summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrion Vibber <brion@users.mediawiki.org>2008-03-03 05:53:26 +0000
committerBrion Vibber <brion@users.mediawiki.org>2008-03-03 05:53:26 +0000
commitfb142b00bc666e27014c2b3ecd535a710d9268d2 (patch)
tree251f4e57ee7d281282b77fb75763336e29fbde7a
tag 1.9.61.9.6
Notes
http://mediawiki.org/wiki/Special:Code/MediaWiki/31486
-rw-r--r--AdminSettings.sample31
-rw-r--r--COPYING340
-rw-r--r--FAQ5
-rw-r--r--HISTORY3345
-rw-r--r--INSTALL106
-rw-r--r--Makefile2
-rw-r--r--README103
-rw-r--r--RELEASE-NOTES995
-rw-r--r--StartProfiler.php22
-rw-r--r--UPGRADE335
-rw-r--r--api.php65
-rwxr-xr-xbin/ulimit-tvf.sh6
-rw-r--r--bin/ulimit.sh7
-rw-r--r--config/index.php1724
-rw-r--r--docs/README17
-rw-r--r--docs/database.txt179
-rw-r--r--docs/deferred.txt19
-rw-r--r--docs/design.txt128
-rw-r--r--docs/export-0.1.xsd76
-rw-r--r--docs/export-0.2.xsd100
-rw-r--r--docs/export-0.3.xsd154
-rw-r--r--docs/export-demo.xml115
-rw-r--r--docs/globals.txt74
-rw-r--r--docs/hooks.txt533
-rw-r--r--docs/html/README4
-rw-r--r--docs/language.txt24
-rw-r--r--docs/linkcache.txt18
-rw-r--r--docs/magicword.txt44
-rw-r--r--docs/memcached.txt132
-rw-r--r--docs/php-memcached/ChangeLog45
-rw-r--r--docs/php-memcached/Documentation258
-rw-r--r--docs/schema.txt6
-rw-r--r--docs/skin.txt48
-rw-r--r--docs/title.txt72
-rw-r--r--docs/user.txt63
-rw-r--r--extensions/README3
-rw-r--r--images/README5
-rw-r--r--img_auth.php62
-rw-r--r--includes/.htaccess1
-rw-r--r--includes/AjaxDispatcher.php91
-rw-r--r--includes/AjaxFunctions.php171
-rw-r--r--includes/AjaxResponse.php203
-rw-r--r--includes/Article.php2790
-rw-r--r--includes/AuthPlugin.php237
-rw-r--r--includes/AutoLoader.php323
-rw-r--r--includes/BagOStuff.php694
-rw-r--r--includes/Block.php669
-rw-r--r--includes/CacheDependency.php328
-rw-r--r--includes/CategoryPage.php413
-rw-r--r--includes/Categoryfinder.php191
-rw-r--r--includes/ChangesList.php687
-rw-r--r--includes/CoreParserFunctions.php193
-rw-r--r--includes/Credits.php189
-rw-r--r--includes/Database.php2113
-rw-r--r--includes/DatabaseFunctions.php403
-rw-r--r--includes/DatabaseOracle.php691
-rw-r--r--includes/DatabasePostgres.php912
-rw-r--r--includes/DateFormatter.php291
-rw-r--r--includes/DefaultSettings.php2419
-rw-r--r--includes/Defines.php210
-rw-r--r--includes/DifferenceEngine.php1791
-rw-r--r--includes/DjVuImage.php231
-rw-r--r--includes/EditPage.php1927
-rw-r--r--includes/Exception.php218
-rw-r--r--includes/Exif.php1130
-rw-r--r--includes/Export.php754
-rw-r--r--includes/ExternalEdit.php77
-rw-r--r--includes/ExternalStore.php70
-rw-r--r--includes/ExternalStoreDB.php149
-rw-r--r--includes/ExternalStoreHttp.php23
-rw-r--r--includes/FakeTitle.php88
-rw-r--r--includes/Feed.php310
-rw-r--r--includes/FileStore.php373
-rw-r--r--includes/GlobalFunctions.php2138
-rw-r--r--includes/HTMLCacheUpdate.php229
-rw-r--r--includes/HTMLFileCache.php159
-rw-r--r--includes/HTMLForm.php158
-rw-r--r--includes/HistoryBlob.php307
-rw-r--r--includes/Hooks.php130
-rw-r--r--includes/HttpFunctions.php91
-rw-r--r--includes/IP.php260
-rw-r--r--includes/Image.php2373
-rw-r--r--includes/ImageFunctions.php259
-rw-r--r--includes/ImageGallery.php226
-rw-r--r--includes/ImagePage.php770
-rw-r--r--includes/JobQueue.php267
-rw-r--r--includes/Licenses.php173
-rw-r--r--includes/LinkBatch.php183
-rw-r--r--includes/LinkCache.php177
-rw-r--r--includes/LinkFilter.php92
-rw-r--r--includes/Linker.php1207
-rw-r--r--includes/LinksUpdate.php601
-rw-r--r--includes/LoadBalancer.php650
-rw-r--r--includes/LogPage.php246
-rw-r--r--includes/MacBinary.php272
-rw-r--r--includes/MagicWord.php393
-rw-r--r--includes/Math.php274
-rw-r--r--includes/MemcachedSessions.php73
-rw-r--r--includes/MessageCache.php683
-rw-r--r--includes/Metadata.php367
-rw-r--r--includes/MimeMagic.php715
-rw-r--r--includes/Namespace.php129
-rw-r--r--includes/ObjectCache.php126
-rw-r--r--includes/OutputPage.php1164
-rw-r--r--includes/PageHistory.php565
-rw-r--r--includes/Pager.php656
-rw-r--r--includes/Parser.php4974
-rw-r--r--includes/ParserCache.php125
-rw-r--r--includes/Profiler.php367
-rw-r--r--includes/ProfilerSimple.php130
-rw-r--r--includes/ProfilerSimpleUDP.php39
-rw-r--r--includes/ProfilerStub.php26
-rw-r--r--includes/ProtectionForm.php243
-rw-r--r--includes/ProxyTools.php217
-rw-r--r--includes/QueryPage.php501
-rw-r--r--includes/RawPage.php206
-rw-r--r--includes/RecentChange.php598
-rw-r--r--includes/Revision.php844
-rw-r--r--includes/Sanitizer.php1263
-rw-r--r--includes/SearchEngine.php351
-rw-r--r--includes/SearchMySQL.php206
-rw-r--r--includes/SearchMySQL4.php74
-rw-r--r--includes/SearchPostgres.php158
-rw-r--r--includes/SearchTsearch2.php124
-rw-r--r--includes/SearchUpdate.php115
-rw-r--r--includes/Setup.php235
-rw-r--r--includes/SiteConfiguration.php121
-rw-r--r--includes/SiteStats.php168
-rw-r--r--includes/Skin.php1653
-rw-r--r--includes/SkinTemplate.php1172
-rw-r--r--includes/SpecialAllmessages.php200
-rw-r--r--includes/SpecialAllpages.php360
-rw-r--r--includes/SpecialAncientpages.php65
-rw-r--r--includes/SpecialBlockip.php293
-rw-r--r--includes/SpecialBlockme.php40
-rw-r--r--includes/SpecialBooksources.php110
-rw-r--r--includes/SpecialBrokenRedirects.php88
-rw-r--r--includes/SpecialCategories.php69
-rw-r--r--includes/SpecialConfirmemail.php107
-rw-r--r--includes/SpecialContributions.php457
-rw-r--r--includes/SpecialDeadendpages.php67
-rw-r--r--includes/SpecialDisambiguations.php115
-rw-r--r--includes/SpecialDoubleRedirects.php107
-rw-r--r--includes/SpecialEmailuser.php183
-rw-r--r--includes/SpecialExport.php131
-rw-r--r--includes/SpecialImagelist.php170
-rw-r--r--includes/SpecialImport.php859
-rw-r--r--includes/SpecialIpblocklist.php363
-rw-r--r--includes/SpecialListredirects.php67
-rw-r--r--includes/SpecialListusers.php234
-rw-r--r--includes/SpecialLockdb.php136
-rw-r--r--includes/SpecialLog.php425
-rw-r--r--includes/SpecialLonelypages.php61
-rw-r--r--includes/SpecialLongpages.php36
-rw-r--r--includes/SpecialMIMEsearch.php158
-rw-r--r--includes/SpecialMostcategories.php59
-rw-r--r--includes/SpecialMostimages.php64
-rw-r--r--includes/SpecialMostlinked.php98
-rw-r--r--includes/SpecialMostlinkedcategories.php81
-rw-r--r--includes/SpecialMostrevisions.php68
-rw-r--r--includes/SpecialMovepage.php313
-rw-r--r--includes/SpecialNewimages.php209
-rw-r--r--includes/SpecialNewpages.php203
-rw-r--r--includes/SpecialPage.php776
-rw-r--r--includes/SpecialPopularpages.php59
-rw-r--r--includes/SpecialPreferences.php961
-rw-r--r--includes/SpecialPrefixindex.php148
-rw-r--r--includes/SpecialRandompage.php58
-rw-r--r--includes/SpecialRandomredirect.php54
-rw-r--r--includes/SpecialRecentchanges.php706
-rw-r--r--includes/SpecialRecentchangeslinked.php174
-rw-r--r--includes/SpecialResetpass.php158
-rw-r--r--includes/SpecialRevisiondelete.php268
-rw-r--r--includes/SpecialSearch.php406
-rw-r--r--includes/SpecialShortpages.php94
-rw-r--r--includes/SpecialSpecialpages.php60
-rw-r--r--includes/SpecialStatistics.php81
-rw-r--r--includes/SpecialUncategorizedcategories.php39
-rw-r--r--includes/SpecialUncategorizedimages.php55
-rw-r--r--includes/SpecialUncategorizedpages.php59
-rw-r--r--includes/SpecialUndelete.php767
-rw-r--r--includes/SpecialUnlockdb.php112
-rw-r--r--includes/SpecialUnusedcategories.php48
-rw-r--r--includes/SpecialUnusedimages.php86
-rw-r--r--includes/SpecialUnusedtemplates.php59
-rw-r--r--includes/SpecialUnwatchedpages.php71
-rw-r--r--includes/SpecialUpload.php1260
-rw-r--r--includes/SpecialUploadMogile.php134
-rw-r--r--includes/SpecialUserlogin.php802
-rw-r--r--includes/SpecialUserlogout.php27
-rw-r--r--includes/SpecialUserrights.php178
-rw-r--r--includes/SpecialVersion.php321
-rw-r--r--includes/SpecialWantedcategories.php85
-rw-r--r--includes/SpecialWantedpages.php133
-rw-r--r--includes/SpecialWatchlist.php501
-rw-r--r--includes/SpecialWhatlinkshere.php273
-rw-r--r--includes/SquidUpdate.php282
-rw-r--r--includes/StreamFile.php72
-rw-r--r--includes/StringUtils.php301
-rw-r--r--includes/StubObject.php136
-rw-r--r--includes/Title.php2505
-rw-r--r--includes/User.php2527
-rw-r--r--includes/UserMailer.php433
-rw-r--r--includes/Utf8Case.php1506
-rw-r--r--includes/WatchedItem.php189
-rw-r--r--includes/WebRequest.php540
-rw-r--r--includes/WebResponse.php18
-rw-r--r--includes/WebStart.php92
-rw-r--r--includes/Wiki.php448
-rw-r--r--includes/WikiError.php125
-rw-r--r--includes/Xml.php345
-rw-r--r--includes/XmlFunctions.php65
-rw-r--r--includes/ZhClient.php149
-rw-r--r--includes/ZhConversion.php8457
-rw-r--r--includes/api/ApiBase.php533
-rw-r--r--includes/api/ApiFeedWatchlist.php125
-rw-r--r--includes/api/ApiFormatBase.php235
-rw-r--r--includes/api/ApiFormatJson.php69
-rw-r--r--includes/api/ApiFormatJson_json.php841
-rw-r--r--includes/api/ApiFormatPhp.php54
-rw-r--r--includes/api/ApiFormatWddx.php89
-rw-r--r--includes/api/ApiFormatXml.php145
-rw-r--r--includes/api/ApiFormatYaml.php54
-rw-r--r--includes/api/ApiFormatYaml_spyc.php861
-rw-r--r--includes/api/ApiHelp.php55
-rw-r--r--includes/api/ApiLogin.php122
-rw-r--r--includes/api/ApiMain.php366
-rw-r--r--includes/api/ApiOpenSearch.php109
-rw-r--r--includes/api/ApiPageSet.php598
-rw-r--r--includes/api/ApiQuery.php378
-rw-r--r--includes/api/ApiQueryAllpages.php173
-rw-r--r--includes/api/ApiQueryBacklinks.php358
-rw-r--r--includes/api/ApiQueryBase.php373
-rw-r--r--includes/api/ApiQueryInfo.php85
-rw-r--r--includes/api/ApiQueryLogEvents.php173
-rw-r--r--includes/api/ApiQueryRecentChanges.php187
-rw-r--r--includes/api/ApiQueryRevisions.php268
-rw-r--r--includes/api/ApiQuerySiteinfo.php116
-rw-r--r--includes/api/ApiQueryUserContributions.php175
-rw-r--r--includes/api/ApiQueryWatchlist.php234
-rw-r--r--includes/api/ApiResult.php157
-rw-r--r--includes/cbt/CBTCompiler.php367
-rw-r--r--includes/cbt/CBTProcessor.php540
-rw-r--r--includes/cbt/README108
-rw-r--r--includes/memcached-client.php1088
-rw-r--r--includes/mime.info76
-rw-r--r--includes/mime.types117
-rw-r--r--includes/normal/CleanUpTest.php423
-rw-r--r--includes/normal/Makefile72
-rw-r--r--includes/normal/README55
-rw-r--r--includes/normal/RandomTest.php108
-rw-r--r--includes/normal/Utf8Test.php153
-rw-r--r--includes/normal/UtfNormal.php808
-rw-r--r--includes/normal/UtfNormalBench.php107
-rw-r--r--includes/normal/UtfNormalData.inc13
-rw-r--r--includes/normal/UtfNormalDataK.inc10
-rw-r--r--includes/normal/UtfNormalGenerate.php236
-rw-r--r--includes/normal/UtfNormalTest.php249
-rw-r--r--includes/normal/UtfNormalUtil.php142
-rw-r--r--includes/proxy_check.php55
-rw-r--r--includes/templates/NoLocalSettings.php48
-rw-r--r--includes/templates/Userlogin.php229
-rw-r--r--includes/zhtable/Makefile268
-rw-r--r--includes/zhtable/README16
-rw-r--r--includes/zhtable/printutf8.c99
-rw-r--r--includes/zhtable/simp2trad.manual178
-rw-r--r--includes/zhtable/toCN.manual331
-rw-r--r--includes/zhtable/toHK.manual211
-rw-r--r--includes/zhtable/toSG.manual15
-rw-r--r--includes/zhtable/toTW.manual309
-rw-r--r--includes/zhtable/trad2simp.manual15
-rw-r--r--includes/zhtable/tradphrases.manual149
-rw-r--r--index.php55
-rw-r--r--install-utils.inc153
-rw-r--r--languages/.htaccess1
-rw-r--r--languages/Language.php1779
-rw-r--r--languages/LanguageConverter.php814
-rw-r--r--languages/Names.php287
-rw-r--r--languages/classes/LanguageAz.php17
-rw-r--r--languages/classes/LanguageBe.php89
-rw-r--r--languages/classes/LanguageBg.php25
-rw-r--r--languages/classes/LanguageBs.php137
-rw-r--r--languages/classes/LanguageCs.php87
-rw-r--r--languages/classes/LanguageCu.php50
-rw-r--r--languages/classes/LanguageEo.php74
-rw-r--r--languages/classes/LanguageEt.php21
-rw-r--r--languages/classes/LanguageFi.php140
-rw-r--r--languages/classes/LanguageFr.php17
-rw-r--r--languages/classes/LanguageGa.php52
-rw-r--r--languages/classes/LanguageGsw.php69
-rw-r--r--languages/classes/LanguageHe.php72
-rw-r--r--languages/classes/LanguageHr.php26
-rw-r--r--languages/classes/LanguageHsb.php117
-rw-r--r--languages/classes/LanguageHu.php53
-rw-r--r--languages/classes/LanguageJa.php42
-rw-r--r--languages/classes/LanguageKk.deps.php12
-rw-r--r--languages/classes/LanguageKk.php210
-rw-r--r--languages/classes/LanguageKk_kz.php269
-rw-r--r--languages/classes/LanguageKo.php57
-rw-r--r--languages/classes/LanguageKsh.php36
-rw-r--r--languages/classes/LanguageLa.php37
-rw-r--r--languages/classes/LanguageLt.php22
-rw-r--r--languages/classes/LanguageLv.php57
-rw-r--r--languages/classes/LanguagePt_br.php17
-rw-r--r--languages/classes/LanguageRmy.php72
-rw-r--r--languages/classes/LanguageRu.php87
-rw-r--r--languages/classes/LanguageSk.php94
-rw-r--r--languages/classes/LanguageSl.php124
-rw-r--r--languages/classes/LanguageSr.deps.php10
-rw-r--r--languages/classes/LanguageSr.php192
-rw-r--r--languages/classes/LanguageSr_ec.php28
-rw-r--r--languages/classes/LanguageSr_el.deps.php9
-rw-r--r--languages/classes/LanguageSr_el.php28
-rw-r--r--languages/classes/LanguageTr.php18
-rw-r--r--languages/classes/LanguageTyv.php233
-rw-r--r--languages/classes/LanguageVi.php74
-rw-r--r--languages/classes/LanguageWa.php71
-rw-r--r--languages/classes/LanguageZh.deps.php10
-rw-r--r--languages/classes/LanguageZh.php103
-rw-r--r--languages/classes/LanguageZh_cn.php27
-rw-r--r--languages/classes/LanguageZh_yue.php27
-rw-r--r--languages/messages/MessagesAb.php5
-rw-r--r--languages/messages/MessagesAf.php694
-rw-r--r--languages/messages/MessagesAn.php24
-rw-r--r--languages/messages/MessagesAr.php608
-rw-r--r--languages/messages/MessagesArc.php15
-rw-r--r--languages/messages/MessagesAs.php20
-rw-r--r--languages/messages/MessagesAst.php29
-rw-r--r--languages/messages/MessagesAv.php9
-rw-r--r--languages/messages/MessagesAy.php9
-rw-r--r--languages/messages/MessagesAz.php675
-rw-r--r--languages/messages/MessagesBa.php201
-rw-r--r--languages/messages/MessagesBar.php17
-rw-r--r--languages/messages/MessagesBat_smg.php9
-rw-r--r--languages/messages/MessagesBe.php838
-rw-r--r--languages/messages/MessagesBg.php1379
-rw-r--r--languages/messages/MessagesBm.php9
-rw-r--r--languages/messages/MessagesBn.php133
-rw-r--r--languages/messages/MessagesBo.php20
-rw-r--r--languages/messages/MessagesBpy.php299
-rw-r--r--languages/messages/MessagesBr.php1097
-rw-r--r--languages/messages/MessagesBs.php1094
-rw-r--r--languages/messages/MessagesCa.php1248
-rw-r--r--languages/messages/MessagesCe.php9
-rw-r--r--languages/messages/MessagesCs.php2081
-rw-r--r--languages/messages/MessagesCsb.php327
-rw-r--r--languages/messages/MessagesCu.php141
-rw-r--r--languages/messages/MessagesCv.php245
-rw-r--r--languages/messages/MessagesCy.php846
-rw-r--r--languages/messages/MessagesDa.php1341
-rw-r--r--languages/messages/MessagesDe.php2186
-rw-r--r--languages/messages/MessagesDv.php9
-rw-r--r--languages/messages/MessagesDz.php22
-rw-r--r--languages/messages/MessagesEl.php1770
-rw-r--r--languages/messages/MessagesEn.php2711
-rw-r--r--languages/messages/MessagesEnRTL.php5
-rw-r--r--languages/messages/MessagesEo.php1251
-rw-r--r--languages/messages/MessagesEs.php1711
-rw-r--r--languages/messages/MessagesEt.php898
-rw-r--r--languages/messages/MessagesEu.php1906
-rw-r--r--languages/messages/MessagesFa.php925
-rw-r--r--languages/messages/MessagesFi.php2063
-rw-r--r--languages/messages/MessagesFo.php116
-rw-r--r--languages/messages/MessagesFr.php1540
-rw-r--r--languages/messages/MessagesFur.php728
-rw-r--r--languages/messages/MessagesFy.php868
-rw-r--r--languages/messages/MessagesGa.php1786
-rw-r--r--languages/messages/MessagesGn.php9
-rw-r--r--languages/messages/MessagesGsw.php794
-rw-r--r--languages/messages/MessagesGu.php19
-rw-r--r--languages/messages/MessagesHe.php2206
-rw-r--r--languages/messages/MessagesHi.php127
-rw-r--r--languages/messages/MessagesHr.php1559
-rw-r--r--languages/messages/MessagesHsb.php1575
-rw-r--r--languages/messages/MessagesHu.php1053
-rw-r--r--languages/messages/MessagesIa.php801
-rw-r--r--languages/messages/MessagesId.php2011
-rw-r--r--languages/messages/MessagesIi.php9
-rw-r--r--languages/messages/MessagesIs.php706
-rw-r--r--languages/messages/MessagesIt.php2035
-rw-r--r--languages/messages/MessagesJa.php1876
-rw-r--r--languages/messages/MessagesJbo.php24
-rw-r--r--languages/messages/MessagesJv.php45
-rw-r--r--languages/messages/MessagesKa.php575
-rw-r--r--languages/messages/MessagesKaa.php11
-rw-r--r--languages/messages/MessagesKg.php99
-rw-r--r--languages/messages/MessagesKk.php13
-rw-r--r--languages/messages/MessagesKk_cn.php2175
-rw-r--r--languages/messages/MessagesKk_kz.php2150
-rw-r--r--languages/messages/MessagesKk_tr.php2151
-rw-r--r--languages/messages/MessagesKm.php22
-rw-r--r--languages/messages/MessagesKn.php377
-rw-r--r--languages/messages/MessagesKo.php1205
-rw-r--r--languages/messages/MessagesKs.php11
-rw-r--r--languages/messages/MessagesKsh.php2347
-rw-r--r--languages/messages/MessagesKu.php775
-rw-r--r--languages/messages/MessagesKv.php9
-rw-r--r--languages/messages/MessagesLa.php853
-rw-r--r--languages/messages/MessagesLi.php947
-rw-r--r--languages/messages/MessagesLn.php17
-rw-r--r--languages/messages/MessagesLo.php22
-rw-r--r--languages/messages/MessagesLt.php2077
-rw-r--r--languages/messages/MessagesLv.php979
-rw-r--r--languages/messages/MessagesMi.php111
-rw-r--r--languages/messages/MessagesMk.php1709
-rw-r--r--languages/messages/MessagesMl.php23
-rw-r--r--languages/messages/MessagesMs.php817
-rw-r--r--languages/messages/MessagesMt.php99
-rw-r--r--languages/messages/MessagesMzn.php23
-rw-r--r--languages/messages/MessagesNah.php51
-rw-r--r--languages/messages/MessagesNap.php10
-rw-r--r--languages/messages/MessagesNds.php1171
-rw-r--r--languages/messages/MessagesNds_nl.php63
-rw-r--r--languages/messages/MessagesNl.php1901
-rw-r--r--languages/messages/MessagesNn.php1602
-rw-r--r--languages/messages/MessagesNo.php1368
-rw-r--r--languages/messages/MessagesNon.php11
-rw-r--r--languages/messages/MessagesNv.php72
-rw-r--r--languages/messages/MessagesOc.php821
-rw-r--r--languages/messages/MessagesOr.php22
-rw-r--r--languages/messages/MessagesOs.php218
-rw-r--r--languages/messages/MessagesPa.php410
-rw-r--r--languages/messages/MessagesPl.php1798
-rw-r--r--languages/messages/MessagesPms.php1698
-rw-r--r--languages/messages/MessagesPs.php17
-rw-r--r--languages/messages/MessagesPt.php2001
-rw-r--r--languages/messages/MessagesPt_br.php790
-rw-r--r--languages/messages/MessagesQu.php9
-rw-r--r--languages/messages/MessagesRmy.php337
-rw-r--r--languages/messages/MessagesRo.php1625
-rw-r--r--languages/messages/MessagesRu.php2259
-rw-r--r--languages/messages/MessagesSc.php655
-rw-r--r--languages/messages/MessagesSd.php12
-rw-r--r--languages/messages/MessagesSk.php1924
-rw-r--r--languages/messages/MessagesSl.php1587
-rw-r--r--languages/messages/MessagesSq.php1496
-rw-r--r--languages/messages/MessagesSr.php12
-rw-r--r--languages/messages/MessagesSr_ec.php2214
-rw-r--r--languages/messages/MessagesSr_el.php2217
-rw-r--r--languages/messages/MessagesSr_jc.php10
-rw-r--r--languages/messages/MessagesSr_jl.php10
-rw-r--r--languages/messages/MessagesSu.php1030
-rw-r--r--languages/messages/MessagesSv.php1668
-rw-r--r--languages/messages/MessagesTa.php731
-rw-r--r--languages/messages/MessagesTe.php844
-rw-r--r--languages/messages/MessagesTg.php34
-rw-r--r--languages/messages/MessagesTh.php215
-rw-r--r--languages/messages/MessagesTlh.php30
-rw-r--r--languages/messages/MessagesTr.php1113
-rw-r--r--languages/messages/MessagesTt.php793
-rw-r--r--languages/messages/MessagesTyv.php307
-rw-r--r--languages/messages/MessagesUdm.php51
-rw-r--r--languages/messages/MessagesUg.php10
-rw-r--r--languages/messages/MessagesUk.php826
-rw-r--r--languages/messages/MessagesUr.php33
-rw-r--r--languages/messages/MessagesUz.php11
-rw-r--r--languages/messages/MessagesVec.php1175
-rw-r--r--languages/messages/MessagesVi.php1344
-rw-r--r--languages/messages/MessagesVls.php30
-rw-r--r--languages/messages/MessagesWa.php1768
-rw-r--r--languages/messages/MessagesXal.php55
-rw-r--r--languages/messages/MessagesYi.php586
-rw-r--r--languages/messages/MessagesZa.php9
-rw-r--r--languages/messages/MessagesZh.php7
-rw-r--r--languages/messages/MessagesZh_cn.php856
-rw-r--r--languages/messages/MessagesZh_hk.php10
-rw-r--r--languages/messages/MessagesZh_sg.php10
-rw-r--r--languages/messages/MessagesZh_tw.php845
-rw-r--r--languages/messages/MessagesZh_yue.php2204
-rw-r--r--locale/README1
-rw-r--r--maintenance/.htaccess1
-rw-r--r--maintenance/Doxyfile279
-rw-r--r--maintenance/FiveUpgrade.inc1213
-rw-r--r--maintenance/Makefile20
-rw-r--r--maintenance/README85
-rw-r--r--maintenance/addwiki.php234
-rw-r--r--maintenance/apache-ampersand.diff53
-rw-r--r--maintenance/archives/.htaccess1
-rw-r--r--maintenance/archives/patch-archive-rev_id.sql6
-rw-r--r--maintenance/archives/patch-archive-text_id.sql14
-rw-r--r--maintenance/archives/patch-backlinkindexes.sql19
-rw-r--r--maintenance/archives/patch-bot.sql11
-rw-r--r--maintenance/archives/patch-cache.sql41
-rw-r--r--maintenance/archives/patch-categorylinks.sql39
-rw-r--r--maintenance/archives/patch-drop-user_newtalk.sql3
-rw-r--r--maintenance/archives/patch-drop_img_type.sql3
-rw-r--r--maintenance/archives/patch-email-authentication.sql3
-rw-r--r--maintenance/archives/patch-email-notification.sql11
-rw-r--r--maintenance/archives/patch-externallinks.sql13
-rw-r--r--maintenance/archives/patch-filearchive.sql51
-rw-r--r--maintenance/archives/patch-hitcounter.sql9
-rw-r--r--maintenance/archives/patch-image_name_primary.sql6
-rw-r--r--maintenance/archives/patch-image_name_unique.sql6
-rw-r--r--maintenance/archives/patch-img_exif.sql3
-rw-r--r--maintenance/archives/patch-img_media_type.sql17
-rw-r--r--maintenance/archives/patch-img_metadata.sql6
-rw-r--r--maintenance/archives/patch-img_width.sql18
-rw-r--r--maintenance/archives/patch-indexes.sql24
-rw-r--r--maintenance/archives/patch-interwiki-trans.sql2
-rw-r--r--maintenance/archives/patch-interwiki.sql20
-rw-r--r--maintenance/archives/patch-inverse_timestamp.sql15
-rw-r--r--maintenance/archives/patch-ipb_anon_only.sql44
-rw-r--r--maintenance/archives/patch-ipb_expiry.sql8
-rw-r--r--maintenance/archives/patch-ipb_optional_autoblock.sql3
-rw-r--r--maintenance/archives/patch-ipb_range_start.sql25
-rw-r--r--maintenance/archives/patch-ipblocks.sql6
-rw-r--r--maintenance/archives/patch-job.sql20
-rw-r--r--maintenance/archives/patch-langlinks.sql14
-rw-r--r--maintenance/archives/patch-linkscc-1.3.sql6
-rw-r--r--maintenance/archives/patch-linkscc.sql12
-rw-r--r--maintenance/archives/patch-linktables.sql70
-rw-r--r--maintenance/archives/patch-list.txt182
-rw-r--r--maintenance/archives/patch-log_params.sql1
-rw-r--r--maintenance/archives/patch-logging-times-index.sql9
-rw-r--r--maintenance/archives/patch-logging-title.sql6
-rw-r--r--maintenance/archives/patch-logging.sql37
-rw-r--r--maintenance/archives/patch-math.sql28
-rw-r--r--maintenance/archives/patch-mimesearch-indexes.sql22
-rw-r--r--maintenance/archives/patch-objectcache.sql9
-rw-r--r--maintenance/archives/patch-oldestindex.sql5
-rw-r--r--maintenance/archives/patch-page_len.sql16
-rw-r--r--maintenance/archives/patch-page_no_title_convert.sql0
-rw-r--r--maintenance/archives/patch-pagelinks.sql56
-rw-r--r--maintenance/archives/patch-parsercache.sql15
-rw-r--r--maintenance/archives/patch-profiling.sql10
-rw-r--r--maintenance/archives/patch-querycache.sql16
-rw-r--r--maintenance/archives/patch-querycacheinfo.sql12
-rw-r--r--maintenance/archives/patch-querycachetwo.sql22
-rw-r--r--maintenance/archives/patch-random-dateindex.sql54
-rw-r--r--maintenance/archives/patch-rc-newindex.sql9
-rw-r--r--maintenance/archives/patch-rc-patrol.sql9
-rw-r--r--maintenance/archives/patch-rc_id.sql7
-rw-r--r--maintenance/archives/patch-rc_ip.sql7
-rw-r--r--maintenance/archives/patch-rc_len.sql9
-rw-r--r--maintenance/archives/patch-rc_type.sql9
-rw-r--r--maintenance/archives/patch-rc_user_text-index.sql7
-rw-r--r--maintenance/archives/patch-recentchanges-utindex.sql4
-rw-r--r--maintenance/archives/patch-redirect.sql28
-rw-r--r--maintenance/archives/patch-rename-group.sql10
-rw-r--r--maintenance/archives/patch-rename-user_groups-and_rights.sql9
-rw-r--r--maintenance/archives/patch-restructure.sql147
-rw-r--r--maintenance/archives/patch-rev_deleted.sql11
-rw-r--r--maintenance/archives/patch-rev_text_id.sql17
-rw-r--r--maintenance/archives/patch-searchindex.sql40
-rw-r--r--maintenance/archives/patch-ss_images.sql5
-rw-r--r--maintenance/archives/patch-ss_total_articles.sql6
-rw-r--r--maintenance/archives/patch-templatelinks.sql19
-rw-r--r--maintenance/archives/patch-trackbacks.sql10
-rw-r--r--maintenance/archives/patch-transcache.sql7
-rw-r--r--maintenance/archives/patch-user-realname.sql5
-rw-r--r--maintenance/archives/patch-user_editcount.sql5
-rw-r--r--maintenance/archives/patch-user_email_token.sql12
-rw-r--r--maintenance/archives/patch-user_groups.sql25
-rw-r--r--maintenance/archives/patch-user_nameindex.sql13
-rw-r--r--maintenance/archives/patch-user_newpass_time.sql4
-rw-r--r--maintenance/archives/patch-user_registration.sql9
-rw-r--r--maintenance/archives/patch-user_rights.sql21
-rw-r--r--maintenance/archives/patch-user_token.sql15
-rw-r--r--maintenance/archives/patch-userindex.sql1
-rw-r--r--maintenance/archives/patch-userlevels-defaultgroups.sql30
-rw-r--r--maintenance/archives/patch-userlevels-rights.sql5
-rw-r--r--maintenance/archives/patch-userlevels.sql22
-rw-r--r--maintenance/archives/patch-usernewtalk.sql20
-rw-r--r--maintenance/archives/patch-usernewtalk2.sql6
-rw-r--r--maintenance/archives/patch-val_ip.sql4
-rw-r--r--maintenance/archives/patch-validate.sql13
-rw-r--r--maintenance/archives/patch-watchlist-null.sql9
-rw-r--r--maintenance/archives/patch-watchlist.sql30
-rw-r--r--maintenance/archives/rebuildRecentchanges.inc122
-rw-r--r--maintenance/archives/upgradeWatchlist.php67
-rw-r--r--maintenance/attachLatest.php73
-rw-r--r--maintenance/attribute.php105
-rw-r--r--maintenance/backup.inc292
-rw-r--r--maintenance/backupPrefetch.inc203
-rw-r--r--maintenance/benchmarkPurge.php65
-rw-r--r--maintenance/build-intl-wiki.sql31
-rw-r--r--maintenance/changePassword.php53
-rw-r--r--maintenance/changeuser.sql12
-rw-r--r--maintenance/checkUsernames.php34
-rw-r--r--maintenance/cleanupCaps.php158
-rw-r--r--maintenance/cleanupDupes.inc130
-rw-r--r--maintenance/cleanupDupes.php37
-rw-r--r--maintenance/cleanupImages.php168
-rw-r--r--maintenance/cleanupSpam.php112
-rw-r--r--maintenance/cleanupTable.inc86
-rw-r--r--maintenance/cleanupTitles.php141
-rw-r--r--maintenance/cleanupWatchlist.php140
-rw-r--r--maintenance/clear_interwiki_cache.php26
-rw-r--r--maintenance/clear_stats.php31
-rw-r--r--maintenance/commandLine.inc245
-rw-r--r--maintenance/convertLinks.inc220
-rw-r--r--maintenance/convertLinks.php16
-rw-r--r--maintenance/counter.php5
-rw-r--r--maintenance/createAndPromote.php47
-rw-r--r--maintenance/database.sql7
-rw-r--r--maintenance/delete-idle-wiki-users.pl138
-rw-r--r--maintenance/deleteBatch.php88
-rw-r--r--maintenance/deleteDefaultMessages.php45
-rw-r--r--maintenance/deleteImageMemcached.php60
-rw-r--r--maintenance/deleteOldRevisions.inc60
-rw-r--r--maintenance/deleteOldRevisions.php30
-rw-r--r--maintenance/deleteOrphanedRevisions.inc.php33
-rw-r--r--maintenance/deleteOrphanedRevisions.php55
-rw-r--r--maintenance/deleteRevision.php40
-rw-r--r--maintenance/dtrace/counts.d23
-rw-r--r--maintenance/dtrace/tree.d26
-rw-r--r--maintenance/dumpBackup.php99
-rw-r--r--maintenance/dumpHTML.inc1008
-rw-r--r--maintenance/dumpHTML.php151
-rw-r--r--maintenance/dumpInterwiki.inc220
-rw-r--r--maintenance/dumpInterwiki.php25
-rw-r--r--maintenance/dumpLinks.php63
-rw-r--r--maintenance/dumpReplayLog.php118
-rw-r--r--maintenance/dumpSisterSites.php49
-rw-r--r--maintenance/dumpTextPass.php371
-rw-r--r--maintenance/dumpUploads.php116
-rw-r--r--maintenance/edit.php68
-rw-r--r--maintenance/eval.php63
-rw-r--r--maintenance/fetchInterwiki.pl102
-rw-r--r--maintenance/findhooks.php93
-rw-r--r--maintenance/fixSlaveDesync.php195
-rw-r--r--maintenance/fixTimestamps.php104
-rw-r--r--maintenance/fixUserRegistration.php31
-rw-r--r--maintenance/fuzz-tester.php2458
-rw-r--r--maintenance/generateSitemap.php470
-rw-r--r--maintenance/getLagTimes.php23
-rw-r--r--maintenance/getSlaveServer.php7
-rw-r--r--maintenance/importDump.php143
-rw-r--r--maintenance/importImages.inc.php67
-rw-r--r--maintenance/importImages.php124
-rw-r--r--maintenance/importLogs.inc144
-rw-r--r--maintenance/importLogs.php27
-rw-r--r--maintenance/importPhase2.php370
-rw-r--r--maintenance/importTextFile.php84
-rw-r--r--maintenance/importUseModWiki.php365
-rw-r--r--maintenance/initEditCount.php85
-rw-r--r--maintenance/initStats.php79
-rw-r--r--maintenance/installExtension.php642
-rw-r--r--maintenance/interwiki.sql180
-rw-r--r--maintenance/language/alltrans.php16
-rw-r--r--maintenance/language/checkLanguage.php177
-rw-r--r--maintenance/language/date-formats.php45
-rw-r--r--maintenance/language/diffLanguage.php159
-rw-r--r--maintenance/language/dumpMessages.php20
-rw-r--r--maintenance/language/function-list.php44
-rw-r--r--maintenance/language/lang2po.php154
-rw-r--r--maintenance/language/langmemusage.php30
-rw-r--r--maintenance/language/languages.inc396
-rw-r--r--maintenance/language/messageTypes.inc346
-rw-r--r--maintenance/language/messages.inc2081
-rw-r--r--maintenance/language/rebuildLanguage.php82
-rw-r--r--maintenance/language/splitLanguageFiles.inc1168
-rw-r--r--maintenance/language/splitLanguageFiles.php13
-rw-r--r--maintenance/language/transstat.php213
-rw-r--r--maintenance/language/validate.php40
-rw-r--r--maintenance/language/writeMessagesArray.inc145
-rw-r--r--maintenance/mcc.php173
-rw-r--r--maintenance/mctest.php60
-rw-r--r--maintenance/moveBatch.php95
-rw-r--r--maintenance/mwdocgen.php205
-rw-r--r--maintenance/mwdoxygen.cfg1136
-rw-r--r--maintenance/mysql5/tables-binary.sql1095
-rw-r--r--maintenance/mysql5/tables.sql1086
-rw-r--r--maintenance/namespace2sql.php14
-rw-r--r--maintenance/namespaceDupes.php195
-rw-r--r--maintenance/nukePage.inc80
-rw-r--r--maintenance/nukePage.php30
-rw-r--r--maintenance/oracle/archives/patch-trackbacks.sql10
-rw-r--r--maintenance/oracle/archives/patch-transcache.sql5
-rw-r--r--maintenance/oracle/interwiki.sql178
-rw-r--r--maintenance/oracle/tables.sql335
-rw-r--r--maintenance/orphans.php207
-rw-r--r--maintenance/ourusers.php70
-rw-r--r--maintenance/parserTests.inc1077
-rw-r--r--maintenance/parserTests.php69
-rw-r--r--maintenance/parserTests.txt6423
-rw-r--r--maintenance/parserTestsParserHook.php34
-rw-r--r--maintenance/parserTestsParserTime.php26
-rw-r--r--maintenance/parserTestsStaticParserHook.php44
-rw-r--r--maintenance/postgres/compare_schemas.pl243
-rw-r--r--maintenance/postgres/tables.sql502
-rw-r--r--maintenance/postgres/wp_mysql2postgres.pl400
-rw-r--r--maintenance/purgeList.php34
-rw-r--r--maintenance/purgeOldText.inc63
-rw-r--r--maintenance/purgeOldText.php30
-rw-r--r--maintenance/reassignEdits.inc.php144
-rw-r--r--maintenance/reassignEdits.php57
-rw-r--r--maintenance/rebuildImages.php275
-rw-r--r--maintenance/rebuildInterwiki.inc260
-rw-r--r--maintenance/rebuildInterwiki.php31
-rw-r--r--maintenance/rebuildall.php39
-rw-r--r--maintenance/rebuildrecentchanges.inc97
-rw-r--r--maintenance/rebuildrecentchanges.php25
-rw-r--r--maintenance/rebuildtextindex.inc68
-rw-r--r--maintenance/rebuildtextindex.php25
-rw-r--r--maintenance/refreshImageCount.php25
-rw-r--r--maintenance/refreshLinks.inc131
-rw-r--r--maintenance/refreshLinks.php32
-rw-r--r--maintenance/removeUnusedAccounts.inc47
-rw-r--r--maintenance/removeUnusedAccounts.php58
-rw-r--r--maintenance/renderDump.php103
-rw-r--r--maintenance/runJobs.php32
-rw-r--r--maintenance/showJobs.php19
-rw-r--r--maintenance/showStats.php46
-rw-r--r--maintenance/stats.php49
-rw-r--r--maintenance/storage/blobs.sql8
-rw-r--r--maintenance/storage/checkStorage.php468
-rw-r--r--maintenance/storage/compressOld.inc311
-rw-r--r--maintenance/storage/compressOld.php82
-rw-r--r--maintenance/storage/dumpRev.php14
-rwxr-xr-xmaintenance/storage/make-blobs11
-rw-r--r--maintenance/storage/moveToExternal.php97
-rw-r--r--maintenance/storage/resolveStubs.php100
-rw-r--r--maintenance/tables.sql1078
-rw-r--r--maintenance/testRunner.sql35
-rw-r--r--maintenance/update.php64
-rw-r--r--maintenance/updateArticleCount.inc.php67
-rw-r--r--maintenance/updateArticleCount.php42
-rw-r--r--maintenance/updateSearchIndex.inc115
-rw-r--r--maintenance/updateSearchIndex.php57
-rw-r--r--maintenance/updateSpecialPages.php104
-rw-r--r--maintenance/updaters.inc1099
-rw-r--r--maintenance/upgrade1_5.php24
-rw-r--r--maintenance/userDupes.inc326
-rw-r--r--maintenance/userDupes.php41
-rw-r--r--maintenance/users.sql12
-rw-r--r--maintenance/wikipedia-interwiki.sql220
-rw-r--r--maintenance/wiktionary-interwiki.sql160
-rw-r--r--math/.htaccess1
-rw-r--r--math/.svnignore7
-rw-r--r--math/Makefile64
-rw-r--r--math/README120
-rw-r--r--math/TODO3
-rw-r--r--math/html.ml142
-rw-r--r--math/html.mli5
-rw-r--r--math/lexer.mll107
-rw-r--r--math/mathml.ml20
-rw-r--r--math/mathml.mli1
-rw-r--r--math/parser.mly118
-rw-r--r--math/render.ml40
-rw-r--r--math/render_info.mli20
-rw-r--r--math/tex.mli23
-rw-r--r--math/texutil.ml720
-rw-r--r--math/texutil.mli11
-rw-r--r--math/texvc.ml34
-rw-r--r--math/texvc_cgi.ml62
-rw-r--r--math/texvc_test.ml24
-rw-r--r--math/texvc_tex.ml3
-rw-r--r--math/util.ml17
-rw-r--r--opensearch_desc.php45
-rw-r--r--profileinfo.php247
-rw-r--r--redirect.php14
-rw-r--r--redirect.phtml4
-rw-r--r--serialized/Makefile28
-rw-r--r--serialized/README37
-rw-r--r--serialized/Utf8Case.ser1
-rw-r--r--serialized/serialize-localisation.php35
-rw-r--r--serialized/serialize.php75
-rw-r--r--skins/Chick.deps.php13
-rw-r--r--skins/Chick.php30
-rw-r--r--skins/CologneBlue.php314
-rw-r--r--skins/MonoBook.deps.php12
-rw-r--r--skins/MonoBook.php289
-rw-r--r--skins/MySkin.deps.php13
-rw-r--r--skins/MySkin.php30
-rw-r--r--skins/Nostalgia.php99
-rw-r--r--skins/Simple.deps.php13
-rw-r--r--skins/Simple.php70
-rw-r--r--skins/Skin.sample19
-rw-r--r--skins/SkinPHPTal.sample28
-rw-r--r--skins/Standard.php304
-rw-r--r--skins/chick/IE50Fixes.css67
-rw-r--r--skins/chick/IE55Fixes.css81
-rw-r--r--skins/chick/IE60Fixes.css79
-rw-r--r--skins/chick/main.css499
-rw-r--r--skins/common/IEFixes.js127
-rw-r--r--skins/common/ajax.js149
-rw-r--r--skins/common/ajaxsearch.js104
-rw-r--r--skins/common/ajaxwatch.js127
-rw-r--r--skins/common/cologneblue.css96
-rw-r--r--skins/common/common.css467
-rw-r--r--skins/common/commonPrint.css288
-rw-r--r--skins/common/common_rtl.css28
-rw-r--r--skins/common/feed.css95
-rw-r--r--skins/common/images/Arr_.pngbin0 -> 918 bytes
-rw-r--r--skins/common/images/Arr_d.pngbin0 -> 215 bytes
-rw-r--r--skins/common/images/Arr_l.pngbin0 -> 263 bytes
-rw-r--r--skins/common/images/Arr_r.pngbin0 -> 210 bytes
-rw-r--r--skins/common/images/Arr_r.xcfbin0 -> 1437 bytes
-rw-r--r--skins/common/images/Arr_u.pngbin0 -> 1044 bytes
-rw-r--r--skins/common/images/Zoom_sans.gifbin0 -> 901 bytes
-rw-r--r--skins/common/images/arrow_disabled_first_25.pngbin0 -> 481 bytes
-rw-r--r--skins/common/images/arrow_disabled_last_25.pngbin0 -> 480 bytes
-rw-r--r--skins/common/images/arrow_disabled_left_25.pngbin0 -> 460 bytes
-rw-r--r--skins/common/images/arrow_disabled_right_25.pngbin0 -> 447 bytes
-rw-r--r--skins/common/images/arrow_first.svg85
-rw-r--r--skins/common/images/arrow_first_25.pngbin0 -> 482 bytes
-rw-r--r--skins/common/images/arrow_last_25.pngbin0 -> 484 bytes
-rw-r--r--skins/common/images/arrow_left.svg78
-rw-r--r--skins/common/images/arrow_left_25.pngbin0 -> 462 bytes
-rw-r--r--skins/common/images/arrow_right_25.pngbin0 -> 449 bytes
-rw-r--r--skins/common/images/bullet.gifbin0 -> 50 bytes
-rw-r--r--skins/common/images/button_bold.pngbin0 -> 978 bytes
-rw-r--r--skins/common/images/button_extlink.pngbin0 -> 1093 bytes
-rw-r--r--skins/common/images/button_headline.pngbin0 -> 497 bytes
-rw-r--r--skins/common/images/button_hr.pngbin0 -> 372 bytes
-rw-r--r--skins/common/images/button_image.pngbin0 -> 1110 bytes
-rw-r--r--skins/common/images/button_italic.pngbin0 -> 975 bytes
-rw-r--r--skins/common/images/button_link.pngbin0 -> 434 bytes
-rw-r--r--skins/common/images/button_math.pngbin0 -> 730 bytes
-rw-r--r--skins/common/images/button_media.pngbin0 -> 1155 bytes
-rw-r--r--skins/common/images/button_nowiki.pngbin0 -> 375 bytes
-rw-r--r--skins/common/images/button_sig.pngbin0 -> 1217 bytes
-rw-r--r--skins/common/images/button_template.pngbin0 -> 362 bytes
-rw-r--r--skins/common/images/fileicon.xcfbin0 -> 26160 bytes
-rw-r--r--skins/common/images/gnu-fdl.pngbin0 -> 1748 bytes
-rw-r--r--skins/common/images/gnu-fdl.xcfbin0 -> 5578 bytes
-rw-r--r--skins/common/images/icons/COPYING43
-rw-r--r--skins/common/images/icons/fileicon-c.pngbin0 -> 2995 bytes
-rw-r--r--skins/common/images/icons/fileicon-cpp.pngbin0 -> 2250 bytes
-rw-r--r--skins/common/images/icons/fileicon-deb.pngbin0 -> 5528 bytes
-rw-r--r--skins/common/images/icons/fileicon-djvu.pngbin0 -> 11137 bytes
-rw-r--r--skins/common/images/icons/fileicon-djvu.xcfbin0 -> 83394 bytes
-rw-r--r--skins/common/images/icons/fileicon-dvi.pngbin0 -> 13042 bytes
-rw-r--r--skins/common/images/icons/fileicon-exe.pngbin0 -> 5864 bytes
-rw-r--r--skins/common/images/icons/fileicon-h.pngbin0 -> 1195 bytes
-rw-r--r--skins/common/images/icons/fileicon-html.pngbin0 -> 7601 bytes
-rw-r--r--skins/common/images/icons/fileicon-iso.pngbin0 -> 6673 bytes
-rw-r--r--skins/common/images/icons/fileicon-java.pngbin0 -> 6825 bytes
-rw-r--r--skins/common/images/icons/fileicon-mid.pngbin0 -> 7191 bytes
-rw-r--r--skins/common/images/icons/fileicon-mov.pngbin0 -> 7946 bytes
-rw-r--r--skins/common/images/icons/fileicon-o.pngbin0 -> 2893 bytes
-rw-r--r--skins/common/images/icons/fileicon-ogg.pngbin0 -> 6143 bytes
-rw-r--r--skins/common/images/icons/fileicon-ogg.xcfbin0 -> 40236 bytes
-rw-r--r--skins/common/images/icons/fileicon-pdf.pngbin0 -> 5138 bytes
-rw-r--r--skins/common/images/icons/fileicon-ps.pngbin0 -> 3293 bytes
-rw-r--r--skins/common/images/icons/fileicon-rm.pngbin0 -> 4977 bytes
-rw-r--r--skins/common/images/icons/fileicon-rpm.pngbin0 -> 4753 bytes
-rw-r--r--skins/common/images/icons/fileicon-svg.pngbin0 -> 5193 bytes
-rw-r--r--skins/common/images/icons/fileicon-tar.pngbin0 -> 6544 bytes
-rw-r--r--skins/common/images/icons/fileicon-tex.pngbin0 -> 4203 bytes
-rw-r--r--skins/common/images/icons/fileicon-ttf.pngbin0 -> 3625 bytes
-rw-r--r--skins/common/images/icons/fileicon-txt.pngbin0 -> 6801 bytes
-rw-r--r--skins/common/images/icons/fileicon.pngbin0 -> 1121 bytes
-rw-r--r--skins/common/images/link_icon.gifbin0 -> 942 bytes
-rw-r--r--skins/common/images/magnify-clip.pngbin0 -> 267 bytes
-rw-r--r--skins/common/images/mediawiki-large.xcfbin0 -> 672765 bytes
-rw-r--r--skins/common/images/mediawiki-largesquare.xcfbin0 -> 859358 bytes
-rw-r--r--skins/common/images/mediawiki-small.xcfbin0 -> 36011 bytes
-rw-r--r--skins/common/images/mediawiki.pngbin0 -> 23064 bytes
-rw-r--r--skins/common/images/poweredby_mediawiki_88x31.pngbin0 -> 1933 bytes
-rw-r--r--skins/common/images/redirectltr.pngbin0 -> 1024 bytes
-rw-r--r--skins/common/images/redirectrtl.pngbin0 -> 1017 bytes
-rw-r--r--skins/common/images/sort_down.gifbin0 -> 879 bytes
-rw-r--r--skins/common/images/sort_none.gifbin0 -> 877 bytes
-rw-r--r--skins/common/images/sort_up.gifbin0 -> 881 bytes
-rw-r--r--skins/common/images/wiki.pngbin0 -> 24954 bytes
-rw-r--r--skins/common/metadata.js49
-rw-r--r--skins/common/nostalgia.css17
-rw-r--r--skins/common/preview.js53
-rw-r--r--skins/common/protect.js129
-rw-r--r--skins/common/quickbar-right.css1
-rw-r--r--skins/common/quickbar.css1
-rw-r--r--skins/common/sorttable.js358
-rw-r--r--skins/common/sticky.js124
-rw-r--r--skins/common/upload.js23
-rw-r--r--skins/common/wikibits.js908
-rw-r--r--skins/common/wikiprintable.css46
-rw-r--r--skins/common/wikistandard.css48
-rw-r--r--skins/disabled/HTMLDump.php234
-rw-r--r--skins/disabled/MonoBook.tpl200
-rw-r--r--skins/disabled/MonoBookCBT.php1389
-rw-r--r--skins/htmldump/lookup.js91
-rw-r--r--skins/htmldump/main.css9
-rw-r--r--skins/htmldump/md5.js256
-rw-r--r--skins/htmldump/utf8.js72
-rw-r--r--skins/monobook/IE50Fixes.css67
-rw-r--r--skins/monobook/IE55Fixes.css85
-rw-r--r--skins/monobook/IE60Fixes.css84
-rw-r--r--skins/monobook/IE70Fixes.css74
-rw-r--r--skins/monobook/IEMacFixes.css44
-rw-r--r--skins/monobook/KHTMLFixes.css3
-rw-r--r--skins/monobook/Opera6Fixes.css14
-rw-r--r--skins/monobook/Opera7Fixes.css11
-rw-r--r--skins/monobook/audio.pngbin0 -> 312 bytes
-rw-r--r--skins/monobook/bullet.gifbin0 -> 50 bytes
-rw-r--r--skins/monobook/discussionitem_icon.gifbin0 -> 949 bytes
-rw-r--r--skins/monobook/document.pngbin0 -> 270 bytes
-rw-r--r--skins/monobook/external.pngbin0 -> 165 bytes
-rw-r--r--skins/monobook/file_icon.gifbin0 -> 921 bytes
-rw-r--r--skins/monobook/handheld.css1337
-rw-r--r--skins/monobook/headbg.jpgbin0 -> 7881 bytes
-rw-r--r--skins/monobook/link_icon.gifbin0 -> 942 bytes
-rw-r--r--skins/monobook/lock_icon.gifbin0 -> 918 bytes
-rw-r--r--skins/monobook/magnify-clip.pngbin0 -> 237 bytes
-rw-r--r--skins/monobook/mail_icon.gifbin0 -> 918 bytes
-rw-r--r--skins/monobook/main.css1616
-rw-r--r--skins/monobook/news_icon.pngbin0 -> 297 bytes
-rw-r--r--skins/monobook/required.gifbin0 -> 47 bytes
-rw-r--r--skins/monobook/rtl.css216
-rw-r--r--skins/monobook/user.gifbin0 -> 932 bytes
-rw-r--r--skins/monobook/video.pngbin0 -> 215 bytes
-rw-r--r--skins/monobook/wiki-indexed.pngbin0 -> 8205 bytes
-rw-r--r--skins/monobook/wiki.pngbin0 -> 23064 bytes
-rw-r--r--skins/myskin/main.css1
-rw-r--r--skins/simple/discussionitem_icon.gifbin0 -> 949 bytes
-rw-r--r--skins/simple/external.pngbin0 -> 165 bytes
-rw-r--r--skins/simple/file_icon.gifbin0 -> 921 bytes
-rw-r--r--skins/simple/link_icon.gifbin0 -> 942 bytes
-rw-r--r--skins/simple/lock_icon.gifbin0 -> 918 bytes
-rw-r--r--skins/simple/mail_icon.gifbin0 -> 918 bytes
-rw-r--r--skins/simple/main.css442
-rw-r--r--t/00-test.t8
-rw-r--r--t/README10
-rw-r--r--t/inc/IP.t60
-rw-r--r--t/inc/Licenses.t29
-rw-r--r--t/inc/Sanitizer.t55
-rw-r--r--t/inc/Xml.t56
-rw-r--r--tests/.htaccess1
-rw-r--r--tests/.svnignore6
-rw-r--r--tests/ArticleTest.php150
-rw-r--r--tests/DatabaseTest.php93
-rw-r--r--tests/GlobalTest.php211
-rw-r--r--tests/ImageTest.php66
-rw-r--r--tests/LocalTestSettings.sample29
-rw-r--r--tests/Makefile15
-rw-r--r--tests/README8
-rw-r--r--tests/RunTests.php100
-rw-r--r--tests/SanitizerTest.php65
-rw-r--r--tests/SearchEngineTest.php135
-rw-r--r--tests/SearchMySQL4Test.php34
-rw-r--r--tests/test-prefetch-current.xml75
-rw-r--r--tests/test-prefetch-previous.xml57
-rw-r--r--tests/test-prefetch-stub.xml75
-rw-r--r--thumb.php91
-rw-r--r--trackback.php68
-rw-r--r--wiki.phtml4
937 files changed, 282071 insertions, 0 deletions
diff --git a/AdminSettings.sample b/AdminSettings.sample
new file mode 100644
index 000000000000..1670cf5e6c0d
--- /dev/null
+++ b/AdminSettings.sample
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file should be copied to AdminSettings.php, and modified
+ * to reflect local settings. It is required for the maintenance
+ * scripts which run on the command line, as an extra security
+ * measure to allow using a separate user account with higher
+ * privileges to do maintenance work.
+ *
+ * Developers: Do not check AdminSettings.php into Subversion
+ *
+ * @package MediaWiki
+ */
+
+/*
+ * This data is used by all database maintenance scripts
+ * (see directory maintenance/). The SQL user MUST BE
+ * MANUALLY CREATED or set to an existing user with
+ * necessary permissions.
+ *
+ * This is not to be confused with sysop accounts for the
+ * wiki.
+ */
+$wgDBadminuser = 'wikiadmin';
+$wgDBadminpassword = 'adminpass';
+
+/*
+ * Whether to enable the profileinfo.php script.
+ */
+$wgEnableProfileInfo = false;
+
+?>
diff --git a/COPYING b/COPYING
new file mode 100644
index 000000000000..d7c31ed3f1ed
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/FAQ b/FAQ
new file mode 100644
index 000000000000..a4b54cf3e2d3
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,5 @@
+The original MediaWiki FAQ can be found at
+http://meta.wikimedia.org/wiki/MediaWiki_FAQ.
+
+A newer version is available at
+http://www.mediawiki.org/wiki/Help:FAQ.
diff --git a/HISTORY b/HISTORY
new file mode 100644
index 000000000000..302f9b0f8794
--- /dev/null
+++ b/HISTORY
@@ -0,0 +1,3345 @@
+Change notes from older releases. For current info see RELEASE-NOTES.
+
+= MediaWiki release notes =
+
+Security reminder: MediaWiki does not require PHP's register_globals
+setting since version 1.2.0. If you have it on, turn it *off* if you can.
+
+== Changes since 1.7 ==
+
+* Introduced AjaxResponse object, superceding AjaxCachePolicy
+* Changes to sajax_do_call: optionally accept an element to fill instead of a
+ callback function; take the target function or element as a third parameter;
+ pass the full XMLHttpRequest object to the handler function, instead of just
+ the resultText value; use HTTP response codes to report errors.
+* (bug 6562) Removed unmaintained ParserXml.php for now
+* History paging overlap bug fixed
+* (bug 6586) Regression in "unblocked" subtitle
+* Don't put empty-page message into view-source when page text is blank
+* (bug 6587) Remove redundant "allnonarticles" message
+* Block improvements: Allow blocks on anonymous users only. Optionally allow
+ or disallow account creation from blocked IP addresses. Prevent duplicate
+ blocks. Fixed the problem of expiry and unblocking erroneously affecting
+ multiple blocks. Fixed confusing lack of error message when a blocked user
+ attempts to create an account. Fixed inefficiency of Special:Ipblocklist in
+ the presence of large numbers of blocks; added indexes and implemented an
+ indexed pager.
+* (bug 6448) Allow filtering of Special:Newpages according to username
+* (bug 6618) Improve permissions/error detection in Special:Lockdb
+* Quick hack for extension testing: parser test doesn't create new message
+ cache object.
+* (bug 6299) Maintain parser's revision ID across recursive calls to fix
+ {{REVISIONID}} when Cite extension is used
+* (bug 6622) Removed deprecated function Image::newFromTitle
+* (bug 6627) Fix regression in Special:Ipblocklist with table prefix
+* Removed forced dereferencements (new() returns a reference in PHP5)
+* Note about $wgUploadSizeWarning using byte
+* (bug 6592) Add most viewed pages summary to Special:Statistics
+* Pre-strip characters ignored in IDNs from URLs so they can't be used
+ to break the blacklists for regular URLs
+* Fix regression in blocking of user accounts
+* (bug 6635) Fix regression searching for range blocks on Ipblocklist
+* Fix regression searching Ipblocklist with ugly URLs
+* (bug 6639) Use a consistent default for upload directories
+* Preserve entered reason when reporting unconfirmed lock on Special:Lockdb
+* (bug 6642) Don't offer to unlock the database when it isn't locked
+* cleanupTitles.php changed from --dry-run option to --fix, so default
+ behavior is now a non-invasive check as with namespaceDupes.php
+* (bug 6660) Fix behaviour of EditPage::blockedPage() when the article does
+ not exist; now doesn't show the source box if the user hasn't provided it
+ (blocked mid-edit) and the page doesn't exist
+* Improve default value of "blockedtext"
+* (bug 6680) Added localisation for Dutch bookstore list (nl)
+* Renamed maintainace script redundanttrans.php to unusedMessages.php - clearer usage
+* Fix regression which allowed some blocked users to create additional accounts
+* (bug 6657) Fix Hungarian linktrail
+* (bug 6751) Fix preview of blanked section with edit on first preview option
+* (bug 5456) Separate MediaWiki:Search into messages for both noun and verb,
+ introduced 'MediaWiki:Searchbutton'
+* Made lines from initialiseMessages() appear as list items during installation
+* Moved the bulk of the localisation data from the Language*.php files to the
+ Messages*.php files. Deleted most of the Languages*.php files.
+* Introduced "stub global" framework to provide deferred initialisation of core
+ modules.
+* Removed placeholder values for $wgTitle and $wgArticle, these variables will
+ now be null during the initialisation process, until they are set by index.php
+ or another entry point.
+* Added DBA cache type, for BDB-style caches.
+* Removed custom date format functions, replacing them with a format string in
+ the style of PHP's date(). Used string identifiers instead of integer
+ identifiers, in both the language files and user preferences. Migration should
+ be transparent in most cases.
+* Simplified the initialisation API for LoadBalancer objects.
+* Removed the broken altencoding feature.
+* Moved default user options and toggles from Language to User. Language objects
+ are still able to define default preference overrides and extra user toggles,
+ via a slightly different interface.
+* Don't include the date option in the parser cache rendering hash unless
+ $wgUseDynamicDates is enabled.
+* Merged LanguageUtf8 with Language. Removed LanguageUtf8.php.
+* Removed inclusion of language files from the bottom of Language.php. This is
+ now consistently done from Language::factory().
+* Add the name of the executing maintenance script to the debug log. Start the
+ profiler during maintenance scripts.
+* Added "serialized" directory, for storing precompiled data in serialized form.
+* Fix regression in auto-set NS_PROJECT_TALK namespace
+* Fix regression in ordering of namespaces
+* (bug 6806, 6030) Added several global JS variables for article path, user name,
+ page title, etc.
+* hooks registered with addOnloadHook are now called at the one of the html body
+ by all skins.
+* Split ajax aided search from core ajax framework. Use wgUseAjax to enable the
+ framework and wgAjaxSearch to enable the suggest feature for the search box.
+* Added experimental installer for extensions.
+ See maintenance/installExtension.php
+* Added Tajic (tg) language file.
+* (bug 6903) Added Cantonese localisation (zh-yue)
+* Fix regression in Korean and Japanese date formatting (day of week)
+* (bug 6919) Add English alias magic words for Tatar (tt) language file.
+* (bug 6753) Fixed broken Kazakh linktrail (kk)
+* (bug 6700) Added Kazakh language variants to Names.php
+* (bug 6827) some i18n specific maintenance scripts fails after merge of localisation-work branch
+* Throwed an exception for the deprecated functions OutputPage::sysopRequired and
+ OutputPage::developerRequired - use OutputPage::permissionRequired instead.
+* Removed the deprecated functions User::isSysop, User::isBureaucrat and User::isDeveloper -
+ use User::isAllowed instead.
+* (bug 769) OutputPage::permissionRequired() should suggest groups with the needed permission
+* (bug 6971) Fix regression in Special:Export history view
+* Revamped Special:Imagelist
+* (bug 7000) updated MessagesPl.php
+* (bug 6946) Fix unexpected behavior change with GET hits to Special:Export
+* (bug 1866) Improve navigation on Special:Listusers; user now a starting
+ point as with Special:Allpages, rather than a pure limit.
+* Clean up tab order on Special:Blockip
+* (bug 5969) Clean up tab order on Special:Userlogin forms
+* (bug 3512) namespaceDupes now handles spaces and initial caps properly
+* (bug 7037) Fix regression in login tab order
+* (bug 7031) Report missing email on 'email password' instead of false success
+* (bug 7010) Don't send email notifications for watched talk pages when user
+ has selected to receive only updates for their own talk page
+* Added {{CURRENTHOUR}}
+* Added [[:Image:Foo.png]] style links to the pagelinks table
+* Avoid duplicate revision imports with Special:Import
+* (bug 7054) Validate email address before sending email confirmation message
+* (bug 7061) Format title on "from (page)" links on Special:Allpages
+* (bug 7044) Introduce "padleft" and "padright" colon functions
+* Pass page title as parameters to "linkshere" and "nolinkshere" and update
+ default message text
+* Allows to upload from publicy accessible URL. Set $wgAllowCopyUploads = true ; in LocalSettings.php
+ Limited to $wgMaxUploadSize (default:100MB); URL upload is limited to sysops by default, and displayed as a second line if appropriate
+* (bug 832) Return to user page after emailing a user
+* (bug 366) Add local-system-timezone equivalents for date/time variables
+* (bug 7109) Fix Atom feed version number in header links
+* (bug 7075) List registered parser function hooks on Special:Version
+* (bug 7059) Introduce "anchorencode" colon function
+* Include SVN revision number in {{CURRENTVERSION}} output, where applicable
+* Fix bug in wfRunHooks which caused corruption of objects in the hook list
+* (bug 4979) Use simplified email addresses when running on Windows
+* (bug 4434) Show block log fragment on Special:Blockip
+* [[MediaWiki:Disambiguationspage]] may optionally contain wiki links to any number
+ of disambiguation templates.
+* [[Special:Disambiguations]] now shows pages in NS:0 that link to any pages that embed
+ any of the templates listed at [[MediaWiki:Disambiguationspage]].
+* Fix formatting of titles on Special:Undelete
+* (bug 7026) Fix action=raw&templates=expand
+* (bug 6976) Add namespace and direction classes to classic skins
+* (bug 7144) Don't "return to main" from OutputPage::loginToUse() if the the user can't
+ read the main page in the first place
+* (bug 7188) Fix minor borkage in HTMLForm
+* (bug 6675) Replaced message 'watchthis' with new message 'watchthisupload in Special:Upload
+* Add a quickie script dumpSisterSites.php for generating a page list in the
+ format for WSR-1 SisterSites support
+* (bug 7223) Monobook.js is used for site content, should not be localized
+* Set default disabled values for DjVu render options
+* Added Xml::option() for generating <option>s easily
+* Localized page numbers in drop-down for DjVu page selection
+* Fixed linktrail for vi
+* (bug 6893) "Call to a member function exists() on a non-object" on trackback.php with bad input
+* (bug 6886) PHP undefined offset on bad input to Special:Revisiondelete
+* (bug 6887) PHP error for call to getId() on bad input to Special:Revisiondelete
+* (bug 6888) PHP error for call to getTimestamp() on bad input to Special:Revisiondelete
+* (bug 7252) Use dvipng support in texvc math rastrization. dvipng is required if texvc is rebuilt.
+* (bug 7279) Use wfBaseName in place of basename() in more places
+* Clear newtalk marker on diff links with explicit current revision number
+* (bug 7064) Replace hard-coded empty message checks with wfEmptyMsg calls
+* (bug 6777) Remove some PHP 4 compat cruft
+* Add --user, --comment, and --license options to importImages.php
+* (bug 6216) The immobile namespace message does not mention the source page
+* (bug 7299) Normalize username filter on Special:Newpages
+* (bug 7306) RTL text in an LTR wiki breaks appearance of Special:Recentchanges
+* (bug 7312) Don't emit SET NAMES utf8 if connection failed
+* (bug 7305) Proper compare for bot check on RC notify, should fix overrides
+ that force edits by non-bot users to bot mode
+* Set Vary: Cookie on action=raw generated CSS and JS, to ensure that user
+ preferences don't get stuck in proxy caches for other people
+* (bug 7324) Fix error message for failure of Database::sourceFile()
+* (bug 7309) Plurals: use singular form for zero in French and Brazilian Portuguese
+* Add page_no_title_convert field to support language variant conversion
+ for page titles which shouldn't be converted on display/linking
+* Lazy extraction of text chunks in Revision objects, may reduce hits to
+ external storage when actual text content is not used
+* Added experimental $wgRevisionCacheExpiry to cache extracted revision text
+ in $wgMemc, to further reduce hits to external storage.
+ Set to 0 (disabled) by default.
+* Minor changes to the installer.
+* Remove ":" for 'youremail' and 'yourrealname' in includes/templates/Userlogin.php
+ so that ":" could be used in i18n for Special:Preferences (like 'username' and 'uid').
+* Fix layout for Special:Preferences->Date and Time (position for 'timezonetext').
+* Updates to language variant code for Serbian et al
+* (bug 6756) Enabling RTL direction for kk-cn
+* (bug 6701) Kazakh language variants in MessagesEn.php
+* (bug 7335) SVN revision check in Special:Version fails on SVN 1.4 working copy
+* (bug 6518) Replaced 'lastmodified' with 'lastmodifiedat' and 'lastmodifiedby' with 'lastmodifiedatby'
+ with seperated parameters for date and time to allow better localisation. Updated all message files
+ to display the old format for compatibility.
+* (bug 7357) Make supposedly static methods of Skin actually static
+* Added info text to Special:Deadendpages and Special:Lonelypages
+* Fix regression in cachability of generated CSS and JS for MonoBook skin,
+ while avoiding clobbering of different users' cached data
+* (bug 6849) Block @ from usernames; interferes with multi-database tools and
+ was meant to be banned years ago... For now existing accounts will not be
+ prevented fromm login.
+* (bug 6092) Introduce magic words {{REVISIONDAY}}, {{REVISIONDAY2}, {{REVISIONMONTH}},
+ {{REVISIONYEAR}} and {{REVISIONTIMESTAMP}}
+* (bug 7425) Preceeding whitespace in [[...]] breaks subpages
+* Try to reconnect after transitory database errors in dumpTextPass.php
+* (bug 6023) Fixed mismatch of 0/NULL for wl_notificationtimestamp; now notification
+ mails are working after 'Mark all pages visited' button on Special:Watchlist is clicked
+* Made {{INT:}} a core parser function instead of a special case. The syntax
+ and behaviour is largely unchanged.
+* (bug 7448) Fixing the native name for Ewe (ee)
+* (bug 6864) Replace message 'editing' with new message 'editinguser' in Special:Userrights
+ to allow better localisation
+* Add '*-summary' for special pages to MessagesEn.php to allow customizing/translation
+ directly through Special:Allmessages
+* (bug 6130, bug 5818) Replaced message 'go' with the new message 'searcharticle' in skins
+ to allow better localisation
+* Add + to $wgLegalTitleChars by default. Some sites may have occasional
+ problems with hard-to-reach pages, but it should be less trouble than
+ "I can't import dumps from Wikipedia" complaints
+* (bug 7460) Revert broken patch for bug 7226 which slows down
+ Special:Allmessages by a factor of 16
+* Committed a bunch of live hacks from Wikimedia servers
+* (bug 6889) PHP notices in thumb.php with missing params
+* Cleaner error behavior on thumb.php with invalid page selection
+* (bug 6617) Validate timestamps on Special:Undelete
+* Do fewer unnecessary full writes of user rows; only update user_touched
+ for watch/unwatch, group membership change, and login operations
+* Restructured the languages directory, to avoid problems when people
+ untar MW 1.8 over the top of a 1.7 installation.
+* (bug 6890) SQL query error on bad input to Pager lists
+ due to negative LIMIT clause, caused by integer wraparound.
+* Fixed various bugs related to table prefixes, especially the interaction
+ between table prefixes and memcached, which was formerly completely broken.
+* (bug 7004) PHP iconv() notice on bad password input to Special:Userlogin.
+* (bug 6826) Extend pre-save transform context link ("pipe trick")
+ syntax to pages with commas in title
+* Use ImageMagick -thumbnail option instead of -resize to avoid including
+ excessive metadata in thumbs (requires ImageMagick 6.0.0 or newer).
+* (bug 7499) Corrections to Swedish talk namespace names
+* (bug 7508) Added option to compress HTML pages by dumpHTML.php
+* (bug 7519) Add plural in SpecialWatchlist
+* (bug 7459) Magic word variables are always case sensitive
+* Replaced {{SERVER}}{{localurl:xxx}} with {{fullurl:xxx}} in localisation files
+* Fix regression in Special:Watchlist text header
+* (bug 7510) Update article counts etc on undelete
+* (bug 7520) Update article counts on XML import
+* (bug 7526) Make $wgDefaultUserOptions work again
+* (bug 7472) Localize Help namespace for Basque
+* (bug 7529) Including a non-existent category in an article places that article in the category
+* (bug 4528) Lack of important LaTeX functions stackrel, rightleftharpoon
+* (bug 6721) missing symbols ulcorner, urcorner, llcorner, lrcorner, twoheadrightarrow, twoheadleftarrow
+* (bug 7367) Hyphens sometimes erroneously appended to equations when not converted to PNG
+* Add "title" to the opensearch link to allow automatic adding of the search engine in Firefox 2
+* (bug 7537) Add php5 to $wgFileBlacklist
+* (bug 6929) Restore AutoAuthenticate hook
+
+
+== Changes since 1.6 ==
+
+* (bug 5458) Fix double-URL encoding in block log link in contribs and contribs
+ link in block log
+* (bug 5462) Bogus missing patch warning in updater
+* (bug 5461) Use of deprecated "showhideminor" in Special:Recentchangeslinked
+* PHP warning when allow_call_time_pass_reference is off
+* Update to Finnish localization
+* (bug 5467) Link to page histories in watchlist edit mode
+* Further additions to Hebrew localisation
+* (bug 5476) Invalid xhtml in German localization
+* (bug 5479) Id translation for preferences tabs caption
+* (bug 5493) Id translation for special pages
+* Added skinname and style path parameters to CBT version of MonoBook
+* Include subversion revision number in Special:Version if available
+* (bug 5344) Fix regression that broke slashes in extension tag parameters
+* Improve Special:Log performance on big log sets
+* (bug 5507) Changed mediawiki:logouttext from plain to wikitext
+* (bug 4760) Prevent creation of entries in protection log when protection
+ levels haven't changed
+* (bug 861) Show page protection/unprotection events in histories
+* (bug 5499) Don't clear the tag strip state when asked not to clear state.
+ Fixes regression with use of <ref> in a template breaking <nowiki> etc.
+* Minor improvements to English language files
+* Display the anon talk page info message on anon talk pages again
+ (moved outside the parser cache)
+* Optional {{DISPLAYTITLE|title with markup}} magic word
+ Deactivated by default, set "$wgAllowDisplayTitle = true" in LocalSettings.php
+ to activate
+* Cleaned SpecialContributions a bit
+* Added a table to track interlanguage links
+* (bug 5544) Fix redirect arrow in Special:Listredirects for right-to-left
+ languages
+* Replace "doubleredirectsarrow" with a content language check that picks the
+ appropriate arrow
+* (bug 5537) Add stub language file for Samogitian (bat-smg); inherits
+ Lithuanian (lt)
+* Don't force edit summaries when a user is editing their own user/talk page
+* (bug 5510) Warning produced when using {{SUBPAGENAME}} in some namespaces
+* (bug 385) Installer support for PostgreSQL, fixes for PG compatibility
+* PersistentObject removed; it doesn't do anything and was broken besides.
+ All extensions using it have been corrected.
+* Propagate ISBN number for Booksources in LanguageNo.php
+* (bug 5548) Improvements to Indonesian localisation [patch: Ivan Lanin]
+* Add TALKSPACE, SUBJECTSPACE, TALKPAGENAME, SUBJECTPAGENAME (and encoded forms
+ for all) magic words
+* (bug 5403) Fix Special:Newpages RSS/Atom feeds
+* Reject malformed addresses in X-Forwarded-For entries
+* (bug 3359) Add hooks on completion of file upload
+* (bug 5559) Improve detection of ImageMagick [patch: Greg Turnquist]
+* (bug 5475) New pages feeds ignore "limit" argument
+* (bug 5184) CSS misapplied to elements in Special:Allmessages due to
+ conflicting anchor identifiers
+* (bug 5519) Allow sidebar cache to be disabled; disable it by default.
+* Maintenance script to import the contents of a text file into a wiki page
+* Add $wgReservedUsernames configuration directive to block account creation/use
+* (bug 5576) Remove debugging hack in session check
+* (bug 5426) Lowercase treatment of titles in rights log leads to broken links
+ on Special:Log
+* Minor improvements to French localisation files
+* (bug 5181) Update "nogomatch" for Slovak
+* (bug 5594) Id translation up to # Login and logout pages section
+* (bug 5536) Use content language for editing help link
+* Improvements to German localisation files
+* (bug 5570) Problems using <special page>/parameter link form for long titles
+* (bug 3884) Add $user parameter to AddNewUser hook, call it for by-email
+ registrations as well as self-registrations.
+* (bug 4327) Report age of cached data sets in query pages
+* (bug 4662) Fix Safari check in wikibits.js
+* (bug 4663) Edit toolbar enabled in compatible versions of Safari
+* (bug 5572) Edit toolbar enabled in compatible versions of Konqueror (3.5+)
+* (bug 5235) Edit toolbar tooltips no longer show JavaScript junk in Opera
+* Edit toolbar now works in pure XHTML mode (application/xhtml+xml)
+* Add watchlist clear function to allow quick purging of all items
+* (bug 5625) Additional namespace translations for Welsh
+* Add meta tag and JavaScript variables to cached special pages which provides
+ the timestamp of the last update, in YYYYMMDDHHMMSS format.
+* (bug 5628) More translations for MessagesHr.php
+* (bug 5595) Localisation for Bosnian language (bs)
+* (bug 2910) Default view preferences for watchlists
+* Add "hide bot edits from the watchlist" user preference
+* (bug 5250) Introduce Special:Unusedtemplates
+* Add user preference setting for an extended watchlist, showing all recent
+ edits up to a certain edit, and not just the latest edit..
+* Made MessageRo.php more general
+* (bug 5640) Indonesian localisation improvements
+* (bug 5592) Actions are logged with the default language for the
+ wiki, not the language of the user performing the operation.
+* (bug 5644) Error in LanguageBs.php file
+* (bug 5646) Compare for identical types in wfElement()
+* (bug 5472) Language::userAdjust()->minDiff not initialized on else condition
+* (bug 5386) LanguageMk.php: updated namespaces translations
+* (bug 5422) Stub for Romani (rmy) language which extends ro
+* Fix linktrail for LanguageSr
+* (bug 5664) Fix Bosnian linktrail
+* (bug 3825) Namespace filtering on Special:Newpages
+* (bug 1922) When Special:Wantedpages is cached, mark links to pages
+ which have since been created
+* (bug 5659) Change grammar hacks for Bosnian Wikimedia namespaces.
+ This sort of special casing should be removed and fixed properly.
+* Remove useless whitespace from Special:Brokenredirects header
+* Treat "allmessagesnotsupporteddb" as wikitext when echoing; change default
+ text
+* (bug 5497) Regression in HTML normalization in 1.6 (unclosed <li>,<dd>,<dt>)
+* (bug 5709) Allow customisation of separator for categories
+* (bug 5684) Introduce Special:Randomredirect
+* (bug 5611) Add a name attribute to the text box containing source text in
+ read-only pages
+* Indicate when a protected page is an interface message ("protectedinterface")
+* (bug 4259) Indicate when a protected page being edited is an interface message
+ ("editinginterface")
+* (bug 4834) Fix XHTML output when using $wgMaxTocLevel
+* Pass login link to "whitelistedittext" containing 'returnto' parameter
+* (bug 5728): mVersion missing from User::__sleep() leading to constant cache
+ miss
+* Updated maintenance/transstat.php so it can show duplicate messages
+* Improvements to update scripts; print out the version, check for superuser
+ credentials before attempting a connection, and produce a friendlier error if
+ the connection fails
+* (bug 5005) Fix XHTML <gallery> output.
+* (bug 5315) "Expires: -1" HTTP header made strictly valid (using 1970 date).
+* (bug 4825) note in DefaultSettings.php about 'profiling' table creation
+* Remove unneeded extra whitespace at top of Special:Categories
+* (bug 5679) time units are now using local numerals
+* (bug 5751) Updates to Portuguese localisation files
+* (bug 5741) Introduce {{NUMBEROFUSERS}} magic word
+* (bug 93) <nowiki> tags and tildes in templates
+* The returnto parameter is now actually used by SpecialUserlogin.php
+* Parser can now know that it is parsing an interface message
+* (bug 4737) MediaWiki:Viewcount supports {{PLURAL}} now
+* Fix bug in wfMsgExt under PHP 5.1.2
+* (bug 5761) Project talk namespace broken in Xal, Os, Udm and Cv
+* Rewrite reassignEdits script to be more efficient; support optional updates to
+ recent changes table; add reporting and silent modes
+* Cleaned up formatNum usage in langfiles
+* (bug 5716) Warn when a user tries to upload a file which was previously
+ deleted
+* (bug 5565) Add a class attribute to the table on Special:Allpages
+* "lang=xx" option for parser test cases to set content language
+* (bug 5764) Friulian translation updated
+* (bug 5757) Fix premature cutoff in LanguageConverter with extra end markers
+* (bug 5516) Show appropriate "return to" link on blocked page
+* (bug 5377) Do not auto-login when creating an account as another user
+* (bug 5284) Special redirect pages should remember parameters
+* Suppress 7za output on dumpBackup
+* (bug 5338) Reject extra initial colons in title
+* (bug 5487) Escape self-closed HTML pair tags
+* Add "raw suffix" magic word for some magic words, e.g. {{NUMBEROFUSERS|R}}
+ will produce a count minus formatting
+* Fix Parser::cleanSig() to use Parser::startExternalParse() and choose an
+ appropriate output format given the scope of the clean
+* (bug 5593) Change "bureaucrat log" to "rights log"
+* Show a boilerplate "(none)" in place of a blank within the log action text for
+ user rights
+* (bug 137) Commented out translations for copyrightwarning which mention GNU FDL
+* (bug 5723) Don't count pages linked to from the MediaWiki namespace as "wanted"
+* (bug 5696) Add a third parameter, $3, to "rcnote", passing the current time
+ formatted according to the current user's settings
+* (bug 5780) Thousands and decimal separators for Norwegian
+* Updated initStats maintenance script
+* (bug 5767) Fix date formats in Vietnamese locale
+* (bug 361) URL in URL, they were almost fixed. Now they are.
+* (bug 4876) Add __NEWSECTIONLINK__ magic word to force the "new section" link/tab to
+ show up on specific pages on demand
+* Bidi-aid on list pages
+* (bug 5782) Allow entries in the bad image list to use canonical namespace names
+* (bug 5789) Treat "loginreqpagetext" as wikitext
+* Sanitizer: now handles nested <li> in <ul> or <ol>
+* (bug 5796) We require MySQL >=4.0.14
+* Add 'EmailConfirmed' hook
+* New findhooks.php script to find undocumented hooks.
+* Silently ignore errors on profiling table update.
+* (bug 5801) Correct handling of underscores in Special:Listusers
+* Clean up Special:Listusers; add an "(all)" label to the group selection box
+* (bug 5812) Use appropriate link colour in Special:Mostlinked
+* (bug 5802) {{CURRENTMONTHNAME}} variable broken in Vietnamese locale
+* (bug 5817) Appropriate handling for Special:Recentchangeslinked where the target
+ page doesn't exist
+* Special:Randompage now additionally accepts English namespace name as parameter
+* (bug 2981) Really fixed linktrail for Tamil (ta)
+* Disallow substituting Special pages when included into a page
+* (bug 5587) Clean up the languages from references to the Groups special page
+* Added new group-X and group-X-member messages
+* Rewritten removeUnusedAccounts to be more efficient, print names of inactive
+ accounts
+* Redirect Special:Userlist to Special:Listusers
+* Introduce $wgAllowTitlesInSVG, which allows the <title> attribute in uploaded files
+ bearing the image/svg MIME type. Disabled by default due to the vast majority of
+ web servers being hideously misconfigured. See DefaultSettings.php for more details.
+* Changed default LocalSettings.php to append the previous include path when setting it
+* (bug 5837) Use "members" for the value descriptor in Special:Categories,
+ Special:Wantedcategories and Special:Mostlinkedcategories.
+* (bug 3309) Allow comments when undeleting pages
+* Clean up Special:Undelete a bit
+* (bug 5805) messages nbytes, ncategories can now use {{plural:}}
+* Clean up Special:Imagelist a bit
+* (bug 5838) Namespace names for Nds-NL
+* (bug 5749) Added Tyvan language files
+* (bug 5791) Fix SQL syntax in Special:BrokenRedirects, was causing incorrect data to show
+* (bug 5839) Prevent access to Special:Confirmemail for logged-out users
+* (bug 5853) Update for Portuguese messages (pt)
+* (bug 5851) Use Cyrillic for Kirghiz language name
+* (bug 5841) Allow the 'EditFilter' hook to return a non-fatal error message
+* (bug 5846) Link to individual group description pages in Special:Listusers
+* (bug 5857) Update for German localisation (de)
+* (bug 5858) Update for Russian language (ru)
+* (bug 5860) Update for Indonesian language (id)
+* (bug 1120) Update for Czech language (Cs)
+* Added many missing formatNum calls
+* Added grammar function to Belarusian (be)
+* (bug 5819) Add 'PersonalUrls' hook
+* (bug 5862) Update of Belarusian language (be)
+* (bug 5886) Update for Portuguese messages (pt)
+* (bug 5586) <gallery> treated text as links
+* (bug 5878) Update for Indonesian language (id)
+* (bug 5697) Update for Malay language (ms)
+* (bug 5890) Update for German language (de)
+* (bug 5889) Name for Sindhi language should appear as سنڌي
+* --force-normal parameter on dump scripts to force check for ICU extension
+* (bug 5895) Update for Dutch language (nl)
+* (bug 5891) Linktrail for Polish language (pl)
+* User::isBureaucrat , User::isDeveloper , User::isSysop deprecated in
+ v1.6 now die with a backtrace. They will be removed in v1.8
+* dumpTextPass now skips goes to database for entries that were blank in the
+ previous dump, as this may indicate a broken dump.
+* dumpTextPass progress includes percentage of items prefetched
+* dumpTextPass can now use 7zip files for prefetch
+* (bug 5915) Update to Indonesian localisation (id)
+* (bug 5913) Update for German localisation (de)
+* (bug 5905) Plural support for Bosnian localisation (bs)
+* Groups which won't hit the rate limiter now configurable with
+ $wgRateLimitsExcludedGroups
+* (bug 5806) {{plural:}} support instead of "twin" MediaWiki messages
+* (bug 5931) Update for Polish language (pl)
+* Ignore the user and user talk namespaces on Special:Wantedpages
+* Introduce NUMBEROFPAGES magic word
+* (bug 5833) Introduce CURRENTVERSION magic word
+* (bug 5370) Allow throttling of password reminder requests with the rate limiter
+* (bug 5683) Respect parser output marked as uncacheable when saving
+* (bug 5918) Links autonumbering now work for all defined protocols
+* (bug 5935) Improvement to German localisation (de)
+* (bug 5937) Register links from gallery captions with the parent parser output
+ object so that link tables receive those updates too
+* (bug 5845) Introduce BASEPAGENAME and BASEPAGENAMEE magic words
+* (bug 5941) Use content language when getting the administrator page title for
+ Special:Statistics
+* (bug 5949) Update to Indonesian localisation (id)
+* (bug 5862) Update of Belarusian translation (be)
+* (bug 5950) Improvements to French localisation
+* (bug 5805) {{plural:}} support for counters in some special pages
+* (bug 5952) Improvement to German localisation (de)
+* Rename conflicting metadata help message to "metadata_help" (was "metadata")
+ and treat it as wiki text
+* Improve preferences input filtering
+* Maintenance script to import multiple files into the wiki
+* (bug 5957) Update for Hebrew language (he)
+* (bug 5962) Update for Italian language (it)
+* (bug 5961) Update for Portuguese localisation (pt)
+* (bug 5849) Remove some hard-coded references to "Wikipedia" in messages
+* (bug 5967) Improvement to German localisation (de)
+* (bug 5962) Update for Italian language (it)
+* Suppress images in galleries which appear on the bad image list (when rendering
+ for a wiki page; galleries in special pages and categories are unaffected)
+* Maintenance script to remove orphaned revisions from the database
+* (bug 5991) Update for Russian language (ru)
+* (bug 6001) PAGENAMEE and FULLPAGENAMEE don't work in FULLURL and LOCALURL magic
+ words
+* (bug 5958) Switch Uzbek language name to use latin script
+* (bug 839) Add URLENCODE magic word
+* (bug 6004) Update for Polish language (pl)
+* (bug 5971) Improvement to German localisation (de)
+* (bug 4873) Don't overwrite the subtitle navigation when viewing a redirect page
+ that isn't current
+* (bug 2203) Namespace updates for Thai
+* Fix breakage in parser test suite which caused incorrect reporting of the failure of
+ {{NUMBEROFFILES}}. Now initialises the site_stats table with some dumb data. Updated
+ the expected output for {{NUMBEROFARTICLES}} to reflect this.
+* (bug 6009) Use {{ns:project}} in messages where appropriate
+* (bug 6012) Update to Indonesian localisation (id)
+* (bug 6017) Update list of bookstores in German localisation files
+* (bug 5187) Allow programmatically bypassing username validation, for scripts
+* (bug 6025) SpecialImport: wrong message when no file selected
+* (bug 6015) EditPage: add spacing in the boxes "edit is minor" and "watch this"
+* (bug 6018) Userrights: new message when no user specified ('nouserspecified')
+* (bug 2015) Add "\sim" to ~ conversion for HTML rendering
+* (bug 6029) Improvement to German localisation (de)
+* (bug 5015) Update be: magic words
+* (bug 3974) Add parameter for site URL to "passwordremindertext"
+* (bug 6039) Update for Portuguese localisation (pt)
+* (bug 764) Add CREATE TEMPORARY TABLES to default database permissions
+* Big update to Swedish localisation (sv)
+* Use appropriate HTML functions to create the tool links on image pages, so they don't
+ look garbled when tidy isn't on
+* (bug 5511) Fix URL-encoding of usernames in links on Special:Ipblocklist
+* (bug 6046) Update to Indonesian localisation (id) #15
+* (bug 5523) $wgNoFollowNsExceptions to allow disabling rel="nofollow" in
+ specially-selected namespaces.
+* (bug 6055) Fix for HTML/JS injection bug in variable handler (found by Nick Jenkins)
+* Reordered wiki table handling and __TOC__ extraction in the parser to better
+ handle some overlapping tag cases.
+* Only the first __TOC__ is now turned into a TOC
+* (bug 4610) Indicate patrolled status on watchlists and allow users to mark
+ changes as patrolled using the diff links there
+* Add 'DiffViewHeader' hook called before diff page output
+* (bug 6051) Improvement to German localisation (de)
+* (bug 6054) Update to Indonesian localisation (id) #16
+* Add {{CURRENTTIMESTAMP}} magic word
+* (bug 6061) Improper escaping in some html forms
+* (bug 6065) Remove underscore when using NAMESPACE and TALKSPACE magics.
+* (bug 6074) Correct squid purging of offsite upload URLs
+* To simplify the lives of extension developers, the logging type arrays
+ can now be appended to directly by an extension setup function. It is
+ no longer necessary to write four separate functions just to add a
+ custom log type.
+* (bug 6057) Count "licenses" as a message (and show it in Special:Allmessages)
+* Added $wgGrammarForms global
+* Fixed hardcoded 'done.' when removing watchlist entries.
+* (bug 5962) Update for Italian language (it)
+* (bug 6086) Remove vestigial attempt to call Article::validate()
+* wfHostname() function for consistent server hostname use in debug messages
+* Send thumbnailing error messages to 'thumbnail' log group
+* wfShellexec() now accepts an optional parameter to receive the exit code
+* Failed, but not zero-length, thumbnail renderings are now removed.
+ Should help clean up when rsvg fails in weird ways.
+* (bug 6081) Change description for Turkmen language
+* Increase robustness of parser placeholders; fixes some glitches when
+ adjacent to identifier-ish constructs such as URLs.
+* Shut up the parser test whining about files in a temp directory.
+* (bug 6098) Add Aragonese language support (an)
+* (bug 6101) Update for Russian language (ru)
+* Add $wgIgnoreImageErrors to suppress error messages for thumbnail rendering
+ problems. If errors are transitory, this should reduce annoying messages
+ making it into cached display.
+* (bug 6103) Wrap self-links in a CSS class ("selflink")
+* (bug 6102) For consistency with other markup, normalize all HTML-encoded
+ character entities in URLs, not just ampersands. This allows use of eg
+ &#61; when making URLs for template parameters.
+* Markup anality: escape </ as <\/ in toolbar javascript for pure correctness
+ under HTML-compatible browsers.
+* (bug 5077) Added hook 'BeforePageDisplay' to SkinTemplate::outputPage
+* Replace fatally changed 'uploadnewversion' with 'uploadnewversion-linktext'
+* (bug 472) Syndication feeds for the last few edits of page history
+* Format edit comments in Recent Changes feed
+* Switch incorrectly ordered column headers on Recent Changes feed diffs
+* (bug 6117) Use message for history feed description, add German localization
+* (bug 1017) fixed thumbnails of animated gifs.
+* Add APC as object caching option
+* Update to Albanian localization (sq)
+* (bug 6099) Introduce {{DIRECTIONMARK}} magic word (with {{DIRMARK}} as an alias)
+* Use optimized php5-only microtime()
+* Add possibility to store local message cache as PHP executable script
+* Fix profiling table definition
+* (bug 6040) Run pre-save transform before calculating the diff. when doing a
+ "show changes" operation in the editor
+* (bug 4033) Respect $wgStyleDirectory when checking available skins
+* Remove hideous backslashes from MessagesBr.php
+* Fix APC object cache issues, add functionality to installer
+* (bug 6133) Update strip state as we work. This mostly fixes extensions
+ used in Cite.php <ref> tags when Tidy is on.
+* (bug 6139) Workaround for transclusion oddities in Vietnamese upload text
+* (bug 6136) Update to Catalan language (ca)
+* Update to Japanese localization (ja)
+* Add /usr/local/bin to the diff3 search paths in the installer
+* (bug 6106) Update to Indonesian localisation (id) #17
+* (bug 6125) Add links to edit old versions to diff views
+* (bug 5127) Auto edit summary when creating/editing redirect page
+* (bug 3926) Introduce {{#language:}} magic word
+* Fix section links from edit comments for [[:Image:Bla.jpg]] in section titles
+* (bug 6126) Allow fallback to customized primary language when user language
+ message contains '-'; fixes licenses selector on Commons configuration after
+ recent addition of the message to Messages.php
+* (bug 5527) Batch up job queue insertions for, hopefully, better survivability
+ of lock contention etc. Duplicates are now removed at pop time instead of
+ at insert time.
+* When showing the "blah has been undeleted" page, make sure it's a blue link
+* parserTests.php accepts a --file parameter to run an alternate test sutie
+* parser tests can now test extensions using !!hooks sections
+* Fix oddity with open tag parameters getting stuck on </li>
+* (bug 5384) Fix <!-- comments --> in <ref> extension
+* Nesting of different tag extensions and comments should now work more
+ consistently and more safely. A cleaner, one-pass tag strip lets the
+ 'outer' tag either take source (<nowiki>-style) or pass it down to
+ further parsing (<ref>-style). There should no longer be surprise
+ expansion of foreign extensions inside HTML output, or differences
+ in behavior based on the order tags are loaded.
+* (bug 885) Pre-save transform no longer silently appends close tags
+* Pre-save transform no longer changes the case of close tags
+* (bug 6164) Fix regression with <gallery> resetting <ref> state
+* Hackaround for IE 7 wrapping bug in MonoBook footer
+* New message sp-newimages-showfrom replaces rclistfrom on special:newimages
+* Improve handling of ;: definition list construct with overlapping or
+ nested HTML tags
+* (bug 6171) Fix sanitizing of HTML-elements with an optional closing
+ tag. The sanitizer still needs to learn how to make well-formed XML
+ in this case.
+* Fix fatal error when specifying illegal name for manual thumbnail
+* (bug 6184) Use shinier Linker::userLink() to make user links in
+ Special:Undelete
+* (bug 6170) Update for Kashubian translation (csb)
+* (bug 6191) Update to Indonesian translation (id) #18
+* (bug 6114) Update to Walloon localization (wa)
+* Added $wgNamespaceRobotPolicies to allow customisation of robot policies on a
+ per-namespace basis.
+* Add <ol> to the list of block elements for doBlockLevels; avoids <p>s being
+ interspersed into your ordered lists.
+* (bug 5021) Transcluding the same special page twice now works
+* Add 'SiteNoticeBefore' and 'SiteNoticeAfter' hooks
+* (bug 6182) Date passed in "sp-newimages-showfrom" not adjusted to user time
+ preferences
+* (bug 2587) Fix for section editing with comment prefix
+* (bug 2607) Fix for section editing with mix of wiki and HTML headings
+* (bug 3342) Fix for section editing with headings wrapped in <noinclude>
+* (bug 3476) Fix for section editing with faux headings in extensions
+* (bug 5272) Fix for section editing with HTML-heading subsections
+* Fix for bogus wiki headings improperly detected with following text
+* Fix for HTML headings improperly not detected with preceding/following text
+* Section extraction and replacement functions merged into one implementation
+ on the Parser object, so they can't get out of sync with each other.
+* Edit security precautions in raw HTML mode, etc
+* (bug 6197) Update to Indonesian translation (id) #19
+* (bug 6175) Improvement to German translation (de)
+* Redirect Special:Logs to Special:Log
+* (bug 6206) Linktrail for Swedish localization (se)
+* (bug 3202) Attributes now allowed on <pre> tags
+* Sanitizer::validateTagAttributes now available to discard illegal/unsafe
+ attribute values from an array.
+* (bug 3837) Leave <center> as is instead of doing an unsafe text replacement
+ to <div class="center">. <center> is perfectly valid in the target doctype
+ (XHTML 1.0 Transitional), while the replacement didn't catch all cases and
+ could even result in invalid output from valid input.
+* (bug 4280) Use 'noindex,nofollow' instead of 'noindex,follow' for default
+ meta robots tag on diff view and special pages. Should reduce impact of
+ robots on scrolling special pages, diffs etc on sites where robots.txt
+ doesn't forbid access.
+* Regression fix: suppress warning about session failure when clicking to
+ edit with 'preview on first edit' enabled.
+* (bug 6230) Regression fix: <nowiki> in [URL link text]
+* Added AutoLoader.php, which loads classes without need of require_once()
+* (bug 5981) Add plural function Slovenian (sl)
+* (bug 5945) Introduce {{CONTENTLANGUAGE}} magic word
+* {{PLURAL}} can now take up to five forms
+* (bug 6243) Fix email for usernames containing dots when using PEAR::Mail
+* Remove a number of needless {{ns:project}}-type transforms from messages files. These
+ usages already have separate label text. Such transforms are wasteful on each page view.
+* Update to Yiddish localization (yi)
+* (bug 6254) Update to Indonesian translation (id) #20
+* (bug 6255) Fix transclusions starting with "#" or "*" in HTML attributes
+* Whitespace now normalized more or less properly in HTML attributes
+* Fix regression(?) in behavior of initial-whitespace-pre in <center>
+* (bug 6260) Update to Interlingua localization (ia)
+* Update to Vlax Romany localization (rmy)
+* Update to Latin translation (la)
+* Update to Dutch translation (nl)
+* Avoid some notices in page history with bad input
+* Use double quoted consistently on attributes in linker output; preparing
+ for new normalization code when tidy not in use
+* Replace "nogomatch" with "noexactmatch" and place the magic colon in the messages
+ themselves. Some minor tweaks to the actual message content.
+* Introduce $wgContentNamespaces which allows for articles to exist in namespaces other
+ than the main namespace, and still be counted as valid content in the site statistics.
+* (bug 5932) Introduce {{PAGESINNAMESPACE}} magic word
+* Disable $wgAllowExternalImages by default.
+* (bug 2700) Nice things like link completion and signatures now work in <gallery> tags.
+* Cancel output buffering in StreamFile; when used inside gzip buffering this
+ could cause funny timeout behavior as the Content-Length was wrong.
+* Return correct content-type header with 304 responses for StreamFile;
+ it confuses Safari if you let it return "text/html".
+* (bug 6280) Correct GRAMMAR for Slovenian localisation (sl)
+* (bug 6162) Change date format for Dutch Low Saxon (nds-nl)
+* (bug 6296) Update to Indonesian localisation (id) #21
+* Introduce EditFormPreloadText hook, see docs/hooks.txt for more information
+* (bug 4054) Add "boteditletter" to recent changes flags
+* Update to Catalan localization (ca)
+* (bug 2099) Deleted image files can now be archived and undeleted.
+ Set $wgSaveDeletedFiles on and an appropriate directory path in
+ $wgFileStore['deleted']['directory']
+* (bug 6324) Fix regression in enhanced RC alignment
+* Introduce {{NUMBEROFADMINS}} magic word
+* Update to Slovak translation (sk)
+* Update to Alemannic localization (gsw)
+* (bug 6300) Bug fixes for sr: variants
+* namespaceDupes.php can now accept an arbitrary prefix, for checking rogue
+ interwikis and such. Not yet fully automated.
+* (bug 6344) Add Special:Uncategorizedimages page
+* (bug 6357) Update to Russian translation (ru)
+* Workaround possible bug in Firefox nightlies by properly removing the
+ Content-Encoding header instead of sending explicit 'identity' value
+ in StreamFile
+* (bug 6304) Show timestamp for current revision in diff pages
+* Vertically align current version with old version header in diff display
+* (bug 6174) Remove redundant "emailforlost" message
+* (bug 6189) Show an error to an unprivilleged user trying to create account
+* (bug 6365) Show user information in the "old revision" navigation links
+* Introduce 'FetchChangesList' hook; see docs/hooks.txt for more information
+* (bug 6345) Update to Indonesian localisation (id) #22
+* (bug 6279) Add genitive month names to Slovenian localisation
+* (bug 6351) Update to German translation (de)
+* Respect language directionality when displaying arrow in Special:Brokenredirects
+* Remove unused "validation" table definitions from the schema files
+* (bug 6398) Work around apparent PCRE bug breaking section editing when
+ massively-indented preformatted text immediately followed a header
+* (bug 6392) Fix misbehaving <br /> in preferences form
+* Add translated magic words to Hebrew localization
+* (bug 6396) Change name for Chuvash language
+* Introduce optional (off by default) language selector bar for user login
+ and registration. Customisable via the "loginlanguagelinks" message, the
+ links will preserve "returnto" values. If the user creates an account while
+ using such a link, then the language in use will be saved as their language
+ preference.
+* Make sure '~~~' '~~~~' '~~~~~' are removed in Nickname preference.
+* Rename "ipusuccess" to "unblocked", change the format (now wiki text)
+* (bug 2316) Add "caption" attribute to <gallery> tag
+* Allow setting the skin object that ImageGallery will use; needed during parse
+ operations (the skin must come from the ParserOptions, not $wgUser)
+* Fix notice in MacBinary detection debug data for files of certain lengths
+* (bug 6131) Add type detection for DjVu files, allowing them to be uploaded
+ with validity checking and size detection. No inline thumbnailing yet,
+ but could be added in the future.
+* (bug 6423) Don't update newtalk flag if page content didn't change (null edits
+ were causing the newtalk flag to trigger inappropriately)
+* Parser functions are now set using magic words.
+* (bug 6428) Incorrect form action URL on Special:Newimages with hidebots = 0 set
+* (bug 4990) Show page source to blocked users on edits, or their modified version
+ if blocked during an edit
+* (bug 5903) When requesting the raw source of a non-existent message page,
+ return blank content (as opposed to the message key)
+* Improve default blank content of MediaWiki:Common.css and MediaWiki:Monobook.css
+* (bug 6434) Allow customisation of submit button text on Special:Export
+* (bug 6314) Add user tool links on page histories
+* Fix display of file-type icons in galleries when $wgIgnoreImageErrors is off
+* (bug 6438) Update to Indonesian translation (id) #23
+* Adding the language code parameter to the hook "LanguageGetMagic", to allow
+ localizble extensions magic words.
+* Update to Romanian translation (ro)
+* Update to Esperanto translation (eo)
+* Check for preg_match() existence when installing and die out whining about PCRE
+ if it's not there, instead of throwing a fatal error
+* (bug 672) Add MathAfterTexvc hook
+* Update to Piedmontese localization (pms)
+* dumpBackup can optionally compress via dbzip2
+* (bug 2483) Run link updates on change via XML import
+* (bug 2481) List imported pages during Special:Import
+* (bug 2482) Log and RC entries for Special:Import events
+* Allow fetching all revisions from transwiki Special:Import
+* Allow fetching all revisions from Special:Export GET request
+* Disable output buffering on Special:Export; should help with streaming
+ large numbers of history items.
+* Allow setting a maximum number of revisions for history Special:Export;
+ pages with more than $wgExportMaxHistory revisions are excluded from
+ export when history is requested.
+* Fix transwiki import of pages with space in name
+* Save null edit when importing pages through Special:Import
+* Update to Korean translation (ko)
+* Show a more specific message when an anonymous user tries to access Special:Watchlist
+* (bug 3278) Paging links in Special:Prefixindex
+* Added Latvian localization (lv)
+* (bug 6472) Fix regression in Special:Export with multiple pages
+* Update to Macedonian translation (mk)
+* Allow page moves over historyless self-redirects. Such are usually created
+ as part of namespace rearrangements, and it's easier to clean them up if
+ we can move over them.
+* Show some error results in moveBatch.php
+* (bug 6479) Allow specification of the skin to use during HTML dumps
+* (bug 6461) Link to page histories in Special:Newpages
+* (bug 6484) Don't do message transformations when preloading messages for editing
+* (bug 6201) Treat spaces as underscores in parameters to {{ns:}}
+* (bug 6006) Allow hiding the password change fields using an authentication plugin
+* (bug 6489) Use appropriate link colour on Special:Shortpages
+* Added formatnum magic word
+* Added Javanese localization (jv)
+* (bug 6491) Apply bad image list in category galleries
+* (bug 6488) Show relevant log fragment in Special:Movepage
+* Fix potential PHP notice in Special:Blockme when $wgBlockOpenProxies is true
+* Use mysql_real_escape_string instead of addslashes for string escaping in
+ the MySQL Database class. This may fix some rare breakage with binary fields.
+ Note that MediaWiki does not support the multibyte character sets where a
+ "dumb" byte replacement can be actively dangerous; UTF-8 is always safe
+ in this regard due to the bit patterns which make head and tail bytes
+ distinct.
+* (bug 6497) Use $wgMetaNamespaceTalk for Esperanto if set
+* (bug 6498) Use localized forms for image size in Special:Undelete
+* (bug 6485) Update to Indonesian translation (id) #24
+* Extension messages translation is now possible.
+* Add target namespace override selector for transwiki imports.
+ $wgImportTargetNamespace specifies the default, to be used for
+ Wiktionary's 'Transwiki:' namespace etc.
+* (bug 6506) Update to German localisation (de)
+* (bug 502) Avoid silly tabs on bad title by using virtual special page
+* (bug 6511) Add diff links to old revision navigation bar
+* (bug 6511) Replace 'oldrevisionnavigation' message with 'old-revision-navigation'
+* Fix regression in Polish genitive month forms
+* (bug 4037) Make input handling in Special:Allpages and Special:Prefixindex
+ more consistent: Accept just a namespace prefix and a colon, reject input
+ with interwiki prefixes, otherwise do what Title::makeTitleSafe() does.
+* (bug 6516) Update to Russian translation
+* New 'allpagesbadtitle' message for Special:Allpages, based on 'badtitletext'.
+* Rename "searchquery" to "searchsubtitle" and support wiki text in it
+* Introduce updateArticleCount maintenance script which uses a better check that
+ reflects what Article::isCountable() tests for
+* Introduce 'BadImage' hook; see docs/hooks.txt for more information
+* Add "searchsubtitleinvalid" message for searches that are not valid titles.
+* (bug 5962) Update to Italian localisation
+* (bug 6530) Update to Indonesian localisation (id) #25
+* (bug 6523) Fix SVG issue in rebuildImages.php
+* (bug 6512) Link to page-specific logs on page histories
+* (bug 6504) Allow configuring session name with $wgSessionName
+* (bug 6185) Add standard user tool links to log page views
+* Update to Venetian translation (vec)
+* Update to Slovenian translation (sl)
+* Add standard user tool links to deleted revision list
+* Separate out EditPage's getContent bits from regular Article getContent.
+ Cleans up read-only-mode warning on empty pages and neats up some code.
+* (bug 6565) Strict JavaScript writing
+* (bug 6570) Update to Indonesian localisation (id) #26
+* Added Telugu translation (te)
+* Update to Catalan translation (ca)
+* (bug 6560) Avoid PHP notice when trimming ISBN whitespace
+* Added namespace translation to Kannada (ka)
+* (bug 6566) Improve input validation on timestamp conversion
+* Implicit group "emailconfirmed" for all users whose email addresses are confirmed
+* (bug 6577) Avoid multiline parser breakage on <pre> with newline in attribute
+* (bug 6771) Make old revisions of MediaWiki pages available with action=raw
+
+== Changes since 1.5 ==
+
+* (bug 2885) More PHP 5.1 fixes: skin, search, log, undelete
+
+Code quality:
+* Use strval() to make sure we don't accidentally get null on bad revision
+ text loads or other fields mucking up XML export output
+* Clean up duplicate code for selection of changeslist style
+* Correct blob caching to reduce redundant blob loads on backups
+* (bug 3182) Clear link cache during import to prevent memory leak
+* Fixed possible infinite loop in formatComment
+* Wrap message page insertions in a transaction to speed up installation
+* Avoid notice warning on edit with no User-Agent header
+* (bug 3649) Remove obsolete, broken moveCustomMessages script
+* Avoid numerous redundant latest-revision lookups in history
+* Require PHP 4.3.2 or higher strictly now.
+* Tweak infinite-template-handling loop for PHP 5.1.1 string handling change
+* Remove unused OutputPage::addCookie()
+* Fix for short_open_tag off again; please don't break this, guys
+* (bug 4507) Adjust FULLPAGENAMEE escaping to standard form
+* (bug 5302) Merge the two #p-search .pBody statements in monobook css.
+
+Database:
+* Finally dropped MySQL 3.23.x support
+* Oracle support
+* (bug 3056) MySQL 3 compatibility fix: USE INDEX instead of FORCE INDEX
+* Update all stats fields on recount.sql
+* (bug 3227) Fix SQL injection introduced in experimental code
+* Fix table prefix usage in Block::enumBlocks
+* (bug 3448) Set page_len on undelete
+* (bug 3506) Avoid MySQL error when Listusers returns no results
+* Skip update of disused 'rc_cur_time' field (todo: discard the field)
+* (bug 3735) Fix to run under MySQL 5's strict mode
+* (bug 3786) Experimental support for MySQL 4.1/5.0 utf8 charset mode
+ NOTE: Enabling this may break existing wikis, and still doesn't
+ work for all Unicode characters due to MySQL limitations.
+* MySQL 5.0 strict mode fix for moving unwatched pages
+* Ability to set the table name for external storage servers
+* Update ipblocks table in MySQL 5 table defs
+* Removed FulltextStoplist.php, no longer used (was for MySQL 3.x workaround)
+* Added templatelinks table, to track template inclusions. User-visible effects
+ will be:
+ * (inclusion) tag for inclusions in Special:Whatlinkshere
+ * More accurate list of used templates on the edit page
+ * More reliable cache invalidation when templates outside the template
+ namespace are changed
+* Respect database prefix in dumpHTML.inc
+* Removed read-only check from Database::query()
+* Added externallinks table, to track links to arbitrary URLs
+* Added job table, for deferred processing of jobs. The immediate application is
+ to complete the link table refresh operation when templates are changed.
+* Don't change the password of the MySQL root user.
+
+Documentation:
+* (bug 3306) Document $wgLocalTZoffset
+
+Hooks:
+(list not complete)
+* Move ArticleSave hook execution into Article insert/update functions,
+ so they get called on non-EditPage actions that use these functions
+ to create or update pages.
+* Added EditFilter hook, and output callback on EditPage::showEditForm()
+ for a place to add in captcha-type extensions in the edit flow
+* (bug 3684) Fix typo in fatal error backtraces in Hooks.php
+* Fix for hook callbacks on objects containing no fields
+* Add a hook for additional user creation throttle / limiter extensions
+* Use $wgOut->parse() in wfGetSiteNotice() instead of creating a new parser
+ instance. This allows use of extension hooks if required.
+* Added AutoAuthenticate hook for external User object suppliers
+* Added 'PageRenderingHash' hook for changing the parser cache hash key
+ from an extension that changes rendering based on nonstandard options.
+* Add 'GetInternalURL' hook to match the GetFullURL and GetLocalURL ones
+* (bug 4456) Add hook for marking article patrolled
+* Add UserRights hook, fires after a user's group memberships are changed
+
+Images:
+* Support SVG rendering with rsvg
+* Cap arbitrary SVG renders to given image size or $wgSVGMaxSize pixels wide
+* (bug 3127) Render large SVGs at image page size correctly
+* Fix scaling of non-integer SVG unit sizes
+* (bug 2800) Don't scale up small images on |thumb| without explicit size
+* Use the real file link instead of the default-size rasterized version for
+ large SVG images on image description page
+* Include the file name/type/size line for non-resized images
+* (bug 3489) PHP 5.1 compat problem with captioned images
+* (bug 3643) Fix image page display of large images with resizing disabled
+* Added a limit to the size of image files which can be thumbnailed
+* (bug 3806) Gracefully fall back to client-side scaling on |thumb| image
+ that passes $wgMaxImageArea
+* (bug 153) Adjust thumbnail size calculations to match consistently;
+ patch by David Benbennick
+* (bug 4162) Add $wgThumbnailEpoch timestamp to force old thumbs to
+ be rerendered on demand, sitewide
+* (bug 1850) Additional fixes so existing local and remote images
+ get a blue link even if there's no local description page
+* Avoid FATAL ERROR when creating thumbnail of non-existing image
+* (bug 4207) Wrong image size when using 100x200px syntax to scale image up
+ patch by David Benbennick
+* Don't delete thumbnails when refreshing exif metadata. This caused thumbs
+ to vanish mysteriously from time to time for files that didn't have metadata.
+* (bug 4426) Add link to user_talk page on image pages
+* Support a custom convert command for thumbnailing. See DefaultSettings.php
+ and the comments for $wgCustomConvertCommand, for more information.
+* UserCan hook now allows advisory return values, rather than mandatory ones.
+
+Installer:
+* (bug 3782) Throw fatal installation warning if mbstring.func_overload on.
+ Why do people invent these crazy options that change language semantics?
+* Fixed installer bugs 921 and 3914 (issues with using root and so forth)
+* (bug 4258) Use ugly urls for ISAPI by default
+ patch by Rob Church
+* Improve installer
+ * Use a superuser account (such as root), if specifed, to create tables
+ * Don't overwrite conservative permissions on the mySQL user with ALL
+ permissions, if said user exists
+ * Changes to some of the wording of explanations for fields
+* (bug 1734) granting db permissions failed with db usernames containg '-'
+* Add basic check for session support in PHP and die if not present
+
+Maintenance:
+* Fix problem reported on mailing list where re-initialising stats didn't work (can't insert
+ duplicate rows with the same id field)
+* Added --conf option to command line scripts, allowing the user to specify a
+ different LocalSettings.php.
+* Maintenance script to delete unused text records
+* Maintenance script to delete non-current revisions
+* Maintenance script to wipe a page and all revisions from the database
+* Maintenance script to reassign edits from one user to another
+* Maintenance script to find and remove links to a given domain (cleanupSpam.php)
+* Fix --report interval option for dumpTextPass
+
+i18n / Languages:
+* Partial support for Basque language (from wikipedia and meta)
+* (bug 3141) Partial support for Breton language (thanks Fulup).
+* Support for venitian language
+* (bug 1334) LanguageGa.php update
+* Finnish date format was hardcoded, now implemented properly
+* (bug 3190) Added some date format choices for language sr
+* (bug 2753) Some namespaces were not translated in LanguageTa.php (Tamil)
+* (bug 3204) Fix typo breaking special pages in fy localization
+* (bug 3177) Estonian date formats not implemented in LanguageEt.php
+* (bug 1020) Changing user interface language does not work immediately
+* (bug 3271) Updated LanguageNn.php for HEAD
+* Experimental feature to allow translation of block expiry times
+ Implementation only for Finnish currently
+* (bug 3304) Language file for Croatian (LanguageHr.php)
+* (bug 2143) Update Vietnamese interface
+* (bug 3063) Remove some hardcodings from Hebrew localisation
+* (bug 3408) Bulgarian formatNum corrected
+* (bug 1512) Disable x-code interp on Esperanto URLs for now, it does more
+ harm than good under current system by breaking incoming URLs with "ux".
+ (Editing is not affected, just URLs.)
+* (bug 1423) LanguageJa.php update
+* Fix language name for dv
+* (bug 3503) Update LanguageSq.php from sq.wikipedia.org messages
+* (bug 3629) Fix date & time format for Frisian
+* (bug 3334) Namespace changes for Polish
+* (bug 3580) Change default Dutch language file to more neutral
+* (bug 3656) LanguageHr.php - added convertPlural
+* (bug 3414) LanguageBe.php - added convertPlural
+* (bug 3163) Full translation of LanguageBr
+* (bug 3617) Update for portuguese language (pt)
+* Namespaces hacks on LanguagePl
+* (bug 3682) LanguageSr.php - added convertPlural
+* (bug 3694) LanguageTr.php update
+* (bug 3711) Removed invisible unicode characters from LanguageHu
+* (bug 2981) Linktrail for Tamil (ta)
+* (bug 3722) Update of Arabic language (ar) Namespace changes
+* Removed hardcoded Norwegian (no) project namespaces
+* (bug 2324) image for redirects should be without text and oriented according to content language
+* (bug 3666) Don't spew PHP warnings in prefs on unrecognized site language
+* (bug 3817) Use localized date formats in preferences; 'no preference' option
+ localizable as 'datedefault' message. Tweaked lots of languages files...
+* (bug 2721) Regression: Use European number separators for vi: wikis
+* (bug 3961) minor languageDe changes
+* (bug 1984) LanguageKo.php (Korean) update
+* (bug 3804) update of LanguageWa.php file
+* (bug 3886) Update for Portuguese language (pt)
+* (bug 4020) Update namespaces for ms
+* (bug 3922) bidi embedding overrides on category links
+* (bug 4061) Update of Slovene namespace names (LanguageSl.php)
+* (bug 4064) LanguageDe comma changes
+* (bug 3922) Further tweaks to bidi overrides in category list for old
+ versions of Safari and Konqueror
+* Fix custom namespaces on wikis set for Portuguese
+* (bug 4153) Fix block length localizations in Greek
+* (bug 3844) ab: av: ba: ce: & kv: now inherit from LanguageRu.php
+ ii: & za: now inherit from LanguageZn_cn.php
+* (bug 4165) Correct validation for user language selection (data taint)
+* (bug 4192) Remove silly 'The Free Encyclopedia' default sitesubtitle
+* Use content-lang for sitenotice
+* (bug 4233) Update LanguageJa.php
+* (bug 4279) Small correction to LanguageDa.php
+* (bug 4108, 4336) Remove trailing whitespace from various messages, which
+ mucks up message updating to create dupe entries
+* (bug 4389) Fix math options on zh-hk and zh-tw (but not localized)
+* (bug 4392) Update of LanguageSr.php
+* (bug 4382) Frisian numeric format
+* (bug 4424) Update for Spanish language (es) 100% messages translated
+* (bug 4425) Typos in Polish translation
+* (bug 4436) Update for Turkish language (tr)
+* (bug 4413) Update of Farsi language file (LanguageFa.php)
+* Update for LanguageSr (Serbian): magic words
+* (bug 137) MediaWiki:Copyrightwarning hardcoding
+* (bug 4457) Update for Portuguese language (pt)
+* convertPlural breakage fixed a little
+* (bug 4144) Support for Sudanese language (Basa Sunda)
+* Big cleanup:
+ - Removed obsolote, badly or untranslated messages
+ - Removed references to wikipedia/wikimedia etc in messages
+ - Other cleanup, like removing html and javascript and extension calls
+ - Removed hardcoded namespaces: Tt, Ms, Ia, Ga, Fo, Bn, Csb, He, Nv, Oc, Tlh
+ - Removed some useless backwards compatibility hacks
+ - Fixed formatnum on many languages
+* wgAmericanDates check produced incorrect results in languages that don't have
+ a such distinction
+* (bug 4548) Update for Portuguese language (pt): time format
+* (bug 4530) Use consistent name for Kurdish
+* Tweak default "upload disabled" text
+* (bug 4504) Use site language for namespace name resolution
+* (bug 4510) Correct Barnes & Noble bookstore URLs
+* (bug 3991) Allow the operation of wikicode on Protect move only text
+* (bug 4267) Switch dv sd ug ks arc languages to RTL
+* Default main page content improved per bug 4690
+* (bug 4615) Update for Portuguese language (pt)
+* Separated MessagesSl.php as the other languages.
+* (bug 4960) Add additional namespaces variants to Yiddish for compatibility
+* (bug 4805) Removed more wikipedia-references from MessagesUk.php
+* (bug 5015) Update magic words translation in LanguageBe.php
+* (bug 4859) Update for Portuguese messages (pt)
+* (bug 4788) One string for MessagesPl
+* Restriction types now use restriction-* messages instead of ui messages
+* (bug 4685) Slovenian LanguageSl.php hardcodes project namespace
+* (bug 5097) Fix Hungarian language (hu): thousands separator
+* (bug 5098) Update for Portuguese messages (pt)
+* (bug 5113) Spelling error in French language file
+* (bug 5105) Magic words for LanguageAr.php
+* (bug 3993) Variants for Serbian language
+* Typo in English messages file
+* (bug 4114) Spacing in watchlist rows (in editing mode)
+* Update default "exporttext" to reflect that Special:Import exists
+* (bug 4960) Add additional namespaces variants to Yi projects: Yiddish Wikinews fix
+* (bug 5357) Add the icon near the user name also in RTL interfaces
+* (bug 5156) Update for Hebrew language (he)
+* (bug 4497,4704,5010) Added some new language codes.
+* (bug 5362) Piedmontese added
+* (bug 5349) Update for Portuguese messages (pt)
+* (bug 3573) Finished full Greek translation: namespaces
+* (bug 5288) Initial localisation for Az
+* (bug 4361) Fix "allmessagesnotsupportedui" so it doesn't refer to nonexisting
+ page
+* Tweak wording of "allmessagesnotsupporteddb"
+
+Parser:
+* (bug 2522) {{CURRENTDAY2}} now shows the current day number with two digits
+* (bug 3210) Fix Media: links with remote image URL path
+* (bug 3405) Don't use raw letters as aliases of MSGNW: and SUBST:
+* (bug 3412) Clean up date format handling so ~~~~-sigs work with default
+ format as designed. Documentation comments updated.
+* Fix Parser::unstrip on PHP 5.1.0RC4
+* (bug 3797) Don't expand variables and sigs in comments
+* Allow parser cache on redirect targets
+* Run wikitext-escaping on plaintext sigs (no wiki markup, just name)
+* Check for unbalanced HTML tags on raw sigs (markup allowed, but show
+ a warning in prefs and use default sig if not balanced)
+* Respect <noinclude> and <includeonly> during {{subst:}} expansion as well as
+ ordinary templates.
+* Support <includeonly> in templates loaded through preload= parameter
+* (bug 3979) Save correct {{REVISIONID}} into parser cache on edit
+* Substitute {{REVISIONID}} correctly in diff display
+* (bug 1850) Allow red-links on image pages linked with [[:image:foo]]
+* Fix XML validity checks in parser tests on PHP 5.1
+* (bug 4377) "[" is not valid in URLs
+* (bug 4453) fix for __TOC__ dollar-number breakage
+* Convert unnecessary URL escape codes in external links to their equivalent
+ character before doing anything with them. This prevents certain kinds of
+ spam filter evasion.
+* (bug 4783) : Fix for "{{ns:0}} does not render"
+* Improved support for interwiki transclusion
+* (bug 1850) Image link to nonexistent file fixed.
+* (bug 5167) Add {{SUBPAGENAME}} and {{SUBPAGENAMEE}} variables
+* (bug 4949) Missing : in "addedwatchtext" for English and Spanish
+* Allow user-defined functions, which work in a similar way to {{GRAMMAR:}}
+ etc. Registered via an interface similar to tag hooks.
+
+Upload:
+* (bug 2527) Always set destination filename when new file is selected
+* (bug 3076) Support MacBinary-encoded uploads from IE/Mac
+* (bug 2554) Tell users they are uploading too large file
+* Support for a license selection box on Special:Upload, configurable from MediaWiki:Licenses
+* Add 'reupload' and 'reupload-shared' permission keys to restrict new uploads
+ overwriting existing files; default is the old behavior (allowed).
+
+Security:
+* (bug 3244) Fix remote image loading hack, JavaScript injection on MSIE
+* (bug 3280) Respect 'move' group permission on page moves
+* (bug 2613) Clear saved passwords from the form
+* IP privacy fix for blocklist search on autoblocks
+* Security fix for <math>
+* Security fix for tables
+* Security fix for Special:Upload license selection list
+* Add UploadVerification hook for custom file upload validation/security checks
+* Blacklist additional MSIE CSS safety tricks
+* Fix meta robots tag on Special:Version again to avoid listing vulnerable
+ versions for convenient harvesting by automated worms
+* Sanitizer CSS comment processing order fix
+* Forbid usernames that can be interpreted as titles with namespaces, as that
+ leads to hard-to-manage names.
+* (bug 4071) Generate passwords long enough for $wgMinimalPasswordLength
+* Add createpage and createtalk permission keys, allowing a quick
+ switch to disable page creation for anonymous users.
+* (bug 675) Add page protection level for unregistered/new accounts
+* User::isNewbie now uses the registration date and $wgAutoconfirmAge
+* Add 'deletedhistory' permission key for ability to view deleted history
+ list via Special:Undelete. Default is off, replicating the 1.5 behavior,
+ but it can be turned back on for random users to replicate the previous
+ 1.6 dev behavior.
+* Set cookies to secure mode based on use of HTTPS or $wgCookieSecure
+* (bug 4371) Disallow tilde character in signatures
+* Removed broken wgAllowAnonymousMinor and added new group right minoredit
+* Added detection for WMF files (application/x-msmetafile), added this
+ MIME type to the default blacklist. Prevented inline display of images
+ which are not of known image types. This is in response to
+ http://en.wikipedia.org/wiki/Windows_Metafile_vulnerability
+* Blocked users can no longer roll back, change the protection of, or delete/undelete pages
+* Protect against spoofing of X-Forwarded-For header
+* XSS issue : now sanitize search query input (fixed in 1.5rc3)
+* Remove deprecated $wgOnlySysopsCanPatrol references; use User::isAllowed( 'patrol' )
+ per bug 5282. Patch by Alan Harder.
+* Prevent registration/login with the username "MediaWiki default"
+
+Special Pages:
+* Rearranged Special:Movepage form to reduce confusion between destination
+ title and reason input boxes
+* (bug 1956) Hide bot uploads from Special:Newimages
+* (bug 3220) Fix escaping of block URLs in Recentchanges
+* (bug 3284) Ipblocklist paging, substring search
+* Allow filtering of robot edits in Special:Watchlist by stting
+ $wgFilterRobotsWL = true.
+* Fix interlanguage links on special pages when extra namespaces configured
+* (bug 3475) anon contrib links on Special:Newpages
+* Special:Import/importDump fixes: report XML parse errors, accept <minor/>
+* (bug 2369) Add separate message for input box on Special:Prefixindex
+* (bug 3798) DoubleRedirects no longer has hard coded arrows
+* (bug 3803) Fix links on Special:Wantedcategories with miser mode off
+* Fix Special:BrokenRedirects on MySQL 5.0
+* (bug 3807) Fix 'all' in namespaces drop-down on contribs, rc
+* Fail gracefully on invalid namespace in Special:Newpages
+* (bug 3762) Define missing Special:Import UI messages
+* (bug 3761) Avoid deprecation warnings in Special:Import
+* (bug 2894) Enhanced Recent Changes link fixes
+* (bug 4059) fix 'hide minor edits' on Recentchangeslinked
+* (bug 146) List number of category members in Special:Categories
+ (patch by Joel Nothman)
+* (bug 4090) Fix diff links in Special:Recentchangeslinked
+* (bug 4093) '&bot=1' in Special:Contributions now propagate to other links
+* Fix display of old recentchanges records for page moves
+* (bug 360) Let Whatlinkshere track [[:image:foo]] links
+* (bug 3073) Keep search parameter on paging in Special:Newimages
+* Removed Special:Validate, it's been superseded by the Review extension
+* (bug 4359) red [[user:#id]] links generated in [[special:Log]]
+* (bug 1996) Special page to list redirects
+* (bug 4334) Add "watch" links to Special:Unwatchedpages
+* Generate target user page links in Special:Ipblocklist where appropriate
+ (i.e. not an autoblock)
+* Generate link to talk page of the blocker in Special:Ipblocklist, move
+ contribs. link of the target next to their name
+* (bug 2714) Backlink from special:whatlinkshere was hard set as 'existing'
+* Move parentheses out of <a> link in Special:Contributions
+* (bug 3192): properly check 'limit' parameter on Special:Contributions
+* (bug 3187) watchlist text refer to unexistent "Stop watching" action
+* Add block, block log and general log links to Special:Contributions
+* Add contributions link to block log items
+* Added optional "hide own edits" feature to Special:Recentchanges
+* (bug 5018) Anchors for each message in Special:Allmessages
+* Introduce $wgWantedPagesThreshold per bug 5011; Special:Wantedpages will not
+ list pages with less than this number of links. Defaults to 1.
+* (bug 4319) Don't show a "create account" link on the login form when
+ account creation is disabled.
+* JavaScript filter for Special:Allmessages
+* (bug 3047) Don't mention talk pages on Special:Movepage when there isn't one
+* Show links to user page, talk page and contributions page on Special:Newpages
+* Special:Export can now export a list of all contributors to an article (off by default)
+* (bug 5372) Add number of files to Special:Statistics
+* (bug 2871) Links to talk pages in watchlist editing view
+* (bug 5385) Allow hiding anonymous edits on Special:Recentchanges
+* (bug 2544) Illogical error reporting order in Special:Userlogin
+* (bug 5409) Hide "show/hide patrolled edits" in Special:Recentchanges if patrolling
+ is disabled
+* (bug 5447) Convert first letter of username to uppercase before searching in Special:Listusers
+* (bug 759) Wrap redirects on the watchlist editing page in a span, class "watchlistredir"
+* (bug 1862) Namespace filtering in watchlists
+
+Misc.:
+* PHP 4.1 compatibility fix: don't use new_link parameter to mysql_connect
+ if running prior to 4.2.0 as it causes the call to fail
+* (bug 3117) Fix display of upload size and type with tidy on
+* (bug 2323) Remove "last" tabindex from history page
+* (bug 3116) Division by zero on [[Image:Foo.png|123x123px|]]
+* Fix display of read-only lockfile message
+* Include software-visible client IP address in Special:Version comment
+ as a proxy debugging aid
+* (bug 3170) Page Title failed to obey MediaWiki:Pagetitle.
+ wikititlesuffix was removed
+* Add ability to break off certain debug topics into additional log files;
+ use $wgDebugLogGroups to configure and wfDebugLog() to log.
+* Edit conflict on recreation of deleted page
+* (bug 3216) Don't show empty warning page when no warnings.
+* (bug 3218) Use proper quoting on history Compare Revisions button
+* Fix upgrade from 1.4 due to version number check breakage [for rc future]
+* Fix upgrade from 1.4 with no old revisions
+* Remove "info" editing toolbar that was shown in browsers which do not
+fully support the editing toolbar, but was found to be too confusing.
+* Don't override edit conflict suppression on section edits; section merging
+ should provide the expected transparency here and fits usage patterns better.
+* (bug 3292) Fix move-over-redirect test when current entries are not plaintext
+* (bug 2078) Don't hide watch tab on preview
+* Fix regressions in ChangesList traditional layout
+* Fix edit on double-click for move-protected pages in Classic skin
+* (bug 3485) Fix bogus warning about filename capitalization when off
+* (bug 2570) Add 'watch this page' checkbox on uploads, watch uploads
+ by default when 'watchdefault' option is on
+* Add options to dumpBackup.php for making split/partial dumps by page id
+* Added filter options, compression piping, and multiple output streams for
+ dumpBackup.php
+* (bug 3595) Warn and abort if importDump.php called in read-only mode.
+* (bug 3598) Update message cache on message page deletion, patch by Tietew
+* Added separate noarticletext and newarticletext messages for logged in and anon users.
+* (bug 3332) Installation now uses Monobook, validates, plus usability improvements.
+* (bug 3660) Update diff3 detection to work with Windows/Cygwin
+* (bug 2330) Don't do funny thinks with "links" in MediaWiki:Undeletedtext
+* Two-pass data dump for friendliness to the DB (--stub, then dumpTextPass.php)
+* Data dump 'prefetch' mode to read normalized text from a prior dump
+ (requires PHP 5, XMLReader extension)
+* (bug 2773) Print style sheet no longer overrides RTL text direction
+* (bug 2938) Update MediaWiki:Exporttext to be more general
+* Various fixes
+* Fix wfMsg*() replacements; args containing literal $[2-9] were wiped
+* Added @import for [[MediaWiki:Common.css]] to all skins
+* Edit box now remembers scrollbar position on preview
+* (bug 3816) Throw edit conflict instead of fatal error when a page is
+ moved or deleted during section edit
+* (bug 3771) Handle internal functions in backtrace in wfAbruptExit()
+* (bug 3291) 'last' diff link for last history line when not at end
+* (bug 3667) Add missing global in page move code
+* (bug 2885) Remove unnecessary reference parameter which broke classic skin
+ talk notification on PHP 5.0.5
+* (bug 3852) "Redirected from" link no longer obscured on double-redirects
+* changed directory hierarchy in images/math/. System upgrades from old to
+ new hierarchy on the fly.
+* (bug 3487) Fix category edit preview with preview-on-bottom
+* (bug 918) Search index incorrectly joined words at == headings ==
+* (bug 3877) Render math images into temp directory, then move to hashed
+ subdir so you can render new math images and have them work
+* (bug 2392) Fix Atom items content type, upgrade to Atom 1.0
+* Allow $wgFeedCacheTimeout of 0 to disable feed caching
+* Fix WebRequest::getRequestURL() to strip off the host bits squid prepends
+* Require POST for action=purge, to stop bots from purging the cache
+* Added local message cache feature ($wgLocalMessageCache), to reduce bandwidth
+ requirements to the memcached server.
+* (bug 3562) for go search, try Caps-Variants-Broken-At-Non-Whitespace
+* (bug 2569) Use PATH_SEPARATOR instead of trying to guess based on
+ DIRECTORY_SEPARATOR (was wrong on NetWare)
+* (bug 2740) Accept image deletions on 'enter' submit from MSIE
+* (bug 3939) Don't try to load text for interwiki redirect target
+* (bug 3948) Avoid notice warning in debug statement in bad search
+* Recognize Special:Search consistently so read whitelist works
+* (bug 3999) Change atom 1.0 feed id; had been unnecessarily complex due to
+ unclear language in the spec. Now using the URL, same as the permalink,
+ which someone else will probably whine about because it's not 'perma'
+ enough or something.
+* (bug 4014) Fix include mode for Allpages on small page sets
+* (bug 3996) Fix text for new entries in RC RSS/Atom feed
+* (bug 3065) Update both watched namespaces when renaming pages
+* Changed mail form to have a bigger message entry box (like for editing
+ a page
+* Fix ulimit parameters for wfShellExec when memory_limit is specified in 'm'
+* (bug 2111) Collapsable exif metadata table, clean up display
+* Reduce fractions in display of exif exposure time
+* (bug 4048) Optional footer link to site privacy policy
+* Don't die() when update.php reaches the end of the warning count
+* (bug 1915) Fix edit links when 'direction' used with 'oldid';
+ using revision ID reported via OutputPage; Skin::editUrlOptions()
+* Remove obsolete 'redirect=no' on some edit links
+* Include oldid for the second revision on edit link on diff view
+* (bug 4035) Fix prev/next revision links on edit page
+* (bug 4100, 3049) Add 'edittools' message to hold edit tools, put it
+ on Special:Upload as well as edit, rearrange edit page pieces a bit.
+ Copyright warning now above the buttons to ensure it's visible,
+ template list at the bottom so it can grow.
+* Optional summary parameter to action=rollback, for user javascript
+* (bug 4167) Fix regression caused by patch for bug 153
+* (bug 4169) Use $wgLegalTitleChars in pipe trick conversions
+* (bug 4170) Decode HTML character escapes in sort key
+* (bug 4201) Fix user-talk mode for Enotif, and general code cleanup
+* (bug 4214) Skip redundant action text inserts into the HTML <title>
+* (bug 4212) Skip redundant meta-robots tag for default settings
+* Fix regression: old version missing from edit links in Nostalgia skin
+* (bug 1600) Trigger edit conflict on duplicate section=new submissions
+* (bug 4001) Use local variables properly in wikibits.js akeytt()
+* Fix regression: old version missing from edit links on CSS/JS pages
+* (bug 3211) Include Date, To mail headers when using PEAR::Mail
+* (bug 3407) Fix encoding of subject and from/to headers on notification
+ mails; userMailer() now takes a MailAddress wrapper object instead of
+ a raw string to abstract things a level.
+* Fixed --server override on dumpTextPass.php
+* Added plugin interface for dumpBackup, so additional filters and output
+ sink types can be registered at runtime from an extension
+* (bug 349) Fix for some numeric differences not being highlighted
+ patch by Andrius Ramanauskas
+* (bug 4298) Include rc_id on enhanced RC singleton diff links for patrolling
+* Did some refactoring on ChangesList.php merging dupe code
+* (bug 1586) Fix interwiki generator for wikimedia obscure domains
+* (bug 3493) Mark edits patrolled when they are reverted
+ patch by Leon Planken
+* Removed experimental Amethyst skin from default set
+* Upgrade old skin preferences properly at Special:Preferences
+ (used to spontaneously switch to Classic skin for old numeric pref records)
+* (bug 3424) Update page_touched for category members on category page creation
+* Log views show message when no matches
+* Fix raw sitenotice display on database error
+* Fix autoconfirm check for old accounts
+* (bug 4368) Don't show useless empty preview on new section creation
+* Don't show useless empty preview on new page creation
+* (bug 4411) Fix messages diff link for classic skin
+* (bug 4385) Separate parser cache entries for non-editing users, so section
+ edit links don't vanish / appear unwanted on protected pages
+* (bug 2726, 3397) Fix [[Special:]] and [[:Image]] links in action=render
+* (bug 4419) Remove obsolete magnify.png.old
+* Removed $wgUseCategoryMagic option, categories are now enabled unconditionally
+* (bug 3318) UI workarounds for disabled items in license selector
+ MSIE/Win: items now grayed out, JS will revert to 'non selected' if clicked
+ Safari: JS will revert to 'non selected' if clicked (but not gray)
+ MSIE/Mac: indented items now visible (JS hack)
+* (bug 714) "plainlinks" class issues in IE, Opera
+* (bug 4317) Inconsistent "broken redirects" messages
+* Default interface text for "selflinks" tweaked
+* (bug 3194) default implementation of translateBlockExpiry
+ which uses ipboptions
+* (bug 4446) $wgExportAllowHistory option to explicitly disable history in
+ Special:Export form, 'exportnohistory' message to translate live hack.
+* Maintenance script to delete unused user accounts
+* (bug 912) Search box easier to reach in text browsers (lynx, links)
+* $wgParserCacheExpireTime added
+* Skip loading of RecentChange.php except where needed
+* Enforce $wgSVGMaxSize when rendering, even for SVGs with a very large source
+ size. This is necessary to limit server memory usage.
+* Cleanup and error checking on Special:Listredirects
+* Clear up some instances of old OutputPage::sysopRequired() function usage
+* Improve "upload disabled" notice
+* Move parts of index.php to include/Wiki.php in an attempt to both cleanup index.php
+ and create a MediaWiki-class mediaWiki base object
+* (bug 4104) Added OutputPageBeforeHTML hook for tweaking primary wiki output
+ HTML on final output (cached or not)
+* Avoid PHP notice on command-line scripts if empty argument is passed ('')
+* (bug 4571) Partial fix hack for {{fulllurl:}} in action=render
+* (bug 3502) Bowtie symbol for TeX
+* (bug 4000) Support for \textstyle et al. in <math>
+* (bug 1663) support color in TeX formulas
+* (bug 2026) missing glue around \not= (TeX)
+* (bug 4576) Missing '>' broke license selector's first option in IE, Opera
+* Override $wgLocaltimezone in parser tests for us outside Iceland and UK
+* Fix extra whitespace at end of Wiki.php, DESTROYS XML OUTPUT
+* Remove redundant 'echo' statements from MonoBook.php
+* (bug 1103) Fix up redirect handling for images, categories
+ Redirects are now followed from the top-level, outside of the Article
+ content loading and viewing, for clarity and consistency.
+* (bug 4104) 'OutputPageBeforeHTML' hook to postprocess article HTML on
+ page view (comes after parser cache, if used). Patch by ThomasV.
+* Linker::formatComment corrupted the passed title object on PHP 5
+ if the comment included a section link. Use clone() to make a safe copy.
+* Add wfClone() wrapper since we're still using PHP 4 on some servers.
+* Remove obsolete killthread.php
+* Added wfDie() wrapper, and some manual die(-1), to force the return code
+ to the shell to return nonzero when we crap out with an error.
+* Allow input of the stub from a compressed file instead of stdin
+ for dumpTextPass.php; easier to get errors back on the shell
+* Added an attractive space on the namespace selector on contribs
+* Move PHP 5-friendly XHTML doctype hack to Sanitizer, use for sig checks.
+ Fixes use of named entities in sigs on PHP 5
+* (bug 4482) Include move comment on the null edit as well as the redirect
+* (bug 3990) Use existing session name if session.auto_start is on
+ Fixes checks for open sessions, such as the cookie warning on login.
+ Patch by Zbigniew Braniecki.
+* Add cache-safe alternate sitenotice for anonymous users. (MediaWiki:Anonnotice)
+ This is displayed instead of the regular sitenotice, if it exists. If not, the
+ regular sitenotice shows. If that doesn't exist, the value of $wgSiteNotice is used,
+ and if that's null, then nothing is shown.
+* Spit the generated LocalSettings code out during the installer as an aid
+ to debugging issues. (Keep this?)
+* Use __FILE__ to form path in new LocalSettings.php, so it stays accurate
+ when the directory is relocated for typical usage.
+* Auto-update $wgCacheEpoch when LocalSettings.php changes on new installs.
+ For typical usage this will be a light burden and should reduce confusion
+ when the configuration is edited.
+* Fix $wgCacheEpoch's effect on client-side caching.
+* (bug 1122) gray out 'older revision' when viewing first article revision.
+* Clearer message in DefaultSettings.php: edit LocalSettings.php instead
+* MonoBook skin top link id changed from "contentTop" to "top" (shared with
+ name attribute)
+* (bug 3350) Missing label for move talk page checkbox.
+* (bug 2108) Sort entries when using category browser
+* (bug 2393) Fix MIME type for Atom feeds ( application/rss+atom )
+* Add ".deps.php" include-file preloaders for some dynamically-loaded
+ language and skin classes. Should help with the broken base-class
+ problem under PHP 5 with APC as opcode cache. See details:
+ http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+* Small changes to tabs in Monobook skin c/o Chris Ware
+* (bug 4679) Work around buggy basename() function in PHP5, which breaks
+ uploads of files starting with multibyte characters on Linux.
+ wfBaseName() doesn't suffer this bug, and understands backslash on
+ both Unix and Windows.
+* (bug 3603) headscripts variable not hooked up to MonoBook skin
+* Allow local cdb-based interwiki cache
+* Use the "block", not the "protect" permission, when determining whether to
+ show a "block user" link in the toolbox
+* Fix backup dump text prefetch for XMLReader constant changes in PHP 5.1
+* Suppress useless percentage indicator on output from 7za during dumps
+* (bug 4633) Add (previous 200) (next 200) also above catlinks
+* (bug 4686) Fix regression where ?diff=0&oldid=0 caused fatal error on
+ pages with only one revision. Fixes message diff link on first edit.
+* Fix dependence on hardcoded UNIQ_PREFIX in LanguageConverter.php
+* Do not check lag on external storage servers
+* Do not tidy interface messages (unless full tidy is set)
+* Do not trust equality propagation and give more hints to MySQL
+ optimizer for revision fetches (avoids index scans)
+* Use revision rate for ETA in dump generation; it tends to be more stable
+ than the per-page count for full-history dumps.
+* Include timestamp in wfDebugLog breakouts
+* (bug 4469) Namespace-specific notice to be displayed below site-notice
+ Edit messages like "MediaWiki:Namespacenotice-" plus namespace name
+ which is blank for main namespace, or like e.g. "User_talk"
+* Adjust user login/creation form hooks to work with a captcha plugin
+* (bug 1284) Inline styles for diffs in Recent Changes RSS/Atom feeds
+* (bug 4824) IE7 beta 2 broke compatibility with PNG logo workarounds,
+ and seems to work ok with other bits. No longer including the IE
+ workarounds JavaScript for IE 7 and above.
+* Fix extra namespace for Bulgarian
+* (bug 4303) Add $wgFavicon to change the shorticon icon link from
+ the default /favicon.ico or disable it (if set to false)
+* (bug 3347) strip linebreaks in math error source
+* (bug 4841) Warning for non-logged-in edits
+* (bug 4867) Leave invalid EXIF date fields unformatted instead of
+ showing a bogus current timestamp
+* Reset $wgActionPaths during parser test; corrects some false failures
+ in the automated test report.
+* (bug 4875) Define a div containing the shared image description
+* (bug 4860) Expose Title->userCan() as Hooks
+* (bug 4828) Fix genitive month-name variable for cs, pl, uk
+* (bug 4842) Fix 'show number of watching users' with enhanced RC
+* (bug 4889) Fix image talk namespace for Tamil
+* (bug 4147) Added cleanupWatchlist.php to clear out bogus watchlist entries
+* (partial bug 3456) Disable auto redirect to Main Page after account creation
+* (bug 4824) Separate out IE7 CSS compat hacks, fix for RTL pages
+* Added support for wikidiff2 and similar external diff engines.
+* Allow cookies to be shared between multiple wikis with a shared user database
+* Blocking some Unicode whitespace characters in usernames. Should check
+ if some or all should be blocked from all page titles.
+* Unknown log types no longer throw notices everywhere in RecentChanges
+* (bug 4502, 5017) Don't render potentially hostile deleted page contents
+ on Special:Undelete by default; show source, with an optional preview.
+ The revisions list no longer shows the latest text by default, so it can
+ still be operated if the text is hostile.
+* (bug 5013) Check for existence on "return to" links
+* Removed trailing whitespace on a bunch more messages.
+* Fix missing bad title check in Special:Booksources
+* Remove empty booksources string in fy
+* Avoid corrupting <gallery> inside <!-- comment -->
+* Remove legacy PHPTal code, hasn't been maintained in ages.
+* Tweak Userlogin include order for APC issue
+* Don't try to link to current page on protection tab
+* More exact checking in Title::equals() to fox moves of numerically similar
+ page titles. (Odd hex title bug on 64-bit.)
+* Fix explicit s-maxage=0 on raw pages; should help with proxy issues in
+ generated stylesheets... hopefully...
+* (bug 4685) More fixes for Slovenian project namespace
+* Fixed and enhanced a little the Live Preview, which had been broken for some time
+* Added article size limit, $wgMaxArticleSize
+* (bug 4974) Don't follow redirected talk page on "new messages" link
+* (bug 4970) Make category paging limits configurable
+* (bug 4535) Warn user when editing CSS or JS subpage of a skin that doesn't exist
+* Make Live Preview an user preference, still controllable by the global variable
+* Rename the stub LanguageAls / LanguageGem_alsation to LanguageGsw to follow
+ updated language code assignments
+* (bug 5081) Remove bogus fix for invalid characters in links which simply
+ broke use of legitimate multiple whitespace characters in bracketed link.
+* (bug 4838) Add relative oldids (prev, next, cur) for raw pages
+ Patch by Lupin
+* (bug 5086) Force image resize dimensions on ImageMagick, as for instance
+ "-resize 100x35!"; some thumbs were off due to differences in rounding and
+ would be generated smaller than expected.
+* (bug 5062) Width sometimes one pixel short when using maximum heights
+* Purge thumbnails and metadata cache for action=purge on an image page
+* (bug 4273) Bounce back with a message when attempting to submit a new comment
+ with an empty main textbox (user probably hit Enter in subject field)
+* (bug 5141) Gracefully handle the new account link when createaccount off
+* (bug 5150 and related) Fix missing ID attribute in HTML namespace selector
+* (bug 5152) Proper HTML escaping on subpage breadcrumbs
+* (bug 4855) Section edit links now have the section name in the title attribute.
+* (bug 2115) Support shift-selecting multiple checkboxes with JavaScript.
+* (bug 5161) Don't try to load template list for nonexistent pages
+* (bug 5228) Workaround for broken LanguageConverter title overrides; avoid
+ unnecessary hidden UI work when watch/unwatch is performed on edit
+* Fixed bogus master fallback in external storage
+* (bug 5246) Add speak:none to "hiddenStructure" class in main.css
+* Further work on rev_deleted; changed to a bitfield with several data-hiding
+ options. Not yet ready for production use; Special:Revisiondelete is
+ incomplete, and the flags are not preserved across page deletion/undeletion.
+ To try it; add the 'deleterevision' permission to a privileged group.
+* (bug 5270) Fix broken linktrail for br, cv, fr, hr, nn, oc, ta, wa
+* Add a clickable contribs link in user tool links (rc, watchlist, diff view)
+ to see how people like it. (There was one in the old hacked-up diff view.)
+* (bug 5236) Load wikibits.js before site-customized javascript
+* (bug 4119) Workaround for <nowiki> following link in Walloon; remove capitals
+ from linktrail, as they're not used anywhere else.
+* (bug 4781) Output links with the percent-encoding they're supplied with;
+ save the normalization for internal link storage. The normalization is a bit
+ buggy and can make incorrect foldings in the query string and such, so isn't
+ reliable beyond the hostname where it's used for the spam bulk checker.
+* Don't URL-decode in the title attribute for URL links; it can produce false
+ results that don't code back to their original values.
+* (bug 4611) Add user preference (default on) to add new pages to creators's watchlist
+* (bug 5286) Fix regression in display of missing/bad revision IDs
+* (bug 4729) Add user preference that marks a user's edits as patrolled if user is able to
+* (bug 4630) Add user preference to prompt users when entering blank edit summaries
+* Added optional suggest feature for the search box. Set wgUseAjax to true to
+ enable it.
+* (bug 5277) Use audio/midi rather that audio/mid
+* (bug 5410) Use namespace name when a custom namespace's nstab-NS message is nonexistent
+* (bug 5432) Fix inconsistencies in cookie names when using table prefixes
+* Additional protections against HTML breakage in table parsing
+* (bug 5355) Include skin name and style JS settings in page source;
+ fixes regression where Opera 6/7 and KHTML CSS fixes weren't applied
+ when wikibits.js was moved up before user JS inclusion.
+* Added $wgColorErrors: if set, database error messages will be highlighted
+ when running command-line scripts in a Unix terminal.
+* (bug 5195) rebuildrecentchanges.php works again; Database::insertSelect now
+ has a parameter for select options.
+* Fix updateSearchIndex.php for new schema
+* Fix bogus "filename too short" error when uploading files with a period in the base
+ name, e.g. "Mr. Zee.png"
+* (bug 2139) Show page title in subtitle when viewing "read only" page
+* (bug 5452) Update language name for Cree
+
+
+
+----
+
+== MediaWiki 1.5.8 ==
+
+March 26, 2006
+
+MediaWiki 1.5.8 is a security and bugfix maintenance release.
+
+A bug in decoding of certain encoded links could allow injection of raw
+HTML into page output; this could potentially lead to XSS attacks.
+
+Some minor UI fixes were also made, see the change log at the bottom of
+this file.
+
+
+== MediaWiki 1.5.7 ==
+
+March 2, 2006
+
+MediaWiki 1.5.7 is a bugfix maintenance release.
+
+Most importantly, a security issue in the installer has been fixed. The bug
+affects new installations of 1.5.6 only. If the user specified the MySQL root
+password, to allow the installer to create an unprivileged account, the
+installer would not only create the new account but also change the root
+password to be equal to the password of the new account.
+
+Anyone affected by this bug will need to change the root password back
+manually. For information about how to change passwords in MySQL please see:
+http://dev.mysql.com/doc/refman/5.1/en/passwords.html
+
+This version includes fixes for compatibility with Internet Explorer 7
+beta 2, and various other bugs; see the full changelog at the end of
+the release notes.
+
+
+== MediaWiki 1.5.6 ==
+
+January 19, 2006
+
+MediaWiki 1.5.6 is a security and bugfix maintenance release.
+
+A bug in edit comment formatting could send PHP into an infinite loop
+if certain malformed links were included. In most installations, this
+would cause the script to fail after PHP's 30-second failsafe timeout.
+
+Some improvements have been made to the installer which should make
+installation possible on a system with a broken MySQL "root" account.
+
+For several other minor fixes, see the complete changelog at the end
+of this file.
+
+
+== MediaWiki 1.5.5 ==
+
+January 5, 2006
+
+MediaWiki 1.5.5 is a security and bugfix maintenance release.
+
+Detection for uploads of Windows Metafile (.wmf) images has been added
+to help protect against a client-side vulnerability in unpatched Microsoft
+Windows operating systems.
+
+Sites which have enabled uploads and added non-standard file types
+(such as .ogg, .doc, or .pdf) should upgrade to this release to ensure
+that malicious .wmf files can't be uploaded with a fake extension;
+such files could put visitors to the site at risk.
+
+For more details on this, see:
+http://en.wikipedia.org/wiki/Windows_Metafile_vulnerability
+
+Additionally, a maintenance script removeUnusedAccounts.php has been added;
+this replaces an older Perl script which had not been updated for the new
+schema in 1.5.
+
+
+== MediaWiki 1.5.4 ==
+
+December 21, 2005
+
+MediaWiki 1.5.4 is a security and bugfix maintenance release.
+
+A hardcoded internal placeholder string has been replaced with a random
+one. This closes a hole where security checks in inline style attributes
+could be bypassed, injecting JavaScript code that could execute in
+Microsoft Internet Explorer.
+
+Other browsers would not be vulnerable.
+
+Several minor fixes are included in this release, most notably a fix
+to clear the "you have new messages" flag properly for usernames
+containing spaces when e-mail notification is enabled.
+
+See the changelog at the end of the release notes for a full list of
+fixes.
+
+
+== MediaWiki 1.5.3 ==
+
+December 4, 2005
+
+MediaWiki 1.5.3 is a security and bugfix maintenance release.
+
+Validation of the user language option was broken by a code change in
+May 2005, opening the possibility of remote code execution as this
+parameter is used in forming a class name dynamically created with
+eval().
+
+The validation has been corrected in this version. All prior 1.5 release
+and prelease versions are affected; 1.4 and earlier and not affected.
+
+Additionally several bugs have been fixed; see the changelog later in
+this file for a complete list.
+
+
+== MediaWiki 1.5.2 ==
+
+November 2, 2005
+
+MediaWiki 1.5.2 is a bugfix maintenance release.
+
+A change in PHP 4.4.1 and PHP 5.1.0RC broke handling of extension and
+<pre> sections, causing garbage data to be inserted in output and saved
+edits. This version works around the change.
+
+Several other glitches with MySQL 5.0 and PHP 5.0.5 were also fixed;
+see the change log below for a complete list.
+
+
+== MediaWiki 1.5.1 ==
+
+October 26, 2005
+
+MediaWiki 1.5.1 is a bugfix and security maintenance release, and is a
+recommended upgrade for all installations.
+
+This release includes further corrections to the inline CSS style sanitation
+which works around a JavaScript "feature" on Microsoft Internet Explorer.
+Users of Microsoft Internet Explorer for Windows may be vulnerable to
+XSS injections on prior versions; users of standards-compliant browsers
+are not vulnerable.
+
+Major fixes include:
+* Image pages work again with resizing disabled
+* Works in MySQL 5.0 strict mode
+
+There is experimental support in this release for explicitly declaring
+the UTF-8 charset in the database; this has been tested with MySQL 5.0.15
+but should work on 4.1 as well.
+
+IMPORTANT: Changing this setting on an existing wiki may produce interesting
+data corruption, depending on server configuration. Page contents should,
+usually, be unaffected, but page titles and other items may be. Limitations
+in MySQL's Unicode support mean that characters outside the BMP cannot be used
+in page titles or various other fields when using this mode.
+
+Table definitions are in maintenance/mysql5/tables.sql, and the runtime
+option to send 'SET NAMES utf8' is set by $wgDBmysql5 = true.
+
+(MySQL 3.23.x and 4.0.x do not support character set declarations; on these
+versions MediaWiki simply works with UTF-8 data and MySQL is blissfully
+unaware of it.)
+
+
+
+== MediaWiki 1.5.0 final ==
+
+October 5, 2005
+
+MediaWiki 1.5.0 is the new stable release branch of MediaWiki, and is
+recommended for all new installations.
+
+Any wikis running a 1.5 beta or release candidate are strongly recommended
+to upgrade to the final release, which includes a number of bug fixes and
+a security fix for CSS bugs in Microsoft Internet Explorer.
+
+IMPORTANT: Running a 1.3 or 1.4 wiki and don't want to jump to 1.5 yet?
+Be sure to upgrade to 1.3.17 or 1.4.11, also released today. Versions
+prior to 1.3.16 and 1.4.10 have a serious data corruption bug which is
+triggered by a spambot known to operate in the wild.
+
+
+=== What's new in 1.5? ===
+
+Schema:
+ The core table schema has changed significantly. This should make better
+ use of the database's cache and disk I/O, and make significantly speed up
+ rename and delete operations on pages with very long edit histories.
+
+ Unfortunately this does mean upgrading a wiki of size from 1.4 will require
+ some downtime for the schema restructuring, but future storage backend
+ changes should be able to integrate into the new system more easily.
+
+Permalinks:
+ The current revision of a page now has a permanent 'oldid' number assigned
+ immediately, and the id numbers are now preserved across deletion/undeletion.
+ A permanent reference to the current revision of a page is now just a matter
+ of going to the 'history' tab and copying the first link in the list.
+
+Page move log:
+ Renames of pages are now recorded in Special:Log and the page history.
+ A handy revert link is available from the log for sysops.
+
+Editing diff:
+ Ever lost track of what you'd done so far during an edit? A 'Show diff'
+ button on the edit page now makes it easy to remember.
+
+Uploads:
+ It's now possible to specify the final filename of an upload distinct
+ from the original filename on your disk.
+
+ An image link for a missing file will now take you straight to the upload page.
+
+ More metadata is pre-extracted from uploaded images, which will ease pressure
+ on disk or NFS volumes used to store images. EXIF metadata is displayed on
+ the image description page if PHP is configured with the necessary module.
+
+ If .svg files are added to the upload whitelist, you can choose to render
+ them to rasterized .png images for inline display using one of several
+ external helper programs. See DefaultSettings.php for SVG options.
+
+User accounts:
+ There are some changes to the user permissions system, with assignable
+ groups. Note that this does *not* allow you to make pages which are only
+ accessible to certain groups.
+
+ For details see: http://meta.wikimedia.org/wiki/Help:User_rights
+
+E-mail:
+ User-to-user e-mail can now be restricted to require a mail-back confirmation
+ first to reduce potential for abuse with false addresses.
+
+ Updates to user talk pages and watchlist entries can optionally send e-mail
+ notifications.
+
+External hooks:
+ A somewhat experimental interface for hooking in an external editor
+ application is included.
+
+And...
+ A bunch of stuff we forgot to mention.
+
+
+=== What's gone? ===
+
+Latin-1:
+ Wikis must now be encoded in Unicode UTF-8; this has been the default for
+ some time, but some languages could optionally be installed in Latin-1 mode.
+ This is no longer supported.
+
+ You can check if your current wiki is in Latin-1 mode by using your browser's
+ "view source"; look for a line like this:
+
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ If it says charset=utf-8, you're ready. If it says charset=iso8859-1,
+ you may need to convert your data. (English-language wikis avoiding
+ any accented characters may be able to get away without conversion.)
+
+MySQL 3.x:
+ Some optimization hacks for MySQL 3.x have been removed as part of the schema
+ clean-up (specifically, the inverse_timestamp fields).
+
+ MediaWiki 1.5 may still run on 3.x, but wikis of non-trivial size should
+ very seriously consider upgrading to a more modern release. MySQL 3.x support
+ will probably be entirely dropped in the next major release.
+
+Special:Maintenance
+ These tools were, ironically enough, not really maintained. This special
+ page has been removed; insofar as some of its pieces were useful and haven't
+ already been supplanted by other special pages they should be rewritten in
+ an efficient and safe manner in the future.
+
+
+=== Caveats ===
+
+Upgrade:
+ Wikis in Latin-1 encoding are no longer supported; only Unicode UTF-8.
+ A new option $wgLegacyEncoding is provided to allow on-the-fly recoding of
+ old page text entries, but other metadata fields (titles, comments etc) need
+ to be pre-converted. The standard upgrade process does not yet fully automate
+ this, but you can try the alternate partial-upgrader in upgrade1_5.php.
+
+ The upgrade from 1.4 to 1.5 schema has not been tested for all cases, so
+ it's possible you may experience problems in some combinations.
+
+Backups:
+ The text entries of deleted pages are no longer removed from the main
+ text table on deletion. If you provide public backup dumps of your databases,
+ you will probably want to use the new XML-format dump generator, available
+ as maintenance/dumpBackup.php.
+
+ For more information on how we run our own public data dumps at Wikimedia,
+ see http://meta.wikimedia.org/wiki/Data_dumps
+
+PostgreSQL:
+ The table definitions for PostgreSQL install are out of date. PostgreSQL
+ support may return in later releases, pending appropriate patches.
+
+MySQL 4.1+:
+ Some users may encounter installation problems with MySQL 4.1 or higher
+ due to strange charset encoding / collation configurations. Try setting
+ to 'latin1' or 'utf8' if you encounter problems.
+
+
+
+== MediaWiki 1.5 release candidate 4 ==
+
+August 29, 2005
+
+MediaWiki 1.5rc4 is a preview release of the new 1.5 release series.
+It fixes compatibility with PHP 5.1, and corrects two cross-site scripting
+security bugs:
+
+* <math> tags were handled incorrectly when TeX rendering support is off,
+ as in the default configuration.
+* Extension or <nowiki> sections in Wiki table syntax could bypass HTML
+ style attribute restrictions for cross-site scripting attacks against
+ Microsoft Internet Explorer
+
+Wikis where the optional math support has been *enabled* are not vulnerable
+to the first, but are vulnerable to the second.
+
+
+
+== MediaWiki 1.5 release candidate 3 ==
+
+August 24, 2005
+
+MediaWiki 1.5rc3 is a preview release of the new 1.5 release series.
+It fixes several major problems in 1.5rc2:
+
+* Fixed a cross-site scripting injection in the search form
+ (broken since 1.5beta1)
+
+* Fixed upgrades from 1.4 database schema
+ (broken since 1.5rc2)
+
+1.3 and 1.4 releases are not vulnerable to the XSS bug, but anyone
+running an earlier 1.5 beta or release candidate should upgrade
+immediately.
+
+
+== MediaWiki 1.5 release candidate 2 ==
+
+August 23, 2005
+
+MediaWiki 1.5rc2 is a preview release of the new 1.5 release series.
+Numerous bug fixes since last beta, plus a security fix; see change
+log below for full details.
+
+A flaw in the interaction between extensions and HTML attribute
+sanitization was discovered which could allow unauthorized use
+of offsite resources in style sheets, and possible exploitation
+of a JavaScript injection feature on Microsoft Internet Explorer.
+
+This version expands the returned text and properly checks it
+before output.
+
+A 1.5rc1 release was mistakenly made from the incorrect source code
+branch; 1.5rc2 is identical to the actual 1.5rc1 in revision control
+except for version number.
+
+
+== MediaWiki 1.5 beta 4 ==
+
+July 30, 2005
+
+MediaWiki 1.5 beta 4 is a preview release of the new 1.5 release series.
+A number of bugs have been fixed since beta 3; see the full changelist below.
+
+
+== MediaWiki 1.5 beta 3 ==
+
+July 7, 2005
+
+MediaWiki 1.5 beta 3 is a preview release of the new 1.5 release
+series, with a security update over beta 2.
+
+Incorrect escaping of a parameter in the page move template could
+be used to inject JavaScript code by getting a victim to visit a
+maliciously constructed URL. Users of vulnerable releases are
+recommended to upgrade to this release.
+
+Vulnerable versions:
+* 1.5 preview series: n <= 1.5beta2 vulnerable, fixed in 1.5beta3
+* 1.4 stable series: 1.4beta6 <= n <= 1.4.5 vulnerable, fixed in 1.4.6
+* 1.3 legacy series: not vulnerable
+
+This release also includes several bug fixes and localization updates.
+See the changelog at the end of this file for a detailed list.
+
+
+
+== MediaWiki 1.5 beta 2 ==
+
+July 5, 2005
+
+MediaWiki 1.5 beta 2 is a preview release of the new 1.5 release series.
+While most exciting new bugs should have been ironed out at this point,
+third-party wiki operators should probably not run this beta release
+on a public site without closely following additional development.
+
+Anyone who _has_ been running beta 1 is very very strongly advised to
+upgrade to beta 2, as it fixes many bugs from the previous beta including
+a couple of HTML and SQL injections.
+
+This release should be followed by one or two release candidates and
+a 1.5.0 final within the next few weeks.
+
+Beta upgraders, note there are some minor database changes. For upgrades
+from 1.4, see the file UPGRADE for details on significant database and
+configuration file changes.
+
+Beta 2 includes a preliminary command-line XML wiki dump importer tool,
+maintenance/importDump.php, paired with maintenance/dumpBackup.php.
+These use the same format as Special:Export and Special:Import, able
+to package a wiki's entire page set independent of the backend database
+and compression format.
+
+
+== MediaWiki 1.5 beta 1 ==
+
+June 26, 2005
+
+MediaWiki 1.5 beta 1 is a preview release, pretty much feature complete,
+of the new 1.5 release series. There are several known and likely a number
+of unknown bugs; it is not recommended to use this release in a production
+environment but would be recommended for testing in mind of an upcoming
+deployment.
+
+A number of significant changes have been made since the alpha releases,
+including database changes and a reworking of the user permissions settings.
+See the file UPGRADE for details of upgrading and changing your prior
+configuration settings for the new system.
+
+
+
+== MediaWiki 1.5 alpha 2 ==
+
+June 3, 2005
+
+MediaWiki 1.5 alpha 2 includes a lot of bug fixes, feature merges,
+and a security update.
+
+Incorrect handling of page template inclusions made it possible to
+inject JavaScript code into HTML attributes, which could lead to
+cross-site scripting attacks on a publicly editable wiki.
+
+Vulnerable releases and fix:
+* 1.5 prerelease: fixed in 1.5alpha2
+* 1.4 stable series: fixed in 1.4.5
+* 1.3 legacy series: fixed in 1.3.13
+* 1.2 series no longer supported; upgrade to 1.4.5 strongly recommended
+
+
+== MediaWiki 1.5 alpha 1 ==
+
+May 3, 2005
+
+This is a testing preview release, being put out mainly to aid testers in
+finding installation bugs and other major problems. It is strongly recommended
+NOT to run a live production web site on this alpha release.
+
+** WARNING: USE OF THIS ALPHA RELEASE MAY INFEST YOUR HOUSE WITH **
+** TERMITES, ROT YOUR TEETH, GROW HAIR ON YOUR PALMS, AND PASTE **
+** INNUENDO INTO YOUR C.V. RIGHT BEFORE A JOB INTERVIEW! **
+** DON'T SAY WE DIDN'T WARN YOU, MAN. WE TOTALLY DID RIGHT HERE. **
+
+
+=== Smaller changes since 1.4 ===
+
+Various bugfixes, small features, and a few experimental things:
+
+* 'live preview' reduces preview reload burden on supported browsers
+* support for external editors for files and wiki pages:
+ http://meta.wikimedia.org/wiki/Help:External_editors
+* Schema reworking: http://meta.wikimedia.org/wiki/Proposed_Database_Schema_Changes/October_2004
+* (bug 15) Allow editors to view diff of their change before actually submitting an edit
+* (bug 190) Hide your own edits on the watchlist
+* (bug 510): Special:Randompage now works for other namespaces than NS_MAIN.
+* (bug 1015) support for the full wikisyntax in <gallery> captions.
+* (bug 1105) A "Destination filename" (save as) added to Special:Upload Upload.
+* (bug 1352) Images on description pages now get thumbnailed regardless of whether the thumbnail is larger than the original.
+* (bug 1662) A new magicword, {{CURRENTMONTHABBREV}} returns the abbreviation of the current month
+* (bug 1668) 'Date format' supported for other languages than English, see:
+ http://mail.wikipedia.org/pipermail/wikitech-l/2005-March/028364.html
+* (bug 1739) A new magicword, {{REVISIONID}} give you the article or diff database
+ revision id, useful for proper citation.
+* (bug 1998) Updated the Russian translation.
+* (bug 2064) Configurable JavaScript mimetype with $wgJsMimeType
+* (bug 2084) Fixed a regular expression in includes/Title.php that was accepting invalid syntax like #REDIRECT [[foo] in redirects
+* It's now possible to invert the namespace selection at Special:Allpages and Special:Contributions
+* No longer using sorbs.net to check for open proxies by default.
+* What was $wgDisableUploads is now $wgEnableUploads, and should be set to true if one wishes to enable uploads.
+* Supplying a reason for a block is no longer mandatory
+* Language conversion support for category pages
+* $wgStyleSheetDirectory is no longer an alias for $wgStyleDirectory;
+* Special:Movepage can now take paramaters like Special:Movepage/Page_to_move
+ (used to just be able to take paramaters via a GET request like index.php?title=Special:Movepage&target=Page_to_move)
+* (bug 2151) The delete summary now includes editor name, if only one has edited the article.
+* (bug 2105) Fixed from argument to the PHP mail() function. A missing space could prevent sending mail with some versions of sendmail.
+* (bug 2228) Updated the Slovak translation
+* ...and more!
+
+
+=== Changes since 1.5alpha1 ===
+
+* (bug 73) Category sort key is set to file name when adding category to
+ file description from upload page (previously it would be set to
+ "Special:Upload", causing problems with category paging)
+* (bug 419) The contents of the navigation toolbar are now editable through
+ the MediaWiki namespace on the MediaWiki:navbar page.
+* (bug 498) The Views heading in MonoBook.php is now localizable
+* (bug 898) The wiki can now do advanced sanity check on uploaded files
+ including virus checks using external programs.
+* (bug 1692) Fix margin on unwatch tab
+* (bug 1906) Generalize project namespace for Latin localization, update namespaces
+* (bug 1975) The name for Limburgish (li) changed from "Lèmburgs" to "Limburgs
+* (bug 2019) Wrapped the output of Special:Version in <div dir='ltr'> in order
+ to preserve the correct flow of text on RTL wikis.
+* (bug 2067) Fixed crash on empty quoted HTML attribute
+* (bug 2075) Corrected namespace definitions in Tamil localization
+* (bug 2079) Removed links to Special:Maintenance from movepagetext message
+* (bug 2094) Multiple use of a template produced wrong results in some cases
+* (bug 2095) Triple-closing-bracket thing partly fixed
+* (bug 2110) "noarticletext" should not display on Image page for "sharedupload" media
+* (bug 2150) Fix tab indexes on edit form
+* (bug 2152) Add missing bgcolor to attribute whitelist for <td> and <th>
+* (bug 2176) Section edit 'show changes' button works correctly now
+* (bug 2178) Use temp dir from environment in parser tests
+* (bug 2217) Negative ISO years were incorrectly converted to BC notation
+* (bug 2234) allow special chars in database passwords during install
+* Deprecated the {{msg:template}} syntax for referring to templates, {{msg: is
+ now the wikisyntax representation of wfMsgForContent()
+* Fix for reading incorrectly re-gzipped HistoryBlob entries
+* HistoryBlobStub: the last-used HistoryBlob is kept open to speed up
+ multiple-revision pulls
+* Add $wgLegacySchemaConversion update-time option to reduce amount of
+ copying during the schema upgrade: creates HistoryBlobCurStub reference
+ records in text instead of copying all the cur_text fields. Requires
+ that the cur table be left in place until/unless such fields are migrated
+ into the main text store.
+* Special:Export now includes page, revision, and user id numbers by
+ default (previously this was disabled for no particular reason)
+* dumpBackup.php can dump the full database to Export XML, with current
+ revisions only or complete histories.
+* The group table was renamed to groups because "group" is a reserved word in
+ SQL which caused some inconveniances.
+* New fileicons for c, cpp, deb, dvi, exe, h, html, iso, java, mid, mov, o,
+ ogg, pdf, ps, rm, rpm, tar, tex, ttf and txt files based on the KDE
+ crystalsvg theme.
+* Fixed a bug in Special:Newimages that made it impossible to search for '0'
+* Added language variant support for Icelandic, now supports "Íslenzka"
+* The #p-nav id in MonoBook is now #p-navigation
+* Putting $4 in msg:userstatstext will now give the percentage of
+ admnistrators out of normal users.
+* links and brokenlinks tables merged to pagelinks; this will reduce pain
+ dealing with moves and deletes of widely-linked pages.
+* Add validate table and val_ip column through the updater.
+* Simple rate limiter for edits and page moves; set $wgRateLimits
+ (somewhat experimental; currently needs memcached)
+* (bug 2262) Hide math preferences when TeX is not enabled
+* (bug 2267) Don't generate thumbnail at the same size as the source image.
+* Fix rebuildtextindex.inc for new schema
+* Remove linkscc table code, no longer used.
+* (bug 2271) Use faster text-only link replacement in image alt text
+ instead of rerunning expensive link lookup and HTML generation.
+* Only build the HTML attribute whitelist tree once.
+* Replace wfMungeToUtf8 and do_html_entity_decode with a single function
+ that does both numeric and named chars: Sanitizer::decodeCharReferences
+* Removed some obsolete UTF-8 converter functions
+* Fix function comment in debug dump of SQL statements
+* (bug 2275) Update search index more or less right on page move
+* (bug 2053) Move comment whitespace trimming from edit page to save;
+ leaves the whitespace from the section comment there on preview.
+* (bug 2274) Respect stub threshold in category page list
+* (bug 2173) Fatal error when removing an article with an empty title from the watchlist
+* Removed -f parameter from mail() usage, likely to cause failures and bounces.
+* (bug 2130) Fixed interwiki links with fragments
+* (bug 684) Accept an attribute parameter array on parser hook tags
+* (bug 814) Integrate AuthPlugin changes to support Ryan Lane's external
+ LDAP authentication plugin
+* (bug 2034) Armor HTML attributes against template inclusion and links munging
+
+=== Changes since 1.5alpha2 ===
+
+* (bug 2319) Fix parse hook tag matching
+* (bug 2329) Fix title formatting in several special pages
+* (bug 2223) Add unique index on user_name field to prevent duplicate accounts
+* (bug 1976) fix shared user database with a table prefix set
+* (bug 2334) Accept null for attribs in wfElement without PHP warning
+* (bug 2309) Allow templates and template parameters in HTML attribute zone,
+ with proper validation checks. (regression from fix for 2304)
+* Disallow close tags and enforce empty tags for <hr> and <br>
+* Changed user_groups format quite a bit.
+* (bug 2368) Avoid fatally breaking PHP 4.1.2 in a debug line
+* (bug 2367) Insert correct redirect link record on page move
+* (bug 2372) Fix rendering of empty-title inline interwiki links
+* (bug 2384) Fix typo in regex for IP address checking
+* (bug 650) Prominently link MySQL 4.1 help page in installer if a possible
+ version conflict is detected
+* (bug 2394) Undo incompatible breakage to {{msg:}} compatiblity includes
+* (bug 1322) Use a shorter cl_sortkey field to avoid breaking on MySQL 4.1
+ when the default charset is set to utf8
+* (bug 2400) don't send confirmation mail on account creation if
+ $wgEmailAuthentication is false.
+* (bug 2172) Fix problem with nowiki beeing replaced by marker strings
+ when a template with a gallery was used.
+* Guard Special:Userrights against form submission forgery
+* (bug 2408) page_is_new was inverted (whoops!)
+* Added wfMsgHtml() function for escaping messages and leaving params intact
+* Fix ordering of Special:Listusers; fix groups list so it shows all groups
+ when searching for a specific group and can't be split across pages
+* (bug 1702) Display a handy upload link instead of a useless blank link
+ for [[media:]] links to nonexistent files.
+* (bug 873) Fix usage of createaccount permission; replaces $wgWhitelistAccount
+* (bug 1805) Initialise $wgContLang before $wgUser
+* (bug 2277) Added Friulian language file
+* (bug 2457) The "Special page" href now links to the current special page
+ rather than to "".
+* (bug 1120) Updated the Czech translation
+* A new magic word, {{SCRIPTPATH}}, returns $wgScriptPath
+* A new magic word, {{SERVERNAME}}, returns $wgServerName
+* A new magic word, {{NUMBEROFFILES}}, returns the number of rows in the image table
+* Special:Imagelist displays titles with " " instead of "_"
+* Less gratuitous munging of content sample in delete summary
+* badaccess/badaccesstext to supercede sysop*, developer* messages
+* Changed $wgGroupPermissions to more cut-n-paste-friendly format
+* 'developer' group deprecated by default
+* Special:Upload now uses 'upload' permission instead of hardcoding login check
+* Add 'importupload' permission to disable direct uploads to Special:Import
+* (bug 2459) Correct escaping in Special:Log prev/next links
+* (bug 2462 etc) Taking out the experimental dash conversion; it broke too many
+ things for the current parser to handle cleanly
+* (bug 2467) Added a Turkish language file
+* Fixed a bug in Special:Contributions that caused the namespace selection to
+ be forgotten between submits
+* Special:Watchlist/edit now has namespace subheadings
+* (bug 1714) the "Save page" button now has right margin to seperate it from
+ "Show preview" and "Show changes"
+* Special:Statistics now supports action=raw, useful for bots designed to
+ harwest e.g. article counts from multiple wikis.
+* The copyright confirmation box at Special:Upload is now turned off by default
+ and can be turned back on by setting $wgCopyrightAffirmation to a true value.
+* Restored prior text for password reminder button and e-mail, replacing
+ the factually inaccurate text that was there.
+* (bug 2178) Fix temp dir check again
+* (bug 2488) Format 'deletedtext' message as wikitext
+* (bug 750) Keep line endings consistent in LocalSettings.php
+* (bug 1577) Add 'printable version' tab in MonoBook for people who don't
+ realize you can just hit print to get a nicely formatted printable page.
+* Trim whitespace from option values to weather line-ending corruption problems
+* Fixed a typo in the Romanian language file (NS_MESIA => NS_MEDIA)
+* (bug 2504) Updated the Finnish translation
+* (bug 2506, 2512) Updated the Nynorsk translation
+* (bug 996) Replace $wgWhitelistEdit with 'edit' permission; fixup UPGRADE
+ documentation about edit and read whitelists.
+* (bug 2515) Fix incremental link table update
+* Removed some wikipedia-specifica from LanguageXx.php's
+* (bug 2496) Allow MediaWiki:edithelppage to point to external page
+* Added a versionRequired() function to OutputPage, useful for extension
+ writers that want to control what version of MediaWiki their extension
+ can be used with.
+* Serialized user objects now checked for versioning
+* Fix for interwiki link regression
+* Printable link shorter in monobook
+* Experimental Latin-1-and-replication-friendly upgrader script
+* (bug 2520) Don't show enotif options when disabled
+
+== Changes since 1.5beta1 ==
+
+* (bug 2531) Changed the interwiki name for sh (Serbocroatian) to
+ Srpskohrvatski/Српскохрватски (was Српскохрватски (Srbskohrvatski))
+* Nonzero return code for command-line scripts on wfDebugDieBacktrace()
+* Conversion fix for empty old table in upgrade1_5.php
+* Try reading revisions from master if no result on slave
+* (bug 2538) Suppress notice on user serialized checks
+* Fix paging on Special:Contributions
+* (bug 2541) Fix unprotect tab
+* (bug 1242) category list now show on edit page
+* Skip sidebar entries where link text is '-'
+* Convert non-UTF-8 URL parameters even if referer is local
+* (bug 2460) <img> width & height properly filled when resizing image
+* (bug 2273) deletion log comment used user interface langage
+* Try reading revision _text_ from master if no result on slave
+* Use content-language message cache for raw view of message pages
+* (bug 2530) Not displaying talk pages on Special:Watchlist/edit
+* Fixed a bug that would occour if $wgCapitalLinks was set to false, a user
+ agent could create a username that began with a lower case letter that was
+ not in the ASCII character set ( now user $wgContLang->ucfirst() instead of
+ PHP ucfirst() )
+* Moved the user name / password validity checking from
+ LoginForm::addNewAccountInternal() to two new functions,
+ User::isValidUserName() and User::isValidPassword(), extensions can now do
+ these checks without rewriting code.
+* Fix $wgSiteNotice when MediaWiki:Sitenotice is set to default '-'
+* Fixed a bug where the watchlist count without talk pages would be off by a
+ factor of two.
+* upgrade1_5.php uses insert ignore, allows to skip image info initialization
+* Fix namespaces in category list.
+* Add rebuildImages.php to update image metadata fields
+* Special:Ancientpages is expensive in new schema for now
+* (bug 2568) Fixed a logic error in the Special:Statistics code which caused
+ the displayed percentage of admins to be totally off.
+* (bug 2560) Don't show blank width/height attributes for missing size
+* Don't show bogus messages about watchlist notifications when disabled
+* Don't show old debug messages in watchlist
+* (bug 2576) Fix recording of transclusion links
+* (bug 2577) Allow sysops to enter non-standard block times
+* Fixed a bug where Special:Contributions wouldn't remember the 'invert'
+ status between next/previous buttons.
+* Move MonoBook printable link from tab to sidebar
+* (bug 2567) Fix HTML escaping on category titles in list
+* (bug 2562) Show rollback link for current revisions on diff pages
+* (bug 2583) Add --missinig option on rebuildImages.php to add db entries
+ for uploaded files that don't have them
+* (bug 2572) Fix edit conflict handling
+* (bug 2595) Show "Earlier" and "Latest" links on history go to the first/last
+ page in the article history pager.
+* Don't show empty-page text in 'Show changes' on new page
+* (bug 2591) Check for end, fix limits on Whatlinkshere
+* (bug 2584) Fix output of subcategory list
+* (bug 2597) Don't crash when undeleting an image description page
+* (bug 2564) Don't show "editingold" warning for recent revision
+* Various code cleanup and HTML escaping fixlets
+* Copy IRC-over-UDP update option from REL1_4
+* (bug 2548) Keep summary on 'show changes' of section edit
+* Move center on toc to title part to avoid breaking .toc style usage
+* HTML sanitizer: correct multiple attributes by keeping last, not first
+* (bug 2614) Fix section edit links on diff-to-current with oldid set
+ Also fix navigation links on current-with-oldid view.
+* (bug 2620) Return to prior behavior for some more things (such as
+ subpage parent links) on current-diff view.
+* (bug 2618) Fix regression from another fix; show initial preview for
+ categories only if the page does not exist.
+* (bug 2625) Keep group & user settings when paging in Listusers
+* (bug 2627) Fix regression: diff radio button initial selection
+* Copy fix for old search URLs with Lucene search plugin from REL1_4
+* (bug 619) Don't use incompatible diff3 executable on non-Linux systems.
+* (bug 2631) Fix Hebrew namespaces.
+* (bug 2630) Indicate no-longer-valid cached entries in BrokenRedirects list
+* (bug 2644, 2645) "cur" diff links in page history, watchlist and
+ recentchanges should specify current ID explicitly.
+* (bug 2609) Fix text justification preferenced with MonoBook skin.
+* (bug 2594) Display article tab as red for non-existent articles.
+* (bug 2656) Fix regression: prevent blocked users from reverting images
+* (bug 2629) Automatically capitalize usernames again instead of
+ rejecting lowercase with a useless error message
+* (bug 2661) Fix link generation in contribs
+* Add support for &preload=Page_name (load text of an existing page into
+edit area) and &editintro=Page_name (load text of an existing page instead
+of MediaWiki:Newpagetext) to &action=edit, if page is new.
+* (bugs 2633, 2672, 2685, 2695) Fix Estonian, Portuguese, Italian, Finnish and
+ Spanish numeric formatting
+* Fixed Swedish numeric formatting
+* (bug 2658) Fix signature time, localtime to match timezone offset again
+* Files from shared repositories (e.g. commons) now display with their
+ image description pages when viewed on local wikis.
+* Restore compatibility namespace aliases for French Wikipedia
+* Fix diff order on Enhanced RC 'changes' link
+* (bug 2650) Fix national date type display on wikis that don't support
+ dynamic date conversion.
+* FiveUpgrade: large table hacks, install iw_trans update before links
+* (bug 2648) Rename namespaces in Afrikaanse
+* Special:Booksources checks if custom list page exists before using it
+* (bug 1170) Fixed linktrail for da: and ru:
+* (bug 2683) Really fix apostrophe escaping for toolbox tips
+* (bug 923) Fix title and subtitle for rclinked special page
+* (bug 2642) watchdetails message in several languages used <a></a> instead of [ ]
+* (bug 2181) basic CSB language localisation by Tomasz G. Sienicki (thanks for the patch)
+* Fix correct use of escaping in edit toolbar bits
+* Removed language conversion support from Icelandic
+* (bug 2616) Fix proportional image scaling, giving correct height
+* (bug 2640) Include width and height attributes on unscaled images
+* Workaround for mysterious problem with bogus epoch If-Last-Modified reqs
+* (bug 1109) Suppress compressed output on 304 responses
+* (bug 2674) Include some site configuration info in export data:
+ namespaces definitions, case-sensitivity, site name, version.
+* Use xml:space="preserve" hint on export <text> elements
+* Make language variant selection work again for zh
+
+== Changes since 1.5beta2 ==
+
+* Escaped & correctly in Special:Contributions
+* (bug 2534) Hide edit sections with CSS to make right click to edit section work
+* (bug 2708) Avoid undefined notice on cookieless login attempt
+* (bug 2188) Correct template namespace for Greek localization
+* Fixed number formatting for Dutch
+* (bug 1355) add class noprint to commonPrint.css
+* (bug 2350) Massive update for Limburgish (li) language using Wikipédia
+* Massive update for Arab (ar) language using Wikipédia
+* (bug 1560) Massive update for Kurdish (ku) language using Wikipédia
+* (bug 2709) Some messages were not read from database
+* (bug 2416) Don't allow search engine robots to index or follow nonexisting articles
+* Fix escaping in page move template.
+* (bug 153) Discrepancy between thumbnail size and <img> height attribute
+
+== Changes since 1.5beta3 ==
+
+* Fix talk page move handling
+* (bug 2721) New language file for Vietnamese with the Vietnamese number notation
+* (bug 2749) &nbsp; would appear as a literal in image galleries for Cs, Fr, Fur, Pl and Sv
+* (bug 787) external links being rendered when they only have one slash
+* Fixed a missing typecast in Language::dateFormat() that would cause some
+ interesting errors with signitures.
+* (bug 2764) Number format for Nds
+* (bug 1553) Stop forcing lowercase in Monobook skin for German language.
+* (bug 1064) Implements Special:Unusedcategories
+* (bug 2311) New language file for Macedonian
+* Fix nohistory message on empty page history
+* Fix fatal error in history when validation on
+* Cleaned up email notification message formatting
+* Finally fixed Special:Disambiguations that was broke since SCHEMA_WORK
+* (bug 2761) fix capitalization of "i" in Turkish
+* (bug 2789) memcached image metadata now cleared after deletion
+* Add serialized version number to image metadata cache records
+* (bug 2780) Fix thumbnail generation with GD for new image schema
+* (bug 2791) Slovene numeric format
+* (bug 655) Provide empty search form when searching for nothing
+* Nynorsk numeric format fix
+* (bug 2825) Fix regression in newtalk notifications for anons w/ enotif off
+* (bug 2833) Fix bug in previous fix
+* With $wgCapitalLinks off, accept off-by-first-letter-case in 'go' match
+* Optional parameters for [[Special:Listusers]]
+* (bug 2832) [[Special:Listadmins]] redirects to [[Special:Listusers/sysop]]
+* (bug 785) Parser did not get out of <pre> with list elements
+* Some shared upload fixes
+* (bug 2768) section=new on nonexistent talk page does not add heading
+* support preload= parameter for section=new
+* show comment subject in preview when using section=new
+* use comment form when creating a new talk page
+* (bug 460) Properly handle <center> tags as a block.
+* Undo inconsistent editing behavior change
+* (bug 2835) Back out fix for bug 2802, caused regressions in category sort
+* PHP 4.1.2 compatibility fix: define floatval() equivalent if missing
+* (bug 2901) Number format for Catalan
+* Special:Allpages performance hacks: index memcached caching, removed
+ inverse checkbox, use friendlier relative offsets in index build
+* Bring back "Chick" skin for mobile devices. It needs testing.
+* Fix spelling of $wgForwardSearchUrl in DefaultSettings.php
+* Specify USE INDEX on Allpages chunk queries, sometimes gets lost
+ due to bogus optimization
+* (bug 275) Section duplication fix
+* Remove unused use of undefined variable in UserMailer
+* Fix notice on search index update due to non-array
+* (bug 2885) Fix fatal errors and notices in PHP 5.1.0beta3
+* (bug 2931) Fix additional notices on reference use in PHP 4.4.0
+* (bug 2774) Add three new $wgHooks to LogPage which enable extensions to add
+ their own logtypes, see extensions/Renameuser/SpecialRenameuser.php for an
+ example of this.
+* (bug 740) Messages from extensions now appear in Special:Allmessages
+* (bug 2857) fixed parsing of lists in <pre> sections
+* (bug 796) Trackback support
+* Fix 1.5 regression: weird, backwards diff links on new pages in enhanced RC
+ are now suppressed as before.
+* New skin: Simple
+* "uselang" and "useskin" URL parameters can now be used in the URL when
+ viewing a page, to change the language and skin of a page respectively.
+* Skins can now be previewed in preferences
+* (bug 2943) AuthPlugin::getCanonicalName() name canonicalization hook,
+ patch from robla
+* Wrap revision insert & page update in a transaction, rollback on late
+ edit conflict.
+* (bug 2953) 'other' didn't work in Special:Blockip when localized
+* (bug 2958) Rollback and delete auto-summary should be in the project's
+ content language
+* Removed useless protectreason message
+* Spelling fix: $wgUrlProtcols -> $wgUrlProtocols
+* Switch Moldovan local name to cyrillic
+* Fix typo in undefined array index access prevention
+* (bug 2947) Update namespaces for sr localization
+* (bug 2952) Added Asturian language file with translated namespaces
+* (bug 2676) Apply a protective transformation on editing input/output
+ for browsers that hit the Unicode blacklist. Patch by plugwash.
+* (bug 2999) Fix encoding conversion of pl_title in upgrade1_5.php
+* compressOld.php disabled, as it's known to be broken.
+
+
+=== Changes since 1.5beta4 ===
+
+* Fix Special:Allmessages under PHP 5
+* (bug 2911) Special:Watchlist allowed only one type of limit at a time
+* (bug 693) Special:Allmessages is excessively wide and redundant
+* (bug 3001) Updated and applied live hack for recentchanges-based watchlist
+* (bug 145) Finish 'exclude redirect' implementation in search form
+* Rearranged Special:Movepage form to reduce confusion between destination
+ title and reason input boxes
+* (bug 2527) Always set destination filename when new file is selected
+* (bug 3056) MySQL 3 compatibility fix: USE INDEX instead of FORCE INDEX
+* PHP 4.1 compatibility fix: don't use new_link parameter to mysql_connect
+ if running prior to 4.2.0 as it causes the call to fail
+* (bug 3117) Fix display of upload size and type with tidy on
+* (bug 1487) invalid html on empty list in banlist
+* (bug 3017) Hotkey conflict for delete and show changes
+* made pixel unit translateable and blocklistline now eats infiniteblock
+ and expiringblock
+* (bug 3092) Wrong numerical separator for big numbers in Serbian.
+* (bug 2855) Credit for a uniq author showed its realname even with
+ $wgAllowRealName=false.
+* New special page: SpecialMostlinked
+* (bug 2393) Fix MIME type for Atom feeds ( application/rss+atom )
+* Fix display of read-only lockfile message
+* Added a new hook, 'AddNewAccount', which is run after account creation
+* Update all stats fields on recount.sql
+* Include software-visible client IP address in Special:Version comment
+ as a proxy debugging aid
+* (bug 3162) Fix 'undefined property page_is_new' error on watchlist
+* (bug 1734) granting db permissions failed with db usernames containg '-'
+* (bug 3170) wikititlesuffix was removed, use pagetitle instead
+* (bug 3187) watchlist text refer to unexistent "Stop watching" action
+* (bug 3190) Added some date format choices for language sr
+* (bug 1334) LanguageGa.php update
+* (bug 1020) Changing user interface language does not work immediately
+* (bug 2753) Some namespaces were not translated in LanguageTa.php (Tamil)
+* (bug 3204) Fix typo breaking special pages in fy localization
+* (bug 3210) Fix Media: links with remote image URL path
+* (bug 3220) Fix escaping of block URLs in Recentchanges
+* (bug 3238): Updated LanguageNn.php for 1_5 branch
+* (bug 3192): properly check 'limit' parameter on Special:Contributions
+* (bug 3244) Fix remote image loading hack, JavaScript injection on MSIE
+* Fix URL sanitization in HTML attributes, which broke in this branch
+* (bug 3475) anon contrib links on Special:Newpages
+
+
+=== Changes since 1.5rc2 ===
+
+* Fix upgrade from 1.4 due to version number check breakage
+* Fix upgrade from 1.4 with no old revisions
+* (bug 2108) Sort entries when using category browser
+* XSS issue : now sanitize search query input
+
+
+=== Changes since 1.5rc3 ===
+
+* (bug 3280) Respect 'move' group permission on page moves
+* (bug 2885) More PHP 5.1 fixes: skin, search, log, undelete
+* Security fix for <math>
+* Security fix for tables
+
+
+=== Changes since 1.5rc4 ===
+
+* (bug 3292) Fix move-over-redirect test when current entries are not plaintext
+* (bug 2078) Don't hide watch tab on preview
+* (bug 3306) Document $wgLocalTZoffset
+* Support SVG rendering with rsvg
+* Cap arbitrary SVG renders to given image size or $wgSVGMaxSize pixels wide
+* (bug 3127) Render large SVGs at image page size correctly
+* (bug 3448) Set page_len on undelete
+* (bug 2800) Don't scale up small iamges on |thumb| without explicit size
+* Use the real file link instead of the default-size rasterized version for
+ large SVG images on image description page
+* Include the file name/type/size line for non-resized images
+* (bug 3412) Clean up date format handling so ~~~~-sigs work with default
+ format as designed. Documentation comments updated.
+* (bug 1423) LanguageJa.php update
+* (bug 3405) Don't use raw letters as aliases of MSGNW: and SUBST:
+* (bug 3485) Fix bogus warning about filename capitalization when off
+* (bug 2792) Update rebuildrecentchanges.inc for new schema
+* Special:Import/importDump fixes: report XML parse errors, accept <minor/>
+* (bug 3489) PHP 5.1 compat problem with captioned images
+* (bug 3350) Missing label for move talk page checkbox.
+* (bug 2570) Add 'watch this page' checkbox on uploads, watch uploads
+ by default when 'watchdefault' option is on
+* (bug 3182) Clear link cache during import to prevent memory leak
+* (bug 3573) Full Greek Translation
+* (bug 3595) Warn and abort if importDump.php called in read-only mode.
+* (bug 3598) Update message cache on message page deletion, patch by Tietew
+* Blacklist additional MSIE CSS safety tricks
+
+
+=== Changes since 1.5.0 ===
+
+* (bug 3629) Fix date & time format for Frisian
+* (bug 3641) Fix handling of unrecognized file uploads with known extensions
+* (bug 3643) Fix image page display of large images with resizing disabled
+* Fix meta robots tag on Special:Version again to avoid listing vulnerable
+ versions for convenient harvesting by automated worms
+* (bug 3684) Fix typo in fatal error backtraces in Hooks.php
+* Backport fix for reference usage notice in Special:Search on PHP 4.4.0
+* Backport database connect error display fix from HEAD
+* (bug 2773) Print style sheet no longer overrides RTL text direction
+* MonoBook skin top link id changed from "contentTop" to "top" (shared with
+ name attribute)
+* Wrap message page insertions in a transaction to speed up installation
+* Fix Special:MovePage invalid HTML attribute for reason textarea
+* Avoid notice warning on edit with no User-Agent header
+* (bug 3734) Swapped out obsolete recount.sql with initStats.php
+* (bug 3735) Fix to run under MySQL 5's strict mode
+* (bug 3786) Experimental support for MySQL 4.1/5.0 utf8 charset mode
+ NOTE: Enabling this may break existing wikis, and still doesn't
+ work for all Unicode characters due to MySQL limitations.
+* Sanitizer CSS comment processing order fix
+
+
+=== Changes since 1.5.1 ===
+
+* Fix Special:BrokenRedirects on MySQL 5.0
+* (bug 3809) Backport fix for detecting diff3 failure
+* MySQL 5.0 strict mode fix for moving unwatched pages
+* (bug 3782) Throw fatal installation warning if mbstring.func_overload on.
+ Why do people invent these crazy options that change language semantics?
+* (bug 3762) Define missing Special:Import UI messages
+* (bug 3771) Handle internal functions in backtrace in wfAbruptExit()
+* (bug 3649) Remove obsolete, broken moveCustomMessages script
+* (bug 3667) Add missing global in page move code
+* (bug 3761) Avoid deprecation warnings in Special:Import
+* (bug 2885) Remove unnecessary reference parameter which broke classic skin
+ talk notification on PHP 5.0.5
+* (bug 3845) Update attribute.php for 1.5 schema
+* Fix Parser::unstrip on PHP 4.4.1 and PHP 5.1.0RC4
+
+
+=== Changes since 1.5.2 ===
+
+* (bug 3612) Remove old broken version of maintenance/compressOld.php
+ The working version is in maintenance/storage/compressOld.php
+* (bug 2740) Accept image deletions on 'enter' submit from MSIE
+* (bug 3933) specify XML namespace for Atom 0.3 feeds
+* (bug 3939) Don't try to load text for interwiki redirect target
+* (bug 3948) Avoid notice warning in debug statement in bad search
+* Recognize Special:Search consistently so read whitelist works
+* (bug 4013) typo in fr
+* (bug 3996) Fix text for new entries in RC RSS/Atom feed
+* (bug 2894) Enhanced Recent Changes link fixes
+* (bug 3065) Update both watched namespaces when renaming pages
+* Move parentheses out of <a> link in Special:Contributions
+* (bug 4071) Generate passwords long enough for $wgMinimalPasswordLength
+* (bug 4035) Fix prev/next revision links on edit page
+* (bug 4165) Correct validation for user language selection (data taint)
+* Clearer message in DefaultSettings.php: edit LocalSettings.php instead
+
+
+=== Changes since 1.5.3 ===
+
+* (bug 3805) Clear 'new messages' flag properly in enotif mode
+ for usernames containing spaces
+* (bug 2714) Backlink from special:whatlinkshere was hard set as 'existing'
+* (bug 4249) Typo in entities2literals.pl
+* (bug 4233) Update for japanese language
+* (bug 4279) Small correction to LanguageDa.php
+* (bug 4267) Switch dv sd ug ks arc languages to RTL
+* (bug 3991) Allow the operation of wikicode on Protect move only text
+* Added AutoAuthenticate hook for external User object suppliers
+* Parser internal placeholder string now fully randomized for safety
+
+=== Changes since 1.5.4 ===
+
+* Maintenance script to delete unused user accounts
+* Added detection for WMF files (application/x-msmetafile), added this
+ MIME type to the default blacklist. Prevented inline display of images
+ which are not of known image types. This is in response to
+ http://en.wikipedia.org/wiki/Windows_Metafile_vulnerability
+
+=== Changes since 1.5.5 ===
+
+* (bug 4258) When installing under IIS, $wgArticlePath = "$wgScript?title=$1"
+ should be set
+* (bug 4510) Correct Barnes & Noble bookstore URLs
+* (bug 4504) Use site language for namespace name resolution
+* Installer fixes from HEAD backported; now uses a more sensible method of
+ establishing which mySQL user to use, which clears up bug 921 et al. Minor
+ changes to installer.
+* Fix problem reported on mailing list where re-initialising stats didn't work
+ (can't insert duplicate rows with the same id field)
+* (bug 1122) gray out 'older revision' when viewing first article revision.
+* Respect database prefix in dumpHTML.inc
+* Minor improvements to removeUnusedAccounts.php maintenance script
+* Fix for single-digit week numbers from {{CURRENTWEEK}}, broken by PHP 4.4.1
+* Removed read-only check from Database::query()
+* Added --conf option to command line scripts, allowing the user to specify a
+ different LocalSettings.php.
+
+=== Changes since 1.5.6 ===
+
+* Default main page content improved per bug 4690
+* Fix dependence on hardcoded UNIQ_PREFIX in LanguageConverter.php
+* Fixed Special:Unlockdb
+* Maintenance script to delete unused text records
+* Maintenance script to delete non-current revisions
+* Maintenance script to wipe a page and all revisions from the database
+* (bug 4768) Wrong Russian translation (typo)
+* Performance bugfix: propagate equality manually for Revision fetches
+* (bug 4773) PHP fatal error when invalid title passed to Special:Export
+* Added missing table defs. for transcache to installer schemas
+* (bug 4824) IE7 beta 2 broke compatibility with PNG logo workarounds,
+ and seems to work ok with other bits. No longer including the IE
+ workarounds JavaScript for IE 7 and above.
+* (bug 2532) Image directory structure migration bug
+* (bug 4881) Correction to the fix for 1487; Ipblocklist showed 'no blocks'
+ message at the end of the list even if there were blocks.
+* (bug 4805) Removed more wikipedia-references from LanguageUk.php
+* Introduce $wgWantedPagesThreshold per bug 5011; Special:Wantedpages will not
+ list pages with less than this number of links. Defaults to 1.
+* Allow customisation of paging limits for items in categories using the
+ $wgCategoryPagingLimit global, per bug 4970.
+* Improve "nogomatch" text to make it more obvious that a page can be created.
+* (bug 5113) Spelling error in French language file
+* Don't change the password of the MySQL root user.
+
+=== Changes since 1.5.7 ===
+
+* (bug 5180) User login page shows inappropriate email blurb
+* Add the "AbortNewAccount" hook on account creation; see hooks.txt for more info.
+* Update default "exporttext" to reflect that Special:Import exists
+* Add links to useful material to the default main page content
+* Fix fragment HTML injection
+
+=== Changes since 1.5.8 ===
+
+* Fixed obvious mistakes in Finnish (fi) translation
+* Fixed obvious mistakes in Kurdish (ku) translation
+* Merge two #p-search .pBody statements i monobook/main.css
+* (bug 5156) Update for Hebrew language (he) translation
+* Add the "UserRights" hook on user group changes; see hooks.txt for more info.
+* Translated "listingcontinuesabbrev" for German
+
+=== Caveats ===
+
+Some output, particularly involving user-supplied inline HTML, may not
+produce 100% valid or well-formed XHTML output. Testers are welcome to
+set $wgMimeType = "application/xhtml+xml"; to test for remaining problem
+cases, but this is not recommended on live sites. (This must be set for
+MathML to display properly in Mozilla.)
+
+----
+
+== MediaWiki 1.4.3 ==
+
+(released 2005-04-28)
+
+MediaWiki 1.4.3 is a bugfix release for the 1.4 stable release series.
+
+Chiefly, this fixes a compatibility problem with PHP 5 and a minor link
+table corruption bug on initial page save.
+
+
+== MediaWiki 1.4.2 ==
+
+(released 2005-04-20)
+
+MediaWiki 1.4.2 is a security and bug fix release for the 1.4 stable release
+series.
+
+A cross-site scripting injection vulnerability was discovered, which
+affects only MSIE clients and is only open if MediaWiki has been
+manually configured to run output through HTML Tidy ($wgUseTidy).
+
+Several other bugs are fixed in this release, see the changelog below.
+
+All new installations are highly recommended to use 1.4.2 instead of
+1.3.x; 1.3.x users should consider upgrading for bug fixes and new
+features. Ealier 1.4.x release and beta users should upgrade to this
+release for relevant bug fixes; see the changelog later in this file.
+
+
+If you have trouble, remember to read this whole file and the online FAQ page
+before asking for help:
+
+http://meta.wikimedia.org/wiki/MediaWiki_FAQ
+
+
+=== READ THIS FIRST: Upgrading ===
+
+If upgrading from an older release, see the notes in the file UPGRADE.
+There are a couple of minor database changes from the beta releases,
+and somewhat larger changes from 1.3.x.
+
+Upgrading from a previous 1.4.x stable release installation should
+generally only require copying the new files over the old ones.
+
+
+==== READ THIS FIRST, TOO: MySQL 4.1 AND 5.0 ====
+
+MySQL 5.0 is a beta release, not yet ready for production use. If you
+are using it, the notes below about 4.1 apply to you too.
+
+If you have the choice of MySQL 4.0 or MySQL 4.1 and don't need 4.1 for
+some other application, you should consider sticking with 4.0 for the
+moment. 4.1 may require you to do extra fiddling to get things to work
+due to changes that aren't fully backwards-compatible.
+
+MySQL 4.1 has changed the authentication protocol in an incompatible
+way; many PHP installations still use the older client libraries and
+CANNOT CONNECT TO THE SERVER WITH A PASSWORD without some changes.
+
+See: http://dev.mysql.com/doc/mysql/en/Old_client.html
+
+If MySQL is set with utf-8 as the default character set, installation
+may fail with "key too long" errors. Set the default charset to 'latin1'
+for installation and it should work.
+
+The mysqldump backup generator now applies an automatic conversion to
+UTF-8, which may irretrivably corrupt your data. Pass the -charset option
+with the original default charset (eg 'latin1') to skip the conversion.
+
+
+==== READ THIS FIRST IF RUNNING ON A WINDOWS SERVER ====
+
+MediaWiki is tested and deployed primarily under the Apache web server
+on Linux Unix systems. There are known to be problems running on
+Microsoft's IIS which are not fully resolved. If you have a choice,
+try running under Apache on Windows, or on a Unix/Linux box instead.
+
+If you're having trouble with blank pages on IIS and can't switch,
+try the workaround suggested in this bug report:
+http://bugzilla.wikimedia.org/show_bug.cgi?id=1763
+
+
+=== New features ===
+
+* 'Recentchanges Patrol' to mark new edits that haven't yet been viewed.
+* New, searchable deletion/upload/protection logs
+* Image gallery generation (Special:Newimages and <gallery> tag)
+* SVG rasterization support (requires external support tools)
+* Users can select from the available localizations to override the
+ default user interface language.
+* Traditional/Simplified Chinese conversion support
+* rel="nofollow" support to combat linkspam
+
+The current implementation adds this attribute to _all_ external URL
+links in wiki text (but not internal [[wiki links]] or interwiki links).
+To disable the attribute for _all_ external links, add this line to your
+LocalSettings.php:
+
+ $wgNoFollowLinks = false
+
+For background information on nofollow see:
+
+ http://www.google.com/googleblog/2005/01/preventing-comment-spam.html
+
+
+=== Installation and compatibility ===
+
+* The default MonoBook theme now works with PHP 5.0
+* Installation on systems with PHP's safe mode or other oddities
+ should work more reliably, as MonoBook no longer needs to
+ create a compiled template file for the wiki to run.
+* A table prefix may be specified, to avoid conflicts with other
+ web applications forced to share a database.
+* More thorough UTF-8 input validation; fixes non-ASCII uploaded
+ filenames from Safari.
+* Command-line database upgrade script.
+
+
+=== Customizability ===
+
+* Default user options can now be overridden in LocalSettings.
+* Skins system more modular: templates and CSS are now in /skins/
+ New skins can be dropped into this directory and used immediately.
+* More extension hooks have been added.
+* Authentication plugin hook.
+* More internal code documentation, generated with phpdoc:
+ http://www.mediawiki.org/docs/html/
+
+
+=== Optimization ===
+
+* For many operations, MediaWiki 1.4 should run faster and use
+ less memory than MediaWiki 1.3. Page rendering is up to twice
+ as fast. (Use a PHP accelerator such as Turck MMCache for best
+ results with any PHP application, though!)
+* The parser cache no longer requires memcached, and is enabled
+ by default. This avoids a lot of re-rendering of pages that
+ have been shown recently, greatly speeding longer page views.
+* Support for compiled PHP modules to speed up page diff and
+ Unicode validation/normalization. (Requires ability to compile
+ and load PHP extensions).
+
+
+=== What isn't ready yet ===
+
+* A new user/groups permissions scheme has been held back to 1.5.
+* An experimental SOAP interface will be made available as an extension
+* PostgreSQL support is largely working, minus search and the installer.
+ You can perform a manual installation.
+* E-mail notification of watched page changes and verification of
+ user-submitted e-mail addresses is not yet included.
+* Log pages are not automatically imported into the new log table
+ at upgrade time. A script to import old text log entries is
+ incomplete, but may be available in later point releases.
+* Some localizations are still incomplete.
+
+
+
+== Changelog ==
+
+=== Important security updates ===
+
+A security audit found and fixed a number of problems. Users of MediaWiki
+1.3.10 and earlier should upgrade to 1.3.11; users of 1.4 beta releases
+prior to 1.4rc1 should upgrade immediately.
+
+==== Cross-site scripting vulnerability ====
+
+XSS injection points can be used to hijack session and authentication
+cookies as well as more serious attacks.
+
+* Media: links output raw text into an attribute value, potentially
+ abusable for JavaScript injection. This has been corrected.
+* Additional checks added to file upload to protect against MSIE and
+ Safari MIME-type autodetection bugs.
+
+As of 1.3.10/1.4beta6, per-user customized CSS and JavaScript is disabled
+by default as a general precaution. Sites which want this ability may set
+$wgAllowUserCss and $wgAllowUserJs in LocalSettings.php.
+
+
+==== Cross-site request forgery ====
+
+An attacker could use JavaScript-submitted forms to perform various
+restricted actions by tricking an authenticated user into visiting
+a malicious web page. A fix for page editing in 1.3.10/1.4beta6 has
+been expanded in this release to other forms and functions.
+
+Authors of bot tools may need to update their code to include the
+additional fields.
+
+
+==== Directory traversal ====
+
+An unchecked parameter in image deletion could allow an authenticated
+administrator to delete arbitary files in directories writable by the
+web server, and confirm existence of files not deletable.
+
+
+==== Older issues ====
+
+Note that 1.4 beta releases prior to beta 5 include an input validation
+error which could lead to execution of arbitrary PHP code on the server.
+Users of older betas should upgrade immediately to the current version.
+
+
+Beta 6 also introduces the use of rel="nofollow" attributes on external
+links in wiki pages to reduce the effectiveness of wiki spam. This will
+cause participating search engines to ignore external URL links from wiki
+pages for purposes of page relevancy ranking.
+
+
+=== Misc bugs fixed in beta 1 ===
+
+* (bug 95) Templates no longer limited to 5 inclusions per page
+* New user preference for limiting the image size for images on image description
+ pages
+* (bug 530) Allow user to preview article on first edit
+* (bug 479) [[RFC 1234]] will now make an internal link
+* (bug 511) PhpTal skins shown bogus 'What links here' etc on special pages
+* (bug 770) Adding filter and username exact search match for Special:Listusers
+* (bug 733) Installer die if it can not write LocalSettings.php
+* (bug 705) Various special pages no more show the rss/atom feed links
+* (bug 114) use category backlinks in Special:Recentchangeslinked
+
+=== Beta 2 fixes ===
+
+* (bug 987) Reverted bogus fix for bug 502
+* (bug 992) Fix enhanced recent changes in PHP5
+* (bug 1009) Fix Special:Makesysop when using table prefixes
+* (bug 1010) fix broken Commons image link on Classic & Cologne Blue
+* (bug 985) Fix auto-summary for section edits
+* (bug 995) Close <a> tag
+* (bug 1004) renamed norsk language links (twice)
+* Login works again when using an old-style default skin
+* Fix for load balancing mode, notify if using old settings format
+* (bug 1014) Missing image size option on old accounts handled gracefully
+* (bug 1027) Fix page moves with table prefix
+* (bug 1018) Some pages fail with stub threshold enabled
+* (bug 1024) Fix link to high-res image version on Image: pages
+* (bug 1016) Fix handling of lines omitting Image: in a <gallery> tag
+* security fix for image galleries
+* (bug 1039) Avoid error message in certain message cache failure modes
+* Fix string escaping with PostgreSQL
+* (bug 1015) [partial] -- use comment formatter on image gallery text
+* Allow customization of all UI languages
+* use $wgForceUIMsgAsContentMsg to make regular UI messages act as content
+* new user option for zh users to disable language conversion
+* Defer message cache initialization, shaving a few ms off file cache hits
+* Fixed Special:Allmessages when using table prefixes
+* (bug 996) Fix $wgWhitelistRead to work again
+* (bug 1028) fix page move over redirect to not fail on the unique index
+
+=== Beta 3 fixes ===
+
+* Hide RC patrol markers when patrol is disabled or not allowed to patrol.
+* Fix language selection for upgraded accounts
+* (bug 1076) navigation links in QueryPage should be translated by wgContLang.
+* (bug 922) bogus DOS line endings in LanguageEl.php
+* Fix index usage in contribs
+* Caching and load limiting options for Recentchanges RSS/Atom feed
+* (bug 1074) Add stock icons for non-image files in gallery/Newimages
+* Add width and height attributes on thumbs in gallery/Newimages
+* Enhance upload extension blacklist to protect against vulnerable
+ Apache configurations
+
+=== Beta 4 fixes ===
+
+* (bug 1090) Fix sitesupport links in CB/classic skins
+* Gracefully ignore non-legal titles in a <gallery>
+* Fix message page caching behavior when $wgCapitalLinks is turned off
+ after installation and the wiki is subsequently upgraded
+* Database error messages include the database server name/address
+* Paging support for large categories
+* Fix image page scaling when thumbnail generation is disabled
+* Select the content language in prefs when bogus interface language is set
+* Fix interwiki links in edit comments
+* Fix crash on banned user visit
+* Avoid PHP warning messages when thumbnail not generated
+* (bug 1157) List unblocks correctly in Special:Log
+* Fix fatal errors in LanguageLi.php
+* Undo overly bright, difficult to read colors in Cologne Blue
+* (bug 1162) fix five-tilde date inserter
+* Add raw signatures option for those who simply must have cute sigs
+* (bug 1164) Let wikitext be used in Loginprompt and Loginend messages
+* Add the dreaded <span> to the HTML whitelist
+* (bug 1170) Fix Russian linktrail
+* (bug 1168) Missing text on the bureaucrat log
+* (bug 1180) Fix Makesysop on shared-user-table sites
+* (bug 1178) Fix previous diff link when using 'oldid=0'
+* (bug 1173) Stop blocked accounts from reverting/deleting images
+* Keep generated stylesheets cache-separated for each user
+* (bug 1175) Fix "preview on first edit" mode
+* Fix revert bug caused by bug 1175 fix
+* Fix CSS classes on minor, new, unpatrolled markers in enhanced RC
+* Set MySQL 4 boolean search back to 'and' mode by default
+* (bug 1193) Fix move-only page protection mode
+* Fix zhtable Makefile to include the traditional manual table
+* Add memcache timeout for the zh conversion tables
+* Allow user customization of the zh conversion tables through
+ Mediawiki:zhconversiontable
+* Add zh-min-man (back) to language names list
+* Ported $wgCopyrightIcon setting from REL1_3A
+* (bug 1218) Show the original image on image pages if the thumbnail would be
+ bigger than the original image
+* (bug 1213) i18n of Special:Log labels
+* (bug 1013) Fix jbo, minnan in language names list
+* Added magic word MAG_NOTITLECONVERT to indicate that the title of the page
+ do not need to be converted. Useful in zh:
+* (bug 1224) Use proper date messages for date reformatter
+* (bug 1241) Don't show 'cont.' for first entry of the category list
+* (bug 1240) Special:Preferences was broken in Slovenian locale when
+ $wgUseDynamicDates is enabled
+* Added magic word MAG_NOCONTENTCONVERT to supress the conversion of the
+ content of an article. Useful in zh:
+* write-lock for updating the zh conversion tables in memcache
+* recursively parse subpages of MediaWiki:Zhconversiontable
+* (bug 1144) Fix export for fy language
+* make removal of an entry from zhconversiontable work
+* (bug 752) Don't insert newline in link title for url with %0a
+* Fix missing search box contents in MonoBook skin
+* Add option to forward search directly to an external URL (eg google)
+* Correctly highlight the fallback language variant when the selected
+ variant is disabled. Used in zh: only for now.
+
+=== Beta 5 fixes ===
+
+* (bug 1124) Fix ImageGallery XHTML compliance
+* (bug 1186) news: in the middle of a word
+* (bug 1283) Use underlining and borders to highlight additions/deletions
+ in diff-view
+* Use user's local timezone in Special:Log display
+* Show filename for images in gallery by default (restore beta 3 behaviour)
+* (bug 1201) Double-escaping in brokenlinks, imagelinks, categorylinks, searchindex
+* When using squid reverse proxy, cache the redirect to the Main_Page
+* (bug 1302) Fix Norwegian language file
+* (bug 1205) Fix broken article saving in PHP 5.1
+* (bug 1206) Implement CURRENTWEEK and CURRENTDOW magic keyword (will give
+ number of the week and number of the day).
+* (bug 1204) Blocks do not expire automatically
+* (bug 1184) expiry time of indefinite blocks shown as the current time
+* (bug 1317) Fix external links in image captions
+* (bug 1084) Fix logo not rendering centrally in IE
+* (bug 288) Fix tabs wrapping in IE6
+* (bug 119) Fix full-width tabs with RTL text in IE
+* (bug 1323) Fix logo rendering off-screen in IE with RTL language
+* Show "block" link in Special:Recentchanges for logged in users, too, if
+ wgUserSysopBans is true.
+* (bug 1326) Use content language for '1movedto2' in edit history
+* zh: Fix warning when HTTP_ACCEPT_LANGUAGE is not set
+* zh: Fix double conversion for zh-sg and zh-hk
+* (bug 1132) Fix concatenation of link lists in refreshLinks
+* (bug 1101) Fix memory leak in refreshLinks
+* (bug 1339) Fix order of @imports in Cologne Blue CSS
+* Don't try to create links without namespaces ([[Category:]] link bug)
+* Memcached data compression fixes
+* Several valid XHTML fixes
+* (bug 624) Fix IE freezing rendering whilst waiting for CSS with MonoBook
+* (bug 211) Fix tabbed preferences with XHTML MIME type
+* Fix for script execution vulnerability.
+
+=== Beta 6 fixes ===
+
+* (bug 1335) implement 'tooltip-watch' in Language.php
+* Fix linktrail for nn: language
+* (bug 1214) Fix prev/next links in Special:Log
+* (bug 1354) Fix linktrail for fo: language
+* (bug 512) Reload generated CSS on preference change
+* (bug 63) Fix displaying as if logged in after logout
+* Set default MediaWiki:Sitenotice to '-', avoiding extra database hits
+* Skip message cache initialization on raw page view (quick hack)
+* Fix notice errors in wfDebugDieBacktrace() in XML callbacks
+* Suppress notice error on bogus timestamp input (returns epoch as before)
+* Remove unnecessary initialization and double-caching of parser variables
+* Call-tree output mode for profiling
+* (bug 730) configurable $wgRCMaxAge; don't try to update purged RC entries
+* Add $wgNoFollowLinks option to add rel="nofollow" on external links
+ (on by default)
+* (bug 1130) Show actual title when moving page instead of encoded one.
+* (bug 925) Fix headings containing <math>
+* (bug 1131) Fix headings containing interwiki links
+* (bug 1380) Update Nynorsk language file
+* (bug 1232) Fix sorting of cached Special:Wantedpages in miser mode
+* (bug 1217) Image within an image caption broke rendering
+* (bug 1384) Make patrol signs have the same width for page moves as for edits
+* (bug 1364) fix "clean up whitespace" in Title:SecureAndSplit
+* (bug 1389) i18n for proxyblocker message
+* Add fur/Furlan/Friulian to language names list
+* Add TitleMoveComplete hook on page renames
+* Allow simple comments for each translation rules in MW:Zhconversiontable
+* (bug 1402) Make link color of tab subject page link on talk page indicate whether article exists
+* (bug 1368) Fix SQL error on stopword/short word search w/ MySQL 3.x
+* Translated Hebrew namespace names
+* (bug 1429) Stop double-escaping of block comments; fix formatting
+* (bug 829) Fix URL-escaping on block success
+* (bug 1228) Fix double-escaping on &amp; sequences in [enclosed] URLs
+* (bug 1435) Fixed many CSS errors
+* (bug 1457) Fix XHTML validation on category column list
+* (bug 1458) Don't save if edit form submission is incomplete
+* Logged-in edits and preview of user CSS/JS are now locked to a session token.
+* Per-user CSS and JavaScript subpage customizations now disabled by default.
+ They can be re-enabled via $wgAllowUserJs and $wgAllowUserCss.
+* Removed .ogg from the default uploads whitelist as an extra precaution.
+ If your web server is configured to serve Ogg files with the correct
+ Content-Type header, you can re-add it in LocalSettings.php:
+ $wgFileExtensions[] = 'ogg';
+
+=== RC1 fixes ===
+
+* Fix notice error on nonexistent template in wikitext system message
+* (bug 1469) add missing <ul> tags on Special:Log
+* (bug 1470) remove extra <ul> tags from Danish log messages
+* Fix notice on purge w/ squid mode off
+* (bug 1477) hide details of SQL error messages by default
+ Set $wgShowSQLErrors = true for debugging.
+* (bug 1430) Don't check for template data when editing page that doesn't exist
+* Recentchanges table purging fixed when using table prefix
+* (bug 1431) Avoid redundant objectcache garbage collection
+* (bug 1474) Switch to better-cached index for statistics page count
+* Run Unicode normalization on all input fields
+* Fix translation for allpagesformtext2 in LanguageZh_cn and LanguageZh_tw
+* Block image revert without valid login
+* (bug 1446) stub Bambara (bm) language file using French messages
+* (bug 1432) Update Estonian localization
+* (bug 1471) unclosed <p> tag in Danish messages
+* convertLinks script fixes
+* Corrections to template loop detection
+* XHTML encoding fix for usernames containing & in Special:Emailuser
+* (for zh) Search for variant links even when conversion is turned off,
+ to help prevent duplicate articles.
+* Disallow ISO 8859-1 C1 characters and "no-break space" in user names
+ on Latin-1 wikis.
+* Correct the name of the main page it LanguageIt
+* Allow Special:Makesysop to work for usernames containing SQL special
+ characters.
+* Fix annoying blue line in Safari on scaled-down images on description page
+* Increase upload sanity checks
+* Fix XSS bug in Media: links
+* Add cross-site form submission protection to various actions
+* Fix fatal error on some dubious page titles
+* Stub threshold displays correctly again
+
+
+=== 1.4.0 final fixes ===
+
+* (bug 65) Fix broken interwiki link encoding on Latin-1 wikis; force to UTF-8
+* (bug 563) Fix UTF-8 interwiki URL redirects via Latin-1 wikis
+* (bug 1536) Fix page info
+* Support os (Ossetic) as language code, using Russian localization base
+* (bug 1610) Support non (Old Norse) as language code, using Icelandic localization base
+* (bug 1618) Properly list custom namespaces in Special:Allpages
+* (bug 1622) Remove trailing' >' when using category browser
+* (bug 1570) Fix php 4.2.x error on conflict merging
+* (bug 1585) Fix page title on post-login redirection page
+* Run UTF-8 validation on old text in Recentchanges RSS diffs
+* (bug 1642) fix a mime type typo in img_auth.php
+* Automated interwiki redirects only for local interwikis
+* Respect read-only mode on block removals
+* Trim old illegal characters from syndication feeds
+* Reduce message cache outage recovery delay from 1 day to 5 minutes
+* (bug 1403) Update Finnish localization
+* (bug 1478) Punjabi localization
+* (bug 1667) Update script 5 second countdown.
+* (bug 1057) Fix logging table encoding (error on MySQL 4.1)
+* (bug 1680) Fix linktrail for fo
+* (bug 1653) Removing hardcoded messages in Special:Allmessages
+* (bug 1594) Render a hyphen in a formula as &minus; in HTML
+* (bug 1495) Fall back to default language MediaWiki: for custom messages
+* (bug 1617) Show different error messages for "user does not
+ exist" and "wrong password" when using AuthPlugin
+* (bug 1532), (bug 1544) Changed language names for
+ 'bn', 'bo', 'dv', 'dz', 'ht', 'ii', 'li', 'lo', 'ng', 'or', 'pa', 'si',
+ 'ti', 've'
+* Fix editing on non-Esperanto wiki with user language pref set to Esperanto
+* Make conversion table for zh-sg default to zh-cn, and zh-hk default to zh-tw
+* Fix PHP notice in MonoBook when counters disabled
+* (bug 1696) Update namespaces, dates in uk localization
+* (bug 551) Installer warns about magic_quotes_runtime and magic_quotes_sybase
+ instead of trying to install with corrupt table files
+* Installer no longer tries to move non-default MediaWiki: pages into Template:
+* User-to-user email disabled by default ($wgEnableUserEmail)
+
+
+=== 1.4.1 fixes ===
+
+* (bug 1720) fix genitive month names for uk
+* (bug 1704) fixed untranslateable string in Special:Log
+* (bug 1638) Added Belrusian language file
+* (bug 1736) typo in SpecialValidate.php
+* (bug 73) Upload doesn't run edit updates on description page (links,
+ search index and categories)
+* (bug 646) <math> fails to recognize \ll and \gg
+* (bug 926) \div element from TeX not supported in <math> element
+* (bug 1147) add \checkmark to whitelist in texutil.ml
+* (bug 937) \limits function from LaTeX not supported in <math> element
+* Support for manually converting article title to different Chinese
+ variants (for zh)
+* (bug 1488, bug 1744) Fix encoding for preferences, dates in Latin-1 mode
+* (bug 1042) Fix UTF-8 case conversion for PHP <4.3 with mbstring extension
+* Fix code typo that broke article credits display
+* Installation fixes for running under IIS
+* (bug 1556) login page tab order. "remember" checkbox now come after password.
+* SQL debug log fixlets
+* (bug 1815) Fix namespace in old revision display with mismatched title
+* (bug 1788) Fix link duplication when edit/upload comment includes newlines
+* Change default on $wgSysopUserBans and $wgSysopRangeBans to true
+* Fix link conversion for URL request
+* (bug 1851) Updated download URL for the SCIM packages used by zhtable
+* (bug 1853) Try stripping quotes from term for 'go' title match
+* Fix missing function in Latin1 mode
+* (bug 1860) Anchors of interwiki links did not get normalized
+* (bug 1847) accept lowercase x in ISBN, do not accept invalid A-W,Y,Z
+* Fix link conversion for URL request, hopefully without breaking the wiki
+* (bug 1849) New option allows to consider categorized images as used on
+ Special:Unusedimages
+* Localized category namespace for ka (Georgian)
+* (bug 1107) Work around includes problem in installer when parent dir is not
+ readable by the web server
+* (bug 1927) Incorrect escaping on wikitext message in Blockip
+
+
+=== 1.4.2 fixes ===
+
+* Fix math options in Finnish localization
+* Use in-process Tidy extension if available when $wgUseTidy is on
+* (bug 1933) Fix PATH_INFO usage under IIS with PHP ISAPI module
+* (bug 1188) <nowiki> in {{subst:}} includes fixed
+* (bug 1936) <!-- comments --> in {{subst:}} includes fixed
+* Fix a potential MSIE JavaScript injection vector in Tidy mode
+
+
+=== 1.4.3 fixes ===
+
+* (bug 1636) Refs like &#0355; were misinterpreted as octal in some places
+* (bug 1163) Special:Undelete showed oldest revision instead of newest
+* (bug 1938) Fix escaping of illegal character references in link text
+* (bug 1997) Fix for error on display of renamed items in Recentchanges on PHP5
+* (bug 1949) Profiling typo in rare error case
+* (bug 1963) Fix deletion log link when $wgCapitalLinks is off
+* (bug 1970) Don't show move tab for immobile pages
+* (bug 1770) Page creation recorded links from the 'newarticletext' message
+* Optional change to the site_stats table. When applied, this removes the need
+ for expensive queries in Special:Statistics.
+
+
+=== 1.4.4 fixes ===
+
+* (bug 725) Let dir="ltr" attribute work again in MonoBook on RTL languages
+* (bug 2024) Skip JavaScript error for custom skins where .js message not set
+* (bug 2025) Updated Indonesian localization
+* (bug 2039) Updated Lithuanian localization
+
+
+=== Caveats ===
+
+Some output, particularly involving user-supplied inline HTML, may not
+produce 100% valid or well-formed XHTML output. Testers are welcome to
+set $wgMimeType = "application/xhtml+xml"; to test for remaining problem
+cases, but this is not recommended on live sites. (This must be set for
+MathML to display properly in Mozilla.)
+
+
+For notes on 1.3.x and older releases, see HISTORY.
+
+
+=== Online documentation ===
+
+Documentation for both end-users and site administrators is currently being
+built up on Meta-Wikipedia, and is covered under the GNU Free Documentation
+License:
+
+ http://meta.wikipedia.org/wiki/Help:Contents
+
+
+=== Mailing list ===
+
+A MediaWiki-l mailing list has been set up distinct from the Wikipedia
+wikitech-l list:
+
+ http://mail.wikipedia.org/mailman/listinfo/mediawiki-l
+
+A low-traffic announcements-only list is also available:
+ http://mail.wikipedia.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/INSTALL b/INSTALL
new file mode 100644
index 000000000000..4c69dcf92c91
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,106 @@
+---
+Installing MediaWiki
+---
+
+Starting with MediaWiki 1.2.0, it's possible to install
+and configure the wiki "in-place", as long as you have
+the necessary prerequisites available.
+
+Required software:
+* Web server with PHP 5.x or higher.
+* A MySQL server, 4.0.14 or higher OR a Postgres server, 8.1 or higher
+
+MediaWiki is developed and tested mainly on Unix/Linux
+platforms, but should work on Windows as well.
+
+If your PHP is configured as a CGI plug-in rather than
+an Apache module you may experience problems, as this
+configuration is not well tested. safe_mode is also not
+tested and unlikely to work.
+
+If you want math support see the instructions in math/README
+
+Don't forget to check the RELEASE-NOTES file...
+
+
+Additional documentation is available online, which may include more
+detailed notes on particular operating systems and workarounds for
+difficult hosting environments:
+
+http://meta.wikimedia.org/wiki/Help:Installation
+
+
+********************** WARNING **************************
+
+REMEMBER: ALWAYS BACK UP YOUR DATABASE BEFORE ATTEMPTING
+TO INSTALL OR UPGRADE!!!
+
+********************** WARNING **************************
+
+----
+In-place web install
+----
+
+Decompress the MediaWiki installation archive either on
+your server, or on your local machine and upload the
+directory tree. Rename it from "mediawiki-1.x.x" to
+something nice, like "wiki", since it'll be in your URL.
+
+ +-----------------------------------------------------------+
+ | Hint: If you plan to use a fancy URL-rewriting scheme |
+ | to prettify your URLs, you should put the files in a |
+ | *different* directory from the virtual path where page |
+ | names will appear. |
+ | |
+ | See: http://meta.wikimedia.org/wiki/Rewrite_rules |
+ +-----------------------------------------------------------+
+
+To run the install script, you'll need to temporarily make
+the 'config' subdirectory writable by the web server. The
+simplest way to do this on a Unix/Linux system is to make
+it world-writable:
+
+ chmod a+w config
+
+Hop into your browser and surf into the wiki directory.
+It'll direct you into the config script. Fill out the form...
+remember you're probably not on an encrypted connection.
+Gaaah! :)
+
+If all goes well, you should soon be told that it's set up
+your wiki database and written a configuration file. There
+should now be a 'LocalSettings.php' in the config directory;
+move it back up to the main wiki directory, and the wiki
+should now be working.
+
+ +------------------------------------------------------------+
+ | Security hint: if you have limited access on your server |
+ | and cannot change ownership of files, you might want to |
+ | *copy* instead of *move* LocalSettings.php. |
+ | |
+ | This will make the file owned by your user account |
+ | instead of by the web server, which is safer in case |
+ | another user's account is compromised. |
+ +------------------------------------------------------------+
+
+Once the wiki is set up, you should remove the config
+directory, or at least make it not world-writable (though
+it will refuse to config again if the wiki is set up).
+
+
+----
+
+Don't forget that this is free software under development!
+Chances are good there's a crucial step that hasn't made it
+into the documentation. You should probably sign up for the
+MediaWiki developers' mailing list; you can ask for help (please
+provide enough information to work with, and preferably be aware
+of what you're doing!) and keep track of major changes to the
+software, including performance improvements and security patches.
+
+http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce (low traffic)
+
+http://lists.wikimedia.org/mailman/listinfo/mediawiki-l (site admin support)
+
+http://lists.wikimedia.org/mailman/listinfo/wikitech-l (development)
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000000..0cfba45ad453
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,2 @@
+test: Test.php
+ prove -r t
diff --git a/README b/README
new file mode 100644
index 000000000000..427b5479e6eb
--- /dev/null
+++ b/README
@@ -0,0 +1,103 @@
+2006-04-05
+
+For system requirements, installation and upgrade details, see the files RELEASE-NOTES,
+INSTALL, and UPGRADE.
+
+== MediaWiki ==
+
+MediaWiki is the software used for Wikipedia [http://www.wikipedia.org/] and the
+other Wikimedia Foundation websites. Compared to other wikis, it has an
+excellent range of features and support for high-traffic websites using
+multiple servers (Wikimedia sites peak in the 5000+ requests per second range
+as of November 2005).
+
+While quite usable on smaller sites, you may find you have to "roll your own"
+local documentation, and some aspects of configuration may seem overcomplicated
+because MediaWiki is primarily targeted as an in-house tool.
+
+The MediaWiki software was written by:
+* Lee Daniel Crocker
+* Magnus Manske
+* Jan Hidders
+* Brion Vibber
+* Axel Boldt
+* Geoffrey T. Dairiki
+* Tomasz Wegrzanowski
+* Erik Moeller
+* Tim Starling
+* Gabriel Wicke
+* Ashar Voultoiz
+* Evan Prodromou
+* Ævar Arnfjörð Bjarmason
+* Niklas Laxström
+* Domas Mituzas
+* Rob Church
+* Jens Frank
+* Several others
+
+The contributors hold the copyright to this work, and it is licensed
+under the terms of the GNU General Public License, version 2 or later[1]
+(see http://www.fsf.org/licenses/gpl.html). Derivative works and later
+versions of the code must be free software licensed under the same
+terms. This includes "extensions" that use MediaWiki functions or
+variables; see http://www.gnu.org/licenses/gpl-faq.html#GPLAndPlugins
+for details.
+
+The Wikimedia Foundation currently has no legal rights to the software.
+
+[1] Sections of code written exclusively by Lee Crocker or Erik Moeller are
+also released into the public domain, which does not impair the obligations of
+users under the GPL for use of the whole code or other sections thereof.
+
+[2] MediaWiki makes use of the Sajax Toolkit by modernmethod,
+ http://www.modernmethod.com/sajax/
+ which has the following license:
+
+ 'This work is licensed under the Creative Commons Attribution
+ License. To view a copy of this license, visit
+ http://creativecommons.org/licenses/by/2.0/ or send a letter
+ to Creative Commons, 559 Nathan Abbott Way,
+ Stanford, California 94305, USA.'
+
+Many thanks to the Wikimedia regulars for testing and suggestions.
+
+The official website for mediawiki is located at:
+
+ http://www.mediawiki.org/
+
+The code is currently maintained in a Subversion repository
+at svn.wikimedia.org. See http://www.mediawiki.org/wiki/Subversion
+for details.
+
+Please report bugs and make feature requests in our Bugzilla system:
+
+ http://bugzilla.wikimedia.org/
+
+Documentation and discussion on new features may be found at:
+
+ http://www.mediawiki.org/wiki/Help:FAQ
+ http://www.mediawiki.org/wiki/Documentation
+ http://www.mediawiki.org/wiki/Development
+
+Extensions are listed at:
+
+ http://meta.wikimedia.org/wiki/Category:MediaWiki_extensions
+
+If you are setting up your own wiki based on this software, it is highly
+recommended that you subscribe to mediawiki-announce:
+
+ http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce
+
+The mailing list is very low volume, and is intended primarily for
+announcements of new versions, bug fixes, and security issues.
+
+A higher volume support mailing list can be found at:
+
+ http://mail.wikimedia.org/mailman/listinfo/mediawiki-l
+
+Developer discussion takes place at:
+
+ http://mail.wikimedia.org/mailman/listinfo/wikitech-l
+
+There is also a development and support channel #mediawiki on
+irc.freenode.net, and an unoffical support forum at www.mwusers.com.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
new file mode 100644
index 000000000000..5225384168f9
--- /dev/null
+++ b/RELEASE-NOTES
@@ -0,0 +1,995 @@
+= MediaWiki release notes =
+
+Security reminder: MediaWiki does not require PHP's register_globals
+setting since version 1.2.0. If you have it on, turn it *off* if you can.
+
+== MediaWiki 1.9.6 ==
+
+March 2, 2008
+
+* Correction for API path fix, broken in 1.9.5
+
+
+== MediaWiki 1.9.5 ==
+
+January 23, 2008
+
+This is a security update to the Winter 2007 quarterly release. A potential
+XSS injection vector affecting api.php only for Microsoft Internet Explorer
+users has been closed.
+
+
+To work around the vulnerability without upgrading, you may disable the
+API if you don't need it:
+
+ $wgEnableAPI = false;
+
+Not vulnerable versions:
+* 1.12 or later
+* 1.11 >= 1.11.1
+* 1.10 >= 1.10.3
+* 1.9 >= 1.9.5
+* 1.8 any version (if $wgEnableAPI has been left off)
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.2
+* 1.9 <= 1.9.4
+* 1.8 any version (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include
+the API functionality, however the BotQuery extension is similarly
+vulnerable unless updated to the latest SVN version.
+
+
+== MediaWiki 1.9.4 ==
+
+September 10, 2007
+
+This is a security and bug fix update to the Winter 2007 quarterly release.
+Minor compatibility fixes for IIS 5 are included.
+
+* (bug 8847) Strip spurious #fragments from request URI to fix redirect
+ loops on some server configurations
+* A possible HTML/XSS injection vector in the API pretty-printing mode
+ has been found and fixed.
+
+The vulnerability may be worked around in an unfixed version by simply
+disabling the API interface if it is not in use, by adding this to
+LocalSettings.php:
+
+ $wgEnableAPI = false;
+
+Not vulnerable versions:
+* 1.11 >= 1.11.0
+* 1.10 >= 1.10.2
+* 1.9 >= 1.9.4
+* 1.8 >= 1.8.5
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.1
+* 1.9 <= 1.9.3
+* 1.8 <= 1.8.4 (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include
+the faulty function, however the BotQuery extension is similarly
+vulnerable unless updated to the latest SVN version.
+
+
+== MediaWiki 1.9.3 ==
+
+February 20, 2007
+
+This is a security and bug-fix update to the Winter 2007 quarterly release.
+Minor compatibility fixes for IIS and PostgreSQL are included.
+
+An XSS injection vulnerability based on Microsoft Internet Explorer's UTF-7
+charset autodetection was located in the AJAX support module, affecting MSIE
+users on MediaWiki 1.6.x and up when the optional setting $wgUseAjax is
+enabled.
+
+If you are using an extension based on the optional Ajax module,
+either disable it or upgrade to a version containing the fix:
+
+* 1.9: fixed in 1.9.3
+* 1.8: fixed in 1.8.4
+* 1.7: fixed in 1.7.3
+* 1.6: fixed in 1.6.10
+
+There is no known danger in the default configuration, with $wgUseAjax off.
+
+* (bug 8992) Fix a remaining raw use of REQUEST_URI in history
+* (bug 8984) Fix a database error in Special:Recentchangeslinked
+ when using the PostgreSQL database.
+* Add 'charset' to Content-Type headers on various HTTP error responses
+ to forestall additional UTF-7-autodetect XSS issues. PHP sends only
+ 'text/html' by default when the script didn't specify more details,
+ which some inconsiderate browsers consider a license to autodetect
+ the deadly, hard-to-escape UTF-7.
+ This fixes an issue with the Ajax interface error message on MSIE when
+ $wgUseAjax is enabled (not default configuration); this UTF-7 variant
+ on a previously fixed attack vector was discovered by Moshe BA from BugSec:
+ http://www.bugsec.com/articles.php?Security=24
+* Trackback responses now specify XML content type
+
+
+== MediaWiki 1.9.2 ==
+
+February 4, 2007
+
+This is a bug-fix update that fixes some installation and other minor
+issues with the 1.9.1 release as well as a security issue which was
+introduced in the 1.9 branch.
+
+JavaScript code which regenerated the "sortable tables" feature did
+not properly sanitize input, leading to an HTML injection vulnerability.
+
+* (bug 8774) Fix path for GNU FDL rights icon on new installs
+* (bug 8819) Fix full path disclosure with skins dependencies
+* (bug 4268) Fixed data-loss bug in compressOld batch text compression
+ affecting pages which had null edits (move, protect, etc) as second
+ edit in a batch group. Isolated and patched by Travis Derouin.
+* Security fix for sortable tables JavaScript
+
+
+== MediaWiki 1.9.1 ==
+
+January 24, 2007
+
+This is a bug-fix update that fixes some installation and upgrade issues
+with the original 1.9.0 release.
+
+* (bug 3000) Fall back to SCRIPT_NAME plus QUERY_STRING when REQUEST_URI is
+ not available, as on IIS with PHP-CGI
+* Security fix for DjVu images. (Only affects servers where .djvu file
+ uploads are enabled and $wgDjvuToXML is set.)
+* (bug 8638) Fix update from 1.4 and earlier
+* (bug 8641) Fix order of updates to ipblocks table for updates from <=1.7
+* (bug 8673) Minor fix for web service API content-type header
+* Fix API revision list on PHP 5.2.1; bad reference assignment
+* Fixed up the AjaxSearch
+* Exclude settings files when generating documentation. That could
+ expose the database user and password to remote users.
+* ar: fix the 'create a new page' on search page when no exact match found
+* Correct tooltip accesskey hint for Opera on the Macintosh
+ (uses Shift-Esc-, not Ctrl-).
+* (bug 8719) Firefox release notes lie! Fix tooltips for Firefox 2 on x11;
+ accesskeys default settings appear to be same as Windows.
+
+
+== MediaWiki 1.9 ==
+
+January 10, 2007
+
+This is the quarterly release snapshot for Winter 2007. While the code
+has been running on Wikipedia for some time, installation and upgrade
+bits may be less well tested. Bug fix releases may follow in the coming
+days or weeks.
+
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept
+"ready to run", and in fact runs our own sites on Wikipedia.
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature development happen
+will be made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain
+it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+
+
+== Security fixes ==
+
+An XSS injection vulnerability was located in the AJAX support module,
+affecting MediaWiki 1.6.x and up when the optional setting $wgUseAjax
+is enabled.
+
+There is no danger in the default configuration, with $wgUseAjax off.
+
+If you are using an extension based on the optional Ajax module,
+either disable it or upgrade to a version containing the fix:
+
+* 1.9: fixed in 1.9.0rc2
+* 1.8: fixed in 1.8.3
+* 1.7: fixed in 1.7.2
+* 1.6: fixed in 1.6.9
+
+
+== Compatibility changes ==
+
+=== Zend Optimizer ===
+
+A bug in some versions of PHP 5 and Zend Optimizer which was triggered under
+MediaWiki 1.8.x has been worked around by disabling some internal debugging
+features when Zend Optimizer is loaded. This should solve some common
+"blank page" problems.
+
+=== PHP 5.0 64-bit ===
+
+MediaWiki now checks for a condition where PHP 5.0.x corrupts array data
+on 64-bit systems and warns you to upgrade PHP to solve the problem. This
+bug causes Special: pages to fail on affected systems under MediaWiki 1.8
+and higher, and subtler data corruption on earlier versions.
+
+The only known workaround is to upgrade PHP to 5.1 or later, which you
+probably should do anyway for security reasons!
+
+=== MySQL 5 ===
+
+MediaWiki should now install and run correctly on MySQL 5.0 and higher when
+MySQL's "strict mode" is enabled. (This is now the default for many Windows
+installations, though it seems to remain off by default on Unix.)
+
+This fixes errors about "cannot default default value for BLOB/TEXT fields".
+
+=== ImageMagick ===
+
+Note that ImageMagick older than 6.x may no longer work for image resizing
+due to use of the -thumbnail option.
+
+
+== Behavior changes ==
+
+=== Localized special pages ===
+
+The names of Special: pages can now be localized, so links and URLs to them
+are more legible in languages that aren't English.
+
+Not all languages have included localized names yet.
+
+=== E-mail password ===
+
+Users are now required to set a new password for themselves when they first
+log in with a newly generated e-mailed password.
+
+Requesting passwords frequently is prevented to reduce abusive mailbombing.
+
+=== Undo revision ===
+
+An "undo" link now appears in diff view for easier reverting of older edits.
+When GNU diff3 is available for edit conflict merging, this can make it much
+easier to "undo" the changes of an older edit when there are surrounding
+changes elsewhere in the page.
+
+The changes must be manually reviewed and approved, as with conventional
+full-revision reverts.
+
+=== Blocking ===
+
+User blocks can be set to disable the automatic blocking of IP addresses the
+account logs in with.
+
+
+== Database changes ==
+
+* new 'redirect' table stores data on page redirects
+* new 'querycachetwo' table used for some cached special pages
+* 'ipblocks' table adds 'ipb_enable_autoblock'
+* 'recentchanges' table adds 'rc_old_len', 'rc_new_len' for size tracking
+* 'user' table has added 'user_newpass_time' and 'user_editcount' fields
+* some indexes have been updated on 'recentchanges'
+
+
+== Configuration changes ==
+
+Several configuration options have changed since 1.8:
+
+=== $wgEnableAPI ===
+
+The experimental machine API interface is now enabled by default, read-only.
+You can disable it by setting $wgEnableAPI = false; in LocalSettings.php.
+
+=== $wgPathInfo ===
+
+The use of PATH_INFO (the text after the script name in 'index.php/Blah')
+is controlled by the $wgUsePathInfo setting. This is now explicitly disabled
+for CGI, apache2filter, and ISAPI configurations of PHP, for more consistency
+with the autodetection from the installer.
+
+In some rarer configurations you may have to switch $wgUsePathInfo from false
+to true or, perhaps, from true to false to make things work properly if bad
+PATH_INFO data comes through the server.
+
+The wiki now tries to detect this condition and should show you an error
+message describing what to change instead of sending the browser into an
+infinite redirect loop.
+
+=== $wgScript and other path settings ===
+
+The following configuration variables are now automatically set in Setup.php
+if they are not overridden in LocalSettings.php:
+
+from $wgScriptPath:
+ + $wgScript
+ | \- $wgArticlePath
+ + $wgRedirectScript
+ + $wgStylePath
+ + $wgUploadPath
+ \- $wgLogo
+ + $wgMathPath
+
+from $IP:
+ - $wgStyleDirectory
+ + $wgUploadDirectory
+ \- $wgMathDirectory
+ + $wgTmpDirectory
+ + $wgReadOnlyFile
+ + $wgFileCacheDirectory
+
+Newly generated configuration files will by default include only $wgScriptPath
+(hardcoded from the installer) and $IP (detected at runtime).
+
+Old configuration files which specify all these values explicitly should
+continue to work just fine, but if you use the defaults you can remove them
+to reduce clutter.
+
+=== $wgGroupPermissions ===
+
+The sysop group now holds the "autopatrol" and "ipblock-exempt" rights by
+default.
+
+"autopatrol" replaces the preference for marking ones own edits patrolled
+by default; users holding this permission will automatically have their
+edits patrolled, while others cannot mark their own edits as patrolled
+even if they have patrolling rights.
+
+"ipblock-exempt" excludes the user from IP blocks; accounts which are blocked
+explicitly by name will still be blocked, however. This is given to sysops
+to minimize annoyance from accidental "collateral damage"; remember that a
+sysop will be able to lift the block if they desire.
+
+The bot group now holds the "nominornewtalk" right. A user with this right
+will not trigger new message notifications when making minor edits to user
+talk pages. This is meant to minimize annoyance from maintenance bot
+processes.
+
+=== $wgUseWatchlistCache ===
+
+Watchlist caching has been removed. The feature was not maintained, and has
+been unnecessary since switching to the 'recentchanges' database table
+reduced server pressure for Wikipedia's watchlists.
+
+=== $wgBreakFrames ===
+
+MediaWiki in the past attempted to detect when it was embedded in a frameset
+and "break out" of it, assuming it to be hostile.
+
+This behavior is now disabled by default, but can be reenabled by setting
+$wgBreakFrames to true in LocalSettings.php.
+
+
+== New settings ==
+
+=== $wgVariantArticlePath ===
+
+For languages with script variant support (Chinese, Serbian, and others),
+it's possible to use alternate URL paths to select the variant for article
+display, setting $wgVariantArticlePath.
+
+Documentation for this setting would be useful.
+
+=== $wgMaxMsgCacheEntrySize ===
+
+The message cache can now skip items larger than a given size; this allows
+it to better handle the primary caching case when large CSS and JS blobs are
+present.
+
+=== $wgStyleVersion ===
+
+When making significant changes to skin stylesheets and JavaScript files,
+you can append a string to this variable to tweak the generated URLs,
+forcing newly rendered pages to bring in a fresh version despite server-
+or browser-side caching.
+
+Normally this will be set in the course of MediaWiki development, but
+if doing development on a custom skin you may wish to poke it as well.
+
+=== $wgRCShowChangedSize ===
+
+Special:Recentchanges and Special:Watchlist now show the number of bytes
+added or removed to an article to give an idea of the size of the edit.
+This information was previously available only in the IRC update feeds.
+
+To disable this site-wide, set $wgRCShowChangedSize to false.
+(Individual users can suppress the data in custom CSS.)
+
+Adjust $wgRCChangedSizeThreshold to trigger highlighting of particularly
+large changes.
+
+The formatting of the size figure can be adjusted through the
+[[MediaWiki:Rc-change-size]] message.
+
+=== $wgQueryCacheLimit ===
+
+The number of rows stored for "expensive" special pages in miser mode
+can now be adjusted up or down from the default 1000.
+
+=== $wgDisableQueryPageUpdate ===
+
+Individual "expensive" special pages can be skipped in processing by
+updateSpecialPages if added to this list.
+
+=== $wgSorbsUrl ===
+
+The base hostname for the DNS-based proxy blacklist can now be overridden
+when $wgEnableSorbs is set, to use a different blacklist instead of SORBS.
+The blacklist would need to respond the same was as SORBS; any positive
+response will be taken as a proxy.
+
+=== $wgAjaxWatch ===
+
+Experimental AJAX mode for the watch/unwatch tabs to execute inline.
+Does not include the UI messages describing how to reach the watchlist,
+so you may not want it on a general-audience site just yet.
+
+=== $wgParserTestFiles ===
+
+MediaWiki's parser test suite can now be expanded with additional test
+files. Custom extensions can add their test files to this array, and
+they will be run along with the main tests by maintenance/parserTests.php
+
+
+== Changes since 1.8 ==
+
+* (bug 8200) Make category lists sorted by name when using Postgres.
+* (bug 7841) Support 'IGNORE' inserts for Postgres, fixes watchlist
+ adding problem.
+* (bug 6835) Removing the includes/Parser.php::getTemplateArgs() function,
+ because it seems to be unused.
+* (bug 7139) Increasing the visual width of the edit summary field on larger
+ screen sizes, for the default monobook skin.
+* Fix PHP notice and estimates for dumpBackup.php and friends
+* Improved register_globals paranoia checks
+* (bug 7545) Fix PHP version check on install
+* Disable PHP exception backtrace printing unless $wgShowExceptionDetails
+ is set. Backtraces may contain sensitive information in function call
+ parameters.
+* (bug 6164) Avoid smashing Cite state if message transformation triggers
+ during bad image list check, by skipping message transformation.
+ This isn't a good permanent fix.
+* (bug 6918) Stopped borders and backgrounds from showing through floated
+ tables in Monobook
+* (bug 6868) Un-hardcode section edit link style
+* (bug 3205) Stop right floats from stacking horizontally in non-Monobook skins
+* Added global $wgStyleVersion to centralize bumping CSS and JS file versions
+ for cache-friendly style and script updating
+* (bug 7562) Fix non-ASCII namespaces on Windows/XAMPP servers
+* Friendlier check for PHP 5 in command-line scripts; it's common for parallel
+ PHP 4 and 5 installations to interfere on the command-line.
+* Fix regression in autoconfirm permission check
+* (bug 3015) Add CSS ids to subcategory and page sections on category pages
+* (bug 7587) Fix erroneous id for specialpage tab, enabling informative popup
+* (bug 7599) Fix thumbnail purging, PHP notices on HTCP image page purge
+* (bug 7581) Update language name for cbk-zam
+* (bug 7444) Update namespace translations for Telugu (te), kept old values as
+ alias for compatibility
+* (bug 4525) Move section links down visually to same level as headings
+ (editsection links are now inside the heading elements)
+* Workaround for http://bugs.php.net/bug.php?id=31892 , PATH_INFO and hence
+ URLs of the style /index.php/Main_Page were broken on some CGI installations.
+* (bug 7623) Validate custom HTML id's correctly in Monobook interface
+* (bug 2241) Fix collision of 'w' and 'd' accesskeys
+* (bug 5795) CSS class added to body based on page name for page-specific
+ styling
+* (bug 6276) Stopped search field from getting too large in Cologne Blue
+* (bug 7644) User creations that are aborted by hooks shouldn't be counted
+ against account creations per day limit
+* (bug 7636) Show Firefox 2 users correct accesskey prefix
+* (bug 6427) Block blocked IPs from using the mail password function
+ to allow blocking of flooders
+* Include common.css from classic-style skins in main HTML with the bump URL
+* (bug 7607) Add Karakalpak (kaa) to Names.php and stub message file for linktrail
+* (bug 7582) Add 'tog-nolangconversion' to MessagesEn.php.
+ This key is need for languages with variants (zh, sr, kk)
+* (bug 7606) MediaWiki messages for "rss" and "atom" missing
+* (bug 7609) Add some more '*-summary' messages to MessagesEn.php with empty
+ strings to allow better localisation via Special:Allmessages. Mark this new
+ messages as optional for localisation.
+* Fix user_newpass upgrade for prefixed tables (reported by Fyren)
+* (bug 7663) Include language variant switcher links on Nostalgia skin
+* (bug 6531) Fix PHP fatal error on installation page with bad username input.
+* (bug 6977) Remove 404 link for autogenerated database documentation.
+* (bug 7369) Allow "Show Changes" without requiring edit token.
+* (bug 7687) Fix movetalk box checks itself when confirming a delete and move.
+* (bug 7684) Obey watchcreated preference for Special:Upload watch checkbox
+* (bug 7686) Include id attribute on delete form confirmation button
+* Allow compound interwiki prefixes in $wgImportSources
+* (bug 7304) Added redirect table to store redirect targets.
+* Added querycachetwo table (similar to querycache but has two titles)
+* PageArchive can now return a Revision object for more convenient processing
+ of deleted revision data
+* Added 'UndeleteShowRevision' hook in Special:Undelete
+* Error message on attempt to view invalid or missing deleted revisions
+* Remove unsightly "_" from namespace in Special:Allpages, Special:Prefixindex
+* (bug 3224) Allow minor edits by bots to skip new message notification on
+ user talk pages. This can be disabled by adjusting the 'nominornewtalk'
+ permission. Patch by Werdna.
+* (bug 7741) MATH: fixed broken syntax of underbrace etc. Fixed arrays
+* Fix purging for updated SVG files
+* (bug 7745) Add id attribute to search button in Monobook
+* (bug 7749) MATH: added some more LaTeX symbols, e.g. parallel, diamond, ast, ...
+* (bug 7304) Added code in Article.php to keep redirect table up to date.
+* Made special page names case-insensitive and localisable. Care has been taken
+ to maintain backwards compatibility.
+* Used special page subpages in a few more places, instead of query parameters.
+* (bug 7758) Added wrapper span to "templates used" explanation to allow CSS
+ styling (class="mw-templatesUsedExplanation").
+* Added {{#special:}} parser function, to give the local default title for
+ special pages
+* (bug 7766) Remove redundant / from AJAX requests, can break some servers
+* Add tab links from extensions to classic-based skins (SkinTemplateTab hook)
+ Provides better cross-skin compatibility for extensions using the modern
+ skin hooks, such as Oversight
+* Moved variant language links on Cologne Blue and Nostalgia to before the
+ login/logout link
+* Fix for parser tests with MySQL 5 in strict mode
+* Added block option "enable autoblocks"
+* Amend Special:Ipblocklist to note when a block has autoblock DISABLED.
+* (bug 7780) Fix regression in editing redirects
+* Add whitespace above "templates included on this page" using CSS, not
+ hardcoded line break.
+* Remove entries from redirect table on article deletion
+* (bug 7788) Force section headers in new section links for users who have
+ 'prompt for blank edit summaries' on.
+* (bug 1133) Special:Emailuser: add an option to send yourself a copy of your mail.
+* (bug 461) Allow "Categories:" link at bottom of pages to be customized via
+ pagecategorieslink message.
+* Sort the list of skins in "My Preferences" -> Skins by alphabetical order.
+* (bug 7785) Postgres compatibility for timestamps in RC feeds
+* (bug 7550) Normalize user parameter normally on Special:Log
+* (bug 7294) Fix PATH search for diff3 on install
+* Various fixes related to the blocking change re: autoblocks. On inserting
+ an IP block, the ipb_enable_autoblock field is now automagically blanked,
+ because it doesn't make any sense for an IP. Additionally, IP blocks
+ without the ipb_enable_autoblock option no longer show up as "autoblock
+ disabled" on Special:Ipblocklist.
+* (bug 7774) MATH: aded more amstex functions
+* (bug 1182) MATH: fixed inconsistent rendering of upper case Greek letters in TeX
+* Fix regression in streaming page dump generation
+* (bug 7801) Add support for parser function hooks in parser tests
+* checkUsernames.php now uses wfDebugLog instead of hardcoded path to log
+* (bug 7810) Update talk namespaces for Occitan
+* Allow case-sensitive URLs to be used for uploading from URLs.
+* (bug 1109) Correct fix for compressed 304 responses when additional output
+ buffers have been installed within the compression handler
+* (bug 7819) Move automatic redirect edit summary after pre-save transform
+ to work properly with subst: fun
+* (bug 7826) Fix typos in two English messages.
+* (bug 5365) Stop users being prompted to enter an edit summary for null edits,
+ if they have selected that option in preferences.
+* (bug 5936) Show an 'm' to the left of the edit summary on diff pages for minor edits.
+* (bug 7820) Improve error reporting for uploads via URL.
+* (bug 5149) When autoblocks are enabled, retroactively apply an autoblock to the most
+ recently used IP of a user when they are blocked.
+* Add an index on (rc_user_text,rc_timestamp) on the recentchanges table. This will
+ make CheckUser.php and the new retroactive autoblock functionality faster.
+* Fix regression in Special:Undelete for revisions deleted under MediaWiki 1.4
+ with compression or legacy encoding
+* (bug 6737) Fixes for MySQL 5 schema in strict mode
+* Approximate height for client-side scaling fallback instead of passing -1
+ into the HTML output.
+* Make the DNSBL to check for proxy blocking configurable via $wgSorbsUrl
+* Add experimental recording/reporting mode to parser tests runner, to
+ compare changes against the previous run.
+ Additional tables 'testrun' and 'testitem' are in maintenance/testRunner.sql,
+ source this and pass --record option to parserTests.php
+* Make the set of default parser test input files extensible via
+ $wgParserTestFiles. This can now be appended to by extensions or local
+ configuration files so that extension or custom tests can be automatically
+ run along with the main batch.
+* Run PHP install version checks on update.php so command-line updaters see
+ new version requirements
+* Do a check for the PHP 5.0.x 64-bit bug, since this is much more disruptive
+ as of MW 1.8 than it used to be. Install or upgrade now aborts with a
+ warning and a request to upgrade.
+* (bug 6440) Updated indexes to improve backlinking queries (links, templates, images)
+* Switched 'anon-only' block mode to default for IP blocks
+* (bug 3687, 7892) Add distinct heading for media files in category display,
+ with count.
+* (bug 1578) Add different icons for external links to audio, video, or PDF in
+ Monobook.
+* Made autoblocks block account creation if the user block has that option enabled.
+* Add auto-summaries to blankings and large removals without summaries.
+* (bug 7811) Allow preview of edit summaries.
+* (bug 6839) Wikibits.js minor changes to make JS-lint happier.
+* (bug 7932) Make sure that edit toolbar clears floats so it appears correctly.
+* (bug 6873) When viewing old revisions, add link to diff to current version.
+* (bug 3315) Provide rollback link directly on history page.
+* Replace 'old-revision-navigation' message with 'revision-info' and
+ 'revision-nav' messages, wrapped in divs with appropriate id's.
+* (bug 4178) MediaWiki:Common.js will now be included for all users if
+ $wgUseSiteJs is enabled, in addition to (if applicable) MediaWiki:Monobook.js
+ and user JS subpages.
+* (bug 7918) "Templates used on this page" changes during preview to reflect
+ any added or removed templates, and works as expected for section edits.
+* (bug 7919) "Templates used on this page" is now shown for read-only pages.
+* (bug 7688) When viewing diff, section anchors in autosummary jump to section
+ on current page instead of loading the latest version.
+* (bug 7970) Use current connection explicitly on Database::getServerVersion
+* (bug 2001) Tables with class="sortable" can now be dynamically sorted via
+ JavaScript.
+* Added autosummary for new pages with 500 or less characters, and refactor
+ the autosummary code so it's all done in one function. doEdit is getting too
+ big!
+* (bug 7554) The correct MIME type for SVG images is now displayed on the
+ image page (image/svg+xml, not image/svg).
+* (bug 7883) Added autoblock whitelisting feature, using which specific ranges
+ can be protected from autoblocking. These ranges are specified, in list format,
+ in the autoblock_whitelist system message.
+* Added placeholders for text injection by hooks to EditPage.php
+* (bug 8009) Automatic edit summary for redirects is not filled for edits in existing pages
+* Installer support for experimental MySQL 4.1/5.0 binary-safe schema
+* Use INSERT IGNORE for db-based BagOStuff add/insert, for more memcache-like
+ behavior when keys already exist on add (instead of dying with an error...)
+* Add a hook 'UploadForm:initial' before the upload form is generated, and two
+ member variable for text injection into the form, which can be filled by the hooks.
+* (bug 6295) Add a "revision patching" functionality, where an edit can be undone
+ (with a functionality similar to diff rev1 rev2 | patch -R rev3 -o rev3).
+ This is triggered by including &undo=revid in an edit URL. A link to a URL
+ that will undo a given edit is shown on NEW revision headers on diff pages.
+ The link leads to a "Show Changes" page showing what will be done to undo the
+ edit.
+* Fix display of link in "already rolled back" message for image/category pages
+* (bug 6016) Left-aligned images should stack vertically, like right-aligned
+ images, not horizontally.
+* Patch from LeonWP: added UploadForm:BeforeProcessing hook in SpecialUpload.php
+* Add AuthPluginSetup hook to override $wgAuth after configuration
+* Fix regression in authentication hook auto-creation on login
+* (bug 8110) Allow spaces in ISBNs
+* (bug 8024) Introduce "send me copies of emails I send to others" preference
+* Added 'EditPage::attemptSave' hook before an article is saved.
+* (bug 8083) Applied patch for sk localisation
+* Add a backslash character to the edit token, to prevent edits via certain
+ broken proxies that mangle such characters in form submissions
+* (bug 7461) Allow overwriting pages using importTextFile.php
+* (bug 7946) importTextFile.php doesn't perform pre-save transform
+* (bug 8117) {{REVISIONTIMESTAMP}} showed weird default if $wgLocalTZoffset set;
+ now uses current time for previews and if timestamp can't be loaded from DB
+* {{REVISIONTIMESTAMP}} now uses site local timezone instead of user timezone
+ to ensure consistent behavior
+* {{REVISIONTIMESTAMP}} and friends should now work on non-MySQL backends
+* (bug 7671) Observe canonical media namespace prefix in Linker::formatComment
+* Added js variable wgCurRevisionId to the output
+* (bug 8141) Cleanup of Parser::doTableStuff, patch by AzaTht
+* (bug 8042) Make miser mode caching limits settable via $wgQueryCacheLimit
+ instead of hardcoding to 1000
+* Enable QueryPage classes to override list formatting
+* (bug 5485) Show number of intervening revisions in diff view
+* (bug 8100) Fix XHTML validity in Taiwanese localization
+* Added redirect to section feature. Use it wisely.
+* Added a configuration variable allowing the "break out of framesets" feature
+ to be switched on and off ($wgBreakFrames). Off by default.
+* Allow Xml::check() $attribs parameter to override 'value' attribute
+* DB schema change: added two columns (rc_old_len and rc_new_len) to the recentchanges table to store
+ the text lengths before and after the edit
+* (bug 1085) Made Special:Recentchanges show the character difference between the changed revisions
+* Removed a redundant <strong> tag from diff pages that was causing display issues for some users
+* (bug 8203) The keyboard shortcut for "log out" was removed, because users were pressing it
+ when they intended to press the shortcut for "preview".
+* (bug 8148) Handle non-removable output buffers gracefully when cleaning
+ buffers for HTTP 304 responses, StreamFile, and Special:Export.
+ Duplicated code merged into wfResetOutputBuffers() and wfClearOutputBuffers()
+* Special:AllPages : 'next page' link now point to the first title of the next
+ chunk instead of pointing to the last title of current chunk.
+* (bug 4673) Special:AllPages : add a 'previous' link (new message 'prevpage')
+* (bug 8121) wfRandom() was not between 0 and 1
+* Add static method Parser::createAssocArgs($args), so parser functions can
+ use the same code to parse arguments as the templates do.
+* Change behavior of logins using the temporary e-mailed password (as stored
+ in user_newpassword hash field). Instead of just logging in silently and
+ leaving the previous user_password field in place indefinitely, the user
+ is now prompted to set a new password.
+
+ The password-changing form is at Special:Resetpass; currently it's only
+ usable for changing from the temporary password during login, but it
+ could perhaps be generalized, replacing the subform in preferences.
+
+ Once the new password is set successfully, the temporary password is wiped
+ so it cannot be used to login a second time, and the login process
+ is completed.
+* Suppress 'mail new password' button on login form if $wgAuth forbids
+ changing user passwords; it wouldn't work very well...
+* Consolidate password length checks and $wgAuth manipulation into
+ User::setPassword() to avoid duplicate code in different places
+ that set passwords.
+* User::setPassword() now throws PasswordError exceptions if the password
+ is illegal or cannot be set via $wgAuth. These can be caught and a human-
+ readable error message displayed by UI code.
+* Added Title::isSubpage()
+* (bug 8241) Don't consider user pages of User:Foo.css to be CSS subpages
+* Set an explicit class on framed thumbnail inner divs and images, changed some
+ CSS to use these instead of using descendent selectors.
+* Accept null parameter to User::setPassword() as indicating the password
+ field should be cleared to an unusable state. Login will only be possible
+ after the password is reset, for instance by e-mail.
+* (bug 6394) Invalidate the password set for "by e-mail" account creations
+ to avoid accidental empty password creations.
+* Made the show change size function work on page moves, page creations, and
+ log entries. Also fixed it in the javascript recentchanges.
+* (bug 8239) correctly get 50 new contributions when clicking '(50 next)'
+* (bug 2259) Fix old regression where e-mail addresses were no longer
+ confirmed on login with mailed password.
+* Add a notification about the confirmation mail sent during account
+ creation, so people don't immediately go off to request a second one.
+* Add a warning on Special:Confirmemail if a code was already sent and has
+ not yet expired.
+* Add user_editcount field to provide data for heuristics on account use.
+ Incremented on edit, with lazy initialization from past revision data.
+ Can batch-initialize with maintenance/initEditCount.php (not yet friendly
+ to replication environments, this will do all accounts in one query).
+* Allow raw SQL subsections in Database::update() SET portion as well as
+ for WHERE portion. Handy for increments and such.
+* User::getOption now accept a default value to override default user values
+ this makes it consistent with WebRequest::get* methods. Corrected code in
+ various places accordingly.
+* (bug 8264) Fix JavaScript global vars for XHTML mode
+* Make $wgSiteNotice value wikitext again, for consistency with editable
+ MediaWiki:Sitenotice and MediaWiki:Anonnotice.
+* (bug 8044) When redirecting from the canonical name of the special page
+ to the localised one, parameters/subpages are omitted
+* (bug 8164) Special:Booksources should use GET for form submission
+* Rewrite Special:Booksources to clean up interface and remove redundant code
+* (bug 7925) Change Special:Allmessages message name filter javascript to be
+ a bit more responsive and easier on the CPU
+* (bug 4488) Support watching pages on deletion; introduces new user preference
+* Minor restructuring of Special:Preferences; "watch pages I edit" and "watch
+ pages I create" options now accessible under "Watchlist" options
+* (bug 8153) <nowiki> doesn't work in site notice
+* (bug 6690) wfMsgNoTrans() transforms messages
+* (bug 8274) Wrap edit tools in a <div> with a specified class
+* Detect PHP 5.0.x 64-bit bug and abort in WebStart.php; too many things break
+ mysteriously otherwise (detection code copied from install-utils.inc)
+* (bug 8295) Change handling of <center> tags in doBlockLevels() to match that
+ of <div>
+* (bug 8110) Make magic ISBN linking stricter: only match ten-digit sequences
+ (plus optional ISBN-13 prefix) with no immediately following alphanumeric
+ character, disallow multiple consecutive internal redirects
+* (bug 2785) Accept optional colon prefix in links when formatting comments
+* Don't show "you can view and copy the source of this page" message for
+ pages which don't exist
+* (bug 8310) Blank line added to top of 'post' when page is blank
+* (bug 8109) Template parameters ignored in "recentchangestext"
+* Gracefully skip redirect-to-fragment on WebKit versions less than 420;
+ it messes up on current versions of Safari but is ok in the latest
+ nightlies. Checking the version number will allow it to automatically
+ work when new releases of Safari appear.
+* Fix regression in thumb styles; size and padding didn't match with
+ new arrangement.
+* (bug 8333) Fix quick user data update on login password change on
+ replication database setups. User data is now pulled from master
+ instead of slave in User::loadFromDatabase, ensuring that it is
+ fresh and accurate when read and then saved back into cache.
+ This was breaking with the Special:Rename operation which
+ automatically logs the user in with the new password after changing
+ it; pulling from slave meant the record was often not the updated
+ one.
+* (bug 8335) Set image width to the first valid parameter found.
+* (bug 8350) Fix watchlist viewing bug when using Postgres.
+* (bug 6603) When warning about invalid file extensions, output the bit
+ of the extension we actually checked
+* (bug 7669) Drop defaults on BLOB/TEXT columns for better compatibility
+ with MySQL's strict mode, often enabled by the Windows installer.
+ The defaults are ignored anyway when strict mode is off...
+* (bug 7685) Use explicit values for ar_text and ar_flags when deleting,
+ for better compatibility with MySQL's strict mode
+* Update default interwiki values to reflect changed location of ursine:
+* (bug 5411) Remove autopatrol preference
+* Users who have the "autopatrol" permission will have their edits marked as
+ patrolled automatically
+* Users who do not have the "autopatrol" permission will no longer be able
+ to mark their own edits as patrolled
+* Introduce 'PingLimiter' hook; see docs/hooks.txt for more information
+* (bug 532) Tweaked alt text for some interface messages
+* (bug 8231) Gave useful alt text to the main <img> on image pages
+* (bug 371) Remove alt text for "Enlarge" icon on thumbnails
+* Initialize user_editcount to 0 instead of NULL for newly created accounts
+* (bug 3696) Strip LRM and RLM characters from titles to work around the
+ problem some people have where titles cut-and-pasted from lists include
+ the bidi override characters appended to the lists.
+ A more thorough blacklist for forbidden and translatable characters would
+ be wise, though, as might a cleaner method for the lists in the first place.
+* Fix regression in email password resets on read-restricted sites
+* Set tabindex on fields in deletion form so you don't have to tab through
+ the links in the sitenotice
+* (bug 8271) Show full time and date on viewer for individual deleted
+ revisions
+* (bug 8214) Output file size limit and actual file size in appropriate units
+ on Special:Upload
+* (bug 8016) Purge objectcache table during upgrade processes - use the --nopurge
+ option to prevent this when running maintenance/update.php
+* (bug 7612) Remove superfluous link to Special:Categories from result items
+ on Special:Mostcategories
+* {{PLURAL:}} now handles formatted numbers correctly
+* (bug 8331) Added the change size value to watchlists; therefore made
+ watchlists use RecentChange::newFromRow() instead of newFromCurRow()
+* (bug 8351) Fix undo for simple reverts
+* (bug 6856) User::clearNotification() does not respect read-only mode
+* (bug 6853) Use a checkbox on the installer form to indicate that a superuser
+ account should be used; this is clearer than the old check which relied on
+ the password never being an obscure value
+* Remove old unused watchlist cache, which was a leftover from the old schema
+ where watchlists were more expensive to generate
+* Minor cosmetic changes to Special:Userrights
+* Added wgCanonicalSpecialPageName to JavaScript variables
+* Fix image deleting when using Postgres.
+* Output both source and destination titles in maintenance/moveBatch.php
+* Added basic parser tests for language variants
+* Enable selflinks and categories to be written in some of the language variants
+* Prevent conversion of JavaScript code in language variants
+* Output software version number in maintenance/parserTests.php
+* (bug 7169) Use Ajax to watch/unwatch articles if enabled
+* Make variant table caching a little more robust, using main language code
+ in cache key. Probably this is still a bit wonky, though. Was breaking
+ parser tests when Chinese tables were getting loaded into Serbian code.
+* (bug 8380) Be nicer about blank lines in deleteBatch.php
+* (bug 8401) Fix regression in SORBS lookup for some DNS setups
+* Use raw file descriptor in posix_isatty() check to avoid warning on
+ Linux systems with at least some versions of PHP
+* (bug 5908) Allow overriding the default category sort key for all items on
+ a page using {{DEFAULTSORT}}
+* (bug 6449) Throw a more definitive error message when installation fails
+ due to an invalid database name
+* (bug 5827) Use full text for option link labels on Special:Watchlist
+* (bug 8018) Allow hiding minor edits from the watchlist
+* (bug 8427) MonoBook RTL IE 7.0 tweaks failed when sidebar's navigation
+ section is renamed; no longer relies on first section name
+* Stabilize client-side table sorting even if the underlying Javascript sort()
+ implementation is unstable
+* Add hook for extensions to add user information to the panel in preferences,
+ next to the user name and ID.
+* (bug 8392) Display protection status of transcluded pages in the edit page
+ template list. Patch by Fyren, with i18n naming tweak.
+* Fix for interwiki transclusion where target wiki uses query string for title
+* Resolve namespaces on interwiki Title objects using canonical namespace names
+ if possible (should not happen, though, outside interwiki transclusion... and
+ maybe not even then, but it does)
+* (bug 8447) Fix SQL typo breaking non-default $wgHitcounterUpdateFreq
+* Do not allow previews of deleted images to be cached
+* Add global variable $wgDefaultLanguageVariant used to set the default language
+ variant of a wiki to something different than the main language code
+* Add 'variant' option to parserTests - runs test with the given variant as
+ preferred, utilize it for more parser tests of language variants code
+* (bug 6503) Fix bug that stopped certain irrelevant links from being hidden
+ for printing
+* Avoid PHP warning in Creative Commons metadata when a creative commons
+ license is not actually set up
+* (bug 8463) Don't print external link icons for Monobook
+* (bug 8461) Support watching pages on move
+* (bug 8041) Work around bug with debug_backtrace when Zend Optimizer is
+ loaded by skipping the function. Use wfDebugBacktrace() wrapper function.
+* Reduce config file clutter by setting various script and upload paths
+ based on $IP or $wgScriptPath in Setup.php. They can still be explicitly
+ overridden in LocalSettings.php if desired...
+* Attempt to detect redirect loops for the canonical title redirect, and
+ give some hints to the poor confused administrator.
+* Introduce new flag 'R' - raw output for language variant escape tags
+* Advise users when updates for a query page have been disabled using
+ $wgDisableQueryPageUpdate
+* (bug 8413) Improve comments for $wgNamespaceRobotPolicies
+* (bug 8330) Show "bytes" suffix on recent changes diff counter
+ optionally... if set in rc-changes-size message (default empty for now)
+* (bug 8489) Support basic links in <gallery> caption attribute
+* (bug 8485) Correct Lingala number formatting
+* The MediaWiki namespace is no longer pre-filled with default messages on
+ install. All default messages will be removed from the MediaWiki namespace
+ on upgrade.
+* Recentchanges RSS/Atom feeds now use a separate message for the description
+ to avoid cluttering it with useless wiki formatting
+* (bug 8417) Handle EXIF unknown dates
+* (bug 8372) Return nothing on empty <math> tags.
+* New maintenance script to show the cached statistics : showStats.php.
+* Count deleted edits when regenerating total edits in maintenance/initStats.php
+* (bug 3706) Allow users to be exempted from IP blocks. The ipblock-exempt permission
+ key has been added to enable this behaviour, by default assigned to sysops.
+* (bug 7948) importDump.php now warn that Recentchanges need to be rebuild.
+* (bug 7667) allow XHTML namespaces customization
+* (bug 8531) Correct local name of Lingála (patch by Raymond)
+* Fix regression with default lock file and cache directories; threw visible
+ warning with open_basedir
+
+
+== Languages updated ==
+
+* Basque (eu)
+* Bishnupriya Manipuri (bpy)
+* Cantonese (zh-yue)
+* Finnish (fi)
+* Frisian (fy)
+* German (de)
+* Hebrew (he)
+* Indonesian (id)
+* Italian (it)
+* Japanese (ja)
+* Kazakh (kk)
+* Kongo (kg)
+* Latin (la)
+* Limburgish (li)
+* Lingala (ln)
+* Lithuanian (lt)
+* Maltese (mt)
+* Maori (mi)
+* Norwegian (no)
+* Occitan (oc)
+* Old Church Slavonic (cu)
+* Polish (pl)
+* Portuguese (pt)
+* Ripurian (ksh)
+* Russian (ru)
+* Slovak (sk)
+* Swedish (sv)
+* Taiwanese/Holo: (bug 8217) changed language code to nan (from zh-min-nan)
+ due to http://www.sil.org/iso639-3/codes.asp?order=639_3&letter=n
+* Upper Sorbian (hsb)
+* Vietnamese (vi)
+
+== Compatibility ==
+
+MediaWiki 1.9 requires PHP 5 (5.1 recommended). PHP 4 is no longer supported.
+
+PHP 5.0.x fails on 64-bit systems due to serious bugs with array processing:
+http://bugs.php.net/bug.php?id=34879
+Upgrade affected systems to PHP 5.1 or higher.
+
+MySQL 3.23.x is no longer supported; some older hosts may need to upgrade.
+At this time we still recommend 4.0, but 4.1/5.0 will work fine in most cases.
+
+
+== Upgrading ==
+
+Some minor database changes have been made since 1.7:
+* new fields and indexes on ipblocks
+* index change on recentchanges
+
+Several changes from 1.5 and 1.6 do require updates to be run on upgrade.
+To ensure that these tables are filled with data, run refreshLinks.php after
+the upgrade.
+
+If you are upgrading from MediaWiki 1.4.x or earlier, some major database
+changes are made, and there is a slightly higher chance that things could
+break. Don't forget to always back up your database before upgrading!
+
+See the file UPGRADE for more detailed upgrade instructions.
+
+
+
+=== Caveats ===
+
+Some output, particularly involving user-supplied inline HTML, may not
+produce 100% valid or well-formed XHTML output. Testers are welcome to
+set $wgMimeType = "application/xhtml+xml"; to test for remaining problem
+cases, but this is not recommended on live sites. (This must be set for
+MathML to display properly in Mozilla.)
+
+
+For notes on 1.8.x and older releases, see HISTORY.
+
+
+=== Online documentation ===
+
+Documentation for both end-users and site administrators is currently being
+built up on Meta-Wikipedia, and is covered under the GNU Free Documentation
+License:
+
+ http://www.mediawiki.org/wiki/Documentation
+
+
+=== Mailing list ===
+
+A MediaWiki-l mailing list has been set up distinct from the Wikipedia
+wikitech-l list:
+
+ http://lists.wikimedia.org/mailman/listinfo/mediawiki-l
+
+A low-traffic announcements-only list is also available:
+
+ http://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/StartProfiler.php b/StartProfiler.php
new file mode 100644
index 000000000000..8fc3ff887fc7
--- /dev/null
+++ b/StartProfiler.php
@@ -0,0 +1,22 @@
+<?php
+
+require_once( dirname(__FILE__).'/includes/ProfilerStub.php' );
+
+/**
+ * To use a profiler, delete the line above and add something like this:
+ *
+ * require_once( dirname(__FILE__).'/includes/Profiler.php' );
+ * $wgProfiler = new Profiler;
+ *
+ * Or for a sampling profiler:
+ * if ( !mt_rand( 0, 100 ) ) {
+ * require_once( dirname(__FILE__).'/includes/Profiler.php' );
+ * $wgProfiler = new Profiler;
+ * } else {
+ * require_once( dirname(__FILE__).'/includes/ProfilerStub.php' );
+ * }
+ *
+ * Configuration of the profiler output can be done in LocalSettings.php
+ */
+
+?>
diff --git a/UPGRADE b/UPGRADE
new file mode 100644
index 000000000000..40d5b2028f31
--- /dev/null
+++ b/UPGRADE
@@ -0,0 +1,335 @@
+This file provides an overview of the MediaWiki upgrade process. For help with
+specific problems, check
+
+* the documentation at http://www.mediawiki.org
+* the mediawiki-l mailing list archive at
+ http://lists.wikimedia.org/pipermail/mediawiki-l/
+* the bug tracker at http://bugzilla.wikimedia.org
+
+for information and workarounds to common issues.
+
+== Overview ==
+
+Comprehensive documentation on upgrading to the latest version of the software
+is available at http://www.mediawiki.org/wiki/Manual:Upgrading_MediaWiki.
+
+=== Consult the release notes ===
+
+Before doing anything, stop and consult the release notes supplied with the new
+version of the software. This detail bug fixes, new features and functionality,
+and any particular points that may need to be noted during the upgrade
+procedure.
+
+=== Backup first ===
+
+It is imperative that, prior to attempting an upgrade of the database schema,
+you take a complete backup of your wiki database and files and verify it. While
+the upgrade scripts are somewhat robust, there is no guarantee that things will
+not fail, leaving the database in an inconsistent state.
+
+Refer to the MySQL or Postgres documentation for information on backing up a
+database. For information on making copies of files, consult the documentation
+for your operating system.
+
+=== Perform the file upgrade ===
+
+Having downloaded the desired new version of the software, either as a package
+from SourceForge, or via an export from Subversion, decompress the files as
+needed, and replace the existing MediaWiki files with the new.
+
+You should preserve:
+
+* The LocalSettings.php file
+* The AdminSettings.php file, where it exists
+* The extensions directory
+* The images directory
+
+If using an alternative uploads directory, preserve this; and if using custom
+skins, preserve these too. The core code is now updated.
+
+=== Perform the database upgrade ===
+
+You will need an AdminSettings.php file set up in the correct format; see
+AdminSettings.sample in the wiki root for more information and examples.
+
+From the command line, browse to the maintenance directory and run the
+update.php script to check and update the schema. This will insert missing
+tables, update existing tables, and move data around as needed. In most cases,
+this is successful and nothing further needs to be done.
+
+=== Check configuration settings ===
+
+The names of configuration variables, and their default values and purposes,
+can change between release branches, e.g. $wgDisableUploads in 1.4 is replaced
+with $wgEnableUploads in later versions. When upgrading, consult the release
+notes to check for configuration changes which would alter the expected
+behaviour of MediaWiki.
+
+=== Test ===
+
+It makes sense to test your wiki immediately following any kind of maintenance
+procedure, and especially after upgrading; check that page views and edits work
+normally and that special pages continue to function, etc. and correct errors
+and quirks which reveal themselves.
+
+== Upgrading from 1.8 wikis ==
+
+MediaWiki 1.9 and later no longer keep default localized message text
+in the database; 'MediaWiki:'-namespace pages that do not exist in the
+database are simply transparently filled-in on demand.
+
+The upgrade process will delete any 'MediaWiki:' pages which are left
+in the default state (last edited by 'MediaWiki default'). This may
+take a few moments, similar to the old initial setup.
+
+Note that the large number of deletions may cause older edits to expire
+from the list on Special:Recentchanges, although the deletions themselves
+will be hidden by default. (Click "show bot edits" to list them.)
+
+
+See RELEASE-NOTES for more details about new and changed options.
+
+
+== Upgrading from 1.7 wikis ==
+
+$wgDefaultUserOptions now contains all the defaults, not only overrides.
+If you're setting this as a complete array(), you may need to change it
+to set only specific items as recommended in DefaultSettings.php.
+
+== Upgrading from 1.6 wikis ==
+
+$wgLocalTZoffset was in hours, it is now using minutes.
+Link autonumbering got fixed (#5918) for protocols other than http.
+ - 'irc://irc.server.tld/' render as a link with a chat icon
+ - '[irc://irc.server.tld]' render as an autonumbered link: [1]
+
+== Upgrading from pre-1.5 wikis ==
+
+Major changes have been made to the schema from 1.4.x. The updater
+has not been fully tested for all conditions, and might well break.
+
+On a large site, the schema update might take a long time. It might
+explode, or leave your database half-done or otherwise badly hurting.
+
+Among other changes, note that Latin-1 encoding (ISO-8859-1) is
+no longer supported. Latin-1 wikis will need to be upgraded to
+UTF-8; an experimental command-line upgrade helper script,
+'upgrade1_5.php', can do this -- run it prior to 'update.php' or
+the web upgrader.
+
+If you absolutely cannot make the UTF-8 upgrade work, you can try
+doing it by hand: dump your old database, convert the dump file
+using iconv as described here:
+http://portal.suse.com/sdb/en/2004/05/jbartsh_utf-8.html
+and then reimport it. You can also convert filenames using convmv,
+but note that the old directory hashes will no longer be valid,
+so you will also have to move them to new destinations.
+
+Message changes:
+* A number of additional UI messages have been changed from HTML to
+ wikitext, and will need to be manually fixed if customized.
+
+=== Configuration changes from 1.4.x: ===
+
+$wgDisableUploads has been replaced with $wgEnableUploads.
+
+$wgWhitelistAccount has been replaced by the 'createaccount' permission
+key in $wgGroupPermissions. To emulate the old effect of setting:
+ $wgWhitelistAccount['user'] = 0;
+set:
+ $wgGroupPermissions['*']['createaccount'] = false;
+
+$wgWhitelistEdit has been replaced by the 'edit' permission key.
+To emulate the old effect of setting:
+ $wgWhitelistEdit = true;
+set:
+ $wgGroupPermissions['*']['edit'] = false;
+
+If $wgWhitelistRead is set, you must also disable the 'read' permission
+for it to take affect on anonymous users:
+ $wgWhitelistRead = array( "Main Page", "Special:Userlogin" );
+ $wgGroupPermissions['*']['read'] = false;
+
+Note that you can disable/enable several other permissions by modifying
+this configuration array in your LocalSettings.php; see DefaultSettings.php
+for the complete default permission set.
+
+If using Memcached, you must enabled it differently now:
+ $wgUseMemCached = true;
+should be replaced with:
+ $wgMainCacheType = CACHE_MEMCACHED;
+
+
+=== Web installer ===
+
+You can use the web-based installer wizard if you first remove the
+LocalSettings.php (and AdminSettings.php, if any) files; be sure to
+give the installer the same information as you did on the original
+install (language/encoding, database name, password, etc). This will
+also generate a fresh LocalSettings.php, which you may need to customize.
+
+You may change some settings during the install, but be very careful!
+Changing the encoding in particular will generally leave you with a
+lot of corrupt pages, particularly if your wiki is not in English.
+
+=== Command-line upgrade ===
+
+Additionally, as of 1.4.0 you can run an in-place upgrade script from
+the command line, keeping your existing LocalSettings.php. This requires
+that you create an AdminSettings.php giving an appropriate database user
+and password with privileges to modify the database structure.
+
+Once the new files are in place, go into the maintenance subdirectory and
+run the script:
+
+ php update.php
+
+See caveats below on upgrading from 1.3.x or earlier.
+
+
+== Backups! ==
+
+To upgrade an existing MediaWiki installation, first BACK UP YOUR WIKI!
+If something goes wrong, you want to be able to start again.
+
+Your image files, configuration, etc can simply be copied or archived as
+you would any other files. (Make sure that the contents of your
+LocalSettings.php are not accidentally made public, as this contains
+a database password.)
+
+To back up the database, use the tools provided by your service provider
+(if applicable) or the standard mysqldump or pg_dump programs.
+
+For general help on mysqldump:
+http://dev.mysql.com/doc/mysql/en/mysqldump.html
+
+WARNING: If using MySQL 4.1.x, mysqldump's charset conversion may in
+some cases damage data in your wiki. If necessary, set the charset
+option to 'latin1' to avoid the conversion.
+
+For general help on pg_dump:
+http://www.postgresql.org/docs/current/static/app-pgdump.html
+
+
+== Caveats ==
+
+=== Postgres ===
+
+Postgres support is new, and much of the upgrade instructions may
+not apply. The schema was changed significantly from 1.7 to 1.8,
+so you will need to at least use the update.php or web installer,
+as described above.
+
+
+=== Upgrading from 1.4.2 or earlier ===
+
+1.4.3 has added new fields to the sitestats table. These fields are
+optional and help to speed Special:Statistics on large sites. If you
+choose not to run the database upgrades, everything will continue to
+work in 1.4.3.
+
+You can apply the update by running maintenance/update.php, or
+manually run the SQL commands from this file:
+ maintenance/archives/patch-ss_total_articles.sql
+
+
+=== Upgrading from 1.4rc1 or earlier betas ===
+
+The logging table has been altered from 1.4beta4 to 1.4beta5
+and again in 1.4.0 final. Copy in the new files and use the web
+installer to upgrade, or the command-line maintenance/update.php.
+
+If you cannot use the automated installers/updaters, you may
+update the table by manually running the SQL commands in these
+files:
+ maintenance/archives/patch-log_params.sql
+ maintenance/archives/patch-logging-title.sql
+
+
+=== Upgrading from 1.3.x ===
+
+This should generally go smoothly.
+
+If you keep your LocalSettings.php, you may need to change the style paths
+to match the newly rearranged skin modules. Change these lines:
+ $wgStylePath = "$wgScriptPath/stylesheets";
+ $wgStyleDirectory = "$IP/stylesheets";
+ $wgLogo = "$wgStylePath/images/wiki.png";
+
+to this:
+ $wgStylePath = "$wgScriptPath/skins";
+ $wgStyleDirectory = "$IP/skins";
+ $wgLogo = "$wgStylePath/common/images/wiki.png";
+
+As well as new messages, the processing of some messages has changed.
+If you have customized them, please compare the new format using
+Special:Allmessages or the relevant LanguageXX.php files:
+ copyrightwarning
+ dberrortext
+ editingcomment (was named commentedit)
+ editingsection (was named sectionedit)
+ numauthors
+ numedits
+ numtalkauthors
+ numtalkedits
+ numwatchers
+ protectedarticle
+ searchresulttext
+ showhideminor
+ unprotectedarticle
+
+Note that the 1.3 beta releases included a potential vulnerability if PHP
+is configured with register_globals on and the includes directory is
+served to the web. For general safety, turn register_globals *off* if you
+don't _really_ need it for another package.
+
+If your hosting provider turns it on and you can't turn it off yourself,
+send them a kind note explaining that it can expose their servers and their
+customers to attacks.
+
+
+=== Upgrading from 1.2.x ===
+
+If you've been using the MediaWiki: namespace for custom page templates,
+note that things are a little different. The Template: namespace has been
+added which is more powerful -- templates can include parameters for
+instance.
+
+If you were using custom MediaWiki: entries for text inclusions, they
+will *not* automatically be moved to Template: entries at upgrade time.
+Be sure to go through and check that everything is working properly;
+you can move them manually or you can try using moveCustomMessages.php
+in maintenance/archives to do it automatically, but this might break things.
+
+Also, be sure to pick the correct character encoding -- some languages were
+only available in Latin-1 on 1.2.x and are now available for Unicode as well.
+If you want to upgrade an existing wiki from Latin-1 to Unicode you'll have
+to dump the database to SQL, run it through iconv or another conversion tool,
+and restore it. Sorry.
+
+
+=== Upgrading from 1.1.x or earlier ===
+
+This is less thoroughly tested, but should work.
+
+You need to specify the *admin* database username and password to the
+installer in order for it to successfully upgrade the database structure.
+You may wish to manually change the GRANTs later.
+
+If you have a very old database (earlier than organized MediaWiki releases
+in late August 2003) you may need to manually run some of the update SQL
+scripts in maintenance/archives before the installer is able to pick up
+with remaining updates.
+
+
+=== Upgrading from UseModWiki or old "phase 2" Wikipedia code ===
+
+There is a semi-maintained UseModWiki to MediaWiki conversion script at
+maintenance/importUseModWiki.php; it may require tweaking and customization
+to work for you.
+
+Install a new MediaWiki first, then use the conversion script which will
+output SQL statements; direct these to a file and then run that into your
+database.
+
+You will have to rebuild the links tables etc after importing.
diff --git a/api.php b/api.php
new file mode 100644
index 000000000000..92318cb3ca7e
--- /dev/null
+++ b/api.php
@@ -0,0 +1,65 @@
+<?php
+
+
+/**
+* API for MediaWiki 1.8+
+*
+* Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* http://www.gnu.org/copyleft/gpl.html
+*/
+
+// Initialise common code
+require (dirname(__FILE__) . '/includes/WebStart.php');
+
+wfProfileIn('api.php');
+
+// URL safety checks
+//
+// See RawPage.php for details; summary is that MSIE can override the
+// Content-Type if it sees a recognized extension on the URL, such as
+// might be appended via PATH_INFO after 'api.php'.
+//
+// Some data formats can end up containing unfiltered user-provided data
+// which will end up triggering HTML detection and execution, hence
+// XSS injection and all that entails.
+//
+// Ensure that all access is through the canonical entry point...
+//
+if( isset( $_SERVER['SCRIPT_URL'] ) ) {
+ $url = $_SERVER['SCRIPT_URL'];
+} else {
+ $url = $_SERVER['PHP_SELF'];
+}
+if( strcmp( "$wgScriptPath/api.php", $url ) ) {
+ wfHttpError( 403, 'Forbidden',
+ 'API must be accessed through the primary script entry point.' );
+ return;
+}
+
+// Verify that the API has not been disabled
+if (!$wgEnableAPI) {
+ echo 'MediaWiki API is not enabled for this site. Add the following line to your LocalSettings.php';
+ echo '<pre><b>$wgEnableAPI=true;</b></pre>';
+ die(-1);
+}
+
+$processor = new ApiMain($wgRequest, $wgEnableWriteAPI);
+$processor->execute();
+
+wfProfileOut('api.php');
+wfLogProfilingData();
+?>
diff --git a/bin/ulimit-tvf.sh b/bin/ulimit-tvf.sh
new file mode 100755
index 000000000000..8a1eb81c6031
--- /dev/null
+++ b/bin/ulimit-tvf.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+ulimit -t $1 -v $2 -f $3
+shift 3
+"$@"
+
diff --git a/bin/ulimit.sh b/bin/ulimit.sh
new file mode 100644
index 000000000000..7a1925cc2745
--- /dev/null
+++ b/bin/ulimit.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+ulimit -t $1
+ulimit -v $2
+shift 2
+"$@"
+
diff --git a/config/index.php b/config/index.php
new file mode 100644
index 000000000000..69394e69ebe1
--- /dev/null
+++ b/config/index.php
@@ -0,0 +1,1724 @@
+<?php
+
+# MediaWiki web-based config/installation
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>, 2006 Rob Church <robchur@gmail.com>
+# http://www.mediawiki.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
+
+error_reporting( E_ALL );
+header( "Content-type: text/html; charset=utf-8" );
+@ini_set( "display_errors", true );
+
+# In case of errors, let output be clean.
+$wgRequestTime = microtime( true );
+
+# Attempt to set up the include path, to fix problems with relative includes
+$IP = dirname( dirname( __FILE__ ) );
+define( 'MW_INSTALL_PATH', $IP );
+$sep = PATH_SEPARATOR;
+if( !ini_set( "include_path", ".$sep$IP$sep$IP/includes$sep$IP/languages" ) ) {
+ set_include_path( ".$sep$IP$sep$IP/includes$sep$IP/languages" );
+}
+
+# Define an entry point and include some files
+define( "MEDIAWIKI", true );
+define( "MEDIAWIKI_INSTALL", true );
+
+// Run version checks before including other files
+// so people don't see a scary parse error.
+require_once( "install-utils.inc" );
+install_version_checks();
+
+require_once( "includes/Defines.php" );
+require_once( "includes/DefaultSettings.php" );
+require_once( "includes/MagicWord.php" );
+require_once( "includes/Namespace.php" );
+require_once( "includes/ProfilerStub.php" );
+
+## Databases we support:
+
+$ourdb = array();
+$ourdb['mysql']['fullname'] = 'MySQL';
+$ourdb['mysql']['havedriver'] = 0;
+$ourdb['mysql']['compile'] = 'mysql';
+$ourdb['mysql']['bgcolor'] = '#ffe5a7';
+$ourdb['mysql']['rootuser'] = 'root';
+
+$ourdb['postgres']['fullname'] = 'PostgreSQL';
+$ourdb['postgres']['havedriver'] = 0;
+$ourdb['postgres']['compile'] = 'pgsql';
+$ourdb['postgres']['bgcolor'] = '#aaccff';
+$ourdb['postgres']['rootuser'] = 'postgres';
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+ <title>MediaWiki <?php echo( $wgVersion ); ?> Installation</title>
+ <style type="text/css">
+
+ @import "../skins/monobook/main.css";
+
+ .env-check {
+ font-size: 90%;
+ margin: 1em 0 1em 2.5em;
+ }
+
+ .config-section {
+ margin-top: 2em;
+ }
+
+ .config-section label.column {
+ clear: left;
+ font-weight: bold;
+ width: 13em;
+ float: left;
+ text-align: right;
+ padding-right: 1em;
+ padding-top: .2em;
+ }
+
+ .config-input {
+ clear: left;
+ zoom: 100%; /* IE hack */
+ }
+
+ .config-section .config-desc {
+ clear: left;
+ margin: 0 0 2em 18em;
+ padding-top: 1em;
+ font-size: 85%;
+ }
+
+ .iput-text, .iput-password {
+ width: 14em;
+ margin-right: 1em;
+ }
+
+ .error {
+ color: red;
+ background-color: #fff;
+ font-weight: bold;
+ left: 1em;
+ font-size: 100%;
+ }
+
+ .error-top {
+ color: red;
+ background-color: #FFF0F0;
+ border: 2px solid red;
+ font-size: 130%;
+ font-weight: bold;
+ padding: 1em 1.5em;
+ margin: 2em 0 1em;
+ }
+
+ ul.plain {
+ list-style-type: none;
+ list-style-image: none;
+ float: left;
+ margin: 0;
+ padding: 0;
+ }
+
+ .btn-install {
+ font-weight: bold;
+ font-size: 110%;
+ padding: .2em .3em;
+ }
+
+ .license {
+ font-size: 85%;
+ padding-top: 3em;
+ }
+
+ </style>
+ <script type="text/javascript">
+ <!--
+ function hideall() {
+ <?php foreach (array_keys($ourdb) as $db) {
+ echo "\n document.getElementById('$db').style.display='none';";
+ }
+ ?>
+
+ }
+ function toggleDBarea(id,defaultroot) {
+ hideall();
+ var dbarea = document.getElementById(id).style;
+ dbarea.display = (dbarea.display == 'none') ? 'block' : 'none';
+ var db = document.getElementById('RootUser');
+ if (defaultroot) {
+<?php foreach (array_keys($ourdb) as $db) {
+ echo " if (id == '$db') { db.value = '".$ourdb[$db]['rootuser']."';}\n";
+}?>
+ }
+ }
+ // -->
+ </script>
+</head>
+
+<body>
+<div id="globalWrapper">
+<div id="column-content">
+<div id="content">
+<div id="bodyContent">
+
+<h1>MediaWiki <?php print $wgVersion ?> Installation</h1>
+
+<?php
+
+/* Check for existing configurations and bug out! */
+
+if( file_exists( "../LocalSettings.php" ) ) {
+ dieout( "<p><strong>Setup has completed, <a href='../index.php'>your wiki</a> is configured.</strong></p>
+
+ <p>Please delete the /config directory for extra security.</p></div></div></div></div>" );
+}
+
+if( file_exists( "./LocalSettings.php" ) ) {
+ writeSuccessMessage();
+
+ dieout( '' );
+}
+
+if( !is_writable( "." ) ) {
+ dieout( "<h2>Can't write config file, aborting</h2>
+
+ <p>In order to configure the wiki you have to make the <tt>config</tt> subdirectory
+ writable by the web server. Once configuration is done you'll move the created
+ <tt>LocalSettings.php</tt> to the parent directory, and for added safety you can
+ then remove the <tt>config</tt> subdirectory entirely.</p>
+
+ <p>To make the directory writable on a Unix/Linux system:</p>
+
+ <pre>
+ cd <i>/path/to/wiki</i>
+ chmod a+w config
+ </pre>
+
+ <p>Afterwards retry to start the <a href=\"\">setup</a>.</p>" );
+}
+
+
+require_once( "install-utils.inc" );
+require_once( "maintenance/updaters.inc" );
+
+class ConfigData {
+ function getEncoded( $data ) {
+ # removing latin1 support, no need...
+ return $data;
+ }
+ function getSitename() { return $this->getEncoded( $this->Sitename ); }
+ function getSysopName() { return $this->getEncoded( $this->SysopName ); }
+ function getSysopPass() { return $this->getEncoded( $this->SysopPass ); }
+}
+
+?>
+
+<ul>
+ <li>
+ <b>Don't forget security updates!</b> Keep an eye on the
+ <a href="http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce">low-traffic
+ release announcements mailing list</a>.
+ </li>
+</ul>
+
+
+<h2>Checking environment...</h2>
+<p><em>Please include all of the lines below when reporting installation problems.</em></p>
+<ul class="env-check">
+<?php
+$endl = "
+";
+$wgNoOutputBuffer = true;
+$conf = new ConfigData;
+
+install_version_checks();
+
+print "<li>PHP " . phpversion() . " installed</li>\n";
+
+## Temporarily turn off all errors as we try to discover installed databases
+$olderrnum = error_reporting(0);
+
+$phpdatabases = array();
+foreach (array_keys($ourdb) as $db) {
+ $compname = $ourdb[$db]['compile'];
+ if (extension_loaded($compname) or dl($compname . '.' . PHP_SHLIB_SUFFIX)) {
+ array_push($phpdatabases, $db);
+ $ourdb[$db]['havedriver'] = 1;
+ }
+}
+
+error_reporting($olderrornum);
+
+if (!$phpdatabases) {
+ print "Could not find a suitable database driver!<ul>";
+ foreach (array_keys($ourdb) AS $db) {
+ $comp = $ourdb[$db]['compile'];
+ $full = $ourdb[$db]['fullname'];
+ print "<li>For <b>$full</b>, compile PHP using <b>--with-$comp</b>, "
+ ."or install the $comp.so module</li>\n";
+ }
+ dieout( "</ul></ul>" );
+}
+
+print "<li>Found database drivers for:";
+foreach (array_keys($ourdb) AS $db) {
+ if ($ourdb[$db]['havedriver']) {
+ $DefaultDBtype = $db;
+ print " ".$ourdb[$db]['fullname'];
+ }
+}
+print "</li>\n";
+if (count($phpdatabases) != 1)
+ $DefaultDBtype = '';
+
+if( ini_get( "register_globals" ) ) {
+ ?>
+ <li>
+ <div style="font-size:110%">
+ <strong class="error">Warning:</strong>
+ <strong>PHP's <tt><a href="http://php.net/register_globals">register_globals</a></tt> option is enabled. Disable it if you can.</strong>
+ </div>
+ MediaWiki will work, but your server is more exposed to PHP-based security vulnerabilities.
+ </li>
+ <?php
+}
+
+$fatal = false;
+
+if( ini_get( "magic_quotes_runtime" ) ) {
+ $fatal = true;
+ ?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime'>magic_quotes_runtime</a> is active!</strong>
+ This option corrupts data input unpredictably; you cannot install or use
+ MediaWiki unless this option is disabled.
+ <?php
+}
+
+if( ini_get( "magic_quotes_sybase" ) ) {
+ $fatal = true;
+ ?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.sybase.php#ini.magic-quotes-sybase'>magic_quotes_sybase</a> is active!</strong>
+ This option corrupts data input unpredictably; you cannot install or use
+ MediaWiki unless this option is disabled.
+ <?php
+}
+
+if( ini_get( "mbstring.func_overload" ) ) {
+ $fatal = true;
+ ?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload'>mbstring.func_overload</a> is active!</strong>
+ This option causes errors and may corrupt data unpredictably;
+ you cannot install or use MediaWiki unless this option is disabled.
+ <?php
+}
+
+if( $fatal ) {
+ dieout( "</ul><p>Cannot install MediaWiki.</p>" );
+}
+
+if( ini_get( "safe_mode" ) ) {
+ $conf->safeMode = true;
+ ?>
+ <li><b class='error'>Warning:</b> <strong>PHP's
+ <a href='http://www.php.net/features.safe-mode'>safe mode</a> is active.</strong>
+ You may have problems caused by this, particularly if using image uploads.
+ </li>
+ <?php
+} else {
+ $conf->safeMode = false;
+}
+
+$sapi = php_sapi_name();
+print "<li>PHP server API is $sapi; ";
+if( $wgUsePathInfo ) {
+ print "ok, using pretty URLs (<tt>index.php/Page_Title</tt>)";
+} else {
+ print "using ugly URLs (<tt>index.php?title=Page_Title</tt>)";
+}
+print "</li>\n";
+
+$conf->xml = function_exists( "utf8_encode" );
+if( $conf->xml ) {
+ print "<li>Have XML / Latin1-UTF-8 conversion support.</li>\n";
+} else {
+ dieout( "PHP's XML module is missing; the wiki requires functions in
+ this module and won't work in this configuration.
+ If you're running Mandrake, install the php-xml package." );
+}
+
+# Crude check for session support
+if( !function_exists( 'session_name' ) )
+ dieout( "PHP's session module is missing. MediaWiki requires session support in order to function." );
+
+# Likewise for PCRE
+if( !function_exists( 'preg_match' ) )
+ dieout( "The PCRE regular expression functions are missing. MediaWiki requires these in order to function." );
+
+$memlimit = ini_get( "memory_limit" );
+$conf->raiseMemory = false;
+if( empty( $memlimit ) || $memlimit == -1 ) {
+ print "<li>PHP is configured with no <tt>memory_limit</tt>.</li>\n";
+} else {
+ print "<li>PHP's <tt>memory_limit</tt> is " . htmlspecialchars( $memlimit ) . ". <strong>If this is too low, installation may fail!</strong> ";
+ $n = intval( $memlimit );
+ if( preg_match( '/^([0-9]+)[Mm]$/', trim( $memlimit ), $m ) ) {
+ $n = intval( $m[1] * (1024*1024) );
+ }
+ if( $n < 20*1024*1024 ) {
+ print "Attempting to raise limit to 20M... ";
+ if( false === ini_set( "memory_limit", "20M" ) ) {
+ print "failed.";
+ } else {
+ $conf->raiseMemory = true;
+ print "ok.";
+ }
+ }
+ print "</li>\n";
+}
+
+$conf->zlib = function_exists( "gzencode" );
+if( $conf->zlib ) {
+ print "<li>Have zlib support; enabling output compression.</li>\n";
+} else {
+ print "<li>No zlib support.</li>\n";
+}
+
+$conf->turck = function_exists( 'mmcache_get' );
+if ( $conf->turck ) {
+ print "<li><a href=\"http://turck-mmcache.sourceforge.net/\">Turck MMCache</a> installed</li>\n";
+}
+
+$conf->apc = function_exists('apc_fetch');
+if ($conf->apc ) {
+ print "<li><a href=\"http://www.php.net/apc\">APC</a> installed</li>";
+}
+
+$conf->eaccel = function_exists( 'eaccelerator_get' );
+if ( $conf->eaccel ) {
+ $conf->turck = 'eaccelerator';
+ print "<li><a href=\"http://eaccelerator.sourceforge.net/\">eAccelerator</a> installed</li>\n";
+}
+
+if( !$conf->turck && !$conf->eaccel && !$conf->apc ) {
+ echo( '<li>Couldn\'t find <a href="http://turck-mmcache.sourceforge.net">Turck MMCache</a>,
+ <a href="http://eaccelerator.sourceforge.net">eAccelerator</a> or
+ <a href="http://www.php.net/apc">APC</a>. Object caching functions cannot be used.</li>' );
+}
+
+$conf->diff3 = false;
+$diff3locations = array_merge(
+ array(
+ "/usr/bin",
+ "/usr/local/bin",
+ "/opt/csw/bin",
+ "/usr/gnu/bin",
+ "/usr/sfw/bin" ),
+ explode( $sep, getenv( "PATH" ) ) );
+$diff3names = array( "gdiff3", "diff3", "diff3.exe" );
+
+$diff3versioninfo = array( '$1 --version 2>&1', 'diff3 (GNU diffutils)' );
+foreach ($diff3locations as $loc) {
+ $exe = locate_executable($loc, $diff3names, $diff3versioninfo);
+ if ($exe !== false) {
+ $conf->diff3 = $exe;
+ break;
+ }
+}
+
+if ($conf->diff3)
+ print "<li>Found GNU diff3: <tt>$conf->diff3</tt>.</li>";
+else
+ print "<li>GNU diff3 not found.</li>";
+
+$conf->ImageMagick = false;
+$imcheck = array( "/usr/bin", "/opt/csw/bin", "/usr/local/bin", "/sw/bin", "/opt/local/bin" );
+foreach( $imcheck as $dir ) {
+ $im = "$dir/convert";
+ if( file_exists( $im ) ) {
+ print "<li>Found ImageMagick: <tt>$im</tt>; image thumbnailing will be enabled if you enable uploads.</li>\n";
+ $conf->ImageMagick = $im;
+ break;
+ }
+}
+
+$conf->HaveGD = function_exists( "imagejpeg" );
+if( $conf->HaveGD ) {
+ print "<li>Found GD graphics library built-in";
+ if( !$conf->ImageMagick ) {
+ print ", image thumbnailing will be enabled if you enable uploads";
+ }
+ print ".</li>\n";
+} else {
+ if( !$conf->ImageMagick ) {
+ print "<li>Couldn't find GD library or ImageMagick; image thumbnailing disabled.</li>\n";
+ }
+}
+
+$conf->UseImageResize = $conf->HaveGD || $conf->ImageMagick;
+
+$conf->IP = dirname( dirname( __FILE__ ) );
+print "<li>Installation directory: <tt>" . htmlspecialchars( $conf->IP ) . "</tt></li>\n";
+
+
+// PHP_SELF isn't available sometimes, such as when PHP is CGI but
+// cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
+// to get the path to the current script... hopefully it's reliable. SIGH
+$path = ($_SERVER["PHP_SELF"] === '')
+ ? $_SERVER["SCRIPT_NAME"]
+ : $_SERVER["PHP_SELF"];
+$conf->ScriptPath = preg_replace( '{^(.*)/config.*$}', '$1', $path );
+print "<li>Script URI path: <tt>" . htmlspecialchars( $conf->ScriptPath ) . "</tt></li>\n";
+
+print "<li style='font-weight:bold;color:green;font-size:110%'>Environment checked. You can install MediaWiki.</li>\n";
+ $conf->posted = ($_SERVER["REQUEST_METHOD"] == "POST");
+
+ $conf->Sitename = ucfirst( importPost( "Sitename", "" ) );
+ $defaultEmail = empty( $_SERVER["SERVER_ADMIN"] )
+ ? 'root@localhost'
+ : $_SERVER["SERVER_ADMIN"];
+ $conf->EmergencyContact = importPost( "EmergencyContact", $defaultEmail );
+ $conf->DBtype = importPost( "DBtype", $DefaultDBtype );
+?>
+
+<?php
+ $conf->DBserver = importPost( "DBserver", "localhost" );
+ $conf->DBname = importPost( "DBname", "wikidb" );
+ $conf->DBuser = importPost( "DBuser", "wikiuser" );
+ $conf->DBpassword = importPost( "DBpassword" );
+ $conf->DBpassword2 = importPost( "DBpassword2" );
+ $conf->SysopName = importPost( "SysopName", "WikiSysop" );
+ $conf->SysopPass = importPost( "SysopPass" );
+ $conf->SysopPass2 = importPost( "SysopPass2" );
+ $conf->RootUser = importPost( "RootUser", "root" );
+ $conf->RootPW = importPost( "RootPW", "" );
+ $useRoot = importCheck( 'useroot', false );
+
+ ## MySQL specific:
+ $conf->DBprefix = importPost( "DBprefix" );
+ $conf->DBschema = importPost( "DBschema", "mysql4" );
+ $conf->DBmysql5 = ($conf->DBschema == "mysql5" ||
+ $conf->DBschema == "mysql5-binary")
+ ? "true" : "false";
+ $conf->LanguageCode = importPost( "LanguageCode", "en" );
+
+ ## Postgres specific:
+ $conf->DBport = importPost( "DBport", "5432" );
+ $conf->DBmwschema = importPost( "DBmwschema", "mediawiki" );
+ $conf->DBts2schema = importPost( "DBts2schema", "public" );
+
+/* Check for validity */
+$errs = array();
+
+if( $conf->Sitename == "" || $conf->Sitename == "MediaWiki" || $conf->Sitename == "Mediawiki" ) {
+ $errs["Sitename"] = "Must not be blank or \"MediaWiki\"";
+}
+if( $conf->DBuser == "" ) {
+ $errs["DBuser"] = "Must not be blank";
+}
+if( $conf->DBpassword == "" ) {
+ $errs["DBpassword"] = "Must not be blank";
+}
+if( $conf->DBpassword != $conf->DBpassword2 ) {
+ $errs["DBpassword2"] = "Passwords don't match!";
+}
+if( !preg_match( '/^[A-Za-z_0-9]*$/', $conf->DBprefix ) ) {
+ $errs["DBprefix"] = "Invalid table prefix";
+}
+
+if( $conf->SysopPass == "" ) {
+ $errs["SysopPass"] = "Must not be blank";
+}
+if( $conf->SysopPass != $conf->SysopPass2 ) {
+ $errs["SysopPass2"] = "Passwords don't match!";
+}
+
+$conf->License = importRequest( "License", "none" );
+if( $conf->License == "gfdl" ) {
+ $conf->RightsUrl = "http://www.gnu.org/copyleft/fdl.html";
+ $conf->RightsText = "GNU Free Documentation License 1.2";
+ $conf->RightsCode = "gfdl";
+ $conf->RightsIcon = '${wgScriptPath}/skins/common/images/gnu-fdl.png';
+} elseif( $conf->License == "none" ) {
+ $conf->RightsUrl = $conf->RightsText = $conf->RightsCode = $conf->RightsIcon = "";
+} else {
+ $conf->RightsUrl = importRequest( "RightsUrl", "" );
+ $conf->RightsText = importRequest( "RightsText", "" );
+ $conf->RightsCode = importRequest( "RightsCode", "" );
+ $conf->RightsIcon = importRequest( "RightsIcon", "" );
+}
+
+$conf->Shm = importRequest( "Shm", "none" );
+$conf->MCServers = importRequest( "MCServers" );
+
+/* Test memcached servers */
+
+if ( $conf->Shm == 'memcached' && $conf->MCServers ) {
+ $conf->MCServerArray = array_map( 'trim', explode( ',', $conf->MCServers ) );
+ foreach ( $conf->MCServerArray as $server ) {
+ $error = testMemcachedServer( $server );
+ if ( $error ) {
+ $errs["MCServers"] = $error;
+ break;
+ }
+ }
+} else if ( $conf->Shm == 'memcached' ) {
+ $errs["MCServers"] = "Please specify at least one server if you wish to use memcached";
+}
+
+/* default values for installation */
+$conf->Email = importRequest("Email", "email_enabled");
+$conf->Emailuser = importRequest("Emailuser", "emailuser_enabled");
+$conf->Enotif = importRequest("Enotif", "enotif_allpages");
+$conf->Eauthent = importRequest("Eauthent", "eauthent_enabled");
+
+if( $conf->posted && ( 0 == count( $errs ) ) ) {
+ do { /* So we can 'continue' to end prematurely */
+ $conf->Root = ($conf->RootPW != "");
+
+ /* Load up the settings and get installin' */
+ $local = writeLocalSettings( $conf );
+ echo "<li style=\"list-style: none\">\n";
+ echo "<p><b>Generating configuration file...</b></p>\n";
+ echo "</li>\n";
+
+ $wgCommandLineMode = false;
+ chdir( ".." );
+ $ok = eval( $local );
+ if( $ok === false ) {
+ dieout( "Errors in generated configuration; " .
+ "most likely due to a bug in the installer... " .
+ "Config file was: " .
+ "<pre>" .
+ htmlspecialchars( $local ) .
+ "</pre>" .
+ "</ul>" );
+ }
+ $conf->DBtypename = '';
+ foreach (array_keys($ourdb) as $db) {
+ if ($conf->DBtype === $db)
+ $conf->DBtypename = $ourdb[$db]['fullname'];
+ }
+ if ( ! strlen($conf->DBtype)) {
+ $errs["DBpicktype"] = "Please choose a database type";
+ continue;
+ }
+
+ if (! $conf->DBtypename) {
+ $errs["DBtype"] = "Unknown database type '$conf->DBtype'";
+ continue;
+ }
+ print "<li>Database type: {$conf->DBtypename}</li>\n";
+ $dbclass = 'Database'.ucfirst($conf->DBtype);
+ $wgDBtype = $conf->DBtype;
+ $wgDBadminuser = "root";
+ $wgDBadminpassword = $conf->RootPW;
+
+ ## Mysql specific:
+ $wgDBprefix = $conf->DBprefix;
+
+ ## Postgres specific:
+ $wgDBport = $conf->DBport;
+ $wgDBmwschema = $conf->DBmwschema;
+ $wgDBts2schema = $conf->DBts2schema;
+
+ $wgCommandLineMode = true;
+ $wgUseDatabaseMessages = false; /* FIXME: For database failure */
+ require_once( "includes/Setup.php" );
+ chdir( "config" );
+
+ $wgTitle = Title::newFromText( "Installation script" );
+ error_reporting( E_ALL );
+ print "<li>Loading class: $dbclass";
+ $dbc = new $dbclass;
+
+ if( $conf->DBtype == 'mysql' ) {
+ $mysqlOldClient = version_compare( mysql_get_client_info(), "4.1.0", "lt" );
+ if( $mysqlOldClient ) {
+ print "<li><b>PHP is linked with old MySQL client libraries. If you are
+ using a MySQL 4.1 server and have problems connecting to the database,
+ see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
+ >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b></li>\n";
+ }
+ $ok = true; # Let's be optimistic
+
+ # Decide if we're going to use the superuser or the regular database user
+ $conf->Root = $useRoot;
+ if( $conf->Root ) {
+ $db_user = $conf->RootUser;
+ $db_pass = $conf->RootPW;
+ } else {
+ $db_user = $wgDBuser;
+ $db_pass = $wgDBpassword;
+ }
+
+ # Attempt to connect
+ echo( "<li>Attempting to connect to database server as $db_user..." );
+ $wgDatabase = Database::newFromParams( $wgDBserver, $db_user, $db_pass, '', 1 );
+
+ # Check the connection and respond to errors
+ if( $wgDatabase->isOpen() ) {
+ # Seems OK
+ $ok = true;
+ $wgDBadminuser = $db_user;
+ $wgDBadminpassword = $db_pass;
+ echo( "success.</li>\n" );
+ $wgDatabase->ignoreErrors( true );
+ $myver = $wgDatabase->getServerVersion();
+ } else {
+ # There were errors, report them and back out
+ $ok = false;
+ $errno = mysql_errno();
+ $errtx = htmlspecialchars( mysql_error() );
+ switch( $errno ) {
+ case 1045:
+ case 2000:
+ echo( "failed due to authentication errors. Check passwords.</li>" );
+ if( $conf->Root ) {
+ # The superuser details are wrong
+ $errs["RootUser"] = "Check username";
+ $errs["RootPW"] = "and password";
+ } else {
+ # The regular user details are wrong
+ $errs["DBuser"] = "Check username";
+ $errs["DBpassword"] = "and password";
+ }
+ break;
+ case 2002:
+ case 2003:
+ default:
+ # General connection problem
+ echo( "failed with error [$errno] $errtx.</li>\n" );
+ $errs["DBserver"] = "Connection failed";
+ break;
+ } # switch
+ } #conn. att.
+
+ if( !$ok ) { continue; }
+
+ } else /* not mysql */ {
+ error_reporting( E_ALL );
+ $wgSuperUser = '';
+ ## Possible connect as a superuser
+ if( $conf->Root ) {
+ $wgDBsuperuser = $conf->RootUser;
+ echo( "<li>Attempting to connect to database \"postgres\" as superuser \"$wgDBsuperuser\"..." );
+ $wgDatabase = $dbc->newFromParams($wgDBserver, $wgDBsuperuser, $conf->RootPW, "postgres", 1);
+ if (!$wgDatabase->isOpen()) {
+ print " error: " . $wgDatabase->lastError() . "</li>\n";
+ $errs["DBserver"] = "Could not connect to database as superuser";
+ $errs["RootUser"] = "Check username";
+ $errs["RootPW"] = "and password";
+ continue;
+ }
+ }
+ echo( "<li>Attempting to connect to database \"$wgDBname\" as \"$wgDBuser\"..." );
+ $wgDatabase = $dbc->newFromParams($wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1);
+ if (!$wgDatabase->isOpen()) {
+ print " error: " . $wgDatabase->lastError() . "</li>\n";
+ } else {
+ $myver = $wgDatabase->getServerVersion();
+ }
+ }
+
+ if ( !$wgDatabase->isOpen() ) {
+ $errs["DBserver"] = "Couldn't connect to database";
+ continue;
+ }
+
+ print "<li>Connected to $myver";
+ if ($conf->DBtype == 'mysql') {
+ if( version_compare( $myver, "4.0.14" ) < 0 ) {
+ dieout( " -- mysql 4.0.14 or later required. Aborting." );
+ }
+ $mysqlNewAuth = version_compare( $myver, "4.1.0", "ge" );
+ if( $mysqlNewAuth && $mysqlOldClient ) {
+ print "; <b class='error'>You are using MySQL 4.1 server, but PHP is linked
+ to old client libraries; if you have trouble with authentication, see
+ <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
+ >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>";
+ }
+ if( $wgDBmysql5 ) {
+ if( $mysqlNewAuth ) {
+ print "; enabling MySQL 4.1/5.0 charset mode";
+ } else {
+ print "; <b class='error'>MySQL 4.1/5.0 charset mode enabled,
+ but older version detected; will likely fail.</b>";
+ }
+ }
+ print "</li>\n";
+
+ @$sel = $wgDatabase->selectDB( $wgDBname );
+ if( $sel ) {
+ print "<li>Database <tt>" . htmlspecialchars( $wgDBname ) . "</tt> exists</li>\n";
+ } else {
+ $err = mysql_errno();
+ $databaseSafe = htmlspecialchars( $wgDBname );
+ if( $err == 1102 /* Invalid database name */ ) {
+ print "<ul><li><strong>{$databaseSafe}</strong> is not a valid database name.</li></ul>";
+ continue;
+ } elseif( $err != 1049 /* Database doesn't exist */ ) {
+ print "<ul><li>Error selecting database <strong>{$databaseSafe}</strong>: {$err} ";
+ print htmlspecialchars( mysql_error() ) . "</li></ul>";
+ continue;
+ }
+ print "<li>Attempting to create database...</li>";
+ $res = $wgDatabase->query( "CREATE DATABASE `$wgDBname`" );
+ if( !$res ) {
+ print "<li>Couldn't create database <tt>" .
+ htmlspecialchars( $wgDBname ) .
+ "</tt>; try with root access or check your username/pass.</li>\n";
+ $errs["RootPW"] = "&lt;- Enter";
+ continue;
+ }
+ print "<li>Created database <tt>" . htmlspecialchars( $wgDBname ) . "</tt></li>\n";
+ }
+ $wgDatabase->selectDB( $wgDBname );
+ }
+ else if ($conf->DBtype == 'postgres') {
+ if( version_compare( $myver, "PostgreSQL 8.0" ) < 0 ) {
+ dieout( " <b>Postgres 8.0 or later is required</b>. Aborting.</li></ul>" );
+ }
+ }
+
+ if( $wgDatabase->tableExists( "cur" ) || $wgDatabase->tableExists( "revision" ) ) {
+ print "<li>There are already MediaWiki tables in this database. Checking if updates are needed...</li>\n";
+
+ # Create user if required (todo: other databases)
+ if ( $conf->Root && $conf->DBtype == 'mysql') {
+ $conn = $dbc->newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
+ if ( $conn->isOpen() ) {
+ print "<li>DB user account ok</li>\n";
+ $conn->close();
+ } else {
+ print "<li>Granting user permissions...";
+ if( $mysqlOldClient && $mysqlNewAuth ) {
+ print " <b class='error'>If the next step fails, see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'>http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>";
+ }
+ print "</li>\n";
+ dbsource( "../maintenance/users.sql", $wgDatabase );
+ }
+ }
+ print "<pre>\n";
+ chdir( ".." );
+ flush();
+ do_all_updates();
+ chdir( "config" );
+ print "</pre>\n";
+ print "<li>Finished update checks.</li>\n";
+ } else {
+ # FIXME: Check for errors
+ print "<li>Creating tables...";
+ if ($conf->DBtype == 'mysql') {
+ switch( $conf->DBschema ) {
+ case "mysql4":
+ print " using MySQL 4 table defs...";
+ dbsource( "../maintenance/tables.sql", $wgDatabase );
+ break;
+ case "mysql5":
+ print " using MySQL 5 UTF-8 table defs...";
+ dbsource( "../maintenance/mysql5/tables.sql", $wgDatabase );
+ break;
+ case "mysql5-binary":
+ print " using MySQL 5 binary table defs...";
+ dbsource( "../maintenance/mysql5/tables-binary.sql", $wgDatabase );
+ break;
+ default:
+ dieout( " <b>invalid schema selection!</b></li>" );
+ }
+ dbsource( "../maintenance/interwiki.sql", $wgDatabase );
+ } else if ($conf->DBtype == 'postgres') {
+ $wgDatabase->setup_database();
+ }
+ else {
+ $errs["DBtype"] = "Do not know how to handle database type '$conf->DBtype'";
+ continue;
+ }
+
+ print " done.</li>\n";
+
+ print "<li>Initializing data...</li>\n";
+ $wgDatabase->insert( 'site_stats',
+ array ( 'ss_row_id' => 1,
+ 'ss_total_views' => 0,
+ 'ss_total_edits' => 0,
+ 'ss_good_articles' => 0 ) );
+
+ # Set up the "regular user" account *if we can, and if we need to*
+ if( $conf->Root and $conf->DBtype == 'mysql') {
+ # See if we need to
+ $wgDatabase2 = $dbc->newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
+ if( $wgDatabase2->isOpen() ) {
+ # Nope, just close the test connection and continue
+ $wgDatabase2->close();
+ echo( "<li>User $wgDBuser exists. Skipping grants.</li>\n" );
+ } else {
+ # Yes, so run the grants
+ echo( "<li>Granting user permissions to $wgDBuser on $wgDBname..." );
+ dbsource( "../maintenance/users.sql", $wgDatabase );
+ echo( "success.</li>\n" );
+ }
+ }
+
+ if( $conf->SysopName ) {
+ $u = User::newFromName( $conf->getSysopName() );
+ if ( !$u ) {
+ print "<li><strong class=\"error\">Warning:</strong> Skipped sysop account creation - invalid username!</li>\n";
+ }
+ else if ( 0 == $u->idForName() ) {
+ $u->addToDatabase();
+ $u->setPassword( $conf->getSysopPass() );
+ $u->saveSettings();
+
+ $u->addGroup( "sysop" );
+ $u->addGroup( "bureaucrat" );
+
+ print "<li>Created sysop account <tt>" .
+ htmlspecialchars( $conf->SysopName ) . "</tt>.</li>\n";
+ } else {
+ print "<li>Could not create user - already exists!</li>\n";
+ }
+ } else {
+ print "<li>Skipped sysop account creation, no name given.</li>\n";
+ }
+
+ $titleobj = Title::newFromText( wfMsgNoDB( "mainpage" ) );
+ $article = new Article( $titleobj );
+ $newid = $article->insertOn( $wgDatabase );
+ $revision = new Revision( array(
+ 'page' => $newid,
+ 'text' => wfMsg( 'mainpagetext' ) . "\n\n" . wfMsg( 'mainpagedocfooter' ),
+ 'comment' => '',
+ 'user' => 0,
+ 'user_text' => 'MediaWiki default',
+ ) );
+ $revid = $revision->insertOn( $wgDatabase );
+ $article->updateRevisionOn( $wgDatabase, $revision );
+ }
+
+ /* Write out the config file now that all is well */
+ print "<li style=\"list-style: none\">\n";
+ print "<p>Creating LocalSettings.php...</p>\n\n";
+ $localSettings = "<" . "?php$endl$local$endl?" . ">\r\n";
+ // Fix up a common line-ending problem (due to CVS on Windows)
+ $localSettings = str_replace( "\r\n", "\n", $localSettings );
+ $f = fopen( "LocalSettings.php", 'xt' );
+
+ if( $f == false ) {
+ dieout( "<p>Couldn't write out LocalSettings.php. Check that the directory permissions are correct and that there isn't already a file of that name here...</p>\n" .
+ "<p>Here's the file that would have been written, try to paste it into place manually:</p>\n" .
+ "<pre>\n" . htmlspecialchars( $localSettings ) . "</pre>\n" );
+ }
+ if(fwrite( $f, $localSettings ) ) {
+ fclose( $f );
+ writeSuccessMessage();
+ } else {
+ fclose( $f );
+ die("<p class='error'>An error occured while writing the config/LocalSettings.php file. Check user rights and disk space then try again.</p>\n");
+
+ }
+ print "</li>\n";
+
+ } while( false );
+}
+?>
+</ul>
+
+
+<?php
+
+if( count( $errs ) ) {
+ /* Display options form */
+
+ if( $conf->posted ) {
+ echo "<p class='error-top'>Something's not quite right yet; make sure everything below is filled out correctly.</p>\n";
+ }
+?>
+
+<form action="index.php" name="config" method="post">
+
+
+<h2>Site config</h2>
+
+<div class="config-section">
+ <div class="config-input">
+ <?php
+ aField( $conf, "Sitename", "Wiki name:" );
+ ?>
+ </div>
+ <p class="config-desc">
+ Preferably a short word without punctuation, i.e. "Wikipedia".<br />
+ Will appear as the namespace name for "meta" pages, and throughout the interface.
+ </p>
+
+ <div class="config-input">
+ <?php
+ aField( $conf, "EmergencyContact", "Contact e-mail:" );
+ ?>
+ </div>
+ <p class="config-desc">
+ Displayed to users in some error messages, used as the return address for password reminders, and used as the default sender address of e-mail notifications.
+ </p>
+
+ <div class="config-input">
+ <label class='column' for="LanguageCode">Language:</label>
+ <select id="LanguageCode" name="LanguageCode">
+
+ <?php
+ $list = getLanguageList();
+ foreach( $list as $code => $name ) {
+ $sel = ($code == $conf->LanguageCode) ? 'selected="selected"' : '';
+ echo "\t\t<option value=\"$code\" $sel>$name</option>\n";
+ }
+ ?>
+ </select>
+ </div>
+ <p class="config-desc">
+ Select the language for your wiki's interface. Some localizations aren't fully complete. Unicode (UTF-8) is used for all localizations.
+ </p>
+
+ <div class="config-input">
+ <label class='column'>Copyright/license:</label>
+
+ <ul class="plain">
+ <li><?php aField( $conf, "License", "No license metadata", "radio", "none" ); ?></li>
+ <li><?php aField( $conf, "License", "GNU Free Documentation License 1.2 (Wikipedia-compatible)", "radio", "gfdl" ); ?></li>
+ <li><?php
+ aField( $conf, "License", "A Creative Commons license - ", "radio", "cc" );
+ $partner = "MediaWiki";
+ $exit = urlencode( "$wgServer{$conf->ScriptPath}/config/index.php?License=cc&RightsUrl=[license_url]&RightsText=[license_name]&RightsCode=[license_code]&RightsIcon=[license_button]" );
+ $icon = urlencode( "$wgServer$wgUploadPath/wiki.png" );
+ $ccApp = htmlspecialchars( "http://creativecommons.org/license/?partner=$partner&exit_url=$exit&partner_icon_url=$icon" );
+ print "<a href=\"$ccApp\" target='_blank'>choose</a>";
+ ?>
+ <?php if( $conf->License == "cc" ) { ?>
+ <ul>
+ <li><?php aField( $conf, "RightsIcon", "<img src=\"" . htmlspecialchars( $conf->RightsIcon ) . "\" alt='(Creative Commons icon)' />", "hidden" ); ?></li>
+ <li><?php aField( $conf, "RightsText", htmlspecialchars( $conf->RightsText ), "hidden" ); ?></li>
+ <li><?php aField( $conf, "RightsCode", "code: " . htmlspecialchars( $conf->RightsCode ), "hidden" ); ?></li>
+ <li><?php aField( $conf, "RightsUrl", "<a href=\"" . htmlspecialchars( $conf->RightsUrl ) . "\">" . htmlspecialchars( $conf->RightsUrl ) . "</a>", "hidden" ); ?></li>
+ </ul>
+ <?php } ?>
+ </li>
+ </ul>
+ </div>
+ <p class="config-desc">
+ A notice, icon, and machine-readable copyright metadata will be displayed for the license you pick.
+ </p>
+
+
+ <div class="config-input">
+ <?php aField( $conf, "SysopName", "Admin username:" ) ?>
+ </div>
+ <div class="config-input">
+ <?php aField( $conf, "SysopPass", "Password:", "password" ) ?>
+ </div>
+ <div class="config-input">
+ <?php aField( $conf, "SysopPass2", "Password confirm:", "password" ) ?>
+ </div>
+ <p class="config-desc">
+ An admin can lock/delete pages, block users from editing, and do other maintenance tasks.<br />
+ A new account will be added only when creating a new wiki database.
+ </p>
+
+ <div class="config-input">
+ <label class='column'>Shared memory caching:</label>
+
+ <ul class="plain">
+ <li><?php aField( $conf, "Shm", "No caching", "radio", "none" ); ?></li>
+ <?php
+ if ( $conf->turck ) {
+ echo "<li>";
+ aField( $conf, "Shm", "Turck MMCache", "radio", "turck" );
+ echo "</li>";
+ }
+ if ( $conf->apc ) {
+ echo "<li>";
+ aField( $conf, "Shm", "APC", "radio", "apc" );
+ echo "</li>";
+ }
+ if ( $conf->eaccel ) {
+ echo "<li>";
+ aField( $conf, "Shm", "eAccelerator", "radio", "eaccel" );
+ echo "</li>";
+ }
+ ?>
+ <li><?php aField( $conf, "Shm", "Memcached", "radio", "memcached" ); ?></li>
+ </ul>
+ <div style="clear:left"><?php aField( $conf, "MCServers", "Memcached servers:", "text" ) ?></div>
+ </div>
+ <p class="config-desc">
+ Using a shared memory system such as Turck MMCache, APC, eAccelerator, or Memcached
+ will speed up MediaWiki significantly. Memcached is the best solution but needs to be
+ installed. Specify the server addresses and ports in a comma-separted list. Only
+ use Turck shared memory if the wiki will be running on a single Apache server.
+ </p>
+</div>
+
+<h2>E-mail, e-mail notification and authentication setup</h2>
+
+<div class="config-section">
+ <div class="config-input">
+ <label class='column'>E-mail features (global):</label>
+ <ul class="plain">
+ <li><?php aField( $conf, "Email", "Enabled", "radio", "email_enabled" ); ?></li>
+ <li><?php aField( $conf, "Email", "Disabled", "radio", "email_disabled" ); ?></li>
+ </ul>
+ </div>
+ <p class="config-desc">
+ Use this to disable all e-mail functions (password reminders, user-to-user e-mail and e-mail notifications)
+ if sending mail doesn't work on your server.
+ </p>
+
+ <div class="config-input">
+ <label class='column'>User-to-user e-mail:</label>
+ <ul class="plain">
+ <li><?php aField( $conf, "Emailuser", "Enabled", "radio", "emailuser_enabled" ); ?></li>
+ <li><?php aField( $conf, "Emailuser", "Disabled", "radio", "emailuser_disabled" ); ?></li>
+ </ul>
+ </div>
+ <p class="config-desc">
+ The user-to-user e-mail feature (Special:Emailuser) lets the wiki act as a relay to allow users to exchange e-mail without publicly advertising their e-mail address.
+ </p>
+ <div class="config-input">
+ <label class='column'>E-mail notification about changes:</label>
+ <ul class="plain">
+ <li><?php aField( $conf, "Enotif", "Disabled", "radio", "enotif_disabled" ); ?></li>
+ <li><?php aField( $conf, "Enotif", "Enabled for changes to user discussion pages only", "radio", "enotif_usertalk" ); ?></li>
+ <li><?php aField( $conf, "Enotif", "Enabled for changes to user discussion pages, and to pages on watchlists (not recommended for large wikis)", "radio", "enotif_allpages" ); ?></li>
+ </ul>
+ </div>
+ <div class="config-desc">
+ <p>
+ For this feature to work, an e-mail address must be present for the user account, and the notification
+ options in the user's preferences must be enabled. Also note the
+ authentication option below. When testing the feature, keep in mind that your own changes will never trigger notifications to be sent to yourself.</p>
+
+ <p>There are additional options for fine tuning in /includes/DefaultSettings.php; copy these to your LocalSettings.php and edit them there to change them.</p>
+ </div>
+
+ <div class="config-input">
+ <label class='column'>E-mail address authentication:</label>
+ <ul class="plain">
+ <li><?php aField( $conf, "Eauthent", "Disabled", "radio", "eauthent_disabled" ); ?></li>
+ <li><?php aField( $conf, "Eauthent", "Enabled", "radio", "eauthent_enabled" ); ?></li>
+ </ul>
+ </div>
+ <div class="config-desc">
+ <p>If this option is enabled, users have to confirm their e-mail address using a magic link sent to them whenever they set or change it, and only authenticated e-mail addresses can receive mails from other users and/or
+ change notification mails. Setting this option is <B>recommended</B> for public wikis because of potential abuse of the e-mail features above.</p>
+ </div>
+
+</div>
+
+<h2>Database config</h2>
+
+<div class="config-section">
+<div class="config-input">
+ <label class='column'>Database type:</label>
+<?php if (isset($errs['DBpicktype'])) print "<span class='error'>$errs[DBpicktype]</span>\n"; ?>
+ <ul class='plain'><?php database_picker($conf) ?></ul>
+ </div>
+
+ <div class="config-input" style="clear:left"><?php
+ aField( $conf, "DBserver", "Database host:" );
+ ?></div>
+ <p class="config-desc">
+ If your database server isn't on your web server, enter the name or IP address here.
+ </p>
+
+ <div class="config-input"><?php
+ aField( $conf, "DBname", "Database name:" );
+ ?></div>
+ <div class="config-input"><?php
+ aField( $conf, "DBuser", "DB username:" );
+ ?></div>
+ <div class="config-input"><?php
+ aField( $conf, "DBpassword", "DB password:", "password" );
+ ?></div>
+ <div class="config-input"><?php
+ aField( $conf, "DBpassword2", "DB password confirm:", "password" );
+ ?></div>
+ <p class="config-desc">
+ If you only have a single user account and database available,
+ enter those here. If you have database root access (see below)
+ you can specify new accounts/databases to be created. This account
+ will not be created if it pre-exists. If this is the case, ensure that it
+ has SELECT, INSERT, UPDATE and DELETE permissions on the MediaWiki database.
+ </p>
+
+ <div class="config-input">
+ <label class="column">Superuser account:</label>
+ <input type="checkbox" name="useroot" id="useroot" <?php if( $useRoot ) { ?>checked="checked" <?php } ?>/>
+ &nbsp;<label for="useroot">Use superuser account</label>
+ </div>
+ <div class="config-input">
+ <?php
+ aField( $conf, "RootUser", "Superuser name:", "superuser" );
+ ?>
+ </div>
+ <div class="config-input">
+ <?php
+ aField( $conf, "RootPW", "Superuser password:", "password" );
+ ?>
+ </div>
+
+ <p class="config-desc">
+ If the database user specified above does not exist, or does not have access to create
+ the database (if needed) or tables within it, please check the box and provide details
+ of a superuser account, such as <strong>root</strong>, which does.
+ </p>
+
+ <?php database_switcher('mysql'); ?>
+ <div class="config-input"><?php
+ aField( $conf, "DBprefix", "Database table prefix:" );
+ ?></div>
+ <div class="config-desc">
+ <p>If you need to share one database between multiple wikis, or
+ MediaWiki and another web application, you may choose to
+ add a prefix to all the table names to avoid conflicts.</p>
+
+ <p>Avoid exotic characters; something like <tt>mw_</tt> is good.</p>
+ </div>
+
+ <div class="config-input"><label class="column">Database charset</label>
+ <div>Select one:</div>
+ <ul class="plain">
+ <li><?php aField( $conf, "DBschema", "Backwards-compatible UTF-8", "radio", "mysql4" ); ?></li>
+ <li><?php aField( $conf, "DBschema", "Experimental MySQL 4.1/5.0 UTF-8", "radio", "mysql5" ); ?></li>
+ <li><?php aField( $conf, "DBschema", "Experimental MySQL 4.1/5.0 binary", "radio", "mysql5-binary" ); ?></li>
+ </ul>
+ </div>
+ <p class="config-desc">
+ <b>EXPERIMENTAL:</b> You can enable explicit Unicode charset support
+ for MySQL 4.1 and 5.0 servers. This is not well tested and may
+ cause things to break. <b>If upgrading an older installation, leave
+ in backwards-compatible mode.</b>
+ </p>
+ </div>
+
+ <?php database_switcher('postgres'); ?>
+ <div class="config-input"><?php
+ aField( $conf, "DBport", "Database port:" );
+ ?></div>
+ <div class="config-input"><?php
+ aField( $conf, "DBmwschema", "Schema for mediawiki:" );
+ ?></div>
+ <div class="config-input"><?php
+ aField( $conf, "DBts2schema", "Schema for tsearch2:" );
+ ?></div>
+ <div class="config-desc">
+ <p>The username specified above will have it's search path set to the above schemas,
+ so it is recommended that you create a new user.</p>
+ </div>
+ </div>
+
+ <div class="config-input" style="padding:2em 0 3em">
+ <label class='column'>&nbsp;</label>
+ <input type="submit" value="Install MediaWiki!" class="btn-install" />
+ </div>
+
+</div>
+
+<script type="text/javascript">
+window.onload = toggleDBarea('<?php echo $conf->DBtype; ?>',
+<?php
+ ## If they passed in a root user name, don't populate it on page load
+ echo strlen(importPost('RootUser', '')) ? 0 : 1;
+?>);
+</script>
+
+</form>
+
+<?php
+}
+
+/* -------------------------------------------------------------------------------------- */
+function writeSuccessMessage() {
+ if ( ini_get( 'safe_mode' ) && !ini_get( 'open_basedir' ) ) {
+ echo <<<EOT
+<p>Installation successful!</p>
+<p>To complete the installation, please do the following:
+<ol>
+ <li>Download config/LocalSettings.php with your FTP client or file manager</li>
+ <li>Upload it to the parent directory</li>
+ <li>Delete config/LocalSettings.php</li>
+ <li>Start using <a href='../index.php'>your wiki</a>!
+</ol>
+<p>If you are in a shared hosting environment, do <strong>not</strong> just move LocalSettings.php
+remotely. LocalSettings.php is currently owned by the user your webserver is running under,
+which means that anyone on the same server can read your database password! Downloading
+it and uploading it again will hopefully change the ownership to a user ID specific to you.</p>
+EOT;
+ } else {
+ echo "<p><span style='font-weight:bold;color:green;font-size:110%'>Installation successful!</span> Move the <tt>config/LocalSettings.php</tt> file into the parent directory, then follow
+ <strong><a href='../index.php'>this link</a></strong> to your wiki.</p>\n";
+ }
+}
+
+
+function escapePhpString( $string ) {
+ return strtr( $string,
+ array(
+ "\n" => "\\n",
+ "\r" => "\\r",
+ "\t" => "\\t",
+ "\\" => "\\\\",
+ "\$" => "\\\$",
+ "\"" => "\\\""
+ ));
+}
+
+function writeLocalSettings( $conf ) {
+ $conf->UseImageResize = $conf->UseImageResize ? 'true' : 'false';
+ $conf->PasswordSender = $conf->EmergencyContact;
+ $zlib = ($conf->zlib ? "" : "# ");
+ $magic = ($conf->ImageMagick ? "" : "# ");
+ $convert = ($conf->ImageMagick ? $conf->ImageMagick : "/usr/bin/convert" );
+ $rights = ($conf->RightsUrl) ? "" : "# ";
+ $hashedUploads = $conf->safeMode ? '' : '# ';
+
+ switch ( $conf->Shm ) {
+ case 'memcached':
+ $cacheType = 'CACHE_MEMCACHED';
+ $mcservers = var_export( $conf->MCServerArray, true );
+ break;
+ case 'turck':
+ case 'apc':
+ case 'eaccel':
+ $cacheType = 'CACHE_ACCEL';
+ $mcservers = 'array()';
+ break;
+ default:
+ $cacheType = 'CACHE_NONE';
+ $mcservers = 'array()';
+ }
+
+ if ( $conf->Email == 'email_enabled' ) {
+ $enableemail = 'true';
+ $enableuseremail = ( $conf->Emailuser == 'emailuser_enabled' ) ? 'true' : 'false' ;
+ $eauthent = ( $conf->Eauthent == 'eauthent_enabled' ) ? 'true' : 'false' ;
+ switch ( $conf->Enotif ) {
+ case 'enotif_usertalk':
+ $enotifusertalk = 'true';
+ $enotifwatchlist = 'false';
+ break;
+ case 'enotif_allpages':
+ $enotifusertalk = 'true';
+ $enotifwatchlist = 'true';
+ break;
+ default:
+ $enotifusertalk = 'false';
+ $enotifwatchlist = 'false';
+ }
+ } else {
+ $enableuseremail = 'false';
+ $enableemail = 'false';
+ $eauthent = 'false';
+ $enotifusertalk = 'false';
+ $enotifwatchlist = 'false';
+ }
+
+ $file = @fopen( "/dev/urandom", "r" );
+ if ( $file ) {
+ $secretKey = bin2hex( fread( $file, 32 ) );
+ fclose( $file );
+ } else {
+ $secretKey = "";
+ for ( $i=0; $i<8; $i++ ) {
+ $secretKey .= dechex(mt_rand(0, 0x7fffffff));
+ }
+ print "<li>Warning: \$wgSecretKey key is insecure, generated with mt_rand(). Consider changing it manually.</li>\n";
+ }
+
+ # Add slashes to strings for double quoting
+ $slconf = array_map( "escapePhpString", get_object_vars( $conf ) );
+ if( $conf->License == 'gfdl' ) {
+ # Needs literal string interpolation for the current style path
+ $slconf['RightsIcon'] = $conf->RightsIcon;
+ }
+
+ $localsettings = "
+# This file was automatically generated by the MediaWiki installer.
+# If you make manual changes, please keep track in case you need to
+# recreate them later.
+#
+# See includes/DefaultSettings.php for all configurable settings
+# and their default values, but don't forget to make changes in _this_
+# file, not there.
+
+# If you customize your file layout, set \$IP to the directory that contains
+# the other MediaWiki files. It will be used as a base to locate files.
+if( defined( 'MW_INSTALL_PATH' ) ) {
+ \$IP = MW_INSTALL_PATH;
+} else {
+ \$IP = dirname( __FILE__ );
+}
+
+\$path = array( \$IP, \"\$IP/includes\", \"\$IP/languages\" );
+set_include_path( implode( PATH_SEPARATOR, \$path ) . PATH_SEPARATOR . get_include_path() );
+
+require_once( \"includes/DefaultSettings.php\" );
+
+# If PHP's memory limit is very low, some operations may fail.
+" . ($conf->raiseMemory ? '' : '# ' ) . "ini_set( 'memory_limit', '20M' );" . "
+
+if ( \$wgCommandLineMode ) {
+ if ( isset( \$_SERVER ) && array_key_exists( 'REQUEST_METHOD', \$_SERVER ) ) {
+ die( \"This script must be run from the command line\\n\" );
+ }
+} elseif ( empty( \$wgNoOutputBuffer ) ) {
+ ## Compress output if the browser supports it
+ {$zlib}if( !ini_get( 'zlib.output_compression' ) ) @ob_start( 'ob_gzhandler' );
+}
+
+\$wgSitename = \"{$slconf['Sitename']}\";
+
+## The URL base path to the directory containing the wiki;
+## defaults for all runtime URL paths are based off of this.
+\$wgScriptPath = \"{$slconf['ScriptPath']}\";
+
+## For more information on customizing the URLs please see:
+## http://www.mediawiki.org/wiki/Manual:Short_URL
+
+\$wgEnableEmail = $enableemail;
+\$wgEnableUserEmail = $enableuseremail;
+
+\$wgEmergencyContact = \"{$slconf['EmergencyContact']}\";
+\$wgPasswordSender = \"{$slconf['PasswordSender']}\";
+
+## For a detailed description of the following switches see
+## http://meta.wikimedia.org/Enotif and http://meta.wikimedia.org/Eauthent
+## There are many more options for fine tuning available see
+## /includes/DefaultSettings.php
+## UPO means: this is also a user preference option
+\$wgEnotifUserTalk = $enotifusertalk; # UPO
+\$wgEnotifWatchlist = $enotifwatchlist; # UPO
+\$wgEmailAuthentication = $eauthent;
+
+\$wgDBtype = \"{$slconf['DBtype']}\";
+\$wgDBserver = \"{$slconf['DBserver']}\";
+\$wgDBname = \"{$slconf['DBname']}\";
+\$wgDBuser = \"{$slconf['DBuser']}\";
+\$wgDBpassword = \"{$slconf['DBpassword']}\";
+\$wgDBport = \"{$slconf['DBport']}\";
+\$wgDBprefix = \"{$slconf['DBprefix']}\";
+
+# Schemas for Postgres
+\$wgDBmwschema = \"{$slconf['DBmwschema']}\";
+\$wgDBts2schema = \"{$slconf['DBts2schema']}\";
+
+# Experimental charset support for MySQL 4.1/5.0.
+\$wgDBmysql5 = {$conf->DBmysql5};
+
+## Shared memory settings
+\$wgMainCacheType = $cacheType;
+\$wgMemCachedServers = $mcservers;
+
+## To enable image uploads, make sure the 'images' directory
+## is writable, then set this to true:
+\$wgEnableUploads = false;
+\$wgUseImageResize = {$conf->UseImageResize};
+{$magic}\$wgUseImageMagick = true;
+{$magic}\$wgImageMagickConvertCommand = \"{$convert}\";
+
+## If you want to use image uploads under safe mode,
+## create the directories images/archive, images/thumb and
+## images/temp, and make them all writable. Then uncomment
+## this, if it's not already uncommented:
+{$hashedUploads}\$wgHashedUploadDirectory = false;
+
+## If you have the appropriate support software installed
+## you can enable inline LaTeX equations:
+\$wgUseTeX = false;
+
+\$wgLocalInterwiki = \$wgSitename;
+
+\$wgLanguageCode = \"{$slconf['LanguageCode']}\";
+
+\$wgProxyKey = \"$secretKey\";
+
+## Default skin: you can change the default skin. Use the internal symbolic
+## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook':
+\$wgDefaultSkin = 'monobook';
+
+## For attaching licensing metadata to pages, and displaying an
+## appropriate copyright notice / icon. GNU Free Documentation
+## License and Creative Commons licenses are supported so far.
+{$rights}\$wgEnableCreativeCommonsRdf = true;
+\$wgRightsPage = \"\"; # Set to the title of a wiki page that describes your license/copyright
+\$wgRightsUrl = \"{$slconf['RightsUrl']}\";
+\$wgRightsText = \"{$slconf['RightsText']}\";
+\$wgRightsIcon = \"{$slconf['RightsIcon']}\";
+# \$wgRightsCode = \"{$slconf['RightsCode']}\"; # Not yet used
+
+\$wgDiff3 = \"{$slconf['diff3']}\";
+
+# When you make changes to this configuration file, this will make
+# sure that cached pages are cleared.
+\$configdate = gmdate( 'YmdHis', @filemtime( __FILE__ ) );
+\$wgCacheEpoch = max( \$wgCacheEpoch, \$configdate );
+ "; ## End of setting the $localsettings string
+
+ // Keep things in Unix line endings internally;
+ // the system will write out as local text type.
+ return str_replace( "\r\n", "\n", $localsettings );
+}
+
+function dieout( $text ) {
+ die( $text . "\n\n</body>\n</html>" );
+}
+
+function importVar( &$var, $name, $default = "" ) {
+ if( isset( $var[$name] ) ) {
+ $retval = $var[$name];
+ if ( get_magic_quotes_gpc() ) {
+ $retval = stripslashes( $retval );
+ }
+ } else {
+ $retval = $default;
+ }
+ return $retval;
+}
+
+function importPost( $name, $default = "" ) {
+ return importVar( $_POST, $name, $default );
+}
+
+function importCheck( $name ) {
+ return isset( $_POST[$name] );
+}
+
+function importRequest( $name, $default = "" ) {
+ return importVar( $_REQUEST, $name, $default );
+}
+
+$radioCount = 0;
+
+function aField( &$conf, $field, $text, $type = "text", $value = "", $onclick = '' ) {
+ global $radioCount;
+ if( $type != "" ) {
+ $xtype = "type=\"$type\"";
+ } else {
+ $xtype = "";
+ }
+
+ $id = $field;
+ $nolabel = ($type == "radio") || ($type == "hidden");
+
+ if ($type == 'radio')
+ $id .= $radioCount++;
+
+ if( $nolabel ) {
+ echo "\t\t<label>";
+ } else {
+ echo "\t\t<label class='column' for=\"$id\">$text</label>\n";
+ }
+
+ if( $type == "radio" && $value == $conf->$field ) {
+ $checked = "checked='checked'";
+ } else {
+ $checked = "";
+ }
+ echo "\t\t<input $xtype name=\"$field\" id=\"$id\" class=\"iput-$type\" $checked ";
+ if ($onclick) {
+ echo " onclick='toggleDBarea(\"$value\",1)' " ;
+ }
+ echo "value=\"";
+ if( $type == "radio" ) {
+ echo htmlspecialchars( $value );
+ } else {
+ echo htmlspecialchars( $conf->$field );
+ }
+
+
+ echo "\" />\n";
+ if( $nolabel ) {
+ echo " $text</label>\n";
+ }
+
+ global $errs;
+ if(isset($errs[$field])) echo "<span class='error'>" . $errs[$field] . "</span>\n";
+}
+
+function getLanguageList() {
+ global $wgLanguageNames;
+ if( !isset( $wgLanguageNames ) ) {
+ require_once( "languages/Names.php" );
+ }
+
+ $codes = array();
+
+ $d = opendir( "../languages/messages" );
+ /* In case we are called from the root directory */
+ if (!$d)
+ $d = opendir( "languages/messages");
+ while( false !== ($f = readdir( $d ) ) ) {
+ $m = array();
+ if( preg_match( '/Messages([A-Z][a-z_]+)\.php$/', $f, $m ) ) {
+ $code = str_replace( '_', '-', strtolower( $m[1] ) );
+ if( isset( $wgLanguageNames[$code] ) ) {
+ $name = $code . ' - ' . $wgLanguageNames[$code];
+ } else {
+ $name = $code;
+ }
+ $codes[$code] = $name;
+ }
+ }
+ closedir( $d );
+ ksort( $codes );
+ return $codes;
+}
+
+#Check for location of an executable
+# @param string $loc single location to check
+# @param array $names filenames to check for.
+# @param mixed $versioninfo array of details to use when checking version, use false for no version checking
+function locate_executable($loc, $names, $versioninfo = false) {
+ if (!is_array($names))
+ $names = array($names);
+
+ foreach ($names as $name) {
+ $command = "$loc".DIRECTORY_SEPARATOR."$name";
+ if (file_exists($command)) {
+ if (!$versioninfo)
+ return $command;
+
+ $file = str_replace('$1', $command, $versioninfo[0]);
+ if (strstr(`$file`, $versioninfo[1]) !== false)
+ return $command;
+ }
+ }
+ return false;
+}
+
+# Test a memcached server
+function testMemcachedServer( $server ) {
+ $hostport = explode(":", $server);
+ $errstr = false;
+ $fp = false;
+ if ( !function_exists( 'fsockopen' ) ) {
+ $errstr = "Can't connect to memcached, fsockopen() not present";
+ }
+ if ( !$errstr && count( $hostport ) != 2 ) {
+ $errstr = 'Please specify host and port';
+ var_dump( $hostport );
+ }
+ if ( !$errstr ) {
+ list( $host, $port ) = $hostport;
+ $errno = 0;
+ $fsockerr = '';
+
+ $fp = @fsockopen( $host, $port, $errno, $fsockerr, 1.0 );
+ if ( $fp === false ) {
+ $errstr = "Cannot connect to memcached on $host:$port : $fsockerr";
+ }
+ }
+ if ( !$errstr ) {
+ $command = "version\r\n";
+ $bytes = fwrite( $fp, $command );
+ if ( $bytes != strlen( $command ) ) {
+ $errstr = "Cannot write to memcached socket on $host:$port";
+ }
+ }
+ if ( !$errstr ) {
+ $expected = "VERSION ";
+ $response = fread( $fp, strlen( $expected ) );
+ if ( $response != $expected ) {
+ $errstr = "Didn't get correct memcached response from $host:$port";
+ }
+ }
+ if ( $fp ) {
+ fclose( $fp );
+ }
+ if ( !$errstr ) {
+ echo "<li>Connected to memcached on $host:$port successfully";
+ }
+ return $errstr;
+}
+
+function database_picker($conf) {
+ global $ourdb;
+ print "\n";
+ foreach(array_keys($ourdb) as $db) {
+ if ($ourdb[$db]['havedriver']) {
+ print "<li>";
+ aField( $conf, "DBtype", $ourdb[$db]['fullname'], 'radio', $db, 'onclick');
+ print "</li>\n";
+ }
+ }
+ print "\n";
+}
+
+function database_switcher($db) {
+ global $ourdb;
+ $color = $ourdb[$db]['bgcolor'];
+ $full = $ourdb[$db]['fullname'];
+ print "<div id='$db' style='display:none; background: $color'>\n";
+ print "<h3>$full specific options:</h3>\n";
+}
+
+function printListItem( $item ) {
+ print "<li>$item</li>";
+}
+
+?>
+
+ <div class="license">
+ <hr>
+ <p>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.</p>
+
+ <p>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.</p>
+
+ <p>You should have received <a href="../COPYING">a copy of the GNU General Public License</a>
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ or <a href="http://www.gnu.org/copyleft/gpl.html">read it online</a></p>
+ </div>
+
+</div></div></div>
+
+
+<div id="column-one">
+ <div class="portlet" id="p-logo">
+ <a style="background-image: url(../skins/common/images/mediawiki.png);"
+ href="http://www.mediawiki.org/"
+ title="Main Page"></a>
+ </div>
+ <script type="text/javascript"> if (window.isMSIE55) fixalpha(); </script>
+ <div class='portlet'><div class='pBody'>
+ <ul>
+ <li><strong><a href="http://www.mediawiki.org/">MediaWiki home</a></strong></li>
+ <li><a href="../README">Readme</a></li>
+ <li><a href="../RELEASE-NOTES">Release notes</a></li>
+ <li><a href="../docs/">Documentation</a></li>
+ <li><a href="http://meta.wikipedia.org/wiki/MediaWiki_User's_Guide">User's Guide</a></li>
+ <li><a href="http://meta.wikimedia.org/wiki/MediaWiki_FAQ">FAQ</a></li>
+ </ul>
+ <p style="font-size:90%;margin-top:1em">MediaWiki is Copyright &copy; 2001-2007 by Magnus Manske, Brion Vibber, Lee Daniel Crocker, Tim Starling, Erik M&ouml;ller, Gabriel Wicke and others.</p>
+ </div></div>
+</div>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/README b/docs/README
new file mode 100644
index 000000000000..43ac8ef548f8
--- /dev/null
+++ b/docs/README
@@ -0,0 +1,17 @@
+[July 5th 2005]
+
+The 'docs' directory contain various text files that should help you
+understand the most importants classes in MediaWiki.
+
+API documentation is sometime generated and uploaded at:
+ http://svn.wikimedia.org/doc/
+
+You can get a fresh version using 'make doc' or mwdocgen.php
+in the ../maintenance/ directory.
+
+
+
+For end user / administrators, most of the documentation
+is located online at:
+ http://meta.wikimedia.org/wiki/Help:Help
+
diff --git a/docs/database.txt b/docs/database.txt
new file mode 100644
index 000000000000..25dce8b7b893
--- /dev/null
+++ b/docs/database.txt
@@ -0,0 +1,179 @@
+Some information about database access in MediaWiki.
+By Tim Starling, January 2006.
+
+------------------------------------------------------------------------
+ Database layout
+------------------------------------------------------------------------
+
+For information about the MediaWiki database layout, such as a
+description of the tables and their contents, please see:
+ http://meta.wikimedia.org/wiki/Help:Database_layout
+ http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/maintenance/tables.sql?view=markup
+
+
+------------------------------------------------------------------------
+ API
+------------------------------------------------------------------------
+
+To make a read query, something like this usually suffices:
+
+$dbr =& wfGetDB( DB_SLAVE );
+$res = $dbr->select( /* ...see docs... */ );
+while ( $row = $dbr->fetchObject( $res ) ) {
+ ...
+}
+$dbr->freeResult( $res );
+
+Note the assignment operator in the while condition.
+
+For a write query, use something like:
+
+$dbw =& wfGetDB( DB_MASTER );
+$dbw->insert( /* ...see docs... */ );
+
+We use the convention $dbr for read and $dbw for write to help you keep
+track of whether the database object is a slave (read-only) or a master
+(read/write). If you write to a slave, the world will explode. Or to be
+precise, a subsequent write query which succeeded on the master may fail
+when replicated to the slave due to a unique key collision. Replication
+on the slave will stop and it may take hours to repair the database and
+get it back online. Setting read_only in my.cnf on the slave will avoid
+this scenario, but given the dire consequences, we prefer to have as
+many checks as possible.
+
+We provide a query() function for raw SQL, but the wrapper functions
+like select() and insert() are usually more convenient. They take care
+of things like table prefixes and escaping for you. If you really need
+to make your own SQL, please read the documentation for tableName() and
+addQuotes(). You will need both of them.
+
+
+------------------------------------------------------------------------
+ Basic query optimisation
+------------------------------------------------------------------------
+
+MediaWiki developers who need to write DB queries should have some
+understanding of databases and the performance issues associated with
+them. Patches containing unacceptably slow features will not be
+accepted. Unindexed queries are generally not welcome in MediaWiki,
+except in special pages derived from QueryPage. It's a common pitfall
+for new developers to submit code containing SQL queries which examine
+huge numbers of rows. Remember that COUNT(*) is O(N), counting rows in a
+table is like counting beans in a bucket.
+
+
+------------------------------------------------------------------------
+ Replication
+------------------------------------------------------------------------
+
+The largest installation of MediaWiki, Wikimedia, uses a large set of
+slave MySQL servers replicating writes made to a master MySQL server. It
+is important to understand the issues associated with this setup if you
+want to write code destined for Wikipedia.
+
+It's often the case that the best algorithm to use for a given task
+depends on whether or not replication is in use. Due to our unabashed
+Wikipedia-centrism, we often just use the replication-friendly version,
+but if you like, you can use $wgLoadBalancer->getServerCount() > 1 to
+check to see if replication is in use.
+
+=== Lag ===
+
+Lag primarily occurs when large write queries are sent to the master.
+Writes on the master are executed in parallel, but they are executed in
+serial when they are replicated to the slaves. The master writes the
+query to the binlog when the transaction is committed. The slaves poll
+the binlog and start executing the query as soon as it appears. They can
+service reads while they are performing a write query, but will not read
+anything more from the binlog and thus will perform no more writes. This
+means that if the write query runs for a long time, the slaves will lag
+behind the master for the time it takes for the write query to complete.
+
+Lag can be exacerbated by high read load. MediaWiki's load balancer will
+stop sending reads to a slave when it is lagged by more than 30 seconds.
+If the load ratios are set incorrectly, or if there is too much load
+generally, this may lead to a slave permanently hovering around 30
+seconds lag.
+
+If all slaves are lagged by more than 30 seconds, MediaWiki will stop
+writing to the database. All edits and other write operations will be
+refused, with an error returned to the user. This gives the slaves a
+chance to catch up. Before we had this mechanism, the slaves would
+regularly lag by several minutes, making review of recent edits
+difficult.
+
+In addition to this, MediaWiki attempts to ensure that the user sees
+events occuring on the wiki in chronological order. A few seconds of lag
+can be tolerated, as long as the user sees a consistent picture from
+subsequent requests. This is done by saving the master binlog position
+in the session, and then at the start of each request, waiting for the
+slave to catch up to that position before doing any reads from it. If
+this wait times out, reads are allowed anyway, but the request is
+considered to be in "lagged slave mode". Lagged slave mode can be
+checked by calling $wgLoadBalancer->getLaggedSlaveMode(). The only
+practical consequence at present is a warning displayed in the page
+footer.
+
+=== Lag avoidance ===
+
+To avoid excessive lag, queries which write large numbers of rows should
+be split up, generally to write one row at a time. Multi-row INSERT ...
+SELECT queries are the worst offenders should be avoided altogether.
+Instead do the select first and then the insert.
+
+=== Working with lag ===
+
+Despite our best efforts, it's not practical to guarantee a low-lag
+environment. Lag will usually be less than one second, but may
+occasionally be up to 30 seconds. For scalability, it's very important
+to keep load on the master low, so simply sending all your queries to
+the master is not the answer. So when you have a genuine need for
+up-to-date data, the following approach is advised:
+
+1) Do a quick query to the master for a sequence number or timestamp 2)
+Run the full query on the slave and check if it matches the data you got
+from the master 3) If it doesn't, run the full query on the master
+
+To avoid swamping the master every time the slaves lag, use of this
+approach should be kept to a minimum. In most cases you should just read
+from the slave and let the user deal with the delay.
+
+
+------------------------------------------------------------------------
+ Lock contention
+------------------------------------------------------------------------
+
+Due to the high write rate on Wikipedia (and some other wikis),
+MediaWiki developers need to be very careful to structure their writes
+to avoid long-lasting locks. By default, MediaWiki opens a transaction
+at the first query, and commits it before the output is sent. Locks will
+be held from the time when the query is done until the commit. So you
+can reduce lock time by doing as much processing as possible before you
+do your write queries. Update operations which do not require database
+access can be delayed until after the commit by adding an object to
+$wgPostCommitUpdateList.
+
+Often this approach is not good enough, and it becomes necessary to
+enclose small groups of queries in their own transaction. Use the
+following syntax:
+
+$dbw =& wfGetDB( DB_MASTER );
+$dbw->immediateBegin();
+/* Do queries */
+$dbw->immediateCommit();
+
+There are functions called begin() and commit() but they don't do what
+you would expect. Don't use them.
+
+Use of locking reads (e.g. the FOR UPDATE clause) is not advised. They
+are poorly implemented in InnoDB and will cause regular deadlock errors.
+It's also surprisingly easy to cripple the wiki with lock contention. If
+you must use them, define a new flag for $wgAntiLockFlags which allows
+them to be turned off, because we'll almost certainly need to do so on
+the Wikimedia cluster.
+
+Instead of locking reads, combine your existence checks into your write
+queries, by using an appropriate condition in the WHERE clause of an
+UPDATE, or by using unique indexes in combination with INSERT IGNORE.
+Then use the affected row count to see if the query succeeded.
+
diff --git a/docs/deferred.txt b/docs/deferred.txt
new file mode 100644
index 000000000000..445eb0e485b2
--- /dev/null
+++ b/docs/deferred.txt
@@ -0,0 +1,19 @@
+
+deferred.txt
+
+A few of the database updates required by various functions here
+can be deferred until after the result page is displayed to the
+user. For example, updating the view counts, updating the
+linked-to tables after a save, etc. PHP does not yet have any
+way to tell the server to actually return and disconnect while
+still running these updates (as a Java servelet could), but it
+might have such a feature in the future.
+
+We handle these by creating a deferred-update object (in a real
+O-O language these would be classes that implement an interface)
+and putting those objects on a global list, then executing the
+whole list after the page is displayed. We don't do anything
+smart like collating updates to the same table or such because
+the list is almost always going to have just one item on it, if
+that, so it's not worth the trouble.
+
diff --git a/docs/design.txt b/docs/design.txt
new file mode 100644
index 000000000000..5fff9fd0ff6a
--- /dev/null
+++ b/docs/design.txt
@@ -0,0 +1,128 @@
+This is a brief overview of the new design.
+
+Primary source files/objects:
+
+ index.php
+ Main script. It creates the necessary global objects and parses
+ the URL to determine what to do, which it then generally passes
+ off to somebody else (depending on the action to be taken).
+
+ All of the functions to which it might delegate generally do
+ their job by sending content to the $wgOut object. After returning,
+ the script flushes that out by calling $wgOut->output(). If there
+ are any changes that need to be made to the database that can be
+ deferred until after page display, those happen at the end.
+
+ Note that the order in the includes is touchy; Language uses
+ some global functions, etc. Likewise with the creation of the
+ global variables. Don't move them around without some forethought.
+
+ User
+ Encapsulates the state of the user viewing/using the site.
+ Can be queried for things like the user's settings, name, etc.
+ Handles the details of getting and saving to the "user" table
+ of the database, and dealing with sessions and cookies.
+ More details in USER.TXT.
+
+ OutputPage
+ Encapsulates the entire HTML page that will be sent in
+ response to any server request. It is used by calling its
+ functions to add text, headers, etc., in any order, and then
+ calling output() to send it all. It could be easily changed
+ to send incrementally if that becomes useful, but I prefer
+ the flexibility. This should also do the output encoding.
+ The system allocates a global one in $wgOut. This class
+ also handles converting wikitext format to HTML.
+
+ Title
+ Represents the title of an article, and does all the work
+ of translating among various forms such as plain text, URL,
+ database key, etc. For convenience, and for historical
+ reasons, it also represents a few features of articles that
+ don't involve their text, such as access rights.
+
+ Article
+ Encapsulates access to the "cur" table of the database. The
+ object represents a an article, and maintains state such as
+ text (in Wikitext format), flags, etc.
+
+ Skin
+ Encapsulates a "look and feel" for the wiki. All of the
+ functions that render HTML, and make choices about how to
+ render it, are here, and are called from various other
+ places when needed (most notably, OutputPage::addWikiText()).
+ The StandardSkin object is a complete implementation, and is
+ meant to be subclassed with other skins that may override
+ some of its functions. The User object contains a reference
+ to a skin (according to that user's preference), and so
+ rather than having a global skin object we just rely on the
+ global User and get the skin with $wgUser->getSkin().
+
+ Language
+ Represents the language used for incidental text, and also
+ has some character encoding functions and other locale stuff.
+ A global one is allocated in $wgLang.
+
+ LinkCache
+ Keeps information on existence of articles. See LINKCACHE.TXT.
+
+Naming/coding conventions:
+
+ These are meant to be descriptive, not dictatorial; I won't
+ presume to tell you how to program, I'm just describing the
+ methods I chose to use for myself. If you do choose to
+ follow these guidelines, it will probably be easier for you
+ to collaborate with others on the project, but if you want
+ to contribute without bothering, by all means do so (and don't
+ be surprised if I reformat your code).
+
+ - I have the code indented with tabs to save file size and
+ so that users can set their tab stops to any depth they like.
+ I use 4-space tab stops, which work well. I also use K&R brace
+ matching style. I know that's a religious issue for some,
+ so if you want to use a style that puts opening braces on the
+ next line, that's OK too, but please don't use a style where
+ closing braces don't align with either the opening brace on
+ its own line or the statement that opened the block--that's
+ confusing as hell.
+
+ - PHP doesn't have "private" member variables of functions,
+ so I've used the comment "/* private */" in some places to
+ indicate my intent. Don't access things marked that way
+ from outside the class def--use the accessor functions (or
+ make your own if you need them). Yes, even some globals
+ are marked private, because PHP is broken and doesn't
+ allow static class variables.
+
+ - Member variables are generally "mXxx" to distinguish them.
+ This should make it easier to spot errors of forgetting the
+ required "$this->", which PHP will happily accept by creating
+ a new local variable rather than complaining.
+
+ - Globals are particularly evil in PHP; it sets a lot of them
+ automatically from cookies, query strings, and such, leading to
+ namespace conflicts; when a variable name is used in a function,
+ it is silently declared as a new local masking the global, so
+ you'll get weird error because you forgot the global declaration;
+ lack of static class member variables means you have to use
+ globals for them, etc. Evil, evil.
+
+ I think I've managed to pare down the number of globals we use
+ to a scant few dozen or so, and I've prefixed them all with "wg"
+ so you can spot errors better (odds are, if you see a "wg"
+ variable being used in a function that doesn't declare it global,
+ that's probably an error).
+
+ Other conventions: Top-level functions are wfFuncname(), names
+ of session variables are wsName, cookies wcName, and form field
+ values wpName ("p" for "POST").
+
+ - Be kind to your release manager and don't use CVS keywords (Id,
+ Revision, etc.) to mark file versions. They make merging code
+ between different branches a pain for CVS, and are kind of sketchy
+ for versions after that. (Yes, you can use the '-kk' flag so that
+ merges ignore keywords, but that messes up binary files. See
+ https://www.cvshome.org/docs/manual/cvs-1.11.18/cvs_5.html#SEC64).
+
+
+
diff --git a/docs/export-0.1.xsd b/docs/export-0.1.xsd
new file mode 100644
index 000000000000..0b3eb1791439
--- /dev/null
+++ b/docs/export-0.1.xsd
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ This is an XML Schema description of the format
+ output by MediaWiki's Special:Export system.
+
+ The canonical URL to the schema document is:
+ http://www.mediawiki.org/xml/export-0.1.xsd
+
+ Use the namespace:
+ http://www.mediawiki.org/xml/export-0.1/
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:mw="http://www.mediawiki.org/xml/export-0.1/"
+ targetNamespace="http://www.mediawiki.org/xml/export-0.1/"
+ elementFormDefault="qualified">
+
+ <annotation>
+ <documentation xml:lang="en">
+ MediaWiki's page export format
+ </documentation>
+ </annotation>
+
+ <!-- Need this to reference xml:lang -->
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ <!-- Our root element -->
+ <element name="mediawiki" type="mw:MediaWikiType"/>
+
+ <complexType name="MediaWikiType">
+ <sequence>
+ <element name="page" type="mw:PageType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="version" type="string" use="required"/>
+ <attribute ref="xml:lang" use="required"/>
+ </complexType>
+
+ <complexType name="PageType">
+ <sequence>
+ <!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
+ <element name="title" type="string"/>
+
+ <!-- optional page ID number -->
+ <element name="id" type="positiveInteger" minOccurs="0"/>
+
+ <!-- comma-separated list of string tokens, if present -->
+ <element name="restrictions" type="string" minOccurs="0"/>
+
+ <!-- Zero or more sets of revision data -->
+ <element name="revision" type="mw:RevisionType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="RevisionType">
+ <sequence>
+ <element name="id" type="positiveInteger" minOccurs="0"/>
+ <element name="timestamp" type="dateTime"/>
+ <element name="contributor" type="mw:ContributorType"/>
+ <element name="minor" minOccurs="0" />
+ <element name="comment" type="string" minOccurs="0"/>
+ <element name="text" type="string"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="ContributorType">
+ <sequence>
+ <element name="username" type="string" minOccurs="0"/>
+ <element name="id" type="positiveInteger" minOccurs="0" />
+
+ <element name="ip" type="string" minOccurs="0"/>
+ </sequence>
+ </complexType>
+
+</schema>
diff --git a/docs/export-0.2.xsd b/docs/export-0.2.xsd
new file mode 100644
index 000000000000..8acbf543b984
--- /dev/null
+++ b/docs/export-0.2.xsd
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ This is an XML Schema description of the format
+ output by MediaWiki's Special:Export system.
+
+ Version 0.2 adds optional basic file upload info support,
+ which is used by our OAI export/import submodule.
+
+ The canonical URL to the schema document is:
+ http://www.mediawiki.org/xml/export-0.2.xsd
+
+ Use the namespace:
+ http://www.mediawiki.org/xml/export-0.2/
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:mw="http://www.mediawiki.org/xml/export-0.2/"
+ targetNamespace="http://www.mediawiki.org/xml/export-0.2/"
+ elementFormDefault="qualified">
+
+ <annotation>
+ <documentation xml:lang="en">
+ MediaWiki's page export format
+ </documentation>
+ </annotation>
+
+ <!-- Need this to reference xml:lang -->
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ <!-- Our root element -->
+ <element name="mediawiki" type="mw:MediaWikiType"/>
+
+ <complexType name="MediaWikiType">
+ <sequence>
+ <element name="page" type="mw:PageType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="version" type="string" use="required"/>
+ <attribute ref="xml:lang" use="required"/>
+ </complexType>
+
+ <complexType name="PageType">
+ <sequence>
+ <!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
+ <element name="title" type="string"/>
+
+ <!-- optional page ID number -->
+ <element name="id" type="positiveInteger" minOccurs="0"/>
+
+ <!-- comma-separated list of string tokens, if present -->
+ <element name="restrictions" type="string" minOccurs="0"/>
+
+ <!-- Zero or more sets of revision or upload data -->
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element name="revision" type="mw:RevisionType" />
+ <element name="upload" type="mw:UploadType" />
+ </choice>
+ </sequence>
+ </complexType>
+
+ <complexType name="RevisionType">
+ <sequence>
+ <element name="id" type="positiveInteger" minOccurs="0"/>
+ <element name="timestamp" type="dateTime"/>
+ <element name="contributor" type="mw:ContributorType"/>
+ <element name="minor" minOccurs="0" />
+ <element name="comment" type="string" minOccurs="0"/>
+ <element name="text" type="string"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="ContributorType">
+ <sequence>
+ <element name="username" type="string" minOccurs="0"/>
+ <element name="id" type="positiveInteger" minOccurs="0" />
+
+ <element name="ip" type="string" minOccurs="0"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="UploadType">
+ <sequence>
+ <!-- Revision-style data... -->
+ <element name="timestamp" type="dateTime"/>
+ <element name="contributor" type="mw:ContributorType"/>
+ <element name="comment" type="string" minOccurs="0"/>
+
+ <!-- Filename. (Using underscores, not spaces. No 'Image:' namespace marker.) -->
+ <element name="filename" type="string"/>
+
+ <!-- URI at which this resource can be obtained -->
+ <element name="src" type="anyURI"/>
+
+ <element name="size" type="positiveInteger" />
+
+ <!-- TODO: add other metadata fields -->
+ </sequence>
+ </complexType>
+
+</schema>
diff --git a/docs/export-0.3.xsd b/docs/export-0.3.xsd
new file mode 100644
index 000000000000..1e0b7c88f2ef
--- /dev/null
+++ b/docs/export-0.3.xsd
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ This is an XML Schema description of the format
+ output by MediaWiki's Special:Export system.
+
+ Version 0.2 adds optional basic file upload info support,
+ which is used by our OAI export/import submodule.
+
+ Version 0.3 adds some site configuration information such
+ as a list of defined namespaces.
+
+ The canonical URL to the schema document is:
+ http://www.mediawiki.org/xml/export-0.3.xsd
+
+ Use the namespace:
+ http://www.mediawiki.org/xml/export-0.3/
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:mw="http://www.mediawiki.org/xml/export-0.3/"
+ targetNamespace="http://www.mediawiki.org/xml/export-0.3/"
+ elementFormDefault="qualified">
+
+ <annotation>
+ <documentation xml:lang="en">
+ MediaWiki's page export format
+ </documentation>
+ </annotation>
+
+ <!-- Need this to reference xml:lang -->
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ <!-- Our root element -->
+ <element name="mediawiki" type="mw:MediaWikiType"/>
+
+ <complexType name="MediaWikiType">
+ <sequence>
+ <element name="siteinfo" type="mw:SiteInfoType"
+ minOccurs="0" maxOccurs="1"/>
+ <element name="page" type="mw:PageType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="version" type="string" use="required"/>
+ <attribute ref="xml:lang" use="required"/>
+ </complexType>
+
+ <complexType name="SiteInfoType">
+ <sequence>
+ <element name="sitename" type="string" minOccurs="0" />
+ <element name="base" type="anyURI" minOccurs="0" />
+ <element name="generator" type="string" minOccurs="0" />
+ <element name="case" type="mw:CaseType" minOccurs="0" />
+ <element name="namespaces" type="mw:NamespacesType" minOccurs="0" />
+ </sequence>
+ </complexType>
+
+ <simpleType name="CaseType">
+ <restriction base="NMTOKEN">
+ <!-- Cannot have two titles differing only by case of first letter. -->
+ <!-- Default behavior through 1.5, $wgCapitalLinks = true -->
+ <enumeration value="first-letter" />
+
+ <!-- Complete title is case-sensitive -->
+ <!-- Behavior when $wgCapitalLinks = false -->
+ <enumeration value="case-sensitive" />
+
+ <!-- Cannot have two titles differing only by case. -->
+ <!-- Not yet implemented as of MediaWiki 1.5 -->
+ <enumeration value="case-insensitive" />
+ </restriction>
+ </simpleType>
+
+ <complexType name="NamespacesType">
+ <sequence>
+ <element name="namespace" type="mw:NamespaceType"
+ minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ </complexType>
+
+ <complexType name="NamespaceType">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="key" type="integer" />
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="PageType">
+ <sequence>
+ <!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
+ <element name="title" type="string"/>
+
+ <!-- optional page ID number -->
+ <element name="id" type="positiveInteger" minOccurs="0"/>
+
+ <!-- comma-separated list of string tokens, if present -->
+ <element name="restrictions" type="string" minOccurs="0"/>
+
+ <!-- Zero or more sets of revision or upload data -->
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <element name="revision" type="mw:RevisionType" />
+ <element name="upload" type="mw:UploadType" />
+ </choice>
+ </sequence>
+ </complexType>
+
+ <complexType name="RevisionType">
+ <sequence>
+ <element name="id" type="positiveInteger" minOccurs="0"/>
+ <element name="timestamp" type="dateTime"/>
+ <element name="contributor" type="mw:ContributorType"/>
+ <element name="minor" minOccurs="0" />
+ <element name="comment" type="string" minOccurs="0"/>
+ <element name="text" type="mw:TextType" />
+ </sequence>
+ </complexType>
+
+ <complexType name="TextType">
+ <simpleContent>
+ <extension base="string">
+ <attribute ref="xml:space" use="optional" default="preserve" />
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="ContributorType">
+ <sequence>
+ <element name="username" type="string" minOccurs="0"/>
+ <element name="id" type="positiveInteger" minOccurs="0" />
+
+ <element name="ip" type="string" minOccurs="0"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="UploadType">
+ <sequence>
+ <!-- Revision-style data... -->
+ <element name="timestamp" type="dateTime"/>
+ <element name="contributor" type="mw:ContributorType"/>
+ <element name="comment" type="string" minOccurs="0"/>
+
+ <!-- Filename. (Using underscores, not spaces. No 'Image:' namespace marker.) -->
+ <element name="filename" type="string"/>
+
+ <!-- URI at which this resource can be obtained -->
+ <element name="src" type="anyURI"/>
+
+ <element name="size" type="positiveInteger" />
+
+ <!-- TODO: add other metadata fields -->
+ </sequence>
+ </complexType>
+
+</schema>
diff --git a/docs/export-demo.xml b/docs/export-demo.xml
new file mode 100644
index 000000000000..1b4bd7cf73cb
--- /dev/null
+++ b/docs/export-demo.xml
@@ -0,0 +1,115 @@
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en">
+
+<!-- Optional global configuration info -->
+<siteinfo>
+ <!-- Site name, as set in $wgSitename -->
+ <sitename>DemoWiki</sitename>
+
+ <!-- Forgot where you got this set? -->
+ <base>http://example.com/wiki/Main_Page</base>
+
+ <!-- Source software version -->
+ <generator>MediaWiki 1.5.0</generator>
+
+ <!-- Title case sensitivity options of the wiki this data came from -->
+ <!-- May be 'first-letter', 'case-sensitive', or 'case-insensitive' -->
+ <case>first-letter</case>
+
+ <!-- Defined namespace keys on the source wiki. -->
+ <!-- Titles can be substring-split to obtain the symbolic numeric key -->
+ <namespaces>
+ <namespace key="-2">Media</namespace>
+ <namespace key="-1">Special</namespace>
+ <namespace key="0"></namespace>
+ <namespace key="1">Talk</namespace>
+ <namespace key="2">User</namespace>
+ <namespace key="3">User talk</namespace>
+ <namespace key="4">DemoWiki</namespace>
+ <namespace key="5">DemoWIki talk</namespace>
+ <namespace key="6">Image</namespace>
+ <namespace key="7">Image talk</namespace>
+ <namespace key="8">MediaWiki</namespace>
+ <namespace key="9">MediaWiki talk</namespace>
+ <namespace key="10">Template</namespace>
+ <namespace key="11">Template talk</namespace>
+ <namespace key="12">Help</namespace>
+ <namespace key="13">Help talk</namespace>
+ <namespace key="14">Category</namespace>
+ <namespace key="15">Category talk</namespace>
+ </namespaces>
+</siteinfo>
+
+<!-- The rest of the data will be a series of page records -->
+<page>
+ <!-- Titles are listed here in text form, with namespace prefix -->
+ <!-- if any, and spaces rather than the underscores used in URLs. -->
+ <title>Page title</title>
+
+ <!-- The page's immutable page_id number in the source database. -->
+ <!-- Page ID numbers are kept across page moves, but may change -->
+ <!-- if a page is deleted and recreated. -->
+ <id>1</id>
+
+ <!-- If restricted, the ACL is listed here raw. -->
+ <restrictions>edit=sysop:move=sysop</restrictions>
+
+ <!-- With a series of revision records... -->
+
+ <!-- Remember this is XML; if you must use a regex-based extractor -->
+ <!-- in place of a standard XML parser, be very careful. -->
+ <!-- * Don't forget to decode character entities! -->
+ <!-- * If using a 'loose' XML parser, ensure that whitespace is -->
+ <!-- preserved in the <text> elements. -->
+ <revision>
+ <!-- Unique revision ID number (rev_id) in the source database. -->
+ <!-- This number uniquely identifies the revision on that wiki. -->
+ <id>100</id>
+
+ <timestamp>2001-01-15T13:15:00Z</timestamp>
+ <contributor><username>Foobar</username><id>42</id></contributor>
+ <minor />
+ <comment>I have just one thing to say!</comment>
+ <text xml:space="preserve">A bunch of [[text]] here.</text>
+ </revision>
+
+ <revision>
+ <timestamp>2001-01-15T13:10:27Z</timestamp>
+ <contributor><ip>10.0.0.2</ip></contributor>
+ <comment>new!</comment>
+ <text xml:space="preserve">An earlier [[revision]].</text>
+ </revision>
+</page>
+
+<page>
+ <title>Talk:Page title</title>
+ <id>2</id>
+ <revision>
+ <id>101</id>
+ <timestamp>2001-01-15T14:03:00Z</timestamp>
+ <contributor><ip>10.0.0.2</ip></contributor>
+ <comment>hey</comment>
+ <text xml:space="preserve">WHYD YOU LOCK PAGE??!!! i was editing that jerk</text>
+ </revision>
+</page>
+
+<page>
+ <title>Image:Some image.jpg</title>
+ <id>3</id>
+ <revision>
+ <id>102</id>
+ <timestamp>2001-01-15T20:34:12Z</timestamp>
+ <contributor><username>Foobar</username><id>42</id></contributor>
+ <comment>My awesomeest image!</comment>
+ <text xml:space="preserve">This is an awesome little imgae. I lurves it. {{PD}}</text>
+ </revision>
+ <upload>
+ <timestamp>2001-01-15T20:34:12Z</timestamp>
+ <contributor><username>Foobar</username><id>42</id></contributor>
+ <comment>My awesomeest image!</comment>
+ <filename>Some_image.jpg</filename>
+ <src>http://upload.wikimedia.org/commons/2/22/Some_image.jpg</src>
+ <size>12345</size>
+ </upload>
+</page>
+
+</mediawiki>
diff --git a/docs/globals.txt b/docs/globals.txt
new file mode 100644
index 000000000000..ecc5ab33fdb1
--- /dev/null
+++ b/docs/globals.txt
@@ -0,0 +1,74 @@
+globals.txt
+
+Globals are evil. The original MediaWiki code relied on
+globals for processing context far too often. MediaWiki
+development since then has been a story of slowly moving
+context out of global variables and into objects. Storing
+processing context in object member variables allows those
+objects to be reused in a much more flexible way. Consider
+the elegance of:
+
+ # Generate the article HTML as if viewed by a web request
+ $article = new Article( Title::newFromText( $t ) );
+ $article->view();
+
+versus
+
+ # Save current globals
+ $oldTitle = $wgTitle;
+ $oldArticle = $wgArticle;
+
+ # Generate the HTML
+ $wgTitle = Title::newFromText( $t );
+ $wgArticle = new Article;
+ $wgArticle->view();
+
+ # Restore globals
+ $wgTitle = $oldTitle
+ $wgArticle = $oldArticle
+
+Some of the current MediaWiki developers have an idle
+fantasy that some day, globals will be eliminated from
+MediaWiki entirely, replaced by an application object which
+would be passed to constructors. Whether that would be an
+efficient, convenient solution remains to be seen, but
+certainly PHP 5 makes such object-oriented programming
+models easier than they were in previous versions.
+
+For the time being though, MediaWiki programmers will have
+to work in an environment with some global context. At the
+time of writing, 418 globals were initialised on startup by
+MediaWiki. 304 of these were configuration settings, which
+are documented in DefaultSettings.php. There is no
+comprehensive documentation for the remaining 114 globals,
+however some of the most important ones are listed below.
+They are typically initialised either in index.php or in
+Setup.php.
+
+
+$wgOut
+ OutputPage object for HTTP response.
+
+$wgUser
+ User object for the user associated with the current
+ request.
+
+$wgTitle
+ Title object created from the request URL.
+
+$wgLang
+ Language object selected by user preferences
+
+$wgContLang
+ Language object associated with the wiki being
+ viewed.
+
+$wgArticle
+ Article object corresponding to $wgTitle.
+
+$wgParser
+ Parser object. Parser extensions register their
+ hooks here.
+
+$wgLoadBalancer
+ A LoadBalancer object, manages database connections.
diff --git a/docs/hooks.txt b/docs/hooks.txt
new file mode 100644
index 000000000000..d5a176603599
--- /dev/null
+++ b/docs/hooks.txt
@@ -0,0 +1,533 @@
+hooks.txt
+
+This document describes how event hooks work in MediaWiki; how to add
+hooks for an event; and how to run hooks for an event.
+
+==Glossary==
+
+event
+ Something that happens with the wiki. For example: a user logs
+ in. A wiki page is saved. A wiki page is deleted. Often there are
+ two events associated with a single action: one before the code
+ is run to make the event happen, and one after. Each event has a
+ name, preferably in CamelCase. For example, 'UserLogin',
+ 'ArticleSave', 'ArticleSaveComplete', 'ArticleDelete'.
+
+hook
+ A clump of code and data that should be run when an event
+ happens. This can be either a function and a chunk of data, or an
+ object and a method.
+
+hook function
+ The function part of a hook.
+
+==Rationale==
+
+Hooks allow us to decouple optionally-run code from code that is run
+for everyone. It allows MediaWiki hackers, third-party developers and
+local administrators to define code that will be run at certain points
+in the mainline code, and to modify the data run by that mainline
+code. Hooks can keep mainline code simple, and make it easier to
+write extensions. Hooks are a principled alternative to local patches.
+
+Consider, for example, two options in MediaWiki. One reverses the
+order of a title before displaying the article; the other converts the
+title to all uppercase letters. Currently, in MediaWiki code, we
+would handle this as follows (note: not real code, here):
+
+ function showAnArticle($article) {
+ global $wgReverseTitle, $wgCapitalizeTitle;
+
+ if ($wgReverseTitle) {
+ wfReverseTitle($article);
+ }
+
+ if ($wgCapitalizeTitle) {
+ wfCapitalizeTitle($article);
+ }
+
+ # code to actually show the article goes here
+ }
+
+An extension writer, or a local admin, will often add custom code to
+the function -- with or without a global variable. For example,
+someone wanting email notification when an article is shown may add:
+
+ function showAnArticle($article) {
+ global $wgReverseTitle, $wgCapitalizeTitle;
+
+ if ($wgReverseTitle) {
+ wfReverseTitle($article);
+ }
+
+ if ($wgCapitalizeTitle) {
+ wfCapitalizeTitle($article);
+ }
+
+ # code to actually show the article goes here
+
+ if ($wgNotifyArticle) {
+ wfNotifyArticleShow($article));
+ }
+ }
+
+Using a hook-running strategy, we can avoid having all this
+option-specific stuff in our mainline code. Using hooks, the function
+becomes:
+
+ function showAnArticle($article) {
+
+ if (wfRunHooks('ArticleShow', array(&$article))) {
+
+ # code to actually show the article goes here
+
+ wfRunHooks('ArticleShowComplete', array(&$article));
+ }
+ }
+
+We've cleaned up the code here by removing clumps of weird,
+infrequently used code and moving them off somewhere else. It's much
+easier for someone working with this code to see what's _really_ going
+on, and make changes or fix bugs.
+
+In addition, we can take all the code that deals with the little-used
+title-reversing options (say) and put it in one place. Instead of
+having little title-reversing if-blocks spread all over the codebase
+in showAnArticle, deleteAnArticle, exportArticle, etc., we can
+concentrate it all in an extension file:
+
+ function reverseArticleTitle($article) {
+ # ...
+ }
+
+ function reverseForExport($article) {
+ # ...
+ }
+
+The setup function for the extension just has to add its hook
+functions to the appropriate events:
+
+ setupTitleReversingExtension() {
+ global $wgHooks;
+
+ $wgHooks['ArticleShow'][] = 'reverseArticleTitle';
+ $wgHooks['ArticleDelete'][] = 'reverseArticleTitle';
+ $wgHooks['ArticleExport'][] = 'reverseForExport';
+ }
+
+Having all this code related to the title-reversion option in one
+place means that it's easier to read and understand; you don't have to
+do a grep-find to see where the $wgReverseTitle variable is used, say.
+
+If the code is well enough isolated, it can even be excluded when not
+used -- making for some slight savings in memory and load-up
+performance at runtime. Admins who want to have all the reversed
+titles can add:
+
+ require_once('extensions/ReverseTitle.php');
+
+...to their LocalSettings.php file; those of us who don't want or need
+it can just leave it out.
+
+The extensions don't even have to be shipped with MediaWiki; they
+could be provided by a third-party developer or written by the admin
+him/herself.
+
+==Writing hooks==
+
+A hook is a chunk of code run at some particular event. It consists of:
+
+ * a function with some optional accompanying data, or
+ * an object with a method and some optional accompanying data.
+
+Hooks are registered by adding them to the global $wgHooks array for a
+given event. All the following are valid ways to define hooks:
+
+ $wgHooks['EventName'][] = 'someFunction'; # function, no data
+ $wgHooks['EventName'][] = array('someFunction', $someData);
+ $wgHooks['EventName'][] = array('someFunction'); # weird, but OK
+
+ $wgHooks['EventName'][] = $object; # object only
+ $wgHooks['EventName'][] = array($object, 'someMethod');
+ $wgHooks['EventName'][] = array($object, 'someMethod', $someData);
+ $wgHooks['EventName'][] = array($object); # weird but OK
+
+When an event occurs, the function (or object method) will be called
+with the optional data provided as well as event-specific parameters.
+The above examples would result in the following code being executed
+when 'EventName' happened:
+
+ # function, no data
+ someFunction($param1, $param2)
+ # function with data
+ someFunction($someData, $param1, $param2)
+
+ # object only
+ $object->onEventName($param1, $param2)
+ # object with method
+ $object->someMethod($param1, $param2)
+ # object with method and data
+ $object->someMethod($someData, $param1, $param2)
+
+Note that when an object is the hook, and there's no specified method,
+the default method called is 'onEventName'. For different events this
+would be different: 'onArticleSave', 'onUserLogin', etc.
+
+The extra data is useful if we want to use the same function or object
+for different purposes. For example:
+
+ $wgHooks['ArticleSaveComplete'][] = array('ircNotify', 'TimStarling');
+ $wgHooks['ArticleSaveComplete'][] = array('ircNotify', 'brion');
+
+This code would result in ircNotify being run twice when an article is
+saved: once for 'TimStarling', and once for 'brion'.
+
+Hooks can return three possible values:
+
+ * true: the hook has operated successfully
+ * "some string": an error occurred; processing should
+ stop and the error should be shown to the user
+ * false: the hook has successfully done the work
+ necessary and the calling function should skip
+
+The last result would be for cases where the hook function replaces
+the main functionality. For example, if you wanted to authenticate
+users to a custom system (LDAP, another PHP program, whatever), you
+could do:
+
+ $wgHooks['UserLogin'][] = array('ldapLogin', $ldapServer);
+
+ function ldapLogin($username, $password) {
+ # log user into LDAP
+ return false;
+ }
+
+Returning false makes less sense for events where the action is
+complete, and will normally be ignored.
+
+==Using hooks==
+
+A calling function or method uses the wfRunHooks() function to run
+the hooks related to a particular event, like so:
+
+ class Article {
+ # ...
+ function protect() {
+ global $wgUser;
+ if (wfRunHooks('ArticleProtect', array(&$this, &$wgUser))) {
+ # protect the article
+ wfRunHooks('ArticleProtectComplete', array(&$this, &$wgUser));
+ }
+ }
+
+wfRunHooks() returns true if the calling function should continue
+processing (the hooks ran OK, or there are no hooks to run), or false
+if it shouldn't (an error occurred, or one of the hooks handled the
+action already). Checking the return value matters more for "before"
+hooks than for "complete" hooks.
+
+Note that hook parameters are passed in an array; this is a necessary
+inconvenience to make it possible to pass reference values (that can
+be changed) into the hook code. Also note that earlier versions of
+wfRunHooks took a variable number of arguments; the array() calling
+protocol came about after MediaWiki 1.4rc1.
+
+==Events and parameters==
+
+This is a list of known events and parameters; please add to it if
+you're going to add events to the MediaWiki code.
+
+'AbortNewAccount': Return false to cancel account creation.
+$user: the User object about to be created (read-only, incomplete)
+$message: out parameter: error message to display on abort
+
+'AddNewAccount': after a user account is created
+$user: the User object that was created. (Parameter added in 1.7)
+
+'ArticleDelete': before an article is deleted
+$article: the article (object) being deleted
+$user: the user (object) deleting the article
+$reason: the reason (string) the article is being deleted
+
+'ArticleDeleteComplete': after an article is deleted
+$article: the article that was deleted
+$user: the user that deleted the article
+$reason: the reason the article was deleted
+
+'ArticleProtect': before an article is protected
+$article: the article being protected
+$user: the user doing the protection
+$protect: boolean whether this is a protect or an unprotect
+$reason: Reason for protect
+$moveonly: boolean whether this is for move only or not
+
+'ArticleProtectComplete': after an article is protected
+$article: the article that was protected
+$user: the user who did the protection
+$protect: boolean whether it was a protect or an unprotect
+$reason: Reason for protect
+$moveonly: boolean whether it was for move only or not
+
+'ArticleSave': before an article is saved
+$article: the article (object) being saved
+$user: the user (object) saving the article
+$text: the new article text
+$summary: the article summary (comment)
+$isminor: minor flag
+$iswatch: watch flag
+$section: section #
+
+'ArticleSaveComplete': after an article is saved
+$article: the article (object) saved
+$user: the user (object) who saved the article
+$text: the new article text
+$summary: the article summary (comment)
+$isminor: minor flag
+$iswatch: watch flag
+$section: section #
+
+'AuthPluginSetup': update or replace authentication plugin object ($wgAuth)
+Gives a chance for an extension to set it programattically to a variable class.
+&$auth: the $wgAuth object, probably a stub
+
+'AutoAuthenticate': called to authenticate users on external/environmental means
+$user: writes user object to this parameter
+
+'BadImage': When checking against the bad image list
+$name: Image name being checked
+&$bad: Whether or not the image is "bad"
+
+Change $bad and return false to override. If an image is "bad", it is not
+rendered inline in wiki pages or galleries in category pages.
+
+'BlockIp': before an IP address or user is blocked
+$block: the Block object about to be saved
+$user: the user _doing_ the block (not the one being blocked)
+
+'BlockIpComplete': after an IP address or user is blocked
+$block: the Block object that was saved
+$user: the user who did the block (not the one being blocked)
+
+'DiffViewHeader': called before diff display
+$diff: DifferenceEngine object that's calling
+$oldRev: Revision object of the "old" revision (may be null/invalid)
+$newRev: Revision object of the "new" revision
+
+'EditPage::attemptSave': called before an article is
+saved, that is before insertNewArticle() is called
+&$editpage_Obj: the current EditPage object
+
+'EditFormPreloadText': Allows population of the edit form when creating new pages
+&$text: Text to preload with
+&$title: Title object representing the page being created
+
+'EditFilter': Perform checks on an edit
+$editor: Edit form (see includes/EditPage.php)
+$text: Contents of the edit box
+$section: Section being edited
+&$error: Error message to return
+
+Return false to halt editing; you'll need to handle error messages, etc. yourself.
+Alternatively, modifying $error and returning true will cause the contents of $error
+to be echoed at the top of the edit form as wikitext. Return true without altering
+$error to allow the edit to proceed.
+
+'EmailConfirmed': When checking that the user's email address is "confirmed"
+$user: User being checked
+$confirmed: Whether or not the email address is confirmed
+This runs before the other checks, such as anonymity and the real check; return
+true to allow those checks to occur, and false if checking is done.
+
+'EmailUser': before sending email from one user to another
+$to: address of receiving user
+$from: address of sending user
+$subject: subject of the mail
+$text: text of the mail
+
+'EmailUserComplete': after sending email from one user to another
+$to: address of receiving user
+$from: address of sending user
+$subject: subject of the mail
+$text: text of the mail
+
+'FetchChangesList': When fetching the ChangesList derivative for a particular user
+&$user: User the list is being fetched for
+&$skin: Skin object to be used with the list
+&$list: List object (defaults to NULL, change it to an object instance and return
+false override the list derivative used)
+
+'GetInternalURL': modify fully-qualified URLs used for squid cache purging
+$title: Title object of page
+$url: string value as output (out parameter, can modify)
+$query: query options passed to Title::getInternalURL()
+
+'GetLocalURL': modify local URLs as output into page links
+$title: Title object of page
+$url: string value as output (out parameter, can modify)
+$query: query options passed to Title::getLocalURL()
+
+'GetFullURL': modify fully-qualified URLs used in redirects/export/offsite data
+$title: Title object of page
+$url: string value as output (out parameter, can modify)
+$query: query options passed to Title::getFullURL()
+
+'LogPageValidTypes': action being logged. DEPRECATED: Use $wgLogTypes
+&$type: array of strings
+
+'LogPageLogName': name of the logging page(s). DEPRECATED: Use $wgLogNames
+&$typeText: array of strings
+
+'LogPageLogHeader': strings used by wfMsg as a header. DEPRECATED: Use $wgLogHeaders
+&$headerText: array of strings
+
+'LogPageActionText': strings used by wfMsg as a header. DEPRECATED: Use $wgLogActions
+&$actionText: array of strings
+
+'MarkPatrolled': before an edit is marked patrolled
+$rcid: ID of the revision to be marked patrolled
+$user: the user (object) marking the revision as patrolled
+$wcOnlySysopsCanPatrol: config setting indicating whether the user
+ needs to be a sysop in order to mark an edit patrolled
+
+'MarkPatrolledComplete': after an edit is marked patrolled
+$rcid: ID of the revision marked as patrolled
+$user: user (object) who marked the edit patrolled
+$wcOnlySysopsCanPatrol: config setting indicating whether the user
+ must be a sysop to patrol the edit
+
+'MathAfterTexvc': after texvc is executed when rendering mathematics
+$mathRenderer: instance of MathRenderer
+$errmsg: error message, in HTML (string). Nonempty indicates failure
+ of rendering the formula
+
+'OutputPageBeforeHTML': a page has been processed by the parser and
+the resulting HTML is about to be displayed.
+$parserOutput: the parserOutput (object) that corresponds to the page
+$text: the text that will be displayed, in HTML (string)
+
+'PageRenderingHash': alter the parser cache option hash key
+ A parser extension which depends on user options should install
+ this hook and append its values to the key.
+$hash: reference to a hash key string which can be modified
+
+'PersonalUrls': Alter the user-specific navigation links (e.g. "my page,
+my talk page, my contributions" etc).
+
+&$personal_urls: Array of link specifiers (see SkinTemplate.php)
+&$title: Title object representing the current page
+
+'PingLimiter': Allows extensions to override the results of User::pingLimiter()
+&$user : User performing the action
+$action : Action being performed
+&$result : Whether or not the action should be prevented
+Change $result and return false to give a definitive answer, otherwise
+the built-in rate limiting checks are used, if enabled.
+
+'PreferencesUserInformationPanel': Add HTML bits to user information list in preferences form
+$form : PreferencesForm object
+&$html : HTML to append to
+
+'SiteNoticeBefore': Before the sitenotice/anonnotice is composed
+&$siteNotice: HTML returned as the sitenotice
+Return true to allow the normal method of notice selection/rendering to work,
+or change the value of $siteNotice and return false to alter it.
+
+'SiteNoticeAfter': After the sitenotice/anonnotice is composed
+&$siteNotice: HTML sitenotice
+Alter the contents of $siteNotice to add to/alter the sitenotice/anonnotice.
+
+'TitleMoveComplete': after moving an article (title)
+$old: old title
+$nt: new title
+$user: user who did the move
+$pageid: database ID of the page that's been moved
+$redirid: database ID of the created redirect
+
+'UnknownAction': An unknown "action" has occured (useful for defining
+ your own actions)
+$action: action name
+$article: article "acted on"
+
+'UnwatchArticle': before a watch is removed from an article
+$user: user watching
+$article: article object to be removed
+
+'UnwatchArticle': after a watch is removed from an article
+$user: user that was watching
+$article: article object removed
+
+'UploadForm:initial': before the upload form is generated
+$form: UploadForm object
+You might set the member-variables $uploadFormTextTop and
+$uploadFormTextAfterSummary to inject text (HTML) either before
+or after the editform.
+
+'UploadForm:BeforeProcessing': at the beginning of processUpload()
+$form: UploadForm object
+Lets you poke at member variables like $mUploadDescription before the
+file is saved.
+
+'UploadVerification': additional chances to reject an uploaded file
+string $saveName: destination file name
+string $tempName: filesystem path to the temporary file for checks
+string &$error: output: HTML error to show if upload canceled by returning false
+
+'UploadComplete': Upon completion of a file upload
+$image: Image object representing the file that was uploaded
+
+'UserCan': To interrupt/advise the "user can do X to Y article" check
+$title: Title object being checked against
+$user : Current user object
+$action: Action being checked
+$result: Pointer to result returned if hook returns false. If null is returned,
+ UserCan checks are continued by internal code
+
+'UserCreateForm': change to manipulate the login form
+$template: SimpleTemplate instance for the form
+
+'UserLoginComplete': after a user has logged in
+$user: the user object that was created on login
+
+'UserLoginForm': change to manipulate the login form
+$template: SimpleTemplate instance for the form
+
+'UserLogout': before a user logs out
+$user: the user object that is about to be logged out
+
+'UserLogoutComplete': after a user has logged out
+$user: the user object _after_ logout (won't have name, ID, etc.)
+
+'UserRights': After a user's group memberships are changed
+$user : User object that was changed
+$add : Array of strings corresponding to groups added
+$remove: Array of strings corresponding to groups removed
+
+'WatchArticle': before a watch is added to an article
+$user: user that will watch
+$article: article object to be watched
+
+'WatchArticleComplete': after a watch is added to an article
+$user: user that watched
+$article: article object watched
+
+'UnwatchArticleComplete': after a watch is removed from an article
+$user: user that watched
+$article: article object that was watched
+
+'CategoryPageView': before viewing a categorypage in CategoryPage::view
+$catpage: CategoryPage instance
+
+'SkinTemplateContentActions': after building the $content_action array right
+ before returning it, see Content_action.php in
+ the extensions/examples/ directory
+ ( http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/examples/ )
+ for a demonstration of how to use this hook.
+$content_actions: The array of content actions
+
+'BeforePageDisplay': Called just before outputting a page (all kinds of,
+ articles, special, history, preview, diff, edit, ...)
+ Can be used to set custom CSS/JS
+$out: OutputPage object
+
+More hooks might be available but undocumented, you can execute
+./maintenance/findhooks.php to find hidden one.
diff --git a/docs/html/README b/docs/html/README
new file mode 100644
index 000000000000..d25b803d2ef4
--- /dev/null
+++ b/docs/html/README
@@ -0,0 +1,4 @@
+This directory is for the auto-generated phpdoc documentation.
+Run 'php mwdocgen.php' in the maintenance subdirectory to build the docs.
+
+Get phpDocumentor from http://phpdoc.org/
diff --git a/docs/language.txt b/docs/language.txt
new file mode 100644
index 000000000000..9d6a0db329d6
--- /dev/null
+++ b/docs/language.txt
@@ -0,0 +1,24 @@
+language.txt
+
+The Language object handles all readable text produced by the
+software. The most used function is getMessage(), usually
+called with the wrapper function wfMsg() which calls that method
+on the global language object. It just returns a piece of text
+given a text key. It is recommended that you use each key only
+once--bits of text in different contexts that happen to be
+identical in English may not be in other languages, so it's
+better to add new keys than to reuse them a lot. Likewise,
+if there is text that gets combined with things like names and
+titles, it is better to put markers like "$1" inside a piece
+of text and use str_replace() than to compose such messages in
+code, because their order may change in other languages too.
+
+While the system is running, there will be one global language
+object, which will be a subtype of Language. The methods in
+these objects will return the native text requested if available,
+otherwise they fall back to sending English text (which is why
+the LanguageEn object has no code at all--it just inherits the
+English defaults of the Language base class).
+
+The names of the namespaces are also contained in the language
+object, though the numbers are fixed.
diff --git a/docs/linkcache.txt b/docs/linkcache.txt
new file mode 100644
index 000000000000..3e9799c31e04
--- /dev/null
+++ b/docs/linkcache.txt
@@ -0,0 +1,18 @@
+linkcache.txt
+
+The LinkCache class maintains a list of article titles and
+the information about whether or not the article exists in
+the database. This is used to mark up links when displaying
+a page. If the same link appears more than once on any page,
+then it only has to be looked up once. In most cases, link
+lookups are done in batches with the LinkBatch class, or the
+equivalent in Parser::replaceLinkHolders(), so the link
+cache is mostly useful for short snippets of parsed text
+(such as the site notice), and for links in the navigation
+areas of the skin.
+
+The link cache was formerly used to track links used in a
+document for the purposes of updating the link tables. This
+application is now deprecated.
+
+
diff --git a/docs/magicword.txt b/docs/magicword.txt
new file mode 100644
index 000000000000..74e49cff0f48
--- /dev/null
+++ b/docs/magicword.txt
@@ -0,0 +1,44 @@
+magicword.txt
+
+Magic Words are some phrases used in the wikitext. They are defined in several arrays:
+* $magicWords (includes/MagicWord.php) includes their internal names ('MAG_XXX').
+* $wgVariableIDs (includes/MagicWord.php) includes their IDs (MAG_XXX, which are constants),
+ after their internal names are used for "define()".
+* Localized arrays (languages/LanguageXX.php) include their different names to be used by the users.
+
+The localized arrays keys are the internal IDs, and the values are an array, whose include their
+case-sensitivity and their alias forms. The first form defined is used by the program, for example,
+when moving a page and its old name should include #REDIRECT.
+
+Adding magic words should be done using several hooks:
+* "MagicWordMagicWords" should be used to add the internal name ('MAG_XXX') to $magicWords.
+* "MagicWordwgVariableIDs" should be used to add the ID (MAG_XXX constant) to $wgVariableIDs.
+* "LanguageGetMagic" should be used to add the different names of the magic word. Use both
+ the localized name and the English name. Get the language code by the parameter $langCode;
+
+For example:
+
+$wgHooks['MagicWordMagicWords'][] = 'wfAddCustomMagicWord';
+$wgHooks['MagicWordwgVariableIDs'][] = 'wfAddCustomMagicWordID';
+$wgHooks['LanguageGetMagic'][] = 'wfAddCustomMagicWordLang';
+
+function wfAddCustomMagicWord( &$magicWords ) {
+ $magicWords[] = 'MAG_CUSTOM';
+ return true;
+}
+
+function wfAddCustomMagicWordID( &$magicWords ) {
+ $magicWords[] = MAG_CUSTOM;
+ return true;
+}
+
+function wfAddCustomMagicWordLang( &$magicWords, $langCode ) {
+ switch ( $langCode ) {
+ case 'es':
+ $magicWords[MAG_CUSTOM] = array( 0, "#aduanero", "#custom" );
+ break;
+ default:
+ $magicWords[MAG_CUSTOM] = array( 0, "#custom" );
+ }
+ return true;
+}
diff --git a/docs/memcached.txt b/docs/memcached.txt
new file mode 100644
index 000000000000..6752e9c81d22
--- /dev/null
+++ b/docs/memcached.txt
@@ -0,0 +1,132 @@
+memcached support for MediaWiki:
+
+From ca August 2003, MediaWiki has optional support for memcached, a
+"high-performance, distributed memory object caching system".
+For general information on it, see: http://www.danga.com/memcached/
+
+Memcached is likely more trouble than a small site will need, but
+for a larger site with heavy load, like Wikipedia, it should help
+lighten the load on the database servers by caching data and objects
+in memory.
+
+== Requirements ==
+
+* PHP must be compiled with --enable-sockets
+
+* libevent: http://www.monkey.org/~provos/libevent/
+ (as of 2003-08-11, 0.7a is current)
+
+* optionally, epoll-rt patch for Linux kernel:
+ http://www.xmailserver.org/linux-patches/nio-improve.html
+
+* memcached: http://www.danga.com/memcached/download.bml
+ (as of this writing, 1.1.9 is current)
+
+Memcached and libevent are under BSD-style licenses.
+
+The server should run on Linux and other Unix-like systems... you
+can run multiple servers on one machine or on multiple machines on
+a network; storage can be distributed across multiple servers, and
+multiple web servers can use the same cache cluster.
+
+
+********************* W A R N I N G ! ! ! ! ! ***********************
+Memcached has no security or authentication. Please ensure that your
+server is appropriately firewalled, and that the port(s) used for
+memcached servers are not publicly accessible. Otherwise, anyone on
+the internet can put data into and read data from your cache.
+
+An attacker familiar with MediaWiki internals could use this to give
+themselves developer access and delete all data from the wiki's
+database, as well as getting all users' password hashes and e-mail
+addresses.
+********************* W A R N I N G ! ! ! ! ! ***********************
+
+== Setup ==
+
+If you want to start small, just run one memcached on your web
+server:
+
+ memcached -d -l 127.0.0.1 -p 11000 -m 64
+
+(to run in daemon mode, accessible only via loopback interface,
+on port 11000, using up to 64MB of memory)
+
+In your LocalSettings.php file, set:
+
+ $wgUseMemCached = true;
+ $wgMemCachedServers = array( "127.0.0.1:11000" );
+
+The wiki should then use memcached to cache various data. To use
+multiple servers (physically separate boxes or multiple caches
+on one machine on a large-memory x86 box), just add more items
+to the array. To increase the weight of a server (say, because
+it has twice the memory of the others and you want to spread
+usage evenly), make its entry a subarray:
+
+ $wgMemCachedServers = array(
+ "127.0.0.1:11000", # one gig on this box
+ array("192.168.0.1:11000", 2) # two gigs on the other box
+ );
+
+
+== PHP client for memcached ==
+
+As of this writing, MediaWiki includes version 1.0.10 of the PHP
+memcached client by Ryan Gilfether <hotrodder@rocketmail.com>.
+You'll find some documentation for it in the 'php-memcached'
+subdirectory under the present one.
+
+We intend to track updates, but if you want to check for the lastest
+released version, see http://www.danga.com/memcached/apis.bml
+
+If you don't set $wgUseMemCached, we still create a MemCacheClient,
+but requests to it are no-ops and we always fall through to the
+database. If the cache daemon can't be contacted, it should also
+disable itself fairly smoothly.
+
+== Keys used ==
+
+User:
+ key: $wgDBname:user:id:$sId
+ ex: wikidb:user:id:51
+ stores: instance of class User
+ set in: User::loadFromSession()
+ cleared by: User::saveSettings(), UserTalkUpdate::doUpdate()
+
+Newtalk:
+ key: $wgDBname:newtalk:ip:$ip
+ ex: wikidb:newtalk:ip:123.45.67.89
+ stores: integer, 0 or 1
+ set in: User::loadFromDatabase()
+ cleared by: User::saveSettings() # ?
+ expiry set to 30 minutes
+
+LinkCache:
+ key: $wgDBname:lc:title:$title
+ ex: wikidb:lc:title:Wikipedia:Welcome,_Newcomers!
+ stores: cur_id of page, or 0 if page does not exist
+ set in: LinkCache::addLink()
+ cleared by: LinkCache::clearBadLink()
+ should be cleared on page deletion and rename
+MediaWiki namespace:
+ key: $wgDBname:messages
+ ex: wikidb:messages
+ stores: an array where the keys are DB keys and the values are messages
+ set in: wfMsg(), Article::editUpdates() both call wfLoadAllMessages()
+ cleared by: nothing
+
+Watchlist:
+ key: $wgDBname:watchlist:id:$userID
+ ex: wikidb:watchlist:id:4635
+ stores: HTML string
+ cleared by: nothing, expiry time $wgWLCacheTimeout (1 hour)
+ note: emergency optimisation only
+
+IP blocks:
+ key: $wgDBname:ipblocks
+ ex: wikidb:ipblocks
+ stores: array of arrays, for the BlockCache class
+ cleared by: BlockCache:clear()
+
+... more to come ...
diff --git a/docs/php-memcached/ChangeLog b/docs/php-memcached/ChangeLog
new file mode 100644
index 000000000000..86792f607e70
--- /dev/null
+++ b/docs/php-memcached/ChangeLog
@@ -0,0 +1,45 @@
+Release 1.0.10
+--------------
+* bug fix: changes hashing function to crc32, sprintf %u
+* feature: optional compression
+
+Release 1.0.9
+-------------
+* protocol parsing bug
+
+Release 1.0.8
+-------------
+* whitespace/punctuation/wording cleanups
+
+Release 1.0.7
+-------------
+* added 3 functions which handle error reporting
+ error() - returns error number of last error generated, else returns 0
+ error_string() - returns a string description of error number retuned
+ error_clear() - clears the last error number and error string
+* removed call to preg_match() in _loaditems()
+* only non-scalar values are serialize() before being
+ sent to the server
+* added the optional timestamp argument for delete()
+ read Documentation file for details
+* PHPDocs/PEAR style comments added
+* abstract debugging (Brion Vibber <brion@pobox.com>)
+
+Release 1.0.6
+-------------
+* removed all array_push() calls
+* applied patch provided by Stuart Herbert<stuart@gentoo.org>
+ corrects possible endless loop. Available at
+ http://bugs.gentoo.org/show_bug.cgi?id=25385
+* fixed problem with storing large binary files
+* added more error checking, specifically on all socket functions
+* added support for the INCR and DECR commands
+ which increment or decrement a value stored in MemCached
+* Documentation removed from source and is now available
+ in the file Documentation
+
+Release 1.0.4
+-------------
+* initial release, version numbers kept
+ in sync with MemCached version
+* capable of storing any datatype in MemCached
diff --git a/docs/php-memcached/Documentation b/docs/php-memcached/Documentation
new file mode 100644
index 000000000000..4782807b6898
--- /dev/null
+++ b/docs/php-memcached/Documentation
@@ -0,0 +1,258 @@
+Ryan Gilfether <hotrodder@rocketmail.com>
+http://www.gilfether.com
+This module is Copyright (c) 2003 Ryan Gilfether.
+All rights reserved.
+
+You may distribute under the terms of the GNU General Public License
+This is free software. IT COMES WITHOUT WARRANTY OF ANY KIND.
+
+See the memcached website: http://www.danga.com/memcached/
+
+
+// Takes one parameter, a array of options. The most important key is
+// options["servers"], but that can also be set later with the set_servers()
+// method. The servers must be an array of hosts, each of which is
+// either a scalar of the form <10.0.0.10:11211> or an array of the
+// former and an integer weight value. (the default weight if
+// unspecified is 1.) It's recommended that weight values be kept as low
+// as possible, as this module currently allocates memory for bucket
+// distribution proportional to the total host weights.
+// $options["debug"] turns the debugging on if set to true
+MemCachedClient::MemCachedClient($options);
+
+// sets up the list of servers and the ports to connect to
+// takes an array of servers in the same format as in the constructor
+MemCachedClient::set_servers($servers);
+
+// Retrieves a key from the memcache. Returns the value (automatically
+// unserialized, if necessary) or FALSE if it fails.
+// The $key can optionally be an array, with the first element being the
+// hash value, if you want to avoid making this module calculate a hash
+// value. You may prefer, for example, to keep all of a given user's
+// objects on the same memcache server, so you could use the user's
+// unique id as the hash value.
+// Possible errors set are:
+// MC_ERR_GET
+MemCachedClient::get($key);
+
+// just like get(), but takes an array of keys, returns FALSE on error
+// Possible errors set are:
+// MC_ERR_NOT_ACTIVE
+MemCachedClient::get_multi($keys)
+
+// Unconditionally sets a key to a given value in the memcache. Returns true
+// if it was stored successfully.
+// The $key can optionally be an arrayref, with the first element being the
+// hash value, as described above.
+// returns TRUE on success else FALSE
+// Possible errors set are:
+// MC_ERR_NOT_ACTIVE
+// MC_ERR_GET_SOCK
+// MC_ERR_SOCKET_WRITE
+// MC_ERR_SOCKET_READ
+// MC_ERR_SET
+MemCachedClient::set($key, $value, $exptime);
+
+// Like set(), but only stores in memcache if the key doesn't already exist.
+// returns TRUE on success else FALSE
+// Possible errors set are:
+// MC_ERR_NOT_ACTIVE
+// MC_ERR_GET_SOCK
+// MC_ERR_SOCKET_WRITE
+// MC_ERR_SOCKET_READ
+// MC_ERR_SET
+MemCachedClient::add($key, $value, $exptime);
+
+// Like set(), but only stores in memcache if the key already exists.
+// returns TRUE on success else FALSE
+// Possible errors set are:
+// MC_ERR_NOT_ACTIVE
+// MC_ERR_GET_SOCK
+// MC_ERR_SOCKET_WRITE
+// MC_ERR_SOCKET_READ
+// MC_ERR_SET
+MemCachedClient::replace($key, $value, $exptime);
+
+// removes the key from the MemCache
+// $time is the amount of time in seconds (or Unix time) until which
+// the client wishes the server to refuse "add" and "replace" commands
+// with this key. For this amount of item, the item is put into a
+// delete queue, which means that it won't possible to retrieve it by
+// the "get" command, but "add" and "replace" command with this key
+// will also fail (the "set" command will succeed, however). After the
+// time passes, the item is finally deleted from server memory.
+// The parameter $time is optional, and, if absent, defaults to 0
+// (which means that the item will be deleted immediately and further
+// storage commands with this key will succeed).
+// returns TRUE on success else returns FALSE
+// Possible errors set are:
+// MC_ERR_NOT_ACTIVE
+// MC_ERR_GET_SOCK
+// MC_ERR_SOCKET_WRITE
+// MC_ERR_SOCKET_READ
+// MC_ERR_DELETE
+MemCachedClient::delete($key, $time = 0);
+
+// Sends a command to the server to atomically increment the value for
+// $key by $value, or by 1 if $value is undefined. Returns FALSE if $key
+// doesn't exist on server, otherwise it returns the new value after
+// incrementing. Value should be zero or greater. Overflow on server
+// is not checked. Be aware of values approaching 2**32. See decr.
+// Possible errors set are:
+// MC_ERR_NOT_ACTIVE
+// MC_ERR_GET_SOCK
+// MC_ERR_SOCKET_WRITE
+// MC_ERR_SOCKET_READ
+// returns new value on success, else returns FALSE
+// ONLY WORKS WITH NUMERIC VALUES
+MemCachedClient::incr($key[, $value]);
+
+// Like incr, but decrements. Unlike incr, underflow is checked and new
+// values are capped at 0. If server value is 1, a decrement of 2
+// returns 0, not -1.
+// Possible errors set are:
+// MC_ERR_NOT_ACTIVE
+// MC_ERR_GET_SOCK
+// MC_ERR_SOCKET_WRITE
+// MC_ERR_SOCKET_READ
+// returns new value on success, else returns FALSE
+// ONLY WORKS WITH NUMERIC VALUES
+MemCachedClient::decr($key[, $value]);
+
+// disconnects from all servers
+MemCachedClient::disconnect_all();
+
+// if $do_debug is set to true, will print out
+// debugging info, else debug is turned off
+MemCachedClient::set_debug($do_debug);
+
+// remove all cached hosts that are no longer good
+MemCachedClient::forget_dead_hosts();
+
+// When a function returns FALSE, an error code is set.
+// This funtion will return the error code.
+// See error_string()
+// returns last error code set
+MemCachedClient::error()
+
+// Returns a string describing the error set in error()
+// See error()
+// returns a string describing the error code given
+MemCachedClient::error_string()
+
+// Resets the error number and error string
+MemCachedClient::error_clear()
+
+Error codes are as follows:
+MC_ERR_NOT_ACTIVE // no active servers
+MC_ERR_SOCKET_WRITE // socket_write() failed
+MC_ERR_SOCKET_READ // socket_read() failed
+MC_ERR_SOCKET_CONNECT // failed to connect to host
+MC_ERR_DELETE // delete() did not recieve DELETED command
+MC_ERR_HOST_FORMAT // sock_to_host() invalid host format
+MC_ERR_HOST_DEAD // sock_to_host() host is dead
+MC_ERR_GET_SOCK // get_sock() failed to find a valid socket
+MC_ERR_SET // _set() failed to receive the STORED response
+MC_ERR_LOADITEM_HEADER // _load_items failed to receive valid data header
+MC_ERR_LOADITEM_END // _load_items failed to receive END response
+MC_ERR_LOADITEM_BYTES // _load_items bytes read larger than bytes available
+MC_ERR_GET // failed to get value associated with key
+
+// Turns compression on or off; 0=off, 1=on
+MemCacheClient::set_compression($setting)
+
+EXAMPLE:
+<?php
+require("MemCachedClient.inc.php");
+
+// set the servers, with the last one having an interger weight value of 3
+$options["servers"] = array("10.0.0.15:11000","10.0.0.16:11001",array("10.0.0.17:11002", 3));
+$options["debug"] = false;
+
+$memc = new MemCachedClient($options);
+
+
+/***********************
+ * STORE AN ARRAY
+ ***********************/
+$myarr = array("one","two", 3);
+$memc->set("key_one", $myarr);
+$val = $memc->get("key_one");
+print $val[0]."\n"; // prints 'one'
+print $val[1]."\n"; // prints 'two'
+print $val[2]."\n"; // prints 3
+
+
+print "\n";
+
+
+/***********************
+ * STORE A CLASS
+ ***********************/
+class tester
+{
+ var $one;
+ var $two;
+ var $three;
+}
+
+$t = new tester;
+$t->one = "one";
+$t->two = "two";
+$t->three = 3;
+$memc->set("key_two", $t);
+$val = $memc->get("key_two");
+print $val->one."\n";
+print $val->two."\n";
+print $val->three."\n";
+
+
+print "\n";
+
+
+/***********************
+ * STORE A STRING
+ ***********************/
+$memc->set("key_three", "my string");
+$val = $memc->get("key_three");
+print $val; // prints 'my string'
+
+$memc->delete("key_one");
+$memc->delete("key_two");
+$memc->delete("key_three");
+
+$memc->disconnect_all();
+
+
+
+print "\n";
+
+
+/***********************
+ * STORE A BINARY FILE
+ ***********************/
+
+ // first read the file and save it in memcache
+$fp = fopen( "./image.jpg", "rb" ) ;
+if ( !$fp )
+{
+ print "Could not open ./file.dat!\n" ;
+ exit ;
+}
+$data = fread( $fp, filesize( "./image.jpg" ) ) ;
+fclose( $fp ) ;
+print "Data length is " . strlen( $data ) . "\n" ;
+$memc->set( "key", $data ) ;
+
+// now open a file for writing and write the data
+// retrieved from memcache
+$fp = fopen("./test.jpg","wb");
+$data = $memc->get( "key" ) ;
+print "Data length is " . strlen( $data ) . "\n" ;
+fwrite($fp,$data,strlen( $data ));
+fclose($fp);
+
+
+?>
+
+
diff --git a/docs/schema.txt b/docs/schema.txt
new file mode 100644
index 000000000000..f73484629e71
--- /dev/null
+++ b/docs/schema.txt
@@ -0,0 +1,6 @@
+The most up-to-date schema for the tables in the database
+will always be "tables.sql" in the maintenance directory,
+which is called from the installation script.
+
+That file has been commented with details of the usage for
+each table and field.
diff --git a/docs/skin.txt b/docs/skin.txt
new file mode 100644
index 000000000000..82a5b72ec1ae
--- /dev/null
+++ b/docs/skin.txt
@@ -0,0 +1,48 @@
+
+skin.txt
+
+This document describes the overall architecture of MediaWiki's HTML rendering
+code as well as some history about the skin system. It is placed here rather
+than in comments in the code itself to help reduce the code size.
+
+== Version 1.4 ==
+
+MediaWiki still use the PHPTal skin system introduced in version 1.3 but some
+changes have been made to the file organisation.
+
+PHP class and PHPTal templates have been moved to /skins/ (respectivly from
+/includes/ and /templates/). This way skin designer and end user just stick to
+one directory.
+
+Two samples are provided to start with, one for PHPTal use (SkinPHPTal.sample)
+and one without (Skin.sample).
+
+
+== Version 1.3 ==
+
+The following might help a bit though.
+
+Firstly, there's Skin.php; this file will check various settings, and it
+contains a base class from which new skins can be derived.
+
+Before version 1.3, each skin had its own PHP file (with a sub-class to Skin)
+to generate the output. The files are:
+ * SkinCologneBlue.php
+ * SkinNostalgia.php
+ * SkinStandard.php
+ * SkinWikimediaWiki.php
+If you want to change those skins, you have to edit these PHP files.
+
+Since 1.3 a new special skin file is available: SkinPHPTal.php. It makes use of
+the PHPTal template engine and allows you to separate code and layout of the
+pages. The default 1.3 skin is MonoBook and it uses the SkinPHPTAL class.
+
+To change the layout, just edit the PHPTal template (templates/xhtml_slim.pt)
+as well as the stylesheets (stylesheets/monobook/*).
+
+
+== pre 1.3 version ==
+
+Unfortunately there isn't any documentation, and the code's in a bit of a mess
+right now during the transition from the old skin code to the new template-based
+skin code in 1.3.
diff --git a/docs/title.txt b/docs/title.txt
new file mode 100644
index 000000000000..b404bd3ced27
--- /dev/null
+++ b/docs/title.txt
@@ -0,0 +1,72 @@
+title.txt
+
+The MediaWiki software's "Title" class represents article
+titles, which are used for many purposes: as the human-readable
+text title of the article, in the URL used to access the article,
+the wikitext link to the article, the key into the article
+database, and so on. The class in instantiated from one of
+these forms and can be queried for the others, and for other
+attributes of the title. This is intended to be an
+immutable "value" class, so there are no mutator functions.
+
+To get a new instance, call one of the static factory
+methods WikiTitle::newFromURL(), WikiTitle::newFromDBKey(),
+or WikiTitle::newFromText(). Once instantiated, the
+other non-static accessor methods can be used, such as
+getText(), getDBKey(), getNamespace(), etc.
+
+The prefix rules: a title consists of an optional Interwiki
+prefix (such as "m:" for meta or "de:" for German), followed
+by an optional namespace, followed by the remainder of the
+title. Both Interwiki prefixes and namespace prefixes have
+the same rules: they contain only letters, digits, space, and
+underscore, must start with a letter, are case insensitive,
+and spaces and underscores are interchangeable. Prefixes end
+with a ":". A prefix is only recognized if it is one of those
+specifically allowed by the software. For example, "de:name"
+is a link to the article "name" in the German Wikipedia, because
+"de" is recognized as one of the allowable interwikis. The
+title "talk:name" is a link to the article "name" in the "talk"
+namespace of the current wiki, because "talk" is a recognized
+namespace. Both may be present, and if so, the interwiki must
+come first, for example, "m:talk:name". If a title begins with
+a colon as its first character, no prefixes are scanned for,
+and the colon is just removed. Note that because of these
+rules, it is possible to have articles with colons in their
+names. "E. Coli 0157:H7" is a valid title, as is "2001: A Space
+Odyssey", because "E. Coli 0157" and "2001" are not valid
+interwikis or namespaces. Likewise, ":de:name" is a link to
+the article "de:name"--even though "de" is a valid interwiki,
+the initial colon stops all prefix matching.
+
+Character mapping rules: Once prefixes have been stripped, the
+rest of the title processed this way: spaces and underscores are
+treated as equivalent and each is converted to the other in the
+appropriate context (underscore in URL and database keys, spaces
+in plain text). "Extended" characters in the 0x80..0xFF range
+are allowed in all places, and are valid characters. They are
+encoded in URLs. Other characters may be ASCII letters, digits,
+hyphen, comma, period, apostrophe, parentheses, and colon. No
+other ASCII characters are allowed, and will be deleted if found
+(they will probably cause a browser to misinterpret the URL).
+Extended characters are _not_ urlencoded when used as text or
+database keys.
+
+Character encoding rules: TODO
+
+Canonical forms: the canonical form of a title will always be
+returned by the object. In this form, the first (and only the
+first) character of the namespace and title will be uppercased;
+the rest of the namespace will be lowercased, while the title
+will be left as is. The text form will use spaces, the URL and
+DBkey forms will use underscores. Interwiki prefixes are all
+lowercase. The namespace will use underscores when returned
+alone; it will use spaces only when attached to the text title.
+
+getArticleID() needs some explanation: for "internal" articles,
+it should return the "cur_id" field if the article exists, else
+it returns 0. For all external articles it returns 0. All of
+the IDs for all instances of Title created during a request are
+cached, so they can be looked up wuickly while rendering wiki
+text with lots of internal links.
+
diff --git a/docs/user.txt b/docs/user.txt
new file mode 100644
index 000000000000..3f1c8202ef2d
--- /dev/null
+++ b/docs/user.txt
@@ -0,0 +1,63 @@
+
+user.txt
+
+Documenting the MediaWiki User object.
+
+(DISCLAIMER: The documentation is not guaranteed to be in sync with
+the code at all times. If in doubt, check the table definitions
+and User.php.)
+
+Database fields:
+
+ user_id
+ Unique integer identifier; primary key. Sent to user in
+ cookie "{$wgDBname}UserID".
+
+ user_name
+ Text of full user name; title of "user:" page. Displayed
+ on change lists, etc. Sent to user as cookie "{$wgDBname}UserName".
+ Note that user names can contain spaces, while these are
+ converted to underscores in page titles.
+
+ user_rights
+ Comma-separated list of rights. Right now, only "sysop",
+ "developer", "bureaucrat", and "bot" have meaning.
+
+ user_password
+ Salted md5 hash of md5-hashed user login password. If user option to
+ remember password is set, an md5 password hash is stored in cookie
+ "{$wgDBname}UserPassword". The original password and the hashed password
+ can be compared to the salted-hashed-hashed password.
+
+ user_newpassword
+ Hash for randomly generated password sent on 'send me a new password'.
+ If a match is made on login, the new password will replace the old one.
+
+ user_email
+ User's e-mail address. (Optional, used for user-to-user
+ e-mail and password recovery.)
+
+ user_options
+ A urlencoded string of name=value pairs to set various
+ user options.
+
+ user_touched
+ Timestamp updated when the user logs in, changes preferences, alters
+ watchlist, or when someone edits their user talk page or they clear
+ the new-talk field by viewing it. Used to invalidate old cached pages
+ from the user's browser cache.
+
+ user_real_name
+ "Real name" optionally used in some metadata lists.
+
+The user object encapsulates all of the settings, and clients
+classes use the getXXX() functions to access them. These functions
+do all the work of determining whether the user is logged in,
+whether the requested option can be satisfied from cookies or
+whether a database query is needed. Most of the settings needed
+for rendering normal pages are set in the cookie to minimize use
+of the database.
+
+Options
+ The user_options field is a list of name-value pairs. The
+ following option names are used at various points in the system:
diff --git a/extensions/README b/extensions/README
new file mode 100644
index 000000000000..cc931160781e
--- /dev/null
+++ b/extensions/README
@@ -0,0 +1,3 @@
+Some extensions (such as the hieroglyphic module WikiHiero) are
+distributed separately. Drop them into this extensions directory
+and enable as per the extension's directions.
diff --git a/images/README b/images/README
new file mode 100644
index 000000000000..ca30bbcbaec6
--- /dev/null
+++ b/images/README
@@ -0,0 +1,5 @@
+If uploads are enabled in the wiki, files will be put in subdirectories
+under here.
+
+Note to upgraders: as of MediaWiki 1.5, the images used in the user
+interface have been moved to skins/common/images.
diff --git a/img_auth.php b/img_auth.php
new file mode 100644
index 000000000000..e0a6459f740b
--- /dev/null
+++ b/img_auth.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Image download authorisation script
+ *
+ * To use, in LocalSettings.php set $wgUploadDirectory to point to a non-public
+ * directory, and $wgUploadPath to point to this file. Also set $wgWhitelistRead
+ * to an array of pages you want everyone to be able to access. Your server must
+ * support PATH_INFO, CGI-based configurations generally don't.
+ */
+require_once( './includes/WebStart.php' );
+wfProfileIn( 'img_auth.php' );
+require_once( './includes/StreamFile.php' );
+
+if( !isset( $_SERVER['PATH_INFO'] ) ) {
+ wfDebugLog( 'img_auth', "missing PATH_INFO" );
+ wfForbidden();
+}
+
+# Get filenames/directories
+wfDebugLog( 'img_auth', "PATH_INFO is: " . $_SERVER['PATH_INFO'] );
+$filename = realpath( $wgUploadDirectory . $_SERVER['PATH_INFO'] );
+$realUploadDirectory = realpath( $wgUploadDirectory );
+$imageName = $wgContLang->getNsText( NS_IMAGE ) . ":" . wfBaseName( $_SERVER['PATH_INFO'] );
+
+# Check if the filename is in the correct directory
+if ( substr( $filename, 0, strlen( $realUploadDirectory ) ) != $realUploadDirectory ) {
+ wfDebugLog( 'img_auth', "requested path not in upload dir: $filename" );
+ wfForbidden();
+}
+
+if ( is_array( $wgWhitelistRead ) && !in_array( $imageName, $wgWhitelistRead ) && !$wgUser->getID() ) {
+ wfDebugLog( 'img_auth', "not logged in and requested file not in whitelist: $imageName" );
+ wfForbidden();
+}
+
+if( !file_exists( $filename ) ) {
+ wfDebugLog( 'img_auth', "requested file does not exist: $filename" );
+ wfForbidden();
+}
+if( is_dir( $filename ) ) {
+ wfDebugLog( 'img_auth', "requested file is a directory: $filename" );
+ wfForbidden();
+}
+
+# Write file
+wfDebugLog( 'img_auth', "streaming file: $filename" );
+wfStreamFile( $filename );
+wfLogProfilingData();
+
+function wfForbidden() {
+ header( 'HTTP/1.0 403 Forbidden' );
+ header( 'Content-Type: text/html; charset=utf-8' );
+ print
+"<html><body>
+<h1>Access denied</h1>
+<p>You need to log in to access files on this server</p>
+</body></html>";
+ wfLogProfilingData();
+ exit;
+}
+
+?>
diff --git a/includes/.htaccess b/includes/.htaccess
new file mode 100644
index 000000000000..3a4288278871
--- /dev/null
+++ b/includes/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/includes/AjaxDispatcher.php b/includes/AjaxDispatcher.php
new file mode 100644
index 000000000000..39ec19f883d0
--- /dev/null
+++ b/includes/AjaxDispatcher.php
@@ -0,0 +1,91 @@
+<?php
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+if ( ! $wgUseAjax ) {
+ die( 1 );
+}
+
+require_once( 'AjaxFunctions.php' );
+
+class AjaxDispatcher {
+ var $mode;
+ var $func_name;
+ var $args;
+
+ function AjaxDispatcher() {
+ wfProfileIn( __METHOD__ );
+
+ $this->mode = "";
+
+ if (! empty($_GET["rs"])) {
+ $this->mode = "get";
+ }
+
+ if (!empty($_POST["rs"])) {
+ $this->mode = "post";
+ }
+
+ if ($this->mode == "get") {
+ $this->func_name = $_GET["rs"];
+ if (! empty($_GET["rsargs"])) {
+ $this->args = $_GET["rsargs"];
+ } else {
+ $this->args = array();
+ }
+ } else {
+ $this->func_name = $_POST["rs"];
+ if (! empty($_POST["rsargs"])) {
+ $this->args = $_POST["rsargs"];
+ } else {
+ $this->args = array();
+ }
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ function performAction() {
+ global $wgAjaxExportList, $wgOut;
+
+ if ( empty( $this->mode ) ) {
+ return;
+ }
+ wfProfileIn( __METHOD__ );
+
+ if (! in_array( $this->func_name, $wgAjaxExportList ) ) {
+ wfHttpError( 400, 'Bad Request',
+ "unknown function " . (string) $this->func_name );
+ } else {
+ try {
+ $result = call_user_func_array($this->func_name, $this->args);
+
+ if ( $result === false || $result === NULL ) {
+ wfHttpError( 500, 'Internal Error',
+ "{$this->func_name} returned no data" );
+ }
+ else {
+ if ( is_string( $result ) ) {
+ $result= new AjaxResponse( $result );
+ }
+
+ $result->sendHeaders();
+ $result->printText();
+ }
+
+ } catch (Exception $e) {
+ if (!headers_sent()) {
+ wfHttpError( 500, 'Internal Error',
+ $e->getMessage() );
+ } else {
+ print $e->getMessage();
+ }
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ $wgOut = null;
+ }
+}
+
+?>
diff --git a/includes/AjaxFunctions.php b/includes/AjaxFunctions.php
new file mode 100644
index 000000000000..eee2a1a4e604
--- /dev/null
+++ b/includes/AjaxFunctions.php
@@ -0,0 +1,171 @@
+<?php
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+/**
+ * Function converts an Javascript escaped string back into a string with
+ * specified charset (default is UTF-8).
+ * Modified function from http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
+ *
+ * @param $source String escaped with Javascript's escape() function
+ * @param $iconv_to String destination character set will be used as second paramether in the iconv function. Default is UTF-8.
+ * @return string
+ */
+function js_unescape($source, $iconv_to = 'UTF-8') {
+ $decodedStr = '';
+ $pos = 0;
+ $len = strlen ($source);
+ while ($pos < $len) {
+ $charAt = substr ($source, $pos, 1);
+ if ($charAt == '%') {
+ $pos++;
+ $charAt = substr ($source, $pos, 1);
+ if ($charAt == 'u') {
+ // we got a unicode character
+ $pos++;
+ $unicodeHexVal = substr ($source, $pos, 4);
+ $unicode = hexdec ($unicodeHexVal);
+ $decodedStr .= code2utf($unicode);
+ $pos += 4;
+ }
+ else {
+ // we have an escaped ascii character
+ $hexVal = substr ($source, $pos, 2);
+ $decodedStr .= chr (hexdec ($hexVal));
+ $pos += 2;
+ }
+ }
+ else {
+ $decodedStr .= $charAt;
+ $pos++;
+ }
+ }
+
+ if ($iconv_to != "UTF-8") {
+ $decodedStr = iconv("UTF-8", $iconv_to, $decodedStr);
+ }
+
+ return $decodedStr;
+}
+
+/**
+ * Function coverts number of utf char into that character.
+ * Function taken from: http://sk2.php.net/manual/en/function.utf8-encode.php#49336
+ *
+ * @param $num Integer
+ * @return utf8char
+ */
+function code2utf($num){
+ if ( $num<128 )
+ return chr($num);
+ if ( $num<2048 )
+ return chr(($num>>6)+192).chr(($num&63)+128);
+ if ( $num<65536 )
+ return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
+ if ( $num<2097152 )
+ return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
+ return '';
+}
+
+function wfSajaxSearch( $term ) {
+ global $wgContLang, $wgOut;
+ $limit = 16;
+
+ $l = new Linker;
+
+ $term = str_replace( ' ', '_', $wgContLang->ucfirst(
+ $wgContLang->checkTitleEncoding( $wgContLang->recodeInput( js_unescape( $term ) ) )
+ ) );
+
+ if ( strlen( str_replace( '_', '', $term ) )<3 )
+ return;
+
+ $db =& wfGetDB( DB_SLAVE );
+ $res = $db->select( 'page', 'page_title',
+ array( 'page_namespace' => 0,
+ "page_title LIKE '". $db->strencode( $term) ."%'" ),
+ "wfSajaxSearch",
+ array( 'LIMIT' => $limit+1 )
+ );
+
+ $r = "";
+
+ $i=0;
+ while ( ( $row = $db->fetchObject( $res ) ) && ( ++$i <= $limit ) ) {
+ $nt = Title::newFromDBkey( $row->page_title );
+ $r .= '<li>' . $l->makeKnownLinkObj( $nt ) . "</li>\n";
+ }
+ if ( $i > $limit ) {
+ $more = '<i>' . $l->makeKnownLink( $wgContLang->specialPage( "Allpages" ),
+ wfMsg('moredotdotdot'),
+ "namespace=0&from=" . wfUrlEncode ( $term ) ) .
+ '</i>';
+ } else {
+ $more = '';
+ }
+
+ $subtitlemsg = ( Title::newFromText($term) ? 'searchsubtitle' : 'searchsubtitleinvalid' );
+ $subtitle = $wgOut->parse( wfMsg( $subtitlemsg, wfEscapeWikiText($term) ) ); #FIXME: parser is missing mTitle !
+
+ $term = htmlspecialchars( $term );
+ $html = '<div style="float:right; border:solid 1px black;background:gainsboro;padding:2px;"><a onclick="Searching_Hide_Results();">'
+ . wfMsg( 'hideresults' ) . '</a></div>'
+ . '<h1 class="firstHeading">'.wfMsg('search')
+ . '</h1><div id="contentSub">'. $subtitle . '</div><ul><li>'
+ . $l->makeKnownLink( $wgContLang->specialPage( 'Search' ),
+ wfMsg( 'searchcontaining', $term ),
+ "search=$term&fulltext=Search" )
+ . '</li><li>' . $l->makeKnownLink( $wgContLang->specialPage( 'Search' ),
+ wfMsg( 'searchnamed', $term ) ,
+ "search=$term&go=Go" )
+ . "</li></ul><h2>" . wfMsg( 'articletitles', $term ) . "</h2>"
+ . '<ul>' .$r .'</ul>'.$more;
+
+ $response = new AjaxResponse( $html );
+
+ $response->setCacheDuration( 30*60 );
+
+ return $response;
+}
+
+/**
+ * Called for AJAX watch/unwatch requests.
+ * @param $pageID Integer ID of the page to be watched/unwatched
+ * @param $watch String 'w' to watch, 'u' to unwatch
+ * @return String '<w#>' or '<u#>' on successful watch or unwatch, respectively, or '<err#>' on error (invalid XML in case we want to add HTML sometime)
+ */
+function wfAjaxWatch($pageID = "", $watch = "") {
+ if(wfReadOnly())
+ return '<err#>'; // redirect to action=(un)watch, which will display the database lock message
+
+ if(('w' !== $watch && 'u' !== $watch) || !is_numeric($pageID))
+ return '<err#>';
+ $watch = 'w' === $watch;
+ $pageID = intval($pageID);
+
+ $title = Title::newFromID($pageID);
+ if(!$title)
+ return '<err#>';
+ $article = new Article($title);
+ $watching = $title->userIsWatching();
+
+ if($watch) {
+ if(!$watching) {
+ $dbw =& wfGetDB(DB_MASTER);
+ $dbw->begin();
+ $article->doWatch();
+ $dbw->commit();
+ }
+ } else {
+ if($watching) {
+ $dbw =& wfGetDB(DB_MASTER);
+ $dbw->begin();
+ $article->doUnwatch();
+ $dbw->commit();
+ }
+ }
+
+ return $watch ? '<w#>' : '<u#>';
+}
+?>
diff --git a/includes/AjaxResponse.php b/includes/AjaxResponse.php
new file mode 100644
index 000000000000..a59c73bb14a5
--- /dev/null
+++ b/includes/AjaxResponse.php
@@ -0,0 +1,203 @@
+<?php
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+class AjaxResponse {
+ var $mCacheDuration;
+ var $mVary;
+
+ var $mDisabled;
+ var $mText;
+ var $mResponseCode;
+ var $mLastModified;
+ var $mContentType;
+
+ function AjaxResponse( $text = NULL ) {
+ $this->mCacheDuration = NULL;
+ $this->mVary = NULL;
+
+ $this->mDisabled = false;
+ $this->mText = '';
+ $this->mResponseCode = '200 OK';
+ $this->mLastModified = false;
+ $this->mContentType= 'text/html; charset=utf-8';
+
+ if ( $text ) {
+ $this->addText( $text );
+ }
+ }
+
+ function setCacheDuration( $duration ) {
+ $this->mCacheDuration = $duration;
+ }
+
+ function setVary( $vary ) {
+ $this->mVary = $vary;
+ }
+
+ function setResponseCode( $code ) {
+ $this->mResponseCode = $code;
+ }
+
+ function setContentType( $type ) {
+ $this->mContentType = $type;
+ }
+
+ function disable() {
+ $this->mDisabled = true;
+ }
+
+ function addText( $text ) {
+ if ( ! $this->mDisabled && $text ) {
+ $this->mText .= $text;
+ }
+ }
+
+ function printText() {
+ if ( ! $this->mDisabled ) {
+ print $this->mText;
+ }
+ }
+
+ function sendHeaders() {
+ global $wgUseSquid, $wgUseESI;
+
+ if ( $this->mResponseCode ) {
+ $n = preg_replace( '/^ *(\d+)/', '\1', $this->mResponseCode );
+ header( "Status: " . $this->mResponseCode, true, (int)$n );
+ }
+
+ header ("Content-Type: " . $this->mContentType );
+
+ if ( $this->mLastModified ) {
+ header ("Last-Modified: " . $this->mLastModified );
+ }
+ else {
+ header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ }
+
+ if ( $this->mCacheDuration ) {
+
+ # If squid caches are configured, tell them to cache the response,
+ # and tell the client to always check with the squid. Otherwise,
+ # tell the client to use a cached copy, without a way to purge it.
+
+ if( $wgUseSquid ) {
+
+ # Expect explicite purge of the proxy cache, but require end user agents
+ # to revalidate against the proxy on each visit.
+ # Surrogate-Control controls our Squid, Cache-Control downstream caches
+
+ if ( $wgUseESI ) {
+ header( 'Surrogate-Control: max-age='.$this->mCacheDuration.', content="ESI/1.0"');
+ header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
+ } else {
+ header( 'Cache-Control: s-maxage='.$this->mCacheDuration.', must-revalidate, max-age=0' );
+ }
+
+ } else {
+
+ # Let the client do the caching. Cache is not purged.
+ header ("Expires: " . gmdate( "D, d M Y H:i:s", time() + $this->mCacheDuration ) . " GMT");
+ header ("Cache-Control: s-max-age={$this->mCacheDuration},public,max-age={$this->mCacheDuration}");
+ }
+
+ } else {
+ # always expired, always modified
+ header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
+ header ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
+ header ("Pragma: no-cache"); // HTTP/1.0
+ }
+
+ if ( $this->mVary ) {
+ header ( "Vary: " . $this->mVary );
+ }
+ }
+
+ /**
+ * checkLastModified tells the client to use the client-cached response if
+ * possible. If sucessful, the AjaxResponse is disabled so that
+ * any future call to AjaxResponse::printText() have no effect. The method
+ * returns true iff the response code was set to 304 Not Modified.
+ */
+ function checkLastModified ( $timestamp ) {
+ global $wgCachePages, $wgCacheEpoch, $wgUser;
+ $fname = 'AjaxResponse::checkLastModified';
+
+ if ( !$timestamp || $timestamp == '19700101000000' ) {
+ wfDebug( "$fname: CACHE DISABLED, NO TIMESTAMP\n" );
+ return;
+ }
+ if( !$wgCachePages ) {
+ wfDebug( "$fname: CACHE DISABLED\n", false );
+ return;
+ }
+ if( $wgUser->getOption( 'nocache' ) ) {
+ wfDebug( "$fname: USER DISABLED CACHE\n", false );
+ return;
+ }
+
+ $timestamp = wfTimestamp( TS_MW, $timestamp );
+ $lastmod = wfTimestamp( TS_RFC2822, max( $timestamp, $wgUser->mTouched, $wgCacheEpoch ) );
+
+ if( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
+ # IE sends sizes after the date like this:
+ # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
+ # this breaks strtotime().
+ $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
+ $modsinceTime = strtotime( $modsince );
+ $ismodsince = wfTimestamp( TS_MW, $modsinceTime ? $modsinceTime : 1 );
+ wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", false );
+ wfDebug( "$fname: -- we might send Last-Modified : $lastmod\n", false );
+ if( ($ismodsince >= $timestamp ) && $wgUser->validateCache( $ismodsince ) && $ismodsince >= $wgCacheEpoch ) {
+ $this->setResponseCode( "304 Not Modified" );
+ $this->disable();
+ $this->mLastModified = $lastmod;
+
+ wfDebug( "$fname: CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp ; site $wgCacheEpoch\n", false );
+
+ return true;
+ } else {
+ wfDebug( "$fname: READY client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp ; site $wgCacheEpoch\n", false );
+ $this->mLastModified = $lastmod;
+ }
+ } else {
+ wfDebug( "$fname: client did not send If-Modified-Since header\n", false );
+ $this->mLastModified = $lastmod;
+ }
+ }
+
+ function loadFromMemcached( $mckey, $touched ) {
+ global $wgMemc;
+ if ( !$touched ) return false;
+
+ $mcvalue = $wgMemc->get( $mckey );
+ if ( $mcvalue ) {
+ # Check to see if the value has been invalidated
+ if ( $touched <= $mcvalue['timestamp'] ) {
+ wfDebug( "Got $mckey from cache\n" );
+ $this->mText = $mcvalue['value'];
+ return true;
+ } else {
+ wfDebug( "$mckey has expired\n" );
+ }
+ }
+
+ return false;
+ }
+
+ function storeInMemcached( $mckey, $expiry = 86400 ) {
+ global $wgMemc;
+
+ $wgMemc->set( $mckey,
+ array(
+ 'timestamp' => wfTimestampNow(),
+ 'value' => $this->mText
+ ), $expiry
+ );
+
+ return true;
+ }
+}
+?>
diff --git a/includes/Article.php b/includes/Article.php
new file mode 100644
index 000000000000..6b4f527082bc
--- /dev/null
+++ b/includes/Article.php
@@ -0,0 +1,2790 @@
+<?php
+/**
+ * File for articles
+ * @package MediaWiki
+ */
+
+/**
+ * Class representing a MediaWiki article and history.
+ *
+ * See design.txt for an overview.
+ * Note: edit user interface and cache support functions have been
+ * moved to separate EditPage and HTMLFileCache classes.
+ *
+ * @package MediaWiki
+ */
+class Article {
+ /**@{{
+ * @private
+ */
+ var $mComment; //!<
+ var $mContent; //!<
+ var $mContentLoaded; //!<
+ var $mCounter; //!<
+ var $mForUpdate; //!<
+ var $mGoodAdjustment; //!<
+ var $mLatest; //!<
+ var $mMinorEdit; //!<
+ var $mOldId; //!<
+ var $mRedirectedFrom; //!<
+ var $mRedirectUrl; //!<
+ var $mRevIdFetched; //!<
+ var $mRevision; //!<
+ var $mTimestamp; //!<
+ var $mTitle; //!<
+ var $mTotalAdjustment; //!<
+ var $mTouched; //!<
+ var $mUser; //!<
+ var $mUserText; //!<
+ /**@}}*/
+
+ /**
+ * Constructor and clear the article
+ * @param $title Reference to a Title object.
+ * @param $oldId Integer revision ID, null to fetch from request, zero for current
+ */
+ function Article( &$title, $oldId = null ) {
+ $this->mTitle =& $title;
+ $this->mOldId = $oldId;
+ $this->clear();
+ }
+
+ /**
+ * Tell the page view functions that this view was redirected
+ * from another page on the wiki.
+ * @param $from Title object.
+ */
+ function setRedirectedFrom( $from ) {
+ $this->mRedirectedFrom = $from;
+ }
+
+ /**
+ * @return mixed false, Title of in-wiki target, or string with URL
+ */
+ function followRedirect() {
+ $text = $this->getContent();
+ $rt = Title::newFromRedirect( $text );
+
+ # process if title object is valid and not special:userlogout
+ if( $rt ) {
+ if( $rt->getInterwiki() != '' ) {
+ if( $rt->isLocal() ) {
+ // Offsite wikis need an HTTP redirect.
+ //
+ // This can be hard to reverse and may produce loops,
+ // so they may be disabled in the site configuration.
+
+ $source = $this->mTitle->getFullURL( 'redirect=no' );
+ return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) );
+ }
+ } else {
+ if( $rt->getNamespace() == NS_SPECIAL ) {
+ // Gotta handle redirects to special pages differently:
+ // Fill the HTTP response "Location" header and ignore
+ // the rest of the page we're on.
+ //
+ // This can be hard to reverse, so they may be disabled.
+
+ if( $rt->isSpecial( 'Userlogout' ) ) {
+ // rolleyes
+ } else {
+ return $rt->getFullURL();
+ }
+ }
+ return $rt;
+ }
+ }
+
+ // No or invalid redirect
+ return false;
+ }
+
+ /**
+ * get the title object of the article
+ */
+ function getTitle() {
+ return $this->mTitle;
+ }
+
+ /**
+ * Clear the object
+ * @private
+ */
+ function clear() {
+ $this->mDataLoaded = false;
+ $this->mContentLoaded = false;
+
+ $this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded
+ $this->mRedirectedFrom = null; # Title object if set
+ $this->mUserText =
+ $this->mTimestamp = $this->mComment = '';
+ $this->mGoodAdjustment = $this->mTotalAdjustment = 0;
+ $this->mTouched = '19700101000000';
+ $this->mForUpdate = false;
+ $this->mIsRedirect = false;
+ $this->mRevIdFetched = 0;
+ $this->mRedirectUrl = false;
+ $this->mLatest = false;
+ }
+
+ /**
+ * Note that getContent/loadContent do not follow redirects anymore.
+ * If you need to fetch redirectable content easily, try
+ * the shortcut in Article::followContent()
+ * FIXME
+ * @todo There are still side-effects in this!
+ * In general, you should use the Revision class, not Article,
+ * to fetch text for purposes other than page views.
+ *
+ * @return Return the text of this revision
+ */
+ function getContent() {
+ global $wgUser, $wgOut;
+
+ wfProfileIn( __METHOD__ );
+
+ if ( 0 == $this->getID() ) {
+ wfProfileOut( __METHOD__ );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+ $ret = wfMsgWeirdKey ( $this->mTitle->getText() ) ;
+ } else {
+ $ret = wfMsg( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon' );
+ }
+
+ return "<div class='noarticletext'>$ret</div>";
+ } else {
+ $this->loadContent();
+ wfProfileOut( __METHOD__ );
+ return $this->mContent;
+ }
+ }
+
+ /**
+ * This function returns the text of a section, specified by a number ($section).
+ * A section is text under a heading like == Heading == or \<h1\>Heading\</h1\>, or
+ * the first section before any such heading (section 0).
+ *
+ * If a section contains subsections, these are also returned.
+ *
+ * @param $text String: text to look in
+ * @param $section Integer: section number
+ * @return string text of the requested section
+ * @deprecated
+ */
+ function getSection($text,$section) {
+ global $wgParser;
+ return $wgParser->getSection( $text, $section );
+ }
+
+ /**
+ * @return int The oldid of the article that is to be shown, 0 for the
+ * current revision
+ */
+ function getOldID() {
+ if ( is_null( $this->mOldId ) ) {
+ $this->mOldId = $this->getOldIDFromRequest();
+ }
+ return $this->mOldId;
+ }
+
+ /**
+ * Sets $this->mRedirectUrl to a correct URL if the query parameters are incorrect
+ *
+ * @return int The old id for the request
+ */
+ function getOldIDFromRequest() {
+ global $wgRequest;
+ $this->mRedirectUrl = false;
+ $oldid = $wgRequest->getVal( 'oldid' );
+ if ( isset( $oldid ) ) {
+ $oldid = intval( $oldid );
+ if ( $wgRequest->getVal( 'direction' ) == 'next' ) {
+ $nextid = $this->mTitle->getNextRevisionID( $oldid );
+ if ( $nextid ) {
+ $oldid = $nextid;
+ } else {
+ $this->mRedirectUrl = $this->mTitle->getFullURL( 'redirect=no' );
+ }
+ } elseif ( $wgRequest->getVal( 'direction' ) == 'prev' ) {
+ $previd = $this->mTitle->getPreviousRevisionID( $oldid );
+ if ( $previd ) {
+ $oldid = $previd;
+ } else {
+ # TODO
+ }
+ }
+ # unused:
+ # $lastid = $oldid;
+ }
+
+ if ( !$oldid ) {
+ $oldid = 0;
+ }
+ return $oldid;
+ }
+
+ /**
+ * Load the revision (including text) into this object
+ */
+ function loadContent() {
+ if ( $this->mContentLoaded ) return;
+
+ # Query variables :P
+ $oldid = $this->getOldID();
+
+ # Pre-fill content with error message so that if something
+ # fails we'll have something telling us what we intended.
+ $this->mOldId = $oldid;
+ $this->fetchContent( $oldid );
+ }
+
+
+ /**
+ * Fetch a page record with the given conditions
+ * @param Database $dbr
+ * @param array $conditions
+ * @private
+ */
+ function pageData( &$dbr, $conditions ) {
+ $fields = array(
+ 'page_id',
+ 'page_namespace',
+ 'page_title',
+ 'page_restrictions',
+ 'page_counter',
+ 'page_is_redirect',
+ 'page_is_new',
+ 'page_random',
+ 'page_touched',
+ 'page_latest',
+ 'page_len' ) ;
+ wfRunHooks( 'ArticlePageDataBefore', array( &$this , &$fields ) ) ;
+ $row = $dbr->selectRow( 'page',
+ $fields,
+ $conditions,
+ 'Article::pageData' );
+ wfRunHooks( 'ArticlePageDataAfter', array( &$this , &$row ) ) ;
+ return $row ;
+ }
+
+ /**
+ * @param Database $dbr
+ * @param Title $title
+ */
+ function pageDataFromTitle( &$dbr, $title ) {
+ return $this->pageData( $dbr, array(
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDBkey() ) );
+ }
+
+ /**
+ * @param Database $dbr
+ * @param int $id
+ */
+ function pageDataFromId( &$dbr, $id ) {
+ return $this->pageData( $dbr, array( 'page_id' => $id ) );
+ }
+
+ /**
+ * Set the general counter, title etc data loaded from
+ * some source.
+ *
+ * @param object $data
+ * @private
+ */
+ function loadPageData( $data = 'fromdb' ) {
+ if ( $data === 'fromdb' ) {
+ $dbr =& $this->getDB();
+ $data = $this->pageDataFromId( $dbr, $this->getId() );
+ }
+
+ $lc =& LinkCache::singleton();
+ if ( $data ) {
+ $lc->addGoodLinkObj( $data->page_id, $this->mTitle );
+
+ $this->mTitle->mArticleID = $data->page_id;
+ $this->mTitle->loadRestrictions( $data->page_restrictions );
+ $this->mTitle->mRestrictionsLoaded = true;
+
+ $this->mCounter = $data->page_counter;
+ $this->mTouched = wfTimestamp( TS_MW, $data->page_touched );
+ $this->mIsRedirect = $data->page_is_redirect;
+ $this->mLatest = $data->page_latest;
+ } else {
+ if ( is_object( $this->mTitle ) ) {
+ $lc->addBadLinkObj( $this->mTitle );
+ }
+ $this->mTitle->mArticleID = 0;
+ }
+
+ $this->mDataLoaded = true;
+ }
+
+ /**
+ * Get text of an article from database
+ * Does *NOT* follow redirects.
+ * @param int $oldid 0 for whatever the latest revision is
+ * @return string
+ */
+ function fetchContent( $oldid = 0 ) {
+ if ( $this->mContentLoaded ) {
+ return $this->mContent;
+ }
+
+ $dbr =& $this->getDB();
+
+ # Pre-fill content with error message so that if something
+ # fails we'll have something telling us what we intended.
+ $t = $this->mTitle->getPrefixedText();
+ if( $oldid ) {
+ $t .= ',oldid='.$oldid;
+ }
+ $this->mContent = wfMsg( 'missingarticle', $t ) ;
+
+ if( $oldid ) {
+ $revision = Revision::newFromId( $oldid );
+ if( is_null( $revision ) ) {
+ wfDebug( __METHOD__." failed to retrieve specified revision, id $oldid\n" );
+ return false;
+ }
+ $data = $this->pageDataFromId( $dbr, $revision->getPage() );
+ if( !$data ) {
+ wfDebug( __METHOD__." failed to get page data linked to revision id $oldid\n" );
+ return false;
+ }
+ $this->mTitle = Title::makeTitle( $data->page_namespace, $data->page_title );
+ $this->loadPageData( $data );
+ } else {
+ if( !$this->mDataLoaded ) {
+ $data = $this->pageDataFromTitle( $dbr, $this->mTitle );
+ if( !$data ) {
+ wfDebug( __METHOD__." failed to find page data for title " . $this->mTitle->getPrefixedText() . "\n" );
+ return false;
+ }
+ $this->loadPageData( $data );
+ }
+ $revision = Revision::newFromId( $this->mLatest );
+ if( is_null( $revision ) ) {
+ wfDebug( __METHOD__." failed to retrieve current page, rev_id {$data->page_latest}\n" );
+ return false;
+ }
+ }
+
+ // FIXME: Horrible, horrible! This content-loading interface just plain sucks.
+ // We should instead work with the Revision object when we need it...
+ $this->mContent = $revision->userCan( Revision::DELETED_TEXT ) ? $revision->getRawText() : "";
+ //$this->mContent = $revision->getText();
+
+ $this->mUser = $revision->getUser();
+ $this->mUserText = $revision->getUserText();
+ $this->mComment = $revision->getComment();
+ $this->mTimestamp = wfTimestamp( TS_MW, $revision->getTimestamp() );
+
+ $this->mRevIdFetched = $revision->getID();
+ $this->mContentLoaded = true;
+ $this->mRevision =& $revision;
+
+ wfRunHooks( 'ArticleAfterFetchContent', array( &$this, &$this->mContent ) ) ;
+
+ return $this->mContent;
+ }
+
+ /**
+ * Read/write accessor to select FOR UPDATE
+ *
+ * @param $x Mixed: FIXME
+ */
+ function forUpdate( $x = NULL ) {
+ return wfSetVar( $this->mForUpdate, $x );
+ }
+
+ /**
+ * Get the database which should be used for reads
+ *
+ * @return Database
+ */
+ function &getDB() {
+ $ret =& wfGetDB( DB_MASTER );
+ return $ret;
+ }
+
+ /**
+ * Get options for all SELECT statements
+ *
+ * @param $options Array: an optional options array which'll be appended to
+ * the default
+ * @return Array: options
+ */
+ function getSelectOptions( $options = '' ) {
+ if ( $this->mForUpdate ) {
+ if ( is_array( $options ) ) {
+ $options[] = 'FOR UPDATE';
+ } else {
+ $options = 'FOR UPDATE';
+ }
+ }
+ return $options;
+ }
+
+ /**
+ * @return int Page ID
+ */
+ function getID() {
+ if( $this->mTitle ) {
+ return $this->mTitle->getArticleID();
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * @return bool Whether or not the page exists in the database
+ */
+ function exists() {
+ return $this->getId() != 0;
+ }
+
+ /**
+ * @return int The view count for the page
+ */
+ function getCount() {
+ if ( -1 == $this->mCounter ) {
+ $id = $this->getID();
+ if ( $id == 0 ) {
+ $this->mCounter = 0;
+ } else {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $this->mCounter = $dbr->selectField( 'page', 'page_counter', array( 'page_id' => $id ),
+ 'Article::getCount', $this->getSelectOptions() );
+ }
+ }
+ return $this->mCounter;
+ }
+
+ /**
+ * Determine whether a page would be suitable for being counted as an
+ * article in the site_stats table based on the title & its content
+ *
+ * @param $text String: text to analyze
+ * @return bool
+ */
+ function isCountable( $text ) {
+ global $wgUseCommaCount, $wgContentNamespaces;
+
+ $token = $wgUseCommaCount ? ',' : '[[';
+ return
+ array_search( $this->mTitle->getNamespace(), $wgContentNamespaces ) !== false
+ && ! $this->isRedirect( $text )
+ && in_string( $token, $text );
+ }
+
+ /**
+ * Tests if the article text represents a redirect
+ *
+ * @param $text String: FIXME
+ * @return bool
+ */
+ function isRedirect( $text = false ) {
+ if ( $text === false ) {
+ $this->loadContent();
+ $titleObj = Title::newFromRedirect( $this->fetchContent() );
+ } else {
+ $titleObj = Title::newFromRedirect( $text );
+ }
+ return $titleObj !== NULL;
+ }
+
+ /**
+ * Returns true if the currently-referenced revision is the current edit
+ * to this page (and it exists).
+ * @return bool
+ */
+ function isCurrent() {
+ return $this->exists() &&
+ isset( $this->mRevision ) &&
+ $this->mRevision->isCurrent();
+ }
+
+ /**
+ * Loads everything except the text
+ * This isn't necessary for all uses, so it's only done if needed.
+ * @private
+ */
+ function loadLastEdit() {
+ if ( -1 != $this->mUser )
+ return;
+
+ # New or non-existent articles have no user information
+ $id = $this->getID();
+ if ( 0 == $id ) return;
+
+ $this->mLastRevision = Revision::loadFromPageId( $this->getDB(), $id );
+ if( !is_null( $this->mLastRevision ) ) {
+ $this->mUser = $this->mLastRevision->getUser();
+ $this->mUserText = $this->mLastRevision->getUserText();
+ $this->mTimestamp = $this->mLastRevision->getTimestamp();
+ $this->mComment = $this->mLastRevision->getComment();
+ $this->mMinorEdit = $this->mLastRevision->isMinor();
+ $this->mRevIdFetched = $this->mLastRevision->getID();
+ }
+ }
+
+ function getTimestamp() {
+ // Check if the field has been filled by ParserCache::get()
+ if ( !$this->mTimestamp ) {
+ $this->loadLastEdit();
+ }
+ return wfTimestamp(TS_MW, $this->mTimestamp);
+ }
+
+ function getUser() {
+ $this->loadLastEdit();
+ return $this->mUser;
+ }
+
+ function getUserText() {
+ $this->loadLastEdit();
+ return $this->mUserText;
+ }
+
+ function getComment() {
+ $this->loadLastEdit();
+ return $this->mComment;
+ }
+
+ function getMinorEdit() {
+ $this->loadLastEdit();
+ return $this->mMinorEdit;
+ }
+
+ function getRevIdFetched() {
+ $this->loadLastEdit();
+ return $this->mRevIdFetched;
+ }
+
+ /**
+ * @todo Document, fixme $offset never used.
+ * @param $limit Integer: default 0.
+ * @param $offset Integer: default 0.
+ */
+ function getContributors($limit = 0, $offset = 0) {
+ # XXX: this is expensive; cache this info somewhere.
+
+ $contribs = array();
+ $dbr =& wfGetDB( DB_SLAVE );
+ $revTable = $dbr->tableName( 'revision' );
+ $userTable = $dbr->tableName( 'user' );
+ $user = $this->getUser();
+ $pageId = $this->getId();
+
+ $sql = "SELECT rev_user, rev_user_text, user_real_name, MAX(rev_timestamp) as timestamp
+ FROM $revTable LEFT JOIN $userTable ON rev_user = user_id
+ WHERE rev_page = $pageId
+ AND rev_user != $user
+ GROUP BY rev_user, rev_user_text, user_real_name
+ ORDER BY timestamp DESC";
+
+ if ($limit > 0) { $sql .= ' LIMIT '.$limit; }
+ $sql .= ' '. $this->getSelectOptions();
+
+ $res = $dbr->query($sql, __METHOD__);
+
+ while ( $line = $dbr->fetchObject( $res ) ) {
+ $contribs[] = array($line->rev_user, $line->rev_user_text, $line->user_real_name);
+ }
+
+ $dbr->freeResult($res);
+ return $contribs;
+ }
+
+ /**
+ * This is the default action of the script: just view the page of
+ * the given title.
+ */
+ function view() {
+ global $wgUser, $wgOut, $wgRequest, $wgContLang;
+ global $wgEnableParserCache, $wgStylePath, $wgUseRCPatrol, $wgParser;
+ global $wgUseTrackbacks, $wgNamespaceRobotPolicies;
+ $sk = $wgUser->getSkin();
+
+ wfProfileIn( __METHOD__ );
+
+ $parserCache =& ParserCache::singleton();
+ $ns = $this->mTitle->getNamespace(); # shortcut
+
+ # Get variables from query string
+ $oldid = $this->getOldID();
+
+ # getOldID may want us to redirect somewhere else
+ if ( $this->mRedirectUrl ) {
+ $wgOut->redirect( $this->mRedirectUrl );
+ wfProfileOut( __METHOD__ );
+ return;
+ }
+
+ $diff = $wgRequest->getVal( 'diff' );
+ $rcid = $wgRequest->getVal( 'rcid' );
+ $rdfrom = $wgRequest->getVal( 'rdfrom' );
+
+ $wgOut->setArticleFlag( true );
+ if ( isset( $wgNamespaceRobotPolicies[$ns] ) ) {
+ $policy = $wgNamespaceRobotPolicies[$ns];
+ } else {
+ # The default policy. Dev note: make sure you change the documentation
+ # in DefaultSettings.php before changing it.
+ $policy = 'index,follow';
+ }
+ $wgOut->setRobotpolicy( $policy );
+
+ # If we got diff and oldid in the query, we want to see a
+ # diff page instead of the article.
+
+ if ( !is_null( $diff ) ) {
+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+
+ $de = new DifferenceEngine( $this->mTitle, $oldid, $diff, $rcid );
+ // DifferenceEngine directly fetched the revision:
+ $this->mRevIdFetched = $de->mNewid;
+ $de->showDiffPage();
+
+ // Needed to get the page's current revision
+ $this->loadPageData();
+ if( $diff == 0 || $diff == $this->mLatest ) {
+ # Run view updates for current revision only
+ $this->viewUpdates();
+ }
+ wfProfileOut( __METHOD__ );
+ return;
+ }
+
+ if ( empty( $oldid ) && $this->checkTouched() ) {
+ $wgOut->setETag($parserCache->getETag($this, $wgUser));
+
+ if( $wgOut->checkLastModified( $this->mTouched ) ){
+ wfProfileOut( __METHOD__ );
+ return;
+ } else if ( $this->tryFileCache() ) {
+ # tell wgOut that output is taken care of
+ $wgOut->disable();
+ $this->viewUpdates();
+ wfProfileOut( __METHOD__ );
+ return;
+ }
+ }
+
+ # Should the parser cache be used?
+ $pcache = $wgEnableParserCache &&
+ intval( $wgUser->getOption( 'stubthreshold' ) ) == 0 &&
+ $this->exists() &&
+ empty( $oldid );
+ wfDebug( 'Article::view using parser cache: ' . ($pcache ? 'yes' : 'no' ) . "\n" );
+ if ( $wgUser->getOption( 'stubthreshold' ) ) {
+ wfIncrStats( 'pcache_miss_stub' );
+ }
+
+ $wasRedirected = false;
+ if ( isset( $this->mRedirectedFrom ) ) {
+ // This is an internally redirected page view.
+ // We'll need a backlink to the source page for navigation.
+ if ( wfRunHooks( 'ArticleViewRedirect', array( &$this ) ) ) {
+ $sk = $wgUser->getSkin();
+ $redir = $sk->makeKnownLinkObj( $this->mRedirectedFrom, '', 'redirect=no' );
+ $s = wfMsg( 'redirectedfrom', $redir );
+ $wgOut->setSubtitle( $s );
+
+ // Set the fragment if one was specified in the redirect
+ if ( strval( $this->mTitle->getFragment() ) != '' ) {
+ $fragment = Xml::escapeJsString( $this->mTitle->getFragmentForURL() );
+ $wgOut->addInlineScript( "redirectToFragment(\"$fragment\");" );
+ }
+ $wasRedirected = true;
+ }
+ } elseif ( !empty( $rdfrom ) ) {
+ // This is an externally redirected view, from some other wiki.
+ // If it was reported from a trusted site, supply a backlink.
+ global $wgRedirectSources;
+ if( $wgRedirectSources && preg_match( $wgRedirectSources, $rdfrom ) ) {
+ $sk = $wgUser->getSkin();
+ $redir = $sk->makeExternalLink( $rdfrom, $rdfrom );
+ $s = wfMsg( 'redirectedfrom', $redir );
+ $wgOut->setSubtitle( $s );
+ $wasRedirected = true;
+ }
+ }
+
+ $outputDone = false;
+ if ( $pcache ) {
+ if ( $wgOut->tryParserCache( $this, $wgUser ) ) {
+ wfRunHooks( 'ArticleViewHeader', array( &$this ) );
+ $outputDone = true;
+ }
+ }
+ if ( !$outputDone ) {
+ $text = $this->getContent();
+ if ( $text === false ) {
+ # Failed to load, replace text with error message
+ $t = $this->mTitle->getPrefixedText();
+ if( $oldid ) {
+ $t .= ',oldid='.$oldid;
+ $text = wfMsg( 'missingarticle', $t );
+ } else {
+ $text = wfMsg( 'noarticletext', $t );
+ }
+ }
+
+ # Another whitelist check in case oldid is altering the title
+ if ( !$this->mTitle->userCanRead() ) {
+ $wgOut->loginToUse();
+ $wgOut->output();
+ exit;
+ }
+
+ # We're looking at an old revision
+
+ if ( !empty( $oldid ) ) {
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ if( is_null( $this->mRevision ) ) {
+ // FIXME: This would be a nice place to load the 'no such page' text.
+ } else {
+ $this->setOldSubtitle( isset($this->mOldId) ? $this->mOldId : $oldid );
+ if( $this->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
+ if( !$this->mRevision->userCan( Revision::DELETED_TEXT ) ) {
+ $wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) );
+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ return;
+ } else {
+ $wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) );
+ // and we are allowed to see...
+ }
+ }
+ }
+
+ }
+ }
+ if( !$outputDone ) {
+ /**
+ * @fixme: this hook doesn't work most of the time, as it doesn't
+ * trigger when the parser cache is used.
+ */
+ wfRunHooks( 'ArticleViewHeader', array( &$this ) ) ;
+ $wgOut->setRevisionId( $this->getRevIdFetched() );
+ # wrap user css and user js in pre and don't parse
+ # XXX: use $this->mTitle->usCssJsSubpage() when php is fixed/ a workaround is found
+ if (
+ $ns == NS_USER &&
+ preg_match('/\\/[\\w]+\\.(css|js)$/', $this->mTitle->getDBkey())
+ ) {
+ $wgOut->addWikiText( wfMsg('clearyourcache'));
+ $wgOut->addHTML( '<pre>'.htmlspecialchars($this->mContent)."\n</pre>" );
+ } else if ( $rt = Title::newFromRedirect( $text ) ) {
+ # Display redirect
+ $imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
+ $imageUrl = $wgStylePath.'/common/images/redirect' . $imageDir . '.png';
+ # Don't overwrite the subtitle if this was an old revision
+ if( !$wasRedirected && $this->isCurrent() ) {
+ $wgOut->setSubtitle( wfMsgHtml( 'redirectpagesub' ) );
+ }
+ $link = $sk->makeLinkObj( $rt, $rt->getFullText() );
+
+ $wgOut->addHTML( '<img src="'.$imageUrl.'" alt="#REDIRECT " />' .
+ '<span class="redirectText">'.$link.'</span>' );
+
+ $parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser));
+ $wgOut->addParserOutputNoText( $parseout );
+ } else if ( $pcache ) {
+ # Display content and save to parser cache
+ $wgOut->addPrimaryWikiText( $text, $this );
+ } else {
+ # Display content, don't attempt to save to parser cache
+ # Don't show section-edit links on old revisions... this way lies madness.
+ if( !$this->isCurrent() ) {
+ $oldEditSectionSetting = $wgOut->parserOptions()->setEditSection( false );
+ }
+ # Display content and don't save to parser cache
+ $wgOut->addPrimaryWikiText( $text, $this, false );
+
+ if( !$this->isCurrent() ) {
+ $wgOut->parserOptions()->setEditSection( $oldEditSectionSetting );
+ }
+ }
+ }
+ /* title may have been set from the cache */
+ $t = $wgOut->getPageTitle();
+ if( empty( $t ) ) {
+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ }
+
+ # check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
+ if( $ns == NS_USER_TALK &&
+ User::isIP( $this->mTitle->getText() ) ) {
+ $wgOut->addWikiText( wfMsg('anontalkpagetext') );
+ }
+
+ # If we have been passed an &rcid= parameter, we want to give the user a
+ # chance to mark this new article as patrolled.
+ if ( $wgUseRCPatrol && !is_null( $rcid ) && $rcid != 0 && $wgUser->isAllowed( 'patrol' ) ) {
+ $wgOut->addHTML(
+ "<div class='patrollink'>" .
+ wfMsg ( 'markaspatrolledlink',
+ $sk->makeKnownLinkObj( $this->mTitle, wfMsg('markaspatrolledtext'), "action=markpatrolled&rcid=$rcid" )
+ ) .
+ '</div>'
+ );
+ }
+
+ # Trackbacks
+ if ($wgUseTrackbacks)
+ $this->addTrackbacks();
+
+ $this->viewUpdates();
+ wfProfileOut( __METHOD__ );
+ }
+
+ function addTrackbacks() {
+ global $wgOut, $wgUser;
+
+ $dbr =& wfGetDB(DB_SLAVE);
+ $tbs = $dbr->select(
+ /* FROM */ 'trackbacks',
+ /* SELECT */ array('tb_id', 'tb_title', 'tb_url', 'tb_ex', 'tb_name'),
+ /* WHERE */ array('tb_page' => $this->getID())
+ );
+
+ if (!$dbr->numrows($tbs))
+ return;
+
+ $tbtext = "";
+ while ($o = $dbr->fetchObject($tbs)) {
+ $rmvtxt = "";
+ if ($wgUser->isAllowed( 'trackback' )) {
+ $delurl = $this->mTitle->getFullURL("action=deletetrackback&tbid="
+ . $o->tb_id . "&token=" . $wgUser->editToken());
+ $rmvtxt = wfMsg('trackbackremove', $delurl);
+ }
+ $tbtext .= wfMsg(strlen($o->tb_ex) ? 'trackbackexcerpt' : 'trackback',
+ $o->tb_title,
+ $o->tb_url,
+ $o->tb_ex,
+ $o->tb_name,
+ $rmvtxt);
+ }
+ $wgOut->addWikitext(wfMsg('trackbackbox', $tbtext));
+ }
+
+ function deletetrackback() {
+ global $wgUser, $wgRequest, $wgOut, $wgTitle;
+
+ if (!$wgUser->matchEditToken($wgRequest->getVal('token'))) {
+ $wgOut->addWikitext(wfMsg('sessionfailure'));
+ return;
+ }
+
+ if ((!$wgUser->isAllowed('delete'))) {
+ $wgOut->permissionRequired( 'delete' );
+ return;
+ }
+
+ if (wfReadOnly()) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+
+ $db =& wfGetDB(DB_MASTER);
+ $db->delete('trackbacks', array('tb_id' => $wgRequest->getInt('tbid')));
+ $wgTitle->invalidateCache();
+ $wgOut->addWikiText(wfMsg('trackbackdeleteok'));
+ }
+
+ function render() {
+ global $wgOut;
+
+ $wgOut->setArticleBodyOnly(true);
+ $this->view();
+ }
+
+ /**
+ * Handle action=purge
+ */
+ function purge() {
+ global $wgUser, $wgRequest, $wgOut;
+
+ if ( $wgUser->isLoggedIn() || $wgRequest->wasPosted() ) {
+ if( wfRunHooks( 'ArticlePurge', array( &$this ) ) ) {
+ $this->doPurge();
+ }
+ } else {
+ $msg = $wgOut->parse( wfMsg( 'confirm_purge' ) );
+ $action = $this->mTitle->escapeLocalURL( 'action=purge' );
+ $button = htmlspecialchars( wfMsg( 'confirm_purge_button' ) );
+ $msg = str_replace( '$1',
+ "<form method=\"post\" action=\"$action\">\n" .
+ "<input type=\"submit\" name=\"submit\" value=\"$button\" />\n" .
+ "</form>\n", $msg );
+
+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->addHTML( $msg );
+ }
+ }
+
+ /**
+ * Perform the actions of a page purging
+ */
+ function doPurge() {
+ global $wgUseSquid;
+ // Invalidate the cache
+ $this->mTitle->invalidateCache();
+
+ if ( $wgUseSquid ) {
+ // Commit the transaction before the purge is sent
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->immediateCommit();
+
+ // Send purge
+ $update = SquidUpdate::newSimplePurge( $this->mTitle );
+ $update->doUpdate();
+ }
+ $this->view();
+ }
+
+ /**
+ * Insert a new empty page record for this article.
+ * This *must* be followed up by creating a revision
+ * and running $this->updateToLatest( $rev_id );
+ * or else the record will be left in a funky state.
+ * Best if all done inside a transaction.
+ *
+ * @param Database $dbw
+ * @param string $restrictions
+ * @return int The newly created page_id key
+ * @private
+ */
+ function insertOn( &$dbw, $restrictions = '' ) {
+ wfProfileIn( __METHOD__ );
+
+ $page_id = $dbw->nextSequenceValue( 'page_page_id_seq' );
+ $dbw->insert( 'page', array(
+ 'page_id' => $page_id,
+ 'page_namespace' => $this->mTitle->getNamespace(),
+ 'page_title' => $this->mTitle->getDBkey(),
+ 'page_counter' => 0,
+ 'page_restrictions' => $restrictions,
+ 'page_is_redirect' => 0, # Will set this shortly...
+ 'page_is_new' => 1,
+ 'page_random' => wfRandom(),
+ 'page_touched' => $dbw->timestamp(),
+ 'page_latest' => 0, # Fill this in shortly...
+ 'page_len' => 0, # Fill this in shortly...
+ ), __METHOD__ );
+ $newid = $dbw->insertId();
+
+ $this->mTitle->resetArticleId( $newid );
+
+ wfProfileOut( __METHOD__ );
+ return $newid;
+ }
+
+ /**
+ * Update the page record to point to a newly saved revision.
+ *
+ * @param Database $dbw
+ * @param Revision $revision For ID number, and text used to set
+ length and redirect status fields
+ * @param int $lastRevision If given, will not overwrite the page field
+ * when different from the currently set value.
+ * Giving 0 indicates the new page flag should
+ * be set on.
+ * @param bool $lastRevIsRedirect If given, will optimize adding and
+ * removing rows in redirect table.
+ * @return bool true on success, false on failure
+ * @private
+ */
+ function updateRevisionOn( &$dbw, $revision, $lastRevision = null, $lastRevIsRedirect = null ) {
+ wfProfileIn( __METHOD__ );
+
+ $text = $revision->getText();
+ $rt = Title::newFromRedirect( $text );
+
+ $conditions = array( 'page_id' => $this->getId() );
+ if( !is_null( $lastRevision ) ) {
+ # An extra check against threads stepping on each other
+ $conditions['page_latest'] = $lastRevision;
+ }
+
+ $dbw->update( 'page',
+ array( /* SET */
+ 'page_latest' => $revision->getId(),
+ 'page_touched' => $dbw->timestamp(),
+ 'page_is_new' => ($lastRevision === 0) ? 1 : 0,
+ 'page_is_redirect' => $rt !== NULL ? 1 : 0,
+ 'page_len' => strlen( $text ),
+ ),
+ $conditions,
+ __METHOD__ );
+
+ $result = $dbw->affectedRows() != 0;
+
+ if ($result) {
+ // FIXME: Should the result from updateRedirectOn() be returned instead?
+ $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect );
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $result;
+ }
+
+ /**
+ * Add row to the redirect table if this is a redirect, remove otherwise.
+ *
+ * @param Database $dbw
+ * @param $redirectTitle a title object pointing to the redirect target,
+ * or NULL if this is not a redirect
+ * @param bool $lastRevIsRedirect If given, will optimize adding and
+ * removing rows in redirect table.
+ * @return bool true on success, false on failure
+ * @private
+ */
+ function updateRedirectOn( &$dbw, $redirectTitle, $lastRevIsRedirect = null ) {
+
+ // Always update redirects (target link might have changed)
+ // Update/Insert if we don't know if the last revision was a redirect or not
+ // Delete if changing from redirect to non-redirect
+ $isRedirect = !is_null($redirectTitle);
+ if ($isRedirect || is_null($lastRevIsRedirect) || $lastRevIsRedirect !== $isRedirect) {
+
+ wfProfileIn( __METHOD__ );
+
+ if ($isRedirect) {
+
+ // This title is a redirect, Add/Update row in the redirect table
+ $set = array( /* SET */
+ 'rd_namespace' => $redirectTitle->getNamespace(),
+ 'rd_title' => $redirectTitle->getDBkey(),
+ 'rd_from' => $this->getId(),
+ );
+
+ $dbw->replace( 'redirect', array( 'rd_from' ), $set, __METHOD__ );
+ } else {
+ // This is not a redirect, remove row from redirect table
+ $where = array( 'rd_from' => $this->getId() );
+ $dbw->delete( 'redirect', $where, __METHOD__);
+ }
+
+ wfProfileOut( __METHOD__ );
+ return ( $dbw->affectedRows() != 0 );
+ }
+
+ return true;
+ }
+
+ /**
+ * If the given revision is newer than the currently set page_latest,
+ * update the page record. Otherwise, do nothing.
+ *
+ * @param Database $dbw
+ * @param Revision $revision
+ */
+ function updateIfNewerOn( &$dbw, $revision ) {
+ wfProfileIn( __METHOD__ );
+
+ $row = $dbw->selectRow(
+ array( 'revision', 'page' ),
+ array( 'rev_id', 'rev_timestamp', 'page_is_redirect' ),
+ array(
+ 'page_id' => $this->getId(),
+ 'page_latest=rev_id' ),
+ __METHOD__ );
+ if( $row ) {
+ if( wfTimestamp(TS_MW, $row->rev_timestamp) >= $revision->getTimestamp() ) {
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+ $prev = $row->rev_id;
+ $lastRevIsRedirect = (bool)$row->page_is_redirect;
+ } else {
+ # No or missing previous revision; mark the page as new
+ $prev = 0;
+ $lastRevIsRedirect = null;
+ }
+
+ $ret = $this->updateRevisionOn( $dbw, $revision, $prev, $lastRevIsRedirect );
+ wfProfileOut( __METHOD__ );
+ return $ret;
+ }
+
+ /**
+ * @return string Complete article text, or null if error
+ */
+ function replaceSection($section, $text, $summary = '', $edittime = NULL) {
+ wfProfileIn( __METHOD__ );
+
+ if( $section == '' ) {
+ // Whole-page edit; let the text through unmolested.
+ } else {
+ if( is_null( $edittime ) ) {
+ $rev = Revision::newFromTitle( $this->mTitle );
+ } else {
+ $dbw =& wfGetDB( DB_MASTER );
+ $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
+ }
+ if( is_null( $rev ) ) {
+ wfDebug( "Article::replaceSection asked for bogus section (page: " .
+ $this->getId() . "; section: $section; edittime: $edittime)\n" );
+ return null;
+ }
+ $oldtext = $rev->getText();
+
+ if( $section == 'new' ) {
+ # Inserting a new section
+ $subject = $summary ? "== {$summary} ==\n\n" : '';
+ $text = strlen( trim( $oldtext ) ) > 0
+ ? "{$oldtext}\n\n{$subject}{$text}"
+ : "{$subject}{$text}";
+ } else {
+ # Replacing an existing section; roll out the big guns
+ global $wgParser;
+ $text = $wgParser->replaceSection( $oldtext, $section, $text );
+ }
+
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * @deprecated use Article::doEdit()
+ */
+ function insertNewArticle( $text, $summary, $isminor, $watchthis, $suppressRC=false, $comment=false ) {
+ $flags = EDIT_NEW | EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY |
+ ( $isminor ? EDIT_MINOR : 0 ) |
+ ( $suppressRC ? EDIT_SUPPRESS_RC : 0 );
+
+ # If this is a comment, add the summary as headline
+ if ( $comment && $summary != "" ) {
+ $text = "== {$summary} ==\n\n".$text;
+ }
+
+ $this->doEdit( $text, $summary, $flags );
+
+ $dbw =& wfGetDB( DB_MASTER );
+ if ($watchthis) {
+ if (!$this->mTitle->userIsWatching()) {
+ $dbw->begin();
+ $this->doWatch();
+ $dbw->commit();
+ }
+ } else {
+ if ( $this->mTitle->userIsWatching() ) {
+ $dbw->begin();
+ $this->doUnwatch();
+ $dbw->commit();
+ }
+ }
+ $this->doRedirect( $this->isRedirect( $text ) );
+ }
+
+ /**
+ * @deprecated use Article::doEdit()
+ */
+ function updateArticle( $text, $summary, $minor, $watchthis, $forceBot = false, $sectionanchor = '' ) {
+ $flags = EDIT_UPDATE | EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY |
+ ( $minor ? EDIT_MINOR : 0 ) |
+ ( $forceBot ? EDIT_FORCE_BOT : 0 );
+
+ $good = $this->doEdit( $text, $summary, $flags );
+ if ( $good ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ if ($watchthis) {
+ if (!$this->mTitle->userIsWatching()) {
+ $dbw->begin();
+ $this->doWatch();
+ $dbw->commit();
+ }
+ } else {
+ if ( $this->mTitle->userIsWatching() ) {
+ $dbw->begin();
+ $this->doUnwatch();
+ $dbw->commit();
+ }
+ }
+
+ $this->doRedirect( $this->isRedirect( $text ), $sectionanchor );
+ }
+ return $good;
+ }
+
+ /**
+ * Article::doEdit()
+ *
+ * Change an existing article or create a new article. Updates RC and all necessary caches,
+ * optionally via the deferred update array.
+ *
+ * $wgUser must be set before calling this function.
+ *
+ * @param string $text New text
+ * @param string $summary Edit summary
+ * @param integer $flags bitfield:
+ * EDIT_NEW
+ * Article is known or assumed to be non-existent, create a new one
+ * EDIT_UPDATE
+ * Article is known or assumed to be pre-existing, update it
+ * EDIT_MINOR
+ * Mark this edit minor, if the user is allowed to do so
+ * EDIT_SUPPRESS_RC
+ * Do not log the change in recentchanges
+ * EDIT_FORCE_BOT
+ * Mark the edit a "bot" edit regardless of user rights
+ * EDIT_DEFER_UPDATES
+ * Defer some of the updates until the end of index.php
+ * EDIT_AUTOSUMMARY
+ * Fill in blank summaries with generated text where possible
+ *
+ * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected.
+ * If EDIT_UPDATE is specified and the article doesn't exist, the function will return false. If
+ * EDIT_NEW is specified and the article does exist, a duplicate key error will cause an exception
+ * to be thrown from the Database. These two conditions are also possible with auto-detection due
+ * to MediaWiki's performance-optimised locking strategy.
+ *
+ * @return bool success
+ */
+ function doEdit( $text, $summary, $flags = 0 ) {
+ global $wgUser, $wgDBtransactions;
+
+ wfProfileIn( __METHOD__ );
+ $good = true;
+
+ if ( !($flags & EDIT_NEW) && !($flags & EDIT_UPDATE) ) {
+ $aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
+ if ( $aid ) {
+ $flags |= EDIT_UPDATE;
+ } else {
+ $flags |= EDIT_NEW;
+ }
+ }
+
+ if( !wfRunHooks( 'ArticleSave', array( &$this, &$wgUser, &$text,
+ &$summary, $flags & EDIT_MINOR,
+ null, null, &$flags ) ) )
+ {
+ wfDebug( __METHOD__ . ": ArticleSave hook aborted save!\n" );
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+
+ # Silently ignore EDIT_MINOR if not allowed
+ $isminor = ( $flags & EDIT_MINOR ) && $wgUser->isAllowed('minoredit');
+ $bot = $wgUser->isAllowed( 'bot' ) || ( $flags & EDIT_FORCE_BOT );
+
+ $oldtext = $this->getContent();
+ $oldsize = strlen( $oldtext );
+
+ # Provide autosummaries if one is not provided.
+ if ($flags & EDIT_AUTOSUMMARY && $summary == '')
+ $summary = $this->getAutosummary( $oldtext, $text, $flags );
+
+ $text = $this->preSaveTransform( $text );
+ $newsize = strlen( $text );
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $now = wfTimestampNow();
+
+ if ( $flags & EDIT_UPDATE ) {
+ # Update article, but only if changed.
+
+ # Make sure the revision is either completely inserted or not inserted at all
+ if( !$wgDBtransactions ) {
+ $userAbort = ignore_user_abort( true );
+ }
+
+ $lastRevision = 0;
+ $revisionId = 0;
+
+ if ( 0 != strcmp( $text, $oldtext ) ) {
+ $this->mGoodAdjustment = (int)$this->isCountable( $text )
+ - (int)$this->isCountable( $oldtext );
+ $this->mTotalAdjustment = 0;
+
+ $lastRevision = $dbw->selectField(
+ 'page', 'page_latest', array( 'page_id' => $this->getId() ) );
+
+ if ( !$lastRevision ) {
+ # Article gone missing
+ wfDebug( __METHOD__.": EDIT_UPDATE specified but article doesn't exist\n" );
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+
+ $revision = new Revision( array(
+ 'page' => $this->getId(),
+ 'comment' => $summary,
+ 'minor_edit' => $isminor,
+ 'text' => $text
+ ) );
+
+ $dbw->begin();
+ $revisionId = $revision->insertOn( $dbw );
+
+ # Update page
+ $ok = $this->updateRevisionOn( $dbw, $revision, $lastRevision );
+
+ if( !$ok ) {
+ /* Belated edit conflict! Run away!! */
+ $good = false;
+ $dbw->rollback();
+ } else {
+ # Update recentchanges
+ if( !( $flags & EDIT_SUPPRESS_RC ) ) {
+ $rcid = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $wgUser, $summary,
+ $lastRevision, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
+ $revisionId );
+
+ # Mark as patrolled if the user can do so
+ if( $wgUser->isAllowed( 'autopatrol' ) ) {
+ RecentChange::markPatrolled( $rcid );
+ }
+ }
+ $wgUser->incEditCount();
+ $dbw->commit();
+ }
+ } else {
+ // Keep the same revision ID, but do some updates on it
+ $revisionId = $this->getRevIdFetched();
+ // Update page_touched, this is usually implicit in the page update
+ // Other cache updates are done in onArticleEdit()
+ $this->mTitle->invalidateCache();
+ }
+
+ if( !$wgDBtransactions ) {
+ ignore_user_abort( $userAbort );
+ }
+
+ if ( $good ) {
+ # Invalidate cache of this article and all pages using this article
+ # as a template. Partly deferred.
+ Article::onArticleEdit( $this->mTitle );
+
+ # Update links tables, site stats, etc.
+ $changed = ( strcmp( $oldtext, $text ) != 0 );
+ $this->editUpdates( $text, $summary, $isminor, $now, $revisionId, $changed );
+ }
+ } else {
+ # Create new article
+
+ # Set statistics members
+ # We work out if it's countable after PST to avoid counter drift
+ # when articles are created with {{subst:}}
+ $this->mGoodAdjustment = (int)$this->isCountable( $text );
+ $this->mTotalAdjustment = 1;
+
+ $dbw->begin();
+
+ # Add the page record; stake our claim on this title!
+ # This will fail with a database query exception if the article already exists
+ $newid = $this->insertOn( $dbw );
+
+ # Save the revision text...
+ $revision = new Revision( array(
+ 'page' => $newid,
+ 'comment' => $summary,
+ 'minor_edit' => $isminor,
+ 'text' => $text
+ ) );
+ $revisionId = $revision->insertOn( $dbw );
+
+ $this->mTitle->resetArticleID( $newid );
+
+ # Update the page record with revision data
+ $this->updateRevisionOn( $dbw, $revision, 0 );
+
+ if( !( $flags & EDIT_SUPPRESS_RC ) ) {
+ $rcid = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary, $bot,
+ '', strlen( $text ), $revisionId );
+ # Mark as patrolled if the user can
+ if( $wgUser->isAllowed( 'autopatrol' ) ) {
+ RecentChange::markPatrolled( $rcid );
+ }
+ }
+ $wgUser->incEditCount();
+ $dbw->commit();
+
+ # Update links, etc.
+ $this->editUpdates( $text, $summary, $isminor, $now, $revisionId, true );
+
+ # Clear caches
+ Article::onArticleCreate( $this->mTitle );
+
+ wfRunHooks( 'ArticleInsertComplete', array( &$this, &$wgUser, $text,
+ $summary, $flags & EDIT_MINOR,
+ null, null, &$flags ) );
+ }
+
+ if ( $good && !( $flags & EDIT_DEFER_UPDATES ) ) {
+ wfDoUpdates();
+ }
+
+ wfRunHooks( 'ArticleSaveComplete',
+ array( &$this, &$wgUser, $text,
+ $summary, $flags & EDIT_MINOR,
+ null, null, &$flags ) );
+
+ wfProfileOut( __METHOD__ );
+ return $good;
+ }
+
+ /**
+ * @deprecated wrapper for doRedirect
+ */
+ function showArticle( $text, $subtitle , $sectionanchor = '', $me2, $now, $summary, $oldid ) {
+ $this->doRedirect( $this->isRedirect( $text ), $sectionanchor );
+ }
+
+ /**
+ * Output a redirect back to the article.
+ * This is typically used after an edit.
+ *
+ * @param boolean $noRedir Add redirect=no
+ * @param string $sectionAnchor section to redirect to, including "#"
+ */
+ function doRedirect( $noRedir = false, $sectionAnchor = '' ) {
+ global $wgOut;
+ if ( $noRedir ) {
+ $query = 'redirect=no';
+ } else {
+ $query = '';
+ }
+ $wgOut->redirect( $this->mTitle->getFullURL( $query ) . $sectionAnchor );
+ }
+
+ /**
+ * Mark this particular edit as patrolled
+ */
+ function markpatrolled() {
+ global $wgOut, $wgRequest, $wgUseRCPatrol, $wgUser;
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+
+ # Check RC patrol config. option
+ if( !$wgUseRCPatrol ) {
+ $wgOut->errorPage( 'rcpatroldisabled', 'rcpatroldisabledtext' );
+ return;
+ }
+
+ # Check permissions
+ if( !$wgUser->isAllowed( 'patrol' ) ) {
+ $wgOut->permissionRequired( 'patrol' );
+ return;
+ }
+
+ # If we haven't been given an rc_id value, we can't do anything
+ $rcid = $wgRequest->getVal( 'rcid' );
+ if( !$rcid ) {
+ $wgOut->errorPage( 'markedaspatrollederror', 'markedaspatrollederrortext' );
+ return;
+ }
+
+ # Handle the 'MarkPatrolled' hook
+ if( !wfRunHooks( 'MarkPatrolled', array( $rcid, &$wgUser, false ) ) ) {
+ return;
+ }
+
+ $return = SpecialPage::getTitleFor( 'Recentchanges' );
+ # If it's left up to us, check that the user is allowed to patrol this edit
+ # If the user has the "autopatrol" right, then we'll assume there are no
+ # other conditions stopping them doing so
+ if( !$wgUser->isAllowed( 'autopatrol' ) ) {
+ $rc = RecentChange::newFromId( $rcid );
+ # Graceful error handling, as we've done before here...
+ # (If the recent change doesn't exist, then it doesn't matter whether
+ # the user is allowed to patrol it or not; nothing is going to happen
+ if( is_object( $rc ) && $wgUser->getName() == $rc->getAttribute( 'rc_user_text' ) ) {
+ # The user made this edit, and can't patrol it
+ # Tell them so, and then back off
+ $wgOut->setPageTitle( wfMsg( 'markedaspatrollederror' ) );
+ $wgOut->addWikiText( wfMsgNoTrans( 'markedaspatrollederror-noautopatrol' ) );
+ $wgOut->returnToMain( false, $return );
+ return;
+ }
+ }
+
+ # Mark the edit as patrolled
+ RecentChange::markPatrolled( $rcid );
+ wfRunHooks( 'MarkPatrolledComplete', array( &$rcid, &$wgUser, false ) );
+
+ # Inform the user
+ $wgOut->setPageTitle( wfMsg( 'markedaspatrolled' ) );
+ $wgOut->addWikiText( wfMsgNoTrans( 'markedaspatrolledtext' ) );
+ $wgOut->returnToMain( false, $return );
+ }
+
+ /**
+ * User-interface handler for the "watch" action
+ */
+
+ function watch() {
+
+ global $wgUser, $wgOut;
+
+ if ( $wgUser->isAnon() ) {
+ $wgOut->showErrorPage( 'watchnologin', 'watchnologintext' );
+ return;
+ }
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+
+ if( $this->doWatch() ) {
+ $wgOut->setPagetitle( wfMsg( 'addedwatch' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ $link = wfEscapeWikiText( $this->mTitle->getPrefixedText() );
+ $text = wfMsg( 'addedwatchtext', $link );
+ $wgOut->addWikiText( $text );
+ }
+
+ $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() );
+ }
+
+ /**
+ * Add this page to $wgUser's watchlist
+ * @return bool true on successful watch operation
+ */
+ function doWatch() {
+ global $wgUser;
+ if( $wgUser->isAnon() ) {
+ return false;
+ }
+
+ if (wfRunHooks('WatchArticle', array(&$wgUser, &$this))) {
+ $wgUser->addWatch( $this->mTitle );
+
+ return wfRunHooks('WatchArticleComplete', array(&$wgUser, &$this));
+ }
+
+ return false;
+ }
+
+ /**
+ * User interface handler for the "unwatch" action.
+ */
+ function unwatch() {
+
+ global $wgUser, $wgOut;
+
+ if ( $wgUser->isAnon() ) {
+ $wgOut->showErrorPage( 'watchnologin', 'watchnologintext' );
+ return;
+ }
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+
+ if( $this->doUnwatch() ) {
+ $wgOut->setPagetitle( wfMsg( 'removedwatch' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ $link = wfEscapeWikiText( $this->mTitle->getPrefixedText() );
+ $text = wfMsg( 'removedwatchtext', $link );
+ $wgOut->addWikiText( $text );
+ }
+
+ $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() );
+ }
+
+ /**
+ * Stop watching a page
+ * @return bool true on successful unwatch
+ */
+ function doUnwatch() {
+ global $wgUser;
+ if( $wgUser->isAnon() ) {
+ return false;
+ }
+
+ if (wfRunHooks('UnwatchArticle', array(&$wgUser, &$this))) {
+ $wgUser->removeWatch( $this->mTitle );
+
+ return wfRunHooks('UnwatchArticleComplete', array(&$wgUser, &$this));
+ }
+
+ return false;
+ }
+
+ /**
+ * action=protect handler
+ */
+ function protect() {
+ $form = new ProtectionForm( $this );
+ $form->show();
+ }
+
+ /**
+ * action=unprotect handler (alias)
+ */
+ function unprotect() {
+ $this->protect();
+ }
+
+ /**
+ * Update the article's restriction field, and leave a log entry.
+ *
+ * @param array $limit set of restriction keys
+ * @param string $reason
+ * @return bool true on success
+ */
+ function updateRestrictions( $limit = array(), $reason = '' ) {
+ global $wgUser, $wgRestrictionTypes, $wgContLang;
+
+ $id = $this->mTitle->getArticleID();
+ if( !$wgUser->isAllowed( 'protect' ) || wfReadOnly() || $id == 0 ) {
+ return false;
+ }
+
+ # FIXME: Same limitations as described in ProtectionForm.php (line 37);
+ # we expect a single selection, but the schema allows otherwise.
+ $current = array();
+ foreach( $wgRestrictionTypes as $action )
+ $current[$action] = implode( '', $this->mTitle->getRestrictions( $action ) );
+
+ $current = Article::flattenRestrictions( $current );
+ $updated = Article::flattenRestrictions( $limit );
+
+ $changed = ( $current != $updated );
+ $protect = ( $updated != '' );
+
+ # If nothing's changed, do nothing
+ if( $changed ) {
+ if( wfRunHooks( 'ArticleProtect', array( &$this, &$wgUser, $limit, $reason ) ) ) {
+
+ $dbw =& wfGetDB( DB_MASTER );
+
+ # Prepare a null revision to be added to the history
+ $comment = $wgContLang->ucfirst( wfMsgForContent( $protect ? 'protectedarticle' : 'unprotectedarticle', $this->mTitle->getPrefixedText() ) );
+ if( $reason )
+ $comment .= ": $reason";
+ if( $protect )
+ $comment .= " [$updated]";
+ $nullRevision = Revision::newNullRevision( $dbw, $id, $comment, true );
+ $nullRevId = $nullRevision->insertOn( $dbw );
+
+ # Update page record
+ $dbw->update( 'page',
+ array( /* SET */
+ 'page_touched' => $dbw->timestamp(),
+ 'page_restrictions' => $updated,
+ 'page_latest' => $nullRevId
+ ), array( /* WHERE */
+ 'page_id' => $id
+ ), 'Article::protect'
+ );
+ wfRunHooks( 'ArticleProtectComplete', array( &$this, &$wgUser, $limit, $reason ) );
+
+ # Update the protection log
+ $log = new LogPage( 'protect' );
+ if( $protect ) {
+ $log->addEntry( 'protect', $this->mTitle, trim( $reason . " [$updated]" ) );
+ } else {
+ $log->addEntry( 'unprotect', $this->mTitle, $reason );
+ }
+
+ } # End hook
+ } # End "changed" check
+
+ return true;
+ }
+
+ /**
+ * Take an array of page restrictions and flatten it to a string
+ * suitable for insertion into the page_restrictions field.
+ * @param array $limit
+ * @return string
+ * @private
+ */
+ function flattenRestrictions( $limit ) {
+ if( !is_array( $limit ) ) {
+ throw new MWException( 'Article::flattenRestrictions given non-array restriction set' );
+ }
+ $bits = array();
+ ksort( $limit );
+ foreach( $limit as $action => $restrictions ) {
+ if( $restrictions != '' ) {
+ $bits[] = "$action=$restrictions";
+ }
+ }
+ return implode( ':', $bits );
+ }
+
+ /*
+ * UI entry point for page deletion
+ */
+ function delete() {
+ global $wgUser, $wgOut, $wgRequest;
+ $confirm = $wgRequest->wasPosted() &&
+ $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
+ $reason = $wgRequest->getText( 'wpReason' );
+
+ # This code desperately needs to be totally rewritten
+
+ # Check permissions
+ if( $wgUser->isAllowed( 'delete' ) ) {
+ if( $wgUser->isBlocked( !$confirm ) ) {
+ $wgOut->blockedPage();
+ return;
+ }
+ } else {
+ $wgOut->permissionRequired( 'delete' );
+ return;
+ }
+
+ if( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+
+ $wgOut->setPagetitle( wfMsg( 'confirmdelete' ) );
+
+ # Better double-check that it hasn't been deleted yet!
+ $dbw =& wfGetDB( DB_MASTER );
+ $conds = $this->mTitle->pageCond();
+ $latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ );
+ if ( $latest === false ) {
+ $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
+ return;
+ }
+
+ if( $confirm ) {
+ $this->doDelete( $reason );
+ if( $wgRequest->getCheck( 'wpWatch' ) ) {
+ $this->doWatch();
+ } elseif( $this->mTitle->userIsWatching() ) {
+ $this->doUnwatch();
+ }
+ return;
+ }
+
+ # determine whether this page has earlier revisions
+ # and insert a warning if it does
+ $maxRevisions = 20;
+ $authors = $this->getLastNAuthors( $maxRevisions, $latest );
+
+ if( count( $authors ) > 1 && !$confirm ) {
+ $skin=$wgUser->getSkin();
+ $wgOut->addHTML( '<strong>' . wfMsg( 'historywarning' ) . ' ' . $skin->historyLink() . '</strong>' );
+ }
+
+ # If a single user is responsible for all revisions, find out who they are
+ if ( count( $authors ) == $maxRevisions ) {
+ // Query bailed out, too many revisions to find out if they're all the same
+ $authorOfAll = false;
+ } else {
+ $authorOfAll = reset( $authors );
+ foreach ( $authors as $author ) {
+ if ( $authorOfAll != $author ) {
+ $authorOfAll = false;
+ break;
+ }
+ }
+ }
+ # Fetch article text
+ $rev = Revision::newFromTitle( $this->mTitle );
+
+ if( !is_null( $rev ) ) {
+ # if this is a mini-text, we can paste part of it into the deletion reason
+ $text = $rev->getText();
+
+ #if this is empty, an earlier revision may contain "useful" text
+ $blanked = false;
+ if( $text == '' ) {
+ $prev = $rev->getPrevious();
+ if( $prev ) {
+ $text = $prev->getText();
+ $blanked = true;
+ }
+ }
+
+ $length = strlen( $text );
+
+ # this should not happen, since it is not possible to store an empty, new
+ # page. Let's insert a standard text in case it does, though
+ if( $length == 0 && $reason === '' ) {
+ $reason = wfMsgForContent( 'exblank' );
+ }
+
+ if( $length < 500 && $reason === '' ) {
+ # comment field=255, let's grep the first 150 to have some user
+ # space left
+ global $wgContLang;
+ $text = $wgContLang->truncate( $text, 150, '...' );
+
+ # let's strip out newlines
+ $text = preg_replace( "/[\n\r]/", '', $text );
+
+ if( !$blanked ) {
+ if( $authorOfAll === false ) {
+ $reason = wfMsgForContent( 'excontent', $text );
+ } else {
+ $reason = wfMsgForContent( 'excontentauthor', $text, $authorOfAll );
+ }
+ } else {
+ $reason = wfMsgForContent( 'exbeforeblank', $text );
+ }
+ }
+ }
+
+ return $this->confirmDelete( '', $reason );
+ }
+
+ /**
+ * Get the last N authors
+ * @param int $num Number of revisions to get
+ * @param string $revLatest The latest rev_id, selected from the master (optional)
+ * @return array Array of authors, duplicates not removed
+ */
+ function getLastNAuthors( $num, $revLatest = 0 ) {
+ wfProfileIn( __METHOD__ );
+
+ // First try the slave
+ // If that doesn't have the latest revision, try the master
+ $continue = 2;
+ $db =& wfGetDB( DB_SLAVE );
+ do {
+ $res = $db->select( array( 'page', 'revision' ),
+ array( 'rev_id', 'rev_user_text' ),
+ array(
+ 'page_namespace' => $this->mTitle->getNamespace(),
+ 'page_title' => $this->mTitle->getDBkey(),
+ 'rev_page = page_id'
+ ), __METHOD__, $this->getSelectOptions( array(
+ 'ORDER BY' => 'rev_timestamp DESC',
+ 'LIMIT' => $num
+ ) )
+ );
+ if ( !$res ) {
+ wfProfileOut( __METHOD__ );
+ return array();
+ }
+ $row = $db->fetchObject( $res );
+ if ( $continue == 2 && $revLatest && $row->rev_id != $revLatest ) {
+ $db =& wfGetDB( DB_MASTER );
+ $continue--;
+ } else {
+ $continue = 0;
+ }
+ } while ( $continue );
+
+ $authors = array( $row->rev_user_text );
+ while ( $row = $db->fetchObject( $res ) ) {
+ $authors[] = $row->rev_user_text;
+ }
+ wfProfileOut( __METHOD__ );
+ return $authors;
+ }
+
+ /**
+ * Output deletion confirmation dialog
+ */
+ function confirmDelete( $par, $reason ) {
+ global $wgOut, $wgUser;
+
+ wfDebug( "Article::confirmDelete\n" );
+
+ $sub = htmlspecialchars( $this->mTitle->getPrefixedText() );
+ $wgOut->setSubtitle( wfMsg( 'deletesub', $sub ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->addWikiText( wfMsg( 'confirmdeletetext' ) );
+
+ $formaction = $this->mTitle->escapeLocalURL( 'action=delete' . $par );
+
+ $confirm = htmlspecialchars( wfMsg( 'deletepage' ) );
+ $delcom = htmlspecialchars( wfMsg( 'deletecomment' ) );
+ $token = htmlspecialchars( $wgUser->editToken() );
+ $watch = Xml::checkLabel( wfMsg( 'watchthis' ), 'wpWatch', 'wpWatch', $wgUser->getBoolOption( 'watchdeletion' ) || $this->mTitle->userIsWatching(), array( 'tabindex' => '2' ) );
+
+ $wgOut->addHTML( "
+<form id='deleteconfirm' method='post' action=\"{$formaction}\">
+ <table border='0'>
+ <tr>
+ <td align='right'>
+ <label for='wpReason'>{$delcom}:</label>
+ </td>
+ <td align='left'>
+ <input type='text' size='60' name='wpReason' id='wpReason' value=\"" . htmlspecialchars( $reason ) . "\" tabindex=\"1\" />
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td>$watch</td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td>
+ <input type='submit' name='wpConfirmB' id='wpConfirmB' value=\"{$confirm}\" tabindex=\"3\" />
+ </td>
+ </tr>
+ </table>
+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
+</form>\n" );
+
+ $wgOut->returnToMain( false );
+ }
+
+
+ /**
+ * Perform a deletion and output success or failure messages
+ */
+ function doDelete( $reason ) {
+ global $wgOut, $wgUser;
+ wfDebug( __METHOD__."\n" );
+
+ if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason))) {
+ if ( $this->doDeleteArticle( $reason ) ) {
+ $deleted = wfEscapeWikiText( $this->mTitle->getPrefixedText() );
+
+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ $loglink = '[[Special:Log/delete|' . wfMsg( 'deletionlog' ) . ']]';
+ $text = wfMsg( 'deletedtext', $deleted, $loglink );
+
+ $wgOut->addWikiText( $text );
+ $wgOut->returnToMain( false );
+ wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason));
+ } else {
+ $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
+ }
+ }
+ }
+
+ /**
+ * Back-end article deletion
+ * Deletes the article with database consistency, writes logs, purges caches
+ * Returns success
+ */
+ function doDeleteArticle( $reason ) {
+ global $wgUseSquid, $wgDeferredUpdateList;
+ global $wgUseTrackbacks;
+
+ wfDebug( __METHOD__."\n" );
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $ns = $this->mTitle->getNamespace();
+ $t = $this->mTitle->getDBkey();
+ $id = $this->mTitle->getArticleID();
+
+ if ( $t == '' || $id == 0 ) {
+ return false;
+ }
+
+ $u = new SiteStatsUpdate( 0, 1, -(int)$this->isCountable( $this->getContent() ), -1 );
+ array_push( $wgDeferredUpdateList, $u );
+
+ // For now, shunt the revision data into the archive table.
+ // Text is *not* removed from the text table; bulk storage
+ // is left intact to avoid breaking block-compression or
+ // immutable storage schemes.
+ //
+ // For backwards compatibility, note that some older archive
+ // table entries will have ar_text and ar_flags fields still.
+ //
+ // In the future, we may keep revisions and mark them with
+ // the rev_deleted field, which is reserved for this purpose.
+ $dbw->insertSelect( 'archive', array( 'page', 'revision' ),
+ array(
+ 'ar_namespace' => 'page_namespace',
+ 'ar_title' => 'page_title',
+ 'ar_comment' => 'rev_comment',
+ 'ar_user' => 'rev_user',
+ 'ar_user_text' => 'rev_user_text',
+ 'ar_timestamp' => 'rev_timestamp',
+ 'ar_minor_edit' => 'rev_minor_edit',
+ 'ar_rev_id' => 'rev_id',
+ 'ar_text_id' => 'rev_text_id',
+ 'ar_text' => '\'\'', // Be explicit to appease
+ 'ar_flags' => '\'\'', // MySQL's "strict mode"...
+ ), array(
+ 'page_id' => $id,
+ 'page_id = rev_page'
+ ), __METHOD__
+ );
+
+ # Now that it's safely backed up, delete it
+ $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__);
+
+ # If using cascading deletes, we can skip some explicit deletes
+ if ( !$dbw->cascadingDeletes() ) {
+
+ $dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
+
+ if ($wgUseTrackbacks)
+ $dbw->delete( 'trackbacks', array( 'tb_page' => $id ), __METHOD__ );
+
+ # Delete outgoing links
+ $dbw->delete( 'pagelinks', array( 'pl_from' => $id ) );
+ $dbw->delete( 'imagelinks', array( 'il_from' => $id ) );
+ $dbw->delete( 'categorylinks', array( 'cl_from' => $id ) );
+ $dbw->delete( 'templatelinks', array( 'tl_from' => $id ) );
+ $dbw->delete( 'externallinks', array( 'el_from' => $id ) );
+ $dbw->delete( 'langlinks', array( 'll_from' => $id ) );
+ $dbw->delete( 'redirect', array( 'rd_from' => $id ) );
+ }
+
+ # If using cleanup triggers, we can skip some manual deletes
+ if ( !$dbw->cleanupTriggers() ) {
+
+ # Clean up recentchanges entries...
+ $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), __METHOD__ );
+ }
+
+ # Clear caches
+ Article::onArticleDelete( $this->mTitle );
+
+ # Log the deletion
+ $log = new LogPage( 'delete' );
+ $log->addEntry( 'delete', $this->mTitle, $reason );
+
+ # Clear the cached article id so the interface doesn't act like we exist
+ $this->mTitle->resetArticleID( 0 );
+ $this->mTitle->mArticleID = 0;
+ return true;
+ }
+
+ /**
+ * Revert a modification
+ */
+ function rollback() {
+ global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol;
+
+ if( $wgUser->isAllowed( 'rollback' ) ) {
+ if( $wgUser->isBlocked() ) {
+ $wgOut->blockedPage();
+ return;
+ }
+ } else {
+ $wgOut->permissionRequired( 'rollback' );
+ return;
+ }
+
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage( $this->getContent() );
+ return;
+ }
+ if( !$wgUser->matchEditToken( $wgRequest->getVal( 'token' ),
+ array( $this->mTitle->getPrefixedText(),
+ $wgRequest->getVal( 'from' ) ) ) ) {
+ $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) );
+ $wgOut->addWikiText( wfMsg( 'sessionfailure' ) );
+ return;
+ }
+ $dbw =& wfGetDB( DB_MASTER );
+
+ # Enhanced rollback, marks edits rc_bot=1
+ $bot = $wgRequest->getBool( 'bot' );
+
+ # Replace all this user's current edits with the next one down
+
+ # Get the last editor
+ $current = Revision::newFromTitle( $this->mTitle );
+ if( is_null( $current ) ) {
+ # Something wrong... no page?
+ $wgOut->addHTML( wfMsg( 'notanarticle' ) );
+ return;
+ }
+
+ $from = str_replace( '_', ' ', $wgRequest->getVal( 'from' ) );
+ if( $from != $current->getUserText() ) {
+ $wgOut->setPageTitle( wfMsg('rollbackfailed') );
+ $wgOut->addWikiText( wfMsg( 'alreadyrolled',
+ htmlspecialchars( $this->mTitle->getPrefixedText()),
+ htmlspecialchars( $from ),
+ htmlspecialchars( $current->getUserText() ) ) );
+ if( $current->getComment() != '') {
+ $wgOut->addHTML(
+ wfMsg( 'editcomment',
+ htmlspecialchars( $current->getComment() ) ) );
+ }
+ return;
+ }
+
+ # Get the last edit not by this guy
+ $user = intval( $current->getUser() );
+ $user_text = $dbw->addQuotes( $current->getUserText() );
+ $s = $dbw->selectRow( 'revision',
+ array( 'rev_id', 'rev_timestamp' ),
+ array(
+ 'rev_page' => $current->getPage(),
+ "rev_user <> {$user} OR rev_user_text <> {$user_text}"
+ ), __METHOD__,
+ array(
+ 'USE INDEX' => 'page_timestamp',
+ 'ORDER BY' => 'rev_timestamp DESC' )
+ );
+ if( $s === false ) {
+ # Something wrong
+ $wgOut->setPageTitle(wfMsg('rollbackfailed'));
+ $wgOut->addHTML( wfMsg( 'cantrollback' ) );
+ return;
+ }
+
+ $set = array();
+ if ( $bot ) {
+ # Mark all reverted edits as bot
+ $set['rc_bot'] = 1;
+ }
+ if ( $wgUseRCPatrol ) {
+ # Mark all reverted edits as patrolled
+ $set['rc_patrolled'] = 1;
+ }
+
+ if ( $set ) {
+ $dbw->update( 'recentchanges', $set,
+ array( /* WHERE */
+ 'rc_cur_id' => $current->getPage(),
+ 'rc_user_text' => $current->getUserText(),
+ "rc_timestamp > '{$s->rev_timestamp}'",
+ ), __METHOD__
+ );
+ }
+
+ # Get the edit summary
+ $target = Revision::newFromId( $s->rev_id );
+ $newComment = wfMsgForContent( 'revertpage', $target->getUserText(), $from );
+ $newComment = $wgRequest->getText( 'summary', $newComment );
+
+ # Save it!
+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->addHTML( '<h2>' . htmlspecialchars( $newComment ) . "</h2>\n<hr />\n" );
+
+ $this->updateArticle( $target->getText(), $newComment, 1, $this->mTitle->userIsWatching(), $bot );
+
+ $wgOut->returnToMain( false );
+ }
+
+
+ /**
+ * Do standard deferred updates after page view
+ * @private
+ */
+ function viewUpdates() {
+ global $wgDeferredUpdateList;
+
+ if ( 0 != $this->getID() ) {
+ global $wgDisableCounters;
+ if( !$wgDisableCounters ) {
+ Article::incViewCount( $this->getID() );
+ $u = new SiteStatsUpdate( 1, 0, 0 );
+ array_push( $wgDeferredUpdateList, $u );
+ }
+ }
+
+ # Update newtalk / watchlist notification status
+ global $wgUser;
+ $wgUser->clearNotification( $this->mTitle );
+ }
+
+ /**
+ * Do standard deferred updates after page edit.
+ * Update links tables, site stats, search index and message cache.
+ * Every 1000th edit, prune the recent changes table.
+ *
+ * @private
+ * @param $text New text of the article
+ * @param $summary Edit summary
+ * @param $minoredit Minor edit
+ * @param $timestamp_of_pagechange Timestamp associated with the page change
+ * @param $newid rev_id value of the new revision
+ * @param $changed Whether or not the content actually changed
+ */
+ function editUpdates( $text, $summary, $minoredit, $timestamp_of_pagechange, $newid, $changed = true ) {
+ global $wgDeferredUpdateList, $wgMessageCache, $wgUser, $wgParser;
+
+ wfProfileIn( __METHOD__ );
+
+ # Parse the text
+ $options = new ParserOptions;
+ $options->setTidy(true);
+ $poutput = $wgParser->parse( $text, $this->mTitle, $options, true, true, $newid );
+
+ # Save it to the parser cache
+ $parserCache =& ParserCache::singleton();
+ $parserCache->save( $poutput, $this, $wgUser );
+
+ # Update the links tables
+ $u = new LinksUpdate( $this->mTitle, $poutput );
+ $u->doUpdate();
+
+ if ( wfRunHooks( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) {
+ wfSeedRandom();
+ if ( 0 == mt_rand( 0, 999 ) ) {
+ # Periodically flush old entries from the recentchanges table.
+ global $wgRCMaxAge;
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $cutoff = $dbw->timestamp( time() - $wgRCMaxAge );
+ $recentchanges = $dbw->tableName( 'recentchanges' );
+ $sql = "DELETE FROM $recentchanges WHERE rc_timestamp < '{$cutoff}'";
+ $dbw->query( $sql );
+ }
+ }
+
+ $id = $this->getID();
+ $title = $this->mTitle->getPrefixedDBkey();
+ $shortTitle = $this->mTitle->getDBkey();
+
+ if ( 0 == $id ) {
+ wfProfileOut( __METHOD__ );
+ return;
+ }
+
+ $u = new SiteStatsUpdate( 0, 1, $this->mGoodAdjustment, $this->mTotalAdjustment );
+ array_push( $wgDeferredUpdateList, $u );
+ $u = new SearchUpdate( $id, $title, $text );
+ array_push( $wgDeferredUpdateList, $u );
+
+ # If this is another user's talk page, update newtalk
+ # Don't do this if $changed = false otherwise some idiot can null-edit a
+ # load of user talk pages and piss people off, nor if it's a minor edit
+ # by a properly-flagged bot.
+ if( $this->mTitle->getNamespace() == NS_USER_TALK && $shortTitle != $wgUser->getTitleKey() && $changed
+ && !($minoredit && $wgUser->isAllowed('nominornewtalk') ) ) {
+ if (wfRunHooks('ArticleEditUpdateNewTalk', array(&$this)) ) {
+ $other = User::newFromName( $shortTitle );
+ if( is_null( $other ) && User::isIP( $shortTitle ) ) {
+ // An anonymous user
+ $other = new User();
+ $other->setName( $shortTitle );
+ }
+ if( $other ) {
+ $other->setNewtalk( true );
+ }
+ }
+ }
+
+ if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+ $wgMessageCache->replace( $shortTitle, $text );
+ }
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Perform article updates on a special page creation.
+ *
+ * @param Revision $rev
+ *
+ * @fixme This is a shitty interface function. Kill it and replace the
+ * other shitty functions like editUpdates and such so it's not needed
+ * anymore.
+ */
+ function createUpdates( $rev ) {
+ $this->mGoodAdjustment = $this->isCountable( $rev->getText() );
+ $this->mTotalAdjustment = 1;
+ $this->editUpdates( $rev->getText(), $rev->getComment(),
+ $rev->isMinor(), wfTimestamp(), $rev->getId(), true );
+ }
+
+ /**
+ * Generate the navigation links when browsing through an article revisions
+ * It shows the information as:
+ * Revision as of \<date\>; view current revision
+ * \<- Previous version | Next Version -\>
+ *
+ * @private
+ * @param string $oldid Revision ID of this article revision
+ */
+ function setOldSubtitle( $oldid=0 ) {
+ global $wgLang, $wgOut, $wgUser;
+
+ if ( !wfRunHooks( 'DisplayOldSubtitle', array(&$this, &$oldid) ) ) {
+ return;
+ }
+
+ $revision = Revision::newFromId( $oldid );
+
+ $current = ( $oldid == $this->mLatest );
+ $td = $wgLang->timeanddate( $this->mTimestamp, true );
+ $sk = $wgUser->getSkin();
+ $lnk = $current
+ ? wfMsg( 'currentrevisionlink' )
+ : $lnk = $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'currentrevisionlink' ) );
+ $curdiff = $current
+ ? wfMsg( 'diff' )
+ : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=cur&oldid='.$oldid );
+ $prev = $this->mTitle->getPreviousRevisionID( $oldid ) ;
+ $prevlink = $prev
+ ? $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'previousrevision' ), 'direction=prev&oldid='.$oldid )
+ : wfMsg( 'previousrevision' );
+ $prevdiff = $prev
+ ? $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=prev&oldid='.$oldid )
+ : wfMsg( 'diff' );
+ $nextlink = $current
+ ? wfMsg( 'nextrevision' )
+ : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'nextrevision' ), 'direction=next&oldid='.$oldid );
+ $nextdiff = $current
+ ? wfMsg( 'diff' )
+ : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=next&oldid='.$oldid );
+
+ $userlinks = $sk->userLink( $revision->getUser(), $revision->getUserText() )
+ . $sk->userToolLinks( $revision->getUser(), $revision->getUserText() );
+
+ $r = "\n\t\t\t\t<div id=\"mw-revision-info\">" . wfMsg( 'revision-info', $td, $userlinks ) . "</div>\n" .
+ "\n\t\t\t\t<div id=\"mw-revision-nav\">" . wfMsg( 'revision-nav', $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>\n\t\t\t";
+ $wgOut->setSubtitle( $r );
+ }
+
+ /**
+ * This function is called right before saving the wikitext,
+ * so we can do things like signatures and links-in-context.
+ *
+ * @param string $text
+ */
+ function preSaveTransform( $text ) {
+ global $wgParser, $wgUser;
+ return $wgParser->preSaveTransform( $text, $this->mTitle, $wgUser, ParserOptions::newFromUser( $wgUser ) );
+ }
+
+ /* Caching functions */
+
+ /**
+ * checkLastModified returns true if it has taken care of all
+ * output to the client that is necessary for this request.
+ * (that is, it has sent a cached version of the page)
+ */
+ function tryFileCache() {
+ static $called = false;
+ if( $called ) {
+ wfDebug( "Article::tryFileCache(): called twice!?\n" );
+ return;
+ }
+ $called = true;
+ if($this->isFileCacheable()) {
+ $touched = $this->mTouched;
+ $cache = new HTMLFileCache( $this->mTitle );
+ if($cache->isFileCacheGood( $touched )) {
+ wfDebug( "Article::tryFileCache(): about to load file\n" );
+ $cache->loadFromFileCache();
+ return true;
+ } else {
+ wfDebug( "Article::tryFileCache(): starting buffer\n" );
+ ob_start( array(&$cache, 'saveToFileCache' ) );
+ }
+ } else {
+ wfDebug( "Article::tryFileCache(): not cacheable\n" );
+ }
+ }
+
+ /**
+ * Check if the page can be cached
+ * @return bool
+ */
+ function isFileCacheable() {
+ global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest;
+ $action = $wgRequest->getVal( 'action' );
+ $oldid = $wgRequest->getVal( 'oldid' );
+ $diff = $wgRequest->getVal( 'diff' );
+ $redirect = $wgRequest->getVal( 'redirect' );
+ $printable = $wgRequest->getVal( 'printable' );
+
+ return $wgUseFileCache
+ and (!$wgShowIPinHeader)
+ and ($this->getID() != 0)
+ and ($wgUser->isAnon())
+ and (!$wgUser->getNewtalk())
+ and ($this->mTitle->getNamespace() != NS_SPECIAL )
+ and (empty( $action ) || $action == 'view')
+ and (!isset($oldid))
+ and (!isset($diff))
+ and (!isset($redirect))
+ and (!isset($printable))
+ and (!$this->mRedirectedFrom);
+ }
+
+ /**
+ * Loads page_touched and returns a value indicating if it should be used
+ *
+ */
+ function checkTouched() {
+ if( !$this->mDataLoaded ) {
+ $this->loadPageData();
+ }
+ return !$this->mIsRedirect;
+ }
+
+ /**
+ * Get the page_touched field
+ */
+ function getTouched() {
+ # Ensure that page data has been loaded
+ if( !$this->mDataLoaded ) {
+ $this->loadPageData();
+ }
+ return $this->mTouched;
+ }
+
+ /**
+ * Get the page_latest field
+ */
+ function getLatest() {
+ if ( !$this->mDataLoaded ) {
+ $this->loadPageData();
+ }
+ return $this->mLatest;
+ }
+
+ /**
+ * Edit an article without doing all that other stuff
+ * The article must already exist; link tables etc
+ * are not updated, caches are not flushed.
+ *
+ * @param string $text text submitted
+ * @param string $comment comment submitted
+ * @param bool $minor whereas it's a minor modification
+ */
+ function quickEdit( $text, $comment = '', $minor = 0 ) {
+ wfProfileIn( __METHOD__ );
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+ $revision = new Revision( array(
+ 'page' => $this->getId(),
+ 'text' => $text,
+ 'comment' => $comment,
+ 'minor_edit' => $minor ? 1 : 0,
+ ) );
+ $revision->insertOn( $dbw );
+ $this->updateRevisionOn( $dbw, $revision );
+ $dbw->commit();
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Used to increment the view counter
+ *
+ * @static
+ * @param integer $id article id
+ */
+ function incViewCount( $id ) {
+ $id = intval( $id );
+ global $wgHitcounterUpdateFreq, $wgDBtype;
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $pageTable = $dbw->tableName( 'page' );
+ $hitcounterTable = $dbw->tableName( 'hitcounter' );
+ $acchitsTable = $dbw->tableName( 'acchits' );
+
+ if( $wgHitcounterUpdateFreq <= 1 ) {
+ $dbw->query( "UPDATE $pageTable SET page_counter = page_counter + 1 WHERE page_id = $id" );
+ return;
+ }
+
+ # Not important enough to warrant an error page in case of failure
+ $oldignore = $dbw->ignoreErrors( true );
+
+ $dbw->query( "INSERT INTO $hitcounterTable (hc_id) VALUES ({$id})" );
+
+ $checkfreq = intval( $wgHitcounterUpdateFreq/25 + 1 );
+ if( (rand() % $checkfreq != 0) or ($dbw->lastErrno() != 0) ){
+ # Most of the time (or on SQL errors), skip row count check
+ $dbw->ignoreErrors( $oldignore );
+ return;
+ }
+
+ $res = $dbw->query("SELECT COUNT(*) as n FROM $hitcounterTable");
+ $row = $dbw->fetchObject( $res );
+ $rown = intval( $row->n );
+ if( $rown >= $wgHitcounterUpdateFreq ){
+ wfProfileIn( 'Article::incViewCount-collect' );
+ $old_user_abort = ignore_user_abort( true );
+
+ if ($wgDBtype == 'mysql')
+ $dbw->query("LOCK TABLES $hitcounterTable WRITE");
+ $tabletype = $wgDBtype == 'mysql' ? "ENGINE=HEAP " : '';
+ $dbw->query("CREATE TEMPORARY TABLE $acchitsTable $tabletype AS ".
+ "SELECT hc_id,COUNT(*) AS hc_n FROM $hitcounterTable ".
+ 'GROUP BY hc_id');
+ $dbw->query("DELETE FROM $hitcounterTable");
+ if ($wgDBtype == 'mysql') {
+ $dbw->query('UNLOCK TABLES');
+ $dbw->query("UPDATE $pageTable,$acchitsTable SET page_counter=page_counter + hc_n ".
+ 'WHERE page_id = hc_id');
+ }
+ else {
+ $dbw->query("UPDATE $pageTable SET page_counter=page_counter + hc_n ".
+ "FROM $acchitsTable WHERE page_id = hc_id");
+ }
+ $dbw->query("DROP TABLE $acchitsTable");
+
+ ignore_user_abort( $old_user_abort );
+ wfProfileOut( 'Article::incViewCount-collect' );
+ }
+ $dbw->ignoreErrors( $oldignore );
+ }
+
+ /**#@+
+ * The onArticle*() functions are supposed to be a kind of hooks
+ * which should be called whenever any of the specified actions
+ * are done.
+ *
+ * This is a good place to put code to clear caches, for instance.
+ *
+ * This is called on page move and undelete, as well as edit
+ * @static
+ * @param $title_obj a title object
+ */
+
+ static function onArticleCreate($title) {
+ # The talk page isn't in the regular link tables, so we need to update manually:
+ if ( $title->isTalkPage() ) {
+ $other = $title->getSubjectPage();
+ } else {
+ $other = $title->getTalkPage();
+ }
+ $other->invalidateCache();
+ $other->purgeSquid();
+
+ $title->touchLinks();
+ $title->purgeSquid();
+ }
+
+ static function onArticleDelete( $title ) {
+ global $wgUseFileCache, $wgMessageCache;
+
+ $title->touchLinks();
+ $title->purgeSquid();
+
+ # File cache
+ if ( $wgUseFileCache ) {
+ $cm = new HTMLFileCache( $title );
+ @unlink( $cm->fileCacheName() );
+ }
+
+ if( $title->getNamespace() == NS_MEDIAWIKI) {
+ $wgMessageCache->replace( $title->getDBkey(), false );
+ }
+ }
+
+ /**
+ * Purge caches on page update etc
+ */
+ static function onArticleEdit( $title ) {
+ global $wgDeferredUpdateList, $wgUseFileCache;
+
+ // Invalidate caches of articles which include this page
+ $update = new HTMLCacheUpdate( $title, 'templatelinks' );
+ $wgDeferredUpdateList[] = $update;
+
+ # Purge squid for this page only
+ $title->purgeSquid();
+
+ # Clear file cache
+ if ( $wgUseFileCache ) {
+ $cm = new HTMLFileCache( $title );
+ @unlink( $cm->fileCacheName() );
+ }
+ }
+
+ /**#@-*/
+
+ /**
+ * Info about this page
+ * Called for ?action=info when $wgAllowPageInfo is on.
+ *
+ * @public
+ */
+ function info() {
+ global $wgLang, $wgOut, $wgAllowPageInfo, $wgUser;
+
+ if ( !$wgAllowPageInfo ) {
+ $wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
+ return;
+ }
+
+ $page = $this->mTitle->getSubjectPage();
+
+ $wgOut->setPagetitle( $page->getPrefixedText() );
+ $wgOut->setSubtitle( wfMsg( 'infosubtitle' ));
+
+ # first, see if the page exists at all.
+ $exists = $page->getArticleId() != 0;
+ if( !$exists ) {
+ if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+ $wgOut->addHTML(wfMsgWeirdKey ( $this->mTitle->getText() ) );
+ } else {
+ $wgOut->addHTML(wfMsg( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon' ) );
+ }
+ } else {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $wl_clause = array(
+ 'wl_title' => $page->getDBkey(),
+ 'wl_namespace' => $page->getNamespace() );
+ $numwatchers = $dbr->selectField(
+ 'watchlist',
+ 'COUNT(*)',
+ $wl_clause,
+ __METHOD__,
+ $this->getSelectOptions() );
+
+ $pageInfo = $this->pageCountInfo( $page );
+ $talkInfo = $this->pageCountInfo( $page->getTalkPage() );
+
+ $wgOut->addHTML( "<ul><li>" . wfMsg("numwatchers", $wgLang->formatNum( $numwatchers ) ) . '</li>' );
+ $wgOut->addHTML( "<li>" . wfMsg('numedits', $wgLang->formatNum( $pageInfo['edits'] ) ) . '</li>');
+ if( $talkInfo ) {
+ $wgOut->addHTML( '<li>' . wfMsg("numtalkedits", $wgLang->formatNum( $talkInfo['edits'] ) ) . '</li>');
+ }
+ $wgOut->addHTML( '<li>' . wfMsg("numauthors", $wgLang->formatNum( $pageInfo['authors'] ) ) . '</li>' );
+ if( $talkInfo ) {
+ $wgOut->addHTML( '<li>' . wfMsg('numtalkauthors', $wgLang->formatNum( $talkInfo['authors'] ) ) . '</li>' );
+ }
+ $wgOut->addHTML( '</ul>' );
+
+ }
+ }
+
+ /**
+ * Return the total number of edits and number of unique editors
+ * on a given page. If page does not exist, returns false.
+ *
+ * @param Title $title
+ * @return array
+ * @private
+ */
+ function pageCountInfo( $title ) {
+ $id = $title->getArticleId();
+ if( $id == 0 ) {
+ return false;
+ }
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $rev_clause = array( 'rev_page' => $id );
+
+ $edits = $dbr->selectField(
+ 'revision',
+ 'COUNT(rev_page)',
+ $rev_clause,
+ __METHOD__,
+ $this->getSelectOptions() );
+
+ $authors = $dbr->selectField(
+ 'revision',
+ 'COUNT(DISTINCT rev_user_text)',
+ $rev_clause,
+ __METHOD__,
+ $this->getSelectOptions() );
+
+ return array( 'edits' => $edits, 'authors' => $authors );
+ }
+
+ /**
+ * Return a list of templates used by this article.
+ * Uses the templatelinks table
+ *
+ * @return array Array of Title objects
+ */
+ function getUsedTemplates() {
+ $result = array();
+ $id = $this->mTitle->getArticleID();
+ if( $id == 0 ) {
+ return array();
+ }
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( array( 'templatelinks' ),
+ array( 'tl_namespace', 'tl_title' ),
+ array( 'tl_from' => $id ),
+ 'Article:getUsedTemplates' );
+ if ( false !== $res ) {
+ if ( $dbr->numRows( $res ) ) {
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $result[] = Title::makeTitle( $row->tl_namespace, $row->tl_title );
+ }
+ }
+ }
+ $dbr->freeResult( $res );
+ return $result;
+ }
+
+ /**
+ * Return an auto-generated summary if the text provided is a redirect.
+ *
+ * @param string $text The wikitext to check
+ * @return string '' or an appropriate summary
+ */
+ public static function getRedirectAutosummary( $text ) {
+ $rt = Title::newFromRedirect( $text );
+ if( is_object( $rt ) )
+ return wfMsgForContent( 'autoredircomment', $rt->getFullText() );
+ else
+ return '';
+ }
+
+ /**
+ * Return an auto-generated summary if the new text is much shorter than
+ * the old text.
+ *
+ * @param string $oldtext The previous text of the page
+ * @param string $text The submitted text of the page
+ * @return string An appropriate autosummary, or an empty string.
+ */
+ public static function getBlankingAutosummary( $oldtext, $text ) {
+ if ($oldtext!='' && $text=='') {
+ return wfMsgForContent('autosumm-blank');
+ } elseif (strlen($oldtext) > 10 * strlen($text) && strlen($text) < 500) {
+ #Removing more than 90% of the article
+ global $wgContLang;
+ $truncatedtext = $wgContLang->truncate($text, max(0, 200 - strlen(wfMsgForContent('autosumm-replace'))), '...');
+ return wfMsgForContent('autosumm-replace', $truncatedtext);
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Return an applicable autosummary if one exists for the given edit.
+ * @param string $oldtext The previous text of the page.
+ * @param string $newtext The submitted text of the page.
+ * @param bitmask $flags A bitmask of flags submitted for the edit.
+ * @return string An appropriate autosummary, or an empty string.
+ */
+ public static function getAutosummary( $oldtext, $newtext, $flags ) {
+
+ # This code is UGLY UGLY UGLY.
+ # Somebody PLEASE come up with a more elegant way to do it.
+
+ #Redirect autosummaries
+ $summary = self::getRedirectAutosummary( $newtext );
+
+ if ($summary)
+ return $summary;
+
+ #Blanking autosummaries
+ if (!($flags & EDIT_NEW))
+ $summary = self::getBlankingAutosummary( $oldtext, $newtext );
+
+ if ($summary)
+ return $summary;
+
+ #New page autosummaries
+ if ($flags & EDIT_NEW && strlen($newtext)) {
+ #If they're making a new article, give its text, truncated, in the summary.
+ global $wgContLang;
+ $truncatedtext = $wgContLang->truncate(
+ str_replace("\n", ' ', $newtext),
+ max( 0, 200 - strlen( wfMsgForContent( 'autosumm-new') ) ),
+ '...' );
+ $summary = wfMsgForContent( 'autosumm-new', $truncatedtext );
+ }
+
+ if ($summary)
+ return $summary;
+
+ return $summary;
+ }
+}
+
+?>
diff --git a/includes/AuthPlugin.php b/includes/AuthPlugin.php
new file mode 100644
index 000000000000..e33ef1bf94ea
--- /dev/null
+++ b/includes/AuthPlugin.php
@@ -0,0 +1,237 @@
+<?php
+/**
+ * @package MediaWiki
+ */
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Authentication plugin interface. Instantiate a subclass of AuthPlugin
+ * and set $wgAuth to it to authenticate against some external tool.
+ *
+ * The default behavior is not to do anything, and use the local user
+ * database for all authentication. A subclass can require that all
+ * accounts authenticate externally, or use it only as a fallback; also
+ * you can transparently create internal wiki accounts the first time
+ * someone logs in who can be authenticated externally.
+ *
+ * This interface is new, and might change a bit before 1.4.0 final is
+ * done...
+ *
+ * @package MediaWiki
+ */
+class AuthPlugin {
+ /**
+ * Check whether there exists a user account with the given name.
+ * The name will be normalized to MediaWiki's requirements, so
+ * you might need to munge it (for instance, for lowercase initial
+ * letters).
+ *
+ * @param $username String: username.
+ * @return bool
+ * @public
+ */
+ function userExists( $username ) {
+ # Override this!
+ return false;
+ }
+
+ /**
+ * Check if a username+password pair is a valid login.
+ * The name will be normalized to MediaWiki's requirements, so
+ * you might need to munge it (for instance, for lowercase initial
+ * letters).
+ *
+ * @param $username String: username.
+ * @param $password String: user password.
+ * @return bool
+ * @public
+ */
+ function authenticate( $username, $password ) {
+ # Override this!
+ return false;
+ }
+
+ /**
+ * Modify options in the login template.
+ *
+ * @param $template UserLoginTemplate object.
+ * @public
+ */
+ function modifyUITemplate( &$template ) {
+ # Override this!
+ $template->set( 'usedomain', false );
+ }
+
+ /**
+ * Set the domain this plugin is supposed to use when authenticating.
+ *
+ * @param $domain String: authentication domain.
+ * @public
+ */
+ function setDomain( $domain ) {
+ $this->domain = $domain;
+ }
+
+ /**
+ * Check to see if the specific domain is a valid domain.
+ *
+ * @param $domain String: authentication domain.
+ * @return bool
+ * @public
+ */
+ function validDomain( $domain ) {
+ # Override this!
+ return true;
+ }
+
+ /**
+ * When a user logs in, optionally fill in preferences and such.
+ * For instance, you might pull the email address or real name from the
+ * external user database.
+ *
+ * The User object is passed by reference so it can be modified; don't
+ * forget the & on your function declaration.
+ *
+ * @param User $user
+ * @public
+ */
+ function updateUser( &$user ) {
+ # Override this and do something
+ return true;
+ }
+
+
+ /**
+ * Return true if the wiki should create a new local account automatically
+ * when asked to login a user who doesn't exist locally but does in the
+ * external auth database.
+ *
+ * If you don't automatically create accounts, you must still create
+ * accounts in some way. It's not possible to authenticate without
+ * a local account.
+ *
+ * This is just a question, and shouldn't perform any actions.
+ *
+ * @return bool
+ * @public
+ */
+ function autoCreate() {
+ return false;
+ }
+
+ /**
+ * Can users change their passwords?
+ *
+ * @return bool
+ */
+ function allowPasswordChange() {
+ return true;
+ }
+
+ /**
+ * Set the given password in the authentication database.
+ * As a special case, the password may be set to null to request
+ * locking the password to an unusable value, with the expectation
+ * that it will be set later through a mail reset or other method.
+ *
+ * Return true if successful.
+ *
+ * @param $user User object.
+ * @param $password String: password.
+ * @return bool
+ * @public
+ */
+ function setPassword( $user, $password ) {
+ return true;
+ }
+
+ /**
+ * Update user information in the external authentication database.
+ * Return true if successful.
+ *
+ * @param $user User object.
+ * @return bool
+ * @public
+ */
+ function updateExternalDB( $user ) {
+ return true;
+ }
+
+ /**
+ * Check to see if external accounts can be created.
+ * Return true if external accounts can be created.
+ * @return bool
+ * @public
+ */
+ function canCreateAccounts() {
+ return false;
+ }
+
+ /**
+ * Add a user to the external authentication database.
+ * Return true if successful.
+ *
+ * @param User $user
+ * @param string $password
+ * @return bool
+ * @public
+ */
+ function addUser( $user, $password ) {
+ return true;
+ }
+
+
+ /**
+ * Return true to prevent logins that don't authenticate here from being
+ * checked against the local database's password fields.
+ *
+ * This is just a question, and shouldn't perform any actions.
+ *
+ * @return bool
+ * @public
+ */
+ function strict() {
+ return false;
+ }
+
+ /**
+ * When creating a user account, optionally fill in preferences and such.
+ * For instance, you might pull the email address or real name from the
+ * external user database.
+ *
+ * The User object is passed by reference so it can be modified; don't
+ * forget the & on your function declaration.
+ *
+ * @param $user User object.
+ * @public
+ */
+ function initUser( &$user ) {
+ # Override this to do something.
+ }
+
+ /**
+ * If you want to munge the case of an account name before the final
+ * check, now is your chance.
+ */
+ function getCanonicalName( $username ) {
+ return $username;
+ }
+}
+
+?>
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
new file mode 100644
index 000000000000..8de5608f0685
--- /dev/null
+++ b/includes/AutoLoader.php
@@ -0,0 +1,323 @@
+<?php
+
+/* This defines autoloading handler for whole MediaWiki framework */
+
+ini_set('unserialize_callback_func', '__autoload' );
+
+function __autoload($className) {
+ global $wgAutoloadClasses;
+
+ static $localClasses = array(
+ 'AjaxDispatcher' => 'includes/AjaxDispatcher.php',
+ 'AjaxCachePolicy' => 'includes/AjaxFunctions.php',
+ 'AjaxResponse' => 'includes/AjaxResponse.php',
+ 'Article' => 'includes/Article.php',
+ 'AuthPlugin' => 'includes/AuthPlugin.php',
+ 'BagOStuff' => 'includes/BagOStuff.php',
+ 'HashBagOStuff' => 'includes/BagOStuff.php',
+ 'SqlBagOStuff' => 'includes/BagOStuff.php',
+ 'MediaWikiBagOStuff' => 'includes/BagOStuff.php',
+ 'TurckBagOStuff' => 'includes/BagOStuff.php',
+ 'APCBagOStuff' => 'includes/BagOStuff.php',
+ 'eAccelBagOStuff' => 'includes/BagOStuff.php',
+ 'DBABagOStuff' => 'includes/BagOStuff.php',
+ 'Block' => 'includes/Block.php',
+ 'HTMLFileCache' => 'includes/HTMLFileCache.php',
+ 'DependencyWrapper' => 'includes/CacheDependency.php',
+ 'FileDependency' => 'includes/CacheDependency.php',
+ 'TitleDependency' => 'includes/CacheDependency.php',
+ 'TitleListDependency' => 'includes/CacheDependency.php',
+ 'CategoryPage' => 'includes/CategoryPage.php',
+ 'CategoryViewer' => 'includes/CategoryPage.php',
+ 'Categoryfinder' => 'includes/Categoryfinder.php',
+ 'RCCacheEntry' => 'includes/ChangesList.php',
+ 'ChangesList' => 'includes/ChangesList.php',
+ 'OldChangesList' => 'includes/ChangesList.php',
+ 'EnhancedChangesList' => 'includes/ChangesList.php',
+ 'CoreParserFunctions' => 'includes/CoreParserFunctions.php',
+ 'DBObject' => 'includes/Database.php',
+ 'Database' => 'includes/Database.php',
+ 'DatabaseMysql' => 'includes/Database.php',
+ 'ResultWrapper' => 'includes/Database.php',
+ 'OracleBlob' => 'includes/DatabaseOracle.php',
+ 'DatabaseOracle' => 'includes/DatabaseOracle.php',
+ 'DatabasePostgres' => 'includes/DatabasePostgres.php',
+ 'DateFormatter' => 'includes/DateFormatter.php',
+ 'DifferenceEngine' => 'includes/DifferenceEngine.php',
+ '_DiffOp' => 'includes/DifferenceEngine.php',
+ '_DiffOp_Copy' => 'includes/DifferenceEngine.php',
+ '_DiffOp_Delete' => 'includes/DifferenceEngine.php',
+ '_DiffOp_Add' => 'includes/DifferenceEngine.php',
+ '_DiffOp_Change' => 'includes/DifferenceEngine.php',
+ '_DiffEngine' => 'includes/DifferenceEngine.php',
+ 'Diff' => 'includes/DifferenceEngine.php',
+ 'MappedDiff' => 'includes/DifferenceEngine.php',
+ 'DiffFormatter' => 'includes/DifferenceEngine.php',
+ 'DjVuImage' => 'includes/DjVuImage.php',
+ '_HWLDF_WordAccumulator' => 'includes/DifferenceEngine.php',
+ 'WordLevelDiff' => 'includes/DifferenceEngine.php',
+ 'TableDiffFormatter' => 'includes/DifferenceEngine.php',
+ 'EditPage' => 'includes/EditPage.php',
+ 'MWException' => 'includes/Exception.php',
+ 'Exif' => 'includes/Exif.php',
+ 'FormatExif' => 'includes/Exif.php',
+ 'WikiExporter' => 'includes/Export.php',
+ 'XmlDumpWriter' => 'includes/Export.php',
+ 'DumpOutput' => 'includes/Export.php',
+ 'DumpFileOutput' => 'includes/Export.php',
+ 'DumpPipeOutput' => 'includes/Export.php',
+ 'DumpGZipOutput' => 'includes/Export.php',
+ 'DumpBZip2Output' => 'includes/Export.php',
+ 'Dump7ZipOutput' => 'includes/Export.php',
+ 'DumpFilter' => 'includes/Export.php',
+ 'DumpNotalkFilter' => 'includes/Export.php',
+ 'DumpNamespaceFilter' => 'includes/Export.php',
+ 'DumpLatestFilter' => 'includes/Export.php',
+ 'DumpMultiWriter' => 'includes/Export.php',
+ 'ExternalEdit' => 'includes/ExternalEdit.php',
+ 'ExternalStore' => 'includes/ExternalStore.php',
+ 'ExternalStoreDB' => 'includes/ExternalStoreDB.php',
+ 'ExternalStoreHttp' => 'includes/ExternalStoreHttp.php',
+ 'FakeTitle' => 'includes/FakeTitle.php',
+ 'FeedItem' => 'includes/Feed.php',
+ 'ChannelFeed' => 'includes/Feed.php',
+ 'RSSFeed' => 'includes/Feed.php',
+ 'AtomFeed' => 'includes/Feed.php',
+ 'FileStore' => 'includes/FileStore.php',
+ 'FSException' => 'includes/FileStore.php',
+ 'FSTransaction' => 'includes/FileStore.php',
+ 'HTMLForm' => 'includes/HTMLForm.php',
+ 'HistoryBlob' => 'includes/HistoryBlob.php',
+ 'ConcatenatedGzipHistoryBlob' => 'includes/HistoryBlob.php',
+ 'HistoryBlobStub' => 'includes/HistoryBlob.php',
+ 'HistoryBlobCurStub' => 'includes/HistoryBlob.php',
+ 'HTMLCacheUpdate' => 'includes/HTMLCacheUpdate.php',
+ 'HTMLCacheUpdateJob' => 'includes/HTMLCacheUpdate.php',
+ 'Http' => 'includes/HttpFunctions.php',
+ 'Image' => 'includes/Image.php',
+ 'IP' => 'includes/IP.php',
+ 'ThumbnailImage' => 'includes/Image.php',
+ 'ImageGallery' => 'includes/ImageGallery.php',
+ 'ImagePage' => 'includes/ImagePage.php',
+ 'ImageHistoryList' => 'includes/ImagePage.php',
+ 'ImageRemote' => 'includes/ImageRemote.php',
+ 'Job' => 'includes/JobQueue.php',
+ 'Licenses' => 'includes/Licenses.php',
+ 'License' => 'includes/Licenses.php',
+ 'LinkBatch' => 'includes/LinkBatch.php',
+ 'LinkCache' => 'includes/LinkCache.php',
+ 'LinkFilter' => 'includes/LinkFilter.php',
+ 'Linker' => 'includes/Linker.php',
+ 'LinksUpdate' => 'includes/LinksUpdate.php',
+ 'LoadBalancer' => 'includes/LoadBalancer.php',
+ 'LogPage' => 'includes/LogPage.php',
+ 'MacBinary' => 'includes/MacBinary.php',
+ 'MagicWord' => 'includes/MagicWord.php',
+ 'MathRenderer' => 'includes/Math.php',
+ 'MessageCache' => 'includes/MessageCache.php',
+ 'MimeMagic' => 'includes/MimeMagic.php',
+ 'Namespace' => 'includes/Namespace.php',
+ 'FakeMemCachedClient' => 'includes/ObjectCache.php',
+ 'OutputPage' => 'includes/OutputPage.php',
+ 'PageHistory' => 'includes/PageHistory.php',
+ 'IndexPager' => 'includes/Pager.php',
+ 'ReverseChronologicalPager' => 'includes/Pager.php',
+ 'TablePager' => 'includes/Pager.php',
+ 'Parser' => 'includes/Parser.php',
+ 'ParserOutput' => 'includes/Parser.php',
+ 'ParserOptions' => 'includes/Parser.php',
+ 'ParserCache' => 'includes/ParserCache.php',
+ 'ProfilerSimple' => 'includes/ProfilerSimple.php',
+ 'ProfilerSimpleUDP' => 'includes/ProfilerSimpleUDP.php',
+ 'Profiler' => 'includes/Profiler.php',
+ 'ProxyTools' => 'includes/ProxyTools.php',
+ 'ProtectionForm' => 'includes/ProtectionForm.php',
+ 'QueryPage' => 'includes/QueryPage.php',
+ 'PageQueryPage' => 'includes/QueryPage.php',
+ 'RawPage' => 'includes/RawPage.php',
+ 'RecentChange' => 'includes/RecentChange.php',
+ 'Revision' => 'includes/Revision.php',
+ 'Sanitizer' => 'includes/Sanitizer.php',
+ 'SearchEngine' => 'includes/SearchEngine.php',
+ 'SearchResultSet' => 'includes/SearchEngine.php',
+ 'SearchResult' => 'includes/SearchEngine.php',
+ 'SearchEngineDummy' => 'includes/SearchEngine.php',
+ 'SearchMySQL' => 'includes/SearchMySQL.php',
+ 'MySQLSearchResultSet' => 'includes/SearchMySQL.php',
+ 'SearchMySQL4' => 'includes/SearchMySQL4.php',
+ 'SearchPostgres' => 'includes/SearchPostgres.php',
+ 'SearchUpdate' => 'includes/SearchUpdate.php',
+ 'SearchUpdateMyISAM' => 'includes/SearchUpdate.php',
+ 'SiteConfiguration' => 'includes/SiteConfiguration.php',
+ 'SiteStats' => 'includes/SiteStats.php',
+ 'SiteStatsUpdate' => 'includes/SiteStats.php',
+ 'Skin' => 'includes/Skin.php',
+ 'MediaWiki_I18N' => 'includes/SkinTemplate.php',
+ 'SkinTemplate' => 'includes/SkinTemplate.php',
+ 'QuickTemplate' => 'includes/SkinTemplate.php',
+ 'SpecialAllpages' => 'includes/SpecialAllpages.php',
+ 'AncientPagesPage' => 'includes/SpecialAncientpages.php',
+ 'IPBlockForm' => 'includes/SpecialBlockip.php',
+ 'SpecialBookSources' => 'includes/SpecialBooksources.php',
+ 'BrokenRedirectsPage' => 'includes/SpecialBrokenRedirects.php',
+ 'CategoriesPage' => 'includes/SpecialCategories.php',
+ 'EmailConfirmation' => 'includes/SpecialConfirmemail.php',
+ 'ContributionsPage' => 'includes/SpecialContributions.php',
+ 'DeadendPagesPage' => 'includes/SpecialDeadendpages.php',
+ 'DisambiguationsPage' => 'includes/SpecialDisambiguations.php',
+ 'DoubleRedirectsPage' => 'includes/SpecialDoubleRedirects.php',
+ 'EmailUserForm' => 'includes/SpecialEmailuser.php',
+ 'WikiRevision' => 'includes/SpecialImport.php',
+ 'WikiImporter' => 'includes/SpecialImport.php',
+ 'ImportStringSource' => 'includes/SpecialImport.php',
+ 'ImportStreamSource' => 'includes/SpecialImport.php',
+ 'IPUnblockForm' => 'includes/SpecialIpblocklist.php',
+ 'ListredirectsPage' => 'includes/SpecialListredirects.php',
+ 'ListUsersPage' => 'includes/SpecialListusers.php',
+ 'DBLockForm' => 'includes/SpecialLockdb.php',
+ 'LogReader' => 'includes/SpecialLog.php',
+ 'LogViewer' => 'includes/SpecialLog.php',
+ 'LonelyPagesPage' => 'includes/SpecialLonelypages.php',
+ 'LongPagesPage' => 'includes/SpecialLongpages.php',
+ 'MIMEsearchPage' => 'includes/SpecialMIMEsearch.php',
+ 'MostcategoriesPage' => 'includes/SpecialMostcategories.php',
+ 'MostimagesPage' => 'includes/SpecialMostimages.php',
+ 'MostlinkedPage' => 'includes/SpecialMostlinked.php',
+ 'MostlinkedCategoriesPage' => 'includes/SpecialMostlinkedcategories.php',
+ 'MostrevisionsPage' => 'includes/SpecialMostrevisions.php',
+ 'MovePageForm' => 'includes/SpecialMovepage.php',
+ 'NewbieContributionsPage' => 'includes/SpecialNewbieContributions.php',
+ 'NewPagesPage' => 'includes/SpecialNewpages.php',
+ 'SpecialPage' => 'includes/SpecialPage.php',
+ 'UnlistedSpecialPage' => 'includes/SpecialPage.php',
+ 'IncludableSpecialPage' => 'includes/SpecialPage.php',
+ 'PopularPagesPage' => 'includes/SpecialPopularpages.php',
+ 'PreferencesForm' => 'includes/SpecialPreferences.php',
+ 'SpecialPrefixindex' => 'includes/SpecialPrefixindex.php',
+ 'RevisionDeleteForm' => 'includes/SpecialRevisiondelete.php',
+ 'RevisionDeleter' => 'includes/SpecialRevisiondelete.php',
+ 'SpecialSearch' => 'includes/SpecialSearch.php',
+ 'ShortPagesPage' => 'includes/SpecialShortpages.php',
+ 'UncategorizedCategoriesPage' => 'includes/SpecialUncategorizedcategories.php',
+ 'UncategorizedPagesPage' => 'includes/SpecialUncategorizedpages.php',
+ 'PageArchive' => 'includes/SpecialUndelete.php',
+ 'UndeleteForm' => 'includes/SpecialUndelete.php',
+ 'DBUnlockForm' => 'includes/SpecialUnlockdb.php',
+ 'UnusedCategoriesPage' => 'includes/SpecialUnusedcategories.php',
+ 'UnusedimagesPage' => 'includes/SpecialUnusedimages.php',
+ 'UnusedtemplatesPage' => 'includes/SpecialUnusedtemplates.php',
+ 'UnwatchedpagesPage' => 'includes/SpecialUnwatchedpages.php',
+ 'UploadForm' => 'includes/SpecialUpload.php',
+ 'UploadFormMogile' => 'includes/SpecialUploadMogile.php',
+ 'LoginForm' => 'includes/SpecialUserlogin.php',
+ 'UserrightsForm' => 'includes/SpecialUserrights.php',
+ 'SpecialVersion' => 'includes/SpecialVersion.php',
+ 'WantedCategoriesPage' => 'includes/SpecialWantedcategories.php',
+ 'WantedPagesPage' => 'includes/SpecialWantedpages.php',
+ 'WhatLinksHerePage' => 'includes/SpecialWhatlinkshere.php',
+ 'SquidUpdate' => 'includes/SquidUpdate.php',
+ 'ReplacementArray' => 'includes/StringUtils.php',
+ 'Replacer' => 'includes/StringUtils.php',
+ 'RegexlikeReplacer' => 'includes/StringUtils.php',
+ 'DoubleReplacer' => 'includes/StringUtils.php',
+ 'HashtableReplacer' => 'includes/StringUtils.php',
+ 'StringUtils' => 'includes/StringUtils.php',
+ 'Title' => 'includes/Title.php',
+ 'User' => 'includes/User.php',
+ 'MailAddress' => 'includes/UserMailer.php',
+ 'EmailNotification' => 'includes/UserMailer.php',
+ 'WatchedItem' => 'includes/WatchedItem.php',
+ 'WebRequest' => 'includes/WebRequest.php',
+ 'WebResponse' => 'includes/WebResponse.php',
+ 'FauxRequest' => 'includes/WebRequest.php',
+ 'MediaWiki' => 'includes/Wiki.php',
+ 'WikiError' => 'includes/WikiError.php',
+ 'WikiErrorMsg' => 'includes/WikiError.php',
+ 'WikiXmlError' => 'includes/WikiError.php',
+ 'Xml' => 'includes/Xml.php',
+ 'ZhClient' => 'includes/ZhClient.php',
+ 'memcached' => 'includes/memcached-client.php',
+ 'UtfNormal' => 'includes/normal/UtfNormal.php',
+ 'UsercreateTemplate' => 'includes/templates/Userlogin.php',
+ 'UserloginTemplate' => 'includes/templates/Userlogin.php',
+ 'Language' => 'languages/Language.php',
+ 'PasswordResetForm' => 'includes/SpecialResetpass.php',
+
+ // API classes
+ 'ApiBase' => 'includes/api/ApiBase.php',
+ 'ApiFormatFeedWrapper' => 'includes/api/ApiFormatBase.php',
+ 'ApiFeedWatchlist' => 'includes/api/ApiFeedWatchlist.php',
+ 'ApiFormatBase' => 'includes/api/ApiFormatBase.php',
+ 'Services_JSON' => 'includes/api/ApiFormatJson_json.php',
+ 'ApiFormatJson' => 'includes/api/ApiFormatJson.php',
+ 'ApiFormatPhp' => 'includes/api/ApiFormatPhp.php',
+ 'ApiFormatWddx' => 'includes/api/ApiFormatWddx.php',
+ 'ApiFormatXml' => 'includes/api/ApiFormatXml.php',
+ 'Spyc' => 'includes/api/ApiFormatYaml_spyc.php',
+ 'ApiFormatYaml' => 'includes/api/ApiFormatYaml.php',
+ 'ApiHelp' => 'includes/api/ApiHelp.php',
+ 'ApiLogin' => 'includes/api/ApiLogin.php',
+ 'ApiMain' => 'includes/api/ApiMain.php',
+ 'ApiOpenSearch' => 'includes/api/ApiOpenSearch.php',
+ 'ApiPageSet' => 'includes/api/ApiPageSet.php',
+ 'ApiQuery' => 'includes/api/ApiQuery.php',
+ 'ApiQueryAllpages' => 'includes/api/ApiQueryAllpages.php',
+ 'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
+ 'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
+ 'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php',
+ 'ApiQueryInfo' => 'includes/api/ApiQueryInfo.php',
+ 'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
+ 'ApiQueryRecentChanges'=> 'includes/api/ApiQueryRecentChanges.php',
+ 'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
+ 'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
+ 'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
+ 'ApiResult' => 'includes/api/ApiResult.php',
+ );
+
+ if ( isset( $localClasses[$className] ) ) {
+ $filename = $localClasses[$className];
+ } elseif ( isset( $wgAutoloadClasses[$className] ) ) {
+ $filename = $wgAutoloadClasses[$className];
+ } else {
+ # Try a different capitalisation
+ # The case can sometimes be wrong when unserializing PHP 4 objects
+ $filename = false;
+ $lowerClass = strtolower( $className );
+ foreach ( $localClasses as $class2 => $file2 ) {
+ if ( strtolower( $class2 ) == $lowerClass ) {
+ $filename = $file2;
+ }
+ }
+ if ( !$filename ) {
+ # Give up
+ return;
+ }
+ }
+
+ # Make an absolute path, this improves performance by avoiding some stat calls
+ if ( substr( $filename, 0, 1 ) != '/' && substr( $filename, 1, 1 ) != ':' ) {
+ global $IP;
+ $filename = "$IP/$filename";
+ }
+ require( $filename );
+}
+
+function wfLoadAllExtensions() {
+ global $wgAutoloadClasses;
+
+ # It is crucial that SpecialPage.php is included before any special page
+ # extensions are loaded. Otherwise the parent class will not be available
+ # when APC loads the early-bound extension class. Normally this is
+ # guaranteed by entering special pages via SpecialPage members such as
+ # executePath(), but here we have to take a more explicit measure.
+
+ require_once( 'SpecialPage.php' );
+
+ foreach( $wgAutoloadClasses as $class => $file ) {
+ if ( ! class_exists( $class ) ) {
+ require( $file );
+ }
+ }
+}
+
+?>
diff --git a/includes/BagOStuff.php b/includes/BagOStuff.php
new file mode 100644
index 000000000000..c720807d3863
--- /dev/null
+++ b/includes/BagOStuff.php
@@ -0,0 +1,694 @@
+<?php
+#
+# Copyright (C) 2003-2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+/**
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Simple generic object store
+ *
+ * interface is intended to be more or less compatible with
+ * the PHP memcached client.
+ *
+ * backends for local hash array and SQL table included:
+ * $bag = new HashBagOStuff();
+ * $bag = new MysqlBagOStuff($tablename); # connect to db first
+ *
+ * @package MediaWiki
+ */
+class BagOStuff {
+ var $debugmode;
+
+ function BagOStuff() {
+ $this->set_debug( false );
+ }
+
+ function set_debug($bool) {
+ $this->debugmode = $bool;
+ }
+
+ /* *** THE GUTS OF THE OPERATION *** */
+ /* Override these with functional things in subclasses */
+
+ function get($key) {
+ /* stub */
+ return false;
+ }
+
+ function set($key, $value, $exptime=0) {
+ /* stub */
+ return false;
+ }
+
+ function delete($key, $time=0) {
+ /* stub */
+ return false;
+ }
+
+ function lock($key, $timeout = 0) {
+ /* stub */
+ return true;
+ }
+
+ function unlock($key) {
+ /* stub */
+ return true;
+ }
+
+ /* *** Emulated functions *** */
+ /* Better performance can likely be got with custom written versions */
+ function get_multi($keys) {
+ $out = array();
+ foreach($keys as $key)
+ $out[$key] = $this->get($key);
+ return $out;
+ }
+
+ function set_multi($hash, $exptime=0) {
+ foreach($hash as $key => $value)
+ $this->set($key, $value, $exptime);
+ }
+
+ function add($key, $value, $exptime=0) {
+ if( $this->get($key) == false ) {
+ $this->set($key, $value, $exptime);
+ return true;
+ }
+ }
+
+ function add_multi($hash, $exptime=0) {
+ foreach($hash as $key => $value)
+ $this->add($key, $value, $exptime);
+ }
+
+ function delete_multi($keys, $time=0) {
+ foreach($keys as $key)
+ $this->delete($key, $time);
+ }
+
+ function replace($key, $value, $exptime=0) {
+ if( $this->get($key) !== false )
+ $this->set($key, $value, $exptime);
+ }
+
+ function incr($key, $value=1) {
+ if ( !$this->lock($key) ) {
+ return false;
+ }
+ $value = intval($value);
+ if($value < 0) $value = 0;
+
+ $n = false;
+ if( ($n = $this->get($key)) !== false ) {
+ $n += $value;
+ $this->set($key, $n); // exptime?
+ }
+ $this->unlock($key);
+ return $n;
+ }
+
+ function decr($key, $value=1) {
+ if ( !$this->lock($key) ) {
+ return false;
+ }
+ $value = intval($value);
+ if($value < 0) $value = 0;
+
+ $m = false;
+ if( ($n = $this->get($key)) !== false ) {
+ $m = $n - $value;
+ if($m < 0) $m = 0;
+ $this->set($key, $m); // exptime?
+ }
+ $this->unlock($key);
+ return $m;
+ }
+
+ function _debug($text) {
+ if($this->debugmode)
+ wfDebug("BagOStuff debug: $text\n");
+ }
+
+ /**
+ * Convert an optionally relative time to an absolute time
+ */
+ static function convertExpiry( $exptime ) {
+ if(($exptime != 0) && ($exptime < 3600*24*30)) {
+ return time() + $exptime;
+ } else {
+ return $exptime;
+ }
+ }
+}
+
+
+/**
+ * Functional versions!
+ * @todo document
+ * @package MediaWiki
+ */
+class HashBagOStuff extends BagOStuff {
+ /*
+ This is a test of the interface, mainly. It stores
+ things in an associative array, which is not going to
+ persist between program runs.
+ */
+ var $bag;
+
+ function HashBagOStuff() {
+ $this->bag = array();
+ }
+
+ function _expire($key) {
+ $et = $this->bag[$key][1];
+ if(($et == 0) || ($et > time()))
+ return false;
+ $this->delete($key);
+ return true;
+ }
+
+ function get($key) {
+ if(!$this->bag[$key])
+ return false;
+ if($this->_expire($key))
+ return false;
+ return $this->bag[$key][0];
+ }
+
+ function set($key,$value,$exptime=0) {
+ $this->bag[$key] = array( $value, BagOStuff::convertExpiry( $exptime ) );
+ }
+
+ function delete($key,$time=0) {
+ if(!$this->bag[$key])
+ return false;
+ unset($this->bag[$key]);
+ return true;
+ }
+}
+
+/*
+CREATE TABLE objectcache (
+ keyname char(255) binary not null default '',
+ value mediumblob,
+ exptime datetime,
+ unique key (keyname),
+ key (exptime)
+);
+*/
+
+/**
+ * @todo document
+ * @abstract
+ * @package MediaWiki
+ */
+abstract class SqlBagOStuff extends BagOStuff {
+ var $table;
+ var $lastexpireall = 0;
+
+ function SqlBagOStuff($tablename = 'objectcache') {
+ $this->table = $tablename;
+ }
+
+ function get($key) {
+ /* expire old entries if any */
+ $this->garbageCollect();
+
+ $res = $this->_query(
+ "SELECT value,exptime FROM $0 WHERE keyname='$1'", $key);
+ if(!$res) {
+ $this->_debug("get: ** error: " . $this->_dberror($res) . " **");
+ return false;
+ }
+ if($row=$this->_fetchobject($res)) {
+ $this->_debug("get: retrieved data; exp time is " . $row->exptime);
+ if ( $row->exptime != $this->_maxdatetime() &&
+ wfTimestamp( TS_UNIX, $row->exptime ) < time() )
+ {
+ $this->_debug("get: key has expired, deleting");
+ $this->delete($key);
+ return false;
+ }
+ return $this->_unserialize($this->_blobdecode($row->value));
+ } else {
+ $this->_debug('get: no matching rows');
+ }
+ return false;
+ }
+
+ function set($key,$value,$exptime=0) {
+ $exptime = intval($exptime);
+ if($exptime < 0) $exptime = 0;
+ if($exptime == 0) {
+ $exp = $this->_maxdatetime();
+ } else {
+ if($exptime < 3.16e8) # ~10 years
+ $exptime += time();
+ $exp = $this->_fromunixtime($exptime);
+ }
+ $this->delete( $key );
+ $this->_doinsert($this->getTableName(), array(
+ 'keyname' => $key,
+ 'value' => $this->_blobencode($this->_serialize($value)),
+ 'exptime' => $exp
+ ));
+ return true; /* ? */
+ }
+
+ function delete($key,$time=0) {
+ $this->_query(
+ "DELETE FROM $0 WHERE keyname='$1'", $key );
+ return true; /* ? */
+ }
+
+ function getTableName() {
+ return $this->table;
+ }
+
+ function _query($sql) {
+ $reps = func_get_args();
+ $reps[0] = $this->getTableName();
+ // ewwww
+ for($i=0;$i<count($reps);$i++) {
+ $sql = str_replace(
+ '$' . $i,
+ $i > 0 ? $this->_strencode($reps[$i]) : $reps[$i],
+ $sql);
+ }
+ $res = $this->_doquery($sql);
+ if($res == false) {
+ $this->_debug('query failed: ' . $this->_dberror($res));
+ }
+ return $res;
+ }
+
+ function _strencode($str) {
+ /* Protect strings in SQL */
+ return str_replace( "'", "''", $str );
+ }
+ function _blobencode($str) {
+ return $str;
+ }
+ function _blobdecode($str) {
+ return $str;
+ }
+
+ abstract function _doinsert($table, $vals);
+ abstract function _doquery($sql);
+
+ function _freeresult($result) {
+ /* stub */
+ return false;
+ }
+
+ function _dberror($result) {
+ /* stub */
+ return 'unknown error';
+ }
+
+ abstract function _maxdatetime();
+ abstract function _fromunixtime($ts);
+
+ function garbageCollect() {
+ /* Ignore 99% of requests */
+ if ( !mt_rand( 0, 100 ) ) {
+ $nowtime = time();
+ /* Avoid repeating the delete within a few seconds */
+ if ( $nowtime > ($this->lastexpireall + 1) ) {
+ $this->lastexpireall = $nowtime;
+ $this->expireall();
+ }
+ }
+ }
+
+ function expireall() {
+ /* Remove any items that have expired */
+ $now = $this->_fromunixtime( time() );
+ $this->_query( "DELETE FROM $0 WHERE exptime < '$now'" );
+ }
+
+ function deleteall() {
+ /* Clear *all* items from cache table */
+ $this->_query( "DELETE FROM $0" );
+ }
+
+ /**
+ * Serialize an object and, if possible, compress the representation.
+ * On typical message and page data, this can provide a 3X decrease
+ * in storage requirements.
+ *
+ * @param mixed $data
+ * @return string
+ */
+ function _serialize( &$data ) {
+ $serial = serialize( $data );
+ if( function_exists( 'gzdeflate' ) ) {
+ return gzdeflate( $serial );
+ } else {
+ return $serial;
+ }
+ }
+
+ /**
+ * Unserialize and, if necessary, decompress an object.
+ * @param string $serial
+ * @return mixed
+ */
+ function _unserialize( $serial ) {
+ if( function_exists( 'gzinflate' ) ) {
+ $decomp = @gzinflate( $serial );
+ if( false !== $decomp ) {
+ $serial = $decomp;
+ }
+ }
+ $ret = unserialize( $serial );
+ return $ret;
+ }
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class MediaWikiBagOStuff extends SqlBagOStuff {
+ var $tableInitialised = false;
+
+ function _doquery($sql) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->query($sql, 'MediaWikiBagOStuff::_doquery');
+ }
+ function _doinsert($t, $v) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->insert($t, $v, 'MediaWikiBagOStuff::_doinsert',
+ array( 'IGNORE' ) );
+ }
+ function _fetchobject($result) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->fetchObject($result);
+ }
+ function _freeresult($result) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->freeResult($result);
+ }
+ function _dberror($result) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->lastError();
+ }
+ function _maxdatetime() {
+ $dbw =& wfGetDB(DB_MASTER);
+ if ( time() > 0x7fffffff ) {
+ return $this->_fromunixtime( 1<<62 );
+ } else {
+ return $this->_fromunixtime( 0x7fffffff );
+ }
+ }
+ function _fromunixtime($ts) {
+ $dbw =& wfGetDB(DB_MASTER);
+ return $dbw->timestamp($ts);
+ }
+ function _strencode($s) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->strencode($s);
+ }
+ function _blobencode($s) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->encodeBlob($s);
+ }
+ function _blobdecode($s) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->decodeBlob($s);
+ }
+ function getTableName() {
+ if ( !$this->tableInitialised ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ /* This is actually a hack, we should be able
+ to use Language classes here... or not */
+ if (!$dbw)
+ throw new MWException("Could not connect to database");
+ $this->table = $dbw->tableName( $this->table );
+ $this->tableInitialised = true;
+ }
+ return $this->table;
+ }
+}
+
+/**
+ * This is a wrapper for Turck MMCache's shared memory functions.
+ *
+ * You can store objects with mmcache_put() and mmcache_get(), but Turck seems
+ * to use a weird custom serializer that randomly segfaults. So we wrap calls
+ * with serialize()/unserialize().
+ *
+ * The thing I noticed about the Turck serialized data was that unlike ordinary
+ * serialize(), it contained the names of methods, and judging by the amount of
+ * binary data, perhaps even the bytecode of the methods themselves. It may be
+ * that Turck's serializer is faster, so a possible future extension would be
+ * to use it for arrays but not for objects.
+ *
+ * @package MediaWiki
+ */
+class TurckBagOStuff extends BagOStuff {
+ function get($key) {
+ $val = mmcache_get( $key );
+ if ( is_string( $val ) ) {
+ $val = unserialize( $val );
+ }
+ return $val;
+ }
+
+ function set($key, $value, $exptime=0) {
+ mmcache_put( $key, serialize( $value ), $exptime );
+ return true;
+ }
+
+ function delete($key, $time=0) {
+ mmcache_rm( $key );
+ return true;
+ }
+
+ function lock($key, $waitTimeout = 0 ) {
+ mmcache_lock( $key );
+ return true;
+ }
+
+ function unlock($key) {
+ mmcache_unlock( $key );
+ return true;
+ }
+}
+
+/**
+ * This is a wrapper for APC's shared memory functions
+ *
+ * @package MediaWiki
+ */
+
+class APCBagOStuff extends BagOStuff {
+ function get($key) {
+ $val = apc_fetch($key);
+ if ( is_string( $val ) ) {
+ $val = unserialize( $val );
+ }
+ return $val;
+ }
+
+ function set($key, $value, $exptime=0) {
+ apc_store($key, serialize($value), $exptime);
+ return true;
+ }
+
+ function delete($key, $time=0) {
+ apc_delete($key);
+ return true;
+ }
+}
+
+
+/**
+ * This is a wrapper for eAccelerator's shared memory functions.
+ *
+ * This is basically identical to the Turck MMCache version,
+ * mostly because eAccelerator is based on Turck MMCache.
+ *
+ * @package MediaWiki
+ */
+class eAccelBagOStuff extends BagOStuff {
+ function get($key) {
+ $val = eaccelerator_get( $key );
+ if ( is_string( $val ) ) {
+ $val = unserialize( $val );
+ }
+ return $val;
+ }
+
+ function set($key, $value, $exptime=0) {
+ eaccelerator_put( $key, serialize( $value ), $exptime );
+ return true;
+ }
+
+ function delete($key, $time=0) {
+ eaccelerator_rm( $key );
+ return true;
+ }
+
+ function lock($key, $waitTimeout = 0 ) {
+ eaccelerator_lock( $key );
+ return true;
+ }
+
+ function unlock($key) {
+ eaccelerator_unlock( $key );
+ return true;
+ }
+}
+
+class DBABagOStuff extends BagOStuff {
+ var $mHandler, $mFile, $mReader, $mWriter, $mDisabled;
+
+ function __construct( $handler = 'db3', $dir = false ) {
+ if ( $dir === false ) {
+ global $wgTmpDirectory;
+ $dir = $wgTmpDirectory;
+ }
+ $this->mFile = "$dir/mw-cache-" . wfWikiID();
+ $this->mFile .= '.db';
+ $this->mHandler = $handler;
+ }
+
+ /**
+ * Encode value and expiry for storage
+ */
+ function encode( $value, $expiry ) {
+ # Convert to absolute time
+ $expiry = BagOStuff::convertExpiry( $expiry );
+ return sprintf( '%010u', intval( $expiry ) ) . ' ' . serialize( $value );
+ }
+
+ /**
+ * @return list containing value first and expiry second
+ */
+ function decode( $blob ) {
+ if ( !is_string( $blob ) ) {
+ return array( null, 0 );
+ } else {
+ return array(
+ unserialize( substr( $blob, 11 ) ),
+ intval( substr( $blob, 0, 10 ) )
+ );
+ }
+ }
+
+ function getReader() {
+ if ( file_exists( $this->mFile ) ) {
+ $handle = dba_open( $this->mFile, 'rl', $this->mHandler );
+ } else {
+ $handle = $this->getWriter();
+ }
+ if ( !$handle ) {
+ wfDebug( "Unable to open DBA cache file {$this->mFile}\n" );
+ }
+ return $handle;
+ }
+
+ function getWriter() {
+ $handle = dba_open( $this->mFile, 'cl', $this->mHandler );
+ if ( !$handle ) {
+ wfDebug( "Unable to open DBA cache file {$this->mFile}\n" );
+ }
+ return $handle;
+ }
+
+ function get( $key ) {
+ wfProfileIn( __METHOD__ );
+ wfDebug( __METHOD__."($key)\n" );
+ $handle = $this->getReader();
+ if ( !$handle ) {
+ return null;
+ }
+ $val = dba_fetch( $key, $handle );
+ list( $val, $expiry ) = $this->decode( $val );
+ # Must close ASAP because locks are held
+ dba_close( $handle );
+
+ if ( !is_null( $val ) && $expiry && $expiry < time() ) {
+ # Key is expired, delete it
+ $handle = $this->getWriter();
+ dba_delete( $key, $handle );
+ dba_close( $handle );
+ wfDebug( __METHOD__.": $key expired\n" );
+ $val = null;
+ }
+ wfProfileOut( __METHOD__ );
+ return $val;
+ }
+
+ function set( $key, $value, $exptime=0 ) {
+ wfProfileIn( __METHOD__ );
+ wfDebug( __METHOD__."($key)\n" );
+ $blob = $this->encode( $value, $exptime );
+ $handle = $this->getWriter();
+ if ( !$handle ) {
+ return false;
+ }
+ $ret = dba_replace( $key, $blob, $handle );
+ dba_close( $handle );
+ wfProfileOut( __METHOD__ );
+ return $ret;
+ }
+
+ function delete( $key, $time = 0 ) {
+ wfProfileIn( __METHOD__ );
+ $handle = $this->getWriter();
+ if ( !$handle ) {
+ return false;
+ }
+ $ret = dba_delete( $key, $handle );
+ dba_close( $handle );
+ wfProfileOut( __METHOD__ );
+ return $ret;
+ }
+
+ function add( $key, $value, $exptime = 0 ) {
+ wfProfileIn( __METHOD__ );
+ $blob = $this->encode( $value, $exptime );
+ $handle = $this->getWriter();
+ if ( !$handle ) {
+ return false;
+ }
+ $ret = dba_insert( $key, $blob, $handle );
+ # Insert failed, check to see if it failed due to an expired key
+ if ( !$ret ) {
+ list( $value, $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
+ if ( $expiry < time() ) {
+ # Yes expired, delete and try again
+ dba_delete( $key, $handle );
+ $ret = dba_insert( $key, $blob, $handle );
+ # This time if it failed then it will be handled by the caller like any other race
+ }
+ }
+
+ dba_close( $handle );
+ wfProfileOut( __METHOD__ );
+ return $ret;
+ }
+}
+
+?>
diff --git a/includes/Block.php b/includes/Block.php
new file mode 100644
index 000000000000..ff813ba3e4aa
--- /dev/null
+++ b/includes/Block.php
@@ -0,0 +1,669 @@
+<?php
+/**
+ * Blocks and bans object
+ * @package MediaWiki
+ */
+
+/**
+ * The block class
+ * All the functions in this class assume the object is either explicitly
+ * loaded or filled. It is not load-on-demand. There are no accessors.
+ *
+ * Globals used: $wgAutoblockExpiry, $wgAntiLockFlags
+ *
+ * @todo This could be used everywhere, but it isn't.
+ * @package MediaWiki
+ */
+class Block
+{
+ /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
+ $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock;
+ /* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster, $mByName;
+
+ const EB_KEEP_EXPIRED = 1;
+ const EB_FOR_UPDATE = 2;
+ const EB_RANGE_ONLY = 4;
+
+ function Block( $address = '', $user = 0, $by = 0, $reason = '',
+ $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0 )
+ {
+ $this->mId = 0;
+ $this->mAddress = $address;
+ $this->mUser = $user;
+ $this->mBy = $by;
+ $this->mReason = $reason;
+ $this->mTimestamp = wfTimestamp(TS_MW,$timestamp);
+ $this->mAuto = $auto;
+ $this->mAnonOnly = $anonOnly;
+ $this->mCreateAccount = $createAccount;
+ $this->mExpiry = self::decodeExpiry( $expiry );
+ $this->mEnableAutoblock = $enableAutoblock;
+
+ $this->mForUpdate = false;
+ $this->mFromMaster = false;
+ $this->mByName = false;
+ $this->initialiseRange();
+ }
+
+ static function newFromDB( $address, $user = 0, $killExpired = true )
+ {
+ $block = new Block();
+ $block->load( $address, $user, $killExpired );
+ if ( $block->isValid() ) {
+ return $block;
+ } else {
+ return null;
+ }
+ }
+
+ static function newFromID( $id )
+ {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->resultObject( $dbr->select( 'ipblocks', '*',
+ array( 'ipb_id' => $id ), __METHOD__ ) );
+ $block = new Block;
+ if ( $block->loadFromResult( $res ) ) {
+ return $block;
+ } else {
+ return null;
+ }
+ }
+
+ function clear()
+ {
+ $this->mAddress = $this->mReason = $this->mTimestamp = '';
+ $this->mId = $this->mAnonOnly = $this->mCreateAccount =
+ $this->mEnableAutoblock = $this->mAuto = $this->mUser =
+ $this->mBy = 0;
+ $this->mByName = false;
+ }
+
+ /**
+ * Get the DB object and set the reference parameter to the query options
+ */
+ function &getDBOptions( &$options )
+ {
+ global $wgAntiLockFlags;
+ if ( $this->mForUpdate || $this->mFromMaster ) {
+ $db =& wfGetDB( DB_MASTER );
+ if ( !$this->mForUpdate || ($wgAntiLockFlags & ALF_NO_BLOCK_LOCK) ) {
+ $options = array();
+ } else {
+ $options = array( 'FOR UPDATE' );
+ }
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ $options = array();
+ }
+ return $db;
+ }
+
+ /**
+ * Get a ban from the DB, with either the given address or the given username
+ *
+ * @param string $address The IP address of the user, or blank to skip IP blocks
+ * @param integer $user The user ID, or zero for anonymous users
+ * @param bool $killExpired Whether to delete expired rows while loading
+ *
+ */
+ function load( $address = '', $user = 0, $killExpired = true )
+ {
+ wfDebug( "Block::load: '$address', '$user', $killExpired\n" );
+
+ $options = array();
+ $db =& $this->getDBOptions( $options );
+
+ if ( 0 == $user && $address == '' ) {
+ # Invalid user specification, not blocked
+ $this->clear();
+ return false;
+ }
+
+ # Try user block
+ if ( $user ) {
+ $res = $db->resultObject( $db->select( 'ipblocks', '*', array( 'ipb_user' => $user ),
+ __METHOD__, $options ) );
+ if ( $this->loadFromResult( $res, $killExpired ) ) {
+ return true;
+ }
+ }
+
+ # Try IP block
+ # TODO: improve performance by merging this query with the autoblock one
+ # Slightly tricky while handling killExpired as well
+ if ( $address ) {
+ $conds = array( 'ipb_address' => $address, 'ipb_auto' => 0 );
+ $res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
+ if ( $this->loadFromResult( $res, $killExpired ) ) {
+ if ( $user && $this->mAnonOnly ) {
+ # Block is marked anon-only
+ # Whitelist this IP address against autoblocks and range blocks
+ $this->clear();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ # Try range block
+ if ( $this->loadRange( $address, $killExpired, $user == 0 ) ) {
+ if ( $user && $this->mAnonOnly ) {
+ $this->clear();
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ # Try autoblock
+ if ( $address ) {
+ $conds = array( 'ipb_address' => $address, 'ipb_auto' => 1 );
+ if ( $user ) {
+ $conds['ipb_anon_only'] = 0;
+ }
+ $res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
+ if ( $this->loadFromResult( $res, $killExpired ) ) {
+ return true;
+ }
+ }
+
+ # Give up
+ $this->clear();
+ return false;
+ }
+
+ /**
+ * Fill in member variables from a result wrapper
+ */
+ function loadFromResult( ResultWrapper $res, $killExpired = true ) {
+ $ret = false;
+ if ( 0 != $res->numRows() ) {
+ # Get first block
+ $row = $res->fetchObject();
+ $this->initFromRow( $row );
+
+ if ( $killExpired ) {
+ # If requested, delete expired rows
+ do {
+ $killed = $this->deleteIfExpired();
+ if ( $killed ) {
+ $row = $res->fetchObject();
+ if ( $row ) {
+ $this->initFromRow( $row );
+ }
+ }
+ } while ( $killed && $row );
+
+ # If there were any left after the killing finished, return true
+ if ( $row ) {
+ $ret = true;
+ }
+ } else {
+ $ret = true;
+ }
+ }
+ $res->free();
+ return $ret;
+ }
+
+ /**
+ * Search the database for any range blocks matching the given address, and
+ * load the row if one is found.
+ */
+ function loadRange( $address, $killExpired = true )
+ {
+ $iaddr = IP::toHex( $address );
+ if ( $iaddr === false ) {
+ # Invalid address
+ return false;
+ }
+
+ # Only scan ranges which start in this /16, this improves search speed
+ # Blocks should not cross a /16 boundary.
+ $range = substr( $iaddr, 0, 4 );
+
+ $options = array();
+ $db =& $this->getDBOptions( $options );
+ $conds = array(
+ "ipb_range_start LIKE '$range%'",
+ "ipb_range_start <= '$iaddr'",
+ "ipb_range_end >= '$iaddr'"
+ );
+
+ $res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
+ $success = $this->loadFromResult( $res, $killExpired );
+ return $success;
+ }
+
+ /**
+ * Determine if a given integer IPv4 address is in a given CIDR network
+ * @deprecated Use IP::isInRange
+ */
+ function isAddressInRange( $addr, $range ) {
+ return IP::isInRange( $addr, $range );
+ }
+
+ function initFromRow( $row )
+ {
+ $this->mAddress = $row->ipb_address;
+ $this->mReason = $row->ipb_reason;
+ $this->mTimestamp = wfTimestamp(TS_MW,$row->ipb_timestamp);
+ $this->mUser = $row->ipb_user;
+ $this->mBy = $row->ipb_by;
+ $this->mAuto = $row->ipb_auto;
+ $this->mAnonOnly = $row->ipb_anon_only;
+ $this->mCreateAccount = $row->ipb_create_account;
+ $this->mEnableAutoblock = $row->ipb_enable_autoblock;
+ $this->mId = $row->ipb_id;
+ $this->mExpiry = self::decodeExpiry( $row->ipb_expiry );
+ if ( isset( $row->user_name ) ) {
+ $this->mByName = $row->user_name;
+ } else {
+ $this->mByName = false;
+ }
+ $this->mRangeStart = $row->ipb_range_start;
+ $this->mRangeEnd = $row->ipb_range_end;
+ }
+
+ function initialiseRange()
+ {
+ $this->mRangeStart = '';
+ $this->mRangeEnd = '';
+
+ if ( $this->mUser == 0 ) {
+ list( $this->mRangeStart, $this->mRangeEnd ) = IP::parseRange( $this->mAddress );
+ }
+ }
+
+ /**
+ * Callback with a Block object for every block
+ * @return integer number of blocks;
+ */
+ /*static*/ function enumBlocks( $callback, $tag, $flags = 0 )
+ {
+ global $wgAntiLockFlags;
+
+ $block = new Block();
+ if ( $flags & Block::EB_FOR_UPDATE ) {
+ $db =& wfGetDB( DB_MASTER );
+ if ( $wgAntiLockFlags & ALF_NO_BLOCK_LOCK ) {
+ $options = '';
+ } else {
+ $options = 'FOR UPDATE';
+ }
+ $block->forUpdate( true );
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ $options = '';
+ }
+ if ( $flags & Block::EB_RANGE_ONLY ) {
+ $cond = " AND ipb_range_start <> ''";
+ } else {
+ $cond = '';
+ }
+
+ $now = wfTimestampNow();
+
+ list( $ipblocks, $user ) = $db->tableNamesN( 'ipblocks', 'user' );
+
+ $sql = "SELECT $ipblocks.*,user_name FROM $ipblocks,$user " .
+ "WHERE user_id=ipb_by $cond ORDER BY ipb_timestamp DESC $options";
+ $res = $db->query( $sql, 'Block::enumBlocks' );
+ $num_rows = $db->numRows( $res );
+
+ while ( $row = $db->fetchObject( $res ) ) {
+ $block->initFromRow( $row );
+ if ( ( $flags & Block::EB_RANGE_ONLY ) && $block->mRangeStart == '' ) {
+ continue;
+ }
+
+ if ( !( $flags & Block::EB_KEEP_EXPIRED ) ) {
+ if ( $block->mExpiry && $now > $block->mExpiry ) {
+ $block->delete();
+ } else {
+ call_user_func( $callback, $block, $tag );
+ }
+ } else {
+ call_user_func( $callback, $block, $tag );
+ }
+ }
+ $db->freeResult( $res );
+ return $num_rows;
+ }
+
+ function delete()
+ {
+ if (wfReadOnly()) {
+ return false;
+ }
+ if ( !$this->mId ) {
+ throw new MWException( "Block::delete() now requires that the mId member be filled\n" );
+ }
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'ipblocks', array( 'ipb_id' => $this->mId ), __METHOD__ );
+ return $dbw->affectedRows() > 0;
+ }
+
+ /**
+ * Insert a block into the block table.
+ *@return Whether or not the insertion was successful.
+ */
+ function insert()
+ {
+ wfDebug( "Block::insert; timestamp {$this->mTimestamp}\n" );
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ # Unset ipb_anon_only for user blocks, makes no sense
+ if ( $this->mUser ) {
+ $this->mAnonOnly = 0;
+ }
+
+ # Unset ipb_enable_autoblock for IP blocks, makes no sense
+ if ( !$this->mUser ) {
+ $this->mEnableAutoblock = 0;
+ }
+
+ # Don't collide with expired blocks
+ Block::purgeExpired();
+
+ $ipb_id = $dbw->nextSequenceValue('ipblocks_ipb_id_val');
+ $dbw->insert( 'ipblocks',
+ array(
+ 'ipb_id' => $ipb_id,
+ 'ipb_address' => $this->mAddress,
+ 'ipb_user' => $this->mUser,
+ 'ipb_by' => $this->mBy,
+ 'ipb_reason' => $this->mReason,
+ 'ipb_timestamp' => $dbw->timestamp($this->mTimestamp),
+ 'ipb_auto' => $this->mAuto,
+ 'ipb_anon_only' => $this->mAnonOnly,
+ 'ipb_create_account' => $this->mCreateAccount,
+ 'ipb_enable_autoblock' => $this->mEnableAutoblock,
+ 'ipb_expiry' => self::encodeExpiry( $this->mExpiry, $dbw ),
+ 'ipb_range_start' => $this->mRangeStart,
+ 'ipb_range_end' => $this->mRangeEnd,
+ ), 'Block::insert', array( 'IGNORE' )
+ );
+ $affected = $dbw->affectedRows();
+ $dbw->commit();
+
+ if ($affected)
+ $this->doRetroactiveAutoblock();
+
+ return $affected;
+ }
+
+ /**
+ * Retroactively autoblocks the last IP used by the user (if it is a user)
+ * blocked by this Block.
+ *@return Whether or not a retroactive autoblock was made.
+ */
+ function doRetroactiveAutoblock() {
+ $dbr = wfGetDB( DB_SLAVE );
+ #If autoblock is enabled, autoblock the LAST IP used
+ # - stolen shamelessly from CheckUser_body.php
+
+ if ($this->mEnableAutoblock && $this->mUser) {
+ wfDebug("Doing retroactive autoblocks for " . $this->mAddress . "\n");
+
+ $row = $dbr->selectRow( 'recentchanges', array( 'rc_ip' ), array( 'rc_user_text' => $this->mAddress ),
+ __METHOD__ , array( 'ORDER BY' => 'rc_timestamp DESC' ) );
+
+ if ( !$row || !$row->rc_ip ) {
+ #No results, don't autoblock anything
+ wfDebug("No IP found to retroactively autoblock\n");
+ } else {
+ #Limit is 1, so no loop needed.
+ $retroblockip = $row->rc_ip;
+ return $this->doAutoblock($retroblockip);
+ }
+ }
+ }
+
+ /**
+ * Autoblocks the given IP, referring to this Block.
+ * @param $autoblockip The IP to autoblock.
+ * @return bool Whether or not an autoblock was inserted.
+ */
+ function doAutoblock( $autoblockip ) {
+ # Check if this IP address is already blocked
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ # If autoblocks are disabled, go away.
+ if ( !$this->mEnableAutoblock ) {
+ return;
+ }
+
+ # Check for presence on the autoblock whitelist
+ # TODO cache this?
+ $lines = explode( "\n", wfMsgForContentNoTrans( 'autoblock_whitelist' ) );
+
+ $ip = $autoblockip;
+
+ wfDebug("Checking the autoblock whitelist..\n");
+
+ foreach( $lines as $line ) {
+ # List items only
+ if ( substr( $line, 0, 1 ) !== '*' ) {
+ continue;
+ }
+
+ $wlEntry = substr($line, 1);
+ $wlEntry = trim($wlEntry);
+
+ wfDebug("Checking $ip against $wlEntry...");
+
+ # Is the IP in this range?
+ if (IP::isInRange( $ip, $wlEntry )) {
+ wfDebug(" IP $ip matches $wlEntry, not autoblocking\n");
+ #$autoblockip = null; # Don't autoblock a whitelisted IP.
+ return; #This /SHOULD/ introduce a dummy block - but
+ # I don't know a safe way to do so. -werdna
+ } else {
+ wfDebug( " No match\n" );
+ }
+ }
+
+ # It's okay to autoblock. Go ahead and create/insert the block.
+
+ $ipblock = Block::newFromDB( $autoblockip );
+ if ( $ipblock ) {
+ # If the user is already blocked. Then check if the autoblock would
+ # exceed the user block. If it would exceed, then do nothing, else
+ # prolong block time
+ if ($this->mExpiry &&
+ ($this->mExpiry < Block::getAutoblockExpiry($ipblock->mTimestamp))) {
+ return;
+ }
+ # Just update the timestamp
+ $ipblock->updateTimestamp();
+ return;
+ } else {
+ $ipblock = new Block;
+ }
+
+ # Make a new block object with the desired properties
+ wfDebug( "Autoblocking {$this->mAddress}@" . $autoblockip . "\n" );
+ $ipblock->mAddress = $autoblockip;
+ $ipblock->mUser = 0;
+ $ipblock->mBy = $this->mBy;
+ $ipblock->mReason = wfMsgForContent( 'autoblocker', $this->mAddress, $this->mReason );
+ $ipblock->mTimestamp = wfTimestampNow();
+ $ipblock->mAuto = 1;
+ $ipblock->mCreateAccount = $this->mCreateAccount;
+
+ # If the user is already blocked with an expiry date, we don't
+ # want to pile on top of that!
+ if($this->mExpiry) {
+ $ipblock->mExpiry = min ( $this->mExpiry, Block::getAutoblockExpiry( $this->mTimestamp ));
+ } else {
+ $ipblock->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
+ }
+ # Insert it
+ return $ipblock->insert();
+ }
+
+ function deleteIfExpired()
+ {
+ $fname = 'Block::deleteIfExpired';
+ wfProfileIn( $fname );
+ if ( $this->isExpired() ) {
+ wfDebug( "Block::deleteIfExpired() -- deleting\n" );
+ $this->delete();
+ $retVal = true;
+ } else {
+ wfDebug( "Block::deleteIfExpired() -- not expired\n" );
+ $retVal = false;
+ }
+ wfProfileOut( $fname );
+ return $retVal;
+ }
+
+ function isExpired()
+ {
+ wfDebug( "Block::isExpired() checking current " . wfTimestampNow() . " vs $this->mExpiry\n" );
+ if ( !$this->mExpiry ) {
+ return false;
+ } else {
+ return wfTimestampNow() > $this->mExpiry;
+ }
+ }
+
+ function isValid()
+ {
+ return $this->mAddress != '';
+ }
+
+ function updateTimestamp()
+ {
+ if ( $this->mAuto ) {
+ $this->mTimestamp = wfTimestamp();
+ $this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'ipblocks',
+ array( /* SET */
+ 'ipb_timestamp' => $dbw->timestamp($this->mTimestamp),
+ 'ipb_expiry' => $dbw->timestamp($this->mExpiry),
+ ), array( /* WHERE */
+ 'ipb_address' => $this->mAddress
+ ), 'Block::updateTimestamp'
+ );
+ }
+ }
+
+ /*
+ function getIntegerAddr()
+ {
+ return $this->mIntegerAddr;
+ }
+
+ function getNetworkBits()
+ {
+ return $this->mNetworkBits;
+ }*/
+
+ /**
+ * @return The blocker user ID.
+ */
+ public function getBy() {
+ return $this->mBy;
+ }
+
+ /**
+ * @return The blocker user name.
+ */
+ function getByName()
+ {
+ if ( $this->mByName === false ) {
+ $this->mByName = User::whoIs( $this->mBy );
+ }
+ return $this->mByName;
+ }
+
+ function forUpdate( $x = NULL ) {
+ return wfSetVar( $this->mForUpdate, $x );
+ }
+
+ function fromMaster( $x = NULL ) {
+ return wfSetVar( $this->mFromMaster, $x );
+ }
+
+ function getRedactedName() {
+ if ( $this->mAuto ) {
+ return '#' . $this->mId;
+ } else {
+ return $this->mAddress;
+ }
+ }
+
+ /**
+ * Encode expiry for DB
+ */
+ static function encodeExpiry( $expiry, $db ) {
+ if ( $expiry == '' || $expiry == Block::infinity() ) {
+ return Block::infinity();
+ } else {
+ return $db->timestamp( $expiry );
+ }
+ }
+
+ /**
+ * Decode expiry which has come from the DB
+ */
+ static function decodeExpiry( $expiry ) {
+ if ( $expiry == '' || $expiry == Block::infinity() ) {
+ return Block::infinity();
+ } else {
+ return wfTimestamp( TS_MW, $expiry );
+ }
+ }
+
+ static function getAutoblockExpiry( $timestamp )
+ {
+ global $wgAutoblockExpiry;
+ return wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $timestamp ) + $wgAutoblockExpiry );
+ }
+
+ static function normaliseRange( $range )
+ {
+ $parts = explode( '/', $range );
+ if ( count( $parts ) == 2 ) {
+ $shift = 32 - $parts[1];
+ $ipint = IP::toUnsigned( $parts[0] );
+ $ipint = $ipint >> $shift << $shift;
+ $newip = long2ip( $ipint );
+ $range = "$newip/{$parts[1]}";
+ }
+ return $range;
+ }
+
+ /**
+ * Purge expired blocks from the ipblocks table
+ */
+ static function purgeExpired() {
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'ipblocks', array( 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ), __METHOD__ );
+ }
+
+ static function infinity() {
+ # This is a special keyword for timestamps in PostgreSQL, and
+ # works with CHAR(14) as well because "i" sorts after all numbers.
+ return 'infinity';
+
+ /*
+ static $infinity;
+ if ( !isset( $infinity ) ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $infinity = $dbr->bigTimestamp();
+ }
+ return $infinity;
+ */
+ }
+
+}
+?>
diff --git a/includes/CacheDependency.php b/includes/CacheDependency.php
new file mode 100644
index 000000000000..4bb3d3286895
--- /dev/null
+++ b/includes/CacheDependency.php
@@ -0,0 +1,328 @@
+<?php
+
+/**
+ * This class stores an arbitrary value along with its dependencies.
+ * Users should typically only use DependencyWrapper::getFromCache(), rather
+ * than instantiating one of these objects directly.
+ */
+class DependencyWrapper {
+ var $value;
+ var $deps;
+
+ /**
+ * Create an instance.
+ * @param mixed $value The user-supplied value
+ * @param mixed $deps A dependency or dependency array. All dependencies
+ * must be objects implementing CacheDependency.
+ */
+ function __construct( $value = false, $deps = array() ) {
+ $this->value = $value;
+ if ( !is_array( $deps ) ) {
+ $deps = array( $deps );
+ }
+ $this->deps = $deps;
+ }
+
+ /**
+ * Returns true if any of the dependencies have expired
+ */
+ function isExpired() {
+ foreach ( $this->deps as $dep ) {
+ if ( $dep->isExpired() ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Initialise dependency values in preparation for storing. This must be
+ * called before serialization.
+ */
+ function initialiseDeps() {
+ foreach ( $this->deps as $dep ) {
+ $dep->loadDependencyValues();
+ }
+ }
+
+ /**
+ * Get the user-defined value
+ */
+ function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * Store the wrapper to a cache
+ */
+ function storeToCache( $cache, $key, $expiry = 0 ) {
+ $this->initialiseDeps();
+ $cache->set( $key, $this, $expiry );
+ }
+
+ /**
+ * Attempt to get a value from the cache. If the value is expired or missing,
+ * it will be generated with the callback function (if present), and the newly
+ * calculated value will be stored to the cache in a wrapper.
+ *
+ * @param object $cache A cache object such as $wgMemc
+ * @param string $key The cache key
+ * @param integer $expiry The expiry timestamp or interval in seconds
+ * @param mixed $callback The callback for generating the value, or false
+ * @param array $callbackParams The function parameters for the callback
+ * @param array $deps The dependencies to store on a cache miss. Note: these
+ * are not the dependencies used on a cache hit! Cache hits use the stored
+ * dependency array.
+ *
+ * @return mixed The value, or null if it was not present in the cache and no
+ * callback was defined.
+ */
+ static function getValueFromCache( $cache, $key, $expiry = 0, $callback = false,
+ $callbackParams = array(), $deps = array() )
+ {
+ $obj = $cache->get( $key );
+ if ( is_object( $obj ) && $obj instanceof DependencyWrapper && !$obj->isExpired() ) {
+ $value = $obj->value;
+ } elseif ( $callback ) {
+ $value = call_user_func_array( $callback, $callbackParams );
+ # Cache the newly-generated value
+ $wrapper = new DependencyWrapper( $value, $deps );
+ $wrapper->storeToCache( $cache, $key, $expiry );
+ } else {
+ $value = null;
+ }
+ return $value;
+ }
+}
+
+abstract class CacheDependency {
+ /**
+ * Returns true if the dependency is expired, false otherwise
+ */
+ abstract function isExpired();
+
+ /**
+ * Hook to perform any expensive pre-serialize loading of dependency values.
+ */
+ function loadDependencyValues() {}
+}
+
+class FileDependency extends CacheDependency {
+ var $filename, $timestamp;
+
+ /**
+ * Create a file dependency
+ *
+ * @param string $filename The name of the file, preferably fully qualified
+ * @param mixed $timestamp The unix last modified timestamp, or false if the
+ * file does not exist. If omitted, the timestamp will be loaded from
+ * the file.
+ *
+ * A dependency on a nonexistent file will be triggered when the file is
+ * created. A dependency on an existing file will be triggered when the
+ * file is changed.
+ */
+ function __construct( $filename, $timestamp = null ) {
+ $this->filename = $filename;
+ $this->timestamp = $timestamp;
+ }
+
+ function loadDependencyValues() {
+ if ( is_null( $this->timestamp ) ) {
+ if ( !file_exists( $this->filename ) ) {
+ # Dependency on a non-existent file
+ # This is a valid concept!
+ $this->timestamp = false;
+ } else {
+ $this->timestamp = filemtime( $this->filename );
+ }
+ }
+ }
+
+ function isExpired() {
+ if ( !file_exists( $this->filename ) ) {
+ if ( $this->timestamp === false ) {
+ # Still nonexistent
+ return false;
+ } else {
+ # Deleted
+ wfDebug( "Dependency triggered: {$this->filename} deleted.\n" );
+ return true;
+ }
+ } else {
+ $lastmod = filemtime( $this->filename );
+ if ( $lastmod > $this->timestamp ) {
+ # Modified or created
+ wfDebug( "Dependency triggered: {$this->filename} changed.\n" );
+ return true;
+ } else {
+ # Not modified
+ return false;
+ }
+ }
+ }
+}
+
+class TitleDependency extends CacheDependency {
+ var $titleObj;
+ var $ns, $dbk;
+ var $touched;
+
+ /**
+ * Construct a title dependency
+ * @param Title $title
+ */
+ function __construct( Title $title ) {
+ $this->titleObj = $title;
+ $this->ns = $title->getNamespace();
+ $this->dbk = $title->getDBkey();
+ }
+
+ function loadDependencyValues() {
+ $this->touched = $this->getTitle()->getTouched();
+ }
+
+ /**
+ * Get rid of bulky Title object for sleep
+ */
+ function __sleep() {
+ return array( 'ns', 'dbk', 'touched' );
+ }
+
+ function getTitle() {
+ if ( !isset( $this->titleObj ) ) {
+ $this->titleObj = Title::makeTitle( $this->ns, $this->dbk );
+ }
+ return $this->titleObj;
+ }
+
+ function isExpired() {
+ $touched = $this->getTitle()->getTouched();
+ if ( $this->touched === false ) {
+ if ( $touched === false ) {
+ # Still missing
+ return false;
+ } else {
+ # Created
+ return true;
+ }
+ } elseif ( $touched === false ) {
+ # Deleted
+ return true;
+ } elseif ( $touched > $this->touched ) {
+ # Updated
+ return true;
+ } else {
+ # Unmodified
+ return false;
+ }
+ }
+}
+
+class TitleListDependency extends CacheDependency {
+ var $linkBatch;
+ var $timestamps;
+
+ /**
+ * Construct a dependency on a list of titles
+ */
+ function __construct( LinkBatch $linkBatch ) {
+ $this->linkBatch = $linkBatch;
+ }
+
+ function calculateTimestamps() {
+ # Initialise values to false
+ $timestamps = array();
+ foreach ( $this->getLinkBatch()->data as $ns => $dbks ) {
+ if ( count( $dbks ) > 0 ) {
+ $timestamps[$ns] = array();
+ foreach ( $dbks as $dbk => $value ) {
+ $timestamps[$ns][$dbk] = false;
+ }
+ }
+ }
+
+ # Do the query
+ if ( count( $timestamps ) ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $where = $this->getLinkBatch()->constructSet( 'page', $dbr );
+ $res = $dbr->select( 'page',
+ array( 'page_namespace', 'page_title', 'page_touched' ),
+ $where, __METHOD__ );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $timestamps[$row->page_namespace][$row->page_title] = $row->page_touched;
+ }
+ }
+ return $timestamps;
+ }
+
+ function loadDependencyValues() {
+ $this->timestamps = $this->calculateTimestamps();
+ }
+
+ function __sleep() {
+ return array( 'timestamps' );
+ }
+
+ function getLinkBatch() {
+ if ( !isset( $this->linkBatch ) ){
+ $this->linkBatch = new LinkBatch;
+ $this->linkBatch->setArray( $this->timestamps );
+ }
+ return $this->linkBatch;
+ }
+
+ function isExpired() {
+ $newTimestamps = $this->calculateTimestamps();
+ foreach ( $this->timestamps as $ns => $dbks ) {
+ foreach ( $dbks as $dbk => $oldTimestamp ) {
+ $newTimestamp = $newTimestamps[$ns][$dbk];
+ if ( $oldTimestamp === false ) {
+ if ( $newTimestamp === false ) {
+ # Still missing
+ } else {
+ # Created
+ return true;
+ }
+ } elseif ( $newTimestamp === false ) {
+ # Deleted
+ return true;
+ } elseif ( $newTimestamp > $oldTimestamp ) {
+ # Updated
+ return true;
+ } else {
+ # Unmodified
+ }
+ }
+ }
+ return false;
+ }
+}
+
+class GlobalDependency extends CacheDependency {
+ var $name, $value;
+
+ function __construct( $name ) {
+ $this->name = $name;
+ $this->value = $GLOBALS[$name];
+ }
+
+ function isExpired() {
+ return $GLOBALS[$this->name] != $this->value;
+ }
+}
+
+class ConstantDependency extends CacheDependency {
+ var $name, $value;
+
+ function __construct( $name ) {
+ $this->name = $name;
+ $this->value = constant( $name );
+ }
+
+ function isExpired() {
+ return constant( $this->name ) != $this->value;
+ }
+}
+
+?>
diff --git a/includes/CategoryPage.php b/includes/CategoryPage.php
new file mode 100644
index 000000000000..0086a2f9682d
--- /dev/null
+++ b/includes/CategoryPage.php
@@ -0,0 +1,413 @@
+<?php
+/**
+ * Special handling for category description pages
+ * Modelled after ImagePage.php
+ *
+ * @package MediaWiki
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+/**
+ * @package MediaWiki
+ */
+class CategoryPage extends Article {
+ function view() {
+ if(!wfRunHooks('CategoryPageView', array(&$this))) return;
+
+ if ( NS_CATEGORY == $this->mTitle->getNamespace() ) {
+ $this->openShowCategory();
+ }
+
+ Article::view();
+
+ # If the article we've just shown is in the "Image" namespace,
+ # follow it with the history list and link list for the image
+ # it describes.
+
+ if ( NS_CATEGORY == $this->mTitle->getNamespace() ) {
+ $this->closeShowCategory();
+ }
+ }
+
+ function openShowCategory() {
+ # For overloading
+ }
+
+ function closeShowCategory() {
+ global $wgOut, $wgRequest;
+ $from = $wgRequest->getVal( 'from' );
+ $until = $wgRequest->getVal( 'until' );
+
+ $viewer = new CategoryViewer( $this->mTitle, $from, $until );
+ $wgOut->addHTML( $viewer->getHTML() );
+ }
+}
+
+class CategoryViewer {
+ var $title, $limit, $from, $until,
+ $articles, $articles_start_char,
+ $children, $children_start_char,
+ $showGallery, $gallery,
+ $skin;
+
+ function __construct( $title, $from = '', $until = '' ) {
+ global $wgCategoryPagingLimit;
+ $this->title = $title;
+ $this->from = $from;
+ $this->until = $until;
+ $this->limit = $wgCategoryPagingLimit;
+ }
+
+ /**
+ * Format the category data list.
+ *
+ * @param string $from -- return only sort keys from this item on
+ * @param string $until -- don't return keys after this point.
+ * @return string HTML output
+ * @private
+ */
+ function getHTML() {
+ global $wgOut, $wgCategoryMagicGallery, $wgCategoryPagingLimit;
+ wfProfileIn( __METHOD__ );
+
+ $this->showGallery = $wgCategoryMagicGallery && !$wgOut->mNoGallery;
+
+ $this->clearCategoryState();
+ $this->doCategoryQuery();
+ $this->finaliseCategoryState();
+
+ $r = $this->getCategoryTop() .
+ $this->getSubcategorySection() .
+ $this->getPagesSection() .
+ $this->getImageSection() .
+ $this->getCategoryBottom();
+
+ wfProfileOut( __METHOD__ );
+ return $r;
+ }
+
+ function clearCategoryState() {
+ $this->articles = array();
+ $this->articles_start_char = array();
+ $this->children = array();
+ $this->children_start_char = array();
+ if( $this->showGallery ) {
+ $this->gallery = new ImageGallery();
+ $this->gallery->setParsing();
+ }
+ }
+
+ function getSkin() {
+ if ( !$this->skin ) {
+ global $wgUser;
+ $this->skin = $wgUser->getSkin();
+ }
+ return $this->skin;
+ }
+
+ /**
+ * Add a subcategory to the internal lists
+ */
+ function addSubcategory( $title, $sortkey, $pageLength ) {
+ global $wgContLang;
+ // Subcategory; strip the 'Category' namespace from the link text.
+ $this->children[] = $this->getSkin()->makeKnownLinkObj(
+ $title, $wgContLang->convertHtml( $title->getText() ) );
+
+ $this->children_start_char[] = $this->getSubcategorySortChar( $title, $sortkey );
+ }
+
+ /**
+ * Get the character to be used for sorting subcategories.
+ * If there's a link from Category:A to Category:B, the sortkey of the resulting
+ * entry in the categorylinks table is Category:A, not A, which it SHOULD be.
+ * Workaround: If sortkey == "Category:".$title, than use $title for sorting,
+ * else use sortkey...
+ */
+ function getSubcategorySortChar( $title, $sortkey ) {
+ global $wgContLang;
+
+ if( $title->getPrefixedText() == $sortkey ) {
+ $firstChar = $wgContLang->firstChar( $title->getDBkey() );
+ } else {
+ $firstChar = $wgContLang->firstChar( $sortkey );
+ }
+
+ return $wgContLang->convert( $firstChar );
+ }
+
+ /**
+ * Add a page in the image namespace
+ */
+ function addImage( $title, $sortkey, $pageLength ) {
+ if ( $this->showGallery ) {
+ $image = new Image( $title );
+ if( $this->flip ) {
+ $this->gallery->insert( $image );
+ } else {
+ $this->gallery->add( $image );
+ }
+ } else {
+ $this->addPage( $title, $sortkey, $pageLength );
+ }
+ }
+
+ /**
+ * Add a miscellaneous page
+ */
+ function addPage( $title, $sortkey, $pageLength ) {
+ global $wgContLang;
+ $this->articles[] = $this->getSkin()->makeSizeLinkObj(
+ $pageLength, $title, $wgContLang->convert( $title->getPrefixedText() )
+ );
+ $this->articles_start_char[] = $wgContLang->convert( $wgContLang->firstChar( $sortkey ) );
+ }
+
+ function finaliseCategoryState() {
+ if( $this->flip ) {
+ $this->children = array_reverse( $this->children );
+ $this->children_start_char = array_reverse( $this->children_start_char );
+ $this->articles = array_reverse( $this->articles );
+ $this->articles_start_char = array_reverse( $this->articles_start_char );
+ }
+ }
+
+ function doCategoryQuery() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ if( $this->from != '' ) {
+ $pageCondition = 'cl_sortkey >= ' . $dbr->addQuotes( $this->from );
+ $this->flip = false;
+ } elseif( $this->until != '' ) {
+ $pageCondition = 'cl_sortkey < ' . $dbr->addQuotes( $this->until );
+ $this->flip = true;
+ } else {
+ $pageCondition = '1 = 1';
+ $this->flip = false;
+ }
+ $res = $dbr->select(
+ array( 'page', 'categorylinks' ),
+ array( 'page_title', 'page_namespace', 'page_len', 'cl_sortkey' ),
+ array( $pageCondition,
+ 'cl_from = page_id',
+ 'cl_to' => $this->title->getDBKey()),
+ #'page_is_redirect' => 0),
+ #+ $pageCondition,
+ __METHOD__,
+ array( 'ORDER BY' => $this->flip ? 'cl_sortkey DESC' : 'cl_sortkey',
+ 'LIMIT' => $this->limit + 1 ) );
+
+ $count = 0;
+ $this->nextPage = null;
+ while( $x = $dbr->fetchObject ( $res ) ) {
+ if( ++$count > $this->limit ) {
+ // We've reached the one extra which shows that there are
+ // additional pages to be had. Stop here...
+ $this->nextPage = $x->cl_sortkey;
+ break;
+ }
+
+ $title = Title::makeTitle( $x->page_namespace, $x->page_title );
+
+ if( $title->getNamespace() == NS_CATEGORY ) {
+ $this->addSubcategory( $title, $x->cl_sortkey, $x->page_len );
+ } elseif( $title->getNamespace() == NS_IMAGE ) {
+ $this->addImage( $title, $x->cl_sortkey, $x->page_len );
+ } else {
+ $this->addPage( $title, $x->cl_sortkey, $x->page_len );
+ }
+ }
+ $dbr->freeResult( $res );
+ }
+
+ function getCategoryTop() {
+ $r = "<br style=\"clear:both;\"/>\n";
+ if( $this->until != '' ) {
+ $r .= $this->pagingLinks( $this->title, $this->nextPage, $this->until, $this->limit );
+ } elseif( $this->nextPage != '' || $this->from != '' ) {
+ $r .= $this->pagingLinks( $this->title, $this->from, $this->nextPage, $this->limit );
+ }
+ return $r;
+ }
+
+ function getSubcategorySection() {
+ # Don't show subcategories section if there are none.
+ $r = '';
+ if( count( $this->children ) > 0 ) {
+ # Showing subcategories
+ $r .= "<div id=\"mw-subcategories\">\n";
+ $r .= '<h2>' . wfMsg( 'subcategories' ) . "</h2>\n";
+ $r .= wfMsgExt( 'subcategorycount', array( 'parse' ), count( $this->children) );
+ $r .= $this->formatList( $this->children, $this->children_start_char );
+ $r .= "\n</div>";
+ }
+ return $r;
+ }
+
+ function getPagesSection() {
+ $ti = htmlspecialchars( $this->title->getText() );
+ $r = "<div id=\"mw-pages\">\n";
+ $r .= '<h2>' . wfMsg( 'category_header', $ti ) . "</h2>\n";
+ $r .= wfMsgExt( 'categoryarticlecount', array( 'parse' ), count( $this->articles) );
+ $r .= $this->formatList( $this->articles, $this->articles_start_char );
+ $r .= "\n</div>";
+ return $r;
+ }
+
+ function getImageSection() {
+ if( $this->showGallery && ! $this->gallery->isEmpty() ) {
+ return "<div id=\"mw-category-media\">\n" .
+ '<h2>' . wfMsg( 'category-media-header', htmlspecialchars($this->title->getText()) ) . "</h2>\n" .
+ wfMsgExt( 'category-media-count', array( 'parse' ), $this->gallery->count() ) .
+ $this->gallery->toHTML() . "\n</div>";
+ } else {
+ return '';
+ }
+ }
+
+ function getCategoryBottom() {
+ if( $this->until != '' ) {
+ return $this->pagingLinks( $this->title, $this->nextPage, $this->until, $this->limit );
+ } elseif( $this->nextPage != '' || $this->from != '' ) {
+ return $this->pagingLinks( $this->title, $this->from, $this->nextPage, $this->limit );
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Format a list of articles chunked by letter, either as a
+ * bullet list or a columnar format, depending on the length.
+ *
+ * @param array $articles
+ * @param array $articles_start_char
+ * @param int $cutoff
+ * @return string
+ * @private
+ */
+ function formatList( $articles, $articles_start_char, $cutoff = 6 ) {
+ if ( count ( $articles ) > $cutoff ) {
+ return $this->columnList( $articles, $articles_start_char );
+ } elseif ( count($articles) > 0) {
+ // for short lists of articles in categories.
+ return $this->shortList( $articles, $articles_start_char );
+ }
+ return '';
+ }
+
+ /**
+ * Format a list of articles chunked by letter in a three-column
+ * list, ordered vertically.
+ *
+ * @param array $articles
+ * @param array $articles_start_char
+ * @return string
+ * @private
+ */
+ function columnList( $articles, $articles_start_char ) {
+ // divide list into three equal chunks
+ $chunk = (int) (count ( $articles ) / 3);
+
+ // get and display header
+ $r = '<table width="100%"><tr valign="top">';
+
+ $prev_start_char = 'none';
+
+ // loop through the chunks
+ for($startChunk = 0, $endChunk = $chunk, $chunkIndex = 0;
+ $chunkIndex < 3;
+ $chunkIndex++, $startChunk = $endChunk, $endChunk += $chunk + 1)
+ {
+ $r .= "<td>\n";
+ $atColumnTop = true;
+
+ // output all articles in category
+ for ($index = $startChunk ;
+ $index < $endChunk && $index < count($articles);
+ $index++ )
+ {
+ // check for change of starting letter or begining of chunk
+ if ( ($index == $startChunk) ||
+ ($articles_start_char[$index] != $articles_start_char[$index - 1]) )
+
+ {
+ if( $atColumnTop ) {
+ $atColumnTop = false;
+ } else {
+ $r .= "</ul>\n";
+ }
+ $cont_msg = "";
+ if ( $articles_start_char[$index] == $prev_start_char )
+ $cont_msg = wfMsgHtml('listingcontinuesabbrev');
+ $r .= "<h3>" . htmlspecialchars( $articles_start_char[$index] ) . "$cont_msg</h3>\n<ul>";
+ $prev_start_char = $articles_start_char[$index];
+ }
+
+ $r .= "<li>{$articles[$index]}</li>";
+ }
+ if( !$atColumnTop ) {
+ $r .= "</ul>\n";
+ }
+ $r .= "</td>\n";
+
+
+ }
+ $r .= '</tr></table>';
+ return $r;
+ }
+
+ /**
+ * Format a list of articles chunked by letter in a bullet list.
+ * @param array $articles
+ * @param array $articles_start_char
+ * @return string
+ * @private
+ */
+ function shortList( $articles, $articles_start_char ) {
+ $r = '<h3>' . htmlspecialchars( $articles_start_char[0] ) . "</h3>\n";
+ $r .= '<ul><li>'.$articles[0].'</li>';
+ for ($index = 1; $index < count($articles); $index++ )
+ {
+ if ($articles_start_char[$index] != $articles_start_char[$index - 1])
+ {
+ $r .= "</ul><h3>" . htmlspecialchars( $articles_start_char[$index] ) . "</h3>\n<ul>";
+ }
+
+ $r .= "<li>{$articles[$index]}</li>";
+ }
+ $r .= '</ul>';
+ return $r;
+ }
+
+ /**
+ * @param Title $title
+ * @param string $first
+ * @param string $last
+ * @param int $limit
+ * @param array $query - additional query options to pass
+ * @return string
+ * @private
+ */
+ function pagingLinks( $title, $first, $last, $limit, $query = array() ) {
+ global $wgUser, $wgLang;
+ $sk =& $this->getSkin();
+ $limitText = $wgLang->formatNum( $limit );
+
+ $prevLink = htmlspecialchars( wfMsg( 'prevn', $limitText ) );
+ if( $first != '' ) {
+ $prevLink = $sk->makeLinkObj( $title, $prevLink,
+ wfArrayToCGI( $query + array( 'until' => $first ) ) );
+ }
+ $nextLink = htmlspecialchars( wfMsg( 'nextn', $limitText ) );
+ if( $last != '' ) {
+ $nextLink = $sk->makeLinkObj( $title, $nextLink,
+ wfArrayToCGI( $query + array( 'from' => $last ) ) );
+ }
+
+ return "($prevLink) ($nextLink)";
+ }
+}
+
+
+?>
diff --git a/includes/Categoryfinder.php b/includes/Categoryfinder.php
new file mode 100644
index 000000000000..a8cdf3ce4df7
--- /dev/null
+++ b/includes/Categoryfinder.php
@@ -0,0 +1,191 @@
+<?php
+/*
+The "Categoryfinder" class takes a list of articles, creates an internal representation of all their parent
+categories (as well as parents of parents etc.). From this representation, it determines which of these articles
+are in one or all of a given subset of categories.
+
+Example use :
+
+ # Determines wether the article with the page_id 12345 is in both
+ # "Category 1" and "Category 2" or their subcategories, respectively
+
+ $cf = new Categoryfinder ;
+ $cf->seed (
+ array ( 12345 ) ,
+ array ( "Category 1","Category 2" ) ,
+ "AND"
+ ) ;
+ $a = $cf->run() ;
+ print implode ( "," , $a ) ;
+
+*/
+
+
+class Categoryfinder {
+
+ var $articles = array () ; # The original article IDs passed to the seed function
+ var $deadend = array () ; # Array of DBKEY category names for categories that don't have a page
+ var $parents = array () ; # Array of [ID => array()]
+ var $next = array () ; # Array of article/category IDs
+ var $targets = array () ; # Array of DBKEY category names
+ var $name2id = array () ;
+ var $mode ; # "AND" or "OR"
+ var $dbr ; # Read-DB slave
+
+ /**
+ * Constructor (currently empty).
+ */
+ function Categoryfinder () {
+ }
+
+ /**
+ * Initializes the instance. Do this prior to calling run().
+ * @param $article_ids Array of article IDs
+ * @param $categories FIXME
+ * @param $mode String: FIXME, default 'AND'.
+ */
+ function seed ( $article_ids , $categories , $mode = "AND" ) {
+ $this->articles = $article_ids ;
+ $this->next = $article_ids ;
+ $this->mode = $mode ;
+
+ # Set the list of target categories; convert them to DBKEY form first
+ $this->targets = array () ;
+ foreach ( $categories AS $c ) {
+ $ct = Title::newFromText ( $c , NS_CATEGORY ) ;
+ $c = $ct->getDBkey () ;
+ $this->targets[$c] = $c ;
+ }
+ }
+
+ /**
+ * Iterates through the parent tree starting with the seed values,
+ * then checks the articles if they match the conditions
+ @return array of page_ids (those given to seed() that match the conditions)
+ */
+ function run () {
+ $this->dbr =& wfGetDB( DB_SLAVE );
+ while ( count ( $this->next ) > 0 ) {
+ $this->scan_next_layer () ;
+ }
+
+ # Now check if this applies to the individual articles
+ $ret = array () ;
+ foreach ( $this->articles AS $article ) {
+ $conds = $this->targets ;
+ if ( $this->check ( $article , $conds ) ) {
+ # Matches the conditions
+ $ret[] = $article ;
+ }
+ }
+ return $ret ;
+ }
+
+ /**
+ * This functions recurses through the parent representation, trying to match the conditions
+ @param $id The article/category to check
+ @param $conds The array of categories to match
+ @return bool Does this match the conditions?
+ */
+ function check ( $id , &$conds ) {
+ # Shortcut (runtime paranoia): No contitions=all matched
+ if ( count ( $conds ) == 0 ) return true ;
+
+ if ( !isset ( $this->parents[$id] ) ) return false ;
+
+ # iterate through the parents
+ foreach ( $this->parents[$id] AS $p ) {
+ $pname = $p->cl_to ;
+
+ # Is this a condition?
+ if ( isset ( $conds[$pname] ) ) {
+ # This key is in the category list!
+ if ( $this->mode == "OR" ) {
+ # One found, that's enough!
+ $conds = array () ;
+ return true ;
+ } else {
+ # Assuming "AND" as default
+ unset ( $conds[$pname] ) ;
+ if ( count ( $conds ) == 0 ) {
+ # All conditions met, done
+ return true ;
+ }
+ }
+ }
+
+ # Not done yet, try sub-parents
+ if ( !isset ( $this->name2id[$pname] ) ) {
+ # No sub-parent
+ continue ;
+ }
+ $done = $this->check ( $this->name2id[$pname] , $conds ) ;
+ if ( $done OR count ( $conds ) == 0 ) {
+ # Subparents have done it!
+ return true ;
+ }
+ }
+ return false ;
+ }
+
+ /**
+ * Scans a "parent layer" of the articles/categories in $this->next
+ */
+ function scan_next_layer () {
+ $fname = "Categoryfinder::scan_next_layer" ;
+
+ # Find all parents of the article currently in $this->next
+ $layer = array () ;
+ $res = $this->dbr->select(
+ /* FROM */ 'categorylinks',
+ /* SELECT */ '*',
+ /* WHERE */ array( 'cl_from' => $this->next ),
+ $fname."-1"
+ );
+ while ( $o = $this->dbr->fetchObject( $res ) ) {
+ $k = $o->cl_to ;
+
+ # Update parent tree
+ if ( !isset ( $this->parents[$o->cl_from] ) ) {
+ $this->parents[$o->cl_from] = array () ;
+ }
+ $this->parents[$o->cl_from][$k] = $o ;
+
+ # Ignore those we already have
+ if ( in_array ( $k , $this->deadend ) ) continue ;
+ if ( isset ( $this->name2id[$k] ) ) continue ;
+
+ # Hey, new category!
+ $layer[$k] = $k ;
+ }
+ $this->dbr->freeResult( $res ) ;
+
+ $this->next = array() ;
+
+ # Find the IDs of all category pages in $layer, if they exist
+ if ( count ( $layer ) > 0 ) {
+ $res = $this->dbr->select(
+ /* FROM */ 'page',
+ /* SELECT */ 'page_id,page_title',
+ /* WHERE */ array( 'page_namespace' => NS_CATEGORY , 'page_title' => $layer ),
+ $fname."-2"
+ );
+ while ( $o = $this->dbr->fetchObject( $res ) ) {
+ $id = $o->page_id ;
+ $name = $o->page_title ;
+ $this->name2id[$name] = $id ;
+ $this->next[] = $id ;
+ unset ( $layer[$name] ) ;
+ }
+ $this->dbr->freeResult( $res ) ;
+ }
+
+ # Mark dead ends
+ foreach ( $layer AS $v ) {
+ $this->deadend[$v] = $v ;
+ }
+ }
+
+} # END OF CLASS "Categoryfinder"
+
+?>
diff --git a/includes/ChangesList.php b/includes/ChangesList.php
new file mode 100644
index 000000000000..a2c1a265e18f
--- /dev/null
+++ b/includes/ChangesList.php
@@ -0,0 +1,687 @@
+<?php
+/**
+ * @package MediaWiki
+ * Contain class to show various lists of change:
+ * - what's link here
+ * - related changes
+ * - recent changes
+ */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class RCCacheEntry extends RecentChange
+{
+ var $secureName, $link;
+ var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
+ var $userlink, $timestamp, $watched;
+
+ function newFromParent( $rc )
+ {
+ $rc2 = new RCCacheEntry;
+ $rc2->mAttribs = $rc->mAttribs;
+ $rc2->mExtra = $rc->mExtra;
+ return $rc2;
+ }
+} ;
+
+/**
+ * @package MediaWiki
+ */
+class ChangesList {
+ # Called by history lists and recent changes
+ #
+
+ /** @todo document */
+ function ChangesList( &$skin ) {
+ $this->skin =& $skin;
+ $this->preCacheMessages();
+ }
+
+ /**
+ * Fetch an appropriate changes list class for the specified user
+ * Some users might want to use an enhanced list format, for instance
+ *
+ * @param $user User to fetch the list class for
+ * @return ChangesList derivative
+ */
+ public static function newFromUser( &$user ) {
+ $sk =& $user->getSkin();
+ $list = NULL;
+ if( wfRunHooks( 'FetchChangesList', array( &$user, &$sk, &$list ) ) ) {
+ return $user->getOption( 'usenewrc' ) ? new EnhancedChangesList( $sk ) : new OldChangesList( $sk );
+ } else {
+ return $list;
+ }
+ }
+
+ /**
+ * As we use the same small set of messages in various methods and that
+ * they are called often, we call them once and save them in $this->message
+ */
+ function preCacheMessages() {
+ // Precache various messages
+ if( !isset( $this->message ) ) {
+ foreach( explode(' ', 'cur diff hist minoreditletter newpageletter last '.
+ 'blocklink changes history boteditletter' ) as $msg ) {
+ $this->message[$msg] = wfMsgExt( $msg, array( 'escape') );
+ }
+ }
+ }
+
+
+ /**
+ * Returns the appropriate flags for new page, minor change and patrolling
+ */
+ function recentChangesFlags( $new, $minor, $patrolled, $nothing = '&nbsp;', $bot = false ) {
+ $f = $new ? '<span class="newpage">' . $this->message['newpageletter'] . '</span>'
+ : $nothing;
+ $f .= $minor ? '<span class="minor">' . $this->message['minoreditletter'] . '</span>'
+ : $nothing;
+ $f .= $bot ? '<span class="bot">' . $this->message['boteditletter'] . '</span>' : $nothing;
+ $f .= $patrolled ? '<span class="unpatrolled">!</span>' : $nothing;
+ return $f;
+ }
+
+ /**
+ * Returns text for the start of the tabular part of RC
+ */
+ function beginRecentChangesList() {
+ $this->rc_cache = array();
+ $this->rcMoveIndex = 0;
+ $this->rcCacheIndex = 0;
+ $this->lastdate = '';
+ $this->rclistOpen = false;
+ return '';
+ }
+
+ /**
+ * Returns text for the end of RC
+ */
+ function endRecentChangesList() {
+ if( $this->rclistOpen ) {
+ return "</ul>\n";
+ } else {
+ return '';
+ }
+ }
+
+
+ function insertMove( &$s, $rc ) {
+ # Diff
+ $s .= '(' . $this->message['diff'] . ') (';
+ # Hist
+ $s .= $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), $this->message['hist'], 'action=history' ) .
+ ') . . ';
+
+ # "[[x]] moved to [[y]]"
+ $msg = ( $rc->mAttribs['rc_type'] == RC_MOVE ) ? '1movedto2' : '1movedto2_redir';
+ $s .= wfMsg( $msg, $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
+ $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
+ }
+
+ function insertDateHeader(&$s, $rc_timestamp) {
+ global $wgLang;
+
+ # Make date header if necessary
+ $date = $wgLang->date( $rc_timestamp, true, true );
+ $s = '';
+ if( $date != $this->lastdate ) {
+ if( '' != $this->lastdate ) {
+ $s .= "</ul>\n";
+ }
+ $s .= '<h4>'.$date."</h4>\n<ul class=\"special\">";
+ $this->lastdate = $date;
+ $this->rclistOpen = true;
+ }
+ }
+
+ function insertLog(&$s, $title, $logtype) {
+ $logname = LogPage::logName( $logtype );
+ $s .= '(' . $this->skin->makeKnownLinkObj($title, $logname ) . ')';
+ }
+
+
+ function insertDiffHist(&$s, &$rc, $unpatrolled) {
+ # Diff link
+ if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) {
+ $diffLink = $this->message['diff'];
+ } else {
+ $rcidparam = $unpatrolled
+ ? array( 'rcid' => $rc->mAttribs['rc_id'] )
+ : array();
+ $diffLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['diff'],
+ wfArrayToCGI( array(
+ 'curid' => $rc->mAttribs['rc_cur_id'],
+ 'diff' => $rc->mAttribs['rc_this_oldid'],
+ 'oldid' => $rc->mAttribs['rc_last_oldid'] ),
+ $rcidparam ),
+ '', '', ' tabindex="'.$rc->counter.'"');
+ }
+ $s .= '('.$diffLink.') (';
+
+ # History link
+ $s .= $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['hist'],
+ wfArrayToCGI( array(
+ 'curid' => $rc->mAttribs['rc_cur_id'],
+ 'action' => 'history' ) ) );
+ $s .= ') . . ';
+ }
+
+ function insertArticleLink(&$s, &$rc, $unpatrolled, $watched) {
+ # Article link
+ # If it's a new article, there is no diff link, but if it hasn't been
+ # patrolled yet, we need to give users a way to do so
+ $params = ( $unpatrolled && $rc->mAttribs['rc_type'] == RC_NEW )
+ ? 'rcid='.$rc->mAttribs['rc_id']
+ : '';
+ $articlelink = ' '. $this->skin->makeKnownLinkObj( $rc->getTitle(), '', $params );
+ if($watched) $articlelink = '<strong>'.$articlelink.'</strong>';
+ global $wgContLang;
+ $articlelink .= $wgContLang->getDirMark();
+
+ $s .= ' '.$articlelink;
+ }
+
+ function insertTimestamp(&$s, $rc) {
+ global $wgLang;
+ # Timestamp
+ $s .= '; ' . $wgLang->time( $rc->mAttribs['rc_timestamp'], true, true ) . ' . . ';
+ }
+
+ /** Insert links to user page, user talk page and eventually a blocking link */
+ function insertUserRelatedLinks(&$s, &$rc) {
+ $s .= $this->skin->userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
+ $s .= $this->skin->userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
+ }
+
+ /** insert a formatted comment */
+ function insertComment(&$s, &$rc) {
+ # Add comment
+ if( $rc->mAttribs['rc_type'] != RC_MOVE && $rc->mAttribs['rc_type'] != RC_MOVE_OVER_REDIRECT ) {
+ $s .= $this->skin->commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() );
+ }
+ }
+
+ /**
+ * Check whether to enable recent changes patrol features
+ * @return bool
+ */
+ function usePatrol() {
+ global $wgUseRCPatrol, $wgUser;
+ return( $wgUseRCPatrol && $wgUser->isAllowed( 'patrol' ) );
+ }
+}
+
+
+/**
+ * Generate a list of changes using the good old system (no javascript)
+ */
+class OldChangesList extends ChangesList {
+ /**
+ * Format a line using the old system (aka without any javascript).
+ */
+ function recentChangesLine( &$rc, $watched = false ) {
+ global $wgContLang, $wgRCShowChangedSize;
+
+ $fname = 'ChangesList::recentChangesLineOld';
+ wfProfileIn( $fname );
+
+ # Extract DB fields into local scope
+ extract( $rc->mAttribs );
+
+ # Should patrol-related stuff be shown?
+ $unpatrolled = $this->usePatrol() && $rc_patrolled == 0;
+
+ $this->insertDateHeader($s,$rc_timestamp);
+
+ $s .= '<li>';
+
+ // moved pages
+ if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $this->insertMove( $s, $rc );
+ // log entries
+ } elseif ( $rc_namespace == NS_SPECIAL ) {
+ list( $specialName, $specialSubpage ) = SpecialPage::resolveAliasWithSubpage( $rc_title );
+ if ( $specialName == 'Log' ) {
+ $this->insertLog( $s, $rc->getTitle(), $specialSubpage );
+ } else {
+ wfDebug( "Unexpected special page in recentchanges\n" );
+ }
+ // all other stuff
+ } else {
+ wfProfileIn($fname.'-page');
+
+ $this->insertDiffHist($s, $rc, $unpatrolled);
+
+ # M, N, b and ! (minor, new, bot and unpatrolled)
+ $s .= ' ' . $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $unpatrolled, '', $rc_bot );
+ $this->insertArticleLink($s, $rc, $unpatrolled, $watched);
+
+ wfProfileOut($fname.'-page');
+ }
+
+ wfProfileIn( $fname.'-rest' );
+
+ $this->insertTimestamp($s,$rc);
+
+ if( $wgRCShowChangedSize ) {
+ $s .= ( $rc->getCharacterDifference() == '' ? '' : $rc->getCharacterDifference() . ' . . ' );
+ }
+
+ $this->insertUserRelatedLinks($s,$rc);
+ $this->insertComment($s, $rc);
+
+ if($rc->numberofWatchingusers > 0) {
+ $s .= ' ' . wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($rc->numberofWatchingusers));
+ }
+
+ $s .= "</li>\n";
+
+ wfProfileOut( $fname.'-rest' );
+
+ wfProfileOut( $fname );
+ return $s;
+ }
+}
+
+
+/**
+ * Generate a list of changes using an Enhanced system (use javascript).
+ */
+class EnhancedChangesList extends ChangesList {
+ /**
+ * Format a line for enhanced recentchange (aka with javascript and block of lines).
+ */
+ function recentChangesLine( &$baseRC, $watched = false ) {
+ global $wgLang, $wgContLang;
+
+ # Create a specialised object
+ $rc = RCCacheEntry::newFromParent( $baseRC );
+
+ # Extract fields from DB into the function scope (rc_xxxx variables)
+ extract( $rc->mAttribs );
+ $curIdEq = 'curid=' . $rc_cur_id;
+
+ # If it's a new day, add the headline and flush the cache
+ $date = $wgLang->date( $rc_timestamp, true);
+ $ret = '';
+ if( $date != $this->lastdate ) {
+ # Process current cache
+ $ret = $this->recentChangesBlock();
+ $this->rc_cache = array();
+ $ret .= "<h4>{$date}</h4>\n";
+ $this->lastdate = $date;
+ }
+
+ # Should patrol-related stuff be shown?
+ if( $this->usePatrol() ) {
+ $rc->unpatrolled = !$rc_patrolled;
+ } else {
+ $rc->unpatrolled = false;
+ }
+
+ # Make article link
+ if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $msg = ( $rc_type == RC_MOVE ) ? "1movedto2" : "1movedto2_redir";
+ $clink = wfMsg( $msg, $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
+ $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
+ } elseif( $rc_namespace == NS_SPECIAL ) {
+ list( $specialName, $logtype ) = SpecialPage::resolveAliasWithSubpage( $rc_title );
+ if ( $specialName == 'Log' ) {
+ # Log updates, etc
+ $logname = LogPage::logName( $logtype );
+ $clink = '(' . $this->skin->makeKnownLinkObj( $rc->getTitle(), $logname ) . ')';
+ } else {
+ wfDebug( "Unexpected special page in recentchanges\n" );
+ $clink = '';
+ }
+ } elseif( $rc->unpatrolled && $rc_type == RC_NEW ) {
+ # Unpatrolled new page, give rc_id in query
+ $clink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
+ } else {
+ $clink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '' );
+ }
+
+ $time = $wgContLang->time( $rc_timestamp, true, true );
+ $rc->watched = $watched;
+ $rc->link = $clink;
+ $rc->timestamp = $time;
+ $rc->numberofWatchingusers = $baseRC->numberofWatchingusers;
+
+ # Make "cur" and "diff" links
+ if( $rc->unpatrolled ) {
+ $rcIdQuery = "&rcid={$rc_id}";
+ } else {
+ $rcIdQuery = '';
+ }
+ $querycur = $curIdEq."&diff=0&oldid=$rc_this_oldid";
+ $querydiff = $curIdEq."&diff=$rc_this_oldid&oldid=$rc_last_oldid$rcIdQuery";
+ $aprops = ' tabindex="'.$baseRC->counter.'"';
+ $curLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['cur'], $querycur, '' ,'', $aprops );
+ if( $rc_type == RC_NEW || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ if( $rc_type != RC_NEW ) {
+ $curLink = $this->message['cur'];
+ }
+ $diffLink = $this->message['diff'];
+ } else {
+ $diffLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['diff'], $querydiff, '' ,'', $aprops );
+ }
+
+ # Make "last" link
+ if( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $lastLink = $this->message['last'];
+ } else {
+ $lastLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['last'],
+ $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid . $rcIdQuery );
+ }
+
+ $rc->userlink = $this->skin->userLink( $rc_user, $rc_user_text );
+
+ $rc->lastlink = $lastLink;
+ $rc->curlink = $curLink;
+ $rc->difflink = $diffLink;
+
+ $rc->usertalklink = $this->skin->userToolLinks( $rc_user, $rc_user_text );
+
+ # Put accumulated information into the cache, for later display
+ # Page moves go on their own line
+ $title = $rc->getTitle();
+ $secureName = $title->getPrefixedDBkey();
+ if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ # Use an @ character to prevent collision with page names
+ $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
+ } else {
+ if( !isset ( $this->rc_cache[$secureName] ) ) {
+ $this->rc_cache[$secureName] = array();
+ }
+ array_push( $this->rc_cache[$secureName], $rc );
+ }
+ return $ret;
+ }
+
+ /**
+ * Enhanced RC group
+ */
+ function recentChangesBlockGroup( $block ) {
+ global $wgContLang, $wgRCShowChangedSize;
+ $r = '';
+
+ # Collate list of users
+ $isnew = false;
+ $unpatrolled = false;
+ $userlinks = array();
+ foreach( $block as $rcObj ) {
+ $oldid = $rcObj->mAttribs['rc_last_oldid'];
+ if( $rcObj->mAttribs['rc_new'] ) {
+ $isnew = true;
+ }
+ $u = $rcObj->userlink;
+ if( !isset( $userlinks[$u] ) ) {
+ $userlinks[$u] = 0;
+ }
+ if( $rcObj->unpatrolled ) {
+ $unpatrolled = true;
+ }
+ $bot = $rcObj->mAttribs['rc_bot'];
+ $userlinks[$u]++;
+ }
+
+ # Sort the list and convert to text
+ krsort( $userlinks );
+ asort( $userlinks );
+ $users = array();
+ foreach( $userlinks as $userlink => $count) {
+ $text = $userlink;
+ $text .= $wgContLang->getDirMark();
+ if( $count > 1 ) {
+ $text .= ' ('.$count.'&times;)';
+ }
+ array_push( $users, $text );
+ }
+
+ $users = ' <span class="changedby">['.implode('; ',$users).']</span>';
+
+ # Arrow
+ $rci = 'RCI'.$this->rcCacheIndex;
+ $rcl = 'RCL'.$this->rcCacheIndex;
+ $rcm = 'RCM'.$this->rcCacheIndex;
+ $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')";
+ $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'">' . $this->sideArrow() . '</a></span>';
+ $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'">' . $this->downArrow() . '</a></span>';
+ $r .= $tl;
+
+ # Main line
+ $r .= '<tt>';
+ $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, '&nbsp;', $bot );
+
+ # Timestamp
+ $r .= ' '.$block[0]->timestamp.' </tt>';
+
+ # Article link
+ $r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched );
+ $r .= $wgContLang->getDirMark();
+
+ $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id'];
+ $currentRevision = $block[0]->mAttribs['rc_this_oldid'];
+ if( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
+ # Changes
+ $r .= ' ('.count($block).' ';
+
+ if( $isnew ) {
+ $r .= $this->message['changes'];
+ } else {
+ $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(),
+ $this->message['changes'], $curIdEq."&diff=$currentRevision&oldid=$oldid" );
+ }
+
+ # Character difference
+ $chardiff = $rcObj->getCharacterDifference( $block[ count( $block ) - 1 ]->mAttribs['rc_old_len'],
+ $block[0]->mAttribs['rc_new_len'] );
+ if( $chardiff == '' ) {
+ $r .= '; ';
+ } else {
+ $r .= '; ' . $chardiff . ' ';
+ }
+
+
+ # History
+ $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(),
+ $this->message['history'], $curIdEq.'&action=history' );
+ $r .= ')';
+ }
+
+ $r .= $users;
+
+ if($block[0]->numberofWatchingusers > 0) {
+ global $wgContLang;
+ $r .= wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($block[0]->numberofWatchingusers));
+ }
+ $r .= "<br />\n";
+
+ # Sub-entries
+ $r .= '<div id="'.$rci.'" style="display:none">';
+ foreach( $block as $rcObj ) {
+ # Get rc_xxxx variables
+ extract( $rcObj->mAttribs );
+
+ $r .= $this->spacerArrow();
+ $r .= '<tt>&nbsp; &nbsp; &nbsp; &nbsp;';
+ $r .= $this->recentChangesFlags( $rc_new, $rc_minor, $rcObj->unpatrolled, '&nbsp;', $rc_bot );
+ $r .= '&nbsp;</tt>';
+
+ $o = '';
+ if( $rc_this_oldid != 0 ) {
+ $o = 'oldid='.$rc_this_oldid;
+ }
+ if( $rc_type == RC_LOG ) {
+ $link = $rcObj->timestamp;
+ } else {
+ $link = $this->skin->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp, $curIdEq.'&'.$o );
+ }
+ $link = '<tt>'.$link.'</tt>';
+
+ $r .= $link;
+ $r .= ' (';
+ $r .= $rcObj->curlink;
+ $r .= '; ';
+ $r .= $rcObj->lastlink;
+ $r .= ') . . ';
+
+ # Character diff
+ if( $wgRCShowChangedSize ) {
+ $r .= ( $rcObj->getCharacterDifference() == '' ? '' : $rcObj->getCharacterDifference() . ' . . ' ) ;
+ }
+
+ $r .= $rcObj->userlink;
+ $r .= $rcObj->usertalklink;
+ $r .= $this->skin->commentBlock( $rc_comment, $rcObj->getTitle() );
+ $r .= "<br />\n";
+ }
+ $r .= "</div>\n";
+
+ $this->rcCacheIndex++;
+ return $r;
+ }
+
+ function maybeWatchedLink( $link, $watched=false ) {
+ if( $watched ) {
+ // FIXME: css style might be more appropriate
+ return '<strong>' . $link . '</strong>';
+ } else {
+ return $link;
+ }
+ }
+
+ /**
+ * Generate HTML for an arrow or placeholder graphic
+ * @param string $dir one of '', 'd', 'l', 'r'
+ * @param string $alt text
+ * @return string HTML <img> tag
+ * @access private
+ */
+ function arrow( $dir, $alt='' ) {
+ global $wgStylePath;
+ $encUrl = htmlspecialchars( $wgStylePath . '/common/images/Arr_' . $dir . '.png' );
+ $encAlt = htmlspecialchars( $alt );
+ return "<img src=\"$encUrl\" width=\"12\" height=\"12\" alt=\"$encAlt\" />";
+ }
+
+ /**
+ * Generate HTML for a right- or left-facing arrow,
+ * depending on language direction.
+ * @return string HTML <img> tag
+ * @access private
+ */
+ function sideArrow() {
+ global $wgContLang;
+ $dir = $wgContLang->isRTL() ? 'l' : 'r';
+ return $this->arrow( $dir, '+' );
+ }
+
+ /**
+ * Generate HTML for a down-facing arrow
+ * depending on language direction.
+ * @return string HTML <img> tag
+ * @access private
+ */
+ function downArrow() {
+ return $this->arrow( 'd', '-' );
+ }
+
+ /**
+ * Generate HTML for a spacer image
+ * @return string HTML <img> tag
+ * @access private
+ */
+ function spacerArrow() {
+ return $this->arrow( '', ' ' );
+ }
+
+ /**
+ * Enhanced RC ungrouped line.
+ * @return string a HTML formated line (generated using $r)
+ */
+ function recentChangesBlockLine( $rcObj ) {
+ global $wgContLang, $wgRCShowChangedSize;
+
+ # Get rc_xxxx variables
+ extract( $rcObj->mAttribs );
+ $curIdEq = 'curid='.$rc_cur_id;
+
+ $r = '';
+
+ # Spacer image
+ $r .= $this->spacerArrow();
+
+ # Flag and Timestamp
+ $r .= '<tt>';
+
+ if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $r .= '&nbsp;&nbsp;&nbsp;';
+ } else {
+ $r .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, '&nbsp;', $rc_bot );
+ }
+ $r .= ' '.$rcObj->timestamp.' </tt>';
+
+ # Article link
+ $r .= $this->maybeWatchedLink( $rcObj->link, $rcObj->watched );
+
+ # Diff
+ $r .= ' ('. $rcObj->difflink .'; ';
+
+ # Hist
+ $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' ) . ') . . ';
+
+ # Character diff
+ if( $wgRCShowChangedSize ) {
+ $r .= ( $rcObj->getCharacterDifference() == '' ? '' : '&nbsp;' . $rcObj->getCharacterDifference() . ' . . ' ) ;
+ }
+
+ # User/talk
+ $r .= $rcObj->userlink . $rcObj->usertalklink;
+
+ # Comment
+ if( $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
+ $r .= $this->skin->commentBlock( $rc_comment, $rcObj->getTitle() );
+ }
+
+ if( $rcObj->numberofWatchingusers > 0 ) {
+ $r .= wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($rcObj->numberofWatchingusers));
+ }
+
+ $r .= "<br />\n";
+ return $r;
+ }
+
+ /**
+ * If enhanced RC is in use, this function takes the previously cached
+ * RC lines, arranges them, and outputs the HTML
+ */
+ function recentChangesBlock() {
+ if( count ( $this->rc_cache ) == 0 ) {
+ return '';
+ }
+ $blockOut = '';
+ foreach( $this->rc_cache as $block ) {
+ if( count( $block ) < 2 ) {
+ $blockOut .= $this->recentChangesBlockLine( array_shift( $block ) );
+ } else {
+ $blockOut .= $this->recentChangesBlockGroup( $block );
+ }
+ }
+
+ return '<div>'.$blockOut.'</div>';
+ }
+
+ /**
+ * Returns text for the end of RC
+ * If enhanced RC is in use, returns pretty much all the text
+ */
+ function endRecentChangesList() {
+ return $this->recentChangesBlock() . parent::endRecentChangesList();
+ }
+
+}
+?>
diff --git a/includes/CoreParserFunctions.php b/includes/CoreParserFunctions.php
new file mode 100644
index 000000000000..402a3ba9f2f4
--- /dev/null
+++ b/includes/CoreParserFunctions.php
@@ -0,0 +1,193 @@
+<?php
+
+/**
+ * Various core parser functions, registered in Parser::firstCallInit()
+ */
+
+class CoreParserFunctions {
+ static function intFunction( $parser, $part1 = '' /*, ... */ ) {
+ if ( strval( $part1 ) !== '' ) {
+ $args = array_slice( func_get_args(), 2 );
+ return wfMsgReal( $part1, $args, true );
+ } else {
+ return array( 'found' => false );
+ }
+ }
+
+ static function ns( $parser, $part1 = '' ) {
+ global $wgContLang;
+ $found = false;
+ if ( intval( $part1 ) || $part1 == "0" ) {
+ $text = $wgContLang->getNsText( intval( $part1 ) );
+ $found = true;
+ } else {
+ $param = str_replace( ' ', '_', strtolower( $part1 ) );
+ $index = Namespace::getCanonicalIndex( strtolower( $param ) );
+ if ( !is_null( $index ) ) {
+ $text = $wgContLang->getNsText( $index );
+ $found = true;
+ }
+ }
+ if ( $found ) {
+ return $text;
+ } else {
+ return array( 'found' => false );
+ }
+ }
+
+ static function urlencode( $parser, $s = '' ) {
+ return urlencode( $s );
+ }
+
+ static function lcfirst( $parser, $s = '' ) {
+ global $wgContLang;
+ return $wgContLang->lcfirst( $s );
+ }
+
+ static function ucfirst( $parser, $s = '' ) {
+ global $wgContLang;
+ return $wgContLang->ucfirst( $s );
+ }
+
+ static function lc( $parser, $s = '' ) {
+ global $wgContLang;
+ return $wgContLang->lc( $s );
+ }
+
+ static function uc( $parser, $s = '' ) {
+ global $wgContLang;
+ return $wgContLang->uc( $s );
+ }
+
+ static function localurl( $parser, $s = '', $arg = null ) { return self::urlFunction( 'getLocalURL', $s, $arg ); }
+ static function localurle( $parser, $s = '', $arg = null ) { return self::urlFunction( 'escapeLocalURL', $s, $arg ); }
+ static function fullurl( $parser, $s = '', $arg = null ) { return self::urlFunction( 'getFullURL', $s, $arg ); }
+ static function fullurle( $parser, $s = '', $arg = null ) { return self::urlFunction( 'escapeFullURL', $s, $arg ); }
+
+ static function urlFunction( $func, $s = '', $arg = null ) {
+ $title = Title::newFromText( $s );
+ # Due to order of execution of a lot of bits, the values might be encoded
+ # before arriving here; if that's true, then the title can't be created
+ # and the variable will fail. If we can't get a decent title from the first
+ # attempt, url-decode and try for a second.
+ if( is_null( $title ) )
+ $title = Title::newFromUrl( urldecode( $s ) );
+ if ( !is_null( $title ) ) {
+ if ( !is_null( $arg ) ) {
+ $text = $title->$func( $arg );
+ } else {
+ $text = $title->$func();
+ }
+ return $text;
+ } else {
+ return array( 'found' => false );
+ }
+ }
+
+ static function formatNum( $parser, $num = '' ) {
+ return $parser->getFunctionLang()->formatNum( $num );
+ }
+
+ static function grammar( $parser, $case = '', $word = '' ) {
+ return $parser->getFunctionLang()->convertGrammar( $word, $case );
+ }
+
+ static function plural( $parser, $text = '', $arg0 = null, $arg1 = null, $arg2 = null, $arg3 = null, $arg4 = null ) {
+ $text = $parser->getFunctionLang()->parseFormattedNumber( $text );
+ return $parser->getFunctionLang()->convertPlural( $text, $arg0, $arg1, $arg2, $arg3, $arg4 );
+ }
+
+ static function displaytitle( $parser, $param = '' ) {
+ $parserOptions = new ParserOptions;
+ $local_parser = clone $parser;
+ $t2 = $local_parser->parse ( $param, $parser->mTitle, $parserOptions, false );
+ $parser->mOutput->mHTMLtitle = $t2->GetText();
+
+ # Add subtitle
+ $t = $parser->mTitle->getPrefixedText();
+ $parser->mOutput->mSubtitle .= wfMsg('displaytitle', $t);
+ return '';
+ }
+
+ static function isRaw( $param ) {
+ static $mwRaw;
+ if ( !$mwRaw ) {
+ $mwRaw =& MagicWord::get( 'rawsuffix' );
+ }
+ if ( is_null( $param ) ) {
+ return false;
+ } else {
+ return $mwRaw->match( $param );
+ }
+ }
+
+ static function statisticsFunction( $func, $raw = null ) {
+ if ( self::isRaw( $raw ) ) {
+ return call_user_func( array( 'SiteStats', $func ) );
+ } else {
+ global $wgContLang;
+ return $wgContLang->formatNum( call_user_func( array( 'SiteStats', $func ) ) );
+ }
+ }
+
+ static function numberofpages( $parser, $raw = null ) { return self::statisticsFunction( 'pages', $raw ); }
+ static function numberofusers( $parser, $raw = null ) { return self::statisticsFunction( 'users', $raw ); }
+ static function numberofarticles( $parser, $raw = null ) { return self::statisticsFunction( 'articles', $raw ); }
+ static function numberoffiles( $parser, $raw = null ) { return self::statisticsFunction( 'images', $raw ); }
+ static function numberofadmins( $parser, $raw = null ) { return self::statisticsFunction( 'admins', $raw ); }
+
+ static function pagesinnamespace( $parser, $namespace = 0, $raw = null ) {
+ $count = SiteStats::pagesInNs( intval( $namespace ) );
+ if ( self::isRaw( $raw ) ) {
+ global $wgContLang;
+ return $wgContLang->formatNum( $count );
+ } else {
+ return $count;
+ }
+ }
+
+ static function language( $parser, $arg = '' ) {
+ global $wgContLang;
+ $lang = $wgContLang->getLanguageName( strtolower( $arg ) );
+ return $lang != '' ? $lang : $arg;
+ }
+
+ static function pad( $string = '', $length = 0, $char = 0, $direction = STR_PAD_RIGHT ) {
+ $length = min( max( $length, 0 ), 500 );
+ $char = substr( $char, 0, 1 );
+ return ( $string && (int)$length > 0 && strlen( trim( (string)$char ) ) > 0 )
+ ? str_pad( $string, $length, (string)$char, $direction )
+ : $string;
+ }
+
+ static function padleft( $parser, $string = '', $length = 0, $char = 0 ) {
+ return self::pad( $string, $length, $char, STR_PAD_LEFT );
+ }
+
+ static function padright( $parser, $string = '', $length = 0, $char = 0 ) {
+ return self::pad( $string, $length, $char );
+ }
+
+ static function anchorencode( $parser, $text ) {
+ return strtr( urlencode( $text ) , array( '%' => '.' , '+' => '_' ) );
+ }
+
+ static function special( $parser, $text ) {
+ $title = SpecialPage::getTitleForAlias( $text );
+ if ( $title ) {
+ return $title->getPrefixedText();
+ } else {
+ return wfMsgForContent( 'nosuchspecialpage' );
+ }
+ }
+
+ public static function defaultsort( $parser, $text ) {
+ $text = trim( $text );
+ if( strlen( $text ) > 0 )
+ $parser->setDefaultSort( $text );
+ return '';
+ }
+
+}
+
+?>
diff --git a/includes/Credits.php b/includes/Credits.php
new file mode 100644
index 000000000000..62f0b2566a79
--- /dev/null
+++ b/includes/Credits.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Credits.php -- formats credits for articles
+ * Copyright 2004, Evan Prodromou <evan@wikitravel.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
+ *
+ * @author <evan@wikitravel.org>
+ * @package MediaWiki
+ */
+
+/**
+ * This is largely cadged from PageHistory::history
+ */
+function showCreditsPage($article) {
+ global $wgOut;
+
+ $fname = 'showCreditsPage';
+
+ wfProfileIn( $fname );
+
+ $wgOut->setPageTitle( $article->mTitle->getPrefixedText() );
+ $wgOut->setSubtitle( wfMsg( 'creditspage' ) );
+ $wgOut->setArticleFlag( false );
+ $wgOut->setArticleRelated( true );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ if( $article->mTitle->getArticleID() == 0 ) {
+ $s = wfMsg( 'nocredits' );
+ } else {
+ $s = getCredits($article, -1);
+ }
+
+ $wgOut->addHTML( $s );
+
+ wfProfileOut( $fname );
+}
+
+function getCredits($article, $cnt, $showIfMax=true) {
+ $fname = 'getCredits';
+ wfProfileIn( $fname );
+ $s = '';
+
+ if (isset($cnt) && $cnt != 0) {
+ $s = getAuthorCredits($article);
+ if ($cnt > 1 || $cnt < 0) {
+ $s .= ' ' . getContributorCredits($article, $cnt - 1, $showIfMax);
+ }
+ }
+
+ wfProfileOut( $fname );
+ return $s;
+}
+
+/**
+ *
+ */
+function getAuthorCredits($article) {
+ global $wgLang, $wgAllowRealName;
+
+ $last_author = $article->getUser();
+
+ if ($last_author == 0) {
+ $author_credit = wfMsg('anonymous');
+ } else {
+ if($wgAllowRealName) { $real_name = User::whoIsReal($last_author); }
+ $user_name = User::whoIs($last_author);
+
+ if (!empty($real_name)) {
+ $author_credit = creditLink($user_name, $real_name);
+ } else {
+ $author_credit = wfMsg('siteuser', creditLink($user_name));
+ }
+ }
+
+ $timestamp = $article->getTimestamp();
+ if ($timestamp) {
+ $d = $wgLang->date($article->getTimestamp(), true);
+ $t = $wgLang->time($article->getTimestamp(), true);
+ } else {
+ $d = '';
+ $t = '';
+ }
+ return wfMsg('lastmodifiedatby', $d, $t, $author_credit);
+}
+
+/**
+ *
+ */
+function getContributorCredits($article, $cnt, $showIfMax) {
+
+ global $wgLang, $wgAllowRealName;
+
+ $contributors = $article->getContributors();
+
+ $others_link = '';
+
+ # Hmm... too many to fit!
+
+ if ($cnt > 0 && count($contributors) > $cnt) {
+ $others_link = creditOthersLink($article);
+ if (!$showIfMax) {
+ return wfMsg('othercontribs', $others_link);
+ } else {
+ $contributors = array_slice($contributors, 0, $cnt);
+ }
+ }
+
+ $real_names = array();
+ $user_names = array();
+
+ $anon = '';
+
+ # Sift for real versus user names
+
+ foreach ($contributors as $user_parts) {
+ if ($user_parts[0] != 0) {
+ if ($wgAllowRealName && !empty($user_parts[2])) {
+ $real_names[] = creditLink($user_parts[1], $user_parts[2]);
+ } else {
+ $user_names[] = creditLink($user_parts[1]);
+ }
+ } else {
+ $anon = wfMsg('anonymous');
+ }
+ }
+
+ # Two strings: real names, and user names
+
+ $real = $wgLang->listToText($real_names);
+ $user = $wgLang->listToText($user_names);
+
+ # "ThisSite user(s) A, B and C"
+
+ if (!empty($user)) {
+ $user = wfMsg('siteusers', $user);
+ }
+
+ # This is the big list, all mooshed together. We sift for blank strings
+
+ $fulllist = array();
+
+ foreach (array($real, $user, $anon, $others_link) as $s) {
+ if (!empty($s)) {
+ array_push($fulllist, $s);
+ }
+ }
+
+ # Make the list into text...
+
+ $creds = $wgLang->listToText($fulllist);
+
+ # "Based on work by ..."
+
+ return (empty($creds)) ? '' : wfMsg('othercontribs', $creds);
+}
+
+/**
+ *
+ */
+function creditLink($user_name, $link_text = '') {
+ global $wgUser, $wgContLang;
+ $skin = $wgUser->getSkin();
+ return $skin->makeLink($wgContLang->getNsText(NS_USER) . ':' . $user_name,
+ htmlspecialchars( (empty($link_text)) ? $user_name : $link_text ));
+}
+
+/**
+ *
+ */
+function creditOthersLink($article) {
+ global $wgUser;
+ $skin = $wgUser->getSkin();
+ return $skin->makeKnownLink($article->mTitle->getPrefixedText(), wfMsg('others'), 'action=credits');
+}
+
+?>
diff --git a/includes/Database.php b/includes/Database.php
new file mode 100644
index 000000000000..eb1ee1359c53
--- /dev/null
+++ b/includes/Database.php
@@ -0,0 +1,2113 @@
+<?php
+/**
+ * This file deals with MySQL interface functions
+ * and query specifics/optimisations
+ * @package MediaWiki
+ */
+
+/** Number of times to re-try an operation in case of deadlock */
+define( 'DEADLOCK_TRIES', 4 );
+/** Minimum time to wait before retry, in microseconds */
+define( 'DEADLOCK_DELAY_MIN', 500000 );
+/** Maximum time to wait before retry */
+define( 'DEADLOCK_DELAY_MAX', 1500000 );
+
+/******************************************************************************
+ * Utility classes
+ *****************************************************************************/
+
+class DBObject {
+ public $mData;
+
+ function DBObject($data) {
+ $this->mData = $data;
+ }
+
+ function isLOB() {
+ return false;
+ }
+
+ function data() {
+ return $this->mData;
+ }
+};
+
+/******************************************************************************
+ * Error classes
+ *****************************************************************************/
+
+/**
+ * Database error base class
+ */
+class DBError extends MWException {
+ public $db;
+
+ /**
+ * Construct a database error
+ * @param Database $db The database object which threw the error
+ * @param string $error A simple error message to be used for debugging
+ */
+ function __construct( Database &$db, $error ) {
+ $this->db =& $db;
+ parent::__construct( $error );
+ }
+}
+
+class DBConnectionError extends DBError {
+ public $error;
+
+ function __construct( Database &$db, $error = 'unknown error' ) {
+ $msg = 'DB connection error';
+ if ( trim( $error ) != '' ) {
+ $msg .= ": $error";
+ }
+ $this->error = $error;
+ parent::__construct( $db, $msg );
+ }
+
+ function useOutputPage() {
+ // Not likely to work
+ return false;
+ }
+
+ function useMessageCache() {
+ // Not likely to work
+ return false;
+ }
+
+ function getText() {
+ return $this->getMessage() . "\n";
+ }
+
+ function getLogMessage() {
+ # Don't send to the exception log
+ return false;
+ }
+
+ function getPageTitle() {
+ global $wgSitename;
+ return "$wgSitename has a problem";
+ }
+
+ function getHTML() {
+ global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding;
+ global $wgSitename, $wgServer, $wgMessageCache;
+
+ # I give up, Brion is right. Getting the message cache to work when there is no DB is tricky.
+ # Hard coding strings instead.
+
+ $noconnect = "<p><strong>Sorry! This site is experiencing technical difficulties.</strong></p><p>Try waiting a few minutes and reloading.</p><p><small>(Can't contact the database server: $1)</small></p>";
+ $mainpage = 'Main Page';
+ $searchdisabled = <<<EOT
+<p style="margin: 1.5em 2em 1em">$wgSitename search is disabled for performance reasons. You can search via Google in the meantime.
+<span style="font-size: 89%; display: block; margin-left: .2em">Note that their indexes of $wgSitename content may be out of date.</span></p>',
+EOT;
+
+ $googlesearch = "
+<!-- SiteSearch Google -->
+<FORM method=GET action=\"http://www.google.com/search\">
+<TABLE bgcolor=\"#FFFFFF\"><tr><td>
+<A HREF=\"http://www.google.com/\">
+<IMG SRC=\"http://www.google.com/logos/Logo_40wht.gif\"
+border=\"0\" ALT=\"Google\"></A>
+</td>
+<td>
+<INPUT TYPE=text name=q size=31 maxlength=255 value=\"$1\">
+<INPUT type=submit name=btnG VALUE=\"Google Search\">
+<font size=-1>
+<input type=hidden name=domains value=\"$wgServer\"><br /><input type=radio name=sitesearch value=\"\"> WWW <input type=radio name=sitesearch value=\"$wgServer\" checked> $wgServer <br />
+<input type='hidden' name='ie' value='$2'>
+<input type='hidden' name='oe' value='$2'>
+</font>
+</td></tr></TABLE>
+</FORM>
+<!-- SiteSearch Google -->";
+ $cachederror = "The following is a cached copy of the requested page, and may not be up to date. ";
+
+ # No database access
+ if ( is_object( $wgMessageCache ) ) {
+ $wgMessageCache->disable();
+ }
+
+ if ( trim( $this->error ) == '' ) {
+ $this->error = $this->db->getProperty('mServer');
+ }
+
+ $text = str_replace( '$1', $this->error, $noconnect );
+ $text .= wfGetSiteNotice();
+
+ if($wgUseFileCache) {
+ if($wgTitle) {
+ $t =& $wgTitle;
+ } else {
+ if($title) {
+ $t = Title::newFromURL( $title );
+ } elseif (@/**/$_REQUEST['search']) {
+ $search = $_REQUEST['search'];
+ return $searchdisabled .
+ str_replace( array( '$1', '$2' ), array( htmlspecialchars( $search ),
+ $wgInputEncoding ), $googlesearch );
+ } else {
+ $t = Title::newFromText( $mainpage );
+ }
+ }
+
+ $cache = new HTMLFileCache( $t );
+ if( $cache->isFileCached() ) {
+ $msg = '<p style="color: red"><b>'.$msg."<br />\n" .
+ $cachederror . "</b></p>\n";
+
+ $tag = '<div id="article">';
+ $text = str_replace(
+ $tag,
+ $tag . $msg,
+ $cache->fetchPageText() );
+ }
+ }
+
+ return $text;
+ }
+}
+
+class DBQueryError extends DBError {
+ public $error, $errno, $sql, $fname;
+
+ function __construct( Database &$db, $error, $errno, $sql, $fname ) {
+ $message = "A database error has occurred\n" .
+ "Query: $sql\n" .
+ "Function: $fname\n" .
+ "Error: $errno $error\n";
+
+ parent::__construct( $db, $message );
+ $this->error = $error;
+ $this->errno = $errno;
+ $this->sql = $sql;
+ $this->fname = $fname;
+ }
+
+ function getText() {
+ if ( $this->useMessageCache() ) {
+ return wfMsg( 'dberrortextcl', htmlspecialchars( $this->getSQL() ),
+ htmlspecialchars( $this->fname ), $this->errno, htmlspecialchars( $this->error ) ) . "\n";
+ } else {
+ return $this->getMessage();
+ }
+ }
+
+ function getSQL() {
+ global $wgShowSQLErrors;
+ if( !$wgShowSQLErrors ) {
+ return $this->msg( 'sqlhidden', 'SQL hidden' );
+ } else {
+ return $this->sql;
+ }
+ }
+
+ function getLogMessage() {
+ # Don't send to the exception log
+ return false;
+ }
+
+ function getPageTitle() {
+ return $this->msg( 'databaseerror', 'Database error' );
+ }
+
+ function getHTML() {
+ if ( $this->useMessageCache() ) {
+ return wfMsgNoDB( 'dberrortext', htmlspecialchars( $this->getSQL() ),
+ htmlspecialchars( $this->fname ), $this->errno, htmlspecialchars( $this->error ) );
+ } else {
+ return nl2br( htmlspecialchars( $this->getMessage() ) );
+ }
+ }
+}
+
+class DBUnexpectedError extends DBError {}
+
+/******************************************************************************/
+
+/**
+ * Database abstraction object
+ * @package MediaWiki
+ */
+class Database {
+
+#------------------------------------------------------------------------------
+# Variables
+#------------------------------------------------------------------------------
+
+ protected $mLastQuery = '';
+
+ protected $mServer, $mUser, $mPassword, $mConn = null, $mDBname;
+ protected $mOut, $mOpened = false;
+
+ protected $mFailFunction;
+ protected $mTablePrefix;
+ protected $mFlags;
+ protected $mTrxLevel = 0;
+ protected $mErrorCount = 0;
+ protected $mLBInfo = array();
+ protected $mCascadingDeletes = false;
+ protected $mCleanupTriggers = false;
+ protected $mStrictIPs = false;
+
+#------------------------------------------------------------------------------
+# Accessors
+#------------------------------------------------------------------------------
+ # These optionally set a variable and return the previous state
+
+ /**
+ * Fail function, takes a Database as a parameter
+ * Set to false for default, 1 for ignore errors
+ */
+ function failFunction( $function = NULL ) {
+ return wfSetVar( $this->mFailFunction, $function );
+ }
+
+ /**
+ * Output page, used for reporting errors
+ * FALSE means discard output
+ */
+ function setOutputPage( $out ) {
+ $this->mOut = $out;
+ }
+
+ /**
+ * Boolean, controls output of large amounts of debug information
+ */
+ function debug( $debug = NULL ) {
+ return wfSetBit( $this->mFlags, DBO_DEBUG, $debug );
+ }
+
+ /**
+ * Turns buffering of SQL result sets on (true) or off (false).
+ * Default is "on" and it should not be changed without good reasons.
+ */
+ function bufferResults( $buffer = NULL ) {
+ if ( is_null( $buffer ) ) {
+ return !(bool)( $this->mFlags & DBO_NOBUFFER );
+ } else {
+ return !wfSetBit( $this->mFlags, DBO_NOBUFFER, !$buffer );
+ }
+ }
+
+ /**
+ * Turns on (false) or off (true) the automatic generation and sending
+ * of a "we're sorry, but there has been a database error" page on
+ * database errors. Default is on (false). When turned off, the
+ * code should use lastErrno() and lastError() to handle the
+ * situation as appropriate.
+ */
+ function ignoreErrors( $ignoreErrors = NULL ) {
+ return wfSetBit( $this->mFlags, DBO_IGNORE, $ignoreErrors );
+ }
+
+ /**
+ * The current depth of nested transactions
+ * @param $level Integer: , default NULL.
+ */
+ function trxLevel( $level = NULL ) {
+ return wfSetVar( $this->mTrxLevel, $level );
+ }
+
+ /**
+ * Number of errors logged, only useful when errors are ignored
+ */
+ function errorCount( $count = NULL ) {
+ return wfSetVar( $this->mErrorCount, $count );
+ }
+
+ /**
+ * Properties passed down from the server info array of the load balancer
+ */
+ function getLBInfo( $name = NULL ) {
+ if ( is_null( $name ) ) {
+ return $this->mLBInfo;
+ } else {
+ if ( array_key_exists( $name, $this->mLBInfo ) ) {
+ return $this->mLBInfo[$name];
+ } else {
+ return NULL;
+ }
+ }
+ }
+
+ function setLBInfo( $name, $value = NULL ) {
+ if ( is_null( $value ) ) {
+ $this->mLBInfo = $name;
+ } else {
+ $this->mLBInfo[$name] = $value;
+ }
+ }
+
+ /**
+ * Returns true if this database supports (and uses) cascading deletes
+ */
+ function cascadingDeletes() {
+ return $this->mCascadingDeletes;
+ }
+
+ /**
+ * Returns true if this database supports (and uses) triggers (e.g. on the page table)
+ */
+ function cleanupTriggers() {
+ return $this->mCleanupTriggers;
+ }
+
+ /**
+ * Returns true if this database is strict about what can be put into an IP field.
+ * Specifically, it uses a NULL value instead of an empty string.
+ */
+ function strictIPs() {
+ return $this->mStrictIPs;
+ }
+
+ /**
+ * Returns true if this database uses timestamps rather than integers
+ */
+ function realTimestamps() {
+ return false;
+ }
+
+ /**
+ * Returns true if this database does an implicit sort when doing GROUP BY
+ */
+ function implicitGroupby() {
+ return true;
+ }
+
+ /**#@+
+ * Get function
+ */
+ function lastQuery() { return $this->mLastQuery; }
+ function isOpen() { return $this->mOpened; }
+ /**#@-*/
+
+ function setFlag( $flag ) {
+ $this->mFlags |= $flag;
+ }
+
+ function clearFlag( $flag ) {
+ $this->mFlags &= ~$flag;
+ }
+
+ function getFlag( $flag ) {
+ return !!($this->mFlags & $flag);
+ }
+
+ /**
+ * General read-only accessor
+ */
+ function getProperty( $name ) {
+ return $this->$name;
+ }
+
+#------------------------------------------------------------------------------
+# Other functions
+#------------------------------------------------------------------------------
+
+ /**@{{
+ * @param string $server database server host
+ * @param string $user database user name
+ * @param string $password database user password
+ * @param string $dbname database name
+ */
+
+ /**
+ * @param failFunction
+ * @param $flags
+ * @param $tablePrefix String: database table prefixes. By default use the prefix gave in LocalSettings.php
+ */
+ function __construct( $server = false, $user = false, $password = false, $dbName = false,
+ $failFunction = false, $flags = 0, $tablePrefix = 'get from global' ) {
+
+ global $wgOut, $wgDBprefix, $wgCommandLineMode;
+ # Can't get a reference if it hasn't been set yet
+ if ( !isset( $wgOut ) ) {
+ $wgOut = NULL;
+ }
+ $this->mOut =& $wgOut;
+
+ $this->mFailFunction = $failFunction;
+ $this->mFlags = $flags;
+
+ if ( $this->mFlags & DBO_DEFAULT ) {
+ if ( $wgCommandLineMode ) {
+ $this->mFlags &= ~DBO_TRX;
+ } else {
+ $this->mFlags |= DBO_TRX;
+ }
+ }
+
+ /*
+ // Faster read-only access
+ if ( wfReadOnly() ) {
+ $this->mFlags |= DBO_PERSISTENT;
+ $this->mFlags &= ~DBO_TRX;
+ }*/
+
+ /** Get the default table prefix*/
+ if ( $tablePrefix == 'get from global' ) {
+ $this->mTablePrefix = $wgDBprefix;
+ } else {
+ $this->mTablePrefix = $tablePrefix;
+ }
+
+ if ( $server ) {
+ $this->open( $server, $user, $password, $dbName );
+ }
+ }
+
+ /**
+ * @static
+ * @param failFunction
+ * @param $flags
+ */
+ static function newFromParams( $server, $user, $password, $dbName,
+ $failFunction = false, $flags = 0 )
+ {
+ return new Database( $server, $user, $password, $dbName, $failFunction, $flags );
+ }
+
+ /**
+ * Usually aborts on failure
+ * If the failFunction is set to a non-zero integer, returns success
+ */
+ function open( $server, $user, $password, $dbName ) {
+ global $wguname;
+ wfProfileIn( __METHOD__ );
+
+ # Test for missing mysql.so
+ # First try to load it
+ if (!@extension_loaded('mysql')) {
+ @dl('mysql.so');
+ }
+
+ # Fail now
+ # Otherwise we get a suppressed fatal error, which is very hard to track down
+ if ( !function_exists( 'mysql_connect' ) ) {
+ throw new DBConnectionError( $this, "MySQL functions missing, have you compiled PHP with the --with-mysql option?\n" );
+ }
+
+ $this->close();
+ $this->mServer = $server;
+ $this->mUser = $user;
+ $this->mPassword = $password;
+ $this->mDBname = $dbName;
+
+ $success = false;
+
+ wfProfileIn("dbconnect-$server");
+
+ # LIVE PATCH by Tim, ask Domas for why: retry loop
+ $this->mConn = false;
+ $max = 3;
+ for ( $i = 0; $i < $max && !$this->mConn; $i++ ) {
+ if ( $i > 1 ) {
+ usleep( 1000 );
+ }
+ if ( $this->mFlags & DBO_PERSISTENT ) {
+ @/**/$this->mConn = mysql_pconnect( $server, $user, $password );
+ } else {
+ # Create a new connection...
+ @/**/$this->mConn = mysql_connect( $server, $user, $password, true );
+ }
+ if ($this->mConn === false) {
+ $iplus = $i + 1;
+ wfLogDBError("Connect loop error $iplus of $max ($server): " . mysql_errno() . " - " . mysql_error()."\n");
+ }
+ }
+
+ wfProfileOut("dbconnect-$server");
+
+ if ( $dbName != '' ) {
+ if ( $this->mConn !== false ) {
+ $success = @/**/mysql_select_db( $dbName, $this->mConn );
+ if ( !$success ) {
+ $error = "Error selecting database $dbName on server {$this->mServer} " .
+ "from client host {$wguname['nodename']}\n";
+ wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
+ wfDebug( $error );
+ }
+ } else {
+ wfDebug( "DB connection error\n" );
+ wfDebug( "Server: $server, User: $user, Password: " .
+ substr( $password, 0, 3 ) . "..., error: " . mysql_error() . "\n" );
+ $success = false;
+ }
+ } else {
+ # Delay USE query
+ $success = (bool)$this->mConn;
+ }
+
+ if ( $success ) {
+ global $wgDBmysql5;
+ if( $wgDBmysql5 ) {
+ // Tell the server we're communicating with it in UTF-8.
+ // This may engage various charset conversions.
+ $this->query( 'SET NAMES utf8' );
+ }
+ } else {
+ $this->reportConnectionError();
+ }
+
+ $this->mOpened = $success;
+ wfProfileOut( __METHOD__ );
+ return $success;
+ }
+ /**@}}*/
+
+ /**
+ * Closes a database connection.
+ * if it is open : commits any open transactions
+ *
+ * @return bool operation success. true if already closed.
+ */
+ function close()
+ {
+ $this->mOpened = false;
+ if ( $this->mConn ) {
+ if ( $this->trxLevel() ) {
+ $this->immediateCommit();
+ }
+ return mysql_close( $this->mConn );
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * @param string $error fallback error message, used if none is given by MySQL
+ */
+ function reportConnectionError( $error = 'Unknown error' ) {
+ $myError = $this->lastError();
+ if ( $myError ) {
+ $error = $myError;
+ }
+
+ if ( $this->mFailFunction ) {
+ # Legacy error handling method
+ if ( !is_int( $this->mFailFunction ) ) {
+ $ff = $this->mFailFunction;
+ $ff( $this, $error );
+ }
+ } else {
+ # New method
+ wfLogDBError( "Connection error: $error\n" );
+ throw new DBConnectionError( $this, $error );
+ }
+ }
+
+ /**
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns success
+ */
+ function query( $sql, $fname = '', $tempIgnore = false ) {
+ global $wgProfiling;
+
+ if ( $wgProfiling ) {
+ # generalizeSQL will probably cut down the query to reasonable
+ # logging size most of the time. The substr is really just a sanity check.
+
+ # Who's been wasting my precious column space? -- TS
+ #$profName = 'query: ' . $fname . ' ' . substr( Database::generalizeSQL( $sql ), 0, 255 );
+
+ if ( is_null( $this->getLBInfo( 'master' ) ) ) {
+ $queryProf = 'query: ' . substr( Database::generalizeSQL( $sql ), 0, 255 );
+ $totalProf = 'Database::query';
+ } else {
+ $queryProf = 'query-m: ' . substr( Database::generalizeSQL( $sql ), 0, 255 );
+ $totalProf = 'Database::query-master';
+ }
+ wfProfileIn( $totalProf );
+ wfProfileIn( $queryProf );
+ }
+
+ $this->mLastQuery = $sql;
+
+ # Add a comment for easy SHOW PROCESSLIST interpretation
+ if ( $fname ) {
+ $commentedSql = preg_replace('/\s/', " /* $fname */ ", $sql, 1);
+ } else {
+ $commentedSql = $sql;
+ }
+
+ # If DBO_TRX is set, start a transaction
+ if ( ( $this->mFlags & DBO_TRX ) && !$this->trxLevel() &&
+ $sql != 'BEGIN' && $sql != 'COMMIT' && $sql != 'ROLLBACK'
+ ) {
+ $this->begin();
+ }
+
+ if ( $this->debug() ) {
+ $sqlx = substr( $commentedSql, 0, 500 );
+ $sqlx = strtr( $sqlx, "\t\n", ' ' );
+ wfDebug( "SQL: $sqlx\n" );
+ }
+
+ # Do the query and handle errors
+ $ret = $this->doQuery( $commentedSql );
+
+ # Try reconnecting if the connection was lost
+ if ( false === $ret && ( $this->lastErrno() == 2013 || $this->lastErrno() == 2006 ) ) {
+ # Transaction is gone, like it or not
+ $this->mTrxLevel = 0;
+ wfDebug( "Connection lost, reconnecting...\n" );
+ if ( $this->ping() ) {
+ wfDebug( "Reconnected\n" );
+ $ret = $this->doQuery( $commentedSql );
+ } else {
+ wfDebug( "Failed\n" );
+ }
+ }
+
+ if ( false === $ret ) {
+ $this->reportQueryError( $this->lastError(), $this->lastErrno(), $sql, $fname, $tempIgnore );
+ }
+
+ if ( $wgProfiling ) {
+ wfProfileOut( $queryProf );
+ wfProfileOut( $totalProf );
+ }
+ return $ret;
+ }
+
+ /**
+ * The DBMS-dependent part of query()
+ * @param string $sql SQL query.
+ */
+ function doQuery( $sql ) {
+ if( $this->bufferResults() ) {
+ $ret = mysql_query( $sql, $this->mConn );
+ } else {
+ $ret = mysql_unbuffered_query( $sql, $this->mConn );
+ }
+ return $ret;
+ }
+
+ /**
+ * @param $error
+ * @param $errno
+ * @param $sql
+ * @param string $fname
+ * @param bool $tempIgnore
+ */
+ function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
+ global $wgCommandLineMode;
+ # Ignore errors during error handling to avoid infinite recursion
+ $ignore = $this->ignoreErrors( true );
+ ++$this->mErrorCount;
+
+ if( $ignore || $tempIgnore ) {
+ wfDebug("SQL ERROR (ignored): $error\n");
+ $this->ignoreErrors( $ignore );
+ } else {
+ $sql1line = str_replace( "\n", "\\n", $sql );
+ wfLogDBError("$fname\t{$this->mServer}\t$errno\t$error\t$sql1line\n");
+ wfDebug("SQL ERROR: " . $error . "\n");
+ throw new DBQueryError( $this, $error, $errno, $sql, $fname );
+ }
+ }
+
+
+ /**
+ * Intended to be compatible with the PEAR::DB wrapper functions.
+ * http://pear.php.net/manual/en/package.database.db.intro-execute.php
+ *
+ * ? = scalar value, quoted as necessary
+ * ! = raw SQL bit (a function for instance)
+ * & = filename; reads the file and inserts as a blob
+ * (we don't use this though...)
+ */
+ function prepare( $sql, $func = 'Database::prepare' ) {
+ /* MySQL doesn't support prepared statements (yet), so just
+ pack up the query for reference. We'll manually replace
+ the bits later. */
+ return array( 'query' => $sql, 'func' => $func );
+ }
+
+ function freePrepared( $prepared ) {
+ /* No-op for MySQL */
+ }
+
+ /**
+ * Execute a prepared query with the various arguments
+ * @param string $prepared the prepared sql
+ * @param mixed $args Either an array here, or put scalars as varargs
+ */
+ function execute( $prepared, $args = null ) {
+ if( !is_array( $args ) ) {
+ # Pull the var args
+ $args = func_get_args();
+ array_shift( $args );
+ }
+ $sql = $this->fillPrepared( $prepared['query'], $args );
+ return $this->query( $sql, $prepared['func'] );
+ }
+
+ /**
+ * Prepare & execute an SQL statement, quoting and inserting arguments
+ * in the appropriate places.
+ * @param string $query
+ * @param string $args ...
+ */
+ function safeQuery( $query, $args = null ) {
+ $prepared = $this->prepare( $query, 'Database::safeQuery' );
+ if( !is_array( $args ) ) {
+ # Pull the var args
+ $args = func_get_args();
+ array_shift( $args );
+ }
+ $retval = $this->execute( $prepared, $args );
+ $this->freePrepared( $prepared );
+ return $retval;
+ }
+
+ /**
+ * For faking prepared SQL statements on DBs that don't support
+ * it directly.
+ * @param string $preparedSql - a 'preparable' SQL statement
+ * @param array $args - array of arguments to fill it with
+ * @return string executable SQL
+ */
+ function fillPrepared( $preparedQuery, $args ) {
+ reset( $args );
+ $this->preparedArgs =& $args;
+ return preg_replace_callback( '/(\\\\[?!&]|[?!&])/',
+ array( &$this, 'fillPreparedArg' ), $preparedQuery );
+ }
+
+ /**
+ * preg_callback func for fillPrepared()
+ * The arguments should be in $this->preparedArgs and must not be touched
+ * while we're doing this.
+ *
+ * @param array $matches
+ * @return string
+ * @private
+ */
+ function fillPreparedArg( $matches ) {
+ switch( $matches[1] ) {
+ case '\\?': return '?';
+ case '\\!': return '!';
+ case '\\&': return '&';
+ }
+ list( /* $n */ , $arg ) = each( $this->preparedArgs );
+ switch( $matches[1] ) {
+ case '?': return $this->addQuotes( $arg );
+ case '!': return $arg;
+ case '&':
+ # return $this->addQuotes( file_get_contents( $arg ) );
+ throw new DBUnexpectedError( $this, '& mode is not implemented. If it\'s really needed, uncomment the line above.' );
+ default:
+ throw new DBUnexpectedError( $this, 'Received invalid match. This should never happen!' );
+ }
+ }
+
+ /**#@+
+ * @param mixed $res A SQL result
+ */
+ /**
+ * Free a result object
+ */
+ function freeResult( $res ) {
+ if ( !@/**/mysql_free_result( $res ) ) {
+ throw new DBUnexpectedError( $this, "Unable to free MySQL result" );
+ }
+ }
+
+ /**
+ * Fetch the next row from the given result object, in object form
+ */
+ function fetchObject( $res ) {
+ @/**/$row = mysql_fetch_object( $res );
+ if( $this->lastErrno() ) {
+ throw new DBUnexpectedError( $this, 'Error in fetchObject(): ' . htmlspecialchars( $this->lastError() ) );
+ }
+ return $row;
+ }
+
+ /**
+ * Fetch the next row from the given result object
+ * Returns an array
+ */
+ function fetchRow( $res ) {
+ @/**/$row = mysql_fetch_array( $res );
+ if ( $this->lastErrno() ) {
+ throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' . htmlspecialchars( $this->lastError() ) );
+ }
+ return $row;
+ }
+
+ /**
+ * Get the number of rows in a result object
+ */
+ function numRows( $res ) {
+ @/**/$n = mysql_num_rows( $res );
+ if( $this->lastErrno() ) {
+ throw new DBUnexpectedError( $this, 'Error in numRows(): ' . htmlspecialchars( $this->lastError() ) );
+ }
+ return $n;
+ }
+
+ /**
+ * Get the number of fields in a result object
+ * See documentation for mysql_num_fields()
+ */
+ function numFields( $res ) { return mysql_num_fields( $res ); }
+
+ /**
+ * Get a field name in a result object
+ * See documentation for mysql_field_name():
+ * http://www.php.net/mysql_field_name
+ */
+ function fieldName( $res, $n ) { return mysql_field_name( $res, $n ); }
+
+ /**
+ * Get the inserted value of an auto-increment row
+ *
+ * The value inserted should be fetched from nextSequenceValue()
+ *
+ * Example:
+ * $id = $dbw->nextSequenceValue('page_page_id_seq');
+ * $dbw->insert('page',array('page_id' => $id));
+ * $id = $dbw->insertId();
+ */
+ function insertId() { return mysql_insert_id( $this->mConn ); }
+
+ /**
+ * Change the position of the cursor in a result object
+ * See mysql_data_seek()
+ */
+ function dataSeek( $res, $row ) { return mysql_data_seek( $res, $row ); }
+
+ /**
+ * Get the last error number
+ * See mysql_errno()
+ */
+ function lastErrno() {
+ if ( $this->mConn ) {
+ return mysql_errno( $this->mConn );
+ } else {
+ return mysql_errno();
+ }
+ }
+
+ /**
+ * Get a description of the last error
+ * See mysql_error() for more details
+ */
+ function lastError() {
+ if ( $this->mConn ) {
+ # Even if it's non-zero, it can still be invalid
+ wfSuppressWarnings();
+ $error = mysql_error( $this->mConn );
+ if ( !$error ) {
+ $error = mysql_error();
+ }
+ wfRestoreWarnings();
+ } else {
+ $error = mysql_error();
+ }
+ if( $error ) {
+ $error .= ' (' . $this->mServer . ')';
+ }
+ return $error;
+ }
+ /**
+ * Get the number of rows affected by the last write query
+ * See mysql_affected_rows() for more details
+ */
+ function affectedRows() { return mysql_affected_rows( $this->mConn ); }
+ /**#@-*/ // end of template : @param $result
+
+ /**
+ * Simple UPDATE wrapper
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns success
+ *
+ * This function exists for historical reasons, Database::update() has a more standard
+ * calling convention and feature set
+ */
+ function set( $table, $var, $value, $cond, $fname = 'Database::set' )
+ {
+ $table = $this->tableName( $table );
+ $sql = "UPDATE $table SET $var = '" .
+ $this->strencode( $value ) . "' WHERE ($cond)";
+ return (bool)$this->query( $sql, $fname );
+ }
+
+ /**
+ * Simple SELECT wrapper, returns a single field, input must be encoded
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns FALSE on failure
+ */
+ function selectField( $table, $var, $cond='', $fname = 'Database::selectField', $options = array() ) {
+ if ( !is_array( $options ) ) {
+ $options = array( $options );
+ }
+ $options['LIMIT'] = 1;
+
+ $res = $this->select( $table, $var, $cond, $fname, $options );
+ if ( $res === false || !$this->numRows( $res ) ) {
+ return false;
+ }
+ $row = $this->fetchRow( $res );
+ if ( $row !== false ) {
+ $this->freeResult( $res );
+ return $row[0];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns an optional USE INDEX clause to go after the table, and a
+ * string to go at the end of the query
+ *
+ * @private
+ *
+ * @param array $options an associative array of options to be turned into
+ * an SQL query, valid keys are listed in the function.
+ * @return array
+ */
+ function makeSelectOptions( $options ) {
+ $tailOpts = '';
+ $startOpts = '';
+
+ $noKeyOptions = array();
+ foreach ( $options as $key => $option ) {
+ if ( is_numeric( $key ) ) {
+ $noKeyOptions[$option] = true;
+ }
+ }
+
+ if ( isset( $options['GROUP BY'] ) ) $tailOpts .= " GROUP BY {$options['GROUP BY']}";
+ if ( isset( $options['ORDER BY'] ) ) $tailOpts .= " ORDER BY {$options['ORDER BY']}";
+
+ if (isset($options['LIMIT'])) {
+ $tailOpts .= $this->limitResult('', $options['LIMIT'],
+ isset($options['OFFSET']) ? $options['OFFSET'] : false);
+ }
+
+ if ( isset( $noKeyOptions['FOR UPDATE'] ) ) $tailOpts .= ' FOR UPDATE';
+ if ( isset( $noKeyOptions['LOCK IN SHARE MODE'] ) ) $tailOpts .= ' LOCK IN SHARE MODE';
+ if ( isset( $noKeyOptions['DISTINCT'] ) && isset( $noKeyOptions['DISTINCTROW'] ) ) $startOpts .= 'DISTINCT';
+
+ # Various MySQL extensions
+ if ( isset( $noKeyOptions['STRAIGHT_JOIN'] ) ) $startOpts .= ' /*! STRAIGHT_JOIN */';
+ if ( isset( $noKeyOptions['HIGH_PRIORITY'] ) ) $startOpts .= ' HIGH_PRIORITY';
+ if ( isset( $noKeyOptions['SQL_BIG_RESULT'] ) ) $startOpts .= ' SQL_BIG_RESULT';
+ if ( isset( $noKeyOptions['SQL_BUFFER_RESULT'] ) ) $startOpts .= ' SQL_BUFFER_RESULT';
+ if ( isset( $noKeyOptions['SQL_SMALL_RESULT'] ) ) $startOpts .= ' SQL_SMALL_RESULT';
+ if ( isset( $noKeyOptions['SQL_CALC_FOUND_ROWS'] ) ) $startOpts .= ' SQL_CALC_FOUND_ROWS';
+ if ( isset( $noKeyOptions['SQL_CACHE'] ) ) $startOpts .= ' SQL_CACHE';
+ if ( isset( $noKeyOptions['SQL_NO_CACHE'] ) ) $startOpts .= ' SQL_NO_CACHE';
+
+ if ( isset( $options['USE INDEX'] ) && ! is_array( $options['USE INDEX'] ) ) {
+ $useIndex = $this->useIndexClause( $options['USE INDEX'] );
+ } else {
+ $useIndex = '';
+ }
+
+ return array( $startOpts, $useIndex, $tailOpts );
+ }
+
+ /**
+ * SELECT wrapper
+ *
+ * @param mixed $table Array or string, table name(s) (prefix auto-added)
+ * @param mixed $vars Array or string, field name(s) to be retrieved
+ * @param mixed $conds Array or string, condition(s) for WHERE
+ * @param string $fname Calling function name (use __METHOD__) for logs/profiling
+ * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')),
+ * see Database::makeSelectOptions code for list of supported stuff
+ * @return mixed Database result resource (feed to Database::fetchObject or whatever), or false on failure
+ */
+ function select( $table, $vars, $conds='', $fname = 'Database::select', $options = array() )
+ {
+ if( is_array( $vars ) ) {
+ $vars = implode( ',', $vars );
+ }
+ if( !is_array( $options ) ) {
+ $options = array( $options );
+ }
+ if( is_array( $table ) ) {
+ if ( isset( $options['USE INDEX'] ) && is_array( $options['USE INDEX'] ) )
+ $from = ' FROM ' . $this->tableNamesWithUseIndex( $table, $options['USE INDEX'] );
+ else
+ $from = ' FROM ' . implode( ',', array_map( array( &$this, 'tableName' ), $table ) );
+ } elseif ($table!='') {
+ $from = ' FROM ' . $this->tableName( $table );
+ } else {
+ $from = '';
+ }
+
+ list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $options );
+
+ if( !empty( $conds ) ) {
+ if ( is_array( $conds ) ) {
+ $conds = $this->makeList( $conds, LIST_AND );
+ }
+ $sql = "SELECT $startOpts $vars $from $useIndex WHERE $conds $tailOpts";
+ } else {
+ $sql = "SELECT $startOpts $vars $from $useIndex $tailOpts";
+ }
+
+ return $this->query( $sql, $fname );
+ }
+
+ /**
+ * Single row SELECT wrapper
+ * Aborts or returns FALSE on error
+ *
+ * $vars: the selected variables
+ * $conds: a condition map, terms are ANDed together.
+ * Items with numeric keys are taken to be literal conditions
+ * Takes an array of selected variables, and a condition map, which is ANDed
+ * e.g: selectRow( "page", array( "page_id" ), array( "page_namespace" =>
+ * NS_MAIN, "page_title" => "Astronomy" ) ) would return an object where
+ * $obj- >page_id is the ID of the Astronomy article
+ *
+ * @todo migrate documentation to phpdocumentor format
+ */
+ function selectRow( $table, $vars, $conds, $fname = 'Database::selectRow', $options = array() ) {
+ $options['LIMIT'] = 1;
+ $res = $this->select( $table, $vars, $conds, $fname, $options );
+ if ( $res === false )
+ return false;
+ if ( !$this->numRows($res) ) {
+ $this->freeResult($res);
+ return false;
+ }
+ $obj = $this->fetchObject( $res );
+ $this->freeResult( $res );
+ return $obj;
+
+ }
+
+ /**
+ * Removes most variables from an SQL query and replaces them with X or N for numbers.
+ * It's only slightly flawed. Don't use for anything important.
+ *
+ * @param string $sql A SQL Query
+ * @static
+ */
+ static function generalizeSQL( $sql ) {
+ # This does the same as the regexp below would do, but in such a way
+ # as to avoid crashing php on some large strings.
+ # $sql = preg_replace ( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql);
+
+ $sql = str_replace ( "\\\\", '', $sql);
+ $sql = str_replace ( "\\'", '', $sql);
+ $sql = str_replace ( "\\\"", '', $sql);
+ $sql = preg_replace ("/'.*'/s", "'X'", $sql);
+ $sql = preg_replace ('/".*"/s', "'X'", $sql);
+
+ # All newlines, tabs, etc replaced by single space
+ $sql = preg_replace ( '/\s+/', ' ', $sql);
+
+ # All numbers => N
+ $sql = preg_replace ('/-?[0-9]+/s', 'N', $sql);
+
+ return $sql;
+ }
+
+ /**
+ * Determines whether a field exists in a table
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns NULL on failure
+ */
+ function fieldExists( $table, $field, $fname = 'Database::fieldExists' ) {
+ $table = $this->tableName( $table );
+ $res = $this->query( 'DESCRIBE '.$table, $fname );
+ if ( !$res ) {
+ return NULL;
+ }
+
+ $found = false;
+
+ while ( $row = $this->fetchObject( $res ) ) {
+ if ( $row->Field == $field ) {
+ $found = true;
+ break;
+ }
+ }
+ return $found;
+ }
+
+ /**
+ * Determines whether an index exists
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns NULL on failure
+ */
+ function indexExists( $table, $index, $fname = 'Database::indexExists' ) {
+ $info = $this->indexInfo( $table, $index, $fname );
+ if ( is_null( $info ) ) {
+ return NULL;
+ } else {
+ return $info !== false;
+ }
+ }
+
+
+ /**
+ * Get information about an index into an object
+ * Returns false if the index does not exist
+ */
+ function indexInfo( $table, $index, $fname = 'Database::indexInfo' ) {
+ # SHOW INDEX works in MySQL 3.23.58, but SHOW INDEXES does not.
+ # SHOW INDEX should work for 3.x and up:
+ # http://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
+ $table = $this->tableName( $table );
+ $sql = 'SHOW INDEX FROM '.$table;
+ $res = $this->query( $sql, $fname );
+ if ( !$res ) {
+ return NULL;
+ }
+
+ $result = array();
+ while ( $row = $this->fetchObject( $res ) ) {
+ if ( $row->Key_name == $index ) {
+ $result[] = $row;
+ }
+ }
+ $this->freeResult($res);
+
+ return empty($result) ? false : $result;
+ }
+
+ /**
+ * Query whether a given table exists
+ */
+ function tableExists( $table ) {
+ $table = $this->tableName( $table );
+ $old = $this->ignoreErrors( true );
+ $res = $this->query( "SELECT 1 FROM $table LIMIT 1" );
+ $this->ignoreErrors( $old );
+ if( $res ) {
+ $this->freeResult( $res );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * mysql_fetch_field() wrapper
+ * Returns false if the field doesn't exist
+ *
+ * @param $table
+ * @param $field
+ */
+ function fieldInfo( $table, $field ) {
+ $table = $this->tableName( $table );
+ $res = $this->query( "SELECT * FROM $table LIMIT 1" );
+ $n = mysql_num_fields( $res );
+ for( $i = 0; $i < $n; $i++ ) {
+ $meta = mysql_fetch_field( $res, $i );
+ if( $field == $meta->name ) {
+ return $meta;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * mysql_field_type() wrapper
+ */
+ function fieldType( $res, $index ) {
+ return mysql_field_type( $res, $index );
+ }
+
+ /**
+ * Determines if a given index is unique
+ */
+ function indexUnique( $table, $index ) {
+ $indexInfo = $this->indexInfo( $table, $index );
+ if ( !$indexInfo ) {
+ return NULL;
+ }
+ return !$indexInfo[0]->Non_unique;
+ }
+
+ /**
+ * INSERT wrapper, inserts an array into a table
+ *
+ * $a may be a single associative array, or an array of these with numeric keys, for
+ * multi-row insert.
+ *
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns success
+ */
+ function insert( $table, $a, $fname = 'Database::insert', $options = array() ) {
+ # No rows to insert, easy just return now
+ if ( !count( $a ) ) {
+ return true;
+ }
+
+ $table = $this->tableName( $table );
+ if ( !is_array( $options ) ) {
+ $options = array( $options );
+ }
+ if ( isset( $a[0] ) && is_array( $a[0] ) ) {
+ $multi = true;
+ $keys = array_keys( $a[0] );
+ } else {
+ $multi = false;
+ $keys = array_keys( $a );
+ }
+
+ $sql = 'INSERT ' . implode( ' ', $options ) .
+ " INTO $table (" . implode( ',', $keys ) . ') VALUES ';
+
+ if ( $multi ) {
+ $first = true;
+ foreach ( $a as $row ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ',';
+ }
+ $sql .= '(' . $this->makeList( $row ) . ')';
+ }
+ } else {
+ $sql .= '(' . $this->makeList( $a ) . ')';
+ }
+ return (bool)$this->query( $sql, $fname );
+ }
+
+ /**
+ * Make UPDATE options for the Database::update function
+ *
+ * @private
+ * @param array $options The options passed to Database::update
+ * @return string
+ */
+ function makeUpdateOptions( $options ) {
+ if( !is_array( $options ) ) {
+ $options = array( $options );
+ }
+ $opts = array();
+ if ( in_array( 'LOW_PRIORITY', $options ) )
+ $opts[] = $this->lowPriorityOption();
+ if ( in_array( 'IGNORE', $options ) )
+ $opts[] = 'IGNORE';
+ return implode(' ', $opts);
+ }
+
+ /**
+ * UPDATE wrapper, takes a condition array and a SET array
+ *
+ * @param string $table The table to UPDATE
+ * @param array $values An array of values to SET
+ * @param array $conds An array of conditions (WHERE). Use '*' to update all rows.
+ * @param string $fname The Class::Function calling this function
+ * (for the log)
+ * @param array $options An array of UPDATE options, can be one or
+ * more of IGNORE, LOW_PRIORITY
+ */
+ function update( $table, $values, $conds, $fname = 'Database::update', $options = array() ) {
+ $table = $this->tableName( $table );
+ $opts = $this->makeUpdateOptions( $options );
+ $sql = "UPDATE $opts $table SET " . $this->makeList( $values, LIST_SET );
+ if ( $conds != '*' ) {
+ $sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
+ }
+ $this->query( $sql, $fname );
+ }
+
+ /**
+ * Makes an encoded list of strings from an array
+ * $mode:
+ * LIST_COMMA - comma separated, no field names
+ * LIST_AND - ANDed WHERE clause (without the WHERE)
+ * LIST_OR - ORed WHERE clause (without the WHERE)
+ * LIST_SET - comma separated with field names, like a SET clause
+ * LIST_NAMES - comma separated field names
+ */
+ function makeList( $a, $mode = LIST_COMMA ) {
+ if ( !is_array( $a ) ) {
+ throw new DBUnexpectedError( $this, 'Database::makeList called with incorrect parameters' );
+ }
+
+ $first = true;
+ $list = '';
+ foreach ( $a as $field => $value ) {
+ if ( !$first ) {
+ if ( $mode == LIST_AND ) {
+ $list .= ' AND ';
+ } elseif($mode == LIST_OR) {
+ $list .= ' OR ';
+ } else {
+ $list .= ',';
+ }
+ } else {
+ $first = false;
+ }
+ if ( ($mode == LIST_AND || $mode == LIST_OR) && is_numeric( $field ) ) {
+ $list .= "($value)";
+ } elseif ( ($mode == LIST_SET) && is_numeric( $field ) ) {
+ $list .= "$value";
+ } elseif ( ($mode == LIST_AND || $mode == LIST_OR) && is_array ($value) ) {
+ $list .= $field." IN (".$this->makeList($value).") ";
+ } else {
+ if ( $mode == LIST_AND || $mode == LIST_OR || $mode == LIST_SET ) {
+ $list .= "$field = ";
+ }
+ $list .= $mode == LIST_NAMES ? $value : $this->addQuotes( $value );
+ }
+ }
+ return $list;
+ }
+
+ /**
+ * Change the current database
+ */
+ function selectDB( $db ) {
+ $this->mDBname = $db;
+ return mysql_select_db( $db, $this->mConn );
+ }
+
+ /**
+ * Format a table name ready for use in constructing an SQL query
+ *
+ * This does two important things: it quotes table names which as necessary,
+ * and it adds a table prefix if there is one.
+ *
+ * All functions of this object which require a table name call this function
+ * themselves. Pass the canonical name to such functions. This is only needed
+ * when calling query() directly.
+ *
+ * @param string $name database table name
+ */
+ function tableName( $name ) {
+ global $wgSharedDB;
+ # Skip quoted literals
+ if ( $name{0} != '`' ) {
+ if ( $this->mTablePrefix !== '' && strpos( '.', $name ) === false ) {
+ $name = "{$this->mTablePrefix}$name";
+ }
+ if ( isset( $wgSharedDB ) && "{$this->mTablePrefix}user" == $name ) {
+ $name = "`$wgSharedDB`.`$name`";
+ } else {
+ # Standard quoting
+ $name = "`$name`";
+ }
+ }
+ return $name;
+ }
+
+ /**
+ * Fetch a number of table names into an array
+ * This is handy when you need to construct SQL for joins
+ *
+ * Example:
+ * extract($dbr->tableNames('user','watchlist'));
+ * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
+ * WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
+ */
+ public function tableNames() {
+ $inArray = func_get_args();
+ $retVal = array();
+ foreach ( $inArray as $name ) {
+ $retVal[$name] = $this->tableName( $name );
+ }
+ return $retVal;
+ }
+
+ /**
+ * @desc: Fetch a number of table names into an zero-indexed numerical array
+ * This is handy when you need to construct SQL for joins
+ *
+ * Example:
+ * list( $user, $watchlist ) = $dbr->tableNames('user','watchlist');
+ * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
+ * WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
+ */
+ public function tableNamesN() {
+ $inArray = func_get_args();
+ $retVal = array();
+ foreach ( $inArray as $name ) {
+ $retVal[] = $this->tableName( $name );
+ }
+ return $retVal;
+ }
+
+ /**
+ * @private
+ */
+ function tableNamesWithUseIndex( $tables, $use_index ) {
+ $ret = array();
+
+ foreach ( $tables as $table )
+ if ( @$use_index[$table] !== null )
+ $ret[] = $this->tableName( $table ) . ' ' . $this->useIndexClause( implode( ',', (array)$use_index[$table] ) );
+ else
+ $ret[] = $this->tableName( $table );
+
+ return implode( ',', $ret );
+ }
+
+ /**
+ * Wrapper for addslashes()
+ * @param string $s String to be slashed.
+ * @return string slashed string.
+ */
+ function strencode( $s ) {
+ return mysql_real_escape_string( $s, $this->mConn );
+ }
+
+ /**
+ * If it's a string, adds quotes and backslashes
+ * Otherwise returns as-is
+ */
+ function addQuotes( $s ) {
+ if ( is_null( $s ) ) {
+ return 'NULL';
+ } else {
+ # This will also quote numeric values. This should be harmless,
+ # and protects against weird problems that occur when they really
+ # _are_ strings such as article titles and string->number->string
+ # conversion is not 1:1.
+ return "'" . $this->strencode( $s ) . "'";
+ }
+ }
+
+ /**
+ * Escape string for safe LIKE usage
+ */
+ function escapeLike( $s ) {
+ $s=$this->strencode( $s );
+ $s=str_replace(array('%','_'),array('\%','\_'),$s);
+ return $s;
+ }
+
+ /**
+ * Returns an appropriately quoted sequence value for inserting a new row.
+ * MySQL has autoincrement fields, so this is just NULL. But the PostgreSQL
+ * subclass will return an integer, and save the value for insertId()
+ */
+ function nextSequenceValue( $seqName ) {
+ return NULL;
+ }
+
+ /**
+ * USE INDEX clause
+ * PostgreSQL doesn't have them and returns ""
+ */
+ function useIndexClause( $index ) {
+ return "FORCE INDEX ($index)";
+ }
+
+ /**
+ * REPLACE query wrapper
+ * PostgreSQL simulates this with a DELETE followed by INSERT
+ * $row is the row to insert, an associative array
+ * $uniqueIndexes is an array of indexes. Each element may be either a
+ * field name or an array of field names
+ *
+ * It may be more efficient to leave off unique indexes which are unlikely to collide.
+ * However if you do this, you run the risk of encountering errors which wouldn't have
+ * occurred in MySQL
+ *
+ * @todo migrate comment to phodocumentor format
+ */
+ function replace( $table, $uniqueIndexes, $rows, $fname = 'Database::replace' ) {
+ $table = $this->tableName( $table );
+
+ # Single row case
+ if ( !is_array( reset( $rows ) ) ) {
+ $rows = array( $rows );
+ }
+
+ $sql = "REPLACE INTO $table (" . implode( ',', array_keys( $rows[0] ) ) .') VALUES ';
+ $first = true;
+ foreach ( $rows as $row ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ',';
+ }
+ $sql .= '(' . $this->makeList( $row ) . ')';
+ }
+ return $this->query( $sql, $fname );
+ }
+
+ /**
+ * DELETE where the condition is a join
+ * MySQL does this with a multi-table DELETE syntax, PostgreSQL does it with sub-selects
+ *
+ * For safety, an empty $conds will not delete everything. If you want to delete all rows where the
+ * join condition matches, set $conds='*'
+ *
+ * DO NOT put the join condition in $conds
+ *
+ * @param string $delTable The table to delete from.
+ * @param string $joinTable The other table.
+ * @param string $delVar The variable to join on, in the first table.
+ * @param string $joinVar The variable to join on, in the second table.
+ * @param array $conds Condition array of field names mapped to variables, ANDed together in the WHERE clause
+ */
+ function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = 'Database::deleteJoin' ) {
+ if ( !$conds ) {
+ throw new DBUnexpectedError( $this, 'Database::deleteJoin() called with empty $conds' );
+ }
+
+ $delTable = $this->tableName( $delTable );
+ $joinTable = $this->tableName( $joinTable );
+ $sql = "DELETE $delTable FROM $delTable, $joinTable WHERE $delVar=$joinVar ";
+ if ( $conds != '*' ) {
+ $sql .= ' AND ' . $this->makeList( $conds, LIST_AND );
+ }
+
+ return $this->query( $sql, $fname );
+ }
+
+ /**
+ * Returns the size of a text field, or -1 for "unlimited"
+ */
+ function textFieldSize( $table, $field ) {
+ $table = $this->tableName( $table );
+ $sql = "SHOW COLUMNS FROM $table LIKE \"$field\";";
+ $res = $this->query( $sql, 'Database::textFieldSize' );
+ $row = $this->fetchObject( $res );
+ $this->freeResult( $res );
+
+ $m = array();
+ if ( preg_match( '/\((.*)\)/', $row->Type, $m ) ) {
+ $size = $m[1];
+ } else {
+ $size = -1;
+ }
+ return $size;
+ }
+
+ /**
+ * @return string Returns the text of the low priority option if it is supported, or a blank string otherwise
+ */
+ function lowPriorityOption() {
+ return 'LOW_PRIORITY';
+ }
+
+ /**
+ * DELETE query wrapper
+ *
+ * Use $conds == "*" to delete all rows
+ */
+ function delete( $table, $conds, $fname = 'Database::delete' ) {
+ if ( !$conds ) {
+ throw new DBUnexpectedError( $this, 'Database::delete() called with no conditions' );
+ }
+ $table = $this->tableName( $table );
+ $sql = "DELETE FROM $table";
+ if ( $conds != '*' ) {
+ $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
+ }
+ return $this->query( $sql, $fname );
+ }
+
+ /**
+ * INSERT SELECT wrapper
+ * $varMap must be an associative array of the form array( 'dest1' => 'source1', ...)
+ * Source items may be literals rather than field names, but strings should be quoted with Database::addQuotes()
+ * $conds may be "*" to copy the whole table
+ * srcTable may be an array of tables.
+ */
+ function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = 'Database::insertSelect',
+ $insertOptions = array(), $selectOptions = array() )
+ {
+ $destTable = $this->tableName( $destTable );
+ if ( is_array( $insertOptions ) ) {
+ $insertOptions = implode( ' ', $insertOptions );
+ }
+ if( !is_array( $selectOptions ) ) {
+ $selectOptions = array( $selectOptions );
+ }
+ list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
+ if( is_array( $srcTable ) ) {
+ $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
+ } else {
+ $srcTable = $this->tableName( $srcTable );
+ }
+ $sql = "INSERT $insertOptions INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
+ " SELECT $startOpts " . implode( ',', $varMap ) .
+ " FROM $srcTable $useIndex ";
+ if ( $conds != '*' ) {
+ $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
+ }
+ $sql .= " $tailOpts";
+ return $this->query( $sql, $fname );
+ }
+
+ /**
+ * Construct a LIMIT query with optional offset
+ * This is used for query pages
+ * $sql string SQL query we will append the limit too
+ * $limit integer the SQL limit
+ * $offset integer the SQL offset (default false)
+ */
+ function limitResult($sql, $limit, $offset=false) {
+ if( !is_numeric($limit) ) {
+ throw new DBUnexpectedError( $this, "Invalid non-numeric limit passed to limitResult()\n" );
+ }
+ return " $sql LIMIT "
+ . ( (is_numeric($offset) && $offset != 0) ? "{$offset}," : "" )
+ . "{$limit} ";
+ }
+ function limitResultForUpdate($sql, $num) {
+ return $this->limitResult($sql, $num, 0);
+ }
+
+ /**
+ * Returns an SQL expression for a simple conditional.
+ * Uses IF on MySQL.
+ *
+ * @param string $cond SQL expression which will result in a boolean value
+ * @param string $trueVal SQL expression to return if true
+ * @param string $falseVal SQL expression to return if false
+ * @return string SQL fragment
+ */
+ function conditional( $cond, $trueVal, $falseVal ) {
+ return " IF($cond, $trueVal, $falseVal) ";
+ }
+
+ /**
+ * Determines if the last failure was due to a deadlock
+ */
+ function wasDeadlock() {
+ return $this->lastErrno() == 1213;
+ }
+
+ /**
+ * Perform a deadlock-prone transaction.
+ *
+ * This function invokes a callback function to perform a set of write
+ * queries. If a deadlock occurs during the processing, the transaction
+ * will be rolled back and the callback function will be called again.
+ *
+ * Usage:
+ * $dbw->deadlockLoop( callback, ... );
+ *
+ * Extra arguments are passed through to the specified callback function.
+ *
+ * Returns whatever the callback function returned on its successful,
+ * iteration, or false on error, for example if the retry limit was
+ * reached.
+ */
+ function deadlockLoop() {
+ $myFname = 'Database::deadlockLoop';
+
+ $this->begin();
+ $args = func_get_args();
+ $function = array_shift( $args );
+ $oldIgnore = $this->ignoreErrors( true );
+ $tries = DEADLOCK_TRIES;
+ if ( is_array( $function ) ) {
+ $fname = $function[0];
+ } else {
+ $fname = $function;
+ }
+ do {
+ $retVal = call_user_func_array( $function, $args );
+ $error = $this->lastError();
+ $errno = $this->lastErrno();
+ $sql = $this->lastQuery();
+
+ if ( $errno ) {
+ if ( $this->wasDeadlock() ) {
+ # Retry
+ usleep( mt_rand( DEADLOCK_DELAY_MIN, DEADLOCK_DELAY_MAX ) );
+ } else {
+ $this->reportQueryError( $error, $errno, $sql, $fname );
+ }
+ }
+ } while( $this->wasDeadlock() && --$tries > 0 );
+ $this->ignoreErrors( $oldIgnore );
+ if ( $tries <= 0 ) {
+ $this->query( 'ROLLBACK', $myFname );
+ $this->reportQueryError( $error, $errno, $sql, $fname );
+ return false;
+ } else {
+ $this->query( 'COMMIT', $myFname );
+ return $retVal;
+ }
+ }
+
+ /**
+ * Do a SELECT MASTER_POS_WAIT()
+ *
+ * @param string $file the binlog file
+ * @param string $pos the binlog position
+ * @param integer $timeout the maximum number of seconds to wait for synchronisation
+ */
+ function masterPosWait( $file, $pos, $timeout ) {
+ $fname = 'Database::masterPosWait';
+ wfProfileIn( $fname );
+
+
+ # Commit any open transactions
+ $this->immediateCommit();
+
+ # Call doQuery() directly, to avoid opening a transaction if DBO_TRX is set
+ $encFile = $this->strencode( $file );
+ $sql = "SELECT MASTER_POS_WAIT('$encFile', $pos, $timeout)";
+ $res = $this->doQuery( $sql );
+ if ( $res && $row = $this->fetchRow( $res ) ) {
+ $this->freeResult( $res );
+ wfProfileOut( $fname );
+ return $row[0];
+ } else {
+ wfProfileOut( $fname );
+ return false;
+ }
+ }
+
+ /**
+ * Get the position of the master from SHOW SLAVE STATUS
+ */
+ function getSlavePos() {
+ $res = $this->query( 'SHOW SLAVE STATUS', 'Database::getSlavePos' );
+ $row = $this->fetchObject( $res );
+ if ( $row ) {
+ return array( $row->Master_Log_File, $row->Read_Master_Log_Pos );
+ } else {
+ return array( false, false );
+ }
+ }
+
+ /**
+ * Get the position of the master from SHOW MASTER STATUS
+ */
+ function getMasterPos() {
+ $res = $this->query( 'SHOW MASTER STATUS', 'Database::getMasterPos' );
+ $row = $this->fetchObject( $res );
+ if ( $row ) {
+ return array( $row->File, $row->Position );
+ } else {
+ return array( false, false );
+ }
+ }
+
+ /**
+ * Begin a transaction, committing any previously open transaction
+ */
+ function begin( $fname = 'Database::begin' ) {
+ $this->query( 'BEGIN', $fname );
+ $this->mTrxLevel = 1;
+ }
+
+ /**
+ * End a transaction
+ */
+ function commit( $fname = 'Database::commit' ) {
+ $this->query( 'COMMIT', $fname );
+ $this->mTrxLevel = 0;
+ }
+
+ /**
+ * Rollback a transaction
+ */
+ function rollback( $fname = 'Database::rollback' ) {
+ $this->query( 'ROLLBACK', $fname );
+ $this->mTrxLevel = 0;
+ }
+
+ /**
+ * Begin a transaction, committing any previously open transaction
+ * @deprecated use begin()
+ */
+ function immediateBegin( $fname = 'Database::immediateBegin' ) {
+ $this->begin();
+ }
+
+ /**
+ * Commit transaction, if one is open
+ * @deprecated use commit()
+ */
+ function immediateCommit( $fname = 'Database::immediateCommit' ) {
+ $this->commit();
+ }
+
+ /**
+ * Return MW-style timestamp used for MySQL schema
+ */
+ function timestamp( $ts=0 ) {
+ return wfTimestamp(TS_MW,$ts);
+ }
+
+ /**
+ * Local database timestamp format or null
+ */
+ function timestampOrNull( $ts = null ) {
+ if( is_null( $ts ) ) {
+ return null;
+ } else {
+ return $this->timestamp( $ts );
+ }
+ }
+
+ /**
+ * @todo document
+ */
+ function resultObject( $result ) {
+ if( empty( $result ) ) {
+ return NULL;
+ } else {
+ return new ResultWrapper( $this, $result );
+ }
+ }
+
+ /**
+ * Return aggregated value alias
+ */
+ function aggregateValue ($valuedata,$valuename='value') {
+ return $valuename;
+ }
+
+ /**
+ * @return string wikitext of a link to the server software's web site
+ */
+ function getSoftwareLink() {
+ return "[http://www.mysql.com/ MySQL]";
+ }
+
+ /**
+ * @return string Version information from the database
+ */
+ function getServerVersion() {
+ return mysql_get_server_info( $this->mConn );
+ }
+
+ /**
+ * Ping the server and try to reconnect if it there is no connection
+ */
+ function ping() {
+ if( function_exists( 'mysql_ping' ) ) {
+ return mysql_ping( $this->mConn );
+ } else {
+ wfDebug( "Tried to call mysql_ping but this is ancient PHP version. Faking it!\n" );
+ return true;
+ }
+ }
+
+ /**
+ * Get slave lag.
+ * At the moment, this will only work if the DB user has the PROCESS privilege
+ */
+ function getLag() {
+ $res = $this->query( 'SHOW PROCESSLIST' );
+ # Find slave SQL thread. Assumed to be the second one running, which is a bit
+ # dubious, but unfortunately there's no easy rigorous way
+ while ( $row = $this->fetchObject( $res ) ) {
+ /* This should work for most situations - when default db
+ * for thread is not specified, it had no events executed,
+ * and therefore it doesn't know yet how lagged it is.
+ *
+ * Relay log I/O thread does not select databases.
+ */
+ if ( $row->User == 'system user' &&
+ $row->State != 'Waiting for master to send event' &&
+ $row->State != 'Connecting to master' &&
+ $row->State != 'Queueing master event to the relay log' &&
+ $row->State != 'Waiting for master update' &&
+ $row->State != 'Requesting binlog dump'
+ ) {
+ # This is it, return the time (except -ve)
+ if ( $row->Time > 0x7fffffff ) {
+ return false;
+ } else {
+ return $row->Time;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get status information from SHOW STATUS in an associative array
+ */
+ function getStatus($which="%") {
+ $res = $this->query( "SHOW STATUS LIKE '{$which}'" );
+ $status = array();
+ while ( $row = $this->fetchObject( $res ) ) {
+ $status[$row->Variable_name] = $row->Value;
+ }
+ return $status;
+ }
+
+ /**
+ * Return the maximum number of items allowed in a list, or 0 for unlimited.
+ */
+ function maxListLen() {
+ return 0;
+ }
+
+ function encodeBlob($b) {
+ return $b;
+ }
+
+ function decodeBlob($b) {
+ return $b;
+ }
+
+ /**
+ * Read and execute SQL commands from a file.
+ * Returns true on success, error string on failure
+ */
+ function sourceFile( $filename ) {
+ $fp = fopen( $filename, 'r' );
+ if ( false === $fp ) {
+ return "Could not open \"{$filename}\".\n";
+ }
+
+ $cmd = "";
+ $done = false;
+ $dollarquote = false;
+
+ while ( ! feof( $fp ) ) {
+ $line = trim( fgets( $fp, 1024 ) );
+ $sl = strlen( $line ) - 1;
+
+ if ( $sl < 0 ) { continue; }
+ if ( '-' == $line{0} && '-' == $line{1} ) { continue; }
+
+ ## Allow dollar quoting for function declarations
+ if (substr($line,0,4) == '$mw$') {
+ if ($dollarquote) {
+ $dollarquote = false;
+ $done = true;
+ }
+ else {
+ $dollarquote = true;
+ }
+ }
+ else if (!$dollarquote) {
+ if ( ';' == $line{$sl} && ($sl < 2 || ';' != $line{$sl - 1})) {
+ $done = true;
+ $line = substr( $line, 0, $sl );
+ }
+ }
+
+ if ( '' != $cmd ) { $cmd .= ' '; }
+ $cmd .= "$line\n";
+
+ if ( $done ) {
+ $cmd = str_replace(';;', ";", $cmd);
+ $cmd = $this->replaceVars( $cmd );
+ $res = $this->query( $cmd, 'dbsource', true );
+
+ if ( false === $res ) {
+ $err = $this->lastError();
+ return "Query \"{$cmd}\" failed with error code \"$err\".\n";
+ }
+
+ $cmd = '';
+ $done = false;
+ }
+ }
+ fclose( $fp );
+ return true;
+ }
+
+ /**
+ * Replace variables in sourced SQL
+ */
+ protected function replaceVars( $ins ) {
+ $varnames = array(
+ 'wgDBserver', 'wgDBname', 'wgDBintlname', 'wgDBuser',
+ 'wgDBpassword', 'wgDBsqluser', 'wgDBsqlpassword',
+ 'wgDBadminuser', 'wgDBadminpassword',
+ );
+
+ // Ordinary variables
+ foreach ( $varnames as $var ) {
+ if( isset( $GLOBALS[$var] ) ) {
+ $val = addslashes( $GLOBALS[$var] ); // FIXME: safety check?
+ $ins = str_replace( '{$' . $var . '}', $val, $ins );
+ $ins = str_replace( '/*$' . $var . '*/`', '`' . $val, $ins );
+ $ins = str_replace( '/*$' . $var . '*/', $val, $ins );
+ }
+ }
+
+ // Table prefixes
+ $ins = preg_replace_callback( '/\/\*(?:\$wgDBprefix|_)\*\/([a-z_]*)/',
+ array( &$this, 'tableNameCallback' ), $ins );
+ return $ins;
+ }
+
+ /**
+ * Table name callback
+ * @private
+ */
+ protected function tableNameCallback( $matches ) {
+ return $this->tableName( $matches[1] );
+ }
+
+}
+
+/**
+ * Database abstraction object for mySQL
+ * Inherit all methods and properties of Database::Database()
+ *
+ * @package MediaWiki
+ * @see Database
+ */
+class DatabaseMysql extends Database {
+ # Inherit all
+}
+
+
+/**
+ * Result wrapper for grabbing data queried by someone else
+ *
+ * @package MediaWiki
+ */
+class ResultWrapper {
+ var $db, $result;
+
+ /**
+ * @todo document
+ */
+ function ResultWrapper( &$database, $result ) {
+ $this->db =& $database;
+ $this->result =& $result;
+ }
+
+ /**
+ * @todo document
+ */
+ function numRows() {
+ return $this->db->numRows( $this->result );
+ }
+
+ /**
+ * @todo document
+ */
+ function fetchObject() {
+ return $this->db->fetchObject( $this->result );
+ }
+
+ /**
+ * @todo document
+ */
+ function fetchRow() {
+ return $this->db->fetchRow( $this->result );
+ }
+
+ /**
+ * @todo document
+ */
+ function free() {
+ $this->db->freeResult( $this->result );
+ unset( $this->result );
+ unset( $this->db );
+ }
+
+ function seek( $row ) {
+ $this->db->dataSeek( $this->result, $row );
+ }
+
+}
+
+?>
diff --git a/includes/DatabaseFunctions.php b/includes/DatabaseFunctions.php
new file mode 100644
index 000000000000..ca83b9e551bb
--- /dev/null
+++ b/includes/DatabaseFunctions.php
@@ -0,0 +1,403 @@
+<?php
+/**
+ * Legacy database functions, for compatibility with pre-1.3 code
+ * NOTE: this file is no longer loaded by default.
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns success
+ * @param $sql String: SQL query
+ * @param $db Mixed: database handler
+ * @param $fname String: name of the php function calling
+ */
+function wfQuery( $sql, $db, $fname = '' ) {
+ if ( !is_numeric( $db ) ) {
+ # Someone has tried to call this the old way
+ throw new FatalError( wfMsgNoDB( 'wrong_wfQuery_params', $db, $sql ) );
+ }
+ $c =& wfGetDB( $db );
+ if ( $c !== false ) {
+ return $c->query( $sql, $fname );
+ } else {
+ return false;
+ }
+}
+
+/**
+ *
+ * @param $sql String: SQL query
+ * @param $dbi
+ * @param $fname String: name of the php function calling
+ * @return Array: first row from the database
+ */
+function wfSingleQuery( $sql, $dbi, $fname = '' ) {
+ $db =& wfGetDB( $dbi );
+ $res = $db->query($sql, $fname );
+ $row = $db->fetchRow( $res );
+ $ret = $row[0];
+ $db->freeResult( $res );
+ return $ret;
+}
+
+/**
+ * Turns on (false) or off (true) the automatic generation and sending
+ * of a "we're sorry, but there has been a database error" page on
+ * database errors. Default is on (false). When turned off, the
+ * code should use wfLastErrno() and wfLastError() to handle the
+ * situation as appropriate.
+ *
+ * @param $newstate
+ * @param $dbi
+ * @return Returns the previous state.
+ */
+function wfIgnoreSQLErrors( $newstate, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->ignoreErrors( $newstate );
+ } else {
+ return NULL;
+ }
+}
+
+/**#@+
+ * @param $res Database result handler
+ * @param $dbi
+*/
+
+/**
+ * Free a database result
+ * @return Bool: whether result is sucessful or not.
+ */
+function wfFreeResult( $res, $dbi = DB_LAST )
+{
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ $db->freeResult( $res );
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Get an object from a database result
+ * @return object|false object we requested
+ */
+function wfFetchObject( $res, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fetchObject( $res, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Get a row from a database result
+ * @return object|false row we requested
+ */
+function wfFetchRow( $res, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fetchRow ( $res, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Get a number of rows from a database result
+ * @return integer|false number of rows
+ */
+function wfNumRows( $res, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->numRows( $res, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Get the number of fields from a database result
+ * @return integer|false number of fields
+ */
+function wfNumFields( $res, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->numFields( $res );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Return name of a field in a result
+ * @param $res Mixed: Ressource link see Database::fieldName()
+ * @param $n Integer: id of the field
+ * @param $dbi Default DB_LAST
+ * @return string|false name of field
+ */
+function wfFieldName( $res, $n, $dbi = DB_LAST )
+{
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fieldName( $res, $n, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
+}
+/**#@-*/
+
+/**
+ * @todo document function
+ */
+function wfInsertId( $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->insertId();
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfDataSeek( $res, $row, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->dataSeek( $res, $row );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfLastErrno( $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->lastErrno();
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfLastError( $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->lastError();
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfAffectedRows( $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->affectedRows();
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfLastDBquery( $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->lastQuery();
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @see Database::Set()
+ * @todo document function
+ * @param $table
+ * @param $var
+ * @param $value
+ * @param $cond
+ * @param $dbi Default DB_MASTER
+ */
+function wfSetSQL( $table, $var, $value, $cond, $dbi = DB_MASTER )
+{
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->set( $table, $var, $value, $cond );
+ } else {
+ return false;
+ }
+}
+
+
+/**
+ * @see Database::selectField()
+ * @todo document function
+ * @param $table
+ * @param $var
+ * @param $cond Default ''
+ * @param $dbi Default DB_LAST
+ */
+function wfGetSQL( $table, $var, $cond='', $dbi = DB_LAST )
+{
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->selectField( $table, $var, $cond );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @see Database::fieldExists()
+ * @todo document function
+ * @param $table
+ * @param $field
+ * @param $dbi Default DB_LAST
+ * @return Result of Database::fieldExists() or false.
+ */
+function wfFieldExists( $table, $field, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fieldExists( $table, $field );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @see Database::indexExists()
+ * @todo document function
+ * @param $table String
+ * @param $index
+ * @param $dbi Default DB_LAST
+ * @return Result of Database::indexExists() or false.
+ */
+function wfIndexExists( $table, $index, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->indexExists( $table, $index );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @see Database::insert()
+ * @todo document function
+ * @param $table String
+ * @param $array Array
+ * @param $fname String, default 'wfInsertArray'.
+ * @param $dbi Default DB_MASTER
+ * @return result of Database::insert() or false.
+ */
+function wfInsertArray( $table, $array, $fname = 'wfInsertArray', $dbi = DB_MASTER ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->insert( $table, $array, $fname );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @see Database::getArray()
+ * @todo document function
+ * @param $table String
+ * @param $vars
+ * @param $conds
+ * @param $fname String, default 'wfGetArray'.
+ * @param $dbi Default DB_LAST
+ * @return result of Database::getArray() or false.
+ */
+function wfGetArray( $table, $vars, $conds, $fname = 'wfGetArray', $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->getArray( $table, $vars, $conds, $fname );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @see Database::update()
+ * @param $table String
+ * @param $values
+ * @param $conds
+ * @param $fname String, default 'wfUpdateArray'
+ * @param $dbi Default DB_MASTER
+ * @return Result of Database::update()) or false;
+ * @todo document function
+ */
+function wfUpdateArray( $table, $values, $conds, $fname = 'wfUpdateArray', $dbi = DB_MASTER ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ $db->update( $table, $values, $conds, $fname );
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfTableName( $name, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->tableName( $name );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfStrencode( $s, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->strencode( $s );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfNextSequenceValue( $seqName, $dbi = DB_MASTER ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->nextSequenceValue( $seqName );
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @todo document function
+ */
+function wfUseIndexClause( $index, $dbi = DB_SLAVE ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->useIndexClause( $index );
+ } else {
+ return false;
+ }
+}
+?>
diff --git a/includes/DatabaseOracle.php b/includes/DatabaseOracle.php
new file mode 100644
index 000000000000..1a6f62f2fe37
--- /dev/null
+++ b/includes/DatabaseOracle.php
@@ -0,0 +1,691 @@
+<?php
+
+/**
+ * Oracle.
+ *
+ * @package MediaWiki
+ */
+
+class OracleBlob extends DBObject {
+ function isLOB() {
+ return true;
+ }
+ function data() {
+ return $this->mData;
+ }
+};
+
+/**
+ *
+ * @package MediaWiki
+ */
+class DatabaseOracle extends Database {
+ var $mInsertId = NULL;
+ var $mLastResult = NULL;
+ var $mFetchCache = array();
+ var $mFetchID = array();
+ var $mNcols = array();
+ var $mFieldNames = array(), $mFieldTypes = array();
+ var $mAffectedRows = array();
+ var $mErr;
+
+ function DatabaseOracle($server = false, $user = false, $password = false, $dbName = false,
+ $failFunction = false, $flags = 0, $tablePrefix = 'get from global' )
+ {
+ Database::Database( $server, $user, $password, $dbName, $failFunction, $flags, $tablePrefix );
+ }
+
+ /* static */ function newFromParams( $server = false, $user = false, $password = false, $dbName = false,
+ $failFunction = false, $flags = 0, $tablePrefix = 'get from global' )
+ {
+ return new DatabaseOracle( $server, $user, $password, $dbName, $failFunction, $flags, $tablePrefix );
+ }
+
+ /**
+ * Usually aborts on failure
+ * If the failFunction is set to a non-zero integer, returns success
+ */
+ function open( $server, $user, $password, $dbName ) {
+ if ( !function_exists( 'oci_connect' ) ) {
+ throw new DBConnectionError( $this, "Oracle functions missing, have you compiled PHP with the --with-oci8 option?\n" );
+ }
+ $this->close();
+ $this->mServer = $server;
+ $this->mUser = $user;
+ $this->mPassword = $password;
+ $this->mDBname = $dbName;
+
+ $this->mConn = oci_new_connect($user, $password, $dbName, "AL32UTF8");
+ if ( $this->mConn === false ) {
+ wfDebug( "DB connection error\n" );
+ wfDebug( "Server: $server, Database: $dbName, User: $user, Password: "
+ . substr( $password, 0, 3 ) . "...\n" );
+ wfDebug( $this->lastError()."\n" );
+ } else {
+ $this->mOpened = true;
+ }
+ return $this->mConn;
+ }
+
+ /**
+ * Closes a database connection, if it is open
+ * Returns success, true if already closed
+ */
+ function close() {
+ $this->mOpened = false;
+ if ($this->mConn) {
+ return oci_close($this->mConn);
+ } else {
+ return true;
+ }
+ }
+
+ function parseStatement($sql) {
+ $this->mErr = $this->mLastResult = false;
+ if (($stmt = oci_parse($this->mConn, $sql)) === false) {
+ $this->lastError();
+ return $this->mLastResult = false;
+ }
+ $this->mAffectedRows[$stmt] = 0;
+ return $this->mLastResult = $stmt;
+ }
+
+ function doQuery($sql) {
+ if (($stmt = $this->parseStatement($sql)) === false)
+ return false;
+ return $this->executeStatement($stmt);
+ }
+
+ function executeStatement($stmt) {
+ if (!oci_execute($stmt, OCI_DEFAULT)) {
+ $this->lastError();
+ oci_free_statement($stmt);
+ return false;
+ }
+ $this->mAffectedRows[$stmt] = oci_num_rows($stmt);
+ $this->mFetchCache[$stmt] = array();
+ $this->mFetchID[$stmt] = 0;
+ $this->mNcols[$stmt] = oci_num_fields($stmt);
+ if ($this->mNcols[$stmt] == 0)
+ return $this->mLastResult;
+ for ($i = 1; $i <= $this->mNcols[$stmt]; $i++) {
+ $this->mFieldNames[$stmt][$i] = oci_field_name($stmt, $i);
+ $this->mFieldTypes[$stmt][$i] = oci_field_type($stmt, $i);
+ }
+ while (($o = oci_fetch_array($stmt)) !== false) {
+ foreach ($o as $key => $value) {
+ if (is_object($value)) {
+ $o[$key] = $value->load();
+ }
+ }
+ $this->mFetchCache[$stmt][] = $o;
+ }
+ return $this->mLastResult;
+ }
+
+ function queryIgnore( $sql, $fname = '' ) {
+ return $this->query( $sql, $fname, true );
+ }
+
+ function freeResult( $res ) {
+ if (!oci_free_statement($res)) {
+ throw new DBUnexpectedError( $this, "Unable to free Oracle result\n" );
+ }
+ unset($this->mFetchID[$res]);
+ unset($this->mFetchCache[$res]);
+ unset($this->mNcols[$res]);
+ unset($this->mFieldNames[$res]);
+ unset($this->mFieldTypes[$res]);
+ }
+
+ function fetchAssoc($res) {
+ if ($this->mFetchID[$res] >= count($this->mFetchCache[$res]))
+ return false;
+
+ for ($i = 1; $i <= $this->mNcols[$res]; $i++) {
+ $name = $this->mFieldNames[$res][$i];
+ if (isset($this->mFetchCache[$res][$this->mFetchID[$res]][$name]))
+ $value = $this->mFetchCache[$res][$this->mFetchID[$res]][$name];
+ else $value = NULL;
+ $key = strtolower($name);
+ wfdebug("'$key' => '$value'\n");
+ $ret[$key] = $value;
+ }
+ $this->mFetchID[$res]++;
+ return $ret;
+ }
+
+ function fetchRow($res) {
+ $r = $this->fetchAssoc($res);
+ if (!$r)
+ return false;
+ $i = 0;
+ $ret = array();
+ foreach ($r as $value) {
+ wfdebug("ret[$i]=[$value]\n");
+ $ret[$i++] = $value;
+ }
+ return $ret;
+ }
+
+ function fetchObject($res) {
+ $row = $this->fetchAssoc($res);
+ if (!$row)
+ return false;
+ $ret = new stdClass;
+ foreach ($row as $key => $value)
+ $ret->$key = $value;
+ return $ret;
+ }
+
+ function numRows($res) {
+ return count($this->mFetchCache[$res]);
+ }
+ function numFields( $res ) { return pg_num_fields( $res ); }
+ function fieldName( $res, $n ) { return pg_field_name( $res, $n ); }
+
+ /**
+ * This must be called after nextSequenceVal
+ */
+ function insertId() {
+ return $this->mInsertId;
+ }
+
+ function dataSeek($res, $row) {
+ $this->mFetchID[$res] = $row;
+ }
+
+ function lastError() {
+ if ($this->mErr === false) {
+ if ($this->mLastResult !== false) {
+ $what = $this->mLastResult;
+ } else if ($this->mConn !== false) {
+ $what = $this->mConn;
+ } else {
+ $what = false;
+ }
+ $err = ($what !== false) ? oci_error($what) : oci_error();
+ if ($err === false) {
+ $this->mErr = 'no error';
+ } else {
+ $this->mErr = $err['message'];
+ }
+ }
+ return str_replace("\n", '<br />', $this->mErr);
+ }
+ function lastErrno() {
+ return 0;
+ }
+
+ function affectedRows() {
+ return $this->mAffectedRows[$this->mLastResult];
+ }
+
+ /**
+ * Returns information about an index
+ * If errors are explicitly ignored, returns NULL on failure
+ */
+ function indexInfo ($table, $index, $fname = 'Database::indexInfo' ) {
+ $table = $this->tableName($table, true);
+ if ($index == 'PRIMARY')
+ $index = "${table}_pk";
+ $sql = "SELECT uniqueness FROM all_indexes WHERE table_name='" .
+ $table . "' AND index_name='" .
+ $this->strencode(strtoupper($index)) . "'";
+ $res = $this->query($sql, $fname);
+ if (!$res)
+ return NULL;
+ if (($row = $this->fetchObject($res)) == NULL)
+ return false;
+ $this->freeResult($res);
+ $row->Non_unique = !$row->uniqueness;
+ return $row;
+
+ // BUG: !!!! This code needs to be synced up with database.php
+
+ }
+
+ function indexUnique ($table, $index, $fname = 'indexUnique') {
+ if (!($i = $this->indexInfo($table, $index, $fname)))
+ return $i;
+ return $i->uniqueness == 'UNIQUE';
+ }
+
+ function fieldInfo( $table, $field ) {
+ $o = new stdClass;
+ $o->multiple_key = true; /* XXX */
+ return $o;
+ }
+
+ function getColumnInformation($table, $field) {
+ $table = $this->tableName($table, true);
+ $field = strtoupper($field);
+
+ $res = $this->doQuery("SELECT * FROM all_tab_columns " .
+ "WHERE table_name='".$table."' " .
+ "AND column_name='".$field."'");
+ if (!$res)
+ return false;
+ $o = $this->fetchObject($res);
+ $this->freeResult($res);
+ return $o;
+ }
+
+ function fieldExists( $table, $field, $fname = 'Database::fieldExists' ) {
+ $column = $this->getColumnInformation($table, $field);
+ if (!$column)
+ return false;
+ return true;
+ }
+
+ function tableName($name, $forddl = false) {
+ # First run any transformations from the parent object
+ $name = parent::tableName( $name );
+
+ # Replace backticks into empty
+ # Note: "foo" and foo are not the same in Oracle!
+ $name = str_replace('`', '', $name);
+
+ # Now quote Oracle reserved keywords
+ switch( $name ) {
+ case 'user':
+ case 'group':
+ case 'validate':
+ if ($forddl)
+ return $name;
+ else
+ return '"' . $name . '"';
+
+ default:
+ return strtoupper($name);
+ }
+ }
+
+ function strencode( $s ) {
+ return str_replace("'", "''", $s);
+ }
+
+ /**
+ * Return the next in a sequence, save the value for retrieval via insertId()
+ */
+ function nextSequenceValue( $seqName ) {
+ $r = $this->doQuery("SELECT $seqName.nextval AS val FROM dual");
+ $o = $this->fetchObject($r);
+ $this->freeResult($r);
+ return $this->mInsertId = (int)$o->val;
+ }
+
+ /**
+ * USE INDEX clause
+ * PostgreSQL doesn't have them and returns ""
+ */
+ function useIndexClause( $index ) {
+ return '';
+ }
+
+ # REPLACE query wrapper
+ # PostgreSQL simulates this with a DELETE followed by INSERT
+ # $row is the row to insert, an associative array
+ # $uniqueIndexes is an array of indexes. Each element may be either a
+ # field name or an array of field names
+ #
+ # It may be more efficient to leave off unique indexes which are unlikely to collide.
+ # However if you do this, you run the risk of encountering errors which wouldn't have
+ # occurred in MySQL
+ function replace( $table, $uniqueIndexes, $rows, $fname = 'Database::replace' ) {
+ $table = $this->tableName( $table );
+
+ if (count($rows)==0) {
+ return;
+ }
+
+ # Single row case
+ if ( !is_array( reset( $rows ) ) ) {
+ $rows = array( $rows );
+ }
+
+ foreach( $rows as $row ) {
+ # Delete rows which collide
+ if ( $uniqueIndexes ) {
+ $sql = "DELETE FROM $table WHERE ";
+ $first = true;
+ foreach ( $uniqueIndexes as $index ) {
+ if ( $first ) {
+ $first = false;
+ $sql .= "(";
+ } else {
+ $sql .= ') OR (';
+ }
+ if ( is_array( $index ) ) {
+ $first2 = true;
+ foreach ( $index as $col ) {
+ if ( $first2 ) {
+ $first2 = false;
+ } else {
+ $sql .= ' AND ';
+ }
+ $sql .= $col.'=' . $this->addQuotes( $row[$col] );
+ }
+ } else {
+ $sql .= $index.'=' . $this->addQuotes( $row[$index] );
+ }
+ }
+ $sql .= ')';
+ $this->query( $sql, $fname );
+ }
+
+ # Now insert the row
+ $sql = "INSERT INTO $table (" . $this->makeList( array_keys( $row ), LIST_NAMES ) .') VALUES (' .
+ $this->makeList( $row, LIST_COMMA ) . ')';
+ $this->query( $sql, $fname );
+ }
+ }
+
+ # DELETE where the condition is a join
+ function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin" ) {
+ if ( !$conds ) {
+ throw new DBUnexpectedError( $this, 'Database::deleteJoin() called with empty $conds' );
+ }
+
+ $delTable = $this->tableName( $delTable );
+ $joinTable = $this->tableName( $joinTable );
+ $sql = "DELETE FROM $delTable WHERE $delVar IN (SELECT $joinVar FROM $joinTable ";
+ if ( $conds != '*' ) {
+ $sql .= 'WHERE ' . $this->makeList( $conds, LIST_AND );
+ }
+ $sql .= ')';
+
+ $this->query( $sql, $fname );
+ }
+
+ # Returns the size of a text field, or -1 for "unlimited"
+ function textFieldSize( $table, $field ) {
+ $table = $this->tableName( $table );
+ $sql = "SELECT t.typname as ftype,a.atttypmod as size
+ FROM pg_class c, pg_attribute a, pg_type t
+ WHERE relname='$table' AND a.attrelid=c.oid AND
+ a.atttypid=t.oid and a.attname='$field'";
+ $res =$this->query($sql);
+ $row=$this->fetchObject($res);
+ if ($row->ftype=="varchar") {
+ $size=$row->size-4;
+ } else {
+ $size=$row->size;
+ }
+ $this->freeResult( $res );
+ return $size;
+ }
+
+ function lowPriorityOption() {
+ return '';
+ }
+
+ function limitResult($sql, $limit, $offset) {
+ $ret = "SELECT * FROM ($sql) WHERE ROWNUM < " . ((int)$limit + (int)($offset+1));
+ if (is_numeric($offset))
+ $ret .= " AND ROWNUM >= " . (int)$offset;
+ return $ret;
+ }
+ function limitResultForUpdate($sql, $limit) {
+ return $sql;
+ }
+ /**
+ * Returns an SQL expression for a simple conditional.
+ * Uses CASE on PostgreSQL.
+ *
+ * @param string $cond SQL expression which will result in a boolean value
+ * @param string $trueVal SQL expression to return if true
+ * @param string $falseVal SQL expression to return if false
+ * @return string SQL fragment
+ */
+ function conditional( $cond, $trueVal, $falseVal ) {
+ return " (CASE WHEN $cond THEN $trueVal ELSE $falseVal END) ";
+ }
+
+ # FIXME: actually detecting deadlocks might be nice
+ function wasDeadlock() {
+ return false;
+ }
+
+ # Return DB-style timestamp used for MySQL schema
+ function timestamp($ts = 0) {
+ return $this->strencode(wfTimestamp(TS_ORACLE, $ts));
+# return "TO_TIMESTAMP('" . $this->strencode(wfTimestamp(TS_DB, $ts)) . "', 'RRRR-MM-DD HH24:MI:SS')";
+ }
+
+ /**
+ * Return aggregated value function call
+ */
+ function aggregateValue ($valuedata,$valuename='value') {
+ return $valuedata;
+ }
+
+
+ function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
+ $message = "A database error has occurred\n" .
+ "Query: $sql\n" .
+ "Function: $fname\n" .
+ "Error: $errno $error\n";
+ throw new DBUnexpectedError($this, $message);
+ }
+
+ /**
+ * @return string wikitext of a link to the server software's web site
+ */
+ function getSoftwareLink() {
+ return "[http://www.oracle.com/ Oracle]";
+ }
+
+ /**
+ * @return string Version information from the database
+ */
+ function getServerVersion() {
+ return oci_server_version($this->mConn);
+ }
+
+ function setSchema($schema=false) {
+ $schemas=$this->mSchemas;
+ if ($schema) { array_unshift($schemas,$schema); }
+ $searchpath=$this->makeList($schemas,LIST_NAMES);
+ $this->query("SET search_path = $searchpath");
+ }
+
+ function begin() {
+ }
+
+ function immediateCommit( $fname = 'Database::immediateCommit' ) {
+ oci_commit($this->mConn);
+ $this->mTrxLevel = 0;
+ }
+ function rollback( $fname = 'Database::rollback' ) {
+ oci_rollback($this->mConn);
+ $this->mTrxLevel = 0;
+ }
+ function getLag() {
+ return false;
+ }
+ function getStatus($which=null) {
+ $result = array('Threads_running' => 0, 'Threads_connected' => 0);
+ return $result;
+ }
+
+ /**
+ * Returns an optional USE INDEX clause to go after the table, and a
+ * string to go at the end of the query
+ *
+ * @access private
+ *
+ * @param array $options an associative array of options to be turned into
+ * an SQL query, valid keys are listed in the function.
+ * @return array
+ */
+ function makeSelectOptions($options) {
+ $tailOpts = '';
+
+ if (isset( $options['ORDER BY'])) {
+ $tailOpts .= " ORDER BY {$options['ORDER BY']}";
+ }
+
+ return array('', $tailOpts);
+ }
+
+ function maxListLen() {
+ return 1000;
+ }
+
+ /**
+ * Query whether a given table exists
+ */
+ function tableExists( $table ) {
+ $table = $this->tableName($table, true);
+ $res = $this->query( "SELECT COUNT(*) as NUM FROM user_tables WHERE table_name='"
+ . $table . "'" );
+ if (!$res)
+ return false;
+ $row = $this->fetchObject($res);
+ $this->freeResult($res);
+ return $row->num >= 1;
+ }
+
+ /**
+ * UPDATE wrapper, takes a condition array and a SET array
+ */
+ function update( $table, $values, $conds, $fname = 'Database::update' ) {
+ $table = $this->tableName( $table );
+
+ $sql = "UPDATE $table SET ";
+ $first = true;
+ foreach ($values as $field => $v) {
+ if ($first)
+ $first = false;
+ else
+ $sql .= ", ";
+ $sql .= "$field = :n$field ";
+ }
+ if ( $conds != '*' ) {
+ $sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
+ }
+ $stmt = $this->parseStatement($sql);
+ if ($stmt === false) {
+ $this->reportQueryError( $this->lastError(), $this->lastErrno(), $stmt );
+ return false;
+ }
+ if ($this->debug())
+ wfDebug("SQL: $sql\n");
+ $s = '';
+ foreach ($values as $field => $v) {
+ oci_bind_by_name($stmt, ":n$field", $values[$field]);
+ if ($this->debug())
+ $s .= " [$field] = [$v]\n";
+ }
+ if ($this->debug())
+ wfdebug(" PH: $s\n");
+ $ret = $this->executeStatement($stmt);
+ return $ret;
+ }
+
+ /**
+ * INSERT wrapper, inserts an array into a table
+ *
+ * $a may be a single associative array, or an array of these with numeric keys, for
+ * multi-row insert.
+ *
+ * Usually aborts on failure
+ * If errors are explicitly ignored, returns success
+ */
+ function insert( $table, $a, $fname = 'Database::insert', $options = array() ) {
+ # No rows to insert, easy just return now
+ if ( !count( $a ) ) {
+ return true;
+ }
+
+ $table = $this->tableName( $table );
+ if (!is_array($options))
+ $options = array($options);
+
+ $oldIgnore = false;
+ if (in_array('IGNORE', $options))
+ $oldIgnore = $this->ignoreErrors( true );
+
+ if ( isset( $a[0] ) && is_array( $a[0] ) ) {
+ $multi = true;
+ $keys = array_keys( $a[0] );
+ } else {
+ $multi = false;
+ $keys = array_keys( $a );
+ }
+
+ $sql = "INSERT INTO $table (" . implode( ',', $keys ) . ') VALUES (';
+ $return = '';
+ $first = true;
+ foreach ($a as $key => $value) {
+ if ($first)
+ $first = false;
+ else
+ $sql .= ", ";
+ if (is_object($value) && $value->isLOB()) {
+ $sql .= "EMPTY_BLOB()";
+ $return = "RETURNING $key INTO :bobj";
+ } else
+ $sql .= ":$key";
+ }
+ $sql .= ") $return";
+
+ if ($this->debug()) {
+ wfDebug("SQL: $sql\n");
+ }
+
+ if (($stmt = $this->parseStatement($sql)) === false) {
+ $this->reportQueryError($this->lastError(), $this->lastErrno(), $sql, $fname);
+ $this->ignoreErrors($oldIgnore);
+ return false;
+ }
+
+ /*
+ * If we're inserting multiple rows, parse the statement once and
+ * execute it for each set of values. Otherwise, convert it into an
+ * array and pretend.
+ */
+ if (!$multi)
+ $a = array($a);
+
+ foreach ($a as $key => $row) {
+ $blob = false;
+ $bdata = false;
+ $s = '';
+ foreach ($row as $k => $value) {
+ if (is_object($value) && $value->isLOB()) {
+ $blob = oci_new_descriptor($this->mConn, OCI_D_LOB);
+ $bdata = $value->data();
+ oci_bind_by_name($stmt, ":bobj", $blob, -1, OCI_B_BLOB);
+ } else
+ oci_bind_by_name($stmt, ":$k", $a[$key][$k], -1);
+ if ($this->debug())
+ $s .= " [$k] = {$row[$k]}";
+ }
+ if ($this->debug())
+ wfDebug(" PH: $s\n");
+ if (($s = $this->executeStatement($stmt)) === false) {
+ $this->reportQueryError($this->lastError(), $this->lastErrno(), $sql, $fname);
+ $this->ignoreErrors($oldIgnore);
+ return false;
+ }
+
+ if ($blob) {
+ $blob->save($bdata);
+ }
+ }
+ $this->ignoreErrors($oldIgnore);
+ return $this->mLastResult = $s;
+ }
+
+ function ping() {
+ return true;
+ }
+
+ function encodeBlob($b) {
+ return new OracleBlob($b);
+ }
+}
+
+?>
diff --git a/includes/DatabasePostgres.php b/includes/DatabasePostgres.php
new file mode 100644
index 000000000000..803c0e26fb86
--- /dev/null
+++ b/includes/DatabasePostgres.php
@@ -0,0 +1,912 @@
+<?php
+
+/**
+ * This is the Postgres database abstraction layer.
+ *
+ * As it includes more generic version for DB functions,
+ * than MySQL ones, some of them should be moved to parent
+ * Database class.
+ *
+ * @package MediaWiki
+ */
+
+class DatabasePostgres extends Database {
+ var $mInsertId = NULL;
+ var $mLastResult = NULL;
+
+ function DatabasePostgres($server = false, $user = false, $password = false, $dbName = false,
+ $failFunction = false, $flags = 0 )
+ {
+
+ global $wgOut;
+ # Can't get a reference if it hasn't been set yet
+ if ( !isset( $wgOut ) ) {
+ $wgOut = NULL;
+ }
+ $this->mOut =& $wgOut;
+ $this->mFailFunction = $failFunction;
+ $this->mCascadingDeletes = true;
+ $this->mCleanupTriggers = true;
+ $this->mStrictIPs = true;
+ $this->mFlags = $flags;
+ $this->open( $server, $user, $password, $dbName);
+
+ }
+
+ function realTimestamps() {
+ return true;
+ }
+
+ function implicitGroupby() {
+ return false;
+ }
+
+ static function newFromParams( $server = false, $user = false, $password = false, $dbName = false,
+ $failFunction = false, $flags = 0)
+ {
+ return new DatabasePostgres( $server, $user, $password, $dbName, $failFunction, $flags );
+ }
+
+ /**
+ * Usually aborts on failure
+ * If the failFunction is set to a non-zero integer, returns success
+ */
+ function open( $server, $user, $password, $dbName ) {
+ # Test for Postgres support, to avoid suppressed fatal error
+ if ( !function_exists( 'pg_connect' ) ) {
+ throw new DBConnectionError( $this, "Postgres functions missing, have you compiled PHP with the --with-pgsql option?\n (Note: if you recently installed PHP, you may need to restart your webserver and database)\n" );
+ }
+
+
+ global $wgDBport;
+
+ $this->close();
+ $this->mServer = $server;
+ $port = $wgDBport;
+ $this->mUser = $user;
+ $this->mPassword = $password;
+ $this->mDBname = $dbName;
+
+ $hstring="";
+ if ($server!=false && $server!="") {
+ $hstring="host=$server ";
+ }
+ if ($port!=false && $port!="") {
+ $hstring .= "port=$port ";
+ }
+
+ if (!strlen($user)) { ## e.g. the class is being loaded
+ return;
+ }
+
+ error_reporting( E_ALL );
+ @$this->mConn = pg_connect("$hstring dbname=$dbName user=$user password=$password");
+
+ if ( $this->mConn == false ) {
+ wfDebug( "DB connection error\n" );
+ wfDebug( "Server: $server, Database: $dbName, User: $user, Password: " . substr( $password, 0, 3 ) . "...\n" );
+ wfDebug( $this->lastError()."\n" );
+ return false;
+ }
+
+ $this->mOpened = true;
+ ## If this is the initial connection, setup the schema stuff and possibly create the user
+ if (defined('MEDIAWIKI_INSTALL')) {
+ global $wgDBname, $wgDBuser, $wgDBpassword, $wgDBsuperuser, $wgDBmwschema,
+ $wgDBts2schema;
+ print "OK</li>\n";
+
+ print "<li>Checking the version of Postgres...";
+ $version = pg_fetch_result($this->doQuery("SELECT version()"),0,0);
+ $thisver = array();
+ if (!preg_match('/PostgreSQL (\d+\.\d+)(\S+)/', $version, $thisver)) {
+ print "<b>FAILED</b> (could not determine the version)</li>\n";
+ dieout("</ul>");
+ }
+ $PGMINVER = "8.1";
+ if ($thisver[1] < $PGMINVER) {
+ print "<b>FAILED</b>. Required version is $PGMINVER. You have $thisver[1]$thisver[2]</li>\n";
+ dieout("</ul>");
+ }
+ print "version $thisver[1]$thisver[2] is OK.</li>\n";
+
+ $safeuser = $this->quote_ident($wgDBuser);
+ ## Are we connecting as a superuser for the first time?
+ if ($wgDBsuperuser) {
+ ## Are we really a superuser? Check out our rights
+ $SQL = "SELECT
+ CASE WHEN usesuper IS TRUE THEN
+ CASE WHEN usecreatedb IS TRUE THEN 3 ELSE 1 END
+ ELSE CASE WHEN usecreatedb IS TRUE THEN 2 ELSE 0 END
+ END AS rights
+ FROM pg_catalog.pg_user WHERE usename = " . $this->addQuotes($wgDBsuperuser);
+ $rows = $this->numRows($res = $this->doQuery($SQL));
+ if (!$rows) {
+ print "<li>ERROR: Could not read permissions for user \"$wgDBsuperuser\"</li>\n";
+ dieout('</ul>');
+ }
+ $perms = pg_fetch_result($res, 0, 0);
+
+ $SQL = "SELECT 1 FROM pg_catalog.pg_user WHERE usename = " . $this->addQuotes($wgDBuser);
+ $rows = $this->numRows($this->doQuery($SQL));
+ if ($rows) {
+ print "<li>User \"$wgDBuser\" already exists, skipping account creation.</li>";
+ }
+ else {
+ if ($perms != 1 and $perms != 3) {
+ print "<li>ERROR: the user \"$wgDBsuperuser\" cannot create other users. ";
+ print 'Please use a different Postgres user.</li>';
+ dieout('</ul>');
+ }
+ print "<li>Creating user <b>$wgDBuser</b>...";
+ $safepass = $this->addQuotes($wgDBpassword);
+ $SQL = "CREATE USER $safeuser NOCREATEDB PASSWORD $safepass";
+ $this->doQuery($SQL);
+ print "OK</li>\n";
+ }
+ ## User now exists, check out the database
+ if ($dbName != $wgDBname) {
+ $SQL = "SELECT 1 FROM pg_catalog.pg_database WHERE datname = " . $this->addQuotes($wgDBname);
+ $rows = $this->numRows($this->doQuery($SQL));
+ if ($rows) {
+ print "<li>Database \"$wgDBname\" already exists, skipping database creation.</li>";
+ }
+ else {
+ if ($perms < 2) {
+ print "<li>ERROR: the user \"$wgDBsuperuser\" cannot create databases. ";
+ print 'Please use a different Postgres user.</li>';
+ dieout('</ul>');
+ }
+ print "<li>Creating database <b>$wgDBname</b>...";
+ $safename = $this->quote_ident($wgDBname);
+ $SQL = "CREATE DATABASE $safename OWNER $safeuser ";
+ $this->doQuery($SQL);
+ print "OK</li>\n";
+ ## Hopefully tsearch2 and plpgsql are in template1...
+ }
+
+ ## Reconnect to check out tsearch2 rights for this user
+ print "<li>Connecting to \"$wgDBname\" as superuser \"$wgDBsuperuser\" to check rights...";
+ @$this->mConn = pg_connect("$hstring dbname=$wgDBname user=$user password=$password");
+ if ( $this->mConn == false ) {
+ print "<b>FAILED TO CONNECT!</b></li>";
+ dieout("</ul>");
+ }
+ print "OK</li>\n";
+ }
+
+ ## Tsearch2 checks
+ print "<li>Checking that tsearch2 is installed in the database \"$wgDBname\"...";
+ if (! $this->tableExists("pg_ts_cfg", $wgDBts2schema)) {
+ print "<b>FAILED</b>. tsearch2 must be installed in the database \"$wgDBname\".";
+ print "Please see <a href='http://www.devx.com/opensource/Article/21674/0/page/2'>this article</a>";
+ print " for instructions or ask on #postgresql on irc.freenode.net</li>\n";
+ dieout("</ul>");
+ }
+ print "OK</li>\n";
+ print "<li>Ensuring that user \"$wgDBuser\" has select rights on the tsearch2 tables...";
+ foreach (array('cfg','cfgmap','dict','parser') as $table) {
+ $SQL = "GRANT SELECT ON pg_ts_$table TO $safeuser";
+ $this->doQuery($SQL);
+ }
+ print "OK</li>\n";
+
+
+ ## Setup the schema for this user if needed
+ $result = $this->schemaExists($wgDBmwschema);
+ $safeschema = $this->quote_ident($wgDBmwschema);
+ if (!$result) {
+ print "<li>Creating schema <b>$wgDBmwschema</b> ...";
+ $result = $this->doQuery("CREATE SCHEMA $safeschema AUTHORIZATION $safeuser");
+ if (!$result) {
+ print "<b>FAILED</b>.</li>\n";
+ dieout("</ul>");
+ }
+ print "OK</li>\n";
+ }
+ else {
+ print "<li>Schema already exists, explicitly granting rights...\n";
+ $safeschema2 = $this->addQuotes($wgDBmwschema);
+ $SQL = "SELECT 'GRANT ALL ON '||pg_catalog.quote_ident(relname)||' TO $safeuser;'\n".
+ "FROM pg_catalog.pg_class p, pg_catalog.pg_namespace n\n".
+ "WHERE relnamespace = n.oid AND n.nspname = $safeschema2\n".
+ "AND p.relkind IN ('r','S','v')\n";
+ $SQL .= "UNION\n";
+ $SQL .= "SELECT 'GRANT ALL ON FUNCTION '||pg_catalog.quote_ident(proname)||'('||\n".
+ "pg_catalog.oidvectortypes(p.proargtypes)||') TO $safeuser;'\n".
+ "FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n\n".
+ "WHERE p.pronamespace = n.oid AND n.nspname = $safeschema2";
+ $res = $this->doQuery($SQL);
+ if (!$res) {
+ print "<b>FAILED</b>. Could not set rights for the user.</li>\n";
+ dieout("</ul>");
+ }
+ $this->doQuery("SET search_path = $safeschema");
+ $rows = $this->numRows($res);
+ while ($rows) {
+ $rows--;
+ $this->doQuery(pg_fetch_result($res, $rows, 0));
+ }
+ print "OK</li>";
+ }
+
+ $wgDBsuperuser = '';
+ return true; ## Reconnect as regular user
+ }
+
+ if (!defined('POSTGRES_SEARCHPATH')) {
+
+ ## Do we have the basic tsearch2 table?
+ print "<li>Checking for tsearch2 in the schema \"$wgDBts2schema\"...";
+ if (! $this->tableExists("pg_ts_dict", $wgDBts2schema)) {
+ print "<b>FAILED</b>. Make sure tsearch2 is installed. See <a href=";
+ print "'http://www.devx.com/opensource/Article/21674/0/page/2'>this article</a>";
+ print " for instructions.</li>\n";
+ dieout("</ul>");
+ }
+ print "OK</li>\n";
+
+ ## Does this user have the rights to the tsearch2 tables?
+ $ctype = pg_fetch_result($this->doQuery("SHOW lc_ctype"),0,0);
+ print "<li>Checking tsearch2 permissions...";
+ $SQL = "SELECT ts_name FROM $wgDBts2schema.pg_ts_cfg WHERE locale = '$ctype'";
+ $SQL .= " ORDER BY CASE WHEN ts_name <> 'default' THEN 1 ELSE 0 END";
+ error_reporting( 0 );
+ $res = $this->doQuery($SQL);
+ error_reporting( E_ALL );
+ if (!$res) {
+ print "<b>FAILED</b>. Make sure that the user \"$wgDBuser\" has SELECT access to the tsearch2 tables</li>\n";
+ dieout("</ul>");
+ }
+ print "OK</li>";
+
+ ## Will the current locale work? Can we force it to?
+ print "<li>Verifying tsearch2 locale with $ctype...";
+ $rows = $this->numRows($res);
+ $resetlocale = 0;
+ if (!$rows) {
+ print "<b>not found</b></li>\n";
+ print "<li>Attempting to set default tsearch2 locale to \"$ctype\"...";
+ $resetlocale = 1;
+ }
+ else {
+ $tsname = pg_fetch_result($res, 0, 0);
+ if ($tsname != 'default') {
+ print "<b>not set to default ($tsname)</b>";
+ print "<li>Attempting to change tsearch2 default locale to \"$ctype\"...";
+ $resetlocale = 1;
+ }
+ }
+ if ($resetlocale) {
+ $SQL = "UPDATE $wgDBts2schema.pg_ts_cfg SET locale = '$ctype' WHERE ts_name = 'default'";
+ $res = $this->doQuery($SQL);
+ if (!$res) {
+ print "<b>FAILED</b>. ";
+ print "Please make sure that the locale in pg_ts_cfg for \"default\" is set to \"ctype\"</li>\n";
+ dieout("</ul>");
+ }
+ print "OK</li>";
+ }
+
+ ## Final test: try out a simple tsearch2 query
+ $SQL = "SELECT $wgDBts2schema.to_tsvector('default','MediaWiki tsearch2 testing')";
+ $res = $this->doQuery($SQL);
+ if (!$res) {
+ print "<b>FAILED</b>. Specifically, \"$SQL\" did not work.</li>";
+ dieout("</ul>");
+ }
+ print "OK</li>";
+
+ ## Do we have plpgsql installed?
+ print "<li>Checking for Pl/Pgsql ...";
+ $SQL = "SELECT 1 FROM pg_catalog.pg_language WHERE lanname = 'plpgsql'";
+ $rows = $this->numRows($this->doQuery($SQL));
+ if ($rows < 1) {
+ // plpgsql is not installed, but if we have a pg_pltemplate table, we should be able to create it
+ print "not installed. Attempting to install Pl/Pgsql ...";
+ $SQL = "SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace) ".
+ "WHERE relname = 'pg_pltemplate' AND nspname='pg_catalog'";
+ $rows = $this->numRows($this->doQuery($SQL));
+ if ($rows >= 1) {
+ $result = $this->doQuery("CREATE LANGUAGE plpgsql");
+ if (!$result) {
+ print "<b>FAILED</b>. You need to install the language plpgsql in the database <tt>$wgDBname</tt></li>";
+ dieout("</ul>");
+ }
+ }
+ else {
+ print "<b>FAILED</b>. You need to install the language plpgsql in the database <tt>$wgDBname</tt></li>";
+ dieout("</ul>");
+ }
+ }
+ print "OK</li>\n";
+
+ ## Does the schema already exist? Who owns it?
+ $result = $this->schemaExists($wgDBmwschema);
+ if (!$result) {
+ print "<li>Creating schema <b>$wgDBmwschema</b> ...";
+ $result = $this->doQuery("CREATE SCHEMA $wgDBmwschema");
+ if (!$result) {
+ print "<b>FAILED</b>.</li>\n";
+ dieout("</ul>");
+ }
+ print "OK</li>\n";
+ }
+ else if ($result != $user) {
+ print "<li>Schema \"$wgDBmwschema\" exists but is not owned by \"$user\". Not ideal.</li>\n";
+ }
+ else {
+ print "<li>Schema \"$wgDBmwschema\" exists and is owned by \"$user\". Excellent.</li>\n";
+ }
+
+ ## Fix up the search paths if needed
+ print "<li>Setting the search path for user \"$user\" ...";
+ $path = $this->quote_ident($wgDBmwschema);
+ if ($wgDBts2schema !== $wgDBmwschema)
+ $path .= ", ". $this->quote_ident($wgDBts2schema);
+ if ($wgDBmwschema !== 'public' and $wgDBts2schema !== 'public')
+ $path .= ", public";
+ $SQL = "ALTER USER $safeuser SET search_path = $path";
+ $result = pg_query($this->mConn, $SQL);
+ if (!$result) {
+ print "<b>FAILED</b>.</li>\n";
+ dieout("</ul>");
+ }
+ print "OK</li>\n";
+ ## Set for the rest of this session
+ $SQL = "SET search_path = $path";
+ $result = pg_query($this->mConn, $SQL);
+ if (!$result) {
+ print "<li>Failed to set search_path</li>\n";
+ dieout("</ul>");
+ }
+ define( "POSTGRES_SEARCHPATH", $path );
+ }}
+
+ global $wgCommandLineMode;
+ ## If called from the command-line (e.g. importDump), only show errors
+ if ($wgCommandLineMode) {
+ $this->doQuery("SET client_min_messages = 'ERROR'");
+ }
+
+ return $this->mConn;
+ }
+
+ /**
+ * Closes a database connection, if it is open
+ * Returns success, true if already closed
+ */
+ function close() {
+ $this->mOpened = false;
+ if ( $this->mConn ) {
+ return pg_close( $this->mConn );
+ } else {
+ return true;
+ }
+ }
+
+ function doQuery( $sql ) {
+ return $this->mLastResult=pg_query( $this->mConn , $sql);
+ }
+
+ function queryIgnore( $sql, $fname = '' ) {
+ return $this->query( $sql, $fname, true );
+ }
+
+ function freeResult( $res ) {
+ if ( !@pg_free_result( $res ) ) {
+ throw new DBUnexpectedError($this, "Unable to free Postgres result\n" );
+ }
+ }
+
+ function fetchObject( $res ) {
+ @$row = pg_fetch_object( $res );
+ # FIXME: HACK HACK HACK HACK debug
+
+ # TODO:
+ # hashar : not sure if the following test really trigger if the object
+ # fetching failled.
+ if( pg_last_error($this->mConn) ) {
+ throw new DBUnexpectedError($this, 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
+ }
+ return $row;
+ }
+
+ function fetchRow( $res ) {
+ @$row = pg_fetch_array( $res );
+ if( pg_last_error($this->mConn) ) {
+ throw new DBUnexpectedError($this, 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
+ }
+ return $row;
+ }
+
+ function numRows( $res ) {
+ @$n = pg_num_rows( $res );
+ if( pg_last_error($this->mConn) ) {
+ throw new DBUnexpectedError($this, 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
+ }
+ return $n;
+ }
+ function numFields( $res ) { return pg_num_fields( $res ); }
+ function fieldName( $res, $n ) { return pg_field_name( $res, $n ); }
+
+ /**
+ * This must be called after nextSequenceVal
+ */
+ function insertId() {
+ return $this->mInsertId;
+ }
+
+ function dataSeek( $res, $row ) { return pg_result_seek( $res, $row ); }
+ function lastError() {
+ if ( $this->mConn ) {
+ return pg_last_error();
+ }
+ else {
+ return "No database connection";
+ }
+ }
+ function lastErrno() {
+ return pg_last_error() ? 1 : 0;
+ }
+
+ function affectedRows() {
+ return pg_affected_rows( $this->mLastResult );
+ }
+
+ /**
+ * Returns information about an index
+ * If errors are explicitly ignored, returns NULL on failure
+ */
+ function indexInfo( $table, $index, $fname = 'Database::indexExists' ) {
+ $sql = "SELECT indexname FROM pg_indexes WHERE tablename='$table'";
+ $res = $this->query( $sql, $fname );
+ if ( !$res ) {
+ return NULL;
+ }
+
+ while ( $row = $this->fetchObject( $res ) ) {
+ if ( $row->indexname == $index ) {
+ return $row;
+
+ // BUG: !!!! This code needs to be synced up with database.php
+
+ }
+ }
+ return false;
+ }
+
+ function indexUnique ($table, $index, $fname = 'Database::indexUnique' ) {
+ $sql = "SELECT indexname FROM pg_indexes WHERE tablename='{$table}'".
+ " AND indexdef LIKE 'CREATE UNIQUE%({$index})'";
+ $res = $this->query( $sql, $fname );
+ if ( !$res )
+ return NULL;
+ while ($row = $this->fetchObject( $res ))
+ return true;
+ return false;
+
+ }
+
+ function insert( $table, $a, $fname = 'Database::insert', $options = array() ) {
+ # Postgres doesn't support options
+ # We have a go at faking one of them
+ # TODO: DELAYED, LOW_PRIORITY
+
+ if ( !is_array($options))
+ $options = array($options);
+
+ if ( in_array( 'IGNORE', $options ) )
+ $oldIgnore = $this->ignoreErrors( true );
+
+ # IGNORE is performed using single-row inserts, ignoring errors in each
+ # FIXME: need some way to distiguish between key collision and other types of error
+ $oldIgnore = $this->ignoreErrors( true );
+ if ( !is_array( reset( $a ) ) ) {
+ $a = array( $a );
+ }
+ foreach ( $a as $row ) {
+ parent::insert( $table, $row, $fname, array() );
+ }
+ $this->ignoreErrors( $oldIgnore );
+ $retVal = true;
+
+ if ( in_array( 'IGNORE', $options ) )
+ $this->ignoreErrors( $oldIgnore );
+
+ return $retVal;
+ }
+
+ function tableName( $name ) {
+ # Replace reserved words with better ones
+ switch( $name ) {
+ case 'user':
+ return 'mwuser';
+ case 'text':
+ return 'pagecontent';
+ default:
+ return $name;
+ }
+ }
+
+ /**
+ * Return the next in a sequence, save the value for retrieval via insertId()
+ */
+ function nextSequenceValue( $seqName ) {
+ $safeseq = preg_replace( "/'/", "''", $seqName );
+ $res = $this->query( "SELECT nextval('$safeseq')" );
+ $row = $this->fetchRow( $res );
+ $this->mInsertId = $row[0];
+ $this->freeResult( $res );
+ return $this->mInsertId;
+ }
+
+ /**
+ * Postgres does not have a "USE INDEX" clause, so return an empty string
+ */
+ function useIndexClause( $index ) {
+ return '';
+ }
+
+ # REPLACE query wrapper
+ # Postgres simulates this with a DELETE followed by INSERT
+ # $row is the row to insert, an associative array
+ # $uniqueIndexes is an array of indexes. Each element may be either a
+ # field name or an array of field names
+ #
+ # It may be more efficient to leave off unique indexes which are unlikely to collide.
+ # However if you do this, you run the risk of encountering errors which wouldn't have
+ # occurred in MySQL
+ function replace( $table, $uniqueIndexes, $rows, $fname = 'Database::replace' ) {
+ $table = $this->tableName( $table );
+
+ if (count($rows)==0) {
+ return;
+ }
+
+ # Single row case
+ if ( !is_array( reset( $rows ) ) ) {
+ $rows = array( $rows );
+ }
+
+ foreach( $rows as $row ) {
+ # Delete rows which collide
+ if ( $uniqueIndexes ) {
+ $sql = "DELETE FROM $table WHERE ";
+ $first = true;
+ foreach ( $uniqueIndexes as $index ) {
+ if ( $first ) {
+ $first = false;
+ $sql .= "(";
+ } else {
+ $sql .= ') OR (';
+ }
+ if ( is_array( $index ) ) {
+ $first2 = true;
+ foreach ( $index as $col ) {
+ if ( $first2 ) {
+ $first2 = false;
+ } else {
+ $sql .= ' AND ';
+ }
+ $sql .= $col.'=' . $this->addQuotes( $row[$col] );
+ }
+ } else {
+ $sql .= $index.'=' . $this->addQuotes( $row[$index] );
+ }
+ }
+ $sql .= ')';
+ $this->query( $sql, $fname );
+ }
+
+ # Now insert the row
+ $sql = "INSERT INTO $table (" . $this->makeList( array_keys( $row ), LIST_NAMES ) .') VALUES (' .
+ $this->makeList( $row, LIST_COMMA ) . ')';
+ $this->query( $sql, $fname );
+ }
+ }
+
+ # DELETE where the condition is a join
+ function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin" ) {
+ if ( !$conds ) {
+ throw new DBUnexpectedError($this, 'Database::deleteJoin() called with empty $conds' );
+ }
+
+ $delTable = $this->tableName( $delTable );
+ $joinTable = $this->tableName( $joinTable );
+ $sql = "DELETE FROM $delTable WHERE $delVar IN (SELECT $joinVar FROM $joinTable ";
+ if ( $conds != '*' ) {
+ $sql .= 'WHERE ' . $this->makeList( $conds, LIST_AND );
+ }
+ $sql .= ')';
+
+ $this->query( $sql, $fname );
+ }
+
+ # Returns the size of a text field, or -1 for "unlimited"
+ function textFieldSize( $table, $field ) {
+ $table = $this->tableName( $table );
+ $sql = "SELECT t.typname as ftype,a.atttypmod as size
+ FROM pg_class c, pg_attribute a, pg_type t
+ WHERE relname='$table' AND a.attrelid=c.oid AND
+ a.atttypid=t.oid and a.attname='$field'";
+ $res =$this->query($sql);
+ $row=$this->fetchObject($res);
+ if ($row->ftype=="varchar") {
+ $size=$row->size-4;
+ } else {
+ $size=$row->size;
+ }
+ $this->freeResult( $res );
+ return $size;
+ }
+
+ function lowPriorityOption() {
+ return '';
+ }
+
+ function limitResult($sql, $limit,$offset) {
+ return "$sql LIMIT $limit ".(is_numeric($offset)?" OFFSET {$offset} ":"");
+ }
+
+ /**
+ * Returns an SQL expression for a simple conditional.
+ * Uses CASE on Postgres
+ *
+ * @param string $cond SQL expression which will result in a boolean value
+ * @param string $trueVal SQL expression to return if true
+ * @param string $falseVal SQL expression to return if false
+ * @return string SQL fragment
+ */
+ function conditional( $cond, $trueVal, $falseVal ) {
+ return " (CASE WHEN $cond THEN $trueVal ELSE $falseVal END) ";
+ }
+
+ function wasDeadlock() {
+ return $this->lastErrno() == '40P01';
+ }
+
+ function timestamp( $ts=0 ) {
+ return wfTimestamp(TS_POSTGRES,$ts);
+ }
+
+ /**
+ * Return aggregated value function call
+ */
+ function aggregateValue ($valuedata,$valuename='value') {
+ return $valuedata;
+ }
+
+
+ function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
+ # Ignore errors during error handling to avoid infinite recursion
+ $ignore = $this->ignoreErrors( true );
+ ++$this->mErrorCount;
+
+ if ($ignore || $tempIgnore) {
+ wfDebug("SQL ERROR (ignored): $error\n");
+ $this->ignoreErrors( $ignore );
+ }
+ else {
+ $message = "A database error has occurred\n" .
+ "Query: $sql\n" .
+ "Function: $fname\n" .
+ "Error: $errno $error\n";
+ throw new DBUnexpectedError($this, $message);
+ }
+ }
+
+ /**
+ * @return string wikitext of a link to the server software's web site
+ */
+ function getSoftwareLink() {
+ return "[http://www.postgresql.org/ PostgreSQL]";
+ }
+
+ /**
+ * @return string Version information from the database
+ */
+ function getServerVersion() {
+ $res = $this->query( "SELECT version()" );
+ $row = $this->fetchRow( $res );
+ $version = $row[0];
+ $this->freeResult( $res );
+ return $version;
+ }
+
+
+ /**
+ * Query whether a given table exists (in the given schema, or the default mw one if not given)
+ */
+ function tableExists( $table, $schema = false ) {
+ global $wgDBmwschema;
+ if (! $schema )
+ $schema = $wgDBmwschema;
+ $etable = preg_replace("/'/", "''", $table);
+ $eschema = preg_replace("/'/", "''", $schema);
+ $SQL = "SELECT 1 FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n "
+ . "WHERE c.relnamespace = n.oid AND c.relname = '$etable' AND n.nspname = '$eschema' "
+ . "AND c.relkind IN ('r','v')";
+ $res = $this->query( $SQL );
+ $count = $res ? pg_num_rows($res) : 0;
+ if ($res)
+ $this->freeResult( $res );
+ return $count;
+ }
+
+
+ /**
+ * Query whether a given schema exists. Returns the name of the owner
+ */
+ function schemaExists( $schema ) {
+ $eschema = preg_replace("/'/", "''", $schema);
+ $SQL = "SELECT rolname FROM pg_catalog.pg_namespace n, pg_catalog.pg_roles r "
+ ."WHERE n.nspowner=r.oid AND n.nspname = '$eschema'";
+ $res = $this->query( $SQL );
+ $owner = $res ? pg_num_rows($res) ? pg_fetch_result($res, 0, 0) : false : false;
+ if ($res)
+ $this->freeResult($res);
+ return $owner;
+ }
+
+ /**
+ * Query whether a given column exists in the mediawiki schema
+ */
+ function fieldExists( $table, $field ) {
+ global $wgDBmwschema;
+ $etable = preg_replace("/'/", "''", $table);
+ $eschema = preg_replace("/'/", "''", $wgDBmwschema);
+ $ecol = preg_replace("/'/", "''", $field);
+ $SQL = "SELECT 1 FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n, pg_catalog.pg_attribute a "
+ . "WHERE c.relnamespace = n.oid AND c.relname = '$etable' AND n.nspname = '$eschema' "
+ . "AND a.attrelid = c.oid AND a.attname = '$ecol'";
+ $res = $this->query( $SQL );
+ $count = $res ? pg_num_rows($res) : 0;
+ if ($res)
+ $this->freeResult( $res );
+ return $count;
+ }
+
+ function fieldInfo( $table, $field ) {
+ $res = $this->query( "SELECT $field FROM $table LIMIT 1" );
+ $type = pg_field_type( $res, 0 );
+ return $type;
+ }
+
+ function begin( $fname = 'DatabasePostgrs::begin' ) {
+ $this->query( 'BEGIN', $fname );
+ $this->mTrxLevel = 1;
+ }
+ function immediateCommit( $fname = 'DatabasePostgres::immediateCommit' ) {
+ return true;
+ }
+ function commit( $fname = 'DatabasePostgres::commit' ) {
+ $this->query( 'COMMIT', $fname );
+ $this->mTrxLevel = 0;
+ }
+
+ /* Not even sure why this is used in the main codebase... */
+ function limitResultForUpdate($sql, $num) {
+ return $sql;
+ }
+
+ function setup_database() {
+ global $wgVersion, $wgDBmwschema, $wgDBts2schema, $wgDBport;
+
+ dbsource( "../maintenance/postgres/tables.sql", $this);
+
+ ## Update version information
+ $mwv = $this->addQuotes($wgVersion);
+ $pgv = $this->addQuotes($this->getServerVersion());
+ $pgu = $this->addQuotes($this->mUser);
+ $mws = $this->addQuotes($wgDBmwschema);
+ $tss = $this->addQuotes($wgDBts2schema);
+ $pgp = $this->addQuotes($wgDBport);
+ $dbn = $this->addQuotes($this->mDBname);
+ $ctype = pg_fetch_result($this->doQuery("SHOW lc_ctype"),0,0);
+
+ $SQL = "UPDATE mediawiki_version SET mw_version=$mwv, pg_version=$pgv, pg_user=$pgu, ".
+ "mw_schema = $mws, ts2_schema = $tss, pg_port=$pgp, pg_dbname=$dbn, ".
+ "ctype = '$ctype' ".
+ "WHERE type = 'Creation'";
+ $this->query($SQL);
+
+ ## Avoid the non-standard "REPLACE INTO" syntax
+ $f = fopen( "../maintenance/interwiki.sql", 'r' );
+ if ($f == false ) {
+ dieout( "<li>Could not find the interwiki.sql file");
+ }
+ ## We simply assume it is already empty as we have just created it
+ $SQL = "INSERT INTO interwiki(iw_prefix,iw_url,iw_local) VALUES ";
+ while ( ! feof( $f ) ) {
+ $line = fgets($f,1024);
+ $matches = array();
+ if (!preg_match('/^\s*(\(.+?),(\d)\)/', $line, $matches)) {
+ continue;
+ }
+ $this->query("$SQL $matches[1],$matches[2])");
+ }
+ print " (table interwiki successfully populated)...\n";
+ }
+
+ function encodeBlob($b) {
+ return array('bytea',pg_escape_bytea($b));
+ }
+ function decodeBlob($b) {
+ return pg_unescape_bytea( $b );
+ }
+
+ function strencode( $s ) { ## Should not be called by us
+ return pg_escape_string( $s );
+ }
+
+ function addQuotes( $s ) {
+ if ( is_null( $s ) ) {
+ return 'NULL';
+ } else if (is_array( $s )) { ## Assume it is bytea data
+ return "E'$s[1]'";
+ }
+ return "'" . pg_escape_string($s) . "'";
+ // Unreachable: return "E'" . pg_escape_string($s) . "'";
+ }
+
+ function quote_ident( $s ) {
+ return '"' . preg_replace( '/"/', '""', $s) . '"';
+ }
+
+ /* For now, does nothing */
+ function selectDB( $db ) {
+ return true;
+ }
+
+ /**
+ * Returns an optional USE INDEX clause to go after the table, and a
+ * string to go at the end of the query
+ *
+ * @private
+ *
+ * @param array $options an associative array of options to be turned into
+ * an SQL query, valid keys are listed in the function.
+ * @return array
+ */
+ function makeSelectOptions( $options ) {
+ $tailOpts = '';
+ $startOpts = '';
+
+ $noKeyOptions = array();
+ foreach ( $options as $key => $option ) {
+ if ( is_numeric( $key ) ) {
+ $noKeyOptions[$option] = true;
+ }
+ }
+
+ if ( isset( $options['GROUP BY'] ) ) $tailOpts .= " GROUP BY {$options['GROUP BY']}";
+ if ( isset( $options['ORDER BY'] ) ) $tailOpts .= " ORDER BY {$options['ORDER BY']}";
+
+ if (isset($options['LIMIT'])) {
+ $tailOpts .= $this->limitResult('', $options['LIMIT'],
+ isset($options['OFFSET']) ? $options['OFFSET'] : false);
+ }
+
+ if ( isset( $noKeyOptions['FOR UPDATE'] ) ) $tailOpts .= ' FOR UPDATE';
+ if ( isset( $noKeyOptions['LOCK IN SHARE MODE'] ) ) $tailOpts .= ' LOCK IN SHARE MODE';
+ if ( isset( $noKeyOptions['DISTINCT'] ) && isset( $noKeyOptions['DISTINCTROW'] ) ) $startOpts .= 'DISTINCT';
+
+ if ( isset( $options['USE INDEX'] ) && ! is_array( $options['USE INDEX'] ) ) {
+ $useIndex = $this->useIndexClause( $options['USE INDEX'] );
+ } else {
+ $useIndex = '';
+ }
+
+ return array( $startOpts, $useIndex, $tailOpts );
+ }
+
+ function ping() {
+ wfDebug( "Function ping() not written for DatabasePostgres.php yet");
+ return true;
+ }
+
+
+} // end DatabasePostgres class
+
+?>
diff --git a/includes/DateFormatter.php b/includes/DateFormatter.php
new file mode 100644
index 000000000000..c795618a7743
--- /dev/null
+++ b/includes/DateFormatter.php
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Date formatter, recognises dates in plain text and formats them accoding to user preferences.
+ *
+ * @package MediaWiki
+ * @subpackage Parser
+ */
+
+/**
+ * @todo preferences, OutputPage
+ * @package MediaWiki
+ * @subpackage Parser
+ */
+class DateFormatter
+{
+ var $mSource, $mTarget;
+ var $monthNames = '', $rxDM, $rxMD, $rxDMY, $rxYDM, $rxMDY, $rxYMD;
+
+ var $regexes, $pDays, $pMonths, $pYears;
+ var $rules, $xMonths, $preferences;
+
+ const ALL = -1;
+ const NONE = 0;
+ const MDY = 1;
+ const DMY = 2;
+ const YMD = 3;
+ const ISO1 = 4;
+ const LASTPREF = 4;
+ const ISO2 = 5;
+ const YDM = 6;
+ const DM = 7;
+ const MD = 8;
+ const LAST = 8;
+
+ /**
+ * @todo document
+ */
+ function DateFormatter() {
+ global $wgContLang;
+
+ $this->monthNames = $this->getMonthRegex();
+ for ( $i=1; $i<=12; $i++ ) {
+ $this->xMonths[$wgContLang->lc( $wgContLang->getMonthName( $i ) )] = $i;
+ $this->xMonths[$wgContLang->lc( $wgContLang->getMonthAbbreviation( $i ) )] = $i;
+ }
+
+ $this->regexTrail = '(?![a-z])/iu';
+
+ # Partial regular expressions
+ $this->prxDM = '\[\[(\d{1,2})[ _](' . $this->monthNames . ')]]';
+ $this->prxMD = '\[\[(' . $this->monthNames . ')[ _](\d{1,2})]]';
+ $this->prxY = '\[\[(\d{1,4}([ _]BC|))]]';
+ $this->prxISO1 = '\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})]]';
+ $this->prxISO2 = '\[\[(-?\d{4})-(\d{2})-(\d{2})]]';
+
+ # Real regular expressions
+ $this->regexes[self::DMY] = "/{$this->prxDM} *,? *{$this->prxY}{$this->regexTrail}";
+ $this->regexes[self::YDM] = "/{$this->prxY} *,? *{$this->prxDM}{$this->regexTrail}";
+ $this->regexes[self::MDY] = "/{$this->prxMD} *,? *{$this->prxY}{$this->regexTrail}";
+ $this->regexes[self::YMD] = "/{$this->prxY} *,? *{$this->prxMD}{$this->regexTrail}";
+ $this->regexes[self::DM] = "/{$this->prxDM}{$this->regexTrail}";
+ $this->regexes[self::MD] = "/{$this->prxMD}{$this->regexTrail}";
+ $this->regexes[self::ISO1] = "/{$this->prxISO1}{$this->regexTrail}";
+ $this->regexes[self::ISO2] = "/{$this->prxISO2}{$this->regexTrail}";
+
+ # Extraction keys
+ # See the comments in replace() for the meaning of the letters
+ $this->keys[self::DMY] = 'jFY';
+ $this->keys[self::YDM] = 'Y jF';
+ $this->keys[self::MDY] = 'FjY';
+ $this->keys[self::YMD] = 'Y Fj';
+ $this->keys[self::DM] = 'jF';
+ $this->keys[self::MD] = 'Fj';
+ $this->keys[self::ISO1] = 'ymd'; # y means ISO year
+ $this->keys[self::ISO2] = 'ymd';
+
+ # Target date formats
+ $this->targets[self::DMY] = '[[F j|j F]] [[Y]]';
+ $this->targets[self::YDM] = '[[Y]], [[F j|j F]]';
+ $this->targets[self::MDY] = '[[F j]], [[Y]]';
+ $this->targets[self::YMD] = '[[Y]] [[F j]]';
+ $this->targets[self::DM] = '[[F j|j F]]';
+ $this->targets[self::MD] = '[[F j]]';
+ $this->targets[self::ISO1] = '[[Y|y]]-[[F j|m-d]]';
+ $this->targets[self::ISO2] = '[[y-m-d]]';
+
+ # Rules
+ # pref source target
+ $this->rules[self::DMY][self::MD] = self::DM;
+ $this->rules[self::ALL][self::MD] = self::MD;
+ $this->rules[self::MDY][self::DM] = self::MD;
+ $this->rules[self::ALL][self::DM] = self::DM;
+ $this->rules[self::NONE][self::ISO2] = self::ISO1;
+
+ $this->preferences = array(
+ 'default' => self::NONE,
+ 'dmy' => self::DMY,
+ 'mdy' => self::MDY,
+ 'ymd' => self::YMD,
+ 'ISO 8601' => self::ISO1,
+ );
+ }
+
+ /**
+ * @static
+ */
+ function &getInstance() {
+ global $wgMemc;
+ static $dateFormatter = false;
+ if ( !$dateFormatter ) {
+ $dateFormatter = $wgMemc->get( wfMemcKey( 'dateformatter' ) );
+ if ( !$dateFormatter ) {
+ $dateFormatter = new DateFormatter;
+ $wgMemc->set( wfMemcKey( 'dateformatter' ), $dateFormatter, 3600 );
+ }
+ }
+ return $dateFormatter;
+ }
+
+ /**
+ * @param string $preference User preference
+ * @param string $text Text to reformat
+ */
+ function reformat( $preference, $text ) {
+ if ( isset( $this->preferences[$preference] ) ) {
+ $preference = $this->preferences[$preference];
+ } else {
+ $preference = self::NONE;
+ }
+ for ( $i=1; $i<=self::LAST; $i++ ) {
+ $this->mSource = $i;
+ if ( isset ( $this->rules[$preference][$i] ) ) {
+ # Specific rules
+ $this->mTarget = $this->rules[$preference][$i];
+ } elseif ( isset ( $this->rules[self::ALL][$i] ) ) {
+ # General rules
+ $this->mTarget = $this->rules[self::ALL][$i];
+ } elseif ( $preference ) {
+ # User preference
+ $this->mTarget = $preference;
+ } else {
+ # Default
+ $this->mTarget = $i;
+ }
+ $text = preg_replace_callback( $this->regexes[$i], array( &$this, 'replace' ), $text );
+ }
+ return $text;
+ }
+
+ /**
+ * @param $matches
+ */
+ function replace( $matches ) {
+ # Extract information from $matches
+ $bits = array();
+ $key = $this->keys[$this->mSource];
+ for ( $p=0; $p < strlen($key); $p++ ) {
+ if ( $key{$p} != ' ' ) {
+ $bits[$key{$p}] = $matches[$p+1];
+ }
+ }
+
+ $format = $this->targets[$this->mTarget];
+
+ # Construct new date
+ $text = '';
+ $fail = false;
+
+ for ( $p=0; $p < strlen( $format ); $p++ ) {
+ $char = $format{$p};
+ switch ( $char ) {
+ case 'd': # ISO day of month
+ if ( !isset($bits['d']) ) {
+ $text .= sprintf( '%02d', $bits['j'] );
+ } else {
+ $text .= $bits['d'];
+ }
+ break;
+ case 'm': # ISO month
+ if ( !isset($bits['m']) ) {
+ $m = $this->makeIsoMonth( $bits['F'] );
+ if ( !$m || $m == '00' ) {
+ $fail = true;
+ } else {
+ $text .= $m;
+ }
+ } else {
+ $text .= $bits['m'];
+ }
+ break;
+ case 'y': # ISO year
+ if ( !isset( $bits['y'] ) ) {
+ $text .= $this->makeIsoYear( $bits['Y'] );
+ } else {
+ $text .= $bits['y'];
+ }
+ break;
+ case 'j': # ordinary day of month
+ if ( !isset($bits['j']) ) {
+ $text .= intval( $bits['d'] );
+ } else {
+ $text .= $bits['j'];
+ }
+ break;
+ case 'F': # long month
+ if ( !isset( $bits['F'] ) ) {
+ $m = intval($bits['m']);
+ if ( $m > 12 || $m < 1 ) {
+ $fail = true;
+ } else {
+ global $wgContLang;
+ $text .= $wgContLang->getMonthName( $m );
+ }
+ } else {
+ $text .= ucfirst( $bits['F'] );
+ }
+ break;
+ case 'Y': # ordinary (optional BC) year
+ if ( !isset( $bits['Y'] ) ) {
+ $text .= $this->makeNormalYear( $bits['y'] );
+ } else {
+ $text .= $bits['Y'];
+ }
+ break;
+ default:
+ $text .= $char;
+ }
+ }
+ if ( $fail ) {
+ $text = $matches[0];
+ }
+ return $text;
+ }
+
+ /**
+ * @todo document
+ */
+ function getMonthRegex() {
+ global $wgContLang;
+ $names = array();
+ for( $i = 1; $i <= 12; $i++ ) {
+ $names[] = $wgContLang->getMonthName( $i );
+ $names[] = $wgContLang->getMonthAbbreviation( $i );
+ }
+ return implode( '|', $names );
+ }
+
+ /**
+ * Makes an ISO month, e.g. 02, from a month name
+ * @param $monthName String: month name
+ * @return string ISO month name
+ */
+ function makeIsoMonth( $monthName ) {
+ global $wgContLang;
+
+ $n = $this->xMonths[$wgContLang->lc( $monthName )];
+ return sprintf( '%02d', $n );
+ }
+
+ /**
+ * @todo document
+ * @param $year String: Year name
+ * @return string ISO year name
+ */
+ function makeIsoYear( $year ) {
+ # Assumes the year is in a nice format, as enforced by the regex
+ if ( substr( $year, -2 ) == 'BC' ) {
+ $num = intval(substr( $year, 0, -3 )) - 1;
+ # PHP bug note: sprintf( "%04d", -1 ) fails poorly
+ $text = sprintf( '-%04d', $num );
+
+ } else {
+ $text = sprintf( '%04d', $year );
+ }
+ return $text;
+ }
+
+ /**
+ * @todo document
+ */
+ function makeNormalYear( $iso ) {
+ if ( $iso{0} == '-' ) {
+ $text = (intval( substr( $iso, 1 ) ) + 1) . ' BC';
+ } else {
+ $text = intval( $iso );
+ }
+ return $text;
+ }
+}
+
+?>
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
new file mode 100644
index 000000000000..7550ec1f1015
--- /dev/null
+++ b/includes/DefaultSettings.php
@@ -0,0 +1,2419 @@
+<?php
+/**
+ *
+ * NEVER EDIT THIS FILE
+ *
+ *
+ * To customize your installation, edit "LocalSettings.php". If you make
+ * changes here, they will be lost on next upgrade of MediaWiki!
+ *
+ * Note that since all these string interpolations are expanded
+ * before LocalSettings is included, if you localize something
+ * like $wgScriptPath, you must also localize everything that
+ * depends on it.
+ *
+ * Documentation is in the source and on:
+ * http://www.mediawiki.org/wiki/Help:Configuration_settings
+ *
+ * @package MediaWiki
+ */
+
+# This is not a valid entry point, perform no further processing unless MEDIAWIKI is defined
+if( !defined( 'MEDIAWIKI' ) ) {
+ echo "This file is part of MediaWiki and is not a valid entry point\n";
+ die( 1 );
+}
+
+/**
+ * Create a site configuration object
+ * Not used for much in a default install
+ */
+require_once( 'includes/SiteConfiguration.php' );
+$wgConf = new SiteConfiguration;
+
+/** MediaWiki version number */
+$wgVersion = '1.9.6';
+
+/** Name of the site. It must be changed in LocalSettings.php */
+$wgSitename = 'MediaWiki';
+
+/**
+ * Name of the project namespace. If left set to false, $wgSitename will be
+ * used instead.
+ */
+$wgMetaNamespace = false;
+
+/**
+ * Name of the project talk namespace. If left set to false, a name derived
+ * from the name of the project namespace will be used.
+ */
+$wgMetaNamespaceTalk = false;
+
+
+/** URL of the server. It will be automatically built including https mode */
+$wgServer = '';
+
+if( isset( $_SERVER['SERVER_NAME'] ) ) {
+ $wgServerName = $_SERVER['SERVER_NAME'];
+} elseif( isset( $_SERVER['HOSTNAME'] ) ) {
+ $wgServerName = $_SERVER['HOSTNAME'];
+} elseif( isset( $_SERVER['HTTP_HOST'] ) ) {
+ $wgServerName = $_SERVER['HTTP_HOST'];
+} elseif( isset( $_SERVER['SERVER_ADDR'] ) ) {
+ $wgServerName = $_SERVER['SERVER_ADDR'];
+} else {
+ $wgServerName = 'localhost';
+}
+
+# check if server use https:
+$wgProto = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
+
+$wgServer = $wgProto.'://' . $wgServerName;
+# If the port is a non-standard one, add it to the URL
+if( isset( $_SERVER['SERVER_PORT'] )
+ && !strpos( $wgServerName, ':' )
+ && ( ( $wgProto == 'http' && $_SERVER['SERVER_PORT'] != 80 )
+ || ( $wgProto == 'https' && $_SERVER['SERVER_PORT'] != 443 ) ) ) {
+
+ $wgServer .= ":" . $_SERVER['SERVER_PORT'];
+}
+
+
+/**
+ * The path we should point to.
+ * It might be a virtual path in case with use apache mod_rewrite for example
+ *
+ * This *needs* to be set correctly.
+ *
+ * Other paths will be set to defaults based on it unless they are directly
+ * set in LocalSettings.php
+ */
+$wgScriptPath = '/wiki';
+
+/**
+ * Whether to support URLs like index.php/Page_title
+ * These often break when PHP is set up in CGI mode.
+ * PATH_INFO *may* be correct if cgi.fix_pathinfo is
+ * set, but then again it may not; lighttpd converts
+ * incoming path data to lowercase on systems with
+ * case-insensitive filesystems, and there have been
+ * reports of problems on Apache as well.
+ *
+ * To be safe we'll continue to keep it off by default.
+ *
+ * Override this to false if $_SERVER['PATH_INFO']
+ * contains unexpectedly incorrect garbage, or to
+ * true if it is really correct.
+ *
+ * The default $wgArticlePath will be set based on
+ * this value at runtime, but if you have customized
+ * it, having this incorrectly set to true can
+ * cause redirect loops when "pretty URLs" are used.
+ *
+ */
+$wgUsePathInfo =
+ ( strpos( php_sapi_name(), 'cgi' ) === false ) &&
+ ( strpos( php_sapi_name(), 'apache2filter' ) === false ) &&
+ ( strpos( php_sapi_name(), 'isapi' ) === false );
+
+
+/**#@+
+ * Script users will request to get articles
+ * ATTN: Old installations used wiki.phtml and redirect.phtml -
+ * make sure that LocalSettings.php is correctly set!
+ *
+ * Will be set based on $wgScriptPath in Setup.php if not overridden
+ * in LocalSettings.php. Generally you should not need to change this
+ * unless you don't like seeing "index.php".
+ */
+$wgScript = false; /// defaults to "{$wgScriptPath}/index.php"
+$wgRedirectScript = false; /// defaults to "{$wgScriptPath}/redirect.php"
+/**#@-*/
+
+
+/**#@+
+ * These various web and file path variables are set to their defaults
+ * in Setup.php if they are not explicitly set from LocalSettings.php.
+ * If you do override them, be sure to set them all!
+ *
+ * These will relatively rarely need to be set manually, unless you are
+ * splitting style sheets or images outside the main document root.
+ *
+ * @global string
+ */
+/**
+ * style path as seen by users
+ */
+$wgStylePath = false; /// defaults to "{$wgScriptPath}/skins"
+/**
+ * filesystem stylesheets directory
+ */
+$wgStyleDirectory = false; /// defaults to "{$IP}/skins"
+$wgStyleSheetPath = &$wgStylePath;
+$wgArticlePath = false; /// default to "{$wgScript}/$1" or "{$wgScript}?title=$1", depending on $wgUsePathInfo
+$wgVariantArticlePath = false;
+$wgUploadPath = false; /// defaults to "{$wgScriptPath}/images"
+$wgUploadDirectory = false; /// defaults to "{$IP}/images"
+$wgHashedUploadDirectory = true;
+$wgLogo = false; /// defaults to "{$wgStylePath}/common/images/wiki.png"
+$wgFavicon = '/favicon.ico';
+$wgMathPath = false; /// defaults to "{$wgUploadPath}/math"
+$wgMathDirectory = false; /// defaults to "{$wgUploadDirectory}/math"
+$wgTmpDirectory = false; /// defaults to "{$wgUploadDirectory}/tmp"
+$wgUploadBaseUrl = "";
+/**#@-*/
+
+
+/**
+ * By default deleted files are simply discarded; to save them and
+ * make it possible to undelete images, create a directory which
+ * is writable to the web server but is not exposed to the internet.
+ *
+ * Set $wgSaveDeletedFiles to true and set up the save path in
+ * $wgFileStore['deleted']['directory'].
+ */
+$wgSaveDeletedFiles = false;
+
+/**
+ * New file storage paths; currently used only for deleted files.
+ * Set it like this:
+ *
+ * $wgFileStore['deleted']['directory'] = '/var/wiki/private/deleted';
+ *
+ */
+$wgFileStore = array();
+$wgFileStore['deleted']['directory'] = null; // Don't forget to set this.
+$wgFileStore['deleted']['url'] = null; // Private
+$wgFileStore['deleted']['hash'] = 3; // 3-level subdirectory split
+
+/**
+ * Allowed title characters -- regex character class
+ * Don't change this unless you know what you're doing
+ *
+ * Problematic punctuation:
+ * []{}|# Are needed for link syntax, never enable these
+ * % Enabled by default, minor problems with path to query rewrite rules, see below
+ * + Enabled by default, but doesn't work with path to query rewrite rules, corrupted by apache
+ * ? Enabled by default, but doesn't work with path to PATH_INFO rewrites
+ *
+ * All three of these punctuation problems can be avoided by using an alias, instead of a
+ * rewrite rule of either variety.
+ *
+ * The problem with % is that when using a path to query rewrite rule, URLs are
+ * double-unescaped: once by Apache's path conversion code, and again by PHP. So
+ * %253F, for example, becomes "?". Our code does not double-escape to compensate
+ * for this, indeed double escaping would break if the double-escaped title was
+ * passed in the query string rather than the path. This is a minor security issue
+ * because articles can be created such that they are hard to view or edit.
+ *
+ * In some rare cases you may wish to remove + for compatibility with old links.
+ *
+ * Theoretically 0x80-0x9F of ISO 8859-1 should be disallowed, but
+ * this breaks interlanguage links
+ */
+$wgLegalTitleChars = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+";
+
+
+/**
+ * The external URL protocols
+ */
+$wgUrlProtocols = array(
+ 'http://',
+ 'https://',
+ 'ftp://',
+ 'irc://',
+ 'gopher://',
+ 'telnet://', // Well if we're going to support the above.. -ævar
+ 'nntp://', // @bug 3808 RFC 1738
+ 'worldwind://',
+ 'mailto:',
+ 'news:'
+);
+
+/** internal name of virus scanner. This servers as a key to the $wgAntivirusSetup array.
+ * Set this to NULL to disable virus scanning. If not null, every file uploaded will be scanned for viruses.
+ * @global string $wgAntivirus
+ */
+$wgAntivirus= NULL;
+
+/** Configuration for different virus scanners. This an associative array of associative arrays:
+ * it contains on setup array per known scanner type. The entry is selected by $wgAntivirus, i.e.
+ * valid values for $wgAntivirus are the keys defined in this array.
+ *
+ * The configuration array for each scanner contains the following keys: "command", "codemap", "messagepattern";
+ *
+ * "command" is the full command to call the virus scanner - %f will be replaced with the name of the
+ * file to scan. If not present, the filename will be appended to the command. Note that this must be
+ * overwritten if the scanner is not in the system path; in that case, plase set
+ * $wgAntivirusSetup[$wgAntivirus]['command'] to the desired command with full path.
+ *
+ * "codemap" is a mapping of exit code to return codes of the detectVirus function in SpecialUpload.
+ * An exit code mapped to AV_SCAN_FAILED causes the function to consider the scan to be failed. This will pass
+ * the file if $wgAntivirusRequired is not set.
+ * An exit code mapped to AV_SCAN_ABORTED causes the function to consider the file to have an usupported format,
+ * which is probably imune to virusses. This causes the file to pass.
+ * An exit code mapped to AV_NO_VIRUS will cause the file to pass, meaning no virus was found.
+ * All other codes (like AV_VIRUS_FOUND) will cause the function to report a virus.
+ * You may use "*" as a key in the array to catch all exit codes not mapped otherwise.
+ *
+ * "messagepattern" is a perl regular expression to extract the meaningful part of the scanners
+ * output. The relevant part should be matched as group one (\1).
+ * If not defined or the pattern does not match, the full message is shown to the user.
+ *
+ * @global array $wgAntivirusSetup
+ */
+$wgAntivirusSetup= array(
+
+ #setup for clamav
+ 'clamav' => array (
+ 'command' => "clamscan --no-summary ",
+
+ 'codemap'=> array (
+ "0"=> AV_NO_VIRUS, #no virus
+ "1"=> AV_VIRUS_FOUND, #virus found
+ "52"=> AV_SCAN_ABORTED, #unsupported file format (probably imune)
+ "*"=> AV_SCAN_FAILED, #else scan failed
+ ),
+
+ 'messagepattern'=> '/.*?:(.*)/sim',
+ ),
+
+ #setup for f-prot
+ 'f-prot' => array (
+ 'command' => "f-prot ",
+
+ 'codemap'=> array (
+ "0"=> AV_NO_VIRUS, #no virus
+ "3"=> AV_VIRUS_FOUND, #virus found
+ "6"=> AV_VIRUS_FOUND, #virus found
+ "*"=> AV_SCAN_FAILED, #else scan failed
+ ),
+
+ 'messagepattern'=> '/.*?Infection:(.*)$/m',
+ ),
+);
+
+
+/** Determines if a failed virus scan (AV_SCAN_FAILED) will cause the file to be rejected.
+ * @global boolean $wgAntivirusRequired
+*/
+$wgAntivirusRequired= true;
+
+/** Determines if the mime type of uploaded files should be checked
+ * @global boolean $wgVerifyMimeType
+*/
+$wgVerifyMimeType= true;
+
+/** Sets the mime type definition file to use by MimeMagic.php.
+* @global string $wgMimeTypeFile
+*/
+#$wgMimeTypeFile= "/etc/mime.types";
+$wgMimeTypeFile= "includes/mime.types";
+#$wgMimeTypeFile= NULL; #use built-in defaults only.
+
+/** Sets the mime type info file to use by MimeMagic.php.
+* @global string $wgMimeInfoFile
+*/
+$wgMimeInfoFile= "includes/mime.info";
+#$wgMimeInfoFile= NULL; #use built-in defaults only.
+
+/** Switch for loading the FileInfo extension by PECL at runtime.
+ * This should be used only if fileinfo is installed as a shared object
+ * or a dynamic libary
+ * @global string $wgLoadFileinfoExtension
+*/
+$wgLoadFileinfoExtension= false;
+
+/** Sets an external mime detector program. The command must print only
+ * the mime type to standard output.
+ * The name of the file to process will be appended to the command given here.
+ * If not set or NULL, mime_content_type will be used if available.
+*/
+$wgMimeDetectorCommand= NULL; # use internal mime_content_type function, available since php 4.3.0
+#$wgMimeDetectorCommand= "file -bi"; #use external mime detector (Linux)
+
+/** Switch for trivial mime detection. Used by thumb.php to disable all fance
+ * things, because only a few types of images are needed and file extensions
+ * can be trusted.
+*/
+$wgTrivialMimeDetection= false;
+
+/**
+ * To set 'pretty' URL paths for actions other than
+ * plain page views, add to this array. For instance:
+ * 'edit' => "$wgScriptPath/edit/$1"
+ *
+ * There must be an appropriate script or rewrite rule
+ * in place to handle these URLs.
+ */
+$wgActionPaths = array();
+
+/**
+ * If you operate multiple wikis, you can define a shared upload path here.
+ * Uploads to this wiki will NOT be put there - they will be put into
+ * $wgUploadDirectory.
+ * If $wgUseSharedUploads is set, the wiki will look in the shared repository if
+ * no file of the given name is found in the local repository (for [[Image:..]],
+ * [[Media:..]] links). Thumbnails will also be looked for and generated in this
+ * directory.
+ */
+$wgUseSharedUploads = false;
+/** Full path on the web server where shared uploads can be found */
+$wgSharedUploadPath = "http://commons.wikimedia.org/shared/images";
+/** Fetch commons image description pages and display them on the local wiki? */
+$wgFetchCommonsDescriptions = false;
+/** Path on the file system where shared uploads can be found. */
+$wgSharedUploadDirectory = "/var/www/wiki3/images";
+/** DB name with metadata about shared directory. Set this to false if the uploads do not come from a wiki. */
+$wgSharedUploadDBname = false;
+/** Optional table prefix used in database. */
+$wgSharedUploadDBprefix = '';
+/** Cache shared metadata in memcached. Don't do this if the commons wiki is in a different memcached domain */
+$wgCacheSharedUploads = true;
+/** Allow for upload to be copied from an URL. Requires Special:Upload?source=web */
+$wgAllowCopyUploads = false;
+/** Max size for uploads, in bytes */
+$wgMaxUploadSize = 1024*1024*100; # 100MB
+
+/**
+ * Point the upload navigation link to an external URL
+ * Useful if you want to use a shared repository by default
+ * without disabling local uploads (use $wgEnableUploads = false for that)
+ * e.g. $wgUploadNavigationUrl = 'http://commons.wikimedia.org/wiki/Special:Upload';
+*/
+$wgUploadNavigationUrl = false;
+
+/**
+ * Give a path here to use thumb.php for thumbnail generation on client request, instead of
+ * generating them on render and outputting a static URL. This is necessary if some of your
+ * apache servers don't have read/write access to the thumbnail path.
+ *
+ * Example:
+ * $wgThumbnailScriptPath = "{$wgScriptPath}/thumb.php";
+ */
+$wgThumbnailScriptPath = false;
+$wgSharedThumbnailScriptPath = false;
+
+/**
+ * Set the following to false especially if you have a set of files that need to
+ * be accessible by all wikis, and you do not want to use the hash (path/a/aa/)
+ * directory layout.
+ */
+$wgHashedSharedUploadDirectory = true;
+
+/**
+ * Base URL for a repository wiki. Leave this blank if uploads are just stored
+ * in a shared directory and not meant to be accessible through a separate wiki.
+ * Otherwise the image description pages on the local wiki will link to the
+ * image description page on this wiki.
+ *
+ * Please specify the namespace, as in the example below.
+ */
+$wgRepositoryBaseUrl="http://commons.wikimedia.org/wiki/Image:";
+
+
+#
+# Email settings
+#
+
+/**
+ * Site admin email address
+ * Default to wikiadmin@SERVER_NAME
+ * @global string $wgEmergencyContact
+ */
+$wgEmergencyContact = 'wikiadmin@' . $wgServerName;
+
+/**
+ * Password reminder email address
+ * The address we should use as sender when a user is requesting his password
+ * Default to apache@SERVER_NAME
+ * @global string $wgPasswordSender
+ */
+$wgPasswordSender = 'MediaWiki Mail <apache@' . $wgServerName . '>';
+
+/**
+ * dummy address which should be accepted during mail send action
+ * It might be necessay to adapt the address or to set it equal
+ * to the $wgEmergencyContact address
+ */
+#$wgNoReplyAddress = $wgEmergencyContact;
+$wgNoReplyAddress = 'reply@not.possible';
+
+/**
+ * Set to true to enable the e-mail basic features:
+ * Password reminders, etc. If sending e-mail on your
+ * server doesn't work, you might want to disable this.
+ * @global bool $wgEnableEmail
+ */
+$wgEnableEmail = true;
+
+/**
+ * Set to true to enable user-to-user e-mail.
+ * This can potentially be abused, as it's hard to track.
+ * @global bool $wgEnableUserEmail
+ */
+$wgEnableUserEmail = true;
+
+/**
+ * Minimum time, in hours, which must elapse between password reminder
+ * emails for a given account. This is to prevent abuse by mail flooding.
+ */
+$wgPasswordReminderResendTime = 24;
+
+/**
+ * SMTP Mode
+ * For using a direct (authenticated) SMTP server connection.
+ * Default to false or fill an array :
+ * <code>
+ * "host" => 'SMTP domain',
+ * "IDHost" => 'domain for MessageID',
+ * "port" => "25",
+ * "auth" => true/false,
+ * "username" => user,
+ * "password" => password
+ * </code>
+ *
+ * @global mixed $wgSMTP
+ */
+$wgSMTP = false;
+
+
+/**#@+
+ * Database settings
+ */
+/** database host name or ip address */
+$wgDBserver = 'localhost';
+/** database port number */
+$wgDBport = '';
+/** name of the database */
+$wgDBname = 'wikidb';
+/** */
+$wgDBconnection = '';
+/** Database username */
+$wgDBuser = 'wikiuser';
+/** Database type
+ */
+$wgDBtype = "mysql";
+/** Search type
+ * Leave as null to select the default search engine for the
+ * selected database type (eg SearchMySQL4), or set to a class
+ * name to override to a custom search engine.
+ */
+$wgSearchType = null;
+/** Table name prefix */
+$wgDBprefix = '';
+/**#@-*/
+
+/** Live high performance sites should disable this - some checks acquire giant mysql locks */
+$wgCheckDBSchema = true;
+
+
+/**
+ * Shared database for multiple wikis. Presently used for storing a user table
+ * for single sign-on. The server for this database must be the same as for the
+ * main database.
+ * EXPERIMENTAL
+ */
+$wgSharedDB = null;
+
+# Database load balancer
+# This is a two-dimensional array, an array of server info structures
+# Fields are:
+# host: Host name
+# dbname: Default database name
+# user: DB user
+# password: DB password
+# type: "mysql" or "postgres"
+# load: ratio of DB_SLAVE load, must be >=0, the sum of all loads must be >0
+# groupLoads: array of load ratios, the key is the query group name. A query may belong
+# to several groups, the most specific group defined here is used.
+#
+# flags: bit field
+# DBO_DEFAULT -- turns on DBO_TRX only if !$wgCommandLineMode (recommended)
+# DBO_DEBUG -- equivalent of $wgDebugDumpSql
+# DBO_TRX -- wrap entire request in a transaction
+# DBO_IGNORE -- ignore errors (not useful in LocalSettings.php)
+# DBO_NOBUFFER -- turn off buffering (not useful in LocalSettings.php)
+#
+# max lag: (optional) Maximum replication lag before a slave will taken out of rotation
+# max threads: (optional) Maximum number of running threads
+#
+# These and any other user-defined properties will be assigned to the mLBInfo member
+# variable of the Database object.
+#
+# Leave at false to use the single-server variables above
+$wgDBservers = false;
+
+/** How long to wait for a slave to catch up to the master */
+$wgMasterWaitTimeout = 10;
+
+/** File to log database errors to */
+$wgDBerrorLog = false;
+
+/** When to give an error message */
+$wgDBClusterTimeout = 10;
+
+/**
+ * wgDBminWordLen :
+ * MySQL 3.x : used to discard words that MySQL will not return any results for
+ * shorter values configure mysql directly.
+ * MySQL 4.x : ignore it and configure mySQL
+ * See: http://dev.mysql.com/doc/mysql/en/Fulltext_Fine-tuning.html
+ */
+$wgDBminWordLen = 4;
+/** Set to true if using InnoDB tables */
+$wgDBtransactions = false;
+/** Set to true for compatibility with extensions that might be checking.
+ * MySQL 3.23.x is no longer supported. */
+$wgDBmysql4 = true;
+
+/**
+ * Set to true to engage MySQL 4.1/5.0 charset-related features;
+ * for now will just cause sending of 'SET NAMES=utf8' on connect.
+ *
+ * WARNING: THIS IS EXPERIMENTAL!
+ *
+ * May break if you're not using the table defs from mysql5/tables.sql.
+ * May break if you're upgrading an existing wiki if set differently.
+ * Broken symptoms likely to include incorrect behavior with page titles,
+ * usernames, comments etc containing non-ASCII characters.
+ * Might also cause failures on the object cache and other things.
+ *
+ * Even correct usage may cause failures with Unicode supplementary
+ * characters (those not in the Basic Multilingual Plane) unless MySQL
+ * has enhanced their Unicode support.
+ */
+$wgDBmysql5 = false;
+
+/**
+ * Other wikis on this site, can be administered from a single developer
+ * account.
+ * Array numeric key => database name
+ */
+$wgLocalDatabases = array();
+
+/**
+ * Object cache settings
+ * See Defines.php for types
+ */
+$wgMainCacheType = CACHE_NONE;
+$wgMessageCacheType = CACHE_ANYTHING;
+$wgParserCacheType = CACHE_ANYTHING;
+
+$wgParserCacheExpireTime = 86400;
+
+$wgSessionsInMemcached = false;
+$wgLinkCacheMemcached = false; # Not fully tested
+
+/**
+ * Memcached-specific settings
+ * See docs/memcached.txt
+ */
+$wgUseMemCached = false;
+$wgMemCachedDebug = false; # Will be set to false in Setup.php, if the server isn't working
+$wgMemCachedServers = array( '127.0.0.1:11000' );
+$wgMemCachedDebug = false;
+$wgMemCachedPersistent = false;
+
+/**
+ * Directory for local copy of message cache, for use in addition to memcached
+ */
+$wgLocalMessageCache = false;
+/**
+ * Defines format of local cache
+ * true - Serialized object
+ * false - PHP source file (Warning - security risk)
+ */
+$wgLocalMessageCacheSerialized = true;
+
+/**
+ * Directory for compiled constant message array databases
+ * WARNING: turning anything on will just break things, aaaaaah!!!!
+ */
+$wgCachedMessageArrays = false;
+
+# Language settings
+#
+/** Site language code, should be one of ./languages/Language(.*).php */
+$wgLanguageCode = 'en';
+
+/**
+ * Some languages need different word forms, usually for different cases.
+ * Used in Language::convertGrammar().
+ */
+$wgGrammarForms = array();
+#$wgGrammarForms['en']['genitive']['car'] = 'car\'s';
+
+/** Treat language links as magic connectors, not inline links */
+$wgInterwikiMagic = true;
+
+/** Hide interlanguage links from the sidebar */
+$wgHideInterlanguageLinks = false;
+
+
+/** We speak UTF-8 all the time now, unless some oddities happen */
+$wgInputEncoding = 'UTF-8';
+$wgOutputEncoding = 'UTF-8';
+$wgEditEncoding = '';
+
+# Set this to eg 'ISO-8859-1' to perform character set
+# conversion when loading old revisions not marked with
+# "utf-8" flag. Use this when converting wiki to UTF-8
+# without the burdensome mass conversion of old text data.
+#
+# NOTE! This DOES NOT touch any fields other than old_text.
+# Titles, comments, user names, etc still must be converted
+# en masse in the database before continuing as a UTF-8 wiki.
+$wgLegacyEncoding = false;
+
+/**
+ * If set to true, the MediaWiki 1.4 to 1.5 schema conversion will
+ * create stub reference rows in the text table instead of copying
+ * the full text of all current entries from 'cur' to 'text'.
+ *
+ * This will speed up the conversion step for large sites, but
+ * requires that the cur table be kept around for those revisions
+ * to remain viewable.
+ *
+ * maintenance/migrateCurStubs.php can be used to complete the
+ * migration in the background once the wiki is back online.
+ *
+ * This option affects the updaters *only*. Any present cur stub
+ * revisions will be readable at runtime regardless of this setting.
+ */
+$wgLegacySchemaConversion = false;
+
+$wgMimeType = 'text/html';
+$wgJsMimeType = 'text/javascript';
+$wgDocType = '-//W3C//DTD XHTML 1.0 Transitional//EN';
+$wgDTD = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd';
+$wgXhtmlDefaultNamespace = 'http://www.w3.org/1999/xhtml';
+
+# Permit other namespaces in addition to the w3.org default.
+# Use the prefix for the key and the namespace for the value. For
+# example:
+# $wgXhtmlNamespaces['svg'] = 'http://www.w3.org/2000/svg';
+# Normally we wouldn't have to define this in the root <html>
+# element, but IE needs it there in some circumstances.
+$wgXhtmlNamespaces = array();
+
+/** Enable to allow rewriting dates in page text.
+ * DOES NOT FORMAT CORRECTLY FOR MOST LANGUAGES */
+$wgUseDynamicDates = false;
+/** Enable dates like 'May 12' instead of '12 May', this only takes effect if
+ * the interface is set to English
+ */
+$wgAmericanDates = false;
+/**
+ * For Hindi and Arabic use local numerals instead of Western style (0-9)
+ * numerals in interface.
+ */
+$wgTranslateNumerals = true;
+
+/**
+ * Translation using MediaWiki: namespace.
+ * This will increase load times by 25-60% unless memcached is installed.
+ * Interface messages will be loaded from the database.
+ */
+$wgUseDatabaseMessages = true;
+
+/**
+ * Expiry time for the message cache key
+ */
+$wgMsgCacheExpiry = 86400;
+
+/**
+ * Maximum entry size in the message cache, in bytes
+ */
+$wgMaxMsgCacheEntrySize = 10000;
+
+# Whether to enable language variant conversion.
+$wgDisableLangConversion = false;
+
+# Default variant code, if false, the default will be the language code
+$wgDefaultLanguageVariant = false;
+
+/**
+ * Show a bar of language selection links in the user login and user
+ * registration forms; edit the "loginlanguagelinks" message to
+ * customise these
+ */
+$wgLoginLanguageSelector = false;
+
+# Whether to use zhdaemon to perform Chinese text processing
+# zhdaemon is under developement, so normally you don't want to
+# use it unless for testing
+$wgUseZhdaemon = false;
+$wgZhdaemonHost="localhost";
+$wgZhdaemonPort=2004;
+
+/** Normally you can ignore this and it will be something
+ like $wgMetaNamespace . "_talk". In some languages, you
+ may want to set this manually for grammatical reasons.
+ It is currently only respected by those languages
+ where it might be relevant and where no automatic
+ grammar converter exists.
+*/
+$wgMetaNamespaceTalk = false;
+
+# Miscellaneous configuration settings
+#
+
+$wgLocalInterwiki = 'w';
+$wgInterwikiExpiry = 10800; # Expiry time for cache of interwiki table
+
+/** Interwiki caching settings.
+ $wgInterwikiCache specifies path to constant database file
+ This cdb database is generated by dumpInterwiki from maintenance
+ and has such key formats:
+ dbname:key - a simple key (e.g. enwiki:meta)
+ _sitename:key - site-scope key (e.g. wiktionary:meta)
+ __global:key - global-scope key (e.g. __global:meta)
+ __sites:dbname - site mapping (e.g. __sites:enwiki)
+ Sites mapping just specifies site name, other keys provide
+ "local url" data layout.
+ $wgInterwikiScopes specify number of domains to check for messages:
+ 1 - Just wiki(db)-level
+ 2 - wiki and global levels
+ 3 - site levels
+ $wgInterwikiFallbackSite - if unable to resolve from cache
+*/
+$wgInterwikiCache = false;
+$wgInterwikiScopes = 3;
+$wgInterwikiFallbackSite = 'wiki';
+
+/**
+ * If local interwikis are set up which allow redirects,
+ * set this regexp to restrict URLs which will be displayed
+ * as 'redirected from' links.
+ *
+ * It might look something like this:
+ * $wgRedirectSources = '!^https?://[a-z-]+\.wikipedia\.org/!';
+ *
+ * Leave at false to avoid displaying any incoming redirect markers.
+ * This does not affect intra-wiki redirects, which don't change
+ * the URL.
+ */
+$wgRedirectSources = false;
+
+
+$wgShowIPinHeader = true; # For non-logged in users
+$wgMaxNameChars = 255; # Maximum number of bytes in username
+$wgMaxArticleSize = 2048; # Maximum article size in kilobytes
+
+$wgExtraSubtitle = '';
+$wgSiteSupportPage = ''; # A page where you users can receive donations
+
+/***
+ * If this lock file exists, the wiki will be forced into read-only mode.
+ * Its contents will be shown to users as part of the read-only warning
+ * message.
+ */
+$wgReadOnlyFile = false; /// defaults to "{$wgUploadDirectory}/lock_yBgMBwiR";
+
+/**
+ * The debug log file should be not be publicly accessible if it is used, as it
+ * may contain private data. */
+$wgDebugLogFile = '';
+
+/**#@+
+ * @global bool
+ */
+$wgDebugRedirects = false;
+$wgDebugRawPage = false; # Avoid overlapping debug entries by leaving out CSS
+
+$wgDebugComments = false;
+$wgReadOnly = null;
+$wgLogQueries = false;
+
+/**
+ * Write SQL queries to the debug log
+ */
+$wgDebugDumpSql = false;
+
+/**
+ * Set to an array of log group keys to filenames.
+ * If set, wfDebugLog() output for that group will go to that file instead
+ * of the regular $wgDebugLogFile. Useful for enabling selective logging
+ * in production.
+ */
+$wgDebugLogGroups = array();
+
+/**
+ * Whether to show "we're sorry, but there has been a database error" pages.
+ * Displaying errors aids in debugging, but may display information useful
+ * to an attacker.
+ */
+$wgShowSQLErrors = false;
+
+/**
+ * If true, some error messages will be colorized when running scripts on the
+ * command line; this can aid picking important things out when debugging.
+ * Ignored when running on Windows or when output is redirected to a file.
+ */
+$wgColorErrors = true;
+
+/**
+ * If set to true, uncaught exceptions will print a complete stack trace
+ * to output. This should only be used for debugging, as it may reveal
+ * private information in function parameters due to PHP's backtrace
+ * formatting.
+ */
+$wgShowExceptionDetails = false;
+
+/**
+ * disable experimental dmoz-like category browsing. Output things like:
+ * Encyclopedia > Music > Style of Music > Jazz
+ */
+$wgUseCategoryBrowser = false;
+
+/**
+ * Keep parsed pages in a cache (objectcache table, turck, or memcached)
+ * to speed up output of the same page viewed by another user with the
+ * same options.
+ *
+ * This can provide a significant speedup for medium to large pages,
+ * so you probably want to keep it on.
+ */
+$wgEnableParserCache = true;
+
+/**
+ * If on, the sidebar navigation links are cached for users with the
+ * current language set. This can save a touch of load on a busy site
+ * by shaving off extra message lookups.
+ *
+ * However it is also fragile: changing the site configuration, or
+ * having a variable $wgArticlePath, can produce broken links that
+ * don't update as expected.
+ */
+$wgEnableSidebarCache = false;
+
+/**
+ * Under which condition should a page in the main namespace be counted
+ * as a valid article? If $wgUseCommaCount is set to true, it will be
+ * counted if it contains at least one comma. If it is set to false
+ * (default), it will only be counted if it contains at least one [[wiki
+ * link]]. See http://meta.wikimedia.org/wiki/Help:Article_count
+ *
+ * Retroactively changing this variable will not affect
+ * the existing count (cf. maintenance/recount.sql).
+*/
+$wgUseCommaCount = false;
+
+/**#@-*/
+
+/**
+ * wgHitcounterUpdateFreq sets how often page counters should be updated, higher
+ * values are easier on the database. A value of 1 causes the counters to be
+ * updated on every hit, any higher value n cause them to update *on average*
+ * every n hits. Should be set to either 1 or something largish, eg 1000, for
+ * maximum efficiency.
+*/
+$wgHitcounterUpdateFreq = 1;
+
+# Basic user rights and block settings
+$wgSysopUserBans = true; # Allow sysops to ban logged-in users
+$wgSysopRangeBans = true; # Allow sysops to ban IP ranges
+$wgAutoblockExpiry = 86400; # Number of seconds before autoblock entries expire
+$wgBlockAllowsUTEdit = false; # Blocks allow users to edit their own user talk page
+
+# Pages anonymous user may see as an array, e.g.:
+# array ( "Main Page", "Special:Userlogin", "Wikipedia:Help");
+# NOTE: This will only work if $wgGroupPermissions['*']['read']
+# is false -- see below. Otherwise, ALL pages are accessible,
+# regardless of this setting.
+# Also note that this will only protect _pages in the wiki_.
+# Uploaded files will remain readable. Make your upload
+# directory name unguessable, or use .htaccess to protect it.
+$wgWhitelistRead = false;
+
+/**
+ * Should editors be required to have a validated e-mail
+ * address before being allowed to edit?
+ */
+$wgEmailConfirmToEdit=false;
+
+/**
+ * Permission keys given to users in each group.
+ * All users are implicitly in the '*' group including anonymous visitors;
+ * logged-in users are all implicitly in the 'user' group. These will be
+ * combined with the permissions of all groups that a given user is listed
+ * in in the user_groups table.
+ *
+ * Functionality to make pages inaccessible has not been extensively tested
+ * for security. Use at your own risk!
+ *
+ * This replaces wgWhitelistAccount and wgWhitelistEdit
+ */
+$wgGroupPermissions = array();
+
+// Implicit group for all visitors
+$wgGroupPermissions['*' ]['createaccount'] = true;
+$wgGroupPermissions['*' ]['read'] = true;
+$wgGroupPermissions['*' ]['edit'] = true;
+$wgGroupPermissions['*' ]['createpage'] = true;
+$wgGroupPermissions['*' ]['createtalk'] = true;
+
+// Implicit group for all logged-in accounts
+$wgGroupPermissions['user' ]['move'] = true;
+$wgGroupPermissions['user' ]['read'] = true;
+$wgGroupPermissions['user' ]['edit'] = true;
+$wgGroupPermissions['user' ]['createpage'] = true;
+$wgGroupPermissions['user' ]['createtalk'] = true;
+$wgGroupPermissions['user' ]['upload'] = true;
+$wgGroupPermissions['user' ]['reupload'] = true;
+$wgGroupPermissions['user' ]['reupload-shared'] = true;
+$wgGroupPermissions['user' ]['minoredit'] = true;
+
+// Implicit group for accounts that pass $wgAutoConfirmAge
+$wgGroupPermissions['autoconfirmed']['autoconfirmed'] = true;
+
+// Implicit group for accounts with confirmed email addresses
+// This has little use when email address confirmation is off
+$wgGroupPermissions['emailconfirmed']['emailconfirmed'] = true;
+
+// Users with bot privilege can have their edits hidden
+// from various log pages by default
+$wgGroupPermissions['bot' ]['bot'] = true;
+$wgGroupPermissions['bot' ]['autoconfirmed'] = true;
+$wgGroupPermissions['bot' ]['nominornewtalk'] = true;
+
+// Most extra permission abilities go to this group
+$wgGroupPermissions['sysop']['block'] = true;
+$wgGroupPermissions['sysop']['createaccount'] = true;
+$wgGroupPermissions['sysop']['delete'] = true;
+$wgGroupPermissions['sysop']['deletedhistory'] = true; // can view deleted history entries, but not see or restore the text
+$wgGroupPermissions['sysop']['editinterface'] = true;
+$wgGroupPermissions['sysop']['import'] = true;
+$wgGroupPermissions['sysop']['importupload'] = true;
+$wgGroupPermissions['sysop']['move'] = true;
+$wgGroupPermissions['sysop']['patrol'] = true;
+$wgGroupPermissions['sysop']['autopatrol'] = true;
+$wgGroupPermissions['sysop']['protect'] = true;
+$wgGroupPermissions['sysop']['proxyunbannable'] = true;
+$wgGroupPermissions['sysop']['rollback'] = true;
+$wgGroupPermissions['sysop']['trackback'] = true;
+$wgGroupPermissions['sysop']['upload'] = true;
+$wgGroupPermissions['sysop']['reupload'] = true;
+$wgGroupPermissions['sysop']['reupload-shared'] = true;
+$wgGroupPermissions['sysop']['unwatchedpages'] = true;
+$wgGroupPermissions['sysop']['autoconfirmed'] = true;
+$wgGroupPermissions['sysop']['upload_by_url'] = true;
+$wgGroupPermissions['sysop']['ipblock-exempt'] = true;
+
+// Permission to change users' group assignments
+$wgGroupPermissions['bureaucrat']['userrights'] = true;
+
+// Experimental permissions, not ready for production use
+//$wgGroupPermissions['sysop']['deleterevision'] = true;
+//$wgGroupPermissions['bureaucrat']['hiderevision'] = true;
+
+/**
+ * The developer group is deprecated, but can be activated if need be
+ * to use the 'lockdb' and 'unlockdb' special pages. Those require
+ * that a lock file be defined and creatable/removable by the web
+ * server.
+ */
+# $wgGroupPermissions['developer']['siteadmin'] = true;
+
+/**
+ * Set of available actions that can be restricted via action=protect
+ * You probably shouldn't change this.
+ * Translated trough restriction-* messages.
+ */
+$wgRestrictionTypes = array( 'edit', 'move' );
+
+/**
+ * Set of permission keys that can be selected via action=protect.
+ * 'autoconfirm' allows all registerd users if $wgAutoConfirmAge is 0.
+ */
+$wgRestrictionLevels = array( '', 'autoconfirmed', 'sysop' );
+
+
+/**
+ * Number of seconds an account is required to age before
+ * it's given the implicit 'autoconfirm' group membership.
+ * This can be used to limit privileges of new accounts.
+ *
+ * Accounts created by earlier versions of the software
+ * may not have a recorded creation date, and will always
+ * be considered to pass the age test.
+ *
+ * When left at 0, all registered accounts will pass.
+ */
+$wgAutoConfirmAge = 0;
+//$wgAutoConfirmAge = 600; // ten minutes
+//$wgAutoConfirmAge = 3600*24; // one day
+
+
+
+# Proxy scanner settings
+#
+
+/**
+ * If you enable this, every editor's IP address will be scanned for open HTTP
+ * proxies.
+ *
+ * Don't enable this. Many sysops will report "hostile TCP port scans" to your
+ * ISP and ask for your server to be shut down.
+ *
+ * You have been warned.
+ */
+$wgBlockOpenProxies = false;
+/** Port we want to scan for a proxy */
+$wgProxyPorts = array( 80, 81, 1080, 3128, 6588, 8000, 8080, 8888, 65506 );
+/** Script used to scan */
+$wgProxyScriptPath = "$IP/includes/proxy_check.php";
+/** */
+$wgProxyMemcExpiry = 86400;
+/** This should always be customised in LocalSettings.php */
+$wgSecretKey = false;
+/** big list of banned IP addresses, in the keys not the values */
+$wgProxyList = array();
+/** deprecated */
+$wgProxyKey = false;
+
+/** Number of accounts each IP address may create, 0 to disable.
+ * Requires memcached */
+$wgAccountCreationThrottle = 0;
+
+# Client-side caching:
+
+/** Allow client-side caching of pages */
+$wgCachePages = true;
+
+/**
+ * Set this to current time to invalidate all prior cached pages. Affects both
+ * client- and server-side caching.
+ * You can get the current date on your server by using the command:
+ * date +%Y%m%d%H%M%S
+ */
+$wgCacheEpoch = '20030516000000';
+
+/**
+ * Bump this number when changing the global style sheets and JavaScript.
+ * It should be appended in the query string of static CSS and JS includes,
+ * to ensure that client-side caches don't keep obsolete copies of global
+ * styles.
+ */
+$wgStyleVersion = '42b';
+
+
+# Server-side caching:
+
+/**
+ * This will cache static pages for non-logged-in users to reduce
+ * database traffic on public sites.
+ * Must set $wgShowIPinHeader = false
+ */
+$wgUseFileCache = false;
+
+/** Directory where the cached page will be saved */
+$wgFileCacheDirectory = false; /// defaults to "{$wgUploadDirectory}/cache";
+
+/**
+ * When using the file cache, we can store the cached HTML gzipped to save disk
+ * space. Pages will then also be served compressed to clients that support it.
+ * THIS IS NOT COMPATIBLE with ob_gzhandler which is now enabled if supported in
+ * the default LocalSettings.php! If you enable this, remove that setting first.
+ *
+ * Requires zlib support enabled in PHP.
+ */
+$wgUseGzip = false;
+
+/** Whether MediaWiki should send an ETag header */
+$wgUseETag = false;
+
+# Email notification settings
+#
+
+/** For email notification on page changes */
+$wgPasswordSender = $wgEmergencyContact;
+
+# true: from page editor if s/he opted-in
+# false: Enotif mails appear to come from $wgEmergencyContact
+$wgEnotifFromEditor = false;
+
+// TODO move UPO to preferences probably ?
+# If set to true, users get a corresponding option in their preferences and can choose to enable or disable at their discretion
+# If set to false, the corresponding input form on the user preference page is suppressed
+# It call this to be a "user-preferences-option (UPO)"
+$wgEmailAuthentication = true; # UPO (if this is set to false, texts referring to authentication are suppressed)
+$wgEnotifWatchlist = false; # UPO
+$wgEnotifUserTalk = false; # UPO
+$wgEnotifRevealEditorAddress = false; # UPO; reply-to address may be filled with page editor's address (if user allowed this in the preferences)
+$wgEnotifMinorEdits = true; # UPO; false: "minor edits" on pages do not trigger notification mails.
+# # Attention: _every_ change on a user_talk page trigger a notification mail (if the user is not yet notified)
+
+/** Show watching users in recent changes, watchlist and page history views */
+$wgRCShowWatchingUsers = false; # UPO
+/** Show watching users in Page views */
+$wgPageShowWatchingUsers = false;
+/** Show the amount of changed characters in recent changes */
+$wgRCShowChangedSize = true;
+
+/**
+ * If the difference between the character counts of the text
+ * before and after the edit is below that value, the value will be
+ * highlighted on the RC page.
+ */
+$wgRCChangedSizeThreshold = -500;
+
+/**
+ * Show "Updated (since my last visit)" marker in RC view, watchlist and history
+ * view for watched pages with new changes */
+$wgShowUpdatedMarker = true;
+
+$wgCookieExpiration = 2592000;
+
+/** Clock skew or the one-second resolution of time() can occasionally cause cache
+ * problems when the user requests two pages within a short period of time. This
+ * variable adds a given number of seconds to vulnerable timestamps, thereby giving
+ * a grace period.
+ */
+$wgClockSkewFudge = 5;
+
+# Squid-related settings
+#
+
+/** Enable/disable Squid */
+$wgUseSquid = false;
+
+/** If you run Squid3 with ESI support, enable this (default:false): */
+$wgUseESI = false;
+
+/** Internal server name as known to Squid, if different */
+# $wgInternalServer = 'http://yourinternal.tld:8000';
+$wgInternalServer = $wgServer;
+
+/**
+ * Cache timeout for the squid, will be sent as s-maxage (without ESI) or
+ * Surrogate-Control (with ESI). Without ESI, you should strip out s-maxage in
+ * the Squid config. 18000 seconds = 5 hours, more cache hits with 2678400 = 31
+ * days
+ */
+$wgSquidMaxage = 18000;
+
+/**
+ * A list of proxy servers (ips if possible) to purge on changes don't specify
+ * ports here (80 is default)
+ */
+# $wgSquidServers = array('127.0.0.1');
+$wgSquidServers = array();
+$wgSquidServersNoPurge = array();
+
+/** Maximum number of titles to purge in any one client operation */
+$wgMaxSquidPurgeTitles = 400;
+
+/** HTCP multicast purging */
+$wgHTCPPort = 4827;
+$wgHTCPMulticastTTL = 1;
+# $wgHTCPMulticastAddress = "224.0.0.85";
+$wgHTCPMulticastAddress = false;
+
+# Cookie settings:
+#
+/**
+ * Set to set an explicit domain on the login cookies eg, "justthis.domain. org"
+ * or ".any.subdomain.net"
+ */
+$wgCookieDomain = '';
+$wgCookiePath = '/';
+$wgCookieSecure = ($wgProto == 'https');
+$wgDisableCookieCheck = false;
+
+/** Override to customise the session name */
+$wgSessionName = false;
+
+/** Whether to allow inline image pointing to other websites */
+$wgAllowExternalImages = false;
+
+/** If the above is false, you can specify an exception here. Image URLs
+ * that start with this string are then rendered, while all others are not.
+ * You can use this to set up a trusted, simple repository of images.
+ *
+ * Example:
+ * $wgAllowExternalImagesFrom = 'http://127.0.0.1/';
+ */
+$wgAllowExternalImagesFrom = '';
+
+/** Disable database-intensive features */
+$wgMiserMode = false;
+/** Disable all query pages if miser mode is on, not just some */
+$wgDisableQueryPages = false;
+/** Number of rows to cache in 'querycache' table when miser mode is on */
+$wgQueryCacheLimit = 1000;
+/** Number of links to a page required before it is deemed "wanted" */
+$wgWantedPagesThreshold = 1;
+/** Enable slow parser functions */
+$wgAllowSlowParserFunctions = false;
+
+/**
+ * To use inline TeX, you need to compile 'texvc' (in the 'math' subdirectory of
+ * the MediaWiki package and have latex, dvips, gs (ghostscript), andconvert
+ * (ImageMagick) installed and available in the PATH.
+ * Please see math/README for more information.
+ */
+$wgUseTeX = false;
+/** Location of the texvc binary */
+$wgTexvc = './math/texvc';
+
+#
+# Profiling / debugging
+#
+# You have to create a 'profiling' table in your database before using
+# profiling see maintenance/archives/patch-profiling.sql .
+#
+# To enable profiling, edit StartProfiler.php
+
+/** Only record profiling info for pages that took longer than this */
+$wgProfileLimit = 0.0;
+/** Don't put non-profiling info into log file */
+$wgProfileOnly = false;
+/** Log sums from profiling into "profiling" table in db. */
+$wgProfileToDatabase = false;
+/** If true, print a raw call tree instead of per-function report */
+$wgProfileCallTree = false;
+/** Should application server host be put into profiling table */
+$wgProfilePerHost = false;
+
+/** Settings for UDP profiler */
+$wgUDPProfilerHost = '127.0.0.1';
+$wgUDPProfilerPort = '3811';
+
+/** Detects non-matching wfProfileIn/wfProfileOut calls */
+$wgDebugProfiling = false;
+/** Output debug message on every wfProfileIn/wfProfileOut */
+$wgDebugFunctionEntry = 0;
+/** Lots of debugging output from SquidUpdate.php */
+$wgDebugSquid = false;
+
+$wgDisableCounters = false;
+$wgDisableTextSearch = false;
+$wgDisableSearchContext = false;
+/**
+ * If you've disabled search semi-permanently, this also disables updates to the
+ * table. If you ever re-enable, be sure to rebuild the search table.
+ */
+$wgDisableSearchUpdate = false;
+/** Uploads have to be specially set up to be secure */
+$wgEnableUploads = false;
+/**
+ * Show EXIF data, on by default if available.
+ * Requires PHP's EXIF extension: http://www.php.net/manual/en/ref.exif.php
+ */
+$wgShowEXIF = function_exists( 'exif_read_data' );
+
+/**
+ * Set to true to enable the upload _link_ while local uploads are disabled.
+ * Assumes that the special page link will be bounced to another server where
+ * uploads do work.
+ */
+$wgRemoteUploads = false;
+$wgDisableAnonTalk = false;
+/**
+ * Do DELETE/INSERT for link updates instead of incremental
+ */
+$wgUseDumbLinkUpdate = false;
+
+/**
+ * Anti-lock flags - bitfield
+ * ALF_PRELOAD_LINKS
+ * Preload links during link update for save
+ * ALF_PRELOAD_EXISTENCE
+ * Preload cur_id during replaceLinkHolders
+ * ALF_NO_LINK_LOCK
+ * Don't use locking reads when updating the link table. This is
+ * necessary for wikis with a high edit rate for performance
+ * reasons, but may cause link table inconsistency
+ * ALF_NO_BLOCK_LOCK
+ * As for ALF_LINK_LOCK, this flag is a necessity for high-traffic
+ * wikis.
+ */
+$wgAntiLockFlags = 0;
+
+/**
+ * Path to the GNU diff3 utility. If the file doesn't exist, edit conflicts will
+ * fall back to the old behaviour (no merging).
+ */
+$wgDiff3 = '/usr/bin/diff3';
+
+/**
+ * We can also compress text in the old revisions table. If this is set on, old
+ * revisions will be compressed on page save if zlib support is available. Any
+ * compressed revisions will be decompressed on load regardless of this setting
+ * *but will not be readable at all* if zlib support is not available.
+ */
+$wgCompressRevisions = false;
+
+/**
+ * This is the list of preferred extensions for uploading files. Uploading files
+ * with extensions not in this list will trigger a warning.
+ */
+$wgFileExtensions = array( 'png', 'gif', 'jpg', 'jpeg' );
+
+/** Files with these extensions will never be allowed as uploads. */
+$wgFileBlacklist = array(
+ # HTML may contain cookie-stealing JavaScript and web bugs
+ 'html', 'htm', 'js', 'jsb',
+ # PHP scripts may execute arbitrary code on the server
+ 'php', 'phtml', 'php3', 'php4', 'php5', 'phps',
+ # Other types that may be interpreted by some servers
+ 'shtml', 'jhtml', 'pl', 'py', 'cgi',
+ # May contain harmful executables for Windows victims
+ 'exe', 'scr', 'dll', 'msi', 'vbs', 'bat', 'com', 'pif', 'cmd', 'vxd', 'cpl' );
+
+/** Files with these mime types will never be allowed as uploads
+ * if $wgVerifyMimeType is enabled.
+ */
+$wgMimeTypeBlacklist= array(
+ # HTML may contain cookie-stealing JavaScript and web bugs
+ 'text/html', 'text/javascript', 'text/x-javascript', 'application/x-shellscript',
+ # PHP scripts may execute arbitrary code on the server
+ 'application/x-php', 'text/x-php',
+ # Other types that may be interpreted by some servers
+ 'text/x-python', 'text/x-perl', 'text/x-bash', 'text/x-sh', 'text/x-csh',
+ # Windows metafile, client-side vulnerability on some systems
+ 'application/x-msmetafile'
+);
+
+/** This is a flag to determine whether or not to check file extensions on upload. */
+$wgCheckFileExtensions = true;
+
+/**
+ * If this is turned off, users may override the warning for files not covered
+ * by $wgFileExtensions.
+ */
+$wgStrictFileExtensions = true;
+
+/** Warn if uploaded files are larger than this (in bytes)*/
+$wgUploadSizeWarning = 150 * 1024;
+
+/** For compatibility with old installations set to false */
+$wgPasswordSalt = true;
+
+/** Which namespaces should support subpages?
+ * See Language.php for a list of namespaces.
+ */
+$wgNamespacesWithSubpages = array(
+ NS_TALK => true,
+ NS_USER => true,
+ NS_USER_TALK => true,
+ NS_PROJECT_TALK => true,
+ NS_IMAGE_TALK => true,
+ NS_MEDIAWIKI_TALK => true,
+ NS_TEMPLATE_TALK => true,
+ NS_HELP_TALK => true,
+ NS_CATEGORY_TALK => true
+);
+
+$wgNamespacesToBeSearchedDefault = array(
+ NS_MAIN => true,
+);
+
+/** If set, a bold ugly notice will show up at the top of every page. */
+$wgSiteNotice = '';
+
+
+#
+# Images settings
+#
+
+/** dynamic server side image resizing ("Thumbnails") */
+$wgUseImageResize = false;
+
+/**
+ * Resizing can be done using PHP's internal image libraries or using
+ * ImageMagick or another third-party converter, e.g. GraphicMagick.
+ * These support more file formats than PHP, which only supports PNG,
+ * GIF, JPG, XBM and WBMP.
+ *
+ * Use Image Magick instead of PHP builtin functions.
+ */
+$wgUseImageMagick = false;
+/** The convert command shipped with ImageMagick */
+$wgImageMagickConvertCommand = '/usr/bin/convert';
+
+/**
+ * Use another resizing converter, e.g. GraphicMagick
+ * %s will be replaced with the source path, %d with the destination
+ * %w and %h will be replaced with the width and height
+ *
+ * An example is provided for GraphicMagick
+ * Leave as false to skip this
+ */
+#$wgCustomConvertCommand = "gm convert %s -resize %wx%h %d"
+$wgCustomConvertCommand = false;
+
+# Scalable Vector Graphics (SVG) may be uploaded as images.
+# Since SVG support is not yet standard in browsers, it is
+# necessary to rasterize SVGs to PNG as a fallback format.
+#
+# An external program is required to perform this conversion:
+$wgSVGConverters = array(
+ 'ImageMagick' => '$path/convert -background white -geometry $width $input $output',
+ 'sodipodi' => '$path/sodipodi -z -w $width -f $input -e $output',
+ 'inkscape' => '$path/inkscape -z -w $width -f $input -e $output',
+ 'batik' => 'java -Djava.awt.headless=true -jar $path/batik-rasterizer.jar -w $width -d $output $input',
+ 'rsvg' => '$path/rsvg -w$width -h$height $input $output',
+ );
+/** Pick one of the above */
+$wgSVGConverter = 'ImageMagick';
+/** If not in the executable PATH, specify */
+$wgSVGConverterPath = '';
+/** Don't scale a SVG larger than this */
+$wgSVGMaxSize = 1024;
+/**
+ * Don't thumbnail an image if it will use too much working memory
+ * Default is 50 MB if decompressed to RGBA form, which corresponds to
+ * 12.5 million pixels or 3500x3500
+ */
+$wgMaxImageArea = 1.25e7;
+/**
+ * If rendered thumbnail files are older than this timestamp, they
+ * will be rerendered on demand as if the file didn't already exist.
+ * Update if there is some need to force thumbs and SVG rasterizations
+ * to rerender, such as fixes to rendering bugs.
+ */
+$wgThumbnailEpoch = '20030516000000';
+
+/**
+ * If set, inline scaled images will still produce <img> tags ready for
+ * output instead of showing an error message.
+ *
+ * This may be useful if errors are transitory, especially if the site
+ * is configured to automatically render thumbnails on request.
+ *
+ * On the other hand, it may obscure error conditions from debugging.
+ * Enable the debug log or the 'thumbnail' log group to make sure errors
+ * are logged to a file for review.
+ */
+$wgIgnoreImageErrors = false;
+
+/**
+ * Allow thumbnail rendering on page view. If this is false, a valid
+ * thumbnail URL is still output, but no file will be created at
+ * the target location. This may save some time if you have a
+ * thumb.php or 404 handler set up which is faster than the regular
+ * webserver(s).
+ */
+$wgGenerateThumbnailOnParse = true;
+
+/** Set $wgCommandLineMode if it's not set already, to avoid notices */
+if( !isset( $wgCommandLineMode ) ) {
+ $wgCommandLineMode = false;
+}
+
+
+#
+# Recent changes settings
+#
+
+/** Log IP addresses in the recentchanges table; can be accessed only by extensions (e.g. CheckUser) or a DB admin */
+$wgPutIPinRC = true;
+
+/**
+ * Recentchanges items are periodically purged; entries older than this many
+ * seconds will go.
+ * For one week : 7 * 24 * 3600
+ */
+$wgRCMaxAge = 7 * 24 * 3600;
+
+
+# Send RC updates via UDP
+$wgRC2UDPAddress = false;
+$wgRC2UDPPort = false;
+$wgRC2UDPPrefix = '';
+
+#
+# Copyright and credits settings
+#
+
+/** RDF metadata toggles */
+$wgEnableDublinCoreRdf = false;
+$wgEnableCreativeCommonsRdf = false;
+
+/** Override for copyright metadata.
+ * TODO: these options need documentation
+ */
+$wgRightsPage = NULL;
+$wgRightsUrl = NULL;
+$wgRightsText = NULL;
+$wgRightsIcon = NULL;
+
+/** Set this to some HTML to override the rights icon with an arbitrary logo */
+$wgCopyrightIcon = NULL;
+
+/** Set this to true if you want detailed copyright information forms on Upload. */
+$wgUseCopyrightUpload = false;
+
+/** Set this to false if you want to disable checking that detailed copyright
+ * information values are not empty. */
+$wgCheckCopyrightUpload = true;
+
+/**
+ * Set this to the number of authors that you want to be credited below an
+ * article text. Set it to zero to hide the attribution block, and a negative
+ * number (like -1) to show all authors. Note that this will require 2-3 extra
+ * database hits, which can have a not insignificant impact on performance for
+ * large wikis.
+ */
+$wgMaxCredits = 0;
+
+/** If there are more than $wgMaxCredits authors, show $wgMaxCredits of them.
+ * Otherwise, link to a separate credits page. */
+$wgShowCreditsIfMax = true;
+
+
+
+/**
+ * Set this to false to avoid forcing the first letter of links to capitals.
+ * WARNING: may break links! This makes links COMPLETELY case-sensitive. Links
+ * appearing with a capital at the beginning of a sentence will *not* go to the
+ * same place as links in the middle of a sentence using a lowercase initial.
+ */
+$wgCapitalLinks = true;
+
+/**
+ * List of interwiki prefixes for wikis we'll accept as sources for
+ * Special:Import (for sysops). Since complete page history can be imported,
+ * these should be 'trusted'.
+ *
+ * If a user has the 'import' permission but not the 'importupload' permission,
+ * they will only be able to run imports through this transwiki interface.
+ */
+$wgImportSources = array();
+
+/**
+ * Optional default target namespace for interwiki imports.
+ * Can use this to create an incoming "transwiki"-style queue.
+ * Set to numeric key, not the name.
+ *
+ * Users may override this in the Special:Import dialog.
+ */
+$wgImportTargetNamespace = null;
+
+/**
+ * If set to false, disables the full-history option on Special:Export.
+ * This is currently poorly optimized for long edit histories, so is
+ * disabled on Wikimedia's sites.
+ */
+$wgExportAllowHistory = true;
+
+/**
+ * If set nonzero, Special:Export requests for history of pages with
+ * more revisions than this will be rejected. On some big sites things
+ * could get bogged down by very very long pages.
+ */
+$wgExportMaxHistory = 0;
+
+$wgExportAllowListContributors = false ;
+
+
+/** Text matching this regular expression will be recognised as spam
+ * See http://en.wikipedia.org/wiki/Regular_expression */
+$wgSpamRegex = false;
+/** Similarly if this function returns true */
+$wgFilterCallback = false;
+
+/** Go button goes straight to the edit screen if the article doesn't exist. */
+$wgGoToEdit = false;
+
+/** Allow limited user-specified HTML in wiki pages?
+ * It will be run through a whitelist for security. Set this to false if you
+ * want wiki pages to consist only of wiki markup. Note that replacements do not
+ * yet exist for all HTML constructs.*/
+$wgUserHtml = true;
+
+/** Allow raw, unchecked HTML in <html>...</html> sections.
+ * THIS IS VERY DANGEROUS on a publically editable site, so USE wgGroupPermissions
+ * TO RESTRICT EDITING to only those that you trust
+ */
+$wgRawHtml = false;
+
+/**
+ * $wgUseTidy: use tidy to make sure HTML output is sane.
+ * This should only be enabled if $wgUserHtml is true.
+ * tidy is a free tool that fixes broken HTML.
+ * See http://www.w3.org/People/Raggett/tidy/
+ * $wgTidyBin should be set to the path of the binary and
+ * $wgTidyConf to the path of the configuration file.
+ * $wgTidyOpts can include any number of parameters.
+ *
+ * $wgTidyInternal controls the use of the PECL extension to use an in-
+ * process tidy library instead of spawning a separate program.
+ * Normally you shouldn't need to override the setting except for
+ * debugging. To install, use 'pear install tidy' and add a line
+ * 'extension=tidy.so' to php.ini.
+ */
+$wgUseTidy = false;
+$wgAlwaysUseTidy = false;
+$wgTidyBin = 'tidy';
+$wgTidyConf = $IP.'/extensions/tidy/tidy.conf';
+$wgTidyOpts = '';
+$wgTidyInternal = function_exists( 'tidy_load_config' );
+
+/** See list of skins and their symbolic names in languages/Language.php */
+$wgDefaultSkin = 'monobook';
+
+/**
+ * Settings added to this array will override the default globals for the user
+ * preferences used by anonymous visitors and newly created accounts.
+ * For instance, to disable section editing links:
+ *  $wgDefaultUserOptions ['editsection'] = 0;
+ *
+ */
+$wgDefaultUserOptions = array(
+ 'quickbar' => 1,
+ 'underline' => 2,
+ 'cols' => 80,
+ 'rows' => 25,
+ 'searchlimit' => 20,
+ 'contextlines' => 5,
+ 'contextchars' => 50,
+ 'skin' => false,
+ 'math' => 1,
+ 'rcdays' => 7,
+ 'rclimit' => 50,
+ 'wllimit' => 250,
+ 'highlightbroken' => 1,
+ 'stubthreshold' => 0,
+ 'previewontop' => 1,
+ 'editsection' => 1,
+ 'editsectiononrightclick'=> 0,
+ 'showtoc' => 1,
+ 'showtoolbar' => 1,
+ 'date' => 'default',
+ 'imagesize' => 2,
+ 'thumbsize' => 2,
+ 'rememberpassword' => 0,
+ 'enotifwatchlistpages' => 0,
+ 'enotifusertalkpages' => 1,
+ 'enotifminoredits' => 0,
+ 'enotifrevealaddr' => 0,
+ 'shownumberswatching' => 1,
+ 'fancysig' => 0,
+ 'externaleditor' => 0,
+ 'externaldiff' => 0,
+ 'showjumplinks' => 1,
+ 'numberheadings' => 0,
+ 'uselivepreview' => 0,
+ 'watchlistdays' => 3.0,
+);
+
+/** Whether or not to allow and use real name fields. Defaults to true. */
+$wgAllowRealName = true;
+
+/*****************************************************************************
+ * Extensions
+ */
+
+/**
+ * A list of callback functions which are called once MediaWiki is fully initialised
+ */
+$wgExtensionFunctions = array();
+
+/**
+ * Extension functions for initialisation of skins. This is called somewhat earlier
+ * than $wgExtensionFunctions.
+ */
+$wgSkinExtensionFunctions = array();
+
+/**
+ * List of valid skin names.
+ * The key should be the name in all lower case, the value should be a display name.
+ * The default skins will be added later, by Skin::getSkinNames(). Use
+ * Skin::getSkinNames() as an accessor if you wish to have access to the full list.
+ */
+$wgValidSkinNames = array();
+
+/**
+ * Special page list.
+ * See the top of SpecialPage.php for documentation.
+ */
+$wgSpecialPages = array();
+
+/**
+ * Array mapping class names to filenames, for autoloading.
+ */
+$wgAutoloadClasses = array();
+
+/**
+ * An array of extension types and inside that their names, versions, authors
+ * and urls, note that the version and url key can be omitted.
+ *
+ * <code>
+ * $wgExtensionCredits[$type][] = array(
+ * 'name' => 'Example extension',
+ * 'version' => 1.9,
+ * 'author' => 'Foo Barstein',
+ * 'url' => 'http://wwww.example.com/Example%20Extension/',
+ * );
+ * </code>
+ *
+ * Where $type is 'specialpage', 'parserhook', or 'other'.
+ */
+$wgExtensionCredits = array();
+/*
+ * end extensions
+ ******************************************************************************/
+
+/**
+ * Allow user Javascript page?
+ * This enables a lot of neat customizations, but may
+ * increase security risk to users and server load.
+ */
+$wgAllowUserJs = false;
+
+/**
+ * Allow user Cascading Style Sheets (CSS)?
+ * This enables a lot of neat customizations, but may
+ * increase security risk to users and server load.
+ */
+$wgAllowUserCss = false;
+
+/** Use the site's Javascript page? */
+$wgUseSiteJs = true;
+
+/** Use the site's Cascading Style Sheets (CSS)? */
+$wgUseSiteCss = true;
+
+/** Filter for Special:Randompage. Part of a WHERE clause */
+$wgExtraRandompageSQL = false;
+
+/** Allow the "info" action, very inefficient at the moment */
+$wgAllowPageInfo = false;
+
+/** Maximum indent level of toc. */
+$wgMaxTocLevel = 999;
+
+/** Name of the external diff engine to use */
+$wgExternalDiffEngine = false;
+
+/** Use RC Patrolling to check for vandalism */
+$wgUseRCPatrol = true;
+
+/** Set maximum number of results to return in syndication feeds (RSS, Atom) for
+ * eg Recentchanges, Newpages. */
+$wgFeedLimit = 50;
+
+/** _Minimum_ timeout for cached Recentchanges feed, in seconds.
+ * A cached version will continue to be served out even if changes
+ * are made, until this many seconds runs out since the last render.
+ *
+ * If set to 0, feed caching is disabled. Use this for debugging only;
+ * feed generation can be pretty slow with diffs.
+ */
+$wgFeedCacheTimeout = 60;
+
+/** When generating Recentchanges RSS/Atom feed, diffs will not be generated for
+ * pages larger than this size. */
+$wgFeedDiffCutoff = 32768;
+
+
+/**
+ * Additional namespaces. If the namespaces defined in Language.php and
+ * Namespace.php are insufficient, you can create new ones here, for example,
+ * to import Help files in other languages.
+ * PLEASE NOTE: Once you delete a namespace, the pages in that namespace will
+ * no longer be accessible. If you rename it, then you can access them through
+ * the new namespace name.
+ *
+ * Custom namespaces should start at 100 to avoid conflicting with standard
+ * namespaces, and should always follow the even/odd main/talk pattern.
+ */
+#$wgExtraNamespaces =
+# array(100 => "Hilfe",
+# 101 => "Hilfe_Diskussion",
+# 102 => "Aide",
+# 103 => "Discussion_Aide"
+# );
+$wgExtraNamespaces = NULL;
+
+/**
+ * Limit images on image description pages to a user-selectable limit. In order
+ * to reduce disk usage, limits can only be selected from a list. This is the
+ * list of settings the user can choose from:
+ */
+$wgImageLimits = array (
+ array(320,240),
+ array(640,480),
+ array(800,600),
+ array(1024,768),
+ array(1280,1024),
+ array(10000,10000) );
+
+/**
+ * Adjust thumbnails on image pages according to a user setting. In order to
+ * reduce disk usage, the values can only be selected from a list. This is the
+ * list of settings the user can choose from:
+ */
+$wgThumbLimits = array(
+ 120,
+ 150,
+ 180,
+ 200,
+ 250,
+ 300
+);
+
+/**
+ * On category pages, show thumbnail gallery for images belonging to that
+ * category instead of listing them as articles.
+ */
+$wgCategoryMagicGallery = true;
+
+/**
+ * Paging limit for categories
+ */
+$wgCategoryPagingLimit = 200;
+
+/**
+ * Browser Blacklist for unicode non compliant browsers
+ * Contains a list of regexps : "/regexp/" matching problematic browsers
+ */
+$wgBrowserBlackList = array(
+ /**
+ * Netscape 2-4 detection
+ * The minor version may contain strings such as "Gold" or "SGoldC-SGI"
+ * Lots of non-netscape user agents have "compatible", so it's useful to check for that
+ * with a negative assertion. The [UIN] identifier specifies the level of security
+ * in a Netscape/Mozilla browser, checking for it rules out a number of fakers.
+ * The language string is unreliable, it is missing on NS4 Mac.
+ *
+ * Reference: http://www.psychedelix.com/agents/index.shtml
+ */
+ '/^Mozilla\/2\.[^ ]+ .*?\((?!compatible).*; [UIN]/',
+ '/^Mozilla\/3\.[^ ]+ .*?\((?!compatible).*; [UIN]/',
+ '/^Mozilla\/4\.[^ ]+ .*?\((?!compatible).*; [UIN]/',
+
+ /**
+ * MSIE on Mac OS 9 is teh sux0r, converts þ to <thorn>, ð to <eth>, Þ to <THORN> and Ð to <ETH>
+ *
+ * Known useragents:
+ * - Mozilla/4.0 (compatible; MSIE 5.0; Mac_PowerPC)
+ * - Mozilla/4.0 (compatible; MSIE 5.15; Mac_PowerPC)
+ * - Mozilla/4.0 (compatible; MSIE 5.23; Mac_PowerPC)
+ * - [...]
+ *
+ * @link http://en.wikipedia.org/w/index.php?title=User%3A%C6var_Arnfj%F6r%F0_Bjarmason%2Ftestme&diff=12356041&oldid=12355864
+ * @link http://en.wikipedia.org/wiki/Template%3AOS9
+ */
+ '/^Mozilla\/4\.0 \(compatible; MSIE \d+\.\d+; Mac_PowerPC\)/'
+);
+
+/**
+ * Fake out the timezone that the server thinks it's in. This will be used for
+ * date display and not for what's stored in the DB. Leave to null to retain
+ * your server's OS-based timezone value. This is the same as the timezone.
+ *
+ * This variable is currently used ONLY for signature formatting, not for
+ * anything else.
+ */
+# $wgLocaltimezone = 'GMT';
+# $wgLocaltimezone = 'PST8PDT';
+# $wgLocaltimezone = 'Europe/Sweden';
+# $wgLocaltimezone = 'CET';
+$wgLocaltimezone = null;
+
+/**
+ * Set an offset from UTC in minutes to use for the default timezone setting
+ * for anonymous users and new user accounts.
+ *
+ * This setting is used for most date/time displays in the software, and is
+ * overrideable in user preferences. It is *not* used for signature timestamps.
+ *
+ * You can set it to match the configured server timezone like this:
+ * $wgLocalTZoffset = date("Z") / 60;
+ *
+ * If your server is not configured for the timezone you want, you can set
+ * this in conjunction with the signature timezone and override the TZ
+ * environment variable like so:
+ * $wgLocaltimezone="Europe/Berlin";
+ * putenv("TZ=$wgLocaltimezone");
+ * $wgLocalTZoffset = date("Z") / 60;
+ *
+ * Leave at NULL to show times in universal time (UTC/GMT).
+ */
+$wgLocalTZoffset = null;
+
+
+/**
+ * When translating messages with wfMsg(), it is not always clear what should be
+ * considered UI messages and what shoud be content messages.
+ *
+ * For example, for regular wikipedia site like en, there should be only one
+ * 'mainpage', therefore when getting the link of 'mainpage', we should treate
+ * it as content of the site and call wfMsgForContent(), while for rendering the
+ * text of the link, we call wfMsg(). The code in default behaves this way.
+ * However, sites like common do offer different versions of 'mainpage' and the
+ * like for different languages. This array provides a way to override the
+ * default behavior. For example, to allow language specific mainpage and
+ * community portal, set
+ *
+ * $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
+ */
+$wgForceUIMsgAsContentMsg = array();
+
+
+/**
+ * Authentication plugin.
+ */
+$wgAuth = null;
+
+/**
+ * Global list of hooks.
+ * Add a hook by doing:
+ * $wgHooks['event_name'][] = $function;
+ * or:
+ * $wgHooks['event_name'][] = array($function, $data);
+ * or:
+ * $wgHooks['event_name'][] = array($object, 'method');
+ */
+$wgHooks = array();
+
+/**
+ * The logging system has two levels: an event type, which describes the
+ * general category and can be viewed as a named subset of all logs; and
+ * an action, which is a specific kind of event that can exist in that
+ * log type.
+ */
+$wgLogTypes = array( '',
+ 'block',
+ 'protect',
+ 'rights',
+ 'delete',
+ 'upload',
+ 'move',
+ 'import' );
+
+/**
+ * Lists the message key string for each log type. The localized messages
+ * will be listed in the user interface.
+ *
+ * Extensions with custom log types may add to this array.
+ */
+$wgLogNames = array(
+ '' => 'log',
+ 'block' => 'blocklogpage',
+ 'protect' => 'protectlogpage',
+ 'rights' => 'rightslog',
+ 'delete' => 'dellogpage',
+ 'upload' => 'uploadlogpage',
+ 'move' => 'movelogpage',
+ 'import' => 'importlogpage' );
+
+/**
+ * Lists the message key string for descriptive text to be shown at the
+ * top of each log type.
+ *
+ * Extensions with custom log types may add to this array.
+ */
+$wgLogHeaders = array(
+ '' => 'alllogstext',
+ 'block' => 'blocklogtext',
+ 'protect' => 'protectlogtext',
+ 'rights' => 'rightslogtext',
+ 'delete' => 'dellogpagetext',
+ 'upload' => 'uploadlogpagetext',
+ 'move' => 'movelogpagetext',
+ 'import' => 'importlogpagetext', );
+
+/**
+ * Lists the message key string for formatting individual events of each
+ * type and action when listed in the logs.
+ *
+ * Extensions with custom log types may add to this array.
+ */
+$wgLogActions = array(
+ 'block/block' => 'blocklogentry',
+ 'block/unblock' => 'unblocklogentry',
+ 'protect/protect' => 'protectedarticle',
+ 'protect/unprotect' => 'unprotectedarticle',
+ 'rights/rights' => 'rightslogentry',
+ 'delete/delete' => 'deletedarticle',
+ 'delete/restore' => 'undeletedarticle',
+ 'delete/revision' => 'revdelete-logentry',
+ 'upload/upload' => 'uploadedimage',
+ 'upload/revert' => 'uploadedimage',
+ 'move/move' => '1movedto2',
+ 'move/move_redir' => '1movedto2_redir',
+ 'import/upload' => 'import-logentry-upload',
+ 'import/interwiki' => 'import-logentry-interwiki' );
+
+/**
+ * Experimental preview feature to fetch rendered text
+ * over an XMLHttpRequest from JavaScript instead of
+ * forcing a submit and reload of the whole page.
+ * Leave disabled unless you're testing it.
+ */
+$wgLivePreview = false;
+
+/**
+ * Disable the internal MySQL-based search, to allow it to be
+ * implemented by an extension instead.
+ */
+$wgDisableInternalSearch = false;
+
+/**
+ * Set this to a URL to forward search requests to some external location.
+ * If the URL includes '$1', this will be replaced with the URL-encoded
+ * search term.
+ *
+ * For example, to forward to Google you'd have something like:
+ * $wgSearchForwardUrl = 'http://www.google.com/search?q=$1' .
+ * '&domains=http://example.com' .
+ * '&sitesearch=http://example.com' .
+ * '&ie=utf-8&oe=utf-8';
+ */
+$wgSearchForwardUrl = null;
+
+/**
+ * If true, external URL links in wiki text will be given the
+ * rel="nofollow" attribute as a hint to search engines that
+ * they should not be followed for ranking purposes as they
+ * are user-supplied and thus subject to spamming.
+ */
+$wgNoFollowLinks = true;
+
+/**
+ * Namespaces in which $wgNoFollowLinks doesn't apply.
+ * See Language.php for a list of namespaces.
+ */
+$wgNoFollowNsExceptions = array();
+
+/**
+ * Robot policies per namespaces.
+ * The default policy is 'index,follow', the array is made of namespace
+ * constants as defined in includes/Defines.php
+ * Example:
+ * $wgNamespaceRobotPolicies = array( NS_TALK => 'noindex' );
+ */
+$wgNamespaceRobotPolicies = array();
+
+/**
+ * Specifies the minimal length of a user password. If set to
+ * 0, empty passwords are allowed.
+ */
+$wgMinimalPasswordLength = 0;
+
+/**
+ * Activate external editor interface for files and pages
+ * See http://meta.wikimedia.org/wiki/Help:External_editors
+ */
+$wgUseExternalEditor = true;
+
+/** Whether or not to sort special pages in Special:Specialpages */
+
+$wgSortSpecialPages = true;
+
+/**
+ * Specify the name of a skin that should not be presented in the
+ * list of available skins.
+ * Use for blacklisting a skin which you do not want to remove
+ * from the .../skins/ directory
+ */
+$wgSkipSkin = '';
+$wgSkipSkins = array(); # More of the same
+
+/**
+ * Array of disabled article actions, e.g. view, edit, dublincore, delete, etc.
+ */
+$wgDisabledActions = array();
+
+/**
+ * Disable redirects to special pages and interwiki redirects, which use a 302 and have no "redirected from" link
+ */
+$wgDisableHardRedirects = false;
+
+/**
+ * Use http.dnsbl.sorbs.net to check for open proxies
+ */
+$wgEnableSorbs = false;
+$wgSorbsUrl = 'http.dnsbl.sorbs.net.';
+
+/**
+ * Proxy whitelist, list of addresses that are assumed to be non-proxy despite what the other
+ * methods might say
+ */
+$wgProxyWhitelist = array();
+
+/**
+ * Simple rate limiter options to brake edit floods.
+ * Maximum number actions allowed in the given number of seconds;
+ * after that the violating client receives HTTP 500 error pages
+ * until the period elapses.
+ *
+ * array( 4, 60 ) for a maximum of 4 hits in 60 seconds.
+ *
+ * This option set is experimental and likely to change.
+ * Requires memcached.
+ */
+$wgRateLimits = array(
+ 'edit' => array(
+ 'anon' => null, // for any and all anonymous edits (aggregate)
+ 'user' => null, // for each logged-in user
+ 'newbie' => null, // for each recent account; overrides 'user'
+ 'ip' => null, // for each anon and recent account
+ 'subnet' => null, // ... with final octet removed
+ ),
+ 'move' => array(
+ 'user' => null,
+ 'newbie' => null,
+ 'ip' => null,
+ 'subnet' => null,
+ ),
+ 'mailpassword' => array(
+ 'anon' => NULL,
+ ),
+ );
+
+/**
+ * Set to a filename to log rate limiter hits.
+ */
+$wgRateLimitLog = null;
+
+/**
+ * Array of groups which should never trigger the rate limiter
+ */
+$wgRateLimitsExcludedGroups = array( 'sysop', 'bureaucrat' );
+
+/**
+ * On Special:Unusedimages, consider images "used", if they are put
+ * into a category. Default (false) is not to count those as used.
+ */
+$wgCountCategorizedImagesAsUsed = false;
+
+/**
+ * External stores allow including content
+ * from non database sources following URL links
+ *
+ * Short names of ExternalStore classes may be specified in an array here:
+ * $wgExternalStores = array("http","file","custom")...
+ *
+ * CAUTION: Access to database might lead to code execution
+ */
+$wgExternalStores = false;
+
+/**
+ * An array of external mysql servers, e.g.
+ * $wgExternalServers = array( 'cluster1' => array( 'srv28', 'srv29', 'srv30' ) );
+ */
+$wgExternalServers = array();
+
+/**
+ * The place to put new revisions, false to put them in the local text table.
+ * Part of a URL, e.g. DB://cluster1
+ *
+ * Can be an array instead of a single string, to enable data distribution. Keys
+ * must be consecutive integers, starting at zero. Example:
+ *
+ * $wgDefaultExternalStore = array( 'DB://cluster1', 'DB://cluster2' );
+ *
+ */
+$wgDefaultExternalStore = false;
+
+/**
+ * Revision text may be cached in $wgMemc to reduce load on external storage
+ * servers and object extraction overhead for frequently-loaded revisions.
+ *
+ * Set to 0 to disable, or number of seconds before cache expiry.
+ */
+$wgRevisionCacheExpiry = 0;
+
+/**
+* list of trusted media-types and mime types.
+* Use the MEDIATYPE_xxx constants to represent media types.
+* This list is used by Image::isSafeFile
+*
+* Types not listed here will have a warning about unsafe content
+* displayed on the images description page. It would also be possible
+* to use this for further restrictions, like disabling direct
+* [[media:...]] links for non-trusted formats.
+*/
+$wgTrustedMediaFormats= array(
+ MEDIATYPE_BITMAP, //all bitmap formats
+ MEDIATYPE_AUDIO, //all audio formats
+ MEDIATYPE_VIDEO, //all plain video formats
+ "image/svg", //svg (only needed if inline rendering of svg is not supported)
+ "application/pdf", //PDF files
+ #"application/x-shockwave-flash", //flash/shockwave movie
+);
+
+/**
+ * Allow special page inclusions such as {{Special:Allpages}}
+ */
+$wgAllowSpecialInclusion = true;
+
+/**
+ * Timeout for HTTP requests done via CURL
+ */
+$wgHTTPTimeout = 3;
+
+/**
+ * Proxy to use for CURL requests.
+ */
+$wgHTTPProxy = false;
+
+/**
+ * Enable interwiki transcluding. Only when iw_trans=1.
+ */
+$wgEnableScaryTranscluding = false;
+/**
+ * Expiry time for interwiki transclusion
+ */
+$wgTranscludeCacheExpiry = 3600;
+
+/**
+ * Support blog-style "trackbacks" for articles. See
+ * http://www.sixapart.com/pronet/docs/trackback_spec for details.
+ */
+$wgUseTrackbacks = false;
+
+/**
+ * Enable filtering of categories in Recentchanges
+ */
+$wgAllowCategorizedRecentChanges = false ;
+
+/**
+ * Number of jobs to perform per request. May be less than one in which case
+ * jobs are performed probabalistically. If this is zero, jobs will not be done
+ * during ordinary apache requests. In this case, maintenance/runJobs.php should
+ * be run periodically.
+ */
+$wgJobRunRate = 1;
+
+/**
+ * Number of rows to update per job
+ */
+$wgUpdateRowsPerJob = 500;
+
+/**
+ * Number of rows to update per query
+ */
+$wgUpdateRowsPerQuery = 10;
+
+/**
+ * Enable AJAX framework
+ */
+$wgUseAjax = false;
+
+/**
+ * Enable auto suggestion for the search bar
+ * Requires $wgUseAjax to be true too.
+ * Causes wfSajaxSearch to be added to $wgAjaxExportList
+ */
+$wgAjaxSearch = false;
+
+/**
+ * List of Ajax-callable functions.
+ * Extensions acting as Ajax callbacks must register here
+ */
+$wgAjaxExportList = array( );
+
+/**
+ * Enable watching/unwatching pages using AJAX.
+ * Requires $wgUseAjax to be true too.
+ * Causes wfAjaxWatch to be added to $wgAjaxExportList
+ */
+$wgAjaxWatch = false;
+
+/**
+ * Allow DISPLAYTITLE to change title display
+ */
+$wgAllowDisplayTitle = false ;
+
+/**
+ * Array of usernames which may not be registered or logged in from
+ * Maintenance scripts can still use these
+ */
+$wgReservedUsernames = array(
+ 'MediaWiki default', // Default 'Main Page' and MediaWiki: message pages
+ 'Conversion script', // Used for the old Wikipedia software upgrade
+ 'Maintenance script', // ... maintenance/edit.php uses this?
+ 'Template namespace initialisation script', // Used in 1.2->1.3 upgrade
+);
+
+/**
+ * MediaWiki will reject HTMLesque tags in uploaded files due to idiotic browsers which can't
+ * perform basic stuff like MIME detection and which are vulnerable to further idiots uploading
+ * crap files as images. When this directive is on, <title> will be allowed in files with
+ * an "image/svg" MIME type. You should leave this disabled if your web server is misconfigured
+ * and doesn't send appropriate MIME types for SVG images.
+ */
+$wgAllowTitlesInSVG = false;
+
+/**
+ * Array of namespaces which can be deemed to contain valid "content", as far
+ * as the site statistics are concerned. Useful if additional namespaces also
+ * contain "content" which should be considered when generating a count of the
+ * number of articles in the wiki.
+ */
+$wgContentNamespaces = array( NS_MAIN );
+
+/**
+ * Maximum amount of virtual memory available to shell processes under linux, in KB.
+ */
+$wgMaxShellMemory = 102400;
+
+/**
+ * Maximum file size created by shell processes under linux, in KB
+ * ImageMagick convert for example can be fairly hungry for scratch space
+ */
+$wgMaxShellFileSize = 102400;
+
+/**
+ * DJVU settings
+ * Path of the djvutoxml executable
+ * Enable this and $wgDjvuRenderer to enable djvu rendering
+ */
+# $wgDjvuToXML = 'djvutoxml';
+$wgDjvuToXML = null;
+
+/**
+ * Path of the ddjvu DJVU renderer
+ * Enable this and $wgDjvuToXML to enable djvu rendering
+ */
+# $wgDjvuRenderer = 'ddjvu';
+$wgDjvuRenderer = null;
+
+/**
+ * Path of the DJVU post processor
+ * May include command line options
+ * Default: ppmtojpeg, since ddjvu generates ppm output
+ */
+$wgDjvuPostProcessor = 'ppmtojpeg';
+
+/**
+* Enable direct access to the data API
+* through api.php
+*/
+$wgEnableAPI = true;
+$wgEnableWriteAPI = false;
+
+/**
+ * Parser test suite files to be run by parserTests.php when no specific
+ * filename is passed to it.
+ *
+ * Extensions may add their own tests to this array, or site-local tests
+ * may be added via LocalSettings.php
+ *
+ * Use full paths.
+ */
+$wgParserTestFiles = array(
+ "$IP/maintenance/parserTests.txt",
+);
+
+/**
+ * Break out of framesets. This can be used to prevent external sites from
+ * framing your site with ads.
+ */
+$wgBreakFrames = false;
+
+/**
+ * Set this to an array of special page names to prevent
+ * maintenance/updateSpecialPages.php from updating those pages.
+ */
+$wgDisableQueryPageUpdate = false;
+
+?>
diff --git a/includes/Defines.php b/includes/Defines.php
new file mode 100644
index 000000000000..84bc44950f69
--- /dev/null
+++ b/includes/Defines.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * A few constants that might be needed during LocalSettings.php
+ * @package MediaWiki
+ */
+
+/**
+ * Version constants for the benefit of extensions
+ */
+define( 'MW_SPECIALPAGE_VERSION', 2 );
+
+/**#@+
+ * Database related constants
+ */
+define( 'DBO_DEBUG', 1 );
+define( 'DBO_NOBUFFER', 2 );
+define( 'DBO_IGNORE', 4 );
+define( 'DBO_TRX', 8 );
+define( 'DBO_DEFAULT', 16 );
+define( 'DBO_PERSISTENT', 32 );
+/**#@-*/
+
+# Valid database indexes
+# Operation-based indexes
+define( 'DB_SLAVE', -1 ); # Read from the slave (or only server)
+define( 'DB_MASTER', -2 ); # Write to master (or only server)
+define( 'DB_LAST', -3 ); # Whatever database was used last
+
+# Obsolete aliases
+define( 'DB_READ', -1 );
+define( 'DB_WRITE', -2 );
+
+
+/**#@+
+ * Virtual namespaces; don't appear in the page database
+ */
+define('NS_MEDIA', -2);
+define('NS_SPECIAL', -1);
+/**#@-*/
+
+/**#@+
+ * Real namespaces
+ *
+ * Number 100 and beyond are reserved for custom namespaces;
+ * DO NOT assign standard namespaces at 100 or beyond.
+ * DO NOT Change integer values as they are most probably hardcoded everywhere
+ * see bug #696 which talked about that.
+ */
+define('NS_MAIN', 0);
+define('NS_TALK', 1);
+define('NS_USER', 2);
+define('NS_USER_TALK', 3);
+define('NS_PROJECT', 4);
+define('NS_PROJECT_TALK', 5);
+define('NS_IMAGE', 6);
+define('NS_IMAGE_TALK', 7);
+define('NS_MEDIAWIKI', 8);
+define('NS_MEDIAWIKI_TALK', 9);
+define('NS_TEMPLATE', 10);
+define('NS_TEMPLATE_TALK', 11);
+define('NS_HELP', 12);
+define('NS_HELP_TALK', 13);
+define('NS_CATEGORY', 14);
+define('NS_CATEGORY_TALK', 15);
+/**#@-*/
+
+/**
+ * Available feeds objects
+ * Should probably only be defined when a page is syndicated ie when
+ * $wgOut->isSyndicated() is true
+ */
+$wgFeedClasses = array(
+ 'rss' => 'RSSFeed',
+ 'atom' => 'AtomFeed',
+);
+
+/**#@+
+ * Maths constants
+ */
+define( 'MW_MATH_PNG', 0 );
+define( 'MW_MATH_SIMPLE', 1 );
+define( 'MW_MATH_HTML', 2 );
+define( 'MW_MATH_SOURCE', 3 );
+define( 'MW_MATH_MODERN', 4 );
+define( 'MW_MATH_MATHML', 5 );
+/**#@-*/
+
+/**
+ * User rights list
+ * @deprecated
+ */
+$wgAvailableRights = array(
+ 'block',
+ 'bot',
+ 'createaccount',
+ 'delete',
+ 'edit',
+ 'editinterface',
+ 'import',
+ 'importupload',
+ 'move',
+ 'patrol',
+ 'protect',
+ 'read',
+ 'rollback',
+ 'siteadmin',
+ 'unwatchedpages',
+ 'upload',
+ 'userrights',
+);
+
+/**#@+
+ * Cache type
+ */
+define( 'CACHE_ANYTHING', -1 ); // Use anything, as long as it works
+define( 'CACHE_NONE', 0 ); // Do not cache
+define( 'CACHE_DB', 1 ); // Store cache objects in the DB
+define( 'CACHE_MEMCACHED', 2 ); // MemCached, must specify servers in $wgMemCacheServers
+define( 'CACHE_ACCEL', 3 ); // eAccelerator or Turck, whichever is available
+define( 'CACHE_DBA', 4 ); // Use PHP's DBA extension to store in a DBM-style database
+/**#@-*/
+
+
+
+/**#@+
+ * Media types.
+ * This defines constants for the value returned by Image::getMediaType()
+ */
+define( 'MEDIATYPE_UNKNOWN', 'UNKNOWN' ); // unknown format
+define( 'MEDIATYPE_BITMAP', 'BITMAP' ); // some bitmap image or image source (like psd, etc). Can't scale up.
+define( 'MEDIATYPE_DRAWING', 'DRAWING' ); // some vector drawing (SVG, WMF, PS, ...) or image source (oo-draw, etc). Can scale up.
+define( 'MEDIATYPE_AUDIO', 'AUDIO' ); // simple audio file (ogg, mp3, wav, midi, whatever)
+define( 'MEDIATYPE_VIDEO', 'VIDEO' ); // simple video file (ogg, mpg, etc; no not include formats here that may contain executable sections or scripts!)
+define( 'MEDIATYPE_MULTIMEDIA', 'MULTIMEDIA' ); // Scriptable Multimedia (flash, advanced video container formats, etc)
+define( 'MEDIATYPE_OFFICE', 'OFFICE' ); // Office Documents, Spreadsheets (office formats possibly containing apples, scripts, etc)
+define( 'MEDIATYPE_TEXT', 'TEXT' ); // Plain text (possibly containing program code or scripts)
+define( 'MEDIATYPE_EXECUTABLE', 'EXECUTABLE' ); // binary executable
+define( 'MEDIATYPE_ARCHIVE', 'ARCHIVE' ); // archive file (zip, tar, etc)
+/**#@-*/
+
+/**#@+
+ * Antivirus result codes, for use in $wgAntivirusSetup.
+ */
+define( 'AV_NO_VIRUS', 0 ); #scan ok, no virus found
+define( 'AV_VIRUS_FOUND', 1 ); #virus found!
+define( 'AV_SCAN_ABORTED', -1 ); #scan aborted, the file is probably imune
+define( 'AV_SCAN_FAILED', false ); #scan failed (scanner not found or error in scanner)
+/**#@-*/
+
+/**#@+
+ * Anti-lock flags
+ * See DefaultSettings.php for a description
+ */
+define( 'ALF_PRELOAD_LINKS', 1 );
+define( 'ALF_PRELOAD_EXISTENCE', 2 );
+define( 'ALF_NO_LINK_LOCK', 4 );
+define( 'ALF_NO_BLOCK_LOCK', 8 );
+/**#@-*/
+
+/**#@+
+ * Date format selectors; used in user preference storage and by
+ * Language::date() and co.
+ */
+/*define( 'MW_DATE_DEFAULT', '0' );
+define( 'MW_DATE_MDY', '1' );
+define( 'MW_DATE_DMY', '2' );
+define( 'MW_DATE_YMD', '3' );
+define( 'MW_DATE_ISO', 'ISO 8601' );*/
+define( 'MW_DATE_DEFAULT', 'default' );
+define( 'MW_DATE_MDY', 'mdy' );
+define( 'MW_DATE_DMY', 'dmy' );
+define( 'MW_DATE_YMD', 'ymd' );
+define( 'MW_DATE_ISO', 'ISO 8601' );
+/**#@-*/
+
+/**#@+
+ * RecentChange type identifiers
+ * This may be obsolete; log items are now used for moves?
+ */
+define( 'RC_EDIT', 0);
+define( 'RC_NEW', 1);
+define( 'RC_MOVE', 2);
+define( 'RC_LOG', 3);
+define( 'RC_MOVE_OVER_REDIRECT', 4);
+/**#@-*/
+
+/**#@+
+ * Article edit flags
+ */
+define( 'EDIT_NEW', 1 );
+define( 'EDIT_UPDATE', 2 );
+define( 'EDIT_MINOR', 4 );
+define( 'EDIT_SUPPRESS_RC', 8 );
+define( 'EDIT_FORCE_BOT', 16 );
+define( 'EDIT_DEFER_UPDATES', 32 );
+define( 'EDIT_AUTOSUMMARY', 64 );
+/**#@-*/
+
+/**
+ * Flags for Database::makeList()
+ * These are also available as Database class constants
+ */
+define( 'LIST_COMMA', 0 );
+define( 'LIST_AND', 1 );
+define( 'LIST_SET', 2 );
+define( 'LIST_NAMES', 3);
+define( 'LIST_OR', 4);
+
+
+?>
diff --git a/includes/DifferenceEngine.php b/includes/DifferenceEngine.php
new file mode 100644
index 000000000000..a72f01535fca
--- /dev/null
+++ b/includes/DifferenceEngine.php
@@ -0,0 +1,1791 @@
+<?php
+/**
+ * See diff.doc
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+
+/**
+ * @todo document
+ * @public
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class DifferenceEngine {
+ /**#@+
+ * @private
+ */
+ var $mOldid, $mNewid, $mTitle;
+ var $mOldtitle, $mNewtitle, $mPagetitle;
+ var $mOldtext, $mNewtext;
+ var $mOldPage, $mNewPage;
+ var $mRcidMarkPatrolled;
+ var $mOldRev, $mNewRev;
+ var $mRevisionsLoaded = false; // Have the revisions been loaded
+ var $mTextLoaded = 0; // How many text blobs have been loaded, 0, 1 or 2?
+ /**#@-*/
+
+ /**
+ * Constructor
+ * @param $titleObj Title object that the diff is associated with
+ * @param $old Integer: old ID we want to show and diff with.
+ * @param $new String: either 'prev' or 'next'.
+ * @param $rcid Integer: ??? FIXME (default 0)
+ */
+ function DifferenceEngine( $titleObj = null, $old = 0, $new = 0, $rcid = 0 ) {
+ $this->mTitle = $titleObj;
+ wfDebug("DifferenceEngine old '$old' new '$new' rcid '$rcid'\n");
+
+ if ( 'prev' === $new ) {
+ # Show diff between revision $old and the previous one.
+ # Get previous one from DB.
+ #
+ $this->mNewid = intval($old);
+
+ $this->mOldid = $this->mTitle->getPreviousRevisionID( $this->mNewid );
+
+ } elseif ( 'next' === $new ) {
+ # Show diff between revision $old and the previous one.
+ # Get previous one from DB.
+ #
+ $this->mOldid = intval($old);
+ $this->mNewid = $this->mTitle->getNextRevisionID( $this->mOldid );
+ if ( false === $this->mNewid ) {
+ # if no result, NewId points to the newest old revision. The only newer
+ # revision is cur, which is "0".
+ $this->mNewid = 0;
+ }
+
+ } else {
+ $this->mOldid = intval($old);
+ $this->mNewid = intval($new);
+ }
+ $this->mRcidMarkPatrolled = intval($rcid); # force it to be an integer
+ }
+
+ function showDiffPage() {
+ global $wgUser, $wgOut, $wgContLang, $wgUseExternalEditor, $wgUseRCPatrol;
+ $fname = 'DifferenceEngine::showDiffPage';
+ wfProfileIn( $fname );
+
+ # If external diffs are enabled both globally and for the user,
+ # we'll use the application/x-external-editor interface to call
+ # an external diff tool like kompare, kdiff3, etc.
+ if($wgUseExternalEditor && $wgUser->getOption('externaldiff')) {
+ global $wgInputEncoding,$wgServer,$wgScript,$wgLang;
+ $wgOut->disable();
+ header ( "Content-type: application/x-external-editor; charset=".$wgInputEncoding );
+ $url1=$this->mTitle->getFullURL("action=raw&oldid=".$this->mOldid);
+ $url2=$this->mTitle->getFullURL("action=raw&oldid=".$this->mNewid);
+ $special=$wgLang->getNsText(NS_SPECIAL);
+ $control=<<<CONTROL
+[Process]
+Type=Diff text
+Engine=MediaWiki
+Script={$wgServer}{$wgScript}
+Special namespace={$special}
+
+[File]
+Extension=wiki
+URL=$url1
+
+[File 2]
+Extension=wiki
+URL=$url2
+CONTROL;
+ echo($control);
+ return;
+ }
+
+ $wgOut->setArticleFlag( false );
+ if ( ! $this->loadRevisionData() ) {
+ $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, {$this->mNewid})";
+ $mtext = wfMsg( 'missingarticle', "<nowiki>$t</nowiki>" );
+ $wgOut->setPagetitle( wfMsg( 'errorpagetitle' ) );
+ $wgOut->addWikitext( $mtext );
+ wfProfileOut( $fname );
+ return;
+ }
+
+ wfRunHooks( 'DiffViewHeader', array( $this, $this->mOldRev, $this->mNewRev ) );
+
+ if ( $this->mNewRev->isCurrent() ) {
+ $wgOut->setArticleFlag( true );
+ }
+
+ # mOldid is false if the difference engine is called with a "vague" query for
+ # a diff between a version V and its previous version V' AND the version V
+ # is the first version of that article. In that case, V' does not exist.
+ if ( $this->mOldid === false ) {
+ $this->showFirstRevision();
+ wfProfileOut( $fname );
+ return;
+ }
+
+ $wgOut->suppressQuickbar();
+
+ $oldTitle = $this->mOldPage->getPrefixedText();
+ $newTitle = $this->mNewPage->getPrefixedText();
+ if( $oldTitle == $newTitle ) {
+ $wgOut->setPageTitle( $newTitle );
+ } else {
+ $wgOut->setPageTitle( $oldTitle . ', ' . $newTitle );
+ }
+ $wgOut->setSubtitle( wfMsg( 'difference' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ if ( !( $this->mOldPage->userCanRead() && $this->mNewPage->userCanRead() ) ) {
+ $wgOut->loginToUse();
+ $wgOut->output();
+ wfProfileOut( $fname );
+ exit;
+ }
+
+ $sk = $wgUser->getSkin();
+
+ if ( $this->mNewRev->isCurrent() && $wgUser->isAllowed('rollback') ) {
+ $rollback = '&nbsp;&nbsp;&nbsp;' . $sk->generateRollback( $this->mNewRev );
+ } else {
+ $rollback = '';
+ }
+ if( $wgUseRCPatrol && $this->mRcidMarkPatrolled != 0 && $wgUser->isAllowed( 'patrol' ) ) {
+ $patrol = ' [' . $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'markaspatrolleddiff' ), "action=markpatrolled&rcid={$this->mRcidMarkPatrolled}" ) . ']';
+ } else {
+ $patrol = '';
+ }
+
+ $prevlink = $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'previousdiff' ),
+ 'diff=prev&oldid='.$this->mOldid, '', '', 'id="differences-prevlink"' );
+ if ( $this->mNewRev->isCurrent() ) {
+ $nextlink = '&nbsp;';
+ } else {
+ $nextlink = $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'nextdiff' ),
+ 'diff=next&oldid='.$this->mNewid, '', '', 'id="differences-nextlink"' );
+ }
+
+ $oldminor = '';
+ $newminor = '';
+
+ if ($this->mOldRev->mMinorEdit == 1) {
+ $oldminor = wfElement( 'span', array( 'class' => 'minor' ),
+ wfMsg( 'minoreditletter') ) . ' ';
+ }
+
+ if ($this->mNewRev->mMinorEdit == 1) {
+ $newminor = wfElement( 'span', array( 'class' => 'minor' ),
+ wfMsg( 'minoreditletter') ) . ' ';
+ }
+
+ $oldHeader = "<strong>{$this->mOldtitle}</strong><br />" .
+ $sk->revUserTools( $this->mOldRev ) . "<br />" .
+ $oldminor . $sk->revComment( $this->mOldRev, true ) . "<br />" .
+ $prevlink;
+ $newHeader = "<strong>{$this->mNewtitle}</strong><br />" .
+ $sk->revUserTools( $this->mNewRev ) . " $rollback<br />" .
+ $newminor . $sk->revComment( $this->mNewRev, true ) . "<br />" .
+ $nextlink . $patrol;
+
+ $this->showDiff( $oldHeader, $newHeader );
+ $wgOut->addHTML( "<hr /><h2>{$this->mPagetitle}</h2>\n" );
+
+ if( !$this->mNewRev->isCurrent() ) {
+ $oldEditSectionSetting = $wgOut->parserOptions()->setEditSection( false );
+ }
+
+ $this->loadNewText();
+ if( is_object( $this->mNewRev ) ) {
+ $wgOut->setRevisionId( $this->mNewRev->getId() );
+ }
+ $wgOut->addSecondaryWikiText( $this->mNewtext );
+
+ if( !$this->mNewRev->isCurrent() ) {
+ $wgOut->parserOptions()->setEditSection( $oldEditSectionSetting );
+ }
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Show the first revision of an article. Uses normal diff headers in
+ * contrast to normal "old revision" display style.
+ */
+ function showFirstRevision() {
+ global $wgOut, $wgUser;
+
+ $fname = 'DifferenceEngine::showFirstRevision';
+ wfProfileIn( $fname );
+
+ # Get article text from the DB
+ #
+ if ( ! $this->loadNewText() ) {
+ $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, " .
+ "{$this->mNewid})";
+ $mtext = wfMsg( 'missingarticle', "<nowiki>$t</nowiki>" );
+ $wgOut->setPagetitle( wfMsg( 'errorpagetitle' ) );
+ $wgOut->addWikitext( $mtext );
+ wfProfileOut( $fname );
+ return;
+ }
+ if ( $this->mNewRev->isCurrent() ) {
+ $wgOut->setArticleFlag( true );
+ }
+
+ # Check if user is allowed to look at this page. If not, bail out.
+ #
+ if ( !( $this->mTitle->userCanRead() ) ) {
+ $wgOut->loginToUse();
+ $wgOut->output();
+ wfProfileOut( $fname );
+ exit;
+ }
+
+ # Prepare the header box
+ #
+ $sk = $wgUser->getSkin();
+
+ $nextlink = $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'nextdiff' ), 'diff=next&oldid='.$this->mNewid, '', '', 'id="differences-nextlink"' );
+ $header = "<div class=\"firstrevisionheader\" style=\"text-align: center\"><strong>{$this->mOldtitle}</strong><br />" .
+ $sk->revUserTools( $this->mNewRev ) . "<br />" .
+ $sk->revComment( $this->mNewRev ) . "<br />" .
+ $nextlink . "</div>\n";
+
+ $wgOut->addHTML( $header );
+
+ $wgOut->setSubtitle( wfMsg( 'difference' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+
+ # Show current revision
+ #
+ $wgOut->addHTML( "<hr /><h2>{$this->mPagetitle}</h2>\n" );
+ if( is_object( $this->mNewRev ) ) {
+ $wgOut->setRevisionId( $this->mNewRev->getId() );
+ }
+ $wgOut->addSecondaryWikiText( $this->mNewtext );
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Get the diff text, send it to $wgOut
+ * Returns false if the diff could not be generated, otherwise returns true
+ */
+ function showDiff( $otitle, $ntitle ) {
+ global $wgOut;
+ $diff = $this->getDiff( $otitle, $ntitle );
+ if ( $diff === false ) {
+ $wgOut->addWikitext( wfMsg( 'missingarticle', "<nowiki>(fixme, bug)</nowiki>" ) );
+ return false;
+ } else {
+ $wgOut->addHTML( $diff );
+ return true;
+ }
+ }
+
+ /**
+ * Get diff table, including header
+ * Note that the interface has changed, it's no longer static.
+ * Returns false on error
+ */
+ function getDiff( $otitle, $ntitle ) {
+ $body = $this->getDiffBody();
+ if ( $body === false ) {
+ return false;
+ } else {
+ $multi = $this->getMultiNotice();
+ return $this->addHeader( $body, $otitle, $ntitle, $multi );
+ }
+ }
+
+ /**
+ * Get the diff table body, without header
+ * Results are cached
+ * Returns false on error
+ */
+ function getDiffBody() {
+ global $wgMemc;
+ $fname = 'DifferenceEngine::getDiffBody';
+ wfProfileIn( $fname );
+
+ // Cacheable?
+ $key = false;
+ if ( $this->mOldid && $this->mNewid ) {
+ // Try cache
+ $key = wfMemcKey( 'diff', 'oldid', $this->mOldid, 'newid', $this->mNewid );
+ $difftext = $wgMemc->get( $key );
+ if ( $difftext ) {
+ wfIncrStats( 'diff_cache_hit' );
+ $difftext = $this->localiseLineNumbers( $difftext );
+ $difftext .= "\n<!-- diff cache key $key -->\n";
+ wfProfileOut( $fname );
+ return $difftext;
+ }
+ }
+
+ if ( !$this->loadText() ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ $difftext = $this->generateDiffBody( $this->mOldtext, $this->mNewtext );
+
+ // Save to cache for 7 days
+ if ( $key !== false && $difftext !== false ) {
+ wfIncrStats( 'diff_cache_miss' );
+ $wgMemc->set( $key, $difftext, 7*86400 );
+ } else {
+ wfIncrStats( 'diff_uncacheable' );
+ }
+ // Replace line numbers with the text in the user's language
+ if ( $difftext !== false ) {
+ $difftext = $this->localiseLineNumbers( $difftext );
+ }
+ wfProfileOut( $fname );
+ return $difftext;
+ }
+
+ /**
+ * Generate a diff, no caching
+ * $otext and $ntext must be already segmented
+ */
+ function generateDiffBody( $otext, $ntext ) {
+ global $wgExternalDiffEngine, $wgContLang;
+ $fname = 'DifferenceEngine::generateDiffBody';
+
+ $otext = str_replace( "\r\n", "\n", $otext );
+ $ntext = str_replace( "\r\n", "\n", $ntext );
+
+ if ( $wgExternalDiffEngine == 'wikidiff' ) {
+ # For historical reasons, external diff engine expects
+ # input text to be HTML-escaped already
+ $otext = htmlspecialchars ( $wgContLang->segmentForDiff( $otext ) );
+ $ntext = htmlspecialchars ( $wgContLang->segmentForDiff( $ntext ) );
+ if( !function_exists( 'wikidiff_do_diff' ) ) {
+ dl('php_wikidiff.so');
+ }
+ return $wgContLang->unsegementForDiff( wikidiff_do_diff( $otext, $ntext, 2 ) );
+ }
+
+ if ( $wgExternalDiffEngine == 'wikidiff2' ) {
+ # Better external diff engine, the 2 may some day be dropped
+ # This one does the escaping and segmenting itself
+ if ( !function_exists( 'wikidiff2_do_diff' ) ) {
+ wfProfileIn( "$fname-dl" );
+ @dl('php_wikidiff2.so');
+ wfProfileOut( "$fname-dl" );
+ }
+ if ( function_exists( 'wikidiff2_do_diff' ) ) {
+ wfProfileIn( 'wikidiff2_do_diff' );
+ $text = wikidiff2_do_diff( $otext, $ntext, 2 );
+ wfProfileOut( 'wikidiff2_do_diff' );
+ return $text;
+ }
+ }
+ if ( $wgExternalDiffEngine !== false ) {
+ # Diff via the shell
+ global $wgTmpDirectory;
+ $tempName1 = tempnam( $wgTmpDirectory, 'diff_' );
+ $tempName2 = tempnam( $wgTmpDirectory, 'diff_' );
+
+ $tempFile1 = fopen( $tempName1, "w" );
+ if ( !$tempFile1 ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ $tempFile2 = fopen( $tempName2, "w" );
+ if ( !$tempFile2 ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ fwrite( $tempFile1, $otext );
+ fwrite( $tempFile2, $ntext );
+ fclose( $tempFile1 );
+ fclose( $tempFile2 );
+ $cmd = wfEscapeShellArg( $wgExternalDiffEngine, $tempName1, $tempName2 );
+ wfProfileIn( "$fname-shellexec" );
+ $difftext = wfShellExec( $cmd );
+ wfProfileOut( "$fname-shellexec" );
+ unlink( $tempName1 );
+ unlink( $tempName2 );
+ return $difftext;
+ }
+
+ # Native PHP diff
+ $ota = explode( "\n", $wgContLang->segmentForDiff( $otext ) );
+ $nta = explode( "\n", $wgContLang->segmentForDiff( $ntext ) );
+ $diffs = new Diff( $ota, $nta );
+ $formatter = new TableDiffFormatter();
+ return $wgContLang->unsegmentForDiff( $formatter->format( $diffs ) );
+ }
+
+
+ /**
+ * Replace line numbers with the text in the user's language
+ */
+ function localiseLineNumbers( $text ) {
+ return preg_replace_callback( '/<!--LINE (\d+)-->/',
+ array( &$this, 'localiseLineNumbersCb' ), $text );
+ }
+
+ function localiseLineNumbersCb( $matches ) {
+ global $wgLang;
+ return wfMsgExt( 'lineno', array('parseinline'), $wgLang->formatNum( $matches[1] ) );
+ }
+
+
+ /**
+ * If there are revisions between the ones being compared, return a note saying so.
+ */
+ function getMultiNotice() {
+ if ( !is_object($this->mOldRev) || !is_object($this->mNewRev) )
+ return '';
+
+ if( !$this->mOldPage->equals( $this->mNewPage ) ) {
+ // Comparing two different pages? Count would be meaningless.
+ return '';
+ }
+
+ $oldid = $this->mOldRev->getId();
+ $newid = $this->mNewRev->getId();
+ if ( $oldid > $newid ) {
+ $tmp = $oldid; $oldid = $newid; $newid = $tmp;
+ }
+
+ $n = $this->mTitle->countRevisionsBetween( $oldid, $newid );
+ if ( !$n )
+ return '';
+
+ return wfMsgExt( 'diff-multi', array( 'parseinline' ), $n );
+ }
+
+
+ /**
+ * Add the header to a diff body
+ */
+ function addHeader( $diff, $otitle, $ntitle, $multi = '' ) {
+ $header = "
+ <table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>
+ <tr>
+ <td colspan='2' width='50%' align='center' class='diff-otitle'>{$otitle}</td>
+ <td colspan='2' width='50%' align='center' class='diff-ntitle'>{$ntitle}</td>
+ </tr>
+ ";
+
+ if ( $multi != '' )
+ $header .= "<tr><td colspan='4' align='center' class='diff-multi'>{$multi}</td></tr>";
+
+ return $header . $diff . "</table>";
+ }
+
+ /**
+ * Use specified text instead of loading from the database
+ */
+ function setText( $oldText, $newText ) {
+ $this->mOldtext = $oldText;
+ $this->mNewtext = $newText;
+ $this->mTextLoaded = 2;
+ }
+
+ /**
+ * Load revision metadata for the specified articles. If newid is 0, then compare
+ * the old article in oldid to the current article; if oldid is 0, then
+ * compare the current article to the immediately previous one (ignoring the
+ * value of newid).
+ *
+ * If oldid is false, leave the corresponding revision object set
+ * to false. This is impossible via ordinary user input, and is provided for
+ * API convenience.
+ */
+ function loadRevisionData() {
+ global $wgLang;
+ if ( $this->mRevisionsLoaded ) {
+ return true;
+ } else {
+ // Whether it succeeds or fails, we don't want to try again
+ $this->mRevisionsLoaded = true;
+ }
+
+ // Load the new revision object
+ if( $this->mNewid ) {
+ $this->mNewRev = Revision::newFromId( $this->mNewid );
+ } else {
+ $this->mNewRev = Revision::newFromTitle( $this->mTitle );
+ }
+
+ if( is_null( $this->mNewRev ) ) {
+ return false;
+ }
+
+ // Set assorted variables
+ $timestamp = $wgLang->timeanddate( $this->mNewRev->getTimestamp(), true );
+ $this->mNewPage = $this->mNewRev->getTitle();
+ if( $this->mNewRev->isCurrent() ) {
+ $newLink = $this->mNewPage->escapeLocalUrl();
+ $this->mPagetitle = htmlspecialchars( wfMsg( 'currentrev' ) );
+ $newEdit = $this->mNewPage->escapeLocalUrl( 'action=edit' );
+ $newUndo = $this->mNewPage->escapeLocalUrl( 'action=edit&undo=' . $this->mNewid );
+
+ $this->mNewtitle = "<a href='$newLink'>{$this->mPagetitle}</a> ($timestamp)"
+ . " (<a href='$newEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)"
+ . " (<a href='$newUndo'>" . htmlspecialchars( wfMsg( 'editundo' ) ) . "</a>)";
+
+ } else {
+ $newLink = $this->mNewPage->escapeLocalUrl( 'oldid=' . $this->mNewid );
+ $newEdit = $this->mNewPage->escapeLocalUrl( 'action=edit&oldid=' . $this->mNewid );
+ $newUndo = $this->mNewPage->escapeLocalUrl( 'action=edit&undo=' . $this->mNewid );
+ $this->mPagetitle = htmlspecialchars( wfMsg( 'revisionasof', $timestamp ) );
+
+ $this->mNewtitle = "<a href='$newLink'>{$this->mPagetitle}</a>"
+ . " (<a href='$newEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)"
+ . " (<a href='$newUndo'>" . htmlspecialchars( wfMsg( 'editundo' ) ) . "</a>)";
+ }
+
+ // Load the old revision object
+ $this->mOldRev = false;
+ if( $this->mOldid ) {
+ $this->mOldRev = Revision::newFromId( $this->mOldid );
+ } elseif ( $this->mOldid === 0 ) {
+ $rev = $this->mNewRev->getPrevious();
+ if( $rev ) {
+ $this->mOldid = $rev->getId();
+ $this->mOldRev = $rev;
+ } else {
+ // No previous revision; mark to show as first-version only.
+ $this->mOldid = false;
+ $this->mOldRev = false;
+ }
+ }/* elseif ( $this->mOldid === false ) leave mOldRev false; */
+
+ if( is_null( $this->mOldRev ) ) {
+ return false;
+ }
+
+ if ( $this->mOldRev ) {
+ $this->mOldPage = $this->mOldRev->getTitle();
+
+ $t = $wgLang->timeanddate( $this->mOldRev->getTimestamp(), true );
+ $oldLink = $this->mOldPage->escapeLocalUrl( 'oldid=' . $this->mOldid );
+ $oldEdit = $this->mOldPage->escapeLocalUrl( 'action=edit&oldid=' . $this->mOldid );
+ $this->mOldtitle = "<a href='$oldLink'>" . htmlspecialchars( wfMsg( 'revisionasof', $t ) )
+ . "</a> (<a href='$oldEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)";
+ }
+
+ return true;
+ }
+
+ /**
+ * Load the text of the revisions, as well as revision data.
+ */
+ function loadText() {
+ if ( $this->mTextLoaded == 2 ) {
+ return true;
+ } else {
+ // Whether it succeeds or fails, we don't want to try again
+ $this->mTextLoaded = 2;
+ }
+
+ if ( !$this->loadRevisionData() ) {
+ return false;
+ }
+ if ( $this->mOldRev ) {
+ // FIXME: permission tests
+ $this->mOldtext = $this->mOldRev->getText();
+ if ( $this->mOldtext === false ) {
+ return false;
+ }
+ }
+ if ( $this->mNewRev ) {
+ $this->mNewtext = $this->mNewRev->getText();
+ if ( $this->mNewtext === false ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Load the text of the new revision, not the old one
+ */
+ function loadNewText() {
+ if ( $this->mTextLoaded >= 1 ) {
+ return true;
+ } else {
+ $this->mTextLoaded = 1;
+ }
+ if ( !$this->loadRevisionData() ) {
+ return false;
+ }
+ $this->mNewtext = $this->mNewRev->getText();
+ return true;
+ }
+
+
+}
+
+// A PHP diff engine for phpwiki. (Taken from phpwiki-1.3.3)
+//
+// Copyright (C) 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org>
+// You may copy this code freely under the conditions of the GPL.
+//
+
+define('USE_ASSERTS', function_exists('assert'));
+
+/**
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp {
+ var $type;
+ var $orig;
+ var $closing;
+
+ function reverse() {
+ trigger_error('pure virtual', E_USER_ERROR);
+ }
+
+ function norig() {
+ return $this->orig ? sizeof($this->orig) : 0;
+ }
+
+ function nclosing() {
+ return $this->closing ? sizeof($this->closing) : 0;
+ }
+}
+
+/**
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Copy extends _DiffOp {
+ var $type = 'copy';
+
+ function _DiffOp_Copy ($orig, $closing = false) {
+ if (!is_array($closing))
+ $closing = $orig;
+ $this->orig = $orig;
+ $this->closing = $closing;
+ }
+
+ function reverse() {
+ return new _DiffOp_Copy($this->closing, $this->orig);
+ }
+}
+
+/**
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Delete extends _DiffOp {
+ var $type = 'delete';
+
+ function _DiffOp_Delete ($lines) {
+ $this->orig = $lines;
+ $this->closing = false;
+ }
+
+ function reverse() {
+ return new _DiffOp_Add($this->orig);
+ }
+}
+
+/**
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Add extends _DiffOp {
+ var $type = 'add';
+
+ function _DiffOp_Add ($lines) {
+ $this->closing = $lines;
+ $this->orig = false;
+ }
+
+ function reverse() {
+ return new _DiffOp_Delete($this->closing);
+ }
+}
+
+/**
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class _DiffOp_Change extends _DiffOp {
+ var $type = 'change';
+
+ function _DiffOp_Change ($orig, $closing) {
+ $this->orig = $orig;
+ $this->closing = $closing;
+ }
+
+ function reverse() {
+ return new _DiffOp_Change($this->closing, $this->orig);
+ }
+}
+
+
+/**
+ * Class used internally by Diff to actually compute the diffs.
+ *
+ * The algorithm used here is mostly lifted from the perl module
+ * Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
+ * http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
+ *
+ * More ideas are taken from:
+ * http://www.ics.uci.edu/~eppstein/161/960229.html
+ *
+ * Some ideas are (and a bit of code) are from from analyze.c, from GNU
+ * diffutils-2.7, which can be found at:
+ * ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
+ *
+ * closingly, some ideas (subdivision by NCHUNKS > 2, and some optimizations)
+ * are my own.
+ *
+ * Line length limits for robustness added by Tim Starling, 2005-08-31
+ *
+ * @author Geoffrey T. Dairiki, Tim Starling
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class _DiffEngine
+{
+ const MAX_XREF_LENGTH = 10000;
+
+ function diff ($from_lines, $to_lines) {
+ $fname = '_DiffEngine::diff';
+ wfProfileIn( $fname );
+
+ $n_from = sizeof($from_lines);
+ $n_to = sizeof($to_lines);
+
+ $this->xchanged = $this->ychanged = array();
+ $this->xv = $this->yv = array();
+ $this->xind = $this->yind = array();
+ unset($this->seq);
+ unset($this->in_seq);
+ unset($this->lcs);
+
+ // Skip leading common lines.
+ for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
+ if ($from_lines[$skip] !== $to_lines[$skip])
+ break;
+ $this->xchanged[$skip] = $this->ychanged[$skip] = false;
+ }
+ // Skip trailing common lines.
+ $xi = $n_from; $yi = $n_to;
+ for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
+ if ($from_lines[$xi] !== $to_lines[$yi])
+ break;
+ $this->xchanged[$xi] = $this->ychanged[$yi] = false;
+ }
+
+ // Ignore lines which do not exist in both files.
+ for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
+ $xhash[$this->_line_hash($from_lines[$xi])] = 1;
+ }
+
+ for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
+ $line = $to_lines[$yi];
+ if ( ($this->ychanged[$yi] = empty($xhash[$this->_line_hash($line)])) )
+ continue;
+ $yhash[$this->_line_hash($line)] = 1;
+ $this->yv[] = $line;
+ $this->yind[] = $yi;
+ }
+ for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
+ $line = $from_lines[$xi];
+ if ( ($this->xchanged[$xi] = empty($yhash[$this->_line_hash($line)])) )
+ continue;
+ $this->xv[] = $line;
+ $this->xind[] = $xi;
+ }
+
+ // Find the LCS.
+ $this->_compareseq(0, sizeof($this->xv), 0, sizeof($this->yv));
+
+ // Merge edits when possible
+ $this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged);
+ $this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged);
+
+ // Compute the edit operations.
+ $edits = array();
+ $xi = $yi = 0;
+ while ($xi < $n_from || $yi < $n_to) {
+ USE_ASSERTS && assert($yi < $n_to || $this->xchanged[$xi]);
+ USE_ASSERTS && assert($xi < $n_from || $this->ychanged[$yi]);
+
+ // Skip matching "snake".
+ $copy = array();
+ while ( $xi < $n_from && $yi < $n_to
+ && !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
+ $copy[] = $from_lines[$xi++];
+ ++$yi;
+ }
+ if ($copy)
+ $edits[] = new _DiffOp_Copy($copy);
+
+ // Find deletes & adds.
+ $delete = array();
+ while ($xi < $n_from && $this->xchanged[$xi])
+ $delete[] = $from_lines[$xi++];
+
+ $add = array();
+ while ($yi < $n_to && $this->ychanged[$yi])
+ $add[] = $to_lines[$yi++];
+
+ if ($delete && $add)
+ $edits[] = new _DiffOp_Change($delete, $add);
+ elseif ($delete)
+ $edits[] = new _DiffOp_Delete($delete);
+ elseif ($add)
+ $edits[] = new _DiffOp_Add($add);
+ }
+ wfProfileOut( $fname );
+ return $edits;
+ }
+
+ /**
+ * Returns the whole line if it's small enough, or the MD5 hash otherwise
+ */
+ function _line_hash( $line ) {
+ if ( strlen( $line ) > self::MAX_XREF_LENGTH ) {
+ return md5( $line );
+ } else {
+ return $line;
+ }
+ }
+
+
+ /* Divide the Largest Common Subsequence (LCS) of the sequences
+ * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally
+ * sized segments.
+ *
+ * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an
+ * array of NCHUNKS+1 (X, Y) indexes giving the diving points between
+ * sub sequences. The first sub-sequence is contained in [X0, X1),
+ * [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on. Note
+ * that (X0, Y0) == (XOFF, YOFF) and
+ * (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
+ *
+ * This function assumes that the first lines of the specified portions
+ * of the two files do not match, and likewise that the last lines do not
+ * match. The caller must trim matching lines from the beginning and end
+ * of the portions it is going to specify.
+ */
+ function _diag ($xoff, $xlim, $yoff, $ylim, $nchunks) {
+ $fname = '_DiffEngine::_diag';
+ wfProfileIn( $fname );
+ $flip = false;
+
+ if ($xlim - $xoff > $ylim - $yoff) {
+ // Things seems faster (I'm not sure I understand why)
+ // when the shortest sequence in X.
+ $flip = true;
+ list ($xoff, $xlim, $yoff, $ylim)
+ = array( $yoff, $ylim, $xoff, $xlim);
+ }
+
+ if ($flip)
+ for ($i = $ylim - 1; $i >= $yoff; $i--)
+ $ymatches[$this->xv[$i]][] = $i;
+ else
+ for ($i = $ylim - 1; $i >= $yoff; $i--)
+ $ymatches[$this->yv[$i]][] = $i;
+
+ $this->lcs = 0;
+ $this->seq[0]= $yoff - 1;
+ $this->in_seq = array();
+ $ymids[0] = array();
+
+ $numer = $xlim - $xoff + $nchunks - 1;
+ $x = $xoff;
+ for ($chunk = 0; $chunk < $nchunks; $chunk++) {
+ wfProfileIn( "$fname-chunk" );
+ if ($chunk > 0)
+ for ($i = 0; $i <= $this->lcs; $i++)
+ $ymids[$i][$chunk-1] = $this->seq[$i];
+
+ $x1 = $xoff + (int)(($numer + ($xlim-$xoff)*$chunk) / $nchunks);
+ for ( ; $x < $x1; $x++) {
+ $line = $flip ? $this->yv[$x] : $this->xv[$x];
+ if (empty($ymatches[$line]))
+ continue;
+ $matches = $ymatches[$line];
+ reset($matches);
+ while (list ($junk, $y) = each($matches))
+ if (empty($this->in_seq[$y])) {
+ $k = $this->_lcs_pos($y);
+ USE_ASSERTS && assert($k > 0);
+ $ymids[$k] = $ymids[$k-1];
+ break;
+ }
+ while (list ( /* $junk */, $y) = each($matches)) {
+ if ($y > $this->seq[$k-1]) {
+ USE_ASSERTS && assert($y < $this->seq[$k]);
+ // Optimization: this is a common case:
+ // next match is just replacing previous match.
+ $this->in_seq[$this->seq[$k]] = false;
+ $this->seq[$k] = $y;
+ $this->in_seq[$y] = 1;
+ } else if (empty($this->in_seq[$y])) {
+ $k = $this->_lcs_pos($y);
+ USE_ASSERTS && assert($k > 0);
+ $ymids[$k] = $ymids[$k-1];
+ }
+ }
+ }
+ wfProfileOut( "$fname-chunk" );
+ }
+
+ $seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
+ $ymid = $ymids[$this->lcs];
+ for ($n = 0; $n < $nchunks - 1; $n++) {
+ $x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
+ $y1 = $ymid[$n] + 1;
+ $seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
+ }
+ $seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
+
+ wfProfileOut( $fname );
+ return array($this->lcs, $seps);
+ }
+
+ function _lcs_pos ($ypos) {
+ $fname = '_DiffEngine::_lcs_pos';
+ wfProfileIn( $fname );
+
+ $end = $this->lcs;
+ if ($end == 0 || $ypos > $this->seq[$end]) {
+ $this->seq[++$this->lcs] = $ypos;
+ $this->in_seq[$ypos] = 1;
+ wfProfileOut( $fname );
+ return $this->lcs;
+ }
+
+ $beg = 1;
+ while ($beg < $end) {
+ $mid = (int)(($beg + $end) / 2);
+ if ( $ypos > $this->seq[$mid] )
+ $beg = $mid + 1;
+ else
+ $end = $mid;
+ }
+
+ USE_ASSERTS && assert($ypos != $this->seq[$end]);
+
+ $this->in_seq[$this->seq[$end]] = false;
+ $this->seq[$end] = $ypos;
+ $this->in_seq[$ypos] = 1;
+ wfProfileOut( $fname );
+ return $end;
+ }
+
+ /* Find LCS of two sequences.
+ *
+ * The results are recorded in the vectors $this->{x,y}changed[], by
+ * storing a 1 in the element for each line that is an insertion
+ * or deletion (ie. is not in the LCS).
+ *
+ * The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1.
+ *
+ * Note that XLIM, YLIM are exclusive bounds.
+ * All line numbers are origin-0 and discarded lines are not counted.
+ */
+ function _compareseq ($xoff, $xlim, $yoff, $ylim) {
+ $fname = '_DiffEngine::_compareseq';
+ wfProfileIn( $fname );
+
+ // Slide down the bottom initial diagonal.
+ while ($xoff < $xlim && $yoff < $ylim
+ && $this->xv[$xoff] == $this->yv[$yoff]) {
+ ++$xoff;
+ ++$yoff;
+ }
+
+ // Slide up the top initial diagonal.
+ while ($xlim > $xoff && $ylim > $yoff
+ && $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
+ --$xlim;
+ --$ylim;
+ }
+
+ if ($xoff == $xlim || $yoff == $ylim)
+ $lcs = 0;
+ else {
+ // This is ad hoc but seems to work well.
+ //$nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
+ //$nchunks = max(2,min(8,(int)$nchunks));
+ $nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
+ list ($lcs, $seps)
+ = $this->_diag($xoff,$xlim,$yoff, $ylim,$nchunks);
+ }
+
+ if ($lcs == 0) {
+ // X and Y sequences have no common subsequence:
+ // mark all changed.
+ while ($yoff < $ylim)
+ $this->ychanged[$this->yind[$yoff++]] = 1;
+ while ($xoff < $xlim)
+ $this->xchanged[$this->xind[$xoff++]] = 1;
+ } else {
+ // Use the partitions to split this problem into subproblems.
+ reset($seps);
+ $pt1 = $seps[0];
+ while ($pt2 = next($seps)) {
+ $this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
+ $pt1 = $pt2;
+ }
+ }
+ wfProfileOut( $fname );
+ }
+
+ /* Adjust inserts/deletes of identical lines to join changes
+ * as much as possible.
+ *
+ * We do something when a run of changed lines include a
+ * line at one end and has an excluded, identical line at the other.
+ * We are free to choose which identical line is included.
+ * `compareseq' usually chooses the one at the beginning,
+ * but usually it is cleaner to consider the following identical line
+ * to be the "change".
+ *
+ * This is extracted verbatim from analyze.c (GNU diffutils-2.7).
+ */
+ function _shift_boundaries ($lines, &$changed, $other_changed) {
+ $fname = '_DiffEngine::_shift_boundaries';
+ wfProfileIn( $fname );
+ $i = 0;
+ $j = 0;
+
+ USE_ASSERTS && assert('sizeof($lines) == sizeof($changed)');
+ $len = sizeof($lines);
+ $other_len = sizeof($other_changed);
+
+ while (1) {
+ /*
+ * Scan forwards to find beginning of another run of changes.
+ * Also keep track of the corresponding point in the other file.
+ *
+ * Throughout this code, $i and $j are adjusted together so that
+ * the first $i elements of $changed and the first $j elements
+ * of $other_changed both contain the same number of zeros
+ * (unchanged lines).
+ * Furthermore, $j is always kept so that $j == $other_len or
+ * $other_changed[$j] == false.
+ */
+ while ($j < $other_len && $other_changed[$j])
+ $j++;
+
+ while ($i < $len && ! $changed[$i]) {
+ USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]');
+ $i++; $j++;
+ while ($j < $other_len && $other_changed[$j])
+ $j++;
+ }
+
+ if ($i == $len)
+ break;
+
+ $start = $i;
+
+ // Find the end of this run of changes.
+ while (++$i < $len && $changed[$i])
+ continue;
+
+ do {
+ /*
+ * Record the length of this run of changes, so that
+ * we can later determine whether the run has grown.
+ */
+ $runlength = $i - $start;
+
+ /*
+ * Move the changed region back, so long as the
+ * previous unchanged line matches the last changed one.
+ * This merges with previous changed regions.
+ */
+ while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
+ $changed[--$start] = 1;
+ $changed[--$i] = false;
+ while ($start > 0 && $changed[$start - 1])
+ $start--;
+ USE_ASSERTS && assert('$j > 0');
+ while ($other_changed[--$j])
+ continue;
+ USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]');
+ }
+
+ /*
+ * Set CORRESPONDING to the end of the changed run, at the last
+ * point where it corresponds to a changed run in the other file.
+ * CORRESPONDING == LEN means no such point has been found.
+ */
+ $corresponding = $j < $other_len ? $i : $len;
+
+ /*
+ * Move the changed region forward, so long as the
+ * first changed line matches the following unchanged one.
+ * This merges with following changed regions.
+ * Do this second, so that if there are no merges,
+ * the changed region is moved forward as far as possible.
+ */
+ while ($i < $len && $lines[$start] == $lines[$i]) {
+ $changed[$start++] = false;
+ $changed[$i++] = 1;
+ while ($i < $len && $changed[$i])
+ $i++;
+
+ USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]');
+ $j++;
+ if ($j < $other_len && $other_changed[$j]) {
+ $corresponding = $i;
+ while ($j < $other_len && $other_changed[$j])
+ $j++;
+ }
+ }
+ } while ($runlength != $i - $start);
+
+ /*
+ * If possible, move the fully-merged run of changes
+ * back to a corresponding run in the other file.
+ */
+ while ($corresponding < $i) {
+ $changed[--$start] = 1;
+ $changed[--$i] = 0;
+ USE_ASSERTS && assert('$j > 0');
+ while ($other_changed[--$j])
+ continue;
+ USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]');
+ }
+ }
+ wfProfileOut( $fname );
+ }
+}
+
+/**
+ * Class representing a 'diff' between two sequences of strings.
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class Diff
+{
+ var $edits;
+
+ /**
+ * Constructor.
+ * Computes diff between sequences of strings.
+ *
+ * @param $from_lines array An array of strings.
+ * (Typically these are lines from a file.)
+ * @param $to_lines array An array of strings.
+ */
+ function Diff($from_lines, $to_lines) {
+ $eng = new _DiffEngine;
+ $this->edits = $eng->diff($from_lines, $to_lines);
+ //$this->_check($from_lines, $to_lines);
+ }
+
+ /**
+ * Compute reversed Diff.
+ *
+ * SYNOPSIS:
+ *
+ * $diff = new Diff($lines1, $lines2);
+ * $rev = $diff->reverse();
+ * @return object A Diff object representing the inverse of the
+ * original diff.
+ */
+ function reverse () {
+ $rev = $this;
+ $rev->edits = array();
+ foreach ($this->edits as $edit) {
+ $rev->edits[] = $edit->reverse();
+ }
+ return $rev;
+ }
+
+ /**
+ * Check for empty diff.
+ *
+ * @return bool True iff two sequences were identical.
+ */
+ function isEmpty () {
+ foreach ($this->edits as $edit) {
+ if ($edit->type != 'copy')
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compute the length of the Longest Common Subsequence (LCS).
+ *
+ * This is mostly for diagnostic purposed.
+ *
+ * @return int The length of the LCS.
+ */
+ function lcs () {
+ $lcs = 0;
+ foreach ($this->edits as $edit) {
+ if ($edit->type == 'copy')
+ $lcs += sizeof($edit->orig);
+ }
+ return $lcs;
+ }
+
+ /**
+ * Get the original set of lines.
+ *
+ * This reconstructs the $from_lines parameter passed to the
+ * constructor.
+ *
+ * @return array The original sequence of strings.
+ */
+ function orig() {
+ $lines = array();
+
+ foreach ($this->edits as $edit) {
+ if ($edit->orig)
+ array_splice($lines, sizeof($lines), 0, $edit->orig);
+ }
+ return $lines;
+ }
+
+ /**
+ * Get the closing set of lines.
+ *
+ * This reconstructs the $to_lines parameter passed to the
+ * constructor.
+ *
+ * @return array The sequence of strings.
+ */
+ function closing() {
+ $lines = array();
+
+ foreach ($this->edits as $edit) {
+ if ($edit->closing)
+ array_splice($lines, sizeof($lines), 0, $edit->closing);
+ }
+ return $lines;
+ }
+
+ /**
+ * Check a Diff for validity.
+ *
+ * This is here only for debugging purposes.
+ */
+ function _check ($from_lines, $to_lines) {
+ $fname = 'Diff::_check';
+ wfProfileIn( $fname );
+ if (serialize($from_lines) != serialize($this->orig()))
+ trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
+ if (serialize($to_lines) != serialize($this->closing()))
+ trigger_error("Reconstructed closing doesn't match", E_USER_ERROR);
+
+ $rev = $this->reverse();
+ if (serialize($to_lines) != serialize($rev->orig()))
+ trigger_error("Reversed original doesn't match", E_USER_ERROR);
+ if (serialize($from_lines) != serialize($rev->closing()))
+ trigger_error("Reversed closing doesn't match", E_USER_ERROR);
+
+
+ $prevtype = 'none';
+ foreach ($this->edits as $edit) {
+ if ( $prevtype == $edit->type )
+ trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
+ $prevtype = $edit->type;
+ }
+
+ $lcs = $this->lcs();
+ trigger_error('Diff okay: LCS = '.$lcs, E_USER_NOTICE);
+ wfProfileOut( $fname );
+ }
+}
+
+/**
+ * FIXME: bad name.
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class MappedDiff extends Diff
+{
+ /**
+ * Constructor.
+ *
+ * Computes diff between sequences of strings.
+ *
+ * This can be used to compute things like
+ * case-insensitve diffs, or diffs which ignore
+ * changes in white-space.
+ *
+ * @param $from_lines array An array of strings.
+ * (Typically these are lines from a file.)
+ *
+ * @param $to_lines array An array of strings.
+ *
+ * @param $mapped_from_lines array This array should
+ * have the same size number of elements as $from_lines.
+ * The elements in $mapped_from_lines and
+ * $mapped_to_lines are what is actually compared
+ * when computing the diff.
+ *
+ * @param $mapped_to_lines array This array should
+ * have the same number of elements as $to_lines.
+ */
+ function MappedDiff($from_lines, $to_lines,
+ $mapped_from_lines, $mapped_to_lines) {
+ $fname = 'MappedDiff::MappedDiff';
+ wfProfileIn( $fname );
+
+ assert(sizeof($from_lines) == sizeof($mapped_from_lines));
+ assert(sizeof($to_lines) == sizeof($mapped_to_lines));
+
+ $this->Diff($mapped_from_lines, $mapped_to_lines);
+
+ $xi = $yi = 0;
+ for ($i = 0; $i < sizeof($this->edits); $i++) {
+ $orig = &$this->edits[$i]->orig;
+ if (is_array($orig)) {
+ $orig = array_slice($from_lines, $xi, sizeof($orig));
+ $xi += sizeof($orig);
+ }
+
+ $closing = &$this->edits[$i]->closing;
+ if (is_array($closing)) {
+ $closing = array_slice($to_lines, $yi, sizeof($closing));
+ $yi += sizeof($closing);
+ }
+ }
+ wfProfileOut( $fname );
+ }
+}
+
+/**
+ * A class to format Diffs
+ *
+ * This class formats the diff in classic diff format.
+ * It is intended that this class be customized via inheritance,
+ * to obtain fancier outputs.
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class DiffFormatter
+{
+ /**
+ * Number of leading context "lines" to preserve.
+ *
+ * This should be left at zero for this class, but subclasses
+ * may want to set this to other values.
+ */
+ var $leading_context_lines = 0;
+
+ /**
+ * Number of trailing context "lines" to preserve.
+ *
+ * This should be left at zero for this class, but subclasses
+ * may want to set this to other values.
+ */
+ var $trailing_context_lines = 0;
+
+ /**
+ * Format a diff.
+ *
+ * @param $diff object A Diff object.
+ * @return string The formatted output.
+ */
+ function format($diff) {
+ $fname = 'DiffFormatter::format';
+ wfProfileIn( $fname );
+
+ $xi = $yi = 1;
+ $block = false;
+ $context = array();
+
+ $nlead = $this->leading_context_lines;
+ $ntrail = $this->trailing_context_lines;
+
+ $this->_start_diff();
+
+ foreach ($diff->edits as $edit) {
+ if ($edit->type == 'copy') {
+ if (is_array($block)) {
+ if (sizeof($edit->orig) <= $nlead + $ntrail) {
+ $block[] = $edit;
+ }
+ else{
+ if ($ntrail) {
+ $context = array_slice($edit->orig, 0, $ntrail);
+ $block[] = new _DiffOp_Copy($context);
+ }
+ $this->_block($x0, $ntrail + $xi - $x0,
+ $y0, $ntrail + $yi - $y0,
+ $block);
+ $block = false;
+ }
+ }
+ $context = $edit->orig;
+ }
+ else {
+ if (! is_array($block)) {
+ $context = array_slice($context, sizeof($context) - $nlead);
+ $x0 = $xi - sizeof($context);
+ $y0 = $yi - sizeof($context);
+ $block = array();
+ if ($context)
+ $block[] = new _DiffOp_Copy($context);
+ }
+ $block[] = $edit;
+ }
+
+ if ($edit->orig)
+ $xi += sizeof($edit->orig);
+ if ($edit->closing)
+ $yi += sizeof($edit->closing);
+ }
+
+ if (is_array($block))
+ $this->_block($x0, $xi - $x0,
+ $y0, $yi - $y0,
+ $block);
+
+ $end = $this->_end_diff();
+ wfProfileOut( $fname );
+ return $end;
+ }
+
+ function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) {
+ $fname = 'DiffFormatter::_block';
+ wfProfileIn( $fname );
+ $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
+ foreach ($edits as $edit) {
+ if ($edit->type == 'copy')
+ $this->_context($edit->orig);
+ elseif ($edit->type == 'add')
+ $this->_added($edit->closing);
+ elseif ($edit->type == 'delete')
+ $this->_deleted($edit->orig);
+ elseif ($edit->type == 'change')
+ $this->_changed($edit->orig, $edit->closing);
+ else
+ trigger_error('Unknown edit type', E_USER_ERROR);
+ }
+ $this->_end_block();
+ wfProfileOut( $fname );
+ }
+
+ function _start_diff() {
+ ob_start();
+ }
+
+ function _end_diff() {
+ $val = ob_get_contents();
+ ob_end_clean();
+ return $val;
+ }
+
+ function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+ if ($xlen > 1)
+ $xbeg .= "," . ($xbeg + $xlen - 1);
+ if ($ylen > 1)
+ $ybeg .= "," . ($ybeg + $ylen - 1);
+
+ return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
+ }
+
+ function _start_block($header) {
+ echo $header;
+ }
+
+ function _end_block() {
+ }
+
+ function _lines($lines, $prefix = ' ') {
+ foreach ($lines as $line)
+ echo "$prefix $line\n";
+ }
+
+ function _context($lines) {
+ $this->_lines($lines);
+ }
+
+ function _added($lines) {
+ $this->_lines($lines, '>');
+ }
+ function _deleted($lines) {
+ $this->_lines($lines, '<');
+ }
+
+ function _changed($orig, $closing) {
+ $this->_deleted($orig);
+ echo "---\n";
+ $this->_added($closing);
+ }
+}
+
+
+/**
+ * Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
+ *
+ */
+
+define('NBSP', '&#160;'); // iso-8859-x non-breaking space.
+
+/**
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class _HWLDF_WordAccumulator {
+ function _HWLDF_WordAccumulator () {
+ $this->_lines = array();
+ $this->_line = '';
+ $this->_group = '';
+ $this->_tag = '';
+ }
+
+ function _flushGroup ($new_tag) {
+ if ($this->_group !== '') {
+ if ($this->_tag == 'mark')
+ $this->_line .= '<span class="diffchange">' .
+ htmlspecialchars ( $this->_group ) . '</span>';
+ else
+ $this->_line .= htmlspecialchars ( $this->_group );
+ }
+ $this->_group = '';
+ $this->_tag = $new_tag;
+ }
+
+ function _flushLine ($new_tag) {
+ $this->_flushGroup($new_tag);
+ if ($this->_line != '')
+ array_push ( $this->_lines, $this->_line );
+ else
+ # make empty lines visible by inserting an NBSP
+ array_push ( $this->_lines, NBSP );
+ $this->_line = '';
+ }
+
+ function addWords ($words, $tag = '') {
+ if ($tag != $this->_tag)
+ $this->_flushGroup($tag);
+
+ foreach ($words as $word) {
+ // new-line should only come as first char of word.
+ if ($word == '')
+ continue;
+ if ($word[0] == "\n") {
+ $this->_flushLine($tag);
+ $word = substr($word, 1);
+ }
+ assert(!strstr($word, "\n"));
+ $this->_group .= $word;
+ }
+ }
+
+ function getLines() {
+ $this->_flushLine('~done');
+ return $this->_lines;
+ }
+}
+
+/**
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class WordLevelDiff extends MappedDiff
+{
+ const MAX_LINE_LENGTH = 10000;
+
+ function WordLevelDiff ($orig_lines, $closing_lines) {
+ $fname = 'WordLevelDiff::WordLevelDiff';
+ wfProfileIn( $fname );
+
+ list ($orig_words, $orig_stripped) = $this->_split($orig_lines);
+ list ($closing_words, $closing_stripped) = $this->_split($closing_lines);
+
+ $this->MappedDiff($orig_words, $closing_words,
+ $orig_stripped, $closing_stripped);
+ wfProfileOut( $fname );
+ }
+
+ function _split($lines) {
+ $fname = 'WordLevelDiff::_split';
+ wfProfileIn( $fname );
+
+ $words = array();
+ $stripped = array();
+ $first = true;
+ foreach ( $lines as $line ) {
+ # If the line is too long, just pretend the entire line is one big word
+ # This prevents resource exhaustion problems
+ if ( $first ) {
+ $first = false;
+ } else {
+ $words[] = "\n";
+ $stripped[] = "\n";
+ }
+ if ( strlen( $line ) > self::MAX_LINE_LENGTH ) {
+ $words[] = $line;
+ $stripped[] = $line;
+ } else {
+ $m = array();
+ if (preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs',
+ $line, $m))
+ {
+ $words = array_merge( $words, $m[0] );
+ $stripped = array_merge( $stripped, $m[1] );
+ }
+ }
+ }
+ wfProfileOut( $fname );
+ return array($words, $stripped);
+ }
+
+ function orig () {
+ $fname = 'WordLevelDiff::orig';
+ wfProfileIn( $fname );
+ $orig = new _HWLDF_WordAccumulator;
+
+ foreach ($this->edits as $edit) {
+ if ($edit->type == 'copy')
+ $orig->addWords($edit->orig);
+ elseif ($edit->orig)
+ $orig->addWords($edit->orig, 'mark');
+ }
+ $lines = $orig->getLines();
+ wfProfileOut( $fname );
+ return $lines;
+ }
+
+ function closing () {
+ $fname = 'WordLevelDiff::closing';
+ wfProfileIn( $fname );
+ $closing = new _HWLDF_WordAccumulator;
+
+ foreach ($this->edits as $edit) {
+ if ($edit->type == 'copy')
+ $closing->addWords($edit->closing);
+ elseif ($edit->closing)
+ $closing->addWords($edit->closing, 'mark');
+ }
+ $lines = $closing->getLines();
+ wfProfileOut( $fname );
+ return $lines;
+ }
+}
+
+/**
+ * Wikipedia Table style diff formatter.
+ * @todo document
+ * @private
+ * @package MediaWiki
+ * @subpackage DifferenceEngine
+ */
+class TableDiffFormatter extends DiffFormatter
+{
+ function TableDiffFormatter() {
+ $this->leading_context_lines = 2;
+ $this->trailing_context_lines = 2;
+ }
+
+ function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
+ $r = '<tr><td colspan="2" align="left"><strong><!--LINE '.$xbeg."--></strong></td>\n" .
+ '<td colspan="2" align="left"><strong><!--LINE '.$ybeg."--></strong></td></tr>\n";
+ return $r;
+ }
+
+ function _start_block( $header ) {
+ echo $header;
+ }
+
+ function _end_block() {
+ }
+
+ function _lines( $lines, $prefix=' ', $color='white' ) {
+ }
+
+ # HTML-escape parameter before calling this
+ function addedLine( $line ) {
+ return "<td>+</td><td class='diff-addedline'>{$line}</td>";
+ }
+
+ # HTML-escape parameter before calling this
+ function deletedLine( $line ) {
+ return "<td>-</td><td class='diff-deletedline'>{$line}</td>";
+ }
+
+ # HTML-escape parameter before calling this
+ function contextLine( $line ) {
+ return "<td> </td><td class='diff-context'>{$line}</td>";
+ }
+
+ function emptyLine() {
+ return '<td colspan="2">&nbsp;</td>';
+ }
+
+ function _added( $lines ) {
+ foreach ($lines as $line) {
+ echo '<tr>' . $this->emptyLine() .
+ $this->addedLine( htmlspecialchars ( $line ) ) . "</tr>\n";
+ }
+ }
+
+ function _deleted($lines) {
+ foreach ($lines as $line) {
+ echo '<tr>' . $this->deletedLine( htmlspecialchars ( $line ) ) .
+ $this->emptyLine() . "</tr>\n";
+ }
+ }
+
+ function _context( $lines ) {
+ foreach ($lines as $line) {
+ echo '<tr>' .
+ $this->contextLine( htmlspecialchars ( $line ) ) .
+ $this->contextLine( htmlspecialchars ( $line ) ) . "</tr>\n";
+ }
+ }
+
+ function _changed( $orig, $closing ) {
+ $fname = 'TableDiffFormatter::_changed';
+ wfProfileIn( $fname );
+
+ $diff = new WordLevelDiff( $orig, $closing );
+ $del = $diff->orig();
+ $add = $diff->closing();
+
+ # Notice that WordLevelDiff returns HTML-escaped output.
+ # Hence, we will be calling addedLine/deletedLine without HTML-escaping.
+
+ while ( $line = array_shift( $del ) ) {
+ $aline = array_shift( $add );
+ echo '<tr>' . $this->deletedLine( $line ) .
+ $this->addedLine( $aline ) . "</tr>\n";
+ }
+ foreach ($add as $line) { # If any leftovers
+ echo '<tr>' . $this->emptyLine() .
+ $this->addedLine( $line ) . "</tr>\n";
+ }
+ wfProfileOut( $fname );
+ }
+}
+
+?>
diff --git a/includes/DjVuImage.php b/includes/DjVuImage.php
new file mode 100644
index 000000000000..3b8a68ba128c
--- /dev/null
+++ b/includes/DjVuImage.php
@@ -0,0 +1,231 @@
+<?php
+/**
+ * Support for detecting/validating DjVu image files and getting
+ * some basic file metadata (resolution etc)
+ *
+ * File format docs are available in source package for DjVuLibre:
+ * http://djvulibre.djvuzone.org/
+ *
+ *
+ * Copyright (C) 2006 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ */
+
+class DjVuImage {
+ function __construct( $filename ) {
+ $this->mFilename = $filename;
+ }
+
+ /**
+ * Check if the given file is indeed a valid DjVu image file
+ * @return bool
+ */
+ public function isValid() {
+ $info = $this->getInfo();
+ return $info !== false;
+ }
+
+
+ /**
+ * Return data in the style of getimagesize()
+ * @return array or false on failure
+ */
+ public function getImageSize() {
+ $data = $this->getInfo();
+
+ if( $data !== false ) {
+ $width = $data['width'];
+ $height = $data['height'];
+
+ return array( $width, $height, 'DjVu',
+ "width=\"$width\" height=\"$height\"" );
+ }
+ return false;
+ }
+
+ // ---------
+
+ /**
+ * For debugging; dump the IFF chunk structure
+ */
+ function dump() {
+ $file = fopen( $this->mFilename, 'rb' );
+ $header = fread( $file, 12 );
+ extract( unpack( 'a4magic/a4chunk/NchunkLength', $header ) );
+ echo "$chunk $chunkLength\n";
+ $this->dumpForm( $file, $chunkLength, 1 );
+ fclose( $file );
+ }
+
+ private function dumpForm( $file, $length, $indent ) {
+ $start = ftell( $file );
+ $secondary = fread( $file, 4 );
+ echo str_repeat( ' ', $indent * 4 ) . "($secondary)\n";
+ while( ftell( $file ) - $start < $length ) {
+ $chunkHeader = fread( $file, 8 );
+ if( $chunkHeader == '' ) {
+ break;
+ }
+ extract( unpack( 'a4chunk/NchunkLength', $chunkHeader ) );
+ echo str_repeat( ' ', $indent * 4 ) . "$chunk $chunkLength\n";
+
+ if( $chunk == 'FORM' ) {
+ $this->dumpForm( $file, $chunkLength, $indent + 1 );
+ } else {
+ fseek( $file, $chunkLength, SEEK_CUR );
+ if( $chunkLength & 1 == 1 ) {
+ // Padding byte between chunks
+ fseek( $file, 1, SEEK_CUR );
+ }
+ }
+ }
+ }
+
+ function getInfo() {
+ $file = fopen( $this->mFilename, 'rb' );
+ if( $file === false ) {
+ wfDebug( __METHOD__ . ": missing or failed file read\n" );
+ return false;
+ }
+
+ $header = fread( $file, 16 );
+ $info = false;
+
+ if( strlen( $header ) < 16 ) {
+ wfDebug( __METHOD__ . ": too short file header\n" );
+ } else {
+ extract( unpack( 'a4magic/a4form/NformLength/a4subtype', $header ) );
+
+ if( $magic != 'AT&T' ) {
+ wfDebug( __METHOD__ . ": not a DjVu file\n" );
+ } elseif( $subtype == 'DJVU' ) {
+ // Single-page document
+ $info = $this->getPageInfo( $file, $formLength );
+ } elseif( $subtype == 'DJVM' ) {
+ // Multi-page document
+ $info = $this->getMultiPageInfo( $file, $formLength );
+ } else {
+ wfDebug( __METHOD__ . ": unrecognized DJVU file type '$formType'\n" );
+ }
+ }
+ fclose( $file );
+ return $info;
+ }
+
+ private function readChunk( $file ) {
+ $header = fread( $file, 8 );
+ if( strlen( $header ) < 8 ) {
+ return array( false, 0 );
+ } else {
+ extract( unpack( 'a4chunk/Nlength', $header ) );
+ return array( $chunk, $length );
+ }
+ }
+
+ private function skipChunk( $file, $chunkLength ) {
+ fseek( $file, $chunkLength, SEEK_CUR );
+
+ if( $chunkLength & 0x01 == 1 && !feof( $file ) ) {
+ // padding byte
+ fseek( $file, 1, SEEK_CUR );
+ }
+ }
+
+ private function getMultiPageInfo( $file, $formLength ) {
+ // For now, we'll just look for the first page in the file
+ // and report its information, hoping others are the same size.
+ $start = ftell( $file );
+ do {
+ list( $chunk, $length ) = $this->readChunk( $file );
+ if( !$chunk ) {
+ break;
+ }
+
+ if( $chunk == 'FORM' ) {
+ $subtype = fread( $file, 4 );
+ if( $subtype == 'DJVU' ) {
+ wfDebug( __METHOD__ . ": found first subpage\n" );
+ return $this->getPageInfo( $file, $length );
+ }
+ $this->skipChunk( $file, $length - 4 );
+ } else {
+ wfDebug( __METHOD__ . ": skipping '$chunk' chunk\n" );
+ $this->skipChunk( $file, $length );
+ }
+ } while( $length != 0 && !feof( $file ) && ftell( $file ) - $start < $formLength );
+
+ wfDebug( __METHOD__ . ": multi-page DJVU file contained no pages\n" );
+ return false;
+ }
+
+ private function getPageInfo( $file, $formLength ) {
+ list( $chunk, $length ) = $this->readChunk( $file );
+ if( $chunk != 'INFO' ) {
+ wfDebug( __METHOD__ . ": expected INFO chunk, got '$chunk'\n" );
+ return false;
+ }
+
+ if( $length < 9 ) {
+ wfDebug( __METHOD__ . ": INFO should be 9 or 10 bytes, found $length\n" );
+ return false;
+ }
+ $data = fread( $file, $length );
+ if( strlen( $data ) < $length ) {
+ wfDebug( __METHOD__ . ": INFO chunk cut off\n" );
+ return false;
+ }
+
+ extract( unpack(
+ 'nwidth/' .
+ 'nheight/' .
+ 'Cminor/' .
+ 'Cmajor/' .
+ 'vresolution/' .
+ 'Cgamma', $data ) );
+ # Newer files have rotation info in byte 10, but we don't use it yet.
+
+ return array(
+ 'width' => $width,
+ 'height' => $height,
+ 'version' => "$major.$minor",
+ 'resolution' => $resolution,
+ 'gamma' => $gamma / 10.0 );
+ }
+
+ /**
+ * Return an XML string describing the DjVu image
+ * @return string
+ */
+ function retrieveMetaData() {
+ global $wgDjvuToXML;
+ if ( isset( $wgDjvuToXML ) ) {
+ $cmd = $wgDjvuToXML . ' --without-anno --without-text ' .
+ wfEscapeShellArg( $this->mFilename );
+ $xml = wfShellExec( $cmd );
+ } else {
+ $xml = null;
+ }
+ return $xml;
+ }
+
+}
+
+
+?>
diff --git a/includes/EditPage.php b/includes/EditPage.php
new file mode 100644
index 000000000000..7688a64aa926
--- /dev/null
+++ b/includes/EditPage.php
@@ -0,0 +1,1927 @@
+<?php
+/**
+ * Contain the EditPage class
+ * @package MediaWiki
+ */
+
+/**
+ * Splitting edit page/HTML interface from Article...
+ * The actual database and text munging is still in Article,
+ * but it should get easier to call those from alternate
+ * interfaces.
+ *
+ * @package MediaWiki
+ */
+
+class EditPage {
+ var $mArticle;
+ var $mTitle;
+ var $mMetaData = '';
+ var $isConflict = false;
+ var $isCssJsSubpage = false;
+ var $deletedSinceEdit = false;
+ var $formtype;
+ var $firsttime;
+ var $lastDelete;
+ var $mTokenOk = false;
+ var $mTriedSave = false;
+ var $tooBig = false;
+ var $kblength = false;
+ var $missingComment = false;
+ var $missingSummary = false;
+ var $allowBlankSummary = false;
+ var $autoSumm = '';
+ var $hookError = '';
+ var $mPreviewTemplates;
+
+ # Form values
+ var $save = false, $preview = false, $diff = false;
+ var $minoredit = false, $watchthis = false, $recreate = false;
+ var $textbox1 = '', $textbox2 = '', $summary = '';
+ var $edittime = '', $section = '', $starttime = '';
+ var $oldid = 0, $editintro = '', $scrolltop = null;
+
+ # Placeholders for text injection by hooks (must be HTML)
+ # extensions should take care to _append_ to the present value
+ public $editFormPageTop; // Before even the preview
+ public $editFormTextTop;
+ public $editFormTextAfterWarn;
+ public $editFormTextAfterTools;
+ public $editFormTextBottom;
+
+ /**
+ * @todo document
+ * @param $article
+ */
+ function EditPage( $article ) {
+ $this->mArticle =& $article;
+ global $wgTitle;
+ $this->mTitle =& $wgTitle;
+
+ # Placeholders for text injection by hooks (empty per default)
+ $this->editFormPageTop =
+ $this->editFormTextTop =
+ $this->editFormTextAfterWarn =
+ $this->editFormTextAfterTools =
+ $this->editFormTextBottom = "";
+ }
+
+ /**
+ * Fetch initial editing page content.
+ */
+ private function getContent() {
+ global $wgOut, $wgRequest, $wgParser;
+
+ # Get variables from query string :P
+ $section = $wgRequest->getVal( 'section' );
+ $preload = $wgRequest->getVal( 'preload' );
+ $undo = $wgRequest->getVal( 'undo' );
+
+ wfProfileIn( __METHOD__ );
+
+ $text = '';
+ if( !$this->mTitle->exists() ) {
+
+ # If requested, preload some text.
+ $text = $this->getPreloadedText( $preload );
+
+ # We used to put MediaWiki:Newarticletext here if
+ # $text was empty at this point.
+ # This is now shown above the edit box instead.
+ } else {
+ // FIXME: may be better to use Revision class directly
+ // But don't mess with it just yet. Article knows how to
+ // fetch the page record from the high-priority server,
+ // which is needed to guarantee we don't pick up lagged
+ // information.
+
+ $text = $this->mArticle->getContent();
+
+ if ( $undo > 0 ) {
+ #Undoing a specific edit overrides section editing; section-editing
+ # doesn't work with undoing.
+ $undorev = Revision::newFromId($undo);
+
+ #Sanity check, make sure it's the right page.
+ # Otherwise, $text will be left as-is.
+ if (!is_null($undorev) && $undorev->getPage() == $this->mArticle->getID()) {
+ $oldrev = $undorev->getPrevious();
+ $undorev_text = $undorev->getText();
+ $oldrev_text = $oldrev->getText();
+ $currev_text = $text;
+
+ #No use doing a merge if it's just a straight revert.
+ if ($currev_text != $undorev_text) {
+ $result = wfMerge($undorev_text, $oldrev_text, $currev_text, $text);
+ } else {
+ $text = $oldrev_text;
+ $result = true;
+ }
+
+ if( $result ) {
+ # Inform the user of our success and set an automatic edit summary
+ $this->editFormPageTop .= $wgOut->parse( wfMsgNoTrans( 'undo-success' ) );
+ $this->summary = wfMsgForContent( 'undo-summary', $undo, $undorev->getUserText() );
+ $this->formtype = 'diff';
+ } else {
+ # Warn the user that something went wrong
+ $this->editFormPageTop .= $wgOut->parse( wfMsgNoTrans( 'undo-failure' ) );
+ }
+
+ }
+ }
+ else if( $section != '' ) {
+ if( $section == 'new' ) {
+ $text = $this->getPreloadedText( $preload );
+ } else {
+ $text = $wgParser->getSection( $text, $section );
+ }
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * Get the contents of a page from its title and remove includeonly tags
+ *
+ * @param $preload String: the title of the page.
+ * @return string The contents of the page.
+ */
+ private function getPreloadedText($preload) {
+ if ( $preload === '' )
+ return '';
+ else {
+ $preloadTitle = Title::newFromText( $preload );
+ if ( isset( $preloadTitle ) && $preloadTitle->userCanRead() ) {
+ $rev=Revision::newFromTitle($preloadTitle);
+ if ( is_object( $rev ) ) {
+ $text = $rev->getText();
+ // TODO FIXME: AAAAAAAAAAA, this shouldn't be implementing
+ // its own mini-parser! -ævar
+ $text = preg_replace( '~</?includeonly>~', '', $text );
+ return $text;
+ } else
+ return '';
+ }
+ }
+ }
+
+ /**
+ * This is the function that extracts metadata from the article body on the first view.
+ * To turn the feature on, set $wgUseMetadataEdit = true ; in LocalSettings
+ * and set $wgMetadataWhitelist to the *full* title of the template whitelist
+ */
+ function extractMetaDataFromArticle () {
+ global $wgUseMetadataEdit , $wgMetadataWhitelist , $wgLang ;
+ $this->mMetaData = '' ;
+ if ( !$wgUseMetadataEdit ) return ;
+ if ( $wgMetadataWhitelist == '' ) return ;
+ $s = '' ;
+ $t = $this->getContent();
+
+ # MISSING : <nowiki> filtering
+
+ # Categories and language links
+ $t = explode ( "\n" , $t ) ;
+ $catlow = strtolower ( $wgLang->getNsText ( NS_CATEGORY ) ) ;
+ $cat = $ll = array() ;
+ foreach ( $t AS $key => $x )
+ {
+ $y = trim ( strtolower ( $x ) ) ;
+ while ( substr ( $y , 0 , 2 ) == '[[' )
+ {
+ $y = explode ( ']]' , trim ( $x ) ) ;
+ $first = array_shift ( $y ) ;
+ $first = explode ( ':' , $first ) ;
+ $ns = array_shift ( $first ) ;
+ $ns = trim ( str_replace ( '[' , '' , $ns ) ) ;
+ if ( strlen ( $ns ) == 2 OR strtolower ( $ns ) == $catlow )
+ {
+ $add = '[[' . $ns . ':' . implode ( ':' , $first ) . ']]' ;
+ if ( strtolower ( $ns ) == $catlow ) $cat[] = $add ;
+ else $ll[] = $add ;
+ $x = implode ( ']]' , $y ) ;
+ $t[$key] = $x ;
+ $y = trim ( strtolower ( $x ) ) ;
+ }
+ }
+ }
+ if ( count ( $cat ) ) $s .= implode ( ' ' , $cat ) . "\n" ;
+ if ( count ( $ll ) ) $s .= implode ( ' ' , $ll ) . "\n" ;
+ $t = implode ( "\n" , $t ) ;
+
+ # Load whitelist
+ $sat = array () ; # stand-alone-templates; must be lowercase
+ $wl_title = Title::newFromText ( $wgMetadataWhitelist ) ;
+ $wl_article = new Article ( $wl_title ) ;
+ $wl = explode ( "\n" , $wl_article->getContent() ) ;
+ foreach ( $wl AS $x )
+ {
+ $isentry = false ;
+ $x = trim ( $x ) ;
+ while ( substr ( $x , 0 , 1 ) == '*' )
+ {
+ $isentry = true ;
+ $x = trim ( substr ( $x , 1 ) ) ;
+ }
+ if ( $isentry )
+ {
+ $sat[] = strtolower ( $x ) ;
+ }
+
+ }
+
+ # Templates, but only some
+ $t = explode ( '{{' , $t ) ;
+ $tl = array () ;
+ foreach ( $t AS $key => $x )
+ {
+ $y = explode ( '}}' , $x , 2 ) ;
+ if ( count ( $y ) == 2 )
+ {
+ $z = $y[0] ;
+ $z = explode ( '|' , $z ) ;
+ $tn = array_shift ( $z ) ;
+ if ( in_array ( strtolower ( $tn ) , $sat ) )
+ {
+ $tl[] = '{{' . $y[0] . '}}' ;
+ $t[$key] = $y[1] ;
+ $y = explode ( '}}' , $y[1] , 2 ) ;
+ }
+ else $t[$key] = '{{' . $x ;
+ }
+ else if ( $key != 0 ) $t[$key] = '{{' . $x ;
+ else $t[$key] = $x ;
+ }
+ if ( count ( $tl ) ) $s .= implode ( ' ' , $tl ) ;
+ $t = implode ( '' , $t ) ;
+
+ $t = str_replace ( "\n\n\n" , "\n" , $t ) ;
+ $this->mArticle->mContent = $t ;
+ $this->mMetaData = $s ;
+ }
+
+ function submit() {
+ $this->edit();
+ }
+
+ /**
+ * This is the function that gets called for "action=edit". It
+ * sets up various member variables, then passes execution to
+ * another function, usually showEditForm()
+ *
+ * The edit form is self-submitting, so that when things like
+ * preview and edit conflicts occur, we get the same form back
+ * with the extra stuff added. Only when the final submission
+ * is made and all is well do we actually save and redirect to
+ * the newly-edited page.
+ */
+ function edit() {
+ global $wgOut, $wgUser, $wgRequest, $wgTitle;
+ global $wgEmailConfirmToEdit;
+
+ if ( ! wfRunHooks( 'AlternateEdit', array( &$this ) ) )
+ return;
+
+ $fname = 'EditPage::edit';
+ wfProfileIn( $fname );
+ wfDebug( "$fname: enter\n" );
+
+ // this is not an article
+ $wgOut->setArticleFlag(false);
+
+ $this->importFormData( $wgRequest );
+ $this->firsttime = false;
+
+ if( $this->live ) {
+ $this->livePreview();
+ wfProfileOut( $fname );
+ return;
+ }
+
+ if ( ! $this->mTitle->userCanEdit() ) {
+ wfDebug( "$fname: user can't edit\n" );
+ $wgOut->readOnlyPage( $this->getContent(), true );
+ wfProfileOut( $fname );
+ return;
+ }
+ wfDebug( "$fname: Checking blocks\n" );
+ if ( !$this->preview && !$this->diff && $wgUser->isBlockedFrom( $this->mTitle, !$this->save ) ) {
+ # When previewing, don't check blocked state - will get caught at save time.
+ # Also, check when starting edition is done against slave to improve performance.
+ wfDebug( "$fname: user is blocked\n" );
+ $this->blockedPage();
+ wfProfileOut( $fname );
+ return;
+ }
+ if ( !$wgUser->isAllowed('edit') ) {
+ if ( $wgUser->isAnon() ) {
+ wfDebug( "$fname: user must log in\n" );
+ $this->userNotLoggedInPage();
+ wfProfileOut( $fname );
+ return;
+ } else {
+ wfDebug( "$fname: read-only page\n" );
+ $wgOut->readOnlyPage( $this->getContent(), true );
+ wfProfileOut( $fname );
+ return;
+ }
+ }
+ if ($wgEmailConfirmToEdit && !$wgUser->isEmailConfirmed()) {
+ wfDebug("$fname: user must confirm e-mail address\n");
+ $this->userNotConfirmedPage();
+ wfProfileOut($fname);
+ return;
+ }
+ if ( !$this->mTitle->userCanCreate() && !$this->mTitle->exists() ) {
+ wfDebug( "$fname: no create permission\n" );
+ $this->noCreatePermission();
+ wfProfileOut( $fname );
+ return;
+ }
+ if ( wfReadOnly() ) {
+ wfDebug( "$fname: read-only mode is engaged\n" );
+ if( $this->save || $this->preview ) {
+ $this->formtype = 'preview';
+ } else if ( $this->diff ) {
+ $this->formtype = 'diff';
+ } else {
+ $wgOut->readOnlyPage( $this->getContent() );
+ wfProfileOut( $fname );
+ return;
+ }
+ } else {
+ if ( $this->save ) {
+ $this->formtype = 'save';
+ } else if ( $this->preview ) {
+ $this->formtype = 'preview';
+ } else if ( $this->diff ) {
+ $this->formtype = 'diff';
+ } else { # First time through
+ $this->firsttime = true;
+ if( $this->previewOnOpen() ) {
+ $this->formtype = 'preview';
+ } else {
+ $this->extractMetaDataFromArticle () ;
+ $this->formtype = 'initial';
+ }
+ }
+ }
+
+ wfProfileIn( "$fname-business-end" );
+
+ $this->isConflict = false;
+ // css / js subpages of user pages get a special treatment
+ $this->isCssJsSubpage = $wgTitle->isCssJsSubpage();
+ $this->isValidCssJsSubpage = $wgTitle->isValidCssJsSubpage();
+
+ /* Notice that we can't use isDeleted, because it returns true if article is ever deleted
+ * no matter it's current state
+ */
+ $this->deletedSinceEdit = false;
+ if ( $this->edittime != '' ) {
+ /* Note that we rely on logging table, which hasn't been always there,
+ * but that doesn't matter, because this only applies to brand new
+ * deletes. This is done on every preview and save request. Move it further down
+ * to only perform it on saves
+ */
+ if ( $this->mTitle->isDeleted() ) {
+ $this->lastDelete = $this->getLastDelete();
+ if ( !is_null($this->lastDelete) ) {
+ $deletetime = $this->lastDelete->log_timestamp;
+ if ( ($deletetime - $this->starttime) > 0 ) {
+ $this->deletedSinceEdit = true;
+ }
+ }
+ }
+ }
+
+ if(!$this->mTitle->getArticleID() && ('initial' == $this->formtype || $this->firsttime )) { # new article
+ $this->showIntro();
+ }
+ if( $this->mTitle->isTalkPage() ) {
+ $wgOut->addWikiText( wfMsg( 'talkpagetext' ) );
+ }
+
+ # Attempt submission here. This will check for edit conflicts,
+ # and redundantly check for locked database, blocked IPs, etc.
+ # that edit() already checked just in case someone tries to sneak
+ # in the back door with a hand-edited submission URL.
+
+ if ( 'save' == $this->formtype ) {
+ if ( !$this->attemptSave() ) {
+ wfProfileOut( "$fname-business-end" );
+ wfProfileOut( $fname );
+ return;
+ }
+ }
+
+ # First time through: get contents, set time for conflict
+ # checking, etc.
+ if ( 'initial' == $this->formtype || $this->firsttime ) {
+ $this->initialiseForm();
+ if( !$this->mTitle->getArticleId() )
+ wfRunHooks( 'EditFormPreloadText', array( &$this->textbox1, &$this->mTitle ) );
+ }
+
+ $this->showEditForm();
+ wfProfileOut( "$fname-business-end" );
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Return true if this page should be previewed when the edit form
+ * is initially opened.
+ * @return bool
+ * @private
+ */
+ function previewOnOpen() {
+ global $wgUser;
+ return $this->section != 'new' &&
+ ( ( $wgUser->getOption( 'previewonfirst' ) && $this->mTitle->exists() ) ||
+ ( $this->mTitle->getNamespace() == NS_CATEGORY &&
+ !$this->mTitle->exists() ) );
+ }
+
+ /**
+ * @todo document
+ * @param $request
+ */
+ function importFormData( &$request ) {
+ global $wgLang, $wgUser;
+ $fname = 'EditPage::importFormData';
+ wfProfileIn( $fname );
+
+ if( $request->wasPosted() ) {
+ # These fields need to be checked for encoding.
+ # Also remove trailing whitespace, but don't remove _initial_
+ # whitespace from the text boxes. This may be significant formatting.
+ $this->textbox1 = $this->safeUnicodeInput( $request, 'wpTextbox1' );
+ $this->textbox2 = $this->safeUnicodeInput( $request, 'wpTextbox2' );
+ $this->mMetaData = rtrim( $request->getText( 'metadata' ) );
+ # Truncate for whole multibyte characters. +5 bytes for ellipsis
+ $this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 250 );
+
+ $this->edittime = $request->getVal( 'wpEdittime' );
+ $this->starttime = $request->getVal( 'wpStarttime' );
+
+ $this->scrolltop = $request->getIntOrNull( 'wpScrolltop' );
+
+ if( is_null( $this->edittime ) ) {
+ # If the form is incomplete, force to preview.
+ wfDebug( "$fname: Form data appears to be incomplete\n" );
+ wfDebug( "POST DATA: " . var_export( $_POST, true ) . "\n" );
+ $this->preview = true;
+ } else {
+ /* Fallback for live preview */
+ $this->preview = $request->getCheck( 'wpPreview' ) || $request->getCheck( 'wpLivePreview' );
+ $this->diff = $request->getCheck( 'wpDiff' );
+
+ // Remember whether a save was requested, so we can indicate
+ // if we forced preview due to session failure.
+ $this->mTriedSave = !$this->preview;
+
+ if ( $this->tokenOk( $request ) ) {
+ # Some browsers will not report any submit button
+ # if the user hits enter in the comment box.
+ # The unmarked state will be assumed to be a save,
+ # if the form seems otherwise complete.
+ wfDebug( "$fname: Passed token check.\n" );
+ } else if ( $this->diff ) {
+ # Failed token check, but only requested "Show Changes".
+ wfDebug( "$fname: Failed token check; Show Changes requested.\n" );
+ } else {
+ # Page might be a hack attempt posted from
+ # an external site. Preview instead of saving.
+ wfDebug( "$fname: Failed token check; forcing preview\n" );
+ $this->preview = true;
+ }
+ }
+ $this->save = ! ( $this->preview OR $this->diff );
+ if( !preg_match( '/^\d{14}$/', $this->edittime )) {
+ $this->edittime = null;
+ }
+
+ if( !preg_match( '/^\d{14}$/', $this->starttime )) {
+ $this->starttime = null;
+ }
+
+ $this->recreate = $request->getCheck( 'wpRecreate' );
+
+ $this->minoredit = $request->getCheck( 'wpMinoredit' );
+ $this->watchthis = $request->getCheck( 'wpWatchthis' );
+
+ # Don't force edit summaries when a user is editing their own user or talk page
+ if( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK ) && $this->mTitle->getText() == $wgUser->getName() ) {
+ $this->allowBlankSummary = true;
+ } else {
+ $this->allowBlankSummary = $request->getBool( 'wpIgnoreBlankSummary' );
+ }
+
+ $this->autoSumm = $request->getText( 'wpAutoSummary' );
+ } else {
+ # Not a posted form? Start with nothing.
+ wfDebug( "$fname: Not a posted form.\n" );
+ $this->textbox1 = '';
+ $this->textbox2 = '';
+ $this->mMetaData = '';
+ $this->summary = '';
+ $this->edittime = '';
+ $this->starttime = wfTimestampNow();
+ $this->preview = false;
+ $this->save = false;
+ $this->diff = false;
+ $this->minoredit = false;
+ $this->watchthis = false;
+ $this->recreate = false;
+ }
+
+ $this->oldid = $request->getInt( 'oldid' );
+
+ # Section edit can come from either the form or a link
+ $this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
+
+ $this->live = $request->getCheck( 'live' );
+ $this->editintro = $request->getText( 'editintro' );
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Make sure the form isn't faking a user's credentials.
+ *
+ * @param $request WebRequest
+ * @return bool
+ * @private
+ */
+ function tokenOk( &$request ) {
+ global $wgUser;
+ if( $wgUser->isAnon() ) {
+ # Anonymous users may not have a session
+ # open. Check for suffix anyway.
+ $this->mTokenOk = ( EDIT_TOKEN_SUFFIX == $request->getVal( 'wpEditToken' ) );
+ } else {
+ $this->mTokenOk = $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
+ }
+ return $this->mTokenOk;
+ }
+
+ /** */
+ function showIntro() {
+ global $wgOut, $wgUser;
+ $addstandardintro=true;
+ if($this->editintro) {
+ $introtitle=Title::newFromText($this->editintro);
+ if(isset($introtitle) && $introtitle->userCanRead()) {
+ $rev=Revision::newFromTitle($introtitle);
+ if($rev) {
+ $wgOut->addSecondaryWikiText($rev->getText());
+ $addstandardintro=false;
+ }
+ }
+ }
+ if($addstandardintro) {
+ if ( $wgUser->isLoggedIn() )
+ $wgOut->addWikiText( wfMsg( 'newarticletext' ) );
+ else
+ $wgOut->addWikiText( wfMsg( 'newarticletextanon' ) );
+ }
+ }
+
+ /**
+ * Attempt submission
+ * @return bool false if output is done, true if the rest of the form should be displayed
+ */
+ function attemptSave() {
+ global $wgSpamRegex, $wgFilterCallback, $wgUser, $wgOut;
+ global $wgMaxArticleSize;
+
+ $fname = 'EditPage::attemptSave';
+ wfProfileIn( $fname );
+ wfProfileIn( "$fname-checks" );
+
+ if( !wfRunHooks( 'EditPage::attemptSave', array( &$this ) ) )
+ {
+ wfDebug( "Hook 'EditPage::attemptSave' aborted article saving" );
+ return false;
+ }
+
+ # Reintegrate metadata
+ if ( $this->mMetaData != '' ) $this->textbox1 .= "\n" . $this->mMetaData ;
+ $this->mMetaData = '' ;
+
+ # Check for spam
+ $matches = array();
+ if ( $wgSpamRegex && preg_match( $wgSpamRegex, $this->textbox1, $matches ) ) {
+ $this->spamPage ( $matches[0] );
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ if ( $wgFilterCallback && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section ) ) {
+ # Error messages or other handling should be performed by the filter function
+ wfProfileOut( $fname );
+ wfProfileOut( "$fname-checks" );
+ return false;
+ }
+ if ( !wfRunHooks( 'EditFilter', array( $this, $this->textbox1, $this->section, &$this->hookError ) ) ) {
+ # Error messages etc. could be handled within the hook...
+ wfProfileOut( $fname );
+ wfProfileOut( "$fname-checks" );
+ return false;
+ } elseif( $this->hookError != '' ) {
+ # ...or the hook could be expecting us to produce an error
+ wfProfileOut( "$fname-checks " );
+ wfProfileOut( $fname );
+ return true;
+ }
+ if ( $wgUser->isBlockedFrom( $this->mTitle, false ) ) {
+ # Check block state against master, thus 'false'.
+ $this->blockedPage();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ $this->kblength = (int)(strlen( $this->textbox1 ) / 1024);
+ if ( $this->kblength > $wgMaxArticleSize ) {
+ // Error will be displayed by showEditForm()
+ $this->tooBig = true;
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ if ( !$wgUser->isAllowed('edit') ) {
+ if ( $wgUser->isAnon() ) {
+ $this->userNotLoggedInPage();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ else {
+ $wgOut->readOnlyPage();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ }
+
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ if ( $wgUser->pingLimiter() ) {
+ $wgOut->rateLimited();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ # If the article has been deleted while editing, don't save it without
+ # confirmation
+ if ( $this->deletedSinceEdit && !$this->recreate ) {
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ wfProfileOut( "$fname-checks" );
+
+ # If article is new, insert it.
+ $aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
+ if ( 0 == $aid ) {
+
+ // Late check for create permission, just in case *PARANOIA*
+ if ( !$this->mTitle->userCanCreate() ) {
+ wfDebug( "$fname: no create permission\n" );
+ $this->noCreatePermission();
+ wfProfileOut( $fname );
+ return;
+ }
+
+ # Don't save a new article if it's blank.
+ if ( ( '' == $this->textbox1 ) ) {
+ $wgOut->redirect( $this->mTitle->getFullURL() );
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ $isComment=($this->section=='new');
+ $this->mArticle->insertNewArticle( $this->textbox1, $this->summary,
+ $this->minoredit, $this->watchthis, false, $isComment);
+
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ # Article exists. Check for edit conflict.
+
+ $this->mArticle->clear(); # Force reload of dates, etc.
+ $this->mArticle->forUpdate( true ); # Lock the article
+
+ if( $this->mArticle->getTimestamp() != $this->edittime ) {
+ $this->isConflict = true;
+ if( $this->section == 'new' ) {
+ if( $this->mArticle->getUserText() == $wgUser->getName() &&
+ $this->mArticle->getComment() == $this->summary ) {
+ // Probably a duplicate submission of a new comment.
+ // This can happen when squid resends a request after
+ // a timeout but the first one actually went through.
+ wfDebug( "EditPage::editForm duplicate new section submission; trigger edit conflict!\n" );
+ } else {
+ // New comment; suppress conflict.
+ $this->isConflict = false;
+ wfDebug( "EditPage::editForm conflict suppressed; new section\n" );
+ }
+ }
+ }
+ $userid = $wgUser->getID();
+
+ if ( $this->isConflict) {
+ wfDebug( "EditPage::editForm conflict! getting section '$this->section' for time '$this->edittime' (article time '" .
+ $this->mArticle->getTimestamp() . "'\n" );
+ $text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $this->summary, $this->edittime);
+ }
+ else {
+ wfDebug( "EditPage::editForm getting section '$this->section'\n" );
+ $text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $this->summary);
+ }
+ if( is_null( $text ) ) {
+ wfDebug( "EditPage::editForm activating conflict; section replace failed.\n" );
+ $this->isConflict = true;
+ $text = $this->textbox1;
+ }
+
+ # Suppress edit conflict with self, except for section edits where merging is required.
+ if ( ( $this->section == '' ) && ( 0 != $userid ) && ( $this->mArticle->getUser() == $userid ) ) {
+ wfDebug( "Suppressing edit conflict, same user.\n" );
+ $this->isConflict = false;
+ } else {
+ # switch from section editing to normal editing in edit conflict
+ if($this->isConflict) {
+ # Attempt merge
+ if( $this->mergeChangesInto( $text ) ){
+ // Successful merge! Maybe we should tell the user the good news?
+ $this->isConflict = false;
+ wfDebug( "Suppressing edit conflict, successful merge.\n" );
+ } else {
+ $this->section = '';
+ $this->textbox1 = $text;
+ wfDebug( "Keeping edit conflict, failed merge.\n" );
+ }
+ }
+ }
+
+ if ( $this->isConflict ) {
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ $oldtext = $this->mArticle->getContent();
+
+ # Handle the user preference to force summaries here, but not for null edits
+ if( $this->section != 'new' && !$this->allowBlankSummary && $wgUser->getOption( 'forceeditsummary')
+ && 0 != strcmp($oldtext, $text) && !Article::getRedirectAutosummary( $text )) {
+ if( md5( $this->summary ) == $this->autoSumm ) {
+ $this->missingSummary = true;
+ wfProfileOut( $fname );
+ return( true );
+ }
+ }
+
+ #And a similar thing for new sections
+ if( $this->section == 'new' && !$this->allowBlankSummary && $wgUser->getOption( 'forceeditsummary' ) ) {
+ if (trim($this->summary) == '') {
+ $this->missingSummary = true;
+ wfProfileOut( $fname );
+ return( true );
+ }
+ }
+
+ # All's well
+ wfProfileIn( "$fname-sectionanchor" );
+ $sectionanchor = '';
+ if( $this->section == 'new' ) {
+ if ( $this->textbox1 == '' ) {
+ $this->missingComment = true;
+ return true;
+ }
+ if( $this->summary != '' ) {
+ $sectionanchor = $this->sectionAnchor( $this->summary );
+ }
+ } elseif( $this->section != '' ) {
+ # Try to get a section anchor from the section source, redirect to edited section if header found
+ # XXX: might be better to integrate this into Article::replaceSection
+ # for duplicate heading checking and maybe parsing
+ $hasmatch = preg_match( "/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
+ # we can't deal with anchors, includes, html etc in the header for now,
+ # headline would need to be parsed to improve this
+ if($hasmatch and strlen($matches[2]) > 0) {
+ $sectionanchor = $this->sectionAnchor( $matches[2] );
+ }
+ }
+ wfProfileOut( "$fname-sectionanchor" );
+
+ // Save errors may fall down to the edit form, but we've now
+ // merged the section into full text. Clear the section field
+ // so that later submission of conflict forms won't try to
+ // replace that into a duplicated mess.
+ $this->textbox1 = $text;
+ $this->section = '';
+
+ // Check for length errors again now that the section is merged in
+ $this->kblength = (int)(strlen( $text ) / 1024);
+ if ( $this->kblength > $wgMaxArticleSize ) {
+ $this->tooBig = true;
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ # update the article here
+ if( $this->mArticle->updateArticle( $text, $this->summary, $this->minoredit,
+ $this->watchthis, '', $sectionanchor ) ) {
+ wfProfileOut( $fname );
+ return false;
+ } else {
+ $this->isConflict = true;
+ }
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ /**
+ * Initialise form fields in the object
+ * Called on the first invocation, e.g. when a user clicks an edit link
+ */
+ function initialiseForm() {
+ $this->edittime = $this->mArticle->getTimestamp();
+ $this->summary = '';
+ $this->textbox1 = $this->getContent();
+ if ( !$this->mArticle->exists() && $this->mArticle->mTitle->getNamespace() == NS_MEDIAWIKI )
+ $this->textbox1 = wfMsgWeirdKey( $this->mArticle->mTitle->getText() ) ;
+ wfProxyCheck();
+ }
+
+ /**
+ * Send the edit form and related headers to $wgOut
+ * @param $formCallback Optional callable that takes an OutputPage
+ * parameter; will be called during form output
+ * near the top, for captchas and the like.
+ */
+ function showEditForm( $formCallback=null ) {
+ global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize;
+
+ $fname = 'EditPage::showEditForm';
+ wfProfileIn( $fname );
+
+ $sk =& $wgUser->getSkin();
+
+ wfRunHooks( 'EditPage::showEditForm:initial', array( &$this ) ) ;
+
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ # Enabled article-related sidebar, toplinks, etc.
+ $wgOut->setArticleRelated( true );
+
+ if ( $this->isConflict ) {
+ $s = wfMsg( 'editconflict', $this->mTitle->getPrefixedText() );
+ $wgOut->setPageTitle( $s );
+ $wgOut->addWikiText( wfMsg( 'explainconflict' ) );
+
+ $this->textbox2 = $this->textbox1;
+ $this->textbox1 = $this->getContent();
+ $this->edittime = $this->mArticle->getTimestamp();
+ } else {
+
+ if( $this->section != '' ) {
+ if( $this->section == 'new' ) {
+ $s = wfMsg('editingcomment', $this->mTitle->getPrefixedText() );
+ } else {
+ $s = wfMsg('editingsection', $this->mTitle->getPrefixedText() );
+ $matches = array();
+ if( !$this->summary && !$this->preview && !$this->diff ) {
+ preg_match( "/^(=+)(.+)\\1/mi",
+ $this->textbox1,
+ $matches );
+ if( !empty( $matches[2] ) ) {
+ $this->summary = "/* ". trim($matches[2])." */ ";
+ }
+ }
+ }
+ } else {
+ $s = wfMsg( 'editing', $this->mTitle->getPrefixedText() );
+ }
+ $wgOut->setPageTitle( $s );
+
+ if ( $this->missingComment ) {
+ $wgOut->addWikiText( wfMsg( 'missingcommenttext' ) );
+ }
+
+ if( $this->missingSummary && $this->section != 'new' ) {
+ $wgOut->addWikiText( wfMsg( 'missingsummary' ) );
+ }
+
+ if( $this->missingSummary && $this->section == 'new' ) {
+ $wgOut->addWikiText( wfMsg( 'missingcommentheader' ) );
+ }
+
+ if( !$this->hookError == '' ) {
+ $wgOut->addWikiText( $this->hookError );
+ }
+
+ if ( !$this->checkUnicodeCompliantBrowser() ) {
+ $wgOut->addWikiText( wfMsg( 'nonunicodebrowser') );
+ }
+ if ( isset( $this->mArticle )
+ && isset( $this->mArticle->mRevision )
+ && !$this->mArticle->mRevision->isCurrent() ) {
+ $this->mArticle->setOldSubtitle( $this->mArticle->mRevision->getId() );
+ $wgOut->addWikiText( wfMsg( 'editingold' ) );
+ }
+ }
+
+ if( wfReadOnly() ) {
+ $wgOut->addWikiText( wfMsg( 'readonlywarning' ) );
+ } elseif( $wgUser->isAnon() && $this->formtype != 'preview' ) {
+ $wgOut->addWikiText( wfMsg( 'anoneditwarning' ) );
+ } else {
+ if( $this->isCssJsSubpage && $this->formtype != 'preview' ) {
+ # Check the skin exists
+ if( $this->isValidCssJsSubpage ) {
+ $wgOut->addWikiText( wfMsg( 'usercssjsyoucanpreview' ) );
+ } else {
+ $wgOut->addWikiText( wfMsg( 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() ) );
+ }
+ }
+ }
+
+ if( $this->mTitle->isProtected( 'edit' ) ) {
+ # Is the protection due to the namespace, e.g. interface text?
+ if( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+ # Yes; remind the user
+ $notice = wfMsg( 'editinginterface' );
+ } elseif( $this->mTitle->isSemiProtected() ) {
+ # No; semi protected
+ $notice = wfMsg( 'semiprotectedpagewarning' );
+ if( wfEmptyMsg( 'semiprotectedpagewarning', $notice ) || $notice == '-' ) {
+ $notice = '';
+ }
+ } else {
+ # No; regular protection
+ $notice = wfMsg( 'protectedpagewarning' );
+ }
+ $wgOut->addWikiText( $notice );
+ }
+
+ if ( $this->kblength === false ) {
+ $this->kblength = (int)(strlen( $this->textbox1 ) / 1024);
+ }
+ if ( $this->tooBig || $this->kblength > $wgMaxArticleSize ) {
+ $wgOut->addWikiText( wfMsg( 'longpageerror', $wgLang->formatNum( $this->kblength ), $wgMaxArticleSize ) );
+ } elseif( $this->kblength > 29 ) {
+ $wgOut->addWikiText( wfMsg( 'longpagewarning', $wgLang->formatNum( $this->kblength ) ) );
+ }
+
+ #need to parse the preview early so that we know which templates are used,
+ #otherwise users with "show preview after edit box" will get a blank list
+ if ( $this->formtype == 'preview' ) {
+ $previewOutput = $this->getPreviewText();
+ }
+
+ $rows = $wgUser->getIntOption( 'rows' );
+ $cols = $wgUser->getIntOption( 'cols' );
+
+ $ew = $wgUser->getOption( 'editwidth' );
+ if ( $ew ) $ew = " style=\"width:100%\"";
+ else $ew = '';
+
+ $q = 'action=submit';
+ #if ( "no" == $redirect ) { $q .= "&redirect=no"; }
+ $action = $this->mTitle->escapeLocalURL( $q );
+
+ $summary = wfMsg('summary');
+ $subject = wfMsg('subject');
+ $minor = wfMsgExt('minoredit', array('parseinline'));
+ $watchthis = wfMsgExt('watchthis', array('parseinline'));
+
+ $cancel = $sk->makeKnownLink( $this->mTitle->getPrefixedText(),
+ wfMsgExt('cancel', array('parseinline')) );
+ $edithelpurl = Skin::makeInternalOrExternalUrl( wfMsgForContent( 'edithelppage' ));
+ $edithelp = '<a target="helpwindow" href="'.$edithelpurl.'">'.
+ htmlspecialchars( wfMsg( 'edithelp' ) ).'</a> '.
+ htmlspecialchars( wfMsg( 'newwindow' ) );
+
+ global $wgRightsText;
+ $copywarn = "<div id=\"editpage-copywarn\">\n" .
+ wfMsg( $wgRightsText ? 'copyrightwarning' : 'copyrightwarning2',
+ '[[' . wfMsgForContent( 'copyrightpage' ) . ']]',
+ $wgRightsText ) . "\n</div>";
+
+ if( $wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage ) {
+ # prepare toolbar for edit buttons
+ $toolbar = $this->getEditToolbar();
+ } else {
+ $toolbar = '';
+ }
+
+ // activate checkboxes if user wants them to be always active
+ if( !$this->preview && !$this->diff ) {
+ # Sort out the "watch" checkbox
+ if( $wgUser->getOption( 'watchdefault' ) ) {
+ # Watch all edits
+ $this->watchthis = true;
+ } elseif( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
+ # Watch creations
+ $this->watchthis = true;
+ } elseif( $this->mTitle->userIsWatching() ) {
+ # Already watched
+ $this->watchthis = true;
+ }
+
+ if( $wgUser->getOption( 'minordefault' ) ) $this->minoredit = true;
+ }
+
+ $minoredithtml = '';
+
+ if ( $wgUser->isAllowed('minoredit') ) {
+ $minoredithtml =
+ "<input tabindex='3' type='checkbox' value='1' name='wpMinoredit'".($this->minoredit?" checked='checked'":"").
+ " accesskey='".wfMsg('accesskey-minoredit')."' id='wpMinoredit' />\n".
+ "<label for='wpMinoredit' title='".wfMsg('tooltip-minoredit')."'>{$minor}</label>\n";
+ }
+
+ $watchhtml = '';
+
+ if ( $wgUser->isLoggedIn() ) {
+ $watchhtml = "<input tabindex='4' type='checkbox' name='wpWatchthis'".
+ ($this->watchthis?" checked='checked'":"").
+ " accesskey=\"".htmlspecialchars(wfMsg('accesskey-watch'))."\" id='wpWatchthis' />\n".
+ "<label for='wpWatchthis' title=\"" .
+ htmlspecialchars(wfMsg('tooltip-watch'))."\">{$watchthis}</label>\n";
+ }
+
+ $checkboxhtml = $minoredithtml . $watchhtml;
+
+ $wgOut->addHTML( $this->editFormPageTop );
+
+ if ( $wgUser->getOption( 'previewontop' ) ) {
+
+ if ( 'preview' == $this->formtype ) {
+ $this->showPreview( $previewOutput );
+ } else {
+ $wgOut->addHTML( '<div id="wikiPreview"></div>' );
+ }
+
+ if ( 'diff' == $this->formtype ) {
+ $wgOut->addHTML( $this->getDiff() );
+ }
+ }
+
+
+ $wgOut->addHTML( $this->editFormTextTop );
+
+ # if this is a comment, show a subject line at the top, which is also the edit summary.
+ # Otherwise, show a summary field at the bottom
+ $summarytext = htmlspecialchars( $wgContLang->recodeForEdit( $this->summary ) ); # FIXME
+ if( $this->section == 'new' ) {
+ $commentsubject="<span id='wpSummaryLabel'><label for='wpSummary'>{$subject}:</label></span>\n<div class='editOptions'>\n<input tabindex='1' type='text' value=\"$summarytext\" name='wpSummary' id='wpSummary' maxlength='200' size='60' /><br />";
+ $editsummary = '';
+ $subjectpreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">".wfMsg('subject-preview').':'.$sk->commentBlock( $this->summary, $this->mTitle )."</div>\n" : '';
+ $summarypreview = '';
+ } else {
+ $commentsubject = '';
+ $editsummary="<span id='wpSummaryLabel'><label for='wpSummary'>{$summary}:</label></span>\n<div class='editOptions'>\n<input tabindex='2' type='text' value=\"$summarytext\" name='wpSummary' id='wpSummary' maxlength='200' size='60' /><br />";
+ $summarypreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">".wfMsg('summary-preview').':'.$sk->commentBlock( $this->summary, $this->mTitle )."</div>\n" : '';
+ $subjectpreview = '';
+ }
+
+ # Set focus to the edit box on load, except on preview or diff, where it would interfere with the display
+ if( !$this->preview && !$this->diff ) {
+ $wgOut->setOnloadHandler( 'document.editform.wpTextbox1.focus()' );
+ }
+ $templates = ($this->preview || $this->section) ? $this->mPreviewTemplates : $this->mArticle->getUsedTemplates();
+ $formattedtemplates = $sk->formatTemplates( $templates, $this->preview, $this->section != '');
+
+ global $wgUseMetadataEdit ;
+ if ( $wgUseMetadataEdit ) {
+ $metadata = $this->mMetaData ;
+ $metadata = htmlspecialchars( $wgContLang->recodeForEdit( $metadata ) ) ;
+ $top = wfMsgWikiHtml( 'metadata_help' );
+ $metadata = $top . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>" ;
+ }
+ else $metadata = "" ;
+
+ $hidden = '';
+ $recreate = '';
+ if ($this->deletedSinceEdit) {
+ if ( 'save' != $this->formtype ) {
+ $wgOut->addWikiText( wfMsg('deletedwhileediting'));
+ } else {
+ // Hide the toolbar and edit area, use can click preview to get it back
+ // Add an confirmation checkbox and explanation.
+ $toolbar = '';
+ $hidden = 'type="hidden" style="display:none;"';
+ $recreate = $wgOut->parse( wfMsg( 'confirmrecreate', $this->lastDelete->user_name , $this->lastDelete->log_comment ));
+ $recreate .=
+ "<br /><input tabindex='1' type='checkbox' value='1' name='wpRecreate' id='wpRecreate' />".
+ "<label for='wpRecreate' title='".wfMsg('tooltip-recreate')."'>". wfMsg('recreate')."</label>";
+ }
+ }
+
+ $temp = array(
+ 'id' => 'wpSave',
+ 'name' => 'wpSave',
+ 'type' => 'submit',
+ 'tabindex' => '5',
+ 'value' => wfMsg('savearticle'),
+ 'accesskey' => wfMsg('accesskey-save'),
+ 'title' => wfMsg('tooltip-save'),
+ );
+ $buttons['save'] = wfElement('input', $temp, '');
+ $temp = array(
+ 'id' => 'wpDiff',
+ 'name' => 'wpDiff',
+ 'type' => 'submit',
+ 'tabindex' => '7',
+ 'value' => wfMsg('showdiff'),
+ 'accesskey' => wfMsg('accesskey-diff'),
+ 'title' => wfMsg('tooltip-diff'),
+ );
+ $buttons['diff'] = wfElement('input', $temp, '');
+
+ global $wgLivePreview;
+ if ( $wgLivePreview && $wgUser->getOption( 'uselivepreview' ) ) {
+ $temp = array(
+ 'id' => 'wpPreview',
+ 'name' => 'wpPreview',
+ 'type' => 'submit',
+ 'tabindex' => '6',
+ 'value' => wfMsg('showpreview'),
+ 'accesskey' => '',
+ 'title' => wfMsg('tooltip-preview'),
+ 'style' => 'display: none;',
+ );
+ $buttons['preview'] = wfElement('input', $temp, '');
+ $temp = array(
+ 'id' => 'wpLivePreview',
+ 'name' => 'wpLivePreview',
+ 'type' => 'submit',
+ 'tabindex' => '6',
+ 'value' => wfMsg('showlivepreview'),
+ 'accesskey' => wfMsg('accesskey-preview'),
+ 'title' => '',
+ 'onclick' => $this->doLivePreviewScript(),
+ );
+ $buttons['live'] = wfElement('input', $temp, '');
+ } else {
+ $temp = array(
+ 'id' => 'wpPreview',
+ 'name' => 'wpPreview',
+ 'type' => 'submit',
+ 'tabindex' => '6',
+ 'value' => wfMsg('showpreview'),
+ 'accesskey' => wfMsg('accesskey-preview'),
+ 'title' => wfMsg('tooltip-preview'),
+ );
+ $buttons['preview'] = wfElement('input', $temp, '');
+ $buttons['live'] = '';
+ }
+
+ $safemodehtml = $this->checkUnicodeCompliantBrowser()
+ ? ""
+ : "<input type='hidden' name=\"safemode\" value='1' />\n";
+
+ $wgOut->addHTML( <<<END
+{$toolbar}
+<form id="editform" name="editform" method="post" action="$action" enctype="multipart/form-data">
+END
+);
+
+ if( is_callable( $formCallback ) ) {
+ call_user_func_array( $formCallback, array( &$wgOut ) );
+ }
+
+ // Put these up at the top to ensure they aren't lost on early form submission
+ $wgOut->addHTML( "
+<input type='hidden' value=\"" . htmlspecialchars( $this->section ) . "\" name=\"wpSection\" />
+<input type='hidden' value=\"{$this->starttime}\" name=\"wpStarttime\" />\n
+<input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n
+<input type='hidden' value=\"{$this->scrolltop}\" name=\"wpScrolltop\" id=\"wpScrolltop\" />\n" );
+
+ $wgOut->addHTML( <<<END
+$recreate
+{$commentsubject}
+{$subjectpreview}
+<textarea tabindex='1' accesskey="," name="wpTextbox1" id="wpTextbox1" rows='{$rows}'
+cols='{$cols}'{$ew} $hidden>
+END
+. htmlspecialchars( $this->safeUnicodeOutput( $this->textbox1 ) ) .
+"
+</textarea>
+ " );
+
+ $wgOut->addWikiText( $copywarn );
+ $wgOut->addHTML( $this->editFormTextAfterWarn );
+ $wgOut->addHTML( "
+{$metadata}
+{$editsummary}
+{$summarypreview}
+{$checkboxhtml}
+{$safemodehtml}
+");
+
+ $wgOut->addHTML(
+"<div class='editButtons'>
+ {$buttons['save']}
+ {$buttons['preview']}
+ {$buttons['live']}
+ {$buttons['diff']}
+ <span class='editHelp'>{$cancel} | {$edithelp}</span>
+</div><!-- editButtons -->
+</div><!-- editOptions -->");
+
+ $wgOut->addHtml( '<div class="mw-editTools">' );
+ $wgOut->addWikiText( wfMsgForContent( 'edittools' ) );
+ $wgOut->addHtml( '</div>' );
+
+ $wgOut->addHTML( $this->editFormTextAfterTools );
+
+ $wgOut->addHTML( "
+<div class='templatesUsed'>
+{$formattedtemplates}
+</div>
+" );
+
+ /**
+ * To make it harder for someone to slip a user a page
+ * which submits an edit form to the wiki without their
+ * knowledge, a random token is associated with the login
+ * session. If it's not passed back with the submission,
+ * we won't save the page, or render user JavaScript and
+ * CSS previews.
+ *
+ * For anon editors, who may not have a session, we just
+ * include the constant suffix to prevent editing from
+ * broken text-mangling proxies.
+ */
+ if ( $wgUser->isLoggedIn() )
+ $token = htmlspecialchars( $wgUser->editToken() );
+ else
+ $token = EDIT_TOKEN_SUFFIX;
+ $wgOut->addHTML( "\n<input type='hidden' value=\"$token\" name=\"wpEditToken\" />\n" );
+
+
+ # If a blank edit summary was previously provided, and the appropriate
+ # user preference is active, pass a hidden tag here. This will stop the
+ # user being bounced back more than once in the event that a summary
+ # is not required.
+ if( $this->missingSummary ) {
+ $wgOut->addHTML( "<input type=\"hidden\" name=\"wpIgnoreBlankSummary\" value=\"1\" />\n" );
+ }
+
+ # For a bit more sophisticated detection of blank summaries, hash the
+ # automatic one and pass that in a hidden field.
+ $autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
+ $wgOut->addHtml( wfHidden( 'wpAutoSummary', $autosumm ) );
+
+ if ( $this->isConflict ) {
+ $wgOut->addWikiText( '==' . wfMsg( "yourdiff" ) . '==' );
+
+ $de = new DifferenceEngine( $this->mTitle );
+ $de->setText( $this->textbox2, $this->textbox1 );
+ $de->showDiff( wfMsg( "yourtext" ), wfMsg( "storedversion" ) );
+
+ $wgOut->addWikiText( '==' . wfMsg( "yourtext" ) . '==' );
+ $wgOut->addHTML( "<textarea tabindex=6 id='wpTextbox2' name=\"wpTextbox2\" rows='{$rows}' cols='{$cols}' wrap='virtual'>"
+ . htmlspecialchars( $this->safeUnicodeOutput( $this->textbox2 ) ) . "\n</textarea>" );
+ }
+ $wgOut->addHTML( $this->editFormTextBottom );
+ $wgOut->addHTML( "</form>\n" );
+ if ( !$wgUser->getOption( 'previewontop' ) ) {
+
+ if ( $this->formtype == 'preview') {
+ $this->showPreview( $previewOutput );
+ } else {
+ $wgOut->addHTML( '<div id="wikiPreview"></div>' );
+ }
+
+ if ( $this->formtype == 'diff') {
+ $wgOut->addHTML( $this->getDiff() );
+ }
+
+ }
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Append preview output to $wgOut.
+ * Includes category rendering if this is a category page.
+ *
+ * @param string $text The HTML to be output for the preview.
+ */
+ private function showPreview( $text ) {
+ global $wgOut;
+
+ $wgOut->addHTML( '<div id="wikiPreview">' );
+ if($this->mTitle->getNamespace() == NS_CATEGORY) {
+ $this->mArticle->openShowCategory();
+ }
+ $wgOut->addHTML( $text );
+ if($this->mTitle->getNamespace() == NS_CATEGORY) {
+ $this->mArticle->closeShowCategory();
+ }
+ $wgOut->addHTML( '</div>' );
+ }
+
+ /**
+ * Live Preview lets us fetch rendered preview page content and
+ * add it to the page without refreshing the whole page.
+ * If not supported by the browser it will fall through to the normal form
+ * submission method.
+ *
+ * This function outputs a script tag to support live preview, and
+ * returns an onclick handler which should be added to the attributes
+ * of the preview button
+ */
+ function doLivePreviewScript() {
+ global $wgStylePath, $wgJsMimeType, $wgStyleVersion, $wgOut, $wgTitle;
+ $wgOut->addHTML( '<script type="'.$wgJsMimeType.'" src="' .
+ htmlspecialchars( "$wgStylePath/common/preview.js?$wgStyleVersion" ) .
+ '"></script>' . "\n" );
+ $liveAction = $wgTitle->getLocalUrl( 'action=submit&wpPreview=true&live=true' );
+ return "return !livePreview(" .
+ "getElementById('wikiPreview')," .
+ "editform.wpTextbox1.value," .
+ '"' . $liveAction . '"' . ")";
+ }
+
+ function getLastDelete() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $fname = 'EditPage::getLastDelete';
+ $res = $dbr->select(
+ array( 'logging', 'user' ),
+ array( 'log_type',
+ 'log_action',
+ 'log_timestamp',
+ 'log_user',
+ 'log_namespace',
+ 'log_title',
+ 'log_comment',
+ 'log_params',
+ 'user_name', ),
+ array( 'log_namespace' => $this->mTitle->getNamespace(),
+ 'log_title' => $this->mTitle->getDBkey(),
+ 'log_type' => 'delete',
+ 'log_action' => 'delete',
+ 'user_id=log_user' ),
+ $fname,
+ array( 'LIMIT' => 1, 'ORDER BY' => 'log_timestamp DESC' ) );
+
+ if($dbr->numRows($res) == 1) {
+ while ( $x = $dbr->fetchObject ( $res ) )
+ $data = $x;
+ $dbr->freeResult ( $res ) ;
+ } else {
+ $data = null;
+ }
+ return $data;
+ }
+
+ /**
+ * @todo document
+ */
+ function getPreviewText() {
+ global $wgOut, $wgUser, $wgTitle, $wgParser;
+
+ $fname = 'EditPage::getPreviewText';
+ wfProfileIn( $fname );
+
+ if ( $this->mTriedSave && !$this->mTokenOk ) {
+ $msg = 'session_fail_preview';
+ } else {
+ $msg = 'previewnote';
+ }
+ $previewhead = '<h2>' . htmlspecialchars( wfMsg( 'preview' ) ) . "</h2>\n" .
+ "<div class='previewnote'>" . $wgOut->parse( wfMsg( $msg ) ) . "</div>\n";
+ if ( $this->isConflict ) {
+ $previewhead.='<h2>' . htmlspecialchars( wfMsg( 'previewconflict' ) ) . "</h2>\n";
+ }
+
+ $parserOptions = ParserOptions::newFromUser( $wgUser );
+ $parserOptions->setEditSection( false );
+
+ global $wgRawHtml;
+ if( $wgRawHtml && !$this->mTokenOk ) {
+ // Could be an offsite preview attempt. This is very unsafe if
+ // HTML is enabled, as it could be an attack.
+ return $wgOut->parse( "<div class='previewnote'>" .
+ wfMsg( 'session_fail_preview_html' ) . "</div>" );
+ }
+
+ # don't parse user css/js, show message about preview
+ # XXX: stupid php bug won't let us use $wgTitle->isCssJsSubpage() here
+
+ if ( $this->isCssJsSubpage ) {
+ if(preg_match("/\\.css$/", $wgTitle->getText() ) ) {
+ $previewtext = wfMsg('usercsspreview');
+ } else if(preg_match("/\\.js$/", $wgTitle->getText() ) ) {
+ $previewtext = wfMsg('userjspreview');
+ }
+ $parserOptions->setTidy(true);
+ $parserOutput = $wgParser->parse( $previewtext , $wgTitle, $parserOptions );
+ $wgOut->addHTML( $parserOutput->mText );
+ wfProfileOut( $fname );
+ return $previewhead;
+ } else {
+ $toparse = $this->textbox1;
+
+ # If we're adding a comment, we need to show the
+ # summary as the headline
+ if($this->section=="new" && $this->summary!="") {
+ $toparse="== {$this->summary} ==\n\n".$toparse;
+ }
+
+ if ( $this->mMetaData != "" ) $toparse .= "\n" . $this->mMetaData ;
+ $parserOptions->setTidy(true);
+ $parserOutput = $wgParser->parse( $this->mArticle->preSaveTransform( $toparse ) ."\n\n",
+ $wgTitle, $parserOptions );
+
+ $previewHTML = $parserOutput->getText();
+ $wgOut->addParserOutputNoText( $parserOutput );
+
+ foreach ( $parserOutput->getTemplates() as $ns => $template)
+ foreach ( array_keys( $template ) as $dbk)
+ $this->mPreviewTemplates[] = Title::makeTitle($ns, $dbk);
+
+ wfProfileOut( $fname );
+ return $previewhead . $previewHTML;
+ }
+ }
+
+ /**
+ * Call the stock "user is blocked" page
+ */
+ function blockedPage() {
+ global $wgOut, $wgUser;
+ $wgOut->blockedPage( false ); # Standard block notice on the top, don't 'return'
+
+ # If the user made changes, preserve them when showing the markup
+ # (This happens when a user is blocked during edit, for instance)
+ $first = $this->firsttime || ( !$this->save && $this->textbox1 == '' );
+ if( $first ) {
+ $source = $this->mTitle->exists() ? $this->getContent() : false;
+ } else {
+ $source = $this->textbox1;
+ }
+
+ # Spit out the source or the user's modified version
+ if( $source !== false ) {
+ $rows = $wgUser->getOption( 'rows' );
+ $cols = $wgUser->getOption( 'cols' );
+ $attribs = array( 'id' => 'wpTextbox1', 'name' => 'wpTextbox1', 'cols' => $cols, 'rows' => $rows, 'readonly' => 'readonly' );
+ $wgOut->addHtml( '<hr />' );
+ $wgOut->addWikiText( wfMsg( $first ? 'blockedoriginalsource' : 'blockededitsource', $this->mTitle->getPrefixedText() ) );
+ $wgOut->addHtml( wfOpenElement( 'textarea', $attribs ) . htmlspecialchars( $source ) . wfCloseElement( 'textarea' ) );
+ }
+ }
+
+ /**
+ * Produce the stock "please login to edit pages" page
+ */
+ function userNotLoggedInPage() {
+ global $wgUser, $wgOut;
+ $skin = $wgUser->getSkin();
+
+ $loginTitle = SpecialPage::getTitleFor( 'Userlogin' );
+ $loginLink = $skin->makeKnownLinkObj( $loginTitle, wfMsgHtml( 'loginreqlink' ), 'returnto=' . $this->mTitle->getPrefixedUrl() );
+
+ $wgOut->setPageTitle( wfMsg( 'whitelistedittitle' ) );
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+
+ $wgOut->addHtml( wfMsgWikiHtml( 'whitelistedittext', $loginLink ) );
+ $wgOut->returnToMain( false, $this->mTitle->getPrefixedUrl() );
+ }
+
+ /**
+ * Creates a basic error page which informs the user that
+ * they have to validate their email address before being
+ * allowed to edit.
+ */
+ function userNotConfirmedPage() {
+ global $wgOut;
+
+ $wgOut->setPageTitle( wfMsg( 'confirmedittitle' ) );
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+
+ $wgOut->addWikiText( wfMsg( 'confirmedittext' ) );
+ $wgOut->returnToMain( false );
+ }
+
+ /**
+ * Produce the stock "your edit contains spam" page
+ *
+ * @param $match Text which triggered one or more filters
+ */
+ function spamPage( $match = false ) {
+ global $wgOut;
+
+ $wgOut->setPageTitle( wfMsg( 'spamprotectiontitle' ) );
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+
+ $wgOut->addWikiText( wfMsg( 'spamprotectiontext' ) );
+ if ( $match )
+ $wgOut->addWikiText( wfMsg( 'spamprotectionmatch', "<nowiki>{$match}</nowiki>" ) );
+
+ $wgOut->returnToMain( false );
+ }
+
+ /**
+ * @private
+ * @todo document
+ */
+ function mergeChangesInto( &$editText ){
+ $fname = 'EditPage::mergeChangesInto';
+ wfProfileIn( $fname );
+
+ $db =& wfGetDB( DB_MASTER );
+
+ // This is the revision the editor started from
+ $baseRevision = Revision::loadFromTimestamp(
+ $db, $this->mArticle->mTitle, $this->edittime );
+ if( is_null( $baseRevision ) ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ $baseText = $baseRevision->getText();
+
+ // The current state, we want to merge updates into it
+ $currentRevision = Revision::loadFromTitle(
+ $db, $this->mArticle->mTitle );
+ if( is_null( $currentRevision ) ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ $currentText = $currentRevision->getText();
+
+ $result = '';
+ if( wfMerge( $baseText, $editText, $currentText, $result ) ){
+ $editText = $result;
+ wfProfileOut( $fname );
+ return true;
+ } else {
+ wfProfileOut( $fname );
+ return false;
+ }
+ }
+
+ /**
+ * Check if the browser is on a blacklist of user-agents known to
+ * mangle UTF-8 data on form submission. Returns true if Unicode
+ * should make it through, false if it's known to be a problem.
+ * @return bool
+ * @private
+ */
+ function checkUnicodeCompliantBrowser() {
+ global $wgBrowserBlackList;
+ if( empty( $_SERVER["HTTP_USER_AGENT"] ) ) {
+ // No User-Agent header sent? Trust it by default...
+ return true;
+ }
+ $currentbrowser = $_SERVER["HTTP_USER_AGENT"];
+ foreach ( $wgBrowserBlackList as $browser ) {
+ if ( preg_match($browser, $currentbrowser) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Format an anchor fragment as it would appear for a given section name
+ * @param string $text
+ * @return string
+ * @private
+ */
+ function sectionAnchor( $text ) {
+ $headline = Sanitizer::decodeCharReferences( $text );
+ # strip out HTML
+ $headline = preg_replace( '/<.*?' . '>/', '', $headline );
+ $headline = trim( $headline );
+ $sectionanchor = '#' . urlencode( str_replace( ' ', '_', $headline ) );
+ $replacearray = array(
+ '%3A' => ':',
+ '%' => '.'
+ );
+ return str_replace(
+ array_keys( $replacearray ),
+ array_values( $replacearray ),
+ $sectionanchor );
+ }
+
+ /**
+ * Shows a bulletin board style toolbar for common editing functions.
+ * It can be disabled in the user preferences.
+ * The necessary JavaScript code can be found in style/wikibits.js.
+ */
+ function getEditToolbar() {
+ global $wgStylePath, $wgContLang, $wgJsMimeType;
+
+ /**
+ * toolarray an array of arrays which each include the filename of
+ * the button image (without path), the opening tag, the closing tag,
+ * and optionally a sample text that is inserted between the two when no
+ * selection is highlighted.
+ * The tip text is shown when the user moves the mouse over the button.
+ *
+ * Already here are accesskeys (key), which are not used yet until someone
+ * can figure out a way to make them work in IE. However, we should make
+ * sure these keys are not defined on the edit page.
+ */
+ $toolarray=array(
+ array( 'image'=>'button_bold.png',
+ 'open' => '\\\'\\\'\\\'',
+ 'close' => '\\\'\\\'\\\'',
+ 'sample'=> wfMsg('bold_sample'),
+ 'tip' => wfMsg('bold_tip'),
+ 'key' => 'B'
+ ),
+ array( 'image'=>'button_italic.png',
+ 'open' => '\\\'\\\'',
+ 'close' => '\\\'\\\'',
+ 'sample'=> wfMsg('italic_sample'),
+ 'tip' => wfMsg('italic_tip'),
+ 'key' => 'I'
+ ),
+ array( 'image'=>'button_link.png',
+ 'open' => '[[',
+ 'close' => ']]',
+ 'sample'=> wfMsg('link_sample'),
+ 'tip' => wfMsg('link_tip'),
+ 'key' => 'L'
+ ),
+ array( 'image'=>'button_extlink.png',
+ 'open' => '[',
+ 'close' => ']',
+ 'sample'=> wfMsg('extlink_sample'),
+ 'tip' => wfMsg('extlink_tip'),
+ 'key' => 'X'
+ ),
+ array( 'image'=>'button_headline.png',
+ 'open' => "\\n== ",
+ 'close' => " ==\\n",
+ 'sample'=> wfMsg('headline_sample'),
+ 'tip' => wfMsg('headline_tip'),
+ 'key' => 'H'
+ ),
+ array( 'image'=>'button_image.png',
+ 'open' => '[['.$wgContLang->getNsText(NS_IMAGE).":",
+ 'close' => ']]',
+ 'sample'=> wfMsg('image_sample'),
+ 'tip' => wfMsg('image_tip'),
+ 'key' => 'D'
+ ),
+ array( 'image' =>'button_media.png',
+ 'open' => '[['.$wgContLang->getNsText(NS_MEDIA).':',
+ 'close' => ']]',
+ 'sample'=> wfMsg('media_sample'),
+ 'tip' => wfMsg('media_tip'),
+ 'key' => 'M'
+ ),
+ array( 'image' =>'button_math.png',
+ 'open' => "<math>",
+ 'close' => "<\\/math>",
+ 'sample'=> wfMsg('math_sample'),
+ 'tip' => wfMsg('math_tip'),
+ 'key' => 'C'
+ ),
+ array( 'image' =>'button_nowiki.png',
+ 'open' => "<nowiki>",
+ 'close' => "<\\/nowiki>",
+ 'sample'=> wfMsg('nowiki_sample'),
+ 'tip' => wfMsg('nowiki_tip'),
+ 'key' => 'N'
+ ),
+ array( 'image' =>'button_sig.png',
+ 'open' => '--~~~~',
+ 'close' => '',
+ 'sample'=> '',
+ 'tip' => wfMsg('sig_tip'),
+ 'key' => 'Y'
+ ),
+ array( 'image' =>'button_hr.png',
+ 'open' => "\\n----\\n",
+ 'close' => '',
+ 'sample'=> '',
+ 'tip' => wfMsg('hr_tip'),
+ 'key' => 'R'
+ )
+ );
+ $toolbar = "<div id='toolbar'>\n";
+ $toolbar.="<script type='$wgJsMimeType'>\n/*<![CDATA[*/\n";
+
+ foreach($toolarray as $tool) {
+
+ $image=$wgStylePath.'/common/images/'.$tool['image'];
+ $open=$tool['open'];
+ $close=$tool['close'];
+ $sample = wfEscapeJsString( $tool['sample'] );
+
+ // 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
+ // probably don't need to be.
+ $tip = wfEscapeJsString( $tool['tip'] );
+
+ #$key = $tool["key"];
+
+ $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
+ }
+
+ $toolbar.="/*]]>*/\n</script>";
+ $toolbar.="\n</div>";
+ return $toolbar;
+ }
+
+ /**
+ * Output preview text only. This can be sucked into the edit page
+ * via JavaScript, and saves the server time rendering the skin as
+ * well as theoretically being more robust on the client (doesn't
+ * disturb the edit box's undo history, won't eat your text on
+ * failure, etc).
+ *
+ * @todo This doesn't include category or interlanguage links.
+ * Would need to enhance it a bit, maybe wrap them in XML
+ * or something... that might also require more skin
+ * initialization, so check whether that's a problem.
+ */
+ function livePreview() {
+ global $wgOut;
+ $wgOut->disable();
+ header( 'Content-type: text/xml; charset=utf-8' );
+ header( 'Cache-control: no-cache' );
+ # FIXME
+ echo $this->getPreviewText( );
+ /* To not shake screen up and down between preview and live-preview */
+ echo "<br style=\"clear:both;\" />\n";
+ }
+
+
+ /**
+ * Get a diff between the current contents of the edit box and the
+ * version of the page we're editing from.
+ *
+ * If this is a section edit, we'll replace the section as for final
+ * save and then make a comparison.
+ *
+ * @return string HTML
+ */
+ function getDiff() {
+ $oldtext = $this->mArticle->fetchContent();
+ $newtext = $this->mArticle->replaceSection(
+ $this->section, $this->textbox1, $this->summary, $this->edittime );
+ $newtext = $this->mArticle->preSaveTransform( $newtext );
+ $oldtitle = wfMsgExt( 'currentrev', array('parseinline') );
+ $newtitle = wfMsgExt( 'yourtext', array('parseinline') );
+ if ( $oldtext !== false || $newtext != '' ) {
+ $de = new DifferenceEngine( $this->mTitle );
+ $de->setText( $oldtext, $newtext );
+ $difftext = $de->getDiff( $oldtitle, $newtitle );
+ } else {
+ $difftext = '';
+ }
+
+ return '<div id="wikiDiff">' . $difftext . '</div>';
+ }
+
+ /**
+ * Filter an input field through a Unicode de-armoring process if it
+ * came from an old browser with known broken Unicode editing issues.
+ *
+ * @param WebRequest $request
+ * @param string $field
+ * @return string
+ * @private
+ */
+ function safeUnicodeInput( $request, $field ) {
+ $text = rtrim( $request->getText( $field ) );
+ return $request->getBool( 'safemode' )
+ ? $this->unmakesafe( $text )
+ : $text;
+ }
+
+ /**
+ * Filter an output field through a Unicode armoring process if it is
+ * going to an old browser with known broken Unicode editing issues.
+ *
+ * @param string $text
+ * @return string
+ * @private
+ */
+ function safeUnicodeOutput( $text ) {
+ global $wgContLang;
+ $codedText = $wgContLang->recodeForEdit( $text );
+ return $this->checkUnicodeCompliantBrowser()
+ ? $codedText
+ : $this->makesafe( $codedText );
+ }
+
+ /**
+ * A number of web browsers are known to corrupt non-ASCII characters
+ * in a UTF-8 text editing environment. To protect against this,
+ * detected browsers will be served an armored version of the text,
+ * with non-ASCII chars converted to numeric HTML character references.
+ *
+ * Preexisting such character references will have a 0 added to them
+ * to ensure that round-trips do not alter the original data.
+ *
+ * @param string $invalue
+ * @return string
+ * @private
+ */
+ function makesafe( $invalue ) {
+ // Armor existing references for reversability.
+ $invalue = strtr( $invalue, array( "&#x" => "&#x0" ) );
+
+ $bytesleft = 0;
+ $result = "";
+ $working = 0;
+ for( $i = 0; $i < strlen( $invalue ); $i++ ) {
+ $bytevalue = ord( $invalue{$i} );
+ if( $bytevalue <= 0x7F ) { //0xxx xxxx
+ $result .= chr( $bytevalue );
+ $bytesleft = 0;
+ } elseif( $bytevalue <= 0xBF ) { //10xx xxxx
+ $working = $working << 6;
+ $working += ($bytevalue & 0x3F);
+ $bytesleft--;
+ if( $bytesleft <= 0 ) {
+ $result .= "&#x" . strtoupper( dechex( $working ) ) . ";";
+ }
+ } elseif( $bytevalue <= 0xDF ) { //110x xxxx
+ $working = $bytevalue & 0x1F;
+ $bytesleft = 1;
+ } elseif( $bytevalue <= 0xEF ) { //1110 xxxx
+ $working = $bytevalue & 0x0F;
+ $bytesleft = 2;
+ } else { //1111 0xxx
+ $working = $bytevalue & 0x07;
+ $bytesleft = 3;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Reverse the previously applied transliteration of non-ASCII characters
+ * back to UTF-8. Used to protect data from corruption by broken web browsers
+ * as listed in $wgBrowserBlackList.
+ *
+ * @param string $invalue
+ * @return string
+ * @private
+ */
+ function unmakesafe( $invalue ) {
+ $result = "";
+ for( $i = 0; $i < strlen( $invalue ); $i++ ) {
+ if( ( substr( $invalue, $i, 3 ) == "&#x" ) && ( $invalue{$i+3} != '0' ) ) {
+ $i += 3;
+ $hexstring = "";
+ do {
+ $hexstring .= $invalue{$i};
+ $i++;
+ } while( ctype_xdigit( $invalue{$i} ) && ( $i < strlen( $invalue ) ) );
+
+ // Do some sanity checks. These aren't needed for reversability,
+ // but should help keep the breakage down if the editor
+ // breaks one of the entities whilst editing.
+ if ((substr($invalue,$i,1)==";") and (strlen($hexstring) <= 6)) {
+ $codepoint = hexdec($hexstring);
+ $result .= codepointToUtf8( $codepoint );
+ } else {
+ $result .= "&#x" . $hexstring . substr( $invalue, $i, 1 );
+ }
+ } else {
+ $result .= substr( $invalue, $i, 1 );
+ }
+ }
+ // reverse the transform that we made for reversability reasons.
+ return strtr( $result, array( "&#x0" => "&#x" ) );
+ }
+
+ function noCreatePermission() {
+ global $wgOut;
+ $wgOut->setPageTitle( wfMsg( 'nocreatetitle' ) );
+ $wgOut->addWikiText( wfMsg( 'nocreatetext' ) );
+ }
+
+}
+
+?>
diff --git a/includes/Exception.php b/includes/Exception.php
new file mode 100644
index 000000000000..ad7ec14a933e
--- /dev/null
+++ b/includes/Exception.php
@@ -0,0 +1,218 @@
+<?php
+
+class MWException extends Exception
+{
+ function useOutputPage() {
+ return !empty( $GLOBALS['wgFullyInitialised'] ) &&
+ !empty( $GLOBALS['wgArticle'] ) && !empty( $GLOBALS['wgTitle'] );
+ }
+
+ function useMessageCache() {
+ global $wgLang;
+ return is_object( $wgLang );
+ }
+
+ function msg( $key, $fallback /*[, params...] */ ) {
+ $args = array_slice( func_get_args(), 2 );
+ if ( $this->useMessageCache() ) {
+ return wfMsgReal( $key, $args );
+ } else {
+ return wfMsgReplaceArgs( $fallback, $args );
+ }
+ }
+
+ function getHTML() {
+ global $wgShowExceptionDetails;
+ if( $wgShowExceptionDetails ) {
+ return '<p>' . htmlspecialchars( $this->getMessage() ) .
+ '</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
+ "</p>\n";
+ } else {
+ return "<p>Set <b><tt>\$wgShowExceptionDetails = true;</tt></b> " .
+ "in LocalSettings.php to show detailed debugging information.</p>";
+ }
+ }
+
+ function getText() {
+ global $wgShowExceptionDetails;
+ if( $wgShowExceptionDetails ) {
+ return $this->getMessage() .
+ "\nBacktrace:\n" . $this->getTraceAsString() . "\n";
+ } else {
+ return "<p>Set <tt>\$wgShowExceptionDetails = true;</tt> " .
+ "in LocalSettings.php to show detailed debugging information.</p>";
+ }
+ }
+
+ function getPageTitle() {
+ if ( $this->useMessageCache() ) {
+ return wfMsg( 'internalerror' );
+ } else {
+ global $wgSitename;
+ return "$wgSitename error";
+ }
+ }
+
+ function getLogMessage() {
+ global $wgRequest;
+ $file = $this->getFile();
+ $line = $this->getLine();
+ $message = $this->getMessage();
+ return $wgRequest->getRequestURL() . " Exception from line $line of $file: $message";
+ }
+
+ function reportHTML() {
+ global $wgOut;
+ if ( $this->useOutputPage() ) {
+ $wgOut->setPageTitle( $this->getPageTitle() );
+ $wgOut->setRobotpolicy( "noindex,nofollow" );
+ $wgOut->setArticleRelated( false );
+ $wgOut->enableClientCache( false );
+ $wgOut->redirect( '' );
+ $wgOut->clearHTML();
+ $wgOut->addHTML( $this->getHTML() );
+ $wgOut->output();
+ } else {
+ echo $this->htmlHeader();
+ echo $this->getHTML();
+ echo $this->htmlFooter();
+ }
+ }
+
+ function reportText() {
+ echo $this->getText();
+ }
+
+ function report() {
+ global $wgCommandLineMode;
+ if ( $wgCommandLineMode ) {
+ $this->reportText();
+ } else {
+ $log = $this->getLogMessage();
+ if ( $log ) {
+ wfDebugLog( 'exception', $log );
+ }
+ $this->reportHTML();
+ }
+ }
+
+ function htmlHeader() {
+ global $wgLogo, $wgSitename, $wgOutputEncoding;
+
+ if ( !headers_sent() ) {
+ header( 'HTTP/1.0 500 Internal Server Error' );
+ header( 'Content-type: text/html; charset='.$wgOutputEncoding );
+ /* Don't cache error pages! They cause no end of trouble... */
+ header( 'Cache-control: none' );
+ header( 'Pragma: nocache' );
+ }
+ $title = $this->getPageTitle();
+ echo "<html>
+ <head>
+ <title>$title</title>
+ </head>
+ <body>
+ <h1><img src='$wgLogo' style='float:left;margin-right:1em' alt=''>$title</h1>
+ ";
+ }
+
+ function htmlFooter() {
+ echo "</body></html>";
+ }
+
+}
+
+/**
+ * Exception class which takes an HTML error message, and does not
+ * produce a backtrace. Replacement for OutputPage::fatalError().
+ */
+class FatalError extends MWException {
+ function getHTML() {
+ return $this->getMessage();
+ }
+
+ function getText() {
+ return $this->getMessage();
+ }
+}
+
+class ErrorPageError extends MWException {
+ public $title, $msg;
+
+ /**
+ * Note: these arguments are keys into wfMsg(), not text!
+ */
+ function __construct( $title, $msg ) {
+ $this->title = $title;
+ $this->msg = $msg;
+ parent::__construct( wfMsg( $msg ) );
+ }
+
+ function report() {
+ global $wgOut;
+ $wgOut->showErrorPage( $this->title, $this->msg );
+ $wgOut->output();
+ }
+}
+
+/**
+ * Install an exception handler for MediaWiki exception types.
+ */
+function wfInstallExceptionHandler() {
+ set_exception_handler( 'wfExceptionHandler' );
+}
+
+/**
+ * Report an exception to the user
+ */
+function wfReportException( Exception $e ) {
+ if ( $e instanceof MWException ) {
+ try {
+ $e->report();
+ } catch ( Exception $e2 ) {
+ // Exception occurred from within exception handler
+ // Show a simpler error message for the original exception,
+ // don't try to invoke report()
+ $message = "MediaWiki internal error.\n\n" .
+ "Original exception: " . $e->__toString() .
+ "\n\nException caught inside exception handler: " .
+ $e2->__toString() . "\n";
+
+ if ( !empty( $GLOBALS['wgCommandLineMode'] ) ) {
+ echo $message;
+ } else {
+ echo nl2br( htmlspecialchars( $message ) ). "\n";
+ }
+ }
+ } else {
+ echo $e->__toString();
+ }
+}
+
+/**
+ * Exception handler which simulates the appropriate catch() handling:
+ *
+ * try {
+ * ...
+ * } catch ( MWException $e ) {
+ * $e->report();
+ * } catch ( Exception $e ) {
+ * echo $e->__toString();
+ * }
+ */
+function wfExceptionHandler( $e ) {
+ global $wgFullyInitialised;
+ wfReportException( $e );
+
+ // Final cleanup, similar to wfErrorExit()
+ if ( $wgFullyInitialised ) {
+ try {
+ wfLogProfilingData(); // uses $wgRequest, hence the $wgFullyInitialised condition
+ } catch ( Exception $e ) {}
+ }
+
+ // Exit value should be nonzero for the benefit of shell jobs
+ exit( 1 );
+}
+
+?>
diff --git a/includes/Exif.php b/includes/Exif.php
new file mode 100644
index 000000000000..0860d5f7e5d8
--- /dev/null
+++ b/includes/Exif.php
@@ -0,0 +1,1130 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Metadata
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ *
+ * 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
+ *
+ * @link http://exif.org/Exif2-2.PDF The Exif 2.2 specification
+ * @bug 1555, 1947
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage Metadata
+ */
+class Exif {
+ //@{
+ /* @var array
+ * @private
+ */
+
+ /**#@+
+ * Exif tag type definition
+ */
+ const BYTE = 1; # An 8-bit (1-byte) unsigned integer.
+ const ASCII = 2; # An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated with NULL.
+ const SHORT = 3; # A 16-bit (2-byte) unsigned integer.
+ const LONG = 4; # A 32-bit (4-byte) unsigned integer.
+ const RATIONAL = 5; # Two LONGs. The first LONG is the numerator and the second LONG expresses the denominator
+ const UNDEFINED = 7; # An 8-bit byte that can take any value depending on the field definition
+ const SLONG = 9; # A 32-bit (4-byte) signed integer (2's complement notation),
+ const SRATIONAL = 10; # Two SLONGs. The first SLONG is the numerator and the second SLONG is the denominator.
+
+ /**
+ * Exif tags grouped by category, the tagname itself is the key and the type
+ * is the value, in the case of more than one possible value type they are
+ * seperated by commas.
+ */
+ var $mExifTags;
+
+ /**
+ * A one dimentional array of all Exif tags
+ */
+ var $mFlatExifTags;
+
+ /**
+ * The raw Exif data returned by exif_read_data()
+ */
+ var $mRawExifData;
+
+ /**
+ * A Filtered version of $mRawExifData that has been pruned of invalid
+ * tags and tags that contain content they shouldn't contain according
+ * to the Exif specification
+ */
+ var $mFilteredExifData;
+
+ /**
+ * Filtered and formatted Exif data, see FormatExif::getFormattedData()
+ */
+ var $mFormattedExifData;
+
+ //@}
+
+ //@{
+ /* @var string
+ * @private
+ */
+
+ /**
+ * The file being processed
+ */
+ var $file;
+
+ /**
+ * The basename of the file being processed
+ */
+ var $basename;
+
+ /**
+ * The private log to log to
+ */
+ var $log = 'exif';
+
+ //@}
+
+ /**
+ * Constructor
+ *
+ * @param $file String: filename.
+ */
+ function Exif( $file ) {
+ /**
+ * Page numbers here refer to pages in the EXIF 2.2 standard
+ *
+ * @link http://exif.org/Exif2-2.PDF The Exif 2.2 specification
+ */
+ $this->mExifTags = array(
+ # TIFF Rev. 6.0 Attribute Information (p22)
+ 'tiff' => array(
+ # Tags relating to image structure
+ 'structure' => array(
+ 'ImageWidth' => Exif::SHORT.','.Exif::LONG, # Image width
+ 'ImageLength' => Exif::SHORT.','.Exif::LONG, # Image height
+ 'BitsPerSample' => Exif::SHORT, # Number of bits per component
+ # "When a primary image is JPEG compressed, this designation is not"
+ # "necessary and is omitted." (p23)
+ 'Compression' => Exif::SHORT, # Compression scheme #p23
+ 'PhotometricInterpretation' => Exif::SHORT, # Pixel composition #p23
+ 'Orientation' => Exif::SHORT, # Orientation of image #p24
+ 'SamplesPerPixel' => Exif::SHORT, # Number of components
+ 'PlanarConfiguration' => Exif::SHORT, # Image data arrangement #p24
+ 'YCbCrSubSampling' => Exif::SHORT, # Subsampling ratio of Y to C #p24
+ 'YCbCrPositioning' => Exif::SHORT, # Y and C positioning #p24-25
+ 'XResolution' => Exif::RATIONAL, # Image resolution in width direction
+ 'YResolution' => Exif::RATIONAL, # Image resolution in height direction
+ 'ResolutionUnit' => Exif::SHORT, # Unit of X and Y resolution #(p26)
+ ),
+
+ # Tags relating to recording offset
+ 'offset' => array(
+ 'StripOffsets' => Exif::SHORT.','.Exif::LONG, # Image data location
+ 'RowsPerStrip' => Exif::SHORT.','.Exif::LONG, # Number of rows per strip
+ 'StripByteCounts' => Exif::SHORT.','.Exif::LONG, # Bytes per compressed strip
+ 'JPEGInterchangeFormat' => Exif::SHORT.','.Exif::LONG, # Offset to JPEG SOI
+ 'JPEGInterchangeFormatLength' => Exif::SHORT.','.Exif::LONG, # Bytes of JPEG data
+ ),
+
+ # Tags relating to image data characteristics
+ 'characteristics' => array(
+ 'TransferFunction' => Exif::SHORT, # Transfer function
+ 'WhitePoint' => Exif::RATIONAL, # White point chromaticity
+ 'PrimaryChromaticities' => Exif::RATIONAL, # Chromaticities of primarities
+ 'YCbCrCoefficients' => Exif::RATIONAL, # Color space transformation matrix coefficients #p27
+ 'ReferenceBlackWhite' => Exif::RATIONAL # Pair of black and white reference values
+ ),
+
+ # Other tags
+ 'other' => array(
+ 'DateTime' => Exif::ASCII, # File change date and time
+ 'ImageDescription' => Exif::ASCII, # Image title
+ 'Make' => Exif::ASCII, # Image input equipment manufacturer
+ 'Model' => Exif::ASCII, # Image input equipment model
+ 'Software' => Exif::ASCII, # Software used
+ 'Artist' => Exif::ASCII, # Person who created the image
+ 'Copyright' => Exif::ASCII, # Copyright holder
+ ),
+ ),
+
+ # Exif IFD Attribute Information (p30-31)
+ 'exif' => array(
+ # Tags relating to version
+ 'version' => array(
+ # TODO: NOTE: Nonexistence of this field is taken to mean nonconformance
+ # to the EXIF 2.1 AND 2.2 standards
+ 'ExifVersion' => Exif::UNDEFINED, # Exif version
+ 'FlashpixVersion' => Exif::UNDEFINED, # Supported Flashpix version #p32
+ ),
+
+ # Tags relating to Image Data Characteristics
+ 'characteristics' => array(
+ 'ColorSpace' => Exif::SHORT, # Color space information #p32
+ ),
+
+ # Tags relating to image configuration
+ 'configuration' => array(
+ 'ComponentsConfiguration' => Exif::UNDEFINED, # Meaning of each component #p33
+ 'CompressedBitsPerPixel' => Exif::RATIONAL, # Image compression mode
+ 'PixelYDimension' => Exif::SHORT.','.Exif::LONG, # Valid image width
+ 'PixelXDimension' => Exif::SHORT.','.Exif::LONG, # Valind image height
+ ),
+
+ # Tags relating to related user information
+ 'user' => array(
+ 'MakerNote' => Exif::UNDEFINED, # Manufacturer notes
+ 'UserComment' => Exif::UNDEFINED, # User comments #p34
+ ),
+
+ # Tags relating to related file information
+ 'related' => array(
+ 'RelatedSoundFile' => Exif::ASCII, # Related audio file
+ ),
+
+ # Tags relating to date and time
+ 'dateandtime' => array(
+ 'DateTimeOriginal' => Exif::ASCII, # Date and time of original data generation #p36
+ 'DateTimeDigitized' => Exif::ASCII, # Date and time of original data generation
+ 'SubSecTime' => Exif::ASCII, # DateTime subseconds
+ 'SubSecTimeOriginal' => Exif::ASCII, # DateTimeOriginal subseconds
+ 'SubSecTimeDigitized' => Exif::ASCII, # DateTimeDigitized subseconds
+ ),
+
+ # Tags relating to picture-taking conditions (p31)
+ 'conditions' => array(
+ 'ExposureTime' => Exif::RATIONAL, # Exposure time
+ 'FNumber' => Exif::RATIONAL, # F Number
+ 'ExposureProgram' => Exif::SHORT, # Exposure Program #p38
+ 'SpectralSensitivity' => Exif::ASCII, # Spectral sensitivity
+ 'ISOSpeedRatings' => Exif::SHORT, # ISO speed rating
+ 'OECF' => Exif::UNDEFINED, # Optoelectronic conversion factor
+ 'ShutterSpeedValue' => Exif::SRATIONAL, # Shutter speed
+ 'ApertureValue' => Exif::RATIONAL, # Aperture
+ 'BrightnessValue' => Exif::SRATIONAL, # Brightness
+ 'ExposureBiasValue' => Exif::SRATIONAL, # Exposure bias
+ 'MaxApertureValue' => Exif::RATIONAL, # Maximum land aperture
+ 'SubjectDistance' => Exif::RATIONAL, # Subject distance
+ 'MeteringMode' => Exif::SHORT, # Metering mode #p40
+ 'LightSource' => Exif::SHORT, # Light source #p40-41
+ 'Flash' => Exif::SHORT, # Flash #p41-42
+ 'FocalLength' => Exif::RATIONAL, # Lens focal length
+ 'SubjectArea' => Exif::SHORT, # Subject area
+ 'FlashEnergy' => Exif::RATIONAL, # Flash energy
+ 'SpatialFrequencyResponse' => Exif::UNDEFINED, # Spatial frequency response
+ 'FocalPlaneXResolution' => Exif::RATIONAL, # Focal plane X resolution
+ 'FocalPlaneYResolution' => Exif::RATIONAL, # Focal plane Y resolution
+ 'FocalPlaneResolutionUnit' => Exif::SHORT, # Focal plane resolution unit #p46
+ 'SubjectLocation' => Exif::SHORT, # Subject location
+ 'ExposureIndex' => Exif::RATIONAL, # Exposure index
+ 'SensingMethod' => Exif::SHORT, # Sensing method #p46
+ 'FileSource' => Exif::UNDEFINED, # File source #p47
+ 'SceneType' => Exif::UNDEFINED, # Scene type #p47
+ 'CFAPattern' => Exif::UNDEFINED, # CFA pattern
+ 'CustomRendered' => Exif::SHORT, # Custom image processing #p48
+ 'ExposureMode' => Exif::SHORT, # Exposure mode #p48
+ 'WhiteBalance' => Exif::SHORT, # White Balance #p49
+ 'DigitalZoomRatio' => Exif::RATIONAL, # Digital zoom ration
+ 'FocalLengthIn35mmFilm' => Exif::SHORT, # Focal length in 35 mm film
+ 'SceneCaptureType' => Exif::SHORT, # Scene capture type #p49
+ 'GainControl' => Exif::RATIONAL, # Scene control #p49-50
+ 'Contrast' => Exif::SHORT, # Contrast #p50
+ 'Saturation' => Exif::SHORT, # Saturation #p50
+ 'Sharpness' => Exif::SHORT, # Sharpness #p50
+ 'DeviceSettingDescription' => Exif::UNDEFINED, # Desice settings description
+ 'SubjectDistanceRange' => Exif::SHORT, # Subject distance range #p51
+ ),
+
+ 'other' => array(
+ 'ImageUniqueID' => Exif::ASCII, # Unique image ID
+ ),
+ ),
+
+ # GPS Attribute Information (p52)
+ 'gps' => array(
+ 'GPSVersionID' => Exif::BYTE, # GPS tag version
+ 'GPSLatitudeRef' => Exif::ASCII, # North or South Latitude #p52-53
+ 'GPSLatitude' => Exif::RATIONAL, # Latitude
+ 'GPSLongitudeRef' => Exif::ASCII, # East or West Longitude #p53
+ 'GPSLongitude' => Exif::RATIONAL, # Longitude
+ 'GPSAltitudeRef' => Exif::BYTE, # Altitude reference
+ 'GPSAltitude' => Exif::RATIONAL, # Altitude
+ 'GPSTimeStamp' => Exif::RATIONAL, # GPS time (atomic clock)
+ 'GPSSatellites' => Exif::ASCII, # Satellites used for measurement
+ 'GPSStatus' => Exif::ASCII, # Receiver status #p54
+ 'GPSMeasureMode' => Exif::ASCII, # Measurement mode #p54-55
+ 'GPSDOP' => Exif::RATIONAL, # Measurement precision
+ 'GPSSpeedRef' => Exif::ASCII, # Speed unit #p55
+ 'GPSSpeed' => Exif::RATIONAL, # Speed of GPS receiver
+ 'GPSTrackRef' => Exif::ASCII, # Reference for direction of movement #p55
+ 'GPSTrack' => Exif::RATIONAL, # Direction of movement
+ 'GPSImgDirectionRef' => Exif::ASCII, # Reference for direction of image #p56
+ 'GPSImgDirection' => Exif::RATIONAL, # Direction of image
+ 'GPSMapDatum' => Exif::ASCII, # Geodetic survey data used
+ 'GPSDestLatitudeRef' => Exif::ASCII, # Reference for latitude of destination #p56
+ 'GPSDestLatitude' => Exif::RATIONAL, # Latitude destination
+ 'GPSDestLongitudeRef' => Exif::ASCII, # Reference for longitude of destination #p57
+ 'GPSDestLongitude' => Exif::RATIONAL, # Longitude of destination
+ 'GPSDestBearingRef' => Exif::ASCII, # Reference for bearing of destination #p57
+ 'GPSDestBearing' => Exif::RATIONAL, # Bearing of destination
+ 'GPSDestDistanceRef' => Exif::ASCII, # Reference for distance to destination #p57-58
+ 'GPSDestDistance' => Exif::RATIONAL, # Distance to destination
+ 'GPSProcessingMethod' => Exif::UNDEFINED, # Name of GPS processing method
+ 'GPSAreaInformation' => Exif::UNDEFINED, # Name of GPS area
+ 'GPSDateStamp' => Exif::ASCII, # GPS date
+ 'GPSDifferential' => Exif::SHORT, # GPS differential correction
+ ),
+ );
+
+ $this->file = $file;
+ $this->basename = wfBaseName( $this->file );
+
+ $this->makeFlatExifTags();
+
+ $this->debugFile( $this->basename, __FUNCTION__, true );
+ wfSuppressWarnings();
+ $data = exif_read_data( $this->file );
+ wfRestoreWarnings();
+ /**
+ * exif_read_data() will return false on invalid input, such as
+ * when somebody uploads a file called something.jpeg
+ * containing random gibberish.
+ */
+ $this->mRawExifData = $data ? $data : array();
+
+ $this->makeFilteredData();
+ $this->makeFormattedData();
+
+ $this->debugFile( __FUNCTION__, false );
+ }
+
+ /**#@+
+ * @private
+ */
+ /**
+ * Generate a flat list of the exif tags
+ */
+ function makeFlatExifTags() {
+ $this->extractTags( $this->mExifTags );
+ }
+
+ /**
+ * A recursing extractor function used by makeFlatExifTags()
+ *
+ * Note: This used to use an array_walk function, but it made PHP5
+ * segfault, see `cvs diff -u -r 1.4 -r 1.5 Exif.php`
+ */
+ function extractTags( &$tagset ) {
+ foreach( $tagset as $key => $val ) {
+ if( is_array( $val ) ) {
+ $this->extractTags( $val );
+ } else {
+ $this->mFlatExifTags[$key] = $val;
+ }
+ }
+ }
+
+ /**
+ * Make $this->mFilteredExifData
+ */
+ function makeFilteredData() {
+ $this->mFilteredExifData = $this->mRawExifData;
+
+ foreach( $this->mFilteredExifData as $k => $v ) {
+ if ( !in_array( $k, array_keys( $this->mFlatExifTags ) ) ) {
+ $this->debug( $v, __FUNCTION__, "'$k' is not a valid Exif tag" );
+ unset( $this->mFilteredExifData[$k] );
+ }
+ }
+
+ foreach( $this->mFilteredExifData as $k => $v ) {
+ if ( !$this->validate($k, $v) ) {
+ $this->debug( $v, __FUNCTION__, "'$k' contained invalid data" );
+ unset( $this->mFilteredExifData[$k] );
+ }
+ }
+ }
+
+ /**
+ * @todo document
+ */
+ function makeFormattedData( ) {
+ $format = new FormatExif( $this->getFilteredData() );
+ $this->mFormattedExifData = $format->getFormattedData();
+ }
+ /**#@-*/
+
+ /**#@+
+ * @return array
+ */
+ /**
+ * Get $this->mRawExifData
+ */
+ function getData() {
+ return $this->mRawExifData;
+ }
+
+ /**
+ * Get $this->mFilteredExifData
+ */
+ function getFilteredData() {
+ return $this->mFilteredExifData;
+ }
+
+ /**
+ * Get $this->mFormattedExifData
+ */
+ function getFormattedData() {
+ return $this->mFormattedExifData;
+ }
+ /**#@-*/
+
+ /**
+ * The version of the output format
+ *
+ * Before the actual metadata information is saved in the database we
+ * strip some of it since we don't want to save things like thumbnails
+ * which usually accompany Exif data. This value gets saved in the
+ * database along with the actual Exif data, and if the version in the
+ * database doesn't equal the value returned by this function the Exif
+ * data is regenerated.
+ *
+ * @return int
+ */
+ function version() {
+ return 1; // We don't need no bloddy constants!
+ }
+
+ /**#@+
+ * Validates if a tag value is of the type it should be according to the Exif spec
+ *
+ * @private
+ *
+ * @param $in Mixed: the input value to check
+ * @return bool
+ */
+ function isByte( $in ) {
+ if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 255 ) {
+ $this->debug( $in, __FUNCTION__, true );
+ return true;
+ } else {
+ $this->debug( $in, __FUNCTION__, false );
+ return false;
+ }
+ }
+
+ function isASCII( $in ) {
+ if ( is_array( $in ) ) {
+ return false;
+ }
+
+ if ( preg_match( "/[^\x0a\x20-\x7e]/", $in ) ) {
+ $this->debug( $in, __FUNCTION__, 'found a character not in our whitelist' );
+ return false;
+ }
+
+ if ( preg_match( '/^\s*$/', $in ) ) {
+ $this->debug( $in, __FUNCTION__, 'input consisted solely of whitespace' );
+ return false;
+ }
+
+ return true;
+ }
+
+ function isShort( $in ) {
+ if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 65536 ) {
+ $this->debug( $in, __FUNCTION__, true );
+ return true;
+ } else {
+ $this->debug( $in, __FUNCTION__, false );
+ return false;
+ }
+ }
+
+ function isLong( $in ) {
+ if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 4294967296 ) {
+ $this->debug( $in, __FUNCTION__, true );
+ return true;
+ } else {
+ $this->debug( $in, __FUNCTION__, false );
+ return false;
+ }
+ }
+
+ function isRational( $in ) {
+ $m = array();
+ if ( !is_array( $in ) && @preg_match( '/^(\d+)\/(\d+[1-9]|[1-9]\d*)$/', $in, $m ) ) { # Avoid division by zero
+ return $this->isLong( $m[1] ) && $this->isLong( $m[2] );
+ } else {
+ $this->debug( $in, __FUNCTION__, 'fed a non-fraction value' );
+ return false;
+ }
+ }
+
+ function isUndefined( $in ) {
+ if ( !is_array( $in ) && preg_match( '/^\d{4}$/', $in ) ) { // Allow ExifVersion and FlashpixVersion
+ $this->debug( $in, __FUNCTION__, true );
+ return true;
+ } else {
+ $this->debug( $in, __FUNCTION__, false );
+ return false;
+ }
+ }
+
+ function isSlong( $in ) {
+ if ( $this->isLong( abs( $in ) ) ) {
+ $this->debug( $in, __FUNCTION__, true );
+ return true;
+ } else {
+ $this->debug( $in, __FUNCTION__, false );
+ return false;
+ }
+ }
+
+ function isSrational( $in ) {
+ $m = array();
+ if ( !is_array( $in ) && preg_match( '/^(\d+)\/(\d+[1-9]|[1-9]\d*)$/', $in, $m ) ) { # Avoid division by zero
+ return $this->isSlong( $m[0] ) && $this->isSlong( $m[1] );
+ } else {
+ $this->debug( $in, __FUNCTION__, 'fed a non-fraction value' );
+ return false;
+ }
+ }
+ /**#@-*/
+
+ /**
+ * Validates if a tag has a legal value according to the Exif spec
+ *
+ * @private
+ *
+ * @param $tag String: the tag to check.
+ * @param $val Mixed: the value of the tag.
+ * @return bool
+ */
+ function validate( $tag, $val ) {
+ $debug = "tag is '$tag'";
+ // Does not work if not typecast
+ switch( (string)$this->mFlatExifTags[$tag] ) {
+ case (string)Exif::BYTE:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isByte( $val );
+ case (string)Exif::ASCII:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isASCII( $val );
+ case (string)Exif::SHORT:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isShort( $val );
+ case (string)Exif::LONG:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isLong( $val );
+ case (string)Exif::RATIONAL:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isRational( $val );
+ case (string)Exif::UNDEFINED:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isUndefined( $val );
+ case (string)Exif::SLONG:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isSlong( $val );
+ case (string)Exif::SRATIONAL:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isSrational( $val );
+ case (string)Exif::SHORT.','.Exif::LONG:
+ $this->debug( $val, __FUNCTION__, $debug );
+ return $this->isShort( $val ) || $this->isLong( $val );
+ default:
+ $this->debug( $val, __FUNCTION__, "The tag '$tag' is unknown" );
+ return false;
+ }
+ }
+
+ /**
+ * Convenience function for debugging output
+ *
+ * @private
+ *
+ * @param $in Mixed:
+ * @param $fname String:
+ * @param $action Mixed: , default NULL.
+ */
+ function debug( $in, $fname, $action = NULL ) {
+ $type = gettype( $in );
+ $class = ucfirst( __CLASS__ );
+ if ( $type === 'array' )
+ $in = print_r( $in, true );
+
+ if ( $action === true )
+ wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)\n");
+ elseif ( $action === false )
+ wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)\n");
+ elseif ( $action === null )
+ wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)\n");
+ else
+ wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')\n");
+ }
+
+ /**
+ * Convenience function for debugging output
+ *
+ * @private
+ *
+ * @param $fname String: the name of the function calling this function
+ * @param $io Boolean: Specify whether we're beginning or ending
+ */
+ function debugFile( $fname, $io ) {
+ $class = ucfirst( __CLASS__ );
+ if ( $io ) {
+ wfDebugLog( $this->log, "$class::$fname: begin processing: '{$this->basename}'\n" );
+ } else {
+ wfDebugLog( $this->log, "$class::$fname: end processing: '{$this->basename}'\n" );
+ }
+ }
+
+}
+
+/**
+ * @package MediaWiki
+ * @subpackage Metadata
+ */
+class FormatExif {
+ /**
+ * The Exif data to format
+ *
+ * @var array
+ * @private
+ */
+ var $mExif;
+
+ /**
+ * Constructor
+ *
+ * @param $exif Array: the Exif data to format ( as returned by
+ * Exif::getFilteredData() )
+ */
+ function FormatExif( $exif ) {
+ $this->mExif = $exif;
+ }
+
+ /**
+ * Numbers given by Exif user agents are often magical, that is they
+ * should be replaced by a detailed explanation depending on their
+ * value which most of the time are plain integers. This function
+ * formats Exif values into human readable form.
+ *
+ * @return array
+ */
+ function getFormattedData() {
+ global $wgLang;
+
+ $tags =& $this->mExif;
+
+ $resolutionunit = !isset( $tags['ResolutionUnit'] ) || $tags['ResolutionUnit'] == 2 ? 2 : 3;
+ unset( $tags['ResolutionUnit'] );
+
+ foreach( $tags as $tag => $val ) {
+ switch( $tag ) {
+ case 'Compression':
+ switch( $val ) {
+ case 1: case 6:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'PhotometricInterpretation':
+ switch( $val ) {
+ case 2: case 6:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'Orientation':
+ switch( $val ) {
+ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'PlanarConfiguration':
+ switch( $val ) {
+ case 1: case 2:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ // TODO: YCbCrSubSampling
+ // TODO: YCbCrPositioning
+
+ case 'XResolution':
+ case 'YResolution':
+ switch( $resolutionunit ) {
+ case 2:
+ $tags[$tag] = $this->msg( 'XYResolution', 'i', $this->formatNum( $val ) );
+ break;
+ case 3:
+ $this->msg( 'XYResolution', 'c', $this->formatNum( $val ) );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ // TODO: YCbCrCoefficients #p27 (see annex E)
+ case 'ExifVersion': case 'FlashpixVersion':
+ $tags[$tag] = "$val"/100;
+ break;
+
+ case 'ColorSpace':
+ switch( $val ) {
+ case 1: case 'FFFF.H':
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'ComponentsConfiguration':
+ switch( $val ) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'DateTime':
+ case 'DateTimeOriginal':
+ case 'DateTimeDigitized':
+ if( $val == '0000:00:00 00:00:00' ) {
+ $tags[$tag] = wfMsg('exif-unknowndate');
+ } elseif( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/', $val ) ) {
+ $tags[$tag] = $wgLang->timeanddate( wfTimestamp(TS_MW, $val) );
+ }
+ break;
+
+ case 'ExposureProgram':
+ switch( $val ) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'SubjectDistance':
+ $tags[$tag] = $this->msg( $tag, '', $this->formatNum( $val ) );
+ break;
+
+ case 'MeteringMode':
+ switch( $val ) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 255:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'LightSource':
+ switch( $val ) {
+ case 0: case 1: case 2: case 3: case 4: case 9: case 10: case 11:
+ case 12: case 13: case 14: case 15: case 17: case 18: case 19: case 20:
+ case 21: case 22: case 23: case 24: case 255:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ // TODO: Flash
+ case 'FocalPlaneResolutionUnit':
+ switch( $val ) {
+ case 2:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'SensingMethod':
+ switch( $val ) {
+ case 1: case 2: case 3: case 4: case 5: case 7: case 8:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'FileSource':
+ switch( $val ) {
+ case 3:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'SceneType':
+ switch( $val ) {
+ case 1:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'CustomRendered':
+ switch( $val ) {
+ case 0: case 1:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'ExposureMode':
+ switch( $val ) {
+ case 0: case 1: case 2:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'WhiteBalance':
+ switch( $val ) {
+ case 0: case 1:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'SceneCaptureType':
+ switch( $val ) {
+ case 0: case 1: case 2: case 3:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GainControl':
+ switch( $val ) {
+ case 0: case 1: case 2: case 3: case 4:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'Contrast':
+ switch( $val ) {
+ case 0: case 1: case 2:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'Saturation':
+ switch( $val ) {
+ case 0: case 1: case 2:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'Sharpness':
+ switch( $val ) {
+ case 0: case 1: case 2:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'SubjectDistanceRange':
+ switch( $val ) {
+ case 0: case 1: case 2: case 3:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GPSLatitudeRef':
+ case 'GPSDestLatitudeRef':
+ switch( $val ) {
+ case 'N': case 'S':
+ $tags[$tag] = $this->msg( 'GPSLatitude', $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GPSLongitudeRef':
+ case 'GPSDestLongitudeRef':
+ switch( $val ) {
+ case 'E': case 'W':
+ $tags[$tag] = $this->msg( 'GPSLongitude', $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GPSStatus':
+ switch( $val ) {
+ case 'A': case 'V':
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GPSMeasureMode':
+ switch( $val ) {
+ case 2: case 3:
+ $tags[$tag] = $this->msg( $tag, $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GPSSpeedRef':
+ case 'GPSDestDistanceRef':
+ switch( $val ) {
+ case 'K': case 'M': case 'N':
+ $tags[$tag] = $this->msg( 'GPSSpeed', $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GPSTrackRef':
+ case 'GPSImgDirectionRef':
+ case 'GPSDestBearingRef':
+ switch( $val ) {
+ case 'T': case 'M':
+ $tags[$tag] = $this->msg( 'GPSDirection', $val );
+ break;
+ default:
+ $tags[$tag] = $val;
+ break;
+ }
+ break;
+
+ case 'GPSDateStamp':
+ $tags[$tag] = $wgLang->date( substr( $val, 0, 4 ) . substr( $val, 5, 2 ) . substr( $val, 8, 2 ) . '000000' );
+ break;
+
+ // This is not in the Exif standard, just a special
+ // case for our purposes which enables wikis to wikify
+ // the make, model and software name to link to their articles.
+ case 'Make':
+ case 'Model':
+ case 'Software':
+ $tags[$tag] = $this->msg( $tag, '', $val );
+ break;
+
+ case 'ExposureTime':
+ // Show the pretty fraction as well as decimal version
+ $tags[$tag] = wfMsg( 'exif-exposuretime-format',
+ $this->formatFraction( $val ), $this->formatNum( $val ) );
+ break;
+
+ case 'FNumber':
+ $tags[$tag] = wfMsg( 'exif-fnumber-format',
+ $this->formatNum( $val ) );
+ break;
+
+ case 'FocalLength':
+ $tags[$tag] = wfMsg( 'exif-focallength-format',
+ $this->formatNum( $val ) );
+ break;
+
+ default:
+ $tags[$tag] = $this->formatNum( $val );
+ break;
+ }
+ }
+
+ return $tags;
+ }
+
+ /**
+ * Convenience function for getFormattedData()
+ *
+ * @private
+ *
+ * @param $tag String: the tag name to pass on
+ * @param $val String: the value of the tag
+ * @param $arg String: an argument to pass ($1)
+ * @return string A wfMsg of "exif-$tag-$val" in lower case
+ */
+ function msg( $tag, $val, $arg = null ) {
+ global $wgContLang;
+
+ if ($val === '')
+ $val = 'value';
+ return wfMsg( $wgContLang->lc( "exif-$tag-$val" ), $arg );
+ }
+
+ /**
+ * Format a number, convert numbers from fractions into floating point
+ * numbers
+ *
+ * @private
+ *
+ * @param $num Mixed: the value to format
+ * @return mixed A floating point number or whatever we were fed
+ */
+ function formatNum( $num ) {
+ $m = array();
+ if ( preg_match( '/^(\d+)\/(\d+)$/', $num, $m ) )
+ return $m[2] != 0 ? $m[1] / $m[2] : $num;
+ else
+ return $num;
+ }
+
+ /**
+ * Format a rational number, reducing fractions
+ *
+ * @private
+ *
+ * @param $num Mixed: the value to format
+ * @return mixed A floating point number or whatever we were fed
+ */
+ function formatFraction( $num ) {
+ $m = array();
+ if ( preg_match( '/^(\d+)\/(\d+)$/', $num, $m ) ) {
+ $numerator = intval( $m[1] );
+ $denominator = intval( $m[2] );
+ $gcd = $this->gcd( $numerator, $denominator );
+ if( $gcd != 0 ) {
+ // 0 shouldn't happen! ;)
+ return $numerator / $gcd . '/' . $denominator / $gcd;
+ }
+ }
+ return $this->formatNum( $num );
+ }
+
+ /**
+ * Calculate the greatest common divisor of two integers.
+ *
+ * @param $a Integer: FIXME
+ * @param $b Integer: FIXME
+ * @return int
+ * @private
+ */
+ function gcd( $a, $b ) {
+ /*
+ // http://en.wikipedia.org/wiki/Euclidean_algorithm
+ // Recursive form would be:
+ if( $b == 0 )
+ return $a;
+ else
+ return gcd( $b, $a % $b );
+ */
+ while( $b != 0 ) {
+ $remainder = $a % $b;
+
+ // tail recursion...
+ $a = $b;
+ $b = $remainder;
+ }
+ return $a;
+ }
+}
+
+/**
+ * MW 1.6 compatibility
+ */
+define( 'MW_EXIF_BYTE', Exif::BYTE );
+define( 'MW_EXIF_ASCII', Exif::ASCII );
+define( 'MW_EXIF_SHORT', Exif::SHORT );
+define( 'MW_EXIF_LONG', Exif::LONG );
+define( 'MW_EXIF_RATIONAL', Exif::RATIONAL );
+define( 'MW_EXIF_UNDEFINED', Exif::UNDEFINED );
+define( 'MW_EXIF_SLONG', Exif::SLONG );
+define( 'MW_EXIF_SRATIONAL', Exif::SRATIONAL );
+
+?>
diff --git a/includes/Export.php b/includes/Export.php
new file mode 100644
index 000000000000..b7e0f9a1d4b0
--- /dev/null
+++ b/includes/Export.php
@@ -0,0 +1,754 @@
+<?php
+# Copyright (C) 2003, 2005, 2006 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+class WikiExporter {
+ var $list_authors = false ; # Return distinct author list (when not returning full history)
+ var $author_list = "" ;
+
+ const FULL = 0;
+ const CURRENT = 1;
+
+ const BUFFER = 0;
+ const STREAM = 1;
+
+ const TEXT = 0;
+ const STUB = 1;
+
+ /**
+ * If using WikiExporter::STREAM to stream a large amount of data,
+ * provide a database connection which is not managed by
+ * LoadBalancer to read from: some history blob types will
+ * make additional queries to pull source data while the
+ * main query is still running.
+ *
+ * @param Database $db
+ * @param mixed $history one of WikiExporter::FULL or WikiExporter::CURRENT, or an
+ * associative array:
+ * offset: non-inclusive offset at which to start the query
+ * limit: maximum number of rows to return
+ * dir: "asc" or "desc" timestamp order
+ * @param int $buffer one of WikiExporter::BUFFER or WikiExporter::STREAM
+ */
+ function WikiExporter( &$db, $history = WikiExporter::CURRENT,
+ $buffer = WikiExporter::BUFFER, $text = WikiExporter::TEXT ) {
+ $this->db =& $db;
+ $this->history = $history;
+ $this->buffer = $buffer;
+ $this->writer = new XmlDumpWriter();
+ $this->sink = new DumpOutput();
+ $this->text = $text;
+ }
+
+ /**
+ * Set the DumpOutput or DumpFilter object which will receive
+ * various row objects and XML output for filtering. Filters
+ * can be chained or used as callbacks.
+ *
+ * @param mixed $callback
+ */
+ function setOutputSink( &$sink ) {
+ $this->sink =& $sink;
+ }
+
+ function openStream() {
+ $output = $this->writer->openStream();
+ $this->sink->writeOpenStream( $output );
+ }
+
+ function closeStream() {
+ $output = $this->writer->closeStream();
+ $this->sink->writeCloseStream( $output );
+ }
+
+ /**
+ * Dumps a series of page and revision records for all pages
+ * in the database, either including complete history or only
+ * the most recent version.
+ */
+ function allPages() {
+ return $this->dumpFrom( '' );
+ }
+
+ /**
+ * Dumps a series of page and revision records for those pages
+ * in the database falling within the page_id range given.
+ * @param int $start Inclusive lower limit (this id is included)
+ * @param int $end Exclusive upper limit (this id is not included)
+ * If 0, no upper limit.
+ */
+ function pagesByRange( $start, $end ) {
+ $condition = 'page_id >= ' . intval( $start );
+ if( $end ) {
+ $condition .= ' AND page_id < ' . intval( $end );
+ }
+ return $this->dumpFrom( $condition );
+ }
+
+ /**
+ * @param Title $title
+ */
+ function pageByTitle( $title ) {
+ return $this->dumpFrom(
+ 'page_namespace=' . $title->getNamespace() .
+ ' AND page_title=' . $this->db->addQuotes( $title->getDbKey() ) );
+ }
+
+ function pageByName( $name ) {
+ $title = Title::newFromText( $name );
+ if( is_null( $title ) ) {
+ return new WikiError( "Can't export invalid title" );
+ } else {
+ return $this->pageByTitle( $title );
+ }
+ }
+
+ function pagesByName( $names ) {
+ foreach( $names as $name ) {
+ $this->pageByName( $name );
+ }
+ }
+
+
+ // -------------------- private implementation below --------------------
+
+ # Generates the distinct list of authors of an article
+ # Not called by default (depends on $this->list_authors)
+ # Can be set by Special:Export when not exporting whole history
+ function do_list_authors ( $page , $revision , $cond ) {
+ $fname = "do_list_authors" ;
+ wfProfileIn( $fname );
+ $this->author_list = "<contributors>";
+ $sql = "SELECT DISTINCT rev_user_text,rev_user FROM {$page},{$revision} WHERE page_id=rev_page AND " . $cond ;
+ $result = $this->db->query( $sql, $fname );
+ $resultset = $this->db->resultObject( $result );
+ while( $row = $resultset->fetchObject() ) {
+ $this->author_list .= "<contributor>" .
+ "<username>" .
+ htmlentities( $row->rev_user_text ) .
+ "</username>" .
+ "<id>" .
+ $row->rev_user .
+ "</id>" .
+ "</contributor>";
+ }
+ wfProfileOut( $fname );
+ $this->author_list .= "</contributors>";
+ }
+
+ function dumpFrom( $cond = '' ) {
+ $fname = 'WikiExporter::dumpFrom';
+ wfProfileIn( $fname );
+
+ $page = $this->db->tableName( 'page' );
+ $revision = $this->db->tableName( 'revision' );
+ $text = $this->db->tableName( 'text' );
+
+ $order = 'ORDER BY page_id';
+ $limit = '';
+
+ if( $this->history == WikiExporter::FULL ) {
+ $join = 'page_id=rev_page';
+ } elseif( $this->history == WikiExporter::CURRENT ) {
+ if ( $this->list_authors && $cond != '' ) { // List authors, if so desired
+ $this->do_list_authors ( $page , $revision , $cond );
+ }
+ $join = 'page_id=rev_page AND page_latest=rev_id';
+ } elseif ( is_array( $this->history ) ) {
+ $join = 'page_id=rev_page';
+ if ( $this->history['dir'] == 'asc' ) {
+ $op = '>';
+ $order .= ', rev_timestamp';
+ } else {
+ $op = '<';
+ $order .= ', rev_timestamp DESC';
+ }
+ if ( !empty( $this->history['offset'] ) ) {
+ $join .= " AND rev_timestamp $op " . $this->db->addQuotes(
+ $this->db->timestamp( $this->history['offset'] ) );
+ }
+ if ( !empty( $this->history['limit'] ) ) {
+ $limitNum = intval( $this->history['limit'] );
+ if ( $limitNum > 0 ) {
+ $limit = "LIMIT $limitNum";
+ }
+ }
+ } else {
+ wfProfileOut( $fname );
+ return new WikiError( "$fname given invalid history dump type." );
+ }
+ $where = ( $cond == '' ) ? '' : "$cond AND";
+
+ if( $this->buffer == WikiExporter::STREAM ) {
+ $prev = $this->db->bufferResults( false );
+ }
+ if( $cond == '' ) {
+ // Optimization hack for full-database dump
+ $revindex = $pageindex = $this->db->useIndexClause("PRIMARY");
+ $straight = ' /*! STRAIGHT_JOIN */ ';
+ } else {
+ $pageindex = '';
+ $revindex = '';
+ $straight = '';
+ }
+ if( $this->text == WikiExporter::STUB ) {
+ $sql = "SELECT $straight * FROM
+ $page $pageindex,
+ $revision $revindex
+ WHERE $where $join
+ $order $limit";
+ } else {
+ $sql = "SELECT $straight * FROM
+ $page $pageindex,
+ $revision $revindex,
+ $text
+ WHERE $where $join AND rev_text_id=old_id
+ $order $limit";
+ }
+ $result = $this->db->query( $sql, $fname );
+ $wrapper = $this->db->resultObject( $result );
+ $this->outputStream( $wrapper );
+
+ if ( $this->list_authors ) {
+ $this->outputStream( $wrapper );
+ }
+
+ if( $this->buffer == WikiExporter::STREAM ) {
+ $this->db->bufferResults( $prev );
+ }
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Runs through a query result set dumping page and revision records.
+ * The result set should be sorted/grouped by page to avoid duplicate
+ * page records in the output.
+ *
+ * The result set will be freed once complete. Should be safe for
+ * streaming (non-buffered) queries, as long as it was made on a
+ * separate database connection not managed by LoadBalancer; some
+ * blob storage types will make queries to pull source data.
+ *
+ * @param ResultWrapper $resultset
+ * @access private
+ */
+ function outputStream( $resultset ) {
+ $last = null;
+ while( $row = $resultset->fetchObject() ) {
+ if( is_null( $last ) ||
+ $last->page_namespace != $row->page_namespace ||
+ $last->page_title != $row->page_title ) {
+ if( isset( $last ) ) {
+ $output = $this->writer->closePage();
+ $this->sink->writeClosePage( $output );
+ }
+ $output = $this->writer->openPage( $row );
+ $this->sink->writeOpenPage( $row, $output );
+ $last = $row;
+ }
+ $output = $this->writer->writeRevision( $row );
+ $this->sink->writeRevision( $row, $output );
+ }
+ if( isset( $last ) ) {
+ $output = $this->author_list . $this->writer->closePage();
+ $this->sink->writeClosePage( $output );
+ }
+ $resultset->free();
+ }
+}
+
+class XmlDumpWriter {
+
+ /**
+ * Returns the export schema version.
+ * @return string
+ */
+ function schemaVersion() {
+ return "0.3"; // FIXME: upgrade to 0.4 when updated XSD is ready, for the revision deletion bits
+ }
+
+ /**
+ * Opens the XML output stream's root <mediawiki> element.
+ * This does not include an xml directive, so is safe to include
+ * as a subelement in a larger XML stream. Namespace and XML Schema
+ * references are included.
+ *
+ * Output will be encoded in UTF-8.
+ *
+ * @return string
+ */
+ function openStream() {
+ global $wgContLanguageCode;
+ $ver = $this->schemaVersion();
+ return wfElement( 'mediawiki', array(
+ 'xmlns' => "http://www.mediawiki.org/xml/export-$ver/",
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
+ 'xsi:schemaLocation' => "http://www.mediawiki.org/xml/export-$ver/ " .
+ "http://www.mediawiki.org/xml/export-$ver.xsd",
+ 'version' => $ver,
+ 'xml:lang' => $wgContLanguageCode ),
+ null ) .
+ "\n" .
+ $this->siteInfo();
+ }
+
+ function siteInfo() {
+ $info = array(
+ $this->sitename(),
+ $this->homelink(),
+ $this->generator(),
+ $this->caseSetting(),
+ $this->namespaces() );
+ return " <siteinfo>\n " .
+ implode( "\n ", $info ) .
+ "\n </siteinfo>\n";
+ }
+
+ function sitename() {
+ global $wgSitename;
+ return wfElement( 'sitename', array(), $wgSitename );
+ }
+
+ function generator() {
+ global $wgVersion;
+ return wfElement( 'generator', array(), "MediaWiki $wgVersion" );
+ }
+
+ function homelink() {
+ return wfElement( 'base', array(), Title::newMainPage()->getFullUrl() );
+ }
+
+ function caseSetting() {
+ global $wgCapitalLinks;
+ // "case-insensitive" option is reserved for future
+ $sensitivity = $wgCapitalLinks ? 'first-letter' : 'case-sensitive';
+ return wfElement( 'case', array(), $sensitivity );
+ }
+
+ function namespaces() {
+ global $wgContLang;
+ $spaces = " <namespaces>\n";
+ foreach( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
+ $spaces .= ' ' . wfElement( 'namespace', array( 'key' => $ns ), $title ) . "\n";
+ }
+ $spaces .= " </namespaces>";
+ return $spaces;
+ }
+
+ /**
+ * Closes the output stream with the closing root element.
+ * Call when finished dumping things.
+ */
+ function closeStream() {
+ return "</mediawiki>\n";
+ }
+
+
+ /**
+ * Opens a <page> section on the output stream, with data
+ * from the given database row.
+ *
+ * @param object $row
+ * @return string
+ * @access private
+ */
+ function openPage( $row ) {
+ $out = " <page>\n";
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $out .= ' ' . wfElementClean( 'title', array(), $title->getPrefixedText() ) . "\n";
+ $out .= ' ' . wfElement( 'id', array(), strval( $row->page_id ) ) . "\n";
+ if( '' != $row->page_restrictions ) {
+ $out .= ' ' . wfElement( 'restrictions', array(),
+ strval( $row->page_restrictions ) ) . "\n";
+ }
+ return $out;
+ }
+
+ /**
+ * Closes a <page> section on the output stream.
+ *
+ * @access private
+ */
+ function closePage() {
+ return " </page>\n";
+ }
+
+ /**
+ * Dumps a <revision> section on the output stream, with
+ * data filled in from the given database row.
+ *
+ * @param object $row
+ * @return string
+ * @access private
+ */
+ function writeRevision( $row ) {
+ $fname = 'WikiExporter::dumpRev';
+ wfProfileIn( $fname );
+
+ $out = " <revision>\n";
+ $out .= " " . wfElement( 'id', null, strval( $row->rev_id ) ) . "\n";
+
+ $ts = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
+ $out .= " " . wfElement( 'timestamp', null, $ts ) . "\n";
+
+ if( $row->rev_deleted & Revision::DELETED_USER ) {
+ $out .= " " . wfElement( 'contributor', array( 'deleted' => 'deleted' ) ) . "\n";
+ } else {
+ $out .= " <contributor>\n";
+ if( $row->rev_user ) {
+ $out .= " " . wfElementClean( 'username', null, strval( $row->rev_user_text ) ) . "\n";
+ $out .= " " . wfElement( 'id', null, strval( $row->rev_user ) ) . "\n";
+ } else {
+ $out .= " " . wfElementClean( 'ip', null, strval( $row->rev_user_text ) ) . "\n";
+ }
+ $out .= " </contributor>\n";
+ }
+
+ if( $row->rev_minor_edit ) {
+ $out .= " <minor/>\n";
+ }
+ if( $row->rev_deleted & Revision::DELETED_COMMENT ) {
+ $out .= " " . wfElement( 'comment', array( 'deleted' => 'deleted' ) ) . "\n";
+ } elseif( $row->rev_comment != '' ) {
+ $out .= " " . wfElementClean( 'comment', null, strval( $row->rev_comment ) ) . "\n";
+ }
+
+ if( $row->rev_deleted & Revision::DELETED_TEXT ) {
+ $out .= " " . wfElement( 'text', array( 'deleted' => 'deleted' ) ) . "\n";
+ } elseif( isset( $row->old_text ) ) {
+ // Raw text from the database may have invalid chars
+ $text = strval( Revision::getRevisionText( $row ) );
+ $out .= " " . wfElementClean( 'text',
+ array( 'xml:space' => 'preserve' ),
+ strval( $text ) ) . "\n";
+ } else {
+ // Stub output
+ $out .= " " . wfElement( 'text',
+ array( 'id' => $row->rev_text_id ),
+ "" ) . "\n";
+ }
+
+ $out .= " </revision>\n";
+
+ wfProfileOut( $fname );
+ return $out;
+ }
+
+}
+
+
+/**
+ * Base class for output stream; prints to stdout or buffer or whereever.
+ */
+class DumpOutput {
+ function writeOpenStream( $string ) {
+ $this->write( $string );
+ }
+
+ function writeCloseStream( $string ) {
+ $this->write( $string );
+ }
+
+ function writeOpenPage( $page, $string ) {
+ $this->write( $string );
+ }
+
+ function writeClosePage( $string ) {
+ $this->write( $string );
+ }
+
+ function writeRevision( $rev, $string ) {
+ $this->write( $string );
+ }
+
+ /**
+ * Override to write to a different stream type.
+ * @return bool
+ */
+ function write( $string ) {
+ print $string;
+ }
+}
+
+/**
+ * Stream outputter to send data to a file.
+ */
+class DumpFileOutput extends DumpOutput {
+ var $handle;
+
+ function DumpFileOutput( $file ) {
+ $this->handle = fopen( $file, "wt" );
+ }
+
+ function write( $string ) {
+ fputs( $this->handle, $string );
+ }
+}
+
+/**
+ * Stream outputter to send data to a file via some filter program.
+ * Even if compression is available in a library, using a separate
+ * program can allow us to make use of a multi-processor system.
+ */
+class DumpPipeOutput extends DumpFileOutput {
+ function DumpPipeOutput( $command, $file = null ) {
+ if( !is_null( $file ) ) {
+ $command .= " > " . wfEscapeShellArg( $file );
+ }
+ $this->handle = popen( $command, "w" );
+ }
+}
+
+/**
+ * Sends dump output via the gzip compressor.
+ */
+class DumpGZipOutput extends DumpPipeOutput {
+ function DumpGZipOutput( $file ) {
+ parent::DumpPipeOutput( "gzip", $file );
+ }
+}
+
+/**
+ * Sends dump output via the bgzip2 compressor.
+ */
+class DumpBZip2Output extends DumpPipeOutput {
+ function DumpBZip2Output( $file ) {
+ parent::DumpPipeOutput( "bzip2", $file );
+ }
+}
+
+/**
+ * Sends dump output via the p7zip compressor.
+ */
+class Dump7ZipOutput extends DumpPipeOutput {
+ function Dump7ZipOutput( $file ) {
+ $command = "7za a -bd -si " . wfEscapeShellArg( $file );
+ // Suppress annoying useless crap from p7zip
+ // Unfortunately this could suppress real error messages too
+ $command .= " >/dev/null 2>&1";
+ parent::DumpPipeOutput( $command );
+ }
+}
+
+
+
+/**
+ * Dump output filter class.
+ * This just does output filtering and streaming; XML formatting is done
+ * higher up, so be careful in what you do.
+ */
+class DumpFilter {
+ function DumpFilter( &$sink ) {
+ $this->sink =& $sink;
+ }
+
+ function writeOpenStream( $string ) {
+ $this->sink->writeOpenStream( $string );
+ }
+
+ function writeCloseStream( $string ) {
+ $this->sink->writeCloseStream( $string );
+ }
+
+ function writeOpenPage( $page, $string ) {
+ $this->sendingThisPage = $this->pass( $page, $string );
+ if( $this->sendingThisPage ) {
+ $this->sink->writeOpenPage( $page, $string );
+ }
+ }
+
+ function writeClosePage( $string ) {
+ if( $this->sendingThisPage ) {
+ $this->sink->writeClosePage( $string );
+ $this->sendingThisPage = false;
+ }
+ }
+
+ function writeRevision( $rev, $string ) {
+ if( $this->sendingThisPage ) {
+ $this->sink->writeRevision( $rev, $string );
+ }
+ }
+
+ /**
+ * Override for page-based filter types.
+ * @return bool
+ */
+ function pass( $page ) {
+ return true;
+ }
+}
+
+/**
+ * Simple dump output filter to exclude all talk pages.
+ */
+class DumpNotalkFilter extends DumpFilter {
+ function pass( $page ) {
+ return !Namespace::isTalk( $page->page_namespace );
+ }
+}
+
+/**
+ * Dump output filter to include or exclude pages in a given set of namespaces.
+ */
+class DumpNamespaceFilter extends DumpFilter {
+ var $invert = false;
+ var $namespaces = array();
+
+ function DumpNamespaceFilter( &$sink, $param ) {
+ parent::DumpFilter( $sink );
+
+ $constants = array(
+ "NS_MAIN" => NS_MAIN,
+ "NS_TALK" => NS_TALK,
+ "NS_USER" => NS_USER,
+ "NS_USER_TALK" => NS_USER_TALK,
+ "NS_PROJECT" => NS_PROJECT,
+ "NS_PROJECT_TALK" => NS_PROJECT_TALK,
+ "NS_IMAGE" => NS_IMAGE,
+ "NS_IMAGE_TALK" => NS_IMAGE_TALK,
+ "NS_MEDIAWIKI" => NS_MEDIAWIKI,
+ "NS_MEDIAWIKI_TALK" => NS_MEDIAWIKI_TALK,
+ "NS_TEMPLATE" => NS_TEMPLATE,
+ "NS_TEMPLATE_TALK" => NS_TEMPLATE_TALK,
+ "NS_HELP" => NS_HELP,
+ "NS_HELP_TALK" => NS_HELP_TALK,
+ "NS_CATEGORY" => NS_CATEGORY,
+ "NS_CATEGORY_TALK" => NS_CATEGORY_TALK );
+
+ if( $param{0} == '!' ) {
+ $this->invert = true;
+ $param = substr( $param, 1 );
+ }
+
+ foreach( explode( ',', $param ) as $key ) {
+ $key = trim( $key );
+ if( isset( $constants[$key] ) ) {
+ $ns = $constants[$key];
+ $this->namespaces[$ns] = true;
+ } elseif( is_numeric( $key ) ) {
+ $ns = intval( $key );
+ $this->namespaces[$ns] = true;
+ } else {
+ throw new MWException( "Unrecognized namespace key '$key'\n" );
+ }
+ }
+ }
+
+ function pass( $page ) {
+ $match = isset( $this->namespaces[$page->page_namespace] );
+ return $this->invert xor $match;
+ }
+}
+
+
+/**
+ * Dump output filter to include only the last revision in each page sequence.
+ */
+class DumpLatestFilter extends DumpFilter {
+ var $page, $pageString, $rev, $revString;
+
+ function writeOpenPage( $page, $string ) {
+ $this->page = $page;
+ $this->pageString = $string;
+ }
+
+ function writeClosePage( $string ) {
+ if( $this->rev ) {
+ $this->sink->writeOpenPage( $this->page, $this->pageString );
+ $this->sink->writeRevision( $this->rev, $this->revString );
+ $this->sink->writeClosePage( $string );
+ }
+ $this->rev = null;
+ $this->revString = null;
+ $this->page = null;
+ $this->pageString = null;
+ }
+
+ function writeRevision( $rev, $string ) {
+ if( $rev->rev_id == $this->page->page_latest ) {
+ $this->rev = $rev;
+ $this->revString = $string;
+ }
+ }
+}
+
+/**
+ * Base class for output stream; prints to stdout or buffer or whereever.
+ */
+class DumpMultiWriter {
+ function DumpMultiWriter( $sinks ) {
+ $this->sinks = $sinks;
+ $this->count = count( $sinks );
+ }
+
+ function writeOpenStream( $string ) {
+ for( $i = 0; $i < $this->count; $i++ ) {
+ $this->sinks[$i]->writeOpenStream( $string );
+ }
+ }
+
+ function writeCloseStream( $string ) {
+ for( $i = 0; $i < $this->count; $i++ ) {
+ $this->sinks[$i]->writeCloseStream( $string );
+ }
+ }
+
+ function writeOpenPage( $page, $string ) {
+ for( $i = 0; $i < $this->count; $i++ ) {
+ $this->sinks[$i]->writeOpenPage( $page, $string );
+ }
+ }
+
+ function writeClosePage( $string ) {
+ for( $i = 0; $i < $this->count; $i++ ) {
+ $this->sinks[$i]->writeClosePage( $string );
+ }
+ }
+
+ function writeRevision( $rev, $string ) {
+ for( $i = 0; $i < $this->count; $i++ ) {
+ $this->sinks[$i]->writeRevision( $rev, $string );
+ }
+ }
+}
+
+function xmlsafe( $string ) {
+ $fname = 'xmlsafe';
+ wfProfileIn( $fname );
+
+ /**
+ * The page may contain old data which has not been properly normalized.
+ * Invalid UTF-8 sequences or forbidden control characters will make our
+ * XML output invalid, so be sure to strip them out.
+ */
+ $string = UtfNormal::cleanUp( $string );
+
+ $string = htmlspecialchars( $string );
+ wfProfileOut( $fname );
+ return $string;
+}
+
+?>
diff --git a/includes/ExternalEdit.php b/includes/ExternalEdit.php
new file mode 100644
index 000000000000..14b55fdbde26
--- /dev/null
+++ b/includes/ExternalEdit.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * License: Public domain
+ *
+ * @author Erik Moeller <moeller@scireview.de>
+ * @package MediaWiki
+ */
+
+/**
+ *
+ * @package MediaWiki
+ *
+ * Support for external editors to modify both text and files
+ * in external applications. It works as follows: MediaWiki
+ * sends a meta-file with the MIME type 'application/x-external-editor'
+ * to the client. The user has to associate that MIME type with
+ * a helper application (a reference implementation in Perl
+ * can be found in extensions/ee), which will launch the editor,
+ * and save the modified data back to the server.
+ *
+ */
+
+class ExternalEdit {
+
+ function ExternalEdit ( $article, $mode ) {
+ global $wgInputEncoding;
+ $this->mArticle =& $article;
+ $this->mTitle =& $article->mTitle;
+ $this->mCharset = $wgInputEncoding;
+ $this->mMode = $mode;
+ }
+
+ function edit() {
+ global $wgOut, $wgScript, $wgScriptPath, $wgServer, $wgLang;
+ $wgOut->disable();
+ $name=$this->mTitle->getText();
+ $pos=strrpos($name,".")+1;
+ header ( "Content-type: application/x-external-editor; charset=".$this->mCharset );
+
+ # $type can be "Edit text", "Edit file" or "Diff text" at the moment
+ # See the protocol specifications at [[m:Help:External editors/Tech]] for
+ # details.
+ if(!isset($this->mMode)) {
+ $type="Edit text";
+ $url=$this->mTitle->getFullURL("action=edit&internaledit=true");
+ # *.wiki file extension is used by some editors for syntax
+ # highlighting, so we follow that convention
+ $extension="wiki";
+ } elseif($this->mMode=="file") {
+ $type="Edit file";
+ $image = new Image( $this->mTitle );
+ $img_url = $image->getURL();
+ if(strpos($img_url,"://")) {
+ $url = $img_url;
+ } else {
+ $url = $wgServer . $img_url;
+ }
+ $extension=substr($name, $pos);
+ }
+ $special=$wgLang->getNsText(NS_SPECIAL);
+ $control = <<<CONTROL
+[Process]
+Type=$type
+Engine=MediaWiki
+Script={$wgServer}{$wgScript}
+Server={$wgServer}
+Path={$wgScriptPath}
+Special namespace=$special
+
+[File]
+Extension=$extension
+URL=$url
+CONTROL;
+ echo $control;
+ }
+}
+?>
diff --git a/includes/ExternalStore.php b/includes/ExternalStore.php
new file mode 100644
index 000000000000..79f1a5289e09
--- /dev/null
+++ b/includes/ExternalStore.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ *
+ * Constructor class for data kept in external repositories
+ *
+ * External repositories might be populated by maintenance/async
+ * scripts, thus partial moving of data may be possible, as well
+ * as possibility to have any storage format (i.e. for archives)
+ *
+ */
+
+class ExternalStore {
+ /* Fetch data from given URL */
+ function fetchFromURL($url) {
+ global $wgExternalStores;
+
+ if (!$wgExternalStores)
+ return false;
+
+ @list($proto,$path)=explode('://',$url,2);
+ /* Bad URL */
+ if ($path=="")
+ return false;
+
+ $store =& ExternalStore::getStoreObject( $proto );
+ if ( $store === false )
+ return false;
+ return $store->fetchFromURL($url);
+ }
+
+ /**
+ * Get an external store object of the given type
+ */
+ function &getStoreObject( $proto ) {
+ global $wgExternalStores;
+ if (!$wgExternalStores)
+ return false;
+ /* Protocol not enabled */
+ if (!in_array( $proto, $wgExternalStores ))
+ return false;
+
+ $class='ExternalStore'.ucfirst($proto);
+ /* Preloaded modules might exist, especially ones serving multiple protocols */
+ if (!class_exists($class)) {
+ if (!include_once($class.'.php'))
+ return false;
+ }
+ $store=new $class();
+ return $store;
+ }
+
+ /**
+ * Store a data item to an external store, identified by a partial URL
+ * The protocol part is used to identify the class, the rest is passed to the
+ * class itself as a parameter.
+ * Returns the URL of the stored data item, or false on error
+ */
+ function insert( $url, $data ) {
+ list( $proto, $params ) = explode( '://', $url, 2 );
+ $store =& ExternalStore::getStoreObject( $proto );
+ if ( $store === false ) {
+ return false;
+ } else {
+ return $store->store( $params, $data );
+ }
+ }
+}
+?>
diff --git a/includes/ExternalStoreDB.php b/includes/ExternalStoreDB.php
new file mode 100644
index 000000000000..861a9939626c
--- /dev/null
+++ b/includes/ExternalStoreDB.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ *
+ * DB accessable external objects
+ *
+ */
+
+
+/** @package MediaWiki */
+
+/**
+ * External database storage will use one (or more) separate connection pools
+ * from what the main wiki uses. If we load many revisions, such as when doing
+ * bulk backups or maintenance, we want to keep them around over the lifetime
+ * of the script.
+ *
+ * Associative array of LoadBalancer objects, indexed by cluster name.
+ */
+global $wgExternalLoadBalancers;
+$wgExternalLoadBalancers = array();
+
+/**
+ * One-step cache variable to hold base blobs; operations that
+ * pull multiple revisions may often pull multiple times from
+ * the same blob. By keeping the last-used one open, we avoid
+ * redundant unserialization and decompression overhead.
+ */
+global $wgExternalBlobCache;
+$wgExternalBlobCache = array();
+
+class ExternalStoreDB {
+
+ /** @todo Document.*/
+ function &getLoadBalancer( $cluster ) {
+ global $wgExternalServers, $wgExternalLoadBalancers;
+ if ( !array_key_exists( $cluster, $wgExternalLoadBalancers ) ) {
+ $wgExternalLoadBalancers[$cluster] = LoadBalancer::newFromParams( $wgExternalServers[$cluster] );
+ }
+ $wgExternalLoadBalancers[$cluster]->allowLagged(true);
+ return $wgExternalLoadBalancers[$cluster];
+ }
+
+ /** @todo Document.*/
+ function &getSlave( $cluster ) {
+ $lb =& $this->getLoadBalancer( $cluster );
+ return $lb->getConnection( DB_SLAVE );
+ }
+
+ /** @todo Document.*/
+ function &getMaster( $cluster ) {
+ $lb =& $this->getLoadBalancer( $cluster );
+ return $lb->getConnection( DB_MASTER );
+ }
+
+ /** @todo Document.*/
+ function getTable( &$db ) {
+ $table = $db->getLBInfo( 'blobs table' );
+ if ( is_null( $table ) ) {
+ $table = 'blobs';
+ }
+ return $table;
+ }
+
+ /**
+ * Fetch data from given URL
+ * @param string $url An url of the form DB://cluster/id or DB://cluster/id/itemid for concatened storage.
+ */
+ function fetchFromURL($url) {
+ $path = explode( '/', $url );
+ $cluster = $path[2];
+ $id = $path[3];
+ if ( isset( $path[4] ) ) {
+ $itemID = $path[4];
+ } else {
+ $itemID = false;
+ }
+
+ $ret =& $this->fetchBlob( $cluster, $id, $itemID );
+
+ if ( $itemID !== false && $ret !== false ) {
+ return $ret->getItem( $itemID );
+ }
+ return $ret;
+ }
+
+ /**
+ * Fetch a blob item out of the database; a cache of the last-loaded
+ * blob will be kept so that multiple loads out of a multi-item blob
+ * can avoid redundant database access and decompression.
+ * @param $cluster
+ * @param $id
+ * @param $itemID
+ * @return mixed
+ * @private
+ */
+ function &fetchBlob( $cluster, $id, $itemID ) {
+ global $wgExternalBlobCache;
+ $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/";
+ if( isset( $wgExternalBlobCache[$cacheID] ) ) {
+ wfDebug( "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" );
+ return $wgExternalBlobCache[$cacheID];
+ }
+
+ wfDebug( "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" );
+
+ $dbr =& $this->getSlave( $cluster );
+ $ret = $dbr->selectField( $this->getTable( $dbr ), 'blob_text', array( 'blob_id' => $id ) );
+ if ( $ret === false ) {
+ wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" );
+ // Try the master
+ $dbw =& $this->getMaster( $cluster );
+ $ret = $dbw->selectField( $this->getTable( $dbw ), 'blob_text', array( 'blob_id' => $id ) );
+ if( $ret === false) {
+ wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" );
+ }
+ }
+ if( $itemID !== false && $ret !== false ) {
+ // Unserialise object; caller extracts item
+ $ret = unserialize( $ret );
+ }
+
+ $wgExternalBlobCache = array( $cacheID => &$ret );
+ return $ret;
+ }
+
+ /**
+ * Insert a data item into a given cluster
+ *
+ * @param $cluster String: the cluster name
+ * @param $data String: the data item
+ * @return string URL
+ */
+ function store( $cluster, $data ) {
+ $fname = 'ExternalStoreDB::store';
+
+ $dbw =& $this->getMaster( $cluster );
+
+ $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
+ $dbw->insert( $this->getTable( $dbw ), array( 'blob_id' => $id, 'blob_text' => $data ), $fname );
+ $id = $dbw->insertId();
+ if ( $dbw->getFlag( DBO_TRX ) ) {
+ $dbw->immediateCommit();
+ }
+ return "DB://$cluster/$id";
+ }
+}
+?>
diff --git a/includes/ExternalStoreHttp.php b/includes/ExternalStoreHttp.php
new file mode 100644
index 000000000000..daf62cc4459b
--- /dev/null
+++ b/includes/ExternalStoreHttp.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ *
+ * Example class for HTTP accessable external objects
+ *
+ */
+
+class ExternalStoreHttp {
+ /* Fetch data from given URL */
+ function fetchFromURL($url) {
+ ini_set( "allow_url_fopen", true );
+ $ret = file_get_contents( $url );
+ ini_set( "allow_url_fopen", false );
+ return $ret;
+ }
+
+ /* XXX: may require other methods, for store, delete,
+ * whatever, for initial ext storage
+ */
+}
+?>
diff --git a/includes/FakeTitle.php b/includes/FakeTitle.php
new file mode 100644
index 000000000000..ae05385ad2bc
--- /dev/null
+++ b/includes/FakeTitle.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * Fake title class that triggers an error if any members are called
+ */
+class FakeTitle {
+ function error() { throw new MWException( "Attempt to call member function of FakeTitle\n" ); }
+
+ // PHP 5.1 method overload
+ function __call( $name, $args ) { $this->error(); }
+
+ // PHP <5.1 compatibility
+ function getInterwikiLink() { $this->error(); }
+ function getInterwikiCached() { $this->error(); }
+ function isLocal() { $this->error(); }
+ function isTrans() { $this->error(); }
+ function touchArray( $titles, $timestamp = '' ) { $this->error(); }
+ function getText() { $this->error(); }
+ function getPartialURL() { $this->error(); }
+ function getDBkey() { $this->error(); }
+ function getNamespace() { $this->error(); }
+ function getNsText() { $this->error(); }
+ function getSubjectNsText() { $this->error(); }
+ function getInterwiki() { $this->error(); }
+ function getFragment() { $this->error(); }
+ function getDefaultNamespace() { $this->error(); }
+ function getIndexTitle() { $this->error(); }
+ function getPrefixedDBkey() { $this->error(); }
+ function getPrefixedText() { $this->error(); }
+ function getFullText() { $this->error(); }
+ function getPrefixedURL() { $this->error(); }
+ function getFullURL() {$this->error(); }
+ function getLocalURL() { $this->error(); }
+ function escapeLocalURL() { $this->error(); }
+ function escapeFullURL() { $this->error(); }
+ function getInternalURL() { $this->error(); }
+ function getEditURL() { $this->error(); }
+ function getEscapedText() { $this->error(); }
+ function isExternal() { $this->error(); }
+ function isSemiProtected() { $this->error(); }
+ function isProtected() { $this->error(); }
+ function userIsWatching() { $this->error(); }
+ function userCan() { $this->error(); }
+ function userCanEdit() { $this->error(); }
+ function userCanMove() { $this->error(); }
+ function isMovable() { $this->error(); }
+ function userCanRead() { $this->error(); }
+ function isTalkPage() { $this->error(); }
+ function isCssJsSubpage() { $this->error(); }
+ function isValidCssJsSubpage() { $this->error(); }
+ function getSkinFromCssJsSubpage() { $this->error(); }
+ function isCssSubpage() { $this->error(); }
+ function isJsSubpage() { $this->error(); }
+ function userCanEditCssJsSubpage() { $this->error(); }
+ function loadRestrictions( $res ) { $this->error(); }
+ function getRestrictions($action) { $this->error(); }
+ function isDeleted() { $this->error(); }
+ function getArticleID( $flags = 0 ) { $this->error(); }
+ function getLatestRevID() { $this->error(); }
+ function resetArticleID( $newid ) { $this->error(); }
+ function invalidateCache() { $this->error(); }
+ function getTalkPage() { $this->error(); }
+ function getSubjectPage() { $this->error(); }
+ function getLinksTo() { $this->error(); }
+ function getTemplateLinksTo() { $this->error(); }
+ function getBrokenLinksFrom() { $this->error(); }
+ function getSquidURLs() { $this->error(); }
+ function moveNoAuth() { $this->error(); }
+ function isValidMoveOperation() { $this->error(); }
+ function moveTo() { $this->error(); }
+ function moveOverExistingRedirect() { $this->error(); }
+ function moveToNewTitle() { $this->error(); }
+ function isValidMoveTarget() { $this->error(); }
+ function createRedirect() { $this->error(); }
+ function getParentCategories() { $this->error(); }
+ function getParentCategoryTree() { $this->error(); }
+ function pageCond() { $this->error(); }
+ function getPreviousRevisionID() { $this->error(); }
+ function getNextRevisionID() { $this->error(); }
+ function equals() { $this->error(); }
+ function exists() { $this->error(); }
+ function isAlwaysKnown() { $this->error(); }
+ function touchLinks() { $this->error(); }
+ function trackbackURL() { $this->error(); }
+ function trackbackRDF() { $this->error(); }
+}
+
+?>
diff --git a/includes/Feed.php b/includes/Feed.php
new file mode 100644
index 000000000000..5c14865d8f18
--- /dev/null
+++ b/includes/Feed.php
@@ -0,0 +1,310 @@
+<?php
+# Basic support for outputting syndication feeds in RSS, other formats
+#
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Contain a feed class as well as classes to build rss / atom ... feeds
+ * Available feeds are defined in Defines.php
+ * @package MediaWiki
+ */
+
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class FeedItem {
+ /**#@+
+ * @var string
+ * @private
+ */
+ var $Title = 'Wiki';
+ var $Description = '';
+ var $Url = '';
+ var $Date = '';
+ var $Author = '';
+ /**#@-*/
+
+ /**#@+
+ * @todo document
+ */
+ function FeedItem( $Title, $Description, $Url, $Date = '', $Author = '', $Comments = '' ) {
+ $this->Title = $Title;
+ $this->Description = $Description;
+ $this->Url = $Url;
+ $this->Date = $Date;
+ $this->Author = $Author;
+ $this->Comments = $Comments;
+ }
+
+ /**
+ * @static
+ */
+ function xmlEncode( $string ) {
+ $string = str_replace( "\r\n", "\n", $string );
+ $string = preg_replace( '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', '', $string );
+ return htmlspecialchars( $string );
+ }
+
+ function getTitle() { return $this->xmlEncode( $this->Title ); }
+ function getUrl() { return $this->xmlEncode( $this->Url ); }
+ function getDescription() { return $this->xmlEncode( $this->Description ); }
+ function getLanguage() {
+ global $wgContLanguageCode;
+ return $wgContLanguageCode;
+ }
+ function getDate() { return $this->Date; }
+ function getAuthor() { return $this->xmlEncode( $this->Author ); }
+ function getComments() { return $this->xmlEncode( $this->Comments ); }
+ /**#@-*/
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class ChannelFeed extends FeedItem {
+ /**#@+
+ * Abstract function, override!
+ * @abstract
+ */
+
+ /**
+ * Generate Header of the feed
+ */
+ function outHeader() {
+ # print "<feed>";
+ }
+
+ /**
+ * Generate an item
+ * @param $item
+ */
+ function outItem( $item ) {
+ # print "<item>...</item>";
+ }
+
+ /**
+ * Generate Footer of the feed
+ */
+ function outFooter() {
+ # print "</feed>";
+ }
+ /**#@-*/
+
+ /**
+ * Setup and send HTTP headers. Don't send any content;
+ * content might end up being cached and re-sent with
+ * these same headers later.
+ *
+ * This should be called from the outHeader() method,
+ * but can also be called separately.
+ *
+ * @public
+ */
+ function httpHeaders() {
+ global $wgOut;
+
+ # We take over from $wgOut, excepting its cache header info
+ $wgOut->disable();
+ $mimetype = $this->contentType();
+ header( "Content-type: $mimetype; charset=UTF-8" );
+ $wgOut->sendCacheControl();
+
+ }
+
+ /**
+ * Return an internet media type to be sent in the headers.
+ *
+ * @return string
+ * @private
+ */
+ function contentType() {
+ global $wgRequest;
+ $ctype = $wgRequest->getVal('ctype','application/xml');
+ $allowedctypes = array('application/xml','text/xml','application/rss+xml','application/atom+xml');
+ return (in_array($ctype, $allowedctypes) ? $ctype : 'application/xml');
+ }
+
+ /**
+ * Output the initial XML headers with a stylesheet for legibility
+ * if someone finds it in a browser.
+ * @private
+ */
+ function outXmlHeader() {
+ global $wgServer, $wgStylePath, $wgStyleVersion;
+
+ $this->httpHeaders();
+ echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
+ echo '<?xml-stylesheet type="text/css" href="' .
+ htmlspecialchars( "$wgServer$wgStylePath/common/feed.css?$wgStyleVersion" ) . '"?' . ">\n";
+ }
+}
+
+/**
+ * Generate a RSS feed
+ * @todo document
+ * @package MediaWiki
+ */
+class RSSFeed extends ChannelFeed {
+
+ /**
+ * Format a date given a timestamp
+ * @param integer $ts Timestamp
+ * @return string Date string
+ */
+ function formatTime( $ts ) {
+ return gmdate( 'D, d M Y H:i:s \G\M\T', wfTimestamp( TS_UNIX, $ts ) );
+ }
+
+ /**
+ * Ouput an RSS 2.0 header
+ */
+ function outHeader() {
+ global $wgVersion;
+
+ $this->outXmlHeader();
+ ?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <channel>
+ <title><?php print $this->getTitle() ?></title>
+ <link><?php print $this->getUrl() ?></link>
+ <description><?php print $this->getDescription() ?></description>
+ <language><?php print $this->getLanguage() ?></language>
+ <generator>MediaWiki <?php print $wgVersion ?></generator>
+ <lastBuildDate><?php print $this->formatTime( wfTimestampNow() ) ?></lastBuildDate>
+<?php
+ }
+
+ /**
+ * Output an RSS 2.0 item
+ * @param FeedItem item to be output
+ */
+ function outItem( $item ) {
+ ?>
+ <item>
+ <title><?php print $item->getTitle() ?></title>
+ <link><?php print $item->getUrl() ?></link>
+ <description><?php print $item->getDescription() ?></description>
+ <?php if( $item->getDate() ) { ?><pubDate><?php print $this->formatTime( $item->getDate() ) ?></pubDate><?php } ?>
+ <?php if( $item->getAuthor() ) { ?><dc:creator><?php print $item->getAuthor() ?></dc:creator><?php }?>
+ <?php if( $item->getComments() ) { ?><comments><?php print $item->getComments() ?></comments><?php }?>
+ </item>
+<?php
+ }
+
+ /**
+ * Ouput an RSS 2.0 footer
+ */
+ function outFooter() {
+ ?>
+ </channel>
+</rss><?php
+ }
+}
+
+/**
+ * Generate an Atom feed
+ * @todo document
+ * @package MediaWiki
+ */
+class AtomFeed extends ChannelFeed {
+ /**
+ * @todo document
+ */
+ function formatTime( $ts ) {
+ // need to use RFC 822 time format at least for rss2.0
+ return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $ts ) );
+ }
+
+ /**
+ * Outputs a basic header for Atom 1.0 feeds.
+ */
+ function outHeader() {
+ global $wgVersion;
+
+ $this->outXmlHeader();
+ ?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="<?php print $this->getLanguage() ?>">
+ <id><?php print $this->getFeedId() ?></id>
+ <title><?php print $this->getTitle() ?></title>
+ <link rel="self" type="application/atom+xml" href="<?php print $this->getSelfUrl() ?>"/>
+ <link rel="alternate" type="text/html" href="<?php print $this->getUrl() ?>"/>
+ <updated><?php print $this->formatTime( wfTimestampNow() ) ?>Z</updated>
+ <subtitle><?php print $this->getDescription() ?></subtitle>
+ <generator>MediaWiki <?php print $wgVersion ?></generator>
+
+<?php
+ }
+
+ /**
+ * Atom 1.0 requires a unique, opaque IRI as a unique indentifier
+ * for every feed we create. For now just use the URL, but who
+ * can tell if that's right? If we put options on the feed, do we
+ * have to change the id? Maybe? Maybe not.
+ *
+ * @return string
+ * @private
+ */
+ function getFeedId() {
+ return $this->getSelfUrl();
+ }
+
+ /**
+ * Atom 1.0 requests a self-reference to the feed.
+ * @return string
+ * @private
+ */
+ function getSelfUrl() {
+ global $wgRequest;
+ return htmlspecialchars( $wgRequest->getFullRequestURL() );
+ }
+
+ /**
+ * Output a given item.
+ * @param $item
+ */
+ function outItem( $item ) {
+ global $wgMimeType;
+ ?>
+ <entry>
+ <id><?php print $item->getUrl() ?></id>
+ <title><?php print $item->getTitle() ?></title>
+ <link rel="alternate" type="<?php print $wgMimeType ?>" href="<?php print $item->getUrl() ?>"/>
+ <?php if( $item->getDate() ) { ?>
+ <updated><?php print $this->formatTime( $item->getDate() ) ?>Z</updated>
+ <?php } ?>
+
+ <summary type="html"><?php print $item->getDescription() ?></summary>
+ <?php if( $item->getAuthor() ) { ?><author><name><?php print $item->getAuthor() ?></name></author><?php }?>
+ </entry>
+
+<?php /* FIXME need to add comments
+ <?php if( $item->getComments() ) { ?><dc:comment><?php print $item->getComments() ?></dc:comment><?php }?>
+ */
+ }
+
+ /**
+ * Outputs the footer for Atom 1.0 feed (basicly '\</feed\>').
+ */
+ function outFooter() {?>
+ </feed><?php
+ }
+}
+
+?>
diff --git a/includes/FileStore.php b/includes/FileStore.php
new file mode 100644
index 000000000000..1fd35b01f618
--- /dev/null
+++ b/includes/FileStore.php
@@ -0,0 +1,373 @@
+<?php
+
+class FileStore {
+ const DELETE_ORIGINAL = 1;
+
+ /**
+ * Fetch the FileStore object for a given storage group
+ */
+ static function get( $group ) {
+ global $wgFileStore;
+
+ if( isset( $wgFileStore[$group] ) ) {
+ $info = $wgFileStore[$group];
+ return new FileStore( $group,
+ $info['directory'],
+ $info['url'],
+ intval( $info['hash'] ) );
+ } else {
+ return null;
+ }
+ }
+
+ private function __construct( $group, $directory, $path, $hash ) {
+ $this->mGroup = $group;
+ $this->mDirectory = $directory;
+ $this->mPath = $path;
+ $this->mHashLevel = $hash;
+ }
+
+ /**
+ * Acquire a lock; use when performing write operations on a store.
+ * This is attached to your master database connection, so if you
+ * suffer an uncaught error the lock will be released when the
+ * connection is closed.
+ *
+ * @fixme Probably only works on MySQL. Abstract to the Database class?
+ */
+ static function lock() {
+ global $wgDBtype;
+ if ($wgDBtype != 'mysql')
+ return true;
+ $dbw = wfGetDB( DB_MASTER );
+ $lockname = $dbw->addQuotes( FileStore::lockName() );
+ $result = $dbw->query( "SELECT GET_LOCK($lockname, 5) AS lockstatus", __METHOD__ );
+ $row = $dbw->fetchObject( $result );
+ $dbw->freeResult( $result );
+
+ if( $row->lockstatus == 1 ) {
+ return true;
+ } else {
+ wfDebug( __METHOD__." failed to acquire lock\n" );
+ return false;
+ }
+ }
+
+ /**
+ * Release the global file store lock.
+ */
+ static function unlock() {
+ global $wgDBtype;
+ if ($wgDBtype != 'mysql')
+ return true;
+ $dbw = wfGetDB( DB_MASTER );
+ $lockname = $dbw->addQuotes( FileStore::lockName() );
+ $result = $dbw->query( "SELECT RELEASE_LOCK($lockname)", __METHOD__ );
+ $dbw->fetchObject( $result );
+ $dbw->freeResult( $result );
+ }
+
+ private static function lockName() {
+ return 'MediaWiki.' . wfWikiID() . '.FileStore';
+ }
+
+ /**
+ * Copy a file into the file store from elsewhere in the filesystem.
+ * Should be protected by FileStore::lock() to avoid race conditions.
+ *
+ * @param $key storage key string
+ * @param $flags
+ * DELETE_ORIGINAL - remove the source file on transaction commit.
+ *
+ * @throws FSException if copy can't be completed
+ * @return FSTransaction
+ */
+ function insert( $key, $sourcePath, $flags=0 ) {
+ $destPath = $this->filePath( $key );
+ return $this->copyFile( $sourcePath, $destPath, $flags );
+ }
+
+ /**
+ * Copy a file from the file store to elsewhere in the filesystem.
+ * Should be protected by FileStore::lock() to avoid race conditions.
+ *
+ * @param $key storage key string
+ * @param $flags
+ * DELETE_ORIGINAL - remove the source file on transaction commit.
+ *
+ * @throws FSException if copy can't be completed
+ * @return FSTransaction on success
+ */
+ function export( $key, $destPath, $flags=0 ) {
+ $sourcePath = $this->filePath( $key );
+ return $this->copyFile( $sourcePath, $destPath, $flags );
+ }
+
+ private function copyFile( $sourcePath, $destPath, $flags=0 ) {
+ if( !file_exists( $sourcePath ) ) {
+ // Abort! Abort!
+ throw new FSException( "missing source file '$sourcePath'\n" );
+ }
+
+ $transaction = new FSTransaction();
+
+ if( $flags & self::DELETE_ORIGINAL ) {
+ $transaction->addCommit( FSTransaction::DELETE_FILE, $sourcePath );
+ }
+
+ if( file_exists( $destPath ) ) {
+ // An identical file is already present; no need to copy.
+ } else {
+ if( !file_exists( dirname( $destPath ) ) ) {
+ wfSuppressWarnings();
+ $ok = mkdir( dirname( $destPath ), 0777, true );
+ wfRestoreWarnings();
+
+ if( !$ok ) {
+ throw new FSException(
+ "failed to create directory for '$destPath'\n" );
+ }
+ }
+
+ wfSuppressWarnings();
+ $ok = copy( $sourcePath, $destPath );
+ wfRestoreWarnings();
+
+ if( $ok ) {
+ wfDebug( __METHOD__." copied '$sourcePath' to '$destPath'\n" );
+ $transaction->addRollback( FSTransaction::DELETE_FILE, $destPath );
+ } else {
+ throw new FSException(
+ __METHOD__." failed to copy '$sourcePath' to '$destPath'\n" );
+ }
+ }
+
+ return $transaction;
+ }
+
+ /**
+ * Delete a file from the file store.
+ * Caller's responsibility to make sure it's not being used by another row.
+ *
+ * File is not actually removed until transaction commit.
+ * Should be protected by FileStore::lock() to avoid race conditions.
+ *
+ * @param $key storage key string
+ * @throws FSException if file can't be deleted
+ * @return FSTransaction
+ */
+ function delete( $key ) {
+ $destPath = $this->filePath( $key );
+ if( false === $destPath ) {
+ throw new FSExcepton( "file store does not contain file '$key'" );
+ } else {
+ return FileStore::deleteFile( $destPath );
+ }
+ }
+
+ /**
+ * Delete a non-managed file on a transactional basis.
+ *
+ * File is not actually removed until transaction commit.
+ * Should be protected by FileStore::lock() to avoid race conditions.
+ *
+ * @param $path file to remove
+ * @throws FSException if file can't be deleted
+ * @return FSTransaction
+ *
+ * @fixme Might be worth preliminary permissions check
+ */
+ static function deleteFile( $path ) {
+ if( file_exists( $path ) ) {
+ $transaction = new FSTransaction();
+ $transaction->addCommit( FSTransaction::DELETE_FILE, $path );
+ return $transaction;
+ } else {
+ throw new FSException( "cannot delete missing file '$path'" );
+ }
+ }
+
+ /**
+ * Stream a contained file directly to HTTP output.
+ * Will throw a 404 if file is missing; 400 if invalid key.
+ * @return true on success, false on failure
+ */
+ function stream( $key ) {
+ $path = $this->filePath( $key );
+ if( $path === false ) {
+ wfHttpError( 400, "Bad request", "Invalid or badly-formed filename." );
+ return false;
+ }
+
+ if( file_exists( $path ) ) {
+ // Set the filename for more convenient save behavior from browsers
+ // FIXME: Is this safe?
+ header( 'Content-Disposition: inline; filename="' . $key . '"' );
+
+ require_once 'StreamFile.php';
+ wfStreamFile( $path );
+ } else {
+ return wfHttpError( 404, "Not found",
+ "The requested resource does not exist." );
+ }
+ }
+
+ /**
+ * Confirm that the given file key is valid.
+ * Note that a valid key may refer to a file that does not exist.
+ *
+ * Key should consist of a 32-digit base-36 SHA-1 hash and
+ * an optional alphanumeric extension, all lowercase.
+ * The whole must not exceed 64 characters.
+ *
+ * @param $key
+ * @return boolean
+ */
+ static function validKey( $key ) {
+ return preg_match( '/^[0-9a-z]{32}(\.[0-9a-z]{1,31})?$/', $key );
+ }
+
+
+ /**
+ * Calculate file storage key from a file on disk.
+ * You must pass an extension to it, as some files may be calculated
+ * out of a temporary file etc.
+ *
+ * @param $path to file
+ * @param $extension
+ * @return string or false if could not open file or bad extension
+ */
+ static function calculateKey( $path, $extension ) {
+ wfSuppressWarnings();
+ $hash = sha1_file( $path );
+ wfRestoreWarnings();
+ if( $hash === false ) {
+ wfDebug( __METHOD__.": couldn't hash file '$path'\n" );
+ return false;
+ }
+
+ $base36 = wfBaseConvert( $hash, 16, 36, 32 );
+ if( $extension == '' ) {
+ $key = $base36;
+ } else {
+ $key = $base36 . '.' . $extension;
+ }
+
+ // Sanity check
+ if( self::validKey( $key ) ) {
+ return $key;
+ } else {
+ wfDebug( __METHOD__.": generated bad key '$key'\n" );
+ return false;
+ }
+ }
+
+ /**
+ * Return filesystem path to the given file.
+ * Note that the file may or may not exist.
+ * @return string or false if an invalid key
+ */
+ function filePath( $key ) {
+ if( self::validKey( $key ) ) {
+ return $this->mDirectory . DIRECTORY_SEPARATOR .
+ $this->hashPath( $key, DIRECTORY_SEPARATOR );
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return URL path to the given file, if the store is public.
+ * @return string or false if not public
+ */
+ function urlPath( $key ) {
+ if( $this->mUrl && self::validKey( $key ) ) {
+ return $this->mUrl . '/' . $this->hashPath( $key, '/' );
+ } else {
+ return false;
+ }
+ }
+
+ private function hashPath( $key, $separator ) {
+ $parts = array();
+ for( $i = 0; $i < $this->mHashLevel; $i++ ) {
+ $parts[] = $key{$i};
+ }
+ $parts[] = $key;
+ return implode( $separator, $parts );
+ }
+}
+
+/**
+ * Wrapper for file store transaction stuff.
+ *
+ * FileStore methods may return one of these for undoable operations;
+ * you can then call its rollback() or commit() methods to perform
+ * final cleanup if dependent database work fails or succeeds.
+ */
+class FSTransaction {
+ const DELETE_FILE = 1;
+
+ /**
+ * Combine more items into a fancier transaction
+ */
+ function add( FSTransaction $transaction ) {
+ $this->mOnCommit = array_merge(
+ $this->mOnCommit, $transaction->mOnCommit );
+ $this->mOnRollback = array_merge(
+ $this->mOnRollback, $transaction->mOnRollback );
+ }
+
+ /**
+ * Perform final actions for success.
+ * @return true if actions applied ok, false if errors
+ */
+ function commit() {
+ return $this->apply( $this->mOnCommit );
+ }
+
+ /**
+ * Perform final actions for failure.
+ * @return true if actions applied ok, false if errors
+ */
+ function rollback() {
+ return $this->apply( $this->mOnRollback );
+ }
+
+ // --- Private and friend functions below...
+
+ function __construct() {
+ $this->mOnCommit = array();
+ $this->mOnRollback = array();
+ }
+
+ function addCommit( $action, $path ) {
+ $this->mOnCommit[] = array( $action, $path );
+ }
+
+ function addRollback( $action, $path ) {
+ $this->mOnRollback[] = array( $action, $path );
+ }
+
+ private function apply( $actions ) {
+ $result = true;
+ foreach( $actions as $item ) {
+ list( $action, $path ) = $item;
+ if( $action == self::DELETE_FILE ) {
+ wfSuppressWarnings();
+ $ok = unlink( $path );
+ wfRestoreWarnings();
+ if( $ok )
+ wfDebug( __METHOD__.": deleting file '$path'\n" );
+ else
+ wfDebug( __METHOD__.": failed to delete file '$path'\n" );
+ $result = $result && $ok;
+ }
+ }
+ return $result;
+ }
+}
+
+class FSException extends MWException { }
+
+?>
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
new file mode 100644
index 000000000000..de07b321e0ac
--- /dev/null
+++ b/includes/GlobalFunctions.php
@@ -0,0 +1,2138 @@
+<?php
+
+/**
+ * Global functions used everywhere
+ * @package MediaWiki
+ */
+
+/**
+ * Some globals and requires needed
+ */
+
+/** Total number of articles */
+$wgNumberOfArticles = -1; # Unset
+
+/** Total number of views */
+$wgTotalViews = -1;
+
+/** Total number of edits */
+$wgTotalEdits = -1;
+
+
+require_once( 'LogPage.php' );
+require_once( 'normal/UtfNormalUtil.php' );
+require_once( 'XmlFunctions.php' );
+
+/**
+ * Compatibility functions
+ *
+ * We more or less support PHP 5.0.x and up.
+ * Re-implementations of newer functions or functions in non-standard
+ * PHP extensions may be included here.
+ */
+if( !function_exists('iconv') ) {
+ # iconv support is not in the default configuration and so may not be present.
+ # Assume will only ever use utf-8 and iso-8859-1.
+ # This will *not* work in all circumstances.
+ function iconv( $from, $to, $string ) {
+ if(strcasecmp( $from, $to ) == 0) return $string;
+ if(strcasecmp( $from, 'utf-8' ) == 0) return utf8_decode( $string );
+ if(strcasecmp( $to, 'utf-8' ) == 0) return utf8_encode( $string );
+ return $string;
+ }
+}
+
+# UTF-8 substr function based on a PHP manual comment
+if ( !function_exists( 'mb_substr' ) ) {
+ function mb_substr( $str, $start ) {
+ $ar = array();
+ preg_match_all( '/./us', $str, $ar );
+
+ if( func_num_args() >= 3 ) {
+ $end = func_get_arg( 2 );
+ return join( '', array_slice( $ar[0], $start, $end ) );
+ } else {
+ return join( '', array_slice( $ar[0], $start ) );
+ }
+ }
+}
+
+if ( !function_exists( 'array_diff_key' ) ) {
+ /**
+ * Exists in PHP 5.1.0+
+ * Not quite compatible, two-argument version only
+ * Null values will cause problems due to this use of isset()
+ */
+ function array_diff_key( $left, $right ) {
+ $result = $left;
+ foreach ( $left as $key => $unused ) {
+ if ( isset( $right[$key] ) ) {
+ unset( $result[$key] );
+ }
+ }
+ return $result;
+ }
+}
+
+
+/**
+ * Wrapper for clone(), for compatibility with PHP4-friendly extensions.
+ * PHP 5 won't let you declare a 'clone' function, even conditionally,
+ * so it has to be a wrapper with a different name.
+ */
+function wfClone( $object ) {
+ return clone( $object );
+}
+
+/**
+ * Where as we got a random seed
+ */
+$wgRandomSeeded = false;
+
+/**
+ * Seed Mersenne Twister
+ * No-op for compatibility; only necessary in PHP < 4.2.0
+ */
+function wfSeedRandom() {
+ /* No-op */
+}
+
+/**
+ * Get a random decimal value between 0 and 1, in a way
+ * not likely to give duplicate values for any realistic
+ * number of articles.
+ *
+ * @return string
+ */
+function wfRandom() {
+ # The maximum random value is "only" 2^31-1, so get two random
+ # values to reduce the chance of dupes
+ $max = mt_getrandmax() + 1;
+ $rand = number_format( (mt_rand() * $max + mt_rand())
+ / $max / $max, 12, '.', '' );
+ return $rand;
+}
+
+/**
+ * We want / and : to be included as literal characters in our title URLs.
+ * %2F in the page titles seems to fatally break for some reason.
+ *
+ * @param $s String:
+ * @return string
+*/
+function wfUrlencode ( $s ) {
+ $s = urlencode( $s );
+ $s = preg_replace( '/%3[Aa]/', ':', $s );
+ $s = preg_replace( '/%2[Ff]/', '/', $s );
+
+ return $s;
+}
+
+/**
+ * Sends a line to the debug log if enabled or, optionally, to a comment in output.
+ * In normal operation this is a NOP.
+ *
+ * Controlling globals:
+ * $wgDebugLogFile - points to the log file
+ * $wgProfileOnly - if set, normal debug messages will not be recorded.
+ * $wgDebugRawPage - if false, 'action=raw' hits will not result in debug output.
+ * $wgDebugComments - if on, some debug items may appear in comments in the HTML output.
+ *
+ * @param $text String
+ * @param $logonly Bool: set true to avoid appearing in HTML when $wgDebugComments is set
+ */
+function wfDebug( $text, $logonly = false ) {
+ global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly, $wgDebugRawPage;
+ static $recursion = 0;
+
+ # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
+ if ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' && !$wgDebugRawPage ) {
+ return;
+ }
+
+ if ( $wgDebugComments && !$logonly ) {
+ if ( !isset( $wgOut ) ) {
+ return;
+ }
+ if ( !StubObject::isRealObject( $wgOut ) ) {
+ if ( $recursion ) {
+ return;
+ }
+ $recursion++;
+ $wgOut->_unstub();
+ $recursion--;
+ }
+ $wgOut->debug( $text );
+ }
+ if ( '' != $wgDebugLogFile && !$wgProfileOnly ) {
+ # Strip unprintables; they can switch terminal modes when binary data
+ # gets dumped, which is pretty annoying.
+ $text = preg_replace( '![\x00-\x08\x0b\x0c\x0e-\x1f]!', ' ', $text );
+ @error_log( $text, 3, $wgDebugLogFile );
+ }
+}
+
+/**
+ * Send a line to a supplementary debug log file, if configured, or main debug log if not.
+ * $wgDebugLogGroups[$logGroup] should be set to a filename to send to a separate log.
+ *
+ * @param $logGroup String
+ * @param $text String
+ * @param $public Bool: whether to log the event in the public log if no private
+ * log file is specified, (default true)
+ */
+function wfDebugLog( $logGroup, $text, $public = true ) {
+ global $wgDebugLogGroups;
+ if( $text{strlen( $text ) - 1} != "\n" ) $text .= "\n";
+ if( isset( $wgDebugLogGroups[$logGroup] ) ) {
+ $time = wfTimestamp( TS_DB );
+ $wiki = wfWikiID();
+ @error_log( "$time $wiki: $text", 3, $wgDebugLogGroups[$logGroup] );
+ } else if ( $public === true ) {
+ wfDebug( $text, true );
+ }
+}
+
+/**
+ * Log for database errors
+ * @param $text String: database error message.
+ */
+function wfLogDBError( $text ) {
+ global $wgDBerrorLog;
+ if ( $wgDBerrorLog ) {
+ $host = trim(`hostname`);
+ $text = date('D M j G:i:s T Y') . "\t$host\t".$text;
+ error_log( $text, 3, $wgDBerrorLog );
+ }
+}
+
+/**
+ * @todo document
+ */
+function wfLogProfilingData() {
+ global $wgRequestTime, $wgDebugLogFile, $wgDebugRawPage, $wgRequest;
+ global $wgProfiling, $wgUser;
+ if ( $wgProfiling ) {
+ $now = wfTime();
+ $elapsed = $now - $wgRequestTime;
+ $prof = wfGetProfilingOutput( $wgRequestTime, $elapsed );
+ $forward = '';
+ if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
+ $forward = ' forwarded for ' . $_SERVER['HTTP_X_FORWARDED_FOR'];
+ if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) )
+ $forward .= ' client IP ' . $_SERVER['HTTP_CLIENT_IP'];
+ if( !empty( $_SERVER['HTTP_FROM'] ) )
+ $forward .= ' from ' . $_SERVER['HTTP_FROM'];
+ if( $forward )
+ $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})";
+ // Don't unstub $wgUser at this late stage just for statistics purposes
+ if( StubObject::isRealObject($wgUser) && $wgUser->isAnon() )
+ $forward .= ' anon';
+ $log = sprintf( "%s\t%04.3f\t%s\n",
+ gmdate( 'YmdHis' ), $elapsed,
+ urldecode( $wgRequest->getRequestURL() . $forward ) );
+ if ( '' != $wgDebugLogFile && ( $wgRequest->getVal('action') != 'raw' || $wgDebugRawPage ) ) {
+ error_log( $log . $prof, 3, $wgDebugLogFile );
+ }
+ }
+}
+
+/**
+ * Check if the wiki read-only lock file is present. This can be used to lock
+ * off editing functions, but doesn't guarantee that the database will not be
+ * modified.
+ * @return bool
+ */
+function wfReadOnly() {
+ global $wgReadOnlyFile, $wgReadOnly;
+
+ if ( !is_null( $wgReadOnly ) ) {
+ return (bool)$wgReadOnly;
+ }
+ if ( '' == $wgReadOnlyFile ) {
+ return false;
+ }
+ // Set $wgReadOnly for faster access next time
+ if ( is_file( $wgReadOnlyFile ) ) {
+ $wgReadOnly = file_get_contents( $wgReadOnlyFile );
+ } else {
+ $wgReadOnly = false;
+ }
+ return (bool)$wgReadOnly;
+}
+
+
+/**
+ * Get a message from anywhere, for the current user language.
+ *
+ * Use wfMsgForContent() instead if the message should NOT
+ * change depending on the user preferences.
+ *
+ * Note that the message may contain HTML, and is therefore
+ * not safe for insertion anywhere. Some functions such as
+ * addWikiText will do the escaping for you. Use wfMsgHtml()
+ * if you need an escaped message.
+ *
+ * @param $key String: lookup key for the message, usually
+ * defined in languages/Language.php
+ *
+ * This function also takes extra optional parameters (not
+ * shown in the function definition), which can by used to
+ * insert variable text into the predefined message.
+ */
+function wfMsg( $key ) {
+ $args = func_get_args();
+ array_shift( $args );
+ return wfMsgReal( $key, $args, true );
+}
+
+/**
+ * Same as above except doesn't transform the message
+ */
+function wfMsgNoTrans( $key ) {
+ $args = func_get_args();
+ array_shift( $args );
+ return wfMsgReal( $key, $args, true, false, false );
+}
+
+/**
+ * Get a message from anywhere, for the current global language
+ * set with $wgLanguageCode.
+ *
+ * Use this if the message should NOT change dependent on the
+ * language set in the user's preferences. This is the case for
+ * most text written into logs, as well as link targets (such as
+ * the name of the copyright policy page). Link titles, on the
+ * other hand, should be shown in the UI language.
+ *
+ * Note that MediaWiki allows users to change the user interface
+ * language in their preferences, but a single installation
+ * typically only contains content in one language.
+ *
+ * Be wary of this distinction: If you use wfMsg() where you should
+ * use wfMsgForContent(), a user of the software may have to
+ * customize over 70 messages in order to, e.g., fix a link in every
+ * possible language.
+ *
+ * @param $key String: lookup key for the message, usually
+ * defined in languages/Language.php
+ */
+function wfMsgForContent( $key ) {
+ global $wgForceUIMsgAsContentMsg;
+ $args = func_get_args();
+ array_shift( $args );
+ $forcontent = true;
+ if( is_array( $wgForceUIMsgAsContentMsg ) &&
+ in_array( $key, $wgForceUIMsgAsContentMsg ) )
+ $forcontent = false;
+ return wfMsgReal( $key, $args, true, $forcontent );
+}
+
+/**
+ * Same as above except doesn't transform the message
+ */
+function wfMsgForContentNoTrans( $key ) {
+ global $wgForceUIMsgAsContentMsg;
+ $args = func_get_args();
+ array_shift( $args );
+ $forcontent = true;
+ if( is_array( $wgForceUIMsgAsContentMsg ) &&
+ in_array( $key, $wgForceUIMsgAsContentMsg ) )
+ $forcontent = false;
+ return wfMsgReal( $key, $args, true, $forcontent, false );
+}
+
+/**
+ * Get a message from the language file, for the UI elements
+ */
+function wfMsgNoDB( $key ) {
+ $args = func_get_args();
+ array_shift( $args );
+ return wfMsgReal( $key, $args, false );
+}
+
+/**
+ * Get a message from the language file, for the content
+ */
+function wfMsgNoDBForContent( $key ) {
+ global $wgForceUIMsgAsContentMsg;
+ $args = func_get_args();
+ array_shift( $args );
+ $forcontent = true;
+ if( is_array( $wgForceUIMsgAsContentMsg ) &&
+ in_array( $key, $wgForceUIMsgAsContentMsg ) )
+ $forcontent = false;
+ return wfMsgReal( $key, $args, false, $forcontent );
+}
+
+
+/**
+ * Really get a message
+ * @param $key String: key to get.
+ * @param $args
+ * @param $useDB Boolean
+ * @param $transform Boolean: Whether or not to transform the message.
+ * @param $forContent Boolean
+ * @return String: the requested message.
+ */
+function wfMsgReal( $key, $args, $useDB = true, $forContent=false, $transform = true ) {
+ $message = wfMsgGetKey( $key, $useDB, $forContent, $transform );
+ $message = wfMsgReplaceArgs( $message, $args );
+ return $message;
+}
+
+/**
+ * This function provides the message source for messages to be edited which are *not* stored in the database.
+ * @param $key String:
+ */
+function wfMsgWeirdKey ( $key ) {
+ $subsource = str_replace ( ' ' , '_' , $key ) ;
+ $source = wfMsgForContentNoTrans( $subsource ) ;
+ if ( wfEmptyMsg( $subsource, $source) ) {
+ # Try again with first char lower case
+ $subsource = strtolower ( substr ( $subsource , 0 , 1 ) ) . substr ( $subsource , 1 ) ;
+ $source = wfMsgForContentNoTrans( $subsource ) ;
+ }
+ if ( wfEmptyMsg( $subsource, $source ) ) {
+ # Didn't work either, return blank text
+ $source = "" ;
+ }
+ return $source ;
+}
+
+/**
+ * Fetch a message string value, but don't replace any keys yet.
+ * @param string $key
+ * @param bool $useDB
+ * @param bool $forContent
+ * @return string
+ * @private
+ */
+function wfMsgGetKey( $key, $useDB, $forContent = false, $transform = true ) {
+ global $wgParser, $wgContLang, $wgMessageCache, $wgLang;
+
+ if ( is_object( $wgMessageCache ) )
+ $transstat = $wgMessageCache->getTransform();
+
+ if( is_object( $wgMessageCache ) ) {
+ if ( ! $transform )
+ $wgMessageCache->disableTransform();
+ $message = $wgMessageCache->get( $key, $useDB, $forContent );
+ } else {
+ if( $forContent ) {
+ $lang = &$wgContLang;
+ } else {
+ $lang = &$wgLang;
+ }
+
+ wfSuppressWarnings();
+
+ if( is_object( $lang ) ) {
+ $message = $lang->getMessage( $key );
+ } else {
+ $message = false;
+ }
+ wfRestoreWarnings();
+ if($message === false)
+ $message = Language::getMessage($key);
+ if ( $transform && strstr( $message, '{{' ) !== false ) {
+ $message = $wgParser->transformMsg($message, $wgMessageCache->getParserOptions() );
+ }
+ }
+
+ if ( is_object( $wgMessageCache ) && ! $transform )
+ $wgMessageCache->setTransform( $transstat );
+
+ return $message;
+}
+
+/**
+ * Replace message parameter keys on the given formatted output.
+ *
+ * @param string $message
+ * @param array $args
+ * @return string
+ * @private
+ */
+function wfMsgReplaceArgs( $message, $args ) {
+ # Fix windows line-endings
+ # Some messages are split with explode("\n", $msg)
+ $message = str_replace( "\r", '', $message );
+
+ // Replace arguments
+ if ( count( $args ) ) {
+ if ( is_array( $args[0] ) ) {
+ foreach ( $args[0] as $key => $val ) {
+ $message = str_replace( '$' . $key, $val, $message );
+ }
+ } else {
+ foreach( $args as $n => $param ) {
+ $replacementKeys['$' . ($n + 1)] = $param;
+ }
+ $message = strtr( $message, $replacementKeys );
+ }
+ }
+
+ return $message;
+}
+
+/**
+ * Return an HTML-escaped version of a message.
+ * Parameter replacements, if any, are done *after* the HTML-escaping,
+ * so parameters may contain HTML (eg links or form controls). Be sure
+ * to pre-escape them if you really do want plaintext, or just wrap
+ * the whole thing in htmlspecialchars().
+ *
+ * @param string $key
+ * @param string ... parameters
+ * @return string
+ */
+function wfMsgHtml( $key ) {
+ $args = func_get_args();
+ array_shift( $args );
+ return wfMsgReplaceArgs( htmlspecialchars( wfMsgGetKey( $key, true ) ), $args );
+}
+
+/**
+ * Return an HTML version of message
+ * Parameter replacements, if any, are done *after* parsing the wiki-text message,
+ * so parameters may contain HTML (eg links or form controls). Be sure
+ * to pre-escape them if you really do want plaintext, or just wrap
+ * the whole thing in htmlspecialchars().
+ *
+ * @param string $key
+ * @param string ... parameters
+ * @return string
+ */
+function wfMsgWikiHtml( $key ) {
+ global $wgOut;
+ $args = func_get_args();
+ array_shift( $args );
+ return wfMsgReplaceArgs( $wgOut->parse( wfMsgGetKey( $key, true ), /* can't be set to false */ true ), $args );
+}
+
+/**
+ * Returns message in the requested format
+ * @param string $key Key of the message
+ * @param array $options Processing rules:
+ * <i>parse<i>: parses wikitext to html
+ * <i>parseinline<i>: parses wikitext to html and removes the surrounding p's added by parser or tidy
+ * <i>escape<i>: filters message trough htmlspecialchars
+ * <i>replaceafter<i>: parameters are substituted after parsing or escaping
+ * <i>parsemag<i>: ??
+ */
+function wfMsgExt( $key, $options ) {
+ global $wgOut, $wgParser;
+
+ $args = func_get_args();
+ array_shift( $args );
+ array_shift( $args );
+
+ if( !is_array($options) ) {
+ $options = array($options);
+ }
+
+ $string = wfMsgGetKey( $key, true, false, false );
+
+ if( !in_array('replaceafter', $options) ) {
+ $string = wfMsgReplaceArgs( $string, $args );
+ }
+
+ if( in_array('parse', $options) ) {
+ $string = $wgOut->parse( $string, true, true );
+ } elseif ( in_array('parseinline', $options) ) {
+ $string = $wgOut->parse( $string, true, true );
+ $m = array();
+ if( preg_match( "~^<p>(.*)\n?</p>$~", $string, $m ) ) {
+ $string = $m[1];
+ }
+ } elseif ( in_array('parsemag', $options) ) {
+ global $wgMessageCache;
+ if ( isset( $wgMessageCache ) ) {
+ $string = $wgMessageCache->transform( $string );
+ }
+ }
+
+ if ( in_array('escape', $options) ) {
+ $string = htmlspecialchars ( $string );
+ }
+
+ if( in_array('replaceafter', $options) ) {
+ $string = wfMsgReplaceArgs( $string, $args );
+ }
+
+ return $string;
+}
+
+
+/**
+ * Just like exit() but makes a note of it.
+ * Commits open transactions except if the error parameter is set
+ *
+ * @obsolete Please return control to the caller or throw an exception
+ */
+function wfAbruptExit( $error = false ){
+ global $wgLoadBalancer;
+ static $called = false;
+ if ( $called ){
+ exit( -1 );
+ }
+ $called = true;
+
+ $bt = wfDebugBacktrace();
+ if( $bt ) {
+ for($i = 0; $i < count($bt) ; $i++){
+ $file = isset($bt[$i]['file']) ? $bt[$i]['file'] : "unknown";
+ $line = isset($bt[$i]['line']) ? $bt[$i]['line'] : "unknown";
+ wfDebug("WARNING: Abrupt exit in $file at line $line\n");
+ }
+ } else {
+ wfDebug('WARNING: Abrupt exit\n');
+ }
+
+ wfLogProfilingData();
+
+ if ( !$error ) {
+ $wgLoadBalancer->closeAll();
+ }
+ exit( -1 );
+}
+
+/**
+ * @obsolete Please return control the caller or throw an exception
+ */
+function wfErrorExit() {
+ wfAbruptExit( true );
+}
+
+/**
+ * Print a simple message and die, returning nonzero to the shell if any.
+ * Plain die() fails to return nonzero to the shell if you pass a string.
+ * @param string $msg
+ */
+function wfDie( $msg='' ) {
+ echo $msg;
+ die( 1 );
+}
+
+/**
+ * Throw a debugging exception. This function previously once exited the process,
+ * but now throws an exception instead, with similar results.
+ *
+ * @param string $msg Message shown when dieing.
+ */
+function wfDebugDieBacktrace( $msg = '' ) {
+ throw new MWException( $msg );
+}
+
+/**
+ * Fetch server name for use in error reporting etc.
+ * Use real server name if available, so we know which machine
+ * in a server farm generated the current page.
+ * @return string
+ */
+function wfHostname() {
+ if ( function_exists( 'posix_uname' ) ) {
+ // This function not present on Windows
+ $uname = @posix_uname();
+ } else {
+ $uname = false;
+ }
+ if( is_array( $uname ) && isset( $uname['nodename'] ) ) {
+ return $uname['nodename'];
+ } else {
+ # This may be a virtual server.
+ return $_SERVER['SERVER_NAME'];
+ }
+}
+
+ /**
+ * Returns a HTML comment with the elapsed time since request.
+ * This method has no side effects.
+ * @return string
+ */
+ function wfReportTime() {
+ global $wgRequestTime;
+
+ $now = wfTime();
+ $elapsed = $now - $wgRequestTime;
+
+ $com = sprintf( "<!-- Served by %s in %01.3f secs. -->",
+ wfHostname(), $elapsed );
+ return $com;
+ }
+
+/**
+ * Safety wrapper for debug_backtrace().
+ *
+ * With Zend Optimizer 3.2.0 loaded, this causes segfaults under somewhat
+ * murky circumstances, which may be triggered in part by stub objects
+ * or other fancy talkin'.
+ *
+ * Will return an empty array if Zend Optimizer is detected, otherwise
+ * the output from debug_backtrace() (trimmed).
+ *
+ * @return array of backtrace information
+ */
+function wfDebugBacktrace() {
+ if( extension_loaded( 'Zend Optimizer' ) ) {
+ wfDebug( "Zend Optimizer detected; skipping debug_backtrace for safety.\n" );
+ return array();
+ } else {
+ return array_slice( debug_backtrace(), 1 );
+ }
+}
+
+function wfBacktrace() {
+ global $wgCommandLineMode;
+
+ if ( $wgCommandLineMode ) {
+ $msg = '';
+ } else {
+ $msg = "<ul>\n";
+ }
+ $backtrace = wfDebugBacktrace();
+ foreach( $backtrace as $call ) {
+ if( isset( $call['file'] ) ) {
+ $f = explode( DIRECTORY_SEPARATOR, $call['file'] );
+ $file = $f[count($f)-1];
+ } else {
+ $file = '-';
+ }
+ if( isset( $call['line'] ) ) {
+ $line = $call['line'];
+ } else {
+ $line = '-';
+ }
+ if ( $wgCommandLineMode ) {
+ $msg .= "$file line $line calls ";
+ } else {
+ $msg .= '<li>' . $file . ' line ' . $line . ' calls ';
+ }
+ if( !empty( $call['class'] ) ) $msg .= $call['class'] . '::';
+ $msg .= $call['function'] . '()';
+
+ if ( $wgCommandLineMode ) {
+ $msg .= "\n";
+ } else {
+ $msg .= "</li>\n";
+ }
+ }
+ if ( $wgCommandLineMode ) {
+ $msg .= "\n";
+ } else {
+ $msg .= "</ul>\n";
+ }
+
+ return $msg;
+}
+
+
+/* Some generic result counters, pulled out of SearchEngine */
+
+
+/**
+ * @todo document
+ */
+function wfShowingResults( $offset, $limit ) {
+ global $wgLang;
+ return wfMsg( 'showingresults', $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ) );
+}
+
+/**
+ * @todo document
+ */
+function wfShowingResultsNum( $offset, $limit, $num ) {
+ global $wgLang;
+ return wfMsg( 'showingresultsnum', $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ), $wgLang->formatNum( $num ) );
+}
+
+/**
+ * @todo document
+ */
+function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) {
+ global $wgLang;
+ $fmtLimit = $wgLang->formatNum( $limit );
+ $prev = wfMsg( 'prevn', $fmtLimit );
+ $next = wfMsg( 'nextn', $fmtLimit );
+
+ if( is_object( $link ) ) {
+ $title =& $link;
+ } else {
+ $title = Title::newFromText( $link );
+ if( is_null( $title ) ) {
+ return false;
+ }
+ }
+
+ if ( 0 != $offset ) {
+ $po = $offset - $limit;
+ if ( $po < 0 ) { $po = 0; }
+ $q = "limit={$limit}&offset={$po}";
+ if ( '' != $query ) { $q .= '&'.$query; }
+ $plink = '<a href="' . $title->escapeLocalUrl( $q ) . "\">{$prev}</a>";
+ } else { $plink = $prev; }
+
+ $no = $offset + $limit;
+ $q = 'limit='.$limit.'&offset='.$no;
+ if ( '' != $query ) { $q .= '&'.$query; }
+
+ if ( $atend ) {
+ $nlink = $next;
+ } else {
+ $nlink = '<a href="' . $title->escapeLocalUrl( $q ) . "\">{$next}</a>";
+ }
+ $nums = wfNumLink( $offset, 20, $title, $query ) . ' | ' .
+ wfNumLink( $offset, 50, $title, $query ) . ' | ' .
+ wfNumLink( $offset, 100, $title, $query ) . ' | ' .
+ wfNumLink( $offset, 250, $title, $query ) . ' | ' .
+ wfNumLink( $offset, 500, $title, $query );
+
+ return wfMsg( 'viewprevnext', $plink, $nlink, $nums );
+}
+
+/**
+ * @todo document
+ */
+function wfNumLink( $offset, $limit, &$title, $query = '' ) {
+ global $wgLang;
+ if ( '' == $query ) { $q = ''; }
+ else { $q = $query.'&'; }
+ $q .= 'limit='.$limit.'&offset='.$offset;
+
+ $fmtLimit = $wgLang->formatNum( $limit );
+ $s = '<a href="' . $title->escapeLocalUrl( $q ) . "\">{$fmtLimit}</a>";
+ return $s;
+}
+
+/**
+ * @todo document
+ * @todo FIXME: we may want to blacklist some broken browsers
+ *
+ * @return bool Whereas client accept gzip compression
+ */
+function wfClientAcceptsGzip() {
+ global $wgUseGzip;
+ if( $wgUseGzip ) {
+ # FIXME: we may want to blacklist some broken browsers
+ $m = array();
+ if( preg_match(
+ '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
+ $_SERVER['HTTP_ACCEPT_ENCODING'],
+ $m ) ) {
+ if( isset( $m[2] ) && ( $m[1] == 'q' ) && ( $m[2] == 0 ) ) return false;
+ wfDebug( " accepts gzip\n" );
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Obtain the offset and limit values from the request string;
+ * used in special pages
+ *
+ * @param $deflimit Default limit if none supplied
+ * @param $optionname Name of a user preference to check against
+ * @return array
+ *
+ */
+function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) {
+ global $wgRequest;
+ return $wgRequest->getLimitOffset( $deflimit, $optionname );
+}
+
+/**
+ * Escapes the given text so that it may be output using addWikiText()
+ * without any linking, formatting, etc. making its way through. This
+ * is achieved by substituting certain characters with HTML entities.
+ * As required by the callers, <nowiki> is not used. It currently does
+ * not filter out characters which have special meaning only at the
+ * start of a line, such as "*".
+ *
+ * @param string $text Text to be escaped
+ */
+function wfEscapeWikiText( $text ) {
+ $text = str_replace(
+ array( '[', '|', '\'', 'ISBN ', 'RFC ', '://', "\n=", '{{' ),
+ array( '&#91;', '&#124;', '&#39;', 'ISBN&#32;', 'RFC&#32;', '&#58;//', "\n&#61;", '&#123;&#123;' ),
+ htmlspecialchars($text) );
+ return $text;
+}
+
+/**
+ * @todo document
+ */
+function wfQuotedPrintable( $string, $charset = '' ) {
+ # Probably incomplete; see RFC 2045
+ if( empty( $charset ) ) {
+ global $wgInputEncoding;
+ $charset = $wgInputEncoding;
+ }
+ $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( "/([$replace])/e", 'sprintf("=%02X",ord("$1"))', $string );
+ $out .= '?=';
+ return $out;
+}
+
+
+/**
+ * @todo document
+ * @return float
+ */
+function wfTime() {
+ return microtime(true);
+}
+
+/**
+ * Sets dest to source and returns the original value of dest
+ * If source is NULL, it just returns the value, it doesn't set the variable
+ */
+function wfSetVar( &$dest, $source ) {
+ $temp = $dest;
+ if ( !is_null( $source ) ) {
+ $dest = $source;
+ }
+ return $temp;
+}
+
+/**
+ * As for wfSetVar except setting a bit
+ */
+function wfSetBit( &$dest, $bit, $state = true ) {
+ $temp = (bool)($dest & $bit );
+ if ( !is_null( $state ) ) {
+ if ( $state ) {
+ $dest |= $bit;
+ } else {
+ $dest &= ~$bit;
+ }
+ }
+ return $temp;
+}
+
+/**
+ * This function takes two arrays as input, and returns a CGI-style string, e.g.
+ * "days=7&limit=100". Options in the first array override options in the second.
+ * Options set to "" will not be output.
+ */
+function wfArrayToCGI( $array1, $array2 = NULL )
+{
+ if ( !is_null( $array2 ) ) {
+ $array1 = $array1 + $array2;
+ }
+
+ $cgi = '';
+ foreach ( $array1 as $key => $value ) {
+ if ( '' !== $value ) {
+ if ( '' != $cgi ) {
+ $cgi .= '&';
+ }
+ $cgi .= urlencode( $key ) . '=' . urlencode( $value );
+ }
+ }
+ return $cgi;
+}
+
+/**
+ * This is obsolete, use SquidUpdate::purge()
+ * @deprecated
+ */
+function wfPurgeSquidServers ($urlArr) {
+ SquidUpdate::purge( $urlArr );
+}
+
+/**
+ * Windows-compatible version of escapeshellarg()
+ * Windows doesn't recognise single-quotes in the shell, but the escapeshellarg()
+ * function puts single quotes in regardless of OS
+ */
+function wfEscapeShellArg( ) {
+ $args = func_get_args();
+ $first = true;
+ $retVal = '';
+ foreach ( $args as $arg ) {
+ if ( !$first ) {
+ $retVal .= ' ';
+ } else {
+ $first = false;
+ }
+
+ if ( wfIsWindows() ) {
+ // Escaping for an MSVC-style command line parser
+ // Ref: http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html
+ // Double the backslashes before any double quotes. Escape the double quotes.
+ $tokens = preg_split( '/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
+ $arg = '';
+ $delim = false;
+ foreach ( $tokens as $token ) {
+ if ( $delim ) {
+ $arg .= str_replace( '\\', '\\\\', substr( $token, 0, -1 ) ) . '\\"';
+ } else {
+ $arg .= $token;
+ }
+ $delim = !$delim;
+ }
+ // Double the backslashes before the end of the string, because
+ // we will soon add a quote
+ $m = array();
+ if ( preg_match( '/^(.*?)(\\\\+)$/', $arg, $m ) ) {
+ $arg = $m[1] . str_replace( '\\', '\\\\', $m[2] );
+ }
+
+ // Add surrounding quotes
+ $retVal .= '"' . $arg . '"';
+ } else {
+ $retVal .= escapeshellarg( $arg );
+ }
+ }
+ return $retVal;
+}
+
+/**
+ * wfMerge attempts to merge differences between three texts.
+ * Returns true for a clean merge and false for failure or a conflict.
+ */
+function wfMerge( $old, $mine, $yours, &$result ){
+ global $wgDiff3;
+
+ # This check may also protect against code injection in
+ # case of broken installations.
+ if(! file_exists( $wgDiff3 ) ){
+ wfDebug( "diff3 not found\n" );
+ return false;
+ }
+
+ # Make temporary files
+ $td = wfTempDir();
+ $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
+ $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
+ $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
+
+ fwrite( $oldtextFile, $old ); fclose( $oldtextFile );
+ fwrite( $mytextFile, $mine ); fclose( $mytextFile );
+ fwrite( $yourtextFile, $yours ); fclose( $yourtextFile );
+
+ # Check for a conflict
+ $cmd = $wgDiff3 . ' -a --overlap-only ' .
+ wfEscapeShellArg( $mytextName ) . ' ' .
+ wfEscapeShellArg( $oldtextName ) . ' ' .
+ wfEscapeShellArg( $yourtextName );
+ $handle = popen( $cmd, 'r' );
+
+ if( fgets( $handle, 1024 ) ){
+ $conflict = true;
+ } else {
+ $conflict = false;
+ }
+ pclose( $handle );
+
+ # Merge differences
+ $cmd = $wgDiff3 . ' -a -e --merge ' .
+ wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
+ $handle = popen( $cmd, 'r' );
+ $result = '';
+ do {
+ $data = fread( $handle, 8192 );
+ if ( strlen( $data ) == 0 ) {
+ break;
+ }
+ $result .= $data;
+ } while ( true );
+ pclose( $handle );
+ unlink( $mytextName ); unlink( $oldtextName ); unlink( $yourtextName );
+
+ if ( $result === '' && $old !== '' && $conflict == false ) {
+ wfDebug( "Unexpected null result from diff3. Command: $cmd\n" );
+ $conflict = true;
+ }
+ return ! $conflict;
+}
+
+/**
+ * @todo document
+ */
+function wfVarDump( $var ) {
+ global $wgOut;
+ $s = str_replace("\n","<br />\n", var_export( $var, true ) . "\n");
+ if ( headers_sent() || !@is_object( $wgOut ) ) {
+ print $s;
+ } else {
+ $wgOut->addHTML( $s );
+ }
+}
+
+/**
+ * Provide a simple HTTP error.
+ */
+function wfHttpError( $code, $label, $desc ) {
+ global $wgOut;
+ $wgOut->disable();
+ header( "HTTP/1.0 $code $label" );
+ header( "Status: $code $label" );
+ $wgOut->sendCacheControl();
+
+ header( 'Content-type: text/html; charset=utf-8' );
+ print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">".
+ "<html><head><title>" .
+ htmlspecialchars( $label ) .
+ "</title></head><body><h1>" .
+ htmlspecialchars( $label ) .
+ "</h1><p>" .
+ nl2br( htmlspecialchars( $desc ) ) .
+ "</p></body></html>\n";
+}
+
+/**
+ * Clear away any user-level output buffers, discarding contents.
+ *
+ * Suitable for 'starting afresh', for instance when streaming
+ * relatively large amounts of data without buffering, or wanting to
+ * output image files without ob_gzhandler's compression.
+ *
+ * The optional $resetGzipEncoding parameter controls suppression of
+ * the Content-Encoding header sent by ob_gzhandler; by default it
+ * is left. See comments for wfClearOutputBuffers() for why it would
+ * be used.
+ *
+ * Note that some PHP configuration options may add output buffer
+ * layers which cannot be removed; these are left in place.
+ *
+ * @parameter bool $resetGzipEncoding
+ */
+function wfResetOutputBuffers( $resetGzipEncoding=true ) {
+ while( $status = ob_get_status() ) {
+ if( $status['type'] == 0 /* PHP_OUTPUT_HANDLER_INTERNAL */ ) {
+ // Probably from zlib.output_compression or other
+ // PHP-internal setting which can't be removed.
+ //
+ // Give up, and hope the result doesn't break
+ // output behavior.
+ break;
+ }
+ if( !ob_end_clean() ) {
+ // Could not remove output buffer handler; abort now
+ // to avoid getting in some kind of infinite loop.
+ break;
+ }
+ if( $resetGzipEncoding ) {
+ if( $status['name'] == 'ob_gzhandler' ) {
+ // Reset the 'Content-Encoding' field set by this handler
+ // so we can start fresh.
+ header( 'Content-Encoding:' );
+ }
+ }
+ }
+}
+
+/**
+ * More legible than passing a 'false' parameter to wfResetOutputBuffers():
+ *
+ * Clear away output buffers, but keep the Content-Encoding header
+ * produced by ob_gzhandler, if any.
+ *
+ * This should be used for HTTP 304 responses, where you need to
+ * preserve the Content-Encoding header of the real result, but
+ * also need to suppress the output of ob_gzhandler to keep to spec
+ * and avoid breaking Firefox in rare cases where the headers and
+ * body are broken over two packets.
+ */
+function wfClearOutputBuffers() {
+ wfResetOutputBuffers( false );
+}
+
+/**
+ * Converts an Accept-* header into an array mapping string values to quality
+ * factors
+ */
+function wfAcceptToPrefs( $accept, $def = '*/*' ) {
+ # No arg means accept anything (per HTTP spec)
+ if( !$accept ) {
+ return array( $def => 1 );
+ }
+
+ $prefs = array();
+
+ $parts = explode( ',', $accept );
+
+ foreach( $parts as $part ) {
+ # FIXME: doesn't deal with params like 'text/html; level=1'
+ @list( $value, $qpart ) = explode( ';', $part );
+ $match = array();
+ if( !isset( $qpart ) ) {
+ $prefs[$value] = 1;
+ } elseif( preg_match( '/q\s*=\s*(\d*\.\d+)/', $qpart, $match ) ) {
+ $prefs[$value] = $match[1];
+ }
+ }
+
+ return $prefs;
+}
+
+/**
+ * Checks if a given MIME type matches any of the keys in the given
+ * array. Basic wildcards are accepted in the array keys.
+ *
+ * Returns the matching MIME type (or wildcard) if a match, otherwise
+ * NULL if no match.
+ *
+ * @param string $type
+ * @param array $avail
+ * @return string
+ * @private
+ */
+function mimeTypeMatch( $type, $avail ) {
+ if( array_key_exists($type, $avail) ) {
+ return $type;
+ } else {
+ $parts = explode( '/', $type );
+ if( array_key_exists( $parts[0] . '/*', $avail ) ) {
+ return $parts[0] . '/*';
+ } elseif( array_key_exists( '*/*', $avail ) ) {
+ return '*/*';
+ } else {
+ return NULL;
+ }
+ }
+}
+
+/**
+ * Returns the 'best' match between a client's requested internet media types
+ * and the server's list of available types. Each list should be an associative
+ * array of type to preference (preference is a float between 0.0 and 1.0).
+ * Wildcards in the types are acceptable.
+ *
+ * @param array $cprefs Client's acceptable type list
+ * @param array $sprefs Server's offered types
+ * @return string
+ *
+ * @todo FIXME: doesn't handle params like 'text/plain; charset=UTF-8'
+ * XXX: generalize to negotiate other stuff
+ */
+function wfNegotiateType( $cprefs, $sprefs ) {
+ $combine = array();
+
+ foreach( array_keys($sprefs) as $type ) {
+ $parts = explode( '/', $type );
+ if( $parts[1] != '*' ) {
+ $ckey = mimeTypeMatch( $type, $cprefs );
+ if( $ckey ) {
+ $combine[$type] = $sprefs[$type] * $cprefs[$ckey];
+ }
+ }
+ }
+
+ foreach( array_keys( $cprefs ) as $type ) {
+ $parts = explode( '/', $type );
+ if( $parts[1] != '*' && !array_key_exists( $type, $sprefs ) ) {
+ $skey = mimeTypeMatch( $type, $sprefs );
+ if( $skey ) {
+ $combine[$type] = $sprefs[$skey] * $cprefs[$type];
+ }
+ }
+ }
+
+ $bestq = 0;
+ $besttype = NULL;
+
+ foreach( array_keys( $combine ) as $type ) {
+ if( $combine[$type] > $bestq ) {
+ $besttype = $type;
+ $bestq = $combine[$type];
+ }
+ }
+
+ return $besttype;
+}
+
+/**
+ * Array lookup
+ * Returns an array where the values in the first array are replaced by the
+ * values in the second array with the corresponding keys
+ *
+ * @return array
+ */
+function wfArrayLookup( $a, $b ) {
+ return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) );
+}
+
+/**
+ * Convenience function; returns MediaWiki timestamp for the present time.
+ * @return string
+ */
+function wfTimestampNow() {
+ # return NOW
+ return wfTimestamp( TS_MW, time() );
+}
+
+/**
+ * Reference-counted warning suppression
+ */
+function wfSuppressWarnings( $end = false ) {
+ static $suppressCount = 0;
+ static $originalLevel = false;
+
+ if ( $end ) {
+ if ( $suppressCount ) {
+ --$suppressCount;
+ if ( !$suppressCount ) {
+ error_reporting( $originalLevel );
+ }
+ }
+ } else {
+ if ( !$suppressCount ) {
+ $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE ) );
+ }
+ ++$suppressCount;
+ }
+}
+
+/**
+ * Restore error level to previous value
+ */
+function wfRestoreWarnings() {
+ wfSuppressWarnings( true );
+}
+
+# Autodetect, convert and provide timestamps of various types
+
+/**
+ * Unix time - the number of seconds since 1970-01-01 00:00:00 UTC
+ */
+define('TS_UNIX', 0);
+
+/**
+ * MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
+ */
+define('TS_MW', 1);
+
+/**
+ * MySQL DATETIME (YYYY-MM-DD HH:MM:SS)
+ */
+define('TS_DB', 2);
+
+/**
+ * RFC 2822 format, for E-mail and HTTP headers
+ */
+define('TS_RFC2822', 3);
+
+/**
+ * ISO 8601 format with no timezone: 1986-02-09T20:00:00Z
+ *
+ * This is used by Special:Export
+ */
+define('TS_ISO_8601', 4);
+
+/**
+ * An Exif timestamp (YYYY:MM:DD HH:MM:SS)
+ *
+ * @url http://exif.org/Exif2-2.PDF The Exif 2.2 spec, see page 28 for the
+ * DateTime tag and page 36 for the DateTimeOriginal and
+ * DateTimeDigitized tags.
+ */
+define('TS_EXIF', 5);
+
+/**
+ * Oracle format time.
+ */
+define('TS_ORACLE', 6);
+
+/**
+ * Postgres format time.
+ */
+define('TS_POSTGRES', 7);
+
+/**
+ * @param mixed $outputtype A timestamp in one of the supported formats, the
+ * function will autodetect which format is supplied
+ * and act accordingly.
+ * @return string Time in the format specified in $outputtype
+ */
+function wfTimestamp($outputtype=TS_UNIX,$ts=0) {
+ $uts = 0;
+ $da = array();
+ if ($ts==0) {
+ $uts=time();
+ } elseif (preg_match('/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D',$ts,$da)) {
+ # TS_DB
+ $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
+ (int)$da[2],(int)$da[3],(int)$da[1]);
+ } elseif (preg_match('/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D',$ts,$da)) {
+ # TS_EXIF
+ $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
+ (int)$da[2],(int)$da[3],(int)$da[1]);
+ } elseif (preg_match('/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D',$ts,$da)) {
+ # TS_MW
+ $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
+ (int)$da[2],(int)$da[3],(int)$da[1]);
+ } elseif (preg_match('/^(\d{1,13})$/D',$ts,$da)) {
+ # TS_UNIX
+ $uts = $ts;
+ } elseif (preg_match('/^(\d{1,2})-(...)-(\d\d(\d\d)?) (\d\d)\.(\d\d)\.(\d\d)/', $ts, $da)) {
+ # TS_ORACLE
+ $uts = strtotime(preg_replace('/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
+ str_replace("+00:00", "UTC", $ts)));
+ } elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/', $ts, $da)) {
+ # TS_ISO_8601
+ $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
+ (int)$da[2],(int)$da[3],(int)$da[1]);
+ } elseif (preg_match('/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)[\+\- ](\d\d)$/',$ts,$da)) {
+ # TS_POSTGRES
+ $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
+ (int)$da[2],(int)$da[3],(int)$da[1]);
+ } elseif (preg_match('/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/',$ts,$da)) {
+ # TS_POSTGRES
+ $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
+ (int)$da[2],(int)$da[3],(int)$da[1]);
+ } else {
+ # Bogus value; fall back to the epoch...
+ wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n");
+ $uts = 0;
+ }
+
+
+ switch($outputtype) {
+ case TS_UNIX:
+ return $uts;
+ case TS_MW:
+ return gmdate( 'YmdHis', $uts );
+ case TS_DB:
+ return gmdate( 'Y-m-d H:i:s', $uts );
+ case TS_ISO_8601:
+ return gmdate( 'Y-m-d\TH:i:s\Z', $uts );
+ // This shouldn't ever be used, but is included for completeness
+ case TS_EXIF:
+ return gmdate( 'Y:m:d H:i:s', $uts );
+ case TS_RFC2822:
+ return gmdate( 'D, d M Y H:i:s', $uts ) . ' GMT';
+ case TS_ORACLE:
+ return gmdate( 'd-M-y h.i.s A', $uts) . ' +00:00';
+ case TS_POSTGRES:
+ return gmdate( 'Y-m-d H:i:s', $uts) . ' GMT';
+ default:
+ throw new MWException( 'wfTimestamp() called with illegal output type.');
+ }
+}
+
+/**
+ * Return a formatted timestamp, or null if input is null.
+ * For dealing with nullable timestamp columns in the database.
+ * @param int $outputtype
+ * @param string $ts
+ * @return string
+ */
+function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) {
+ if( is_null( $ts ) ) {
+ return null;
+ } else {
+ return wfTimestamp( $outputtype, $ts );
+ }
+}
+
+/**
+ * Check if the operating system is Windows
+ *
+ * @return bool True if it's Windows, False otherwise.
+ */
+function wfIsWindows() {
+ if (substr(php_uname(), 0, 7) == 'Windows') {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Swap two variables
+ */
+function swap( &$x, &$y ) {
+ $z = $x;
+ $x = $y;
+ $y = $z;
+}
+
+function wfGetCachedNotice( $name ) {
+ global $wgOut, $parserMemc;
+ $fname = 'wfGetCachedNotice';
+ wfProfileIn( $fname );
+
+ $needParse = false;
+
+ if( $name === 'default' ) {
+ // special case
+ global $wgSiteNotice;
+ $notice = $wgSiteNotice;
+ if( empty( $notice ) ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ } else {
+ $notice = wfMsgForContentNoTrans( $name );
+ if( wfEmptyMsg( $name, $notice ) || $notice == '-' ) {
+ wfProfileOut( $fname );
+ return( false );
+ }
+ }
+
+ $cachedNotice = $parserMemc->get( wfMemcKey( $name ) );
+ if( is_array( $cachedNotice ) ) {
+ if( md5( $notice ) == $cachedNotice['hash'] ) {
+ $notice = $cachedNotice['html'];
+ } else {
+ $needParse = true;
+ }
+ } else {
+ $needParse = true;
+ }
+
+ if( $needParse ) {
+ if( is_object( $wgOut ) ) {
+ $parsed = $wgOut->parse( $notice );
+ $parserMemc->set( wfMemcKey( $name ), array( 'html' => $parsed, 'hash' => md5( $notice ) ), 600 );
+ $notice = $parsed;
+ } else {
+ wfDebug( 'wfGetCachedNotice called for ' . $name . ' with no $wgOut available' );
+ $notice = '';
+ }
+ }
+
+ wfProfileOut( $fname );
+ return $notice;
+}
+
+function wfGetNamespaceNotice() {
+ global $wgTitle;
+
+ # Paranoia
+ if ( !isset( $wgTitle ) || !is_object( $wgTitle ) )
+ return "";
+
+ $fname = 'wfGetNamespaceNotice';
+ wfProfileIn( $fname );
+
+ $key = "namespacenotice-" . $wgTitle->getNsText();
+ $namespaceNotice = wfGetCachedNotice( $key );
+ if ( $namespaceNotice && substr ( $namespaceNotice , 0 ,7 ) != "<p>&lt;" ) {
+ $namespaceNotice = '<div id="namespacebanner">' . $namespaceNotice . "</div>";
+ } else {
+ $namespaceNotice = "";
+ }
+
+ wfProfileOut( $fname );
+ return $namespaceNotice;
+}
+
+function wfGetSiteNotice() {
+ global $wgUser, $wgSiteNotice;
+ $fname = 'wfGetSiteNotice';
+ wfProfileIn( $fname );
+ $siteNotice = '';
+
+ if( wfRunHooks( 'SiteNoticeBefore', array( &$siteNotice ) ) ) {
+ if( is_object( $wgUser ) && $wgUser->isLoggedIn() ) {
+ $siteNotice = wfGetCachedNotice( 'sitenotice' );
+ } else {
+ $anonNotice = wfGetCachedNotice( 'anonnotice' );
+ if( !$anonNotice ) {
+ $siteNotice = wfGetCachedNotice( 'sitenotice' );
+ } else {
+ $siteNotice = $anonNotice;
+ }
+ }
+ if( !$siteNotice ) {
+ $siteNotice = wfGetCachedNotice( 'default' );
+ }
+ }
+
+ wfRunHooks( 'SiteNoticeAfter', array( &$siteNotice ) );
+ wfProfileOut( $fname );
+ return $siteNotice;
+}
+
+/**
+ * BC wrapper for MimeMagic::singleton()
+ * @deprecated
+ */
+function &wfGetMimeMagic() {
+ return MimeMagic::singleton();
+}
+
+/**
+ * Tries to get the system directory for temporary files.
+ * The TMPDIR, TMP, and TEMP environment variables are checked in sequence,
+ * and if none are set /tmp is returned as the generic Unix default.
+ *
+ * NOTE: When possible, use the tempfile() function to create temporary
+ * files to avoid race conditions on file creation, etc.
+ *
+ * @return string
+ */
+function wfTempDir() {
+ foreach( array( 'TMPDIR', 'TMP', 'TEMP' ) as $var ) {
+ $tmp = getenv( $var );
+ if( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) {
+ return $tmp;
+ }
+ }
+ # Hope this is Unix of some kind!
+ return '/tmp';
+}
+
+/**
+ * Make directory, and make all parent directories if they don't exist
+ */
+function wfMkdirParents( $fullDir, $mode = 0777 ) {
+ if ( strval( $fullDir ) === '' ) {
+ return true;
+ }
+
+ # Go back through the paths to find the first directory that exists
+ $currentDir = $fullDir;
+ $createList = array();
+ while ( strval( $currentDir ) !== '' && !file_exists( $currentDir ) ) {
+ # Strip trailing slashes
+ $currentDir = rtrim( $currentDir, '/\\' );
+
+ # Add to create list
+ $createList[] = $currentDir;
+
+ # Find next delimiter searching from the end
+ $p = max( strrpos( $currentDir, '/' ), strrpos( $currentDir, '\\' ) );
+ if ( $p === false ) {
+ $currentDir = false;
+ } else {
+ $currentDir = substr( $currentDir, 0, $p );
+ }
+ }
+
+ if ( count( $createList ) == 0 ) {
+ # Directory specified already exists
+ return true;
+ } elseif ( $currentDir === false ) {
+ # Went all the way back to root and it apparently doesn't exist
+ return false;
+ }
+
+ # Now go forward creating directories
+ $createList = array_reverse( $createList );
+ foreach ( $createList as $dir ) {
+ # use chmod to override the umask, as suggested by the PHP manual
+ if ( !mkdir( $dir, $mode ) || !chmod( $dir, $mode ) ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * Increment a statistics counter
+ */
+ function wfIncrStats( $key ) {
+ global $wgMemc;
+ $key = wfMemcKey( 'stats', $key );
+ if ( is_null( $wgMemc->incr( $key ) ) ) {
+ $wgMemc->add( $key, 1 );
+ }
+ }
+
+/**
+ * @param mixed $nr The number to format
+ * @param int $acc The number of digits after the decimal point, default 2
+ * @param bool $round Whether or not to round the value, default true
+ * @return float
+ */
+function wfPercent( $nr, $acc = 2, $round = true ) {
+ $ret = sprintf( "%.${acc}f", $nr );
+ return $round ? round( $ret, $acc ) . '%' : "$ret%";
+}
+
+/**
+ * Encrypt a username/password.
+ *
+ * @param string $userid ID of the user
+ * @param string $password Password of the user
+ * @return string Hashed password
+ */
+function wfEncryptPassword( $userid, $password ) {
+ global $wgPasswordSalt;
+ $p = md5( $password);
+
+ if($wgPasswordSalt)
+ return md5( "{$userid}-{$p}" );
+ else
+ return $p;
+}
+
+/**
+ * Appends to second array if $value differs from that in $default
+ */
+function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) {
+ if ( is_null( $changed ) ) {
+ throw new MWException('GlobalFunctions::wfAppendToArrayIfNotDefault got null');
+ }
+ if ( $default[$key] !== $value ) {
+ $changed[$key] = $value;
+ }
+}
+
+/**
+ * Since wfMsg() and co suck, they don't return false if the message key they
+ * looked up didn't exist but a XHTML string, this function checks for the
+ * nonexistance of messages by looking at wfMsg() output
+ *
+ * @param $msg The message key looked up
+ * @param $wfMsgOut The output of wfMsg*()
+ * @return bool
+ */
+function wfEmptyMsg( $msg, $wfMsgOut ) {
+ return $wfMsgOut === "&lt;$msg&gt;";
+}
+
+/**
+ * Find out whether or not a mixed variable exists in a string
+ *
+ * @param mixed needle
+ * @param string haystack
+ * @return bool
+ */
+function in_string( $needle, $str ) {
+ return strpos( $str, $needle ) !== false;
+}
+
+function wfSpecialList( $page, $details ) {
+ global $wgContLang;
+ $details = $details ? ' ' . $wgContLang->getDirMark() . "($details)" : "";
+ return $page . $details;
+}
+
+/**
+ * Returns a regular expression of url protocols
+ *
+ * @return string
+ */
+function wfUrlProtocols() {
+ global $wgUrlProtocols;
+
+ // Support old-style $wgUrlProtocols strings, for backwards compatibility
+ // with LocalSettings files from 1.5
+ if ( is_array( $wgUrlProtocols ) ) {
+ $protocols = array();
+ foreach ($wgUrlProtocols as $protocol)
+ $protocols[] = preg_quote( $protocol, '/' );
+
+ return implode( '|', $protocols );
+ } else {
+ return $wgUrlProtocols;
+ }
+}
+
+/**
+ * Execute a shell command, with time and memory limits mirrored from the PHP
+ * configuration if supported.
+ * @param $cmd Command line, properly escaped for shell.
+ * @param &$retval optional, will receive the program's exit code.
+ * (non-zero is usually failure)
+ * @return collected stdout as a string (trailing newlines stripped)
+ */
+function wfShellExec( $cmd, &$retval=null ) {
+ global $IP, $wgMaxShellMemory, $wgMaxShellFileSize;
+
+ if( ini_get( 'safe_mode' ) ) {
+ wfDebug( "wfShellExec can't run in safe_mode, PHP's exec functions are too broken.\n" );
+ $retval = 1;
+ return "Unable to run external programs in safe mode.";
+ }
+
+ if ( php_uname( 's' ) == 'Linux' ) {
+ $time = ini_get( 'max_execution_time' );
+ $mem = intval( $wgMaxShellMemory );
+ $filesize = intval( $wgMaxShellFileSize );
+
+ if ( $time > 0 && $mem > 0 ) {
+ $script = "$IP/bin/ulimit-tvf.sh";
+ if ( is_executable( $script ) ) {
+ $cmd = escapeshellarg( $script ) . " $time $mem $filesize $cmd";
+ }
+ }
+ } elseif ( php_uname( 's' ) == 'Windows NT' ) {
+ # This is a hack to work around PHP's flawed invocation of cmd.exe
+ # http://news.php.net/php.internals/21796
+ $cmd = '"' . $cmd . '"';
+ }
+ wfDebug( "wfShellExec: $cmd\n" );
+
+ $output = array();
+ $retval = 1; // error by default?
+ exec( $cmd, $output, $retval ); // returns the last line of output.
+ return implode( "\n", $output );
+
+}
+
+/**
+ * This function works like "use VERSION" in Perl, the program will die with a
+ * backtrace if the current version of PHP is less than the version provided
+ *
+ * This is useful for extensions which due to their nature are not kept in sync
+ * with releases, and might depend on other versions of PHP than the main code
+ *
+ * Note: PHP might die due to parsing errors in some cases before it ever
+ * manages to call this function, such is life
+ *
+ * @see perldoc -f use
+ *
+ * @param mixed $version The version to check, can be a string, an integer, or
+ * a float
+ */
+function wfUsePHP( $req_ver ) {
+ $php_ver = PHP_VERSION;
+
+ if ( version_compare( $php_ver, (string)$req_ver, '<' ) )
+ throw new MWException( "PHP $req_ver required--this is only $php_ver" );
+}
+
+/**
+ * This function works like "use VERSION" in Perl except it checks the version
+ * of MediaWiki, the program will die with a backtrace if the current version
+ * of MediaWiki is less than the version provided.
+ *
+ * This is useful for extensions which due to their nature are not kept in sync
+ * with releases
+ *
+ * @see perldoc -f use
+ *
+ * @param mixed $version The version to check, can be a string, an integer, or
+ * a float
+ */
+function wfUseMW( $req_ver ) {
+ global $wgVersion;
+
+ if ( version_compare( $wgVersion, (string)$req_ver, '<' ) )
+ throw new MWException( "MediaWiki $req_ver required--this is only $wgVersion" );
+}
+
+/**
+ * @deprecated use StringUtils::escapeRegexReplacement
+ */
+function wfRegexReplacement( $string ) {
+ return StringUtils::escapeRegexReplacement( $string );
+}
+
+/**
+ * Return the final portion of a pathname.
+ * Reimplemented because PHP5's basename() is buggy with multibyte text.
+ * http://bugs.php.net/bug.php?id=33898
+ *
+ * PHP's basename() only considers '\' a pathchar on Windows and Netware.
+ * We'll consider it so always, as we don't want \s in our Unix paths either.
+ *
+ * @param string $path
+ * @return string
+ */
+function wfBaseName( $path ) {
+ $matches = array();
+ if( preg_match( '#([^/\\\\]*)[/\\\\]*$#', $path, $matches ) ) {
+ return $matches[1];
+ } else {
+ return '';
+ }
+}
+
+/**
+ * Make a URL index, appropriate for the el_index field of externallinks.
+ */
+function wfMakeUrlIndex( $url ) {
+ wfSuppressWarnings();
+ $bits = parse_url( $url );
+ wfRestoreWarnings();
+ if ( !$bits || $bits['scheme'] !== 'http' ) {
+ return false;
+ }
+ // Reverse the labels in the hostname, convert to lower case
+ $reversedHost = strtolower( implode( '.', array_reverse( explode( '.', $bits['host'] ) ) ) );
+ // Add an extra dot to the end
+ if ( substr( $reversedHost, -1, 1 ) !== '.' ) {
+ $reversedHost .= '.';
+ }
+ // Reconstruct the pseudo-URL
+ $index = "http://$reversedHost";
+ // Leave out user and password. Add the port, path, query and fragment
+ if ( isset( $bits['port'] ) ) $index .= ':' . $bits['port'];
+ if ( isset( $bits['path'] ) ) {
+ $index .= $bits['path'];
+ } else {
+ $index .= '/';
+ }
+ if ( isset( $bits['query'] ) ) $index .= '?' . $bits['query'];
+ if ( isset( $bits['fragment'] ) ) $index .= '#' . $bits['fragment'];
+ return $index;
+}
+
+/**
+ * Do any deferred updates and clear the list
+ * TODO: This could be in Wiki.php if that class made any sense at all
+ */
+function wfDoUpdates()
+{
+ global $wgPostCommitUpdateList, $wgDeferredUpdateList;
+ foreach ( $wgDeferredUpdateList as $update ) {
+ $update->doUpdate();
+ }
+ foreach ( $wgPostCommitUpdateList as $update ) {
+ $update->doUpdate();
+ }
+ $wgDeferredUpdateList = array();
+ $wgPostCommitUpdateList = array();
+}
+
+/**
+ * @deprecated use StringUtils::explodeMarkup
+ */
+function wfExplodeMarkup( $separator, $text ) {
+ return StringUtils::explodeMarkup( $separator, $text );
+}
+
+/**
+ * Convert an arbitrarily-long digit string from one numeric base
+ * to another, optionally zero-padding to a minimum column width.
+ *
+ * Supports base 2 through 36; digit values 10-36 are represented
+ * as lowercase letters a-z. Input is case-insensitive.
+ *
+ * @param $input string of digits
+ * @param $sourceBase int 2-36
+ * @param $destBase int 2-36
+ * @param $pad int 1 or greater
+ * @return string or false on invalid input
+ */
+function wfBaseConvert( $input, $sourceBase, $destBase, $pad=1 ) {
+ if( $sourceBase < 2 ||
+ $sourceBase > 36 ||
+ $destBase < 2 ||
+ $destBase > 36 ||
+ $pad < 1 ||
+ $sourceBase != intval( $sourceBase ) ||
+ $destBase != intval( $destBase ) ||
+ $pad != intval( $pad ) ||
+ !is_string( $input ) ||
+ $input == '' ) {
+ return false;
+ }
+
+ $digitChars = '0123456789abcdefghijklmnopqrstuvwxyz';
+ $inDigits = array();
+ $outChars = '';
+
+ // Decode and validate input string
+ $input = strtolower( $input );
+ for( $i = 0; $i < strlen( $input ); $i++ ) {
+ $n = strpos( $digitChars, $input{$i} );
+ if( $n === false || $n > $sourceBase ) {
+ return false;
+ }
+ $inDigits[] = $n;
+ }
+
+ // Iterate over the input, modulo-ing out an output digit
+ // at a time until input is gone.
+ while( count( $inDigits ) ) {
+ $work = 0;
+ $workDigits = array();
+
+ // Long division...
+ foreach( $inDigits as $digit ) {
+ $work *= $sourceBase;
+ $work += $digit;
+
+ if( $work < $destBase ) {
+ // Gonna need to pull another digit.
+ if( count( $workDigits ) ) {
+ // Avoid zero-padding; this lets us find
+ // the end of the input very easily when
+ // length drops to zero.
+ $workDigits[] = 0;
+ }
+ } else {
+ // Finally! Actual division!
+ $workDigits[] = intval( $work / $destBase );
+
+ // Isn't it annoying that most programming languages
+ // don't have a single divide-and-remainder operator,
+ // even though the CPU implements it that way?
+ $work = $work % $destBase;
+ }
+ }
+
+ // All that division leaves us with a remainder,
+ // which is conveniently our next output digit.
+ $outChars .= $digitChars[$work];
+
+ // And we continue!
+ $inDigits = $workDigits;
+ }
+
+ while( strlen( $outChars ) < $pad ) {
+ $outChars .= '0';
+ }
+
+ return strrev( $outChars );
+}
+
+/**
+ * Create an object with a given name and an array of construct parameters
+ * @param string $name
+ * @param array $p parameters
+ */
+function wfCreateObject( $name, $p ){
+ $p = array_values( $p );
+ switch ( count( $p ) ) {
+ case 0:
+ return new $name;
+ case 1:
+ return new $name( $p[0] );
+ case 2:
+ return new $name( $p[0], $p[1] );
+ case 3:
+ return new $name( $p[0], $p[1], $p[2] );
+ case 4:
+ return new $name( $p[0], $p[1], $p[2], $p[3] );
+ case 5:
+ return new $name( $p[0], $p[1], $p[2], $p[3], $p[4] );
+ case 6:
+ return new $name( $p[0], $p[1], $p[2], $p[3], $p[4], $p[5] );
+ default:
+ throw new MWException( "Too many arguments to construtor in wfCreateObject" );
+ }
+}
+
+/**
+ * Aliases for modularized functions
+ */
+function wfGetHTTP( $url, $timeout = 'default' ) {
+ return Http::get( $url, $timeout );
+}
+function wfIsLocalURL( $url ) {
+ return Http::isLocalURL( $url );
+}
+
+/**
+ * Initialise php session
+ */
+function wfSetupSession() {
+ global $wgSessionsInMemcached, $wgCookiePath, $wgCookieDomain;
+ if( $wgSessionsInMemcached ) {
+ require_once( 'MemcachedSessions.php' );
+ } elseif( 'files' != ini_get( 'session.save_handler' ) ) {
+ # If it's left on 'user' or another setting from another
+ # application, it will end up failing. Try to recover.
+ ini_set ( 'session.save_handler', 'files' );
+ }
+ session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain );
+ session_cache_limiter( 'private, must-revalidate' );
+ @session_start();
+}
+
+/**
+ * Get an object from the precompiled serialized directory
+ *
+ * @return mixed The variable on success, false on failure
+ */
+function wfGetPrecompiledData( $name ) {
+ global $IP;
+
+ $file = "$IP/serialized/$name";
+ if ( file_exists( $file ) ) {
+ $blob = file_get_contents( $file );
+ if ( $blob ) {
+ return unserialize( $blob );
+ }
+ }
+ return false;
+}
+
+function wfGetCaller( $level = 2 ) {
+ $backtrace = wfDebugBacktrace();
+ if ( isset( $backtrace[$level] ) ) {
+ if ( isset( $backtrace[$level]['class'] ) ) {
+ $caller = $backtrace[$level]['class'] . '::' . $backtrace[$level]['function'];
+ } else {
+ $caller = $backtrace[$level]['function'];
+ }
+ } else {
+ $caller = 'unknown';
+ }
+ return $caller;
+}
+
+/** Return a string consisting all callers in stack, somewhat useful sometimes for profiling specific points */
+function wfGetAllCallers() {
+ return implode('/', array_map(
+ create_function('$frame','
+ return isset( $frame["class"] )?
+ $frame["class"]."::".$frame["function"]:
+ $frame["function"];
+ '),
+ array_reverse(wfDebugBacktrace())));
+}
+
+/**
+ * Get a cache key
+ */
+function wfMemcKey( /*... */ ) {
+ global $wgDBprefix, $wgDBname;
+ $args = func_get_args();
+ if ( $wgDBprefix ) {
+ $key = "$wgDBname-$wgDBprefix:" . implode( ':', $args );
+ } else {
+ $key = $wgDBname . ':' . implode( ':', $args );
+ }
+ return $key;
+}
+
+/**
+ * Get a cache key for a foreign DB
+ */
+function wfForeignMemcKey( $db, $prefix /*, ... */ ) {
+ $args = array_slice( func_get_args(), 2 );
+ if ( $prefix ) {
+ $key = "$db-$prefix:" . implode( ':', $args );
+ } else {
+ $key = $db . ':' . implode( ':', $args );
+ }
+ return $key;
+}
+
+/**
+ * Get an ASCII string identifying this wiki
+ * This is used as a prefix in memcached keys
+ */
+function wfWikiID() {
+ global $wgDBprefix, $wgDBname;
+ if ( $wgDBprefix ) {
+ return "$wgDBname-$wgDBprefix";
+ } else {
+ return $wgDBname;
+ }
+}
+
+/*
+ * Get a Database object
+ * @param integer $db Index of the connection to get. May be DB_MASTER for the
+ * master (for write queries), DB_SLAVE for potentially lagged
+ * read queries, or an integer >= 0 for a particular server.
+ *
+ * @param mixed $groups Query groups. An array of group names that this query
+ * belongs to. May contain a single string if the query is only
+ * in one group.
+ */
+function &wfGetDB( $db = DB_LAST, $groups = array() ) {
+ global $wgLoadBalancer;
+ $ret = $wgLoadBalancer->getConnection( $db, true, $groups );
+ return $ret;
+}
+?>
diff --git a/includes/HTMLCacheUpdate.php b/includes/HTMLCacheUpdate.php
new file mode 100644
index 000000000000..bda4720d06c5
--- /dev/null
+++ b/includes/HTMLCacheUpdate.php
@@ -0,0 +1,229 @@
+<?php
+
+/**
+ * Class to invalidate the HTML cache of all the pages linking to a given title.
+ * Small numbers of links will be done immediately, large numbers are pushed onto
+ * the job queue.
+ *
+ * This class is designed to work efficiently with small numbers of links, and
+ * to work reasonably well with up to ~10^5 links. Above ~10^6 links, the memory
+ * and time requirements of loading all backlinked IDs in doUpdate() might become
+ * prohibitive. The requirements measured at Wikimedia are approximately:
+ *
+ * memory: 48 bytes per row
+ * time: 16us per row for the query plus processing
+ *
+ * The reason this query is done is to support partitioning of the job
+ * by backlinked ID. The memory issue could be allieviated by doing this query in
+ * batches, but of course LIMIT with an offset is inefficient on the DB side.
+ *
+ * The class is nevertheless a vast improvement on the previous method of using
+ * Image::getLinksTo() and Title::touchArray(), which uses about 2KB of memory per
+ * link.
+ */
+class HTMLCacheUpdate
+{
+ public $mTitle, $mTable, $mPrefix;
+ public $mRowsPerJob, $mRowsPerQuery;
+
+ function __construct( $titleTo, $table ) {
+ global $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery;
+
+ $this->mTitle = $titleTo;
+ $this->mTable = $table;
+ $this->mRowsPerJob = $wgUpdateRowsPerJob;
+ $this->mRowsPerQuery = $wgUpdateRowsPerQuery;
+ }
+
+ function doUpdate() {
+ # Fetch the IDs
+ $cond = $this->getToCondition();
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( $this->mTable, $this->getFromField(), $cond, __METHOD__ );
+ $resWrap = new ResultWrapper( $dbr, $res );
+ if ( $dbr->numRows( $res ) != 0 ) {
+ if ( $dbr->numRows( $res ) > $this->mRowsPerJob ) {
+ $this->insertJobs( $resWrap );
+ } else {
+ $this->invalidateIDs( $resWrap );
+ }
+ }
+ $dbr->freeResult( $res );
+ }
+
+ function insertJobs( ResultWrapper $res ) {
+ $numRows = $res->numRows();
+ $numBatches = ceil( $numRows / $this->mRowsPerJob );
+ $realBatchSize = $numRows / $numBatches;
+ $start = false;
+ $jobs = array();
+ do {
+ for ( $i = 0; $i < $realBatchSize - 1; $i++ ) {
+ $row = $res->fetchRow();
+ if ( $row ) {
+ $id = $row[0];
+ } else {
+ $id = false;
+ break;
+ }
+ }
+ if ( $id !== false ) {
+ // One less on the end to avoid duplicating the boundary
+ $job = new HTMLCacheUpdateJob( $this->mTitle, $this->mTable, $start, $id - 1 );
+ } else {
+ $job = new HTMLCacheUpdateJob( $this->mTitle, $this->mTable, $start, false );
+ }
+ $jobs[] = $job;
+
+ $start = $id;
+ } while ( $start );
+
+ Job::batchInsert( $jobs );
+ }
+
+ function getPrefix() {
+ static $prefixes = array(
+ 'pagelinks' => 'pl',
+ 'imagelinks' => 'il',
+ 'categorylinks' => 'cl',
+ 'templatelinks' => 'tl',
+
+ # Not needed
+ # 'externallinks' => 'el',
+ # 'langlinks' => 'll'
+ );
+
+ if ( is_null( $this->mPrefix ) ) {
+ $this->mPrefix = $prefixes[$this->mTable];
+ if ( is_null( $this->mPrefix ) ) {
+ throw new MWException( "Invalid table type \"{$this->mTable}\" in " . __CLASS__ );
+ }
+ }
+ return $this->mPrefix;
+ }
+
+ function getFromField() {
+ return $this->getPrefix() . '_from';
+ }
+
+ function getToCondition() {
+ switch ( $this->mTable ) {
+ case 'pagelinks':
+ return array(
+ 'pl_namespace' => $this->mTitle->getNamespace(),
+ 'pl_title' => $this->mTitle->getDBkey()
+ );
+ case 'templatelinks':
+ return array(
+ 'tl_namespace' => $this->mTitle->getNamespace(),
+ 'tl_title' => $this->mTitle->getDBkey()
+ );
+ case 'imagelinks':
+ return array( 'il_to' => $this->mTitle->getDBkey() );
+ case 'categorylinks':
+ return array( 'cl_to' => $this->mTitle->getDBkey() );
+ }
+ throw new MWException( 'Invalid table type in ' . __CLASS__ );
+ }
+
+ /**
+ * Invalidate a set of IDs, right now
+ */
+ function invalidateIDs( ResultWrapper $res ) {
+ global $wgUseFileCache, $wgUseSquid;
+
+ if ( $res->numRows() == 0 ) {
+ return;
+ }
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $timestamp = $dbw->timestamp();
+ $done = false;
+
+ while ( !$done ) {
+ # Get all IDs in this query into an array
+ $ids = array();
+ for ( $i = 0; $i < $this->mRowsPerQuery; $i++ ) {
+ $row = $res->fetchRow();
+ if ( $row ) {
+ $ids[] = $row[0];
+ } else {
+ $done = true;
+ break;
+ }
+ }
+
+ if ( !count( $ids ) ) {
+ break;
+ }
+
+ # Update page_touched
+ $dbw->update( 'page',
+ array( 'page_touched' => $timestamp ),
+ array( 'page_id IN (' . $dbw->makeList( $ids ) . ')' ),
+ __METHOD__
+ );
+
+ # Update squid
+ if ( $wgUseSquid || $wgUseFileCache ) {
+ $titles = Title::newFromIDs( $ids );
+ if ( $wgUseSquid ) {
+ $u = SquidUpdate::newFromTitles( $titles );
+ $u->doUpdate();
+ }
+
+ # Update file cache
+ if ( $wgUseFileCache ) {
+ foreach ( $titles as $title ) {
+ $cm = new HTMLFileCache($title);
+ @unlink($cm->fileCacheName());
+ }
+ }
+ }
+ }
+ }
+}
+
+class HTMLCacheUpdateJob extends Job {
+ var $table, $start, $end;
+
+ /**
+ * Construct a job
+ * @param Title $title The title linked to
+ * @param string $table The name of the link table.
+ * @param integer $start Beginning page_id or false for open interval
+ * @param integer $end End page_id or false for open interval
+ * @param integer $id job_id
+ */
+ function __construct( $title, $table, $start, $end, $id = 0 ) {
+ $params = array(
+ 'table' => $table,
+ 'start' => $start,
+ 'end' => $end );
+ parent::__construct( 'htmlCacheUpdate', $title, $params, $id );
+ $this->table = $table;
+ $this->start = intval( $start );
+ $this->end = intval( $end );
+ }
+
+ function run() {
+ $update = new HTMLCacheUpdate( $this->title, $this->table );
+
+ $fromField = $update->getFromField();
+ $conds = $update->getToCondition();
+ if ( $this->start ) {
+ $conds[] = "$fromField >= {$this->start}";
+ }
+ if ( $this->end ) {
+ $conds[] = "$fromField <= {$this->end}";
+ }
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( $this->table, $fromField, $conds, __METHOD__ );
+ $update->invalidateIDs( new ResultWrapper( $dbr, $res ) );
+ $dbr->freeResult( $res );
+
+ return true;
+ }
+}
+?>
diff --git a/includes/HTMLFileCache.php b/includes/HTMLFileCache.php
new file mode 100644
index 000000000000..d85a44110614
--- /dev/null
+++ b/includes/HTMLFileCache.php
@@ -0,0 +1,159 @@
+<?php
+/**
+ * Contain the HTMLFileCache class
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+
+/**
+ * Handles talking to the file cache, putting stuff in and taking it back out.
+ * Mostly called from Article.php, also from DatabaseFunctions.php for the
+ * emergency abort/fallback to cache.
+ *
+ * Global options that affect this module:
+ * $wgCachePages
+ * $wgCacheEpoch
+ * $wgUseFileCache
+ * $wgFileCacheDirectory
+ * $wgUseGzip
+ * @package MediaWiki
+ */
+class HTMLFileCache {
+ var $mTitle, $mFileCache;
+
+ function HTMLFileCache( &$title ) {
+ $this->mTitle =& $title;
+ $this->mFileCache = '';
+ }
+
+ function fileCacheName() {
+ global $wgFileCacheDirectory;
+ if( !$this->mFileCache ) {
+ $key = $this->mTitle->getPrefixedDbkey();
+ $hash = md5( $key );
+ $key = str_replace( '.', '%2E', urlencode( $key ) );
+
+ $hash1 = substr( $hash, 0, 1 );
+ $hash2 = substr( $hash, 0, 2 );
+ $this->mFileCache = "{$wgFileCacheDirectory}/{$hash1}/{$hash2}/{$key}.html";
+
+ if($this->useGzip())
+ $this->mFileCache .= '.gz';
+
+ wfDebug( " fileCacheName() - {$this->mFileCache}\n" );
+ }
+ return $this->mFileCache;
+ }
+
+ function isFileCached() {
+ return file_exists( $this->fileCacheName() );
+ }
+
+ function fileCacheTime() {
+ return wfTimestamp( TS_MW, filemtime( $this->fileCacheName() ) );
+ }
+
+ function isFileCacheGood( $timestamp ) {
+ global $wgCacheEpoch;
+
+ if( !$this->isFileCached() ) return false;
+
+ $cachetime = $this->fileCacheTime();
+ $good = (( $timestamp <= $cachetime ) &&
+ ( $wgCacheEpoch <= $cachetime ));
+
+ wfDebug(" isFileCacheGood() - cachetime $cachetime, touched {$timestamp} epoch {$wgCacheEpoch}, good $good\n");
+ return $good;
+ }
+
+ function useGzip() {
+ global $wgUseGzip;
+ return $wgUseGzip;
+ }
+
+ /* In handy string packages */
+ function fetchRawText() {
+ return file_get_contents( $this->fileCacheName() );
+ }
+
+ function fetchPageText() {
+ if( $this->useGzip() ) {
+ /* Why is there no gzfile_get_contents() or gzdecode()? */
+ return implode( '', gzfile( $this->fileCacheName() ) );
+ } else {
+ return $this->fetchRawText();
+ }
+ }
+
+ /* Working directory to/from output */
+ function loadFromFileCache() {
+ global $wgOut, $wgMimeType, $wgOutputEncoding, $wgContLanguageCode;
+ wfDebug(" loadFromFileCache()\n");
+
+ $filename=$this->fileCacheName();
+ $wgOut->sendCacheControl();
+
+ header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" );
+ header( "Content-language: $wgContLanguageCode" );
+
+ if( $this->useGzip() ) {
+ if( wfClientAcceptsGzip() ) {
+ header( 'Content-Encoding: gzip' );
+ } else {
+ /* Send uncompressed */
+ readgzfile( $filename );
+ return;
+ }
+ }
+ readfile( $filename );
+ }
+
+ function checkCacheDirs() {
+ $filename = $this->fileCacheName();
+ $mydir2=substr($filename,0,strrpos($filename,'/')); # subdirectory level 2
+ $mydir1=substr($mydir2,0,strrpos($mydir2,'/')); # subdirectory level 1
+
+ if(!file_exists($mydir1)) { mkdir($mydir1,0775); } # create if necessary
+ if(!file_exists($mydir2)) { mkdir($mydir2,0775); }
+ }
+
+ function saveToFileCache( $origtext ) {
+ $text = $origtext;
+ if(strcmp($text,'') == 0) return '';
+
+ wfDebug(" saveToFileCache()\n", false);
+
+ $this->checkCacheDirs();
+
+ $f = fopen( $this->fileCacheName(), 'w' );
+ if($f) {
+ $now = wfTimestampNow();
+ if( $this->useGzip() ) {
+ $rawtext = str_replace( '</html>',
+ '<!-- Cached/compressed '.$now." -->\n</html>",
+ $text );
+ $text = gzencode( $rawtext );
+ } else {
+ $text = str_replace( '</html>',
+ '<!-- Cached '.$now." -->\n</html>",
+ $text );
+ }
+ fwrite( $f, $text );
+ fclose( $f );
+ if( $this->useGzip() ) {
+ if( wfClientAcceptsGzip() ) {
+ header( 'Content-Encoding: gzip' );
+ return $text;
+ } else {
+ return $rawtext;
+ }
+ } else {
+ return $text;
+ }
+ }
+ return $text;
+ }
+
+}
+
+?>
diff --git a/includes/HTMLForm.php b/includes/HTMLForm.php
new file mode 100644
index 000000000000..189e5c7956ae
--- /dev/null
+++ b/includes/HTMLForm.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * This file contain a class to easily build HTML forms as well as custom
+ * functions used by SpecialUserrights.php
+ * @package MediaWiki
+ */
+
+/**
+ * Class to build various forms
+ *
+ * @package MediaWiki
+ * @author jeluf, hashar
+ */
+class HTMLForm {
+ /** name of our form. Used as prefix for labels */
+ var $mName, $mRequest;
+
+ function HTMLForm( &$request ) {
+ $this->mRequest = $request;
+ }
+
+ /**
+ * @private
+ * @param $name String: name of the fieldset.
+ * @param $content String: HTML content to put in.
+ * @return string HTML fieldset
+ */
+ function fieldset( $name, $content ) {
+ return "<fieldset><legend>".wfMsg($this->mName.'-'.$name)."</legend>\n" .
+ $content . "\n</fieldset>\n";
+ }
+
+ /**
+ * @private
+ * @param $varname String: name of the checkbox.
+ * @param $checked Boolean: set true to check the box (default False).
+ */
+ function checkbox( $varname, $checked=false ) {
+ if ( $this->mRequest->wasPosted() && !is_null( $this->mRequest->getVal( $varname ) ) ) {
+ $checked = $this->mRequest->getCheck( $varname );
+ }
+ return "<div><input type='checkbox' value=\"1\" id=\"{$varname}\" name=\"wpOp{$varname}\"" .
+ ( $checked ? ' checked="checked"' : '' ) .
+ " /><label for=\"{$varname}\">". wfMsg( $this->mName.'-'.$varname ) .
+ "</label></div>\n";
+ }
+
+ /**
+ * @private
+ * @param $varname String: name of the textbox.
+ * @param $value String: optional value (default empty)
+ * @param $size Integer: optional size of the textbox (default 20)
+ */
+ function textbox( $varname, $value='', $size=20 ) {
+ if ( $this->mRequest->wasPosted() ) {
+ $value = $this->mRequest->getText( $varname, $value );
+ }
+ $value = htmlspecialchars( $value );
+ return "<div><label>". wfMsg( $this->mName.'-'.$varname ) .
+ "<input type='text' name=\"{$varname}\" value=\"{$value}\" size=\"{$size}\" /></label></div>\n";
+ }
+
+ /**
+ * @private
+ * @param $varname String: name of the radiobox.
+ * @param $fields Array: Various fields.
+ */
+ function radiobox( $varname, $fields ) {
+ foreach ( $fields as $value => $checked ) {
+ $s .= "<div><label><input type='radio' name=\"{$varname}\" value=\"{$value}\"" .
+ ( $checked ? ' checked="checked"' : '' ) . " />" . wfMsg( $this->mName.'-'.$varname.'-'.$value ) .
+ "</label></div>\n";
+ }
+ return $this->fieldset( $varname, $s );
+ }
+
+ /**
+ * @private
+ * @param $varname String: name of the textareabox.
+ * @param $value String: optional value (default empty)
+ * @param $size Integer: optional size of the textarea (default 20)
+ */
+ function textareabox ( $varname, $value='', $size=20 ) {
+ if ( $this->mRequest->wasPosted() ) {
+ $value = $this->mRequest->getText( $varname, $value );
+ }
+ $value = htmlspecialchars( $value );
+ return '<div><label>'.wfMsg( $this->mName.'-'.$varname ).
+ "<textarea name=\"{$varname}\" rows=\"5\" cols=\"{$size}\">$value</textarea></label></div>\n";
+ }
+
+ /**
+ * @private
+ * @param $varname String: name of the arraybox.
+ * @param $size Integer: Optional size of the textarea (default 20)
+ */
+ function arraybox( $varname , $size=20 ) {
+ $s = '';
+ if ( $this->mRequest->wasPosted() ) {
+ $arr = $this->mRequest->getArray( $varname );
+ if ( is_array( $arr ) ) {
+ foreach ( $_POST[$varname] as $element ) {
+ $s .= htmlspecialchars( $element )."\n";
+ }
+ }
+ }
+ return "<div><label>".wfMsg( $this->mName.'-'.$varname ).
+ "<textarea name=\"{$varname}\" rows=\"5\" cols=\"{$size}\">{$s}</textarea>\n";
+ }
+} // end class
+
+/** Build a select with all defined groups
+ *
+ * used by SpecialUserrights.php
+ * @todo move it to there, and don't forget to copy it for SpecialMakesysop.php
+ *
+ * @param $selectname String: name of this element. Name of form is automaticly prefixed.
+ * @param $selectmsg String: FIXME
+ * @param $selected Array: array of element selected when posted. Only multiples will show them.
+ * @param $multiple Boolean: A multiple elements select.
+ * @param $size Integer: number of elements to be shown ignored for non-multiple (default 6).
+ * @param $reverse Boolean: if true, multiple select will hide selected elements (default false).
+ * @todo Document $selectmsg
+*/
+function HTMLSelectGroups($selectname, $selectmsg, $selected=array(), $multiple=false, $size=6, $reverse=false) {
+ $groups = User::getAllGroups();
+ $out = htmlspecialchars( wfMsg( $selectmsg ) );
+
+ if( $multiple ) {
+ $attribs = array(
+ 'name' => $selectname . '[]',
+ 'multiple'=> 'multiple',
+ 'size' => $size );
+ } else {
+ $attribs = array( 'name' => $selectname );
+ }
+ $out .= wfElement( 'select', $attribs, null );
+
+ foreach( $groups as $group ) {
+ $attribs = array( 'value' => $group );
+ if( $multiple ) {
+ // for multiple will only show the things we want
+ if( !in_array( $group, $selected ) xor $reverse ) {
+ continue;
+ }
+ } else {
+ if( in_array( $group, $selected ) ) {
+ $attribs['selected'] = 'selected';
+ }
+ }
+ $out .= wfElement( 'option', $attribs, User::getGroupName( $group ) ) . "\n";
+ }
+
+ $out .= "</select>\n";
+ return $out;
+}
+
+?>
diff --git a/includes/HistoryBlob.php b/includes/HistoryBlob.php
new file mode 100644
index 000000000000..a06b620d5ac5
--- /dev/null
+++ b/includes/HistoryBlob.php
@@ -0,0 +1,307 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Pure virtual parent
+ * @package MediaWiki
+ */
+class HistoryBlob
+{
+ /**
+ * setMeta and getMeta currently aren't used for anything, I just thought
+ * they might be useful in the future.
+ * @param $meta String: a single string.
+ */
+ function setMeta( $meta ) {}
+
+ /**
+ * setMeta and getMeta currently aren't used for anything, I just thought
+ * they might be useful in the future.
+ * Gets the meta-value
+ */
+ function getMeta() {}
+
+ /**
+ * Adds an item of text, returns a stub object which points to the item.
+ * You must call setLocation() on the stub object before storing it to the
+ * database
+ */
+ function addItem() {}
+
+ /**
+ * Get item by hash
+ */
+ function getItem( $hash ) {}
+
+ # Set the "default text"
+ # This concept is an odd property of the current DB schema, whereby each text item has a revision
+ # associated with it. The default text is the text of the associated revision. There may, however,
+ # be other revisions in the same object
+ function setText() {}
+
+ /**
+ * Get default text. This is called from Revision::getRevisionText()
+ */
+ function getText() {}
+}
+
+/**
+ * The real object
+ * @package MediaWiki
+ */
+class ConcatenatedGzipHistoryBlob extends HistoryBlob
+{
+ /* private */ var $mVersion = 0, $mCompressed = false, $mItems = array(), $mDefaultHash = '';
+ /* private */ var $mFast = 0, $mSize = 0;
+
+ function ConcatenatedGzipHistoryBlob() {
+ if ( !function_exists( 'gzdeflate' ) ) {
+ throw new MWException( "Need zlib support to read or write this kind of history object (ConcatenatedGzipHistoryBlob)\n" );
+ }
+ }
+
+ /** @todo document */
+ function setMeta( $metaData ) {
+ $this->uncompress();
+ $this->mItems['meta'] = $metaData;
+ }
+
+ /** @todo document */
+ function getMeta() {
+ $this->uncompress();
+ return $this->mItems['meta'];
+ }
+
+ /** @todo document */
+ function addItem( $text ) {
+ $this->uncompress();
+ $hash = md5( $text );
+ $this->mItems[$hash] = $text;
+ $this->mSize += strlen( $text );
+
+ $stub = new HistoryBlobStub( $hash );
+ return $stub;
+ }
+
+ /** @todo document */
+ function getItem( $hash ) {
+ $this->uncompress();
+ if ( array_key_exists( $hash, $this->mItems ) ) {
+ return $this->mItems[$hash];
+ } else {
+ return false;
+ }
+ }
+
+ /** @todo document */
+ function removeItem( $hash ) {
+ $this->mSize -= strlen( $this->mItems[$hash] );
+ unset( $this->mItems[$hash] );
+ }
+
+ /** @todo document */
+ function compress() {
+ if ( !$this->mCompressed ) {
+ $this->mItems = gzdeflate( serialize( $this->mItems ) );
+ $this->mCompressed = true;
+ }
+ }
+
+ /** @todo document */
+ function uncompress() {
+ if ( $this->mCompressed ) {
+ $this->mItems = unserialize( gzinflate( $this->mItems ) );
+ $this->mCompressed = false;
+ }
+ }
+
+ /** @todo document */
+ function getText() {
+ $this->uncompress();
+ return $this->getItem( $this->mDefaultHash );
+ }
+
+ /** @todo document */
+ function setText( $text ) {
+ $this->uncompress();
+ $stub = $this->addItem( $text );
+ $this->mDefaultHash = $stub->mHash;
+ }
+
+ /** @todo document */
+ function __sleep() {
+ $this->compress();
+ return array( 'mVersion', 'mCompressed', 'mItems', 'mDefaultHash' );
+ }
+
+ /** @todo document */
+ function __wakeup() {
+ $this->uncompress();
+ }
+
+ /**
+ * Determines if this object is happy
+ */
+ function isHappy( $maxFactor, $factorThreshold ) {
+ if ( count( $this->mItems ) == 0 ) {
+ return true;
+ }
+ if ( !$this->mFast ) {
+ $this->uncompress();
+ $record = serialize( $this->mItems );
+ $size = strlen( $record );
+ $avgUncompressed = $size / count( $this->mItems );
+ $compressed = strlen( gzdeflate( $record ) );
+
+ if ( $compressed < $factorThreshold * 1024 ) {
+ return true;
+ } else {
+ return $avgUncompressed * $maxFactor < $compressed;
+ }
+ } else {
+ return count( $this->mItems ) <= 10;
+ }
+ }
+}
+
+
+/**
+ * One-step cache variable to hold base blobs; operations that
+ * pull multiple revisions may often pull multiple times from
+ * the same blob. By keeping the last-used one open, we avoid
+ * redundant unserialization and decompression overhead.
+ */
+global $wgBlobCache;
+$wgBlobCache = array();
+
+
+/**
+ * @package MediaWiki
+ */
+class HistoryBlobStub {
+ var $mOldId, $mHash, $mRef;
+
+ /** @todo document */
+ function HistoryBlobStub( $hash = '', $oldid = 0 ) {
+ $this->mHash = $hash;
+ }
+
+ /**
+ * Sets the location (old_id) of the main object to which this object
+ * points
+ */
+ function setLocation( $id ) {
+ $this->mOldId = $id;
+ }
+
+ /**
+ * Sets the location (old_id) of the referring object
+ */
+ function setReferrer( $id ) {
+ $this->mRef = $id;
+ }
+
+ /**
+ * Gets the location of the referring object
+ */
+ function getReferrer() {
+ return $this->mRef;
+ }
+
+ /** @todo document */
+ function getText() {
+ $fname = 'HistoryBlob::getText';
+ global $wgBlobCache;
+ if( isset( $wgBlobCache[$this->mOldId] ) ) {
+ $obj = $wgBlobCache[$this->mOldId];
+ } else {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow( 'text', array( 'old_flags', 'old_text' ), array( 'old_id' => $this->mOldId ) );
+ if( !$row ) {
+ return false;
+ }
+ $flags = explode( ',', $row->old_flags );
+ if( in_array( 'external', $flags ) ) {
+ $url=$row->old_text;
+ @list( /* $proto */ ,$path)=explode('://',$url,2);
+ if ($path=="") {
+ wfProfileOut( $fname );
+ return false;
+ }
+ $row->old_text=ExternalStore::fetchFromUrl($url);
+
+ }
+ if( !in_array( 'object', $flags ) ) {
+ return false;
+ }
+
+ if( in_array( 'gzip', $flags ) ) {
+ // This shouldn't happen, but a bug in the compress script
+ // may at times gzip-compress a HistoryBlob object row.
+ $obj = unserialize( gzinflate( $row->old_text ) );
+ } else {
+ $obj = unserialize( $row->old_text );
+ }
+
+ if( !is_object( $obj ) ) {
+ // Correct for old double-serialization bug.
+ $obj = unserialize( $obj );
+ }
+
+ // Save this item for reference; if pulling many
+ // items in a row we'll likely use it again.
+ $obj->uncompress();
+ $wgBlobCache = array( $this->mOldId => $obj );
+ }
+ return $obj->getItem( $this->mHash );
+ }
+
+ /** @todo document */
+ function getHash() {
+ return $this->mHash;
+ }
+}
+
+
+/**
+ * To speed up conversion from 1.4 to 1.5 schema, text rows can refer to the
+ * leftover cur table as the backend. This avoids expensively copying hundreds
+ * of megabytes of data during the conversion downtime.
+ *
+ * Serialized HistoryBlobCurStub objects will be inserted into the text table
+ * on conversion if $wgFastSchemaUpgrades is set to true.
+ *
+ * @package MediaWiki
+ */
+class HistoryBlobCurStub {
+ var $mCurId;
+
+ /** @todo document */
+ function HistoryBlobCurStub( $curid = 0 ) {
+ $this->mCurId = $curid;
+ }
+
+ /**
+ * Sets the location (cur_id) of the main object to which this object
+ * points
+ */
+ function setLocation( $id ) {
+ $this->mCurId = $id;
+ }
+
+ /** @todo document */
+ function getText() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow( 'cur', array( 'cur_text' ), array( 'cur_id' => $this->mCurId ) );
+ if( !$row ) {
+ return false;
+ }
+ return $row->cur_text;
+ }
+}
+
+
+?>
diff --git a/includes/Hooks.php b/includes/Hooks.php
new file mode 100644
index 000000000000..2eecfd72f2e8
--- /dev/null
+++ b/includes/Hooks.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Hooks.php -- a tool for running hook functions
+ * Copyright 2004, 2005 Evan Prodromou <evan@wikitravel.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
+ *
+ * @author Evan Prodromou <evan@wikitravel.org>
+ * @package MediaWiki
+ * @see hooks.txt
+ */
+
+
+/**
+ * Because programmers assign to $wgHooks, we need to be very
+ * careful about its contents. So, there's a lot more error-checking
+ * in here than would normally be necessary.
+ */
+function wfRunHooks($event, $args = null) {
+
+ global $wgHooks;
+
+ if (!is_array($wgHooks)) {
+ throw new MWException("Global hooks array is not an array!\n");
+ return false;
+ }
+
+ if (!array_key_exists($event, $wgHooks)) {
+ return true;
+ }
+
+ if (!is_array($wgHooks[$event])) {
+ throw new MWException("Hooks array for event '$event' is not an array!\n");
+ return false;
+ }
+
+ foreach ($wgHooks[$event] as $index => $hook) {
+
+ $object = NULL;
+ $method = NULL;
+ $func = NULL;
+ $data = NULL;
+ $have_data = false;
+
+ /* $hook can be: a function, an object, an array of $function and $data,
+ * an array of just a function, an array of object and method, or an
+ * array of object, method, and data.
+ */
+
+ if (is_array($hook)) {
+ if (count($hook) < 1) {
+ throw new MWException("Empty array in hooks for " . $event . "\n");
+ } else if (is_object($hook[0])) {
+ $object = $wgHooks[$event][$index][0];
+ if (count($hook) < 2) {
+ $method = "on" . $event;
+ } else {
+ $method = $hook[1];
+ if (count($hook) > 2) {
+ $data = $hook[2];
+ $have_data = true;
+ }
+ }
+ } else if (is_string($hook[0])) {
+ $func = $hook[0];
+ if (count($hook) > 1) {
+ $data = $hook[1];
+ $have_data = true;
+ }
+ } else {
+ var_dump( $wgHooks );
+ throw new MWException("Unknown datatype in hooks for " . $event . "\n");
+ }
+ } else if (is_string($hook)) { # functions look like strings, too
+ $func = $hook;
+ } else if (is_object($hook)) {
+ $object = $wgHooks[$event][$index];
+ $method = "on" . $event;
+ } else {
+ throw new MWException("Unknown datatype in hooks for " . $event . "\n");
+ }
+
+ /* We put the first data element on, if needed. */
+
+ if ($have_data) {
+ $hook_args = array_merge(array($data), $args);
+ } else {
+ $hook_args = $args;
+ }
+
+ if ( isset( $object ) ) {
+ $func = get_class( $object ) . '::' . $method;
+ $callback = array( $object, $method );
+ } elseif ( false !== ( $pos = strpos( '::', $func ) ) ) {
+ $callback = array( substr( $func, 0, $pos ), substr( $func, $pos + 2 ) );
+ } else {
+ $callback = $func;
+ }
+
+ /* Call the hook. */
+ wfProfileIn( $func );
+ $retval = call_user_func_array( $callback, $hook_args );
+ wfProfileOut( $func );
+
+ /* String return is an error; false return means stop processing. */
+
+ if (is_string($retval)) {
+ global $wgOut;
+ $wgOut->showFatalError($retval);
+ return false;
+ } else if (!$retval) {
+ return false;
+ }
+ }
+
+ return true;
+}
+?>
diff --git a/includes/HttpFunctions.php b/includes/HttpFunctions.php
new file mode 100644
index 000000000000..a9fb13cae913
--- /dev/null
+++ b/includes/HttpFunctions.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * Various HTTP related functions
+ */
+class Http {
+ /**
+ * Get the contents of a file by HTTP
+ *
+ * if $timeout is 'default', $wgHTTPTimeout is used
+ */
+ static function get( $url, $timeout = 'default' ) {
+ global $wgHTTPTimeout, $wgHTTPProxy, $wgVersion, $wgTitle;
+
+ # Use curl if available
+ if ( function_exists( 'curl_init' ) ) {
+ $c = curl_init( $url );
+ if ( wfIsLocalURL( $url ) ) {
+ curl_setopt( $c, CURLOPT_PROXY, 'localhost:80' );
+ } else if ($wgHTTPProxy) {
+ curl_setopt($c, CURLOPT_PROXY, $wgHTTPProxy);
+ }
+
+ if ( $timeout == 'default' ) {
+ $timeout = $wgHTTPTimeout;
+ }
+ curl_setopt( $c, CURLOPT_TIMEOUT, $timeout );
+ curl_setopt( $c, CURLOPT_USERAGENT, "MediaWiki/$wgVersion" );
+
+ # Set the referer to $wgTitle, even in command-line mode
+ # This is useful for interwiki transclusion, where the foreign
+ # server wants to know what the referring page is.
+ # $_SERVER['REQUEST_URI'] gives a less reliable indication of the
+ # referring page.
+ if ( is_object( $wgTitle ) ) {
+ curl_setopt( $c, CURLOPT_REFERER, $wgTitle->getFullURL() );
+ }
+
+ ob_start();
+ curl_exec( $c );
+ $text = ob_get_contents();
+ ob_end_clean();
+
+ # Don't return the text of error messages, return false on error
+ if ( curl_getinfo( $c, CURLINFO_HTTP_CODE ) != 200 ) {
+ $text = false;
+ }
+ curl_close( $c );
+ } else {
+ # Otherwise use file_get_contents, or its compatibility function from GlobalFunctions.php
+ # This may take 3 minutes to time out, and doesn't have local fetch capabilities
+ $url_fopen = ini_set( 'allow_url_fopen', 1 );
+ $text = file_get_contents( $url );
+ ini_set( 'allow_url_fopen', $url_fopen );
+ }
+ return $text;
+ }
+
+ /**
+ * Check if the URL can be served by localhost
+ */
+ static function isLocalURL( $url ) {
+ global $wgCommandLineMode, $wgConf;
+ if ( $wgCommandLineMode ) {
+ return false;
+ }
+
+ // Extract host part
+ $matches = array();
+ if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) {
+ $host = $matches[1];
+ // Split up dotwise
+ $domainParts = explode( '.', $host );
+ // Check if this domain or any superdomain is listed in $wgConf as a local virtual host
+ $domainParts = array_reverse( $domainParts );
+ for ( $i = 0; $i < count( $domainParts ); $i++ ) {
+ $domainPart = $domainParts[$i];
+ if ( $i == 0 ) {
+ $domain = $domainPart;
+ } else {
+ $domain = $domainPart . '.' . $domain;
+ }
+ if ( $wgConf->isLocalVHost( $domain ) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
+?>
diff --git a/includes/IP.php b/includes/IP.php
new file mode 100644
index 000000000000..edf4af7a6fd5
--- /dev/null
+++ b/includes/IP.php
@@ -0,0 +1,260 @@
+<?php
+/*
+ * Collection of public static functions to play with IP address
+ * and IP blocks.
+ *
+ * @Author "Ashar Voultoiz" <hashar@altern.org>
+ * @License GPL v2 or later
+ */
+
+// Some regex definition to "play" with IP address and IP address blocks
+
+// An IP is made of 4 bytes from x00 to xFF which is d0 to d255
+define( 'RE_IP_BYTE', '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])');
+define( 'RE_IP_ADD' , RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE );
+// An IP block is an IP address and a prefix (d1 to d32)
+define( 'RE_IP_PREFIX', '(3[0-2]|[12]?\d)');
+define( 'RE_IP_BLOCK', RE_IP_ADD . '\/' . RE_IP_PREFIX);
+// For IPv6 canonicalization (NOT for strict validation; these are quite lax!)
+define( 'RE_IPV6_WORD', '([0-9A-Fa-f]{1,4})' );
+define( 'RE_IPV6_GAP', ':(?:0+:)*(?::(?:0+:)*)?' );
+define( 'RE_IPV6_V4_PREFIX', '0*' . RE_IPV6_GAP . '(?:ffff:)?' );
+
+class IP {
+
+ /**
+ * Validate an IP address.
+ * @return boolean True if it is valid.
+ */
+ public static function isValid( $ip ) {
+ return preg_match( '/^' . RE_IP_ADD . '$/', $ip) ;
+ }
+
+ /**
+ * Validate an IP Block.
+ * @return boolean True if it is valid.
+ */
+ public static function isValidBlock( $ipblock ) {
+ return ( count(self::toArray($ipblock)) == 1 + 5 );
+ }
+
+ /**
+ * Determine if an IP address really is an IP address, and if it is public,
+ * i.e. not RFC 1918 or similar
+ * Comes from ProxyTools.php
+ */
+ public static function isPublic( $ip ) {
+ $n = IP::toUnsigned( $ip );
+ if ( !$n ) {
+ return false;
+ }
+
+ // ip2long accepts incomplete addresses, as well as some addresses
+ // followed by garbage characters. Check that it's really valid.
+ if( $ip != long2ip( $n ) ) {
+ return false;
+ }
+
+ static $privateRanges = false;
+ if ( !$privateRanges ) {
+ $privateRanges = array(
+ array( '10.0.0.0', '10.255.255.255' ), # RFC 1918 (private)
+ array( '172.16.0.0', '172.31.255.255' ), # "
+ array( '192.168.0.0', '192.168.255.255' ), # "
+ array( '0.0.0.0', '0.255.255.255' ), # this network
+ array( '127.0.0.0', '127.255.255.255' ), # loopback
+ );
+ }
+
+ foreach ( $privateRanges as $r ) {
+ $start = IP::toUnsigned( $r[0] );
+ $end = IP::toUnsigned( $r[1] );
+ if ( $n >= $start && $n <= $end ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Split out an IP block as an array of 4 bytes and a mask,
+ * return false if it can't be determined
+ *
+ * @parameter $ip string A quad dotted IP address
+ * @return array
+ */
+ public static function toArray( $ipblock ) {
+ $matches = array();
+ if(! preg_match( '/^' . RE_IP_ADD . '(?:\/(?:'.RE_IP_PREFIX.'))?' . '$/', $ipblock, $matches ) ) {
+ return false;
+ } else {
+ return $matches;
+ }
+ }
+
+ /**
+ * Return a zero-padded hexadecimal representation of an IP address.
+ *
+ * Hexadecimal addresses are used because they can easily be extended to
+ * IPv6 support. To separate the ranges, the return value from this
+ * function for an IPv6 address will be prefixed with "v6-", a non-
+ * hexadecimal string which sorts after the IPv4 addresses.
+ *
+ * @param $ip Quad dotted IP address.
+ */
+ public static function toHex( $ip ) {
+ $n = self::toUnsigned( $ip );
+ if ( $n !== false ) {
+ $n = sprintf( '%08X', $n );
+ }
+ return $n;
+ }
+
+ /**
+ * Given an IP address in dotted-quad notation, returns an unsigned integer.
+ * Like ip2long() except that it actually works and has a consistent error return value.
+ * Comes from ProxyTools.php
+ * @param $ip Quad dotted IP address.
+ */
+ public static function toUnsigned( $ip ) {
+ if ( $ip == '255.255.255.255' ) {
+ $n = -1;
+ } else {
+ $n = ip2long( $ip );
+ if ( $n == -1 || $n === false ) { # Return value on error depends on PHP version
+ $n = false;
+ }
+ }
+ if ( $n < 0 ) {
+ $n += pow( 2, 32 );
+ }
+ return $n;
+ }
+
+ /**
+ * Convert a dotted-quad IP to a signed integer
+ * Returns false on failure
+ */
+ public static function toSigned( $ip ) {
+ if ( $ip == '255.255.255.255' ) {
+ $n = -1;
+ } else {
+ $n = ip2long( $ip );
+ if ( $n == -1 ) {
+ $n = false;
+ }
+ }
+ return $n;
+ }
+
+ /**
+ * Convert a network specification in CIDR notation to an integer network and a number of bits
+ */
+ public static function parseCIDR( $range ) {
+ $parts = explode( '/', $range, 2 );
+ if ( count( $parts ) != 2 ) {
+ return array( false, false );
+ }
+ $network = IP::toSigned( $parts[0] );
+ if ( $network !== false && is_numeric( $parts[1] ) && $parts[1] >= 0 && $parts[1] <= 32 ) {
+ $bits = $parts[1];
+ if ( $bits == 0 ) {
+ $network = 0;
+ } else {
+ $network &= ~((1 << (32 - $bits)) - 1);
+ }
+ # Convert to unsigned
+ if ( $network < 0 ) {
+ $network += pow( 2, 32 );
+ }
+ } else {
+ $network = false;
+ $bits = false;
+ }
+ return array( $network, $bits );
+ }
+
+ /**
+ * Given a string range in a number of formats, return the start and end of
+ * the range in hexadecimal.
+ *
+ * Formats are:
+ * 1.2.3.4/24 CIDR
+ * 1.2.3.4 - 1.2.3.5 Explicit range
+ * 1.2.3.4 Single IP
+ */
+ public static function parseRange( $range ) {
+ if ( strpos( $range, '/' ) !== false ) {
+ # CIDR
+ list( $network, $bits ) = IP::parseCIDR( $range );
+ if ( $network === false ) {
+ $start = $end = false;
+ } else {
+ $start = sprintf( '%08X', $network );
+ $end = sprintf( '%08X', $network + pow( 2, (32 - $bits) ) - 1 );
+ }
+ } elseif ( strpos( $range, '-' ) !== false ) {
+ # Explicit range
+ list( $start, $end ) = array_map( 'trim', explode( '-', $range, 2 ) );
+ if ( $start > $end ) {
+ $start = $end = false;
+ } else {
+ $start = IP::toHex( $start );
+ $end = IP::toHex( $end );
+ }
+ } else {
+ # Single IP
+ $start = $end = IP::toHex( $range );
+ }
+ if ( $start === false || $end === false ) {
+ return array( false, false );
+ } else {
+ return array( $start, $end );
+ }
+ }
+
+ /**
+ * Determine if a given integer IPv4 address is in a given CIDR network
+ * @param $addr The address to check against the given range.
+ * @param $range The range to check the given address against.
+ * @return bool Whether or not the given address is in the given range.
+ */
+ public static function isInRange( $addr, $range ) {
+ $unsignedIP = IP::toUnsigned($addr);
+ list( $start, $end ) = IP::parseRange($range);
+
+ $start = hexdec($start);
+ $end = hexdec($end);
+
+ return (($unsignedIP >= $start) && ($unsignedIP <= $end));
+ }
+
+ /**
+ * Convert some unusual representations of IPv4 addresses to their
+ * canonical dotted quad representation.
+ *
+ * This currently only checks a few IPV4-to-IPv6 related cases. More
+ * unusual representations may be added later.
+ *
+ * @param $addr something that might be an IP address
+ * @return valid dotted quad IPv4 address or null
+ */
+ public static function canonicalize( $addr ) {
+ if ( IP::isValid( $addr ) )
+ return $addr;
+
+ // IPv6 loopback address
+ if ( preg_match( '/^0*' . RE_IPV6_GAP . '1$/', $addr, $m ) )
+ return '127.0.0.1';
+
+ // IPv4-mapped and IPv4-compatible IPv6 addresses
+ if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . '(' . RE_IP_ADD . ')$/i', $addr, $m ) )
+ return $m[1];
+ if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD . ':' . RE_IPV6_WORD . '$/i', $addr, $m ) )
+ return long2ip( ( hexdec( $m[1] ) << 16 ) + hexdec( $m[2] ) );
+
+ return null; // give up
+ }
+}
+
+?>
diff --git a/includes/Image.php b/includes/Image.php
new file mode 100644
index 000000000000..7a6442c36cd5
--- /dev/null
+++ b/includes/Image.php
@@ -0,0 +1,2373 @@
+<?php
+/**
+ * @package MediaWiki
+ */
+
+/**
+ * NOTE FOR WINDOWS USERS:
+ * To enable EXIF functions, add the folloing lines to the
+ * "Windows extensions" section of php.ini:
+ *
+ * extension=extensions/php_mbstring.dll
+ * extension=extensions/php_exif.dll
+ */
+
+/**
+ * Bump this number when serialized cache records may be incompatible.
+ */
+define( 'MW_IMAGE_VERSION', 1 );
+
+/**
+ * Class to represent an image
+ *
+ * Provides methods to retrieve paths (physical, logical, URL),
+ * to generate thumbnails or for uploading.
+ * @package MediaWiki
+ */
+class Image
+{
+ /**#@+
+ * @private
+ */
+ var $name, # name of the image (constructor)
+ $imagePath, # Path of the image (loadFromXxx)
+ $url, # Image URL (accessor)
+ $title, # Title object for this image (constructor)
+ $fileExists, # does the image file exist on disk? (loadFromXxx)
+ $fromSharedDirectory, # load this image from $wgSharedUploadDirectory (loadFromXxx)
+ $historyLine, # Number of line to return by nextHistoryLine() (constructor)
+ $historyRes, # result of the query for the image's history (nextHistoryLine)
+ $width, # \
+ $height, # |
+ $bits, # --- returned by getimagesize (loadFromXxx)
+ $attr, # /
+ $type, # MEDIATYPE_xxx (bitmap, drawing, audio...)
+ $mime, # MIME type, determined by MimeMagic::guessMimeType
+ $size, # Size in bytes (loadFromXxx)
+ $metadata, # Metadata
+ $dataLoaded, # Whether or not all this has been loaded from the database (loadFromXxx)
+ $page, # Page to render when creating thumbnails
+ $lastError; # Error string associated with a thumbnail display error
+
+
+ /**#@-*/
+
+ /**
+ * Create an Image object from an image name
+ *
+ * @param string $name name of the image, used to create a title object using Title::makeTitleSafe
+ * @public
+ */
+ public static function newFromName( $name ) {
+ $title = Title::makeTitleSafe( NS_IMAGE, $name );
+ if ( is_object( $title ) ) {
+ return new Image( $title );
+ } else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Obsolete factory function, use constructor
+ * @deprecated
+ */
+ function newFromTitle( $title ) {
+ return new Image( $title );
+ }
+
+ function Image( $title ) {
+ if( !is_object( $title ) ) {
+ throw new MWException( 'Image constructor given bogus title.' );
+ }
+ $this->title =& $title;
+ $this->name = $title->getDBkey();
+ $this->metadata = serialize ( array() ) ;
+
+ $n = strrpos( $this->name, '.' );
+ $this->extension = Image::normalizeExtension( $n ?
+ substr( $this->name, $n + 1 ) : '' );
+ $this->historyLine = 0;
+ $this->page = 1;
+
+ $this->dataLoaded = false;
+ }
+
+
+ /**
+ * Normalize a file extension to the common form, and ensure it's clean.
+ * Extensions with non-alphanumeric characters will be discarded.
+ *
+ * @param $ext string (without the .)
+ * @return string
+ */
+ static function normalizeExtension( $ext ) {
+ $lower = strtolower( $ext );
+ $squish = array(
+ 'htm' => 'html',
+ 'jpeg' => 'jpg',
+ 'mpeg' => 'mpg',
+ 'tiff' => 'tif' );
+ if( isset( $squish[$lower] ) ) {
+ return $squish[$lower];
+ } elseif( preg_match( '/^[0-9a-z]+$/', $lower ) ) {
+ return $lower;
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Get the memcached keys
+ * Returns an array, first element is the local cache key, second is the shared cache key, if there is one
+ */
+ function getCacheKeys( ) {
+ global $wgUseSharedUploads, $wgSharedUploadDBname, $wgCacheSharedUploads;
+
+ $hashedName = md5($this->name);
+ $keys = array( wfMemcKey( 'Image', $hashedName ) );
+ if ( $wgUseSharedUploads && $wgSharedUploadDBname && $wgCacheSharedUploads ) {
+ $keys[] = wfForeignMemcKey( $wgSharedUploadDBname, false, 'Image', $hashedName );
+ }
+ return $keys;
+ }
+
+ /**
+ * Try to load image metadata from memcached. Returns true on success.
+ */
+ function loadFromCache() {
+ global $wgUseSharedUploads, $wgMemc;
+ wfProfileIn( __METHOD__ );
+ $this->dataLoaded = false;
+ $keys = $this->getCacheKeys();
+ $cachedValues = $wgMemc->get( $keys[0] );
+
+ // Check if the key existed and belongs to this version of MediaWiki
+ if (!empty($cachedValues) && is_array($cachedValues)
+ && isset($cachedValues['version']) && ( $cachedValues['version'] == MW_IMAGE_VERSION )
+ && isset( $cachedValues['mime'] ) && isset( $cachedValues['metadata'] ) )
+ {
+ if ( $wgUseSharedUploads && $cachedValues['fromShared']) {
+ # if this is shared file, we need to check if image
+ # in shared repository has not changed
+ if ( isset( $keys[1] ) ) {
+ $commonsCachedValues = $wgMemc->get( $keys[1] );
+ if (!empty($commonsCachedValues) && is_array($commonsCachedValues)
+ && isset($commonsCachedValues['version'])
+ && ( $commonsCachedValues['version'] == MW_IMAGE_VERSION )
+ && isset($commonsCachedValues['mime'])) {
+ wfDebug( "Pulling image metadata from shared repository cache\n" );
+ $this->name = $commonsCachedValues['name'];
+ $this->imagePath = $commonsCachedValues['imagePath'];
+ $this->fileExists = $commonsCachedValues['fileExists'];
+ $this->width = $commonsCachedValues['width'];
+ $this->height = $commonsCachedValues['height'];
+ $this->bits = $commonsCachedValues['bits'];
+ $this->type = $commonsCachedValues['type'];
+ $this->mime = $commonsCachedValues['mime'];
+ $this->metadata = $commonsCachedValues['metadata'];
+ $this->size = $commonsCachedValues['size'];
+ $this->fromSharedDirectory = true;
+ $this->dataLoaded = true;
+ $this->imagePath = $this->getFullPath(true);
+ }
+ }
+ } else {
+ wfDebug( "Pulling image metadata from local cache\n" );
+ $this->name = $cachedValues['name'];
+ $this->imagePath = $cachedValues['imagePath'];
+ $this->fileExists = $cachedValues['fileExists'];
+ $this->width = $cachedValues['width'];
+ $this->height = $cachedValues['height'];
+ $this->bits = $cachedValues['bits'];
+ $this->type = $cachedValues['type'];
+ $this->mime = $cachedValues['mime'];
+ $this->metadata = $cachedValues['metadata'];
+ $this->size = $cachedValues['size'];
+ $this->fromSharedDirectory = false;
+ $this->dataLoaded = true;
+ $this->imagePath = $this->getFullPath();
+ }
+ }
+ if ( $this->dataLoaded ) {
+ wfIncrStats( 'image_cache_hit' );
+ } else {
+ wfIncrStats( 'image_cache_miss' );
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $this->dataLoaded;
+ }
+
+ /**
+ * Save the image metadata to memcached
+ */
+ function saveToCache() {
+ global $wgMemc, $wgUseSharedUploads;
+ $this->load();
+ $keys = $this->getCacheKeys();
+ // We can't cache negative metadata for non-existent files,
+ // because if the file later appears in commons, the local
+ // keys won't be purged.
+ if ( $this->fileExists || !$wgUseSharedUploads ) {
+ $cachedValues = array(
+ 'version' => MW_IMAGE_VERSION,
+ 'name' => $this->name,
+ 'imagePath' => $this->imagePath,
+ 'fileExists' => $this->fileExists,
+ 'fromShared' => $this->fromSharedDirectory,
+ 'width' => $this->width,
+ 'height' => $this->height,
+ 'bits' => $this->bits,
+ 'type' => $this->type,
+ 'mime' => $this->mime,
+ 'metadata' => $this->metadata,
+ 'size' => $this->size );
+
+ $wgMemc->set( $keys[0], $cachedValues, 60 * 60 * 24 * 7 ); // A week
+ } else {
+ // However we should clear them, so they aren't leftover
+ // if we've deleted the file.
+ $wgMemc->delete( $keys[0] );
+ }
+ }
+
+ /**
+ * Load metadata from the file itself
+ */
+ function loadFromFile() {
+ global $wgUseSharedUploads, $wgSharedUploadDirectory, $wgContLang;
+ wfProfileIn( __METHOD__ );
+ $this->imagePath = $this->getFullPath();
+ $this->fileExists = file_exists( $this->imagePath );
+ $this->fromSharedDirectory = false;
+ $gis = array();
+
+ if (!$this->fileExists) wfDebug(__METHOD__.': '.$this->imagePath." not found locally!\n");
+
+ # If the file is not found, and a shared upload directory is used, look for it there.
+ if (!$this->fileExists && $wgUseSharedUploads && $wgSharedUploadDirectory) {
+ # In case we're on a wgCapitalLinks=false wiki, we
+ # capitalize the first letter of the filename before
+ # looking it up in the shared repository.
+ $sharedImage = Image::newFromName( $wgContLang->ucfirst($this->name) );
+ $this->fileExists = $sharedImage && file_exists( $sharedImage->getFullPath(true) );
+ if ( $this->fileExists ) {
+ $this->name = $sharedImage->name;
+ $this->imagePath = $this->getFullPath(true);
+ $this->fromSharedDirectory = true;
+ }
+ }
+
+
+ if ( $this->fileExists ) {
+ $magic=& MimeMagic::singleton();
+
+ $this->mime = $magic->guessMimeType($this->imagePath,true);
+ $this->type = $magic->getMediaType($this->imagePath,$this->mime);
+
+ # Get size in bytes
+ $this->size = filesize( $this->imagePath );
+
+ $magic=& MimeMagic::singleton();
+
+ # Height and width
+ wfSuppressWarnings();
+ if( $this->mime == 'image/svg' ) {
+ $gis = wfGetSVGsize( $this->imagePath );
+ } elseif( $this->mime == 'image/vnd.djvu' ) {
+ $deja = new DjVuImage( $this->imagePath );
+ $gis = $deja->getImageSize();
+ } elseif ( !$magic->isPHPImageType( $this->mime ) ) {
+ # Don't try to get the width and height of sound and video files, that's bad for performance
+ $gis = false;
+ } else {
+ $gis = getimagesize( $this->imagePath );
+ }
+ wfRestoreWarnings();
+
+ wfDebug(__METHOD__.': '.$this->imagePath." loaded, ".$this->size." bytes, ".$this->mime.".\n");
+ }
+ else {
+ $this->mime = NULL;
+ $this->type = MEDIATYPE_UNKNOWN;
+ wfDebug(__METHOD__.': '.$this->imagePath." NOT FOUND!\n");
+ }
+
+ if( $gis ) {
+ $this->width = $gis[0];
+ $this->height = $gis[1];
+ } else {
+ $this->width = 0;
+ $this->height = 0;
+ }
+
+ #NOTE: $gis[2] contains a code for the image type. This is no longer used.
+
+ #NOTE: we have to set this flag early to avoid load() to be called
+ # be some of the functions below. This may lead to recursion or other bad things!
+ # as ther's only one thread of execution, this should be safe anyway.
+ $this->dataLoaded = true;
+
+
+ if ( $this->mime == 'image/vnd.djvu' ) {
+ $this->metadata = $deja->retrieveMetaData();
+ } else {
+ $this->metadata = serialize( $this->retrieveExifData( $this->imagePath ) );
+ }
+
+ if ( isset( $gis['bits'] ) ) $this->bits = $gis['bits'];
+ else $this->bits = 0;
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Load image metadata from the DB
+ */
+ function loadFromDB() {
+ global $wgUseSharedUploads, $wgSharedUploadDBname, $wgSharedUploadDBprefix, $wgContLang;
+ wfProfileIn( __METHOD__ );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $this->checkDBSchema($dbr);
+
+ $row = $dbr->selectRow( 'image',
+ array( 'img_size', 'img_width', 'img_height', 'img_bits',
+ 'img_media_type', 'img_major_mime', 'img_minor_mime', 'img_metadata' ),
+ array( 'img_name' => $this->name ), __METHOD__ );
+ if ( $row ) {
+ $this->fromSharedDirectory = false;
+ $this->fileExists = true;
+ $this->loadFromRow( $row );
+ $this->imagePath = $this->getFullPath();
+ // Check for rows from a previous schema, quietly upgrade them
+ if ( is_null($this->type) ) {
+ $this->upgradeRow();
+ }
+ } elseif ( $wgUseSharedUploads && $wgSharedUploadDBname ) {
+ # In case we're on a wgCapitalLinks=false wiki, we
+ # capitalize the first letter of the filename before
+ # looking it up in the shared repository.
+ $name = $wgContLang->ucfirst($this->name);
+ $dbc =& wfGetDB( DB_SLAVE, 'commons' );
+
+ $row = $dbc->selectRow( "`$wgSharedUploadDBname`.{$wgSharedUploadDBprefix}image",
+ array(
+ 'img_size', 'img_width', 'img_height', 'img_bits',
+ 'img_media_type', 'img_major_mime', 'img_minor_mime', 'img_metadata' ),
+ array( 'img_name' => $name ), __METHOD__ );
+ if ( $row ) {
+ $this->fromSharedDirectory = true;
+ $this->fileExists = true;
+ $this->imagePath = $this->getFullPath(true);
+ $this->name = $name;
+ $this->loadFromRow( $row );
+
+ // Check for rows from a previous schema, quietly upgrade them
+ if ( is_null($this->type) ) {
+ $this->upgradeRow();
+ }
+ }
+ }
+
+ if ( !$row ) {
+ $this->size = 0;
+ $this->width = 0;
+ $this->height = 0;
+ $this->bits = 0;
+ $this->type = 0;
+ $this->fileExists = false;
+ $this->fromSharedDirectory = false;
+ $this->metadata = serialize ( array() ) ;
+ $this->mime = false;
+ }
+
+ # Unconditionally set loaded=true, we don't want the accessors constantly rechecking
+ $this->dataLoaded = true;
+ wfProfileOut( __METHOD__ );
+ }
+
+ /*
+ * Load image metadata from a DB result row
+ */
+ function loadFromRow( &$row ) {
+ $this->size = $row->img_size;
+ $this->width = $row->img_width;
+ $this->height = $row->img_height;
+ $this->bits = $row->img_bits;
+ $this->type = $row->img_media_type;
+
+ $major= $row->img_major_mime;
+ $minor= $row->img_minor_mime;
+
+ if (!$major) $this->mime = "unknown/unknown";
+ else {
+ if (!$minor) $minor= "unknown";
+ $this->mime = $major.'/'.$minor;
+ }
+
+ $this->metadata = $row->img_metadata;
+ if ( $this->metadata == "" ) $this->metadata = serialize ( array() ) ;
+
+ $this->dataLoaded = true;
+ }
+
+ /**
+ * Load image metadata from cache or DB, unless already loaded
+ */
+ function load() {
+ global $wgSharedUploadDBname, $wgUseSharedUploads;
+ if ( !$this->dataLoaded ) {
+ if ( !$this->loadFromCache() ) {
+ $this->loadFromDB();
+ if ( !$wgSharedUploadDBname && $wgUseSharedUploads ) {
+ $this->loadFromFile();
+ } elseif ( $this->fileExists || !$wgUseSharedUploads ) {
+ // We can do negative caching for local images, because the cache
+ // will be purged on upload. But we can't do it when shared images
+ // are enabled, since updates to that won't purge foreign caches.
+ $this->saveToCache();
+ }
+ }
+ $this->dataLoaded = true;
+ }
+ }
+
+ /**
+ * Metadata was loaded from the database, but the row had a marker indicating it needs to be
+ * upgraded from the 1.4 schema, which had no width, height, bits or type. Upgrade the row.
+ */
+ function upgradeRow() {
+ global $wgDBname, $wgSharedUploadDBname;
+ wfProfileIn( __METHOD__ );
+
+ $this->loadFromFile();
+
+ if ( $this->fromSharedDirectory ) {
+ if ( !$wgSharedUploadDBname ) {
+ wfProfileOut( __METHOD__ );
+ return;
+ }
+
+ // Write to the other DB using selectDB, not database selectors
+ // This avoids breaking replication in MySQL
+ $dbw =& wfGetDB( DB_MASTER, 'commons' );
+ $dbw->selectDB( $wgSharedUploadDBname );
+ } else {
+ $dbw =& wfGetDB( DB_MASTER );
+ }
+
+ $this->checkDBSchema($dbw);
+
+ list( $major, $minor ) = self::splitMime( $this->mime );
+
+ wfDebug(__METHOD__.': upgrading '.$this->name." to 1.5 schema\n");
+
+ $dbw->update( 'image',
+ array(
+ 'img_width' => $this->width,
+ 'img_height' => $this->height,
+ 'img_bits' => $this->bits,
+ 'img_media_type' => $this->type,
+ 'img_major_mime' => $major,
+ 'img_minor_mime' => $minor,
+ 'img_metadata' => $this->metadata,
+ ), array( 'img_name' => $this->name ), __METHOD__
+ );
+ if ( $this->fromSharedDirectory ) {
+ $dbw->selectDB( $wgDBname );
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Split an internet media type into its two components; if not
+ * a two-part name, set the minor type to 'unknown'.
+ *
+ * @param $mime "text/html" etc
+ * @return array ("text", "html") etc
+ */
+ static function splitMime( $mime ) {
+ if( strpos( $mime, '/' ) !== false ) {
+ return explode( '/', $mime, 2 );
+ } else {
+ return array( $mime, 'unknown' );
+ }
+ }
+
+ /**
+ * Return the name of this image
+ * @public
+ */
+ function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Return the associated title object
+ * @public
+ */
+ function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * Return the URL of the image file
+ * @public
+ */
+ function getURL() {
+ if ( !$this->url ) {
+ $this->load();
+ if($this->fileExists) {
+ $this->url = Image::imageUrl( $this->name, $this->fromSharedDirectory );
+ } else {
+ $this->url = '';
+ }
+ }
+ return $this->url;
+ }
+
+ function getViewURL() {
+ if( $this->mustRender()) {
+ if( $this->canRender() ) {
+ return $this->createThumb( $this->getWidth() );
+ }
+ else {
+ wfDebug('Image::getViewURL(): supposed to render '.$this->name.' ('.$this->mime."), but can't!\n");
+ return $this->getURL(); #hm... return NULL?
+ }
+ } else {
+ return $this->getURL();
+ }
+ }
+
+ /**
+ * Return the image path of the image in the
+ * local file system as an absolute path
+ * @public
+ */
+ function getImagePath() {
+ $this->load();
+ return $this->imagePath;
+ }
+
+ /**
+ * Return the width of the image
+ *
+ * Returns -1 if the file specified is not a known image type
+ * @public
+ */
+ function getWidth() {
+ $this->load();
+ return $this->width;
+ }
+
+ /**
+ * Return the height of the image
+ *
+ * Returns -1 if the file specified is not a known image type
+ * @public
+ */
+ function getHeight() {
+ $this->load();
+ return $this->height;
+ }
+
+ /**
+ * Return the size of the image file, in bytes
+ * @public
+ */
+ function getSize() {
+ $this->load();
+ return $this->size;
+ }
+
+ /**
+ * Returns the mime type of the file.
+ */
+ function getMimeType() {
+ $this->load();
+ return $this->mime;
+ }
+
+ /**
+ * Return the type of the media in the file.
+ * Use the value returned by this function with the MEDIATYPE_xxx constants.
+ */
+ function getMediaType() {
+ $this->load();
+ return $this->type;
+ }
+
+ /**
+ * Checks if the file can be presented to the browser as a bitmap.
+ *
+ * Currently, this checks if the file is an image format
+ * that can be converted to a format
+ * supported by all browsers (namely GIF, PNG and JPEG),
+ * or if it is an SVG image and SVG conversion is enabled.
+ *
+ * @todo remember the result of this check.
+ */
+ function canRender() {
+ global $wgUseImageMagick, $wgDjvuRenderer;
+
+ if( $this->getWidth()<=0 || $this->getHeight()<=0 ) return false;
+
+ $mime= $this->getMimeType();
+
+ if (!$mime || $mime==='unknown' || $mime==='unknown/unknown') return false;
+
+ #if it's SVG, check if there's a converter enabled
+ if ($mime === 'image/svg') {
+ global $wgSVGConverters, $wgSVGConverter;
+
+ if ($wgSVGConverter && isset( $wgSVGConverters[$wgSVGConverter])) {
+ wfDebug( "Image::canRender: SVG is ready!\n" );
+ return true;
+ } else {
+ wfDebug( "Image::canRender: SVG renderer missing\n" );
+ }
+ }
+
+ #image formats available on ALL browsers
+ if ( $mime === 'image/gif'
+ || $mime === 'image/png'
+ || $mime === 'image/jpeg' ) return true;
+
+ #image formats that can be converted to the above formats
+ if ($wgUseImageMagick) {
+ #convertable by ImageMagick (there are more...)
+ if ( $mime === 'image/vnd.wap.wbmp'
+ || $mime === 'image/x-xbitmap'
+ || $mime === 'image/x-xpixmap'
+ #|| $mime === 'image/x-icon' #file may be split into multiple parts
+ || $mime === 'image/x-portable-anymap'
+ || $mime === 'image/x-portable-bitmap'
+ || $mime === 'image/x-portable-graymap'
+ || $mime === 'image/x-portable-pixmap'
+ #|| $mime === 'image/x-photoshop' #this takes a lot of CPU and RAM!
+ || $mime === 'image/x-rgb'
+ || $mime === 'image/x-bmp'
+ || $mime === 'image/tiff' ) return true;
+ }
+ else {
+ #convertable by the PHP GD image lib
+ if ( $mime === 'image/vnd.wap.wbmp'
+ || $mime === 'image/x-xbitmap' ) return true;
+ }
+ if ( $mime === 'image/vnd.djvu' && isset( $wgDjvuRenderer ) && $wgDjvuRenderer ) return true;
+
+ return false;
+ }
+
+
+ /**
+ * Return true if the file is of a type that can't be directly
+ * rendered by typical browsers and needs to be re-rasterized.
+ *
+ * This returns true for everything but the bitmap types
+ * supported by all browsers, i.e. JPEG; GIF and PNG. It will
+ * also return true for any non-image formats.
+ *
+ * @return bool
+ */
+ function mustRender() {
+ $mime= $this->getMimeType();
+
+ if ( $mime === "image/gif"
+ || $mime === "image/png"
+ || $mime === "image/jpeg" ) return false;
+
+ return true;
+ }
+
+ /**
+ * Determines if this media file may be shown inline on a page.
+ *
+ * This is currently synonymous to canRender(), but this could be
+ * extended to also allow inline display of other media,
+ * like flash animations or videos. If you do so, please keep in mind that
+ * that could be a security risk.
+ */
+ function allowInlineDisplay() {
+ return $this->canRender();
+ }
+
+ /**
+ * Determines if this media file is in a format that is unlikely to
+ * contain viruses or malicious content. It uses the global
+ * $wgTrustedMediaFormats list to determine if the file is safe.
+ *
+ * This is used to show a warning on the description page of non-safe files.
+ * It may also be used to disallow direct [[media:...]] links to such files.
+ *
+ * Note that this function will always return true if allowInlineDisplay()
+ * or isTrustedFile() is true for this file.
+ */
+ function isSafeFile() {
+ if ($this->allowInlineDisplay()) return true;
+ if ($this->isTrustedFile()) return true;
+
+ global $wgTrustedMediaFormats;
+
+ $type= $this->getMediaType();
+ $mime= $this->getMimeType();
+ #wfDebug("Image::isSafeFile: type= $type, mime= $mime\n");
+
+ if (!$type || $type===MEDIATYPE_UNKNOWN) return false; #unknown type, not trusted
+ if ( in_array( $type, $wgTrustedMediaFormats) ) return true;
+
+ if ($mime==="unknown/unknown") return false; #unknown type, not trusted
+ if ( in_array( $mime, $wgTrustedMediaFormats) ) return true;
+
+ return false;
+ }
+
+ /** Returns true if the file is flagged as trusted. Files flagged that way
+ * can be linked to directly, even if that is not allowed for this type of
+ * file normally.
+ *
+ * This is a dummy function right now and always returns false. It could be
+ * implemented to extract a flag from the database. The trusted flag could be
+ * set on upload, if the user has sufficient privileges, to bypass script-
+ * and html-filters. It may even be coupled with cryptographics signatures
+ * or such.
+ */
+ function isTrustedFile() {
+ #this could be implemented to check a flag in the databas,
+ #look for signatures, etc
+ return false;
+ }
+
+ /**
+ * Return the escapeLocalURL of this image
+ * @public
+ */
+ function getEscapeLocalURL( $query=false) {
+ $this->getTitle();
+ if ( $query === false ) {
+ if ( $this->page != 1 ) {
+ $query = 'page=' . $this->page;
+ } else {
+ $query = '';
+ }
+ }
+ return $this->title->escapeLocalURL( $query );
+ }
+
+ /**
+ * Return the escapeFullURL of this image
+ * @public
+ */
+ function getEscapeFullURL() {
+ $this->getTitle();
+ return $this->title->escapeFullURL();
+ }
+
+ /**
+ * Return the URL of an image, provided its name.
+ *
+ * @param string $name Name of the image, without the leading "Image:"
+ * @param boolean $fromSharedDirectory Should this be in $wgSharedUploadPath?
+ * @return string URL of $name image
+ * @public
+ * @static
+ */
+ function imageUrl( $name, $fromSharedDirectory = false ) {
+ global $wgUploadPath,$wgUploadBaseUrl,$wgSharedUploadPath;
+ if($fromSharedDirectory) {
+ $base = '';
+ $path = $wgSharedUploadPath;
+ } else {
+ $base = $wgUploadBaseUrl;
+ $path = $wgUploadPath;
+ }
+ $url = "{$base}{$path}" . wfGetHashPath($name, $fromSharedDirectory) . "{$name}";
+ return wfUrlencode( $url );
+ }
+
+ /**
+ * Returns true if the image file exists on disk.
+ * @return boolean Whether image file exist on disk.
+ * @public
+ */
+ function exists() {
+ $this->load();
+ return $this->fileExists;
+ }
+
+ /**
+ * @todo document
+ * @private
+ */
+ function thumbUrl( $width, $subdir='thumb') {
+ global $wgUploadPath, $wgUploadBaseUrl, $wgSharedUploadPath;
+ global $wgSharedThumbnailScriptPath, $wgThumbnailScriptPath;
+
+ // Generate thumb.php URL if possible
+ $script = false;
+ $url = false;
+
+ if ( $this->fromSharedDirectory ) {
+ if ( $wgSharedThumbnailScriptPath ) {
+ $script = $wgSharedThumbnailScriptPath;
+ }
+ } else {
+ if ( $wgThumbnailScriptPath ) {
+ $script = $wgThumbnailScriptPath;
+ }
+ }
+ if ( $script ) {
+ $url = $script . '?f=' . urlencode( $this->name ) . '&w=' . urlencode( $width );
+ if( $this->mustRender() ) {
+ $url.= '&r=1';
+ }
+ } else {
+ $name = $this->thumbName( $width );
+ if($this->fromSharedDirectory) {
+ $base = '';
+ $path = $wgSharedUploadPath;
+ } else {
+ $base = $wgUploadBaseUrl;
+ $path = $wgUploadPath;
+ }
+ if ( Image::isHashed( $this->fromSharedDirectory ) ) {
+ $url = "{$base}{$path}/{$subdir}" .
+ wfGetHashPath($this->name, $this->fromSharedDirectory)
+ . $this->name.'/'.$name;
+ $url = wfUrlencode( $url );
+ } else {
+ $url = "{$base}{$path}/{$subdir}/{$name}";
+ }
+ }
+ return array( $script !== false, $url );
+ }
+
+ /**
+ * Return the file name of a thumbnail of the specified width
+ *
+ * @param integer $width Width of the thumbnail image
+ * @param boolean $shared Does the thumbnail come from the shared repository?
+ * @private
+ */
+ function thumbName( $width ) {
+ $thumb = $width."px-".$this->name;
+ if ( $this->page != 1 ) {
+ $thumb = "page{$this->page}-$thumb";
+ }
+
+ if( $this->mustRender() ) {
+ if( $this->canRender() ) {
+ # Rasterize to PNG (for SVG vector images, etc)
+ $thumb .= '.png';
+ }
+ else {
+ #should we use iconThumb here to get a symbolic thumbnail?
+ #or should we fail with an internal error?
+ return NULL; //can't make bitmap
+ }
+ }
+ return $thumb;
+ }
+
+ /**
+ * Create a thumbnail of the image having the specified width/height.
+ * The thumbnail will not be created if the width is larger than the
+ * image's width. Let the browser do the scaling in this case.
+ * The thumbnail is stored on disk and is only computed if the thumbnail
+ * file does not exist OR if it is older than the image.
+ * Returns the URL.
+ *
+ * Keeps aspect ratio of original image. If both width and height are
+ * specified, the generated image will be no bigger than width x height,
+ * and will also have correct aspect ratio.
+ *
+ * @param integer $width maximum width of the generated thumbnail
+ * @param integer $height maximum height of the image (optional)
+ * @public
+ */
+ function createThumb( $width, $height=-1 ) {
+ $thumb = $this->getThumbnail( $width, $height );
+ if( is_null( $thumb ) ) return '';
+ return $thumb->getUrl();
+ }
+
+ /**
+ * As createThumb, but returns a ThumbnailImage object. This can
+ * provide access to the actual file, the real size of the thumb,
+ * and can produce a convenient <img> tag for you.
+ *
+ * For non-image formats, this may return a filetype-specific icon.
+ *
+ * @param integer $width maximum width of the generated thumbnail
+ * @param integer $height maximum height of the image (optional)
+ * @param boolean $render True to render the thumbnail if it doesn't exist,
+ * false to just return the URL
+ *
+ * @return ThumbnailImage or null on failure
+ * @public
+ */
+ function getThumbnail( $width, $height=-1, $render = true ) {
+ wfProfileIn( __METHOD__ );
+ if ($this->canRender()) {
+ if ( $height > 0 ) {
+ $this->load();
+ if ( $width > $this->width * $height / $this->height ) {
+ $width = wfFitBoxWidth( $this->width, $this->height, $height );
+ }
+ }
+ if ( $render ) {
+ $thumb = $this->renderThumb( $width );
+ } else {
+ // Don't render, just return the URL
+ if ( $this->validateThumbParams( $width, $height ) ) {
+ if ( !$this->mustRender() && $width == $this->width && $height == $this->height ) {
+ $url = $this->getURL();
+ } else {
+ list( /* $isScriptUrl */, $url ) = $this->thumbUrl( $width );
+ }
+ $thumb = new ThumbnailImage( $url, $width, $height );
+ } else {
+ $thumb = null;
+ }
+ }
+ } else {
+ // not a bitmap or renderable image, don't try.
+ $thumb = $this->iconThumb();
+ }
+ wfProfileOut( __METHOD__ );
+ return $thumb;
+ }
+
+ /**
+ * @return ThumbnailImage
+ */
+ function iconThumb() {
+ global $wgStylePath, $wgStyleDirectory;
+
+ $try = array( 'fileicon-' . $this->extension . '.png', 'fileicon.png' );
+ foreach( $try as $icon ) {
+ $path = '/common/images/icons/' . $icon;
+ $filepath = $wgStyleDirectory . $path;
+ if( file_exists( $filepath ) ) {
+ return new ThumbnailImage( $wgStylePath . $path, 120, 120 );
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Validate thumbnail parameters and fill in the correct height
+ *
+ * @param integer &$width Specified width (input/output)
+ * @param integer &$height Height (output only)
+ * @return false to indicate that an error should be returned to the user.
+ */
+ function validateThumbParams( &$width, &$height ) {
+ global $wgSVGMaxSize, $wgMaxImageArea;
+
+ $this->load();
+
+ if ( ! $this->exists() )
+ {
+ # If there is no image, there will be no thumbnail
+ return false;
+ }
+
+ $width = intval( $width );
+
+ # Sanity check $width
+ if( $width <= 0 || $this->width <= 0) {
+ # BZZZT
+ return false;
+ }
+
+ # Don't thumbnail an image so big that it will fill hard drives and send servers into swap
+ # JPEG has the handy property of allowing thumbnailing without full decompression, so we make
+ # an exception for it.
+ if ( $this->getMediaType() == MEDIATYPE_BITMAP &&
+ $this->getMimeType() !== 'image/jpeg' &&
+ $this->width * $this->height > $wgMaxImageArea )
+ {
+ return false;
+ }
+
+ # Don't make an image bigger than the source, or wgMaxSVGSize for SVGs
+ if ( $this->mustRender() ) {
+ $width = min( $width, $wgSVGMaxSize );
+ } elseif ( $width > $this->width - 1 ) {
+ $width = $this->width;
+ $height = $this->height;
+ return true;
+ }
+
+ $height = round( $this->height * $width / $this->width );
+ return true;
+ }
+
+ /**
+ * Create a thumbnail of the image having the specified width.
+ * The thumbnail will not be created if the width is larger than the
+ * image's width. Let the browser do the scaling in this case.
+ * The thumbnail is stored on disk and is only computed if the thumbnail
+ * file does not exist OR if it is older than the image.
+ * Returns an object which can return the pathname, URL, and physical
+ * pixel size of the thumbnail -- or null on failure.
+ *
+ * @return ThumbnailImage or null on failure
+ * @private
+ */
+ function renderThumb( $width, $useScript = true ) {
+ global $wgUseSquid, $wgThumbnailEpoch;
+
+ wfProfileIn( __METHOD__ );
+
+ $this->load();
+ $height = -1;
+ if ( !$this->validateThumbParams( $width, $height ) ) {
+ # Validation error
+ wfProfileOut( __METHOD__ );
+ return null;
+ }
+
+ if ( !$this->mustRender() && $width == $this->width && $height == $this->height ) {
+ # validateThumbParams (or the user) wants us to return the unscaled image
+ $thumb = new ThumbnailImage( $this->getURL(), $width, $height );
+ wfProfileOut( __METHOD__ );
+ return $thumb;
+ }
+
+ list( $isScriptUrl, $url ) = $this->thumbUrl( $width );
+ if ( $isScriptUrl && $useScript ) {
+ // Use thumb.php to render the image
+ $thumb = new ThumbnailImage( $url, $width, $height );
+ wfProfileOut( __METHOD__ );
+ return $thumb;
+ }
+
+ $thumbName = $this->thumbName( $width, $this->fromSharedDirectory );
+ $thumbDir = wfImageThumbDir( $this->name, $this->fromSharedDirectory );
+ $thumbPath = $thumbDir.'/'.$thumbName;
+
+ if ( is_dir( $thumbPath ) ) {
+ // Directory where file should be
+ // This happened occasionally due to broken migration code in 1.5
+ // Rename to broken-*
+ global $wgUploadDirectory;
+ for ( $i = 0; $i < 100 ; $i++ ) {
+ $broken = "$wgUploadDirectory/broken-$i-$thumbName";
+ if ( !file_exists( $broken ) ) {
+ rename( $thumbPath, $broken );
+ break;
+ }
+ }
+ // Code below will ask if it exists, and the answer is now no
+ clearstatcache();
+ }
+
+ $done = true;
+ if ( !file_exists( $thumbPath ) ||
+ filemtime( $thumbPath ) < wfTimestamp( TS_UNIX, $wgThumbnailEpoch ) )
+ {
+ // Create the directory if it doesn't exist
+ if ( is_file( $thumbDir ) ) {
+ // File where thumb directory should be, destroy if possible
+ @unlink( $thumbDir );
+ }
+ wfMkdirParents( $thumbDir );
+
+ $oldThumbPath = wfDeprecatedThumbDir( $thumbName, 'thumb', $this->fromSharedDirectory ).
+ '/'.$thumbName;
+ $done = false;
+
+ // Migration from old directory structure
+ if ( is_file( $oldThumbPath ) ) {
+ if ( filemtime($oldThumbPath) >= filemtime($this->imagePath) ) {
+ if ( file_exists( $thumbPath ) ) {
+ if ( !is_dir( $thumbPath ) ) {
+ // Old image in the way of rename
+ unlink( $thumbPath );
+ } else {
+ // This should have been dealt with already
+ throw new MWException( "Directory where image should be: $thumbPath" );
+ }
+ }
+ // Rename the old image into the new location
+ rename( $oldThumbPath, $thumbPath );
+ $done = true;
+ } else {
+ unlink( $oldThumbPath );
+ }
+ }
+ if ( !$done ) {
+ $this->lastError = $this->reallyRenderThumb( $thumbPath, $width, $height );
+ if ( $this->lastError === true ) {
+ $done = true;
+ } elseif( $GLOBALS['wgIgnoreImageErrors'] ) {
+ // Log the error but output anyway.
+ // With luck it's a transitory error...
+ $done = true;
+ }
+
+ # Purge squid
+ # This has to be done after the image is updated and present for all machines on NFS,
+ # or else the old version might be stored into the squid again
+ if ( $wgUseSquid ) {
+ $urlArr = array( $url );
+ wfPurgeSquidServers($urlArr);
+ }
+ }
+ }
+
+ if ( $done ) {
+ $thumb = new ThumbnailImage( $url, $width, $height, $thumbPath );
+ } else {
+ $thumb = null;
+ }
+ wfProfileOut( __METHOD__ );
+ return $thumb;
+ } // END OF function renderThumb
+
+ /**
+ * Really render a thumbnail
+ * Call this only for images for which canRender() returns true.
+ *
+ * @param string $thumbPath Path to thumbnail
+ * @param int $width Desired width in pixels
+ * @param int $height Desired height in pixels
+ * @return bool True on error, false or error string on failure.
+ * @private
+ */
+ function reallyRenderThumb( $thumbPath, $width, $height ) {
+ global $wgSVGConverters, $wgSVGConverter;
+ global $wgUseImageMagick, $wgImageMagickConvertCommand;
+ global $wgCustomConvertCommand;
+ global $wgDjvuRenderer, $wgDjvuPostProcessor;
+
+ $this->load();
+
+ $err = false;
+ $cmd = "";
+ $retval = 0;
+
+ if( $this->mime === "image/svg" ) {
+ #Right now we have only SVG
+
+ global $wgSVGConverters, $wgSVGConverter;
+ if( isset( $wgSVGConverters[$wgSVGConverter] ) ) {
+ global $wgSVGConverterPath;
+ $cmd = str_replace(
+ array( '$path/', '$width', '$height', '$input', '$output' ),
+ array( $wgSVGConverterPath ? "$wgSVGConverterPath/" : "",
+ intval( $width ),
+ intval( $height ),
+ wfEscapeShellArg( $this->imagePath ),
+ wfEscapeShellArg( $thumbPath ) ),
+ $wgSVGConverters[$wgSVGConverter] );
+ wfProfileIn( 'rsvg' );
+ wfDebug( "reallyRenderThumb SVG: $cmd\n" );
+ $err = wfShellExec( $cmd, $retval );
+ wfProfileOut( 'rsvg' );
+ }
+ } else {
+ if ( $this->mime === "image/vnd.djvu" && $wgDjvuRenderer ) {
+ // DJVU image
+ // The file contains several images. First, extract the
+ // page in hi-res, if it doesn't yet exist. Then, thumbnail
+ // it.
+
+ $cmd = "{$wgDjvuRenderer} -page={$this->page} -size=${width}x${height} " .
+ wfEscapeShellArg( $this->imagePath ) .
+ " | {$wgDjvuPostProcessor} > " . wfEscapeShellArg($thumbPath);
+ wfProfileIn( 'ddjvu' );
+ wfDebug( "reallyRenderThumb DJVU: $cmd\n" );
+ $err = wfShellExec( $cmd, $retval );
+ wfProfileOut( 'ddjvu' );
+
+ } elseif ( $wgUseImageMagick ) {
+ # use ImageMagick
+
+ if ( $this->mime == 'image/jpeg' ) {
+ $quality = "-quality 80"; // 80%
+ } elseif ( $this->mime == 'image/png' ) {
+ $quality = "-quality 95"; // zlib 9, adaptive filtering
+ } else {
+ $quality = ''; // default
+ }
+
+ # Specify white background color, will be used for transparent images
+ # in Internet Explorer/Windows instead of default black.
+
+ # Note, we specify "-size {$width}" and NOT "-size {$width}x{$height}".
+ # It seems that ImageMagick has a bug wherein it produces thumbnails of
+ # the wrong size in the second case.
+
+ $cmd = wfEscapeShellArg($wgImageMagickConvertCommand) .
+ " {$quality} -background white -size {$width} ".
+ wfEscapeShellArg($this->imagePath) .
+ // Coalesce is needed to scale animated GIFs properly (bug 1017).
+ ' -coalesce ' .
+ // For the -resize option a "!" is needed to force exact size,
+ // or ImageMagick may decide your ratio is wrong and slice off
+ // a pixel.
+ " -thumbnail " . wfEscapeShellArg( "{$width}x{$height}!" ) .
+ " -depth 8 " .
+ wfEscapeShellArg($thumbPath) . " 2>&1";
+ wfDebug("reallyRenderThumb: running ImageMagick: $cmd\n");
+ wfProfileIn( 'convert' );
+ $err = wfShellExec( $cmd, $retval );
+ wfProfileOut( 'convert' );
+ } elseif( $wgCustomConvertCommand ) {
+ # Use a custom convert command
+ # Variables: %s %d %w %h
+ $src = wfEscapeShellArg( $this->imagePath );
+ $dst = wfEscapeShellArg( $thumbPath );
+ $cmd = $wgCustomConvertCommand;
+ $cmd = str_replace( '%s', $src, str_replace( '%d', $dst, $cmd ) ); # Filenames
+ $cmd = str_replace( '%h', $height, str_replace( '%w', $width, $cmd ) ); # Size
+ wfDebug( "reallyRenderThumb: Running custom convert command $cmd\n" );
+ wfProfileIn( 'convert' );
+ $err = wfShellExec( $cmd, $retval );
+ wfProfileOut( 'convert' );
+ } else {
+ # Use PHP's builtin GD library functions.
+ #
+ # First find out what kind of file this is, and select the correct
+ # input routine for this.
+
+ $typemap = array(
+ 'image/gif' => array( 'imagecreatefromgif', 'palette', 'imagegif' ),
+ 'image/jpeg' => array( 'imagecreatefromjpeg', 'truecolor', array( &$this, 'imageJpegWrapper' ) ),
+ 'image/png' => array( 'imagecreatefrompng', 'bits', 'imagepng' ),
+ 'image/vnd.wap.wmbp' => array( 'imagecreatefromwbmp', 'palette', 'imagewbmp' ),
+ 'image/xbm' => array( 'imagecreatefromxbm', 'palette', 'imagexbm' ),
+ );
+ if( !isset( $typemap[$this->mime] ) ) {
+ $err = 'Image type not supported';
+ wfDebug( "$err\n" );
+ return $err;
+ }
+ list( $loader, $colorStyle, $saveType ) = $typemap[$this->mime];
+
+ if( !function_exists( $loader ) ) {
+ $err = "Incomplete GD library configuration: missing function $loader";
+ wfDebug( "$err\n" );
+ return $err;
+ }
+ if( $colorStyle == 'palette' ) {
+ $truecolor = false;
+ } elseif( $colorStyle == 'truecolor' ) {
+ $truecolor = true;
+ } elseif( $colorStyle == 'bits' ) {
+ $truecolor = ( $this->bits > 8 );
+ }
+
+ $src_image = call_user_func( $loader, $this->imagePath );
+ if ( $truecolor ) {
+ $dst_image = imagecreatetruecolor( $width, $height );
+ } else {
+ $dst_image = imagecreate( $width, $height );
+ }
+ imagecopyresampled( $dst_image, $src_image,
+ 0,0,0,0,
+ $width, $height, $this->width, $this->height );
+ call_user_func( $saveType, $dst_image, $thumbPath );
+ imagedestroy( $dst_image );
+ imagedestroy( $src_image );
+ }
+ }
+
+ #
+ # Check for zero-sized thumbnails. Those can be generated when
+ # no disk space is available or some other error occurs
+ #
+ if( file_exists( $thumbPath ) ) {
+ $thumbstat = stat( $thumbPath );
+ if( $thumbstat['size'] == 0 || $retval != 0 ) {
+ wfDebugLog( 'thumbnail',
+ sprintf( 'Removing bad %d-byte thumbnail "%s"',
+ $thumbstat['size'], $thumbPath ) );
+ unlink( $thumbPath );
+ }
+ }
+ if ( $retval != 0 ) {
+ wfDebugLog( 'thumbnail',
+ sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
+ wfHostname(), $retval, trim($err), $cmd ) );
+ return wfMsg( 'thumbnail_error', $err );
+ } else {
+ return true;
+ }
+ }
+
+ function getLastError() {
+ return $this->lastError;
+ }
+
+ function imageJpegWrapper( $dst_image, $thumbPath ) {
+ imageinterlace( $dst_image );
+ imagejpeg( $dst_image, $thumbPath, 95 );
+ }
+
+ /**
+ * Get all thumbnail names previously generated for this image
+ */
+ function getThumbnails( $shared = false ) {
+ if ( Image::isHashed( $shared ) ) {
+ $this->load();
+ $files = array();
+ $dir = wfImageThumbDir( $this->name, $shared );
+
+ // This generates an error on failure, hence the @
+ $handle = @opendir( $dir );
+
+ if ( $handle ) {
+ while ( false !== ( $file = readdir($handle) ) ) {
+ if ( $file{0} != '.' ) {
+ $files[] = $file;
+ }
+ }
+ closedir( $handle );
+ }
+ } else {
+ $files = array();
+ }
+
+ return $files;
+ }
+
+ /**
+ * Refresh metadata in memcached, but don't touch thumbnails or squid
+ */
+ function purgeMetadataCache() {
+ clearstatcache();
+ $this->loadFromFile();
+ $this->saveToCache();
+ }
+
+ /**
+ * Delete all previously generated thumbnails, refresh metadata in memcached and purge the squid
+ */
+ function purgeCache( $archiveFiles = array(), $shared = false ) {
+ global $wgUseSquid;
+
+ // Refresh metadata cache
+ $this->purgeMetadataCache();
+
+ // Delete thumbnails
+ $files = $this->getThumbnails( $shared );
+ $dir = wfImageThumbDir( $this->name, $shared );
+ $urls = array();
+ foreach ( $files as $file ) {
+ $m = array();
+ if ( preg_match( '/^(\d+)px/', $file, $m ) ) {
+ list( /* $isScriptUrl */, $url ) = $this->thumbUrl( $m[1] );
+ $urls[] = $url;
+ @unlink( "$dir/$file" );
+ }
+ }
+
+ // Purge the squid
+ if ( $wgUseSquid ) {
+ $urls[] = $this->getURL();
+ foreach ( $archiveFiles as $file ) {
+ $urls[] = wfImageArchiveUrl( $file );
+ }
+ wfPurgeSquidServers( $urls );
+ }
+ }
+
+ /**
+ * Purge the image description page, but don't go after
+ * pages using the image. Use when modifying file history
+ * but not the current data.
+ */
+ function purgeDescription() {
+ $page = Title::makeTitle( NS_IMAGE, $this->name );
+ $page->invalidateCache();
+ $page->purgeSquid();
+ }
+
+ /**
+ * Purge metadata and all affected pages when the image is created,
+ * deleted, or majorly updated. A set of additional URLs may be
+ * passed to purge, such as specific image files which have changed.
+ * @param $urlArray array
+ */
+ function purgeEverything( $urlArr=array() ) {
+ // Delete thumbnails and refresh image metadata cache
+ $this->purgeCache();
+ $this->purgeDescription();
+
+ // Purge cache of all pages using this image
+ $update = new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' );
+ $update->doUpdate();
+ }
+
+ function checkDBSchema(&$db) {
+ static $checkDone = false;
+ global $wgCheckDBSchema;
+ if (!$wgCheckDBSchema || $checkDone) {
+ return;
+ }
+ # img_name must be unique
+ if ( !$db->indexUnique( 'image', 'img_name' ) && !$db->indexExists('image','PRIMARY') ) {
+ throw new MWException( 'Database schema not up to date, please run maintenance/archives/patch-image_name_unique.sql' );
+ }
+ $checkDone = true;
+
+ # new fields must exist
+ #
+ # Not really, there's hundreds of checks like this that we could do and they're all pointless, because
+ # if the fields are missing, the database will loudly report a query error, the first time you try to do
+ # something. The only reason I put the above schema check in was because the absence of that particular
+ # index would lead to an annoying subtle bug. No error message, just some very odd behaviour on duplicate
+ # uploads. -- TS
+ /*
+ if ( !$db->fieldExists( 'image', 'img_media_type' )
+ || !$db->fieldExists( 'image', 'img_metadata' )
+ || !$db->fieldExists( 'image', 'img_width' ) ) {
+
+ throw new MWException( 'Database schema not up to date, please run maintenance/update.php' );
+ }
+ */
+ }
+
+ /**
+ * Return the image history of this image, line by line.
+ * starts with current version, then old versions.
+ * uses $this->historyLine to check which line to return:
+ * 0 return line for current version
+ * 1 query for old versions, return first one
+ * 2, ... return next old version from above query
+ *
+ * @public
+ */
+ function nextHistoryLine() {
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $this->checkDBSchema($dbr);
+
+ if ( $this->historyLine == 0 ) {// called for the first time, return line from cur
+ $this->historyRes = $dbr->select( 'image',
+ array(
+ 'img_size',
+ 'img_description',
+ 'img_user','img_user_text',
+ 'img_timestamp',
+ 'img_width',
+ 'img_height',
+ "'' AS oi_archive_name"
+ ),
+ array( 'img_name' => $this->title->getDBkey() ),
+ __METHOD__
+ );
+ if ( 0 == $dbr->numRows( $this->historyRes ) ) {
+ return FALSE;
+ }
+ } else if ( $this->historyLine == 1 ) {
+ $this->historyRes = $dbr->select( 'oldimage',
+ array(
+ 'oi_size AS img_size',
+ 'oi_description AS img_description',
+ 'oi_user AS img_user',
+ 'oi_user_text AS img_user_text',
+ 'oi_timestamp AS img_timestamp',
+ 'oi_width as img_width',
+ 'oi_height as img_height',
+ 'oi_archive_name'
+ ),
+ array( 'oi_name' => $this->title->getDBkey() ),
+ __METHOD__,
+ array( 'ORDER BY' => 'oi_timestamp DESC' )
+ );
+ }
+ $this->historyLine ++;
+
+ return $dbr->fetchObject( $this->historyRes );
+ }
+
+ /**
+ * Reset the history pointer to the first element of the history
+ * @public
+ */
+ function resetHistory() {
+ $this->historyLine = 0;
+ }
+
+ /**
+ * Return the full filesystem path to the file. Note that this does
+ * not mean that a file actually exists under that location.
+ *
+ * This path depends on whether directory hashing is active or not,
+ * i.e. whether the images are all found in the same directory,
+ * or in hashed paths like /images/3/3c.
+ *
+ * @public
+ * @param boolean $fromSharedDirectory Return the path to the file
+ * in a shared repository (see $wgUseSharedRepository and related
+ * options in DefaultSettings.php) instead of a local one.
+ *
+ */
+ function getFullPath( $fromSharedRepository = false ) {
+ global $wgUploadDirectory, $wgSharedUploadDirectory;
+
+ $dir = $fromSharedRepository ? $wgSharedUploadDirectory :
+ $wgUploadDirectory;
+
+ // $wgSharedUploadDirectory may be false, if thumb.php is used
+ if ( $dir ) {
+ $fullpath = $dir . wfGetHashPath($this->name, $fromSharedRepository) . $this->name;
+ } else {
+ $fullpath = false;
+ }
+
+ return $fullpath;
+ }
+
+ /**
+ * @return bool
+ * @static
+ */
+ public static function isHashed( $shared ) {
+ global $wgHashedUploadDirectory, $wgHashedSharedUploadDirectory;
+ return $shared ? $wgHashedSharedUploadDirectory : $wgHashedUploadDirectory;
+ }
+
+ /**
+ * Record an image upload in the upload log and the image table
+ */
+ function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '', $watch = false ) {
+ global $wgUser, $wgUseCopyrightUpload;
+
+ $dbw =& wfGetDB( DB_MASTER );
+
+ $this->checkDBSchema($dbw);
+
+ // Delete thumbnails and refresh the metadata cache
+ $this->purgeCache();
+
+ // Fail now if the image isn't there
+ if ( !$this->fileExists || $this->fromSharedDirectory ) {
+ wfDebug( "Image::recordUpload: File ".$this->imagePath." went missing!\n" );
+ return false;
+ }
+
+ if ( $wgUseCopyrightUpload ) {
+ if ( $license != '' ) {
+ $licensetxt = '== ' . wfMsgForContent( 'license' ) . " ==\n" . '{{' . $license . '}}' . "\n";
+ }
+ $textdesc = '== ' . wfMsg ( 'filedesc' ) . " ==\n" . $desc . "\n" .
+ '== ' . wfMsgForContent ( 'filestatus' ) . " ==\n" . $copyStatus . "\n" .
+ "$licensetxt" .
+ '== ' . wfMsgForContent ( 'filesource' ) . " ==\n" . $source ;
+ } else {
+ if ( $license != '' ) {
+ $filedesc = $desc == '' ? '' : '== ' . wfMsg ( 'filedesc' ) . " ==\n" . $desc . "\n";
+ $textdesc = $filedesc .
+ '== ' . wfMsgForContent ( 'license' ) . " ==\n" . '{{' . $license . '}}' . "\n";
+ } else {
+ $textdesc = $desc;
+ }
+ }
+
+ $now = $dbw->timestamp();
+
+ #split mime type
+ if (strpos($this->mime,'/')!==false) {
+ list($major,$minor)= explode('/',$this->mime,2);
+ }
+ else {
+ $major= $this->mime;
+ $minor= "unknown";
+ }
+
+ # Test to see if the row exists using INSERT IGNORE
+ # This avoids race conditions by locking the row until the commit, and also
+ # doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition.
+ $dbw->insert( 'image',
+ array(
+ 'img_name' => $this->name,
+ 'img_size'=> $this->size,
+ 'img_width' => intval( $this->width ),
+ 'img_height' => intval( $this->height ),
+ 'img_bits' => $this->bits,
+ 'img_media_type' => $this->type,
+ 'img_major_mime' => $major,
+ 'img_minor_mime' => $minor,
+ 'img_timestamp' => $now,
+ 'img_description' => $desc,
+ 'img_user' => $wgUser->getID(),
+ 'img_user_text' => $wgUser->getName(),
+ 'img_metadata' => $this->metadata,
+ ),
+ __METHOD__,
+ 'IGNORE'
+ );
+
+ if( $dbw->affectedRows() == 0 ) {
+ # Collision, this is an update of an image
+ # Insert previous contents into oldimage
+ $dbw->insertSelect( 'oldimage', 'image',
+ array(
+ 'oi_name' => 'img_name',
+ 'oi_archive_name' => $dbw->addQuotes( $oldver ),
+ 'oi_size' => 'img_size',
+ 'oi_width' => 'img_width',
+ 'oi_height' => 'img_height',
+ 'oi_bits' => 'img_bits',
+ 'oi_timestamp' => 'img_timestamp',
+ 'oi_description' => 'img_description',
+ 'oi_user' => 'img_user',
+ 'oi_user_text' => 'img_user_text',
+ ), array( 'img_name' => $this->name ), __METHOD__
+ );
+
+ # Update the current image row
+ $dbw->update( 'image',
+ array( /* SET */
+ 'img_size' => $this->size,
+ 'img_width' => intval( $this->width ),
+ 'img_height' => intval( $this->height ),
+ 'img_bits' => $this->bits,
+ 'img_media_type' => $this->type,
+ 'img_major_mime' => $major,
+ 'img_minor_mime' => $minor,
+ 'img_timestamp' => $now,
+ 'img_description' => $desc,
+ 'img_user' => $wgUser->getID(),
+ 'img_user_text' => $wgUser->getName(),
+ 'img_metadata' => $this->metadata,
+ ), array( /* WHERE */
+ 'img_name' => $this->name
+ ), __METHOD__
+ );
+ } else {
+ # This is a new image
+ # Update the image count
+ $site_stats = $dbw->tableName( 'site_stats' );
+ $dbw->query( "UPDATE $site_stats SET ss_images=ss_images+1", __METHOD__ );
+ }
+
+ $descTitle = $this->getTitle();
+ $article = new Article( $descTitle );
+ $minor = false;
+ $watch = $watch || $wgUser->isWatched( $descTitle );
+ $suppressRC = true; // There's already a log entry, so don't double the RC load
+
+ if( $descTitle->exists() ) {
+ // TODO: insert a null revision into the page history for this update.
+ if( $watch ) {
+ $wgUser->addWatch( $descTitle );
+ }
+
+ # Invalidate the cache for the description page
+ $descTitle->invalidateCache();
+ $descTitle->purgeSquid();
+ } else {
+ // New image; create the description page.
+ $article->insertNewArticle( $textdesc, $desc, $minor, $watch, $suppressRC );
+ }
+
+ # Add the log entry
+ $log = new LogPage( 'upload' );
+ $log->addEntry( 'upload', $descTitle, $desc );
+
+ # Commit the transaction now, in case something goes wrong later
+ # The most important thing is that images don't get lost, especially archives
+ $dbw->immediateCommit();
+
+ # Invalidate cache for all pages using this image
+ $update = new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' );
+ $update->doUpdate();
+
+ return true;
+ }
+
+ /**
+ * Get an array of Title objects which are articles which use this image
+ * Also adds their IDs to the link cache
+ *
+ * This is mostly copied from Title::getLinksTo()
+ *
+ * @deprecated Use HTMLCacheUpdate, this function uses too much memory
+ */
+ function getLinksTo( $options = '' ) {
+ wfProfileIn( __METHOD__ );
+
+ if ( $options ) {
+ $db =& wfGetDB( DB_MASTER );
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ }
+ $linkCache =& LinkCache::singleton();
+
+ list( $page, $imagelinks ) = $db->tableNamesN( 'page', 'imagelinks' );
+ $encName = $db->addQuotes( $this->name );
+ $sql = "SELECT page_namespace,page_title,page_id FROM $page,$imagelinks WHERE page_id=il_from AND il_to=$encName $options";
+ $res = $db->query( $sql, __METHOD__ );
+
+ $retVal = array();
+ if ( $db->numRows( $res ) ) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( $titleObj = Title::makeTitle( $row->page_namespace, $row->page_title ) ) {
+ $linkCache->addGoodLinkObj( $row->page_id, $titleObj );
+ $retVal[] = $titleObj;
+ }
+ }
+ }
+ $db->freeResult( $res );
+ wfProfileOut( __METHOD__ );
+ return $retVal;
+ }
+
+ /**
+ * Retrive Exif data from the file and prune unrecognized tags
+ * and/or tags with invalid contents
+ *
+ * @param $filename
+ * @return array
+ */
+ private function retrieveExifData( $filename ) {
+ global $wgShowEXIF;
+
+ /*
+ if ( $this->getMimeType() !== "image/jpeg" )
+ return array();
+ */
+
+ if( $wgShowEXIF && file_exists( $filename ) ) {
+ $exif = new Exif( $filename );
+ return $exif->getFilteredData();
+ }
+
+ return array();
+ }
+
+ function getExifData() {
+ global $wgRequest;
+ if ( $this->metadata === '0' || $this->mime == 'image/vnd.djvu' )
+ return array();
+
+ $purge = $wgRequest->getVal( 'action' ) == 'purge';
+ $ret = unserialize( $this->metadata );
+
+ $oldver = isset( $ret['MEDIAWIKI_EXIF_VERSION'] ) ? $ret['MEDIAWIKI_EXIF_VERSION'] : 0;
+ $newver = Exif::version();
+
+ if ( !count( $ret ) || $purge || $oldver != $newver ) {
+ $this->purgeMetadataCache();
+ $this->updateExifData( $newver );
+ }
+ if ( isset( $ret['MEDIAWIKI_EXIF_VERSION'] ) )
+ unset( $ret['MEDIAWIKI_EXIF_VERSION'] );
+ $format = new FormatExif( $ret );
+
+ return $format->getFormattedData();
+ }
+
+ function updateExifData( $version ) {
+ if ( $this->getImagePath() === false ) # Not a local image
+ return;
+
+ # Get EXIF data from image
+ $exif = $this->retrieveExifData( $this->imagePath );
+ if ( count( $exif ) ) {
+ $exif['MEDIAWIKI_EXIF_VERSION'] = $version;
+ $this->metadata = serialize( $exif );
+ } else {
+ $this->metadata = '0';
+ }
+
+ # Update EXIF data in database
+ $dbw =& wfGetDB( DB_MASTER );
+
+ $this->checkDBSchema($dbw);
+
+ $dbw->update( 'image',
+ array( 'img_metadata' => $this->metadata ),
+ array( 'img_name' => $this->name ),
+ __METHOD__
+ );
+ }
+
+ /**
+ * Returns true if the image does not come from the shared
+ * image repository.
+ *
+ * @return bool
+ */
+ function isLocal() {
+ return !$this->fromSharedDirectory;
+ }
+
+ /**
+ * Was this image ever deleted from the wiki?
+ *
+ * @return bool
+ */
+ function wasDeleted() {
+ $title = Title::makeTitle( NS_IMAGE, $this->name );
+ return ( $title->isDeleted() > 0 );
+ }
+
+ /**
+ * Delete all versions of the image.
+ *
+ * Moves the files into an archive directory (or deletes them)
+ * and removes the database rows.
+ *
+ * Cache purging is done; logging is caller's responsibility.
+ *
+ * @param $reason
+ * @return true on success, false on some kind of failure
+ */
+ function delete( $reason ) {
+ $transaction = new FSTransaction();
+ $urlArr = array( $this->getURL() );
+
+ if( !FileStore::lock() ) {
+ wfDebug( __METHOD__.": failed to acquire file store lock, aborting\n" );
+ return false;
+ }
+
+ try {
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ // Delete old versions
+ $result = $dbw->select( 'oldimage',
+ array( 'oi_archive_name' ),
+ array( 'oi_name' => $this->name ) );
+
+ while( $row = $dbw->fetchObject( $result ) ) {
+ $oldName = $row->oi_archive_name;
+
+ $transaction->add( $this->prepareDeleteOld( $oldName, $reason ) );
+
+ // We'll need to purge this URL from caches...
+ $urlArr[] = wfImageArchiveUrl( $oldName );
+ }
+ $dbw->freeResult( $result );
+
+ // And the current version...
+ $transaction->add( $this->prepareDeleteCurrent( $reason ) );
+
+ $dbw->immediateCommit();
+ } catch( MWException $e ) {
+ wfDebug( __METHOD__.": db error, rolling back file transactions\n" );
+ $transaction->rollback();
+ FileStore::unlock();
+ throw $e;
+ }
+
+ wfDebug( __METHOD__.": deleted db items, applying file transactions\n" );
+ $transaction->commit();
+ FileStore::unlock();
+
+
+ // Update site_stats
+ $site_stats = $dbw->tableName( 'site_stats' );
+ $dbw->query( "UPDATE $site_stats SET ss_images=ss_images-1", __METHOD__ );
+
+ $this->purgeEverything( $urlArr );
+
+ return true;
+ }
+
+
+ /**
+ * Delete an old version of the image.
+ *
+ * Moves the file into an archive directory (or deletes it)
+ * and removes the database row.
+ *
+ * Cache purging is done; logging is caller's responsibility.
+ *
+ * @param $reason
+ * @throws MWException or FSException on database or filestore failure
+ * @return true on success, false on some kind of failure
+ */
+ function deleteOld( $archiveName, $reason ) {
+ $transaction = new FSTransaction();
+ $urlArr = array();
+
+ if( !FileStore::lock() ) {
+ wfDebug( __METHOD__.": failed to acquire file store lock, aborting\n" );
+ return false;
+ }
+
+ $transaction = new FSTransaction();
+ try {
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin();
+ $transaction->add( $this->prepareDeleteOld( $archiveName, $reason ) );
+ $dbw->immediateCommit();
+ } catch( MWException $e ) {
+ wfDebug( __METHOD__.": db error, rolling back file transaction\n" );
+ $transaction->rollback();
+ FileStore::unlock();
+ throw $e;
+ }
+
+ wfDebug( __METHOD__.": deleted db items, applying file transaction\n" );
+ $transaction->commit();
+ FileStore::unlock();
+
+ $this->purgeDescription();
+
+ // Squid purging
+ global $wgUseSquid;
+ if ( $wgUseSquid ) {
+ $urlArr = array(
+ wfImageArchiveUrl( $archiveName ),
+ );
+ wfPurgeSquidServers( $urlArr );
+ }
+ return true;
+ }
+
+ /**
+ * Delete the current version of a file.
+ * May throw a database error.
+ * @return true on success, false on failure
+ */
+ private function prepareDeleteCurrent( $reason ) {
+ return $this->prepareDeleteVersion(
+ $this->getFullPath(),
+ $reason,
+ 'image',
+ array(
+ 'fa_name' => 'img_name',
+ 'fa_archive_name' => 'NULL',
+ 'fa_size' => 'img_size',
+ 'fa_width' => 'img_width',
+ 'fa_height' => 'img_height',
+ 'fa_metadata' => 'img_metadata',
+ 'fa_bits' => 'img_bits',
+ 'fa_media_type' => 'img_media_type',
+ 'fa_major_mime' => 'img_major_mime',
+ 'fa_minor_mime' => 'img_minor_mime',
+ 'fa_description' => 'img_description',
+ 'fa_user' => 'img_user',
+ 'fa_user_text' => 'img_user_text',
+ 'fa_timestamp' => 'img_timestamp' ),
+ array( 'img_name' => $this->name ),
+ __METHOD__ );
+ }
+
+ /**
+ * Delete a given older version of a file.
+ * May throw a database error.
+ * @return true on success, false on failure
+ */
+ private function prepareDeleteOld( $archiveName, $reason ) {
+ $oldpath = wfImageArchiveDir( $this->name ) .
+ DIRECTORY_SEPARATOR . $archiveName;
+ return $this->prepareDeleteVersion(
+ $oldpath,
+ $reason,
+ 'oldimage',
+ array(
+ 'fa_name' => 'oi_name',
+ 'fa_archive_name' => 'oi_archive_name',
+ 'fa_size' => 'oi_size',
+ 'fa_width' => 'oi_width',
+ 'fa_height' => 'oi_height',
+ 'fa_metadata' => 'NULL',
+ 'fa_bits' => 'oi_bits',
+ 'fa_media_type' => 'NULL',
+ 'fa_major_mime' => 'NULL',
+ 'fa_minor_mime' => 'NULL',
+ 'fa_description' => 'oi_description',
+ 'fa_user' => 'oi_user',
+ 'fa_user_text' => 'oi_user_text',
+ 'fa_timestamp' => 'oi_timestamp' ),
+ array(
+ 'oi_name' => $this->name,
+ 'oi_archive_name' => $archiveName ),
+ __METHOD__ );
+ }
+
+ /**
+ * Do the dirty work of backing up an image row and its file
+ * (if $wgSaveDeletedFiles is on) and removing the originals.
+ *
+ * Must be run while the file store is locked and a database
+ * transaction is open to avoid race conditions.
+ *
+ * @return FSTransaction
+ */
+ private function prepareDeleteVersion( $path, $reason, $table, $fieldMap, $where, $fname ) {
+ global $wgUser, $wgSaveDeletedFiles;
+
+ // Dupe the file into the file store
+ if( file_exists( $path ) ) {
+ if( $wgSaveDeletedFiles ) {
+ $group = 'deleted';
+
+ $store = FileStore::get( $group );
+ $key = FileStore::calculateKey( $path, $this->extension );
+ $transaction = $store->insert( $key, $path,
+ FileStore::DELETE_ORIGINAL );
+ } else {
+ $group = null;
+ $key = null;
+ $transaction = FileStore::deleteFile( $path );
+ }
+ } else {
+ wfDebug( __METHOD__." deleting already-missing '$path'; moving on to database\n" );
+ $group = null;
+ $key = null;
+ $transaction = new FSTransaction(); // empty
+ }
+
+ if( $transaction === false ) {
+ // Fail to restore?
+ wfDebug( __METHOD__.": import to file store failed, aborting\n" );
+ throw new MWException( "Could not archive and delete file $path" );
+ return false;
+ }
+
+ $dbw = wfGetDB( DB_MASTER );
+ $storageMap = array(
+ 'fa_storage_group' => $dbw->addQuotes( $group ),
+ 'fa_storage_key' => $dbw->addQuotes( $key ),
+
+ 'fa_deleted_user' => $dbw->addQuotes( $wgUser->getId() ),
+ 'fa_deleted_timestamp' => $dbw->timestamp(),
+ 'fa_deleted_reason' => $dbw->addQuotes( $reason ) );
+ $allFields = array_merge( $storageMap, $fieldMap );
+
+ try {
+ if( $wgSaveDeletedFiles ) {
+ $dbw->insertSelect( 'filearchive', $table, $allFields, $where, $fname );
+ }
+ $dbw->delete( $table, $where, $fname );
+ } catch( DBQueryError $e ) {
+ // Something went horribly wrong!
+ // Leave the file as it was...
+ wfDebug( __METHOD__.": database error, rolling back file transaction\n" );
+ $transaction->rollback();
+ throw $e;
+ }
+
+ return $transaction;
+ }
+
+ /**
+ * Restore all or specified deleted revisions to the given file.
+ * Permissions and logging are left to the caller.
+ *
+ * May throw database exceptions on error.
+ *
+ * @param $versions set of record ids of deleted items to restore,
+ * or empty to restore all revisions.
+ * @return the number of file revisions restored if successful,
+ * or false on failure
+ */
+ function restore( $versions=array() ) {
+ if( !FileStore::lock() ) {
+ wfDebug( __METHOD__." could not acquire filestore lock\n" );
+ return false;
+ }
+
+ $transaction = new FSTransaction();
+ try {
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ // Re-confirm whether this image presently exists;
+ // if no we'll need to create an image record for the
+ // first item we restore.
+ $exists = $dbw->selectField( 'image', '1',
+ array( 'img_name' => $this->name ),
+ __METHOD__ );
+
+ // Fetch all or selected archived revisions for the file,
+ // sorted from the most recent to the oldest.
+ $conditions = array( 'fa_name' => $this->name );
+ if( $versions ) {
+ $conditions['fa_id'] = $versions;
+ }
+
+ $result = $dbw->select( 'filearchive', '*',
+ $conditions,
+ __METHOD__,
+ array( 'ORDER BY' => 'fa_timestamp DESC' ) );
+
+ if( $dbw->numRows( $result ) < count( $versions ) ) {
+ // There's some kind of conflict or confusion;
+ // we can't restore everything we were asked to.
+ wfDebug( __METHOD__.": couldn't find requested items\n" );
+ $dbw->rollback();
+ FileStore::unlock();
+ return false;
+ }
+
+ if( $dbw->numRows( $result ) == 0 ) {
+ // Nothing to do.
+ wfDebug( __METHOD__.": nothing to do\n" );
+ $dbw->rollback();
+ FileStore::unlock();
+ return true;
+ }
+
+ $revisions = 0;
+ while( $row = $dbw->fetchObject( $result ) ) {
+ $revisions++;
+ $store = FileStore::get( $row->fa_storage_group );
+ if( !$store ) {
+ wfDebug( __METHOD__.": skipping row with no file.\n" );
+ continue;
+ }
+
+ if( $revisions == 1 && !$exists ) {
+ $destDir = wfImageDir( $row->fa_name );
+ if ( !is_dir( $destDir ) ) {
+ wfMkdirParents( $destDir );
+ }
+ $destPath = $destDir . DIRECTORY_SEPARATOR . $row->fa_name;
+
+ // We may have to fill in data if this was originally
+ // an archived file revision.
+ if( is_null( $row->fa_metadata ) ) {
+ $tempFile = $store->filePath( $row->fa_storage_key );
+ $metadata = serialize( $this->retrieveExifData( $tempFile ) );
+
+ $magic = MimeMagic::singleton();
+ $mime = $magic->guessMimeType( $tempFile, true );
+ $media_type = $magic->getMediaType( $tempFile, $mime );
+ list( $major_mime, $minor_mime ) = self::splitMime( $mime );
+ } else {
+ $metadata = $row->fa_metadata;
+ $major_mime = $row->fa_major_mime;
+ $minor_mime = $row->fa_minor_mime;
+ $media_type = $row->fa_media_type;
+ }
+
+ $table = 'image';
+ $fields = array(
+ 'img_name' => $row->fa_name,
+ 'img_size' => $row->fa_size,
+ 'img_width' => $row->fa_width,
+ 'img_height' => $row->fa_height,
+ 'img_metadata' => $metadata,
+ 'img_bits' => $row->fa_bits,
+ 'img_media_type' => $media_type,
+ 'img_major_mime' => $major_mime,
+ 'img_minor_mime' => $minor_mime,
+ 'img_description' => $row->fa_description,
+ 'img_user' => $row->fa_user,
+ 'img_user_text' => $row->fa_user_text,
+ 'img_timestamp' => $row->fa_timestamp );
+ } else {
+ $archiveName = $row->fa_archive_name;
+ if( $archiveName == '' ) {
+ // This was originally a current version; we
+ // have to devise a new archive name for it.
+ // Format is <timestamp of archiving>!<name>
+ $archiveName =
+ wfTimestamp( TS_MW, $row->fa_deleted_timestamp ) .
+ '!' . $row->fa_name;
+ }
+ $destDir = wfImageArchiveDir( $row->fa_name );
+ if ( !is_dir( $destDir ) ) {
+ wfMkdirParents( $destDir );
+ }
+ $destPath = $destDir . DIRECTORY_SEPARATOR . $archiveName;
+
+ $table = 'oldimage';
+ $fields = array(
+ 'oi_name' => $row->fa_name,
+ 'oi_archive_name' => $archiveName,
+ 'oi_size' => $row->fa_size,
+ 'oi_width' => $row->fa_width,
+ 'oi_height' => $row->fa_height,
+ 'oi_bits' => $row->fa_bits,
+ 'oi_description' => $row->fa_description,
+ 'oi_user' => $row->fa_user,
+ 'oi_user_text' => $row->fa_user_text,
+ 'oi_timestamp' => $row->fa_timestamp );
+ }
+
+ $dbw->insert( $table, $fields, __METHOD__ );
+ /// @fixme this delete is not totally safe, potentially
+ $dbw->delete( 'filearchive',
+ array( 'fa_id' => $row->fa_id ),
+ __METHOD__ );
+
+ // Check if any other stored revisions use this file;
+ // if so, we shouldn't remove the file from the deletion
+ // archives so they will still work.
+ $useCount = $dbw->selectField( 'filearchive',
+ 'COUNT(*)',
+ array(
+ 'fa_storage_group' => $row->fa_storage_group,
+ 'fa_storage_key' => $row->fa_storage_key ),
+ __METHOD__ );
+ if( $useCount == 0 ) {
+ wfDebug( __METHOD__.": nothing else using {$row->fa_storage_key}, will deleting after\n" );
+ $flags = FileStore::DELETE_ORIGINAL;
+ } else {
+ $flags = 0;
+ }
+
+ $transaction->add( $store->export( $row->fa_storage_key,
+ $destPath, $flags ) );
+ }
+
+ $dbw->immediateCommit();
+ } catch( MWException $e ) {
+ wfDebug( __METHOD__." caught error, aborting\n" );
+ $transaction->rollback();
+ throw $e;
+ }
+
+ $transaction->commit();
+ FileStore::unlock();
+
+ if( $revisions > 0 ) {
+ if( !$exists ) {
+ wfDebug( __METHOD__." restored $revisions items, creating a new current\n" );
+
+ // Update site_stats
+ $site_stats = $dbw->tableName( 'site_stats' );
+ $dbw->query( "UPDATE $site_stats SET ss_images=ss_images+1", __METHOD__ );
+
+ $this->purgeEverything();
+ } else {
+ wfDebug( __METHOD__." restored $revisions as archived versions\n" );
+ $this->purgeDescription();
+ }
+ }
+
+ return $revisions;
+ }
+
+ /**
+ * Select a page from a multipage document. Determines the page used for
+ * rendering thumbnails.
+ *
+ * @param $page Integer: page number, starting with 1
+ */
+ function selectPage( $page ) {
+ wfDebug( __METHOD__." selecting page $page \n" );
+ $this->page = $page;
+ if ( ! $this->dataLoaded ) {
+ $this->load();
+ }
+ if ( ! isset( $this->multiPageXML ) ) {
+ $this->initializeMultiPageXML();
+ }
+ $o = $this->multiPageXML->BODY[0]->OBJECT[$page-1];
+ $this->height = intval( $o['height'] );
+ $this->width = intval( $o['width'] );
+ }
+
+ function initializeMultiPageXML() {
+ #
+ # Check for files uploaded prior to DJVU support activation
+ # They have a '0' in their metadata field.
+ #
+ if ( $this->metadata == '0' || $this->metadata == '' ) {
+ $deja = new DjVuImage( $this->imagePath );
+ $this->metadata = $deja->retrieveMetaData();
+ $this->purgeMetadataCache();
+
+ # Update metadata in the database
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'image',
+ array( 'img_metadata' => $this->metadata ),
+ array( 'img_name' => $this->name ),
+ __METHOD__
+ );
+ }
+ wfSuppressWarnings();
+ $this->multiPageXML = new SimpleXMLElement( $this->metadata );
+ wfRestoreWarnings();
+ }
+
+ /**
+ * Returns 'true' if this image is a multipage document, e.g. a DJVU
+ * document.
+ *
+ * @return Bool
+ */
+ function isMultipage() {
+ return ( $this->mime == 'image/vnd.djvu' );
+ }
+
+ /**
+ * Returns the number of pages of a multipage document, or NULL for
+ * documents which aren't multipage documents
+ */
+ function pageCount() {
+ if ( ! $this->isMultipage() ) {
+ return null;
+ }
+ if ( ! isset( $this->multiPageXML ) ) {
+ $this->initializeMultiPageXML();
+ }
+ return count( $this->multiPageXML->xpath( '//OBJECT' ) );
+ }
+
+} //class
+
+/**
+ * Wrapper class for thumbnail images
+ * @package MediaWiki
+ */
+class ThumbnailImage {
+ /**
+ * @param string $path Filesystem path to the thumb
+ * @param string $url URL path to the thumb
+ * @private
+ */
+ function ThumbnailImage( $url, $width, $height, $path = false ) {
+ $this->url = $url;
+ $this->width = round( $width );
+ $this->height = round( $height );
+ # These should be integers when they get here.
+ # If not, there's a bug somewhere. But let's at
+ # least produce valid HTML code regardless.
+ $this->path = $path;
+ }
+
+ /**
+ * @return string The thumbnail URL
+ */
+ function getUrl() {
+ return $this->url;
+ }
+
+ /**
+ * Return HTML <img ... /> tag for the thumbnail, will include
+ * width and height attributes and a blank alt text (as required).
+ *
+ * You can set or override additional attributes by passing an
+ * associative array of name => data pairs. The data will be escaped
+ * for HTML output, so should be in plaintext.
+ *
+ * @param array $attribs
+ * @return string
+ * @public
+ */
+ function toHtml( $attribs = array() ) {
+ $attribs['src'] = $this->url;
+ $attribs['width'] = $this->width;
+ $attribs['height'] = $this->height;
+ if( !isset( $attribs['alt'] ) ) $attribs['alt'] = '';
+
+ $html = '<img ';
+ foreach( $attribs as $name => $data ) {
+ $html .= $name . '="' . htmlspecialchars( $data ) . '" ';
+ }
+ $html .= '/>';
+ return $html;
+ }
+
+}
+
+?>
diff --git a/includes/ImageFunctions.php b/includes/ImageFunctions.php
new file mode 100644
index 000000000000..931fdff177ac
--- /dev/null
+++ b/includes/ImageFunctions.php
@@ -0,0 +1,259 @@
+<?php
+
+/**
+ * Returns the image directory of an image
+ * The result is an absolute path.
+ *
+ * This function is called from thumb.php before Setup.php is included
+ *
+ * @param $fname String: file name of the image file.
+ * @public
+ */
+function wfImageDir( $fname ) {
+ global $wgUploadDirectory, $wgHashedUploadDirectory;
+
+ if (!$wgHashedUploadDirectory) { return $wgUploadDirectory; }
+
+ $hash = md5( $fname );
+ $dest = $wgUploadDirectory . '/' . $hash{0} . '/' . substr( $hash, 0, 2 );
+
+ return $dest;
+}
+
+/**
+ * Returns the image directory of an image's thubnail
+ * The result is an absolute path.
+ *
+ * This function is called from thumb.php before Setup.php is included
+ *
+ * @param $fname String: file name of the original image file
+ * @param $shared Boolean: (optional) use the shared upload directory (default: 'false').
+ * @public
+ */
+function wfImageThumbDir( $fname, $shared = false ) {
+ $base = wfImageArchiveDir( $fname, 'thumb', $shared );
+ if ( Image::isHashed( $shared ) ) {
+ $dir = "$base/$fname";
+ } else {
+ $dir = $base;
+ }
+
+ return $dir;
+}
+
+/**
+ * Old thumbnail directory, kept for conversion
+ */
+function wfDeprecatedThumbDir( $thumbName , $subdir='thumb', $shared=false) {
+ return wfImageArchiveDir( $thumbName, $subdir, $shared );
+}
+
+/**
+ * Returns the image directory of an image's old version
+ * The result is an absolute path.
+ *
+ * This function is called from thumb.php before Setup.php is included
+ *
+ * @param $fname String: file name of the thumbnail file, including file size prefix.
+ * @param $subdir String: subdirectory of the image upload directory that should be used for storing the old version. Default is 'archive'.
+ * @param $shared Boolean use the shared upload directory (only relevant for other functions which call this one). Default is 'false'.
+ * @public
+ */
+function wfImageArchiveDir( $fname , $subdir='archive', $shared=false ) {
+ global $wgUploadDirectory, $wgHashedUploadDirectory;
+ global $wgSharedUploadDirectory, $wgHashedSharedUploadDirectory;
+ $dir = $shared ? $wgSharedUploadDirectory : $wgUploadDirectory;
+ $hashdir = $shared ? $wgHashedSharedUploadDirectory : $wgHashedUploadDirectory;
+ if (!$hashdir) { return $dir.'/'.$subdir; }
+ $hash = md5( $fname );
+
+ return $dir.'/'.$subdir.'/'.$hash[0].'/'.substr( $hash, 0, 2 );
+}
+
+
+/*
+ * Return the hash path component of an image path (URL or filesystem),
+ * e.g. "/3/3c/", or just "/" if hashing is not used.
+ *
+ * @param $dbkey The filesystem / database name of the file
+ * @param $fromSharedDirectory Use the shared file repository? It may
+ * use different hash settings from the local one.
+ */
+function wfGetHashPath ( $dbkey, $fromSharedDirectory = false ) {
+ if( Image::isHashed( $fromSharedDirectory ) ) {
+ $hash = md5($dbkey);
+ return '/' . $hash{0} . '/' . substr( $hash, 0, 2 ) . '/';
+ } else {
+ return '/';
+ }
+}
+
+/**
+ * Returns the image URL of an image's old version
+ *
+ * @param $name String: file name of the image file
+ * @param $subdir String: (optional) subdirectory of the image upload directory that is used by the old version. Default is 'archive'
+ * @public
+ */
+function wfImageArchiveUrl( $name, $subdir='archive' ) {
+ global $wgUploadPath, $wgHashedUploadDirectory;
+
+ if ($wgHashedUploadDirectory) {
+ $hash = md5( substr( $name, 15) );
+ $url = $wgUploadPath.'/'.$subdir.'/' . $hash{0} . '/' .
+ substr( $hash, 0, 2 ) . '/'.$name;
+ } else {
+ $url = $wgUploadPath.'/'.$subdir.'/'.$name;
+ }
+ return wfUrlencode($url);
+}
+
+/**
+ * Return a rounded pixel equivalent for a labeled CSS/SVG length.
+ * http://www.w3.org/TR/SVG11/coords.html#UnitIdentifiers
+ *
+ * @param $length String: CSS/SVG length.
+ * @return Integer: length in pixels
+ */
+function wfScaleSVGUnit( $length ) {
+ static $unitLength = array(
+ 'px' => 1.0,
+ 'pt' => 1.25,
+ 'pc' => 15.0,
+ 'mm' => 3.543307,
+ 'cm' => 35.43307,
+ 'in' => 90.0,
+ '' => 1.0, // "User units" pixels by default
+ '%' => 2.0, // Fake it!
+ );
+ $matches = array();
+ if( preg_match( '/^(\d+(?:\.\d+)?)(em|ex|px|pt|pc|cm|mm|in|%|)$/', $length, $matches ) ) {
+ $length = floatval( $matches[1] );
+ $unit = $matches[2];
+ return round( $length * $unitLength[$unit] );
+ } else {
+ // Assume pixels
+ return round( floatval( $length ) );
+ }
+}
+
+/**
+ * Compatible with PHP getimagesize()
+ * @todo support gzipped SVGZ
+ * @todo check XML more carefully
+ * @todo sensible defaults
+ *
+ * @param $filename String: full name of the file (passed to php fopen()).
+ * @return array
+ */
+function wfGetSVGsize( $filename ) {
+ $width = 256;
+ $height = 256;
+
+ // Read a chunk of the file
+ $f = fopen( $filename, "rt" );
+ if( !$f ) return false;
+ $chunk = fread( $f, 4096 );
+ fclose( $f );
+
+ // Uber-crappy hack! Run through a real XML parser.
+ $matches = array();
+ if( !preg_match( '/<svg\s*([^>]*)\s*>/s', $chunk, $matches ) ) {
+ return false;
+ }
+ $tag = $matches[1];
+ if( preg_match( '/\bwidth\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) {
+ $width = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) );
+ }
+ if( preg_match( '/\bheight\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) {
+ $height = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) );
+ }
+
+ return array( $width, $height, 'SVG',
+ "width=\"$width\" height=\"$height\"" );
+}
+
+/**
+ * Determine if an image exists on the 'bad image list'.
+ *
+ * The format of MediaWiki:Bad_image_list is as follows:
+ * * Only list items (lines starting with "*") are considered
+ * * The first link on a line must be a link to a bad image
+ * * Any subsequent links on the same line are considered to be exceptions,
+ * i.e. articles where the image may occur inline.
+ *
+ * @param string $name the image name to check
+ * @param Title $contextTitle The page on which the image occurs, if known
+ * @return bool
+ */
+function wfIsBadImage( $name, $contextTitle = false ) {
+ static $badImages = false;
+ wfProfileIn( __METHOD__ );
+
+ # Run the extension hook
+ $bad = false;
+ if( !wfRunHooks( 'BadImage', array( $name, &$bad ) ) ) {
+ wfProfileOut( __METHOD__ );
+ return $bad;
+ }
+
+ if( !$badImages ) {
+ # Build the list now
+ $badImages = array();
+ $lines = explode( "\n", wfMsgForContentNoTrans( 'bad_image_list' ) );
+ foreach( $lines as $line ) {
+ # List items only
+ if ( substr( $line, 0, 1 ) !== '*' ) {
+ continue;
+ }
+
+ # Find all links
+ $m = array();
+ if ( !preg_match_all( '/\[\[:?(.*?)\]\]/', $line, $m ) ) {
+ continue;
+ }
+
+ $exceptions = array();
+ $imageDBkey = false;
+ foreach ( $m[1] as $i => $titleText ) {
+ $title = Title::newFromText( $titleText );
+ if ( !is_null( $title ) ) {
+ if ( $i == 0 ) {
+ $imageDBkey = $title->getDBkey();
+ } else {
+ $exceptions[$title->getPrefixedDBkey()] = true;
+ }
+ }
+ }
+
+ if ( $imageDBkey !== false ) {
+ $badImages[$imageDBkey] = $exceptions;
+ }
+ }
+ }
+
+ $contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() : false;
+ $bad = isset( $badImages[$name] ) && !isset( $badImages[$name][$contextKey] );
+ wfProfileOut( __METHOD__ );
+ return $bad;
+}
+
+/**
+ * Calculate the largest thumbnail width for a given original file size
+ * such that the thumbnail's height is at most $maxHeight.
+ * @param $boxWidth Integer Width of the thumbnail box.
+ * @param $boxHeight Integer Height of the thumbnail box.
+ * @param $maxHeight Integer Maximum height expected for the thumbnail.
+ * @return Integer.
+ */
+function wfFitBoxWidth( $boxWidth, $boxHeight, $maxHeight ) {
+ $idealWidth = $boxWidth * $maxHeight / $boxHeight;
+ $roundedUp = ceil( $idealWidth );
+ if( round( $roundedUp * $boxHeight / $boxWidth ) > $maxHeight )
+ return floor( $idealWidth );
+ else
+ return $roundedUp;
+}
+
+
+?>
diff --git a/includes/ImageGallery.php b/includes/ImageGallery.php
new file mode 100644
index 000000000000..9d58b7f6d4b7
--- /dev/null
+++ b/includes/ImageGallery.php
@@ -0,0 +1,226 @@
+<?php
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+/**
+ * @package MediaWiki
+ */
+
+/**
+ * Image gallery
+ *
+ * Add images to the gallery using add(), then render that list to HTML using toHTML().
+ *
+ * @package MediaWiki
+ */
+class ImageGallery
+{
+ var $mImages, $mShowBytes, $mShowFilename;
+ var $mCaption = false;
+ var $mSkin = false;
+
+ /**
+ * Is the gallery on a wiki page (i.e. not a special page)
+ */
+ var $mParsing;
+
+ /**
+ * Create a new image gallery object.
+ */
+ function ImageGallery( ) {
+ $this->mImages = array();
+ $this->mShowBytes = true;
+ $this->mShowFilename = true;
+ $this->mParsing = false;
+ }
+
+ /**
+ * Set the "parse" bit so we know to hide "bad" images
+ */
+ function setParsing( $val = true ) {
+ $this->mParsing = $val;
+ }
+
+ /**
+ * Set the caption (as plain text)
+ *
+ * @param $caption Caption
+ */
+ function setCaption( $caption ) {
+ $this->mCaption = htmlspecialchars( $caption );
+ }
+
+ /**
+ * Set the caption (as HTML)
+ *
+ * @param $caption Caption
+ */
+ function setCaptionHtml( $caption ) {
+ $this->mCaption = $caption;
+ }
+
+ /**
+ * Instruct the class to use a specific skin for rendering
+ *
+ * @param $skin Skin object
+ */
+ function useSkin( $skin ) {
+ $this->mSkin =& $skin;
+ }
+
+ /**
+ * Return the skin that should be used
+ *
+ * @return Skin object
+ */
+ function getSkin() {
+ if( !$this->mSkin ) {
+ global $wgUser;
+ $skin =& $wgUser->getSkin();
+ } else {
+ $skin =& $this->mSkin;
+ }
+ return $skin;
+ }
+
+ /**
+ * Add an image to the gallery.
+ *
+ * @param $image Image object that is added to the gallery
+ * @param $html String: additional HTML text to be shown. The name and size of the image are always shown.
+ */
+ function add( $image, $html='' ) {
+ $this->mImages[] = array( &$image, $html );
+ wfDebug( "ImageGallery::add " . $image->getName() . "\n" );
+ }
+
+ /**
+ * Add an image at the beginning of the gallery.
+ *
+ * @param $image Image object that is added to the gallery
+ * @param $html String: Additional HTML text to be shown. The name and size of the image are always shown.
+ */
+ function insert( $image, $html='' ) {
+ array_unshift( $this->mImages, array( &$image, $html ) );
+ }
+
+
+ /**
+ * isEmpty() returns true if the gallery contains no images
+ */
+ function isEmpty() {
+ return empty( $this->mImages );
+ }
+
+ /**
+ * Enable/Disable showing of the file size of an image in the gallery.
+ * Enabled by default.
+ *
+ * @param $f Boolean: set to false to disable.
+ */
+ function setShowBytes( $f ) {
+ $this->mShowBytes = ( $f == true);
+ }
+
+ /**
+ * Enable/Disable showing of the filename of an image in the gallery.
+ * Enabled by default.
+ *
+ * @param $f Boolean: set to false to disable.
+ */
+ function setShowFilename( $f ) {
+ $this->mShowFilename = ( $f == true);
+ }
+
+ /**
+ * Return a HTML representation of the image gallery
+ *
+ * For each image in the gallery, display
+ * - a thumbnail
+ * - the image name
+ * - the additional text provided when adding the image
+ * - the size of the image
+ *
+ */
+ function toHTML() {
+ global $wgLang, $wgGenerateThumbnailOnParse;
+
+ $sk = $this->getSkin();
+
+ $s = '<table class="gallery" cellspacing="0" cellpadding="0">';
+ if( $this->mCaption )
+ $s .= '<td class="galleryheader" colspan="4"><big>' . $this->mCaption . '</big></td>';
+
+ $i = 0;
+ foreach ( $this->mImages as $pair ) {
+ $img =& $pair[0];
+ $text = $pair[1];
+
+ $nt = $img->getTitle();
+
+ if( $nt->getNamespace() != NS_IMAGE ) {
+ # We're dealing with a non-image, spit out the name and be done with it.
+ $thumbhtml = '<div style="height: 152px;">' . htmlspecialchars( $nt->getText() ) . '</div>';
+ }
+ else if( $this->mParsing && wfIsBadImage( $nt->getDBkey() ) ) {
+ # The image is blacklisted, just show it as a text link.
+ $thumbhtml = '<div style="height: 152px;">'
+ . $sk->makeKnownLinkObj( $nt, htmlspecialchars( $nt->getText() ) ) . '</div>';
+ } else if( !( $thumb = $img->getThumbnail( 120, 120, $wgGenerateThumbnailOnParse ) ) ) {
+ # Error generating thumbnail.
+ $thumbhtml = '<div style="height: 152px;">'
+ . htmlspecialchars( $img->getLastError() ) . '</div>';
+ }
+ else {
+ $vpad = floor( ( 150 - $thumb->height ) /2 ) - 2;
+ $thumbhtml = '<div class="thumb" style="padding: ' . $vpad . 'px 0;">'
+ . $sk->makeKnownLinkObj( $nt, $thumb->toHtml() ) . '</div>';
+ }
+
+ //TODO
+ //$ul = $sk->makeLink( $wgContLang->getNsText( Namespace::getUser() ) . ":{$ut}", $ut );
+
+ if( $this->mShowBytes ) {
+ if( $img->exists() ) {
+ $nb = wfMsgExt( 'nbytes', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $img->getSize() ) );
+ } else {
+ $nb = wfMsgHtml( 'filemissing' );
+ }
+ $nb = "$nb<br />\n";
+ } else {
+ $nb = '';
+ }
+
+ $textlink = $this->mShowFilename ?
+ $sk->makeKnownLinkObj( $nt, htmlspecialchars( $wgLang->truncate( $nt->getText(), 20, '...' ) ) ) . "<br />\n" :
+ '' ;
+
+ # ATTENTION: The newline after <div class="gallerytext"> is needed to accommodate htmltidy which
+ # in version 4.8.6 generated crackpot html in its absence, see:
+ # http://bugzilla.wikimedia.org/show_bug.cgi?id=1765 -Ævar
+
+ $s .= ($i%4==0) ? '<tr>' : '';
+ $s .= '<td><div class="gallerybox">' . $thumbhtml
+ . '<div class="gallerytext">' . "\n" . $textlink . $text . $nb
+ . "</div></div></td>\n";
+ $s .= ($i%4==3) ? '</tr>' : '';
+ $i++;
+ }
+ if( $i %4 != 0 ) {
+ $s .= "</tr>\n";
+ }
+ $s .= '</table>';
+
+ return $s;
+ }
+
+ /**
+ * @return int Number of images in the gallery
+ */
+ public function count() {
+ return count( $this->mImages );
+ }
+
+} //class
+?>
diff --git a/includes/ImagePage.php b/includes/ImagePage.php
new file mode 100644
index 000000000000..43b9913073b5
--- /dev/null
+++ b/includes/ImagePage.php
@@ -0,0 +1,770 @@
+<?php
+/**
+ * @package MediaWiki
+ */
+
+/**
+ *
+ */
+if( !defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+/**
+ * Special handling for image description pages
+ * @package MediaWiki
+ */
+class ImagePage extends Article {
+
+ /* private */ var $img; // Image object this page is shown for
+ var $mExtraDescription = false;
+
+ /**
+ * Handler for action=render
+ * Include body text only; none of the image extras
+ */
+ function render() {
+ global $wgOut;
+ $wgOut->setArticleBodyOnly( true );
+ $wgOut->addSecondaryWikitext( $this->getContent() );
+ }
+
+ function view() {
+ global $wgOut, $wgShowEXIF;
+
+ $this->img = new Image( $this->mTitle );
+
+ if( $this->mTitle->getNamespace() == NS_IMAGE ) {
+ if ($wgShowEXIF && $this->img->exists()) {
+ $exif = $this->img->getExifData();
+ $showmeta = count($exif) ? true : false;
+ } else {
+ $exif = false;
+ $showmeta = false;
+ }
+
+ if ($this->img->exists())
+ $wgOut->addHTML($this->showTOC($showmeta));
+
+ $this->openShowImage();
+
+ # No need to display noarticletext, we use our own message, output in openShowImage()
+ if( $this->getID() ) {
+ Article::view();
+ } else {
+ # Just need to set the right headers
+ $wgOut->setArticleFlag( true );
+ $wgOut->setRobotpolicy( 'index,follow' );
+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ $this->viewUpdates();
+ }
+
+ # Show shared description, if needed
+ if( $this->mExtraDescription ) {
+ $fol = wfMsg( 'shareddescriptionfollows' );
+ if( $fol != '-' ) {
+ $wgOut->addWikiText( $fol );
+ }
+ $wgOut->addHTML( '<div id="shared-image-desc">' . $this->mExtraDescription . '</div>' );
+ }
+
+ $this->closeShowImage();
+ $this->imageHistory();
+ $this->imageLinks();
+ if( $exif ) {
+ global $wgStylePath, $wgStyleVersion;
+ $expand = htmlspecialchars( wfEscapeJsString( wfMsg( 'metadata-expand' ) ) );
+ $collapse = htmlspecialchars( wfEscapeJsString( wfMsg( 'metadata-collapse' ) ) );
+ $wgOut->addHTML( "<h2 id=\"metadata\">" . wfMsgHtml( 'metadata' ) . "</h2>\n" );
+ $wgOut->addWikiText( $this->makeMetadataTable( $exif ) );
+ $wgOut->addHTML(
+ "<script type=\"text/javascript\" src=\"$wgStylePath/common/metadata.js?$wgStyleVersion\"></script>\n" .
+ "<script type=\"text/javascript\">attachMetadataToggle('mw_metadata', '$expand', '$collapse');</script>\n" );
+ }
+ } else {
+ Article::view();
+ }
+ }
+
+ /**
+ * Create the TOC
+ *
+ * @access private
+ *
+ * @param bool $metadata Whether or not to show the metadata link
+ * @return string
+ */
+ function showTOC( $metadata ) {
+ global $wgLang;
+ $r = '<ul id="filetoc">
+ <li><a href="#file">' . $wgLang->getNsText( NS_IMAGE ) . '</a></li>
+ <li><a href="#filehistory">' . wfMsgHtml( 'imghistory' ) . '</a></li>
+ <li><a href="#filelinks">' . wfMsgHtml( 'imagelinks' ) . '</a></li>' .
+ ($metadata ? '<li><a href="#metadata">' . wfMsgHtml( 'metadata' ) . '</a></li>' : '') . '
+ </ul>';
+ return $r;
+ }
+
+ /**
+ * Make a table with metadata to be shown in the output page.
+ *
+ * @access private
+ *
+ * @param array $exif The array containing the EXIF data
+ * @return string
+ */
+ function makeMetadataTable( $exif ) {
+ $r = wfMsg( 'metadata-help' ) . "\n\n";
+ $r .= "{| id=mw_metadata class=mw_metadata\n";
+ $visibleFields = $this->visibleMetadataFields();
+ foreach( $exif as $k => $v ) {
+ $tag = strtolower( $k );
+ $msg = wfMsg( "exif-$tag" );
+ $class = "exif-$tag";
+ if( !in_array( $tag, $visibleFields ) ) {
+ $class .= ' collapsable';
+ }
+ $r .= "|- class=\"$class\"\n";
+ $r .= "!| $msg\n";
+ $r .= "|| $v\n";
+ }
+ $r .= '|}';
+ return $r;
+ }
+
+ /**
+ * Get a list of EXIF metadata items which should be displayed when
+ * the metadata table is collapsed.
+ *
+ * @return array of strings
+ * @access private
+ */
+ function visibleMetadataFields() {
+ $fields = array();
+ $lines = explode( "\n", wfMsgForContent( 'metadata-fields' ) );
+ foreach( $lines as $line ) {
+ $matches = array();
+ if( preg_match( '/^\\*\s*(.*?)\s*$/', $line, $matches ) ) {
+ $fields[] = $matches[1];
+ }
+ }
+ return $fields;
+ }
+
+ /**
+ * Overloading Article's getContent method.
+ *
+ * Omit noarticletext if sharedupload; text will be fetched from the
+ * shared upload server if possible.
+ */
+ function getContent() {
+ if( $this->img && $this->img->fromSharedDirectory && 0 == $this->getID() ) {
+ return '';
+ }
+ return Article::getContent();
+ }
+
+ function openShowImage() {
+ global $wgOut, $wgUser, $wgImageLimits, $wgRequest, $wgLang;
+ global $wgUseImageResize, $wgGenerateThumbnailOnParse;
+
+ $full_url = $this->img->getURL();
+ $anchoropen = '';
+ $anchorclose = '';
+ $sizeSel = intval( $wgUser->getOption( 'imagesize') );
+
+ if( !isset( $wgImageLimits[$sizeSel] ) ) {
+ $sizeSel = User::getDefaultOption( 'imagesize' );
+ }
+ $max = $wgImageLimits[$sizeSel];
+ $maxWidth = $max[0];
+ $maxHeight = $max[1];
+ $sk = $wgUser->getSkin();
+
+ if ( $this->img->exists() ) {
+ # image
+ $page = $wgRequest->getIntOrNull( 'page' );
+ if ( ! is_null( $page ) ) {
+ $this->img->selectPage( $page );
+ } else {
+ $page = 1;
+ }
+ $width = $this->img->getWidth();
+ $height = $this->img->getHeight();
+ $showLink = false;
+
+ if ( $this->img->allowInlineDisplay() and $width and $height) {
+ # image
+
+ # "Download high res version" link below the image
+ $msg = wfMsgHtml('showbigimage', $width, $height, intval( $this->img->getSize()/1024 ) );
+
+ # We'll show a thumbnail of this image
+ if ( $width > $maxWidth || $height > $maxHeight ) {
+ # Calculate the thumbnail size.
+ # First case, the limiting factor is the width, not the height.
+ if ( $width / $height >= $maxWidth / $maxHeight ) {
+ $height = round( $height * $maxWidth / $width);
+ $width = $maxWidth;
+ # Note that $height <= $maxHeight now.
+ } else {
+ $newwidth = floor( $width * $maxHeight / $height);
+ $height = round( $height * $newwidth / $width );
+ $width = $newwidth;
+ # Note that $height <= $maxHeight now, but might not be identical
+ # because of rounding.
+ }
+
+ if( $wgUseImageResize ) {
+ $thumbnail = $this->img->getThumbnail( $width, -1, $wgGenerateThumbnailOnParse );
+ if ( $thumbnail == null ) {
+ $url = $this->img->getViewURL();
+ } else {
+ $url = $thumbnail->getURL();
+ }
+ } else {
+ # No resize ability? Show the full image, but scale
+ # it down in the browser so it fits on the page.
+ $url = $this->img->getViewURL();
+ }
+ $anchoropen = "<a href=\"{$full_url}\">";
+ $anchorclose = "</a><br />";
+ if( $this->img->mustRender() ) {
+ $showLink = true;
+ } else {
+ $anchorclose .= "\n$anchoropen{$msg}</a>";
+ }
+ } else {
+ $url = $this->img->getViewURL();
+ $showLink = true;
+ }
+
+ if ( $this->img->isMultipage() ) {
+ $wgOut->addHTML( '<table class="multipageimage"><tr><td>' );
+ }
+
+ $wgOut->addHTML( '<div class="fullImageLink" id="file">' . $anchoropen .
+ "<img border=\"0\" src=\"{$url}\" width=\"{$width}\" height=\"{$height}\" alt=\"" .
+ htmlspecialchars( $this->img->getTitle()->getPrefixedText() ).'" />' . $anchorclose . '</div>' );
+
+ if ( $this->img->isMultipage() ) {
+ $count = $this->img->pageCount();
+
+ if ( $page > 1 ) {
+ $label = $wgOut->parse( wfMsg( 'imgmultipageprev' ), false );
+ $link = $sk->makeLinkObj( $this->mTitle, $label, 'page='. ($page-1) );
+ $this->img->selectPage( $page - 1 );
+ $thumb1 = $sk->makeThumbLinkObj( $this->img, $link, $label, 'none' );
+ } else {
+ $thumb1 = '';
+ }
+
+ if ( $page < $count ) {
+ $label = wfMsg( 'imgmultipagenext' );
+ $this->img->selectPage( $page + 1 );
+ $link = $sk->makeLinkObj( $this->mTitle, $label, 'page='. ($page+1) );
+ $thumb2 = $sk->makeThumbLinkObj( $this->img, $link, $label, 'none' );
+ } else {
+ $thumb2 = '';
+ }
+
+ $select = '<form name="pageselector" action="' . $this->img->getEscapeLocalUrl( '' ) . '" method="GET" onchange="document.pageselector.submit();">' ;
+ $select .= $wgOut->parse( wfMsg( 'imgmultigotopre' ), false ) .
+ ' <select id="pageselector" name="page">';
+ for ( $i=1; $i <= $count; $i++ ) {
+ $select .= Xml::option( $wgLang->formatNum( $i ), $i,
+ $i == $page );
+ }
+ $select .= '</select>' . $wgOut->parse( wfMsg( 'imgmultigotopost' ), false ) .
+ '<input type="submit" value="' .
+ htmlspecialchars( wfMsg( 'imgmultigo' ) ) . '"></form>';
+
+ $wgOut->addHTML( '</td><td><div class="multipageimagenavbox">' .
+ "$select<hr />$thumb1\n$thumb2<br clear=\"all\" /></div></td></tr></table>" );
+ }
+ } else {
+ #if direct link is allowed but it's not a renderable image, show an icon.
+ if ($this->img->isSafeFile()) {
+ $icon= $this->img->iconThumb();
+
+ $wgOut->addHTML( '<div class="fullImageLink" id="file"><a href="' . $full_url . '">' .
+ $icon->toHtml() .
+ '</a></div>' );
+ }
+
+ $showLink = true;
+ }
+
+
+ if ($showLink) {
+ $filename = wfEscapeWikiText( $this->img->getName() );
+ // Hacky workaround: for some reason we use the incorrect MIME type
+ // image/svg for SVG. This should be fixed internally, but at least
+ // make the displayed type right.
+ $mime = $this->img->getMimeType();
+ if ($mime == 'image/svg') $mime = 'image/svg+xml';
+
+ $info = wfMsg( 'fileinfo',
+ ceil($this->img->getSize()/1024.0),
+ $mime );
+
+ global $wgContLang;
+ $dirmark = $wgContLang->getDirMark();
+ if (!$this->img->isSafeFile()) {
+ $warning = wfMsg( 'mediawarning' );
+ $wgOut->addWikiText( <<<END
+<div class="fullMedia">
+<span class="dangerousLink">[[Media:$filename|$filename]]</span>$dirmark
+<span class="fileInfo"> ($info)</span>
+</div>
+
+<div class="mediaWarning">$warning</div>
+END
+ );
+ } else {
+ $wgOut->addWikiText( <<<END
+<div class="fullMedia">
+[[Media:$filename|$filename]]$dirmark <span class="fileInfo"> ($info)</span>
+</div>
+END
+ );
+ }
+ }
+
+ if($this->img->fromSharedDirectory) {
+ $this->printSharedImageText();
+ }
+ } else {
+ # Image does not exist
+
+ $title = SpecialPage::getTitleFor( 'Upload' );
+ $link = $sk->makeKnownLinkObj($title, wfMsgHtml('noimage-linktext'),
+ 'wpDestFile=' . urlencode( $this->img->getName() ) );
+ $wgOut->addHTML( wfMsgWikiHtml( 'noimage', $link ) );
+ }
+ }
+
+ function printSharedImageText() {
+ global $wgRepositoryBaseUrl, $wgFetchCommonsDescriptions, $wgOut, $wgUser;
+
+ $url = $wgRepositoryBaseUrl . urlencode($this->mTitle->getDBkey());
+ $sharedtext = "<div class='sharedUploadNotice'>" . wfMsgWikiHtml("sharedupload");
+ if ($wgRepositoryBaseUrl && !$wgFetchCommonsDescriptions) {
+
+ $sk = $wgUser->getSkin();
+ $title = SpecialPage::getTitleFor( 'Upload' );
+ $link = $sk->makeKnownLinkObj($title, wfMsgHtml('shareduploadwiki-linktext'),
+ array( 'wpDestFile' => urlencode( $this->img->getName() )));
+ $sharedtext .= " " . wfMsgWikiHtml('shareduploadwiki', $link);
+ }
+ $sharedtext .= "</div>";
+ $wgOut->addHTML($sharedtext);
+
+ if ($wgRepositoryBaseUrl && $wgFetchCommonsDescriptions) {
+ $text = Http::get($url . '?action=render');
+ if ($text)
+ $this->mExtraDescription = $text;
+ }
+ }
+
+ function getUploadUrl() {
+ global $wgServer;
+ $uploadTitle = SpecialPage::getTitleFor( 'Upload' );
+ return $wgServer . $uploadTitle->getLocalUrl( 'wpDestFile=' . urlencode( $this->img->getName() ) );
+ }
+
+ /**
+ * Print out the various links at the bottom of the image page, e.g. reupload,
+ * external editing (and instructions link) etc.
+ */
+ function uploadLinksBox() {
+ global $wgUser, $wgOut;
+
+ if( $this->img->fromSharedDirectory )
+ return;
+
+ $sk = $wgUser->getSkin();
+
+ $wgOut->addHtml( '<br /><ul>' );
+
+ # "Upload a new version of this file" link
+ if( $wgUser->isAllowed( 'reupload' ) ) {
+ $ulink = $sk->makeExternalLink( $this->getUploadUrl(), wfMsg( 'uploadnewversion-linktext' ) );
+ $wgOut->addHtml( "<li><div>{$ulink}</div></li>" );
+ }
+
+ # External editing link
+ $elink = $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'edit-externally' ), 'action=edit&externaledit=true&mode=file' );
+ $wgOut->addHtml( '<li>' . $elink . '<div>' . wfMsgWikiHtml( 'edit-externally-help' ) . '</div></li>' );
+
+ $wgOut->addHtml( '</ul>' );
+ }
+
+ function closeShowImage()
+ {
+ # For overloading
+
+ }
+
+ /**
+ * If the page we've just displayed is in the "Image" namespace,
+ * we follow it with an upload history of the image and its usage.
+ */
+ function imageHistory()
+ {
+ global $wgUser, $wgOut, $wgUseExternalEditor;
+
+ $sk = $wgUser->getSkin();
+
+ $line = $this->img->nextHistoryLine();
+
+ if ( $line ) {
+ $list = new ImageHistoryList( $sk );
+ $s = $list->beginImageHistoryList() .
+ $list->imageHistoryLine( true, wfTimestamp(TS_MW, $line->img_timestamp),
+ $this->mTitle->getDBkey(), $line->img_user,
+ $line->img_user_text, $line->img_size, $line->img_description,
+ $line->img_width, $line->img_height
+ );
+
+ while ( $line = $this->img->nextHistoryLine() ) {
+ $s .= $list->imageHistoryLine( false, $line->img_timestamp,
+ $line->oi_archive_name, $line->img_user,
+ $line->img_user_text, $line->img_size, $line->img_description,
+ $line->img_width, $line->img_height
+ );
+ }
+ $s .= $list->endImageHistoryList();
+ } else { $s=''; }
+ $wgOut->addHTML( $s );
+
+ # Exist check because we don't want to show this on pages where an image
+ # doesn't exist along with the noimage message, that would suck. -ævar
+ if( $wgUseExternalEditor && $this->img->exists() ) {
+ $this->uploadLinksBox();
+ }
+
+ }
+
+ function imageLinks()
+ {
+ global $wgUser, $wgOut;
+
+ $wgOut->addHTML( '<h2 id="filelinks">' . wfMsg( 'imagelinks' ) . "</h2>\n" );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $page = $dbr->tableName( 'page' );
+ $imagelinks = $dbr->tableName( 'imagelinks' );
+
+ $sql = "SELECT page_namespace,page_title FROM $imagelinks,$page WHERE il_to=" .
+ $dbr->addQuotes( $this->mTitle->getDBkey() ) . " AND il_from=page_id";
+ $sql = $dbr->limitResult($sql, 500, 0);
+ $res = $dbr->query( $sql, "ImagePage::imageLinks" );
+
+ if ( 0 == $dbr->numRows( $res ) ) {
+ $wgOut->addHtml( '<p>' . wfMsg( "nolinkstoimage" ) . "</p>\n" );
+ return;
+ }
+ $wgOut->addHTML( '<p>' . wfMsg( 'linkstoimage' ) . "</p>\n<ul>" );
+
+ $sk = $wgUser->getSkin();
+ while ( $s = $dbr->fetchObject( $res ) ) {
+ $name = Title::MakeTitle( $s->page_namespace, $s->page_title );
+ $link = $sk->makeKnownLinkObj( $name, "" );
+ $wgOut->addHTML( "<li>{$link}</li>\n" );
+ }
+ $wgOut->addHTML( "</ul>\n" );
+ }
+
+ function delete()
+ {
+ global $wgUser, $wgOut, $wgRequest;
+
+ $confirm = $wgRequest->wasPosted();
+ $reason = $wgRequest->getVal( 'wpReason' );
+ $image = $wgRequest->getVal( 'image' );
+ $oldimage = $wgRequest->getVal( 'oldimage' );
+
+ # Only sysops can delete images. Previously ordinary users could delete
+ # old revisions, but this is no longer the case.
+ if ( !$wgUser->isAllowed('delete') ) {
+ $wgOut->permissionRequired( 'delete' );
+ return;
+ }
+ if ( $wgUser->isBlocked() ) {
+ return $this->blockedIPpage();
+ }
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+
+ # Better double-check that it hasn't been deleted yet!
+ $wgOut->setPagetitle( wfMsg( 'confirmdelete' ) );
+ if ( ( !is_null( $image ) )
+ && ( '' == trim( $image ) ) ) {
+ $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
+ return;
+ }
+
+ $this->img = new Image( $this->mTitle );
+
+ # Deleting old images doesn't require confirmation
+ if ( !is_null( $oldimage ) || $confirm ) {
+ if( $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) {
+ $this->doDelete( $reason );
+ } else {
+ $wgOut->showFatalError( wfMsg( 'sessionfailure' ) );
+ }
+ return;
+ }
+
+ if ( !is_null( $image ) ) {
+ $q = '&image=' . urlencode( $image );
+ } else if ( !is_null( $oldimage ) ) {
+ $q = '&oldimage=' . urlencode( $oldimage );
+ } else {
+ $q = '';
+ }
+ return $this->confirmDelete( $q, $wgRequest->getText( 'wpReason' ) );
+ }
+
+ /*
+ * Delete an image.
+ * @param $reason User provided reason for deletion.
+ */
+ function doDelete( $reason ) {
+ global $wgOut, $wgRequest;
+
+ $oldimage = $wgRequest->getVal( 'oldimage' );
+
+ if ( !is_null( $oldimage ) ) {
+ if ( strlen( $oldimage ) < 16 ) {
+ $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
+ return;
+ }
+ if ( strstr( $oldimage, "/" ) || strstr( $oldimage, "\\" ) ) {
+ $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
+ return;
+ }
+ if ( !$this->doDeleteOldImage( $oldimage ) ) {
+ return;
+ }
+ $deleted = $oldimage;
+ } else {
+ $ok = $this->img->delete( $reason );
+ if( !$ok ) {
+ # If the deletion operation actually failed, bug out:
+ $wgOut->showFileDeleteError( $this->img->getName() );
+ return;
+ }
+
+ # Image itself is now gone, and database is cleaned.
+ # Now we remove the image description page.
+
+ $article = new Article( $this->mTitle );
+ $article->doDeleteArticle( $reason ); # ignore errors
+
+ $deleted = $this->img->getName();
+ }
+
+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ $loglink = '[[Special:Log/delete|' . wfMsg( 'deletionlog' ) . ']]';
+ $text = wfMsg( 'deletedtext', $deleted, $loglink );
+
+ $wgOut->addWikiText( $text );
+
+ $wgOut->returnToMain( false, $this->mTitle->getPrefixedText() );
+ }
+
+ /**
+ * @return success
+ */
+ function doDeleteOldImage( $oldimage )
+ {
+ global $wgOut;
+
+ $ok = $this->img->deleteOld( $oldimage, '' );
+ if( !$ok ) {
+ # If we actually have a file and can't delete it, throw an error.
+ # Something went awry...
+ $wgOut->showFileDeleteError( "$oldimage" );
+ } else {
+ # Log the deletion
+ $log = new LogPage( 'delete' );
+ $log->addEntry( 'delete', $this->mTitle, wfMsg('deletedrevision',$oldimage) );
+ }
+ return $ok;
+ }
+
+ function revert() {
+ global $wgOut, $wgRequest, $wgUser;
+
+ $oldimage = $wgRequest->getText( 'oldimage' );
+ if ( strlen( $oldimage ) < 16 ) {
+ $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
+ return;
+ }
+ if ( strstr( $oldimage, "/" ) || strstr( $oldimage, "\\" ) ) {
+ $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
+ return;
+ }
+
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+ if( $wgUser->isAnon() ) {
+ $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
+ return;
+ }
+ if ( ! $this->mTitle->userCanEdit() ) {
+ $wgOut->readOnlyPage( $this->getContent(), true );
+ return;
+ }
+ if ( $wgUser->isBlocked() ) {
+ return $this->blockedIPpage();
+ }
+ if( !$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) {
+ $wgOut->showErrorPage( 'internalerror', 'sessionfailure' );
+ return;
+ }
+ $name = substr( $oldimage, 15 );
+
+ $dest = wfImageDir( $name );
+ $archive = wfImageArchiveDir( $name );
+ $curfile = "{$dest}/{$name}";
+
+ if ( !is_dir( $dest ) ) wfMkdirParents( $dest );
+ if ( !is_dir( $archive ) ) wfMkdirParents( $archive );
+
+ if ( ! is_file( $curfile ) ) {
+ $wgOut->showFileNotFoundError( htmlspecialchars( $curfile ) );
+ return;
+ }
+ $oldver = wfTimestampNow() . "!{$name}";
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $size = $dbr->selectField( 'oldimage', 'oi_size', array( 'oi_archive_name' => $oldimage ) );
+
+ if ( ! rename( $curfile, "${archive}/{$oldver}" ) ) {
+ $wgOut->showFileRenameError( $curfile, "${archive}/{$oldver}" );
+ return;
+ }
+ if ( ! copy( "{$archive}/{$oldimage}", $curfile ) ) {
+ $wgOut->showFileCopyError( "${archive}/{$oldimage}", $curfile );
+ return;
+ }
+
+ # Record upload and update metadata cache
+ $img = Image::newFromName( $name );
+ $img->recordUpload( $oldver, wfMsg( "reverted" ) );
+
+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->addHTML( wfMsg( 'imagereverted' ) );
+
+ $descTitle = $img->getTitle();
+ $wgOut->returnToMain( false, $descTitle->getPrefixedText() );
+ }
+
+ function blockedIPpage() {
+ $edit = new EditPage( $this );
+ return $edit->blockedIPpage();
+ }
+
+ /**
+ * Override handling of action=purge
+ */
+ function doPurge() {
+ $this->img = new Image( $this->mTitle );
+ if( $this->img->exists() ) {
+ wfDebug( "ImagePage::doPurge purging " . $this->img->getName() . "\n" );
+ $update = new HTMLCacheUpdate( $this->mTitle, 'imagelinks' );
+ $update->doUpdate();
+ $this->img->purgeCache();
+ } else {
+ wfDebug( "ImagePage::doPurge no image\n" );
+ }
+ parent::doPurge();
+ }
+
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class ImageHistoryList {
+ function ImageHistoryList( &$skin ) {
+ $this->skin =& $skin;
+ }
+
+ function beginImageHistoryList() {
+ $s = "\n<h2 id=\"filehistory\">" . wfMsg( 'imghistory' ) . "</h2>\n" .
+ "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
+ return $s;
+ }
+
+ function endImageHistoryList() {
+ $s = "</ul>\n";
+ return $s;
+ }
+
+ function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description, $width, $height ) {
+ global $wgUser, $wgLang, $wgTitle, $wgContLang;
+
+ $datetime = $wgLang->timeanddate( $timestamp, true );
+ $del = wfMsg( 'deleteimg' );
+ $delall = wfMsg( 'deleteimgcompletely' );
+ $cur = wfMsg( 'cur' );
+
+ if ( $iscur ) {
+ $url = Image::imageUrl( $img );
+ $rlink = $cur;
+ if ( $wgUser->isAllowed('delete') ) {
+ $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
+ '&action=delete' );
+ $style = $this->skin->getInternalLinkAttributes( $link, $delall );
+
+ $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
+ } else {
+ $dlink = $del;
+ }
+ } else {
+ $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
+ if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
+ $token = urlencode( $wgUser->editToken( $img ) );
+ $rlink = $this->skin->makeKnownLinkObj( $wgTitle,
+ wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
+ urlencode( $img ) . "&wpEditToken=$token" );
+ $dlink = $this->skin->makeKnownLinkObj( $wgTitle,
+ $del, 'action=delete&oldimage=' . urlencode( $img ) .
+ "&wpEditToken=$token" );
+ } else {
+ # Having live active links for non-logged in users
+ # means that bots and spiders crawling our site can
+ # inadvertently change content. Baaaad idea.
+ $rlink = wfMsg( 'revertimg' );
+ $dlink = $del;
+ }
+ }
+
+ $userlink = $this->skin->userLink( $user, $usertext ) . $this->skin->userToolLinks( $user, $usertext );
+ $nbytes = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ),
+ $wgLang->formatNum( $size ) );
+ $widthheight = wfMsg( 'widthheight', $width, $height );
+ $style = $this->skin->getInternalLinkAttributes( $url, $datetime );
+
+ $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a> . . {$userlink} . . {$widthheight} ({$nbytes})";
+
+ $s .= $this->skin->commentBlock( $description, $wgTitle );
+ $s .= "</li>\n";
+ return $s;
+ }
+
+}
+
+
+?>
diff --git a/includes/JobQueue.php b/includes/JobQueue.php
new file mode 100644
index 000000000000..746cf5de7793
--- /dev/null
+++ b/includes/JobQueue.php
@@ -0,0 +1,267 @@
+<?php
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ die( "This file is part of MediaWiki, it is not a valid entry point\n" );
+}
+
+abstract class Job {
+ var $command,
+ $title,
+ $params,
+ $id,
+ $removeDuplicates,
+ $error;
+
+ /*-------------------------------------------------------------------------
+ * Static functions
+ *------------------------------------------------------------------------*/
+
+ /**
+ * @deprecated use LinksUpdate::queueRecursiveJobs()
+ */
+ /**
+ * static function queueLinksJobs( $titles ) {}
+ */
+
+ /**
+ * Pop a job off the front of the queue
+ * @static
+ * @return Job or false if there's no jobs
+ */
+ static function pop() {
+ wfProfileIn( __METHOD__ );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ // Get a job from the slave
+ $row = $dbr->selectRow( 'job', '*', '', __METHOD__,
+ array( 'ORDER BY' => 'job_id', 'LIMIT' => 1 )
+ );
+
+ if ( $row === false ) {
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+
+ // Try to delete it from the master
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'job', array( 'job_id' => $row->job_id ), __METHOD__ );
+ $affected = $dbw->affectedRows();
+ $dbw->immediateCommit();
+
+ if ( !$affected ) {
+ // Failed, someone else beat us to it
+ // Try getting a random row
+ $row = $dbw->selectRow( 'job', array( 'MIN(job_id) as minjob',
+ 'MAX(job_id) as maxjob' ), '', __METHOD__ );
+ if ( $row === false || is_null( $row->minjob ) || is_null( $row->maxjob ) ) {
+ // No jobs to get
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+ // Get the random row
+ $row = $dbw->selectRow( 'job', '*',
+ array( 'job_id' => mt_rand( $row->minjob, $row->maxjob ) ), __METHOD__ );
+ if ( $row === false ) {
+ // Random job gone before we got the chance to select it
+ // Give up
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+ // Delete the random row
+ $dbw->delete( 'job', array( 'job_id' => $row->job_id ), __METHOD__ );
+ $affected = $dbw->affectedRows();
+ $dbw->immediateCommit();
+
+ if ( !$affected ) {
+ // Random job gone before we exclusively deleted it
+ // Give up
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+ }
+
+ // If execution got to here, there's a row in $row that has been deleted from the database
+ // by this thread. Hence the concurrent pop was successful.
+ $namespace = $row->job_namespace;
+ $dbkey = $row->job_title;
+ $title = Title::makeTitleSafe( $namespace, $dbkey );
+ $job = Job::factory( $row->job_cmd, $title, Job::extractBlob( $row->job_params ), $row->job_id );
+
+ // Remove any duplicates it may have later in the queue
+ $dbw->delete( 'job', $job->insertFields(), __METHOD__ );
+
+ wfProfileOut( __METHOD__ );
+ return $job;
+ }
+
+ /**
+ * Create an object of a subclass
+ */
+ static function factory( $command, $title, $params = false, $id = 0 ) {
+ switch ( $command ) {
+ case 'refreshLinks':
+ return new RefreshLinksJob( $title, $params, $id );
+ case 'htmlCacheUpdate':
+ case 'html_cache_update': # BC
+ return new HTMLCacheUpdateJob( $title, $params['table'], $params['start'], $params['end'], $id );
+ default:
+ throw new MWException( "Invalid job command \"$command\"" );
+ }
+ }
+
+ static function makeBlob( $params ) {
+ if ( $params !== false ) {
+ return serialize( $params );
+ } else {
+ return '';
+ }
+ }
+
+ static function extractBlob( $blob ) {
+ if ( (string)$blob !== '' ) {
+ return unserialize( $blob );
+ } else {
+ return false;
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * Non-static functions
+ *------------------------------------------------------------------------*/
+
+ function __construct( $command, $title, $params = false, $id = 0 ) {
+ $this->command = $command;
+ $this->title = $title;
+ $this->params = $params;
+ $this->id = $id;
+
+ // A bit of premature generalisation
+ // Oh well, the whole class is premature generalisation really
+ $this->removeDuplicates = true;
+ }
+
+ /**
+ * Insert a single job into the queue.
+ */
+ function insert() {
+ $fields = $this->insertFields();
+
+ $dbw =& wfGetDB( DB_MASTER );
+
+ if ( $this->removeDuplicates ) {
+ $res = $dbw->select( 'job', array( '1' ), $fields, __METHOD__ );
+ if ( $dbw->numRows( $res ) ) {
+ return;
+ }
+ }
+ $fields['job_id'] = $dbw->nextSequenceValue( 'job_job_id_seq' );
+ $dbw->insert( 'job', $fields, __METHOD__ );
+ }
+
+ protected function insertFields() {
+ return array(
+ 'job_cmd' => $this->command,
+ 'job_namespace' => $this->title->getNamespace(),
+ 'job_title' => $this->title->getDBkey(),
+ 'job_params' => Job::makeBlob( $this->params )
+ );
+ }
+
+ /**
+ * Batch-insert a group of jobs into the queue.
+ * This will be wrapped in a transaction with a forced commit.
+ *
+ * This may add duplicate at insert time, but they will be
+ * removed later on, when the first one is popped.
+ *
+ * @param $jobs array of Job objects
+ */
+ static function batchInsert( $jobs ) {
+ if( count( $jobs ) ) {
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin();
+ foreach( $jobs as $job ) {
+ $rows[] = $job->insertFields();
+ }
+ $dbw->insert( 'job', $rows, __METHOD__, 'IGNORE' );
+ $dbw->commit();
+ }
+ }
+
+ /**
+ * Run the job
+ * @return boolean success
+ */
+ abstract function run();
+
+ function toString() {
+ $paramString = '';
+ if ( $this->params ) {
+ foreach ( $this->params as $key => $value ) {
+ if ( $paramString != '' ) {
+ $paramString .= ' ';
+ }
+ $paramString .= "$key=$value";
+ }
+ }
+
+ if ( is_object( $this->title ) ) {
+ $s = "{$this->command} " . $this->title->getPrefixedDBkey();
+ if ( $paramString !== '' ) {
+ $s .= ' ' . $paramString;
+ }
+ return $s;
+ } else {
+ return "{$this->command} $paramString";
+ }
+ }
+
+ function getLastError() {
+ return $this->error;
+ }
+}
+
+class RefreshLinksJob extends Job {
+ function __construct( $title, $params = '', $id = 0 ) {
+ parent::__construct( 'refreshLinks', $title, $params, $id );
+ }
+
+ /**
+ * Run a refreshLinks job
+ * @return boolean success
+ */
+ function run() {
+ global $wgParser;
+ wfProfileIn( __METHOD__ );
+
+ $linkCache =& LinkCache::singleton();
+ $linkCache->clear();
+
+ if ( is_null( $this->title ) ) {
+ $this->error = "refreshLinks: Invalid title";
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+
+ $revision = Revision::newFromTitle( $this->title );
+ if ( !$revision ) {
+ $this->error = 'refreshLinks: Article not found "' . $this->title->getPrefixedDBkey() . '"';
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+
+ wfProfileIn( __METHOD__.'-parse' );
+ $options = new ParserOptions;
+ $parserOutput = $wgParser->parse( $revision->getText(), $this->title, $options, true, true, $revision->getId() );
+ wfProfileOut( __METHOD__.'-parse' );
+ wfProfileIn( __METHOD__.'-update' );
+ $update = new LinksUpdate( $this->title, $parserOutput, false );
+ $update->doUpdate();
+ wfProfileOut( __METHOD__.'-update' );
+ wfProfileOut( __METHOD__ );
+ return true;
+ }
+}
+
+?>
diff --git a/includes/Licenses.php b/includes/Licenses.php
new file mode 100644
index 000000000000..dd1308b44e63
--- /dev/null
+++ b/includes/Licenses.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ * A License class for use on Special:Upload
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+class Licenses {
+ /**#@+
+ * @private
+ */
+ /**
+ * @var string
+ */
+ var $msg;
+
+ /**
+ * @var array
+ */
+ var $licenses = array();
+
+ /**
+ * @var string
+ */
+ var $html;
+ /**#@-*/
+
+ /**
+ * Constrictor
+ *
+ * @param $str String: the string to build the licenses member from, will use
+ * wfMsgForContent( 'licenses' ) if null (default: null)
+ */
+ function Licenses( $str = null ) {
+ // PHP sucks, this should be possible in the constructor
+ $this->msg = is_null( $str ) ? wfMsgForContent( 'licenses' ) : $str;
+ $this->html = '';
+
+ $this->makeLicenses();
+ $tmp = $this->getLicenses();
+ $this->makeHtml( $tmp );
+ }
+
+ /**#@+
+ * @private
+ */
+ function makeLicenses() {
+ $levels = array();
+ $lines = explode( "\n", $this->msg );
+
+ foreach ( $lines as $line ) {
+ if ( strpos( $line, '*' ) !== 0 )
+ continue;
+ else {
+ list( $level, $line ) = $this->trimStars( $line );
+
+ if ( strpos( $line, '|' ) !== false ) {
+ $obj = new License( $line );
+ $this->stackItem( $this->licenses, $levels, $obj );
+ } else {
+ if ( $level < count( $levels ) ) {
+ $levels = array_slice( $levels, 0, $level );
+ }
+ if ( $level == count( $levels ) ) {
+ $levels[$level - 1] = $line;
+ } else if ( $level > count( $levels ) ) {
+ $levels[] = $line;
+ }
+ }
+ }
+ }
+ }
+
+ function trimStars( $str ) {
+ $i = $count = 0;
+
+ wfSuppressWarnings();
+ while ($str[$i++] == '*')
+ ++$count;
+ wfRestoreWarnings();
+
+ return array( $count, ltrim( $str, '* ' ) );
+ }
+
+ function stackItem( &$list, $path, $item ) {
+ $position =& $list;
+ if ( $path )
+ foreach( $path as $key )
+ $position =& $position[$key];
+ $position[] = $item;
+ }
+
+ function makeHtml( &$tagset, $depth = 0 ) {
+ foreach ( $tagset as $key => $val )
+ if ( is_array( $val ) ) {
+ $this->html .= $this->outputOption(
+ $this->msg( $key ),
+ array(
+ 'value' => '',
+ 'disabled' => 'disabled',
+ 'style' => 'color: GrayText', // for MSIE
+ ),
+ $depth
+ );
+ $this->makeHtml( $val, $depth + 1 );
+ } else {
+ $this->html .= $this->outputOption(
+ $this->msg( $val->text ),
+ array(
+ 'value' => $val->template,
+ 'title' => '{{' . $val->template . '}}'
+ ),
+ $depth
+ );
+ }
+ }
+
+ function outputOption( $val, $attribs = null, $depth ) {
+ $val = str_repeat( /* &nbsp */ "\xc2\xa0", $depth * 2 ) . $val;
+ return str_repeat( "\t", $depth ) . wfElement( 'option', $attribs, $val ) . "\n";
+ }
+
+ function msg( $str ) {
+ $out = wfMsg( $str );
+ return wfEmptyMsg( $str, $out ) ? $str : $out;
+ }
+
+ /**#@-*/
+
+ /**
+ * Accessor for $this->licenses
+ *
+ * @return array
+ */
+ function getLicenses() { return $this->licenses; }
+
+ /**
+ * Accessor for $this->html
+ *
+ * @return string
+ */
+ function getHtml() { return $this->html; }
+}
+
+class License {
+ /**
+ * @var string
+ */
+ var $template;
+
+ /**
+ * @var string
+ */
+ var $text;
+
+ /**
+ * Constructor
+ *
+ * @param $str String: license name??
+ */
+ function License( $str ) {
+ list( $text, $template ) = explode( '|', strrev( $str ), 2 );
+
+ $this->template = strrev( $template );
+ $this->text = strrev( $text );
+ }
+}
+?>
diff --git a/includes/LinkBatch.php b/includes/LinkBatch.php
new file mode 100644
index 000000000000..61e1c040d4fb
--- /dev/null
+++ b/includes/LinkBatch.php
@@ -0,0 +1,183 @@
+<?php
+
+/**
+ * Class representing a list of titles
+ * The execute() method checks them all for existence and adds them to a LinkCache object
+ +
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+class LinkBatch {
+ /**
+ * 2-d array, first index namespace, second index dbkey, value arbitrary
+ */
+ var $data = array();
+
+ function LinkBatch( $arr = array() ) {
+ foreach( $arr as $item ) {
+ $this->addObj( $item );
+ }
+ }
+
+ function addObj( $title ) {
+ if ( is_object( $title ) ) {
+ $this->add( $title->getNamespace(), $title->getDBkey() );
+ } else {
+ wfDebug( "Warning: LinkBatch::addObj got invalid title object\n" );
+ }
+ }
+
+ function add( $ns, $dbkey ) {
+ if ( $ns < 0 ) {
+ return;
+ }
+ if ( !array_key_exists( $ns, $this->data ) ) {
+ $this->data[$ns] = array();
+ }
+
+ $this->data[$ns][$dbkey] = 1;
+ }
+
+ /**
+ * Set the link list to a given 2-d array
+ * First key is the namespace, second is the DB key, value arbitrary
+ */
+ function setArray( $array ) {
+ $this->data = $array;
+ }
+
+ /**
+ * Returns true if no pages have been added, false otherwise.
+ */
+ function isEmpty() {
+ return ($this->getSize() == 0);
+ }
+
+ /**
+ * Returns the size of the batch.
+ */
+ function getSize() {
+ return count( $this->data );
+ }
+
+ /**
+ * Do the query and add the results to the LinkCache object
+ * Return an array mapping PDBK to ID
+ */
+ function execute() {
+ $linkCache =& LinkCache::singleton();
+ return $this->executeInto( $linkCache );
+ }
+
+ /**
+ * Do the query and add the results to a given LinkCache object
+ * Return an array mapping PDBK to ID
+ */
+ function executeInto( &$cache ) {
+ $fname = 'LinkBatch::executeInto';
+ wfProfileIn( $fname );
+ // Do query
+ $res = $this->doQuery();
+ if ( !$res ) {
+ wfProfileOut( $fname );
+ return array();
+ }
+
+ // For each returned entry, add it to the list of good links, and remove it from $remaining
+
+ $ids = array();
+ $remaining = $this->data;
+ while ( $row = $res->fetchObject() ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $cache->addGoodLinkObj( $row->page_id, $title );
+ $ids[$title->getPrefixedDBkey()] = $row->page_id;
+ unset( $remaining[$row->page_namespace][$row->page_title] );
+ }
+ $res->free();
+
+ // The remaining links in $data are bad links, register them as such
+ foreach ( $remaining as $ns => $dbkeys ) {
+ foreach ( $dbkeys as $dbkey => $unused ) {
+ $title = Title::makeTitle( $ns, $dbkey );
+ $cache->addBadLinkObj( $title );
+ $ids[$title->getPrefixedDBkey()] = 0;
+ }
+ }
+ wfProfileOut( $fname );
+ return $ids;
+ }
+
+ /**
+ * Perform the existence test query, return a ResultWrapper with page_id fields
+ */
+ function doQuery() {
+ $fname = 'LinkBatch::doQuery';
+
+ if ( $this->isEmpty() ) {
+ return false;
+ }
+ wfProfileIn( $fname );
+
+ // Construct query
+ // This is very similar to Parser::replaceLinkHolders
+ $dbr =& wfGetDB( DB_SLAVE );
+ $page = $dbr->tableName( 'page' );
+ $set = $this->constructSet( 'page', $dbr );
+ if ( $set === false ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ $sql = "SELECT page_id, page_namespace, page_title FROM $page WHERE $set";
+
+ // Do query
+ $res = new ResultWrapper( $dbr, $dbr->query( $sql, $fname ) );
+ wfProfileOut( $fname );
+ return $res;
+ }
+
+ /**
+ * Construct a WHERE clause which will match all the given titles.
+ * Give the appropriate table's field name prefix ('page', 'pl', etc).
+ *
+ * @param $prefix String: ??
+ * @return string
+ * @public
+ */
+ function constructSet( $prefix, &$db ) {
+ $first = true;
+ $firstTitle = true;
+ $sql = '';
+ foreach ( $this->data as $ns => $dbkeys ) {
+ if ( !count( $dbkeys ) ) {
+ continue;
+ }
+
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ' OR ';
+ }
+ $sql .= "({$prefix}_namespace=$ns AND {$prefix}_title IN (";
+
+ $firstTitle = true;
+ foreach( $dbkeys as $dbkey => $unused ) {
+ if ( $firstTitle ) {
+ $firstTitle = false;
+ } else {
+ $sql .= ',';
+ }
+ $sql .= $db->addQuotes( $dbkey );
+ }
+
+ $sql .= '))';
+ }
+ if ( $first && $firstTitle ) {
+ # No titles added
+ return false;
+ } else {
+ return $sql;
+ }
+ }
+}
+
+?>
diff --git a/includes/LinkCache.php b/includes/LinkCache.php
new file mode 100644
index 000000000000..8e56225ba0f0
--- /dev/null
+++ b/includes/LinkCache.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Cache for article titles (prefixed DB keys) and ids linked from one source
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+class LinkCache {
+ // Increment $mClassVer whenever old serialized versions of this class
+ // becomes incompatible with the new version.
+ /* private */ var $mClassVer = 3;
+
+ /* private */ var $mPageLinks;
+ /* private */ var $mGoodLinks, $mBadLinks;
+ /* private */ var $mForUpdate;
+
+ /**
+ * Get an instance of this class
+ */
+ static function &singleton() {
+ static $instance;
+ if ( !isset( $instance ) ) {
+ $instance = new LinkCache;
+ }
+ return $instance;
+ }
+
+ function LinkCache() {
+ $this->mForUpdate = false;
+ $this->mPageLinks = array();
+ $this->mGoodLinks = array();
+ $this->mBadLinks = array();
+ }
+
+ /* private */ function getKey( $title ) {
+ return wfMemcKey( 'lc', 'title', $title );
+ }
+
+ /**
+ * General accessor to get/set whether SELECT FOR UPDATE should be used
+ */
+ function forUpdate( $update = NULL ) {
+ return wfSetVar( $this->mForUpdate, $update );
+ }
+
+ function getGoodLinkID( $title ) {
+ if ( array_key_exists( $title, $this->mGoodLinks ) ) {
+ return $this->mGoodLinks[$title];
+ } else {
+ return 0;
+ }
+ }
+
+ function isBadLink( $title ) {
+ return array_key_exists( $title, $this->mBadLinks );
+ }
+
+ function addGoodLinkObj( $id, $title ) {
+ $dbkey = $title->getPrefixedDbKey();
+ $this->mGoodLinks[$dbkey] = $id;
+ $this->mPageLinks[$dbkey] = $title;
+ }
+
+ function addBadLinkObj( $title ) {
+ $dbkey = $title->getPrefixedDbKey();
+ if ( ! $this->isBadLink( $dbkey ) ) {
+ $this->mBadLinks[$dbkey] = 1;
+ $this->mPageLinks[$dbkey] = $title;
+ }
+ }
+
+ function clearBadLink( $title ) {
+ unset( $this->mBadLinks[$title] );
+ $this->clearLink( $title );
+ }
+
+ function clearLink( $title ) {
+ global $wgMemc, $wgLinkCacheMemcached;
+ if( $wgLinkCacheMemcached )
+ $wgMemc->delete( $this->getKey( $title ) );
+ }
+
+ function getPageLinks() { return $this->mPageLinks; }
+ function getGoodLinks() { return $this->mGoodLinks; }
+ function getBadLinks() { return array_keys( $this->mBadLinks ); }
+
+ /**
+ * Add a title to the link cache, return the page_id or zero if non-existent
+ * @param $title String: title to add
+ * @return integer
+ */
+ function addLink( $title ) {
+ $nt = Title::newFromDBkey( $title );
+ if( $nt ) {
+ return $this->addLinkObj( $nt );
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Add a title to the link cache, return the page_id or zero if non-existent
+ * @param $nt Title to add.
+ * @return integer
+ */
+ function addLinkObj( &$nt ) {
+ global $wgMemc, $wgLinkCacheMemcached, $wgAntiLockFlags;
+ $title = $nt->getPrefixedDBkey();
+ if ( $this->isBadLink( $title ) ) { return 0; }
+ $id = $this->getGoodLinkID( $title );
+ if ( 0 != $id ) { return $id; }
+
+ $fname = 'LinkCache::addLinkObj';
+ global $wgProfiling, $wgProfiler;
+ if ( $wgProfiling && isset( $wgProfiler ) ) {
+ $fname .= ' (' . $wgProfiler->getCurrentSection() . ')';
+ }
+
+ wfProfileIn( $fname );
+
+ $ns = $nt->getNamespace();
+ $t = $nt->getDBkey();
+
+ if ( '' == $title ) {
+ wfProfileOut( $fname );
+ return 0;
+ }
+
+ $id = NULL;
+ if( $wgLinkCacheMemcached )
+ $id = $wgMemc->get( $key = $this->getKey( $title ) );
+ if( ! is_integer( $id ) ) {
+ if ( $this->mForUpdate ) {
+ $db =& wfGetDB( DB_MASTER );
+ if ( !( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) ) {
+ $options = array( 'FOR UPDATE' );
+ } else {
+ $options = array();
+ }
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ $options = array();
+ }
+
+ $id = $db->selectField( 'page', 'page_id',
+ array( 'page_namespace' => $ns, 'page_title' => $t ),
+ $fname, $options );
+ if ( !$id ) {
+ $id = 0;
+ }
+ if( $wgLinkCacheMemcached )
+ $wgMemc->add( $key, $id, 3600*24 );
+ }
+
+ if( 0 == $id ) {
+ $this->addBadLinkObj( $nt );
+ } else {
+ $this->addGoodLinkObj( $id, $nt );
+ }
+ wfProfileOut( $fname );
+ return $id;
+ }
+
+ /**
+ * Clears cache
+ */
+ function clear() {
+ $this->mPageLinks = array();
+ $this->mGoodLinks = array();
+ $this->mBadLinks = array();
+ }
+}
+?>
diff --git a/includes/LinkFilter.php b/includes/LinkFilter.php
new file mode 100644
index 000000000000..e03b59dd6079
--- /dev/null
+++ b/includes/LinkFilter.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * Some functions to help implement an external link filter for spam control.
+ *
+ * TODO: implement the filter. Currently these are just some functions to help
+ * maintenance/cleanupSpam.php remove links to a single specified domain. The
+ * next thing is to implement functions for checking a given page against a big
+ * list of domains.
+ *
+ * Another cool thing to do would be a web interface for fast spam removal.
+ */
+class LinkFilter {
+ /**
+ * @static
+ */
+ function matchEntry( $text, $filterEntry ) {
+ $regex = LinkFilter::makeRegex( $filterEntry );
+ return preg_match( $regex, $text );
+ }
+
+ /**
+ * @static
+ */
+ function makeRegex( $filterEntry ) {
+ $regex = '!http://';
+ if ( substr( $filterEntry, 0, 2 ) == '*.' ) {
+ $regex .= '([A-Za-z0-9.-]+\.|)';
+ $filterEntry = substr( $filterEntry, 2 );
+ }
+ $regex .= preg_quote( $filterEntry, '!' ) . '!Si';
+ return $regex;
+ }
+
+ /**
+ * Make a string to go after an SQL LIKE, which will match the specified
+ * string. There are several kinds of filter entry:
+ * *.domain.com - Produces http://com.domain.%, matches domain.com
+ * and www.domain.com
+ * domain.com - Produces http://com.domain./%, matches domain.com
+ * or domain.com/ but not www.domain.com
+ * *.domain.com/x - Produces http://com.domain.%/x%, matches
+ * www.domain.com/xy
+ * domain.com/x - Produces http://com.domain./x%, matches
+ * domain.com/xy but not www.domain.com/xy
+ *
+ * Asterisks in any other location are considered invalid.
+ *
+ * @static
+ */
+ function makeLike( $filterEntry ) {
+ if ( substr( $filterEntry, 0, 2 ) == '*.' ) {
+ $subdomains = true;
+ $filterEntry = substr( $filterEntry, 2 );
+ if ( $filterEntry == '' ) {
+ // We don't want to make a clause that will match everything,
+ // that could be dangerous
+ return false;
+ }
+ } else {
+ $subdomains = false;
+ }
+ // No stray asterisks, that could cause confusion
+ // It's not simple or efficient to handle it properly so we don't
+ // handle it at all.
+ if ( strpos( $filterEntry, '*' ) !== false ) {
+ return false;
+ }
+ $slash = strpos( $filterEntry, '/' );
+ if ( $slash !== false ) {
+ $path = substr( $filterEntry, $slash );
+ $host = substr( $filterEntry, 0, $slash );
+ } else {
+ $path = '/';
+ $host = $filterEntry;
+ }
+ $host = strtolower( implode( '.', array_reverse( explode( '.', $host ) ) ) );
+ if ( substr( $host, -1, 1 ) !== '.' ) {
+ $host .= '.';
+ }
+ $like = "http://$host";
+
+ if ( $subdomains ) {
+ $like .= '%';
+ }
+ if ( !$subdomains || $path !== '/' ) {
+ $like .= $path . '%';
+ }
+ return $like;
+ }
+}
+?>
diff --git a/includes/Linker.php b/includes/Linker.php
new file mode 100644
index 000000000000..0eabab2f2a34
--- /dev/null
+++ b/includes/Linker.php
@@ -0,0 +1,1207 @@
+<?php
+/**
+ * Split off some of the internal bits from Skin.php.
+ * These functions are used for primarily page content:
+ * links, embedded images, table of contents. Links are
+ * also used in the skin.
+ * @package MediaWiki
+ */
+
+/**
+ * For the moment, Skin is a descendent class of Linker.
+ * In the future, it should probably be further split
+ * so that ever other bit of the wiki doesn't have to
+ * go loading up Skin to get at it.
+ *
+ * @package MediaWiki
+ */
+class Linker {
+ function Linker() {}
+
+ /**
+ * @deprecated
+ */
+ function postParseLinkColour( $s = NULL ) {
+ return NULL;
+ }
+
+ /** @todo document */
+ function getExternalLinkAttributes( $link, $text, $class='' ) {
+ $link = htmlspecialchars( $link );
+
+ $r = ($class != '') ? " class=\"$class\"" : " class=\"external\"";
+
+ $r .= " title=\"{$link}\"";
+ return $r;
+ }
+
+ function getInterwikiLinkAttributes( $link, $text, $class='' ) {
+ global $wgContLang;
+
+ $link = urldecode( $link );
+ $link = $wgContLang->checkTitleEncoding( $link );
+ $link = preg_replace( '/[\\x00-\\x1f]/', ' ', $link );
+ $link = htmlspecialchars( $link );
+
+ $r = ($class != '') ? " class=\"$class\"" : " class=\"external\"";
+
+ $r .= " title=\"{$link}\"";
+ return $r;
+ }
+
+ /** @todo document */
+ function getInternalLinkAttributes( $link, $text, $broken = false ) {
+ $link = urldecode( $link );
+ $link = str_replace( '_', ' ', $link );
+ $link = htmlspecialchars( $link );
+
+ if( $broken == 'stub' ) {
+ $r = ' class="stub"';
+ } else if ( $broken == 'yes' ) {
+ $r = ' class="new"';
+ } else {
+ $r = '';
+ }
+
+ $r .= " title=\"{$link}\"";
+ return $r;
+ }
+
+ /**
+ * @param $nt Title object.
+ * @param $text String: FIXME
+ * @param $broken Boolean: FIXME, default 'false'.
+ */
+ function getInternalLinkAttributesObj( &$nt, $text, $broken = false ) {
+ if( $broken == 'stub' ) {
+ $r = ' class="stub"';
+ } else if ( $broken == 'yes' ) {
+ $r = ' class="new"';
+ } else {
+ $r = '';
+ }
+
+ $r .= ' title="' . $nt->getEscapedText() . '"';
+ return $r;
+ }
+
+ /**
+ * This function is a shortcut to makeLinkObj(Title::newFromText($title),...). Do not call
+ * it if you already have a title object handy. See makeLinkObj for further documentation.
+ *
+ * @param $title String: the text of the title
+ * @param $text String: link text
+ * @param $query String: optional query part
+ * @param $trail String: optional trail. Alphabetic characters at the start of this string will
+ * be included in the link text. Other characters will be appended after
+ * the end of the link.
+ */
+ function makeLink( $title, $text = '', $query = '', $trail = '' ) {
+ wfProfileIn( 'Linker::makeLink' );
+ $nt = Title::newFromText( $title );
+ if ($nt) {
+ $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
+ } else {
+ wfDebug( 'Invalid title passed to Linker::makeLink(): "'.$title."\"\n" );
+ $result = $text == "" ? $title : $text;
+ }
+
+ wfProfileOut( 'Linker::makeLink' );
+ return $result;
+ }
+
+ /**
+ * This function is a shortcut to makeKnownLinkObj(Title::newFromText($title),...). Do not call
+ * it if you already have a title object handy. See makeKnownLinkObj for further documentation.
+ *
+ * @param $title String: the text of the title
+ * @param $text String: link text
+ * @param $query String: optional query part
+ * @param $trail String: optional trail. Alphabetic characters at the start of this string will
+ * be included in the link text. Other characters will be appended after
+ * the end of the link.
+ */
+ function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
+ $nt = Title::newFromText( $title );
+ if ($nt) {
+ return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
+ } else {
+ wfDebug( 'Invalid title passed to Linker::makeKnownLink(): "'.$title."\"\n" );
+ return $text == '' ? $title : $text;
+ }
+ }
+
+ /**
+ * This function is a shortcut to makeBrokenLinkObj(Title::newFromText($title),...). Do not call
+ * it if you already have a title object handy. See makeBrokenLinkObj for further documentation.
+ *
+ * @param string $title The text of the title
+ * @param string $text Link text
+ * @param string $query Optional query part
+ * @param string $trail Optional trail. Alphabetic characters at the start of this string will
+ * be included in the link text. Other characters will be appended after
+ * the end of the link.
+ */
+ function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
+ $nt = Title::newFromText( $title );
+ if ($nt) {
+ return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
+ } else {
+ wfDebug( 'Invalid title passed to Linker::makeBrokenLink(): "'.$title."\"\n" );
+ return $text == '' ? $title : $text;
+ }
+ }
+
+ /**
+ * This function is a shortcut to makeStubLinkObj(Title::newFromText($title),...). Do not call
+ * it if you already have a title object handy. See makeStubLinkObj for further documentation.
+ *
+ * @param $title String: the text of the title
+ * @param $text String: link text
+ * @param $query String: optional query part
+ * @param $trail String: optional trail. Alphabetic characters at the start of this string will
+ * be included in the link text. Other characters will be appended after
+ * the end of the link.
+ */
+ function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
+ $nt = Title::newFromText( $title );
+ if ($nt) {
+ return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
+ } else {
+ wfDebug( 'Invalid title passed to Linker::makeStubLink(): "'.$title."\"\n" );
+ return $text == '' ? $title : $text;
+ }
+ }
+
+ /**
+ * Make a link for a title which may or may not be in the database. If you need to
+ * call this lots of times, pre-fill the link cache with a LinkBatch, otherwise each
+ * call to this will result in a DB query.
+ *
+ * @param $nt Title: the title object to make the link from, e.g. from
+ * Title::newFromText.
+ * @param $text String: link text
+ * @param $query String: optional query part
+ * @param $trail String: optional trail. Alphabetic characters at the start of this string will
+ * be included in the link text. Other characters will be appended after
+ * the end of the link.
+ * @param $prefix String: optional prefix. As trail, only before instead of after.
+ */
+ function makeLinkObj( $nt, $text= '', $query = '', $trail = '', $prefix = '' ) {
+ global $wgUser;
+ $fname = 'Linker::makeLinkObj';
+ wfProfileIn( $fname );
+
+ # Fail gracefully
+ if ( ! is_object($nt) ) {
+ # throw new MWException();
+ wfProfileOut( $fname );
+ return "<!-- ERROR -->{$prefix}{$text}{$trail}";
+ }
+
+ if ( $nt->isExternal() ) {
+ $u = $nt->getFullURL();
+ $link = $nt->getPrefixedURL();
+ if ( '' == $text ) { $text = $nt->getPrefixedText(); }
+ $style = $this->getInterwikiLinkAttributes( $link, $text, 'extiw' );
+
+ $inside = '';
+ if ( '' != $trail ) {
+ $m = array();
+ if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
+ $inside = $m[1];
+ $trail = $m[2];
+ }
+ }
+ $t = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>";
+
+ wfProfileOut( $fname );
+ return $t;
+ } elseif ( $nt->isAlwaysKnown() ) {
+ # Image links, special page links and self-links with fragements are always known.
+ $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+ } else {
+ wfProfileIn( $fname.'-immediate' );
+ # Work out link colour immediately
+ $aid = $nt->getArticleID() ;
+ if ( 0 == $aid ) {
+ $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
+ } else {
+ $threshold = $wgUser->getOption('stubthreshold') ;
+ if ( $threshold > 0 ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $s = $dbr->selectRow(
+ array( 'page' ),
+ array( 'page_len',
+ 'page_namespace',
+ 'page_is_redirect' ),
+ array( 'page_id' => $aid ), $fname ) ;
+ if ( $s !== false ) {
+ $size = $s->page_len;
+ if ( $s->page_is_redirect OR $s->page_namespace != NS_MAIN ) {
+ $size = $threshold*2 ; # Really big
+ }
+ } else {
+ $size = $threshold*2 ; # Really big
+ }
+ } else {
+ $size = 1 ;
+ }
+ if ( $size < $threshold ) {
+ $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
+ } else {
+ $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+ }
+ }
+ wfProfileOut( $fname.'-immediate' );
+ }
+ wfProfileOut( $fname );
+ return $retVal;
+ }
+
+ /**
+ * Make a link for a title which definitely exists. This is faster than makeLinkObj because
+ * it doesn't have to do a database query. It's also valid for interwiki titles and special
+ * pages.
+ *
+ * @param $nt Title object of target page
+ * @param $text String: text to replace the title
+ * @param $query String: link target
+ * @param $trail String: text after link
+ * @param $prefix String: text before link text
+ * @param $aprops String: extra attributes to the a-element
+ * @param $style String: style to apply - if empty, use getInternalLinkAttributesObj instead
+ * @return the a-element
+ */
+ function makeKnownLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = '' ) {
+
+ $fname = 'Linker::makeKnownLinkObj';
+ wfProfileIn( $fname );
+
+ if ( !is_object( $nt ) ) {
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ $u = $nt->escapeLocalURL( $query );
+ if ( $nt->getFragment() != '' ) {
+ if( $nt->getPrefixedDbkey() == '' ) {
+ $u = '';
+ if ( '' == $text ) {
+ $text = htmlspecialchars( $nt->getFragment() );
+ }
+ }
+ $u .= $nt->getFragmentForURL();
+ }
+ if ( $text == '' ) {
+ $text = htmlspecialchars( $nt->getPrefixedText() );
+ }
+ if ( $style == '' ) {
+ $style = $this->getInternalLinkAttributesObj( $nt, $text );
+ }
+
+ if ( $aprops !== '' ) $aprops = ' ' . $aprops;
+
+ list( $inside, $trail ) = Linker::splitTrail( $trail );
+ $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
+ wfProfileOut( $fname );
+ return $r;
+ }
+
+ /**
+ * Make a red link to the edit page of a given title.
+ *
+ * @param $title String: The text of the title
+ * @param $text String: Link text
+ * @param $query String: Optional query part
+ * @param $trail String: Optional trail. Alphabetic characters at the start of this string will
+ * be included in the link text. Other characters will be appended after
+ * the end of the link.
+ */
+ function makeBrokenLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ # Fail gracefully
+ if ( ! isset($nt) ) {
+ # throw new MWException();
+ return "<!-- ERROR -->{$prefix}{$text}{$trail}";
+ }
+
+ $fname = 'Linker::makeBrokenLinkObj';
+ wfProfileIn( $fname );
+
+ if ( '' == $query ) {
+ $q = 'action=edit';
+ } else {
+ $q = 'action=edit&'.$query;
+ }
+ $u = $nt->escapeLocalURL( $q );
+
+ if ( '' == $text ) {
+ $text = htmlspecialchars( $nt->getPrefixedText() );
+ }
+ $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
+
+ list( $inside, $trail ) = Linker::splitTrail( $trail );
+ $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
+
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ /**
+ * Make a brown link to a short article.
+ *
+ * @param $title String: the text of the title
+ * @param $text String: link text
+ * @param $query String: optional query part
+ * @param $trail String: optional trail. Alphabetic characters at the start of this string will
+ * be included in the link text. Other characters will be appended after
+ * the end of the link.
+ */
+ function makeStubLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ $u = $nt->escapeLocalURL( $query );
+
+ if ( '' == $text ) {
+ $text = htmlspecialchars( $nt->getPrefixedText() );
+ }
+ $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
+
+ list( $inside, $trail ) = Linker::splitTrail( $trail );
+ $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
+ return $s;
+ }
+
+ /**
+ * Generate either a normal exists-style link or a stub link, depending
+ * on the given page size.
+ *
+ * @param $size Integer
+ * @param $nt Title object.
+ * @param $text String
+ * @param $query String
+ * @param $trail String
+ * @param $prefix String
+ * @return string HTML of link
+ */
+ function makeSizeLinkObj( $size, $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ global $wgUser;
+ $threshold = intval( $wgUser->getOption( 'stubthreshold' ) );
+ if( $size < $threshold ) {
+ return $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
+ } else {
+ return $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+ }
+ }
+
+ /**
+ * Make appropriate markup for a link to the current article. This is currently rendered
+ * as the bold link text. The calling sequence is the same as the other make*LinkObj functions,
+ * despite $query not being used.
+ */
+ function makeSelfLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ if ( '' == $text ) {
+ $text = htmlspecialchars( $nt->getPrefixedText() );
+ }
+ list( $inside, $trail ) = Linker::splitTrail( $trail );
+ return "<strong class=\"selflink\">{$prefix}{$text}{$inside}</strong>{$trail}";
+ }
+
+ /** @todo document */
+ function fnamePart( $url ) {
+ $basename = strrchr( $url, '/' );
+ if ( false === $basename ) {
+ $basename = $url;
+ } else {
+ $basename = substr( $basename, 1 );
+ }
+ return htmlspecialchars( $basename );
+ }
+
+ /** Obsolete alias */
+ function makeImage( $url, $alt = '' ) {
+ return $this->makeExternalImage( $url, $alt );
+ }
+
+ /** @todo document */
+ function makeExternalImage( $url, $alt = '' ) {
+ if ( '' == $alt ) {
+ $alt = $this->fnamePart( $url );
+ }
+ $s = '<img src="'.$url.'" alt="'.$alt.'" />';
+ return $s;
+ }
+
+ /** @todo document */
+ function makeImageLinkObj( $nt, $label, $alt, $align = '', $width = false, $height = false, $framed = false,
+ $thumb = false, $manual_thumb = '', $page = null )
+ {
+ global $wgContLang, $wgUser, $wgThumbLimits, $wgGenerateThumbnailOnParse;
+
+ $img = new Image( $nt );
+
+ if ( ! is_null( $page ) ) {
+ $img->selectPage( $page );
+ }
+
+ if ( !$img->allowInlineDisplay() && $img->exists() ) {
+ return $this->makeKnownLinkObj( $nt );
+ }
+
+ $url = $img->getViewURL();
+ $error = $prefix = $postfix = '';
+
+ wfDebug( "makeImageLinkObj: '$width'x'$height', \"$label\"\n" );
+
+ if ( 'center' == $align )
+ {
+ $prefix = '<div class="center">';
+ $postfix = '</div>';
+ $align = 'none';
+ }
+
+ if ( $thumb || $framed ) {
+
+ # Create a thumbnail. Alignment depends on language
+ # writing direction, # right aligned for left-to-right-
+ # languages ("Western languages"), left-aligned
+ # for right-to-left-languages ("Semitic languages")
+ #
+ # If thumbnail width has not been provided, it is set
+ # to the default user option as specified in Language*.php
+ if ( $align == '' ) {
+ $align = $wgContLang->isRTL() ? 'left' : 'right';
+ }
+
+
+ if ( $width === false ) {
+ $wopt = $wgUser->getOption( 'thumbsize' );
+
+ if( !isset( $wgThumbLimits[$wopt] ) ) {
+ $wopt = User::getDefaultOption( 'thumbsize' );
+ }
+
+ $width = min( $img->getWidth(), $wgThumbLimits[$wopt] );
+ }
+
+ return $prefix.$this->makeThumbLinkObj( $img, $label, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
+ }
+
+ if ( $width && $img->exists() ) {
+
+ # Create a resized image, without the additional thumbnail
+ # features
+
+ if ( $height == false )
+ $height = -1;
+ if ( $manual_thumb == '') {
+ $thumb = $img->getThumbnail( $width, $height, $wgGenerateThumbnailOnParse );
+ if ( $thumb ) {
+ // In most cases, $width = $thumb->width or $height = $thumb->height.
+ // If not, we're scaling the image larger than it can be scaled,
+ // so we send to the browser a smaller thumbnail, and let the client do the scaling.
+
+ if ($height != -1 && $width > $thumb->width * $height / $thumb->height) {
+ // $height is the limiting factor, not $width
+ // set $width to the largest it can be, such that the resulting
+ // scaled height is at most $height
+ $width = floor($thumb->width * $height / $thumb->height);
+ }
+ $height = round($thumb->height * $width / $thumb->width);
+
+ wfDebug( "makeImageLinkObj: client-size set to '$width x $height'\n" );
+ $url = $thumb->getUrl();
+ } else {
+ $error = htmlspecialchars( $img->getLastError() );
+ // Do client-side scaling...
+ $height = intval( $img->getHeight() * $width / $img->getWidth() );
+ }
+ }
+ } else {
+ $width = $img->width;
+ $height = $img->height;
+ }
+
+ wfDebug( "makeImageLinkObj2: '$width'x'$height'\n" );
+ $u = $nt->escapeLocalURL();
+ if ( $error ) {
+ $s = $error;
+ } elseif ( $url == '' ) {
+ $s = $this->makeBrokenImageLinkObj( $img->getTitle() );
+ //$s .= "<br />{$alt}<br />{$url}<br />\n";
+ } else {
+ $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
+ '<img src="'.$url.'" alt="'.$alt.'" ' .
+ ( $width
+ ? ( 'width="'.$width.'" height="'.$height.'" ' )
+ : '' ) .
+ 'longdesc="'.$u.'" /></a>';
+ }
+ if ( '' != $align ) {
+ $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
+ }
+ return str_replace("\n", ' ',$prefix.$s.$postfix);
+ }
+
+ /**
+ * Make HTML for a thumbnail including image, border and caption
+ * $img is an Image object
+ */
+ function makeThumbLinkObj( $img, $label = '', $alt, $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
+ global $wgStylePath, $wgContLang, $wgGenerateThumbnailOnParse;
+ $thumbUrl = '';
+ $error = '';
+
+ $width = $height = 0;
+ if ( $img->exists() ) {
+ $width = $img->getWidth();
+ $height = $img->getHeight();
+ }
+ if ( 0 == $width || 0 == $height ) {
+ $width = $height = 180;
+ }
+ if ( $boxwidth == 0 ) {
+ $boxwidth = 180;
+ }
+ if ( $framed ) {
+ // Use image dimensions, don't scale
+ $boxwidth = $width;
+ $boxheight = $height;
+ $thumbUrl = $img->getViewURL();
+ } else {
+ if ( $boxheight === false )
+ $boxheight = -1;
+ if ( '' == $manual_thumb ) {
+ $thumb = $img->getThumbnail( $boxwidth, $boxheight, $wgGenerateThumbnailOnParse );
+ if ( $thumb ) {
+ $thumbUrl = $thumb->getUrl();
+ $boxwidth = $thumb->width;
+ $boxheight = $thumb->height;
+ } else {
+ $error = $img->getLastError();
+ }
+ }
+ }
+ $oboxwidth = $boxwidth + 2;
+
+ if ( $manual_thumb != '' ) # Use manually specified thumbnail
+ {
+ $manual_title = Title::makeTitleSafe( NS_IMAGE, $manual_thumb ); #new Title ( $manual_thumb ) ;
+ if( $manual_title ) {
+ $manual_img = new Image( $manual_title );
+ $thumbUrl = $manual_img->getViewURL();
+ if ( $manual_img->exists() )
+ {
+ $width = $manual_img->getWidth();
+ $height = $manual_img->getHeight();
+ $boxwidth = $width ;
+ $boxheight = $height ;
+ $oboxwidth = $boxwidth + 2 ;
+ }
+ }
+ }
+
+ $u = $img->getEscapeLocalURL();
+
+ $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
+ $magnifyalign = $wgContLang->isRTL() ? 'left' : 'right';
+ $textalign = $wgContLang->isRTL() ? ' style="text-align:right"' : '';
+
+ $s = "<div class=\"thumb t{$align}\"><div class=\"thumbinner\" style=\"width:{$oboxwidth}px;\">";
+ if( $thumbUrl == '' ) {
+ // Couldn't generate thumbnail? Scale the image client-side.
+ $thumbUrl = $img->getViewURL();
+ if( $boxheight == -1 ) {
+ // Approximate...
+ $boxheight = intval( $height * $boxwidth / $width );
+ }
+ }
+ if ( $error ) {
+ $s .= htmlspecialchars( $error );
+ $zoomicon = '';
+ } elseif( !$img->exists() ) {
+ $s .= $this->makeBrokenImageLinkObj( $img->getTitle() );
+ $zoomicon = '';
+ } else {
+ $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
+ '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
+ 'width="'.$boxwidth.'" height="'.$boxheight.'" ' .
+ 'longdesc="'.$u.'" class="thumbimage" /></a>';
+ if ( $framed ) {
+ $zoomicon="";
+ } else {
+ $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
+ '<a href="'.$u.'" class="internal" title="'.$more.'">'.
+ '<img src="'.$wgStylePath.'/common/images/magnify-clip.png" ' .
+ 'width="15" height="11" alt="" /></a></div>';
+ }
+ }
+ $s .= ' <div class="thumbcaption"'.$textalign.'>'.$zoomicon.$label."</div></div></div>";
+ return str_replace("\n", ' ', $s);
+ }
+
+ /**
+ * Pass a title object, not a title string
+ */
+ function makeBrokenImageLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ # Fail gracefully
+ if ( ! isset($nt) ) {
+ # throw new MWException();
+ return "<!-- ERROR -->{$prefix}{$text}{$trail}";
+ }
+
+ $fname = 'Linker::makeBrokenImageLinkObj';
+ wfProfileIn( $fname );
+
+ $q = 'wpDestFile=' . urlencode( $nt->getDBkey() );
+ if ( '' != $query ) {
+ $q .= "&$query";
+ }
+ $uploadTitle = SpecialPage::getTitleFor( 'Upload' );
+ $url = $uploadTitle->escapeLocalURL( $q );
+
+ if ( '' == $text ) {
+ $text = htmlspecialchars( $nt->getPrefixedText() );
+ }
+ $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
+ list( $inside, $trail ) = Linker::splitTrail( $trail );
+ $s = "<a href=\"{$url}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
+
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ /** @todo document */
+ function makeMediaLink( $name, /* wtf?! */ $url, $alt = '' ) {
+ $nt = Title::makeTitleSafe( NS_IMAGE, $name );
+ return $this->makeMediaLinkObj( $nt, $alt );
+ }
+
+ /**
+ * Create a direct link to a given uploaded file.
+ *
+ * @param $title Title object.
+ * @param $text String: pre-sanitized HTML
+ * @param $nourl Boolean: Mask absolute URLs, so the parser doesn't
+ * linkify them (it is currently not context-aware)
+ * @return string HTML
+ *
+ * @public
+ * @todo Handle invalid or missing images better.
+ */
+ function makeMediaLinkObj( $title, $text = '' ) {
+ if( is_null( $title ) ) {
+ ### HOTFIX. Instead of breaking, return empty string.
+ return $text;
+ } else {
+ $img = new Image( $title );
+ if( $img->exists() ) {
+ $url = $img->getURL();
+ $class = 'internal';
+ } else {
+ $upload = SpecialPage::getTitleFor( 'Upload' );
+ $url = $upload->getLocalUrl( 'wpDestFile=' . urlencode( $img->getName() ) );
+ $class = 'new';
+ }
+ $alt = htmlspecialchars( $title->getText() );
+ if( $text == '' ) {
+ $text = $alt;
+ }
+ $u = htmlspecialchars( $url );
+ return "<a href=\"{$u}\" class=\"$class\" title=\"{$alt}\">{$text}</a>";
+ }
+ }
+
+ /** @todo document */
+ function specialLink( $name, $key = '' ) {
+ global $wgContLang;
+
+ if ( '' == $key ) { $key = strtolower( $name ); }
+ $pn = $wgContLang->ucfirst( $name );
+ return $this->makeKnownLink( $wgContLang->specialPage( $pn ),
+ wfMsg( $key ) );
+ }
+
+ /** @todo document */
+ function makeExternalLink( $url, $text, $escape = true, $linktype = '', $ns = null ) {
+ $style = $this->getExternalLinkAttributes( $url, $text, 'external ' . $linktype );
+ global $wgNoFollowLinks, $wgNoFollowNsExceptions;
+ if( $wgNoFollowLinks && !(isset($ns) && in_array($ns, $wgNoFollowNsExceptions)) ) {
+ $style .= ' rel="nofollow"';
+ }
+ $url = htmlspecialchars( $url );
+ if( $escape ) {
+ $text = htmlspecialchars( $text );
+ }
+ return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
+ }
+
+ /**
+ * Make user link (or user contributions for unregistered users)
+ * @param $userId Integer: user id in database.
+ * @param $userText String: user name in database
+ * @return string HTML fragment
+ * @private
+ */
+ function userLink( $userId, $userText ) {
+ $encName = htmlspecialchars( $userText );
+ if( $userId == 0 ) {
+ $contribsPage = SpecialPage::getTitleFor( 'Contributions', $userText );
+ return $this->makeKnownLinkObj( $contribsPage,
+ $encName);
+ } else {
+ $userPage = Title::makeTitle( NS_USER, $userText );
+ return $this->makeLinkObj( $userPage, $encName );
+ }
+ }
+
+ /**
+ * @param $userId Integer: user id in database.
+ * @param $userText String: user name in database.
+ * @return string HTML fragment with talk and/or block links
+ * @private
+ */
+ function userToolLinks( $userId, $userText ) {
+ global $wgUser, $wgDisableAnonTalk, $wgSysopUserBans;
+ $talkable = !( $wgDisableAnonTalk && 0 == $userId );
+ $blockable = ( $wgSysopUserBans || 0 == $userId );
+
+ $items = array();
+ if( $talkable ) {
+ $items[] = $this->userTalkLink( $userId, $userText );
+ }
+ if( $userId ) {
+ $contribsPage = SpecialPage::getTitleFor( 'Contributions', $userText );
+ $items[] = $this->makeKnownLinkObj( $contribsPage ,
+ wfMsgHtml( 'contribslink' ) );
+ }
+ if( $blockable && $wgUser->isAllowed( 'block' ) ) {
+ $items[] = $this->blockLink( $userId, $userText );
+ }
+
+ if( $items ) {
+ return ' (' . implode( ' | ', $items ) . ')';
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * @param $userId Integer: user id in database.
+ * @param $userText String: user name in database.
+ * @return string HTML fragment with user talk link
+ * @private
+ */
+ function userTalkLink( $userId, $userText ) {
+ global $wgLang;
+ $talkname = $wgLang->getNsText( NS_TALK ); # use the shorter name
+
+ $userTalkPage = Title::makeTitle( NS_USER_TALK, $userText );
+ $userTalkLink = $this->makeLinkObj( $userTalkPage, $talkname );
+ return $userTalkLink;
+ }
+
+ /**
+ * @param $userId Integer: userid
+ * @param $userText String: user name in database.
+ * @return string HTML fragment with block link
+ * @private
+ */
+ function blockLink( $userId, $userText ) {
+ $blockPage = SpecialPage::getTitleFor( 'Blockip', $userText );
+ $blockLink = $this->makeKnownLinkObj( $blockPage,
+ wfMsgHtml( 'blocklink' ) );
+ return $blockLink;
+ }
+
+ /**
+ * Generate a user link if the current user is allowed to view it
+ * @param $rev Revision object.
+ * @return string HTML
+ */
+ function revUserLink( $rev ) {
+ if( $rev->userCan( Revision::DELETED_USER ) ) {
+ $link = $this->userLink( $rev->getRawUser(), $rev->getRawUserText() );
+ } else {
+ $link = wfMsgHtml( 'rev-deleted-user' );
+ }
+ if( $rev->isDeleted( Revision::DELETED_USER ) ) {
+ return '<span class="history-deleted">' . $link . '</span>';
+ }
+ return $link;
+ }
+
+ /**
+ * Generate a user tool link cluster if the current user is allowed to view it
+ * @param $rev Revision object.
+ * @return string HTML
+ */
+ function revUserTools( $rev ) {
+ if( $rev->userCan( Revision::DELETED_USER ) ) {
+ $link = $this->userLink( $rev->getRawUser(), $rev->getRawUserText() ) .
+ ' ' .
+ $this->userToolLinks( $rev->getRawUser(), $rev->getRawUserText() );
+ } else {
+ $link = wfMsgHtml( 'rev-deleted-user' );
+ }
+ if( $rev->isDeleted( Revision::DELETED_USER ) ) {
+ return '<span class="history-deleted">' . $link . '</span>';
+ }
+ return $link;
+ }
+
+ /**
+ * This function is called by all recent changes variants, by the page history,
+ * and by the user contributions list. It is responsible for formatting edit
+ * comments. It escapes any HTML in the comment, but adds some CSS to format
+ * auto-generated comments (from section editing) and formats [[wikilinks]].
+ *
+ * @author Erik Moeller <moeller@scireview.de>
+ *
+ * Note: there's not always a title to pass to this function.
+ * Since you can't set a default parameter for a reference, I've turned it
+ * temporarily to a value pass. Should be adjusted further. --brion
+ *
+ * $param string $comment
+ * @param mixed $title Title object (to generate link to the section in autocomment) or null
+ * @param bool $local Whether section links should refer to local page
+ */
+ function formatComment($comment, $title = NULL, $local = false) {
+ wfProfileIn( __METHOD__ );
+
+ global $wgContLang;
+ $comment = str_replace( "\n", " ", $comment );
+ $comment = htmlspecialchars( $comment );
+
+ # The pattern for autogen comments is / * foo * /, which makes for
+ # some nasty regex.
+ # We look for all comments, match any text before and after the comment,
+ # add a separator where needed and format the comment itself with CSS
+ $match = array();
+ while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
+ $pre=$match[1];
+ $auto=$match[2];
+ $post=$match[3];
+ $link='';
+ if( $title ) {
+ $section = $auto;
+
+ # Generate a valid anchor name from the section title.
+ # Hackish, but should generally work - we strip wiki
+ # syntax, including the magic [[: that is used to
+ # "link rather than show" in case of images and
+ # interlanguage links.
+ $section = str_replace( '[[:', '', $section );
+ $section = str_replace( '[[', '', $section );
+ $section = str_replace( ']]', '', $section );
+ if ( $local ) {
+ $sectionTitle = Title::newFromText( '#' . $section);
+ } else {
+ $sectionTitle = wfClone( $title );
+ $sectionTitle->mFragment = $section;
+ }
+ $link = $this->makeKnownLinkObj( $sectionTitle, wfMsg( 'sectionlink' ) );
+ }
+ $sep='-';
+ $auto=$link.$auto;
+ if($pre) { $auto = $sep.' '.$auto; }
+ if($post) { $auto .= ' '.$sep; }
+ $auto='<span class="autocomment">'.$auto.'</span>';
+ $comment=$pre.$auto.$post;
+ }
+
+ # format regular and media links - all other wiki formatting
+ # is ignored
+ $medians = '(?:' . preg_quote( Namespace::getCanonicalName( NS_MEDIA ), '/' ) . '|';
+ $medians .= preg_quote( $wgContLang->getNsText( NS_MEDIA ), '/' ) . '):';
+ while(preg_match('/\[\[:?(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
+ # Handle link renaming [[foo|text]] will show link as "text"
+ if( "" != $match[3] ) {
+ $text = $match[3];
+ } else {
+ $text = $match[1];
+ }
+ $submatch = array();
+ if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
+ # Media link; trail not supported.
+ $linkRegexp = '/\[\[(.*?)\]\]/';
+ $thelink = $this->makeMediaLink( $submatch[1], "", $text );
+ } else {
+ # Other kind of link
+ if( preg_match( $wgContLang->linkTrail(), $match[4], $submatch ) ) {
+ $trail = $submatch[1];
+ } else {
+ $trail = "";
+ }
+ $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
+ if (isset($match[1][0]) && $match[1][0] == ':')
+ $match[1] = substr($match[1], 1);
+ $thelink = $this->makeLink( $match[1], $text, "", $trail );
+ }
+ $comment = preg_replace( $linkRegexp, StringUtils::escapeRegexReplacement( $thelink ), $comment, 1 );
+ }
+ wfProfileOut( __METHOD__ );
+ return $comment;
+ }
+
+ /**
+ * Wrap a comment in standard punctuation and formatting if
+ * it's non-empty, otherwise return empty string.
+ *
+ * @param string $comment
+ * @param mixed $title Title object (to generate link to section in autocomment) or null
+ * @param bool $local Whether section links should refer to local page
+ *
+ * @return string
+ */
+ function commentBlock( $comment, $title = NULL, $local = false ) {
+ // '*' used to be the comment inserted by the software way back
+ // in antiquity in case none was provided, here for backwards
+ // compatability, acc. to brion -ævar
+ if( $comment == '' || $comment == '*' ) {
+ return '';
+ } else {
+ $formatted = $this->formatComment( $comment, $title, $local );
+ return " <span class=\"comment\">($formatted)</span>";
+ }
+ }
+
+ /**
+ * Wrap and format the given revision's comment block, if the current
+ * user is allowed to view it.
+ *
+ * @param Revision $rev
+ * @param bool $local Whether section links should refer to local page
+ * @return string HTML
+ */
+ function revComment( Revision $rev, $local = false ) {
+ if( $rev->userCan( Revision::DELETED_COMMENT ) ) {
+ $block = $this->commentBlock( $rev->getRawComment(), $rev->getTitle(), $local );
+ } else {
+ $block = " <span class=\"comment\">" .
+ wfMsgHtml( 'rev-deleted-comment' ) . "</span>";
+ }
+ if( $rev->isDeleted( Revision::DELETED_COMMENT ) ) {
+ return " <span class=\"history-deleted\">$block</span>";
+ }
+ return $block;
+ }
+
+ /** @todo document */
+ function tocIndent() {
+ return "\n<ul>";
+ }
+
+ /** @todo document */
+ function tocUnindent($level) {
+ return "</li>\n" . str_repeat( "</ul>\n</li>\n", $level>0 ? $level : 0 );
+ }
+
+ /**
+ * parameter level defines if we are on an indentation level
+ */
+ function tocLine( $anchor, $tocline, $tocnumber, $level ) {
+ return "\n<li class=\"toclevel-$level\"><a href=\"#" .
+ $anchor . '"><span class="tocnumber">' .
+ $tocnumber . '</span> <span class="toctext">' .
+ $tocline . '</span></a>';
+ }
+
+ /** @todo document */
+ function tocLineEnd() {
+ return "</li>\n";
+ }
+
+ /** @todo document */
+ function tocList($toc) {
+ global $wgJsMimeType;
+ $title = wfMsgForContent('toc') ;
+ return
+ '<table id="toc" class="toc" summary="' . $title .'"><tr><td>'
+ . '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
+ . $toc
+ # no trailing newline, script should not be wrapped in a
+ # paragraph
+ . "</ul>\n</td></tr></table>"
+ . '<script type="' . $wgJsMimeType . '">'
+ . ' if (window.showTocToggle) {'
+ . ' var tocShowText = "' . wfEscapeJsString( wfMsgForContent('showtoc') ) . '";'
+ . ' var tocHideText = "' . wfEscapeJsString( wfMsgForContent('hidetoc') ) . '";'
+ . ' showTocToggle();'
+ . ' } '
+ . "</script>\n";
+ }
+
+ /** @todo document */
+ public function editSectionLinkForOther( $title, $section ) {
+ global $wgContLang;
+
+ $title = Title::newFromText( $title );
+ $editurl = '&section='.$section;
+ $url = $this->makeKnownLinkObj( $title, wfMsg('editsection'), 'action=edit'.$editurl );
+
+ return "<span class=\"editsection\">[".$url."]</span>";
+
+ }
+
+ /**
+ * @param $title Title object.
+ * @param $section Integer: section number.
+ * @param $hint Link String: title, or default if omitted or empty
+ */
+ public function editSectionLink( $nt, $section, $hint='' ) {
+ global $wgContLang;
+
+ $editurl = '&section='.$section;
+ $hint = ( $hint=='' ) ? '' : ' title="' . wfMsgHtml( 'editsectionhint', htmlspecialchars( $hint ) ) . '"';
+ $url = $this->makeKnownLinkObj( $nt, wfMsg('editsection'), 'action=edit'.$editurl, '', '', '', $hint );
+
+ return "<span class=\"editsection\">[".$url."]</span>";
+ }
+
+ /**
+ * Create a headline for content
+ *
+ * @param int $level The level of the headline (1-6)
+ * @param string $attribs Any attributes for the headline, starting with a space and ending with '>'
+ * This *must* be at least '>' for no attribs
+ * @param string $anchor The anchor to give the headline (the bit after the #)
+ * @param string $text The text of the header
+ * @param string $link HTML to add for the section edit link
+ *
+ * @return string HTML headline
+ */
+ public function makeHeadline( $level, $attribs, $anchor, $text, $link ) {
+ return "<a name=\"$anchor\"></a><h$level$attribs$link <span class=\"mw-headline\">$text</span></h$level>";
+ }
+
+ /**
+ * Split a link trail, return the "inside" portion and the remainder of the trail
+ * as a two-element array
+ *
+ * @static
+ */
+ static function splitTrail( $trail ) {
+ static $regex = false;
+ if ( $regex === false ) {
+ global $wgContLang;
+ $regex = $wgContLang->linkTrail();
+ }
+ $inside = '';
+ if ( '' != $trail ) {
+ $m = array();
+ if ( preg_match( $regex, $trail, $m ) ) {
+ $inside = $m[1];
+ $trail = $m[2];
+ }
+ }
+ return array( $inside, $trail );
+ }
+
+ /**
+ * Generate a rollback link for a given revision. Currently it's the
+ * caller's responsibility to ensure that the revision is the top one. If
+ * it's not, of course, the user will get an error message.
+ *
+ * If the calling page is called with the parameter &bot=1, all rollback
+ * links also get that parameter. It causes the edit itself and the rollback
+ * to be marked as "bot" edits. Bot edits are hidden by default from recent
+ * changes, so this allows sysops to combat a busy vandal without bothering
+ * other users.
+ *
+ * @param Revision $rev
+ */
+ function generateRollback( $rev ) {
+ global $wgUser, $wgRequest;
+ $title = $rev->getTitle();
+
+ $extraRollback = $wgRequest->getBool( 'bot' ) ? '&bot=1' : '';
+ $extraRollback .= '&token=' . urlencode(
+ $wgUser->editToken( array( $title->getPrefixedText(), $rev->getUserText() ) ) );
+ return '<span class="mw-rollback-link">['. $this->makeKnownLinkObj( $title,
+ wfMsg('rollbacklink'),
+ 'action=rollback&from=' . urlencode( $rev->getUserText() ) . $extraRollback ) .']</span>';
+ }
+
+ /**
+ * Returns HTML for the "templates used on this page" list.
+ *
+ * @param array $templates Array of templates from Article::getUsedTemplate
+ * or similar
+ * @param bool $preview Whether this is for a preview
+ * @param bool $section Whether this is for a section edit
+ * @return string HTML output
+ */
+ public function formatTemplates( $templates, $preview = false, $section = false) {
+ global $wgUser;
+ wfProfileIn( __METHOD__ );
+
+ $sk =& $wgUser->getSkin();
+
+ $outText = '';
+ if ( count( $templates ) > 0 ) {
+ # Do a batch existence check
+ $batch = new LinkBatch;
+ foreach( $templates as $title ) {
+ $batch->addObj( $title );
+ }
+ $batch->execute();
+
+ # Construct the HTML
+ $outText = '<div class="mw-templatesUsedExplanation">';
+ if ( $preview ) {
+ $outText .= wfMsgExt( 'templatesusedpreview', array( 'parse' ) );
+ } elseif ( $section ) {
+ $outText .= wfMsgExt( 'templatesusedsection', array( 'parse' ) );
+ } else {
+ $outText .= wfMsgExt( 'templatesused', array( 'parse' ) );
+ }
+ $outText .= '</div><ul>';
+
+ foreach ( $templates as $titleObj ) {
+ $r = $titleObj->getRestrictions( 'edit' );
+ if ( in_array( 'sysop', $r ) ) {
+ $protected = wfMsgExt( 'template-protected', array( 'parseinline' ) );
+ } elseif ( in_array( 'autoconfirmed', $r ) ) {
+ $protected = wfMsgExt( 'template-semiprotected', array( 'parseinline' ) );
+ } else {
+ $protected = '';
+ }
+ $outText .= '<li>' . $sk->makeLinkObj( $titleObj ) . ' ' . $protected . '</li>';
+ }
+ $outText .= '</ul>';
+ }
+ wfProfileOut( __METHOD__ );
+ return $outText;
+ }
+
+ /**
+ * Format a size in bytes for output, using an appropriate
+ * unit (B, KB, MB or GB) according to the magnitude in question
+ *
+ * @param $size Size to format
+ * @return string
+ */
+ public function formatSize( $size ) {
+ global $wgLang;
+ if( $size > 1024 ) {
+ $size = $size / 1024;
+ if( $size > 1024 ) {
+ $size = $size / 1024;
+ if( $size > 1024 ) {
+ $size = $size / 1024;
+ $msg = 'size-gigabytes';
+ } else {
+ $msg = 'size-megabytes';
+ }
+ } else {
+ $msg = 'size-kilobytes';
+ }
+ } else {
+ $msg = 'size-bytes';
+ }
+ $size = round( $size, 0 );
+ return wfMsgHtml( $msg, $wgLang->formatNum( $size ) );
+ }
+
+}
+
+?>
diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php
new file mode 100644
index 000000000000..9e25bf07d0ae
--- /dev/null
+++ b/includes/LinksUpdate.php
@@ -0,0 +1,601 @@
+<?php
+/**
+ * See deferred.txt
+ * @package MediaWiki
+ */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class LinksUpdate {
+
+ /**@{{
+ * @private
+ */
+ var $mId, //!< Page ID of the article linked from
+ $mTitle, //!< Title object of the article linked from
+ $mLinks, //!< Map of title strings to IDs for the links in the document
+ $mImages, //!< DB keys of the images used, in the array key only
+ $mTemplates, //!< Map of title strings to IDs for the template references, including broken ones
+ $mExternals, //!< URLs of external links, array key only
+ $mCategories, //!< Map of category names to sort keys
+ $mInterlangs, //!< Map of language codes to titles
+ $mDb, //!< Database connection reference
+ $mOptions, //!< SELECT options to be used (array)
+ $mRecursive; //!< Whether to queue jobs for recursive updates
+ /**@}}*/
+
+ /**
+ * Constructor
+ * Initialize private variables
+ * @param $title Integer: FIXME
+ * @param $parserOutput FIXME
+ * @param $recursive Boolean: FIXME, default 'true'.
+ */
+ function LinksUpdate( $title, $parserOutput, $recursive = true ) {
+ global $wgAntiLockFlags;
+
+ if ( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) {
+ $this->mOptions = array();
+ } else {
+ $this->mOptions = array( 'FOR UPDATE' );
+ }
+ $this->mDb =& wfGetDB( DB_MASTER );
+
+ if ( !is_object( $title ) ) {
+ throw new MWException( "The calling convention to LinksUpdate::LinksUpdate() has changed. " .
+ "Please see Article::editUpdates() for an invocation example.\n" );
+ }
+ $this->mTitle = $title;
+ $this->mId = $title->getArticleID();
+
+ $this->mLinks = $parserOutput->getLinks();
+ $this->mImages = $parserOutput->getImages();
+ $this->mTemplates = $parserOutput->getTemplates();
+ $this->mExternals = $parserOutput->getExternalLinks();
+ $this->mCategories = $parserOutput->getCategories();
+
+ # Convert the format of the interlanguage links
+ # I didn't want to change it in the ParserOutput, because that array is passed all
+ # the way back to the skin, so either a skin API break would be required, or an
+ # inefficient back-conversion.
+ $ill = $parserOutput->getLanguageLinks();
+ $this->mInterlangs = array();
+ foreach ( $ill as $link ) {
+ list( $key, $title ) = explode( ':', $link, 2 );
+ $this->mInterlangs[$key] = $title;
+ }
+
+ $this->mRecursive = $recursive;
+ }
+
+ /**
+ * Update link tables with outgoing links from an updated article
+ */
+ function doUpdate() {
+ global $wgUseDumbLinkUpdate;
+ if ( $wgUseDumbLinkUpdate ) {
+ $this->doDumbUpdate();
+ } else {
+ $this->doIncrementalUpdate();
+ }
+ }
+
+ function doIncrementalUpdate() {
+ $fname = 'LinksUpdate::doIncrementalUpdate';
+ wfProfileIn( $fname );
+
+ # Page links
+ $existing = $this->getExistingLinks();
+ $this->incrTableUpdate( 'pagelinks', 'pl', $this->getLinkDeletions( $existing ),
+ $this->getLinkInsertions( $existing ) );
+
+ # Image links
+ $existing = $this->getExistingImages();
+ $this->incrTableUpdate( 'imagelinks', 'il', $this->getImageDeletions( $existing ),
+ $this->getImageInsertions( $existing ) );
+
+ # Invalidate all image description pages which had links added or removed
+ $imageUpdates = array_diff_key( $existing, $this->mImages ) + array_diff_key( $this->mImages, $existing );
+ $this->invalidateImageDescriptions( $imageUpdates );
+
+ # External links
+ $existing = $this->getExistingExternals();
+ $this->incrTableUpdate( 'externallinks', 'el', $this->getExternalDeletions( $existing ),
+ $this->getExternalInsertions( $existing ) );
+
+ # Language links
+ $existing = $this->getExistingInterlangs();
+ $this->incrTableUpdate( 'langlinks', 'll', $this->getInterlangDeletions( $existing ),
+ $this->getInterlangInsertions( $existing ) );
+
+ # Template links
+ $existing = $this->getExistingTemplates();
+ $this->incrTableUpdate( 'templatelinks', 'tl', $this->getTemplateDeletions( $existing ),
+ $this->getTemplateInsertions( $existing ) );
+
+ # Category links
+ $existing = $this->getExistingCategories();
+ $this->incrTableUpdate( 'categorylinks', 'cl', $this->getCategoryDeletions( $existing ),
+ $this->getCategoryInsertions( $existing ) );
+
+ # Invalidate all categories which were added, deleted or changed (set symmetric difference)
+ $categoryUpdates = array_diff_assoc( $existing, $this->mCategories ) + array_diff_assoc( $this->mCategories, $existing );
+ $this->invalidateCategories( $categoryUpdates );
+
+ # Refresh links of all pages including this page
+ # This will be in a separate transaction
+ if ( $this->mRecursive ) {
+ $this->queueRecursiveJobs();
+ }
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Link update which clears the previous entries and inserts new ones
+ * May be slower or faster depending on level of lock contention and write speed of DB
+ * Also useful where link table corruption needs to be repaired, e.g. in refreshLinks.php
+ */
+ function doDumbUpdate() {
+ $fname = 'LinksUpdate::doDumbUpdate';
+ wfProfileIn( $fname );
+
+ # Refresh category pages and image description pages
+ $existing = $this->getExistingCategories();
+ $categoryUpdates = array_diff_assoc( $existing, $this->mCategories ) + array_diff_assoc( $this->mCategories, $existing );
+ $existing = $this->getExistingImages();
+ $imageUpdates = array_diff_key( $existing, $this->mImages ) + array_diff_key( $this->mImages, $existing );
+
+ $this->dumbTableUpdate( 'pagelinks', $this->getLinkInsertions(), 'pl_from' );
+ $this->dumbTableUpdate( 'imagelinks', $this->getImageInsertions(), 'il_from' );
+ $this->dumbTableUpdate( 'categorylinks', $this->getCategoryInsertions(), 'cl_from' );
+ $this->dumbTableUpdate( 'templatelinks', $this->getTemplateInsertions(), 'tl_from' );
+ $this->dumbTableUpdate( 'externallinks', $this->getExternalInsertions(), 'el_from' );
+ $this->dumbTableUpdate( 'langlinks', $this->getInterlangInsertions(), 'll_from' );
+
+ # Update the cache of all the category pages and image description pages which were changed
+ $this->invalidateCategories( $categoryUpdates );
+ $this->invalidateImageDescriptions( $imageUpdates );
+
+ # Refresh links of all pages including this page
+ # This will be in a separate transaction
+ if ( $this->mRecursive ) {
+ $this->queueRecursiveJobs();
+ }
+
+ wfProfileOut( $fname );
+ }
+
+ function queueRecursiveJobs() {
+ wfProfileIn( __METHOD__ );
+
+ $batchSize = 100;
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( array( 'templatelinks', 'page' ),
+ array( 'page_namespace', 'page_title' ),
+ array(
+ 'page_id=tl_from',
+ 'tl_namespace' => $this->mTitle->getNamespace(),
+ 'tl_title' => $this->mTitle->getDBkey()
+ ), __METHOD__
+ );
+
+ $done = false;
+ while ( !$done ) {
+ $jobs = array();
+ for ( $i = 0; $i < $batchSize; $i++ ) {
+ $row = $dbr->fetchObject( $res );
+ if ( !$row ) {
+ $done = true;
+ break;
+ }
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $jobs[] = Job::factory( 'refreshLinks', $title );
+ }
+ Job::batchInsert( $jobs );
+ }
+ $dbr->freeResult( $res );
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Invalidate the cache of a list of pages from a single namespace
+ *
+ * @param integer $namespace
+ * @param array $dbkeys
+ */
+ function invalidatePages( $namespace, $dbkeys ) {
+ $fname = 'LinksUpdate::invalidatePages';
+
+ if ( !count( $dbkeys ) ) {
+ return;
+ }
+
+ /**
+ * Determine which pages need to be updated
+ * This is necessary to prevent the job queue from smashing the DB with
+ * large numbers of concurrent invalidations of the same page
+ */
+ $now = $this->mDb->timestamp();
+ $ids = array();
+ $res = $this->mDb->select( 'page', array( 'page_id' ),
+ array(
+ 'page_namespace' => $namespace,
+ 'page_title IN (' . $this->mDb->makeList( $dbkeys ) . ')',
+ 'page_touched < ' . $this->mDb->addQuotes( $now )
+ ), $fname
+ );
+ while ( $row = $this->mDb->fetchObject( $res ) ) {
+ $ids[] = $row->page_id;
+ }
+ if ( !count( $ids ) ) {
+ return;
+ }
+
+ /**
+ * Do the update
+ * We still need the page_touched condition, in case the row has changed since
+ * the non-locking select above.
+ */
+ $this->mDb->update( 'page', array( 'page_touched' => $now ),
+ array(
+ 'page_id IN (' . $this->mDb->makeList( $ids ) . ')',
+ 'page_touched < ' . $this->mDb->addQuotes( $now )
+ ), $fname
+ );
+ }
+
+ function invalidateCategories( $cats ) {
+ $this->invalidatePages( NS_CATEGORY, array_keys( $cats ) );
+ }
+
+ function invalidateImageDescriptions( $images ) {
+ $this->invalidatePages( NS_IMAGE, array_keys( $images ) );
+ }
+
+ function dumbTableUpdate( $table, $insertions, $fromField ) {
+ $fname = 'LinksUpdate::dumbTableUpdate';
+ $this->mDb->delete( $table, array( $fromField => $this->mId ), $fname );
+ if ( count( $insertions ) ) {
+ # The link array was constructed without FOR UPDATE, so there may be collisions
+ # This may cause minor link table inconsistencies, which is better than
+ # crippling the site with lock contention.
+ $this->mDb->insert( $table, $insertions, $fname, array( 'IGNORE' ) );
+ }
+ }
+
+ /**
+ * Make a WHERE clause from a 2-d NS/dbkey array
+ *
+ * @param array $arr 2-d array indexed by namespace and DB key
+ * @param string $prefix Field name prefix, without the underscore
+ */
+ function makeWhereFrom2d( &$arr, $prefix ) {
+ $lb = new LinkBatch;
+ $lb->setArray( $arr );
+ return $lb->constructSet( $prefix, $this->mDb );
+ }
+
+ /**
+ * Update a table by doing a delete query then an insert query
+ * @private
+ */
+ function incrTableUpdate( $table, $prefix, $deletions, $insertions ) {
+ $fname = 'LinksUpdate::incrTableUpdate';
+ $where = array( "{$prefix}_from" => $this->mId );
+ if ( $table == 'pagelinks' || $table == 'templatelinks' ) {
+ $clause = $this->makeWhereFrom2d( $deletions, $prefix );
+ if ( $clause ) {
+ $where[] = $clause;
+ } else {
+ $where = false;
+ }
+ } else {
+ if ( $table == 'langlinks' ) {
+ $toField = 'll_lang';
+ } else {
+ $toField = $prefix . '_to';
+ }
+ if ( count( $deletions ) ) {
+ $where[] = "$toField IN (" . $this->mDb->makeList( array_keys( $deletions ) ) . ')';
+ } else {
+ $where = false;
+ }
+ }
+ if ( $where ) {
+ $this->mDb->delete( $table, $where, $fname );
+ }
+ if ( count( $insertions ) ) {
+ $this->mDb->insert( $table, $insertions, $fname, 'IGNORE' );
+ }
+ }
+
+
+ /**
+ * Get an array of pagelinks insertions for passing to the DB
+ * Skips the titles specified by the 2-D array $existing
+ * @private
+ */
+ function getLinkInsertions( $existing = array() ) {
+ $arr = array();
+ foreach( $this->mLinks as $ns => $dbkeys ) {
+ # array_diff_key() was introduced in PHP 5.1, there is a compatibility function
+ # in GlobalFunctions.php
+ $diffs = isset( $existing[$ns] ) ? array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys;
+ foreach ( $diffs as $dbk => $id ) {
+ $arr[] = array(
+ 'pl_from' => $this->mId,
+ 'pl_namespace' => $ns,
+ 'pl_title' => $dbk
+ );
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * Get an array of template insertions. Like getLinkInsertions()
+ * @private
+ */
+ function getTemplateInsertions( $existing = array() ) {
+ $arr = array();
+ foreach( $this->mTemplates as $ns => $dbkeys ) {
+ $diffs = isset( $existing[$ns] ) ? array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys;
+ foreach ( $diffs as $dbk => $id ) {
+ $arr[] = array(
+ 'tl_from' => $this->mId,
+ 'tl_namespace' => $ns,
+ 'tl_title' => $dbk
+ );
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * Get an array of image insertions
+ * Skips the names specified in $existing
+ * @private
+ */
+ function getImageInsertions( $existing = array() ) {
+ $arr = array();
+ $diffs = array_diff_key( $this->mImages, $existing );
+ foreach( $diffs as $iname => $dummy ) {
+ $arr[] = array(
+ 'il_from' => $this->mId,
+ 'il_to' => $iname
+ );
+ }
+ return $arr;
+ }
+
+ /**
+ * Get an array of externallinks insertions. Skips the names specified in $existing
+ * @private
+ */
+ function getExternalInsertions( $existing = array() ) {
+ $arr = array();
+ $diffs = array_diff_key( $this->mExternals, $existing );
+ foreach( $diffs as $url => $dummy ) {
+ $arr[] = array(
+ 'el_from' => $this->mId,
+ 'el_to' => $url,
+ 'el_index' => wfMakeUrlIndex( $url ),
+ );
+ }
+ return $arr;
+ }
+
+ /**
+ * Get an array of category insertions
+ * @param array $existing Array mapping existing category names to sort keys. If both
+ * match a link in $this, the link will be omitted from the output
+ * @private
+ */
+ function getCategoryInsertions( $existing = array() ) {
+ $diffs = array_diff_assoc( $this->mCategories, $existing );
+ $arr = array();
+ foreach ( $diffs as $name => $sortkey ) {
+ $arr[] = array(
+ 'cl_from' => $this->mId,
+ 'cl_to' => $name,
+ 'cl_sortkey' => $sortkey,
+ 'cl_timestamp' => $this->mDb->timestamp()
+ );
+ }
+ return $arr;
+ }
+
+ /**
+ * Get an array of interlanguage link insertions
+ * @param array $existing Array mapping existing language codes to titles
+ * @private
+ */
+ function getInterlangInsertions( $existing = array() ) {
+ $diffs = array_diff_assoc( $this->mInterlangs, $existing );
+ $arr = array();
+ foreach( $diffs as $lang => $title ) {
+ $arr[] = array(
+ 'll_from' => $this->mId,
+ 'll_lang' => $lang,
+ 'll_title' => $title
+ );
+ }
+ return $arr;
+ }
+
+ /**
+ * Given an array of existing links, returns those links which are not in $this
+ * and thus should be deleted.
+ * @private
+ */
+ function getLinkDeletions( $existing ) {
+ $del = array();
+ foreach ( $existing as $ns => $dbkeys ) {
+ if ( isset( $this->mLinks[$ns] ) ) {
+ $del[$ns] = array_diff_key( $existing[$ns], $this->mLinks[$ns] );
+ } else {
+ $del[$ns] = $existing[$ns];
+ }
+ }
+ return $del;
+ }
+
+ /**
+ * Given an array of existing templates, returns those templates which are not in $this
+ * and thus should be deleted.
+ * @private
+ */
+ function getTemplateDeletions( $existing ) {
+ $del = array();
+ foreach ( $existing as $ns => $dbkeys ) {
+ if ( isset( $this->mTemplates[$ns] ) ) {
+ $del[$ns] = array_diff_key( $existing[$ns], $this->mTemplates[$ns] );
+ } else {
+ $del[$ns] = $existing[$ns];
+ }
+ }
+ return $del;
+ }
+
+ /**
+ * Given an array of existing images, returns those images which are not in $this
+ * and thus should be deleted.
+ * @private
+ */
+ function getImageDeletions( $existing ) {
+ return array_diff_key( $existing, $this->mImages );
+ }
+
+ /**
+ * Given an array of existing external links, returns those links which are not
+ * in $this and thus should be deleted.
+ * @private
+ */
+ function getExternalDeletions( $existing ) {
+ return array_diff_key( $existing, $this->mExternals );
+ }
+
+ /**
+ * Given an array of existing categories, returns those categories which are not in $this
+ * and thus should be deleted.
+ * @private
+ */
+ function getCategoryDeletions( $existing ) {
+ return array_diff_assoc( $existing, $this->mCategories );
+ }
+
+ /**
+ * Given an array of existing interlanguage links, returns those links which are not
+ * in $this and thus should be deleted.
+ * @private
+ */
+ function getInterlangDeletions( $existing ) {
+ return array_diff_assoc( $existing, $this->mInterlangs );
+ }
+
+ /**
+ * Get an array of existing links, as a 2-D array
+ * @private
+ */
+ function getExistingLinks() {
+ $fname = 'LinksUpdate::getExistingLinks';
+ $res = $this->mDb->select( 'pagelinks', array( 'pl_namespace', 'pl_title' ),
+ array( 'pl_from' => $this->mId ), $fname, $this->mOptions );
+ $arr = array();
+ while ( $row = $this->mDb->fetchObject( $res ) ) {
+ if ( !isset( $arr[$row->pl_namespace] ) ) {
+ $arr[$row->pl_namespace] = array();
+ }
+ $arr[$row->pl_namespace][$row->pl_title] = 1;
+ }
+ $this->mDb->freeResult( $res );
+ return $arr;
+ }
+
+ /**
+ * Get an array of existing templates, as a 2-D array
+ * @private
+ */
+ function getExistingTemplates() {
+ $fname = 'LinksUpdate::getExistingTemplates';
+ $res = $this->mDb->select( 'templatelinks', array( 'tl_namespace', 'tl_title' ),
+ array( 'tl_from' => $this->mId ), $fname, $this->mOptions );
+ $arr = array();
+ while ( $row = $this->mDb->fetchObject( $res ) ) {
+ if ( !isset( $arr[$row->tl_namespace] ) ) {
+ $arr[$row->tl_namespace] = array();
+ }
+ $arr[$row->tl_namespace][$row->tl_title] = 1;
+ }
+ $this->mDb->freeResult( $res );
+ return $arr;
+ }
+
+ /**
+ * Get an array of existing images, image names in the keys
+ * @private
+ */
+ function getExistingImages() {
+ $fname = 'LinksUpdate::getExistingImages';
+ $res = $this->mDb->select( 'imagelinks', array( 'il_to' ),
+ array( 'il_from' => $this->mId ), $fname, $this->mOptions );
+ $arr = array();
+ while ( $row = $this->mDb->fetchObject( $res ) ) {
+ $arr[$row->il_to] = 1;
+ }
+ $this->mDb->freeResult( $res );
+ return $arr;
+ }
+
+ /**
+ * Get an array of existing external links, URLs in the keys
+ * @private
+ */
+ function getExistingExternals() {
+ $fname = 'LinksUpdate::getExistingExternals';
+ $res = $this->mDb->select( 'externallinks', array( 'el_to' ),
+ array( 'el_from' => $this->mId ), $fname, $this->mOptions );
+ $arr = array();
+ while ( $row = $this->mDb->fetchObject( $res ) ) {
+ $arr[$row->el_to] = 1;
+ }
+ $this->mDb->freeResult( $res );
+ return $arr;
+ }
+
+ /**
+ * Get an array of existing categories, with the name in the key and sort key in the value.
+ * @private
+ */
+ function getExistingCategories() {
+ $fname = 'LinksUpdate::getExistingCategories';
+ $res = $this->mDb->select( 'categorylinks', array( 'cl_to', 'cl_sortkey' ),
+ array( 'cl_from' => $this->mId ), $fname, $this->mOptions );
+ $arr = array();
+ while ( $row = $this->mDb->fetchObject( $res ) ) {
+ $arr[$row->cl_to] = $row->cl_sortkey;
+ }
+ $this->mDb->freeResult( $res );
+ return $arr;
+ }
+
+ /**
+ * Get an array of existing interlanguage links, with the language code in the key and the
+ * title in the value.
+ * @private
+ */
+ function getExistingInterlangs() {
+ $fname = 'LinksUpdate::getExistingInterlangs';
+ $res = $this->mDb->select( 'langlinks', array( 'll_lang', 'll_title' ),
+ array( 'll_from' => $this->mId ), $fname, $this->mOptions );
+ $arr = array();
+ while ( $row = $this->mDb->fetchObject( $res ) ) {
+ $arr[$row->ll_lang] = $row->ll_title;
+ }
+ return $arr;
+ }
+}
+?>
diff --git a/includes/LoadBalancer.php b/includes/LoadBalancer.php
new file mode 100644
index 000000000000..396ef865be4f
--- /dev/null
+++ b/includes/LoadBalancer.php
@@ -0,0 +1,650 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ */
+
+
+/**
+ * Database load balancing object
+ *
+ * @todo document
+ * @package MediaWiki
+ */
+class LoadBalancer {
+ /* private */ var $mServers, $mConnections, $mLoads, $mGroupLoads;
+ /* private */ var $mFailFunction, $mErrorConnection;
+ /* private */ var $mForce, $mReadIndex, $mLastIndex, $mAllowLagged;
+ /* private */ var $mWaitForFile, $mWaitForPos, $mWaitTimeout;
+ /* private */ var $mLaggedSlaveMode, $mLastError = 'Unknown error';
+
+ /**
+ * Scale polling time so that under overload conditions, the database server
+ * receives a SHOW STATUS query at an average interval of this many microseconds
+ */
+ const AVG_STATUS_POLL = 2000;
+
+ function LoadBalancer( $servers, $failFunction = false, $waitTimeout = 10, $waitForMasterNow = false )
+ {
+ $this->mServers = $servers;
+ $this->mFailFunction = $failFunction;
+ $this->mReadIndex = -1;
+ $this->mWriteIndex = -1;
+ $this->mForce = -1;
+ $this->mConnections = array();
+ $this->mLastIndex = 1;
+ $this->mLoads = array();
+ $this->mWaitForFile = false;
+ $this->mWaitForPos = false;
+ $this->mWaitTimeout = $waitTimeout;
+ $this->mLaggedSlaveMode = false;
+ $this->mErrorConnection = false;
+ $this->mAllowLag = false;
+
+ foreach( $servers as $i => $server ) {
+ $this->mLoads[$i] = $server['load'];
+ if ( isset( $server['groupLoads'] ) ) {
+ foreach ( $server['groupLoads'] as $group => $ratio ) {
+ if ( !isset( $this->mGroupLoads[$group] ) ) {
+ $this->mGroupLoads[$group] = array();
+ }
+ $this->mGroupLoads[$group][$i] = $ratio;
+ }
+ }
+ }
+ if ( $waitForMasterNow ) {
+ $this->loadMasterPos();
+ }
+ }
+
+ static function newFromParams( $servers, $failFunction = false, $waitTimeout = 10 )
+ {
+ return new LoadBalancer( $servers, $failFunction, $waitTimeout );
+ }
+
+ /**
+ * Given an array of non-normalised probabilities, this function will select
+ * an element and return the appropriate key
+ */
+ function pickRandom( $weights )
+ {
+ if ( !is_array( $weights ) || count( $weights ) == 0 ) {
+ return false;
+ }
+
+ $sum = array_sum( $weights );
+ if ( $sum == 0 ) {
+ # No loads on any of them
+ # In previous versions, this triggered an unweighted random selection,
+ # but this feature has been removed as of April 2006 to allow for strict
+ # separation of query groups.
+ return false;
+ }
+ $max = mt_getrandmax();
+ $rand = mt_rand(0, $max) / $max * $sum;
+
+ $sum = 0;
+ foreach ( $weights as $i => $w ) {
+ $sum += $w;
+ if ( $sum >= $rand ) {
+ break;
+ }
+ }
+ return $i;
+ }
+
+ function getRandomNonLagged( $loads ) {
+ # Unset excessively lagged servers
+ $lags = $this->getLagTimes();
+ foreach ( $lags as $i => $lag ) {
+ if ( isset( $this->mServers[$i]['max lag'] ) && $lag > $this->mServers[$i]['max lag'] ) {
+ unset( $loads[$i] );
+ }
+ }
+
+ # Find out if all the slaves with non-zero load are lagged
+ $sum = 0;
+ foreach ( $loads as $load ) {
+ $sum += $load;
+ }
+ if ( $sum == 0 ) {
+ # No appropriate DB servers except maybe the master and some slaves with zero load
+ # Do NOT use the master
+ # Instead, this function will return false, triggering read-only mode,
+ # and a lagged slave will be used instead.
+ return false;
+ }
+
+ if ( count( $loads ) == 0 ) {
+ return false;
+ }
+
+ #wfDebugLog( 'connect', var_export( $loads, true ) );
+
+ # Return a random representative of the remainder
+ return $this->pickRandom( $loads );
+ }
+
+ /**
+ * Get the index of the reader connection, which may be a slave
+ * This takes into account load ratios and lag times. It should
+ * always return a consistent index during a given invocation
+ *
+ * Side effect: opens connections to databases
+ */
+ function getReaderIndex() {
+ global $wgReadOnly, $wgDBClusterTimeout;
+
+ $fname = 'LoadBalancer::getReaderIndex';
+ wfProfileIn( $fname );
+
+ $i = false;
+ if ( $this->mForce >= 0 ) {
+ $i = $this->mForce;
+ } elseif ( count( $this->mServers ) == 1 ) {
+ # Skip the load balancing if there's only one server
+ $i = 0;
+ } else {
+ if ( $this->mReadIndex >= 0 ) {
+ $i = $this->mReadIndex;
+ } else {
+ # $loads is $this->mLoads except with elements knocked out if they
+ # don't work
+ $loads = $this->mLoads;
+ $done = false;
+ $totalElapsed = 0;
+ do {
+ if ( $wgReadOnly or $this->mAllowLagged ) {
+ $i = $this->pickRandom( $loads );
+ } else {
+ $i = $this->getRandomNonLagged( $loads );
+ if ( $i === false && count( $loads ) != 0 ) {
+ # All slaves lagged. Switch to read-only mode
+ $wgReadOnly = wfMsgNoDBForContent( 'readonly_lag' );
+ $i = $this->pickRandom( $loads );
+ }
+ }
+ $serverIndex = $i;
+ if ( $i !== false ) {
+ wfDebugLog( 'connect', "$fname: Using reader #$i: {$this->mServers[$i]['host']}...\n" );
+ $this->openConnection( $i );
+
+ if ( !$this->isOpen( $i ) ) {
+ wfDebug( "$fname: Failed\n" );
+ unset( $loads[$i] );
+ $sleepTime = 0;
+ } else {
+ if ( isset( $this->mServers[$i]['max threads'] ) ) {
+ $status = $this->mConnections[$i]->getStatus("Thread%");
+ if ( $status['Threads_running'] > $this->mServers[$i]['max threads'] ) {
+ # Too much load, back off and wait for a while.
+ # The sleep time is scaled by the number of threads connected,
+ # to produce a roughly constant global poll rate.
+ $sleepTime = self::AVG_STATUS_POLL * $status['Threads_connected'];
+
+ # If we reach the timeout and exit the loop, don't use it
+ $i = false;
+ } else {
+ $done = true;
+ $sleepTime = 0;
+ }
+ } else {
+ $done = true;
+ $sleepTime = 0;
+ }
+ }
+ } else {
+ $sleepTime = 500000;
+ }
+ if ( $sleepTime ) {
+ $totalElapsed += $sleepTime;
+ $x = "{$this->mServers[$serverIndex]['host']} [$serverIndex]";
+ wfProfileIn( "$fname-sleep $x" );
+ usleep( $sleepTime );
+ wfProfileOut( "$fname-sleep $x" );
+ }
+ } while ( count( $loads ) && !$done && $totalElapsed / 1e6 < $wgDBClusterTimeout );
+
+ if ( $totalElapsed / 1e6 >= $wgDBClusterTimeout ) {
+ $this->mErrorConnection = false;
+ $this->mLastError = 'All servers busy';
+ }
+
+ if ( $i !== false && $this->isOpen( $i ) ) {
+ # Wait for the session master pos for a short time
+ if ( $this->mWaitForFile ) {
+ if ( !$this->doWait( $i ) ) {
+ $this->mServers[$i]['slave pos'] = $this->mConnections[$i]->getSlavePos();
+ }
+ }
+ if ( $i !== false ) {
+ $this->mReadIndex = $i;
+ }
+ } else {
+ $i = false;
+ }
+ }
+ }
+ wfProfileOut( $fname );
+ return $i;
+ }
+
+ /**
+ * Get a random server to use in a query group
+ */
+ function getGroupIndex( $group ) {
+ if ( isset( $this->mGroupLoads[$group] ) ) {
+ $i = $this->pickRandom( $this->mGroupLoads[$group] );
+ } else {
+ $i = false;
+ }
+ wfDebug( "Query group $group => $i\n" );
+ return $i;
+ }
+
+ /**
+ * Set the master wait position
+ * If a DB_SLAVE connection has been opened already, waits
+ * Otherwise sets a variable telling it to wait if such a connection is opened
+ */
+ function waitFor( $file, $pos ) {
+ $fname = 'LoadBalancer::waitFor';
+ wfProfileIn( $fname );
+
+ wfDebug( "User master pos: $file $pos\n" );
+ $this->mWaitForFile = false;
+ $this->mWaitForPos = false;
+
+ if ( count( $this->mServers ) > 1 ) {
+ $this->mWaitForFile = $file;
+ $this->mWaitForPos = $pos;
+ $i = $this->mReadIndex;
+
+ if ( $i > 0 ) {
+ if ( !$this->doWait( $i ) ) {
+ $this->mServers[$i]['slave pos'] = $this->mConnections[$i]->getSlavePos();
+ $this->mLaggedSlaveMode = true;
+ }
+ }
+ }
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Wait for a given slave to catch up to the master pos stored in $this
+ */
+ function doWait( $index ) {
+ global $wgMemc;
+
+ $retVal = false;
+
+ # Debugging hacks
+ if ( isset( $this->mServers[$index]['lagged slave'] ) ) {
+ return false;
+ } elseif ( isset( $this->mServers[$index]['fake slave'] ) ) {
+ return true;
+ }
+
+ $key = 'masterpos:' . $index;
+ $memcPos = $wgMemc->get( $key );
+ if ( $memcPos ) {
+ list( $file, $pos ) = explode( ' ', $memcPos );
+ # If the saved position is later than the requested position, return now
+ if ( $file == $this->mWaitForFile && $this->mWaitForPos <= $pos ) {
+ $retVal = true;
+ }
+ }
+
+ if ( !$retVal && $this->isOpen( $index ) ) {
+ $conn =& $this->mConnections[$index];
+ wfDebug( "Waiting for slave #$index to catch up...\n" );
+ $result = $conn->masterPosWait( $this->mWaitForFile, $this->mWaitForPos, $this->mWaitTimeout );
+
+ if ( $result == -1 || is_null( $result ) ) {
+ # Timed out waiting for slave, use master instead
+ wfDebug( "Timed out waiting for slave #$index pos {$this->mWaitForFile} {$this->mWaitForPos}\n" );
+ $retVal = false;
+ } else {
+ $retVal = true;
+ wfDebug( "Done\n" );
+ }
+ }
+ return $retVal;
+ }
+
+ /**
+ * Get a connection by index
+ */
+ function &getConnection( $i, $fail = true, $groups = array() )
+ {
+ global $wgDBtype;
+ $fname = 'LoadBalancer::getConnection';
+ wfProfileIn( $fname );
+
+
+ # Query groups
+ if ( !is_array( $groups ) ) {
+ $groupIndex = $this->getGroupIndex( $groups, $i );
+ if ( $groupIndex !== false ) {
+ $i = $groupIndex;
+ }
+ } else {
+ foreach ( $groups as $group ) {
+ $groupIndex = $this->getGroupIndex( $group, $i );
+ if ( $groupIndex !== false ) {
+ $i = $groupIndex;
+ break;
+ }
+ }
+ }
+
+ # For now, only go through all this for mysql databases
+ if ($wgDBtype != 'mysql') {
+ $i = $this->getWriterIndex();
+ }
+ # Operation-based index
+ elseif ( $i == DB_SLAVE ) {
+ $i = $this->getReaderIndex();
+ } elseif ( $i == DB_MASTER ) {
+ $i = $this->getWriterIndex();
+ } elseif ( $i == DB_LAST ) {
+ # Just use $this->mLastIndex, which should already be set
+ $i = $this->mLastIndex;
+ if ( $i === -1 ) {
+ # Oh dear, not set, best to use the writer for safety
+ wfDebug( "Warning: DB_LAST used when there was no previous index\n" );
+ $i = $this->getWriterIndex();
+ }
+ }
+ # Couldn't find a working server in getReaderIndex()?
+ if ( $i === false ) {
+ $this->reportConnectionError( $this->mErrorConnection );
+ }
+ # Now we have an explicit index into the servers array
+ $this->openConnection( $i, $fail );
+
+ wfProfileOut( $fname );
+ return $this->mConnections[$i];
+ }
+
+ /**
+ * Open a connection to the server given by the specified index
+ * Index must be an actual index into the array
+ * Returns success
+ * @access private
+ */
+ function openConnection( $i, $fail = false ) {
+ $fname = 'LoadBalancer::openConnection';
+ wfProfileIn( $fname );
+ $success = true;
+
+ if ( !$this->isOpen( $i ) ) {
+ $this->mConnections[$i] = $this->reallyOpenConnection( $this->mServers[$i] );
+ }
+
+ if ( !$this->isOpen( $i ) ) {
+ wfDebug( "Failed to connect to database $i at {$this->mServers[$i]['host']}\n" );
+ if ( $fail ) {
+ $this->reportConnectionError( $this->mConnections[$i] );
+ }
+ $this->mErrorConnection = $this->mConnections[$i];
+ $this->mConnections[$i] = false;
+ $success = false;
+ }
+ $this->mLastIndex = $i;
+ wfProfileOut( $fname );
+ return $success;
+ }
+
+ /**
+ * Test if the specified index represents an open connection
+ * @access private
+ */
+ function isOpen( $index ) {
+ if( !is_integer( $index ) ) {
+ return false;
+ }
+ if ( array_key_exists( $index, $this->mConnections ) && is_object( $this->mConnections[$index] ) &&
+ $this->mConnections[$index]->isOpen() )
+ {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Really opens a connection
+ * @access private
+ */
+ function reallyOpenConnection( &$server ) {
+ if( !is_array( $server ) ) {
+ throw new MWException( 'You must update your load-balancing configuration. See DefaultSettings.php entry for $wgDBservers.' );
+ }
+
+ extract( $server );
+ # Get class for this database type
+ $class = 'Database' . ucfirst( $type );
+
+ # Create object
+ $db = new $class( $host, $user, $password, $dbname, 1, $flags );
+ $db->setLBInfo( $server );
+ return $db;
+ }
+
+ function reportConnectionError( &$conn )
+ {
+ $fname = 'LoadBalancer::reportConnectionError';
+ wfProfileIn( $fname );
+ # Prevent infinite recursion
+
+ static $reporting = false;
+ if ( !$reporting ) {
+ $reporting = true;
+ if ( !is_object( $conn ) ) {
+ // No last connection, probably due to all servers being too busy
+ $conn = new Database;
+ if ( $this->mFailFunction ) {
+ $conn->failFunction( $this->mFailFunction );
+ $conn->reportConnectionError( $this->mLastError );
+ } else {
+ // If all servers were busy, mLastError will contain something sensible
+ throw new DBConnectionError( $conn, $this->mLastError );
+ }
+ } else {
+ if ( $this->mFailFunction ) {
+ $conn->failFunction( $this->mFailFunction );
+ } else {
+ $conn->failFunction( false );
+ }
+ $server = $conn->getProperty( 'mServer' );
+ $conn->reportConnectionError( "{$this->mLastError} ({$server})" );
+ }
+ $reporting = false;
+ }
+ wfProfileOut( $fname );
+ }
+
+ function getWriterIndex() {
+ return 0;
+ }
+
+ /**
+ * Force subsequent calls to getConnection(DB_SLAVE) to return the
+ * given index. Set to -1 to restore the original load balancing
+ * behaviour. I thought this was a good idea when I originally
+ * wrote this class, but it has never been used.
+ */
+ function force( $i ) {
+ $this->mForce = $i;
+ }
+
+ /**
+ * Returns true if the specified index is a valid server index
+ */
+ function haveIndex( $i ) {
+ return array_key_exists( $i, $this->mServers );
+ }
+
+ /**
+ * Returns true if the specified index is valid and has non-zero load
+ */
+ function isNonZeroLoad( $i ) {
+ return array_key_exists( $i, $this->mServers ) && $this->mLoads[$i] != 0;
+ }
+
+ /**
+ * Get the number of defined servers (not the number of open connections)
+ */
+ function getServerCount() {
+ return count( $this->mServers );
+ }
+
+ /**
+ * Save master pos to the session and to memcached, if the session exists
+ */
+ function saveMasterPos() {
+ global $wgSessionStarted;
+ if ( $wgSessionStarted && count( $this->mServers ) > 1 ) {
+ # If this entire request was served from a slave without opening a connection to the
+ # master (however unlikely that may be), then we can fetch the position from the slave.
+ if ( empty( $this->mConnections[0] ) ) {
+ $conn =& $this->getConnection( DB_SLAVE );
+ list( $file, $pos ) = $conn->getSlavePos();
+ wfDebug( "Saving master pos fetched from slave: $file $pos\n" );
+ } else {
+ $conn =& $this->getConnection( 0 );
+ list( $file, $pos ) = $conn->getMasterPos();
+ wfDebug( "Saving master pos: $file $pos\n" );
+ }
+ if ( $file !== false ) {
+ $_SESSION['master_log_file'] = $file;
+ $_SESSION['master_pos'] = $pos;
+ }
+ }
+ }
+
+ /**
+ * Loads the master pos from the session, waits for it if necessary
+ */
+ function loadMasterPos() {
+ if ( isset( $_SESSION['master_log_file'] ) && isset( $_SESSION['master_pos'] ) ) {
+ $this->waitFor( $_SESSION['master_log_file'], $_SESSION['master_pos'] );
+ }
+ }
+
+ /**
+ * Close all open connections
+ */
+ function closeAll() {
+ foreach( $this->mConnections as $i => $conn ) {
+ if ( $this->isOpen( $i ) ) {
+ // Need to use this syntax because $conn is a copy not a reference
+ $this->mConnections[$i]->close();
+ }
+ }
+ }
+
+ function commitAll() {
+ foreach( $this->mConnections as $i => $conn ) {
+ if ( $this->isOpen( $i ) ) {
+ // Need to use this syntax because $conn is a copy not a reference
+ $this->mConnections[$i]->immediateCommit();
+ }
+ }
+ }
+
+ function waitTimeout( $value = NULL ) {
+ return wfSetVar( $this->mWaitTimeout, $value );
+ }
+
+ function getLaggedSlaveMode() {
+ return $this->mLaggedSlaveMode;
+ }
+
+ /* Disables/enables lag checks */
+ function allowLagged($mode=null) {
+ if ($mode===null)
+ return $this->mAllowLagged;
+ $this->mAllowLagged=$mode;
+ }
+
+ function pingAll() {
+ $success = true;
+ foreach ( $this->mConnections as $i => $conn ) {
+ if ( $this->isOpen( $i ) ) {
+ if ( !$this->mConnections[$i]->ping() ) {
+ $success = false;
+ }
+ }
+ }
+ return $success;
+ }
+
+ /**
+ * Get the hostname and lag time of the most-lagged slave
+ * This is useful for maintenance scripts that need to throttle their updates
+ */
+ function getMaxLag() {
+ $maxLag = -1;
+ $host = '';
+ foreach ( $this->mServers as $i => $conn ) {
+ if ( $this->openConnection( $i ) ) {
+ $lag = $this->mConnections[$i]->getLag();
+ if ( $lag > $maxLag ) {
+ $maxLag = $lag;
+ $host = $this->mServers[$i]['host'];
+ }
+ }
+ }
+ return array( $host, $maxLag );
+ }
+
+ /**
+ * Get lag time for each DB
+ * Results are cached for a short time in memcached
+ */
+ function getLagTimes() {
+ wfProfileIn( __METHOD__ );
+ $expiry = 5;
+ $requestRate = 10;
+
+ global $wgMemc;
+ $times = $wgMemc->get( wfMemcKey( 'lag_times' ) );
+ if ( $times ) {
+ # Randomly recache with probability rising over $expiry
+ $elapsed = time() - $times['timestamp'];
+ $chance = max( 0, ( $expiry - $elapsed ) * $requestRate );
+ if ( mt_rand( 0, $chance ) != 0 ) {
+ unset( $times['timestamp'] );
+ wfProfileOut( __METHOD__ );
+ return $times;
+ }
+ wfIncrStats( 'lag_cache_miss_expired' );
+ } else {
+ wfIncrStats( 'lag_cache_miss_absent' );
+ }
+
+ # Cache key missing or expired
+
+ $times = array();
+ foreach ( $this->mServers as $i => $conn ) {
+ if ($i==0) { # Master
+ $times[$i] = 0;
+ } elseif ( $this->openConnection( $i ) ) {
+ $times[$i] = $this->mConnections[$i]->getLag();
+ }
+ }
+
+ # Add a timestamp key so we know when it was cached
+ $times['timestamp'] = time();
+ $wgMemc->set( wfMemcKey( 'lag_times' ), $times, $expiry );
+
+ # But don't give the timestamp to the caller
+ unset($times['timestamp']);
+ wfProfileOut( __METHOD__ );
+ return $times;
+ }
+}
+
+?>
diff --git a/includes/LogPage.php b/includes/LogPage.php
new file mode 100644
index 000000000000..dd395126249a
--- /dev/null
+++ b/includes/LogPage.php
@@ -0,0 +1,246 @@
+<?php
+#
+# Copyright (C) 2002, 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Contain log classes
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Class to simplify the use of log pages.
+ * The logs are now kept in a table which is easier to manage and trim
+ * than ever-growing wiki pages.
+ *
+ * @package MediaWiki
+ */
+class LogPage {
+ /* @access private */
+ var $type, $action, $comment, $params, $target;
+ /* @acess public */
+ var $updateRecentChanges;
+
+ /**
+ * Constructor
+ *
+ * @param string $type One of '', 'block', 'protect', 'rights', 'delete',
+ * 'upload', 'move'
+ * @param bool $rc Whether to update recent changes as well as the logging table
+ */
+ function LogPage( $type, $rc = true ) {
+ $this->type = $type;
+ $this->updateRecentChanges = $rc;
+ }
+
+ function saveContent() {
+ if( wfReadOnly() ) return false;
+
+ global $wgUser;
+ $fname = 'LogPage::saveContent';
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $uid = $wgUser->getID();
+
+ $this->timestamp = $now = wfTimestampNow();
+ $dbw->insert( 'logging',
+ array(
+ 'log_type' => $this->type,
+ 'log_action' => $this->action,
+ 'log_timestamp' => $dbw->timestamp( $now ),
+ 'log_user' => $uid,
+ 'log_namespace' => $this->target->getNamespace(),
+ 'log_title' => $this->target->getDBkey(),
+ 'log_comment' => $this->comment,
+ 'log_params' => $this->params
+ ), $fname
+ );
+
+ # And update recentchanges
+ if ( $this->updateRecentChanges ) {
+ $titleObj = SpecialPage::getTitleFor( 'Log', $this->type );
+ $rcComment = $this->actionText;
+ if( '' != $this->comment ) {
+ if ($rcComment == '')
+ $rcComment = $this->comment;
+ else
+ $rcComment .= ': ' . $this->comment;
+ }
+
+ RecentChange::notifyLog( $now, $titleObj, $wgUser, $rcComment, '',
+ $this->type, $this->action, $this->target, $this->comment, $this->params );
+ }
+ return true;
+ }
+
+ /**
+ * @static
+ */
+ function validTypes() {
+ global $wgLogTypes;
+ return $wgLogTypes;
+ }
+
+ /**
+ * @static
+ */
+ function isLogType( $type ) {
+ return in_array( $type, LogPage::validTypes() );
+ }
+
+ /**
+ * @static
+ */
+ public static function logName( $type ) {
+ global $wgLogNames;
+
+ if( isset( $wgLogNames[$type] ) ) {
+ return str_replace( '_', ' ', wfMsg( $wgLogNames[$type] ) );
+ } else {
+ // Bogus log types? Perhaps an extension was removed.
+ return $type;
+ }
+ }
+
+ /**
+ * @fixme: handle missing log types
+ * @static
+ */
+ function logHeader( $type ) {
+ global $wgLogHeaders;
+ return wfMsg( $wgLogHeaders[$type] );
+ }
+
+ /**
+ * @static
+ */
+ function actionText( $type, $action, $title = NULL, $skin = NULL, $params = array(), $filterWikilinks=false, $translate=false ) {
+ global $wgLang, $wgContLang, $wgLogActions;
+
+ $key = "$type/$action";
+ if( isset( $wgLogActions[$key] ) ) {
+ if( is_null( $title ) ) {
+ $rv=wfMsg( $wgLogActions[$key] );
+ } else {
+ if( $skin ) {
+
+ switch( $type ) {
+ case 'move':
+ $titleLink = $skin->makeLinkObj( $title, $title->getPrefixedText(), 'redirect=no' );
+ $params[0] = $skin->makeLinkObj( Title::newFromText( $params[0] ), $params[0] );
+ break;
+ case 'block':
+ if( substr( $title->getText(), 0, 1 ) == '#' ) {
+ $titleLink = $title->getText();
+ } else {
+ $titleLink = $skin->makeLinkObj( $title, $title->getText() );
+ $titleLink .= ' (' . $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Contributions', $title->getDBkey() ), wfMsg( 'contribslink' ) ) . ')';
+ }
+ break;
+ case 'rights':
+ $text = $wgContLang->ucfirst( $title->getText() );
+ $titleLink = $skin->makeLinkObj( Title::makeTitle( NS_USER, $text ) );
+ break;
+ default:
+ $titleLink = $skin->makeLinkObj( $title );
+ }
+
+ } else {
+ $titleLink = $title->getPrefixedText();
+ }
+ if( $key == 'rights/rights' ) {
+ if ($skin) {
+ $rightsnone = wfMsg( 'rightsnone' );
+ } else {
+ $rightsnone = wfMsgForContent( 'rightsnone' );
+ }
+ if( !isset( $params[0] ) || trim( $params[0] ) == '' )
+ $params[0] = $rightsnone;
+ if( !isset( $params[1] ) || trim( $params[1] ) == '' )
+ $params[1] = $rightsnone;
+ }
+ if( count( $params ) == 0 ) {
+ if ( $skin ) {
+ $rv = wfMsg( $wgLogActions[$key], $titleLink );
+ } else {
+ $rv = wfMsgForContent( $wgLogActions[$key], $titleLink );
+ }
+ } else {
+ array_unshift( $params, $titleLink );
+ if ( $translate && $key == 'block/block' ) {
+ $params[1] = $wgLang->translateBlockExpiry($params[1]);
+ }
+ $rv = wfMsgReal( $wgLogActions[$key], $params, true, !$skin );
+ }
+ }
+ } else {
+ wfDebug( "LogPage::actionText - unknown action $key\n" );
+ $rv = "$action";
+ }
+ if( $filterWikilinks ) {
+ $rv = str_replace( "[[", "", $rv );
+ $rv = str_replace( "]]", "", $rv );
+ }
+ return $rv;
+ }
+
+ /**
+ * Add a log entry
+ * @param string $action one of '', 'block', 'protect', 'rights', 'delete', 'upload', 'move', 'move_redir'
+ * @param object &$target A title object.
+ * @param string $comment Description associated
+ * @param array $params Parameters passed later to wfMsg.* functions
+ */
+ function addEntry( $action, $target, $comment, $params = array() ) {
+ if ( !is_array( $params ) ) {
+ $params = array( $params );
+ }
+
+ $this->action = $action;
+ $this->target = $target;
+ $this->comment = $comment;
+ $this->params = LogPage::makeParamBlob( $params );
+
+ $this->actionText = LogPage::actionText( $this->type, $action, $target, NULL, $params );
+
+ return $this->saveContent();
+ }
+
+ /**
+ * Create a blob from a parameter array
+ * @static
+ */
+ function makeParamBlob( $params ) {
+ return implode( "\n", $params );
+ }
+
+ /**
+ * Extract a parameter array from a blob
+ * @static
+ */
+ function extractParams( $blob ) {
+ if ( $blob === '' ) {
+ return array();
+ } else {
+ return explode( "\n", $blob );
+ }
+ }
+}
+
+?>
diff --git a/includes/MacBinary.php b/includes/MacBinary.php
new file mode 100644
index 000000000000..05c3ce5cfd99
--- /dev/null
+++ b/includes/MacBinary.php
@@ -0,0 +1,272 @@
+<?php
+/**
+ * MacBinary signature checker and data fork extractor, for files
+ * uploaded from Internet Explorer for Mac.
+ *
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * Portions based on Convert::BinHex by Eryq et al
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+class MacBinary {
+ function MacBinary( $filename ) {
+ $this->open( $filename );
+ $this->loadHeader();
+ }
+
+ /**
+ * The file must be seekable, such as local filesystem.
+ * Remote URLs probably won't work.
+ *
+ * @param string $filename
+ */
+ function open( $filename ) {
+ $this->valid = false;
+ $this->version = 0;
+ $this->filename = '';
+ $this->dataLength = 0;
+ $this->resourceLength = 0;
+ $this->handle = fopen( $filename, 'rb' );
+ }
+
+ /**
+ * Does this appear to be a valid MacBinary archive?
+ * @return bool
+ */
+ function isValid() {
+ return $this->valid;
+ }
+
+ /**
+ * Get length of data fork
+ * @return int
+ */
+ function dataForkLength() {
+ return $this->dataLength;
+ }
+
+ /**
+ * Copy the data fork to an external file or resource.
+ * @param resource $destination
+ * @return bool
+ */
+ function extractData( $destination ) {
+ if( !$this->isValid() ) {
+ return false;
+ }
+
+ // Data fork appears immediately after header
+ fseek( $this->handle, 128 );
+ return $this->copyBytesTo( $destination, $this->dataLength );
+ }
+
+ /**
+ *
+ */
+ function close() {
+ fclose( $this->handle );
+ }
+
+ // --------------------------------------------------------------
+
+ /**
+ * Check if the given file appears to be MacBinary-encoded,
+ * as Internet Explorer on Mac OS may provide for unknown types.
+ * http://www.lazerware.com/formats/macbinary/macbinary_iii.html
+ * If ok, load header data.
+ *
+ * @return bool
+ * @access private
+ */
+ function loadHeader() {
+ $fname = 'MacBinary::loadHeader';
+
+ fseek( $this->handle, 0 );
+ $head = fread( $this->handle, 128 );
+ $this->hexdump( $head );
+
+ if( strlen( $head ) < 128 ) {
+ wfDebug( "$fname: couldn't read full MacBinary header\n" );
+ return false;
+ }
+
+ if( $head{0} != "\x00" || $head{74} != "\x00" ) {
+ wfDebug( "$fname: header bytes 0 and 74 not null\n" );
+ return false;
+ }
+
+ $signature = substr( $head, 102, 4 );
+ $a = unpack( "ncrc", substr( $head, 124, 2 ) );
+ $storedCRC = $a['crc'];
+ $calculatedCRC = $this->calcCRC( substr( $head, 0, 124 ) );
+ if( $storedCRC == $calculatedCRC ) {
+ if( $signature == 'mBIN' ) {
+ $this->version = 3;
+ } else {
+ $this->version = 2;
+ }
+ } else {
+ $crc = sprintf( "%x != %x", $storedCRC, $calculatedCRC );
+ if( $storedCRC == 0 && $head{82} == "\x00" &&
+ substr( $head, 101, 24 ) == str_repeat( "\x00", 24 ) ) {
+ wfDebug( "$fname: no CRC, looks like MacBinary I\n" );
+ $this->version = 1;
+ } elseif( $signature == 'mBIN' && $storedCRC == 0x185 ) {
+ // Mac IE 5.0 seems to insert this value in the CRC field.
+ // 5.2.3 works correctly; don't know about other versions.
+ wfDebug( "$fname: CRC doesn't match ($crc), looks like Mac IE 5.0\n" );
+ $this->version = 3;
+ } else {
+ wfDebug( "$fname: CRC doesn't match ($crc) and not MacBinary I\n" );
+ return false;
+ }
+ }
+
+ $nameLength = ord( $head{1} );
+ if( $nameLength < 1 || $nameLength > 63 ) {
+ wfDebug( "$fname: invalid filename size $nameLength\n" );
+ return false;
+ }
+ $this->filename = substr( $head, 2, $nameLength );
+
+ $forks = unpack( "Ndata/Nresource", substr( $head, 83, 8 ) );
+ $this->dataLength = $forks['data'];
+ $this->resourceLength = $forks['resource'];
+ $maxForkLength = 0x7fffff;
+
+ if( $this->dataLength < 0 || $this->dataLength > $maxForkLength ) {
+ wfDebug( "$fname: invalid data fork length $this->dataLength\n" );
+ return false;
+ }
+
+ if( $this->resourceLength < 0 || $this->resourceLength > $maxForkLength ) {
+ wfDebug( "$fname: invalid resource fork size $this->resourceLength\n" );
+ return false;
+ }
+
+ wfDebug( "$fname: appears to be MacBinary $this->version, data length $this->dataLength\n" );
+ $this->valid = true;
+ return true;
+ }
+
+ /**
+ * Calculate a 16-bit CRC value as for MacBinary headers.
+ * Adapted from perl5 Convert::BinHex by Eryq,
+ * based on the mcvert utility (Doug Moore, April '87),
+ * with magic array thingy by Jim Van Verth.
+ * http://search.cpan.org/~eryq/Convert-BinHex-1.119/lib/Convert/BinHex.pm
+ *
+ * @param string $data
+ * @param int $seed
+ * @return int
+ * @access private
+ */
+ function calcCRC( $data, $seed = 0 ) {
+ # An array useful for CRC calculations that use 0x1021 as the "seed":
+ $MAGIC = array(
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+ );
+ $len = strlen( $data );
+ $crc = $seed;
+ for( $i = 0; $i < $len; $i++ ) {
+ $crc ^= ord( $data{$i} ) << 8;
+ $crc &= 0xFFFF;
+ $crc = ($crc << 8) ^ $MAGIC[$crc >> 8];
+ $crc &= 0xFFFF;
+ }
+ return $crc;
+ }
+
+ /**
+ * @param resource $destination
+ * @param int $bytesToCopy
+ * @return bool
+ * @access private
+ */
+ function copyBytesTo( $destination, $bytesToCopy ) {
+ $bufferSize = 65536;
+ for( $remaining = $bytesToCopy; $remaining > 0; $remaining -= $bufferSize ) {
+ $thisChunkSize = min( $remaining, $bufferSize );
+ $buffer = fread( $this->handle, $thisChunkSize );
+ fwrite( $destination, $buffer );
+ }
+ }
+
+ /**
+ * Hex dump of the header for debugging
+ * @access private
+ */
+ function hexdump( $data ) {
+ global $wgDebugLogFile;
+ if( !$wgDebugLogFile ) return;
+
+ $width = 16;
+ $at = 0;
+ for( $remaining = strlen( $data ); $remaining > 0; $remaining -= $width ) {
+ $line = sprintf( "%04x:", $at );
+ $printable = '';
+ for( $i = 0; $i < $width && $remaining - $i > 0; $i++ ) {
+ $byte = ord( $data{$at++} );
+ $line .= sprintf( " %02x", $byte );
+ $printable .= ($byte >= 32 && $byte <= 126 )
+ ? chr( $byte )
+ : '.';
+ }
+ if( $i < $width ) {
+ $line .= str_repeat( ' ', $width - $i );
+ }
+ wfDebug( "MacBinary: $line $printable\n" );
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/includes/MagicWord.php b/includes/MagicWord.php
new file mode 100644
index 000000000000..60bfd0f4c5eb
--- /dev/null
+++ b/includes/MagicWord.php
@@ -0,0 +1,393 @@
+<?php
+/**
+ * File for magic words
+ * @package MediaWiki
+ * @subpackage Parser
+ */
+
+/**
+ * This class encapsulates "magic words" such as #redirect, __NOTOC__, etc.
+ * Usage:
+ * if (MagicWord::get( 'redirect' )->match( $text ) )
+ *
+ * Possible future improvements:
+ * * Simultaneous searching for a number of magic words
+ * * MagicWord::$mObjects in shared memory
+ *
+ * Please avoid reading the data out of one of these objects and then writing
+ * special case code. If possible, add another match()-like function here.
+ *
+ * To add magic words in an extension, use the LanguageGetMagic hook. For
+ * magic words which are also Parser variables, add a MagicWordwgVariableIDs
+ * hook. Use string keys.
+ *
+ * @package MediaWiki
+ */
+class MagicWord {
+ /**#@+
+ * @private
+ */
+ var $mId, $mSynonyms, $mCaseSensitive, $mRegex;
+ var $mRegexStart, $mBaseRegex, $mVariableRegex;
+ var $mModified, $mFound;
+
+ static public $mVariableIDsInitialised = false;
+ static public $mVariableIDs = array(
+ 'currentmonth',
+ 'currentmonthname',
+ 'currentmonthnamegen',
+ 'currentmonthabbrev',
+ 'currentday',
+ 'currentday2',
+ 'currentdayname',
+ 'currentyear',
+ 'currenttime',
+ 'currenthour',
+ 'localmonth',
+ 'localmonthname',
+ 'localmonthnamegen',
+ 'localmonthabbrev',
+ 'localday',
+ 'localday2',
+ 'localdayname',
+ 'localyear',
+ 'localtime',
+ 'localhour',
+ 'numberofarticles',
+ 'numberoffiles',
+ 'sitename',
+ 'server',
+ 'servername',
+ 'scriptpath',
+ 'pagename',
+ 'pagenamee',
+ 'fullpagename',
+ 'fullpagenamee',
+ 'namespace',
+ 'namespacee',
+ 'currentweek',
+ 'currentdow',
+ 'localweek',
+ 'localdow',
+ 'revisionid',
+ 'revisionday',
+ 'revisionday2',
+ 'revisionmonth',
+ 'revisionyear',
+ 'revisiontimestamp',
+ 'subpagename',
+ 'subpagenamee',
+ 'displaytitle',
+ 'talkspace',
+ 'talkspacee',
+ 'subjectspace',
+ 'subjectspacee',
+ 'talkpagename',
+ 'talkpagenamee',
+ 'subjectpagename',
+ 'subjectpagenamee',
+ 'numberofusers',
+ 'rawsuffix',
+ 'newsectionlink',
+ 'numberofpages',
+ 'currentversion',
+ 'basepagename',
+ 'basepagenamee',
+ 'urlencode',
+ 'currenttimestamp',
+ 'localtimestamp',
+ 'directionmark',
+ 'language',
+ 'contentlanguage',
+ 'pagesinnamespace',
+ 'numberofadmins',
+ 'defaultsort',
+ );
+
+ static public $mObjects = array();
+
+ /**#@-*/
+
+ function MagicWord($id = 0, $syn = '', $cs = false) {
+ $this->mId = $id;
+ $this->mSynonyms = (array)$syn;
+ $this->mCaseSensitive = $cs;
+ $this->mRegex = '';
+ $this->mRegexStart = '';
+ $this->mVariableRegex = '';
+ $this->mVariableStartToEndRegex = '';
+ $this->mModified = false;
+ }
+
+ /**
+ * Factory: creates an object representing an ID
+ * @static
+ */
+ static function &get( $id ) {
+ if (!array_key_exists( $id, self::$mObjects ) ) {
+ $mw = new MagicWord();
+ $mw->load( $id );
+ self::$mObjects[$id] = $mw;
+ }
+ return self::$mObjects[$id];
+ }
+
+ /**
+ * Get an array of parser variable IDs
+ */
+ static function getVariableIDs() {
+ if ( !self::$mVariableIDsInitialised ) {
+ # Deprecated constant definition hook, available for extensions that need it
+ $magicWords = array();
+ wfRunHooks( 'MagicWordMagicWords', array( &$magicWords ) );
+ foreach ( $magicWords as $word ) {
+ define( $word, $word );
+ }
+
+ # Get variable IDs
+ wfRunHooks( 'MagicWordwgVariableIDs', array( &self::$mVariableIDs ) );
+ self::$mVariableIDsInitialised = true;
+ }
+ return self::$mVariableIDs;
+ }
+
+ # Initialises this object with an ID
+ function load( $id ) {
+ global $wgContLang;
+ $this->mId = $id;
+ $wgContLang->getMagic( $this );
+ if ( !$this->mSynonyms ) {
+ $this->mSynonyms = array( 'dkjsagfjsgashfajsh' );
+ #throw new MWException( "Error: invalid magic word '$id'" );
+ wfDebugLog( 'exception', "Error: invalid magic word '$id'\n" );
+ }
+ }
+
+ /**
+ * Preliminary initialisation
+ * @private
+ */
+ function initRegex() {
+ #$variableClass = Title::legalChars();
+ # This was used for matching "$1" variables, but different uses of the feature will have
+ # different restrictions, which should be checked *after* the MagicWord has been matched,
+ # not here. - IMSoP
+
+ $escSyn = array();
+ foreach ( $this->mSynonyms as $synonym )
+ // In case a magic word contains /, like that's going to happen;)
+ $escSyn[] = preg_quote( $synonym, '/' );
+ $this->mBaseRegex = implode( '|', $escSyn );
+
+ $case = $this->mCaseSensitive ? '' : 'iu';
+ $this->mRegex = "/{$this->mBaseRegex}/{$case}";
+ $this->mRegexStart = "/^(?:{$this->mBaseRegex})/{$case}";
+ $this->mVariableRegex = str_replace( "\\$1", "(.*?)", $this->mRegex );
+ $this->mVariableStartToEndRegex = str_replace( "\\$1", "(.*?)",
+ "/^(?:{$this->mBaseRegex})$/{$case}" );
+ }
+
+ /**
+ * Gets a regex representing matching the word
+ */
+ function getRegex() {
+ if ($this->mRegex == '' ) {
+ $this->initRegex();
+ }
+ return $this->mRegex;
+ }
+
+ /**
+ * Gets the regexp case modifier to use, i.e. i or nothing, to be used if
+ * one is using MagicWord::getBaseRegex(), otherwise it'll be included in
+ * the complete expression
+ */
+ function getRegexCase() {
+ if ( $this->mRegex === '' )
+ $this->initRegex();
+
+ return $this->mCaseSensitive ? '' : 'iu';
+ }
+
+ /**
+ * Gets a regex matching the word, if it is at the string start
+ */
+ function getRegexStart() {
+ if ($this->mRegex == '' ) {
+ $this->initRegex();
+ }
+ return $this->mRegexStart;
+ }
+
+ /**
+ * regex without the slashes and what not
+ */
+ function getBaseRegex() {
+ if ($this->mRegex == '') {
+ $this->initRegex();
+ }
+ return $this->mBaseRegex;
+ }
+
+ /**
+ * Returns true if the text contains the word
+ * @return bool
+ */
+ function match( $text ) {
+ return preg_match( $this->getRegex(), $text );
+ }
+
+ /**
+ * Returns true if the text starts with the word
+ * @return bool
+ */
+ function matchStart( $text ) {
+ return preg_match( $this->getRegexStart(), $text );
+ }
+
+ /**
+ * Returns NULL if there's no match, the value of $1 otherwise
+ * The return code is the matched string, if there's no variable
+ * part in the regex and the matched variable part ($1) if there
+ * is one.
+ */
+ function matchVariableStartToEnd( $text ) {
+ $matches = array();
+ $matchcount = preg_match( $this->getVariableStartToEndRegex(), $text, $matches );
+ if ( $matchcount == 0 ) {
+ return NULL;
+ } else {
+ # multiple matched parts (variable match); some will be empty because of
+ # synonyms. The variable will be the second non-empty one so remove any
+ # blank elements and re-sort the indices.
+ # See also bug 6526
+
+ $matches = array_values(array_filter($matches));
+
+ if ( count($matches) == 1 ) { return $matches[0]; }
+ else { return $matches[1]; }
+ }
+ }
+
+
+ /**
+ * Returns true if the text matches the word, and alters the
+ * input string, removing all instances of the word
+ */
+ function matchAndRemove( &$text ) {
+ $this->mFound = false;
+ $text = preg_replace_callback( $this->getRegex(), array( &$this, 'pregRemoveAndRecord' ), $text );
+ return $this->mFound;
+ }
+
+ function matchStartAndRemove( &$text ) {
+ $this->mFound = false;
+ $text = preg_replace_callback( $this->getRegexStart(), array( &$this, 'pregRemoveAndRecord' ), $text );
+ return $this->mFound;
+ }
+
+ /**
+ * Used in matchAndRemove()
+ * @private
+ **/
+ function pregRemoveAndRecord( ) {
+ $this->mFound = true;
+ return '';
+ }
+
+ /**
+ * Replaces the word with something else
+ */
+ function replace( $replacement, $subject, $limit=-1 ) {
+ $res = preg_replace( $this->getRegex(), StringUtils::escapeRegexReplacement( $replacement ), $subject, $limit );
+ $this->mModified = !($res === $subject);
+ return $res;
+ }
+
+ /**
+ * Variable handling: {{SUBST:xxx}} style words
+ * Calls back a function to determine what to replace xxx with
+ * Input word must contain $1
+ */
+ function substituteCallback( $text, $callback ) {
+ $res = preg_replace_callback( $this->getVariableRegex(), $callback, $text );
+ $this->mModified = !($res === $text);
+ return $res;
+ }
+
+ /**
+ * Matches the word, where $1 is a wildcard
+ */
+ function getVariableRegex() {
+ if ( $this->mVariableRegex == '' ) {
+ $this->initRegex();
+ }
+ return $this->mVariableRegex;
+ }
+
+ /**
+ * Matches the entire string, where $1 is a wildcard
+ */
+ function getVariableStartToEndRegex() {
+ if ( $this->mVariableStartToEndRegex == '' ) {
+ $this->initRegex();
+ }
+ return $this->mVariableStartToEndRegex;
+ }
+
+ /**
+ * Accesses the synonym list directly
+ */
+ function getSynonym( $i ) {
+ return $this->mSynonyms[$i];
+ }
+
+ function getSynonyms() {
+ return $this->mSynonyms;
+ }
+
+ /**
+ * Returns true if the last call to replace() or substituteCallback()
+ * returned a modified text, otherwise false.
+ */
+ function getWasModified(){
+ return $this->mModified;
+ }
+
+ /**
+ * $magicarr is an associative array of (magic word ID => replacement)
+ * This method uses the php feature to do several replacements at the same time,
+ * thereby gaining some efficiency. The result is placed in the out variable
+ * $result. The return value is true if something was replaced.
+ * @static
+ **/
+ function replaceMultiple( $magicarr, $subject, &$result ){
+ $search = array();
+ $replace = array();
+ foreach( $magicarr as $id => $replacement ){
+ $mw = MagicWord::get( $id );
+ $search[] = $mw->getRegex();
+ $replace[] = $replacement;
+ }
+
+ $result = preg_replace( $search, $replace, $subject );
+ return !($result === $subject);
+ }
+
+ /**
+ * Adds all the synonyms of this MagicWord to an array, to allow quick
+ * lookup in a list of magic words
+ */
+ function addToArray( &$array, $value ) {
+ global $wgContLang;
+ foreach ( $this->mSynonyms as $syn ) {
+ $array[$wgContLang->lc($syn)] = $value;
+ }
+ }
+
+ function isCaseSensitive() {
+ return $this->mCaseSensitive;
+ }
+}
+
+?>
diff --git a/includes/Math.php b/includes/Math.php
new file mode 100644
index 000000000000..9fa631f7f1f9
--- /dev/null
+++ b/includes/Math.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * Contain everything related to <math> </math> parsing
+ * @package MediaWiki
+ */
+
+/**
+ * Takes LaTeX fragments, sends them to a helper program (texvc) for rendering
+ * to rasterized PNG and HTML and MathML approximations. An appropriate
+ * rendering form is picked and returned.
+ *
+ * by Tomasz Wegrzanowski, with additions by Brion Vibber (2003, 2004)
+ *
+ * @package MediaWiki
+ */
+class MathRenderer {
+ var $mode = MW_MATH_MODERN;
+ var $tex = '';
+ var $inputhash = '';
+ var $hash = '';
+ var $html = '';
+ var $mathml = '';
+ var $conservativeness = 0;
+
+ function MathRenderer( $tex ) {
+ $this->tex = $tex;
+ }
+
+ function setOutputMode( $mode ) {
+ $this->mode = $mode;
+ }
+
+ function render() {
+ global $wgTmpDirectory, $wgInputEncoding;
+ global $wgTexvc;
+ $fname = 'MathRenderer::render';
+
+ if( $this->mode == MW_MATH_SOURCE ) {
+ # No need to render or parse anything more!
+ return ('$ '.htmlspecialchars( $this->tex ).' $');
+ }
+ if( $this->tex == '' ) {
+ return; # bug 8372
+ }
+
+ if( !$this->_recall() ) {
+ # Ensure that the temp and output directories are available before continuing...
+ if( !file_exists( $wgTmpDirectory ) ) {
+ if( !@mkdir( $wgTmpDirectory ) ) {
+ return $this->_error( 'math_bad_tmpdir' );
+ }
+ } elseif( !is_dir( $wgTmpDirectory ) || !is_writable( $wgTmpDirectory ) ) {
+ return $this->_error( 'math_bad_tmpdir' );
+ }
+
+ if( function_exists( 'is_executable' ) && !is_executable( $wgTexvc ) ) {
+ return $this->_error( 'math_notexvc' );
+ }
+ $cmd = $wgTexvc . ' ' .
+ escapeshellarg( $wgTmpDirectory ).' '.
+ escapeshellarg( $wgTmpDirectory ).' '.
+ escapeshellarg( $this->tex ).' '.
+ escapeshellarg( $wgInputEncoding );
+
+ if ( wfIsWindows() ) {
+ # Invoke it within cygwin sh, because texvc expects sh features in its default shell
+ $cmd = 'sh -c ' . wfEscapeShellArg( $cmd );
+ }
+
+ wfDebug( "TeX: $cmd\n" );
+ $contents = `$cmd`;
+ wfDebug( "TeX output:\n $contents\n---\n" );
+
+ if (strlen($contents) == 0) {
+ return $this->_error( 'math_unknown_error' );
+ }
+
+ $retval = substr ($contents, 0, 1);
+ $errmsg = '';
+ if (($retval == 'C') || ($retval == 'M') || ($retval == 'L')) {
+ if ($retval == 'C') {
+ $this->conservativeness = 2;
+ } else if ($retval == 'M') {
+ $this->conservativeness = 1;
+ } else {
+ $this->conservativeness = 0;
+ }
+ $outdata = substr ($contents, 33);
+
+ $i = strpos($outdata, "\000");
+
+ $this->html = substr($outdata, 0, $i);
+ $this->mathml = substr($outdata, $i+1);
+ } else if (($retval == 'c') || ($retval == 'm') || ($retval == 'l')) {
+ $this->html = substr ($contents, 33);
+ if ($retval == 'c') {
+ $this->conservativeness = 2;
+ } else if ($retval == 'm') {
+ $this->conservativeness = 1;
+ } else {
+ $this->conservativeness = 0;
+ }
+ $this->mathml = NULL;
+ } else if ($retval == 'X') {
+ $this->html = NULL;
+ $this->mathml = substr ($contents, 33);
+ $this->conservativeness = 0;
+ } else if ($retval == '+') {
+ $this->html = NULL;
+ $this->mathml = NULL;
+ $this->conservativeness = 0;
+ } else {
+ $errbit = htmlspecialchars( substr($contents, 1) );
+ switch( $retval ) {
+ case 'E': $errmsg = $this->_error( 'math_lexing_error', $errbit );
+ case 'S': $errmsg = $this->_error( 'math_syntax_error', $errbit );
+ case 'F': $errmsg = $this->_error( 'math_unknown_function', $errbit );
+ default: $errmsg = $this->_error( 'math_unknown_error', $errbit );
+ }
+ }
+
+ if ( !$errmsg ) {
+ $this->hash = substr ($contents, 1, 32);
+ }
+
+ wfRunHooks( 'MathAfterTexvc', array( &$this, &$errmsg ) );
+
+ if ( $errmsg ) {
+ return $errmsg;
+ }
+
+ if (!preg_match("/^[a-f0-9]{32}$/", $this->hash)) {
+ return $this->_error( 'math_unknown_error' );
+ }
+
+ if( !file_exists( "$wgTmpDirectory/{$this->hash}.png" ) ) {
+ return $this->_error( 'math_image_error' );
+ }
+
+ $hashpath = $this->_getHashPath();
+ if( !file_exists( $hashpath ) ) {
+ if( !@wfMkdirParents( $hashpath, 0755 ) ) {
+ return $this->_error( 'math_bad_output' );
+ }
+ } elseif( !is_dir( $hashpath ) || !is_writable( $hashpath ) ) {
+ return $this->_error( 'math_bad_output' );
+ }
+
+ if( !rename( "$wgTmpDirectory/{$this->hash}.png", "$hashpath/{$this->hash}.png" ) ) {
+ return $this->_error( 'math_output_error' );
+ }
+
+ # Now save it back to the DB:
+ if ( !wfReadOnly() ) {
+ $outmd5_sql = pack('H32', $this->hash);
+
+ $md5_sql = pack('H32', $this->md5); # Binary packed, not hex
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->replace( 'math', array( 'math_inputhash' ),
+ array(
+ 'math_inputhash' => $md5_sql,
+ 'math_outputhash' => $outmd5_sql,
+ 'math_html_conservativeness' => $this->conservativeness,
+ 'math_html' => $this->html,
+ 'math_mathml' => $this->mathml,
+ ), $fname, array( 'IGNORE' )
+ );
+ }
+
+ }
+
+ return $this->_doRender();
+ }
+
+ function _error( $msg, $append = '' ) {
+ $mf = htmlspecialchars( wfMsg( 'math_failure' ) );
+ $errmsg = htmlspecialchars( wfMsg( $msg ) );
+ $source = htmlspecialchars( str_replace( "\n", ' ', $this->tex ) );
+ return "<strong class='error'>$mf ($errmsg$append): $source</strong>\n";
+ }
+
+ function _recall() {
+ global $wgMathDirectory;
+ $fname = 'MathRenderer::_recall';
+
+ $this->md5 = md5( $this->tex );
+ $dbr =& wfGetDB( DB_SLAVE );
+ $rpage = $dbr->selectRow( 'math',
+ array( 'math_outputhash','math_html_conservativeness','math_html','math_mathml' ),
+ array( 'math_inputhash' => pack("H32", $this->md5)), # Binary packed, not hex
+ $fname
+ );
+
+ if( $rpage !== false ) {
+ # Tailing 0x20s can get dropped by the database, add it back on if necessary:
+ $xhash = unpack( 'H32md5', $rpage->math_outputhash . " " );
+ $this->hash = $xhash ['md5'];
+
+ $this->conservativeness = $rpage->math_html_conservativeness;
+ $this->html = $rpage->math_html;
+ $this->mathml = $rpage->math_mathml;
+
+ if( file_exists( $this->_getHashPath() . "/{$this->hash}.png" ) ) {
+ return true;
+ }
+
+ if( file_exists( $wgMathDirectory . "/{$this->hash}.png" ) ) {
+ $hashpath = $this->_getHashPath();
+
+ if( !file_exists( $hashpath ) ) {
+ if( !@wfMkdirParents( $hashpath, 0755 ) ) {
+ return false;
+ }
+ } elseif( !is_dir( $hashpath ) || !is_writable( $hashpath ) ) {
+ return false;
+ }
+ if ( function_exists( "link" ) ) {
+ return link ( $wgMathDirectory . "/{$this->hash}.png",
+ $hashpath . "/{$this->hash}.png" );
+ } else {
+ return rename ( $wgMathDirectory . "/{$this->hash}.png",
+ $hashpath . "/{$this->hash}.png" );
+ }
+ }
+
+ }
+
+ # Missing from the database and/or the render cache
+ return false;
+ }
+
+ /**
+ * Select among PNG, HTML, or MathML output depending on
+ */
+ function _doRender() {
+ if( $this->mode == MW_MATH_MATHML && $this->mathml != '' ) {
+ return "<math xmlns='http://www.w3.org/1998/Math/MathML'>{$this->mathml}</math>";
+ }
+ if (($this->mode == MW_MATH_PNG) || ($this->html == '') ||
+ (($this->mode == MW_MATH_SIMPLE) && ($this->conservativeness != 2)) ||
+ (($this->mode == MW_MATH_MODERN || $this->mode == MW_MATH_MATHML) && ($this->conservativeness == 0))) {
+ return $this->_linkToMathImage();
+ } else {
+ return '<span class="texhtml">'.$this->html.'</span>';
+ }
+ }
+
+ function _linkToMathImage() {
+ global $wgMathPath;
+ $url = htmlspecialchars( "$wgMathPath/" . substr($this->hash, 0, 1)
+ .'/'. substr($this->hash, 1, 1) .'/'. substr($this->hash, 2, 1)
+ . "/{$this->hash}.png" );
+ $alt = trim(str_replace("\n", ' ', htmlspecialchars( $this->tex )));
+ return "<img class='tex' src=\"$url\" alt=\"$alt\" />";
+ }
+
+ function _getHashPath() {
+ global $wgMathDirectory;
+ $path = $wgMathDirectory .'/'. substr($this->hash, 0, 1)
+ .'/'. substr($this->hash, 1, 1)
+ .'/'. substr($this->hash, 2, 1);
+ wfDebug( "TeX: getHashPath, hash is: $this->hash, path is: $path\n" );
+ return $path;
+ }
+
+ public static function renderMath( $tex ) {
+ global $wgUser;
+ $math = new MathRenderer( $tex );
+ $math->setOutputMode( $wgUser->getOption('math'));
+ return $math->render();
+ }
+}
+?>
diff --git a/includes/MemcachedSessions.php b/includes/MemcachedSessions.php
new file mode 100644
index 000000000000..e2dc52ca7f19
--- /dev/null
+++ b/includes/MemcachedSessions.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * This file gets included if $wgSessionsInMemcache is set in the config.
+ * It redirects session handling functions to store their data in memcached
+ * instead of the local filesystem. Depending on circumstances, it may also
+ * be necessary to change the cookie settings to work across hostnames.
+ * See: http://www.php.net/manual/en/function.session-set-save-handler.php
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * @todo document
+ */
+function memsess_key( $id ) {
+ return wfMemcKey( 'session', $id );
+}
+
+/**
+ * @todo document
+ */
+function memsess_open( $save_path, $session_name ) {
+ # NOP, $wgMemc should be set up already
+ return true;
+}
+
+/**
+ * @todo document
+ */
+function memsess_close() {
+ # NOP
+ return true;
+}
+
+/**
+ * @todo document
+ */
+function memsess_read( $id ) {
+ global $wgMemc;
+ $data = $wgMemc->get( memsess_key( $id ) );
+ if( ! $data ) return '';
+ return $data;
+}
+
+/**
+ * @todo document
+ */
+function memsess_write( $id, $data ) {
+ global $wgMemc;
+ $wgMemc->set( memsess_key( $id ), $data, 3600 );
+ return true;
+}
+
+/**
+ * @todo document
+ */
+function memsess_destroy( $id ) {
+ global $wgMemc;
+ $wgMemc->delete( memsess_key( $id ) );
+ return true;
+}
+
+/**
+ * @todo document
+ */
+function memsess_gc( $maxlifetime ) {
+ # NOP: Memcached performs garbage collection.
+ return true;
+}
+
+session_set_save_handler( 'memsess_open', 'memsess_close', 'memsess_read', 'memsess_write', 'memsess_destroy', 'memsess_gc' );
+
+?>
diff --git a/includes/MessageCache.php b/includes/MessageCache.php
new file mode 100644
index 000000000000..a269c620870a
--- /dev/null
+++ b/includes/MessageCache.php
@@ -0,0 +1,683 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+
+/**
+ *
+ */
+define( 'MSG_LOAD_TIMEOUT', 60);
+define( 'MSG_LOCK_TIMEOUT', 10);
+define( 'MSG_WAIT_TIMEOUT', 10);
+define( 'MSG_CACHE_VERSION', 1 );
+
+/**
+ * Message cache
+ * Performs various MediaWiki namespace-related functions
+ *
+ * @package MediaWiki
+ */
+class MessageCache {
+ var $mCache, $mUseCache, $mDisable, $mExpiry;
+ var $mMemcKey, $mKeys, $mParserOptions, $mParser;
+ var $mExtensionMessages = array();
+ var $mInitialised = false;
+ var $mDeferred = true;
+
+ function __construct( &$memCached, $useDB, $expiry, $memcPrefix) {
+ wfProfileIn( __METHOD__ );
+
+ $this->mUseCache = !is_null( $memCached );
+ $this->mMemc = &$memCached;
+ $this->mDisable = !$useDB;
+ $this->mExpiry = $expiry;
+ $this->mDisableTransform = false;
+ $this->mMemcKey = $memcPrefix.':messages';
+ $this->mKeys = false; # initialised on demand
+ $this->mInitialised = true;
+ $this->mParser = null;
+
+ # When we first get asked for a message,
+ # then we'll fill up the cache. If we
+ # can return a cache hit, this saves
+ # some extra milliseconds
+ $this->mDeferred = true;
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ function getParserOptions() {
+ if ( !$this->mParserOptions ) {
+ $this->mParserOptions = new ParserOptions;
+ }
+ return $this->mParserOptions;
+ }
+
+ /**
+ * Try to load the cache from a local file
+ */
+ function loadFromLocal( $hash ) {
+ global $wgLocalMessageCache;
+
+ $this->mCache = false;
+ if ( $wgLocalMessageCache === false ) {
+ return;
+ }
+
+ $filename = "$wgLocalMessageCache/messages-" . wfWikiID();
+
+ wfSuppressWarnings();
+ $file = fopen( $filename, 'r' );
+ wfRestoreWarnings();
+ if ( !$file ) {
+ return;
+ }
+
+ // Check to see if the file has the hash specified
+ $localHash = fread( $file, 32 );
+ if ( $hash == $localHash ) {
+ // All good, get the rest of it
+ $serialized = fread( $file, 10000000 );
+ $this->setCache( unserialize( $serialized ) );
+ }
+ fclose( $file );
+ }
+
+ /**
+ * Save the cache to a local file
+ */
+ function saveToLocal( $serialized, $hash ) {
+ global $wgLocalMessageCache;
+
+ if ( $wgLocalMessageCache === false ) {
+ return;
+ }
+
+ $filename = "$wgLocalMessageCache/messages-" . wfWikiID();
+ $oldUmask = umask( 0 );
+ wfMkdirParents( $wgLocalMessageCache, 0777 );
+ umask( $oldUmask );
+
+ $file = fopen( $filename, 'w' );
+ if ( !$file ) {
+ wfDebug( "Unable to open local cache file for writing\n" );
+ return;
+ }
+
+ fwrite( $file, $hash . $serialized );
+ fclose( $file );
+ @chmod( $filename, 0666 );
+ }
+
+ function loadFromScript( $hash ) {
+ global $wgLocalMessageCache;
+ if ( $wgLocalMessageCache === false ) {
+ return;
+ }
+
+ $filename = "$wgLocalMessageCache/messages-" . wfWikiID();
+
+ wfSuppressWarnings();
+ $file = fopen( $filename, 'r' );
+ wfRestoreWarnings();
+ if ( !$file ) {
+ return;
+ }
+ $localHash=substr(fread($file,40),8);
+ fclose($file);
+ if ($hash!=$localHash) {
+ return;
+ }
+ require("$wgLocalMessageCache/messages-" . wfWikiID());
+ $this->setCache( $this->mCache);
+ }
+
+ function saveToScript($array, $hash) {
+ global $wgLocalMessageCache;
+ if ( $wgLocalMessageCache === false ) {
+ return;
+ }
+
+ $filename = "$wgLocalMessageCache/messages-" . wfWikiID();
+ $oldUmask = umask( 0 );
+ wfMkdirParents( $wgLocalMessageCache, 0777 );
+ umask( $oldUmask );
+ $file = fopen( $filename.'.tmp', 'w');
+ fwrite($file,"<?php\n//$hash\n\n \$this->mCache = array(");
+
+ foreach ($array as $key => $message) {
+ fwrite($file, "'". $this->escapeForScript($key).
+ "' => '" . $this->escapeForScript($message).
+ "',\n");
+ }
+ fwrite($file,");\n?>");
+ fclose($file);
+ rename($filename.'.tmp',$filename);
+ }
+
+ function escapeForScript($string) {
+ $string = str_replace( '\\', '\\\\', $string );
+ $string = str_replace( '\'', '\\\'', $string );
+ return $string;
+ }
+
+ /**
+ * Set the cache to $cache, if it is valid. Otherwise set the cache to false.
+ */
+ function setCache( $cache ) {
+ if ( isset( $cache['VERSION'] ) && $cache['VERSION'] == MSG_CACHE_VERSION ) {
+ $this->mCache = $cache;
+ } else {
+ $this->mCache = false;
+ }
+ }
+
+ /**
+ * Loads messages either from memcached or the database, if not disabled
+ * On error, quietly switches to a fallback mode
+ * Returns false for a reportable error, true otherwise
+ */
+ function load() {
+ global $wgLocalMessageCache, $wgLocalMessageCacheSerialized;
+
+ if ( $this->mDisable ) {
+ static $shownDisabled = false;
+ if ( !$shownDisabled ) {
+ wfDebug( "MessageCache::load(): disabled\n" );
+ $shownDisabled = true;
+ }
+ return true;
+ }
+ if ( !$this->mUseCache ) {
+ $this->mDeferred = false;
+ return true;
+ }
+
+ $fname = 'MessageCache::load';
+ wfProfileIn( $fname );
+ $success = true;
+
+ $this->mCache = false;
+
+ # Try local cache
+ wfProfileIn( $fname.'-fromlocal' );
+ $hash = $this->mMemc->get( "{$this->mMemcKey}-hash" );
+ if ( $hash ) {
+ if ($wgLocalMessageCacheSerialized) {
+ $this->loadFromLocal( $hash );
+ } else {
+ $this->loadFromScript( $hash );
+ }
+ if ( $this->mCache ) {
+ wfDebug( "MessageCache::load(): got from local cache\n" );
+ }
+ }
+ wfProfileOut( $fname.'-fromlocal' );
+
+ # Try memcached
+ if ( !$this->mCache ) {
+ wfProfileIn( $fname.'-fromcache' );
+ $this->setCache( $this->mMemc->get( $this->mMemcKey ) );
+ if ( $this->mCache ) {
+ wfDebug( "MessageCache::load(): got from global cache\n" );
+ # Save to local cache
+ if ( $wgLocalMessageCache !== false ) {
+ $serialized = serialize( $this->mCache );
+ if ( !$hash ) {
+ $hash = md5( $serialized );
+ $this->mMemc->set( "{$this->mMemcKey}-hash", $hash, $this->mExpiry );
+ }
+ if ($wgLocalMessageCacheSerialized) {
+ $this->saveToLocal( $serialized,$hash );
+ } else {
+ $this->saveToScript( $this->mCache, $hash );
+ }
+ }
+ }
+ wfProfileOut( $fname.'-fromcache' );
+ }
+
+
+ # If there's nothing in memcached, load all the messages from the database
+ if ( !$this->mCache ) {
+ wfDebug( "MessageCache::load(): cache is empty\n" );
+ $this->lock();
+ # Other threads don't need to load the messages if another thread is doing it.
+ $success = $this->mMemc->add( $this->mMemcKey.'-status', "loading", MSG_LOAD_TIMEOUT );
+ if ( $success ) {
+ wfProfileIn( $fname.'-load' );
+ wfDebug( "MessageCache::load(): loading all messages from DB\n" );
+ $this->loadFromDB();
+ wfProfileOut( $fname.'-load' );
+
+ # Save in memcached
+ # Keep trying if it fails, this is kind of important
+ wfProfileIn( $fname.'-save' );
+ for ($i=0; $i<20 &&
+ !$this->mMemc->set( $this->mMemcKey, $this->mCache, $this->mExpiry );
+ $i++ ) {
+ usleep(mt_rand(500000,1500000));
+ }
+
+ # Save to local cache
+ if ( $wgLocalMessageCache !== false ) {
+ $serialized = serialize( $this->mCache );
+ $hash = md5( $serialized );
+ $this->mMemc->set( "{$this->mMemcKey}-hash", $hash, $this->mExpiry );
+ if ($wgLocalMessageCacheSerialized) {
+ $this->saveToLocal( $serialized,$hash );
+ } else {
+ $this->saveToScript( $this->mCache, $hash );
+ }
+ }
+
+ wfProfileOut( $fname.'-save' );
+ if ( $i == 20 ) {
+ $this->mMemc->set( $this->mMemcKey.'-status', 'error', 60*5 );
+ wfDebug( "MemCached set error in MessageCache: restart memcached server!\n" );
+ } else {
+ $this->mMemc->delete( $this->mMemcKey.'-status' );
+ }
+ }
+ $this->unlock();
+ }
+
+ if ( !is_array( $this->mCache ) ) {
+ wfDebug( "MessageCache::load(): unable to load cache, disabled\n" );
+ $this->mDisable = true;
+ $this->mCache = false;
+ }
+ wfProfileOut( $fname );
+ $this->mDeferred = false;
+ return $success;
+ }
+
+ /**
+ * Loads all or main part of cacheable messages from the database
+ */
+ function loadFromDB() {
+ global $wgLang, $wgMaxMsgCacheEntrySize;
+
+ wfProfileIn( __METHOD__ );
+ $dbr =& wfGetDB( DB_SLAVE );
+ $this->mCache = array();
+
+ # Load titles for all oversized pages in the MediaWiki namespace
+ $res = $dbr->select( 'page', 'page_title',
+ array(
+ 'page_len > ' . intval( $wgMaxMsgCacheEntrySize ),
+ 'page_is_redirect' => 0,
+ 'page_namespace' => NS_MEDIAWIKI,
+ ),
+ __METHOD__ );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $this->mCache[$row->page_title] = '!TOO BIG';
+ }
+ $dbr->freeResult( $res );
+
+ # Load text for the remaining pages
+ $res = $dbr->select( array( 'page', 'revision', 'text' ),
+ array( 'page_title', 'old_text', 'old_flags' ),
+ array(
+ 'page_is_redirect' => 0,
+ 'page_namespace' => NS_MEDIAWIKI,
+ 'page_latest=rev_id',
+ 'rev_text_id=old_id',
+ 'page_len <= ' . intval( $wgMaxMsgCacheEntrySize ) ),
+ __METHOD__ );
+
+ for ( $row = $dbr->fetchObject( $res ); $row; $row = $dbr->fetchObject( $res ) ) {
+ $this->mCache[$row->page_title] = ' ' . Revision::getRevisionText( $row );
+ }
+ $this->mCache['VERSION'] = MSG_CACHE_VERSION;
+ $dbr->freeResult( $res );
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Not really needed anymore
+ */
+ function getKeys() {
+ global $wgContLang;
+ if ( !$this->mKeys ) {
+ $this->mKeys = array();
+ $allMessages = Language::getMessagesFor( 'en' );
+ foreach ( $allMessages as $key => $unused ) {
+ $title = $wgContLang->ucfirst( $key );
+ array_push( $this->mKeys, $title );
+ }
+ }
+ return $this->mKeys;
+ }
+
+ function replace( $title, $text ) {
+ global $wgLocalMessageCache, $wgLocalMessageCacheSerialized, $parserMemc;
+ global $wgMaxMsgCacheEntrySize;
+
+ wfProfileIn( __METHOD__ );
+ $this->lock();
+ $this->load();
+ $parserMemc->delete(wfMemcKey('sidebar'));
+ if ( is_array( $this->mCache ) ) {
+ if ( $text === false ) {
+ # Article was deleted
+ unset( $this->mCache[$title] );
+ $this->mMemc->delete( "$this->mMemcKey:{$title}" );
+ } elseif ( strlen( $text ) > $wgMaxMsgCacheEntrySize ) {
+ $this->mCache[$title] = '!TOO BIG';
+ $this->mMemc->set( "$this->mMemcKey:{$title}", ' '.$text, $this->mExpiry );
+ } else {
+ $this->mCache[$title] = ' ' . $text;
+ $this->mMemc->delete( "$this->mMemcKey:{$title}" );
+ }
+ $this->mMemc->set( $this->mMemcKey, $this->mCache, $this->mExpiry );
+
+ # Save to local cache
+ if ( $wgLocalMessageCache !== false ) {
+ $serialized = serialize( $this->mCache );
+ $hash = md5( $serialized );
+ $this->mMemc->set( "{$this->mMemcKey}-hash", $hash, $this->mExpiry );
+ if ($wgLocalMessageCacheSerialized) {
+ $this->saveToLocal( $serialized,$hash );
+ } else {
+ $this->saveToScript( $this->mCache, $hash );
+ }
+ }
+ }
+ $this->unlock();
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Returns success
+ * Represents a write lock on the messages key
+ */
+ function lock() {
+ if ( !$this->mUseCache ) {
+ return true;
+ }
+
+ $lockKey = $this->mMemcKey . 'lock';
+ for ($i=0; $i < MSG_WAIT_TIMEOUT && !$this->mMemc->add( $lockKey, 1, MSG_LOCK_TIMEOUT ); $i++ ) {
+ sleep(1);
+ }
+
+ return $i >= MSG_WAIT_TIMEOUT;
+ }
+
+ function unlock() {
+ if ( !$this->mUseCache ) {
+ return;
+ }
+
+ $lockKey = $this->mMemcKey . 'lock';
+ $this->mMemc->delete( $lockKey );
+ }
+
+ /**
+ * Get a message from either the content language or the user language.
+ *
+ * @param string $key The message cache key
+ * @param bool $useDB Get the message from the DB, false to use only the localisation
+ * @param bool $forContent Get the message from the content language rather than the
+ * user language
+ * @param bool $isFullKey Specifies whether $key is a two part key "lang/msg".
+ */
+ function get( $key, $useDB = true, $forContent = true, $isFullKey = false ) {
+ global $wgContLanguageCode, $wgContLang, $wgLang;
+ if( $forContent ) {
+ $lang =& $wgContLang;
+ } else {
+ $lang =& $wgLang;
+ }
+ $langcode = $lang->getCode();
+ # If uninitialised, someone is trying to call this halfway through Setup.php
+ if( !$this->mInitialised ) {
+ return '&lt;' . htmlspecialchars($key) . '&gt;';
+ }
+ # If cache initialization was deferred, start it now.
+ if( $this->mDeferred && !$this->mDisable && $useDB ) {
+ $this->load();
+ }
+
+ $message = false;
+
+ # Normalise title-case input
+ $lckey = $wgContLang->lcfirst( $key );
+ $lckey = str_replace( ' ', '_', $lckey );
+
+ # Try the MediaWiki namespace
+ if( !$this->mDisable && $useDB ) {
+ $title = $wgContLang->ucfirst( $lckey );
+ if(!$isFullKey && ($langcode != $wgContLanguageCode) ) {
+ $title .= '/' . $langcode;
+ }
+ $message = $this->getMsgFromNamespace( $title );
+ }
+ # Try the extension array
+ if( $message === false && isset( $this->mExtensionMessages[$langcode][$lckey] ) ) {
+ $message = $this->mExtensionMessages[$langcode][$lckey];
+ }
+ if ( $message === false && isset( $this->mExtensionMessages['en'][$lckey] ) ) {
+ $message = $this->mExtensionMessages['en'][$lckey];
+ }
+
+ # Try the array in the language object
+ if( $message === false ) {
+ #wfDebug( "Trying language object for message $key\n" );
+ wfSuppressWarnings();
+ $message = $lang->getMessage( $lckey );
+ wfRestoreWarnings();
+ if ( is_null( $message ) ) {
+ $message = false;
+ }
+ }
+
+ # Try the array of another language
+ if( $message === false && strpos( $lckey, '/' ) ) {
+ $message = explode( '/', $lckey );
+ if ( $message[1] ) {
+ wfSuppressWarnings();
+ $message = Language::getMessageFor( $message[0], $message[1] );
+ wfRestoreWarnings();
+ if ( is_null( $message ) ) {
+ $message = false;
+ }
+ } else {
+ $message = false;
+ }
+ }
+
+ # Is this a custom message? Try the default language in the db...
+ if( ($message === false || $message === '-' ) &&
+ !$this->mDisable && $useDB &&
+ !$isFullKey && ($langcode != $wgContLanguageCode) ) {
+ $message = $this->getMsgFromNamespace( $wgContLang->ucfirst( $lckey ) );
+ }
+
+ # Final fallback
+ if( $message === false ) {
+ return '&lt;' . htmlspecialchars($key) . '&gt;';
+ }
+
+ # Replace brace tags
+ $message = $this->transform( $message );
+ return $message;
+ }
+
+ /**
+ * Get a message from the MediaWiki namespace, with caching. The key must
+ * first be converted to two-part lang/msg form if necessary.
+ *
+ * @param string $title Message cache key with initial uppercase letter
+ */
+ function getMsgFromNamespace( $title ) {
+ $message = false;
+ $type = false;
+
+ # Try the cache
+ if( $this->mUseCache && isset( $this->mCache[$title] ) ) {
+ $entry = $this->mCache[$title];
+ $type = substr( $entry, 0, 1 );
+ if ( $type == ' ' ) {
+ return substr( $entry, 1 );
+ }
+ }
+
+ # Call message hooks, in case they are defined
+ wfRunHooks('MessagesPreLoad', array( $title, &$message ) );
+ if ( $message !== false ) {
+ return $message;
+ }
+
+ # If there is no cache entry and no placeholder, it doesn't exist
+ if ( $type != '!' && $message === false ) {
+ return false;
+ }
+
+ $memcKey = $this->mMemcKey . ':' . $title;
+
+ # Try the individual message cache
+ if ( $this->mUseCache ) {
+ $entry = $this->mMemc->get( $memcKey );
+ if ( $entry ) {
+ $type = substr( $entry, 0, 1 );
+
+ if ( $type == ' ' ) {
+ $message = substr( $entry, 1 );
+ $this->mCache[$title] = $message;
+ return $message;
+ } elseif ( $entry == '!NONEXISTENT' ) {
+ return false;
+ } else {
+ # Corrupt/obsolete entry, delete it
+ $this->mMemc->delete( $memcKey );
+ }
+
+ }
+ }
+
+ # Try loading it from the DB
+ $revision = Revision::newFromTitle( Title::makeTitle( NS_MEDIAWIKI, $title ) );
+ if( $revision ) {
+ $message = $revision->getText();
+ if ($this->mUseCache) {
+ $this->mCache[$title] = ' ' . $message;
+ $this->mMemc->set( $memcKey, $message, $this->mExpiry );
+ }
+ } else {
+ # Negative caching
+ # Use some special text instead of false, because false gets converted to '' somewhere
+ $this->mMemc->set( $memcKey, '!NONEXISTENT', $this->mExpiry );
+ $this->mCache[$title] = false;
+ }
+
+ return $message;
+ }
+
+ function transform( $message ) {
+ global $wgParser;
+ if ( !$this->mParser && isset( $wgParser ) ) {
+ # Do some initialisation so that we don't have to do it twice
+ $wgParser->firstCallInit();
+ # Clone it and store it
+ $this->mParser = clone $wgParser;
+ }
+ if ( !$this->mDisableTransform && $this->mParser ) {
+ if( strpos( $message, '{{' ) !== false ) {
+ $message = $this->mParser->transformMsg( $message, $this->getParserOptions() );
+ }
+ }
+ return $message;
+ }
+
+ function disable() { $this->mDisable = true; }
+ function enable() { $this->mDisable = false; }
+ function disableTransform() { $this->mDisableTransform = true; }
+ function enableTransform() { $this->mDisableTransform = false; }
+ function setTransform( $x ) { $this->mDisableTransform = $x; }
+ function getTransform() { return $this->mDisableTransform; }
+
+ /**
+ * Add a message to the cache
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @param string $lang The messages language, English by default
+ */
+ function addMessage( $key, $value, $lang = 'en' ) {
+ $this->mExtensionMessages[$lang][$key] = $value;
+ }
+
+ /**
+ * Add an associative array of message to the cache
+ *
+ * @param array $messages An associative array of key => values to be added
+ * @param string $lang The messages language, English by default
+ */
+ function addMessages( $messages, $lang = 'en' ) {
+ wfProfileIn( __METHOD__ );
+ if ( isset( $this->mExtensionMessages[$lang] ) ) {
+ $this->mExtensionMessages[$lang] = $messages + $this->mExtensionMessages[$lang];
+ } else {
+ $this->mExtensionMessages[$lang] = $messages;
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Add a 2-D array of messages by lang. Useful for extensions.
+ * Introduced in 1.9. Please do not use it for now, for backwards compatibility.
+ *
+ * @param array $messages The array to be added
+ */
+ function addMessagesByLang( $messages ) {
+ wfProfileIn( __METHOD__ );
+ foreach ( $messages as $key => $value ) {
+ $this->addMessages( $value, $key );
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Get the extension messages for a specific language
+ *
+ * @param string $lang The messages language, English by default
+ */
+ function getExtensionMessagesFor( $lang = 'en' ) {
+ wfProfileIn( __METHOD__ );
+ $messages = array();
+ if ( isset( $this->mExtensionMessages[$lang] ) ) {
+ $messages = $this->mExtensionMessages[$lang];
+ }
+ if ( $lang != 'en' ) {
+ $messages = $messages + $this->mExtensionMessages['en'];
+ }
+ wfProfileOut( __METHOD__ );
+ return $messages;
+ }
+
+ /**
+ * Clear all stored messages. Mainly used after a mass rebuild.
+ */
+ function clear() {
+ global $wgLocalMessageCache;
+ if( $this->mUseCache ) {
+ # Global cache
+ $this->mMemc->delete( $this->mMemcKey );
+ # Invalidate all local caches
+ $this->mMemc->delete( "{$this->mMemcKey}-hash" );
+ }
+ }
+
+ static function loadAllMessages() {
+ # Some extensions will load their messages when you load their class file
+ wfLoadAllExtensions();
+ # Others will respond to this hook
+ wfRunHooks( 'LoadAllMessages' );
+ # Still others will respond to neither, they are EVIL. We sometimes need to know!
+ }
+}
+?>
diff --git a/includes/Metadata.php b/includes/Metadata.php
new file mode 100644
index 000000000000..4e0d91b76239
--- /dev/null
+++ b/includes/Metadata.php
@@ -0,0 +1,367 @@
+<?php
+/**
+ * Metadata.php -- provides DublinCore and CreativeCommons metadata
+ * Copyright 2004, Evan Prodromou <evan@wikitravel.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
+ *
+ * @author Evan Prodromou <evan@wikitravel.org>
+ * @package MediaWiki
+ */
+
+/**
+ * TODO: Perhaps make this file into a Metadata class, with static methods (declared
+ * as private where indicated), to move these functions out of the global namespace?
+ */
+define('RDF_TYPE_PREFS', "application/rdf+xml,text/xml;q=0.7,application/xml;q=0.5,text/rdf;q=0.1");
+
+function wfDublinCoreRdf($article) {
+
+ $url = dcReallyFullUrl($article->mTitle);
+
+ if (rdfSetup()) {
+ dcPrologue($url);
+ dcBasics($article);
+ dcEpilogue();
+ }
+}
+
+function wfCreativeCommonsRdf($article) {
+
+ if (rdfSetup()) {
+ global $wgRightsUrl;
+
+ $url = dcReallyFullUrl($article->mTitle);
+
+ ccPrologue();
+ ccSubPrologue('Work', $url);
+ dcBasics($article);
+ if (isset($wgRightsUrl)) {
+ $url = htmlspecialchars( $wgRightsUrl );
+ print " <cc:license rdf:resource=\"$url\" />\n";
+ }
+
+ ccSubEpilogue('Work');
+
+ if (isset($wgRightsUrl)) {
+ $terms = ccGetTerms($wgRightsUrl);
+ if ($terms) {
+ ccSubPrologue('License', $wgRightsUrl);
+ ccLicense($terms);
+ ccSubEpilogue('License');
+ }
+ }
+ }
+
+ ccEpilogue();
+}
+
+/**
+ * @private
+ */
+function rdfSetup() {
+ global $wgOut, $_SERVER;
+
+ $rdftype = wfNegotiateType(wfAcceptToPrefs($_SERVER['HTTP_ACCEPT']), wfAcceptToPrefs(RDF_TYPE_PREFS));
+
+ if (!$rdftype) {
+ wfHttpError(406, "Not Acceptable", wfMsg("notacceptable"));
+ return false;
+ } else {
+ $wgOut->disable();
+ header( "Content-type: {$rdftype}; charset=utf-8" );
+ $wgOut->sendCacheControl();
+ return true;
+ }
+}
+
+/**
+ * @private
+ */
+function dcPrologue($url) {
+ global $wgOutputEncoding;
+
+ $url = htmlspecialchars( $url );
+ print "<" . "?xml version=\"1.0\" encoding=\"{$wgOutputEncoding}\" ?" . ">
+
+ <!DOCTYPE rdf:RDF PUBLIC \"-//DUBLIN CORE//DCMES DTD 2002/07/31//EN\" \"http://dublincore.org/documents/2002/07/31/dcmes-xml/dcmes-xml-dtd.dtd\">
+
+ <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
+ xmlns:dc=\"http://purl.org/dc/elements/1.1/\">
+ <rdf:Description rdf:about=\"$url\">
+ ";
+}
+
+/**
+ * @private
+ */
+function dcEpilogue() {
+ print "
+ </rdf:Description>
+ </rdf:RDF>
+ ";
+}
+
+/**
+ * @private
+ */
+function dcBasics($article) {
+ global $wgContLanguageCode, $wgSitename;
+
+ dcElement('title', $article->mTitle->getText());
+ dcPageOrString('publisher', wfMsg('aboutpage'), $wgSitename);
+ dcElement('language', $wgContLanguageCode);
+ dcElement('type', 'Text');
+ dcElement('format', 'text/html');
+ dcElement('identifier', dcReallyFullUrl($article->mTitle));
+ dcElement('date', dcDate($article->getTimestamp()));
+
+ $last_editor = $article->getUser();
+
+ if ($last_editor == 0) {
+ dcPerson('creator', 0);
+ } else {
+ dcPerson('creator', $last_editor, $article->getUserText(),
+ User::whoIsReal($last_editor));
+ }
+
+ $contributors = $article->getContributors();
+
+ foreach ($contributors as $user_parts) {
+ dcPerson('contributor', $user_parts[0], $user_parts[1], $user_parts[2]);
+ }
+
+ dcRights();
+}
+
+/**
+ * @private
+ */
+function ccPrologue() {
+ global $wgOutputEncoding;
+
+ echo "<" . "?xml version='1.0' encoding='{$wgOutputEncoding}' ?" . ">
+
+ <rdf:RDF xmlns:cc=\"http://web.resource.org/cc/\"
+ xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
+ xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">
+ ";
+}
+
+/**
+ * @private
+ */
+function ccSubPrologue($type, $url) {
+ $url = htmlspecialchars( $url );
+ echo " <cc:{$type} rdf:about=\"{$url}\">\n";
+}
+
+/**
+ * @private
+ */
+function ccSubEpilogue($type) {
+ echo " </cc:{$type}>\n";
+}
+
+/**
+ * @private
+ */
+function ccLicense($terms) {
+
+ foreach ($terms as $term) {
+ switch ($term) {
+ case 're':
+ ccTerm('permits', 'Reproduction'); break;
+ case 'di':
+ ccTerm('permits', 'Distribution'); break;
+ case 'de':
+ ccTerm('permits', 'DerivativeWorks'); break;
+ case 'nc':
+ ccTerm('prohibits', 'CommercialUse'); break;
+ case 'no':
+ ccTerm('requires', 'Notice'); break;
+ case 'by':
+ ccTerm('requires', 'Attribution'); break;
+ case 'sa':
+ ccTerm('requires', 'ShareAlike'); break;
+ case 'sc':
+ ccTerm('requires', 'SourceCode'); break;
+ }
+ }
+}
+
+/**
+ * @private
+ */
+function ccTerm($term, $name) {
+ print " <cc:{$term} rdf:resource=\"http://web.resource.org/cc/{$name}\" />\n";
+}
+
+/**
+ * @private
+ */
+function ccEpilogue() {
+ echo "</rdf:RDF>\n";
+}
+
+/**
+ * @private
+ */
+function dcElement($name, $value) {
+ $value = htmlspecialchars( $value );
+ print " <dc:{$name}>{$value}</dc:{$name}>\n";
+}
+
+/**
+ * @private
+ */
+function dcDate($timestamp) {
+ return substr($timestamp, 0, 4) . '-'
+ . substr($timestamp, 4, 2) . '-'
+ . substr($timestamp, 6, 2);
+}
+
+/**
+ * @private
+ */
+function dcReallyFullUrl($title) {
+ return $title->getFullURL();
+}
+
+/**
+ * @private
+ */
+function dcPageOrString($name, $page, $str) {
+ $nt = Title::newFromText($page);
+
+ if (!$nt || $nt->getArticleID() == 0) {
+ dcElement($name, $str);
+ } else {
+ dcPage($name, $nt);
+ }
+}
+
+/**
+ * @private
+ */
+function dcPage($name, $title) {
+ dcUrl($name, dcReallyFullUrl($title));
+}
+
+/**
+ * @private
+ */
+function dcUrl($name, $url) {
+ $url = htmlspecialchars( $url );
+ print " <dc:{$name} rdf:resource=\"{$url}\" />\n";
+}
+
+/**
+ * @private
+ */
+function dcPerson($name, $id, $user_name='', $user_real_name='') {
+ global $wgContLang;
+
+ if ($id == 0) {
+ dcElement($name, wfMsg('anonymous'));
+ } else if ( !empty($user_real_name) ) {
+ dcElement($name, $user_real_name);
+ } else {
+ # XXX: This shouldn't happen.
+ if( empty( $user_name ) ) {
+ $user_name = User::whoIs($id);
+ }
+ dcPageOrString($name, $wgContLang->getNsText(NS_USER) . ':' . $user_name, wfMsg('siteuser', $user_name));
+ }
+}
+
+/**
+ * Takes an arg, for future enhancement with different rights for
+ * different pages.
+ * @private
+ */
+function dcRights() {
+
+ global $wgRightsPage, $wgRightsUrl, $wgRightsText;
+
+ if (isset($wgRightsPage) &&
+ ($nt = Title::newFromText($wgRightsPage))
+ && ($nt->getArticleID() != 0)) {
+ dcPage('rights', $nt);
+ } else if (isset($wgRightsUrl)) {
+ dcUrl('rights', $wgRightsUrl);
+ } else if (isset($wgRightsText)) {
+ dcElement('rights', $wgRightsText);
+ }
+}
+
+/**
+ * @private
+ */
+function ccGetTerms($url) {
+ global $wgLicenseTerms;
+
+ if (isset($wgLicenseTerms)) {
+ return $wgLicenseTerms;
+ } else {
+ $known = getKnownLicenses();
+ if( isset( $known[$url] ) ) {
+ return $known[$url];
+ } else {
+ return array();
+ }
+ }
+}
+
+/**
+ * @private
+ */
+function getKnownLicenses() {
+
+ $ccLicenses = array('by', 'by-nd', 'by-nd-nc', 'by-nc',
+ 'by-nc-sa', 'by-sa');
+ $ccVersions = array('1.0', '2.0');
+ $knownLicenses = array();
+
+ foreach ($ccVersions as $version) {
+ foreach ($ccLicenses as $license) {
+ if( $version == '2.0' && substr( $license, 0, 2) != 'by' ) {
+ # 2.0 dropped the non-attribs licenses
+ continue;
+ }
+ $lurl = "http://creativecommons.org/licenses/{$license}/{$version}/";
+ $knownLicenses[$lurl] = explode('-', $license);
+ $knownLicenses[$lurl][] = 're';
+ $knownLicenses[$lurl][] = 'di';
+ $knownLicenses[$lurl][] = 'no';
+ if (!in_array('nd', $knownLicenses[$lurl])) {
+ $knownLicenses[$lurl][] = 'de';
+ }
+ }
+ }
+
+ /* Handle the GPL and LGPL, too. */
+
+ $knownLicenses['http://creativecommons.org/licenses/GPL/2.0/'] =
+ array('de', 're', 'di', 'no', 'sa', 'sc');
+ $knownLicenses['http://creativecommons.org/licenses/LGPL/2.1/'] =
+ array('de', 're', 'di', 'no', 'sa', 'sc');
+ $knownLicenses['http://www.gnu.org/copyleft/fdl.html'] =
+ array('de', 're', 'di', 'no', 'sa', 'sc');
+
+ return $knownLicenses;
+}
+
+?>
diff --git a/includes/MimeMagic.php b/includes/MimeMagic.php
new file mode 100644
index 000000000000..ca05dbb35147
--- /dev/null
+++ b/includes/MimeMagic.php
@@ -0,0 +1,715 @@
+<?php
+/** Module defining helper functions for detecting and dealing with mime types.
+ *
+ * @package MediaWiki
+ */
+
+ /** Defines a set of well known mime types
+ * This is used as a fallback to mime.types files.
+ * An extensive list of well known mime types is provided by
+ * the file mime.types in the includes directory.
+ */
+define('MM_WELL_KNOWN_MIME_TYPES',<<<END_STRING
+application/ogg ogg ogm
+application/pdf pdf
+application/x-javascript js
+application/x-shockwave-flash swf
+audio/midi mid midi kar
+audio/mpeg mpga mpa mp2 mp3
+audio/x-aiff aif aiff aifc
+audio/x-wav wav
+audio/ogg ogg
+image/x-bmp bmp
+image/gif gif
+image/jpeg jpeg jpg jpe
+image/png png
+image/svg+xml svg
+image/tiff tiff tif
+image/vnd.djvu djvu
+text/plain txt
+text/html html htm
+video/ogg ogm ogg
+video/mpeg mpg mpeg
+END_STRING
+);
+
+ /** Defines a set of well known mime info entries
+ * This is used as a fallback to mime.info files.
+ * An extensive list of well known mime types is provided by
+ * the file mime.info in the includes directory.
+ */
+define('MM_WELL_KNOWN_MIME_INFO', <<<END_STRING
+application/pdf [OFFICE]
+text/javascript application/x-javascript [EXECUTABLE]
+application/x-shockwave-flash [MULTIMEDIA]
+audio/midi [AUDIO]
+audio/x-aiff [AUDIO]
+audio/x-wav [AUDIO]
+audio/mp3 audio/mpeg [AUDIO]
+application/ogg audio/ogg video/ogg [MULTIMEDIA]
+image/x-bmp image/bmp [BITMAP]
+image/gif [BITMAP]
+image/jpeg [BITMAP]
+image/png [BITMAP]
+image/svg image/svg+xml [DRAWING]
+image/tiff [BITMAP]
+image/vnd.djvu [BITMAP]
+text/plain [TEXT]
+text/html [TEXT]
+video/ogg [VIDEO]
+video/mpeg [VIDEO]
+unknown/unknown application/octet-stream application/x-empty [UNKNOWN]
+END_STRING
+);
+
+#note: because this file is possibly included by a function,
+#we need to access the global scope explicitely!
+global $wgLoadFileinfoExtension;
+
+if ($wgLoadFileinfoExtension) {
+ if(!extension_loaded('fileinfo')) dl('fileinfo.' . PHP_SHLIB_SUFFIX);
+}
+
+/** Implements functions related to mime types such as detection and mapping to
+* file extension,
+*
+* Instances of this class are stateles, there only needs to be one global instance
+* of MimeMagic. Please use MimeMagic::singleton() to get that instance.
+* @package MediaWiki
+*/
+class MimeMagic {
+
+ /**
+ * Mapping of media types to arrays of mime types.
+ * This is used by findMediaType and getMediaType, respectively
+ */
+ var $mMediaTypes= NULL;
+
+ /** Map of mime type aliases
+ */
+ var $mMimeTypeAliases= NULL;
+
+ /** map of mime types to file extensions (as a space seprarated list)
+ */
+ var $mMimeToExt= NULL;
+
+ /** map of file extensions types to mime types (as a space seprarated list)
+ */
+ var $mExtToMime= NULL;
+
+ /** The singleton instance
+ */
+ private static $instance;
+
+ /** Initializes the MimeMagic object. This is called by MimeMagic::singleton().
+ *
+ * This constructor parses the mime.types and mime.info files and build internal mappings.
+ */
+ function MimeMagic() {
+ /*
+ * --- load mime.types ---
+ */
+
+ global $wgMimeTypeFile;
+
+ $types= MM_WELL_KNOWN_MIME_TYPES;
+
+ if ($wgMimeTypeFile) {
+ if (is_file($wgMimeTypeFile) and is_readable($wgMimeTypeFile)) {
+ wfDebug("MimeMagic::MimeMagic: loading mime types from $wgMimeTypeFile\n");
+
+ $types.= "\n";
+ $types.= file_get_contents($wgMimeTypeFile);
+ }
+ else wfDebug("MimeMagic::MimeMagic: can't load mime types from $wgMimeTypeFile\n");
+ }
+ else wfDebug("MimeMagic::MimeMagic: no mime types file defined, using build-ins only.\n");
+
+ $types= str_replace(array("\r\n","\n\r","\n\n","\r\r","\r"),"\n",$types);
+ $types= str_replace("\t"," ",$types);
+
+ $this->mMimeToExt= array();
+ $this->mToMime= array();
+
+ $lines= explode("\n",$types);
+ foreach ($lines as $s) {
+ $s= trim($s);
+ if (empty($s)) continue;
+ if (strpos($s,'#')===0) continue;
+
+ $s= strtolower($s);
+ $i= strpos($s,' ');
+
+ if ($i===false) continue;
+
+ #print "processing MIME line $s<br>";
+
+ $mime= substr($s,0,$i);
+ $ext= trim(substr($s,$i+1));
+
+ if (empty($ext)) continue;
+
+ if (@$this->mMimeToExt[$mime]) $this->mMimeToExt[$mime] .= ' '.$ext;
+ else $this->mMimeToExt[$mime]= $ext;
+
+ $extensions= explode(' ',$ext);
+
+ foreach ($extensions as $e) {
+ $e= trim($e);
+ if (empty($e)) continue;
+
+ if (@$this->mExtToMime[$e]) $this->mExtToMime[$e] .= ' '.$mime;
+ else $this->mExtToMime[$e]= $mime;
+ }
+ }
+
+ /*
+ * --- load mime.info ---
+ */
+
+ global $wgMimeInfoFile;
+
+ $info= MM_WELL_KNOWN_MIME_INFO;
+
+ if ($wgMimeInfoFile) {
+ if (is_file($wgMimeInfoFile) and is_readable($wgMimeInfoFile)) {
+ wfDebug("MimeMagic::MimeMagic: loading mime info from $wgMimeInfoFile\n");
+
+ $info.= "\n";
+ $info.= file_get_contents($wgMimeInfoFile);
+ }
+ else wfDebug("MimeMagic::MimeMagic: can't load mime info from $wgMimeInfoFile\n");
+ }
+ else wfDebug("MimeMagic::MimeMagic: no mime info file defined, using build-ins only.\n");
+
+ $info= str_replace(array("\r\n","\n\r","\n\n","\r\r","\r"),"\n",$info);
+ $info= str_replace("\t"," ",$info);
+
+ $this->mMimeTypeAliases= array();
+ $this->mMediaTypes= array();
+
+ $lines= explode("\n",$info);
+ foreach ($lines as $s) {
+ $s= trim($s);
+ if (empty($s)) continue;
+ if (strpos($s,'#')===0) continue;
+
+ $s= strtolower($s);
+ $i= strpos($s,' ');
+
+ if ($i===false) continue;
+
+ #print "processing MIME INFO line $s<br>";
+
+ $match= array();
+ if (preg_match('!\[\s*(\w+)\s*\]!',$s,$match)) {
+ $s= preg_replace('!\[\s*(\w+)\s*\]!','',$s);
+ $mtype= trim(strtoupper($match[1]));
+ }
+ else $mtype= MEDIATYPE_UNKNOWN;
+
+ $m= explode(' ',$s);
+
+ if (!isset($this->mMediaTypes[$mtype])) $this->mMediaTypes[$mtype]= array();
+
+ foreach ($m as $mime) {
+ $mime= trim($mime);
+ if (empty($mime)) continue;
+
+ $this->mMediaTypes[$mtype][]= $mime;
+ }
+
+ if (sizeof($m)>1) {
+ $main= $m[0];
+ for ($i=1; $i<sizeof($m); $i+= 1) {
+ $mime= $m[$i];
+ $this->mMimeTypeAliases[$mime]= $main;
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Get an instance of this class
+ */
+ static function &singleton() {
+ if ( !isset( self::$instance ) ) {
+ self::$instance = new MimeMagic;
+ }
+ return self::$instance;
+ }
+
+ /** returns a list of file extensions for a given mime type
+ * as a space separated string.
+ */
+ function getExtensionsForType($mime) {
+ $mime= strtolower($mime);
+
+ $r= @$this->mMimeToExt[$mime];
+
+ if (@!$r and isset($this->mMimeTypeAliases[$mime])) {
+ $mime= $this->mMimeTypeAliases[$mime];
+ $r= @$this->mMimeToExt[$mime];
+ }
+
+ return $r;
+ }
+
+ /** returns a list of mime types for a given file extension
+ * as a space separated string.
+ */
+ function getTypesForExtension($ext) {
+ $ext= strtolower($ext);
+
+ $r= @$this->mExtToMime[$ext];
+ return $r;
+ }
+
+ /** returns a single mime type for a given file extension.
+ * This is always the first type from the list returned by getTypesForExtension($ext).
+ */
+ function guessTypesForExtension($ext) {
+ $m= $this->getTypesForExtension( $ext );
+ if( is_null($m) ) return NULL;
+
+ $m= trim( $m );
+ $m= preg_replace('/\s.*$/','',$m);
+
+ return $m;
+ }
+
+
+ /** tests if the extension matches the given mime type.
+ * returns true if a match was found, NULL if the mime type is unknown,
+ * and false if the mime type is known but no matches where found.
+ */
+ function isMatchingExtension($extension,$mime) {
+ $ext= $this->getExtensionsForType($mime);
+
+ if (!$ext) {
+ return NULL; //unknown
+ }
+
+ $ext= explode(' ',$ext);
+
+ $extension= strtolower($extension);
+ if (in_array($extension,$ext)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /** returns true if the mime type is known to represent
+ * an image format supported by the PHP GD library.
+ */
+ function isPHPImageType( $mime ) {
+ #as defined by imagegetsize and image_type_to_mime
+ static $types = array(
+ 'image/gif', 'image/jpeg', 'image/png',
+ 'image/x-bmp', 'image/xbm', 'image/tiff',
+ 'image/jp2', 'image/jpeg2000', 'image/iff',
+ 'image/xbm', 'image/x-xbitmap',
+ 'image/vnd.wap.wbmp', 'image/vnd.xiff',
+ 'image/x-photoshop',
+ 'application/x-shockwave-flash',
+ );
+
+ return in_array( $mime, $types );
+ }
+
+ /**
+ * Returns true if the extension represents a type which can
+ * be reliably detected from its content. Use this to determine
+ * whether strict content checks should be applied to reject
+ * invalid uploads; if we can't identify the type we won't
+ * be able to say if it's invalid.
+ *
+ * @todo Be more accurate when using fancy mime detector plugins;
+ * right now this is the bare minimum getimagesize() list.
+ * @return bool
+ */
+ function isRecognizableExtension( $extension ) {
+ static $types = array(
+ 'gif', 'jpeg', 'jpg', 'png', 'swf', 'psd',
+ 'bmp', 'tiff', 'tif', 'jpc', 'jp2',
+ 'jpx', 'jb2', 'swc', 'iff', 'wbmp',
+ 'xbm', 'djvu'
+ );
+ return in_array( strtolower( $extension ), $types );
+ }
+
+
+ /** mime type detection. This uses detectMimeType to detect the mim type of the file,
+ * but applies additional checks to determine some well known file formats that may be missed
+ * or misinterpreter by the default mime detection (namely xml based formats like XHTML or SVG).
+ *
+ * @param string $file The file to check
+ * @param bool $useExt switch for allowing to use the file extension to guess the mime type. true by default.
+ *
+ * @return string the mime type of $file
+ */
+ function guessMimeType( $file, $useExt=true ) {
+ $fname = 'MimeMagic::guessMimeType';
+ $mime= $this->detectMimeType($file,$useExt);
+
+ // Read a chunk of the file
+ $f = fopen( $file, "rt" );
+ if( !$f ) return "unknown/unknown";
+ $head = fread( $f, 1024 );
+ fclose( $f );
+
+ $sub4 = substr( $head, 0, 4 );
+ if ( $sub4 == "\x01\x00\x09\x00" || $sub4 == "\xd7\xcd\xc6\x9a" ) {
+ // WMF kill kill kill
+ // Note that WMF may have a bare header, no magic number.
+ // The former of the above two checks is theoretically prone to false positives
+ $mime = "application/x-msmetafile";
+ }
+
+ if (strpos($mime,"text/")===0 || $mime==="application/xml") {
+
+ $xml_type= NULL;
+ $script_type= NULL;
+
+ /*
+ * look for XML formats (XHTML and SVG)
+ */
+ if ($mime==="text/sgml" ||
+ $mime==="text/plain" ||
+ $mime==="text/html" ||
+ $mime==="text/xml" ||
+ $mime==="application/xml") {
+
+ if (substr($head,0,5)=="<?xml") $xml_type= "ASCII";
+ elseif (substr($head,0,8)=="\xef\xbb\xbf<?xml") $xml_type= "UTF-8";
+ elseif (substr($head,0,10)=="\xfe\xff\x00<\x00?\x00x\x00m\x00l") $xml_type= "UTF-16BE";
+ elseif (substr($head,0,10)=="\xff\xfe<\x00?\x00x\x00m\x00l\x00") $xml_type= "UTF-16LE";
+
+ if ($xml_type) {
+ if ($xml_type!=="UTF-8" && $xml_type!=="ASCII") $head= iconv($xml_type,"ASCII//IGNORE",$head);
+
+ $match= array();
+ $doctype= "";
+ $tag= "";
+
+ if (preg_match('%<!DOCTYPE\s+[\w-]+\s+PUBLIC\s+["'."'".'"](.*?)["'."'".'"].*>%sim',$head,$match)) $doctype= $match[1];
+ if (preg_match('%<(\w+).*>%sim',$head,$match)) $tag= $match[1];
+
+ #print "<br>ANALYSING $file ($mime): doctype= $doctype; tag= $tag<br>";
+
+ if (strpos($doctype,"-//W3C//DTD SVG")===0) $mime= "image/svg";
+ elseif ($tag==="svg") $mime= "image/svg";
+ elseif (strpos($doctype,"-//W3C//DTD XHTML")===0) $mime= "text/html";
+ elseif ($tag==="html") $mime= "text/html";
+ }
+ }
+
+ /*
+ * look for shell scripts
+ */
+ if (!$xml_type) {
+ $script_type= NULL;
+
+ #detect by shebang
+ if (substr($head,0,2)=="#!") $script_type= "ASCII";
+ elseif (substr($head,0,5)=="\xef\xbb\xbf#!") $script_type= "UTF-8";
+ elseif (substr($head,0,7)=="\xfe\xff\x00#\x00!") $script_type= "UTF-16BE";
+ elseif (substr($head,0,7)=="\xff\xfe#\x00!") $script_type= "UTF-16LE";
+
+ if ($script_type) {
+ if ($script_type!=="UTF-8" && $script_type!=="ASCII") $head= iconv($script_type,"ASCII//IGNORE",$head);
+
+ $match= array();
+ $prog= "";
+
+ if (preg_match('%/?([^\s]+/)(w+)%sim',$head,$match)) $script= $match[2];
+
+ $mime= "application/x-$prog";
+ }
+ }
+
+ /*
+ * look for PHP
+ */
+ if( !$xml_type && !$script_type ) {
+
+ if( ( strpos( $head, '<?php' ) !== false ) ||
+ ( strpos( $head, '<? ' ) !== false ) ||
+ ( strpos( $head, "<?\n" ) !== false ) ||
+ ( strpos( $head, "<?\t" ) !== false ) ||
+ ( strpos( $head, "<?=" ) !== false ) ||
+
+ ( strpos( $head, "<\x00?\x00p\x00h\x00p" ) !== false ) ||
+ ( strpos( $head, "<\x00?\x00 " ) !== false ) ||
+ ( strpos( $head, "<\x00?\x00\n" ) !== false ) ||
+ ( strpos( $head, "<\x00?\x00\t" ) !== false ) ||
+ ( strpos( $head, "<\x00?\x00=" ) !== false ) ) {
+
+ $mime= "application/x-php";
+ }
+ }
+
+ }
+
+ if (isset($this->mMimeTypeAliases[$mime])) $mime= $this->mMimeTypeAliases[$mime];
+
+ wfDebug("$fname: final mime type of $file: $mime\n");
+ return $mime;
+ }
+
+ /** Internal mime type detection, please use guessMimeType() for application code instead.
+ * Detection is done using an external program, if $wgMimeDetectorCommand is set.
+ * Otherwise, the fileinfo extension and mime_content_type are tried (in this order), if they are available.
+ * If the dections fails and $useExt is true, the mime type is guessed from the file extension, using guessTypesForExtension.
+ * If the mime type is still unknown, getimagesize is used to detect the mime type if the file is an image.
+ * If no mime type can be determined, this function returns "unknown/unknown".
+ *
+ * @param string $file The file to check
+ * @param bool $useExt switch for allowing to use the file extension to guess the mime type. true by default.
+ *
+ * @return string the mime type of $file
+ * @access private
+ */
+ function detectMimeType( $file, $useExt=true ) {
+ $fname = 'MimeMagic::detectMimeType';
+
+ global $wgMimeDetectorCommand;
+
+ $m= NULL;
+ if ($wgMimeDetectorCommand) {
+ $fn= wfEscapeShellArg($file);
+ $m= `$wgMimeDetectorCommand $fn`;
+ }
+ else if (function_exists("finfo_open") && function_exists("finfo_file")) {
+
+ # This required the fileinfo extension by PECL,
+ # see http://pecl.php.net/package/fileinfo
+ # This must be compiled into PHP
+ #
+ # finfo is the official replacement for the deprecated
+ # mime_content_type function, see below.
+ #
+ # If you may need to load the fileinfo extension at runtime, set
+ # $wgLoadFileinfoExtension in LocalSettings.php
+
+ $mime_magic_resource = finfo_open(FILEINFO_MIME); /* return mime type ala mimetype extension */
+
+ if ($mime_magic_resource) {
+ $m= finfo_file($mime_magic_resource, $file);
+
+ finfo_close($mime_magic_resource);
+ }
+ else wfDebug("$fname: finfo_open failed on ".FILEINFO_MIME."!\n");
+ }
+ else if (function_exists("mime_content_type")) {
+
+ # NOTE: this function is available since PHP 4.3.0, but only if
+ # PHP was compiled with --with-mime-magic or, before 4.3.2, with --enable-mime-magic.
+ #
+ # On Windows, you must set mime_magic.magicfile in php.ini to point to the mime.magic file bundeled with PHP;
+ # sometimes, this may even be needed under linus/unix.
+ #
+ # Also note that this has been DEPRECATED in favor of the fileinfo extension by PECL, see above.
+ # see http://www.php.net/manual/en/ref.mime-magic.php for details.
+
+ $m= mime_content_type($file);
+
+ if ( $m == 'text/plain' ) {
+ // mime_content_type sometimes considers DJVU files to be text/plain.
+ $deja = new DjVuImage( $file );
+ if( $deja->isValid() ) {
+ wfDebug("$fname: (re)detected $file as image/vnd.djvu\n");
+ $m = 'image/vnd.djvu';
+ }
+ }
+ }
+ else wfDebug("$fname: no magic mime detector found!\n");
+
+ if ($m) {
+ #normalize
+ $m= preg_replace('![;, ].*$!','',$m); #strip charset, etc
+ $m= trim($m);
+ $m= strtolower($m);
+
+ if (strpos($m,'unknown')!==false) $m= NULL;
+ else {
+ wfDebug("$fname: magic mime type of $file: $m\n");
+ return $m;
+ }
+ }
+
+ #if still not known, use getimagesize to find out the type of image
+ #TODO: skip things that do not have a well-known image extension? Would that be safe?
+ wfSuppressWarnings();
+ $gis = getimagesize( $file );
+ wfRestoreWarnings();
+
+ $notAnImage= false;
+
+ if ($gis && is_array($gis) && $gis[2]) {
+ switch ($gis[2]) {
+ case IMAGETYPE_GIF: $m= "image/gif"; break;
+ case IMAGETYPE_JPEG: $m= "image/jpeg"; break;
+ case IMAGETYPE_PNG: $m= "image/png"; break;
+ case IMAGETYPE_SWF: $m= "application/x-shockwave-flash"; break;
+ case IMAGETYPE_PSD: $m= "application/photoshop"; break;
+ case IMAGETYPE_BMP: $m= "image/bmp"; break;
+ case IMAGETYPE_TIFF_II: $m= "image/tiff"; break;
+ case IMAGETYPE_TIFF_MM: $m= "image/tiff"; break;
+ case IMAGETYPE_JPC: $m= "image"; break;
+ case IMAGETYPE_JP2: $m= "image/jpeg2000"; break;
+ case IMAGETYPE_JPX: $m= "image/jpeg2000"; break;
+ case IMAGETYPE_JB2: $m= "image"; break;
+ case IMAGETYPE_SWC: $m= "application/x-shockwave-flash"; break;
+ case IMAGETYPE_IFF: $m= "image/vnd.xiff"; break;
+ case IMAGETYPE_WBMP: $m= "image/vnd.wap.wbmp"; break;
+ case IMAGETYPE_XBM: $m= "image/x-xbitmap"; break;
+ }
+
+ if ($m) {
+ wfDebug("$fname: image mime type of $file: $m\n");
+ return $m;
+ }
+ else $notAnImage= true;
+ } else {
+ // Also test DjVu
+ $deja = new DjVuImage( $file );
+ if( $deja->isValid() ) {
+ wfDebug("$fname: detected $file as image/vnd.djvu\n");
+ return 'image/vnd.djvu';
+ }
+ }
+
+ #if desired, look at extension as a fallback.
+ if ($useExt) {
+ $i = strrpos( $file, '.' );
+ $e= strtolower( $i ? substr( $file, $i + 1 ) : '' );
+
+ $m= $this->guessTypesForExtension($e);
+
+ #TODO: if $notAnImage is set, do not trust the file extension if
+ # the results is one of the image types that should have been recognized
+ # by getimagesize
+
+ if ($m) {
+ wfDebug("$fname: extension mime type of $file: $m\n");
+ return $m;
+ }
+ }
+
+ #unknown type
+ wfDebug("$fname: failed to guess mime type for $file!\n");
+ return "unknown/unknown";
+ }
+
+ /**
+ * Determine the media type code for a file, using its mime type, name and possibly
+ * its contents.
+ *
+ * This function relies on the findMediaType(), mapping extensions and mime
+ * types to media types.
+ *
+ * @todo analyse file if need be
+ * @todo look at multiple extension, separately and together.
+ *
+ * @param string $path full path to the image file, in case we have to look at the contents
+ * (if null, only the mime type is used to determine the media type code).
+ * @param string $mime mime type. If null it will be guessed using guessMimeType.
+ *
+ * @return (int?string?) a value to be used with the MEDIATYPE_xxx constants.
+ */
+ function getMediaType($path=NULL,$mime=NULL) {
+ if( !$mime && !$path ) return MEDIATYPE_UNKNOWN;
+
+ #if mime type is unknown, guess it
+ if( !$mime ) $mime= $this->guessMimeType($path,false);
+
+ #special code for ogg - detect if it's video (theora),
+ #else label it as sound.
+ if( $mime=="application/ogg" && file_exists($path) ) {
+
+ // Read a chunk of the file
+ $f = fopen( $path, "rt" );
+ if( !$f ) return MEDIATYPE_UNKNOWN;
+ $head = fread( $f, 256 );
+ fclose( $f );
+
+ $head= strtolower( $head );
+
+ #This is an UGLY HACK, file should be parsed correctly
+ if( strpos($head,'theora')!==false ) return MEDIATYPE_VIDEO;
+ elseif( strpos($head,'vorbis')!==false ) return MEDIATYPE_AUDIO;
+ elseif( strpos($head,'flac')!==false ) return MEDIATYPE_AUDIO;
+ elseif( strpos($head,'speex')!==false ) return MEDIATYPE_AUDIO;
+ else return MEDIATYPE_MULTIMEDIA;
+ }
+
+ #check for entry for full mime type
+ if( $mime ) {
+ $type= $this->findMediaType($mime);
+ if( $type!==MEDIATYPE_UNKNOWN ) return $type;
+ }
+
+ #check for entry for file extension
+ $e= NULL;
+ if( $path ) {
+ $i = strrpos( $path, '.' );
+ $e= strtolower( $i ? substr( $path, $i + 1 ) : '' );
+
+ #TODO: look at multi-extension if this fails, parse from full path
+
+ $type= $this->findMediaType('.'.$e);
+ if( $type!==MEDIATYPE_UNKNOWN ) return $type;
+ }
+
+ #check major mime type
+ if( $mime ) {
+ $i= strpos($mime,'/');
+ if( $i !== false ) {
+ $major= substr($mime,0,$i);
+ $type= $this->findMediaType($major);
+ if( $type!==MEDIATYPE_UNKNOWN ) return $type;
+ }
+ }
+
+ if( !$type ) $type= MEDIATYPE_UNKNOWN;
+
+ return $type;
+ }
+
+ /** returns a media code matching the given mime type or file extension.
+ * File extensions are represented by a string starting with a dot (.) to
+ * distinguish them from mime types.
+ *
+ * This funktion relies on the mapping defined by $this->mMediaTypes
+ * @access private
+ */
+ function findMediaType($extMime) {
+
+ if (strpos($extMime,'.')===0) { #if it's an extension, look up the mime types
+ $m= $this->getTypesForExtension(substr($extMime,1));
+ if (!$m) return MEDIATYPE_UNKNOWN;
+
+ $m= explode(' ',$m);
+ }
+ else { #normalize mime type
+ if (isset($this->mMimeTypeAliases[$extMime])) {
+ $extMime= $this->mMimeTypeAliases[$extMime];
+ }
+
+ $m= array($extMime);
+ }
+
+ foreach ($m as $mime) {
+ foreach ($this->mMediaTypes as $type => $codes) {
+ if (in_array($mime,$codes,true)) return $type;
+ }
+ }
+
+ return MEDIATYPE_UNKNOWN;
+ }
+}
+
+?>
diff --git a/includes/Namespace.php b/includes/Namespace.php
new file mode 100644
index 000000000000..78493902f27b
--- /dev/null
+++ b/includes/Namespace.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Provide things related to namespaces
+ * @package MediaWiki
+ */
+
+/**
+ * Definitions of the NS_ constants are in Defines.php
+ * @private
+ */
+$wgCanonicalNamespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_TALK => 'Talk',
+ NS_USER => 'User',
+ NS_USER_TALK => 'User_talk',
+ NS_PROJECT => 'Project',
+ NS_PROJECT_TALK => 'Project_talk',
+ NS_IMAGE => 'Image',
+ NS_IMAGE_TALK => 'Image_talk',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Template_talk',
+ NS_HELP => 'Help',
+ NS_HELP_TALK => 'Help_talk',
+ NS_CATEGORY => 'Category',
+ NS_CATEGORY_TALK => 'Category_talk',
+);
+
+if( is_array( $wgExtraNamespaces ) ) {
+ $wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces;
+}
+
+/**
+ * This is a utility class with only static functions
+ * for dealing with namespaces that encodes all the
+ * "magic" behaviors of them based on index. The textual
+ * names of the namespaces are handled by Language.php.
+ *
+ * These are synonyms for the names given in the language file
+ * Users and translators should not change them
+ *
+ * @package MediaWiki
+ */
+class Namespace {
+
+ /**
+ * Check if the given namespace might be moved
+ * @return bool
+ */
+ static function isMovable( $index ) {
+ return !( $index < NS_MAIN || $index == NS_IMAGE || $index == NS_CATEGORY );
+ }
+
+ /**
+ * Check if the given namespace is not a talk page
+ * @return bool
+ */
+ static function isMain( $index ) {
+ return ! Namespace::isTalk( $index );
+ }
+
+ /**
+ * Check if the give namespace is a talk page
+ * @return bool
+ */
+ static function isTalk( $index ) {
+ return ($index > NS_MAIN) // Special namespaces are negative
+ && ($index % 2); // Talk namespaces are odd-numbered
+ }
+
+ /**
+ * Get the talk namespace corresponding to the given index
+ */
+ static function getTalk( $index ) {
+ if ( Namespace::isTalk( $index ) ) {
+ return $index;
+ } else {
+ # FIXME
+ return $index + 1;
+ }
+ }
+
+ static function getSubject( $index ) {
+ if ( Namespace::isTalk( $index ) ) {
+ return $index - 1;
+ } else {
+ return $index;
+ }
+ }
+
+ /**
+ * Returns the canonical (English Wikipedia) name for a given index
+ */
+ static function getCanonicalName( $index ) {
+ global $wgCanonicalNamespaceNames;
+ return $wgCanonicalNamespaceNames[$index];
+ }
+
+ /**
+ * Returns the index for a given canonical name, or NULL
+ * The input *must* be converted to lower case first
+ */
+ static function getCanonicalIndex( $name ) {
+ global $wgCanonicalNamespaceNames;
+ static $xNamespaces = false;
+ if ( $xNamespaces === false ) {
+ $xNamespaces = array();
+ foreach ( $wgCanonicalNamespaceNames as $i => $text ) {
+ $xNamespaces[strtolower($text)] = $i;
+ }
+ }
+ if ( array_key_exists( $name, $xNamespaces ) ) {
+ return $xNamespaces[$name];
+ } else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Can this namespace ever have a talk namespace?
+ * @param $index Namespace index
+ */
+ static function canTalk( $index ) {
+ return( $index >= NS_MAIN );
+ }
+}
+?>
diff --git a/includes/ObjectCache.php b/includes/ObjectCache.php
new file mode 100644
index 000000000000..2b26cf4efb58
--- /dev/null
+++ b/includes/ObjectCache.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+
+/**
+ * FakeMemCachedClient imitates the API of memcached-client v. 0.1.2.
+ * It acts as a memcached server with no RAM, that is, all objects are
+ * cleared the moment they are set. All set operations succeed and all
+ * get operations return null.
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+class FakeMemCachedClient {
+ function add ($key, $val, $exp = 0) { return true; }
+ function decr ($key, $amt=1) { return null; }
+ function delete ($key, $time = 0) { return false; }
+ function disconnect_all () { }
+ function enable_compress ($enable) { }
+ function forget_dead_hosts () { }
+ function get ($key) { return null; }
+ function get_multi ($keys) { return array_pad(array(), count($keys), null); }
+ function incr ($key, $amt=1) { return null; }
+ function replace ($key, $value, $exp=0) { return false; }
+ function run_command ($sock, $cmd) { return null; }
+ function set ($key, $value, $exp=0){ return true; }
+ function set_compress_threshold ($thresh){ }
+ function set_debug ($dbg) { }
+ function set_servers ($list) { }
+}
+
+global $wgCaches;
+$wgCaches = array();
+
+/** @todo document */
+function &wfGetCache( $inputType ) {
+ global $wgCaches, $wgMemCachedServers, $wgMemCachedDebug, $wgMemCachedPersistent;
+ $cache = false;
+
+ if ( $inputType == CACHE_ANYTHING ) {
+ reset( $wgCaches );
+ $type = key( $wgCaches );
+ if ( $type === false || $type === CACHE_NONE ) {
+ $type = CACHE_DB;
+ }
+ } else {
+ $type = $inputType;
+ }
+
+ if ( $type == CACHE_MEMCACHED ) {
+ if ( !array_key_exists( CACHE_MEMCACHED, $wgCaches ) ){
+ require_once( 'memcached-client.php' );
+
+ if (!class_exists("MemcachedClientforWiki")) {
+ class MemCachedClientforWiki extends memcached {
+ function _debugprint( $text ) {
+ wfDebug( "memcached: $text\n" );
+ }
+ }
+ }
+
+ $wgCaches[CACHE_DB] = new MemCachedClientforWiki(
+ array('persistant' => $wgMemCachedPersistent, 'compress_threshold' => 1500 ) );
+ $cache =& $wgCaches[CACHE_DB];
+ $cache->set_servers( $wgMemCachedServers );
+ $cache->set_debug( $wgMemCachedDebug );
+ }
+ } elseif ( $type == CACHE_ACCEL ) {
+ if ( !array_key_exists( CACHE_ACCEL, $wgCaches ) ) {
+ if ( function_exists( 'eaccelerator_get' ) ) {
+ $wgCaches[CACHE_ACCEL] = new eAccelBagOStuff;
+ } elseif ( function_exists( 'apc_fetch') ) {
+ $wgCaches[CACHE_ACCEL] = new APCBagOStuff;
+ } elseif ( function_exists( 'mmcache_get' ) ) {
+ $wgCaches[CACHE_ACCEL] = new TurckBagOStuff;
+ } else {
+ $wgCaches[CACHE_ACCEL] = false;
+ }
+ }
+ if ( $wgCaches[CACHE_ACCEL] !== false ) {
+ $cache =& $wgCaches[CACHE_ACCEL];
+ }
+ } elseif ( $type == CACHE_DBA ) {
+ if ( !array_key_exists( CACHE_DBA, $wgCaches ) ) {
+ $wgCaches[CACHE_DBA] = new DBABagOStuff;
+ }
+ $cache =& $wgCaches[CACHE_DBA];
+ }
+
+ if ( $type == CACHE_DB || ( $inputType == CACHE_ANYTHING && $cache === false ) ) {
+ if ( !array_key_exists( CACHE_DB, $wgCaches ) ) {
+ $wgCaches[CACHE_DB] = new MediaWikiBagOStuff('objectcache');
+ }
+ $cache =& $wgCaches[CACHE_DB];
+ }
+
+ if ( $cache === false ) {
+ if ( !array_key_exists( CACHE_NONE, $wgCaches ) ) {
+ $wgCaches[CACHE_NONE] = new FakeMemCachedClient;
+ }
+ $cache =& $wgCaches[CACHE_NONE];
+ }
+
+ return $cache;
+}
+
+function &wfGetMainCache() {
+ global $wgMainCacheType;
+ $ret =& wfGetCache( $wgMainCacheType );
+ return $ret;
+}
+
+function &wfGetMessageCacheStorage() {
+ global $wgMessageCacheType;
+ $ret =& wfGetCache( $wgMessageCacheType );
+ return $ret;
+}
+
+function &wfGetParserCacheStorage() {
+ global $wgParserCacheType;
+ $ret =& wfGetCache( $wgParserCacheType );
+ return $ret;
+}
+
+?>
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
new file mode 100644
index 000000000000..6d3cc0ac8649
--- /dev/null
+++ b/includes/OutputPage.php
@@ -0,0 +1,1164 @@
+<?php
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+/**
+ * @package MediaWiki
+ */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class OutputPage {
+ var $mMetatags, $mKeywords;
+ var $mLinktags, $mPagetitle, $mBodytext, $mDebugtext;
+ var $mHTMLtitle, $mRobotpolicy, $mIsarticle, $mPrintable;
+ var $mSubtitle, $mRedirect, $mStatusCode;
+ var $mLastModified, $mETag, $mCategoryLinks;
+ var $mScripts, $mLinkColours, $mPageLinkTitle;
+
+ var $mSuppressQuickbar;
+ var $mOnloadHandler;
+ var $mDoNothing;
+ var $mContainsOldMagic, $mContainsNewMagic;
+ var $mIsArticleRelated;
+ protected $mParserOptions; // lazy initialised, use parserOptions()
+ var $mShowFeedLinks = false;
+ var $mEnableClientCache = true;
+ var $mArticleBodyOnly = false;
+
+ var $mNewSectionLink = false;
+ var $mNoGallery = false;
+
+ /**
+ * Constructor
+ * Initialise private variables
+ */
+ function OutputPage() {
+ $this->mMetatags = $this->mKeywords = $this->mLinktags = array();
+ $this->mHTMLtitle = $this->mPagetitle = $this->mBodytext =
+ $this->mRedirect = $this->mLastModified =
+ $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy =
+ $this->mOnloadHandler = $this->mPageLinkTitle = '';
+ $this->mIsArticleRelated = $this->mIsarticle = $this->mPrintable = true;
+ $this->mSuppressQuickbar = $this->mPrintable = false;
+ $this->mLanguageLinks = array();
+ $this->mCategoryLinks = array();
+ $this->mDoNothing = false;
+ $this->mContainsOldMagic = $this->mContainsNewMagic = 0;
+ $this->mParserOptions = null;
+ $this->mSquidMaxage = 0;
+ $this->mScripts = '';
+ $this->mETag = false;
+ $this->mRevisionId = null;
+ $this->mNewSectionLink = false;
+ }
+
+ public function redirect( $url, $responsecode = '302' ) {
+ # Strip newlines as a paranoia check for header injection in PHP<5.1.2
+ $this->mRedirect = str_replace( "\n", '', $url );
+ $this->mRedirectCode = $responsecode;
+ }
+
+ /**
+ * Set the HTTP status code to send with the output.
+ *
+ * @param int $statusCode
+ * @return nothing
+ */
+ function setStatusCode( $statusCode ) { $this->mStatusCode = $statusCode; }
+
+ # To add an http-equiv meta tag, precede the name with "http:"
+ function addMeta( $name, $val ) { array_push( $this->mMetatags, array( $name, $val ) ); }
+ function addKeyword( $text ) { array_push( $this->mKeywords, $text ); }
+ function addScript( $script ) { $this->mScripts .= $script; }
+
+ /**
+ * Add a self-contained script tag with the given contents
+ * @param string $script JavaScript text, no <script> tags
+ */
+ function addInlineScript( $script ) {
+ global $wgJsMimeType;
+ $this->mScripts .= "<script type=\"$wgJsMimeType\"><!--\n$script\n--></script>";
+ }
+
+ function getScript() { return $this->mScripts; }
+
+ function setETag($tag) { $this->mETag = $tag; }
+ function setArticleBodyOnly($only) { $this->mArticleBodyOnly = $only; }
+ function getArticleBodyOnly($only) { return $this->mArticleBodyOnly; }
+
+ function addLink( $linkarr ) {
+ # $linkarr should be an associative array of attributes. We'll escape on output.
+ array_push( $this->mLinktags, $linkarr );
+ }
+
+ function addMetadataLink( $linkarr ) {
+ # note: buggy CC software only reads first "meta" link
+ static $haveMeta = false;
+ $linkarr['rel'] = ($haveMeta) ? 'alternate meta' : 'meta';
+ $this->addLink( $linkarr );
+ $haveMeta = true;
+ }
+
+ /**
+ * checkLastModified tells the client to use the client-cached page if
+ * possible. If sucessful, the OutputPage is disabled so that
+ * any future call to OutputPage->output() have no effect.
+ *
+ * @return bool True iff cache-ok headers was sent.
+ */
+ function checkLastModified ( $timestamp ) {
+ global $wgCachePages, $wgCacheEpoch, $wgUser, $wgRequest;
+ $fname = 'OutputPage::checkLastModified';
+
+ if ( !$timestamp || $timestamp == '19700101000000' ) {
+ wfDebug( "$fname: CACHE DISABLED, NO TIMESTAMP\n" );
+ return;
+ }
+ if( !$wgCachePages ) {
+ wfDebug( "$fname: CACHE DISABLED\n", false );
+ return;
+ }
+ if( $wgUser->getOption( 'nocache' ) ) {
+ wfDebug( "$fname: USER DISABLED CACHE\n", false );
+ return;
+ }
+
+ $timestamp=wfTimestamp(TS_MW,$timestamp);
+ $lastmod = wfTimestamp( TS_RFC2822, max( $timestamp, $wgUser->mTouched, $wgCacheEpoch ) );
+
+ if( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
+ # IE sends sizes after the date like this:
+ # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
+ # this breaks strtotime().
+ $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
+ $modsinceTime = strtotime( $modsince );
+ $ismodsince = wfTimestamp( TS_MW, $modsinceTime ? $modsinceTime : 1 );
+ wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", false );
+ wfDebug( "$fname: -- we might send Last-Modified : $lastmod\n", false );
+ if( ($ismodsince >= $timestamp ) && $wgUser->validateCache( $ismodsince ) && $ismodsince >= $wgCacheEpoch ) {
+ # Make sure you're in a place you can leave when you call us!
+ $wgRequest->response()->header( "HTTP/1.0 304 Not Modified" );
+ $this->mLastModified = $lastmod;
+ $this->sendCacheControl();
+ wfDebug( "$fname: CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp ; site $wgCacheEpoch\n", false );
+ $this->disable();
+
+ // Don't output a compressed blob when using ob_gzhandler;
+ // it's technically against HTTP spec and seems to confuse
+ // Firefox when the response gets split over two packets.
+ wfClearOutputBuffers();
+
+ return true;
+ } else {
+ wfDebug( "$fname: READY client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp ; site $wgCacheEpoch\n", false );
+ $this->mLastModified = $lastmod;
+ }
+ } else {
+ wfDebug( "$fname: client did not send If-Modified-Since header\n", false );
+ $this->mLastModified = $lastmod;
+ }
+ }
+
+ function getPageTitleActionText () {
+ global $action;
+ switch($action) {
+ case 'edit':
+ case 'delete':
+ case 'protect':
+ case 'unprotect':
+ case 'watch':
+ case 'unwatch':
+ // Display title is already customized
+ return '';
+ case 'history':
+ return wfMsg('history_short');
+ case 'submit':
+ // FIXME: bug 2735; not correct for special pages etc
+ return wfMsg('preview');
+ case 'info':
+ return wfMsg('info_short');
+ default:
+ return '';
+ }
+ }
+
+ public function setRobotpolicy( $str ) { $this->mRobotpolicy = $str; }
+ public function setHTMLTitle( $name ) {$this->mHTMLtitle = $name; }
+ public function setPageTitle( $name ) {
+ global $action, $wgContLang;
+ $name = $wgContLang->convert($name, true);
+ $this->mPagetitle = $name;
+ if(!empty($action)) {
+ $taction = $this->getPageTitleActionText();
+ if( !empty( $taction ) ) {
+ $name .= ' - '.$taction;
+ }
+ }
+
+ $this->setHTMLTitle( wfMsg( 'pagetitle', $name ) );
+ }
+ public function getHTMLTitle() { return $this->mHTMLtitle; }
+ public function getPageTitle() { return $this->mPagetitle; }
+ public function setSubtitle( $str ) { $this->mSubtitle = /*$this->parse(*/$str/*)*/; } // @bug 2514
+ public function getSubtitle() { return $this->mSubtitle; }
+ public function isArticle() { return $this->mIsarticle; }
+ public function setPrintable() { $this->mPrintable = true; }
+ public function isPrintable() { return $this->mPrintable; }
+ public function setSyndicated( $show = true ) { $this->mShowFeedLinks = $show; }
+ public function isSyndicated() { return $this->mShowFeedLinks; }
+ public function setOnloadHandler( $js ) { $this->mOnloadHandler = $js; }
+ public function getOnloadHandler() { return $this->mOnloadHandler; }
+ public function disable() { $this->mDoNothing = true; }
+
+ public function setArticleRelated( $v ) {
+ $this->mIsArticleRelated = $v;
+ if ( !$v ) {
+ $this->mIsarticle = false;
+ }
+ }
+ public function setArticleFlag( $v ) {
+ $this->mIsarticle = $v;
+ if ( $v ) {
+ $this->mIsArticleRelated = $v;
+ }
+ }
+
+ public function isArticleRelated() { return $this->mIsArticleRelated; }
+
+ public function getLanguageLinks() { return $this->mLanguageLinks; }
+ public function addLanguageLinks($newLinkArray) {
+ $this->mLanguageLinks += $newLinkArray;
+ }
+ public function setLanguageLinks($newLinkArray) {
+ $this->mLanguageLinks = $newLinkArray;
+ }
+
+ public function getCategoryLinks() {
+ return $this->mCategoryLinks;
+ }
+
+ /**
+ * Add an array of categories, with names in the keys
+ */
+ public function addCategoryLinks($categories) {
+ global $wgUser, $wgContLang;
+
+ if ( !is_array( $categories ) ) {
+ return;
+ }
+ # Add the links to the link cache in a batch
+ $arr = array( NS_CATEGORY => $categories );
+ $lb = new LinkBatch;
+ $lb->setArray( $arr );
+ $lb->execute();
+
+ $sk =& $wgUser->getSkin();
+ foreach ( $categories as $category => $unused ) {
+ $title = Title::makeTitleSafe( NS_CATEGORY, $category );
+ $text = $wgContLang->convertHtml( $title->getText() );
+ $this->mCategoryLinks[] = $sk->makeLinkObj( $title, $text );
+ }
+ }
+
+ public function setCategoryLinks($categories) {
+ $this->mCategoryLinks = array();
+ $this->addCategoryLinks($categories);
+ }
+
+ public function suppressQuickbar() { $this->mSuppressQuickbar = true; }
+ public function isQuickbarSuppressed() { return $this->mSuppressQuickbar; }
+
+ public function addHTML( $text ) { $this->mBodytext .= $text; }
+ public function clearHTML() { $this->mBodytext = ''; }
+ public function getHTML() { return $this->mBodytext; }
+ public function debug( $text ) { $this->mDebugtext .= $text; }
+
+ /* @deprecated */
+ public function setParserOptions( $options ) {
+ return $this->parserOptions( $options );
+ }
+
+ public function parserOptions( $options = null ) {
+ if ( !$this->mParserOptions ) {
+ $this->mParserOptions = new ParserOptions;
+ }
+ return wfSetVar( $this->mParserOptions, $options );
+ }
+
+ /**
+ * Set the revision ID which will be seen by the wiki text parser
+ * for things such as embedded {{REVISIONID}} variable use.
+ * @param mixed $revid an integer, or NULL
+ * @return mixed previous value
+ */
+ public function setRevisionId( $revid ) {
+ $val = is_null( $revid ) ? null : intval( $revid );
+ return wfSetVar( $this->mRevisionId, $val );
+ }
+
+ /**
+ * Convert wikitext to HTML and add it to the buffer
+ * Default assumes that the current page title will
+ * be used.
+ *
+ * @param string $text
+ * @param bool $linestart
+ */
+ public function addWikiText( $text, $linestart = true ) {
+ global $wgTitle;
+ $this->addWikiTextTitle($text, $wgTitle, $linestart);
+ }
+
+ public function addWikiTextWithTitle($text, &$title, $linestart = true) {
+ $this->addWikiTextTitle($text, $title, $linestart);
+ }
+
+ private function addWikiTextTitle($text, &$title, $linestart) {
+ global $wgParser;
+ $fname = 'OutputPage:addWikiTextTitle';
+ wfProfileIn($fname);
+ wfIncrStats('pcache_not_possible');
+ $parserOutput = $wgParser->parse( $text, $title, $this->parserOptions(),
+ $linestart, true, $this->mRevisionId );
+ $this->addParserOutput( $parserOutput );
+ wfProfileOut($fname);
+ }
+
+ /**
+ * @todo document
+ * @param ParserOutput object &$parserOutput
+ */
+ public function addParserOutputNoText( &$parserOutput ) {
+ $this->mLanguageLinks += $parserOutput->getLanguageLinks();
+ $this->addCategoryLinks( $parserOutput->getCategories() );
+ $this->mNewSectionLink = $parserOutput->getNewSection();
+ $this->addKeywords( $parserOutput );
+ if ( $parserOutput->getCacheTime() == -1 ) {
+ $this->enableClientCache( false );
+ }
+ if ( $parserOutput->mHTMLtitle != "" ) {
+ $this->mPagetitle = $parserOutput->mHTMLtitle ;
+ }
+ if ( $parserOutput->mSubtitle != '' ) {
+ $this->mSubtitle .= $parserOutput->mSubtitle ;
+ }
+ $this->mNoGallery = $parserOutput->getNoGallery();
+ wfRunHooks( 'OutputPageParserOutput', array( &$this, $parserOutput ) );
+ }
+
+ /**
+ * @todo document
+ * @param ParserOutput &$parserOutput
+ */
+ function addParserOutput( &$parserOutput ) {
+ $this->addParserOutputNoText( $parserOutput );
+ $text = $parserOutput->getText();
+ wfRunHooks( 'OutputPageBeforeHTML',array( &$this, &$text ) );
+ $this->addHTML( $text );
+ }
+
+ /**
+ * Add wikitext to the buffer, assuming that this is the primary text for a page view
+ * Saves the text into the parser cache if possible.
+ *
+ * @param string $text
+ * @param Article $article
+ * @param bool $cache
+ */
+ public function addPrimaryWikiText( $text, $article, $cache = true ) {
+ global $wgParser, $wgUser;
+
+ $popts = $this->parserOptions();
+ $popts->setTidy(true);
+ $parserOutput = $wgParser->parse( $text, $article->mTitle,
+ $popts, true, true, $this->mRevisionId );
+ $popts->setTidy(false);
+ if ( $cache && $article && $parserOutput->getCacheTime() != -1 ) {
+ $parserCache =& ParserCache::singleton();
+ $parserCache->save( $parserOutput, $article, $wgUser );
+ }
+
+ $this->addParserOutput( $parserOutput );
+ }
+
+ /**
+ * For anything that isn't primary text or interface message
+ *
+ * @param string $text
+ * @param bool $linestart Is this the start of a line?
+ */
+ public function addSecondaryWikiText( $text, $linestart = true ) {
+ global $wgTitle;
+ $popts = $this->parserOptions();
+ $popts->setTidy(true);
+ $this->addWikiTextTitle($text, $wgTitle, $linestart);
+ $popts->setTidy(false);
+ }
+
+
+ /**
+ * Add the output of a QuickTemplate to the output buffer
+ *
+ * @param QuickTemplate $template
+ */
+ public function addTemplate( &$template ) {
+ ob_start();
+ $template->execute();
+ $this->addHTML( ob_get_contents() );
+ ob_end_clean();
+ }
+
+ /**
+ * Parse wikitext and return the HTML.
+ *
+ * @param string $text
+ * @param bool $linestart Is this the start of a line?
+ * @param bool $interface ??
+ */
+ public function parse( $text, $linestart = true, $interface = false ) {
+ global $wgParser, $wgTitle;
+ $popts = $this->parserOptions();
+ if ( $interface) { $popts->setInterfaceMessage(true); }
+ $parserOutput = $wgParser->parse( $text, $wgTitle, $popts,
+ $linestart, true, $this->mRevisionId );
+ if ( $interface) { $popts->setInterfaceMessage(false); }
+ return $parserOutput->getText();
+ }
+
+ /**
+ * @param Article $article
+ * @param User $user
+ *
+ * @return bool True if successful, else false.
+ */
+ public function tryParserCache( &$article, $user ) {
+ $parserCache =& ParserCache::singleton();
+ $parserOutput = $parserCache->get( $article, $user );
+ if ( $parserOutput !== false ) {
+ $this->addParserOutput( $parserOutput );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param int $maxage Maximum cache time on the Squid, in seconds.
+ */
+ public function setSquidMaxage( $maxage ) {
+ $this->mSquidMaxage = $maxage;
+ }
+
+ /**
+ * Use enableClientCache(false) to force it to send nocache headers
+ * @param $state ??
+ */
+ public function enableClientCache( $state ) {
+ return wfSetVar( $this->mEnableClientCache, $state );
+ }
+
+ function uncacheableBecauseRequestvars() {
+ global $wgRequest;
+ return $wgRequest->getText('useskin', false) === false
+ && $wgRequest->getText('uselang', false) === false;
+ }
+
+ public function sendCacheControl() {
+ global $wgUseSquid, $wgUseESI, $wgUseETag, $wgSquidMaxage, $wgRequest;
+ $fname = 'OutputPage::sendCacheControl';
+
+ if ($wgUseETag && $this->mETag)
+ $wgRequest->response()->header("ETag: $this->mETag");
+
+ # don't serve compressed data to clients who can't handle it
+ # maintain different caches for logged-in users and non-logged in ones
+ $wgRequest->response()->header( 'Vary: Accept-Encoding, Cookie' );
+ if( !$this->uncacheableBecauseRequestvars() && $this->mEnableClientCache ) {
+ if( $wgUseSquid && ! isset( $_COOKIE[ini_get( 'session.name') ] ) &&
+ ! $this->isPrintable() && $this->mSquidMaxage != 0 )
+ {
+ if ( $wgUseESI ) {
+ # We'll purge the proxy cache explicitly, but require end user agents
+ # to revalidate against the proxy on each visit.
+ # Surrogate-Control controls our Squid, Cache-Control downstream caches
+ wfDebug( "$fname: proxy caching with ESI; {$this->mLastModified} **\n", false );
+ # start with a shorter timeout for initial testing
+ # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
+ $wgRequest->response()->header( 'Surrogate-Control: max-age='.$wgSquidMaxage.'+'.$this->mSquidMaxage.', content="ESI/1.0"');
+ $wgRequest->response()->header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
+ } else {
+ # We'll purge the proxy cache for anons explicitly, but require end user agents
+ # to revalidate against the proxy on each visit.
+ # IMPORTANT! The Squid needs to replace the Cache-Control header with
+ # Cache-Control: s-maxage=0, must-revalidate, max-age=0
+ wfDebug( "$fname: local proxy caching; {$this->mLastModified} **\n", false );
+ # start with a shorter timeout for initial testing
+ # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
+ $wgRequest->response()->header( 'Cache-Control: s-maxage='.$this->mSquidMaxage.', must-revalidate, max-age=0' );
+ }
+ } else {
+ # We do want clients to cache if they can, but they *must* check for updates
+ # on revisiting the page.
+ wfDebug( "$fname: private caching; {$this->mLastModified} **\n", false );
+ $wgRequest->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
+ $wgRequest->response()->header( "Cache-Control: private, must-revalidate, max-age=0" );
+ }
+ if($this->mLastModified) $wgRequest->response()->header( "Last-modified: {$this->mLastModified}" );
+ } else {
+ wfDebug( "$fname: no caching **\n", false );
+
+ # In general, the absence of a last modified header should be enough to prevent
+ # the client from using its cache. We send a few other things just to make sure.
+ $wgRequest->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
+ $wgRequest->response()->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
+ $wgRequest->response()->header( 'Pragma: no-cache' );
+ }
+ }
+
+ /**
+ * Finally, all the text has been munged and accumulated into
+ * the object, let's actually output it:
+ */
+ public function output() {
+ global $wgUser, $wgOutputEncoding, $wgRequest;
+ global $wgContLanguageCode, $wgDebugRedirects, $wgMimeType;
+ global $wgJsMimeType, $wgStylePath, $wgUseAjax, $wgAjaxSearch, $wgAjaxWatch;
+ global $wgServer, $wgStyleVersion;
+
+ if( $this->mDoNothing ){
+ return;
+ }
+ $fname = 'OutputPage::output';
+ wfProfileIn( $fname );
+ $sk = $wgUser->getSkin();
+
+ if ( $wgUseAjax ) {
+ $this->addScript( "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/ajax.js?$wgStyleVersion\"></script>\n" );
+ if( $wgAjaxSearch ) {
+ $this->addScript( "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/ajaxsearch.js\"></script>\n" );
+ $this->addScript( "<script type=\"{$wgJsMimeType}\">hookEvent(\"load\", sajax_onload);</script>\n" );
+ }
+
+ if( $wgAjaxWatch && $wgUser->isLoggedIn() ) {
+ $this->addScript( "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/ajaxwatch.js\"></script>\n" );
+ }
+ }
+
+ if ( '' != $this->mRedirect ) {
+ if( substr( $this->mRedirect, 0, 4 ) != 'http' ) {
+ # Standards require redirect URLs to be absolute
+ global $wgServer;
+ $this->mRedirect = $wgServer . $this->mRedirect;
+ }
+ if( $this->mRedirectCode == '301') {
+ if( !$wgDebugRedirects ) {
+ $wgRequest->response()->header("HTTP/1.1 {$this->mRedirectCode} Moved Permanently");
+ }
+ $this->mLastModified = wfTimestamp( TS_RFC2822 );
+ }
+
+ $this->sendCacheControl();
+
+ $wgRequest->response()->header("Content-Type: text/html; charset=utf-8");
+ if( $wgDebugRedirects ) {
+ $url = htmlspecialchars( $this->mRedirect );
+ print "<html>\n<head>\n<title>Redirect</title>\n</head>\n<body>\n";
+ print "<p>Location: <a href=\"$url\">$url</a></p>\n";
+ print "</body>\n</html>\n";
+ } else {
+ $wgRequest->response()->header( 'Location: '.$this->mRedirect );
+ }
+ wfProfileOut( $fname );
+ return;
+ }
+ elseif ( $this->mStatusCode )
+ {
+ $statusMessage = array(
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+ 102 => 'Processing',
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 207 => 'Multi-Status',
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Large',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Request Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+ 422 => 'Unprocessable Entity',
+ 423 => 'Locked',
+ 424 => 'Failed Dependency',
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 507 => 'Insufficient Storage'
+ );
+
+ if ( $statusMessage[$this->mStatusCode] )
+ $wgRequest->response()->header( 'HTTP/1.1 ' . $this->mStatusCode . ' ' . $statusMessage[$this->mStatusCode] );
+ }
+
+ # Buffer output; final headers may depend on later processing
+ ob_start();
+
+ # Disable temporary placeholders, so that the skin produces HTML
+ $sk->postParseLinkColour( false );
+
+ $wgRequest->response()->header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" );
+ $wgRequest->response()->header( 'Content-language: '.$wgContLanguageCode );
+
+ if ($this->mArticleBodyOnly) {
+ $this->out($this->mBodytext);
+ } else {
+ wfProfileIn( 'Output-skin' );
+ $sk->outputPage( $this );
+ wfProfileOut( 'Output-skin' );
+ }
+
+ $this->sendCacheControl();
+ ob_end_flush();
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * @todo document
+ * @param string $ins
+ */
+ public function out( $ins ) {
+ global $wgInputEncoding, $wgOutputEncoding, $wgContLang;
+ if ( 0 == strcmp( $wgInputEncoding, $wgOutputEncoding ) ) {
+ $outs = $ins;
+ } else {
+ $outs = $wgContLang->iconv( $wgInputEncoding, $wgOutputEncoding, $ins );
+ if ( false === $outs ) { $outs = $ins; }
+ }
+ print $outs;
+ }
+
+ /**
+ * @todo document
+ */
+ public static function setEncodings() {
+ global $wgInputEncoding, $wgOutputEncoding;
+ global $wgUser, $wgContLang;
+
+ $wgInputEncoding = strtolower( $wgInputEncoding );
+
+ if ( empty( $_SERVER['HTTP_ACCEPT_CHARSET'] ) ) {
+ $wgOutputEncoding = strtolower( $wgOutputEncoding );
+ return;
+ }
+ $wgOutputEncoding = $wgInputEncoding;
+ }
+
+ /**
+ * Deprecated, use wfReportTime() instead.
+ * @return string
+ * @deprecated
+ */
+ public function reportTime() {
+ $time = wfReportTime();
+ return $time;
+ }
+
+ /**
+ * Produce a "user is blocked" page.
+ *
+ * @param bool $return Whether to have a "return to $wgTitle" message or not.
+ * @return nothing
+ */
+ function blockedPage( $return = true ) {
+ global $wgUser, $wgContLang, $wgTitle;
+
+ $this->setPageTitle( wfMsg( 'blockedtitle' ) );
+ $this->setRobotpolicy( 'noindex,nofollow' );
+ $this->setArticleRelated( false );
+
+ $id = $wgUser->blockedBy();
+ $reason = $wgUser->blockedFor();
+ $ip = wfGetIP();
+
+ if ( is_numeric( $id ) ) {
+ $name = User::whoIs( $id );
+ } else {
+ $name = $id;
+ }
+ $link = '[[' . $wgContLang->getNsText( NS_USER ) . ":{$name}|{$name}]]";
+
+ $blockid = $wgUser->mBlock->mId;
+
+ $this->addWikiText( wfMsg( 'blockedtext', $link, $reason, $ip, $name, $blockid ) );
+
+ # Don't auto-return to special pages
+ if( $return ) {
+ $return = $wgTitle->getNamespace() > -1 ? $wgTitle->getPrefixedText() : NULL;
+ $this->returnToMain( false, $return );
+ }
+ }
+
+ /**
+ * Outputs a pretty page to explain why the request exploded.
+ *
+ * @param string $title Message key for page title.
+ * @param string $msg Message key for page text.
+ * @return nothing
+ */
+ public function showErrorPage( $title, $msg ) {
+ global $wgTitle;
+
+ $this->mDebugtext .= 'Original title: ' .
+ $wgTitle->getPrefixedText() . "\n";
+ $this->setPageTitle( wfMsg( $title ) );
+ $this->setHTMLTitle( wfMsg( 'errorpagetitle' ) );
+ $this->setRobotpolicy( 'noindex,nofollow' );
+ $this->setArticleRelated( false );
+ $this->enableClientCache( false );
+ $this->mRedirect = '';
+
+ $this->mBodytext = '';
+ $this->addWikiText( wfMsg( $msg ) );
+ $this->returnToMain( false );
+ }
+
+ /** @obsolete */
+ public function errorpage( $title, $msg ) {
+ throw new ErrorPageError( $title, $msg );
+ }
+
+ /**
+ * Display an error page indicating that a given version of MediaWiki is
+ * required to use it
+ *
+ * @param mixed $version The version of MediaWiki needed to use the page
+ */
+ public function versionRequired( $version ) {
+ $this->setPageTitle( wfMsg( 'versionrequired', $version ) );
+ $this->setHTMLTitle( wfMsg( 'versionrequired', $version ) );
+ $this->setRobotpolicy( 'noindex,nofollow' );
+ $this->setArticleRelated( false );
+ $this->mBodytext = '';
+
+ $this->addWikiText( wfMsg( 'versionrequiredtext', $version ) );
+ $this->returnToMain();
+ }
+
+ /**
+ * Display an error page noting that a given permission bit is required.
+ *
+ * @param string $permission key required
+ */
+ public function permissionRequired( $permission ) {
+ global $wgGroupPermissions, $wgUser;
+
+ $this->setPageTitle( wfMsg( 'badaccess' ) );
+ $this->setHTMLTitle( wfMsg( 'errorpagetitle' ) );
+ $this->setRobotpolicy( 'noindex,nofollow' );
+ $this->setArticleRelated( false );
+ $this->mBodytext = '';
+
+ $groups = array();
+ foreach( $wgGroupPermissions as $key => $value ) {
+ if( isset( $value[$permission] ) && $value[$permission] == true ) {
+ $groupName = User::getGroupName( $key );
+ $groupPage = User::getGroupPage( $key );
+ if( $groupPage ) {
+ $skin =& $wgUser->getSkin();
+ $groups[] = '"'.$skin->makeLinkObj( $groupPage, $groupName ).'"';
+ } else {
+ $groups[] = '"'.$groupName.'"';
+ }
+ }
+ }
+ $n = count( $groups );
+ $groups = implode( ', ', $groups );
+ switch( $n ) {
+ case 0:
+ case 1:
+ case 2:
+ $message = wfMsgHtml( "badaccess-group$n", $groups );
+ break;
+ default:
+ $message = wfMsgHtml( 'badaccess-groups', $groups );
+ }
+ $this->addHtml( $message );
+ $this->returnToMain( false );
+ }
+
+ /**
+ * Use permissionRequired.
+ * @deprecated
+ */
+ public function sysopRequired() {
+ throw new MWException( "Call to deprecated OutputPage::sysopRequired() method\n" );
+ }
+
+ /**
+ * Use permissionRequired.
+ * @deprecated
+ */
+ public function developerRequired() {
+ throw new MWException( "Call to deprecated OutputPage::developerRequired() method\n" );
+ }
+
+ /**
+ * Produce the stock "please login to use the wiki" page
+ */
+ public function loginToUse() {
+ global $wgUser, $wgTitle, $wgContLang;
+
+ if( $wgUser->isLoggedIn() ) {
+ $this->permissionRequired( 'read' );
+ return;
+ }
+
+ $skin = $wgUser->getSkin();
+
+ $this->setPageTitle( wfMsg( 'loginreqtitle' ) );
+ $this->setHtmlTitle( wfMsg( 'errorpagetitle' ) );
+ $this->setRobotPolicy( 'noindex,nofollow' );
+ $this->setArticleFlag( false );
+
+ $loginTitle = SpecialPage::getTitleFor( 'Userlogin' );
+ $loginLink = $skin->makeKnownLinkObj( $loginTitle, wfMsgHtml( 'loginreqlink' ), 'returnto=' . $wgTitle->getPrefixedUrl() );
+ $this->addHtml( wfMsgWikiHtml( 'loginreqpagetext', $loginLink ) );
+ $this->addHtml( "\n<!--" . $wgTitle->getPrefixedUrl() . "-->" );
+
+ # Don't return to the main page if the user can't read it
+ # otherwise we'll end up in a pointless loop
+ $mainPage = Title::newMainPage();
+ if( $mainPage->userCanRead() )
+ $this->returnToMain( true, $mainPage );
+ }
+
+ /** @obsolete */
+ public function databaseError( $fname, $sql, $error, $errno ) {
+ throw new MWException( "OutputPage::databaseError is obsolete\n" );
+ }
+
+ /**
+ * @todo document
+ * @param bool $protected Is the reason the page can't be reached because it's protected?
+ * @param mixed $source
+ */
+ public function readOnlyPage( $source = null, $protected = false ) {
+ global $wgUser, $wgReadOnlyFile, $wgReadOnly, $wgTitle;
+ $skin = $wgUser->getSkin();
+
+ $this->setRobotpolicy( 'noindex,nofollow' );
+ $this->setArticleRelated( false );
+
+ if( $protected ) {
+ $this->setPageTitle( wfMsg( 'viewsource' ) );
+ $this->setSubtitle( wfMsg( 'viewsourcefor', $skin->makeKnownLinkObj( $wgTitle ) ) );
+
+ # Determine if protection is due to the page being a system message
+ # and show an appropriate explanation
+ if( $wgTitle->getNamespace() == NS_MEDIAWIKI && !$wgUser->isAllowed( 'editinterface' ) ) {
+ $this->addWikiText( wfMsg( 'protectedinterface' ) );
+ } else {
+ $this->addWikiText( wfMsg( 'protectedpagetext' ) );
+ }
+ } else {
+ $this->setPageTitle( wfMsg( 'readonly' ) );
+ if ( $wgReadOnly ) {
+ $reason = $wgReadOnly;
+ } else {
+ $reason = file_get_contents( $wgReadOnlyFile );
+ }
+ $this->addWikiText( wfMsg( 'readonlytext', $reason ) );
+ }
+
+ if( is_string( $source ) ) {
+ $this->addWikiText( wfMsg( 'viewsourcetext' ) );
+ if( $source === '' ) {
+ global $wgTitle;
+ if ( $wgTitle->getNamespace() == NS_MEDIAWIKI ) {
+ $source = wfMsgWeirdKey ( $wgTitle->getText() );
+ } else {
+ $source = '';
+ }
+ }
+ $rows = $wgUser->getIntOption( 'rows' );
+ $cols = $wgUser->getIntOption( 'cols' );
+
+ $text = "\n<textarea name='wpTextbox1' id='wpTextbox1' cols='$cols' rows='$rows' readonly='readonly'>" .
+ htmlspecialchars( $source ) . "\n</textarea>";
+ $this->addHTML( $text );
+ }
+ $article = new Article($wgTitle);
+ $this->addHTML( $skin->formatTemplates($article->getUsedTemplates()) );
+
+ $this->returnToMain( false );
+ }
+
+ /** @obsolete */
+ public function fatalError( $message ) {
+ throw new FatalError( $message );
+ }
+
+ /** @obsolete */
+ public function unexpectedValueError( $name, $val ) {
+ throw new FatalError( wfMsg( 'unexpected', $name, $val ) );
+ }
+
+ /** @obsolete */
+ public function fileCopyError( $old, $new ) {
+ throw new FatalError( wfMsg( 'filecopyerror', $old, $new ) );
+ }
+
+ /** @obsolete */
+ public function fileRenameError( $old, $new ) {
+ throw new FatalError( wfMsg( 'filerenameerror', $old, $new ) );
+ }
+
+ /** @obsolete */
+ public function fileDeleteError( $name ) {
+ throw new FatalError( wfMsg( 'filedeleteerror', $name ) );
+ }
+
+ /** @obsolete */
+ public function fileNotFoundError( $name ) {
+ throw new FatalError( wfMsg( 'filenotfound', $name ) );
+ }
+
+ public function showFatalError( $message ) {
+ $this->setPageTitle( wfMsg( "internalerror" ) );
+ $this->setRobotpolicy( "noindex,nofollow" );
+ $this->setArticleRelated( false );
+ $this->enableClientCache( false );
+ $this->mRedirect = '';
+ $this->mBodytext = $message;
+ }
+
+ public function showUnexpectedValueError( $name, $val ) {
+ $this->showFatalError( wfMsg( 'unexpected', $name, $val ) );
+ }
+
+ public function showFileCopyError( $old, $new ) {
+ $this->showFatalError( wfMsg( 'filecopyerror', $old, $new ) );
+ }
+
+ public function showFileRenameError( $old, $new ) {
+ $this->showFatalError( wfMsg( 'filerenameerror', $old, $new ) );
+ }
+
+ public function showFileDeleteError( $name ) {
+ $this->showFatalError( wfMsg( 'filedeleteerror', $name ) );
+ }
+
+ public function showFileNotFoundError( $name ) {
+ $this->showFatalError( wfMsg( 'filenotfound', $name ) );
+ }
+
+ /**
+ * return from error messages or notes
+ * @param $auto automatically redirect the user after 10 seconds
+ * @param $returnto page title to return to. Default is Main Page.
+ */
+ public function returnToMain( $auto = true, $returnto = NULL ) {
+ global $wgUser, $wgOut, $wgRequest;
+
+ if ( $returnto == NULL ) {
+ $returnto = $wgRequest->getText( 'returnto' );
+ }
+
+ if ( '' === $returnto ) {
+ $returnto = Title::newMainPage();
+ }
+
+ if ( is_object( $returnto ) ) {
+ $titleObj = $returnto;
+ } else {
+ $titleObj = Title::newFromText( $returnto );
+ }
+ if ( !is_object( $titleObj ) ) {
+ $titleObj = Title::newMainPage();
+ }
+
+ $sk = $wgUser->getSkin();
+ $link = $sk->makeLinkObj( $titleObj, '' );
+
+ $r = wfMsg( 'returnto', $link );
+ if ( $auto ) {
+ $wgOut->addMeta( 'http:Refresh', '10;url=' . $titleObj->escapeFullURL() );
+ }
+ $wgOut->addHTML( "\n<p>$r</p>\n" );
+ }
+
+ /**
+ * This function takes the title (first item of mGoodLinks), categories, existing and broken links for the page
+ * and uses the first 10 of them for META keywords
+ *
+ * @param ParserOutput &$parserOutput
+ */
+ private function addKeywords( &$parserOutput ) {
+ global $wgTitle;
+ $this->addKeyword( $wgTitle->getPrefixedText() );
+ $count = 1;
+ $links2d =& $parserOutput->getLinks();
+ if ( !is_array( $links2d ) ) {
+ return;
+ }
+ foreach ( $links2d as $dbkeys ) {
+ foreach( $dbkeys as $dbkey => $unused ) {
+ $this->addKeyword( $dbkey );
+ if ( ++$count > 10 ) {
+ break 2;
+ }
+ }
+ }
+ }
+
+ /**
+ * @return string The doctype, opening <html>, and head element.
+ */
+ public function headElement() {
+ global $wgDocType, $wgDTD, $wgContLanguageCode, $wgOutputEncoding, $wgMimeType;
+ global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces;
+ global $wgUser, $wgContLang, $wgUseTrackbacks, $wgTitle, $wgStyleVersion;
+
+ if( $wgMimeType == 'text/xml' || $wgMimeType == 'application/xhtml+xml' || $wgMimeType == 'application/xml' ) {
+ $ret = "<?xml version=\"1.0\" encoding=\"$wgOutputEncoding\" ?>\n";
+ } else {
+ $ret = '';
+ }
+
+ $ret .= "<!DOCTYPE html PUBLIC \"$wgDocType\"\n \"$wgDTD\">\n";
+
+ if ( '' == $this->getHTMLTitle() ) {
+ $this->setHTMLTitle( wfMsg( 'pagetitle', $this->getPageTitle() ));
+ }
+
+ $rtl = $wgContLang->isRTL() ? " dir='RTL'" : '';
+ $ret .= "<html xmlns=\"{$wgXhtmlDefaultNamespace}\" ";
+ foreach($wgXhtmlNamespaces as $tag => $ns) {
+ $ret .= "xmlns:{$tag}=\"{$ns}\" ";
+ }
+ $ret .= "xml:lang=\"$wgContLanguageCode\" lang=\"$wgContLanguageCode\" $rtl>\n";
+ $ret .= "<head>\n<title>" . htmlspecialchars( $this->getHTMLTitle() ) . "</title>\n";
+ array_push( $this->mMetatags, array( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ) );
+
+ $ret .= $this->getHeadLinks();
+ global $wgStylePath;
+ if( $this->isPrintable() ) {
+ $media = '';
+ } else {
+ $media = "media='print'";
+ }
+ $printsheet = htmlspecialchars( "$wgStylePath/common/wikiprintable.css?$wgStyleVersion" );
+ $ret .= "<link rel='stylesheet' type='text/css' $media href='$printsheet' />\n";
+
+ $sk = $wgUser->getSkin();
+ $ret .= $sk->getHeadScripts();
+ $ret .= $this->mScripts;
+ $ret .= $sk->getUserStyles();
+
+ if ($wgUseTrackbacks && $this->isArticleRelated())
+ $ret .= $wgTitle->trackbackRDF();
+
+ $ret .= "</head>\n";
+ return $ret;
+ }
+
+ /**
+ * @return string HTML tag links to be put in the header.
+ */
+ public function getHeadLinks() {
+ global $wgRequest;
+ $ret = '';
+ foreach ( $this->mMetatags as $tag ) {
+ if ( 0 == strcasecmp( 'http:', substr( $tag[0], 0, 5 ) ) ) {
+ $a = 'http-equiv';
+ $tag[0] = substr( $tag[0], 5 );
+ } else {
+ $a = 'name';
+ }
+ $ret .= "<meta $a=\"{$tag[0]}\" content=\"{$tag[1]}\" />\n";
+ }
+
+ $p = $this->mRobotpolicy;
+ if( $p !== '' && $p != 'index,follow' ) {
+ // http://www.robotstxt.org/wc/meta-user.html
+ // Only show if it's different from the default robots policy
+ $ret .= "<meta name=\"robots\" content=\"$p\" />\n";
+ }
+
+ if ( count( $this->mKeywords ) > 0 ) {
+ $strip = array(
+ "/<.*?>/" => '',
+ "/_/" => ' '
+ );
+ $ret .= "<meta name=\"keywords\" content=\"" .
+ htmlspecialchars(preg_replace(array_keys($strip), array_values($strip),implode( ",", $this->mKeywords ))) . "\" />\n";
+ }
+ foreach ( $this->mLinktags as $tag ) {
+ $ret .= '<link';
+ foreach( $tag as $attr => $val ) {
+ $ret .= " $attr=\"" . htmlspecialchars( $val ) . "\"";
+ }
+ $ret .= " />\n";
+ }
+ if( $this->isSyndicated() ) {
+ # FIXME: centralize the mime-type and name information in Feed.php
+ $link = $wgRequest->escapeAppendQuery( 'feed=rss' );
+ $ret .= "<link rel='alternate' type='application/rss+xml' title='RSS 2.0' href='$link' />\n";
+ $link = $wgRequest->escapeAppendQuery( 'feed=atom' );
+ $ret .= "<link rel='alternate' type='application/atom+xml' title='Atom 1.0' href='$link' />\n";
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Turn off regular page output and return an error reponse
+ * for when rate limiting has triggered.
+ * @todo i18n
+ */
+ public function rateLimited() {
+ global $wgOut;
+ $wgOut->disable();
+ wfHttpError( 500, 'Internal Server Error',
+ 'Sorry, the server has encountered an internal error. ' .
+ 'Please wait a moment and hit "refresh" to submit the request again.' );
+ }
+
+ /**
+ * Show an "add new section" link?
+ *
+ * @return bool True if the parser output instructs us to add one
+ */
+ public function showNewSectionLink() {
+ return $this->mNewSectionLink;
+ }
+}
+?>
diff --git a/includes/PageHistory.php b/includes/PageHistory.php
new file mode 100644
index 000000000000..aea0f0ed224e
--- /dev/null
+++ b/includes/PageHistory.php
@@ -0,0 +1,565 @@
+<?php
+/**
+ * Page history
+ *
+ * Split off from Article.php and Skin.php, 2003-12-22
+ * @package MediaWiki
+ */
+
+/**
+ * This class handles printing the history page for an article. In order to
+ * be efficient, it uses timestamps rather than offsets for paging, to avoid
+ * costly LIMIT,offset queries.
+ *
+ * Construct it by passing in an Article, and call $h->history() to print the
+ * history.
+ *
+ * @package MediaWiki
+ */
+
+class PageHistory {
+ const DIR_PREV = 0;
+ const DIR_NEXT = 1;
+
+ var $mArticle, $mTitle, $mSkin;
+ var $lastdate;
+ var $linesonpage;
+ var $mNotificationTimestamp;
+ var $mLatestId = null;
+
+ /**
+ * Construct a new PageHistory.
+ *
+ * @param Article $article
+ * @returns nothing
+ */
+ function PageHistory($article) {
+ global $wgUser;
+
+ $this->mArticle =& $article;
+ $this->mTitle =& $article->mTitle;
+ $this->mNotificationTimestamp = NULL;
+ $this->mSkin = $wgUser->getSkin();
+ }
+
+ /**
+ * Print the history page for an article.
+ *
+ * @returns nothing
+ */
+ function history() {
+ global $wgOut, $wgRequest, $wgTitle;
+
+ /*
+ * Allow client caching.
+ */
+
+ if( $wgOut->checkLastModified( $this->mArticle->getTimestamp() ) )
+ /* Client cache fresh and headers sent, nothing more to do. */
+ return;
+
+ $fname = 'PageHistory::history';
+ wfProfileIn( $fname );
+
+ /*
+ * Setup page variables.
+ */
+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ $wgOut->setArticleFlag( false );
+ $wgOut->setArticleRelated( true );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->setSyndicated( true );
+
+ $logPage = SpecialPage::getTitleFor( 'Log' );
+ $logLink = $this->mSkin->makeKnownLinkObj( $logPage, wfMsgHtml( 'viewpagelogs' ), 'page=' . $this->mTitle->getPrefixedUrl() );
+
+ $subtitle = wfMsgHtml( 'revhistory' ) . '<br />' . $logLink;
+ $wgOut->setSubtitle( $subtitle );
+
+ $feedType = $wgRequest->getVal( 'feed' );
+ if( $feedType ) {
+ wfProfileOut( $fname );
+ return $this->feed( $feedType );
+ }
+
+ /*
+ * Fail if article doesn't exist.
+ */
+ if( !$this->mTitle->exists() ) {
+ $wgOut->addWikiText( wfMsg( 'nohistory' ) );
+ wfProfileOut( $fname );
+ return;
+ }
+
+
+ /*
+ * "go=first" means to jump to the last (earliest) history page.
+ * This is deprecated, it no longer appears in the user interface
+ */
+ if ( $wgRequest->getText("go") == 'first' ) {
+ $limit = $wgRequest->getInt( 'limit', 50 );
+ $wgOut->redirect( $wgTitle->getLocalURL( "action=history&limit={$limit}&dir=prev" ) );
+ return;
+ }
+
+ /**
+ * Do the list
+ */
+ $pager = new PageHistoryPager( $this );
+ $this->linesonpage = $pager->getNumRows();
+ $wgOut->addHTML(
+ $pager->getNavigationBar() .
+ $this->beginHistoryList() .
+ $pager->getBody() .
+ $this->endHistoryList() .
+ $pager->getNavigationBar()
+ );
+ wfProfileOut( $fname );
+ }
+
+ /** @todo document */
+ function beginHistoryList() {
+ global $wgTitle;
+ $this->lastdate = '';
+ $s = wfMsgExt( 'histlegend', array( 'parse') );
+ $s .= '<form action="' . $wgTitle->escapeLocalURL( '-' ) . '" method="get">';
+ $prefixedkey = htmlspecialchars($wgTitle->getPrefixedDbKey());
+
+ // The following line is SUPPOSED to have double-quotes around the
+ // $prefixedkey variable, because htmlspecialchars() doesn't escape
+ // single-quotes.
+ //
+ // On at least two occasions people have changed it to single-quotes,
+ // which creates invalid HTML and incorrect display of the resulting
+ // link.
+ //
+ // Please do not break this a third time. Thank you for your kind
+ // consideration and cooperation.
+ //
+ $s .= "<input type='hidden' name='title' value=\"{$prefixedkey}\" />\n";
+
+ $s .= $this->submitButton();
+ $s .= '<ul id="pagehistory">' . "\n";
+ return $s;
+ }
+
+ /** @todo document */
+ function endHistoryList() {
+ $s = '</ul>';
+ $s .= $this->submitButton( array( 'id' => 'historysubmit' ) );
+ $s .= '</form>';
+ return $s;
+ }
+
+ /** @todo document */
+ function submitButton( $bits = array() ) {
+ return ( $this->linesonpage > 0 )
+ ? wfElement( 'input', array_merge( $bits,
+ array(
+ 'class' => 'historysubmit',
+ 'type' => 'submit',
+ 'accesskey' => wfMsg( 'accesskey-compareselectedversions' ),
+ 'title' => wfMsg( 'tooltip-compareselectedversions' ),
+ 'value' => wfMsg( 'compareselectedversions' ),
+ ) ) )
+ : '';
+ }
+
+ /**
+ * Returns a row from the history printout.
+ *
+ * @todo document some more, and maybe clean up the code (some params redundant?)
+ *
+ * @param object $row The database row corresponding to the line (or is it the previous line?).
+ * @param object $next The database row corresponding to the next line (or is it this one?).
+ * @param int $counter Apparently a counter of what row number we're at, counted from the top row = 1.
+ * @param $notificationtimestamp
+ * @param bool $latest Whether this row corresponds to the page's latest revision.
+ * @param bool $firstInList Whether this row corresponds to the first displayed on this history page.
+ * @return string HTML output for the row
+ */
+ function historyLine( $row, $next, $counter = '', $notificationtimestamp = false, $latest = false, $firstInList = false ) {
+ global $wgUser;
+ $rev = new Revision( $row );
+ $rev->setTitle( $this->mTitle );
+
+ $s = '<li>';
+ $curlink = $this->curLink( $rev, $latest );
+ $lastlink = $this->lastLink( $rev, $next, $counter );
+ $arbitrary = $this->diffButtons( $rev, $firstInList, $counter );
+ $link = $this->revLink( $rev );
+
+ $user = $this->mSkin->userLink( $rev->getUser(), $rev->getUserText() )
+ . $this->mSkin->userToolLinks( $rev->getUser(), $rev->getUserText() );
+
+ $s .= "($curlink) ($lastlink) $arbitrary";
+
+ if( $wgUser->isAllowed( 'deleterevision' ) ) {
+ $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
+ if( $firstInList ) {
+ // We don't currently handle well changing the top revision's settings
+ $del = wfMsgHtml( 'rev-delundel' );
+ } else {
+ $del = $this->mSkin->makeKnownLinkObj( $revdel,
+ wfMsg( 'rev-delundel' ),
+ 'target=' . urlencode( $this->mTitle->getPrefixedDbkey() ) .
+ '&oldid=' . urlencode( $rev->getId() ) );
+ }
+ $s .= "(<small>$del</small>) ";
+ }
+
+ $s .= " $link <span class='history-user'>$user</span>";
+
+ if( $row->rev_minor_edit ) {
+ $s .= ' ' . wfElement( 'span', array( 'class' => 'minor' ), wfMsg( 'minoreditletter') );
+ }
+
+ $s .= $this->mSkin->revComment( $rev );
+ if ($notificationtimestamp && ($row->rev_timestamp >= $notificationtimestamp)) {
+ $s .= ' <span class="updatedmarker">' . wfMsgHtml( 'updatedmarker' ) . '</span>';
+ }
+ if( $row->rev_deleted & Revision::DELETED_TEXT ) {
+ $s .= ' ' . wfMsgHtml( 'deletedrev' );
+ }
+ if( $wgUser->isAllowed( 'rollback' ) && $latest ) {
+ $s .= ' '.$this->mSkin->generateRollback( $rev );
+ }
+ $s .= "</li>\n";
+
+ return $s;
+ }
+
+ /** @todo document */
+ function revLink( $rev ) {
+ global $wgLang;
+ $date = $wgLang->timeanddate( wfTimestamp(TS_MW, $rev->getTimestamp()), true );
+ if( $rev->userCan( Revision::DELETED_TEXT ) ) {
+ $link = $this->mSkin->makeKnownLinkObj(
+ $this->mTitle, $date, "oldid=" . $rev->getId() );
+ } else {
+ $link = $date;
+ }
+ if( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+ return '<span class="history-deleted">' . $link . '</span>';
+ }
+ return $link;
+ }
+
+ /** @todo document */
+ function curLink( $rev, $latest ) {
+ $cur = wfMsgExt( 'cur', array( 'escape') );
+ if( $latest || !$rev->userCan( Revision::DELETED_TEXT ) ) {
+ return $cur;
+ } else {
+ return $this->mSkin->makeKnownLinkObj(
+ $this->mTitle, $cur,
+ 'diff=' . $this->getLatestID() .
+ "&oldid=" . $rev->getId() );
+ }
+ }
+
+ /** @todo document */
+ function lastLink( $rev, $next, $counter ) {
+ $last = wfMsgExt( 'last', array( 'escape' ) );
+ if ( is_null( $next ) ) {
+ # Probably no next row
+ return $last;
+ } elseif ( $next === 'unknown' ) {
+ # Next row probably exists but is unknown, use an oldid=prev link
+ return $this->mSkin->makeKnownLinkObj(
+ $this->mTitle,
+ $last,
+ "diff=" . $rev->getId() . "&oldid=prev" );
+ } elseif( !$rev->userCan( Revision::DELETED_TEXT ) ) {
+ return $last;
+ } else {
+ return $this->mSkin->makeKnownLinkObj(
+ $this->mTitle,
+ $last,
+ "diff=" . $rev->getId() . "&oldid={$next->rev_id}"
+ /*,
+ '',
+ '',
+ "tabindex={$counter}"*/ );
+ }
+ }
+
+ /** @todo document */
+ function diffButtons( $rev, $firstInList, $counter ) {
+ if( $this->linesonpage > 1) {
+ $radio = array(
+ 'type' => 'radio',
+ 'value' => $rev->getId(),
+# do we really need to flood this on every item?
+# 'title' => wfMsgHtml( 'selectolderversionfordiff' )
+ );
+
+ if( !$rev->userCan( Revision::DELETED_TEXT ) ) {
+ $radio['disabled'] = 'disabled';
+ }
+
+ /** @todo: move title texts to javascript */
+ if ( $firstInList ) {
+ $first = wfElement( 'input', array_merge(
+ $radio,
+ array(
+ 'style' => 'visibility:hidden',
+ 'name' => 'oldid' ) ) );
+ $checkmark = array( 'checked' => 'checked' );
+ } else {
+ if( $counter == 2 ) {
+ $checkmark = array( 'checked' => 'checked' );
+ } else {
+ $checkmark = array();
+ }
+ $first = wfElement( 'input', array_merge(
+ $radio,
+ $checkmark,
+ array( 'name' => 'oldid' ) ) );
+ $checkmark = array();
+ }
+ $second = wfElement( 'input', array_merge(
+ $radio,
+ $checkmark,
+ array( 'name' => 'diff' ) ) );
+ return $first . $second;
+ } else {
+ return '';
+ }
+ }
+
+ /** @todo document */
+ function getLatestId() {
+ if( is_null( $this->mLatestId ) ) {
+ $id = $this->mTitle->getArticleID();
+ $db =& wfGetDB(DB_SLAVE);
+ $this->mLatestId = $db->selectField( 'page',
+ "page_latest",
+ array( 'page_id' => $id ),
+ 'PageHistory::getLatestID' );
+ }
+ return $this->mLatestId;
+ }
+
+ /**
+ * Fetch an array of revisions, specified by a given limit, offset and
+ * direction. This is now only used by the feeds. It was previously
+ * used by the main UI but that's now handled by the pager.
+ */
+ function fetchRevisions($limit, $offset, $direction) {
+ $fname = 'PageHistory::fetchRevisions';
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ if ($direction == PageHistory::DIR_PREV)
+ list($dirs, $oper) = array("ASC", ">=");
+ else /* $direction == PageHistory::DIR_NEXT */
+ list($dirs, $oper) = array("DESC", "<=");
+
+ if ($offset)
+ $offsets = array("rev_timestamp $oper '$offset'");
+ else
+ $offsets = array();
+
+ $page_id = $this->mTitle->getArticleID();
+
+ $res = $dbr->select(
+ 'revision',
+ array('rev_id', 'rev_page', 'rev_text_id', 'rev_user', 'rev_comment', 'rev_user_text',
+ 'rev_timestamp', 'rev_minor_edit', 'rev_deleted'),
+ array_merge(array("rev_page=$page_id"), $offsets),
+ $fname,
+ array('ORDER BY' => "rev_timestamp $dirs",
+ 'USE INDEX' => 'page_timestamp', 'LIMIT' => $limit)
+ );
+
+ $result = array();
+ while (($obj = $dbr->fetchObject($res)) != NULL)
+ $result[] = $obj;
+
+ return $result;
+ }
+
+ /** @todo document */
+ function getNotificationTimestamp() {
+ global $wgUser, $wgShowUpdatedMarker;
+ $fname = 'PageHistory::getNotficationTimestamp';
+
+ if ($this->mNotificationTimestamp !== NULL)
+ return $this->mNotificationTimestamp;
+
+ if ($wgUser->isAnon() || !$wgShowUpdatedMarker)
+ return $this->mNotificationTimestamp = false;
+
+ $dbr =& wfGetDB(DB_SLAVE);
+
+ $this->mNotificationTimestamp = $dbr->selectField(
+ 'watchlist',
+ 'wl_notificationtimestamp',
+ array( 'wl_namespace' => $this->mTitle->getNamespace(),
+ 'wl_title' => $this->mTitle->getDBkey(),
+ 'wl_user' => $wgUser->getID()
+ ),
+ $fname);
+
+ // Don't use the special value reserved for telling whether the field is filled
+ if ( is_null( $this->mNotificationTimestamp ) ) {
+ $this->mNotificationTimestamp = false;
+ }
+
+ return $this->mNotificationTimestamp;
+ }
+
+ /**
+ * Output a subscription feed listing recent edits to this page.
+ * @param string $type
+ */
+ function feed( $type ) {
+ require_once 'SpecialRecentchanges.php';
+
+ global $wgFeedClasses;
+ if( !isset( $wgFeedClasses[$type] ) ) {
+ global $wgOut;
+ $wgOut->addWikiText( wfMsg( 'feed-invalid' ) );
+ return;
+ }
+
+ $feed = new $wgFeedClasses[$type](
+ $this->mTitle->getPrefixedText() . ' - ' .
+ wfMsgForContent( 'history-feed-title' ),
+ wfMsgForContent( 'history-feed-description' ),
+ $this->mTitle->getFullUrl( 'action=history' ) );
+
+ $items = $this->fetchRevisions(10, 0, PageHistory::DIR_NEXT);
+ $feed->outHeader();
+ if( $items ) {
+ foreach( $items as $row ) {
+ $feed->outItem( $this->feedItem( $row ) );
+ }
+ } else {
+ $feed->outItem( $this->feedEmpty() );
+ }
+ $feed->outFooter();
+ }
+
+ function feedEmpty() {
+ global $wgOut;
+ return new FeedItem(
+ wfMsgForContent( 'nohistory' ),
+ $wgOut->parse( wfMsgForContent( 'history-feed-empty' ) ),
+ $this->mTitle->getFullUrl(),
+ wfTimestamp( TS_MW ),
+ '',
+ $this->mTitle->getTalkPage()->getFullUrl() );
+ }
+
+ /**
+ * Generate a FeedItem object from a given revision table row
+ * Borrows Recent Changes' feed generation functions for formatting;
+ * includes a diff to the previous revision (if any).
+ *
+ * @param $row
+ * @return FeedItem
+ */
+ function feedItem( $row ) {
+ $rev = new Revision( $row );
+ $rev->setTitle( $this->mTitle );
+ $text = rcFormatDiffRow( $this->mTitle,
+ $this->mTitle->getPreviousRevisionID( $rev->getId() ),
+ $rev->getId(),
+ $rev->getTimestamp(),
+ $rev->getComment() );
+
+ if( $rev->getComment() == '' ) {
+ global $wgContLang;
+ $title = wfMsgForContent( 'history-feed-item-nocomment',
+ $rev->getUserText(),
+ $wgContLang->timeanddate( $rev->getTimestamp() ) );
+ } else {
+ $title = $rev->getUserText() . ": " . $this->stripComment( $rev->getComment() );
+ }
+
+ return new FeedItem(
+ $title,
+ $text,
+ $this->mTitle->getFullUrl( 'diff=' . $rev->getId() . '&oldid=prev' ),
+ $rev->getTimestamp(),
+ $rev->getUserText(),
+ $this->mTitle->getTalkPage()->getFullUrl() );
+ }
+
+ /**
+ * Quickie hack... strip out wikilinks to more legible form from the comment.
+ */
+ function stripComment( $text ) {
+ return preg_replace( '/\[\[([^]]*\|)?([^]]+)\]\]/', '\2', $text );
+ }
+}
+
+
+class PageHistoryPager extends ReverseChronologicalPager {
+ public $mLastRow = false, $mPageHistory;
+
+ function __construct( $pageHistory ) {
+ parent::__construct();
+ $this->mPageHistory = $pageHistory;
+ }
+
+ function getQueryInfo() {
+ return array(
+ 'tables' => 'revision',
+ 'fields' => array('rev_id', 'rev_page', 'rev_text_id', 'rev_user', 'rev_comment', 'rev_user_text',
+ 'rev_timestamp', 'rev_minor_edit', 'rev_deleted'),
+ 'conds' => array('rev_page' => $this->mPageHistory->mTitle->getArticleID() ),
+ 'options' => array( 'USE INDEX' => 'page_timestamp' )
+ );
+ }
+
+ function getIndexField() {
+ return 'rev_timestamp';
+ }
+
+ function formatRow( $row ) {
+ if ( $this->mLastRow ) {
+ $latest = $this->mCounter == 1 && $this->mOffset == '';
+ $firstInList = $this->mCounter == 1;
+ $s = $this->mPageHistory->historyLine( $this->mLastRow, $row, $this->mCounter++,
+ $this->mPageHistory->getNotificationTimestamp(), $latest, $firstInList );
+ } else {
+ $s = '';
+ }
+ $this->mLastRow = $row;
+ return $s;
+ }
+
+ function getStartBody() {
+ $this->mLastRow = false;
+ $this->mCounter = 1;
+ return '';
+ }
+
+ function getEndBody() {
+ if ( $this->mLastRow ) {
+ $latest = $this->mCounter == 1 && $this->mOffset == 0;
+ $firstInList = $this->mCounter == 1;
+ if ( $this->mIsBackwards ) {
+ # Next row is unknown, but for UI reasons, probably exists if an offset has been specified
+ if ( $this->mOffset == '' ) {
+ $next = null;
+ } else {
+ $next = 'unknown';
+ }
+ } else {
+ # The next row is the past-the-end row
+ $next = $this->mPastTheEndRow;
+ }
+ $s = $this->mPageHistory->historyLine( $this->mLastRow, $next, $this->mCounter++,
+ $this->mPageHistory->getNotificationTimestamp(), $latest, $firstInList );
+ } else {
+ $s = '';
+ }
+ return $s;
+ }
+}
+
+?>
diff --git a/includes/Pager.php b/includes/Pager.php
new file mode 100644
index 000000000000..0987cc066c44
--- /dev/null
+++ b/includes/Pager.php
@@ -0,0 +1,656 @@
+<?php
+
+/**
+ * Basic pager interface.
+ */
+interface Pager {
+ function getNavigationBar();
+ function getBody();
+}
+
+/**
+ * IndexPager is an efficient pager which uses a (roughly unique) index in the
+ * data set to implement paging, rather than a "LIMIT offset,limit" clause.
+ * In MySQL, such a limit/offset clause requires counting through the specified number
+ * of offset rows to find the desired data, which can be expensive for large offsets.
+ *
+ * ReverseChronologicalPager is a child class of the abstract IndexPager, and contains
+ * some formatting and display code which is specific to the use of timestamps as
+ * indexes. Here is a synopsis of its operation:
+ *
+ * * The query is specified by the offset, limit and direction (dir) parameters, in
+ * addition to any subclass-specific parameters.
+ *
+ * * The offset is the non-inclusive start of the DB query. A row with an index value
+ * equal to the offset will never be shown.
+ *
+ * * The query may either be done backwards, where the rows are returned by the database
+ * in the opposite order to which they are displayed to the user, or forwards. This is
+ * specified by the "dir" parameter, dir=prev means backwards, anything else means
+ * forwards. The offset value specifies the start of the database result set, which
+ * may be either the start or end of the displayed data set. This allows "previous"
+ * links to be implemented without knowledge of the index value at the start of the
+ * previous page.
+ *
+ * * An additional row beyond the user-specified limit is always requested. This allows
+ * us to tell whether we should display a "next" link in the case of forwards mode,
+ * or a "previous" link in the case of backwards mode. Determining whether to
+ * display the other link (the one for the page before the start of the database
+ * result set) can be done heuristically by examining the offset.
+ *
+ * * An empty offset indicates that the offset condition should be omitted from the query.
+ * This naturally produces either the first page or the last page depending on the
+ * dir parameter.
+ *
+ * Subclassing the pager to implement concrete functionality should be fairly simple,
+ * please see the examples in PageHistory.php and SpecialIpblocklist.php. You just need
+ * to override formatRow(), getQueryInfo() and getIndexField(). Don't forget to call the
+ * parent constructor if you override it.
+ */
+abstract class IndexPager implements Pager {
+ public $mRequest;
+ public $mLimitsShown = array( 20, 50, 100, 250, 500 );
+ public $mDefaultLimit = 50;
+ public $mOffset, $mLimit;
+ public $mQueryDone = false;
+ public $mDb;
+ public $mPastTheEndRow;
+
+ protected $mIndexField;
+
+ /**
+ * Default query direction. false for ascending, true for descending
+ */
+ public $mDefaultDirection = false;
+
+ /**
+ * Result object for the query. Warning: seek before use.
+ */
+ public $mResult;
+
+ function __construct() {
+ global $wgRequest;
+ $this->mRequest = $wgRequest;
+
+ # NB: the offset is quoted, not validated. It is treated as an arbitrary string
+ # to support the widest variety of index types. Be careful outputting it into
+ # HTML!
+ $this->mOffset = $this->mRequest->getText( 'offset' );
+ $this->mLimit = $this->mRequest->getInt( 'limit', $this->mDefaultLimit );
+ if ( $this->mLimit <= 0 || $this->mLimit > 50000 ) {
+ $this->mLimit = $this->mDefaultLimit;
+ }
+ $this->mIsBackwards = ( $this->mRequest->getVal( 'dir' ) == 'prev' );
+ $this->mIndexField = $this->getIndexField();
+ $this->mDb = wfGetDB( DB_SLAVE );
+ }
+
+ /**
+ * Do the query, using information from the object context. This function
+ * has been kept minimal to make it overridable if necessary, to allow for
+ * result sets formed from multiple DB queries.
+ */
+ function doQuery() {
+ # Use the child class name for profiling
+ $fname = __METHOD__ . ' (' . get_class( $this ) . ')';
+ wfProfileIn( $fname );
+
+ $descending = ( $this->mIsBackwards == $this->mDefaultDirection );
+ # Plus an extra row so that we can tell the "next" link should be shown
+ $queryLimit = $this->mLimit + 1;
+
+ $this->mResult = $this->reallyDoQuery( $this->mOffset, $queryLimit, $descending );
+ $this->extractResultInfo( $this->mOffset, $queryLimit, $this->mResult );
+ $this->mQueryDone = true;
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Extract some useful data from the result object for use by
+ * the navigation bar, put it into $this
+ */
+ function extractResultInfo( $offset, $limit, ResultWrapper $res ) {
+ $numRows = $res->numRows();
+ if ( $numRows ) {
+ $row = $res->fetchRow();
+ $firstIndex = $row[$this->mIndexField];
+
+ # Discard the extra result row if there is one
+ if ( $numRows > $this->mLimit && $numRows > 1 ) {
+ $res->seek( $numRows - 1 );
+ $this->mPastTheEndRow = $res->fetchObject();
+ $indexField = $this->mIndexField;
+ $this->mPastTheEndIndex = $this->mPastTheEndRow->$indexField;
+ $res->seek( $numRows - 2 );
+ $row = $res->fetchRow();
+ $lastIndex = $row[$this->mIndexField];
+ } else {
+ $this->mPastTheEndRow = null;
+ # Setting indexes to an empty string means that they will be omitted
+ # if they would otherwise appear in URLs. It just so happens that this
+ # is the right thing to do in the standard UI, in all the relevant cases.
+ $this->mPastTheEndIndex = '';
+ $res->seek( $numRows - 1 );
+ $row = $res->fetchRow();
+ $lastIndex = $row[$this->mIndexField];
+ }
+ } else {
+ $firstIndex = '';
+ $lastIndex = '';
+ $this->mPastTheEndRow = null;
+ $this->mPastTheEndIndex = '';
+ }
+
+ if ( $this->mIsBackwards ) {
+ $this->mIsFirst = ( $numRows < $limit );
+ $this->mIsLast = ( $offset == '' );
+ $this->mLastShown = $firstIndex;
+ $this->mFirstShown = $lastIndex;
+ } else {
+ $this->mIsFirst = ( $offset == '' );
+ $this->mIsLast = ( $numRows < $limit );
+ $this->mLastShown = $lastIndex;
+ $this->mFirstShown = $firstIndex;
+ }
+ }
+
+ /**
+ * Do a query with specified parameters, rather than using the object context
+ *
+ * @param string $offset Index offset, inclusive
+ * @param integer $limit Exact query limit
+ * @param boolean $descending Query direction, false for ascending, true for descending
+ * @return ResultWrapper
+ */
+ function reallyDoQuery( $offset, $limit, $ascending ) {
+ $fname = __METHOD__ . ' (' . get_class( $this ) . ')';
+ $info = $this->getQueryInfo();
+ $tables = $info['tables'];
+ $fields = $info['fields'];
+ $conds = isset( $info['conds'] ) ? $info['conds'] : array();
+ $options = isset( $info['options'] ) ? $info['options'] : array();
+ if ( $ascending ) {
+ $options['ORDER BY'] = $this->mIndexField;
+ $operator = '>';
+ } else {
+ $options['ORDER BY'] = $this->mIndexField . ' DESC';
+ $operator = '<';
+ }
+ if ( $offset != '' ) {
+ $conds[] = $this->mIndexField . $operator . $this->mDb->addQuotes( $offset );
+ }
+ $options['LIMIT'] = intval( $limit );
+ $res = $this->mDb->select( $tables, $fields, $conds, $fname, $options );
+ return new ResultWrapper( $this->mDb, $res );
+ }
+
+ /**
+ * Get the formatted result list. Calls getStartBody(), formatRow() and
+ * getEndBody(), concatenates the results and returns them.
+ */
+ function getBody() {
+ if ( !$this->mQueryDone ) {
+ $this->doQuery();
+ }
+ # Don't use any extra rows returned by the query
+ $numRows = min( $this->mResult->numRows(), $this->mLimit );
+
+ $s = $this->getStartBody();
+ if ( $numRows ) {
+ if ( $this->mIsBackwards ) {
+ for ( $i = $numRows - 1; $i >= 0; $i-- ) {
+ $this->mResult->seek( $i );
+ $row = $this->mResult->fetchObject();
+ $s .= $this->formatRow( $row );
+ }
+ } else {
+ $this->mResult->seek( 0 );
+ for ( $i = 0; $i < $numRows; $i++ ) {
+ $row = $this->mResult->fetchObject();
+ $s .= $this->formatRow( $row );
+ }
+ }
+ } else {
+ $s .= $this->getEmptyBody();
+ }
+ $s .= $this->getEndBody();
+ return $s;
+ }
+
+ /**
+ * Make a self-link
+ */
+ function makeLink($text, $query = NULL) {
+ if ( $query === null ) {
+ return $text;
+ } else {
+ return $this->getSkin()->makeKnownLinkObj( $this->getTitle(), $text,
+ wfArrayToCGI( $query, $this->getDefaultQuery() ) );
+ }
+ }
+
+ /**
+ * Hook into getBody(), allows text to be inserted at the start. This
+ * will be called even if there are no rows in the result set.
+ */
+ function getStartBody() {
+ return '';
+ }
+
+ /**
+ * Hook into getBody() for the end of the list
+ */
+ function getEndBody() {
+ return '';
+ }
+
+ /**
+ * Hook into getBody(), for the bit between the start and the
+ * end when there are no rows
+ */
+ function getEmptyBody() {
+ return '';
+ }
+
+ /**
+ * Title used for self-links. Override this if you want to be able to
+ * use a title other than $wgTitle
+ */
+ function getTitle() {
+ return $GLOBALS['wgTitle'];
+ }
+
+ /**
+ * Get the current skin. This can be overridden if necessary.
+ */
+ function getSkin() {
+ if ( !isset( $this->mSkin ) ) {
+ global $wgUser;
+ $this->mSkin = $wgUser->getSkin();
+ }
+ return $this->mSkin;
+ }
+
+ /**
+ * Get an array of query parameters that should be put into self-links.
+ * By default, all parameters passed in the URL are used, except for a
+ * short blacklist.
+ */
+ function getDefaultQuery() {
+ if ( !isset( $this->mDefaultQuery ) ) {
+ $this->mDefaultQuery = $_GET;
+ unset( $this->mDefaultQuery['title'] );
+ unset( $this->mDefaultQuery['dir'] );
+ unset( $this->mDefaultQuery['offset'] );
+ unset( $this->mDefaultQuery['limit'] );
+ }
+ return $this->mDefaultQuery;
+ }
+
+ /**
+ * Get the number of rows in the result set
+ */
+ function getNumRows() {
+ if ( !$this->mQueryDone ) {
+ $this->doQuery();
+ }
+ return $this->mResult->numRows();
+ }
+
+ /**
+ * Get a query array for the prev, next, first and last links.
+ */
+ function getPagingQueries() {
+ if ( !$this->mQueryDone ) {
+ $this->doQuery();
+ }
+
+ # Don't announce the limit everywhere if it's the default
+ $urlLimit = $this->mLimit == $this->mDefaultLimit ? '' : $this->mLimit;
+
+ if ( $this->mIsFirst ) {
+ $prev = false;
+ $first = false;
+ } else {
+ $prev = array( 'dir' => 'prev', 'offset' => $this->mFirstShown, 'limit' => $urlLimit );
+ $first = array( 'limit' => $urlLimit );
+ }
+ if ( $this->mIsLast ) {
+ $next = false;
+ $last = false;
+ } else {
+ $next = array( 'offset' => $this->mLastShown, 'limit' => $urlLimit );
+ $last = array( 'dir' => 'prev', 'limit' => $urlLimit );
+ }
+ return array( 'prev' => $prev, 'next' => $next, 'first' => $first, 'last' => $last );
+ }
+
+ /**
+ * Get paging links. If a link is disabled, the item from $disabledTexts will
+ * be used. If there is no such item, the unlinked text from $linkTexts will
+ * be used. Both $linkTexts and $disabledTexts are arrays of HTML.
+ */
+ function getPagingLinks( $linkTexts, $disabledTexts = array() ) {
+ $queries = $this->getPagingQueries();
+ $links = array();
+ foreach ( $queries as $type => $query ) {
+ if ( $query !== false ) {
+ $links[$type] = $this->makeLink( $linkTexts[$type], $queries[$type] );
+ } elseif ( isset( $disabledTexts[$type] ) ) {
+ $links[$type] = $disabledTexts[$type];
+ } else {
+ $links[$type] = $linkTexts[$type];
+ }
+ }
+ return $links;
+ }
+
+ function getLimitLinks() {
+ global $wgLang;
+ $links = array();
+ if ( $this->mIsBackwards ) {
+ $offset = $this->mPastTheEndIndex;
+ } else {
+ $offset = $this->mOffset;
+ }
+ foreach ( $this->mLimitsShown as $limit ) {
+ $links[] = $this->makeLink( $wgLang->formatNum( $limit ),
+ array( 'offset' => $offset, 'limit' => $limit ) );
+ }
+ return $links;
+ }
+
+ /**
+ * Abstract formatting function. This should return an HTML string
+ * representing the result row $row. Rows will be concatenated and
+ * returned by getBody()
+ */
+ abstract function formatRow( $row );
+
+ /**
+ * This function should be overridden to provide all parameters
+ * needed for the main paged query. It returns an associative
+ * array with the following elements:
+ * tables => Table(s) for passing to Database::select()
+ * fields => Field(s) for passing to Database::select(), may be *
+ * conds => WHERE conditions
+ * options => option array
+ */
+ abstract function getQueryInfo();
+
+ /**
+ * This function should be overridden to return the name of the
+ * index field.
+ */
+ abstract function getIndexField();
+}
+
+/**
+ * IndexPager with a formatted navigation bar
+ */
+abstract class ReverseChronologicalPager extends IndexPager {
+ public $mDefaultDirection = true;
+
+ function __construct() {
+ parent::__construct();
+ }
+
+ function getNavigationBar() {
+ global $wgLang;
+
+ if ( isset( $this->mNavigationBar ) ) {
+ return $this->mNavigationBar;
+ }
+ $linkTexts = array(
+ 'prev' => wfMsgHtml( "prevn", $this->mLimit ),
+ 'next' => wfMsgHtml( 'nextn', $this->mLimit ),
+ 'first' => wfMsgHtml('histlast'),
+ 'last' => wfMsgHtml( 'histfirst' )
+ );
+
+ $pagingLinks = $this->getPagingLinks( $linkTexts );
+ $limitLinks = $this->getLimitLinks();
+ $limits = implode( ' | ', $limitLinks );
+
+ $this->mNavigationBar = "({$pagingLinks['first']} | {$pagingLinks['last']}) " . wfMsgHtml("viewprevnext", $pagingLinks['prev'], $pagingLinks['next'], $limits);
+ return $this->mNavigationBar;
+ }
+}
+
+/**
+ * Table-based display with a user-selectable sort order
+ */
+abstract class TablePager extends IndexPager {
+ var $mSort;
+ var $mCurrentRow;
+
+ function __construct() {
+ global $wgRequest;
+ $this->mSort = $wgRequest->getText( 'sort' );
+ if ( !array_key_exists( $this->mSort, $this->getFieldNames() ) ) {
+ $this->mSort = $this->getDefaultSort();
+ }
+ if ( $wgRequest->getBool( 'asc' ) ) {
+ $this->mDefaultDirection = false;
+ } elseif ( $wgRequest->getBool( 'desc' ) ) {
+ $this->mDefaultDirection = true;
+ } /* Else leave it at whatever the class default is */
+
+ parent::__construct();
+ }
+
+ function getStartBody() {
+ global $wgStylePath;
+ $tableClass = htmlspecialchars( $this->getTableClass() );
+ $sortClass = htmlspecialchars( $this->getSortHeaderClass() );
+
+ $s = "<table border='1' class=\"$tableClass\"><thead><tr>\n";
+ $fields = $this->getFieldNames();
+
+ # Make table header
+ foreach ( $fields as $field => $name ) {
+ if ( strval( $name ) == '' ) {
+ $s .= "<th>&nbsp;</th>\n";
+ } elseif ( $this->isFieldSortable( $field ) ) {
+ $query = array( 'sort' => $field, 'limit' => $this->mLimit );
+ if ( $field == $this->mSort ) {
+ # This is the sorted column
+ # Prepare a link that goes in the other sort order
+ if ( $this->mDefaultDirection ) {
+ # Descending
+ $image = 'Arr_u.png';
+ $query['asc'] = '1';
+ $query['desc'] = '';
+ $alt = htmlspecialchars( wfMsg( 'descending_abbrev' ) );
+ } else {
+ # Ascending
+ $image = 'Arr_d.png';
+ $query['asc'] = '';
+ $query['desc'] = '1';
+ $alt = htmlspecialchars( wfMsg( 'ascending_abbrev' ) );
+ }
+ $image = htmlspecialchars( "$wgStylePath/common/images/$image" );
+ $link = $this->makeLink(
+ "<img width=\"12\" height=\"12\" alt=\"$alt\" src=\"$image\" />" .
+ htmlspecialchars( $name ), $query );
+ $s .= "<th class=\"$sortClass\">$link</th>\n";
+ } else {
+ $s .= '<th>' . $this->makeLink( htmlspecialchars( $name ), $query ) . "</th>\n";
+ }
+ } else {
+ $s .= '<th>' . htmlspecialchars( $name ) . "</th>\n";
+ }
+ }
+ $s .= "</tr></thead><tbody>\n";
+ return $s;
+ }
+
+ function getEndBody() {
+ return "</tbody></table>\n";
+ }
+
+ function getEmptyBody() {
+ $colspan = count( $this->getFieldNames() );
+ $msgEmpty = wfMsgHtml( 'table_pager_empty' );
+ return "<tr><td colspan=\"$colspan\">$msgEmpty</td></tr>\n";
+ }
+
+ function formatRow( $row ) {
+ $s = "<tr>\n";
+ $fieldNames = $this->getFieldNames();
+ $this->mCurrentRow = $row; # In case formatValue needs to know
+ foreach ( $fieldNames as $field => $name ) {
+ $value = isset( $row->$field ) ? $row->$field : null;
+ $formatted = strval( $this->formatValue( $field, $value ) );
+ if ( $formatted == '' ) {
+ $formatted = '&nbsp;';
+ }
+ $class = 'TablePager_col_' . htmlspecialchars( $field );
+ $s .= "<td class=\"$class\">$formatted</td>\n";
+ }
+ $s .= "</tr>\n";
+ return $s;
+ }
+
+ function getIndexField() {
+ return $this->mSort;
+ }
+
+ function getTableClass() {
+ return 'TablePager';
+ }
+
+ function getNavClass() {
+ return 'TablePager_nav';
+ }
+
+ function getSortHeaderClass() {
+ return 'TablePager_sort';
+ }
+
+ /**
+ * A navigation bar with images
+ */
+ function getNavigationBar() {
+ global $wgStylePath, $wgContLang;
+ $path = "$wgStylePath/common/images";
+ $labels = array(
+ 'first' => 'table_pager_first',
+ 'prev' => 'table_pager_prev',
+ 'next' => 'table_pager_next',
+ 'last' => 'table_pager_last',
+ );
+ $images = array(
+ 'first' => $wgContLang->isRTL() ? 'arrow_last_25.png' : 'arrow_first_25.png',
+ 'prev' => $wgContLang->isRTL() ? 'arrow_right_25.png' : 'arrow_left_25.png',
+ 'next' => $wgContLang->isRTL() ? 'arrow_left_25.png' : 'arrow_right_25.png',
+ 'last' => $wgContLang->isRTL() ? 'arrow_first_25.png' : 'arrow_last_25.png',
+ );
+ $disabledImages = array(
+ 'first' => $wgContLang->isRTL() ? 'arrow_disabled_last_25.png' : 'arrow_disabled_first_25.png',
+ 'prev' => $wgContLang->isRTL() ? 'arrow_disabled_right_25.png' : 'arrow_disabled_left_25.png',
+ 'next' => $wgContLang->isRTL() ? 'arrow_disabled_left_25.png' : 'arrow_disabled_right_25.png',
+ 'last' => $wgContLang->isRTL() ? 'arrow_disabled_first_25.png' : 'arrow_disabled_last_25.png',
+ );
+
+ $linkTexts = array();
+ $disabledTexts = array();
+ foreach ( $labels as $type => $label ) {
+ $msgLabel = wfMsgHtml( $label );
+ $linkTexts[$type] = "<img src=\"$path/{$images[$type]}\" alt=\"$msgLabel\"/><br/>$msgLabel";
+ $disabledTexts[$type] = "<img src=\"$path/{$disabledImages[$type]}\" alt=\"$msgLabel\"/><br/>$msgLabel";
+ }
+ $links = $this->getPagingLinks( $linkTexts, $disabledTexts );
+
+ $navClass = htmlspecialchars( $this->getNavClass() );
+ $s = "<table class=\"$navClass\" align=\"center\" cellpadding=\"3\"><tr>\n";
+ $cellAttrs = 'valign="top" align="center" width="' . 100 / count( $links ) . '%"';
+ foreach ( $labels as $type => $label ) {
+ $s .= "<td $cellAttrs>{$links[$type]}</td>\n";
+ }
+ $s .= "</tr></table>\n";
+ return $s;
+ }
+
+ /**
+ * Get a <select> element which has options for each of the allowed limits
+ */
+ function getLimitSelect() {
+ global $wgLang;
+ $s = "<select name=\"limit\">";
+ foreach ( $this->mLimitsShown as $limit ) {
+ $selected = $limit == $this->mLimit ? 'selected="selected"' : '';
+ $formattedLimit = $wgLang->formatNum( $limit );
+ $s .= "<option value=\"$limit\" $selected>$formattedLimit</option>\n";
+ }
+ $s .= "</select>";
+ return $s;
+ }
+
+ /**
+ * Get <input type="hidden"> elements for use in a method="get" form.
+ * Resubmits all defined elements of the $_GET array, except for a
+ * blacklist, passed in the $blacklist parameter.
+ */
+ function getHiddenFields( $blacklist = array() ) {
+ $blacklist = (array)$blacklist;
+ $query = $_GET;
+ foreach ( $blacklist as $name ) {
+ unset( $query[$name] );
+ }
+ $s = '';
+ foreach ( $query as $name => $value ) {
+ $encName = htmlspecialchars( $name );
+ $encValue = htmlspecialchars( $value );
+ $s .= "<input type=\"hidden\" name=\"$encName\" value=\"$encValue\"/>\n";
+ }
+ return $s;
+ }
+
+ /**
+ * Get a form containing a limit selection dropdown
+ */
+ function getLimitForm() {
+ # Make the select with some explanatory text
+ $url = $this->getTitle()->escapeLocalURL();
+ $msgSubmit = wfMsgHtml( 'table_pager_limit_submit' );
+ return
+ "<form method=\"get\" action=\"$url\">" .
+ wfMsgHtml( 'table_pager_limit', $this->getLimitSelect() ) .
+ "\n<input type=\"submit\" value=\"$msgSubmit\"/>\n" .
+ $this->getHiddenFields( 'limit' ) .
+ "</form>\n";
+ }
+
+ /**
+ * Return true if the named field should be sortable by the UI, false otherwise
+ * @param string $field
+ */
+ abstract function isFieldSortable( $field );
+
+ /**
+ * Format a table cell. The return value should be HTML, but use an empty string
+ * not &nbsp; for empty cells. Do not include the <td> and </td>.
+ *
+ * @param string $name The database field name
+ * @param string $value The value retrieved from the database
+ *
+ * The current result row is available as $this->mCurrentRow, in case you need
+ * more context.
+ */
+ abstract function formatValue( $name, $value );
+
+ /**
+ * The database field name used as a default sort order
+ */
+ abstract function getDefaultSort();
+
+ /**
+ * An array mapping database field names to a textual description of the field
+ * name, for use in the table header. The description should be plain text, it
+ * will be HTML-escaped later.
+ */
+ abstract function getFieldNames();
+}
+?>
diff --git a/includes/Parser.php b/includes/Parser.php
new file mode 100644
index 000000000000..8d67279dbea0
--- /dev/null
+++ b/includes/Parser.php
@@ -0,0 +1,4974 @@
+<?php
+/**
+ * File for Parser and related classes
+ *
+ * @package MediaWiki
+ * @subpackage Parser
+ */
+
+/**
+ * Update this version number when the ParserOutput format
+ * changes in an incompatible way, so the parser cache
+ * can automatically discard old data.
+ */
+define( 'MW_PARSER_VERSION', '1.6.1' );
+
+define( 'RLH_FOR_UPDATE', 1 );
+
+# Allowed values for $mOutputType
+define( 'OT_HTML', 1 );
+define( 'OT_WIKI', 2 );
+define( 'OT_MSG' , 3 );
+define( 'OT_PREPROCESS', 4 );
+
+# Flags for setFunctionHook
+define( 'SFH_NO_HASH', 1 );
+
+# string parameter for extractTags which will cause it
+# to strip HTML comments in addition to regular
+# <XML>-style tags. This should not be anything we
+# may want to use in wikisyntax
+define( 'STRIP_COMMENTS', 'HTMLCommentStrip' );
+
+# Constants needed for external link processing
+define( 'HTTP_PROTOCOLS', 'http:\/\/|https:\/\/' );
+# Everything except bracket, space, or control characters
+define( 'EXT_LINK_URL_CLASS', '[^][<>"\\x00-\\x20\\x7F]' );
+# Including space, but excluding newlines
+define( 'EXT_LINK_TEXT_CLASS', '[^\]\\x0a\\x0d]' );
+define( 'EXT_IMAGE_FNAME_CLASS', '[A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]' );
+define( 'EXT_IMAGE_EXTENSIONS', 'gif|png|jpg|jpeg' );
+define( 'EXT_LINK_BRACKETED', '/\[(\b(' . wfUrlProtocols() . ')'.
+ EXT_LINK_URL_CLASS.'+) *('.EXT_LINK_TEXT_CLASS.'*?)\]/S' );
+define( 'EXT_IMAGE_REGEX',
+ '/^('.HTTP_PROTOCOLS.')'. # Protocol
+ '('.EXT_LINK_URL_CLASS.'+)\\/'. # Hostname and path
+ '('.EXT_IMAGE_FNAME_CLASS.'+)\\.((?i)'.EXT_IMAGE_EXTENSIONS.')$/S' # Filename
+);
+
+// State constants for the definition list colon extraction
+define( 'MW_COLON_STATE_TEXT', 0 );
+define( 'MW_COLON_STATE_TAG', 1 );
+define( 'MW_COLON_STATE_TAGSTART', 2 );
+define( 'MW_COLON_STATE_CLOSETAG', 3 );
+define( 'MW_COLON_STATE_TAGSLASH', 4 );
+define( 'MW_COLON_STATE_COMMENT', 5 );
+define( 'MW_COLON_STATE_COMMENTDASH', 6 );
+define( 'MW_COLON_STATE_COMMENTDASHDASH', 7 );
+
+/**
+ * PHP Parser
+ *
+ * Processes wiki markup
+ *
+ * <pre>
+ * There are four main entry points into the Parser class:
+ * parse()
+ * produces HTML output
+ * preSaveTransform().
+ * produces altered wiki markup.
+ * transformMsg()
+ * performs brace substitution on MediaWiki messages
+ * preprocess()
+ * removes HTML comments and expands templates
+ *
+ * Globals used:
+ * objects: $wgLang, $wgContLang
+ *
+ * NOT $wgArticle, $wgUser or $wgTitle. Keep them away!
+ *
+ * settings:
+ * $wgUseTex*, $wgUseDynamicDates*, $wgInterwikiMagic*,
+ * $wgNamespacesWithSubpages, $wgAllowExternalImages*,
+ * $wgLocaltimezone, $wgAllowSpecialInclusion*,
+ * $wgMaxArticleSize*
+ *
+ * * only within ParserOptions
+ * </pre>
+ *
+ * @package MediaWiki
+ */
+class Parser
+{
+ /**#@+
+ * @private
+ */
+ # Persistent:
+ var $mTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables;
+
+ # Cleared with clearState():
+ var $mOutput, $mAutonumber, $mDTopen, $mStripState;
+ var $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
+ var $mInterwikiLinkHolders, $mLinkHolders, $mUniqPrefix;
+ var $mIncludeSizes, $mDefaultSort;
+ var $mTemplates, // cache of already loaded templates, avoids
+ // multiple SQL queries for the same string
+ $mTemplatePath; // stores an unsorted hash of all the templates already loaded
+ // in this path. Used for loop detection.
+
+ # Temporary
+ # These are variables reset at least once per parse regardless of $clearState
+ var $mOptions, // ParserOptions object
+ $mTitle, // Title context, used for self-link rendering and similar things
+ $mOutputType, // Output type, one of the OT_xxx constants
+ $ot, // Shortcut alias, see setOutputType()
+ $mRevisionId, // ID to display in {{REVISIONID}} tags
+ $mRevisionTimestamp, // The timestamp of the specified revision ID
+ $mRevIdForTs; // The revision ID which was used to fetch the timestamp
+
+ /**#@-*/
+
+ /**
+ * Constructor
+ *
+ * @public
+ */
+ function Parser() {
+ $this->mTagHooks = array();
+ $this->mFunctionHooks = array();
+ $this->mFunctionSynonyms = array( 0 => array(), 1 => array() );
+ $this->mFirstCall = true;
+ }
+
+ /**
+ * Do various kinds of initialisation on the first call of the parser
+ */
+ function firstCallInit() {
+ if ( !$this->mFirstCall ) {
+ return;
+ }
+
+ wfProfileIn( __METHOD__ );
+ global $wgAllowDisplayTitle, $wgAllowSlowParserFunctions;
+
+ $this->setHook( 'pre', array( $this, 'renderPreTag' ) );
+
+ $this->setFunctionHook( 'int', array( 'CoreParserFunctions', 'intFunction' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'ns', array( 'CoreParserFunctions', 'ns' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'urlencode', array( 'CoreParserFunctions', 'urlencode' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'lcfirst', array( 'CoreParserFunctions', 'lcfirst' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'ucfirst', array( 'CoreParserFunctions', 'ucfirst' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'lc', array( 'CoreParserFunctions', 'lc' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'uc', array( 'CoreParserFunctions', 'uc' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'localurl', array( 'CoreParserFunctions', 'localurl' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'localurle', array( 'CoreParserFunctions', 'localurle' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'fullurl', array( 'CoreParserFunctions', 'fullurl' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'fullurle', array( 'CoreParserFunctions', 'fullurle' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'formatnum', array( 'CoreParserFunctions', 'formatnum' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'grammar', array( 'CoreParserFunctions', 'grammar' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'plural', array( 'CoreParserFunctions', 'plural' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'numberofpages', array( 'CoreParserFunctions', 'numberofpages' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'numberofusers', array( 'CoreParserFunctions', 'numberofusers' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'numberofarticles', array( 'CoreParserFunctions', 'numberofarticles' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'numberoffiles', array( 'CoreParserFunctions', 'numberoffiles' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'numberofadmins', array( 'CoreParserFunctions', 'numberofadmins' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'language', array( 'CoreParserFunctions', 'language' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'padleft', array( 'CoreParserFunctions', 'padleft' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'padright', array( 'CoreParserFunctions', 'padright' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'anchorencode', array( 'CoreParserFunctions', 'anchorencode' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'special', array( 'CoreParserFunctions', 'special' ) );
+ $this->setFunctionHook( 'defaultsort', array( 'CoreParserFunctions', 'defaultsort' ), SFH_NO_HASH );
+
+ if ( $wgAllowDisplayTitle ) {
+ $this->setFunctionHook( 'displaytitle', array( 'CoreParserFunctions', 'displaytitle' ), SFH_NO_HASH );
+ }
+ if ( $wgAllowSlowParserFunctions ) {
+ $this->setFunctionHook( 'pagesinnamespace', array( 'CoreParserFunctions', 'pagesinnamespace' ), SFH_NO_HASH );
+ }
+
+ $this->initialiseVariables();
+ $this->mFirstCall = false;
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Clear Parser state
+ *
+ * @private
+ */
+ function clearState() {
+ wfProfileIn( __METHOD__ );
+ if ( $this->mFirstCall ) {
+ $this->firstCallInit();
+ }
+ $this->mOutput = new ParserOutput;
+ $this->mAutonumber = 0;
+ $this->mLastSection = '';
+ $this->mDTopen = false;
+ $this->mIncludeCount = array();
+ $this->mStripState = new StripState;
+ $this->mArgStack = array();
+ $this->mInPre = false;
+ $this->mInterwikiLinkHolders = array(
+ 'texts' => array(),
+ 'titles' => array()
+ );
+ $this->mLinkHolders = array(
+ 'namespaces' => array(),
+ 'dbkeys' => array(),
+ 'queries' => array(),
+ 'texts' => array(),
+ 'titles' => array()
+ );
+ $this->mRevisionTimestamp = $this->mRevisionId = null;
+
+ /**
+ * Prefix for temporary replacement strings for the multipass parser.
+ * \x07 should never appear in input as it's disallowed in XML.
+ * Using it at the front also gives us a little extra robustness
+ * since it shouldn't match when butted up against identifier-like
+ * string constructs.
+ */
+ $this->mUniqPrefix = "\x07UNIQ" . Parser::getRandomString();
+
+ # Clear these on every parse, bug 4549
+ $this->mTemplates = array();
+ $this->mTemplatePath = array();
+
+ $this->mShowToc = true;
+ $this->mForceTocPosition = false;
+ $this->mIncludeSizes = array(
+ 'pre-expand' => 0,
+ 'post-expand' => 0,
+ 'arg' => 0
+ );
+ $this->mDefaultSort = false;
+
+ wfRunHooks( 'ParserClearState', array( &$this ) );
+ wfProfileOut( __METHOD__ );
+ }
+
+ function setOutputType( $ot ) {
+ $this->mOutputType = $ot;
+ // Shortcut alias
+ $this->ot = array(
+ 'html' => $ot == OT_HTML,
+ 'wiki' => $ot == OT_WIKI,
+ 'msg' => $ot == OT_MSG,
+ 'pre' => $ot == OT_PREPROCESS,
+ );
+ }
+
+ /**
+ * Accessor for mUniqPrefix.
+ *
+ * @public
+ */
+ function uniqPrefix() {
+ return $this->mUniqPrefix;
+ }
+
+ /**
+ * Convert wikitext to HTML
+ * Do not call this function recursively.
+ *
+ * @private
+ * @param string $text Text we want to parse
+ * @param Title &$title A title object
+ * @param array $options
+ * @param boolean $linestart
+ * @param boolean $clearState
+ * @param int $revid number to pass in {{REVISIONID}}
+ * @return ParserOutput a ParserOutput
+ */
+ function parse( $text, &$title, $options, $linestart = true, $clearState = true, $revid = null ) {
+ /**
+ * First pass--just handle <nowiki> sections, pass the rest off
+ * to internalParse() which does all the real work.
+ */
+
+ global $wgUseTidy, $wgAlwaysUseTidy, $wgContLang;
+ $fname = 'Parser::parse-' . wfGetCaller();
+ wfProfileIn( __METHOD__ );
+ wfProfileIn( $fname );
+
+ if ( $clearState ) {
+ $this->clearState();
+ }
+
+ $this->mOptions = $options;
+ $this->mTitle =& $title;
+ $oldRevisionId = $this->mRevisionId;
+ $oldRevisionTimestamp = $this->mRevisionTimestamp;
+ if( $revid !== null ) {
+ $this->mRevisionId = $revid;
+ $this->mRevisionTimestamp = null;
+ }
+ $this->setOutputType( OT_HTML );
+ wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
+ $text = $this->strip( $text, $this->mStripState );
+ wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
+ $text = $this->internalParse( $text );
+ $text = $this->mStripState->unstripGeneral( $text );
+
+ # Clean up special characters, only run once, next-to-last before doBlockLevels
+ $fixtags = array(
+ # french spaces, last one Guillemet-left
+ # only if there is something before the space
+ '/(.) (?=\\?|:|;|!|\\302\\273)/' => '\\1&nbsp;\\2',
+ # french spaces, Guillemet-right
+ '/(\\302\\253) /' => '\\1&nbsp;',
+ );
+ $text = preg_replace( array_keys($fixtags), array_values($fixtags), $text );
+
+ # only once and last
+ $text = $this->doBlockLevels( $text, $linestart );
+
+ $this->replaceLinkHolders( $text );
+
+ # the position of the parserConvert() call should not be changed. it
+ # assumes that the links are all replaced and the only thing left
+ # is the <nowiki> mark.
+ # Side-effects: this calls $this->mOutput->setTitleText()
+ $text = $wgContLang->parserConvert( $text, $this );
+
+ $text = $this->mStripState->unstripNoWiki( $text );
+
+ wfRunHooks( 'ParserBeforeTidy', array( &$this, &$text ) );
+
+ $text = Sanitizer::normalizeCharReferences( $text );
+
+ if (($wgUseTidy and $this->mOptions->mTidy) or $wgAlwaysUseTidy) {
+ $text = Parser::tidy($text);
+ } else {
+ # attempt to sanitize at least some nesting problems
+ # (bug #2702 and quite a few others)
+ $tidyregs = array(
+ # ''Something [http://www.cool.com cool''] -->
+ # <i>Something</i><a href="http://www.cool.com"..><i>cool></i></a>
+ '/(<([bi])>)(<([bi])>)?([^<]*)(<\/?a[^<]*>)([^<]*)(<\/\\4>)?(<\/\\2>)/' =>
+ '\\1\\3\\5\\8\\9\\6\\1\\3\\7\\8\\9',
+ # fix up an anchor inside another anchor, only
+ # at least for a single single nested link (bug 3695)
+ '/(<a[^>]+>)([^<]*)(<a[^>]+>[^<]*)<\/a>(.*)<\/a>/' =>
+ '\\1\\2</a>\\3</a>\\1\\4</a>',
+ # fix div inside inline elements- doBlockLevels won't wrap a line which
+ # contains a div, so fix it up here; replace
+ # div with escaped text
+ '/(<([aib]) [^>]+>)([^<]*)(<div([^>]*)>)(.*)(<\/div>)([^<]*)(<\/\\2>)/' =>
+ '\\1\\3&lt;div\\5&gt;\\6&lt;/div&gt;\\8\\9',
+ # remove empty italic or bold tag pairs, some
+ # introduced by rules above
+ '/<([bi])><\/\\1>/' => '',
+ );
+
+ $text = preg_replace(
+ array_keys( $tidyregs ),
+ array_values( $tidyregs ),
+ $text );
+ }
+
+ wfRunHooks( 'ParserAfterTidy', array( &$this, &$text ) );
+
+ # Information on include size limits, for the benefit of users who try to skirt them
+ if ( max( $this->mIncludeSizes ) > 1000 ) {
+ $max = $this->mOptions->getMaxIncludeSize();
+ $text .= "<!-- \n" .
+ "Pre-expand include size: {$this->mIncludeSizes['pre-expand']} bytes\n" .
+ "Post-expand include size: {$this->mIncludeSizes['post-expand']} bytes\n" .
+ "Template argument size: {$this->mIncludeSizes['arg']} bytes\n" .
+ "Maximum: $max bytes\n" .
+ "-->\n";
+ }
+ $this->mOutput->setText( $text );
+ $this->mRevisionId = $oldRevisionId;
+ $this->mRevisionTimestamp = $oldRevisionTimestamp;
+ wfProfileOut( $fname );
+ wfProfileOut( __METHOD__ );
+
+ return $this->mOutput;
+ }
+
+ /**
+ * Recursive parser entry point that can be called from an extension tag
+ * hook.
+ */
+ function recursiveTagParse( $text ) {
+ wfProfileIn( __METHOD__ );
+ wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
+ $text = $this->strip( $text, $this->mStripState );
+ wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
+ $text = $this->internalParse( $text );
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * Expand templates and variables in the text, producing valid, static wikitext.
+ * Also removes comments.
+ */
+ function preprocess( $text, $title, $options ) {
+ wfProfileIn( __METHOD__ );
+ $this->clearState();
+ $this->setOutputType( OT_PREPROCESS );
+ $this->mOptions = $options;
+ $this->mTitle = $title;
+ wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
+ $text = $this->strip( $text, $this->mStripState );
+ wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
+ if ( $this->mOptions->getRemoveComments() ) {
+ $text = Sanitizer::removeHTMLcomments( $text );
+ }
+ $text = $this->replaceVariables( $text );
+ $text = $this->mStripState->unstripBoth( $text );
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * Get a random string
+ *
+ * @private
+ * @static
+ */
+ function getRandomString() {
+ return dechex(mt_rand(0, 0x7fffffff)) . dechex(mt_rand(0, 0x7fffffff));
+ }
+
+ function &getTitle() { return $this->mTitle; }
+ function getOptions() { return $this->mOptions; }
+
+ function getFunctionLang() {
+ global $wgLang, $wgContLang;
+ return $this->mOptions->getInterfaceMessage() ? $wgLang : $wgContLang;
+ }
+
+ /**
+ * Replaces all occurrences of HTML-style comments and the given tags
+ * in the text with a random marker and returns teh next text. The output
+ * parameter $matches will be an associative array filled with data in
+ * the form:
+ * 'UNIQ-xxxxx' => array(
+ * 'element',
+ * 'tag content',
+ * array( 'param' => 'x' ),
+ * '<element param="x">tag content</element>' ) )
+ *
+ * @param $elements list of element names. Comments are always extracted.
+ * @param $text Source text string.
+ * @param $uniq_prefix
+ *
+ * @private
+ * @static
+ */
+ function extractTagsAndParams($elements, $text, &$matches, $uniq_prefix = ''){
+ static $n = 1;
+ $stripped = '';
+ $matches = array();
+
+ $taglist = implode( '|', $elements );
+ $start = "/<($taglist)(\\s+[^>]*?|\\s*?)(\/?>)|<(!--)/i";
+
+ while ( '' != $text ) {
+ $p = preg_split( $start, $text, 2, PREG_SPLIT_DELIM_CAPTURE );
+ $stripped .= $p[0];
+ if( count( $p ) < 5 ) {
+ break;
+ }
+ if( count( $p ) > 5 ) {
+ // comment
+ $element = $p[4];
+ $attributes = '';
+ $close = '';
+ $inside = $p[5];
+ } else {
+ // tag
+ $element = $p[1];
+ $attributes = $p[2];
+ $close = $p[3];
+ $inside = $p[4];
+ }
+
+ $marker = "$uniq_prefix-$element-" . sprintf('%08X', $n++) . '-QINU';
+ $stripped .= $marker;
+
+ if ( $close === '/>' ) {
+ // Empty element tag, <tag />
+ $content = null;
+ $text = $inside;
+ $tail = null;
+ } else {
+ if( $element == '!--' ) {
+ $end = '/(-->)/';
+ } else {
+ $end = "/(<\\/$element\\s*>)/i";
+ }
+ $q = preg_split( $end, $inside, 2, PREG_SPLIT_DELIM_CAPTURE );
+ $content = $q[0];
+ if( count( $q ) < 3 ) {
+ # No end tag -- let it run out to the end of the text.
+ $tail = '';
+ $text = '';
+ } else {
+ $tail = $q[1];
+ $text = $q[2];
+ }
+ }
+
+ $matches[$marker] = array( $element,
+ $content,
+ Sanitizer::decodeTagAttributes( $attributes ),
+ "<$element$attributes$close$content$tail" );
+ }
+ return $stripped;
+ }
+
+ /**
+ * Strips and renders nowiki, pre, math, hiero
+ * If $render is set, performs necessary rendering operations on plugins
+ * Returns the text, and fills an array with data needed in unstrip()
+ *
+ * @param StripState $state
+ *
+ * @param bool $stripcomments when set, HTML comments <!-- like this -->
+ * will be stripped in addition to other tags. This is important
+ * for section editing, where these comments cause confusion when
+ * counting the sections in the wikisource
+ *
+ * @param array dontstrip contains tags which should not be stripped;
+ * used to prevent stipping of <gallery> when saving (fixes bug 2700)
+ *
+ * @private
+ */
+ function strip( $text, $state, $stripcomments = false , $dontstrip = array () ) {
+ global $wgContLang;
+ wfProfileIn( __METHOD__ );
+ $render = ($this->mOutputType == OT_HTML);
+
+ $uniq_prefix = $this->mUniqPrefix;
+ $commentState = new ReplacementArray;
+ $nowikiItems = array();
+ $generalItems = array();
+
+ $elements = array_merge(
+ array( 'nowiki', 'gallery' ),
+ array_keys( $this->mTagHooks ) );
+ global $wgRawHtml;
+ if( $wgRawHtml ) {
+ $elements[] = 'html';
+ }
+ if( $this->mOptions->getUseTeX() ) {
+ $elements[] = 'math';
+ }
+
+ # Removing $dontstrip tags from $elements list (currently only 'gallery', fixing bug 2700)
+ foreach ( $elements AS $k => $v ) {
+ if ( !in_array ( $v , $dontstrip ) ) continue;
+ unset ( $elements[$k] );
+ }
+
+ $matches = array();
+ $text = Parser::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
+
+ foreach( $matches as $marker => $data ) {
+ list( $element, $content, $params, $tag ) = $data;
+ if( $render ) {
+ $tagName = strtolower( $element );
+ wfProfileIn( __METHOD__."-render-$tagName" );
+ switch( $tagName ) {
+ case '!--':
+ // Comment
+ if( substr( $tag, -3 ) == '-->' ) {
+ $output = $tag;
+ } else {
+ // Unclosed comment in input.
+ // Close it so later stripping can remove it
+ $output = "$tag-->";
+ }
+ break;
+ case 'html':
+ if( $wgRawHtml ) {
+ $output = $content;
+ break;
+ }
+ // Shouldn't happen otherwise. :)
+ case 'nowiki':
+ $output = Xml::escapeTagsOnly( $content );
+ break;
+ case 'math':
+ $output = $wgContLang->armourMath( MathRenderer::renderMath( $content ) );
+ break;
+ case 'gallery':
+ $output = $this->renderImageGallery( $content, $params );
+ break;
+ default:
+ if( isset( $this->mTagHooks[$tagName] ) ) {
+ $output = call_user_func_array( $this->mTagHooks[$tagName],
+ array( $content, $params, $this ) );
+ } else {
+ throw new MWException( "Invalid call hook $element" );
+ }
+ }
+ wfProfileOut( __METHOD__."-render-$tagName" );
+ } else {
+ // Just stripping tags; keep the source
+ $output = $tag;
+ }
+
+ // Unstrip the output, to support recursive strip() calls
+ $output = $state->unstripBoth( $output );
+
+ if( !$stripcomments && $element == '!--' ) {
+ $commentState->setPair( $marker, $output );
+ } elseif ( $element == 'html' || $element == 'nowiki' ) {
+ $nowikiItems[$marker] = $output;
+ } else {
+ $generalItems[$marker] = $output;
+ }
+ }
+ # Add the new items to the state
+ # We do this after the loop instead of during it to avoid slowing
+ # down the recursive unstrip
+ $state->nowiki->mergeArray( $nowikiItems );
+ $state->general->mergeArray( $generalItems );
+
+ # Unstrip comments unless explicitly told otherwise.
+ # (The comments are always stripped prior to this point, so as to
+ # not invoke any extension tags / parser hooks contained within
+ # a comment.)
+ if ( !$stripcomments ) {
+ // Put them all back and forget them
+ $text = $commentState->replace( $text );
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * Restores pre, math, and other extensions removed by strip()
+ *
+ * always call unstripNoWiki() after this one
+ * @private
+ * @deprecated use $this->mStripState->unstrip()
+ */
+ function unstrip( $text, $state ) {
+ return $state->unstripGeneral( $text );
+ }
+
+ /**
+ * Always call this after unstrip() to preserve the order
+ *
+ * @private
+ * @deprecated use $this->mStripState->unstrip()
+ */
+ function unstripNoWiki( $text, $state ) {
+ return $state->unstripNoWiki( $text );
+ }
+
+ /**
+ * @deprecated use $this->mStripState->unstripBoth()
+ */
+ function unstripForHTML( $text ) {
+ return $this->mStripState->unstripBoth( $text );
+ }
+
+ /**
+ * Add an item to the strip state
+ * Returns the unique tag which must be inserted into the stripped text
+ * The tag will be replaced with the original text in unstrip()
+ *
+ * @private
+ */
+ function insertStripItem( $text, &$state ) {
+ $rnd = $this->mUniqPrefix . '-item' . Parser::getRandomString();
+ $state->general->setPair( $rnd, $text );
+ return $rnd;
+ }
+
+ /**
+ * Interface with html tidy, used if $wgUseTidy = true.
+ * If tidy isn't able to correct the markup, the original will be
+ * returned in all its glory with a warning comment appended.
+ *
+ * Either the external tidy program or the in-process tidy extension
+ * will be used depending on availability. Override the default
+ * $wgTidyInternal setting to disable the internal if it's not working.
+ *
+ * @param string $text Hideous HTML input
+ * @return string Corrected HTML output
+ * @public
+ * @static
+ */
+ function tidy( $text ) {
+ global $wgTidyInternal;
+ $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.
+' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>'.
+'<head><title>test</title></head><body>'.$text.'</body></html>';
+ if( $wgTidyInternal ) {
+ $correctedtext = Parser::internalTidy( $wrappedtext );
+ } else {
+ $correctedtext = Parser::externalTidy( $wrappedtext );
+ }
+ if( is_null( $correctedtext ) ) {
+ wfDebug( "Tidy error detected!\n" );
+ return $text . "\n<!-- Tidy found serious XHTML errors -->\n";
+ }
+ return $correctedtext;
+ }
+
+ /**
+ * Spawn an external HTML tidy process and get corrected markup back from it.
+ *
+ * @private
+ * @static
+ */
+ function externalTidy( $text ) {
+ global $wgTidyConf, $wgTidyBin, $wgTidyOpts;
+ $fname = 'Parser::externalTidy';
+ wfProfileIn( $fname );
+
+ $cleansource = '';
+ $opts = ' -utf8';
+
+ $descriptorspec = array(
+ 0 => array('pipe', 'r'),
+ 1 => array('pipe', 'w'),
+ 2 => array('file', '/dev/null', 'a')
+ );
+ $pipes = array();
+ $process = proc_open("$wgTidyBin -config $wgTidyConf $wgTidyOpts$opts", $descriptorspec, $pipes);
+ if (is_resource($process)) {
+ // Theoretically, this style of communication could cause a deadlock
+ // here. If the stdout buffer fills up, then writes to stdin could
+ // block. This doesn't appear to happen with tidy, because tidy only
+ // writes to stdout after it's finished reading from stdin. Search
+ // for tidyParseStdin and tidySaveStdout in console/tidy.c
+ fwrite($pipes[0], $text);
+ fclose($pipes[0]);
+ while (!feof($pipes[1])) {
+ $cleansource .= fgets($pipes[1], 1024);
+ }
+ fclose($pipes[1]);
+ proc_close($process);
+ }
+
+ wfProfileOut( $fname );
+
+ if( $cleansource == '' && $text != '') {
+ // Some kind of error happened, so we couldn't get the corrected text.
+ // Just give up; we'll use the source text and append a warning.
+ return null;
+ } else {
+ return $cleansource;
+ }
+ }
+
+ /**
+ * Use the HTML tidy PECL extension to use the tidy library in-process,
+ * saving the overhead of spawning a new process. Currently written to
+ * the PHP 4.3.x version of the extension, may not work on PHP 5.
+ *
+ * 'pear install tidy' should be able to compile the extension module.
+ *
+ * @private
+ * @static
+ */
+ function internalTidy( $text ) {
+ global $wgTidyConf;
+ $fname = 'Parser::internalTidy';
+ wfProfileIn( $fname );
+
+ tidy_load_config( $wgTidyConf );
+ tidy_set_encoding( 'utf8' );
+ tidy_parse_string( $text );
+ tidy_clean_repair();
+ if( tidy_get_status() == 2 ) {
+ // 2 is magic number for fatal error
+ // http://www.php.net/manual/en/function.tidy-get-status.php
+ $cleansource = null;
+ } else {
+ $cleansource = tidy_get_output();
+ }
+ wfProfileOut( $fname );
+ return $cleansource;
+ }
+
+ /**
+ * parse the wiki syntax used to render tables
+ *
+ * @private
+ */
+ function doTableStuff ( $text ) {
+ $fname = 'Parser::doTableStuff';
+ wfProfileIn( $fname );
+
+ $lines = explode ( "\n" , $text );
+ $td_history = array (); // Is currently a td tag open?
+ $last_tag_history = array (); // Save history of last lag activated (td, th or caption)
+ $tr_history = array (); // Is currently a tr tag open?
+ $tr_attributes = array (); // history of tr attributes
+ $has_opened_tr = array(); // Did this table open a <tr> element?
+ $indent_level = 0; // indent level of the table
+ foreach ( $lines as $key => $line )
+ {
+ $line = trim ( $line );
+
+ if( $line == '' ) { // empty line, go to next line
+ continue;
+ }
+ $first_character = $line{0};
+ $matches = array();
+
+ if ( preg_match( '/^(:*)\{\|(.*)$/' , $line , $matches ) ) {
+ // First check if we are starting a new table
+ $indent_level = strlen( $matches[1] );
+
+ $attributes = $this->mStripState->unstripBoth( $matches[2] );
+ $attributes = Sanitizer::fixTagAttributes ( $attributes , 'table' );
+
+ $lines[$key] = str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>";
+ array_push ( $td_history , false );
+ array_push ( $last_tag_history , '' );
+ array_push ( $tr_history , false );
+ array_push ( $tr_attributes , '' );
+ array_push ( $has_opened_tr , false );
+ } else if ( count ( $td_history ) == 0 ) {
+ // Don't do any of the following
+ continue;
+ } else if ( substr ( $line , 0 , 2 ) == '|}' ) {
+ // We are ending a table
+ $line = '</table>' . substr ( $line , 2 );
+ $last_tag = array_pop ( $last_tag_history );
+
+ if ( !array_pop ( $has_opened_tr ) ) {
+ $line = "<tr><td></td></tr>{$line}";
+ }
+
+ if ( array_pop ( $tr_history ) ) {
+ $line = "</tr>{$line}";
+ }
+
+ if ( array_pop ( $td_history ) ) {
+ $line = "</{$last_tag}>{$line}";
+ }
+ array_pop ( $tr_attributes );
+ $lines[$key] = $line . str_repeat( '</dd></dl>' , $indent_level );
+ } else if ( substr ( $line , 0 , 2 ) == '|-' ) {
+ // Now we have a table row
+ $line = preg_replace( '#^\|-+#', '', $line );
+
+ // Whats after the tag is now only attributes
+ $attributes = $this->mStripState->unstripBoth( $line );
+ $attributes = Sanitizer::fixTagAttributes ( $attributes , 'tr' );
+ array_pop ( $tr_attributes );
+ array_push ( $tr_attributes , $attributes );
+
+ $line = '';
+ $last_tag = array_pop ( $last_tag_history );
+ array_pop ( $has_opened_tr );
+ array_push ( $has_opened_tr , true );
+
+ if ( array_pop ( $tr_history ) ) {
+ $line = '</tr>';
+ }
+
+ if ( array_pop ( $td_history ) ) {
+ $line = "</{$last_tag}>{$line}";
+ }
+
+ $lines[$key] = $line;
+ array_push ( $tr_history , false );
+ array_push ( $td_history , false );
+ array_push ( $last_tag_history , '' );
+ }
+ else if ( $first_character == '|' || $first_character == '!' || substr ( $line , 0 , 2 ) == '|+' ) {
+ // This might be cell elements, td, th or captions
+ if ( substr ( $line , 0 , 2 ) == '|+' ) {
+ $first_character = '+';
+ $line = substr ( $line , 1 );
+ }
+
+ $line = substr ( $line , 1 );
+
+ if ( $first_character == '!' ) {
+ $line = str_replace ( '!!' , '||' , $line );
+ }
+
+ // Split up multiple cells on the same line.
+ // FIXME : This can result in improper nesting of tags processed
+ // by earlier parser steps, but should avoid splitting up eg
+ // attribute values containing literal "||".
+ $cells = StringUtils::explodeMarkup( '||' , $line );
+
+ $lines[$key] = '';
+
+ // Loop through each table cell
+ foreach ( $cells as $cell )
+ {
+ $previous = '';
+ if ( $first_character != '+' )
+ {
+ $tr_after = array_pop ( $tr_attributes );
+ if ( !array_pop ( $tr_history ) ) {
+ $previous = "<tr{$tr_after}>\n";
+ }
+ array_push ( $tr_history , true );
+ array_push ( $tr_attributes , '' );
+ array_pop ( $has_opened_tr );
+ array_push ( $has_opened_tr , true );
+ }
+
+ $last_tag = array_pop ( $last_tag_history );
+
+ if ( array_pop ( $td_history ) ) {
+ $previous = "</{$last_tag}>{$previous}";
+ }
+
+ if ( $first_character == '|' ) {
+ $last_tag = 'td';
+ } else if ( $first_character == '!' ) {
+ $last_tag = 'th';
+ } else if ( $first_character == '+' ) {
+ $last_tag = 'caption';
+ } else {
+ $last_tag = '';
+ }
+
+ array_push ( $last_tag_history , $last_tag );
+
+ // A cell could contain both parameters and data
+ $cell_data = explode ( '|' , $cell , 2 );
+
+ // Bug 553: Note that a '|' inside an invalid link should not
+ // be mistaken as delimiting cell parameters
+ if ( strpos( $cell_data[0], '[[' ) !== false ) {
+ $cell = "{$previous}<{$last_tag}>{$cell}";
+ } else if ( count ( $cell_data ) == 1 )
+ $cell = "{$previous}<{$last_tag}>{$cell_data[0]}";
+ else {
+ $attributes = $this->mStripState->unstripBoth( $cell_data[0] );
+ $attributes = Sanitizer::fixTagAttributes( $attributes , $last_tag );
+ $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}";
+ }
+
+ $lines[$key] .= $cell;
+ array_push ( $td_history , true );
+ }
+ }
+ }
+
+ // Closing open td, tr && table
+ while ( count ( $td_history ) > 0 )
+ {
+ if ( array_pop ( $td_history ) ) {
+ $lines[] = '</td>' ;
+ }
+ if ( array_pop ( $tr_history ) ) {
+ $lines[] = '</tr>' ;
+ }
+ if ( !array_pop ( $has_opened_tr ) ) {
+ $lines[] = "<tr><td></td></tr>" ;
+ }
+
+ $lines[] = '</table>' ;
+ }
+
+ $output = implode ( "\n" , $lines ) ;
+
+ // special case: don't return empty table
+ if( $output == "<table>\n<tr><td></td></tr>\n</table>" ) {
+ $output = '';
+ }
+
+ wfProfileOut( $fname );
+
+ return $output;
+ }
+
+ /**
+ * Helper function for parse() that transforms wiki markup into
+ * HTML. Only called for $mOutputType == OT_HTML.
+ *
+ * @private
+ */
+ function internalParse( $text ) {
+ $args = array();
+ $isMain = true;
+ $fname = 'Parser::internalParse';
+ wfProfileIn( $fname );
+
+ # Hook to suspend the parser in this state
+ if ( !wfRunHooks( 'ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ) ) ) {
+ wfProfileOut( $fname );
+ return $text ;
+ }
+
+ # Remove <noinclude> tags and <includeonly> sections
+ $text = strtr( $text, array( '<onlyinclude>' => '' , '</onlyinclude>' => '' ) );
+ $text = strtr( $text, array( '<noinclude>' => '', '</noinclude>' => '') );
+ $text = StringUtils::delimiterReplace( '<includeonly>', '</includeonly>', '', $text );
+
+ $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ) );
+
+ $text = $this->replaceVariables( $text, $args );
+
+ // Tables need to come after variable replacement for things to work
+ // properly; putting them before other transformations should keep
+ // exciting things like link expansions from showing up in surprising
+ // places.
+ $text = $this->doTableStuff( $text );
+
+ $text = preg_replace( '/(^|\n)-----*/', '\\1<hr />', $text );
+
+ $text = $this->stripToc( $text );
+ $this->stripNoGallery( $text );
+ $text = $this->doHeadings( $text );
+ if($this->mOptions->getUseDynamicDates()) {
+ $df =& DateFormatter::getInstance();
+ $text = $df->reformat( $this->mOptions->getDateFormat(), $text );
+ }
+ $text = $this->doAllQuotes( $text );
+ $text = $this->replaceInternalLinks( $text );
+ $text = $this->replaceExternalLinks( $text );
+
+ # replaceInternalLinks may sometimes leave behind
+ # absolute URLs, which have to be masked to hide them from replaceExternalLinks
+ $text = str_replace($this->mUniqPrefix."NOPARSE", "", $text);
+
+ $text = $this->doMagicLinks( $text );
+ $text = $this->formatHeadings( $text, $isMain );
+
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ /**
+ * Replace special strings like "ISBN xxx" and "RFC xxx" with
+ * magic external links.
+ *
+ * @private
+ */
+ function &doMagicLinks( &$text ) {
+ wfProfileIn( __METHOD__ );
+ $text = preg_replace_callback(
+ '!(?: # Start cases
+ <a.*?</a> | # Skip link text
+ <.*?> | # Skip stuff inside HTML elements
+ (?:RFC|PMID)\s+([0-9]+) | # RFC or PMID, capture number as m[1]
+ ISBN\s+(\b # ISBN, capture number as m[2]
+ (?: 97[89] [\ \-]? )? # optional 13-digit ISBN prefix
+ (?: [0-9] [\ \-]? ){9} # 9 digits with opt. delimiters
+ [0-9Xx] # check digit
+ \b)
+ )!x', array( &$this, 'magicLinkCallback' ), $text );
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ function magicLinkCallback( $m ) {
+ if ( substr( $m[0], 0, 1 ) == '<' ) {
+ # Skip HTML element
+ return $m[0];
+ } elseif ( substr( $m[0], 0, 4 ) == 'ISBN' ) {
+ $isbn = $m[2];
+ $num = strtr( $isbn, array(
+ '-' => '',
+ ' ' => '',
+ 'x' => 'X',
+ ));
+ $titleObj = SpecialPage::getTitleFor( 'Booksources' );
+ $text = '<a href="' .
+ $titleObj->escapeLocalUrl( "isbn=$num" ) .
+ "\" class=\"internal\">ISBN $isbn</a>";
+ } else {
+ if ( substr( $m[0], 0, 3 ) == 'RFC' ) {
+ $keyword = 'RFC';
+ $urlmsg = 'rfcurl';
+ $id = $m[1];
+ } elseif ( substr( $m[0], 0, 4 ) == 'PMID' ) {
+ $keyword = 'PMID';
+ $urlmsg = 'pubmedurl';
+ $id = $m[1];
+ } else {
+ throw new MWException( __METHOD__.': unrecognised match type "' .
+ substr($m[0], 0, 20 ) . '"' );
+ }
+
+ $url = wfMsg( $urlmsg, $id);
+ $sk =& $this->mOptions->getSkin();
+ $la = $sk->getExternalLinkAttributes( $url, $keyword.$id );
+ $text = "<a href=\"{$url}\"{$la}>{$keyword} {$id}</a>";
+ }
+ return $text;
+ }
+
+ /**
+ * Parse headers and return html
+ *
+ * @private
+ */
+ function doHeadings( $text ) {
+ $fname = 'Parser::doHeadings';
+ wfProfileIn( $fname );
+ for ( $i = 6; $i >= 1; --$i ) {
+ $h = str_repeat( '=', $i );
+ $text = preg_replace( "/^{$h}(.+){$h}\\s*$/m",
+ "<h{$i}>\\1</h{$i}>\\2", $text );
+ }
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ /**
+ * Replace single quotes with HTML markup
+ * @private
+ * @return string the altered text
+ */
+ function doAllQuotes( $text ) {
+ $fname = 'Parser::doAllQuotes';
+ wfProfileIn( $fname );
+ $outtext = '';
+ $lines = explode( "\n", $text );
+ foreach ( $lines as $line ) {
+ $outtext .= $this->doQuotes ( $line ) . "\n";
+ }
+ $outtext = substr($outtext, 0,-1);
+ wfProfileOut( $fname );
+ return $outtext;
+ }
+
+ /**
+ * Helper function for doAllQuotes()
+ * @private
+ */
+ function doQuotes( $text ) {
+ $arr = preg_split( "/(''+)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE );
+ if ( count( $arr ) == 1 )
+ return $text;
+ else
+ {
+ # First, do some preliminary work. This may shift some apostrophes from
+ # being mark-up to being text. It also counts the number of occurrences
+ # of bold and italics mark-ups.
+ $i = 0;
+ $numbold = 0;
+ $numitalics = 0;
+ foreach ( $arr as $r )
+ {
+ if ( ( $i % 2 ) == 1 )
+ {
+ # If there are ever four apostrophes, assume the first is supposed to
+ # be text, and the remaining three constitute mark-up for bold text.
+ if ( strlen( $arr[$i] ) == 4 )
+ {
+ $arr[$i-1] .= "'";
+ $arr[$i] = "'''";
+ }
+ # If there are more than 5 apostrophes in a row, assume they're all
+ # text except for the last 5.
+ else if ( strlen( $arr[$i] ) > 5 )
+ {
+ $arr[$i-1] .= str_repeat( "'", strlen( $arr[$i] ) - 5 );
+ $arr[$i] = "'''''";
+ }
+ # Count the number of occurrences of bold and italics mark-ups.
+ # We are not counting sequences of five apostrophes.
+ if ( strlen( $arr[$i] ) == 2 ) { $numitalics++; }
+ else if ( strlen( $arr[$i] ) == 3 ) { $numbold++; }
+ else if ( strlen( $arr[$i] ) == 5 ) { $numitalics++; $numbold++; }
+ }
+ $i++;
+ }
+
+ # If there is an odd number of both bold and italics, it is likely
+ # that one of the bold ones was meant to be an apostrophe followed
+ # by italics. Which one we cannot know for certain, but it is more
+ # likely to be one that has a single-letter word before it.
+ if ( ( $numbold % 2 == 1 ) && ( $numitalics % 2 == 1 ) )
+ {
+ $i = 0;
+ $firstsingleletterword = -1;
+ $firstmultiletterword = -1;
+ $firstspace = -1;
+ foreach ( $arr as $r )
+ {
+ if ( ( $i % 2 == 1 ) and ( strlen( $r ) == 3 ) )
+ {
+ $x1 = substr ($arr[$i-1], -1);
+ $x2 = substr ($arr[$i-1], -2, 1);
+ if ($x1 == ' ') {
+ if ($firstspace == -1) $firstspace = $i;
+ } else if ($x2 == ' ') {
+ if ($firstsingleletterword == -1) $firstsingleletterword = $i;
+ } else {
+ if ($firstmultiletterword == -1) $firstmultiletterword = $i;
+ }
+ }
+ $i++;
+ }
+
+ # If there is a single-letter word, use it!
+ if ($firstsingleletterword > -1)
+ {
+ $arr [ $firstsingleletterword ] = "''";
+ $arr [ $firstsingleletterword-1 ] .= "'";
+ }
+ # If not, but there's a multi-letter word, use that one.
+ else if ($firstmultiletterword > -1)
+ {
+ $arr [ $firstmultiletterword ] = "''";
+ $arr [ $firstmultiletterword-1 ] .= "'";
+ }
+ # ... otherwise use the first one that has neither.
+ # (notice that it is possible for all three to be -1 if, for example,
+ # there is only one pentuple-apostrophe in the line)
+ else if ($firstspace > -1)
+ {
+ $arr [ $firstspace ] = "''";
+ $arr [ $firstspace-1 ] .= "'";
+ }
+ }
+
+ # Now let's actually convert our apostrophic mush to HTML!
+ $output = '';
+ $buffer = '';
+ $state = '';
+ $i = 0;
+ foreach ($arr as $r)
+ {
+ if (($i % 2) == 0)
+ {
+ if ($state == 'both')
+ $buffer .= $r;
+ else
+ $output .= $r;
+ }
+ else
+ {
+ if (strlen ($r) == 2)
+ {
+ if ($state == 'i')
+ { $output .= '</i>'; $state = ''; }
+ else if ($state == 'bi')
+ { $output .= '</i>'; $state = 'b'; }
+ else if ($state == 'ib')
+ { $output .= '</b></i><b>'; $state = 'b'; }
+ else if ($state == 'both')
+ { $output .= '<b><i>'.$buffer.'</i>'; $state = 'b'; }
+ else # $state can be 'b' or ''
+ { $output .= '<i>'; $state .= 'i'; }
+ }
+ else if (strlen ($r) == 3)
+ {
+ if ($state == 'b')
+ { $output .= '</b>'; $state = ''; }
+ else if ($state == 'bi')
+ { $output .= '</i></b><i>'; $state = 'i'; }
+ else if ($state == 'ib')
+ { $output .= '</b>'; $state = 'i'; }
+ else if ($state == 'both')
+ { $output .= '<i><b>'.$buffer.'</b>'; $state = 'i'; }
+ else # $state can be 'i' or ''
+ { $output .= '<b>'; $state .= 'b'; }
+ }
+ else if (strlen ($r) == 5)
+ {
+ if ($state == 'b')
+ { $output .= '</b><i>'; $state = 'i'; }
+ else if ($state == 'i')
+ { $output .= '</i><b>'; $state = 'b'; }
+ else if ($state == 'bi')
+ { $output .= '</i></b>'; $state = ''; }
+ else if ($state == 'ib')
+ { $output .= '</b></i>'; $state = ''; }
+ else if ($state == 'both')
+ { $output .= '<i><b>'.$buffer.'</b></i>'; $state = ''; }
+ else # ($state == '')
+ { $buffer = ''; $state = 'both'; }
+ }
+ }
+ $i++;
+ }
+ # Now close all remaining tags. Notice that the order is important.
+ if ($state == 'b' || $state == 'ib')
+ $output .= '</b>';
+ if ($state == 'i' || $state == 'bi' || $state == 'ib')
+ $output .= '</i>';
+ if ($state == 'bi')
+ $output .= '</b>';
+ if ($state == 'both')
+ $output .= '<b><i>'.$buffer.'</i></b>';
+ return $output;
+ }
+ }
+
+ /**
+ * Replace external links
+ *
+ * Note: this is all very hackish and the order of execution matters a lot.
+ * Make sure to run maintenance/parserTests.php if you change this code.
+ *
+ * @private
+ */
+ function replaceExternalLinks( $text ) {
+ global $wgContLang;
+ $fname = 'Parser::replaceExternalLinks';
+ wfProfileIn( $fname );
+
+ $sk =& $this->mOptions->getSkin();
+
+ $bits = preg_split( EXT_LINK_BRACKETED, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
+
+ $s = $this->replaceFreeExternalLinks( array_shift( $bits ) );
+
+ $i = 0;
+ while ( $i<count( $bits ) ) {
+ $url = $bits[$i++];
+ $protocol = $bits[$i++];
+ $text = $bits[$i++];
+ $trail = $bits[$i++];
+
+ # The characters '<' and '>' (which were escaped by
+ # removeHTMLtags()) should not be included in
+ # URLs, per RFC 2396.
+ $m2 = array();
+ if (preg_match('/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE)) {
+ $text = substr($url, $m2[0][1]) . ' ' . $text;
+ $url = substr($url, 0, $m2[0][1]);
+ }
+
+ # If the link text is an image URL, replace it with an <img> tag
+ # This happened by accident in the original parser, but some people used it extensively
+ $img = $this->maybeMakeExternalImage( $text );
+ if ( $img !== false ) {
+ $text = $img;
+ }
+
+ $dtrail = '';
+
+ # Set linktype for CSS - if URL==text, link is essentially free
+ $linktype = ($text == $url) ? 'free' : 'text';
+
+ # No link text, e.g. [http://domain.tld/some.link]
+ if ( $text == '' ) {
+ # Autonumber if allowed. See bug #5918
+ if ( strpos( wfUrlProtocols(), substr($protocol, 0, strpos($protocol, ':')) ) !== false ) {
+ $text = '[' . ++$this->mAutonumber . ']';
+ $linktype = 'autonumber';
+ } else {
+ # Otherwise just use the URL
+ $text = htmlspecialchars( $url );
+ $linktype = 'free';
+ }
+ } else {
+ # Have link text, e.g. [http://domain.tld/some.link text]s
+ # Check for trail
+ list( $dtrail, $trail ) = Linker::splitTrail( $trail );
+ }
+
+ $text = $wgContLang->markNoConversion($text);
+
+ $url = Sanitizer::cleanUrl( $url );
+
+ # Process the trail (i.e. everything after this link up until start of the next link),
+ # replacing any non-bracketed links
+ $trail = $this->replaceFreeExternalLinks( $trail );
+
+ # Use the encoded URL
+ # This means that users can paste URLs directly into the text
+ # Funny characters like &ouml; aren't valid in URLs anyway
+ # This was changed in August 2004
+ $s .= $sk->makeExternalLink( $url, $text, false, $linktype, $this->mTitle->getNamespace() ) . $dtrail . $trail;
+
+ # 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 = Parser::replaceUnusualEscapes( $url );
+ $this->mOutput->addExternalLink( $pasteurized );
+ }
+
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ /**
+ * Replace anything that looks like a URL with a link
+ * @private
+ */
+ function replaceFreeExternalLinks( $text ) {
+ global $wgContLang;
+ $fname = 'Parser::replaceFreeExternalLinks';
+ wfProfileIn( $fname );
+
+ $bits = preg_split( '/(\b(?:' . wfUrlProtocols() . '))/S', $text, -1, PREG_SPLIT_DELIM_CAPTURE );
+ $s = array_shift( $bits );
+ $i = 0;
+
+ $sk =& $this->mOptions->getSkin();
+
+ while ( $i < count( $bits ) ){
+ $protocol = $bits[$i++];
+ $remainder = $bits[$i++];
+
+ $m = array();
+ if ( preg_match( '/^('.EXT_LINK_URL_CLASS.'+)(.*)$/s', $remainder, $m ) ) {
+ # Found some characters after the protocol that look promising
+ $url = $protocol . $m[1];
+ $trail = $m[2];
+
+ # special case: handle urls as url args:
+ # http://www.example.com/foo?=http://www.example.com/bar
+ if(strlen($trail) == 0 &&
+ isset($bits[$i]) &&
+ preg_match('/^'. wfUrlProtocols() . '$/S', $bits[$i]) &&
+ preg_match( '/^('.EXT_LINK_URL_CLASS.'+)(.*)$/s', $bits[$i + 1], $m ))
+ {
+ # add protocol, arg
+ $url .= $bits[$i] . $m[1]; # protocol, url as arg to previous link
+ $i += 2;
+ $trail = $m[2];
+ }
+
+ # The characters '<' and '>' (which were escaped by
+ # removeHTMLtags()) should not be included in
+ # URLs, per RFC 2396.
+ $m2 = array();
+ if (preg_match('/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE)) {
+ $trail = substr($url, $m2[0][1]) . $trail;
+ $url = substr($url, 0, $m2[0][1]);
+ }
+
+ # Move trailing punctuation to $trail
+ $sep = ',;\.:!?';
+ # If there is no left bracket, then consider right brackets fair game too
+ if ( strpos( $url, '(' ) === false ) {
+ $sep .= ')';
+ }
+
+ $numSepChars = strspn( strrev( $url ), $sep );
+ if ( $numSepChars ) {
+ $trail = substr( $url, -$numSepChars ) . $trail;
+ $url = substr( $url, 0, -$numSepChars );
+ }
+
+ $url = Sanitizer::cleanUrl( $url );
+
+ # Is this an external image?
+ $text = $this->maybeMakeExternalImage( $url );
+ if ( $text === false ) {
+ # Not an image, make a link
+ $text = $sk->makeExternalLink( $url, $wgContLang->markNoConversion($url), true, 'free', $this->mTitle->getNamespace() );
+ # Register it in the output object...
+ # Replace unnecessary URL escape codes with their equivalent characters
+ $pasteurized = Parser::replaceUnusualEscapes( $url );
+ $this->mOutput->addExternalLink( $pasteurized );
+ }
+ $s .= $text . $trail;
+ } else {
+ $s .= $protocol . $remainder;
+ }
+ }
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ /**
+ * Replace unusual URL escape codes with their equivalent characters
+ * @param string
+ * @return string
+ * @static
+ * @fixme 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.
+ */
+ static function replaceUnusualEscapes( $url ) {
+ return preg_replace_callback( '/%[0-9A-Fa-f]{2}/',
+ array( 'Parser', 'replaceUnusualEscapesCallback' ), $url );
+ }
+
+ /**
+ * Callback function used in replaceUnusualEscapes().
+ * Replaces unusual URL escape codes with their equivalent character
+ * @static
+ * @private
+ */
+ 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];
+ }
+ }
+
+ /**
+ * make an image if it's allowed, either through the global
+ * option or through the exception
+ * @private
+ */
+ function maybeMakeExternalImage( $url ) {
+ $sk =& $this->mOptions->getSkin();
+ $imagesfrom = $this->mOptions->getAllowExternalImagesFrom();
+ $imagesexception = !empty($imagesfrom);
+ $text = false;
+ if ( $this->mOptions->getAllowExternalImages()
+ || ( $imagesexception && strpos( $url, $imagesfrom ) === 0 ) ) {
+ if ( preg_match( EXT_IMAGE_REGEX, $url ) ) {
+ # Image found
+ $text = $sk->makeExternalImage( htmlspecialchars( $url ) );
+ }
+ }
+ return $text;
+ }
+
+ /**
+ * Process [[ ]] wikilinks
+ *
+ * @private
+ */
+ function replaceInternalLinks( $s ) {
+ global $wgContLang;
+ static $fname = 'Parser::replaceInternalLinks' ;
+
+ wfProfileIn( $fname );
+
+ wfProfileIn( $fname.'-setup' );
+ static $tc = FALSE;
+ # the % is needed to support urlencoded titles as well
+ if ( !$tc ) { $tc = Title::legalChars() . '#%'; }
+
+ $sk =& $this->mOptions->getSkin();
+
+ #split the entire text string on occurences of [[
+ $a = explode( '[[', ' ' . $s );
+ #get the first element (all text up to first [[), and remove the space we added
+ $s = array_shift( $a );
+ $s = substr( $s, 1 );
+
+ # Match a link having the form [[namespace:link|alternate]]trail
+ static $e1 = FALSE;
+ if ( !$e1 ) { $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD"; }
+ # Match cases where there is no "]]", which might still be images
+ static $e1_img = FALSE;
+ if ( !$e1_img ) { $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD"; }
+ # Match the end of a line for a word that's not followed by whitespace,
+ # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
+ $e2 = wfMsgForContent( 'linkprefix' );
+
+ $useLinkPrefixExtension = $wgContLang->linkPrefixExtension();
+
+ if( is_null( $this->mTitle ) ) {
+ throw new MWException( __METHOD__.": \$this->mTitle is null\n" );
+ }
+ $nottalk = !$this->mTitle->isTalkPage();
+
+ if ( $useLinkPrefixExtension ) {
+ $m = array();
+ if ( preg_match( $e2, $s, $m ) ) {
+ $first_prefix = $m[2];
+ } else {
+ $first_prefix = false;
+ }
+ } else {
+ $prefix = '';
+ }
+
+ if($wgContLang->hasVariants())
+ $selflink = $wgContLang->convertLinkToAllVariants($this->mTitle->getPrefixedText());
+ else
+ $selflink = array($this->mTitle->getPrefixedText());
+ $useSubpages = $this->areSubpagesAllowed();
+ wfProfileOut( $fname.'-setup' );
+
+ # Loop for each link
+ for ($k = 0; isset( $a[$k] ); $k++) {
+ $line = $a[$k];
+ if ( $useLinkPrefixExtension ) {
+ wfProfileIn( $fname.'-prefixhandling' );
+ if ( preg_match( $e2, $s, $m ) ) {
+ $prefix = $m[2];
+ $s = $m[1];
+ } else {
+ $prefix='';
+ }
+ # first link
+ if($first_prefix) {
+ $prefix = $first_prefix;
+ $first_prefix = false;
+ }
+ wfProfileOut( $fname.'-prefixhandling' );
+ }
+
+ $might_be_img = false;
+
+ wfProfileIn( "$fname-e1" );
+ if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
+ $text = $m[2];
+ # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
+ # [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row fucks up,
+ # the real problem is with the $e1 regex
+ # See bug 1300.
+ #
+ # Still some problems for cases where the ] is meant to be outside punctuation,
+ # and no image is in sight. See bug 2095.
+ #
+ if( $text !== '' &&
+ substr( $m[3], 0, 1 ) === ']' &&
+ strpos($text, '[') !== false
+ )
+ {
+ $text .= ']'; # so that replaceExternalLinks($text) works later
+ $m[3] = substr( $m[3], 1 );
+ }
+ # fix up urlencoded title texts
+ if( strpos( $m[1], '%' ) !== false ) {
+ # Should anchors '#' also be rejected?
+ $m[1] = str_replace( array('<', '>'), array('&lt;', '&gt;'), urldecode($m[1]) );
+ }
+ $trail = $m[3];
+ } elseif( preg_match($e1_img, $line, $m) ) { # Invalid, but might be an image with a link in its caption
+ $might_be_img = true;
+ $text = $m[2];
+ if ( strpos( $m[1], '%' ) !== false ) {
+ $m[1] = urldecode($m[1]);
+ }
+ $trail = "";
+ } else { # Invalid form; output directly
+ $s .= $prefix . '[[' . $line ;
+ wfProfileOut( "$fname-e1" );
+ continue;
+ }
+ wfProfileOut( "$fname-e1" );
+ wfProfileIn( "$fname-misc" );
+
+ # Don't allow internal links to pages containing
+ # PROTO: where PROTO is a valid URL protocol; these
+ # should be external links.
+ if (preg_match('/^(\b(?:' . wfUrlProtocols() . '))/', $m[1])) {
+ $s .= $prefix . '[[' . $line ;
+ continue;
+ }
+
+ # Make subpage if necessary
+ if( $useSubpages ) {
+ $link = $this->maybeDoSubpageLink( $m[1], $text );
+ } else {
+ $link = $m[1];
+ }
+
+ $noforce = (substr($m[1], 0, 1) != ':');
+ if (!$noforce) {
+ # Strip off leading ':'
+ $link = substr($link, 1);
+ }
+
+ wfProfileOut( "$fname-misc" );
+ wfProfileIn( "$fname-title" );
+ $nt = Title::newFromText( $this->mStripState->unstripNoWiki($link) );
+ if( !$nt ) {
+ $s .= $prefix . '[[' . $line;
+ wfProfileOut( "$fname-title" );
+ continue;
+ }
+
+ $ns = $nt->getNamespace();
+ $iw = $nt->getInterWiki();
+ wfProfileOut( "$fname-title" );
+
+ if ($might_be_img) { # if this is actually an invalid link
+ wfProfileIn( "$fname-might_be_img" );
+ if ($ns == NS_IMAGE && $noforce) { #but might be an image
+ $found = false;
+ while (isset ($a[$k+1]) ) {
+ #look at the next 'line' to see if we can close it there
+ $spliced = array_splice( $a, $k + 1, 1 );
+ $next_line = array_shift( $spliced );
+ $m = explode( ']]', $next_line, 3 );
+ if ( count( $m ) == 3 ) {
+ # the first ]] closes the inner link, the second the image
+ $found = true;
+ $text .= "[[{$m[0]}]]{$m[1]}";
+ $trail = $m[2];
+ break;
+ } elseif ( count( $m ) == 2 ) {
+ #if there's exactly one ]] that's fine, we'll keep looking
+ $text .= "[[{$m[0]}]]{$m[1]}";
+ } else {
+ #if $next_line is invalid too, we need look no further
+ $text .= '[[' . $next_line;
+ break;
+ }
+ }
+ if ( !$found ) {
+ # we couldn't find the end of this imageLink, so output it raw
+ #but don't ignore what might be perfectly normal links in the text we've examined
+ $text = $this->replaceInternalLinks($text);
+ $s .= "{$prefix}[[$link|$text";
+ # note: no $trail, because without an end, there *is* no trail
+ wfProfileOut( "$fname-might_be_img" );
+ continue;
+ }
+ } else { #it's not an image, so output it raw
+ $s .= "{$prefix}[[$link|$text";
+ # note: no $trail, because without an end, there *is* no trail
+ wfProfileOut( "$fname-might_be_img" );
+ continue;
+ }
+ wfProfileOut( "$fname-might_be_img" );
+ }
+
+ $wasblank = ( '' == $text );
+ if( $wasblank ) $text = $link;
+
+ # Link not escaped by : , create the various objects
+ if( $noforce ) {
+
+ # Interwikis
+ wfProfileIn( "$fname-interwiki" );
+ if( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName( $iw ) ) {
+ $this->mOutput->addLanguageLink( $nt->getFullText() );
+ $s = rtrim($s . "\n");
+ $s .= trim($prefix . $trail, "\n") == '' ? '': $prefix . $trail;
+ wfProfileOut( "$fname-interwiki" );
+ continue;
+ }
+ wfProfileOut( "$fname-interwiki" );
+
+ if ( $ns == NS_IMAGE ) {
+ wfProfileIn( "$fname-image" );
+ if ( !wfIsBadImage( $nt->getDBkey(), $this->mTitle ) ) {
+ # recursively parse links inside the image caption
+ # actually, this will parse them in any other parameters, too,
+ # but it might be hard to fix that, and it doesn't matter ATM
+ $text = $this->replaceExternalLinks($text);
+ $text = $this->replaceInternalLinks($text);
+
+ # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
+ $s .= $prefix . $this->armorLinks( $this->makeImage( $nt, $text ) ) . $trail;
+ $this->mOutput->addImage( $nt->getDBkey() );
+
+ wfProfileOut( "$fname-image" );
+ continue;
+ } else {
+ # We still need to record the image's presence on the page
+ $this->mOutput->addImage( $nt->getDBkey() );
+ }
+ wfProfileOut( "$fname-image" );
+
+ }
+
+ if ( $ns == NS_CATEGORY ) {
+ wfProfileIn( "$fname-category" );
+ $s = rtrim($s . "\n"); # bug 87
+
+ if ( $wasblank ) {
+ $sortkey = $this->getDefaultSort();
+ } else {
+ $sortkey = $text;
+ }
+ $sortkey = Sanitizer::decodeCharReferences( $sortkey );
+ $sortkey = str_replace( "\n", '', $sortkey );
+ $sortkey = $wgContLang->convertCategoryKey( $sortkey );
+ $this->mOutput->addCategory( $nt->getDBkey(), $sortkey );
+
+ /**
+ * Strip the whitespace Category links produce, see bug 87
+ * @todo We might want to use trim($tmp, "\n") here.
+ */
+ $s .= trim($prefix . $trail, "\n") == '' ? '': $prefix . $trail;
+
+ wfProfileOut( "$fname-category" );
+ continue;
+ }
+ }
+
+ if( ( in_array( $nt->getPrefixedText(), $selflink ) ) &&
+ ( $nt->getFragment() === '' ) ) {
+ # Self-links are handled specially; generally de-link and change to bold.
+ $s .= $prefix . $sk->makeSelfLinkObj( $nt, $text, '', $trail );
+ continue;
+ }
+
+ # Special and Media are pseudo-namespaces; no pages actually exist in them
+ if( $ns == NS_MEDIA ) {
+ $link = $sk->makeMediaLinkObj( $nt, $text );
+ # Cloak with NOPARSE to avoid replacement in replaceExternalLinks
+ $s .= $prefix . $this->armorLinks( $link ) . $trail;
+ $this->mOutput->addImage( $nt->getDBkey() );
+ continue;
+ } elseif( $ns == NS_SPECIAL ) {
+ $s .= $this->makeKnownLinkHolder( $nt, $text, '', $trail, $prefix );
+ continue;
+ } elseif( $ns == NS_IMAGE ) {
+ $img = new Image( $nt );
+ if( $img->exists() ) {
+ // Force a blue link if the file exists; may be a remote
+ // upload on the shared repository, and we want to see its
+ // auto-generated page.
+ $s .= $this->makeKnownLinkHolder( $nt, $text, '', $trail, $prefix );
+ $this->mOutput->addLink( $nt );
+ continue;
+ }
+ }
+ $s .= $this->makeLinkHolder( $nt, $text, '', $trail, $prefix );
+ }
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ /**
+ * Make a link placeholder. The text returned can be later resolved to a real link with
+ * replaceLinkHolders(). This is done for two reasons: firstly to avoid further
+ * parsing of interwiki links, and secondly to allow all existence checks and
+ * article length checks (for stub links) to be bundled into a single query.
+ *
+ */
+ function makeLinkHolder( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ wfProfileIn( __METHOD__ );
+ if ( ! is_object($nt) ) {
+ # Fail gracefully
+ $retVal = "<!-- ERROR -->{$prefix}{$text}{$trail}";
+ } else {
+ # Separate the link trail from the rest of the link
+ list( $inside, $trail ) = Linker::splitTrail( $trail );
+
+ if ( $nt->isExternal() ) {
+ $nr = array_push( $this->mInterwikiLinkHolders['texts'], $prefix.$text.$inside );
+ $this->mInterwikiLinkHolders['titles'][] = $nt;
+ $retVal = '<!--IWLINK '. ($nr-1) ."-->{$trail}";
+ } else {
+ $nr = array_push( $this->mLinkHolders['namespaces'], $nt->getNamespace() );
+ $this->mLinkHolders['dbkeys'][] = $nt->getDBkey();
+ $this->mLinkHolders['queries'][] = $query;
+ $this->mLinkHolders['texts'][] = $prefix.$text.$inside;
+ $this->mLinkHolders['titles'][] = $nt;
+
+ $retVal = '<!--LINK '. ($nr-1) ."-->{$trail}";
+ }
+ }
+ wfProfileOut( __METHOD__ );
+ return $retVal;
+ }
+
+ /**
+ * Render a forced-blue link inline; protect against double expansion of
+ * URLs if we're in a mode that prepends full URL prefixes to internal links.
+ * Since this little disaster has to split off the trail text to avoid
+ * breaking URLs in the following text without breaking trails on the
+ * wiki links, it's been made into a horrible function.
+ *
+ * @param Title $nt
+ * @param string $text
+ * @param string $query
+ * @param string $trail
+ * @param string $prefix
+ * @return string HTML-wikitext mix oh yuck
+ */
+ function makeKnownLinkHolder( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ list( $inside, $trail ) = Linker::splitTrail( $trail );
+ $sk =& $this->mOptions->getSkin();
+ $link = $sk->makeKnownLinkObj( $nt, $text, $query, $inside, $prefix );
+ return $this->armorLinks( $link ) . $trail;
+ }
+
+ /**
+ * Insert a NOPARSE hacky thing into any inline links in a chunk that's
+ * going to go through further parsing steps before inline URL expansion.
+ *
+ * In particular this is important when using action=render, which causes
+ * full URLs to be included.
+ *
+ * Oh man I hate our multi-layer parser!
+ *
+ * @param string more-or-less HTML
+ * @return string less-or-more HTML with NOPARSE bits
+ */
+ function armorLinks( $text ) {
+ return preg_replace( '/\b(' . wfUrlProtocols() . ')/',
+ "{$this->mUniqPrefix}NOPARSE$1", $text );
+ }
+
+ /**
+ * Return true if subpage links should be expanded on this page.
+ * @return bool
+ */
+ function areSubpagesAllowed() {
+ # Some namespaces don't allow subpages
+ global $wgNamespacesWithSubpages;
+ return !empty($wgNamespacesWithSubpages[$this->mTitle->getNamespace()]);
+ }
+
+ /**
+ * Handle link to subpage if necessary
+ * @param string $target the source of the link
+ * @param string &$text the link text, modified as necessary
+ * @return string the full name of the link
+ * @private
+ */
+ function maybeDoSubpageLink($target, &$text) {
+ # Valid link forms:
+ # Foobar -- normal
+ # :Foobar -- override special treatment of prefix (images, language links)
+ # /Foobar -- convert to CurrentPage/Foobar
+ # /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text
+ # ../ -- convert to CurrentPage, from CurrentPage/CurrentSubPage
+ # ../Foobar -- convert to CurrentPage/Foobar, from CurrentPage/CurrentSubPage
+
+ $fname = 'Parser::maybeDoSubpageLink';
+ wfProfileIn( $fname );
+ $ret = $target; # default return value is no change
+
+ # bug 7425
+ $target = trim( $target );
+
+ # Some namespaces don't allow subpages,
+ # so only perform processing if subpages are allowed
+ if( $this->areSubpagesAllowed() ) {
+ # Look at the first character
+ if( $target != '' && $target{0} == '/' ) {
+ # / at end means we don't want the slash to be shown
+ if( substr( $target, -1, 1 ) == '/' ) {
+ $target = substr( $target, 1, -1 );
+ $noslash = $target;
+ } else {
+ $noslash = substr( $target, 1 );
+ }
+
+ $ret = $this->mTitle->getPrefixedText(). '/' . trim($noslash);
+ if( '' === $text ) {
+ $text = $target;
+ } # this might be changed for ugliness reasons
+ } else {
+ # check for .. subpage backlinks
+ $dotdotcount = 0;
+ $nodotdot = $target;
+ while( strncmp( $nodotdot, "../", 3 ) == 0 ) {
+ ++$dotdotcount;
+ $nodotdot = substr( $nodotdot, 3 );
+ }
+ if($dotdotcount > 0) {
+ $exploded = explode( '/', $this->mTitle->GetPrefixedText() );
+ if( count( $exploded ) > $dotdotcount ) { # not allowed to go below top level page
+ $ret = implode( '/', array_slice( $exploded, 0, -$dotdotcount ) );
+ # / at the end means don't show full path
+ if( substr( $nodotdot, -1, 1 ) == '/' ) {
+ $nodotdot = substr( $nodotdot, 0, -1 );
+ if( '' === $text ) {
+ $text = $nodotdot;
+ }
+ }
+ $nodotdot = trim( $nodotdot );
+ if( $nodotdot != '' ) {
+ $ret .= '/' . $nodotdot;
+ }
+ }
+ }
+ }
+ }
+
+ wfProfileOut( $fname );
+ return $ret;
+ }
+
+ /**#@+
+ * Used by doBlockLevels()
+ * @private
+ */
+ /* private */ function closeParagraph() {
+ $result = '';
+ if ( '' != $this->mLastSection ) {
+ $result = '</' . $this->mLastSection . ">\n";
+ }
+ $this->mInPre = false;
+ $this->mLastSection = '';
+ return $result;
+ }
+ # getCommon() returns the length of the longest common substring
+ # of both arguments, starting at the beginning of both.
+ #
+ /* private */ function getCommon( $st1, $st2 ) {
+ $fl = strlen( $st1 );
+ $shorter = strlen( $st2 );
+ if ( $fl < $shorter ) { $shorter = $fl; }
+
+ for ( $i = 0; $i < $shorter; ++$i ) {
+ if ( $st1{$i} != $st2{$i} ) { break; }
+ }
+ return $i;
+ }
+ # These next three functions open, continue, and close the list
+ # element appropriate to the prefix character passed into them.
+ #
+ /* private */ function openList( $char ) {
+ $result = $this->closeParagraph();
+
+ if ( '*' == $char ) { $result .= '<ul><li>'; }
+ else if ( '#' == $char ) { $result .= '<ol><li>'; }
+ else if ( ':' == $char ) { $result .= '<dl><dd>'; }
+ else if ( ';' == $char ) {
+ $result .= '<dl><dt>';
+ $this->mDTopen = true;
+ }
+ else { $result = '<!-- ERR 1 -->'; }
+
+ return $result;
+ }
+
+ /* private */ function nextItem( $char ) {
+ if ( '*' == $char || '#' == $char ) { return '</li><li>'; }
+ else if ( ':' == $char || ';' == $char ) {
+ $close = '</dd>';
+ if ( $this->mDTopen ) { $close = '</dt>'; }
+ if ( ';' == $char ) {
+ $this->mDTopen = true;
+ return $close . '<dt>';
+ } else {
+ $this->mDTopen = false;
+ return $close . '<dd>';
+ }
+ }
+ return '<!-- ERR 2 -->';
+ }
+
+ /* private */ function closeList( $char ) {
+ if ( '*' == $char ) { $text = '</li></ul>'; }
+ else if ( '#' == $char ) { $text = '</li></ol>'; }
+ else if ( ':' == $char ) {
+ if ( $this->mDTopen ) {
+ $this->mDTopen = false;
+ $text = '</dt></dl>';
+ } else {
+ $text = '</dd></dl>';
+ }
+ }
+ else { return '<!-- ERR 3 -->'; }
+ return $text."\n";
+ }
+ /**#@-*/
+
+ /**
+ * Make lists from lines starting with ':', '*', '#', etc.
+ *
+ * @private
+ * @return string the lists rendered as HTML
+ */
+ function doBlockLevels( $text, $linestart ) {
+ $fname = 'Parser::doBlockLevels';
+ wfProfileIn( $fname );
+
+ # Parsing through the text line by line. The main thing
+ # happening here is handling of block-level elements p, pre,
+ # and making lists from lines starting with * # : etc.
+ #
+ $textLines = explode( "\n", $text );
+
+ $lastPrefix = $output = '';
+ $this->mDTopen = $inBlockElem = false;
+ $prefixLength = 0;
+ $paragraphStack = false;
+
+ if ( !$linestart ) {
+ $output .= array_shift( $textLines );
+ }
+ foreach ( $textLines as $oLine ) {
+ $lastPrefixLength = strlen( $lastPrefix );
+ $preCloseMatch = preg_match('/<\\/pre/i', $oLine );
+ $preOpenMatch = preg_match('/<pre/i', $oLine );
+ if ( !$this->mInPre ) {
+ # Multiple prefixes may abut each other for nested lists.
+ $prefixLength = strspn( $oLine, '*#:;' );
+ $pref = substr( $oLine, 0, $prefixLength );
+
+ # eh?
+ $pref2 = str_replace( ';', ':', $pref );
+ $t = substr( $oLine, $prefixLength );
+ $this->mInPre = !empty($preOpenMatch);
+ } else {
+ # Don't interpret any other prefixes in preformatted text
+ $prefixLength = 0;
+ $pref = $pref2 = '';
+ $t = $oLine;
+ }
+
+ # List generation
+ if( $prefixLength && 0 == strcmp( $lastPrefix, $pref2 ) ) {
+ # Same as the last item, so no need to deal with nesting or opening stuff
+ $output .= $this->nextItem( substr( $pref, -1 ) );
+ $paragraphStack = false;
+
+ if ( substr( $pref, -1 ) == ';') {
+ # The one nasty exception: definition lists work like this:
+ # ; title : definition text
+ # So we check for : in the remainder text to split up the
+ # title and definition, without b0rking links.
+ $term = $t2 = '';
+ if ($this->findColonNoLinks($t, $term, $t2) !== false) {
+ $t = $t2;
+ $output .= $term . $this->nextItem( ':' );
+ }
+ }
+ } elseif( $prefixLength || $lastPrefixLength ) {
+ # Either open or close a level...
+ $commonPrefixLength = $this->getCommon( $pref, $lastPrefix );
+ $paragraphStack = false;
+
+ while( $commonPrefixLength < $lastPrefixLength ) {
+ $output .= $this->closeList( $lastPrefix{$lastPrefixLength-1} );
+ --$lastPrefixLength;
+ }
+ if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) {
+ $output .= $this->nextItem( $pref{$commonPrefixLength-1} );
+ }
+ while ( $prefixLength > $commonPrefixLength ) {
+ $char = substr( $pref, $commonPrefixLength, 1 );
+ $output .= $this->openList( $char );
+
+ if ( ';' == $char ) {
+ # FIXME: This is dupe of code above
+ if ($this->findColonNoLinks($t, $term, $t2) !== false) {
+ $t = $t2;
+ $output .= $term . $this->nextItem( ':' );
+ }
+ }
+ ++$commonPrefixLength;
+ }
+ $lastPrefix = $pref2;
+ }
+ if( 0 == $prefixLength ) {
+ wfProfileIn( "$fname-paragraph" );
+ # No prefix (not in list)--go to paragraph mode
+ // XXX: use a stack for nestable elements like span, table and div
+ $openmatch = preg_match('/(<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
+ $closematch = preg_match(
+ '/(<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
+ '<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol|<\\/?center)/iS', $t );
+ if ( $openmatch or $closematch ) {
+ $paragraphStack = false;
+ # TODO bug 5718: paragraph closed
+ $output .= $this->closeParagraph();
+ if ( $preOpenMatch and !$preCloseMatch ) {
+ $this->mInPre = true;
+ }
+ if ( $closematch ) {
+ $inBlockElem = false;
+ } else {
+ $inBlockElem = true;
+ }
+ } else if ( !$inBlockElem && !$this->mInPre ) {
+ if ( ' ' == $t{0} and ( $this->mLastSection == 'pre' or trim($t) != '' ) ) {
+ // pre
+ if ($this->mLastSection != 'pre') {
+ $paragraphStack = false;
+ $output .= $this->closeParagraph().'<pre>';
+ $this->mLastSection = 'pre';
+ }
+ $t = substr( $t, 1 );
+ } else {
+ // paragraph
+ if ( '' == trim($t) ) {
+ if ( $paragraphStack ) {
+ $output .= $paragraphStack.'<br />';
+ $paragraphStack = false;
+ $this->mLastSection = 'p';
+ } else {
+ if ($this->mLastSection != 'p' ) {
+ $output .= $this->closeParagraph();
+ $this->mLastSection = '';
+ $paragraphStack = '<p>';
+ } else {
+ $paragraphStack = '</p><p>';
+ }
+ }
+ } else {
+ if ( $paragraphStack ) {
+ $output .= $paragraphStack;
+ $paragraphStack = false;
+ $this->mLastSection = 'p';
+ } else if ($this->mLastSection != 'p') {
+ $output .= $this->closeParagraph().'<p>';
+ $this->mLastSection = 'p';
+ }
+ }
+ }
+ }
+ wfProfileOut( "$fname-paragraph" );
+ }
+ // somewhere above we forget to get out of pre block (bug 785)
+ if($preCloseMatch && $this->mInPre) {
+ $this->mInPre = false;
+ }
+ if ($paragraphStack === false) {
+ $output .= $t."\n";
+ }
+ }
+ while ( $prefixLength ) {
+ $output .= $this->closeList( $pref2{$prefixLength-1} );
+ --$prefixLength;
+ }
+ if ( '' != $this->mLastSection ) {
+ $output .= '</' . $this->mLastSection . '>';
+ $this->mLastSection = '';
+ }
+
+ wfProfileOut( $fname );
+ return $output;
+ }
+
+ /**
+ * Split up a string on ':', ignoring any occurences inside tags
+ * to prevent illegal overlapping.
+ * @param string $str the string to split
+ * @param string &$before set to everything before the ':'
+ * @param string &$after set to everything after the ':'
+ * return string the position of the ':', or false if none found
+ */
+ function findColonNoLinks($str, &$before, &$after) {
+ $fname = 'Parser::findColonNoLinks';
+ wfProfileIn( $fname );
+
+ $pos = strpos( $str, ':' );
+ if( $pos === false ) {
+ // Nothing to find!
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ $lt = strpos( $str, '<' );
+ if( $lt === false || $lt > $pos ) {
+ // Easy; no tag nesting to worry about
+ $before = substr( $str, 0, $pos );
+ $after = substr( $str, $pos+1 );
+ wfProfileOut( $fname );
+ return $pos;
+ }
+
+ // Ugly state machine to walk through avoiding tags.
+ $state = MW_COLON_STATE_TEXT;
+ $stack = 0;
+ $len = strlen( $str );
+ for( $i = 0; $i < $len; $i++ ) {
+ $c = $str{$i};
+
+ switch( $state ) {
+ // (Using the number is a performance hack for common cases)
+ case 0: // MW_COLON_STATE_TEXT:
+ switch( $c ) {
+ case "<":
+ // Could be either a <start> tag or an </end> tag
+ $state = MW_COLON_STATE_TAGSTART;
+ break;
+ case ":":
+ if( $stack == 0 ) {
+ // We found it!
+ $before = substr( $str, 0, $i );
+ $after = substr( $str, $i + 1 );
+ wfProfileOut( $fname );
+ return $i;
+ }
+ // Embedded in a tag; don't break it.
+ break;
+ default:
+ // Skip ahead looking for something interesting
+ $colon = strpos( $str, ':', $i );
+ if( $colon === false ) {
+ // Nothing else interesting
+ wfProfileOut( $fname );
+ return false;
+ }
+ $lt = strpos( $str, '<', $i );
+ if( $stack === 0 ) {
+ if( $lt === false || $colon < $lt ) {
+ // We found it!
+ $before = substr( $str, 0, $colon );
+ $after = substr( $str, $colon + 1 );
+ wfProfileOut( $fname );
+ return $i;
+ }
+ }
+ if( $lt === false ) {
+ // Nothing else interesting to find; abort!
+ // We're nested, but there's no close tags left. Abort!
+ break 2;
+ }
+ // Skip ahead to next tag start
+ $i = $lt;
+ $state = MW_COLON_STATE_TAGSTART;
+ }
+ break;
+ case 1: // MW_COLON_STATE_TAG:
+ // In a <tag>
+ switch( $c ) {
+ case ">":
+ $stack++;
+ $state = MW_COLON_STATE_TEXT;
+ break;
+ case "/":
+ // Slash may be followed by >?
+ $state = MW_COLON_STATE_TAGSLASH;
+ break;
+ default:
+ // ignore
+ }
+ break;
+ case 2: // MW_COLON_STATE_TAGSTART:
+ switch( $c ) {
+ case "/":
+ $state = MW_COLON_STATE_CLOSETAG;
+ break;
+ case "!":
+ $state = MW_COLON_STATE_COMMENT;
+ break;
+ case ">":
+ // Illegal early close? This shouldn't happen D:
+ $state = MW_COLON_STATE_TEXT;
+ break;
+ default:
+ $state = MW_COLON_STATE_TAG;
+ }
+ break;
+ case 3: // MW_COLON_STATE_CLOSETAG:
+ // In a </tag>
+ if( $c == ">" ) {
+ $stack--;
+ if( $stack < 0 ) {
+ wfDebug( "Invalid input in $fname; too many close tags\n" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ $state = MW_COLON_STATE_TEXT;
+ }
+ break;
+ case MW_COLON_STATE_TAGSLASH:
+ if( $c == ">" ) {
+ // Yes, a self-closed tag <blah/>
+ $state = MW_COLON_STATE_TEXT;
+ } else {
+ // Probably we're jumping the gun, and this is an attribute
+ $state = MW_COLON_STATE_TAG;
+ }
+ break;
+ case 5: // MW_COLON_STATE_COMMENT:
+ if( $c == "-" ) {
+ $state = MW_COLON_STATE_COMMENTDASH;
+ }
+ break;
+ case MW_COLON_STATE_COMMENTDASH:
+ if( $c == "-" ) {
+ $state = MW_COLON_STATE_COMMENTDASHDASH;
+ } else {
+ $state = MW_COLON_STATE_COMMENT;
+ }
+ break;
+ case MW_COLON_STATE_COMMENTDASHDASH:
+ if( $c == ">" ) {
+ $state = MW_COLON_STATE_TEXT;
+ } else {
+ $state = MW_COLON_STATE_COMMENT;
+ }
+ break;
+ default:
+ throw new MWException( "State machine error in $fname" );
+ }
+ }
+ if( $stack > 0 ) {
+ wfDebug( "Invalid input in $fname; not enough close tags (stack $stack, state $state)\n" );
+ return false;
+ }
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ /**
+ * Return value of a magic variable (like PAGENAME)
+ *
+ * @private
+ */
+ function getVariableValue( $index ) {
+ global $wgContLang, $wgSitename, $wgServer, $wgServerName, $wgScriptPath;
+
+ /**
+ * Some of these require message or data lookups and can be
+ * expensive to check many times.
+ */
+ static $varCache = array();
+ if ( wfRunHooks( 'ParserGetVariableValueVarCache', array( &$this, &$varCache ) ) ) {
+ if ( isset( $varCache[$index] ) ) {
+ return $varCache[$index];
+ }
+ }
+
+ $ts = time();
+ wfRunHooks( 'ParserGetVariableValueTs', array( &$this, &$ts ) );
+
+ # Use the time zone
+ global $wgLocaltimezone;
+ if ( isset( $wgLocaltimezone ) ) {
+ $oldtz = getenv( 'TZ' );
+ putenv( 'TZ='.$wgLocaltimezone );
+ }
+ $localTimestamp = date( 'YmdHis', $ts );
+ $localMonth = date( 'm', $ts );
+ $localMonthName = date( 'n', $ts );
+ $localDay = date( 'j', $ts );
+ $localDay2 = date( 'd', $ts );
+ $localDayOfWeek = date( 'w', $ts );
+ $localWeek = date( 'W', $ts );
+ $localYear = date( 'Y', $ts );
+ $localHour = date( 'H', $ts );
+ if ( isset( $wgLocaltimezone ) ) {
+ putenv( 'TZ='.$oldtz );
+ }
+
+ switch ( $index ) {
+ case 'currentmonth':
+ return $varCache[$index] = $wgContLang->formatNum( date( 'm', $ts ) );
+ case 'currentmonthname':
+ return $varCache[$index] = $wgContLang->getMonthName( date( 'n', $ts ) );
+ case 'currentmonthnamegen':
+ return $varCache[$index] = $wgContLang->getMonthNameGen( date( 'n', $ts ) );
+ case 'currentmonthabbrev':
+ return $varCache[$index] = $wgContLang->getMonthAbbreviation( date( 'n', $ts ) );
+ case 'currentday':
+ return $varCache[$index] = $wgContLang->formatNum( date( 'j', $ts ) );
+ case 'currentday2':
+ return $varCache[$index] = $wgContLang->formatNum( date( 'd', $ts ) );
+ case 'localmonth':
+ return $varCache[$index] = $wgContLang->formatNum( $localMonth );
+ case 'localmonthname':
+ return $varCache[$index] = $wgContLang->getMonthName( $localMonthName );
+ case 'localmonthnamegen':
+ return $varCache[$index] = $wgContLang->getMonthNameGen( $localMonthName );
+ case 'localmonthabbrev':
+ return $varCache[$index] = $wgContLang->getMonthAbbreviation( $localMonthName );
+ case 'localday':
+ return $varCache[$index] = $wgContLang->formatNum( $localDay );
+ case 'localday2':
+ return $varCache[$index] = $wgContLang->formatNum( $localDay2 );
+ case 'pagename':
+ return $this->mTitle->getText();
+ case 'pagenamee':
+ return $this->mTitle->getPartialURL();
+ case 'fullpagename':
+ return $this->mTitle->getPrefixedText();
+ case 'fullpagenamee':
+ return $this->mTitle->getPrefixedURL();
+ case 'subpagename':
+ return $this->mTitle->getSubpageText();
+ case 'subpagenamee':
+ return $this->mTitle->getSubpageUrlForm();
+ case 'basepagename':
+ return $this->mTitle->getBaseText();
+ case 'basepagenamee':
+ return wfUrlEncode( str_replace( ' ', '_', $this->mTitle->getBaseText() ) );
+ case 'talkpagename':
+ if( $this->mTitle->canTalk() ) {
+ $talkPage = $this->mTitle->getTalkPage();
+ return $talkPage->getPrefixedText();
+ } else {
+ return '';
+ }
+ case 'talkpagenamee':
+ if( $this->mTitle->canTalk() ) {
+ $talkPage = $this->mTitle->getTalkPage();
+ return $talkPage->getPrefixedUrl();
+ } else {
+ return '';
+ }
+ case 'subjectpagename':
+ $subjPage = $this->mTitle->getSubjectPage();
+ return $subjPage->getPrefixedText();
+ case 'subjectpagenamee':
+ $subjPage = $this->mTitle->getSubjectPage();
+ return $subjPage->getPrefixedUrl();
+ case 'revisionid':
+ return $this->mRevisionId;
+ case 'revisionday':
+ return intval( substr( $this->getRevisionTimestamp(), 6, 2 ) );
+ case 'revisionday2':
+ return substr( $this->getRevisionTimestamp(), 6, 2 );
+ case 'revisionmonth':
+ return intval( substr( $this->getRevisionTimestamp(), 4, 2 ) );
+ case 'revisionyear':
+ return substr( $this->getRevisionTimestamp(), 0, 4 );
+ case 'revisiontimestamp':
+ return $this->getRevisionTimestamp();
+ case 'namespace':
+ return str_replace('_',' ',$wgContLang->getNsText( $this->mTitle->getNamespace() ) );
+ case 'namespacee':
+ return wfUrlencode( $wgContLang->getNsText( $this->mTitle->getNamespace() ) );
+ case 'talkspace':
+ return $this->mTitle->canTalk() ? str_replace('_',' ',$this->mTitle->getTalkNsText()) : '';
+ case 'talkspacee':
+ return $this->mTitle->canTalk() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
+ case 'subjectspace':
+ return $this->mTitle->getSubjectNsText();
+ case 'subjectspacee':
+ return( wfUrlencode( $this->mTitle->getSubjectNsText() ) );
+ case 'currentdayname':
+ return $varCache[$index] = $wgContLang->getWeekdayName( date( 'w', $ts ) + 1 );
+ case 'currentyear':
+ return $varCache[$index] = $wgContLang->formatNum( date( 'Y', $ts ), true );
+ case 'currenttime':
+ return $varCache[$index] = $wgContLang->time( wfTimestamp( TS_MW, $ts ), false, false );
+ case 'currenthour':
+ return $varCache[$index] = $wgContLang->formatNum( date( 'H', $ts ), true );
+ case 'currentweek':
+ // @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
+ // int to remove the padding
+ return $varCache[$index] = $wgContLang->formatNum( (int)date( 'W', $ts ) );
+ case 'currentdow':
+ return $varCache[$index] = $wgContLang->formatNum( date( 'w', $ts ) );
+ case 'localdayname':
+ return $varCache[$index] = $wgContLang->getWeekdayName( $localDayOfWeek + 1 );
+ case 'localyear':
+ return $varCache[$index] = $wgContLang->formatNum( $localYear, true );
+ case 'localtime':
+ return $varCache[$index] = $wgContLang->time( $localTimestamp, false, false );
+ case 'localhour':
+ return $varCache[$index] = $wgContLang->formatNum( $localHour, true );
+ case 'localweek':
+ // @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
+ // int to remove the padding
+ return $varCache[$index] = $wgContLang->formatNum( (int)$localWeek );
+ case 'localdow':
+ return $varCache[$index] = $wgContLang->formatNum( $localDayOfWeek );
+ case 'numberofarticles':
+ return $varCache[$index] = $wgContLang->formatNum( SiteStats::articles() );
+ case 'numberoffiles':
+ return $varCache[$index] = $wgContLang->formatNum( SiteStats::images() );
+ case 'numberofusers':
+ return $varCache[$index] = $wgContLang->formatNum( SiteStats::users() );
+ case 'numberofpages':
+ return $varCache[$index] = $wgContLang->formatNum( SiteStats::pages() );
+ case 'numberofadmins':
+ return $varCache[$index] = $wgContLang->formatNum( SiteStats::admins() );
+ case 'currenttimestamp':
+ return $varCache[$index] = wfTimestampNow();
+ case 'localtimestamp':
+ return $varCache[$index] = $localTimestamp;
+ case 'currentversion':
+ return $varCache[$index] = SpecialVersion::getVersion();
+ case 'sitename':
+ return $wgSitename;
+ case 'server':
+ return $wgServer;
+ case 'servername':
+ return $wgServerName;
+ case 'scriptpath':
+ return $wgScriptPath;
+ case 'directionmark':
+ return $wgContLang->getDirMark();
+ case 'contentlanguage':
+ global $wgContLanguageCode;
+ return $wgContLanguageCode;
+ default:
+ $ret = null;
+ if ( wfRunHooks( 'ParserGetVariableValueSwitch', array( &$this, &$varCache, &$index, &$ret ) ) )
+ return $ret;
+ else
+ return null;
+ }
+ }
+
+ /**
+ * initialise the magic variables (like CURRENTMONTHNAME)
+ *
+ * @private
+ */
+ function initialiseVariables() {
+ $fname = 'Parser::initialiseVariables';
+ wfProfileIn( $fname );
+ $variableIDs = MagicWord::getVariableIDs();
+
+ $this->mVariables = array();
+ foreach ( $variableIDs as $id ) {
+ $mw =& MagicWord::get( $id );
+ $mw->addToArray( $this->mVariables, $id );
+ }
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * parse any parentheses in format ((title|part|part))
+ * and call callbacks to get a replacement text for any found piece
+ *
+ * @param string $text The text to parse
+ * @param array $callbacks rules in form:
+ * '{' => array( # opening parentheses
+ * 'end' => '}', # closing parentheses
+ * 'cb' => array(2 => callback, # replacement callback to call if {{..}} is found
+ * 3 => callback # replacement callback to call if {{{..}}} is found
+ * )
+ * )
+ * 'min' => 2, # Minimum parenthesis count in cb
+ * 'max' => 3, # Maximum parenthesis count in cb
+ * @private
+ */
+ function replace_callback ($text, $callbacks) {
+ wfProfileIn( __METHOD__ );
+ $openingBraceStack = array(); # this array will hold a stack of parentheses which are not closed yet
+ $lastOpeningBrace = -1; # last not closed parentheses
+
+ $validOpeningBraces = implode( '', array_keys( $callbacks ) );
+
+ $i = 0;
+ while ( $i < strlen( $text ) ) {
+ # Find next opening brace, closing brace or pipe
+ if ( $lastOpeningBrace == -1 ) {
+ $currentClosing = '';
+ $search = $validOpeningBraces;
+ } else {
+ $currentClosing = $openingBraceStack[$lastOpeningBrace]['braceEnd'];
+ $search = $validOpeningBraces . '|' . $currentClosing;
+ }
+ $rule = null;
+ $i += strcspn( $text, $search, $i );
+ if ( $i < strlen( $text ) ) {
+ if ( $text[$i] == '|' ) {
+ $found = 'pipe';
+ } elseif ( $text[$i] == $currentClosing ) {
+ $found = 'close';
+ } elseif ( isset( $callbacks[$text[$i]] ) ) {
+ $found = 'open';
+ $rule = $callbacks[$text[$i]];
+ } else {
+ # Some versions of PHP have a strcspn which stops on null characters
+ # Ignore and continue
+ ++$i;
+ continue;
+ }
+ } else {
+ # All done
+ break;
+ }
+
+ if ( $found == 'open' ) {
+ # found opening brace, let's add it to parentheses stack
+ $piece = array('brace' => $text[$i],
+ 'braceEnd' => $rule['end'],
+ 'title' => '',
+ 'parts' => null);
+
+ # count opening brace characters
+ $piece['count'] = strspn( $text, $piece['brace'], $i );
+ $piece['startAt'] = $piece['partStart'] = $i + $piece['count'];
+ $i += $piece['count'];
+
+ # we need to add to stack only if opening brace count is enough for one of the rules
+ if ( $piece['count'] >= $rule['min'] ) {
+ $lastOpeningBrace ++;
+ $openingBraceStack[$lastOpeningBrace] = $piece;
+ }
+ } elseif ( $found == 'close' ) {
+ # lets check if it is enough characters for closing brace
+ $maxCount = $openingBraceStack[$lastOpeningBrace]['count'];
+ $count = strspn( $text, $text[$i], $i, $maxCount );
+
+ # check for maximum matching characters (if there are 5 closing
+ # characters, we will probably need only 3 - depending on the rules)
+ $matchingCount = 0;
+ $matchingCallback = null;
+ $cbType = $callbacks[$openingBraceStack[$lastOpeningBrace]['brace']];
+ if ( $count > $cbType['max'] ) {
+ # The specified maximum exists in the callback array, unless the caller
+ # has made an error
+ $matchingCount = $cbType['max'];
+ } else {
+ # Count is less than the maximum
+ # Skip any gaps in the callback array to find the true largest match
+ # Need to use array_key_exists not isset because the callback can be null
+ $matchingCount = $count;
+ while ( $matchingCount > 0 && !array_key_exists( $matchingCount, $cbType['cb'] ) ) {
+ --$matchingCount;
+ }
+ }
+
+ if ($matchingCount <= 0) {
+ $i += $count;
+ continue;
+ }
+ $matchingCallback = $cbType['cb'][$matchingCount];
+
+ # let's set a title or last part (if '|' was found)
+ if (null === $openingBraceStack[$lastOpeningBrace]['parts']) {
+ $openingBraceStack[$lastOpeningBrace]['title'] =
+ substr($text, $openingBraceStack[$lastOpeningBrace]['partStart'],
+ $i - $openingBraceStack[$lastOpeningBrace]['partStart']);
+ } else {
+ $openingBraceStack[$lastOpeningBrace]['parts'][] =
+ substr($text, $openingBraceStack[$lastOpeningBrace]['partStart'],
+ $i - $openingBraceStack[$lastOpeningBrace]['partStart']);
+ }
+
+ $pieceStart = $openingBraceStack[$lastOpeningBrace]['startAt'] - $matchingCount;
+ $pieceEnd = $i + $matchingCount;
+
+ if( is_callable( $matchingCallback ) ) {
+ $cbArgs = array (
+ 'text' => substr($text, $pieceStart, $pieceEnd - $pieceStart),
+ 'title' => trim($openingBraceStack[$lastOpeningBrace]['title']),
+ 'parts' => $openingBraceStack[$lastOpeningBrace]['parts'],
+ 'lineStart' => (($pieceStart > 0) && ($text[$pieceStart-1] == "\n")),
+ );
+ # finally we can call a user callback and replace piece of text
+ $replaceWith = call_user_func( $matchingCallback, $cbArgs );
+ $text = substr($text, 0, $pieceStart) . $replaceWith . substr($text, $pieceEnd);
+ $i = $pieceStart + strlen($replaceWith);
+ } else {
+ # null value for callback means that parentheses should be parsed, but not replaced
+ $i += $matchingCount;
+ }
+
+ # reset last opening parentheses, but keep it in case there are unused characters
+ $piece = array('brace' => $openingBraceStack[$lastOpeningBrace]['brace'],
+ 'braceEnd' => $openingBraceStack[$lastOpeningBrace]['braceEnd'],
+ 'count' => $openingBraceStack[$lastOpeningBrace]['count'],
+ 'title' => '',
+ 'parts' => null,
+ 'startAt' => $openingBraceStack[$lastOpeningBrace]['startAt']);
+ $openingBraceStack[$lastOpeningBrace--] = null;
+
+ if ($matchingCount < $piece['count']) {
+ $piece['count'] -= $matchingCount;
+ $piece['startAt'] -= $matchingCount;
+ $piece['partStart'] = $piece['startAt'];
+ # do we still qualify for any callback with remaining count?
+ $currentCbList = $callbacks[$piece['brace']]['cb'];
+ while ( $piece['count'] ) {
+ if ( array_key_exists( $piece['count'], $currentCbList ) ) {
+ $lastOpeningBrace++;
+ $openingBraceStack[$lastOpeningBrace] = $piece;
+ break;
+ }
+ --$piece['count'];
+ }
+ }
+ } elseif ( $found == 'pipe' ) {
+ # lets set a title if it is a first separator, or next part otherwise
+ if (null === $openingBraceStack[$lastOpeningBrace]['parts']) {
+ $openingBraceStack[$lastOpeningBrace]['title'] =
+ substr($text, $openingBraceStack[$lastOpeningBrace]['partStart'],
+ $i - $openingBraceStack[$lastOpeningBrace]['partStart']);
+ $openingBraceStack[$lastOpeningBrace]['parts'] = array();
+ } else {
+ $openingBraceStack[$lastOpeningBrace]['parts'][] =
+ substr($text, $openingBraceStack[$lastOpeningBrace]['partStart'],
+ $i - $openingBraceStack[$lastOpeningBrace]['partStart']);
+ }
+ $openingBraceStack[$lastOpeningBrace]['partStart'] = ++$i;
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * Replace magic variables, templates, and template arguments
+ * with the appropriate text. Templates are substituted recursively,
+ * taking care to avoid infinite loops.
+ *
+ * Note that the substitution depends on value of $mOutputType:
+ * OT_WIKI: only {{subst:}} templates
+ * OT_MSG: only magic variables
+ * OT_HTML: all templates and magic variables
+ *
+ * @param string $tex The text to transform
+ * @param array $args Key-value pairs representing template parameters to substitute
+ * @param bool $argsOnly Only do argument (triple-brace) expansion, not double-brace expansion
+ * @private
+ */
+ function replaceVariables( $text, $args = array(), $argsOnly = false ) {
+ # Prevent too big inclusions
+ if( strlen( $text ) > $this->mOptions->getMaxIncludeSize() ) {
+ return $text;
+ }
+
+ $fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
+ wfProfileIn( $fname );
+
+ # This function is called recursively. To keep track of arguments we need a stack:
+ array_push( $this->mArgStack, $args );
+
+ $braceCallbacks = array();
+ if ( !$argsOnly ) {
+ $braceCallbacks[2] = array( &$this, 'braceSubstitution' );
+ }
+ if ( $this->mOutputType != OT_MSG ) {
+ $braceCallbacks[3] = array( &$this, 'argSubstitution' );
+ }
+ if ( $braceCallbacks ) {
+ $callbacks = array(
+ '{' => array(
+ 'end' => '}',
+ 'cb' => $braceCallbacks,
+ 'min' => $argsOnly ? 3 : 2,
+ 'max' => isset( $braceCallbacks[3] ) ? 3 : 2,
+ ),
+ '[' => array(
+ 'end' => ']',
+ 'cb' => array(2=>null),
+ 'min' => 2,
+ 'max' => 2,
+ )
+ );
+ $text = $this->replace_callback ($text, $callbacks);
+
+ array_pop( $this->mArgStack );
+ }
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ /**
+ * Replace magic variables
+ * @private
+ */
+ function variableSubstitution( $matches ) {
+ global $wgContLang;
+ $fname = 'Parser::variableSubstitution';
+ $varname = $wgContLang->lc($matches[1]);
+ wfProfileIn( $fname );
+ $skip = false;
+ if ( $this->mOutputType == OT_WIKI ) {
+ # Do only magic variables prefixed by SUBST
+ $mwSubst =& MagicWord::get( 'subst' );
+ if (!$mwSubst->matchStartAndRemove( $varname ))
+ $skip = true;
+ # Note that if we don't substitute the variable below,
+ # we don't remove the {{subst:}} magic word, in case
+ # it is a template rather than a magic variable.
+ }
+ if ( !$skip && array_key_exists( $varname, $this->mVariables ) ) {
+ $id = $this->mVariables[$varname];
+ # Now check if we did really match, case sensitive or not
+ $mw =& MagicWord::get( $id );
+ if ($mw->match($matches[1])) {
+ $text = $this->getVariableValue( $id );
+ $this->mOutput->mContainsOldMagic = true;
+ } else {
+ $text = $matches[0];
+ }
+ } else {
+ $text = $matches[0];
+ }
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+
+ /// Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.
+ static function createAssocArgs( $args ) {
+ $assocArgs = array();
+ $index = 1;
+ foreach( $args as $arg ) {
+ $eqpos = strpos( $arg, '=' );
+ if ( $eqpos === false ) {
+ $assocArgs[$index++] = $arg;
+ } else {
+ $name = trim( substr( $arg, 0, $eqpos ) );
+ $value = trim( substr( $arg, $eqpos+1 ) );
+ if ( $value === false ) {
+ $value = '';
+ }
+ if ( $name !== false ) {
+ $assocArgs[$name] = $value;
+ }
+ }
+ }
+
+ return $assocArgs;
+ }
+
+ /**
+ * Return the text of a template, after recursively
+ * replacing any variables or templates within the template.
+ *
+ * @param array $piece The parts of the template
+ * $piece['text']: matched text
+ * $piece['title']: the title, i.e. the part before the |
+ * $piece['parts']: the parameter array
+ * @return string the text of the template
+ * @private
+ */
+ function braceSubstitution( $piece ) {
+ global $wgContLang, $wgLang, $wgAllowDisplayTitle;
+ $fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
+ wfProfileIn( $fname );
+ wfProfileIn( __METHOD__.'-setup' );
+
+ # Flags
+ $found = false; # $text has been filled
+ $nowiki = false; # wiki markup in $text should be escaped
+ $noparse = false; # Unsafe HTML tags should not be stripped, etc.
+ $noargs = false; # Don't replace triple-brace arguments in $text
+ $replaceHeadings = false; # Make the edit section links go to the template not the article
+ $headingOffset = 0; # Skip headings when number, to account for those that weren't transcluded.
+ $isHTML = false; # $text is HTML, armour it against wikitext transformation
+ $forceRawInterwiki = false; # Force interwiki transclusion to be done in raw mode not rendered
+
+ # Title object, where $text came from
+ $title = NULL;
+
+ $linestart = '';
+
+
+ # $part1 is the bit before the first |, and must contain only title characters
+ # $args is a list of arguments, starting from index 0, not including $part1
+
+ $titleText = $part1 = $piece['title'];
+ # If the third subpattern matched anything, it will start with |
+
+ if (null == $piece['parts']) {
+ $replaceWith = $this->variableSubstitution (array ($piece['text'], $piece['title']));
+ if ($replaceWith != $piece['text']) {
+ $text = $replaceWith;
+ $found = true;
+ $noparse = true;
+ $noargs = true;
+ }
+ }
+
+ $args = (null == $piece['parts']) ? array() : $piece['parts'];
+ wfProfileOut( __METHOD__.'-setup' );
+
+ # SUBST
+ wfProfileIn( __METHOD__.'-modifiers' );
+ if ( !$found ) {
+ $mwSubst =& MagicWord::get( 'subst' );
+ if ( $mwSubst->matchStartAndRemove( $part1 ) xor $this->ot['wiki'] ) {
+ # One of two possibilities is true:
+ # 1) Found SUBST but not in the PST phase
+ # 2) Didn't find SUBST and in the PST phase
+ # In either case, return without further processing
+ $text = $piece['text'];
+ $found = true;
+ $noparse = true;
+ $noargs = true;
+ }
+ }
+
+ # MSG, MSGNW and RAW
+ if ( !$found ) {
+ # Check for MSGNW:
+ $mwMsgnw =& MagicWord::get( 'msgnw' );
+ if ( $mwMsgnw->matchStartAndRemove( $part1 ) ) {
+ $nowiki = true;
+ } else {
+ # Remove obsolete MSG:
+ $mwMsg =& MagicWord::get( 'msg' );
+ $mwMsg->matchStartAndRemove( $part1 );
+ }
+
+ # Check for RAW:
+ $mwRaw =& MagicWord::get( 'raw' );
+ if ( $mwRaw->matchStartAndRemove( $part1 ) ) {
+ $forceRawInterwiki = true;
+ }
+ }
+ wfProfileOut( __METHOD__.'-modifiers' );
+
+ //save path level before recursing into functions & templates.
+ $lastPathLevel = $this->mTemplatePath;
+
+ # Parser functions
+ if ( !$found ) {
+ wfProfileIn( __METHOD__ . '-pfunc' );
+
+ $colonPos = strpos( $part1, ':' );
+ if ( $colonPos !== false ) {
+ # Case sensitive functions
+ $function = substr( $part1, 0, $colonPos );
+ if ( isset( $this->mFunctionSynonyms[1][$function] ) ) {
+ $function = $this->mFunctionSynonyms[1][$function];
+ } else {
+ # Case insensitive functions
+ $function = strtolower( $function );
+ if ( isset( $this->mFunctionSynonyms[0][$function] ) ) {
+ $function = $this->mFunctionSynonyms[0][$function];
+ } else {
+ $function = false;
+ }
+ }
+ if ( $function ) {
+ $funcArgs = array_map( 'trim', $args );
+ $funcArgs = array_merge( array( &$this, trim( substr( $part1, $colonPos + 1 ) ) ), $funcArgs );
+ $result = call_user_func_array( $this->mFunctionHooks[$function], $funcArgs );
+ $found = true;
+
+ // The text is usually already parsed, doesn't need triple-brace tags expanded, etc.
+ //$noargs = true;
+ //$noparse = true;
+
+ if ( is_array( $result ) ) {
+ if ( isset( $result[0] ) ) {
+ $text = $linestart . $result[0];
+ unset( $result[0] );
+ }
+
+ // Extract flags into the local scope
+ // This allows callers to set flags such as nowiki, noparse, found, etc.
+ extract( $result );
+ } else {
+ $text = $linestart . $result;
+ }
+ }
+ }
+ wfProfileOut( __METHOD__ . '-pfunc' );
+ }
+
+ # Template table test
+
+ # Did we encounter this template already? If yes, it is in the cache
+ # and we need to check for loops.
+ if ( !$found && isset( $this->mTemplates[$piece['title']] ) ) {
+ $found = true;
+
+ # Infinite loop test
+ if ( isset( $this->mTemplatePath[$part1] ) ) {
+ $noparse = true;
+ $noargs = true;
+ $found = true;
+ $text = $linestart .
+ "[[$part1]]<!-- WARNING: template loop detected -->";
+ wfDebug( __METHOD__.": template loop broken at '$part1'\n" );
+ } else {
+ # set $text to cached message.
+ $text = $linestart . $this->mTemplates[$piece['title']];
+ }
+ }
+
+ # Load from database
+ if ( !$found ) {
+ wfProfileIn( __METHOD__ . '-loadtpl' );
+ $ns = NS_TEMPLATE;
+ # declaring $subpage directly in the function call
+ # does not work correctly with references and breaks
+ # {{/subpage}}-style inclusions
+ $subpage = '';
+ $part1 = $this->maybeDoSubpageLink( $part1, $subpage );
+ if ($subpage !== '') {
+ $ns = $this->mTitle->getNamespace();
+ }
+ $title = Title::newFromText( $part1, $ns );
+
+
+ if ( !is_null( $title ) ) {
+ $titleText = $title->getPrefixedText();
+ # Check for language variants if the template is not found
+ if($wgContLang->hasVariants() && $title->getArticleID() == 0){
+ $wgContLang->findVariantLink($part1, $title);
+ }
+
+ if ( !$title->isExternal() ) {
+ if ( $title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html'] ) {
+ $text = SpecialPage::capturePath( $title );
+ if ( is_string( $text ) ) {
+ $found = true;
+ $noparse = true;
+ $noargs = true;
+ $isHTML = true;
+ $this->disableCache();
+ }
+ } else {
+ $articleContent = $this->fetchTemplate( $title );
+ if ( $articleContent !== false ) {
+ $found = true;
+ $text = $articleContent;
+ $replaceHeadings = true;
+ }
+ }
+
+ # If the title is valid but undisplayable, make a link to it
+ if ( !$found && ( $this->ot['html'] || $this->ot['pre'] ) ) {
+ $text = "[[:$titleText]]";
+ $found = true;
+ }
+ } elseif ( $title->isTrans() ) {
+ // Interwiki transclusion
+ if ( $this->ot['html'] && !$forceRawInterwiki ) {
+ $text = $this->interwikiTransclude( $title, 'render' );
+ $isHTML = true;
+ $noparse = true;
+ } else {
+ $text = $this->interwikiTransclude( $title, 'raw' );
+ $replaceHeadings = true;
+ }
+ $found = true;
+ }
+
+ # Template cache array insertion
+ # Use the original $piece['title'] not the mangled $part1, so that
+ # modifiers such as RAW: produce separate cache entries
+ if( $found ) {
+ if( $isHTML ) {
+ // A special page; don't store it in the template cache.
+ } else {
+ $this->mTemplates[$piece['title']] = $text;
+ }
+ $text = $linestart . $text;
+ }
+ }
+ wfProfileOut( __METHOD__ . '-loadtpl' );
+ }
+
+ if ( $found && !$this->incrementIncludeSize( 'pre-expand', strlen( $text ) ) ) {
+ # Error, oversize inclusion
+ $text = $linestart .
+ "[[$titleText]]<!-- WARNING: template omitted, pre-expand include size too large -->";
+ $noparse = true;
+ $noargs = true;
+ }
+
+ # Recursive parsing, escaping and link table handling
+ # Only for HTML output
+ if ( $nowiki && $found && ( $this->ot['html'] || $this->ot['pre'] ) ) {
+ $text = wfEscapeWikiText( $text );
+ } elseif ( !$this->ot['msg'] && $found ) {
+ if ( $noargs ) {
+ $assocArgs = array();
+ } else {
+ # Clean up argument array
+ $assocArgs = self::createAssocArgs($args);
+ # Add a new element to the templace recursion path
+ $this->mTemplatePath[$part1] = 1;
+ }
+
+ if ( !$noparse ) {
+ # If there are any <onlyinclude> tags, only include them
+ if ( in_string( '<onlyinclude>', $text ) && in_string( '</onlyinclude>', $text ) ) {
+ $replacer = new OnlyIncludeReplacer;
+ StringUtils::delimiterReplaceCallback( '<onlyinclude>', '</onlyinclude>',
+ array( &$replacer, 'replace' ), $text );
+ $text = $replacer->output;
+ }
+ # Remove <noinclude> sections and <includeonly> tags
+ $text = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $text );
+ $text = strtr( $text, array( '<includeonly>' => '' , '</includeonly>' => '' ) );
+
+ if( $this->ot['html'] || $this->ot['pre'] ) {
+ # Strip <nowiki>, <pre>, etc.
+ $text = $this->strip( $text, $this->mStripState );
+ if ( $this->ot['html'] ) {
+ $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'replaceVariables' ), $assocArgs );
+ } elseif ( $this->ot['pre'] && $this->mOptions->getRemoveComments() ) {
+ $text = Sanitizer::removeHTMLcomments( $text );
+ }
+ }
+ $text = $this->replaceVariables( $text, $assocArgs );
+
+ # If the template begins with a table or block-level
+ # element, it should be treated as beginning a new line.
+ if (!$piece['lineStart'] && preg_match('/^({\\||:|;|#|\*)/', $text)) /*}*/{
+ $text = "\n" . $text;
+ }
+ } elseif ( !$noargs ) {
+ # $noparse and !$noargs
+ # Just replace the arguments, not any double-brace items
+ # This is used for rendered interwiki transclusion
+ $text = $this->replaceVariables( $text, $assocArgs, true );
+ }
+ }
+ # Prune lower levels off the recursion check path
+ $this->mTemplatePath = $lastPathLevel;
+
+ if ( $found && !$this->incrementIncludeSize( 'post-expand', strlen( $text ) ) ) {
+ # Error, oversize inclusion
+ $text = $linestart .
+ "[[$titleText]]<!-- WARNING: template omitted, post-expand include size too large -->";
+ $noparse = true;
+ $noargs = true;
+ }
+
+ if ( !$found ) {
+ wfProfileOut( $fname );
+ return $piece['text'];
+ } else {
+ wfProfileIn( __METHOD__ . '-placeholders' );
+ if ( $isHTML ) {
+ # Replace raw HTML by a placeholder
+ # Add a blank line preceding, to prevent it from mucking up
+ # immediately preceding headings
+ $text = "\n\n" . $this->insertStripItem( $text, $this->mStripState );
+ } else {
+ # replace ==section headers==
+ # XXX this needs to go away once we have a better parser.
+ if ( !$this->ot['wiki'] && !$this->ot['pre'] && $replaceHeadings ) {
+ if( !is_null( $title ) )
+ $encodedname = base64_encode($title->getPrefixedDBkey());
+ else
+ $encodedname = base64_encode("");
+ $m = preg_split('/(^={1,6}.*?={1,6}\s*?$)/m', $text, -1,
+ PREG_SPLIT_DELIM_CAPTURE);
+ $text = '';
+ $nsec = $headingOffset;
+ for( $i = 0; $i < count($m); $i += 2 ) {
+ $text .= $m[$i];
+ if (!isset($m[$i + 1]) || $m[$i + 1] == "") continue;
+ $hl = $m[$i + 1];
+ if( strstr($hl, "<!--MWTEMPLATESECTION") ) {
+ $text .= $hl;
+ continue;
+ }
+ $m2 = array();
+ preg_match('/^(={1,6})(.*?)(={1,6})\s*?$/m', $hl, $m2);
+ $text .= $m2[1] . $m2[2] . "<!--MWTEMPLATESECTION="
+ . $encodedname . "&" . base64_encode("$nsec") . "-->" . $m2[3];
+
+ $nsec++;
+ }
+ }
+ }
+ wfProfileOut( __METHOD__ . '-placeholders' );
+ }
+
+ # Prune lower levels off the recursion check path
+ $this->mTemplatePath = $lastPathLevel;
+
+ if ( !$found ) {
+ wfProfileOut( $fname );
+ return $piece['text'];
+ } else {
+ wfProfileOut( $fname );
+ return $text;
+ }
+ }
+
+ /**
+ * Fetch the unparsed text of a template and register a reference to it.
+ */
+ function fetchTemplate( $title ) {
+ $text = false;
+ // Loop to fetch the article, with up to 1 redirect
+ for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) {
+ $rev = Revision::newFromTitle( $title );
+ $this->mOutput->addTemplate( $title, $title->getArticleID() );
+ if ( $rev ) {
+ $text = $rev->getText();
+ } elseif( $title->getNamespace() == NS_MEDIAWIKI ) {
+ global $wgLang;
+ $message = $wgLang->lcfirst( $title->getText() );
+ $text = wfMsgForContentNoTrans( $message );
+ if( wfEmptyMsg( $message, $text ) ) {
+ $text = false;
+ break;
+ }
+ } else {
+ break;
+ }
+ if ( $text === false ) {
+ break;
+ }
+ // Redirect?
+ $title = Title::newFromRedirect( $text );
+ }
+ return $text;
+ }
+
+ /**
+ * Transclude an interwiki link.
+ */
+ function interwikiTransclude( $title, $action ) {
+ global $wgEnableScaryTranscluding;
+
+ if (!$wgEnableScaryTranscluding)
+ return wfMsg('scarytranscludedisabled');
+
+ $url = $title->getFullUrl( "action=$action" );
+
+ if (strlen($url) > 255)
+ return wfMsg('scarytranscludetoolong');
+ return $this->fetchScaryTemplateMaybeFromCache($url);
+ }
+
+ function fetchScaryTemplateMaybeFromCache($url) {
+ global $wgTranscludeCacheExpiry;
+ $dbr =& wfGetDB(DB_SLAVE);
+ $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'),
+ array('tc_url' => $url));
+ if ($obj) {
+ $time = $obj->tc_time;
+ $text = $obj->tc_contents;
+ if ($time && time() < $time + $wgTranscludeCacheExpiry ) {
+ return $text;
+ }
+ }
+
+ $text = Http::get($url);
+ if (!$text)
+ return wfMsg('scarytranscludefailed', $url);
+
+ $dbw =& wfGetDB(DB_MASTER);
+ $dbw->replace('transcache', array('tc_url'), array(
+ 'tc_url' => $url,
+ 'tc_time' => time(),
+ 'tc_contents' => $text));
+ return $text;
+ }
+
+
+ /**
+ * Triple brace replacement -- used for template arguments
+ * @private
+ */
+ function argSubstitution( $matches ) {
+ $arg = trim( $matches['title'] );
+ $text = $matches['text'];
+ $inputArgs = end( $this->mArgStack );
+
+ if ( array_key_exists( $arg, $inputArgs ) ) {
+ $text = $inputArgs[$arg];
+ } else if (($this->mOutputType == OT_HTML || $this->mOutputType == OT_PREPROCESS ) &&
+ null != $matches['parts'] && count($matches['parts']) > 0) {
+ $text = $matches['parts'][0];
+ }
+ if ( !$this->incrementIncludeSize( 'arg', strlen( $text ) ) ) {
+ $text = $matches['text'] .
+ '<!-- WARNING: argument omitted, expansion size too large -->';
+ }
+
+ return $text;
+ }
+
+ /**
+ * Increment an include size counter
+ *
+ * @param string $type The type of expansion
+ * @param integer $size The size of the text
+ * @return boolean False if this inclusion would take it over the maximum, true otherwise
+ */
+ function incrementIncludeSize( $type, $size ) {
+ if ( $this->mIncludeSizes[$type] + $size > $this->mOptions->getMaxIncludeSize() ) {
+ return false;
+ } else {
+ $this->mIncludeSizes[$type] += $size;
+ return true;
+ }
+ }
+
+ /**
+ * Detect __NOGALLERY__ magic word and set a placeholder
+ */
+ function stripNoGallery( &$text ) {
+ # if the string __NOGALLERY__ (not case-sensitive) occurs in the HTML,
+ # do not add TOC
+ $mw = MagicWord::get( 'nogallery' );
+ $this->mOutput->mNoGallery = $mw->matchAndRemove( $text ) ;
+ }
+
+ /**
+ * Detect __TOC__ magic word and set a placeholder
+ */
+ function stripToc( $text ) {
+ # if the string __NOTOC__ (not case-sensitive) occurs in the HTML,
+ # do not add TOC
+ $mw = MagicWord::get( 'notoc' );
+ if( $mw->matchAndRemove( $text ) ) {
+ $this->mShowToc = false;
+ }
+
+ $mw = MagicWord::get( 'toc' );
+ if( $mw->match( $text ) ) {
+ $this->mShowToc = true;
+ $this->mForceTocPosition = true;
+
+ // Set a placeholder. At the end we'll fill it in with the TOC.
+ $text = $mw->replace( '<!--MWTOC-->', $text, 1 );
+
+ // Only keep the first one.
+ $text = $mw->replace( '', $text );
+ }
+ return $text;
+ }
+
+ /**
+ * This function accomplishes several tasks:
+ * 1) Auto-number headings if that option is enabled
+ * 2) Add an [edit] link to sections for logged in users who have enabled the option
+ * 3) Add a Table of contents on the top for users who have enabled the option
+ * 4) Auto-anchor headings
+ *
+ * It loops through all headlines, collects the necessary data, then splits up the
+ * string and re-inserts the newly formatted headlines.
+ *
+ * @param string $text
+ * @param boolean $isMain
+ * @private
+ */
+ function formatHeadings( $text, $isMain=true ) {
+ global $wgMaxTocLevel, $wgContLang;
+
+ $doNumberHeadings = $this->mOptions->getNumberHeadings();
+ if( !$this->mTitle->userCanEdit() ) {
+ $showEditLink = 0;
+ } else {
+ $showEditLink = $this->mOptions->getEditSection();
+ }
+
+ # Inhibit editsection links if requested in the page
+ $esw =& MagicWord::get( 'noeditsection' );
+ if( $esw->matchAndRemove( $text ) ) {
+ $showEditLink = 0;
+ }
+
+ # Get all headlines for numbering them and adding funky stuff like [edit]
+ # links - this is for later, but we need the number of headlines right now
+ $matches = array();
+ $numMatches = preg_match_all( '/<H(?P<level>[1-6])(?P<attrib>.*?'.'>)(?P<header>.*?)<\/H[1-6] *>/i', $text, $matches );
+
+ # if there are fewer than 4 headlines in the article, do not show TOC
+ # unless it's been explicitly enabled.
+ $enoughToc = $this->mShowToc &&
+ (($numMatches >= 4) || $this->mForceTocPosition);
+
+ # Allow user to stipulate that a page should have a "new section"
+ # link added via __NEWSECTIONLINK__
+ $mw =& MagicWord::get( 'newsectionlink' );
+ if( $mw->matchAndRemove( $text ) )
+ $this->mOutput->setNewSection( true );
+
+ # if the string __FORCETOC__ (not case-sensitive) occurs in the HTML,
+ # override above conditions and always show TOC above first header
+ $mw =& MagicWord::get( 'forcetoc' );
+ if ($mw->matchAndRemove( $text ) ) {
+ $this->mShowToc = true;
+ $enoughToc = true;
+ }
+
+ # Never ever show TOC if no headers
+ if( $numMatches < 1 ) {
+ $enoughToc = false;
+ }
+
+ # We need this to perform operations on the HTML
+ $sk =& $this->mOptions->getSkin();
+
+ # headline counter
+ $headlineCount = 0;
+ $sectionCount = 0; # headlineCount excluding template sections
+
+ # Ugh .. the TOC should have neat indentation levels which can be
+ # passed to the skin functions. These are determined here
+ $toc = '';
+ $full = '';
+ $head = array();
+ $sublevelCount = array();
+ $levelCount = array();
+ $toclevel = 0;
+ $level = 0;
+ $prevlevel = 0;
+ $toclevel = 0;
+ $prevtoclevel = 0;
+
+ foreach( $matches[3] as $headline ) {
+ $istemplate = 0;
+ $templatetitle = '';
+ $templatesection = 0;
+ $numbering = '';
+ $mat = array();
+ if (preg_match("/<!--MWTEMPLATESECTION=([^&]+)&([^_]+)-->/", $headline, $mat)) {
+ $istemplate = 1;
+ $templatetitle = base64_decode($mat[1]);
+ $templatesection = 1 + (int)base64_decode($mat[2]);
+ $headline = preg_replace("/<!--MWTEMPLATESECTION=([^&]+)&([^_]+)-->/", "", $headline);
+ }
+
+ if( $toclevel ) {
+ $prevlevel = $level;
+ $prevtoclevel = $toclevel;
+ }
+ $level = $matches[1][$headlineCount];
+
+ if( $doNumberHeadings || $enoughToc ) {
+
+ if ( $level > $prevlevel ) {
+ # Increase TOC level
+ $toclevel++;
+ $sublevelCount[$toclevel] = 0;
+ if( $toclevel<$wgMaxTocLevel ) {
+ $toc .= $sk->tocIndent();
+ }
+ }
+ elseif ( $level < $prevlevel && $toclevel > 1 ) {
+ # Decrease TOC level, find level to jump to
+
+ if ( $toclevel == 2 && $level <= $levelCount[1] ) {
+ # Can only go down to level 1
+ $toclevel = 1;
+ } else {
+ for ($i = $toclevel; $i > 0; $i--) {
+ if ( $levelCount[$i] == $level ) {
+ # Found last matching level
+ $toclevel = $i;
+ break;
+ }
+ elseif ( $levelCount[$i] < $level ) {
+ # Found first matching level below current level
+ $toclevel = $i + 1;
+ break;
+ }
+ }
+ }
+ if( $toclevel<$wgMaxTocLevel ) {
+ $toc .= $sk->tocUnindent( $prevtoclevel - $toclevel );
+ }
+ }
+ else {
+ # No change in level, end TOC line
+ if( $toclevel<$wgMaxTocLevel ) {
+ $toc .= $sk->tocLineEnd();
+ }
+ }
+
+ $levelCount[$toclevel] = $level;
+
+ # count number of headlines for each level
+ @$sublevelCount[$toclevel]++;
+ $dot = 0;
+ for( $i = 1; $i <= $toclevel; $i++ ) {
+ if( !empty( $sublevelCount[$i] ) ) {
+ if( $dot ) {
+ $numbering .= '.';
+ }
+ $numbering .= $wgContLang->formatNum( $sublevelCount[$i] );
+ $dot = 1;
+ }
+ }
+ }
+
+ # The canonized header is a version of the header text safe to use for links
+ # Avoid insertion of weird stuff like <math> by expanding the relevant sections
+ $canonized_headline = $this->mStripState->unstripBoth( $headline );
+
+ # Remove link placeholders by the link text.
+ # <!--LINK number-->
+ # turns into
+ # link text with suffix
+ $canonized_headline = preg_replace( '/<!--LINK ([0-9]*)-->/e',
+ "\$this->mLinkHolders['texts'][\$1]",
+ $canonized_headline );
+ $canonized_headline = preg_replace( '/<!--IWLINK ([0-9]*)-->/e',
+ "\$this->mInterwikiLinkHolders['texts'][\$1]",
+ $canonized_headline );
+
+ # strip out HTML
+ $canonized_headline = preg_replace( '/<.*?' . '>/','',$canonized_headline );
+ $tocline = trim( $canonized_headline );
+ # Save headline for section edit hint before it's escaped
+ $headline_hint = trim( $canonized_headline );
+ $canonized_headline = Sanitizer::escapeId( $tocline );
+ $refers[$headlineCount] = $canonized_headline;
+
+ # count how many in assoc. array so we can track dupes in anchors
+ isset( $refers[$canonized_headline] ) ? $refers[$canonized_headline]++ : $refers[$canonized_headline] = 1;
+ $refcount[$headlineCount]=$refers[$canonized_headline];
+
+ # Don't number the heading if it is the only one (looks silly)
+ if( $doNumberHeadings && count( $matches[3] ) > 1) {
+ # the two are different if the line contains a link
+ $headline=$numbering . ' ' . $headline;
+ }
+
+ # Create the anchor for linking from the TOC to the section
+ $anchor = $canonized_headline;
+ if($refcount[$headlineCount] > 1 ) {
+ $anchor .= '_' . $refcount[$headlineCount];
+ }
+ if( $enoughToc && ( !isset($wgMaxTocLevel) || $toclevel<$wgMaxTocLevel ) ) {
+ $toc .= $sk->tocLine($anchor, $tocline, $numbering, $toclevel);
+ }
+ # give headline the correct <h#> tag
+ if( $showEditLink && ( !$istemplate || $templatetitle !== "" ) ) {
+ if( $istemplate )
+ $editlink = $sk->editSectionLinkForOther($templatetitle, $templatesection);
+ else
+ $editlink = $sk->editSectionLink($this->mTitle, $sectionCount+1, $headline_hint);
+ } else {
+ $editlink = '';
+ }
+ $head[$headlineCount] = $sk->makeHeadline( $level, $matches['attrib'][$headlineCount], $anchor, $headline, $editlink );
+
+ $headlineCount++;
+ if( !$istemplate )
+ $sectionCount++;
+ }
+
+ if( $enoughToc ) {
+ if( $toclevel<$wgMaxTocLevel ) {
+ $toc .= $sk->tocUnindent( $toclevel - 1 );
+ }
+ $toc = $sk->tocList( $toc );
+ }
+
+ # split up and insert constructed headlines
+
+ $blocks = preg_split( '/<H[1-6].*?' . '>.*?<\/H[1-6]>/i', $text );
+ $i = 0;
+
+ foreach( $blocks as $block ) {
+ if( $showEditLink && $headlineCount > 0 && $i == 0 && $block != "\n" ) {
+ # This is the [edit] link that appears for the top block of text when
+ # section editing is enabled
+
+ # Disabled because it broke block formatting
+ # For example, a bullet point in the top line
+ # $full .= $sk->editSectionLink(0);
+ }
+ $full .= $block;
+ if( $enoughToc && !$i && $isMain && !$this->mForceTocPosition ) {
+ # Top anchor now in skin
+ $full = $full.$toc;
+ }
+
+ if( !empty( $head[$i] ) ) {
+ $full .= $head[$i];
+ }
+ $i++;
+ }
+ if( $this->mForceTocPosition ) {
+ return str_replace( '<!--MWTOC-->', $toc, $full );
+ } else {
+ return $full;
+ }
+ }
+
+ /**
+ * Transform wiki markup when saving a page by doing \r\n -> \n
+ * conversion, substitting signatures, {{subst:}} templates, etc.
+ *
+ * @param string $text the text to transform
+ * @param Title &$title the Title object for the current article
+ * @param User &$user the User object describing the current user
+ * @param ParserOptions $options parsing options
+ * @param bool $clearState whether to clear the parser state first
+ * @return string the altered wiki markup
+ * @public
+ */
+ function preSaveTransform( $text, &$title, $user, $options, $clearState = true ) {
+ $this->mOptions = $options;
+ $this->mTitle =& $title;
+ $this->setOutputType( OT_WIKI );
+
+ if ( $clearState ) {
+ $this->clearState();
+ }
+
+ $stripState = new StripState;
+ $pairs = array(
+ "\r\n" => "\n",
+ );
+ $text = str_replace( array_keys( $pairs ), array_values( $pairs ), $text );
+ $text = $this->strip( $text, $stripState, true, array( 'gallery' ) );
+ $text = $this->pstPass2( $text, $stripState, $user );
+ $text = $stripState->unstripBoth( $text );
+ return $text;
+ }
+
+ /**
+ * Pre-save transform helper function
+ * @private
+ */
+ function pstPass2( $text, &$stripState, $user ) {
+ global $wgContLang, $wgLocaltimezone;
+
+ /* Note: This is the timestamp saved as hardcoded wikitext to
+ * the database, we use $wgContLang here in order to give
+ * everyone the same signature and use the default one rather
+ * than the one selected in each user's preferences.
+ */
+ if ( isset( $wgLocaltimezone ) ) {
+ $oldtz = getenv( 'TZ' );
+ putenv( 'TZ='.$wgLocaltimezone );
+ }
+ $d = $wgContLang->timeanddate( date( 'YmdHis' ), false, false) .
+ ' (' . date( 'T' ) . ')';
+ if ( isset( $wgLocaltimezone ) ) {
+ putenv( 'TZ='.$oldtz );
+ }
+
+ # Variable replacement
+ # Because mOutputType is OT_WIKI, this will only process {{subst:xxx}} type tags
+ $text = $this->replaceVariables( $text );
+
+ # Strip out <nowiki> etc. added via replaceVariables
+ $text = $this->strip( $text, $stripState, false, array( 'gallery' ) );
+
+ # Signatures
+ $sigText = $this->getUserSig( $user );
+ $text = strtr( $text, array(
+ '~~~~~' => $d,
+ '~~~~' => "$sigText $d",
+ '~~~' => $sigText
+ ) );
+
+ # Context links: [[|name]] and [[name (context)|]]
+ #
+ global $wgLegalTitleChars;
+ $tc = "[$wgLegalTitleChars]";
+ $nc = '[ _0-9A-Za-z\x80-\xff]'; # Namespaces can use non-ascii!
+
+ $p1 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\))\\|]]/"; # [[ns:page (context)|]]
+ $p3 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\)|)(, $tc+|)\\|]]/"; # [[ns:page (context), context|]]
+ $p2 = "/\[\[\\|($tc+)]]/"; # [[|page]]
+
+ # try $p1 first, to turn "[[A, B (C)|]]" into "[[A, B (C)|A, B]]"
+ $text = preg_replace( $p1, '[[\\1\\2\\3|\\2]]', $text );
+ $text = preg_replace( $p3, '[[\\1\\2\\3\\4|\\2]]', $text );
+
+ $t = $this->mTitle->getText();
+ $m = array();
+ if ( preg_match( "/^($nc+:|)$tc+?( \\($tc+\\))$/", $t, $m ) ) {
+ $text = preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text );
+ } elseif ( preg_match( "/^($nc+:|)$tc+?(, $tc+|)$/", $t, $m ) && '' != "$m[1]$m[2]" ) {
+ $text = preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text );
+ } else {
+ # if there's no context, don't bother duplicating the title
+ $text = preg_replace( $p2, '[[\\1]]', $text );
+ }
+
+ # Trim trailing whitespace
+ # __END__ tag allows for trailing
+ # whitespace to be deliberately included
+ $text = rtrim( $text );
+ $mw =& MagicWord::get( 'end' );
+ $mw->matchAndRemove( $text );
+
+ return $text;
+ }
+
+ /**
+ * Fetch the user's signature text, if any, and normalize to
+ * validated, ready-to-insert wikitext.
+ *
+ * @param User $user
+ * @return string
+ * @private
+ */
+ function getUserSig( &$user ) {
+ $username = $user->getName();
+ $nickname = $user->getOption( 'nickname' );
+ $nickname = $nickname === '' ? $username : $nickname;
+
+ if( $user->getBoolOption( 'fancysig' ) !== false ) {
+ # Sig. might contain markup; validate this
+ if( $this->validateSig( $nickname ) !== false ) {
+ # Validated; clean up (if needed) and return it
+ return $this->cleanSig( $nickname, true );
+ } else {
+ # Failed to validate; fall back to the default
+ $nickname = $username;
+ wfDebug( "Parser::getUserSig: $username has bad XML tags in signature.\n" );
+ }
+ }
+
+ // Make sure nickname doesnt get a sig in a sig
+ $nickname = $this->cleanSigInSig( $nickname );
+
+ # If we're still here, make it a link to the user page
+ $userpage = $user->getUserPage();
+ return( '[[' . $userpage->getPrefixedText() . '|' . wfEscapeWikiText( $nickname ) . ']]' );
+ }
+
+ /**
+ * Check that the user's signature contains no bad XML
+ *
+ * @param string $text
+ * @return mixed An expanded string, or false if invalid.
+ */
+ function validateSig( $text ) {
+ return( wfIsWellFormedXmlFragment( $text ) ? $text : false );
+ }
+
+ /**
+ * Clean up signature text
+ *
+ * 1) Strip ~~~, ~~~~ and ~~~~~ out of signatures @see cleanSigInSig
+ * 2) Substitute all transclusions
+ *
+ * @param string $text
+ * @param $parsing Whether we're cleaning (preferences save) or parsing
+ * @return string Signature text
+ */
+ function cleanSig( $text, $parsing = false ) {
+ global $wgTitle;
+ $this->startExternalParse( $wgTitle, new ParserOptions(), $parsing ? OT_WIKI : OT_MSG );
+
+ $substWord = MagicWord::get( 'subst' );
+ $substRegex = '/\{\{(?!(?:' . $substWord->getBaseRegex() . '))/x' . $substWord->getRegexCase();
+ $substText = '{{' . $substWord->getSynonym( 0 );
+
+ $text = preg_replace( $substRegex, $substText, $text );
+ $text = $this->cleanSigInSig( $text );
+ $text = $this->replaceVariables( $text );
+
+ $this->clearState();
+ return $text;
+ }
+
+ /**
+ * Strip ~~~, ~~~~ and ~~~~~ out of signatures
+ * @param string $text
+ * @return string Signature text with /~{3,5}/ removed
+ */
+ function cleanSigInSig( $text ) {
+ $text = preg_replace( '/~{3,5}/', '', $text );
+ return $text;
+ }
+
+ /**
+ * Set up some variables which are usually set up in parse()
+ * so that an external function can call some class members with confidence
+ * @public
+ */
+ function startExternalParse( &$title, $options, $outputType, $clearState = true ) {
+ $this->mTitle =& $title;
+ $this->mOptions = $options;
+ $this->setOutputType( $outputType );
+ if ( $clearState ) {
+ $this->clearState();
+ }
+ }
+
+ /**
+ * Transform a MediaWiki message by replacing magic variables.
+ *
+ * @param string $text the text to transform
+ * @param ParserOptions $options options
+ * @return string the text with variables substituted
+ * @public
+ */
+ function transformMsg( $text, $options ) {
+ global $wgTitle;
+ static $executing = false;
+
+ $fname = "Parser::transformMsg";
+
+ # Guard against infinite recursion
+ if ( $executing ) {
+ return $text;
+ }
+ $executing = true;
+
+ wfProfileIn($fname);
+
+ if ( $wgTitle ) {
+ $this->mTitle = $wgTitle;
+ } else {
+ $this->mTitle = Title::newFromText('msg');
+ }
+ $this->mOptions = $options;
+ $this->setOutputType( OT_MSG );
+ $this->clearState();
+ $text = $this->replaceVariables( $text );
+
+ $executing = false;
+ wfProfileOut($fname);
+ return $text;
+ }
+
+ /**
+ * Create an HTML-style tag, e.g. <yourtag>special text</yourtag>
+ * The callback should have the following form:
+ * function myParserHook( $text, $params, &$parser ) { ... }
+ *
+ * Transform and return $text. Use $parser for any required context, e.g. use
+ * $parser->getTitle() and $parser->getOptions() not $wgTitle or $wgOut->mParserOptions
+ *
+ * @public
+ *
+ * @param mixed $tag The tag to use, e.g. 'hook' for <hook>
+ * @param mixed $callback The callback function (and object) to use for the tag
+ *
+ * @return The old value of the mTagHooks array associated with the hook
+ */
+ function setHook( $tag, $callback ) {
+ $tag = strtolower( $tag );
+ $oldVal = isset( $this->mTagHooks[$tag] ) ? $this->mTagHooks[$tag] : null;
+ $this->mTagHooks[$tag] = $callback;
+
+ return $oldVal;
+ }
+
+ /**
+ * Create a function, e.g. {{sum:1|2|3}}
+ * The callback function should have the form:
+ * function myParserFunction( &$parser, $arg1, $arg2, $arg3 ) { ... }
+ *
+ * The callback may either return the text result of the function, or an array with the text
+ * in element 0, and a number of flags in the other elements. The names of the flags are
+ * specified in the keys. Valid flags are:
+ * found The text returned is valid, stop processing the template. This
+ * is on by default.
+ * nowiki Wiki markup in the return value should be escaped
+ * noparse Unsafe HTML tags should not be stripped, etc.
+ * noargs Don't replace triple-brace arguments in the return value
+ * isHTML The returned text is HTML, armour it against wikitext transformation
+ *
+ * @public
+ *
+ * @param string $id The magic word ID
+ * @param mixed $callback The callback function (and object) to use
+ * @param integer $flags a combination of the following flags:
+ * SFH_NO_HASH No leading hash, i.e. {{plural:...}} instead of {{#if:...}}
+ *
+ * @return The old callback function for this name, if any
+ */
+ function setFunctionHook( $id, $callback, $flags = 0 ) {
+ $oldVal = isset( $this->mFunctionHooks[$id] ) ? $this->mFunctionHooks[$id] : null;
+ $this->mFunctionHooks[$id] = $callback;
+
+ # Add to function cache
+ $mw = MagicWord::get( $id );
+ if( !$mw )
+ throw new MWException( 'Parser::setFunctionHook() expecting a magic word identifier.' );
+
+ $synonyms = $mw->getSynonyms();
+ $sensitive = intval( $mw->isCaseSensitive() );
+
+ foreach ( $synonyms as $syn ) {
+ # Case
+ if ( !$sensitive ) {
+ $syn = strtolower( $syn );
+ }
+ # Add leading hash
+ if ( !( $flags & SFH_NO_HASH ) ) {
+ $syn = '#' . $syn;
+ }
+ # Remove trailing colon
+ if ( substr( $syn, -1, 1 ) == ':' ) {
+ $syn = substr( $syn, 0, -1 );
+ }
+ $this->mFunctionSynonyms[$sensitive][$syn] = $id;
+ }
+ return $oldVal;
+ }
+
+ /**
+ * Get all registered function hook identifiers
+ *
+ * @return array
+ */
+ function getFunctionHooks() {
+ return array_keys( $this->mFunctionHooks );
+ }
+
+ /**
+ * Replace <!--LINK--> link placeholders with actual links, in the buffer
+ * Placeholders created in Skin::makeLinkObj()
+ * Returns an array of links found, indexed by PDBK:
+ * 0 - broken
+ * 1 - normal link
+ * 2 - stub
+ * $options is a bit field, RLH_FOR_UPDATE to select for update
+ */
+ function replaceLinkHolders( &$text, $options = 0 ) {
+ global $wgUser;
+ global $wgContLang;
+
+ $fname = 'Parser::replaceLinkHolders';
+ wfProfileIn( $fname );
+
+ $pdbks = array();
+ $colours = array();
+ $sk =& $this->mOptions->getSkin();
+ $linkCache =& LinkCache::singleton();
+
+ if ( !empty( $this->mLinkHolders['namespaces'] ) ) {
+ wfProfileIn( $fname.'-check' );
+ $dbr =& wfGetDB( DB_SLAVE );
+ $page = $dbr->tableName( 'page' );
+ $threshold = $wgUser->getOption('stubthreshold');
+
+ # Sort by namespace
+ asort( $this->mLinkHolders['namespaces'] );
+
+ # Generate query
+ $query = false;
+ $current = null;
+ foreach ( $this->mLinkHolders['namespaces'] as $key => $ns ) {
+ # Make title object
+ $title = $this->mLinkHolders['titles'][$key];
+
+ # Skip invalid entries.
+ # Result will be ugly, but prevents crash.
+ if ( is_null( $title ) ) {
+ continue;
+ }
+ $pdbk = $pdbks[$key] = $title->getPrefixedDBkey();
+
+ # Check if it's a static known link, e.g. interwiki
+ if ( $title->isAlwaysKnown() ) {
+ $colours[$pdbk] = 1;
+ } elseif ( ( $id = $linkCache->getGoodLinkID( $pdbk ) ) != 0 ) {
+ $colours[$pdbk] = 1;
+ $this->mOutput->addLink( $title, $id );
+ } elseif ( $linkCache->isBadLink( $pdbk ) ) {
+ $colours[$pdbk] = 0;
+ } else {
+ # Not in the link cache, add it to the query
+ if ( !isset( $current ) ) {
+ $current = $ns;
+ $query = "SELECT page_id, page_namespace, page_title";
+ if ( $threshold > 0 ) {
+ $query .= ', page_len, page_is_redirect';
+ }
+ $query .= " FROM $page WHERE (page_namespace=$ns AND page_title IN(";
+ } elseif ( $current != $ns ) {
+ $current = $ns;
+ $query .= ")) OR (page_namespace=$ns AND page_title IN(";
+ } else {
+ $query .= ', ';
+ }
+
+ $query .= $dbr->addQuotes( $this->mLinkHolders['dbkeys'][$key] );
+ }
+ }
+ if ( $query ) {
+ $query .= '))';
+ if ( $options & RLH_FOR_UPDATE ) {
+ $query .= ' FOR UPDATE';
+ }
+
+ $res = $dbr->query( $query, $fname );
+
+ # Fetch data and form into an associative array
+ # non-existent = broken
+ # 1 = known
+ # 2 = stub
+ while ( $s = $dbr->fetchObject($res) ) {
+ $title = Title::makeTitle( $s->page_namespace, $s->page_title );
+ $pdbk = $title->getPrefixedDBkey();
+ $linkCache->addGoodLinkObj( $s->page_id, $title );
+ $this->mOutput->addLink( $title, $s->page_id );
+
+ if ( $threshold > 0 ) {
+ $size = $s->page_len;
+ if ( $s->page_is_redirect || $s->page_namespace != 0 || $size >= $threshold ) {
+ $colours[$pdbk] = 1;
+ } else {
+ $colours[$pdbk] = 2;
+ }
+ } else {
+ $colours[$pdbk] = 1;
+ }
+ }
+ }
+ wfProfileOut( $fname.'-check' );
+
+ # Do a second query for different language variants of links and categories
+ if($wgContLang->hasVariants()){
+ $linkBatch = new LinkBatch();
+ $variantMap = array(); // maps $pdbkey_Variant => $keys (of link holders)
+ $categoryMap = array(); // maps $category_variant => $category (dbkeys)
+ $varCategories = array(); // category replacements oldDBkey => newDBkey
+
+ $categories = $this->mOutput->getCategoryLinks();
+
+ // Add variants of links to link batch
+ foreach ( $this->mLinkHolders['namespaces'] as $key => $ns ) {
+ $title = $this->mLinkHolders['titles'][$key];
+ if ( is_null( $title ) )
+ continue;
+
+ $pdbk = $title->getPrefixedDBkey();
+ $titleText = $title->getText();
+
+ // generate all variants of the link title text
+ $allTextVariants = $wgContLang->convertLinkToAllVariants($titleText);
+
+ // if link was not found (in first query), add all variants to query
+ if ( !isset($colours[$pdbk]) ){
+ foreach($allTextVariants as $textVariant){
+ if($textVariant != $titleText){
+ $variantTitle = Title::makeTitle( $ns, $textVariant );
+ if(is_null($variantTitle)) continue;
+ $linkBatch->addObj( $variantTitle );
+ $variantMap[$variantTitle->getPrefixedDBkey()][] = $key;
+ }
+ }
+ }
+ }
+
+ // process categories, check if a category exists in some variant
+ foreach( $categories as $category){
+ $variants = $wgContLang->convertLinkToAllVariants($category);
+ foreach($variants as $variant){
+ if($variant != $category){
+ $variantTitle = Title::newFromDBkey( Title::makeName(NS_CATEGORY,$variant) );
+ if(is_null($variantTitle)) continue;
+ $linkBatch->addObj( $variantTitle );
+ $categoryMap[$variant] = $category;
+ }
+ }
+ }
+
+
+ if(!$linkBatch->isEmpty()){
+ // construct query
+ $titleClause = $linkBatch->constructSet('page', $dbr);
+
+ $variantQuery = "SELECT page_id, page_namespace, page_title";
+ if ( $threshold > 0 ) {
+ $variantQuery .= ', page_len, page_is_redirect';
+ }
+
+ $variantQuery .= " FROM $page WHERE $titleClause";
+ if ( $options & RLH_FOR_UPDATE ) {
+ $variantQuery .= ' FOR UPDATE';
+ }
+
+ $varRes = $dbr->query( $variantQuery, $fname );
+
+ // for each found variants, figure out link holders and replace
+ while ( $s = $dbr->fetchObject($varRes) ) {
+
+ $variantTitle = Title::makeTitle( $s->page_namespace, $s->page_title );
+ $varPdbk = $variantTitle->getPrefixedDBkey();
+ $vardbk = $variantTitle->getDBkey();
+
+ $holderKeys = array();
+ if(isset($variantMap[$varPdbk])){
+ $holderKeys = $variantMap[$varPdbk];
+ $linkCache->addGoodLinkObj( $s->page_id, $variantTitle );
+ $this->mOutput->addLink( $variantTitle, $s->page_id );
+ }
+
+ // loop over link holders
+ foreach($holderKeys as $key){
+ $title = $this->mLinkHolders['titles'][$key];
+ if ( is_null( $title ) ) continue;
+
+ $pdbk = $title->getPrefixedDBkey();
+
+ if(!isset($colours[$pdbk])){
+ // found link in some of the variants, replace the link holder data
+ $this->mLinkHolders['titles'][$key] = $variantTitle;
+ $this->mLinkHolders['dbkeys'][$key] = $variantTitle->getDBkey();
+
+ // set pdbk and colour
+ $pdbks[$key] = $varPdbk;
+ if ( $threshold > 0 ) {
+ $size = $s->page_len;
+ if ( $s->page_is_redirect || $s->page_namespace != 0 || $size >= $threshold ) {
+ $colours[$varPdbk] = 1;
+ } else {
+ $colours[$varPdbk] = 2;
+ }
+ }
+ else {
+ $colours[$varPdbk] = 1;
+ }
+ }
+ }
+
+ // check if the object is a variant of a category
+ if(isset($categoryMap[$vardbk])){
+ $oldkey = $categoryMap[$vardbk];
+ if($oldkey != $vardbk)
+ $varCategories[$oldkey]=$vardbk;
+ }
+ }
+
+ // rebuild the categories in original order (if there are replacements)
+ if(count($varCategories)>0){
+ $newCats = array();
+ $originalCats = $this->mOutput->getCategories();
+ foreach($originalCats as $cat => $sortkey){
+ // make the replacement
+ if( array_key_exists($cat,$varCategories) )
+ $newCats[$varCategories[$cat]] = $sortkey;
+ else $newCats[$cat] = $sortkey;
+ }
+ $this->mOutput->setCategoryLinks($newCats);
+ }
+ }
+ }
+
+ # Construct search and replace arrays
+ wfProfileIn( $fname.'-construct' );
+ $replacePairs = array();
+ foreach ( $this->mLinkHolders['namespaces'] as $key => $ns ) {
+ $pdbk = $pdbks[$key];
+ $searchkey = "<!--LINK $key-->";
+ $title = $this->mLinkHolders['titles'][$key];
+ if ( empty( $colours[$pdbk] ) ) {
+ $linkCache->addBadLinkObj( $title );
+ $colours[$pdbk] = 0;
+ $this->mOutput->addLink( $title, 0 );
+ $replacePairs[$searchkey] = $sk->makeBrokenLinkObj( $title,
+ $this->mLinkHolders['texts'][$key],
+ $this->mLinkHolders['queries'][$key] );
+ } elseif ( $colours[$pdbk] == 1 ) {
+ $replacePairs[$searchkey] = $sk->makeKnownLinkObj( $title,
+ $this->mLinkHolders['texts'][$key],
+ $this->mLinkHolders['queries'][$key] );
+ } elseif ( $colours[$pdbk] == 2 ) {
+ $replacePairs[$searchkey] = $sk->makeStubLinkObj( $title,
+ $this->mLinkHolders['texts'][$key],
+ $this->mLinkHolders['queries'][$key] );
+ }
+ }
+ $replacer = new HashtableReplacer( $replacePairs, 1 );
+ wfProfileOut( $fname.'-construct' );
+
+ # Do the thing
+ wfProfileIn( $fname.'-replace' );
+ $text = preg_replace_callback(
+ '/(<!--LINK .*?-->)/',
+ $replacer->cb(),
+ $text);
+
+ wfProfileOut( $fname.'-replace' );
+ }
+
+ # Now process interwiki link holders
+ # This is quite a bit simpler than internal links
+ if ( !empty( $this->mInterwikiLinkHolders['texts'] ) ) {
+ wfProfileIn( $fname.'-interwiki' );
+ # Make interwiki link HTML
+ $replacePairs = array();
+ foreach( $this->mInterwikiLinkHolders['texts'] as $key => $link ) {
+ $title = $this->mInterwikiLinkHolders['titles'][$key];
+ $replacePairs[$key] = $sk->makeLinkObj( $title, $link );
+ }
+ $replacer = new HashtableReplacer( $replacePairs, 1 );
+
+ $text = preg_replace_callback(
+ '/<!--IWLINK (.*?)-->/',
+ $replacer->cb(),
+ $text );
+ wfProfileOut( $fname.'-interwiki' );
+ }
+
+ wfProfileOut( $fname );
+ return $colours;
+ }
+
+ /**
+ * Replace <!--LINK--> link placeholders with plain text of links
+ * (not HTML-formatted).
+ * @param string $text
+ * @return string
+ */
+ function replaceLinkHoldersText( $text ) {
+ $fname = 'Parser::replaceLinkHoldersText';
+ wfProfileIn( $fname );
+
+ $text = preg_replace_callback(
+ '/<!--(LINK|IWLINK) (.*?)-->/',
+ array( &$this, 'replaceLinkHoldersTextCallback' ),
+ $text );
+
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ /**
+ * @param array $matches
+ * @return string
+ * @private
+ */
+ function replaceLinkHoldersTextCallback( $matches ) {
+ $type = $matches[1];
+ $key = $matches[2];
+ if( $type == 'LINK' ) {
+ if( isset( $this->mLinkHolders['texts'][$key] ) ) {
+ return $this->mLinkHolders['texts'][$key];
+ }
+ } elseif( $type == 'IWLINK' ) {
+ if( isset( $this->mInterwikiLinkHolders['texts'][$key] ) ) {
+ return $this->mInterwikiLinkHolders['texts'][$key];
+ }
+ }
+ return $matches[0];
+ }
+
+ /**
+ * Tag hook handler for 'pre'.
+ */
+ function renderPreTag( $text, $attribs ) {
+ // Backwards-compatibility hack
+ $content = StringUtils::delimiterReplace( '<nowiki>', '</nowiki>', '$1', $text, 'i' );
+
+ $attribs = Sanitizer::validateTagAttributes( $attribs, 'pre' );
+ return wfOpenElement( 'pre', $attribs ) .
+ Xml::escapeTagsOnly( $content ) .
+ '</pre>';
+ }
+
+ /**
+ * Renders an image gallery from a text with one line per image.
+ * text labels may be given by using |-style alternative text. E.g.
+ * Image:one.jpg|The number "1"
+ * Image:tree.jpg|A tree
+ * given as text will return the HTML of a gallery with two images,
+ * labeled 'The number "1"' and
+ * 'A tree'.
+ */
+ function renderImageGallery( $text, $params ) {
+ $ig = new ImageGallery();
+ $ig->setShowBytes( false );
+ $ig->setShowFilename( false );
+ $ig->setParsing();
+ $ig->useSkin( $this->mOptions->getSkin() );
+
+ if( isset( $params['caption'] ) ) {
+ $caption = $params['caption'];
+ $caption = htmlspecialchars( $caption );
+ $caption = $this->replaceInternalLinks( $caption );
+ $ig->setCaptionHtml( $caption );
+ }
+
+ $lines = explode( "\n", $text );
+ foreach ( $lines as $line ) {
+ # match lines like these:
+ # Image:someimage.jpg|This is some image
+ $matches = array();
+ preg_match( "/^([^|]+)(\\|(.*))?$/", $line, $matches );
+ # Skip empty lines
+ if ( count( $matches ) == 0 ) {
+ continue;
+ }
+ $tp = Title::newFromText( $matches[1] );
+ $nt =& $tp;
+ if( is_null( $nt ) ) {
+ # Bogus title. Ignore these so we don't bomb out later.
+ continue;
+ }
+ if ( isset( $matches[3] ) ) {
+ $label = $matches[3];
+ } else {
+ $label = '';
+ }
+
+ $pout = $this->parse( $label,
+ $this->mTitle,
+ $this->mOptions,
+ false, // Strip whitespace...?
+ false // Don't clear state!
+ );
+ $html = $pout->getText();
+
+ $ig->add( new Image( $nt ), $html );
+
+ # Only add real images (bug #5586)
+ if ( $nt->getNamespace() == NS_IMAGE ) {
+ $this->mOutput->addImage( $nt->getDBkey() );
+ }
+ }
+ return $ig->toHTML();
+ }
+
+ /**
+ * Parse image options text and use it to make an image
+ */
+ function makeImage( $nt, $options ) {
+ global $wgUseImageResize, $wgDjvuRenderer;
+
+ $align = '';
+
+ # Check if the options text is of the form "options|alt text"
+ # Options are:
+ # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
+ # * left no resizing, just left align. label is used for alt= only
+ # * right same, but right aligned
+ # * none same, but not aligned
+ # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
+ # * center center the image
+ # * framed Keep original image size, no magnify-button.
+
+ $part = explode( '|', $options);
+
+ $mwThumb =& MagicWord::get( 'img_thumbnail' );
+ $mwManualThumb =& MagicWord::get( 'img_manualthumb' );
+ $mwLeft =& MagicWord::get( 'img_left' );
+ $mwRight =& MagicWord::get( 'img_right' );
+ $mwNone =& MagicWord::get( 'img_none' );
+ $mwWidth =& MagicWord::get( 'img_width' );
+ $mwCenter =& MagicWord::get( 'img_center' );
+ $mwFramed =& MagicWord::get( 'img_framed' );
+ $mwPage =& MagicWord::get( 'img_page' );
+ $caption = '';
+
+ $width = $height = $framed = $thumb = false;
+ $page = null;
+ $manual_thumb = '' ;
+
+ foreach( $part as $val ) {
+ if ( $wgUseImageResize && ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
+ $thumb=true;
+ } elseif ( ! is_null( $match = $mwManualThumb->matchVariableStartToEnd($val) ) ) {
+ # use manually specified thumbnail
+ $thumb=true;
+ $manual_thumb = $match;
+ } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
+ # remember to set an alignment, don't render immediately
+ $align = 'right';
+ } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
+ # remember to set an alignment, don't render immediately
+ $align = 'left';
+ } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
+ # remember to set an alignment, don't render immediately
+ $align = 'center';
+ } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
+ # remember to set an alignment, don't render immediately
+ $align = 'none';
+ } elseif ( isset( $wgDjvuRenderer ) && $wgDjvuRenderer
+ && ! is_null( $match = $mwPage->matchVariableStartToEnd($val) ) ) {
+ # Select a page in a multipage document
+ $page = $match;
+ } elseif ( $wgUseImageResize && !$width && ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
+ wfDebug( "img_width match: $match\n" );
+ # $match is the image width in pixels
+ $m = array();
+ if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
+ $width = intval( $m[1] );
+ $height = intval( $m[2] );
+ } else {
+ $width = intval($match);
+ }
+ } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
+ $framed=true;
+ } else {
+ $caption = $val;
+ }
+ }
+ # Strip bad stuff out of the alt text
+ $alt = $this->replaceLinkHoldersText( $caption );
+
+ # make sure there are no placeholders in thumbnail attributes
+ # that are later expanded to html- so expand them now and
+ # remove the tags
+ $alt = $this->mStripState->unstripBoth( $alt );
+ $alt = Sanitizer::stripAllTags( $alt );
+
+ # Linker does the rest
+ $sk =& $this->mOptions->getSkin();
+ return $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page );
+ }
+
+ /**
+ * Set a flag in the output object indicating that the content is dynamic and
+ * shouldn't be cached.
+ */
+ function disableCache() {
+ wfDebug( "Parser output marked as uncacheable.\n" );
+ $this->mOutput->mCacheTime = -1;
+ }
+
+ /**#@+
+ * Callback from the Sanitizer for expanding items found in HTML attribute
+ * values, so they can be safely tested and escaped.
+ * @param string $text
+ * @param array $args
+ * @return string
+ * @private
+ */
+ function attributeStripCallback( &$text, $args ) {
+ $text = $this->replaceVariables( $text, $args );
+ $text = $this->mStripState->unstripBoth( $text );
+ return $text;
+ }
+
+ /**#@-*/
+
+ /**#@+
+ * Accessor/mutator
+ */
+ function Title( $x = NULL ) { return wfSetVar( $this->mTitle, $x ); }
+ function Options( $x = NULL ) { return wfSetVar( $this->mOptions, $x ); }
+ function OutputType( $x = NULL ) { return wfSetVar( $this->mOutputType, $x ); }
+ /**#@-*/
+
+ /**#@+
+ * Accessor
+ */
+ function getTags() { return array_keys( $this->mTagHooks ); }
+ /**#@-*/
+
+
+ /**
+ * Break wikitext input into sections, and either pull or replace
+ * some particular section's text.
+ *
+ * External callers should use the getSection and replaceSection methods.
+ *
+ * @param $text Page wikitext
+ * @param $section Numbered section. 0 pulls the text before the first
+ * heading; other numbers will pull the given section
+ * along with its lower-level subsections.
+ * @param $mode One of "get" or "replace"
+ * @param $newtext Replacement text for section data.
+ * @return string for "get", the extracted section text.
+ * for "replace", the whole page with the section replaced.
+ */
+ private function extractSections( $text, $section, $mode, $newtext='' ) {
+ # strip NOWIKI etc. to avoid confusion (true-parameter causes HTML
+ # comments to be stripped as well)
+ $stripState = new StripState;
+
+ $oldOutputType = $this->mOutputType;
+ $oldOptions = $this->mOptions;
+ $this->mOptions = new ParserOptions();
+ $this->setOutputType( OT_WIKI );
+
+ $striptext = $this->strip( $text, $stripState, true );
+
+ $this->setOutputType( $oldOutputType );
+ $this->mOptions = $oldOptions;
+
+ # now that we can be sure that no pseudo-sections are in the source,
+ # split it up by section
+ $uniq = preg_quote( $this->uniqPrefix(), '/' );
+ $comment = "(?:$uniq-!--.*?QINU)";
+ $secs = preg_split(
+ /*
+ "/
+ ^(
+ (?:$comment|<\/?noinclude>)* # Initial comments will be stripped
+ (?:
+ (=+) # Should this be limited to 6?
+ .+? # Section title...
+ \\2 # Ending = count must match start
+ |
+ ^
+ <h([1-6])\b.*?>
+ .*?
+ <\/h\\3\s*>
+ )
+ (?:$comment|<\/?noinclude>|\s+)* # Trailing whitespace ok
+ )$
+ /mix",
+ */
+ "/
+ (
+ ^
+ (?:$comment|<\/?noinclude>)* # Initial comments will be stripped
+ (=+) # Should this be limited to 6?
+ .+? # Section title...
+ \\2 # Ending = count must match start
+ (?:$comment|<\/?noinclude>|[ \\t]+)* # Trailing whitespace ok
+ $
+ |
+ <h([1-6])\b.*?>
+ .*?
+ <\/h\\3\s*>
+ )
+ /mix",
+ $striptext, -1,
+ PREG_SPLIT_DELIM_CAPTURE);
+
+ if( $mode == "get" ) {
+ if( $section == 0 ) {
+ // "Section 0" returns the content before any other section.
+ $rv = $secs[0];
+ } else {
+ $rv = "";
+ }
+ } elseif( $mode == "replace" ) {
+ if( $section == 0 ) {
+ $rv = $newtext . "\n\n";
+ $remainder = true;
+ } else {
+ $rv = $secs[0];
+ $remainder = false;
+ }
+ }
+ $count = 0;
+ $sectionLevel = 0;
+ for( $index = 1; $index < count( $secs ); ) {
+ $headerLine = $secs[$index++];
+ if( $secs[$index] ) {
+ // A wiki header
+ $headerLevel = strlen( $secs[$index++] );
+ } else {
+ // An HTML header
+ $index++;
+ $headerLevel = intval( $secs[$index++] );
+ }
+ $content = $secs[$index++];
+
+ $count++;
+ if( $mode == "get" ) {
+ if( $count == $section ) {
+ $rv = $headerLine . $content;
+ $sectionLevel = $headerLevel;
+ } elseif( $count > $section ) {
+ if( $sectionLevel && $headerLevel > $sectionLevel ) {
+ $rv .= $headerLine . $content;
+ } else {
+ // Broke out to a higher-level section
+ break;
+ }
+ }
+ } elseif( $mode == "replace" ) {
+ if( $count < $section ) {
+ $rv .= $headerLine . $content;
+ } elseif( $count == $section ) {
+ $rv .= $newtext . "\n\n";
+ $sectionLevel = $headerLevel;
+ } elseif( $count > $section ) {
+ if( $headerLevel <= $sectionLevel ) {
+ // Passed the section's sub-parts.
+ $remainder = true;
+ }
+ if( $remainder ) {
+ $rv .= $headerLine . $content;
+ }
+ }
+ }
+ }
+ # reinsert stripped tags
+ $rv = trim( $stripState->unstripBoth( $rv ) );
+ return $rv;
+ }
+
+ /**
+ * This function returns the text of a section, specified by a number ($section).
+ * A section is text under a heading like == Heading == or \<h1\>Heading\</h1\>, or
+ * the first section before any such heading (section 0).
+ *
+ * If a section contains subsections, these are also returned.
+ *
+ * @param $text String: text to look in
+ * @param $section Integer: section number
+ * @return string text of the requested section
+ */
+ function getSection( $text, $section ) {
+ return $this->extractSections( $text, $section, "get" );
+ }
+
+ function replaceSection( $oldtext, $section, $text ) {
+ return $this->extractSections( $oldtext, $section, "replace", $text );
+ }
+
+ /**
+ * Get the timestamp associated with the current revision, adjusted for
+ * the default server-local timestamp
+ */
+ function getRevisionTimestamp() {
+ if ( is_null( $this->mRevisionTimestamp ) ) {
+ wfProfileIn( __METHOD__ );
+ global $wgContLang;
+ $dbr =& wfGetDB( DB_SLAVE );
+ $timestamp = $dbr->selectField( 'revision', 'rev_timestamp',
+ array( 'rev_id' => $this->mRevisionId ), __METHOD__ );
+
+ // Normalize timestamp to internal MW format for timezone processing.
+ // This has the added side-effect of replacing a null value with
+ // the current time, which gives us more sensible behavior for
+ // previews.
+ $timestamp = wfTimestamp( TS_MW, $timestamp );
+
+ // The cryptic '' timezone parameter tells to use the site-default
+ // timezone offset instead of the user settings.
+ //
+ // Since this value will be saved into the parser cache, served
+ // to other users, and potentially even used inside links and such,
+ // it needs to be consistent for all visitors.
+ $this->mRevisionTimestamp = $wgContLang->userAdjust( $timestamp, '' );
+
+ wfProfileOut( __METHOD__ );
+ }
+ return $this->mRevisionTimestamp;
+ }
+
+ /**
+ * Mutator for $mDefaultSort
+ *
+ * @param $sort New value
+ */
+ public function setDefaultSort( $sort ) {
+ $this->mDefaultSort = $sort;
+ }
+
+ /**
+ * Accessor for $mDefaultSort
+ * Will use the title/prefixed title if none is set
+ *
+ * @return string
+ */
+ public function getDefaultSort() {
+ if( $this->mDefaultSort !== false ) {
+ return $this->mDefaultSort;
+ } else {
+ return $this->mTitle->getNamespace() == NS_CATEGORY
+ ? $this->mTitle->getText()
+ : $this->mTitle->getPrefixedText();
+ }
+ }
+
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class ParserOutput
+{
+ var $mText, # The output text
+ $mLanguageLinks, # List of the full text of language links, in the order they appear
+ $mCategories, # Map of category names to sort keys
+ $mContainsOldMagic, # Boolean variable indicating if the input contained variables like {{CURRENTDAY}}
+ $mCacheTime, # Time when this object was generated, or -1 for uncacheable. Used in ParserCache.
+ $mVersion, # Compatibility check
+ $mTitleText, # title text of the chosen language variant
+ $mLinks, # 2-D map of NS/DBK to ID for the links in the document. ID=zero for broken.
+ $mTemplates, # 2-D map of NS/DBK to ID for the template references. ID=zero for broken.
+ $mImages, # DB keys of the images used, in the array key only
+ $mExternalLinks, # External link URLs, in the key only
+ $mHTMLtitle, # Display HTML title
+ $mSubtitle, # Additional subtitle
+ $mNewSection, # Show a new section link?
+ $mNoGallery; # No gallery on category page? (__NOGALLERY__)
+
+ function ParserOutput( $text = '', $languageLinks = array(), $categoryLinks = array(),
+ $containsOldMagic = false, $titletext = '' )
+ {
+ $this->mText = $text;
+ $this->mLanguageLinks = $languageLinks;
+ $this->mCategories = $categoryLinks;
+ $this->mContainsOldMagic = $containsOldMagic;
+ $this->mCacheTime = '';
+ $this->mVersion = MW_PARSER_VERSION;
+ $this->mTitleText = $titletext;
+ $this->mLinks = array();
+ $this->mTemplates = array();
+ $this->mImages = array();
+ $this->mExternalLinks = array();
+ $this->mHTMLtitle = "" ;
+ $this->mSubtitle = "" ;
+ $this->mNewSection = false;
+ $this->mNoGallery = false;
+ }
+
+ function getText() { return $this->mText; }
+ function &getLanguageLinks() { return $this->mLanguageLinks; }
+ function getCategoryLinks() { return array_keys( $this->mCategories ); }
+ function &getCategories() { return $this->mCategories; }
+ function getCacheTime() { return $this->mCacheTime; }
+ function getTitleText() { return $this->mTitleText; }
+ function &getLinks() { return $this->mLinks; }
+ function &getTemplates() { return $this->mTemplates; }
+ function &getImages() { return $this->mImages; }
+ function &getExternalLinks() { return $this->mExternalLinks; }
+ function getNoGallery() { return $this->mNoGallery; }
+ function getSubtitle() { return $this->mSubtitle; }
+
+ function containsOldMagic() { return $this->mContainsOldMagic; }
+ function setText( $text ) { return wfSetVar( $this->mText, $text ); }
+ function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); }
+ function setCategoryLinks( $cl ) { return wfSetVar( $this->mCategories, $cl ); }
+ function setContainsOldMagic( $com ) { return wfSetVar( $this->mContainsOldMagic, $com ); }
+ function setCacheTime( $t ) { return wfSetVar( $this->mCacheTime, $t ); }
+ function setTitleText( $t ) { return wfSetVar($this->mTitleText, $t); }
+ function setSubtitle( $st ) { return wfSetVar( $this->mSubtitle, $st ); }
+
+ function addCategory( $c, $sort ) { $this->mCategories[$c] = $sort; }
+ function addImage( $name ) { $this->mImages[$name] = 1; }
+ function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; }
+ function addExternalLink( $url ) { $this->mExternalLinks[$url] = 1; }
+
+ function setNewSection( $value ) {
+ $this->mNewSection = (bool)$value;
+ }
+ function getNewSection() {
+ return (bool)$this->mNewSection;
+ }
+
+ function addLink( $title, $id = null ) {
+ $ns = $title->getNamespace();
+ $dbk = $title->getDBkey();
+ if ( !isset( $this->mLinks[$ns] ) ) {
+ $this->mLinks[$ns] = array();
+ }
+ if ( is_null( $id ) ) {
+ $id = $title->getArticleID();
+ }
+ $this->mLinks[$ns][$dbk] = $id;
+ }
+
+ function addTemplate( $title, $id ) {
+ $ns = $title->getNamespace();
+ $dbk = $title->getDBkey();
+ if ( !isset( $this->mTemplates[$ns] ) ) {
+ $this->mTemplates[$ns] = array();
+ }
+ $this->mTemplates[$ns][$dbk] = $id;
+ }
+
+ /**
+ * Return true if this cached output object predates the global or
+ * per-article cache invalidation timestamps, or if it comes from
+ * an incompatible older version.
+ *
+ * @param string $touched the affected article's last touched timestamp
+ * @return bool
+ * @public
+ */
+ function expired( $touched ) {
+ global $wgCacheEpoch;
+ return $this->getCacheTime() == -1 || // parser says it's uncacheable
+ $this->getCacheTime() < $touched ||
+ $this->getCacheTime() <= $wgCacheEpoch ||
+ !isset( $this->mVersion ) ||
+ version_compare( $this->mVersion, MW_PARSER_VERSION, "lt" );
+ }
+}
+
+/**
+ * Set options of the Parser
+ * @todo document
+ * @package MediaWiki
+ */
+class ParserOptions
+{
+ # All variables are supposed to be private in theory, although in practise this is not the case.
+ var $mUseTeX; # Use texvc to expand <math> tags
+ var $mUseDynamicDates; # Use DateFormatter to format dates
+ var $mInterwikiMagic; # Interlanguage links are removed and returned in an array
+ var $mAllowExternalImages; # Allow external images inline
+ var $mAllowExternalImagesFrom; # If not, any exception?
+ var $mSkin; # Reference to the preferred skin
+ var $mDateFormat; # Date format index
+ var $mEditSection; # Create "edit section" links
+ var $mNumberHeadings; # Automatically number headings
+ var $mAllowSpecialInclusion; # Allow inclusion of special pages
+ var $mTidy; # Ask for tidy cleanup
+ var $mInterfaceMessage; # Which lang to call for PLURAL and GRAMMAR
+ var $mMaxIncludeSize; # Maximum size of template expansions, in bytes
+ var $mRemoveComments; # Remove HTML comments. ONLY APPLIES TO PREPROCESS OPERATIONS
+
+ var $mUser; # Stored user object, just used to initialise the skin
+
+ function getUseTeX() { return $this->mUseTeX; }
+ function getUseDynamicDates() { return $this->mUseDynamicDates; }
+ function getInterwikiMagic() { return $this->mInterwikiMagic; }
+ function getAllowExternalImages() { return $this->mAllowExternalImages; }
+ function getAllowExternalImagesFrom() { return $this->mAllowExternalImagesFrom; }
+ function getEditSection() { return $this->mEditSection; }
+ function getNumberHeadings() { return $this->mNumberHeadings; }
+ function getAllowSpecialInclusion() { return $this->mAllowSpecialInclusion; }
+ function getTidy() { return $this->mTidy; }
+ function getInterfaceMessage() { return $this->mInterfaceMessage; }
+ function getMaxIncludeSize() { return $this->mMaxIncludeSize; }
+ function getRemoveComments() { return $this->mRemoveComments; }
+
+ function &getSkin() {
+ if ( !isset( $this->mSkin ) ) {
+ $this->mSkin = $this->mUser->getSkin();
+ }
+ return $this->mSkin;
+ }
+
+ function getDateFormat() {
+ if ( !isset( $this->mDateFormat ) ) {
+ $this->mDateFormat = $this->mUser->getDatePreference();
+ }
+ return $this->mDateFormat;
+ }
+
+ function setUseTeX( $x ) { return wfSetVar( $this->mUseTeX, $x ); }
+ function setUseDynamicDates( $x ) { return wfSetVar( $this->mUseDynamicDates, $x ); }
+ function setInterwikiMagic( $x ) { return wfSetVar( $this->mInterwikiMagic, $x ); }
+ function setAllowExternalImages( $x ) { return wfSetVar( $this->mAllowExternalImages, $x ); }
+ function setAllowExternalImagesFrom( $x ) { return wfSetVar( $this->mAllowExternalImagesFrom, $x ); }
+ function setDateFormat( $x ) { return wfSetVar( $this->mDateFormat, $x ); }
+ function setEditSection( $x ) { return wfSetVar( $this->mEditSection, $x ); }
+ function setNumberHeadings( $x ) { return wfSetVar( $this->mNumberHeadings, $x ); }
+ function setAllowSpecialInclusion( $x ) { return wfSetVar( $this->mAllowSpecialInclusion, $x ); }
+ function setTidy( $x ) { return wfSetVar( $this->mTidy, $x); }
+ function setSkin( $x ) { $this->mSkin = $x; }
+ function setInterfaceMessage( $x ) { return wfSetVar( $this->mInterfaceMessage, $x); }
+ function setMaxIncludeSize( $x ) { return wfSetVar( $this->mMaxIncludeSize, $x ); }
+ function setRemoveComments( $x ) { return wfSetVar( $this->mRemoveComments, $x ); }
+
+ function ParserOptions( $user = null ) {
+ $this->initialiseFromUser( $user );
+ }
+
+ /**
+ * Get parser options
+ * @static
+ */
+ static function newFromUser( $user ) {
+ return new ParserOptions( $user );
+ }
+
+ /** Get user options */
+ function initialiseFromUser( $userInput ) {
+ global $wgUseTeX, $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages;
+ global $wgAllowExternalImagesFrom, $wgAllowSpecialInclusion, $wgMaxArticleSize;
+ $fname = 'ParserOptions::initialiseFromUser';
+ wfProfileIn( $fname );
+ if ( !$userInput ) {
+ global $wgUser;
+ if ( isset( $wgUser ) ) {
+ $user = $wgUser;
+ } else {
+ $user = new User;
+ }
+ } else {
+ $user =& $userInput;
+ }
+
+ $this->mUser = $user;
+
+ $this->mUseTeX = $wgUseTeX;
+ $this->mUseDynamicDates = $wgUseDynamicDates;
+ $this->mInterwikiMagic = $wgInterwikiMagic;
+ $this->mAllowExternalImages = $wgAllowExternalImages;
+ $this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
+ $this->mSkin = null; # Deferred
+ $this->mDateFormat = null; # Deferred
+ $this->mEditSection = true;
+ $this->mNumberHeadings = $user->getOption( 'numberheadings' );
+ $this->mAllowSpecialInclusion = $wgAllowSpecialInclusion;
+ $this->mTidy = false;
+ $this->mInterfaceMessage = false;
+ $this->mMaxIncludeSize = $wgMaxArticleSize * 1024;
+ $this->mRemoveComments = true;
+ wfProfileOut( $fname );
+ }
+}
+
+class OnlyIncludeReplacer {
+ var $output = '';
+
+ function replace( $matches ) {
+ if ( substr( $matches[1], -1 ) == "\n" ) {
+ $this->output .= substr( $matches[1], 0, -1 );
+ } else {
+ $this->output .= $matches[1];
+ }
+ }
+}
+
+class StripState {
+ var $general, $nowiki;
+
+ function __construct() {
+ $this->general = new ReplacementArray;
+ $this->nowiki = new ReplacementArray;
+ }
+
+ function unstripGeneral( $text ) {
+ wfProfileIn( __METHOD__ );
+ $text = $this->general->replace( $text );
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ function unstripNoWiki( $text ) {
+ wfProfileIn( __METHOD__ );
+ $text = $this->nowiki->replace( $text );
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ function unstripBoth( $text ) {
+ wfProfileIn( __METHOD__ );
+ $text = $this->general->replace( $text );
+ $text = $this->nowiki->replace( $text );
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+}
+
+?>
diff --git a/includes/ParserCache.php b/includes/ParserCache.php
new file mode 100644
index 000000000000..37a42b7f5cbf
--- /dev/null
+++ b/includes/ParserCache.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage Cache
+ */
+
+/**
+ *
+ * @package MediaWiki
+ */
+class ParserCache {
+ /**
+ * Get an instance of this object
+ */
+ public static function &singleton() {
+ static $instance;
+ if ( !isset( $instance ) ) {
+ global $parserMemc;
+ $instance = new ParserCache( $parserMemc );
+ }
+ return $instance;
+ }
+
+ /**
+ * Setup a cache pathway with a given back-end storage mechanism.
+ * May be a memcached client or a BagOStuff derivative.
+ *
+ * @param object $memCached
+ */
+ function ParserCache( &$memCached ) {
+ $this->mMemc =& $memCached;
+ }
+
+ function getKey( &$article, &$user ) {
+ global $action;
+ $hash = $user->getPageRenderingHash();
+ if( !$article->mTitle->userCanEdit() ) {
+ // section edit links are suppressed even if the user has them on
+ $edit = '!edit=0';
+ } else {
+ $edit = '';
+ }
+ $pageid = intval( $article->getID() );
+ $renderkey = (int)($action == 'render');
+ $key = wfMemcKey( 'pcache', 'idhash', "$pageid-$renderkey!$hash$edit" );
+ return $key;
+ }
+
+ function getETag( &$article, &$user ) {
+ return 'W/"' . $this->getKey($article, $user) . "--" . $article->mTouched. '"';
+ }
+
+ function get( &$article, &$user ) {
+ global $wgCacheEpoch;
+ $fname = 'ParserCache::get';
+ wfProfileIn( $fname );
+
+ $key = $this->getKey( $article, $user );
+
+ wfDebug( "Trying parser cache $key\n" );
+ $value = $this->mMemc->get( $key );
+ if ( is_object( $value ) ) {
+ wfDebug( "Found.\n" );
+ # Delete if article has changed since the cache was made
+ $canCache = $article->checkTouched();
+ $cacheTime = $value->getCacheTime();
+ $touched = $article->mTouched;
+ if ( !$canCache || $value->expired( $touched ) ) {
+ if ( !$canCache ) {
+ wfIncrStats( "pcache_miss_invalid" );
+ wfDebug( "Invalid cached redirect, touched $touched, epoch $wgCacheEpoch, cached $cacheTime\n" );
+ } else {
+ wfIncrStats( "pcache_miss_expired" );
+ wfDebug( "Key expired, touched $touched, epoch $wgCacheEpoch, cached $cacheTime\n" );
+ }
+ $this->mMemc->delete( $key );
+ $value = false;
+ } else {
+ if ( isset( $value->mTimestamp ) ) {
+ $article->mTimestamp = $value->mTimestamp;
+ }
+ wfIncrStats( "pcache_hit" );
+ }
+ } else {
+ wfDebug( "Parser cache miss.\n" );
+ wfIncrStats( "pcache_miss_absent" );
+ $value = false;
+ }
+
+ wfProfileOut( $fname );
+ return $value;
+ }
+
+ function save( $parserOutput, &$article, &$user ){
+ global $wgParserCacheExpireTime;
+ $key = $this->getKey( $article, $user );
+
+ if( $parserOutput->getCacheTime() != -1 ) {
+
+ $now = wfTimestampNow();
+ $parserOutput->setCacheTime( $now );
+
+ // Save the timestamp so that we don't have to load the revision row on view
+ $parserOutput->mTimestamp = $article->getTimestamp();
+
+ $parserOutput->mText .= "\n<!-- Saved in parser cache with key $key and timestamp $now -->\n";
+ wfDebug( "Saved in parser cache with key $key and timestamp $now\n" );
+
+ if( $parserOutput->containsOldMagic() ){
+ $expire = 3600; # 1 hour
+ } else {
+ $expire = $wgParserCacheExpireTime;
+ }
+ $this->mMemc->set( $key, $parserOutput, $expire );
+
+ } else {
+ wfDebug( "Parser output was marked as uncacheable and has not been saved.\n" );
+ }
+
+ }
+
+}
+
+?>
diff --git a/includes/Profiler.php b/includes/Profiler.php
new file mode 100644
index 000000000000..30cda63f6c6b
--- /dev/null
+++ b/includes/Profiler.php
@@ -0,0 +1,367 @@
+<?php
+/**
+ * This file is only included if profiling is enabled
+ * @package MediaWiki
+ */
+
+$wgProfiling = true;
+
+/**
+ * @param $functioname name of the function we will profile
+ */
+function wfProfileIn($functionname) {
+ global $wgProfiler;
+ $wgProfiler->profileIn($functionname);
+}
+
+/**
+ * @param $functioname name of the function we have profiled
+ */
+function wfProfileOut($functionname = 'missing') {
+ global $wgProfiler;
+ $wgProfiler->profileOut($functionname);
+}
+
+function wfGetProfilingOutput($start, $elapsed) {
+ global $wgProfiler;
+ return $wgProfiler->getOutput($start, $elapsed);
+}
+
+function wfProfileClose() {
+ global $wgProfiler;
+ $wgProfiler->close();
+}
+
+if (!function_exists('memory_get_usage')) {
+ # Old PHP or --enable-memory-limit not compiled in
+ function memory_get_usage() {
+ return 0;
+ }
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class Profiler {
+ var $mStack = array (), $mWorkStack = array (), $mCollated = array ();
+ var $mCalls = array (), $mTotals = array ();
+
+ function Profiler()
+ {
+ // Push an entry for the pre-profile setup time onto the stack
+ global $wgRequestTime;
+ if ( !empty( $wgRequestTime ) ) {
+ $this->mWorkStack[] = array( '-total', 0, $wgRequestTime, 0 );
+ $this->mStack[] = array( '-setup', 1, $wgRequestTime, 0, microtime(true), 0 );
+ } else {
+ $this->profileIn( '-total' );
+ }
+
+ }
+
+ function profileIn($functionname) {
+ global $wgDebugFunctionEntry;
+ if ($wgDebugFunctionEntry && function_exists('wfDebug')) {
+ wfDebug(str_repeat(' ', count($this->mWorkStack)).'Entering '.$functionname."\n");
+ }
+ $this->mWorkStack[] = array($functionname, count( $this->mWorkStack ), $this->getTime(), memory_get_usage());
+ }
+
+ function profileOut($functionname) {
+ $memory = memory_get_usage();
+ $time = $this->getTime();
+
+ global $wgDebugFunctionEntry;
+
+ if ($wgDebugFunctionEntry && function_exists('wfDebug')) {
+ wfDebug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n");
+ }
+
+ $bit = array_pop($this->mWorkStack);
+
+ if (!$bit) {
+ wfDebug("Profiling error, !\$bit: $functionname\n");
+ } else {
+ //if ($wgDebugProfiling) {
+ if ($functionname == 'close') {
+ $message = "Profile section ended by close(): {$bit[0]}";
+ wfDebug( "$message\n" );
+ $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 );
+ }
+ elseif ($bit[0] != $functionname) {
+ $message = "Profiling error: in({$bit[0]}), out($functionname)";
+ wfDebug( "$message\n" );
+ $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 );
+ }
+ //}
+ $bit[] = $time;
+ $bit[] = $memory;
+ $this->mStack[] = $bit;
+ }
+ }
+
+ function close() {
+ while (count($this->mWorkStack)) {
+ $this->profileOut('close');
+ }
+ }
+
+ function getOutput() {
+ global $wgDebugFunctionEntry;
+ $wgDebugFunctionEntry = false;
+
+ if (!count($this->mStack) && !count($this->mCollated)) {
+ return "No profiling output\n";
+ }
+ $this->close();
+
+ global $wgProfileCallTree;
+ if ($wgProfileCallTree) {
+ return $this->getCallTree();
+ } else {
+ return $this->getFunctionReport();
+ }
+ }
+
+ function getCallTree($start = 0) {
+ return implode('', array_map(array (& $this, 'getCallTreeLine'), $this->remapCallTree($this->mStack)));
+ }
+
+ function remapCallTree($stack) {
+ if (count($stack) < 2) {
+ return $stack;
+ }
+ $outputs = array ();
+ for ($max = count($stack) - 1; $max > 0;) {
+ /* Find all items under this entry */
+ $level = $stack[$max][1];
+ $working = array ();
+ for ($i = $max -1; $i >= 0; $i --) {
+ if ($stack[$i][1] > $level) {
+ $working[] = $stack[$i];
+ } else {
+ break;
+ }
+ }
+ $working = $this->remapCallTree(array_reverse($working));
+ $output = array ();
+ foreach ($working as $item) {
+ array_push($output, $item);
+ }
+ array_unshift($output, $stack[$max]);
+ $max = $i;
+
+ array_unshift($outputs, $output);
+ }
+ $final = array ();
+ foreach ($outputs as $output) {
+ foreach ($output as $item) {
+ $final[] = $item;
+ }
+ }
+ return $final;
+ }
+
+ function getCallTreeLine($entry) {
+ list ($fname, $level, $start, /* $x */, $end) = $entry;
+ $delta = $end - $start;
+ $space = str_repeat(' ', $level);
+
+ # The ugly double sprintf is to work around a PHP bug,
+ # which has been fixed in recent releases.
+ return sprintf( "%10s %s %s\n",
+ trim( sprintf( "%7.3f", $delta * 1000.0 ) ),
+ $space, $fname );
+ }
+
+ function getTime() {
+ return microtime(true);
+ #return $this->getUserTime();
+ }
+
+ function getUserTime() {
+ $ru = getrusage();
+ return $ru['ru_utime.tv_sec'].' '.$ru['ru_utime.tv_usec'] / 1e6;
+ }
+
+ function getFunctionReport() {
+ $width = 140;
+ $nameWidth = $width - 65;
+ $format = "%-{$nameWidth}s %6d %13.3f %13.3f %13.3f%% %9d (%13.3f -%13.3f) [%d]\n";
+ $titleFormat = "%-{$nameWidth}s %6s %13s %13s %13s %9s\n";
+ $prof = "\nProfiling data\n";
+ $prof .= sprintf($titleFormat, 'Name', 'Calls', 'Total', 'Each', '%', 'Mem');
+ $this->mCollated = array ();
+ $this->mCalls = array ();
+ $this->mMemory = array ();
+
+ # Estimate profiling overhead
+ $profileCount = count($this->mStack);
+ wfProfileIn('-overhead-total');
+ for ($i = 0; $i < $profileCount; $i ++) {
+ wfProfileIn('-overhead-internal');
+ wfProfileOut('-overhead-internal');
+ }
+ wfProfileOut('-overhead-total');
+
+ # First, subtract the overhead!
+ foreach ($this->mStack as $entry) {
+ $fname = $entry[0];
+ $start = $entry[2];
+ $end = $entry[4];
+ $elapsed = $end - $start;
+ $memory = $entry[5] - $entry[3];
+
+ if ($fname == '-overhead-total') {
+ $overheadTotal[] = $elapsed;
+ $overheadMemory[] = $memory;
+ }
+ elseif ($fname == '-overhead-internal') {
+ $overheadInternal[] = $elapsed;
+ }
+ }
+ $overheadTotal = array_sum($overheadTotal) / count($overheadInternal);
+ $overheadMemory = array_sum($overheadMemory) / count($overheadInternal);
+ $overheadInternal = array_sum($overheadInternal) / count($overheadInternal);
+
+ # Collate
+ foreach ($this->mStack as $index => $entry) {
+ $fname = $entry[0];
+ $start = $entry[2];
+ $end = $entry[4];
+ $elapsed = $end - $start;
+
+ $memory = $entry[5] - $entry[3];
+ $subcalls = $this->calltreeCount($this->mStack, $index);
+
+ if (!preg_match('/^-overhead/', $fname)) {
+ # Adjust for profiling overhead (except special values with elapsed=0
+ if ( $elapsed ) {
+ $elapsed -= $overheadInternal;
+ $elapsed -= ($subcalls * $overheadTotal);
+ $memory -= ($subcalls * $overheadMemory);
+ }
+ }
+
+ if (!array_key_exists($fname, $this->mCollated)) {
+ $this->mCollated[$fname] = 0;
+ $this->mCalls[$fname] = 0;
+ $this->mMemory[$fname] = 0;
+ $this->mMin[$fname] = 1 << 24;
+ $this->mMax[$fname] = 0;
+ $this->mOverhead[$fname] = 0;
+ }
+
+ $this->mCollated[$fname] += $elapsed;
+ $this->mCalls[$fname]++;
+ $this->mMemory[$fname] += $memory;
+ $this->mMin[$fname] = min($this->mMin[$fname], $elapsed);
+ $this->mMax[$fname] = max($this->mMax[$fname], $elapsed);
+ $this->mOverhead[$fname] += $subcalls;
+ }
+
+ $total = @ $this->mCollated['-total'];
+ $this->mCalls['-overhead-total'] = $profileCount;
+
+ # Output
+ arsort($this->mCollated, SORT_NUMERIC);
+ foreach ($this->mCollated as $fname => $elapsed) {
+ $calls = $this->mCalls[$fname];
+ $percent = $total ? 100. * $elapsed / $total : 0;
+ $memory = $this->mMemory[$fname];
+ $prof .= sprintf($format, substr($fname, 0, $nameWidth), $calls, (float) ($elapsed * 1000), (float) ($elapsed * 1000) / $calls, $percent, $memory, ($this->mMin[$fname] * 1000.0), ($this->mMax[$fname] * 1000.0), $this->mOverhead[$fname]);
+
+ global $wgProfileToDatabase;
+ if ($wgProfileToDatabase) {
+ Profiler :: logToDB($fname, (float) ($elapsed * 1000), $calls);
+ }
+ }
+ $prof .= "\nTotal: $total\n\n";
+
+ return $prof;
+ }
+
+ /**
+ * Counts the number of profiled function calls sitting under
+ * the given point in the call graph. Not the most efficient algo.
+ *
+ * @param $stack Array:
+ * @param $start Integer:
+ * @return Integer
+ * @private
+ */
+ function calltreeCount(& $stack, $start) {
+ $level = $stack[$start][1];
+ $count = 0;
+ for ($i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i --) {
+ $count ++;
+ }
+ return $count;
+ }
+
+ /**
+ * @static
+ */
+ function logToDB($name, $timeSum, $eventCount) {
+ # Warning: $wguname is a live patch, it should be moved to Setup.php
+ global $wguname, $wgProfilePerHost;
+
+ $fname = 'Profiler::logToDB';
+ $dbw = & wfGetDB(DB_MASTER);
+ if (!is_object($dbw))
+ return false;
+ $errorState = $dbw->ignoreErrors( true );
+ $profiling = $dbw->tableName('profiling');
+
+ $name = substr($name, 0, 255);
+ $encname = $dbw->strencode($name);
+
+ if ($wgProfilePerHost) {
+ $pfhost = $wguname['nodename'];
+ } else {
+ $pfhost = '';
+ }
+
+ $sql = "UPDATE $profiling "."SET pf_count=pf_count+{$eventCount}, "."pf_time=pf_time + {$timeSum} ".
+ "WHERE pf_name='{$encname}' AND pf_server='{$pfhost}'";
+ $dbw->query($sql);
+
+ $rc = $dbw->affectedRows();
+ if ($rc == 0) {
+ $dbw->insert('profiling', array ('pf_name' => $name, 'pf_count' => $eventCount,
+ 'pf_time' => $timeSum, 'pf_server' => $pfhost ), $fname, array ('IGNORE'));
+ }
+ // When we upgrade to mysql 4.1, the insert+update
+ // can be merged into just a insert with this construct added:
+ // "ON DUPLICATE KEY UPDATE ".
+ // "pf_count=pf_count + VALUES(pf_count), ".
+ // "pf_time=pf_time + VALUES(pf_time)";
+ $dbw->ignoreErrors( $errorState );
+ }
+
+ /**
+ * Get the function name of the current profiling section
+ */
+ function getCurrentSection() {
+ $elt = end($this->mWorkStack);
+ return $elt[0];
+ }
+
+ static function getCaller( $level ) {
+ $backtrace = wfDebugBacktrace();
+ if ( isset( $backtrace[$level] ) ) {
+ if ( isset( $backtrace[$level]['class'] ) ) {
+ $caller = $backtrace[$level]['class'] . '::' . $backtrace[$level]['function'];
+ } else {
+ $caller = $backtrace[$level]['function'];
+ }
+ } else {
+ $caller = 'unknown';
+ }
+ return $caller;
+ }
+
+}
+
+?>
diff --git a/includes/ProfilerSimple.php b/includes/ProfilerSimple.php
new file mode 100644
index 000000000000..e69bfc475b15
--- /dev/null
+++ b/includes/ProfilerSimple.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Simple profiler base class
+ * @package MediaWiki
+ */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+require_once(dirname(__FILE__).'/Profiler.php');
+
+class ProfilerSimple extends Profiler {
+ var $mMinimumTime = 0;
+ var $mProfileID = false;
+
+ function ProfilerSimple() {
+ global $wgRequestTime,$wgRUstart;
+ if (!empty($wgRequestTime) && !empty($wgRUstart)) {
+ $this->mWorkStack[] = array( '-total', 0, $wgRequestTime,$this->getCpuTime($wgRUstart));
+
+ $elapsedcpu = $this->getCpuTime() - $this->getCpuTime($wgRUstart);
+ $elapsedreal = microtime(true) - $wgRequestTime;
+
+ $entry =& $this->mCollated["-setup"];
+ if (!is_array($entry)) {
+ $entry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0);
+ $this->mCollated["-setup"] =& $entry;
+
+ }
+ $entry['cpu'] += $elapsedcpu;
+ $entry['cpu_sq'] += $elapsedcpu*$elapsedcpu;
+ $entry['real'] += $elapsedreal;
+ $entry['real_sq'] += $elapsedreal*$elapsedreal;
+ $entry['count']++;
+ }
+ }
+
+ function setMinimum( $min ) {
+ $this->mMinimumTime = $min;
+ }
+
+ function setProfileID( $id ) {
+ $this->mProfileID = $id;
+ }
+
+ function getProfileID() {
+ if ( $this->mProfileID === false ) {
+ return wfWikiID();
+ } else {
+ return $this->mProfileID;
+ }
+ }
+
+ function profileIn($functionname) {
+ global $wgDebugFunctionEntry;
+ if ($wgDebugFunctionEntry) {
+ $this->debug(str_repeat(' ', count($this->mWorkStack)).'Entering '.$functionname."\n");
+ }
+ $this->mWorkStack[] = array($functionname, count( $this->mWorkStack ), microtime(true), $this->getCpuTime());
+ }
+
+ function profileOut($functionname) {
+ global $wgDebugFunctionEntry;
+
+ if ($wgDebugFunctionEntry) {
+ $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n");
+ }
+
+ list($ofname, /* $ocount */ ,$ortime,$octime) = array_pop($this->mWorkStack);
+
+ if (!$ofname) {
+ $this->debug("Profiling error: $functionname\n");
+ } else {
+ if ($functionname == 'close') {
+ $message = "Profile section ended by close(): {$ofname}";
+ $functionname = $ofname;
+ $this->debug( "$message\n" );
+ }
+ elseif ($ofname != $functionname) {
+ $message = "Profiling error: in({$ofname}), out($functionname)";
+ $this->debug( "$message\n" );
+ }
+ $entry =& $this->mCollated[$functionname];
+ $elapsedcpu = $this->getCpuTime() - $octime;
+ $elapsedreal = microtime(true) - $ortime;
+ if (!is_array($entry)) {
+ $entry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0);
+ $this->mCollated[$functionname] =& $entry;
+
+ }
+ $entry['cpu'] += $elapsedcpu;
+ $entry['cpu_sq'] += $elapsedcpu*$elapsedcpu;
+ $entry['real'] += $elapsedreal;
+ $entry['real_sq'] += $elapsedreal*$elapsedreal;
+ $entry['count']++;
+
+ }
+ }
+
+ function getFunctionReport() {
+ /* Implement in output subclasses */
+ }
+
+ function getCpuTime($ru=null) {
+ if ( function_exists( 'getrusage' ) ) {
+ if ( $ru == null )
+ $ru = getrusage();
+ return ($ru['ru_utime.tv_sec'] + $ru['ru_stime.tv_sec'] + ($ru['ru_utime.tv_usec'] +
+ $ru['ru_stime.tv_usec']) * 1e-6);
+ } else {
+ return 0;
+ }
+ }
+
+ /* If argument is passed, it assumes that it is dual-format time string, returns proper float time value */
+ function getTime($time=null) {
+ if ($time==null)
+ return microtime(true);
+ list($a,$b)=explode(" ",$time);
+ return (float)($a+$b);
+ }
+
+ function debug( $s ) {
+ if (function_exists( 'wfDebug' ) ) {
+ wfDebug( $s );
+ }
+ }
+}
+?>
diff --git a/includes/ProfilerSimpleUDP.php b/includes/ProfilerSimpleUDP.php
new file mode 100644
index 000000000000..a8527c38917a
--- /dev/null
+++ b/includes/ProfilerSimpleUDP.php
@@ -0,0 +1,39 @@
+<?php
+/* ProfilerSimpleUDP class, that sends out messages for 'udpprofile' daemon
+ (the one from wikipedia/udpprofile CVS )
+*/
+
+require_once(dirname(__FILE__).'/Profiler.php');
+require_once(dirname(__FILE__).'/ProfilerSimple.php');
+
+class ProfilerSimpleUDP extends ProfilerSimple {
+ function getFunctionReport() {
+ global $wgUDPProfilerHost;
+ global $wgUDPProfilerPort;
+
+ if ( $this->mCollated['-total']['real'] < $this->mMinimumTime ) {
+ # Less than minimum, ignore
+ return;
+ }
+
+
+ $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
+ $plength=0;
+ $packet="";
+ foreach ($this->mCollated as $entry=>$pfdata) {
+ $pfline=sprintf ("%s %s %d %f %f %f %f %s\n", $this->getProfileID(),"-",$pfdata['count'],
+ $pfdata['cpu'],$pfdata['cpu_sq'],$pfdata['real'],$pfdata['real_sq'],$entry);
+ $length=strlen($pfline);
+ /* printf("<!-- $pfline -->"); */
+ if ($length+$plength>1400) {
+ socket_sendto($sock,$packet,$plength,0,$wgUDPProfilerHost,$wgUDPProfilerPort);
+ $packet="";
+ $plength=0;
+ }
+ $packet.=$pfline;
+ $plength+=$length;
+ }
+ socket_sendto($sock,$packet,$plength,0x100,$wgUDPProfilerHost,$wgUDPProfilerPort);
+ }
+}
+?>
diff --git a/includes/ProfilerStub.php b/includes/ProfilerStub.php
new file mode 100644
index 000000000000..4cf0aa4494ad
--- /dev/null
+++ b/includes/ProfilerStub.php
@@ -0,0 +1,26 @@
+<?php
+
+# Stub profiling functions
+
+$haveProctitle=function_exists("setproctitle");
+function wfProfileIn( $fn = '' ) {
+ global $hackwhere, $wgDBname, $haveProctitle;
+ if ($haveProctitle) {
+ $hackwhere[] = $fn;
+ setproctitle($fn . " [$wgDBname]");
+ }
+}
+function wfProfileOut( $fn = '' ) {
+ global $hackwhere, $wgDBname, $haveProctitle;
+ if (!$haveProctitle)
+ return;
+ if (count($hackwhere))
+ array_pop($hackwhere);
+ if (count($hackwhere))
+ setproctitle($hackwhere[count($hackwhere)-1] . " [$wgDBname]");
+}
+function wfGetProfilingOutput( $s, $e ) {}
+function wfProfileClose() {}
+$wgProfiling = false;
+
+?>
diff --git a/includes/ProtectionForm.php b/includes/ProtectionForm.php
new file mode 100644
index 000000000000..f96262fe6b90
--- /dev/null
+++ b/includes/ProtectionForm.php
@@ -0,0 +1,243 @@
+<?php
+/**
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+class ProtectionForm {
+ var $mRestrictions = array();
+ var $mReason = '';
+
+ function ProtectionForm( &$article ) {
+ global $wgRequest, $wgUser;
+ global $wgRestrictionTypes, $wgRestrictionLevels;
+ $this->mArticle =& $article;
+ $this->mTitle =& $article->mTitle;
+
+ if( $this->mTitle ) {
+ foreach( $wgRestrictionTypes as $action ) {
+ // Fixme: this form currently requires individual selections,
+ // but the db allows multiples separated by commas.
+ $this->mRestrictions[$action] = implode( '', $this->mTitle->getRestrictions( $action ) );
+ }
+ }
+
+ // The form will be available in read-only to show levels.
+ $this->disabled = !$wgUser->isAllowed( 'protect' ) || wfReadOnly() || $wgUser->isBlocked();
+ $this->disabledAttrib = $this->disabled
+ ? array( 'disabled' => 'disabled' )
+ : array();
+
+ if( $wgRequest->wasPosted() ) {
+ $this->mReason = $wgRequest->getText( 'mwProtect-reason' );
+ foreach( $wgRestrictionTypes as $action ) {
+ $val = $wgRequest->getVal( "mwProtect-level-$action" );
+ if( isset( $val ) && in_array( $val, $wgRestrictionLevels ) ) {
+ $this->mRestrictions[$action] = $val;
+ }
+ }
+ }
+ }
+
+ function show() {
+ global $wgOut;
+
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ if( is_null( $this->mTitle ) ||
+ !$this->mTitle->exists() ||
+ $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+ $wgOut->showFatalError( wfMsg( 'badarticleerror' ) );
+ return;
+ }
+
+ if( $this->save() ) {
+ $wgOut->redirect( $this->mTitle->getFullUrl() );
+ return;
+ }
+
+ $wgOut->setPageTitle( wfMsg( 'confirmprotect' ) );
+ $wgOut->setSubtitle( wfMsg( 'protectsub', $this->mTitle->getPrefixedText() ) );
+
+ $wgOut->addWikiText(
+ wfMsg( $this->disabled ? "protect-viewtext" : "protect-text",
+ wfEscapeWikiText( $this->mTitle->getPrefixedText() ) ) );
+
+ $wgOut->addHTML( $this->buildForm() );
+
+ $this->showLogExtract( $wgOut );
+ }
+
+ function save() {
+ global $wgRequest, $wgUser, $wgOut;
+ if( !$wgRequest->wasPosted() ) {
+ return false;
+ }
+
+ if( $this->disabled ) {
+ return false;
+ }
+
+ $token = $wgRequest->getVal( 'wpEditToken' );
+ if( !$wgUser->matchEditToken( $token ) ) {
+ throw new FatalError( wfMsg( 'sessionfailure' ) );
+ }
+
+ $ok = $this->mArticle->updateRestrictions( $this->mRestrictions, $this->mReason );
+ if( !$ok ) {
+ throw new FatalError( "Unknown error at restriction save time." );
+ }
+ return $ok;
+ }
+
+ function buildForm() {
+ global $wgUser;
+
+ $out = '';
+ if( !$this->disabled ) {
+ $out .= $this->buildScript();
+ // The submission needs to reenable the move permission selector
+ // if it's in locked mode, or some browsers won't submit the data.
+ $out .= wfOpenElement( 'form', array(
+ 'action' => $this->mTitle->getLocalUrl( 'action=protect' ),
+ 'method' => 'post',
+ 'onsubmit' => 'protectEnable(true)' ) );
+
+ $out .= wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'wpEditToken',
+ 'value' => $wgUser->editToken() ) );
+ }
+
+ $out .= "<table id='mwProtectSet'>";
+ $out .= "<tbody>";
+ $out .= "<tr>\n";
+ foreach( $this->mRestrictions as $action => $required ) {
+ /* Not all languages have V_x <-> N_x relation */
+ $out .= "<th>" . wfMsgHtml( 'restriction-' . $action ) . "</th>\n";
+ }
+ $out .= "</tr>\n";
+ $out .= "<tr>\n";
+ foreach( $this->mRestrictions as $action => $selected ) {
+ $out .= "<td>\n";
+ $out .= $this->buildSelector( $action, $selected );
+ $out .= "</td>\n";
+ }
+ $out .= "</tr>\n";
+
+ // JavaScript will add another row with a value-chaining checkbox
+
+ $out .= "</tbody>\n";
+ $out .= "</table>\n";
+
+ if( !$this->disabled ) {
+ $out .= "<table>\n";
+ $out .= "<tbody>\n";
+ $out .= "<tr><td>" . $this->buildReasonInput() . "</td></tr>\n";
+ $out .= "<tr><td></td><td>" . $this->buildSubmit() . "</td></tr>\n";
+ $out .= "</tbody>\n";
+ $out .= "</table>\n";
+ $out .= "</form>\n";
+ $out .= $this->buildCleanupScript();
+ }
+
+ return $out;
+ }
+
+ function buildSelector( $action, $selected ) {
+ global $wgRestrictionLevels;
+ $id = 'mwProtect-level-' . $action;
+ $attribs = array(
+ 'id' => $id,
+ 'name' => $id,
+ 'size' => count( $wgRestrictionLevels ),
+ 'onchange' => 'protectLevelsUpdate(this)',
+ ) + $this->disabledAttrib;
+
+ $out = wfOpenElement( 'select', $attribs );
+ foreach( $wgRestrictionLevels as $key ) {
+ $out .= $this->buildOption( $key, $selected );
+ }
+ $out .= "</select>\n";
+ return $out;
+ }
+
+ function buildOption( $key, $selected ) {
+ $text = ( $key == '' )
+ ? wfMsg( 'protect-default' )
+ : wfMsg( "protect-level-$key" );
+ $selectedAttrib = ($selected == $key)
+ ? array( 'selected' => 'selected' )
+ : array();
+ return wfElement( 'option',
+ array( 'value' => $key ) + $selectedAttrib,
+ $text );
+ }
+
+ function buildReasonInput() {
+ $id = 'mwProtect-reason';
+ return wfElement( 'label', array(
+ 'id' => "$id-label",
+ 'for' => $id ),
+ wfMsg( 'protectcomment' ) ) .
+ '</td><td>' .
+ wfElement( 'input', array(
+ 'size' => 60,
+ 'name' => $id,
+ 'id' => $id ) );
+ }
+
+ function buildSubmit() {
+ return wfElement( 'input', array(
+ 'type' => 'submit',
+ 'value' => wfMsg( 'confirm' ) ) );
+ }
+
+ function buildScript() {
+ global $wgStylePath, $wgStyleVersion;
+ return '<script type="text/javascript" src="' .
+ htmlspecialchars( $wgStylePath . "/common/protect.js?$wgStyleVersion" ) .
+ '"></script>';
+ }
+
+ function buildCleanupScript() {
+ return '<script type="text/javascript">protectInitialize("mwProtectSet","' .
+ wfEscapeJsString( wfMsg( 'protect-unchain' ) ) . '")</script>';
+ }
+
+ /**
+ * @param OutputPage $out
+ * @access private
+ */
+ function showLogExtract( &$out ) {
+ # Show relevant lines from the deletion log:
+ $out->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'protect' ) ) . "</h2>\n" );
+ $logViewer = new LogViewer(
+ new LogReader(
+ new FauxRequest(
+ array( 'page' => $this->mTitle->getPrefixedText(),
+ 'type' => 'protect' ) ) ) );
+ $logViewer->showList( $out );
+ }
+}
+
+
+?>
diff --git a/includes/ProxyTools.php b/includes/ProxyTools.php
new file mode 100644
index 000000000000..22ea4947cb8c
--- /dev/null
+++ b/includes/ProxyTools.php
@@ -0,0 +1,217 @@
+<?php
+/**
+ * Functions for dealing with proxies
+ * @package MediaWiki
+ */
+
+function wfGetForwardedFor() {
+ if( function_exists( 'apache_request_headers' ) ) {
+ // More reliable than $_SERVER due to case and -/_ folding
+ $set = apache_request_headers();
+ $index = 'X-Forwarded-For';
+ } else {
+ // Subject to spoofing with headers like X_Forwarded_For
+ $set = $_SERVER;
+ $index = 'HTTP_X_FORWARDED_FOR';
+ }
+ if( isset( $set[$index] ) ) {
+ return $set[$index];
+ } else {
+ return null;
+ }
+}
+
+/** Work out the IP address based on various globals */
+function wfGetIP() {
+ global $wgIP;
+
+ # Return cached result
+ if ( !empty( $wgIP ) ) {
+ return $wgIP;
+ }
+
+ /* collect the originating ips */
+ # Client connecting to this webserver
+ if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
+ $ipchain = array( IP::canonicalize( $_SERVER['REMOTE_ADDR'] ) );
+ } else {
+ # Running on CLI?
+ $ipchain = array( '127.0.0.1' );
+ }
+ $ip = $ipchain[0];
+
+ # Append XFF on to $ipchain
+ $forwardedFor = wfGetForwardedFor();
+ if ( isset( $forwardedFor ) ) {
+ $xff = array_map( 'trim', explode( ',', $forwardedFor ) );
+ $xff = array_reverse( $xff );
+ $ipchain = array_merge( $ipchain, $xff );
+ }
+
+ # Step through XFF list and find the last address in the list which is a trusted server
+ # Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private)
+ foreach ( $ipchain as $i => $curIP ) {
+ $curIP = IP::canonicalize( $curIP );
+ if ( wfIsTrustedProxy( $curIP ) ) {
+ if ( isset( $ipchain[$i + 1] ) && IP::isPublic( $ipchain[$i + 1] ) ) {
+ $ip = $ipchain[$i + 1];
+ }
+ } else {
+ break;
+ }
+ }
+
+ wfDebug( "IP: $ip\n" );
+ $wgIP = $ip;
+ return $ip;
+}
+
+function wfIsTrustedProxy( $ip ) {
+ global $wgSquidServers, $wgSquidServersNoPurge;
+
+ if ( in_array( $ip, $wgSquidServers ) ||
+ in_array( $ip, $wgSquidServersNoPurge ) ||
+ wfIsAOLProxy( $ip )
+ ) {
+ $trusted = true;
+ } else {
+ $trusted = false;
+ }
+ wfRunHooks( 'IsTrustedProxy', array( &$ip, &$trusted ) );
+ return $trusted;
+}
+
+/**
+ * Forks processes to scan the originating IP for an open proxy server
+ * MemCached can be used to skip IPs that have already been scanned
+ */
+function wfProxyCheck() {
+ global $wgBlockOpenProxies, $wgProxyPorts, $wgProxyScriptPath;
+ global $wgUseMemCached, $wgMemc, $wgProxyMemcExpiry;
+ global $wgProxyKey;
+
+ if ( !$wgBlockOpenProxies ) {
+ return;
+ }
+
+ $ip = wfGetIP();
+
+ # Get MemCached key
+ $skip = false;
+ if ( $wgUseMemCached ) {
+ $mcKey = wfMemcKey( 'proxy', 'ip', $ip );
+ $mcValue = $wgMemc->get( $mcKey );
+ if ( $mcValue ) {
+ $skip = true;
+ }
+ }
+
+ # Fork the processes
+ if ( !$skip ) {
+ $title = SpecialPage::getTitleFor( 'Blockme' );
+ $iphash = md5( $ip . $wgProxyKey );
+ $url = $title->getFullURL( 'ip='.$iphash );
+
+ foreach ( $wgProxyPorts as $port ) {
+ $params = implode( ' ', array(
+ escapeshellarg( $wgProxyScriptPath ),
+ escapeshellarg( $ip ),
+ escapeshellarg( $port ),
+ escapeshellarg( $url )
+ ));
+ exec( "php $params &>/dev/null &" );
+ }
+ # Set MemCached key
+ if ( $wgUseMemCached ) {
+ $wgMemc->set( $mcKey, 1, $wgProxyMemcExpiry );
+ }
+ }
+}
+
+/**
+ * Convert a network specification in CIDR notation to an integer network and a number of bits
+ */
+function wfParseCIDR( $range ) {
+ return IP::parseCIDR( $range );
+}
+
+/**
+ * Check if an IP address is in the local proxy list
+ */
+function wfIsLocallyBlockedProxy( $ip ) {
+ global $wgProxyList;
+ $fname = 'wfIsLocallyBlockedProxy';
+
+ if ( !$wgProxyList ) {
+ return false;
+ }
+ wfProfileIn( $fname );
+
+ if ( !is_array( $wgProxyList ) ) {
+ # Load from the specified file
+ $wgProxyList = array_map( 'trim', file( $wgProxyList ) );
+ }
+
+ if ( !is_array( $wgProxyList ) ) {
+ $ret = false;
+ } elseif ( array_search( $ip, $wgProxyList ) !== false ) {
+ $ret = true;
+ } elseif ( array_key_exists( $ip, $wgProxyList ) ) {
+ # Old-style flipped proxy list
+ $ret = true;
+ } else {
+ $ret = false;
+ }
+ wfProfileOut( $fname );
+ return $ret;
+}
+
+/**
+ * TODO: move this list to the database in a global IP info table incorporating
+ * trusted ISP proxies, blocked IP addresses and open proxies.
+ */
+function wfIsAOLProxy( $ip ) {
+ $ranges = array(
+ '64.12.96.0/19',
+ '149.174.160.0/20',
+ '152.163.240.0/21',
+ '152.163.248.0/22',
+ '152.163.252.0/23',
+ '152.163.96.0/22',
+ '152.163.100.0/23',
+ '195.93.32.0/22',
+ '195.93.48.0/22',
+ '195.93.64.0/19',
+ '195.93.96.0/19',
+ '195.93.16.0/20',
+ '198.81.0.0/22',
+ '198.81.16.0/20',
+ '198.81.8.0/23',
+ '202.67.64.128/25',
+ '205.188.192.0/20',
+ '205.188.208.0/23',
+ '205.188.112.0/20',
+ '205.188.146.144/30',
+ '207.200.112.0/21',
+ );
+
+ static $parsedRanges;
+ if ( is_null( $parsedRanges ) ) {
+ $parsedRanges = array();
+ foreach ( $ranges as $range ) {
+ $parsedRanges[] = IP::parseRange( $range );
+ }
+ }
+
+ $hex = IP::toHex( $ip );
+ foreach ( $parsedRanges as $range ) {
+ if ( $hex >= $range[0] && $hex <= $range[1] ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+?>
diff --git a/includes/QueryPage.php b/includes/QueryPage.php
new file mode 100644
index 000000000000..ff6355e75432
--- /dev/null
+++ b/includes/QueryPage.php
@@ -0,0 +1,501 @@
+<?php
+/**
+ * Contain a class for special pages
+ * @package MediaWiki
+ */
+
+/**
+ * List of query page classes and their associated special pages, for periodic update purposes
+ */
+global $wgQueryPages; // not redundant
+$wgQueryPages = array(
+// QueryPage subclass Special page name Limit (false for none, none for the default)
+//----------------------------------------------------------------------------
+ array( 'AncientPagesPage', 'Ancientpages' ),
+ array( 'BrokenRedirectsPage', 'BrokenRedirects' ),
+ array( 'CategoriesPage', 'Categories' ),
+ array( 'DeadendPagesPage', 'Deadendpages' ),
+ array( 'DisambiguationsPage', 'Disambiguations' ),
+ array( 'DoubleRedirectsPage', 'DoubleRedirects' ),
+ array( 'ListUsersPage', 'Listusers' ),
+ array( 'ListredirectsPage', 'Listredirects' ),
+ array( 'LonelyPagesPage', 'Lonelypages' ),
+ array( 'LongPagesPage', 'Longpages' ),
+ array( 'MostcategoriesPage', 'Mostcategories' ),
+ array( 'MostimagesPage', 'Mostimages' ),
+ array( 'MostlinkedCategoriesPage', 'Mostlinkedcategories' ),
+ array( 'MostlinkedPage', 'Mostlinked' ),
+ array( 'MostrevisionsPage', 'Mostrevisions' ),
+ array( 'NewPagesPage', 'Newpages' ),
+ array( 'ShortPagesPage', 'Shortpages' ),
+ array( 'UncategorizedCategoriesPage', 'Uncategorizedcategories' ),
+ array( 'UncategorizedPagesPage', 'Uncategorizedpages' ),
+ array( 'UncategorizedImagesPage', 'Uncategorizedimages' ),
+ array( 'UnusedCategoriesPage', 'Unusedcategories' ),
+ array( 'UnusedimagesPage', 'Unusedimages' ),
+ array( 'WantedCategoriesPage', 'Wantedcategories' ),
+ array( 'WantedPagesPage', 'Wantedpages' ),
+ array( 'UnwatchedPagesPage', 'Unwatchedpages' ),
+ array( 'UnusedtemplatesPage', 'Unusedtemplates' ),
+);
+wfRunHooks( 'wgQueryPages', array( &$wgQueryPages ) );
+
+global $wgDisableCounters;
+if ( !$wgDisableCounters )
+ $wgQueryPages[] = array( 'PopularPagesPage', 'Popularpages' );
+
+
+/**
+ * This is a class for doing query pages; since they're almost all the same,
+ * we factor out some of the functionality into a superclass, and let
+ * subclasses derive from it.
+ *
+ * @package MediaWiki
+ */
+class QueryPage {
+ /**
+ * Whether or not we want plain listoutput rather than an ordered list
+ *
+ * @var bool
+ */
+ var $listoutput = false;
+
+ /**
+ * The offset and limit in use, as passed to the query() function
+ *
+ * @var integer
+ */
+ var $offset = 0;
+ var $limit = 0;
+
+ /**
+ * A mutator for $this->listoutput;
+ *
+ * @param bool $bool
+ */
+ function setListoutput( $bool ) {
+ $this->listoutput = $bool;
+ }
+
+ /**
+ * Subclasses return their name here. Make sure the name is also
+ * specified in SpecialPage.php and in Language.php as a language message
+ * param.
+ */
+ function getName() {
+ return '';
+ }
+
+ /**
+ * Return title object representing this page
+ *
+ * @return Title
+ */
+ function getTitle() {
+ return SpecialPage::getTitleFor( $this->getName() );
+ }
+
+ /**
+ * Subclasses return an SQL query here.
+ *
+ * Note that the query itself should return the following four columns:
+ * 'type' (your special page's name), 'namespace', 'title', and 'value'
+ * *in that order*. 'value' is used for sorting.
+ *
+ * These may be stored in the querycache table for expensive queries,
+ * and that cached data will be returned sometimes, so the presence of
+ * extra fields can't be relied upon. The cached 'value' column will be
+ * an integer; non-numeric values are useful only for sorting the initial
+ * query.
+ *
+ * Don't include an ORDER or LIMIT clause, this will be added.
+ */
+ function getSQL() {
+ return "SELECT 'sample' as type, 0 as namespace, 'Sample result' as title, 42 as value";
+ }
+
+ /**
+ * Override to sort by increasing values
+ */
+ function sortDescending() {
+ return true;
+ }
+
+ function getOrder() {
+ return ' ORDER BY value ' .
+ ($this->sortDescending() ? 'DESC' : '');
+ }
+
+ /**
+ * Is this query expensive (for some definition of expensive)? Then we
+ * don't let it run in miser mode. $wgDisableQueryPages causes all query
+ * pages to be declared expensive. Some query pages are always expensive.
+ */
+ function isExpensive( ) {
+ global $wgDisableQueryPages;
+ return $wgDisableQueryPages;
+ }
+
+ /**
+ * Whether or not the output of the page in question is retrived from
+ * the database cache.
+ *
+ * @return bool
+ */
+ function isCached() {
+ global $wgMiserMode;
+
+ return $this->isExpensive() && $wgMiserMode;
+ }
+
+ /**
+ * Sometime we dont want to build rss / atom feeds.
+ */
+ function isSyndicated() {
+ return true;
+ }
+
+ /**
+ * Formats the results of the query for display. The skin is the current
+ * skin; you can use it for making links. The result is a single row of
+ * result data. You should be able to grab SQL results off of it.
+ * If the function return "false", the line output will be skipped.
+ */
+ function formatResult( $skin, $result ) {
+ return '';
+ }
+
+ /**
+ * The content returned by this function will be output before any result
+ */
+ function getPageHeader( ) {
+ return '';
+ }
+
+ /**
+ * If using extra form wheely-dealies, return a set of parameters here
+ * as an associative array. They will be encoded and added to the paging
+ * links (prev/next/lengths).
+ * @return array
+ */
+ function linkParameters() {
+ return array();
+ }
+
+ /**
+ * Some special pages (for example SpecialListusers) might not return the
+ * current object formatted, but return the previous one instead.
+ * Setting this to return true, will call one more time wfFormatResult to
+ * be sure that the very last result is formatted and shown.
+ */
+ function tryLastResult( ) {
+ return false;
+ }
+
+ /**
+ * Clear the cache and save new results
+ */
+ function recache( $limit, $ignoreErrors = true ) {
+ $fname = get_class($this) . '::recache';
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbr =& wfGetDB( DB_SLAVE, array( $this->getName(), 'QueryPage::recache', 'vslow' ) );
+ if ( !$dbw || !$dbr ) {
+ return false;
+ }
+
+ $querycache = $dbr->tableName( 'querycache' );
+
+ if ( $ignoreErrors ) {
+ $ignoreW = $dbw->ignoreErrors( true );
+ $ignoreR = $dbr->ignoreErrors( true );
+ }
+
+ # Clear out any old cached data
+ $dbw->delete( 'querycache', array( 'qc_type' => $this->getName() ), $fname );
+ # Do query
+ $sql = $this->getSQL() . $this->getOrder();
+ if ($limit !== false)
+ $sql = $dbr->limitResult($sql, $limit, 0);
+ $res = $dbr->query($sql, $fname);
+ $num = false;
+ if ( $res ) {
+ $num = $dbr->numRows( $res );
+ # Fetch results
+ $insertSql = "INSERT INTO $querycache (qc_type,qc_namespace,qc_title,qc_value) VALUES ";
+ $first = true;
+ while ( $res && $row = $dbr->fetchObject( $res ) ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $insertSql .= ',';
+ }
+ if ( isset( $row->value ) ) {
+ $value = $row->value;
+ } else {
+ $value = '';
+ }
+
+ $insertSql .= '(' .
+ $dbw->addQuotes( $row->type ) . ',' .
+ $dbw->addQuotes( $row->namespace ) . ',' .
+ $dbw->addQuotes( $row->title ) . ',' .
+ $dbw->addQuotes( $value ) . ')';
+ }
+
+ # Save results into the querycache table on the master
+ if ( !$first ) {
+ if ( !$dbw->query( $insertSql, $fname ) ) {
+ // Set result to false to indicate error
+ $dbr->freeResult( $res );
+ $res = false;
+ }
+ }
+ if ( $res ) {
+ $dbr->freeResult( $res );
+ }
+ if ( $ignoreErrors ) {
+ $dbw->ignoreErrors( $ignoreW );
+ $dbr->ignoreErrors( $ignoreR );
+ }
+
+ # Update the querycache_info record for the page
+ $dbw->delete( 'querycache_info', array( 'qci_type' => $this->getName() ), $fname );
+ $dbw->insert( 'querycache_info', array( 'qci_type' => $this->getName(), 'qci_timestamp' => $dbw->timestamp() ), $fname );
+
+ }
+ return $num;
+ }
+
+ /**
+ * This is the actual workhorse. It does everything needed to make a
+ * real, honest-to-gosh query page.
+ *
+ * @param $offset database query offset
+ * @param $limit database query limit
+ * @param $shownavigation show navigation like "next 200"?
+ */
+ function doQuery( $offset, $limit, $shownavigation=true ) {
+ global $wgUser, $wgOut, $wgLang, $wgContLang;
+
+ $this->offset = $offset;
+ $this->limit = $limit;
+
+ $sname = $this->getName();
+ $fname = get_class($this) . '::doQuery';
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $wgOut->setSyndicated( $this->isSyndicated() );
+
+ if ( !$this->isCached() ) {
+ $sql = $this->getSQL();
+ } else {
+ # Get the cached result
+ $querycache = $dbr->tableName( 'querycache' );
+ $type = $dbr->strencode( $sname );
+ $sql =
+ "SELECT qc_type as type, qc_namespace as namespace,qc_title as title, qc_value as value
+ FROM $querycache WHERE qc_type='$type'";
+
+ if( !$this->listoutput ) {
+
+ # Fetch the timestamp of this update
+ $tRes = $dbr->select( 'querycache_info', array( 'qci_timestamp' ), array( 'qci_type' => $type ), $fname );
+ $tRow = $dbr->fetchObject( $tRes );
+
+ if( $tRow ) {
+ $updated = $wgLang->timeAndDate( $tRow->qci_timestamp, true, true );
+ $cacheNotice = wfMsg( 'perfcachedts', $updated );
+ $wgOut->addMeta( 'Data-Cache-Time', $tRow->qci_timestamp );
+ $wgOut->addScript( '<script language="JavaScript">var dataCacheTime = \'' . $tRow->qci_timestamp . '\';</script>' );
+ } else {
+ $cacheNotice = wfMsg( 'perfcached' );
+ }
+
+ $wgOut->addWikiText( $cacheNotice );
+
+ # If updates on this page have been disabled, let the user know
+ # that the data set won't be refreshed for now
+ global $wgDisableQueryPageUpdate;
+ if( is_array( $wgDisableQueryPageUpdate ) && in_array( $this->getName(), $wgDisableQueryPageUpdate ) ) {
+ $wgOut->addWikiText( wfMsg( 'querypage-no-updates' ) );
+ }
+
+ }
+
+ }
+
+ $sql .= $this->getOrder();
+ $sql = $dbr->limitResult($sql, $limit, $offset);
+ $res = $dbr->query( $sql );
+ $num = $dbr->numRows($res);
+
+ $this->preprocessResults( $dbr, $res );
+
+ $sk = $wgUser->getSkin( );
+
+ if($shownavigation) {
+ $wgOut->addHTML( $this->getPageHeader() );
+ $top = wfShowingResults( $offset, $num);
+ $wgOut->addHTML( "<p>{$top}\n" );
+
+ # often disable 'next' link when we reach the end
+ $atend = $num < $limit;
+
+ $sl = wfViewPrevNext( $offset, $limit ,
+ $wgContLang->specialPage( $sname ),
+ wfArrayToCGI( $this->linkParameters() ), $atend );
+ $wgOut->addHTML( "<br />{$sl}</p>\n" );
+ }
+ if ( $num > 0 ) {
+ $s = array();
+ if ( ! $this->listoutput )
+ $s[] = $this->openList( $offset );
+
+ # Only read at most $num rows, because $res may contain the whole 1000
+ for ( $i = 0; $i < $num && $obj = $dbr->fetchObject( $res ); $i++ ) {
+ $format = $this->formatResult( $sk, $obj );
+ if ( $format ) {
+ $attr = ( isset ( $obj->usepatrol ) && $obj->usepatrol &&
+ $obj->patrolled == 0 ) ? ' class="not-patrolled"' : '';
+ $s[] = $this->listoutput ? $format : "<li{$attr}>{$format}</li>\n";
+ }
+ }
+
+ if($this->tryLastResult()) {
+ // flush the very last result
+ $obj = null;
+ $format = $this->formatResult( $sk, $obj );
+ if( $format ) {
+ $attr = ( isset ( $obj->usepatrol ) && $obj->usepatrol &&
+ $obj->patrolled == 0 ) ? ' class="not-patrolled"' : '';
+ $s[] = "<li{$attr}>{$format}</li>\n";
+ }
+ }
+
+ $dbr->freeResult( $res );
+ if ( ! $this->listoutput )
+ $s[] = $this->closeList();
+ $str = $this->listoutput ? $wgContLang->listToText( $s ) : implode( '', $s );
+ $wgOut->addHTML( $str );
+ }
+ if($shownavigation) {
+ $wgOut->addHTML( "<p>{$sl}</p>\n" );
+ }
+ return $num;
+ }
+
+ function openList( $offset ) {
+ return "<ol start='" . ( $offset + 1 ) . "' class='special'>";
+ }
+
+ function closeList() {
+ return '</ol>';
+ }
+
+ /**
+ * Do any necessary preprocessing of the result object.
+ * You should pass this by reference: &$db , &$res [although probably no longer necessary in PHP5]
+ */
+ function preprocessResults( &$db, &$res ) {}
+
+ /**
+ * Similar to above, but packaging in a syndicated feed instead of a web page
+ */
+ function doFeed( $class = '', $limit = 50 ) {
+ global $wgFeedClasses;
+
+ if( isset($wgFeedClasses[$class]) ) {
+ $feed = new $wgFeedClasses[$class](
+ $this->feedTitle(),
+ $this->feedDesc(),
+ $this->feedUrl() );
+ $feed->outHeader();
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $sql = $this->getSQL() . $this->getOrder();
+ $sql = $dbr->limitResult( $sql, $limit, 0 );
+ $res = $dbr->query( $sql, 'QueryPage::doFeed' );
+ while( $obj = $dbr->fetchObject( $res ) ) {
+ $item = $this->feedResult( $obj );
+ if( $item ) $feed->outItem( $item );
+ }
+ $dbr->freeResult( $res );
+
+ $feed->outFooter();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Override for custom handling. If the titles/links are ok, just do
+ * feedItemDesc()
+ */
+ function feedResult( $row ) {
+ if( !isset( $row->title ) ) {
+ return NULL;
+ }
+ $title = Title::MakeTitle( intval( $row->namespace ), $row->title );
+ if( $title ) {
+ $date = isset( $row->timestamp ) ? $row->timestamp : '';
+ $comments = '';
+ if( $title ) {
+ $talkpage = $title->getTalkPage();
+ $comments = $talkpage->getFullURL();
+ }
+
+ return new FeedItem(
+ $title->getPrefixedText(),
+ $this->feedItemDesc( $row ),
+ $title->getFullURL(),
+ $date,
+ $this->feedItemAuthor( $row ),
+ $comments);
+ } else {
+ return NULL;
+ }
+ }
+
+ function feedItemDesc( $row ) {
+ return isset( $row->comment ) ? htmlspecialchars( $row->comment ) : '';
+ }
+
+ function feedItemAuthor( $row ) {
+ return isset( $row->user_text ) ? $row->user_text : '';
+ }
+
+ function feedTitle() {
+ global $wgContLanguageCode, $wgSitename;
+ $page = SpecialPage::getPage( $this->getName() );
+ $desc = $page->getDescription();
+ return "$wgSitename - $desc [$wgContLanguageCode]";
+ }
+
+ function feedDesc() {
+ return wfMsg( 'tagline' );
+ }
+
+ function feedUrl() {
+ $title = SpecialPage::getTitleFor( $this->getName() );
+ return $title->getFullURL();
+ }
+}
+
+/**
+ * This is a subclass for very simple queries that are just looking for page
+ * titles that match some criteria. It formats each result item as a link to
+ * that page.
+ *
+ * @package MediaWiki
+ */
+class PageQueryPage extends QueryPage {
+
+ function formatResult( $skin, $result ) {
+ global $wgContLang;
+ $nt = Title::makeTitle( $result->namespace, $result->title );
+ return $skin->makeKnownLinkObj( $nt, htmlspecialchars( $wgContLang->convert( $nt->getPrefixedText() ) ) );
+ }
+}
+
+?>
diff --git a/includes/RawPage.php b/includes/RawPage.php
new file mode 100644
index 000000000000..a0b76886cdc4
--- /dev/null
+++ b/includes/RawPage.php
@@ -0,0 +1,206 @@
+<?php
+/**
+ * Copyright (C) 2004 Gabriel Wicke <wicke@wikidev.net>
+ * http://wikidev.net/
+ * Based on PageHistory and SpecialExport
+ *
+ * License: GPL (http://www.gnu.org/copyleft/gpl.html)
+ *
+ * @author Gabriel Wicke <wicke@wikidev.net>
+ * @package MediaWiki
+ */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ */
+class RawPage {
+ var $mArticle, $mTitle, $mRequest;
+ var $mOldId, $mGen, $mCharset;
+ var $mSmaxage, $mMaxage;
+ var $mContentType, $mExpandTemplates;
+
+ function RawPage( &$article, $request = false ) {
+ global $wgRequest, $wgInputEncoding, $wgSquidMaxage, $wgJsMimeType;
+ global $wgUser;
+
+ $allowedCTypes = array('text/x-wiki', $wgJsMimeType, 'text/css', 'application/x-zope-edit');
+ $this->mArticle =& $article;
+ $this->mTitle =& $article->mTitle;
+
+ if ( $request === false ) {
+ $this->mRequest =& $wgRequest;
+ } else {
+ $this->mRequest = $request;
+ }
+
+ $ctype = $this->mRequest->getVal( 'ctype' );
+ $smaxage = $this->mRequest->getIntOrNull( 'smaxage', $wgSquidMaxage );
+ $maxage = $this->mRequest->getInt( 'maxage', $wgSquidMaxage );
+ $this->mExpandTemplates = $this->mRequest->getVal( 'templates' ) === 'expand';
+ $this->mUseMessageCache = $this->mRequest->getBool( 'usemsgcache' );
+
+ $oldid = $this->mRequest->getInt( 'oldid' );
+ switch ( $wgRequest->getText( 'direction' ) ) {
+ case 'next':
+ # output next revision, or nothing if there isn't one
+ if ( $oldid ) {
+ $oldid = $this->mTitle->getNextRevisionId( $oldid );
+ }
+ $oldid = $oldid ? $oldid : -1;
+ break;
+ case 'prev':
+ # output previous revision, or nothing if there isn't one
+ if ( ! $oldid ) {
+ # get the current revision so we can get the penultimate one
+ $this->mArticle->getTouched();
+ $oldid = $this->mArticle->mLatest;
+ }
+ $prev = $this->mTitle->getPreviousRevisionId( $oldid );
+ $oldid = $prev ? $prev : -1 ;
+ break;
+ case 'cur':
+ $oldid = 0;
+ break;
+ }
+ $this->mOldId = $oldid;
+
+ # special case for 'generated' raw things: user css/js
+ $gen = $this->mRequest->getVal( 'gen' );
+
+ if($gen == 'css') {
+ $this->mGen = $gen;
+ if( is_null( $smaxage ) ) $smaxage = $wgSquidMaxage;
+ if($ctype == '') $ctype = 'text/css';
+ } elseif ($gen == 'js') {
+ $this->mGen = $gen;
+ if( is_null( $smaxage ) ) $smaxage = $wgSquidMaxage;
+ if($ctype == '') $ctype = $wgJsMimeType;
+ } else {
+ $this->mGen = false;
+ }
+ $this->mCharset = $wgInputEncoding;
+ $this->mSmaxage = intval( $smaxage );
+ $this->mMaxage = $maxage;
+
+ // Output may contain user-specific data; vary for open sessions
+ $this->mPrivateCache = ( $this->mSmaxage == 0 ) ||
+ ( isset( $_COOKIE[ini_get( 'session.name' )] ) ||
+ $wgUser->isLoggedIn() );
+
+ if ( $ctype == '' or ! in_array( $ctype, $allowedCTypes ) ) {
+ $this->mContentType = 'text/x-wiki';
+ } else {
+ $this->mContentType = $ctype;
+ }
+ }
+
+ function view() {
+ global $wgOut, $wgScript;
+
+ if( isset( $_SERVER['SCRIPT_URL'] ) ) {
+ # Normally we use PHP_SELF to get the URL to the script
+ # as it was called, minus the query string.
+ #
+ # Some sites use Apache rewrite rules to handle subdomains,
+ # and have PHP set up in a weird way that causes PHP_SELF
+ # to contain the rewritten URL instead of the one that the
+ # outside world sees.
+ #
+ # If in this mode, use SCRIPT_URL instead, which mod_rewrite
+ # provides containing the "before" URL.
+ $url = $_SERVER['SCRIPT_URL'];
+ } else {
+ $url = $_SERVER['PHP_SELF'];
+ }
+
+ $ua = @$_SERVER['HTTP_USER_AGENT'];
+ if( strcmp( $wgScript, $url ) && strpos( $ua, 'MSIE' ) !== false ) {
+ # Internet Explorer will ignore the Content-Type header if it
+ # thinks it sees a file extension it recognizes. Make sure that
+ # all raw requests are done through the script node, which will
+ # have eg '.php' and should remain safe.
+ #
+ # We used to redirect to a canonical-form URL as a general
+ # backwards-compatibility / good-citizen nice thing. However
+ # a lot of servers are set up in buggy ways, resulting in
+ # redirect loops which hang the browser until the CSS load
+ # times out.
+ #
+ # Just return a 403 Forbidden and get it over with.
+ wfHttpError( 403, 'Forbidden',
+ 'Raw pages must be accessed through the primary script entry point.' );
+ return;
+ }
+
+ header( "Content-type: ".$this->mContentType.'; charset='.$this->mCharset );
+ # allow the client to cache this for 24 hours
+ $mode = $this->mPrivateCache ? 'private' : 'public';
+ header( 'Cache-Control: '.$mode.', s-maxage='.$this->mSmaxage.', max-age='.$this->mMaxage );
+ echo $this->getRawText();
+ $wgOut->disable();
+ }
+
+ function getRawText() {
+ global $wgUser, $wgOut, $wgRequest;
+ if($this->mGen) {
+ $sk = $wgUser->getSkin();
+ $sk->initPage($wgOut);
+ if($this->mGen == 'css') {
+ return $sk->getUserStylesheet();
+ } else if($this->mGen == 'js') {
+ return $sk->getUserJs();
+ }
+ } else {
+ return $this->getArticleText();
+ }
+ }
+
+ function getArticleText() {
+ $found = false;
+ $text = '';
+ if( $this->mTitle ) {
+ // If it's a MediaWiki message we can just hit the message cache
+ if ( $this->mUseMessageCache && $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+ $key = $this->mTitle->getDBkey();
+ $text = wfMsgForContentNoTrans( $key );
+ # If the message doesn't exist, return a blank
+ if( wfEmptyMsg( $key, $text ) )
+ $text = '';
+ $found = true;
+ } else {
+ // Get it from the DB
+ $rev = Revision::newFromTitle( $this->mTitle, $this->mOldId );
+ if ( $rev ) {
+ $lastmod = wfTimestamp( TS_RFC2822, $rev->getTimestamp() );
+ header( "Last-modified: $lastmod" );
+ $text = $rev->getText();
+ $found = true;
+ }
+ }
+ }
+
+ # Bad title or page does not exist
+ if( !$found && $this->mContentType == 'text/x-wiki' ) {
+ # Don't return a 404 response for CSS or JavaScript;
+ # 404s aren't generally cached and it would create
+ # extra hits when user CSS/JS are on and the user doesn't
+ # have the pages.
+ header( "HTTP/1.0 404 Not Found" );
+ }
+
+ return $this->parseArticleText( $text );
+ }
+
+ function parseArticleText( $text ) {
+ if ( $text === '' )
+ return '';
+ else
+ if ( $this->mExpandTemplates ) {
+ global $wgParser;
+ return $wgParser->preprocess( $text, $this->mTitle, new ParserOptions() );
+ } else
+ return $text;
+ }
+}
+?>
diff --git a/includes/RecentChange.php b/includes/RecentChange.php
new file mode 100644
index 000000000000..1c7791c20e76
--- /dev/null
+++ b/includes/RecentChange.php
@@ -0,0 +1,598 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Utility class for creating new RC entries
+ * mAttribs:
+ * rc_id id of the row in the recentchanges table
+ * rc_timestamp time the entry was made
+ * rc_cur_time timestamp on the cur row
+ * rc_namespace namespace #
+ * rc_title non-prefixed db key
+ * rc_type is new entry, used to determine whether updating is necessary
+ * rc_minor is minor
+ * rc_cur_id page_id of associated page entry
+ * rc_user user id who made the entry
+ * rc_user_text user name who made the entry
+ * rc_comment edit summary
+ * rc_this_oldid rev_id associated with this entry (or zero)
+ * rc_last_oldid rev_id associated with the entry before this one (or zero)
+ * rc_bot is bot, hidden
+ * rc_ip IP address of the user in dotted quad notation
+ * rc_new obsolete, use rc_type==RC_NEW
+ * rc_patrolled boolean whether or not someone has marked this edit as patrolled
+ * rc_old_len integer byte length of the text before the edit
+ * rc_new_len the same after the edit
+ *
+ * mExtra:
+ * prefixedDBkey prefixed db key, used by external app via msg queue
+ * lastTimestamp timestamp of previous entry, used in WHERE clause during update
+ * lang the interwiki prefix, automatically set in save()
+ * oldSize text size before the change
+ * newSize text size after the change
+ *
+ * temporary: not stored in the database
+ * notificationtimestamp
+ * numberofWatchingusers
+ *
+ * @todo document functions and variables
+ * @package MediaWiki
+ */
+class RecentChange
+{
+ var $mAttribs = array(), $mExtra = array();
+ var $mTitle = false, $mMovedToTitle = false;
+ var $numberofWatchingusers = 0 ; # Dummy to prevent error message in SpecialRecentchangeslinked
+
+ # Factory methods
+
+ /* static */ function newFromRow( $row )
+ {
+ $rc = new RecentChange;
+ $rc->loadFromRow( $row );
+ return $rc;
+ }
+
+ public static function newFromCurRow( $row, $rc_this_oldid = 0 )
+ {
+ $rc = new RecentChange;
+ $rc->loadFromCurRow( $row, $rc_this_oldid );
+ $rc->notificationtimestamp = false;
+ $rc->numberofWatchingusers = false;
+ return $rc;
+ }
+
+ /**
+ * Obtain the recent change with a given rc_id value
+ *
+ * @param $rcid rc_id value to retrieve
+ * @return RecentChange
+ */
+ public static function newFromId( $rcid ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'recentchanges', '*', array( 'rc_id' => $rcid ), __METHOD__ );
+ if( $res && $dbr->numRows( $res ) > 0 ) {
+ $row = $dbr->fetchObject( $res );
+ $dbr->freeResult( $res );
+ return self::newFromRow( $row );
+ } else {
+ return NULL;
+ }
+ }
+
+ # Accessors
+
+ function setAttribs( $attribs )
+ {
+ $this->mAttribs = $attribs;
+ }
+
+ function setExtra( $extra )
+ {
+ $this->mExtra = $extra;
+ }
+
+ function &getTitle()
+ {
+ if ( $this->mTitle === false ) {
+ $this->mTitle = Title::makeTitle( $this->mAttribs['rc_namespace'], $this->mAttribs['rc_title'] );
+ }
+ return $this->mTitle;
+ }
+
+ function getMovedToTitle()
+ {
+ if ( $this->mMovedToTitle === false ) {
+ $this->mMovedToTitle = Title::makeTitle( $this->mAttribs['rc_moved_to_ns'],
+ $this->mAttribs['rc_moved_to_title'] );
+ }
+ return $this->mMovedToTitle;
+ }
+
+ # Writes the data in this object to the database
+ function save()
+ {
+ global $wgLocalInterwiki, $wgPutIPinRC, $wgRC2UDPAddress, $wgRC2UDPPort, $wgRC2UDPPrefix;
+ $fname = 'RecentChange::save';
+
+ $dbw =& wfGetDB( DB_MASTER );
+ if ( !is_array($this->mExtra) ) {
+ $this->mExtra = array();
+ }
+ $this->mExtra['lang'] = $wgLocalInterwiki;
+
+ if ( !$wgPutIPinRC ) {
+ $this->mAttribs['rc_ip'] = '';
+ }
+
+ ## If our database is strict about IP addresses, use NULL instead of an empty string
+ if ( $dbw->strictIPs() and $this->mAttribs['rc_ip'] == '' ) {
+ unset( $this->mAttribs['rc_ip'] );
+ }
+
+ # Fixup database timestamps
+ $this->mAttribs['rc_timestamp'] = $dbw->timestamp($this->mAttribs['rc_timestamp']);
+ $this->mAttribs['rc_cur_time'] = $dbw->timestamp($this->mAttribs['rc_cur_time']);
+ $this->mAttribs['rc_id'] = $dbw->nextSequenceValue( 'rc_rc_id_seq' );
+
+ ## If we are using foreign keys, an entry of 0 for the page_id will fail, so use NULL
+ if ( $dbw->cascadingDeletes() and $this->mAttribs['rc_cur_id']==0 ) {
+ unset ( $this->mAttribs['rc_cur_id'] );
+ }
+
+ # Insert new row
+ $dbw->insert( 'recentchanges', $this->mAttribs, $fname );
+
+ # Set the ID
+ $this->mAttribs['rc_id'] = $dbw->insertId();
+
+ # Update old rows, if necessary
+ if ( $this->mAttribs['rc_type'] == RC_EDIT ) {
+ $lastTime = $this->mExtra['lastTimestamp'];
+ #$now = $this->mAttribs['rc_timestamp'];
+ #$curId = $this->mAttribs['rc_cur_id'];
+
+ # Don't bother looking for entries that have probably
+ # been purged, it just locks up the indexes needlessly.
+ global $wgRCMaxAge;
+ $age = time() - wfTimestamp( TS_UNIX, $lastTime );
+ if( $age < $wgRCMaxAge ) {
+ # live hack, will commit once tested - kate
+ # Update rc_this_oldid for the entries which were current
+ #
+ #$oldid = $this->mAttribs['rc_last_oldid'];
+ #$ns = $this->mAttribs['rc_namespace'];
+ #$title = $this->mAttribs['rc_title'];
+ #
+ #$dbw->update( 'recentchanges',
+ # array( /* SET */
+ # 'rc_this_oldid' => $oldid
+ # ), array( /* WHERE */
+ # 'rc_namespace' => $ns,
+ # 'rc_title' => $title,
+ # 'rc_timestamp' => $dbw->timestamp( $lastTime )
+ # ), $fname
+ #);
+ }
+
+ # Update rc_cur_time
+ #$dbw->update( 'recentchanges', array( 'rc_cur_time' => $now ),
+ # array( 'rc_cur_id' => $curId ), $fname );
+ }
+
+ # Notify external application via UDP
+ if ( $wgRC2UDPAddress ) {
+ $conn = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
+ if ( $conn ) {
+ $line = $wgRC2UDPPrefix . $this->getIRCLine();
+ socket_sendto( $conn, $line, strlen($line), 0, $wgRC2UDPAddress, $wgRC2UDPPort );
+ socket_close( $conn );
+ }
+ }
+
+ # E-mail notifications
+ global $wgUseEnotif;
+ if( $wgUseEnotif ) {
+ # this would be better as an extension hook
+ include_once( "UserMailer.php" );
+ $enotif = new EmailNotification();
+ $title = Title::makeTitle( $this->mAttribs['rc_namespace'], $this->mAttribs['rc_title'] );
+ $enotif->notifyOnPageChange( $title,
+ $this->mAttribs['rc_timestamp'],
+ $this->mAttribs['rc_comment'],
+ $this->mAttribs['rc_minor'],
+ $this->mAttribs['rc_last_oldid'] );
+ }
+
+ # Notify extensions
+ wfRunHooks( 'RecentChange_save', array( &$this ) );
+ }
+
+ # Marks a certain row as patrolled
+ function markPatrolled( $rcid )
+ {
+ $fname = 'RecentChange::markPatrolled';
+
+ $dbw =& wfGetDB( DB_MASTER );
+
+ $dbw->update( 'recentchanges',
+ array( /* SET */
+ 'rc_patrolled' => 1
+ ), array( /* WHERE */
+ 'rc_id' => $rcid
+ ), $fname
+ );
+ }
+
+ # Makes an entry in the database corresponding to an edit
+ /*static*/ function notifyEdit( $timestamp, &$title, $minor, &$user, $comment,
+ $oldId, $lastTimestamp, $bot = "default", $ip = '', $oldSize = 0, $newSize = 0,
+ $newId = 0)
+ {
+
+ if ( $bot === 'default' ) {
+ $bot = $user->isAllowed( 'bot' );
+ }
+
+ if ( !$ip ) {
+ $ip = wfGetIP();
+ if ( !$ip ) {
+ $ip = '';
+ }
+ }
+
+ $rc = new RecentChange;
+ $rc->mAttribs = array(
+ 'rc_timestamp' => $timestamp,
+ 'rc_cur_time' => $timestamp,
+ 'rc_namespace' => $title->getNamespace(),
+ 'rc_title' => $title->getDBkey(),
+ 'rc_type' => RC_EDIT,
+ 'rc_minor' => $minor ? 1 : 0,
+ 'rc_cur_id' => $title->getArticleID(),
+ 'rc_user' => $user->getID(),
+ 'rc_user_text' => $user->getName(),
+ 'rc_comment' => $comment,
+ 'rc_this_oldid' => $newId,
+ 'rc_last_oldid' => $oldId,
+ 'rc_bot' => $bot ? 1 : 0,
+ 'rc_moved_to_ns' => 0,
+ 'rc_moved_to_title' => '',
+ 'rc_ip' => $ip,
+ 'rc_patrolled' => 0,
+ 'rc_new' => 0, # obsolete
+ 'rc_old_len' => $oldSize,
+ 'rc_new_len' => $newSize
+ );
+
+ $rc->mExtra = array(
+ 'prefixedDBkey' => $title->getPrefixedDBkey(),
+ 'lastTimestamp' => $lastTimestamp,
+ 'oldSize' => $oldSize,
+ 'newSize' => $newSize,
+ );
+ $rc->save();
+ return( $rc->mAttribs['rc_id'] );
+ }
+
+ /**
+ * Makes an entry in the database corresponding to page creation
+ * Note: the title object must be loaded with the new id using resetArticleID()
+ * @todo Document parameters and return
+ * @public
+ * @static
+ */
+ public static function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = "default",
+ $ip='', $size = 0, $newId = 0 )
+ {
+ if ( !$ip ) {
+ $ip = wfGetIP();
+ if ( !$ip ) {
+ $ip = '';
+ }
+ }
+ if ( $bot == 'default' ) {
+ $bot = $user->isAllowed( 'bot' );
+ }
+
+ $rc = new RecentChange;
+ $rc->mAttribs = array(
+ 'rc_timestamp' => $timestamp,
+ 'rc_cur_time' => $timestamp,
+ 'rc_namespace' => $title->getNamespace(),
+ 'rc_title' => $title->getDBkey(),
+ 'rc_type' => RC_NEW,
+ 'rc_minor' => $minor ? 1 : 0,
+ 'rc_cur_id' => $title->getArticleID(),
+ 'rc_user' => $user->getID(),
+ 'rc_user_text' => $user->getName(),
+ 'rc_comment' => $comment,
+ 'rc_this_oldid' => $newId,
+ 'rc_last_oldid' => 0,
+ 'rc_bot' => $bot ? 1 : 0,
+ 'rc_moved_to_ns' => 0,
+ 'rc_moved_to_title' => '',
+ 'rc_ip' => $ip,
+ 'rc_patrolled' => 0,
+ 'rc_new' => 1, # obsolete
+ 'rc_old_len' => 0,
+ 'rc_new_len' => $size
+ );
+
+ $rc->mExtra = array(
+ 'prefixedDBkey' => $title->getPrefixedDBkey(),
+ 'lastTimestamp' => 0,
+ 'oldSize' => 0,
+ 'newSize' => $size
+ );
+ $rc->save();
+ return( $rc->mAttribs['rc_id'] );
+ }
+
+ # Makes an entry in the database corresponding to a rename
+ /*static*/ function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='', $overRedir = false )
+ {
+ if ( !$ip ) {
+ $ip = wfGetIP();
+ if ( !$ip ) {
+ $ip = '';
+ }
+ }
+
+ $rc = new RecentChange;
+ $rc->mAttribs = array(
+ 'rc_timestamp' => $timestamp,
+ 'rc_cur_time' => $timestamp,
+ 'rc_namespace' => $oldTitle->getNamespace(),
+ 'rc_title' => $oldTitle->getDBkey(),
+ 'rc_type' => $overRedir ? RC_MOVE_OVER_REDIRECT : RC_MOVE,
+ 'rc_minor' => 0,
+ 'rc_cur_id' => $oldTitle->getArticleID(),
+ 'rc_user' => $user->getID(),
+ 'rc_user_text' => $user->getName(),
+ 'rc_comment' => $comment,
+ 'rc_this_oldid' => 0,
+ 'rc_last_oldid' => 0,
+ 'rc_bot' => $user->isAllowed( 'bot' ) ? 1 : 0,
+ 'rc_moved_to_ns' => $newTitle->getNamespace(),
+ 'rc_moved_to_title' => $newTitle->getDBkey(),
+ 'rc_ip' => $ip,
+ 'rc_new' => 0, # obsolete
+ 'rc_patrolled' => 1,
+ 'rc_old_len' => NULL,
+ 'rc_new_len' => NULL,
+ );
+
+ $rc->mExtra = array(
+ 'prefixedDBkey' => $oldTitle->getPrefixedDBkey(),
+ 'lastTimestamp' => 0,
+ 'prefixedMoveTo' => $newTitle->getPrefixedDBkey()
+ );
+ $rc->save();
+ }
+
+ /* static */ function notifyMoveToNew( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='' ) {
+ RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip, false );
+ }
+
+ /* static */ function notifyMoveOverRedirect( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='' ) {
+ RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip, true );
+ }
+
+ # A log entry is different to an edit in that previous revisions are
+ # not kept
+ /*static*/ function notifyLog( $timestamp, &$title, &$user, $comment, $ip='',
+ $type, $action, $target, $logComment, $params )
+ {
+ if ( !$ip ) {
+ $ip = wfGetIP();
+ if ( !$ip ) {
+ $ip = '';
+ }
+ }
+
+ $rc = new RecentChange;
+ $rc->mAttribs = array(
+ 'rc_timestamp' => $timestamp,
+ 'rc_cur_time' => $timestamp,
+ 'rc_namespace' => $title->getNamespace(),
+ 'rc_title' => $title->getDBkey(),
+ 'rc_type' => RC_LOG,
+ 'rc_minor' => 0,
+ 'rc_cur_id' => $title->getArticleID(),
+ 'rc_user' => $user->getID(),
+ 'rc_user_text' => $user->getName(),
+ 'rc_comment' => $comment,
+ 'rc_this_oldid' => 0,
+ 'rc_last_oldid' => 0,
+ 'rc_bot' => $user->isAllowed( 'bot' ) ? 1 : 0,
+ 'rc_moved_to_ns' => 0,
+ 'rc_moved_to_title' => '',
+ 'rc_ip' => $ip,
+ 'rc_patrolled' => 1,
+ 'rc_new' => 0, # obsolete
+ 'rc_old_len' => NULL,
+ 'rc_new_len' => NULL,
+ );
+ $rc->mExtra = array(
+ 'prefixedDBkey' => $title->getPrefixedDBkey(),
+ 'lastTimestamp' => 0,
+ 'logType' => $type,
+ 'logAction' => $action,
+ 'logComment' => $logComment,
+ 'logTarget' => $target,
+ 'logParams' => $params
+ );
+ $rc->save();
+ }
+
+ # Initialises the members of this object from a mysql row object
+ function loadFromRow( $row )
+ {
+ $this->mAttribs = get_object_vars( $row );
+ $this->mAttribs["rc_timestamp"] = wfTimestamp(TS_MW, $this->mAttribs["rc_timestamp"]);
+ $this->mExtra = array();
+ }
+
+ # Makes a pseudo-RC entry from a cur row
+ function loadFromCurRow( $row )
+ {
+ $this->mAttribs = array(
+ 'rc_timestamp' => wfTimestamp(TS_MW, $row->rev_timestamp),
+ 'rc_cur_time' => $row->rev_timestamp,
+ 'rc_user' => $row->rev_user,
+ 'rc_user_text' => $row->rev_user_text,
+ 'rc_namespace' => $row->page_namespace,
+ 'rc_title' => $row->page_title,
+ 'rc_comment' => $row->rev_comment,
+ 'rc_minor' => $row->rev_minor_edit ? 1 : 0,
+ 'rc_type' => $row->page_is_new ? RC_NEW : RC_EDIT,
+ 'rc_cur_id' => $row->page_id,
+ 'rc_this_oldid' => $row->rev_id,
+ 'rc_last_oldid' => isset($row->rc_last_oldid) ? $row->rc_last_oldid : 0,
+ 'rc_bot' => 0,
+ 'rc_moved_to_ns' => 0,
+ 'rc_moved_to_title' => '',
+ 'rc_ip' => '',
+ 'rc_id' => $row->rc_id,
+ 'rc_patrolled' => $row->rc_patrolled,
+ 'rc_new' => $row->page_is_new, # obsolete
+ 'rc_old_len' => $row->rc_old_len,
+ 'rc_new_len' => $row->rc_new_len,
+ );
+
+ $this->mExtra = array();
+ }
+
+ /**
+ * Get an attribute value
+ *
+ * @param $name Attribute name
+ * @return mixed
+ */
+ public function getAttribute( $name ) {
+ return isset( $this->mAttribs[$name] ) ? $this->mAttribs[$name] : NULL;
+ }
+
+ /**
+ * Gets the end part of the diff URL associated with this object
+ * Blank if no diff link should be displayed
+ */
+ function diffLinkTrail( $forceCur )
+ {
+ if ( $this->mAttribs['rc_type'] == RC_EDIT ) {
+ $trail = "curid=" . (int)($this->mAttribs['rc_cur_id']) .
+ "&oldid=" . (int)($this->mAttribs['rc_last_oldid']);
+ if ( $forceCur ) {
+ $trail .= '&diff=0' ;
+ } else {
+ $trail .= '&diff=' . (int)($this->mAttribs['rc_this_oldid']);
+ }
+ } else {
+ $trail = '';
+ }
+ return $trail;
+ }
+
+ function cleanupForIRC( $text ) {
+ return str_replace(array("\n", "\r"), array("", ""), $text);
+ }
+
+ function getIRCLine() {
+ global $wgUseRCPatrol;
+
+ extract($this->mAttribs);
+ extract($this->mExtra);
+
+ $titleObj =& $this->getTitle();
+ if ( $rc_type == RC_LOG ) {
+ $title = Namespace::getCanonicalName( $titleObj->getNamespace() ) . $titleObj->getText();
+ } else {
+ $title = $titleObj->getPrefixedText();
+ }
+ $title = $this->cleanupForIRC( $title );
+
+ $bad = array("\n", "\r");
+ $empty = array("", "");
+ $title = $titleObj->getPrefixedText();
+ $title = str_replace($bad, $empty, $title);
+
+ // FIXME: *HACK* these should be getFullURL(), hacked for SSL madness --brion 2005-12-26
+ if ( $rc_type == RC_LOG ) {
+ $url = '';
+ } elseif ( $rc_new && $wgUseRCPatrol ) {
+ $url = $titleObj->getInternalURL("rcid=$rc_id");
+ } else if ( $rc_new ) {
+ $url = $titleObj->getInternalURL();
+ } else if ( $wgUseRCPatrol ) {
+ $url = $titleObj->getInternalURL("diff=$rc_this_oldid&oldid=$rc_last_oldid&rcid=$rc_id");
+ } else {
+ $url = $titleObj->getInternalURL("diff=$rc_this_oldid&oldid=$rc_last_oldid");
+ }
+
+ if ( isset( $oldSize ) && isset( $newSize ) ) {
+ $szdiff = $newSize - $oldSize;
+ if ($szdiff < -500) {
+ $szdiff = "\002$szdiff\002";
+ } elseif ($szdiff >= 0) {
+ $szdiff = '+' . $szdiff ;
+ }
+ $szdiff = '(' . $szdiff . ')' ;
+ } else {
+ $szdiff = '';
+ }
+
+ $user = $this->cleanupForIRC( $rc_user_text );
+
+ if ( $rc_type == RC_LOG ) {
+ $logTargetText = $logTarget->getPrefixedText();
+ $comment = $this->cleanupForIRC( str_replace( $logTargetText, "\00302$logTargetText\00310", $rc_comment ) );
+ $flag = $logAction;
+ } else {
+ $comment = $this->cleanupForIRC( $rc_comment );
+ $flag = ($rc_minor ? "M" : "") . ($rc_new ? "N" : "");
+ }
+ # see http://www.irssi.org/documentation/formats for some colour codes. prefix is \003,
+ # no colour (\003) switches back to the term default
+ $fullString = "\00314[[\00307$title\00314]]\0034 $flag\00310 " .
+ "\00302$url\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n";
+ return $fullString;
+ }
+
+ /**
+ * Returns the change size (HTML).
+ * The lengths can be given optionally.
+ */
+ function getCharacterDifference( $old = 0, $new = 0 ) {
+ global $wgRCChangedSizeThreshold, $wgLang;
+
+ if( $old === 0 ) {
+ $old = $this->mAttribs['rc_old_len'];
+ }
+ if( $new === 0 ) {
+ $new = $this->mAttribs['rc_new_len'];
+ }
+
+ if( $old === NULL || $new === NULL ) {
+ return '';
+ }
+
+ $szdiff = $new - $old;
+ $formatedSize = wfMsgExt( 'rc-change-size', array( 'parsemag', 'escape'),
+ $wgLang->formatNum($szdiff) );
+
+ if( $szdiff < $wgRCChangedSizeThreshold ) {
+ return '<strong class=\'mw-plusminus-neg\'>(' . $formatedSize . ')</strong>';
+ } elseif( $szdiff === 0 ) {
+ return '<span class=\'mw-plusminus-null\'>(' . $formatedSize . ')</span>';
+ } elseif( $szdiff > 0 ) {
+ return '<span class=\'mw-plusminus-pos\'>(+' . $formatedSize . ')</span>';
+ } else {
+ return '<span class=\'mw-plusminus-neg\'>(' . $formatedSize . ')</span>';
+ }
+ }
+}
+?>
diff --git a/includes/Revision.php b/includes/Revision.php
new file mode 100644
index 000000000000..c5235e2255c2
--- /dev/null
+++ b/includes/Revision.php
@@ -0,0 +1,844 @@
+<?php
+/**
+ * @package MediaWiki
+ * @todo document
+ */
+
+/**
+ * @package MediaWiki
+ * @todo document
+ */
+class Revision {
+ const DELETED_TEXT = 1;
+ const DELETED_COMMENT = 2;
+ const DELETED_USER = 4;
+ const DELETED_RESTRICTED = 8;
+
+ /**
+ * Load a page revision from a given revision ID number.
+ * Returns null if no such revision can be found.
+ *
+ * @param int $id
+ * @access public
+ * @static
+ */
+ public static function newFromId( $id ) {
+ return Revision::newFromConds(
+ array( 'page_id=rev_page',
+ 'rev_id' => intval( $id ) ) );
+ }
+
+ /**
+ * Load either the current, or a specified, revision
+ * that's attached to a given title. If not attached
+ * to that title, will return null.
+ *
+ * @param Title $title
+ * @param int $id
+ * @return Revision
+ * @access public
+ * @static
+ */
+ public static function newFromTitle( &$title, $id = 0 ) {
+ if( $id ) {
+ $matchId = intval( $id );
+ } else {
+ $matchId = 'page_latest';
+ }
+ return Revision::newFromConds(
+ array( "rev_id=$matchId",
+ 'page_id=rev_page',
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDbkey() ) );
+ }
+
+ /**
+ * Load a page revision from a given revision ID number.
+ * Returns null if no such revision can be found.
+ *
+ * @param Database $db
+ * @param int $id
+ * @access public
+ * @static
+ */
+ public static function loadFromId( &$db, $id ) {
+ return Revision::loadFromConds( $db,
+ array( 'page_id=rev_page',
+ 'rev_id' => intval( $id ) ) );
+ }
+
+ /**
+ * Load either the current, or a specified, revision
+ * that's attached to a given page. If not attached
+ * to that page, will return null.
+ *
+ * @param Database $db
+ * @param int $pageid
+ * @param int $id
+ * @return Revision
+ * @access public
+ * @static
+ */
+ public static function loadFromPageId( &$db, $pageid, $id = 0 ) {
+ $conds=array('page_id=rev_page','rev_page'=>intval( $pageid ), 'page_id'=>intval( $pageid ));
+ if( $id ) {
+ $conds['rev_id']=intval($id);
+ } else {
+ $conds[]='rev_id=page_latest';
+ }
+ return Revision::loadFromConds( $db, $conds );
+ }
+
+ /**
+ * Load either the current, or a specified, revision
+ * that's attached to a given page. If not attached
+ * to that page, will return null.
+ *
+ * @param Database $db
+ * @param Title $title
+ * @param int $id
+ * @return Revision
+ * @access public
+ * @static
+ */
+ public static function loadFromTitle( &$db, $title, $id = 0 ) {
+ if( $id ) {
+ $matchId = intval( $id );
+ } else {
+ $matchId = 'page_latest';
+ }
+ return Revision::loadFromConds(
+ $db,
+ array( "rev_id=$matchId",
+ 'page_id=rev_page',
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDbkey() ) );
+ }
+
+ /**
+ * Load the revision for the given title with the given timestamp.
+ * WARNING: Timestamps may in some circumstances not be unique,
+ * so this isn't the best key to use.
+ *
+ * @param Database $db
+ * @param Title $title
+ * @param string $timestamp
+ * @return Revision
+ * @access public
+ * @static
+ */
+ public static function loadFromTimestamp( &$db, &$title, $timestamp ) {
+ return Revision::loadFromConds(
+ $db,
+ array( 'rev_timestamp' => $db->timestamp( $timestamp ),
+ 'page_id=rev_page',
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDbkey() ) );
+ }
+
+ /**
+ * Given a set of conditions, fetch a revision.
+ *
+ * @param array $conditions
+ * @return Revision
+ * @access private
+ * @static
+ */
+ private static function newFromConds( $conditions ) {
+ $db =& wfGetDB( DB_SLAVE );
+ $row = Revision::loadFromConds( $db, $conditions );
+ if( is_null( $row ) ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $row = Revision::loadFromConds( $dbw, $conditions );
+ }
+ return $row;
+ }
+
+ /**
+ * Given a set of conditions, fetch a revision from
+ * the given database connection.
+ *
+ * @param Database $db
+ * @param array $conditions
+ * @return Revision
+ * @access private
+ * @static
+ */
+ private static function loadFromConds( &$db, $conditions ) {
+ $res = Revision::fetchFromConds( $db, $conditions );
+ if( $res ) {
+ $row = $res->fetchObject();
+ $res->free();
+ if( $row ) {
+ $ret = new Revision( $row );
+ return $ret;
+ }
+ }
+ $ret = null;
+ return $ret;
+ }
+
+ /**
+ * Return a wrapper for a series of database rows to
+ * fetch all of a given page's revisions in turn.
+ * Each row can be fed to the constructor to get objects.
+ *
+ * @param Title $title
+ * @return ResultWrapper
+ * @access public
+ * @static
+ */
+ public static function fetchAllRevisions( &$title ) {
+ return Revision::fetchFromConds(
+ wfGetDB( DB_SLAVE ),
+ array( 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDbkey(),
+ 'page_id=rev_page' ) );
+ }
+
+ /**
+ * Return a wrapper for a series of database rows to
+ * fetch all of a given page's revisions in turn.
+ * Each row can be fed to the constructor to get objects.
+ *
+ * @param Title $title
+ * @return ResultWrapper
+ * @access public
+ * @static
+ */
+ public static function fetchRevision( &$title ) {
+ return Revision::fetchFromConds(
+ wfGetDB( DB_SLAVE ),
+ array( 'rev_id=page_latest',
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDbkey(),
+ 'page_id=rev_page' ) );
+ }
+
+ /**
+ * Given a set of conditions, return a ResultWrapper
+ * which will return matching database rows with the
+ * fields necessary to build Revision objects.
+ *
+ * @param Database $db
+ * @param array $conditions
+ * @return ResultWrapper
+ * @access private
+ * @static
+ */
+ private static function fetchFromConds( &$db, $conditions ) {
+ $res = $db->select(
+ array( 'page', 'revision' ),
+ array( 'page_namespace',
+ 'page_title',
+ 'page_latest',
+ 'rev_id',
+ 'rev_page',
+ 'rev_text_id',
+ 'rev_comment',
+ 'rev_user_text',
+ 'rev_user',
+ 'rev_minor_edit',
+ 'rev_timestamp',
+ 'rev_deleted' ),
+ $conditions,
+ 'Revision::fetchRow',
+ array( 'LIMIT' => 1 ) );
+ $ret = $db->resultObject( $res );
+ return $ret;
+ }
+
+ /**
+ * @param object $row
+ * @access private
+ */
+ function Revision( $row ) {
+ if( is_object( $row ) ) {
+ $this->mId = intval( $row->rev_id );
+ $this->mPage = intval( $row->rev_page );
+ $this->mTextId = intval( $row->rev_text_id );
+ $this->mComment = $row->rev_comment;
+ $this->mUserText = $row->rev_user_text;
+ $this->mUser = intval( $row->rev_user );
+ $this->mMinorEdit = intval( $row->rev_minor_edit );
+ $this->mTimestamp = $row->rev_timestamp;
+ $this->mDeleted = intval( $row->rev_deleted );
+
+ if( isset( $row->page_latest ) ) {
+ $this->mCurrent = ( $row->rev_id == $row->page_latest );
+ $this->mTitle = Title::makeTitle( $row->page_namespace,
+ $row->page_title );
+ } else {
+ $this->mCurrent = false;
+ $this->mTitle = null;
+ }
+
+ // Lazy extraction...
+ $this->mText = null;
+ if( isset( $row->old_text ) ) {
+ $this->mTextRow = $row;
+ } else {
+ // 'text' table row entry will be lazy-loaded
+ $this->mTextRow = null;
+ }
+ } elseif( is_array( $row ) ) {
+ // Build a new revision to be saved...
+ global $wgUser;
+
+ $this->mId = isset( $row['id'] ) ? intval( $row['id'] ) : null;
+ $this->mPage = isset( $row['page'] ) ? intval( $row['page'] ) : null;
+ $this->mTextId = isset( $row['text_id'] ) ? intval( $row['text_id'] ) : null;
+ $this->mUserText = isset( $row['user_text'] ) ? strval( $row['user_text'] ) : $wgUser->getName();
+ $this->mUser = isset( $row['user'] ) ? intval( $row['user'] ) : $wgUser->getId();
+ $this->mMinorEdit = isset( $row['minor_edit'] ) ? intval( $row['minor_edit'] ) : 0;
+ $this->mTimestamp = isset( $row['timestamp'] ) ? strval( $row['timestamp'] ) : wfTimestamp( TS_MW );
+ $this->mDeleted = isset( $row['deleted'] ) ? intval( $row['deleted'] ) : 0;
+
+ // Enforce spacing trimming on supplied text
+ $this->mComment = isset( $row['comment'] ) ? trim( strval( $row['comment'] ) ) : null;
+ $this->mText = isset( $row['text'] ) ? rtrim( strval( $row['text'] ) ) : null;
+ $this->mTextRow = null;
+
+ $this->mTitle = null; # Load on demand if needed
+ $this->mCurrent = false;
+ } else {
+ throw new MWException( 'Revision constructor passed invalid row format.' );
+ }
+ }
+
+ /**#@+
+ * @access public
+ */
+
+ /**
+ * @return int
+ */
+ function getId() {
+ return $this->mId;
+ }
+
+ /**
+ * @return int
+ */
+ function getTextId() {
+ return $this->mTextId;
+ }
+
+ /**
+ * Returns the title of the page associated with this entry.
+ * @return Title
+ */
+ function getTitle() {
+ if( isset( $this->mTitle ) ) {
+ return $this->mTitle;
+ }
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow(
+ array( 'page', 'revision' ),
+ array( 'page_namespace', 'page_title' ),
+ array( 'page_id=rev_page',
+ 'rev_id' => $this->mId ),
+ 'Revision::getTitle' );
+ if( $row ) {
+ $this->mTitle = Title::makeTitle( $row->page_namespace,
+ $row->page_title );
+ }
+ return $this->mTitle;
+ }
+
+ /**
+ * Set the title of the revision
+ * @param Title $title
+ */
+ function setTitle( $title ) {
+ $this->mTitle = $title;
+ }
+
+ /**
+ * @return int
+ */
+ function getPage() {
+ return $this->mPage;
+ }
+
+ /**
+ * Fetch revision's user id if it's available to all users
+ * @return int
+ */
+ function getUser() {
+ if( $this->isDeleted( self::DELETED_USER ) ) {
+ return 0;
+ } else {
+ return $this->mUser;
+ }
+ }
+
+ /**
+ * Fetch revision's user id without regard for the current user's permissions
+ * @return string
+ */
+ function getRawUser() {
+ return $this->mUser;
+ }
+
+ /**
+ * Fetch revision's username if it's available to all users
+ * @return string
+ */
+ function getUserText() {
+ if( $this->isDeleted( self::DELETED_USER ) ) {
+ return "";
+ } else {
+ return $this->mUserText;
+ }
+ }
+
+ /**
+ * Fetch revision's username without regard for view restrictions
+ * @return string
+ */
+ function getRawUserText() {
+ return $this->mUserText;
+ }
+
+ /**
+ * Fetch revision comment if it's available to all users
+ * @return string
+ */
+ function getComment() {
+ if( $this->isDeleted( self::DELETED_COMMENT ) ) {
+ return "";
+ } else {
+ return $this->mComment;
+ }
+ }
+
+ /**
+ * Fetch revision comment without regard for the current user's permissions
+ * @return string
+ */
+ function getRawComment() {
+ return $this->mComment;
+ }
+
+ /**
+ * @return bool
+ */
+ function isMinor() {
+ return (bool)$this->mMinorEdit;
+ }
+
+ /**
+ * int $field one of DELETED_* bitfield constants
+ * @return bool
+ */
+ function isDeleted( $field ) {
+ return ($this->mDeleted & $field) == $field;
+ }
+
+ /**
+ * Fetch revision text if it's available to all users
+ * @return string
+ */
+ function getText() {
+ if( $this->isDeleted( self::DELETED_TEXT ) ) {
+ return "";
+ } else {
+ return $this->getRawText();
+ }
+ }
+
+ /**
+ * Fetch revision text without regard for view restrictions
+ * @return string
+ */
+ function getRawText() {
+ if( is_null( $this->mText ) ) {
+ // Revision text is immutable. Load on demand:
+ $this->mText = $this->loadText();
+ }
+ return $this->mText;
+ }
+
+ /**
+ * @return string
+ */
+ function getTimestamp() {
+ return wfTimestamp(TS_MW, $this->mTimestamp);
+ }
+
+ /**
+ * @return bool
+ */
+ function isCurrent() {
+ return $this->mCurrent;
+ }
+
+ /**
+ * @return Revision
+ */
+ function getPrevious() {
+ $prev = $this->mTitle->getPreviousRevisionID( $this->mId );
+ if ( $prev ) {
+ return Revision::newFromTitle( $this->mTitle, $prev );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return Revision
+ */
+ function getNext() {
+ $next = $this->mTitle->getNextRevisionID( $this->mId );
+ if ( $next ) {
+ return Revision::newFromTitle( $this->mTitle, $next );
+ } else {
+ return null;
+ }
+ }
+ /**#@-*/
+
+ /**
+ * Get revision text associated with an old or archive row
+ * $row is usually an object from wfFetchRow(), both the flags and the text
+ * field must be included
+ * @static
+ * @param integer $row Id of a row
+ * @param string $prefix table prefix (default 'old_')
+ * @return string $text|false the text requested
+ */
+ public static function getRevisionText( $row, $prefix = 'old_' ) {
+ $fname = 'Revision::getRevisionText';
+ wfProfileIn( $fname );
+
+ # Get data
+ $textField = $prefix . 'text';
+ $flagsField = $prefix . 'flags';
+
+ if( isset( $row->$flagsField ) ) {
+ $flags = explode( ',', $row->$flagsField );
+ } else {
+ $flags = array();
+ }
+
+ if( isset( $row->$textField ) ) {
+ $text = $row->$textField;
+ } else {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ # Use external methods for external objects, text in table is URL-only then
+ if ( in_array( 'external', $flags ) ) {
+ $url=$text;
+ @list(/* $proto */,$path)=explode('://',$url,2);
+ if ($path=="") {
+ wfProfileOut( $fname );
+ return false;
+ }
+ $text=ExternalStore::fetchFromURL($url);
+ }
+
+ // If the text was fetched without an error, convert it
+ if ( $text !== false ) {
+ if( in_array( 'gzip', $flags ) ) {
+ # Deal with optional compression of archived pages.
+ # This can be done periodically via maintenance/compressOld.php, and
+ # as pages are saved if $wgCompressRevisions is set.
+ $text = gzinflate( $text );
+ }
+
+ if( in_array( 'object', $flags ) ) {
+ # Generic compressed storage
+ $obj = unserialize( $text );
+ if ( !is_object( $obj ) ) {
+ // Invalid object
+ wfProfileOut( $fname );
+ return false;
+ }
+ $text = $obj->getText();
+ }
+
+ global $wgLegacyEncoding;
+ if( $wgLegacyEncoding && !in_array( 'utf-8', $flags ) ) {
+ # Old revisions kept around in a legacy encoding?
+ # Upconvert on demand.
+ global $wgInputEncoding, $wgContLang;
+ $text = $wgContLang->iconv( $wgLegacyEncoding, $wgInputEncoding . '//IGNORE', $text );
+ }
+ }
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ /**
+ * If $wgCompressRevisions is enabled, we will compress data.
+ * The input string is modified in place.
+ * Return value is the flags field: contains 'gzip' if the
+ * data is compressed, and 'utf-8' if we're saving in UTF-8
+ * mode.
+ *
+ * @static
+ * @param mixed $text reference to a text
+ * @return string
+ */
+ function compressRevisionText( &$text ) {
+ global $wgCompressRevisions;
+ $flags = array();
+
+ # Revisions not marked this way will be converted
+ # on load if $wgLegacyCharset is set in the future.
+ $flags[] = 'utf-8';
+
+ if( $wgCompressRevisions ) {
+ if( function_exists( 'gzdeflate' ) ) {
+ $text = gzdeflate( $text );
+ $flags[] = 'gzip';
+ } else {
+ wfDebug( "Revision::compressRevisionText() -- no zlib support, not compressing\n" );
+ }
+ }
+ return implode( ',', $flags );
+ }
+
+ /**
+ * Insert a new revision into the database, returning the new revision ID
+ * number on success and dies horribly on failure.
+ *
+ * @param Database $dbw
+ * @return int
+ */
+ function insertOn( &$dbw ) {
+ global $wgDefaultExternalStore;
+
+ $fname = 'Revision::insertOn';
+ wfProfileIn( $fname );
+
+ $data = $this->mText;
+ $flags = Revision::compressRevisionText( $data );
+
+ # Write to external storage if required
+ if ( $wgDefaultExternalStore ) {
+ if ( is_array( $wgDefaultExternalStore ) ) {
+ // Distribute storage across multiple clusters
+ $store = $wgDefaultExternalStore[mt_rand(0, count( $wgDefaultExternalStore ) - 1)];
+ } else {
+ $store = $wgDefaultExternalStore;
+ }
+ // Store and get the URL
+ $data = ExternalStore::insert( $store, $data );
+ if ( !$data ) {
+ # This should only happen in the case of a configuration error, where the external store is not valid
+ throw new MWException( "Unable to store text to external storage $store" );
+ }
+ if ( $flags ) {
+ $flags .= ',';
+ }
+ $flags .= 'external';
+ }
+
+ # Record the text (or external storage URL) to the text table
+ if( !isset( $this->mTextId ) ) {
+ $old_id = $dbw->nextSequenceValue( 'text_old_id_val' );
+ $dbw->insert( 'text',
+ array(
+ 'old_id' => $old_id,
+ 'old_text' => $data,
+ 'old_flags' => $flags,
+ ), $fname
+ );
+ $this->mTextId = $dbw->insertId();
+ }
+
+ # Record the edit in revisions
+ $rev_id = isset( $this->mId )
+ ? $this->mId
+ : $dbw->nextSequenceValue( 'rev_rev_id_val' );
+ $dbw->insert( 'revision',
+ array(
+ 'rev_id' => $rev_id,
+ 'rev_page' => $this->mPage,
+ 'rev_text_id' => $this->mTextId,
+ 'rev_comment' => $this->mComment,
+ 'rev_minor_edit' => $this->mMinorEdit ? 1 : 0,
+ 'rev_user' => $this->mUser,
+ 'rev_user_text' => $this->mUserText,
+ 'rev_timestamp' => $dbw->timestamp( $this->mTimestamp ),
+ 'rev_deleted' => $this->mDeleted,
+ ), $fname
+ );
+
+ $this->mId = !is_null($rev_id) ? $rev_id : $dbw->insertId();
+ wfProfileOut( $fname );
+ return $this->mId;
+ }
+
+ /**
+ * Lazy-load the revision's text.
+ * Currently hardcoded to the 'text' table storage engine.
+ *
+ * @return string
+ * @access private
+ */
+ function loadText() {
+ $fname = 'Revision::loadText';
+ wfProfileIn( $fname );
+
+ // Caching may be beneficial for massive use of external storage
+ global $wgRevisionCacheExpiry, $wgMemc;
+ $key = wfMemcKey( 'revisiontext', 'textid', $this->getTextId() );
+ if( $wgRevisionCacheExpiry ) {
+ $text = $wgMemc->get( $key );
+ if( is_string( $text ) ) {
+ wfProfileOut( $fname );
+ return $text;
+ }
+ }
+
+ // If we kept data for lazy extraction, use it now...
+ if ( isset( $this->mTextRow ) ) {
+ $row = $this->mTextRow;
+ $this->mTextRow = null;
+ } else {
+ $row = null;
+ }
+
+ if( !$row ) {
+ // Text data is immutable; check slaves first.
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow( 'text',
+ array( 'old_text', 'old_flags' ),
+ array( 'old_id' => $this->getTextId() ),
+ $fname);
+ }
+
+ if( !$row ) {
+ // Possible slave lag!
+ $dbw =& wfGetDB( DB_MASTER );
+ $row = $dbw->selectRow( 'text',
+ array( 'old_text', 'old_flags' ),
+ array( 'old_id' => $this->getTextId() ),
+ $fname);
+ }
+
+ $text = Revision::getRevisionText( $row );
+
+ if( $wgRevisionCacheExpiry ) {
+ $wgMemc->set( $key, $text, $wgRevisionCacheExpiry );
+ }
+
+ wfProfileOut( $fname );
+
+ return $text;
+ }
+
+ /**
+ * Create a new null-revision for insertion into a page's
+ * history. This will not re-save the text, but simply refer
+ * to the text from the previous version.
+ *
+ * Such revisions can for instance identify page rename
+ * operations and other such meta-modifications.
+ *
+ * @param Database $dbw
+ * @param int $pageId ID number of the page to read from
+ * @param string $summary
+ * @param bool $minor
+ * @return Revision
+ */
+ function newNullRevision( &$dbw, $pageId, $summary, $minor ) {
+ $fname = 'Revision::newNullRevision';
+ wfProfileIn( $fname );
+
+ $current = $dbw->selectRow(
+ array( 'page', 'revision' ),
+ array( 'page_latest', 'rev_text_id' ),
+ array(
+ 'page_id' => $pageId,
+ 'page_latest=rev_id',
+ ),
+ $fname );
+
+ if( $current ) {
+ $revision = new Revision( array(
+ 'page' => $pageId,
+ 'comment' => $summary,
+ 'minor_edit' => $minor,
+ 'text_id' => $current->rev_text_id,
+ ) );
+ } else {
+ $revision = null;
+ }
+
+ wfProfileOut( $fname );
+ return $revision;
+ }
+
+ /**
+ * Determine if the current user is allowed to view a particular
+ * field of this revision, if it's marked as deleted.
+ * @param int $field one of self::DELETED_TEXT,
+ * self::DELETED_COMMENT,
+ * self::DELETED_USER
+ * @return bool
+ */
+ function userCan( $field ) {
+ if( ( $this->mDeleted & $field ) == $field ) {
+ global $wgUser;
+ $permission = ( $this->mDeleted & self::DELETED_RESTRICTED ) == self::DELETED_RESTRICTED
+ ? 'hiderevision'
+ : 'deleterevision';
+ wfDebug( "Checking for $permission due to $field match on $this->mDeleted\n" );
+ return $wgUser->isAllowed( $permission );
+ } else {
+ return true;
+ }
+ }
+
+
+ /**
+ * Get rev_timestamp from rev_id, without loading the rest of the row
+ * @param integer $id
+ */
+ static function getTimestampFromID( $id ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $timestamp = $dbr->selectField( 'revision', 'rev_timestamp',
+ array( 'rev_id' => $id ), __METHOD__ );
+ if ( $timestamp === false ) {
+ # Not in slave, try master
+ $dbw =& wfGetDB( DB_MASTER );
+ $timestamp = $dbw->selectField( 'revision', 'rev_timestamp',
+ array( 'rev_id' => $id ), __METHOD__ );
+ }
+ return $timestamp;
+ }
+
+ static function countByPageId( $db, $id ) {
+ $row = $db->selectRow( 'revision', 'COUNT(*) AS revCount',
+ array( 'rev_page' => $id ), __METHOD__ );
+ if( $row ) {
+ return $row->revCount;
+ }
+ return 0;
+ }
+
+ static function countByTitle( $db, $title ) {
+ $id = $title->getArticleId();
+ if( $id ) {
+ return Revision::countByPageId( $db, $id );
+ }
+ return 0;
+ }
+}
+
+/**
+ * Aliases for backwards compatibility with 1.6
+ */
+define( 'MW_REV_DELETED_TEXT', Revision::DELETED_TEXT );
+define( 'MW_REV_DELETED_COMMENT', Revision::DELETED_COMMENT );
+define( 'MW_REV_DELETED_USER', Revision::DELETED_USER );
+define( 'MW_REV_DELETED_RESTRICTED', Revision::DELETED_RESTRICTED );
+
+
+?>
diff --git a/includes/Sanitizer.php b/includes/Sanitizer.php
new file mode 100644
index 000000000000..0c0f72444baf
--- /dev/null
+++ b/includes/Sanitizer.php
@@ -0,0 +1,1263 @@
+<?php
+/**
+ * XHTML sanitizer for MediaWiki
+ *
+ * Copyright (C) 2002-2005 Brion Vibber <brion@pobox.com> et al
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage Parser
+ */
+
+/**
+ * Regular expression to match various types of character references in
+ * Sanitizer::normalizeCharReferences and Sanitizer::decodeCharReferences
+ */
+define( 'MW_CHAR_REFS_REGEX',
+ '/&([A-Za-z0-9]+);
+ |&\#([0-9]+);
+ |&\#x([0-9A-Za-z]+);
+ |&\#X([0-9A-Za-z]+);
+ |(&)/x' );
+
+/**
+ * Regular expression to match HTML/XML attribute pairs within a tag.
+ * Allows some... latitude.
+ * Used in Sanitizer::fixTagAttributes and Sanitizer::decodeTagAttributes
+ */
+$attrib = '[A-Za-z0-9]';
+$space = '[\x09\x0a\x0d\x20]';
+define( 'MW_ATTRIBS_REGEX',
+ "/(?:^|$space)($attrib+)
+ ($space*=$space*
+ (?:
+ # The attribute value: quoted or alone
+ \"([^<\"]*)\"
+ | '([^<']*)'
+ | ([a-zA-Z0-9!#$%&()*,\\-.\\/:;<>?@[\\]^_`{|}~]+)
+ | (\#[0-9a-fA-F]+) # Technically wrong, but lots of
+ # colors are specified like this.
+ # We'll be normalizing it.
+ )
+ )?(?=$space|\$)/sx" );
+
+/**
+ * List of all named character entities defined in HTML 4.01
+ * http://www.w3.org/TR/html4/sgml/entities.html
+ * @private
+ */
+global $wgHtmlEntities;
+$wgHtmlEntities = array(
+ 'Aacute' => 193,
+ 'aacute' => 225,
+ 'Acirc' => 194,
+ 'acirc' => 226,
+ 'acute' => 180,
+ 'AElig' => 198,
+ 'aelig' => 230,
+ 'Agrave' => 192,
+ 'agrave' => 224,
+ 'alefsym' => 8501,
+ 'Alpha' => 913,
+ 'alpha' => 945,
+ 'amp' => 38,
+ 'and' => 8743,
+ 'ang' => 8736,
+ 'Aring' => 197,
+ 'aring' => 229,
+ 'asymp' => 8776,
+ 'Atilde' => 195,
+ 'atilde' => 227,
+ 'Auml' => 196,
+ 'auml' => 228,
+ 'bdquo' => 8222,
+ 'Beta' => 914,
+ 'beta' => 946,
+ 'brvbar' => 166,
+ 'bull' => 8226,
+ 'cap' => 8745,
+ 'Ccedil' => 199,
+ 'ccedil' => 231,
+ 'cedil' => 184,
+ 'cent' => 162,
+ 'Chi' => 935,
+ 'chi' => 967,
+ 'circ' => 710,
+ 'clubs' => 9827,
+ 'cong' => 8773,
+ 'copy' => 169,
+ 'crarr' => 8629,
+ 'cup' => 8746,
+ 'curren' => 164,
+ 'dagger' => 8224,
+ 'Dagger' => 8225,
+ 'darr' => 8595,
+ 'dArr' => 8659,
+ 'deg' => 176,
+ 'Delta' => 916,
+ 'delta' => 948,
+ 'diams' => 9830,
+ 'divide' => 247,
+ 'Eacute' => 201,
+ 'eacute' => 233,
+ 'Ecirc' => 202,
+ 'ecirc' => 234,
+ 'Egrave' => 200,
+ 'egrave' => 232,
+ 'empty' => 8709,
+ 'emsp' => 8195,
+ 'ensp' => 8194,
+ 'Epsilon' => 917,
+ 'epsilon' => 949,
+ 'equiv' => 8801,
+ 'Eta' => 919,
+ 'eta' => 951,
+ 'ETH' => 208,
+ 'eth' => 240,
+ 'Euml' => 203,
+ 'euml' => 235,
+ 'euro' => 8364,
+ 'exist' => 8707,
+ 'fnof' => 402,
+ 'forall' => 8704,
+ 'frac12' => 189,
+ 'frac14' => 188,
+ 'frac34' => 190,
+ 'frasl' => 8260,
+ 'Gamma' => 915,
+ 'gamma' => 947,
+ 'ge' => 8805,
+ 'gt' => 62,
+ 'harr' => 8596,
+ 'hArr' => 8660,
+ 'hearts' => 9829,
+ 'hellip' => 8230,
+ 'Iacute' => 205,
+ 'iacute' => 237,
+ 'Icirc' => 206,
+ 'icirc' => 238,
+ 'iexcl' => 161,
+ 'Igrave' => 204,
+ 'igrave' => 236,
+ 'image' => 8465,
+ 'infin' => 8734,
+ 'int' => 8747,
+ 'Iota' => 921,
+ 'iota' => 953,
+ 'iquest' => 191,
+ 'isin' => 8712,
+ 'Iuml' => 207,
+ 'iuml' => 239,
+ 'Kappa' => 922,
+ 'kappa' => 954,
+ 'Lambda' => 923,
+ 'lambda' => 955,
+ 'lang' => 9001,
+ 'laquo' => 171,
+ 'larr' => 8592,
+ 'lArr' => 8656,
+ 'lceil' => 8968,
+ 'ldquo' => 8220,
+ 'le' => 8804,
+ 'lfloor' => 8970,
+ 'lowast' => 8727,
+ 'loz' => 9674,
+ 'lrm' => 8206,
+ 'lsaquo' => 8249,
+ 'lsquo' => 8216,
+ 'lt' => 60,
+ 'macr' => 175,
+ 'mdash' => 8212,
+ 'micro' => 181,
+ 'middot' => 183,
+ 'minus' => 8722,
+ 'Mu' => 924,
+ 'mu' => 956,
+ 'nabla' => 8711,
+ 'nbsp' => 160,
+ 'ndash' => 8211,
+ 'ne' => 8800,
+ 'ni' => 8715,
+ 'not' => 172,
+ 'notin' => 8713,
+ 'nsub' => 8836,
+ 'Ntilde' => 209,
+ 'ntilde' => 241,
+ 'Nu' => 925,
+ 'nu' => 957,
+ 'Oacute' => 211,
+ 'oacute' => 243,
+ 'Ocirc' => 212,
+ 'ocirc' => 244,
+ 'OElig' => 338,
+ 'oelig' => 339,
+ 'Ograve' => 210,
+ 'ograve' => 242,
+ 'oline' => 8254,
+ 'Omega' => 937,
+ 'omega' => 969,
+ 'Omicron' => 927,
+ 'omicron' => 959,
+ 'oplus' => 8853,
+ 'or' => 8744,
+ 'ordf' => 170,
+ 'ordm' => 186,
+ 'Oslash' => 216,
+ 'oslash' => 248,
+ 'Otilde' => 213,
+ 'otilde' => 245,
+ 'otimes' => 8855,
+ 'Ouml' => 214,
+ 'ouml' => 246,
+ 'para' => 182,
+ 'part' => 8706,
+ 'permil' => 8240,
+ 'perp' => 8869,
+ 'Phi' => 934,
+ 'phi' => 966,
+ 'Pi' => 928,
+ 'pi' => 960,
+ 'piv' => 982,
+ 'plusmn' => 177,
+ 'pound' => 163,
+ 'prime' => 8242,
+ 'Prime' => 8243,
+ 'prod' => 8719,
+ 'prop' => 8733,
+ 'Psi' => 936,
+ 'psi' => 968,
+ 'quot' => 34,
+ 'radic' => 8730,
+ 'rang' => 9002,
+ 'raquo' => 187,
+ 'rarr' => 8594,
+ 'rArr' => 8658,
+ 'rceil' => 8969,
+ 'rdquo' => 8221,
+ 'real' => 8476,
+ 'reg' => 174,
+ 'rfloor' => 8971,
+ 'Rho' => 929,
+ 'rho' => 961,
+ 'rlm' => 8207,
+ 'rsaquo' => 8250,
+ 'rsquo' => 8217,
+ 'sbquo' => 8218,
+ 'Scaron' => 352,
+ 'scaron' => 353,
+ 'sdot' => 8901,
+ 'sect' => 167,
+ 'shy' => 173,
+ 'Sigma' => 931,
+ 'sigma' => 963,
+ 'sigmaf' => 962,
+ 'sim' => 8764,
+ 'spades' => 9824,
+ 'sub' => 8834,
+ 'sube' => 8838,
+ 'sum' => 8721,
+ 'sup' => 8835,
+ 'sup1' => 185,
+ 'sup2' => 178,
+ 'sup3' => 179,
+ 'supe' => 8839,
+ 'szlig' => 223,
+ 'Tau' => 932,
+ 'tau' => 964,
+ 'there4' => 8756,
+ 'Theta' => 920,
+ 'theta' => 952,
+ 'thetasym' => 977,
+ 'thinsp' => 8201,
+ 'THORN' => 222,
+ 'thorn' => 254,
+ 'tilde' => 732,
+ 'times' => 215,
+ 'trade' => 8482,
+ 'Uacute' => 218,
+ 'uacute' => 250,
+ 'uarr' => 8593,
+ 'uArr' => 8657,
+ 'Ucirc' => 219,
+ 'ucirc' => 251,
+ 'Ugrave' => 217,
+ 'ugrave' => 249,
+ 'uml' => 168,
+ 'upsih' => 978,
+ 'Upsilon' => 933,
+ 'upsilon' => 965,
+ 'Uuml' => 220,
+ 'uuml' => 252,
+ 'weierp' => 8472,
+ 'Xi' => 926,
+ 'xi' => 958,
+ 'Yacute' => 221,
+ 'yacute' => 253,
+ 'yen' => 165,
+ 'Yuml' => 376,
+ 'yuml' => 255,
+ 'Zeta' => 918,
+ 'zeta' => 950,
+ 'zwj' => 8205,
+ 'zwnj' => 8204 );
+
+/** @package MediaWiki */
+class Sanitizer {
+ /**
+ * Cleans up HTML, removes dangerous tags and attributes, and
+ * removes HTML comments
+ * @private
+ * @param string $text
+ * @param callback $processCallback to do any variable or parameter replacements in HTML attribute values
+ * @param array $args for the processing callback
+ * @return string
+ */
+ static function removeHTMLtags( $text, $processCallback = null, $args = array() ) {
+ global $wgUseTidy, $wgUserHtml;
+
+ static $htmlpairs, $htmlsingle, $htmlsingleonly, $htmlnest, $tabletags,
+ $htmllist, $listtags, $htmlsingleallowed, $htmlelements, $staticInitialised;
+
+ wfProfileIn( __METHOD__ );
+
+ if ( !$staticInitialised ) {
+ if( $wgUserHtml ) {
+ $htmlpairs = array( # Tags that must be closed
+ 'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1',
+ 'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's',
+ 'strike', 'strong', 'tt', 'var', 'div', 'center',
+ 'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
+ 'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'u'
+ );
+ $htmlsingle = array(
+ 'br', 'hr', 'li', 'dt', 'dd'
+ );
+ $htmlsingleonly = array( # Elements that cannot have close tags
+ 'br', 'hr'
+ );
+ $htmlnest = array( # Tags that can be nested--??
+ 'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul',
+ 'dl', 'font', 'big', 'small', 'sub', 'sup', 'span'
+ );
+ $tabletags = array( # Can only appear inside table
+ 'td', 'th', 'tr',
+ );
+ $htmllist = array( # Tags used by list
+ 'ul','ol',
+ );
+ $listtags = array( # Tags that can appear in a list
+ 'li',
+ );
+
+ } else {
+ $htmlpairs = array();
+ $htmlsingle = array();
+ $htmlnest = array();
+ $tabletags = array();
+ }
+
+ $htmlsingleallowed = array_merge( $htmlsingle, $tabletags );
+ $htmlelements = array_merge( $htmlsingle, $htmlpairs, $htmlnest );
+
+ # Convert them all to hashtables for faster lookup
+ $vars = array( 'htmlpairs', 'htmlsingle', 'htmlsingleonly', 'htmlnest', 'tabletags',
+ 'htmllist', 'listtags', 'htmlsingleallowed', 'htmlelements' );
+ foreach ( $vars as $var ) {
+ $$var = array_flip( $$var );
+ }
+ $staticInitialised = true;
+ }
+
+ # Remove HTML comments
+ $text = Sanitizer::removeHTMLcomments( $text );
+ $bits = explode( '<', $text );
+ $text = array_shift( $bits );
+ if(!$wgUseTidy) {
+ $tagstack = $tablestack = array();
+ foreach ( $bits as $x ) {
+ $regs = array();
+ if( preg_match( '!^(/?)(\\w+)([^>]*?)(/{0,1}>)([^<]*)$!', $x, $regs ) ) {
+ list( /* $qbar */, $slash, $t, $params, $brace, $rest ) = $regs;
+ } else {
+ $slash = $t = $params = $brace = $rest = null;
+ }
+
+ $badtag = 0 ;
+ if ( isset( $htmlelements[$t = strtolower( $t )] ) ) {
+ # Check our stack
+ if ( $slash ) {
+ # Closing a tag...
+ if( isset( $htmlsingleonly[$t] ) ) {
+ $badtag = 1;
+ } elseif ( ( $ot = @array_pop( $tagstack ) ) != $t ) {
+ if ( isset( $htmlsingleallowed[$ot] ) ) {
+ # Pop all elements with an optional close tag
+ # and see if we find a match below them
+ $optstack = array();
+ array_push ($optstack, $ot);
+ while ( ( ( $ot = @array_pop( $tagstack ) ) != $t ) &&
+ isset( $htmlsingleallowed[$ot] ) )
+ {
+ array_push ($optstack, $ot);
+ }
+ if ( $t != $ot ) {
+ # No match. Push the optinal elements back again
+ $badtag = 1;
+ while ( $ot = @array_pop( $optstack ) ) {
+ array_push( $tagstack, $ot );
+ }
+ }
+ } else {
+ @array_push( $tagstack, $ot );
+ # <li> can be nested in <ul> or <ol>, skip those cases:
+ if(!(isset( $htmllist[$ot] ) && isset( $listtags[$t] ) )) {
+ $badtag = 1;
+ }
+ }
+ } else {
+ if ( $t == 'table' ) {
+ $tagstack = array_pop( $tablestack );
+ }
+ }
+ $newparams = '';
+ } else {
+ # Keep track for later
+ if ( isset( $tabletags[$t] ) &&
+ ! in_array( 'table', $tagstack ) ) {
+ $badtag = 1;
+ } else if ( in_array( $t, $tagstack ) &&
+ ! isset( $htmlnest [$t ] ) ) {
+ $badtag = 1 ;
+ # Is it a self closed htmlpair ? (bug 5487)
+ } else if( $brace == '/>' &&
+ isset( $htmlpairs[$t] ) ) {
+ $badtag = 1;
+ } elseif( isset( $htmlsingleonly[$t] ) ) {
+ # Hack to force empty tag for uncloseable elements
+ $brace = '/>';
+ } else if( isset( $htmlsingle[$t] ) ) {
+ # Hack to not close $htmlsingle tags
+ $brace = NULL;
+ } else {
+ if ( $t == 'table' ) {
+ array_push( $tablestack, $tagstack );
+ $tagstack = array();
+ }
+ array_push( $tagstack, $t );
+ }
+
+ # Replace any variables or template parameters with
+ # plaintext results.
+ if( is_callable( $processCallback ) ) {
+ call_user_func_array( $processCallback, array( &$params, $args ) );
+ }
+
+ # Strip non-approved attributes from the tag
+ $newparams = Sanitizer::fixTagAttributes( $params, $t );
+ }
+ if ( ! $badtag ) {
+ $rest = str_replace( '>', '&gt;', $rest );
+ $close = ( $brace == '/>' ) ? ' /' : '';
+ $text .= "<$slash$t$newparams$close>$rest";
+ continue;
+ }
+ }
+ $text .= '&lt;' . str_replace( '>', '&gt;', $x);
+ }
+ # Close off any remaining tags
+ while ( is_array( $tagstack ) && ($t = array_pop( $tagstack )) ) {
+ $text .= "</$t>\n";
+ if ( $t == 'table' ) { $tagstack = array_pop( $tablestack ); }
+ }
+ } else {
+ # this might be possible using tidy itself
+ foreach ( $bits as $x ) {
+ preg_match( '/^(\\/?)(\\w+)([^>]*?)(\\/{0,1}>)([^<]*)$/',
+ $x, $regs );
+ @list( /* $qbar */, $slash, $t, $params, $brace, $rest ) = $regs;
+ if ( isset( $htmlelements[$t = strtolower( $t )] ) ) {
+ if( is_callable( $processCallback ) ) {
+ call_user_func_array( $processCallback, array( &$params, $args ) );
+ }
+ $newparams = Sanitizer::fixTagAttributes( $params, $t );
+ $rest = str_replace( '>', '&gt;', $rest );
+ $text .= "<$slash$t$newparams$brace$rest";
+ } else {
+ $text .= '&lt;' . str_replace( '>', '&gt;', $x);
+ }
+ }
+ }
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * Remove '<!--', '-->', and everything between.
+ * To avoid leaving blank lines, when a comment is both preceded
+ * and followed by a newline (ignoring spaces), trim leading and
+ * trailing spaces and one of the newlines.
+ *
+ * @private
+ * @param string $text
+ * @return string
+ */
+ static function removeHTMLcomments( $text ) {
+ wfProfileIn( __METHOD__ );
+ while (($start = strpos($text, '<!--')) !== false) {
+ $end = strpos($text, '-->', $start + 4);
+ if ($end === false) {
+ # Unterminated comment; bail out
+ break;
+ }
+
+ $end += 3;
+
+ # Trim space and newline if the comment is both
+ # preceded and followed by a newline
+ $spaceStart = max($start - 1, 0);
+ $spaceLen = $end - $spaceStart;
+ while (substr($text, $spaceStart, 1) === ' ' && $spaceStart > 0) {
+ $spaceStart--;
+ $spaceLen++;
+ }
+ while (substr($text, $spaceStart + $spaceLen, 1) === ' ')
+ $spaceLen++;
+ if (substr($text, $spaceStart, 1) === "\n" and substr($text, $spaceStart + $spaceLen, 1) === "\n") {
+ # Remove the comment, leading and trailing
+ # spaces, and leave only one newline.
+ $text = substr_replace($text, "\n", $spaceStart, $spaceLen + 1);
+ }
+ else {
+ # Remove just the comment.
+ $text = substr_replace($text, '', $start, $end - $start);
+ }
+ }
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * Take an array of attribute names and values and normalize or discard
+ * illegal values for the given element type.
+ *
+ * - Discards attributes not on a whitelist for the given element
+ * - Unsafe style attributes are discarded
+ *
+ * @param array $attribs
+ * @param string $element
+ * @return array
+ *
+ * @todo Check for legal values where the DTD limits things.
+ * @todo Check for unique id attribute :P
+ */
+ static function validateTagAttributes( $attribs, $element ) {
+ $whitelist = array_flip( Sanitizer::attributeWhitelist( $element ) );
+ $out = array();
+ foreach( $attribs as $attribute => $value ) {
+ if( !isset( $whitelist[$attribute] ) ) {
+ continue;
+ }
+ # Strip javascript "expression" from stylesheets.
+ # http://msdn.microsoft.com/workshop/author/dhtml/overview/recalc.asp
+ if( $attribute == 'style' ) {
+ $value = Sanitizer::checkCss( $value );
+ if( $value === false ) {
+ # haxx0r
+ continue;
+ }
+ }
+
+ if ( $attribute === 'id' )
+ $value = Sanitizer::escapeId( $value );
+
+ // If this attribute was previously set, override it.
+ // Output should only have one attribute of each name.
+ $out[$attribute] = $value;
+ }
+ return $out;
+ }
+
+ /**
+ * Pick apart some CSS and check it for forbidden or unsafe structures.
+ * Returns a sanitized string, or false if it was just too evil.
+ *
+ * Currently URL references, 'expression', 'tps' are forbidden.
+ *
+ * @param string $value
+ * @return mixed
+ */
+ static function checkCss( $value ) {
+ $stripped = Sanitizer::decodeCharReferences( $value );
+
+ // Remove any comments; IE gets token splitting wrong
+ $stripped = StringUtils::delimiterReplace( '/*', '*/', ' ', $stripped );
+
+ $value = $stripped;
+
+ // ... and continue checks
+ $stripped = preg_replace( '!\\\\([0-9A-Fa-f]{1,6})[ \\n\\r\\t\\f]?!e',
+ 'codepointToUtf8(hexdec("$1"))', $stripped );
+ $stripped = str_replace( '\\', '', $stripped );
+ if( preg_match( '/(expression|tps*:\/\/|url\\s*\().*/is',
+ $stripped ) ) {
+ # haxx0r
+ return false;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Take a tag soup fragment listing an HTML element's attributes
+ * and normalize it to well-formed XML, discarding unwanted attributes.
+ * Output is safe for further wikitext processing, with escaping of
+ * values that could trigger problems.
+ *
+ * - Normalizes attribute names to lowercase
+ * - Discards attributes not on a whitelist for the given element
+ * - Turns broken or invalid entities into plaintext
+ * - Double-quotes all attribute values
+ * - Attributes without values are given the name as attribute
+ * - Double attributes are discarded
+ * - Unsafe style attributes are discarded
+ * - Prepends space if there are attributes.
+ *
+ * @param string $text
+ * @param string $element
+ * @return string
+ */
+ static function fixTagAttributes( $text, $element ) {
+ if( trim( $text ) == '' ) {
+ return '';
+ }
+
+ $stripped = Sanitizer::validateTagAttributes(
+ Sanitizer::decodeTagAttributes( $text ), $element );
+
+ $attribs = array();
+ foreach( $stripped as $attribute => $value ) {
+ $encAttribute = htmlspecialchars( $attribute );
+ $encValue = Sanitizer::safeEncodeAttribute( $value );
+
+ $attribs[] = "$encAttribute=\"$encValue\"";
+ }
+ return count( $attribs ) ? ' ' . implode( ' ', $attribs ) : '';
+ }
+
+ /**
+ * Encode an attribute value for HTML output.
+ * @param $text
+ * @return HTML-encoded text fragment
+ */
+ static function encodeAttribute( $text ) {
+ $encValue = htmlspecialchars( $text );
+
+ // Whitespace is normalized during attribute decoding,
+ // so if we've been passed non-spaces we must encode them
+ // ahead of time or they won't be preserved.
+ $encValue = strtr( $encValue, array(
+ "\n" => '&#10;',
+ "\r" => '&#13;',
+ "\t" => '&#9;',
+ ) );
+
+ return $encValue;
+ }
+
+ /**
+ * Encode an attribute value for HTML tags, with extra armoring
+ * against further wiki processing.
+ * @param $text
+ * @return HTML-encoded text fragment
+ */
+ static function safeEncodeAttribute( $text ) {
+ $encValue = Sanitizer::encodeAttribute( $text );
+
+ # Templates and links may be expanded in later parsing,
+ # creating invalid or dangerous output. Suppress this.
+ $encValue = strtr( $encValue, array(
+ '<' => '&lt;', // This should never happen,
+ '>' => '&gt;', // we've received invalid input
+ '"' => '&quot;', // which should have been escaped.
+ '{' => '&#123;',
+ '[' => '&#91;',
+ "''" => '&#39;&#39;',
+ 'ISBN' => '&#73;SBN',
+ 'RFC' => '&#82;FC',
+ 'PMID' => '&#80;MID',
+ '|' => '&#124;',
+ '__' => '&#95;_',
+ ) );
+
+ # Stupid hack
+ $encValue = preg_replace_callback(
+ '/(' . wfUrlProtocols() . ')/',
+ array( 'Sanitizer', 'armorLinksCallback' ),
+ $encValue );
+ return $encValue;
+ }
+
+ /**
+ * Given a value escape it so that it can be used in an id attribute and
+ * return it, this does not validate the value however (see first link)
+ *
+ * @link http://www.w3.org/TR/html401/types.html#type-name Valid characters
+ * in the id and
+ * name attributes
+ * @link http://www.w3.org/TR/html401/struct/links.html#h-12.2.3 Anchors with the id attribute
+ *
+ * @bug 4461
+ *
+ * @static
+ *
+ * @param string $id
+ * @return string
+ */
+ static function escapeId( $id ) {
+ static $replace = array(
+ '%3A' => ':',
+ '%' => '.'
+ );
+
+ $id = urlencode( Sanitizer::decodeCharReferences( strtr( $id, ' ', '_' ) ) );
+
+ return str_replace( array_keys( $replace ), array_values( $replace ), $id );
+ }
+
+ /**
+ * Given a value, escape it so that it can be used as a CSS class and
+ * return it.
+ *
+ * TODO: For extra validity, input should be validated UTF-8.
+ *
+ * @link http://www.w3.org/TR/CSS21/syndata.html Valid characters/format
+ *
+ * @param string $class
+ * @return string
+ */
+ static function escapeClass( $class ) {
+ // Convert ugly stuff to underscores and kill underscores in ugly places
+ return rtrim(preg_replace(
+ array('/(^[0-9\\-])|[\\x00-\\x20!"#$%&\'()*+,.\\/:;<=>?@[\\]^`{|}~]|\\xC2\\xA0/','/_+/'),
+ '_',
+ $class ), '_');
+ }
+
+ /**
+ * Regex replace callback for armoring links against further processing.
+ * @param array $matches
+ * @return string
+ * @private
+ */
+ private static function armorLinksCallback( $matches ) {
+ return str_replace( ':', '&#58;', $matches[1] );
+ }
+
+ /**
+ * Return an associative array of attribute names and values from
+ * a partial tag string. Attribute names are forces to lowercase,
+ * character references are decoded to UTF-8 text.
+ *
+ * @param string
+ * @return array
+ */
+ static function decodeTagAttributes( $text ) {
+ $attribs = array();
+
+ if( trim( $text ) == '' ) {
+ return $attribs;
+ }
+
+ $pairs = array();
+ if( !preg_match_all(
+ MW_ATTRIBS_REGEX,
+ $text,
+ $pairs,
+ PREG_SET_ORDER ) ) {
+ return $attribs;
+ }
+
+ foreach( $pairs as $set ) {
+ $attribute = strtolower( $set[1] );
+ $value = Sanitizer::getTagAttributeCallback( $set );
+
+ // Normalize whitespace
+ $value = preg_replace( '/[\t\r\n ]+/', ' ', $value );
+ $value = trim( $value );
+
+ // Decode character references
+ $attribs[$attribute] = Sanitizer::decodeCharReferences( $value );
+ }
+ return $attribs;
+ }
+
+ /**
+ * Pick the appropriate attribute value from a match set from the
+ * MW_ATTRIBS_REGEX matches.
+ *
+ * @param array $set
+ * @return string
+ * @private
+ */
+ private static function getTagAttributeCallback( $set ) {
+ if( isset( $set[6] ) ) {
+ # Illegal #XXXXXX color with no quotes.
+ return $set[6];
+ } elseif( isset( $set[5] ) ) {
+ # No quotes.
+ return $set[5];
+ } elseif( isset( $set[4] ) ) {
+ # Single-quoted
+ return $set[4];
+ } elseif( isset( $set[3] ) ) {
+ # Double-quoted
+ return $set[3];
+ } elseif( !isset( $set[2] ) ) {
+ # In XHTML, attributes must have a value.
+ # For 'reduced' form, return explicitly the attribute name here.
+ return $set[1];
+ } else {
+ throw new MWException( "Tag conditions not met. This should never happen and is a bug." );
+ }
+ }
+
+ /**
+ * Normalize whitespace and character references in an XML source-
+ * encoded text for an attribute value.
+ *
+ * See http://www.w3.org/TR/REC-xml/#AVNormalize for background,
+ * but note that we're not returning the value, but are returning
+ * XML source fragments that will be slapped into output.
+ *
+ * @param string $text
+ * @return string
+ * @private
+ */
+ private static function normalizeAttributeValue( $text ) {
+ return str_replace( '"', '&quot;',
+ preg_replace(
+ '/\r\n|[\x20\x0d\x0a\x09]/',
+ ' ',
+ Sanitizer::normalizeCharReferences( $text ) ) );
+ }
+
+ /**
+ * Ensure that any entities and character references are legal
+ * for XML and XHTML specifically. Any stray bits will be
+ * &amp;-escaped to result in a valid text fragment.
+ *
+ * a. any named char refs must be known in XHTML
+ * b. any numeric char refs must be legal chars, not invalid or forbidden
+ * c. use &#x, not &#X
+ * d. fix or reject non-valid attributes
+ *
+ * @param string $text
+ * @return string
+ * @private
+ */
+ static function normalizeCharReferences( $text ) {
+ return preg_replace_callback(
+ MW_CHAR_REFS_REGEX,
+ array( 'Sanitizer', 'normalizeCharReferencesCallback' ),
+ $text );
+ }
+ /**
+ * @param string $matches
+ * @return string
+ */
+ static function normalizeCharReferencesCallback( $matches ) {
+ $ret = null;
+ if( $matches[1] != '' ) {
+ $ret = Sanitizer::normalizeEntity( $matches[1] );
+ } elseif( $matches[2] != '' ) {
+ $ret = Sanitizer::decCharReference( $matches[2] );
+ } elseif( $matches[3] != '' ) {
+ $ret = Sanitizer::hexCharReference( $matches[3] );
+ } elseif( $matches[4] != '' ) {
+ $ret = Sanitizer::hexCharReference( $matches[4] );
+ }
+ if( is_null( $ret ) ) {
+ return htmlspecialchars( $matches[0] );
+ } else {
+ return $ret;
+ }
+ }
+
+ /**
+ * If the named entity is defined in the HTML 4.0/XHTML 1.0 DTD,
+ * return the named entity reference as is. Otherwise, returns
+ * HTML-escaped text of pseudo-entity source (eg &amp;foo;)
+ *
+ * @param string $name
+ * @return string
+ * @static
+ */
+ static function normalizeEntity( $name ) {
+ global $wgHtmlEntities;
+ if( isset( $wgHtmlEntities[$name] ) ) {
+ return "&$name;";
+ } else {
+ return "&amp;$name;";
+ }
+ }
+
+ static function decCharReference( $codepoint ) {
+ $point = intval( $codepoint );
+ if( Sanitizer::validateCodepoint( $point ) ) {
+ return sprintf( '&#%d;', $point );
+ } else {
+ return null;
+ }
+ }
+
+ static function hexCharReference( $codepoint ) {
+ $point = hexdec( $codepoint );
+ if( Sanitizer::validateCodepoint( $point ) ) {
+ return sprintf( '&#x%x;', $point );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns true if a given Unicode codepoint is a valid character in XML.
+ * @param int $codepoint
+ * @return bool
+ */
+ private static function validateCodepoint( $codepoint ) {
+ return ($codepoint == 0x09)
+ || ($codepoint == 0x0a)
+ || ($codepoint == 0x0d)
+ || ($codepoint >= 0x20 && $codepoint <= 0xd7ff)
+ || ($codepoint >= 0xe000 && $codepoint <= 0xfffd)
+ || ($codepoint >= 0x10000 && $codepoint <= 0x10ffff);
+ }
+
+ /**
+ * Decode any character references, numeric or named entities,
+ * in the text and return a UTF-8 string.
+ *
+ * @param string $text
+ * @return string
+ * @public
+ * @static
+ */
+ public static function decodeCharReferences( $text ) {
+ return preg_replace_callback(
+ MW_CHAR_REFS_REGEX,
+ array( 'Sanitizer', 'decodeCharReferencesCallback' ),
+ $text );
+ }
+
+ /**
+ * @param string $matches
+ * @return string
+ */
+ static function decodeCharReferencesCallback( $matches ) {
+ if( $matches[1] != '' ) {
+ return Sanitizer::decodeEntity( $matches[1] );
+ } elseif( $matches[2] != '' ) {
+ return Sanitizer::decodeChar( intval( $matches[2] ) );
+ } elseif( $matches[3] != '' ) {
+ return Sanitizer::decodeChar( hexdec( $matches[3] ) );
+ } elseif( $matches[4] != '' ) {
+ return Sanitizer::decodeChar( hexdec( $matches[4] ) );
+ }
+ # Last case should be an ampersand by itself
+ return $matches[0];
+ }
+
+ /**
+ * Return UTF-8 string for a codepoint if that is a valid
+ * character reference, otherwise U+FFFD REPLACEMENT CHARACTER.
+ * @param int $codepoint
+ * @return string
+ * @private
+ */
+ static function decodeChar( $codepoint ) {
+ if( Sanitizer::validateCodepoint( $codepoint ) ) {
+ return codepointToUtf8( $codepoint );
+ } else {
+ return UTF8_REPLACEMENT;
+ }
+ }
+
+ /**
+ * If the named entity is defined in the HTML 4.0/XHTML 1.0 DTD,
+ * return the UTF-8 encoding of that character. Otherwise, returns
+ * pseudo-entity source (eg &foo;)
+ *
+ * @param string $name
+ * @return string
+ */
+ static function decodeEntity( $name ) {
+ global $wgHtmlEntities;
+ if( isset( $wgHtmlEntities[$name] ) ) {
+ return codepointToUtf8( $wgHtmlEntities[$name] );
+ } else {
+ return "&$name;";
+ }
+ }
+
+ /**
+ * Fetch the whitelist of acceptable attributes for a given
+ * element name.
+ *
+ * @param string $element
+ * @return array
+ */
+ static function attributeWhitelist( $element ) {
+ static $list;
+ if( !isset( $list ) ) {
+ $list = Sanitizer::setupAttributeWhitelist();
+ }
+ return isset( $list[$element] )
+ ? $list[$element]
+ : array();
+ }
+
+ /**
+ * @todo Document it a bit
+ * @return array
+ */
+ static function setupAttributeWhitelist() {
+ $common = array( 'id', 'class', 'lang', 'dir', 'title', 'style' );
+ $block = array_merge( $common, array( 'align' ) );
+ $tablealign = array( 'align', 'char', 'charoff', 'valign' );
+ $tablecell = array( 'abbr',
+ 'axis',
+ 'headers',
+ 'scope',
+ 'rowspan',
+ 'colspan',
+ 'nowrap', # deprecated
+ 'width', # deprecated
+ 'height', # deprecated
+ 'bgcolor' # deprecated
+ );
+
+ # Numbers refer to sections in HTML 4.01 standard describing the element.
+ # See: http://www.w3.org/TR/html4/
+ $whitelist = array (
+ # 7.5.4
+ 'div' => $block,
+ 'center' => $common, # deprecated
+ 'span' => $block, # ??
+
+ # 7.5.5
+ 'h1' => $block,
+ 'h2' => $block,
+ 'h3' => $block,
+ 'h4' => $block,
+ 'h5' => $block,
+ 'h6' => $block,
+
+ # 7.5.6
+ # address
+
+ # 8.2.4
+ # bdo
+
+ # 9.2.1
+ 'em' => $common,
+ 'strong' => $common,
+ 'cite' => $common,
+ # dfn
+ 'code' => $common,
+ # samp
+ # kbd
+ 'var' => $common,
+ # abbr
+ # acronym
+
+ # 9.2.2
+ 'blockquote' => array_merge( $common, array( 'cite' ) ),
+ # q
+
+ # 9.2.3
+ 'sub' => $common,
+ 'sup' => $common,
+
+ # 9.3.1
+ 'p' => $block,
+
+ # 9.3.2
+ 'br' => array( 'id', 'class', 'title', 'style', 'clear' ),
+
+ # 9.3.4
+ 'pre' => array_merge( $common, array( 'width' ) ),
+
+ # 9.4
+ 'ins' => array_merge( $common, array( 'cite', 'datetime' ) ),
+ 'del' => array_merge( $common, array( 'cite', 'datetime' ) ),
+
+ # 10.2
+ 'ul' => array_merge( $common, array( 'type' ) ),
+ 'ol' => array_merge( $common, array( 'type', 'start' ) ),
+ 'li' => array_merge( $common, array( 'type', 'value' ) ),
+
+ # 10.3
+ 'dl' => $common,
+ 'dd' => $common,
+ 'dt' => $common,
+
+ # 11.2.1
+ 'table' => array_merge( $common,
+ array( 'summary', 'width', 'border', 'frame',
+ 'rules', 'cellspacing', 'cellpadding',
+ 'align', 'bgcolor',
+ ) ),
+
+ # 11.2.2
+ 'caption' => array_merge( $common, array( 'align' ) ),
+
+ # 11.2.3
+ 'thead' => array_merge( $common, $tablealign ),
+ 'tfoot' => array_merge( $common, $tablealign ),
+ 'tbody' => array_merge( $common, $tablealign ),
+
+ # 11.2.4
+ 'colgroup' => array_merge( $common, array( 'span', 'width' ), $tablealign ),
+ 'col' => array_merge( $common, array( 'span', 'width' ), $tablealign ),
+
+ # 11.2.5
+ 'tr' => array_merge( $common, array( 'bgcolor' ), $tablealign ),
+
+ # 11.2.6
+ 'td' => array_merge( $common, $tablecell, $tablealign ),
+ 'th' => array_merge( $common, $tablecell, $tablealign ),
+
+ # 15.2.1
+ 'tt' => $common,
+ 'b' => $common,
+ 'i' => $common,
+ 'big' => $common,
+ 'small' => $common,
+ 'strike' => $common,
+ 's' => $common,
+ 'u' => $common,
+
+ # 15.2.2
+ 'font' => array_merge( $common, array( 'size', 'color', 'face' ) ),
+ # basefont
+
+ # 15.3
+ 'hr' => array_merge( $common, array( 'noshade', 'size', 'width' ) ),
+
+ # XHTML Ruby annotation text module, simple ruby only.
+ # http://www.w3c.org/TR/ruby/
+ 'ruby' => $common,
+ # rbc
+ # rtc
+ 'rb' => $common,
+ 'rt' => $common, #array_merge( $common, array( 'rbspan' ) ),
+ 'rp' => $common,
+ );
+ return $whitelist;
+ }
+
+ /**
+ * Take a fragment of (potentially invalid) HTML and return
+ * a version with any tags removed, encoded suitably for literal
+ * inclusion in an attribute value.
+ *
+ * @param string $text HTML fragment
+ * @return string
+ */
+ static function stripAllTags( $text ) {
+ # Actual <tags>
+ $text = StringUtils::delimiterReplace( '<', '>', '', $text );
+
+ # Normalize &entities and whitespace
+ $text = Sanitizer::normalizeAttributeValue( $text );
+
+ # Will be placed into "double-quoted" attributes,
+ # make sure remaining bits are safe.
+ $text = str_replace(
+ array('<', '>', '"'),
+ array('&lt;', '&gt;', '&quot;'),
+ $text );
+
+ return $text;
+ }
+
+ /**
+ * Hack up a private DOCTYPE with HTML's standard entity declarations.
+ * PHP 4 seemed to know these if you gave it an HTML doctype, but
+ * PHP 5.1 doesn't.
+ *
+ * Use for passing XHTML fragments to PHP's XML parsing functions
+ *
+ * @return string
+ * @static
+ */
+ static function hackDocType() {
+ global $wgHtmlEntities;
+ $out = "<!DOCTYPE html [\n";
+ foreach( $wgHtmlEntities as $entity => $codepoint ) {
+ $out .= "<!ENTITY $entity \"&#$codepoint;\">";
+ }
+ $out .= "]>\n";
+ return $out;
+ }
+
+ static function cleanUrl( $url, $hostname=true ) {
+ # Normalize any HTML entities in input. They will be
+ # re-escaped by makeExternalLink().
+ $url = Sanitizer::decodeCharReferences( $url );
+
+ # Escape any control characters introduced by the above step
+ $url = preg_replace( '/[\][<>"\\x00-\\x20\\x7F]/e', "urlencode('\\0')", $url );
+
+ # Validate hostname portion
+ $matches = array();
+ if( preg_match( '!^([^:]+:)(//[^/]+)?(.*)$!iD', $url, $matches ) ) {
+ list( /* $whole */, $protocol, $host, $rest ) = $matches;
+
+ // Characters that will be ignored in IDNs.
+ // http://tools.ietf.org/html/3454#section-3.1
+ // Strip them before further processing so blacklists and such work.
+ $strip = "/
+ \\s| # general whitespace
+ \xc2\xad| # 00ad SOFT HYPHEN
+ \xe1\xa0\x86| # 1806 MONGOLIAN TODO SOFT HYPHEN
+ \xe2\x80\x8b| # 200b ZERO WIDTH SPACE
+ \xe2\x81\xa0| # 2060 WORD JOINER
+ \xef\xbb\xbf| # feff ZERO WIDTH NO-BREAK SPACE
+ \xcd\x8f| # 034f COMBINING GRAPHEME JOINER
+ \xe1\xa0\x8b| # 180b MONGOLIAN FREE VARIATION SELECTOR ONE
+ \xe1\xa0\x8c| # 180c MONGOLIAN FREE VARIATION SELECTOR TWO
+ \xe1\xa0\x8d| # 180d MONGOLIAN FREE VARIATION SELECTOR THREE
+ \xe2\x80\x8c| # 200c ZERO WIDTH NON-JOINER
+ \xe2\x80\x8d| # 200d ZERO WIDTH JOINER
+ [\xef\xb8\x80-\xef\xb8\x8f] # fe00-fe00f VARIATION SELECTOR-1-16
+ /xuD";
+
+ $host = preg_replace( $strip, '', $host );
+
+ // @fixme: validate hostnames here
+
+ return $protocol . $host . $rest;
+ } else {
+ return $url;
+ }
+ }
+
+}
+
+?>
diff --git a/includes/SearchEngine.php b/includes/SearchEngine.php
new file mode 100644
index 000000000000..cec40c91660e
--- /dev/null
+++ b/includes/SearchEngine.php
@@ -0,0 +1,351 @@
+<?php
+/**
+ * Contain a class for special pages
+ * @package MediaWiki
+ * @subpackage Search
+ */
+
+/**
+ * @package MediaWiki
+ */
+class SearchEngine {
+ var $limit = 10;
+ var $offset = 0;
+ var $searchTerms = array();
+ var $namespaces = array( NS_MAIN );
+ var $showRedirects = false;
+
+ /**
+ * Perform a full text search query and return a result set.
+ * If title searches are not supported or disabled, return null.
+ *
+ * @param string $term - Raw search term
+ * @return SearchResultSet
+ * @access public
+ * @abstract
+ */
+ function searchText( $term ) {
+ return null;
+ }
+
+ /**
+ * Perform a title-only search query and return a result set.
+ * If title searches are not supported or disabled, return null.
+ *
+ * @param string $term - Raw search term
+ * @return SearchResultSet
+ * @access public
+ * @abstract
+ */
+ function searchTitle( $term ) {
+ return null;
+ }
+
+ /**
+ * If an exact title match can be find, or a very slightly close match,
+ * return the title. If no match, returns NULL.
+ *
+ * @static
+ * @param string $term
+ * @return Title
+ * @private
+ */
+ function getNearMatch( $searchterm ) {
+ global $wgContLang;
+
+ $allSearchTerms = array($searchterm);
+
+ if($wgContLang->hasVariants()){
+ $allSearchTerms = array_merge($allSearchTerms,$wgContLang->convertLinkToAllVariants($searchterm));
+ }
+
+ foreach($allSearchTerms as $term){
+
+ # Exact match? No need to look further.
+ $title = Title::newFromText( $term );
+ if (is_null($title))
+ return NULL;
+
+ if ( $title->getNamespace() == NS_SPECIAL || $title->exists() ) {
+ return $title;
+ }
+
+ # Now try all lower case (i.e. first letter capitalized)
+ #
+ $title = Title::newFromText( $wgContLang->lc( $term ) );
+ if ( $title->exists() ) {
+ return $title;
+ }
+
+ # Now try capitalized string
+ #
+ $title = Title::newFromText( $wgContLang->ucwords( $term ) );
+ if ( $title->exists() ) {
+ return $title;
+ }
+
+ # Now try all upper case
+ #
+ $title = Title::newFromText( $wgContLang->uc( $term ) );
+ if ( $title->exists() ) {
+ return $title;
+ }
+
+ # Now try Word-Caps-Breaking-At-Word-Breaks, for hyphenated names etc
+ $title = Title::newFromText( $wgContLang->ucwordbreaks($term) );
+ if ( $title->exists() ) {
+ return $title;
+ }
+
+ global $wgCapitalLinks, $wgContLang;
+ if( !$wgCapitalLinks ) {
+ // Catch differs-by-first-letter-case-only
+ $title = Title::newFromText( $wgContLang->ucfirst( $term ) );
+ if ( $title->exists() ) {
+ return $title;
+ }
+ $title = Title::newFromText( $wgContLang->lcfirst( $term ) );
+ if ( $title->exists() ) {
+ return $title;
+ }
+ }
+ }
+
+ $title = Title::newFromText( $searchterm );
+
+ # Entering an IP address goes to the contributions page
+ if ( ( $title->getNamespace() == NS_USER && User::isIP($title->getText() ) )
+ || User::isIP( trim( $searchterm ) ) ) {
+ return SpecialPage::getTitleFor( 'Contributions', $title->getDbkey() );
+ }
+
+
+ # Entering a user goes to the user page whether it's there or not
+ if ( $title->getNamespace() == NS_USER ) {
+ return $title;
+ }
+
+ # Quoted term? Try without the quotes...
+ $matches = array();
+ if( preg_match( '/^"([^"]+)"$/', $searchterm, $matches ) ) {
+ return SearchEngine::getNearMatch( $matches[1] );
+ }
+
+ return NULL;
+ }
+
+ function legalSearchChars() {
+ return "A-Za-z_'0-9\\x80-\\xFF\\-";
+ }
+
+ /**
+ * Set the maximum number of results to return
+ * and how many to skip before returning the first.
+ *
+ * @param int $limit
+ * @param int $offset
+ * @access public
+ */
+ function setLimitOffset( $limit, $offset = 0 ) {
+ $this->limit = intval( $limit );
+ $this->offset = intval( $offset );
+ }
+
+ /**
+ * Set which namespaces the search should include.
+ * Give an array of namespace index numbers.
+ *
+ * @param array $namespaces
+ * @access public
+ */
+ function setNamespaces( $namespaces ) {
+ $this->namespaces = $namespaces;
+ }
+
+ /**
+ * Make a list of searchable namespaces and their canonical names.
+ * @return array
+ * @access public
+ */
+ function searchableNamespaces() {
+ global $wgContLang;
+ $arr = array();
+ foreach( $wgContLang->getNamespaces() as $ns => $name ) {
+ if( $ns >= NS_MAIN ) {
+ $arr[$ns] = $name;
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * Return a 'cleaned up' search string
+ *
+ * @return string
+ * @access public
+ */
+ function filter( $text ) {
+ $lc = $this->legalSearchChars();
+ return trim( preg_replace( "/[^{$lc}]/", " ", $text ) );
+ }
+ /**
+ * Load up the appropriate search engine class for the currently
+ * active database backend, and return a configured instance.
+ *
+ * @return SearchEngine
+ * @private
+ */
+ function create() {
+ global $wgDBtype, $wgSearchType;
+ if( $wgSearchType ) {
+ $class = $wgSearchType;
+ } elseif( $wgDBtype == 'mysql' ) {
+ $class = 'SearchMySQL4';
+ } else if ( $wgDBtype == 'postgres' ) {
+ $class = 'SearchPostgres';
+ } else {
+ $class = 'SearchEngineDummy';
+ }
+ $search = new $class( wfGetDB( DB_SLAVE ) );
+ $search->setLimitOffset(0,0);
+ return $search;
+ }
+
+ /**
+ * Create or update the search index record for the given page.
+ * Title and text should be pre-processed.
+ *
+ * @param int $id
+ * @param string $title
+ * @param string $text
+ * @abstract
+ */
+ function update( $id, $title, $text ) {
+ // no-op
+ }
+
+ /**
+ * Update a search index record's title only.
+ * Title should be pre-processed.
+ *
+ * @param int $id
+ * @param string $title
+ * @abstract
+ */
+ function updateTitle( $id, $title ) {
+ // no-op
+ }
+}
+
+/** @package MediaWiki */
+class SearchResultSet {
+ /**
+ * Fetch an array of regular expression fragments for matching
+ * the search terms as parsed by this engine in a text extract.
+ *
+ * @return array
+ * @access public
+ * @abstract
+ */
+ function termMatches() {
+ return array();
+ }
+
+ function numRows() {
+ return 0;
+ }
+
+ /**
+ * Return true if results are included in this result set.
+ * @return bool
+ * @abstract
+ */
+ function hasResults() {
+ return false;
+ }
+
+ /**
+ * Some search modes return a total hit count for the query
+ * in the entire article database. This may include pages
+ * in namespaces that would not be matched on the given
+ * settings.
+ *
+ * Return null if no total hits number is supported.
+ *
+ * @return int
+ * @access public
+ */
+ function getTotalHits() {
+ return null;
+ }
+
+ /**
+ * Some search modes return a suggested alternate term if there are
+ * no exact hits. Returns true if there is one on this set.
+ *
+ * @return bool
+ * @access public
+ */
+ function hasSuggestion() {
+ return false;
+ }
+
+ /**
+ * Some search modes return a suggested alternate term if there are
+ * no exact hits. Check hasSuggestion() first.
+ *
+ * @return string
+ * @access public
+ */
+ function getSuggestion() {
+ return '';
+ }
+
+ /**
+ * Fetches next search result, or false.
+ * @return SearchResult
+ * @access public
+ * @abstract
+ */
+ function next() {
+ return false;
+ }
+}
+
+/** @package MediaWiki */
+class SearchResult {
+ function SearchResult( $row ) {
+ $this->mTitle = Title::makeTitle( $row->page_namespace, $row->page_title );
+ }
+
+ /**
+ * @return Title
+ * @access public
+ */
+ function getTitle() {
+ return $this->mTitle;
+ }
+
+ /**
+ * @return double or null if not supported
+ */
+ function getScore() {
+ return null;
+ }
+}
+
+/**
+ * @package MediaWiki
+ */
+class SearchEngineDummy {
+ function search( $term ) {
+ return null;
+ }
+ function setLimitOffset($l, $o) {}
+ function legalSearchChars() {}
+ function update() {}
+ function setnamespaces() {}
+ function searchtitle() {}
+ function searchtext() {}
+}
+?>
diff --git a/includes/SearchMySQL.php b/includes/SearchMySQL.php
new file mode 100644
index 000000000000..155159523670
--- /dev/null
+++ b/includes/SearchMySQL.php
@@ -0,0 +1,206 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Search engine hook base class for MySQL.
+ * Specific bits for MySQL 3 and 4 variants are in child classes.
+ * @package MediaWiki
+ * @subpackage Search
+ */
+
+/** @package MediaWiki */
+class SearchMySQL extends SearchEngine {
+ /**
+ * Perform a full text search query and return a result set.
+ *
+ * @param string $term - Raw search term
+ * @return MySQLSearchResultSet
+ * @access public
+ */
+ function searchText( $term ) {
+ $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), true ) ) );
+ return new MySQLSearchResultSet( $resultSet, $this->searchTerms );
+ }
+
+ /**
+ * Perform a title-only search query and return a result set.
+ *
+ * @param string $term - Raw search term
+ * @return MySQLSearchResultSet
+ * @access public
+ */
+ function searchTitle( $term ) {
+ $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), false ) ) );
+ return new MySQLSearchResultSet( $resultSet, $this->searchTerms );
+ }
+
+
+ /**
+ * Return a partial WHERE clause to exclude redirects, if so set
+ * @return string
+ * @private
+ */
+ function queryRedirect() {
+ if( $this->showRedirects ) {
+ return '';
+ } else {
+ return 'AND page_is_redirect=0';
+ }
+ }
+
+ /**
+ * Return a partial WHERE clause to limit the search to the given namespaces
+ * @return string
+ * @private
+ */
+ function queryNamespaces() {
+ $namespaces = implode( ',', $this->namespaces );
+ if ($namespaces == '') {
+ $namespaces = '0';
+ }
+ return 'AND page_namespace IN (' . $namespaces . ')';
+ }
+
+ /**
+ * Return a LIMIT clause to limit results on the query.
+ * @return string
+ * @private
+ */
+ function queryLimit() {
+ return $this->db->limitResult( '', $this->limit, $this->offset );
+ }
+
+ /**
+ * Does not do anything for generic search engine
+ * subclasses may define this though
+ * @return string
+ * @private
+ */
+ function queryRanking( $filteredTerm, $fulltext ) {
+ return '';
+ }
+
+ /**
+ * Construct the full SQL query to do the search.
+ * The guts shoulds be constructed in queryMain()
+ * @param string $filteredTerm
+ * @param bool $fulltext
+ * @private
+ */
+ function getQuery( $filteredTerm, $fulltext ) {
+ return $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
+ $this->queryRedirect() . ' ' .
+ $this->queryNamespaces() . ' ' .
+ $this->queryRanking( $filteredTerm, $fulltext ) . ' ' .
+ $this->queryLimit();
+ }
+
+
+ /**
+ * Picks which field to index on, depending on what type of query.
+ * @param bool $fulltext
+ * @return string
+ */
+ function getIndexField( $fulltext ) {
+ return $fulltext ? 'si_text' : 'si_title';
+ }
+
+ /**
+ * Get the base part of the search query.
+ * The actual match syntax will depend on the server
+ * version; MySQL 3 and MySQL 4 have different capabilities
+ * in their fulltext search indexes.
+ *
+ * @param string $filteredTerm
+ * @param bool $fulltext
+ * @return string
+ * @private
+ */
+ function queryMain( $filteredTerm, $fulltext ) {
+ $match = $this->parseQuery( $filteredTerm, $fulltext );
+ $page = $this->db->tableName( 'page' );
+ $searchindex = $this->db->tableName( 'searchindex' );
+ return 'SELECT page_id, page_namespace, page_title ' .
+ "FROM $page,$searchindex " .
+ 'WHERE page_id=si_page AND ' . $match;
+ }
+
+ /**
+ * Create or update the search index record for the given page.
+ * Title and text should be pre-processed.
+ *
+ * @param int $id
+ * @param string $title
+ * @param string $text
+ */
+ function update( $id, $title, $text ) {
+ $dbw=& wfGetDB( DB_MASTER );
+ $dbw->replace( 'searchindex',
+ array( 'si_page' ),
+ array(
+ 'si_page' => $id,
+ 'si_title' => $title,
+ 'si_text' => $text
+ ), 'SearchMySQL4::update' );
+ }
+
+ /**
+ * Update a search index record's title only.
+ * Title should be pre-processed.
+ *
+ * @param int $id
+ * @param string $title
+ */
+ function updateTitle( $id, $title ) {
+ $dbw =& wfGetDB( DB_MASTER );
+
+ $dbw->update( 'searchindex',
+ array( 'si_title' => $title ),
+ array( 'si_page' => $id ),
+ 'SearchMySQL4::updateTitle',
+ array( $dbw->lowPriorityOption() ) );
+ }
+}
+
+/** @package MediaWiki */
+class MySQLSearchResultSet extends SearchResultSet {
+ function MySQLSearchResultSet( $resultSet, $terms ) {
+ $this->mResultSet = $resultSet;
+ $this->mTerms = $terms;
+ }
+
+ function termMatches() {
+ return $this->mTerms;
+ }
+
+ function numRows() {
+ return $this->mResultSet->numRows();
+ }
+
+ function next() {
+ $row = $this->mResultSet->fetchObject();
+ if( $row === false ) {
+ return false;
+ } else {
+ return new SearchResult( $row );
+ }
+ }
+}
+
+?>
diff --git a/includes/SearchMySQL4.php b/includes/SearchMySQL4.php
new file mode 100644
index 000000000000..c20e3f8e64c9
--- /dev/null
+++ b/includes/SearchMySQL4.php
@@ -0,0 +1,74 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Search engine hook for MySQL 4+
+ * @package MediaWiki
+ * @subpackage Search
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage Search
+ */
+class SearchMySQL4 extends SearchMySQL {
+ var $strictMatching = true;
+
+ /** @todo document */
+ function SearchMySQL4( &$db ) {
+ $this->db =& $db;
+ }
+
+ /** @todo document */
+ function parseQuery( $filteredText, $fulltext ) {
+ global $wgContLang;
+ $lc = SearchEngine::legalSearchChars();
+ $searchon = '';
+ $this->searchTerms = array();
+
+ # FIXME: This doesn't handle parenthetical expressions.
+ $m = array();
+ if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+ $filteredText, $m, PREG_SET_ORDER ) ) {
+ foreach( $m as $terms ) {
+ if( $searchon !== '' ) $searchon .= ' ';
+ if( $this->strictMatching && ($terms[1] == '') ) {
+ $terms[1] = '+';
+ }
+ $searchon .= $terms[1] . $wgContLang->stripForSearch( $terms[2] );
+ if( !empty( $terms[3] ) ) {
+ $regexp = preg_quote( $terms[3], '/' );
+ if( $terms[4] ) $regexp .= "[0-9A-Za-z_]+";
+ } else {
+ $regexp = preg_quote( str_replace( '"', '', $terms[2] ), '/' );
+ }
+ $this->searchTerms[] = $regexp;
+ }
+ wfDebug( "Would search with '$searchon'\n" );
+ wfDebug( 'Match with /\b' . implode( '\b|\b', $this->searchTerms ) . "\b/\n" );
+ } else {
+ wfDebug( "Can't understand search query '{$filteredText}'\n" );
+ }
+
+ $searchon = $this->db->strencode( $searchon );
+ $field = $this->getIndexField( $fulltext );
+ return " MATCH($field) AGAINST('$searchon' IN BOOLEAN MODE) ";
+ }
+}
+?>
diff --git a/includes/SearchPostgres.php b/includes/SearchPostgres.php
new file mode 100644
index 000000000000..457636b48175
--- /dev/null
+++ b/includes/SearchPostgres.php
@@ -0,0 +1,158 @@
+<?php
+# Copyright (C) 2006 Greg Sabino Mullane <greg@turnstep.com>
+# http://www.mediawiki.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
+
+## XXX Better catching of SELECT to_tsquery('the')
+
+/**
+ * Search engine hook base class for Postgres
+ * @package MediaWiki
+ * @subpackage Search
+ */
+
+/** @package MediaWiki */
+class SearchPostgres extends SearchEngine {
+
+ function SearchPostgres( &$db ) {
+ $this->db =& $db;
+ }
+
+ /**
+ * Perform a full text search query via tsearch2 and return a result set.
+ * Currently searches a page's current title (p.page_title) and text (t.old_text)
+ *
+ * @param string $term - Raw search term
+ * @return PostgresSearchResultSet
+ * @access public
+ */
+ function searchText( $term ) {
+ $resultSet = $this->db->resultObject( $this->db->query( $this->searchQuery( $term, 'textvector' ) ) );
+ return new PostgresSearchResultSet( $resultSet, $this->searchTerms );
+ }
+ function searchTitle( $term ) {
+ $resultSet = $this->db->resultObject( $this->db->query( $this->searchQuery( $term , 'titlevector' ) ) );
+ return new PostgresSearchResultSet( $resultSet, $this->searchTerms );
+ }
+
+
+ /*
+ * Transform the user's search string into a better form for tsearch2
+ */
+ function parseQuery( $filteredText, $fulltext ) {
+ global $wgContLang;
+ $lc = SearchEngine::legalSearchChars();
+ $searchon = '';
+ $this->searchTerms = array();
+
+ # FIXME: This doesn't handle parenthetical expressions.
+ $m = array();
+ if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+ $filteredText, $m, PREG_SET_ORDER ) ) {
+ foreach( $m as $terms ) {
+ if( $searchon !== '' ) $searchon .= ' ';
+ if($terms[1] == '') {
+ $terms[1] = '+';
+ }
+ $searchon .= $terms[1] . $wgContLang->stripForSearch( $terms[2] );
+ if( !empty( $terms[3] ) ) {
+ $regexp = preg_quote( $terms[3], '/' );
+ if( $terms[4] ) $regexp .= "[0-9A-Za-z_]+";
+ } else {
+ $regexp = preg_quote( str_replace( '"', '', $terms[2] ), '/' );
+ }
+ $this->searchTerms[] = $regexp;
+ }
+ wfDebug( "Would search with '$searchon'\n" );
+ wfDebug( 'Match with /\b' . implode( '\b|\b', $this->searchTerms ) . "\b/\n" );
+ } else {
+ wfDebug( "Can't understand search query '{$this->filteredText}'\n" );
+ }
+
+ $searchon = preg_replace('/(\s+)/','&',$searchon);
+ $searchon = $this->db->strencode( $searchon );
+ return $searchon;
+ }
+
+ /**
+ * Construct the full SQL query to do the search.
+ * @param string $filteredTerm
+ * @param string $fulltext
+ * @private
+ */
+ function searchQuery( $filteredTerm, $fulltext ) {
+
+ $match = $this->parseQuery( $filteredTerm, $fulltext );
+
+ $query = "SELECT page_id, page_namespace, page_title, old_text AS page_text, ".
+ "rank(titlevector, to_tsquery('default','$match')) AS rnk ".
+ "FROM page p, revision r, pagecontent c WHERE p.page_latest = r.rev_id " .
+ "AND r.rev_text_id = c.old_id AND $fulltext @@ to_tsquery('default','$match')";
+
+ ## Redirects
+ if (! $this->showRedirects)
+ $query .= ' AND page_is_redirect = 0'; ## IS FALSE
+
+ ## Namespaces - defaults to 0
+ if ( count($this->namespaces) < 1)
+ $query .= ' AND page_namespace = 0';
+ else {
+ $namespaces = implode( ',', $this->namespaces );
+ $query .= " AND page_namespace IN ($namespaces)";
+ }
+
+ $query .= " ORDER BY rnk DESC, page_id DESC";
+
+ $query .= $this->db->limitResult( '', $this->limit, $this->offset );
+
+ return $query;
+ }
+
+ ## These two functions are done automatically via triggers
+
+ function update( $id, $title, $text ) { return true; }
+ function updateTitle( $id, $title ) { return true; }
+
+} ## end of the SearchPostgres class
+
+
+/** @package MediaWiki */
+class PostgresSearchResultSet extends SearchResultSet {
+ function PostgresSearchResultSet( $resultSet, $terms ) {
+ $this->mResultSet = $resultSet;
+ $this->mTerms = $terms;
+ }
+
+ function termMatches() {
+ return $this->mTerms;
+ }
+
+ function numRows() {
+ return $this->mResultSet->numRows();
+ }
+
+ function next() {
+ $row = $this->mResultSet->fetchObject();
+ if( $row === false ) {
+ return false;
+ } else {
+ return new SearchResult( $row );
+ }
+ }
+}
+
+?>
diff --git a/includes/SearchTsearch2.php b/includes/SearchTsearch2.php
new file mode 100644
index 000000000000..1fca9899630b
--- /dev/null
+++ b/includes/SearchTsearch2.php
@@ -0,0 +1,124 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>, Domas Mituzas <domas.mituzas@gmail.com>
+# http://www.mediawiki.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
+
+/**
+ * Search engine hook for PostgreSQL / Tsearch2
+ * @package MediaWiki
+ * @subpackage Search
+ */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Search
+ */
+class SearchTsearch2 extends SearchEngine {
+ var $strictMatching = false;
+
+ function SearchTsearch2( &$db ) {
+ $this->db =& $db;
+ $this->mRanking = true;
+ }
+
+ function getIndexField( $fulltext ) {
+ return $fulltext ? 'si_text' : 'si_title';
+ }
+
+ function parseQuery( $filteredText, $fulltext ) {
+ global $wgContLang;
+ $lc = SearchEngine::legalSearchChars();
+ $searchon = '';
+ $this->searchTerms = array();
+
+ # FIXME: This doesn't handle parenthetical expressions.
+ $m = array();
+ if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+ $filteredText, $m, PREG_SET_ORDER ) ) {
+ foreach( $m as $terms ) {
+ if( $searchon !== '' ) $searchon .= ' ';
+ if( $this->strictMatching && ($terms[1] == '') ) {
+ $terms[1] = '+';
+ }
+ $searchon .= $terms[1] . $wgContLang->stripForSearch( $terms[2] );
+ if( !empty( $terms[3] ) ) {
+ $regexp = preg_quote( $terms[3], '/' );
+ if( $terms[4] ) $regexp .= "[0-9A-Za-z_]+";
+ } else {
+ $regexp = preg_quote( str_replace( '"', '', $terms[2] ), '/' );
+ }
+ $this->searchTerms[] = $regexp;
+ }
+ wfDebug( "Would search with '$searchon'\n" );
+ wfDebug( 'Match with /\b' . implode( '\b|\b', $this->searchTerms ) . "\b/\n" );
+ } else {
+ wfDebug( "Can't understand search query '{$this->filteredText}'\n" );
+ }
+
+ $searchon = preg_replace('/(\s+)/','&',$searchon);
+ $searchon = $this->db->strencode( $searchon );
+ return $searchon;
+ }
+
+ function queryRanking($filteredTerm, $fulltext) {
+ $field = $this->getIndexField( $fulltext );
+ $searchon = $this->parseQuery($filteredTerm,$fulltext);
+ if ($this->mRanking)
+ return " ORDER BY rank($field,to_tsquery('$searchon')) DESC";
+ else
+ return "";
+ }
+
+
+ function queryMain( $filteredTerm, $fulltext ) {
+ $match = $this->parseQuery( $filteredTerm, $fulltext );
+ $field = $this->getIndexField( $fulltext );
+ $cur = $this->db->tableName( 'cur' );
+ $searchindex = $this->db->tableName( 'searchindex' );
+ return 'SELECT cur_id, cur_namespace, cur_title, cur_text ' .
+ "FROM $cur,$searchindex " .
+ 'WHERE cur_id=si_page AND ' .
+ " $field @@ to_tsquery ('$match') " ;
+ }
+
+ function update( $id, $title, $text ) {
+ $dbw=& wfGetDB(DB_MASTER);
+ $searchindex = $dbw->tableName( 'searchindex' );
+ $sql = "DELETE FROM $searchindex WHERE si_page={$id}";
+ $dbw->query($sql,"SearchTsearch2:update");
+ $sql = "INSERT INTO $searchindex (si_page,si_title,si_text) ".
+ " VALUES ( $id, to_tsvector('".
+ $dbw->strencode($title).
+ "'),to_tsvector('".
+ $dbw->strencode( $text)."')) ";
+ $dbw->query($sql,"SearchTsearch2:update");
+ }
+
+ function updateTitle($id,$title) {
+ $dbw=& wfGetDB(DB_MASTER);
+ $searchindex = $dbw->tableName( 'searchindex' );
+ $sql = "UPDATE $searchindex SET si_title=to_tsvector('" .
+ $dbw->strencode( $title ) .
+ "') WHERE si_page={$id}";
+
+ $dbw->query( $sql, "SearchMySQL4::updateTitle" );
+ }
+
+}
+
+?>
diff --git a/includes/SearchUpdate.php b/includes/SearchUpdate.php
new file mode 100644
index 000000000000..37981a67d7f7
--- /dev/null
+++ b/includes/SearchUpdate.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * See deferred.txt
+ * @package MediaWiki
+ */
+
+/**
+ *
+ * @package MediaWiki
+ */
+class SearchUpdate {
+
+ /* private */ var $mId = 0, $mNamespace, $mTitle, $mText;
+ /* private */ var $mTitleWords;
+
+ function SearchUpdate( $id, $title, $text = false ) {
+ $nt = Title::newFromText( $title );
+ if( $nt ) {
+ $this->mId = $id;
+ $this->mText = $text;
+
+ $this->mNamespace = $nt->getNamespace();
+ $this->mTitle = $nt->getText(); # Discard namespace
+
+ $this->mTitleWords = $this->mTextWords = array();
+ } else {
+ wfDebug( "SearchUpdate object created with invalid title '$title'\n" );
+ }
+ }
+
+ function doUpdate() {
+ global $wgContLang, $wgDisableSearchUpdate;
+
+ if( $wgDisableSearchUpdate || !$this->mId ) {
+ return false;
+ }
+ $fname = 'SearchUpdate::doUpdate';
+ wfProfileIn( $fname );
+
+ $search = SearchEngine::create();
+ $lc = $search->legalSearchChars() . '&#;';
+
+ if( $this->mText === false ) {
+ $search->updateTitle($this->mId,
+ Title::indexTitle( $this->mNamespace, $this->mTitle ));
+ wfProfileOut( $fname );
+ return;
+ }
+
+ # Language-specific strip/conversion
+ $text = $wgContLang->stripForSearch( $this->mText );
+
+ wfProfileIn( $fname.'-regexps' );
+ $text = preg_replace( "/<\\/?\\s*[A-Za-z][A-Za-z0-9]*\\s*([^>]*?)>/",
+ ' ', strtolower( " " . $text /*$this->mText*/ . " " ) ); # Strip HTML markup
+ $text = preg_replace( "/(^|\\n)==\\s*([^\\n]+)\\s*==(\\s)/sD",
+ "\\1\\2 \\2 \\2\\3", $text ); # Emphasize headings
+
+ # Strip external URLs
+ $uc = "A-Za-z0-9_\\/:.,~%\\-+&;#?!=()@\\xA0-\\xFF";
+ $protos = "http|https|ftp|mailto|news|gopher";
+ $pat = "/(^|[^\\[])({$protos}):[{$uc}]+([^{$uc}]|$)/";
+ $text = preg_replace( $pat, "\\1 \\3", $text );
+
+ $p1 = "/([^\\[])\\[({$protos}):[{$uc}]+]/";
+ $p2 = "/([^\\[])\\[({$protos}):[{$uc}]+\\s+([^\\]]+)]/";
+ $text = preg_replace( $p1, "\\1 ", $text );
+ $text = preg_replace( $p2, "\\1 \\3 ", $text );
+
+ # Internal image links
+ $pat2 = "/\\[\\[image:([{$uc}]+)\\.(gif|png|jpg|jpeg)([^{$uc}])/i";
+ $text = preg_replace( $pat2, " \\1 \\3", $text );
+
+ $text = preg_replace( "/([^{$lc}])([{$lc}]+)]]([a-z]+)/",
+ "\\1\\2 \\2\\3", $text ); # Handle [[game]]s
+
+ # Strip all remaining non-search characters
+ $text = preg_replace( "/[^{$lc}]+/", " ", $text );
+
+ # Handle 's, s'
+ #
+ # $text = preg_replace( "/([{$lc}]+)'s /", "\\1 \\1's ", $text );
+ # $text = preg_replace( "/([{$lc}]+)s' /", "\\1s ", $text );
+ #
+ # These tail-anchored regexps are insanely slow. The worst case comes
+ # when Japanese or Chinese text (ie, no word spacing) is written on
+ # a wiki configured for Western UTF-8 mode. The Unicode characters are
+ # expanded to hex codes and the "words" are very long paragraph-length
+ # monstrosities. On a large page the above regexps may take over 20
+ # seconds *each* on a 1GHz-level processor.
+ #
+ # Following are reversed versions which are consistently fast
+ # (about 3 milliseconds on 1GHz-level processor).
+ #
+ $text = strrev( preg_replace( "/ s'([{$lc}]+)/", " s'\\1 \\1", strrev( $text ) ) );
+ $text = strrev( preg_replace( "/ 's([{$lc}]+)/", " s\\1", strrev( $text ) ) );
+
+ # Strip wiki '' and '''
+ $text = preg_replace( "/''[']*/", " ", $text );
+ wfProfileOut( "$fname-regexps" );
+ $search->update($this->mId, Title::indexTitle( $this->mNamespace, $this->mTitle ),
+ $text);
+ wfProfileOut( $fname );
+ }
+}
+
+/**
+ * Placeholder class
+ * @package MediaWiki
+ */
+class SearchUpdateMyISAM extends SearchUpdate {
+ # Inherits everything
+}
+
+?>
diff --git a/includes/Setup.php b/includes/Setup.php
new file mode 100644
index 000000000000..80a5b48abc4c
--- /dev/null
+++ b/includes/Setup.php
@@ -0,0 +1,235 @@
+<?php
+/**
+ * Include most things that's need to customize the site
+ * @package MediaWiki
+ */
+
+/**
+ * This file is not a valid entry point, perform no further processing unless
+ * MEDIAWIKI is defined
+ */
+if( !defined( 'MEDIAWIKI' ) ) {
+ echo "This file is part of MediaWiki, it is not a valid entry point.\n";
+ exit( 1 );
+}
+
+# The main wiki script and things like database
+# conversion and maintenance scripts all share a
+# common setup of including lots of classes and
+# setting up a few globals.
+#
+
+$fname = 'Setup.php';
+wfProfileIn( $fname );
+
+// Check to see if we are at the file scope
+if ( !isset( $wgVersion ) ) {
+ echo "Error, Setup.php must be included from the file scope, after DefaultSettings.php\n";
+ die( 1 );
+}
+
+// Set various default paths sensibly...
+if( $wgScript === false ) $wgScript = "$wgScriptPath/index.php";
+if( $wgRedirectScript === false ) $wgRedirectScript = "$wgScriptPath/redirect.php";
+
+if( $wgArticlePath === false ) {
+ if( $wgUsePathInfo ) {
+ $wgArticlePath = "$wgScript/$1";
+ } else {
+ $wgArticlePath = "$wgScript?title=$1";
+ }
+}
+
+if( $wgStylePath === false ) $wgStylePath = "$wgScriptPath/skins";
+if( $wgStyleDirectory === false) $wgStyleDirectory = "$IP/skins";
+
+if( $wgLogo === false ) $wgLogo = "$wgStylePath/common/images/wiki.png";
+
+if( $wgUploadPath === false ) $wgUploadPath = "$wgScriptPath/images";
+if( $wgUploadDirectory === false ) $wgUploadDirectory = "$IP/images";
+
+if( $wgMathPath === false ) $wgMathPath = "{$wgUploadPath}/math";
+if( $wgMathDirectory === false ) $wgMathDirectory = "{$wgUploadDirectory}/math";
+if( $wgTmpDirectory === false ) $wgTmpDirectory = "{$wgUploadDirectory}/tmp";
+
+if( $wgReadOnlyFile === false ) $wgReadOnlyFile = "{$wgUploadDirectory}/lock_yBgMBwiR";
+if( $wgFileCacheDirectory === false ) $wgFileCacheDirectory = "{$wgUploadDirectory}/cache";
+
+require_once( "$IP/includes/AutoLoader.php" );
+
+wfProfileIn( $fname.'-exception' );
+require_once( "$IP/includes/Exception.php" );
+wfInstallExceptionHandler();
+wfProfileOut( $fname.'-exception' );
+
+wfProfileIn( $fname.'-includes' );
+require_once( "$IP/includes/GlobalFunctions.php" );
+require_once( "$IP/includes/Hooks.php" );
+require_once( "$IP/includes/Namespace.php" );
+require_once( "$IP/includes/ProxyTools.php" );
+require_once( "$IP/includes/ObjectCache.php" );
+require_once( "$IP/includes/ImageFunctions.php" );
+require_once( "$IP/includes/StubObject.php" );
+wfProfileOut( $fname.'-includes' );
+wfProfileIn( $fname.'-misc1' );
+
+
+$wgIP = false; # Load on demand
+# Can't stub this one, it sets up $_GET and $_REQUEST in its constructor
+$wgRequest = new WebRequest;
+if ( function_exists( 'posix_uname' ) ) {
+ $wguname = posix_uname();
+ $wgNodeName = $wguname['nodename'];
+} else {
+ $wgNodeName = '';
+}
+
+# Useful debug output
+if ( $wgCommandLineMode ) {
+ wfDebug( "\n\nStart command line script $self\n" );
+} elseif ( function_exists( 'getallheaders' ) ) {
+ wfDebug( "\n\nStart request\n" );
+ wfDebug( $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'] . "\n" );
+ $headers = getallheaders();
+ foreach ($headers as $name => $value) {
+ wfDebug( "$name: $value\n" );
+ }
+ wfDebug( "\n" );
+} elseif( isset( $_SERVER['REQUEST_URI'] ) ) {
+ wfDebug( $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'] . "\n" );
+}
+
+if ( $wgSkipSkin ) {
+ $wgSkipSkins[] = $wgSkipSkin;
+}
+
+$wgUseEnotif = $wgEnotifUserTalk || $wgEnotifWatchlist;
+
+if($wgMetaNamespace === FALSE) {
+ $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
+}
+
+# These are now the same, always
+# To determine the user language, use $wgLang->getCode()
+$wgContLanguageCode = $wgLanguageCode;
+
+wfProfileOut( $fname.'-misc1' );
+wfProfileIn( $fname.'-memcached' );
+
+$wgMemc =& wfGetMainCache();
+$messageMemc =& wfGetMessageCacheStorage();
+$parserMemc =& wfGetParserCacheStorage();
+
+wfDebug( 'Main cache: ' . get_class( $wgMemc ) .
+ "\nMessage cache: " . get_class( $messageMemc ) .
+ "\nParser cache: " . get_class( $parserMemc ) . "\n" );
+
+wfProfileOut( $fname.'-memcached' );
+wfProfileIn( $fname.'-SetupSession' );
+
+if ( $wgDBprefix ) {
+ $wgCookiePrefix = $wgDBname . '_' . $wgDBprefix;
+} elseif ( $wgSharedDB ) {
+ $wgCookiePrefix = $wgSharedDB;
+} else {
+ $wgCookiePrefix = $wgDBname;
+}
+
+# If session.auto_start is there, we can't touch session name
+#
+if( !ini_get( 'session.auto_start' ) )
+ session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' );
+
+if( !$wgCommandLineMode && ( isset( $_COOKIE[session_name()] ) || isset( $_COOKIE[$wgCookiePrefix.'Token'] ) ) ) {
+ wfIncrStats( 'request_with_session' );
+ wfSetupSession();
+ $wgSessionStarted = true;
+} else {
+ wfIncrStats( 'request_without_session' );
+ $wgSessionStarted = false;
+}
+
+wfProfileOut( $fname.'-SetupSession' );
+wfProfileIn( $fname.'-globals' );
+
+if ( !$wgDBservers ) {
+ $wgDBservers = array(array(
+ 'host' => $wgDBserver,
+ 'user' => $wgDBuser,
+ 'password' => $wgDBpassword,
+ 'dbname' => $wgDBname,
+ 'type' => $wgDBtype,
+ 'load' => 1,
+ 'flags' => ($wgDebugDumpSql ? DBO_DEBUG : 0) | DBO_DEFAULT
+ ));
+}
+
+$wgLoadBalancer = new StubObject( 'wgLoadBalancer', 'LoadBalancer',
+ array( $wgDBservers, false, $wgMasterWaitTimeout, true ) );
+$wgContLang = new StubContLang;
+$wgUser = new StubUser;
+$wgLang = new StubUserLang;
+$wgOut = new StubObject( 'wgOut', 'OutputPage' );
+$wgParser = new StubObject( 'wgParser', 'Parser' );
+$wgMessageCache = new StubObject( 'wgMessageCache', 'MessageCache',
+ array( $parserMemc, $wgUseDatabaseMessages, $wgMsgCacheExpiry, wfWikiID() ) );
+
+wfProfileOut( $fname.'-globals' );
+wfProfileIn( $fname.'-User' );
+
+# Skin setup functions
+# Entries can be added to this variable during the inclusion
+# of the extension file. Skins can then perform any necessary initialisation.
+#
+foreach ( $wgSkinExtensionFunctions as $func ) {
+ call_user_func( $func );
+}
+
+if( !is_object( $wgAuth ) ) {
+ $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
+ wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
+}
+
+wfProfileOut( $fname.'-User' );
+
+wfProfileIn( $fname.'-misc2' );
+
+$wgDeferredUpdateList = array();
+$wgPostCommitUpdateList = array();
+
+if ( $wgAjaxSearch ) $wgAjaxExportList[] = 'wfSajaxSearch';
+if ( $wgAjaxWatch ) $wgAjaxExportList[] = 'wfAjaxWatch';
+
+wfSeedRandom();
+
+# Placeholders in case of DB error
+$wgTitle = null;
+$wgArticle = null;
+
+wfProfileOut( $fname.'-misc2' );
+wfProfileIn( $fname.'-extensions' );
+
+# Extension setup functions for extensions other than skins
+# Entries should be added to this variable during the inclusion
+# of the extension file. This allows the extension to perform
+# any necessary initialisation in the fully initialised environment
+foreach ( $wgExtensionFunctions as $func ) {
+ $profName = $fname.'-extensions-'.strval( $func );
+ wfProfileIn( $profName );
+ call_user_func( $func );
+ wfProfileOut( $profName );
+}
+
+// For compatibility
+wfRunHooks( 'LogPageValidTypes', array( &$wgLogTypes ) );
+wfRunHooks( 'LogPageLogName', array( &$wgLogNames ) );
+wfRunHooks( 'LogPageLogHeader', array( &$wgLogHeaders ) );
+wfRunHooks( 'LogPageActionText', array( &$wgLogActions ) );
+
+
+wfDebug( "Fully initialised\n" );
+$wgFullyInitialised = true;
+wfProfileOut( $fname.'-extensions' );
+wfProfileOut( $fname );
+
+?>
diff --git a/includes/SiteConfiguration.php b/includes/SiteConfiguration.php
new file mode 100644
index 000000000000..8fd5d6b6bdb9
--- /dev/null
+++ b/includes/SiteConfiguration.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * This is a class used to hold configuration settings, particularly for multi-wiki sites.
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * The include paths change after this file is included from commandLine.inc,
+ * meaning that require_once() fails to detect that it is including the same
+ * file again. We use DIY C-style protection as a workaround.
+ */
+if (!defined('SITE_CONFIGURATION')) {
+define('SITE_CONFIGURATION', 1);
+
+/** @package MediaWiki */
+class SiteConfiguration {
+ var $suffixes = array();
+ var $wikis = array();
+ var $settings = array();
+ var $localVHosts = array();
+
+ /** */
+ function get( $setting, $wiki, $suffix, $params = array() ) {
+ if ( array_key_exists( $setting, $this->settings ) ) {
+ if ( array_key_exists( $wiki, $this->settings[$setting] ) ) {
+ $retval = $this->settings[$setting][$wiki];
+ } elseif ( array_key_exists( $suffix, $this->settings[$setting] ) ) {
+ $retval = $this->settings[$setting][$suffix];
+ } elseif ( array_key_exists( 'default', $this->settings[$setting] ) ) {
+ $retval = $this->settings[$setting]['default'];
+ } else {
+ $retval = NULL;
+ }
+ } else {
+ $retval = NULL;
+ }
+
+ if ( !is_null( $retval ) && count( $params ) ) {
+ foreach ( $params as $key => $value ) {
+ $retval = str_replace( '$' . $key, $value, $retval );
+ }
+ }
+ return $retval;
+ }
+
+ /** */
+ function getAll( $wiki, $suffix, $params ) {
+ $localSettings = array();
+ foreach ( $this->settings as $varname => $stuff ) {
+ $value = $this->get( $varname, $wiki, $suffix, $params );
+ if ( !is_null( $value ) ) {
+ $localSettings[$varname] = $value;
+ }
+ }
+ return $localSettings;
+ }
+
+ /** */
+ function getBool( $setting, $wiki, $suffix ) {
+ return (bool)($this->get( $setting, $wiki, $suffix ));
+ }
+
+ /** */
+ function &getLocalDatabases() {
+ return $this->wikis;
+ }
+
+ /** */
+ function initialise() {
+ }
+
+ /** */
+ function extractVar( $setting, $wiki, $suffix, &$var, $params ) {
+ $value = $this->get( $setting, $wiki, $suffix, $params );
+ if ( !is_null( $value ) ) {
+ $var = $value;
+ }
+ }
+
+ /** */
+ function extractGlobal( $setting, $wiki, $suffix, $params ) {
+ $value = $this->get( $setting, $wiki, $suffix, $params );
+ if ( !is_null( $value ) ) {
+ $GLOBALS[$setting] = $value;
+ }
+ }
+
+ /** */
+ function extractAllGlobals( $wiki, $suffix, $params ) {
+ foreach ( $this->settings as $varName => $setting ) {
+ $this->extractGlobal( $varName, $wiki, $suffix, $params );
+ }
+ }
+
+ /**
+ * Work out the site and language name from a database name
+ * @param $db
+ */
+ function siteFromDB( $db ) {
+ $site = NULL;
+ $lang = NULL;
+ foreach ( $this->suffixes as $suffix ) {
+ if ( substr( $db, -strlen( $suffix ) ) == $suffix ) {
+ $site = $suffix == 'wiki' ? 'wikipedia' : $suffix;
+ $lang = substr( $db, 0, strlen( $db ) - strlen( $suffix ) );
+ break;
+ }
+ }
+ $lang = str_replace( '_', '-', $lang );
+ return array( $site, $lang );
+ }
+
+ /** */
+ function isLocalVHost( $vhost ) {
+ return in_array( $vhost, $this->localVHosts );
+ }
+}
+}
+
+?>
diff --git a/includes/SiteStats.php b/includes/SiteStats.php
new file mode 100644
index 000000000000..e2774a1423a1
--- /dev/null
+++ b/includes/SiteStats.php
@@ -0,0 +1,168 @@
+<?php
+
+/**
+ * Static accessor class for site_stats and related things
+ * @package MediaWiki
+ */
+class SiteStats {
+ static $row, $loaded = false;
+ static $admins;
+ static $pageCount = array();
+
+ static function recache() {
+ self::load( true );
+ }
+
+ static function load( $recache = false ) {
+ if ( self::$loaded && !$recache ) {
+ return;
+ }
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ self::$row = $dbr->selectRow( 'site_stats', '*', false, __METHOD__ );
+
+ # This code is somewhat schema-agnostic, because I'm changing it in a minor release -- TS
+ if ( !isset( self::$row->ss_total_pages ) && self::$row->ss_total_pages == -1 ) {
+ # Update schema
+ $u = new SiteStatsUpdate( 0, 0, 0 );
+ $u->doUpdate();
+ self::$row = $dbr->selectRow( 'site_stats', '*', false, __METHOD__ );
+ }
+ }
+
+ static function views() {
+ self::load();
+ return self::$row->ss_total_views;
+ }
+
+ static function edits() {
+ self::load();
+ return self::$row->ss_total_edits;
+ }
+
+ static function articles() {
+ self::load();
+ return self::$row->ss_good_articles;
+ }
+
+ static function pages() {
+ self::load();
+ return self::$row->ss_total_pages;
+ }
+
+ static function users() {
+ self::load();
+ return self::$row->ss_users;
+ }
+
+ static function images() {
+ self::load();
+ return self::$row->ss_images;
+ }
+
+ static function admins() {
+ if ( !isset( self::$admins ) ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ self::$admins = $dbr->selectField( 'user_groups', 'COUNT(*)', array( 'ug_group' => 'sysop' ), __METHOD__ );
+ }
+ return self::$admins;
+ }
+
+ static function pagesInNs( $ns ) {
+ wfProfileIn( __METHOD__ );
+ if( !isset( self::$pageCount[$ns] ) ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $pageCount[$ns] = (int)$dbr->selectField( 'page', 'COUNT(*)', array( 'page_namespace' => $ns ), __METHOD__ );
+ }
+ wfProfileOut( __METHOD__ );
+ return $pageCount[$ns];
+ }
+
+}
+
+
+/**
+ *
+ * @package MediaWiki
+ */
+class SiteStatsUpdate {
+
+ var $mViews, $mEdits, $mGood, $mPages, $mUsers;
+
+ function SiteStatsUpdate( $views, $edits, $good, $pages = 0, $users = 0 ) {
+ $this->mViews = $views;
+ $this->mEdits = $edits;
+ $this->mGood = $good;
+ $this->mPages = $pages;
+ $this->mUsers = $users;
+ }
+
+ function appendUpdate( &$sql, $field, $delta ) {
+ if ( $delta ) {
+ if ( $sql ) {
+ $sql .= ',';
+ }
+ if ( $delta < 0 ) {
+ $sql .= "$field=$field-1";
+ } else {
+ $sql .= "$field=$field+1";
+ }
+ }
+ }
+
+ function doUpdate() {
+ $fname = 'SiteStatsUpdate::doUpdate';
+ $dbw =& wfGetDB( DB_MASTER );
+
+ # First retrieve the row just to find out which schema we're in
+ $row = $dbw->selectRow( 'site_stats', '*', false, $fname );
+
+ $updates = '';
+
+ $this->appendUpdate( $updates, 'ss_total_views', $this->mViews );
+ $this->appendUpdate( $updates, 'ss_total_edits', $this->mEdits );
+ $this->appendUpdate( $updates, 'ss_good_articles', $this->mGood );
+
+ if ( isset( $row->ss_total_pages ) ) {
+ # Update schema if required
+ if ( $row->ss_total_pages == -1 && !$this->mViews ) {
+ $dbr =& wfGetDB( DB_SLAVE, array( 'SpecialStatistics', 'vslow') );
+ list( $page, $user ) = $dbr->tableNamesN( 'page', 'user' );
+
+ $sql = "SELECT COUNT(page_namespace) AS total FROM $page";
+ $res = $dbr->query( $sql, $fname );
+ $pageRow = $dbr->fetchObject( $res );
+ $pages = $pageRow->total + $this->mPages;
+
+ $sql = "SELECT COUNT(user_id) AS total FROM $user";
+ $res = $dbr->query( $sql, $fname );
+ $userRow = $dbr->fetchObject( $res );
+ $users = $userRow->total + $this->mUsers;
+
+ if ( $updates ) {
+ $updates .= ',';
+ }
+ $updates .= "ss_total_pages=$pages, ss_users=$users";
+ } else {
+ $this->appendUpdate( $updates, 'ss_total_pages', $this->mPages );
+ $this->appendUpdate( $updates, 'ss_users', $this->mUsers );
+ }
+ }
+ if ( $updates ) {
+ $site_stats = $dbw->tableName( 'site_stats' );
+ $sql = $dbw->limitResultForUpdate("UPDATE $site_stats SET $updates", 1);
+ $dbw->begin();
+ $dbw->query( $sql, $fname );
+ $dbw->commit();
+ }
+
+ /*
+ global $wgDBname, $wgTitle;
+ if ( $this->mGood && $wgDBname == 'enwiki' ) {
+ $good = $dbw->selectField( 'site_stats', 'ss_good_articles', '', $fname );
+ error_log( $good . ' ' . $wgTitle->getPrefixedDBkey() . "\n", 3, '/home/wikipedia/logs/million.log' );
+ }
+ */
+ }
+}
+?>
diff --git a/includes/Skin.php b/includes/Skin.php
new file mode 100644
index 000000000000..f8e733efe256
--- /dev/null
+++ b/includes/Skin.php
@@ -0,0 +1,1653 @@
+<?php
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+# See skin.txt
+
+/**
+ * The main skin class that provide methods and properties for all other skins.
+ * This base class is also the "Standard" skin.
+ * @package MediaWiki
+ */
+class Skin extends Linker {
+ /**#@+
+ * @private
+ */
+ var $lastdate, $lastline;
+ var $rc_cache ; # Cache for Enhanced Recent Changes
+ var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
+ var $rcMoveIndex;
+ var $mWatchLinkNum = 0; // Appended to end of watch link id's
+ /**#@-*/
+
+ /** Constructor, call parent constructor */
+ function Skin() { parent::Linker(); }
+
+ /**
+ * Fetch the set of available skins.
+ * @return array of strings
+ * @static
+ */
+ static function &getSkinNames() {
+ global $wgValidSkinNames;
+ static $skinsInitialised = false;
+ if ( !$skinsInitialised ) {
+ # 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 );
+
+ # 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];
+ $wgValidSkinNames[strtolower($aSkin)] = $aSkin;
+ }
+ }
+ $skinDir->close();
+ $skinsInitialised = true;
+ wfProfileOut( __METHOD__ . '-init' );
+ }
+ return $wgValidSkinNames;
+ }
+
+ /**
+ * Normalize a skin preference value to a form that can be loaded.
+ * If a skin can't be found, it will fall back to the configured
+ * default (or the old 'Classic' skin if that's broken).
+ * @param string $key
+ * @return string
+ * @static
+ */
+ static function normalizeKey( $key ) {
+ global $wgDefaultSkin;
+ $skinNames = Skin::getSkinNames();
+
+ if( $key == '' ) {
+ // Don't return the default immediately;
+ // in a misconfiguration we need to fall back.
+ $key = $wgDefaultSkin;
+ }
+
+ if( isset( $skinNames[$key] ) ) {
+ return $key;
+ }
+
+ // Older versions of the software used a numeric setting
+ // in the user preferences.
+ $fallback = array(
+ 0 => $wgDefaultSkin,
+ 1 => 'nostalgia',
+ 2 => 'cologneblue' );
+
+ if( isset( $fallback[$key] ) ){
+ $key = $fallback[$key];
+ }
+
+ if( isset( $skinNames[$key] ) ) {
+ return $key;
+ } else {
+ // The old built-in skin
+ return 'standard';
+ }
+ }
+
+ /**
+ * Factory method for loading a skin of a given type
+ * @param string $key 'monobook', 'standard', etc
+ * @return Skin
+ * @static
+ */
+ static function &newFromKey( $key ) {
+ global $wgStyleDirectory;
+
+ $key = Skin::normalizeKey( $key );
+
+ $skinNames = Skin::getSkinNames();
+ $skinName = $skinNames[$key];
+
+ # Grab the skin class and initialise it.
+ // Preload base classes to work around APC/PHP5 bug
+ $deps = "{$wgStyleDirectory}/{$skinName}.deps.php";
+ if( file_exists( $deps ) ) include_once( $deps );
+ require_once( "{$wgStyleDirectory}/{$skinName}.php" );
+
+ # Check if we got if not failback to default skin
+ $className = 'Skin'.$skinName;
+ 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.
+ wfDebug( "Skin class does not exist: $className\n" );
+ $className = 'SkinStandard';
+ require_once( "{$wgStyleDirectory}/Standard.php" );
+ }
+ $skin = new $className;
+ return $skin;
+ }
+
+ /** @return string path to the skin stylesheet */
+ function getStylesheet() {
+ return 'common/wikistandard.css';
+ }
+
+ /** @return string skin name */
+ function getSkinName() {
+ return 'standard';
+ }
+
+ function qbSetting() {
+ global $wgOut, $wgUser;
+
+ if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
+ $q = $wgUser->getOption( 'quickbar', 0 );
+ return $q;
+ }
+
+ function initPage( &$out ) {
+ global $wgFavicon, $wgScriptPath, $wgSitename, $wgLanguageCode, $wgLanguageNames;
+
+ $fname = 'Skin::initPage';
+ wfProfileIn( $fname );
+
+ if( false !== $wgFavicon ) {
+ $out->addLink( array( 'rel' => 'shortcut icon', 'href' => $wgFavicon ) );
+ }
+
+ # OpenSearch description link
+ $out->addLink( array(
+ 'rel' => 'search',
+ 'type' => 'application/opensearchdescription+xml',
+ 'href' => "$wgScriptPath/opensearch_desc.php",
+ 'title' => "$wgSitename ({$wgLanguageNames[$wgLanguageCode]})",
+ ));
+
+ $this->addMetadataLinks($out);
+
+ $this->mRevisionId = $out->mRevisionId;
+
+ $this->preloadExistence();
+
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Preload the existence of three commonly-requested pages in a single query
+ */
+ function preloadExistence() {
+ global $wgUser, $wgTitle;
+
+ if ( $wgTitle->isTalkPage() ) {
+ $otherTab = $wgTitle->getSubjectPage();
+ } else {
+ $otherTab = $wgTitle->getTalkPage();
+ }
+ $lb = new LinkBatch( array(
+ $wgUser->getUserPage(),
+ $wgUser->getTalkPage(),
+ $otherTab
+ ));
+ $lb->execute();
+ }
+
+ function addMetadataLinks( &$out ) {
+ global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf;
+ global $wgRightsPage, $wgRightsUrl;
+
+ if( $out->isArticleRelated() ) {
+ # note: buggy CC software only reads first "meta" link
+ if( $wgEnableCreativeCommonsRdf ) {
+ $out->addMetadataLink( array(
+ 'title' => 'Creative Commons',
+ 'type' => 'application/rdf+xml',
+ 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
+ }
+ if( $wgEnableDublinCoreRdf ) {
+ $out->addMetadataLink( array(
+ 'title' => 'Dublin Core',
+ 'type' => 'application/rdf+xml',
+ 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
+ }
+ }
+ $copyright = '';
+ if( $wgRightsPage ) {
+ $copy = Title::newFromText( $wgRightsPage );
+ if( $copy ) {
+ $copyright = $copy->getLocalURL();
+ }
+ }
+ if( !$copyright && $wgRightsUrl ) {
+ $copyright = $wgRightsUrl;
+ }
+ if( $copyright ) {
+ $out->addLink( array(
+ 'rel' => 'copyright',
+ 'href' => $copyright ) );
+ }
+ }
+
+ function outputPage( &$out ) {
+ global $wgDebugComments;
+
+ wfProfileIn( 'Skin::outputPage' );
+ $this->initPage( $out );
+
+ $out->out( $out->headElement() );
+
+ $out->out( "\n<body" );
+ $ops = $this->getBodyOptions();
+ foreach ( $ops as $name => $val ) {
+ $out->out( " $name='$val'" );
+ }
+ $out->out( ">\n" );
+ if ( $wgDebugComments ) {
+ $out->out( "<!-- Wiki debugging output:\n" .
+ $out->mDebugtext . "-->\n" );
+ }
+
+ $out->out( $this->beforeContent() );
+
+ $out->out( $out->mBodytext . "\n" );
+
+ $out->out( $this->afterContent() );
+
+ $out->out( $this->bottomScripts() );
+
+ $out->out( $out->reportTime() );
+
+ $out->out( "\n</body></html>" );
+ }
+
+ static function makeVariablesScript( $data ) {
+ global $wgJsMimeType;
+
+ $r = "<script type= \"$wgJsMimeType\">/*<![CDATA[*/\n";
+ foreach ( $data as $name => $value ) {
+ $encValue = Xml::encodeJsVar( $value );
+ $r .= "var $name = $encValue;\n";
+ }
+ $r .= "/*]]>*/</script>\n";
+
+ return $r;
+ }
+
+ /**
+ * Make a <script> tag containing global variables
+ * @param array $data Associative array containing one element:
+ * skinname => the skin name
+ * The odd calling convention is for backwards compatibility
+ */
+ static function makeGlobalVariablesScript( $data ) {
+ global $wgStylePath, $wgUser;
+ global $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgLang;
+ global $wgTitle, $wgCanonicalNamespaceNames, $wgOut, $wgArticle;
+ global $wgBreakFrames;
+
+ $ns = $wgTitle->getNamespace();
+ $nsname = isset( $wgCanonicalNamespaceNames[ $ns ] ) ? $wgCanonicalNamespaceNames[ $ns ] : $wgTitle->getNsText();
+
+ $vars = array(
+ 'skin' => $data['skinname'],
+ 'stylepath' => $wgStylePath,
+ 'wgArticlePath' => $wgArticlePath,
+ 'wgScriptPath' => $wgScriptPath,
+ 'wgServer' => $wgServer,
+ 'wgCanonicalNamespace' => $nsname,
+ 'wgCanonicalSpecialPageName' => SpecialPage::resolveAlias( $wgTitle->getDBKey() ),
+ 'wgNamespaceNumber' => $wgTitle->getNamespace(),
+ 'wgPageName' => $wgTitle->getPrefixedDBKey(),
+ 'wgTitle' => $wgTitle->getText(),
+ 'wgArticleId' => $wgTitle->getArticleId(),
+ 'wgIsArticle' => $wgOut->isArticle(),
+ 'wgUserName' => $wgUser->isAnon() ? NULL : $wgUser->getName(),
+ 'wgUserLanguage' => $wgLang->getCode(),
+ 'wgContentLanguage' => $wgContLang->getCode(),
+ 'wgBreakFrames' => $wgBreakFrames,
+ 'wgCurRevisionId' => isset( $wgArticle ) ? $wgArticle->getLatest() : 0,
+ );
+
+ return self::makeVariablesScript( $vars );
+ }
+
+ function getHeadScripts() {
+ global $wgStylePath, $wgUser, $wgAllowUserJs, $wgJsMimeType, $wgStyleVersion;
+
+ $r = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) );
+
+ $r .= "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/wikibits.js?$wgStyleVersion\"></script>\n";
+ global $wgUseSiteJs;
+ if ($wgUseSiteJs) {
+ if ($wgUser->isLoggedIn()) {
+ $r .= "<script type=\"$wgJsMimeType\" src=\"".htmlspecialchars(self::makeUrl('-','action=raw&smaxage=0&gen=js'))."\"><!-- site js --></script>\n";
+ } else {
+ $r .= "<script type=\"$wgJsMimeType\" src=\"".htmlspecialchars(self::makeUrl('-','action=raw&gen=js'))."\"><!-- site js --></script>\n";
+ }
+ }
+ if( $wgAllowUserJs && $wgUser->isLoggedIn() ) {
+ $userpage = $wgUser->getUserPage();
+ $userjs = htmlspecialchars( self::makeUrl(
+ $userpage->getPrefixedText().'/'.$this->getSkinName().'.js',
+ 'action=raw&ctype='.$wgJsMimeType));
+ $r .= '<script type="'.$wgJsMimeType.'" src="'.$userjs."\"></script>\n";
+ }
+ return $r;
+ }
+
+ /**
+ * To make it harder for someone to slip a user a fake
+ * user-JavaScript or user-CSS preview, a random token
+ * is associated with the login session. If it's not
+ * passed back with the preview request, we won't render
+ * the code.
+ *
+ * @param string $action
+ * @return bool
+ * @private
+ */
+ function userCanPreview( $action ) {
+ global $wgTitle, $wgRequest, $wgUser;
+
+ if( $action != 'submit' )
+ return false;
+ if( !$wgRequest->wasPosted() )
+ return false;
+ if( !$wgTitle->userCanEditCssJsSubpage() )
+ return false;
+ return $wgUser->matchEditToken(
+ $wgRequest->getVal( 'wpEditToken' ) );
+ }
+
+ # get the user/site-specific stylesheet, SkinTemplate loads via RawPage.php (settings are cached that way)
+ function getUserStylesheet() {
+ global $wgStylePath, $wgRequest, $wgContLang, $wgSquidMaxage, $wgStyleVersion;
+ $sheet = $this->getStylesheet();
+ $s = "@import \"$wgStylePath/common/common.css?$wgStyleVersion\";\n";
+ $s .= "@import \"$wgStylePath/$sheet?$wgStyleVersion\";\n";
+ if($wgContLang->isRTL()) $s .= "@import \"$wgStylePath/common/common_rtl.css?$wgStyleVersion\";\n";
+
+ $query = "usemsgcache=yes&action=raw&ctype=text/css&smaxage=$wgSquidMaxage";
+ $s .= '@import "' . self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) . "\";\n" .
+ '@import "' . self::makeNSUrl( ucfirst( $this->getSkinName() . '.css' ), $query, NS_MEDIAWIKI ) . "\";\n";
+
+ $s .= $this->doGetUserStyles();
+ return $s."\n";
+ }
+
+ /**
+ * This returns MediaWiki:Common.js. For some bizarre reason, it does
+ * *not* return any custom user JS from user subpages. Huh?
+ *
+ * @return string
+ */
+ function getUserJs() {
+ $fname = 'Skin::getUserJs';
+ wfProfileIn( __METHOD__ );
+
+ global $wgStylePath;
+ $s = "/* generated javascript */\n";
+ $s .= "var skin = '{$this->skinname}';\nvar stylepath = '{$wgStylePath}';";
+ $s .= "\n\n/* MediaWiki:Common.js */\n";
+ $commonJs = wfMsgForContent('common.js');
+ if ( !wfEmptyMsg ( 'common.js', $commonJs ) ) {
+ $s .= $commonJs;
+ }
+
+ global $wgUseAjax, $wgAjaxWatch;
+ if($wgUseAjax && $wgAjaxWatch) {
+ $s .= "
+
+/* AJAX (un)watch (see /skins/common/ajaxwatch.js) */
+var wgAjaxWatch = {
+ watchMsg: '". str_replace( array("'", "\n"), array("\\'", ' '), wfMsgExt( 'watch', array() ) )."',
+ unwatchMsg: '". str_replace( array("'", "\n"), array("\\'", ' '), wfMsgExt( 'unwatch', array() ) )."',
+ watchingMsg: '". str_replace( array("'", "\n"), array("\\'", ' '), wfMsgExt( 'watching', array() ) )."',
+ unwatchingMsg: '". str_replace( array("'", "\n"), array("\\'", ' '), wfMsgExt( 'unwatching', array() ) )."'
+};";
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $s;
+ }
+
+ /**
+ * Return html code that include User stylesheets
+ */
+ function getUserStyles() {
+ $s = "<style type='text/css'>\n";
+ $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
+ $s .= $this->getUserStylesheet();
+ $s .= "/*]]>*/ /* */\n";
+ $s .= "</style>\n";
+ return $s;
+ }
+
+ /**
+ * Some styles that are set by user through the user settings interface.
+ */
+ function doGetUserStyles() {
+ global $wgUser, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
+
+ $s = '';
+
+ if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { # logged in
+ if($wgTitle->isCssSubpage() && $this->userCanPreview( $wgRequest->getText( 'action' ) ) ) {
+ $s .= $wgRequest->getText('wpTextbox1');
+ } else {
+ $userpage = $wgUser->getUserPage();
+ $s.= '@import "'.self::makeUrl(
+ $userpage->getPrefixedText().'/'.$this->getSkinName().'.css',
+ 'action=raw&ctype=text/css').'";'."\n";
+ }
+ }
+
+ return $s . $this->reallyDoGetUserStyles();
+ }
+
+ function reallyDoGetUserStyles() {
+ global $wgUser;
+ $s = '';
+ if (($undopt = $wgUser->getOption("underline")) != 2) {
+ $underline = $undopt ? 'underline' : 'none';
+ $s .= "a { text-decoration: $underline; }\n";
+ }
+ if( $wgUser->getOption( 'highlightbroken' ) ) {
+ $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
+ } else {
+ $s .= <<<END
+a.new, #quickbar a.new,
+a.stub, #quickbar a.stub {
+ color: inherit;
+ text-decoration: inherit;
+}
+a.new:after, #quickbar a.new:after {
+ content: "?";
+ color: #CC2200;
+ text-decoration: $underline;
+}
+a.stub:after, #quickbar a.stub:after {
+ content: "!";
+ color: #772233;
+ text-decoration: $underline;
+}
+END;
+ }
+ if( $wgUser->getOption( 'justify' ) ) {
+ $s .= "#article, #bodyContent { text-align: justify; }\n";
+ }
+ if( !$wgUser->getOption( 'showtoc' ) ) {
+ $s .= "#toc { display: none; }\n";
+ }
+ if( !$wgUser->getOption( 'editsection' ) ) {
+ $s .= ".editsection { display: none; }\n";
+ }
+ return $s;
+ }
+
+ function getBodyOptions() {
+ global $wgUser, $wgTitle, $wgOut, $wgRequest, $wgContLang;
+
+ extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
+
+ if ( 0 != $wgTitle->getNamespace() ) {
+ $a = array( 'bgcolor' => '#ffffec' );
+ }
+ else $a = array( 'bgcolor' => '#FFFFFF' );
+ if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
+ $wgTitle->userCanEdit() ) {
+ $s = $wgTitle->getFullURL( $this->editUrlOptions() );
+ $s = 'document.location = "' .wfEscapeJSString( $s ) .'";';
+ $a += array ('ondblclick' => $s);
+
+ }
+ $a['onload'] = $wgOut->getOnloadHandler();
+ if( $wgUser->getOption( 'editsectiononrightclick' ) ) {
+ if( $a['onload'] != '' ) {
+ $a['onload'] .= ';';
+ }
+ $a['onload'] .= 'setupRightClickEdit()';
+ }
+ $a['class'] = 'ns-'.$wgTitle->getNamespace().' '.($wgContLang->isRTL() ? "rtl" : "ltr").
+ ' '.Sanitizer::escapeId( 'page-'.$wgTitle->getPrefixedText() );
+ return $a;
+ }
+
+ /**
+ * URL to the logo
+ */
+ function getLogo() {
+ global $wgLogo;
+ return $wgLogo;
+ }
+
+ /**
+ * This will be called immediately after the <body> tag. Split into
+ * two functions to make it easier to subclass.
+ */
+ function beforeContent() {
+ return $this->doBeforeContent();
+ }
+
+ function doBeforeContent() {
+ global $wgContLang;
+ $fname = 'Skin::doBeforeContent';
+ wfProfileIn( $fname );
+
+ $s = '';
+ $qb = $this->qbSetting();
+
+ if( $langlinks = $this->otherLanguages() ) {
+ $rows = 2;
+ $borderhack = '';
+ } else {
+ $rows = 1;
+ $langlinks = false;
+ $borderhack = 'class="top"';
+ }
+
+ $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
+ "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
+
+ $shove = ($qb != 0);
+ $left = ($qb == 1 || $qb == 3);
+ if($wgContLang->isRTL()) $left = !$left;
+
+ if ( !$shove ) {
+ $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
+ $this->logoText() . '</td>';
+ } elseif( $left ) {
+ $s .= $this->getQuickbarCompensator( $rows );
+ }
+ $l = $wgContLang->isRTL() ? 'right' : 'left';
+ $s .= "<td {$borderhack} align='$l' valign='top'>\n";
+
+ $s .= $this->topLinks() ;
+ $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
+
+ $r = $wgContLang->isRTL() ? "left" : "right";
+ $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
+ $s .= $this->nameAndLogin();
+ $s .= "\n<br />" . $this->searchForm() . "</td>";
+
+ if ( $langlinks ) {
+ $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
+ }
+
+ if ( $shove && !$left ) { # Right
+ $s .= $this->getQuickbarCompensator( $rows );
+ }
+ $s .= "</tr>\n</table>\n</div>\n";
+ $s .= "\n<div id='article'>\n";
+
+ $notice = wfGetSiteNotice();
+ if( $notice ) {
+ $s .= "\n<div id='siteNotice'>$notice</div>\n";
+ }
+ $s .= $this->pageTitle();
+ $s .= $this->pageSubtitle() ;
+ $s .= $this->getCategories();
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+
+ function getCategoryLinks () {
+ global $wgOut, $wgTitle, $wgUseCategoryBrowser;
+ global $wgContLang;
+
+ if( count( $wgOut->mCategoryLinks ) == 0 ) return '';
+
+ # Separator
+ $sep = wfMsgHtml( 'catseparator' );
+
+ // Use Unicode bidi embedding override characters,
+ // to make sure links don't smash each other up in ugly ways.
+ $dir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
+ $embed = "<span dir='$dir'>";
+ $pop = '</span>';
+ $t = $embed . implode ( "{$pop} {$sep} {$embed}" , $wgOut->mCategoryLinks ) . $pop;
+
+ $msg = wfMsgExt( 'pagecategories', array( 'parsemag', 'escape' ), count( $wgOut->mCategoryLinks ) );
+ $s = $this->makeLinkObj( Title::newFromText( wfMsgForContent('pagecategorieslink') ), $msg )
+ . ': ' . $t;
+
+ # optional 'dmoz-like' category browser. Will be shown under the list
+ # of categories an article belong to
+ if($wgUseCategoryBrowser) {
+ $s .= '<br /><hr />';
+
+ # get a big array of the parents tree
+ $parenttree = $wgTitle->getParentCategoryTree();
+ # Skin object passed by reference cause it can not be
+ # accessed under the method subfunction drawCategoryBrowser
+ $tempout = explode("\n", Skin::drawCategoryBrowser($parenttree, $this) );
+ # Clean out bogus first entry and sort them
+ unset($tempout[0]);
+ asort($tempout);
+ # Output one per line
+ $s .= implode("<br />\n", $tempout);
+ }
+
+ return $s;
+ }
+
+ /** Render the array as a serie of links.
+ * @param $tree Array: categories tree returned by Title::getParentCategoryTree
+ * @param &skin Object: skin passed by reference
+ * @return String separated by &gt;, terminate with "\n"
+ */
+ function drawCategoryBrowser($tree, &$skin) {
+ $return = '';
+ foreach ($tree as $element => $parent) {
+ if (empty($parent)) {
+ # element start a new list
+ $return .= "\n";
+ } else {
+ # grab the others elements
+ $return .= Skin::drawCategoryBrowser($parent, $skin) . ' &gt; ';
+ }
+ # add our current element to the list
+ $eltitle = Title::NewFromText($element);
+ $return .= $skin->makeLinkObj( $eltitle, $eltitle->getText() ) ;
+ }
+ return $return;
+ }
+
+ function getCategories() {
+ $catlinks=$this->getCategoryLinks();
+ if(!empty($catlinks)) {
+ return "<p class='catlinks'>{$catlinks}</p>";
+ }
+ }
+
+ function getQuickbarCompensator( $rows = 1 ) {
+ return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
+ }
+
+ /**
+ * This gets called shortly before the \</body\> tag.
+ * @return String HTML to be put before \</body\>
+ */
+ function afterContent() {
+ $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
+ return $printfooter . $this->doAfterContent();
+ }
+
+ /**
+ * This gets called shortly before the \</body\> tag.
+ * @return String HTML-wrapped JS code to be put before \</body\>
+ */
+ function bottomScripts() {
+ global $wgJsMimeType;
+ return "\n\t\t<script type=\"$wgJsMimeType\">if (window.runOnloadHook) runOnloadHook();</script>\n";
+ }
+
+ /** @return string Retrievied from HTML text */
+ function printSource() {
+ global $wgTitle;
+ $url = htmlspecialchars( $wgTitle->getFullURL() );
+ return wfMsg( 'retrievedfrom', '<a href="'.$url.'">'.$url.'</a>' );
+ }
+
+ function printFooter() {
+ return "<p>" . $this->printSource() .
+ "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
+ }
+
+ /** overloaded by derived classes */
+ function doAfterContent() { }
+
+ function pageTitleLinks() {
+ global $wgOut, $wgTitle, $wgUser, $wgRequest;
+
+ $oldid = $wgRequest->getVal( 'oldid' );
+ $diff = $wgRequest->getVal( 'diff' );
+ $action = $wgRequest->getText( 'action' );
+
+ $s = $this->printableLink();
+ $disclaimer = $this->disclaimerLink(); # may be empty
+ if( $disclaimer ) {
+ $s .= ' | ' . $disclaimer;
+ }
+ $privacy = $this->privacyLink(); # may be empty too
+ if( $privacy ) {
+ $s .= ' | ' . $privacy;
+ }
+
+ if ( $wgOut->isArticleRelated() ) {
+ if ( $wgTitle->getNamespace() == NS_IMAGE ) {
+ $name = $wgTitle->getDBkey();
+ $image = new Image( $wgTitle );
+ if( $image->exists() ) {
+ $link = htmlspecialchars( $image->getURL() );
+ $style = $this->getInternalLinkAttributes( $link, $name );
+ $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
+ }
+ }
+ }
+ if ( 'history' == $action || isset( $diff ) || isset( $oldid ) ) {
+ $s .= ' | ' . $this->makeKnownLinkObj( $wgTitle,
+ wfMsg( 'currentrev' ) );
+ }
+
+ if ( $wgUser->getNewtalk() ) {
+ # do not show "You have new messages" text when we are viewing our
+ # own talk page
+ if( !$wgTitle->equals( $wgUser->getTalkPage() ) ) {
+ $tl = $this->makeKnownLinkObj( $wgUser->getTalkPage(), wfMsgHtml( 'newmessageslink' ), 'redirect=no' );
+ $dl = $this->makeKnownLinkObj( $wgUser->getTalkPage(), wfMsgHtml( 'newmessagesdifflink' ), 'diff=cur' );
+ $s.= ' | <strong>'. wfMsg( 'youhavenewmessages', $tl, $dl ) . '</strong>';
+ # disable caching
+ $wgOut->setSquidMaxage(0);
+ $wgOut->enableClientCache(false);
+ }
+ }
+
+ $undelete = $this->getUndeleteLink();
+ if( !empty( $undelete ) ) {
+ $s .= ' | '.$undelete;
+ }
+ return $s;
+ }
+
+ function getUndeleteLink() {
+ global $wgUser, $wgTitle, $wgContLang, $action;
+ if( $wgUser->isAllowed( 'deletedhistory' ) &&
+ (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
+ ($n = $wgTitle->isDeleted() ) )
+ {
+ if ( $wgUser->isAllowed( 'delete' ) ) {
+ $msg = 'thisisdeleted';
+ } else {
+ $msg = 'viewdeleted';
+ }
+ return wfMsg( $msg,
+ $this->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Undelete', $wgTitle->getPrefixedDBkey() ),
+ wfMsgExt( 'restorelink', array( 'parsemag', 'escape' ), $n ) ) );
+ }
+ return '';
+ }
+
+ function printableLink() {
+ global $wgOut, $wgFeedClasses, $wgRequest;
+
+ $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
+
+ $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
+ if( $wgOut->isSyndicated() ) {
+ foreach( $wgFeedClasses as $format => $class ) {
+ $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
+ $s .= " | <a href=\"$feedurl\">{$format}</a>";
+ }
+ }
+ return $s;
+ }
+
+ function pageTitle() {
+ global $wgOut;
+ $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
+ return $s;
+ }
+
+ function pageSubtitle() {
+ global $wgOut;
+
+ $sub = $wgOut->getSubtitle();
+ if ( '' == $sub ) {
+ global $wgExtraSubtitle;
+ $sub = wfMsg( 'tagline' ) . $wgExtraSubtitle;
+ }
+ $subpages = $this->subPageSubtitle();
+ $sub .= !empty($subpages)?"</p><p class='subpages'>$subpages":'';
+ $s = "<p class='subtitle'>{$sub}</p>\n";
+ return $s;
+ }
+
+ function subPageSubtitle() {
+ global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
+ $subpages = '';
+ if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
+ $ptext=$wgTitle->getPrefixedText();
+ if(preg_match('/\//',$ptext)) {
+ $links = explode('/',$ptext);
+ $c = 0;
+ $growinglink = '';
+ foreach($links as $link) {
+ $c++;
+ if ($c<count($links)) {
+ $growinglink .= $link;
+ $getlink = $this->makeLink( $growinglink, htmlspecialchars( $link ) );
+ if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
+ if ($c>1) {
+ $subpages .= ' | ';
+ } else {
+ $subpages .= '&lt; ';
+ }
+ $subpages .= $getlink;
+ $growinglink .= '/';
+ }
+ }
+ }
+ }
+ return $subpages;
+ }
+
+ function nameAndLogin() {
+ global $wgUser, $wgTitle, $wgLang, $wgContLang, $wgShowIPinHeader;
+
+ $lo = $wgContLang->specialPage( 'Userlogout' );
+
+ $s = '';
+ if ( $wgUser->isAnon() ) {
+ if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
+ $n = wfGetIP();
+
+ $tl = $this->makeKnownLinkObj( $wgUser->getTalkPage(),
+ $wgLang->getNsText( NS_TALK ) );
+
+ $s .= $n . ' ('.$tl.')';
+ } else {
+ $s .= wfMsg('notloggedin');
+ }
+
+ $rt = $wgTitle->getPrefixedURL();
+ if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
+ $q = '';
+ } else { $q = "returnto={$rt}"; }
+
+ $s .= "\n<br />" . $this->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Userlogin' ),
+ wfMsg( 'login' ), $q );
+ } else {
+ $n = $wgUser->getName();
+ $rt = $wgTitle->getPrefixedURL();
+ $tl = $this->makeKnownLinkObj( $wgUser->getTalkPage(),
+ $wgLang->getNsText( NS_TALK ) );
+
+ $tl = " ({$tl})";
+
+ $s .= $this->makeKnownLinkObj( $wgUser->getUserPage(),
+ $n ) . "{$tl}<br />" .
+ $this->makeKnownLinkObj( SpecialPage::getTitleFor( 'Userlogout' ), wfMsg( 'logout' ),
+ "returnto={$rt}" ) . ' | ' .
+ $this->specialLink( 'preferences' );
+ }
+ $s .= ' | ' . $this->makeKnownLink( wfMsgForContent( 'helppage' ),
+ wfMsg( 'help' ) );
+
+ return $s;
+ }
+
+ function getSearchLink() {
+ $searchPage = SpecialPage::getTitleFor( 'Search' );
+ return $searchPage->getLocalURL();
+ }
+
+ function escapeSearchLink() {
+ return htmlspecialchars( $this->getSearchLink() );
+ }
+
+ function searchForm() {
+ global $wgRequest;
+ $search = $wgRequest->getText( 'search' );
+
+ $s = '<form name="search" class="inline" method="post" action="'
+ . $this->escapeSearchLink() . "\">\n"
+ . '<input type="text" name="search" size="19" value="'
+ . htmlspecialchars(substr($search,0,256)) . "\" />\n"
+ . '<input type="submit" name="go" value="' . wfMsg ('searcharticle') . '" />&nbsp;'
+ . '<input type="submit" name="fulltext" value="' . wfMsg ('searchbutton') . "\" />\n</form>";
+
+ return $s;
+ }
+
+ function topLinks() {
+ global $wgOut;
+ $sep = " |\n";
+
+ $s = $this->mainPageLink() . $sep
+ . $this->specialLink( 'recentchanges' );
+
+ if ( $wgOut->isArticleRelated() ) {
+ $s .= $sep . $this->editThisPage()
+ . $sep . $this->historyLink();
+ }
+ # Many people don't like this dropdown box
+ #$s .= $sep . $this->specialPagesList();
+
+ $s .= $this->variantLinks();
+
+ $s .= $this->extensionTabLinks();
+
+ return $s;
+ }
+
+ /**
+ * Compatibility for extensions adding functionality through tabs.
+ * Eventually these old skins should be replaced with SkinTemplate-based
+ * versions, sigh...
+ * @return string
+ */
+ function extensionTabLinks() {
+ $tabs = array();
+ $s = '';
+ wfRunHooks( 'SkinTemplateTabs', array( $this, &$tabs ) );
+ foreach( $tabs as $tab ) {
+ $s .= ' | ' . Xml::element( 'a',
+ array( 'href' => $tab['href'] ),
+ $tab['text'] );
+ }
+ return $s;
+ }
+
+ /**
+ * Language/charset variant links for classic-style skins
+ * @return string
+ */
+ function variantLinks() {
+ $s = '';
+ /* show links to different language variants */
+ global $wgDisableLangConversion, $wgContLang, $wgTitle;
+ $variants = $wgContLang->getVariants();
+ if( !$wgDisableLangConversion && sizeof( $variants ) > 1 ) {
+ foreach( $variants as $code ) {
+ $varname = $wgContLang->getVariantname( $code );
+ if( $varname == 'disable' )
+ continue;
+ $s .= ' | <a href="' . $wgTitle->escapeLocalUrl( 'variant=' . $code ) . '">' . htmlspecialchars( $varname ) . '</a>';
+ }
+ }
+ return $s;
+ }
+
+ function bottomLinks() {
+ global $wgOut, $wgUser, $wgTitle, $wgUseTrackbacks;
+ $sep = " |\n";
+
+ $s = '';
+ if ( $wgOut->isArticleRelated() ) {
+ $s .= '<strong>' . $this->editThisPage() . '</strong>';
+ if ( $wgUser->isLoggedIn() ) {
+ $s .= $sep . $this->watchThisPage();
+ }
+ $s .= $sep . $this->talkLink()
+ . $sep . $this->historyLink()
+ . $sep . $this->whatLinksHere()
+ . $sep . $this->watchPageLinksLink();
+
+ if ($wgUseTrackbacks)
+ $s .= $sep . $this->trackbackLink();
+
+ if ( $wgTitle->getNamespace() == NS_USER
+ || $wgTitle->getNamespace() == NS_USER_TALK )
+
+ {
+ $id=User::idFromName($wgTitle->getText());
+ $ip=User::isIP($wgTitle->getText());
+
+ if($id || $ip) { # both anons and non-anons have contri list
+ $s .= $sep . $this->userContribsLink();
+ }
+ if( $this->showEmailUser( $id ) ) {
+ $s .= $sep . $this->emailUserLink();
+ }
+ }
+ if ( $wgTitle->getArticleId() ) {
+ $s .= "\n<br />";
+ if($wgUser->isAllowed('delete')) { $s .= $this->deleteThisPage(); }
+ if($wgUser->isAllowed('protect')) { $s .= $sep . $this->protectThisPage(); }
+ if($wgUser->isAllowed('move')) { $s .= $sep . $this->moveThisPage(); }
+ }
+ $s .= "<br />\n" . $this->otherLanguages();
+ }
+ return $s;
+ }
+
+ function pageStats() {
+ global $wgOut, $wgLang, $wgArticle, $wgRequest, $wgUser;
+ global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax, $wgTitle, $wgPageShowWatchingUsers;
+
+ $oldid = $wgRequest->getVal( 'oldid' );
+ $diff = $wgRequest->getVal( 'diff' );
+ if ( ! $wgOut->isArticle() ) { return ''; }
+ if ( isset( $oldid ) || isset( $diff ) ) { return ''; }
+ if ( 0 == $wgArticle->getID() ) { return ''; }
+
+ $s = '';
+ if ( !$wgDisableCounters ) {
+ $count = $wgLang->formatNum( $wgArticle->getCount() );
+ if ( $count ) {
+ $s = wfMsgExt( 'viewcount', array( 'parseinline' ), $count );
+ }
+ }
+
+ if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
+ require_once('Credits.php');
+ $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
+ } else {
+ $s .= $this->lastModified();
+ }
+
+ if ($wgPageShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' )) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $watchlist = $dbr->tableName( 'watchlist' );
+ $sql = "SELECT COUNT(*) AS n FROM $watchlist
+ WHERE wl_title='" . $dbr->strencode($wgTitle->getDBKey()) .
+ "' AND wl_namespace=" . $wgTitle->getNamespace() ;
+ $res = $dbr->query( $sql, 'Skin::pageStats');
+ $x = $dbr->fetchObject( $res );
+ $s .= ' ' . wfMsg('number_of_watching_users_pageview', $x->n );
+ }
+
+ return $s . ' ' . $this->getCopyright();
+ }
+
+ function getCopyright( $type = 'detect' ) {
+ global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
+
+ if ( $type == 'detect' ) {
+ $oldid = $wgRequest->getVal( 'oldid' );
+ $diff = $wgRequest->getVal( 'diff' );
+
+ if ( !is_null( $oldid ) && is_null( $diff ) && wfMsgForContent( 'history_copyright' ) !== '-' ) {
+ $type = 'history';
+ } else {
+ $type = 'normal';
+ }
+ }
+
+ if ( $type == 'history' ) {
+ $msg = 'history_copyright';
+ } else {
+ $msg = 'copyright';
+ }
+
+ $out = '';
+ if( $wgRightsPage ) {
+ $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
+ } elseif( $wgRightsUrl ) {
+ $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
+ } else {
+ # Give up now
+ return $out;
+ }
+ $out .= wfMsgForContent( $msg, $link );
+ return $out;
+ }
+
+ function getCopyrightIcon() {
+ global $wgRightsUrl, $wgRightsText, $wgRightsIcon, $wgCopyrightIcon;
+ $out = '';
+ if ( isset( $wgCopyrightIcon ) && $wgCopyrightIcon ) {
+ $out = $wgCopyrightIcon;
+ } else if ( $wgRightsIcon ) {
+ $icon = htmlspecialchars( $wgRightsIcon );
+ if ( $wgRightsUrl ) {
+ $url = htmlspecialchars( $wgRightsUrl );
+ $out .= '<a href="'.$url.'">';
+ }
+ $text = htmlspecialchars( $wgRightsText );
+ $out .= "<img src=\"$icon\" alt='$text' />";
+ if ( $wgRightsUrl ) {
+ $out .= '</a>';
+ }
+ }
+ return $out;
+ }
+
+ function getPoweredBy() {
+ global $wgStylePath;
+ $url = htmlspecialchars( "$wgStylePath/common/images/poweredby_mediawiki_88x31.png" );
+ $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="Powered by MediaWiki" /></a>';
+ return $img;
+ }
+
+ function lastModified() {
+ global $wgLang, $wgArticle, $wgLoadBalancer;
+
+ $timestamp = $wgArticle->getTimestamp();
+ if ( $timestamp ) {
+ $d = $wgLang->date( $timestamp, true );
+ $t = $wgLang->time( $timestamp, true );
+ $s = ' ' . wfMsg( 'lastmodifiedat', $d, $t );
+ } else {
+ $s = '';
+ }
+ if ( $wgLoadBalancer->getLaggedSlaveMode() ) {
+ $s .= ' <strong>' . wfMsg( 'laggedslavemode' ) . '</strong>';
+ }
+ return $s;
+ }
+
+ function logoText( $align = '' ) {
+ if ( '' != $align ) { $a = " align='{$align}'"; }
+ else { $a = ''; }
+
+ $mp = wfMsg( 'mainpage' );
+ $mptitle = Title::newMainPage();
+ $url = ( is_object($mptitle) ? $mptitle->escapeLocalURL() : '' );
+
+ $logourl = $this->getLogo();
+ $s = "<a href='{$url}'><img{$a} src='{$logourl}' alt='[{$mp}]' /></a>";
+ return $s;
+ }
+
+ /**
+ * show a drop-down box of special pages
+ */
+ function specialPagesList() {
+ global $wgUser, $wgContLang, $wgServer, $wgRedirectScript;
+ $pages = array_merge( SpecialPage::getRegularPages(), SpecialPage::getRestrictedPages() );
+ foreach ( $pages as $name => $page ) {
+ $pages[$name] = $page->getDescription();
+ }
+
+ $go = wfMsg( 'go' );
+ $sp = wfMsg( 'specialpages' );
+ $spp = $wgContLang->specialPage( 'Specialpages' );
+
+ $s = '<form id="specialpages" method="get" class="inline" ' .
+ 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
+ $s .= "<select name=\"wpDropdown\">\n";
+ $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
+
+
+ foreach ( $pages as $name => $desc ) {
+ $p = $wgContLang->specialPage( $name );
+ $s .= "<option value=\"{$p}\">{$desc}</option>\n";
+ }
+ $s .= "</select>\n";
+ $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
+ $s .= "</form>\n";
+ return $s;
+ }
+
+ function mainPageLink() {
+ $s = $this->makeKnownLinkObj( Title::newMainPage(), wfMsg( 'mainpage' ) );
+ return $s;
+ }
+
+ function copyrightLink() {
+ $s = $this->makeKnownLink( wfMsgForContent( 'copyrightpage' ),
+ wfMsg( 'copyrightpagename' ) );
+ return $s;
+ }
+
+ function privacyLink() {
+ $privacy = wfMsg( 'privacy' );
+ if ($privacy == '-') {
+ return '';
+ } else {
+ return $this->makeKnownLink( wfMsgForContent( 'privacypage' ), $privacy);
+ }
+ }
+
+ function aboutLink() {
+ $s = $this->makeKnownLink( wfMsgForContent( 'aboutpage' ),
+ wfMsg( 'aboutsite' ) );
+ return $s;
+ }
+
+ function disclaimerLink() {
+ $disclaimers = wfMsg( 'disclaimers' );
+ if ($disclaimers == '-') {
+ return '';
+ } else {
+ return $this->makeKnownLink( wfMsgForContent( 'disclaimerpage' ),
+ $disclaimers );
+ }
+ }
+
+ function editThisPage() {
+ global $wgOut, $wgTitle;
+
+ if ( ! $wgOut->isArticleRelated() ) {
+ $s = wfMsg( 'protectedpage' );
+ } else {
+ if ( $wgTitle->userCanEdit() ) {
+ $t = wfMsg( 'editthispage' );
+ } else {
+ $t = wfMsg( 'viewsource' );
+ }
+
+ $s = $this->makeKnownLinkObj( $wgTitle, $t, $this->editUrlOptions() );
+ }
+ return $s;
+ }
+
+ /**
+ * Return URL options for the 'edit page' link.
+ * This may include an 'oldid' specifier, if the current page view is such.
+ *
+ * @return string
+ * @private
+ */
+ function editUrlOptions() {
+ global $wgArticle;
+
+ if( $this->mRevisionId && ! $wgArticle->isCurrent() ) {
+ return "action=edit&oldid=" . intval( $this->mRevisionId );
+ } else {
+ return "action=edit";
+ }
+ }
+
+ function deleteThisPage() {
+ global $wgUser, $wgTitle, $wgRequest;
+
+ $diff = $wgRequest->getVal( 'diff' );
+ if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isAllowed('delete') ) {
+ $t = wfMsg( 'deletethispage' );
+
+ $s = $this->makeKnownLinkObj( $wgTitle, $t, 'action=delete' );
+ } else {
+ $s = '';
+ }
+ return $s;
+ }
+
+ function protectThisPage() {
+ global $wgUser, $wgTitle, $wgRequest;
+
+ $diff = $wgRequest->getVal( 'diff' );
+ if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isAllowed('protect') ) {
+ if ( $wgTitle->isProtected() ) {
+ $t = wfMsg( 'unprotectthispage' );
+ $q = 'action=unprotect';
+ } else {
+ $t = wfMsg( 'protectthispage' );
+ $q = 'action=protect';
+ }
+ $s = $this->makeKnownLinkObj( $wgTitle, $t, $q );
+ } else {
+ $s = '';
+ }
+ return $s;
+ }
+
+ function watchThisPage() {
+ global $wgOut, $wgTitle;
+ ++$this->mWatchLinkNum;
+
+ if ( $wgOut->isArticleRelated() ) {
+ if ( $wgTitle->userIsWatching() ) {
+ $t = wfMsg( 'unwatchthispage' );
+ $q = 'action=unwatch';
+ $id = "mw-unwatch-link".$this->mWatchLinkNum;
+ } else {
+ $t = wfMsg( 'watchthispage' );
+ $q = 'action=watch';
+ $id = 'mw-watch-link'.$this->mWatchLinkNum;
+ }
+ $s = $this->makeKnownLinkObj( $wgTitle, $t, $q, '', '', " id=\"$id\"" );
+ } else {
+ $s = wfMsg( 'notanarticle' );
+ }
+ return $s;
+ }
+
+ function moveThisPage() {
+ global $wgTitle;
+
+ if ( $wgTitle->userCanMove() ) {
+ return $this->makeKnownLinkObj( SpecialPage::getTitleFor( 'Movepage' ),
+ wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
+ } else {
+ // no message if page is protected - would be redundant
+ return '';
+ }
+ }
+
+ function historyLink() {
+ global $wgTitle;
+
+ return $this->makeKnownLinkObj( $wgTitle,
+ wfMsg( 'history' ), 'action=history' );
+ }
+
+ function whatLinksHere() {
+ global $wgTitle;
+
+ return $this->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Whatlinkshere', $wgTitle->getPrefixedDBkey() ),
+ wfMsg( 'whatlinkshere' ) );
+ }
+
+ function userContribsLink() {
+ global $wgTitle;
+
+ return $this->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Contributions', $wgTitle->getDBkey() ),
+ wfMsg( 'contributions' ) );
+ }
+
+ function showEmailUser( $id ) {
+ global $wgEnableEmail, $wgEnableUserEmail, $wgUser;
+ return $wgEnableEmail &&
+ $wgEnableUserEmail &&
+ $wgUser->isLoggedIn() && # show only to signed in users
+ 0 != $id; # we can only email to non-anons ..
+# '' != $id->getEmail() && # who must have an email address stored ..
+# 0 != $id->getEmailauthenticationtimestamp() && # .. which is authenticated
+# 1 != $wgUser->getOption('disablemail'); # and not disabled
+ }
+
+ function emailUserLink() {
+ global $wgTitle;
+
+ return $this->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Emailuser', $wgTitle->getDBkey() ),
+ wfMsg( 'emailuser' ) );
+ }
+
+ function watchPageLinksLink() {
+ global $wgOut, $wgTitle;
+
+ if ( ! $wgOut->isArticleRelated() ) {
+ return '(' . wfMsg( 'notanarticle' ) . ')';
+ } else {
+ return $this->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Recentchangeslinked', $wgTitle->getPrefixedDBkey() ),
+ wfMsg( 'recentchangeslinked' ) );
+ }
+ }
+
+ function trackbackLink() {
+ global $wgTitle;
+
+ return "<a href=\"" . $wgTitle->trackbackURL() . "\">"
+ . wfMsg('trackbacklink') . "</a>";
+ }
+
+ function otherLanguages() {
+ global $wgOut, $wgContLang, $wgHideInterlanguageLinks;
+
+ if ( $wgHideInterlanguageLinks ) {
+ return '';
+ }
+
+ $a = $wgOut->getLanguageLinks();
+ if ( 0 == count( $a ) ) {
+ return '';
+ }
+
+ $s = wfMsg( 'otherlanguages' ) . ': ';
+ $first = true;
+ if($wgContLang->isRTL()) $s .= '<span dir="LTR">';
+ foreach( $a as $l ) {
+ if ( ! $first ) { $s .= ' | '; }
+ $first = false;
+
+ $nt = Title::newFromText( $l );
+ $url = $nt->escapeFullURL();
+ $text = $wgContLang->getLanguageName( $nt->getInterwiki() );
+
+ if ( '' == $text ) { $text = $l; }
+ $style = $this->getExternalLinkAttributes( $l, $text );
+ $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
+ }
+ if($wgContLang->isRTL()) $s .= '</span>';
+ return $s;
+ }
+
+ function bugReportsLink() {
+ $s = $this->makeKnownLink( wfMsgForContent( 'bugreportspage' ),
+ wfMsg( 'bugreports' ) );
+ return $s;
+ }
+
+ function dateLink() {
+ $t1 = Title::newFromText( gmdate( 'F j' ) );
+ $t2 = Title::newFromText( gmdate( 'Y' ) );
+
+ $id = $t1->getArticleID();
+
+ if ( 0 == $id ) {
+ $s = $this->makeBrokenLink( $t1->getText() );
+ } else {
+ $s = $this->makeKnownLink( $t1->getText() );
+ }
+ $s .= ', ';
+
+ $id = $t2->getArticleID();
+
+ if ( 0 == $id ) {
+ $s .= $this->makeBrokenLink( $t2->getText() );
+ } else {
+ $s .= $this->makeKnownLink( $t2->getText() );
+ }
+ return $s;
+ }
+
+ function talkLink() {
+ global $wgTitle;
+
+ if ( NS_SPECIAL == $wgTitle->getNamespace() ) {
+ # No discussion links for special pages
+ return '';
+ }
+
+ if( $wgTitle->isTalkPage() ) {
+ $link = $wgTitle->getSubjectPage();
+ switch( $link->getNamespace() ) {
+ case NS_MAIN:
+ $text = wfMsg( 'articlepage' );
+ break;
+ case NS_USER:
+ $text = wfMsg( 'userpage' );
+ break;
+ case NS_PROJECT:
+ $text = wfMsg( 'projectpage' );
+ break;
+ case NS_IMAGE:
+ $text = wfMsg( 'imagepage' );
+ break;
+ case NS_MEDIAWIKI:
+ $text = wfMsg( 'mediawikipage' );
+ break;
+ case NS_TEMPLATE:
+ $text = wfMsg( 'templatepage' );
+ break;
+ case NS_HELP:
+ $text = wfMsg( 'viewhelppage' );
+ break;
+ case NS_CATEGORY:
+ $text = wfMsg( 'categorypage' );
+ break;
+ default:
+ $text = wfMsg( 'articlepage' );
+ }
+ } else {
+ $link = $wgTitle->getTalkPage();
+ $text = wfMsg( 'talkpage' );
+ }
+
+ $s = $this->makeLinkObj( $link, $text );
+
+ return $s;
+ }
+
+ function commentLink() {
+ global $wgTitle, $wgOut;
+
+ if ( $wgTitle->getNamespace() == NS_SPECIAL ) {
+ return '';
+ }
+
+ # __NEWSECTIONLINK___ changes behaviour here
+ # If it's present, the link points to this page, otherwise
+ # it points to the talk page
+ if( $wgTitle->isTalkPage() ) {
+ $title =& $wgTitle;
+ } elseif( $wgOut->showNewSectionLink() ) {
+ $title =& $wgTitle;
+ } else {
+ $title =& $wgTitle->getTalkPage();
+ }
+
+ return $this->makeKnownLinkObj( $title, wfMsg( 'postcomment' ), 'action=edit&section=new' );
+ }
+
+ /* these are used extensively in SkinTemplate, but also some other places */
+ static function makeMainPageUrl( $urlaction = '' ) {
+ $title = Title::newMainPage();
+ self::checkTitle( $title, $name );
+ return $title->getLocalURL( $urlaction );
+ }
+
+ static function makeSpecialUrl( $name, $urlaction = '' ) {
+ $title = SpecialPage::getTitleFor( $name );
+ return $title->getLocalURL( $urlaction );
+ }
+
+ static function makeSpecialUrlSubpage( $name, $subpage, $urlaction = '' ) {
+ $title = SpecialPage::getSafeTitleFor( $name, $subpage );
+ return $title->getLocalURL( $urlaction );
+ }
+
+ static function makeI18nUrl( $name, $urlaction = '' ) {
+ $title = Title::newFromText( wfMsgForContent( $name ) );
+ self::checkTitle( $title, $name );
+ return $title->getLocalURL( $urlaction );
+ }
+
+ static function makeUrl( $name, $urlaction = '' ) {
+ $title = Title::newFromText( $name );
+ self::checkTitle( $title, $name );
+ return $title->getLocalURL( $urlaction );
+ }
+
+ # If url string starts with http, consider as external URL, else
+ # internal
+ static function makeInternalOrExternalUrl( $name ) {
+ if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $name ) ) {
+ return $name;
+ } else {
+ return self::makeUrl( $name );
+ }
+ }
+
+ # this can be passed the NS number as defined in Language.php
+ static function makeNSUrl( $name, $urlaction = '', $namespace = NS_MAIN ) {
+ $title = Title::makeTitleSafe( $namespace, $name );
+ self::checkTitle( $title, $name );
+ return $title->getLocalURL( $urlaction );
+ }
+
+ /* these return an array with the 'href' and boolean 'exists' */
+ static function makeUrlDetails( $name, $urlaction = '' ) {
+ $title = Title::newFromText( $name );
+ self::checkTitle( $title, $name );
+ return array(
+ 'href' => $title->getLocalURL( $urlaction ),
+ 'exists' => $title->getArticleID() != 0 ? true : false
+ );
+ }
+
+ /**
+ * Make URL details where the article exists (or at least it's convenient to think so)
+ */
+ static function makeKnownUrlDetails( $name, $urlaction = '' ) {
+ $title = Title::newFromText( $name );
+ self::checkTitle( $title, $name );
+ return array(
+ 'href' => $title->getLocalURL( $urlaction ),
+ 'exists' => true
+ );
+ }
+
+ # make sure we have some title to operate on
+ static function checkTitle( &$title, &$name ) {
+ if( !is_object( $title ) ) {
+ $title = Title::newFromText( $name );
+ if( !is_object( $title ) ) {
+ $title = Title::newFromText( '--error: link target missing--' );
+ }
+ }
+ }
+
+ /**
+ * Build an array that represents the sidebar(s), the navigation bar among them
+ *
+ * @return array
+ * @private
+ */
+ function buildSidebar() {
+ global $parserMemc, $wgEnableSidebarCache;
+ global $wgLang, $wgContLang;
+
+ $fname = 'SkinTemplate::buildSidebar';
+
+ wfProfileIn( $fname );
+
+ $key = wfMemcKey( 'sidebar' );
+ $cacheSidebar = $wgEnableSidebarCache &&
+ ($wgLang->getCode() == $wgContLang->getCode());
+
+ if ($cacheSidebar) {
+ $cachedsidebar = $parserMemc->get( $key );
+ if ($cachedsidebar!="") {
+ wfProfileOut($fname);
+ return $cachedsidebar;
+ }
+ }
+
+ $bar = array();
+ $lines = explode( "\n", wfMsgForContent( 'sidebar' ) );
+ foreach ($lines as $line) {
+ if (strpos($line, '*') !== 0)
+ continue;
+ if (strpos($line, '**') !== 0) {
+ $line = trim($line, '* ');
+ $heading = $line;
+ } else {
+ if (strpos($line, '|') !== false) { // sanity check
+ $line = explode( '|' , trim($line, '* '), 2 );
+ $link = wfMsgForContent( $line[0] );
+ if ($link == '-')
+ continue;
+ if (wfEmptyMsg($line[1], $text = wfMsg($line[1])))
+ $text = $line[1];
+ if (wfEmptyMsg($line[0], $link))
+ $link = $line[0];
+
+ if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $link ) ) {
+ $href = $link;
+ } else {
+ $title = Title::newFromText( $link );
+ if ( $title ) {
+ $title = $title->fixSpecialName();
+ $href = $title->getLocalURL();
+ } else {
+ $href = 'INVALID-TITLE';
+ }
+ }
+
+ $bar[$heading][] = array(
+ 'text' => $text,
+ 'href' => $href,
+ 'id' => 'n-' . strtr($line[1], ' ', '-'),
+ 'active' => false
+ );
+ } else { continue; }
+ }
+ }
+ if ($cacheSidebar)
+ $parserMemc->set( $key, $bar, 86400 );
+ wfProfileOut( $fname );
+ return $bar;
+ }
+}
+?>
diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php
new file mode 100644
index 000000000000..ff095477f7be
--- /dev/null
+++ b/includes/SkinTemplate.php
@@ -0,0 +1,1172 @@
+<?php
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+# 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
+
+/**
+ * Template-filler skin base class
+ * Formerly generic PHPTal (http://phptal.sourceforge.net/) skin
+ * Based on Brion's smarty skin
+ * Copyright (C) Gabriel Wicke -- http://www.aulinx.de/
+ *
+ * Todo: Needs some serious refactoring into functions that correspond
+ * to the computations individual esi snippets need. Most importantly no body
+ * parsing for most of those of course.
+ *
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+/**
+ * Wrapper object for MediaWiki's localization functions,
+ * to be passed to the template engine.
+ *
+ * @private
+ * @package MediaWiki
+ */
+class MediaWiki_I18N {
+ var $_context = array();
+
+ function set($varName, $value) {
+ $this->_context[$varName] = $value;
+ }
+
+ function translate($value) {
+ $fname = 'SkinTemplate-translate';
+ wfProfileIn( $fname );
+
+ // Hack for i18n:attributes in PHPTAL 1.0.0 dev version as of 2004-10-23
+ $value = preg_replace( '/^string:/', '', $value );
+
+ $value = wfMsg( $value );
+ // interpolate variables
+ $m = array();
+ while (preg_match('/\$([0-9]*?)/sm', $value, $m)) {
+ list($src, $var) = $m;
+ wfSuppressWarnings();
+ $varValue = $this->_context[$var];
+ wfRestoreWarnings();
+ $value = str_replace($src, $varValue, $value);
+ }
+ wfProfileOut( $fname );
+ return $value;
+ }
+}
+
+/**
+ *
+ * @package MediaWiki
+ */
+class SkinTemplate extends Skin {
+ /**#@+
+ * @private
+ */
+
+ /**
+ * Name of our skin, set in initPage()
+ * It probably need to be all lower case.
+ */
+ var $skinname;
+
+ /**
+ * Stylesheets set to use
+ * Sub directory in ./skins/ where various stylesheets are located
+ */
+ var $stylename;
+
+ /**
+ * For QuickTemplate, the name of the subclass which
+ * will actually fill the template.
+ */
+ var $template;
+
+ /**#@-*/
+
+ /**
+ * Setup the base parameters...
+ * Child classes should override this to set the name,
+ * style subdirectory, and template filler callback.
+ *
+ * @param OutputPage $out
+ */
+ function initPage( &$out ) {
+ parent::initPage( $out );
+ $this->skinname = 'monobook';
+ $this->stylename = 'monobook';
+ $this->template = 'QuickTemplate';
+ }
+
+ /**
+ * Create the template engine object; we feed it a bunch of data
+ * and eventually it spits out some HTML. Should have interface
+ * roughly equivalent to PHPTAL 0.7.
+ *
+ * @param string $callback (or file)
+ * @param string $repository subdirectory where we keep template files
+ * @param string $cache_dir
+ * @return object
+ * @private
+ */
+ function setupTemplate( $classname, $repository=false, $cache_dir=false ) {
+ return new $classname();
+ }
+
+ /**
+ * initialize various variables and generate the template
+ *
+ * @param OutputPage $out
+ * @public
+ */
+ function outputPage( &$out ) {
+ global $wgTitle, $wgArticle, $wgUser, $wgLang, $wgContLang, $wgOut;
+ global $wgScript, $wgStylePath, $wgContLanguageCode;
+ global $wgMimeType, $wgJsMimeType, $wgOutputEncoding, $wgRequest;
+ global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces;
+ global $wgDisableCounters, $wgLogo, $action, $wgFeedClasses, $wgHideInterlanguageLinks;
+ global $wgMaxCredits, $wgShowCreditsIfMax;
+ global $wgPageShowWatchingUsers;
+ global $wgUseTrackbacks;
+ global $wgArticlePath, $wgScriptPath, $wgServer, $wgLang, $wgCanonicalNamespaceNames;
+
+ $fname = 'SkinTemplate::outputPage';
+ wfProfileIn( $fname );
+
+ // Hook that allows last minute changes to the output page, e.g.
+ // adding of CSS or Javascript by extensions.
+ wfRunHooks( 'BeforePageDisplay', array( &$out ) );
+
+ $oldid = $wgRequest->getVal( 'oldid' );
+ $diff = $wgRequest->getVal( 'diff' );
+
+ wfProfileIn( "$fname-init" );
+ $this->initPage( $out );
+
+ $this->mTitle =& $wgTitle;
+ $this->mUser =& $wgUser;
+
+ $tpl = $this->setupTemplate( $this->template, 'skins' );
+
+ #if ( $wgUseDatabaseMessages ) { // uncomment this to fall back to GetText
+ $tpl->setTranslator(new MediaWiki_I18N());
+ #}
+ wfProfileOut( "$fname-init" );
+
+ wfProfileIn( "$fname-stuff" );
+ $this->thispage = $this->mTitle->getPrefixedDbKey();
+ $this->thisurl = $this->mTitle->getPrefixedURL();
+ $this->loggedin = $wgUser->isLoggedIn();
+ $this->iscontent = ($this->mTitle->getNamespace() != NS_SPECIAL );
+ $this->iseditable = ($this->iscontent and !($action == 'edit' or $action == 'submit'));
+ $this->username = $wgUser->getName();
+ $userPage = $wgUser->getUserPage();
+ $this->userpage = $userPage->getPrefixedText();
+
+ if ( $wgUser->isLoggedIn() || $this->showIPinHeader() ) {
+ $this->userpageUrlDetails = self::makeUrlDetails( $this->userpage );
+ } else {
+ # This won't be used in the standard skins, but we define it to preserve the interface
+ # To save time, we check for existence
+ $this->userpageUrlDetails = self::makeKnownUrlDetails( $this->userpage );
+ }
+
+ $this->usercss = $this->userjs = $this->userjsprev = false;
+ $this->setupUserCss();
+ $this->setupUserJs();
+ $this->titletxt = $this->mTitle->getPrefixedText();
+ wfProfileOut( "$fname-stuff" );
+
+ wfProfileIn( "$fname-stuff2" );
+ $tpl->set( 'title', $wgOut->getPageTitle() );
+ $tpl->set( 'pagetitle', $wgOut->getHTMLTitle() );
+ $tpl->set( 'displaytitle', $wgOut->mPageLinkTitle );
+ $tpl->set( 'pageclass', Sanitizer::escapeClass( 'page-'.$wgTitle->getPrefixedText() ) );
+
+ $nsname = isset( $wgCanonicalNamespaceNames[ $this->mTitle->getNamespace() ] ) ?
+ $wgCanonicalNamespaceNames[ $this->mTitle->getNamespace() ] :
+ $this->mTitle->getNsText();
+
+ $tpl->set( 'nscanonical', $nsname );
+ $tpl->set( 'nsnumber', $this->mTitle->getNamespace() );
+ $tpl->set( 'titleprefixeddbkey', $this->mTitle->getPrefixedDBKey() );
+ $tpl->set( 'titletext', $this->mTitle->getText() );
+ $tpl->set( 'articleid', $this->mTitle->getArticleId() );
+ $tpl->set( 'currevisionid', isset( $wgArticle ) ? $wgArticle->getLatest() : 0 );
+
+ $tpl->set( 'isarticle', $wgOut->isArticle() );
+
+ $tpl->setRef( "thispage", $this->thispage );
+ $subpagestr = $this->subPageSubtitle();
+ $tpl->set(
+ 'subtitle', !empty($subpagestr)?
+ '<span class="subpages">'.$subpagestr.'</span>'.$out->getSubtitle():
+ $out->getSubtitle()
+ );
+ $undelete = $this->getUndeleteLink();
+ $tpl->set(
+ "undelete", !empty($undelete)?
+ '<span class="subpages">'.$undelete.'</span>':
+ ''
+ );
+
+ $tpl->set( 'catlinks', $this->getCategories());
+ if( $wgOut->isSyndicated() ) {
+ $feeds = array();
+ foreach( $wgFeedClasses as $format => $class ) {
+ $linktext = $format;
+ if ( $format == "atom" ) {
+ $linktext = wfMsg( 'feed-atom' );
+ } else if ( $format == "rss" ) {
+ $linktext = wfMsg( 'feed-rss' );
+ }
+ $feeds[$format] = array(
+ 'text' => $linktext,
+ 'href' => $wgRequest->appendQuery( "feed=$format" )
+ );
+ }
+ $tpl->setRef( 'feeds', $feeds );
+ } else {
+ $tpl->set( 'feeds', false );
+ }
+ if ($wgUseTrackbacks && $out->isArticleRelated()) {
+ $tpl->set( 'trackbackhtml', $wgTitle->trackbackRDF() );
+ } else {
+ $tpl->set( 'trackbackhtml', null );
+ }
+
+ $tpl->setRef( 'xhtmldefaultnamespace', $wgXhtmlDefaultNamespace );
+ $tpl->set( 'xhtmlnamespaces', $wgXhtmlNamespaces );
+ $tpl->setRef( 'mimetype', $wgMimeType );
+ $tpl->setRef( 'jsmimetype', $wgJsMimeType );
+ $tpl->setRef( 'charset', $wgOutputEncoding );
+ $tpl->set( 'headlinks', $out->getHeadLinks() );
+ $tpl->set('headscripts', $out->getScript() );
+ $tpl->setRef( 'wgScript', $wgScript );
+ $tpl->setRef( 'skinname', $this->skinname );
+ $tpl->set( 'skinclass', get_class( $this ) );
+ $tpl->setRef( 'stylename', $this->stylename );
+ $tpl->set( 'printable', $wgRequest->getBool( 'printable' ) );
+ $tpl->setRef( 'loggedin', $this->loggedin );
+ $tpl->set('nsclass', 'ns-'.$this->mTitle->getNamespace());
+ $tpl->set('notspecialpage', $this->mTitle->getNamespace() != NS_SPECIAL);
+ /* XXX currently unused, might get useful later
+ $tpl->set( "editable", ($this->mTitle->getNamespace() != NS_SPECIAL ) );
+ $tpl->set( "exists", $this->mTitle->getArticleID() != 0 );
+ $tpl->set( "watch", $this->mTitle->userIsWatching() ? "unwatch" : "watch" );
+ $tpl->set( "protect", count($this->mTitle->isProtected()) ? "unprotect" : "protect" );
+ $tpl->set( "helppage", wfMsg('helppage'));
+ */
+ $tpl->set( 'searchaction', $this->escapeSearchLink() );
+ $tpl->set( 'search', trim( $wgRequest->getVal( 'search' ) ) );
+ $tpl->setRef( 'stylepath', $wgStylePath );
+ $tpl->setRef( 'articlepath', $wgArticlePath );
+ $tpl->setRef( 'scriptpath', $wgScriptPath );
+ $tpl->setRef( 'serverurl', $wgServer );
+ $tpl->setRef( 'logopath', $wgLogo );
+ $tpl->setRef( "lang", $wgContLanguageCode );
+ $tpl->set( 'dir', $wgContLang->isRTL() ? "rtl" : "ltr" );
+ $tpl->set( 'rtl', $wgContLang->isRTL() );
+ $tpl->set( 'langname', $wgContLang->getLanguageName( $wgContLanguageCode ) );
+ $tpl->set( 'showjumplinks', $wgUser->getOption( 'showjumplinks' ) );
+ $tpl->set( 'username', $wgUser->isAnon() ? NULL : $this->username );
+ $tpl->setRef( 'userpage', $this->userpage);
+ $tpl->setRef( 'userpageurl', $this->userpageUrlDetails['href']);
+ $tpl->set( 'userlang', $wgLang->getCode() );
+ $tpl->set( 'pagecss', $this->setupPageCss() );
+ $tpl->setRef( 'usercss', $this->usercss);
+ $tpl->setRef( 'userjs', $this->userjs);
+ $tpl->setRef( 'userjsprev', $this->userjsprev);
+ global $wgUseSiteJs;
+ if ($wgUseSiteJs) {
+ if($this->loggedin) {
+ $tpl->set( 'jsvarurl', self::makeUrl('-','action=raw&smaxage=0&gen=js') );
+ } else {
+ $tpl->set( 'jsvarurl', self::makeUrl('-','action=raw&gen=js') );
+ }
+ } else {
+ $tpl->set('jsvarurl', false);
+ }
+ $newtalks = $wgUser->getNewMessageLinks();
+
+ if (count($newtalks) == 1 && $newtalks[0]["wiki"] === wfWikiID() ) {
+ $usertitle = $this->mUser->getUserPage();
+ $usertalktitle = $usertitle->getTalkPage();
+ if( !$usertalktitle->equals( $this->mTitle ) ) {
+ $ntl = wfMsg( 'youhavenewmessages',
+ $this->makeKnownLinkObj(
+ $usertalktitle,
+ wfMsgHtml( 'newmessageslink' ),
+ 'redirect=no'
+ ),
+ $this->makeKnownLinkObj(
+ $usertalktitle,
+ wfMsgHtml( 'newmessagesdifflink' ),
+ 'diff=cur'
+ )
+ );
+ # Disable Cache
+ $wgOut->setSquidMaxage(0);
+ }
+ } else if (count($newtalks)) {
+ $sep = str_replace("_", " ", wfMsgHtml("newtalkseperator"));
+ $msgs = array();
+ foreach ($newtalks as $newtalk) {
+ $msgs[] = wfElement("a",
+ array('href' => $newtalk["link"]), $newtalk["wiki"]);
+ }
+ $parts = implode($sep, $msgs);
+ $ntl = wfMsgHtml('youhavenewmessagesmulti', $parts);
+ $wgOut->setSquidMaxage(0);
+ } else {
+ $ntl = '';
+ }
+ wfProfileOut( "$fname-stuff2" );
+
+ wfProfileIn( "$fname-stuff3" );
+ $tpl->setRef( 'newtalk', $ntl );
+ $tpl->setRef( 'skin', $this);
+ $tpl->set( 'logo', $this->logoText() );
+ if ( $wgOut->isArticle() and (!isset( $oldid ) or isset( $diff )) and
+ $wgArticle and 0 != $wgArticle->getID() )
+ {
+ if ( !$wgDisableCounters ) {
+ $viewcount = $wgLang->formatNum( $wgArticle->getCount() );
+ if ( $viewcount ) {
+ $tpl->set('viewcount', wfMsgExt( 'viewcount', array( 'parseinline' ), $viewcount ) );
+ } else {
+ $tpl->set('viewcount', false);
+ }
+ } else {
+ $tpl->set('viewcount', false);
+ }
+
+ if ($wgPageShowWatchingUsers) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $watchlist = $dbr->tableName( 'watchlist' );
+ $sql = "SELECT COUNT(*) AS n FROM $watchlist
+ WHERE wl_title='" . $dbr->strencode($this->mTitle->getDBKey()) .
+ "' AND wl_namespace=" . $this->mTitle->getNamespace() ;
+ $res = $dbr->query( $sql, 'SkinTemplate::outputPage');
+ $x = $dbr->fetchObject( $res );
+ $numberofwatchingusers = $x->n;
+ if ($numberofwatchingusers > 0) {
+ $tpl->set('numberofwatchingusers', wfMsg('number_of_watching_users_pageview', $numberofwatchingusers));
+ } else {
+ $tpl->set('numberofwatchingusers', false);
+ }
+ } else {
+ $tpl->set('numberofwatchingusers', false);
+ }
+
+ $tpl->set('copyright',$this->getCopyright());
+
+ $this->credits = false;
+
+ if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
+ require_once("Credits.php");
+ $this->credits = getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
+ } else {
+ $tpl->set('lastmod', $this->lastModified());
+ }
+
+ $tpl->setRef( 'credits', $this->credits );
+
+ } elseif ( isset( $oldid ) && !isset( $diff ) ) {
+ $tpl->set('copyright', $this->getCopyright());
+ $tpl->set('viewcount', false);
+ $tpl->set('lastmod', false);
+ $tpl->set('credits', false);
+ $tpl->set('numberofwatchingusers', false);
+ } else {
+ $tpl->set('copyright', false);
+ $tpl->set('viewcount', false);
+ $tpl->set('lastmod', false);
+ $tpl->set('credits', false);
+ $tpl->set('numberofwatchingusers', false);
+ }
+ wfProfileOut( "$fname-stuff3" );
+
+ wfProfileIn( "$fname-stuff4" );
+ $tpl->set( 'copyrightico', $this->getCopyrightIcon() );
+ $tpl->set( 'poweredbyico', $this->getPoweredBy() );
+ $tpl->set( 'disclaimer', $this->disclaimerLink() );
+ $tpl->set( 'privacy', $this->privacyLink() );
+ $tpl->set( 'about', $this->aboutLink() );
+
+ $tpl->setRef( 'debug', $out->mDebugtext );
+ $tpl->set( 'reporttime', $out->reportTime() );
+ $tpl->set( 'sitenotice', wfGetSiteNotice() );
+ $tpl->set( 'bottomscripts', $this->bottomScripts() );
+
+ $printfooter = "<div class=\"printfooter\">\n" . $this->printSource() . "</div>\n";
+ $out->mBodytext .= $printfooter ;
+ $tpl->setRef( 'bodytext', $out->mBodytext );
+
+ # Language links
+ $language_urls = array();
+
+ if ( !$wgHideInterlanguageLinks ) {
+ foreach( $wgOut->getLanguageLinks() as $l ) {
+ $tmp = explode( ':', $l, 2 );
+ $class = 'interwiki-' . $tmp[0];
+ unset($tmp);
+ $nt = Title::newFromText( $l );
+ $language_urls[] = array(
+ 'href' => $nt->getFullURL(),
+ 'text' => ($wgContLang->getLanguageName( $nt->getInterwiki()) != ''?$wgContLang->getLanguageName( $nt->getInterwiki()) : $l),
+ 'class' => $class
+ );
+ }
+ }
+ if(count($language_urls)) {
+ $tpl->setRef( 'language_urls', $language_urls);
+ } else {
+ $tpl->set('language_urls', false);
+ }
+ wfProfileOut( "$fname-stuff4" );
+
+ # Personal toolbar
+ $tpl->set('personal_urls', $this->buildPersonalUrls());
+ $content_actions = $this->buildContentActionUrls();
+ $tpl->setRef('content_actions', $content_actions);
+
+ // XXX: attach this from javascript, same with section editing
+ if($this->iseditable && $wgUser->getOption("editondblclick") )
+ {
+ $tpl->set('body_ondblclick', 'document.location = "' .$content_actions['edit']['href'] .'";');
+ } else {
+ $tpl->set('body_ondblclick', false);
+ }
+ if( $this->iseditable && $wgUser->getOption( 'editsectiononrightclick' ) ) {
+ $tpl->set( 'body_onload', 'setupRightClickEdit()' );
+ } else {
+ $tpl->set( 'body_onload', false );
+ }
+ $tpl->set( 'sidebar', $this->buildSidebar() );
+ $tpl->set( 'nav_urls', $this->buildNavUrls() );
+
+ // execute template
+ wfProfileIn( "$fname-execute" );
+ $res = $tpl->execute();
+ wfProfileOut( "$fname-execute" );
+
+ // result may be an error
+ $this->printOrError( $res );
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Output the string, or print error message if it's
+ * an error object of the appropriate type.
+ * For the base class, assume strings all around.
+ *
+ * @param mixed $str
+ * @private
+ */
+ function printOrError( &$str ) {
+ echo $str;
+ }
+
+ /**
+ * build array of urls for personal toolbar
+ * @return array
+ * @private
+ */
+ function buildPersonalUrls() {
+ global $wgTitle, $wgShowIPinHeader;
+
+ $fname = 'SkinTemplate::buildPersonalUrls';
+ $pageurl = $wgTitle->getLocalURL();
+ wfProfileIn( $fname );
+
+ /* set up the default links for the personal toolbar */
+ $personal_urls = array();
+ if ($this->loggedin) {
+ $personal_urls['userpage'] = array(
+ 'text' => $this->username,
+ 'href' => &$this->userpageUrlDetails['href'],
+ 'class' => $this->userpageUrlDetails['exists']?false:'new',
+ 'active' => ( $this->userpageUrlDetails['href'] == $pageurl )
+ );
+ $usertalkUrlDetails = $this->makeTalkUrlDetails($this->userpage);
+ $personal_urls['mytalk'] = array(
+ 'text' => wfMsg('mytalk'),
+ 'href' => &$usertalkUrlDetails['href'],
+ 'class' => $usertalkUrlDetails['exists']?false:'new',
+ 'active' => ( $usertalkUrlDetails['href'] == $pageurl )
+ );
+ $href = self::makeSpecialUrl( 'Preferences' );
+ $personal_urls['preferences'] = array(
+ 'text' => wfMsg( 'mypreferences' ),
+ 'href' => self::makeSpecialUrl( 'Preferences' ),
+ 'active' => ( $href == $pageurl )
+ );
+ $href = self::makeSpecialUrl( 'Watchlist' );
+ $personal_urls['watchlist'] = array(
+ 'text' => wfMsg( 'watchlist' ),
+ 'href' => $href,
+ 'active' => ( $href == $pageurl )
+ );
+ $href = self::makeSpecialUrlSubpage( 'Contributions', $this->username );
+ $personal_urls['mycontris'] = array(
+ 'text' => wfMsg( 'mycontris' ),
+ 'href' => $href,
+ // FIXME # 'active' was disabed in r11346 with message: "disable bold link to my contributions; link was bold on all
+ // Special:Contributions, not just current user's (fix me please!)". Until resolved, explicitly setting active to false.
+ 'active' => false # ( ( $href == $pageurl . '/' . $this->username )
+ );
+ $personal_urls['logout'] = array(
+ 'text' => wfMsg( 'userlogout' ),
+ 'href' => self::makeSpecialUrl( 'Userlogout',
+ $wgTitle->isSpecial( 'Preferences' ) ? '' : "returnto={$this->thisurl}"
+ ),
+ 'active' => false
+ );
+ } else {
+ if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
+ $href = &$this->userpageUrlDetails['href'];
+ $personal_urls['anonuserpage'] = array(
+ 'text' => $this->username,
+ 'href' => $href,
+ 'class' => $this->userpageUrlDetails['exists']?false:'new',
+ 'active' => ( $pageurl == $href )
+ );
+ $usertalkUrlDetails = $this->makeTalkUrlDetails($this->userpage);
+ $href = &$usertalkUrlDetails['href'];
+ $personal_urls['anontalk'] = array(
+ 'text' => wfMsg('anontalk'),
+ 'href' => $href,
+ 'class' => $usertalkUrlDetails['exists']?false:'new',
+ 'active' => ( $pageurl == $href )
+ );
+ $personal_urls['anonlogin'] = array(
+ 'text' => wfMsg('userlogin'),
+ 'href' => self::makeSpecialUrl( 'Userlogin', 'returnto=' . $this->thisurl ),
+ 'active' => $wgTitle->isSpecial( 'Userlogin' )
+ );
+ } else {
+
+ $personal_urls['login'] = array(
+ 'text' => wfMsg('userlogin'),
+ 'href' => self::makeSpecialUrl( 'Userlogin', 'returnto=' . $this->thisurl ),
+ 'active' => $wgTitle->isSpecial( 'Userlogin' )
+ );
+ }
+ }
+
+ wfRunHooks( 'PersonalUrls', array( &$personal_urls, &$wgTitle ) );
+ wfProfileOut( $fname );
+ return $personal_urls;
+ }
+
+ /**
+ * Returns true if the IP should be shown in the header
+ */
+ function showIPinHeader() {
+ global $wgShowIPinHeader;
+ return $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] );
+ }
+
+ function tabAction( $title, $message, $selected, $query='', $checkEdit=false ) {
+ $classes = array();
+ if( $selected ) {
+ $classes[] = 'selected';
+ }
+ if( $checkEdit && $title->getArticleId() == 0 ) {
+ $classes[] = 'new';
+ $query = 'action=edit';
+ }
+
+ $text = wfMsg( $message );
+ if ( wfEmptyMsg( $message, $text ) ) {
+ global $wgContLang;
+ $text = $wgContLang->getFormattedNsText( Namespace::getSubject( $title->getNamespace() ) );
+ }
+
+ return array(
+ 'class' => implode( ' ', $classes ),
+ 'text' => $text,
+ 'href' => $title->getLocalUrl( $query ) );
+ }
+
+ function makeTalkUrlDetails( $name, $urlaction = '' ) {
+ $title = Title::newFromText( $name );
+ $title = $title->getTalkPage();
+ self::checkTitle( $title, $name );
+ return array(
+ 'href' => $title->getLocalURL( $urlaction ),
+ 'exists' => $title->getArticleID() != 0 ? true : false
+ );
+ }
+
+ function makeArticleUrlDetails( $name, $urlaction = '' ) {
+ $title = Title::newFromText( $name );
+ $title= $title->getSubjectPage();
+ self::checkTitle( $title, $name );
+ return array(
+ 'href' => $title->getLocalURL( $urlaction ),
+ 'exists' => $title->getArticleID() != 0 ? true : false
+ );
+ }
+
+ /**
+ * an array of edit links by default used for the tabs
+ * @return array
+ * @private
+ */
+ function buildContentActionUrls () {
+ global $wgContLang, $wgOut;
+ $fname = 'SkinTemplate::buildContentActionUrls';
+ wfProfileIn( $fname );
+
+ global $wgUser, $wgRequest;
+ $action = $wgRequest->getText( 'action' );
+ $section = $wgRequest->getText( 'section' );
+ $content_actions = array();
+
+ $prevent_active_tabs = false ;
+ wfRunHooks( 'SkinTemplatePreventOtherActiveTabs', array( &$this , &$prevent_active_tabs ) ) ;
+
+ if( $this->iscontent ) {
+ $subjpage = $this->mTitle->getSubjectPage();
+ $talkpage = $this->mTitle->getTalkPage();
+
+ $nskey = $this->mTitle->getNamespaceKey();
+ $content_actions[$nskey] = $this->tabAction(
+ $subjpage,
+ $nskey,
+ !$this->mTitle->isTalkPage() && !$prevent_active_tabs,
+ '', true);
+
+ $content_actions['talk'] = $this->tabAction(
+ $talkpage,
+ 'talk',
+ $this->mTitle->isTalkPage() && !$prevent_active_tabs,
+ '',
+ true);
+
+ wfProfileIn( "$fname-edit" );
+ if ( $this->mTitle->userCanEdit() && ( $this->mTitle->exists() || $this->mTitle->userCanCreate() ) ) {
+ $istalk = $this->mTitle->isTalkPage();
+ $istalkclass = $istalk?' istalk':'';
+ $content_actions['edit'] = array(
+ 'class' => ((($action == 'edit' or $action == 'submit') and $section != 'new') ? 'selected' : '').$istalkclass,
+ 'text' => wfMsg('edit'),
+ 'href' => $this->mTitle->getLocalUrl( $this->editUrlOptions() )
+ );
+
+ if ( $istalk || $wgOut->showNewSectionLink() ) {
+ $content_actions['addsection'] = array(
+ 'class' => $section == 'new'?'selected':false,
+ 'text' => wfMsg('addsection'),
+ 'href' => $this->mTitle->getLocalUrl( 'action=edit&section=new' )
+ );
+ }
+ } else {
+ $content_actions['viewsource'] = array(
+ 'class' => ($action == 'edit') ? 'selected' : false,
+ 'text' => wfMsg('viewsource'),
+ 'href' => $this->mTitle->getLocalUrl( $this->editUrlOptions() )
+ );
+ }
+ wfProfileOut( "$fname-edit" );
+
+ wfProfileIn( "$fname-live" );
+ if ( $this->mTitle->getArticleId() ) {
+
+ $content_actions['history'] = array(
+ 'class' => ($action == 'history') ? 'selected' : false,
+ 'text' => wfMsg('history_short'),
+ 'href' => $this->mTitle->getLocalUrl( 'action=history')
+ );
+
+ if ( $this->mTitle->getNamespace() !== NS_MEDIAWIKI && $wgUser->isAllowed( 'protect' ) ) {
+ if(!$this->mTitle->isProtected()){
+ $content_actions['protect'] = array(
+ 'class' => ($action == 'protect') ? 'selected' : false,
+ 'text' => wfMsg('protect'),
+ 'href' => $this->mTitle->getLocalUrl( 'action=protect' )
+ );
+
+ } else {
+ $content_actions['unprotect'] = array(
+ 'class' => ($action == 'unprotect') ? 'selected' : false,
+ 'text' => wfMsg('unprotect'),
+ 'href' => $this->mTitle->getLocalUrl( 'action=unprotect' )
+ );
+ }
+ }
+ if($wgUser->isAllowed('delete')){
+ $content_actions['delete'] = array(
+ 'class' => ($action == 'delete') ? 'selected' : false,
+ 'text' => wfMsg('delete'),
+ 'href' => $this->mTitle->getLocalUrl( 'action=delete' )
+ );
+ }
+ if ( $this->mTitle->userCanMove()) {
+ $moveTitle = SpecialPage::getTitleFor( 'Movepage', $this->thispage );
+ $content_actions['move'] = array(
+ 'class' => $this->mTitle->isSpecial( 'Movepage' ) ? 'selected' : false,
+ 'text' => wfMsg('move'),
+ 'href' => $moveTitle->getLocalUrl()
+ );
+ }
+ } else {
+ //article doesn't exist or is deleted
+ if( $wgUser->isAllowed( 'delete' ) ) {
+ if( $n = $this->mTitle->isDeleted() ) {
+ $undelTitle = SpecialPage::getTitleFor( 'Undelete' );
+ $content_actions['undelete'] = array(
+ 'class' => false,
+ 'text' => wfMsgExt( 'undelete_short', array( 'parsemag' ), $n ),
+ 'href' => $undelTitle->getLocalUrl( 'target=' . urlencode( $this->thispage ) )
+ #'href' => self::makeSpecialUrl( "Undelete/$this->thispage" )
+ );
+ }
+ }
+ }
+ wfProfileOut( "$fname-live" );
+
+ if( $this->loggedin ) {
+ if( !$this->mTitle->userIsWatching()) {
+ $content_actions['watch'] = array(
+ 'class' => ($action == 'watch' or $action == 'unwatch') ? 'selected' : false,
+ 'text' => wfMsg('watch'),
+ 'href' => $this->mTitle->getLocalUrl( 'action=watch' )
+ );
+ } else {
+ $content_actions['unwatch'] = array(
+ 'class' => ($action == 'unwatch' or $action == 'watch') ? 'selected' : false,
+ 'text' => wfMsg('unwatch'),
+ 'href' => $this->mTitle->getLocalUrl( 'action=unwatch' )
+ );
+ }
+ }
+
+ wfRunHooks( 'SkinTemplateTabs', array( &$this , &$content_actions ) ) ;
+ } else {
+ /* show special page tab */
+
+ $content_actions[$this->mTitle->getNamespaceKey()] = array(
+ 'class' => 'selected',
+ 'text' => wfMsg('specialpage'),
+ 'href' => $wgRequest->getRequestURL(), // @bug 2457, 2510
+ );
+
+ wfRunHooks( 'SkinTemplateBuildContentActionUrlsAfterSpecialPage', array( &$this, &$content_actions ) );
+ }
+
+ /* show links to different language variants */
+ global $wgDisableLangConversion;
+ $variants = $wgContLang->getVariants();
+ if( !$wgDisableLangConversion && sizeof( $variants ) > 1 ) {
+ $preferred = $wgContLang->getPreferredVariant();
+ $vcount=0;
+ foreach( $variants as $code ) {
+ $varname = $wgContLang->getVariantname( $code );
+ if( $varname == 'disable' )
+ continue;
+ $selected = ( $code == $preferred )? 'selected' : false;
+ $content_actions['varlang-' . $vcount] = array(
+ 'class' => $selected,
+ 'text' => $varname,
+ 'href' => $this->mTitle->getLocalURL('',$code)
+ );
+ $vcount ++;
+ }
+ }
+
+ wfRunHooks( 'SkinTemplateContentActions', array( &$content_actions ) );
+
+ wfProfileOut( $fname );
+ return $content_actions;
+ }
+
+
+
+ /**
+ * build array of common navigation links
+ * @return array
+ * @private
+ */
+ function buildNavUrls () {
+ global $wgUseTrackbacks, $wgTitle, $wgArticle;
+
+ $fname = 'SkinTemplate::buildNavUrls';
+ wfProfileIn( $fname );
+
+ global $wgUser, $wgRequest;
+ global $wgEnableUploads, $wgUploadNavigationUrl;
+
+ $action = $wgRequest->getText( 'action' );
+ $oldid = $wgRequest->getVal( 'oldid' );
+
+ $nav_urls = array();
+ $nav_urls['mainpage'] = array( 'href' => self::makeMainPageUrl() );
+ if( $wgEnableUploads ) {
+ if ($wgUploadNavigationUrl) {
+ $nav_urls['upload'] = array( 'href' => $wgUploadNavigationUrl );
+ } else {
+ $nav_urls['upload'] = array( 'href' => self::makeSpecialUrl( 'Upload' ) );
+ }
+ } else {
+ if ($wgUploadNavigationUrl)
+ $nav_urls['upload'] = array( 'href' => $wgUploadNavigationUrl );
+ else
+ $nav_urls['upload'] = false;
+ }
+ $nav_urls['specialpages'] = array( 'href' => self::makeSpecialUrl( 'Specialpages' ) );
+
+ // default permalink to being off, will override it as required below.
+ $nav_urls['permalink'] = false;
+
+ // A print stylesheet is attached to all pages, but nobody ever
+ // figures that out. :) Add a link...
+ if( $this->iscontent && ($action == '' || $action == 'view' || $action == 'purge' ) ) {
+ $revid = $wgArticle ? $wgArticle->getLatest() : 0;
+ if ( !( $revid == 0 ) )
+ $nav_urls['print'] = array(
+ 'text' => wfMsg( 'printableversion' ),
+ 'href' => $wgRequest->appendQuery( 'printable=yes' )
+ );
+
+ // Also add a "permalink" while we're at it
+ if ( (int)$oldid ) {
+ $nav_urls['permalink'] = array(
+ 'text' => wfMsg( 'permalink' ),
+ 'href' => ''
+ );
+ } else {
+ if ( !( $revid == 0 ) )
+ $nav_urls['permalink'] = array(
+ 'text' => wfMsg( 'permalink' ),
+ 'href' => $wgTitle->getLocalURL( "oldid=$revid" )
+ );
+ }
+
+ wfRunHooks( 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink', array( &$this, &$nav_urls, &$oldid, &$revid ) );
+ }
+
+ if( $this->mTitle->getNamespace() != NS_SPECIAL ) {
+ $wlhTitle = SpecialPage::getTitleFor( 'Whatlinkshere', $this->thispage );
+ $nav_urls['whatlinkshere'] = array(
+ 'href' => $wlhTitle->getLocalUrl()
+ );
+ if( $this->mTitle->getArticleId() ) {
+ $rclTitle = SpecialPage::getTitleFor( 'Recentchangeslinked', $this->thispage );
+ $nav_urls['recentchangeslinked'] = array(
+ 'href' => $rclTitle->getLocalUrl()
+ );
+ } else {
+ $nav_urls['recentchangeslinked'] = false;
+ }
+ if ($wgUseTrackbacks)
+ $nav_urls['trackbacklink'] = array(
+ 'href' => $wgTitle->trackbackURL()
+ );
+ }
+
+ if( $this->mTitle->getNamespace() == NS_USER || $this->mTitle->getNamespace() == NS_USER_TALK ) {
+ $id = User::idFromName($this->mTitle->getText());
+ $ip = User::isIP($this->mTitle->getText());
+ } else {
+ $id = 0;
+ $ip = false;
+ }
+
+ if($id || $ip) { # both anons and non-anons have contri list
+ $nav_urls['contributions'] = array(
+ 'href' => self::makeSpecialUrlSubpage( 'Contributions', $this->mTitle->getText() )
+ );
+ if ( $wgUser->isAllowed( 'block' ) ) {
+ $nav_urls['blockip'] = array(
+ 'href' => self::makeSpecialUrlSubpage( 'Blockip', $this->mTitle->getText() )
+ );
+ } else {
+ $nav_urls['blockip'] = false;
+ }
+ } else {
+ $nav_urls['contributions'] = false;
+ $nav_urls['blockip'] = false;
+ }
+ $nav_urls['emailuser'] = false;
+ if( $this->showEmailUser( $id ) ) {
+ $nav_urls['emailuser'] = array(
+ 'href' => self::makeSpecialUrlSubpage( 'Emailuser', $this->mTitle->getText() )
+ );
+ }
+ wfProfileOut( $fname );
+ return $nav_urls;
+ }
+
+ /**
+ * Generate strings used for xml 'id' names
+ * @return string
+ * @private
+ */
+ function getNameSpaceKey () {
+ return $this->mTitle->getNamespaceKey();
+ }
+
+ /**
+ * @private
+ */
+ function setupUserCss() {
+ $fname = 'SkinTemplate::setupUserCss';
+ wfProfileIn( $fname );
+
+ global $wgRequest, $wgAllowUserCss, $wgUseSiteCss, $wgContLang, $wgSquidMaxage, $wgStylePath, $wgUser;
+
+ $sitecss = '';
+ $usercss = '';
+ $siteargs = '&maxage=' . $wgSquidMaxage;
+ if( $this->loggedin ) {
+ // Ensure that logged-in users' generated CSS isn't clobbered
+ // by anons' publicly cacheable generated CSS.
+ $siteargs .= '&smaxage=0';
+ }
+
+ # Add user-specific code if this is a user and we allow that kind of thing
+
+ if ( $wgAllowUserCss && $this->loggedin ) {
+ $action = $wgRequest->getText('action');
+
+ # if we're previewing the CSS page, use it
+ if( $this->mTitle->isCssSubpage() and $this->userCanPreview( $action ) ) {
+ $siteargs = "&smaxage=0&maxage=0";
+ $usercss = $wgRequest->getText('wpTextbox1');
+ } else {
+ $usercss = '@import "' .
+ self::makeUrl($this->userpage . '/'.$this->skinname.'.css',
+ 'action=raw&ctype=text/css') . '";' ."\n";
+ }
+
+ $siteargs .= '&ts=' . $wgUser->mTouched;
+ }
+
+ if( $wgContLang->isRTL() ) {
+ global $wgStyleVersion;
+ $sitecss .= "@import \"$wgStylePath/$this->stylename/rtl.css?$wgStyleVersion\";\n";
+ }
+
+ # If we use the site's dynamic CSS, throw that in, too
+ if ( $wgUseSiteCss ) {
+ $query = "usemsgcache=yes&action=raw&ctype=text/css&smaxage=$wgSquidMaxage";
+ $sitecss .= '@import "' . self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI) . '";' . "\n";
+ $sitecss .= '@import "' . self::makeNSUrl( ucfirst( $this->skinname ) . '.css', $query, NS_MEDIAWIKI ) . '";' . "\n";
+ $sitecss .= '@import "' . self::makeUrl( '-', 'action=raw&gen=css' . $siteargs ) . '";' . "\n";
+ }
+
+ # If we use any dynamic CSS, make a little CDATA block out of it.
+
+ if ( !empty($sitecss) || !empty($usercss) ) {
+ $this->usercss = "/*<![CDATA[*/\n" . $sitecss . $usercss . '/*]]>*/';
+ }
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * @private
+ */
+ function setupUserJs() {
+ $fname = 'SkinTemplate::setupUserJs';
+ wfProfileIn( $fname );
+
+ global $wgRequest, $wgAllowUserJs, $wgJsMimeType;
+ $action = $wgRequest->getText('action');
+
+ if( $wgAllowUserJs && $this->loggedin ) {
+ if( $this->mTitle->isJsSubpage() and $this->userCanPreview( $action ) ) {
+ # XXX: additional security check/prompt?
+ $this->userjsprev = '/*<![CDATA[*/ ' . $wgRequest->getText('wpTextbox1') . ' /*]]>*/';
+ } else {
+ $this->userjs = self::makeUrl($this->userpage.'/'.$this->skinname.'.js', 'action=raw&ctype='.$wgJsMimeType.'&dontcountme=s');
+ }
+ }
+ wfProfileOut( $fname );
+ }
+
+ /**
+ * Code for extensions to hook into to provide per-page CSS, see
+ * extensions/PageCSS/PageCSS.php for an implementation of this.
+ *
+ * @private
+ */
+ function setupPageCss() {
+ $fname = 'SkinTemplate::setupPageCss';
+ wfProfileIn( $fname );
+ $out = false;
+ wfRunHooks( 'SkinTemplateSetupPageCss', array( &$out ) );
+
+ wfProfileOut( $fname );
+ return $out;
+ }
+
+ /**
+ * returns css with user-specific options
+ * @public
+ */
+
+ function getUserStylesheet() {
+ $fname = 'SkinTemplate::getUserStylesheet';
+ wfProfileIn( $fname );
+
+ $s = "/* generated user stylesheet */\n";
+ $s .= $this->reallyDoGetUserStyles();
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ /**
+ * This returns MediaWiki:Common.js and MediaWiki:[Skinname].js concate-
+ * nated together. For some bizarre reason, it does *not* return any
+ * custom user JS from subpages. Huh?
+ *
+ * There's absolutely no reason to have separate Monobook/Common JSes.
+ * Any JS that cares can just check the skin variable generated at the
+ * top. For now Monobook.js will be maintained, but it should be consi-
+ * dered deprecated.
+ *
+ * @return string
+ */
+ public function getUserJs() {
+ $fname = 'SkinTemplate::getUserJs';
+ wfProfileIn( $fname );
+
+ $s = parent::getUserJs();
+ $s .= "\n\n/* MediaWiki:".ucfirst($this->skinname).".js (deprecated; migrate to Common.js!) */\n";
+
+ // avoid inclusion of non defined user JavaScript (with custom skins only)
+ // by checking for default message content
+ $msgKey = ucfirst($this->skinname).'.js';
+ $userJS = wfMsgForContent($msgKey);
+ if ( !wfEmptyMsg( $msgKey, $userJS ) ) {
+ $s .= $userJS;
+ }
+
+ wfProfileOut( $fname );
+ return $s;
+ }
+}
+
+/**
+ * Generic wrapper for template functions, with interface
+ * compatible with what we use of PHPTAL 0.7.
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class QuickTemplate {
+ /**
+ * @public
+ */
+ function QuickTemplate() {
+ $this->data = array();
+ $this->translator = new MediaWiki_I18N();
+ }
+
+ /**
+ * @public
+ */
+ function set( $name, $value ) {
+ $this->data[$name] = $value;
+ }
+
+ /**
+ * @public
+ */
+ function setRef($name, &$value) {
+ $this->data[$name] =& $value;
+ }
+
+ /**
+ * @public
+ */
+ function setTranslator( &$t ) {
+ $this->translator = &$t;
+ }
+
+ /**
+ * @public
+ */
+ function execute() {
+ echo "Override this function.";
+ }
+
+
+ /**
+ * @private
+ */
+ function text( $str ) {
+ echo htmlspecialchars( $this->data[$str] );
+ }
+
+ /**
+ * @private
+ */
+ function jstext( $str ) {
+ echo Xml::escapeJsString( $this->data[$str] );
+ }
+
+ /**
+ * @private
+ */
+ function html( $str ) {
+ echo $this->data[$str];
+ }
+
+ /**
+ * @private
+ */
+ function msg( $str ) {
+ echo htmlspecialchars( $this->translator->translate( $str ) );
+ }
+
+ /**
+ * @private
+ */
+ function msgHtml( $str ) {
+ echo $this->translator->translate( $str );
+ }
+
+ /**
+ * An ugly, ugly hack.
+ * @private
+ */
+ function msgWiki( $str ) {
+ global $wgParser, $wgTitle, $wgOut;
+
+ $text = $this->translator->translate( $str );
+ $parserOutput = $wgParser->parse( $text, $wgTitle,
+ $wgOut->parserOptions(), true );
+ echo $parserOutput->getText();
+ }
+
+ /**
+ * @private
+ */
+ function haveData( $str ) {
+ return isset( $this->data[$str] );
+ }
+
+ /**
+ * @private
+ */
+ function haveMsg( $str ) {
+ $msg = $this->translator->translate( $str );
+ return ($msg != '-') && ($msg != ''); # ????
+ }
+}
+?>
diff --git a/includes/SpecialAllmessages.php b/includes/SpecialAllmessages.php
new file mode 100644
index 000000000000..a28ab3c2ede9
--- /dev/null
+++ b/includes/SpecialAllmessages.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Use this special page to get a list of the MediaWiki system messages.
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Constructor.
+ */
+function wfSpecialAllmessages() {
+ global $wgOut, $wgRequest, $wgMessageCache, $wgTitle;
+ global $wgUseDatabaseMessages;
+
+ # The page isn't much use if the MediaWiki namespace is not being used
+ if( !$wgUseDatabaseMessages ) {
+ $wgOut->addWikiText( wfMsg( 'allmessagesnotsupportedDB' ) );
+ return;
+ }
+
+ wfProfileIn( __METHOD__ );
+
+ wfProfileIn( __METHOD__ . '-setup' );
+ $ot = $wgRequest->getText( 'ot' );
+
+ $navText = wfMsg( 'allmessagestext' );
+
+ # Make sure all extension messages are available
+ MessageCache::loadAllMessages();
+
+ $sortedArray = array_merge( Language::getMessagesFor( 'en' ), $wgMessageCache->getExtensionMessagesFor( 'en' ) );
+ ksort( $sortedArray );
+ $messages = array();
+ $wgMessageCache->disableTransform();
+
+ foreach ( $sortedArray as $key => $value ) {
+ $messages[$key]['enmsg'] = $value;
+ $messages[$key]['statmsg'] = wfMsgNoDb( $key );
+ $messages[$key]['msg'] = wfMsg ( $key );
+ }
+
+ $wgMessageCache->enableTransform();
+ wfProfileOut( __METHOD__ . '-setup' );
+
+ wfProfileIn( __METHOD__ . '-output' );
+ if ( $ot == 'php' ) {
+ $navText .= makePhp( $messages );
+ $wgOut->addHTML( 'PHP | <a href="' . $wgTitle->escapeLocalUrl( 'ot=html' ) . '">HTML</a><pre>' . htmlspecialchars( $navText ) . '</pre>' );
+ } else {
+ $wgOut->addHTML( '<a href="' . $wgTitle->escapeLocalUrl( 'ot=php' ) . '">PHP</a> | HTML' );
+ $wgOut->addWikiText( $navText );
+ $wgOut->addHTML( makeHTMLText( $messages ) );
+ }
+ wfProfileOut( __METHOD__ . '-output' );
+
+ wfProfileOut( __METHOD__ );
+}
+
+/**
+ * Create the messages array, formatted in PHP to copy to language files.
+ * @param $messages Messages array.
+ * @return The PHP messages array.
+ * @todo Make suitable for language files.
+ */
+function makePhp( $messages ) {
+ global $wgLang;
+ $txt = "\n\n\$messages = array(\n";
+ foreach( $messages as $key => $m ) {
+ if( $wgLang->getCode() != 'en' && $m['msg'] == $m['enmsg'] ) {
+ continue;
+ } else if ( wfEmptyMsg( $key, $m['msg'] ) ) {
+ $m['msg'] = '';
+ $comment = ' #empty';
+ } else {
+ $comment = '';
+ }
+ $txt .= "'$key' => '" . preg_replace( '/(?<!\\\\)\'/', "\'", $m['msg']) . "',$comment\n";
+ }
+ $txt .= ');';
+ return $txt;
+}
+
+/**
+ * Create a list of messages, formatted in HTML as a list of messages and values and showing differences between the default language file message and the message in MediaWiki: namespace.
+ * @param $messages Messages array.
+ * @return The HTML list of messages.
+ */
+function makeHTMLText( $messages ) {
+ global $wgLang, $wgContLang, $wgUser;
+ wfProfileIn( __METHOD__ );
+
+ $sk =& $wgUser->getSkin();
+ $talk = $wgLang->getNsText( NS_TALK );
+
+ $input = wfElement( 'input', array(
+ 'type' => 'text',
+ 'id' => 'allmessagesinput',
+ 'onkeyup' => 'allmessagesfilter()'
+ ), '' );
+ $checkbox = wfElement( 'input', array(
+ 'type' => 'button',
+ 'value' => wfMsgHtml( 'allmessagesmodified' ),
+ 'id' => 'allmessagescheckbox',
+ 'onclick' => 'allmessagesmodified()'
+ ), '' );
+
+ $txt = '<span id="allmessagesfilter" style="display: none;">' . wfMsgHtml( 'allmessagesfilter' ) . " {$input}{$checkbox} " . '</span>';
+
+ $txt .= '
+<table border="1" cellspacing="0" width="100%" id="allmessagestable">
+ <tr>
+ <th rowspan="2">' . wfMsgHtml( 'allmessagesname' ) . '</th>
+ <th>' . wfMsgHtml( 'allmessagesdefault' ) . '</th>
+ </tr>
+ <tr>
+ <th>' . wfMsgHtml( 'allmessagescurrent' ) . '</th>
+ </tr>';
+
+ wfProfileIn( __METHOD__ . "-check" );
+
+ # This is a nasty hack to avoid doing independent existence checks
+ # without sending the links and table through the slow wiki parser.
+ $pageExists = array(
+ NS_MEDIAWIKI => array(),
+ NS_MEDIAWIKI_TALK => array()
+ );
+ $dbr =& wfGetDB( DB_SLAVE );
+ $page = $dbr->tableName( 'page' );
+ $sql = "SELECT page_namespace,page_title FROM $page WHERE page_namespace IN (" . NS_MEDIAWIKI . ", " . NS_MEDIAWIKI_TALK . ")";
+ $res = $dbr->query( $sql );
+ while( $s = $dbr->fetchObject( $res ) ) {
+ $pageExists[$s->page_namespace][$s->page_title] = true;
+ }
+ $dbr->freeResult( $res );
+ wfProfileOut( __METHOD__ . "-check" );
+
+ wfProfileIn( __METHOD__ . "-output" );
+
+ $i = 0;
+
+ foreach( $messages as $key => $m ) {
+ $title = $wgLang->ucfirst( $key );
+ if( $wgLang->getCode() != $wgContLang->getCode() ) {
+ $title .= '/' . $wgLang->getCode();
+ }
+
+ $titleObj =& Title::makeTitle( NS_MEDIAWIKI, $title );
+ $talkPage =& Title::makeTitle( NS_MEDIAWIKI_TALK, $title );
+
+ $changed = ( $m['statmsg'] != $m['msg'] );
+ $message = htmlspecialchars( $m['statmsg'] );
+ $mw = htmlspecialchars( $m['msg'] );
+
+ if( isset( $pageExists[NS_MEDIAWIKI][$title] ) ) {
+ $pageLink = $sk->makeKnownLinkObj( $titleObj, "<span id=\"sp-allmessages-i-$i\">" . htmlspecialchars( $key ) . '</span>' );
+ } else {
+ $pageLink = $sk->makeBrokenLinkObj( $titleObj, "<span id=\"sp-allmessages-i-$i\">" . htmlspecialchars( $key ) . '</span>' );
+ }
+ if( isset( $pageExists[NS_MEDIAWIKI_TALK][$title] ) ) {
+ $talkLink = $sk->makeKnownLinkObj( $talkPage, htmlspecialchars( $talk ) );
+ } else {
+ $talkLink = $sk->makeBrokenLinkObj( $talkPage, htmlspecialchars( $talk ) );
+ }
+
+ $anchor = 'msg_' . htmlspecialchars( strtolower( $title ) );
+ $anchor = "<a id=\"$anchor\" name=\"$anchor\"></a>";
+
+ if( $changed ) {
+ $txt .= "
+ <tr class=\"orig\" id=\"sp-allmessages-r1-$i\">
+ <td rowspan=\"2\">
+ $anchor$pageLink<br />$talkLink
+ </td><td>
+$message
+ </td>
+ </tr><tr class=\"new\" id=\"sp-allmessages-r2-$i\">
+ <td>
+$mw
+ </td>
+ </tr>";
+ } else {
+ $txt .= "
+ <tr class=\"def\" id=\"sp-allmessages-r1-$i\">
+ <td>
+ $anchor$pageLink<br />$talkLink
+ </td><td>
+$mw
+ </td>
+ </tr>";
+ }
+ $i++;
+ }
+ $txt .= '</table>';
+ wfProfileOut( __METHOD__ . '-output' );
+
+ wfProfileOut( __METHOD__ );
+ return $txt;
+}
+
+?>
diff --git a/includes/SpecialAllpages.php b/includes/SpecialAllpages.php
new file mode 100644
index 000000000000..737e6834f418
--- /dev/null
+++ b/includes/SpecialAllpages.php
@@ -0,0 +1,360 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Entry point : initialise variables and call subfunctions.
+ * @param $par String: becomes "FOO" when called like Special:Allpages/FOO (default NULL)
+ * @param $specialPage @see SpecialPage object.
+ */
+function wfSpecialAllpages( $par=NULL, $specialPage ) {
+ global $wgRequest, $wgOut, $wgContLang;
+
+ # GET values
+ $from = $wgRequest->getVal( 'from' );
+ $namespace = $wgRequest->getInt( 'namespace' );
+
+ $namespaces = $wgContLang->getNamespaces();
+
+ $indexPage = new SpecialAllpages();
+
+ if( !in_array($namespace, array_keys($namespaces)) )
+ $namespace = 0;
+
+ $wgOut->setPagetitle( $namespace > 0 ?
+ wfMsg( 'allinnamespace', str_replace( '_', ' ', $namespaces[$namespace] ) ) :
+ wfMsg( 'allarticles' )
+ );
+
+ if ( isset($par) ) {
+ $indexPage->showChunk( $namespace, $par, $specialPage->including() );
+ } elseif ( isset($from) ) {
+ $indexPage->showChunk( $namespace, $from, $specialPage->including() );
+ } else {
+ $indexPage->showToplevel ( $namespace, $specialPage->including() );
+ }
+}
+
+class SpecialAllpages {
+ var $maxPerPage=960;
+ var $topLevelMax=50;
+ var $name='Allpages';
+ # Determines, which message describes the input field 'nsfrom' (->SpecialPrefixindex.php)
+ var $nsfromMsg='allpagesfrom';
+
+/**
+ * HTML for the top form
+ * @param integer $namespace A namespace constant (default NS_MAIN).
+ * @param string $from Article name we are starting listing at.
+ */
+function namespaceForm ( $namespace = NS_MAIN, $from = '' ) {
+ global $wgScript;
+ $t = SpecialPage::getTitleFor( $this->name );
+
+ $namespaceselect = HTMLnamespaceselector($namespace, null);
+
+ $frombox = "<input type='text' size='20' name='from' id='nsfrom' value=\""
+ . htmlspecialchars ( $from ) . '"/>';
+ $submitbutton = '<input type="submit" value="' . wfMsgHtml( 'allpagessubmit' ) . '" />';
+
+ $out = "<div class='namespaceoptions'><form method='get' action='{$wgScript}'>";
+ $out .= '<input type="hidden" name="title" value="'.$t->getPrefixedText().'" />';
+ $out .= "
+<table id='nsselect' class='allpages'>
+ <tr>
+ <td align='right'>" . wfMsgHtml($this->nsfromMsg) . "</td>
+ <td align='left'><label for='nsfrom'>$frombox</label></td>
+ </tr>
+ <tr>
+ <td align='right'><label for='namespace'>" . wfMsgHtml('namespace') . "</label></td>
+ <td align='left'>
+ $namespaceselect $submitbutton
+ </td>
+ </tr>
+</table>
+";
+ $out .= '</form></div>';
+ return $out;
+}
+
+/**
+ * @param integer $namespace (default NS_MAIN)
+ */
+function showToplevel ( $namespace = NS_MAIN, $including = false ) {
+ global $wgOut;
+ $fname = "indexShowToplevel";
+
+ # TODO: Either make this *much* faster or cache the title index points
+ # in the querycache table.
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $out = "";
+ $where = array( 'page_namespace' => $namespace );
+
+ global $wgMemc;
+ $key = wfMemcKey( 'allpages', 'ns', $namespace );
+ $lines = $wgMemc->get( $key );
+
+ if( !is_array( $lines ) ) {
+ $firstTitle = $dbr->selectField( 'page', 'page_title', $where, $fname, array( 'LIMIT' => 1 ) );
+ $lastTitle = $firstTitle;
+
+ # This array is going to hold the page_titles in order.
+ $lines = array( $firstTitle );
+
+ # If we are going to show n rows, we need n+1 queries to find the relevant titles.
+ $done = false;
+ for( $i = 0; !$done; ++$i ) {
+ // Fetch the last title of this chunk and the first of the next
+ $chunk = is_null( $lastTitle )
+ ? ''
+ : 'page_title >= ' . $dbr->addQuotes( $lastTitle );
+ $res = $dbr->select(
+ 'page', /* FROM */
+ 'page_title', /* WHAT */
+ $where + array( $chunk),
+ $fname,
+ array ('LIMIT' => 2, 'OFFSET' => $this->maxPerPage - 1, 'ORDER BY' => 'page_title') );
+
+ if ( $s = $dbr->fetchObject( $res ) ) {
+ array_push( $lines, $s->page_title );
+ } else {
+ // Final chunk, but ended prematurely. Go back and find the end.
+ $endTitle = $dbr->selectField( 'page', 'MAX(page_title)',
+ array(
+ 'page_namespace' => $namespace,
+ $chunk
+ ), $fname );
+ array_push( $lines, $endTitle );
+ $done = true;
+ }
+ if( $s = $dbr->fetchObject( $res ) ) {
+ array_push( $lines, $s->page_title );
+ $lastTitle = $s->page_title;
+ } else {
+ // This was a final chunk and ended exactly at the limit.
+ // Rare but convenient!
+ $done = true;
+ }
+ $dbr->freeResult( $res );
+ }
+ $wgMemc->add( $key, $lines, 3600 );
+ }
+
+ // If there are only two or less sections, don't even display them.
+ // Instead, display the first section directly.
+ if( count( $lines ) <= 2 ) {
+ $this->showChunk( $namespace, '', $including );
+ return;
+ }
+
+ # At this point, $lines should contain an even number of elements.
+ $out .= "<table class='allpageslist' style='background: inherit;'>";
+ while ( count ( $lines ) > 0 ) {
+ $inpoint = array_shift ( $lines );
+ $outpoint = array_shift ( $lines );
+ $out .= $this->showline ( $inpoint, $outpoint, $namespace, false );
+ }
+ $out .= '</table>';
+ $nsForm = $this->namespaceForm ( $namespace, '', false );
+
+ # Is there more?
+ if ( $including ) {
+ $out2 = '';
+ } else {
+ $morelinks = '';
+ if ( $morelinks != '' ) {
+ $out2 = '<table style="background: inherit;" width="100%" cellpadding="0" cellspacing="0" border="0">';
+ $out2 .= '<tr valign="top"><td align="left">' . $nsForm;
+ $out2 .= '</td><td align="right" style="font-size: smaller; margin-bottom: 1em;">';
+ $out2 .= $morelinks . '</td></tr></table><hr />';
+ } else {
+ $out2 = $nsForm . '<hr />';
+ }
+ }
+
+ $wgOut->addHtml( $out2 . $out );
+}
+
+/**
+ * @todo Document
+ * @param string $from
+ * @param integer $namespace (Default NS_MAIN)
+ */
+function showline( $inpoint, $outpoint, $namespace = NS_MAIN ) {
+ $inpointf = htmlspecialchars( str_replace( '_', ' ', $inpoint ) );
+ $outpointf = htmlspecialchars( str_replace( '_', ' ', $outpoint ) );
+ $queryparams = ($namespace ? "namespace=$namespace" : '');
+ $special = SpecialPage::getTitleFor( $this->name, $inpoint );
+ $link = $special->escapeLocalUrl( $queryparams );
+
+ $out = wfMsgHtml(
+ 'alphaindexline',
+ "<a href=\"$link\">$inpointf</a></td><td><a href=\"$link\">",
+ "</a></td><td align=\"left\"><a href=\"$link\">$outpointf</a>"
+ );
+ return '<tr><td align="right">'.$out.'</td></tr>';
+}
+
+/**
+ * @param integer $namespace (Default NS_MAIN)
+ * @param string $from list all pages from this name (default FALSE)
+ */
+function showChunk( $namespace = NS_MAIN, $from, $including = false ) {
+ global $wgOut, $wgUser, $wgContLang;
+
+ $fname = 'indexShowChunk';
+
+ $sk = $wgUser->getSkin();
+
+ $fromList = $this->getNamespaceKeyAndText($namespace, $from);
+ $n = 0;
+
+ if ( !$fromList ) {
+ $out = wfMsgWikiHtml( 'allpagesbadtitle' );
+ } else {
+ list( $namespace, $fromKey, $from ) = $fromList;
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'page',
+ array( 'page_namespace', 'page_title', 'page_is_redirect' ),
+ array(
+ 'page_namespace' => $namespace,
+ 'page_title >= ' . $dbr->addQuotes( $fromKey )
+ ),
+ $fname,
+ array(
+ 'ORDER BY' => 'page_title',
+ 'LIMIT' => $this->maxPerPage + 1,
+ 'USE INDEX' => 'name_title',
+ )
+ );
+
+ $out = '<table style="background: inherit;" border="0" width="100%">';
+
+ while( ($n < $this->maxPerPage) && ($s = $dbr->fetchObject( $res )) ) {
+ $t = Title::makeTitle( $s->page_namespace, $s->page_title );
+ if( $t ) {
+ $link = ($s->page_is_redirect ? '<div class="allpagesredirect">' : '' ) .
+ $sk->makeKnownLinkObj( $t, htmlspecialchars( $t->getText() ), false, false ) .
+ ($s->page_is_redirect ? '</div>' : '' );
+ } else {
+ $link = '[[' . htmlspecialchars( $s->page_title ) . ']]';
+ }
+ if( $n % 3 == 0 ) {
+ $out .= '<tr>';
+ }
+ $out .= "<td>$link</td>";
+ $n++;
+ if( $n % 3 == 0 ) {
+ $out .= '</tr>';
+ }
+ }
+ if( ($n % 3) != 0 ) {
+ $out .= '</tr>';
+ }
+ $out .= '</table>';
+ }
+
+ if ( $including ) {
+ $out2 = '';
+ } else {
+
+ # Get the last title from previous chunk
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res_prev = $dbr->select(
+ 'page',
+ 'page_title',
+ array( 'page_namespace' => $namespace, 'page_title < '.$dbr->addQuotes($from) ),
+ $fname,
+ array( 'ORDER BY' => 'page_title DESC', 'LIMIT' => $this->maxPerPage, 'OFFSET' => ($this->maxPerPage - 1 ) )
+ );
+
+ # Get first title of previous complete chunk
+ if( $dbr->numrows( $res_prev ) >= $this->maxPerPage ) {
+ $pt = $dbr->fetchObject( $res_prev );
+ $prevTitle = Title::makeTitle( $namespace, $pt->page_title );
+ } else {
+ # The previous chunk is not complete, need to link to the very first title
+ # available in the database
+ $reallyFirstPage_title = $dbr->selectField( 'page', 'page_title', array( 'page_namespace' => $namespace ), $fname, array( 'LIMIT' => 1) );
+
+ # Show the previous link if it s not the current requested chunk
+ if( $from != $reallyFirstPage_title ) {
+ $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title );
+ } else {
+ $prevTitle = null;
+ }
+ }
+
+ $nsForm = $this->namespaceForm ( $namespace, $from );
+ $out2 = '<table style="background: inherit;" width="100%" cellpadding="0" cellspacing="0" border="0">';
+ $out2 .= '<tr valign="top"><td align="left">' . $nsForm;
+ $out2 .= '</td><td align="right" style="font-size: smaller; margin-bottom: 1em;">' .
+ $sk->makeKnownLink( $wgContLang->specialPage( "Allpages" ),
+ wfMsgHtml ( 'allpages' ) );
+
+ $self = SpecialPage::getTitleFor( 'Allpages' );
+
+ # Do we put a previous link ?
+ if( isset( $prevTitle ) && $pt = $prevTitle->getText() ) {
+ $q = 'from=' . $prevTitle->getPartialUrl() . ( $namespace ? '&namespace=' . $namespace : '' );
+ $prevLink = $sk->makeKnownLinkObj( $self, wfMsgHTML( 'prevpage', $pt ), $q );
+ $out2 .= ' | ' . $prevLink;
+ }
+
+ if( $n == $this->maxPerPage && $s = $dbr->fetchObject($res) ) {
+ # $s is the first link of the next chunk
+ $t = Title::MakeTitle($namespace, $s->page_title);
+ $q = 'from=' . $t->getPartialUrl() . ( $namespace ? '&namespace=' . $namespace : '' );
+ $nextLink = $sk->makeKnownLinkObj( $self, wfMsgHtml( 'nextpage', $t->getText() ), $q );
+ $out2 .= ' | ' . $nextLink;
+ }
+ $out2 .= "</td></tr></table><hr />";
+ }
+
+ $wgOut->addHtml( $out2 . $out );
+ if( isset($prevLink) or isset($nextLink) ) {
+ $wgOut->addHtml( '<hr/><p style="font-size: smaller; float: right;">' );
+ if( isset( $prevLink ) )
+ $wgOut->addHTML( $prevLink . ' | ');
+ if( isset( $nextLink ) )
+ $wgOut->addHTML( $nextLink );
+ $wgOut->addHTML( '</p>' );
+
+ }
+
+}
+
+/**
+ * @param int $ns the namespace of the article
+ * @param string $text the name of the article
+ * @return array( int namespace, string dbkey, string pagename ) or NULL on error
+ * @static (sort of)
+ * @access private
+ */
+function getNamespaceKeyAndText ($ns, $text) {
+ if ( $text == '' )
+ return array( $ns, '', '' ); # shortcut for common case
+
+ $t = Title::makeTitleSafe($ns, $text);
+ if ( $t && $t->isLocal() ) {
+ return array( $t->getNamespace(), $t->getDBkey(), $t->getText() );
+ } else if ( $t ) {
+ return NULL;
+ }
+
+ # try again, in case the problem was an empty pagename
+ $text = preg_replace('/(#|$)/', 'X$1', $text);
+ $t = Title::makeTitleSafe($ns, $text);
+ if ( $t && $t->isLocal() ) {
+ return array( $t->getNamespace(), '', '' );
+ } else {
+ return NULL;
+ }
+}
+}
+
+?>
diff --git a/includes/SpecialAncientpages.php b/includes/SpecialAncientpages.php
new file mode 100644
index 000000000000..39a3c8ea17ca
--- /dev/null
+++ b/includes/SpecialAncientpages.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class AncientPagesPage extends QueryPage {
+
+ function getName() {
+ return "Ancientpages";
+ }
+
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ global $wgDBtype;
+ $db =& wfGetDB( DB_SLAVE );
+ $page = $db->tableName( 'page' );
+ $revision = $db->tableName( 'revision' );
+ #$use_index = $db->useIndexClause( 'cur_timestamp' ); # FIXME! this is gone
+ $epoch = $wgDBtype == 'mysql' ? 'UNIX_TIMESTAMP(rev_timestamp)' :
+ 'EXTRACT(epoch FROM rev_timestamp)';
+ return
+ "SELECT 'Ancientpages' as type,
+ page_namespace as namespace,
+ page_title as title,
+ $epoch as value
+ FROM $page, $revision
+ WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0
+ AND page_latest=rev_id";
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+
+ $d = $wgLang->timeanddate( wfTimestamp( TS_MW, $result->value ), true );
+ $title = Title::makeTitle( $result->namespace, $result->title );
+ $link = $skin->makeKnownLinkObj( $title, htmlspecialchars( $wgContLang->convert( $title->getPrefixedText() ) ) );
+ return wfSpecialList($link, $d);
+ }
+}
+
+function wfSpecialAncientpages() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $app = new AncientPagesPage();
+
+ $app->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialBlockip.php b/includes/SpecialBlockip.php
new file mode 100644
index 000000000000..626922bbd5f2
--- /dev/null
+++ b/includes/SpecialBlockip.php
@@ -0,0 +1,293 @@
+<?php
+/**
+ * Constructor for Special:Blockip page
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Constructor
+ */
+function wfSpecialBlockip( $par ) {
+ global $wgUser, $wgOut, $wgRequest;
+
+ if( !$wgUser->isAllowed( 'block' ) ) {
+ $wgOut->permissionRequired( 'block' );
+ return;
+ }
+
+ $ipb = new IPBlockForm( $par );
+
+ $action = $wgRequest->getVal( 'action' );
+ if ( 'success' == $action ) {
+ $ipb->showSuccess();
+ } else if ( $wgRequest->wasPosted() && 'submit' == $action &&
+ $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
+ $ipb->doSubmit();
+ } else {
+ $ipb->showForm( '' );
+ }
+}
+
+/**
+ * Form object
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class IPBlockForm {
+ var $BlockAddress, $BlockExpiry, $BlockReason;
+
+ function IPBlockForm( $par ) {
+ global $wgRequest;
+
+ $this->BlockAddress = $wgRequest->getVal( 'wpBlockAddress', $wgRequest->getVal( 'ip', $par ) );
+ $this->BlockReason = $wgRequest->getText( 'wpBlockReason' );
+ $this->BlockExpiry = $wgRequest->getVal( 'wpBlockExpiry', wfMsg('ipbotheroption') );
+ $this->BlockOther = $wgRequest->getVal( 'wpBlockOther', '' );
+
+ # Unchecked checkboxes are not included in the form data at all, so having one
+ # that is true by default is a bit tricky
+ $byDefault = !$wgRequest->wasPosted();
+ $this->BlockAnonOnly = $wgRequest->getBool( 'wpAnonOnly', $byDefault );
+ $this->BlockCreateAccount = $wgRequest->getBool( 'wpCreateAccount', $byDefault );
+ $this->BlockEnableAutoblock = $wgRequest->getBool( 'wpEnableAutoblock', $byDefault );
+ }
+
+ function showForm( $err ) {
+ global $wgOut, $wgUser, $wgSysopUserBans;
+
+ $wgOut->setPagetitle( wfMsg( 'blockip' ) );
+ $wgOut->addWikiText( wfMsg( 'blockiptext' ) );
+
+ if($wgSysopUserBans) {
+ $mIpaddress = wfMsgHtml( 'ipadressorusername' );
+ } else {
+ $mIpaddress = wfMsgHtml( 'ipaddress' );
+ }
+ $mIpbexpiry = wfMsgHtml( 'ipbexpiry' );
+ $mIpbother = wfMsgHtml( 'ipbother' );
+ $mIpbothertime = wfMsgHtml( 'ipbotheroption' );
+ $mIpbreason = wfMsgHtml( 'ipbreason' );
+ $mIpbsubmit = wfMsgHtml( 'ipbsubmit' );
+ $titleObj = SpecialPage::getTitleFor( 'Blockip' );
+ $action = $titleObj->escapeLocalURL( "action=submit" );
+
+ if ( "" != $err ) {
+ $wgOut->setSubtitle( wfMsgHtml( 'formerror' ) );
+ $wgOut->addHTML( "<p class='error'>{$err}</p>\n" );
+ }
+
+ $scBlockAddress = htmlspecialchars( $this->BlockAddress );
+ $scBlockReason = htmlspecialchars( $this->BlockReason );
+ $scBlockOtherTime = htmlspecialchars( $this->BlockOther );
+ $scBlockExpiryOptions = htmlspecialchars( wfMsgForContent( 'ipboptions' ) );
+
+ $showblockoptions = $scBlockExpiryOptions != '-';
+ if (!$showblockoptions)
+ $mIpbother = $mIpbexpiry;
+
+ $blockExpiryFormOptions = "<option value=\"other\">$mIpbothertime</option>";
+ foreach (explode(',', $scBlockExpiryOptions) as $option) {
+ if ( strpos($option, ":") === false ) $option = "$option:$option";
+ list($show, $value) = explode(":", $option);
+ $show = htmlspecialchars($show);
+ $value = htmlspecialchars($value);
+ $selected = "";
+ if ($this->BlockExpiry === $value)
+ $selected = ' selected="selected"';
+ $blockExpiryFormOptions .= "<option value=\"$value\"$selected>$show</option>";
+ }
+
+ $token = htmlspecialchars( $wgUser->editToken() );
+
+ $wgOut->addHTML( "
+<form id=\"blockip\" method=\"post\" action=\"{$action}\">
+ <table border='0'>
+ <tr>
+ <td align=\"right\">{$mIpaddress}:</td>
+ <td align=\"left\">
+ <input tabindex='1' type='text' size='40' name=\"wpBlockAddress\" value=\"{$scBlockAddress}\" />
+ </td>
+ </tr>
+ <tr>");
+ if ($showblockoptions) {
+ $wgOut->addHTML("
+ <td align=\"right\">{$mIpbexpiry}:</td>
+ <td align=\"left\">
+ <select tabindex='2' id='wpBlockExpiry' name=\"wpBlockExpiry\" onchange=\"considerChangingExpiryFocus()\">
+ $blockExpiryFormOptions
+ </select>
+ </td>
+ ");
+ }
+ $wgOut->addHTML("
+ </tr>
+ <tr id='wpBlockOther'>
+ <td align=\"right\">{$mIpbother}:</td>
+ <td align=\"left\">
+ <input tabindex='3' type='text' size='40' name=\"wpBlockOther\" value=\"{$scBlockOtherTime}\" />
+ </td>
+ </tr>
+ <tr>
+ <td align=\"right\">{$mIpbreason}:</td>
+ <td align=\"left\">
+ <input tabindex='3' type='text' size='40' name=\"wpBlockReason\" value=\"{$scBlockReason}\" />
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td align=\"left\">
+ " . wfCheckLabel( wfMsg( 'ipbanononly' ),
+ 'wpAnonOnly', 'wpAnonOnly', $this->BlockAnonOnly,
+ array( 'tabindex' => 4 ) ) . "
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td align=\"left\">
+ " . wfCheckLabel( wfMsg( 'ipbcreateaccount' ),
+ 'wpCreateAccount', 'wpCreateAccount', $this->BlockCreateAccount,
+ array( 'tabindex' => 5 ) ) . "
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td align=\"left\">
+ " . wfCheckLabel( wfMsg( 'ipbenableautoblock' ),
+ 'wpEnableAutoblock', 'wpEnableAutoblock', $this->BlockEnableAutoblock,
+ array( 'tabindex' => 6 ) ) . "
+ </td>
+ </tr>
+ <tr>
+ <td style='padding-top: 1em'>&nbsp;</td>
+ <td style='padding-top: 1em' align=\"left\">
+ <input tabindex='7' type='submit' name=\"wpBlock\" value=\"{$mIpbsubmit}\" />
+ </td>
+ </tr>
+ </table>
+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
+</form>\n" );
+
+ $user = User::newFromName( $this->BlockAddress );
+ if( is_object( $user ) ) {
+ $this->showLogFragment( $wgOut, $user->getUserPage() );
+ } elseif( preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $this->BlockAddress ) ) {
+ $this->showLogFragment( $wgOut, Title::makeTitle( NS_USER, $this->BlockAddress ) );
+ }
+
+ }
+
+ function doSubmit() {
+ global $wgOut, $wgUser, $wgSysopUserBans, $wgSysopRangeBans;
+
+ $userId = 0;
+ $this->BlockAddress = trim( $this->BlockAddress );
+ $rxIP = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
+
+ # Check for invalid specifications
+ if ( ! preg_match( "/^$rxIP$/", $this->BlockAddress ) ) {
+ $matches = array();
+ if ( preg_match( "/^($rxIP)\\/(\\d{1,2})$/", $this->BlockAddress, $matches ) ) {
+ if ( $wgSysopRangeBans ) {
+ if ( $matches[2] > 31 || $matches[2] < 16 ) {
+ $this->showForm( wfMsg( 'ip_range_invalid' ) );
+ return;
+ }
+ $this->BlockAddress = Block::normaliseRange( $this->BlockAddress );
+ } else {
+ # Range block illegal
+ $this->showForm( wfMsg( 'range_block_disabled' ) );
+ return;
+ }
+ } else {
+ # Username block
+ if ( $wgSysopUserBans ) {
+ $user = User::newFromName( $this->BlockAddress );
+ if( !is_null( $user ) && $user->getID() ) {
+ # Use canonical name
+ $this->BlockAddress = $user->getName();
+ $userId = $user->getID();
+ } else {
+ $this->showForm( wfMsg( 'nosuchusershort', htmlspecialchars( $this->BlockAddress ) ) );
+ return;
+ }
+ } else {
+ $this->showForm( wfMsg( 'badipaddress' ) );
+ return;
+ }
+ }
+ }
+
+ $expirestr = $this->BlockExpiry;
+ if( $expirestr == 'other' )
+ $expirestr = $this->BlockOther;
+
+ if (strlen($expirestr) == 0) {
+ $this->showForm( wfMsg( 'ipb_expiry_invalid' ) );
+ return;
+ }
+
+ if ( $expirestr == 'infinite' || $expirestr == 'indefinite' ) {
+ $expiry = Block::infinity();
+ } else {
+ # Convert GNU-style date, on error returns -1 for PHP <5.1 and false for PHP >=5.1
+ $expiry = strtotime( $expirestr );
+
+ if ( $expiry < 0 || $expiry === false ) {
+ $this->showForm( wfMsg( 'ipb_expiry_invalid' ) );
+ return;
+ }
+
+ $expiry = wfTimestamp( TS_MW, $expiry );
+ }
+
+ # Create block
+ # Note: for a user block, ipb_address is only for display purposes
+
+ $block = new Block( $this->BlockAddress, $userId, $wgUser->getID(),
+ $this->BlockReason, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly,
+ $this->BlockCreateAccount, $this->BlockEnableAutoblock );
+
+ if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) {
+
+ if ( !$block->insert() ) {
+ $this->showForm( wfMsg( 'ipb_already_blocked',
+ htmlspecialchars( $this->BlockAddress ) ) );
+ return;
+ }
+
+ wfRunHooks('BlockIpComplete', array($block, $wgUser));
+
+ # Make log entry
+ $log = new LogPage( 'block' );
+ $log->addEntry( 'block', Title::makeTitle( NS_USER, $this->BlockAddress ),
+ $this->BlockReason, $expirestr );
+
+ # Report to the user
+ $titleObj = SpecialPage::getTitleFor( 'Blockip' );
+ $wgOut->redirect( $titleObj->getFullURL( 'action=success&ip=' .
+ urlencode( $this->BlockAddress ) ) );
+ }
+ }
+
+ function showSuccess() {
+ global $wgOut;
+
+ $wgOut->setPagetitle( wfMsg( 'blockip' ) );
+ $wgOut->setSubtitle( wfMsg( 'blockipsuccesssub' ) );
+ $text = wfMsg( 'blockipsuccesstext', $this->BlockAddress );
+ $wgOut->addWikiText( $text );
+ }
+
+ function showLogFragment( $out, $title ) {
+ $out->addHtml( wfElement( 'h2', NULL, LogPage::logName( 'block' ) ) );
+ $request = new FauxRequest( array( 'page' => $title->getPrefixedText(), 'type' => 'block' ) );
+ $viewer = new LogViewer( new LogReader( $request ) );
+ $viewer->showList( $out );
+ }
+
+}
+
+?>
diff --git a/includes/SpecialBlockme.php b/includes/SpecialBlockme.php
new file mode 100644
index 000000000000..5bfce4eecda1
--- /dev/null
+++ b/includes/SpecialBlockme.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+function wfSpecialBlockme() {
+ global $wgRequest, $wgBlockOpenProxies, $wgOut, $wgProxyKey;
+
+ $ip = wfGetIP();
+
+ if( !$wgBlockOpenProxies || $wgRequest->getText( 'ip' ) != md5( $ip . $wgProxyKey ) ) {
+ $wgOut->addWikiText( wfMsg( 'disabled' ) );
+ return;
+ }
+
+ $blockerName = wfMsg( "proxyblocker" );
+ $reason = wfMsg( "proxyblockreason" );
+ $success = wfMsg( "proxyblocksuccess" );
+
+ $u = User::newFromName( $blockerName );
+ $id = $u->idForName();
+ if ( !$id ) {
+ $u = User::newFromName( $blockerName );
+ $u->addToDatabase();
+ $u->setPassword( bin2hex( mt_rand(0, 0x7fffffff ) ) );
+ $u->saveSettings();
+ $id = $u->getID();
+ }
+
+ $block = new Block( $ip, 0, $id, $reason, wfTimestampNow() );
+ $block->insert();
+
+ $wgOut->addWikiText( $success );
+}
+?>
diff --git a/includes/SpecialBooksources.php b/includes/SpecialBooksources.php
new file mode 100644
index 000000000000..5c047fbe3419
--- /dev/null
+++ b/includes/SpecialBooksources.php
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * Special page outputs information on sourcing a book with a particular ISBN
+ * The parser creates links to this page when dealing with ISBNs in wikitext
+ *
+ * @package MediaWiki
+ * @subpackage Special pages
+ * @author Rob Church <robchur@gmail.com>
+ * @todo Validate ISBNs using the standard check-digit method
+ */
+class SpecialBookSources extends SpecialPage {
+
+ /**
+ * ISBN passed to the page, if any
+ */
+ private $isbn = '';
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ parent::__construct( 'Booksources' );
+ }
+
+ /**
+ * Show the special page
+ *
+ * @param $isbn ISBN passed as a subpage parameter
+ */
+ public function execute( $isbn = false ) {
+ global $wgOut, $wgRequest;
+ $this->setHeaders();
+ $this->isbn = $this->cleanIsbn( $isbn ? $isbn : $wgRequest->getText( 'isbn' ) );
+ $wgOut->addWikiText( wfMsgNoTrans( 'booksources-summary' ) );
+ $wgOut->addHtml( $this->makeForm() );
+ if( strlen( $this->isbn) > 0 )
+ $this->showList();
+ }
+
+ /**
+ * Trim ISBN and remove characters which aren't required
+ *
+ * @param $isbn Unclean ISBN
+ * @return string
+ */
+ private function cleanIsbn( $isbn ) {
+ return trim( preg_replace( '![^0-9X]!', '', $isbn ) );
+ }
+
+ /**
+ * Generate a form to allow users to enter an ISBN
+ *
+ * @return string
+ */
+ private function makeForm() {
+ global $wgScript;
+ $title = self::getTitleFor( 'Booksources' );
+ $form = '<fieldset><legend>' . wfMsgHtml( 'booksources-search-legend' ) . '</legend>';
+ $form .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
+ $form .= Xml::hidden( 'title', $title->getPrefixedText() );
+ $form .= '<p>' . Xml::inputLabel( wfMsg( 'booksources-isbn' ), 'isbn', 'isbn', 20, $this->isbn );
+ $form .= '&nbsp;' . Xml::submitButton( wfMsg( 'booksources-go' ) ) . '</p>';
+ $form .= Xml::closeElement( 'form' );
+ $form .= '</fieldset>';
+ return $form;
+ }
+
+ /**
+ * Determine where to get the list of book sources from,
+ * format and output them
+ *
+ * @return string
+ */
+ private function showList() {
+ global $wgOut, $wgContLang;
+
+ # Check for a local page such as Project:Book_sources and use that if available
+ $title = Title::makeTitleSafe( NS_PROJECT, wfMsg( 'booksources' ) ); # Should this be wfMsgForContent()? -- RC
+ if( is_object( $title ) && $title->exists() ) {
+ $rev = Revision::newFromTitle( $title );
+ $wgOut->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $rev->getText() ) );
+ return true;
+ }
+
+ # Fall back to the defaults given in the language file
+ $wgOut->addWikiText( wfMsgNoTrans( 'booksources-text' ) );
+ $wgOut->addHtml( '<ul>' );
+ $items = $wgContLang->getBookstoreList();
+ foreach( $items as $label => $url )
+ $wgOut->addHtml( $this->makeListItem( $label, $url ) );
+ $wgOut->addHtml( '</ul>' );
+ return true;
+ }
+
+ /**
+ * Format a book source list item
+ *
+ * @param $label Book source label
+ * @param $url Book source URL
+ * @return string
+ */
+ private function makeListItem( $label, $url ) {
+ $url = str_replace( '$1', $this->isbn, $url );
+ return '<li><a href="' . htmlspecialchars( $url ) . '">' . htmlspecialchars( $label ) . '</a></li>';
+ }
+
+}
+
+?>
diff --git a/includes/SpecialBrokenRedirects.php b/includes/SpecialBrokenRedirects.php
new file mode 100644
index 000000000000..509356540c34
--- /dev/null
+++ b/includes/SpecialBrokenRedirects.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class BrokenRedirectsPage extends PageQueryPage {
+ var $targets = array();
+
+ function getName() {
+ return 'BrokenRedirects';
+ }
+
+ function isExpensive( ) { return true; }
+ function isSyndicated() { return false; }
+
+ function getPageHeader( ) {
+ global $wgOut;
+ return $wgOut->parse( wfMsg( 'brokenredirectstext' ) );
+ }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $pagelinks ) = $dbr->tableNamesN( 'page', 'pagelinks' );
+
+ $sql = "SELECT 'BrokenRedirects' AS type,
+ p1.page_namespace AS namespace,
+ p1.page_title AS title,
+ pl_namespace,
+ pl_title
+ FROM $pagelinks AS pl
+ JOIN $page p1 ON (p1.page_is_redirect=1 AND pl.pl_from=p1.page_id)
+ LEFT JOIN $page AS p2 ON (pl_namespace=p2.page_namespace AND pl_title=p2.page_title )
+ WHERE p2.page_namespace IS NULL";
+ return $sql;
+ }
+
+ function getOrder() {
+ return '';
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgContLang;
+
+ $fromObj = Title::makeTitle( $result->namespace, $result->title );
+ if ( isset( $result->pl_title ) ) {
+ $toObj = Title::makeTitle( $result->pl_namespace, $result->pl_title );
+ } else {
+ $blinks = $fromObj->getBrokenLinksFrom();
+ if ( $blinks ) {
+ $toObj = $blinks[0];
+ } else {
+ $toObj = false;
+ }
+ }
+
+ // $toObj may very easily be false if the $result list is cached
+ if ( !is_object( $toObj ) ) {
+ return '<s>' . $skin->makeLinkObj( $fromObj ) . '</s>';
+ }
+
+ $from = $skin->makeKnownLinkObj( $fromObj ,'', 'redirect=no' );
+ $edit = $skin->makeBrokenLinkObj( $fromObj , "(".wfMsg("qbedit").")" , 'redirect=no');
+ $to = $skin->makeBrokenLinkObj( $toObj );
+ $arr = $wgContLang->getArrow();
+
+ return "$from $edit $arr $to";
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialBrokenRedirects() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $sbr = new BrokenRedirectsPage();
+
+ return $sbr->doQuery( $offset, $limit );
+
+}
+?>
diff --git a/includes/SpecialCategories.php b/includes/SpecialCategories.php
new file mode 100644
index 000000000000..346eac633da7
--- /dev/null
+++ b/includes/SpecialCategories.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class CategoriesPage extends QueryPage {
+
+ function getName() {
+ return "Categories";
+ }
+
+ function isExpensive() {
+ return false;
+ }
+
+ function isSyndicated() { return false; }
+
+ function getPageHeader() {
+ return wfMsgWikiHtml( 'categoriespagetext' );
+ }
+
+ function getSQL() {
+ $NScat = NS_CATEGORY;
+ $dbr =& wfGetDB( DB_SLAVE );
+ $categorylinks = $dbr->tableName( 'categorylinks' );
+ $implicit_groupby = $dbr->implicitGroupby() ? '1' : 'cl_to';
+ $s= "SELECT 'Categories' as type,
+ {$NScat} as namespace,
+ cl_to as title,
+ $implicit_groupby as value,
+ COUNT(*) as count
+ FROM $categorylinks
+ GROUP BY 1,2,3,4";
+ return $s;
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang;
+ $title = Title::makeTitle( NS_CATEGORY, $result->title );
+ $plink = $skin->makeLinkObj( $title, $title->getText() );
+ $nlinks = wfMsgExt( 'nmembers', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->count ) );
+ return wfSpecialList($plink, $nlinks);
+ }
+}
+
+/**
+ *
+ */
+function wfSpecialCategories() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $cap = new CategoriesPage();
+
+ return $cap->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialConfirmemail.php b/includes/SpecialConfirmemail.php
new file mode 100644
index 000000000000..e64232aa9aaf
--- /dev/null
+++ b/includes/SpecialConfirmemail.php
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * Special page allows users to request email confirmation message, and handles
+ * processing of the confirmation code when the link in the email is followed
+ *
+ * @package MediaWiki
+ * @subpackage Special pages
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+/**
+ * Main execution point
+ *
+ * @param $par Parameters passed to the page
+ */
+function wfSpecialConfirmemail( $par ) {
+ $form = new EmailConfirmation();
+ $form->execute( $par );
+}
+
+class EmailConfirmation extends SpecialPage {
+
+ /**
+ * Main execution point
+ *
+ * @param $code Confirmation code passed to the page
+ */
+ function execute( $code ) {
+ global $wgUser, $wgOut;
+ if( empty( $code ) ) {
+ if( $wgUser->isLoggedIn() ) {
+ if( User::isValidEmailAddr( $wgUser->getEmail() ) ) {
+ $this->showRequestForm();
+ } else {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_noemail' ) );
+ }
+ } else {
+ $title = SpecialPage::getTitleFor( 'Userlogin' );
+ $self = SpecialPage::getTitleFor( 'Confirmemail' );
+ $skin = $wgUser->getSkin();
+ $llink = $skin->makeKnownLinkObj( $title, wfMsgHtml( 'loginreqlink' ), 'returnto=' . $self->getPrefixedUrl() );
+ $wgOut->addHtml( wfMsgWikiHtml( 'confirmemail_needlogin', $llink ) );
+ }
+ } else {
+ $this->attemptConfirm( $code );
+ }
+ }
+
+ /**
+ * Show a nice form for the user to request a confirmation mail
+ */
+ function showRequestForm() {
+ global $wgOut, $wgUser, $wgLang, $wgRequest;
+ if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getText( 'token' ) ) ) {
+ $ok = $wgUser->sendConfirmationMail();
+ if ( WikiError::isError( $ok ) ) {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_sendfailed', $ok->toString() ) );
+ } else {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_sent' ) );
+ }
+ } else {
+ if( $wgUser->isEmailConfirmed() ) {
+ $time = $wgLang->timeAndDate( $wgUser->mEmailAuthenticated, true );
+ $wgOut->addWikiText( wfMsg( 'emailauthenticated', $time ) );
+ }
+ if( $wgUser->isEmailConfirmationPending() ) {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_pending' ) );
+ }
+ $wgOut->addWikiText( wfMsg( 'confirmemail_text' ) );
+ $self = SpecialPage::getTitleFor( 'Confirmemail' );
+ $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $self->getLocalUrl() ) );
+ $form .= wfHidden( 'token', $wgUser->editToken() );
+ $form .= wfSubmitButton( wfMsgHtml( 'confirmemail_send' ) );
+ $form .= wfCloseElement( 'form' );
+ $wgOut->addHtml( $form );
+ }
+ }
+
+ /**
+ * Attempt to confirm the user's email address and show success or failure
+ * as needed; if successful, take the user to log in
+ *
+ * @param $code Confirmation code
+ */
+ function attemptConfirm( $code ) {
+ global $wgUser, $wgOut;
+ $user = User::newFromConfirmationCode( $code );
+ if( is_object( $user ) ) {
+ if( $user->confirmEmail() ) {
+ $message = $wgUser->isLoggedIn() ? 'confirmemail_loggedin' : 'confirmemail_success';
+ $wgOut->addWikiText( wfMsg( $message ) );
+ if( !$wgUser->isLoggedIn() ) {
+ $title = SpecialPage::getTitleFor( 'Userlogin' );
+ $wgOut->returnToMain( true, $title->getPrefixedText() );
+ }
+ } else {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_error' ) );
+ }
+ } else {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_invalid' ) );
+ }
+ }
+
+}
+
+?>
diff --git a/includes/SpecialContributions.php b/includes/SpecialContributions.php
new file mode 100644
index 000000000000..0a1ef6ee9d2d
--- /dev/null
+++ b/includes/SpecialContributions.php
@@ -0,0 +1,457 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/** @package MediaWiki */
+class ContribsFinder {
+ var $username, $offset, $limit, $namespace;
+ var $dbr;
+
+ /**
+ * Constructor
+ * @param $username Username as a string
+ */
+ function ContribsFinder( $username ) {
+ $this->username = $username;
+ $this->namespace = false;
+ $this->dbr =& wfGetDB( DB_SLAVE );
+ }
+
+ function setNamespace( $ns ) {
+ $this->namespace = $ns;
+ }
+
+ function setLimit( $limit ) {
+ $this->limit = $limit;
+ }
+
+ function setOffset( $offset ) {
+ $this->offset = $offset;
+ }
+
+ /**
+ * Get timestamp of either first or last contribution made by the user.
+ * @todo Maybe it should be private ?
+ * @param $dir string 'ASC' or 'DESC'.
+ * @return Revision timestamp (rev_timestamp).
+ */
+ function getEditLimit( $dir ) {
+ list( $index, $usercond ) = $this->getUserCond();
+ $nscond = $this->getNamespaceCond();
+ $use_index = $this->dbr->useIndexClause( $index );
+ list( $revision, $page) = $this->dbr->tableNamesN( 'revision', 'page' );
+ $sql = "SELECT rev_timestamp " .
+ " FROM $page,$revision $use_index " .
+ " WHERE rev_page=page_id AND $usercond $nscond" .
+ " ORDER BY rev_timestamp $dir LIMIT 1";
+
+ $res = $this->dbr->query( $sql, __METHOD__ );
+ $row = $this->dbr->fetchObject( $res );
+ if ( $row ) {
+ return $row->rev_timestamp;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get timestamps of first and last contributions made by the user.
+ * @return Array containing first rev_timestamp and last rev_timestamp.
+ */
+ function getEditLimits() {
+ return array(
+ $this->getEditLimit( "ASC" ),
+ $this->getEditLimit( "DESC" )
+ );
+ }
+
+ function getUserCond() {
+ $condition = '';
+
+ if ( $this->username == 'newbies' ) {
+ $max = $this->dbr->selectField( 'user', 'max(user_id)', false, 'make_sql' );
+ $condition = '>' . (int)($max - $max / 100);
+ }
+
+ if ( $condition == '' ) {
+ $condition = ' rev_user_text=' . $this->dbr->addQuotes( $this->username );
+ $index = 'usertext_timestamp';
+ } else {
+ $condition = ' rev_user '.$condition ;
+ $index = 'user_timestamp';
+ }
+ return array( $index, $condition );
+ }
+
+ function getNamespaceCond() {
+ if ( $this->namespace !== false )
+ return ' AND page_namespace = ' . (int)$this->namespace;
+ return '';
+ }
+
+ /**
+ * @return Timestamp of first entry in previous page.
+ */
+ function getPreviousOffsetForPaging() {
+ list( $index, $usercond ) = $this->getUserCond();
+ $nscond = $this->getNamespaceCond();
+
+ $use_index = $this->dbr->useIndexClause( $index );
+ list( $page, $revision ) = $this->dbr->tableNamesN( 'page', 'revision' );
+
+ $sql = "SELECT rev_timestamp FROM $page, $revision $use_index " .
+ "WHERE page_id = rev_page AND rev_timestamp > '" . $this->offset . "' AND " .
+ $usercond . $nscond;
+ $sql .= " ORDER BY rev_timestamp ASC";
+ $sql = $this->dbr->limitResult( $sql, $this->limit, 0 );
+ $res = $this->dbr->query( $sql );
+
+ $numRows = $this->dbr->numRows( $res );
+ if ( $numRows ) {
+ $this->dbr->dataSeek( $res, $numRows - 1 );
+ $row = $this->dbr->fetchObject( $res );
+ $offset = $row->rev_timestamp;
+ } else {
+ $offset = false;
+ }
+ $this->dbr->freeResult( $res );
+ return $offset;
+ }
+
+ /**
+ * @return Timestamp of first entry in next page.
+ */
+ function getFirstOffsetForPaging() {
+ list( $index, $usercond ) = $this->getUserCond();
+ $use_index = $this->dbr->useIndexClause( $index );
+ list( $page, $revision ) = $this->dbr->tableNamesN( 'page', 'revision' );
+ $nscond = $this->getNamespaceCond();
+ $sql = "SELECT rev_timestamp FROM $page, $revision $use_index " .
+ "WHERE page_id = rev_page AND " .
+ $usercond . $nscond;
+ $sql .= " ORDER BY rev_timestamp ASC";
+ $sql = $this->dbr->limitResult( $sql, $this->limit, 0 );
+ $res = $this->dbr->query( $sql );
+
+ $numRows = $this->dbr->numRows( $res );
+ if ( $numRows ) {
+ $this->dbr->dataSeek( $res, $numRows - 1 );
+ $row = $this->dbr->fetchObject( $res );
+ $offset = $row->rev_timestamp;
+ } else {
+ $offset = false;
+ }
+ $this->dbr->freeResult( $res );
+ return $offset;
+ }
+
+ /* private */ function makeSql() {
+ $offsetQuery = '';
+
+ list( $page, $revision ) = $this->dbr->tableNamesN( 'page', 'revision' );
+ list( $index, $userCond ) = $this->getUserCond();
+
+ if ( $this->offset )
+ $offsetQuery = "AND rev_timestamp < '{$this->offset}'";
+
+ $nscond = $this->getNamespaceCond();
+ $use_index = $this->dbr->useIndexClause( $index );
+ $sql = "SELECT
+ page_namespace,page_title,page_is_new,page_latest,
+ rev_id,rev_page,rev_text_id,rev_timestamp,rev_comment,rev_minor_edit,rev_user,rev_user_text,
+ rev_deleted
+ FROM $page,$revision $use_index
+ WHERE page_id=rev_page AND $userCond $nscond $offsetQuery
+ ORDER BY rev_timestamp DESC";
+ $sql = $this->dbr->limitResult( $sql, $this->limit, 0 );
+ return $sql;
+ }
+
+ /**
+ * This do the search for the user given when creating the object.
+ * It should probably be the only public function in this class.
+ * @return Array of contributions.
+ */
+ function find() {
+ $contribs = array();
+ $res = $this->dbr->query( $this->makeSql(), __METHOD__ );
+ while ( $c = $this->dbr->fetchObject( $res ) )
+ $contribs[] = $c;
+ $this->dbr->freeResult( $res );
+ return $contribs;
+ }
+};
+
+/**
+ * Special page "user contributions".
+ * Shows a list of the contributions of a user.
+ *
+ * @return none
+ * @param $par String: (optional) user name of the user for which to show the contributions
+ */
+function wfSpecialContributions( $par = null ) {
+ global $wgUser, $wgOut, $wgLang, $wgRequest;
+
+ $target = isset( $par ) ? $par : $wgRequest->getVal( 'target' );
+ if ( !strlen( $target ) ) {
+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
+ return;
+ }
+
+ $nt = Title::newFromURL( $target );
+ if ( !$nt ) {
+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
+ return;
+ }
+
+ $options = array();
+
+ list( $options['limit'], $options['offset']) = wfCheckLimits();
+ $options['offset'] = $wgRequest->getVal( 'offset' );
+ /* Offset must be an integral. */
+ if ( !strlen( $options['offset'] ) || !preg_match( '/^[0-9]+$/', $options['offset'] ) )
+ $options['offset'] = '';
+
+ $title = SpecialPage::getTitleFor( 'Contributions' );
+ $options['target'] = $target;
+
+ $nt =& Title::makeTitle( NS_USER, $nt->getDBkey() );
+ $finder = new ContribsFinder( ( $target == 'newbies' ) ? 'newbies' : $nt->getText() );
+ $finder->setLimit( $options['limit'] );
+ $finder->setOffset( $options['offset'] );
+
+ if ( ( $ns = $wgRequest->getVal( 'namespace', null ) ) !== null && $ns !== '' ) {
+ $options['namespace'] = intval( $ns );
+ $finder->setNamespace( $options['namespace'] );
+ } else {
+ $options['namespace'] = '';
+ }
+
+ if ( $wgUser->isAllowed( 'rollback' ) && $wgRequest->getBool( 'bot' ) ) {
+ $options['bot'] = '1';
+ }
+
+ if ( $wgRequest->getText( 'go' ) == 'prev' ) {
+ $offset = $finder->getPreviousOffsetForPaging();
+ if ( $offset !== false ) {
+ $options['offset'] = $offset;
+ $prevurl = $title->getLocalURL( wfArrayToCGI( $options ) );
+ $wgOut->redirect( $prevurl );
+ return;
+ }
+ }
+
+ if ( $wgRequest->getText( 'go' ) == 'first' && $target != 'newbies') {
+ $offset = $finder->getFirstOffsetForPaging();
+ if ( $offset !== false ) {
+ $options['offset'] = $offset;
+ $prevurl = $title->getLocalURL( wfArrayToCGI( $options ) );
+ $wgOut->redirect( $prevurl );
+ return;
+ }
+ }
+
+ if ( $target == 'newbies' ) {
+ $wgOut->setSubtitle( wfMsgHtml( 'sp-contributions-newbies-sub') );
+ } else {
+ $wgOut->setSubtitle( wfMsgHtml( 'contribsub', contributionsSub( $nt ) ) );
+ }
+
+ $id = User::idFromName( $nt->getText() );
+ wfRunHooks( 'SpecialContributionsBeforeMainOutput', $id );
+
+ $wgOut->addHTML( contributionsForm( $options) );
+
+ $contribs = $finder->find();
+
+ if ( count( $contribs ) == 0) {
+ $wgOut->addWikiText( wfMsg( 'nocontribs' ) );
+ return;
+ }
+
+ list( $early, $late ) = $finder->getEditLimits();
+ $lastts = count( $contribs ) ? $contribs[count( $contribs ) - 1]->rev_timestamp : 0;
+ $atstart = ( !count( $contribs ) || $late == $contribs[0]->rev_timestamp );
+ $atend = ( !count( $contribs ) || $early == $lastts );
+
+ // These four are defaults
+ $newestlink = wfMsgHtml( 'sp-contributions-newest' );
+ $oldestlink = wfMsgHtml( 'sp-contributions-oldest' );
+ $newerlink = wfMsgHtml( 'sp-contributions-newer', $options['limit'] );
+ $olderlink = wfMsgHtml( 'sp-contributions-older', $options['limit'] );
+
+ if ( !$atstart ) {
+ $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'offset' => '' ), $options ) );
+ $newestlink = "<a href=\"$stuff\">$newestlink</a>";
+ $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'go' => 'prev' ), $options ) );
+ $newerlink = "<a href=\"$stuff\">$newerlink</a>";
+ }
+
+ if ( !$atend ) {
+ $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'go' => 'first' ), $options ) );
+ $oldestlink = "<a href=\"$stuff\">$oldestlink</a>";
+ $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'offset' => $lastts ), $options ) );
+ $olderlink = "<a href=\"$stuff\">$olderlink</a>";
+ }
+
+ if ( $target == 'newbies' ) {
+ $firstlast ="($newestlink)";
+ } else {
+ $firstlast = "($newestlink | $oldestlink)";
+ }
+
+ $urls = array();
+ foreach ( array( 20, 50, 100, 250, 500 ) as $num ) {
+ $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'limit' => $num ), $options ) );
+ $urls[] = "<a href=\"$stuff\">".$wgLang->formatNum( $num )."</a>";
+ }
+ $bits = implode( $urls, ' | ' );
+
+ $prevnextbits = $firstlast .' '. wfMsgHtml( 'viewprevnext', $newerlink, $olderlink, $bits );
+
+ $wgOut->addHTML( "<p>{$prevnextbits}</p>\n" );
+
+ $wgOut->addHTML( "<ul>\n" );
+
+ $sk = $wgUser->getSkin();
+ foreach ( $contribs as $contrib )
+ $wgOut->addHTML( ucListEdit( $sk, $contrib ) );
+
+ $wgOut->addHTML( "</ul>\n" );
+ $wgOut->addHTML( "<p>{$prevnextbits}</p>\n" );
+}
+
+/**
+ * Generates the subheading with links
+ * @param $nt @see Title object for the target
+ */
+function contributionsSub( $nt ) {
+ global $wgSysopUserBans, $wgLang, $wgUser;
+
+ $sk = $wgUser->getSkin();
+ $id = User::idFromName( $nt->getText() );
+
+ if ( 0 == $id ) {
+ $ul = $nt->getText();
+ } else {
+ $ul = $sk->makeLinkObj( $nt, htmlspecialchars( $nt->getText() ) );
+ }
+ $talk = $nt->getTalkPage();
+ if( $talk ) {
+ # Talk page link
+ $tools[] = $sk->makeLinkObj( $talk, $wgLang->getNsText( NS_TALK ) );
+ if( ( $id != 0 && $wgSysopUserBans ) || ( $id == 0 && User::isIP( $nt->getText() ) ) ) {
+ # Block link
+ if( $wgUser->isAllowed( 'block' ) )
+ $tools[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Blockip', $nt->getDBkey() ), wfMsgHtml( 'blocklink' ) );
+ # Block log link
+ $tools[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ), wfMsgHtml( 'sp-contributions-blocklog' ), 'type=block&page=' . $nt->getPrefixedUrl() );
+ }
+ # Other logs link
+ $tools[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ), wfMsgHtml( 'log' ), 'user=' . $nt->getPartialUrl() );
+ $ul .= ' (' . implode( ' | ', $tools ) . ')';
+ }
+ return $ul;
+}
+
+/**
+ * Generates the namespace selector form with hidden attributes.
+ * @param $options Array: the options to be included.
+ */
+function contributionsForm( $options ) {
+ global $wgScript, $wgTitle;
+
+ $options['title'] = $wgTitle->getPrefixedText();
+
+ $f = "<form method='get' action=\"$wgScript\">\n";
+ foreach ( $options as $name => $value ) {
+ if( $name === 'namespace') continue;
+ $f .= "\t" . wfElement( 'input', array(
+ 'name' => $name,
+ 'type' => 'hidden',
+ 'value' => $value ) ) . "\n";
+ }
+
+ $f .= '<p>' . wfMsgHtml( 'namespace' ) . ' ' .
+ HTMLnamespaceselector( $options['namespace'], '' ) .
+ wfElement( 'input', array(
+ 'type' => 'submit',
+ 'value' => wfMsg( 'allpagessubmit' ) )
+ ) .
+ "</p></form>\n";
+
+ return $f;
+}
+
+/**
+ * Generates each row in the contributions list.
+ *
+ * Contributions which are marked "top" are currently on top of the history.
+ * For these contributions, a [rollback] link is shown for users with sysop
+ * privileges. The rollback link restores the most recent version that was not
+ * written by the target user.
+ *
+ * @todo This would probably look a lot nicer in a table.
+ */
+function ucListEdit( $sk, $row ) {
+ $fname = 'ucListEdit';
+ wfProfileIn( $fname );
+
+ global $wgLang, $wgUser, $wgRequest;
+ static $messages;
+ if( !isset( $messages ) ) {
+ foreach( explode( ' ', 'uctop diff newarticle rollbacklink diff hist minoreditletter' ) as $msg ) {
+ $messages[$msg] = wfMsgExt( $msg, array( 'escape') );
+ }
+ }
+
+ $rev = new Revision( $row );
+
+ $page = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $link = $sk->makeKnownLinkObj( $page );
+ $difftext = $topmarktext = '';
+ if( $row->rev_id == $row->page_latest ) {
+ $topmarktext .= '<strong>' . $messages['uctop'] . '</strong>';
+ if( !$row->page_is_new ) {
+ $difftext .= '(' . $sk->makeKnownLinkObj( $page, $messages['diff'], 'diff=0' ) . ')';
+ } else {
+ $difftext .= $messages['newarticle'];
+ }
+
+ if( $wgUser->isAllowed( 'rollback' ) ) {
+ $topmarktext .= ' '.$sk->generateRollback( $rev );
+ }
+
+ }
+ if( $rev->userCan( Revision::DELETED_TEXT ) ) {
+ $difftext = '(' . $sk->makeKnownLinkObj( $page, $messages['diff'], 'diff=prev&oldid='.$row->rev_id ) . ')';
+ } else {
+ $difftext = '(' . $messages['diff'] . ')';
+ }
+ $histlink='('.$sk->makeKnownLinkObj( $page, $messages['hist'], 'action=history' ) . ')';
+
+ $comment = $sk->revComment( $rev );
+ $d = $wgLang->timeanddate( wfTimestamp( TS_MW, $row->rev_timestamp ), true );
+
+ if( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+ $d = '<span class="history-deleted">' . $d . '</span>';
+ }
+
+ if( $row->rev_minor_edit ) {
+ $mflag = '<span class="minor">' . $messages['minoreditletter'] . '</span> ';
+ } else {
+ $mflag = '';
+ }
+
+ $ret = "{$d} {$histlink} {$difftext} {$mflag} {$link} {$comment} {$topmarktext}";
+ if( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+ $ret .= ' ' . wfMsgHtml( 'deletedrev' );
+ }
+ $ret = "<li>$ret</li>\n";
+ wfProfileOut( $fname );
+ return $ret;
+}
+
+?>
diff --git a/includes/SpecialDeadendpages.php b/includes/SpecialDeadendpages.php
new file mode 100644
index 000000000000..4ffe5e03316e
--- /dev/null
+++ b/includes/SpecialDeadendpages.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class DeadendPagesPage extends PageQueryPage {
+
+ function getName( ) {
+ return "Deadendpages";
+ }
+
+ function getPageHeader() {
+ return '<p>' . wfMsg('deadendpagestext') . '</p>';
+ }
+
+ /**
+ * LEFT JOIN is expensive
+ *
+ * @return true
+ */
+ function isExpensive( ) {
+ return 1;
+ }
+
+ function isSyndicated() { return false; }
+
+ /**
+ * @return false
+ */
+ function sortDescending() {
+ return false;
+ }
+
+ /**
+ * @return string an sqlquery
+ */
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $pagelinks ) = $dbr->tableNamesN( 'page', 'pagelinks' );
+ return "SELECT 'Deadendpages' as type, page_namespace AS namespace, page_title as title, page_title AS value " .
+ "FROM $page LEFT JOIN $pagelinks ON page_id = pl_from " .
+ "WHERE pl_from IS NULL " .
+ "AND page_namespace = 0 " .
+ "AND page_is_redirect = 0";
+ }
+}
+
+/**
+ * Constructor
+ */
+function wfSpecialDeadendpages() {
+
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $depp = new DeadendPagesPage();
+
+ return $depp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialDisambiguations.php b/includes/SpecialDisambiguations.php
new file mode 100644
index 000000000000..626b967c2add
--- /dev/null
+++ b/includes/SpecialDisambiguations.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class DisambiguationsPage extends PageQueryPage {
+
+ function getName() {
+ return 'Disambiguations';
+ }
+
+ function isExpensive( ) { return true; }
+ function isSyndicated() { return false; }
+
+ function getDisambiguationPageObj() {
+ return Title::makeTitleSafe( NS_MEDIAWIKI, 'disambiguationspage');
+ }
+
+ function getPageHeader( ) {
+ global $wgUser;
+ $sk = $wgUser->getSkin();
+
+ return '<p>'.wfMsg('disambiguationstext', $sk->makeKnownLinkObj($this->getDisambiguationPageObj()))."</p><br />\n";
+ }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $pagelinks, $templatelinks) = $dbr->tableNamesN( 'page', 'pagelinks', 'templatelinks' );
+
+ $dMsgText = wfMsgForContent('disambiguationspage');
+
+ $linkBatch = new LinkBatch;
+
+ # If the text can be treated as a title, use it verbatim.
+ # Otherwise, pull the titles from the links table
+ $dp = Title::newFromText($dMsgText);
+ if( $dp ) {
+ if($dp->getNamespace() != NS_TEMPLATE) {
+ # FIXME we assume the disambiguation message is a template but
+ # the page can potentially be from another namespace :/
+ wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n");
+ }
+ $linkBatch->addObj( $dp );
+ } else {
+ # Get all the templates linked from the Mediawiki:Disambiguationspage
+ $disPageObj = $this->getDisambiguationPageObj();
+ $res = $dbr->select(
+ array('pagelinks', 'page'),
+ 'pl_title',
+ array('page_id = pl_from', 'pl_namespace' => NS_TEMPLATE,
+ 'page_namespace' => $disPageObj->getNamespace(), 'page_title' => $disPageObj->getDBkey()),
+ 'DisambiguationsPage::getSQL' );
+
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $linkBatch->addObj( Title::makeTitle( NS_TEMPLATE, $row->pl_title ));
+ }
+ $dbr->freeResult( $res );
+ }
+
+ $set = $linkBatch->constructSet( 'lb.tl', $dbr );
+ if( $set === false ) {
+ $set = 'FALSE'; # We must always return a valid sql query, but this way DB will always quicly return an empty result
+ wfDebug("Mediawiki:disambiguationspage message does not link to any templates!\n");
+ }
+
+ $sql = "SELECT 'Disambiguations' AS \"type\", pb.page_namespace AS namespace,"
+ ." pb.page_title AS title, la.pl_from AS value"
+ ." FROM {$templatelinks} AS lb, {$page} AS pb, {$pagelinks} AS la, {$page} AS pa"
+ ." WHERE $set" # disambiguation template(s)
+ .' AND pa.page_id = la.pl_from'
+ .' AND pa.page_namespace = ' . NS_MAIN # Limit to just articles in the main namespace
+ .' AND pb.page_id = lb.tl_from'
+ .' AND pb.page_namespace = la.pl_namespace'
+ .' AND pb.page_title = la.pl_title'
+ .' ORDER BY lb.tl_namespace, lb.tl_title';
+
+ return $sql;
+ }
+
+ function getOrder() {
+ return '';
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgContLang;
+ $title = Title::newFromId( $result->value );
+ $dp = Title::makeTitle( $result->namespace, $result->title );
+
+ $from = $skin->makeKnownLinkObj( $title,'');
+ $edit = $skin->makeBrokenLinkObj( $title, "(".wfMsg("qbedit").")" , 'redirect=no');
+ $arr = $wgContLang->getArrow();
+ $to = $skin->makeKnownLinkObj( $dp,'');
+
+ return "$from $edit $arr $to";
+ }
+}
+
+/**
+ * Constructor
+ */
+function wfSpecialDisambiguations() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $sd = new DisambiguationsPage();
+
+ return $sd->doQuery( $offset, $limit );
+}
+?>
diff --git a/includes/SpecialDoubleRedirects.php b/includes/SpecialDoubleRedirects.php
new file mode 100644
index 000000000000..cf1153eaccac
--- /dev/null
+++ b/includes/SpecialDoubleRedirects.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class DoubleRedirectsPage extends PageQueryPage {
+
+ function getName() {
+ return 'DoubleRedirects';
+ }
+
+ function isExpensive( ) { return true; }
+ function isSyndicated() { return false; }
+
+ function getPageHeader( ) {
+ #FIXME : probably need to add a backlink to the maintenance page.
+ return '<p>'.wfMsg("doubleredirectstext")."</p><br />\n";
+ }
+
+ function getSQLText( &$dbr, $namespace = null, $title = null ) {
+
+ list( $page, $pagelinks ) = $dbr->tableNamesN( 'page', 'pagelinks' );
+
+ $limitToTitle = !( $namespace === null && $title === null );
+ $sql = $limitToTitle ? "SELECT" : "SELECT 'DoubleRedirects' as type," ;
+ $sql .=
+ " pa.page_namespace as namespace, pa.page_title as title," .
+ " pb.page_namespace as nsb, pb.page_title as tb," .
+ " pc.page_namespace as nsc, pc.page_title as tc" .
+ " FROM $pagelinks AS la, $pagelinks AS lb, $page AS pa, $page AS pb, $page AS pc" .
+ " WHERE pa.page_is_redirect=1 AND pb.page_is_redirect=1" .
+ " AND la.pl_from=pa.page_id" .
+ " AND la.pl_namespace=pb.page_namespace" .
+ " AND la.pl_title=pb.page_title" .
+ " AND lb.pl_from=pb.page_id" .
+ " AND lb.pl_namespace=pc.page_namespace" .
+ " AND lb.pl_title=pc.page_title";
+
+ if( $limitToTitle ) {
+ $encTitle = $dbr->addQuotes( $title );
+ $sql .= " AND pa.page_namespace=$namespace" .
+ " AND pa.page_title=$encTitle";
+ }
+
+ return $sql;
+ }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $this->getSQLText( $dbr );
+ }
+
+ function getOrder() {
+ return '';
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgContLang;
+
+ $fname = 'DoubleRedirectsPage::formatResult';
+ $titleA = Title::makeTitle( $result->namespace, $result->title );
+
+ if ( $result && !isset( $result->nsb ) ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $sql = $this->getSQLText( $dbr, $result->namespace, $result->title );
+ $res = $dbr->query( $sql, $fname );
+ if ( $res ) {
+ $result = $dbr->fetchObject( $res );
+ $dbr->freeResult( $res );
+ }
+ }
+ if ( !$result ) {
+ return '';
+ }
+
+ $titleB = Title::makeTitle( $result->nsb, $result->tb );
+ $titleC = Title::makeTitle( $result->nsc, $result->tc );
+
+ $linkA = $skin->makeKnownLinkObj( $titleA,'', 'redirect=no' );
+ $edit = $skin->makeBrokenLinkObj( $titleA, "(".wfMsg("qbedit").")" , 'redirect=no');
+ $linkB = $skin->makeKnownLinkObj( $titleB, '', 'redirect=no' );
+ $linkC = $skin->makeKnownLinkObj( $titleC );
+ $arr = $wgContLang->getArrow() . $wgContLang->getDirMark();
+
+ return( "{$linkA} {$edit} {$arr} {$linkB} {$arr} {$linkC}" );
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialDoubleRedirects() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $sdr = new DoubleRedirectsPage();
+
+ return $sdr->doQuery( $offset, $limit );
+
+}
+?>
diff --git a/includes/SpecialEmailuser.php b/includes/SpecialEmailuser.php
new file mode 100644
index 000000000000..38745a370853
--- /dev/null
+++ b/includes/SpecialEmailuser.php
@@ -0,0 +1,183 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+require_once('UserMailer.php');
+
+function wfSpecialEmailuser( $par ) {
+ global $wgUser, $wgOut, $wgRequest, $wgEnableEmail, $wgEnableUserEmail;
+
+ if( !( $wgEnableEmail && $wgEnableUserEmail ) ) {
+ $wgOut->showErrorPage( "nosuchspecialpage", "nospecialpagetext" );
+ return;
+ }
+
+ if( !$wgUser->canSendEmail() ) {
+ wfDebug( "User can't send.\n" );
+ $wgOut->showErrorPage( "mailnologin", "mailnologintext" );
+ return;
+ }
+
+ $action = $wgRequest->getVal( 'action' );
+ $target = isset($par) ? $par : $wgRequest->getVal( 'target' );
+ if ( "" == $target ) {
+ wfDebug( "Target is empty.\n" );
+ $wgOut->showErrorPage( "notargettitle", "notargettext" );
+ return;
+ }
+
+ $nt = Title::newFromURL( $target );
+ if ( is_null( $nt ) ) {
+ wfDebug( "Target is invalid title.\n" );
+ $wgOut->showErrorPage( "notargettitle", "notargettext" );
+ return;
+ }
+
+ $nu = User::newFromName( $nt->getText() );
+ if( is_null( $nu ) || !$nu->canReceiveEmail() ) {
+ wfDebug( "Target is invalid user or can't receive.\n" );
+ $wgOut->showErrorPage( "noemailtitle", "noemailtext" );
+ return;
+ }
+
+ $f = new EmailUserForm( $nu );
+
+ if ( "success" == $action ) {
+ $f->showSuccess( $nu );
+ } else if ( "submit" == $action && $wgRequest->wasPosted() &&
+ $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
+ $f->doSubmit();
+ } else {
+ $f->showForm();
+ }
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class EmailUserForm {
+
+ var $target;
+ var $text, $subject;
+ var $cc_me; // Whether user requested to be sent a separate copy of their email.
+
+ /**
+ * @param User $target
+ */
+ function EmailUserForm( $target ) {
+ global $wgRequest;
+ $this->target = $target;
+ $this->text = $wgRequest->getText( 'wpText' );
+ $this->subject = $wgRequest->getText( 'wpSubject' );
+ $this->cc_me = $wgRequest->getBool( 'wpCCMe' );
+ }
+
+ function showForm() {
+ global $wgOut, $wgUser;
+
+ $wgOut->setPagetitle( wfMsg( "emailpage" ) );
+ $wgOut->addWikiText( wfMsg( "emailpagetext" ) );
+
+ if ( $this->subject === "" ) {
+ $this->subject = wfMsg( "defemailsubject" );
+ }
+
+ $emf = wfMsg( "emailfrom" );
+ $sender = $wgUser->getName();
+ $emt = wfMsg( "emailto" );
+ $rcpt = $this->target->getName();
+ $emr = wfMsg( "emailsubject" );
+ $emm = wfMsg( "emailmessage" );
+ $ems = wfMsg( "emailsend" );
+ $emc = wfMsg( "emailccme" );
+ $encSubject = htmlspecialchars( $this->subject );
+
+ $titleObj = SpecialPage::getTitleFor( "Emailuser" );
+ $action = $titleObj->escapeLocalURL( "target=" .
+ urlencode( $this->target->getName() ) . "&action=submit" );
+ $token = $wgUser->editToken();
+
+ $wgOut->addHTML( "
+<form id=\"emailuser\" method=\"post\" action=\"{$action}\">
+<table border='0' id='mailheader'><tr>
+<td align='right'>{$emf}:</td>
+<td align='left'><strong>" . htmlspecialchars( $sender ) . "</strong></td>
+</tr><tr>
+<td align='right'>{$emt}:</td>
+<td align='left'><strong>" . htmlspecialchars( $rcpt ) . "</strong></td>
+</tr><tr>
+<td align='right'>{$emr}:</td>
+<td align='left'>
+<input type='text' size='60' maxlength='200' name=\"wpSubject\" value=\"{$encSubject}\" />
+</td>
+</tr>
+</table>
+<span id='wpTextLabel'><label for=\"wpText\">{$emm}:</label><br /></span>
+<textarea name=\"wpText\" rows='20' cols='80' wrap='virtual' style=\"width: 100%;\">" . htmlspecialchars( $this->text ) .
+"</textarea>
+" . wfCheckLabel( $emc, 'wpCCMe', 'wpCCMe', $wgUser->getBoolOption( 'ccmeonemails' ) ) . "<br />
+<input type='submit' name=\"wpSend\" value=\"{$ems}\" />
+<input type='hidden' name='wpEditToken' value=\"$token\" />
+</form>\n" );
+
+ }
+
+ function doSubmit() {
+ global $wgOut, $wgUser;
+
+ $to = new MailAddress( $this->target );
+ $from = new MailAddress( $wgUser );
+ $subject = $this->subject;
+
+ if( wfRunHooks( 'EmailUser', array( &$to, &$from, &$subject, &$this->text ) ) ) {
+
+ $mailResult = userMailer( $to, $from, $subject, $this->text );
+
+ if( WikiError::isError( $mailResult ) ) {
+ $wgOut->addHTML( wfMsg( "usermailererror" ) . $mailResult);
+ } else {
+
+ // if the user requested a copy of this mail, do this now,
+ // unless they are emailing themselves, in which case one copy of the message is sufficient.
+ if ($this->cc_me && $to != $from) {
+ $cc_subject = wfMsg('emailccsubject', $this->target->getName(), $subject);
+ if( wfRunHooks( 'EmailUser', array( &$from, &$from, &$cc_subject, &$this->text ) ) ) {
+ $ccResult = userMailer( $from, $from, $cc_subject, $this->text );
+ if( WikiError::isError( $ccResult ) ) {
+ // At this stage, the user's CC mail has failed, but their
+ // original mail has succeeded. It's unlikely, but still, what to do?
+ // We can either show them an error, or we can say everything was fine,
+ // or we can say we sort of failed AND sort of succeeded. Of these options,
+ // simply saying there was an error is probably best.
+ $wgOut->addHTML( wfMsg( "usermailererror" ) . $ccResult);
+ return;
+ }
+ }
+ }
+
+ $titleObj = SpecialPage::getTitleFor( "Emailuser" );
+ $encTarget = wfUrlencode( $this->target->getName() );
+ $wgOut->redirect( $titleObj->getFullURL( "target={$encTarget}&action=success" ) );
+ wfRunHooks( 'EmailUserComplete', array( $to, $from, $subject, $this->text ) );
+ }
+ }
+ }
+
+ function showSuccess( &$user ) {
+ global $wgOut;
+
+ $wgOut->setPagetitle( wfMsg( "emailsent" ) );
+ $wgOut->addHTML( wfMsg( "emailsenttext" ) );
+
+ $wgOut->returnToMain( false, $user->getUserPage() );
+ }
+}
+?>
diff --git a/includes/SpecialExport.php b/includes/SpecialExport.php
new file mode 100644
index 000000000000..5e6d6d8ddaff
--- /dev/null
+++ b/includes/SpecialExport.php
@@ -0,0 +1,131 @@
+<?php
+# Copyright (C) 2003 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+function wfSpecialExport( $page = '' ) {
+ global $wgOut, $wgRequest, $wgExportAllowListContributors;
+ global $wgExportAllowHistory, $wgExportMaxHistory;
+
+ $curonly = true;
+ if( $wgRequest->wasPosted() ) {
+ $page = $wgRequest->getText( 'pages' );
+ $curonly = $wgRequest->getCheck( 'curonly' );
+ $rawOffset = $wgRequest->getVal( 'offset' );
+ if( $rawOffset ) {
+ $offset = wfTimestamp( TS_MW, $rawOffset );
+ } else {
+ $offset = null;
+ }
+ $limit = $wgRequest->getInt( 'limit' );
+ $dir = $wgRequest->getVal( 'dir' );
+ $history = array(
+ 'dir' => 'asc',
+ 'offset' => false,
+ 'limit' => $wgExportMaxHistory,
+ );
+ $historyCheck = $wgRequest->getCheck( 'history' );
+ if ( $curonly ) {
+ $history = WikiExporter::CURRENT;
+ } elseif ( !$historyCheck ) {
+ if ( $limit > 0 && $limit < $wgExportMaxHistory ) {
+ $history['limit'] = $limit;
+ }
+ if ( !is_null( $offset ) ) {
+ $history['offset'] = $offset;
+ }
+ if ( strtolower( $dir ) == 'desc' ) {
+ $history['dir'] = 'desc';
+ }
+ }
+ } else {
+ // Default to current-only for GET requests
+ $page = $wgRequest->getText( 'pages', $page );
+ $historyCheck = $wgRequest->getCheck( 'history' );
+ if( $historyCheck ) {
+ $history = WikiExporter::FULL;
+ } else {
+ $history = WikiExporter::CURRENT;
+ }
+ }
+ if( !$wgExportAllowHistory ) {
+ // Override
+ $history = WikiExporter::CURRENT;
+ }
+
+ $list_authors = $wgRequest->getCheck( 'listauthors' );
+ if ( !$curonly || !$wgExportAllowListContributors ) $list_authors = false ;
+
+ if( $page != '' ) {
+ $wgOut->disable();
+
+ // Cancel output buffering and gzipping if set
+ // This should provide safer streaming for pages with history
+ wfResetOutputBuffers();
+ header( "Content-type: application/xml; charset=utf-8" );
+ $pages = explode( "\n", $page );
+
+ $db =& wfGetDB( DB_SLAVE );
+ $exporter = new WikiExporter( $db, $history );
+ $exporter->list_authors = $list_authors ;
+ $exporter->openStream();
+
+ foreach( $pages as $page ) {
+ /*
+ if( $wgExportMaxHistory && !$curonly ) {
+ $title = Title::newFromText( $page );
+ if( $title ) {
+ $count = Revision::countByTitle( $db, $title );
+ if( $count > $wgExportMaxHistory ) {
+ wfDebug( __FUNCTION__ .
+ ": Skipped $page, $count revisions too big\n" );
+ continue;
+ }
+ }
+ }*/
+ $exporter->pageByName( $page );
+ }
+
+ $exporter->closeStream();
+ return;
+ }
+
+ $wgOut->addWikiText( wfMsg( "exporttext" ) );
+ $titleObj = SpecialPage::getTitleFor( "Export" );
+
+ $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $titleObj->getLocalUrl() ) );
+ $form .= wfOpenElement( 'textarea', array( 'name' => 'pages', 'cols' => 40, 'rows' => 10 ) ) . '</textarea><br />';
+ if( $wgExportAllowHistory ) {
+ $form .= wfCheck( 'curonly', true, array( 'value' => 'true', 'id' => 'curonly' ) );
+ $form .= wfLabel( wfMsg( 'exportcuronly' ), 'curonly' ) . '<br />';
+ } else {
+ $wgOut->addWikiText( wfMsg( 'exportnohistory' ) );
+ }
+ $form .= wfHidden( 'action', 'submit' );
+ $form .= wfSubmitButton( wfMsg( 'export-submit' ) ) . '</form>';
+ $wgOut->addHtml( $form );
+}
+
+?>
diff --git a/includes/SpecialImagelist.php b/includes/SpecialImagelist.php
new file mode 100644
index 000000000000..5ecbe8a627b6
--- /dev/null
+++ b/includes/SpecialImagelist.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+function wfSpecialImagelist() {
+ global $wgOut;
+
+ $pager = new ImageListPager;
+
+ $limit = $pager->getForm();
+ $body = $pager->getBody();
+ $nav = $pager->getNavigationBar();
+ $wgOut->addHTML(
+ $limit
+ . '<br/>'
+ . $body
+ . '<br/>'
+ . $nav );
+}
+
+class ImageListPager extends TablePager {
+ var $mFieldNames = null;
+ var $mMessages = array();
+ var $mQueryConds = array();
+
+ function __construct() {
+ global $wgRequest, $wgMiserMode;
+ if ( $wgRequest->getText( 'sort', 'img_date' ) == 'img_date' ) {
+ $this->mDefaultDirection = true;
+ } else {
+ $this->mDefaultDirection = false;
+ }
+ $search = $wgRequest->getText( 'ilsearch' );
+ if ( $search != '' && !$wgMiserMode ) {
+ $nt = Title::newFromUrl( $search );
+ if( $nt ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $m = $dbr->strencode( strtolower( $nt->getDBkey() ) );
+ $m = str_replace( "%", "\\%", $m );
+ $m = str_replace( "_", "\\_", $m );
+ $this->mQueryConds = array( "LCASE(img_name) LIKE '%{$m}%'" );
+ }
+ }
+
+ parent::__construct();
+ }
+
+ function getFieldNames() {
+ if ( !$this->mFieldNames ) {
+ $this->mFieldNames = array(
+ 'links' => '',
+ 'img_timestamp' => wfMsg( 'imagelist_date' ),
+ 'img_name' => wfMsg( 'imagelist_name' ),
+ 'img_user_text' => wfMsg( 'imagelist_user' ),
+ 'img_size' => wfMsg( 'imagelist_size' ),
+ 'img_description' => wfMsg( 'imagelist_description' ),
+ );
+ }
+ return $this->mFieldNames;
+ }
+
+ function isFieldSortable( $field ) {
+ static $sortable = array( 'img_timestamp', 'img_name', 'img_size' );
+ return in_array( $field, $sortable );
+ }
+
+ function getQueryInfo() {
+ $fields = $this->getFieldNames();
+ unset( $fields['links'] );
+ $fields = array_keys( $fields );
+ $fields[] = 'img_user';
+ return array(
+ 'tables' => 'image',
+ 'fields' => $fields,
+ 'conds' => $this->mQueryConds
+ );
+ }
+
+ function getDefaultSort() {
+ return 'img_timestamp';
+ }
+
+ function getStartBody() {
+ # Do a link batch query for user pages
+ if ( $this->mResult->numRows() ) {
+ $lb = new LinkBatch;
+ $this->mResult->seek( 0 );
+ while ( $row = $this->mResult->fetchObject() ) {
+ if ( $row->img_user ) {
+ $lb->add( NS_USER, str_replace( ' ', '_', $row->img_user_text ) );
+ }
+ }
+ $lb->execute();
+ }
+
+ # Cache messages used in each row
+ $this->mMessages['imgdesc'] = wfMsgHtml( 'imgdesc' );
+ $this->mMessages['imgfile'] = wfMsgHtml( 'imgfile' );
+
+ return parent::getStartBody();
+ }
+
+ function formatValue( $field, $value ) {
+ global $wgLang;
+ switch ( $field ) {
+ case 'links':
+ $name = $this->mCurrentRow->img_name;
+ $ilink = "<a href=\"" . htmlspecialchars( Image::imageUrl( $name ) ) .
+ "\">" . $this->mMessages['imgfile'] . "</a>";
+ $desc = $this->getSkin()->makeKnownLinkObj( Title::makeTitle( NS_IMAGE, $name ),
+ $this->mMessages['imgdesc'] );
+ return "$desc | $ilink";
+ case 'img_timestamp':
+ return $wgLang->timeanddate( $value, true );
+ case 'img_name':
+ return htmlspecialchars( $value );
+ case 'img_user_text':
+ if ( $this->mCurrentRow->img_user ) {
+ $link = $this->getSkin()->makeLinkObj( Title::makeTitle( NS_USER, $value ),
+ htmlspecialchars( $value ) );
+ } else {
+ $link = htmlspecialchars( $value );
+ }
+ return $link;
+ case 'img_size':
+ return $wgLang->formatNum( $value );
+ case 'img_description':
+ return $this->getSkin()->commentBlock( $value );
+ }
+ }
+
+ function getForm() {
+ global $wgRequest, $wgMiserMode;
+ $url = $this->getTitle()->escapeLocalURL();
+ $msgSubmit = wfMsgHtml( 'table_pager_limit_submit' );
+ $msgSearch = wfMsgHtml( 'imagelist_search_for' );
+ $search = $wgRequest->getText( 'ilsearch' );
+ $encSearch = htmlspecialchars( $search );
+ $s = "<form method=\"get\" action=\"$url\">\n" .
+ wfMsgHtml( 'table_pager_limit', $this->getLimitSelect() );
+ if ( !$wgMiserMode ) {
+ $s .= "<br/>\n" . $msgSearch .
+ " <input type=\"text\" size=\"20\" name=\"ilsearch\" value=\"$encSearch\"/><br/>\n";
+ }
+ $s .= " <input type=\"submit\" value=\"$msgSubmit\"/>\n" .
+ $this->getHiddenFields( array( 'limit', 'ilsearch' ) ) .
+ "</form>\n";
+ return $s;
+ }
+
+ function getTableClass() {
+ return 'imagelist ' . parent::getTableClass();
+ }
+
+ function getNavClass() {
+ return 'imagelist_nav ' . parent::getNavClass();
+ }
+
+ function getSortHeaderClass() {
+ return 'imagelist_sort ' . parent::getSortHeaderClass();
+ }
+}
+
+?>
diff --git a/includes/SpecialImport.php b/includes/SpecialImport.php
new file mode 100644
index 000000000000..1c8ee2e05790
--- /dev/null
+++ b/includes/SpecialImport.php
@@ -0,0 +1,859 @@
+<?php
+/**
+ * MediaWiki page data importer
+ * Copyright (C) 2003,2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Constructor
+ */
+function wfSpecialImport( $page = '' ) {
+ global $wgUser, $wgOut, $wgRequest, $wgTitle, $wgImportSources;
+ global $wgImportTargetNamespace;
+
+ $interwiki = false;
+ $namespace = $wgImportTargetNamespace;
+ $frompage = '';
+ $history = true;
+
+ if( $wgRequest->wasPosted() && $wgRequest->getVal( 'action' ) == 'submit') {
+ $isUpload = false;
+ $namespace = $wgRequest->getIntOrNull( 'namespace' );
+
+ switch( $wgRequest->getVal( "source" ) ) {
+ case "upload":
+ $isUpload = true;
+ if( $wgUser->isAllowed( 'importupload' ) ) {
+ $source = ImportStreamSource::newFromUpload( "xmlimport" );
+ } else {
+ return $wgOut->permissionRequired( 'importupload' );
+ }
+ break;
+ case "interwiki":
+ $interwiki = $wgRequest->getVal( 'interwiki' );
+ $history = $wgRequest->getCheck( 'interwikiHistory' );
+ $frompage = $wgRequest->getText( "frompage" );
+ $source = ImportStreamSource::newFromInterwiki(
+ $interwiki,
+ $frompage,
+ $history );
+ break;
+ default:
+ $source = new WikiErrorMsg( "importunknownsource" );
+ }
+
+ if( WikiError::isError( $source ) ) {
+ $wgOut->addWikiText( wfEscapeWikiText( $source->getMessage() ) );
+ } else {
+ $wgOut->addWikiText( wfMsg( "importstart" ) );
+
+ $importer = new WikiImporter( $source );
+ if( !is_null( $namespace ) ) {
+ $importer->setTargetNamespace( $namespace );
+ }
+ $reporter = new ImportReporter( $importer, $isUpload, $interwiki );
+
+ $reporter->open();
+ $result = $importer->doImport();
+ $reporter->close();
+
+ if( WikiError::isError( $result ) ) {
+ $wgOut->addWikiText( wfMsg( "importfailed",
+ wfEscapeWikiText( $result->getMessage() ) ) );
+ } else {
+ # Success!
+ $wgOut->addWikiText( wfMsg( "importsuccess" ) );
+ }
+ }
+ }
+
+ $action = $wgTitle->escapeLocalUrl( 'action=submit' );
+
+ if( $wgUser->isAllowed( 'importupload' ) ) {
+ $wgOut->addWikiText( wfMsg( "importtext" ) );
+ $wgOut->addHTML( "
+<fieldset>
+ <legend>" . wfMsgHtml('upload') . "</legend>
+ <form enctype='multipart/form-data' method='post' action=\"$action\">
+ <input type='hidden' name='action' value='submit' />
+ <input type='hidden' name='source' value='upload' />
+ <input type='hidden' name='MAX_FILE_SIZE' value='2000000' />
+ <input type='file' name='xmlimport' value='' size='30' />
+ <input type='submit' value=\"" . wfMsgHtml( "uploadbtn" ) . "\" />
+ </form>
+</fieldset>
+" );
+ } else {
+ if( empty( $wgImportSources ) ) {
+ $wgOut->addWikiText( wfMsg( 'importnosources' ) );
+ }
+ }
+
+ if( !empty( $wgImportSources ) ) {
+ $wgOut->addHTML( "
+<fieldset>
+ <legend>" . wfMsgHtml('importinterwiki') . "</legend>
+ <form method='post' action=\"$action\">" .
+ $wgOut->parse( wfMsg( 'import-interwiki-text' ) ) . "
+ <input type='hidden' name='action' value='submit' />
+ <input type='hidden' name='source' value='interwiki' />
+ <table>
+ <tr>
+ <td>
+ <select name='interwiki'>" );
+ foreach( $wgImportSources as $prefix ) {
+ $iw = htmlspecialchars( $prefix );
+ $selected = ($interwiki === $prefix) ? ' selected="selected"' : '';
+ $wgOut->addHTML( "<option value=\"$iw\"$selected>$iw</option>\n" );
+ }
+ $wgOut->addHTML( "
+ </select>
+ </td>
+ <td>" .
+ wfInput( 'frompage', 50, $frompage ) .
+ "</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>" .
+ wfCheckLabel( wfMsg( 'import-interwiki-history' ),
+ 'interwikiHistory', 'interwikiHistory', $history ) .
+ "</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>
+ " . wfMsgHtml( 'import-interwiki-namespace' ) . " " .
+ HTMLnamespaceselector( $namespace, '' ) . "
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>" .
+ wfSubmitButton( wfMsg( 'import-interwiki-submit' ) ) .
+ "</td>
+ </tr>
+ </table>
+ </form>
+</fieldset>
+" );
+ }
+}
+
+/**
+ * Reporting callback
+ */
+class ImportReporter {
+ function __construct( $importer, $upload, $interwiki ) {
+ $importer->setPageOutCallback( array( $this, 'reportPage' ) );
+ $this->mPageCount = 0;
+ $this->mIsUpload = $upload;
+ $this->mInterwiki = $interwiki;
+ }
+
+ function open() {
+ global $wgOut;
+ $wgOut->addHtml( "<ul>\n" );
+ }
+
+ function reportPage( $title, $origTitle, $revisionCount, $successCount ) {
+ global $wgOut, $wgUser, $wgLang, $wgContLang;
+
+ $skin = $wgUser->getSkin();
+
+ $this->mPageCount++;
+
+ $localCount = $wgLang->formatNum( $successCount );
+ $contentCount = $wgContLang->formatNum( $successCount );
+
+ $wgOut->addHtml( "<li>" . $skin->makeKnownLinkObj( $title ) .
+ " " .
+ wfMsgExt( 'import-revision-count', array( 'parsemag', 'escape' ), $localCount ) .
+ "</li>\n" );
+
+ if( $successCount > 0 ) {
+ $log = new LogPage( 'import' );
+ if( $this->mIsUpload ) {
+ $detail = wfMsgForContent( 'import-logentry-upload-detail',
+ $contentCount );
+ $log->addEntry( 'upload', $title, $detail );
+ } else {
+ $interwiki = '[[:' . $this->mInterwiki . ':' .
+ $origTitle->getPrefixedText() . ']]';
+ $detail = wfMsgForContent( 'import-logentry-interwiki-detail',
+ $contentCount, $interwiki );
+ $log->addEntry( 'interwiki', $title, $detail );
+ }
+
+ $comment = $detail; // quick
+ $dbw = wfGetDB( DB_MASTER );
+ $nullRevision = Revision::newNullRevision(
+ $dbw, $title->getArticleId(), $comment, true );
+ $nullRevision->insertOn( $dbw );
+ }
+ }
+
+ function close() {
+ global $wgOut;
+ if( $this->mPageCount == 0 ) {
+ $wgOut->addHtml( "<li>" . wfMsgHtml( 'importnopages' ) . "</li>\n" );
+ }
+ $wgOut->addHtml( "</ul>\n" );
+ }
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class WikiRevision {
+ var $title = null;
+ var $id = 0;
+ var $timestamp = "20010115000000";
+ var $user = 0;
+ var $user_text = "";
+ var $text = "";
+ var $comment = "";
+ var $minor = false;
+
+ function setTitle( $title ) {
+ if( is_object( $title ) ) {
+ $this->title = $title;
+ } elseif( is_null( $title ) ) {
+ throw new MWException( "WikiRevision given a null title in import. You may need to adjust \$wgLegalTitleChars." );
+ } else {
+ throw new MWException( "WikiRevision given non-object title in import." );
+ }
+ }
+
+ function setID( $id ) {
+ $this->id = $id;
+ }
+
+ function setTimestamp( $ts ) {
+ # 2003-08-05T18:30:02Z
+ $this->timestamp = wfTimestamp( TS_MW, $ts );
+ }
+
+ function setUsername( $user ) {
+ $this->user_text = $user;
+ }
+
+ function setUserIP( $ip ) {
+ $this->user_text = $ip;
+ }
+
+ function setText( $text ) {
+ $this->text = $text;
+ }
+
+ function setComment( $text ) {
+ $this->comment = $text;
+ }
+
+ function setMinor( $minor ) {
+ $this->minor = (bool)$minor;
+ }
+
+ function getTitle() {
+ return $this->title;
+ }
+
+ function getID() {
+ return $this->id;
+ }
+
+ function getTimestamp() {
+ return $this->timestamp;
+ }
+
+ function getUser() {
+ return $this->user_text;
+ }
+
+ function getText() {
+ return $this->text;
+ }
+
+ function getComment() {
+ return $this->comment;
+ }
+
+ function getMinor() {
+ return $this->minor;
+ }
+
+ function importOldRevision() {
+ $dbw =& wfGetDB( DB_MASTER );
+
+ # Sneak a single revision into place
+ $user = User::newFromName( $this->getUser() );
+ if( $user ) {
+ $userId = intval( $user->getId() );
+ $userText = $user->getName();
+ } else {
+ $userId = 0;
+ $userText = $this->getUser();
+ }
+
+ // avoid memory leak...?
+ $linkCache =& LinkCache::singleton();
+ $linkCache->clear();
+
+ $article = new Article( $this->title );
+ $pageId = $article->getId();
+ if( $pageId == 0 ) {
+ # must create the page...
+ $pageId = $article->insertOn( $dbw );
+ $created = true;
+ } else {
+ $created = false;
+
+ $prior = Revision::loadFromTimestamp( $dbw, $this->title, $this->timestamp );
+ if( !is_null( $prior ) ) {
+ // FIXME: this could fail slightly for multiple matches :P
+ wfDebug( __METHOD__ . ": skipping existing revision for [[" .
+ $this->title->getPrefixedText() . "]], timestamp " .
+ $this->timestamp . "\n" );
+ return false;
+ }
+ }
+
+ # FIXME: Use original rev_id optionally
+ # FIXME: blah blah blah
+
+ #if( $numrows > 0 ) {
+ # return wfMsg( "importhistoryconflict" );
+ #}
+
+ # Insert the row
+ $revision = new Revision( array(
+ 'page' => $pageId,
+ 'text' => $this->getText(),
+ 'comment' => $this->getComment(),
+ 'user' => $userId,
+ 'user_text' => $userText,
+ 'timestamp' => $this->timestamp,
+ 'minor_edit' => $this->minor,
+ ) );
+ $revId = $revision->insertOn( $dbw );
+ $changed = $article->updateIfNewerOn( $dbw, $revision );
+
+ if( $created ) {
+ wfDebug( __METHOD__ . ": running onArticleCreate\n" );
+ Article::onArticleCreate( $this->title );
+
+ wfDebug( __METHOD__ . ": running create updates\n" );
+ $article->createUpdates( $revision );
+
+ } elseif( $changed ) {
+ wfDebug( __METHOD__ . ": running onArticleEdit\n" );
+ Article::onArticleEdit( $this->title );
+
+ wfDebug( __METHOD__ . ": running edit updates\n" );
+ $article->editUpdates(
+ $this->getText(),
+ $this->getComment(),
+ $this->minor,
+ $this->timestamp,
+ $revId );
+ }
+
+ return true;
+ }
+
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class WikiImporter {
+ var $mSource = null;
+ var $mPageCallback = null;
+ var $mPageOutCallback = null;
+ var $mRevisionCallback = null;
+ var $mTargetNamespace = null;
+ var $lastfield;
+
+ function WikiImporter( $source ) {
+ $this->setRevisionCallback( array( &$this, "importRevision" ) );
+ $this->mSource = $source;
+ }
+
+ function throwXmlError( $err ) {
+ $this->debug( "FAILURE: $err" );
+ wfDebug( "WikiImporter XML error: $err\n" );
+ }
+
+ # --------------
+
+ function doImport() {
+ if( empty( $this->mSource ) ) {
+ return new WikiErrorMsg( "importnotext" );
+ }
+
+ $parser = xml_parser_create( "UTF-8" );
+
+ # case folding violates XML standard, turn it off
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
+
+ xml_set_object( $parser, $this );
+ xml_set_element_handler( $parser, "in_start", "" );
+
+ $offset = 0; // for context extraction on error reporting
+ do {
+ $chunk = $this->mSource->readChunk();
+ if( !xml_parse( $parser, $chunk, $this->mSource->atEnd() ) ) {
+ wfDebug( "WikiImporter::doImport encountered XML parsing error\n" );
+ return new WikiXmlError( $parser, 'XML import parse failure', $chunk, $offset );
+ }
+ $offset += strlen( $chunk );
+ } while( $chunk !== false && !$this->mSource->atEnd() );
+ xml_parser_free( $parser );
+
+ return true;
+ }
+
+ function debug( $data ) {
+ #wfDebug( "IMPORT: $data\n" );
+ }
+
+ function notice( $data ) {
+ global $wgCommandLineMode;
+ if( $wgCommandLineMode ) {
+ print "$data\n";
+ } else {
+ global $wgOut;
+ $wgOut->addHTML( "<li>$data</li>\n" );
+ }
+ }
+
+ /**
+ * Sets the action to perform as each new page in the stream is reached.
+ * @param callable $callback
+ * @return callable
+ */
+ function setPageCallback( $callback ) {
+ $previous = $this->mPageCallback;
+ $this->mPageCallback = $callback;
+ return $previous;
+ }
+
+ /**
+ * Sets the action to perform as each page in the stream is completed.
+ * Callback accepts the page title (as a Title object), a second object
+ * with the original title form (in case it's been overridden into a
+ * local namespace), and a count of revisions.
+ *
+ * @param callable $callback
+ * @return callable
+ */
+ function setPageOutCallback( $callback ) {
+ $previous = $this->mPageOutCallback;
+ $this->mPageOutCallback = $callback;
+ return $previous;
+ }
+
+ /**
+ * Sets the action to perform as each page revision is reached.
+ * @param callable $callback
+ * @return callable
+ */
+ function setRevisionCallback( $callback ) {
+ $previous = $this->mRevisionCallback;
+ $this->mRevisionCallback = $callback;
+ return $previous;
+ }
+
+ /**
+ * Set a target namespace to override the defaults
+ */
+ function setTargetNamespace( $namespace ) {
+ if( is_null( $namespace ) ) {
+ // Don't override namespaces
+ $this->mTargetNamespace = null;
+ } elseif( $namespace >= 0 ) {
+ // FIXME: Check for validity
+ $this->mTargetNamespace = intval( $namespace );
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Default per-revision callback, performs the import.
+ * @param WikiRevision $revision
+ * @private
+ */
+ function importRevision( &$revision ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ return $dbw->deadlockLoop( array( &$revision, 'importOldRevision' ) );
+ }
+
+ /**
+ * Alternate per-revision callback, for debugging.
+ * @param WikiRevision $revision
+ * @private
+ */
+ function debugRevisionHandler( &$revision ) {
+ $this->debug( "Got revision:" );
+ if( is_object( $revision->title ) ) {
+ $this->debug( "-- Title: " . $revision->title->getPrefixedText() );
+ } else {
+ $this->debug( "-- Title: <invalid>" );
+ }
+ $this->debug( "-- User: " . $revision->user_text );
+ $this->debug( "-- Timestamp: " . $revision->timestamp );
+ $this->debug( "-- Comment: " . $revision->comment );
+ $this->debug( "-- Text: " . $revision->text );
+ }
+
+ /**
+ * Notify the callback function when a new <page> is reached.
+ * @param Title $title
+ * @private
+ */
+ function pageCallback( $title ) {
+ if( is_callable( $this->mPageCallback ) ) {
+ call_user_func( $this->mPageCallback, $title );
+ }
+ }
+
+ /**
+ * Notify the callback function when a </page> is closed.
+ * @param Title $title
+ * @param Title $origTitle
+ * @param int $revisionCount
+ * @param int $successCount number of revisions for which callback returned true
+ * @private
+ */
+ function pageOutCallback( $title, $origTitle, $revisionCount, $successCount ) {
+ if( is_callable( $this->mPageOutCallback ) ) {
+ call_user_func( $this->mPageOutCallback, $title, $origTitle,
+ $revisionCount, $successCount );
+ }
+ }
+
+
+ # XML parser callbacks from here out -- beware!
+ function donothing( $parser, $x, $y="" ) {
+ #$this->debug( "donothing" );
+ }
+
+ function in_start( $parser, $name, $attribs ) {
+ $this->debug( "in_start $name" );
+ if( $name != "mediawiki" ) {
+ return $this->throwXMLerror( "Expected <mediawiki>, got <$name>" );
+ }
+ xml_set_element_handler( $parser, "in_mediawiki", "out_mediawiki" );
+ }
+
+ function in_mediawiki( $parser, $name, $attribs ) {
+ $this->debug( "in_mediawiki $name" );
+ if( $name == 'siteinfo' ) {
+ xml_set_element_handler( $parser, "in_siteinfo", "out_siteinfo" );
+ } elseif( $name == 'page' ) {
+ $this->workRevisionCount = 0;
+ $this->workSuccessCount = 0;
+ xml_set_element_handler( $parser, "in_page", "out_page" );
+ } else {
+ return $this->throwXMLerror( "Expected <page>, got <$name>" );
+ }
+ }
+ function out_mediawiki( $parser, $name ) {
+ $this->debug( "out_mediawiki $name" );
+ if( $name != "mediawiki" ) {
+ return $this->throwXMLerror( "Expected </mediawiki>, got </$name>" );
+ }
+ xml_set_element_handler( $parser, "donothing", "donothing" );
+ }
+
+
+ function in_siteinfo( $parser, $name, $attribs ) {
+ // no-ops for now
+ $this->debug( "in_siteinfo $name" );
+ switch( $name ) {
+ case "sitename":
+ case "base":
+ case "generator":
+ case "case":
+ case "namespaces":
+ case "namespace":
+ break;
+ default:
+ return $this->throwXMLerror( "Element <$name> not allowed in <siteinfo>." );
+ }
+ }
+
+ function out_siteinfo( $parser, $name ) {
+ if( $name == "siteinfo" ) {
+ xml_set_element_handler( $parser, "in_mediawiki", "out_mediawiki" );
+ }
+ }
+
+
+ function in_page( $parser, $name, $attribs ) {
+ $this->debug( "in_page $name" );
+ switch( $name ) {
+ case "id":
+ case "title":
+ case "restrictions":
+ $this->appendfield = $name;
+ $this->appenddata = "";
+ $this->parenttag = "page";
+ xml_set_element_handler( $parser, "in_nothing", "out_append" );
+ xml_set_character_data_handler( $parser, "char_append" );
+ break;
+ case "revision":
+ $this->workRevision = new WikiRevision;
+ $this->workRevision->setTitle( $this->pageTitle );
+ $this->workRevisionCount++;
+ xml_set_element_handler( $parser, "in_revision", "out_revision" );
+ break;
+ default:
+ return $this->throwXMLerror( "Element <$name> not allowed in a <page>." );
+ }
+ }
+
+ function out_page( $parser, $name ) {
+ $this->debug( "out_page $name" );
+ if( $name != "page" ) {
+ return $this->throwXMLerror( "Expected </page>, got </$name>" );
+ }
+ xml_set_element_handler( $parser, "in_mediawiki", "out_mediawiki" );
+
+ $this->pageOutCallback( $this->pageTitle, $this->origTitle,
+ $this->workRevisionCount, $this->workSuccessCount );
+
+ $this->workTitle = null;
+ $this->workRevision = null;
+ $this->workRevisionCount = 0;
+ $this->workSuccessCount = 0;
+ $this->pageTitle = null;
+ $this->origTitle = null;
+ }
+
+ function in_nothing( $parser, $name, $attribs ) {
+ $this->debug( "in_nothing $name" );
+ return $this->throwXMLerror( "No child elements allowed here; got <$name>" );
+ }
+ function char_append( $parser, $data ) {
+ $this->debug( "char_append '$data'" );
+ $this->appenddata .= $data;
+ }
+ function out_append( $parser, $name ) {
+ $this->debug( "out_append $name" );
+ if( $name != $this->appendfield ) {
+ return $this->throwXMLerror( "Expected </{$this->appendfield}>, got </$name>" );
+ }
+ xml_set_element_handler( $parser, "in_$this->parenttag", "out_$this->parenttag" );
+ xml_set_character_data_handler( $parser, "donothing" );
+
+ switch( $this->appendfield ) {
+ case "title":
+ $this->workTitle = $this->appenddata;
+ $this->origTitle = Title::newFromText( $this->workTitle );
+ if( !is_null( $this->mTargetNamespace ) && !is_null( $this->origTitle ) ) {
+ $this->pageTitle = Title::makeTitle( $this->mTargetNamespace,
+ $this->origTitle->getDbKey() );
+ } else {
+ $this->pageTitle = Title::newFromText( $this->workTitle );
+ }
+ $this->pageCallback( $this->workTitle );
+ break;
+ case "id":
+ if ( $this->parenttag == 'revision' ) {
+ $this->workRevision->setID( $this->appenddata );
+ }
+ break;
+ case "text":
+ $this->workRevision->setText( $this->appenddata );
+ break;
+ case "username":
+ $this->workRevision->setUsername( $this->appenddata );
+ break;
+ case "ip":
+ $this->workRevision->setUserIP( $this->appenddata );
+ break;
+ case "timestamp":
+ $this->workRevision->setTimestamp( $this->appenddata );
+ break;
+ case "comment":
+ $this->workRevision->setComment( $this->appenddata );
+ break;
+ case "minor":
+ $this->workRevision->setMinor( true );
+ break;
+ default:
+ $this->debug( "Bad append: {$this->appendfield}" );
+ }
+ $this->appendfield = "";
+ $this->appenddata = "";
+ }
+
+ function in_revision( $parser, $name, $attribs ) {
+ $this->debug( "in_revision $name" );
+ switch( $name ) {
+ case "id":
+ case "timestamp":
+ case "comment":
+ case "minor":
+ case "text":
+ $this->parenttag = "revision";
+ $this->appendfield = $name;
+ xml_set_element_handler( $parser, "in_nothing", "out_append" );
+ xml_set_character_data_handler( $parser, "char_append" );
+ break;
+ case "contributor":
+ xml_set_element_handler( $parser, "in_contributor", "out_contributor" );
+ break;
+ default:
+ return $this->throwXMLerror( "Element <$name> not allowed in a <revision>." );
+ }
+ }
+
+ function out_revision( $parser, $name ) {
+ $this->debug( "out_revision $name" );
+ if( $name != "revision" ) {
+ return $this->throwXMLerror( "Expected </revision>, got </$name>" );
+ }
+ xml_set_element_handler( $parser, "in_page", "out_page" );
+
+ $ok = call_user_func_array( $this->mRevisionCallback,
+ array( &$this->workRevision, &$this ) );
+ if( $ok ) {
+ $this->workSuccessCount++;
+ }
+ }
+
+ function in_contributor( $parser, $name, $attribs ) {
+ $this->debug( "in_contributor $name" );
+ switch( $name ) {
+ case "username":
+ case "ip":
+ case "id":
+ $this->parenttag = "contributor";
+ $this->appendfield = $name;
+ xml_set_element_handler( $parser, "in_nothing", "out_append" );
+ xml_set_character_data_handler( $parser, "char_append" );
+ break;
+ default:
+ $this->throwXMLerror( "Invalid tag <$name> in <contributor>" );
+ }
+ }
+
+ function out_contributor( $parser, $name ) {
+ $this->debug( "out_contributor $name" );
+ if( $name != "contributor" ) {
+ return $this->throwXMLerror( "Expected </contributor>, got </$name>" );
+ }
+ xml_set_element_handler( $parser, "in_revision", "out_revision" );
+ }
+
+}
+
+/** @package MediaWiki */
+class ImportStringSource {
+ function ImportStringSource( $string ) {
+ $this->mString = $string;
+ $this->mRead = false;
+ }
+
+ function atEnd() {
+ return $this->mRead;
+ }
+
+ function readChunk() {
+ if( $this->atEnd() ) {
+ return false;
+ } else {
+ $this->mRead = true;
+ return $this->mString;
+ }
+ }
+}
+
+/** @package MediaWiki */
+class ImportStreamSource {
+ function ImportStreamSource( $handle ) {
+ $this->mHandle = $handle;
+ }
+
+ function atEnd() {
+ return feof( $this->mHandle );
+ }
+
+ function readChunk() {
+ return fread( $this->mHandle, 32768 );
+ }
+
+ function newFromFile( $filename ) {
+ $file = @fopen( $filename, 'rt' );
+ if( !$file ) {
+ return new WikiErrorMsg( "importcantopen" );
+ }
+ return new ImportStreamSource( $file );
+ }
+
+ static function newFromUpload( $fieldname = "xmlimport" ) {
+ $upload =& $_FILES[$fieldname];
+
+ if( !isset( $upload ) || !$upload['name'] ) {
+ return new WikiErrorMsg( 'importnofile' );
+ }
+ if( !empty( $upload['error'] ) ) {
+ return new WikiErrorMsg( 'importuploaderror', $upload['error'] );
+ }
+ $fname = $upload['tmp_name'];
+ if( is_uploaded_file( $fname ) ) {
+ return ImportStreamSource::newFromFile( $fname );
+ } else {
+ return new WikiErrorMsg( 'importnofile' );
+ }
+ }
+
+ function newFromURL( $url ) {
+ wfDebug( __METHOD__ . ": opening $url\n" );
+ # fopen-wrappers are normally turned off for security.
+ ini_set( "allow_url_fopen", true );
+ $ret = ImportStreamSource::newFromFile( $url );
+ ini_set( "allow_url_fopen", false );
+ return $ret;
+ }
+
+ public static function newFromInterwiki( $interwiki, $page, $history=false ) {
+ $link = Title::newFromText( "$interwiki:Special:Export/$page" );
+ if( is_null( $link ) || $link->getInterwiki() == '' ) {
+ return new WikiErrorMsg( 'importbadinterwiki' );
+ } else {
+ $params = $history ? 'history=1' : '';
+ $url = $link->getFullUrl( $params );
+ return ImportStreamSource::newFromURL( $url );
+ }
+ }
+}
+
+
+?>
diff --git a/includes/SpecialIpblocklist.php b/includes/SpecialIpblocklist.php
new file mode 100644
index 000000000000..293059f290e0
--- /dev/null
+++ b/includes/SpecialIpblocklist.php
@@ -0,0 +1,363 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * @todo document
+ */
+function wfSpecialIpblocklist() {
+ global $wgUser, $wgOut, $wgRequest;
+
+ $ip = $wgRequest->getVal( 'wpUnblockAddress', $wgRequest->getVal( 'ip' ) );
+ $id = $wgRequest->getVal( 'id' );
+ $reason = $wgRequest->getText( 'wpUnblockReason' );
+ $action = $wgRequest->getText( 'action' );
+ $successip = $wgRequest->getVal( 'successip' );
+
+ $ipu = new IPUnblockForm( $ip, $id, $reason );
+
+ if ( "success" == $action ) {
+ $ipu->showList( $wgOut->parse( wfMsg( 'unblocked', $successip ) ) );
+ } else if ( "submit" == $action && $wgRequest->wasPosted() &&
+ $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
+ if ( ! $wgUser->isAllowed('block') ) {
+ $wgOut->permissionRequired( 'block' );
+ return;
+ }
+ $ipu->doSubmit();
+ } else if ( "unblock" == $action ) {
+ $ipu->showForm( "" );
+ } else {
+ $ipu->showList( "" );
+ }
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class IPUnblockForm {
+ var $ip, $reason, $id;
+
+ function IPUnblockForm( $ip, $id, $reason ) {
+ $this->ip = $ip;
+ $this->id = $id;
+ $this->reason = $reason;
+ }
+
+ function showForm( $err ) {
+ global $wgOut, $wgUser, $wgSysopUserBans;
+
+ $wgOut->setPagetitle( wfMsg( 'unblockip' ) );
+ $wgOut->addWikiText( wfMsg( 'unblockiptext' ) );
+
+ $ipa = wfMsgHtml( $wgSysopUserBans ? 'ipadressorusername' : 'ipaddress' );
+ $ipr = wfMsgHtml( 'ipbreason' );
+ $ipus = wfMsgHtml( 'ipusubmit' );
+ $titleObj = SpecialPage::getTitleFor( "Ipblocklist" );
+ $action = $titleObj->escapeLocalURL( "action=submit" );
+
+ if ( "" != $err ) {
+ $wgOut->setSubtitle( wfMsg( "formerror" ) );
+ $wgOut->addWikitext( "<span class='error'>{$err}</span>\n" );
+ }
+ $token = htmlspecialchars( $wgUser->editToken() );
+
+ $addressPart = false;
+ if ( $this->id ) {
+ $block = Block::newFromID( $this->id );
+ if ( $block ) {
+ $encName = htmlspecialchars( $block->getRedactedName() );
+ $encId = htmlspecialchars( $this->id );
+ $addressPart = $encName . "<input type='hidden' name=\"id\" value=\"$encId\" />";
+ }
+ }
+ if ( !$addressPart ) {
+ $addressPart = "<input tabindex='1' type='text' size='20' " .
+ "name=\"wpUnblockAddress\" value=\"" . htmlspecialchars( $this->ip ) . "\" />";
+ }
+
+ $wgOut->addHTML( "
+<form id=\"unblockip\" method=\"post\" action=\"{$action}\">
+ <table border='0'>
+ <tr>
+ <td align='right'>{$ipa}:</td>
+ <td align='left'>
+ {$addressPart}
+ </td>
+ </tr>
+ <tr>
+ <td align='right'>{$ipr}:</td>
+ <td align='left'>
+ <input tabindex='1' type='text' size='40' name=\"wpUnblockReason\" value=\"" . htmlspecialchars( $this->reason ) . "\" />
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td align='left'>
+ <input tabindex='2' type='submit' name=\"wpBlock\" value=\"{$ipus}\" />
+ </td>
+ </tr>
+ </table>
+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
+</form>\n" );
+
+ }
+
+ function doSubmit() {
+ global $wgOut;
+
+ if ( $this->id ) {
+ $block = Block::newFromID( $this->id );
+ if ( $block ) {
+ $this->ip = $block->getRedactedName();
+ }
+ } else {
+ $block = new Block();
+ $this->ip = trim( $this->ip );
+ if ( substr( $this->ip, 0, 1 ) == "#" ) {
+ $id = substr( $this->ip, 1 );
+ $block = Block::newFromID( $id );
+ } else {
+ $block = Block::newFromDB( $this->ip );
+ if ( !$block ) {
+ $block = null;
+ }
+ }
+ }
+ $success = false;
+ if ( $block ) {
+ # Delete block
+ if ( $block->delete() ) {
+ # Make log entry
+ $log = new LogPage( 'block' );
+ $log->addEntry( 'unblock', Title::makeTitle( NS_USER, $this->ip ), $this->reason );
+ $success = true;
+ }
+ }
+
+ if ( $success ) {
+ # Report to the user
+ $titleObj = SpecialPage::getTitleFor( "Ipblocklist" );
+ $success = $titleObj->getFullURL( "action=success&successip=" . urlencode( $this->ip ) );
+ $wgOut->redirect( $success );
+ } else {
+ if ( !$this->ip && $this->id ) {
+ $this->ip = '#' . $this->id;
+ }
+ $this->showForm( wfMsg( 'ipb_cant_unblock', htmlspecialchars( $this->id ) ) );
+ }
+ }
+
+ function showList( $msg ) {
+ global $wgOut;
+
+ $wgOut->setPagetitle( wfMsg( "ipblocklist" ) );
+ if ( "" != $msg ) {
+ $wgOut->setSubtitle( $msg );
+ }
+
+ // Purge expired entries on one in every 10 queries
+ if ( !mt_rand( 0, 10 ) ) {
+ Block::purgeExpired();
+ }
+
+ $conds = array();
+ $matches = array();
+ if ( $this->ip == '' ) {
+ // No extra conditions
+ } elseif ( substr( $this->ip, 0, 1 ) == '#' ) {
+ $conds['ipb_id'] = substr( $this->ip, 1 );
+ } elseif ( IP::toUnsigned( $this->ip ) !== false ) {
+ $conds['ipb_address'] = $this->ip;
+ $conds['ipb_auto'] = 0;
+ } elseif( preg_match( '/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\\/(\\d{1,2})$/', $this->ip, $matches ) ) {
+ $conds['ipb_address'] = Block::normaliseRange( $this->ip );
+ $conds['ipb_auto'] = 0;
+ } else {
+ $user = User::newFromName( $this->ip );
+ if ( $user && ( $id = $user->getID() ) != 0 ) {
+ $conds['ipb_user'] = $id;
+ } else {
+ // Uh...?
+ $conds['ipb_address'] = $this->ip;
+ $conds['ipb_auto'] = 0;
+ }
+ }
+
+ $pager = new IPBlocklistPager( $this, $conds );
+ $s = $pager->getNavigationBar() .
+ $this->searchForm();
+ if ( $pager->getNumRows() ) {
+ $s .= "<ul>" .
+ $pager->getBody() .
+ "</ul>";
+ } else {
+ $s .= '<p>' . wfMsgHTML( 'ipblocklistempty' ) . '</p>';
+ }
+ $s .= $pager->getNavigationBar();
+ $wgOut->addHTML( $s );
+ }
+
+ function searchForm() {
+ global $wgTitle, $wgScript, $wgRequest;
+ return
+ wfElement( 'form', array(
+ 'action' => $wgScript ),
+ null ) .
+ wfHidden( 'title', $wgTitle->getPrefixedDbKey() ) .
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'action',
+ 'value' => 'search' ) ).
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'limit',
+ 'value' => $wgRequest->getText( 'limit' ) ) ) .
+ wfElement( 'input', array(
+ 'name' => 'ip',
+ 'value' => $this->ip ) ) .
+ wfElement( 'input', array(
+ 'type' => 'submit',
+ 'value' => wfMsg( 'searchbutton' ) ) ) .
+ '</form>';
+ }
+
+ /**
+ * Callback function to output a block
+ */
+ function formatRow( $block ) {
+ global $wgUser, $wgLang;
+
+ wfProfileIn( __METHOD__ );
+
+ static $sk=null, $msg=null;
+
+ if( is_null( $sk ) )
+ $sk = $wgUser->getSkin();
+ if( is_null( $msg ) ) {
+ $msg = array();
+ $keys = array( 'infiniteblock', 'expiringblock', 'contribslink', 'unblocklink',
+ 'anononlyblock', 'createaccountblock', 'noautoblockblock' );
+ foreach( $keys as $key ) {
+ $msg[$key] = wfMsgHtml( $key );
+ }
+ $msg['blocklistline'] = wfMsg( 'blocklistline' );
+ $msg['contribslink'] = wfMsg( 'contribslink' );
+ }
+
+ # Prepare links to the blocker's user and talk pages
+ $blocker_id = $block->getBy();
+ $blocker_name = $block->getByName();
+ $blocker = $sk->userLink( $blocker_id, $blocker_name );
+ $blocker .= $sk->userToolLinks( $blocker_id, $blocker_name );
+
+ # Prepare links to the block target's user and contribs. pages (as applicable, don't do it for autoblocks)
+ if( $block->mAuto ) {
+ $target = $block->getRedactedName(); # Hide the IP addresses of auto-blocks; privacy
+ } else {
+ $target = $sk->makeLinkObj( Title::makeTitle( NS_USER, $block->mAddress ), $block->mAddress );
+ $target .= ' (' . $sk->makeKnownLinkObj( SpecialPage::getSafeTitleFor( 'Contributions', $block->mAddress ), $msg['contribslink'] ) . ')';
+ }
+
+ $formattedTime = $wgLang->timeanddate( $block->mTimestamp, true );
+
+ $properties = array();
+ if ( $block->mExpiry === "" || $block->mExpiry === Block::infinity() ) {
+ $properties[] = $msg['infiniteblock'];
+ } else {
+ $properties[] = wfMsgReplaceArgs( $msg['expiringblock'],
+ array( $wgLang->timeanddate( $block->mExpiry, true ) ) );
+ }
+ if ( $block->mAnonOnly ) {
+ $properties[] = $msg['anononlyblock'];
+ }
+ if ( $block->mCreateAccount ) {
+ $properties[] = $msg['createaccountblock'];
+ }
+ if (!$block->mEnableAutoblock && $block->mUser ) {
+ $properties[] = $msg['noautoblockblock'];
+ }
+
+ $properties = implode( ', ', $properties );
+
+ $line = wfMsgReplaceArgs( $msg['blocklistline'], array( $formattedTime, $blocker, $target, $properties ) );
+
+ $s = "<li>{$line}";
+
+ if ( $wgUser->isAllowed('block') ) {
+ $titleObj = SpecialPage::getTitleFor( "Ipblocklist" );
+ $s .= ' (' . $sk->makeKnownLinkObj($titleObj, $msg['unblocklink'], 'action=unblock&id=' . urlencode( $block->mId ) ) . ')';
+ }
+ $s .= $sk->commentBlock( $block->mReason );
+ $s .= "</li>\n";
+ wfProfileOut( __METHOD__ );
+ return $s;
+ }
+}
+
+class IPBlocklistPager extends ReverseChronologicalPager {
+ public $mForm, $mConds;
+
+ function __construct( $form, $conds = array() ) {
+ $this->mForm = $form;
+ $this->mConds = $conds;
+ parent::__construct();
+ }
+
+ function getStartBody() {
+ wfProfileIn( __METHOD__ );
+ # Do a link batch query
+ $this->mResult->seek( 0 );
+ $lb = new LinkBatch;
+
+ /*
+ while ( $row = $this->mResult->fetchObject() ) {
+ $lb->addObj( Title::makeTitleSafe( NS_USER, $row->user_name ) );
+ $lb->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->user_name ) );
+ $lb->addObj( Title::makeTitleSafe( NS_USER, $row->ipb_address ) );
+ $lb->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ipb_address ) );
+ }*/
+ # Faster way
+ # Usernames and titles are in fact related by a simple substitution of space -> underscore
+ # The last few lines of Title::secureAndSplit() tell the story.
+ while ( $row = $this->mResult->fetchObject() ) {
+ $name = str_replace( ' ', '_', $row->user_name );
+ $lb->add( NS_USER, $name );
+ $lb->add( NS_USER_TALK, $name );
+ $name = str_replace( ' ', '_', $row->ipb_address );
+ $lb->add( NS_USER, $name );
+ $lb->add( NS_USER_TALK, $name );
+ }
+ $lb->execute();
+ wfProfileOut( __METHOD__ );
+ return '';
+ }
+
+ function formatRow( $row ) {
+ $block = new Block;
+ $block->initFromRow( $row );
+ return $this->mForm->formatRow( $block );
+ }
+
+ function getQueryInfo() {
+ $conds = $this->mConds;
+ $conds[] = 'ipb_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() );
+ $conds[] = 'ipb_by=user_id';
+ return array(
+ 'tables' => array( 'ipblocks', 'user' ),
+ 'fields' => $this->mDb->tableName( 'ipblocks' ) . '.*,user_name',
+ 'conds' => $conds,
+ );
+ }
+
+ function getIndexField() {
+ return 'ipb_timestamp';
+ }
+}
+
+?>
diff --git a/includes/SpecialListredirects.php b/includes/SpecialListredirects.php
new file mode 100644
index 000000000000..f717ef72c08a
--- /dev/null
+++ b/includes/SpecialListredirects.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Rob Church <robchur@gmail.com>
+ * @copyright © 2006 Rob Church
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+class ListredirectsPage extends QueryPage {
+
+ function getName() { return( 'Listredirects' ); }
+ function isExpensive() { return( true ); }
+ function isSyndicated() { return( false ); }
+ function sortDescending() { return( false ); }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $page = $dbr->tableName( 'page' );
+ $sql = "SELECT 'Listredirects' AS type, page_title AS title, page_namespace AS namespace, 0 AS value FROM $page WHERE page_is_redirect = 1";
+ return( $sql );
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgContLang;
+
+ # Make a link to the redirect itself
+ $rd_title = Title::makeTitle( $result->namespace, $result->title );
+ $arr = $wgContLang->getArrow() . $wgContLang->getDirMark();
+ $rd_link = $skin->makeKnownLinkObj( $rd_title, '', 'redirect=no' );
+
+ # Find out where the redirect leads
+ $revision = Revision::newFromTitle( $rd_title );
+ if( $revision ) {
+ # Make a link to the destination page
+ $target = Title::newFromRedirect( $revision->getText() );
+ if( $target ) {
+ $targetLink = $skin->makeLinkObj( $target );
+ } else {
+ /** @todo Put in some decent error display here */
+ $targetLink = '*';
+ }
+ } else {
+ /** @todo Put in some decent error display here */
+ $targetLink = '*';
+ }
+
+ # Format the whole thing and return it
+ return "$rd_link $arr $targetLink";
+
+ }
+
+}
+
+function wfSpecialListredirects() {
+ list( $limit, $offset ) = wfCheckLimits();
+ $lrp = new ListredirectsPage();
+ $lrp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialListusers.php b/includes/SpecialListusers.php
new file mode 100644
index 000000000000..b0794344426e
--- /dev/null
+++ b/includes/SpecialListusers.php
@@ -0,0 +1,234 @@
+<?php
+
+# Copyright (C) 2004 Brion Vibber, lcrocker, Tim Starling,
+# Domas Mituzas, Ashar Voultoiz, Jens Frank, Zhengzhu.
+#
+# © 2006 Rob Church <robchur@gmail.com>
+#
+# http://www.mediawiki.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
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * This class is used to get a list of user. The ones with specials
+ * rights (sysop, bureaucrat, developer) will have them displayed
+ * next to their names.
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class ListUsersPage extends QueryPage {
+ var $requestedGroup = '';
+ var $requestedUser = '';
+
+ function getName() {
+ return 'Listusers';
+ }
+ function isSyndicated() { return false; }
+
+ /**
+ * Not expensive, this class won't work properly with the caching system anyway
+ */
+ function isExpensive() {
+ return false;
+ }
+
+ /**
+ * Fetch user page links and cache their existence
+ */
+ function preprocessResults( &$db, &$res ) {
+ $batch = new LinkBatch;
+ while ( $row = $db->fetchObject( $res ) ) {
+ $batch->addObj( Title::makeTitleSafe( $row->namespace, $row->title ) );
+ }
+ $batch->execute();
+
+ // Back to start for display
+ if( $db->numRows( $res ) > 0 ) {
+ // If there are no rows we get an error seeking.
+ $db->dataSeek( $res, 0 );
+ }
+ }
+
+ /**
+ * Show a drop down list to select a group as well as a user name
+ * search box.
+ * @todo localize
+ */
+ function getPageHeader( ) {
+ $self = $this->getTitle();
+
+ # Form tag
+ $out = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $self->getLocalUrl() ) );
+
+ # Group drop-down list
+ $out .= wfElement( 'label', array( 'for' => 'group' ), wfMsg( 'group' ) ) . ' ';
+ $out .= wfOpenElement( 'select', array( 'name' => 'group' ) );
+ $out .= wfElement( 'option', array( 'value' => '' ), wfMsg( 'group-all' ) ); # Item for "all groups"
+ $groups = User::getAllGroups();
+ foreach( $groups as $group ) {
+ $attribs = array( 'value' => $group );
+ if( $group == $this->requestedGroup )
+ $attribs['selected'] = 'selected';
+ $out .= wfElement( 'option', $attribs, User::getGroupName( $group ) );
+ }
+ $out .= wfCloseElement( 'select' ) . ' ';;# . wfElement( 'br' );
+
+ # Username field
+ $out .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'listusersfrom' ) ) . ' ';
+ $out .= wfElement( 'input', array( 'type' => 'text', 'id' => 'username', 'name' => 'username',
+ 'value' => $this->requestedUser ) ) . ' ';
+
+ # Preserve offset and limit
+ if( $this->offset )
+ $out .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'offset', 'value' => $this->offset ) );
+ if( $this->limit )
+ $out .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'limit', 'value' => $this->limit ) );
+
+ # Submit button and form bottom
+ $out .= wfElement( 'input', array( 'type' => 'submit', 'value' => wfMsg( 'allpagessubmit' ) ) );
+ $out .= wfCloseElement( 'form' );
+
+ return $out;
+ }
+
+ function getSQL() {
+ global $wgDBtype;
+ $dbr =& wfGetDB( DB_SLAVE );
+ $user = $dbr->tableName( 'user' );
+ $user_groups = $dbr->tableName( 'user_groups' );
+
+ // We need to get an 'atomic' list of users, so that we
+ // don't break the list half-way through a user's group set
+ // and so that lists by group will show all group memberships.
+ //
+ // On MySQL 4.1 we could use GROUP_CONCAT to grab group
+ // assignments together with users pretty easily. On other
+ // versions, it's not so easy to do it consistently.
+ // For now we'll just grab the number of memberships, so
+ // we can then do targetted checks on those who are in
+ // non-default groups as we go down the list.
+
+ $userspace = NS_USER;
+ $sql = "SELECT 'Listusers' as type, $userspace AS namespace, user_name AS title, " .
+ "user_name as value, user_id, COUNT(ug_group) as numgroups " .
+ "FROM $user ".
+ "LEFT JOIN $user_groups ON user_id=ug_user " .
+ $this->userQueryWhere( $dbr ) .
+ " GROUP BY user_name";
+ if ( $wgDBtype != 'mysql' ) {
+ $sql .= ",user_id";
+ }
+ return $sql;
+ }
+
+ function userQueryWhere( &$dbr ) {
+ $conds = $this->userQueryConditions( $dbr );
+ return empty( $conds )
+ ? ""
+ : "WHERE " . $dbr->makeList( $conds, LIST_AND );
+ }
+
+ function userQueryConditions( $dbr ) {
+ $conds = array();
+ if( $this->requestedGroup != '' ) {
+ $conds['ug_group'] = $this->requestedGroup;
+ }
+ if( $this->requestedUser != '' ) {
+ $conds[] = 'user_name >= ' . $dbr->addQuotes( $this->requestedUser );
+ }
+ return $conds;
+ }
+
+ function linkParameters() {
+ $conds = array();
+ if( $this->requestedGroup != '' ) {
+ $conds['group'] = $this->requestedGroup;
+ }
+ if( $this->requestedUser != '' ) {
+ $conds['username'] = $this->requestedUser;
+ }
+ return $conds;
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function formatResult( $skin, $result ) {
+ $userPage = Title::makeTitle( $result->namespace, $result->title );
+ $name = $skin->makeLinkObj( $userPage, htmlspecialchars( $userPage->getText() ) );
+ $groups = null;
+
+ if( !isset( $result->numgroups ) || $result->numgroups > 0 ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $result = $dbr->select( 'user_groups',
+ array( 'ug_group' ),
+ array( 'ug_user' => $result->user_id ),
+ 'ListUsersPage::formatResult' );
+ $groups = array();
+ while( $row = $dbr->fetchObject( $result ) ) {
+ $groups[$row->ug_group] = User::getGroupMember( $row->ug_group );
+ }
+ $dbr->freeResult( $result );
+
+ if( count( $groups ) > 0 ) {
+ foreach( $groups as $group => $desc ) {
+ $list[] = User::makeGroupLinkHTML( $group, $desc );
+ }
+ $groups = implode( ', ', $list );
+ } else {
+ $groups = '';
+ }
+
+ }
+
+ return wfSpecialList( $name, $groups );
+ }
+}
+
+/**
+ * constructor
+ * $par string (optional) A group to list users from
+ */
+function wfSpecialListusers( $par = null ) {
+ global $wgRequest;
+
+ list( $limit, $offset ) = wfCheckLimits();
+
+
+ $slu = new ListUsersPage();
+
+ /**
+ * Get some parameters
+ */
+ $groupTarget = isset($par) ? $par : $wgRequest->getVal( 'group' );
+ $slu->requestedGroup = $groupTarget;
+
+ # 'Validate' the username first
+ $username = $wgRequest->getText( 'username', '' );
+ $user = User::newFromName( $username );
+ $slu->requestedUser = is_object( $user ) ? $user->getName() : '';
+
+ return $slu->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialLockdb.php b/includes/SpecialLockdb.php
new file mode 100644
index 000000000000..f0142e5ca512
--- /dev/null
+++ b/includes/SpecialLockdb.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Constructor
+ */
+function wfSpecialLockdb() {
+ global $wgUser, $wgOut, $wgRequest;
+
+ if( !$wgUser->isAllowed( 'siteadmin' ) ) {
+ $wgOut->permissionRequired( 'siteadmin' );
+ return;
+ }
+
+ # If the lock file isn't writable, we can do sweet bugger all
+ global $wgReadOnlyFile;
+ if( !is_writable( dirname( $wgReadOnlyFile ) ) ) {
+ DBLockForm::notWritable();
+ return;
+ }
+
+ $action = $wgRequest->getVal( 'action' );
+ $f = new DBLockForm();
+
+ if ( 'success' == $action ) {
+ $f->showSuccess();
+ } else if ( 'submit' == $action && $wgRequest->wasPosted() &&
+ $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
+ $f->doSubmit();
+ } else {
+ $f->showForm( '' );
+ }
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class DBLockForm {
+ var $reason = '';
+
+ function DBLockForm() {
+ global $wgRequest;
+ $this->reason = $wgRequest->getText( 'wpLockReason' );
+ }
+
+ function showForm( $err ) {
+ global $wgOut, $wgUser;
+
+ $wgOut->setPagetitle( wfMsg( 'lockdb' ) );
+ $wgOut->addWikiText( wfMsg( 'lockdbtext' ) );
+
+ if ( "" != $err ) {
+ $wgOut->setSubtitle( wfMsg( 'formerror' ) );
+ $wgOut->addHTML( '<p class="error">' . htmlspecialchars( $err ) . "</p>\n" );
+ }
+ $lc = htmlspecialchars( wfMsg( 'lockconfirm' ) );
+ $lb = htmlspecialchars( wfMsg( 'lockbtn' ) );
+ $elr = htmlspecialchars( wfMsg( 'enterlockreason' ) );
+ $titleObj = SpecialPage::getTitleFor( 'Lockdb' );
+ $action = $titleObj->escapeLocalURL( 'action=submit' );
+ $reason = htmlspecialchars( $this->reason );
+ $token = htmlspecialchars( $wgUser->editToken() );
+
+ $wgOut->addHTML( <<<END
+<form id="lockdb" method="post" action="{$action}">
+{$elr}:
+<textarea name="wpLockReason" rows="10" cols="60" wrap="virtual">{$reason}</textarea>
+<table border="0">
+ <tr>
+ <td align="right">
+ <input type="checkbox" name="wpLockConfirm" />
+ </td>
+ <td align="left">{$lc}</td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td align="left">
+ <input type="submit" name="wpLock" value="{$lb}" />
+ </td>
+ </tr>
+</table>
+<input type="hidden" name="wpEditToken" value="{$token}" />
+</form>
+END
+);
+
+ }
+
+ function doSubmit() {
+ global $wgOut, $wgUser, $wgLang, $wgRequest;
+ global $wgReadOnlyFile;
+
+ if ( ! $wgRequest->getCheck( 'wpLockConfirm' ) ) {
+ $this->showForm( wfMsg( 'locknoconfirm' ) );
+ return;
+ }
+ $fp = @fopen( $wgReadOnlyFile, 'w' );
+
+ if ( false === $fp ) {
+ # This used to show a file not found error, but the likeliest reason for fopen()
+ # to fail at this point is insufficient permission to write to the file...good old
+ # is_writable() is plain wrong in some cases, it seems...
+ $this->notWritable();
+ return;
+ }
+ fwrite( $fp, $this->reason );
+ fwrite( $fp, "\n<p>(by " . $wgUser->getName() . " at " .
+ $wgLang->timeanddate( wfTimestampNow() ) . ")\n" );
+ fclose( $fp );
+
+ $titleObj = SpecialPage::getTitleFor( 'Lockdb' );
+ $wgOut->redirect( $titleObj->getFullURL( 'action=success' ) );
+ }
+
+ function showSuccess() {
+ global $wgOut;
+
+ $wgOut->setPagetitle( wfMsg( 'lockdb' ) );
+ $wgOut->setSubtitle( wfMsg( 'lockdbsuccesssub' ) );
+ $wgOut->addWikiText( wfMsg( 'lockdbsuccesstext' ) );
+ }
+
+ function notWritable() {
+ global $wgOut;
+ $wgOut->errorPage( 'lockdb', 'lockfilenotwritable' );
+ }
+
+}
+
+?>
diff --git a/includes/SpecialLog.php b/includes/SpecialLog.php
new file mode 100644
index 000000000000..7076d81978ff
--- /dev/null
+++ b/includes/SpecialLog.php
@@ -0,0 +1,425 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * constructor
+ */
+function wfSpecialLog( $par = '' ) {
+ global $wgRequest;
+ $logReader = new LogReader( $wgRequest );
+ if( $wgRequest->getVal( 'type' ) == '' && $par != '' ) {
+ $logReader->limitType( $par );
+ }
+ $logViewer = new LogViewer( $logReader );
+ $logViewer->show();
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class LogReader {
+ var $db, $joinClauses, $whereClauses;
+ var $type = '', $user = '', $title = null;
+
+ /**
+ * @param WebRequest $request For internal use use a FauxRequest object to pass arbitrary parameters.
+ */
+ function LogReader( $request ) {
+ $this->db =& wfGetDB( DB_SLAVE );
+ $this->setupQuery( $request );
+ }
+
+ /**
+ * Basic setup and applies the limiting factors from the WebRequest object.
+ * @param WebRequest $request
+ * @private
+ */
+ function setupQuery( $request ) {
+ $page = $this->db->tableName( 'page' );
+ $user = $this->db->tableName( 'user' );
+ $this->joinClauses = array(
+ "LEFT OUTER JOIN $page ON log_namespace=page_namespace AND log_title=page_title",
+ "INNER JOIN $user ON user_id=log_user" );
+ $this->whereClauses = array();
+
+ $this->limitType( $request->getVal( 'type' ) );
+ $this->limitUser( $request->getText( 'user' ) );
+ $this->limitTitle( $request->getText( 'page' ) );
+ $this->limitTime( $request->getVal( 'from' ), '>=' );
+ $this->limitTime( $request->getVal( 'until' ), '<=' );
+
+ list( $this->limit, $this->offset ) = $request->getLimitOffset();
+ }
+
+ /**
+ * Set the log reader to return only entries of the given type.
+ * @param string $type A log type ('upload', 'delete', etc)
+ * @private
+ */
+ function limitType( $type ) {
+ if( empty( $type ) ) {
+ return false;
+ }
+ $this->type = $type;
+ $safetype = $this->db->strencode( $type );
+ $this->whereClauses[] = "log_type='$safetype'";
+ }
+
+ /**
+ * Set the log reader to return only entries by the given user.
+ * @param string $name (In)valid user name
+ * @private
+ */
+ function limitUser( $name ) {
+ if ( $name == '' )
+ return false;
+ $usertitle = Title::makeTitleSafe( NS_USER, $name );
+ if ( is_null( $usertitle ) )
+ return false;
+ $this->user = $usertitle->getText();
+
+ /* Fetch userid at first, if known, provides awesome query plan afterwards */
+ $userid = $this->db->selectField('user','user_id',array('user_name'=>$this->user));
+ if (!$userid)
+ /* It should be nicer to abort query at all,
+ but for now it won't pass anywhere behind the optimizer */
+ $this->whereClauses[] = "NULL";
+ else
+ $this->whereClauses[] = "log_user=$userid";
+ }
+
+ /**
+ * Set the log reader to return only entries affecting the given page.
+ * (For the block and rights logs, this is a user page.)
+ * @param string $page Title name as text
+ * @private
+ */
+ function limitTitle( $page ) {
+ $title = Title::newFromText( $page );
+ if( empty( $page ) || is_null( $title ) ) {
+ return false;
+ }
+ $this->title =& $title;
+ $safetitle = $this->db->strencode( $title->getDBkey() );
+ $ns = $title->getNamespace();
+ $this->whereClauses[] = "log_namespace=$ns AND log_title='$safetitle'";
+ }
+
+ /**
+ * Set the log reader to return only entries in a given time range.
+ * @param string $time Timestamp of one endpoint
+ * @param string $direction either ">=" or "<=" operators
+ * @private
+ */
+ function limitTime( $time, $direction ) {
+ # Direction should be a comparison operator
+ if( empty( $time ) ) {
+ return false;
+ }
+ $safetime = $this->db->strencode( wfTimestamp( TS_MW, $time ) );
+ $this->whereClauses[] = "log_timestamp $direction '$safetime'";
+ }
+
+ /**
+ * Build an SQL query from all the set parameters.
+ * @return string the SQL query
+ * @private
+ */
+ function getQuery() {
+ $logging = $this->db->tableName( "logging" );
+ $sql = "SELECT /*! STRAIGHT_JOIN */ log_type, log_action, log_timestamp,
+ log_user, user_name,
+ log_namespace, log_title, page_id,
+ log_comment, log_params FROM $logging ";
+ if( !empty( $this->joinClauses ) ) {
+ $sql .= implode( ' ', $this->joinClauses );
+ }
+ if( !empty( $this->whereClauses ) ) {
+ $sql .= " WHERE " . implode( ' AND ', $this->whereClauses );
+ }
+ $sql .= " ORDER BY log_timestamp DESC ";
+ $sql = $this->db->limitResult($sql, $this->limit, $this->offset );
+ return $sql;
+ }
+
+ /**
+ * Execute the query and start returning results.
+ * @return ResultWrapper result object to return the relevant rows
+ */
+ function getRows() {
+ $res = $this->db->query( $this->getQuery(), 'LogReader::getRows' );
+ return $this->db->resultObject( $res );
+ }
+
+ /**
+ * @return string The query type that this LogReader has been limited to.
+ */
+ function queryType() {
+ return $this->type;
+ }
+
+ /**
+ * @return string The username type that this LogReader has been limited to, if any.
+ */
+ function queryUser() {
+ return $this->user;
+ }
+
+ /**
+ * @return string The text of the title that this LogReader has been limited to.
+ */
+ function queryTitle() {
+ if( is_null( $this->title ) ) {
+ return '';
+ } else {
+ return $this->title->getPrefixedText();
+ }
+ }
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class LogViewer {
+ /**
+ * @var LogReader $reader
+ */
+ var $reader;
+ var $numResults = 0;
+
+ /**
+ * @param LogReader &$reader where to get our data from
+ */
+ function LogViewer( &$reader ) {
+ global $wgUser;
+ $this->skin =& $wgUser->getSkin();
+ $this->reader =& $reader;
+ }
+
+ /**
+ * Take over the whole output page in $wgOut with the log display.
+ */
+ function show() {
+ global $wgOut;
+ $this->showHeader( $wgOut );
+ $this->showOptions( $wgOut );
+ $result = $this->getLogRows();
+ $this->showPrevNext( $wgOut );
+ $this->doShowList( $wgOut, $result );
+ $this->showPrevNext( $wgOut );
+ }
+
+ /**
+ * Load the data from the linked LogReader
+ * Preload the link cache
+ * Initialise numResults
+ *
+ * Must be called before calling showPrevNext
+ *
+ * @return object database result set
+ */
+ function getLogRows() {
+ $result = $this->reader->getRows();
+ $this->numResults = 0;
+
+ // Fetch results and form a batch link existence query
+ $batch = new LinkBatch;
+ while ( $s = $result->fetchObject() ) {
+ // User link
+ $title = Title::makeTitleSafe( NS_USER, $s->user_name );
+ $batch->addObj( $title );
+
+ // Move destination link
+ if ( $s->log_type == 'move' ) {
+ $paramArray = LogPage::extractParams( $s->log_params );
+ $title = Title::newFromText( $paramArray[0] );
+ $batch->addObj( $title );
+ }
+ ++$this->numResults;
+ }
+ $batch->execute();
+
+ return $result;
+ }
+
+
+ /**
+ * Output just the list of entries given by the linked LogReader,
+ * with extraneous UI elements. Use for displaying log fragments in
+ * another page (eg at Special:Undelete)
+ * @param OutputPage $out where to send output
+ */
+ function showList( &$out ) {
+ $this->doShowList( $out, $this->getLogRows() );
+ }
+
+ function doShowList( &$out, $result ) {
+ // Rewind result pointer and go through it again, making the HTML
+ if ($this->numResults > 0) {
+ $html = "\n<ul>\n";
+ $result->seek( 0 );
+ while( $s = $result->fetchObject() ) {
+ $html .= $this->logLine( $s );
+ }
+ $html .= "\n</ul>\n";
+ $out->addHTML( $html );
+ } else {
+ $out->addWikiText( wfMsg( 'logempty' ) );
+ }
+ $result->free();
+ }
+
+ /**
+ * @param Object $s a single row from the result set
+ * @return string Formatted HTML list item
+ * @private
+ */
+ function logLine( $s ) {
+ global $wgLang;
+ $title = Title::makeTitle( $s->log_namespace, $s->log_title );
+ $time = $wgLang->timeanddate( wfTimestamp(TS_MW, $s->log_timestamp), true );
+
+ // Enter the existence or non-existence of this page into the link cache,
+ // for faster makeLinkObj() in LogPage::actionText()
+ $linkCache =& LinkCache::singleton();
+ if( $s->page_id ) {
+ $linkCache->addGoodLinkObj( $s->page_id, $title );
+ } else {
+ $linkCache->addBadLinkObj( $title );
+ }
+
+ $userLink = $this->skin->userLink( $s->log_user, $s->user_name ) . $this->skin->userToolLinks( $s->log_user, $s->user_name );
+ $comment = $this->skin->commentBlock( $s->log_comment );
+ $paramArray = LogPage::extractParams( $s->log_params );
+ $revert = '';
+ if ( $s->log_type == 'move' && isset( $paramArray[0] ) ) {
+ $specialTitle = SpecialPage::getTitleFor( 'Movepage' );
+ $destTitle = Title::newFromText( $paramArray[0] );
+ if ( $destTitle ) {
+ $revert = '(' . $this->skin->makeKnownLinkObj( $specialTitle, wfMsg( 'revertmove' ),
+ 'wpOldTitle=' . urlencode( $destTitle->getPrefixedDBkey() ) .
+ '&wpNewTitle=' . urlencode( $title->getPrefixedDBkey() ) .
+ '&wpReason=' . urlencode( wfMsgForContent( 'revertmove' ) ) .
+ '&wpMovetalk=0' ) . ')';
+ }
+ }
+
+ $action = LogPage::actionText( $s->log_type, $s->log_action, $title, $this->skin, $paramArray, true, true );
+ $out = "<li>$time $userLink $action $comment $revert</li>\n";
+ return $out;
+ }
+
+ /**
+ * @param OutputPage &$out where to send output
+ * @private
+ */
+ function showHeader( &$out ) {
+ $type = $this->reader->queryType();
+ if( LogPage::isLogType( $type ) ) {
+ $out->setPageTitle( LogPage::logName( $type ) );
+ $out->addWikiText( LogPage::logHeader( $type ) );
+ }
+ }
+
+ /**
+ * @param OutputPage &$out where to send output
+ * @private
+ */
+ function showOptions( &$out ) {
+ global $wgScript;
+ $action = htmlspecialchars( $wgScript );
+ $title = SpecialPage::getTitleFor( 'Log' );
+ $special = htmlspecialchars( $title->getPrefixedDBkey() );
+ $out->addHTML( "<form action=\"$action\" method=\"get\">\n" .
+ "<input type='hidden' name='title' value=\"$special\" />\n" .
+ $this->getTypeMenu() .
+ $this->getUserInput() .
+ $this->getTitleInput() .
+ "<input type='submit' value=\"" . wfMsg( 'allpagessubmit' ) . "\" />" .
+ "</form>" );
+ }
+
+ /**
+ * @return string Formatted HTML
+ * @private
+ */
+ function getTypeMenu() {
+ $out = "<select name='type'>\n";
+ foreach( LogPage::validTypes() as $type ) {
+ $text = htmlspecialchars( LogPage::logName( $type ) );
+ $selected = ($type == $this->reader->queryType()) ? ' selected="selected"' : '';
+ $out .= "<option value=\"$type\"$selected>$text</option>\n";
+ }
+ $out .= "</select>\n";
+ return $out;
+ }
+
+ /**
+ * @return string Formatted HTML
+ * @private
+ */
+ function getUserInput() {
+ $user = htmlspecialchars( $this->reader->queryUser() );
+ return wfMsg('specialloguserlabel') . "<input type='text' name='user' size='12' value=\"$user\" />\n";
+ }
+
+ /**
+ * @return string Formatted HTML
+ * @private
+ */
+ function getTitleInput() {
+ $title = htmlspecialchars( $this->reader->queryTitle() );
+ return wfMsg('speciallogtitlelabel') . "<input type='text' name='page' size='20' value=\"$title\" />\n";
+ }
+
+ /**
+ * @param OutputPage &$out where to send output
+ * @private
+ */
+ function showPrevNext( &$out ) {
+ global $wgContLang,$wgRequest;
+ $pieces = array();
+ $pieces[] = 'type=' . urlencode( $this->reader->queryType() );
+ $pieces[] = 'user=' . urlencode( $this->reader->queryUser() );
+ $pieces[] = 'page=' . urlencode( $this->reader->queryTitle() );
+ $bits = implode( '&', $pieces );
+ list( $limit, $offset ) = $wgRequest->getLimitOffset();
+
+ # TODO: use timestamps instead of offsets to make it more natural
+ # to go huge distances in time
+ $html = wfViewPrevNext( $offset, $limit,
+ $wgContLang->specialpage( 'Log' ),
+ $bits,
+ $this->numResults < $limit);
+ $out->addHTML( '<p>' . $html . '</p>' );
+ }
+}
+
+
+?>
diff --git a/includes/SpecialLonelypages.php b/includes/SpecialLonelypages.php
new file mode 100644
index 000000000000..8770a9e7a026
--- /dev/null
+++ b/includes/SpecialLonelypages.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class LonelyPagesPage extends PageQueryPage {
+
+ function getName() {
+ return "Lonelypages";
+ }
+ function getPageHeader() {
+ return '<p>' . wfMsg('lonelypagestext') . '</p>';
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function isExpensive() {
+ return true;
+ }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $pagelinks ) = $dbr->tableNamesN( 'page', 'pagelinks' );
+
+ return
+ "SELECT 'Lonelypages' AS type,
+ page_namespace AS namespace,
+ page_title AS title,
+ page_title AS value
+ FROM $page
+ LEFT JOIN $pagelinks
+ ON page_namespace=pl_namespace AND page_title=pl_title
+ WHERE pl_namespace IS NULL
+ AND page_namespace=".NS_MAIN."
+ AND page_is_redirect=0";
+
+ }
+}
+
+/**
+ * Constructor
+ */
+function wfSpecialLonelypages() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $lpp = new LonelyPagesPage();
+
+ return $lpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialLongpages.php b/includes/SpecialLongpages.php
new file mode 100644
index 000000000000..3736d6fc62cb
--- /dev/null
+++ b/includes/SpecialLongpages.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class LongPagesPage extends ShortPagesPage {
+
+ function getName() {
+ return "Longpages";
+ }
+
+ function sortDescending() {
+ return true;
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialLongpages()
+{
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $lpp = new LongPagesPage();
+
+ $lpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialMIMEsearch.php b/includes/SpecialMIMEsearch.php
new file mode 100644
index 000000000000..8678118f2a6e
--- /dev/null
+++ b/includes/SpecialMIMEsearch.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * A special page to search for files by MIME type as defined in the
+ * img_major_mime and img_minor_mime fields in the image table
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class MIMEsearchPage extends QueryPage {
+ var $major, $minor;
+
+ function MIMEsearchPage( $major, $minor ) {
+ $this->major = $major;
+ $this->minor = $minor;
+ }
+
+ function getName() { return 'MIMEsearch'; }
+
+ /**
+ * Due to this page relying upon extra fields being passed in the SELECT it
+ * will fail if it's set as expensive and misermode is on
+ */
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function linkParameters() {
+ $arr = array( $this->major, $this->minor );
+ $mime = implode( '/', $arr );
+ return array( 'mime' => $mime );
+ }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $image = $dbr->tableName( 'image' );
+ $major = $dbr->addQuotes( $this->major );
+ $minor = $dbr->addQuotes( $this->minor );
+
+ return
+ "SELECT 'MIMEsearch' AS type,
+ " . NS_IMAGE . " AS namespace,
+ img_name AS title,
+ img_major_mime AS value,
+
+ img_size,
+ img_width,
+ img_height,
+ img_user_text,
+ img_timestamp
+ FROM $image
+ WHERE img_major_mime = $major AND img_minor_mime = $minor
+ ";
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgContLang, $wgLang;
+
+ $nt = Title::makeTitle( $result->namespace, $result->title );
+ $text = $wgContLang->convert( $nt->getText() );
+ $plink = $skin->makeLink( $nt->getPrefixedText(), $text );
+
+ $download = $skin->makeMediaLink( $nt->getText(), 'fuck me!', wfMsgHtml( 'download' ) );
+ $bytes = wfMsgExt( 'nbytes', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->img_size ) );
+ $dimensions = wfMsg( 'widthheight', $wgLang->formatNum( $result->img_width ),
+ $wgLang->formatNum( $result->img_height ) );
+ $user = $skin->makeLinkObj( Title::makeTitle( NS_USER, $result->img_user_text ), $result->img_user_text );
+ $time = $wgLang->timeanddate( $result->img_timestamp );
+
+ return "($download) $plink . . $dimensions . . $bytes . . $user . . $time";
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialMIMEsearch( $par = null ) {
+ global $wgRequest, $wgTitle, $wgOut;
+
+ $mime = isset( $par ) ? $par : $wgRequest->getText( 'mime' );
+
+ $wgOut->addHTML(
+ wfElement( 'form',
+ array(
+ 'id' => 'specialmimesearch',
+ 'method' => 'get',
+ 'action' => $wgTitle->escapeLocalUrl()
+ ),
+ null
+ ) .
+ wfOpenElement( 'label' ) .
+ wfMsgHtml( 'mimetype' ) .
+ wfElement( 'input', array(
+ 'type' => 'text',
+ 'size' => 20,
+ 'name' => 'mime',
+ 'value' => $mime
+ ),
+ ''
+ ) .
+ ' ' .
+ wfElement( 'input', array(
+ 'type' => 'submit',
+ 'value' => wfMsg( 'ilsubmit' )
+ ),
+ ''
+ ) .
+ wfCloseElement( 'label' ) .
+ wfCloseElement( 'form' )
+ );
+
+ list( $major, $minor ) = wfSpecialMIMEsearchParse( $mime );
+ if ( $major == '' or $minor == '' or !wfSpecialMIMEsearchValidType( $major ) )
+ return;
+ $wpp = new MIMEsearchPage( $major, $minor );
+
+ list( $limit, $offset ) = wfCheckLimits();
+ $wpp->doQuery( $offset, $limit );
+}
+
+function wfSpecialMIMEsearchParse( $str ) {
+ // searched for an invalid MIME type.
+ if( strpos( $str, '/' ) === false) {
+ return array ('', '');
+ }
+
+ list( $major, $minor ) = explode( '/', $str, 2 );
+
+ return array(
+ ltrim( $major, ' ' ),
+ rtrim( $minor, ' ' )
+ );
+}
+
+function wfSpecialMIMEsearchValidType( $type ) {
+ // From maintenance/tables.sql => img_major_mime
+ $types = array(
+ 'unknown',
+ 'application',
+ 'audio',
+ 'image',
+ 'text',
+ 'video',
+ 'message',
+ 'model',
+ 'multipart'
+ );
+
+ return in_array( $type, $types );
+}
+?>
diff --git a/includes/SpecialMostcategories.php b/includes/SpecialMostcategories.php
new file mode 100644
index 000000000000..41bfb0cdb769
--- /dev/null
+++ b/includes/SpecialMostcategories.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class MostcategoriesPage extends QueryPage {
+
+ function getName() { return 'Mostcategories'; }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $categorylinks, $page) = $dbr->tableNamesN( 'categorylinks', 'page' );
+ return
+ "
+ SELECT
+ 'Mostcategories' as type,
+ page_namespace as namespace,
+ page_title as title,
+ COUNT(*) as value
+ FROM $categorylinks
+ LEFT JOIN $page ON cl_from = page_id
+ WHERE page_namespace = " . NS_MAIN . "
+ GROUP BY 1,2,3
+ HAVING COUNT(*) > 1
+ ";
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang;
+ $title = Title::makeTitleSafe( $result->namespace, $result->title );
+ $count = wfMsgExt( 'ncategories', array( 'parsemag', 'escape' ), $wgLang->formatNum( $result->value ) );
+ $link = $skin->makeKnownLinkObj( $title, $title->getText() );
+ return wfSpecialList( $link, $count );
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialMostcategories() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $wpp = new MostcategoriesPage();
+
+ $wpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialMostimages.php b/includes/SpecialMostimages.php
new file mode 100644
index 000000000000..17c07c70db3d
--- /dev/null
+++ b/includes/SpecialMostimages.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class MostimagesPage extends QueryPage {
+
+ function getName() { return 'Mostimages'; }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $imagelinks = $dbr->tableName( 'imagelinks' );
+ return
+ "
+ SELECT
+ 'Mostimages' as type,
+ " . NS_IMAGE . " as namespace,
+ il_to as title,
+ COUNT(*) as value
+ FROM $imagelinks
+ GROUP BY 1,2,3
+ HAVING COUNT(*) > 1
+ ";
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+
+ $nt = Title::makeTitle( $result->namespace, $result->title );
+ $text = $wgContLang->convert( $nt->getPrefixedText() );
+
+ $plink = $skin->makeKnownLink( $nt->getPrefixedText(), $text );
+
+ $nl = wfMsgExt( 'nlinks', array( 'parsemag', 'escape'),
+ $wgLang->formatNum ( $result->value ) );
+ $nlink = $skin->makeKnownLink( $nt->getPrefixedText() . '#filelinks', $nl );
+
+ return wfSpecialList($plink, $nlink);
+ }
+}
+
+/**
+ * Constructor
+ */
+function wfSpecialMostimages() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $wpp = new MostimagesPage();
+
+ $wpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialMostlinked.php b/includes/SpecialMostlinked.php
new file mode 100644
index 000000000000..2794ecbbb5e1
--- /dev/null
+++ b/includes/SpecialMostlinked.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * A special page to show pages ordered by the number of pages linking to them
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @author Rob Church <robchur@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @copyright © 2006 Rob Church
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class MostlinkedPage extends QueryPage {
+
+ function getName() { return 'Mostlinked'; }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ /**
+ * Note: Getting page_namespace only works if $this->isCached() is false
+ */
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $pagelinks, $page ) = $dbr->tableNamesN( 'pagelinks', 'page' );
+ return
+ "SELECT 'Mostlinked' AS type,
+ pl_namespace AS namespace,
+ pl_title AS title,
+ COUNT(*) AS value,
+ page_namespace
+ FROM $pagelinks
+ LEFT JOIN $page ON pl_namespace=page_namespace AND pl_title=page_title
+ GROUP BY 1,2,3,5
+ HAVING COUNT(*) > 1";
+ }
+
+ /**
+ * Pre-fill the link cache
+ */
+ function preprocessResults( &$db, &$res ) {
+ if( $db->numRows( $res ) > 0 ) {
+ $linkBatch = new LinkBatch();
+ while( $row = $db->fetchObject( $res ) )
+ $linkBatch->addObj( Title::makeTitleSafe( $row->namespace, $row->title ) );
+ $db->dataSeek( $res, 0 );
+ $linkBatch->execute();
+ }
+ }
+
+ /**
+ * Make a link to "what links here" for the specified title
+ *
+ * @param $title Title being queried
+ * @param $skin Skin to use
+ * @return string
+ */
+ function makeWlhLink( &$title, $caption, &$skin ) {
+ $wlh = SpecialPage::getTitleFor( 'Whatlinkshere', $title->getPrefixedDBkey() );
+ return $skin->makeKnownLinkObj( $wlh, $caption );
+ }
+
+ /**
+ * Make links to the page corresponding to the item, and the "what links here" page for it
+ *
+ * @param $skin Skin to be used
+ * @param $result Result row
+ * @return string
+ */
+ function formatResult( $skin, $result ) {
+ global $wgLang;
+ $title = Title::makeTitleSafe( $result->namespace, $result->title );
+ $link = $skin->makeLinkObj( $title );
+ $wlh = $this->makeWlhLink( $title,
+ wfMsgExt( 'nlinks', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->value ) ), $skin );
+ return wfSpecialList( $link, $wlh );
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialMostlinked() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $wpp = new MostlinkedPage();
+
+ $wpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialMostlinkedcategories.php b/includes/SpecialMostlinkedcategories.php
new file mode 100644
index 000000000000..e1f848474d2f
--- /dev/null
+++ b/includes/SpecialMostlinkedcategories.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * A querypage to show categories ordered in descending order by the pages in them
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class MostlinkedCategoriesPage extends QueryPage {
+
+ function getName() { return 'Mostlinkedcategories'; }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $categorylinks = $dbr->tableName( 'categorylinks' );
+ $name = $dbr->addQuotes( $this->getName() );
+ return
+ "
+ SELECT
+ $name as type,
+ " . NS_CATEGORY . " as namespace,
+ cl_to as title,
+ COUNT(*) as value
+ FROM $categorylinks
+ GROUP BY 1,2,3
+ ";
+ }
+
+ function sortDescending() { return true; }
+
+ /**
+ * Fetch user page links and cache their existence
+ */
+ function preprocessResults( &$db, &$res ) {
+ $batch = new LinkBatch;
+ while ( $row = $db->fetchObject( $res ) )
+ $batch->addObj( Title::makeTitleSafe( $row->namespace, $row->title ) );
+ $batch->execute();
+
+ // Back to start for display
+ if ( $db->numRows( $res ) > 0 )
+ // If there are no rows we get an error seeking.
+ $db->dataSeek( $res, 0 );
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+
+ $nt = Title::makeTitle( $result->namespace, $result->title );
+ $text = $wgContLang->convert( $nt->getText() );
+
+ $plink = $skin->makeLinkObj( $nt, htmlspecialchars( $text ) );
+
+ $nlinks = wfMsgExt( 'nmembers', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->value ) );
+ return wfSpecialList($plink, $nlinks);
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialMostlinkedCategories() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $wpp = new MostlinkedCategoriesPage();
+
+ $wpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialMostrevisions.php b/includes/SpecialMostrevisions.php
new file mode 100644
index 000000000000..1e3334e9b604
--- /dev/null
+++ b/includes/SpecialMostrevisions.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * A special page to show pages in the
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class MostrevisionsPage extends QueryPage {
+
+ function getName() { return 'Mostrevisions'; }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $revision, $page ) = $dbr->tableNamesN( 'revision', 'page' );
+ return
+ "
+ SELECT
+ 'Mostrevisions' as type,
+ page_namespace as namespace,
+ page_title as title,
+ COUNT(*) as value
+ FROM $revision
+ JOIN $page ON page_id = rev_page
+ WHERE page_namespace = " . NS_MAIN . "
+ GROUP BY 1,2,3
+ HAVING COUNT(*) > 1
+ ";
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+
+ $nt = Title::makeTitle( $result->namespace, $result->title );
+ $text = $wgContLang->convert( $nt->getPrefixedText() );
+
+ $plink = $skin->makeKnownLinkObj( $nt, $text );
+
+ $nl = wfMsgExt( 'nrevisions', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->value ) );
+ $nlink = $skin->makeKnownLinkObj( $nt, $nl, 'action=history' );
+
+ return wfSpecialList($plink, $nlink);
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialMostrevisions() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $wpp = new MostrevisionsPage();
+
+ $wpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialMovepage.php b/includes/SpecialMovepage.php
new file mode 100644
index 000000000000..e3112c4c0642
--- /dev/null
+++ b/includes/SpecialMovepage.php
@@ -0,0 +1,313 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Constructor
+ */
+function wfSpecialMovepage( $par = null ) {
+ global $wgUser, $wgOut, $wgRequest, $action;
+
+ # Check rights
+ if ( !$wgUser->isAllowed( 'move' ) ) {
+ $wgOut->showErrorPage( 'movenologin', 'movenologintext' );
+ return;
+ }
+
+ # Don't allow blocked users to move pages
+ if ( $wgUser->isBlocked() ) {
+ $wgOut->blockedPage();
+ return;
+ }
+
+ # Check for database lock
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+
+ $f = new MovePageForm( $par );
+
+ if ( 'success' == $action ) {
+ $f->showSuccess();
+ } else if ( 'submit' == $action && $wgRequest->wasPosted()
+ && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
+ $f->doSubmit();
+ } else {
+ $f->showForm( '' );
+ }
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class MovePageForm {
+ var $oldTitle, $newTitle, $reason; # Text input
+ var $moveTalk, $deleteAndMove;
+
+ private $watch = false;
+
+ function MovePageForm( $par ) {
+ global $wgRequest;
+ $target = isset($par) ? $par : $wgRequest->getVal( 'target' );
+ $this->oldTitle = $wgRequest->getText( 'wpOldTitle', $target );
+ $this->newTitle = $wgRequest->getText( 'wpNewTitle' );
+ $this->reason = $wgRequest->getText( 'wpReason' );
+ if ( $wgRequest->wasPosted() ) {
+ $this->moveTalk = $wgRequest->getBool( 'wpMovetalk', false );
+ } else {
+ $this->moveTalk = $wgRequest->getBool( 'wpMovetalk', true );
+ }
+ $this->deleteAndMove = $wgRequest->getBool( 'wpDeleteAndMove' ) && $wgRequest->getBool( 'wpConfirm' );
+ $this->watch = $wgRequest->getCheck( 'wpWatch' );
+ }
+
+ function showForm( $err ) {
+ global $wgOut, $wgUser;
+
+ $wgOut->setPagetitle( wfMsg( 'movepage' ) );
+
+ $ot = Title::newFromURL( $this->oldTitle );
+ if( is_null( $ot ) ) {
+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
+ return;
+ }
+ $oldTitle = $ot->getPrefixedText();
+
+ $encOldTitle = htmlspecialchars( $oldTitle );
+ if( $this->newTitle == '' ) {
+ # Show the current title as a default
+ # when the form is first opened.
+ $encNewTitle = $encOldTitle;
+ } else {
+ if( $err == '' ) {
+ $nt = Title::newFromURL( $this->newTitle );
+ if( $nt ) {
+ # If a title was supplied, probably from the move log revert
+ # link, check for validity. We can then show some diagnostic
+ # information and save a click.
+ $newerr = $ot->isValidMoveOperation( $nt );
+ if( is_string( $newerr ) ) {
+ $err = $newerr;
+ }
+ }
+ }
+ $encNewTitle = htmlspecialchars( $this->newTitle );
+ }
+ $encReason = htmlspecialchars( $this->reason );
+
+ if ( $err == 'articleexists' && $wgUser->isAllowed( 'delete' ) ) {
+ $wgOut->addWikiText( wfMsg( 'delete_and_move_text', $encNewTitle ) );
+ $movepagebtn = wfMsgHtml( 'delete_and_move' );
+ $confirmText = wfMsgHtml( 'delete_and_move_confirm' );
+ $submitVar = 'wpDeleteAndMove';
+ $confirm = "
+ <tr>
+ <td align='right'>
+ <input type='checkbox' name='wpConfirm' id='wpConfirm' value=\"true\" />
+ </td>
+ <td align='left'><label for='wpConfirm'>{$confirmText}</label></td>
+ </tr>";
+ $err = '';
+ } else {
+ $wgOut->addWikiText( wfMsg( 'movepagetext' ) );
+ $movepagebtn = wfMsgHtml( 'movepagebtn' );
+ $submitVar = 'wpMove';
+ $confirm = false;
+ }
+
+ $oldTalk = $ot->getTalkPage();
+ $considerTalk = ( !$ot->isTalkPage() && $oldTalk->exists() );
+
+ if ( $considerTalk ) {
+ $wgOut->addWikiText( wfMsg( 'movepagetalktext' ) );
+ }
+
+ $movearticle = wfMsgHtml( 'movearticle' );
+ $newtitle = wfMsgHtml( 'newtitle' );
+ $movetalk = wfMsgHtml( 'movetalk' );
+ $movereason = wfMsgHtml( 'movereason' );
+
+ $titleObj = SpecialPage::getTitleFor( 'Movepage' );
+ $action = $titleObj->escapeLocalURL( 'action=submit' );
+ $token = htmlspecialchars( $wgUser->editToken() );
+
+ if ( $err != '' ) {
+ $wgOut->setSubtitle( wfMsg( 'formerror' ) );
+ $wgOut->addWikiText( '<p class="error">' . wfMsg($err) . "</p>\n" );
+ }
+
+ $moveTalkChecked = $this->moveTalk ? ' checked="checked"' : '';
+
+ $wgOut->addHTML( "
+<form id=\"movepage\" method=\"post\" action=\"{$action}\">
+ <table border='0'>
+ <tr>
+ <td align='right'>{$movearticle}:</td>
+ <td align='left'><strong>{$oldTitle}</strong></td>
+ </tr>
+ <tr>
+ <td align='right'><label for='wpNewTitle'>{$newtitle}:</label></td>
+ <td align='left'>
+ <input type='text' size='40' name='wpNewTitle' id='wpNewTitle' value=\"{$encNewTitle}\" />
+ <input type='hidden' name=\"wpOldTitle\" value=\"{$encOldTitle}\" />
+ </td>
+ </tr>
+ <tr>
+ <td align='right' valign='top'><br /><label for='wpReason'>{$movereason}:</label></td>
+ <td align='left' valign='top'><br />
+ <textarea cols='60' rows='2' name='wpReason' id='wpReason'>{$encReason}</textarea>
+ </td>
+ </tr>" );
+
+ if ( $considerTalk ) {
+ $wgOut->addHTML( "
+ <tr>
+ <td align='right'>
+ <input type='checkbox' id=\"wpMovetalk\" name=\"wpMovetalk\"{$moveTalkChecked} value=\"1\" />
+ </td>
+ <td><label for=\"wpMovetalk\">{$movetalk}</label></td>
+ </tr>" );
+ }
+
+ $watchChecked = $this->watch || $wgUser->getBoolOption( 'watchmoves' ) || $ot->userIsWatching();
+ $watch = '<tr>';
+ $watch .= '<td align="right">' . Xml::check( 'wpWatch', $watchChecked, array( 'id' => 'watch' ) ) . '</td>';
+ $watch .= '<td>' . Xml::label( wfMsg( 'move-watch' ), 'watch' ) . '</td>';
+ $watch .= '</tr>';
+ $wgOut->addHtml( $watch );
+
+ $wgOut->addHTML( "
+ {$confirm}
+ <tr>
+ <td>&nbsp;</td>
+ <td align='left'>
+ <input type='submit' name=\"{$submitVar}\" value=\"{$movepagebtn}\" />
+ </td>
+ </tr>
+ </table>
+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
+</form>\n" );
+
+ $this->showLogFragment( $ot, $wgOut );
+
+ }
+
+ function doSubmit() {
+ global $wgOut, $wgUser, $wgRequest;
+
+ if ( $wgUser->pingLimiter( 'move' ) ) {
+ $wgOut->rateLimited();
+ return;
+ }
+
+ # Variables beginning with 'o' for old article 'n' for new article
+
+ $ot = Title::newFromText( $this->oldTitle );
+ $nt = Title::newFromText( $this->newTitle );
+
+ # Delete to make way if requested
+ if ( $wgUser->isAllowed( 'delete' ) && $this->deleteAndMove ) {
+ $article = new Article( $nt );
+ // This may output an error message and exit
+ $article->doDelete( wfMsgForContent( 'delete_and_move_reason' ) );
+ }
+
+ # don't allow moving to pages with # in
+ if ( !$nt || $nt->getFragment() != '' ) {
+ $this->showForm( 'badtitletext' );
+ return;
+ }
+
+ $error = $ot->moveTo( $nt, true, $this->reason );
+ if ( $error !== true ) {
+ $this->showForm( $error );
+ return;
+ }
+
+ wfRunHooks( 'SpecialMovepageAfterMove', array( &$this , &$ot , &$nt ) ) ;
+
+ # Move the talk page if relevant, if it exists, and if we've been told to
+ $ott = $ot->getTalkPage();
+ if( $ott->exists() ) {
+ if( $this->moveTalk && !$ot->isTalkPage() && !$nt->isTalkPage() ) {
+ $ntt = $nt->getTalkPage();
+
+ # Attempt the move
+ $error = $ott->moveTo( $ntt, true, $this->reason );
+ if ( $error === true ) {
+ $talkmoved = 1;
+ wfRunHooks( 'SpecialMovepageAfterMove', array( &$this , &$ott , &$ntt ) ) ;
+ } else {
+ $talkmoved = $error;
+ }
+ } else {
+ # Stay silent on the subject of talk.
+ $talkmoved = '';
+ }
+ } else {
+ $talkmoved = 'notalkpage';
+ }
+
+ # Deal with watches
+ if( $this->watch ) {
+ $wgUser->addWatch( $ot );
+ $wgUser->addWatch( $nt );
+ } else {
+ $wgUser->removeWatch( $ot );
+ $wgUser->removeWatch( $nt );
+ }
+
+ # Give back result to user.
+ $titleObj = SpecialPage::getTitleFor( 'Movepage' );
+ $success = $titleObj->getFullURL(
+ 'action=success&oldtitle=' . wfUrlencode( $ot->getPrefixedText() ) .
+ '&newtitle=' . wfUrlencode( $nt->getPrefixedText() ) .
+ '&talkmoved='.$talkmoved );
+
+ $wgOut->redirect( $success );
+ }
+
+ function showSuccess() {
+ global $wgOut, $wgRequest, $wgRawHtml;
+
+ $wgOut->setPagetitle( wfMsg( 'movepage' ) );
+ $wgOut->setSubtitle( wfMsg( 'pagemovedsub' ) );
+
+ $oldText = wfEscapeWikiText( $wgRequest->getVal('oldtitle') );
+ $newText = wfEscapeWikiText( $wgRequest->getVal('newtitle') );
+ $talkmoved = $wgRequest->getVal('talkmoved');
+
+ $text = wfMsg( 'pagemovedtext', $oldText, $newText );
+
+ $allowHTML = $wgRawHtml;
+ $wgRawHtml = false;
+ $wgOut->addWikiText( $text );
+ $wgRawHtml = $allowHTML;
+
+ if ( $talkmoved == 1 ) {
+ $wgOut->addWikiText( wfMsg( 'talkpagemoved' ) );
+ } elseif( 'articleexists' == $talkmoved ) {
+ $wgOut->addWikiText( wfMsg( 'talkexists' ) );
+ } else {
+ $oldTitle = Title::newFromText( $oldText );
+ if ( isset( $oldTitle ) && !$oldTitle->isTalkPage() && $talkmoved != 'notalkpage' ) {
+ $wgOut->addWikiText( wfMsg( 'talkpagenotmoved', wfMsg( $talkmoved ) ) );
+ }
+ }
+ }
+
+ function showLogFragment( $title, &$out ) {
+ $out->addHtml( wfElement( 'h2', NULL, LogPage::logName( 'move' ) ) );
+ $request = new FauxRequest( array( 'page' => $title->getPrefixedText(), 'type' => 'move' ) );
+ $viewer = new LogViewer( new LogReader( $request ) );
+ $viewer->showList( $out );
+ }
+
+}
+?>
diff --git a/includes/SpecialNewimages.php b/includes/SpecialNewimages.php
new file mode 100644
index 000000000000..062e7e12eece
--- /dev/null
+++ b/includes/SpecialNewimages.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+function wfSpecialNewimages( $par, $specialPage ) {
+ global $wgUser, $wgOut, $wgLang, $wgRequest, $wgGroupPermissions;
+
+ $wpIlMatch = $wgRequest->getText( 'wpIlMatch' );
+ $dbr =& wfGetDB( DB_SLAVE );
+ $sk = $wgUser->getSkin();
+ $shownav = !$specialPage->including();
+ $hidebots = $wgRequest->getBool('hidebots',1);
+
+ $hidebotsql = '';
+ if ($hidebots) {
+
+ /** Make a list of group names which have the 'bot' flag
+ set.
+ */
+ $botconds=array();
+ foreach ($wgGroupPermissions as $groupname=>$perms) {
+ if(array_key_exists('bot',$perms) && $perms['bot']) {
+ $botconds[]="ug_group='$groupname'";
+ }
+ }
+
+ /* If not bot groups, do not set $hidebotsql */
+ if ($botconds) {
+ $isbotmember=$dbr->makeList($botconds, LIST_OR);
+
+ /** This join, in conjunction with WHERE ug_group
+ IS NULL, returns only those rows from IMAGE
+ where the uploading user is not a member of
+ a group which has the 'bot' permission set.
+ */
+ $ug = $dbr->tableName('user_groups');
+ $hidebotsql = " LEFT OUTER JOIN $ug ON img_user=ug_user AND ($isbotmember)";
+ }
+ }
+
+ $image = $dbr->tableName('image');
+
+ $sql="SELECT img_timestamp from $image";
+ if ($hidebotsql) {
+ $sql .= "$hidebotsql WHERE ug_group IS NULL";
+ }
+ $sql.=' ORDER BY img_timestamp DESC LIMIT 1';
+ $res = $dbr->query($sql, 'wfSpecialNewImages');
+ $row = $dbr->fetchRow($res);
+ if($row!==false) {
+ $ts=$row[0];
+ } else {
+ $ts=false;
+ }
+ $dbr->freeResult($res);
+ $sql='';
+
+ /** If we were clever, we'd use this to cache. */
+ $latestTimestamp = wfTimestamp( TS_MW, $ts);
+
+ /** Hardcode this for now. */
+ $limit = 48;
+
+ if ( $parval = intval( $par ) ) {
+ if ( $parval <= $limit && $parval > 0 ) {
+ $limit = $parval;
+ }
+ }
+
+ $where = array();
+ $searchpar = '';
+ if ( $wpIlMatch != '' ) {
+ $nt = Title::newFromUrl( $wpIlMatch );
+ if($nt ) {
+ $m = $dbr->strencode( strtolower( $nt->getDBkey() ) );
+ $m = str_replace( '%', "\\%", $m );
+ $m = str_replace( '_', "\\_", $m );
+ $where[] = "LCASE(img_name) LIKE '%{$m}%'";
+ $searchpar = '&wpIlMatch=' . urlencode( $wpIlMatch );
+ }
+ }
+
+ $invertSort = false;
+ if( $until = $wgRequest->getVal( 'until' ) ) {
+ $where[] = 'img_timestamp < ' . $dbr->timestamp( $until );
+ }
+ if( $from = $wgRequest->getVal( 'from' ) ) {
+ $where[] = 'img_timestamp >= ' . $dbr->timestamp( $from );
+ $invertSort = true;
+ }
+ $sql='SELECT img_size, img_name, img_user, img_user_text,'.
+ "img_description,img_timestamp FROM $image";
+
+ if($hidebotsql) {
+ $sql .= $hidebotsql;
+ $where[]='ug_group IS NULL';
+ }
+ if(count($where)) {
+ $sql.=' WHERE '.$dbr->makeList($where, LIST_AND);
+ }
+ $sql.=' ORDER BY img_timestamp '. ( $invertSort ? '' : ' DESC' );
+ $sql.=' LIMIT '.($limit+1);
+ $res = $dbr->query($sql, 'wfSpecialNewImages');
+
+ /**
+ * We have to flip things around to get the last N after a certain date
+ */
+ $images = array();
+ while ( $s = $dbr->fetchObject( $res ) ) {
+ if( $invertSort ) {
+ array_unshift( $images, $s );
+ } else {
+ array_push( $images, $s );
+ }
+ }
+ $dbr->freeResult( $res );
+
+ $gallery = new ImageGallery();
+ $firstTimestamp = null;
+ $lastTimestamp = null;
+ $shownImages = 0;
+ foreach( $images as $s ) {
+ if( ++$shownImages > $limit ) {
+ # One extra just to test for whether to show a page link;
+ # don't actually show it.
+ break;
+ }
+
+ $name = $s->img_name;
+ $ut = $s->img_user_text;
+
+ $nt = Title::newFromText( $name, NS_IMAGE );
+ $img = new Image( $nt );
+ $ul = $sk->makeLinkObj( Title::makeTitle( NS_USER, $ut ), $ut );
+
+ $gallery->add( $img, "$ul<br />\n<i>".$wgLang->timeanddate( $s->img_timestamp, true )."</i><br />\n" );
+
+ $timestamp = wfTimestamp( TS_MW, $s->img_timestamp );
+ if( empty( $firstTimestamp ) ) {
+ $firstTimestamp = $timestamp;
+ }
+ $lastTimestamp = $timestamp;
+ }
+
+ $bydate = wfMsg( 'bydate' );
+ $lt = $wgLang->formatNum( min( $shownImages, $limit ) );
+ if ($shownav) {
+ $text = wfMsgExt( 'imagelisttext', array('parse'), $lt, $bydate );
+ $wgOut->addHTML( $text . "\n" );
+ }
+
+ $sub = wfMsg( 'ilsubmit' );
+ $titleObj = SpecialPage::getTitleFor( 'Newimages' );
+ $action = $titleObj->escapeLocalURL( $hidebots ? '' : 'hidebots=0' );
+ if ($shownav) {
+ $wgOut->addHTML( "<form id=\"imagesearch\" method=\"post\" action=\"" .
+ "{$action}\">" .
+ "<input type='text' size='20' name=\"wpIlMatch\" value=\"" .
+ htmlspecialchars( $wpIlMatch ) . "\" /> " .
+ "<input type='submit' name=\"wpIlSubmit\" value=\"{$sub}\" /></form>" );
+ }
+
+ /**
+ * Paging controls...
+ */
+
+ # If we change bot visibility, this needs to be carried along.
+ if(!$hidebots) {
+ $botpar='&hidebots=0';
+ } else {
+ $botpar='';
+ }
+ $now = wfTimestampNow();
+ $date = $wgLang->timeanddate( $now, true );
+ $dateLink = $sk->makeKnownLinkObj( $titleObj, wfMsg( 'sp-newimages-showfrom', $date ), 'from='.$now.$botpar.$searchpar );
+
+ $botLink = $sk->makeKnownLinkObj($titleObj, wfMsg( 'showhidebots', ($hidebots ? wfMsg('show') : wfMsg('hide'))),'hidebots='.($hidebots ? '0' : '1').$searchpar);
+
+ $prevLink = wfMsg( 'prevn', $wgLang->formatNum( $limit ) );
+ if( $firstTimestamp && $firstTimestamp != $latestTimestamp ) {
+ $prevLink = $sk->makeKnownLinkObj( $titleObj, $prevLink, 'from=' . $firstTimestamp . $botpar . $searchpar );
+ }
+
+ $nextLink = wfMsg( 'nextn', $wgLang->formatNum( $limit ) );
+ if( $shownImages > $limit && $lastTimestamp ) {
+ $nextLink = $sk->makeKnownLinkObj( $titleObj, $nextLink, 'until=' . $lastTimestamp.$botpar.$searchpar );
+ }
+
+ $prevnext = '<p>' . $botLink . ' '. wfMsg( 'viewprevnext', $prevLink, $nextLink, $dateLink ) .'</p>';
+
+ if ($shownav)
+ $wgOut->addHTML( $prevnext );
+
+ if( count( $images ) ) {
+ $wgOut->addHTML( $gallery->toHTML() );
+ if ($shownav)
+ $wgOut->addHTML( $prevnext );
+ } else {
+ $wgOut->addWikiText( wfMsg( 'noimages' ) );
+ }
+}
+
+?>
diff --git a/includes/SpecialNewpages.php b/includes/SpecialNewpages.php
new file mode 100644
index 000000000000..620073835754
--- /dev/null
+++ b/includes/SpecialNewpages.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class NewPagesPage extends QueryPage {
+
+ var $namespace;
+ var $username = '';
+
+ function NewPagesPage( $namespace = NS_MAIN, $username = '' ) {
+ $this->namespace = $namespace;
+ $this->username = $username;
+ }
+
+ function getName() {
+ return 'Newpages';
+ }
+
+ function isExpensive() {
+ # Indexed on RC, and will *not* work with querycache yet.
+ return false;
+ }
+
+ function makeUserWhere( &$dbo ) {
+ $title = Title::makeTitleSafe( NS_USER, $this->username );
+ if( $title ) {
+ return ' AND rc_user_text = ' . $dbo->addQuotes( $title->getText() );
+ } else {
+ return '';
+ }
+ }
+
+ function getSQL() {
+ global $wgUser, $wgUseRCPatrol;
+ $usepatrol = ( $wgUseRCPatrol && $wgUser->isAllowed( 'patrol' ) ) ? 1 : 0;
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $recentchanges, $page ) = $dbr->tableNamesN( 'recentchanges', 'page' );
+
+ $uwhere = $this->makeUserWhere( $dbr );
+
+ # FIXME: text will break with compression
+ return
+ "SELECT 'Newpages' as type,
+ rc_namespace AS namespace,
+ rc_title AS title,
+ rc_cur_id AS cur_id,
+ rc_user AS user,
+ rc_user_text AS user_text,
+ rc_comment as comment,
+ rc_timestamp AS timestamp,
+ rc_timestamp AS value,
+ '{$usepatrol}' as usepatrol,
+ rc_patrolled AS patrolled,
+ rc_id AS rcid,
+ page_len as length,
+ page_latest as rev_id
+ FROM $recentchanges,$page
+ WHERE rc_cur_id=page_id AND rc_new=1
+ AND rc_namespace=" . $this->namespace . " AND page_is_redirect=0
+ {$uwhere}";
+ }
+
+ function preprocessResults( &$dbo, &$res ) {
+ # Do a batch existence check on the user and talk pages
+ $linkBatch = new LinkBatch();
+ while( $row = $dbo->fetchObject( $res ) ) {
+ $linkBatch->addObj( Title::makeTitleSafe( NS_USER, $row->user_text ) );
+ $linkBatch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->user_text ) );
+ }
+ $linkBatch->execute();
+ # Seek to start
+ if( $dbo->numRows( $res ) > 0 )
+ $dbo->dataSeek( $res, 0 );
+ }
+
+ /**
+ * Format a row, providing the timestamp, links to the page/history, size, user links, and a comment
+ *
+ * @param $skin Skin to use
+ * @param $result Result row
+ * @return string
+ */
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+ $dm = $wgContLang->getDirMark();
+
+ $title = Title::makeTitleSafe( $result->namespace, $result->title );
+ $time = $wgLang->timeAndDate( $result->timestamp, true );
+ $plink = $skin->makeKnownLinkObj( $title, '', $this->patrollable( $result ) ? 'rcid=' . $result->rcid : '' );
+ $hist = $skin->makeKnownLinkObj( $title, wfMsgHtml( 'hist' ), 'action=history' );
+ $length = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), $wgLang->formatNum( htmlspecialchars( $result->length ) ) );
+ $ulink = $skin->userLink( $result->user, $result->user_text ) . ' ' . $skin->userToolLinks( $result->user, $result->user_text );
+ $comment = $skin->commentBlock( $result->comment );
+
+ return "{$time} {$dm}{$plink} ({$hist}) {$dm}[{$length}] {$dm}{$ulink} {$comment}";
+ }
+
+ /**
+ * Should a specific result row provide "patrollable" links?
+ *
+ * @param $result Result row
+ * @return bool
+ */
+ function patrollable( $result ) {
+ global $wgUser, $wgUseRCPatrol;
+ return $wgUseRCPatrol && $wgUser->isAllowed( 'patrol' ) && !$result->patrolled;
+ }
+
+ function feedItemDesc( $row ) {
+ if( isset( $row->rev_id ) ) {
+ $revision = Revision::newFromId( $row->rev_id );
+ if( $revision ) {
+ return '<p>' . htmlspecialchars( wfMsg( 'summary' ) ) . ': ' .
+ htmlspecialchars( $revision->getComment() ) . "</p>\n<hr />\n<div>" .
+ nl2br( htmlspecialchars( $revision->getText() ) ) . "</div>";
+ }
+ }
+ return parent::feedItemDesc( $row );
+ }
+
+ /**
+ * Show a form for filtering namespace and username
+ *
+ * @return string
+ */
+ function getPageHeader() {
+ $self = SpecialPage::getTitleFor( $this->getName() );
+ $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $self->getLocalUrl() ) );
+ $form .= '<table><tr><td align="right">' . wfMsgHtml( 'namespace' ) . '</td>';
+ $form .= '<td>' . HtmlNamespaceSelector( $this->namespace ) . '</td><tr>';
+ $form .= '<tr><td align="right">' . wfMsgHtml( 'newpages-username' ) . '</td>';
+ $form .= '<td>' . wfInput( 'username', 30, $this->username ) . '</td></tr>';
+ $form .= '<tr><td></td><td>' . wfSubmitButton( wfMsg( 'allpagessubmit' ) ) . '</td></tr></table>';
+ $form .= wfHidden( 'offset', $this->offset ) . wfHidden( 'limit', $this->limit ) . '</form>';
+ return $form;
+ }
+
+ /**
+ * Link parameters
+ *
+ * @return array
+ */
+ function linkParameters() {
+ return( array( 'namespace' => $this->namespace, 'username' => $this->username ) );
+ }
+
+}
+
+/**
+ * constructor
+ */
+function wfSpecialNewpages($par, $specialPage) {
+ global $wgRequest, $wgContLang;
+
+ list( $limit, $offset ) = wfCheckLimits();
+ $namespace = NS_MAIN;
+ $username = '';
+
+ if ( $par ) {
+ $bits = preg_split( '/\s*,\s*/', trim( $par ) );
+ foreach ( $bits as $bit ) {
+ if ( 'shownav' == $bit )
+ $shownavigation = true;
+ if ( is_numeric( $bit ) )
+ $limit = $bit;
+
+ $m = array();
+ if ( preg_match( '/^limit=(\d+)$/', $bit, $m ) )
+ $limit = intval($m[1]);
+ if ( preg_match( '/^offset=(\d+)$/', $bit, $m ) )
+ $offset = intval($m[1]);
+ if ( preg_match( '/^namespace=(.*)$/', $bit, $m ) ) {
+ $ns = $wgContLang->getNsIndex( $m[1] );
+ if( $ns !== false ) {
+ $namespace = $ns;
+ }
+ }
+ }
+ } else {
+ if( $ns = $wgRequest->getInt( 'namespace', 0 ) )
+ $namespace = $ns;
+ if( $un = $wgRequest->getText( 'username' ) )
+ $username = $un;
+ }
+
+ if ( ! isset( $shownavigation ) )
+ $shownavigation = ! $specialPage->including();
+
+ $npp = new NewPagesPage( $namespace, $username );
+
+ if ( ! $npp->doFeed( $wgRequest->getVal( 'feed' ), $limit ) )
+ $npp->doQuery( $offset, $limit, $shownavigation );
+}
+
+?>
diff --git a/includes/SpecialPage.php b/includes/SpecialPage.php
new file mode 100644
index 000000000000..86438756cf1a
--- /dev/null
+++ b/includes/SpecialPage.php
@@ -0,0 +1,776 @@
+<?php
+/**
+ * SpecialPage: handling special pages and lists thereof.
+ *
+ * To add a special page in an extension, add to $wgSpecialPages either
+ * an object instance or an array containing the name and constructor
+ * parameters. The latter is preferred for performance reasons.
+ *
+ * The object instantiated must be either an instance of SpecialPage or a
+ * sub-class thereof. It must have an execute() method, which sends the HTML
+ * for the special page to $wgOut. The parent class has an execute() method
+ * which distributes the call to the historical global functions. Additionally,
+ * execute() also checks if the user has the necessary access privileges
+ * and bails out if not.
+ *
+ * To add a core special page, use the similar static list in
+ * SpecialPage::$mList. To remove a core static special page at runtime, use
+ * a SpecialPage_initList hook.
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * @access private
+ */
+
+/**
+ * Parent special page class, also static functions for handling the special
+ * page list
+ * @package MediaWiki
+ */
+class SpecialPage
+{
+ /**#@+
+ * @access private
+ */
+ /**
+ * The canonical name of this special page
+ * Also used for the default <h1> heading, @see getDescription()
+ */
+ var $mName;
+ /**
+ * The local name of this special page
+ */
+ var $mLocalName;
+ /**
+ * Minimum user level required to access this page, or "" for anyone.
+ * Also used to categorise the pages in Special:Specialpages
+ */
+ var $mRestriction;
+ /**
+ * Listed in Special:Specialpages?
+ */
+ var $mListed;
+ /**
+ * Function name called by the default execute()
+ */
+ var $mFunction;
+ /**
+ * File which needs to be included before the function above can be called
+ */
+ var $mFile;
+ /**
+ * Whether or not this special page is being included from an article
+ */
+ var $mIncluding;
+ /**
+ * Whether the special page can be included in an article
+ */
+ var $mIncludable;
+ /**
+ * Query parameters that can be passed through redirects
+ */
+ var $mAllowedRedirectParams = array();
+
+ static public $mList = array(
+ 'DoubleRedirects' => array( 'SpecialPage', 'DoubleRedirects' ),
+ 'BrokenRedirects' => array( 'SpecialPage', 'BrokenRedirects' ),
+ 'Disambiguations' => array( 'SpecialPage', 'Disambiguations' ),
+
+ 'Userlogin' => array( 'SpecialPage', 'Userlogin' ),
+ 'Userlogout' => array( 'UnlistedSpecialPage', 'Userlogout' ),
+ 'Preferences' => array( 'SpecialPage', 'Preferences' ),
+ 'Watchlist' => array( 'SpecialPage', 'Watchlist' ),
+
+ 'Recentchanges' => array( 'IncludableSpecialPage', 'Recentchanges' ),
+ 'Upload' => array( 'SpecialPage', 'Upload' ),
+ 'Imagelist' => array( 'SpecialPage', 'Imagelist' ),
+ 'Newimages' => array( 'IncludableSpecialPage', 'Newimages' ),
+ 'Listusers' => array( 'SpecialPage', 'Listusers' ),
+ 'Statistics' => array( 'SpecialPage', 'Statistics' ),
+ 'Randompage' => array( 'SpecialPage', 'Randompage' ),
+ 'Lonelypages' => array( 'SpecialPage', 'Lonelypages' ),
+ 'Uncategorizedpages' => array( 'SpecialPage', 'Uncategorizedpages' ),
+ 'Uncategorizedcategories' => array( 'SpecialPage', 'Uncategorizedcategories' ),
+ 'Uncategorizedimages' => array( 'SpecialPage', 'Uncategorizedimages' ),
+ 'Unusedcategories' => array( 'SpecialPage', 'Unusedcategories' ),
+ 'Unusedimages' => array( 'SpecialPage', 'Unusedimages' ),
+ 'Wantedpages' => array( 'IncludableSpecialPage', 'Wantedpages' ),
+ 'Wantedcategories' => array( 'SpecialPage', 'Wantedcategories' ),
+ 'Mostlinked' => array( 'SpecialPage', 'Mostlinked' ),
+ 'Mostlinkedcategories' => array( 'SpecialPage', 'Mostlinkedcategories' ),
+ 'Mostcategories' => array( 'SpecialPage', 'Mostcategories' ),
+ 'Mostimages' => array( 'SpecialPage', 'Mostimages' ),
+ 'Mostrevisions' => array( 'SpecialPage', 'Mostrevisions' ),
+ 'Shortpages' => array( 'SpecialPage', 'Shortpages' ),
+ 'Longpages' => array( 'SpecialPage', 'Longpages' ),
+ 'Newpages' => array( 'IncludableSpecialPage', 'Newpages' ),
+ 'Ancientpages' => array( 'SpecialPage', 'Ancientpages' ),
+ 'Deadendpages' => array( 'SpecialPage', 'Deadendpages' ),
+ 'Allpages' => array( 'IncludableSpecialPage', 'Allpages' ),
+ 'Prefixindex' => array( 'IncludableSpecialPage', 'Prefixindex' ) ,
+ 'Ipblocklist' => array( 'SpecialPage', 'Ipblocklist' ),
+ 'Specialpages' => array( 'UnlistedSpecialPage', 'Specialpages' ),
+ 'Contributions' => array( 'UnlistedSpecialPage', 'Contributions' ),
+ 'Emailuser' => array( 'UnlistedSpecialPage', 'Emailuser' ),
+ 'Whatlinkshere' => array( 'UnlistedSpecialPage', 'Whatlinkshere' ),
+ 'Recentchangeslinked' => array( 'UnlistedSpecialPage', 'Recentchangeslinked' ),
+ 'Movepage' => array( 'UnlistedSpecialPage', 'Movepage' ),
+ 'Blockme' => array( 'UnlistedSpecialPage', 'Blockme' ),
+ 'Resetpass' => array( 'UnlistedSpecialPage', 'Resetpass' ),
+ 'Booksources' => 'SpecialBookSources',
+ 'Categories' => array( 'SpecialPage', 'Categories' ),
+ 'Export' => array( 'SpecialPage', 'Export' ),
+ 'Version' => array( 'SpecialPage', 'Version' ),
+ 'Allmessages' => array( 'SpecialPage', 'Allmessages' ),
+ 'Log' => array( 'SpecialPage', 'Log' ),
+ 'Blockip' => array( 'SpecialPage', 'Blockip', 'block' ),
+ 'Undelete' => array( 'SpecialPage', 'Undelete', 'deletedhistory' ),
+ 'Import' => array( 'SpecialPage', "Import", 'import' ),
+ 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ),
+ 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ),
+ 'Userrights' => array( 'SpecialPage', 'Userrights', 'userrights' ),
+ 'MIMEsearch' => array( 'SpecialPage', 'MIMEsearch' ),
+ 'Unwatchedpages' => array( 'SpecialPage', 'Unwatchedpages', 'unwatchedpages' ),
+ 'Listredirects' => array( 'SpecialPage', 'Listredirects' ),
+ 'Revisiondelete' => array( 'SpecialPage', 'Revisiondelete', 'deleterevision' ),
+ 'Unusedtemplates' => array( 'SpecialPage', 'Unusedtemplates' ),
+ 'Randomredirect' => array( 'SpecialPage', 'Randomredirect' ),
+
+ 'Mypage' => array( 'SpecialMypage' ),
+ 'Mytalk' => array( 'SpecialMytalk' ),
+ 'Mycontributions' => array( 'SpecialMycontributions' ),
+ 'Listadmins' => array( 'SpecialRedirectToSpecial', 'Listadmins', 'Listusers', 'sysop' ),
+ );
+
+ static public $mAliases;
+ static public $mListInitialised = false;
+
+ /**#@-*/
+
+ /**
+ * Initialise the special page list
+ * This must be called before accessing SpecialPage::$mList
+ */
+ static function initList() {
+ global $wgSpecialPages;
+ global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
+
+ if ( self::$mListInitialised ) {
+ return;
+ }
+ wfProfileIn( __METHOD__ );
+
+ # Better to set this now, to avoid infinite recursion in carelessly written hooks
+ self::$mListInitialised = true;
+
+ if( !$wgDisableCounters ) {
+ self::$mList['Popularpages'] = array( 'SpecialPage', 'Popularpages' );
+ }
+
+ if( !$wgDisableInternalSearch ) {
+ self::$mList['Search'] = array( 'SpecialPage', 'Search' );
+ }
+
+ if( $wgEmailAuthentication ) {
+ self::$mList['Confirmemail'] = array( 'UnlistedSpecialPage', 'Confirmemail' );
+ }
+
+ # Add extension special pages
+ self::$mList = array_merge( self::$mList, $wgSpecialPages );
+
+ # Run hooks
+ # This hook can be used to remove undesired built-in special pages
+ wfRunHooks( 'SpecialPage_initList', array( &self::$mList ) );
+ wfProfileOut( __METHOD__ );
+ }
+
+ static function initAliasList() {
+ if ( !is_null( self::$mAliases ) ) {
+ return;
+ }
+
+ global $wgContLang;
+ $aliases = $wgContLang->getSpecialPageAliases();
+ $missingPages = self::$mList;
+ self::$mAliases = array();
+ foreach ( $aliases as $realName => $aliasList ) {
+ foreach ( $aliasList as $alias ) {
+ self::$mAliases[$wgContLang->caseFold( $alias )] = $realName;
+ }
+ unset( $missingPages[$realName] );
+ }
+ foreach ( $missingPages as $name => $stuff ) {
+ self::$mAliases[$wgContLang->caseFold( $name )] = $name;
+ }
+ }
+
+ /**
+ * Given a special page alias, return the special page name.
+ * Returns false if there is no such alias.
+ */
+ static function resolveAlias( $alias ) {
+ global $wgContLang;
+
+ if ( !self::$mListInitialised ) self::initList();
+ if ( is_null( self::$mAliases ) ) self::initAliasList();
+ $caseFoldedAlias = $wgContLang->caseFold( $alias );
+ if ( isset( self::$mAliases[$caseFoldedAlias] ) ) {
+ return self::$mAliases[$caseFoldedAlias];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Given a special page name with a possible subpage, return an array
+ * where the first element is the special page name and the second is the
+ * subpage.
+ */
+ static function resolveAliasWithSubpage( $alias ) {
+ $bits = explode( '/', $alias, 2 );
+ $name = self::resolveAlias( $bits[0] );
+ if( !isset( $bits[1] ) ) { // bug 2087
+ $par = NULL;
+ } else {
+ $par = $bits[1];
+ }
+ return array( $name, $par );
+ }
+
+ /**
+ * Add a page to the list of valid special pages. This used to be the preferred
+ * method for adding special pages in extensions. It's now suggested that you add
+ * an associative record to $wgSpecialPages. This avoids autoloading SpecialPage.
+ *
+ * @param mixed $page Must either be an array specifying a class name and
+ * constructor parameters, or an object. The object,
+ * when constructed, must have an execute() method which
+ * sends HTML to $wgOut.
+ * @static
+ */
+ static function addPage( &$page ) {
+ if ( !self::$mListInitialised ) {
+ self::initList();
+ }
+ self::$mList[$page->mName] = $page;
+ }
+
+ /**
+ * Remove a special page from the list
+ * Formerly used to disable expensive or dangerous special pages. The
+ * preferred method is now to add a SpecialPage_initList hook.
+ *
+ * @static
+ */
+ static function removePage( $name ) {
+ if ( !self::$mListInitialised ) {
+ self::initList();
+ }
+ unset( self::$mList[$name] );
+ }
+
+ /**
+ * Find the object with a given name and return it (or NULL)
+ * @static
+ * @param string $name
+ */
+ static function getPage( $name ) {
+ if ( !self::$mListInitialised ) {
+ self::initList();
+ }
+ if ( array_key_exists( $name, self::$mList ) ) {
+ $rec = self::$mList[$name];
+ if ( is_string( $rec ) ) {
+ $className = $rec;
+ self::$mList[$name] = new $className;
+ } elseif ( is_array( $rec ) ) {
+ $className = array_shift( $rec );
+ self::$mList[$name] = wfCreateObject( $className, $rec );
+ }
+ return self::$mList[$name];
+ } else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Get a special page with a given localised name, or NULL if there
+ * is no such special page.
+ */
+ static function getPageByAlias( $alias ) {
+ $realName = self::resolveAlias( $alias );
+ if ( $realName ) {
+ return self::getPage( $realName );
+ } else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Return categorised listable special pages for all users
+ * @static
+ */
+ static function getRegularPages() {
+ if ( !self::$mListInitialised ) {
+ self::initList();
+ }
+ $pages = array();
+
+ foreach ( self::$mList as $name => $rec ) {
+ $page = self::getPage( $name );
+ if ( $page->isListed() && $page->getRestriction() == '' ) {
+ $pages[$name] = $page;
+ }
+ }
+ return $pages;
+ }
+
+ /**
+ * Return categorised listable special pages which are available
+ * for the current user, but not for everyone
+ * @static
+ */
+ static function getRestrictedPages() {
+ global $wgUser;
+ if ( !self::$mListInitialised ) {
+ self::initList();
+ }
+ $pages = array();
+
+ foreach ( self::$mList as $name => $rec ) {
+ $page = self::getPage( $name );
+ if ( $page->isListed() ) {
+ $restriction = $page->getRestriction();
+ if ( $restriction != '' && $wgUser->isAllowed( $restriction ) ) {
+ $pages[$name] = $page;
+ }
+ }
+ }
+ return $pages;
+ }
+
+ /**
+ * Execute a special page path.
+ * The path may contain parameters, e.g. Special:Name/Params
+ * Extracts the special page name and call the execute method, passing the parameters
+ *
+ * Returns a title object if the page is redirected, false if there was no such special
+ * page, and true if it was successful.
+ *
+ * @param $title a title object
+ * @param $including output is being captured for use in {{special:whatever}}
+ */
+ static function executePath( &$title, $including = false ) {
+ global $wgOut, $wgTitle, $wgRequest;
+ wfProfileIn( __METHOD__ );
+
+ # FIXME: redirects broken due to this call
+ $bits = explode( '/', $title->getDBkey(), 2 );
+ $name = $bits[0];
+ if( !isset( $bits[1] ) ) { // bug 2087
+ $par = NULL;
+ } else {
+ $par = $bits[1];
+ }
+ $page = SpecialPage::getPageByAlias( $name );
+
+ # Nonexistent?
+ if ( !$page ) {
+ if ( !$including ) {
+ $wgOut->setArticleRelated( false );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->setStatusCode( 404 );
+ $wgOut->showErrorPage( 'nosuchspecialpage', 'nospecialpagetext' );
+ }
+ wfProfileOut( __METHOD__ );
+ return false;
+ }
+
+ # Check for redirect
+ if ( !$including ) {
+ $redirect = $page->getRedirect( $par );
+ if ( $redirect ) {
+ $query = $page->getRedirectQuery();
+ $url = $redirect->getFullUrl( $query );
+ $wgOut->redirect( $url );
+ wfProfileOut( __METHOD__ );
+ return $redirect;
+ }
+ }
+
+ # Redirect to canonical alias for GET commands
+ # Not for POST, we'd lose the post data, so it's best to just distribute
+ # the request. Such POST requests are possible for old extensions that
+ # generate self-links without being aware that their default name has
+ # changed.
+ if ( !$including && $name != $page->getLocalName() && !$wgRequest->wasPosted() ) {
+ $query = $_GET;
+ unset( $query['title'] );
+ $query = wfArrayToCGI( $query );
+ $title = $page->getTitle( $par );
+ $url = $title->getFullUrl( $query );
+ $wgOut->redirect( $url );
+ wfProfileOut( __METHOD__ );
+ return $redirect;
+ }
+
+ if ( $including && !$page->includable() ) {
+ wfProfileOut( __METHOD__ );
+ return false;
+ } elseif ( !$including ) {
+ $wgTitle = $page->getTitle();
+ }
+ $page->including( $including );
+
+ // Execute special page
+ $profName = 'Special:' . $page->getName();
+ wfProfileIn( $profName );
+ $page->execute( $par );
+ wfProfileOut( $profName );
+ wfProfileOut( __METHOD__ );
+ return true;
+ }
+
+ /**
+ * Just like executePath() except it returns the HTML instead of outputting it
+ * Returns false if there was no such special page, or a title object if it was
+ * a redirect.
+ * @static
+ */
+ static function capturePath( &$title ) {
+ global $wgOut, $wgTitle;
+
+ $oldTitle = $wgTitle;
+ $oldOut = $wgOut;
+ $wgOut = new OutputPage;
+
+ $ret = SpecialPage::executePath( $title, true );
+ if ( $ret === true ) {
+ $ret = $wgOut->getHTML();
+ }
+ $wgTitle = $oldTitle;
+ $wgOut = $oldOut;
+ return $ret;
+ }
+
+ /**
+ * Get the local name for a specified canonical name
+ */
+ static function getLocalNameFor( $name, $subpage = false ) {
+ global $wgContLang;
+ $aliases = $wgContLang->getSpecialPageAliases();
+ if ( isset( $aliases[$name][0] ) ) {
+ $name = $aliases[$name][0];
+ }
+ if ( $subpage !== false && !is_null( $subpage ) ) {
+ $name = "$name/$subpage";
+ }
+ return $name;
+ }
+
+ /**
+ * Get a localised Title object for a specified special page name
+ */
+ static function getTitleFor( $name, $subpage = false ) {
+ $name = self::getLocalNameFor( $name, $subpage );
+ if ( $name ) {
+ return Title::makeTitle( NS_SPECIAL, $name );
+ } else {
+ throw new MWException( "Invalid special page name \"$name\"" );
+ }
+ }
+
+ /**
+ * Get a localised Title object for a page name with a possibly unvalidated subpage
+ */
+ static function getSafeTitleFor( $name, $subpage = false ) {
+ $name = self::getLocalNameFor( $name, $subpage );
+ if ( $name ) {
+ return Title::makeTitleSafe( NS_SPECIAL, $name );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get a title for a given alias
+ * @return Title or null if there is no such alias
+ */
+ static function getTitleForAlias( $alias ) {
+ $name = self::resolveAlias( $alias );
+ if ( $name ) {
+ return self::getTitleFor( $name );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Default constructor for special pages
+ * Derivative classes should call this from their constructor
+ * Note that if the user does not have the required level, an error message will
+ * be displayed by the default execute() method, without the global function ever
+ * being called.
+ *
+ * If you override execute(), you can recover the default behaviour with userCanExecute()
+ * and displayRestrictionError()
+ *
+ * @param string $name Name of the special page, as seen in links and URLs
+ * @param string $restriction User right required, e.g. "block" or "delete"
+ * @param boolean $listed Whether the page is listed in Special:Specialpages
+ * @param string $function Function called by execute(). By default it is constructed from $name
+ * @param string $file File which is included by execute(). It is also constructed from $name by default
+ */
+ function SpecialPage( $name = '', $restriction = '', $listed = true, $function = false, $file = 'default', $includable = false ) {
+ $this->mName = $name;
+ $this->mRestriction = $restriction;
+ $this->mListed = $listed;
+ $this->mIncludable = $includable;
+ if ( $function == false ) {
+ $this->mFunction = 'wfSpecial'.$name;
+ } else {
+ $this->mFunction = $function;
+ }
+ if ( $file === 'default' ) {
+ $this->mFile = "Special{$name}.php";
+ } else {
+ $this->mFile = $file;
+ }
+ }
+
+ /**#@+
+ * Accessor
+ *
+ * @deprecated
+ */
+ function getName() { return $this->mName; }
+ function getRestriction() { return $this->mRestriction; }
+ function getFile() { return $this->mFile; }
+ function isListed() { return $this->mListed; }
+ /**#@-*/
+
+ /**#@+
+ * Accessor and mutator
+ */
+ function name( $x = NULL ) { return wfSetVar( $this->mName, $x ); }
+ function restrictions( $x = NULL) { return wfSetVar( $this->mRestrictions, $x ); }
+ function listed( $x = NULL) { return wfSetVar( $this->mListed, $x ); }
+ function func( $x = NULL) { return wfSetVar( $this->mFunction, $x ); }
+ function file( $x = NULL) { return wfSetVar( $this->mFile, $x ); }
+ function includable( $x = NULL ) { return wfSetVar( $this->mIncludable, $x ); }
+ function including( $x = NULL ) { return wfSetVar( $this->mIncluding, $x ); }
+ /**#@-*/
+
+ /**
+ * Get the localised name of the special page
+ */
+ function getLocalName() {
+ if ( !isset( $this->mLocalName ) ) {
+ $this->mLocalName = self::getLocalNameFor( $this->mName );
+ }
+ return $this->mLocalName;
+ }
+
+ /**
+ * Checks if the given user (identified by an object) can execute this
+ * special page (as defined by $mRestriction)
+ */
+ function userCanExecute( &$user ) {
+ return $user->isAllowed( $this->mRestriction );
+ }
+
+ /**
+ * Output an error message telling the user what access level they have to have
+ */
+ function displayRestrictionError() {
+ global $wgOut;
+ $wgOut->permissionRequired( $this->mRestriction );
+ }
+
+ /**
+ * Sets headers - this should be called from the execute() method of all derived classes!
+ */
+ function setHeaders() {
+ global $wgOut;
+ $wgOut->setArticleRelated( false );
+ $wgOut->setRobotPolicy( "noindex,nofollow" );
+ $wgOut->setPageTitle( $this->getDescription() );
+ }
+
+ /**
+ * Default execute method
+ * Checks user permissions, calls the function given in mFunction
+ *
+ * This may be overridden by subclasses.
+ */
+ function execute( $par ) {
+ global $wgUser;
+
+ $this->setHeaders();
+
+ if ( $this->userCanExecute( $wgUser ) ) {
+ $func = $this->mFunction;
+ // only load file if the function does not exist
+ if(!function_exists($func) and $this->mFile) {
+ require_once( $this->mFile );
+ }
+ # FIXME: these hooks are broken for extensions and anything else that subclasses SpecialPage.
+ if ( wfRunHooks( 'SpecialPageExecuteBeforeHeader', array( &$this, &$par, &$func ) ) )
+ $this->outputHeader();
+ if ( ! wfRunHooks( 'SpecialPageExecuteBeforePage', array( &$this, &$par, &$func ) ) )
+ return;
+ $func( $par, $this );
+ if ( ! wfRunHooks( 'SpecialPageExecuteAfterPage', array( &$this, &$par, &$func ) ) )
+ return;
+ } else {
+ $this->displayRestrictionError();
+ }
+ }
+
+ function outputHeader() {
+ global $wgOut, $wgContLang;
+
+ $msg = $wgContLang->lc( $this->name() ) . '-summary';
+ $out = wfMsg( $msg );
+ if ( ! wfEmptyMsg( $msg, $out ) and $out !== '' and ! $this->including() )
+ $wgOut->addWikiText( $out );
+
+ }
+
+ # Returns the name that goes in the <h1> in the special page itself, and also the name that
+ # will be listed in Special:Specialpages
+ #
+ # Derived classes can override this, but usually it is easier to keep the default behaviour.
+ # Messages can be added at run-time, see MessageCache.php
+ function getDescription() {
+ return wfMsg( strtolower( $this->mName ) );
+ }
+
+ /**
+ * Get a self-referential title object
+ */
+ function getTitle( $subpage = false) {
+ return self::getTitleFor( $this->mName, $subpage );
+ }
+
+ /**
+ * Set whether this page is listed in Special:Specialpages, at run-time
+ */
+ function setListed( $listed ) {
+ return wfSetVar( $this->mListed, $listed );
+ }
+
+ /**
+ * If the special page is a redirect, then get the Title object it redirects to.
+ * False otherwise.
+ */
+ function getRedirect( $subpage ) {
+ return false;
+ }
+
+ /**
+ * Return part of the request string for a special redirect page
+ * This allows passing, e.g. action=history to Special:Mypage, etc.
+ *
+ * @return string
+ */
+ function getRedirectQuery() {
+ global $wgRequest;
+ $params = array();
+ foreach( $this->mAllowedRedirectParams as $arg ) {
+ if( $val = $wgRequest->getVal( $arg, false ) )
+ $params[] = $arg . '=' . $val;
+ }
+
+ return count( $params ) ? implode( '&', $params ) : false;
+ }
+}
+
+/**
+ * Shortcut to construct a special page which is unlisted by default
+ * @package MediaWiki
+ */
+class UnlistedSpecialPage extends SpecialPage
+{
+ function UnlistedSpecialPage( $name, $restriction = '', $function = false, $file = 'default' ) {
+ SpecialPage::SpecialPage( $name, $restriction, false, $function, $file );
+ }
+}
+
+/**
+ * Shortcut to construct an includable special page
+ * @package MediaWiki
+ */
+class IncludableSpecialPage extends SpecialPage
+{
+ function IncludableSpecialPage( $name, $restriction = '', $listed = true, $function = false, $file = 'default' ) {
+ SpecialPage::SpecialPage( $name, $restriction, $listed, $function, $file, true );
+ }
+}
+
+class SpecialRedirectToSpecial extends UnlistedSpecialPage {
+ var $redirName, $redirSubpage;
+
+ function __construct( $name, $redirName, $redirSubpage = false, $redirectParams = array() ) {
+ parent::__construct( $name );
+ $this->redirName = $redirName;
+ $this->redirSubpage = $redirSubpage;
+ $this->mAllowedRedirectParams = $redirectParams;
+ }
+
+ function getRedirect( $subpage ) {
+ if ( $this->redirSubpage === false ) {
+ return SpecialPage::getTitleFor( $this->redirName, $subpage );
+ } else {
+ return SpecialPage::getTitleFor( $this->redirName, $this->redirSubpage );
+ }
+ }
+}
+
+class SpecialMypage extends UnlistedSpecialPage {
+ function __construct() {
+ parent::__construct( 'Mypage' );
+ $this->mAllowedRedirectParams = array( 'action' );
+ }
+
+ function getRedirect( $subpage ) {
+ global $wgUser;
+ if ( strval( $subpage ) !== '' ) {
+ return Title::makeTitle( NS_USER, $wgUser->getName() . '/' . $subpage );
+ } else {
+ return Title::makeTitle( NS_USER, $wgUser->getName() );
+ }
+ }
+}
+
+class SpecialMytalk extends UnlistedSpecialPage {
+ function __construct() {
+ parent::__construct( 'Mytalk' );
+ $this->mAllowedRedirectParams = array( 'action' );
+ }
+
+ function getRedirect( $subpage ) {
+ global $wgUser;
+ if ( strval( $subpage ) !== '' ) {
+ return Title::makeTitle( NS_USER_TALK, $wgUser->getName() . '/' . $subpage );
+ } else {
+ return Title::makeTitle( NS_USER_TALK, $wgUser->getName() );
+ }
+ }
+}
+
+class SpecialMycontributions extends UnlistedSpecialPage {
+ function __construct() {
+ parent::__construct( 'Mycontributions' );
+ }
+
+ function getRedirect( $subpage ) {
+ global $wgUser;
+ return SpecialPage::getTitleFor( 'Contributions', $wgUser->getName() );
+ }
+}
+
+?>
diff --git a/includes/SpecialPopularpages.php b/includes/SpecialPopularpages.php
new file mode 100644
index 000000000000..77d41437c5fa
--- /dev/null
+++ b/includes/SpecialPopularpages.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class PopularPagesPage extends QueryPage {
+
+ function getName() {
+ return "Popularpages";
+ }
+
+ function isExpensive() {
+ # page_counter is not indexed
+ return true;
+ }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $page = $dbr->tableName( 'page' );
+
+ return
+ "SELECT 'Popularpages' as type,
+ page_namespace as namespace,
+ page_title as title,
+ page_counter as value
+ FROM $page
+ WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0";
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+ $title = Title::makeTitle( $result->namespace, $result->title );
+ $link = $skin->makeKnownLinkObj( $title, htmlspecialchars( $wgContLang->convert( $title->getPrefixedText() ) ) );
+ $nv = wfMsgExt( 'nviews', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->value ) );
+ return wfSpecialList($link, $nv);
+ }
+}
+
+/**
+ * Constructor
+ */
+function wfSpecialPopularpages() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $ppp = new PopularPagesPage();
+
+ return $ppp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialPreferences.php b/includes/SpecialPreferences.php
new file mode 100644
index 000000000000..643932c4c10b
--- /dev/null
+++ b/includes/SpecialPreferences.php
@@ -0,0 +1,961 @@
+<?php
+/**
+ * Hold things related to displaying and saving user preferences.
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Entry point that create the "Preferences" object
+ */
+function wfSpecialPreferences() {
+ global $wgRequest;
+
+ $form = new PreferencesForm( $wgRequest );
+ $form->execute();
+}
+
+/**
+ * Preferences form handling
+ * This object will show the preferences form and can save it as well.
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class PreferencesForm {
+ var $mQuickbar, $mOldpass, $mNewpass, $mRetypePass, $mStubs;
+ var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick;
+ var $mUserLanguage, $mUserVariant;
+ var $mSearch, $mRecent, $mHourDiff, $mSearchLines, $mSearchChars, $mAction;
+ var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mImageSize;
+ var $mUnderline, $mWatchlistEdits;
+
+ /**
+ * Constructor
+ * Load some values
+ */
+ function PreferencesForm( &$request ) {
+ global $wgContLang, $wgUser, $wgAllowRealName;
+
+ $this->mQuickbar = $request->getVal( 'wpQuickbar' );
+ $this->mOldpass = $request->getVal( 'wpOldpass' );
+ $this->mNewpass = $request->getVal( 'wpNewpass' );
+ $this->mRetypePass =$request->getVal( 'wpRetypePass' );
+ $this->mStubs = $request->getVal( 'wpStubs' );
+ $this->mRows = $request->getVal( 'wpRows' );
+ $this->mCols = $request->getVal( 'wpCols' );
+ $this->mSkin = $request->getVal( 'wpSkin' );
+ $this->mMath = $request->getVal( 'wpMath' );
+ $this->mDate = $request->getVal( 'wpDate' );
+ $this->mUserEmail = $request->getVal( 'wpUserEmail' );
+ $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : '';
+ $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 0 : 1;
+ $this->mNick = $request->getVal( 'wpNick' );
+ $this->mUserLanguage = $request->getVal( 'wpUserLanguage' );
+ $this->mUserVariant = $request->getVal( 'wpUserVariant' );
+ $this->mSearch = $request->getVal( 'wpSearch' );
+ $this->mRecent = $request->getVal( 'wpRecent' );
+ $this->mHourDiff = $request->getVal( 'wpHourDiff' );
+ $this->mSearchLines = $request->getVal( 'wpSearchLines' );
+ $this->mSearchChars = $request->getVal( 'wpSearchChars' );
+ $this->mImageSize = $request->getVal( 'wpImageSize' );
+ $this->mThumbSize = $request->getInt( 'wpThumbSize' );
+ $this->mUnderline = $request->getInt( 'wpOpunderline' );
+ $this->mAction = $request->getVal( 'action' );
+ $this->mReset = $request->getCheck( 'wpReset' );
+ $this->mPosted = $request->wasPosted();
+ $this->mSuccess = $request->getCheck( 'success' );
+ $this->mWatchlistDays = $request->getVal( 'wpWatchlistDays' );
+ $this->mWatchlistEdits = $request->getVal( 'wpWatchlistEdits' );
+
+ $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) &&
+ $this->mPosted &&
+ $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
+
+ # User toggles (the big ugly unsorted list of checkboxes)
+ $this->mToggles = array();
+ if ( $this->mPosted ) {
+ $togs = User::getToggles();
+ foreach ( $togs as $tname ) {
+ $this->mToggles[$tname] = $request->getCheck( "wpOp$tname" ) ? 1 : 0;
+ }
+ }
+
+ $this->mUsedToggles = array();
+
+ # Search namespace options
+ # Note: namespaces don't necessarily have consecutive keys
+ $this->mSearchNs = array();
+ if ( $this->mPosted ) {
+ $namespaces = $wgContLang->getNamespaces();
+ foreach ( $namespaces as $i => $namespace ) {
+ if ( $i >= 0 ) {
+ $this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
+ }
+ }
+ }
+
+ # Validate language
+ if ( !preg_match( '/^[a-z\-]*$/', $this->mUserLanguage ) ) {
+ $this->mUserLanguage = 'nolanguage';
+ }
+ }
+
+ function execute() {
+ global $wgUser, $wgOut;
+
+ if ( $wgUser->isAnon() ) {
+ $wgOut->showErrorPage( 'prefsnologin', 'prefsnologintext' );
+ return;
+ }
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+ if ( $this->mReset ) {
+ $this->resetPrefs();
+ $this->mainPrefsForm( 'reset', wfMsg( 'prefsreset' ) );
+ } else if ( $this->mSaveprefs ) {
+ $this->savePreferences();
+ } else {
+ $this->resetPrefs();
+ $this->mainPrefsForm( '' );
+ }
+ }
+ /**
+ * @access private
+ */
+ function validateInt( &$val, $min=0, $max=0x7fffffff ) {
+ $val = intval($val);
+ $val = min($val, $max);
+ $val = max($val, $min);
+ return $val;
+ }
+
+ /**
+ * @access private
+ */
+ function validateFloat( &$val, $min, $max=0x7fffffff ) {
+ $val = floatval( $val );
+ $val = min( $val, $max );
+ $val = max( $val, $min );
+ return( $val );
+ }
+
+ /**
+ * @access private
+ */
+ function validateIntOrNull( &$val, $min=0, $max=0x7fffffff ) {
+ $val = trim($val);
+ if($val === '') {
+ return $val;
+ } else {
+ return $this->validateInt( $val, $min, $max );
+ }
+ }
+
+ /**
+ * @access private
+ */
+ function validateDate( $val ) {
+ global $wgLang, $wgContLang;
+ if ( $val !== false && (
+ in_array( $val, (array)$wgLang->getDatePreferences() ) ||
+ in_array( $val, (array)$wgContLang->getDatePreferences() ) ) )
+ {
+ return $val;
+ } else {
+ return $wgLang->getDefaultDateFormat();
+ }
+ }
+
+ /**
+ * Used to validate the user inputed timezone before saving it as
+ * 'timeciorrection', will return '00:00' if fed bogus data.
+ * Note: It's not a 100% correct implementation timezone-wise, it will
+ * accept stuff like '14:30',
+ * @access private
+ * @param string $s the user input
+ * @return string
+ */
+ function validateTimeZone( $s ) {
+ if ( $s !== '' ) {
+ if ( strpos( $s, ':' ) ) {
+ # HH:MM
+ $array = explode( ':' , $s );
+ $hour = intval( $array[0] );
+ $minute = intval( $array[1] );
+ } else {
+ $minute = intval( $s * 60 );
+ $hour = intval( $minute / 60 );
+ $minute = abs( $minute ) % 60;
+ }
+ # Max is +14:00 and min is -12:00, see:
+ # http://en.wikipedia.org/wiki/Timezone
+ $hour = min( $hour, 14 );
+ $hour = max( $hour, -12 );
+ $minute = min( $minute, 59 );
+ $minute = max( $minute, 0 );
+ $s = sprintf( "%02d:%02d", $hour, $minute );
+ }
+ return $s;
+ }
+
+ /**
+ * @access private
+ */
+ function savePreferences() {
+ global $wgUser, $wgOut, $wgParser;
+ global $wgEnableUserEmail, $wgEnableEmail;
+ global $wgEmailAuthentication;
+ global $wgAuth;
+
+
+ if ( '' != $this->mNewpass && $wgAuth->allowPasswordChange() ) {
+ if ( $this->mNewpass != $this->mRetypePass ) {
+ $this->mainPrefsForm( 'error', wfMsg( 'badretype' ) );
+ return;
+ }
+
+ if (!$wgUser->checkPassword( $this->mOldpass )) {
+ $this->mainPrefsForm( 'error', wfMsg( 'wrongpassword' ) );
+ return;
+ }
+
+ try {
+ $wgUser->setPassword( $this->mNewpass );
+ $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
+ } catch( PasswordError $e ) {
+ $this->mainPrefsForm( 'error', $e->getMessage() );
+ return;
+ }
+ }
+ $wgUser->setRealName( $this->mRealName );
+
+ if( $wgUser->getOption( 'language' ) !== $this->mUserLanguage ) {
+ $needRedirect = true;
+ } else {
+ $needRedirect = false;
+ }
+
+ # Validate the signature and clean it up as needed
+ if( $this->mToggles['fancysig'] ) {
+ if( Parser::validateSig( $this->mNick ) !== false ) {
+ $this->mNick = $wgParser->cleanSig( $this->mNick );
+ } else {
+ $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
+ }
+ } else {
+ // When no fancy sig used, make sure ~{3,5} get removed.
+ $this->mNick = $wgParser->cleanSigInSig( $this->mNick );
+ }
+
+ $wgUser->setOption( 'language', $this->mUserLanguage );
+ $wgUser->setOption( 'variant', $this->mUserVariant );
+ $wgUser->setOption( 'nickname', $this->mNick );
+ $wgUser->setOption( 'quickbar', $this->mQuickbar );
+ $wgUser->setOption( 'skin', $this->mSkin );
+ global $wgUseTeX;
+ if( $wgUseTeX ) {
+ $wgUser->setOption( 'math', $this->mMath );
+ }
+ $wgUser->setOption( 'date', $this->validateDate( $this->mDate ) );
+ $wgUser->setOption( 'searchlimit', $this->validateIntOrNull( $this->mSearch ) );
+ $wgUser->setOption( 'contextlines', $this->validateIntOrNull( $this->mSearchLines ) );
+ $wgUser->setOption( 'contextchars', $this->validateIntOrNull( $this->mSearchChars ) );
+ $wgUser->setOption( 'rclimit', $this->validateIntOrNull( $this->mRecent ) );
+ $wgUser->setOption( 'wllimit', $this->validateIntOrNull( $this->mWatchlistEdits, 0, 1000 ) );
+ $wgUser->setOption( 'rows', $this->validateInt( $this->mRows, 4, 1000 ) );
+ $wgUser->setOption( 'cols', $this->validateInt( $this->mCols, 4, 1000 ) );
+ $wgUser->setOption( 'stubthreshold', $this->validateIntOrNull( $this->mStubs ) );
+ $wgUser->setOption( 'timecorrection', $this->validateTimeZone( $this->mHourDiff, -12, 14 ) );
+ $wgUser->setOption( 'imagesize', $this->mImageSize );
+ $wgUser->setOption( 'thumbsize', $this->mThumbSize );
+ $wgUser->setOption( 'underline', $this->validateInt($this->mUnderline, 0, 2) );
+ $wgUser->setOption( 'watchlistdays', $this->validateFloat( $this->mWatchlistDays, 0, 7 ) );
+
+ # Set search namespace options
+ foreach( $this->mSearchNs as $i => $value ) {
+ $wgUser->setOption( "searchNs{$i}", $value );
+ }
+
+ if( $wgEnableEmail && $wgEnableUserEmail ) {
+ $wgUser->setOption( 'disablemail', $this->mEmailFlag );
+ }
+
+ # Set user toggles
+ foreach ( $this->mToggles as $tname => $tvalue ) {
+ $wgUser->setOption( $tname, $tvalue );
+ }
+ if (!$wgAuth->updateExternalDB($wgUser)) {
+ $this->mainPrefsForm( wfMsg( 'externaldberror' ) );
+ return;
+ }
+ $wgUser->setCookies();
+ $wgUser->saveSettings();
+
+ $error = false;
+ if( $wgEnableEmail ) {
+ $newadr = $this->mUserEmail;
+ $oldadr = $wgUser->getEmail();
+ if( ($newadr != '') && ($newadr != $oldadr) ) {
+ # the user has supplied a new email address on the login page
+ if( $wgUser->isValidEmailAddr( $newadr ) ) {
+ $wgUser->mEmail = $newadr; # new behaviour: set this new emailaddr from login-page into user database record
+ $wgUser->mEmailAuthenticated = null; # but flag as "dirty" = unauthenticated
+ $wgUser->saveSettings();
+ if ($wgEmailAuthentication) {
+ # Mail a temporary password to the dirty address.
+ # User can come back through the confirmation URL to re-enable email.
+ $result = $wgUser->sendConfirmationMail();
+ if( WikiError::isError( $result ) ) {
+ $error = wfMsg( 'mailerror', htmlspecialchars( $result->getMessage() ) );
+ } else {
+ $error = wfMsg( 'eauthentsent', $wgUser->getName() );
+ }
+ }
+ } else {
+ $error = wfMsg( 'invalidemailaddress' );
+ }
+ } else {
+ $wgUser->setEmail( $this->mUserEmail );
+ $wgUser->setCookies();
+ $wgUser->saveSettings();
+ }
+ }
+
+ if( $needRedirect && $error === false ) {
+ $title =& SpecialPage::getTitleFor( "Preferences" );
+ $wgOut->redirect($title->getFullURL('success'));
+ return;
+ }
+
+ $wgOut->setParserOptions( ParserOptions::newFromUser( $wgUser ) );
+ $this->mainPrefsForm( $error === false ? 'success' : 'error', $error);
+ }
+
+ /**
+ * @access private
+ */
+ function resetPrefs() {
+ global $wgUser, $wgLang, $wgContLang, $wgContLanguageCode, $wgAllowRealName;
+
+ $this->mOldpass = $this->mNewpass = $this->mRetypePass = '';
+ $this->mUserEmail = $wgUser->getEmail();
+ $this->mUserEmailAuthenticationtimestamp = $wgUser->getEmailAuthenticationtimestamp();
+ $this->mRealName = ($wgAllowRealName) ? $wgUser->getRealName() : '';
+
+ # language value might be blank, default to content language
+ $this->mUserLanguage = $wgUser->getOption( 'language', $wgContLanguageCode );
+
+ $this->mUserVariant = $wgUser->getOption( 'variant');
+ $this->mEmailFlag = $wgUser->getOption( 'disablemail' ) == 1 ? 1 : 0;
+ $this->mNick = $wgUser->getOption( 'nickname' );
+
+ $this->mQuickbar = $wgUser->getOption( 'quickbar' );
+ $this->mSkin = Skin::normalizeKey( $wgUser->getOption( 'skin' ) );
+ $this->mMath = $wgUser->getOption( 'math' );
+ $this->mDate = $wgUser->getDatePreference();
+ $this->mRows = $wgUser->getOption( 'rows' );
+ $this->mCols = $wgUser->getOption( 'cols' );
+ $this->mStubs = $wgUser->getOption( 'stubthreshold' );
+ $this->mHourDiff = $wgUser->getOption( 'timecorrection' );
+ $this->mSearch = $wgUser->getOption( 'searchlimit' );
+ $this->mSearchLines = $wgUser->getOption( 'contextlines' );
+ $this->mSearchChars = $wgUser->getOption( 'contextchars' );
+ $this->mImageSize = $wgUser->getOption( 'imagesize' );
+ $this->mThumbSize = $wgUser->getOption( 'thumbsize' );
+ $this->mRecent = $wgUser->getOption( 'rclimit' );
+ $this->mWatchlistEdits = $wgUser->getOption( 'wllimit' );
+ $this->mUnderline = $wgUser->getOption( 'underline' );
+ $this->mWatchlistDays = $wgUser->getOption( 'watchlistdays' );
+
+ $togs = User::getToggles();
+ foreach ( $togs as $tname ) {
+ $this->mToggles[$tname] = $wgUser->getOption( $tname );
+ }
+
+ $namespaces = $wgContLang->getNamespaces();
+ foreach ( $namespaces as $i => $namespace ) {
+ if ( $i >= NS_MAIN ) {
+ $this->mSearchNs[$i] = $wgUser->getOption( 'searchNs'.$i );
+ }
+ }
+ }
+
+ /**
+ * @access private
+ */
+ function namespacesCheckboxes() {
+ global $wgContLang;
+
+ # Determine namespace checkboxes
+ $namespaces = $wgContLang->getNamespaces();
+ $r1 = null;
+
+ foreach ( $namespaces as $i => $name ) {
+ if ($i < 0)
+ continue;
+ $checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
+ $name = str_replace( '_', ' ', $namespaces[$i] );
+
+ if ( empty($name) )
+ $name = wfMsg( 'blanknamespace' );
+
+ $r1 .= "<input type='checkbox' value='1' name='wpNs$i' id='wpNs$i' {$checked}/> <label for='wpNs$i'>{$name}</label><br />\n";
+ }
+ return $r1;
+ }
+
+
+ function getToggle( $tname, $trailer = false, $disabled = false ) {
+ global $wgUser, $wgLang;
+
+ $this->mUsedToggles[$tname] = true;
+ $ttext = $wgLang->getUserToggle( $tname );
+
+ $checked = $wgUser->getOption( $tname ) == 1 ? ' checked="checked"' : '';
+ $disabled = $disabled ? ' disabled="disabled"' : '';
+ $trailer = $trailer ? $trailer : '';
+ return "<div class='toggle'><input type='checkbox' value='1' id=\"$tname\" name=\"wpOp$tname\"$checked$disabled />" .
+ " <span class='toggletext'><label for=\"$tname\">$ttext</label>$trailer</span></div>\n";
+ }
+
+ function getToggles( $items ) {
+ $out = "";
+ foreach( $items as $item ) {
+ if( $item === false )
+ continue;
+ if( is_array( $item ) ) {
+ list( $key, $trailer ) = $item;
+ } else {
+ $key = $item;
+ $trailer = false;
+ }
+ $out .= $this->getToggle( $key, $trailer );
+ }
+ return $out;
+ }
+
+ function addRow($td1, $td2) {
+ return "<tr><td align='right'>$td1</td><td align='left'>$td2</td></tr>";
+ }
+
+ /**
+ * @access private
+ */
+ function mainPrefsForm( $status , $message = '' ) {
+ global $wgUser, $wgOut, $wgLang, $wgContLang;
+ global $wgAllowRealName, $wgImageLimits, $wgThumbLimits;
+ global $wgDisableLangConversion;
+ global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits;
+ global $wgRCShowWatchingUsers, $wgEnotifRevealEditorAddress;
+ global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication;
+ global $wgContLanguageCode, $wgDefaultSkin, $wgSkipSkins, $wgAuth;
+
+ $wgOut->setPageTitle( wfMsg( 'preferences' ) );
+ $wgOut->setArticleRelated( false );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+
+ if ( $this->mSuccess || 'success' == $status ) {
+ $wgOut->addWikitext( '<div class="successbox"><strong>'. wfMsg( 'savedprefs' ) . '</strong></div>' );
+ } else if ( 'error' == $status ) {
+ $wgOut->addWikitext( '<div class="errorbox"><strong>' . $message . '</strong></div>' );
+ } else if ( '' != $status ) {
+ $wgOut->addWikitext( $message . "\n----" );
+ }
+
+ $qbs = $wgLang->getQuickbarSettings();
+ $skinNames = $wgLang->getSkinNames();
+ $mathopts = $wgLang->getMathNames();
+ $dateopts = $wgLang->getDatePreferences();
+ $togs = User::getToggles();
+
+ $titleObj = SpecialPage::getTitleFor( 'Preferences' );
+ $action = $titleObj->escapeLocalURL();
+
+ # Pre-expire some toggles so they won't show if disabled
+ $this->mUsedToggles[ 'shownumberswatching' ] = true;
+ $this->mUsedToggles[ 'showupdated' ] = true;
+ $this->mUsedToggles[ 'enotifwatchlistpages' ] = true;
+ $this->mUsedToggles[ 'enotifusertalkpages' ] = true;
+ $this->mUsedToggles[ 'enotifminoredits' ] = true;
+ $this->mUsedToggles[ 'enotifrevealaddr' ] = true;
+ $this->mUsedToggles[ 'ccmeonemails' ] = true;
+ $this->mUsedToggles[ 'uselivepreview' ] = true;
+
+ # Enotif
+ # <FIXME>
+ $this->mUserEmail = htmlspecialchars( $this->mUserEmail );
+ $this->mRealName = htmlspecialchars( $this->mRealName );
+ $rawNick = $this->mNick;
+ $this->mNick = htmlspecialchars( $this->mNick );
+ if ( !$this->mEmailFlag ) { $emfc = 'checked="checked"'; }
+ else { $emfc = ''; }
+
+
+ if ($wgEmailAuthentication && ($this->mUserEmail != '') ) {
+ if( $wgUser->getEmailAuthenticationTimestamp() ) {
+ $emailauthenticated = wfMsg('emailauthenticated',$wgLang->timeanddate($wgUser->getEmailAuthenticationTimestamp(), true ) ).'<br />';
+ $disableEmailPrefs = false;
+ } else {
+ $disableEmailPrefs = true;
+ $skin = $wgUser->getSkin();
+ $emailauthenticated = wfMsg('emailnotauthenticated').'<br />' .
+ $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Confirmemail' ),
+ wfMsg( 'emailconfirmlink' ) );
+ }
+ } else {
+ $emailauthenticated = '';
+ $disableEmailPrefs = false;
+ }
+
+ if ($this->mUserEmail == '') {
+ $emailauthenticated = wfMsg( 'noemailprefs' );
+ }
+
+ $ps = $this->namespacesCheckboxes();
+
+ $enotifwatchlistpages = ($wgEnotifWatchlist) ? $this->getToggle( 'enotifwatchlistpages', false, $disableEmailPrefs ) : '';
+ $enotifusertalkpages = ($wgEnotifUserTalk) ? $this->getToggle( 'enotifusertalkpages', false, $disableEmailPrefs ) : '';
+ $enotifminoredits = ($wgEnotifWatchlist && $wgEnotifMinorEdits) ? $this->getToggle( 'enotifminoredits', false, $disableEmailPrefs ) : '';
+ $enotifrevealaddr = (($wgEnotifWatchlist || $wgEnotifUserTalk) && $wgEnotifRevealEditorAddress) ? $this->getToggle( 'enotifrevealaddr', false, $disableEmailPrefs ) : '';
+
+ # </FIXME>
+
+ $wgOut->addHTML( "<form action=\"$action\" method='post'>" );
+ $wgOut->addHTML( "<div id='preferences'>" );
+
+ # User data
+ #
+
+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('prefs-personal') . "</legend>\n<table>\n");
+
+ $userInformationHtml =
+ $this->addRow(
+ wfMsg( 'username'),
+ $wgUser->getName()
+ ) .
+ $this->addRow(
+ wfMsg( 'uid' ),
+ $wgUser->getID()
+ );
+
+ if( wfRunHooks( 'PreferencesUserInformationPanel', array( $this, &$userInformationHtml ) ) ) {
+ $wgOut->addHtml( $userInformationHtml );
+ }
+
+
+ if ($wgAllowRealName) {
+ $wgOut->addHTML(
+ $this->addRow(
+ '<label for="wpRealName">' . wfMsg('yourrealname') . '</label>',
+ "<input type='text' name='wpRealName' id='wpRealName' value=\"{$this->mRealName}\" size='25' />"
+ )
+ );
+ }
+ if ($wgEnableEmail) {
+ $wgOut->addHTML(
+ $this->addRow(
+ '<label for="wpUserEmail">' . wfMsg( 'youremail' ) . '</label>',
+ "<input type='text' name='wpUserEmail' id='wpUserEmail' value=\"{$this->mUserEmail}\" size='25' />"
+ )
+ );
+ }
+
+ global $wgParser;
+ if( !empty( $this->mToggles['fancysig'] ) &&
+ false === $wgParser->validateSig( $rawNick ) ) {
+ $invalidSig = $this->addRow(
+ '&nbsp;',
+ '<span class="error">' . wfMsgHtml( 'badsig' ) . '<span>'
+ );
+ } else {
+ $invalidSig = '';
+ }
+
+ $wgOut->addHTML(
+ $this->addRow(
+ '<label for="wpNick">' . wfMsg( 'yournick' ) . '</label>',
+ "<input type='text' name='wpNick' id='wpNick' value=\"{$this->mNick}\" size='25' />"
+ ) .
+ $invalidSig .
+ # FIXME: The <input> part should be where the &nbsp; is, getToggle() needs
+ # to be changed to out return its output in two parts. -ævar
+ $this->addRow(
+ '&nbsp;',
+ $this->getToggle( 'fancysig' )
+ )
+ );
+
+ /**
+ * Make sure the site language is in the list; a custom language code
+ * might not have a defined name...
+ */
+ $languages = Language::getLanguageNames( true );
+ if( !array_key_exists( $wgContLanguageCode, $languages ) ) {
+ $languages[$wgContLanguageCode] = $wgContLanguageCode;
+ }
+ ksort( $languages );
+
+ /**
+ * If a bogus value is set, default to the content language.
+ * Otherwise, no default is selected and the user ends up
+ * with an Afrikaans interface since it's first in the list.
+ */
+ $selectedLang = isset( $languages[$this->mUserLanguage] ) ? $this->mUserLanguage : $wgContLanguageCode;
+ $options = "\n";
+ foreach( $languages as $code => $name ) {
+ $selected = ($code == $selectedLang);
+ $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
+ }
+ $wgOut->addHTML(
+ $this->addRow(
+ '<label for="wpUserLanguage">' . wfMsg('yourlanguage') . '</label>',
+ "<select name='wpUserLanguage' id='wpUserLanguage'>$options</select>"
+ )
+ );
+
+ /* see if there are multiple language variants to choose from*/
+ if(!$wgDisableLangConversion) {
+ $variants = $wgContLang->getVariants();
+ $variantArray = array();
+
+ foreach($variants as $v) {
+ $v = str_replace( '_', '-', strtolower($v));
+ if( array_key_exists( $v, $languages ) ) {
+ // If it doesn't have a name, we'll pretend it doesn't exist
+ $variantArray[$v] = $languages[$v];
+ }
+ }
+
+ $options = "\n";
+ foreach( $variantArray as $code => $name ) {
+ $selected = ($code == $this->mUserVariant);
+ $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
+ }
+
+ if(count($variantArray) > 1) {
+ $wgOut->addHtml(
+ $this->addRow( wfMsg( 'yourvariant' ),
+ "<select name='wpUserVariant'>$options</select>" )
+ );
+ }
+ }
+ $wgOut->addHTML('</table>');
+
+ # Password
+ if( $wgAuth->allowPasswordChange() ) {
+ $this->mOldpass = htmlspecialchars( $this->mOldpass );
+ $this->mNewpass = htmlspecialchars( $this->mNewpass );
+ $this->mRetypePass = htmlspecialchars( $this->mRetypePass );
+
+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'changepassword' ) . '</legend><table>');
+ $wgOut->addHTML(
+ $this->addRow(
+ '<label for="wpOldpass">' . wfMsg( 'oldpassword' ) . '</label>',
+ "<input type='password' name='wpOldpass' id='wpOldpass' value=\"{$this->mOldpass}\" size='20' />"
+ ) .
+ $this->addRow(
+ '<label for="wpNewpass">' . wfMsg( 'newpassword' ) . '</label>',
+ "<input type='password' name='wpNewpass' id='wpNewpass' value=\"{$this->mNewpass}\" size='20' />"
+ ) .
+ $this->addRow(
+ '<label for="wpRetypePass">' . wfMsg( 'retypenew' ) . '</label>',
+ "<input type='password' name='wpRetypePass' id='wpRetypePass' value=\"{$this->mRetypePass}\" size='20' />"
+ ) .
+ "</table>\n" .
+ $this->getToggle( "rememberpassword" ) . "</fieldset>\n\n" );
+ }
+
+ # <FIXME>
+ # Enotif
+ if ($wgEnableEmail) {
+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'email' ) . '</legend>' );
+ $wgOut->addHTML(
+ $emailauthenticated.
+ $enotifrevealaddr.
+ $enotifwatchlistpages.
+ $enotifusertalkpages.
+ $enotifminoredits );
+ if ($wgEnableUserEmail) {
+ $emf = wfMsg( 'allowemail' );
+ $disabled = $disableEmailPrefs ? ' disabled="disabled"' : '';
+ $wgOut->addHTML(
+ "<div><input type='checkbox' $emfc $disabled value='1' name='wpEmailFlag' id='wpEmailFlag' /> <label for='wpEmailFlag'>$emf</label></div>" );
+ }
+ $wgOut->addHtml( $this->getToggle( 'ccmeonemails' ) );
+
+ $wgOut->addHTML( '</fieldset>' );
+ }
+ # </FIXME>
+
+ # Show little "help" tips for the real name and email address options
+ if( $wgAllowRealName || $wgEnableEmail ) {
+ if( $wgAllowRealName )
+ $tips[] = wfMsg( 'prefs-help-realname' );
+ if( $wgEnableEmail )
+ $tips[] = wfMsg( 'prefs-help-email' );
+ $wgOut->addHtml( '<div class="prefsectiontip">' . implode( '<br />', $tips ) . '</div>' );
+ }
+
+ $wgOut->addHTML( '</fieldset>' );
+
+ # Quickbar
+ #
+ if ($this->mSkin == 'cologneblue' || $this->mSkin == 'standard') {
+ $wgOut->addHtml( "<fieldset>\n<legend>" . wfMsg( 'qbsettings' ) . "</legend>\n" );
+ for ( $i = 0; $i < count( $qbs ); ++$i ) {
+ if ( $i == $this->mQuickbar ) { $checked = ' checked="checked"'; }
+ else { $checked = ""; }
+ $wgOut->addHTML( "<div><label><input type='radio' name='wpQuickbar' value=\"$i\"$checked />{$qbs[$i]}</label></div>\n" );
+ }
+ $wgOut->addHtml( "</fieldset>\n\n" );
+ } else {
+ # Need to output a hidden option even if the relevant skin is not in use,
+ # otherwise the preference will get reset to 0 on submit
+ $wgOut->addHtml( wfHidden( 'wpQuickbar', $this->mQuickbar ) );
+ }
+
+ # Skin
+ #
+ $wgOut->addHTML( "<fieldset>\n<legend>\n" . wfMsg('skin') . "</legend>\n" );
+ $mptitle = Title::newMainPage();
+ $previewtext = wfMsg('skinpreview');
+ # Only show members of Skin::getSkinNames() rather than
+ # $skinNames (skins is all skin names from Language.php)
+ $validSkinNames = Skin::getSkinNames();
+ # Sort by UI skin name. First though need to update validSkinNames as sometimes
+ # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
+ foreach ($validSkinNames as $skinkey => & $skinname ) {
+ if ( isset( $skinNames[$skinkey] ) ) {
+ $skinname = $skinNames[$skinkey];
+ }
+ }
+ asort($validSkinNames);
+ foreach ($validSkinNames as $skinkey => $sn ) {
+ if ( in_array( $skinkey, $wgSkipSkins ) ) {
+ continue;
+ }
+ $checked = $skinkey == $this->mSkin ? ' checked="checked"' : '';
+
+ $mplink = htmlspecialchars($mptitle->getLocalURL("useskin=$skinkey"));
+ $previewlink = "<a target='_blank' href=\"$mplink\">$previewtext</a>";
+ if( $skinkey == $wgDefaultSkin )
+ $sn .= ' (' . wfMsg( 'default' ) . ')';
+ $wgOut->addHTML( "<input type='radio' name='wpSkin' id=\"wpSkin$skinkey\" value=\"$skinkey\"$checked /> <label for=\"wpSkin$skinkey\">{$sn}</label> $previewlink<br />\n" );
+ }
+ $wgOut->addHTML( "</fieldset>\n\n" );
+
+ # Math
+ #
+ global $wgUseTeX;
+ if( $wgUseTeX ) {
+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('math') . '</legend>' );
+ foreach ( $mathopts as $k => $v ) {
+ $checked = $k == $this->mMath ? ' checked="checked"' : '';
+ $wgOut->addHTML( "<div><label><input type='radio' name='wpMath' value=\"$k\"$checked /> ".wfMsg($v)."</label></div>\n" );
+ }
+ $wgOut->addHTML( "</fieldset>\n\n" );
+ }
+
+ # Files
+ #
+ $wgOut->addHTML(
+ "<fieldset>\n" . Xml::element( 'legend', null, wfMsg( 'files' ) ) . "\n"
+ );
+
+ $imageLimitOptions = null;
+ foreach ( $wgImageLimits as $index => $limits ) {
+ $selected = ($index == $this->mImageSize);
+ $imageLimitOptions .= Xml::option( "{$limits[0]}×{$limits[1]}" .
+ wfMsg('unit-pixel'), $index, $selected );
+ }
+
+ $imageSizeId = 'wpImageSize';
+ $wgOut->addHTML(
+ "<div>" . Xml::label( wfMsg('imagemaxsize'), $imageSizeId ) . " " .
+ Xml::openElement( 'select', array( 'name' => $imageSizeId, 'id' => $imageSizeId ) ) .
+ $imageLimitOptions .
+ Xml::closeElement( 'select' ) . "</div>\n"
+ );
+
+ $imageThumbOptions = null;
+ foreach ( $wgThumbLimits as $index => $size ) {
+ $selected = ($index == $this->mThumbSize);
+ $imageThumbOptions .= Xml::option($size . wfMsg('unit-pixel'), $index,
+ $selected);
+ }
+
+ $thumbSizeId = 'wpThumbSize';
+ $wgOut->addHTML(
+ "<div>" . Xml::label( wfMsg('thumbsize'), $thumbSizeId ) . " " .
+ Xml::openElement( 'select', array( 'name' => $thumbSizeId, 'id' => $thumbSizeId ) ) .
+ $imageThumbOptions .
+ Xml::closeElement( 'select' ) . "</div>\n"
+ );
+
+ $wgOut->addHTML( "</fieldset>\n\n" );
+
+ # Date format
+ #
+ # Date/Time
+ #
+
+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'datetime' ) . "</legend>\n" );
+
+ if ($dateopts) {
+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'dateformat' ) . "</legend>\n" );
+ $idCnt = 0;
+ $epoch = '20010115161234'; # Wikipedia day
+ foreach( $dateopts as $key ) {
+ if( $key == 'default' ) {
+ $formatted = wfMsgHtml( 'datedefault' );
+ } else {
+ $formatted = htmlspecialchars( $wgLang->timeanddate( $epoch, false, $key ) );
+ }
+ ($key == $this->mDate) ? $checked = ' checked="checked"' : $checked = '';
+ $wgOut->addHTML( "<div><input type='radio' name=\"wpDate\" id=\"wpDate$idCnt\" ".
+ "value=\"$key\"$checked /> <label for=\"wpDate$idCnt\">$formatted</label></div>\n" );
+ $idCnt++;
+ }
+ $wgOut->addHTML( "</fieldset>\n" );
+ }
+
+ $nowlocal = $wgLang->time( $now = wfTimestampNow(), true );
+ $nowserver = $wgLang->time( $now, false );
+
+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'timezonelegend' ). '</legend><table>' .
+ $this->addRow( wfMsg( 'servertime' ), $nowserver ) .
+ $this->addRow( wfMsg( 'localtime' ), $nowlocal ) .
+ $this->addRow(
+ '<label for="wpHourDiff">' . wfMsg( 'timezoneoffset' ) . '</label>',
+ "<input type='text' name='wpHourDiff' id='wpHourDiff' value=\"" . htmlspecialchars( $this->mHourDiff ) . "\" size='6' />"
+ ) . "<tr><td colspan='2'>
+ <input type='button' value=\"" . wfMsg( 'guesstimezone' ) ."\"
+ onclick='javascript:guessTimezone()' id='guesstimezonebutton' style='display:none;' />
+ </td></tr></table><div class='prefsectiontip'>¹" . wfMsg( 'timezonetext' ) . "</div></fieldset>
+ </fieldset>\n\n" );
+
+ # Editing
+ #
+ global $wgLivePreview, $wgUseRCPatrol;
+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'textboxsize' ) . '</legend>
+ <div>' .
+ wfInputLabel( wfMsg( 'rows' ), 'wpRows', 'wpRows', 3, $this->mRows ) .
+ ' ' .
+ wfInputLabel( wfMsg( 'columns' ), 'wpCols', 'wpCols', 3, $this->mCols ) .
+ "</div>" .
+ $this->getToggles( array(
+ 'editsection',
+ 'editsectiononrightclick',
+ 'editondblclick',
+ 'editwidth',
+ 'showtoolbar',
+ 'previewonfirst',
+ 'previewontop',
+ 'minordefault',
+ 'externaleditor',
+ 'externaldiff',
+ $wgLivePreview ? 'uselivepreview' : false,
+ 'forceeditsummary',
+ ) ) . '</fieldset>'
+ );
+
+ $wgOut->addHTML( '<fieldset><legend>' . htmlspecialchars(wfMsg('prefs-rc')) . '</legend>' .
+ wfInputLabel( wfMsg( 'recentchangescount' ),
+ 'wpRecent', 'wpRecent', 3, $this->mRecent ) .
+ $this->getToggles( array(
+ 'hideminor',
+ $wgRCShowWatchingUsers ? 'shownumberswatching' : false,
+ 'usenewrc' )
+ ) . '</fieldset>'
+ );
+
+ # Watchlist
+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-watchlist' ) . '</legend>' );
+
+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-days' ), 'wpWatchlistDays', 'wpWatchlistDays', 3, $this->mWatchlistDays ) );
+ $wgOut->addHtml( '<br /><br />' );
+
+ $wgOut->addHtml( $this->getToggle( 'extendwatchlist' ) );
+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-edits' ), 'wpWatchlistEdits', 'wpWatchlistEdits', 3, $this->mWatchlistEdits ) );
+ $wgOut->addHtml( '<br /><br />' );
+
+ $wgOut->addHtml( $this->getToggles( array( 'watchlisthideown', 'watchlisthidebots', 'watchlisthideminor' ) ) );
+
+ if( $wgUser->isAllowed( 'createpage' ) || $wgUser->isAllowed( 'createtalk' ) )
+ $wgOut->addHtml( $this->getToggle( 'watchcreations' ) );
+ foreach( array( 'edit' => 'watchdefault', 'move' => 'watchmoves', 'delete' => 'watchdeletion' ) as $action => $toggle ) {
+ if( $wgUser->isAllowed( $action ) )
+ $wgOut->addHtml( $this->getToggle( $toggle ) );
+ }
+ $this->mUsedToggles['watchcreations'] = true;
+ $this->mUsedToggles['watchdefault'] = true;
+ $this->mUsedToggles['watchmoves'] = true;
+ $this->mUsedToggles['watchdeletion'] = true;
+
+ $wgOut->addHtml( '</fieldset>' );
+
+ # Search
+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'searchresultshead' ) . '</legend><table>' .
+ $this->addRow(
+ wfLabel( wfMsg( 'resultsperpage' ), 'wpSearch' ),
+ wfInput( 'wpSearch', 4, $this->mSearch, array( 'id' => 'wpSearch' ) )
+ ) .
+ $this->addRow(
+ wfLabel( wfMsg( 'contextlines' ), 'wpSearchLines' ),
+ wfInput( 'wpSearchLines', 4, $this->mSearchLines, array( 'id' => 'wpSearchLines' ) )
+ ) .
+ $this->addRow(
+ wfLabel( wfMsg( 'contextchars' ), 'wpSearchChars' ),
+ wfInput( 'wpSearchChars', 4, $this->mSearchChars, array( 'id' => 'wpSearchChars' ) )
+ ) .
+ "</table><fieldset><legend>" . wfMsg( 'defaultns' ) . "</legend>$ps</fieldset></fieldset>" );
+
+ # Misc
+ #
+ $wgOut->addHTML('<fieldset><legend>' . wfMsg('prefs-misc') . '</legend>');
+ $wgOut->addHTML( wfInputLabel( wfMsg( 'stubthreshold' ),
+ 'wpStubs', 'wpStubs', 6, $this->mStubs ) );
+ $msgUnderline = htmlspecialchars( wfMsg ( 'tog-underline' ) );
+ $msgUnderlinenever = htmlspecialchars( wfMsg ( 'underline-never' ) );
+ $msgUnderlinealways = htmlspecialchars( wfMsg ( 'underline-always' ) );
+ $msgUnderlinedefault = htmlspecialchars( wfMsg ( 'underline-default' ) );
+ $uopt = $wgUser->getOption("underline");
+ $s0 = $uopt == 0 ? ' selected="selected"' : '';
+ $s1 = $uopt == 1 ? ' selected="selected"' : '';
+ $s2 = $uopt == 2 ? ' selected="selected"' : '';
+ $wgOut->addHTML("
+<div class='toggle'><p><label for='wpOpunderline'>$msgUnderline</label>
+<select name='wpOpunderline' id='wpOpunderline'>
+<option value=\"0\"$s0>$msgUnderlinenever</option>
+<option value=\"1\"$s1>$msgUnderlinealways</option>
+<option value=\"2\"$s2>$msgUnderlinedefault</option>
+</select></p></div>");
+
+ foreach ( $togs as $tname ) {
+ if( !array_key_exists( $tname, $this->mUsedToggles ) ) {
+ $wgOut->addHTML( $this->getToggle( $tname ) );
+ }
+ }
+ $wgOut->addHTML( '</fieldset>' );
+
+ $token = $wgUser->editToken();
+ $wgOut->addHTML( "
+ <div id='prefsubmit'>
+ <div>
+ <input type='submit' name='wpSaveprefs' class='btnSavePrefs' value=\"" . wfMsgHtml( 'saveprefs' ) . "\" accesskey=\"".
+ wfMsgHtml('accesskey-save')."\" title=\"".wfMsgHtml('tooltip-save')."\" />
+ <input type='submit' name='wpReset' value=\"" . wfMsgHtml( 'resetprefs' ) . "\" />
+ </div>
+
+ </div>
+
+ <input type='hidden' name='wpEditToken' value='{$token}' />
+ </div></form>\n" );
+
+ $wgOut->addWikiText( '<div class="prefcache">' . wfMsg('clearyourcache') . '</div>' );
+
+ }
+}
+?>
diff --git a/includes/SpecialPrefixindex.php b/includes/SpecialPrefixindex.php
new file mode 100644
index 000000000000..ce296b4b07fe
--- /dev/null
+++ b/includes/SpecialPrefixindex.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+require_once 'SpecialAllpages.php';
+
+/**
+ * Entry point : initialise variables and call subfunctions.
+ * @param $par String: becomes "FOO" when called like Special:Prefixindex/FOO (default NULL)
+ * @param $specialPage SpecialPage object.
+ */
+function wfSpecialPrefixIndex( $par=NULL, $specialPage ) {
+ global $wgRequest, $wgOut, $wgContLang;
+
+ # GET values
+ $from = $wgRequest->getVal( 'from' );
+ $prefix = $wgRequest->getVal( 'prefix' );
+ $namespace = $wgRequest->getInt( 'namespace' );
+
+ $namespaces = $wgContLang->getNamespaces();
+
+ $indexPage = new SpecialPrefixIndex();
+
+ if( !in_array($namespace, array_keys($namespaces)) )
+ $namespace = 0;
+
+ $wgOut->setPagetitle( $namespace > 0 ?
+ wfMsg( 'allinnamespace', str_replace( '_', ' ', $namespaces[$namespace] ) ) :
+ wfMsg( 'allarticles' )
+ );
+
+
+
+ if ( isset($par) ) {
+ $indexPage->showChunk( $namespace, $par, $specialPage->including(), $from );
+ } elseif ( isset($prefix) ) {
+ $indexPage->showChunk( $namespace, $prefix, $specialPage->including(), $from );
+ } elseif ( isset($from) ) {
+ $indexPage->showChunk( $namespace, $from, $specialPage->including(), $from );
+ } else {
+ $wgOut->addHtml($indexPage->namespaceForm ( $namespace, null ));
+ }
+}
+
+class SpecialPrefixindex extends SpecialAllpages {
+ var $maxPerPage=960;
+ var $topLevelMax=50;
+ var $name='Prefixindex';
+ # Determines, which message describes the input field 'nsfrom', used in function namespaceForm (see superclass SpecialAllpages)
+ var $nsfromMsg='allpagesprefix';
+
+/**
+ * @param integer $namespace (Default NS_MAIN)
+ * @param string $from list all pages from this name (default FALSE)
+ */
+function showChunk( $namespace = NS_MAIN, $prefix, $including = false, $from = null ) {
+ global $wgOut, $wgUser, $wgContLang;
+
+ $fname = 'indexShowChunk';
+
+ $sk = $wgUser->getSkin();
+
+ if (!isset($from)) $from = $prefix;
+
+ $fromList = $this->getNamespaceKeyAndText($namespace, $from);
+ $prefixList = $this->getNamespaceKeyAndText($namespace, $prefix);
+
+ if ( !$prefixList || !$fromList ) {
+ $out = wfMsgWikiHtml( 'allpagesbadtitle' );
+ } else {
+ list( $namespace, $prefixKey, $prefix ) = $prefixList;
+ list( $fromNs, $fromKey, $from ) = $fromList;
+
+ ### FIXME: should complain if $fromNs != $namespace
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $res = $dbr->select( 'page',
+ array( 'page_namespace', 'page_title', 'page_is_redirect' ),
+ array(
+ 'page_namespace' => $namespace,
+ 'page_title LIKE \'' . $dbr->escapeLike( $prefixKey ) .'%\'',
+ 'page_title >= ' . $dbr->addQuotes( $fromKey ),
+ ),
+ $fname,
+ array(
+ 'ORDER BY' => 'page_title',
+ 'LIMIT' => $this->maxPerPage + 1,
+ 'USE INDEX' => 'name_title',
+ )
+ );
+
+ ### FIXME: side link to previous
+
+ $n = 0;
+ $out = '<table style="background: inherit;" border="0" width="100%">';
+
+ while( ($n < $this->maxPerPage) && ($s = $dbr->fetchObject( $res )) ) {
+ $t = Title::makeTitle( $s->page_namespace, $s->page_title );
+ if( $t ) {
+ $link = ($s->page_is_redirect ? '<div class="allpagesredirect">' : '' ) .
+ $sk->makeKnownLinkObj( $t, htmlspecialchars( $t->getText() ), false, false ) .
+ ($s->page_is_redirect ? '</div>' : '' );
+ } else {
+ $link = '[[' . htmlspecialchars( $s->page_title ) . ']]';
+ }
+ if( $n % 3 == 0 ) {
+ $out .= '<tr>';
+ }
+ $out .= "<td>$link</td>";
+ $n++;
+ if( $n % 3 == 0 ) {
+ $out .= '</tr>';
+ }
+ }
+ if( ($n % 3) != 0 ) {
+ $out .= '</tr>';
+ }
+ $out .= '</table>';
+ }
+
+ if ( $including ) {
+ $out2 = '';
+ } else {
+ $nsForm = $this->namespaceForm ( $namespace, $prefix );
+ $out2 = '<table style="background: inherit;" width="100%" cellpadding="0" cellspacing="0" border="0">';
+ $out2 .= '<tr valign="top"><td align="left">' . $nsForm;
+ $out2 .= '</td><td align="right" style="font-size: smaller; margin-bottom: 1em;">' .
+ $sk->makeKnownLink( $wgContLang->specialPage( $this->name ),
+ wfMsg ( 'allpages' ) );
+ if ( isset($dbr) && $dbr && ($n == $this->maxPerPage) && ($s = $dbr->fetchObject( $res )) ) {
+ $namespaceparam = $namespace ? "&namespace=$namespace" : "";
+ $out2 .= " | " . $sk->makeKnownLink(
+ $wgContLang->specialPage( $this->name ),
+ wfMsg ( 'nextpage', $s->page_title ),
+ "from=" . wfUrlEncode ( $s->page_title ) .
+ "&prefix=" . wfUrlEncode ( $prefix ) . $namespaceparam );
+ }
+ $out2 .= "</td></tr></table><hr />";
+ }
+
+ $wgOut->addHtml( $out2 . $out );
+}
+}
+
+?>
diff --git a/includes/SpecialRandompage.php b/includes/SpecialRandompage.php
new file mode 100644
index 000000000000..2cd31eb57bba
--- /dev/null
+++ b/includes/SpecialRandompage.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Constructor
+ *
+ * @param $par The namespace to get a random page from (default NS_MAIN),
+ * used as e.g. Special:Randompage/Category
+ */
+function wfSpecialRandompage( $par = NS_MAIN ) {
+ global $wgOut, $wgExtraRandompageSQL;
+ $fname = 'wfSpecialRandompage';
+
+ # Determine namespace
+ $t = Title::newFromText ( $par . ":Dummy" ) ;
+ $namespace = $t->getNamespace () ;
+
+ # NOTE! We use a literal constant in the SQL instead of the RAND()
+ # function because RAND() will return a different value for every row
+ # in the table. That's both very slow and returns results heavily
+ # biased towards low values, as rows later in the table will likely
+ # never be reached for comparison.
+ #
+ # Using a literal constant means the whole thing gets optimized on
+ # the index, and the comparison is both fast and fair.
+
+ # interpolation and sprintf() can muck up with locale-specific decimal separator
+ $randstr = wfRandom();
+
+ $db =& wfGetDB( DB_SLAVE );
+ $use_index = $db->useIndexClause( 'page_random' );
+ $page = $db->tableName( 'page' );
+
+ $extra = $wgExtraRandompageSQL ? "AND ($wgExtraRandompageSQL)" : '';
+ $sql = "SELECT page_id,page_title
+ FROM $page $use_index
+ WHERE page_namespace=$namespace AND page_is_redirect=0 $extra
+ AND page_random>$randstr
+ ORDER BY page_random";
+ $sql = $db->limitResult($sql, 1, 0);
+ $res = $db->query( $sql, $fname );
+
+ $title = null;
+ if( $s = $db->fetchObject( $res ) ) {
+ $title =& Title::makeTitle( $namespace, $s->page_title );
+ }
+ if( is_null( $title ) ) {
+ # That's not supposed to happen :)
+ $title = Title::newMainPage();
+ }
+ $wgOut->reportTime(); # for logfile
+ $wgOut->redirect( $title->getFullUrl() );
+}
+
+?>
diff --git a/includes/SpecialRandomredirect.php b/includes/SpecialRandomredirect.php
new file mode 100644
index 000000000000..2cb2498b1eba
--- /dev/null
+++ b/includes/SpecialRandomredirect.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * Special page to direct the user to a random redirect page (minus the second redirect)
+ *
+ * @package MediaWiki
+ * @subpackage Special pages
+ * @author Rob Church <robchur@gmail.com>
+ * @licence GNU General Public Licence 2.0 or later
+ */
+
+/**
+ * Main execution point
+ * @param $par Namespace to select the redirect from
+ */
+function wfSpecialRandomredirect( $par = NULL ) {
+ global $wgOut, $wgExtraRandompageSQL, $wgContLang;
+ $fname = 'wfSpecialRandomredirect';
+
+ # Validate the namespace
+ $namespace = $wgContLang->getNsIndex( $par );
+ if( $namespace === false || $namespace < NS_MAIN )
+ $namespace = NS_MAIN;
+
+ # Same logic as RandomPage
+ $randstr = wfRandom();
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $use_index = $dbr->useIndexClause( 'page_random' );
+ $page = $dbr->tableName( 'page' );
+
+ $extra = $wgExtraRandompageSQL ? "AND ($wgExtraRandompageSQL)" : '';
+ $sql = "SELECT page_id,page_title
+ FROM $page $use_index
+ WHERE page_namespace = $namespace AND page_is_redirect = 1 $extra
+ AND page_random > $randstr
+ ORDER BY page_random";
+
+ $sql = $dbr->limitResult( $sql, 1, 0 );
+ $res = $dbr->query( $sql, $fname );
+
+ $title = NULL;
+ if( $row = $dbr->fetchObject( $res ) )
+ $title = Title::makeTitleSafe( $namespace, $row->page_title );
+
+ # Catch dud titles and return to the main page
+ if( is_null( $title ) )
+ $title = Title::newMainPage();
+
+ $wgOut->reportTime();
+ $wgOut->redirect( $title->getFullUrl( 'redirect=no' ) );
+}
+
+?>
diff --git a/includes/SpecialRecentchanges.php b/includes/SpecialRecentchanges.php
new file mode 100644
index 000000000000..3b8d69f2b928
--- /dev/null
+++ b/includes/SpecialRecentchanges.php
@@ -0,0 +1,706 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+require_once( 'ChangesList.php' );
+
+/**
+ * Constructor
+ */
+function wfSpecialRecentchanges( $par, $specialPage ) {
+ global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol;
+ global $wgRCShowWatchingUsers, $wgShowUpdatedMarker;
+ global $wgAllowCategorizedRecentChanges ;
+ $fname = 'wfSpecialRecentchanges';
+
+ # Get query parameters
+ $feedFormat = $wgRequest->getVal( 'feed' );
+
+ /* Checkbox values can't be true be default, because
+ * we cannot differentiate between unset and not set at all
+ */
+ $defaults = array(
+ /* int */ 'days' => $wgUser->getDefaultOption('rcdays'),
+ /* int */ 'limit' => $wgUser->getDefaultOption('rclimit'),
+ /* bool */ 'hideminor' => false,
+ /* bool */ 'hidebots' => true,
+ /* bool */ 'hideanons' => false,
+ /* bool */ 'hideliu' => false,
+ /* bool */ 'hidepatrolled' => false,
+ /* bool */ 'hidemyself' => false,
+ /* text */ 'from' => '',
+ /* text */ 'namespace' => null,
+ /* bool */ 'invert' => false,
+ /* bool */ 'categories_any' => false,
+ );
+
+ extract($defaults);
+
+
+ $days = $wgUser->getOption( 'rcdays', $defaults['days']);
+ $days = $wgRequest->getInt( 'days', $days );
+
+ $limit = $wgUser->getOption( 'rclimit', $defaults['limit'] );
+
+ # list( $limit, $offset ) = wfCheckLimits( 100, 'rclimit' );
+ $limit = $wgRequest->getInt( 'limit', $limit );
+
+ /* order of selection: url > preferences > default */
+ $hideminor = $wgRequest->getBool( 'hideminor', $wgUser->getOption( 'hideminor') ? true : $defaults['hideminor'] );
+
+ # As a feed, use limited settings only
+ if( $feedFormat ) {
+ global $wgFeedLimit;
+ if( $limit > $wgFeedLimit ) {
+ $options['limit'] = $wgFeedLimit;
+ }
+
+ } else {
+
+ $namespace = $wgRequest->getIntOrNull( 'namespace' );
+ $invert = $wgRequest->getBool( 'invert', $defaults['invert'] );
+ $hidebots = $wgRequest->getBool( 'hidebots', $defaults['hidebots'] );
+ $hideanons = $wgRequest->getBool( 'hideanons', $defaults['hideanons'] );
+ $hideliu = $wgRequest->getBool( 'hideliu', $defaults['hideliu'] );
+ $hidepatrolled = $wgRequest->getBool( 'hidepatrolled', $defaults['hidepatrolled'] );
+ $hidemyself = $wgRequest->getBool ( 'hidemyself', $defaults['hidemyself'] );
+ $from = $wgRequest->getVal( 'from', $defaults['from'] );
+
+ # Get query parameters from path
+ if( $par ) {
+ $bits = preg_split( '/\s*,\s*/', trim( $par ) );
+ foreach ( $bits as $bit ) {
+ if ( 'hidebots' == $bit ) $hidebots = 1;
+ if ( 'bots' == $bit ) $hidebots = 0;
+ if ( 'hideminor' == $bit ) $hideminor = 1;
+ if ( 'minor' == $bit ) $hideminor = 0;
+ if ( 'hideliu' == $bit ) $hideliu = 1;
+ if ( 'hidepatrolled' == $bit ) $hidepatrolled = 1;
+ if ( 'hideanons' == $bit ) $hideanons = 1;
+ if ( 'hidemyself' == $bit ) $hidemyself = 1;
+
+ if ( is_numeric( $bit ) ) {
+ $limit = $bit;
+ }
+
+ $m = array();
+ if ( preg_match( '/^limit=(\d+)$/', $bit, $m ) ) {
+ $limit = $m[1];
+ }
+
+ if ( preg_match( '/^days=(\d+)$/', $bit, $m ) ) {
+ $days = $m[1];
+ }
+ }
+ }
+ }
+
+ if ( $limit < 0 || $limit > 5000 ) $limit = $defaults['limit'];
+
+
+ # Database connection and caching
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $recentchanges, $watchlist ) = $dbr->tableNamesN( 'recentchanges', 'watchlist' );
+
+
+ $cutoff_unixtime = time() - ( $days * 86400 );
+ $cutoff_unixtime = $cutoff_unixtime - ($cutoff_unixtime % 86400);
+ $cutoff = $dbr->timestamp( $cutoff_unixtime );
+ if(preg_match('/^[0-9]{14}$/', $from) and $from > wfTimestamp(TS_MW,$cutoff)) {
+ $cutoff = $dbr->timestamp($from);
+ } else {
+ $from = $defaults['from'];
+ }
+
+ # 10 seconds server-side caching max
+ $wgOut->setSquidMaxage( 10 );
+
+ # Get last modified date, for client caching
+ # Don't use this if we are using the patrol feature, patrol changes don't update the timestamp
+ $lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, $fname );
+ if ( $feedFormat || !$wgUseRCPatrol ) {
+ if( $lastmod && $wgOut->checkLastModified( $lastmod ) ){
+ # Client cache fresh and headers sent, nothing more to do.
+ return;
+ }
+ }
+
+ # It makes no sense to hide both anons and logged-in users
+ # Where this occurs, force anons to be shown
+ if( $hideanons && $hideliu )
+ $hideanons = false;
+
+ # Form WHERE fragments for all the options
+ $hidem = $hideminor ? 'AND rc_minor = 0' : '';
+ $hidem .= $hidebots ? ' AND rc_bot = 0' : '';
+ $hidem .= $hideliu ? ' AND rc_user = 0' : '';
+ $hidem .= ( $wgUseRCPatrol && $hidepatrolled ) ? ' AND rc_patrolled = 0' : '';
+ $hidem .= $hideanons ? ' AND rc_user != 0' : '';
+
+ if( $hidemyself ) {
+ if( $wgUser->getID() ) {
+ $hidem .= ' AND rc_user != ' . $wgUser->getID();
+ } else {
+ $hidem .= ' AND rc_user_text != ' . $dbr->addQuotes( $wgUser->getName() );
+ }
+ }
+
+ # Namespace filtering
+ $hidem .= is_null( $namespace ) ? '' : ' AND rc_namespace' . ($invert ? '!=' : '=') . $namespace;
+
+ // This is the big thing!
+
+ $uid = $wgUser->getID();
+
+ // Perform query
+ $forceclause = $dbr->useIndexClause("rc_timestamp");
+ $sql2 = "SELECT * FROM $recentchanges $forceclause".
+ ($uid ? "LEFT OUTER JOIN $watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace " : "") .
+ "WHERE rc_timestamp >= '{$cutoff}' {$hidem} " .
+ "ORDER BY rc_timestamp DESC";
+ $sql2 = $dbr->limitResult($sql2, $limit, 0);
+ $res = $dbr->query( $sql2, $fname );
+
+ // Fetch results, prepare a batch link existence check query
+ $rows = array();
+ $batch = new LinkBatch;
+ while( $row = $dbr->fetchObject( $res ) ){
+ $rows[] = $row;
+ if ( !$feedFormat ) {
+ // User page link
+ $title = Title::makeTitleSafe( NS_USER, $row->rc_user_text );
+ $batch->addObj( $title );
+
+ // User talk
+ $title = Title::makeTitleSafe( NS_USER_TALK, $row->rc_user_text );
+ $batch->addObj( $title );
+ }
+
+ }
+ $dbr->freeResult( $res );
+
+ if( $feedFormat ) {
+ rcOutputFeed( $rows, $feedFormat, $limit, $hideminor, $lastmod );
+ } else {
+
+ # Web output...
+
+ // Run existence checks
+ $batch->execute();
+ $any = $wgRequest->getBool( 'categories_any', $defaults['categories_any']);
+
+ // Output header
+ if ( !$specialPage->including() ) {
+ $wgOut->addWikiText( wfMsgForContentNoTrans( "recentchangestext" ) );
+
+ // Dump everything here
+ $nondefaults = array();
+
+ wfAppendToArrayIfNotDefault( 'days', $days, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'limit', $limit , $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'hideminor', $hideminor, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'hidebots', $hidebots, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'hideanons', $hideanons, $defaults, $nondefaults );
+ wfAppendToArrayIfNotDefault( 'hideliu', $hideliu, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'hidepatrolled', $hidepatrolled, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'hidemyself', $hidemyself, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'from', $from, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'namespace', $namespace, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'invert', $invert, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'categories_any', $any, $defaults, $nondefaults);
+
+ // Add end of the texts
+ $wgOut->addHTML( '<div class="rcoptions">' . rcOptionsPanel( $defaults, $nondefaults ) . "\n" );
+ $wgOut->addHTML( rcNamespaceForm( $namespace, $invert, $nondefaults, $any ) . '</div>'."\n");
+ }
+
+ // And now for the content
+ $wgOut->setSyndicated( true );
+
+ $list = ChangesList::newFromUser( $wgUser );
+
+ if ( $wgAllowCategorizedRecentChanges ) {
+ $categories = trim ( $wgRequest->getVal ( 'categories' , "" ) ) ;
+ $categories = str_replace ( "|" , "\n" , $categories ) ;
+ $categories = explode ( "\n" , $categories ) ;
+ rcFilterByCategories ( $rows , $categories , $any ) ;
+ }
+
+ $s = $list->beginRecentChangesList();
+ $counter = 1;
+ foreach( $rows as $obj ){
+ if( $limit == 0) {
+ break;
+ }
+
+ if ( ! ( $hideminor && $obj->rc_minor ) &&
+ ! ( $hidepatrolled && $obj->rc_patrolled ) ) {
+ $rc = RecentChange::newFromRow( $obj );
+ $rc->counter = $counter++;
+
+ if ($wgShowUpdatedMarker
+ && !empty( $obj->wl_notificationtimestamp )
+ && ($obj->rc_timestamp >= $obj->wl_notificationtimestamp)) {
+ $rc->notificationtimestamp = true;
+ } else {
+ $rc->notificationtimestamp = false;
+ }
+
+ if ($wgRCShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' )) {
+ $sql3 = "SELECT COUNT(*) AS n FROM $watchlist WHERE wl_title='" . $dbr->strencode($obj->rc_title) ."' AND wl_namespace=$obj->rc_namespace" ;
+ $res3 = $dbr->query( $sql3, 'wfSpecialRecentChanges');
+ $x = $dbr->fetchObject( $res3 );
+ $rc->numberofWatchingusers = $x->n;
+ } else {
+ $rc->numberofWatchingusers = 0;
+ }
+ $s .= $list->recentChangesLine( $rc, !empty( $obj->wl_user ) );
+ --$limit;
+ }
+ }
+ $s .= $list->endRecentChangesList();
+ $wgOut->addHTML( $s );
+ }
+}
+
+function rcFilterByCategories ( &$rows , $categories , $any ) {
+ require_once ( 'Categoryfinder.php' ) ;
+
+ # Filter categories
+ $cats = array () ;
+ foreach ( $categories AS $cat ) {
+ $cat = trim ( $cat ) ;
+ if ( $cat == "" ) continue ;
+ $cats[] = $cat ;
+ }
+
+ # Filter articles
+ $articles = array () ;
+ $a2r = array () ;
+ foreach ( $rows AS $k => $r ) {
+ $nt = Title::newFromText ( $r->rc_title , $r->rc_namespace ) ;
+ $id = $nt->getArticleID() ;
+ if ( $id == 0 ) continue ; # Page might have been deleted...
+ if ( !in_array ( $id , $articles ) ) {
+ $articles[] = $id ;
+ }
+ if ( !isset ( $a2r[$id] ) ) {
+ $a2r[$id] = array() ;
+ }
+ $a2r[$id][] = $k ;
+ }
+
+ # Shortcut?
+ if ( count ( $articles ) == 0 OR count ( $cats ) == 0 )
+ return ;
+
+ # Look up
+ $c = new Categoryfinder ;
+ $c->seed ( $articles , $cats , $any ? "OR" : "AND" ) ;
+ $match = $c->run () ;
+
+ # Filter
+ $newrows = array () ;
+ foreach ( $match AS $id ) {
+ foreach ( $a2r[$id] AS $rev ) {
+ $k = $rev ;
+ $newrows[$k] = $rows[$k] ;
+ }
+ }
+ $rows = $newrows ;
+}
+
+function rcOutputFeed( $rows, $feedFormat, $limit, $hideminor, $lastmod ) {
+ global $messageMemc, $wgFeedCacheTimeout;
+ global $wgFeedClasses, $wgTitle, $wgSitename, $wgContLanguageCode;
+
+ if( !isset( $wgFeedClasses[$feedFormat] ) ) {
+ wfHttpError( 500, "Internal Server Error", "Unsupported feed type." );
+ return false;
+ }
+
+ $timekey = wfMemcKey( 'rcfeed', $feedFormat, 'timestamp' );
+ $key = wfMemcKey( 'rcfeed', $feedFormat, 'limit', $limit, 'minor', $hideminor );
+
+ $feedTitle = $wgSitename . ' - ' . wfMsgForContent( 'recentchanges' ) .
+ ' [' . $wgContLanguageCode . ']';
+ $feed = new $wgFeedClasses[$feedFormat](
+ $feedTitle,
+ htmlspecialchars( wfMsgForContent( 'recentchanges-feed-description' ) ),
+ $wgTitle->getFullUrl() );
+
+ /**
+ * Bumping around loading up diffs can be pretty slow, so where
+ * possible we want to cache the feed output so the next visitor
+ * gets it quick too.
+ */
+ $cachedFeed = false;
+ if( ( $wgFeedCacheTimeout > 0 ) && ( $feedLastmod = $messageMemc->get( $timekey ) ) ) {
+ /**
+ * If the cached feed was rendered very recently, we may
+ * go ahead and use it even if there have been edits made
+ * since it was rendered. This keeps a swarm of requests
+ * from being too bad on a super-frequently edited wiki.
+ */
+ if( time() - wfTimestamp( TS_UNIX, $feedLastmod )
+ < $wgFeedCacheTimeout
+ || wfTimestamp( TS_UNIX, $feedLastmod )
+ > wfTimestamp( TS_UNIX, $lastmod ) ) {
+ wfDebug( "RC: loading feed from cache ($key; $feedLastmod; $lastmod)...\n" );
+ $cachedFeed = $messageMemc->get( $key );
+ } else {
+ wfDebug( "RC: cached feed timestamp check failed ($feedLastmod; $lastmod)\n" );
+ }
+ }
+ if( is_string( $cachedFeed ) ) {
+ wfDebug( "RC: Outputting cached feed\n" );
+ $feed->httpHeaders();
+ echo $cachedFeed;
+ } else {
+ wfDebug( "RC: rendering new feed and caching it\n" );
+ ob_start();
+ rcDoOutputFeed( $rows, $feed );
+ $cachedFeed = ob_get_contents();
+ ob_end_flush();
+
+ $expire = 3600 * 24; # One day
+ $messageMemc->set( $key, $cachedFeed );
+ $messageMemc->set( $timekey, wfTimestamp( TS_MW ), $expire );
+ }
+ return true;
+}
+
+function rcDoOutputFeed( $rows, &$feed ) {
+ $fname = 'rcDoOutputFeed';
+ wfProfileIn( $fname );
+
+ $feed->outHeader();
+
+ # Merge adjacent edits by one user
+ $sorted = array();
+ $n = 0;
+ foreach( $rows as $obj ) {
+ if( $n > 0 &&
+ $obj->rc_namespace >= 0 &&
+ $obj->rc_cur_id == $sorted[$n-1]->rc_cur_id &&
+ $obj->rc_user_text == $sorted[$n-1]->rc_user_text ) {
+ $sorted[$n-1]->rc_last_oldid = $obj->rc_last_oldid;
+ } else {
+ $sorted[$n] = $obj;
+ $n++;
+ }
+ }
+
+ foreach( $sorted as $obj ) {
+ $title = Title::makeTitle( $obj->rc_namespace, $obj->rc_title );
+ $talkpage = $title->getTalkPage();
+ $item = new FeedItem(
+ $title->getPrefixedText(),
+ rcFormatDiff( $obj ),
+ $title->getFullURL(),
+ $obj->rc_timestamp,
+ $obj->rc_user_text,
+ $talkpage->getFullURL()
+ );
+ $feed->outItem( $item );
+ }
+ $feed->outFooter();
+ wfProfileOut( $fname );
+}
+
+/**
+ *
+ */
+function rcCountLink( $lim, $d, $page='Recentchanges', $more='' ) {
+ global $wgUser, $wgLang, $wgContLang;
+ $sk = $wgUser->getSkin();
+ $s = $sk->makeKnownLink( $wgContLang->specialPage( $page ),
+ ($lim ? $wgLang->formatNum( "{$lim}" ) : wfMsg( 'recentchangesall' ) ), "{$more}" .
+ ($d ? "days={$d}&" : '') . 'limit='.$lim );
+ return $s;
+}
+
+/**
+ *
+ */
+function rcDaysLink( $lim, $d, $page='Recentchanges', $more='' ) {
+ global $wgUser, $wgLang, $wgContLang;
+ $sk = $wgUser->getSkin();
+ $s = $sk->makeKnownLink( $wgContLang->specialPage( $page ),
+ ($d ? $wgLang->formatNum( "{$d}" ) : wfMsg( 'recentchangesall' ) ), $more.'days='.$d .
+ ($lim ? '&limit='.$lim : '') );
+ return $s;
+}
+
+/**
+ * Used by Recentchangeslinked
+ */
+function rcDayLimitLinks( $days, $limit, $page='Recentchanges', $more='', $doall = false, $minorLink = '',
+ $botLink = '', $liuLink = '', $patrLink = '', $myselfLink = '' ) {
+ if ($more != '') $more .= '&';
+ $cl = rcCountLink( 50, $days, $page, $more ) . ' | ' .
+ rcCountLink( 100, $days, $page, $more ) . ' | ' .
+ rcCountLink( 250, $days, $page, $more ) . ' | ' .
+ rcCountLink( 500, $days, $page, $more ) .
+ ( $doall ? ( ' | ' . rcCountLink( 0, $days, $page, $more ) ) : '' );
+ $dl = rcDaysLink( $limit, 1, $page, $more ) . ' | ' .
+ rcDaysLink( $limit, 3, $page, $more ) . ' | ' .
+ rcDaysLink( $limit, 7, $page, $more ) . ' | ' .
+ rcDaysLink( $limit, 14, $page, $more ) . ' | ' .
+ rcDaysLink( $limit, 30, $page, $more ) .
+ ( $doall ? ( ' | ' . rcDaysLink( $limit, 0, $page, $more ) ) : '' );
+
+ $linkParts = array( 'minorLink' => 'minor', 'botLink' => 'bots', 'liuLink' => 'liu', 'patrLink' => 'patr', 'myselfLink' => 'mine' );
+ foreach( $linkParts as $linkVar => $linkMsg ) {
+ if( $$linkVar != '' )
+ $links[] = wfMsgHtml( 'rcshowhide' . $linkMsg, $$linkVar );
+ }
+
+ $shm = implode( ' | ', $links );
+ $note = wfMsg( 'rclinks', $cl, $dl, $shm );
+ return $note;
+}
+
+
+/**
+ * Makes change an option link which carries all the other options
+ * @param $title @see Title
+ * @param $override
+ * @param $options
+ */
+function makeOptionsLink( $title, $override, $options ) {
+ global $wgUser, $wgContLang;
+ $sk = $wgUser->getSkin();
+ return $sk->makeKnownLink( $wgContLang->specialPage( 'Recentchanges' ),
+ htmlspecialchars( $title ), wfArrayToCGI( $override, $options ) );
+}
+
+/**
+ * Creates the options panel.
+ * @param $defaults
+ * @param $nondefaults
+ */
+function rcOptionsPanel( $defaults, $nondefaults ) {
+ global $wgLang, $wgUseRCPatrol;
+
+ $options = $nondefaults + $defaults;
+
+ if( $options['from'] )
+ $note = wfMsgExt( 'rcnotefrom', array( 'parseinline' ),
+ $wgLang->formatNum( $options['limit'] ),
+ $wgLang->timeanddate( $options['from'], true ) );
+ else
+ $note = wfMsgExt( 'rcnote', array( 'parseinline' ),
+ $wgLang->formatNum( $options['limit'] ),
+ $wgLang->formatNum( $options['days'] ),
+ $wgLang->timeAndDate( wfTimestampNow(), true ) );
+
+ // limit links
+ $options_limit = array(50, 100, 250, 500);
+ foreach( $options_limit as $value ) {
+ $cl[] = makeOptionsLink( $wgLang->formatNum( $value ),
+ array( 'limit' => $value ), $nondefaults) ;
+ }
+ $cl = implode( ' | ', $cl);
+
+ // day links, reset 'from' to none
+ $options_days = array(1, 3, 7, 14, 30);
+ foreach( $options_days as $value ) {
+ $dl[] = makeOptionsLink( $wgLang->formatNum( $value ),
+ array( 'days' => $value, 'from' => '' ), $nondefaults) ;
+ }
+ $dl = implode( ' | ', $dl);
+
+
+ // show/hide links
+ $showhide = array( wfMsg( 'show' ), wfMsg( 'hide' ));
+ $minorLink = makeOptionsLink( $showhide[1-$options['hideminor']],
+ array( 'hideminor' => 1-$options['hideminor'] ), $nondefaults);
+ $botLink = makeOptionsLink( $showhide[1-$options['hidebots']],
+ array( 'hidebots' => 1-$options['hidebots'] ), $nondefaults);
+ $anonsLink = makeOptionsLink( $showhide[ 1 - $options['hideanons'] ],
+ array( 'hideanons' => 1 - $options['hideanons'] ), $nondefaults );
+ $liuLink = makeOptionsLink( $showhide[1-$options['hideliu']],
+ array( 'hideliu' => 1-$options['hideliu'] ), $nondefaults);
+ $patrLink = makeOptionsLink( $showhide[1-$options['hidepatrolled']],
+ array( 'hidepatrolled' => 1-$options['hidepatrolled'] ), $nondefaults);
+ $myselfLink = makeOptionsLink( $showhide[1-$options['hidemyself']],
+ array( 'hidemyself' => 1-$options['hidemyself'] ), $nondefaults);
+
+ $links[] = wfMsgHtml( 'rcshowhideminor', $minorLink );
+ $links[] = wfMsgHtml( 'rcshowhidebots', $botLink );
+ $links[] = wfMsgHtml( 'rcshowhideanons', $anonsLink );
+ $links[] = wfMsgHtml( 'rcshowhideliu', $liuLink );
+ if( $wgUseRCPatrol )
+ $links[] = wfMsgHtml( 'rcshowhidepatr', $patrLink );
+ $links[] = wfMsgHtml( 'rcshowhidemine', $myselfLink );
+ $hl = implode( ' | ', $links );
+
+ // show from this onward link
+ $now = $wgLang->timeanddate( wfTimestampNow(), true );
+ $tl = makeOptionsLink( $now, array( 'from' => wfTimestampNow()), $nondefaults );
+
+ $rclinks = wfMsgExt( 'rclinks', array( 'parseinline', 'replaceafter'),
+ $cl, $dl, $hl );
+ $rclistfrom = wfMsgExt( 'rclistfrom', array( 'parseinline', 'replaceafter'), $tl );
+ return "$note<br />$rclinks<br />$rclistfrom";
+
+}
+
+/**
+ * Creates the choose namespace selection
+ *
+ * @private
+ *
+ * @param $namespace Mixed: the key of the currently selected namespace, empty string
+ * if there is none
+ * @param $invert Bool: whether to invert the namespace selection
+ * @param $nondefaults Array: an array of non default options to be remembered
+ * @param $categories_any Bool: Default value for the checkbox
+ *
+ * @return string
+ */
+function rcNamespaceForm( $namespace, $invert, $nondefaults, $categories_any ) {
+ global $wgScript, $wgAllowCategorizedRecentChanges, $wgRequest;
+ $t = SpecialPage::getTitleFor( 'Recentchanges' );
+
+ $namespaceselect = HTMLnamespaceselector($namespace, '');
+ $submitbutton = '<input type="submit" value="' . wfMsgHtml( 'allpagessubmit' ) . "\" />\n";
+ $invertbox = "<input type='checkbox' name='invert' value='1' id='nsinvert'" . ( $invert ? ' checked="checked"' : '' ) . ' />';
+
+ if ( $wgAllowCategorizedRecentChanges ) {
+ $categories = trim ( $wgRequest->getVal ( 'categories' , "" ) ) ;
+ $cb_arr = array( 'type' => 'checkbox', 'name' => 'categories_any', 'value' => "1" ) ;
+ if ( $categories_any ) $cb_arr['checked'] = "checked" ;
+ $catbox = "<br />" ;
+ $catbox .= wfMsgExt('rc_categories', array('parseinline')) . " ";
+ $catbox .= wfElement('input', array( 'type' => 'text', 'name' => 'categories', 'value' => $categories));
+ $catbox .= " &nbsp;" ;
+ $catbox .= wfElement('input', $cb_arr );
+ $catbox .= wfMsgExt('rc_categories_any', array('parseinline'));
+ } else {
+ $catbox = "" ;
+ }
+
+ $out = "<div class='namespacesettings'><form method='get' action='{$wgScript}'>\n";
+
+ foreach ( $nondefaults as $key => $value ) {
+ if ($key != 'namespace' && $key != 'invert')
+ $out .= wfElement('input', array( 'type' => 'hidden', 'name' => $key, 'value' => $value));
+ }
+
+ $out .= '<input type="hidden" name="title" value="'.$t->getPrefixedText().'" />';
+ $out .= "
+<div id='nsselect' class='recentchanges'>
+ <label for='namespace'>" . wfMsgHtml('namespace') . "</label>
+ {$namespaceselect}{$submitbutton}{$invertbox} <label for='nsinvert'>" . wfMsgHtml('invert') . "</label>{$catbox}\n</div>";
+ $out .= '</form></div>';
+ return $out;
+}
+
+
+/**
+ * Format a diff for the newsfeed
+ */
+function rcFormatDiff( $row ) {
+ $titleObj = Title::makeTitle( $row->rc_namespace, $row->rc_title );
+ $timestamp = wfTimestamp( TS_MW, $row->rc_timestamp );
+ return rcFormatDiffRow( $titleObj,
+ $row->rc_last_oldid, $row->rc_this_oldid,
+ $timestamp,
+ $row->rc_comment );
+}
+
+function rcFormatDiffRow( $title, $oldid, $newid, $timestamp, $comment ) {
+ global $wgFeedDiffCutoff, $wgContLang, $wgUser;
+ $fname = 'rcFormatDiff';
+ wfProfileIn( $fname );
+
+ $skin = $wgUser->getSkin();
+ $completeText = '<p>' . $skin->formatComment( $comment ) . "</p>\n";
+
+ if( $title->getNamespace() >= 0 ) {
+ if( $oldid ) {
+ wfProfileIn( "$fname-dodiff" );
+
+ $de = new DifferenceEngine( $title, $oldid, $newid );
+ #$diffText = $de->getDiff( wfMsg( 'revisionasof',
+ # $wgContLang->timeanddate( $timestamp ) ),
+ # wfMsg( 'currentrev' ) );
+ $diffText = $de->getDiff(
+ wfMsg( 'previousrevision' ), // hack
+ wfMsg( 'revisionasof',
+ $wgContLang->timeanddate( $timestamp ) ) );
+
+
+ if ( strlen( $diffText ) > $wgFeedDiffCutoff ) {
+ // Omit large diffs
+ $diffLink = $title->escapeFullUrl(
+ 'diff=' . $newid .
+ '&oldid=' . $oldid );
+ $diffText = '<a href="' .
+ $diffLink .
+ '">' .
+ htmlspecialchars( wfMsgForContent( 'difference' ) ) .
+ '</a>';
+ } elseif ( $diffText === false ) {
+ // Error in diff engine, probably a missing revision
+ $diffText = "<p>Can't load revision $newid</p>";
+ } else {
+ // Diff output fine, clean up any illegal UTF-8
+ $diffText = UtfNormal::cleanUp( $diffText );
+ $diffText = rcApplyDiffStyle( $diffText );
+ }
+ wfProfileOut( "$fname-dodiff" );
+ } else {
+ $rev = Revision::newFromId( $newid );
+ if( is_null( $rev ) ) {
+ $newtext = '';
+ } else {
+ $newtext = $rev->getText();
+ }
+ $diffText = '<p><b>' . wfMsg( 'newpage' ) . '</b></p>' .
+ '<div>' . nl2br( htmlspecialchars( $newtext ) ) . '</div>';
+ }
+ $completeText .= $diffText;
+ }
+
+ wfProfileOut( $fname );
+ return $completeText;
+}
+
+/**
+ * Hacky application of diff styles for the feeds.
+ * Might be 'cleaner' to use DOM or XSLT or something,
+ * but *gack* it's a pain in the ass.
+ *
+ * @param $text String:
+ * @return string
+ * @private
+ */
+function rcApplyDiffStyle( $text ) {
+ $styles = array(
+ 'diff' => 'background-color: white;',
+ 'diff-otitle' => 'background-color: white;',
+ 'diff-ntitle' => 'background-color: white;',
+ 'diff-addedline' => 'background: #cfc; font-size: smaller;',
+ 'diff-deletedline' => 'background: #ffa; font-size: smaller;',
+ 'diff-context' => 'background: #eee; font-size: smaller;',
+ 'diffchange' => 'color: red; font-weight: bold;',
+ );
+
+ foreach( $styles as $class => $style ) {
+ $text = preg_replace( "/(<[^>]+)class=(['\"])$class\\2([^>]*>)/",
+ "\\1style=\"$style\"\\3", $text );
+ }
+
+ return $text;
+}
+
+?>
diff --git a/includes/SpecialRecentchangeslinked.php b/includes/SpecialRecentchangeslinked.php
new file mode 100644
index 000000000000..15292898a650
--- /dev/null
+++ b/includes/SpecialRecentchangeslinked.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * This is to display changes made to all articles linked in an article.
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+require_once( 'SpecialRecentchanges.php' );
+
+/**
+ * Entrypoint
+ * @param string $par parent page we will look at
+ */
+function wfSpecialRecentchangeslinked( $par = NULL ) {
+ global $wgUser, $wgOut, $wgLang, $wgContLang, $wgRequest;
+ $fname = 'wfSpecialRecentchangeslinked';
+
+ $days = $wgRequest->getInt( 'days' );
+ $target = isset($par) ? $par : $wgRequest->getText( 'target' );
+ $hideminor = $wgRequest->getBool( 'hideminor' ) ? 1 : 0;
+
+ $wgOut->setPagetitle( wfMsg( 'recentchangeslinked' ) );
+ $sk = $wgUser->getSkin();
+
+ # Validate the title
+ $nt = Title::newFromURL( $target );
+ if( !is_object( $nt ) ) {
+ $wgOut->errorPage( 'notargettitle', 'notargettext' );
+ return;
+ }
+
+ # Check for existence
+ # Do a quiet redirect back to the page itself if it doesn't
+ if( !$nt->exists() ) {
+ $wgOut->redirect( $nt->getLocalUrl() );
+ return;
+ }
+
+ $id = $nt->getArticleId();
+
+ $wgOut->setSubtitle( htmlspecialchars( wfMsg( 'rclsub', $nt->getPrefixedText() ) ) );
+
+ if ( ! $days ) {
+ $days = (int)$wgUser->getOption( 'rcdays', 7 );
+ }
+ list( $limit, /* offset */ ) = wfCheckLimits( 100, 'rclimit' );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $cutoff = $dbr->timestamp( time() - ( $days * 86400 ) );
+
+ $hideminor = ($hideminor ? 1 : 0);
+ if ( $hideminor ) {
+ $mlink = $sk->makeKnownLink( $wgContLang->specialPage( 'Recentchangeslinked' ),
+ wfMsg( 'show' ), 'target=' . htmlspecialchars( $nt->getPrefixedURL() ) .
+ "&days={$days}&limit={$limit}&hideminor=0" );
+ } else {
+ $mlink = $sk->makeKnownLink( $wgContLang->specialPage( "Recentchangeslinked" ),
+ wfMsg( "hide" ), "target=" . htmlspecialchars( $nt->getPrefixedURL() ) .
+ "&days={$days}&limit={$limit}&hideminor=1" );
+ }
+ if ( $hideminor ) {
+ $cmq = 'AND rc_minor=0';
+ } else { $cmq = ''; }
+
+ list($recentchanges, $categorylinks, $pagelinks, $watchlist) =
+ $dbr->tableNamesN( 'recentchanges', 'categorylinks', 'pagelinks', "watchlist" );
+
+ $uid = $wgUser->getID();
+
+ $GROUPBY = "
+ GROUP BY rc_cur_id,rc_namespace,rc_title,
+ rc_user,rc_comment,rc_user_text,rc_timestamp,rc_minor,
+ rc_new, rc_id, rc_this_oldid, rc_last_oldid, rc_bot, rc_patrolled, rc_type, rc_old_len, rc_new_len
+" . ($uid ? ",wl_user" : "") . "
+ ORDER BY rc_timestamp DESC
+ LIMIT {$limit}";
+
+ // If target is a Category, use categorylinks and invert from and to
+ if( $nt->getNamespace() == NS_CATEGORY ) {
+ $catkey = $dbr->addQuotes( $nt->getDBKey() );
+ $sql = "SELECT /* wfSpecialRecentchangeslinked */
+ rc_id,
+ rc_cur_id,
+ rc_namespace,
+ rc_title,
+ rc_this_oldid,
+ rc_last_oldid,
+ rc_user,
+ rc_comment,
+ rc_user_text,
+ rc_timestamp,
+ rc_minor,
+ rc_bot,
+ rc_new,
+ rc_patrolled,
+ rc_type,
+ rc_old_len,
+ rc_new_len
+" . ($uid ? ",wl_user" : "") . "
+ FROM $categorylinks, $recentchanges
+" . ($uid ? "LEFT OUTER JOIN $watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace " : "") . "
+ WHERE rc_timestamp > '{$cutoff}'
+ {$cmq}
+ AND cl_from=rc_cur_id
+ AND cl_to=$catkey
+$GROUPBY
+ ";
+ } else {
+ $sql =
+"SELECT /* wfSpecialRecentchangeslinked */
+ rc_id,
+ rc_cur_id,
+ rc_namespace,
+ rc_title,
+ rc_user,
+ rc_comment,
+ rc_user_text,
+ rc_this_oldid,
+ rc_last_oldid,
+ rc_timestamp,
+ rc_minor,
+ rc_bot,
+ rc_new,
+ rc_patrolled,
+ rc_type,
+ rc_old_len,
+ rc_new_len
+" . ($uid ? ",wl_user" : "") . "
+ FROM $pagelinks, $recentchanges
+" . ($uid ? " LEFT OUTER JOIN $watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace " : "") . "
+ WHERE rc_timestamp > '{$cutoff}'
+ {$cmq}
+ AND pl_namespace=rc_namespace
+ AND pl_title=rc_title
+ AND pl_from=$id
+$GROUPBY
+";
+ }
+ $res = $dbr->query( $sql, $fname );
+
+ $wgOut->addHTML("&lt; ".$sk->makeKnownLinkObj($nt, "", "redirect=no" )."<br />\n");
+ $note = wfMsg( "rcnote", $limit, $days, $wgLang->timeAndDate( wfTimestampNow(), true ) );
+ $wgOut->addHTML( "<hr />\n{$note}\n<br />" );
+
+ $note = rcDayLimitlinks( $days, $limit, "Recentchangeslinked",
+ "target=" . $nt->getPrefixedURL() . "&hideminor={$hideminor}",
+ false, $mlink );
+
+ $wgOut->addHTML( $note."\n" );
+
+ $list = ChangesList::newFromUser( $wgUser );
+ $s = $list->beginRecentChangesList();
+ $count = $dbr->numRows( $res );
+
+ $counter = 1;
+ while ( $limit ) {
+ if ( 0 == $count ) { break; }
+ $obj = $dbr->fetchObject( $res );
+ --$count;
+ $rc = RecentChange::newFromRow( $obj );
+ $rc->counter = $counter++;
+ $s .= $list->recentChangesLine( $rc , !empty( $obj->wl_user) );
+ --$limit;
+ }
+ $s .= $list->endRecentChangesList();
+
+ $dbr->freeResult( $res );
+ $wgOut->addHTML( $s );
+}
+
+?>
diff --git a/includes/SpecialResetpass.php b/includes/SpecialResetpass.php
new file mode 100644
index 000000000000..cde582b1fead
--- /dev/null
+++ b/includes/SpecialResetpass.php
@@ -0,0 +1,158 @@
+<?php
+
+function wfSpecialResetpass( $par ) {
+ $form = new PasswordResetForm();
+ $form->execute( $par );
+}
+
+class PasswordResetForm extends SpecialPage {
+ function __construct( $name=null, $reset=null ) {
+ if( $name !== null ) {
+ $this->mName = $name;
+ $this->mTemporaryPassword = $reset;
+ } else {
+ global $wgRequest;
+ $this->mName = $wgRequest->getVal( 'wpName' );
+ $this->mTemporaryPassword = $wgRequest->getVal( 'wpPassword' );
+ }
+ }
+
+ /**
+ * Main execution point
+ */
+ function execute( $par='' ) {
+ global $wgUser, $wgAuth, $wgOut, $wgRequest;
+
+ if( !$wgAuth->allowPasswordChange() ) {
+ $this->error( wfMsg( 'resetpass_forbidden' ) );
+ return;
+ }
+
+ if( $this->mName === null && !$wgRequest->wasPosted() ) {
+ $this->error( wfMsg( 'resetpass_missing' ) );
+ return;
+ }
+
+ if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal( 'token' ) ) ) {
+ $newpass = $wgRequest->getVal( 'wpNewPassword' );
+ $retype = $wgRequest->getVal( 'wpRetype' );
+ try {
+ $this->attemptReset( $newpass, $retype );
+ $wgOut->addWikiText( wfMsg( 'resetpass_success' ) );
+
+ $data = array(
+ 'action' => 'submitlogin',
+ 'wpName' => $this->mName,
+ 'wpPassword' => $newpass,
+ 'returnto' => $wgRequest->getVal( 'returnto' ),
+ );
+ if( $wgRequest->getCheck( 'wpRemember' ) ) {
+ $data['wpRemember'] = 1;
+ }
+ $login = new LoginForm( new FauxRequest( $data, true ) );
+ $login->execute();
+
+ return;
+ } catch( PasswordError $e ) {
+ $this->error( $e->getMessage() );
+ }
+ }
+ $this->showForm();
+ }
+
+ function error( $msg ) {
+ global $wgOut;
+ $wgOut->addHtml( '<div class="errorbox">' .
+ htmlspecialchars( $msg ) .
+ '</div>' );
+ }
+
+ function showForm() {
+ global $wgOut, $wgUser, $wgLang, $wgRequest;
+
+ $self = SpecialPage::getTitleFor( 'Resetpass' );
+ $form =
+ '<div id="userloginForm">' .
+ wfOpenElement( 'form',
+ array(
+ 'method' => 'post',
+ 'action' => $self->getLocalUrl() ) ) .
+ '<h2>' . wfMsgHtml( 'resetpass_header' ) . '</h2>' .
+ '<div id="userloginprompt">' .
+ wfMsgExt( 'resetpass_text', array( 'parse' ) ) .
+ '</div>' .
+ '<table>' .
+ wfHidden( 'token', $wgUser->editToken() ) .
+ wfHidden( 'wpName', $this->mName ) .
+ wfHidden( 'wpPassword', $this->mTemporaryPassword ) .
+ wfHidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) .
+ $this->pretty( array(
+ array( 'wpName', 'username', 'text', $this->mName ),
+ array( 'wpNewPassword', 'newpassword', 'password', '' ),
+ array( 'wpRetype', 'yourpasswordagain', 'password', '' ),
+ ) ) .
+ '<tr>' .
+ '<td></td>' .
+ '<td>' .
+ Xml::checkLabel( wfMsg( 'remembermypassword' ),
+ 'wpRemember', 'wpRemember',
+ $wgRequest->getCheck( 'wpRemember' ) ) .
+ '</td>' .
+ '</tr>' .
+ '<tr>' .
+ '<td></td>' .
+ '<td>' .
+ wfSubmitButton( wfMsgHtml( 'resetpass_submit' ) ) .
+ '</td>' .
+ '</tr>' .
+ '</table>' .
+ wfCloseElement( 'form' ) .
+ '</div>';
+ $wgOut->addHtml( $form );
+ }
+
+ function pretty( $fields ) {
+ $out = '';
+ foreach( $fields as $list ) {
+ list( $name, $label, $type, $value ) = $list;
+ if( $type == 'text' ) {
+ $field = '<tt>' . htmlspecialchars( $value ) . '</tt>';
+ } else {
+ $field = Xml::input( $name, 20, $value,
+ array( 'id' => $name, 'type' => $type ) );
+ }
+ $out .= '<tr>';
+ $out .= '<td align="right">';
+ $out .= Xml::label( wfMsg( $label ), $name );
+ $out .= '</td>';
+ $out .= '<td>';
+ $out .= $field;
+ $out .= '</td>';
+ $out .= '</tr>';
+ }
+ return $out;
+ }
+
+ /**
+ * @throws PasswordError
+ */
+ function attemptReset( $newpass, $retype ) {
+ $user = User::newFromName( $this->mName );
+ if( $user->isAnon() ) {
+ throw new PasswordError( 'no such user' );
+ }
+
+ if( !$user->checkTemporaryPassword( $this->mTemporaryPassword ) ) {
+ throw new PasswordError( wfMsg( 'resetpass_bad_temporary' ) );
+ }
+
+ if( $newpass !== $retype ) {
+ throw new PasswordError( wfMsg( 'badretype' ) );
+ }
+
+ $user->setPassword( $newpass );
+ $user->saveSettings();
+ }
+}
+
+?>
diff --git a/includes/SpecialRevisiondelete.php b/includes/SpecialRevisiondelete.php
new file mode 100644
index 000000000000..fb5e9ec8c41d
--- /dev/null
+++ b/includes/SpecialRevisiondelete.php
@@ -0,0 +1,268 @@
+<?php
+
+/**
+ * Not quite ready for production use yet; need to fix up the restricted mode,
+ * and provide for preservation across delete/undelete of the page.
+ *
+ * To try this out, set up extra permissions something like:
+ * $wgGroupPermissions['sysop']['deleterevision'] = true;
+ * $wgGroupPermissions['bureaucrat']['hiderevision'] = true;
+ */
+
+function wfSpecialRevisiondelete( $par = null ) {
+ global $wgOut, $wgRequest;
+
+ $target = $wgRequest->getVal( 'target' );
+ $oldid = $wgRequest->getIntArray( 'oldid' );
+
+ $page = Title::newFromUrl( $target );
+
+ if( is_null( $page ) ) {
+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
+ return;
+ }
+
+ if( is_null( $oldid ) ) {
+ $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
+ return;
+ }
+
+ $form = new RevisionDeleteForm( $wgRequest );
+ if( $wgRequest->wasPosted() ) {
+ $form->submit( $wgRequest );
+ } else {
+ $form->show( $wgRequest );
+ }
+}
+
+class RevisionDeleteForm {
+ /**
+ * @param Title $page
+ * @param int $oldid
+ */
+ function __construct( $request ) {
+ global $wgUser;
+
+ $target = $request->getVal( 'target' );
+ $this->page = Title::newFromUrl( $target );
+
+ $this->revisions = $request->getIntArray( 'oldid', array() );
+
+ $this->skin = $wgUser->getSkin();
+ $this->checks = array(
+ array( 'revdelete-hide-text', 'wpHideText', Revision::DELETED_TEXT ),
+ array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
+ array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER ),
+ array( 'revdelete-hide-restricted', 'wpHideRestricted', Revision::DELETED_RESTRICTED ) );
+ }
+
+ /**
+ * @param WebRequest $request
+ */
+ function show( $request ) {
+ global $wgOut, $wgUser;
+
+ $wgOut->addWikiText( wfMsg( 'revdelete-selected', $this->page->getPrefixedText() ) );
+
+ $wgOut->addHtml( "<ul>" );
+ foreach( $this->revisions as $revid ) {
+ $rev = Revision::newFromTitle( $this->page, $revid );
+ if( !isset( $rev ) ) {
+ $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
+ return;
+ }
+ $wgOut->addHtml( $this->historyLine( $rev ) );
+ $bitfields[] = $rev->mDeleted; // FIXME
+ }
+ $wgOut->addHtml( "</ul>" );
+
+ $wgOut->addWikiText( wfMsg( 'revdelete-text' ) );
+
+ $items = array(
+ wfInputLabel( wfMsg( 'revdelete-log' ), 'wpReason', 'wpReason', 60 ),
+ wfSubmitButton( wfMsg( 'revdelete-submit' ) ) );
+ $hidden = array(
+ wfHidden( 'wpEditToken', $wgUser->editToken() ),
+ wfHidden( 'target', $this->page->getPrefixedText() ) );
+ foreach( $this->revisions as $revid ) {
+ $hidden[] = wfHidden( 'oldid[]', $revid );
+ }
+
+ $special = SpecialPage::getTitleFor( 'Revisiondelete' );
+ $wgOut->addHtml( wfElement( 'form', array(
+ 'method' => 'post',
+ 'action' => $special->getLocalUrl( 'action=submit' ) ),
+ null ) );
+
+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'revdelete-legend' ) . '</legend>' );
+ foreach( $this->checks as $item ) {
+ list( $message, $name, $field ) = $item;
+ $wgOut->addHtml( '<div>' .
+ wfCheckLabel( wfMsg( $message), $name, $name, $rev->isDeleted( $field ) ) .
+ '</div>' );
+ }
+ $wgOut->addHtml( '</fieldset>' );
+ foreach( $items as $item ) {
+ $wgOut->addHtml( '<p>' . $item . '</p>' );
+ }
+ foreach( $hidden as $item ) {
+ $wgOut->addHtml( $item );
+ }
+
+ $wgOut->addHtml( '</form>' );
+ }
+
+ /**
+ * @param Revision $rev
+ * @returns string
+ */
+ function historyLine( $rev ) {
+ global $wgContLang;
+ $date = $wgContLang->timeanddate( $rev->getTimestamp() );
+ return
+ "<li>" .
+ $this->skin->makeLinkObj( $this->page, $date, 'oldid=' . $rev->getId() ) .
+ " " .
+ $this->skin->revUserLink( $rev ) .
+ " " .
+ $this->skin->revComment( $rev ) .
+ "</li>";
+ }
+
+ /**
+ * @param WebRequest $request
+ */
+ function submit( $request ) {
+ $bitfield = $this->extractBitfield( $request );
+ $comment = $request->getText( 'wpReason' );
+ if( $this->save( $bitfield, $comment ) ) {
+ return $this->success( $request );
+ } else {
+ return $this->show( $request );
+ }
+ }
+
+ function success( $request ) {
+ global $wgOut;
+ $wgOut->addWikiText( 'woo' );
+ }
+
+ /**
+ * Put together a rev_deleted bitfield from the submitted checkboxes
+ * @param WebRequest $request
+ * @return int
+ */
+ function extractBitfield( $request ) {
+ $bitfield = 0;
+ foreach( $this->checks as $item ) {
+ list( /* message */ , $name, $field ) = $item;
+ if( $request->getCheck( $name ) ) {
+ $bitfield |= $field;
+ }
+ }
+ return $bitfield;
+ }
+
+ function save( $bitfield, $reason ) {
+ $dbw = wfGetDB( DB_MASTER );
+ $deleter = new RevisionDeleter( $dbw );
+ $deleter->setVisibility( $this->revisions, $bitfield, $reason );
+ }
+}
+
+
+class RevisionDeleter {
+ function __construct( $db ) {
+ $this->db = $db;
+ }
+
+ /**
+ * @param array $items list of revision ID numbers
+ * @param int $bitfield new rev_deleted value
+ * @param string $comment Comment for log records
+ */
+ function setVisibility( $items, $bitfield, $comment ) {
+ $pages = array();
+
+ // To work!
+ foreach( $items as $revid ) {
+ $rev = Revision::newFromId( $revid );
+ if( !isset( $rev ) ) {
+ return false;
+ }
+ $this->updateRevision( $rev, $bitfield );
+ $this->updateRecentChanges( $rev, $bitfield );
+
+ // For logging, maintain a count of revisions per page
+ $pageid = $rev->getPage();
+ if( isset( $pages[$pageid] ) ) {
+ $pages[$pageid]++;
+ } else {
+ $pages[$pageid] = 1;
+ }
+ }
+
+ // Clear caches...
+ foreach( $pages as $pageid => $count ) {
+ $title = Title::newFromId( $pageid );
+ $this->updatePage( $title );
+ $this->updateLog( $title, $count, $bitfield, $comment );
+ }
+
+ return true;
+ }
+
+ /**
+ * Update the revision's rev_deleted field
+ * @param Revision $rev
+ * @param int $bitfield new rev_deleted bitfield value
+ */
+ function updateRevision( $rev, $bitfield ) {
+ $this->db->update( 'revision',
+ array( 'rev_deleted' => $bitfield ),
+ array( 'rev_id' => $rev->getId() ),
+ 'RevisionDeleter::updateRevision' );
+ }
+
+ /**
+ * Update the revision's recentchanges record if fields have been hidden
+ * @param Revision $rev
+ * @param int $bitfield new rev_deleted bitfield value
+ */
+ function updateRecentChanges( $rev, $bitfield ) {
+ $this->db->update( 'recentchanges',
+ array(
+ 'rc_user' => ($bitfield & Revision::DELETED_USER) ? 0 : $rev->getUser(),
+ 'rc_user_text' => ($bitfield & Revision::DELETED_USER) ? wfMsg( 'rev-deleted-user' ) : $rev->getUserText(),
+ 'rc_comment' => ($bitfield & Revision::DELETED_COMMENT) ? wfMsg( 'rev-deleted-comment' ) : $rev->getComment() ),
+ array(
+ 'rc_this_oldid' => $rev->getId() ),
+ 'RevisionDeleter::updateRecentChanges' );
+ }
+
+ /**
+ * Touch the page's cache invalidation timestamp; this forces cached
+ * history views to refresh, so any newly hidden or shown fields will
+ * update properly.
+ * @param Title $title
+ */
+ function updatePage( $title ) {
+ $title->invalidateCache();
+ }
+
+ /**
+ * Record a log entry on the action
+ * @param Title $title
+ * @param int $count the number of revisions altered for this page
+ * @param int $bitfield the new rev_deleted value
+ * @param string $comment
+ */
+ function updateLog( $title, $count, $bitfield, $comment ) {
+ $log = new LogPage( 'delete' );
+ $reason = "changed $count revisions to $bitfield";
+ $reason .= ": $comment";
+ $log->addEntry( 'revision', $title, $reason );
+ }
+}
+
+?>
diff --git a/includes/SpecialSearch.php b/includes/SpecialSearch.php
new file mode 100644
index 000000000000..9ecd39efa0d6
--- /dev/null
+++ b/includes/SpecialSearch.php
@@ -0,0 +1,406 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Run text & title search and display the output
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Entry point
+ *
+ * @param $par String: (default '')
+ */
+function wfSpecialSearch( $par = '' ) {
+ global $wgRequest, $wgUser;
+
+ $search = $wgRequest->getText( 'search', $par );
+ $searchPage = new SpecialSearch( $wgRequest, $wgUser );
+ if( $wgRequest->getVal( 'fulltext' ) ||
+ !is_null( $wgRequest->getVal( 'offset' ) ) ||
+ !is_null ($wgRequest->getVal( 'searchx' ) ) ) {
+ $searchPage->showResults( $search );
+ } else {
+ $searchPage->goResult( $search );
+ }
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class SpecialSearch {
+
+ /**
+ * Set up basic search parameters from the request and user settings.
+ * Typically you'll pass $wgRequest and $wgUser.
+ *
+ * @param WebRequest $request
+ * @param User $user
+ * @public
+ */
+ function SpecialSearch( &$request, &$user ) {
+ list( $this->limit, $this->offset ) = $request->getLimitOffset( 20, 'searchlimit' );
+
+ if( $request->getCheck( 'searchx' ) ) {
+ $this->namespaces = $this->powerSearch( $request );
+ } else {
+ $this->namespaces = $this->userNamespaces( $user );
+ }
+
+ $this->searchRedirects = $request->getcheck( 'redirs' ) ? true : false;
+ }
+
+ /**
+ * If an exact title match can be found, jump straight ahead to it.
+ * @param string $term
+ * @public
+ */
+ function goResult( $term ) {
+ global $wgOut;
+ global $wgGoToEdit;
+
+ $this->setupPage( $term );
+
+ # Try to go to page as entered.
+ $t = Title::newFromText( $term );
+
+ # If the string cannot be used to create a title
+ if( is_null( $t ) ){
+ return $this->showResults( $term );
+ }
+
+ # If there's an exact or very near match, jump right there.
+ $t = SearchEngine::getNearMatch( $term );
+ if( !is_null( $t ) ) {
+ $wgOut->redirect( $t->getFullURL() );
+ return;
+ }
+
+ # No match, generate an edit URL
+ $t = Title::newFromText( $term );
+ if( ! is_null( $t ) ) {
+ wfRunHooks( 'SpecialSearchNogomatch', array( &$t ) );
+ # If the feature is enabled, go straight to the edit page
+ if ( $wgGoToEdit ) {
+ $wgOut->redirect( $t->getFullURL( 'action=edit' ) );
+ return;
+ }
+ }
+ $wgOut->addWikiText( wfMsg( 'noexactmatch', wfEscapeWikiText( $term ) ) );
+
+ return $this->showResults( $term );
+ }
+
+ /**
+ * @param string $term
+ * @public
+ */
+ function showResults( $term ) {
+ $fname = 'SpecialSearch::showResults';
+ wfProfileIn( $fname );
+
+ $this->setupPage( $term );
+
+ global $wgOut;
+ $wgOut->addWikiText( wfMsg( 'searchresulttext' ) );
+
+ #if ( !$this->parseQuery() ) {
+ if( '' === trim( $term ) ) {
+ $wgOut->setSubtitle( '' );
+ $wgOut->addHTML( $this->powerSearchBox( $term ) );
+ wfProfileOut( $fname );
+ return;
+ }
+
+ global $wgDisableTextSearch;
+ if ( $wgDisableTextSearch ) {
+ global $wgForwardSearchUrl;
+ if( $wgForwardSearchUrl ) {
+ $url = str_replace( '$1', urlencode( $term ), $wgForwardSearchUrl );
+ $wgOut->redirect( $url );
+ return;
+ }
+ global $wgInputEncoding;
+ $wgOut->addHTML( wfMsg( 'searchdisabled' ) );
+ $wgOut->addHTML(
+ wfMsg( 'googlesearch',
+ htmlspecialchars( $term ),
+ htmlspecialchars( $wgInputEncoding ),
+ htmlspecialchars( wfMsg( 'searchbutton' ) )
+ )
+ );
+ wfProfileOut( $fname );
+ return;
+ }
+
+ $search = SearchEngine::create();
+ $search->setLimitOffset( $this->limit, $this->offset );
+ $search->setNamespaces( $this->namespaces );
+ $search->showRedirects = $this->searchRedirects;
+ $titleMatches = $search->searchTitle( $term );
+ $textMatches = $search->searchText( $term );
+
+ $num = ( $titleMatches ? $titleMatches->numRows() : 0 )
+ + ( $textMatches ? $textMatches->numRows() : 0);
+ if ( $num >= $this->limit ) {
+ $top = wfShowingResults( $this->offset, $this->limit );
+ } else {
+ $top = wfShowingResultsNum( $this->offset, $this->limit, $num );
+ }
+ $wgOut->addHTML( "<p>{$top}</p>\n" );
+
+ if( $num || $this->offset ) {
+ $prevnext = wfViewPrevNext( $this->offset, $this->limit,
+ SpecialPage::getTitleFor( 'Search' ),
+ wfArrayToCGI(
+ $this->powerSearchOptions(),
+ array( 'search' => $term ) ) );
+ $wgOut->addHTML( "<br />{$prevnext}\n" );
+ }
+
+ if( $titleMatches ) {
+ if( $titleMatches->numRows() ) {
+ $wgOut->addWikiText( '==' . wfMsg( 'titlematches' ) . "==\n" );
+ $wgOut->addHTML( $this->showMatches( $titleMatches ) );
+ } else {
+ $wgOut->addWikiText( '==' . wfMsg( 'notitlematches' ) . "==\n" );
+ }
+ }
+
+ if( $textMatches ) {
+ if( $textMatches->numRows() ) {
+ $wgOut->addWikiText( '==' . wfMsg( 'textmatches' ) . "==\n" );
+ $wgOut->addHTML( $this->showMatches( $textMatches ) );
+ } elseif( $num == 0 ) {
+ # Don't show the 'no text matches' if we received title matches
+ $wgOut->addWikiText( '==' . wfMsg( 'notextmatches' ) . "==\n" );
+ }
+ }
+
+ if ( $num == 0 ) {
+ $wgOut->addWikiText( wfMsg( 'nonefound' ) );
+ }
+ if( $num || $this->offset ) {
+ $wgOut->addHTML( "<p>{$prevnext}</p>\n" );
+ }
+ $wgOut->addHTML( $this->powerSearchBox( $term ) );
+ wfProfileOut( $fname );
+ }
+
+ #------------------------------------------------------------------
+ # Private methods below this line
+
+ /**
+ *
+ */
+ function setupPage( $term ) {
+ global $wgOut;
+ $wgOut->setPageTitle( wfMsg( 'searchresults' ) );
+ $subtitlemsg = ( Title::newFromText($term) ? 'searchsubtitle' : 'searchsubtitleinvalid' );
+ $wgOut->setSubtitle( $wgOut->parse( wfMsg( $subtitlemsg, wfEscapeWikiText($term) ) ) );
+ $wgOut->setArticleRelated( false );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ }
+
+ /**
+ * Extract default namespaces to search from the given user's
+ * settings, returning a list of index numbers.
+ *
+ * @param User $user
+ * @return array
+ * @private
+ */
+ function userNamespaces( &$user ) {
+ $arr = array();
+ foreach( SearchEngine::searchableNamespaces() as $ns => $name ) {
+ if( $user->getOption( 'searchNs' . $ns ) ) {
+ $arr[] = $ns;
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * Extract "power search" namespace settings from the request object,
+ * returning a list of index numbers to search.
+ *
+ * @param WebRequest $request
+ * @return array
+ * @private
+ */
+ function powerSearch( &$request ) {
+ $arr = array();
+ foreach( SearchEngine::searchableNamespaces() as $ns => $name ) {
+ if( $request->getCheck( 'ns' . $ns ) ) {
+ $arr[] = $ns;
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * Reconstruct the 'power search' options for links
+ * @return array
+ * @private
+ */
+ function powerSearchOptions() {
+ $opt = array();
+ foreach( $this->namespaces as $n ) {
+ $opt['ns' . $n] = 1;
+ }
+ $opt['redirs'] = $this->searchRedirects ? 1 : 0;
+ $opt['searchx'] = 1;
+ return $opt;
+ }
+
+ /**
+ * @param SearchResultSet $matches
+ * @param string $terms partial regexp for highlighting terms
+ */
+ function showMatches( &$matches ) {
+ $fname = 'SpecialSearch::showMatches';
+ wfProfileIn( $fname );
+
+ global $wgContLang;
+ $tm = $wgContLang->convertForSearchResult( $matches->termMatches() );
+ $terms = implode( '|', $tm );
+
+ $off = $this->offset + 1;
+ $out = "<ol start='{$off}'>\n";
+
+ while( $result = $matches->next() ) {
+ $out .= $this->showHit( $result, $terms );
+ }
+ $out .= "</ol>\n";
+
+ // convert the whole thing to desired language variant
+ global $wgContLang;
+ $out = $wgContLang->convert( $out );
+ wfProfileOut( $fname );
+ return $out;
+ }
+
+ /**
+ * Format a single hit result
+ * @param SearchResult $result
+ * @param string $terms partial regexp for highlighting terms
+ */
+ function showHit( $result, $terms ) {
+ $fname = 'SpecialSearch::showHit';
+ wfProfileIn( $fname );
+ global $wgUser, $wgContLang, $wgLang;
+
+ $t = $result->getTitle();
+ if( is_null( $t ) ) {
+ wfProfileOut( $fname );
+ return "<!-- Broken link in search result -->\n";
+ }
+ $sk =& $wgUser->getSkin();
+
+ $contextlines = $wgUser->getOption( 'contextlines', 5 );
+ $contextchars = $wgUser->getOption( 'contextchars', 50 );
+
+ $link = $sk->makeKnownLinkObj( $t );
+ $revision = Revision::newFromTitle( $t );
+ $text = $revision->getText();
+ $size = wfMsgExt( 'nbytes', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( strlen( $text ) ) );
+
+ $lines = explode( "\n", $text );
+
+ $max = intval( $contextchars ) + 1;
+ $pat1 = "/(.*)($terms)(.{0,$max})/i";
+
+ $lineno = 0;
+
+ $extract = '';
+ wfProfileIn( "$fname-extract" );
+ foreach ( $lines as $line ) {
+ if ( 0 == $contextlines ) {
+ break;
+ }
+ ++$lineno;
+ $m = array();
+ if ( ! preg_match( $pat1, $line, $m ) ) {
+ continue;
+ }
+ --$contextlines;
+ $pre = $wgContLang->truncate( $m[1], -$contextchars, '...' );
+
+ if ( count( $m ) < 3 ) {
+ $post = '';
+ } else {
+ $post = $wgContLang->truncate( $m[3], $contextchars, '...' );
+ }
+
+ $found = $m[2];
+
+ $line = htmlspecialchars( $pre . $found . $post );
+ $pat2 = '/(' . $terms . ")/i";
+ $line = preg_replace( $pat2,
+ "<span class='searchmatch'>\\1</span>", $line );
+
+ $extract .= "<br /><small>{$lineno}: {$line}</small>\n";
+ }
+ wfProfileOut( "$fname-extract" );
+ wfProfileOut( $fname );
+ return "<li>{$link} ({$size}){$extract}</li>\n";
+ }
+
+ function powerSearchBox( $term ) {
+ $namespaces = '';
+ foreach( SearchEngine::searchableNamespaces() as $ns => $name ) {
+ $checked = in_array( $ns, $this->namespaces )
+ ? ' checked="checked"'
+ : '';
+ $name = str_replace( '_', ' ', $name );
+ if( '' == $name ) {
+ $name = wfMsg( 'blanknamespace' );
+ }
+ $namespaces .= " <label><input type='checkbox' value=\"1\" name=\"" .
+ "ns{$ns}\"{$checked} />{$name}</label>\n";
+ }
+
+ $checked = $this->searchRedirects
+ ? ' checked="checked"'
+ : '';
+ $redirect = "<input type='checkbox' value='1' name=\"redirs\"{$checked} />\n";
+
+ $searchField = '<input type="text" name="search" value="' .
+ htmlspecialchars( $term ) ."\" size=\"16\" />\n";
+
+ $searchButton = '<input type="submit" name="searchx" value="' .
+ htmlspecialchars( wfMsg('powersearch') ) . "\" />\n";
+
+ $ret = wfMsg( 'powersearchtext',
+ $namespaces, $redirect, $searchField,
+ '', '', '', '', '', # Dummy placeholders
+ $searchButton );
+
+ $title = SpecialPage::getTitleFor( 'Search' );
+ $action = $title->escapeLocalURL();
+ return "<br /><br />\n<form id=\"powersearch\" method=\"get\" " .
+ "action=\"$action\">\n{$ret}\n</form>\n";
+ }
+}
+
+?>
diff --git a/includes/SpecialShortpages.php b/includes/SpecialShortpages.php
new file mode 100644
index 000000000000..03164debdef6
--- /dev/null
+++ b/includes/SpecialShortpages.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * SpecialShortpages extends QueryPage. It is used to return the shortest
+ * pages in the database.
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class ShortPagesPage extends QueryPage {
+
+ function getName() {
+ return "Shortpages";
+ }
+
+ /**
+ * This query is indexed as of 1.5
+ */
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $page = $dbr->tableName( 'page' );
+ $name = $dbr->addQuotes( $this->getName() );
+
+ $forceindex = $dbr->useIndexClause("page_len");
+ return
+ "SELECT $name as type,
+ page_namespace as namespace,
+ page_title as title,
+ page_len AS value
+ FROM $page $forceindex
+ WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0";
+ }
+
+ function preprocessResults( &$db, &$res ) {
+ # There's no point doing a batch check if we aren't caching results;
+ # the page must exist for it to have been pulled out of the table
+ if( $this->isCached() ) {
+ $batch = new LinkBatch();
+ while( $row = $db->fetchObject( $res ) )
+ $batch->addObj( Title::makeTitleSafe( $row->namespace, $row->title ) );
+ $batch->execute();
+ if( $db->numRows( $res ) > 0 )
+ $db->dataSeek( $res, 0 );
+ }
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+ $dm = $wgContLang->getDirMark();
+
+ $title = Title::makeTitleSafe( $result->namespace, $result->title );
+ if ( !$title ) {
+ return '<!-- Invalid title ' . htmlspecialchars( "{$result->namespace}:{$result->title}" ). '-->';
+ }
+ $hlink = $skin->makeKnownLinkObj( $title, wfMsgHtml( 'hist' ), 'action=history' );
+ $plink = $this->isCached()
+ ? $skin->makeLinkObj( $title )
+ : $skin->makeKnownLinkObj( $title );
+ $size = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), $wgLang->formatNum( htmlspecialchars( $result->value ) ) );
+
+ return $title->exists()
+ ? "({$hlink}) {$dm}{$plink} {$dm}[{$size}]"
+ : "<s>({$hlink}) {$dm}{$plink} {$dm}[{$size}]</s>";
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialShortpages() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $spp = new ShortPagesPage();
+
+ return $spp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialSpecialpages.php b/includes/SpecialSpecialpages.php
new file mode 100644
index 000000000000..78f9dee51f9a
--- /dev/null
+++ b/includes/SpecialSpecialpages.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+function wfSpecialSpecialpages() {
+ global $wgOut, $wgUser;
+
+ $wgOut->setRobotpolicy( 'index,nofollow' );
+ $sk = $wgUser->getSkin();
+
+ /** Pages available to all */
+ wfSpecialSpecialpages_gen( SpecialPage::getRegularPages(), 'spheading', $sk );
+
+ /** Restricted special pages */
+ wfSpecialSpecialpages_gen( SpecialPage::getRestrictedPages(), 'restrictedpheading', $sk );
+}
+
+/**
+ * sub function generating the list of pages
+ * @param $pages the list of pages
+ * @param $heading header to be used
+ * @param $sk skin object ???
+ */
+function wfSpecialSpecialpages_gen($pages,$heading,$sk) {
+ global $wgOut, $wgSortSpecialPages;
+
+ if( count( $pages ) == 0 ) {
+ # Yeah, that was pointless. Thanks for coming.
+ return;
+ }
+
+ /** Put them into a sortable array */
+ $sortedPages = array();
+ foreach ( $pages as $page ) {
+ if ( $page->isListed() ) {
+ $sortedPages[$page->getDescription()] = $page->getTitle();
+ }
+ }
+
+ /** Sort */
+ if ( $wgSortSpecialPages ) {
+ ksort( $sortedPages );
+ }
+
+ /** Now output the HTML */
+ $wgOut->addHTML( '<h2>' . wfMsgHtml( $heading ) . "</h2>\n<ul>" );
+ foreach ( $sortedPages as $desc => $title ) {
+ $link = $sk->makeKnownLinkObj( $title, $desc );
+ $wgOut->addHTML( "<li>{$link}</li>\n" );
+ }
+ $wgOut->addHTML( "</ul>\n" );
+}
+
+?>
diff --git a/includes/SpecialStatistics.php b/includes/SpecialStatistics.php
new file mode 100644
index 000000000000..a5a0fc3a7cf8
--- /dev/null
+++ b/includes/SpecialStatistics.php
@@ -0,0 +1,81 @@
+<?php
+/**
+*
+* @package MediaWiki
+* @subpackage SpecialPage
+*/
+
+/**
+* constructor
+*/
+function wfSpecialStatistics() {
+ global $wgOut, $wgLang, $wgRequest;
+ $fname = 'wfSpecialStatistics';
+
+ $action = $wgRequest->getVal( 'action' );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $views = SiteStats::views();
+ $edits = SiteStats::edits();
+ $good = SiteStats::articles();
+ $images = SiteStats::images();
+ $total = SiteStats::pages();
+ $users = SiteStats::users();
+
+ $admins = $dbr->selectField( 'user_groups', 'COUNT(*)', array( 'ug_group' => 'sysop' ), $fname );
+ $numJobs = $dbr->selectField( 'job', 'COUNT(*)', '', $fname );
+
+ if ($action == 'raw') {
+ $wgOut->disable();
+ header( 'Pragma: nocache' );
+ echo "total=$total;good=$good;views=$views;edits=$edits;users=$users;admins=$admins;images=$images;jobs=$numJobs\n";
+ return;
+ } else {
+ $text = '==' . wfMsg( 'sitestats' ) . "==\n" ;
+ $text .= wfMsg( 'sitestatstext',
+ $wgLang->formatNum( $total ),
+ $wgLang->formatNum( $good ),
+ $wgLang->formatNum( $views ),
+ $wgLang->formatNum( $edits ),
+ $wgLang->formatNum( sprintf( '%.2f', $total ? $edits / $total : 0 ) ),
+ $wgLang->formatNum( sprintf( '%.2f', $edits ? $views / $edits : 0 ) ),
+ $wgLang->formatNum( $numJobs ),
+ $wgLang->formatNum( $images )
+ );
+
+ $text .= "\n==" . wfMsg( 'userstats' ) . "==\n";
+
+ $text .= wfMsg( 'userstatstext',
+ $wgLang->formatNum( $users ),
+ $wgLang->formatNum( $admins ),
+ '[[' . wfMsgForContent( 'grouppage-sysop' ) . ']]', # TODO somehow remove, kept for backwards compatibility
+ $wgLang->formatNum( sprintf( '%.2f', $admins / $users * 100 ) ),
+ User::makeGroupLinkWiki( 'sysop' )
+ );
+
+ $wgOut->addWikiText( $text );
+
+ global $wgDisableCounters, $wgMiserMode, $wgUser, $wgLang, $wgContLang;
+ if( !$wgDisableCounters && !$wgMiserMode ) {
+ $page = $dbr->tableName( 'page' );
+ $sql = "SELECT page_namespace, page_title, page_counter FROM {$page} WHERE page_is_redirect = 0 AND page_counter > 0 ORDER BY page_counter DESC";
+ $sql = $dbr->limitResult($sql, 10, 0);
+ $res = $dbr->query( $sql, $fname );
+ if( $res ) {
+ $wgOut->addHtml( '<h2>' . wfMsgHtml( 'statistics-mostpopular' ) . '</h2>' );
+ $skin =& $wgUser->getSkin();
+ $wgOut->addHtml( '<ol>' );
+ while( $row = $dbr->fetchObject( $res ) ) {
+ $link = $skin->makeKnownLinkObj( Title::makeTitleSafe( $row->page_namespace, $row->page_title ) );
+ $dirmark = $wgContLang->getDirMark();
+ $wgOut->addHtml( '<li>' . $link . $dirmark . ' [' . $wgLang->formatNum( $row->page_counter ) . ']</li>' );
+ }
+ $wgOut->addHtml( '</ol>' );
+ $dbr->freeResult( $res );
+ }
+ }
+
+ }
+}
+?>
diff --git a/includes/SpecialUncategorizedcategories.php b/includes/SpecialUncategorizedcategories.php
new file mode 100644
index 000000000000..ba399f0ccf06
--- /dev/null
+++ b/includes/SpecialUncategorizedcategories.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+require_once( "SpecialUncategorizedpages.php" );
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UncategorizedCategoriesPage extends UncategorizedPagesPage {
+ function UncategorizedCategoriesPage() {
+ $this->requestedNamespace = NS_CATEGORY;
+ }
+
+ function getName() {
+ return "Uncategorizedcategories";
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialUncategorizedcategories() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $lpp = new UncategorizedCategoriesPage();
+
+ return $lpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialUncategorizedimages.php b/includes/SpecialUncategorizedimages.php
new file mode 100644
index 000000000000..1daba8edcbd4
--- /dev/null
+++ b/includes/SpecialUncategorizedimages.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Special page lists images which haven't been categorised
+ *
+ * @package MediaWiki
+ * @subpackage Special pages
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+class UncategorizedImagesPage extends QueryPage {
+
+ function getName() {
+ return 'Uncategorizedimages';
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $categorylinks ) = $dbr->tableNamesN( 'page', 'categorylinks' );
+ $ns = NS_IMAGE;
+
+ return "SELECT 'Uncategorizedimages' AS type, page_namespace AS namespace,
+ page_title AS title, page_title AS value
+ FROM {$page} LEFT JOIN {$categorylinks} ON page_id = cl_from
+ WHERE cl_from IS NULL AND page_namespace = {$ns} AND page_is_redirect = 0";
+ }
+
+ function formatResult( &$skin, $row ) {
+ global $wgContLang;
+ $title = Title::makeTitleSafe( NS_IMAGE, $row->title );
+ $label = htmlspecialchars( $wgContLang->convert( $title->getText() ) );
+ return $skin->makeKnownLinkObj( $title, $label );
+ }
+
+}
+
+function wfSpecialUncategorizedimages() {
+ $uip = new UncategorizedImagesPage();
+ list( $limit, $offset ) = wfCheckLimits();
+ return $uip->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialUncategorizedpages.php b/includes/SpecialUncategorizedpages.php
new file mode 100644
index 000000000000..dbf23a60d42a
--- /dev/null
+++ b/includes/SpecialUncategorizedpages.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UncategorizedPagesPage extends PageQueryPage {
+ var $requestedNamespace = NS_MAIN;
+
+ function getName() {
+ return "Uncategorizedpages";
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function isExpensive() {
+ return true;
+ }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $categorylinks ) = $dbr->tableNamesN( 'page', 'categorylinks' );
+ $name = $dbr->addQuotes( $this->getName() );
+
+ return
+ "
+ SELECT
+ $name as type,
+ page_namespace AS namespace,
+ page_title AS title,
+ page_title AS value
+ FROM $page
+ LEFT JOIN $categorylinks ON page_id=cl_from
+ WHERE cl_from IS NULL AND page_namespace={$this->requestedNamespace} AND page_is_redirect=0
+ ";
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialUncategorizedpages() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $lpp = new UncategorizedPagesPage();
+
+ return $lpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialUndelete.php b/includes/SpecialUndelete.php
new file mode 100644
index 000000000000..7c9b119111ca
--- /dev/null
+++ b/includes/SpecialUndelete.php
@@ -0,0 +1,767 @@
+<?php
+
+/**
+ * Special page allowing users with the appropriate permissions to view
+ * and restore deleted content
+ *
+ * @package MediaWiki
+ * @subpackage Special pages
+ */
+
+/**
+ *
+ */
+function wfSpecialUndelete( $par ) {
+ global $wgRequest;
+
+ $form = new UndeleteForm( $wgRequest, $par );
+ $form->execute();
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class PageArchive {
+ var $title;
+
+ function PageArchive( &$title ) {
+ if( is_null( $title ) ) {
+ throw new MWException( 'Archiver() given a null title.');
+ }
+ $this->title =& $title;
+ }
+
+ /**
+ * List all deleted pages recorded in the archive table. Returns result
+ * wrapper with (ar_namespace, ar_title, count) fields, ordered by page
+ * namespace/title. Can be called staticaly.
+ *
+ * @return ResultWrapper
+ */
+ /* static */ function listAllPages() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $archive = $dbr->tableName( 'archive' );
+
+ $sql = "SELECT ar_namespace,ar_title, COUNT(*) AS count FROM $archive " .
+ "GROUP BY ar_namespace,ar_title ORDER BY ar_namespace,ar_title";
+
+ return $dbr->resultObject( $dbr->query( $sql, 'PageArchive::listAllPages' ) );
+ }
+
+ /**
+ * List the revisions of the given page. Returns result wrapper with
+ * (ar_minor_edit, ar_timestamp, ar_user, ar_user_text, ar_comment) fields.
+ *
+ * @return ResultWrapper
+ */
+ function listRevisions() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'archive',
+ array( 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text', 'ar_comment' ),
+ array( 'ar_namespace' => $this->title->getNamespace(),
+ 'ar_title' => $this->title->getDBkey() ),
+ 'PageArchive::listRevisions',
+ array( 'ORDER BY' => 'ar_timestamp DESC' ) );
+ $ret = $dbr->resultObject( $res );
+ return $ret;
+ }
+
+ /**
+ * List the deleted file revisions for this page, if it's a file page.
+ * Returns a result wrapper with various filearchive fields, or null
+ * if not a file page.
+ *
+ * @return ResultWrapper
+ * @fixme Does this belong in Image for fuller encapsulation?
+ */
+ function listFiles() {
+ if( $this->title->getNamespace() == NS_IMAGE ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'filearchive',
+ array(
+ 'fa_id',
+ 'fa_name',
+ 'fa_storage_key',
+ 'fa_size',
+ 'fa_width',
+ 'fa_height',
+ 'fa_description',
+ 'fa_user',
+ 'fa_user_text',
+ 'fa_timestamp' ),
+ array( 'fa_name' => $this->title->getDbKey() ),
+ __METHOD__,
+ array( 'ORDER BY' => 'fa_timestamp DESC' ) );
+ $ret = $dbr->resultObject( $res );
+ return $ret;
+ }
+ return null;
+ }
+
+ /**
+ * Fetch (and decompress if necessary) the stored text for the deleted
+ * revision of the page with the given timestamp.
+ *
+ * @return string
+ * @deprecated Use getRevision() for more flexible information
+ */
+ function getRevisionText( $timestamp ) {
+ $rev = $this->getRevision( $timestamp );
+ return $rev ? $rev->getText() : null;
+ }
+
+ /**
+ * Return a Revision object containing data for the deleted revision.
+ * Note that the result *may* or *may not* have a null page ID.
+ * @param string $timestamp
+ * @return Revision
+ */
+ function getRevision( $timestamp ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow( 'archive',
+ array(
+ 'ar_rev_id',
+ 'ar_text',
+ 'ar_comment',
+ 'ar_user',
+ 'ar_user_text',
+ 'ar_timestamp',
+ 'ar_minor_edit',
+ 'ar_flags',
+ 'ar_text_id' ),
+ array( 'ar_namespace' => $this->title->getNamespace(),
+ 'ar_title' => $this->title->getDbkey(),
+ 'ar_timestamp' => $dbr->timestamp( $timestamp ) ),
+ __METHOD__ );
+ if( $row ) {
+ return new Revision( array(
+ 'page' => $this->title->getArticleId(),
+ 'id' => $row->ar_rev_id,
+ 'text' => ($row->ar_text_id
+ ? null
+ : Revision::getRevisionText( $row, 'ar_' ) ),
+ 'comment' => $row->ar_comment,
+ 'user' => $row->ar_user,
+ 'user_text' => $row->ar_user_text,
+ 'timestamp' => $row->ar_timestamp,
+ 'minor_edit' => $row->ar_minor_edit,
+ 'text_id' => $row->ar_text_id ) );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the text from an archive row containing ar_text, ar_flags and ar_text_id
+ */
+ function getTextFromRow( $row ) {
+ if( is_null( $row->ar_text_id ) ) {
+ // An old row from MediaWiki 1.4 or previous.
+ // Text is embedded in this row in classic compression format.
+ return Revision::getRevisionText( $row, "ar_" );
+ } else {
+ // New-style: keyed to the text storage backend.
+ $dbr =& wfGetDB( DB_SLAVE );
+ $text = $dbr->selectRow( 'text',
+ array( 'old_text', 'old_flags' ),
+ array( 'old_id' => $row->ar_text_id ),
+ __METHOD__ );
+ return Revision::getRevisionText( $text );
+ }
+ }
+
+
+ /**
+ * Fetch (and decompress if necessary) the stored text of the most
+ * recently edited deleted revision of the page.
+ *
+ * If there are no archived revisions for the page, returns NULL.
+ *
+ * @return string
+ */
+ function getLastRevisionText() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow( 'archive',
+ array( 'ar_text', 'ar_flags', 'ar_text_id' ),
+ array( 'ar_namespace' => $this->title->getNamespace(),
+ 'ar_title' => $this->title->getDBkey() ),
+ 'PageArchive::getLastRevisionText',
+ array( 'ORDER BY' => 'ar_timestamp DESC' ) );
+ if( $row ) {
+ return $this->getTextFromRow( $row );
+ } else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Quick check if any archived revisions are present for the page.
+ * @return bool
+ */
+ function isDeleted() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
+ array( 'ar_namespace' => $this->title->getNamespace(),
+ 'ar_title' => $this->title->getDBkey() ) );
+ return ($n > 0);
+ }
+
+ /**
+ * Restore the given (or all) text and file revisions for the page.
+ * Once restored, the items will be removed from the archive tables.
+ * The deletion log will be updated with an undeletion notice.
+ *
+ * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete.
+ * @param string $comment
+ * @param array $fileVersions
+ *
+ * @return true on success.
+ */
+ function undelete( $timestamps, $comment = '', $fileVersions = array() ) {
+ // If both the set of text revisions and file revisions are empty,
+ // restore everything. Otherwise, just restore the requested items.
+ $restoreAll = empty( $timestamps ) && empty( $fileVersions );
+
+ $restoreText = $restoreAll || !empty( $timestamps );
+ $restoreFiles = $restoreAll || !empty( $fileVersions );
+
+ if( $restoreFiles && $this->title->getNamespace() == NS_IMAGE ) {
+ $img = new Image( $this->title );
+ $filesRestored = $img->restore( $fileVersions );
+ } else {
+ $filesRestored = 0;
+ }
+
+ if( $restoreText ) {
+ $textRestored = $this->undeleteRevisions( $timestamps );
+ } else {
+ $textRestored = 0;
+ }
+
+ // Touch the log!
+ global $wgContLang;
+ $log = new LogPage( 'delete' );
+
+ if( $textRestored && $filesRestored ) {
+ $reason = wfMsgForContent( 'undeletedrevisions-files',
+ $wgContLang->formatNum( $textRestored ),
+ $wgContLang->formatNum( $filesRestored ) );
+ } elseif( $textRestored ) {
+ $reason = wfMsgForContent( 'undeletedrevisions',
+ $wgContLang->formatNum( $textRestored ) );
+ } elseif( $filesRestored ) {
+ $reason = wfMsgForContent( 'undeletedfiles',
+ $wgContLang->formatNum( $filesRestored ) );
+ } else {
+ wfDebug( "Undelete: nothing undeleted...\n" );
+ return false;
+ }
+
+ if( trim( $comment ) != '' )
+ $reason .= ": {$comment}";
+ $log->addEntry( 'restore', $this->title, $reason );
+
+ return true;
+ }
+
+ /**
+ * This is the meaty bit -- restores archived revisions of the given page
+ * to the cur/old tables. If the page currently exists, all revisions will
+ * be stuffed into old, otherwise the most recent will go into cur.
+ *
+ * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete.
+ * @param string $comment
+ * @param array $fileVersions
+ *
+ * @return int number of revisions restored
+ */
+ private function undeleteRevisions( $timestamps ) {
+ global $wgDBtype;
+
+ $restoreAll = empty( $timestamps );
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $page = $dbw->tableName( 'archive' );
+
+ # Does this page already exist? We'll have to update it...
+ $article = new Article( $this->title );
+ $options = ( $wgDBtype == 'postgres' )
+ ? '' // pg doesn't support this?
+ : 'FOR UPDATE';
+ $page = $dbw->selectRow( 'page',
+ array( 'page_id', 'page_latest' ),
+ array( 'page_namespace' => $this->title->getNamespace(),
+ 'page_title' => $this->title->getDBkey() ),
+ __METHOD__,
+ $options );
+ if( $page ) {
+ # Page already exists. Import the history, and if necessary
+ # we'll update the latest revision field in the record.
+ $newid = 0;
+ $pageId = $page->page_id;
+ $previousRevId = $page->page_latest;
+ } else {
+ # Have to create a new article...
+ $newid = $article->insertOn( $dbw );
+ $pageId = $newid;
+ $previousRevId = 0;
+ }
+
+ if( $restoreAll ) {
+ $oldones = '1 = 1'; # All revisions...
+ } else {
+ $oldts = implode( ',',
+ array_map( array( &$dbw, 'addQuotes' ),
+ array_map( array( &$dbw, 'timestamp' ),
+ $timestamps ) ) );
+
+ $oldones = "ar_timestamp IN ( {$oldts} )";
+ }
+
+ /**
+ * Restore each revision...
+ */
+ $result = $dbw->select( 'archive',
+ /* fields */ array(
+ 'ar_rev_id',
+ 'ar_text',
+ 'ar_comment',
+ 'ar_user',
+ 'ar_user_text',
+ 'ar_timestamp',
+ 'ar_minor_edit',
+ 'ar_flags',
+ 'ar_text_id' ),
+ /* WHERE */ array(
+ 'ar_namespace' => $this->title->getNamespace(),
+ 'ar_title' => $this->title->getDBkey(),
+ $oldones ),
+ __METHOD__,
+ /* options */ array(
+ 'ORDER BY' => 'ar_timestamp' )
+ );
+ if( $dbw->numRows( $result ) < count( $timestamps ) ) {
+ wfDebug( __METHOD__.": couldn't find all requested rows\n" );
+ return false;
+ }
+
+ $revision = null;
+ $restored = 0;
+
+ while( $row = $dbw->fetchObject( $result ) ) {
+ if( $row->ar_text_id ) {
+ // Revision was deleted in 1.5+; text is in
+ // the regular text table, use the reference.
+ // Specify null here so the so the text is
+ // dereferenced for page length info if needed.
+ $revText = null;
+ } else {
+ // Revision was deleted in 1.4 or earlier.
+ // Text is squashed into the archive row, and
+ // a new text table entry will be created for it.
+ $revText = Revision::getRevisionText( $row, 'ar_' );
+ }
+ $revision = new Revision( array(
+ 'page' => $pageId,
+ 'id' => $row->ar_rev_id,
+ 'text' => $revText,
+ 'comment' => $row->ar_comment,
+ 'user' => $row->ar_user,
+ 'user_text' => $row->ar_user_text,
+ 'timestamp' => $row->ar_timestamp,
+ 'minor_edit' => $row->ar_minor_edit,
+ 'text_id' => $row->ar_text_id,
+ ) );
+ $revision->insertOn( $dbw );
+ $restored++;
+ }
+
+ if( $revision ) {
+ # FIXME: Update latest if newer as well...
+ if( $newid ) {
+ // Attach the latest revision to the page...
+ $article->updateRevisionOn( $dbw, $revision, $previousRevId );
+
+ // Update site stats, link tables, etc
+ $article->createUpdates( $revision );
+ }
+
+ if( $newid ) {
+ Article::onArticleCreate( $this->title );
+ } else {
+ Article::onArticleEdit( $this->title );
+ }
+ } else {
+ # Something went terribly wrong!
+ }
+
+ # Now that it's safely stored, take it out of the archive
+ $dbw->delete( 'archive',
+ /* WHERE */ array(
+ 'ar_namespace' => $this->title->getNamespace(),
+ 'ar_title' => $this->title->getDBkey(),
+ $oldones ),
+ __METHOD__ );
+
+ return $restored;
+ }
+
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UndeleteForm {
+ var $mAction, $mTarget, $mTimestamp, $mRestore, $mTargetObj;
+ var $mTargetTimestamp, $mAllowed, $mComment;
+
+ function UndeleteForm( &$request, $par = "" ) {
+ global $wgUser;
+ $this->mAction = $request->getVal( 'action' );
+ $this->mTarget = $request->getVal( 'target' );
+ $time = $request->getVal( 'timestamp' );
+ $this->mTimestamp = $time ? wfTimestamp( TS_MW, $time ) : '';
+ $this->mFile = $request->getVal( 'file' );
+
+ $posted = $request->wasPosted() &&
+ $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
+ $this->mRestore = $request->getCheck( 'restore' ) && $posted;
+ $this->mPreview = $request->getCheck( 'preview' ) && $posted;
+ $this->mComment = $request->getText( 'wpComment' );
+
+ if( $par != "" ) {
+ $this->mTarget = $par;
+ }
+ if ( $wgUser->isAllowed( 'delete' ) && !$wgUser->isBlocked() ) {
+ $this->mAllowed = true;
+ } else {
+ $this->mAllowed = false;
+ $this->mTimestamp = '';
+ $this->mRestore = false;
+ }
+ if ( $this->mTarget !== "" ) {
+ $this->mTargetObj = Title::newFromURL( $this->mTarget );
+ } else {
+ $this->mTargetObj = NULL;
+ }
+ if( $this->mRestore ) {
+ $timestamps = array();
+ $this->mFileVersions = array();
+ foreach( $_REQUEST as $key => $val ) {
+ $matches = array();
+ if( preg_match( '/^ts(\d{14})$/', $key, $matches ) ) {
+ array_push( $timestamps, $matches[1] );
+ }
+
+ if( preg_match( '/^fileid(\d+)$/', $key, $matches ) ) {
+ $this->mFileVersions[] = intval( $matches[1] );
+ }
+ }
+ rsort( $timestamps );
+ $this->mTargetTimestamp = $timestamps;
+ }
+ }
+
+ function execute() {
+
+ if( is_null( $this->mTargetObj ) ) {
+ return $this->showList();
+ }
+ if( $this->mTimestamp !== '' ) {
+ return $this->showRevision( $this->mTimestamp );
+ }
+ if( $this->mFile !== null ) {
+ return $this->showFile( $this->mFile );
+ }
+ if( $this->mRestore && $this->mAction == "submit" ) {
+ return $this->undelete();
+ }
+ return $this->showHistory();
+ }
+
+ /* private */ function showList() {
+ global $wgLang, $wgContLang, $wgUser, $wgOut;
+
+ # List undeletable articles
+ $result = PageArchive::listAllPages();
+
+ if ( $this->mAllowed ) {
+ $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
+ } else {
+ $wgOut->setPagetitle( wfMsg( "viewdeletedpage" ) );
+ }
+ $wgOut->addWikiText( wfMsg( "undeletepagetext" ) );
+
+ $sk = $wgUser->getSkin();
+ $undelete = SpecialPage::getTitleFor( 'Undelete' );
+ $wgOut->addHTML( "<ul>\n" );
+ while( $row = $result->fetchObject() ) {
+ $title = Title::makeTitleSafe( $row->ar_namespace, $row->ar_title );
+ $link = $sk->makeKnownLinkObj( $undelete, htmlspecialchars( $title->getPrefixedText() ), 'target=' . $title->getPrefixedUrl() );
+ $revs = wfMsgHtml( 'undeleterevisions', $wgLang->formatNum( $row->count ) );
+ $wgOut->addHtml( "<li>{$link} ({$revs})</li>\n" );
+ }
+ $result->free();
+ $wgOut->addHTML( "</ul>\n" );
+
+ return true;
+ }
+
+ /* private */ function showRevision( $timestamp ) {
+ global $wgLang, $wgUser, $wgOut;
+
+ if(!preg_match("/[0-9]{14}/",$timestamp)) return 0;
+
+ $archive = new PageArchive( $this->mTargetObj );
+ $rev = $archive->getRevision( $timestamp );
+
+ $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
+ $wgOut->addWikiText( "(" . wfMsg( "undeleterevision",
+ $wgLang->timeAndDate( $timestamp ) ) . ")\n" );
+
+ if( !$rev ) {
+ $wgOut->addWikiText( wfMsg( 'undeleterevision-missing' ) );
+ return;
+ }
+
+ wfRunHooks( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) );
+
+ if( $this->mPreview ) {
+ $wgOut->addHtml( "<hr />\n" );
+ $article = new Article ( $archive->title ); # OutputPage wants an Article obj
+ $wgOut->addPrimaryWikiText( $rev->getText(), $article, false );
+ }
+
+ $self = SpecialPage::getTitleFor( "Undelete" );
+
+ $wgOut->addHtml(
+ wfElement( 'textarea', array(
+ 'readonly' => true,
+ 'cols' => intval( $wgUser->getOption( 'cols' ) ),
+ 'rows' => intval( $wgUser->getOption( 'rows' ) ) ),
+ $rev->getText() . "\n" ) .
+ wfOpenElement( 'div' ) .
+ wfOpenElement( 'form', array(
+ 'method' => 'post',
+ 'action' => $self->getLocalURL( "action=submit" ) ) ) .
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'target',
+ 'value' => $this->mTargetObj->getPrefixedDbKey() ) ) .
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'timestamp',
+ 'value' => $timestamp ) ) .
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'wpEditToken',
+ 'value' => $wgUser->editToken() ) ) .
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'preview',
+ 'value' => '1' ) ) .
+ wfElement( 'input', array(
+ 'type' => 'submit',
+ 'value' => wfMsg( 'showpreview' ) ) ) .
+ wfCloseElement( 'form' ) .
+ wfCloseElement( 'div' ) );
+ }
+
+ /**
+ * Show a deleted file version requested by the visitor.
+ */
+ function showFile( $key ) {
+ global $wgOut, $wgRequest;
+ $wgOut->disable();
+
+ # We mustn't allow the output to be Squid cached, otherwise
+ # if an admin previews a deleted image, and it's cached, then
+ # a user without appropriate permissions can toddle off and
+ # nab the image, and Squid will serve it
+ $wgRequest->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
+ $wgRequest->response()->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
+ $wgRequest->response()->header( 'Pragma: no-cache' );
+
+ $store = FileStore::get( 'deleted' );
+ $store->stream( $key );
+ }
+
+ /* private */ function showHistory() {
+ global $wgLang, $wgUser, $wgOut;
+
+ $sk = $wgUser->getSkin();
+ if ( $this->mAllowed ) {
+ $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
+ } else {
+ $wgOut->setPagetitle( wfMsg( 'viewdeletedpage' ) );
+ }
+
+ $archive = new PageArchive( $this->mTargetObj );
+ /*
+ $text = $archive->getLastRevisionText();
+ if( is_null( $text ) ) {
+ $wgOut->addWikiText( wfMsg( "nohistory" ) );
+ return;
+ }
+ */
+ if ( $this->mAllowed ) {
+ $wgOut->addWikiText( wfMsg( "undeletehistory" ) );
+ } else {
+ $wgOut->addWikiText( wfMsg( "undeletehistorynoadmin" ) );
+ }
+
+ # List all stored revisions
+ $revisions = $archive->listRevisions();
+ $files = $archive->listFiles();
+
+ $haveRevisions = $revisions && $revisions->numRows() > 0;
+ $haveFiles = $files && $files->numRows() > 0;
+
+ # Batch existence check on user and talk pages
+ if( $haveRevisions ) {
+ $batch = new LinkBatch();
+ while( $row = $revisions->fetchObject() ) {
+ $batch->addObj( Title::makeTitleSafe( NS_USER, $row->ar_user_text ) );
+ $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ar_user_text ) );
+ }
+ $batch->execute();
+ $revisions->seek( 0 );
+ }
+ if( $haveFiles ) {
+ $batch = new LinkBatch();
+ while( $row = $files->fetchObject() ) {
+ $batch->addObj( Title::makeTitleSafe( NS_USER, $row->fa_user_text ) );
+ $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->fa_user_text ) );
+ }
+ $batch->execute();
+ $files->seek( 0 );
+ }
+
+ if ( $this->mAllowed ) {
+ $titleObj = SpecialPage::getTitleFor( "Undelete" );
+ $action = $titleObj->getLocalURL( "action=submit" );
+ # Start the form here
+ $top = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $action, 'id' => 'undelete' ) );
+ $wgOut->addHtml( $top );
+ }
+
+ # Show relevant lines from the deletion log:
+ $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
+ $logViewer = new LogViewer(
+ new LogReader(
+ new FauxRequest(
+ array( 'page' => $this->mTargetObj->getPrefixedText(),
+ 'type' => 'delete' ) ) ) );
+ $logViewer->showList( $wgOut );
+
+ if( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) {
+ # Format the user-visible controls (comment field, submission button)
+ # in a nice little table
+ $table = '<fieldset><table><tr>';
+ $table .= '<td colspan="2">' . wfMsgWikiHtml( 'undeleteextrahelp' ) . '</td></tr><tr>';
+ $table .= '<td align="right"><strong>' . wfMsgHtml( 'undeletecomment' ) . '</strong></td>';
+ $table .= '<td>' . wfInput( 'wpComment', 50, $this->mComment ) . '</td>';
+ $table .= '</tr><tr><td>&nbsp;</td><td>';
+ $table .= wfSubmitButton( wfMsg( 'undeletebtn' ), array( 'name' => 'restore' ) );
+ $table .= wfElement( 'input', array( 'type' => 'reset', 'value' => wfMsg( 'undeletereset' ) ) );
+ $table .= '</td></tr></table></fieldset>';
+ $wgOut->addHtml( $table );
+ }
+
+ $wgOut->addHTML( "<h2>" . htmlspecialchars( wfMsg( "history" ) ) . "</h2>\n" );
+
+ if( $haveRevisions ) {
+ # The page's stored (deleted) history:
+ $wgOut->addHTML("<ul>");
+ $target = urlencode( $this->mTarget );
+ while( $row = $revisions->fetchObject() ) {
+ $ts = wfTimestamp( TS_MW, $row->ar_timestamp );
+ if ( $this->mAllowed ) {
+ $checkBox = wfCheck( "ts$ts" );
+ $pageLink = $sk->makeKnownLinkObj( $titleObj,
+ $wgLang->timeanddate( $ts, true ),
+ "target=$target&timestamp=$ts" );
+ } else {
+ $checkBox = '';
+ $pageLink = $wgLang->timeanddate( $ts, true );
+ }
+ $userLink = $sk->userLink( $row->ar_user, $row->ar_user_text ) . $sk->userToolLinks( $row->ar_user, $row->ar_user_text );
+ $comment = $sk->commentBlock( $row->ar_comment );
+ $wgOut->addHTML( "<li>$checkBox $pageLink . . $userLink $comment</li>\n" );
+
+ }
+ $revisions->free();
+ $wgOut->addHTML("</ul>");
+ } else {
+ $wgOut->addWikiText( wfMsg( "nohistory" ) );
+ }
+
+
+ if( $haveFiles ) {
+ $wgOut->addHtml( "<h2>" . wfMsgHtml( 'imghistory' ) . "</h2>\n" );
+ $wgOut->addHtml( "<ul>" );
+ while( $row = $files->fetchObject() ) {
+ $ts = wfTimestamp( TS_MW, $row->fa_timestamp );
+ if ( $this->mAllowed && $row->fa_storage_key ) {
+ $checkBox = wfCheck( "fileid" . $row->fa_id );
+ $key = urlencode( $row->fa_storage_key );
+ $target = urlencode( $this->mTarget );
+ $pageLink = $sk->makeKnownLinkObj( $titleObj,
+ $wgLang->timeanddate( $ts, true ),
+ "target=$target&file=$key" );
+ } else {
+ $checkBox = '';
+ $pageLink = $wgLang->timeanddate( $ts, true );
+ }
+ $userLink = $sk->userLink( $row->fa_user, $row->fa_user_text ) . $sk->userToolLinks( $row->fa_user, $row->fa_user_text );
+ $data =
+ wfMsgHtml( 'widthheight',
+ $wgLang->formatNum( $row->fa_width ),
+ $wgLang->formatNum( $row->fa_height ) ) .
+ ' (' .
+ wfMsgHtml( 'nbytes', $wgLang->formatNum( $row->fa_size ) ) .
+ ')';
+ $comment = $sk->commentBlock( $row->fa_description );
+ $wgOut->addHTML( "<li>$checkBox $pageLink . . $userLink $data $comment</li>\n" );
+ }
+ $files->free();
+ $wgOut->addHTML( "</ul>" );
+ }
+
+ if ( $this->mAllowed ) {
+ # Slip in the hidden controls here
+ $misc = wfHidden( 'target', $this->mTarget );
+ $misc .= wfHidden( 'wpEditToken', $wgUser->editToken() );
+ $wgOut->addHtml( $misc . '</form>' );
+ }
+
+ return true;
+ }
+
+ function undelete() {
+ global $wgOut, $wgUser;
+ if( !is_null( $this->mTargetObj ) ) {
+ $archive = new PageArchive( $this->mTargetObj );
+
+ $ok = $archive->undelete(
+ $this->mTargetTimestamp,
+ $this->mComment,
+ $this->mFileVersions );
+
+ if( $ok ) {
+ $skin =& $wgUser->getSkin();
+ $link = $skin->makeKnownLinkObj( $this->mTargetObj );
+ $wgOut->addHtml( wfMsgWikiHtml( 'undeletedpage', $link ) );
+ return true;
+ }
+ }
+ $wgOut->showFatalError( wfMsg( "cannotundelete" ) );
+ return false;
+ }
+}
+
+?>
diff --git a/includes/SpecialUnlockdb.php b/includes/SpecialUnlockdb.php
new file mode 100644
index 000000000000..1f24d131c01d
--- /dev/null
+++ b/includes/SpecialUnlockdb.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+function wfSpecialUnlockdb() {
+ global $wgUser, $wgOut, $wgRequest;
+
+ if( !$wgUser->isAllowed( 'siteadmin' ) ) {
+ $wgOut->permissionRequired( 'siteadmin' );
+ return;
+ }
+
+ $action = $wgRequest->getVal( 'action' );
+ $f = new DBUnlockForm();
+
+ if ( "success" == $action ) {
+ $f->showSuccess();
+ } else if ( "submit" == $action && $wgRequest->wasPosted() &&
+ $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
+ $f->doSubmit();
+ } else {
+ $f->showForm( "" );
+ }
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class DBUnlockForm {
+ function showForm( $err )
+ {
+ global $wgOut, $wgUser;
+
+ global $wgReadOnlyFile;
+ if( !file_exists( $wgReadOnlyFile ) ) {
+ $wgOut->addWikiText( wfMsg( 'databasenotlocked' ) );
+ return;
+ }
+
+ $wgOut->setPagetitle( wfMsg( "unlockdb" ) );
+ $wgOut->addWikiText( wfMsg( "unlockdbtext" ) );
+
+ if ( "" != $err ) {
+ $wgOut->setSubtitle( wfMsg( "formerror" ) );
+ $wgOut->addHTML( '<p class="error">' . htmlspecialchars( $err ) . "</p>\n" );
+ }
+ $lc = htmlspecialchars( wfMsg( "unlockconfirm" ) );
+ $lb = htmlspecialchars( wfMsg( "unlockbtn" ) );
+ $titleObj = SpecialPage::getTitleFor( "Unlockdb" );
+ $action = $titleObj->escapeLocalURL( "action=submit" );
+ $token = htmlspecialchars( $wgUser->editToken() );
+
+ $wgOut->addHTML( <<<END
+
+<form id="unlockdb" method="post" action="{$action}">
+<table border="0">
+ <tr>
+ <td align="right">
+ <input type="checkbox" name="wpLockConfirm" />
+ </td>
+ <td align="left">{$lc}</td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td align="left">
+ <input type="submit" name="wpLock" value="{$lb}" />
+ </td>
+ </tr>
+</table>
+<input type="hidden" name="wpEditToken" value="{$token}" />
+</form>
+END
+);
+
+ }
+
+ function doSubmit() {
+ global $wgOut, $wgRequest, $wgReadOnlyFile;
+
+ $wpLockConfirm = $wgRequest->getCheck( 'wpLockConfirm' );
+ if ( ! $wpLockConfirm ) {
+ $this->showForm( wfMsg( "locknoconfirm" ) );
+ return;
+ }
+ if ( @! unlink( $wgReadOnlyFile ) ) {
+ $wgOut->showFileDeleteError( $wgReadOnlyFile );
+ return;
+ }
+ $titleObj = SpecialPage::getTitleFor( "Unlockdb" );
+ $success = $titleObj->getFullURL( "action=success" );
+ $wgOut->redirect( $success );
+ }
+
+ function showSuccess() {
+ global $wgOut;
+ global $ip;
+
+ $wgOut->setPagetitle( wfMsg( "unlockdb" ) );
+ $wgOut->setSubtitle( wfMsg( "unlockdbsuccesssub" ) );
+ $wgOut->addWikiText( wfMsg( "unlockdbsuccesstext", $ip ) );
+ }
+}
+
+?>
diff --git a/includes/SpecialUnusedcategories.php b/includes/SpecialUnusedcategories.php
new file mode 100644
index 000000000000..80f46a879899
--- /dev/null
+++ b/includes/SpecialUnusedcategories.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UnusedCategoriesPage extends QueryPage {
+
+ function getName() {
+ return 'Unusedcategories';
+ }
+
+ function getPageHeader() {
+ return '<p>' . wfMsg('unusedcategoriestext') . '</p>';
+ }
+
+ function getSQL() {
+ $NScat = NS_CATEGORY;
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $categorylinks, $page ) = $dbr->tableNamesN( 'categorylinks', 'page' );
+ return "SELECT 'Unusedcategories' as type,
+ {$NScat} as namespace, page_title as title, page_title as value
+ FROM $page
+ LEFT JOIN $categorylinks ON page_title=cl_to
+ WHERE cl_from IS NULL
+ AND page_namespace = {$NScat}
+ AND page_is_redirect = 0";
+ }
+
+ function formatResult( $skin, $result ) {
+ $title = Title::makeTitle( NS_CATEGORY, $result->title );
+ return $skin->makeLinkObj( $title, $title->getText() );
+ }
+}
+
+/** constructor */
+function wfSpecialUnusedCategories() {
+ list( $limit, $offset ) = wfCheckLimits();
+ $uc = new UnusedCategoriesPage();
+ return $uc->doQuery( $offset, $limit );
+}
+?>
diff --git a/includes/SpecialUnusedimages.php b/includes/SpecialUnusedimages.php
new file mode 100644
index 000000000000..75d702c852f6
--- /dev/null
+++ b/includes/SpecialUnusedimages.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UnusedimagesPage extends QueryPage {
+
+ function getName() {
+ return 'Unusedimages';
+ }
+
+ function sortDescending() {
+ return false;
+ }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ global $wgCountCategorizedImagesAsUsed;
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ if ( $wgCountCategorizedImagesAsUsed ) {
+ list( $page, $image, $imagelinks, $categorylinks ) = $dbr->tableNamesN( 'page', 'image', 'imagelinks', 'categorylinks' );
+
+ return 'SELECT img_name as title, img_user, img_user_text, img_timestamp as value, img_description
+ FROM ((('.$page.' AS I LEFT JOIN '.$categorylinks.' AS L ON I.page_id = L.cl_from)
+ LEFT JOIN '.$imagelinks.' AS P ON I.page_title = P.il_to)
+ INNER JOIN '.$image.' AS G ON I.page_title = G.img_name)
+ WHERE I.page_namespace = '.NS_IMAGE.' AND L.cl_from IS NULL AND P.il_to IS NULL';
+ } else {
+ list( $image, $imagelinks ) = $dbr->tableNamesN( 'image','imagelinks' );
+
+ return 'SELECT img_name as title, img_user, img_user_text, img_timestamp as value, img_description' .
+ ' FROM '.$image.' LEFT JOIN '.$imagelinks.' ON img_name=il_to WHERE il_to IS NULL ';
+ }
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+ $title = Title::makeTitle( NS_IMAGE, $result->title );
+
+ $imageUrl = htmlspecialchars( Image::imageUrl( $result->title ) );
+ $dirmark = $wgContLang->getDirMark(); // To keep text in correct order
+
+ $return =
+ # The 'desc' linking to the image page
+ '('.$skin->makeKnownLinkObj( $title, wfMsg('imgdesc') ).') ' . $dirmark .
+
+ # Link to the image itself
+ '<a href="' . $imageUrl . '">' . htmlspecialchars( $title->getText() ) .
+ '</a> . . ' . $dirmark .
+
+ # Last modified date
+ $wgLang->timeanddate($result->value) . ' . . ' . $dirmark .
+
+ # Link to username
+ $skin->makeLinkObj( Title::makeTitle( NS_USER, $result->img_user_text ),
+ $result->img_user_text) . $dirmark .
+
+ # If there is a description, show it
+ $skin->commentBlock( $wgContLang->convert( $result->img_description ) );
+
+ return $return;
+ }
+
+ function getPageHeader() {
+ return wfMsg( "unusedimagestext" );
+ }
+
+}
+
+/**
+ * Entry point
+ */
+function wfSpecialUnusedimages() {
+ list( $limit, $offset ) = wfCheckLimits();
+ $uip = new UnusedimagesPage();
+
+ return $uip->doQuery( $offset, $limit );
+}
+?>
diff --git a/includes/SpecialUnusedtemplates.php b/includes/SpecialUnusedtemplates.php
new file mode 100644
index 000000000000..2af9abc60d33
--- /dev/null
+++ b/includes/SpecialUnusedtemplates.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @package MediaWiki
+ * @subpackage Special pages
+ *
+ * @author Rob Church <robchur@gmail.com>
+ * @copyright © 2006 Rob Church
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+class UnusedtemplatesPage extends QueryPage {
+
+ function getName() { return( 'Unusedtemplates' ); }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+ function sortDescending() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $templatelinks) = $dbr->tableNamesN( 'page', 'templatelinks' );
+ $sql = "SELECT 'Unusedtemplates' AS type, page_title AS title,
+ page_namespace AS namespace, 0 AS value
+ FROM $page
+ LEFT JOIN $templatelinks
+ ON page_namespace = tl_namespace AND page_title = tl_title
+ WHERE page_namespace = 10 AND tl_from IS NULL";
+ return $sql;
+ }
+
+ function formatResult( $skin, $result ) {
+ $title = Title::makeTitle( NS_TEMPLATE, $result->title );
+ $pageLink = $skin->makeKnownLinkObj( $title, '', 'redirect=no' );
+ $wlhLink = $skin->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Whatlinkshere' ),
+ wfMsgHtml( 'unusedtemplateswlh' ),
+ 'target=' . $title->getPrefixedUrl() );
+ return wfSpecialList( $pageLink, $wlhLink );
+ }
+
+ function getPageHeader() {
+ global $wgOut;
+ return $wgOut->parse( wfMsg( 'unusedtemplatestext' ) );
+ }
+
+}
+
+function wfSpecialUnusedtemplates() {
+ list( $limit, $offset ) = wfCheckLimits();
+ $utp = new UnusedtemplatesPage();
+ $utp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialUnwatchedpages.php b/includes/SpecialUnwatchedpages.php
new file mode 100644
index 000000000000..f9dff724a3c5
--- /dev/null
+++ b/includes/SpecialUnwatchedpages.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * A special page that displays a list of pages that are not on anyones watchlist
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UnwatchedpagesPage extends QueryPage {
+
+ function getName() { return 'Unwatchedpages'; }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $page, $watchlist ) = $dbr->tableNamesN( 'page', 'watchlist' );
+ $mwns = NS_MEDIAWIKI;
+ return
+ "
+ SELECT
+ 'Unwatchedpages' as type,
+ page_namespace as namespace,
+ page_title as title,
+ page_namespace as value
+ FROM $page
+ LEFT JOIN $watchlist ON wl_namespace = page_namespace AND page_title = wl_title
+ WHERE wl_title IS NULL AND page_is_redirect = 0 AND page_namespace<>$mwns
+ ";
+ }
+
+ function sortDescending() { return false; }
+
+ function formatResult( $skin, $result ) {
+ global $wgContLang;
+
+ $nt = Title::makeTitle( $result->namespace, $result->title );
+ $text = $wgContLang->convert( $nt->getPrefixedText() );
+
+ $plink = $skin->makeKnownLinkObj( $nt, htmlspecialchars( $text ) );
+ $wlink = $skin->makeKnownLinkObj( $nt, wfMsgHtml( 'watch' ), 'action=watch' );
+
+ return wfSpecialList( $plink, $wlink );
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialUnwatchedpages() {
+ global $wgUser, $wgOut;
+
+ if ( ! $wgUser->isAllowed( 'unwatchedpages' ) )
+ return $wgOut->permissionRequired( 'unwatchedpages' );
+
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $wpp = new UnwatchedpagesPage();
+
+ $wpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialUpload.php b/includes/SpecialUpload.php
new file mode 100644
index 000000000000..d2fd839cd20f
--- /dev/null
+++ b/includes/SpecialUpload.php
@@ -0,0 +1,1260 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+
+/**
+ * Entry point
+ */
+function wfSpecialUpload() {
+ global $wgRequest;
+ $form = new UploadForm( $wgRequest );
+ $form->execute();
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UploadForm {
+ /**#@+
+ * @access private
+ */
+ var $mUploadFile, $mUploadDescription, $mLicense ,$mIgnoreWarning, $mUploadError;
+ var $mUploadSaveName, $mUploadTempName, $mUploadSize, $mUploadOldVersion;
+ var $mUploadCopyStatus, $mUploadSource, $mReUpload, $mAction, $mUpload;
+ var $mOname, $mSessionKey, $mStashed, $mDestFile, $mRemoveTempFile, $mSourceType;
+ var $mUploadTempFileSize = 0;
+
+ # Placeholders for text injection by hooks (must be HTML)
+ # extensions should take care to _append_ to the present value
+ var $uploadFormTextTop;
+ var $uploadFormTextAfterSummary;
+
+ /**#@-*/
+
+ /**
+ * Constructor : initialise object
+ * Get data POSTed through the form and assign them to the object
+ * @param $request Data posted.
+ */
+ function UploadForm( &$request ) {
+ global $wgAllowCopyUploads;
+ $this->mDestFile = $request->getText( 'wpDestFile' );
+
+ if( !$request->wasPosted() ) {
+ # GET requests just give the main form; no data except wpDestfile.
+ return;
+ }
+
+ # Placeholders for text injection by hooks (empty per default)
+ $this->uploadFormTextTop = "";
+ $this->uploadFormTextAfterSummary = "";
+
+ $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' );
+ $this->mReUpload = $request->getCheck( 'wpReUpload' );
+ $this->mUpload = $request->getCheck( 'wpUpload' );
+
+ $this->mUploadDescription = $request->getText( 'wpUploadDescription' );
+ $this->mLicense = $request->getText( 'wpLicense' );
+ $this->mUploadCopyStatus = $request->getText( 'wpUploadCopyStatus' );
+ $this->mUploadSource = $request->getText( 'wpUploadSource' );
+ $this->mWatchthis = $request->getBool( 'wpWatchthis' );
+ $this->mSourceType = $request->getText( 'wpSourceType' );
+ wfDebug( "UploadForm: watchthis is: '$this->mWatchthis'\n" );
+
+ $this->mAction = $request->getVal( 'action' );
+
+ $this->mSessionKey = $request->getInt( 'wpSessionKey' );
+ if( !empty( $this->mSessionKey ) &&
+ isset( $_SESSION['wsUploadData'][$this->mSessionKey] ) ) {
+ /**
+ * Confirming a temporarily stashed upload.
+ * We don't want path names to be forged, so we keep
+ * them in the session on the server and just give
+ * an opaque key to the user agent.
+ */
+ $data = $_SESSION['wsUploadData'][$this->mSessionKey];
+ $this->mUploadTempName = $data['mUploadTempName'];
+ $this->mUploadSize = $data['mUploadSize'];
+ $this->mOname = $data['mOname'];
+ $this->mUploadError = 0/*UPLOAD_ERR_OK*/;
+ $this->mStashed = true;
+ $this->mRemoveTempFile = false;
+ } else {
+ /**
+ *Check for a newly uploaded file.
+ */
+ if( $wgAllowCopyUploads && $this->mSourceType == 'web' ) {
+ $this->initializeFromUrl( $request );
+ } else {
+ $this->initializeFromUpload( $request );
+ }
+ }
+ }
+
+ /**
+ * Initialize the uploaded file from PHP data
+ * @access private
+ */
+ function initializeFromUpload( $request ) {
+ $this->mUploadTempName = $request->getFileTempName( 'wpUploadFile' );
+ $this->mUploadSize = $request->getFileSize( 'wpUploadFile' );
+ $this->mOname = $request->getFileName( 'wpUploadFile' );
+ $this->mUploadError = $request->getUploadError( 'wpUploadFile' );
+ $this->mSessionKey = false;
+ $this->mStashed = false;
+ $this->mRemoveTempFile = false; // PHP will handle this
+ }
+
+ /**
+ * Copy a web file to a temporary file
+ * @access private
+ */
+ function initializeFromUrl( $request ) {
+ global $wgTmpDirectory;
+ $url = $request->getText( 'wpUploadFileURL' );
+ $local_file = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
+
+ $this->mUploadTempName = $local_file;
+ $this->mUploadError = $this->curlCopy( $url, $local_file );
+ $this->mUploadSize = $this->mUploadTempFileSize;
+ $this->mOname = array_pop( explode( '/', $url ) );
+ $this->mSessionKey = false;
+ $this->mStashed = false;
+
+ // PHP won't auto-cleanup the file
+ $this->mRemoveTempFile = file_exists( $local_file );
+ }
+
+ /**
+ * Safe copy from URL
+ * Returns true if there was an error, false otherwise
+ */
+ private function curlCopy( $url, $dest ) {
+ global $wgUser, $wgOut;
+
+ if( !$wgUser->isAllowed( 'upload_by_url' ) ) {
+ $wgOut->permissionRequired( 'upload_by_url' );
+ return true;
+ }
+
+ # Maybe remove some pasting blanks :-)
+ $url = trim( $url );
+ if( stripos($url, 'http://') !== 0 && stripos($url, 'ftp://') !== 0 ) {
+ # Only HTTP or FTP URLs
+ $wgOut->errorPage( 'upload-proto-error', 'upload-proto-error-text' );
+ return true;
+ }
+
+ # Open temporary file
+ $this->mUploadTempFile = @fopen( $this->mUploadTempName, "wb" );
+ if( $this->mUploadTempFile === false ) {
+ # Could not open temporary file to write in
+ $wgOut->errorPage( 'upload-file-error', 'upload-file-error-text');
+ return true;
+ }
+
+ $ch = curl_init();
+ curl_setopt( $ch, CURLOPT_HTTP_VERSION, 1.0); # Probably not needed, but apparently can work around some bug
+ curl_setopt( $ch, CURLOPT_TIMEOUT, 10); # 10 seconds timeout
+ curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 512); # 0.5KB per second minimum transfer speed
+ curl_setopt( $ch, CURLOPT_URL, $url);
+ curl_setopt( $ch, CURLOPT_WRITEFUNCTION, array( $this, 'uploadCurlCallback' ) );
+ curl_exec( $ch );
+ $error = curl_errno( $ch ) ? true : false;
+ $errornum = curl_errno( $ch );
+ // if ( $error ) print curl_error ( $ch ) ; # Debugging output
+ curl_close( $ch );
+
+ fclose( $this->mUploadTempFile );
+ unset( $this->mUploadTempFile );
+ if( $error ) {
+ unlink( $dest );
+ if( wfEmptyMsg( "upload-curl-error$errornum", wfMsg("upload-curl-error$errornum") ) )
+ $wgOut->errorPage( 'upload-misc-error', 'upload-misc-error-text' );
+ else
+ $wgOut->errorPage( "upload-curl-error$errornum", "upload-curl-error$errornum-text" );
+ }
+
+ return $error;
+ }
+
+ /**
+ * Callback function for CURL-based web transfer
+ * Write data to file unless we've passed the length limit;
+ * if so, abort immediately.
+ * @access private
+ */
+ function uploadCurlCallback( $ch, $data ) {
+ global $wgMaxUploadSize;
+ $length = strlen( $data );
+ $this->mUploadTempFileSize += $length;
+ if( $this->mUploadTempFileSize > $wgMaxUploadSize ) {
+ return 0;
+ }
+ fwrite( $this->mUploadTempFile, $data );
+ return $length;
+ }
+
+ /**
+ * Start doing stuff
+ * @access public
+ */
+ function execute() {
+ global $wgUser, $wgOut;
+ global $wgEnableUploads, $wgUploadDirectory;
+
+ # Check uploading enabled
+ if( !$wgEnableUploads ) {
+ $wgOut->showErrorPage( 'uploaddisabled', 'uploaddisabledtext' );
+ return;
+ }
+
+ # Check permissions
+ if( !$wgUser->isAllowed( 'upload' ) ) {
+ if( !$wgUser->isLoggedIn() ) {
+ $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
+ } else {
+ $wgOut->permissionRequired( 'upload' );
+ }
+ return;
+ }
+
+ # Check blocks
+ if( $wgUser->isBlocked() ) {
+ $wgOut->blockedPage();
+ return;
+ }
+
+ if( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return;
+ }
+
+ /** Check if the image directory is writeable, this is a common mistake */
+ if( !is_writeable( $wgUploadDirectory ) ) {
+ $wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $wgUploadDirectory ) );
+ return;
+ }
+
+ if( $this->mReUpload ) {
+ if( !$this->unsaveUploadedFile() ) {
+ return;
+ }
+ $this->mainUploadForm();
+ } else if( 'submit' == $this->mAction || $this->mUpload ) {
+ $this->processUpload();
+ } else {
+ $this->mainUploadForm();
+ }
+
+ $this->cleanupTempFile();
+ }
+
+ /* -------------------------------------------------------------- */
+
+ /**
+ * Really do the upload
+ * Checks are made in SpecialUpload::execute()
+ * @access private
+ */
+ function processUpload() {
+ global $wgUser, $wgOut;
+
+ if( !wfRunHooks( 'UploadForm:BeforeProcessing', array( &$this ) ) )
+ {
+ wfDebug( "Hook 'UploadForm:BeforeProcessing' broke processing the file." );
+ return false;
+ }
+
+ /* Check for PHP error if any, requires php 4.2 or newer */
+ if( $this->mUploadError == 1/*UPLOAD_ERR_INI_SIZE*/ ) {
+ $this->mainUploadForm( wfMsgHtml( 'largefileserver' ) );
+ return;
+ }
+
+ /**
+ * If there was no filename or a zero size given, give up quick.
+ */
+ if( trim( $this->mOname ) == '' || empty( $this->mUploadSize ) ) {
+ $this->mainUploadForm( wfMsgHtml( 'emptyfile' ) );
+ return;
+ }
+
+ # Chop off any directories in the given filename
+ if( $this->mDestFile ) {
+ $basename = wfBaseName( $this->mDestFile );
+ } else {
+ $basename = wfBaseName( $this->mOname );
+ }
+
+ /**
+ * We'll want to blacklist against *any* 'extension', and use
+ * only the final one for the whitelist.
+ */
+ list( $partname, $ext ) = $this->splitExtensions( $basename );
+
+ if( count( $ext ) ) {
+ $finalExt = $ext[count( $ext ) - 1];
+ } else {
+ $finalExt = '';
+ }
+ $fullExt = implode( '.', $ext );
+
+ # If there was more than one "extension", reassemble the base
+ # filename to prevent bogus complaints about length
+ if( count( $ext ) > 1 ) {
+ for( $i = 0; $i < count( $ext ) - 1; $i++ )
+ $partname .= '.' . $ext[$i];
+ }
+
+ if( strlen( $partname ) < 3 ) {
+ $this->mainUploadForm( wfMsgHtml( 'minlength' ) );
+ return;
+ }
+
+ /**
+ * Filter out illegal characters, and try to make a legible name
+ * out of it. We'll strip some silently that Title would die on.
+ */
+ $filtered = preg_replace ( "/[^".Title::legalChars()."]|:/", '-', $basename );
+ $nt = Title::newFromText( $filtered );
+ if( is_null( $nt ) ) {
+ $this->uploadError( wfMsgWikiHtml( 'illegalfilename', htmlspecialchars( $filtered ) ) );
+ return;
+ }
+ $nt =& Title::makeTitle( NS_IMAGE, $nt->getDBkey() );
+ $this->mUploadSaveName = $nt->getDBkey();
+
+ /**
+ * If the image is protected, non-sysop users won't be able
+ * to modify it by uploading a new revision.
+ */
+ if( !$nt->userCanEdit() ) {
+ return $this->uploadError( wfMsgWikiHtml( 'protectedpage' ) );
+ }
+
+ /**
+ * In some cases we may forbid overwriting of existing files.
+ */
+ $overwrite = $this->checkOverwrite( $this->mUploadSaveName );
+ if( WikiError::isError( $overwrite ) ) {
+ return $this->uploadError( $overwrite->toString() );
+ }
+
+ /* Don't allow users to override the blacklist (check file extension) */
+ global $wgStrictFileExtensions;
+ global $wgFileExtensions, $wgFileBlacklist;
+ if( $this->checkFileExtensionList( $ext, $wgFileBlacklist ) ||
+ ($wgStrictFileExtensions &&
+ !$this->checkFileExtension( $finalExt, $wgFileExtensions ) ) ) {
+ return $this->uploadError( wfMsgHtml( 'badfiletype', htmlspecialchars( $finalExt ) ) );
+ }
+
+ /**
+ * Look at the contents of the file; if we can recognize the
+ * type but it's corrupt or data of the wrong type, we should
+ * probably not accept it.
+ */
+ if( !$this->mStashed ) {
+ $this->checkMacBinary();
+ $veri = $this->verify( $this->mUploadTempName, $finalExt );
+
+ if( $veri !== true ) { //it's a wiki error...
+ return $this->uploadError( $veri->toString() );
+ }
+ }
+
+ /**
+ * Provide an opportunity for extensions to add futher checks
+ */
+ $error = '';
+ if( !wfRunHooks( 'UploadVerification',
+ array( $this->mUploadSaveName, $this->mUploadTempName, &$error ) ) ) {
+ return $this->uploadError( $error );
+ }
+
+ /**
+ * Check for non-fatal conditions
+ */
+ if ( ! $this->mIgnoreWarning ) {
+ $warning = '';
+
+ global $wgCapitalLinks;
+ if( $wgCapitalLinks ) {
+ $filtered = ucfirst( $filtered );
+ }
+ if( $this->mUploadSaveName != $filtered ) {
+ $warning .= '<li>'.wfMsgHtml( 'badfilename', htmlspecialchars( $this->mUploadSaveName ) ).'</li>';
+ }
+
+ global $wgCheckFileExtensions;
+ if ( $wgCheckFileExtensions ) {
+ if ( ! $this->checkFileExtension( $finalExt, $wgFileExtensions ) ) {
+ $warning .= '<li>'.wfMsgHtml( 'badfiletype', htmlspecialchars( $finalExt ) ).'</li>';
+ }
+ }
+
+ global $wgUploadSizeWarning;
+ if ( $wgUploadSizeWarning && ( $this->mUploadSize > $wgUploadSizeWarning ) ) {
+ $skin =& $wgUser->getSkin();
+ $wsize = $skin->formatSize( $wgUploadSizeWarning );
+ $asize = $skin->formatSize( $this->mUploadSize );
+ $warning .= '<li>' . wfMsgHtml( 'large-file', $wsize, $asize ) . '</li>';
+ }
+ if ( $this->mUploadSize == 0 ) {
+ $warning .= '<li>'.wfMsgHtml( 'emptyfile' ).'</li>';
+ }
+
+ if( $nt->getArticleID() ) {
+ global $wgUser;
+ $sk = $wgUser->getSkin();
+ $dlink = $sk->makeKnownLinkObj( $nt );
+ $warning .= '<li>'.wfMsgHtml( 'fileexists', $dlink ).'</li>';
+ } else {
+ # If the file existed before and was deleted, warn the user of this
+ # Don't bother doing so if the image exists now, however
+ $image = new Image( $nt );
+ if( $image->wasDeleted() ) {
+ $skin = $wgUser->getSkin();
+ $ltitle = SpecialPage::getTitleFor( 'Log' );
+ $llink = $skin->makeKnownLinkObj( $ltitle, wfMsgHtml( 'deletionlog' ), 'type=delete&page=' . $nt->getPrefixedUrl() );
+ $warning .= wfOpenElement( 'li' ) . wfMsgWikiHtml( 'filewasdeleted', $llink ) . wfCloseElement( 'li' );
+ }
+ }
+
+ if( $warning != '' ) {
+ /**
+ * Stash the file in a temporary location; the user can choose
+ * to let it through and we'll complete the upload then.
+ */
+ return $this->uploadWarning( $warning );
+ }
+ }
+
+ /**
+ * Try actually saving the thing...
+ * It will show an error form on failure.
+ */
+ $hasBeenMunged = !empty( $this->mSessionKey ) || $this->mRemoveTempFile;
+ if( $this->saveUploadedFile( $this->mUploadSaveName,
+ $this->mUploadTempName,
+ $hasBeenMunged ) ) {
+ /**
+ * Update the upload log and create the description page
+ * if it's a new file.
+ */
+ $img = Image::newFromName( $this->mUploadSaveName );
+ $success = $img->recordUpload( $this->mUploadOldVersion,
+ $this->mUploadDescription,
+ $this->mLicense,
+ $this->mUploadCopyStatus,
+ $this->mUploadSource,
+ $this->mWatchthis );
+
+ if ( $success ) {
+ $this->showSuccess();
+ wfRunHooks( 'UploadComplete', array( &$img ) );
+ } else {
+ // Image::recordUpload() fails if the image went missing, which is
+ // unlikely, hence the lack of a specialised message
+ $wgOut->showFileNotFoundError( $this->mUploadSaveName );
+ }
+ }
+ }
+
+ /**
+ * Move the uploaded file from its temporary location to the final
+ * destination. If a previous version of the file exists, move
+ * it into the archive subdirectory.
+ *
+ * @todo If the later save fails, we may have disappeared the original file.
+ *
+ * @param string $saveName
+ * @param string $tempName full path to the temporary file
+ * @param bool $useRename if true, doesn't check that the source file
+ * is a PHP-managed upload temporary
+ */
+ function saveUploadedFile( $saveName, $tempName, $useRename = false ) {
+ global $wgOut, $wgAllowCopyUploads;
+
+ if ( !$useRename AND $wgAllowCopyUploads AND $this->mSourceType == 'web' ) $useRename = true;
+
+ $fname= "SpecialUpload::saveUploadedFile";
+
+ $dest = wfImageDir( $saveName );
+ $archive = wfImageArchiveDir( $saveName );
+ if ( !is_dir( $dest ) ) wfMkdirParents( $dest );
+ if ( !is_dir( $archive ) ) wfMkdirParents( $archive );
+
+ $this->mSavedFile = "{$dest}/{$saveName}";
+
+ if( is_file( $this->mSavedFile ) ) {
+ $this->mUploadOldVersion = gmdate( 'YmdHis' ) . "!{$saveName}";
+ wfSuppressWarnings();
+ $success = rename( $this->mSavedFile, "${archive}/{$this->mUploadOldVersion}" );
+ wfRestoreWarnings();
+
+ if( ! $success ) {
+ $wgOut->showFileRenameError( $this->mSavedFile,
+ "${archive}/{$this->mUploadOldVersion}" );
+ return false;
+ }
+ else wfDebug("$fname: moved file ".$this->mSavedFile." to ${archive}/{$this->mUploadOldVersion}\n");
+ }
+ else {
+ $this->mUploadOldVersion = '';
+ }
+
+ wfSuppressWarnings();
+ $success = $useRename
+ ? rename( $tempName, $this->mSavedFile )
+ : move_uploaded_file( $tempName, $this->mSavedFile );
+ wfRestoreWarnings();
+
+ if( ! $success ) {
+ $wgOut->showFileCopyError( $tempName, $this->mSavedFile );
+ return false;
+ } else {
+ wfDebug("$fname: wrote tempfile $tempName to ".$this->mSavedFile."\n");
+ }
+
+ chmod( $this->mSavedFile, 0644 );
+ return true;
+ }
+
+ /**
+ * Stash a file in a temporary directory for later processing
+ * after the user has confirmed it.
+ *
+ * If the user doesn't explicitly cancel or accept, these files
+ * can accumulate in the temp directory.
+ *
+ * @param string $saveName - the destination filename
+ * @param string $tempName - the source temporary file to save
+ * @return string - full path the stashed file, or false on failure
+ * @access private
+ */
+ function saveTempUploadedFile( $saveName, $tempName ) {
+ global $wgOut;
+ $archive = wfImageArchiveDir( $saveName, 'temp' );
+ if ( !is_dir ( $archive ) ) wfMkdirParents( $archive );
+ $stash = $archive . '/' . gmdate( "YmdHis" ) . '!' . $saveName;
+
+ $success = $this->mRemoveTempFile
+ ? rename( $tempName, $stash )
+ : move_uploaded_file( $tempName, $stash );
+ if ( !$success ) {
+ $wgOut->showFileCopyError( $tempName, $stash );
+ return false;
+ }
+
+ return $stash;
+ }
+
+ /**
+ * Stash a file in a temporary directory for later processing,
+ * and save the necessary descriptive info into the session.
+ * Returns a key value which will be passed through a form
+ * to pick up the path info on a later invocation.
+ *
+ * @return int
+ * @access private
+ */
+ function stashSession() {
+ $stash = $this->saveTempUploadedFile(
+ $this->mUploadSaveName, $this->mUploadTempName );
+
+ if( !$stash ) {
+ # Couldn't save the file.
+ return false;
+ }
+
+ $key = mt_rand( 0, 0x7fffffff );
+ $_SESSION['wsUploadData'][$key] = array(
+ 'mUploadTempName' => $stash,
+ 'mUploadSize' => $this->mUploadSize,
+ 'mOname' => $this->mOname );
+ return $key;
+ }
+
+ /**
+ * Remove a temporarily kept file stashed by saveTempUploadedFile().
+ * @access private
+ * @return success
+ */
+ function unsaveUploadedFile() {
+ global $wgOut;
+ wfSuppressWarnings();
+ $success = unlink( $this->mUploadTempName );
+ wfRestoreWarnings();
+ if ( ! $success ) {
+ $wgOut->showFileDeleteError( $this->mUploadTempName );
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /* -------------------------------------------------------------- */
+
+ /**
+ * Show some text and linkage on successful upload.
+ * @access private
+ */
+ function showSuccess() {
+ global $wgUser, $wgOut, $wgContLang;
+
+ $sk = $wgUser->getSkin();
+ $ilink = $sk->makeMediaLink( $this->mUploadSaveName, Image::imageUrl( $this->mUploadSaveName ) );
+ $dname = $wgContLang->getNsText( NS_IMAGE ) . ':'.$this->mUploadSaveName;
+ $dlink = $sk->makeKnownLink( $dname, $dname );
+
+ $wgOut->addHTML( '<h2>' . wfMsgHtml( 'successfulupload' ) . "</h2>\n" );
+ $text = wfMsgWikiHtml( 'fileuploaded', $ilink, $dlink );
+ $wgOut->addHTML( $text );
+ $wgOut->returnToMain( false );
+ }
+
+ /**
+ * @param string $error as HTML
+ * @access private
+ */
+ function uploadError( $error ) {
+ global $wgOut;
+ $wgOut->addHTML( "<h2>" . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" );
+ $wgOut->addHTML( "<span class='error'>{$error}</span>\n" );
+ }
+
+ /**
+ * There's something wrong with this file, not enough to reject it
+ * totally but we require manual intervention to save it for real.
+ * Stash it away, then present a form asking to confirm or cancel.
+ *
+ * @param string $warning as HTML
+ * @access private
+ */
+ function uploadWarning( $warning ) {
+ global $wgOut;
+ global $wgUseCopyrightUpload;
+
+ $this->mSessionKey = $this->stashSession();
+ if( !$this->mSessionKey ) {
+ # Couldn't save file; an error has been displayed so let's go.
+ return;
+ }
+
+ $wgOut->addHTML( "<h2>" . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" );
+ $wgOut->addHTML( "<ul class='warning'>{$warning}</ul><br />\n" );
+
+ $save = wfMsgHtml( 'savefile' );
+ $reupload = wfMsgHtml( 'reupload' );
+ $iw = wfMsgWikiHtml( 'ignorewarning' );
+ $reup = wfMsgWikiHtml( 'reuploaddesc' );
+ $titleObj = SpecialPage::getTitleFor( 'Upload' );
+ $action = $titleObj->escapeLocalURL( 'action=submit' );
+
+ if ( $wgUseCopyrightUpload )
+ {
+ $copyright = "
+ <input type='hidden' name='wpUploadCopyStatus' value=\"" . htmlspecialchars( $this->mUploadCopyStatus ) . "\" />
+ <input type='hidden' name='wpUploadSource' value=\"" . htmlspecialchars( $this->mUploadSource ) . "\" />
+ ";
+ } else {
+ $copyright = "";
+ }
+
+ $wgOut->addHTML( "
+ <form id='uploadwarning' method='post' enctype='multipart/form-data' action='$action'>
+ <input type='hidden' name='wpIgnoreWarning' value='1' />
+ <input type='hidden' name='wpSessionKey' value=\"" . htmlspecialchars( $this->mSessionKey ) . "\" />
+ <input type='hidden' name='wpUploadDescription' value=\"" . htmlspecialchars( $this->mUploadDescription ) . "\" />
+ <input type='hidden' name='wpLicense' value=\"" . htmlspecialchars( $this->mLicense ) . "\" />
+ <input type='hidden' name='wpDestFile' value=\"" . htmlspecialchars( $this->mDestFile ) . "\" />
+ <input type='hidden' name='wpWatchthis' value=\"" . htmlspecialchars( intval( $this->mWatchthis ) ) . "\" />
+ {$copyright}
+ <table border='0'>
+ <tr>
+ <tr>
+ <td align='right'>
+ <input tabindex='2' type='submit' name='wpUpload' value=\"$save\" />
+ </td>
+ <td align='left'>$iw</td>
+ </tr>
+ <tr>
+ <td align='right'>
+ <input tabindex='2' type='submit' name='wpReUpload' value=\"{$reupload}\" />
+ </td>
+ <td align='left'>$reup</td>
+ </tr>
+ </tr>
+ </table></form>\n" );
+ }
+
+ /**
+ * Displays the main upload form, optionally with a highlighted
+ * error message up at the top.
+ *
+ * @param string $msg as HTML
+ * @access private
+ */
+ function mainUploadForm( $msg='' ) {
+ global $wgOut, $wgUser;
+ global $wgUseCopyrightUpload;
+ global $wgRequest, $wgAllowCopyUploads;
+
+ if( !wfRunHooks( 'UploadForm:initial', array( &$this ) ) )
+ {
+ wfDebug( "Hook 'UploadForm:initial' broke output of the upload form" );
+ return false;
+ }
+
+ $cols = intval($wgUser->getOption( 'cols' ));
+ $ew = $wgUser->getOption( 'editwidth' );
+ if ( $ew ) $ew = " style=\"width:100%\"";
+ else $ew = '';
+
+ if ( '' != $msg ) {
+ $sub = wfMsgHtml( 'uploaderror' );
+ $wgOut->addHTML( "<h2>{$sub}</h2>\n" .
+ "<span class='error'>{$msg}</span>\n" );
+ }
+ $wgOut->addHTML( '<div id="uploadtext">' );
+ $wgOut->addWikiText( wfMsg( 'uploadtext' ) );
+ $wgOut->addHTML( '</div>' );
+
+ $sourcefilename = wfMsgHtml( 'sourcefilename' );
+ $destfilename = wfMsgHtml( 'destfilename' );
+ $summary = wfMsgWikiHtml( 'fileuploadsummary' );
+
+ $licenses = new Licenses();
+ $license = wfMsgHtml( 'license' );
+ $nolicense = wfMsgHtml( 'nolicense' );
+ $licenseshtml = $licenses->getHtml();
+
+ $ulb = wfMsgHtml( 'uploadbtn' );
+
+
+ $titleObj = SpecialPage::getTitleFor( 'Upload' );
+ $action = $titleObj->escapeLocalURL();
+
+ $encDestFile = htmlspecialchars( $this->mDestFile );
+
+ $watchChecked =
+ ( $wgUser->getOption( 'watchdefault' ) ||
+ ( $wgUser->getOption( 'watchcreations' ) && $this->mDestFile == '' ) )
+ ? 'checked="checked"'
+ : '';
+
+ // Prepare form for upload or upload/copy
+ if( $wgAllowCopyUploads && $wgUser->isAllowed( 'upload_by_url' ) ) {
+ $filename_form =
+ "<input type='radio' id='wpSourceTypeFile' name='wpSourceType' value='file' onchange='toggle_element_activation(\"wpUploadFileURL\",\"wpUploadFile\")' checked />" .
+ "<input tabindex='1' type='file' name='wpUploadFile' id='wpUploadFile' onfocus='toggle_element_activation(\"wpUploadFileURL\",\"wpUploadFile\");toggle_element_check(\"wpSourceTypeFile\",\"wpSourceTypeURL\")'" .
+ ($this->mDestFile?"":"onchange='fillDestFilename(\"wpUploadFile\")' ") . "size='40' />" .
+ wfMsgHTML( 'upload_source_file' ) . "<br/>" .
+ "<input type='radio' id='wpSourceTypeURL' name='wpSourceType' value='web' onchange='toggle_element_activation(\"wpUploadFile\",\"wpUploadFileURL\")' />" .
+ "<input tabindex='1' type='text' name='wpUploadFileURL' id='wpUploadFileURL' onfocus='toggle_element_activation(\"wpUploadFile\",\"wpUploadFileURL\");toggle_element_check(\"wpSourceTypeURL\",\"wpSourceTypeFile\")'" .
+ ($this->mDestFile?"":"onchange='fillDestFilename(\"wpUploadFileURL\")' ") . "size='40' DISABLED />" .
+ wfMsgHtml( 'upload_source_url' ) ;
+ } else {
+ $filename_form =
+ "<input tabindex='1' type='file' name='wpUploadFile' id='wpUploadFile' " .
+ ($this->mDestFile?"":"onchange='fillDestFilename(\"wpUploadFile\")' ") .
+ "size='40' />" .
+ "<input type='hidden' name='wpSourceType' value='file' />" ;
+ }
+
+ $wgOut->addHTML( "
+ <form id='upload' method='post' enctype='multipart/form-data' action=\"$action\">
+ <table border='0'>
+ <tr>
+ {$this->uploadFormTextTop}
+ <td align='right' valign='top'><label for='wpUploadFile'>{$sourcefilename}:</label></td>
+ <td align='left'>
+ {$filename_form}
+ </td>
+ </tr>
+ <tr>
+ <td align='right'><label for='wpDestFile'>{$destfilename}:</label></td>
+ <td align='left'>
+ <input tabindex='2' type='text' name='wpDestFile' id='wpDestFile' size='40' value=\"$encDestFile\" />
+ </td>
+ </tr>
+ <tr>
+ <td align='right'><label for='wpUploadDescription'>{$summary}</label></td>
+ <td align='left'>
+ <textarea tabindex='3' name='wpUploadDescription' id='wpUploadDescription' rows='6' cols='{$cols}'{$ew}>" . htmlspecialchars( $this->mUploadDescription ) . "</textarea>
+ {$this->uploadFormTextAfterSummary}
+ </td>
+ </tr>
+ <tr>" );
+
+ if ( $licenseshtml != '' ) {
+ global $wgStylePath;
+ $wgOut->addHTML( "
+ <td align='right'><label for='wpLicense'>$license:</label></td>
+ <td align='left'>
+ <script type='text/javascript' src=\"$wgStylePath/common/upload.js\"></script>
+ <select name='wpLicense' id='wpLicense' tabindex='4'
+ onchange='licenseSelectorCheck()'>
+ <option value=''>$nolicense</option>
+ $licenseshtml
+ </select>
+ </td>
+ </tr>
+ <tr>
+ ");
+ }
+
+ if ( $wgUseCopyrightUpload ) {
+ $filestatus = wfMsgHtml ( 'filestatus' );
+ $copystatus = htmlspecialchars( $this->mUploadCopyStatus );
+ $filesource = wfMsgHtml ( 'filesource' );
+ $uploadsource = htmlspecialchars( $this->mUploadSource );
+
+ $wgOut->addHTML( "
+ <td align='right' nowrap='nowrap'><label for='wpUploadCopyStatus'>$filestatus:</label></td>
+ <td><input tabindex='5' type='text' name='wpUploadCopyStatus' id='wpUploadCopyStatus' value=\"$copystatus\" size='40' /></td>
+ </tr>
+ <tr>
+ <td align='right'><label for='wpUploadCopyStatus'>$filesource:</label></td>
+ <td><input tabindex='6' type='text' name='wpUploadSource' id='wpUploadCopyStatus' value=\"$uploadsource\" size='40' /></td>
+ </tr>
+ <tr>
+ ");
+ }
+
+
+ $wgOut->addHtml( "
+ <td></td>
+ <td>
+ <input tabindex='7' type='checkbox' name='wpWatchthis' id='wpWatchthis' $watchChecked value='true' />
+ <label for='wpWatchthis'>" . wfMsgHtml( 'watchthisupload' ) . "</label>
+ <input tabindex='8' type='checkbox' name='wpIgnoreWarning' id='wpIgnoreWarning' value='true' />
+ <label for='wpIgnoreWarning'>" . wfMsgHtml( 'ignorewarnings' ) . "</label>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td align='left'><input tabindex='9' type='submit' name='wpUpload' value=\"{$ulb}\" /></td>
+ </tr>
+
+ <tr>
+ <td></td>
+ <td align='left'>
+ " );
+ $wgOut->addWikiText( wfMsgForContent( 'edittools' ) );
+ $wgOut->addHTML( "
+ </td>
+ </tr>
+
+ </table>
+ </form>" );
+ }
+
+ /* -------------------------------------------------------------- */
+
+ /**
+ * Split a file into a base name and all dot-delimited 'extensions'
+ * on the end. Some web server configurations will fall back to
+ * earlier pseudo-'extensions' to determine type and execute
+ * scripts, so the blacklist needs to check them all.
+ *
+ * @return array
+ */
+ function splitExtensions( $filename ) {
+ $bits = explode( '.', $filename );
+ $basename = array_shift( $bits );
+ return array( $basename, $bits );
+ }
+
+ /**
+ * Perform case-insensitive match against a list of file extensions.
+ * Returns true if the extension is in the list.
+ *
+ * @param string $ext
+ * @param array $list
+ * @return bool
+ */
+ function checkFileExtension( $ext, $list ) {
+ return in_array( strtolower( $ext ), $list );
+ }
+
+ /**
+ * Perform case-insensitive match against a list of file extensions.
+ * Returns true if any of the extensions are in the list.
+ *
+ * @param array $ext
+ * @param array $list
+ * @return bool
+ */
+ function checkFileExtensionList( $ext, $list ) {
+ foreach( $ext as $e ) {
+ if( in_array( strtolower( $e ), $list ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Verifies that it's ok to include the uploaded file
+ *
+ * @param string $tmpfile the full path of the temporary file to verify
+ * @param string $extension The filename extension that the file is to be served with
+ * @return mixed true of the file is verified, a WikiError object otherwise.
+ */
+ function verify( $tmpfile, $extension ) {
+ #magically determine mime type
+ $magic=& MimeMagic::singleton();
+ $mime= $magic->guessMimeType($tmpfile,false);
+
+ $fname= "SpecialUpload::verify";
+
+ #check mime type, if desired
+ global $wgVerifyMimeType;
+ if ($wgVerifyMimeType) {
+
+ #check mime type against file extension
+ if( !$this->verifyExtension( $mime, $extension ) ) {
+ return new WikiErrorMsg( 'uploadcorrupt' );
+ }
+
+ #check mime type blacklist
+ global $wgMimeTypeBlacklist;
+ if( isset($wgMimeTypeBlacklist) && !is_null($wgMimeTypeBlacklist)
+ && $this->checkFileExtension( $mime, $wgMimeTypeBlacklist ) ) {
+ return new WikiErrorMsg( 'badfiletype', htmlspecialchars( $mime ) );
+ }
+ }
+
+ #check for htmlish code and javascript
+ if( $this->detectScript ( $tmpfile, $mime, $extension ) ) {
+ return new WikiErrorMsg( 'uploadscripted' );
+ }
+
+ /**
+ * Scan the uploaded file for viruses
+ */
+ $virus= $this->detectVirus($tmpfile);
+ if ( $virus ) {
+ return new WikiErrorMsg( 'uploadvirus', htmlspecialchars($virus) );
+ }
+
+ wfDebug( "$fname: all clear; passing.\n" );
+ return true;
+ }
+
+ /**
+ * Checks if the mime type of the uploaded file matches the file extension.
+ *
+ * @param string $mime the mime type of the uploaded file
+ * @param string $extension The filename extension that the file is to be served with
+ * @return bool
+ */
+ function verifyExtension( $mime, $extension ) {
+ $fname = 'SpecialUpload::verifyExtension';
+
+ $magic =& MimeMagic::singleton();
+
+ if ( ! $mime || $mime == 'unknown' || $mime == 'unknown/unknown' )
+ if ( ! $magic->isRecognizableExtension( $extension ) ) {
+ wfDebug( "$fname: passing file with unknown detected mime type; unrecognized extension '$extension', can't verify\n" );
+ return true;
+ } else {
+ wfDebug( "$fname: rejecting file with unknown detected mime type; recognized extension '$extension', so probably invalid file\n" );
+ return false;
+ }
+
+ $match= $magic->isMatchingExtension($extension,$mime);
+
+ if ($match===NULL) {
+ wfDebug( "$fname: no file extension known for mime type $mime, passing file\n" );
+ return true;
+ } elseif ($match===true) {
+ wfDebug( "$fname: mime type $mime matches extension $extension, passing file\n" );
+
+ #TODO: if it's a bitmap, make sure PHP or ImageMagic resp. can handle it!
+ return true;
+
+ } else {
+ wfDebug( "$fname: mime type $mime mismatches file extension $extension, rejecting file\n" );
+ return false;
+ }
+ }
+
+ /** Heuristig for detecting files that *could* contain JavaScript instructions or
+ * things that may look like HTML to a browser and are thus
+ * potentially harmful. The present implementation will produce false positives in some situations.
+ *
+ * @param string $file Pathname to the temporary upload file
+ * @param string $mime The mime type of the file
+ * @param string $extension The extension of the file
+ * @return bool true if the file contains something looking like embedded scripts
+ */
+ function detectScript($file, $mime, $extension) {
+ global $wgAllowTitlesInSVG;
+
+ #ugly hack: for text files, always look at the entire file.
+ #For binarie field, just check the first K.
+
+ if (strpos($mime,'text/')===0) $chunk = file_get_contents( $file );
+ else {
+ $fp = fopen( $file, 'rb' );
+ $chunk = fread( $fp, 1024 );
+ fclose( $fp );
+ }
+
+ $chunk= strtolower( $chunk );
+
+ if (!$chunk) return false;
+
+ #decode from UTF-16 if needed (could be used for obfuscation).
+ if (substr($chunk,0,2)=="\xfe\xff") $enc= "UTF-16BE";
+ elseif (substr($chunk,0,2)=="\xff\xfe") $enc= "UTF-16LE";
+ else $enc= NULL;
+
+ if ($enc) $chunk= iconv($enc,"ASCII//IGNORE",$chunk);
+
+ $chunk= trim($chunk);
+
+ #FIXME: convert from UTF-16 if necessarry!
+
+ wfDebug("SpecialUpload::detectScript: checking for embedded scripts and HTML stuff\n");
+
+ #check for HTML doctype
+ if (eregi("<!DOCTYPE *X?HTML",$chunk)) return true;
+
+ /**
+ * Internet Explorer for Windows performs some really stupid file type
+ * autodetection which can cause it to interpret valid image files as HTML
+ * and potentially execute JavaScript, creating a cross-site scripting
+ * attack vectors.
+ *
+ * Apple's Safari browser also performs some unsafe file type autodetection
+ * which can cause legitimate files to be interpreted as HTML if the
+ * web server is not correctly configured to send the right content-type
+ * (or if you're really uploading plain text and octet streams!)
+ *
+ * Returns true if IE is likely to mistake the given file for HTML.
+ * Also returns true if Safari would mistake the given file for HTML
+ * when served with a generic content-type.
+ */
+
+ $tags = array(
+ '<body',
+ '<head',
+ '<html', #also in safari
+ '<img',
+ '<pre',
+ '<script', #also in safari
+ '<table'
+ );
+ if( ! $wgAllowTitlesInSVG && $extension !== 'svg' && $mime !== 'image/svg' ) {
+ $tags[] = '<title';
+ }
+
+ foreach( $tags as $tag ) {
+ if( false !== strpos( $chunk, $tag ) ) {
+ return true;
+ }
+ }
+
+ /*
+ * look for javascript
+ */
+
+ #resolve entity-refs to look at attributes. may be harsh on big files... cache result?
+ $chunk = Sanitizer::decodeCharReferences( $chunk );
+
+ #look for script-types
+ if (preg_match('!type\s*=\s*[\'"]?\s*(\w*/)?(ecma|java)!sim',$chunk)) return true;
+
+ #look for html-style script-urls
+ if (preg_match('!(href|src|data)\s*=\s*[\'"]?\s*(ecma|java)script:!sim',$chunk)) return true;
+
+ #look for css-style script-urls
+ if (preg_match('!url\s*\(\s*[\'"]?\s*(ecma|java)script:!sim',$chunk)) return true;
+
+ wfDebug("SpecialUpload::detectScript: no scripts found\n");
+ return false;
+ }
+
+ /** Generic wrapper function for a virus scanner program.
+ * This relies on the $wgAntivirus and $wgAntivirusSetup variables.
+ * $wgAntivirusRequired may be used to deny upload if the scan fails.
+ *
+ * @param string $file Pathname to the temporary upload file
+ * @return mixed false if not virus is found, NULL if the scan fails or is disabled,
+ * or a string containing feedback from the virus scanner if a virus was found.
+ * If textual feedback is missing but a virus was found, this function returns true.
+ */
+ function detectVirus($file) {
+ global $wgAntivirus, $wgAntivirusSetup, $wgAntivirusRequired, $wgOut;
+
+ $fname= "SpecialUpload::detectVirus";
+
+ if (!$wgAntivirus) { #disabled?
+ wfDebug("$fname: virus scanner disabled\n");
+
+ return NULL;
+ }
+
+ if (!$wgAntivirusSetup[$wgAntivirus]) {
+ wfDebug("$fname: unknown virus scanner: $wgAntivirus\n");
+
+ $wgOut->addHTML( "<div class='error'>Bad configuration: unknown virus scanner: <i>$wgAntivirus</i></div>\n" ); #LOCALIZE
+
+ return "unknown antivirus: $wgAntivirus";
+ }
+
+ #look up scanner configuration
+ $virus_scanner= $wgAntivirusSetup[$wgAntivirus]["command"]; #command pattern
+ $virus_scanner_codes= $wgAntivirusSetup[$wgAntivirus]["codemap"]; #exit-code map
+ $msg_pattern= $wgAntivirusSetup[$wgAntivirus]["messagepattern"]; #message pattern
+
+ $scanner= $virus_scanner; #copy, so we can resolve the pattern
+
+ if (strpos($scanner,"%f")===false) $scanner.= " ".wfEscapeShellArg($file); #simple pattern: append file to scan
+ else $scanner= str_replace("%f",wfEscapeShellArg($file),$scanner); #complex pattern: replace "%f" with file to scan
+
+ wfDebug("$fname: running virus scan: $scanner \n");
+
+ #execute virus scanner
+ $code= false;
+
+ #NOTE: there's a 50 line workaround to make stderr redirection work on windows, too.
+ # that does not seem to be worth the pain.
+ # Ask me (Duesentrieb) about it if it's ever needed.
+ $output = array();
+ if (wfIsWindows()) exec("$scanner",$output,$code);
+ else exec("$scanner 2>&1",$output,$code);
+
+ $exit_code= $code; #remember for user feedback
+
+ if ($virus_scanner_codes) { #map exit code to AV_xxx constants.
+ if (isset($virus_scanner_codes[$code])) {
+ $code= $virus_scanner_codes[$code]; # explicit mapping
+ } else if (isset($virus_scanner_codes["*"])) {
+ $code= $virus_scanner_codes["*"]; # fallback mapping
+ }
+ }
+
+ if ($code===AV_SCAN_FAILED) { #scan failed (code was mapped to false by $virus_scanner_codes)
+ wfDebug("$fname: failed to scan $file (code $exit_code).\n");
+
+ if ($wgAntivirusRequired) { return "scan failed (code $exit_code)"; }
+ else { return NULL; }
+ }
+ else if ($code===AV_SCAN_ABORTED) { #scan failed because filetype is unknown (probably imune)
+ wfDebug("$fname: unsupported file type $file (code $exit_code).\n");
+ return NULL;
+ }
+ else if ($code===AV_NO_VIRUS) {
+ wfDebug("$fname: file passed virus scan.\n");
+ return false; #no virus found
+ }
+ else {
+ $output= join("\n",$output);
+ $output= trim($output);
+
+ if (!$output) $output= true; #if there's no output, return true
+ else if ($msg_pattern) {
+ $groups= array();
+ if (preg_match($msg_pattern,$output,$groups)) {
+ if ($groups[1]) $output= $groups[1];
+ }
+ }
+
+ wfDebug("$fname: FOUND VIRUS! scanner feedback: $output");
+ return $output;
+ }
+ }
+
+ /**
+ * Check if the temporary file is MacBinary-encoded, as some uploads
+ * from Internet Explorer on Mac OS Classic and Mac OS X will be.
+ * If so, the data fork will be extracted to a second temporary file,
+ * which will then be checked for validity and either kept or discarded.
+ *
+ * @access private
+ */
+ function checkMacBinary() {
+ $macbin = new MacBinary( $this->mUploadTempName );
+ if( $macbin->isValid() ) {
+ $dataFile = tempnam( wfTempDir(), "WikiMacBinary" );
+ $dataHandle = fopen( $dataFile, 'wb' );
+
+ wfDebug( "SpecialUpload::checkMacBinary: Extracting MacBinary data fork to $dataFile\n" );
+ $macbin->extractData( $dataHandle );
+
+ $this->mUploadTempName = $dataFile;
+ $this->mUploadSize = $macbin->dataForkLength();
+
+ // We'll have to manually remove the new file if it's not kept.
+ $this->mRemoveTempFile = true;
+ }
+ $macbin->close();
+ }
+
+ /**
+ * If we've modified the upload file we need to manually remove it
+ * on exit to clean up.
+ * @access private
+ */
+ function cleanupTempFile() {
+ if( $this->mRemoveTempFile && file_exists( $this->mUploadTempName ) ) {
+ wfDebug( "SpecialUpload::cleanupTempFile: Removing temporary file $this->mUploadTempName\n" );
+ unlink( $this->mUploadTempName );
+ }
+ }
+
+ /**
+ * Check if there's an overwrite conflict and, if so, if restrictions
+ * forbid this user from performing the upload.
+ *
+ * @return mixed true on success, WikiError on failure
+ * @access private
+ */
+ function checkOverwrite( $name ) {
+ $img = Image::newFromName( $name );
+ if( is_null( $img ) ) {
+ // Uh... this shouldn't happen ;)
+ // But if it does, fall through to previous behavior
+ return false;
+ }
+
+ $error = '';
+ if( $img->exists() ) {
+ global $wgUser, $wgOut;
+ if( $img->isLocal() ) {
+ if( !$wgUser->isAllowed( 'reupload' ) ) {
+ $error = 'fileexists-forbidden';
+ }
+ } else {
+ if( !$wgUser->isAllowed( 'reupload' ) ||
+ !$wgUser->isAllowed( 'reupload-shared' ) ) {
+ $error = "fileexists-shared-forbidden";
+ }
+ }
+ }
+
+ if( $error ) {
+ $errorText = wfMsg( $error, wfEscapeWikiText( $img->getName() ) );
+ return new WikiError( $wgOut->parse( $errorText ) );
+ }
+
+ // Rockin', go ahead and upload
+ return true;
+ }
+
+}
+
+
+?>
diff --git a/includes/SpecialUploadMogile.php b/includes/SpecialUploadMogile.php
new file mode 100644
index 000000000000..05bfca085a92
--- /dev/null
+++ b/includes/SpecialUploadMogile.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+require_once( 'MogileFS.php' );
+
+/**
+ * Entry point
+ */
+function wfSpecialUploadMogile() {
+ global $wgRequest;
+ $form = new UploadFormMogile( $wgRequest );
+ $form->execute();
+}
+
+/** @package MediaWiki */
+class UploadFormMogile extends UploadForm {
+ /**
+ * Move the uploaded file from its temporary location to the final
+ * destination. If a previous version of the file exists, move
+ * it into the archive subdirectory.
+ *
+ * @todo If the later save fails, we may have disappeared the original file.
+ *
+ * @param string $saveName
+ * @param string $tempName full path to the temporary file
+ * @param bool $useRename Not used in this implementation
+ */
+ function saveUploadedFile( $saveName, $tempName, $useRename = false ) {
+ global $wgOut;
+ $mfs = MogileFS::NewMogileFS();
+
+ $this->mSavedFile = "image!{$saveName}";
+
+ if( $mfs->getPaths( $this->mSavedFile )) {
+ $this->mUploadOldVersion = gmdate( 'YmdHis' ) . "!{$saveName}";
+ if( !$mfs->rename( $this->mSavedFile, "archive!{$this->mUploadOldVersion}" ) ) {
+ $wgOut->showFileRenameError( $this->mSavedFile,
+ "archive!{$this->mUploadOldVersion}" );
+ return false;
+ }
+ } else {
+ $this->mUploadOldVersion = '';
+ }
+
+ if ( $this->mStashed ) {
+ if (!$mfs->rename($tempName,$this->mSavedFile)) {
+ $wgOut->showFileRenameError($tempName, $this->mSavedFile );
+ return false;
+ }
+ } else {
+ if ( !$mfs->saveFile($this->mSavedFile,'normal',$tempName )) {
+ $wgOut->showFileCopyError( $tempName, $this->mSavedFile );
+ return false;
+ }
+ unlink($tempName);
+ }
+ return true;
+ }
+
+ /**
+ * Stash a file in a temporary directory for later processing
+ * after the user has confirmed it.
+ *
+ * If the user doesn't explicitly cancel or accept, these files
+ * can accumulate in the temp directory.
+ *
+ * @param string $saveName - the destination filename
+ * @param string $tempName - the source temporary file to save
+ * @return string - full path the stashed file, or false on failure
+ * @access private
+ */
+ function saveTempUploadedFile( $saveName, $tempName ) {
+ global $wgOut;
+
+ $stash = 'stash!' . gmdate( "YmdHis" ) . '!' . $saveName;
+ $mfs = MogileFS::NewMogileFS();
+ if ( !$mfs->saveFile( $stash, 'normal', $tempName ) ) {
+ $wgOut->showFileCopyError( $tempName, $stash );
+ return false;
+ }
+ unlink($tempName);
+ return $stash;
+ }
+
+ /**
+ * Stash a file in a temporary directory for later processing,
+ * and save the necessary descriptive info into the session.
+ * Returns a key value which will be passed through a form
+ * to pick up the path info on a later invocation.
+ *
+ * @return int
+ * @access private
+ */
+ function stashSession() {
+ $stash = $this->saveTempUploadedFile(
+ $this->mUploadSaveName, $this->mUploadTempName );
+
+ if( !$stash ) {
+ # Couldn't save the file.
+ return false;
+ }
+
+ $key = mt_rand( 0, 0x7fffffff );
+ $_SESSION['wsUploadData'][$key] = array(
+ 'mUploadTempName' => $stash,
+ 'mUploadSize' => $this->mUploadSize,
+ 'mOname' => $this->mOname );
+ return $key;
+ }
+
+ /**
+ * Remove a temporarily kept file stashed by saveTempUploadedFile().
+ * @access private
+ * @return success
+ */
+ function unsaveUploadedFile() {
+ global $wgOut;
+ $mfs = MogileFS::NewMogileFS();
+ if ( ! $mfs->delete( $this->mUploadTempName ) ) {
+ $wgOut->showFileDeleteError( $this->mUploadTempName );
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
+?>
diff --git a/includes/SpecialUserlogin.php b/includes/SpecialUserlogin.php
new file mode 100644
index 000000000000..e60e3d54edf2
--- /dev/null
+++ b/includes/SpecialUserlogin.php
@@ -0,0 +1,802 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * constructor
+ */
+function wfSpecialUserlogin() {
+ global $wgCommandLineMode;
+ global $wgRequest;
+ if( !$wgCommandLineMode && !isset( $_COOKIE[session_name()] ) ) {
+ wfSetupSession();
+ }
+
+ $form = new LoginForm( $wgRequest );
+ $form->execute();
+}
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+class LoginForm {
+
+ const SUCCESS = 0;
+ const NO_NAME = 1;
+ const ILLEGAL = 2;
+ const WRONG_PLUGIN_PASS = 3;
+ const NOT_EXISTS = 4;
+ const WRONG_PASS = 5;
+ const EMPTY_PASS = 6;
+ const RESET_PASS = 7;
+
+ var $mName, $mPassword, $mRetype, $mReturnTo, $mCookieCheck, $mPosted;
+ var $mAction, $mCreateaccount, $mCreateaccountMail, $mMailmypassword;
+ var $mLoginattempt, $mRemember, $mEmail, $mDomain, $mLanguage;
+
+ /**
+ * Constructor
+ * @param webrequest $request A webrequest object passed by reference
+ */
+ function LoginForm( &$request ) {
+ global $wgLang, $wgAllowRealName, $wgEnableEmail;
+ global $wgAuth;
+
+ $this->mType = $request->getText( 'type' );
+ $this->mName = $request->getText( 'wpName' );
+ $this->mPassword = $request->getText( 'wpPassword' );
+ $this->mRetype = $request->getText( 'wpRetype' );
+ $this->mDomain = $request->getText( 'wpDomain' );
+ $this->mReturnTo = $request->getVal( 'returnto' );
+ $this->mCookieCheck = $request->getVal( 'wpCookieCheck' );
+ $this->mPosted = $request->wasPosted();
+ $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' );
+ $this->mCreateaccountMail = $request->getCheck( 'wpCreateaccountMail' )
+ && $wgEnableEmail;
+ $this->mMailmypassword = $request->getCheck( 'wpMailmypassword' )
+ && $wgEnableEmail;
+ $this->mLoginattempt = $request->getCheck( 'wpLoginattempt' );
+ $this->mAction = $request->getVal( 'action' );
+ $this->mRemember = $request->getCheck( 'wpRemember' );
+ $this->mLanguage = $request->getText( 'uselang' );
+
+ if( $wgEnableEmail ) {
+ $this->mEmail = $request->getText( 'wpEmail' );
+ } else {
+ $this->mEmail = '';
+ }
+ if( $wgAllowRealName ) {
+ $this->mRealName = $request->getText( 'wpRealName' );
+ } else {
+ $this->mRealName = '';
+ }
+
+ if( !$wgAuth->validDomain( $this->mDomain ) ) {
+ $this->mDomain = 'invaliddomain';
+ }
+ $wgAuth->setDomain( $this->mDomain );
+
+ # When switching accounts, it sucks to get automatically logged out
+ if( $this->mReturnTo == $wgLang->specialPage( 'Userlogout' ) ) {
+ $this->mReturnTo = '';
+ }
+ }
+
+ function execute() {
+ if ( !is_null( $this->mCookieCheck ) ) {
+ $this->onCookieRedirectCheck( $this->mCookieCheck );
+ return;
+ } else if( $this->mPosted ) {
+ if( $this->mCreateaccount ) {
+ return $this->addNewAccount();
+ } else if ( $this->mCreateaccountMail ) {
+ return $this->addNewAccountMailPassword();
+ } else if ( $this->mMailmypassword ) {
+ return $this->mailPassword();
+ } else if ( ( 'submitlogin' == $this->mAction ) || $this->mLoginattempt ) {
+ return $this->processLogin();
+ }
+ }
+ $this->mainLoginForm( '' );
+ }
+
+ /**
+ * @private
+ */
+ function addNewAccountMailPassword() {
+ global $wgOut;
+
+ if ('' == $this->mEmail) {
+ $this->mainLoginForm( wfMsg( 'noemail', htmlspecialchars( $this->mName ) ) );
+ return;
+ }
+
+ $u = $this->addNewaccountInternal();
+
+ if ($u == NULL) {
+ return;
+ }
+
+ // Wipe the initial password and mail a temporary one
+ $u->setPassword( null );
+ $u->saveSettings();
+ $result = $this->mailPasswordInternal( $u, false );
+
+ wfRunHooks( 'AddNewAccount', array( $u ) );
+
+ $wgOut->setPageTitle( wfMsg( 'accmailtitle' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+
+ if( WikiError::isError( $result ) ) {
+ $this->mainLoginForm( wfMsg( 'mailerror', $result->getMessage() ) );
+ } else {
+ $wgOut->addWikiText( wfMsg( 'accmailtext', $u->getName(), $u->getEmail() ) );
+ $wgOut->returnToMain( false );
+ }
+ $u = 0;
+ }
+
+
+ /**
+ * @private
+ */
+ function addNewAccount() {
+ global $wgUser, $wgEmailAuthentication;
+
+ # Create the account and abort if there's a problem doing so
+ $u = $this->addNewAccountInternal();
+ if( $u == NULL )
+ return;
+
+ # If we showed up language selection links, and one was in use, be
+ # smart (and sensible) and save that language as the user's preference
+ global $wgLoginLanguageSelector;
+ if( $wgLoginLanguageSelector && $this->mLanguage )
+ $u->setOption( 'language', $this->mLanguage );
+
+ # Save user settings and send out an email authentication message if needed
+ $u->saveSettings();
+ if( $wgEmailAuthentication && User::isValidEmailAddr( $u->getEmail() ) ) {
+ global $wgOut;
+ $error = $u->sendConfirmationMail();
+ if( WikiError::isError( $error ) ) {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_sendfailed', $error->getMessage() ) );
+ } else {
+ $wgOut->addWikiText( wfMsg( 'confirmemail_oncreate' ) );
+ }
+ }
+
+ # If not logged in, assume the new account as the current one and set session cookies
+ # then show a "welcome" message or a "need cookies" message as needed
+ if( $wgUser->isAnon() ) {
+ $wgUser = $u;
+ $wgUser->setCookies();
+ wfRunHooks( 'AddNewAccount', array( $wgUser ) );
+ if( $this->hasSessionCookie() ) {
+ return $this->successfulLogin( wfMsg( 'welcomecreation', $wgUser->getName() ), false );
+ } else {
+ return $this->cookieRedirectCheck( 'new' );
+ }
+ } else {
+ # Confirm that the account was created
+ global $wgOut;
+ $self = SpecialPage::getTitleFor( 'Userlogin' );
+ $wgOut->setPageTitle( wfMsgHtml( 'accountcreated' ) );
+ $wgOut->setArticleRelated( false );
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ $wgOut->addHtml( wfMsgWikiHtml( 'accountcreatedtext', $u->getName() ) );
+ $wgOut->returnToMain( $self->getPrefixedText() );
+ wfRunHooks( 'AddNewAccount', array( $u ) );
+ return true;
+ }
+ }
+
+ /**
+ * @private
+ */
+ function addNewAccountInternal() {
+ global $wgUser, $wgOut;
+ global $wgEnableSorbs, $wgProxyWhitelist;
+ global $wgMemc, $wgAccountCreationThrottle;
+ global $wgAuth, $wgMinimalPasswordLength;
+
+ // If the user passes an invalid domain, something is fishy
+ if( !$wgAuth->validDomain( $this->mDomain ) ) {
+ $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
+ return false;
+ }
+
+ // If we are not allowing users to login locally, we should
+ // be checking to see if the user is actually able to
+ // authenticate to the authentication server before they
+ // create an account (otherwise, they can create a local account
+ // and login as any domain user). We only need to check this for
+ // domains that aren't local.
+ if( 'local' != $this->mDomain && '' != $this->mDomain ) {
+ if( !$wgAuth->canCreateAccounts() && ( !$wgAuth->userExists( $this->mName ) || !$wgAuth->authenticate( $this->mName, $this->mPassword ) ) ) {
+ $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
+ return false;
+ }
+ }
+
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ return false;
+ }
+
+ if (!$wgUser->isAllowedToCreateAccount()) {
+ $this->userNotPrivilegedMessage();
+ return false;
+ }
+
+ $ip = wfGetIP();
+ if ( $wgEnableSorbs && !in_array( $ip, $wgProxyWhitelist ) &&
+ $wgUser->inSorbsBlacklist( $ip ) )
+ {
+ $this->mainLoginForm( wfMsg( 'sorbs_create_account_reason' ) . ' (' . htmlspecialchars( $ip ) . ')' );
+ return;
+ }
+
+ $name = trim( $this->mName );
+ $u = User::newFromName( $name, 'creatable' );
+ if ( is_null( $u ) ) {
+ $this->mainLoginForm( wfMsg( 'noname' ) );
+ return false;
+ }
+
+ if ( 0 != $u->idForName() ) {
+ $this->mainLoginForm( wfMsg( 'userexists' ) );
+ return false;
+ }
+
+ if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
+ $this->mainLoginForm( wfMsg( 'badretype' ) );
+ return false;
+ }
+
+ if ( !$wgUser->isValidPassword( $this->mPassword ) ) {
+ $this->mainLoginForm( wfMsg( 'passwordtooshort', $wgMinimalPasswordLength ) );
+ return false;
+ }
+
+ $abortError = '';
+ if( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) {
+ // Hook point to add extra creation throttles and blocks
+ wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" );
+ $this->mainLoginForm( $abortError );
+ return false;
+ }
+
+ if ( $wgAccountCreationThrottle ) {
+ $key = wfMemcKey( 'acctcreate', 'ip', $ip );
+ $value = $wgMemc->incr( $key );
+ if ( !$value ) {
+ $wgMemc->set( $key, 1, 86400 );
+ }
+ if ( $value > $wgAccountCreationThrottle ) {
+ $this->throttleHit( $wgAccountCreationThrottle );
+ return false;
+ }
+ }
+
+ if( !$wgAuth->addUser( $u, $this->mPassword ) ) {
+ $this->mainLoginForm( wfMsg( 'externaldberror' ) );
+ return false;
+ }
+
+ # Update user count
+ $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
+ $ssUpdate->doUpdate();
+
+ return $this->initUser( $u );
+ }
+
+ /**
+ * Actually add a user to the database.
+ * Give it a User object that has been initialised with a name.
+ *
+ * @param $u User object.
+ * @return User object.
+ * @private
+ */
+ function initUser( $u ) {
+ $u->addToDatabase();
+ $u->setPassword( $this->mPassword );
+ $u->setEmail( $this->mEmail );
+ $u->setRealName( $this->mRealName );
+ $u->setToken();
+
+ global $wgAuth;
+ $wgAuth->initUser( $u );
+
+ $u->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 );
+ $u->saveSettings();
+
+ return $u;
+ }
+
+ /**
+ * Internally authenticate the login request.
+ *
+ * This may create a local account as a side effect if the
+ * authentication plugin allows transparent local account
+ * creation.
+ *
+ * @public
+ */
+ function authenticateUserData() {
+ global $wgUser, $wgAuth;
+ if ( '' == $this->mName ) {
+ return self::NO_NAME;
+ }
+ $u = User::newFromName( $this->mName );
+ if( is_null( $u ) || !User::isUsableName( $u->getName() ) ) {
+ return self::ILLEGAL;
+ }
+ if ( 0 == $u->getID() ) {
+ global $wgAuth;
+ /**
+ * If the external authentication plugin allows it,
+ * automatically create a new account for users that
+ * are externally defined but have not yet logged in.
+ */
+ if ( $wgAuth->autoCreate() && $wgAuth->userExists( $u->getName() ) ) {
+ if ( $wgAuth->authenticate( $u->getName(), $this->mPassword ) ) {
+ $u = $this->initUser( $u );
+ } else {
+ return self::WRONG_PLUGIN_PASS;
+ }
+ } else {
+ return self::NOT_EXISTS;
+ }
+ } else {
+ $u->load();
+ }
+
+ if (!$u->checkPassword( $this->mPassword )) {
+ if( $u->checkTemporaryPassword( $this->mPassword ) ) {
+ // The e-mailed temporary password should not be used
+ // for actual logins; that's a very sloppy habit,
+ // and insecure if an attacker has a few seconds to
+ // click "search" on someone's open mail reader.
+ //
+ // Allow it to be used only to reset the password
+ // a single time to a new value, which won't be in
+ // the user's e-mail archives.
+ //
+ // For backwards compatibility, we'll still recognize
+ // it at the login form to minimize surprises for
+ // people who have been logging in with a temporary
+ // password for some time.
+ //
+ // As a side-effect, we can authenticate the user's
+ // e-mail address if it's not already done, since
+ // the temporary password was sent via e-mail.
+ //
+ if( !$u->isEmailConfirmed() ) {
+ $u->confirmEmail();
+ }
+
+ // At this point we just return an appropriate code
+ // indicating that the UI should show a password
+ // reset form; bot interfaces etc will probably just
+ // fail cleanly here.
+ //
+ return self::RESET_PASS;
+ } else {
+ return '' == $this->mPassword ? self::EMPTY_PASS : self::WRONG_PASS;
+ }
+ } else {
+ $wgAuth->updateUser( $u );
+ $wgUser = $u;
+
+ return self::SUCCESS;
+ }
+ }
+
+ function processLogin() {
+ global $wgUser, $wgAuth;
+
+ switch ($this->authenticateUserData())
+ {
+ case self::SUCCESS:
+ # We've verified now, update the real record
+ if( (bool)$this->mRemember != (bool)$wgUser->getOption( 'rememberpassword' ) ) {
+ $wgUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 );
+ $wgUser->saveSettings();
+ } else {
+ $wgUser->invalidateCache();
+ }
+ $wgUser->setCookies();
+
+ if( $this->hasSessionCookie() ) {
+ return $this->successfulLogin( wfMsg( 'loginsuccess', $wgUser->getName() ) );
+ } else {
+ return $this->cookieRedirectCheck( 'login' );
+ }
+ break;
+
+ case self::NO_NAME:
+ case self::ILLEGAL:
+ $this->mainLoginForm( wfMsg( 'noname' ) );
+ break;
+ case self::WRONG_PLUGIN_PASS:
+ $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
+ break;
+ case self::NOT_EXISTS:
+ $this->mainLoginForm( wfMsg( 'nosuchuser', htmlspecialchars( $this->mName ) ) );
+ break;
+ case self::WRONG_PASS:
+ $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
+ break;
+ case self::EMPTY_PASS:
+ $this->mainLoginForm( wfMsg( 'wrongpasswordempty' ) );
+ break;
+ case self::RESET_PASS:
+ $this->resetLoginForm( wfMsg( 'resetpass_announce' ) );
+ break;
+ default:
+ wfDebugDieBacktrace( "Unhandled case value" );
+ }
+ }
+
+ function resetLoginForm( $error ) {
+ global $wgOut;
+ $wgOut->addWikiText( "<div class=\"errorbox\">$error</div>" );
+ $reset = new PasswordResetForm( $this->mName, $this->mPassword );
+ $reset->execute();
+ }
+
+ /**
+ * @private
+ */
+ function mailPassword() {
+ global $wgUser, $wgOut, $wgAuth;
+
+ if( !$wgAuth->allowPasswordChange() ) {
+ $this->mainLoginForm( wfMsg( 'resetpass_forbidden' ) );
+ return;
+ }
+
+ # Check against blocked IPs
+ # fixme -- should we not?
+ if( $wgUser->isBlocked() ) {
+ $this->mainLoginForm( wfMsg( 'blocked-mailpassword' ) );
+ return;
+ }
+
+ # Check against the rate limiter
+ if( $wgUser->pingLimiter( 'mailpassword' ) ) {
+ $wgOut->rateLimited();
+ return;
+ }
+
+ if ( '' == $this->mName ) {
+ $this->mainLoginForm( wfMsg( 'noname' ) );
+ return;
+ }
+ $u = User::newFromName( $this->mName );
+ if( is_null( $u ) ) {
+ $this->mainLoginForm( wfMsg( 'noname' ) );
+ return;
+ }
+ if ( 0 == $u->getID() ) {
+ $this->mainLoginForm( wfMsg( 'nosuchuser', $u->getName() ) );
+ return;
+ }
+
+ # Check against password throttle
+ if ( $u->isPasswordReminderThrottled() ) {
+ global $wgPasswordReminderResendTime;
+ # Round the time in hours to 3 d.p., in case someone is specifying minutes or seconds.
+ $this->mainLoginForm( wfMsg( 'throttled-mailpassword',
+ round( $wgPasswordReminderResendTime, 3 ) ) );
+ return;
+ }
+
+ $result = $this->mailPasswordInternal( $u, true );
+ if( WikiError::isError( $result ) ) {
+ $this->mainLoginForm( wfMsg( 'mailerror', $result->getMessage() ) );
+ } else {
+ $this->mainLoginForm( wfMsg( 'passwordsent', $u->getName() ), 'success' );
+ }
+ }
+
+
+ /**
+ * @return mixed true on success, WikiError on failure
+ * @private
+ */
+ function mailPasswordInternal( $u, $throttle = true ) {
+ global $wgCookiePath, $wgCookieDomain, $wgCookiePrefix, $wgCookieSecure;
+ global $wgServer, $wgScript;
+
+ if ( '' == $u->getEmail() ) {
+ return new WikiError( wfMsg( 'noemail', $u->getName() ) );
+ }
+
+ $np = $u->randomPassword();
+ $u->setNewpassword( $np, $throttle );
+
+ setcookie( "{$wgCookiePrefix}Token", '', time() - 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+
+ $u->saveSettings();
+
+ $ip = wfGetIP();
+ if ( '' == $ip ) { $ip = '(Unknown)'; }
+
+ $m = wfMsg( 'passwordremindertext', $ip, $u->getName(), $np, $wgServer . $wgScript );
+
+ $result = $u->sendMail( wfMsg( 'passwordremindertitle' ), $m );
+ return $result;
+ }
+
+
+ /**
+ * @param string $msg Message that will be shown on success
+ * @param bool $auto Toggle auto-redirect to main page; default true
+ * @private
+ */
+ function successfulLogin( $msg, $auto = true ) {
+ global $wgUser;
+ global $wgOut;
+
+ # Run any hooks; ignore results
+
+ wfRunHooks('UserLoginComplete', array(&$wgUser));
+
+ $wgOut->setPageTitle( wfMsg( 'loginsuccesstitle' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+ $wgOut->addWikiText( $msg );
+ if ( !empty( $this->mReturnTo ) ) {
+ $wgOut->returnToMain( $auto, $this->mReturnTo );
+ } else {
+ $wgOut->returnToMain( $auto );
+ }
+ }
+
+ /** */
+ function userNotPrivilegedMessage() {
+ global $wgOut;
+
+ $wgOut->setPageTitle( wfMsg( 'whitelistacctitle' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+
+ $wgOut->addWikiText( wfMsg( 'whitelistacctext' ) );
+
+ $wgOut->returnToMain( false );
+ }
+
+ /** */
+ function userBlockedMessage() {
+ global $wgOut;
+
+ # Let's be nice about this, it's likely that this feature will be used
+ # for blocking large numbers of innocent people, e.g. range blocks on
+ # schools. Don't blame it on the user. There's a small chance that it
+ # really is the user's fault, i.e. the username is blocked and they
+ # haven't bothered to log out before trying to create an account to
+ # evade it, but we'll leave that to their guilty conscience to figure
+ # out.
+
+ $wgOut->setPageTitle( wfMsg( 'cantcreateaccounttitle' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+
+ $ip = wfGetIP();
+ $wgOut->addWikiText( wfMsg( 'cantcreateaccounttext', $ip ) );
+ $wgOut->returnToMain( false );
+ }
+
+ /**
+ * @private
+ */
+ function mainLoginForm( $msg, $msgtype = 'error' ) {
+ global $wgUser, $wgOut, $wgAllowRealName, $wgEnableEmail;
+ global $wgCookiePrefix, $wgAuth, $wgLoginLanguageSelector;
+ global $wgAuth;
+
+ if ( $this->mType == 'signup' ) {
+ if ( !$wgUser->isAllowed( 'createaccount' ) ) {
+ $this->userNotPrivilegedMessage();
+ return;
+ } elseif ( $wgUser->isBlockedFromCreateAccount() ) {
+ $this->userBlockedMessage();
+ return;
+ }
+ }
+
+ if ( '' == $this->mName ) {
+ if ( $wgUser->isLoggedIn() ) {
+ $this->mName = $wgUser->getName();
+ } else {
+ $this->mName = isset( $_COOKIE[$wgCookiePrefix.'UserName'] ) ? $_COOKIE[$wgCookiePrefix.'UserName'] : null;
+ }
+ }
+
+ $titleObj = SpecialPage::getTitleFor( 'Userlogin' );
+
+ if ( $this->mType == 'signup' ) {
+ $template = new UsercreateTemplate();
+ $q = 'action=submitlogin&type=signup';
+ $linkq = 'type=login';
+ $linkmsg = 'gotaccount';
+ } else {
+ $template = new UserloginTemplate();
+ $q = 'action=submitlogin&type=login';
+ $linkq = 'type=signup';
+ $linkmsg = 'nologin';
+ }
+
+ if ( !empty( $this->mReturnTo ) ) {
+ $returnto = '&returnto=' . wfUrlencode( $this->mReturnTo );
+ $q .= $returnto;
+ $linkq .= $returnto;
+ }
+
+ # Pass any language selection on to the mode switch link
+ if( $wgLoginLanguageSelector && $this->mLanguage )
+ $linkq .= '&uselang=' . $this->mLanguage;
+
+ $link = '<a href="' . htmlspecialchars ( $titleObj->getLocalUrl( $linkq ) ) . '">';
+ $link .= wfMsgHtml( $linkmsg . 'link' );
+ $link .= '</a>';
+
+ # Don't show a "create account" link if the user can't
+ if( $this->showCreateOrLoginLink( $wgUser ) )
+ $template->set( 'link', wfMsgHtml( $linkmsg, $link ) );
+ else
+ $template->set( 'link', '' );
+
+ $template->set( 'header', '' );
+ $template->set( 'name', $this->mName );
+ $template->set( 'password', $this->mPassword );
+ $template->set( 'retype', $this->mRetype );
+ $template->set( 'email', $this->mEmail );
+ $template->set( 'realname', $this->mRealName );
+ $template->set( 'domain', $this->mDomain );
+
+ $template->set( 'action', $titleObj->getLocalUrl( $q ) );
+ $template->set( 'message', $msg );
+ $template->set( 'messagetype', $msgtype );
+ $template->set( 'createemail', $wgEnableEmail && $wgUser->isLoggedIn() );
+ $template->set( 'userealname', $wgAllowRealName );
+ $template->set( 'useemail', $wgEnableEmail );
+ $template->set( 'canreset', $wgAuth->allowPasswordChange() );
+ $template->set( 'remember', $wgUser->getOption( 'rememberpassword' ) or $this->mRemember );
+
+ # Prepare language selection links as needed
+ if( $wgLoginLanguageSelector ) {
+ $template->set( 'languages', $this->makeLanguageSelector() );
+ if( $this->mLanguage )
+ $template->set( 'uselang', $this->mLanguage );
+ }
+
+ // Give authentication and captcha plugins a chance to modify the form
+ $wgAuth->modifyUITemplate( $template );
+ if ( $this->mType == 'signup' ) {
+ wfRunHooks( 'UserCreateForm', array( &$template ) );
+ } else {
+ wfRunHooks( 'UserLoginForm', array( &$template ) );
+ }
+
+ $wgOut->setPageTitle( wfMsg( 'userlogin' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->setArticleRelated( false );
+ $wgOut->addTemplate( $template );
+ }
+
+ /**
+ * @private
+ */
+ function showCreateOrLoginLink( &$user ) {
+ if( $this->mType == 'signup' ) {
+ return( true );
+ } elseif( $user->isAllowed( 'createaccount' ) ) {
+ return( true );
+ } else {
+ return( false );
+ }
+ }
+
+ /**
+ * @private
+ */
+ function hasSessionCookie() {
+ global $wgDisableCookieCheck;
+ return ( $wgDisableCookieCheck ) ? true : ( isset( $_COOKIE[session_name()] ) );
+ }
+
+ /**
+ * @private
+ */
+ function cookieRedirectCheck( $type ) {
+ global $wgOut;
+
+ $titleObj = SpecialPage::getTitleFor( 'Userlogin' );
+ $check = $titleObj->getFullURL( 'wpCookieCheck='.$type );
+
+ return $wgOut->redirect( $check );
+ }
+
+ /**
+ * @private
+ */
+ function onCookieRedirectCheck( $type ) {
+ global $wgUser;
+
+ if ( !$this->hasSessionCookie() ) {
+ if ( $type == 'new' ) {
+ return $this->mainLoginForm( wfMsg( 'nocookiesnew' ) );
+ } else if ( $type == 'login' ) {
+ return $this->mainLoginForm( wfMsg( 'nocookieslogin' ) );
+ } else {
+ # shouldn't happen
+ return $this->mainLoginForm( wfMsg( 'error' ) );
+ }
+ } else {
+ return $this->successfulLogin( wfMsg( 'loginsuccess', $wgUser->getName() ) );
+ }
+ }
+
+ /**
+ * @private
+ */
+ function throttleHit( $limit ) {
+ global $wgOut;
+
+ $wgOut->addWikiText( wfMsg( 'acct_creation_throttle_hit', $limit ) );
+ }
+
+ /**
+ * Produce a bar of links which allow the user to select another language
+ * during login/registration but retain "returnto"
+ *
+ * @return string
+ */
+ function makeLanguageSelector() {
+ $msg = wfMsgForContent( 'loginlanguagelinks' );
+ if( $msg != '' && !wfEmptyMsg( 'loginlanguagelinks', $msg ) ) {
+ $langs = explode( "\n", $msg );
+ $links = array();
+ foreach( $langs as $lang ) {
+ $lang = trim( $lang, '* ' );
+ $parts = explode( '|', $lang );
+ $links[] = $this->makeLanguageSelectorLink( $parts[0], $parts[1] );
+ }
+ return count( $links ) > 0 ? wfMsgHtml( 'loginlanguagelabel', implode( ' | ', $links ) ) : '';
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Create a language selector link for a particular language
+ * Links back to this page preserving type and returnto
+ *
+ * @param $text Link text
+ * @param $lang Language code
+ */
+ function makeLanguageSelectorLink( $text, $lang ) {
+ global $wgUser;
+ $self = SpecialPage::getTitleFor( 'Userlogin' );
+ $attr[] = 'uselang=' . $lang;
+ if( $this->mType == 'signup' )
+ $attr[] = 'type=signup';
+ if( $this->mReturnTo )
+ $attr[] = 'returnto=' . $this->mReturnTo;
+ $skin =& $wgUser->getSkin();
+ return $skin->makeKnownLinkObj( $self, htmlspecialchars( $text ), implode( '&', $attr ) );
+ }
+
+}
+?>
diff --git a/includes/SpecialUserlogout.php b/includes/SpecialUserlogout.php
new file mode 100644
index 000000000000..f3fcbc4f9e09
--- /dev/null
+++ b/includes/SpecialUserlogout.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * constructor
+ */
+function wfSpecialUserlogout() {
+ global $wgUser, $wgOut;
+
+ if (wfRunHooks('UserLogout', array(&$wgUser))) {
+
+ $wgUser->logout();
+
+ wfRunHooks('UserLogoutComplete', array(&$wgUser));
+
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->addHTML( wfMsgExt( 'logouttext', array( 'parse' ) ) );
+ $wgOut->returnToMain();
+
+ }
+}
+
+?>
diff --git a/includes/SpecialUserrights.php b/includes/SpecialUserrights.php
new file mode 100644
index 000000000000..99abd7a7fed7
--- /dev/null
+++ b/includes/SpecialUserrights.php
@@ -0,0 +1,178 @@
+<?php
+
+/**
+ * Special page to allow managing user group membership
+ *
+ * @package MediaWiki
+ * @subpackage Special pages
+ * @todo This code is disgusting and needs a total rewrite
+ */
+
+/** */
+require_once('HTMLForm.php');
+
+/** Entry point */
+function wfSpecialUserrights() {
+ global $wgRequest;
+ $form = new UserrightsForm($wgRequest);
+ $form->execute();
+}
+
+/**
+ * A class to manage user levels rights.
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class UserrightsForm extends HTMLForm {
+ var $mPosted, $mRequest, $mSaveprefs;
+ /** Escaped local url name*/
+ var $action;
+
+ /** Constructor*/
+ function UserrightsForm ( &$request ) {
+ $this->mPosted = $request->wasPosted();
+ $this->mRequest =& $request;
+ $this->mName = 'userrights';
+
+ $titleObj = SpecialPage::getTitleFor( 'Userrights' );
+ $this->action = $titleObj->escapeLocalURL();
+ }
+
+ /**
+ * Manage forms to be shown according to posted data.
+ * Depending on the submit button used, call a form or a save function.
+ */
+ function execute() {
+ // show the general form
+ $this->switchForm();
+ if( $this->mPosted ) {
+ // show some more forms
+ if( $this->mRequest->getCheck( 'ssearchuser' ) ) {
+ $this->editUserGroupsForm( $this->mRequest->getVal( 'user-editname' ) );
+ }
+
+ // save settings
+ if( $this->mRequest->getCheck( 'saveusergroups' ) ) {
+ global $wgUser;
+ $username = $this->mRequest->getVal( 'user-editname' );
+ if( $wgUser->matchEditToken( $this->mRequest->getVal( 'wpEditToken' ), $username ) ) {
+ $this->saveUserGroups( $username,
+ $this->mRequest->getArray( 'member' ),
+ $this->mRequest->getArray( 'available' ) );
+ }
+ }
+ }
+ }
+
+ /**
+ * Save user groups changes in the database.
+ * Data comes from the editUserGroupsForm() form function
+ *
+ * @param string $username Username to apply changes to.
+ * @param array $removegroup id of groups to be removed.
+ * @param array $addgroup id of groups to be added.
+ *
+ */
+ function saveUserGroups( $username, $removegroup, $addgroup) {
+ global $wgOut;
+ $u = User::newFromName($username);
+
+ if(is_null($u)) {
+ $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) );
+ return;
+ }
+
+ if($u->getID() == 0) {
+ $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) );
+ return;
+ }
+
+ $oldGroups = $u->getGroups();
+ $newGroups = $oldGroups;
+ // remove then add groups
+ if(isset($removegroup)) {
+ $newGroups = array_diff($newGroups, $removegroup);
+ foreach( $removegroup as $group ) {
+ $u->removeGroup( $group );
+ }
+ }
+ if(isset($addgroup)) {
+ $newGroups = array_merge($newGroups, $addgroup);
+ foreach( $addgroup as $group ) {
+ $u->addGroup( $group );
+ }
+ }
+ $newGroups = array_unique( $newGroups );
+
+ wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) );
+ wfDebug( 'newGroups: ' . print_r( $newGroups, true ) );
+
+ wfRunHooks( 'UserRights', array( &$u, $addgroup, $removegroup ) );
+ $log = new LogPage( 'rights' );
+ $log->addEntry( 'rights', Title::makeTitle( NS_USER, $u->getName() ), '', array( $this->makeGroupNameList( $oldGroups ),
+ $this->makeGroupNameList( $newGroups ) ) );
+ }
+
+ function makeGroupNameList( $ids ) {
+ return implode( ', ', $ids );
+ }
+
+ /**
+ * Output a form to allow searching for a user
+ */
+ function switchForm() {
+ global $wgOut, $wgRequest;
+ $username = $wgRequest->getText( 'user-editname' );
+ $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->action, 'name' => 'uluser' ) );
+ $form .= '<fieldset><legend>' . wfMsgHtml( 'userrights-lookup-user' ) . '</legend>';
+ $form .= '<p>' . Xml::inputLabel( wfMsg( 'userrights-user-editname' ), 'user-editname', 'username', 30, $username ) . '</p>';
+ $form .= '<p>' . Xml::submitButton( wfMsg( 'editusergroup' ), array( 'name' => 'ssearchuser' ) ) . '</p>';
+ $form .= '</fieldset>';
+ $form .= '</form>';
+ $wgOut->addHTML( $form );
+ }
+
+ /**
+ * Edit user groups membership
+ * @param string $username Name of the user.
+ */
+ function editUserGroupsForm($username) {
+ global $wgOut, $wgUser;
+
+ $user = User::newFromName($username);
+ if( is_null( $user ) ) {
+ $wgOut->addWikiText( wfMsg( 'nouserspecified' ) );
+ return;
+ } elseif( $user->getID() == 0 ) {
+ $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) );
+ return;
+ }
+
+ $groups = $user->getGroups();
+
+ $wgOut->addHTML( "<form name=\"editGroup\" action=\"$this->action\" method=\"post\">\n".
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'user-editname',
+ 'value' => $username ) ) .
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'wpEditToken',
+ 'value' => $wgUser->editToken( $username ) ) ) .
+ $this->fieldset( 'editusergroup',
+ $wgOut->parse( wfMsg('editinguser', $username ) ) .
+ '<table border="0" align="center"><tr><td>'.
+ HTMLSelectGroups('member', $this->mName.'-groupsmember', $groups,true,6).
+ '</td><td>'.
+ HTMLSelectGroups('available', $this->mName.'-groupsavailable', $groups,true,6,true).
+ '</td></tr></table>'."\n".
+ $wgOut->parse( wfMsg('userrights-groupshelp') ) .
+ wfElement( 'input', array(
+ 'type' => 'submit',
+ 'name' => 'saveusergroups',
+ 'value' => wfMsg( 'saveusergroups' ) ) )
+ ));
+ $wgOut->addHTML( "</form>\n" );
+ }
+} // end class UserrightsForm
+?>
diff --git a/includes/SpecialVersion.php b/includes/SpecialVersion.php
new file mode 100644
index 000000000000..dba694c05818
--- /dev/null
+++ b/includes/SpecialVersion.php
@@ -0,0 +1,321 @@
+<?php
+/**#@+
+ * Give information about the version of MediaWiki, PHP, the DB and extensions
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @bug 2019, 4531
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * constructor
+ */
+function wfSpecialVersion() {
+ $version = new SpecialVersion;
+ $version->execute();
+}
+
+class SpecialVersion {
+ private $firstExtOpened = true;
+
+ /**
+ * main()
+ */
+ function execute() {
+ global $wgOut;
+
+ $wgOut->addHTML( '<div dir="ltr">' );
+ $wgOut->addWikiText(
+ $this->MediaWikiCredits() .
+ $this->extensionCredits() .
+ $this->wgHooks()
+ );
+ $wgOut->addHTML( $this->IPInfo() );
+ $wgOut->addHTML( '</div>' );
+ }
+
+ /**#@+
+ * @private
+ */
+
+ /**
+ * Return wiki text showing the licence information and third party
+ * software versions (apache, php, mysql).
+ * @static
+ */
+ function MediaWikiCredits() {
+ $version = self::getVersion();
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ global $wgLanguageNames, $wgLanguageCode;
+ $mwlang = $wgLanguageNames[$wgLanguageCode];
+
+ $ret =
+ "__NOTOC__
+ This wiki is powered by '''[http://www.mediawiki.org/ MediaWiki]''',
+ copyright (C) 2001-2007 Magnus Manske, Brion Vibber, Lee Daniel Crocker,
+ Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason,
+ Niklas Laxström, Domas Mituzas, Rob Church and others.
+
+ MediaWiki 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.
+
+ MediaWiki 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 [{{SERVER}}{{SCRIPTPATH}}/COPYING 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.
+ or [http://www.gnu.org/copyleft/gpl.html read it online]
+
+ * [http://www.mediawiki.org/ MediaWiki]: $version
+ * [http://www.php.net/ PHP]: " . phpversion() . " (" . php_sapi_name() . ")
+ * " . $dbr->getSoftwareLink() . ": " . $dbr->getServerVersion();
+
+ return str_replace( "\t\t", '', $ret ) . "\n";
+ }
+
+ /** Return a string of the MediaWiki version with SVN revision if available */
+ public static function getVersion() {
+ global $wgVersion, $IP;
+ $svn = self::getSvnRevision( $IP );
+ return $svn ? "$wgVersion (r$svn)" : $wgVersion;
+ }
+
+ /** Generate wikitext showing extensions name, URL, author and description */
+ function extensionCredits() {
+ global $wgExtensionCredits, $wgExtensionFunctions, $wgParser, $wgSkinExtensionFunction;
+
+ if ( ! count( $wgExtensionCredits ) && ! count( $wgExtensionFunctions ) && ! count( $wgSkinExtensionFunction ) )
+ return '';
+
+ $extensionTypes = array(
+ 'specialpage' => 'Special pages',
+ 'parserhook' => 'Parser hooks',
+ 'variable' => 'Variables',
+ 'other' => 'Other',
+ );
+ wfRunHooks( 'SpecialVersionExtensionTypes', array( &$this, &$extensionTypes ) );
+
+ $out = "<h2>Extensions</h2>\n";
+ $out .= wfOpenElement('table', array('id' => 'sv-ext') );
+
+ foreach ( $extensionTypes as $type => $text ) {
+ if ( count( @$wgExtensionCredits[$type] ) ) {
+ $out .= $this->openExtType( $text );
+
+ usort( $wgExtensionCredits[$type], array( $this, 'compare' ) );
+
+ foreach ( $wgExtensionCredits[$type] as $extension ) {
+ wfSuppressWarnings();
+ $out .= $this->formatCredits(
+ $extension['name'],
+ $extension['version'],
+ $extension['author'],
+ $extension['url'],
+ $extension['description']
+ );
+ wfRestoreWarnings();
+ }
+ }
+ }
+
+ if ( count( $wgExtensionFunctions ) ) {
+ $out .= $this->openExtType('Extension functions');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $wgExtensionFunctions ) . "</td></tr>\n";
+ }
+
+ if ( $cnt = count( $tags = $wgParser->getTags() ) ) {
+ for ( $i = 0; $i < $cnt; ++$i )
+ $tags[$i] = "&lt;{$tags[$i]}&gt;";
+ $out .= $this->openExtType('Parser extension tags');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $tags ). "</td></tr>\n";
+ }
+
+ if( $cnt = count( $fhooks = $wgParser->getFunctionHooks() ) ) {
+ $out .= $this->openExtType('Parser function hooks');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $fhooks ) . "</td></tr>\n";
+ }
+
+ if ( count( $wgSkinExtensionFunction ) ) {
+ $out .= $this->openExtType('Skin extension functions');
+ $out .= '<tr><td colspan="3">' . $this->listToText( $wgSkinExtensionFunction ) . "</td></tr>\n";
+ }
+ $out .= wfCloseElement( 'table' );
+ return $out;
+ }
+
+ /** Callback to sort extensions by type */
+ function compare( $a, $b ) {
+ if ( $a['name'] === $b['name'] )
+ return 0;
+ else
+ return Language::lc( $a['name'] ) > Language::lc( $b['name'] ) ? 1 : -1;
+ }
+
+ function formatCredits( $name, $version = null, $author = null, $url = null, $description = null) {
+ $ret = '<tr><td>';
+ if ( isset( $url ) )
+ $ret .= "[$url ";
+ $ret .= "''$name";
+ if ( isset( $version ) )
+ $ret .= " (version $version)";
+ $ret .= "''";
+ if ( isset( $url ) )
+ $ret .= ']';
+ $ret .= '</td>';
+ $ret .= "<td>$description</td>";
+ $ret .= "<td>" . $this->listToText( (array)$author ) . "</td>";
+ $ret .= '</tr>';
+ return "$ret\n";
+ }
+
+ /**
+ * @return string
+ */
+ function wgHooks() {
+ global $wgHooks;
+
+ if ( count( $wgHooks ) ) {
+ $myWgHooks = $wgHooks;
+ ksort( $myWgHooks );
+
+ $ret = "<h2>Hooks</h2>\n"
+ . wfOpenElement('table', array('id' => 'sv-hooks') )
+ . "<tr><th>Hook name</th><th>Subscribed by</th></tr>\n";
+
+ foreach ($myWgHooks as $hook => $hooks)
+ $ret .= "<tr><td>$hook</td><td>" . $this->listToText( $hooks ) . "</td></tr>\n";
+
+ $ret .= '</table>';
+ return $ret;
+ } else
+ return '';
+ }
+
+ private function openExtType($text, $name = null) {
+ $opt = array( 'colspan' => 3 );
+ $out = '';
+
+ if(!$this->firstExtOpened) {
+ // Insert a spacing line
+ $out .= '<tr class="sv-space">' . wfElement( 'td', $opt ) . "</tr>\n";
+ }
+ $this->firstExtOpened = false;
+
+ if($name) { $opt['id'] = "sv-$name"; }
+
+ $out .= "<tr>" . wfElement( 'th', $opt, $text) . "</tr>\n";
+ return $out;
+ }
+
+ /**
+ * @static
+ *
+ * @return string
+ */
+ function IPInfo() {
+ $ip = str_replace( '--', ' - ', htmlspecialchars( wfGetIP() ) );
+ return "<!-- visited from $ip -->\n" .
+ "<span style='display:none'>visited from $ip</span>";
+ }
+
+ /**
+ * @param array $list
+ * @return string
+ */
+ function listToText( $list ) {
+ $cnt = count( $list );
+
+ if ( $cnt == 1 ) {
+ // Enforce always returning a string
+ return (string)$this->arrayToString( $list[0] );
+ } elseif ( $cnt == 0 ) {
+ return '';
+ } else {
+ $t = array_slice( $list, 0, $cnt - 1 );
+ $one = array_map( array( &$this, 'arrayToString' ), $t );
+ $two = $this->arrayToString( $list[$cnt - 1] );
+
+ return implode( ', ', $one ) . " and $two";
+ }
+ }
+
+ /**
+ * @static
+ *
+ * @param mixed $list Will convert an array to string if given and return
+ * the paramater unaltered otherwise
+ * @return mixed
+ */
+ function arrayToString( $list ) {
+ if ( ! is_array( $list ) ) {
+ return $list;
+ } else {
+ $class = get_class( $list[0] );
+ return "($class, {$list[1]})";
+ }
+ }
+
+ /**
+ * Retrieve the revision number of a Subversion working directory.
+ *
+ * @bug 7335
+ *
+ * @param string $dir
+ * @return mixed revision number as int, or false if not a SVN checkout
+ */
+ public static function getSvnRevision( $dir ) {
+ // http://svnbook.red-bean.com/nightly/en/svn.developer.insidewc.html
+ $entries = $dir . '/.svn/entries';
+
+ if( !file_exists( $entries ) ) {
+ return false;
+ }
+
+ $content = file( $entries );
+
+ // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4)
+ if( preg_match( '/^<\?xml/', $content[0] ) ) {
+ // subversion is release <= 1.3
+ if( !function_exists( 'simplexml_load_file' ) ) {
+ // We could fall back to expat... YUCK
+ return false;
+ }
+
+ // SimpleXml whines about the xmlns...
+ wfSuppressWarnings();
+ $xml = simplexml_load_file( $entries );
+ wfRestoreWarnings();
+
+ if( $xml ) {
+ foreach( $xml->entry as $entry ) {
+ if( $xml->entry[0]['name'] == '' ) {
+ // The directory entry should always have a revision marker.
+ if( $entry['revision'] ) {
+ return intval( $entry['revision'] );
+ }
+ }
+ }
+ }
+ return false;
+ } else {
+ // subversion is release 1.4
+ return intval( $content[3] );
+ }
+ }
+
+ /**#@-*/
+}
+
+/**#@-*/
+?>
diff --git a/includes/SpecialWantedcategories.php b/includes/SpecialWantedcategories.php
new file mode 100644
index 000000000000..05ee7ec027a7
--- /dev/null
+++ b/includes/SpecialWantedcategories.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * A querypage to list the most wanted categories
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class WantedCategoriesPage extends QueryPage {
+
+ function getName() { return 'Wantedcategories'; }
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ list( $categorylinks, $page ) = $dbr->tableNamesN( 'categorylinks', 'page' );
+ $name = $dbr->addQuotes( $this->getName() );
+ return
+ "
+ SELECT
+ $name as type,
+ " . NS_CATEGORY . " as namespace,
+ cl_to as title,
+ COUNT(*) as value
+ FROM $categorylinks
+ LEFT JOIN $page ON cl_to = page_title AND page_namespace = ". NS_CATEGORY ."
+ WHERE page_title IS NULL
+ GROUP BY 1,2,3
+ ";
+ }
+
+ function sortDescending() { return true; }
+
+ /**
+ * Fetch user page links and cache their existence
+ */
+ function preprocessResults( &$db, &$res ) {
+ $batch = new LinkBatch;
+ while ( $row = $db->fetchObject( $res ) )
+ $batch->addObj( Title::makeTitleSafe( $row->namespace, $row->title ) );
+ $batch->execute();
+
+ // Back to start for display
+ if ( $db->numRows( $res ) > 0 )
+ // If there are no rows we get an error seeking.
+ $db->dataSeek( $res, 0 );
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang, $wgContLang;
+
+ $nt = Title::makeTitle( $result->namespace, $result->title );
+ $text = $wgContLang->convert( $nt->getText() );
+
+ $plink = $this->isCached() ?
+ $skin->makeLinkObj( $nt, htmlspecialchars( $text ) ) :
+ $skin->makeBrokenLinkObj( $nt, htmlspecialchars( $text ) );
+
+ $nlinks = wfMsgExt( 'nmembers', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->value ) );
+ return wfSpecialList($plink, $nlinks);
+ }
+}
+
+/**
+ * constructor
+ */
+function wfSpecialWantedCategories() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $wpp = new WantedCategoriesPage();
+
+ $wpp->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialWantedpages.php b/includes/SpecialWantedpages.php
new file mode 100644
index 000000000000..8e5cee3ec2be
--- /dev/null
+++ b/includes/SpecialWantedpages.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+class WantedPagesPage extends QueryPage {
+ var $nlinks;
+
+ function WantedPagesPage( $inc = false, $nlinks = true ) {
+ $this->setListoutput( $inc );
+ $this->nlinks = $nlinks;
+ }
+
+ function getName() {
+ return 'Wantedpages';
+ }
+
+ function isExpensive() {
+ return true;
+ }
+ function isSyndicated() { return false; }
+
+ function getSQL() {
+ global $wgWantedPagesThreshold;
+ $count = $wgWantedPagesThreshold - 1;
+ $dbr =& wfGetDB( DB_SLAVE );
+ $pagelinks = $dbr->tableName( 'pagelinks' );
+ $page = $dbr->tableName( 'page' );
+ return
+ "SELECT 'Wantedpages' AS type,
+ pl_namespace AS namespace,
+ pl_title AS title,
+ COUNT(*) AS value
+ FROM $pagelinks
+ LEFT JOIN $page AS pg1
+ ON pl_namespace = pg1.page_namespace AND pl_title = pg1.page_title
+ LEFT JOIN $page AS pg2
+ ON pl_from = pg2.page_id
+ WHERE pg1.page_namespace IS NULL
+ AND pl_namespace NOT IN ( 2, 3 )
+ AND pg2.page_namespace != 8
+ GROUP BY 1,2,3
+ HAVING COUNT(*) > $count";
+ }
+
+ /**
+ * Cache page existence for performance
+ */
+ function preprocessResults( &$db, &$res ) {
+ $batch = new LinkBatch;
+ while ( $row = $db->fetchObject( $res ) )
+ $batch->addObj( Title::makeTitleSafe( $row->namespace, $row->title ) );
+ $batch->execute();
+
+ // Back to start for display
+ if ( $db->numRows( $res ) > 0 )
+ // If there are no rows we get an error seeking.
+ $db->dataSeek( $res, 0 );
+ }
+
+
+ function formatResult( $skin, $result ) {
+ global $wgLang;
+
+ $title = Title::makeTitleSafe( $result->namespace, $result->title );
+
+ if( $this->isCached() ) {
+ # Check existence; which is stored in the link cache
+ if( !$title->exists() ) {
+ # Make a redlink
+ $pageLink = $skin->makeBrokenLinkObj( $title );
+ } else {
+ # Make a a struck-out normal link
+ $pageLink = "<s>" . $skin->makeLinkObj( $title ) . "</s>";
+ }
+ } else {
+ # Not cached? Don't bother checking existence; it can't
+ $pageLink = $skin->makeBrokenLinkObj( $title );
+ }
+
+ # Make a link to "what links here" if it's required
+ $wlhLink = $this->nlinks
+ ? $this->makeWlhLink( $title, $skin,
+ wfMsgExt( 'nlinks', array( 'parsemag', 'escape'),
+ $wgLang->formatNum( $result->value ) ) )
+ : null;
+
+ return wfSpecialList($pageLink, $wlhLink);
+ }
+
+ /**
+ * Make a "what links here" link for a specified title
+ * @param $title Title to make the link for
+ * @param $skin Skin to use
+ * @param $text Link text
+ * @return string
+ */
+ function makeWlhLink( &$title, &$skin, $text ) {
+ $wlhTitle = SpecialPage::getTitleFor( 'Whatlinkshere' );
+ return $skin->makeKnownLinkObj( $wlhTitle, $text, 'target=' . $title->getPrefixedUrl() );
+ }
+
+}
+
+/**
+ * constructor
+ */
+function wfSpecialWantedpages( $par = null, $specialPage ) {
+ $inc = $specialPage->including();
+
+ if ( $inc ) {
+ @list( $limit, $nlinks ) = explode( '/', $par, 2 );
+ $limit = (int)$limit;
+ $nlinks = $nlinks === 'nlinks';
+ $offset = 0;
+ } else {
+ list( $limit, $offset ) = wfCheckLimits();
+ $nlinks = true;
+ }
+
+ $wpp = new WantedPagesPage( $inc, $nlinks );
+
+ $wpp->doQuery( $offset, $limit, !$inc );
+}
+
+?>
diff --git a/includes/SpecialWatchlist.php b/includes/SpecialWatchlist.php
new file mode 100644
index 000000000000..33e19a2bdb2a
--- /dev/null
+++ b/includes/SpecialWatchlist.php
@@ -0,0 +1,501 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ *
+ */
+require_once( 'SpecialRecentchanges.php' );
+
+/**
+ * Constructor
+ *
+ * @param $par Parameter passed to the page
+ */
+function wfSpecialWatchlist( $par ) {
+ global $wgUser, $wgOut, $wgLang, $wgMemc, $wgRequest, $wgContLang;
+ global $wgRCShowWatchingUsers, $wgEnotifWatchlist, $wgShowUpdatedMarker;
+ global $wgEnotifWatchlist;
+ $fname = 'wfSpecialWatchlist';
+
+ $skin =& $wgUser->getSkin();
+ $specialTitle = SpecialPage::getTitleFor( 'Watchlist' );
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+
+ # Anons don't get a watchlist
+ if( $wgUser->isAnon() ) {
+ $wgOut->setPageTitle( wfMsg( 'watchnologin' ) );
+ $llink = $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Userlogin' ), wfMsgHtml( 'loginreqlink' ), 'returnto=' . $specialTitle->getPrefixedUrl() );
+ $wgOut->addHtml( wfMsgWikiHtml( 'watchlistanontext', $llink ) );
+ return;
+ } else {
+ $wgOut->setPageTitle( wfMsg( 'watchlist' ) );
+ $wgOut->setSubtitle( wfMsgWikiHtml( 'watchlistfor', htmlspecialchars( $wgUser->getName() ) ) );
+ }
+
+ if( wlHandleClear( $wgOut, $wgRequest, $par ) ) {
+ return;
+ }
+
+ $defaults = array(
+ /* float */ 'days' => floatval( $wgUser->getOption( 'watchlistdays' ) ), /* 3.0 or 0.5, watch further below */
+ /* bool */ 'hideOwn' => (int)$wgUser->getBoolOption( 'watchlisthideown' ),
+ /* bool */ 'hideBots' => (int)$wgUser->getBoolOption( 'watchlisthidebots' ),
+ /* bool */ 'hideMinor' => (int)$wgUser->getBoolOption( 'watchlisthideminor' ),
+ /* ? */ 'namespace' => 'all',
+ );
+
+ extract($defaults);
+
+ # Extract variables from the request, falling back to user preferences or
+ # other default values if these don't exist
+ $prefs['days' ] = floatval( $wgUser->getOption( 'watchlistdays' ) );
+ $prefs['hideown' ] = $wgUser->getBoolOption( 'watchlisthideown' );
+ $prefs['hidebots'] = $wgUser->getBoolOption( 'watchlisthidebots' );
+ $prefs['hideminor'] = $wgUser->getBoolOption( 'watchlisthideminor' );
+
+ # Get query variables
+ $days = $wgRequest->getVal( 'days', $prefs['days'] );
+ $hideOwn = $wgRequest->getBool( 'hideOwn', $prefs['hideown'] );
+ $hideBots = $wgRequest->getBool( 'hideBots', $prefs['hidebots'] );
+ $hideMinor = $wgRequest->getBool( 'hideMinor', $prefs['hideminor'] );
+
+ # Get namespace value, if supplied, and prepare a WHERE fragment
+ $nameSpace = $wgRequest->getIntOrNull( 'namespace' );
+ if( !is_null( $nameSpace ) ) {
+ $nameSpace = intval( $nameSpace );
+ $nameSpaceClause = " AND rc_namespace = $nameSpace";
+ } else {
+ $nameSpace = '';
+ $nameSpaceClause = '';
+ }
+
+ # Watchlist editing
+ $action = $wgRequest->getVal( 'action' );
+ $remove = $wgRequest->getVal( 'remove' );
+ $id = $wgRequest->getArray( 'id' );
+
+ $uid = $wgUser->getID();
+ if( $wgEnotifWatchlist && $wgRequest->getVal( 'reset' ) && $wgRequest->wasPosted() ) {
+ $wgUser->clearAllNotifications( $uid );
+ }
+
+ # Deleting items from watchlist
+ if(($action == 'submit') && isset($remove) && is_array($id)) {
+ $wgOut->addWikiText( wfMsg( 'removingchecked' ) );
+ $wgOut->addHTML( '<p>' );
+ foreach($id as $one) {
+ $t = Title::newFromURL( $one );
+ if( !is_null( $t ) ) {
+ $wl = WatchedItem::fromUserTitle( $wgUser, $t );
+ if( $wl->removeWatch() === false ) {
+ $wgOut->addHTML( wfMsg( 'couldntremove', htmlspecialchars($one) ) . "<br />\n" );
+ } else {
+ wfRunHooks('UnwatchArticle', array(&$wgUser, new Article($t)));
+ $wgOut->addHTML( '(' . htmlspecialchars($one) . ')<br />' );
+ }
+ } else {
+ $wgOut->addHTML( wfMsg( 'iteminvalidname', htmlspecialchars($one) ) . "<br />\n" );
+ }
+ }
+ $wgOut->addHTML( "</p>\n<p>" . wfMsg( 'wldone' ) . "</p>\n" );
+ }
+
+ $dbr =& wfGetDB( DB_SLAVE, 'watchlist' );
+ list( $page, $watchlist, $recentchanges ) = $dbr->tableNamesN( 'page', 'watchlist', 'recentchanges' );
+
+ $sql = "SELECT COUNT(*) AS n FROM $watchlist WHERE wl_user=$uid";
+ $res = $dbr->query( $sql, $fname );
+ $s = $dbr->fetchObject( $res );
+
+# Patch *** A1 *** (see A2 below)
+# adjust for page X, talk:page X, which are both stored separately, but treated together
+ $nitems = floor($s->n / 2);
+# $nitems = $s->n;
+
+ if($nitems == 0) {
+ $wgOut->addWikiText( wfMsg( 'nowatchlist' ) );
+ return;
+ }
+
+ if( is_null($days) || !is_numeric($days) ) {
+ $big = 1000; /* The magical big */
+ if($nitems > $big) {
+ # Set default cutoff shorter
+ $days = $defaults['days'] = (12.0 / 24.0); # 12 hours...
+ } else {
+ $days = $defaults['days']; # default cutoff for shortlisters
+ }
+ } else {
+ $days = floatval($days);
+ }
+
+ // Dump everything here
+ $nondefaults = array();
+
+ wfAppendToArrayIfNotDefault('days' , $days , $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault('hideOwn' , (int)$hideOwn , $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault('hideBots' , (int)$hideBots, $defaults, $nondefaults);
+ wfAppendToArrayIfNotDefault( 'hideMinor', (int)$hideMinor, $defaults, $nondefaults );
+ wfAppendToArrayIfNotDefault('namespace', $nameSpace , $defaults, $nondefaults);
+
+ if ( $days <= 0 ) {
+ $andcutoff = '';
+ $npages = wfMsg( 'watchlistall1' );
+ } else {
+ $andcutoff = "AND rc_timestamp > '".$dbr->timestamp( time() - intval( $days * 86400 ) )."'";
+ /*
+ $sql = "SELECT COUNT(*) AS n FROM $page, $revision WHERE rev_timestamp>'$cutoff' AND page_id=rev_page";
+ $res = $dbr->query( $sql, $fname );
+ $s = $dbr->fetchObject( $res );
+ $npages = $s->n;
+ */
+ $npages = 40000 * $days;
+ }
+
+ /* Edit watchlist form */
+ if($wgRequest->getBool('edit') || $par == 'edit' ) {
+ $wgOut->addWikiText( wfMsg( 'watchlistcontains', $wgLang->formatNum( $nitems ) ) .
+ "\n\n" . wfMsg( 'watcheditlist' ) );
+
+ $wgOut->addHTML( '<form action=\'' .
+ $specialTitle->escapeLocalUrl( 'action=submit' ) .
+ "' method='post'>\n" );
+
+# Patch A2
+# The following was proposed by KTurner 07.11.2004 to T.Gries
+# $sql = "SELECT distinct (wl_namespace & ~1),wl_title FROM $watchlist WHERE wl_user=$uid";
+ $sql = "SELECT wl_namespace, wl_title, page_is_redirect FROM $watchlist LEFT JOIN $page ON wl_namespace = page_namespace AND wl_title = page_title WHERE wl_user=$uid";
+
+ $res = $dbr->query( $sql, $fname );
+
+ # Batch existence check
+ $linkBatch = new LinkBatch();
+ while( $row = $dbr->fetchObject( $res ) )
+ $linkBatch->addObj( Title::makeTitleSafe( $row->wl_namespace, $row->wl_title ) );
+ $linkBatch->execute();
+
+ if( $dbr->numRows( $res ) > 0 )
+ $dbr->dataSeek( $res, 0 ); # Let's do the time warp again!
+
+ $sk = $wgUser->getSkin();
+
+ $list = array();
+ while( $s = $dbr->fetchObject( $res ) ) {
+ $list[$s->wl_namespace][$s->wl_title] = $s->page_is_redirect;
+ }
+
+ // TODO: Display a TOC
+ foreach($list as $ns => $titles) {
+ if (Namespace::isTalk($ns))
+ continue;
+ if ($ns != NS_MAIN)
+ $wgOut->addHTML( '<h2>' . $wgContLang->getFormattedNsText( $ns ) . '</h2>' );
+ $wgOut->addHTML( '<ul>' );
+ foreach( $titles as $title => $redir ) {
+ $titleObj = Title::makeTitle( $ns, $title );
+ if( is_null( $titleObj ) ) {
+ $wgOut->addHTML(
+ '<!-- bad title "' .
+ htmlspecialchars( $s->wl_title ) . '" in namespace ' . $s->wl_namespace . " -->\n"
+ );
+ } else {
+ global $wgContLang;
+ $toolLinks = array();
+ $pageLink = $sk->makeLinkObj( $titleObj );
+ $toolLinks[] = $sk->makeLinkObj( $titleObj->getTalkPage(), $wgLang->getNsText( NS_TALK ) );
+ if( $titleObj->exists() )
+ $toolLinks[] = $sk->makeKnownLinkObj( $titleObj, wfMsgHtml( 'history_short' ), 'action=history' );
+ $toolLinks = '(' . implode( ' | ', $toolLinks ) . ')';
+ $checkbox = '<input type="checkbox" name="id[]" value="' . htmlspecialchars( $titleObj->getPrefixedText() ) . '" /> ' . ( $wgContLang->isRTL() ? '&rlm;' : '&lrm;' );
+ if( $redir ) {
+ $spanopen = '<span class="watchlistredir">';
+ $spanclosed = '</span>';
+ } else {
+ $spanopen = $spanclosed = '';
+ }
+
+ $wgOut->addHTML( "<li>{$checkbox}{$spanopen}{$pageLink}{$spanclosed} {$toolLinks}</li>\n" );
+ }
+ }
+ $wgOut->addHTML( '</ul>' );
+ }
+ $wgOut->addHTML(
+ wfSubmitButton( wfMsg('removechecked'), array('name' => 'remove') ) .
+ "\n</form>\n"
+ );
+
+ return;
+ }
+
+ # If the watchlist is relatively short, it's simplest to zip
+ # down its entirety and then sort the results.
+
+ # If it's relatively long, it may be worth our while to zip
+ # through the time-sorted page list checking for watched items.
+
+ # Up estimate of watched items by 15% to compensate for talk pages...
+
+ # Toggles
+ $andHideOwn = $hideOwn ? "AND (rc_user <> $uid)" : '';
+ $andHideBots = $hideBots ? "AND (rc_bot = 0)" : '';
+ $andHideMinor = $hideMinor ? 'AND rc_minor = 0' : '';
+
+ # Show watchlist header
+ $header = '';
+ if( $wgUser->getOption( 'enotifwatchlistpages' ) && $wgEnotifWatchlist) {
+ $header .= wfMsg( 'wlheader-enotif' ) . "\n";
+ }
+ if ( $wgEnotifWatchlist && $wgShowUpdatedMarker ) {
+ $header .= wfMsg( 'wlheader-showupdated' ) . "\n";
+ }
+
+ # Toggle watchlist content (all recent edits or just the latest)
+ if( $wgUser->getOption( 'extendwatchlist' )) {
+ $andLatest='';
+ $limitWatchlist = 'LIMIT ' . intval( $wgUser->getOption( 'wllimit' ) );
+ } else {
+ $andLatest= 'AND rc_this_oldid=page_latest';
+ $limitWatchlist = '';
+ }
+
+ # TODO: Consider removing the third parameter
+ $header .= wfMsgExt( 'watchdetails', array( 'parsemag' ), $wgLang->formatNum( $nitems ),
+ $wgLang->formatNum( $npages ), '',
+ $specialTitle->getFullUrl( 'edit=yes' ) );
+ $wgOut->addWikiText( $header );
+
+ if ( $wgEnotifWatchlist && $wgShowUpdatedMarker ) {
+ $wgOut->addHTML( '<form action="' .
+ $specialTitle->escapeLocalUrl() .
+ '" method="post"><input type="submit" name="dummy" value="' .
+ htmlspecialchars( wfMsg( 'enotif_reset' ) ) .
+ '" /><input type="hidden" name="reset" value="all" /></form>' .
+ "\n\n" );
+ }
+
+ $sql = "SELECT *
+ FROM $watchlist,$recentchanges,$page
+ WHERE wl_user=$uid
+ AND wl_namespace=rc_namespace
+ AND wl_title=rc_title
+ AND rc_cur_id=page_id
+ $andcutoff
+ $andLatest
+ $andHideOwn
+ $andHideBots
+ $andHideMinor
+ $nameSpaceClause
+ ORDER BY rc_timestamp DESC
+ $limitWatchlist";
+
+ $res = $dbr->query( $sql, $fname );
+ $numRows = $dbr->numRows( $res );
+
+ /* Start bottom header */
+ $wgOut->addHTML( "<hr />\n" );
+
+ if($days >= 1) {
+ $wgOut->addWikiText( wfMsg( 'rcnote', $wgLang->formatNum( $numRows ),
+ $wgLang->formatNum( $days ), $wgLang->timeAndDate( wfTimestampNow(), true ) ) . '<br />' , false );
+ } elseif($days > 0) {
+ $wgOut->addWikiText( wfMsg( 'wlnote', $wgLang->formatNum( $numRows ),
+ $wgLang->formatNum( round($days*24) ) ) . '<br />' , false );
+ }
+
+ $wgOut->addHTML( "\n" . wlCutoffLinks( $days, 'Watchlist', $nondefaults ) . "<br />\n" );
+
+ # Spit out some control panel links
+ $thisTitle = SpecialPage::getTitleFor( 'Watchlist' );
+ $skin = $wgUser->getSkin();
+
+ # Hide/show bot edits
+ $label = $hideBots ? wfMsgHtml( 'watchlist-show-bots' ) : wfMsgHtml( 'watchlist-hide-bots' );
+ $linkBits = wfArrayToCGI( array( 'hideBots' => 1 - (int)$hideBots ), $nondefaults );
+ $links[] = $skin->makeKnownLinkObj( $thisTitle, $label, $linkBits );
+
+ # Hide/show own edits
+ $label = $hideOwn ? wfMsgHtml( 'watchlist-show-own' ) : wfMsgHtml( 'watchlist-hide-own' );
+ $linkBits = wfArrayToCGI( array( 'hideOwn' => 1 - (int)$hideOwn ), $nondefaults );
+ $links[] = $skin->makeKnownLinkObj( $thisTitle, $label, $linkBits );
+
+ # Hide/show minor edits
+ $label = $hideMinor ? wfMsgHtml( 'watchlist-show-minor' ) : wfMsgHtml( 'watchlist-hide-minor' );
+ $linkBits = wfArrayToCGI( array( 'hideMinor' => 1 - (int)$hideMinor ), $nondefaults );
+ $links[] = $skin->makeKnownLinkObj( $thisTitle, $label, $linkBits );
+
+ $wgOut->addHTML( implode( ' | ', $links ) );
+
+ # Form for namespace filtering
+ $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl() ) );
+ $form .= '<p>';
+ $form .= Xml::label( wfMsg( 'namespace' ), 'namespace' ) . '&nbsp;';
+ $form .= Xml::namespaceSelector( $nameSpace, '' ) . '&nbsp;';
+ $form .= Xml::submitButton( wfMsg( 'allpagessubmit' ) ) . '</p>';
+ $form .= Xml::hidden( 'days', $days );
+ if( $hideOwn )
+ $form .= Xml::hidden( 'hideOwn', 1 );
+ if( $hideBots )
+ $form .= Xml::hidden( 'hideBots', 1 );
+ if( $hideMinor )
+ $form .= Xml::hidden( 'hideMinor', 1 );
+ $form .= Xml::closeElement( 'form' );
+ $wgOut->addHtml( $form );
+
+ # If there's nothing to show, stop here
+ if( $numRows == 0 ) {
+ $wgOut->addWikiText( wfMsgNoTrans( 'watchnochange' ) );
+ return;
+ }
+
+ /* End bottom header */
+
+ $list = ChangesList::newFromUser( $wgUser );
+
+ $s = $list->beginRecentChangesList();
+ $counter = 1;
+ while ( $obj = $dbr->fetchObject( $res ) ) {
+ # Make RC entry
+ $rc = RecentChange::newFromRow( $obj );
+ $rc->counter = $counter++;
+
+ if ( $wgShowUpdatedMarker ) {
+ $updated = $obj->wl_notificationtimestamp;
+ } else {
+ // Same visual appearance as MW 1.4
+ $updated = true;
+ }
+
+ if ($wgRCShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' )) {
+ $sql3 = "SELECT COUNT(*) AS n FROM $watchlist WHERE wl_title='" .$dbr->strencode($obj->page_title). "' AND wl_namespace='{$obj->page_namespace}'" ;
+ $res3 = $dbr->query( $sql3, $fname );
+ $x = $dbr->fetchObject( $res3 );
+ $rc->numberofWatchingusers = $x->n;
+ } else {
+ $rc->numberofWatchingusers = 0;
+ }
+
+ $s .= $list->recentChangesLine( $rc, $updated );
+ }
+ $s .= $list->endRecentChangesList();
+
+ $dbr->freeResult( $res );
+ $wgOut->addHTML( $s );
+
+}
+
+function wlHoursLink( $h, $page, $options = array() ) {
+ global $wgUser, $wgLang, $wgContLang;
+ $sk = $wgUser->getSkin();
+ $s = $sk->makeKnownLink(
+ $wgContLang->specialPage( $page ),
+ $wgLang->formatNum( $h ),
+ wfArrayToCGI( array('days' => ($h / 24.0)), $options ) );
+ return $s;
+}
+
+function wlDaysLink( $d, $page, $options = array() ) {
+ global $wgUser, $wgLang, $wgContLang;
+ $sk = $wgUser->getSkin();
+ $s = $sk->makeKnownLink(
+ $wgContLang->specialPage( $page ),
+ ($d ? $wgLang->formatNum( $d ) : wfMsgHtml( 'watchlistall2' ) ),
+ wfArrayToCGI( array('days' => $d), $options ) );
+ return $s;
+}
+
+/**
+ * Returns html
+ */
+function wlCutoffLinks( $days, $page = 'Watchlist', $options = array() ) {
+ $hours = array( 1, 2, 6, 12 );
+ $days = array( 1, 3, 7 );
+ $i = 0;
+ foreach( $hours as $h ) {
+ $hours[$i++] = wlHoursLink( $h, $page, $options );
+ }
+ $i = 0;
+ foreach( $days as $d ) {
+ $days[$i++] = wlDaysLink( $d, $page, $options );
+ }
+ return wfMsgExt('wlshowlast',
+ array('parseinline', 'replaceafter'),
+ implode(' | ', $hours),
+ implode(' | ', $days),
+ wlDaysLink( 0, $page, $options ) );
+}
+
+/**
+ * Count the number of items on a user's watchlist
+ *
+ * @param $talk Include talk pages
+ * @return integer
+ */
+function wlCountItems( &$user, $talk = true ) {
+ $dbr =& wfGetDB( DB_SLAVE, 'watchlist' );
+
+ # Fetch the raw count
+ $res = $dbr->select( 'watchlist', 'COUNT(*) AS count', array( 'wl_user' => $user->mId ), 'wlCountItems' );
+ $row = $dbr->fetchObject( $res );
+ $count = $row->count;
+ $dbr->freeResult( $res );
+
+ # Halve to remove talk pages if needed
+ if( !$talk )
+ $count = floor( $count / 2 );
+
+ return( $count );
+}
+
+/**
+ * Allow the user to clear their watchlist
+ *
+ * @param $out Output object
+ * @param $request Request object
+ * @param $par Parameters passed to the watchlist page
+ * @return bool True if it's been taken care of; false indicates the watchlist
+ * code needs to do something further
+ */
+function wlHandleClear( &$out, &$request, $par ) {
+ global $wgLang;
+
+ # Check this function has something to do
+ if( $request->getText( 'action' ) == 'clear' || $par == 'clear' ) {
+ global $wgUser;
+ $out->setPageTitle( wfMsgHtml( 'clearwatchlist' ) );
+ $count = wlCountItems( $wgUser );
+ if( $count > 0 ) {
+ # See if we're clearing or confirming
+ if( $request->wasPosted() && $wgUser->matchEditToken( $request->getText( 'token' ), 'clearwatchlist' ) ) {
+ # Clearing, so do it and report the result
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'watchlist', array( 'wl_user' => $wgUser->mId ), 'wlHandleClear' );
+ $out->addWikiText( wfMsgExt( 'watchlistcleardone', array( 'parsemag', 'escape'), $wgLang->formatNum( $count ) ) );
+ $out->returnToMain();
+ } else {
+ # Confirming, so show a form
+ $wlTitle = SpecialPage::getTitleFor( 'Watchlist' );
+ $out->addHTML( wfElement( 'form', array( 'method' => 'post', 'action' => $wlTitle->getLocalUrl( 'action=clear' ) ), NULL ) );
+ $out->addWikiText( wfMsgExt( 'watchlistcount', array( 'parsemag', 'escape'), $wgLang->formatNum( $count ) ) );
+ $out->addWikiText( wfMsg( 'watchlistcleartext' ) );
+ $out->addHTML(
+ wfHidden( 'token', $wgUser->editToken( 'clearwatchlist' ) ) .
+ wfElement( 'input', array( 'type' => 'submit', 'name' => 'submit', 'value' => wfMsgHtml( 'watchlistclearbutton' ) ), '' ) .
+ wfCloseElement( 'form' )
+ );
+ }
+ return( true );
+ } else {
+ # Nothing on the watchlist; nothing to do here
+ $out->addWikiText( wfMsg( 'nowatchlist' ) );
+ $out->returnToMain();
+ return( true );
+ }
+ } else {
+ return( false );
+ }
+}
+?>
diff --git a/includes/SpecialWhatlinkshere.php b/includes/SpecialWhatlinkshere.php
new file mode 100644
index 000000000000..bed783f84a13
--- /dev/null
+++ b/includes/SpecialWhatlinkshere.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * Entry point
+ * @param string $par An article name ??
+ */
+function wfSpecialWhatlinkshere($par = NULL) {
+ global $wgRequest;
+ $page = new WhatLinksHerePage( $wgRequest, $par );
+ $page->execute();
+}
+
+class WhatLinksHerePage {
+ var $request, $par;
+ var $limit, $from, $dir, $target;
+ var $selfTitle, $skin;
+
+ function WhatLinksHerePage( &$request, $par = null ) {
+ global $wgUser;
+ $this->request =& $request;
+ $this->skin =& $wgUser->getSkin();
+ $this->par = $par;
+ }
+
+ function execute() {
+ global $wgOut;
+
+ $this->limit = min( $this->request->getInt( 'limit', 50 ), 5000 );
+ if ( $this->limit <= 0 ) {
+ $this->limit = 50;
+ }
+ $this->from = $this->request->getInt( 'from' );
+ $this->dir = $this->request->getText( 'dir', 'next' );
+ if ( $this->dir != 'prev' ) {
+ $this->dir = 'next';
+ }
+
+ $targetString = isset($this->par) ? $this->par : $this->request->getVal( 'target' );
+
+ if (is_null($targetString)) {
+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
+ return;
+ }
+
+ $this->target = Title::newFromURL( $targetString );
+ if( !$this->target ) {
+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
+ return;
+ }
+ $this->selfTitle = Title::makeTitleSafe( NS_SPECIAL,
+ 'Whatlinkshere/' . $this->target->getPrefixedDBkey() );
+ $wgOut->setPagetitle( $this->target->getPrefixedText() );
+ $wgOut->setSubtitle( wfMsg( 'linklistsub' ) );
+
+ $wgOut->addHTML( wfMsg( 'whatlinkshere-barrow' ) . ' ' .$this->skin->makeLinkObj($this->target, '', 'redirect=no' )."<br />\n");
+
+ $this->showIndirectLinks( 0, $this->target, $this->limit, $this->from, $this->dir );
+ }
+
+ /**
+ * @param int $level Recursion level
+ * @param Title $target Target title
+ * @param int $limit Number of entries to display
+ * @param Title $from Display from this article ID
+ * @param string $dir 'next' or 'prev', whether $fromTitle is the start or end of the list
+ * @private
+ */
+ function showIndirectLinks( $level, $target, $limit, $from = 0, $dir = 'next' ) {
+ global $wgOut;
+ $fname = 'WhatLinksHerePage::showIndirectLinks';
+
+ $dbr =& wfGetDB( DB_READ );
+
+ // Some extra validation
+ $from = intval( $from );
+ if ( !$from && $dir == 'prev' ) {
+ // Before start? No make sense
+ $dir = 'next';
+ }
+
+ // Make the query
+ $plConds = array(
+ 'page_id=pl_from',
+ 'pl_namespace' => $target->getNamespace(),
+ 'pl_title' => $target->getDBkey(),
+ );
+
+ $tlConds = array(
+ 'page_id=tl_from',
+ 'tl_namespace' => $target->getNamespace(),
+ 'tl_title' => $target->getDBkey(),
+ );
+
+ if ( $from ) {
+ if ( 'prev' == $dir ) {
+ $offsetCond = "page_id < $from";
+ $options = array( 'ORDER BY page_id DESC' );
+ } else {
+ $offsetCond = "page_id >= $from";
+ $options = array( 'ORDER BY page_id' );
+ }
+ } else {
+ $offsetCond = false;
+ $options = array( 'ORDER BY page_id,is_template DESC' );
+ }
+ // Read an extra row as an at-end check
+ $queryLimit = $limit + 1;
+ $options['LIMIT'] = $queryLimit;
+ if ( $offsetCond ) {
+ $tlConds[] = $offsetCond;
+ $plConds[] = $offsetCond;
+ }
+ $fields = array( 'page_id', 'page_namespace', 'page_title', 'page_is_redirect' );
+
+ $plRes = $dbr->select( array( 'pagelinks', 'page' ), $fields,
+ $plConds, $fname, $options );
+ $tlRes = $dbr->select( array( 'templatelinks', 'page' ), $fields,
+ $tlConds, $fname, $options );
+
+ if ( !$dbr->numRows( $plRes ) && !$dbr->numRows( $tlRes ) ) {
+ if ( 0 == $level ) {
+ $wgOut->addWikiText( wfMsg( 'nolinkshere', $this->target->getPrefixedText() ) );
+ }
+ return;
+ }
+
+ // Read the rows into an array and remove duplicates
+ // templatelinks comes second so that the templatelinks row overwrites the
+ // pagelinks row, so we get (inclusion) rather than nothing
+ while ( $row = $dbr->fetchObject( $plRes ) ) {
+ $row->is_template = 0;
+ $rows[$row->page_id] = $row;
+ }
+ $dbr->freeResult( $plRes );
+ while ( $row = $dbr->fetchObject( $tlRes ) ) {
+ $row->is_template = 1;
+ $rows[$row->page_id] = $row;
+ }
+ $dbr->freeResult( $tlRes );
+
+ // Sort by key and then change the keys to 0-based indices
+ ksort( $rows );
+ $rows = array_values( $rows );
+
+ $numRows = count( $rows );
+
+ // Work out the start and end IDs, for prev/next links
+ if ( $dir == 'prev' ) {
+ // Descending order
+ if ( $numRows > $limit ) {
+ // More rows available before these ones
+ // Get the ID from the next row past the end of the displayed set
+ $prevId = $rows[$limit]->page_id;
+ // Remove undisplayed rows
+ $rows = array_slice( $rows, 0, $limit );
+ } else {
+ // No more rows available before
+ $prevId = 0;
+ }
+ // Assume that the ID specified in $from exists, so there must be another page
+ $nextId = $from;
+
+ // Reverse order ready for display
+ $rows = array_reverse( $rows );
+ } else {
+ // Ascending
+ if ( $numRows > $limit ) {
+ // More rows available after these ones
+ // Get the ID from the last row in the result set
+ $nextId = $rows[$limit]->page_id;
+ // Remove undisplayed rows
+ $rows = array_slice( $rows, 0, $limit );
+ } else {
+ // No more rows after
+ $nextId = false;
+ }
+ $prevId = $from;
+ }
+
+ if ( 0 == $level ) {
+ $wgOut->addWikiText( wfMsg( 'linkshere', $this->target->getPrefixedText() ) );
+ }
+ $isredir = wfMsg( 'isredirect' );
+ $istemplate = wfMsg( 'istemplate' );
+
+ if( $level == 0 ) {
+ $prevnext = $this->getPrevNext( $limit, $prevId, $nextId );
+ $wgOut->addHTML( $prevnext );
+ }
+
+ $wgOut->addHTML( '<ul>' );
+ foreach ( $rows as $row ) {
+ $nt = Title::makeTitle( $row->page_namespace, $row->page_title );
+
+ if ( $row->page_is_redirect ) {
+ $extra = 'redirect=no';
+ } else {
+ $extra = '';
+ }
+
+ $link = $this->skin->makeKnownLinkObj( $nt, '', $extra );
+ $wgOut->addHTML( '<li>'.$link );
+
+ // Display properties (redirect or template)
+ $props = array();
+ if ( $row->page_is_redirect ) {
+ $props[] = $isredir;
+ }
+ if ( $row->is_template ) {
+ $props[] = $istemplate;
+ }
+ if ( count( $props ) ) {
+ // FIXME? Cultural assumption, hard-coded punctuation
+ $wgOut->addHTML( ' (' . implode( ', ', $props ) . ') ' );
+ }
+
+ if ( $row->page_is_redirect ) {
+ if ( $level < 2 ) {
+ $this->showIndirectLinks( $level + 1, $nt, 500 );
+ }
+ }
+ $wgOut->addHTML( "</li>\n" );
+ }
+ $wgOut->addHTML( "</ul>\n" );
+
+ if( $level == 0 ) {
+ $wgOut->addHTML( $prevnext );
+ }
+ }
+
+ function makeSelfLink( $text, $query ) {
+ return $this->skin->makeKnownLinkObj( $this->selfTitle, $text, $query );
+ }
+
+ function getPrevNext( $limit, $prevId, $nextId ) {
+ global $wgLang;
+ $fmtLimit = $wgLang->formatNum( $limit );
+ $prev = wfMsg( 'prevn', $fmtLimit );
+ $next = wfMsg( 'nextn', $fmtLimit );
+
+ if ( 0 != $prevId ) {
+ $prevLink = $this->makeSelfLink( $prev, "limit={$limit}&from={$prevId}&dir=prev" );
+ } else {
+ $prevLink = $prev;
+ }
+ if ( 0 != $nextId ) {
+ $nextLink = $this->makeSelfLink( $next, "limit={$limit}&from={$nextId}" );
+ } else {
+ $nextLink = $next;
+ }
+ $nums = $this->numLink( 20, $prevId ) . ' | ' .
+ $this->numLink( 50, $prevId ) . ' | ' .
+ $this->numLink( 100, $prevId ) . ' | ' .
+ $this->numLink( 250, $prevId ) . ' | ' .
+ $this->numLink( 500, $prevId );
+
+ return wfMsg( 'viewprevnext', $prevLink, $nextLink, $nums );
+ }
+
+ function numLink( $limit, $from ) {
+ global $wgLang;
+ $query = "limit={$limit}&from={$from}";
+ $fmtLimit = $wgLang->formatNum( $limit );
+ return $this->makeSelfLink( $fmtLimit, $query );
+ }
+}
+
+?>
diff --git a/includes/SquidUpdate.php b/includes/SquidUpdate.php
new file mode 100644
index 000000000000..2e2a4a5d86af
--- /dev/null
+++ b/includes/SquidUpdate.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * See deferred.txt
+ * @package MediaWiki
+ */
+
+/**
+ *
+ * @package MediaWiki
+ */
+class SquidUpdate {
+ var $urlArr, $mMaxTitles;
+
+ function SquidUpdate( $urlArr = Array(), $maxTitles = false ) {
+ global $wgMaxSquidPurgeTitles;
+ if ( $maxTitles === false ) {
+ $this->mMaxTitles = $wgMaxSquidPurgeTitles;
+ } else {
+ $this->mMaxTitles = $maxTitles;
+ }
+ if ( count( $urlArr ) > $this->mMaxTitles ) {
+ $urlArr = array_slice( $urlArr, 0, $this->mMaxTitles );
+ }
+ $this->urlArr = $urlArr;
+ }
+
+ /* static */ function newFromLinksTo( &$title ) {
+ $fname = 'SquidUpdate::newFromLinksTo';
+ wfProfileIn( $fname );
+
+ # Get a list of URLs linking to this page
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( array( 'links', 'page' ),
+ array( 'page_namespace', 'page_title' ),
+ array(
+ 'pl_namespace' => $title->getNamespace(),
+ 'pl_title' => $title->getDbKey(),
+ 'pl_from=page_id' ),
+ $fname );
+ $blurlArr = $title->getSquidURLs();
+ if ( $dbr->numRows( $res ) <= $this->mMaxTitles ) {
+ while ( $BL = $dbr->fetchObject ( $res ) )
+ {
+ $tobj = Title::makeTitle( $BL->page_namespace, $BL->page_title ) ;
+ $blurlArr[] = $tobj->getInternalURL();
+ }
+ }
+ $dbr->freeResult ( $res ) ;
+
+ wfProfileOut( $fname );
+ return new SquidUpdate( $blurlArr );
+ }
+
+ /* static */ function newFromTitles( &$titles, $urlArr = array() ) {
+ global $wgMaxSquidPurgeTitles;
+ if ( count( $titles ) > $wgMaxSquidPurgeTitles ) {
+ $titles = array_slice( $titles, 0, $wgMaxSquidPurgeTitles );
+ }
+ foreach ( $titles as $title ) {
+ $urlArr[] = $title->getInternalURL();
+ }
+ return new SquidUpdate( $urlArr );
+ }
+
+ /* static */ function newSimplePurge( &$title ) {
+ $urlArr = $title->getSquidURLs();
+ return new SquidUpdate( $urlArr );
+ }
+
+ function doUpdate() {
+ SquidUpdate::purge( $this->urlArr );
+ }
+
+ /* Purges a list of Squids defined in $wgSquidServers.
+ $urlArr should contain the full URLs to purge as values
+ (example: $urlArr[] = 'http://my.host/something')
+ XXX report broken Squids per mail or log */
+
+ /* static */ function purge( $urlArr ) {
+ global $wgSquidServers, $wgHTCPMulticastAddress, $wgHTCPPort;
+
+ /*if ( (@$wgSquidServers[0]) == 'echo' ) {
+ echo implode("<br />\n", $urlArr) . "<br />\n";
+ return;
+ }*/
+
+ if ( $wgHTCPMulticastAddress && $wgHTCPPort )
+ SquidUpdate::HTCPPurge( $urlArr );
+
+ $fname = 'SquidUpdate::purge';
+ wfProfileIn( $fname );
+
+ $maxsocketspersquid = 8; // socket cap per Squid
+ $urlspersocket = 400; // 400 seems to be a good tradeoff, opening a socket takes a while
+ $firsturl = SquidUpdate::expand( $urlArr[0] );
+ unset($urlArr[0]);
+ $urlArr = array_values($urlArr);
+ $sockspersq = max(ceil(count($urlArr) / $urlspersocket ),1);
+ if ($sockspersq == 1) {
+ /* the most common case */
+ $urlspersocket = count($urlArr);
+ } else if ($sockspersq > $maxsocketspersquid ) {
+ $urlspersocket = ceil(count($urlArr) / $maxsocketspersquid);
+ $sockspersq = $maxsocketspersquid;
+ }
+ $totalsockets = count($wgSquidServers) * $sockspersq;
+ $sockets = Array();
+
+ /* this sets up the sockets and tests the first socket for each server. */
+ for ($ss=0;$ss < count($wgSquidServers);$ss++) {
+ $failed = false;
+ $so = 0;
+ while ($so < $sockspersq && !$failed) {
+ if ($so == 0) {
+ /* first socket for this server, do the tests */
+ @list($server, $port) = explode(':', $wgSquidServers[$ss]);
+ if(!isset($port)) $port = 80;
+ #$this->debug("Opening socket to $server:$port");
+ $error = $errstr = false;
+ $socket = @fsockopen($server, $port, $error, $errstr, 3);
+ #$this->debug("\n");
+ if (!$socket) {
+ $failed = true;
+ $totalsockets -= $sockspersq;
+ } else {
+ $msg = 'PURGE ' . $firsturl . " HTTP/1.0\r\n".
+ "Connection: Keep-Alive\r\n\r\n";
+ #$this->debug($msg);
+ @fputs($socket,$msg);
+ #$this->debug("...");
+ $res = @fread($socket,512);
+ #$this->debug("\n");
+ /* Squid only returns http headers with 200 or 404 status,
+ if there's more returned something's wrong */
+ if (strlen($res) > 250) {
+ fclose($socket);
+ $failed = true;
+ $totalsockets -= $sockspersq;
+ } else {
+ @stream_set_blocking($socket,false);
+ $sockets[] = $socket;
+ }
+ }
+ } else {
+ /* open the remaining sockets for this server */
+ list($server, $port) = explode(':', $wgSquidServers[$ss]);
+ if(!isset($port)) $port = 80;
+ $sockets[$so+1] = @fsockopen($server, $port, $error, $errstr, 2);
+ @stream_set_blocking($sockets[$so+1],false);
+ }
+ $so++;
+ }
+ }
+
+ if ($urlspersocket > 0) {
+ /* now do the heavy lifting. The fread() relies on Squid returning only the headers */
+ for ($r=0;$r < $urlspersocket;$r++) {
+ for ($s=0;$s < $totalsockets;$s++) {
+ if($r != 0) {
+ $res = '';
+ $esc = 0;
+ while (strlen($res) < 100 && $esc < 200 ) {
+ $res .= @fread($sockets[$s],512);
+ $esc++;
+ usleep(20);
+ }
+ }
+ $urindex = $r + $urlspersocket * ($s - $sockspersq * floor($s / $sockspersq));
+ $url = SquidUpdate::expand( $urlArr[$urindex] );
+ $msg = 'PURGE ' . $url . " HTTP/1.0\r\n".
+ "Connection: Keep-Alive\r\n\r\n";
+ #$this->debug($msg);
+ @fputs($sockets[$s],$msg);
+ #$this->debug("\n");
+ }
+ }
+ }
+ #$this->debug("Reading response...");
+ foreach ($sockets as $socket) {
+ $res = '';
+ $esc = 0;
+ while (strlen($res) < 100 && $esc < 200 ) {
+ $res .= @fread($socket,1024);
+ $esc++;
+ usleep(20);
+ }
+
+ @fclose($socket);
+ }
+ #$this->debug("\n");
+ wfProfileOut( $fname );
+ }
+
+ /* static */ function HTCPPurge( $urlArr ) {
+ global $wgHTCPMulticastAddress, $wgHTCPMulticastTTL, $wgHTCPPort;
+ $fname = 'SquidUpdate::HTCPPurge';
+ wfProfileIn( $fname );
+
+ $htcpOpCLR = 4; // HTCP CLR
+
+ // FIXME PHP doesn't support these socket constants (include/linux/in.h)
+ if( !defined( "IPPROTO_IP" ) ) {
+ define( "IPPROTO_IP", 0 );
+ define( "IP_MULTICAST_LOOP", 34 );
+ define( "IP_MULTICAST_TTL", 33 );
+ }
+
+ // pfsockopen doesn't work because we need set_sock_opt
+ $conn = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
+ if ( $conn ) {
+ // Set socket options
+ socket_set_option( $conn, IPPROTO_IP, IP_MULTICAST_LOOP, 0 );
+ if ( $wgHTCPMulticastTTL != 1 )
+ socket_set_option( $conn, IPPROTO_IP, IP_MULTICAST_TTL,
+ $wgHTCPMulticastTTL );
+
+ foreach ( $urlArr as $url ) {
+ if( !is_string( $url ) ) {
+ wfDebugDieBacktrace( 'Bad purge URL' );
+ }
+ $url = SquidUpdate::expand( $url );
+
+ // Construct a minimal HTCP request diagram
+ // as per RFC 2756
+ // Opcode 'CLR', no response desired, no auth
+ $htcpTransID = rand();
+
+ $htcpSpecifier = pack( 'na4na*na8n',
+ 4, 'HEAD', strlen( $url ), $url,
+ 8, 'HTTP/1.0', 0 );
+
+ $htcpDataLen = 8 + 2 + strlen( $htcpSpecifier );
+ $htcpLen = 4 + $htcpDataLen + 2;
+
+ // Note! Squid gets the bit order of the first
+ // word wrong, wrt the RFC. Apparently no other
+ // implementation exists, so adapt to Squid
+ $htcpPacket = pack( 'nxxnCxNxxa*n',
+ $htcpLen, $htcpDataLen, $htcpOpCLR,
+ $htcpTransID, $htcpSpecifier, 2);
+
+ // Send out
+ wfDebug( "Purging URL $url via HTCP\n" );
+ socket_sendto( $conn, $htcpPacket, $htcpLen, 0,
+ $wgHTCPMulticastAddress, $wgHTCPPort );
+ }
+ } else {
+ $errstr = socket_strerror( socket_last_error() );
+ wfDebug( "SquidUpdate::HTCPPurge(): Error opening UDP socket: $errstr\n" );
+ }
+ wfProfileOut( $fname );
+ }
+
+ function debug( $text ) {
+ global $wgDebugSquid;
+ if ( $wgDebugSquid ) {
+ wfDebug( $text );
+ }
+ }
+
+ /**
+ * Expand local URLs to fully-qualified URLs using the internal protocol
+ * and host defined in $wgInternalServer. Input that's already fully-
+ * qualified will be passed through unchanged.
+ *
+ * This is used to generate purge URLs that may be either local to the
+ * main wiki or include a non-native host, such as images hosted on a
+ * second internal server.
+ *
+ * Client functions should not need to call this.
+ *
+ * @return string
+ */
+ static function expand( $url ) {
+ global $wgInternalServer;
+ if( $url != '' && $url{0} == '/' ) {
+ return $wgInternalServer . $url;
+ }
+ return $url;
+ }
+}
+?>
diff --git a/includes/StreamFile.php b/includes/StreamFile.php
new file mode 100644
index 000000000000..dc653e57bf6e
--- /dev/null
+++ b/includes/StreamFile.php
@@ -0,0 +1,72 @@
+<?php
+/** */
+
+/** */
+function wfStreamFile( $fname ) {
+ $stat = @stat( $fname );
+ if ( !$stat ) {
+ header( 'HTTP/1.0 404 Not Found' );
+ header( 'Cache-Control: no-cache' );
+ header( 'Content-Type: text/html; charset=utf-8' );
+ $encFile = htmlspecialchars( $fname );
+ $encScript = htmlspecialchars( $_SERVER['SCRIPT_NAME'] );
+ echo "<html><body>
+<h1>File not found</h1>
+<p>Although this PHP script ($encScript) exists, the file requested for output
+($encFile) does not.</p>
+</body></html>
+";
+ return;
+ }
+
+ header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $stat['mtime'] ) . ' GMT' );
+
+ // Cancel output buffering and gzipping if set
+ wfResetOutputBuffers();
+
+ $type = wfGetType( $fname );
+ if ( $type and $type!="unknown/unknown") {
+ header("Content-type: $type");
+ } else {
+ header('Content-type: application/x-wiki');
+ }
+
+ if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
+ $modsince = preg_replace( '/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
+ $sinceTime = strtotime( $modsince );
+ if ( $stat['mtime'] <= $sinceTime ) {
+ header( "HTTP/1.0 304 Not Modified" );
+ return;
+ }
+ }
+
+ header( 'Content-Length: ' . $stat['size'] );
+
+ readfile( $fname );
+}
+
+/** */
+function wfGetType( $filename ) {
+ global $wgTrivialMimeDetection;
+
+ # trivial detection by file extension,
+ # used for thumbnails (thumb.php)
+ if ($wgTrivialMimeDetection) {
+ $ext= strtolower(strrchr($filename, '.'));
+
+ switch ($ext) {
+ case '.gif': return 'image/gif';
+ case '.png': return 'image/png';
+ case '.jpg': return 'image/jpeg';
+ case '.jpeg': return 'image/jpeg';
+ }
+
+ return 'unknown/unknown';
+ }
+ else {
+ $magic=& MimeMagic::singleton();
+ return $magic->guessMimeType($filename); //full fancy mime detection
+ }
+}
+
+?>
diff --git a/includes/StringUtils.php b/includes/StringUtils.php
new file mode 100644
index 000000000000..0090604dd589
--- /dev/null
+++ b/includes/StringUtils.php
@@ -0,0 +1,301 @@
+<?php
+
+class StringUtils {
+ /**
+ * Perform an operation equivalent to
+ *
+ * preg_replace( "!$startDelim(.*?)$endDelim!", $replace, $subject );
+ *
+ * except that it's worst-case O(N) instead of O(N^2)
+ *
+ * Compared to delimiterReplace(), this implementation is fast but memory-
+ * hungry and inflexible. The memory requirements are such that I don't
+ * recommend using it on anything but guaranteed small chunks of text.
+ */
+ static function hungryDelimiterReplace( $startDelim, $endDelim, $replace, $subject ) {
+ $segments = explode( $startDelim, $subject );
+ $output = array_shift( $segments );
+ foreach ( $segments as $s ) {
+ $endDelimPos = strpos( $s, $endDelim );
+ if ( $endDelimPos === false ) {
+ $output .= $startDelim . $s;
+ } else {
+ $output .= $replace . substr( $s, $endDelimPos + strlen( $endDelim ) );
+ }
+ }
+ return $output;
+ }
+
+ /**
+ * Perform an operation equivalent to
+ *
+ * preg_replace_callback( "!$startDelim(.*)$endDelim!s$flags", $callback, $subject )
+ *
+ * This implementation is slower than hungryDelimiterReplace but uses far less
+ * memory. The delimiters are literal strings, not regular expressions.
+ *
+ * @param string $flags Regular expression flags
+ */
+ # If the start delimiter ends with an initial substring of the end delimiter,
+ # e.g. in the case of C-style comments, the behaviour differs from the model
+ # regex. In this implementation, the end must share no characters with the
+ # start, so e.g. /*/ is not considered to be both the start and end of a
+ # comment. /*/xy/*/ is considered to be a single comment with contents /xy/.
+ static function delimiterReplaceCallback( $startDelim, $endDelim, $callback, $subject, $flags = '' ) {
+ $inputPos = 0;
+ $outputPos = 0;
+ $output = '';
+ $foundStart = false;
+ $encStart = preg_quote( $startDelim, '!' );
+ $encEnd = preg_quote( $endDelim, '!' );
+ $strcmp = strpos( $flags, 'i' ) === false ? 'strcmp' : 'strcasecmp';
+ $endLength = strlen( $endDelim );
+ $m = array();
+
+ while ( $inputPos < strlen( $subject ) &&
+ preg_match( "!($encStart)|($encEnd)!S$flags", $subject, $m, PREG_OFFSET_CAPTURE, $inputPos ) )
+ {
+ $tokenOffset = $m[0][1];
+ if ( $m[1][0] != '' ) {
+ if ( $foundStart &&
+ $strcmp( $endDelim, substr( $subject, $tokenOffset, $endLength ) ) == 0 )
+ {
+ # An end match is present at the same location
+ $tokenType = 'end';
+ $tokenLength = $endLength;
+ } else {
+ $tokenType = 'start';
+ $tokenLength = strlen( $m[0][0] );
+ }
+ } elseif ( $m[2][0] != '' ) {
+ $tokenType = 'end';
+ $tokenLength = strlen( $m[0][0] );
+ } else {
+ throw new MWException( 'Invalid delimiter given to ' . __METHOD__ );
+ }
+
+ if ( $tokenType == 'start' ) {
+ $inputPos = $tokenOffset + $tokenLength;
+ # Only move the start position if we haven't already found a start
+ # This means that START START END matches outer pair
+ if ( !$foundStart ) {
+ # Found start
+ # Write out the non-matching section
+ $output .= substr( $subject, $outputPos, $tokenOffset - $outputPos );
+ $outputPos = $tokenOffset;
+ $contentPos = $inputPos;
+ $foundStart = true;
+ }
+ } elseif ( $tokenType == 'end' ) {
+ if ( $foundStart ) {
+ # Found match
+ $output .= call_user_func( $callback, array(
+ substr( $subject, $outputPos, $tokenOffset + $tokenLength - $outputPos ),
+ substr( $subject, $contentPos, $tokenOffset - $contentPos )
+ ));
+ $foundStart = false;
+ } else {
+ # Non-matching end, write it out
+ $output .= substr( $subject, $inputPos, $tokenOffset + $tokenLength - $outputPos );
+ }
+ $inputPos = $outputPos = $tokenOffset + $tokenLength;
+ } else {
+ throw new MWException( 'Invalid delimiter given to ' . __METHOD__ );
+ }
+ }
+ if ( $outputPos < strlen( $subject ) ) {
+ $output .= substr( $subject, $outputPos );
+ }
+ return $output;
+ }
+
+ /*
+ * Perform an operation equivalent to
+ *
+ * preg_replace( "!$startDelim(.*)$endDelim!$flags", $replace, $subject )
+ *
+ * @param string $startDelim Start delimiter regular expression
+ * @param string $endDelim End delimiter regular expression
+ * @param string $replace Replacement string. May contain $1, which will be
+ * replaced by the text between the delimiters
+ * @param string $subject String to search
+ * @return string The string with the matches replaced
+ */
+ static function delimiterReplace( $startDelim, $endDelim, $replace, $subject, $flags = '' ) {
+ $replacer = new RegexlikeReplacer( $replace );
+ return self::delimiterReplaceCallback( $startDelim, $endDelim,
+ $replacer->cb(), $subject, $flags );
+ }
+
+ /**
+ * More or less "markup-safe" explode()
+ * Ignores any instances of the separator inside <...>
+ * @param string $separator
+ * @param string $text
+ * @return array
+ */
+ static function explodeMarkup( $separator, $text ) {
+ $placeholder = "\x00";
+
+ // Remove placeholder instances
+ $text = str_replace( $placeholder, '', $text );
+
+ // Replace instances of the separator inside HTML-like tags with the placeholder
+ $replacer = new DoubleReplacer( $separator, $placeholder );
+ $cleaned = StringUtils::delimiterReplaceCallback( '<', '>', $replacer->cb(), $text );
+
+ // Explode, then put the replaced separators back in
+ $items = explode( $separator, $cleaned );
+ foreach( $items as $i => $str ) {
+ $items[$i] = str_replace( $placeholder, $separator, $str );
+ }
+
+ return $items;
+ }
+
+ /**
+ * Escape a string to make it suitable for inclusion in a preg_replace()
+ * replacement parameter.
+ *
+ * @param string $string
+ * @return string
+ */
+ static function escapeRegexReplacement( $string ) {
+ $string = str_replace( '\\', '\\\\', $string );
+ $string = str_replace( '$', '\\$', $string );
+ return $string;
+ }
+}
+
+/**
+ * Base class for "replacers", objects used in preg_replace_callback() and
+ * StringUtils::delimiterReplaceCallback()
+ */
+class Replacer {
+ function cb() {
+ return array( &$this, 'replace' );
+ }
+}
+
+/**
+ * Class to replace regex matches with a string similar to that used in preg_replace()
+ */
+class RegexlikeReplacer extends Replacer {
+ var $r;
+ function __construct( $r ) {
+ $this->r = $r;
+ }
+
+ function replace( $matches ) {
+ $pairs = array();
+ foreach ( $matches as $i => $match ) {
+ $pairs["\$$i"] = $match;
+ }
+ return strtr( $this->r, $pairs );
+ }
+
+}
+
+/**
+ * Class to perform secondary replacement within each replacement string
+ */
+class DoubleReplacer extends Replacer {
+ function __construct( $from, $to, $index = 0 ) {
+ $this->from = $from;
+ $this->to = $to;
+ $this->index = $index;
+ }
+
+ function replace( $matches ) {
+ return str_replace( $this->from, $this->to, $matches[$this->index] );
+ }
+}
+
+/**
+ * Class to perform replacement based on a simple hashtable lookup
+ */
+class HashtableReplacer extends Replacer {
+ var $table, $index;
+
+ function __construct( $table, $index = 0 ) {
+ $this->table = $table;
+ $this->index = $index;
+ }
+
+ function replace( $matches ) {
+ return $this->table[$matches[$this->index]];
+ }
+}
+
+/**
+ * Replacement array for FSS with fallback to strtr()
+ * Supports lazy initialisation of FSS resource
+ */
+class ReplacementArray {
+ /*mostly private*/ var $data = false;
+ /*mostly private*/ var $fss = false;
+
+ /**
+ * Create an object with the specified replacement array
+ * The array should have the same form as the replacement array for strtr()
+ */
+ function __construct( $data = array() ) {
+ $this->data = $data;
+ }
+
+ function __sleep() {
+ return array( 'data' );
+ }
+
+ function __wakeup() {
+ $this->fss = false;
+ }
+
+ /**
+ * Set the whole replacement array at once
+ */
+ function setArray( $data ) {
+ $this->data = $data;
+ $this->fss = false;
+ }
+
+ function getArray() {
+ return $this->data;
+ }
+
+ /**
+ * Set an element of the replacement array
+ */
+ function setPair( $from, $to ) {
+ $this->data[$from] = $to;
+ $this->fss = false;
+ }
+
+ function mergeArray( $data ) {
+ $this->data = array_merge( $this->data, $data );
+ $this->fss = false;
+ }
+
+ function merge( $other ) {
+ $this->data = array_merge( $this->data, $other->data );
+ $this->fss = false;
+ }
+
+ function replace( $subject ) {
+ if ( function_exists( 'fss_prep_replace' ) ) {
+ wfProfileIn( __METHOD__.'-fss' );
+ if ( $this->fss === false ) {
+ $this->fss = fss_prep_replace( $this->data );
+ }
+ $result = fss_exec_replace( $this->fss, $subject );
+ wfProfileOut( __METHOD__.'-fss' );
+ } else {
+ wfProfileIn( __METHOD__.'-strtr' );
+ $result = strtr( $subject, $this->data );
+ wfProfileOut( __METHOD__.'-strtr' );
+ }
+ return $result;
+ }
+}
+
+?>
diff --git a/includes/StubObject.php b/includes/StubObject.php
new file mode 100644
index 000000000000..1501d9632091
--- /dev/null
+++ b/includes/StubObject.php
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * Class to implement stub globals, which are globals that delay loading the
+ * their associated module code by deferring initialisation until the first
+ * method call.
+ *
+ * Note on unstub loops:
+ *
+ * Unstub loops (infinite recursion) sometimes occur when a constructor calls
+ * another function, and the other function calls some method of the stub. The
+ * best way to avoid this is to make constructors as lightweight as possible,
+ * deferring any initialisation which depends on other modules. As a last
+ * resort, you can use StubObject::isRealObject() to break the loop, but as a
+ * general rule, the stub object mechanism should be transparent, and code
+ * which refers to it should be kept to a minimum.
+ */
+class StubObject {
+ var $mGlobal, $mClass, $mParams;
+ function __construct( $global = null, $class = null, $params = array() ) {
+ $this->mGlobal = $global;
+ $this->mClass = $class;
+ $this->mParams = $params;
+ }
+
+ static function isRealObject( $obj ) {
+ return is_object( $obj ) && !is_a( $obj, 'StubObject' );
+ }
+
+ function _call( $name, $args ) {
+ $this->_unstub( $name, 5 );
+ return call_user_func_array( array( $GLOBALS[$this->mGlobal], $name ), $args );
+ }
+
+ function _newObject() {
+ return wfCreateObject( $this->mClass, $this->mParams );
+ }
+
+ function __call( $name, $args ) {
+ return $this->_call( $name, $args );
+ }
+
+ /**
+ * This is public, for the convenience of external callers wishing to access
+ * properties, e.g. eval.php
+ */
+ function _unstub( $name = '_unstub', $level = 2 ) {
+ static $recursionLevel = 0;
+ if ( get_class( $GLOBALS[$this->mGlobal] ) != $this->mClass ) {
+ $fname = __METHOD__.'-'.$this->mGlobal;
+ wfProfileIn( $fname );
+ $caller = wfGetCaller( $level );
+ if ( ++$recursionLevel > 2 ) {
+ throw new MWException( "Unstub loop detected on call of \${$this->mGlobal}->$name from $caller\n" );
+ }
+ wfDebug( "Unstubbing \${$this->mGlobal} on call of \${$this->mGlobal}->$name from $caller\n" );
+ $GLOBALS[$this->mGlobal] = $this->_newObject();
+ --$recursionLevel;
+ wfProfileOut( $fname );
+ }
+ }
+}
+
+class StubContLang extends StubObject {
+ function __construct() {
+ parent::__construct( 'wgContLang' );
+ }
+
+ function __call( $name, $args ) {
+ return StubObject::_call( $name, $args );
+ }
+
+ function _newObject() {
+ global $wgContLanguageCode;
+ $obj = Language::factory( $wgContLanguageCode );
+ $obj->initEncoding();
+ $obj->initContLang();
+ return $obj;
+ }
+}
+class StubUserLang extends StubObject {
+ function __construct() {
+ parent::__construct( 'wgLang' );
+ }
+
+ function __call( $name, $args ) {
+ return $this->_call( $name, $args );
+ }
+
+ function _newObject() {
+ global $wgContLanguageCode, $wgRequest, $wgUser, $wgContLang;
+ $code = $wgRequest->getVal('uselang', $wgUser->getOption('language') );
+
+ // if variant is explicitely selected, use it instead the one from wgUser
+ // see bug #7605
+ if($wgContLang->hasVariants()){
+ $variant = $wgContLang->getPreferredVariant();
+ if($variant != $wgContLanguageCode)
+ $code = $variant;
+ }
+
+ # Validate $code
+ if( empty( $code ) || !preg_match( '/^[a-z]+(-[a-z]+)?$/', $code ) ) {
+ $code = $wgContLanguageCode;
+ }
+
+ if( $code == $wgContLanguageCode ) {
+ return $wgContLang;
+ } else {
+ $obj = Language::factory( $code );
+ return $obj;
+ }
+ }
+}
+class StubUser extends StubObject {
+ function __construct() {
+ parent::__construct( 'wgUser' );
+ }
+
+ function __call( $name, $args ) {
+ return $this->_call( $name, $args );
+ }
+
+ function _newObject() {
+ global $wgCommandLineMode;
+ if( $wgCommandLineMode ) {
+ $user = new User;
+ } else {
+ $user = User::newFromSession();
+ wfRunHooks('AutoAuthenticate',array(&$user));
+ }
+ return $user;
+ }
+}
+
+?>
diff --git a/includes/Title.php b/includes/Title.php
new file mode 100644
index 000000000000..56414c8a84b1
--- /dev/null
+++ b/includes/Title.php
@@ -0,0 +1,2505 @@
+<?php
+/**
+ * See title.txt
+ *
+ * @package MediaWiki
+ */
+
+/** */
+require_once( 'normal/UtfNormal.php' );
+
+define ( 'GAID_FOR_UPDATE', 1 );
+
+# Title::newFromTitle maintains a cache to avoid
+# expensive re-normalization of commonly used titles.
+# On a batch operation this can become a memory leak
+# if not bounded. After hitting this many titles,
+# reset the cache.
+define( 'MW_TITLECACHE_MAX', 1000 );
+
+/**
+ * Title class
+ * - Represents a title, which may contain an interwiki designation or namespace
+ * - Can fetch various kinds of data from the database, albeit inefficiently.
+ *
+ * @package MediaWiki
+ */
+class Title {
+ /**
+ * Static cache variables
+ */
+ static private $titleCache=array();
+ static private $interwikiCache=array();
+
+
+ /**
+ * All member variables should be considered private
+ * Please use the accessor functions
+ */
+
+ /**#@+
+ * @private
+ */
+
+ var $mTextform; # Text form (spaces not underscores) of the main part
+ var $mUrlform; # URL-encoded form of the main part
+ var $mDbkeyform; # Main part with underscores
+ var $mNamespace; # Namespace index, i.e. one of the NS_xxxx constants
+ var $mInterwiki; # Interwiki prefix (or null string)
+ var $mFragment; # Title fragment (i.e. the bit after the #)
+ var $mArticleID; # Article ID, fetched from the link cache on demand
+ var $mLatestID; # ID of most recent revision
+ var $mRestrictions; # Array of groups allowed to edit this article
+ # Only null or "sysop" are supported
+ var $mRestrictionsLoaded; # Boolean for initialisation on demand
+ var $mPrefixedText; # Text form including namespace/interwiki, initialised on demand
+ var $mDefaultNamespace; # Namespace index when there is no namespace
+ # Zero except in {{transclusion}} tags
+ var $mWatched; # Is $wgUser watching this page? NULL if unfilled, accessed through userIsWatching()
+ /**#@-*/
+
+
+ /**
+ * Constructor
+ * @private
+ */
+ /* private */ function Title() {
+ $this->mInterwiki = $this->mUrlform =
+ $this->mTextform = $this->mDbkeyform = '';
+ $this->mArticleID = -1;
+ $this->mNamespace = NS_MAIN;
+ $this->mRestrictionsLoaded = false;
+ $this->mRestrictions = array();
+ # Dont change the following, NS_MAIN is hardcoded in several place
+ # See bug #696
+ $this->mDefaultNamespace = NS_MAIN;
+ $this->mWatched = NULL;
+ $this->mLatestID = false;
+ }
+
+ /**
+ * Create a new Title from a prefixed DB key
+ * @param string $key The database key, which has underscores
+ * instead of spaces, possibly including namespace and
+ * interwiki prefixes
+ * @return Title the new object, or NULL on an error
+ * @static
+ * @access public
+ */
+ /* static */ function newFromDBkey( $key ) {
+ $t = new Title();
+ $t->mDbkeyform = $key;
+ if( $t->secureAndSplit() )
+ return $t;
+ else
+ return NULL;
+ }
+
+ /**
+ * Create a new Title from text, such as what one would
+ * find in a link. Decodes any HTML entities in the text.
+ *
+ * @param string $text the link text; spaces, prefixes,
+ * and an initial ':' indicating the main namespace
+ * are accepted
+ * @param int $defaultNamespace the namespace to use if
+ * none is specified by a prefix
+ * @return Title the new object, or NULL on an error
+ * @static
+ * @access public
+ */
+ public static function newFromText( $text, $defaultNamespace = NS_MAIN ) {
+ if( is_object( $text ) ) {
+ throw new MWException( 'Title::newFromText given an object' );
+ }
+
+ /**
+ * Wiki pages often contain multiple links to the same page.
+ * Title normalization and parsing can become expensive on
+ * pages with many links, so we can save a little time by
+ * caching them.
+ *
+ * In theory these are value objects and won't get changed...
+ */
+ if( $defaultNamespace == NS_MAIN && isset( Title::$titleCache[$text] ) ) {
+ return Title::$titleCache[$text];
+ }
+
+ /**
+ * Convert things like &eacute; &#257; or &#x3017; into real text...
+ */
+ $filteredText = Sanitizer::decodeCharReferences( $text );
+
+ $t = new Title();
+ $t->mDbkeyform = str_replace( ' ', '_', $filteredText );
+ $t->mDefaultNamespace = $defaultNamespace;
+
+ static $cachedcount = 0 ;
+ if( $t->secureAndSplit() ) {
+ if( $defaultNamespace == NS_MAIN ) {
+ if( $cachedcount >= MW_TITLECACHE_MAX ) {
+ # Avoid memory leaks on mass operations...
+ Title::$titleCache = array();
+ $cachedcount=0;
+ }
+ $cachedcount++;
+ Title::$titleCache[$text] =& $t;
+ }
+ return $t;
+ } else {
+ $ret = NULL;
+ return $ret;
+ }
+ }
+
+ /**
+ * Create a new Title from URL-encoded text. Ensures that
+ * the given title's length does not exceed the maximum.
+ * @param string $url the title, as might be taken from a URL
+ * @return Title the new object, or NULL on an error
+ * @static
+ * @access public
+ */
+ public static function newFromURL( $url ) {
+ global $wgLegalTitleChars;
+ $t = new Title();
+
+ # For compatibility with old buggy URLs. "+" is usually not valid in titles,
+ # but some URLs used it as a space replacement and they still come
+ # from some external search tools.
+ if ( strpos( $wgLegalTitleChars, '+' ) === false ) {
+ $url = str_replace( '+', ' ', $url );
+ }
+
+ $t->mDbkeyform = str_replace( ' ', '_', $url );
+ if( $t->secureAndSplit() ) {
+ return $t;
+ } else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Create a new Title from an article ID
+ *
+ * @todo This is inefficiently implemented, the page row is requested
+ * but not used for anything else
+ *
+ * @param int $id the page_id corresponding to the Title to create
+ * @return Title the new object, or NULL on an error
+ * @access public
+ * @static
+ */
+ public static function newFromID( $id ) {
+ $fname = 'Title::newFromID';
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow( 'page', array( 'page_namespace', 'page_title' ),
+ array( 'page_id' => $id ), $fname );
+ if ( $row !== false ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ } else {
+ $title = NULL;
+ }
+ return $title;
+ }
+
+ /**
+ * Make an array of titles from an array of IDs
+ */
+ function newFromIDs( $ids ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'page', array( 'page_namespace', 'page_title' ),
+ 'page_id IN (' . $dbr->makeList( $ids ) . ')', __METHOD__ );
+
+ $titles = array();
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $titles[] = Title::makeTitle( $row->page_namespace, $row->page_title );
+ }
+ return $titles;
+ }
+
+ /**
+ * Create a new Title from a namespace index and a DB key.
+ * It's assumed that $ns and $title are *valid*, for instance when
+ * they came directly from the database or a special page name.
+ * For convenience, spaces are converted to underscores so that
+ * eg user_text fields can be used directly.
+ *
+ * @param int $ns the namespace of the article
+ * @param string $title the unprefixed database key form
+ * @return Title the new object
+ * @static
+ * @access public
+ */
+ public static function &makeTitle( $ns, $title ) {
+ $t = new Title();
+ $t->mInterwiki = '';
+ $t->mFragment = '';
+ $t->mNamespace = intval( $ns );
+ $t->mDbkeyform = str_replace( ' ', '_', $title );
+ $t->mArticleID = ( $ns >= 0 ) ? -1 : 0;
+ $t->mUrlform = wfUrlencode( $t->mDbkeyform );
+ $t->mTextform = str_replace( '_', ' ', $title );
+ return $t;
+ }
+
+ /**
+ * Create a new Title from a namespace index and a DB key.
+ * The parameters will be checked for validity, which is a bit slower
+ * than makeTitle() but safer for user-provided data.
+ *
+ * @param int $ns the namespace of the article
+ * @param string $title the database key form
+ * @return Title the new object, or NULL on an error
+ * @static
+ * @access public
+ */
+ public static function makeTitleSafe( $ns, $title ) {
+ $t = new Title();
+ $t->mDbkeyform = Title::makeName( $ns, $title );
+ if( $t->secureAndSplit() ) {
+ return $t;
+ } else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Create a new Title for the Main Page
+ *
+ * @static
+ * @return Title the new object
+ * @access public
+ */
+ public static function newMainPage() {
+ return Title::newFromText( wfMsgForContent( 'mainpage' ) );
+ }
+
+ /**
+ * Create a new Title for a redirect
+ * @param string $text the redirect title text
+ * @return Title the new object, or NULL if the text is not a
+ * valid redirect
+ * @static
+ * @access public
+ */
+ public static function newFromRedirect( $text ) {
+ $mwRedir = MagicWord::get( 'redirect' );
+ $rt = NULL;
+ if ( $mwRedir->matchStart( $text ) ) {
+ $m = array();
+ if ( preg_match( '/\[{2}(.*?)(?:\||\]{2})/', $text, $m ) ) {
+ # categories are escaped using : for example one can enter:
+ # #REDIRECT [[:Category:Music]]. Need to remove it.
+ if ( substr($m[1],0,1) == ':') {
+ # We don't want to keep the ':'
+ $m[1] = substr( $m[1], 1 );
+ }
+
+ $rt = Title::newFromText( $m[1] );
+ # Disallow redirects to Special:Userlogout
+ if ( !is_null($rt) && $rt->isSpecial( 'Userlogout' ) ) {
+ $rt = NULL;
+ }
+ }
+ }
+ return $rt;
+ }
+
+#----------------------------------------------------------------------------
+# Static functions
+#----------------------------------------------------------------------------
+
+ /**
+ * Get the prefixed DB key associated with an ID
+ * @param int $id the page_id of the article
+ * @return Title an object representing the article, or NULL
+ * if no such article was found
+ * @static
+ * @access public
+ */
+ function nameOf( $id ) {
+ $fname = 'Title::nameOf';
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $s = $dbr->selectRow( 'page', array( 'page_namespace','page_title' ), array( 'page_id' => $id ), $fname );
+ if ( $s === false ) { return NULL; }
+
+ $n = Title::makeName( $s->page_namespace, $s->page_title );
+ return $n;
+ }
+
+ /**
+ * Get a regex character class describing the legal characters in a link
+ * @return string the list of characters, not delimited
+ * @static
+ * @access public
+ */
+ public static function legalChars() {
+ global $wgLegalTitleChars;
+ return $wgLegalTitleChars;
+ }
+
+ /**
+ * Get a string representation of a title suitable for
+ * including in a search index
+ *
+ * @param int $ns a namespace index
+ * @param string $title text-form main part
+ * @return string a stripped-down title string ready for the
+ * search index
+ */
+ /* static */ function indexTitle( $ns, $title ) {
+ global $wgContLang;
+
+ $lc = SearchEngine::legalSearchChars() . '&#;';
+ $t = $wgContLang->stripForSearch( $title );
+ $t = preg_replace( "/[^{$lc}]+/", ' ', $t );
+ $t = $wgContLang->lc( $t );
+
+ # Handle 's, s'
+ $t = preg_replace( "/([{$lc}]+)'s( |$)/", "\\1 \\1's ", $t );
+ $t = preg_replace( "/([{$lc}]+)s'( |$)/", "\\1s ", $t );
+
+ $t = preg_replace( "/\\s+/", ' ', $t );
+
+ if ( $ns == NS_IMAGE ) {
+ $t = preg_replace( "/ (png|gif|jpg|jpeg|ogg)$/", "", $t );
+ }
+ return trim( $t );
+ }
+
+ /*
+ * Make a prefixed DB key from a DB key and a namespace index
+ * @param int $ns numerical representation of the namespace
+ * @param string $title the DB key form the title
+ * @return string the prefixed form of the title
+ */
+ public static function makeName( $ns, $title ) {
+ global $wgContLang;
+
+ $n = $wgContLang->getNsText( $ns );
+ return $n == '' ? $title : "$n:$title";
+ }
+
+ /**
+ * Returns the URL associated with an interwiki prefix
+ * @param string $key the interwiki prefix (e.g. "MeatBall")
+ * @return the associated URL, containing "$1", which should be
+ * replaced by an article title
+ * @static (arguably)
+ * @access public
+ */
+ function getInterwikiLink( $key ) {
+ global $wgMemc, $wgInterwikiExpiry;
+ global $wgInterwikiCache, $wgContLang;
+ $fname = 'Title::getInterwikiLink';
+
+ $key = $wgContLang->lc( $key );
+
+ $k = wfMemcKey( 'interwiki', $key );
+ if( array_key_exists( $k, Title::$interwikiCache ) ) {
+ return Title::$interwikiCache[$k]->iw_url;
+ }
+
+ if ($wgInterwikiCache) {
+ return Title::getInterwikiCached( $key );
+ }
+
+ $s = $wgMemc->get( $k );
+ # Ignore old keys with no iw_local
+ if( $s && isset( $s->iw_local ) && isset($s->iw_trans)) {
+ Title::$interwikiCache[$k] = $s;
+ return $s->iw_url;
+ }
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'interwiki',
+ array( 'iw_url', 'iw_local', 'iw_trans' ),
+ array( 'iw_prefix' => $key ), $fname );
+ if( !$res ) {
+ return '';
+ }
+
+ $s = $dbr->fetchObject( $res );
+ if( !$s ) {
+ # Cache non-existence: create a blank object and save it to memcached
+ $s = (object)false;
+ $s->iw_url = '';
+ $s->iw_local = 0;
+ $s->iw_trans = 0;
+ }
+ $wgMemc->set( $k, $s, $wgInterwikiExpiry );
+ Title::$interwikiCache[$k] = $s;
+
+ return $s->iw_url;
+ }
+
+ /**
+ * Fetch interwiki prefix data from local cache in constant database
+ *
+ * More logic is explained in DefaultSettings
+ *
+ * @return string URL of interwiki site
+ * @access public
+ */
+ function getInterwikiCached( $key ) {
+ global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
+ static $db, $site;
+
+ if (!$db)
+ $db=dba_open($wgInterwikiCache,'r','cdb');
+ /* Resolve site name */
+ if ($wgInterwikiScopes>=3 and !$site) {
+ $site = dba_fetch('__sites:' . wfWikiID(), $db);
+ if ($site=="")
+ $site = $wgInterwikiFallbackSite;
+ }
+ $value = dba_fetch( wfMemcKey( $key ), $db);
+ if ($value=='' and $wgInterwikiScopes>=3) {
+ /* try site-level */
+ $value = dba_fetch("_{$site}:{$key}", $db);
+ }
+ if ($value=='' and $wgInterwikiScopes>=2) {
+ /* try globals */
+ $value = dba_fetch("__global:{$key}", $db);
+ }
+ if ($value=='undef')
+ $value='';
+ $s = (object)false;
+ $s->iw_url = '';
+ $s->iw_local = 0;
+ $s->iw_trans = 0;
+ if ($value!='') {
+ list($local,$url)=explode(' ',$value,2);
+ $s->iw_url=$url;
+ $s->iw_local=(int)$local;
+ }
+ Title::$interwikiCache[wfMemcKey( 'interwiki', $key )] = $s;
+ return $s->iw_url;
+ }
+ /**
+ * Determine whether the object refers to a page within
+ * this project.
+ *
+ * @return bool TRUE if this is an in-project interwiki link
+ * or a wikilink, FALSE otherwise
+ * @access public
+ */
+ function isLocal() {
+ if ( $this->mInterwiki != '' ) {
+ # Make sure key is loaded into cache
+ $this->getInterwikiLink( $this->mInterwiki );
+ $k = wfMemcKey( 'interwiki', $this->mInterwiki );
+ return (bool)(Title::$interwikiCache[$k]->iw_local);
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Determine whether the object refers to a page within
+ * this project and is transcludable.
+ *
+ * @return bool TRUE if this is transcludable
+ * @access public
+ */
+ function isTrans() {
+ if ($this->mInterwiki == '')
+ return false;
+ # Make sure key is loaded into cache
+ $this->getInterwikiLink( $this->mInterwiki );
+ $k = wfMemcKey( 'interwiki', $this->mInterwiki );
+ return (bool)(Title::$interwikiCache[$k]->iw_trans);
+ }
+
+ /**
+ * Update the page_touched field for an array of title objects
+ * @todo Inefficient unless the IDs are already loaded into the
+ * link cache
+ * @param array $titles an array of Title objects to be touched
+ * @param string $timestamp the timestamp to use instead of the
+ * default current time
+ * @static
+ * @access public
+ */
+ function touchArray( $titles, $timestamp = '' ) {
+
+ if ( count( $titles ) == 0 ) {
+ return;
+ }
+ $dbw =& wfGetDB( DB_MASTER );
+ if ( $timestamp == '' ) {
+ $timestamp = $dbw->timestamp();
+ }
+ /*
+ $page = $dbw->tableName( 'page' );
+ $sql = "UPDATE $page SET page_touched='{$timestamp}' WHERE page_id IN (";
+ $first = true;
+
+ foreach ( $titles as $title ) {
+ if ( $wgUseFileCache ) {
+ $cm = new HTMLFileCache($title);
+ @unlink($cm->fileCacheName());
+ }
+
+ if ( ! $first ) {
+ $sql .= ',';
+ }
+ $first = false;
+ $sql .= $title->getArticleID();
+ }
+ $sql .= ')';
+ if ( ! $first ) {
+ $dbw->query( $sql, 'Title::touchArray' );
+ }
+ */
+ // hack hack hack -- brion 2005-07-11. this was unfriendly to db.
+ // do them in small chunks:
+ $fname = 'Title::touchArray';
+ foreach( $titles as $title ) {
+ $dbw->update( 'page',
+ array( 'page_touched' => $timestamp ),
+ array(
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDBkey() ),
+ $fname );
+ }
+ }
+
+ /**
+ * Escape a text fragment, say from a link, for a URL
+ */
+ static function escapeFragmentForURL( $fragment ) {
+ $fragment = str_replace( ' ', '_', $fragment );
+ $fragment = urlencode( Sanitizer::decodeCharReferences( $fragment ) );
+ $replaceArray = array(
+ '%3A' => ':',
+ '%' => '.'
+ );
+ return strtr( $fragment, $replaceArray );
+ }
+
+#----------------------------------------------------------------------------
+# Other stuff
+#----------------------------------------------------------------------------
+
+ /** Simple accessors */
+ /**
+ * Get the text form (spaces not underscores) of the main part
+ * @return string
+ * @access public
+ */
+ function getText() { return $this->mTextform; }
+ /**
+ * Get the URL-encoded form of the main part
+ * @return string
+ * @access public
+ */
+ function getPartialURL() { return $this->mUrlform; }
+ /**
+ * Get the main part with underscores
+ * @return string
+ * @access public
+ */
+ function getDBkey() { return $this->mDbkeyform; }
+ /**
+ * Get the namespace index, i.e. one of the NS_xxxx constants
+ * @return int
+ * @access public
+ */
+ function getNamespace() { return $this->mNamespace; }
+ /**
+ * Get the namespace text
+ * @return string
+ * @access public
+ */
+ function getNsText() {
+ global $wgContLang, $wgCanonicalNamespaceNames;
+
+ if ( '' != $this->mInterwiki ) {
+ // This probably shouldn't even happen. ohh man, oh yuck.
+ // But for interwiki transclusion it sometimes does.
+ // Shit. Shit shit shit.
+ //
+ // Use the canonical namespaces if possible to try to
+ // resolve a foreign namespace.
+ if( isset( $wgCanonicalNamespaceNames[$this->mNamespace] ) ) {
+ return $wgCanonicalNamespaceNames[$this->mNamespace];
+ }
+ }
+ return $wgContLang->getNsText( $this->mNamespace );
+ }
+ /**
+ * Get the namespace text of the subject (rather than talk) page
+ * @return string
+ * @access public
+ */
+ function getSubjectNsText() {
+ global $wgContLang;
+ return $wgContLang->getNsText( Namespace::getSubject( $this->mNamespace ) );
+ }
+
+ /**
+ * Get the namespace text of the talk page
+ * @return string
+ */
+ function getTalkNsText() {
+ global $wgContLang;
+ return( $wgContLang->getNsText( Namespace::getTalk( $this->mNamespace ) ) );
+ }
+
+ /**
+ * Could this title have a corresponding talk page?
+ * @return bool
+ */
+ function canTalk() {
+ return( Namespace::canTalk( $this->mNamespace ) );
+ }
+
+ /**
+ * Get the interwiki prefix (or null string)
+ * @return string
+ * @access public
+ */
+ function getInterwiki() { return $this->mInterwiki; }
+ /**
+ * Get the Title fragment (i.e. the bit after the #) in text form
+ * @return string
+ * @access public
+ */
+ function getFragment() { return $this->mFragment; }
+ /**
+ * Get the fragment in URL form, including the "#" character if there is one
+ *
+ * @return string
+ * @access public
+ */
+ function getFragmentForURL() {
+ if ( $this->mFragment == '' ) {
+ return '';
+ } else {
+ return '#' . Title::escapeFragmentForURL( $this->mFragment );
+ }
+ }
+ /**
+ * Get the default namespace index, for when there is no namespace
+ * @return int
+ * @access public
+ */
+ function getDefaultNamespace() { return $this->mDefaultNamespace; }
+
+ /**
+ * Get title for search index
+ * @return string a stripped-down title string ready for the
+ * search index
+ */
+ function getIndexTitle() {
+ return Title::indexTitle( $this->mNamespace, $this->mTextform );
+ }
+
+ /**
+ * Get the prefixed database key form
+ * @return string the prefixed title, with underscores and
+ * any interwiki and namespace prefixes
+ * @access public
+ */
+ function getPrefixedDBkey() {
+ $s = $this->prefix( $this->mDbkeyform );
+ $s = str_replace( ' ', '_', $s );
+ return $s;
+ }
+
+ /**
+ * Get the prefixed title with spaces.
+ * This is the form usually used for display
+ * @return string the prefixed title, with spaces
+ * @access public
+ */
+ function getPrefixedText() {
+ if ( empty( $this->mPrefixedText ) ) { // FIXME: bad usage of empty() ?
+ $s = $this->prefix( $this->mTextform );
+ $s = str_replace( '_', ' ', $s );
+ $this->mPrefixedText = $s;
+ }
+ return $this->mPrefixedText;
+ }
+
+ /**
+ * Get the prefixed title with spaces, plus any fragment
+ * (part beginning with '#')
+ * @return string the prefixed title, with spaces and
+ * the fragment, including '#'
+ * @access public
+ */
+ function getFullText() {
+ $text = $this->getPrefixedText();
+ if( '' != $this->mFragment ) {
+ $text .= '#' . $this->mFragment;
+ }
+ return $text;
+ }
+
+ /**
+ * Get the base name, i.e. the leftmost parts before the /
+ * @return string Base name
+ */
+ function getBaseText() {
+ global $wgNamespacesWithSubpages;
+ if( isset( $wgNamespacesWithSubpages[ $this->mNamespace ] ) && $wgNamespacesWithSubpages[ $this->mNamespace ] ) {
+ $parts = explode( '/', $this->getText() );
+ # Don't discard the real title if there's no subpage involved
+ if( count( $parts ) > 1 )
+ unset( $parts[ count( $parts ) - 1 ] );
+ return implode( '/', $parts );
+ } else {
+ return $this->getText();
+ }
+ }
+
+ /**
+ * Get the lowest-level subpage name, i.e. the rightmost part after /
+ * @return string Subpage name
+ */
+ function getSubpageText() {
+ global $wgNamespacesWithSubpages;
+ if( isset( $wgNamespacesWithSubpages[ $this->mNamespace ] ) && $wgNamespacesWithSubpages[ $this->mNamespace ] ) {
+ $parts = explode( '/', $this->mTextform );
+ return( $parts[ count( $parts ) - 1 ] );
+ } else {
+ return( $this->mTextform );
+ }
+ }
+
+ /**
+ * Get a URL-encoded form of the subpage text
+ * @return string URL-encoded subpage name
+ */
+ function getSubpageUrlForm() {
+ $text = $this->getSubpageText();
+ $text = wfUrlencode( str_replace( ' ', '_', $text ) );
+ $text = str_replace( '%28', '(', str_replace( '%29', ')', $text ) ); # Clean up the URL; per below, this might not be safe
+ return( $text );
+ }
+
+ /**
+ * Get a URL-encoded title (not an actual URL) including interwiki
+ * @return string the URL-encoded form
+ * @access public
+ */
+ function getPrefixedURL() {
+ $s = $this->prefix( $this->mDbkeyform );
+ $s = str_replace( ' ', '_', $s );
+
+ $s = wfUrlencode ( $s ) ;
+
+ # Cleaning up URL to make it look nice -- is this safe?
+ $s = str_replace( '%28', '(', $s );
+ $s = str_replace( '%29', ')', $s );
+
+ return $s;
+ }
+
+ /**
+ * Get a real URL referring to this title, with interwiki link and
+ * fragment
+ *
+ * @param string $query an optional query string, not used
+ * for interwiki links
+ * @param string $variant language variant of url (for sr, zh..)
+ * @return string the URL
+ * @access public
+ */
+ function getFullURL( $query = '', $variant = false ) {
+ global $wgContLang, $wgServer, $wgRequest;
+
+ if ( '' == $this->mInterwiki ) {
+ $url = $this->getLocalUrl( $query, $variant );
+
+ // Ugly quick hack to avoid duplicate prefixes (bug 4571 etc)
+ // Correct fix would be to move the prepending elsewhere.
+ if ($wgRequest->getVal('action') != 'render') {
+ $url = $wgServer . $url;
+ }
+ } else {
+ $baseUrl = $this->getInterwikiLink( $this->mInterwiki );
+
+ $namespace = wfUrlencode( $this->getNsText() );
+ if ( '' != $namespace ) {
+ # Can this actually happen? Interwikis shouldn't be parsed.
+ # Yes! It can in interwiki transclusion. But... it probably shouldn't.
+ $namespace .= ':';
+ }
+ $url = str_replace( '$1', $namespace . $this->mUrlform, $baseUrl );
+ if( $query != '' ) {
+ if( false === strpos( $url, '?' ) ) {
+ $url .= '?';
+ } else {
+ $url .= '&';
+ }
+ $url .= $query;
+ }
+ }
+
+ # Finally, add the fragment.
+ $url .= $this->getFragmentForURL();
+
+ wfRunHooks( 'GetFullURL', array( &$this, &$url, $query ) );
+ return $url;
+ }
+
+ /**
+ * Get a URL with no fragment or server name. If this page is generated
+ * with action=render, $wgServer is prepended.
+ * @param string $query an optional query string; if not specified,
+ * $wgArticlePath will be used.
+ * @param string $variant language variant of url (for sr, zh..)
+ * @return string the URL
+ * @access public
+ */
+ function getLocalURL( $query = '', $variant = false ) {
+ global $wgArticlePath, $wgScript, $wgServer, $wgRequest;
+ global $wgVariantArticlePath, $wgContLang, $wgUser;
+
+ // internal links should point to same variant as current page (only anonymous users)
+ if($variant == false && $wgContLang->hasVariants() && !$wgUser->isLoggedIn()){
+ $pref = $wgContLang->getPreferredVariant(false);
+ if($pref != $wgContLang->getCode())
+ $variant = $pref;
+ }
+
+ if ( $this->isExternal() ) {
+ $url = $this->getFullURL();
+ if ( $query ) {
+ // This is currently only used for edit section links in the
+ // context of interwiki transclusion. In theory we should
+ // append the query to the end of any existing query string,
+ // but interwiki transclusion is already broken in that case.
+ $url .= "?$query";
+ }
+ } else {
+ $dbkey = wfUrlencode( $this->getPrefixedDBkey() );
+ if ( $query == '' ) {
+ if($variant!=false && $wgContLang->hasVariants()){
+ if($wgVariantArticlePath==false)
+ $variantArticlePath = "$wgScript?title=$1&variant=$2"; // default
+ else
+ $variantArticlePath = $wgVariantArticlePath;
+
+ $url = str_replace( '$2', urlencode( $variant ), $variantArticlePath );
+ $url = str_replace( '$1', $dbkey, $url );
+
+ }
+ else
+ $url = str_replace( '$1', $dbkey, $wgArticlePath );
+ } else {
+ global $wgActionPaths;
+ $url = false;
+ $matches = array();
+ if( !empty( $wgActionPaths ) &&
+ preg_match( '/^(.*&|)action=([^&]*)(&(.*)|)$/', $query, $matches ) )
+ {
+ $action = urldecode( $matches[2] );
+ if( isset( $wgActionPaths[$action] ) ) {
+ $query = $matches[1];
+ if( isset( $matches[4] ) ) $query .= $matches[4];
+ $url = str_replace( '$1', $dbkey, $wgActionPaths[$action] );
+ if( $query != '' ) $url .= '?' . $query;
+ }
+ }
+ if ( $url === false ) {
+ if ( $query == '-' ) {
+ $query = '';
+ }
+ $url = "{$wgScript}?title={$dbkey}&{$query}";
+ }
+ }
+
+ // FIXME: this causes breakage in various places when we
+ // actually expected a local URL and end up with dupe prefixes.
+ if ($wgRequest->getVal('action') == 'render') {
+ $url = $wgServer . $url;
+ }
+ }
+ wfRunHooks( 'GetLocalURL', array( &$this, &$url, $query ) );
+ return $url;
+ }
+
+ /**
+ * Get an HTML-escaped version of the URL form, suitable for
+ * using in a link, without a server name or fragment
+ * @param string $query an optional query string
+ * @return string the URL
+ * @access public
+ */
+ function escapeLocalURL( $query = '' ) {
+ return htmlspecialchars( $this->getLocalURL( $query ) );
+ }
+
+ /**
+ * Get an HTML-escaped version of the URL form, suitable for
+ * using in a link, including the server name and fragment
+ *
+ * @return string the URL
+ * @param string $query an optional query string
+ * @access public
+ */
+ function escapeFullURL( $query = '' ) {
+ return htmlspecialchars( $this->getFullURL( $query ) );
+ }
+
+ /**
+ * Get the URL form for an internal link.
+ * - Used in various Squid-related code, in case we have a different
+ * internal hostname for the server from the exposed one.
+ *
+ * @param string $query an optional query string
+ * @param string $variant language variant of url (for sr, zh..)
+ * @return string the URL
+ * @access public
+ */
+ function getInternalURL( $query = '', $variant = false ) {
+ global $wgInternalServer;
+ $url = $wgInternalServer . $this->getLocalURL( $query, $variant );
+ wfRunHooks( 'GetInternalURL', array( &$this, &$url, $query ) );
+ return $url;
+ }
+
+ /**
+ * Get the edit URL for this Title
+ * @return string the URL, or a null string if this is an
+ * interwiki link
+ * @access public
+ */
+ function getEditURL() {
+ if ( '' != $this->mInterwiki ) { return ''; }
+ $s = $this->getLocalURL( 'action=edit' );
+
+ return $s;
+ }
+
+ /**
+ * Get the HTML-escaped displayable text form.
+ * Used for the title field in <a> tags.
+ * @return string the text, including any prefixes
+ * @access public
+ */
+ function getEscapedText() {
+ return htmlspecialchars( $this->getPrefixedText() );
+ }
+
+ /**
+ * Is this Title interwiki?
+ * @return boolean
+ * @access public
+ */
+ function isExternal() { return ( '' != $this->mInterwiki ); }
+
+ /**
+ * Is this page "semi-protected" - the *only* protection is autoconfirm?
+ *
+ * @param string Action to check (default: edit)
+ * @return bool
+ */
+ function isSemiProtected( $action = 'edit' ) {
+ if( $this->exists() ) {
+ $restrictions = $this->getRestrictions( $action );
+ if( count( $restrictions ) > 0 ) {
+ foreach( $restrictions as $restriction ) {
+ if( strtolower( $restriction ) != 'autoconfirmed' )
+ return false;
+ }
+ } else {
+ # Not protected
+ return false;
+ }
+ return true;
+ } else {
+ # If it doesn't exist, it can't be protected
+ return false;
+ }
+ }
+
+ /**
+ * Does the title correspond to a protected article?
+ * @param string $what the action the page is protected from,
+ * by default checks move and edit
+ * @return boolean
+ * @access public
+ */
+ function isProtected( $action = '' ) {
+ global $wgRestrictionLevels;
+ if ( NS_SPECIAL == $this->mNamespace ) { return true; }
+
+ if( $action == 'edit' || $action == '' ) {
+ $r = $this->getRestrictions( 'edit' );
+ foreach( $wgRestrictionLevels as $level ) {
+ if( in_array( $level, $r ) && $level != '' ) {
+ return( true );
+ }
+ }
+ }
+
+ if( $action == 'move' || $action == '' ) {
+ $r = $this->getRestrictions( 'move' );
+ foreach( $wgRestrictionLevels as $level ) {
+ if( in_array( $level, $r ) && $level != '' ) {
+ return( true );
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Is $wgUser is watching this page?
+ * @return boolean
+ * @access public
+ */
+ function userIsWatching() {
+ global $wgUser;
+
+ if ( is_null( $this->mWatched ) ) {
+ if ( NS_SPECIAL == $this->mNamespace || !$wgUser->isLoggedIn()) {
+ $this->mWatched = false;
+ } else {
+ $this->mWatched = $wgUser->isWatched( $this );
+ }
+ }
+ return $this->mWatched;
+ }
+
+ /**
+ * Can $wgUser perform $action this page?
+ * @param string $action action that permission needs to be checked for
+ * @return boolean
+ * @private
+ */
+ function userCan($action) {
+ $fname = 'Title::userCan';
+ wfProfileIn( $fname );
+
+ global $wgUser;
+
+ $result = null;
+ wfRunHooks( 'userCan', array( &$this, &$wgUser, $action, &$result ) );
+ if ( $result !== null ) {
+ wfProfileOut( $fname );
+ return $result;
+ }
+
+ if( NS_SPECIAL == $this->mNamespace ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ // XXX: This is the code that prevents unprotecting a page in NS_MEDIAWIKI
+ // from taking effect -ævar
+ if( NS_MEDIAWIKI == $this->mNamespace &&
+ !$wgUser->isAllowed('editinterface') ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ if( $this->mDbkeyform == '_' ) {
+ # FIXME: Is this necessary? Shouldn't be allowed anyway...
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ # protect css/js subpages of user pages
+ # XXX: this might be better using restrictions
+ # XXX: Find a way to work around the php bug that prevents using $this->userCanEditCssJsSubpage() from working
+ if( $this->isCssJsSubpage()
+ && !$wgUser->isAllowed('editinterface')
+ && !preg_match('/^'.preg_quote($wgUser->getName(), '/').'\//', $this->mTextform) ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ foreach( $this->getRestrictions($action) as $right ) {
+ // Backwards compatibility, rewrite sysop -> protect
+ if ( $right == 'sysop' ) {
+ $right = 'protect';
+ }
+ if( '' != $right && !$wgUser->isAllowed( $right ) ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ }
+
+ if( $action == 'move' &&
+ !( $this->isMovable() && $wgUser->isAllowed( 'move' ) ) ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ if( $action == 'create' ) {
+ if( ( $this->isTalkPage() && !$wgUser->isAllowed( 'createtalk' ) ) ||
+ ( !$this->isTalkPage() && !$wgUser->isAllowed( 'createpage' ) ) ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+ }
+
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ /**
+ * Can $wgUser edit this page?
+ * @return boolean
+ * @access public
+ */
+ function userCanEdit() {
+ return $this->userCan('edit');
+ }
+
+ /**
+ * Can $wgUser create this page?
+ * @return boolean
+ * @access public
+ */
+ function userCanCreate() {
+ return $this->userCan('create');
+ }
+
+ /**
+ * Can $wgUser move this page?
+ * @return boolean
+ * @access public
+ */
+ function userCanMove() {
+ return $this->userCan('move');
+ }
+
+ /**
+ * Would anybody with sufficient privileges be able to move this page?
+ * Some pages just aren't movable.
+ *
+ * @return boolean
+ * @access public
+ */
+ function isMovable() {
+ return Namespace::isMovable( $this->getNamespace() )
+ && $this->getInterwiki() == '';
+ }
+
+ /**
+ * Can $wgUser read this page?
+ * @return boolean
+ * @access public
+ */
+ function userCanRead() {
+ global $wgUser;
+
+ $result = null;
+ wfRunHooks( 'userCan', array( &$this, &$wgUser, 'read', &$result ) );
+ if ( $result !== null ) {
+ return $result;
+ }
+
+ if( $wgUser->isAllowed('read') ) {
+ return true;
+ } else {
+ global $wgWhitelistRead;
+
+ /**
+ * Always grant access to the login page.
+ * Even anons need to be able to log in.
+ */
+ if( $this->isSpecial( 'Userlogin' ) || $this->isSpecial( 'Resetpass' ) ) {
+ return true;
+ }
+
+ /** some pages are explicitly allowed */
+ $name = $this->getPrefixedText();
+ if( $wgWhitelistRead && in_array( $name, $wgWhitelistRead ) ) {
+ return true;
+ }
+
+ # Compatibility with old settings
+ if( $wgWhitelistRead && $this->getNamespace() == NS_MAIN ) {
+ if( in_array( ':' . $name, $wgWhitelistRead ) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is this a talk page of some sort?
+ * @return bool
+ * @access public
+ */
+ function isTalkPage() {
+ return Namespace::isTalk( $this->getNamespace() );
+ }
+
+ /**
+ * Is this a subpage?
+ * @return bool
+ * @access public
+ */
+ function isSubpage() {
+ global $wgNamespacesWithSubpages;
+
+ if( isset( $wgNamespacesWithSubpages[ $this->mNamespace ] ) ) {
+ return ( strpos( $this->getText(), '/' ) !== false && $wgNamespacesWithSubpages[ $this->mNamespace ] == true );
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Is this a .css or .js subpage of a user page?
+ * @return bool
+ * @access public
+ */
+ function isCssJsSubpage() {
+ return ( NS_USER == $this->mNamespace and preg_match("/\\/.*\\.(css|js)$/", $this->mTextform ) );
+ }
+ /**
+ * Is this a *valid* .css or .js subpage of a user page?
+ * Check that the corresponding skin exists
+ */
+ function isValidCssJsSubpage() {
+ if ( $this->isCssJsSubpage() ) {
+ $skinNames = Skin::getSkinNames();
+ return array_key_exists( $this->getSkinFromCssJsSubpage(), $skinNames );
+ } else {
+ return false;
+ }
+ }
+ /**
+ * Trim down a .css or .js subpage title to get the corresponding skin name
+ */
+ function getSkinFromCssJsSubpage() {
+ $subpage = explode( '/', $this->mTextform );
+ $subpage = $subpage[ count( $subpage ) - 1 ];
+ return( str_replace( array( '.css', '.js' ), array( '', '' ), $subpage ) );
+ }
+ /**
+ * Is this a .css subpage of a user page?
+ * @return bool
+ * @access public
+ */
+ function isCssSubpage() {
+ return ( NS_USER == $this->mNamespace and preg_match("/\\/.*\\.css$/", $this->mTextform ) );
+ }
+ /**
+ * Is this a .js subpage of a user page?
+ * @return bool
+ * @access public
+ */
+ function isJsSubpage() {
+ return ( NS_USER == $this->mNamespace and preg_match("/\\/.*\\.js$/", $this->mTextform ) );
+ }
+ /**
+ * Protect css/js subpages of user pages: can $wgUser edit
+ * this page?
+ *
+ * @return boolean
+ * @todo XXX: this might be better using restrictions
+ * @access public
+ */
+ function userCanEditCssJsSubpage() {
+ global $wgUser;
+ return ( $wgUser->isAllowed('editinterface') or preg_match('/^'.preg_quote($wgUser->getName(), '/').'\//', $this->mTextform) );
+ }
+
+ /**
+ * Loads a string into mRestrictions array
+ * @param string $res restrictions in string format
+ * @access public
+ */
+ function loadRestrictions( $res ) {
+ $this->mRestrictions['edit'] = array();
+ $this->mRestrictions['move'] = array();
+
+ if( !$res ) {
+ # No restrictions (page_restrictions blank)
+ $this->mRestrictionsLoaded = true;
+ return;
+ }
+
+ foreach( explode( ':', trim( $res ) ) as $restrict ) {
+ $temp = explode( '=', trim( $restrict ) );
+ if(count($temp) == 1) {
+ // old format should be treated as edit/move restriction
+ $this->mRestrictions["edit"] = explode( ',', trim( $temp[0] ) );
+ $this->mRestrictions["move"] = explode( ',', trim( $temp[0] ) );
+ } else {
+ $this->mRestrictions[$temp[0]] = explode( ',', trim( $temp[1] ) );
+ }
+ }
+ $this->mRestrictionsLoaded = true;
+ }
+
+ /**
+ * Accessor/initialisation for mRestrictions
+ *
+ * @access public
+ * @param string $action action that permission needs to be checked for
+ * @return array the array of groups allowed to edit this article
+ */
+ function getRestrictions( $action ) {
+ if( $this->exists() ) {
+ if( !$this->mRestrictionsLoaded ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->selectField( 'page', 'page_restrictions', array( 'page_id' => $this->getArticleId() ) );
+ $this->loadRestrictions( $res );
+ }
+ return isset( $this->mRestrictions[$action] )
+ ? $this->mRestrictions[$action]
+ : array();
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * Is there a version of this page in the deletion archive?
+ * @return int the number of archived revisions
+ * @access public
+ */
+ function isDeleted() {
+ $fname = 'Title::isDeleted';
+ if ( $this->getNamespace() < 0 ) {
+ $n = 0;
+ } else {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $n = $dbr->selectField( 'archive', 'COUNT(*)', array( 'ar_namespace' => $this->getNamespace(),
+ 'ar_title' => $this->getDBkey() ), $fname );
+ if( $this->getNamespace() == NS_IMAGE ) {
+ $n += $dbr->selectField( 'filearchive', 'COUNT(*)',
+ array( 'fa_name' => $this->getDBkey() ), $fname );
+ }
+ }
+ return (int)$n;
+ }
+
+ /**
+ * Get the article ID for this Title from the link cache,
+ * adding it if necessary
+ * @param int $flags a bit field; may be GAID_FOR_UPDATE to select
+ * for update
+ * @return int the ID
+ * @access public
+ */
+ function getArticleID( $flags = 0 ) {
+ $linkCache =& LinkCache::singleton();
+ if ( $flags & GAID_FOR_UPDATE ) {
+ $oldUpdate = $linkCache->forUpdate( true );
+ $this->mArticleID = $linkCache->addLinkObj( $this );
+ $linkCache->forUpdate( $oldUpdate );
+ } else {
+ if ( -1 == $this->mArticleID ) {
+ $this->mArticleID = $linkCache->addLinkObj( $this );
+ }
+ }
+ return $this->mArticleID;
+ }
+
+ function getLatestRevID() {
+ if ($this->mLatestID !== false)
+ return $this->mLatestID;
+
+ $db =& wfGetDB(DB_SLAVE);
+ return $this->mLatestID = $db->selectField( 'revision',
+ "max(rev_id)",
+ array('rev_page' => $this->getArticleID()),
+ 'Title::getLatestRevID' );
+ }
+
+ /**
+ * This clears some fields in this object, and clears any associated
+ * keys in the "bad links" section of the link cache.
+ *
+ * - This is called from Article::insertNewArticle() to allow
+ * loading of the new page_id. It's also called from
+ * Article::doDeleteArticle()
+ *
+ * @param int $newid the new Article ID
+ * @access public
+ */
+ function resetArticleID( $newid ) {
+ $linkCache =& LinkCache::singleton();
+ $linkCache->clearBadLink( $this->getPrefixedDBkey() );
+
+ if ( 0 == $newid ) { $this->mArticleID = -1; }
+ else { $this->mArticleID = $newid; }
+ $this->mRestrictionsLoaded = false;
+ $this->mRestrictions = array();
+ }
+
+ /**
+ * Updates page_touched for this page; called from LinksUpdate.php
+ * @return bool true if the update succeded
+ * @access public
+ */
+ function invalidateCache() {
+ global $wgUseFileCache;
+
+ if ( wfReadOnly() ) {
+ return;
+ }
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $success = $dbw->update( 'page',
+ array( /* SET */
+ 'page_touched' => $dbw->timestamp()
+ ), array( /* WHERE */
+ 'page_namespace' => $this->getNamespace() ,
+ 'page_title' => $this->getDBkey()
+ ), 'Title::invalidateCache'
+ );
+
+ if ($wgUseFileCache) {
+ $cache = new HTMLFileCache($this);
+ @unlink($cache->fileCacheName());
+ }
+
+ return $success;
+ }
+
+ /**
+ * Prefix some arbitrary text with the namespace or interwiki prefix
+ * of this object
+ *
+ * @param string $name the text
+ * @return string the prefixed text
+ * @private
+ */
+ /* private */ function prefix( $name ) {
+ $p = '';
+ if ( '' != $this->mInterwiki ) {
+ $p = $this->mInterwiki . ':';
+ }
+ if ( 0 != $this->mNamespace ) {
+ $p .= $this->getNsText() . ':';
+ }
+ return $p . $name;
+ }
+
+ /**
+ * Secure and split - main initialisation function for this object
+ *
+ * Assumes that mDbkeyform has been set, and is urldecoded
+ * and uses underscores, but not otherwise munged. This function
+ * removes illegal characters, splits off the interwiki and
+ * namespace prefixes, sets the other forms, and canonicalizes
+ * everything.
+ * @return bool true on success
+ * @private
+ */
+ /* private */ function secureAndSplit() {
+ global $wgContLang, $wgLocalInterwiki, $wgCapitalLinks;
+
+ # Initialisation
+ static $rxTc = false;
+ if( !$rxTc ) {
+ # % is needed as well
+ $rxTc = '/[^' . Title::legalChars() . ']|%[0-9A-Fa-f]{2}/S';
+ }
+
+ $this->mInterwiki = $this->mFragment = '';
+ $this->mNamespace = $this->mDefaultNamespace; # Usually NS_MAIN
+
+ $dbkey = $this->mDbkeyform;
+
+ # Strip Unicode bidi override characters.
+ # Sometimes they slip into cut-n-pasted page titles, where the
+ # override chars get included in list displays.
+ $dbkey = str_replace( "\xE2\x80\x8E", '', $dbkey ); // 200E LEFT-TO-RIGHT MARK
+ $dbkey = str_replace( "\xE2\x80\x8F", '', $dbkey ); // 200F RIGHT-TO-LEFT MARK
+
+ # Clean up whitespace
+ #
+ $dbkey = preg_replace( '/[ _]+/', '_', $dbkey );
+ $dbkey = trim( $dbkey, '_' );
+
+ if ( '' == $dbkey ) {
+ return false;
+ }
+
+ if( false !== strpos( $dbkey, UTF8_REPLACEMENT ) ) {
+ # Contained illegal UTF-8 sequences or forbidden Unicode chars.
+ return false;
+ }
+
+ $this->mDbkeyform = $dbkey;
+
+ # Initial colon indicates main namespace rather than specified default
+ # but should not create invalid {ns,title} pairs such as {0,Project:Foo}
+ if ( ':' == $dbkey{0} ) {
+ $this->mNamespace = NS_MAIN;
+ $dbkey = substr( $dbkey, 1 ); # remove the colon but continue processing
+ }
+
+ # Namespace or interwiki prefix
+ $firstPass = true;
+ do {
+ $m = array();
+ if ( preg_match( "/^(.+?)_*:_*(.*)$/S", $dbkey, $m ) ) {
+ $p = $m[1];
+ $lowerNs = $wgContLang->lc( $p );
+ if ( $ns = Namespace::getCanonicalIndex( $lowerNs ) ) {
+ # Canonical namespace
+ $dbkey = $m[2];
+ $this->mNamespace = $ns;
+ } elseif ( $ns = $wgContLang->getNsIndex( $lowerNs )) {
+ # Ordinary namespace
+ $dbkey = $m[2];
+ $this->mNamespace = $ns;
+ } elseif( $this->getInterwikiLink( $p ) ) {
+ if( !$firstPass ) {
+ # Can't make a local interwiki link to an interwiki link.
+ # That's just crazy!
+ return false;
+ }
+
+ # Interwiki link
+ $dbkey = $m[2];
+ $this->mInterwiki = $wgContLang->lc( $p );
+
+ # Redundant interwiki prefix to the local wiki
+ if ( 0 == strcasecmp( $this->mInterwiki, $wgLocalInterwiki ) ) {
+ if( $dbkey == '' ) {
+ # Can't have an empty self-link
+ return false;
+ }
+ $this->mInterwiki = '';
+ $firstPass = false;
+ # Do another namespace split...
+ continue;
+ }
+
+ # If there's an initial colon after the interwiki, that also
+ # resets the default namespace
+ if ( $dbkey !== '' && $dbkey[0] == ':' ) {
+ $this->mNamespace = NS_MAIN;
+ $dbkey = substr( $dbkey, 1 );
+ }
+ }
+ # If there's no recognized interwiki or namespace,
+ # then let the colon expression be part of the title.
+ }
+ break;
+ } while( true );
+
+ # We already know that some pages won't be in the database!
+ #
+ if ( '' != $this->mInterwiki || NS_SPECIAL == $this->mNamespace ) {
+ $this->mArticleID = 0;
+ }
+ $fragment = strstr( $dbkey, '#' );
+ if ( false !== $fragment ) {
+ $this->setFragment( $fragment );
+ $dbkey = substr( $dbkey, 0, strlen( $dbkey ) - strlen( $fragment ) );
+ # remove whitespace again: prevents "Foo_bar_#"
+ # becoming "Foo_bar_"
+ $dbkey = preg_replace( '/_*$/', '', $dbkey );
+ }
+
+ # Reject illegal characters.
+ #
+ if( preg_match( $rxTc, $dbkey ) ) {
+ return false;
+ }
+
+ /**
+ * Pages with "/./" or "/../" appearing in the URLs will
+ * often be unreachable due to the way web browsers deal
+ * with 'relative' URLs. Forbid them explicitly.
+ */
+ if ( strpos( $dbkey, '.' ) !== false &&
+ ( $dbkey === '.' || $dbkey === '..' ||
+ strpos( $dbkey, './' ) === 0 ||
+ strpos( $dbkey, '../' ) === 0 ||
+ strpos( $dbkey, '/./' ) !== false ||
+ strpos( $dbkey, '/../' ) !== false ) )
+ {
+ return false;
+ }
+
+ /**
+ * Limit the size of titles to 255 bytes.
+ * This is typically the size of the underlying database field.
+ * We make an exception for special pages, which don't need to be stored
+ * in the database, and may edge over 255 bytes due to subpage syntax
+ * for long titles, e.g. [[Special:Block/Long name]]
+ */
+ if ( ( $this->mNamespace != NS_SPECIAL && strlen( $dbkey ) > 255 ) ||
+ strlen( $dbkey ) > 512 )
+ {
+ return false;
+ }
+
+ /**
+ * Normally, all wiki links are forced to have
+ * an initial capital letter so [[foo]] and [[Foo]]
+ * point to the same place.
+ *
+ * Don't force it for interwikis, since the other
+ * site might be case-sensitive.
+ */
+ if( $wgCapitalLinks && $this->mInterwiki == '') {
+ $dbkey = $wgContLang->ucfirst( $dbkey );
+ }
+
+ /**
+ * Can't make a link to a namespace alone...
+ * "empty" local links can only be self-links
+ * with a fragment identifier.
+ */
+ if( $dbkey == '' &&
+ $this->mInterwiki == '' &&
+ $this->mNamespace != NS_MAIN ) {
+ return false;
+ }
+
+ // Any remaining initial :s are illegal.
+ if ( $dbkey !== '' && ':' == $dbkey{0} ) {
+ return false;
+ }
+
+ # Fill fields
+ $this->mDbkeyform = $dbkey;
+ $this->mUrlform = wfUrlencode( $dbkey );
+
+ $this->mTextform = str_replace( '_', ' ', $dbkey );
+
+ return true;
+ }
+
+ /**
+ * Set the fragment for this title
+ * This is kind of bad, since except for this rarely-used function, Title objects
+ * are immutable. The reason this is here is because it's better than setting the
+ * members directly, which is what Linker::formatComment was doing previously.
+ *
+ * @param string $fragment text
+ * @access kind of public
+ */
+ function setFragment( $fragment ) {
+ $this->mFragment = str_replace( '_', ' ', substr( $fragment, 1 ) );
+ }
+
+ /**
+ * Get a Title object associated with the talk page of this article
+ * @return Title the object for the talk page
+ * @access public
+ */
+ function getTalkPage() {
+ return Title::makeTitle( Namespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
+ }
+
+ /**
+ * Get a title object associated with the subject page of this
+ * talk page
+ *
+ * @return Title the object for the subject page
+ * @access public
+ */
+ function getSubjectPage() {
+ return Title::makeTitle( Namespace::getSubject( $this->getNamespace() ), $this->getDBkey() );
+ }
+
+ /**
+ * Get an array of Title objects linking to this Title
+ * Also stores the IDs in the link cache.
+ *
+ * WARNING: do not use this function on arbitrary user-supplied titles!
+ * On heavily-used templates it will max out the memory.
+ *
+ * @param string $options may be FOR UPDATE
+ * @return array the Title objects linking here
+ * @access public
+ */
+ function getLinksTo( $options = '', $table = 'pagelinks', $prefix = 'pl' ) {
+ $linkCache =& LinkCache::singleton();
+
+ if ( $options ) {
+ $db =& wfGetDB( DB_MASTER );
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ }
+
+ $res = $db->select( array( 'page', $table ),
+ array( 'page_namespace', 'page_title', 'page_id' ),
+ array(
+ "{$prefix}_from=page_id",
+ "{$prefix}_namespace" => $this->getNamespace(),
+ "{$prefix}_title" => $this->getDbKey() ),
+ 'Title::getLinksTo',
+ $options );
+
+ $retVal = array();
+ if ( $db->numRows( $res ) ) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( $titleObj = Title::makeTitle( $row->page_namespace, $row->page_title ) ) {
+ $linkCache->addGoodLinkObj( $row->page_id, $titleObj );
+ $retVal[] = $titleObj;
+ }
+ }
+ }
+ $db->freeResult( $res );
+ return $retVal;
+ }
+
+ /**
+ * Get an array of Title objects using this Title as a template
+ * Also stores the IDs in the link cache.
+ *
+ * WARNING: do not use this function on arbitrary user-supplied titles!
+ * On heavily-used templates it will max out the memory.
+ *
+ * @param string $options may be FOR UPDATE
+ * @return array the Title objects linking here
+ * @access public
+ */
+ function getTemplateLinksTo( $options = '' ) {
+ return $this->getLinksTo( $options, 'templatelinks', 'tl' );
+ }
+
+ /**
+ * Get an array of Title objects referring to non-existent articles linked from this page
+ *
+ * @param string $options may be FOR UPDATE
+ * @return array the Title objects
+ * @access public
+ */
+ function getBrokenLinksFrom( $options = '' ) {
+ if ( $options ) {
+ $db =& wfGetDB( DB_MASTER );
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ }
+
+ $res = $db->safeQuery(
+ "SELECT pl_namespace, pl_title
+ FROM !
+ LEFT JOIN !
+ ON pl_namespace=page_namespace
+ AND pl_title=page_title
+ WHERE pl_from=?
+ AND page_namespace IS NULL
+ !",
+ $db->tableName( 'pagelinks' ),
+ $db->tableName( 'page' ),
+ $this->getArticleId(),
+ $options );
+
+ $retVal = array();
+ if ( $db->numRows( $res ) ) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ $retVal[] = Title::makeTitle( $row->pl_namespace, $row->pl_title );
+ }
+ }
+ $db->freeResult( $res );
+ return $retVal;
+ }
+
+
+ /**
+ * Get a list of URLs to purge from the Squid cache when this
+ * page changes
+ *
+ * @return array the URLs
+ * @access public
+ */
+ function getSquidURLs() {
+ global $wgContLang;
+
+ $urls = array(
+ $this->getInternalURL(),
+ $this->getInternalURL( 'action=history' )
+ );
+
+ // purge variant urls as well
+ if($wgContLang->hasVariants()){
+ $variants = $wgContLang->getVariants();
+ foreach($variants as $vCode){
+ if($vCode==$wgContLang->getCode()) continue; // we don't want default variant
+ $urls[] = $this->getInternalURL('',$vCode);
+ }
+ }
+
+ return $urls;
+ }
+
+ function purgeSquid() {
+ global $wgUseSquid;
+ if ( $wgUseSquid ) {
+ $urls = $this->getSquidURLs();
+ $u = new SquidUpdate( $urls );
+ $u->doUpdate();
+ }
+ }
+
+ /**
+ * Move this page without authentication
+ * @param Title &$nt the new page Title
+ * @access public
+ */
+ function moveNoAuth( &$nt ) {
+ return $this->moveTo( $nt, false );
+ }
+
+ /**
+ * Check whether a given move operation would be valid.
+ * Returns true if ok, or a message key string for an error message
+ * if invalid. (Scarrrrry ugly interface this.)
+ * @param Title &$nt the new title
+ * @param bool $auth indicates whether $wgUser's permissions
+ * should be checked
+ * @return mixed true on success, message name on failure
+ * @access public
+ */
+ function isValidMoveOperation( &$nt, $auth = true ) {
+ if( !$this or !$nt ) {
+ return 'badtitletext';
+ }
+ if( $this->equals( $nt ) ) {
+ return 'selfmove';
+ }
+ if( !$this->isMovable() || !$nt->isMovable() ) {
+ return 'immobile_namespace';
+ }
+
+ $oldid = $this->getArticleID();
+ $newid = $nt->getArticleID();
+
+ if ( strlen( $nt->getDBkey() ) < 1 ) {
+ return 'articleexists';
+ }
+ if ( ( '' == $this->getDBkey() ) ||
+ ( !$oldid ) ||
+ ( '' == $nt->getDBkey() ) ) {
+ return 'badarticleerror';
+ }
+
+ if ( $auth && (
+ !$this->userCanEdit() || !$nt->userCanEdit() ||
+ !$this->userCanMove() || !$nt->userCanMove() ) ) {
+ return 'protectedpage';
+ }
+
+ # The move is allowed only if (1) the target doesn't exist, or
+ # (2) the target is a redirect to the source, and has no history
+ # (so we can undo bad moves right after they're done).
+
+ if ( 0 != $newid ) { # Target exists; check for validity
+ if ( ! $this->isValidMoveTarget( $nt ) ) {
+ return 'articleexists';
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Move a title to a new location
+ * @param Title &$nt the new title
+ * @param bool $auth indicates whether $wgUser's permissions
+ * should be checked
+ * @return mixed true on success, message name on failure
+ * @access public
+ */
+ function moveTo( &$nt, $auth = true, $reason = '' ) {
+ $err = $this->isValidMoveOperation( $nt, $auth );
+ if( is_string( $err ) ) {
+ return $err;
+ }
+
+ $pageid = $this->getArticleID();
+ if( $nt->exists() ) {
+ $this->moveOverExistingRedirect( $nt, $reason );
+ $pageCountChange = 0;
+ } else { # Target didn't exist, do normal move.
+ $this->moveToNewTitle( $nt, $reason );
+ $pageCountChange = 1;
+ }
+ $redirid = $this->getArticleID();
+
+ # Fixing category links (those without piped 'alternate' names) to be sorted under the new title
+ $dbw =& wfGetDB( DB_MASTER );
+ $categorylinks = $dbw->tableName( 'categorylinks' );
+ $sql = "UPDATE $categorylinks SET cl_sortkey=" . $dbw->addQuotes( $nt->getPrefixedText() ) .
+ " WHERE cl_from=" . $dbw->addQuotes( $pageid ) .
+ " AND cl_sortkey=" . $dbw->addQuotes( $this->getPrefixedText() );
+ $dbw->query( $sql, 'SpecialMovepage::doSubmit' );
+
+ # Update watchlists
+
+ $oldnamespace = $this->getNamespace() & ~1;
+ $newnamespace = $nt->getNamespace() & ~1;
+ $oldtitle = $this->getDBkey();
+ $newtitle = $nt->getDBkey();
+
+ if( $oldnamespace != $newnamespace || $oldtitle != $newtitle ) {
+ WatchedItem::duplicateEntries( $this, $nt );
+ }
+
+ # Update search engine
+ $u = new SearchUpdate( $pageid, $nt->getPrefixedDBkey() );
+ $u->doUpdate();
+ $u = new SearchUpdate( $redirid, $this->getPrefixedDBkey(), '' );
+ $u->doUpdate();
+
+ # Update site_stats
+ if ( $this->getNamespace() == NS_MAIN and $nt->getNamespace() != NS_MAIN ) {
+ # Moved out of main namespace
+ # not viewed, edited, removing
+ $u = new SiteStatsUpdate( 0, 1, -1, $pageCountChange);
+ } elseif ( $this->getNamespace() != NS_MAIN and $nt->getNamespace() == NS_MAIN ) {
+ # Moved into main namespace
+ # not viewed, edited, adding
+ $u = new SiteStatsUpdate( 0, 1, +1, $pageCountChange );
+ } elseif ( $pageCountChange ) {
+ # Added redirect
+ $u = new SiteStatsUpdate( 0, 0, 0, 1 );
+ } else{
+ $u = false;
+ }
+ if ( $u ) {
+ $u->doUpdate();
+ }
+
+ global $wgUser;
+ wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) );
+ return true;
+ }
+
+ /**
+ * Move page to a title which is at present a redirect to the
+ * source page
+ *
+ * @param Title &$nt the page to move to, which should currently
+ * be a redirect
+ * @private
+ */
+ function moveOverExistingRedirect( &$nt, $reason = '' ) {
+ global $wgUseSquid;
+ $fname = 'Title::moveOverExistingRedirect';
+ $comment = wfMsgForContent( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() );
+
+ if ( $reason ) {
+ $comment .= ": $reason";
+ }
+
+ $now = wfTimestampNow();
+ $newid = $nt->getArticleID();
+ $oldid = $this->getArticleID();
+ $dbw =& wfGetDB( DB_MASTER );
+ $linkCache =& LinkCache::singleton();
+
+ # 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 ), $fname );
+
+ # Save a null revision in the page's history notifying of the move
+ $nullRevision = Revision::newNullRevision( $dbw, $oldid, $comment, true );
+ $nullRevId = $nullRevision->insertOn( $dbw );
+
+ # Change the name of the target page:
+ $dbw->update( 'page',
+ /* SET */ array(
+ 'page_touched' => $dbw->timestamp($now),
+ 'page_namespace' => $nt->getNamespace(),
+ 'page_title' => $nt->getDBkey(),
+ 'page_latest' => $nullRevId,
+ ),
+ /* WHERE */ array( 'page_id' => $oldid ),
+ $fname
+ );
+ $linkCache->clearLink( $nt->getPrefixedDBkey() );
+
+ # Recreate the redirect, this time in the other direction.
+ $mwRedir = MagicWord::get( 'redirect' );
+ $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n";
+ $redirectArticle = new Article( $this );
+ $newid = $redirectArticle->insertOn( $dbw );
+ $redirectRevision = new Revision( array(
+ 'page' => $newid,
+ 'comment' => $comment,
+ 'text' => $redirectText ) );
+ $redirectRevision->insertOn( $dbw );
+ $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
+ $linkCache->clearLink( $this->getPrefixedDBkey() );
+
+ # Log the move
+ $log = new LogPage( 'move' );
+ $log->addEntry( 'move_redir', $this, $reason, array( 1 => $nt->getPrefixedText() ) );
+
+ # Now, we record the link from the redirect to the new title.
+ # It should have no other outgoing links...
+ $dbw->delete( 'pagelinks', array( 'pl_from' => $newid ), $fname );
+ $dbw->insert( 'pagelinks',
+ array(
+ 'pl_from' => $newid,
+ 'pl_namespace' => $nt->getNamespace(),
+ 'pl_title' => $nt->getDbKey() ),
+ $fname );
+
+ # Purge squid
+ if ( $wgUseSquid ) {
+ $urls = array_merge( $nt->getSquidURLs(), $this->getSquidURLs() );
+ $u = new SquidUpdate( $urls );
+ $u->doUpdate();
+ }
+ }
+
+ /**
+ * Move page to non-existing title.
+ * @param Title &$nt the new Title
+ * @private
+ */
+ function moveToNewTitle( &$nt, $reason = '' ) {
+ global $wgUseSquid;
+ $fname = 'MovePageForm::moveToNewTitle';
+ $comment = wfMsgForContent( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() );
+ if ( $reason ) {
+ $comment .= ": $reason";
+ }
+
+ $newid = $nt->getArticleID();
+ $oldid = $this->getArticleID();
+ $dbw =& wfGetDB( DB_MASTER );
+ $now = $dbw->timestamp();
+ $linkCache =& LinkCache::singleton();
+
+ # Save a null revision in the page's history notifying of the move
+ $nullRevision = Revision::newNullRevision( $dbw, $oldid, $comment, true );
+ $nullRevId = $nullRevision->insertOn( $dbw );
+
+ # Rename cur entry
+ $dbw->update( 'page',
+ /* SET */ array(
+ 'page_touched' => $now,
+ 'page_namespace' => $nt->getNamespace(),
+ 'page_title' => $nt->getDBkey(),
+ 'page_latest' => $nullRevId,
+ ),
+ /* WHERE */ array( 'page_id' => $oldid ),
+ $fname
+ );
+
+ $linkCache->clearLink( $nt->getPrefixedDBkey() );
+
+ # Insert redirect
+ $mwRedir = MagicWord::get( 'redirect' );
+ $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n";
+ $redirectArticle = new Article( $this );
+ $newid = $redirectArticle->insertOn( $dbw );
+ $redirectRevision = new Revision( array(
+ 'page' => $newid,
+ 'comment' => $comment,
+ 'text' => $redirectText ) );
+ $redirectRevision->insertOn( $dbw );
+ $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
+ $linkCache->clearLink( $this->getPrefixedDBkey() );
+
+ # Log the move
+ $log = new LogPage( 'move' );
+ $log->addEntry( 'move', $this, $reason, array( 1 => $nt->getPrefixedText()) );
+
+ # Purge caches as per article creation
+ Article::onArticleCreate( $nt );
+
+ # Record the just-created redirect's linking to the page
+ $dbw->insert( 'pagelinks',
+ array(
+ 'pl_from' => $newid,
+ 'pl_namespace' => $nt->getNamespace(),
+ 'pl_title' => $nt->getDBkey() ),
+ $fname );
+
+ # Purge old title from squid
+ # The new title, and links to the new title, are purged in Article::onArticleCreate()
+ $this->purgeSquid();
+ }
+
+ /**
+ * Checks if $this can be moved to a given Title
+ * - Selects for update, so don't call it unless you mean business
+ *
+ * @param Title &$nt the new title to check
+ * @access public
+ */
+ function isValidMoveTarget( $nt ) {
+
+ $fname = 'Title::isValidMoveTarget';
+ $dbw =& wfGetDB( DB_MASTER );
+
+ # Is it a redirect?
+ $id = $nt->getArticleID();
+ $obj = $dbw->selectRow( array( 'page', 'revision', 'text'),
+ array( 'page_is_redirect','old_text','old_flags' ),
+ array( 'page_id' => $id, 'page_latest=rev_id', 'rev_text_id=old_id' ),
+ $fname, 'FOR UPDATE' );
+
+ if ( !$obj || 0 == $obj->page_is_redirect ) {
+ # Not a redirect
+ wfDebug( __METHOD__ . ": not a redirect\n" );
+ return false;
+ }
+ $text = Revision::getRevisionText( $obj );
+
+ # Does the redirect point to the source?
+ # Or is it a broken self-redirect, usually caused by namespace collisions?
+ $m = array();
+ if ( preg_match( "/\\[\\[\\s*([^\\]\\|]*)]]/", $text, $m ) ) {
+ $redirTitle = Title::newFromText( $m[1] );
+ if( !is_object( $redirTitle ) ||
+ ( $redirTitle->getPrefixedDBkey() != $this->getPrefixedDBkey() &&
+ $redirTitle->getPrefixedDBkey() != $nt->getPrefixedDBkey() ) ) {
+ wfDebug( __METHOD__ . ": redirect points to other page\n" );
+ return false;
+ }
+ } else {
+ # Fail safe
+ wfDebug( __METHOD__ . ": failsafe\n" );
+ return false;
+ }
+
+ # Does the article have a history?
+ $row = $dbw->selectRow( array( 'page', 'revision'),
+ array( 'rev_id' ),
+ array( 'page_namespace' => $nt->getNamespace(),
+ 'page_title' => $nt->getDBkey(),
+ 'page_id=rev_page AND page_latest != rev_id'
+ ), $fname, 'FOR UPDATE'
+ );
+
+ # Return true if there was no history
+ return $row === false;
+ }
+
+ /**
+ * Create a redirect; fails if the title already exists; does
+ * not notify RC
+ *
+ * @param Title $dest the destination of the redirect
+ * @param string $comment the comment string describing the move
+ * @return bool true on success
+ * @access public
+ */
+ function createRedirect( $dest, $comment ) {
+ if ( $this->getArticleID() ) {
+ return false;
+ }
+
+ $fname = 'Title::createRedirect';
+ $dbw =& wfGetDB( DB_MASTER );
+
+ $article = new Article( $this );
+ $newid = $article->insertOn( $dbw );
+ $revision = new Revision( array(
+ 'page' => $newid,
+ 'comment' => $comment,
+ 'text' => "#REDIRECT [[" . $dest->getPrefixedText() . "]]\n",
+ ) );
+ $revision->insertOn( $dbw );
+ $article->updateRevisionOn( $dbw, $revision, 0 );
+
+ # Link table
+ $dbw->insert( 'pagelinks',
+ array(
+ 'pl_from' => $newid,
+ 'pl_namespace' => $dest->getNamespace(),
+ 'pl_title' => $dest->getDbKey()
+ ), $fname
+ );
+
+ Article::onArticleCreate( $this );
+ return true;
+ }
+
+ /**
+ * Get categories to which this Title belongs and return an array of
+ * categories' names.
+ *
+ * @return array an array of parents in the form:
+ * $parent => $currentarticle
+ * @access public
+ */
+ function getParentCategories() {
+ global $wgContLang;
+
+ $titlekey = $this->getArticleId();
+ $dbr =& wfGetDB( DB_SLAVE );
+ $categorylinks = $dbr->tableName( 'categorylinks' );
+
+ # NEW SQL
+ $sql = "SELECT * FROM $categorylinks"
+ ." WHERE cl_from='$titlekey'"
+ ." AND cl_from <> '0'"
+ ." ORDER BY cl_sortkey";
+
+ $res = $dbr->query ( $sql ) ;
+
+ if($dbr->numRows($res) > 0) {
+ while ( $x = $dbr->fetchObject ( $res ) )
+ //$data[] = Title::newFromText($wgContLang->getNSText ( NS_CATEGORY ).':'.$x->cl_to);
+ $data[$wgContLang->getNSText ( NS_CATEGORY ).':'.$x->cl_to] = $this->getFullText();
+ $dbr->freeResult ( $res ) ;
+ } else {
+ $data = '';
+ }
+ return $data;
+ }
+
+ /**
+ * Get a tree of parent categories
+ * @param array $children an array with the children in the keys, to check for circular refs
+ * @return array
+ * @access public
+ */
+ function getParentCategoryTree( $children = array() ) {
+ $parents = $this->getParentCategories();
+
+ if($parents != '') {
+ foreach($parents as $parent => $current) {
+ if ( array_key_exists( $parent, $children ) ) {
+ # Circular reference
+ $stack[$parent] = array();
+ } else {
+ $nt = Title::newFromText($parent);
+ if ( $nt ) {
+ $stack[$parent] = $nt->getParentCategoryTree( $children + array($parent => 1) );
+ }
+ }
+ }
+ return $stack;
+ } else {
+ return array();
+ }
+ }
+
+
+ /**
+ * Get an associative array for selecting this title from
+ * the "page" table
+ *
+ * @return array
+ * @access public
+ */
+ function pageCond() {
+ return array( 'page_namespace' => $this->mNamespace, 'page_title' => $this->mDbkeyform );
+ }
+
+ /**
+ * Get the revision ID of the previous revision
+ *
+ * @param integer $revision Revision ID. Get the revision that was before this one.
+ * @return integer $oldrevision|false
+ */
+ function getPreviousRevisionID( $revision ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $dbr->selectField( 'revision', 'rev_id',
+ 'rev_page=' . intval( $this->getArticleId() ) .
+ ' AND rev_id<' . intval( $revision ) . ' ORDER BY rev_id DESC' );
+ }
+
+ /**
+ * Get the revision ID of the next revision
+ *
+ * @param integer $revision Revision ID. Get the revision that was after this one.
+ * @return integer $oldrevision|false
+ */
+ function getNextRevisionID( $revision ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $dbr->selectField( 'revision', 'rev_id',
+ 'rev_page=' . intval( $this->getArticleId() ) .
+ ' AND rev_id>' . intval( $revision ) . ' ORDER BY rev_id' );
+ }
+
+ /**
+ * Get the number of revisions between the given revision IDs.
+ *
+ * @param integer $old Revision ID.
+ * @param integer $new Revision ID.
+ * @return integer Number of revisions between these IDs.
+ */
+ function countRevisionsBetween( $old, $new ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $dbr->selectField( 'revision', 'count(*)',
+ 'rev_page = ' . intval( $this->getArticleId() ) .
+ ' AND rev_id > ' . intval( $old ) .
+ ' AND rev_id < ' . intval( $new ) );
+ }
+
+ /**
+ * Compare with another title.
+ *
+ * @param Title $title
+ * @return bool
+ */
+ function equals( $title ) {
+ // Note: === is necessary for proper matching of number-like titles.
+ return $this->getInterwiki() === $title->getInterwiki()
+ && $this->getNamespace() == $title->getNamespace()
+ && $this->getDbkey() === $title->getDbkey();
+ }
+
+ /**
+ * Check if page exists
+ * @return bool
+ */
+ function exists() {
+ return $this->getArticleId() != 0;
+ }
+
+ /**
+ * Should a link should be displayed as a known link, just based on its title?
+ *
+ * Currently, a self-link with a fragment and special pages are in
+ * this category. Special pages never exist in the database.
+ */
+ function isAlwaysKnown() {
+ return $this->isExternal() || ( 0 == $this->mNamespace && "" == $this->mDbkeyform )
+ || NS_SPECIAL == $this->mNamespace;
+ }
+
+ /**
+ * Update page_touched timestamps and send squid purge messages for
+ * pages linking to this title. May be sent to the job queue depending
+ * on the number of links. Typically called on create and delete.
+ */
+ function touchLinks() {
+ $u = new HTMLCacheUpdate( $this, 'pagelinks' );
+ $u->doUpdate();
+
+ if ( $this->getNamespace() == NS_CATEGORY ) {
+ $u = new HTMLCacheUpdate( $this, 'categorylinks' );
+ $u->doUpdate();
+ }
+ }
+
+ /**
+ * Get the last touched timestamp
+ */
+ function getTouched() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $touched = $dbr->selectField( 'page', 'page_touched',
+ array(
+ 'page_namespace' => $this->getNamespace(),
+ 'page_title' => $this->getDBkey()
+ ), __METHOD__
+ );
+ return $touched;
+ }
+
+ /**
+ * Get a cached value from a global cache that is invalidated when this page changes
+ * @param string $key the key
+ * @param callback $callback A callback function which generates the value on cache miss
+ *
+ * @deprecated use DependencyWrapper
+ */
+ function getRelatedCache( $memc, $key, $expiry, $callback, $params = array() ) {
+ return DependencyWrapper::getValueFromCache( $memc, $key, $expiry, $callback,
+ $params, new TitleDependency( $this ) );
+ }
+
+ function trackbackURL() {
+ global $wgTitle, $wgScriptPath, $wgServer;
+
+ return "$wgServer$wgScriptPath/trackback.php?article="
+ . htmlspecialchars(urlencode($wgTitle->getPrefixedDBkey()));
+ }
+
+ function trackbackRDF() {
+ $url = htmlspecialchars($this->getFullURL());
+ $title = htmlspecialchars($this->getText());
+ $tburl = $this->trackbackURL();
+
+ return "
+<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
+ xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
+ xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\">
+<rdf:Description
+ rdf:about=\"$url\"
+ dc:identifier=\"$url\"
+ dc:title=\"$title\"
+ trackback:ping=\"$tburl\" />
+</rdf:RDF>";
+ }
+
+ /**
+ * Generate strings used for xml 'id' names in monobook tabs
+ * @return string
+ */
+ function getNamespaceKey() {
+ global $wgContLang;
+ switch ($this->getNamespace()) {
+ case NS_MAIN:
+ case NS_TALK:
+ return 'nstab-main';
+ case NS_USER:
+ case NS_USER_TALK:
+ return 'nstab-user';
+ case NS_MEDIA:
+ return 'nstab-media';
+ case NS_SPECIAL:
+ return 'nstab-special';
+ case NS_PROJECT:
+ case NS_PROJECT_TALK:
+ return 'nstab-project';
+ case NS_IMAGE:
+ case NS_IMAGE_TALK:
+ return 'nstab-image';
+ case NS_MEDIAWIKI:
+ case NS_MEDIAWIKI_TALK:
+ return 'nstab-mediawiki';
+ case NS_TEMPLATE:
+ case NS_TEMPLATE_TALK:
+ return 'nstab-template';
+ case NS_HELP:
+ case NS_HELP_TALK:
+ return 'nstab-help';
+ case NS_CATEGORY:
+ case NS_CATEGORY_TALK:
+ return 'nstab-category';
+ default:
+ return 'nstab-' . $wgContLang->lc( $this->getSubjectNsText() );
+ }
+ }
+
+ /**
+ * Returns true if this title resolves to the named special page
+ * @param string $name The special page name
+ * @access public
+ */
+ function isSpecial( $name ) {
+ if ( $this->getNamespace() == NS_SPECIAL ) {
+ list( $thisName, /* $subpage */ ) = SpecialPage::resolveAliasWithSubpage( $this->getDBkey() );
+ if ( $name == $thisName ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * If the Title refers to a special page alias which is not the local default,
+ * returns a new Title which points to the local default. Otherwise, returns $this.
+ */
+ function fixSpecialName() {
+ if ( $this->getNamespace() == NS_SPECIAL ) {
+ $canonicalName = SpecialPage::resolveAlias( $this->mDbkeyform );
+ if ( $canonicalName ) {
+ $localName = SpecialPage::getLocalNameFor( $canonicalName );
+ if ( $localName != $this->mDbkeyform ) {
+ return Title::makeTitle( NS_SPECIAL, $localName );
+ }
+ }
+ }
+ return $this;
+ }
+}
+?>
diff --git a/includes/User.php b/includes/User.php
new file mode 100644
index 000000000000..35ff8299b973
--- /dev/null
+++ b/includes/User.php
@@ -0,0 +1,2527 @@
+<?php
+/**
+ * See user.txt
+ *
+ * @package MediaWiki
+ */
+
+# Number of characters in user_token field
+define( 'USER_TOKEN_LENGTH', 32 );
+
+# Serialized record version
+define( 'MW_USER_VERSION', 4 );
+
+# Some punctuation to prevent editing from broken text-mangling proxies.
+# FIXME: this is embedded unescaped into HTML attributes in various
+# places, so we can't safely include ' or " even though we really should.
+define( 'EDIT_TOKEN_SUFFIX', '\\' );
+
+/**
+ * Thrown by User::setPassword() on error
+ */
+class PasswordError extends MWException {
+ // NOP
+}
+
+/**
+ *
+ * @package MediaWiki
+ */
+class User {
+
+ /**
+ * A list of default user toggles, i.e. boolean user preferences that are
+ * displayed by Special:Preferences as checkboxes. This list can be
+ * extended via the UserToggles hook or $wgContLang->getExtraUserToggles().
+ */
+ static public $mToggles = array(
+ 'highlightbroken',
+ 'justify',
+ 'hideminor',
+ 'extendwatchlist',
+ 'usenewrc',
+ 'numberheadings',
+ 'showtoolbar',
+ 'editondblclick',
+ 'editsection',
+ 'editsectiononrightclick',
+ 'showtoc',
+ 'rememberpassword',
+ 'editwidth',
+ 'watchcreations',
+ 'watchdefault',
+ 'watchmoves',
+ 'watchdeletion',
+ 'minordefault',
+ 'previewontop',
+ 'previewonfirst',
+ 'nocache',
+ 'enotifwatchlistpages',
+ 'enotifusertalkpages',
+ 'enotifminoredits',
+ 'enotifrevealaddr',
+ 'shownumberswatching',
+ 'fancysig',
+ 'externaleditor',
+ 'externaldiff',
+ 'showjumplinks',
+ 'uselivepreview',
+ 'forceeditsummary',
+ 'watchlisthideown',
+ 'watchlisthidebots',
+ 'watchlisthideminor',
+ 'ccmeonemails',
+ );
+
+ /**
+ * List of member variables which are saved to the shared cache (memcached).
+ * Any operation which changes the corresponding database fields must
+ * call a cache-clearing function.
+ */
+ static $mCacheVars = array(
+ # user table
+ 'mId',
+ 'mName',
+ 'mRealName',
+ 'mPassword',
+ 'mNewpassword',
+ 'mNewpassTime',
+ 'mEmail',
+ 'mOptions',
+ 'mTouched',
+ 'mToken',
+ 'mEmailAuthenticated',
+ 'mEmailToken',
+ 'mEmailTokenExpires',
+ 'mRegistration',
+
+ # user_group table
+ 'mGroups',
+ );
+
+ /**
+ * The cache variable declarations
+ */
+ var $mId, $mName, $mRealName, $mPassword, $mNewpassword, $mNewpassTime,
+ $mEmail, $mOptions, $mTouched, $mToken, $mEmailAuthenticated,
+ $mEmailToken, $mEmailTokenExpires, $mRegistration, $mGroups;
+
+ /**
+ * Whether the cache variables have been loaded
+ */
+ var $mDataLoaded;
+
+ /**
+ * Initialisation data source if mDataLoaded==false. May be one of:
+ * defaults anonymous user initialised from class defaults
+ * name initialise from mName
+ * id initialise from mId
+ * session log in from cookies or session if possible
+ *
+ * Use the User::newFrom*() family of functions to set this.
+ */
+ var $mFrom;
+
+ /**
+ * Lazy-initialised variables, invalidated with clearInstanceCache
+ */
+ var $mNewtalk, $mDatePreference, $mBlockedby, $mHash, $mSkin, $mRights,
+ $mBlockreason, $mBlock, $mEffectiveGroups;
+
+ /**
+ * Lightweight constructor for anonymous user
+ * Use the User::newFrom* factory functions for other kinds of users
+ */
+ function User() {
+ $this->clearInstanceCache( 'defaults' );
+ }
+
+ /**
+ * Load the user table data for this object from the source given by mFrom
+ */
+ function load() {
+ if ( $this->mDataLoaded ) {
+ return;
+ }
+ wfProfileIn( __METHOD__ );
+
+ # Set it now to avoid infinite recursion in accessors
+ $this->mDataLoaded = true;
+
+ switch ( $this->mFrom ) {
+ case 'defaults':
+ $this->loadDefaults();
+ break;
+ case 'name':
+ $this->mId = self::idFromName( $this->mName );
+ if ( !$this->mId ) {
+ # Nonexistent user placeholder object
+ $this->loadDefaults( $this->mName );
+ } else {
+ $this->loadFromId();
+ }
+ break;
+ case 'id':
+ $this->loadFromId();
+ break;
+ case 'session':
+ $this->loadFromSession();
+ break;
+ default:
+ throw new MWException( "Unrecognised value for User->mFrom: \"{$this->mFrom}\"" );
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Load user table data given mId
+ * @return false if the ID does not exist, true otherwise
+ * @private
+ */
+ function loadFromId() {
+ global $wgMemc;
+ if ( $this->mId == 0 ) {
+ $this->loadDefaults();
+ return false;
+ }
+
+ # Try cache
+ $key = wfMemcKey( 'user', 'id', $this->mId );
+ $data = $wgMemc->get( $key );
+
+ if ( !is_array( $data ) || $data['mVersion'] < MW_USER_VERSION ) {
+ # Object is expired, load from DB
+ $data = false;
+ }
+
+ if ( !$data ) {
+ wfDebug( "Cache miss for user {$this->mId}\n" );
+ # Load from DB
+ if ( !$this->loadFromDatabase() ) {
+ # Can't load from ID, user is anonymous
+ return false;
+ }
+
+ # Save to cache
+ $data = array();
+ foreach ( self::$mCacheVars as $name ) {
+ $data[$name] = $this->$name;
+ }
+ $data['mVersion'] = MW_USER_VERSION;
+ $wgMemc->set( $key, $data );
+ } else {
+ wfDebug( "Got user {$this->mId} from cache\n" );
+ # Restore from cache
+ foreach ( self::$mCacheVars as $name ) {
+ $this->$name = $data[$name];
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Static factory method for creation from username.
+ *
+ * This is slightly less efficient than newFromId(), so use newFromId() if
+ * you have both an ID and a name handy.
+ *
+ * @param string $name Username, validated by Title:newFromText()
+ * @param mixed $validate Validate username. Takes the same parameters as
+ * User::getCanonicalName(), except that true is accepted as an alias
+ * for 'valid', for BC.
+ *
+ * @return User object, or null if the username is invalid. If the username
+ * is not present in the database, the result will be a user object with
+ * a name, zero user ID and default settings.
+ * @static
+ */
+ static function newFromName( $name, $validate = 'valid' ) {
+ if ( $validate === true ) {
+ $validate = 'valid';
+ }
+ $name = self::getCanonicalName( $name, $validate );
+ if ( $name === false ) {
+ return null;
+ } else {
+ # Create unloaded user object
+ $u = new User;
+ $u->mName = $name;
+ $u->mFrom = 'name';
+ return $u;
+ }
+ }
+
+ static function newFromId( $id ) {
+ $u = new User;
+ $u->mId = $id;
+ $u->mFrom = 'id';
+ return $u;
+ }
+
+ /**
+ * Factory method to fetch whichever user has a given email confirmation code.
+ * This code is generated when an account is created or its e-mail address
+ * has changed.
+ *
+ * If the code is invalid or has expired, returns NULL.
+ *
+ * @param string $code
+ * @return User
+ * @static
+ */
+ static function newFromConfirmationCode( $code ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $id = $dbr->selectField( 'user', 'user_id', array(
+ 'user_email_token' => md5( $code ),
+ 'user_email_token_expires > ' . $dbr->addQuotes( $dbr->timestamp() ),
+ ) );
+ if( $id !== false ) {
+ return User::newFromId( $id );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Create a new user object using data from session or cookies. If the
+ * login credentials are invalid, the result is an anonymous user.
+ *
+ * @return User
+ * @static
+ */
+ static function newFromSession() {
+ $user = new User;
+ $user->mFrom = 'session';
+ return $user;
+ }
+
+ /**
+ * Get username given an id.
+ * @param integer $id Database user id
+ * @return string Nickname of a user
+ * @static
+ */
+ static function whoIs( $id ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $dbr->selectField( 'user', 'user_name', array( 'user_id' => $id ), 'User::whoIs' );
+ }
+
+ /**
+ * Get real username given an id.
+ * @param integer $id Database user id
+ * @return string Realname of a user
+ * @static
+ */
+ static function whoIsReal( $id ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $dbr->selectField( 'user', 'user_real_name', array( 'user_id' => $id ), 'User::whoIsReal' );
+ }
+
+ /**
+ * Get database id given a user name
+ * @param string $name Nickname of a user
+ * @return integer|null Database user id (null: if non existent
+ * @static
+ */
+ static function idFromName( $name ) {
+ $nt = Title::newFromText( $name );
+ if( is_null( $nt ) ) {
+ # Illegal name
+ return null;
+ }
+ $dbr =& wfGetDB( DB_SLAVE );
+ $s = $dbr->selectRow( 'user', array( 'user_id' ), array( 'user_name' => $nt->getText() ), __METHOD__ );
+
+ if ( $s === false ) {
+ return 0;
+ } else {
+ return $s->user_id;
+ }
+ }
+
+ /**
+ * Does the string match an anonymous IPv4 address?
+ *
+ * This function exists for username validation, in order to reject
+ * usernames which are similar in form to IP addresses. Strings such
+ * as 300.300.300.300 will return true because it looks like an IP
+ * address, despite not being strictly valid.
+ *
+ * We match \d{1,3}\.\d{1,3}\.\d{1,3}\.xxx as an anonymous IP
+ * address because the usemod software would "cloak" anonymous IP
+ * addresses like this, if we allowed accounts like this to be created
+ * new users could get the old edits of these anonymous users.
+ *
+ * @bug 3631
+ *
+ * @static
+ * @param string $name Nickname of a user
+ * @return bool
+ */
+ static function isIP( $name ) {
+ return preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/',$name);
+ /*return preg_match("/^
+ (?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))\.
+ (?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))\.
+ (?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))\.
+ (?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))
+ $/x", $name);*/
+ }
+
+ /**
+ * Is the input a valid username?
+ *
+ * Checks if the input is a valid username, we don't want an empty string,
+ * an IP address, anything that containins slashes (would mess up subpages),
+ * is longer than the maximum allowed username size or doesn't begin with
+ * a capital letter.
+ *
+ * @param string $name
+ * @return bool
+ * @static
+ */
+ static function isValidUserName( $name ) {
+ global $wgContLang, $wgMaxNameChars;
+
+ if ( $name == ''
+ || User::isIP( $name )
+ || strpos( $name, '/' ) !== false
+ || strlen( $name ) > $wgMaxNameChars
+ || $name != $wgContLang->ucfirst( $name ) )
+ return false;
+
+ // Ensure that the name can't be misresolved as a different title,
+ // such as with extra namespace keys at the start.
+ $parsed = Title::newFromText( $name );
+ if( is_null( $parsed )
+ || $parsed->getNamespace()
+ || strcmp( $name, $parsed->getPrefixedText() ) )
+ return false;
+
+ // Check an additional blacklist of troublemaker characters.
+ // Should these be merged into the title char list?
+ $unicodeBlacklist = '/[' .
+ '\x{0080}-\x{009f}' . # iso-8859-1 control chars
+ '\x{00a0}' . # non-breaking space
+ '\x{2000}-\x{200f}' . # various whitespace
+ '\x{2028}-\x{202f}' . # breaks and control chars
+ '\x{3000}' . # ideographic space
+ '\x{e000}-\x{f8ff}' . # private use
+ ']/u';
+ if( preg_match( $unicodeBlacklist, $name ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Usernames which fail to pass this function will be blocked
+ * from user login and new account registrations, but may be used
+ * internally by batch processes.
+ *
+ * If an account already exists in this form, login will be blocked
+ * by a failure to pass this function.
+ *
+ * @param string $name
+ * @return bool
+ */
+ static function isUsableName( $name ) {
+ global $wgReservedUsernames;
+ return
+ // Must be a usable username, obviously ;)
+ self::isValidUserName( $name ) &&
+
+ // Certain names may be reserved for batch processes.
+ !in_array( $name, $wgReservedUsernames );
+ }
+
+ /**
+ * Usernames which fail to pass this function will be blocked
+ * from new account registrations, but may be used internally
+ * either by batch processes or by user accounts which have
+ * already been created.
+ *
+ * Additional character blacklisting may be added here
+ * rather than in isValidUserName() to avoid disrupting
+ * existing accounts.
+ *
+ * @param string $name
+ * @return bool
+ */
+ static function isCreatableName( $name ) {
+ return
+ self::isUsableName( $name ) &&
+
+ // Registration-time character blacklisting...
+ strpos( $name, '@' ) === false;
+ }
+
+ /**
+ * Is the input a valid password?
+ *
+ * @param string $password
+ * @return bool
+ * @static
+ */
+ static function isValidPassword( $password ) {
+ global $wgMinimalPasswordLength;
+ return strlen( $password ) >= $wgMinimalPasswordLength;
+ }
+
+ /**
+ * Does the string match roughly an email address ?
+ *
+ * There used to be a regular expression here, it got removed because it
+ * rejected valid addresses. Actually just check if there is '@' somewhere
+ * in the given address.
+ *
+ * @todo Check for RFC 2822 compilance
+ * @bug 959
+ *
+ * @param string $addr email address
+ * @static
+ * @return bool
+ */
+ static function isValidEmailAddr ( $addr ) {
+ return ( trim( $addr ) != '' ) &&
+ (false !== strpos( $addr, '@' ) );
+ }
+
+ /**
+ * Given unvalidated user input, return a canonical username, or false if
+ * the username is invalid.
+ * @param string $name
+ * @param mixed $validate Type of validation to use:
+ * false No validation
+ * 'valid' Valid for batch processes
+ * 'usable' Valid for batch processes and login
+ * 'creatable' Valid for batch processes, login and account creation
+ */
+ static function getCanonicalName( $name, $validate = 'valid' ) {
+ # Force usernames to capital
+ global $wgContLang;
+ $name = $wgContLang->ucfirst( $name );
+
+ # Clean up name according to title rules
+ $t = Title::newFromText( $name );
+ if( is_null( $t ) ) {
+ return false;
+ }
+
+ # Reject various classes of invalid names
+ $name = $t->getText();
+ global $wgAuth;
+ $name = $wgAuth->getCanonicalName( $t->getText() );
+
+ switch ( $validate ) {
+ case false:
+ break;
+ case 'valid':
+ if ( !User::isValidUserName( $name ) ) {
+ $name = false;
+ }
+ break;
+ case 'usable':
+ if ( !User::isUsableName( $name ) ) {
+ $name = false;
+ }
+ break;
+ case 'creatable':
+ if ( !User::isCreatableName( $name ) ) {
+ $name = false;
+ }
+ break;
+ default:
+ throw new MWException( 'Invalid parameter value for $validate in '.__METHOD__ );
+ }
+ return $name;
+ }
+
+ /**
+ * Count the number of edits of a user
+ *
+ * @param int $uid The user ID to check
+ * @return int
+ * @static
+ */
+ static function edits( $uid ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $dbr->selectField(
+ 'revision', 'count(*)',
+ array( 'rev_user' => $uid ),
+ __METHOD__
+ );
+ }
+
+ /**
+ * Return a random password. Sourced from mt_rand, so it's not particularly secure.
+ * @todo: hash random numbers to improve security, like generateToken()
+ *
+ * @return string
+ * @static
+ */
+ static function randomPassword() {
+ global $wgMinimalPasswordLength;
+ $pwchars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz';
+ $l = strlen( $pwchars ) - 1;
+
+ $pwlength = max( 7, $wgMinimalPasswordLength );
+ $digit = mt_rand(0, $pwlength - 1);
+ $np = '';
+ for ( $i = 0; $i < $pwlength; $i++ ) {
+ $np .= $i == $digit ? chr( mt_rand(48, 57) ) : $pwchars{ mt_rand(0, $l)};
+ }
+ return $np;
+ }
+
+ /**
+ * Set cached properties to default. Note: this no longer clears
+ * uncached lazy-initialised properties. The constructor does that instead.
+ *
+ * @private
+ */
+ function loadDefaults( $name = false ) {
+ wfProfileIn( __METHOD__ );
+
+ global $wgCookiePrefix;
+
+ $this->mId = 0;
+ $this->mName = $name;
+ $this->mRealName = '';
+ $this->mPassword = $this->mNewpassword = '';
+ $this->mNewpassTime = null;
+ $this->mEmail = '';
+ $this->mOptions = null; # Defer init
+
+ if ( isset( $_COOKIE[$wgCookiePrefix.'LoggedOut'] ) ) {
+ $this->mTouched = wfTimestamp( TS_MW, $_COOKIE[$wgCookiePrefix.'LoggedOut'] );
+ } else {
+ $this->mTouched = '0'; # Allow any pages to be cached
+ }
+
+ $this->setToken(); # Random
+ $this->mEmailAuthenticated = null;
+ $this->mEmailToken = '';
+ $this->mEmailTokenExpires = null;
+ $this->mRegistration = wfTimestamp( TS_MW );
+ $this->mGroups = array();
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Initialise php session
+ * @deprecated use wfSetupSession()
+ */
+ function SetupSession() {
+ wfSetupSession();
+ }
+
+ /**
+ * Load user data from the session or login cookie. If there are no valid
+ * credentials, initialises the user as an anon.
+ * @return true if the user is logged in, false otherwise
+ *
+ * @private
+ */
+ function loadFromSession() {
+ global $wgMemc, $wgCookiePrefix;
+
+ if ( isset( $_SESSION['wsUserID'] ) ) {
+ if ( 0 != $_SESSION['wsUserID'] ) {
+ $sId = $_SESSION['wsUserID'];
+ } else {
+ $this->loadDefaults();
+ return false;
+ }
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}UserID"] ) ) {
+ $sId = intval( $_COOKIE["{$wgCookiePrefix}UserID"] );
+ $_SESSION['wsUserID'] = $sId;
+ } else {
+ $this->loadDefaults();
+ return false;
+ }
+ if ( isset( $_SESSION['wsUserName'] ) ) {
+ $sName = $_SESSION['wsUserName'];
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}UserName"] ) ) {
+ $sName = $_COOKIE["{$wgCookiePrefix}UserName"];
+ $_SESSION['wsUserName'] = $sName;
+ } else {
+ $this->loadDefaults();
+ return false;
+ }
+
+ $passwordCorrect = FALSE;
+ $this->mId = $sId;
+ if ( !$this->loadFromId() ) {
+ # Not a valid ID, loadFromId has switched the object to anon for us
+ return false;
+ }
+
+ if ( isset( $_SESSION['wsToken'] ) ) {
+ $passwordCorrect = $_SESSION['wsToken'] == $this->mToken;
+ $from = 'session';
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}Token"] ) ) {
+ $passwordCorrect = $this->mToken == $_COOKIE["{$wgCookiePrefix}Token"];
+ $from = 'cookie';
+ } else {
+ # No session or persistent login cookie
+ $this->loadDefaults();
+ return false;
+ }
+
+ if ( ( $sName == $this->mName ) && $passwordCorrect ) {
+ wfDebug( "Logged in from $from\n" );
+ return true;
+ } else {
+ # Invalid credentials
+ wfDebug( "Can't log in from $from, invalid credentials\n" );
+ $this->loadDefaults();
+ return false;
+ }
+ }
+
+ /**
+ * Load user and user_group data from the database
+ * $this->mId must be set, this is how the user is identified.
+ *
+ * @return true if the user exists, false if the user is anonymous
+ * @private
+ */
+ function loadFromDatabase() {
+ # Paranoia
+ $this->mId = intval( $this->mId );
+
+ /** Anonymous user */
+ if( !$this->mId ) {
+ $this->loadDefaults();
+ return false;
+ }
+
+ $dbr =& wfGetDB( DB_MASTER );
+ $s = $dbr->selectRow( 'user', '*', array( 'user_id' => $this->mId ), __METHOD__ );
+
+ if ( $s !== false ) {
+ # Initialise user table data
+ $this->mName = $s->user_name;
+ $this->mRealName = $s->user_real_name;
+ $this->mPassword = $s->user_password;
+ $this->mNewpassword = $s->user_newpassword;
+ $this->mNewpassTime = wfTimestampOrNull( TS_MW, $s->user_newpass_time );
+ $this->mEmail = $s->user_email;
+ $this->decodeOptions( $s->user_options );
+ $this->mTouched = wfTimestamp(TS_MW,$s->user_touched);
+ $this->mToken = $s->user_token;
+ $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $s->user_email_authenticated );
+ $this->mEmailToken = $s->user_email_token;
+ $this->mEmailTokenExpires = wfTimestampOrNull( TS_MW, $s->user_email_token_expires );
+ $this->mRegistration = wfTimestampOrNull( TS_MW, $s->user_registration );
+
+ # Load group data
+ $res = $dbr->select( 'user_groups',
+ array( 'ug_group' ),
+ array( 'ug_user' => $this->mId ),
+ __METHOD__ );
+ $this->mGroups = array();
+ while( $row = $dbr->fetchObject( $res ) ) {
+ $this->mGroups[] = $row->ug_group;
+ }
+ return true;
+ } else {
+ # Invalid user_id
+ $this->mId = 0;
+ $this->loadDefaults();
+ return false;
+ }
+ }
+
+ /**
+ * Clear various cached data stored in this object.
+ * @param string $reloadFrom Reload user and user_groups table data from a
+ * given source. May be "name", "id", "defaults", "session" or false for
+ * no reload.
+ */
+ function clearInstanceCache( $reloadFrom = false ) {
+ $this->mNewtalk = -1;
+ $this->mDatePreference = null;
+ $this->mBlockedby = -1; # Unset
+ $this->mHash = false;
+ $this->mSkin = null;
+ $this->mRights = null;
+ $this->mEffectiveGroups = null;
+
+ if ( $reloadFrom ) {
+ $this->mDataLoaded = false;
+ $this->mFrom = $reloadFrom;
+ }
+ }
+
+ /**
+ * Combine the language default options with any site-specific options
+ * and add the default language variants.
+ * Not really private cause it's called by Language class
+ * @return array
+ * @static
+ * @private
+ */
+ static function getDefaultOptions() {
+ global $wgNamespacesToBeSearchedDefault;
+ /**
+ * Site defaults will override the global/language defaults
+ */
+ global $wgDefaultUserOptions, $wgContLang;
+ $defOpt = $wgDefaultUserOptions + $wgContLang->getDefaultUserOptionOverrides();
+
+ /**
+ * default language setting
+ */
+ $variant = $wgContLang->getPreferredVariant( false );
+ $defOpt['variant'] = $variant;
+ $defOpt['language'] = $variant;
+
+ foreach( $wgNamespacesToBeSearchedDefault as $nsnum => $val ) {
+ $defOpt['searchNs'.$nsnum] = $val;
+ }
+ return $defOpt;
+ }
+
+ /**
+ * Get a given default option value.
+ *
+ * @param string $opt
+ * @return string
+ * @static
+ * @public
+ */
+ function getDefaultOption( $opt ) {
+ $defOpts = User::getDefaultOptions();
+ if( isset( $defOpts[$opt] ) ) {
+ return $defOpts[$opt];
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Get a list of user toggle names
+ * @return array
+ */
+ static function getToggles() {
+ global $wgContLang;
+ $extraToggles = array();
+ wfRunHooks( 'UserToggles', array( &$extraToggles ) );
+ return array_merge( self::$mToggles, $extraToggles, $wgContLang->getExtraUserToggles() );
+ }
+
+
+ /**
+ * Get blocking information
+ * @private
+ * @param bool $bFromSlave Specify whether to check slave or master. To improve performance,
+ * non-critical checks are done against slaves. Check when actually saving should be done against
+ * master.
+ */
+ function getBlockedStatus( $bFromSlave = true ) {
+ global $wgEnableSorbs, $wgProxyWhitelist;
+
+ if ( -1 != $this->mBlockedby ) {
+ wfDebug( "User::getBlockedStatus: already loaded.\n" );
+ return;
+ }
+
+ wfProfileIn( __METHOD__ );
+ wfDebug( __METHOD__.": checking...\n" );
+
+ $this->mBlockedby = 0;
+ $ip = wfGetIP();
+
+ if ($this->isAllowed( 'ipblock-exempt' ) ) {
+ # Exempt from all types of IP-block
+ $ip = '';
+ }
+
+ # User/IP blocking
+ $this->mBlock = new Block();
+ $this->mBlock->fromMaster( !$bFromSlave );
+ if ( $this->mBlock->load( $ip , $this->mId ) ) {
+ wfDebug( __METHOD__.": Found block.\n" );
+ $this->mBlockedby = $this->mBlock->mBy;
+ $this->mBlockreason = $this->mBlock->mReason;
+ if ( $this->isLoggedIn() ) {
+ $this->spreadBlock();
+ }
+ } else {
+ $this->mBlock = null;
+ wfDebug( __METHOD__.": No block.\n" );
+ }
+
+ # Proxy blocking
+ if ( !$this->isAllowed('proxyunbannable') && !in_array( $ip, $wgProxyWhitelist ) ) {
+
+ # Local list
+ if ( wfIsLocallyBlockedProxy( $ip ) ) {
+ $this->mBlockedby = wfMsg( 'proxyblocker' );
+ $this->mBlockreason = wfMsg( 'proxyblockreason' );
+ }
+
+ # DNSBL
+ if ( !$this->mBlockedby && $wgEnableSorbs && !$this->getID() ) {
+ if ( $this->inSorbsBlacklist( $ip ) ) {
+ $this->mBlockedby = wfMsg( 'sorbs' );
+ $this->mBlockreason = wfMsg( 'sorbsreason' );
+ }
+ }
+ }
+
+ # Extensions
+ wfRunHooks( 'GetBlockedStatus', array( &$this ) );
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ function inSorbsBlacklist( $ip ) {
+ global $wgEnableSorbs, $wgSorbsUrl;
+
+ return $wgEnableSorbs &&
+ $this->inDnsBlacklist( $ip, $wgSorbsUrl );
+ }
+
+ function inDnsBlacklist( $ip, $base ) {
+ wfProfileIn( __METHOD__ );
+
+ $found = false;
+ $host = '';
+
+ $m = array();
+ if ( preg_match( '/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip, $m ) ) {
+ # Make hostname
+ for ( $i=4; $i>=1; $i-- ) {
+ $host .= $m[$i] . '.';
+ }
+ $host .= $base;
+
+ # Send query
+ $ipList = gethostbynamel( $host );
+
+ if ( $ipList ) {
+ wfDebug( "Hostname $host is {$ipList[0]}, it's a proxy says $base!\n" );
+ $found = true;
+ } else {
+ wfDebug( "Requested $host, not found in $base.\n" );
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $found;
+ }
+
+ /**
+ * Primitive rate limits: enforce maximum actions per time period
+ * to put a brake on flooding.
+ *
+ * Note: when using a shared cache like memcached, IP-address
+ * last-hit counters will be shared across wikis.
+ *
+ * @return bool true if a rate limiter was tripped
+ * @public
+ */
+ function pingLimiter( $action='edit' ) {
+
+ # Call the 'PingLimiter' hook
+ $result = false;
+ if( !wfRunHooks( 'PingLimiter', array( &$this, $action, $result ) ) ) {
+ return $result;
+ }
+
+ global $wgRateLimits, $wgRateLimitsExcludedGroups;
+ if( !isset( $wgRateLimits[$action] ) ) {
+ return false;
+ }
+
+ # Some groups shouldn't trigger the ping limiter, ever
+ foreach( $this->getGroups() as $group ) {
+ if( array_search( $group, $wgRateLimitsExcludedGroups ) !== false )
+ return false;
+ }
+
+ global $wgMemc, $wgRateLimitLog;
+ wfProfileIn( __METHOD__ );
+
+ $limits = $wgRateLimits[$action];
+ $keys = array();
+ $id = $this->getId();
+ $ip = wfGetIP();
+
+ if( isset( $limits['anon'] ) && $id == 0 ) {
+ $keys[wfMemcKey( 'limiter', $action, 'anon' )] = $limits['anon'];
+ }
+
+ if( isset( $limits['user'] ) && $id != 0 ) {
+ $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $limits['user'];
+ }
+ if( $this->isNewbie() ) {
+ if( isset( $limits['newbie'] ) && $id != 0 ) {
+ $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $limits['newbie'];
+ }
+ if( isset( $limits['ip'] ) ) {
+ $keys["mediawiki:limiter:$action:ip:$ip"] = $limits['ip'];
+ }
+ $matches = array();
+ if( isset( $limits['subnet'] ) && preg_match( '/^(\d+\.\d+\.\d+)\.\d+$/', $ip, $matches ) ) {
+ $subnet = $matches[1];
+ $keys["mediawiki:limiter:$action:subnet:$subnet"] = $limits['subnet'];
+ }
+ }
+
+ $triggered = false;
+ foreach( $keys as $key => $limit ) {
+ list( $max, $period ) = $limit;
+ $summary = "(limit $max in {$period}s)";
+ $count = $wgMemc->get( $key );
+ if( $count ) {
+ if( $count > $max ) {
+ wfDebug( __METHOD__.": tripped! $key at $count $summary\n" );
+ if( $wgRateLimitLog ) {
+ @error_log( wfTimestamp( TS_MW ) . ' ' . wfWikiID() . ': ' . $this->getName() . " tripped $key at $count $summary\n", 3, $wgRateLimitLog );
+ }
+ $triggered = true;
+ } else {
+ wfDebug( __METHOD__.": ok. $key at $count $summary\n" );
+ }
+ } else {
+ wfDebug( __METHOD__.": adding record for $key $summary\n" );
+ $wgMemc->add( $key, 1, intval( $period ) );
+ }
+ $wgMemc->incr( $key );
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $triggered;
+ }
+
+ /**
+ * Check if user is blocked
+ * @return bool True if blocked, false otherwise
+ */
+ function isBlocked( $bFromSlave = true ) { // hacked from false due to horrible probs on site
+ wfDebug( "User::isBlocked: enter\n" );
+ $this->getBlockedStatus( $bFromSlave );
+ return $this->mBlockedby !== 0;
+ }
+
+ /**
+ * Check if user is blocked from editing a particular article
+ */
+ function isBlockedFrom( $title, $bFromSlave = false ) {
+ global $wgBlockAllowsUTEdit;
+ wfProfileIn( __METHOD__ );
+ wfDebug( __METHOD__.": enter\n" );
+
+ if ( $wgBlockAllowsUTEdit && $title->getText() === $this->getName() &&
+ $title->getNamespace() == NS_USER_TALK )
+ {
+ $blocked = false;
+ wfDebug( __METHOD__.": self-talk page, ignoring any blocks\n" );
+ } else {
+ wfDebug( __METHOD__.": asking isBlocked()\n" );
+ $blocked = $this->isBlocked( $bFromSlave );
+ }
+ wfProfileOut( __METHOD__ );
+ return $blocked;
+ }
+
+ /**
+ * Get name of blocker
+ * @return string name of blocker
+ */
+ function blockedBy() {
+ $this->getBlockedStatus();
+ return $this->mBlockedby;
+ }
+
+ /**
+ * Get blocking reason
+ * @return string Blocking reason
+ */
+ function blockedFor() {
+ $this->getBlockedStatus();
+ return $this->mBlockreason;
+ }
+
+ /**
+ * Get the user ID. Returns 0 if the user is anonymous or nonexistent.
+ */
+ function getID() {
+ $this->load();
+ return $this->mId;
+ }
+
+ /**
+ * Set the user and reload all fields according to that ID
+ * @deprecated use User::newFromId()
+ */
+ function setID( $v ) {
+ $this->mId = $v;
+ $this->clearInstanceCache( 'id' );
+ }
+
+ /**
+ * Get the user name, or the IP for anons
+ */
+ function getName() {
+ if ( !$this->mDataLoaded && $this->mFrom == 'name' ) {
+ # Special case optimisation
+ return $this->mName;
+ } else {
+ $this->load();
+ if ( $this->mName === false ) {
+ $this->mName = wfGetIP();
+ }
+ return $this->mName;
+ }
+ }
+
+ /**
+ * Set the user name.
+ *
+ * This does not reload fields from the database according to the given
+ * name. Rather, it is used to create a temporary "nonexistent user" for
+ * later addition to the database. It can also be used to set the IP
+ * address for an anonymous user to something other than the current
+ * remote IP.
+ *
+ * User::newFromName() has rougly the same function, when the named user
+ * does not exist.
+ */
+ function setName( $str ) {
+ $this->load();
+ $this->mName = $str;
+ }
+
+ /**
+ * Return the title dbkey form of the name, for eg user pages.
+ * @return string
+ * @public
+ */
+ function getTitleKey() {
+ return str_replace( ' ', '_', $this->getName() );
+ }
+
+ function getNewtalk() {
+ $this->load();
+
+ # Load the newtalk status if it is unloaded (mNewtalk=-1)
+ if( $this->mNewtalk === -1 ) {
+ $this->mNewtalk = false; # reset talk page status
+
+ # Check memcached separately for anons, who have no
+ # entire User object stored in there.
+ if( !$this->mId ) {
+ global $wgMemc;
+ $key = wfMemcKey( 'newtalk', 'ip', $this->getName() );
+ $newtalk = $wgMemc->get( $key );
+ if( is_integer( $newtalk ) ) {
+ $this->mNewtalk = (bool)$newtalk;
+ } else {
+ $this->mNewtalk = $this->checkNewtalk( 'user_ip', $this->getName() );
+ $wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 );
+ }
+ } else {
+ $this->mNewtalk = $this->checkNewtalk( 'user_id', $this->mId );
+ }
+ }
+
+ return (bool)$this->mNewtalk;
+ }
+
+ /**
+ * Return the talk page(s) this user has new messages on.
+ */
+ function getNewMessageLinks() {
+ $talks = array();
+ if (!wfRunHooks('UserRetrieveNewTalks', array(&$this, &$talks)))
+ return $talks;
+
+ if (!$this->getNewtalk())
+ return array();
+ $up = $this->getUserPage();
+ $utp = $up->getTalkPage();
+ return array(array("wiki" => wfWikiID(), "link" => $utp->getLocalURL()));
+ }
+
+
+ /**
+ * Perform a user_newtalk check on current slaves; if the memcached data
+ * is funky we don't want newtalk state to get stuck on save, as that's
+ * damn annoying.
+ *
+ * @param string $field
+ * @param mixed $id
+ * @return bool
+ * @private
+ */
+ function checkNewtalk( $field, $id ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $ok = $dbr->selectField( 'user_newtalk', $field,
+ array( $field => $id ), __METHOD__ );
+ return $ok !== false;
+ }
+
+ /**
+ * Add or update the
+ * @param string $field
+ * @param mixed $id
+ * @private
+ */
+ function updateNewtalk( $field, $id ) {
+ if( $this->checkNewtalk( $field, $id ) ) {
+ wfDebug( __METHOD__." already set ($field, $id), ignoring\n" );
+ return false;
+ }
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->insert( 'user_newtalk',
+ array( $field => $id ),
+ __METHOD__,
+ 'IGNORE' );
+ wfDebug( __METHOD__.": set on ($field, $id)\n" );
+ return true;
+ }
+
+ /**
+ * Clear the new messages flag for the given user
+ * @param string $field
+ * @param mixed $id
+ * @private
+ */
+ function deleteNewtalk( $field, $id ) {
+ if( !$this->checkNewtalk( $field, $id ) ) {
+ wfDebug( __METHOD__.": already gone ($field, $id), ignoring\n" );
+ return false;
+ }
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'user_newtalk',
+ array( $field => $id ),
+ __METHOD__ );
+ wfDebug( __METHOD__.": killed on ($field, $id)\n" );
+ return true;
+ }
+
+ /**
+ * Update the 'You have new messages!' status.
+ * @param bool $val
+ */
+ function setNewtalk( $val ) {
+ if( wfReadOnly() ) {
+ return;
+ }
+
+ $this->load();
+ $this->mNewtalk = $val;
+
+ if( $this->isAnon() ) {
+ $field = 'user_ip';
+ $id = $this->getName();
+ } else {
+ $field = 'user_id';
+ $id = $this->getId();
+ }
+
+ if( $val ) {
+ $changed = $this->updateNewtalk( $field, $id );
+ } else {
+ $changed = $this->deleteNewtalk( $field, $id );
+ }
+
+ if( $changed ) {
+ if( $this->isAnon() ) {
+ // Anons have a separate memcached space, since
+ // user records aren't kept for them.
+ global $wgMemc;
+ $key = wfMemcKey( 'newtalk', 'ip', $val );
+ $wgMemc->set( $key, $val ? 1 : 0 );
+ } else {
+ if( $val ) {
+ // Make sure the user page is watched, so a notification
+ // will be sent out if enabled.
+ $this->addWatch( $this->getTalkPage() );
+ }
+ }
+ $this->invalidateCache();
+ }
+ }
+
+ /**
+ * Generate a current or new-future timestamp to be stored in the
+ * user_touched field when we update things.
+ */
+ private static function newTouchedTimestamp() {
+ global $wgClockSkewFudge;
+ return wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
+ }
+
+ /**
+ * Clear user data from memcached.
+ * Use after applying fun updates to the database; caller's
+ * responsibility to update user_touched if appropriate.
+ *
+ * Called implicitly from invalidateCache() and saveSettings().
+ */
+ private function clearSharedCache() {
+ if( $this->mId ) {
+ global $wgMemc;
+ $wgMemc->delete( wfMemcKey( 'user', 'id', $this->mId ) );
+ }
+ }
+
+ /**
+ * Immediately touch the user data cache for this account.
+ * Updates user_touched field, and removes account data from memcached
+ * for reload on the next hit.
+ */
+ function invalidateCache() {
+ $this->load();
+ if( $this->mId ) {
+ $this->mTouched = self::newTouchedTimestamp();
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'user',
+ array( 'user_touched' => $dbw->timestamp( $this->mTouched ) ),
+ array( 'user_id' => $this->mId ),
+ __METHOD__ );
+
+ $this->clearSharedCache();
+ }
+ }
+
+ function validateCache( $timestamp ) {
+ $this->load();
+ return ($timestamp >= $this->mTouched);
+ }
+
+ /**
+ * Encrypt a password.
+ * It can eventuall salt a password @see User::addSalt()
+ * @param string $p clear Password.
+ * @return string Encrypted password.
+ */
+ function encryptPassword( $p ) {
+ $this->load();
+ return wfEncryptPassword( $this->mId, $p );
+ }
+
+ /**
+ * Set the password and reset the random token
+ * Calls through to authentication plugin if necessary;
+ * will have no effect if the auth plugin refuses to
+ * pass the change through or if the legal password
+ * checks fail.
+ *
+ * As a special case, setting the password to null
+ * wipes it, so the account cannot be logged in until
+ * a new password is set, for instance via e-mail.
+ *
+ * @param string $str
+ * @throws PasswordError on failure
+ */
+ function setPassword( $str ) {
+ global $wgAuth;
+
+ if( $str !== null ) {
+ if( !$wgAuth->allowPasswordChange() ) {
+ throw new PasswordError( wfMsg( 'password-change-forbidden' ) );
+ }
+
+ if( !$this->isValidPassword( $str ) ) {
+ global $wgMinimalPasswordLength;
+ throw new PasswordError( wfMsg( 'passwordtooshort',
+ $wgMinimalPasswordLength ) );
+ }
+ }
+
+ if( !$wgAuth->setPassword( $this, $str ) ) {
+ throw new PasswordError( wfMsg( 'externaldberror' ) );
+ }
+
+ $this->load();
+ $this->setToken();
+
+ if( $str === null ) {
+ // Save an invalid hash...
+ $this->mPassword = '';
+ } else {
+ $this->mPassword = $this->encryptPassword( $str );
+ }
+ $this->mNewpassword = '';
+ $this->mNewpassTime = null;
+
+ return true;
+ }
+
+ /**
+ * Set the random token (used for persistent authentication)
+ * Called from loadDefaults() among other places.
+ * @private
+ */
+ function setToken( $token = false ) {
+ global $wgSecretKey, $wgProxyKey;
+ $this->load();
+ if ( !$token ) {
+ if ( $wgSecretKey ) {
+ $key = $wgSecretKey;
+ } elseif ( $wgProxyKey ) {
+ $key = $wgProxyKey;
+ } else {
+ $key = microtime();
+ }
+ $this->mToken = md5( $key . mt_rand( 0, 0x7fffffff ) . wfWikiID() . $this->mId );
+ } else {
+ $this->mToken = $token;
+ }
+ }
+
+ function setCookiePassword( $str ) {
+ $this->load();
+ $this->mCookiePassword = md5( $str );
+ }
+
+ /**
+ * Set the password for a password reminder or new account email
+ * Sets the user_newpass_time field if $throttle is true
+ */
+ function setNewpassword( $str, $throttle = true ) {
+ $this->load();
+ $this->mNewpassword = $this->encryptPassword( $str );
+ if ( $throttle ) {
+ $this->mNewpassTime = wfTimestampNow();
+ }
+ }
+
+ /**
+ * Returns true if a password reminder email has already been sent within
+ * the last $wgPasswordReminderResendTime hours
+ */
+ function isPasswordReminderThrottled() {
+ global $wgPasswordReminderResendTime;
+ $this->load();
+ if ( !$this->mNewpassTime || !$wgPasswordReminderResendTime ) {
+ return false;
+ }
+ $expiry = wfTimestamp( TS_UNIX, $this->mNewpassTime ) + $wgPasswordReminderResendTime * 3600;
+ return time() < $expiry;
+ }
+
+ function getEmail() {
+ $this->load();
+ return $this->mEmail;
+ }
+
+ function getEmailAuthenticationTimestamp() {
+ $this->load();
+ return $this->mEmailAuthenticated;
+ }
+
+ function setEmail( $str ) {
+ $this->load();
+ $this->mEmail = $str;
+ }
+
+ function getRealName() {
+ $this->load();
+ return $this->mRealName;
+ }
+
+ function setRealName( $str ) {
+ $this->load();
+ $this->mRealName = $str;
+ }
+
+ /**
+ * @param string $oname The option to check
+ * @param string $defaultOverride A default value returned if the option does not exist
+ * @return string
+ */
+ function getOption( $oname, $defaultOverride = '' ) {
+ $this->load();
+
+ if ( is_null( $this->mOptions ) ) {
+ if($defaultOverride != '') {
+ return $defaultOverride;
+ }
+ $this->mOptions = User::getDefaultOptions();
+ }
+
+ if ( array_key_exists( $oname, $this->mOptions ) ) {
+ return trim( $this->mOptions[$oname] );
+ } else {
+ return $defaultOverride;
+ }
+ }
+
+ /**
+ * Get the user's date preference, including some important migration for
+ * old user rows.
+ */
+ function getDatePreference() {
+ if ( is_null( $this->mDatePreference ) ) {
+ global $wgLang;
+ $value = $this->getOption( 'date' );
+ $map = $wgLang->getDatePreferenceMigrationMap();
+ if ( isset( $map[$value] ) ) {
+ $value = $map[$value];
+ }
+ $this->mDatePreference = $value;
+ }
+ return $this->mDatePreference;
+ }
+
+ /**
+ * @param string $oname The option to check
+ * @return bool False if the option is not selected, true if it is
+ */
+ function getBoolOption( $oname ) {
+ return (bool)$this->getOption( $oname );
+ }
+
+ /**
+ * Get an option as an integer value from the source string.
+ * @param string $oname The option to check
+ * @param int $default Optional value to return if option is unset/blank.
+ * @return int
+ */
+ function getIntOption( $oname, $default=0 ) {
+ $val = $this->getOption( $oname );
+ if( $val == '' ) {
+ $val = $default;
+ }
+ return intval( $val );
+ }
+
+ function setOption( $oname, $val ) {
+ $this->load();
+ if ( is_null( $this->mOptions ) ) {
+ $this->mOptions = User::getDefaultOptions();
+ }
+ if ( $oname == 'skin' ) {
+ # Clear cached skin, so the new one displays immediately in Special:Preferences
+ unset( $this->mSkin );
+ }
+ // Filter out any newlines that may have passed through input validation.
+ // Newlines are used to separate items in the options blob.
+ $val = str_replace( "\r\n", "\n", $val );
+ $val = str_replace( "\r", "\n", $val );
+ $val = str_replace( "\n", " ", $val );
+ $this->mOptions[$oname] = $val;
+ }
+
+ function getRights() {
+ if ( is_null( $this->mRights ) ) {
+ $this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() );
+ }
+ return $this->mRights;
+ }
+
+ /**
+ * Get the list of explicit group memberships this user has.
+ * The implicit * and user groups are not included.
+ * @return array of strings
+ */
+ function getGroups() {
+ $this->load();
+ return $this->mGroups;
+ }
+
+ /**
+ * Get the list of implicit group memberships this user has.
+ * This includes all explicit groups, plus 'user' if logged in
+ * and '*' for all accounts.
+ * @param boolean $recache Don't use the cache
+ * @return array of strings
+ */
+ function getEffectiveGroups( $recache = false ) {
+ if ( $recache || is_null( $this->mEffectiveGroups ) ) {
+ $this->load();
+ $this->mEffectiveGroups = $this->mGroups;
+ $this->mEffectiveGroups[] = '*';
+ if( $this->mId ) {
+ $this->mEffectiveGroups[] = 'user';
+
+ global $wgAutoConfirmAge;
+ $accountAge = time() - wfTimestampOrNull( TS_UNIX, $this->mRegistration );
+ if( $accountAge >= $wgAutoConfirmAge ) {
+ $this->mEffectiveGroups[] = 'autoconfirmed';
+ }
+
+ # Implicit group for users whose email addresses are confirmed
+ global $wgEmailAuthentication;
+ if( self::isValidEmailAddr( $this->mEmail ) ) {
+ if( $wgEmailAuthentication ) {
+ if( $this->mEmailAuthenticated )
+ $this->mEffectiveGroups[] = 'emailconfirmed';
+ } else {
+ $this->mEffectiveGroups[] = 'emailconfirmed';
+ }
+ }
+ }
+ }
+ return $this->mEffectiveGroups;
+ }
+
+ /**
+ * Add the user to the given group.
+ * This takes immediate effect.
+ * @string $group
+ */
+ function addGroup( $group ) {
+ $this->load();
+ $dbw =& wfGetDB( DB_MASTER );
+ if( $this->getId() ) {
+ $dbw->insert( 'user_groups',
+ array(
+ 'ug_user' => $this->getID(),
+ 'ug_group' => $group,
+ ),
+ 'User::addGroup',
+ array( 'IGNORE' ) );
+ }
+
+ $this->mGroups[] = $group;
+ $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups( true ) );
+
+ $this->invalidateCache();
+ }
+
+ /**
+ * Remove the user from the given group.
+ * This takes immediate effect.
+ * @string $group
+ */
+ function removeGroup( $group ) {
+ $this->load();
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'user_groups',
+ array(
+ 'ug_user' => $this->getID(),
+ 'ug_group' => $group,
+ ),
+ 'User::removeGroup' );
+
+ $this->mGroups = array_diff( $this->mGroups, array( $group ) );
+ $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups( true ) );
+
+ $this->invalidateCache();
+ }
+
+
+ /**
+ * A more legible check for non-anonymousness.
+ * Returns true if the user is not an anonymous visitor.
+ *
+ * @return bool
+ */
+ function isLoggedIn() {
+ return( $this->getID() != 0 );
+ }
+
+ /**
+ * A more legible check for anonymousness.
+ * Returns true if the user is an anonymous visitor.
+ *
+ * @return bool
+ */
+ function isAnon() {
+ return !$this->isLoggedIn();
+ }
+
+ /**
+ * Whether the user is a bot
+ * @deprecated
+ */
+ function isBot() {
+ return $this->isAllowed( 'bot' );
+ }
+
+ /**
+ * Check if user is allowed to access a feature / make an action
+ * @param string $action Action to be checked
+ * @return boolean True: action is allowed, False: action should not be allowed
+ */
+ function isAllowed($action='') {
+ if ( $action === '' )
+ // In the spirit of DWIM
+ return true;
+
+ return in_array( $action, $this->getRights() );
+ }
+
+ /**
+ * Load a skin if it doesn't exist or return it
+ * @todo FIXME : need to check the old failback system [AV]
+ */
+ function &getSkin() {
+ global $wgRequest;
+ if ( ! isset( $this->mSkin ) ) {
+ wfProfileIn( __METHOD__ );
+
+ # get the user skin
+ $userSkin = $this->getOption( 'skin' );
+ $userSkin = $wgRequest->getVal('useskin', $userSkin);
+
+ $this->mSkin =& Skin::newFromKey( $userSkin );
+ wfProfileOut( __METHOD__ );
+ }
+ return $this->mSkin;
+ }
+
+ /**#@+
+ * @param string $title Article title to look at
+ */
+
+ /**
+ * Check watched status of an article
+ * @return bool True if article is watched
+ */
+ function isWatched( $title ) {
+ $wl = WatchedItem::fromUserTitle( $this, $title );
+ return $wl->isWatched();
+ }
+
+ /**
+ * Watch an article
+ */
+ function addWatch( $title ) {
+ $wl = WatchedItem::fromUserTitle( $this, $title );
+ $wl->addWatch();
+ $this->invalidateCache();
+ }
+
+ /**
+ * Stop watching an article
+ */
+ function removeWatch( $title ) {
+ $wl = WatchedItem::fromUserTitle( $this, $title );
+ $wl->removeWatch();
+ $this->invalidateCache();
+ }
+
+ /**
+ * Clear the user's notification timestamp for the given title.
+ * If e-notif e-mails are on, they will receive notification mails on
+ * the next change of the page if it's watched etc.
+ */
+ function clearNotification( &$title ) {
+ global $wgUser, $wgUseEnotif;
+
+ # Do nothing if the database is locked to writes
+ if( wfReadOnly() ) {
+ return;
+ }
+
+ if ($title->getNamespace() == NS_USER_TALK &&
+ $title->getText() == $this->getName() ) {
+ if (!wfRunHooks('UserClearNewTalkNotification', array(&$this)))
+ return;
+ $this->setNewtalk( false );
+ }
+
+ if( !$wgUseEnotif ) {
+ return;
+ }
+
+ if( $this->isAnon() ) {
+ // Nothing else to do...
+ return;
+ }
+
+ // Only update the timestamp if the page is being watched.
+ // The query to find out if it is watched is cached both in memcached and per-invocation,
+ // and when it does have to be executed, it can be on a slave
+ // If this is the user's newtalk page, we always update the timestamp
+ if ($title->getNamespace() == NS_USER_TALK &&
+ $title->getText() == $wgUser->getName())
+ {
+ $watched = true;
+ } elseif ( $this->getID() == $wgUser->getID() ) {
+ $watched = $title->userIsWatching();
+ } else {
+ $watched = true;
+ }
+
+ // If the page is watched by the user (or may be watched), update the timestamp on any
+ // any matching rows
+ if ( $watched ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'watchlist',
+ array( /* SET */
+ 'wl_notificationtimestamp' => NULL
+ ), array( /* WHERE */
+ 'wl_title' => $title->getDBkey(),
+ 'wl_namespace' => $title->getNamespace(),
+ 'wl_user' => $this->getID()
+ ), 'User::clearLastVisited'
+ );
+ }
+ }
+
+ /**#@-*/
+
+ /**
+ * Resets all of the given user's page-change notification timestamps.
+ * If e-notif e-mails are on, they will receive notification mails on
+ * the next change of any watched page.
+ *
+ * @param int $currentUser user ID number
+ * @public
+ */
+ function clearAllNotifications( $currentUser ) {
+ global $wgUseEnotif;
+ if ( !$wgUseEnotif ) {
+ $this->setNewtalk( false );
+ return;
+ }
+ if( $currentUser != 0 ) {
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'watchlist',
+ array( /* SET */
+ 'wl_notificationtimestamp' => NULL
+ ), array( /* WHERE */
+ 'wl_user' => $currentUser
+ ), 'UserMailer::clearAll'
+ );
+
+ # we also need to clear here the "you have new message" notification for the own user_talk page
+ # This is cleared one page view later in Article::viewUpdates();
+ }
+ }
+
+ /**
+ * @private
+ * @return string Encoding options
+ */
+ function encodeOptions() {
+ $this->load();
+ if ( is_null( $this->mOptions ) ) {
+ $this->mOptions = User::getDefaultOptions();
+ }
+ $a = array();
+ foreach ( $this->mOptions as $oname => $oval ) {
+ array_push( $a, $oname.'='.$oval );
+ }
+ $s = implode( "\n", $a );
+ return $s;
+ }
+
+ /**
+ * @private
+ */
+ function decodeOptions( $str ) {
+ $this->mOptions = array();
+ $a = explode( "\n", $str );
+ foreach ( $a as $s ) {
+ $m = array();
+ if ( preg_match( "/^(.[^=]*)=(.*)$/", $s, $m ) ) {
+ $this->mOptions[$m[1]] = $m[2];
+ }
+ }
+ }
+
+ function setCookies() {
+ global $wgCookieExpiration, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookiePrefix;
+ $this->load();
+ if ( 0 == $this->mId ) return;
+ $exp = time() + $wgCookieExpiration;
+
+ $_SESSION['wsUserID'] = $this->mId;
+ setcookie( $wgCookiePrefix.'UserID', $this->mId, $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+
+ $_SESSION['wsUserName'] = $this->getName();
+ setcookie( $wgCookiePrefix.'UserName', $this->getName(), $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+
+ $_SESSION['wsToken'] = $this->mToken;
+ if ( 1 == $this->getOption( 'rememberpassword' ) ) {
+ setcookie( $wgCookiePrefix.'Token', $this->mToken, $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+ } else {
+ setcookie( $wgCookiePrefix.'Token', '', time() - 3600 );
+ }
+ }
+
+ /**
+ * Logout user
+ * Clears the cookies and session, resets the instance cache
+ */
+ function logout() {
+ global $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookiePrefix;
+ $this->clearInstanceCache( 'defaults' );
+
+ $_SESSION['wsUserID'] = 0;
+
+ setcookie( $wgCookiePrefix.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+ setcookie( $wgCookiePrefix.'Token', '', time() - 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+
+ # Remember when user logged out, to prevent seeing cached pages
+ setcookie( $wgCookiePrefix.'LoggedOut', wfTimestampNow(), time() + 86400, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+ }
+
+ /**
+ * Save object settings into database
+ * @fixme Only rarely do all these fields need to be set!
+ */
+ function saveSettings() {
+ $this->load();
+ if ( wfReadOnly() ) { return; }
+ if ( 0 == $this->mId ) { return; }
+
+ $this->mTouched = self::newTouchedTimestamp();
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'user',
+ array( /* SET */
+ 'user_name' => $this->mName,
+ 'user_password' => $this->mPassword,
+ 'user_newpassword' => $this->mNewpassword,
+ 'user_newpass_time' => $dbw->timestampOrNull( $this->mNewpassTime ),
+ 'user_real_name' => $this->mRealName,
+ 'user_email' => $this->mEmail,
+ 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
+ 'user_options' => $this->encodeOptions(),
+ 'user_touched' => $dbw->timestamp($this->mTouched),
+ 'user_token' => $this->mToken
+ ), array( /* WHERE */
+ 'user_id' => $this->mId
+ ), __METHOD__
+ );
+ $this->clearSharedCache();
+ }
+
+
+ /**
+ * Checks if a user with the given name exists, returns the ID
+ */
+ function idForName() {
+ $s = trim( $this->getName() );
+ if ( 0 == strcmp( '', $s ) ) return 0;
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $id = $dbr->selectField( 'user', 'user_id', array( 'user_name' => $s ), __METHOD__ );
+ if ( $id === false ) {
+ $id = 0;
+ }
+ return $id;
+ }
+
+ /**
+ * Add a user to the database, return the user object
+ *
+ * @param string $name The user's name
+ * @param array $params Associative array of non-default parameters to save to the database:
+ * password The user's password. Password logins will be disabled if this is omitted.
+ * newpassword A temporary password mailed to the user
+ * email The user's email address
+ * email_authenticated The email authentication timestamp
+ * real_name The user's real name
+ * options An associative array of non-default options
+ * token Random authentication token. Do not set.
+ * registration Registration timestamp. Do not set.
+ *
+ * @return User object, or null if the username already exists
+ */
+ static function createNew( $name, $params = array() ) {
+ $user = new User;
+ $user->load();
+ if ( isset( $params['options'] ) ) {
+ $user->mOptions = $params['options'] + $user->mOptions;
+ unset( $params['options'] );
+ }
+ $dbw =& wfGetDB( DB_MASTER );
+ $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+ $fields = array(
+ 'user_id' => $seqVal,
+ 'user_name' => $name,
+ 'user_password' => $user->mPassword,
+ 'user_newpassword' => $user->mNewpassword,
+ 'user_newpass_time' => $dbw->timestamp( $user->mNewpassTime ),
+ 'user_email' => $user->mEmail,
+ 'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ),
+ 'user_real_name' => $user->mRealName,
+ 'user_options' => $user->encodeOptions(),
+ 'user_token' => $user->mToken,
+ 'user_registration' => $dbw->timestamp( $user->mRegistration ),
+ 'user_editcount' => 0,
+ );
+ foreach ( $params as $name => $value ) {
+ $fields["user_$name"] = $value;
+ }
+ $dbw->insert( 'user', $fields, __METHOD__, array( 'IGNORE' ) );
+ if ( $dbw->affectedRows() ) {
+ $newUser = User::newFromId( $dbw->insertId() );
+ } else {
+ $newUser = null;
+ }
+ return $newUser;
+ }
+
+ /**
+ * Add an existing user object to the database
+ */
+ function addToDatabase() {
+ $this->load();
+ $dbw =& wfGetDB( DB_MASTER );
+ $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+ $dbw->insert( 'user',
+ array(
+ 'user_id' => $seqVal,
+ 'user_name' => $this->mName,
+ 'user_password' => $this->mPassword,
+ 'user_newpassword' => $this->mNewpassword,
+ 'user_newpass_time' => $dbw->timestamp( $this->mNewpassTime ),
+ 'user_email' => $this->mEmail,
+ 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
+ 'user_real_name' => $this->mRealName,
+ 'user_options' => $this->encodeOptions(),
+ 'user_token' => $this->mToken,
+ 'user_registration' => $dbw->timestamp( $this->mRegistration ),
+ 'user_editcount' => 0,
+ ), __METHOD__
+ );
+ $this->mId = $dbw->insertId();
+
+ # Clear instance cache other than user table data, which is already accurate
+ $this->clearInstanceCache();
+ }
+
+ /**
+ * If the (non-anonymous) user is blocked, this function will block any IP address
+ * that they successfully log on from.
+ */
+ function spreadBlock() {
+ wfDebug( __METHOD__."()\n" );
+ $this->load();
+ if ( $this->mId == 0 ) {
+ return;
+ }
+
+ $userblock = Block::newFromDB( '', $this->mId );
+ if ( !$userblock ) {
+ return;
+ }
+
+ $userblock->doAutoblock( wfGetIp() );
+
+ }
+
+ /**
+ * Generate a string which will be different for any combination of
+ * user options which would produce different parser output.
+ * This will be used as part of the hash key for the parser cache,
+ * so users will the same options can share the same cached data
+ * safely.
+ *
+ * Extensions which require it should install 'PageRenderingHash' hook,
+ * which will give them a chance to modify this key based on their own
+ * settings.
+ *
+ * @return string
+ */
+ function getPageRenderingHash() {
+ global $wgContLang, $wgUseDynamicDates, $wgLang;
+ if( $this->mHash ){
+ return $this->mHash;
+ }
+
+ // stubthreshold is only included below for completeness,
+ // it will always be 0 when this function is called by parsercache.
+
+ $confstr = $this->getOption( 'math' );
+ $confstr .= '!' . $this->getOption( 'stubthreshold' );
+ if ( $wgUseDynamicDates ) {
+ $confstr .= '!' . $this->getDatePreference();
+ }
+ $confstr .= '!' . ($this->getOption( 'numberheadings' ) ? '1' : '');
+ $confstr .= '!' . $wgLang->getCode();
+ $confstr .= '!' . $this->getOption( 'thumbsize' );
+ // add in language specific options, if any
+ $extra = $wgContLang->getExtraHashOptions();
+ $confstr .= $extra;
+
+ // Give a chance for extensions to modify the hash, if they have
+ // extra options or other effects on the parser cache.
+ wfRunHooks( 'PageRenderingHash', array( &$confstr ) );
+
+ $this->mHash = $confstr;
+ return $confstr;
+ }
+
+ function isBlockedFromCreateAccount() {
+ $this->getBlockedStatus();
+ return $this->mBlock && $this->mBlock->mCreateAccount;
+ }
+
+ function isAllowedToCreateAccount() {
+ return $this->isAllowed( 'createaccount' ) && !$this->isBlockedFromCreateAccount();
+ }
+
+ /**
+ * @deprecated
+ */
+ function setLoaded( $loaded ) {}
+
+ /**
+ * Get this user's personal page title.
+ *
+ * @return Title
+ * @public
+ */
+ function getUserPage() {
+ return Title::makeTitle( NS_USER, $this->getName() );
+ }
+
+ /**
+ * Get this user's talk page title.
+ *
+ * @return Title
+ * @public
+ */
+ function getTalkPage() {
+ $title = $this->getUserPage();
+ return $title->getTalkPage();
+ }
+
+ /**
+ * @static
+ */
+ function getMaxID() {
+ static $res; // cache
+
+ if ( isset( $res ) )
+ return $res;
+ else {
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $res = $dbr->selectField( 'user', 'max(user_id)', false, 'User::getMaxID' );
+ }
+ }
+
+ /**
+ * Determine whether the user is a newbie. Newbies are either
+ * anonymous IPs, or the most recently created accounts.
+ * @return bool True if it is a newbie.
+ */
+ function isNewbie() {
+ return !$this->isAllowed( 'autoconfirmed' );
+ }
+
+ /**
+ * Check to see if the given clear-text password is one of the accepted passwords
+ * @param string $password User password.
+ * @return bool True if the given password is correct otherwise False.
+ */
+ function checkPassword( $password ) {
+ global $wgAuth;
+ $this->load();
+
+ // Even though we stop people from creating passwords that
+ // are shorter than this, doesn't mean people wont be able
+ // to. Certain authentication plugins do NOT want to save
+ // domain passwords in a mysql database, so we should
+ // check this (incase $wgAuth->strict() is false).
+ if( !$this->isValidPassword( $password ) ) {
+ return false;
+ }
+
+ if( $wgAuth->authenticate( $this->getName(), $password ) ) {
+ return true;
+ } elseif( $wgAuth->strict() ) {
+ /* Auth plugin doesn't allow local authentication */
+ return false;
+ }
+ $ep = $this->encryptPassword( $password );
+ if ( 0 == strcmp( $ep, $this->mPassword ) ) {
+ return true;
+ } elseif ( function_exists( 'iconv' ) ) {
+ # Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
+ # Check for this with iconv
+ $cp1252hash = $this->encryptPassword( iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password ) );
+ if ( 0 == strcmp( $cp1252hash, $this->mPassword ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if the given clear-text password matches the temporary password
+ * sent by e-mail for password reset operations.
+ * @return bool
+ */
+ function checkTemporaryPassword( $plaintext ) {
+ $hash = $this->encryptPassword( $plaintext );
+ return $hash === $this->mNewpassword;
+ }
+
+ /**
+ * Initialize (if necessary) and return a session token value
+ * which can be used in edit forms to show that the user's
+ * login credentials aren't being hijacked with a foreign form
+ * submission.
+ *
+ * @param mixed $salt - Optional function-specific data for hash.
+ * Use a string or an array of strings.
+ * @return string
+ * @public
+ */
+ function editToken( $salt = '' ) {
+ if( !isset( $_SESSION['wsEditToken'] ) ) {
+ $token = $this->generateToken();
+ $_SESSION['wsEditToken'] = $token;
+ } else {
+ $token = $_SESSION['wsEditToken'];
+ }
+ if( is_array( $salt ) ) {
+ $salt = implode( '|', $salt );
+ }
+ return md5( $token . $salt ) . EDIT_TOKEN_SUFFIX;
+ }
+
+ /**
+ * Generate a hex-y looking random token for various uses.
+ * Could be made more cryptographically sure if someone cares.
+ * @return string
+ */
+ function generateToken( $salt = '' ) {
+ $token = dechex( mt_rand() ) . dechex( mt_rand() );
+ return md5( $token . $salt );
+ }
+
+ /**
+ * Check given value against the token value stored in the session.
+ * A match should confirm that the form was submitted from the
+ * user's own login session, not a form submission from a third-party
+ * site.
+ *
+ * @param string $val - the input value to compare
+ * @param string $salt - Optional function-specific data for hash
+ * @return bool
+ * @public
+ */
+ function matchEditToken( $val, $salt = '' ) {
+ global $wgMemc;
+ $sessionToken = $this->editToken( $salt );
+ if ( $val != $sessionToken ) {
+ wfDebug( "User::matchEditToken: broken session data\n" );
+ }
+ return $val == $sessionToken;
+ }
+
+ /**
+ * Generate a new e-mail confirmation token and send a confirmation
+ * mail to the user's given address.
+ *
+ * @return mixed True on success, a WikiError object on failure.
+ */
+ function sendConfirmationMail() {
+ global $wgContLang;
+ $expiration = null; // gets passed-by-ref and defined in next line.
+ $url = $this->confirmationTokenUrl( $expiration );
+ return $this->sendMail( wfMsg( 'confirmemail_subject' ),
+ wfMsg( 'confirmemail_body',
+ wfGetIP(),
+ $this->getName(),
+ $url,
+ $wgContLang->timeanddate( $expiration, false ) ) );
+ }
+
+ /**
+ * Send an e-mail to this user's account. Does not check for
+ * confirmed status or validity.
+ *
+ * @param string $subject
+ * @param string $body
+ * @param strong $from Optional from address; default $wgPasswordSender will be used otherwise.
+ * @return mixed True on success, a WikiError object on failure.
+ */
+ function sendMail( $subject, $body, $from = null ) {
+ if( is_null( $from ) ) {
+ global $wgPasswordSender;
+ $from = $wgPasswordSender;
+ }
+
+ require_once( 'UserMailer.php' );
+ $to = new MailAddress( $this );
+ $sender = new MailAddress( $from );
+ $error = userMailer( $to, $sender, $subject, $body );
+
+ if( $error == '' ) {
+ return true;
+ } else {
+ return new WikiError( $error );
+ }
+ }
+
+ /**
+ * Generate, store, and return a new e-mail confirmation code.
+ * A hash (unsalted since it's used as a key) is stored.
+ * @param &$expiration mixed output: accepts the expiration time
+ * @return string
+ * @private
+ */
+ function confirmationToken( &$expiration ) {
+ $now = time();
+ $expires = $now + 7 * 24 * 60 * 60;
+ $expiration = wfTimestamp( TS_MW, $expires );
+
+ $token = $this->generateToken( $this->mId . $this->mEmail . $expires );
+ $hash = md5( $token );
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'user',
+ array( 'user_email_token' => $hash,
+ 'user_email_token_expires' => $dbw->timestamp( $expires ) ),
+ array( 'user_id' => $this->mId ),
+ __METHOD__ );
+
+ return $token;
+ }
+
+ /**
+ * Generate and store a new e-mail confirmation token, and return
+ * the URL the user can use to confirm.
+ * @param &$expiration mixed output: accepts the expiration time
+ * @return string
+ * @private
+ */
+ function confirmationTokenUrl( &$expiration ) {
+ $token = $this->confirmationToken( $expiration );
+ $title = SpecialPage::getTitleFor( 'Confirmemail', $token );
+ return $title->getFullUrl();
+ }
+
+ /**
+ * Mark the e-mail address confirmed and save.
+ */
+ function confirmEmail() {
+ $this->load();
+ $this->mEmailAuthenticated = wfTimestampNow();
+ $this->saveSettings();
+ return true;
+ }
+
+ /**
+ * Is this user allowed to send e-mails within limits of current
+ * site configuration?
+ * @return bool
+ */
+ function canSendEmail() {
+ return $this->isEmailConfirmed();
+ }
+
+ /**
+ * Is this user allowed to receive e-mails within limits of current
+ * site configuration?
+ * @return bool
+ */
+ function canReceiveEmail() {
+ return $this->canSendEmail() && !$this->getOption( 'disablemail' );
+ }
+
+ /**
+ * Is this user's e-mail address valid-looking and confirmed within
+ * limits of the current site configuration?
+ *
+ * If $wgEmailAuthentication is on, this may require the user to have
+ * confirmed their address by returning a code or using a password
+ * sent to the address from the wiki.
+ *
+ * @return bool
+ */
+ function isEmailConfirmed() {
+ global $wgEmailAuthentication;
+ $this->load();
+ $confirmed = true;
+ if( wfRunHooks( 'EmailConfirmed', array( &$this, &$confirmed ) ) ) {
+ if( $this->isAnon() )
+ return false;
+ if( !self::isValidEmailAddr( $this->mEmail ) )
+ return false;
+ if( $wgEmailAuthentication && !$this->getEmailAuthenticationTimestamp() )
+ return false;
+ return true;
+ } else {
+ return $confirmed;
+ }
+ }
+
+ /**
+ * Return true if there is an outstanding request for e-mail confirmation.
+ * @return bool
+ */
+ function isEmailConfirmationPending() {
+ global $wgEmailAuthentication;
+ return $wgEmailAuthentication &&
+ !$this->isEmailConfirmed() &&
+ $this->mEmailToken &&
+ $this->mEmailTokenExpires > wfTimestamp();
+ }
+
+ /**
+ * @param array $groups list of groups
+ * @return array list of permission key names for given groups combined
+ * @static
+ */
+ static function getGroupPermissions( $groups ) {
+ global $wgGroupPermissions;
+ $rights = array();
+ foreach( $groups as $group ) {
+ if( isset( $wgGroupPermissions[$group] ) ) {
+ $rights = array_merge( $rights,
+ array_keys( array_filter( $wgGroupPermissions[$group] ) ) );
+ }
+ }
+ return $rights;
+ }
+
+ /**
+ * @param string $group key name
+ * @return string localized descriptive name for group, if provided
+ * @static
+ */
+ static function getGroupName( $group ) {
+ $key = "group-$group";
+ $name = wfMsg( $key );
+ if( $name == '' || wfEmptyMsg( $key, $name ) ) {
+ return $group;
+ } else {
+ return $name;
+ }
+ }
+
+ /**
+ * @param string $group key name
+ * @return string localized descriptive name for member of a group, if provided
+ * @static
+ */
+ static function getGroupMember( $group ) {
+ $key = "group-$group-member";
+ $name = wfMsg( $key );
+ if( $name == '' || wfEmptyMsg( $key, $name ) ) {
+ return $group;
+ } else {
+ return $name;
+ }
+ }
+
+ /**
+ * Return the set of defined explicit groups.
+ * The *, 'user', 'autoconfirmed' and 'emailconfirmed'
+ * groups are not included, as they are defined
+ * automatically, not in the database.
+ * @return array
+ * @static
+ */
+ static function getAllGroups() {
+ global $wgGroupPermissions;
+ return array_diff(
+ array_keys( $wgGroupPermissions ),
+ array( '*', 'user', 'autoconfirmed', 'emailconfirmed' ) );
+ }
+
+ /**
+ * Get the title of a page describing a particular group
+ *
+ * @param $group Name of the group
+ * @return mixed
+ */
+ static function getGroupPage( $group ) {
+ $page = wfMsgForContent( 'grouppage-' . $group );
+ if( !wfEmptyMsg( 'grouppage-' . $group, $page ) ) {
+ $title = Title::newFromText( $page );
+ if( is_object( $title ) )
+ return $title;
+ }
+ return false;
+ }
+
+ /**
+ * Create a link to the group in HTML, if available
+ *
+ * @param $group Name of the group
+ * @param $text The text of the link
+ * @return mixed
+ */
+ static function makeGroupLinkHTML( $group, $text = '' ) {
+ if( $text == '' ) {
+ $text = self::getGroupName( $group );
+ }
+ $title = self::getGroupPage( $group );
+ if( $title ) {
+ global $wgUser;
+ $sk = $wgUser->getSkin();
+ return $sk->makeLinkObj( $title, $text );
+ } else {
+ return $text;
+ }
+ }
+
+ /**
+ * Create a link to the group in Wikitext, if available
+ *
+ * @param $group Name of the group
+ * @param $text The text of the link (by default, the name of the group)
+ * @return mixed
+ */
+ static function makeGroupLinkWiki( $group, $text = '' ) {
+ if( $text == '' ) {
+ $text = self::getGroupName( $group );
+ }
+ $title = self::getGroupPage( $group );
+ if( $title ) {
+ $page = $title->getPrefixedText();
+ return "[[$page|$text]]";
+ } else {
+ return $text;
+ }
+ }
+
+ /**
+ * Increment the user's edit-count field.
+ * Will have no effect for anonymous users.
+ */
+ function incEditCount() {
+ if( !$this->isAnon() ) {
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->update( 'user',
+ array( 'user_editcount=user_editcount+1' ),
+ array( 'user_id' => $this->getId() ),
+ __METHOD__ );
+
+ // Lazy initialization check...
+ if( $dbw->affectedRows() == 0 ) {
+ // Pull from a slave to be less cruel to servers
+ // Accuracy isn't the point anyway here
+ $dbr = wfGetDB( DB_SLAVE );
+ $count = $dbr->selectField( 'revision',
+ 'COUNT(rev_user)',
+ array( 'rev_user' => $this->getId() ),
+ __METHOD__ );
+
+ // Now here's a goddamn hack...
+ if( $dbr !== $dbw ) {
+ // If we actually have a slave server, the count is
+ // at least one behind because the current transaction
+ // has not been committed and replicated.
+ $count++;
+ } else {
+ // But if DB_SLAVE is selecting the master, then the
+ // count we just read includes the revision that was
+ // just added in the working transaction.
+ }
+
+ $dbw->update( 'user',
+ array( 'user_editcount' => $count ),
+ array( 'user_id' => $this->getId() ),
+ __METHOD__ );
+ }
+ }
+ }
+}
+
+?>
diff --git a/includes/UserMailer.php b/includes/UserMailer.php
new file mode 100644
index 000000000000..0101f74412a0
--- /dev/null
+++ b/includes/UserMailer.php
@@ -0,0 +1,433 @@
+<?php
+/**
+ * UserMailer.php
+ * Copyright (C) 2004 Thomas Gries <mail@tgries.de>
+ * http://www.mediawiki.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
+ *
+ * @author <brion@pobox.com>
+ * @author <mail@tgries.de>
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Converts a string into a valid RFC 822 "phrase", such as is used for the sender name
+ */
+function wfRFC822Phrase( $phrase ) {
+ $phrase = strtr( $phrase, array( "\r" => '', "\n" => '', '"' => '' ) );
+ return '"' . $phrase . '"';
+}
+
+class MailAddress {
+ /**
+ * @param mixed $address String with an email address, or a User object
+ * @param string $name Human-readable name if a string address is given
+ */
+ function MailAddress( $address, $name=null ) {
+ if( is_object( $address ) && $address instanceof User ) {
+ $this->address = $address->getEmail();
+ $this->name = $address->getName();
+ } else {
+ $this->address = strval( $address );
+ $this->name = strval( $name );
+ }
+ }
+
+ /**
+ * 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->name != '' && !wfIsWindows() ) {
+ $quoted = wfQuotedPrintable( $this->name );
+ if( strpos( $quoted, '.' ) !== false ) {
+ $quoted = '"' . $quoted . '"';
+ }
+ return "$quoted <{$this->address}>";
+ } else {
+ return $this->address;
+ }
+ }
+}
+
+/**
+ * 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 $to MailAddress: recipient's email
+ * @param $from MailAddress: sender's email
+ * @param $subject String: email's subject.
+ * @param $body String: email's text.
+ * @param $replyto String: optional reply-to email (default: false).
+ */
+function userMailer( $to, $from, $subject, $body, $replyto=false ) {
+ global $wgUser, $wgSMTP, $wgOutputEncoding, $wgErrorString;
+
+ if (is_array( $wgSMTP )) {
+ require_once( 'Mail.php' );
+
+ $timestamp = time();
+ $dest = $to->address;
+
+ $headers['From'] = $from->toString();
+ $headers['To'] = $to->toString();
+ if ( $replyto ) {
+ $headers['Reply-To'] = $replyto;
+ }
+ $headers['Subject'] = wfQuotedPrintable( $subject );
+ $headers['Date'] = date( 'r' );
+ $headers['MIME-Version'] = '1.0';
+ $headers['Content-type'] = 'text/plain; charset='.$wgOutputEncoding;
+ $headers['Content-transfer-encoding'] = '8bit';
+ $headers['Message-ID'] = "<{$timestamp}" . $wgUser->getName() . '@' . $wgSMTP['IDHost'] . '>'; // FIXME
+ $headers['X-Mailer'] = 'MediaWiki mailer';
+
+ // 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" );
+ return $mail_object->getMessage();
+ }
+
+ wfDebug( "Sending mail via PEAR::Mail to $dest\n" );
+ $mailResult =& $mail_object->send($dest, $headers, $body);
+
+ # Based on the result return an error string,
+ if ($mailResult === true) {
+ return '';
+ } elseif (is_object($mailResult)) {
+ wfDebug( "PEAR::Mail failed: " . $mailResult->getMessage() . "\n" );
+ return $mailResult->getMessage();
+ } else {
+ wfDebug( "PEAR::Mail failed, unknown error result\n" );
+ return 'Mail object return unknown error.';
+ }
+ } else {
+ # In the following $headers = expression we removed "Reply-To: {$from}\r\n" , because it is treated differently
+ # (fifth parameter of the PHP mail function, see some lines below)
+
+ # Line endings need to be different on Unix and Windows due to
+ # the bug described at http://trac.wordpress.org/ticket/2603
+ if ( wfIsWindows() ) {
+ $body = str_replace( "\n", "\r\n", $body );
+ $endl = "\r\n";
+ } else {
+ $endl = "\n";
+ }
+ $headers =
+ "MIME-Version: 1.0$endl" .
+ "Content-type: text/plain; charset={$wgOutputEncoding}$endl" .
+ "Content-Transfer-Encoding: 8bit$endl" .
+ "X-Mailer: MediaWiki mailer$endl".
+ 'From: ' . $from->toString();
+ if ($replyto) {
+ $headers .= "{$endl}Reply-To: $replyto";
+ }
+
+ $dest = $to->toString();
+
+ $wgErrorString = '';
+ set_error_handler( 'mailErrorHandler' );
+ wfDebug( "Sending mail via internal mail() function to $dest\n" );
+ mail( $dest, wfQuotedPrintable( $subject ), $body, $headers );
+ restore_error_handler();
+
+ if ( $wgErrorString ) {
+ wfDebug( "Error sending mail: $wgErrorString\n" );
+ }
+ return $wgErrorString;
+ }
+}
+
+/**
+ * Get the mail error message in global $wgErrorString
+ *
+ * @param $code Integer: error number
+ * @param $string String: error message
+ */
+function mailErrorHandler( $code, $string ) {
+ global $wgErrorString;
+ $wgErrorString = preg_replace( '/^mail\(\)(\s*\[.*?\])?: /', '', $string );
+}
+
+
+/**
+ * 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
+ *
+ * @package MediaWiki
+ *
+ */
+class EmailNotification {
+ /**@{{
+ * @private
+ */
+ var $to, $subject, $body, $replyto, $from;
+ var $user, $title, $timestamp, $summary, $minorEdit, $oldid;
+
+ /**@}}*/
+
+ /**
+ * @todo document
+ * @param $title Title object
+ * @param $timestamp
+ * @param $summary
+ * @param $minorEdit
+ * @param $oldid (default: false)
+ */
+ function notifyOnPageChange(&$title, $timestamp, $summary, $minorEdit, $oldid=false) {
+
+ # we use $wgEmergencyContact as sender's address
+ global $wgUser, $wgEnotifWatchlist;
+ global $wgEnotifMinorEdits, $wgEnotifUserTalk, $wgShowUpdatedMarker;
+
+ $fname = 'UserMailer::notifyOnPageChange';
+ wfProfileIn( $fname );
+
+ # 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);
+ $enotifusertalkpage = ($isUserTalkPage && $wgEnotifUserTalk);
+ $enotifwatchlistpage = $wgEnotifWatchlist;
+
+ if ( (!$minorEdit || $wgEnotifMinorEdits) ) {
+ if( $wgEnotifWatchlist ) {
+ // Send updates to watchers other than the current editor
+ $userCondition = 'wl_user <> ' . intval( $wgUser->getId() );
+ } elseif( $wgEnotifUserTalk && $title->getNamespace() == NS_USER_TALK ) {
+ $targetUser = User::newFromName( $title->getText() );
+ if( is_null( $targetUser ) ) {
+ wfDebug( "$fname: user-talk-only mode; no such user\n" );
+ $userCondition = false;
+ } elseif( $targetUser->getId() == $wgUser->getId() ) {
+ wfDebug( "$fname: user-talk-only mode; editor is target user\n" );
+ $userCondition = false;
+ } else {
+ // Don't notify anyone other than the owner of the talk page
+ $userCondition = 'wl_user = ' . intval( $targetUser->getId() );
+ }
+ } else {
+ // Notifications disabled
+ $userCondition = false;
+ }
+ if( $userCondition ) {
+ $dbr =& wfGetDB( DB_MASTER );
+
+ $res = $dbr->select( 'watchlist', array( 'wl_user' ),
+ array(
+ 'wl_title' => $title->getDBkey(),
+ 'wl_namespace' => $title->getNamespace(),
+ $userCondition,
+ 'wl_notificationtimestamp IS NULL',
+ ), $fname );
+
+ # if anyone is watching ... set up the email message text which is
+ # common for all receipients ...
+ if ( $dbr->numRows( $res ) > 0 ) {
+ $this->title =& $title;
+ $this->timestamp = $timestamp;
+ $this->summary = $summary;
+ $this->minorEdit = $minorEdit;
+ $this->oldid = $oldid;
+
+ $this->composeCommonMailtext();
+ $watchingUser = new User();
+
+ # ... now do for all watching users ... if the options fit
+ for ($i = 1; $i <= $dbr->numRows( $res ); $i++) {
+
+ $wuser = $dbr->fetchObject( $res );
+ $watchingUser->setID($wuser->wl_user);
+
+ if ( ( $enotifwatchlistpage && $watchingUser->getOption('enotifwatchlistpages') ) ||
+ ( $enotifusertalkpage
+ && $watchingUser->getOption('enotifusertalkpages')
+ && $title->equals( $watchingUser->getTalkPage() ) )
+ && (!$minorEdit || ($wgEnotifMinorEdits && $watchingUser->getOption('enotifminoredits') ) )
+ && ($watchingUser->isEmailConfirmed() ) ) {
+ # ... adjust remaining text and page edit time placeholders
+ # which needs to be personalized for each user
+ $this->composeAndSendPersonalisedMail( $watchingUser );
+
+ } # if the watching user has an email address in the preferences
+ }
+ }
+ } # if anyone is watching
+ } # if $wgEnotifWatchlist = true
+
+ if ( $wgShowUpdatedMarker || $wgEnotifWatchlist ) {
+ # mark the changed watch-listed page with a timestamp, so that the page is
+ # listed with an "updated since your last visit" icon in the watch list, ...
+ $dbw =& wfGetDB( DB_MASTER );
+ $success = $dbw->update( 'watchlist',
+ array( /* SET */
+ 'wl_notificationtimestamp' => $dbw->timestamp($timestamp)
+ ), array( /* WHERE */
+ 'wl_title' => $title->getDBkey(),
+ 'wl_namespace' => $title->getNamespace(),
+ ), 'UserMailer::NotifyOnChange'
+ );
+ # FIXME what do we do on failure ?
+ }
+ wfProfileOut( $fname );
+ } # function NotifyOnChange
+
+ /**
+ * @private
+ */
+ function composeCommonMailtext() {
+ global $wgUser, $wgEmergencyContact, $wgNoReplyAddress;
+ global $wgEnotifFromEditor, $wgEnotifRevealEditorAddress;
+
+ $summary = ($this->summary == '') ? ' - ' : $this->summary;
+ $medit = ($this->minorEdit) ? wfMsg( 'minoredit' ) : '';
+
+ # 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
+
+ $subject = wfMsgForContent( 'enotif_subject' );
+ $body = wfMsgForContent( 'enotif_body' );
+ $from = ''; /* fail safe */
+ $replyto = ''; /* fail safe */
+ $keys = array();
+
+ # regarding the use of oldid as an indicator for the last visited version, see also
+ # http://bugzilla.wikipeda.org/show_bug.cgi?id=603 "Delete + undelete cycle doesn't preserve old_id"
+ # However, in the case of a new page which is already watched, we have no previous version to compare
+ if( $this->oldid ) {
+ $difflink = $this->title->getFullUrl( 'diff=0&oldid=' . $this->oldid );
+ $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_lastvisited', $difflink );
+ $keys['$OLDID'] = $this->oldid;
+ $keys['$CHANGEDORCREATED'] = wfMsgForContent( 'changed' );
+ } else {
+ $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_newpagetext' );
+ # clear $OLDID placeholder in the message template
+ $keys['$OLDID'] = '';
+ $keys['$CHANGEDORCREATED'] = wfMsgForContent( 'created' );
+ }
+
+ $body = strtr( $body, $keys );
+ $pagetitle = $this->title->getPrefixedText();
+ $keys['$PAGETITLE'] = $pagetitle;
+ $keys['$PAGETITLE_URL'] = $this->title->getFullUrl();
+
+ $keys['$PAGEMINOREDIT'] = $medit;
+ $keys['$PAGESUMMARY'] = $summary;
+
+ $subject = strtr( $subject, $keys );
+
+ # 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.
+ $name = $wgUser->getName();
+ $adminAddress = new MailAddress( $wgEmergencyContact, 'WikiAdmin' );
+ $editorAddress = new MailAddress( $wgUser );
+ if( $wgEnotifRevealEditorAddress
+ && ( $wgUser->getEmail() != '' )
+ && $wgUser->getOption( 'enotifrevealaddr' ) ) {
+ if( $wgEnotifFromEditor ) {
+ $from = $editorAddress;
+ } else {
+ $from = $adminAddress;
+ $replyto = $editorAddress;
+ }
+ } else {
+ $from = $adminAddress;
+ $replyto = $wgNoReplyAddress;
+ }
+
+ if( $wgUser->isIP( $name ) ) {
+ #real anon (user:xxx.xxx.xxx.xxx)
+ $subject = str_replace('$PAGEEDITOR', 'anonymous user '. $name, $subject);
+ $keys['$PAGEEDITOR'] = 'anonymous user ' . $name;
+ $keys['$PAGEEDITOR_EMAIL'] = wfMsgForContent( 'noemailtitle' );
+ } else {
+ $subject = str_replace('$PAGEEDITOR', $name, $subject);
+ $keys['$PAGEEDITOR'] = $name;
+ $emailPage = SpecialPage::getSafeTitleFor( 'Emailuser', $name );
+ $keys['$PAGEEDITOR_EMAIL'] = $emailPage->getFullUrl();
+ }
+ $userPage = $wgUser->getUserPage();
+ $keys['$PAGEEDITOR_WIKI'] = $userPage->getFullUrl();
+ $body = strtr( $body, $keys );
+ $body = wordwrap( $body, 72 );
+
+ # now save this as the constant user-independent part of the message
+ $this->from = $from;
+ $this->replyto = $replyto;
+ $this->subject = $subject;
+ $this->body = $body;
+ }
+
+
+
+ /**
+ * 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
+ * @param object $mail
+ * @return bool
+ * @private
+ */
+ function composeAndSendPersonalisedMail( $watchingUser ) {
+ global $wgLang;
+ // 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 );
+ $body = str_replace( '$WATCHINGUSERNAME', $watchingUser->getName() , $this->body );
+
+ $timecorrection = $watchingUser->getOption( 'timecorrection' );
+
+ # $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('$PAGEEDITDATE',
+ $wgLang->timeanddate( $this->timestamp, true, false, $timecorrection ),
+ $body);
+
+ $error = userMailer( $to, $this->from, $this->subject, $body, $this->replyto );
+ return ($error == '');
+ }
+
+} # end of class EmailNotification
+?>
diff --git a/includes/Utf8Case.php b/includes/Utf8Case.php
new file mode 100644
index 000000000000..8c7fdd0b8db8
--- /dev/null
+++ b/includes/Utf8Case.php
@@ -0,0 +1,1506 @@
+<?php
+/**
+ * Simple 1:1 upper/lowercase switching arrays for utf-8 text
+ * Won't get context-sensitive things yet
+ *
+ * Hack for bugs in ucfirst() and company
+ *
+ * These are pulled from memcached if possible, as this is faster than filling
+ * up a big array manually.
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/*
+ * Translation array to get upper case character
+ */
+$wikiUpperChars = array(
+ "a" => "A",
+ "b" => "B",
+ "c" => "C",
+ "d" => "D",
+ "e" => "E",
+ "f" => "F",
+ "g" => "G",
+ "h" => "H",
+ "i" => "I",
+ "j" => "J",
+ "k" => "K",
+ "l" => "L",
+ "m" => "M",
+ "n" => "N",
+ "o" => "O",
+ "p" => "P",
+ "q" => "Q",
+ "r" => "R",
+ "s" => "S",
+ "t" => "T",
+ "u" => "U",
+ "v" => "V",
+ "w" => "W",
+ "x" => "X",
+ "y" => "Y",
+ "z" => "Z",
+ "\xc2\xb5" => "\xce\x9c",
+ "\xc3\xa0" => "\xc3\x80",
+ "\xc3\xa1" => "\xc3\x81",
+ "\xc3\xa2" => "\xc3\x82",
+ "\xc3\xa3" => "\xc3\x83",
+ "\xc3\xa4" => "\xc3\x84",
+ "\xc3\xa5" => "\xc3\x85",
+ "\xc3\xa6" => "\xc3\x86",
+ "\xc3\xa7" => "\xc3\x87",
+ "\xc3\xa8" => "\xc3\x88",
+ "\xc3\xa9" => "\xc3\x89",
+ "\xc3\xaa" => "\xc3\x8a",
+ "\xc3\xab" => "\xc3\x8b",
+ "\xc3\xac" => "\xc3\x8c",
+ "\xc3\xad" => "\xc3\x8d",
+ "\xc3\xae" => "\xc3\x8e",
+ "\xc3\xaf" => "\xc3\x8f",
+ "\xc3\xb0" => "\xc3\x90",
+ "\xc3\xb1" => "\xc3\x91",
+ "\xc3\xb2" => "\xc3\x92",
+ "\xc3\xb3" => "\xc3\x93",
+ "\xc3\xb4" => "\xc3\x94",
+ "\xc3\xb5" => "\xc3\x95",
+ "\xc3\xb6" => "\xc3\x96",
+ "\xc3\xb8" => "\xc3\x98",
+ "\xc3\xb9" => "\xc3\x99",
+ "\xc3\xba" => "\xc3\x9a",
+ "\xc3\xbb" => "\xc3\x9b",
+ "\xc3\xbc" => "\xc3\x9c",
+ "\xc3\xbd" => "\xc3\x9d",
+ "\xc3\xbe" => "\xc3\x9e",
+ "\xc3\xbf" => "\xc5\xb8",
+ "\xc4\x81" => "\xc4\x80",
+ "\xc4\x83" => "\xc4\x82",
+ "\xc4\x85" => "\xc4\x84",
+ "\xc4\x87" => "\xc4\x86",
+ "\xc4\x89" => "\xc4\x88",
+ "\xc4\x8b" => "\xc4\x8a",
+ "\xc4\x8d" => "\xc4\x8c",
+ "\xc4\x8f" => "\xc4\x8e",
+ "\xc4\x91" => "\xc4\x90",
+ "\xc4\x93" => "\xc4\x92",
+ "\xc4\x95" => "\xc4\x94",
+ "\xc4\x97" => "\xc4\x96",
+ "\xc4\x99" => "\xc4\x98",
+ "\xc4\x9b" => "\xc4\x9a",
+ "\xc4\x9d" => "\xc4\x9c",
+ "\xc4\x9f" => "\xc4\x9e",
+ "\xc4\xa1" => "\xc4\xa0",
+ "\xc4\xa3" => "\xc4\xa2",
+ "\xc4\xa5" => "\xc4\xa4",
+ "\xc4\xa7" => "\xc4\xa6",
+ "\xc4\xa9" => "\xc4\xa8",
+ "\xc4\xab" => "\xc4\xaa",
+ "\xc4\xad" => "\xc4\xac",
+ "\xc4\xaf" => "\xc4\xae",
+ "\xc4\xb1" => "I",
+ "\xc4\xb3" => "\xc4\xb2",
+ "\xc4\xb5" => "\xc4\xb4",
+ "\xc4\xb7" => "\xc4\xb6",
+ "\xc4\xba" => "\xc4\xb9",
+ "\xc4\xbc" => "\xc4\xbb",
+ "\xc4\xbe" => "\xc4\xbd",
+ "\xc5\x80" => "\xc4\xbf",
+ "\xc5\x82" => "\xc5\x81",
+ "\xc5\x84" => "\xc5\x83",
+ "\xc5\x86" => "\xc5\x85",
+ "\xc5\x88" => "\xc5\x87",
+ "\xc5\x8b" => "\xc5\x8a",
+ "\xc5\x8d" => "\xc5\x8c",
+ "\xc5\x8f" => "\xc5\x8e",
+ "\xc5\x91" => "\xc5\x90",
+ "\xc5\x93" => "\xc5\x92",
+ "\xc5\x95" => "\xc5\x94",
+ "\xc5\x97" => "\xc5\x96",
+ "\xc5\x99" => "\xc5\x98",
+ "\xc5\x9b" => "\xc5\x9a",
+ "\xc5\x9d" => "\xc5\x9c",
+ "\xc5\x9f" => "\xc5\x9e",
+ "\xc5\xa1" => "\xc5\xa0",
+ "\xc5\xa3" => "\xc5\xa2",
+ "\xc5\xa5" => "\xc5\xa4",
+ "\xc5\xa7" => "\xc5\xa6",
+ "\xc5\xa9" => "\xc5\xa8",
+ "\xc5\xab" => "\xc5\xaa",
+ "\xc5\xad" => "\xc5\xac",
+ "\xc5\xaf" => "\xc5\xae",
+ "\xc5\xb1" => "\xc5\xb0",
+ "\xc5\xb3" => "\xc5\xb2",
+ "\xc5\xb5" => "\xc5\xb4",
+ "\xc5\xb7" => "\xc5\xb6",
+ "\xc5\xba" => "\xc5\xb9",
+ "\xc5\xbc" => "\xc5\xbb",
+ "\xc5\xbe" => "\xc5\xbd",
+ "\xc5\xbf" => "S",
+ "\xc6\x83" => "\xc6\x82",
+ "\xc6\x85" => "\xc6\x84",
+ "\xc6\x88" => "\xc6\x87",
+ "\xc6\x8c" => "\xc6\x8b",
+ "\xc6\x92" => "\xc6\x91",
+ "\xc6\x95" => "\xc7\xb6",
+ "\xc6\x99" => "\xc6\x98",
+ "\xc6\xa1" => "\xc6\xa0",
+ "\xc6\xa3" => "\xc6\xa2",
+ "\xc6\xa5" => "\xc6\xa4",
+ "\xc6\xa8" => "\xc6\xa7",
+ "\xc6\xad" => "\xc6\xac",
+ "\xc6\xb0" => "\xc6\xaf",
+ "\xc6\xb4" => "\xc6\xb3",
+ "\xc6\xb6" => "\xc6\xb5",
+ "\xc6\xb9" => "\xc6\xb8",
+ "\xc6\xbd" => "\xc6\xbc",
+ "\xc6\xbf" => "\xc7\xb7",
+ "\xc7\x85" => "\xc7\x84",
+ "\xc7\x86" => "\xc7\x84",
+ "\xc7\x88" => "\xc7\x87",
+ "\xc7\x89" => "\xc7\x87",
+ "\xc7\x8b" => "\xc7\x8a",
+ "\xc7\x8c" => "\xc7\x8a",
+ "\xc7\x8e" => "\xc7\x8d",
+ "\xc7\x90" => "\xc7\x8f",
+ "\xc7\x92" => "\xc7\x91",
+ "\xc7\x94" => "\xc7\x93",
+ "\xc7\x96" => "\xc7\x95",
+ "\xc7\x98" => "\xc7\x97",
+ "\xc7\x9a" => "\xc7\x99",
+ "\xc7\x9c" => "\xc7\x9b",
+ "\xc7\x9d" => "\xc6\x8e",
+ "\xc7\x9f" => "\xc7\x9e",
+ "\xc7\xa1" => "\xc7\xa0",
+ "\xc7\xa3" => "\xc7\xa2",
+ "\xc7\xa5" => "\xc7\xa4",
+ "\xc7\xa7" => "\xc7\xa6",
+ "\xc7\xa9" => "\xc7\xa8",
+ "\xc7\xab" => "\xc7\xaa",
+ "\xc7\xad" => "\xc7\xac",
+ "\xc7\xaf" => "\xc7\xae",
+ "\xc7\xb2" => "\xc7\xb1",
+ "\xc7\xb3" => "\xc7\xb1",
+ "\xc7\xb5" => "\xc7\xb4",
+ "\xc7\xb9" => "\xc7\xb8",
+ "\xc7\xbb" => "\xc7\xba",
+ "\xc7\xbd" => "\xc7\xbc",
+ "\xc7\xbf" => "\xc7\xbe",
+ "\xc8\x81" => "\xc8\x80",
+ "\xc8\x83" => "\xc8\x82",
+ "\xc8\x85" => "\xc8\x84",
+ "\xc8\x87" => "\xc8\x86",
+ "\xc8\x89" => "\xc8\x88",
+ "\xc8\x8b" => "\xc8\x8a",
+ "\xc8\x8d" => "\xc8\x8c",
+ "\xc8\x8f" => "\xc8\x8e",
+ "\xc8\x91" => "\xc8\x90",
+ "\xc8\x93" => "\xc8\x92",
+ "\xc8\x95" => "\xc8\x94",
+ "\xc8\x97" => "\xc8\x96",
+ "\xc8\x99" => "\xc8\x98",
+ "\xc8\x9b" => "\xc8\x9a",
+ "\xc8\x9d" => "\xc8\x9c",
+ "\xc8\x9f" => "\xc8\x9e",
+ "\xc8\xa3" => "\xc8\xa2",
+ "\xc8\xa5" => "\xc8\xa4",
+ "\xc8\xa7" => "\xc8\xa6",
+ "\xc8\xa9" => "\xc8\xa8",
+ "\xc8\xab" => "\xc8\xaa",
+ "\xc8\xad" => "\xc8\xac",
+ "\xc8\xaf" => "\xc8\xae",
+ "\xc8\xb1" => "\xc8\xb0",
+ "\xc8\xb3" => "\xc8\xb2",
+ "\xc9\x93" => "\xc6\x81",
+ "\xc9\x94" => "\xc6\x86",
+ "\xc9\x96" => "\xc6\x89",
+ "\xc9\x97" => "\xc6\x8a",
+ "\xc9\x99" => "\xc6\x8f",
+ "\xc9\x9b" => "\xc6\x90",
+ "\xc9\xa0" => "\xc6\x93",
+ "\xc9\xa3" => "\xc6\x94",
+ "\xc9\xa8" => "\xc6\x97",
+ "\xc9\xa9" => "\xc6\x96",
+ "\xc9\xaf" => "\xc6\x9c",
+ "\xc9\xb2" => "\xc6\x9d",
+ "\xc9\xb5" => "\xc6\x9f",
+ "\xca\x80" => "\xc6\xa6",
+ "\xca\x83" => "\xc6\xa9",
+ "\xca\x88" => "\xc6\xae",
+ "\xca\x8a" => "\xc6\xb1",
+ "\xca\x8b" => "\xc6\xb2",
+ "\xca\x92" => "\xc6\xb7",
+ "\xcd\x85" => "\xce\x99",
+ "\xce\xac" => "\xce\x86",
+ "\xce\xad" => "\xce\x88",
+ "\xce\xae" => "\xce\x89",
+ "\xce\xaf" => "\xce\x8a",
+ "\xce\xb1" => "\xce\x91",
+ "\xce\xb2" => "\xce\x92",
+ "\xce\xb3" => "\xce\x93",
+ "\xce\xb4" => "\xce\x94",
+ "\xce\xb5" => "\xce\x95",
+ "\xce\xb6" => "\xce\x96",
+ "\xce\xb7" => "\xce\x97",
+ "\xce\xb8" => "\xce\x98",
+ "\xce\xb9" => "\xce\x99",
+ "\xce\xba" => "\xce\x9a",
+ "\xce\xbb" => "\xce\x9b",
+ "\xce\xbc" => "\xce\x9c",
+ "\xce\xbd" => "\xce\x9d",
+ "\xce\xbe" => "\xce\x9e",
+ "\xce\xbf" => "\xce\x9f",
+ "\xcf\x80" => "\xce\xa0",
+ "\xcf\x81" => "\xce\xa1",
+ "\xcf\x82" => "\xce\xa3",
+ "\xcf\x83" => "\xce\xa3",
+ "\xcf\x84" => "\xce\xa4",
+ "\xcf\x85" => "\xce\xa5",
+ "\xcf\x86" => "\xce\xa6",
+ "\xcf\x87" => "\xce\xa7",
+ "\xcf\x88" => "\xce\xa8",
+ "\xcf\x89" => "\xce\xa9",
+ "\xcf\x8a" => "\xce\xaa",
+ "\xcf\x8b" => "\xce\xab",
+ "\xcf\x8c" => "\xce\x8c",
+ "\xcf\x8d" => "\xce\x8e",
+ "\xcf\x8e" => "\xce\x8f",
+ "\xcf\x90" => "\xce\x92",
+ "\xcf\x91" => "\xce\x98",
+ "\xcf\x95" => "\xce\xa6",
+ "\xcf\x96" => "\xce\xa0",
+ "\xcf\x9b" => "\xcf\x9a",
+ "\xcf\x9d" => "\xcf\x9c",
+ "\xcf\x9f" => "\xcf\x9e",
+ "\xcf\xa1" => "\xcf\xa0",
+ "\xcf\xa3" => "\xcf\xa2",
+ "\xcf\xa5" => "\xcf\xa4",
+ "\xcf\xa7" => "\xcf\xa6",
+ "\xcf\xa9" => "\xcf\xa8",
+ "\xcf\xab" => "\xcf\xaa",
+ "\xcf\xad" => "\xcf\xac",
+ "\xcf\xaf" => "\xcf\xae",
+ "\xcf\xb0" => "\xce\x9a",
+ "\xcf\xb1" => "\xce\xa1",
+ "\xcf\xb2" => "\xce\xa3",
+ "\xcf\xb5" => "\xce\x95",
+ "\xd0\xb0" => "\xd0\x90",
+ "\xd0\xb1" => "\xd0\x91",
+ "\xd0\xb2" => "\xd0\x92",
+ "\xd0\xb3" => "\xd0\x93",
+ "\xd0\xb4" => "\xd0\x94",
+ "\xd0\xb5" => "\xd0\x95",
+ "\xd0\xb6" => "\xd0\x96",
+ "\xd0\xb7" => "\xd0\x97",
+ "\xd0\xb8" => "\xd0\x98",
+ "\xd0\xb9" => "\xd0\x99",
+ "\xd0\xba" => "\xd0\x9a",
+ "\xd0\xbb" => "\xd0\x9b",
+ "\xd0\xbc" => "\xd0\x9c",
+ "\xd0\xbd" => "\xd0\x9d",
+ "\xd0\xbe" => "\xd0\x9e",
+ "\xd0\xbf" => "\xd0\x9f",
+ "\xd1\x80" => "\xd0\xa0",
+ "\xd1\x81" => "\xd0\xa1",
+ "\xd1\x82" => "\xd0\xa2",
+ "\xd1\x83" => "\xd0\xa3",
+ "\xd1\x84" => "\xd0\xa4",
+ "\xd1\x85" => "\xd0\xa5",
+ "\xd1\x86" => "\xd0\xa6",
+ "\xd1\x87" => "\xd0\xa7",
+ "\xd1\x88" => "\xd0\xa8",
+ "\xd1\x89" => "\xd0\xa9",
+ "\xd1\x8a" => "\xd0\xaa",
+ "\xd1\x8b" => "\xd0\xab",
+ "\xd1\x8c" => "\xd0\xac",
+ "\xd1\x8d" => "\xd0\xad",
+ "\xd1\x8e" => "\xd0\xae",
+ "\xd1\x8f" => "\xd0\xaf",
+ "\xd1\x90" => "\xd0\x80",
+ "\xd1\x91" => "\xd0\x81",
+ "\xd1\x92" => "\xd0\x82",
+ "\xd1\x93" => "\xd0\x83",
+ "\xd1\x94" => "\xd0\x84",
+ "\xd1\x95" => "\xd0\x85",
+ "\xd1\x96" => "\xd0\x86",
+ "\xd1\x97" => "\xd0\x87",
+ "\xd1\x98" => "\xd0\x88",
+ "\xd1\x99" => "\xd0\x89",
+ "\xd1\x9a" => "\xd0\x8a",
+ "\xd1\x9b" => "\xd0\x8b",
+ "\xd1\x9c" => "\xd0\x8c",
+ "\xd1\x9d" => "\xd0\x8d",
+ "\xd1\x9e" => "\xd0\x8e",
+ "\xd1\x9f" => "\xd0\x8f",
+ "\xd1\xa1" => "\xd1\xa0",
+ "\xd1\xa3" => "\xd1\xa2",
+ "\xd1\xa5" => "\xd1\xa4",
+ "\xd1\xa7" => "\xd1\xa6",
+ "\xd1\xa9" => "\xd1\xa8",
+ "\xd1\xab" => "\xd1\xaa",
+ "\xd1\xad" => "\xd1\xac",
+ "\xd1\xaf" => "\xd1\xae",
+ "\xd1\xb1" => "\xd1\xb0",
+ "\xd1\xb3" => "\xd1\xb2",
+ "\xd1\xb5" => "\xd1\xb4",
+ "\xd1\xb7" => "\xd1\xb6",
+ "\xd1\xb9" => "\xd1\xb8",
+ "\xd1\xbb" => "\xd1\xba",
+ "\xd1\xbd" => "\xd1\xbc",
+ "\xd1\xbf" => "\xd1\xbe",
+ "\xd2\x81" => "\xd2\x80",
+ "\xd2\x8d" => "\xd2\x8c",
+ "\xd2\x8f" => "\xd2\x8e",
+ "\xd2\x91" => "\xd2\x90",
+ "\xd2\x93" => "\xd2\x92",
+ "\xd2\x95" => "\xd2\x94",
+ "\xd2\x97" => "\xd2\x96",
+ "\xd2\x99" => "\xd2\x98",
+ "\xd2\x9b" => "\xd2\x9a",
+ "\xd2\x9d" => "\xd2\x9c",
+ "\xd2\x9f" => "\xd2\x9e",
+ "\xd2\xa1" => "\xd2\xa0",
+ "\xd2\xa3" => "\xd2\xa2",
+ "\xd2\xa5" => "\xd2\xa4",
+ "\xd2\xa7" => "\xd2\xa6",
+ "\xd2\xa9" => "\xd2\xa8",
+ "\xd2\xab" => "\xd2\xaa",
+ "\xd2\xad" => "\xd2\xac",
+ "\xd2\xaf" => "\xd2\xae",
+ "\xd2\xb1" => "\xd2\xb0",
+ "\xd2\xb3" => "\xd2\xb2",
+ "\xd2\xb5" => "\xd2\xb4",
+ "\xd2\xb7" => "\xd2\xb6",
+ "\xd2\xb9" => "\xd2\xb8",
+ "\xd2\xbb" => "\xd2\xba",
+ "\xd2\xbd" => "\xd2\xbc",
+ "\xd2\xbf" => "\xd2\xbe",
+ "\xd3\x82" => "\xd3\x81",
+ "\xd3\x84" => "\xd3\x83",
+ "\xd3\x88" => "\xd3\x87",
+ "\xd3\x8c" => "\xd3\x8b",
+ "\xd3\x91" => "\xd3\x90",
+ "\xd3\x93" => "\xd3\x92",
+ "\xd3\x95" => "\xd3\x94",
+ "\xd3\x97" => "\xd3\x96",
+ "\xd3\x99" => "\xd3\x98",
+ "\xd3\x9b" => "\xd3\x9a",
+ "\xd3\x9d" => "\xd3\x9c",
+ "\xd3\x9f" => "\xd3\x9e",
+ "\xd3\xa1" => "\xd3\xa0",
+ "\xd3\xa3" => "\xd3\xa2",
+ "\xd3\xa5" => "\xd3\xa4",
+ "\xd3\xa7" => "\xd3\xa6",
+ "\xd3\xa9" => "\xd3\xa8",
+ "\xd3\xab" => "\xd3\xaa",
+ "\xd3\xad" => "\xd3\xac",
+ "\xd3\xaf" => "\xd3\xae",
+ "\xd3\xb1" => "\xd3\xb0",
+ "\xd3\xb3" => "\xd3\xb2",
+ "\xd3\xb5" => "\xd3\xb4",
+ "\xd3\xb9" => "\xd3\xb8",
+ "\xd5\xa1" => "\xd4\xb1",
+ "\xd5\xa2" => "\xd4\xb2",
+ "\xd5\xa3" => "\xd4\xb3",
+ "\xd5\xa4" => "\xd4\xb4",
+ "\xd5\xa5" => "\xd4\xb5",
+ "\xd5\xa6" => "\xd4\xb6",
+ "\xd5\xa7" => "\xd4\xb7",
+ "\xd5\xa8" => "\xd4\xb8",
+ "\xd5\xa9" => "\xd4\xb9",
+ "\xd5\xaa" => "\xd4\xba",
+ "\xd5\xab" => "\xd4\xbb",
+ "\xd5\xac" => "\xd4\xbc",
+ "\xd5\xad" => "\xd4\xbd",
+ "\xd5\xae" => "\xd4\xbe",
+ "\xd5\xaf" => "\xd4\xbf",
+ "\xd5\xb0" => "\xd5\x80",
+ "\xd5\xb1" => "\xd5\x81",
+ "\xd5\xb2" => "\xd5\x82",
+ "\xd5\xb3" => "\xd5\x83",
+ "\xd5\xb4" => "\xd5\x84",
+ "\xd5\xb5" => "\xd5\x85",
+ "\xd5\xb6" => "\xd5\x86",
+ "\xd5\xb7" => "\xd5\x87",
+ "\xd5\xb8" => "\xd5\x88",
+ "\xd5\xb9" => "\xd5\x89",
+ "\xd5\xba" => "\xd5\x8a",
+ "\xd5\xbb" => "\xd5\x8b",
+ "\xd5\xbc" => "\xd5\x8c",
+ "\xd5\xbd" => "\xd5\x8d",
+ "\xd5\xbe" => "\xd5\x8e",
+ "\xd5\xbf" => "\xd5\x8f",
+ "\xd6\x80" => "\xd5\x90",
+ "\xd6\x81" => "\xd5\x91",
+ "\xd6\x82" => "\xd5\x92",
+ "\xd6\x83" => "\xd5\x93",
+ "\xd6\x84" => "\xd5\x94",
+ "\xd6\x85" => "\xd5\x95",
+ "\xd6\x86" => "\xd5\x96",
+ "\xe1\xb8\x81" => "\xe1\xb8\x80",
+ "\xe1\xb8\x83" => "\xe1\xb8\x82",
+ "\xe1\xb8\x85" => "\xe1\xb8\x84",
+ "\xe1\xb8\x87" => "\xe1\xb8\x86",
+ "\xe1\xb8\x89" => "\xe1\xb8\x88",
+ "\xe1\xb8\x8b" => "\xe1\xb8\x8a",
+ "\xe1\xb8\x8d" => "\xe1\xb8\x8c",
+ "\xe1\xb8\x8f" => "\xe1\xb8\x8e",
+ "\xe1\xb8\x91" => "\xe1\xb8\x90",
+ "\xe1\xb8\x93" => "\xe1\xb8\x92",
+ "\xe1\xb8\x95" => "\xe1\xb8\x94",
+ "\xe1\xb8\x97" => "\xe1\xb8\x96",
+ "\xe1\xb8\x99" => "\xe1\xb8\x98",
+ "\xe1\xb8\x9b" => "\xe1\xb8\x9a",
+ "\xe1\xb8\x9d" => "\xe1\xb8\x9c",
+ "\xe1\xb8\x9f" => "\xe1\xb8\x9e",
+ "\xe1\xb8\xa1" => "\xe1\xb8\xa0",
+ "\xe1\xb8\xa3" => "\xe1\xb8\xa2",
+ "\xe1\xb8\xa5" => "\xe1\xb8\xa4",
+ "\xe1\xb8\xa7" => "\xe1\xb8\xa6",
+ "\xe1\xb8\xa9" => "\xe1\xb8\xa8",
+ "\xe1\xb8\xab" => "\xe1\xb8\xaa",
+ "\xe1\xb8\xad" => "\xe1\xb8\xac",
+ "\xe1\xb8\xaf" => "\xe1\xb8\xae",
+ "\xe1\xb8\xb1" => "\xe1\xb8\xb0",
+ "\xe1\xb8\xb3" => "\xe1\xb8\xb2",
+ "\xe1\xb8\xb5" => "\xe1\xb8\xb4",
+ "\xe1\xb8\xb7" => "\xe1\xb8\xb6",
+ "\xe1\xb8\xb9" => "\xe1\xb8\xb8",
+ "\xe1\xb8\xbb" => "\xe1\xb8\xba",
+ "\xe1\xb8\xbd" => "\xe1\xb8\xbc",
+ "\xe1\xb8\xbf" => "\xe1\xb8\xbe",
+ "\xe1\xb9\x81" => "\xe1\xb9\x80",
+ "\xe1\xb9\x83" => "\xe1\xb9\x82",
+ "\xe1\xb9\x85" => "\xe1\xb9\x84",
+ "\xe1\xb9\x87" => "\xe1\xb9\x86",
+ "\xe1\xb9\x89" => "\xe1\xb9\x88",
+ "\xe1\xb9\x8b" => "\xe1\xb9\x8a",
+ "\xe1\xb9\x8d" => "\xe1\xb9\x8c",
+ "\xe1\xb9\x8f" => "\xe1\xb9\x8e",
+ "\xe1\xb9\x91" => "\xe1\xb9\x90",
+ "\xe1\xb9\x93" => "\xe1\xb9\x92",
+ "\xe1\xb9\x95" => "\xe1\xb9\x94",
+ "\xe1\xb9\x97" => "\xe1\xb9\x96",
+ "\xe1\xb9\x99" => "\xe1\xb9\x98",
+ "\xe1\xb9\x9b" => "\xe1\xb9\x9a",
+ "\xe1\xb9\x9d" => "\xe1\xb9\x9c",
+ "\xe1\xb9\x9f" => "\xe1\xb9\x9e",
+ "\xe1\xb9\xa1" => "\xe1\xb9\xa0",
+ "\xe1\xb9\xa3" => "\xe1\xb9\xa2",
+ "\xe1\xb9\xa5" => "\xe1\xb9\xa4",
+ "\xe1\xb9\xa7" => "\xe1\xb9\xa6",
+ "\xe1\xb9\xa9" => "\xe1\xb9\xa8",
+ "\xe1\xb9\xab" => "\xe1\xb9\xaa",
+ "\xe1\xb9\xad" => "\xe1\xb9\xac",
+ "\xe1\xb9\xaf" => "\xe1\xb9\xae",
+ "\xe1\xb9\xb1" => "\xe1\xb9\xb0",
+ "\xe1\xb9\xb3" => "\xe1\xb9\xb2",
+ "\xe1\xb9\xb5" => "\xe1\xb9\xb4",
+ "\xe1\xb9\xb7" => "\xe1\xb9\xb6",
+ "\xe1\xb9\xb9" => "\xe1\xb9\xb8",
+ "\xe1\xb9\xbb" => "\xe1\xb9\xba",
+ "\xe1\xb9\xbd" => "\xe1\xb9\xbc",
+ "\xe1\xb9\xbf" => "\xe1\xb9\xbe",
+ "\xe1\xba\x81" => "\xe1\xba\x80",
+ "\xe1\xba\x83" => "\xe1\xba\x82",
+ "\xe1\xba\x85" => "\xe1\xba\x84",
+ "\xe1\xba\x87" => "\xe1\xba\x86",
+ "\xe1\xba\x89" => "\xe1\xba\x88",
+ "\xe1\xba\x8b" => "\xe1\xba\x8a",
+ "\xe1\xba\x8d" => "\xe1\xba\x8c",
+ "\xe1\xba\x8f" => "\xe1\xba\x8e",
+ "\xe1\xba\x91" => "\xe1\xba\x90",
+ "\xe1\xba\x93" => "\xe1\xba\x92",
+ "\xe1\xba\x95" => "\xe1\xba\x94",
+ "\xe1\xba\x9b" => "\xe1\xb9\xa0",
+ "\xe1\xba\xa1" => "\xe1\xba\xa0",
+ "\xe1\xba\xa3" => "\xe1\xba\xa2",
+ "\xe1\xba\xa5" => "\xe1\xba\xa4",
+ "\xe1\xba\xa7" => "\xe1\xba\xa6",
+ "\xe1\xba\xa9" => "\xe1\xba\xa8",
+ "\xe1\xba\xab" => "\xe1\xba\xaa",
+ "\xe1\xba\xad" => "\xe1\xba\xac",
+ "\xe1\xba\xaf" => "\xe1\xba\xae",
+ "\xe1\xba\xb1" => "\xe1\xba\xb0",
+ "\xe1\xba\xb3" => "\xe1\xba\xb2",
+ "\xe1\xba\xb5" => "\xe1\xba\xb4",
+ "\xe1\xba\xb7" => "\xe1\xba\xb6",
+ "\xe1\xba\xb9" => "\xe1\xba\xb8",
+ "\xe1\xba\xbb" => "\xe1\xba\xba",
+ "\xe1\xba\xbd" => "\xe1\xba\xbc",
+ "\xe1\xba\xbf" => "\xe1\xba\xbe",
+ "\xe1\xbb\x81" => "\xe1\xbb\x80",
+ "\xe1\xbb\x83" => "\xe1\xbb\x82",
+ "\xe1\xbb\x85" => "\xe1\xbb\x84",
+ "\xe1\xbb\x87" => "\xe1\xbb\x86",
+ "\xe1\xbb\x89" => "\xe1\xbb\x88",
+ "\xe1\xbb\x8b" => "\xe1\xbb\x8a",
+ "\xe1\xbb\x8d" => "\xe1\xbb\x8c",
+ "\xe1\xbb\x8f" => "\xe1\xbb\x8e",
+ "\xe1\xbb\x91" => "\xe1\xbb\x90",
+ "\xe1\xbb\x93" => "\xe1\xbb\x92",
+ "\xe1\xbb\x95" => "\xe1\xbb\x94",
+ "\xe1\xbb\x97" => "\xe1\xbb\x96",
+ "\xe1\xbb\x99" => "\xe1\xbb\x98",
+ "\xe1\xbb\x9b" => "\xe1\xbb\x9a",
+ "\xe1\xbb\x9d" => "\xe1\xbb\x9c",
+ "\xe1\xbb\x9f" => "\xe1\xbb\x9e",
+ "\xe1\xbb\xa1" => "\xe1\xbb\xa0",
+ "\xe1\xbb\xa3" => "\xe1\xbb\xa2",
+ "\xe1\xbb\xa5" => "\xe1\xbb\xa4",
+ "\xe1\xbb\xa7" => "\xe1\xbb\xa6",
+ "\xe1\xbb\xa9" => "\xe1\xbb\xa8",
+ "\xe1\xbb\xab" => "\xe1\xbb\xaa",
+ "\xe1\xbb\xad" => "\xe1\xbb\xac",
+ "\xe1\xbb\xaf" => "\xe1\xbb\xae",
+ "\xe1\xbb\xb1" => "\xe1\xbb\xb0",
+ "\xe1\xbb\xb3" => "\xe1\xbb\xb2",
+ "\xe1\xbb\xb5" => "\xe1\xbb\xb4",
+ "\xe1\xbb\xb7" => "\xe1\xbb\xb6",
+ "\xe1\xbb\xb9" => "\xe1\xbb\xb8",
+ "\xe1\xbc\x80" => "\xe1\xbc\x88",
+ "\xe1\xbc\x81" => "\xe1\xbc\x89",
+ "\xe1\xbc\x82" => "\xe1\xbc\x8a",
+ "\xe1\xbc\x83" => "\xe1\xbc\x8b",
+ "\xe1\xbc\x84" => "\xe1\xbc\x8c",
+ "\xe1\xbc\x85" => "\xe1\xbc\x8d",
+ "\xe1\xbc\x86" => "\xe1\xbc\x8e",
+ "\xe1\xbc\x87" => "\xe1\xbc\x8f",
+ "\xe1\xbc\x90" => "\xe1\xbc\x98",
+ "\xe1\xbc\x91" => "\xe1\xbc\x99",
+ "\xe1\xbc\x92" => "\xe1\xbc\x9a",
+ "\xe1\xbc\x93" => "\xe1\xbc\x9b",
+ "\xe1\xbc\x94" => "\xe1\xbc\x9c",
+ "\xe1\xbc\x95" => "\xe1\xbc\x9d",
+ "\xe1\xbc\xa0" => "\xe1\xbc\xa8",
+ "\xe1\xbc\xa1" => "\xe1\xbc\xa9",
+ "\xe1\xbc\xa2" => "\xe1\xbc\xaa",
+ "\xe1\xbc\xa3" => "\xe1\xbc\xab",
+ "\xe1\xbc\xa4" => "\xe1\xbc\xac",
+ "\xe1\xbc\xa5" => "\xe1\xbc\xad",
+ "\xe1\xbc\xa6" => "\xe1\xbc\xae",
+ "\xe1\xbc\xa7" => "\xe1\xbc\xaf",
+ "\xe1\xbc\xb0" => "\xe1\xbc\xb8",
+ "\xe1\xbc\xb1" => "\xe1\xbc\xb9",
+ "\xe1\xbc\xb2" => "\xe1\xbc\xba",
+ "\xe1\xbc\xb3" => "\xe1\xbc\xbb",
+ "\xe1\xbc\xb4" => "\xe1\xbc\xbc",
+ "\xe1\xbc\xb5" => "\xe1\xbc\xbd",
+ "\xe1\xbc\xb6" => "\xe1\xbc\xbe",
+ "\xe1\xbc\xb7" => "\xe1\xbc\xbf",
+ "\xe1\xbd\x80" => "\xe1\xbd\x88",
+ "\xe1\xbd\x81" => "\xe1\xbd\x89",
+ "\xe1\xbd\x82" => "\xe1\xbd\x8a",
+ "\xe1\xbd\x83" => "\xe1\xbd\x8b",
+ "\xe1\xbd\x84" => "\xe1\xbd\x8c",
+ "\xe1\xbd\x85" => "\xe1\xbd\x8d",
+ "\xe1\xbd\x91" => "\xe1\xbd\x99",
+ "\xe1\xbd\x93" => "\xe1\xbd\x9b",
+ "\xe1\xbd\x95" => "\xe1\xbd\x9d",
+ "\xe1\xbd\x97" => "\xe1\xbd\x9f",
+ "\xe1\xbd\xa0" => "\xe1\xbd\xa8",
+ "\xe1\xbd\xa1" => "\xe1\xbd\xa9",
+ "\xe1\xbd\xa2" => "\xe1\xbd\xaa",
+ "\xe1\xbd\xa3" => "\xe1\xbd\xab",
+ "\xe1\xbd\xa4" => "\xe1\xbd\xac",
+ "\xe1\xbd\xa5" => "\xe1\xbd\xad",
+ "\xe1\xbd\xa6" => "\xe1\xbd\xae",
+ "\xe1\xbd\xa7" => "\xe1\xbd\xaf",
+ "\xe1\xbd\xb0" => "\xe1\xbe\xba",
+ "\xe1\xbd\xb1" => "\xe1\xbe\xbb",
+ "\xe1\xbd\xb2" => "\xe1\xbf\x88",
+ "\xe1\xbd\xb3" => "\xe1\xbf\x89",
+ "\xe1\xbd\xb4" => "\xe1\xbf\x8a",
+ "\xe1\xbd\xb5" => "\xe1\xbf\x8b",
+ "\xe1\xbd\xb6" => "\xe1\xbf\x9a",
+ "\xe1\xbd\xb7" => "\xe1\xbf\x9b",
+ "\xe1\xbd\xb8" => "\xe1\xbf\xb8",
+ "\xe1\xbd\xb9" => "\xe1\xbf\xb9",
+ "\xe1\xbd\xba" => "\xe1\xbf\xaa",
+ "\xe1\xbd\xbb" => "\xe1\xbf\xab",
+ "\xe1\xbd\xbc" => "\xe1\xbf\xba",
+ "\xe1\xbd\xbd" => "\xe1\xbf\xbb",
+ "\xe1\xbe\x80" => "\xe1\xbe\x88",
+ "\xe1\xbe\x81" => "\xe1\xbe\x89",
+ "\xe1\xbe\x82" => "\xe1\xbe\x8a",
+ "\xe1\xbe\x83" => "\xe1\xbe\x8b",
+ "\xe1\xbe\x84" => "\xe1\xbe\x8c",
+ "\xe1\xbe\x85" => "\xe1\xbe\x8d",
+ "\xe1\xbe\x86" => "\xe1\xbe\x8e",
+ "\xe1\xbe\x87" => "\xe1\xbe\x8f",
+ "\xe1\xbe\x90" => "\xe1\xbe\x98",
+ "\xe1\xbe\x91" => "\xe1\xbe\x99",
+ "\xe1\xbe\x92" => "\xe1\xbe\x9a",
+ "\xe1\xbe\x93" => "\xe1\xbe\x9b",
+ "\xe1\xbe\x94" => "\xe1\xbe\x9c",
+ "\xe1\xbe\x95" => "\xe1\xbe\x9d",
+ "\xe1\xbe\x96" => "\xe1\xbe\x9e",
+ "\xe1\xbe\x97" => "\xe1\xbe\x9f",
+ "\xe1\xbe\xa0" => "\xe1\xbe\xa8",
+ "\xe1\xbe\xa1" => "\xe1\xbe\xa9",
+ "\xe1\xbe\xa2" => "\xe1\xbe\xaa",
+ "\xe1\xbe\xa3" => "\xe1\xbe\xab",
+ "\xe1\xbe\xa4" => "\xe1\xbe\xac",
+ "\xe1\xbe\xa5" => "\xe1\xbe\xad",
+ "\xe1\xbe\xa6" => "\xe1\xbe\xae",
+ "\xe1\xbe\xa7" => "\xe1\xbe\xaf",
+ "\xe1\xbe\xb0" => "\xe1\xbe\xb8",
+ "\xe1\xbe\xb1" => "\xe1\xbe\xb9",
+ "\xe1\xbe\xb3" => "\xe1\xbe\xbc",
+ "\xe1\xbe\xbe" => "\xce\x99",
+ "\xe1\xbf\x83" => "\xe1\xbf\x8c",
+ "\xe1\xbf\x90" => "\xe1\xbf\x98",
+ "\xe1\xbf\x91" => "\xe1\xbf\x99",
+ "\xe1\xbf\xa0" => "\xe1\xbf\xa8",
+ "\xe1\xbf\xa1" => "\xe1\xbf\xa9",
+ "\xe1\xbf\xa5" => "\xe1\xbf\xac",
+ "\xe1\xbf\xb3" => "\xe1\xbf\xbc",
+ "\xe2\x85\xb0" => "\xe2\x85\xa0",
+ "\xe2\x85\xb1" => "\xe2\x85\xa1",
+ "\xe2\x85\xb2" => "\xe2\x85\xa2",
+ "\xe2\x85\xb3" => "\xe2\x85\xa3",
+ "\xe2\x85\xb4" => "\xe2\x85\xa4",
+ "\xe2\x85\xb5" => "\xe2\x85\xa5",
+ "\xe2\x85\xb6" => "\xe2\x85\xa6",
+ "\xe2\x85\xb7" => "\xe2\x85\xa7",
+ "\xe2\x85\xb8" => "\xe2\x85\xa8",
+ "\xe2\x85\xb9" => "\xe2\x85\xa9",
+ "\xe2\x85\xba" => "\xe2\x85\xaa",
+ "\xe2\x85\xbb" => "\xe2\x85\xab",
+ "\xe2\x85\xbc" => "\xe2\x85\xac",
+ "\xe2\x85\xbd" => "\xe2\x85\xad",
+ "\xe2\x85\xbe" => "\xe2\x85\xae",
+ "\xe2\x85\xbf" => "\xe2\x85\xaf",
+ "\xe2\x93\x90" => "\xe2\x92\xb6",
+ "\xe2\x93\x91" => "\xe2\x92\xb7",
+ "\xe2\x93\x92" => "\xe2\x92\xb8",
+ "\xe2\x93\x93" => "\xe2\x92\xb9",
+ "\xe2\x93\x94" => "\xe2\x92\xba",
+ "\xe2\x93\x95" => "\xe2\x92\xbb",
+ "\xe2\x93\x96" => "\xe2\x92\xbc",
+ "\xe2\x93\x97" => "\xe2\x92\xbd",
+ "\xe2\x93\x98" => "\xe2\x92\xbe",
+ "\xe2\x93\x99" => "\xe2\x92\xbf",
+ "\xe2\x93\x9a" => "\xe2\x93\x80",
+ "\xe2\x93\x9b" => "\xe2\x93\x81",
+ "\xe2\x93\x9c" => "\xe2\x93\x82",
+ "\xe2\x93\x9d" => "\xe2\x93\x83",
+ "\xe2\x93\x9e" => "\xe2\x93\x84",
+ "\xe2\x93\x9f" => "\xe2\x93\x85",
+ "\xe2\x93\xa0" => "\xe2\x93\x86",
+ "\xe2\x93\xa1" => "\xe2\x93\x87",
+ "\xe2\x93\xa2" => "\xe2\x93\x88",
+ "\xe2\x93\xa3" => "\xe2\x93\x89",
+ "\xe2\x93\xa4" => "\xe2\x93\x8a",
+ "\xe2\x93\xa5" => "\xe2\x93\x8b",
+ "\xe2\x93\xa6" => "\xe2\x93\x8c",
+ "\xe2\x93\xa7" => "\xe2\x93\x8d",
+ "\xe2\x93\xa8" => "\xe2\x93\x8e",
+ "\xe2\x93\xa9" => "\xe2\x93\x8f",
+ "\xef\xbd\x81" => "\xef\xbc\xa1",
+ "\xef\xbd\x82" => "\xef\xbc\xa2",
+ "\xef\xbd\x83" => "\xef\xbc\xa3",
+ "\xef\xbd\x84" => "\xef\xbc\xa4",
+ "\xef\xbd\x85" => "\xef\xbc\xa5",
+ "\xef\xbd\x86" => "\xef\xbc\xa6",
+ "\xef\xbd\x87" => "\xef\xbc\xa7",
+ "\xef\xbd\x88" => "\xef\xbc\xa8",
+ "\xef\xbd\x89" => "\xef\xbc\xa9",
+ "\xef\xbd\x8a" => "\xef\xbc\xaa",
+ "\xef\xbd\x8b" => "\xef\xbc\xab",
+ "\xef\xbd\x8c" => "\xef\xbc\xac",
+ "\xef\xbd\x8d" => "\xef\xbc\xad",
+ "\xef\xbd\x8e" => "\xef\xbc\xae",
+ "\xef\xbd\x8f" => "\xef\xbc\xaf",
+ "\xef\xbd\x90" => "\xef\xbc\xb0",
+ "\xef\xbd\x91" => "\xef\xbc\xb1",
+ "\xef\xbd\x92" => "\xef\xbc\xb2",
+ "\xef\xbd\x93" => "\xef\xbc\xb3",
+ "\xef\xbd\x94" => "\xef\xbc\xb4",
+ "\xef\xbd\x95" => "\xef\xbc\xb5",
+ "\xef\xbd\x96" => "\xef\xbc\xb6",
+ "\xef\xbd\x97" => "\xef\xbc\xb7",
+ "\xef\xbd\x98" => "\xef\xbc\xb8",
+ "\xef\xbd\x99" => "\xef\xbc\xb9",
+ "\xef\xbd\x9a" => "\xef\xbc\xba",
+ "\xf0\x90\x90\xa8" => "\xf0\x90\x90\x80",
+ "\xf0\x90\x90\xa9" => "\xf0\x90\x90\x81",
+ "\xf0\x90\x90\xaa" => "\xf0\x90\x90\x82",
+ "\xf0\x90\x90\xab" => "\xf0\x90\x90\x83",
+ "\xf0\x90\x90\xac" => "\xf0\x90\x90\x84",
+ "\xf0\x90\x90\xad" => "\xf0\x90\x90\x85",
+ "\xf0\x90\x90\xae" => "\xf0\x90\x90\x86",
+ "\xf0\x90\x90\xaf" => "\xf0\x90\x90\x87",
+ "\xf0\x90\x90\xb0" => "\xf0\x90\x90\x88",
+ "\xf0\x90\x90\xb1" => "\xf0\x90\x90\x89",
+ "\xf0\x90\x90\xb2" => "\xf0\x90\x90\x8a",
+ "\xf0\x90\x90\xb3" => "\xf0\x90\x90\x8b",
+ "\xf0\x90\x90\xb4" => "\xf0\x90\x90\x8c",
+ "\xf0\x90\x90\xb5" => "\xf0\x90\x90\x8d",
+ "\xf0\x90\x90\xb6" => "\xf0\x90\x90\x8e",
+ "\xf0\x90\x90\xb7" => "\xf0\x90\x90\x8f",
+ "\xf0\x90\x90\xb8" => "\xf0\x90\x90\x90",
+ "\xf0\x90\x90\xb9" => "\xf0\x90\x90\x91",
+ "\xf0\x90\x90\xba" => "\xf0\x90\x90\x92",
+ "\xf0\x90\x90\xbb" => "\xf0\x90\x90\x93",
+ "\xf0\x90\x90\xbc" => "\xf0\x90\x90\x94",
+ "\xf0\x90\x90\xbd" => "\xf0\x90\x90\x95",
+ "\xf0\x90\x90\xbe" => "\xf0\x90\x90\x96",
+ "\xf0\x90\x90\xbf" => "\xf0\x90\x90\x97",
+ "\xf0\x90\x91\x80" => "\xf0\x90\x90\x98",
+ "\xf0\x90\x91\x81" => "\xf0\x90\x90\x99",
+ "\xf0\x90\x91\x82" => "\xf0\x90\x90\x9a",
+ "\xf0\x90\x91\x83" => "\xf0\x90\x90\x9b",
+ "\xf0\x90\x91\x84" => "\xf0\x90\x90\x9c",
+ "\xf0\x90\x91\x85" => "\xf0\x90\x90\x9d",
+ "\xf0\x90\x91\x86" => "\xf0\x90\x90\x9e",
+ "\xf0\x90\x91\x87" => "\xf0\x90\x90\x9f",
+ "\xf0\x90\x91\x88" => "\xf0\x90\x90\xa0",
+ "\xf0\x90\x91\x89" => "\xf0\x90\x90\xa1",
+ "\xf0\x90\x91\x8a" => "\xf0\x90\x90\xa2",
+ "\xf0\x90\x91\x8b" => "\xf0\x90\x90\xa3",
+ "\xf0\x90\x91\x8c" => "\xf0\x90\x90\xa4",
+ "\xf0\x90\x91\x8d" => "\xf0\x90\x90\xa5"
+);
+
+/*
+ * Translation array to get lower case character
+ */
+$wikiLowerChars = array (
+ "A" => "a",
+ "B" => "b",
+ "C" => "c",
+ "D" => "d",
+ "E" => "e",
+ "F" => "f",
+ "G" => "g",
+ "H" => "h",
+ "I" => "i",
+ "J" => "j",
+ "K" => "k",
+ "L" => "l",
+ "M" => "m",
+ "N" => "n",
+ "O" => "o",
+ "P" => "p",
+ "Q" => "q",
+ "R" => "r",
+ "S" => "s",
+ "T" => "t",
+ "U" => "u",
+ "V" => "v",
+ "W" => "w",
+ "X" => "x",
+ "Y" => "y",
+ "Z" => "z",
+ "\xc3\x80" => "\xc3\xa0",
+ "\xc3\x81" => "\xc3\xa1",
+ "\xc3\x82" => "\xc3\xa2",
+ "\xc3\x83" => "\xc3\xa3",
+ "\xc3\x84" => "\xc3\xa4",
+ "\xc3\x85" => "\xc3\xa5",
+ "\xc3\x86" => "\xc3\xa6",
+ "\xc3\x87" => "\xc3\xa7",
+ "\xc3\x88" => "\xc3\xa8",
+ "\xc3\x89" => "\xc3\xa9",
+ "\xc3\x8a" => "\xc3\xaa",
+ "\xc3\x8b" => "\xc3\xab",
+ "\xc3\x8c" => "\xc3\xac",
+ "\xc3\x8d" => "\xc3\xad",
+ "\xc3\x8e" => "\xc3\xae",
+ "\xc3\x8f" => "\xc3\xaf",
+ "\xc3\x90" => "\xc3\xb0",
+ "\xc3\x91" => "\xc3\xb1",
+ "\xc3\x92" => "\xc3\xb2",
+ "\xc3\x93" => "\xc3\xb3",
+ "\xc3\x94" => "\xc3\xb4",
+ "\xc3\x95" => "\xc3\xb5",
+ "\xc3\x96" => "\xc3\xb6",
+ "\xc3\x98" => "\xc3\xb8",
+ "\xc3\x99" => "\xc3\xb9",
+ "\xc3\x9a" => "\xc3\xba",
+ "\xc3\x9b" => "\xc3\xbb",
+ "\xc3\x9c" => "\xc3\xbc",
+ "\xc3\x9d" => "\xc3\xbd",
+ "\xc3\x9e" => "\xc3\xbe",
+ "\xc4\x80" => "\xc4\x81",
+ "\xc4\x82" => "\xc4\x83",
+ "\xc4\x84" => "\xc4\x85",
+ "\xc4\x86" => "\xc4\x87",
+ "\xc4\x88" => "\xc4\x89",
+ "\xc4\x8a" => "\xc4\x8b",
+ "\xc4\x8c" => "\xc4\x8d",
+ "\xc4\x8e" => "\xc4\x8f",
+ "\xc4\x90" => "\xc4\x91",
+ "\xc4\x92" => "\xc4\x93",
+ "\xc4\x94" => "\xc4\x95",
+ "\xc4\x96" => "\xc4\x97",
+ "\xc4\x98" => "\xc4\x99",
+ "\xc4\x9a" => "\xc4\x9b",
+ "\xc4\x9c" => "\xc4\x9d",
+ "\xc4\x9e" => "\xc4\x9f",
+ "\xc4\xa0" => "\xc4\xa1",
+ "\xc4\xa2" => "\xc4\xa3",
+ "\xc4\xa4" => "\xc4\xa5",
+ "\xc4\xa6" => "\xc4\xa7",
+ "\xc4\xa8" => "\xc4\xa9",
+ "\xc4\xaa" => "\xc4\xab",
+ "\xc4\xac" => "\xc4\xad",
+ "\xc4\xae" => "\xc4\xaf",
+ "\xc4\xb0" => "i",
+ "\xc4\xb2" => "\xc4\xb3",
+ "\xc4\xb4" => "\xc4\xb5",
+ "\xc4\xb6" => "\xc4\xb7",
+ "\xc4\xb9" => "\xc4\xba",
+ "\xc4\xbb" => "\xc4\xbc",
+ "\xc4\xbd" => "\xc4\xbe",
+ "\xc4\xbf" => "\xc5\x80",
+ "\xc5\x81" => "\xc5\x82",
+ "\xc5\x83" => "\xc5\x84",
+ "\xc5\x85" => "\xc5\x86",
+ "\xc5\x87" => "\xc5\x88",
+ "\xc5\x8a" => "\xc5\x8b",
+ "\xc5\x8c" => "\xc5\x8d",
+ "\xc5\x8e" => "\xc5\x8f",
+ "\xc5\x90" => "\xc5\x91",
+ "\xc5\x92" => "\xc5\x93",
+ "\xc5\x94" => "\xc5\x95",
+ "\xc5\x96" => "\xc5\x97",
+ "\xc5\x98" => "\xc5\x99",
+ "\xc5\x9a" => "\xc5\x9b",
+ "\xc5\x9c" => "\xc5\x9d",
+ "\xc5\x9e" => "\xc5\x9f",
+ "\xc5\xa0" => "\xc5\xa1",
+ "\xc5\xa2" => "\xc5\xa3",
+ "\xc5\xa4" => "\xc5\xa5",
+ "\xc5\xa6" => "\xc5\xa7",
+ "\xc5\xa8" => "\xc5\xa9",
+ "\xc5\xaa" => "\xc5\xab",
+ "\xc5\xac" => "\xc5\xad",
+ "\xc5\xae" => "\xc5\xaf",
+ "\xc5\xb0" => "\xc5\xb1",
+ "\xc5\xb2" => "\xc5\xb3",
+ "\xc5\xb4" => "\xc5\xb5",
+ "\xc5\xb6" => "\xc5\xb7",
+ "\xc5\xb8" => "\xc3\xbf",
+ "\xc5\xb9" => "\xc5\xba",
+ "\xc5\xbb" => "\xc5\xbc",
+ "\xc5\xbd" => "\xc5\xbe",
+ "\xc6\x81" => "\xc9\x93",
+ "\xc6\x82" => "\xc6\x83",
+ "\xc6\x84" => "\xc6\x85",
+ "\xc6\x86" => "\xc9\x94",
+ "\xc6\x87" => "\xc6\x88",
+ "\xc6\x89" => "\xc9\x96",
+ "\xc6\x8a" => "\xc9\x97",
+ "\xc6\x8b" => "\xc6\x8c",
+ "\xc6\x8e" => "\xc7\x9d",
+ "\xc6\x8f" => "\xc9\x99",
+ "\xc6\x90" => "\xc9\x9b",
+ "\xc6\x91" => "\xc6\x92",
+ "\xc6\x93" => "\xc9\xa0",
+ "\xc6\x94" => "\xc9\xa3",
+ "\xc6\x96" => "\xc9\xa9",
+ "\xc6\x97" => "\xc9\xa8",
+ "\xc6\x98" => "\xc6\x99",
+ "\xc6\x9c" => "\xc9\xaf",
+ "\xc6\x9d" => "\xc9\xb2",
+ "\xc6\x9f" => "\xc9\xb5",
+ "\xc6\xa0" => "\xc6\xa1",
+ "\xc6\xa2" => "\xc6\xa3",
+ "\xc6\xa4" => "\xc6\xa5",
+ "\xc6\xa6" => "\xca\x80",
+ "\xc6\xa7" => "\xc6\xa8",
+ "\xc6\xa9" => "\xca\x83",
+ "\xc6\xac" => "\xc6\xad",
+ "\xc6\xae" => "\xca\x88",
+ "\xc6\xaf" => "\xc6\xb0",
+ "\xc6\xb1" => "\xca\x8a",
+ "\xc6\xb2" => "\xca\x8b",
+ "\xc6\xb3" => "\xc6\xb4",
+ "\xc6\xb5" => "\xc6\xb6",
+ "\xc6\xb7" => "\xca\x92",
+ "\xc6\xb8" => "\xc6\xb9",
+ "\xc6\xbc" => "\xc6\xbd",
+ "\xc7\x84" => "\xc7\x86",
+ "\xc7\x85" => "\xc7\x86",
+ "\xc7\x87" => "\xc7\x89",
+ "\xc7\x88" => "\xc7\x89",
+ "\xc7\x8a" => "\xc7\x8c",
+ "\xc7\x8b" => "\xc7\x8c",
+ "\xc7\x8d" => "\xc7\x8e",
+ "\xc7\x8f" => "\xc7\x90",
+ "\xc7\x91" => "\xc7\x92",
+ "\xc7\x93" => "\xc7\x94",
+ "\xc7\x95" => "\xc7\x96",
+ "\xc7\x97" => "\xc7\x98",
+ "\xc7\x99" => "\xc7\x9a",
+ "\xc7\x9b" => "\xc7\x9c",
+ "\xc7\x9e" => "\xc7\x9f",
+ "\xc7\xa0" => "\xc7\xa1",
+ "\xc7\xa2" => "\xc7\xa3",
+ "\xc7\xa4" => "\xc7\xa5",
+ "\xc7\xa6" => "\xc7\xa7",
+ "\xc7\xa8" => "\xc7\xa9",
+ "\xc7\xaa" => "\xc7\xab",
+ "\xc7\xac" => "\xc7\xad",
+ "\xc7\xae" => "\xc7\xaf",
+ "\xc7\xb1" => "\xc7\xb3",
+ "\xc7\xb2" => "\xc7\xb3",
+ "\xc7\xb4" => "\xc7\xb5",
+ "\xc7\xb6" => "\xc6\x95",
+ "\xc7\xb7" => "\xc6\xbf",
+ "\xc7\xb8" => "\xc7\xb9",
+ "\xc7\xba" => "\xc7\xbb",
+ "\xc7\xbc" => "\xc7\xbd",
+ "\xc7\xbe" => "\xc7\xbf",
+ "\xc8\x80" => "\xc8\x81",
+ "\xc8\x82" => "\xc8\x83",
+ "\xc8\x84" => "\xc8\x85",
+ "\xc8\x86" => "\xc8\x87",
+ "\xc8\x88" => "\xc8\x89",
+ "\xc8\x8a" => "\xc8\x8b",
+ "\xc8\x8c" => "\xc8\x8d",
+ "\xc8\x8e" => "\xc8\x8f",
+ "\xc8\x90" => "\xc8\x91",
+ "\xc8\x92" => "\xc8\x93",
+ "\xc8\x94" => "\xc8\x95",
+ "\xc8\x96" => "\xc8\x97",
+ "\xc8\x98" => "\xc8\x99",
+ "\xc8\x9a" => "\xc8\x9b",
+ "\xc8\x9c" => "\xc8\x9d",
+ "\xc8\x9e" => "\xc8\x9f",
+ "\xc8\xa2" => "\xc8\xa3",
+ "\xc8\xa4" => "\xc8\xa5",
+ "\xc8\xa6" => "\xc8\xa7",
+ "\xc8\xa8" => "\xc8\xa9",
+ "\xc8\xaa" => "\xc8\xab",
+ "\xc8\xac" => "\xc8\xad",
+ "\xc8\xae" => "\xc8\xaf",
+ "\xc8\xb0" => "\xc8\xb1",
+ "\xc8\xb2" => "\xc8\xb3",
+ "\xce\x86" => "\xce\xac",
+ "\xce\x88" => "\xce\xad",
+ "\xce\x89" => "\xce\xae",
+ "\xce\x8a" => "\xce\xaf",
+ "\xce\x8c" => "\xcf\x8c",
+ "\xce\x8e" => "\xcf\x8d",
+ "\xce\x8f" => "\xcf\x8e",
+ "\xce\x91" => "\xce\xb1",
+ "\xce\x92" => "\xce\xb2",
+ "\xce\x93" => "\xce\xb3",
+ "\xce\x94" => "\xce\xb4",
+ "\xce\x95" => "\xce\xb5",
+ "\xce\x96" => "\xce\xb6",
+ "\xce\x97" => "\xce\xb7",
+ "\xce\x98" => "\xce\xb8",
+ "\xce\x99" => "\xce\xb9",
+ "\xce\x9a" => "\xce\xba",
+ "\xce\x9b" => "\xce\xbb",
+ "\xce\x9c" => "\xce\xbc",
+ "\xce\x9d" => "\xce\xbd",
+ "\xce\x9e" => "\xce\xbe",
+ "\xce\x9f" => "\xce\xbf",
+ "\xce\xa0" => "\xcf\x80",
+ "\xce\xa1" => "\xcf\x81",
+ "\xce\xa3" => "\xcf\x83",
+ "\xce\xa4" => "\xcf\x84",
+ "\xce\xa5" => "\xcf\x85",
+ "\xce\xa6" => "\xcf\x86",
+ "\xce\xa7" => "\xcf\x87",
+ "\xce\xa8" => "\xcf\x88",
+ "\xce\xa9" => "\xcf\x89",
+ "\xce\xaa" => "\xcf\x8a",
+ "\xce\xab" => "\xcf\x8b",
+ "\xcf\x9a" => "\xcf\x9b",
+ "\xcf\x9c" => "\xcf\x9d",
+ "\xcf\x9e" => "\xcf\x9f",
+ "\xcf\xa0" => "\xcf\xa1",
+ "\xcf\xa2" => "\xcf\xa3",
+ "\xcf\xa4" => "\xcf\xa5",
+ "\xcf\xa6" => "\xcf\xa7",
+ "\xcf\xa8" => "\xcf\xa9",
+ "\xcf\xaa" => "\xcf\xab",
+ "\xcf\xac" => "\xcf\xad",
+ "\xcf\xae" => "\xcf\xaf",
+ "\xcf\xb4" => "\xce\xb8",
+ "\xd0\x80" => "\xd1\x90",
+ "\xd0\x81" => "\xd1\x91",
+ "\xd0\x82" => "\xd1\x92",
+ "\xd0\x83" => "\xd1\x93",
+ "\xd0\x84" => "\xd1\x94",
+ "\xd0\x85" => "\xd1\x95",
+ "\xd0\x86" => "\xd1\x96",
+ "\xd0\x87" => "\xd1\x97",
+ "\xd0\x88" => "\xd1\x98",
+ "\xd0\x89" => "\xd1\x99",
+ "\xd0\x8a" => "\xd1\x9a",
+ "\xd0\x8b" => "\xd1\x9b",
+ "\xd0\x8c" => "\xd1\x9c",
+ "\xd0\x8d" => "\xd1\x9d",
+ "\xd0\x8e" => "\xd1\x9e",
+ "\xd0\x8f" => "\xd1\x9f",
+ "\xd0\x90" => "\xd0\xb0",
+ "\xd0\x91" => "\xd0\xb1",
+ "\xd0\x92" => "\xd0\xb2",
+ "\xd0\x93" => "\xd0\xb3",
+ "\xd0\x94" => "\xd0\xb4",
+ "\xd0\x95" => "\xd0\xb5",
+ "\xd0\x96" => "\xd0\xb6",
+ "\xd0\x97" => "\xd0\xb7",
+ "\xd0\x98" => "\xd0\xb8",
+ "\xd0\x99" => "\xd0\xb9",
+ "\xd0\x9a" => "\xd0\xba",
+ "\xd0\x9b" => "\xd0\xbb",
+ "\xd0\x9c" => "\xd0\xbc",
+ "\xd0\x9d" => "\xd0\xbd",
+ "\xd0\x9e" => "\xd0\xbe",
+ "\xd0\x9f" => "\xd0\xbf",
+ "\xd0\xa0" => "\xd1\x80",
+ "\xd0\xa1" => "\xd1\x81",
+ "\xd0\xa2" => "\xd1\x82",
+ "\xd0\xa3" => "\xd1\x83",
+ "\xd0\xa4" => "\xd1\x84",
+ "\xd0\xa5" => "\xd1\x85",
+ "\xd0\xa6" => "\xd1\x86",
+ "\xd0\xa7" => "\xd1\x87",
+ "\xd0\xa8" => "\xd1\x88",
+ "\xd0\xa9" => "\xd1\x89",
+ "\xd0\xaa" => "\xd1\x8a",
+ "\xd0\xab" => "\xd1\x8b",
+ "\xd0\xac" => "\xd1\x8c",
+ "\xd0\xad" => "\xd1\x8d",
+ "\xd0\xae" => "\xd1\x8e",
+ "\xd0\xaf" => "\xd1\x8f",
+ "\xd1\xa0" => "\xd1\xa1",
+ "\xd1\xa2" => "\xd1\xa3",
+ "\xd1\xa4" => "\xd1\xa5",
+ "\xd1\xa6" => "\xd1\xa7",
+ "\xd1\xa8" => "\xd1\xa9",
+ "\xd1\xaa" => "\xd1\xab",
+ "\xd1\xac" => "\xd1\xad",
+ "\xd1\xae" => "\xd1\xaf",
+ "\xd1\xb0" => "\xd1\xb1",
+ "\xd1\xb2" => "\xd1\xb3",
+ "\xd1\xb4" => "\xd1\xb5",
+ "\xd1\xb6" => "\xd1\xb7",
+ "\xd1\xb8" => "\xd1\xb9",
+ "\xd1\xba" => "\xd1\xbb",
+ "\xd1\xbc" => "\xd1\xbd",
+ "\xd1\xbe" => "\xd1\xbf",
+ "\xd2\x80" => "\xd2\x81",
+ "\xd2\x8c" => "\xd2\x8d",
+ "\xd2\x8e" => "\xd2\x8f",
+ "\xd2\x90" => "\xd2\x91",
+ "\xd2\x92" => "\xd2\x93",
+ "\xd2\x94" => "\xd2\x95",
+ "\xd2\x96" => "\xd2\x97",
+ "\xd2\x98" => "\xd2\x99",
+ "\xd2\x9a" => "\xd2\x9b",
+ "\xd2\x9c" => "\xd2\x9d",
+ "\xd2\x9e" => "\xd2\x9f",
+ "\xd2\xa0" => "\xd2\xa1",
+ "\xd2\xa2" => "\xd2\xa3",
+ "\xd2\xa4" => "\xd2\xa5",
+ "\xd2\xa6" => "\xd2\xa7",
+ "\xd2\xa8" => "\xd2\xa9",
+ "\xd2\xaa" => "\xd2\xab",
+ "\xd2\xac" => "\xd2\xad",
+ "\xd2\xae" => "\xd2\xaf",
+ "\xd2\xb0" => "\xd2\xb1",
+ "\xd2\xb2" => "\xd2\xb3",
+ "\xd2\xb4" => "\xd2\xb5",
+ "\xd2\xb6" => "\xd2\xb7",
+ "\xd2\xb8" => "\xd2\xb9",
+ "\xd2\xba" => "\xd2\xbb",
+ "\xd2\xbc" => "\xd2\xbd",
+ "\xd2\xbe" => "\xd2\xbf",
+ "\xd3\x81" => "\xd3\x82",
+ "\xd3\x83" => "\xd3\x84",
+ "\xd3\x87" => "\xd3\x88",
+ "\xd3\x8b" => "\xd3\x8c",
+ "\xd3\x90" => "\xd3\x91",
+ "\xd3\x92" => "\xd3\x93",
+ "\xd3\x94" => "\xd3\x95",
+ "\xd3\x96" => "\xd3\x97",
+ "\xd3\x98" => "\xd3\x99",
+ "\xd3\x9a" => "\xd3\x9b",
+ "\xd3\x9c" => "\xd3\x9d",
+ "\xd3\x9e" => "\xd3\x9f",
+ "\xd3\xa0" => "\xd3\xa1",
+ "\xd3\xa2" => "\xd3\xa3",
+ "\xd3\xa4" => "\xd3\xa5",
+ "\xd3\xa6" => "\xd3\xa7",
+ "\xd3\xa8" => "\xd3\xa9",
+ "\xd3\xaa" => "\xd3\xab",
+ "\xd3\xac" => "\xd3\xad",
+ "\xd3\xae" => "\xd3\xaf",
+ "\xd3\xb0" => "\xd3\xb1",
+ "\xd3\xb2" => "\xd3\xb3",
+ "\xd3\xb4" => "\xd3\xb5",
+ "\xd3\xb8" => "\xd3\xb9",
+ "\xd4\xb1" => "\xd5\xa1",
+ "\xd4\xb2" => "\xd5\xa2",
+ "\xd4\xb3" => "\xd5\xa3",
+ "\xd4\xb4" => "\xd5\xa4",
+ "\xd4\xb5" => "\xd5\xa5",
+ "\xd4\xb6" => "\xd5\xa6",
+ "\xd4\xb7" => "\xd5\xa7",
+ "\xd4\xb8" => "\xd5\xa8",
+ "\xd4\xb9" => "\xd5\xa9",
+ "\xd4\xba" => "\xd5\xaa",
+ "\xd4\xbb" => "\xd5\xab",
+ "\xd4\xbc" => "\xd5\xac",
+ "\xd4\xbd" => "\xd5\xad",
+ "\xd4\xbe" => "\xd5\xae",
+ "\xd4\xbf" => "\xd5\xaf",
+ "\xd5\x80" => "\xd5\xb0",
+ "\xd5\x81" => "\xd5\xb1",
+ "\xd5\x82" => "\xd5\xb2",
+ "\xd5\x83" => "\xd5\xb3",
+ "\xd5\x84" => "\xd5\xb4",
+ "\xd5\x85" => "\xd5\xb5",
+ "\xd5\x86" => "\xd5\xb6",
+ "\xd5\x87" => "\xd5\xb7",
+ "\xd5\x88" => "\xd5\xb8",
+ "\xd5\x89" => "\xd5\xb9",
+ "\xd5\x8a" => "\xd5\xba",
+ "\xd5\x8b" => "\xd5\xbb",
+ "\xd5\x8c" => "\xd5\xbc",
+ "\xd5\x8d" => "\xd5\xbd",
+ "\xd5\x8e" => "\xd5\xbe",
+ "\xd5\x8f" => "\xd5\xbf",
+ "\xd5\x90" => "\xd6\x80",
+ "\xd5\x91" => "\xd6\x81",
+ "\xd5\x92" => "\xd6\x82",
+ "\xd5\x93" => "\xd6\x83",
+ "\xd5\x94" => "\xd6\x84",
+ "\xd5\x95" => "\xd6\x85",
+ "\xd5\x96" => "\xd6\x86",
+ "\xe1\xb8\x80" => "\xe1\xb8\x81",
+ "\xe1\xb8\x82" => "\xe1\xb8\x83",
+ "\xe1\xb8\x84" => "\xe1\xb8\x85",
+ "\xe1\xb8\x86" => "\xe1\xb8\x87",
+ "\xe1\xb8\x88" => "\xe1\xb8\x89",
+ "\xe1\xb8\x8a" => "\xe1\xb8\x8b",
+ "\xe1\xb8\x8c" => "\xe1\xb8\x8d",
+ "\xe1\xb8\x8e" => "\xe1\xb8\x8f",
+ "\xe1\xb8\x90" => "\xe1\xb8\x91",
+ "\xe1\xb8\x92" => "\xe1\xb8\x93",
+ "\xe1\xb8\x94" => "\xe1\xb8\x95",
+ "\xe1\xb8\x96" => "\xe1\xb8\x97",
+ "\xe1\xb8\x98" => "\xe1\xb8\x99",
+ "\xe1\xb8\x9a" => "\xe1\xb8\x9b",
+ "\xe1\xb8\x9c" => "\xe1\xb8\x9d",
+ "\xe1\xb8\x9e" => "\xe1\xb8\x9f",
+ "\xe1\xb8\xa0" => "\xe1\xb8\xa1",
+ "\xe1\xb8\xa2" => "\xe1\xb8\xa3",
+ "\xe1\xb8\xa4" => "\xe1\xb8\xa5",
+ "\xe1\xb8\xa6" => "\xe1\xb8\xa7",
+ "\xe1\xb8\xa8" => "\xe1\xb8\xa9",
+ "\xe1\xb8\xaa" => "\xe1\xb8\xab",
+ "\xe1\xb8\xac" => "\xe1\xb8\xad",
+ "\xe1\xb8\xae" => "\xe1\xb8\xaf",
+ "\xe1\xb8\xb0" => "\xe1\xb8\xb1",
+ "\xe1\xb8\xb2" => "\xe1\xb8\xb3",
+ "\xe1\xb8\xb4" => "\xe1\xb8\xb5",
+ "\xe1\xb8\xb6" => "\xe1\xb8\xb7",
+ "\xe1\xb8\xb8" => "\xe1\xb8\xb9",
+ "\xe1\xb8\xba" => "\xe1\xb8\xbb",
+ "\xe1\xb8\xbc" => "\xe1\xb8\xbd",
+ "\xe1\xb8\xbe" => "\xe1\xb8\xbf",
+ "\xe1\xb9\x80" => "\xe1\xb9\x81",
+ "\xe1\xb9\x82" => "\xe1\xb9\x83",
+ "\xe1\xb9\x84" => "\xe1\xb9\x85",
+ "\xe1\xb9\x86" => "\xe1\xb9\x87",
+ "\xe1\xb9\x88" => "\xe1\xb9\x89",
+ "\xe1\xb9\x8a" => "\xe1\xb9\x8b",
+ "\xe1\xb9\x8c" => "\xe1\xb9\x8d",
+ "\xe1\xb9\x8e" => "\xe1\xb9\x8f",
+ "\xe1\xb9\x90" => "\xe1\xb9\x91",
+ "\xe1\xb9\x92" => "\xe1\xb9\x93",
+ "\xe1\xb9\x94" => "\xe1\xb9\x95",
+ "\xe1\xb9\x96" => "\xe1\xb9\x97",
+ "\xe1\xb9\x98" => "\xe1\xb9\x99",
+ "\xe1\xb9\x9a" => "\xe1\xb9\x9b",
+ "\xe1\xb9\x9c" => "\xe1\xb9\x9d",
+ "\xe1\xb9\x9e" => "\xe1\xb9\x9f",
+ "\xe1\xb9\xa0" => "\xe1\xb9\xa1",
+ "\xe1\xb9\xa2" => "\xe1\xb9\xa3",
+ "\xe1\xb9\xa4" => "\xe1\xb9\xa5",
+ "\xe1\xb9\xa6" => "\xe1\xb9\xa7",
+ "\xe1\xb9\xa8" => "\xe1\xb9\xa9",
+ "\xe1\xb9\xaa" => "\xe1\xb9\xab",
+ "\xe1\xb9\xac" => "\xe1\xb9\xad",
+ "\xe1\xb9\xae" => "\xe1\xb9\xaf",
+ "\xe1\xb9\xb0" => "\xe1\xb9\xb1",
+ "\xe1\xb9\xb2" => "\xe1\xb9\xb3",
+ "\xe1\xb9\xb4" => "\xe1\xb9\xb5",
+ "\xe1\xb9\xb6" => "\xe1\xb9\xb7",
+ "\xe1\xb9\xb8" => "\xe1\xb9\xb9",
+ "\xe1\xb9\xba" => "\xe1\xb9\xbb",
+ "\xe1\xb9\xbc" => "\xe1\xb9\xbd",
+ "\xe1\xb9\xbe" => "\xe1\xb9\xbf",
+ "\xe1\xba\x80" => "\xe1\xba\x81",
+ "\xe1\xba\x82" => "\xe1\xba\x83",
+ "\xe1\xba\x84" => "\xe1\xba\x85",
+ "\xe1\xba\x86" => "\xe1\xba\x87",
+ "\xe1\xba\x88" => "\xe1\xba\x89",
+ "\xe1\xba\x8a" => "\xe1\xba\x8b",
+ "\xe1\xba\x8c" => "\xe1\xba\x8d",
+ "\xe1\xba\x8e" => "\xe1\xba\x8f",
+ "\xe1\xba\x90" => "\xe1\xba\x91",
+ "\xe1\xba\x92" => "\xe1\xba\x93",
+ "\xe1\xba\x94" => "\xe1\xba\x95",
+ "\xe1\xba\xa0" => "\xe1\xba\xa1",
+ "\xe1\xba\xa2" => "\xe1\xba\xa3",
+ "\xe1\xba\xa4" => "\xe1\xba\xa5",
+ "\xe1\xba\xa6" => "\xe1\xba\xa7",
+ "\xe1\xba\xa8" => "\xe1\xba\xa9",
+ "\xe1\xba\xaa" => "\xe1\xba\xab",
+ "\xe1\xba\xac" => "\xe1\xba\xad",
+ "\xe1\xba\xae" => "\xe1\xba\xaf",
+ "\xe1\xba\xb0" => "\xe1\xba\xb1",
+ "\xe1\xba\xb2" => "\xe1\xba\xb3",
+ "\xe1\xba\xb4" => "\xe1\xba\xb5",
+ "\xe1\xba\xb6" => "\xe1\xba\xb7",
+ "\xe1\xba\xb8" => "\xe1\xba\xb9",
+ "\xe1\xba\xba" => "\xe1\xba\xbb",
+ "\xe1\xba\xbc" => "\xe1\xba\xbd",
+ "\xe1\xba\xbe" => "\xe1\xba\xbf",
+ "\xe1\xbb\x80" => "\xe1\xbb\x81",
+ "\xe1\xbb\x82" => "\xe1\xbb\x83",
+ "\xe1\xbb\x84" => "\xe1\xbb\x85",
+ "\xe1\xbb\x86" => "\xe1\xbb\x87",
+ "\xe1\xbb\x88" => "\xe1\xbb\x89",
+ "\xe1\xbb\x8a" => "\xe1\xbb\x8b",
+ "\xe1\xbb\x8c" => "\xe1\xbb\x8d",
+ "\xe1\xbb\x8e" => "\xe1\xbb\x8f",
+ "\xe1\xbb\x90" => "\xe1\xbb\x91",
+ "\xe1\xbb\x92" => "\xe1\xbb\x93",
+ "\xe1\xbb\x94" => "\xe1\xbb\x95",
+ "\xe1\xbb\x96" => "\xe1\xbb\x97",
+ "\xe1\xbb\x98" => "\xe1\xbb\x99",
+ "\xe1\xbb\x9a" => "\xe1\xbb\x9b",
+ "\xe1\xbb\x9c" => "\xe1\xbb\x9d",
+ "\xe1\xbb\x9e" => "\xe1\xbb\x9f",
+ "\xe1\xbb\xa0" => "\xe1\xbb\xa1",
+ "\xe1\xbb\xa2" => "\xe1\xbb\xa3",
+ "\xe1\xbb\xa4" => "\xe1\xbb\xa5",
+ "\xe1\xbb\xa6" => "\xe1\xbb\xa7",
+ "\xe1\xbb\xa8" => "\xe1\xbb\xa9",
+ "\xe1\xbb\xaa" => "\xe1\xbb\xab",
+ "\xe1\xbb\xac" => "\xe1\xbb\xad",
+ "\xe1\xbb\xae" => "\xe1\xbb\xaf",
+ "\xe1\xbb\xb0" => "\xe1\xbb\xb1",
+ "\xe1\xbb\xb2" => "\xe1\xbb\xb3",
+ "\xe1\xbb\xb4" => "\xe1\xbb\xb5",
+ "\xe1\xbb\xb6" => "\xe1\xbb\xb7",
+ "\xe1\xbb\xb8" => "\xe1\xbb\xb9",
+ "\xe1\xbc\x88" => "\xe1\xbc\x80",
+ "\xe1\xbc\x89" => "\xe1\xbc\x81",
+ "\xe1\xbc\x8a" => "\xe1\xbc\x82",
+ "\xe1\xbc\x8b" => "\xe1\xbc\x83",
+ "\xe1\xbc\x8c" => "\xe1\xbc\x84",
+ "\xe1\xbc\x8d" => "\xe1\xbc\x85",
+ "\xe1\xbc\x8e" => "\xe1\xbc\x86",
+ "\xe1\xbc\x8f" => "\xe1\xbc\x87",
+ "\xe1\xbc\x98" => "\xe1\xbc\x90",
+ "\xe1\xbc\x99" => "\xe1\xbc\x91",
+ "\xe1\xbc\x9a" => "\xe1\xbc\x92",
+ "\xe1\xbc\x9b" => "\xe1\xbc\x93",
+ "\xe1\xbc\x9c" => "\xe1\xbc\x94",
+ "\xe1\xbc\x9d" => "\xe1\xbc\x95",
+ "\xe1\xbc\xa8" => "\xe1\xbc\xa0",
+ "\xe1\xbc\xa9" => "\xe1\xbc\xa1",
+ "\xe1\xbc\xaa" => "\xe1\xbc\xa2",
+ "\xe1\xbc\xab" => "\xe1\xbc\xa3",
+ "\xe1\xbc\xac" => "\xe1\xbc\xa4",
+ "\xe1\xbc\xad" => "\xe1\xbc\xa5",
+ "\xe1\xbc\xae" => "\xe1\xbc\xa6",
+ "\xe1\xbc\xaf" => "\xe1\xbc\xa7",
+ "\xe1\xbc\xb8" => "\xe1\xbc\xb0",
+ "\xe1\xbc\xb9" => "\xe1\xbc\xb1",
+ "\xe1\xbc\xba" => "\xe1\xbc\xb2",
+ "\xe1\xbc\xbb" => "\xe1\xbc\xb3",
+ "\xe1\xbc\xbc" => "\xe1\xbc\xb4",
+ "\xe1\xbc\xbd" => "\xe1\xbc\xb5",
+ "\xe1\xbc\xbe" => "\xe1\xbc\xb6",
+ "\xe1\xbc\xbf" => "\xe1\xbc\xb7",
+ "\xe1\xbd\x88" => "\xe1\xbd\x80",
+ "\xe1\xbd\x89" => "\xe1\xbd\x81",
+ "\xe1\xbd\x8a" => "\xe1\xbd\x82",
+ "\xe1\xbd\x8b" => "\xe1\xbd\x83",
+ "\xe1\xbd\x8c" => "\xe1\xbd\x84",
+ "\xe1\xbd\x8d" => "\xe1\xbd\x85",
+ "\xe1\xbd\x99" => "\xe1\xbd\x91",
+ "\xe1\xbd\x9b" => "\xe1\xbd\x93",
+ "\xe1\xbd\x9d" => "\xe1\xbd\x95",
+ "\xe1\xbd\x9f" => "\xe1\xbd\x97",
+ "\xe1\xbd\xa8" => "\xe1\xbd\xa0",
+ "\xe1\xbd\xa9" => "\xe1\xbd\xa1",
+ "\xe1\xbd\xaa" => "\xe1\xbd\xa2",
+ "\xe1\xbd\xab" => "\xe1\xbd\xa3",
+ "\xe1\xbd\xac" => "\xe1\xbd\xa4",
+ "\xe1\xbd\xad" => "\xe1\xbd\xa5",
+ "\xe1\xbd\xae" => "\xe1\xbd\xa6",
+ "\xe1\xbd\xaf" => "\xe1\xbd\xa7",
+ "\xe1\xbe\x88" => "\xe1\xbe\x80",
+ "\xe1\xbe\x89" => "\xe1\xbe\x81",
+ "\xe1\xbe\x8a" => "\xe1\xbe\x82",
+ "\xe1\xbe\x8b" => "\xe1\xbe\x83",
+ "\xe1\xbe\x8c" => "\xe1\xbe\x84",
+ "\xe1\xbe\x8d" => "\xe1\xbe\x85",
+ "\xe1\xbe\x8e" => "\xe1\xbe\x86",
+ "\xe1\xbe\x8f" => "\xe1\xbe\x87",
+ "\xe1\xbe\x98" => "\xe1\xbe\x90",
+ "\xe1\xbe\x99" => "\xe1\xbe\x91",
+ "\xe1\xbe\x9a" => "\xe1\xbe\x92",
+ "\xe1\xbe\x9b" => "\xe1\xbe\x93",
+ "\xe1\xbe\x9c" => "\xe1\xbe\x94",
+ "\xe1\xbe\x9d" => "\xe1\xbe\x95",
+ "\xe1\xbe\x9e" => "\xe1\xbe\x96",
+ "\xe1\xbe\x9f" => "\xe1\xbe\x97",
+ "\xe1\xbe\xa8" => "\xe1\xbe\xa0",
+ "\xe1\xbe\xa9" => "\xe1\xbe\xa1",
+ "\xe1\xbe\xaa" => "\xe1\xbe\xa2",
+ "\xe1\xbe\xab" => "\xe1\xbe\xa3",
+ "\xe1\xbe\xac" => "\xe1\xbe\xa4",
+ "\xe1\xbe\xad" => "\xe1\xbe\xa5",
+ "\xe1\xbe\xae" => "\xe1\xbe\xa6",
+ "\xe1\xbe\xaf" => "\xe1\xbe\xa7",
+ "\xe1\xbe\xb8" => "\xe1\xbe\xb0",
+ "\xe1\xbe\xb9" => "\xe1\xbe\xb1",
+ "\xe1\xbe\xba" => "\xe1\xbd\xb0",
+ "\xe1\xbe\xbb" => "\xe1\xbd\xb1",
+ "\xe1\xbe\xbc" => "\xe1\xbe\xb3",
+ "\xe1\xbf\x88" => "\xe1\xbd\xb2",
+ "\xe1\xbf\x89" => "\xe1\xbd\xb3",
+ "\xe1\xbf\x8a" => "\xe1\xbd\xb4",
+ "\xe1\xbf\x8b" => "\xe1\xbd\xb5",
+ "\xe1\xbf\x8c" => "\xe1\xbf\x83",
+ "\xe1\xbf\x98" => "\xe1\xbf\x90",
+ "\xe1\xbf\x99" => "\xe1\xbf\x91",
+ "\xe1\xbf\x9a" => "\xe1\xbd\xb6",
+ "\xe1\xbf\x9b" => "\xe1\xbd\xb7",
+ "\xe1\xbf\xa8" => "\xe1\xbf\xa0",
+ "\xe1\xbf\xa9" => "\xe1\xbf\xa1",
+ "\xe1\xbf\xaa" => "\xe1\xbd\xba",
+ "\xe1\xbf\xab" => "\xe1\xbd\xbb",
+ "\xe1\xbf\xac" => "\xe1\xbf\xa5",
+ "\xe1\xbf\xb8" => "\xe1\xbd\xb8",
+ "\xe1\xbf\xb9" => "\xe1\xbd\xb9",
+ "\xe1\xbf\xba" => "\xe1\xbd\xbc",
+ "\xe1\xbf\xbb" => "\xe1\xbd\xbd",
+ "\xe1\xbf\xbc" => "\xe1\xbf\xb3",
+ "\xe2\x84\xa6" => "\xcf\x89",
+ "\xe2\x84\xaa" => "k",
+ "\xe2\x84\xab" => "\xc3\xa5",
+ "\xe2\x85\xa0" => "\xe2\x85\xb0",
+ "\xe2\x85\xa1" => "\xe2\x85\xb1",
+ "\xe2\x85\xa2" => "\xe2\x85\xb2",
+ "\xe2\x85\xa3" => "\xe2\x85\xb3",
+ "\xe2\x85\xa4" => "\xe2\x85\xb4",
+ "\xe2\x85\xa5" => "\xe2\x85\xb5",
+ "\xe2\x85\xa6" => "\xe2\x85\xb6",
+ "\xe2\x85\xa7" => "\xe2\x85\xb7",
+ "\xe2\x85\xa8" => "\xe2\x85\xb8",
+ "\xe2\x85\xa9" => "\xe2\x85\xb9",
+ "\xe2\x85\xaa" => "\xe2\x85\xba",
+ "\xe2\x85\xab" => "\xe2\x85\xbb",
+ "\xe2\x85\xac" => "\xe2\x85\xbc",
+ "\xe2\x85\xad" => "\xe2\x85\xbd",
+ "\xe2\x85\xae" => "\xe2\x85\xbe",
+ "\xe2\x85\xaf" => "\xe2\x85\xbf",
+ "\xe2\x92\xb6" => "\xe2\x93\x90",
+ "\xe2\x92\xb7" => "\xe2\x93\x91",
+ "\xe2\x92\xb8" => "\xe2\x93\x92",
+ "\xe2\x92\xb9" => "\xe2\x93\x93",
+ "\xe2\x92\xba" => "\xe2\x93\x94",
+ "\xe2\x92\xbb" => "\xe2\x93\x95",
+ "\xe2\x92\xbc" => "\xe2\x93\x96",
+ "\xe2\x92\xbd" => "\xe2\x93\x97",
+ "\xe2\x92\xbe" => "\xe2\x93\x98",
+ "\xe2\x92\xbf" => "\xe2\x93\x99",
+ "\xe2\x93\x80" => "\xe2\x93\x9a",
+ "\xe2\x93\x81" => "\xe2\x93\x9b",
+ "\xe2\x93\x82" => "\xe2\x93\x9c",
+ "\xe2\x93\x83" => "\xe2\x93\x9d",
+ "\xe2\x93\x84" => "\xe2\x93\x9e",
+ "\xe2\x93\x85" => "\xe2\x93\x9f",
+ "\xe2\x93\x86" => "\xe2\x93\xa0",
+ "\xe2\x93\x87" => "\xe2\x93\xa1",
+ "\xe2\x93\x88" => "\xe2\x93\xa2",
+ "\xe2\x93\x89" => "\xe2\x93\xa3",
+ "\xe2\x93\x8a" => "\xe2\x93\xa4",
+ "\xe2\x93\x8b" => "\xe2\x93\xa5",
+ "\xe2\x93\x8c" => "\xe2\x93\xa6",
+ "\xe2\x93\x8d" => "\xe2\x93\xa7",
+ "\xe2\x93\x8e" => "\xe2\x93\xa8",
+ "\xe2\x93\x8f" => "\xe2\x93\xa9",
+ "\xef\xbc\xa1" => "\xef\xbd\x81",
+ "\xef\xbc\xa2" => "\xef\xbd\x82",
+ "\xef\xbc\xa3" => "\xef\xbd\x83",
+ "\xef\xbc\xa4" => "\xef\xbd\x84",
+ "\xef\xbc\xa5" => "\xef\xbd\x85",
+ "\xef\xbc\xa6" => "\xef\xbd\x86",
+ "\xef\xbc\xa7" => "\xef\xbd\x87",
+ "\xef\xbc\xa8" => "\xef\xbd\x88",
+ "\xef\xbc\xa9" => "\xef\xbd\x89",
+ "\xef\xbc\xaa" => "\xef\xbd\x8a",
+ "\xef\xbc\xab" => "\xef\xbd\x8b",
+ "\xef\xbc\xac" => "\xef\xbd\x8c",
+ "\xef\xbc\xad" => "\xef\xbd\x8d",
+ "\xef\xbc\xae" => "\xef\xbd\x8e",
+ "\xef\xbc\xaf" => "\xef\xbd\x8f",
+ "\xef\xbc\xb0" => "\xef\xbd\x90",
+ "\xef\xbc\xb1" => "\xef\xbd\x91",
+ "\xef\xbc\xb2" => "\xef\xbd\x92",
+ "\xef\xbc\xb3" => "\xef\xbd\x93",
+ "\xef\xbc\xb4" => "\xef\xbd\x94",
+ "\xef\xbc\xb5" => "\xef\xbd\x95",
+ "\xef\xbc\xb6" => "\xef\xbd\x96",
+ "\xef\xbc\xb7" => "\xef\xbd\x97",
+ "\xef\xbc\xb8" => "\xef\xbd\x98",
+ "\xef\xbc\xb9" => "\xef\xbd\x99",
+ "\xef\xbc\xba" => "\xef\xbd\x9a",
+ "\xf0\x90\x90\x80" => "\xf0\x90\x90\xa8",
+ "\xf0\x90\x90\x81" => "\xf0\x90\x90\xa9",
+ "\xf0\x90\x90\x82" => "\xf0\x90\x90\xaa",
+ "\xf0\x90\x90\x83" => "\xf0\x90\x90\xab",
+ "\xf0\x90\x90\x84" => "\xf0\x90\x90\xac",
+ "\xf0\x90\x90\x85" => "\xf0\x90\x90\xad",
+ "\xf0\x90\x90\x86" => "\xf0\x90\x90\xae",
+ "\xf0\x90\x90\x87" => "\xf0\x90\x90\xaf",
+ "\xf0\x90\x90\x88" => "\xf0\x90\x90\xb0",
+ "\xf0\x90\x90\x89" => "\xf0\x90\x90\xb1",
+ "\xf0\x90\x90\x8a" => "\xf0\x90\x90\xb2",
+ "\xf0\x90\x90\x8b" => "\xf0\x90\x90\xb3",
+ "\xf0\x90\x90\x8c" => "\xf0\x90\x90\xb4",
+ "\xf0\x90\x90\x8d" => "\xf0\x90\x90\xb5",
+ "\xf0\x90\x90\x8e" => "\xf0\x90\x90\xb6",
+ "\xf0\x90\x90\x8f" => "\xf0\x90\x90\xb7",
+ "\xf0\x90\x90\x90" => "\xf0\x90\x90\xb8",
+ "\xf0\x90\x90\x91" => "\xf0\x90\x90\xb9",
+ "\xf0\x90\x90\x92" => "\xf0\x90\x90\xba",
+ "\xf0\x90\x90\x93" => "\xf0\x90\x90\xbb",
+ "\xf0\x90\x90\x94" => "\xf0\x90\x90\xbc",
+ "\xf0\x90\x90\x95" => "\xf0\x90\x90\xbd",
+ "\xf0\x90\x90\x96" => "\xf0\x90\x90\xbe",
+ "\xf0\x90\x90\x97" => "\xf0\x90\x90\xbf",
+ "\xf0\x90\x90\x98" => "\xf0\x90\x91\x80",
+ "\xf0\x90\x90\x99" => "\xf0\x90\x91\x81",
+ "\xf0\x90\x90\x9a" => "\xf0\x90\x91\x82",
+ "\xf0\x90\x90\x9b" => "\xf0\x90\x91\x83",
+ "\xf0\x90\x90\x9c" => "\xf0\x90\x91\x84",
+ "\xf0\x90\x90\x9d" => "\xf0\x90\x91\x85",
+ "\xf0\x90\x90\x9e" => "\xf0\x90\x91\x86",
+ "\xf0\x90\x90\x9f" => "\xf0\x90\x91\x87",
+ "\xf0\x90\x90\xa0" => "\xf0\x90\x91\x88",
+ "\xf0\x90\x90\xa1" => "\xf0\x90\x91\x89",
+ "\xf0\x90\x90\xa2" => "\xf0\x90\x91\x8a",
+ "\xf0\x90\x90\xa3" => "\xf0\x90\x91\x8b",
+ "\xf0\x90\x90\xa4" => "\xf0\x90\x91\x8c",
+ "\xf0\x90\x90\xa5" => "\xf0\x90\x91\x8d"
+);
+
+?>
diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php
new file mode 100644
index 000000000000..788774fb2053
--- /dev/null
+++ b/includes/WatchedItem.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ *
+ * @package MediaWiki
+ */
+
+/**
+ *
+ * @package MediaWiki
+ */
+class WatchedItem {
+ var $mTitle, $mUser;
+
+ /**
+ * Create a WatchedItem object with the given user and title
+ * @todo document
+ * @access private
+ */
+ function &fromUserTitle( &$user, &$title ) {
+ $wl = new WatchedItem;
+ $wl->mUser =& $user;
+ $wl->mTitle =& $title;
+ $wl->id = $user->getId();
+# Patch (also) for email notification on page changes T.Gries/M.Arndt 11.09.2004
+# TG patch: here we do not consider pages and their talk pages equivalent - why should we ?
+# The change results in talk-pages not automatically included in watchlists, when their parent page is included
+# $wl->ns = $title->getNamespace() & ~1;
+ $wl->ns = $title->getNamespace();
+
+ $wl->ti = $title->getDBkey();
+ return $wl;
+ }
+
+ /**
+ * Returns the memcached key for this item
+ */
+ function watchKey() {
+ return wfMemcKey( 'watchlist', 'user', $this->id, 'page', $this->ns, $this->ti );
+ }
+
+ /**
+ * Is mTitle being watched by mUser?
+ */
+ function isWatched() {
+ # Pages and their talk pages are considered equivalent for watching;
+ # remember that talk namespaces are numbered as page namespace+1.
+ global $wgMemc;
+ $fname = 'WatchedItem::isWatched';
+
+ $key = $this->watchKey();
+ $iswatched = $wgMemc->get( $key );
+ if( is_integer( $iswatched ) ) return $iswatched;
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'watchlist', 1, array( 'wl_user' => $this->id, 'wl_namespace' => $this->ns,
+ 'wl_title' => $this->ti ), $fname );
+ $iswatched = ($dbr->numRows( $res ) > 0) ? 1 : 0;
+ $wgMemc->set( $key, $iswatched );
+ return $iswatched;
+ }
+
+ /**
+ * @todo document
+ */
+ function addWatch() {
+ $fname = 'WatchedItem::addWatch';
+ wfProfileIn( $fname );
+
+ // Use INSERT IGNORE to avoid overwriting the notification timestamp
+ // if there's already an entry for this page
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->insert( 'watchlist',
+ array(
+ 'wl_user' => $this->id,
+ 'wl_namespace' => ($this->ns & ~1),
+ 'wl_title' => $this->ti,
+ 'wl_notificationtimestamp' => NULL
+ ), $fname, 'IGNORE' );
+
+ // Every single watched page needs now to be listed in watchlist;
+ // namespace:page and namespace_talk:page need separate entries:
+ $dbw->insert( 'watchlist',
+ array(
+ 'wl_user' => $this->id,
+ 'wl_namespace' => ($this->ns | 1 ),
+ 'wl_title' => $this->ti,
+ 'wl_notificationtimestamp' => NULL
+ ), $fname, 'IGNORE' );
+
+ global $wgMemc;
+ $wgMemc->set( $this->watchkey(), 1 );
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ function removeWatch() {
+ global $wgMemc;
+ $fname = 'WatchedItem::removeWatch';
+
+ $success = false;
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'watchlist',
+ array(
+ 'wl_user' => $this->id,
+ 'wl_namespace' => ($this->ns & ~1),
+ 'wl_title' => $this->ti
+ ), $fname
+ );
+ if ( $dbw->affectedRows() ) {
+ $success = true;
+ }
+
+ # the following code compensates the new behaviour, introduced by the
+ # enotif patch, that every single watched page needs now to be listed
+ # in watchlist namespace:page and namespace_talk:page had separate
+ # entries: clear them
+ $dbw->delete( 'watchlist',
+ array(
+ 'wl_user' => $this->id,
+ 'wl_namespace' => ($this->ns | 1),
+ 'wl_title' => $this->ti
+ ), $fname
+ );
+
+ if ( $dbw->affectedRows() ) {
+ $success = true;
+ }
+ if ( $success ) {
+ $wgMemc->set( $this->watchkey(), 0 );
+ }
+ return $success;
+ }
+
+ /**
+ * Check if the given title already is watched by the user, and if so
+ * add watches on a new title. To be used for page renames and such.
+ *
+ * @param Title $ot Page title to duplicate entries from, if present
+ * @param Title $nt Page title to add watches on
+ * @static
+ */
+ function duplicateEntries( $ot, $nt ) {
+ WatchedItem::doDuplicateEntries( $ot->getSubjectPage(), $nt->getSubjectPage() );
+ WatchedItem::doDuplicateEntries( $ot->getTalkPage(), $nt->getTalkPage() );
+ }
+
+ /**
+ * @static
+ * @access private
+ */
+ function doDuplicateEntries( $ot, $nt ) {
+ $fname = "WatchedItem::duplicateEntries";
+ $oldnamespace = $ot->getNamespace();
+ $newnamespace = $nt->getNamespace();
+ $oldtitle = $ot->getDBkey();
+ $newtitle = $nt->getDBkey();
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $res = $dbw->select( 'watchlist', 'wl_user',
+ array( 'wl_namespace' => $oldnamespace, 'wl_title' => $oldtitle ),
+ $fname, 'FOR UPDATE'
+ );
+ # Construct array to replace into the watchlist
+ $values = array();
+ while ( $s = $dbw->fetchObject( $res ) ) {
+ $values[] = array(
+ 'wl_user' => $s->wl_user,
+ 'wl_namespace' => $newnamespace,
+ 'wl_title' => $newtitle
+ );
+ }
+ $dbw->freeResult( $res );
+
+ if( empty( $values ) ) {
+ // Nothing to do
+ return true;
+ }
+
+ # Perform replace
+ # Note that multi-row replace is very efficient for MySQL but may be inefficient for
+ # some other DBMSes, mostly due to poor simulation by us
+ $dbw->replace( 'watchlist', array(array( 'wl_user', 'wl_namespace', 'wl_title')), $values, $fname );
+ return true;
+ }
+
+
+}
+
+?>
diff --git a/includes/WebRequest.php b/includes/WebRequest.php
new file mode 100644
index 000000000000..3a584a4ca9ef
--- /dev/null
+++ b/includes/WebRequest.php
@@ -0,0 +1,540 @@
+<?php
+/**
+ * Deal with importing all those nasssty globals and things
+ * @package MediaWiki
+ */
+
+# Copyright (C) 2003 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * The WebRequest class encapsulates getting at data passed in the
+ * URL or via a POSTed form, handling remove of "magic quotes" slashes,
+ * stripping illegal input characters and normalizing Unicode sequences.
+ *
+ * Usually this is used via a global singleton, $wgRequest. You should
+ * not create a second WebRequest object; make a FauxRequest object if
+ * you want to pass arbitrary data to some function in place of the web
+ * input.
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Some entry points may use this file without first enabling the
+ * autoloader.
+ */
+if ( !function_exists( '__autoload' ) ) {
+ require_once( dirname(__FILE__) . '/normal/UtfNormal.php' );
+}
+
+class WebRequest {
+ function WebRequest() {
+ $this->checkMagicQuotes();
+ global $wgUsePathInfo;
+ if ( $wgUsePathInfo ) {
+ if ( isset( $_SERVER['ORIG_PATH_INFO'] ) && $_SERVER['ORIG_PATH_INFO'] != '' ) {
+ # Mangled PATH_INFO
+ # http://bugs.php.net/bug.php?id=31892
+ # Also reported when ini_get('cgi.fix_pathinfo')==false
+ $_GET['title'] = $_REQUEST['title'] = substr( $_SERVER['ORIG_PATH_INFO'], 1 );
+ } elseif ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != '') && $wgUsePathInfo ) {
+ $_GET['title'] = $_REQUEST['title'] = substr( $_SERVER['PATH_INFO'], 1 );
+ }
+ }
+ }
+
+ private $_response;
+
+ /**
+ * Recursively strips slashes from the given array;
+ * used for undoing the evil that is magic_quotes_gpc.
+ * @param array &$arr will be modified
+ * @return array the original array
+ * @private
+ */
+ function &fix_magic_quotes( &$arr ) {
+ foreach( $arr as $key => $val ) {
+ if( is_array( $val ) ) {
+ $this->fix_magic_quotes( $arr[$key] );
+ } else {
+ $arr[$key] = stripslashes( $val );
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * If magic_quotes_gpc option is on, run the global arrays
+ * through fix_magic_quotes to strip out the stupid slashes.
+ * WARNING: This should only be done once! Running a second
+ * time could damage the values.
+ * @private
+ */
+ function checkMagicQuotes() {
+ if ( get_magic_quotes_gpc() ) {
+ $this->fix_magic_quotes( $_COOKIE );
+ $this->fix_magic_quotes( $_ENV );
+ $this->fix_magic_quotes( $_GET );
+ $this->fix_magic_quotes( $_POST );
+ $this->fix_magic_quotes( $_REQUEST );
+ $this->fix_magic_quotes( $_SERVER );
+ }
+ }
+
+ /**
+ * Recursively normalizes UTF-8 strings in the given array.
+ * @param array $data string or array
+ * @return cleaned-up version of the given
+ * @private
+ */
+ function normalizeUnicode( $data ) {
+ if( is_array( $data ) ) {
+ foreach( $data as $key => $val ) {
+ $data[$key] = $this->normalizeUnicode( $val );
+ }
+ } else {
+ $data = UtfNormal::cleanUp( $data );
+ }
+ return $data;
+ }
+
+ /**
+ * Fetch a value from the given array or return $default if it's not set.
+ *
+ * @param array $arr
+ * @param string $name
+ * @param mixed $default
+ * @return mixed
+ * @private
+ */
+ function getGPCVal( $arr, $name, $default ) {
+ if( isset( $arr[$name] ) ) {
+ global $wgContLang;
+ $data = $arr[$name];
+ if( isset( $_GET[$name] ) && !is_array( $data ) ) {
+ # Check for alternate/legacy character encoding.
+ if( isset( $wgContLang ) ) {
+ $data = $wgContLang->checkTitleEncoding( $data );
+ }
+ }
+ $data = $this->normalizeUnicode( $data );
+ return $data;
+ } else {
+ return $default;
+ }
+ }
+
+ /**
+ * Fetch a scalar from the input or return $default if it's not set.
+ * Returns a string. Arrays are discarded.
+ *
+ * @param string $name
+ * @param string $default optional default (or NULL)
+ * @return string
+ */
+ function getVal( $name, $default = NULL ) {
+ $val = $this->getGPCVal( $_REQUEST, $name, $default );
+ if( is_array( $val ) ) {
+ $val = $default;
+ }
+ if( is_null( $val ) ) {
+ return null;
+ } else {
+ return (string)$val;
+ }
+ }
+
+ /**
+ * Fetch an array from the input or return $default if it's not set.
+ * If source was scalar, will return an array with a single element.
+ * If no source and no default, returns NULL.
+ *
+ * @param string $name
+ * @param array $default optional default (or NULL)
+ * @return array
+ */
+ function getArray( $name, $default = NULL ) {
+ $val = $this->getGPCVal( $_REQUEST, $name, $default );
+ if( is_null( $val ) ) {
+ return null;
+ } else {
+ return (array)$val;
+ }
+ }
+
+ /**
+ * Fetch an array of integers, or return $default if it's not set.
+ * If source was scalar, will return an array with a single element.
+ * If no source and no default, returns NULL.
+ * If an array is returned, contents are guaranteed to be integers.
+ *
+ * @param string $name
+ * @param array $default option default (or NULL)
+ * @return array of ints
+ */
+ function getIntArray( $name, $default = NULL ) {
+ $val = $this->getArray( $name, $default );
+ if( is_array( $val ) ) {
+ $val = array_map( 'intval', $val );
+ }
+ return $val;
+ }
+
+ /**
+ * Fetch an integer value from the input or return $default if not set.
+ * Guaranteed to return an integer; non-numeric input will typically
+ * return 0.
+ * @param string $name
+ * @param int $default
+ * @return int
+ */
+ function getInt( $name, $default = 0 ) {
+ return intval( $this->getVal( $name, $default ) );
+ }
+
+ /**
+ * Fetch an integer value from the input or return null if empty.
+ * Guaranteed to return an integer or null; non-numeric input will
+ * typically return null.
+ * @param string $name
+ * @return int
+ */
+ function getIntOrNull( $name ) {
+ $val = $this->getVal( $name );
+ return is_numeric( $val )
+ ? intval( $val )
+ : null;
+ }
+
+ /**
+ * Fetch a boolean value from the input or return $default if not set.
+ * Guaranteed to return true or false, with normal PHP semantics for
+ * boolean interpretation of strings.
+ * @param string $name
+ * @param bool $default
+ * @return bool
+ */
+ function getBool( $name, $default = false ) {
+ return $this->getVal( $name, $default ) ? true : false;
+ }
+
+ /**
+ * Return true if the named value is set in the input, whatever that
+ * value is (even "0"). Return false if the named value is not set.
+ * Example use is checking for the presence of check boxes in forms.
+ * @param string $name
+ * @return bool
+ */
+ function getCheck( $name ) {
+ # Checkboxes and buttons are only present when clicked
+ # Presence connotes truth, abscense false
+ $val = $this->getVal( $name, NULL );
+ return isset( $val );
+ }
+
+ /**
+ * Fetch a text string from the given array or return $default if it's not
+ * set. \r is stripped from the text, and with some language modules there
+ * is an input transliteration applied. This should generally be used for
+ * form <textarea> and <input> fields.
+ *
+ * @param string $name
+ * @param string $default optional
+ * @return string
+ */
+ function getText( $name, $default = '' ) {
+ global $wgContLang;
+ $val = $this->getVal( $name, $default );
+ return str_replace( "\r\n", "\n",
+ $wgContLang->recodeInput( $val ) );
+ }
+
+ /**
+ * Extracts the given named values into an array.
+ * If no arguments are given, returns all input values.
+ * No transformation is performed on the values.
+ */
+ function getValues() {
+ $names = func_get_args();
+ if ( count( $names ) == 0 ) {
+ $names = array_keys( $_REQUEST );
+ }
+
+ $retVal = array();
+ foreach ( $names as $name ) {
+ $value = $this->getVal( $name );
+ if ( !is_null( $value ) ) {
+ $retVal[$name] = $value;
+ }
+ }
+ return $retVal;
+ }
+
+ /**
+ * Returns true if the present request was reached by a POST operation,
+ * false otherwise (GET, HEAD, or command-line).
+ *
+ * Note that values retrieved by the object may come from the
+ * GET URL etc even on a POST request.
+ *
+ * @return bool
+ */
+ function wasPosted() {
+ return $_SERVER['REQUEST_METHOD'] == 'POST';
+ }
+
+ /**
+ * Returns true if there is a session cookie set.
+ * This does not necessarily mean that the user is logged in!
+ *
+ * @return bool
+ */
+ function checkSessionCookie() {
+ return isset( $_COOKIE[ini_get('session.name')] );
+ }
+
+ /**
+ * Return the path portion of the request URI.
+ * @return string
+ */
+ function getRequestURL() {
+ if( isset( $_SERVER['REQUEST_URI'] ) ) {
+ $base = $_SERVER['REQUEST_URI'];
+ } elseif( isset( $_SERVER['SCRIPT_NAME'] ) ) {
+ // Probably IIS; doesn't set REQUEST_URI
+ $base = $_SERVER['SCRIPT_NAME'];
+ if( isset( $_SERVER['QUERY_STRING'] ) && $_SERVER['QUERY_STRING'] != '' ) {
+ $base .= '?' . $_SERVER['QUERY_STRING'];
+ }
+ } else {
+ // This shouldn't happen!
+ throw new MWException( "Web server doesn't provide either " .
+ "REQUEST_URI or SCRIPT_NAME. Report details of your " .
+ "web server configuration to http://bugzilla.wikimedia.org/" );
+ }
+ // User-agents should not send a fragment with the URI, but
+ // if they do, and the web server passes it on to us, we
+ // need to strip it or we get false-positive redirect loops
+ // or weird output URLs
+ $hash = strpos( $base, '#' );
+ if( $hash !== false ) {
+ $base = substr( $base, 0, $hash );
+ }
+ if( $base{0} == '/' ) {
+ return $base;
+ } else {
+ // We may get paths with a host prepended; strip it.
+ return preg_replace( '!^[^:]+://[^/]+/!', '/', $base );
+ }
+ }
+
+ /**
+ * Return the request URI with the canonical service and hostname.
+ * @return string
+ */
+ function getFullRequestURL() {
+ global $wgServer;
+ return $wgServer . $this->getRequestURL();
+ }
+
+ /**
+ * Take an arbitrary query and rewrite the present URL to include it
+ * @param $query String: query string fragment; do not include initial '?'
+ * @return string
+ */
+ function appendQuery( $query ) {
+ global $wgTitle;
+ $basequery = '';
+ foreach( $_GET as $var => $val ) {
+ if ( $var == 'title' )
+ continue;
+ if ( is_array( $val ) )
+ /* This will happen given a request like
+ * http://en.wikipedia.org/w/index.php?title[]=Special:Userlogin&returnto[]=Main_Page
+ */
+ continue;
+ $basequery .= '&' . urlencode( $var ) . '=' . urlencode( $val );
+ }
+ $basequery .= '&' . $query;
+
+ # Trim the extra &
+ $basequery = substr( $basequery, 1 );
+ return $wgTitle->getLocalURL( $basequery );
+ }
+
+ /**
+ * HTML-safe version of appendQuery().
+ * @param $query String: query string fragment; do not include initial '?'
+ * @return string
+ */
+ function escapeAppendQuery( $query ) {
+ return htmlspecialchars( $this->appendQuery( $query ) );
+ }
+
+ /**
+ * Check for limit and offset parameters on the input, and return sensible
+ * defaults if not given. The limit must be positive and is capped at 5000.
+ * Offset must be positive but is not capped.
+ *
+ * @param $deflimit Integer: limit to use if no input and the user hasn't set the option.
+ * @param $optionname String: to specify an option other than rclimit to pull from.
+ * @return array first element is limit, second is offset
+ */
+ function getLimitOffset( $deflimit = 50, $optionname = 'rclimit' ) {
+ global $wgUser;
+
+ $limit = $this->getInt( 'limit', 0 );
+ if( $limit < 0 ) $limit = 0;
+ if( ( $limit == 0 ) && ( $optionname != '' ) ) {
+ $limit = (int)$wgUser->getOption( $optionname );
+ }
+ if( $limit <= 0 ) $limit = $deflimit;
+ if( $limit > 5000 ) $limit = 5000; # We have *some* limits...
+
+ $offset = $this->getInt( 'offset', 0 );
+ if( $offset < 0 ) $offset = 0;
+
+ return array( $limit, $offset );
+ }
+
+ /**
+ * Return the path to the temporary file where PHP has stored the upload.
+ * @param $key String:
+ * @return string or NULL if no such file.
+ */
+ function getFileTempname( $key ) {
+ if( !isset( $_FILES[$key] ) ) {
+ return NULL;
+ }
+ return $_FILES[$key]['tmp_name'];
+ }
+
+ /**
+ * Return the size of the upload, or 0.
+ * @param $key String:
+ * @return integer
+ */
+ function getFileSize( $key ) {
+ if( !isset( $_FILES[$key] ) ) {
+ return 0;
+ }
+ return $_FILES[$key]['size'];
+ }
+
+ /**
+ * Return the upload error or 0
+ * @param $key String:
+ * @return integer
+ */
+ function getUploadError( $key ) {
+ if( !isset( $_FILES[$key] ) || !isset( $_FILES[$key]['error'] ) ) {
+ return 0/*UPLOAD_ERR_OK*/;
+ }
+ return $_FILES[$key]['error'];
+ }
+
+ /**
+ * Return the original filename of the uploaded file, as reported by
+ * the submitting user agent. HTML-style character entities are
+ * interpreted and normalized to Unicode normalization form C, in part
+ * to deal with weird input from Safari with non-ASCII filenames.
+ *
+ * Other than this the name is not verified for being a safe filename.
+ *
+ * @param $key String:
+ * @return string or NULL if no such file.
+ */
+ function getFileName( $key ) {
+ if( !isset( $_FILES[$key] ) ) {
+ return NULL;
+ }
+ $name = $_FILES[$key]['name'];
+
+ # Safari sends filenames in HTML-encoded Unicode form D...
+ # Horrid and evil! Let's try to make some kind of sense of it.
+ $name = Sanitizer::decodeCharReferences( $name );
+ $name = UtfNormal::cleanUp( $name );
+ wfDebug( "WebRequest::getFileName() '" . $_FILES[$key]['name'] . "' normalized to '$name'\n" );
+ return $name;
+ }
+
+ /**
+ * Return a handle to WebResponse style object, for setting cookies,
+ * headers and other stuff, for Request being worked on.
+ */
+ function response() {
+ /* Lazy initialization of response object for this request */
+ if (!is_object($this->_response)) {
+ $this->_response = new WebResponse;
+ }
+ return $this->_response;
+ }
+
+}
+
+/**
+ * WebRequest clone which takes values from a provided array.
+ *
+ * @package MediaWiki
+ */
+class FauxRequest extends WebRequest {
+ var $data = null;
+ var $wasPosted = false;
+
+ function FauxRequest( $data, $wasPosted = false ) {
+ if( is_array( $data ) ) {
+ $this->data = $data;
+ } else {
+ throw new MWException( "FauxRequest() got bogus data" );
+ }
+ $this->wasPosted = $wasPosted;
+ }
+
+ function getVal( $name, $default = NULL ) {
+ return $this->getGPCVal( $this->data, $name, $default );
+ }
+
+ function getText( $name, $default = '' ) {
+ # Override; don't recode since we're using internal data
+ return $this->getVal( $name, $default );
+ }
+
+ function getValues() {
+ return $this->data;
+ }
+
+ function wasPosted() {
+ return $this->wasPosted;
+ }
+
+ function checkSessionCookie() {
+ return false;
+ }
+
+ function getRequestURL() {
+ throw new MWException( 'FauxRequest::getRequestURL() not implemented' );
+ }
+
+ function appendQuery( $query ) {
+ throw new MWException( 'FauxRequest::appendQuery() not implemented' );
+ }
+
+}
+
+?>
diff --git a/includes/WebResponse.php b/includes/WebResponse.php
new file mode 100644
index 000000000000..e159152e4084
--- /dev/null
+++ b/includes/WebResponse.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Allow programs to request this object from WebRequest::response() and handle all outputting (or lack of outputting) via it.
+ */
+
+class WebResponse {
+ function header($string, $replace=true) {
+ header($string,$replace);
+ }
+
+ function setcookie($name, $value, $expire) {
+ global $wgCookiePath, $wgCookieDomain, $wgCookieSecure;
+ setcookie($name,$value,$expire, $wgCookiePath, $wgCookieDomain, $wgCookieSecure);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/includes/WebStart.php b/includes/WebStart.php
new file mode 100644
index 000000000000..37582290d533
--- /dev/null
+++ b/includes/WebStart.php
@@ -0,0 +1,92 @@
+<?php
+
+# This does the initial setup for a web request. It does some security checks,
+# starts the profiler and loads the configuration, and optionally loads
+# Setup.php depending on whether MW_NO_SETUP is defined.
+
+# Test for PHP bug which breaks PHP 5.0.x on 64-bit...
+# As of 1.8 this breaks lots of common operations instead
+# of just some rare ones like export.
+$borked = str_replace( 'a', 'b', array( -1 => -1 ) );
+if( !isset( $borked[-1] ) ) {
+ echo "PHP 5.0.x is buggy on your 64-bit system; you must upgrade to PHP 5.1.x\n" .
+ "or higher. ABORTING. (http://bugs.php.net/bug.php?id=34879 for details)\n";
+ die( -1 );
+}
+
+# Protect against register_globals
+# This must be done before any globals are set by the code
+if ( ini_get( 'register_globals' ) ) {
+ if ( isset( $_REQUEST['GLOBALS'] ) ) {
+ die( '<a href="http://www.hardened-php.net/index.76.html">$GLOBALS overwrite vulnerability</a>');
+ }
+ $verboten = array(
+ 'GLOBALS',
+ '_SERVER',
+ 'HTTP_SERVER_VARS',
+ '_GET',
+ 'HTTP_GET_VARS',
+ '_POST',
+ 'HTTP_POST_VARS',
+ '_COOKIE',
+ 'HTTP_COOKIE_VARS',
+ '_FILES',
+ 'HTTP_POST_FILES',
+ '_ENV',
+ 'HTTP_ENV_VARS',
+ '_REQUEST',
+ '_SESSION',
+ 'HTTP_SESSION_VARS'
+ );
+ foreach ( $_REQUEST as $name => $value ) {
+ if( in_array( $name, $verboten ) ) {
+ header( "HTTP/1.x 500 Internal Server Error" );
+ echo "register_globals security paranoia: trying to overwrite superglobals, aborting.";
+ die( -1 );
+ }
+ unset( $GLOBALS[$name] );
+ }
+}
+
+$wgRequestTime = microtime(true);
+# getrusage() does not exist on the Microsoft Windows platforms, catching this
+if ( function_exists ( 'getrusage' ) ) {
+ $wgRUstart = getrusage();
+} else {
+ $wgRUstart = array();
+}
+unset( $IP );
+@ini_set( 'allow_url_fopen', 0 ); # For security
+
+# Valid web server entry point, enable includes.
+# Please don't move this line to includes/Defines.php. This line essentially
+# defines a valid entry point. If you put it in includes/Defines.php, then
+# any script that includes it becomes an entry point, thereby defeating
+# its purpose.
+define( 'MEDIAWIKI', true );
+
+# Start profiler
+require_once( './StartProfiler.php' );
+wfProfileIn( 'WebStart.php-conf' );
+
+# Load up some global defines.
+require_once( './includes/Defines.php' );
+
+# LocalSettings.php is the per site customization file. If it does not exit
+# the wiki installer need to be launched or the generated file moved from
+# ./config/ to ./
+if( !file_exists( './LocalSettings.php' ) ) {
+ $IP = '.';
+ require_once( './includes/DefaultSettings.php' ); # used for printing the version
+ require_once( './includes/templates/NoLocalSettings.php' );
+ die();
+}
+
+# Include this site setttings
+require_once( './LocalSettings.php' );
+wfProfileOut( 'WebStart.php-conf' );
+
+if ( !defined( 'MW_NO_SETUP' ) ) {
+ require_once( './includes/Setup.php' );
+}
+?>
diff --git a/includes/Wiki.php b/includes/Wiki.php
new file mode 100644
index 000000000000..06248b35c0eb
--- /dev/null
+++ b/includes/Wiki.php
@@ -0,0 +1,448 @@
+<?php
+/**
+ * MediaWiki is the to-be base class for this whole project
+ */
+
+class MediaWiki {
+
+ var $GET; /* Stores the $_GET variables at time of creation, can be changed */
+ var $params = array();
+
+ /**
+ * Constructor
+ */
+ function MediaWiki () {
+ $this->GET = $_GET;
+ }
+
+ /**
+ * Stores key/value pairs to circumvent global variables
+ * Note that keys are case-insensitive!
+ */
+ function setVal( $key, &$value ) {
+ $key = strtolower( $key );
+ $this->params[$key] =& $value;
+ }
+
+ /**
+ * Retrieves key/value pairs to circumvent global variables
+ * Note that keys are case-insensitive!
+ */
+ function getVal( $key, $default = '' ) {
+ $key = strtolower( $key );
+ if( isset( $this->params[$key] ) ) {
+ return $this->params[$key];
+ }
+ return $default;
+ }
+
+ /**
+ * Initialization of ... everything
+ @return Article either the object to become $wgArticle, or NULL
+ */
+ function initialize ( &$title, &$output, &$user, $request) {
+ wfProfileIn( 'MediaWiki::initialize' );
+ $this->preliminaryChecks ( $title, $output, $request ) ;
+ $article = NULL;
+ if ( !$this->initializeSpecialCases( $title, $output, $request ) ) {
+ $article = $this->initializeArticle( $title, $request );
+ if( is_object( $article ) ) {
+ $this->performAction( $output, $article, $title, $user, $request );
+ } elseif( is_string( $article ) ) {
+ $output->redirect( $article );
+ } else {
+ throw new MWException( "Shouldn't happen: MediaWiki::initializeArticle() returned neither an object nor a URL" );
+ }
+ }
+ wfProfileOut( 'MediaWiki::initialize' );
+ return $article;
+ }
+
+ /**
+ * Checks some initial queries
+ * Note that $title here is *not* a Title object, but a string!
+ */
+ function checkInitialQueries( $title,$action,&$output,$request, $lang) {
+ if ($request->getVal( 'printable' ) == 'yes') {
+ $output->setPrintable();
+ }
+
+ $ret = NULL ;
+
+
+ if ( '' == $title && 'delete' != $action ) {
+ $ret = Title::newMainPage();
+ } elseif ( $curid = $request->getInt( 'curid' ) ) {
+ # URLs like this are generated by RC, because rc_title isn't always accurate
+ $ret = Title::newFromID( $curid );
+ } else {
+ $ret = Title::newFromURL( $title );
+ /* check variant links so that interwiki links don't have to worry about
+ the possible different language variants
+ */
+ if( count($lang->getVariants()) > 1 && !is_null($ret) && $ret->getArticleID() == 0 )
+ $lang->findVariantLink( $title, $ret );
+
+ }
+ return $ret ;
+ }
+
+ /**
+ * Checks for search query and anon-cannot-read case
+ */
+ function preliminaryChecks ( &$title, &$output, $request ) {
+
+ # Debug statement for user levels
+ // print_r($wgUser);
+
+ $search = $request->getText( 'search' );
+ if( !is_null( $search ) && $search !== '' ) {
+ // Compatibility with old search URLs which didn't use Special:Search
+ // Do this above the read whitelist check for security...
+ $title = SpecialPage::getTitleFor( 'Search' );
+ }
+ $this->setVal( 'Search', $search );
+
+ # If the user is not logged in, the Namespace:title of the article must be in
+ # the Read array in order for the user to see it. (We have to check here to
+ # catch special pages etc. We check again in Article::view())
+ if ( !is_null( $title ) && !$title->userCanRead() ) {
+ $output->loginToUse();
+ $output->output();
+ exit;
+ }
+
+ }
+
+ /**
+ * Initialize the object to be known as $wgArticle for special cases
+ */
+ function initializeSpecialCases ( &$title, &$output, $request ) {
+ global $wgRequest;
+ wfProfileIn( 'MediaWiki::initializeSpecialCases' );
+
+ $search = $this->getVal('Search');
+ $action = $this->getVal('Action');
+ if( !$this->getVal('DisableInternalSearch') && !is_null( $search ) && $search !== '' ) {
+ require_once( 'includes/SpecialSearch.php' );
+ $title = SpecialPage::getTitleFor( 'Search' );
+ wfSpecialSearch();
+ } else if( !$title or $title->getDBkey() == '' ) {
+ $title = SpecialPage::getTitleFor( 'Badtitle' );
+ # Die now before we mess up $wgArticle and the skin stops working
+ throw new ErrorPageError( 'badtitle', 'badtitletext' );
+ } else if ( $title->getInterwiki() != '' ) {
+ if( $rdfrom = $request->getVal( 'rdfrom' ) ) {
+ $url = $title->getFullURL( 'rdfrom=' . urlencode( $rdfrom ) );
+ } else {
+ $url = $title->getFullURL();
+ }
+ /* Check for a redirect loop */
+ if ( !preg_match( '/^' . preg_quote( $this->getVal('Server'), '/' ) . '/', $url ) && $title->isLocal() ) {
+ $output->redirect( $url );
+ } else {
+ $title = SpecialPage::getTitleFor( 'Badtitle' );
+ throw new ErrorPageError( 'badtitle', 'badtitletext' );
+ }
+ } else if ( ( $action == 'view' ) &&
+ (!isset( $this->GET['title'] ) || $title->getPrefixedDBKey() != $this->GET['title'] ) &&
+ !count( array_diff( array_keys( $this->GET ), array( 'action', 'title' ) ) ) )
+ {
+ $targetUrl = $title->getFullURL();
+ // Redirect to canonical url, make it a 301 to allow caching
+ global $wgServer, $wgUsePathInfo;
+ if( $targetUrl == $wgRequest->getFullRequestURL() ) {
+ $message = "Redirect loop detected!\n\n" .
+ "This means the wiki got confused about what page was " .
+ "requested; this sometimes happens when moving a wiki " .
+ "to a new server or changing the server configuration.\n\n";
+
+ if( $wgUsePathInfo ) {
+ $message .= "The wiki is trying to interpret the page " .
+ "title from the URL path portion (PATH_INFO), which " .
+ "sometimes fails depending on the web server. Try " .
+ "setting \"\$wgUsePathInfo = false;\" in your " .
+ "LocalSettings.php, or check that \$wgArticlePath " .
+ "is correct.";
+ } else {
+ $message .= "Your web server was detected as possibly not " .
+ "supporting URL path components (PATH_INFO) correctly; " .
+ "check your LocalSettings.php for a customized " .
+ "\$wgArticlePath setting and/or toggle \$wgUsePathInfo " .
+ "to true.";
+ }
+ wfHttpError( 500, "Internal error", $message );
+ return false;
+ } else {
+ $output->setSquidMaxage( 1200 );
+ $output->redirect( $targetUrl, '301');
+ }
+ } else if ( NS_SPECIAL == $title->getNamespace() ) {
+ /* actions that need to be made when we have a special pages */
+ SpecialPage::executePath( $title );
+ } else {
+ /* No match to special cases */
+ wfProfileOut( 'MediaWiki::initializeSpecialCases' );
+ return false;
+ }
+ /* Did match a special case */
+ wfProfileOut( 'MediaWiki::initializeSpecialCases' );
+ return true;
+ }
+
+ /**
+ * Create an Article object of the appropriate class for the given page.
+ * @param Title $title
+ * @return Article
+ */
+ function articleFromTitle( $title ) {
+ $article = null;
+ wfRunHooks('ArticleFromTitle', array( &$title, &$article ) );
+ if ( $article ) {
+ return $article;
+ }
+
+ if( NS_MEDIA == $title->getNamespace() ) {
+ // FIXME: where should this go?
+ $title = Title::makeTitle( NS_IMAGE, $title->getDBkey() );
+ }
+
+ switch( $title->getNamespace() ) {
+ case NS_IMAGE:
+ return new ImagePage( $title );
+ case NS_CATEGORY:
+ return new CategoryPage( $title );
+ default:
+ return new Article( $title );
+ }
+ }
+
+ /**
+ * Initialize the object to be known as $wgArticle for "standard" actions
+ * Create an Article object for the page, following redirects if needed.
+ * @param Title $title
+ * @param Request $request
+ * @param string $action
+ * @return mixed an Article, or a string to redirect to another URL
+ */
+ function initializeArticle( $title, $request ) {
+ global $wgTitle;
+ wfProfileIn( 'MediaWiki::initializeArticle' );
+
+ $action = $this->getVal('Action');
+ $article = $this->articleFromTitle( $title );
+
+ // Namespace might change when using redirects
+ if( $action == 'view' && !$request->getVal( 'oldid' ) &&
+ $request->getVal( 'redirect' ) != 'no' ) {
+
+ $dbr =& wfGetDB(DB_SLAVE);
+ $article->loadPageData($article->pageDataFromTitle($dbr, $title));
+
+ /* Follow redirects only for... redirects */
+ if ($article->mIsRedirect) {
+ $target = $article->followRedirect();
+ if( is_string( $target ) ) {
+ global $wgDisableHardRedirects;
+ if( !$wgDisableHardRedirects ) {
+ // we'll need to redirect
+ return $target;
+ }
+ }
+ if( is_object( $target ) ) {
+ /* Rewrite environment to redirected article */
+ $rarticle = $this->articleFromTitle($target);
+ $rarticle->loadPageData($rarticle->pageDataFromTitle($dbr,$target));
+ if ($rarticle->mTitle->mArticleID) {
+ $article = $rarticle;
+ $wgTitle = $target;
+ $article->setRedirectedFrom( $title );
+ } else {
+ $wgTitle = $title;
+ }
+ }
+ } else {
+ $wgTitle = $article->mTitle;
+ }
+ }
+ wfProfileOut( 'MediaWiki::initializeArticle' );
+ return $article;
+ }
+
+ /**
+ * Cleaning up by doing deferred updates, calling loadbalancer and doing the output
+ */
+ function finalCleanup ( &$deferredUpdates, &$loadBalancer, &$output ) {
+ wfProfileIn( 'MediaWiki::finalCleanup' );
+ $this->doUpdates( $deferredUpdates );
+ $this->doJobs();
+ $loadBalancer->saveMasterPos();
+ # Now commit any transactions, so that unreported errors after output() don't roll back the whole thing
+ $loadBalancer->commitAll();
+ $output->output();
+ wfProfileOut( 'MediaWiki::finalCleanup' );
+ }
+
+ /**
+ * Deferred updates aren't really deferred anymore. It's important to report errors to the
+ * user, and that means doing this before OutputPage::output(). Note that for page saves,
+ * the client will wait until the script exits anyway before following the redirect.
+ */
+ function doUpdates ( &$updates ) {
+ wfProfileIn( 'MediaWiki::doUpdates' );
+ $dbw =& wfGetDB( DB_MASTER );
+ foreach( $updates as $up ) {
+ $up->doUpdate();
+
+ # Commit after every update to prevent lock contention
+ if ( $dbw->trxLevel() ) {
+ $dbw->commit();
+ }
+ }
+ wfProfileOut( 'MediaWiki::doUpdates' );
+ }
+
+ /**
+ * Do a job from the job queue
+ */
+ function doJobs() {
+ global $wgJobRunRate;
+
+ if ( $wgJobRunRate <= 0 || wfReadOnly() ) {
+ return;
+ }
+ if ( $wgJobRunRate < 1 ) {
+ $max = mt_getrandmax();
+ if ( mt_rand( 0, $max ) > $max * $wgJobRunRate ) {
+ return;
+ }
+ $n = 1;
+ } else {
+ $n = intval( $wgJobRunRate );
+ }
+
+ while ( $n-- && false != ($job = Job::pop())) {
+ $output = $job->toString() . "\n";
+ $t = -wfTime();
+ $success = $job->run();
+ $t += wfTime();
+ $t = round( $t*1000 );
+ if ( !$success ) {
+ $output .= "Error: " . $job->getLastError() . ", Time: $t ms\n";
+ } else {
+ $output .= "Success, Time: $t ms\n";
+ }
+ wfDebugLog( 'jobqueue', $output );
+ }
+ }
+
+ /**
+ * Ends this task peacefully
+ */
+ function restInPeace ( &$loadBalancer ) {
+ wfLogProfilingData();
+ $loadBalancer->closeAll();
+ wfDebug( "Request ended normally\n" );
+ }
+
+ /**
+ * Perform one of the "standard" actions
+ */
+ function performAction( &$output, &$article, &$title, &$user, &$request ) {
+
+ wfProfileIn( 'MediaWiki::performAction' );
+
+ $action = $this->getVal('Action');
+ if( in_array( $action, $this->getVal('DisabledActions',array()) ) ) {
+ /* No such action; this will switch to the default case */
+ $action = 'nosuchaction';
+ }
+
+ switch( $action ) {
+ case 'view':
+ $output->setSquidMaxage( $this->getVal( 'SquidMaxage' ) );
+ $article->view();
+ break;
+ case 'watch':
+ case 'unwatch':
+ case 'delete':
+ case 'revert':
+ case 'rollback':
+ case 'protect':
+ case 'unprotect':
+ case 'info':
+ case 'markpatrolled':
+ case 'render':
+ case 'deletetrackback':
+ case 'purge':
+ $article->$action();
+ break;
+ case 'print':
+ $article->view();
+ break;
+ case 'dublincore':
+ if( !$this->getVal( 'EnableDublinCoreRdf' ) ) {
+ wfHttpError( 403, 'Forbidden', wfMsg( 'nodublincore' ) );
+ } else {
+ require_once( 'includes/Metadata.php' );
+ wfDublinCoreRdf( $article );
+ }
+ break;
+ case 'creativecommons':
+ if( !$this->getVal( 'EnableCreativeCommonsRdf' ) ) {
+ wfHttpError( 403, 'Forbidden', wfMsg( 'nocreativecommons' ) );
+ } else {
+ require_once( 'includes/Metadata.php' );
+ wfCreativeCommonsRdf( $article );
+ }
+ break;
+ case 'credits':
+ require_once( 'includes/Credits.php' );
+ showCreditsPage( $article );
+ break;
+ case 'submit':
+ if( !$this->getVal( 'CommandLineMode' ) && !$request->checkSessionCookie() ) {
+ /* Send a cookie so anons get talk message notifications */
+ User::SetupSession();
+ }
+ /* Continue... */
+ case 'edit':
+ $internal = $request->getVal( 'internaledit' );
+ $external = $request->getVal( 'externaledit' );
+ $section = $request->getVal( 'section' );
+ $oldid = $request->getVal( 'oldid' );
+ if( !$this->getVal( 'UseExternalEditor' ) || $action=='submit' || $internal ||
+ $section || $oldid || ( !$user->getOption( 'externaleditor' ) && !$external ) ) {
+ $editor = new EditPage( $article );
+ $editor->submit();
+ } elseif( $this->getVal( 'UseExternalEditor' ) && ( $external || $user->getOption( 'externaleditor' ) ) ) {
+ $mode = $request->getVal( 'mode' );
+ $extedit = new ExternalEdit( $article, $mode );
+ $extedit->edit();
+ }
+ break;
+ case 'history':
+ global $wgRequest;
+ if( $wgRequest->getFullRequestURL() == $title->getInternalURL( 'action=history' ) ) {
+ $output->setSquidMaxage( $this->getVal( 'SquidMaxage' ) );
+ }
+ $history = new PageHistory( $article );
+ $history->history();
+ break;
+ case 'raw':
+ $raw = new RawPage( $article );
+ $raw->view();
+ break;
+ default:
+ if( wfRunHooks( 'UnknownAction', array( $action, $article ) ) ) {
+ $output->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
+ }
+ }
+ wfProfileOut( 'MediaWiki::performAction' );
+
+
+ }
+
+}; /* End of class MediaWiki */
+
+?>
diff --git a/includes/WikiError.php b/includes/WikiError.php
new file mode 100644
index 000000000000..029184d46578
--- /dev/null
+++ b/includes/WikiError.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * MediaWiki error classes
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ */
+
+/**
+ * Since PHP4 doesn't have exceptions, here's some error objects
+ * loosely modeled on the standard PEAR_Error model...
+ * @package MediaWiki
+ */
+class WikiError {
+ /**
+ * @param string $message
+ */
+ function WikiError( $message ) {
+ $this->mMessage = $message;
+ }
+
+ /**
+ * @return string Plaintext error message to display
+ */
+ function getMessage() {
+ return $this->mMessage;
+ }
+
+ /**
+ * In following PEAR_Error model this could be formatted differently,
+ * but so far it's not.
+ * @return string
+ */
+ function toString() {
+ return $this->getMessage();
+ }
+
+ /**
+ * Returns true if the given object is a WikiError-descended
+ * error object, false otherwise.
+ *
+ * @param mixed $object
+ * @return bool
+ * @static
+ */
+ public static function isError( $object ) {
+ return $object instanceof WikiError;
+ }
+}
+
+/**
+ * Localized error message object
+ * @package MediaWiki
+ */
+class WikiErrorMsg extends WikiError {
+ /**
+ * @param string $message Wiki message name
+ * @param ... parameters to pass to wfMsg()
+ */
+ function WikiErrorMsg( $message/*, ... */ ) {
+ $args = func_get_args();
+ array_shift( $args );
+ $this->mMessage = wfMsgReal( $message, $args, true );
+ }
+}
+
+/**
+ * @package MediaWiki
+ * @todo document
+ */
+class WikiXmlError extends WikiError {
+ /**
+ * @param resource $parser
+ * @param string $message
+ */
+ function WikiXmlError( $parser, $message = 'XML parsing error', $context = null, $offset = 0 ) {
+ $this->mXmlError = xml_get_error_code( $parser );
+ $this->mColumn = xml_get_current_column_number( $parser );
+ $this->mLine = xml_get_current_line_number( $parser );
+ $this->mByte = xml_get_current_byte_index( $parser );
+ $this->mContext = $this->_extractContext( $context, $offset );
+ $this->mMessage = $message;
+ xml_parser_free( $parser );
+ wfDebug( "WikiXmlError: " . $this->getMessage() . "\n" );
+ }
+
+ /** @return string */
+ function getMessage() {
+ return sprintf( '%s at line %d, col %d (byte %d%s): %s',
+ $this->mMessage,
+ $this->mLine,
+ $this->mColumn,
+ $this->mByte,
+ $this->mContext,
+ xml_error_string( $this->mXmlError ) );
+ }
+
+ function _extractContext( $context, $offset ) {
+ if( is_null( $context ) ) {
+ return null;
+ } else {
+ // Hopefully integer overflow will be handled transparently here
+ $inlineOffset = $this->mByte - $offset;
+ return '; "' . substr( $context, $inlineOffset, 16 ) . '"';
+ }
+ }
+}
+
+?>
diff --git a/includes/Xml.php b/includes/Xml.php
new file mode 100644
index 000000000000..67dda7fea970
--- /dev/null
+++ b/includes/Xml.php
@@ -0,0 +1,345 @@
+<?php
+
+/**
+ * Module of static functions for generating XML
+ */
+
+class Xml {
+ /**
+ * Format an XML element with given attributes and, optionally, text content.
+ * Element and attribute names are assumed to be ready for literal inclusion.
+ * Strings are assumed to not contain XML-illegal characters; special
+ * characters (<, >, &) are escaped but illegals are not touched.
+ *
+ * @param $element String:
+ * @param $attribs Array: Name=>value pairs. Values will be escaped.
+ * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default)
+ * @return string
+ */
+ public static function element( $element, $attribs = null, $contents = '') {
+ $out = '<' . $element;
+ if( !is_null( $attribs ) ) {
+ foreach( $attribs as $name => $val ) {
+ $out .= ' ' . $name . '="' . Sanitizer::encodeAttribute( $val ) . '"';
+ }
+ }
+ if( is_null( $contents ) ) {
+ $out .= '>';
+ } else {
+ if( $contents === '' ) {
+ $out .= ' />';
+ } else {
+ $out .= '>' . htmlspecialchars( $contents ) . "</$element>";
+ }
+ }
+ return $out;
+ }
+
+ /**
+ * Format an XML element as with self::element(), but run text through the
+ * UtfNormal::cleanUp() validator first to ensure that no invalid UTF-8
+ * is passed.
+ *
+ * @param $element String:
+ * @param $attribs Array: Name=>value pairs. Values will be escaped.
+ * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default)
+ * @return string
+ */
+ public static function elementClean( $element, $attribs = array(), $contents = '') {
+ if( $attribs ) {
+ $attribs = array_map( array( 'UtfNormal', 'cleanUp' ), $attribs );
+ }
+ if( $contents ) {
+ $contents = UtfNormal::cleanUp( $contents );
+ }
+ return self::element( $element, $attribs, $contents );
+ }
+
+ // Shortcuts
+ public static function openElement( $element, $attribs = null ) { return self::element( $element, $attribs, null ); }
+ public static function closeElement( $element ) { return "</$element>"; }
+
+ /**
+ * Create a namespace selector
+ *
+ * @param $selected Mixed: the namespace which should be selected, default ''
+ * @param $allnamespaces String: value of a special item denoting all namespaces. Null to not include (default)
+ * @param $includehidden Bool: include hidden namespaces?
+ * @return String: Html string containing the namespace selector
+ */
+ public static function &namespaceSelector($selected = '', $allnamespaces = null, $includehidden=false) {
+ global $wgContLang;
+ if( $selected !== '' ) {
+ if( is_null( $selected ) ) {
+ // No namespace selected; let exact match work without hitting Main
+ $selected = '';
+ } else {
+ // Let input be numeric strings without breaking the empty match.
+ $selected = intval( $selected );
+ }
+ }
+ $s = "\n<select id='namespace' name='namespace' class='namespaceselector'>\n";
+ $arr = $wgContLang->getFormattedNamespaces();
+ if( !is_null($allnamespaces) ) {
+ $arr = array($allnamespaces => wfMsg('namespacesall')) + $arr;
+ }
+ foreach ($arr as $index => $name) {
+ if ($index < NS_MAIN) continue;
+
+ $name = $index !== 0 ? $name : wfMsg('blanknamespace');
+
+ if ($index === $selected) {
+ $s .= "\t" . self::element("option",
+ array("value" => $index, "selected" => "selected"),
+ $name) . "\n";
+ } else {
+ $s .= "\t" . self::element("option", array("value" => $index), $name) . "\n";
+ }
+ }
+ $s .= "</select>\n";
+ return $s;
+ }
+
+ public static function span( $text, $class, $attribs=array() ) {
+ return self::element( 'span', array( 'class' => $class ) + $attribs, $text );
+ }
+
+ /**
+ * Convenience function to build an HTML text input field
+ * @return string HTML
+ */
+ public static function input( $name, $size=false, $value=false, $attribs=array() ) {
+ return self::element( 'input', array(
+ 'name' => $name,
+ 'size' => $size,
+ 'value' => $value ) + $attribs );
+ }
+
+ /**
+ * Internal function for use in checkboxes and radio buttons and such.
+ * @return array
+ */
+ public static function attrib( $name, $present = true ) {
+ return $present ? array( $name => $name ) : array();
+ }
+
+ /**
+ * Convenience function to build an HTML checkbox
+ * @return string HTML
+ */
+ public static function check( $name, $checked=false, $attribs=array() ) {
+ return self::element( 'input', array_merge(
+ array(
+ 'name' => $name,
+ 'type' => 'checkbox',
+ 'value' => 1 ),
+ self::attrib( 'checked', $checked ),
+ $attribs ) );
+ }
+
+ /**
+ * Convenience function to build an HTML radio button
+ * @return string HTML
+ */
+ public static function radio( $name, $value, $checked=false, $attribs=array() ) {
+ return self::element( 'input', array(
+ 'name' => $name,
+ 'type' => 'radio',
+ 'value' => $value ) + self::attrib( 'checked', $checked ) + $attribs );
+ }
+
+ /**
+ * Convenience function to build an HTML form label
+ * @return string HTML
+ */
+ public static function label( $label, $id ) {
+ return self::element( 'label', array( 'for' => $id ), $label );
+ }
+
+ /**
+ * Convenience function to build an HTML text input field with a label
+ * @return string HTML
+ */
+ public static function inputLabel( $label, $name, $id, $size=false, $value=false, $attribs=array() ) {
+ return Xml::label( $label, $id ) .
+ '&nbsp;' .
+ self::input( $name, $size, $value, array( 'id' => $id ) + $attribs );
+ }
+
+ /**
+ * Convenience function to build an HTML checkbox with a label
+ * @return string HTML
+ */
+ public static function checkLabel( $label, $name, $id, $checked=false, $attribs=array() ) {
+ return self::check( $name, $checked, array( 'id' => $id ) + $attribs ) .
+ '&nbsp;' .
+ self::label( $label, $id );
+ }
+
+ /**
+ * Convenience function to build an HTML radio button with a label
+ * @return string HTML
+ */
+ public static function radioLabel( $label, $name, $value, $id, $checked=false, $attribs=array() ) {
+ return self::radio( $name, $value, $checked, array( 'id' => $id ) + $attribs ) .
+ '&nbsp;' .
+ self::label( $label, $id );
+ }
+
+ /**
+ * Convenience function to build an HTML submit button
+ * @param $value String: label text for the button
+ * @param $attribs Array: optional custom attributes
+ * @return string HTML
+ */
+ public static function submitButton( $value, $attribs=array() ) {
+ return self::element( 'input', array( 'type' => 'submit', 'value' => $value ) + $attribs );
+ }
+
+ /**
+ * Convenience function to build an HTML hidden form field.
+ * @todo Document $name parameter.
+ * @param $name FIXME
+ * @param $value String: label text for the button
+ * @param $attribs Array: optional custom attributes
+ * @return string HTML
+ */
+ public static function hidden( $name, $value, $attribs=array() ) {
+ return self::element( 'input', array(
+ 'name' => $name,
+ 'type' => 'hidden',
+ 'value' => $value ) + $attribs );
+ }
+
+ /**
+ * Convenience function to build an HTML drop-down list item.
+ * @param $text String: text for this item
+ * @param $value String: form submission value; if empty, use text
+ * @param $selected boolean: if true, will be the default selected item
+ * @param $attribs array: optional additional HTML attributes
+ * @return string HTML
+ */
+ public static function option( $text, $value=null, $selected=false,
+ $attribs=array() ) {
+ if( !is_null( $value ) ) {
+ $attribs['value'] = $value;
+ }
+ if( $selected ) {
+ $attribs['selected'] = 'selected';
+ }
+ return self::element( 'option', $attribs, $text );
+ }
+
+ /**
+ * Returns an escaped string suitable for inclusion in a string literal
+ * for JavaScript source code.
+ * Illegal control characters are assumed not to be present.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function escapeJsString( $string ) {
+ // See ECMA 262 section 7.8.4 for string literal format
+ $pairs = array(
+ "\\" => "\\\\",
+ "\"" => "\\\"",
+ '\'' => '\\\'',
+ "\n" => "\\n",
+ "\r" => "\\r",
+
+ # To avoid closing the element or CDATA section
+ "<" => "\\x3c",
+ ">" => "\\x3e",
+
+ # To avoid any complaints about bad entity refs
+ "&" => "\\x26",
+ );
+ return strtr( $string, $pairs );
+ }
+
+ /**
+ * Encode a variable of unknown type to JavaScript.
+ * Doesn't support hashtables just yet.
+ */
+ public static function encodeJsVar( $value ) {
+ if ( is_bool( $value ) ) {
+ $s = $value ? 'true' : 'false';
+ } elseif ( is_null( $value ) ) {
+ $s = 'null';
+ } elseif ( is_int( $value ) ) {
+ $s = $value;
+ } elseif ( is_array( $value ) ) {
+ $s = '[';
+ foreach ( $value as $name => $elt ) {
+ if ( $s != '[' ) {
+ $s .= ', ';
+ }
+ $s .= self::encodeJsVar( $elt );
+ }
+ $s .= ']';
+ } else {
+ $s = '"' . self::escapeJsString( $value ) . '"';
+ }
+ return $s;
+ }
+
+
+ /**
+ * Check if a string is well-formed XML.
+ * Must include the surrounding tag.
+ *
+ * @param $text String: string to test.
+ * @return bool
+ *
+ * @todo Error position reporting return
+ */
+ public static function isWellFormed( $text ) {
+ $parser = xml_parser_create( "UTF-8" );
+
+ # case folding violates XML standard, turn it off
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
+
+ if( !xml_parse( $parser, $text, true ) ) {
+ //$err = xml_error_string( xml_get_error_code( $parser ) );
+ //$position = xml_get_current_byte_index( $parser );
+ //$fragment = $this->extractFragment( $html, $position );
+ //$this->mXmlError = "$err at byte $position:\n$fragment";
+ xml_parser_free( $parser );
+ return false;
+ }
+ xml_parser_free( $parser );
+ return true;
+ }
+
+ /**
+ * Check if a string is a well-formed XML fragment.
+ * Wraps fragment in an \<html\> bit and doctype, so it can be a fragment
+ * and can use HTML named entities.
+ *
+ * @param $text String:
+ * @return bool
+ */
+ public static function isWellFormedXmlFragment( $text ) {
+ $html =
+ Sanitizer::hackDocType() .
+ '<html>' .
+ $text .
+ '</html>';
+ return Xml::isWellFormed( $html );
+ }
+
+ /**
+ * Replace " > and < with their respective HTML entities ( &quot;,
+ * &gt;, &lt;)
+ *
+ * @param $in String: text that might contain HTML tags.
+ * @return string Escaped string
+ */
+ public static function escapeTagsOnly( $in ) {
+ return str_replace(
+ array( '"', '>', '<' ),
+ array( '&quot;', '&gt;', '&lt;' ),
+ $in );
+ }
+}
+?>
diff --git a/includes/XmlFunctions.php b/includes/XmlFunctions.php
new file mode 100644
index 000000000000..cbdcf5c4b884
--- /dev/null
+++ b/includes/XmlFunctions.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Aliases for functions in the Xml module
+ * Look at the Xml class (Xml.php) for the implementations.
+ */
+function wfElement( $element, $attribs = null, $contents = '') {
+ return Xml::element( $element, $attribs, $contents );
+}
+function wfElementClean( $element, $attribs = array(), $contents = '') {
+ return Xml::elementClean( $element, $attribs, $contents );
+}
+function wfOpenElement( $element, $attribs = null ) {
+ return Xml::openElement( $element, $attribs );
+}
+function wfCloseElement( $element ) {
+ return "</$element>";
+}
+function &HTMLnamespaceselector($selected = '', $allnamespaces = null, $includehidden=false) {
+ return Xml::namespaceSelector( $selected, $allnamespaces, $includehidden );
+}
+function wfSpan( $text, $class, $attribs=array() ) {
+ return Xml::span( $text, $class, $attribs );
+}
+function wfInput( $name, $size=false, $value=false, $attribs=array() ) {
+ return Xml::input( $name, $size, $value, $attribs );
+}
+function wfAttrib( $name, $present = true ) {
+ return Xml::attrib( $name, $present );
+}
+function wfCheck( $name, $checked=false, $attribs=array() ) {
+ return Xml::check( $name, $checked, $attribs );
+}
+function wfRadio( $name, $value, $checked=false, $attribs=array() ) {
+ return Xml::radio( $name, $value, $checked, $attribs );
+}
+function wfLabel( $label, $id ) {
+ return Xml::label( $label, $id );
+}
+function wfInputLabel( $label, $name, $id, $size=false, $value=false, $attribs=array() ) {
+ return Xml::inputLabel( $label, $name, $id, $size, $value, $attribs );
+}
+function wfCheckLabel( $label, $name, $id, $checked=false, $attribs=array() ) {
+ return Xml::checkLabel( $label, $name, $id, $checked, $attribs );
+}
+function wfRadioLabel( $label, $name, $value, $id, $checked=false, $attribs=array() ) {
+ return Xml::radioLabel( $label, $name, $value, $id, $checked, $attribs );
+}
+function wfSubmitButton( $value, $attribs=array() ) {
+ return Xml::submitButton( $value, $attribs );
+}
+function wfHidden( $name, $value, $attribs=array() ) {
+ return Xml::hidden( $name, $value, $attribs );
+}
+function wfEscapeJsString( $string ) {
+ return Xml::escapeJsString( $string );
+}
+function wfIsWellFormedXml( $text ) {
+ return Xml::isWellFormed( $text );
+}
+function wfIsWellFormedXmlFragment( $text ) {
+ return Xml::isWellFormedXmlFragment( $text );
+}
+
+
+?>
diff --git a/includes/ZhClient.php b/includes/ZhClient.php
new file mode 100644
index 000000000000..9c9461d5397b
--- /dev/null
+++ b/includes/ZhClient.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * @package MediaWiki
+ */
+
+/**
+ * Client for querying zhdaemon
+ *
+ * @package MediaWiki
+ */
+class ZhClient {
+ var $mHost, $mPort, $mFP, $mConnected;
+
+ /**
+ * Constructor
+ *
+ * @access private
+ */
+ function ZhClient($host, $port) {
+ $this->mHost = $host;
+ $this->mPort = $port;
+ $this->mConnected = $this->connect();
+ }
+
+ /**
+ * Check if connection to zhdaemon is successful
+ *
+ * @access public
+ */
+ function isconnected() {
+ return $this->mConnected;
+ }
+
+ /**
+ * Establish conncetion
+ *
+ * @access private
+ */
+ function connect() {
+ wfSuppressWarnings();
+ $errno = $errstr = '';
+ $this->mFP = fsockopen($this->mHost, $this->mPort, $errno, $errstr, 30);
+ wfRestoreWarnings();
+ if(!$this->mFP) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Query the daemon and return the result
+ *
+ * @access private
+ */
+ function query($request) {
+ if(!$this->mConnected)
+ return false;
+
+ fwrite($this->mFP, $request);
+
+ $result=fgets($this->mFP, 1024);
+
+ list($status, $len) = explode(" ", $result);
+ if($status == 'ERROR') {
+ //$len is actually the error code...
+ print "zhdaemon error $len<br />\n";
+ return false;
+ }
+ $bytesread=0;
+ $data='';
+ while(!feof($this->mFP) && $bytesread<$len) {
+ $str= fread($this->mFP, $len-$bytesread);
+ $bytesread += strlen($str);
+ $data .= $str;
+ }
+ //data should be of length $len. otherwise something is wrong
+ if(strlen($data) != $len)
+ return false;
+ return $data;
+ }
+
+ /**
+ * Convert the input to a different language variant
+ *
+ * @param string $text input text
+ * @param string $tolang language variant
+ * @return string the converted text
+ * @access public
+ */
+ function convert($text, $tolang) {
+ $len = strlen($text);
+ $q = "CONV $tolang $len\n$text";
+ $result = $this->query($q);
+ if(!$result)
+ $result = $text;
+ return $result;
+ }
+
+ /**
+ * Convert the input to all possible variants
+ *
+ * @param string $text input text
+ * @return array langcode => converted_string
+ * @access public
+ */
+ function convertToAllVariants($text) {
+ $len = strlen($text);
+ $q = "CONV ALL $len\n$text";
+ $result = $this->query($q);
+ if(!$result)
+ return false;
+ list($infoline, $data) = explode('|', $result, 2);
+ $info = explode(";", $infoline);
+ $ret = array();
+ $i=0;
+ foreach($info as $variant) {
+ list($code, $len) = explode(' ', $variant);
+ $ret[strtolower($code)] = substr($data, $i, $len);
+ $i+=$len;
+ }
+ return $ret;
+ }
+ /**
+ * Perform word segmentation
+ *
+ * @param string $text input text
+ * @return string segmented text
+ * @access public
+ */
+ function segment($text) {
+ $len = strlen($text);
+ $q = "SEG $len\n$text";
+ $result = $this->query($q);
+ if(!$result) {// fallback to character based segmentation
+ $result = ZhClientFake::segment($text);
+ }
+ return $result;
+ }
+
+ /**
+ * Close the connection
+ *
+ * @access public
+ */
+ function close() {
+ fclose($this->mFP);
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/ZhConversion.php b/includes/ZhConversion.php
new file mode 100644
index 000000000000..e63281eb5595
--- /dev/null
+++ b/includes/ZhConversion.php
@@ -0,0 +1,8457 @@
+<?php
+/**
+ * Simplified/Traditional Chinese conversion tables
+ *
+ * Automatically generated using code and data in includes/zhtable/
+ * Do not modify directly!
+ *
+ * @package MediaWiki
+*/
+
+$zh2TW=array(
+"画"=>"畫",
+"板"=>"板",
+"表"=>"表",
+"才"=>"才",
+"丑"=>"醜",
+"出"=>"出",
+"淀"=>"澱",
+"冬"=>"冬",
+"范"=>"範",
+"丰"=>"豐",
+"刮"=>"刮",
+"后"=>"後",
+"胡"=>"胡",
+"回"=>"回",
+"伙"=>"夥",
+"姜"=>"薑",
+"借"=>"借",
+"克"=>"克",
+"困"=>"困",
+"漓"=>"漓",
+"里"=>"里",
+"帘"=>"簾",
+"霉"=>"霉",
+"面"=>"面",
+"蔑"=>"蔑",
+"千"=>"千",
+"秋"=>"秋",
+"松"=>"松",
+"咸"=>"咸",
+"向"=>"向",
+"余"=>"餘",
+"郁"=>"鬱",
+"御"=>"御",
+"愿"=>"願",
+"云"=>"雲",
+"芸"=>"芸",
+"沄"=>"沄",
+"致"=>"致",
+"制"=>"制",
+"朱"=>"朱",
+"筑"=>"築",
+"准"=>"準",
+"厂"=>"廠",
+"广"=>"廣",
+"辟"=>"闢",
+"别"=>"別",
+"卜"=>"卜",
+"沈"=>"沈",
+"冲"=>"沖",
+"种"=>"種",
+"虫"=>"蟲",
+"担"=>"擔",
+"党"=>"黨",
+"斗"=>"鬥",
+"儿"=>"兒",
+"干"=>"乾",
+"谷"=>"谷",
+"柜"=>"櫃",
+"合"=>"合",
+"划"=>"劃",
+"坏"=>"壞",
+"几"=>"幾",
+"系"=>"系",
+"家"=>"家",
+"价"=>"價",
+"据"=>"據",
+"卷"=>"捲",
+"适"=>"適",
+"蜡"=>"蠟",
+"腊"=>"臘",
+"了"=>"了",
+"累"=>"累",
+"么"=>"麽",
+"蒙"=>"蒙",
+"万"=>"萬",
+"宁"=>"寧",
+"朴"=>"樸",
+"苹"=>"蘋",
+"仆"=>"僕",
+"曲"=>"曲",
+"确"=>"確",
+"舍"=>"舍",
+"胜"=>"勝",
+"术"=>"術",
+"台"=>"台",
+"体"=>"體",
+"涂"=>"塗",
+"叶"=>"葉",
+"吁"=>"吁",
+"旋"=>"旋",
+"佣"=>"傭",
+"与"=>"與",
+"折"=>"折",
+"征"=>"徵",
+"症"=>"症",
+"恶"=>"惡",
+"发"=>"發",
+"复"=>"復",
+"汇"=>"匯",
+"获"=>"獲",
+"饥"=>"飢",
+"尽"=>"盡",
+"历"=>"歷",
+"卤"=>"滷",
+"弥"=>"彌",
+"签"=>"簽",
+"纤"=>"纖",
+"苏"=>"蘇",
+"坛"=>"壇",
+"团"=>"團",
+"须"=>"須",
+"脏"=>"臟",
+"只"=>"只",
+"钟"=>"鐘",
+"药"=>"藥",
+"同"=>"同",
+"志"=>"志",
+"杯"=>"杯",
+"岳"=>"岳",
+"布"=>"布",
+"当"=>"當",
+"吊"=>"弔",
+"仇"=>"仇",
+"蕴"=>"蘊",
+"线"=>"線",
+"为"=>"為",
+"产"=>"產",
+"众"=>"眾",
+"伪"=>"偽",
+"凫"=>"鳧",
+"厕"=>"廁",
+"启"=>"啟",
+"墙"=>"牆",
+"壳"=>"殼",
+"奖"=>"獎",
+"妫"=>"媯",
+"并"=>"並",
+"录"=>"錄",
+"悫"=>"愨",
+"极"=>"極",
+"沩"=>"溈",
+"瘘"=>"瘺",
+"硷"=>"鹼",
+"竖"=>"豎",
+"绝"=>"絕",
+"绣"=>"繡",
+"绦"=>"絛",
+"绱"=>"緔",
+"绷"=>"綳",
+"绿"=>"綠",
+"缰"=>"韁",
+"苧"=>"苎",
+"莼"=>"蒓",
+"说"=>"說",
+"谣"=>"謠",
+"谫"=>"譾",
+"赃"=>"贓",
+"赍"=>"齎",
+"赝"=>"贗",
+"酝"=>"醞",
+"采"=>"採",
+"钩"=>"鉤",
+"钵"=>"缽",
+"锈"=>"銹",
+"锐"=>"銳",
+"锨"=>"杴",
+"镌"=>"鐫",
+"镢"=>"钁",
+"阅"=>"閱",
+"颓"=>"頹",
+"颜"=>"顏",
+"骂"=>"罵",
+"鲇"=>"鯰",
+"鲞"=>"鯗",
+"鳄"=>"鱷",
+"鸡"=>"雞",
+"鹚"=>"鶿",
+"䌶"=>"䊷",
+"䜥"=>"𧩙",
+"专"=>"專",
+"业"=>"業",
+"丛"=>"叢",
+"东"=>"東",
+"丝"=>"絲",
+"丢"=>"丟",
+"两"=>"兩",
+"严"=>"嚴",
+"丧"=>"喪",
+"个"=>"個",
+"临"=>"臨",
+"丽"=>"麗",
+"举"=>"舉",
+"义"=>"義",
+"乌"=>"烏",
+"乐"=>"樂",
+"乔"=>"喬",
+"习"=>"習",
+"乡"=>"鄉",
+"书"=>"書",
+"买"=>"買",
+"乱"=>"亂",
+"争"=>"爭",
+"于"=>"於",
+"亏"=>"虧",
+"亚"=>"亞",
+"亩"=>"畝",
+"亲"=>"親",
+"亵"=>"褻",
+"亸"=>"嚲",
+"亿"=>"億",
+"仅"=>"僅",
+"从"=>"從",
+"仑"=>"侖",
+"仓"=>"倉",
+"仪"=>"儀",
+"们"=>"們",
+"优"=>"優",
+"会"=>"會",
+"伛"=>"傴",
+"伞"=>"傘",
+"伟"=>"偉",
+"传"=>"傳",
+"伣"=>"俔",
+"伤"=>"傷",
+"伥"=>"倀",
+"伦"=>"倫",
+"伧"=>"傖",
+"伫"=>"佇",
+"佥"=>"僉",
+"侠"=>"俠",
+"侣"=>"侶",
+"侥"=>"僥",
+"侦"=>"偵",
+"侧"=>"側",
+"侨"=>"僑",
+"侩"=>"儈",
+"侪"=>"儕",
+"侬"=>"儂",
+"俣"=>"俁",
+"俦"=>"儔",
+"俨"=>"儼",
+"俩"=>"倆",
+"俪"=>"儷",
+"俫"=>"倈",
+"俭"=>"儉",
+"债"=>"債",
+"倾"=>"傾",
+"偬"=>"傯",
+"偻"=>"僂",
+"偾"=>"僨",
+"偿"=>"償",
+"傥"=>"儻",
+"傧"=>"儐",
+"储"=>"儲",
+"傩"=>"儺",
+"兑"=>"兌",
+"兖"=>"兗",
+"兰"=>"蘭",
+"关"=>"關",
+"兴"=>"興",
+"兹"=>"茲",
+"养"=>"養",
+"兽"=>"獸",
+"冁"=>"囅",
+"内"=>"內",
+"冈"=>"岡",
+"册"=>"冊",
+"写"=>"寫",
+"军"=>"軍",
+"农"=>"農",
+"冯"=>"馮",
+"决"=>"決",
+"况"=>"況",
+"冻"=>"凍",
+"净"=>"凈",
+"凉"=>"涼",
+"减"=>"減",
+"凑"=>"湊",
+"凛"=>"凜",
+"凤"=>"鳳",
+"凭"=>"憑",
+"凯"=>"凱",
+"击"=>"擊",
+"凿"=>"鑿",
+"刍"=>"芻",
+"刘"=>"劉",
+"则"=>"則",
+"刚"=>"剛",
+"创"=>"創",
+"删"=>"刪",
+"刬"=>"剗",
+"刭"=>"剄",
+"刹"=>"剎",
+"刽"=>"劊",
+"刿"=>"劌",
+"剀"=>"剴",
+"剂"=>"劑",
+"剐"=>"剮",
+"剑"=>"劍",
+"剥"=>"剝",
+"剧"=>"劇",
+"劝"=>"勸",
+"办"=>"辦",
+"务"=>"務",
+"劢"=>"勱",
+"动"=>"動",
+"励"=>"勵",
+"劲"=>"勁",
+"劳"=>"勞",
+"势"=>"勢",
+"勋"=>"勛",
+"勚"=>"勩",
+"匀"=>"勻",
+"匦"=>"匭",
+"匮"=>"匱",
+"区"=>"區",
+"医"=>"醫",
+"华"=>"華",
+"协"=>"協",
+"单"=>"單",
+"卖"=>"賣",
+"卢"=>"盧",
+"卫"=>"衛",
+"却"=>"卻",
+"厅"=>"廳",
+"厉"=>"厲",
+"压"=>"壓",
+"厌"=>"厭",
+"厍"=>"厙",
+"厐"=>"龎",
+"厘"=>"釐",
+"厢"=>"廂",
+"厣"=>"厴",
+"厦"=>"廈",
+"厨"=>"廚",
+"厩"=>"廄",
+"厮"=>"廝",
+"县"=>"縣",
+"叁"=>"叄",
+"参"=>"參",
+"双"=>"雙",
+"变"=>"變",
+"叙"=>"敘",
+"叠"=>"疊",
+"号"=>"號",
+"叹"=>"嘆",
+"叽"=>"嘰",
+"吓"=>"嚇",
+"吕"=>"呂",
+"吗"=>"嗎",
+"吣"=>"唚",
+"吨"=>"噸",
+"听"=>"聽",
+"吴"=>"吳",
+"呐"=>"吶",
+"呒"=>"嘸",
+"呓"=>"囈",
+"呕"=>"嘔",
+"呖"=>"嚦",
+"呗"=>"唄",
+"员"=>"員",
+"呙"=>"咼",
+"呛"=>"嗆",
+"呜"=>"嗚",
+"咏"=>"詠",
+"咙"=>"嚨",
+"咛"=>"嚀",
+"咝"=>"噝",
+"咤"=>"吒",
+"响"=>"響",
+"哑"=>"啞",
+"哒"=>"噠",
+"哓"=>"嘵",
+"哔"=>"嗶",
+"哕"=>"噦",
+"哗"=>"嘩",
+"哙"=>"噲",
+"哜"=>"嚌",
+"哝"=>"噥",
+"哟"=>"喲",
+"唛"=>"嘜",
+"唝"=>"嗊",
+"唠"=>"嘮",
+"唡"=>"啢",
+"唢"=>"嗩",
+"唤"=>"喚",
+"啧"=>"嘖",
+"啬"=>"嗇",
+"啭"=>"囀",
+"啮"=>"嚙",
+"啴"=>"嘽",
+"啸"=>"嘯",
+"㖞"=>"喎",
+"喷"=>"噴",
+"喽"=>"嘍",
+"喾"=>"嚳",
+"嗫"=>"囁",
+"嗳"=>"噯",
+"嘘"=>"噓",
+"嘤"=>"嚶",
+"嘱"=>"囑",
+"噜"=>"嚕",
+"嚣"=>"囂",
+"园"=>"園",
+"囱"=>"囪",
+"围"=>"圍",
+"囵"=>"圇",
+"国"=>"國",
+"图"=>"圖",
+"圆"=>"圓",
+"圣"=>"聖",
+"圹"=>"壙",
+"场"=>"場",
+"坂"=>"阪",
+"块"=>"塊",
+"坚"=>"堅",
+"坜"=>"壢",
+"坝"=>"壩",
+"坞"=>"塢",
+"坟"=>"墳",
+"坠"=>"墜",
+"垄"=>"壟",
+"垅"=>"壠",
+"垆"=>"壚",
+"垒"=>"壘",
+"垦"=>"墾",
+"垩"=>"堊",
+"垫"=>"墊",
+"垭"=>"埡",
+"垱"=>"壋",
+"垲"=>"塏",
+"垴"=>"堖",
+"埘"=>"塒",
+"埙"=>"塤",
+"埚"=>"堝",
+"埯"=>"垵",
+"堑"=>"塹",
+"堕"=>"墮",
+"𡒄"=>"壈",
+"壮"=>"壯",
+"声"=>"聲",
+"壶"=>"壺",
+"壸"=>"壼",
+"处"=>"處",
+"备"=>"備",
+"够"=>"夠",
+"头"=>"頭",
+"夸"=>"誇",
+"夹"=>"夾",
+"夺"=>"奪",
+"奁"=>"奩",
+"奂"=>"奐",
+"奋"=>"奮",
+"奥"=>"奧",
+"奸"=>"姦",
+"妆"=>"妝",
+"妇"=>"婦",
+"妈"=>"媽",
+"妩"=>"嫵",
+"妪"=>"嫗",
+"姗"=>"姍",
+"姹"=>"奼",
+"娄"=>"婁",
+"娅"=>"婭",
+"娆"=>"嬈",
+"娇"=>"嬌",
+"娈"=>"孌",
+"娱"=>"娛",
+"娲"=>"媧",
+"娴"=>"嫻",
+"婳"=>"嫿",
+"婴"=>"嬰",
+"婵"=>"嬋",
+"婶"=>"嬸",
+"媪"=>"媼",
+"嫒"=>"嬡",
+"嫔"=>"嬪",
+"嫱"=>"嬙",
+"嬷"=>"嬤",
+"孙"=>"孫",
+"学"=>"學",
+"孪"=>"孿",
+"宝"=>"寶",
+"实"=>"實",
+"宠"=>"寵",
+"审"=>"審",
+"宪"=>"憲",
+"宫"=>"宮",
+"宽"=>"寬",
+"宾"=>"賓",
+"寝"=>"寢",
+"对"=>"對",
+"寻"=>"尋",
+"导"=>"導",
+"寿"=>"壽",
+"将"=>"將",
+"尔"=>"爾",
+"尘"=>"塵",
+"尝"=>"嘗",
+"尧"=>"堯",
+"尴"=>"尷",
+"尸"=>"屍",
+"层"=>"層",
+"屃"=>"屓",
+"屉"=>"屜",
+"届"=>"屆",
+"属"=>"屬",
+"屡"=>"屢",
+"屦"=>"屨",
+"屿"=>"嶼",
+"岁"=>"歲",
+"岂"=>"豈",
+"岖"=>"嶇",
+"岗"=>"崗",
+"岘"=>"峴",
+"岙"=>"嶴",
+"岚"=>"嵐",
+"岛"=>"島",
+"岭"=>"嶺",
+"岽"=>"崬",
+"岿"=>"巋",
+"峄"=>"嶧",
+"峡"=>"峽",
+"峣"=>"嶢",
+"峤"=>"嶠",
+"峥"=>"崢",
+"峦"=>"巒",
+"崂"=>"嶗",
+"崃"=>"崍",
+"崄"=>"嶮",
+"崭"=>"嶄",
+"嵘"=>"嶸",
+"嵚"=>"嶔",
+"嵝"=>"嶁",
+"巅"=>"巔",
+"巩"=>"鞏",
+"巯"=>"巰",
+"币"=>"幣",
+"帅"=>"帥",
+"师"=>"師",
+"帏"=>"幃",
+"帐"=>"帳",
+"帜"=>"幟",
+"带"=>"帶",
+"帧"=>"幀",
+"帮"=>"幫",
+"帱"=>"幬",
+"帻"=>"幘",
+"帼"=>"幗",
+"幂"=>"冪",
+"幺"=>"么",
+"庄"=>"莊",
+"庆"=>"慶",
+"庐"=>"廬",
+"庑"=>"廡",
+"库"=>"庫",
+"应"=>"應",
+"庙"=>"廟",
+"庞"=>"龐",
+"废"=>"廢",
+"廪"=>"廩",
+"开"=>"開",
+"异"=>"異",
+"弃"=>"棄",
+"弑"=>"弒",
+"张"=>"張",
+"弪"=>"弳",
+"弯"=>"彎",
+"弹"=>"彈",
+"强"=>"強",
+"归"=>"歸",
+"彝"=>"彞",
+"彦"=>"彥",
+"彻"=>"徹",
+"径"=>"徑",
+"徕"=>"徠",
+"忆"=>"憶",
+"忏"=>"懺",
+"忧"=>"憂",
+"忾"=>"愾",
+"怀"=>"懷",
+"态"=>"態",
+"怂"=>"慫",
+"怃"=>"憮",
+"怄"=>"慪",
+"怅"=>"悵",
+"怆"=>"愴",
+"怜"=>"憐",
+"总"=>"總",
+"怼"=>"懟",
+"怿"=>"懌",
+"恋"=>"戀",
+"恒"=>"恆",
+"恳"=>"懇",
+"恸"=>"慟",
+"恹"=>"懨",
+"恺"=>"愷",
+"恻"=>"惻",
+"恼"=>"惱",
+"恽"=>"惲",
+"悦"=>"悅",
+"悬"=>"懸",
+"悭"=>"慳",
+"悮"=>"悞",
+"悯"=>"憫",
+"惊"=>"驚",
+"惧"=>"懼",
+"惨"=>"慘",
+"惩"=>"懲",
+"惫"=>"憊",
+"惬"=>"愜",
+"惭"=>"慚",
+"惮"=>"憚",
+"惯"=>"慣",
+"愠"=>"慍",
+"愤"=>"憤",
+"愦"=>"憒",
+"慑"=>"懾",
+"懑"=>"懣",
+"懒"=>"懶",
+"懔"=>"懍",
+"戆"=>"戇",
+"戋"=>"戔",
+"戏"=>"戲",
+"戗"=>"戧",
+"战"=>"戰",
+"戬"=>"戩",
+"戯"=>"戱",
+"户"=>"戶",
+"扑"=>"撲",
+"执"=>"執",
+"扩"=>"擴",
+"扪"=>"捫",
+"扫"=>"掃",
+"扬"=>"揚",
+"扰"=>"擾",
+"抚"=>"撫",
+"抛"=>"拋",
+"抟"=>"摶",
+"抠"=>"摳",
+"抡"=>"掄",
+"抢"=>"搶",
+"护"=>"護",
+"报"=>"報",
+"拟"=>"擬",
+"拢"=>"攏",
+"拣"=>"揀",
+"拥"=>"擁",
+"拦"=>"攔",
+"拧"=>"擰",
+"拨"=>"撥",
+"择"=>"擇",
+"挂"=>"掛",
+"挚"=>"摯",
+"挛"=>"攣",
+"挜"=>"掗",
+"挝"=>"撾",
+"挞"=>"撻",
+"挟"=>"挾",
+"挠"=>"撓",
+"挡"=>"擋",
+"挢"=>"撟",
+"挣"=>"掙",
+"挤"=>"擠",
+"挥"=>"揮",
+"挦"=>"撏",
+"挽"=>"輓",
+"捝"=>"挩",
+"捞"=>"撈",
+"损"=>"損",
+"捡"=>"撿",
+"换"=>"換",
+"捣"=>"搗",
+"掳"=>"擄",
+"掴"=>"摑",
+"掷"=>"擲",
+"掸"=>"撣",
+"掺"=>"摻",
+"掼"=>"摜",
+"揽"=>"攬",
+"揾"=>"搵",
+"揿"=>"撳",
+"搀"=>"攙",
+"搁"=>"擱",
+"搂"=>"摟",
+"搅"=>"攪",
+"携"=>"攜",
+"摄"=>"攝",
+"摅"=>"攄",
+"摆"=>"擺",
+"摇"=>"搖",
+"摈"=>"擯",
+"摊"=>"攤",
+"撄"=>"攖",
+"撑"=>"撐",
+"㧑"=>"撝",
+"撵"=>"攆",
+"撷"=>"擷",
+"撸"=>"擼",
+"撺"=>"攛",
+"㧟"=>"擓",
+"擞"=>"擻",
+"攒"=>"攢",
+"敌"=>"敵",
+"敛"=>"斂",
+"数"=>"數",
+"斋"=>"齋",
+"斓"=>"斕",
+"斩"=>"斬",
+"断"=>"斷",
+"无"=>"無",
+"旧"=>"舊",
+"时"=>"時",
+"旷"=>"曠",
+"旸"=>"暘",
+"昙"=>"曇",
+"昼"=>"晝",
+"昽"=>"曨",
+"显"=>"顯",
+"晋"=>"晉",
+"晒"=>"曬",
+"晓"=>"曉",
+"晔"=>"曄",
+"晕"=>"暈",
+"晖"=>"暉",
+"暂"=>"暫",
+"暧"=>"曖",
+"机"=>"機",
+"杀"=>"殺",
+"杂"=>"雜",
+"权"=>"權",
+"杆"=>"桿",
+"条"=>"條",
+"来"=>"來",
+"杨"=>"楊",
+"杩"=>"榪",
+"杰"=>"傑",
+"构"=>"構",
+"枞"=>"樅",
+"枢"=>"樞",
+"枣"=>"棗",
+"枥"=>"櫪",
+"枧"=>"梘",
+"枨"=>"棖",
+"枪"=>"槍",
+"枫"=>"楓",
+"枭"=>"梟",
+"柠"=>"檸",
+"柽"=>"檉",
+"栀"=>"梔",
+"栅"=>"柵",
+"标"=>"標",
+"栈"=>"棧",
+"栉"=>"櫛",
+"栊"=>"櫳",
+"栋"=>"棟",
+"栌"=>"櫨",
+"栎"=>"櫟",
+"栏"=>"欄",
+"树"=>"樹",
+"栖"=>"棲",
+"栗"=>"慄",
+"样"=>"樣",
+"栾"=>"欒",
+"桠"=>"椏",
+"桡"=>"橈",
+"桢"=>"楨",
+"档"=>"檔",
+"桤"=>"榿",
+"桥"=>"橋",
+"桦"=>"樺",
+"桧"=>"檜",
+"桨"=>"槳",
+"桩"=>"樁",
+"梦"=>"夢",
+"梼"=>"檮",
+"梾"=>"棶",
+"梿"=>"槤",
+"检"=>"檢",
+"棁"=>"梲",
+"棂"=>"欞",
+"椁"=>"槨",
+"椟"=>"櫝",
+"椠"=>"槧",
+"椤"=>"欏",
+"椭"=>"橢",
+"楼"=>"樓",
+"榄"=>"欖",
+"榅"=>"榲",
+"榇"=>"櫬",
+"榈"=>"櫚",
+"榉"=>"櫸",
+"槚"=>"檟",
+"槛"=>"檻",
+"槟"=>"檳",
+"槠"=>"櫧",
+"横"=>"橫",
+"樯"=>"檣",
+"樱"=>"櫻",
+"橥"=>"櫫",
+"橱"=>"櫥",
+"橹"=>"櫓",
+"橼"=>"櫞",
+"檩"=>"檁",
+"欢"=>"歡",
+"欤"=>"歟",
+"欧"=>"歐",
+"歼"=>"殲",
+"殁"=>"歿",
+"殇"=>"殤",
+"残"=>"殘",
+"殒"=>"殞",
+"殓"=>"殮",
+"殚"=>"殫",
+"殡"=>"殯",
+"㱮"=>"殨",
+"殴"=>"毆",
+"毁"=>"毀",
+"毂"=>"轂",
+"毕"=>"畢",
+"毙"=>"斃",
+"毡"=>"氈",
+"毵"=>"毿",
+"氇"=>"氌",
+"气"=>"氣",
+"氢"=>"氫",
+"氩"=>"氬",
+"氲"=>"氳",
+"汉"=>"漢",
+"汤"=>"湯",
+"汹"=>"洶",
+"沟"=>"溝",
+"没"=>"沒",
+"沣"=>"灃",
+"沤"=>"漚",
+"沥"=>"瀝",
+"沦"=>"淪",
+"沧"=>"滄",
+"沪"=>"滬",
+"泞"=>"濘",
+"注"=>"註",
+"泪"=>"淚",
+"泶"=>"澩",
+"泷"=>"瀧",
+"泸"=>"瀘",
+"泺"=>"濼",
+"泻"=>"瀉",
+"泼"=>"潑",
+"泽"=>"澤",
+"泾"=>"涇",
+"洁"=>"潔",
+"洒"=>"灑",
+"洼"=>"窪",
+"浃"=>"浹",
+"浅"=>"淺",
+"浆"=>"漿",
+"浇"=>"澆",
+"浈"=>"湞",
+"浊"=>"濁",
+"测"=>"測",
+"浍"=>"澮",
+"济"=>"濟",
+"浏"=>"瀏",
+"浐"=>"滻",
+"浑"=>"渾",
+"浒"=>"滸",
+"浓"=>"濃",
+"浔"=>"潯",
+"涛"=>"濤",
+"涝"=>"澇",
+"涞"=>"淶",
+"涟"=>"漣",
+"涠"=>"潿",
+"涡"=>"渦",
+"涣"=>"渙",
+"涤"=>"滌",
+"润"=>"潤",
+"涧"=>"澗",
+"涨"=>"漲",
+"涩"=>"澀",
+"渊"=>"淵",
+"渌"=>"淥",
+"渍"=>"漬",
+"渎"=>"瀆",
+"渐"=>"漸",
+"渑"=>"澠",
+"渔"=>"漁",
+"渖"=>"瀋",
+"渗"=>"滲",
+"温"=>"溫",
+"湾"=>"灣",
+"湿"=>"濕",
+"溃"=>"潰",
+"溅"=>"濺",
+"溆"=>"漵",
+"滗"=>"潷",
+"滚"=>"滾",
+"滞"=>"滯",
+"滟"=>"灧",
+"滠"=>"灄",
+"满"=>"滿",
+"滢"=>"瀅",
+"滤"=>"濾",
+"滥"=>"濫",
+"滦"=>"灤",
+"滨"=>"濱",
+"滩"=>"灘",
+"滪"=>"澦",
+"漤"=>"灠",
+"潆"=>"瀠",
+"潇"=>"瀟",
+"潋"=>"瀲",
+"潍"=>"濰",
+"潜"=>"潛",
+"潴"=>"瀦",
+"澜"=>"瀾",
+"濑"=>"瀨",
+"濒"=>"瀕",
+"灏"=>"灝",
+"灭"=>"滅",
+"灯"=>"燈",
+"灵"=>"靈",
+"灶"=>"竈",
+"灾"=>"災",
+"灿"=>"燦",
+"炀"=>"煬",
+"炉"=>"爐",
+"炖"=>"燉",
+"炜"=>"煒",
+"炝"=>"熗",
+"点"=>"點",
+"炼"=>"煉",
+"炽"=>"熾",
+"烁"=>"爍",
+"烂"=>"爛",
+"烃"=>"烴",
+"烛"=>"燭",
+"烟"=>"煙",
+"烦"=>"煩",
+"烧"=>"燒",
+"烨"=>"燁",
+"烩"=>"燴",
+"烫"=>"燙",
+"烬"=>"燼",
+"热"=>"熱",
+"焕"=>"煥",
+"焖"=>"燜",
+"焘"=>"燾",
+"煴"=>"熅",
+"爱"=>"愛",
+"爷"=>"爺",
+"牍"=>"牘",
+"牦"=>"氂",
+"牵"=>"牽",
+"牺"=>"犧",
+"犊"=>"犢",
+"状"=>"狀",
+"犷"=>"獷",
+"犸"=>"獁",
+"犹"=>"猶",
+"狈"=>"狽",
+"狝"=>"獮",
+"狞"=>"獰",
+"独"=>"獨",
+"狭"=>"狹",
+"狮"=>"獅",
+"狯"=>"獪",
+"狰"=>"猙",
+"狱"=>"獄",
+"狲"=>"猻",
+"猃"=>"獫",
+"猎"=>"獵",
+"猕"=>"獼",
+"猡"=>"玀",
+"猪"=>"豬",
+"猫"=>"貓",
+"猬"=>"蝟",
+"献"=>"獻",
+"獭"=>"獺",
+"玑"=>"璣",
+"玚"=>"瑒",
+"玛"=>"瑪",
+"玮"=>"瑋",
+"环"=>"環",
+"现"=>"現",
+"玱"=>"瑲",
+"玺"=>"璽",
+"珐"=>"琺",
+"珑"=>"瓏",
+"珰"=>"璫",
+"珲"=>"琿",
+"琏"=>"璉",
+"琐"=>"瑣",
+"琼"=>"瓊",
+"瑶"=>"瑤",
+"瑷"=>"璦",
+"璎"=>"瓔",
+"瓒"=>"瓚",
+"瓯"=>"甌",
+"电"=>"電",
+"画"=>"畫",
+"畅"=>"暢",
+"畴"=>"疇",
+"疖"=>"癤",
+"疗"=>"療",
+"疟"=>"瘧",
+"疠"=>"癘",
+"疡"=>"瘍",
+"疬"=>"癧",
+"疭"=>"瘲",
+"疮"=>"瘡",
+"疯"=>"瘋",
+"疱"=>"皰",
+"疴"=>"痾",
+"痈"=>"癰",
+"痉"=>"痙",
+"痒"=>"癢",
+"痖"=>"瘂",
+"痨"=>"癆",
+"痪"=>"瘓",
+"痫"=>"癇",
+"瘅"=>"癉",
+"瘆"=>"瘮",
+"瘗"=>"瘞",
+"瘪"=>"癟",
+"瘫"=>"癱",
+"瘾"=>"癮",
+"瘿"=>"癭",
+"癞"=>"癩",
+"癣"=>"癬",
+"癫"=>"癲",
+"皑"=>"皚",
+"皱"=>"皺",
+"皲"=>"皸",
+"盏"=>"盞",
+"盐"=>"鹽",
+"监"=>"監",
+"盖"=>"蓋",
+"盗"=>"盜",
+"盘"=>"盤",
+"眍"=>"瞘",
+"眦"=>"眥",
+"眬"=>"矓",
+"着"=>"著",
+"睁"=>"睜",
+"睐"=>"睞",
+"睑"=>"瞼",
+"瞆"=>"瞶",
+"瞒"=>"瞞",
+"䁖"=>"瞜",
+"瞩"=>"矚",
+"矫"=>"矯",
+"矶"=>"磯",
+"矾"=>"礬",
+"矿"=>"礦",
+"砀"=>"碭",
+"码"=>"碼",
+"砖"=>"磚",
+"砗"=>"硨",
+"砚"=>"硯",
+"砜"=>"碸",
+"砺"=>"礪",
+"砻"=>"礱",
+"砾"=>"礫",
+"础"=>"礎",
+"硁"=>"硜",
+"硕"=>"碩",
+"硖"=>"硤",
+"硗"=>"磽",
+"硙"=>"磑",
+"碍"=>"礙",
+"碛"=>"磧",
+"碜"=>"磣",
+"碱"=>"鹼",
+"礼"=>"禮",
+"祃"=>"禡",
+"祎"=>"禕",
+"祢"=>"禰",
+"祯"=>"禎",
+"祷"=>"禱",
+"祸"=>"禍",
+"禀"=>"稟",
+"禄"=>"祿",
+"禅"=>"禪",
+"离"=>"離",
+"秃"=>"禿",
+"秆"=>"稈",
+"积"=>"積",
+"称"=>"稱",
+"秽"=>"穢",
+"秾"=>"穠",
+"稆"=>"穭",
+"税"=>"稅",
+"稣"=>"穌",
+"稳"=>"穩",
+"穑"=>"穡",
+"穷"=>"窮",
+"窃"=>"竊",
+"窍"=>"竅",
+"窎"=>"窵",
+"窑"=>"窯",
+"窜"=>"竄",
+"窝"=>"窩",
+"窥"=>"窺",
+"窦"=>"竇",
+"窭"=>"窶",
+"竞"=>"競",
+"笃"=>"篤",
+"笋"=>"筍",
+"笔"=>"筆",
+"笕"=>"筧",
+"笺"=>"箋",
+"笼"=>"籠",
+"笾"=>"籩",
+"筚"=>"篳",
+"筛"=>"篩",
+"筜"=>"簹",
+"筝"=>"箏",
+"䇲"=>"筴",
+"筹"=>"籌",
+"筼"=>"篔",
+"简"=>"簡",
+"箓"=>"籙",
+"箦"=>"簀",
+"箧"=>"篋",
+"箨"=>"籜",
+"箩"=>"籮",
+"箪"=>"簞",
+"箫"=>"簫",
+"篑"=>"簣",
+"篓"=>"簍",
+"篮"=>"籃",
+"篱"=>"籬",
+"簖"=>"籪",
+"籁"=>"籟",
+"籴"=>"糴",
+"类"=>"類",
+"籼"=>"秈",
+"粜"=>"糶",
+"粝"=>"糲",
+"粤"=>"粵",
+"粪"=>"糞",
+"粮"=>"糧",
+"糁"=>"糝",
+"糇"=>"餱",
+"紧"=>"緊",
+"䌷"=>"紬",
+"䌹"=>"絅",
+"絷"=>"縶",
+"䌸"=>"縳",
+"䍁"=>"繸",
+"纟"=>"糹",
+"纠"=>"糾",
+"纡"=>"紆",
+"红"=>"紅",
+"纣"=>"紂",
+"纥"=>"紇",
+"约"=>"約",
+"级"=>"級",
+"纨"=>"紈",
+"纩"=>"纊",
+"纪"=>"紀",
+"纫"=>"紉",
+"纬"=>"緯",
+"纭"=>"紜",
+"纮"=>"紘",
+"纯"=>"純",
+"纰"=>"紕",
+"纱"=>"紗",
+"纲"=>"綱",
+"纳"=>"納",
+"纴"=>"紝",
+"纵"=>"縱",
+"纶"=>"綸",
+"纷"=>"紛",
+"纸"=>"紙",
+"纹"=>"紋",
+"纺"=>"紡",
+"纻"=>"紵",
+"纼"=>"紖",
+"纽"=>"紐",
+"纾"=>"紓",
+"绀"=>"紺",
+"绁"=>"紲",
+"绂"=>"紱",
+"练"=>"練",
+"组"=>"組",
+"绅"=>"紳",
+"细"=>"細",
+"织"=>"織",
+"终"=>"終",
+"绉"=>"縐",
+"绊"=>"絆",
+"绋"=>"紼",
+"绌"=>"絀",
+"绍"=>"紹",
+"绎"=>"繹",
+"经"=>"經",
+"绐"=>"紿",
+"绑"=>"綁",
+"绒"=>"絨",
+"结"=>"結",
+"绔"=>"絝",
+"绕"=>"繞",
+"绖"=>"絰",
+"绗"=>"絎",
+"绘"=>"繪",
+"给"=>"給",
+"绚"=>"絢",
+"绛"=>"絳",
+"络"=>"絡",
+"绞"=>"絞",
+"统"=>"統",
+"绠"=>"綆",
+"绡"=>"綃",
+"绢"=>"絹",
+"绤"=>"綌",
+"绥"=>"綏",
+"继"=>"繼",
+"绨"=>"綈",
+"绩"=>"績",
+"绪"=>"緒",
+"绫"=>"綾",
+"绬"=>"緓",
+"续"=>"續",
+"绮"=>"綺",
+"绯"=>"緋",
+"绰"=>"綽",
+"绲"=>"緄",
+"绳"=>"繩",
+"维"=>"維",
+"绵"=>"綿",
+"绶"=>"綬",
+"绸"=>"綢",
+"绹"=>"綯",
+"绺"=>"綹",
+"绻"=>"綣",
+"综"=>"綜",
+"绽"=>"綻",
+"绾"=>"綰",
+"缀"=>"綴",
+"缁"=>"緇",
+"缂"=>"緙",
+"缃"=>"緗",
+"缄"=>"緘",
+"缅"=>"緬",
+"缆"=>"纜",
+"缇"=>"緹",
+"缈"=>"緲",
+"缉"=>"緝",
+"缊"=>"縕",
+"缋"=>"繢",
+"缌"=>"緦",
+"缍"=>"綞",
+"缎"=>"緞",
+"缏"=>"緶",
+"缑"=>"緱",
+"缒"=>"縋",
+"缓"=>"緩",
+"缔"=>"締",
+"缕"=>"縷",
+"编"=>"編",
+"缗"=>"緡",
+"缘"=>"緣",
+"缙"=>"縉",
+"缚"=>"縛",
+"缛"=>"縟",
+"缜"=>"縝",
+"缝"=>"縫",
+"缞"=>"縗",
+"缟"=>"縞",
+"缠"=>"纏",
+"缡"=>"縭",
+"缢"=>"縊",
+"缣"=>"縑",
+"缤"=>"繽",
+"缥"=>"縹",
+"缦"=>"縵",
+"缧"=>"縲",
+"缨"=>"纓",
+"缩"=>"縮",
+"缪"=>"繆",
+"缫"=>"繅",
+"缬"=>"纈",
+"缭"=>"繚",
+"缮"=>"繕",
+"缯"=>"繒",
+"缱"=>"繾",
+"缲"=>"繰",
+"缳"=>"繯",
+"缴"=>"繳",
+"缵"=>"纘",
+"罂"=>"罌",
+"网"=>"網",
+"罗"=>"羅",
+"罚"=>"罰",
+"罢"=>"罷",
+"罴"=>"羆",
+"羁"=>"羈",
+"羟"=>"羥",
+"翘"=>"翹",
+"耢"=>"耮",
+"耧"=>"耬",
+"耸"=>"聳",
+"耻"=>"恥",
+"聂"=>"聶",
+"聋"=>"聾",
+"职"=>"職",
+"聍"=>"聹",
+"联"=>"聯",
+"聩"=>"聵",
+"聪"=>"聰",
+"肃"=>"肅",
+"肠"=>"腸",
+"肤"=>"膚",
+"肮"=>"骯",
+"肴"=>"餚",
+"肾"=>"腎",
+"肿"=>"腫",
+"胀"=>"脹",
+"胁"=>"脅",
+"胆"=>"膽",
+"胧"=>"朧",
+"胨"=>"腖",
+"胪"=>"臚",
+"胫"=>"脛",
+"胶"=>"膠",
+"脉"=>"脈",
+"脍"=>"膾",
+"脐"=>"臍",
+"脑"=>"腦",
+"脓"=>"膿",
+"脔"=>"臠",
+"脚"=>"腳",
+"脱"=>"脫",
+"脶"=>"腡",
+"脸"=>"臉",
+"腭"=>"齶",
+"腻"=>"膩",
+"腼"=>"靦",
+"腽"=>"膃",
+"腾"=>"騰",
+"膑"=>"臏",
+"臜"=>"臢",
+"舆"=>"輿",
+"舣"=>"艤",
+"舰"=>"艦",
+"舱"=>"艙",
+"舻"=>"艫",
+"艰"=>"艱",
+"艳"=>"艷",
+"艺"=>"藝",
+"节"=>"節",
+"芈"=>"羋",
+"芗"=>"薌",
+"芜"=>"蕪",
+"芦"=>"蘆",
+"苁"=>"蓯",
+"苇"=>"葦",
+"苈"=>"藶",
+"苋"=>"莧",
+"苌"=>"萇",
+"苍"=>"蒼",
+"苎"=>"苧",
+"茎"=>"莖",
+"茏"=>"蘢",
+"茑"=>"蔦",
+"茔"=>"塋",
+"茕"=>"煢",
+"茧"=>"繭",
+"荆"=>"荊",
+"荐"=>"薦",
+"荙"=>"薘",
+"荚"=>"莢",
+"荛"=>"蕘",
+"荜"=>"蓽",
+"荞"=>"蕎",
+"荟"=>"薈",
+"荠"=>"薺",
+"荡"=>"蕩",
+"荣"=>"榮",
+"荤"=>"葷",
+"荥"=>"滎",
+"荦"=>"犖",
+"荧"=>"熒",
+"荨"=>"蕁",
+"荩"=>"藎",
+"荪"=>"蓀",
+"荫"=>"蔭",
+"荬"=>"蕒",
+"荭"=>"葒",
+"荮"=>"葤",
+"莅"=>"蒞",
+"莱"=>"萊",
+"莲"=>"蓮",
+"莳"=>"蒔",
+"莴"=>"萵",
+"莶"=>"薟",
+"莸"=>"蕕",
+"莹"=>"瑩",
+"莺"=>"鶯",
+"萝"=>"蘿",
+"萤"=>"螢",
+"营"=>"營",
+"萦"=>"縈",
+"萧"=>"蕭",
+"萨"=>"薩",
+"葱"=>"蔥",
+"蒇"=>"蕆",
+"蒉"=>"蕢",
+"蒋"=>"蔣",
+"蒌"=>"蔞",
+"蓝"=>"藍",
+"蓟"=>"薊",
+"蓠"=>"蘺",
+"蓣"=>"蕷",
+"蓥"=>"鎣",
+"蓦"=>"驀",
+"蔂"=>"虆",
+"蔷"=>"薔",
+"蔹"=>"蘞",
+"蔺"=>"藺",
+"蔼"=>"藹",
+"蕰"=>"薀",
+"蕲"=>"蘄",
+"薮"=>"藪",
+"藓"=>"蘚",
+"蘖"=>"櫱",
+"虏"=>"虜",
+"虑"=>"慮",
+"虚"=>"虛",
+"虬"=>"虯",
+"虮"=>"蟣",
+"虽"=>"雖",
+"虾"=>"蝦",
+"虿"=>"蠆",
+"蚀"=>"蝕",
+"蚁"=>"蟻",
+"蚂"=>"螞",
+"蚕"=>"蠶",
+"蚬"=>"蜆",
+"蛊"=>"蠱",
+"蛎"=>"蠣",
+"蛏"=>"蟶",
+"蛮"=>"蠻",
+"蛰"=>"蟄",
+"蛱"=>"蛺",
+"蛲"=>"蟯",
+"蛳"=>"螄",
+"蛴"=>"蠐",
+"蜕"=>"蛻",
+"蜗"=>"蝸",
+"蝇"=>"蠅",
+"蝈"=>"蟈",
+"蝉"=>"蟬",
+"蝼"=>"螻",
+"蝾"=>"蠑",
+"螀"=>"螿",
+"螨"=>"蟎",
+"蟏"=>"蠨",
+"衅"=>"釁",
+"衔"=>"銜",
+"补"=>"補",
+"衬"=>"襯",
+"衮"=>"袞",
+"袄"=>"襖",
+"袅"=>"裊",
+"袆"=>"褘",
+"袜"=>"襪",
+"袭"=>"襲",
+"袯"=>"襏",
+"装"=>"裝",
+"裆"=>"襠",
+"裈"=>"褌",
+"裢"=>"褳",
+"裣"=>"襝",
+"裤"=>"褲",
+"裥"=>"襇",
+"褛"=>"褸",
+"褴"=>"襤",
+"见"=>"見",
+"观"=>"觀",
+"觃"=>"覎",
+"规"=>"規",
+"觅"=>"覓",
+"视"=>"視",
+"觇"=>"覘",
+"览"=>"覽",
+"觉"=>"覺",
+"觊"=>"覬",
+"觋"=>"覡",
+"觌"=>"覿",
+"觍"=>"覥",
+"觎"=>"覦",
+"觏"=>"覯",
+"觐"=>"覲",
+"觑"=>"覷",
+"觞"=>"觴",
+"触"=>"觸",
+"觯"=>"觶",
+"訚"=>"誾",
+"䜣"=>"訢",
+"誉"=>"譽",
+"誊"=>"謄",
+"讠"=>"訁",
+"计"=>"計",
+"订"=>"訂",
+"讣"=>"訃",
+"认"=>"認",
+"讥"=>"譏",
+"讦"=>"訐",
+"讧"=>"訌",
+"讨"=>"討",
+"让"=>"讓",
+"讪"=>"訕",
+"讫"=>"訖",
+"讬"=>"託",
+"训"=>"訓",
+"议"=>"議",
+"讯"=>"訊",
+"记"=>"記",
+"讱"=>"訒",
+"讲"=>"講",
+"讳"=>"諱",
+"讴"=>"謳",
+"讵"=>"詎",
+"讶"=>"訝",
+"讷"=>"訥",
+"许"=>"許",
+"讹"=>"訛",
+"论"=>"論",
+"讻"=>"訩",
+"讼"=>"訟",
+"讽"=>"諷",
+"设"=>"設",
+"访"=>"訪",
+"诀"=>"訣",
+"证"=>"證",
+"诂"=>"詁",
+"诃"=>"訶",
+"评"=>"評",
+"诅"=>"詛",
+"识"=>"識",
+"诇"=>"詗",
+"诈"=>"詐",
+"诉"=>"訴",
+"诊"=>"診",
+"诋"=>"詆",
+"诌"=>"謅",
+"词"=>"詞",
+"诎"=>"詘",
+"诏"=>"詔",
+"诐"=>"詖",
+"译"=>"譯",
+"诒"=>"詒",
+"诓"=>"誆",
+"诔"=>"誄",
+"试"=>"試",
+"诖"=>"詿",
+"诗"=>"詩",
+"诘"=>"詰",
+"诙"=>"詼",
+"诚"=>"誠",
+"诛"=>"誅",
+"诜"=>"詵",
+"话"=>"話",
+"诞"=>"誕",
+"诟"=>"詬",
+"诠"=>"詮",
+"诡"=>"詭",
+"询"=>"詢",
+"诣"=>"詣",
+"诤"=>"諍",
+"该"=>"該",
+"详"=>"詳",
+"诧"=>"詫",
+"诨"=>"諢",
+"诩"=>"詡",
+"诪"=>"譸",
+"诫"=>"誡",
+"诬"=>"誣",
+"语"=>"語",
+"诮"=>"誚",
+"误"=>"誤",
+"诰"=>"誥",
+"诱"=>"誘",
+"诲"=>"誨",
+"诳"=>"誑",
+"诵"=>"誦",
+"诶"=>"誒",
+"请"=>"請",
+"诸"=>"諸",
+"诹"=>"諏",
+"诺"=>"諾",
+"读"=>"讀",
+"诼"=>"諑",
+"诽"=>"誹",
+"课"=>"課",
+"诿"=>"諉",
+"谀"=>"諛",
+"谁"=>"誰",
+"谂"=>"諗",
+"调"=>"調",
+"谄"=>"諂",
+"谅"=>"諒",
+"谆"=>"諄",
+"谇"=>"誶",
+"谈"=>"談",
+"谊"=>"誼",
+"谋"=>"謀",
+"谌"=>"諶",
+"谍"=>"諜",
+"谎"=>"謊",
+"谏"=>"諫",
+"谐"=>"諧",
+"谑"=>"謔",
+"谒"=>"謁",
+"谓"=>"謂",
+"谔"=>"諤",
+"谕"=>"諭",
+"谖"=>"諼",
+"谗"=>"讒",
+"谘"=>"諮",
+"谙"=>"諳",
+"谚"=>"諺",
+"谛"=>"諦",
+"谜"=>"謎",
+"谝"=>"諞",
+"谞"=>"諝",
+"谟"=>"謨",
+"谠"=>"讜",
+"谡"=>"謖",
+"谢"=>"謝",
+"谤"=>"謗",
+"谥"=>"謚",
+"谦"=>"謙",
+"谧"=>"謐",
+"谨"=>"謹",
+"谩"=>"謾",
+"谪"=>"謫",
+"谬"=>"謬",
+"谭"=>"譚",
+"谮"=>"譖",
+"谯"=>"譙",
+"谰"=>"讕",
+"谱"=>"譜",
+"谲"=>"譎",
+"谳"=>"讞",
+"谴"=>"譴",
+"谵"=>"譫",
+"谶"=>"讖",
+"豮"=>"豶",
+"贝"=>"貝",
+"贞"=>"貞",
+"负"=>"負",
+"贠"=>"貟",
+"贡"=>"貢",
+"财"=>"財",
+"责"=>"責",
+"贤"=>"賢",
+"败"=>"敗",
+"账"=>"賬",
+"货"=>"貨",
+"质"=>"質",
+"贩"=>"販",
+"贪"=>"貪",
+"贫"=>"貧",
+"贬"=>"貶",
+"购"=>"購",
+"贮"=>"貯",
+"贯"=>"貫",
+"贰"=>"貳",
+"贱"=>"賤",
+"贲"=>"賁",
+"贳"=>"貰",
+"贴"=>"貼",
+"贵"=>"貴",
+"贶"=>"貺",
+"贷"=>"貸",
+"贸"=>"貿",
+"费"=>"費",
+"贺"=>"賀",
+"贻"=>"貽",
+"贼"=>"賊",
+"贽"=>"贄",
+"贾"=>"賈",
+"贿"=>"賄",
+"赀"=>"貲",
+"赁"=>"賃",
+"赂"=>"賂",
+"资"=>"資",
+"赅"=>"賅",
+"赆"=>"贐",
+"赇"=>"賕",
+"赈"=>"賑",
+"赉"=>"賚",
+"赊"=>"賒",
+"赋"=>"賦",
+"赌"=>"賭",
+"赎"=>"贖",
+"赏"=>"賞",
+"赐"=>"賜",
+"赑"=>"贔",
+"赒"=>"賙",
+"赓"=>"賡",
+"赔"=>"賠",
+"赕"=>"賧",
+"赖"=>"賴",
+"赗"=>"賵",
+"赘"=>"贅",
+"赙"=>"賻",
+"赚"=>"賺",
+"赛"=>"賽",
+"赜"=>"賾",
+"赞"=>"贊",
+"赟"=>"贇",
+"赠"=>"贈",
+"赡"=>"贍",
+"赢"=>"贏",
+"赣"=>"贛",
+"赪"=>"赬",
+"赵"=>"趙",
+"赶"=>"趕",
+"趋"=>"趨",
+"趱"=>"趲",
+"趸"=>"躉",
+"跃"=>"躍",
+"跄"=>"蹌",
+"跞"=>"躒",
+"践"=>"踐",
+"跶"=>"躂",
+"跷"=>"蹺",
+"跸"=>"蹕",
+"跹"=>"躚",
+"跻"=>"躋",
+"踊"=>"踴",
+"踌"=>"躊",
+"踪"=>"蹤",
+"踬"=>"躓",
+"踯"=>"躑",
+"蹑"=>"躡",
+"蹒"=>"蹣",
+"蹰"=>"躕",
+"蹿"=>"躥",
+"躏"=>"躪",
+"躜"=>"躦",
+"躯"=>"軀",
+"车"=>"車",
+"轧"=>"軋",
+"轨"=>"軌",
+"轩"=>"軒",
+"轪"=>"軑",
+"轫"=>"軔",
+"转"=>"轉",
+"轭"=>"軛",
+"轮"=>"輪",
+"软"=>"軟",
+"轰"=>"轟",
+"轱"=>"軲",
+"轲"=>"軻",
+"轳"=>"轤",
+"轴"=>"軸",
+"轵"=>"軹",
+"轶"=>"軼",
+"轷"=>"軤",
+"轸"=>"軫",
+"轹"=>"轢",
+"轺"=>"軺",
+"轻"=>"輕",
+"轼"=>"軾",
+"载"=>"載",
+"轾"=>"輊",
+"轿"=>"轎",
+"辀"=>"輈",
+"辁"=>"輇",
+"辂"=>"輅",
+"较"=>"較",
+"辄"=>"輒",
+"辅"=>"輔",
+"辆"=>"輛",
+"辇"=>"輦",
+"辈"=>"輩",
+"辉"=>"輝",
+"辊"=>"輥",
+"辋"=>"輞",
+"辌"=>"輬",
+"辍"=>"輟",
+"辎"=>"輜",
+"辏"=>"輳",
+"辐"=>"輻",
+"辑"=>"輯",
+"辒"=>"轀",
+"输"=>"輸",
+"辔"=>"轡",
+"辕"=>"轅",
+"辖"=>"轄",
+"辗"=>"輾",
+"辘"=>"轆",
+"辙"=>"轍",
+"辚"=>"轔",
+"辞"=>"辭",
+"辩"=>"辯",
+"辫"=>"辮",
+"边"=>"邊",
+"辽"=>"遼",
+"达"=>"達",
+"迁"=>"遷",
+"过"=>"過",
+"迈"=>"邁",
+"运"=>"運",
+"还"=>"還",
+"这"=>"這",
+"进"=>"進",
+"远"=>"遠",
+"违"=>"違",
+"连"=>"連",
+"迟"=>"遲",
+"迩"=>"邇",
+"迳"=>"逕",
+"迹"=>"跡",
+"选"=>"選",
+"逊"=>"遜",
+"递"=>"遞",
+"逦"=>"邐",
+"逻"=>"邏",
+"遗"=>"遺",
+"遥"=>"遙",
+"邓"=>"鄧",
+"邝"=>"鄺",
+"邬"=>"鄔",
+"邮"=>"郵",
+"邹"=>"鄒",
+"邺"=>"鄴",
+"邻"=>"鄰",
+"郏"=>"郟",
+"郐"=>"鄶",
+"郑"=>"鄭",
+"郓"=>"鄆",
+"郦"=>"酈",
+"郧"=>"鄖",
+"郸"=>"鄲",
+"酂"=>"酇",
+"酦"=>"醱",
+"酱"=>"醬",
+"酽"=>"釅",
+"酾"=>"釃",
+"酿"=>"釀",
+"释"=>"釋",
+"鉴"=>"鑒",
+"銮"=>"鑾",
+"錾"=>"鏨",
+"钅"=>"釒",
+"钆"=>"釓",
+"钇"=>"釔",
+"针"=>"針",
+"钉"=>"釘",
+"钊"=>"釗",
+"钋"=>"釙",
+"钌"=>"釕",
+"钍"=>"釷",
+"钎"=>"釺",
+"钏"=>"釧",
+"钐"=>"釤",
+"钑"=>"鈒",
+"钒"=>"釩",
+"钓"=>"釣",
+"钔"=>"鍆",
+"钕"=>"釹",
+"钖"=>"鍚",
+"钗"=>"釵",
+"钘"=>"鈃",
+"钙"=>"鈣",
+"钚"=>"鈈",
+"钛"=>"鈦",
+"钜"=>"鉅",
+"钝"=>"鈍",
+"钞"=>"鈔",
+"钠"=>"鈉",
+"钡"=>"鋇",
+"钢"=>"鋼",
+"钣"=>"鈑",
+"钤"=>"鈐",
+"钥"=>"鑰",
+"钦"=>"欽",
+"钧"=>"鈞",
+"钨"=>"鎢",
+"钪"=>"鈧",
+"钫"=>"鈁",
+"钬"=>"鈥",
+"钭"=>"鈄",
+"钮"=>"鈕",
+"钯"=>"鈀",
+"钰"=>"鈺",
+"钱"=>"錢",
+"钲"=>"鉦",
+"钳"=>"鉗",
+"钴"=>"鈷",
+"钶"=>"鈳",
+"钷"=>"鉕",
+"钸"=>"鈽",
+"钹"=>"鈸",
+"钺"=>"鉞",
+"钻"=>"鑽",
+"钼"=>"鉬",
+"钽"=>"鉭",
+"钾"=>"鉀",
+"钿"=>"鈿",
+"铀"=>"鈾",
+"铁"=>"鐵",
+"铂"=>"鉑",
+"铃"=>"鈴",
+"铄"=>"鑠",
+"铅"=>"鉛",
+"铆"=>"鉚",
+"铇"=>"鉋",
+"铈"=>"鈰",
+"铉"=>"鉉",
+"铊"=>"鉈",
+"铋"=>"鉍",
+"铌"=>"鈮",
+"铍"=>"鈹",
+"铎"=>"鐸",
+"铏"=>"鉶",
+"铐"=>"銬",
+"铑"=>"銠",
+"铒"=>"鉺",
+"铓"=>"鋩",
+"铔"=>"錏",
+"铕"=>"銪",
+"铖"=>"鋮",
+"铗"=>"鋏",
+"铘"=>"鋣",
+"铙"=>"鐃",
+"铚"=>"銍",
+"铛"=>"鐺",
+"铜"=>"銅",
+"铝"=>"鋁",
+"铞"=>"銱",
+"铟"=>"銦",
+"铠"=>"鎧",
+"铡"=>"鍘",
+"铢"=>"銖",
+"铣"=>"銑",
+"铤"=>"鋌",
+"铥"=>"銩",
+"铦"=>"銛",
+"铧"=>"鏵",
+"铨"=>"銓",
+"铩"=>"鎩",
+"铪"=>"鉿",
+"铫"=>"銚",
+"铬"=>"鉻",
+"铭"=>"銘",
+"铮"=>"錚",
+"铯"=>"銫",
+"铰"=>"鉸",
+"铱"=>"銥",
+"铲"=>"鏟",
+"铳"=>"銃",
+"铴"=>"鐋",
+"铵"=>"銨",
+"银"=>"銀",
+"铷"=>"銣",
+"铸"=>"鑄",
+"铹"=>"鐒",
+"铺"=>"鋪",
+"铻"=>"鋙",
+"铼"=>"錸",
+"铽"=>"鋱",
+"链"=>"鏈",
+"铿"=>"鏗",
+"销"=>"銷",
+"锁"=>"鎖",
+"锂"=>"鋰",
+"锃"=>"鋥",
+"锄"=>"鋤",
+"锅"=>"鍋",
+"锆"=>"鋯",
+"锇"=>"鋨",
+"锉"=>"銼",
+"锊"=>"鋝",
+"锋"=>"鋒",
+"锌"=>"鋅",
+"锍"=>"鋶",
+"锎"=>"鐦",
+"锏"=>"鐧",
+"锑"=>"銻",
+"锒"=>"鋃",
+"锓"=>"鋟",
+"锔"=>"鋦",
+"锕"=>"錒",
+"锖"=>"錆",
+"锗"=>"鍺",
+"锘"=>"鍩",
+"错"=>"錯",
+"锚"=>"錨",
+"锛"=>"錛",
+"锜"=>"錡",
+"锝"=>"鍀",
+"锞"=>"錁",
+"锟"=>"錕",
+"锠"=>"錩",
+"锡"=>"錫",
+"锢"=>"錮",
+"锣"=>"鑼",
+"锤"=>"錘",
+"锥"=>"錐",
+"锦"=>"錦",
+"锧"=>"鑕",
+"锩"=>"錈",
+"锪"=>"鍃",
+"锫"=>"錇",
+"锬"=>"錟",
+"锭"=>"錠",
+"键"=>"鍵",
+"锯"=>"鋸",
+"锰"=>"錳",
+"锱"=>"錙",
+"锲"=>"鍥",
+"锳"=>"鍈",
+"锴"=>"鍇",
+"锵"=>"鏘",
+"锶"=>"鍶",
+"锷"=>"鍔",
+"锸"=>"鍤",
+"锹"=>"鍬",
+"锺"=>"鍾",
+"锻"=>"鍛",
+"锼"=>"鎪",
+"锽"=>"鍠",
+"锾"=>"鍰",
+"锿"=>"鎄",
+"镀"=>"鍍",
+"镁"=>"鎂",
+"镂"=>"鏤",
+"镃"=>"鎡",
+"镄"=>"鐨",
+"镅"=>"鎇",
+"镆"=>"鏌",
+"镇"=>"鎮",
+"镈"=>"鎛",
+"镉"=>"鎘",
+"镊"=>"鑷",
+"镋"=>"鎲",
+"镍"=>"鎳",
+"镎"=>"鎿",
+"镏"=>"鎦",
+"镐"=>"鎬",
+"镑"=>"鎊",
+"镒"=>"鎰",
+"镓"=>"鎵",
+"镔"=>"鑌",
+"镕"=>"鎔",
+"镖"=>"鏢",
+"镗"=>"鏜",
+"镘"=>"鏝",
+"镙"=>"鏍",
+"镚"=>"鏰",
+"镛"=>"鏞",
+"镜"=>"鏡",
+"镝"=>"鏑",
+"镞"=>"鏃",
+"镟"=>"鏇",
+"镠"=>"鏐",
+"镡"=>"鐔",
+"镣"=>"鐐",
+"镤"=>"鏷",
+"镥"=>"鑥",
+"镦"=>"鐓",
+"镧"=>"鑭",
+"镨"=>"鐠",
+"镩"=>"鑹",
+"镪"=>"鏹",
+"镫"=>"鐙",
+"镬"=>"鑊",
+"镭"=>"鐳",
+"镮"=>"鐶",
+"镯"=>"鐲",
+"镰"=>"鐮",
+"镱"=>"鐿",
+"镲"=>"鑔",
+"镳"=>"鑣",
+"镴"=>"鑞",
+"镵"=>"鑱",
+"镶"=>"鑲",
+"长"=>"長",
+"门"=>"門",
+"闩"=>"閂",
+"闪"=>"閃",
+"闫"=>"閆",
+"闬"=>"閈",
+"闭"=>"閉",
+"问"=>"問",
+"闯"=>"闖",
+"闰"=>"閏",
+"闱"=>"闈",
+"闲"=>"閑",
+"闳"=>"閎",
+"间"=>"間",
+"闵"=>"閔",
+"闶"=>"閌",
+"闷"=>"悶",
+"闸"=>"閘",
+"闹"=>"鬧",
+"闺"=>"閨",
+"闻"=>"聞",
+"闼"=>"闥",
+"闽"=>"閩",
+"闾"=>"閭",
+"闿"=>"闓",
+"阀"=>"閥",
+"阁"=>"閣",
+"阂"=>"閡",
+"阃"=>"閫",
+"阄"=>"鬮",
+"阆"=>"閬",
+"阇"=>"闍",
+"阈"=>"閾",
+"阉"=>"閹",
+"阊"=>"閶",
+"阋"=>"鬩",
+"阌"=>"閿",
+"阍"=>"閽",
+"阎"=>"閻",
+"阏"=>"閼",
+"阐"=>"闡",
+"阑"=>"闌",
+"阒"=>"闃",
+"阓"=>"闠",
+"阔"=>"闊",
+"阕"=>"闋",
+"阖"=>"闔",
+"阗"=>"闐",
+"阘"=>"闒",
+"阙"=>"闕",
+"阚"=>"闞",
+"阛"=>"闤",
+"队"=>"隊",
+"阳"=>"陽",
+"阴"=>"陰",
+"阵"=>"陣",
+"阶"=>"階",
+"际"=>"際",
+"陆"=>"陸",
+"陇"=>"隴",
+"陈"=>"陳",
+"陉"=>"陘",
+"陕"=>"陝",
+"陧"=>"隉",
+"陨"=>"隕",
+"险"=>"險",
+"随"=>"隨",
+"隐"=>"隱",
+"隶"=>"隸",
+"隽"=>"雋",
+"难"=>"難",
+"雏"=>"雛",
+"雠"=>"讎",
+"雳"=>"靂",
+"雾"=>"霧",
+"霁"=>"霽",
+"霡"=>"霢",
+"霭"=>"靄",
+"靓"=>"靚",
+"静"=>"靜",
+"靥"=>"靨",
+"鞑"=>"韃",
+"鞒"=>"鞽",
+"鞯"=>"韉",
+"韦"=>"韋",
+"韧"=>"韌",
+"韨"=>"韍",
+"韩"=>"韓",
+"韪"=>"韙",
+"韫"=>"韞",
+"韬"=>"韜",
+"韵"=>"韻",
+"页"=>"頁",
+"顶"=>"頂",
+"顷"=>"頃",
+"顸"=>"頇",
+"项"=>"項",
+"顺"=>"順",
+"顼"=>"頊",
+"顽"=>"頑",
+"顾"=>"顧",
+"顿"=>"頓",
+"颀"=>"頎",
+"颁"=>"頒",
+"颂"=>"頌",
+"颃"=>"頏",
+"预"=>"預",
+"颅"=>"顱",
+"领"=>"領",
+"颇"=>"頗",
+"颈"=>"頸",
+"颉"=>"頡",
+"颊"=>"頰",
+"颋"=>"頲",
+"颌"=>"頜",
+"颍"=>"潁",
+"颎"=>"熲",
+"颏"=>"頦",
+"颐"=>"頤",
+"频"=>"頻",
+"颒"=>"頮",
+"颔"=>"頷",
+"颕"=>"頴",
+"颖"=>"穎",
+"颗"=>"顆",
+"题"=>"題",
+"颙"=>"顒",
+"颚"=>"顎",
+"颛"=>"顓",
+"额"=>"額",
+"颞"=>"顳",
+"颟"=>"顢",
+"颠"=>"顛",
+"颡"=>"顙",
+"颢"=>"顥",
+"颤"=>"顫",
+"颥"=>"顬",
+"颦"=>"顰",
+"颧"=>"顴",
+"风"=>"風",
+"飏"=>"颺",
+"飐"=>"颭",
+"飑"=>"颮",
+"飒"=>"颯",
+"飓"=>"颶",
+"飔"=>"颸",
+"飕"=>"颼",
+"飖"=>"颻",
+"飗"=>"飀",
+"飘"=>"飄",
+"飙"=>"飆",
+"飚"=>"飈",
+"飞"=>"飛",
+"飨"=>"饗",
+"餍"=>"饜",
+"饣"=>"飠",
+"饤"=>"飣",
+"饦"=>"飥",
+"饧"=>"餳",
+"饨"=>"飩",
+"饩"=>"餼",
+"饪"=>"飪",
+"饫"=>"飫",
+"饬"=>"飭",
+"饭"=>"飯",
+"饮"=>"飲",
+"饯"=>"餞",
+"饰"=>"飾",
+"饱"=>"飽",
+"饲"=>"飼",
+"饳"=>"飿",
+"饴"=>"飴",
+"饵"=>"餌",
+"饶"=>"饒",
+"饷"=>"餉",
+"饸"=>"餄",
+"饹"=>"餎",
+"饺"=>"餃",
+"饻"=>"餏",
+"饼"=>"餅",
+"饽"=>"餑",
+"饾"=>"餖",
+"饿"=>"餓",
+"馀"=>"餘",
+"馁"=>"餒",
+"馂"=>"餕",
+"馃"=>"餜",
+"馄"=>"餛",
+"馅"=>"餡",
+"馆"=>"館",
+"馇"=>"餷",
+"馈"=>"饋",
+"馉"=>"餶",
+"馊"=>"餿",
+"馋"=>"饞",
+"馌"=>"饁",
+"馍"=>"饃",
+"馎"=>"餺",
+"馏"=>"餾",
+"馐"=>"饈",
+"馑"=>"饉",
+"馒"=>"饅",
+"馓"=>"饊",
+"馔"=>"饌",
+"馕"=>"饢",
+"马"=>"馬",
+"驭"=>"馭",
+"驮"=>"馱",
+"驯"=>"馴",
+"驰"=>"馳",
+"驱"=>"驅",
+"驲"=>"馹",
+"驳"=>"駁",
+"驴"=>"驢",
+"驵"=>"駔",
+"驶"=>"駛",
+"驷"=>"駟",
+"驸"=>"駙",
+"驹"=>"駒",
+"驺"=>"騶",
+"驻"=>"駐",
+"驼"=>"駝",
+"驽"=>"駑",
+"驾"=>"駕",
+"驿"=>"驛",
+"骀"=>"駘",
+"骁"=>"驍",
+"骃"=>"駰",
+"骄"=>"驕",
+"骅"=>"驊",
+"骆"=>"駱",
+"骇"=>"駭",
+"骈"=>"駢",
+"骉"=>"驫",
+"骊"=>"驪",
+"骋"=>"騁",
+"验"=>"驗",
+"骍"=>"騂",
+"骎"=>"駸",
+"骏"=>"駿",
+"骐"=>"騏",
+"骑"=>"騎",
+"骒"=>"騍",
+"骓"=>"騅",
+"骔"=>"騌",
+"骕"=>"驌",
+"骖"=>"驂",
+"骗"=>"騙",
+"骘"=>"騭",
+"骙"=>"騤",
+"骚"=>"騷",
+"骛"=>"騖",
+"骜"=>"驁",
+"骝"=>"騮",
+"骞"=>"騫",
+"骟"=>"騸",
+"骠"=>"驃",
+"骡"=>"騾",
+"骢"=>"驄",
+"骣"=>"驏",
+"骤"=>"驟",
+"骥"=>"驥",
+"骦"=>"驦",
+"骧"=>"驤",
+"髅"=>"髏",
+"髋"=>"髖",
+"髌"=>"髕",
+"鬓"=>"鬢",
+"魇"=>"魘",
+"魉"=>"魎",
+"鱼"=>"魚",
+"鱽"=>"魛",
+"鱾"=>"魢",
+"鱿"=>"魷",
+"鲀"=>"魨",
+"鲁"=>"魯",
+"鲂"=>"魴",
+"鲃"=>"䰾",
+"鲄"=>"魺",
+"鲅"=>"鮁",
+"鲆"=>"鮃",
+"鲈"=>"鱸",
+"鲉"=>"鮋",
+"鲊"=>"鮓",
+"鲋"=>"鮒",
+"鲌"=>"鮊",
+"鲍"=>"鮑",
+"鲎"=>"鱟",
+"鲏"=>"鮍",
+"鲐"=>"鮐",
+"鲑"=>"鮭",
+"鲒"=>"鮚",
+"鲓"=>"鮳",
+"鲔"=>"鮪",
+"鲕"=>"鮞",
+"鲖"=>"鮦",
+"鲗"=>"鰂",
+"鲘"=>"鮜",
+"鲙"=>"鱠",
+"鲚"=>"鱭",
+"鲛"=>"鮫",
+"鲜"=>"鮮",
+"鲝"=>"鮺",
+"鲟"=>"鱘",
+"鲠"=>"鯁",
+"鲡"=>"鱺",
+"鲢"=>"鰱",
+"鲣"=>"鰹",
+"鲤"=>"鯉",
+"鲥"=>"鰣",
+"鲦"=>"鰷",
+"鲧"=>"鯀",
+"鲨"=>"鯊",
+"鲩"=>"鯇",
+"鲪"=>"鮶",
+"鲫"=>"鯽",
+"鲬"=>"鯒",
+"鲭"=>"鯖",
+"鲮"=>"鯪",
+"鲯"=>"鯕",
+"鲰"=>"鯫",
+"鲱"=>"鯡",
+"鲲"=>"鯤",
+"鲳"=>"鯧",
+"鲴"=>"鯝",
+"鲵"=>"鯢",
+"鲶"=>"鯰",
+"鲷"=>"鯛",
+"鲸"=>"鯨",
+"鲹"=>"鰺",
+"鲺"=>"鯴",
+"鲻"=>"鯔",
+"鲼"=>"鱝",
+"鲽"=>"鰈",
+"鲾"=>"鰏",
+"鲿"=>"鱨",
+"鳀"=>"鯷",
+"鳁"=>"鰮",
+"鳂"=>"鰃",
+"鳃"=>"鰓",
+"鳅"=>"鰍",
+"鳆"=>"鰒",
+"鳇"=>"鰉",
+"鳈"=>"鰁",
+"鳉"=>"鱂",
+"鳊"=>"鯿",
+"鳋"=>"鰠",
+"鳌"=>"鰲",
+"鳍"=>"鰭",
+"鳎"=>"鰨",
+"鳏"=>"鰥",
+"鳐"=>"鰩",
+"鳑"=>"鰟",
+"鳒"=>"鰜",
+"鳓"=>"鰳",
+"鳔"=>"鰾",
+"鳕"=>"鱈",
+"鳖"=>"鱉",
+"鳗"=>"鰻",
+"鳘"=>"鰵",
+"鳙"=>"鱅",
+"鳚"=>"䲁",
+"鳛"=>"鰼",
+"鳜"=>"鱖",
+"鳝"=>"鱔",
+"鳞"=>"鱗",
+"鳟"=>"鱒",
+"鳠"=>"鱯",
+"鳡"=>"鱤",
+"鳢"=>"鱧",
+"鳣"=>"鱣",
+"䴓"=>"鳾",
+"䴕"=>"鴷",
+"䴔"=>"鵁",
+"䴖"=>"鶄",
+"䴗"=>"鶪",
+"䴘"=>"鷈",
+"䴙"=>"鷿",
+"鸟"=>"鳥",
+"鸠"=>"鳩",
+"鸢"=>"鳶",
+"鸣"=>"鳴",
+"鸤"=>"鳲",
+"鸥"=>"鷗",
+"鸦"=>"鴉",
+"鸧"=>"鶬",
+"鸨"=>"鴇",
+"鸩"=>"鴆",
+"鸪"=>"鴣",
+"鸫"=>"鶇",
+"鸬"=>"鸕",
+"鸭"=>"鴨",
+"鸮"=>"鴞",
+"鸯"=>"鴦",
+"鸰"=>"鴒",
+"鸱"=>"鴟",
+"鸲"=>"鴝",
+"鸳"=>"鴛",
+"鸴"=>"鷽",
+"鸵"=>"鴕",
+"鸶"=>"鷥",
+"鸷"=>"鷙",
+"鸸"=>"鴯",
+"鸹"=>"鴰",
+"鸺"=>"鵂",
+"鸻"=>"鴴",
+"鸼"=>"鵃",
+"鸽"=>"鴿",
+"鸾"=>"鸞",
+"鸿"=>"鴻",
+"鹀"=>"鵐",
+"鹁"=>"鵓",
+"鹂"=>"鸝",
+"鹃"=>"鵑",
+"鹄"=>"鵠",
+"鹅"=>"鵝",
+"鹆"=>"鵒",
+"鹇"=>"鷳",
+"鹈"=>"鵜",
+"鹉"=>"鵡",
+"鹊"=>"鵲",
+"鹋"=>"鶓",
+"鹌"=>"鵪",
+"鹍"=>"鵾",
+"鹎"=>"鵯",
+"鹏"=>"鵬",
+"鹐"=>"鵮",
+"鹑"=>"鶉",
+"鹒"=>"鶊",
+"鹓"=>"鵷",
+"鹔"=>"鷫",
+"鹕"=>"鶘",
+"鹖"=>"鶡",
+"鹗"=>"鶚",
+"鹘"=>"鶻",
+"鹙"=>"鶖",
+"鹛"=>"鶥",
+"鹜"=>"鶩",
+"鹝"=>"鷊",
+"鹞"=>"鷂",
+"鹟"=>"鶲",
+"鹠"=>"鶹",
+"鹡"=>"鶺",
+"鹢"=>"鷁",
+"鹣"=>"鶼",
+"鹤"=>"鶴",
+"鹥"=>"鷖",
+"鹦"=>"鸚",
+"鹧"=>"鷓",
+"鹨"=>"鷚",
+"鹩"=>"鷯",
+"鹪"=>"鷦",
+"鹫"=>"鷲",
+"鹬"=>"鷸",
+"鹭"=>"鷺",
+"鹯"=>"鸇",
+"鹰"=>"鷹",
+"鹱"=>"鸌",
+"鹲"=>"鸏",
+"鹳"=>"鸛",
+"鹴"=>"鸘",
+"鹾"=>"鹺",
+"麦"=>"麥",
+"麸"=>"麩",
+"麽"=>"麼",
+"黄"=>"黃",
+"黉"=>"黌",
+"黡"=>"黶",
+"黩"=>"黷",
+"黪"=>"黲",
+"黾"=>"黽",
+"鼋"=>"黿",
+"鼍"=>"鼉",
+"鼗"=>"鞀",
+"鼹"=>"鼴",
+"齐"=>"齊",
+"齑"=>"齏",
+"齿"=>"齒",
+"龀"=>"齔",
+"龁"=>"齕",
+"龂"=>"齗",
+"龃"=>"齟",
+"龄"=>"齡",
+"龅"=>"齙",
+"龆"=>"齠",
+"龇"=>"齜",
+"龈"=>"齦",
+"龉"=>"齬",
+"龊"=>"齪",
+"龋"=>"齲",
+"龌"=>"齷",
+"龙"=>"龍",
+"龚"=>"龔",
+"龛"=>"龕",
+"龟"=>"龜",
+
+"BIG-" => "BIG-",
+".PRG" => ".PRG",
+"一伙" => "一伙",
+"一并" => "一併",
+"一准" => "一准",
+"一划" => "一划",
+"一地里" => "一地裡",
+"一干" => "一干",
+"一树百获" => "一樹百穫",
+"一台" => "一臺",
+"一冲" => "一衝",
+"一只" => "一隻",
+"一发千钧" => "一髮千鈞",
+"一出" => "一齣",
+"七只" => "七隻",
+"三元里" => "三元裡",
+"三国志" => "三國誌",
+"三复" => "三複",
+"三只" => "三隻",
+"上吊" => "上吊",
+"上台" => "上臺",
+"下不了台" => "下不了臺",
+"下台" => "下臺",
+"下面" => "下麵",
+"不准" => "不准",
+"不吊" => "不吊",
+"不干" => "不幹",
+"不舍" => "不捨",
+"不知所云" => "不知所云",
+"不识台举" => "不識檯舉",
+"不锈钢" => "不鏽鋼",
+"丑剧" => "丑劇",
+"丑旦" => "丑旦",
+"丑角" => "丑角",
+"世界杯" => "世界盃",
+"并存着" => "並存著",
+"中岳" => "中嶽",
+"中台路" => "中臺路",
+"中台医专" => "中臺醫專",
+"丰南" => "丰南",
+"丰台" => "丰台",
+"丰姿" => "丰姿",
+"丰神俊朗" => "丰神俊朗",
+"丰采" => "丰采",
+"丰韵" => "丰韻",
+"主干" => "主幹",
+"九世之雠" => "九世之讎",
+"九只" => "九隻",
+"干丝" => "乾絲",
+"干着急" => "乾著急",
+"干面" => "乾麵",
+"乱发" => "亂髮",
+"云云" => "云云",
+"云何" => "云何",
+"云尔" => "云爾",
+"五岳" => "五嶽",
+"五斗柜" => "五斗櫃",
+"五斗橱" => "五斗櫥",
+"五斗米" => "五斗米",
+"五谷" => "五穀",
+"五行生克" => "五行生剋",
+"五只" => "五隻",
+"五出" => "五齣",
+"井里" => "井裡",
+"交卷" => "交卷",
+"人云亦云" => "人云亦云",
+"人物志" => "人物誌",
+"什锦面" => "什錦麵",
+"什么" => "什麼",
+"仆倒" => "仆倒",
+"仇雠" => "仇讎",
+"介系词" => "介係詞",
+"介系词" => "介繫詞",
+"仿制" => "仿製",
+"伙伕" => "伙伕",
+"伙伴" => "伙伴",
+"伙同" => "伙同",
+"伙夫" => "伙夫",
+"伙房" => "伙房",
+"伙计" => "伙計",
+"伙食" => "伙食",
+"布下" => "佈下",
+"布告" => "佈告",
+"布哨" => "佈哨",
+"布局" => "佈局",
+"布岗" => "佈崗",
+"布施" => "佈施",
+"布景" => "佈景",
+"布有" => "佈有",
+"布满" => "佈滿",
+"布线" => "佈線",
+"布置" => "佈置",
+"布署" => "佈署",
+"布道" => "佈道",
+"布达" => "佈達",
+"布防" => "佈防",
+"布阵" => "佈陣",
+"布雷" => "佈雷",
+"体育锻鍊" => "体育鍛鍊",
+"何干" => "何干",
+"作准" => "作准",
+"佣人" => "佣人",
+"佣工" => "佣工",
+"佣金" => "佣金",
+"并入" => "併入",
+"并列" => "併列",
+"并到" => "併到",
+"并合" => "併合",
+"并吞" => "併吞",
+"并在" => "併在",
+"并成" => "併成",
+"并排" => "併排",
+"并拢" => "併攏",
+"并案" => "併案",
+"并为" => "併為",
+"并发" => "併發",
+"并科" => "併科",
+"并购" => "併購",
+"并进" => "併進",
+"来复" => "來複",
+"供制" => "供製",
+"侵并" => "侵併",
+"便辟" => "便辟",
+"系数" => "係數",
+"系为" => "係為",
+"保险柜" => "保險柜",
+"信号台" => "信號臺",
+"修复" => "修複",
+"修胡刀" => "修鬍刀",
+"俯冲" => "俯衝",
+"个里" => "個裡",
+"倒绷孩儿" => "倒繃孩兒",
+"借着" => "借著",
+"偃仆" => "偃仆",
+"假发" => "假髮",
+"停制" => "停製",
+"偷鸡不着" => "偷雞不著",
+"家伙" => "傢伙",
+"家俱" => "傢俱",
+"家具" => "傢具",
+"传布" => "傳佈",
+"债台高筑" => "債臺高築",
+"傻里傻气" => "傻裡傻氣",
+"倾复" => "傾複",
+"倾复" => "傾覆",
+"僱佣" => "僱佣",
+"仪表" => "儀錶",
+"亿只" => "億隻",
+"尽尽" => "儘儘",
+"尽先" => "儘先",
+"尽其所有" => "儘其所有",
+"尽力" => "儘力",
+"尽可能" => "儘可能",
+"尽快" => "儘快",
+"尽早" => "儘早",
+"尽是" => "儘是",
+"尽管" => "儘管",
+"尽速" => "儘速",
+"尽量" => "儘量",
+"允准" => "允准",
+"兄台" => "兄臺",
+"充饥" => "充饑",
+"光采" => "光采",
+"克里" => "克裡",
+"克复" => "克複",
+"入伙" => "入伙",
+"内制" => "內製",
+"两只" => "兩隻",
+"八字胡" => "八字鬍",
+"八只" => "八隻",
+"公布" => "公佈",
+"公干" => "公幹",
+"公斗" => "公斗",
+"公历" => "公曆",
+"公里" => "公裡",
+"六谷" => "六穀",
+"六只" => "六隻",
+"六出" => "六齣",
+"兼并" => "兼併",
+"册卷" => "冊卷",
+"冤雠" => "冤讎",
+"准予" => "准予",
+"准假" => "准假",
+"准定" => "准定",
+"准将" => "准將",
+"准尉" => "准尉",
+"准此" => "准此",
+"准考证" => "准考證",
+"准许" => "准許",
+"几几" => "几几",
+"几杖" => "几杖",
+"几案" => "几案",
+"几筵" => "几筵",
+"几丝" => "几絲",
+"凹洞里" => "凹洞裡",
+"出征" => "出征",
+"函复" => "函覆",
+"刀削面" => "刀削麵",
+"刁斗" => "刁斗",
+"分布" => "分佈",
+"切面" => "切麵",
+"刊布" => "刊佈",
+"划上" => "划上",
+"划下" => "划下",
+"划不来" => "划不來",
+"划了" => "划了",
+"划具" => "划具",
+"划出" => "划出",
+"划到" => "划到",
+"划动" => "划動",
+"划去" => "划去",
+"划子" => "划子",
+"划得来" => "划得來",
+"划拳" => "划拳",
+"划桨" => "划槳",
+"划水" => "划水",
+"划算" => "划算",
+"划船" => "划船",
+"划艇" => "划艇",
+"划着" => "划著",
+"划着走" => "划著走",
+"划行" => "划行",
+"划走" => "划走",
+"划起" => "划起",
+"划进" => "划進",
+"划过" => "划過",
+"初征" => "初征",
+"别致" => "別緻",
+"别着" => "別著",
+"别只" => "別隻",
+"利比里亚" => "利比裡亞",
+"刮着" => "刮著",
+"刮胡刀" => "刮鬍刀",
+"剃发" => "剃髮",
+"剃须" => "剃鬚",
+"削发" => "削髮",
+"克制" => "剋制",
+"克扣" => "剋扣",
+"克日" => "剋日",
+"克星" => "剋星",
+"克服" => "剋服",
+"克期" => "剋期",
+"克死" => "剋死",
+"克薄" => "剋薄",
+"前仆后仰" => "前仆後仰",
+"前仆后继" => "前仆後繼",
+"前台" => "前臺",
+"前车之复" => "前車之覆",
+"刚才" => "剛纔",
+"剥制" => "剝製",
+"剪发" => "剪髮",
+"割舍" => "割捨",
+"创获" => "創穫",
+"创制" => "創製",
+"加里宁" => "加裡寧",
+"劳力士表" => "勞力士錶",
+"包准" => "包准",
+"包谷" => "包穀",
+"匏系" => "匏繫",
+"北岳" => "北嶽",
+"北斗" => "北斗",
+"北回" => "北迴",
+"匡复" => "匡複",
+"匪干" => "匪幹",
+"十卷" => "十卷",
+"十干" => "十干",
+"十台" => "十臺",
+"十只" => "十隻",
+"十出" => "十齣",
+"千百只" => "千百隻",
+"千丝万缕" => "千絲萬縷",
+"千回百折" => "千迴百折",
+"千回百转" => "千迴百轉",
+"千钧一发" => "千鈞一髮",
+"千只" => "千隻",
+"升斗小民" => "升斗小民",
+"半只" => "半隻",
+"南岳" => "南嶽",
+"南征" => "南征",
+"南斗" => "南斗",
+"南台" => "南臺",
+"南回" => "南迴",
+"卡里" => "卡裡",
+"印制" => "印製",
+"卷入" => "卷入",
+"卷取" => "卷取",
+"卷土重来" => "卷土重來",
+"卷子" => "卷子",
+"卷宗" => "卷宗",
+"卷尺" => "卷尺",
+"卷层云" => "卷層雲",
+"卷帙" => "卷帙",
+"卷扬机" => "卷揚機",
+"卷曲" => "卷曲",
+"卷染" => "卷染",
+"卷烟" => "卷煙",
+"卷筒" => "卷筒",
+"卷纬" => "卷緯",
+"卷绕" => "卷繞",
+"卷舌" => "卷舌",
+"卷装" => "卷裝",
+"卷轴" => "卷軸",
+"卷云" => "卷雲",
+"卷领" => "卷領",
+"卷发" => "卷髮",
+"卷须" => "卷鬚",
+"厚朴" => "厚朴",
+"参与" => "參与",
+"参与者" => "參与者",
+"参合" => "參合",
+"参考价值" => "參考價值",
+"参与" => "參與",
+"参与人员" => "參與人員",
+"参与制" => "參與制",
+"参与感" => "參與感",
+"参与者" => "參與者",
+"参观团" => "參觀團",
+"参观团体" => "參觀團體",
+"参阅" => "參閱",
+"反冲" => "反衝",
+"反复" => "反複",
+"反复" => "反覆",
+"取舍" => "取捨",
+"口里" => "口裡",
+"古柯咸" => "古柯鹹",
+"只准" => "只准",
+"只冲" => "只衝",
+"叮当" => "叮噹",
+"可怜虫" => "可憐虫",
+"可紧可松" => "可緊可鬆",
+"台制" => "台製",
+"司令台" => "司令臺",
+"吃着不尽" => "吃著不盡",
+"吃里扒外" => "吃裡扒外",
+"吃里爬外" => "吃裡爬外",
+"各吊" => "各吊",
+"合伙" => "合伙",
+"合并" => "合併",
+"合着" => "合著",
+"合着者" => "合著者",
+"吊上" => "吊上",
+"吊下" => "吊下",
+"吊了" => "吊了",
+"吊个" => "吊個",
+"吊儿郎当" => "吊兒郎當",
+"吊到" => "吊到",
+"吊去" => "吊去",
+"吊取" => "吊取",
+"吊吊" => "吊吊",
+"吊嗓" => "吊嗓",
+"吊好" => "吊好",
+"吊子" => "吊子",
+"吊带" => "吊帶",
+"吊带裤" => "吊帶褲",
+"吊床" => "吊床",
+"吊得" => "吊得",
+"吊挂" => "吊掛",
+"吊挂着" => "吊掛著",
+"吊杆" => "吊杆",
+"吊架" => "吊架",
+"吊桶" => "吊桶",
+"吊杆" => "吊桿",
+"吊桥" => "吊橋",
+"吊死" => "吊死",
+"吊灯" => "吊燈",
+"吊环" => "吊環",
+"吊盘" => "吊盤",
+"吊索" => "吊索",
+"吊着" => "吊著",
+"吊装" => "吊裝",
+"吊裤" => "吊褲",
+"吊裤带" => "吊褲帶",
+"吊袜" => "吊襪",
+"吊走" => "吊走",
+"吊起" => "吊起",
+"吊车" => "吊車",
+"吊钩" => "吊鉤",
+"吊销" => "吊銷",
+"吊钟" => "吊鐘",
+"同伙" => "同伙",
+"名表" => "名錶",
+"後冠" => "后冠",
+"後北街" => "后北街",
+"後土" => "后土",
+"後妃" => "后妃",
+"後安路" => "后安路",
+"後平路" => "后平路",
+"後座" => "后座",
+"後稷" => "后稷",
+"後羿" => "后羿",
+"後街" => "后街",
+"後里" => "后里",
+"向着" => "向著",
+"吞并" => "吞併",
+"吹发" => "吹髮",
+"吕後" => "呂后",
+"呆里呆气" => "呆裡呆氣",
+"呈准" => "呈准",
+"周而复始" => "周而複始",
+"呼吁" => "呼籲",
+"和面" => "和麵",
+"哪里" => "哪裡",
+"哭脏" => "哭髒",
+"问卷" => "問卷",
+"喝采" => "喝采",
+"乔岳" => "喬嶽",
+"单干" => "單干",
+"单只" => "單隻",
+"嘴里" => "嘴裏",
+"嘴里" => "嘴裡",
+"恶心" => "噁心",
+"当啷" => "噹啷",
+"当当" => "噹噹",
+"噜苏" => "嚕囌",
+"向导" => "嚮導",
+"向往" => "嚮往",
+"向应" => "嚮應",
+"向日" => "嚮日",
+"向迩" => "嚮邇",
+"严丝合缝" => "嚴絲合縫",
+"严复" => "嚴複",
+"囉苏" => "囉囌",
+"四舍五入" => "四捨五入",
+"四只" => "四隻",
+"四出" => "四齣",
+"回历新年" => "回曆新年",
+"回丝" => "回絲",
+"回着" => "回著",
+"回复" => "回覆",
+"回采" => "回采",
+"圈子里" => "圈子裡",
+"圈里" => "圈裡",
+"国历" => "國曆",
+"国雠" => "國讎",
+"园里" => "園裡",
+"圆台" => "圓臺",
+"图里" => "圖裡",
+"土里" => "土裡",
+"土制" => "土製",
+"地志" => "地誌",
+"坍台" => "坍臺",
+"坑里" => "坑裡",
+"垂发" => "垂髮",
+"垮台" => "垮臺",
+"埃及豔後" => "埃及豔后",
+"埃荣冲" => "埃榮衝",
+"埋布" => "埋佈",
+"城里" => "城裡",
+"基干" => "基幹",
+"报复" => "報複",
+"塌台" => "塌臺",
+"塔台" => "塔臺",
+"涂着" => "塗著",
+"墓志" => "墓誌",
+"墨斗" => "墨斗",
+"墨索里尼" => "墨索裡尼",
+"垦复" => "墾複",
+"压卷" => "壓卷",
+"垄断价格" => "壟斷價格",
+"垄断资产" => "壟斷資產",
+"垄断集团" => "壟斷集團",
+"壶里" => "壺裡",
+"寿面" => "壽麵",
+"夏天里" => "夏天裡",
+"夏历" => "夏曆",
+"外制" => "外製",
+"多冲" => "多衝",
+"多采多姿" => "多采多姿",
+"多么" => "多麼",
+"夜光表" => "夜光錶",
+"夜里" => "夜裡",
+"梦里" => "夢裡",
+"大伙" => "大伙",
+"大卷" => "大卷",
+"大干" => "大干",
+"大干" => "大幹",
+"大辟" => "大辟",
+"大只" => "大隻",
+"天後" => "天后",
+"天干" => "天干",
+"天文台" => "天文臺",
+"天翻地复" => "天翻地覆",
+"太後" => "太后",
+"奏折" => "奏摺",
+"女丑" => "女丑",
+"女佣" => "女佣",
+"好家夥" => "好傢夥",
+"好戏连台" => "好戲連臺",
+"好困" => "好睏",
+"如饥似渴" => "如饑似渴",
+"妆台" => "妝臺",
+"姜太公" => "姜太公",
+"姜子牙" => "姜子牙",
+"姜丝" => "姜絲",
+"字汇" => "字彙",
+"字里行间" => "字裡行間",
+"存折" => "存摺",
+"孟姜女" => "孟姜女",
+"宇宙志" => "宇宙誌",
+"宋皇台道" => "宋皇臺道",
+"定准" => "定准",
+"定制" => "定製",
+"宣布" => "宣佈",
+"宫里" => "宮裡",
+"家伙" => "家伙",
+"家里" => "家裏",
+"家里" => "家裡",
+"密布" => "密佈",
+"密致" => "密緻",
+"寇雠" => "寇讎",
+"富台街" => "富臺街",
+"寓禁于征" => "寓禁於征",
+"实干" => "實幹",
+"写字台" => "寫字檯",
+"写字台" => "寫字臺",
+"宽松" => "寬鬆",
+"宝卷" => "寶卷",
+"宝里宝气" => "寶裡寶氣",
+"封後" => "封后",
+"封面里" => "封面裡",
+"射干" => "射干",
+"对表" => "對錶",
+"小丑" => "小丑",
+"小伙" => "小伙",
+"小只" => "小隻",
+"少吊" => "少吊",
+"就里" => "就裡",
+"尺布斗粟" => "尺布斗粟",
+"尼克松" => "尼克鬆",
+"尼采" => "尼采",
+"尿斗" => "尿斗",
+"局里" => "局裡",
+"居里" => "居裡",
+"屋子里" => "屋子裡",
+"屋里" => "屋裡",
+"展布" => "展佈",
+"展卷" => "展卷",
+"屡仆屡起" => "屢仆屢起",
+"屯里" => "屯裡",
+"山岳" => "山嶽",
+"山斗" => "山斗",
+"山里" => "山裡",
+"山重水复" => "山重水複",
+"岱岳" => "岱嶽",
+"峰回" => "峰迴",
+"岳岳" => "嶽嶽",
+"巅复" => "巔覆",
+"巡回" => "巡迴",
+"巧干" => "巧幹",
+"巴尔干" => "巴爾幹",
+"巴里" => "巴裡",
+"巷里" => "巷裡",
+"市里" => "市裡",
+"布谷" => "布穀",
+"希腊" => "希腊",
+"帘子" => "帘子",
+"帘布" => "帘布",
+"席卷" => "席卷",
+"带团参加" => "帶團參加",
+"带发修行" => "帶髮修行",
+"干世" => "干世",
+"干休" => "干休",
+"干系" => "干係",
+"干冒" => "干冒",
+"干卿何事" => "干卿何事",
+"干卿底事" => "干卿底事",
+"干城" => "干城",
+"干将" => "干將",
+"干德道" => "干德道",
+"干戈" => "干戈",
+"干挠" => "干撓",
+"干扰" => "干擾",
+"干支" => "干支",
+"干政" => "干政",
+"干时" => "干時",
+"干没" => "干沒",
+"干涉" => "干涉",
+"干犯" => "干犯",
+"干禄" => "干祿",
+"干与" => "干與",
+"干着急" => "干著急",
+"干诺道中" => "干諾道中",
+"干诺道西" => "干諾道西",
+"干谒" => "干謁",
+"干证" => "干證",
+"干誉" => "干譽",
+"干贝" => "干貝",
+"干连" => "干連",
+"干云蔽日" => "干雲蔽日",
+"干预" => "干預",
+"平台" => "平臺",
+"年历" => "年曆",
+"年里" => "年裡",
+"干上" => "幹上",
+"干下去" => "幹下去",
+"干不了" => "幹不了",
+"干不成" => "幹不成",
+"干了" => "幹了",
+"干事" => "幹事",
+"干些" => "幹些",
+"干个" => "幹個",
+"干劲" => "幹勁",
+"干员" => "幹員",
+"干啥" => "幹啥",
+"干吗" => "幹嗎",
+"干嘛" => "幹嘛",
+"干坏事" => "幹壞事",
+"干完" => "幹完",
+"干将" => "幹將",
+"干得" => "幹得",
+"干性油" => "幹性油",
+"干才" => "幹才",
+"干掉" => "幹掉",
+"干校" => "幹校",
+"干活" => "幹活",
+"干流" => "幹流",
+"干球温度" => "幹球溫度",
+"干略" => "幹略",
+"干线" => "幹線",
+"干练" => "幹練",
+"干警" => "幹警",
+"干起来" => "幹起來",
+"干路" => "幹路",
+"干办" => "幹辦",
+"干这一行" => "幹這一行",
+"干这种事" => "幹這種事",
+"干道" => "幹道",
+"干部" => "幹部",
+"干么" => "幹麼",
+"几丝" => "幾絲",
+"几只" => "幾隻",
+"几出" => "幾齣",
+"底里" => "底裡",
+"店里" => "店裡",
+"康采恩" => "康采恩",
+"庙里" => "廟裡",
+"建台" => "建臺",
+"弄脏" => "弄髒",
+"弔卷" => "弔卷",
+"弘历" => "弘曆",
+"强干弱枝" => "強幹弱枝",
+"别扭" => "彆扭",
+"别拗" => "彆拗",
+"别气" => "彆氣",
+"别脚" => "彆腳",
+"别着" => "彆著",
+"弹子台" => "彈子檯",
+"弹珠台" => "彈珠檯",
+"弹药" => "彈葯",
+"汇刊" => "彙刊",
+"汇报" => "彙報",
+"汇整" => "彙整",
+"汇算" => "彙算",
+"汇编" => "彙編",
+"汇总" => "彙總",
+"汇纂" => "彙纂",
+"汇辑" => "彙輯",
+"汇集" => "彙集",
+"形单影只" => "形單影隻",
+"影後" => "影后",
+"往里" => "往裡",
+"往复" => "往複",
+"征伐" => "征伐",
+"征兵" => "征兵",
+"征利" => "征利",
+"征尘" => "征塵",
+"征夫" => "征夫",
+"征属" => "征屬",
+"征帆" => "征帆",
+"征戌" => "征戌",
+"征战" => "征戰",
+"征收" => "征收",
+"征服" => "征服",
+"征求" => "征求",
+"征发" => "征發",
+"征衣" => "征衣",
+"征讨" => "征討",
+"征途" => "征途",
+"后台" => "後臺",
+"从里到外" => "從裡到外",
+"从里向外" => "從裡向外",
+"复雠" => "復讎",
+"复辟" => "復辟",
+"德干高原" => "德干高原",
+"心愿" => "心愿",
+"心里" => "心裏",
+"心里" => "心裡",
+"忙里" => "忙裡",
+"快干" => "快幹",
+"快冲" => "快衝",
+"怎么" => "怎麼",
+"怎么着" => "怎麼著",
+"急冲而下" => "急衝而下",
+"怪里怪气" => "怪裡怪氣",
+"恩准" => "恩准",
+"情有所钟" => "情有所鍾",
+"情有独钟" => "情有獨鍾",
+"意面" => "意麵",
+"慌里慌张" => "慌裡慌張",
+"慰借" => "慰藉",
+"忧郁" => "憂郁",
+"凭吊" => "憑吊",
+"凭借" => "憑藉",
+"凭借着" => "憑藉著",
+"蒙懂" => "懞懂",
+"怀里" => "懷裡",
+"怀表" => "懷錶",
+"悬吊" => "懸吊",
+"悬心吊胆" => "懸心吊膽",
+"戏台" => "戲臺",
+"戴表" => "戴錶",
+"戽斗" => "戽斗",
+"房里" => "房裡",
+"手不释卷" => "手不釋卷",
+"手卷" => "手卷",
+"手折" => "手摺",
+"手里" => "手裏",
+"手里" => "手裡",
+"手表" => "手錶",
+"手松" => "手鬆",
+"才干" => "才幹",
+"才高八斗" => "才高八斗",
+"打谷" => "打穀",
+"扞御" => "扞禦",
+"批准" => "批准",
+"批复" => "批複",
+"批复" => "批覆",
+"承制" => "承製",
+"抗御" => "抗禦",
+"折冲" => "折衝",
+"披复" => "披覆",
+"披发" => "披髮",
+"抱朴" => "抱朴",
+"抵御" => "抵禦",
+"拆伙" => "拆伙",
+"拆台" => "拆臺",
+"拈须" => "拈鬚",
+"拉纤" => "拉縴",
+"拉面" => "拉麵",
+"拖吊" => "拖吊",
+"拗别" => "拗彆",
+"拮据" => "拮据",
+"捍御" => "捍禦",
+"舍不得" => "捨不得",
+"舍出" => "捨出",
+"舍去" => "捨去",
+"舍命" => "捨命",
+"舍己从人" => "捨己從人",
+"舍己救人" => "捨己救人",
+"舍己为人" => "捨己為人",
+"舍己为公" => "捨己為公",
+"舍己为国" => "捨己為國",
+"舍得" => "捨得",
+"舍我其谁" => "捨我其誰",
+"舍本逐末" => "捨本逐末",
+"舍弃" => "捨棄",
+"舍死忘生" => "捨死忘生",
+"舍生" => "捨生",
+"舍短取长" => "捨短取長",
+"舍身" => "捨身",
+"舍车保帅" => "捨車保帥",
+"舍近求远" => "捨近求遠",
+"捲发" => "捲髮",
+"捵面" => "捵麵",
+"掌柜" => "掌柜",
+"排骨面" => "排骨麵",
+"挂帘" => "掛帘",
+"挂面" => "掛麵",
+"接着说" => "接著說",
+"掩卷" => "掩卷",
+"提心吊胆" => "提心吊膽",
+"插图卷" => "插圖卷",
+"换吊" => "換吊",
+"换只" => "換隻",
+"换发" => "換髮",
+"握发" => "握髮",
+"搭伙" => "搭伙",
+"折合" => "摺合",
+"折奏" => "摺奏",
+"折子" => "摺子",
+"折尺" => "摺尺",
+"折扇" => "摺扇",
+"折梯" => "摺梯",
+"折椅" => "摺椅",
+"折叠" => "摺疊",
+"折痕" => "摺痕",
+"折篷" => "摺篷",
+"折纸" => "摺紙",
+"折裙" => "摺裙",
+"撒布" => "撒佈",
+"撚须" => "撚鬚",
+"撞球台" => "撞球檯",
+"擂台" => "擂臺",
+"担仔面" => "擔仔麵",
+"担担面" => "擔擔麵",
+"担着" => "擔著",
+"担负着" => "擔負著",
+"据云" => "據云",
+"擢发难数" => "擢髮難數",
+"拟准" => "擬准",
+"摆布" => "擺佈",
+"摄制" => "攝製",
+"支干" => "支幹",
+"收获" => "收穫",
+"改制" => "改製",
+"攻克" => "攻剋",
+"放松" => "放鬆",
+"故布疑阵" => "故佈疑陣",
+"叙说着" => "敘說著",
+"散伙" => "散伙",
+"散布" => "散佈",
+"散发" => "散髮",
+"整只" => "整隻",
+"整出" => "整齣",
+"敌忾同雠" => "敵愾同讎",
+"文借" => "文藉",
+"文采" => "文采",
+"斗亚兰路" => "斗亞蘭路",
+"斗六" => "斗六",
+"斗南" => "斗南",
+"斗大" => "斗大",
+"斗子" => "斗子",
+"斗室" => "斗室",
+"斗宿" => "斗宿",
+"斗方" => "斗方",
+"斗栱" => "斗栱",
+"斗笠" => "斗笠",
+"斗筲" => "斗筲",
+"斗箕" => "斗箕",
+"斗篷" => "斗篷",
+"斗胆" => "斗膽",
+"斗蓬" => "斗蓬",
+"斗转参横" => "斗轉參橫",
+"斗量" => "斗量",
+"斗门" => "斗門",
+"料斗" => "料斗",
+"斤斗" => "斤斗",
+"斯里兰卡" => "斯裡蘭卡",
+"新历" => "新曆",
+"断头台" => "斷頭臺",
+"断发文身" => "斷髮文身",
+"方才" => "方纔",
+"方志" => "方誌",
+"施舍" => "施捨",
+"旋绕着" => "旋繞著",
+"旋回" => "旋迴",
+"族里" => "族裡",
+"日历" => "日曆",
+"日志" => "日誌",
+"日进斗金" => "日進斗金",
+"明了" => "明瞭",
+"明窗净几" => "明窗淨几",
+"明里" => "明裡",
+"星斗" => "星斗",
+"星历" => "星曆",
+"星移斗换" => "星移斗換",
+"星移斗转" => "星移斗轉",
+"星罗棋布" => "星羅棋佈",
+"星辰表" => "星辰錶",
+"春假里" => "春假裡",
+"春天里" => "春天裡",
+"景致" => "景緻",
+"暗地里" => "暗地裡",
+"暗沟里" => "暗溝裡",
+"暗里" => "暗裡",
+"暴敛横征" => "暴斂橫征",
+"历数" => "曆數",
+"历书" => "曆書",
+"历法" => "曆法",
+"历象" => "曆象",
+"书卷" => "書卷",
+"会干" => "會幹",
+"会里" => "會裡",
+"月历" => "月曆",
+"月台" => "月臺",
+"有只" => "有隻",
+"木制" => "木製",
+"本台" => "本臺",
+"朴子" => "朴子",
+"朴实" => "朴實",
+"朴忠" => "朴忠",
+"朴直" => "朴直",
+"朴硝" => "朴硝",
+"朴素" => "朴素",
+"朴茂" => "朴茂",
+"朴资茅斯" => "朴資茅斯",
+"朴钝" => "朴鈍",
+"材干" => "材幹",
+"村里" => "村裡",
+"杜老志道" => "杜老誌道",
+"束发" => "束髮",
+"杯面" => "杯麵",
+"东岳" => "東嶽",
+"东征" => "東征",
+"松赞干布" => "松贊干布",
+"板着脸" => "板著臉",
+"枕借" => "枕藉",
+"林宏岳" => "林宏嶽",
+"枝干" => "枝幹",
+"枯干" => "枯幹",
+"某只" => "某隻",
+"染发" => "染髮",
+"柜上" => "柜上",
+"柜台" => "柜台",
+"柜子" => "柜子",
+"柜柳" => "柜柳",
+"查卷" => "查卷",
+"查号台" => "查號臺",
+"校雠学" => "校讎學",
+"核准" => "核准",
+"核复" => "核覆",
+"格里" => "格裡",
+"案准" => "案准",
+"案卷" => "案卷",
+"条干" => "條幹",
+"梯冲" => "梯衝",
+"械系" => "械繫",
+"棉卷" => "棉卷",
+"棉制" => "棉製",
+"植发" => "植髮",
+"楼台" => "樓臺",
+"标志着" => "標志著",
+"标致" => "標緻",
+"标志" => "標誌",
+"模制" => "模製",
+"树干" => "樹幹",
+"横征暴敛" => "橫征暴斂",
+"横冲" => "橫衝",
+"档卷" => "檔卷",
+"检复" => "檢覆",
+"台子" => "檯子",
+"台布" => "檯布",
+"台灯" => "檯燈",
+"台球" => "檯球",
+"台面" => "檯面",
+"柜台" => "櫃檯",
+"柜台" => "櫃臺",
+"栏干" => "欄干",
+"欺蒙" => "欺矇",
+"歌後" => "歌后",
+"歌台舞榭" => "歌臺舞榭",
+"欧几里得" => "歐幾裡得",
+"正当着" => "正當著",
+"此仆彼起" => "此仆彼起",
+"武後" => "武后",
+"武松" => "武鬆",
+"归并" => "歸併",
+"死里求生" => "死裡求生",
+"死里逃生" => "死裡逃生",
+"残卷" => "殘卷",
+"杀虫药" => "殺虫藥",
+"壳里" => "殼裡",
+"母後" => "母后",
+"每只" => "每隻",
+"比干" => "比干",
+"毛卷" => "毛卷",
+"毛坏" => "毛坏",
+"毛发" => "毛髮",
+"毫发" => "毫髮",
+"气冲斗牛" => "氣沖斗牛",
+"气冲牛斗" => "氣沖牛斗",
+"气象台" => "氣象臺",
+"水斗" => "水斗",
+"水里" => "水裡",
+"水表" => "水錶",
+"永历" => "永曆",
+"永志不忘" => "永誌不忘",
+"污蔑" => "汙衊",
+"江干" => "江干",
+"池里" => "池裡",
+"污蔑" => "污衊",
+"沈着" => "沈著",
+"没事干" => "沒事幹",
+"没精打采" => "沒精打采",
+"冲着" => "沖著",
+"沙里淘金" => "沙裡淘金",
+"河岳" => "河嶽",
+"河里" => "河裡",
+"油面" => "油麵",
+"泡制" => "泡製",
+"泡面" => "泡麵",
+"泰斗" => "泰斗",
+"洗发" => "洗髮",
+"派团参加" => "派團參加",
+"浪琴表" => "浪琴錶",
+"浮吊" => "浮吊",
+"海里" => "海裡",
+"涂着" => "涂著",
+"液晶表" => "液晶錶",
+"凉面" => "涼麵",
+"淡朱" => "淡硃",
+"渊淳岳峙" => "淵淳嶽峙",
+"渠冲" => "渠衝",
+"测验卷" => "測驗卷",
+"港制" => "港製",
+"凑合着" => "湊合著",
+"湖里" => "湖裡",
+"汤团" => "湯糰",
+"汤面" => "湯麵",
+"温郁" => "溫郁",
+"卤制" => "滷製",
+"卤面" => "滷麵",
+"满布" => "滿佈",
+"漏斗" => "漏斗",
+"演奏台" => "演奏臺",
+"潜意识里" => "潛意識裡",
+"潭里" => "潭裡",
+"浓郁" => "濃郁",
+"浓发" => "濃髮",
+"湿地松" => "濕地鬆",
+"蒙蒙" => "濛濛",
+"蒙雾" => "濛霧",
+"蒙鸿" => "濛鴻",
+"瀛台" => "瀛臺",
+"弥漫" => "瀰漫",
+"弥漫着" => "瀰漫著",
+"漓江" => "灕江",
+"火并" => "火併",
+"灰蒙" => "灰濛",
+"炒面" => "炒麵",
+"炮制" => "炮製",
+"炸药" => "炸葯",
+"炸酱面" => "炸醬麵",
+"为着" => "為著",
+"乌干达" => "烏干達",
+"乌苏里江" => "烏蘇裡江",
+"乌发" => "烏髮",
+"乌龙面" => "烏龍麵",
+"烘制" => "烘製",
+"烽火台" => "烽火臺",
+"无干" => "無干",
+"无精打采" => "無精打采",
+"炼制" => "煉製",
+"烟卷儿" => "煙卷兒",
+"烟斗" => "煙斗",
+"烟斗丝" => "煙斗絲",
+"烟台" => "煙臺",
+"照准" => "照准",
+"熨斗" => "熨斗",
+"灯台" => "燈臺",
+"燎发" => "燎髮",
+"烫发" => "燙髮",
+"烫面" => "燙麵",
+"烛台" => "燭臺",
+"炉台" => "爐臺",
+"墙里" => "牆裡",
+"片言只语" => "片言隻語",
+"牛肉面" => "牛肉麵",
+"牛只" => "牛隻",
+"特准" => "特准",
+"特征" => "特征",
+"特里" => "特裡",
+"特制" => "特製",
+"牵系" => "牽繫",
+"狼借" => "狼藉",
+"猛冲" => "猛衝",
+"奖杯" => "獎盃",
+"获准" => "獲准",
+"率团参加" => "率團參加",
+"王侯後" => "王侯后",
+"王後" => "王后",
+"班里" => "班裡",
+"理发" => "理髮",
+"瑶台" => "瑤臺",
+"甚么" => "甚麼",
+"甜面酱" => "甜麵醬",
+"生力面" => "生力麵",
+"生锈" => "生鏽",
+"生发" => "生髮",
+"田里" => "田裡",
+"由馀" => "由余",
+"由表及里" => "由表及裡",
+"男佣" => "男佣",
+"男用表" => "男用錶",
+"留发" => "留髮",
+"畚斗" => "畚斗",
+"当着" => "當著",
+"疏松" => "疏鬆",
+"疑系" => "疑係",
+"疲困" => "疲睏",
+"病症" => "病癥",
+"症候" => "癥候",
+"症状" => "癥狀",
+"症结" => "癥結",
+"登台" => "登臺",
+"发布" => "發佈",
+"发蒙" => "發矇",
+"发着" => "發著",
+"发面" => "發麵",
+"发霉" => "發黴",
+"白卷" => "白卷",
+"白干儿" => "白干兒",
+"白里透红" => "白裡透紅",
+"白发" => "白髮",
+"白面" => "白麵",
+"百谷" => "百穀",
+"百里" => "百裡",
+"百只" => "百隻",
+"皇後" => "皇后",
+"皇历" => "皇曆",
+"皓发" => "皓髮",
+"皮里阳秋" => "皮裏陽秋",
+"皮里春秋" => "皮裡春秋",
+"皮制" => "皮製",
+"皱折" => "皺摺",
+"盒里" => "盒裡",
+"监制" => "監製",
+"盘里" => "盤裡",
+"盘回" => "盤迴",
+"直接参与" => "直接參与",
+"直冲" => "直衝",
+"相克" => "相剋",
+"相干" => "相干",
+"相冲" => "相衝",
+"看台" => "看臺",
+"眼帘" => "眼帘",
+"眼眶里" => "眼眶裡",
+"眼里" => "眼裡",
+"困乏" => "睏乏",
+"困倦" => "睏倦",
+"睡着了" => "睡著了",
+"了如" => "瞭如",
+"了望" => "瞭望",
+"了然" => "瞭然",
+"了若指掌" => "瞭若指掌",
+"了解" => "瞭解",
+"瞳蒙" => "瞳矇",
+"蒙住" => "矇住",
+"蒙昧无知" => "矇昧無知",
+"蒙混" => "矇混",
+"蒙蒙" => "矇矇",
+"蒙眬" => "矇矓",
+"蒙蔽" => "矇蔽",
+"蒙骗" => "矇騙",
+"短发" => "短髮",
+"矮几" => "矮几",
+"石英表" => "石英錶",
+"石莼" => "石蓴",
+"研制" => "研製",
+"砰当" => "砰噹",
+"砲台" => "砲臺",
+"朱唇皓齿" => "硃唇皓齒",
+"朱批" => "硃批",
+"朱砂" => "硃砂",
+"朱笔" => "硃筆",
+"朱红色" => "硃紅色",
+"朱色" => "硃色",
+"朱谕" => "硃諭",
+"硬干" => "硬幹",
+"砚台" => "硯臺",
+"碑志" => "碑誌",
+"磁制" => "磁製",
+"磨制" => "磨製",
+"示复" => "示覆",
+"社里" => "社裡",
+"神采" => "神采",
+"御侮" => "禦侮",
+"御寇" => "禦寇",
+"御寒" => "禦寒",
+"御敌" => "禦敵",
+"礼义干橹" => "禮義干櫓",
+"秃发" => "禿髮",
+"秀斗" => "秀斗",
+"秀发" => "秀髮",
+"私下里" => "私下裡",
+"秋天里" => "秋天裡",
+"秋裤" => "秋褲",
+"秒表" => "秒錶",
+"稀松" => "稀鬆",
+"禀复" => "稟覆",
+"稻谷" => "稻穀",
+"稽征" => "稽征",
+"谷人" => "穀人",
+"谷保家商" => "穀保家商",
+"谷仓" => "穀倉",
+"谷场" => "穀場",
+"谷子" => "穀子",
+"谷梁" => "穀梁",
+"谷壳" => "穀殼",
+"谷物" => "穀物",
+"谷皮" => "穀皮",
+"谷神" => "穀神",
+"谷谷" => "穀穀",
+"谷粒" => "穀粒",
+"谷舱" => "穀艙",
+"谷苗" => "穀苗",
+"谷草" => "穀草",
+"谷贱伤农" => "穀賤傷農",
+"谷道" => "穀道",
+"谷雨" => "穀雨",
+"谷类" => "穀類",
+"谷风" => "穀風",
+"积极参与" => "積极參与",
+"积极参加" => "積极參加",
+"积谷防饥" => "積穀防饑",
+"空蒙" => "空濛",
+"窗帘" => "窗帘",
+"窗明几净" => "窗明几淨",
+"窗台" => "窗檯",
+"窗台" => "窗臺",
+"窝里" => "窩裡",
+"窝阔台" => "窩闊臺",
+"穷发" => "窮髮",
+"站台" => "站臺",
+"笆斗" => "笆斗",
+"笑里藏刀" => "笑裡藏刀",
+"第一卷" => "第一卷",
+"筋斗" => "筋斗",
+"答卷" => "答卷",
+"答复" => "答複",
+"答复" => "答覆",
+"筵几" => "筵几",
+"箕斗" => "箕斗",
+"算历" => "算曆",
+"签着" => "簽著",
+"吁求" => "籲求",
+"吁请" => "籲請",
+"粗制" => "粗製",
+"粗卤" => "粗鹵",
+"精干" => "精幹",
+"精明强干" => "精明強幹",
+"精致" => "精緻",
+"精制" => "精製",
+"精辟" => "精辟",
+"精采" => "精采",
+"糊里糊涂" => "糊裡糊塗",
+"团子" => "糰子",
+"系着" => "系著",
+"系里" => "系裡",
+"纪历" => "紀曆",
+"红绳系足" => "紅繩繫足",
+"红发" => "紅髮",
+"纡回" => "紆迴",
+"纳采" => "納采",
+"素食面" => "素食麵",
+"素发" => "素髮",
+"素面" => "素麵",
+"紫微斗数" => "紫微斗數",
+"细致" => "細緻",
+"组里" => "組裡",
+"结发" => "結髮",
+"绝对参照" => "絕對參照",
+"丝来线去" => "絲來線去",
+"丝布" => "絲布",
+"丝板" => "絲板",
+"丝瓜布" => "絲瓜布",
+"丝绒布" => "絲絨布",
+"丝线" => "絲線",
+"丝织厂" => "絲織廠",
+"丝虫" => "絲蟲",
+"綑吊" => "綑吊",
+"经卷" => "經卷",
+"维系" => "維繫",
+"绾发" => "綰髮",
+"网里" => "網裡",
+"紧绷" => "緊繃",
+"紧绷着" => "緊繃著",
+"编制" => "編製",
+"编发" => "編髮",
+"缓冲" => "緩衝",
+"致密" => "緻密",
+"萦回" => "縈迴",
+"县里" => "縣裡",
+"县志" => "縣誌",
+"缝里" => "縫裡",
+"缝制" => "縫製",
+"纤夫" => "縴夫",
+"纤手" => "縴手",
+"繁复" => "繁複",
+"绷住" => "繃住",
+"绷子" => "繃子",
+"绷带" => "繃帶",
+"绷紧" => "繃緊",
+"绷脸" => "繃臉",
+"绷着" => "繃著",
+"绷着脸" => "繃著臉",
+"绷着脸儿" => "繃著臉兒",
+"绷开" => "繃開",
+"绘制" => "繪製",
+"系上" => "繫上",
+"系世" => "繫世",
+"系到" => "繫到",
+"系囚" => "繫囚",
+"系心" => "繫心",
+"系念" => "繫念",
+"系怀" => "繫懷",
+"系恋" => "繫戀",
+"系数" => "繫數",
+"系于" => "繫於",
+"系系" => "繫系",
+"系结" => "繫結",
+"系紧" => "繫緊",
+"系绳" => "繫繩",
+"系累" => "繫纍",
+"系着" => "繫著",
+"系辞" => "繫辭",
+"系风捕影" => "繫風捕影",
+"缴卷" => "繳卷",
+"累囚" => "纍囚",
+"累累" => "纍纍",
+"坛子" => "罈子",
+"坛坛罐罐" => "罈罈罐罐",
+"骂着" => "罵著",
+"羁系" => "羈繫",
+"美制" => "美製",
+"美发" => "美髮",
+"翻来复去" => "翻來覆去",
+"翻天复地" => "翻天覆地",
+"翻复" => "翻覆",
+"翻云复雨" => "翻雲覆雨",
+"老么" => "老么",
+"老板" => "老闆",
+"考卷" => "考卷",
+"耕获" => "耕穫",
+"聊斋志异" => "聊齋誌異",
+"联系" => "聯係",
+"联系" => "聯繫",
+"肉丝面" => "肉絲麵",
+"肉羹面" => "肉羹麵",
+"肉松" => "肉鬆",
+"肚里" => "肚裏",
+"肚里" => "肚裡",
+"肢体" => "肢体",
+"胃里" => "胃裡",
+"背向着" => "背向著",
+"背地里" => "背地裡",
+"胡里胡涂" => "胡裡胡塗",
+"能干" => "能幹",
+"脉冲" => "脈衝",
+"脱发" => "脫髮",
+"腊味" => "腊味",
+"腊笔" => "腊筆",
+"腊肉" => "腊肉",
+"脑子里" => "腦子裡",
+"腰里" => "腰裡",
+"胶卷" => "膠卷",
+"膨松" => "膨鬆",
+"自制" => "自製",
+"自觉自愿" => "自覺自愿",
+"台上" => "臺上",
+"台下" => "臺下",
+"台中" => "臺中",
+"台儿庄" => "臺兒莊",
+"台北" => "臺北",
+"台南" => "臺南",
+"台地" => "臺地",
+"台塑" => "臺塑",
+"台大" => "臺大",
+"台币" => "臺幣",
+"台座" => "臺座",
+"台东" => "臺東",
+"台柱" => "臺柱",
+"台榭" => "臺榭",
+"台机路" => "臺機路",
+"台步" => "臺步",
+"台汽" => "臺汽",
+"台海" => "臺海",
+"台澎金马" => "臺澎金馬",
+"台湾" => "臺灣",
+"台灯" => "臺燈",
+"台球" => "臺球",
+"台省" => "臺省",
+"台端" => "臺端",
+"台糖" => "臺糖",
+"台肥" => "臺肥",
+"台航" => "臺航",
+"台西" => "臺西",
+"台视" => "臺視",
+"台词" => "臺詞",
+"台车" => "臺車",
+"台铁" => "臺鐵",
+"台阶" => "臺階",
+"台电" => "臺電",
+"台面" => "臺面",
+"舂谷" => "舂穀",
+"兴致" => "興緻",
+"兴高采烈" => "興高采烈",
+"旧历" => "舊曆",
+"舒卷" => "舒卷",
+"舞榭歌台" => "舞榭歌臺",
+"舞台" => "舞臺",
+"航海历" => "航海曆",
+"船只" => "船隻",
+"舰只" => "艦隻",
+"芬郁" => "芬郁",
+"花卷" => "花卷",
+"花盆里" => "花盆裡",
+"花采" => "花采",
+"苑里" => "苑裡",
+"若干" => "若干",
+"若干" => "若幹",
+"苦干" => "苦幹",
+"苦里" => "苦裏",
+"苦卤" => "苦鹵",
+"范仲淹" => "范仲淹",
+"范蠡" => "范蠡",
+"范阳" => "范陽",
+"茅台" => "茅臺",
+"茶几" => "茶几",
+"草丛里" => "草叢裡",
+"庄里" => "莊裡",
+"茎干" => "莖幹",
+"菌丝体" => "菌絲体",
+"菌丝体" => "菌絲體",
+"华里" => "華裡",
+"华发" => "華髮",
+"万卷" => "萬卷",
+"万历" => "萬曆",
+"万只" => "萬隻",
+"落发" => "落髮",
+"着儿" => "著兒",
+"着书立说" => "著書立說",
+"着色软体" => "著色軟體",
+"着重指出" => "著重指出",
+"着录" => "著錄",
+"着录规则" => "著錄規則",
+"蓄发" => "蓄髮",
+"蓄须" => "蓄鬚",
+"蓬发" => "蓬髮",
+"蓬松" => "蓬鬆",
+"莲台" => "蓮臺",
+"薑丝" => "薑絲",
+"薙发" => "薙髮",
+"借以" => "藉以",
+"借助" => "藉助",
+"借口" => "藉口",
+"借故" => "藉故",
+"借机" => "藉機",
+"借此" => "藉此",
+"借由" => "藉由",
+"借端" => "藉端",
+"借着" => "藉著",
+"借借" => "藉藉",
+"借词" => "藉詞",
+"借资" => "藉資",
+"借酒浇愁" => "藉酒澆愁",
+"藤制" => "藤製",
+"蕴含着" => "蘊含著",
+"蕴涵着" => "蘊涵著",
+"蕴借" => "蘊藉",
+"萝卜" => "蘿蔔",
+"虎须" => "虎鬚",
+"号志" => "號誌",
+"蜂後" => "蜂后",
+"蜜里调油" => "蜜裡調油",
+"蠁干" => "蠁幹",
+"蛮干" => "蠻幹",
+"行事历" => "行事曆",
+"胡同" => "衚衕",
+"冲上" => "衝上",
+"冲下" => "衝下",
+"冲来" => "衝來",
+"冲倒" => "衝倒",
+"冲冠" => "衝冠",
+"冲出" => "衝出",
+"冲到" => "衝到",
+"冲刺" => "衝刺",
+"冲克" => "衝剋",
+"冲力" => "衝力",
+"冲劲" => "衝勁",
+"冲动" => "衝動",
+"冲去" => "衝去",
+"冲口" => "衝口",
+"冲垮" => "衝垮",
+"冲堂" => "衝堂",
+"冲压" => "衝壓",
+"冲天" => "衝天",
+"冲掉" => "衝掉",
+"冲撞" => "衝撞",
+"冲击" => "衝擊",
+"冲散" => "衝散",
+"冲决" => "衝決",
+"冲浪" => "衝浪",
+"冲激" => "衝激",
+"冲破" => "衝破",
+"冲程" => "衝程",
+"冲突" => "衝突",
+"冲线" => "衝線",
+"冲着" => "衝著",
+"冲冲" => "衝衝",
+"冲要" => "衝要",
+"冲起" => "衝起",
+"冲进" => "衝進",
+"冲过" => "衝過",
+"冲锋" => "衝鋒",
+"表里" => "表裡",
+"袋里" => "袋裡",
+"袖里" => "袖裡",
+"被里" => "被裡",
+"被复" => "被複",
+"被复" => "被覆",
+"被复着" => "被覆著",
+"被发" => "被髮",
+"裁并" => "裁併",
+"裁制" => "裁製",
+"里面" => "裏面",
+"里人" => "裡人",
+"里加" => "裡加",
+"里外" => "裡外",
+"里子" => "裡子",
+"里屋" => "裡屋",
+"里层" => "裡層",
+"里布" => "裡布",
+"里带" => "裡帶",
+"里弦" => "裡弦",
+"里应外合" => "裡應外合",
+"里拉" => "裡拉",
+"里斯" => "裡斯",
+"里海" => "裡海",
+"里脊" => "裡脊",
+"里衣" => "裡衣",
+"里里" => "裡裡",
+"里通外国" => "裡通外國",
+"里通外敌" => "裡通外敵",
+"里边" => "裡邊",
+"里间" => "裡間",
+"里面" => "裡面",
+"里头" => "裡頭",
+"制件" => "製件",
+"制作" => "製作",
+"制做" => "製做",
+"制备" => "製備",
+"制冰" => "製冰",
+"制冷" => "製冷",
+"制剂" => "製劑",
+"制品" => "製品",
+"制图" => "製圖",
+"制成" => "製成",
+"制法" => "製法",
+"制为" => "製為",
+"制片" => "製片",
+"制版" => "製版",
+"制程" => "製程",
+"制糖" => "製糖",
+"制纸" => "製紙",
+"制药" => "製藥",
+"制表" => "製表",
+"制裁" => "製裁",
+"制造" => "製造",
+"制革" => "製革",
+"制鞋" => "製鞋",
+"制盐" => "製鹽",
+"复仞年如" => "複仞年如",
+"复以百万" => "複以百萬",
+"复位" => "複位",
+"复信" => "複信",
+"复分数" => "複分數",
+"复列" => "複列",
+"复利" => "複利",
+"复印" => "複印",
+"复原" => "複原",
+"复句" => "複句",
+"复合" => "複合",
+"复名" => "複名",
+"复员" => "複員",
+"复壁" => "複壁",
+"复壮" => "複壯",
+"复姓" => "複姓",
+"复字键" => "複字鍵",
+"复审" => "複審",
+"复写" => "複寫",
+"复式" => "複式",
+"复复" => "複復",
+"复数" => "複數",
+"复本" => "複本",
+"复查" => "複查",
+"复核" => "複核",
+"复检" => "複檢",
+"复次" => "複次",
+"复比" => "複比",
+"复决" => "複決",
+"复活" => "複活",
+"复测" => "複測",
+"复亩珍" => "複畝珍",
+"复发" => "複發",
+"复目" => "複目",
+"复眼" => "複眼",
+"复种" => "複種",
+"复线" => "複線",
+"复习" => "複習",
+"复兴社" => "複興社",
+"复旧" => "複舊",
+"复色" => "複色",
+"复叶" => "複葉",
+"复盖" => "複蓋",
+"复苏" => "複蘇",
+"复制" => "複製",
+"复诊" => "複診",
+"复评" => "複評",
+"复词" => "複詞",
+"复试" => "複試",
+"复课" => "複課",
+"复议" => "複議",
+"复变函数" => "複變函數",
+"复赛" => "複賽",
+"复述" => "複述",
+"复选" => "複選",
+"复钱" => "複錢",
+"复阅" => "複閱",
+"复杂" => "複雜",
+"复电" => "複電",
+"复音" => "複音",
+"复韵" => "複韻",
+"衬里" => "襯裡",
+"西岳" => "西嶽",
+"西征" => "西征",
+"西历" => "西曆",
+"要冲" => "要衝",
+"要么" => "要麼",
+"复上" => "覆上",
+"复亡" => "覆亡",
+"复住" => "覆住",
+"复信" => "覆信",
+"复冒" => "覆冒",
+"复判" => "覆判",
+"复命" => "覆命",
+"复在" => "覆在",
+"复审" => "覆審",
+"复写" => "覆寫",
+"复巢" => "覆巢",
+"复成" => "覆成",
+"复败" => "覆敗",
+"复文" => "覆文",
+"复校" => "覆校",
+"复核" => "覆核",
+"复水难收" => "覆水難收",
+"复没" => "覆沒",
+"复灭" => "覆滅",
+"复叠" => "覆疊",
+"复盆" => "覆盆",
+"复舟" => "覆舟",
+"复着" => "覆著",
+"复盖" => "覆蓋",
+"复盖着" => "覆蓋著",
+"复试" => "覆試",
+"复诵" => "覆誦",
+"复议" => "覆議",
+"复车" => "覆車",
+"复载" => "覆載",
+"复辙" => "覆轍",
+"复述" => "覆述",
+"复选" => "覆選",
+"复电" => "覆電",
+"复鼎金" => "覆鼎金",
+"见复" => "見覆",
+"亲征" => "親征",
+"观众台" => "觀眾臺",
+"观台" => "觀臺",
+"观象台" => "觀象臺",
+"角落里" => "角落裡",
+"觔斗" => "觔斗",
+"触须" => "觸鬚",
+"订制" => "訂製",
+"诉说着" => "訴說著",
+"词汇" => "詞彙",
+"词采" => "詞采",
+"试卷" => "試卷",
+"试制" => "試製",
+"诗卷" => "詩卷",
+"话里有话" => "話裡有話",
+"志哀" => "誌哀",
+"志喜" => "誌喜",
+"志庆" => "誌慶",
+"语云" => "語云",
+"语汇" => "語彙",
+"诬蔑" => "誣衊",
+"诵经台" => "誦經臺",
+"说着" => "說著",
+"课征" => "課征",
+"调制" => "調製",
+"调频台" => "調頻臺",
+"请参阅" => "請參閱",
+"讲台" => "講臺",
+"谢绝参观" => "謝絕參觀",
+"护发" => "護髮",
+"雠正" => "讎正",
+"雠隙" => "讎隙",
+"豆腐干" => "豆腐干",
+"竖着" => "豎著",
+"丰富多采" => "豐富多采",
+"丰滨" => "豐濱",
+"丰滨乡" => "豐濱鄉",
+"丰采" => "豐采",
+"象征着" => "象徵著",
+"贵干" => "貴幹",
+"贾後" => "賈后",
+"赈饥" => "賑饑",
+"赐复" => "賜覆",
+"贤後" => "賢后",
+"质朴" => "質朴",
+"赌台" => "賭檯",
+"购并" => "購併",
+"赤绳系足" => "赤繩繫足",
+"赤松" => "赤鬆",
+"起吊" => "起吊",
+"起复" => "起複",
+"超级杯" => "超級盃",
+"赶制" => "趕製",
+"跟斗" => "跟斗",
+"跳表" => "跳錶",
+"蹈借" => "蹈藉",
+"踬仆" => "躓仆",
+"躯干" => "軀幹",
+"车库里" => "車庫裡",
+"车站里" => "車站裡",
+"车里" => "車裡",
+"轻松" => "輕鬆",
+"轮回" => "輪迴",
+"转台" => "轉檯",
+"辛丑" => "辛丑",
+"辟易" => "辟易",
+"辟邪" => "辟邪",
+"办伙" => "辦伙",
+"办公台" => "辦公檯",
+"辞汇" => "辭彙",
+"农历" => "農曆",
+"迂回" => "迂迴",
+"近日里" => "近日裡",
+"迥然回异" => "迥然迴異",
+"回光返照" => "迴光返照",
+"回向" => "迴向",
+"回圈" => "迴圈",
+"回廊" => "迴廊",
+"回形夹" => "迴形夾",
+"回文" => "迴文",
+"回旋" => "迴旋",
+"回流" => "迴流",
+"回环" => "迴環",
+"回盪" => "迴盪",
+"回纹针" => "迴紋針",
+"回绕" => "迴繞",
+"回翔" => "迴翔",
+"回肠" => "迴腸",
+"回荡" => "迴蕩",
+"回诵" => "迴誦",
+"回路" => "迴路",
+"回转" => "迴轉",
+"回递性" => "迴遞性",
+"回避" => "迴避",
+"回銮" => "迴鑾",
+"回音" => "迴音",
+"回响" => "迴響",
+"回风" => "迴風",
+"回首" => "迴首",
+"迷蒙" => "迷濛",
+"退伙" => "退伙",
+"这么着" => "這么著",
+"这里" => "這裏",
+"这里" => "這裡",
+"这只" => "這隻",
+"这么" => "這麼",
+"这么着" => "這麼著",
+"通心面" => "通心麵",
+"速食面" => "速食麵",
+"连系" => "連繫",
+"连台好戏" => "連臺好戲",
+"遍布" => "遍佈",
+"递回" => "遞迴",
+"远征" => "遠征",
+"适才" => "適纔",
+"遮复" => "遮覆",
+"还冲" => "還衝",
+"邋里邋遢" => "邋裡邋遢",
+"那里" => "那裏",
+"那里" => "那裡",
+"那只" => "那隻",
+"那么" => "那麼",
+"那么着" => "那麼著",
+"邪辟" => "邪辟",
+"郁烈" => "郁烈",
+"郁穆" => "郁穆",
+"郁郁" => "郁郁",
+"郁闭" => "郁閉",
+"郁馥" => "郁馥",
+"乡愿" => "鄉愿",
+"乡里" => "鄉裡",
+"邻里" => "鄰裡",
+"配合着" => "配合著",
+"配制" => "配製",
+"酒杯" => "酒盃",
+"酒坛" => "酒罈",
+"酥松" => "酥鬆",
+"醋坛" => "醋罈",
+"酝借" => "醞藉",
+"酝酿着" => "醞釀著",
+"医药" => "醫葯",
+"醲郁" => "醲郁",
+"酿制" => "釀製",
+"采地" => "采地",
+"采女" => "采女",
+"采声" => "采聲",
+"采色" => "采色",
+"采薇" => "采薇",
+"采薪之忧" => "采薪之憂",
+"采兰赠药" => "采蘭贈藥",
+"采邑" => "采邑",
+"采采" => "采采",
+"采风" => "采風",
+"里程表" => "里程錶",
+"重折" => "重摺",
+"重制" => "重製",
+"重复" => "重複",
+"重复" => "重覆",
+"野台戏" => "野臺戲",
+"金斗" => "金斗",
+"金装玉里" => "金裝玉裡",
+"金表" => "金錶",
+"金发" => "金髮",
+"银朱" => "銀硃",
+"银发" => "銀髮",
+"铜制" => "銅製",
+"铝制" => "鋁製",
+"钢制" => "鋼製",
+"录着" => "錄著",
+"录制" => "錄製",
+"表带" => "錶帶",
+"表店" => "錶店",
+"表厂" => "錶廠",
+"表壳" => "錶殼",
+"表链" => "錶鏈",
+"表面" => "錶面",
+"锅台" => "鍋臺",
+"锻鍊出" => "鍛鍊出",
+"锻鍊身体" => "鍛鍊身体",
+"镜台" => "鏡臺",
+"锈病" => "鏽病",
+"锈菌" => "鏽菌",
+"锈蚀" => "鏽蝕",
+"钟表" => "鐘錶",
+"铁锈" => "鐵鏽",
+"长征" => "長征",
+"长发" => "長髮",
+"长须鲸" => "長鬚鯨",
+"门帘" => "門帘",
+"门斗" => "門斗",
+"门里" => "門裡",
+"开伙" => "開伙",
+"开卷" => "開卷",
+"开诚布公" => "開誠佈公",
+"开采" => "開采",
+"閒情逸致" => "閒情逸緻",
+"间不容发" => "間不容髮",
+"闵采尔" => "閔采爾",
+"阅卷" => "閱卷",
+"阑干" => "闌干",
+"关系" => "關係",
+"关系着" => "關係著",
+"防御" => "防禦",
+"防锈" => "防鏽",
+"防台" => "防颱",
+"阿斗" => "阿斗",
+"阿里" => "阿裡",
+"除旧布新" => "除舊佈新",
+"阴干" => "陰干",
+"阴历" => "陰曆",
+"阴郁" => "陰郁",
+"陆征祥" => "陸征祥",
+"阳春面" => "陽春麵",
+"阳历" => "陽曆",
+"阳台" => "陽臺",
+"只字" => "隻字",
+"只影" => "隻影",
+"只手遮天" => "隻手遮天",
+"只眼" => "隻眼",
+"只言片语" => "隻言片語",
+"只身" => "隻身",
+"雅致" => "雅緻",
+"雇佣" => "雇佣",
+"双折" => "雙摺",
+"杂志" => "雜誌",
+"鸡丝" => "雞絲",
+"鸡丝面" => "雞絲麵",
+"鸡腿面" => "雞腿麵",
+"鸡只" => "雞隻",
+"难舍" => "難捨",
+"雨花台" => "雨花臺",
+"雪里" => "雪裡",
+"云须" => "雲鬚",
+"电子表" => "電子錶",
+"电台" => "電臺",
+"电冲" => "電衝",
+"电复" => "電覆",
+"电视台" => "電視臺",
+"电表" => "電錶",
+"雾台" => "霧臺",
+"雾里" => "霧裡",
+"露台" => "露臺",
+"灵台" => "靈臺",
+"青瓦台" => "青瓦臺",
+"青霉" => "青黴",
+"面朝着" => "面朝著",
+"面临着" => "面臨著",
+"鞋里" => "鞋裡",
+"鞣制" => "鞣製",
+"秋千" => "鞦韆",
+"鞭辟入里" => "鞭辟入裡",
+"韩国制" => "韓國製",
+"韩制" => "韓製",
+"颂系" => "頌繫",
+"预制" => "預製",
+"颁布" => "頒佈",
+"头里" => "頭裡",
+"头发" => "頭髮",
+"颊须" => "頰鬚",
+"颠仆" => "顛仆",
+"颠复" => "顛複",
+"颠复" => "顛覆",
+"显着标志" => "顯著標志",
+"风土志" => "風土誌",
+"风斗" => "風斗",
+"风物志" => "風物誌",
+"风里" => "風裡",
+"风采" => "風采",
+"台风" => "颱風",
+"刮了" => "颳了",
+"刮倒" => "颳倒",
+"刮去" => "颳去",
+"刮得" => "颳得",
+"刮着" => "颳著",
+"刮走" => "颳走",
+"刮起" => "颳起",
+"刮风" => "颳風",
+"饭团" => "飯糰",
+"饼干" => "餅干",
+"馄饨面" => "餛飩麵",
+"饥不择食" => "饑不擇食",
+"饥寒" => "饑寒",
+"饥民" => "饑民",
+"饥渴" => "饑渴",
+"饥溺" => "饑溺",
+"饥荒" => "饑荒",
+"饥饱" => "饑飽",
+"饥饿" => "饑餓",
+"饥馑" => "饑饉",
+"首当其冲" => "首當其衝",
+"香郁" => "香郁",
+"馥郁" => "馥郁",
+"马里" => "馬裡",
+"马表" => "馬錶",
+"腾冲" => "騰衝",
+"骨子里" => "骨子裡",
+"骨干" => "骨幹",
+"骨灰坛" => "骨灰罈",
+"肮脏" => "骯髒",
+"脏乱" => "髒亂",
+"脏了" => "髒了",
+"脏兮兮" => "髒兮兮",
+"脏字" => "髒字",
+"脏得" => "髒得",
+"脏东西" => "髒東西",
+"脏水" => "髒水",
+"脏的" => "髒的",
+"脏话" => "髒話",
+"脏钱" => "髒錢",
+"高干" => "高幹",
+"高台" => "高臺",
+"髭须" => "髭鬚",
+"发型" => "髮型",
+"发夹" => "髮夾",
+"发妻" => "髮妻",
+"发姐" => "髮姐",
+"发带" => "髮帶",
+"发廊" => "髮廊",
+"发式" => "髮式",
+"发指" => "髮指",
+"发捲" => "髮捲",
+"发根" => "髮根",
+"发毛" => "髮毛",
+"发油" => "髮油",
+"发状" => "髮狀",
+"发短心长" => "髮短心長",
+"发端" => "髮端",
+"发结" => "髮結",
+"发丝" => "髮絲",
+"发网" => "髮網",
+"发肤" => "髮膚",
+"发胶" => "髮膠",
+"发菜" => "髮菜",
+"发蜡" => "髮蠟",
+"发辫" => "髮辮",
+"发针" => "髮針",
+"发长" => "髮長",
+"发际" => "髮際",
+"发雕" => "髮雕",
+"发霜" => "髮霜",
+"发髻" => "髮髻",
+"发鬓" => "髮鬢",
+"鬅松" => "鬅鬆",
+"松了" => "鬆了",
+"松些" => "鬆些",
+"松劲" => "鬆勁",
+"松动" => "鬆動",
+"松口" => "鬆口",
+"松土" => "鬆土",
+"松弛" => "鬆弛",
+"松快" => "鬆快",
+"松懈" => "鬆懈",
+"松手" => "鬆手",
+"松掉" => "鬆掉",
+"松散" => "鬆散",
+"松林" => "鬆林",
+"松柔" => "鬆柔",
+"松毛虫" => "鬆毛蟲",
+"松浮" => "鬆浮",
+"松涛" => "鬆濤",
+"松科" => "鬆科",
+"松节油" => "鬆節油",
+"松绑" => "鬆綁",
+"松紧" => "鬆緊",
+"松缓" => "鬆緩",
+"松脆" => "鬆脆",
+"松脱" => "鬆脫",
+"松起" => "鬆起",
+"松软" => "鬆軟",
+"松通" => "鬆通",
+"松开" => "鬆開",
+"松饼" => "鬆餅",
+"松松" => "鬆鬆",
+"鬈发" => "鬈髮",
+"胡子" => "鬍子",
+"胡梢" => "鬍梢",
+"胡渣" => "鬍渣",
+"胡髭" => "鬍髭",
+"胡须" => "鬍鬚",
+"须根" => "鬚根",
+"须毛" => "鬚毛",
+"须生" => "鬚生",
+"须眉" => "鬚眉",
+"须发" => "鬚髮",
+"须须" => "鬚鬚",
+"鬓发" => "鬢髮",
+"斗着" => "鬥著",
+"闹着玩儿" => "鬧著玩儿",
+"闹着玩儿" => "鬧著玩兒",
+"郁郁" => "鬱郁",
+"魂牵梦系" => "魂牽夢繫",
+"鱼松" => "魚鬆",
+"鲸须" => "鯨鬚",
+"鲇鱼" => "鯰魚",
+"鸿篇巨制" => "鴻篇巨製",
+"鹤发" => "鶴髮",
+"卤化" => "鹵化",
+"卤味" => "鹵味",
+"卤族" => "鹵族",
+"卤水" => "鹵水",
+"卤汁" => "鹵汁",
+"卤簿" => "鹵簿",
+"卤素" => "鹵素",
+"卤莽" => "鹵莽",
+"卤钝" => "鹵鈍",
+"咸味" => "鹹味",
+"咸土" => "鹹土",
+"咸度" => "鹹度",
+"咸得" => "鹹得",
+"咸水" => "鹹水",
+"咸海" => "鹹海",
+"咸淡" => "鹹淡",
+"咸湖" => "鹹湖",
+"咸汤" => "鹹湯",
+"咸的" => "鹹的",
+"咸肉" => "鹹肉",
+"咸菜" => "鹹菜",
+"咸蛋" => "鹹蛋",
+"咸猪肉" => "鹹豬肉",
+"咸类" => "鹹類",
+"咸鱼" => "鹹魚",
+"咸鸭蛋" => "鹹鴨蛋",
+"咸卤" => "鹹鹵",
+"咸咸" => "鹹鹹",
+"盐卤" => "鹽鹵",
+"面价" => "麵價",
+"面包" => "麵包",
+"面团" => "麵團",
+"面店" => "麵店",
+"面厂" => "麵廠",
+"面摊" => "麵攤",
+"面杖" => "麵杖",
+"面条" => "麵條",
+"面灰" => "麵灰",
+"面皮" => "麵皮",
+"面筋" => "麵筋",
+"面粉" => "麵粉",
+"面糊" => "麵糊",
+"面线" => "麵線",
+"面茶" => "麵茶",
+"面食" => "麵食",
+"面饺" => "麵餃",
+"面饼" => "麵餅",
+"麻酱面" => "麻醬麵",
+"黄卷" => "黃卷",
+"黄历" => "黃曆",
+"黄发" => "黃髮",
+"黑发" => "黑髮",
+"黑松" => "黑鬆",
+"霉毒" => "黴毒",
+"霉素" => "黴素",
+"霉菌" => "黴菌",
+"鼓里" => "鼓裡",
+"冬冬" => "鼕鼕",
+"龙卷" => "龍卷",
+"龙须" => "龍鬚",
+"内存"=>"記憶體",
+"默认"=>"預設",
+"缺省"=>"預設",
+"串行"=>"串列",
+"以太网"=>"乙太網",
+"位图"=>"點陣圖",
+"例程"=>"常式",
+"信道"=>"通道",
+"光标"=>"游標",
+"光盘"=>"光碟",
+"光驱"=>"光碟機",
+"全角"=>"全形",
+"共享"=>"共用",
+"兼容"=>"相容",
+"前缀"=>"首碼",
+"后缀"=>"尾碼",
+"加载"=>"載入",
+"半角"=>"半形",
+"变量"=>"變數",
+"噪声"=>"雜訊",
+"因子"=>"因數",
+"在线"=>"線上",
+"脱机"=>"離線",
+"域名"=>"功能變數名稱",
+"声卡"=>"音效卡",
+"字号"=>"字型大小",
+"字库"=>"字型檔",
+"字段"=>"欄位",
+"字符"=>"字元",
+"存盘"=>"存檔",
+"寻址"=>"定址",
+"尾注"=>"章節附註",
+"异步"=>"非同步",
+"总线"=>"匯流排",
+"括号"=>"括弧",
+"接口"=>"介面",
+"控件"=>"控制項",
+"权限"=>"許可權",
+"盘片"=>"碟片",
+"硅片"=>"矽片",
+"硅谷"=>"矽谷",
+"硬盘"=>"硬碟",
+"磁盘"=>"磁碟",
+"磁道"=>"磁軌",
+"程控"=>"程式控制",
+"端口"=>"埠",
+"算子"=>"運算元",
+"算法"=>"演算法",
+"芯片"=>"晶片",
+"芯片"=>"晶元",
+"词组"=>"片語",
+"译码"=>"解碼",
+"软驱"=>"軟碟機",
+"闪存"=>"快閃記憶體",
+"鼠标"=>"滑鼠",
+"进制"=>"進位",
+"交互式"=>"互動式",
+"仿真"=>"模擬",
+"优先级"=>"優先順序",
+"传感"=>"感測",
+"便携式"=>"攜帶型",
+"信息论"=>"資訊理論",
+"循环"=>"迴圈",
+"写保护"=>"防寫",
+"分布式"=>"分散式",
+"分辨率"=>"解析度",
+"程序"=>"程式",
+"服务器"=>"伺服器",
+"等于"=>"等於",
+"局域网"=>"區域網",
+"上载"=>"上傳",
+"计算机"=>"電腦",
+"宏"=>"巨集",
+"扫瞄仪"=>"掃瞄器",
+"宽带"=>"寬頻",
+"窗口"=>"視窗",
+"数据库"=>"資料庫",
+"公历"=>"西曆",
+"奶酪"=>"乳酪",
+"巨商"=>"鉅賈",
+"手电"=>"手電筒",
+"万历"=>"萬曆",
+"永历"=>"永曆",
+"词汇"=>"辭彙",
+"保安"=>"保全",
+"习用"=>"慣用",
+"元音"=>"母音",
+"任意球"=>"自由球",
+"头球"=>"頭槌",
+"入球"=>"進球",
+"粒入球"=>"顆進球",
+"打门"=>"射門",
+"火锅盖帽"=>"蓋火鍋",
+"打印机"=>"印表機",
+"打印機"=>"印表機",
+"字节"=>"位元組",
+"字節"=>"位元組",
+"打印"=>"列印",
+"打印"=>"列印",
+"硬件"=>"硬體",
+"硬件"=>"硬體",
+"二极管"=>"二極體",
+"二極管"=>"二極體",
+"三极管"=>"三極體",
+"三極管"=>"三極體",
+"数码"=>"數位",
+"數碼"=>"數位",
+"软件"=>"軟體",
+"軟件"=>"軟體",
+"网络"=>"網路",
+"網絡"=>"網路",
+"人工智能"=>"人工智慧",
+"航天飞机"=>"太空梭",
+"穿梭機"=>"太空梭",
+"因特网"=>"網際網路",
+"互聯網"=>"網際網路",
+"机器人"=>"機器人",
+"機械人"=>"機器人",
+"移动电话"=>"行動電話",
+"流動電話"=>"行動電話",
+"调制解调器"=>"數據機",
+"調制解調器"=>"數據機",
+"短信"=>"簡訊",
+"短訊"=>"簡訊",
+"乌兹别克斯坦"=>"烏茲別克",
+"乍得"=>"查德",
+"乍得"=>"查德",
+"也门"=>"葉門",
+"也門"=>"葉門",
+"伯利兹"=>"貝里斯",
+"伯利茲"=>"貝里斯",
+"佛得角"=>"維德角",
+"佛得角"=>"維德角",
+"克罗地亚"=>"克羅埃西亞",
+"克羅地亞"=>"克羅埃西亞",
+"冈比亚"=>"甘比亞",
+"岡比亞"=>"甘比亞",
+"几内亚比绍"=>"幾內亞比索",
+"幾內亞比紹"=>"幾內亞比索",
+"列支敦士登"=>"列支敦斯登",
+"列支敦士登"=>"列支敦斯登",
+"利比里亚"=>"賴比瑞亞",
+"利比里亞"=>"賴比瑞亞",
+"加纳"=>"迦納",
+"加納"=>"迦納",
+"加蓬"=>"加彭",
+"加蓬"=>"加彭",
+"博茨瓦纳"=>"波札那",
+"博茨瓦納"=>"波札那",
+"卡塔尔"=>"卡達",
+"卡塔爾"=>"卡達",
+"卢旺达"=>"盧安達",
+"盧旺達"=>"盧安達",
+"危地马拉"=>"瓜地馬拉",
+"危地馬拉"=>"瓜地馬拉",
+"厄瓜多尔"=>"厄瓜多",
+"厄瓜多爾"=>"厄瓜多",
+"厄立特里亚"=>"厄利垂亞",
+"厄立特里亞"=>"厄利垂亞",
+"吉布提"=>"吉布地",
+"吉布堤"=>"吉布地",
+"哈萨克斯坦"=>"哈薩克",
+"哥斯达黎加"=>"哥斯大黎加",
+"哥斯達黎加"=>"哥斯大黎加",
+"图瓦卢"=>"吐瓦魯",
+"圖瓦盧"=>"吐瓦魯",
+"土库曼斯坦"=>"土庫曼",
+"圣卢西亚"=>"聖露西亞",
+"聖盧西亞"=>"聖露西亞",
+"圣基茨和尼维斯"=>"聖克里斯多福及尼維斯",
+"聖吉斯納域斯"=>"聖克里斯多福及尼維斯",
+"圣文森特和格林纳丁斯"=>"聖文森及格瑞那丁",
+"聖文森特和格林納丁斯"=>"聖文森及格瑞那丁",
+"圣马力诺"=>"聖馬利諾",
+"聖馬力諾"=>"聖馬利諾",
+"圭亚那"=>"蓋亞那",
+"圭亞那"=>"蓋亞那",
+"坦桑尼亚"=>"坦尚尼亞",
+"坦桑尼亞"=>"坦尚尼亞",
+"埃塞俄比亚"=>"衣索比亞",
+"埃塞俄比亞"=>"衣索比亞",
+"基里巴斯"=>"吉里巴斯",
+"基里巴斯"=>"吉里巴斯",
+"塔吉克斯坦"=>"塔吉克",
+"塞拉利昂"=>"獅子山",
+"塞拉利昂"=>"獅子山",
+"塞浦路斯"=>"塞普勒斯",
+"塞浦路斯"=>"塞普勒斯",
+"塞舌尔"=>"塞席爾",
+"塞舌爾"=>"塞席爾",
+"多米尼加"=>"多明尼加",
+"多明尼加共和國"=>"多明尼加",
+"多米尼加联邦"=>"多米尼克",
+"多明尼加聯邦"=>"多米尼克",
+"安提瓜和巴布达"=>"安地卡及巴布達",
+"安提瓜和巴布達"=>"安地卡及巴布達",
+"尼日利亚"=>"奈及利亞",
+"尼日利亞"=>"奈及利亞",
+"尼日尔"=>"尼日",
+"尼日爾"=>"尼日",
+"巴巴多斯"=>"巴貝多",
+"巴巴多斯"=>"巴貝多",
+"巴布亚新几内亚"=>"巴布亞紐幾內亞",
+"巴布亞新畿內亞"=>"巴布亞紐幾內亞",
+"布基纳法索"=>"布吉納法索",
+"布基納法索"=>"布吉納法索",
+"布隆迪"=>"蒲隆地",
+"布隆迪"=>"蒲隆地",
+"希腊"=>"希臘",
+"帕劳"=>"帛琉",
+"意大利"=>"義大利",
+"意大利"=>"義大利",
+"所罗门群岛"=>"索羅門群島",
+"所羅門群島"=>"索羅門群島",
+"文莱"=>"汶萊",
+"斯威士兰"=>"史瓦濟蘭",
+"斯威士蘭"=>"史瓦濟蘭",
+"斯洛文尼亚"=>"斯洛維尼亞",
+"斯洛文尼亞"=>"斯洛維尼亞",
+"新西兰"=>"紐西蘭",
+"新西蘭"=>"紐西蘭",
+"朝鲜"=>"北韓",
+"格林纳达"=>"格瑞那達",
+"格林納達"=>"格瑞那達",
+"格鲁吉亚"=>"喬治亞",
+"格魯吉亞"=>"喬治亞",
+"梵蒂冈"=>"教廷",
+"梵蒂岡"=>"教廷",
+"毛里塔尼亚"=>"茅利塔尼亞",
+"毛里塔尼亞"=>"茅利塔尼亞",
+"毛里求斯"=>"模里西斯",
+"毛里裘斯"=>"模里西斯",
+"沙特阿拉伯"=>"沙烏地阿拉伯",
+"沙地阿拉伯"=>"沙烏地阿拉伯",
+"波斯尼亚和黑塞哥维那"=>"波士尼亞赫塞哥維納",
+"波斯尼亞黑塞哥維那"=>"波士尼亞赫塞哥維納",
+"津巴布韦"=>"辛巴威",
+"津巴布韋"=>"辛巴威",
+"洪都拉斯"=>"宏都拉斯",
+"洪都拉斯"=>"宏都拉斯",
+"特立尼达和托巴哥"=>"千里達托貝哥",
+"特立尼達和多巴哥"=>"千里達托貝哥",
+"瑙鲁"=>"諾魯",
+"瑙魯"=>"諾魯",
+"瓦努阿图"=>"萬那杜",
+"瓦努阿圖"=>"萬那杜",
+"溫納圖萬"=>"那杜",
+"科摩罗"=>"葛摩",
+"科摩羅"=>"葛摩",
+"科特迪瓦"=>"象牙海岸",
+"突尼斯"=>"突尼西亞",
+"索马里"=>"索馬利亞",
+"索馬里"=>"索馬利亞",
+"老挝"=>"寮國",
+"老撾"=>"寮國",
+"肯尼亚"=>"肯亞",
+"肯雅"=>"肯亞",
+"苏里南"=>"蘇利南",
+"莫桑比克"=>"莫三比克",
+"莱索托"=>"賴索托",
+"萊索托"=>"賴索托",
+"贝宁"=>"貝南",
+"貝寧"=>"貝南",
+"赞比亚"=>"尚比亞",
+"贊比亞"=>"尚比亞",
+"阿塞拜疆"=>"亞塞拜然",
+"阿塞拜疆"=>"亞塞拜然",
+"阿拉伯联合酋长国"=>"阿拉伯聯合大公國",
+"阿拉伯聯合酋長國"=>"阿拉伯聯合大公國",
+"韩国"=>"南韓",
+"马尔代夫"=>"馬爾地夫",
+"馬爾代夫"=>"馬爾地夫",
+"马耳他"=>"馬爾他",
+"马里"=>"馬利",
+"馬里"=>"馬利",
+"方便面"=>"速食麵",
+"快速面"=>"速食麵",
+"即食麵"=>"速食麵",
+"薯仔"=>"土豆",
+"蹦极跳"=>"笨豬跳",
+"绑紧跳"=>"笨豬跳",
+"冷菜"=>"冷盤",
+"凉菜"=>"冷盤",
+"的士"=>"計程車",
+"出租车"=>"計程車",
+"巴士"=>"公車",
+"公共汽车"=>"公車",
+"台球"=>"撞球",
+"桌球"=>"撞球",
+"雪糕"=>"冰淇淋",
+"卫生"=>"衛生",
+"衞生"=>"衛生",
+"平治"=>"賓士",
+"奔驰"=>"賓士",
+"積架"=>"捷豹",
+"福士"=>"福斯",
+"雪铁龙"=>"雪鐵龍",
+"马自达"=>"馬自達",
+"萬事得"=>"馬自達",
+"布什"=>"布希",
+"布殊"=>"布希",
+"克林顿"=>"柯林頓",
+"克林頓"=>"柯林頓",
+"萨达姆"=>"海珊",
+"薩達姆"=>"海珊",
+"凡高"=>"梵谷",
+"狄安娜"=>"黛安娜",
+"戴安娜"=>"黛安娜",
+"赫拉"=>"希拉",
+);
+
+
+$zh2CN=array(
+"么"=>"么",
+"瀋"=>"沈",
+"畫"=>"划",
+"鍾"=>"钟",
+"餘"=>"余",
+"鯰"=>"鲇",
+"鹼"=>"硷",
+"麼"=>"么",
+"䊷"=>"䌶",
+"𧩙"=>"䜥",
+"万"=>"万",
+"与"=>"与",
+"丑"=>"丑",
+"丟"=>"丢",
+"並"=>"并",
+"丰"=>"丰",
+"么"=>"么",
+"乾"=>"干",
+"亂"=>"乱",
+"云"=>"云",
+"亙"=>"亘",
+"亞"=>"亚",
+"仆"=>"仆",
+"价"=>"价",
+"伙"=>"伙",
+"佇"=>"伫",
+"佈"=>"布",
+"体"=>"体",
+"余"=>"余",
+"余"=>"馀",
+"佣"=>"佣",
+"併"=>"并",
+"來"=>"来",
+"侖"=>"仑",
+"侶"=>"侣",
+"俁"=>"俣",
+"係"=>"系",
+"俔"=>"伣",
+"俠"=>"侠",
+"倀"=>"伥",
+"倆"=>"俩",
+"倈"=>"俫",
+"倉"=>"仓",
+"個"=>"个",
+"們"=>"们",
+"倫"=>"伦",
+"偉"=>"伟",
+"側"=>"侧",
+"偵"=>"侦",
+"偽"=>"伪",
+"傑"=>"杰",
+"傖"=>"伧",
+"傘"=>"伞",
+"備"=>"备",
+"傢"=>"家",
+"傭"=>"佣",
+"傯"=>"偬",
+"傳"=>"传",
+"傴"=>"伛",
+"債"=>"债",
+"傷"=>"伤",
+"傾"=>"倾",
+"僂"=>"偻",
+"僅"=>"仅",
+"僉"=>"佥",
+"僑"=>"侨",
+"僕"=>"仆",
+"僞"=>"伪",
+"僥"=>"侥",
+"僨"=>"偾",
+"價"=>"价",
+"儀"=>"仪",
+"儂"=>"侬",
+"億"=>"亿",
+"儈"=>"侩",
+"儉"=>"俭",
+"儐"=>"傧",
+"儔"=>"俦",
+"儕"=>"侪",
+"儘"=>"尽",
+"償"=>"偿",
+"優"=>"优",
+"儲"=>"储",
+"儷"=>"俪",
+"儺"=>"傩",
+"儻"=>"傥",
+"儼"=>"俨",
+"儿"=>"儿",
+"兇"=>"凶",
+"兌"=>"兑",
+"兒"=>"儿",
+"兗"=>"兖",
+"党"=>"党",
+"內"=>"内",
+"兩"=>"两",
+"冊"=>"册",
+"冪"=>"幂",
+"准"=>"准",
+"凈"=>"净",
+"凍"=>"冻",
+"凜"=>"凛",
+"几"=>"几",
+"凱"=>"凯",
+"划"=>"划",
+"別"=>"别",
+"刪"=>"删",
+"剄"=>"刭",
+"則"=>"则",
+"剋"=>"克",
+"剎"=>"刹",
+"剗"=>"刬",
+"剛"=>"刚",
+"剝"=>"剥",
+"剮"=>"剐",
+"剴"=>"剀",
+"創"=>"创",
+"劃"=>"划",
+"劇"=>"剧",
+"劉"=>"刘",
+"劊"=>"刽",
+"劌"=>"刿",
+"劍"=>"剑",
+"劑"=>"剂",
+"勁"=>"劲",
+"動"=>"动",
+"務"=>"务",
+"勛"=>"勋",
+"勝"=>"胜",
+"勞"=>"劳",
+"勢"=>"势",
+"勩"=>"勚",
+"勱"=>"劢",
+"勵"=>"励",
+"勸"=>"劝",
+"勻"=>"匀",
+"匭"=>"匦",
+"匯"=>"汇",
+"匱"=>"匮",
+"區"=>"区",
+"協"=>"协",
+"卷"=>"卷",
+"卻"=>"却",
+"厂"=>"厂",
+"厙"=>"厍",
+"厠"=>"厕",
+"厭"=>"厌",
+"厲"=>"厉",
+"厴"=>"厣",
+"參"=>"参",
+"叄"=>"叁",
+"叢"=>"丛",
+"台"=>"台",
+"叶"=>"叶",
+"吊"=>"吊",
+"后"=>"后",
+"后"=>"後",
+"吒"=>"咤",
+"吳"=>"吴",
+"吶"=>"呐",
+"呂"=>"吕",
+"咼"=>"呙",
+"員"=>"员",
+"唄"=>"呗",
+"唚"=>"吣",
+"問"=>"问",
+"啓"=>"启",
+"啞"=>"哑",
+"啟"=>"启",
+"啢"=>"唡",
+"喎"=>"㖞",
+"喚"=>"唤",
+"喪"=>"丧",
+"喬"=>"乔",
+"單"=>"单",
+"喲"=>"哟",
+"嗆"=>"呛",
+"嗇"=>"啬",
+"嗊"=>"唝",
+"嗎"=>"吗",
+"嗚"=>"呜",
+"嗩"=>"唢",
+"嗶"=>"哔",
+"嘆"=>"叹",
+"嘍"=>"喽",
+"嘔"=>"呕",
+"嘖"=>"啧",
+"嘗"=>"尝",
+"嘜"=>"唛",
+"嘩"=>"哗",
+"嘮"=>"唠",
+"嘯"=>"啸",
+"嘰"=>"叽",
+"嘵"=>"哓",
+"嘸"=>"呒",
+"嘽"=>"啴",
+"噁"=>"恶",
+"噓"=>"嘘",
+"噝"=>"咝",
+"噠"=>"哒",
+"噥"=>"哝",
+"噦"=>"哕",
+"噯"=>"嗳",
+"噲"=>"哙",
+"噴"=>"喷",
+"噸"=>"吨",
+"噹"=>"当",
+"嚀"=>"咛",
+"嚇"=>"吓",
+"嚌"=>"哜",
+"嚕"=>"噜",
+"嚙"=>"啮",
+"嚥"=>"咽",
+"嚦"=>"呖",
+"嚨"=>"咙",
+"嚮"=>"向",
+"嚲"=>"亸",
+"嚳"=>"喾",
+"嚴"=>"严",
+"嚶"=>"嘤",
+"囀"=>"啭",
+"囁"=>"嗫",
+"囂"=>"嚣",
+"囅"=>"冁",
+"囈"=>"呓",
+"囌"=>"苏",
+"囑"=>"嘱",
+"囪"=>"囱",
+"圇"=>"囵",
+"國"=>"国",
+"圍"=>"围",
+"園"=>"园",
+"圓"=>"圆",
+"圖"=>"图",
+"團"=>"团",
+"坏"=>"坏",
+"垵"=>"埯",
+"埡"=>"垭",
+"埰"=>"采",
+"執"=>"执",
+"堅"=>"坚",
+"堊"=>"垩",
+"堖"=>"垴",
+"堝"=>"埚",
+"堯"=>"尧",
+"報"=>"报",
+"場"=>"场",
+"塊"=>"块",
+"塋"=>"茔",
+"塏"=>"垲",
+"塒"=>"埘",
+"塗"=>"涂",
+"塚"=>"冢",
+"塢"=>"坞",
+"塤"=>"埙",
+"塵"=>"尘",
+"塹"=>"堑",
+"墊"=>"垫",
+"墜"=>"坠",
+"墮"=>"堕",
+"墳"=>"坟",
+"墻"=>"墙",
+"墾"=>"垦",
+"壇"=>"坛",
+"壈"=>"𡒄",
+"壋"=>"垱",
+"壓"=>"压",
+"壘"=>"垒",
+"壙"=>"圹",
+"壚"=>"垆",
+"壞"=>"坏",
+"壟"=>"垄",
+"壠"=>"垅",
+"壢"=>"坜",
+"壩"=>"坝",
+"壯"=>"壮",
+"壺"=>"壶",
+"壼"=>"壸",
+"壽"=>"寿",
+"夠"=>"够",
+"夢"=>"梦",
+"夾"=>"夹",
+"奐"=>"奂",
+"奧"=>"奥",
+"奩"=>"奁",
+"奪"=>"夺",
+"奬"=>"奖",
+"奮"=>"奋",
+"奼"=>"姹",
+"妝"=>"妆",
+"姍"=>"姗",
+"姜"=>"姜",
+"姦"=>"奸",
+"娛"=>"娱",
+"婁"=>"娄",
+"婦"=>"妇",
+"婭"=>"娅",
+"媧"=>"娲",
+"媯"=>"妫",
+"媼"=>"媪",
+"媽"=>"妈",
+"嫗"=>"妪",
+"嫵"=>"妩",
+"嫻"=>"娴",
+"嫿"=>"婳",
+"嬀"=>"妫",
+"嬈"=>"娆",
+"嬋"=>"婵",
+"嬌"=>"娇",
+"嬙"=>"嫱",
+"嬡"=>"嫒",
+"嬤"=>"嬷",
+"嬪"=>"嫔",
+"嬰"=>"婴",
+"嬸"=>"婶",
+"孌"=>"娈",
+"孫"=>"孙",
+"學"=>"学",
+"孿"=>"孪",
+"宁"=>"宁",
+"宮"=>"宫",
+"寢"=>"寝",
+"實"=>"实",
+"寧"=>"宁",
+"審"=>"审",
+"寫"=>"写",
+"寬"=>"宽",
+"寵"=>"宠",
+"寶"=>"宝",
+"將"=>"将",
+"專"=>"专",
+"尋"=>"寻",
+"對"=>"对",
+"導"=>"导",
+"尷"=>"尴",
+"屆"=>"届",
+"屍"=>"尸",
+"屓"=>"屃",
+"屜"=>"屉",
+"屢"=>"屡",
+"層"=>"层",
+"屨"=>"屦",
+"屬"=>"属",
+"岡"=>"冈",
+"峴"=>"岘",
+"島"=>"岛",
+"峽"=>"峡",
+"崍"=>"崃",
+"崗"=>"岗",
+"崢"=>"峥",
+"崬"=>"岽",
+"嵐"=>"岚",
+"嶁"=>"嵝",
+"嶄"=>"崭",
+"嶇"=>"岖",
+"嶔"=>"嵚",
+"嶗"=>"崂",
+"嶠"=>"峤",
+"嶢"=>"峣",
+"嶧"=>"峄",
+"嶮"=>"崄",
+"嶴"=>"岙",
+"嶸"=>"嵘",
+"嶺"=>"岭",
+"嶼"=>"屿",
+"嶽"=>"岳",
+"巋"=>"岿",
+"巒"=>"峦",
+"巔"=>"巅",
+"巰"=>"巯",
+"帘"=>"帘",
+"帥"=>"帅",
+"師"=>"师",
+"帳"=>"帐",
+"帶"=>"带",
+"幀"=>"帧",
+"幃"=>"帏",
+"幗"=>"帼",
+"幘"=>"帻",
+"幟"=>"帜",
+"幣"=>"币",
+"幫"=>"帮",
+"幬"=>"帱",
+"幹"=>"干",
+"幺"=>"么",
+"幾"=>"几",
+"广"=>"广",
+"庫"=>"库",
+"廁"=>"厕",
+"廂"=>"厢",
+"廄"=>"厩",
+"廈"=>"厦",
+"廚"=>"厨",
+"廝"=>"厮",
+"廟"=>"庙",
+"廠"=>"厂",
+"廡"=>"庑",
+"廢"=>"废",
+"廣"=>"广",
+"廩"=>"廪",
+"廬"=>"庐",
+"廳"=>"厅",
+"弒"=>"弑",
+"弳"=>"弪",
+"張"=>"张",
+"強"=>"强",
+"彆"=>"别",
+"彈"=>"弹",
+"彌"=>"弥",
+"彎"=>"弯",
+"彙"=>"汇",
+"彞"=>"彝",
+"彥"=>"彦",
+"征"=>"征",
+"後"=>"后",
+"徑"=>"径",
+"從"=>"从",
+"徠"=>"徕",
+"復"=>"复",
+"徵"=>"征",
+"徹"=>"彻",
+"恆"=>"恒",
+"恥"=>"耻",
+"悅"=>"悦",
+"悞"=>"悮",
+"悵"=>"怅",
+"悶"=>"闷",
+"惡"=>"恶",
+"惱"=>"恼",
+"惲"=>"恽",
+"惻"=>"恻",
+"愛"=>"爱",
+"愜"=>"惬",
+"愨"=>"悫",
+"愴"=>"怆",
+"愷"=>"恺",
+"愾"=>"忾",
+"愿"=>"愿",
+"慄"=>"栗",
+"態"=>"态",
+"慍"=>"愠",
+"慘"=>"惨",
+"慚"=>"惭",
+"慟"=>"恸",
+"慣"=>"惯",
+"慤"=>"悫",
+"慪"=>"怄",
+"慫"=>"怂",
+"慮"=>"虑",
+"慳"=>"悭",
+"慶"=>"庆",
+"憂"=>"忧",
+"憊"=>"惫",
+"憐"=>"怜",
+"憑"=>"凭",
+"憒"=>"愦",
+"憚"=>"惮",
+"憤"=>"愤",
+"憫"=>"悯",
+"憮"=>"怃",
+"憲"=>"宪",
+"憶"=>"忆",
+"懇"=>"恳",
+"應"=>"应",
+"懌"=>"怿",
+"懍"=>"懔",
+"懞"=>"蒙",
+"懟"=>"怼",
+"懣"=>"懑",
+"懨"=>"恹",
+"懲"=>"惩",
+"懶"=>"懒",
+"懷"=>"怀",
+"懸"=>"悬",
+"懺"=>"忏",
+"懼"=>"惧",
+"懾"=>"慑",
+"戀"=>"恋",
+"戇"=>"戆",
+"戔"=>"戋",
+"戧"=>"戗",
+"戩"=>"戬",
+"戰"=>"战",
+"戱"=>"戯",
+"戲"=>"戏",
+"戶"=>"户",
+"担"=>"担",
+"拋"=>"抛",
+"拾"=>"十",
+"挩"=>"捝",
+"挾"=>"挟",
+"捨"=>"舍",
+"捫"=>"扪",
+"据"=>"据",
+"掃"=>"扫",
+"掄"=>"抡",
+"掗"=>"挜",
+"掙"=>"挣",
+"掛"=>"挂",
+"採"=>"采",
+"揀"=>"拣",
+"揚"=>"扬",
+"換"=>"换",
+"揮"=>"挥",
+"損"=>"损",
+"搖"=>"摇",
+"搗"=>"捣",
+"搵"=>"揾",
+"搶"=>"抢",
+"摑"=>"掴",
+"摜"=>"掼",
+"摟"=>"搂",
+"摯"=>"挚",
+"摳"=>"抠",
+"摶"=>"抟",
+"摺"=>"折",
+"摻"=>"掺",
+"撈"=>"捞",
+"撏"=>"挦",
+"撐"=>"撑",
+"撓"=>"挠",
+"撝"=>"㧑",
+"撟"=>"挢",
+"撣"=>"掸",
+"撥"=>"拨",
+"撫"=>"抚",
+"撲"=>"扑",
+"撳"=>"揿",
+"撻"=>"挞",
+"撾"=>"挝",
+"撿"=>"捡",
+"擁"=>"拥",
+"擄"=>"掳",
+"擇"=>"择",
+"擊"=>"击",
+"擋"=>"挡",
+"擓"=>"㧟",
+"擔"=>"担",
+"據"=>"据",
+"擠"=>"挤",
+"擬"=>"拟",
+"擯"=>"摈",
+"擰"=>"拧",
+"擱"=>"搁",
+"擲"=>"掷",
+"擴"=>"扩",
+"擷"=>"撷",
+"擺"=>"摆",
+"擻"=>"擞",
+"擼"=>"撸",
+"擾"=>"扰",
+"攄"=>"摅",
+"攆"=>"撵",
+"攏"=>"拢",
+"攔"=>"拦",
+"攖"=>"撄",
+"攙"=>"搀",
+"攛"=>"撺",
+"攜"=>"携",
+"攝"=>"摄",
+"攢"=>"攒",
+"攣"=>"挛",
+"攤"=>"摊",
+"攪"=>"搅",
+"攬"=>"揽",
+"敗"=>"败",
+"敘"=>"叙",
+"敵"=>"敌",
+"數"=>"数",
+"斂"=>"敛",
+"斃"=>"毙",
+"斕"=>"斓",
+"斗"=>"斗",
+"斬"=>"斩",
+"斷"=>"断",
+"於"=>"于",
+"時"=>"时",
+"晉"=>"晋",
+"晝"=>"昼",
+"暈"=>"晕",
+"暉"=>"晖",
+"暘"=>"旸",
+"暢"=>"畅",
+"暫"=>"暂",
+"曄"=>"晔",
+"曆"=>"历",
+"曇"=>"昙",
+"曉"=>"晓",
+"曏"=>"向",
+"曖"=>"暧",
+"曠"=>"旷",
+"曨"=>"昽",
+"曬"=>"晒",
+"書"=>"书",
+"會"=>"会",
+"朧"=>"胧",
+"朮"=>"术",
+"术"=>"术",
+"朴"=>"朴",
+"東"=>"东",
+"杴"=>"锨",
+"极"=>"极",
+"柜"=>"柜",
+"柵"=>"栅",
+"桿"=>"杆",
+"梔"=>"栀",
+"梘"=>"枧",
+"條"=>"条",
+"梟"=>"枭",
+"梲"=>"棁",
+"棄"=>"弃",
+"棖"=>"枨",
+"棗"=>"枣",
+"棟"=>"栋",
+"棧"=>"栈",
+"棲"=>"栖",
+"棶"=>"梾",
+"椏"=>"桠",
+"楊"=>"杨",
+"楓"=>"枫",
+"楨"=>"桢",
+"業"=>"业",
+"極"=>"极",
+"榪"=>"杩",
+"榮"=>"荣",
+"榲"=>"榅",
+"榿"=>"桤",
+"構"=>"构",
+"槍"=>"枪",
+"槤"=>"梿",
+"槧"=>"椠",
+"槨"=>"椁",
+"槳"=>"桨",
+"樁"=>"桩",
+"樂"=>"乐",
+"樅"=>"枞",
+"樓"=>"楼",
+"標"=>"标",
+"樞"=>"枢",
+"樣"=>"样",
+"樸"=>"朴",
+"樹"=>"树",
+"樺"=>"桦",
+"橈"=>"桡",
+"橋"=>"桥",
+"機"=>"机",
+"橢"=>"椭",
+"橫"=>"横",
+"檁"=>"檩",
+"檉"=>"柽",
+"檔"=>"档",
+"檜"=>"桧",
+"檟"=>"槚",
+"檢"=>"检",
+"檣"=>"樯",
+"檮"=>"梼",
+"檯"=>"台",
+"檳"=>"槟",
+"檸"=>"柠",
+"檻"=>"槛",
+"櫃"=>"柜",
+"櫓"=>"橹",
+"櫚"=>"榈",
+"櫛"=>"栉",
+"櫝"=>"椟",
+"櫞"=>"橼",
+"櫟"=>"栎",
+"櫥"=>"橱",
+"櫧"=>"槠",
+"櫨"=>"栌",
+"櫪"=>"枥",
+"櫫"=>"橥",
+"櫬"=>"榇",
+"櫱"=>"蘖",
+"櫳"=>"栊",
+"櫸"=>"榉",
+"櫻"=>"樱",
+"欄"=>"栏",
+"權"=>"权",
+"欏"=>"椤",
+"欒"=>"栾",
+"欖"=>"榄",
+"欞"=>"棂",
+"欽"=>"钦",
+"歐"=>"欧",
+"歟"=>"欤",
+"歡"=>"欢",
+"歲"=>"岁",
+"歷"=>"历",
+"歸"=>"归",
+"歿"=>"殁",
+"殘"=>"残",
+"殞"=>"殒",
+"殤"=>"殇",
+"殨"=>"㱮",
+"殫"=>"殚",
+"殮"=>"殓",
+"殯"=>"殡",
+"殲"=>"歼",
+"殺"=>"杀",
+"殻"=>"壳",
+"殼"=>"壳",
+"毀"=>"毁",
+"毆"=>"殴",
+"毿"=>"毵",
+"氂"=>"牦",
+"氈"=>"毡",
+"氌"=>"氇",
+"氣"=>"气",
+"氫"=>"氢",
+"氬"=>"氩",
+"氳"=>"氲",
+"汙"=>"污",
+"決"=>"决",
+"沒"=>"没",
+"沖"=>"冲",
+"況"=>"况",
+"洶"=>"汹",
+"浹"=>"浃",
+"涂"=>"涂",
+"涇"=>"泾",
+"涼"=>"凉",
+"淀"=>"淀",
+"淒"=>"凄",
+"淚"=>"泪",
+"淥"=>"渌",
+"淨"=>"净",
+"淩"=>"凌",
+"淪"=>"沦",
+"淵"=>"渊",
+"淶"=>"涞",
+"淺"=>"浅",
+"渙"=>"涣",
+"減"=>"减",
+"渦"=>"涡",
+"測"=>"测",
+"渾"=>"浑",
+"湊"=>"凑",
+"湞"=>"浈",
+"湯"=>"汤",
+"溈"=>"沩",
+"準"=>"准",
+"溝"=>"沟",
+"溫"=>"温",
+"滄"=>"沧",
+"滅"=>"灭",
+"滌"=>"涤",
+"滎"=>"荥",
+"滬"=>"沪",
+"滯"=>"滞",
+"滲"=>"渗",
+"滷"=>"卤",
+"滸"=>"浒",
+"滻"=>"浐",
+"滾"=>"滚",
+"滿"=>"满",
+"漁"=>"渔",
+"漚"=>"沤",
+"漢"=>"汉",
+"漣"=>"涟",
+"漬"=>"渍",
+"漲"=>"涨",
+"漵"=>"溆",
+"漸"=>"渐",
+"漿"=>"浆",
+"潁"=>"颍",
+"潑"=>"泼",
+"潔"=>"洁",
+"潙"=>"沩",
+"潛"=>"潜",
+"潤"=>"润",
+"潯"=>"浔",
+"潰"=>"溃",
+"潷"=>"滗",
+"潿"=>"涠",
+"澀"=>"涩",
+"澆"=>"浇",
+"澇"=>"涝",
+"澐"=>"沄",
+"澗"=>"涧",
+"澠"=>"渑",
+"澤"=>"泽",
+"澦"=>"滪",
+"澩"=>"泶",
+"澮"=>"浍",
+"澱"=>"淀",
+"濁"=>"浊",
+"濃"=>"浓",
+"濕"=>"湿",
+"濘"=>"泞",
+"濛"=>"蒙",
+"濟"=>"济",
+"濤"=>"涛",
+"濫"=>"滥",
+"濰"=>"潍",
+"濱"=>"滨",
+"濺"=>"溅",
+"濼"=>"泺",
+"濾"=>"滤",
+"瀅"=>"滢",
+"瀆"=>"渎",
+"瀉"=>"泻",
+"瀋"=>"沈",
+"瀏"=>"浏",
+"瀕"=>"濒",
+"瀘"=>"泸",
+"瀝"=>"沥",
+"瀟"=>"潇",
+"瀠"=>"潆",
+"瀦"=>"潴",
+"瀧"=>"泷",
+"瀨"=>"濑",
+"瀰"=>"弥",
+"瀲"=>"潋",
+"瀾"=>"澜",
+"灃"=>"沣",
+"灄"=>"滠",
+"灑"=>"洒",
+"灕"=>"漓",
+"灘"=>"滩",
+"灝"=>"灏",
+"灠"=>"漤",
+"灣"=>"湾",
+"灤"=>"滦",
+"灧"=>"滟",
+"災"=>"灾",
+"為"=>"为",
+"烏"=>"乌",
+"烴"=>"烃",
+"無"=>"无",
+"煉"=>"炼",
+"煒"=>"炜",
+"煙"=>"烟",
+"煢"=>"茕",
+"煥"=>"焕",
+"煩"=>"烦",
+"煬"=>"炀",
+"熅"=>"煴",
+"熒"=>"荧",
+"熗"=>"炝",
+"熱"=>"热",
+"熲"=>"颎",
+"熾"=>"炽",
+"燁"=>"烨",
+"燈"=>"灯",
+"燉"=>"炖",
+"燒"=>"烧",
+"燙"=>"烫",
+"燜"=>"焖",
+"營"=>"营",
+"燦"=>"灿",
+"燭"=>"烛",
+"燴"=>"烩",
+"燼"=>"烬",
+"燾"=>"焘",
+"爍"=>"烁",
+"爐"=>"炉",
+"爛"=>"烂",
+"爭"=>"争",
+"爲"=>"为",
+"爺"=>"爷",
+"爾"=>"尔",
+"牆"=>"墙",
+"牘"=>"牍",
+"牽"=>"牵",
+"犖"=>"荦",
+"犢"=>"犊",
+"犧"=>"牺",
+"狀"=>"状",
+"狹"=>"狭",
+"狽"=>"狈",
+"猙"=>"狰",
+"猶"=>"犹",
+"猻"=>"狲",
+"獁"=>"犸",
+"獄"=>"狱",
+"獅"=>"狮",
+"獎"=>"奖",
+"獨"=>"独",
+"獪"=>"狯",
+"獫"=>"猃",
+"獮"=>"狝",
+"獰"=>"狞",
+"獲"=>"获",
+"獵"=>"猎",
+"獷"=>"犷",
+"獸"=>"兽",
+"獺"=>"獭",
+"獻"=>"献",
+"獼"=>"猕",
+"玀"=>"猡",
+"現"=>"现",
+"琺"=>"珐",
+"琿"=>"珲",
+"瑋"=>"玮",
+"瑒"=>"玚",
+"瑣"=>"琐",
+"瑤"=>"瑶",
+"瑩"=>"莹",
+"瑪"=>"玛",
+"瑲"=>"玱",
+"璉"=>"琏",
+"璣"=>"玑",
+"璦"=>"瑷",
+"璫"=>"珰",
+"環"=>"环",
+"璽"=>"玺",
+"瓊"=>"琼",
+"瓏"=>"珑",
+"瓔"=>"璎",
+"瓚"=>"瓒",
+"甌"=>"瓯",
+"產"=>"产",
+"産"=>"产",
+"畝"=>"亩",
+"畢"=>"毕",
+"異"=>"异",
+"畵"=>"画",
+"當"=>"当",
+"疇"=>"畴",
+"疊"=>"叠",
+"痙"=>"痉",
+"痾"=>"疴",
+"瘂"=>"痖",
+"瘋"=>"疯",
+"瘍"=>"疡",
+"瘓"=>"痪",
+"瘞"=>"瘗",
+"瘡"=>"疮",
+"瘧"=>"疟",
+"瘮"=>"瘆",
+"瘲"=>"疭",
+"瘺"=>"瘘",
+"瘻"=>"瘘",
+"療"=>"疗",
+"癆"=>"痨",
+"癇"=>"痫",
+"癉"=>"瘅",
+"癘"=>"疠",
+"癟"=>"瘪",
+"癢"=>"痒",
+"癤"=>"疖",
+"癥"=>"症",
+"癧"=>"疬",
+"癩"=>"癞",
+"癬"=>"癣",
+"癭"=>"瘿",
+"癮"=>"瘾",
+"癰"=>"痈",
+"癱"=>"瘫",
+"癲"=>"癫",
+"發"=>"发",
+"皚"=>"皑",
+"皰"=>"疱",
+"皸"=>"皲",
+"皺"=>"皱",
+"盃"=>"杯",
+"盜"=>"盗",
+"盞"=>"盏",
+"盡"=>"尽",
+"監"=>"监",
+"盤"=>"盘",
+"盧"=>"卢",
+"眥"=>"眦",
+"眾"=>"众",
+"睏"=>"困",
+"睜"=>"睁",
+"睞"=>"睐",
+"瞘"=>"眍",
+"瞜"=>"䁖",
+"瞞"=>"瞒",
+"瞭"=>"了",
+"瞶"=>"瞆",
+"瞼"=>"睑",
+"矇"=>"蒙",
+"矓"=>"眬",
+"矚"=>"瞩",
+"矯"=>"矫",
+"硃"=>"朱",
+"硜"=>"硁",
+"硤"=>"硖",
+"硨"=>"砗",
+"确"=>"确",
+"硯"=>"砚",
+"碩"=>"硕",
+"碭"=>"砀",
+"碸"=>"砜",
+"確"=>"确",
+"碼"=>"码",
+"磑"=>"硙",
+"磚"=>"砖",
+"磣"=>"碜",
+"磧"=>"碛",
+"磯"=>"矶",
+"磽"=>"硗",
+"礆"=>"硷",
+"礎"=>"础",
+"礙"=>"碍",
+"礦"=>"矿",
+"礪"=>"砺",
+"礫"=>"砾",
+"礬"=>"矾",
+"礱"=>"砻",
+"祿"=>"禄",
+"禍"=>"祸",
+"禎"=>"祯",
+"禕"=>"祎",
+"禡"=>"祃",
+"禦"=>"御",
+"禪"=>"禅",
+"禮"=>"礼",
+"禰"=>"祢",
+"禱"=>"祷",
+"禿"=>"秃",
+"秈"=>"籼",
+"种"=>"种",
+"稅"=>"税",
+"稈"=>"秆",
+"稟"=>"禀",
+"種"=>"种",
+"稱"=>"称",
+"穀"=>"谷",
+"穌"=>"稣",
+"積"=>"积",
+"穎"=>"颖",
+"穠"=>"秾",
+"穡"=>"穑",
+"穢"=>"秽",
+"穩"=>"稳",
+"穫"=>"获",
+"穭"=>"稆",
+"窩"=>"窝",
+"窪"=>"洼",
+"窮"=>"穷",
+"窯"=>"窑",
+"窵"=>"窎",
+"窶"=>"窭",
+"窺"=>"窥",
+"竄"=>"窜",
+"竅"=>"窍",
+"竇"=>"窦",
+"竈"=>"灶",
+"竊"=>"窃",
+"竪"=>"竖",
+"競"=>"竞",
+"筆"=>"笔",
+"筍"=>"笋",
+"筑"=>"筑",
+"筧"=>"笕",
+"筴"=>"䇲",
+"箋"=>"笺",
+"箏"=>"筝",
+"節"=>"节",
+"範"=>"范",
+"築"=>"筑",
+"篋"=>"箧",
+"篔"=>"筼",
+"篤"=>"笃",
+"篩"=>"筛",
+"篳"=>"筚",
+"簀"=>"箦",
+"簍"=>"篓",
+"簞"=>"箪",
+"簡"=>"简",
+"簣"=>"篑",
+"簫"=>"箫",
+"簹"=>"筜",
+"簽"=>"签",
+"簾"=>"帘",
+"籃"=>"篮",
+"籌"=>"筹",
+"籖"=>"签",
+"籙"=>"箓",
+"籜"=>"箨",
+"籟"=>"籁",
+"籠"=>"笼",
+"籩"=>"笾",
+"籪"=>"簖",
+"籬"=>"篱",
+"籮"=>"箩",
+"籲"=>"吁",
+"粵"=>"粤",
+"糝"=>"糁",
+"糞"=>"粪",
+"糧"=>"粮",
+"糰"=>"团",
+"糲"=>"粝",
+"糴"=>"籴",
+"糶"=>"粜",
+"糹"=>"纟",
+"糾"=>"纠",
+"紀"=>"纪",
+"紂"=>"纣",
+"約"=>"约",
+"紅"=>"红",
+"紆"=>"纡",
+"紇"=>"纥",
+"紈"=>"纨",
+"紉"=>"纫",
+"紋"=>"纹",
+"納"=>"纳",
+"紐"=>"纽",
+"紓"=>"纾",
+"純"=>"纯",
+"紕"=>"纰",
+"紖"=>"纼",
+"紗"=>"纱",
+"紘"=>"纮",
+"紙"=>"纸",
+"級"=>"级",
+"紛"=>"纷",
+"紜"=>"纭",
+"紝"=>"纴",
+"紡"=>"纺",
+"紬"=>"䌷",
+"細"=>"细",
+"紱"=>"绂",
+"紲"=>"绁",
+"紳"=>"绅",
+"紵"=>"纻",
+"紹"=>"绍",
+"紺"=>"绀",
+"紼"=>"绋",
+"紿"=>"绐",
+"絀"=>"绌",
+"終"=>"终",
+"組"=>"组",
+"絅"=>"䌹",
+"絆"=>"绊",
+"絎"=>"绗",
+"結"=>"结",
+"絕"=>"绝",
+"絛"=>"绦",
+"絝"=>"绔",
+"絞"=>"绞",
+"絡"=>"络",
+"絢"=>"绚",
+"給"=>"给",
+"絨"=>"绒",
+"絰"=>"绖",
+"統"=>"统",
+"絲"=>"丝",
+"絳"=>"绛",
+"絶"=>"绝",
+"絹"=>"绢",
+"綁"=>"绑",
+"綃"=>"绡",
+"綆"=>"绠",
+"綈"=>"绨",
+"綉"=>"绣",
+"綌"=>"绤",
+"綏"=>"绥",
+"經"=>"经",
+"綜"=>"综",
+"綞"=>"缍",
+"綠"=>"绿",
+"綢"=>"绸",
+"綣"=>"绻",
+"綫"=>"线",
+"綬"=>"绶",
+"維"=>"维",
+"綯"=>"绹",
+"綰"=>"绾",
+"綱"=>"纲",
+"網"=>"网",
+"綳"=>"绷",
+"綴"=>"缀",
+"綸"=>"纶",
+"綹"=>"绺",
+"綺"=>"绮",
+"綻"=>"绽",
+"綽"=>"绰",
+"綾"=>"绫",
+"綿"=>"绵",
+"緄"=>"绲",
+"緇"=>"缁",
+"緊"=>"紧",
+"緋"=>"绯",
+"緑"=>"绿",
+"緒"=>"绪",
+"緓"=>"绬",
+"緔"=>"绱",
+"緗"=>"缃",
+"緘"=>"缄",
+"緙"=>"缂",
+"線"=>"线",
+"緝"=>"缉",
+"緞"=>"缎",
+"締"=>"缔",
+"緡"=>"缗",
+"緣"=>"缘",
+"緦"=>"缌",
+"編"=>"编",
+"緩"=>"缓",
+"緬"=>"缅",
+"緯"=>"纬",
+"緱"=>"缑",
+"緲"=>"缈",
+"練"=>"练",
+"緶"=>"缏",
+"緹"=>"缇",
+"緻"=>"致",
+"縈"=>"萦",
+"縉"=>"缙",
+"縊"=>"缢",
+"縋"=>"缒",
+"縐"=>"绉",
+"縑"=>"缣",
+"縕"=>"缊",
+"縗"=>"缞",
+"縛"=>"缚",
+"縝"=>"缜",
+"縞"=>"缟",
+"縟"=>"缛",
+"縣"=>"县",
+"縧"=>"绦",
+"縫"=>"缝",
+"縭"=>"缡",
+"縮"=>"缩",
+"縱"=>"纵",
+"縲"=>"缧",
+"縳"=>"䌸",
+"縴"=>"纤",
+"縵"=>"缦",
+"縶"=>"絷",
+"縷"=>"缕",
+"縹"=>"缥",
+"總"=>"总",
+"績"=>"绩",
+"繃"=>"绷",
+"繅"=>"缫",
+"繆"=>"缪",
+"繒"=>"缯",
+"織"=>"织",
+"繕"=>"缮",
+"繚"=>"缭",
+"繞"=>"绕",
+"繡"=>"绣",
+"繢"=>"缋",
+"繩"=>"绳",
+"繪"=>"绘",
+"繫"=>"系",
+"繭"=>"茧",
+"繮"=>"缰",
+"繯"=>"缳",
+"繰"=>"缲",
+"繳"=>"缴",
+"繸"=>"䍁",
+"繹"=>"绎",
+"繼"=>"继",
+"繽"=>"缤",
+"繾"=>"缱",
+"纈"=>"缬",
+"纊"=>"纩",
+"續"=>"续",
+"纍"=>"累",
+"纏"=>"缠",
+"纓"=>"缨",
+"纔"=>"才",
+"纖"=>"纤",
+"纘"=>"缵",
+"纜"=>"缆",
+"缽"=>"钵",
+"罈"=>"坛",
+"罌"=>"罂",
+"罰"=>"罚",
+"罵"=>"骂",
+"罷"=>"罢",
+"羅"=>"罗",
+"羆"=>"罴",
+"羈"=>"羁",
+"羋"=>"芈",
+"羥"=>"羟",
+"義"=>"义",
+"習"=>"习",
+"翹"=>"翘",
+"耬"=>"耧",
+"耮"=>"耢",
+"聖"=>"圣",
+"聞"=>"闻",
+"聯"=>"联",
+"聰"=>"聪",
+"聲"=>"声",
+"聳"=>"耸",
+"聵"=>"聩",
+"聶"=>"聂",
+"職"=>"职",
+"聹"=>"聍",
+"聽"=>"听",
+"聾"=>"聋",
+"肅"=>"肃",
+"胜"=>"胜",
+"脅"=>"胁",
+"脈"=>"脉",
+"脛"=>"胫",
+"脫"=>"脱",
+"脹"=>"胀",
+"腊"=>"腊",
+"腎"=>"肾",
+"腖"=>"胨",
+"腡"=>"脶",
+"腦"=>"脑",
+"腫"=>"肿",
+"腳"=>"脚",
+"腸"=>"肠",
+"膃"=>"腽",
+"膚"=>"肤",
+"膠"=>"胶",
+"膩"=>"腻",
+"膽"=>"胆",
+"膾"=>"脍",
+"膿"=>"脓",
+"臉"=>"脸",
+"臍"=>"脐",
+"臏"=>"膑",
+"臘"=>"腊",
+"臚"=>"胪",
+"臟"=>"脏",
+"臠"=>"脔",
+"臢"=>"臜",
+"臥"=>"卧",
+"臨"=>"临",
+"臺"=>"台",
+"與"=>"与",
+"興"=>"兴",
+"舉"=>"举",
+"舊"=>"旧",
+"艙"=>"舱",
+"艤"=>"舣",
+"艦"=>"舰",
+"艫"=>"舻",
+"艱"=>"艰",
+"艷"=>"艳",
+"芻"=>"刍",
+"苎"=>"苧",
+"苧"=>"苎",
+"苹"=>"苹",
+"范"=>"范",
+"茲"=>"兹",
+"荊"=>"荆",
+"莊"=>"庄",
+"莖"=>"茎",
+"莢"=>"荚",
+"莧"=>"苋",
+"華"=>"华",
+"萇"=>"苌",
+"萊"=>"莱",
+"萬"=>"万",
+"萵"=>"莴",
+"葉"=>"叶",
+"葒"=>"荭",
+"著"=>"着",
+"葤"=>"荮",
+"葦"=>"苇",
+"葯"=>"药",
+"葷"=>"荤",
+"蒓"=>"莼",
+"蒔"=>"莳",
+"蒞"=>"莅",
+"蒼"=>"苍",
+"蓀"=>"荪",
+"蓋"=>"盖",
+"蓮"=>"莲",
+"蓯"=>"苁",
+"蓴"=>"莼",
+"蓽"=>"荜",
+"蔔"=>"卜",
+"蔞"=>"蒌",
+"蔣"=>"蒋",
+"蔥"=>"葱",
+"蔦"=>"茑",
+"蔭"=>"荫",
+"蕁"=>"荨",
+"蕆"=>"蒇",
+"蕎"=>"荞",
+"蕒"=>"荬",
+"蕓"=>"芸",
+"蕕"=>"莸",
+"蕘"=>"荛",
+"蕢"=>"蒉",
+"蕩"=>"荡",
+"蕪"=>"芜",
+"蕭"=>"萧",
+"蕷"=>"蓣",
+"薀"=>"蕰",
+"薈"=>"荟",
+"薊"=>"蓟",
+"薌"=>"芗",
+"薔"=>"蔷",
+"薘"=>"荙",
+"薟"=>"莶",
+"薦"=>"荐",
+"薩"=>"萨",
+"薴"=>"苧",
+"薺"=>"荠",
+"藉"=>"借",
+"藍"=>"蓝",
+"藎"=>"荩",
+"藝"=>"艺",
+"藥"=>"药",
+"藪"=>"薮",
+"藴"=>"蕴",
+"藶"=>"苈",
+"藹"=>"蔼",
+"藺"=>"蔺",
+"蘄"=>"蕲",
+"蘆"=>"芦",
+"蘇"=>"苏",
+"蘊"=>"蕴",
+"蘋"=>"苹",
+"蘚"=>"藓",
+"蘞"=>"蔹",
+"蘢"=>"茏",
+"蘭"=>"兰",
+"蘺"=>"蓠",
+"蘿"=>"萝",
+"虆"=>"蔂",
+"處"=>"处",
+"虛"=>"虚",
+"虜"=>"虏",
+"號"=>"号",
+"虧"=>"亏",
+"虫"=>"虫",
+"虯"=>"虬",
+"蛺"=>"蛱",
+"蛻"=>"蜕",
+"蜆"=>"蚬",
+"蜡"=>"蜡",
+"蝕"=>"蚀",
+"蝟"=>"猬",
+"蝦"=>"虾",
+"蝸"=>"蜗",
+"螄"=>"蛳",
+"螞"=>"蚂",
+"螢"=>"萤",
+"螻"=>"蝼",
+"螿"=>"螀",
+"蟄"=>"蛰",
+"蟈"=>"蝈",
+"蟎"=>"螨",
+"蟣"=>"虮",
+"蟬"=>"蝉",
+"蟯"=>"蛲",
+"蟲"=>"虫",
+"蟶"=>"蛏",
+"蟻"=>"蚁",
+"蠅"=>"蝇",
+"蠆"=>"虿",
+"蠐"=>"蛴",
+"蠑"=>"蝾",
+"蠟"=>"蜡",
+"蠣"=>"蛎",
+"蠨"=>"蟏",
+"蠱"=>"蛊",
+"蠶"=>"蚕",
+"蠻"=>"蛮",
+"衆"=>"众",
+"衊"=>"蔑",
+"術"=>"术",
+"衕"=>"同",
+"衚"=>"胡",
+"衛"=>"卫",
+"衝"=>"冲",
+"衹"=>"只",
+"袞"=>"衮",
+"裊"=>"袅",
+"裏"=>"里",
+"補"=>"补",
+"裝"=>"装",
+"裡"=>"里",
+"製"=>"制",
+"複"=>"复",
+"褌"=>"裈",
+"褘"=>"袆",
+"褲"=>"裤",
+"褳"=>"裢",
+"褸"=>"褛",
+"褻"=>"亵",
+"襇"=>"裥",
+"襏"=>"袯",
+"襖"=>"袄",
+"襝"=>"裣",
+"襠"=>"裆",
+"襤"=>"褴",
+"襪"=>"袜",
+"襯"=>"衬",
+"襲"=>"袭",
+"覆"=>"复",
+"見"=>"见",
+"覎"=>"觃",
+"規"=>"规",
+"覓"=>"觅",
+"視"=>"视",
+"覘"=>"觇",
+"覡"=>"觋",
+"覥"=>"觍",
+"覦"=>"觎",
+"親"=>"亲",
+"覬"=>"觊",
+"覯"=>"觏",
+"覲"=>"觐",
+"覷"=>"觑",
+"覺"=>"觉",
+"覽"=>"览",
+"覿"=>"觌",
+"觀"=>"观",
+"觴"=>"觞",
+"觶"=>"觯",
+"觸"=>"触",
+"訁"=>"讠",
+"訂"=>"订",
+"訃"=>"讣",
+"計"=>"计",
+"訊"=>"讯",
+"訌"=>"讧",
+"討"=>"讨",
+"訐"=>"讦",
+"訒"=>"讱",
+"訓"=>"训",
+"訕"=>"讪",
+"訖"=>"讫",
+"託"=>"讬",
+"記"=>"记",
+"訛"=>"讹",
+"訝"=>"讶",
+"訟"=>"讼",
+"訢"=>"䜣",
+"訣"=>"诀",
+"訥"=>"讷",
+"訩"=>"讻",
+"訪"=>"访",
+"設"=>"设",
+"許"=>"许",
+"訴"=>"诉",
+"訶"=>"诃",
+"診"=>"诊",
+"註"=>"注",
+"詁"=>"诂",
+"詆"=>"诋",
+"詎"=>"讵",
+"詐"=>"诈",
+"詒"=>"诒",
+"詔"=>"诏",
+"評"=>"评",
+"詖"=>"诐",
+"詗"=>"诇",
+"詘"=>"诎",
+"詛"=>"诅",
+"詞"=>"词",
+"詠"=>"咏",
+"詡"=>"诩",
+"詢"=>"询",
+"詣"=>"诣",
+"試"=>"试",
+"詩"=>"诗",
+"詫"=>"诧",
+"詬"=>"诟",
+"詭"=>"诡",
+"詮"=>"诠",
+"詰"=>"诘",
+"話"=>"话",
+"該"=>"该",
+"詳"=>"详",
+"詵"=>"诜",
+"詼"=>"诙",
+"詿"=>"诖",
+"誄"=>"诔",
+"誅"=>"诛",
+"誆"=>"诓",
+"誇"=>"夸",
+"誌"=>"志",
+"認"=>"认",
+"誑"=>"诳",
+"誒"=>"诶",
+"誕"=>"诞",
+"誘"=>"诱",
+"誚"=>"诮",
+"語"=>"语",
+"誠"=>"诚",
+"誡"=>"诫",
+"誣"=>"诬",
+"誤"=>"误",
+"誥"=>"诰",
+"誦"=>"诵",
+"誨"=>"诲",
+"說"=>"说",
+"説"=>"说",
+"誰"=>"谁",
+"課"=>"课",
+"誶"=>"谇",
+"誹"=>"诽",
+"誼"=>"谊",
+"誾"=>"訚",
+"調"=>"调",
+"諂"=>"谄",
+"諄"=>"谆",
+"談"=>"谈",
+"諉"=>"诿",
+"請"=>"请",
+"諍"=>"诤",
+"諏"=>"诹",
+"諑"=>"诼",
+"諒"=>"谅",
+"論"=>"论",
+"諗"=>"谂",
+"諛"=>"谀",
+"諜"=>"谍",
+"諝"=>"谞",
+"諞"=>"谝",
+"諢"=>"诨",
+"諤"=>"谔",
+"諦"=>"谛",
+"諧"=>"谐",
+"諫"=>"谏",
+"諭"=>"谕",
+"諮"=>"谘",
+"諱"=>"讳",
+"諳"=>"谙",
+"諶"=>"谌",
+"諷"=>"讽",
+"諸"=>"诸",
+"諺"=>"谚",
+"諼"=>"谖",
+"諾"=>"诺",
+"謀"=>"谋",
+"謁"=>"谒",
+"謂"=>"谓",
+"謄"=>"誊",
+"謅"=>"诌",
+"謊"=>"谎",
+"謎"=>"谜",
+"謐"=>"谧",
+"謔"=>"谑",
+"謖"=>"谡",
+"謗"=>"谤",
+"謙"=>"谦",
+"謚"=>"谥",
+"講"=>"讲",
+"謝"=>"谢",
+"謠"=>"谣",
+"謡"=>"谣",
+"謨"=>"谟",
+"謫"=>"谪",
+"謬"=>"谬",
+"謭"=>"谫",
+"謳"=>"讴",
+"謹"=>"谨",
+"謾"=>"谩",
+"證"=>"证",
+"譎"=>"谲",
+"譏"=>"讥",
+"譖"=>"谮",
+"識"=>"识",
+"譙"=>"谯",
+"譚"=>"谭",
+"譜"=>"谱",
+"譫"=>"谵",
+"譯"=>"译",
+"議"=>"议",
+"譴"=>"谴",
+"護"=>"护",
+"譸"=>"诪",
+"譽"=>"誉",
+"譾"=>"谫",
+"讀"=>"读",
+"變"=>"变",
+"讎"=>"仇",
+"讎"=>"雠",
+"讒"=>"谗",
+"讓"=>"让",
+"讕"=>"谰",
+"讖"=>"谶",
+"讜"=>"谠",
+"讞"=>"谳",
+"豈"=>"岂",
+"豎"=>"竖",
+"豐"=>"丰",
+"豬"=>"猪",
+"豶"=>"豮",
+"貓"=>"猫",
+"貝"=>"贝",
+"貞"=>"贞",
+"貟"=>"贠",
+"負"=>"负",
+"財"=>"财",
+"貢"=>"贡",
+"貧"=>"贫",
+"貨"=>"货",
+"販"=>"贩",
+"貪"=>"贪",
+"貫"=>"贯",
+"責"=>"责",
+"貯"=>"贮",
+"貰"=>"贳",
+"貲"=>"赀",
+"貳"=>"贰",
+"貴"=>"贵",
+"貶"=>"贬",
+"買"=>"买",
+"貸"=>"贷",
+"貺"=>"贶",
+"費"=>"费",
+"貼"=>"贴",
+"貽"=>"贻",
+"貿"=>"贸",
+"賀"=>"贺",
+"賁"=>"贲",
+"賂"=>"赂",
+"賃"=>"赁",
+"賄"=>"贿",
+"賅"=>"赅",
+"資"=>"资",
+"賈"=>"贾",
+"賊"=>"贼",
+"賑"=>"赈",
+"賒"=>"赊",
+"賓"=>"宾",
+"賕"=>"赇",
+"賙"=>"赒",
+"賚"=>"赉",
+"賜"=>"赐",
+"賞"=>"赏",
+"賠"=>"赔",
+"賡"=>"赓",
+"賢"=>"贤",
+"賣"=>"卖",
+"賤"=>"贱",
+"賦"=>"赋",
+"賧"=>"赕",
+"質"=>"质",
+"賫"=>"赍",
+"賬"=>"账",
+"賭"=>"赌",
+"賴"=>"赖",
+"賵"=>"赗",
+"賺"=>"赚",
+"賻"=>"赙",
+"購"=>"购",
+"賽"=>"赛",
+"賾"=>"赜",
+"贄"=>"贽",
+"贅"=>"赘",
+"贇"=>"赟",
+"贈"=>"赠",
+"贊"=>"赞",
+"贋"=>"赝",
+"贍"=>"赡",
+"贏"=>"赢",
+"贐"=>"赆",
+"贓"=>"赃",
+"贔"=>"赑",
+"贖"=>"赎",
+"贗"=>"赝",
+"贛"=>"赣",
+"贜"=>"赃",
+"赬"=>"赪",
+"趕"=>"赶",
+"趙"=>"赵",
+"趨"=>"趋",
+"趲"=>"趱",
+"跡"=>"迹",
+"踐"=>"践",
+"踴"=>"踊",
+"蹌"=>"跄",
+"蹕"=>"跸",
+"蹣"=>"蹒",
+"蹤"=>"踪",
+"蹺"=>"跷",
+"躂"=>"跶",
+"躉"=>"趸",
+"躊"=>"踌",
+"躋"=>"跻",
+"躍"=>"跃",
+"躑"=>"踯",
+"躒"=>"跞",
+"躓"=>"踬",
+"躕"=>"蹰",
+"躚"=>"跹",
+"躡"=>"蹑",
+"躥"=>"蹿",
+"躦"=>"躜",
+"躪"=>"躏",
+"軀"=>"躯",
+"車"=>"车",
+"軋"=>"轧",
+"軌"=>"轨",
+"軍"=>"军",
+"軑"=>"轪",
+"軒"=>"轩",
+"軔"=>"轫",
+"軛"=>"轭",
+"軟"=>"软",
+"軤"=>"轷",
+"軫"=>"轸",
+"軲"=>"轱",
+"軸"=>"轴",
+"軹"=>"轵",
+"軺"=>"轺",
+"軻"=>"轲",
+"軼"=>"轶",
+"軾"=>"轼",
+"較"=>"较",
+"輅"=>"辂",
+"輇"=>"辁",
+"輈"=>"辀",
+"載"=>"载",
+"輊"=>"轾",
+"輒"=>"辄",
+"輓"=>"挽",
+"輔"=>"辅",
+"輕"=>"轻",
+"輛"=>"辆",
+"輜"=>"辎",
+"輝"=>"辉",
+"輞"=>"辋",
+"輟"=>"辍",
+"輥"=>"辊",
+"輦"=>"辇",
+"輩"=>"辈",
+"輪"=>"轮",
+"輬"=>"辌",
+"輯"=>"辑",
+"輳"=>"辏",
+"輸"=>"输",
+"輻"=>"辐",
+"輾"=>"辗",
+"輿"=>"舆",
+"轀"=>"辒",
+"轂"=>"毂",
+"轄"=>"辖",
+"轅"=>"辕",
+"轆"=>"辘",
+"轉"=>"转",
+"轍"=>"辙",
+"轎"=>"轿",
+"轔"=>"辚",
+"轟"=>"轰",
+"轡"=>"辔",
+"轢"=>"轹",
+"轤"=>"轳",
+"辟"=>"辟",
+"辦"=>"办",
+"辭"=>"辞",
+"辮"=>"辫",
+"辯"=>"辩",
+"農"=>"农",
+"迴"=>"回",
+"适"=>"适",
+"逕"=>"迳",
+"這"=>"这",
+"連"=>"连",
+"週"=>"周",
+"進"=>"进",
+"遊"=>"游",
+"運"=>"运",
+"過"=>"过",
+"達"=>"达",
+"違"=>"违",
+"遙"=>"遥",
+"遜"=>"逊",
+"遞"=>"递",
+"遠"=>"远",
+"適"=>"适",
+"遲"=>"迟",
+"遷"=>"迁",
+"選"=>"选",
+"遺"=>"遗",
+"遼"=>"辽",
+"邁"=>"迈",
+"還"=>"还",
+"邇"=>"迩",
+"邊"=>"边",
+"邏"=>"逻",
+"邐"=>"逦",
+"郁"=>"郁",
+"郟"=>"郏",
+"郵"=>"邮",
+"鄆"=>"郓",
+"鄉"=>"乡",
+"鄒"=>"邹",
+"鄔"=>"邬",
+"鄖"=>"郧",
+"鄧"=>"邓",
+"鄭"=>"郑",
+"鄰"=>"邻",
+"鄲"=>"郸",
+"鄴"=>"邺",
+"鄶"=>"郐",
+"鄺"=>"邝",
+"酇"=>"酂",
+"酈"=>"郦",
+"醖"=>"酝",
+"醜"=>"丑",
+"醞"=>"酝",
+"醫"=>"医",
+"醬"=>"酱",
+"醱"=>"酦",
+"釀"=>"酿",
+"釁"=>"衅",
+"釃"=>"酾",
+"釅"=>"酽",
+"采"=>"采",
+"釋"=>"释",
+"釐"=>"厘",
+"釒"=>"钅",
+"釓"=>"钆",
+"釔"=>"钇",
+"釕"=>"钌",
+"釗"=>"钊",
+"釘"=>"钉",
+"釙"=>"钋",
+"針"=>"针",
+"釣"=>"钓",
+"釤"=>"钐",
+"釧"=>"钏",
+"釩"=>"钒",
+"釵"=>"钗",
+"釷"=>"钍",
+"釹"=>"钕",
+"釺"=>"钎",
+"鈀"=>"钯",
+"鈁"=>"钫",
+"鈃"=>"钘",
+"鈄"=>"钭",
+"鈈"=>"钚",
+"鈉"=>"钠",
+"鈍"=>"钝",
+"鈎"=>"钩",
+"鈐"=>"钤",
+"鈑"=>"钣",
+"鈒"=>"钑",
+"鈔"=>"钞",
+"鈕"=>"钮",
+"鈞"=>"钧",
+"鈣"=>"钙",
+"鈥"=>"钬",
+"鈦"=>"钛",
+"鈧"=>"钪",
+"鈮"=>"铌",
+"鈰"=>"铈",
+"鈳"=>"钶",
+"鈴"=>"铃",
+"鈷"=>"钴",
+"鈸"=>"钹",
+"鈹"=>"铍",
+"鈺"=>"钰",
+"鈽"=>"钸",
+"鈾"=>"铀",
+"鈿"=>"钿",
+"鉀"=>"钾",
+"鉅"=>"钜",
+"鉈"=>"铊",
+"鉉"=>"铉",
+"鉋"=>"铇",
+"鉍"=>"铋",
+"鉑"=>"铂",
+"鉕"=>"钷",
+"鉗"=>"钳",
+"鉚"=>"铆",
+"鉛"=>"铅",
+"鉞"=>"钺",
+"鉢"=>"钵",
+"鉤"=>"钩",
+"鉦"=>"钲",
+"鉬"=>"钼",
+"鉭"=>"钽",
+"鉶"=>"铏",
+"鉸"=>"铰",
+"鉺"=>"铒",
+"鉻"=>"铬",
+"鉿"=>"铪",
+"銀"=>"银",
+"銃"=>"铳",
+"銅"=>"铜",
+"銍"=>"铚",
+"銑"=>"铣",
+"銓"=>"铨",
+"銖"=>"铢",
+"銘"=>"铭",
+"銚"=>"铫",
+"銛"=>"铦",
+"銜"=>"衔",
+"銠"=>"铑",
+"銣"=>"铷",
+"銥"=>"铱",
+"銦"=>"铟",
+"銨"=>"铵",
+"銩"=>"铥",
+"銪"=>"铕",
+"銫"=>"铯",
+"銬"=>"铐",
+"銱"=>"铞",
+"銳"=>"锐",
+"銷"=>"销",
+"銹"=>"锈",
+"銻"=>"锑",
+"銼"=>"锉",
+"鋁"=>"铝",
+"鋃"=>"锒",
+"鋅"=>"锌",
+"鋇"=>"钡",
+"鋌"=>"铤",
+"鋏"=>"铗",
+"鋒"=>"锋",
+"鋙"=>"铻",
+"鋝"=>"锊",
+"鋟"=>"锓",
+"鋣"=>"铘",
+"鋤"=>"锄",
+"鋥"=>"锃",
+"鋦"=>"锔",
+"鋨"=>"锇",
+"鋩"=>"铓",
+"鋪"=>"铺",
+"鋭"=>"锐",
+"鋮"=>"铖",
+"鋯"=>"锆",
+"鋰"=>"锂",
+"鋱"=>"铽",
+"鋶"=>"锍",
+"鋸"=>"锯",
+"鋼"=>"钢",
+"錁"=>"锞",
+"錄"=>"录",
+"錆"=>"锖",
+"錇"=>"锫",
+"錈"=>"锩",
+"錏"=>"铔",
+"錐"=>"锥",
+"錒"=>"锕",
+"錕"=>"锟",
+"錘"=>"锤",
+"錙"=>"锱",
+"錚"=>"铮",
+"錛"=>"锛",
+"錟"=>"锬",
+"錠"=>"锭",
+"錡"=>"锜",
+"錢"=>"钱",
+"錦"=>"锦",
+"錨"=>"锚",
+"錩"=>"锠",
+"錫"=>"锡",
+"錮"=>"锢",
+"錯"=>"错",
+"録"=>"录",
+"錳"=>"锰",
+"錶"=>"表",
+"錸"=>"铼",
+"鍀"=>"锝",
+"鍁"=>"锨",
+"鍃"=>"锪",
+"鍆"=>"钔",
+"鍇"=>"锴",
+"鍈"=>"锳",
+"鍋"=>"锅",
+"鍍"=>"镀",
+"鍔"=>"锷",
+"鍘"=>"铡",
+"鍚"=>"钖",
+"鍛"=>"锻",
+"鍠"=>"锽",
+"鍤"=>"锸",
+"鍥"=>"锲",
+"鍩"=>"锘",
+"鍬"=>"锹",
+"鍰"=>"锾",
+"鍵"=>"键",
+"鍶"=>"锶",
+"鍺"=>"锗",
+"鍾"=>"钟",
+"鎂"=>"镁",
+"鎄"=>"锿",
+"鎇"=>"镅",
+"鎊"=>"镑",
+"鎔"=>"镕",
+"鎖"=>"锁",
+"鎘"=>"镉",
+"鎛"=>"镈",
+"鎡"=>"镃",
+"鎢"=>"钨",
+"鎣"=>"蓥",
+"鎦"=>"镏",
+"鎧"=>"铠",
+"鎩"=>"铩",
+"鎪"=>"锼",
+"鎬"=>"镐",
+"鎮"=>"镇",
+"鎰"=>"镒",
+"鎲"=>"镋",
+"鎳"=>"镍",
+"鎵"=>"镓",
+"鎸"=>"镌",
+"鎿"=>"镎",
+"鏃"=>"镞",
+"鏇"=>"镟",
+"鏈"=>"链",
+"鏌"=>"镆",
+"鏍"=>"镙",
+"鏐"=>"镠",
+"鏑"=>"镝",
+"鏗"=>"铿",
+"鏘"=>"锵",
+"鏜"=>"镗",
+"鏝"=>"镘",
+"鏞"=>"镛",
+"鏟"=>"铲",
+"鏡"=>"镜",
+"鏢"=>"镖",
+"鏤"=>"镂",
+"鏨"=>"錾",
+"鏰"=>"镚",
+"鏵"=>"铧",
+"鏷"=>"镤",
+"鏹"=>"镪",
+"鏽"=>"锈",
+"鐃"=>"铙",
+"鐋"=>"铴",
+"鐐"=>"镣",
+"鐒"=>"铹",
+"鐓"=>"镦",
+"鐔"=>"镡",
+"鐘"=>"钟",
+"鐙"=>"镫",
+"鐝"=>"镢",
+"鐠"=>"镨",
+"鐦"=>"锎",
+"鐧"=>"锏",
+"鐨"=>"镄",
+"鐫"=>"镌",
+"鐮"=>"镰",
+"鐲"=>"镯",
+"鐳"=>"镭",
+"鐵"=>"铁",
+"鐶"=>"镮",
+"鐸"=>"铎",
+"鐺"=>"铛",
+"鐿"=>"镱",
+"鑄"=>"铸",
+"鑊"=>"镬",
+"鑌"=>"镔",
+"鑒"=>"鉴",
+"鑔"=>"镲",
+"鑕"=>"锧",
+"鑞"=>"镴",
+"鑠"=>"铄",
+"鑣"=>"镳",
+"鑥"=>"镥",
+"鑭"=>"镧",
+"鑰"=>"钥",
+"鑱"=>"镵",
+"鑲"=>"镶",
+"鑷"=>"镊",
+"鑹"=>"镩",
+"鑼"=>"锣",
+"鑽"=>"钻",
+"鑾"=>"銮",
+"鑿"=>"凿",
+"钁"=>"镢",
+"镟"=>"旋",
+"長"=>"长",
+"門"=>"门",
+"閂"=>"闩",
+"閃"=>"闪",
+"閆"=>"闫",
+"閈"=>"闬",
+"閉"=>"闭",
+"開"=>"开",
+"閌"=>"闶",
+"閎"=>"闳",
+"閏"=>"闰",
+"閑"=>"闲",
+"間"=>"间",
+"閔"=>"闵",
+"閘"=>"闸",
+"閡"=>"阂",
+"閣"=>"阁",
+"閤"=>"合",
+"閥"=>"阀",
+"閨"=>"闺",
+"閩"=>"闽",
+"閫"=>"阃",
+"閬"=>"阆",
+"閭"=>"闾",
+"閱"=>"阅",
+"閲"=>"阅",
+"閶"=>"阊",
+"閹"=>"阉",
+"閻"=>"阎",
+"閼"=>"阏",
+"閽"=>"阍",
+"閾"=>"阈",
+"閿"=>"阌",
+"闃"=>"阒",
+"闆"=>"板",
+"闈"=>"闱",
+"闊"=>"阔",
+"闋"=>"阕",
+"闌"=>"阑",
+"闍"=>"阇",
+"闐"=>"阗",
+"闒"=>"阘",
+"闓"=>"闿",
+"闔"=>"阖",
+"闕"=>"阙",
+"闖"=>"闯",
+"關"=>"关",
+"闞"=>"阚",
+"闠"=>"阓",
+"闡"=>"阐",
+"闤"=>"阛",
+"闥"=>"闼",
+"阪"=>"坂",
+"陘"=>"陉",
+"陝"=>"陕",
+"陣"=>"阵",
+"陰"=>"阴",
+"陳"=>"陈",
+"陸"=>"陆",
+"陽"=>"阳",
+"隉"=>"陧",
+"隊"=>"队",
+"階"=>"阶",
+"隕"=>"陨",
+"際"=>"际",
+"隨"=>"随",
+"險"=>"险",
+"隱"=>"隐",
+"隴"=>"陇",
+"隸"=>"隶",
+"隻"=>"只",
+"雋"=>"隽",
+"雖"=>"虽",
+"雙"=>"双",
+"雛"=>"雏",
+"雜"=>"杂",
+"雞"=>"鸡",
+"離"=>"离",
+"難"=>"难",
+"雲"=>"云",
+"電"=>"电",
+"霢"=>"霡",
+"霧"=>"雾",
+"霽"=>"霁",
+"靂"=>"雳",
+"靄"=>"霭",
+"靈"=>"灵",
+"靚"=>"靓",
+"靜"=>"静",
+"靦"=>"腼",
+"靨"=>"靥",
+"鞀"=>"鼗",
+"鞏"=>"巩",
+"鞝"=>"绱",
+"鞦"=>"秋",
+"鞽"=>"鞒",
+"韁"=>"缰",
+"韃"=>"鞑",
+"韆"=>"千",
+"韉"=>"鞯",
+"韋"=>"韦",
+"韌"=>"韧",
+"韍"=>"韨",
+"韓"=>"韩",
+"韙"=>"韪",
+"韜"=>"韬",
+"韞"=>"韫",
+"韻"=>"韵",
+"響"=>"响",
+"頁"=>"页",
+"頂"=>"顶",
+"頃"=>"顷",
+"項"=>"项",
+"順"=>"顺",
+"頇"=>"顸",
+"須"=>"须",
+"頊"=>"顼",
+"頌"=>"颂",
+"頎"=>"颀",
+"頏"=>"颃",
+"預"=>"预",
+"頑"=>"顽",
+"頒"=>"颁",
+"頓"=>"顿",
+"頗"=>"颇",
+"領"=>"领",
+"頜"=>"颌",
+"頡"=>"颉",
+"頤"=>"颐",
+"頦"=>"颏",
+"頭"=>"头",
+"頮"=>"颒",
+"頰"=>"颊",
+"頲"=>"颋",
+"頴"=>"颕",
+"頷"=>"颔",
+"頸"=>"颈",
+"頹"=>"颓",
+"頻"=>"频",
+"頽"=>"颓",
+"顆"=>"颗",
+"題"=>"题",
+"額"=>"额",
+"顎"=>"颚",
+"顏"=>"颜",
+"顒"=>"颙",
+"顓"=>"颛",
+"顔"=>"颜",
+"願"=>"愿",
+"顙"=>"颡",
+"顛"=>"颠",
+"類"=>"类",
+"顢"=>"颟",
+"顥"=>"颢",
+"顧"=>"顾",
+"顫"=>"颤",
+"顬"=>"颥",
+"顯"=>"显",
+"顰"=>"颦",
+"顱"=>"颅",
+"顳"=>"颞",
+"顴"=>"颧",
+"風"=>"风",
+"颭"=>"飐",
+"颮"=>"飑",
+"颯"=>"飒",
+"颱"=>"台",
+"颳"=>"刮",
+"颶"=>"飓",
+"颸"=>"飔",
+"颺"=>"飏",
+"颻"=>"飖",
+"颼"=>"飕",
+"飀"=>"飗",
+"飄"=>"飘",
+"飆"=>"飙",
+"飈"=>"飚",
+"飛"=>"飞",
+"飠"=>"饣",
+"飢"=>"饥",
+"飣"=>"饤",
+"飥"=>"饦",
+"飩"=>"饨",
+"飪"=>"饪",
+"飫"=>"饫",
+"飭"=>"饬",
+"飯"=>"饭",
+"飲"=>"饮",
+"飴"=>"饴",
+"飼"=>"饲",
+"飽"=>"饱",
+"飾"=>"饰",
+"飿"=>"饳",
+"餃"=>"饺",
+"餄"=>"饸",
+"餅"=>"饼",
+"餉"=>"饷",
+"養"=>"养",
+"餌"=>"饵",
+"餎"=>"饹",
+"餏"=>"饻",
+"餑"=>"饽",
+"餒"=>"馁",
+"餓"=>"饿",
+"餕"=>"馂",
+"餖"=>"饾",
+"餚"=>"肴",
+"餛"=>"馄",
+"餜"=>"馃",
+"餞"=>"饯",
+"餡"=>"馅",
+"館"=>"馆",
+"餱"=>"糇",
+"餳"=>"饧",
+"餶"=>"馉",
+"餷"=>"馇",
+"餺"=>"馎",
+"餼"=>"饩",
+"餾"=>"馏",
+"餿"=>"馊",
+"饁"=>"馌",
+"饃"=>"馍",
+"饅"=>"馒",
+"饈"=>"馐",
+"饉"=>"馑",
+"饊"=>"馓",
+"饋"=>"馈",
+"饌"=>"馔",
+"饑"=>"饥",
+"饒"=>"饶",
+"饗"=>"飨",
+"饜"=>"餍",
+"饞"=>"馋",
+"饢"=>"馕",
+"馬"=>"马",
+"馭"=>"驭",
+"馮"=>"冯",
+"馱"=>"驮",
+"馳"=>"驰",
+"馴"=>"驯",
+"馹"=>"驲",
+"駁"=>"驳",
+"駐"=>"驻",
+"駑"=>"驽",
+"駒"=>"驹",
+"駔"=>"驵",
+"駕"=>"驾",
+"駘"=>"骀",
+"駙"=>"驸",
+"駛"=>"驶",
+"駝"=>"驼",
+"駟"=>"驷",
+"駡"=>"骂",
+"駢"=>"骈",
+"駭"=>"骇",
+"駰"=>"骃",
+"駱"=>"骆",
+"駸"=>"骎",
+"駿"=>"骏",
+"騁"=>"骋",
+"騂"=>"骍",
+"騅"=>"骓",
+"騌"=>"骔",
+"騍"=>"骒",
+"騎"=>"骑",
+"騏"=>"骐",
+"騖"=>"骛",
+"騙"=>"骗",
+"騤"=>"骙",
+"騫"=>"骞",
+"騭"=>"骘",
+"騮"=>"骝",
+"騰"=>"腾",
+"騶"=>"驺",
+"騷"=>"骚",
+"騸"=>"骟",
+"騾"=>"骡",
+"驀"=>"蓦",
+"驁"=>"骜",
+"驂"=>"骖",
+"驃"=>"骠",
+"驄"=>"骢",
+"驅"=>"驱",
+"驊"=>"骅",
+"驌"=>"骕",
+"驍"=>"骁",
+"驏"=>"骣",
+"驕"=>"骄",
+"驗"=>"验",
+"驚"=>"惊",
+"驛"=>"驿",
+"驟"=>"骤",
+"驢"=>"驴",
+"驤"=>"骧",
+"驥"=>"骥",
+"驦"=>"骦",
+"驪"=>"骊",
+"驫"=>"骉",
+"骯"=>"肮",
+"髏"=>"髅",
+"髒"=>"脏",
+"體"=>"体",
+"髕"=>"髌",
+"髖"=>"髋",
+"髮"=>"发",
+"鬆"=>"松",
+"鬍"=>"胡",
+"鬚"=>"须",
+"鬢"=>"鬓",
+"鬥"=>"斗",
+"鬧"=>"闹",
+"鬩"=>"阋",
+"鬮"=>"阄",
+"鬱"=>"郁",
+"魎"=>"魉",
+"魘"=>"魇",
+"魚"=>"鱼",
+"魛"=>"鱽",
+"魢"=>"鱾",
+"魨"=>"鲀",
+"魯"=>"鲁",
+"魴"=>"鲂",
+"魷"=>"鱿",
+"魺"=>"鲄",
+"鮁"=>"鲅",
+"鮃"=>"鲆",
+"鮊"=>"鲌",
+"鮋"=>"鲉",
+"鮍"=>"鲏",
+"鮎"=>"鲇",
+"鮐"=>"鲐",
+"鮑"=>"鲍",
+"鮒"=>"鲋",
+"鮓"=>"鲊",
+"鮚"=>"鲒",
+"鮜"=>"鲘",
+"鮝"=>"鲞",
+"鮞"=>"鲕",
+"鮦"=>"鲖",
+"鮪"=>"鲔",
+"鮫"=>"鲛",
+"鮭"=>"鲑",
+"鮮"=>"鲜",
+"鮳"=>"鲓",
+"鮶"=>"鲪",
+"鮺"=>"鲝",
+"鯀"=>"鲧",
+"鯁"=>"鲠",
+"鯇"=>"鲩",
+"鯉"=>"鲤",
+"鯊"=>"鲨",
+"鯒"=>"鲬",
+"鯔"=>"鲻",
+"鯕"=>"鲯",
+"鯖"=>"鲭",
+"鯗"=>"鲞",
+"鯛"=>"鲷",
+"鯝"=>"鲴",
+"鯡"=>"鲱",
+"鯢"=>"鲵",
+"鯤"=>"鲲",
+"鯧"=>"鲳",
+"鯨"=>"鲸",
+"鯪"=>"鲮",
+"鯫"=>"鲰",
+"鯴"=>"鲺",
+"鯷"=>"鳀",
+"鯽"=>"鲫",
+"鯿"=>"鳊",
+"鰁"=>"鳈",
+"鰂"=>"鲗",
+"鰃"=>"鳂",
+"鰈"=>"鲽",
+"鰉"=>"鳇",
+"鰍"=>"鳅",
+"鰏"=>"鲾",
+"鰐"=>"鳄",
+"鰒"=>"鳆",
+"鰓"=>"鳃",
+"鰜"=>"鳒",
+"鰟"=>"鳑",
+"鰠"=>"鳋",
+"鰣"=>"鲥",
+"鰥"=>"鳏",
+"鰨"=>"鳎",
+"鰩"=>"鳐",
+"鰭"=>"鳍",
+"鰮"=>"鳁",
+"鰱"=>"鲢",
+"鰲"=>"鳌",
+"鰳"=>"鳓",
+"鰵"=>"鳘",
+"鰷"=>"鲦",
+"鰹"=>"鲣",
+"鰺"=>"鲹",
+"鰻"=>"鳗",
+"鰼"=>"鳛",
+"鰾"=>"鳔",
+"鱂"=>"鳉",
+"鱅"=>"鳙",
+"鱈"=>"鳕",
+"鱉"=>"鳖",
+"鱒"=>"鳟",
+"鱔"=>"鳝",
+"鱖"=>"鳜",
+"鱗"=>"鳞",
+"鱘"=>"鲟",
+"鱝"=>"鲼",
+"鱟"=>"鲎",
+"鱠"=>"鲙",
+"鱣"=>"鳣",
+"鱤"=>"鳡",
+"鱧"=>"鳢",
+"鱨"=>"鲿",
+"鱭"=>"鲚",
+"鱯"=>"鳠",
+"鱷"=>"鳄",
+"鱸"=>"鲈",
+"鱺"=>"鲡",
+"䰾"=>"鲃",
+"䲁"=>"鳚",
+"鳥"=>"鸟",
+"鳧"=>"凫",
+"鳩"=>"鸠",
+"鳬"=>"凫",
+"鳲"=>"鸤",
+"鳳"=>"凤",
+"鳴"=>"鸣",
+"鳶"=>"鸢",
+"鳾"=>"䴓",
+"鴆"=>"鸩",
+"鴇"=>"鸨",
+"鴉"=>"鸦",
+"鴒"=>"鸰",
+"鴕"=>"鸵",
+"鴛"=>"鸳",
+"鴝"=>"鸲",
+"鴞"=>"鸮",
+"鴟"=>"鸱",
+"鴣"=>"鸪",
+"鴦"=>"鸯",
+"鴨"=>"鸭",
+"鴯"=>"鸸",
+"鴰"=>"鸹",
+"鴴"=>"鸻",
+"鴷"=>"䴕",
+"鴻"=>"鸿",
+"鴿"=>"鸽",
+"鵁"=>"䴔",
+"鵂"=>"鸺",
+"鵃"=>"鸼",
+"鵐"=>"鹀",
+"鵑"=>"鹃",
+"鵒"=>"鹆",
+"鵓"=>"鹁",
+"鵜"=>"鹈",
+"鵝"=>"鹅",
+"鵠"=>"鹄",
+"鵡"=>"鹉",
+"鵪"=>"鹌",
+"鵬"=>"鹏",
+"鵮"=>"鹐",
+"鵯"=>"鹎",
+"鵲"=>"鹊",
+"鵷"=>"鹓",
+"鵾"=>"鹍",
+"鶄"=>"䴖",
+"鶇"=>"鸫",
+"鶉"=>"鹑",
+"鶊"=>"鹒",
+"鶓"=>"鹋",
+"鶖"=>"鹙",
+"鶘"=>"鹕",
+"鶚"=>"鹗",
+"鶡"=>"鹖",
+"鶥"=>"鹛",
+"鶩"=>"鹜",
+"鶪"=>"䴗",
+"鶬"=>"鸧",
+"鶯"=>"莺",
+"鶲"=>"鹟",
+"鶴"=>"鹤",
+"鶹"=>"鹠",
+"鶺"=>"鹡",
+"鶻"=>"鹘",
+"鶼"=>"鹣",
+"鶿"=>"鹚",
+"鷀"=>"鹚",
+"鷁"=>"鹢",
+"鷂"=>"鹞",
+"鷄"=>"鸡",
+"鷈"=>"䴘",
+"鷊"=>"鹝",
+"鷓"=>"鹧",
+"鷖"=>"鹥",
+"鷗"=>"鸥",
+"鷙"=>"鸷",
+"鷚"=>"鹨",
+"鷥"=>"鸶",
+"鷦"=>"鹪",
+"鷫"=>"鹔",
+"鷯"=>"鹩",
+"鷲"=>"鹫",
+"鷳"=>"鹇",
+"鷸"=>"鹬",
+"鷹"=>"鹰",
+"鷺"=>"鹭",
+"鷽"=>"鸴",
+"鷿"=>"䴙",
+"鸇"=>"鹯",
+"鸌"=>"鹱",
+"鸏"=>"鹲",
+"鸕"=>"鸬",
+"鸘"=>"鹴",
+"鸚"=>"鹦",
+"鸛"=>"鹳",
+"鸝"=>"鹂",
+"鸞"=>"鸾",
+"鹵"=>"卤",
+"鹹"=>"咸",
+"鹺"=>"鹾",
+"鹽"=>"盐",
+"麗"=>"丽",
+"麥"=>"麦",
+"麩"=>"麸",
+"麯"=>"曲",
+"麵"=>"面",
+"麼"=>"么",
+"麽"=>"么",
+"黃"=>"黄",
+"黌"=>"黉",
+"點"=>"点",
+"黨"=>"党",
+"黲"=>"黪",
+"黴"=>"霉",
+"黶"=>"黡",
+"黷"=>"黩",
+"黽"=>"黾",
+"黿"=>"鼋",
+"鼉"=>"鼍",
+"鼕"=>"冬",
+"鼴"=>"鼹",
+"齊"=>"齐",
+"齋"=>"斋",
+"齎"=>"赍",
+"齏"=>"齑",
+"齒"=>"齿",
+"齔"=>"龀",
+"齕"=>"龁",
+"齗"=>"龂",
+"齙"=>"龅",
+"齜"=>"龇",
+"齟"=>"龃",
+"齠"=>"龆",
+"齡"=>"龄",
+"齣"=>"出",
+"齦"=>"龈",
+"齪"=>"龊",
+"齬"=>"龉",
+"齲"=>"龋",
+"齶"=>"腭",
+"齷"=>"龌",
+"龍"=>"龙",
+"龎"=>"厐",
+"龐"=>"庞",
+"龔"=>"龚",
+"龕"=>"龛",
+"龜"=>"龟",
+
+"幾畫" => "几画",
+"賣畫" => "卖画",
+"滷鹼" => "卤碱",
+"原畫" => "原画",
+"口鹼" => "口碱",
+"古畫" => "古画",
+"名畫" => "名画",
+"奇畫" => "奇画",
+"如畫" => "如画",
+"么 " => "幺 ",
+"么廝" => "幺厮",
+"么爹" => "幺爹",
+"弱鹼" => "弱碱",
+"彩畫" => "彩画",
+"所畫" => "所画",
+"扉畫" => "扉画",
+"教畫" => "教画",
+"楊么" => "杨幺",
+"水鹼" => "水碱",
+"洋鹼" => "洋碱",
+"炭畫" => "炭画",
+"畫一" => "画一",
+"畫上" => "画上",
+"畫下" => "画下",
+"畫中" => "画中",
+"畫供" => "画供",
+"畫兒" => "画儿",
+"畫具" => "画具",
+"畫出" => "画出",
+"畫史" => "画史",
+"畫品" => "画品",
+"畫商" => "画商",
+"畫圈" => "画圈",
+"畫境" => "画境",
+"畫工" => "画工",
+"畫帖" => "画帖",
+"畫幅" => "画幅",
+"畫意" => "画意",
+"畫成" => "画成",
+"畫景" => "画景",
+"畫本" => "画本",
+"畫架" => "画架",
+"畫框" => "画框",
+"畫法" => "画法",
+"畫王" => "画王",
+"畫界" => "画界",
+"畫符" => "画符",
+"畫紙" => "画纸",
+"畫線" => "画线",
+"畫航" => "画航",
+"畫舫" => "画舫",
+"畫虎" => "画虎",
+"畫論" => "画论",
+"畫譜" => "画谱",
+"畫象" => "画象",
+"畫質" => "画质",
+"畫貼" => "画贴",
+"畫軸" => "画轴",
+"畫頁" => "画页",
+"鹽鹼" => "盐碱",
+"鹼 " => "碱 ",
+"鹼基" => "碱基",
+"鹼度" => "碱度",
+"鹼水" => "碱水",
+"鹼熔" => "碱熔",
+"磁畫" => "磁画",
+"策畫" => "策画",
+"組畫" => "组画",
+"絹畫" => "绢画",
+"老么" => "老幺",
+"耐鹼" => "耐碱",
+"肉鹼" => "肉碱",
+"膠畫" => "胶画",
+"茶鹼" => "茶碱",
+"西畫" => "西画",
+"貼畫" => "贴画",
+"返鹼" => "返碱",
+"那麼" => "那麽",
+"鍾鍛" => "锺锻",
+"鍛鍾" => "锻锺",
+"雕畫" => "雕画",
+"鯰 " => "鲶 ",
+"麼 " => "麽 ",
+"三聯畫" => "三联画",
+"中國畫" => "中国画",
+"書畫 " => "书画 ",
+"書畫社" => "书画社",
+"五筆畫" => "五笔画",
+"作畫 " => "作画 ",
+"入畫 " => "入画 ",
+"寫生畫" => "写生画",
+"刻畫 " => "刻画 ",
+"動畫 " => "动画 ",
+"勾畫 " => "勾画 ",
+"單色畫" => "单色画",
+"卡通畫" => "卡通画",
+"國畫 " => "国画 ",
+"圖畫 " => "图画 ",
+"壁畫 " => "壁画 ",
+"字畫 " => "字画 ",
+"宣傳畫" => "宣传画",
+"工筆畫" => "工笔画",
+"年畫 " => "年画 ",
+"幽默畫" => "幽默画",
+"指畫 " => "指画 ",
+"描畫 " => "描画 ",
+"插畫 " => "插画 ",
+"擘畫 " => "擘画 ",
+"春畫 " => "春画 ",
+"木刻畫" => "木刻画",
+"機械畫" => "机械画",
+"比畫 " => "比画 ",
+"毛筆畫" => "毛笔画",
+"水粉畫" => "水粉画",
+"油畫 " => "油画 ",
+"海景畫" => "海景画",
+"漫畫 " => "漫画 ",
+"點畫 " => "点画 ",
+"版畫 " => "版画 ",
+"畫 " => "画 ",
+"畫像 " => "画像 ",
+"畫冊 " => "画册 ",
+"畫刊 " => "画刊 ",
+"畫匠 " => "画匠 ",
+"畫捲 " => "画卷 ",
+"畫圖 " => "画图 ",
+"畫壇 " => "画坛 ",
+"畫室 " => "画室 ",
+"畫家 " => "画家 ",
+"畫屏 " => "画屏 ",
+"畫展 " => "画展 ",
+"畫布 " => "画布 ",
+"畫師 " => "画师 ",
+"畫廊 " => "画廊 ",
+"畫報 " => "画报 ",
+"畫押 " => "画押 ",
+"畫板 " => "画板 ",
+"畫片 " => "画片 ",
+"畫畫 " => "画画 ",
+"畫皮 " => "画皮 ",
+"畫眉鳥" => "画眉鸟",
+"畫稿 " => "画稿 ",
+"畫筆 " => "画笔 ",
+"畫院 " => "画院 ",
+"畫集 " => "画集 ",
+"畫面 " => "画面 ",
+"筆畫 " => "笔画 ",
+"細密畫" => "细密画",
+"繪畫 " => "绘画 ",
+"自畫像" => "自画像",
+"蠟筆畫" => "蜡笔画",
+"裸體畫" => "裸体画",
+"西洋畫" => "西洋画",
+"透視畫" => "透视画",
+"銅版畫" => "铜版画",
+"鍾 " => "锺 ",
+"靜物畫" => "静物画",
+"餘 " => "馀 ",
+"記憶體"=>"内存",
+"預設"=>"默认",
+"預設"=>"缺省",
+"串列"=>"串行",
+"乙太網"=>"以太网",
+"點陣圖"=>"位图",
+"常式"=>"例程",
+"通道"=>"信道",
+"游標"=>"光标",
+"光碟"=>"光盘",
+"光碟機"=>"光驱",
+"全形"=>"全角",
+"共用"=>"共享",
+"相容"=>"兼容",
+"首碼"=>"前缀",
+"尾碼"=>"后缀",
+"載入"=>"加载",
+"半形"=>"半角",
+"變數"=>"变量",
+"雜訊"=>"噪声",
+"因數"=>"因子",
+"線上"=>"在线",
+"離線"=>"脱机",
+"功能變數名稱"=>"域名",
+"音效卡"=>"声卡",
+"字型大小"=>"字号",
+"字型檔"=>"字库",
+"欄位"=>"字段",
+"字元"=>"字符",
+"存檔"=>"存盘",
+"定址"=>"寻址",
+"章節附註"=>"尾注",
+"非同步"=>"异步",
+"匯流排"=>"总线",
+"括弧"=>"括号",
+"介面"=>"接口",
+"控制項"=>"控件",
+"許可權"=>"权限",
+"碟片"=>"盘片",
+"矽片"=>"硅片",
+"矽谷"=>"硅谷",
+"硬碟"=>"硬盘",
+"磁碟"=>"磁盘",
+"磁軌"=>"磁道",
+"程式控制"=>"程控",
+"埠"=>"端口",
+"運算元"=>"算子",
+"演算法"=>"算法",
+"晶片"=>"芯片",
+"晶元"=>"芯片",
+"片語"=>"词组",
+"解碼"=>"译码",
+"軟碟機"=>"软驱",
+"快閃記憶體"=>"闪存",
+"滑鼠"=>"鼠标",
+"進位"=>"进制",
+"互動式"=>"交互式",
+"模擬"=>"仿真",
+"優先順序"=>"优先级",
+"感測"=>"传感",
+"攜帶型"=>"便携式",
+"資訊理論"=>"信息论",
+"迴圈"=>"循环",
+"防寫"=>"写保护",
+"分散式"=>"分布式",
+"解析度"=>"分辨率",
+"程式"=>"程序",
+"伺服器"=>"服务器",
+"等於"=>"等于",
+"區域網"=>"局域网",
+"上傳"=>"上载",
+"電腦"=>"计算机",
+"巨集"=>"宏",
+"掃瞄器"=>"扫瞄仪",
+"寬頻"=>"宽带",
+"視窗"=>"窗口",
+"資料庫"=>"数据库",
+"西曆"=>"公历",
+"乳酪"=>"奶酪",
+"鉅賈"=>"巨商",
+"手電筒"=>"手电",
+"萬曆"=>"万历",
+"永曆"=>"永历",
+"辭彙"=>"词汇",
+"保全"=>"保安",
+"慣用"=>"习用",
+"母音"=>"元音",
+"自由球"=>"任意球",
+"頭槌"=>"头球",
+"進球"=>"入球",
+"顆進球"=>"粒入球",
+"射門"=>"打门",
+"蓋火鍋"=>"火锅盖帽",
+"印表機"=>"打印机",
+"打印機"=>"打印机",
+"位元組"=>"字节",
+"字節"=>"字节",
+"列印"=>"打印",
+"打印"=>"打印",
+"硬體"=>"硬件",
+"二極體"=>"二极管",
+"二極管"=>"二极管",
+"三極體"=>"三极管",
+"三極管"=>"三极管",
+"數位"=>"数码",
+"數碼"=>"数码",
+"軟體"=>"软件",
+"軟件"=>"软件",
+"網路"=>"网络",
+"網絡"=>"网络",
+"人工智慧"=>"人工智能",
+"太空梭"=>"航天飞机",
+"穿梭機"=>"航天飞机",
+"網際網路"=>"因特网",
+"互聯網"=>"因特网",
+"機械人"=>"机器人",
+"機器人"=>"机器人",
+"行動電話"=>"移动电话",
+"流動電話"=>"移动电话",
+"調制解調器"=>"调制解调器",
+"數據機"=>"调制解调器",
+"短訊"=>"短信",
+"簡訊"=>"短信",
+"烏茲別克"=>"乌兹别克斯坦",
+"查德"=>"乍得",
+"乍得"=>"乍得",
+"也門"=>"",
+"葉門"=>"也门",
+"伯利茲"=>"伯利兹",
+"貝里斯"=>"伯利兹",
+"維德角"=>"佛得角",
+"佛得角"=>"佛得角",
+"克羅地亞"=>"克罗地亚",
+"克羅埃西亞"=>"克罗地亚",
+"岡比亞"=>"冈比亚",
+"甘比亞"=>"冈比亚",
+"幾內亞比紹"=>"几内亚比绍",
+"幾內亞比索"=>"几内亚比绍",
+"列支敦斯登"=>"列支敦士登",
+"列支敦士登"=>"列支敦士登",
+"利比里亞"=>"利比里亚",
+"賴比瑞亞"=>"利比里亚",
+"加納"=>"加纳",
+"迦納"=>"加纳",
+"加彭"=>"加蓬",
+"加蓬"=>"加蓬",
+"博茨瓦納"=>"博茨瓦纳",
+"波札那"=>"博茨瓦纳",
+"卡塔爾"=>"卡塔尔",
+"卡達"=>"卡塔尔",
+"盧旺達"=>"卢旺达",
+"盧安達"=>"卢旺达",
+"危地馬拉"=>"危地马拉",
+"瓜地馬拉"=>"危地马拉",
+"厄瓜多爾"=>"厄瓜多尔",
+"厄瓜多"=>"厄瓜多尔",
+"厄立特里亞"=>"厄立特里亚",
+"厄利垂亞"=>"厄立特里亚",
+"吉布堤"=>"吉布提",
+"吉布地"=>"吉布提",
+"哈薩克"=>"哈萨克斯坦",
+"哥斯達黎加"=>"哥斯达黎加",
+"哥斯大黎加"=>"哥斯达黎加",
+"圖瓦盧"=>"图瓦卢",
+"吐瓦魯"=>"图瓦卢",
+"土庫曼"=>"土库曼斯坦",
+"聖盧西亞"=>"圣卢西亚",
+"聖露西亞"=>"圣卢西亚",
+"聖吉斯納域斯"=>"圣基茨和尼维斯",
+"聖克里斯多福及尼維斯"=>"圣基茨和尼维斯",
+"聖文森特和格林納丁斯"=>"圣文森特和格林纳丁斯",
+"聖文森及格瑞那丁"=>"圣文森特和格林纳丁斯",
+"聖馬力諾"=>"圣马力诺",
+"聖馬利諾"=>"圣马力诺",
+"圭亞那"=>"圭亚那",
+"蓋亞那"=>"圭亚那",
+"坦桑尼亞"=>"坦桑尼亚",
+"坦尚尼亞"=>"坦桑尼亚",
+"埃塞俄比亞"=>"埃塞俄比亚",
+"衣索比亞"=>"埃塞俄比亚",
+"吉里巴斯"=>"基里巴斯",
+"基里巴斯"=>"基里巴斯",
+"塔吉克"=>"塔吉克斯坦",
+"獅子山"=>"塞拉利昂",
+"塞拉利昂"=>"塞拉利昂",
+"塞普勒斯"=>"塞浦路斯",
+"塞浦路斯"=>"塞浦路斯",
+"塞舌爾"=>"塞舌尔",
+"塞席爾"=>"塞舌尔",
+"多明尼加共和國"=>"多米尼加",
+"多明尼加"=>"多米尼加",
+"多明尼加聯邦"=>"多米尼加联邦",
+"多米尼克"=>"多米尼加联邦",
+"安提瓜和巴布達"=>"安提瓜和巴布达",
+"安地卡及巴布達"=>"安提瓜和巴布达",
+"尼日利亞"=>"尼日利亚",
+"奈及利亞"=>"尼日利亚",
+"尼日爾"=>"尼日尔",
+"尼日"=>"尼日尔",
+"巴貝多"=>"巴巴多斯",
+"巴巴多斯"=>"巴巴多斯",
+"巴布亞新畿內亞"=>"巴布亚新几内亚",
+"巴布亞紐幾內亞"=>"巴布亚新几内亚",
+"布基納法索"=>"布基纳法索",
+"布吉納法索"=>"布基纳法索",
+"蒲隆地"=>"布隆迪",
+"布隆迪"=>"布隆迪",
+"希臘"=>"希腊",
+"帛琉"=>"帕劳",
+"義大利"=>"意大利",
+"意大利"=>"意大利",
+"所羅門群島"=>"所罗门群岛",
+"索羅門群島"=>"所罗门群岛",
+"汶萊"=>"文莱",
+"斯威士蘭"=>"斯威士兰",
+"史瓦濟蘭"=>"斯威士兰",
+"斯洛文尼亞"=>"斯洛文尼亚",
+"斯洛維尼亞"=>"斯洛文尼亚",
+"新西蘭"=>"新西兰",
+"紐西蘭"=>"新西兰",
+"北韓"=>"朝鲜",
+"格林納達"=>"格林纳达",
+"格瑞那達"=>"格林纳达",
+"格魯吉亞"=>"格鲁吉亚",
+"喬治亞"=>"格鲁吉亚",
+"梵蒂岡"=>"梵蒂冈",
+"教廷"=>"梵蒂冈",
+"毛里塔尼亞"=>"毛里塔尼亚",
+"茅利塔尼亞"=>"毛里塔尼亚",
+"毛里裘斯"=>"毛里求斯",
+"模里西斯"=>"毛里求斯",
+"沙地阿拉伯"=>"沙特阿拉伯",
+"沙烏地阿拉伯"=>"沙特阿拉伯",
+"波斯尼亞黑塞哥維那"=>"波斯尼亚和黑塞哥维那",
+"波士尼亞赫塞哥維納"=>"波斯尼亚和黑塞哥维那",
+"津巴布韋"=>"津巴布韦",
+"辛巴威"=>"津巴布韦",
+"宏都拉斯"=>"洪都拉斯",
+"洪都拉斯"=>"洪都拉斯",
+"特立尼達和多巴哥"=>"特立尼达和托巴哥",
+"千里達托貝哥"=>"特立尼达和托巴哥",
+"瑙魯"=>"瑙鲁",
+"諾魯"=>"瑙鲁",
+"瓦努阿圖"=>"瓦努阿图",
+"萬那杜"=>"瓦努阿图",
+"溫納圖"=>"瓦努阿图",
+"科摩羅"=>"科摩罗",
+"葛摩"=>"科摩罗",
+"象牙海岸"=>"科特迪瓦",
+"突尼西亞"=>"突尼斯",
+"索馬里"=>"索马里",
+"索馬利亞"=>"索马里",
+"老撾"=>"老挝",
+"寮國"=>"老挝",
+"肯雅"=>"肯尼亚",
+"肯亞"=>"肯尼亚",
+"蘇利南"=>"苏里南",
+"莫三比克"=>"莫桑比克",
+"莫桑比克"=>"莫桑比克",
+"萊索托"=>"莱索托",
+"賴索托"=>"莱索托",
+"貝寧"=>"贝宁",
+"貝南"=>"贝宁",
+"贊比亞"=>"赞比亚",
+"尚比亞"=>"赞比亚",
+"亞塞拜然"=>"阿塞拜疆",
+"阿塞拜疆"=>"阿塞拜疆",
+"阿拉伯聯合酋長國"=>"阿拉伯联合酋长国",
+"阿拉伯聯合大公國"=>"阿拉伯联合酋长国",
+"南韓"=>"韩国",
+"馬爾代夫"=>"马尔代夫",
+"馬爾地夫"=>"马尔代夫",
+"馬爾他"=>"马耳他",
+"馬里"=>"马里",
+"馬利"=>"马里",
+"即食麵"=>"方便面",
+"快速面"=>"方便面",
+"速食麵"=>"方便面",
+"泡麵"=>"方便面",
+"笨豬跳"=>"蹦极跳",
+"绑紧跳"=>"蹦极跳",
+"冷盤  "=>"凉菜",
+"冷菜"=>"凉菜",
+"散钱"=>"零钱",
+"谐星"=>"笑星    ",
+"夜学"=>"夜校",
+"华乐"=>"民乐",
+"中樂"=>"民乐",
+"住屋"=>"住房",
+"屋价"=>"房价",
+"的士"=>"出租车",
+"計程車"=>"出租车",
+"巴士"=>"公共汽车",
+"公車"=>"公共汽车",
+"單車"=>"自行车",
+"節慶"=>"节日",
+"芝士"=>"乾酪",
+"狗隻"=>"犬只",
+"士多啤梨"=>"草莓",
+"忌廉"=>"奶油",
+"桌球"=>"台球",
+"撞球"=>"台球",
+"雪糕"=>"冰淇淋",
+"衞生"=>"卫生",
+"衛生"=>"卫生",
+"賓士"=>"奔驰",
+"平治"=>"奔驰",
+"捷豹"=>"美洲虎",
+"積架"=>"美洲虎",
+"福斯"=>"大众",
+"福士"=>"大众",
+"雪鐵龍"=>"雪铁龙",
+"萬事得"=>"马自达",
+"馬自達"=>"马自达",
+"寶獅"=>"标志",
+"布殊"=>"布什",
+"布希"=>"布什",
+"柯林頓"=>"克林顿",
+"克林頓"=>"克林顿",
+"薩達姆"=>"萨达姆",
+"海珊"=>"萨达姆",
+"梵谷"=>"凡高",
+"大衛碧咸"=>"大卫·贝克汉姆",
+"米高奧雲"=>"迈克尔·欧文",
+"卡佩雅蒂"=>"珍妮弗·卡普里亚蒂",
+"沙芬"=>"马拉特·萨芬",
+"舒麥加"=>"迈克尔·舒马赫",
+"希特拉"=>"希特勒",
+"戴安娜"=>"狄安娜",
+"黛安娜"=>"狄安娜",
+"希拉"=>"赫拉",
+);
+
+$zh2HK=array(
+"打印机" => "打印機",
+"印表機" => "打印機",
+"字节" => "字節",
+"位元組" => "字節",
+"打印" => "打印",
+"列印" => "打印",
+"硬件" => "硬件",
+"硬體" => "硬件",
+"二极管" => "二極管",
+"二極體" => "二極管",
+"三极管" => "三極管",
+"三極體" => "三極管",
+"数码" => "數碼",
+"數位" => "數碼",
+"软件" => "軟件",
+"軟體" => "軟件",
+"网络" => "網絡",
+"網路" => "網絡",
+"人工智能" => "人工智能",
+"人工智慧" => "人工智能",
+"航天飞机" => "穿梭機",
+"太空梭" => "穿梭機",
+"因特网" => "互聯網",
+"網際網路" => "互聯網",
+"机器人" => "機械人",
+"機器人" => "機械人",
+"移动电话" => "流動電話",
+"行動電話" => "流動電話",
+"调制解调器" => "調制解調器",
+"數據機" => "調制解調器",
+"短信" => "短訊",
+"簡訊" => "短訊",
+"乍得" => "乍得",
+"查德" => "乍得",
+"也门" => "也門",
+"葉門" => "也門",
+"伯利兹" => "伯利茲",
+"貝里斯" => "伯利茲",
+"佛得角" => "佛得角",
+"維德角" => "佛得角",
+"克罗地亚" => "克羅地亞",
+"克羅埃西亞" => "克羅地亞",
+"冈比亚" => "岡比亞",
+"甘比亞" => "岡比亞",
+"几内亚比绍" => "幾內亞比紹",
+"幾內亞比索" => "幾內亞比紹",
+"列支敦士登" => "列支敦士登",
+"列支敦斯登" => "列支敦士登",
+"利比里亚" => "利比里亞",
+"賴比瑞亞" => "利比里亞",
+"加纳" => "加納",
+"迦納" => "加納",
+"加蓬" => "加蓬",
+"加彭" => "加蓬",
+"博茨瓦纳" => "博茨瓦納",
+"波札那" => "博茨瓦納",
+"卡塔尔" => "卡塔爾",
+"卡達" => "卡塔爾",
+"卢旺达" => "盧旺達",
+"盧安達" => "盧旺達",
+"危地马拉" => "危地馬拉",
+"瓜地馬拉" => "危地馬拉",
+"厄瓜多尔" => "厄瓜多爾",
+"厄瓜多" => "厄瓜多爾",
+"厄立特里亚" => "厄立特里亞",
+"厄利垂亞" => "厄立特里亞",
+"吉布提" => "吉布堤",
+"吉布地" => "吉布堤",
+"哥斯达黎加" => "哥斯達黎加",
+"哥斯大黎加" => "哥斯達黎加",
+"图瓦卢" => "圖瓦盧",
+"吐瓦魯" => "圖瓦盧",
+"圣卢西亚" => "聖盧西亞",
+"聖露西亞" => "聖盧西亞",
+"圣基茨和尼维斯" => "聖吉斯納域斯",
+"聖克里斯多福及尼維斯" => "聖吉斯納域斯",
+"圣文森特和格林纳丁斯" => "聖文森特和格林納丁斯",
+"聖文森及格瑞那丁" => "聖文森特和格林納丁斯",
+"圣马力诺" => "聖馬力諾",
+"聖馬利諾" => "聖馬力諾",
+"圭亚那" => "圭亞那",
+"蓋亞那" => "圭亞那",
+"坦桑尼亚" => "坦桑尼亞",
+"坦尚尼亞" => "坦桑尼亞",
+"埃塞俄比亚" => "埃塞俄比亞",
+"衣索比亞" => "埃塞俄比亞",
+"基里巴斯" => "基里巴斯",
+"吉里巴斯" => "基里巴斯",
+"獅子山" => "塞拉利昂",
+"塞普勒斯" => "塞浦路斯",
+"塞舌尔" => "塞舌爾",
+"塞席爾" => "塞舌爾",
+"多米尼加" => "多明尼加共和國",
+"多明尼加" => "多明尼加共和國",
+"多米尼加联邦" => "多明尼加聯邦",
+"多米尼克" => "多明尼加聯邦",
+"安提瓜和巴布达" => "安提瓜和巴布達",
+"安地卡及巴布達" => "安提瓜和巴布達",
+"尼日利亚" => "尼日利亞",
+"奈及利亞" => "尼日利亞",
+"尼日尔" => "尼日爾",
+"尼日" => "尼日爾",
+"巴巴多斯" => "巴巴多斯",
+"巴貝多" => "巴巴多斯",
+"巴布亚新几内亚" => "巴布亞新畿內亞",
+"巴布亞紐幾內亞" => "巴布亞新畿內亞",
+"布基纳法索" => "布基納法索",
+"布吉納法索" => "布基納法索",
+"布隆迪" => "布隆迪",
+"蒲隆地" => "布隆迪",
+"義大利" => "意大利",
+"所罗门群岛" => "所羅門群島",
+"索羅門群島" => "所羅門群島",
+"斯威士兰" => "斯威士蘭",
+"史瓦濟蘭" => "斯威士蘭",
+"斯洛文尼亚" => "斯洛文尼亞",
+"斯洛維尼亞" => "斯洛文尼亞",
+"新西兰" => "新西蘭",
+"紐西蘭" => "新西蘭",
+"格林纳达" => "格林納達",
+"格瑞那達" => "格林納達",
+"格鲁吉亚" => "格魯吉亞",
+"喬治亞" => "格魯吉亞",
+"梵蒂冈" => "梵蒂岡",
+"教廷" => "梵蒂岡",
+"毛里塔尼亚" => "毛里塔尼亞",
+"茅利塔尼亞" => "毛里塔尼亞",
+"毛里求斯" => "毛里裘斯",
+"模里西斯" => "毛里裘斯",
+"沙特阿拉伯" => "沙地阿拉伯",
+"沙烏地阿拉伯" => "沙地阿拉伯",
+"波斯尼亚和黑塞哥维那" => "波斯尼亞黑塞哥維那",
+"波士尼亞赫塞哥維納" => "波斯尼亞黑塞哥維那",
+"津巴布韦" => "津巴布韋",
+"辛巴威" => "津巴布韋",
+"洪都拉斯" => "洪都拉斯",
+"宏都拉斯" => "洪都拉斯",
+"特立尼达和托巴哥" => "特立尼達和多巴哥",
+"千里達托貝哥" => "特立尼達和多巴哥",
+"瑙鲁" => "瑙魯",
+"諾魯" => "瑙魯",
+"瓦努阿图" => "瓦努阿圖",
+"萬那杜" => "瓦努阿圖",
+"科摩罗" => "科摩羅",
+"葛摩" => "科摩羅",
+"索马里" => "索馬里",
+"索馬利亞" => "索馬里",
+"老挝" => "老撾",
+"寮國" => "老撾",
+"肯尼亚" => "肯雅",
+"肯亞" => "肯雅",
+"莫桑比克" => "莫桑比克",
+"莫三比克" => "莫桑比克",
+"莱索托" => "萊索托",
+"賴索托" => "萊索托",
+"贝宁" => "貝寧",
+"貝南" => "貝寧",
+"赞比亚" => "贊比亞",
+"尚比亞" => "贊比亞",
+"阿塞拜疆" => "阿塞拜疆",
+"亞塞拜然" => "阿塞拜疆",
+"阿拉伯联合酋长国" => "阿拉伯聯合酋長國",
+"阿拉伯聯合大公國" => "阿拉伯聯合酋長國",
+"马尔代夫" => "馬爾代夫",
+"馬爾地夫" => "馬爾代夫",
+"马里" => "馬里",
+"馬利" => "馬里",
+"方便面" => "即食麵",
+"快速面" => "即食麵",
+"速食麵" => "即食麵",
+"泡麵" => "即食麵",
+"土豆" => "薯仔",
+"华乐" => "中樂",
+"民乐" => "中樂",
+"計程車 " => "的士",
+"出租车" => "的士",
+"公車" => "巴士",
+"公共汽车" => "巴士",
+"自行车" => "單車",
+"节日" => "節慶",
+"犬只" => "狗隻",
+"台球" => "桌球",
+"撞球" => "桌球",
+"冰淇淋" => "雪糕",
+"冰淇淋" => "雪糕",
+"卫生" => "衞生",
+"衛生" => "衞生",
+"老人" => "長者",
+"賓士" => "平治",
+"捷豹" => "積架",
+"福斯" => "福士",
+"雪铁龙" => "先進",
+"雪鐵龍" => "先進",
+"沃尓沃" => "富豪",
+"马自达" => "萬事得",
+"馬自達" => "萬事得",
+"寶獅" => "標致",
+"布什" => "布殊",
+"布希" => "布殊",
+"克林顿" => "克林頓",
+"柯林頓" => "克林頓",
+"萨达姆" => "薩達姆",
+"海珊" => "薩達姆",
+"大卫·贝克汉姆" => "大衛碧咸",
+"迈克尔·欧文" => "米高奧雲",
+"珍妮弗·卡普里亚蒂" => "卡佩雅蒂",
+"马拉特·萨芬" => "沙芬",
+"迈克尔·舒马赫" => "舒麥加",
+"希特勒" => "希特拉",
+"狄安娜" => "戴安娜",
+"黛安娜" => "戴安娜",
+);
+
+$zh2SG=array(
+"方便面" => "快速面",
+"速食麵" => "快速面",
+"即食麵" => "快速面",
+"蹦极跳" => "绑紧跳",
+"笨豬跳" => "绑紧跳",
+"凉菜" => "冷菜",
+"冷盤" => "冷菜",
+"零钱" => "散钱",
+"散紙" => "散钱",
+"笑星" => "谐星",
+"夜校" => "夜学",
+"民乐" => "华乐",
+"住房" => "住屋",
+"房价" => "屋价",
+"泡麵" => "快速面",
+);
+?> \ No newline at end of file
diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php
new file mode 100644
index 000000000000..c2dd93b09c15
--- /dev/null
+++ b/includes/api/ApiBase.php
@@ -0,0 +1,533 @@
+<?php
+
+
+/*
+ * Created on Sep 5, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+abstract class ApiBase {
+
+ // These constants allow modules to specify exactly how to treat incomming parameters.
+
+ const PARAM_DFLT = 0;
+ const PARAM_ISMULTI = 1;
+ const PARAM_TYPE = 2;
+ const PARAM_MAX1 = 3;
+ const PARAM_MAX2 = 4;
+ const PARAM_MIN = 5;
+
+ const LIMIT_BIG1 = 500; // Fast query, user's limit
+ const LIMIT_BIG2 = 5000; // Fast query, bot's limit
+ const LIMIT_SML1 = 50; // Slow query, user's limit
+ const LIMIT_SML2 = 500; // Slow query, bot's limit
+
+ private $mMainModule, $mModuleName, $mParamPrefix;
+
+ /**
+ * Constructor
+ */
+ public function __construct($mainModule, $moduleName, $paramPrefix = '') {
+ $this->mMainModule = $mainModule;
+ $this->mModuleName = $moduleName;
+ $this->mParamPrefix = $paramPrefix;
+ }
+
+ /**
+ * Executes this module
+ */
+ public abstract function execute();
+
+ /**
+ * Get the name of the module being executed by this instance
+ */
+ public function getModuleName() {
+ return $this->mModuleName;
+ }
+
+ /**
+ * Get the name of the module as shown in the profiler log
+ */
+ public function getModuleProfileName($db = false) {
+ if ($db)
+ return 'API:' . $this->mModuleName . '-DB';
+ else
+ return 'API:' . $this->mModuleName;
+ }
+
+ /**
+ * Get main module
+ */
+ public function getMain() {
+ return $this->mMainModule;
+ }
+
+ /**
+ * If this module's $this is the same as $this->mMainModule, its the root, otherwise no
+ */
+ public function isMain() {
+ return $this === $this->mMainModule;
+ }
+
+ /**
+ * Get result object
+ */
+ public function getResult() {
+ // Main module has getResult() method overriden
+ // Safety - avoid infinite loop:
+ if ($this->isMain())
+ ApiBase :: dieDebug(__METHOD__, 'base method was called on main module. ');
+ return $this->getMain()->getResult();
+ }
+
+ /**
+ * Get the result data array
+ */
+ public function & getResultData() {
+ return $this->getResult()->getData();
+ }
+
+ /**
+ * If the module may only be used with a certain format module,
+ * it should override this method to return an instance of that formatter.
+ * A value of null means the default format will be used.
+ */
+ public function getCustomPrinter() {
+ return null;
+ }
+
+ /**
+ * Generates help message for this module, or false if there is no description
+ */
+ public function makeHelpMsg() {
+
+ static $lnPrfx = "\n ";
+
+ $msg = $this->getDescription();
+
+ if ($msg !== false) {
+
+ if (!is_array($msg))
+ $msg = array (
+ $msg
+ );
+ $msg = $lnPrfx . implode($lnPrfx, $msg) . "\n";
+
+ // Parameters
+ $paramsMsg = $this->makeHelpMsgParameters();
+ if ($paramsMsg !== false) {
+ $msg .= "Parameters:\n$paramsMsg";
+ }
+
+ // Examples
+ $examples = $this->getExamples();
+ if ($examples !== false) {
+ if (!is_array($examples))
+ $examples = array (
+ $examples
+ );
+ $msg .= 'Example' . (count($examples) > 1 ? 's' : '') . ":\n ";
+ $msg .= implode($lnPrfx, $examples) . "\n";
+ }
+
+ if ($this->getMain()->getShowVersions()) {
+ $versions = $this->getVersion();
+ $pattern = '(\$.*) ([0-9a-z_]+\.php) (.*\$)';
+ $replacement = '\\0' . "\n " . 'http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/api/\\2';
+
+ if (is_array($versions)) {
+ foreach ($versions as &$v)
+ $v = eregi_replace($pattern, $replacement, $v);
+ $versions = implode("\n ", $versions);
+ }
+ else
+ $versions = eregi_replace($pattern, $replacement, $versions);
+
+ $msg .= "Version:\n $versions\n";
+ }
+ }
+
+ return $msg;
+ }
+
+ public function makeHelpMsgParameters() {
+ $params = $this->getAllowedParams();
+ if ($params !== false) {
+
+ $paramsDescription = $this->getParamDescription();
+ $msg = '';
+ $paramPrefix = "\n" . str_repeat(' ', 19);
+ foreach ($params as $paramName => $paramSettings) {
+ $desc = isset ($paramsDescription[$paramName]) ? $paramsDescription[$paramName] : '';
+ if (is_array($desc))
+ $desc = implode($paramPrefix, $desc);
+
+ @ $type = $paramSettings[self :: PARAM_TYPE];
+ if (isset ($type)) {
+ if (isset ($paramSettings[self :: PARAM_ISMULTI]))
+ $prompt = 'Values (separate with \'|\'): ';
+ else
+ $prompt = 'One value: ';
+
+ if (is_array($type)) {
+ $desc .= $paramPrefix . $prompt . implode(', ', $type);
+ }
+ elseif ($type == 'namespace') {
+ // Special handling because namespaces are type-limited, yet they are not given
+ $desc .= $paramPrefix . $prompt . implode(', ', ApiBase :: getValidNamespaces());
+ }
+ }
+
+ $default = is_array($paramSettings) ? (isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null) : $paramSettings;
+ if (!is_null($default) && $default !== false)
+ $desc .= $paramPrefix . "Default: $default";
+
+ $msg .= sprintf(" %-14s - %s\n", $this->encodeParamName($paramName), $desc);
+ }
+ return $msg;
+
+ } else
+ return false;
+ }
+
+ /**
+ * Returns the description string for this module
+ */
+ protected function getDescription() {
+ return false;
+ }
+
+ /**
+ * Returns usage examples for this module. Return null if no examples are available.
+ */
+ protected function getExamples() {
+ return false;
+ }
+
+ /**
+ * Returns an array of allowed parameters (keys) => default value for that parameter
+ */
+ protected function getAllowedParams() {
+ return false;
+ }
+
+ /**
+ * Returns the description string for the given parameter.
+ */
+ protected function getParamDescription() {
+ return false;
+ }
+
+ /**
+ * This method mangles parameter name based on the prefix supplied to the constructor.
+ * Override this method to change parameter name during runtime
+ */
+ public function encodeParamName($paramName) {
+ return $this->mParamPrefix . $paramName;
+ }
+
+ /**
+ * Using getAllowedParams(), makes an array of the values provided by the user,
+ * with key being the name of the variable, and value - validated value from user or default.
+ * This method can be used to generate local variables using extract().
+ */
+ public function extractRequestParams() {
+ $params = $this->getAllowedParams();
+ $results = array ();
+
+ foreach ($params as $paramName => $paramSettings)
+ $results[$paramName] = $this->getParameterFromSettings($paramName, $paramSettings);
+
+ return $results;
+ }
+
+ /**
+ * Get a value for the given parameter
+ */
+ protected function getParameter($paramName) {
+ $params = $this->getAllowedParams();
+ $paramSettings = $params[$paramName];
+ return $this->getParameterFromSettings($paramName, $paramSettings);
+ }
+
+ public static function getValidNamespaces() {
+ static $mValidNamespaces = null;
+ if (is_null($mValidNamespaces)) {
+
+ global $wgContLang;
+ $mValidNamespaces = array ();
+ foreach (array_keys($wgContLang->getNamespaces()) as $ns) {
+ if ($ns >= 0)
+ $mValidNamespaces[] = $ns;
+ }
+ }
+ return $mValidNamespaces;
+ }
+
+ /**
+ * Using the settings determine the value for the given parameter
+ * @param $paramName String: parameter name
+ * @param $paramSettings Mixed: default value or an array of settings using PARAM_* constants.
+ */
+ protected function getParameterFromSettings($paramName, $paramSettings) {
+
+ // Some classes may decide to change parameter names
+ $paramName = $this->encodeParamName($paramName);
+
+ if (!is_array($paramSettings)) {
+ $default = $paramSettings;
+ $multi = false;
+ $type = gettype($paramSettings);
+ } else {
+ $default = isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null;
+ $multi = isset ($paramSettings[self :: PARAM_ISMULTI]) ? $paramSettings[self :: PARAM_ISMULTI] : false;
+ $type = isset ($paramSettings[self :: PARAM_TYPE]) ? $paramSettings[self :: PARAM_TYPE] : null;
+
+ // When type is not given, and no choices, the type is the same as $default
+ if (!isset ($type)) {
+ if (isset ($default))
+ $type = gettype($default);
+ else
+ $type = 'NULL'; // allow everything
+ }
+ }
+
+ if ($type == 'boolean') {
+ if (isset ($default) && $default !== false) {
+ // Having a default value of anything other than 'false' is pointless
+ ApiBase :: dieDebug(__METHOD__, "Boolean param $paramName's default is set to '$default'");
+ }
+
+ $value = $this->getMain()->getRequest()->getCheck($paramName);
+ } else {
+ $value = $this->getMain()->getRequest()->getVal($paramName, $default);
+
+ if (isset ($value) && $type == 'namespace')
+ $type = ApiBase :: getValidNamespaces();
+ }
+
+ if (isset ($value) && ($multi || is_array($type)))
+ $value = $this->parseMultiValue($paramName, $value, $multi, is_array($type) ? $type : null);
+
+ // More validation only when choices were not given
+ // choices were validated in parseMultiValue()
+ if (isset ($value)) {
+ if (!is_array($type)) {
+ switch ($type) {
+ case 'NULL' : // nothing to do
+ break;
+ case 'string' : // nothing to do
+ break;
+ case 'integer' : // Force everything using intval()
+ $value = is_array($value) ? array_map('intval', $value) : intval($value);
+ break;
+ case 'limit' :
+ if (!isset ($paramSettings[self :: PARAM_MAX1]) || !isset ($paramSettings[self :: PARAM_MAX2]))
+ ApiBase :: dieDebug(__METHOD__, "MAX1 or MAX2 are not defined for the limit $paramName");
+ if ($multi)
+ ApiBase :: dieDebug(__METHOD__, "Multi-values not supported for $paramName");
+ $min = isset ($paramSettings[self :: PARAM_MIN]) ? $paramSettings[self :: PARAM_MIN] : 0;
+ $value = intval($value);
+ $this->validateLimit($paramName, $value, $min, $paramSettings[self :: PARAM_MAX1], $paramSettings[self :: PARAM_MAX2]);
+ break;
+ case 'boolean' :
+ if ($multi)
+ ApiBase :: dieDebug(__METHOD__, "Multi-values not supported for $paramName");
+ break;
+ case 'timestamp' :
+ if ($multi)
+ ApiBase :: dieDebug(__METHOD__, "Multi-values not supported for $paramName");
+ $value = wfTimestamp(TS_UNIX, $value);
+ if ($value === 0)
+ $this->dieUsage("Invalid value '$value' for timestamp parameter $paramName", "badtimestamp_{$paramName}");
+ $value = wfTimestamp(TS_MW, $value);
+ break;
+ default :
+ ApiBase :: dieDebug(__METHOD__, "Param $paramName's type is unknown - $type");
+ }
+ }
+
+ // There should never be any duplicate values in a list
+ if (is_array($value))
+ $value = array_unique($value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Return an array of values that were given in a 'a|b|c' notation,
+ * after it optionally validates them against the list allowed values.
+ *
+ * @param valueName - The name of the parameter (for error reporting)
+ * @param value - The value being parsed
+ * @param allowMultiple - Can $value contain more than one value separated by '|'?
+ * @param allowedValues - An array of values to check against. If null, all values are accepted.
+ * @return (allowMultiple ? an_array_of_values : a_single_value)
+ */
+ protected function parseMultiValue($valueName, $value, $allowMultiple, $allowedValues) {
+ $valuesList = explode('|', $value);
+ if (!$allowMultiple && count($valuesList) != 1) {
+ $possibleValues = is_array($allowedValues) ? "of '" . implode("', '", $allowedValues) . "'" : '';
+ $this->dieUsage("Only one $possibleValues is allowed for parameter '$valueName'", "multival_$valueName");
+ }
+ if (is_array($allowedValues)) {
+ $unknownValues = array_diff($valuesList, $allowedValues);
+ if ($unknownValues) {
+ $this->dieUsage('Unrecognised value' . (count($unknownValues) > 1 ? "s" : "") . " for parameter '$valueName'", "unknown_$valueName");
+ }
+ }
+
+ return $allowMultiple ? $valuesList : $valuesList[0];
+ }
+
+ /**
+ * Validate the value against the minimum and user/bot maximum limits. Prints usage info on failure.
+ */
+ function validateLimit($varname, $value, $min, $max, $botMax) {
+ if ($value < $min) {
+ $this->dieUsage("$varname may not be less than $min (set to $value)", $varname);
+ }
+
+ if ($this->getMain()->isBot()) {
+ if ($value > $botMax) {
+ $this->dieUsage("$varname may not be over $botMax (set to $value) for bots", $varname);
+ }
+ }
+ elseif ($value > $max) {
+ $this->dieUsage("$varname may not be over $max (set to $value) for users", $varname);
+ }
+ }
+
+ /**
+ * Call main module's error handler
+ */
+ public function dieUsage($description, $errorCode, $httpRespCode = 0) {
+ throw new UsageException($description, $this->encodeParamName($errorCode), $httpRespCode);
+ }
+
+ /**
+ * Internal code errors should be reported with this method
+ */
+ protected static function dieDebug($method, $message) {
+ wfDebugDieBacktrace("Internal error in $method: $message");
+ }
+
+ /**
+ * Profiling: total module execution time
+ */
+ private $mTimeIn = 0, $mModuleTime = 0;
+
+ /**
+ * Start module profiling
+ */
+ public function profileIn() {
+ if ($this->mTimeIn !== 0)
+ ApiBase :: dieDebug(__METHOD__, 'called twice without calling profileOut()');
+ $this->mTimeIn = microtime(true);
+ wfProfileIn($this->getModuleProfileName());
+ }
+
+ /**
+ * End module profiling
+ */
+ public function profileOut() {
+ if ($this->mTimeIn === 0)
+ ApiBase :: dieDebug(__METHOD__, 'called without calling profileIn() first');
+ if ($this->mDBTimeIn !== 0)
+ ApiBase :: dieDebug(__METHOD__, 'must be called after database profiling is done with profileDBOut()');
+
+ $this->mModuleTime += microtime(true) - $this->mTimeIn;
+ $this->mTimeIn = 0;
+ wfProfileOut($this->getModuleProfileName());
+ }
+
+ /**
+ * When modules crash, sometimes it is needed to do a profileOut() regardless
+ * of the profiling state the module was in. This method does such cleanup.
+ */
+ public function safeProfileOut() {
+ if ($this->mTimeIn !== 0) {
+ if ($this->mDBTimeIn !== 0)
+ $this->profileDBOut();
+ $this->profileOut();
+ }
+ }
+
+ /**
+ * Total time the module was executed
+ */
+ public function getProfileTime() {
+ if ($this->mTimeIn !== 0)
+ ApiBase :: dieDebug(__METHOD__, 'called without calling profileOut() first');
+ return $this->mModuleTime;
+ }
+
+ /**
+ * Profiling: database execution time
+ */
+ private $mDBTimeIn = 0, $mDBTime = 0;
+
+ /**
+ * Start module profiling
+ */
+ public function profileDBIn() {
+ if ($this->mTimeIn === 0)
+ ApiBase :: dieDebug(__METHOD__, 'must be called while profiling the entire module with profileIn()');
+ if ($this->mDBTimeIn !== 0)
+ ApiBase :: dieDebug(__METHOD__, 'called twice without calling profileDBOut()');
+ $this->mDBTimeIn = microtime(true);
+ wfProfileIn($this->getModuleProfileName(true));
+ }
+
+ /**
+ * End database profiling
+ */
+ public function profileDBOut() {
+ if ($this->mTimeIn === 0)
+ ApiBase :: dieDebug(__METHOD__, 'must be called while profiling the entire module with profileIn()');
+ if ($this->mDBTimeIn === 0)
+ ApiBase :: dieDebug(__METHOD__, 'called without calling profileDBIn() first');
+
+ $time = microtime(true) - $this->mDBTimeIn;
+ $this->mDBTimeIn = 0;
+
+ $this->mDBTime += $time;
+ $this->getMain()->mDBTime += $time;
+ wfProfileOut($this->getModuleProfileName(true));
+ }
+
+ /**
+ * Total time the module used the database
+ */
+ public function getProfileDBTime() {
+ if ($this->mDBTimeIn !== 0)
+ ApiBase :: dieDebug(__METHOD__, 'called without calling profileDBOut() first');
+ return $this->mDBTime;
+ }
+
+ public abstract function getVersion();
+
+ public static function getBaseVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiFeedWatchlist.php b/includes/api/ApiFeedWatchlist.php
new file mode 100644
index 000000000000..335df324b7f8
--- /dev/null
+++ b/includes/api/ApiFeedWatchlist.php
@@ -0,0 +1,125 @@
+<?php
+
+
+/*
+ * Created on Oct 13, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+class ApiFeedWatchlist extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function getCustomPrinter() {
+ return new ApiFormatFeedWrapper($this->getMain());
+ }
+
+ public function execute() {
+ $feedformat = null;
+ extract($this->extractRequestParams());
+
+ // limit to 1 day
+ $startTime = wfTimestamp(TS_MW, time() - intval(1 * 86400));
+
+ // Prepare nested request
+ $params = new FauxRequest(array (
+ 'action' => 'query',
+ 'meta' => 'siteinfo',
+ 'siprop' => 'general',
+ 'list' => 'watchlist',
+ 'wlprop' => 'user|comment|timestamp',
+ 'wlstart' => $startTime,
+ 'wllimit' => 50
+ ));
+
+ // Execute
+ $module = new ApiMain($params);
+ $module->execute();
+
+ // Get data array
+ $data = $module->getResultData();
+
+ $feedItems = array ();
+ foreach ($data['query']['watchlist'] as $info) {
+ $feedItems[] = $this->createFeedItem($info);
+ }
+
+ global $wgFeedClasses, $wgSitename, $wgContLanguageCode;
+ $feedTitle = $wgSitename . ' - ' . wfMsgForContent('watchlist') . ' [' . $wgContLanguageCode . ']';
+ $feedUrl = SpecialPage::getTitleFor( 'Watchlist' )->getFullUrl();
+
+ $feed = new $wgFeedClasses[$feedformat] ($feedTitle, htmlspecialchars(wfMsgForContent('watchlist')), $feedUrl);
+
+ ApiFormatFeedWrapper :: setResult($this->getResult(), $feed, $feedItems);
+ }
+
+ private function createFeedItem($info) {
+ $titleStr = $info['title'];
+ $title = Title :: newFromText($titleStr);
+ $titleUrl = $title->getFullUrl();
+ $comment = isset( $info['comment'] ) ? $info['comment'] : null;
+ $timestamp = $info['timestamp'];
+ $user = $info['user'];
+
+ $completeText = "$comment ($user)";
+
+ return new FeedItem($titleStr, $completeText, $titleUrl, $timestamp, $user);
+ }
+
+ protected function getAllowedParams() {
+ global $wgFeedClasses;
+ $feedFormatNames = array_keys($wgFeedClasses);
+ return array (
+ 'feedformat' => array (
+ ApiBase :: PARAM_DFLT => 'rss',
+ ApiBase :: PARAM_TYPE => $feedFormatNames
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'feedformat' => 'The format of the feed'
+ );
+ }
+
+ protected function getDescription() {
+ return 'This module returns a watchlist feed';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=feedwatchlist'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiFormatBase.php b/includes/api/ApiFormatBase.php
new file mode 100644
index 000000000000..ec131ad3b76e
--- /dev/null
+++ b/includes/api/ApiFormatBase.php
@@ -0,0 +1,235 @@
+<?php
+
+
+/*
+ * Created on Sep 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+abstract class ApiFormatBase extends ApiBase {
+
+ private $mIsHtml, $mFormat;
+
+ /**
+ * Constructor
+ */
+ public function __construct($main, $format) {
+ parent :: __construct($main, $format);
+
+ $this->mIsHtml = (substr($format, -2, 2) === 'fm'); // ends with 'fm'
+ if ($this->mIsHtml)
+ $this->mFormat = substr($format, 0, -2); // remove ending 'fm'
+ else
+ $this->mFormat = $format;
+ $this->mFormat = strtoupper($this->mFormat);
+ }
+
+ /**
+ * Overriding class returns the mime type that should be sent to the client.
+ * This method is not called if getIsHtml() returns true.
+ * @return string
+ */
+ public abstract function getMimeType();
+
+ public function getNeedsRawData() {
+ return false;
+ }
+
+ /**
+ * Returns true when an HTML filtering printer should be used.
+ * The default implementation assumes that formats ending with 'fm'
+ * should be formatted in HTML.
+ */
+ public function getIsHtml() {
+ return $this->mIsHtml;
+ }
+
+ /**
+ * Initialize the printer function and prepares the output headers, etc.
+ * This method must be the first outputing method during execution.
+ * A help screen's header is printed for the HTML-based output
+ */
+ function initPrinter($isError) {
+ $isHtml = $this->getIsHtml();
+ $mime = $isHtml ? 'text/html' : $this->getMimeType();
+
+ // Some printers (ex. Feed) do their own header settings,
+ // in which case $mime will be set to null
+ if (is_null($mime))
+ return; // skip any initialization
+
+ header("Content-Type: $mime; charset=utf-8");
+
+ if ($isHtml) {
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>MediaWiki API</title>
+</head>
+<body>
+<?php
+
+
+ if (!$isError) {
+?>
+<br/>
+<small>
+You are looking at the HTML representation of the <?=$this->mFormat?> format.<br/>
+HTML is good for debugging, but probably is not suitable for your application.<br/>
+Please see "format" parameter documentation at the <a href='api.php'>API help</a>
+for more information.
+</small>
+<?php
+
+
+ }
+?>
+<pre>
+<?php
+
+
+ }
+ }
+
+ /**
+ * Finish printing. Closes HTML tags.
+ */
+ public function closePrinter() {
+ if ($this->getIsHtml()) {
+?>
+
+</pre>
+</body>
+</html>
+<?php
+
+
+ }
+ }
+
+ public function printText($text) {
+ if ($this->getIsHtml())
+ echo $this->formatHTML($text);
+ else
+ echo $text;
+ }
+
+ /**
+ * Prety-print various elements in HTML format, such as xml tags and URLs.
+ * This method also replaces any '<' with &lt;
+ */
+ protected function formatHTML($text) {
+ // Escape everything first for full coverage
+ $text = htmlspecialchars($text);
+
+ // encode all comments or tags as safe blue strings
+ $text = preg_replace('/\&lt;(!--.*?--|.*?)\&gt;/', '<span style="color:blue;">&lt;\1&gt;</span>', $text);
+ // identify URLs
+ $protos = "http|https|ftp|gopher";
+ $text = ereg_replace("($protos)://[^ '\"()<\n]+", '<a href="\\0">\\0</a>', $text);
+ // identify requests to api.php
+ $text = ereg_replace("api\\.php\\?[^ ()<\n\t]+", '<a href="\\0">\\0</a>', $text);
+ // make strings inside * bold
+ $text = ereg_replace("\\*[^<>\n]+\\*", '<b>\\0</b>', $text);
+ // make strings inside $ italic
+ $text = ereg_replace("\\$[^<>\n]+\\$", '<b><i>\\0</i></b>', $text);
+
+ return $text;
+ }
+
+ /**
+ * Returns usage examples for this format.
+ */
+ protected function getExamples() {
+ return 'api.php?action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName();
+ }
+
+ protected function getDescription() {
+ return $this->getIsHtml() ? ' (pretty-print in HTML)' : '';
+ }
+
+ public static function getBaseVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
+/**
+ * This printer is used to wrap an instance of the Feed class
+ */
+class ApiFormatFeedWrapper extends ApiFormatBase {
+
+ public function __construct($main) {
+ parent :: __construct($main, 'feed');
+ }
+
+ /**
+ * Call this method to initialize output data
+ */
+ public static function setResult($result, $feed, $feedItems) {
+ // Store output in the Result data.
+ // This way we can check during execution if any error has occured
+ $data = & $result->getData();
+ $data['_feed'] = $feed;
+ $data['_feeditems'] = $feedItems;
+ }
+
+ /**
+ * Feed does its own headers
+ */
+ public function getMimeType() {
+ return null;
+ }
+
+ /**
+ * Optimization - no need to sanitize data that will not be needed
+ */
+ public function getNeedsRawData() {
+ return true;
+ }
+
+ public function execute() {
+ $data = $this->getResultData();
+ if (isset ($data['_feed']) && isset ($data['_feeditems'])) {
+ $feed = $data['_feed'];
+ $items = $data['_feeditems'];
+
+ $feed->outHeader();
+ foreach ($items as & $item)
+ $feed->outItem($item);
+ $feed->outFooter();
+ } else {
+ // Error has occured, print something usefull
+ // TODO: make this error more informative using ApiBase :: dieDebug() or similar
+ wfHttpError(500, 'Internal Server Error', '');
+ }
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiFormatJson.php b/includes/api/ApiFormatJson.php
new file mode 100644
index 000000000000..06dc99bbd68a
--- /dev/null
+++ b/includes/api/ApiFormatJson.php
@@ -0,0 +1,69 @@
+<?php
+
+
+/*
+ * Created on Sep 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiFormatBase.php');
+}
+
+class ApiFormatJson extends ApiFormatBase {
+
+ private $mIsRaw;
+
+ public function __construct($main, $format) {
+ parent :: __construct($main, $format);
+ $this->mIsRaw = ($format === 'rawfm');
+ }
+
+ public function getMimeType() {
+ return 'application/json';
+ }
+
+ public function getNeedsRawData() {
+ return $this->mIsRaw;
+ }
+
+ public function execute() {
+ if (!function_exists('json_encode') || $this->getIsHtml()) {
+ $json = new Services_JSON();
+ $this->printText($json->encode($this->getResultData(), $this->getIsHtml()));
+ } else {
+ $this->printText(json_encode($this->getResultData()));
+ }
+ }
+
+ protected function getDescription() {
+ if ($this->mIsRaw)
+ return 'Output data with the debuging elements in JSON format' . parent :: getDescription();
+ else
+ return 'Output data in JSON format' . parent :: getDescription();
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiFormatJson_json.php b/includes/api/ApiFormatJson_json.php
new file mode 100644
index 000000000000..375de7eb8480
--- /dev/null
+++ b/includes/api/ApiFormatJson_json.php
@@ -0,0 +1,841 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+* Converts to and from JSON format.
+*
+* JSON (JavaScript Object Notation) is a lightweight data-interchange
+* format. It is easy for humans to read and write. It is easy for machines
+* to parse and generate. It is based on a subset of the JavaScript
+* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
+* This feature can also be found in Python. JSON is a text format that is
+* completely language independent but uses conventions that are familiar
+* to programmers of the C-family of languages, including C, C++, C#, Java,
+* JavaScript, Perl, TCL, and many others. These properties make JSON an
+* ideal data-interchange language.
+*
+* This package provides a simple encoder and decoder for JSON notation. It
+* is intended for use with client-side Javascript applications that make
+* use of HTTPRequest to perform server communication functions - data can
+* be encoded into JSON notation for use in a client-side javascript, or
+* decoded from incoming Javascript requests. JSON format is native to
+* Javascript, and can be directly eval()'ed with no further parsing
+* overhead
+*
+* All strings should be in ASCII or UTF-8 format!
+*
+* LICENSE: Redistribution and use in source and binary forms, with or
+* without modification, are permitted provided that the following
+* conditions are met: Redistributions of source code must retain the
+* above copyright notice, this list of conditions and the following
+* disclaimer. Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+* @category
+* @package Services_JSON
+* @author Michal Migurski <mike-json@teczno.com>
+* @author Matt Knapp <mdknapp[at]gmail[dot]com>
+* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+* @copyright 2005 Michal Migurski
+* @version CVS: $Id: JSON.php,v 1.30 2006/03/08 16:10:20 migurski Exp $
+* @license http://www.opensource.org/licenses/bsd-license.php
+* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+*/
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_SLICE', 1);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_STR', 2);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_ARR', 3);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_OBJ', 4);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_CMT', 5);
+
+/**
+* Behavior switch for Services_JSON::decode()
+*/
+define('SERVICES_JSON_LOOSE_TYPE', 16);
+
+/**
+* Behavior switch for Services_JSON::decode()
+*/
+define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
+
+/**
+* Converts to and from JSON format.
+*
+* Brief example of use:
+*
+* <code>
+* // create a new instance of Services_JSON
+* $json = new Services_JSON();
+*
+* // convert a complexe value to JSON notation, and send it to the browser
+* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+* $output = $json->encode($value);
+*
+* print($output);
+* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+*
+* // accept incoming POST data, assumed to be in JSON notation
+* $input = file_get_contents('php://input', 1000000);
+* $value = $json->decode($input);
+* </code>
+*/
+class Services_JSON
+{
+ /**
+ * constructs a new JSON instance
+ *
+ * @param int $use object behavior flags; combine with boolean-OR
+ *
+ * possible values:
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
+ * "{...}" syntax creates associative arrays
+ * instead of objects in decode().
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
+ * Values which can't be encoded (e.g. resources)
+ * appear as NULL instead of throwing errors.
+ * By default, a deeply-nested resource will
+ * bubble up with an error, so all return values
+ * from encode() should be checked with isError()
+ */
+ function Services_JSON($use = 0)
+ {
+ $this->use = $use;
+ }
+
+ /**
+ * convert a string from one UTF-16 char to one UTF-8 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibye string extension.
+ *
+ * @param string $utf16 UTF-16 character
+ * @return string UTF-8 character
+ * @access private
+ */
+ function utf162utf8($utf16)
+ {
+ // oh please oh please oh please oh please oh please
+ if(function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+ }
+
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+ switch(true) {
+ case ((0x7F & $bytes) == $bytes):
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0x7F & $bytes);
+
+ case (0x07FF & $bytes) == $bytes:
+ // return a 2-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
+ . chr(0x80 | ($bytes & 0x3F));
+
+ case (0xFFFF & $bytes) == $bytes:
+ // return a 3-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
+ . chr(0x80 | ($bytes & 0x3F));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
+ }
+
+ /**
+ * convert a string from one UTF-8 char to one UTF-16 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibye string extension.
+ *
+ * @param string $utf8 UTF-8 character
+ * @return string UTF-16 character
+ * @access private
+ */
+ function utf82utf16($utf8)
+ {
+ // oh please oh please oh please oh please oh please
+ if(function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+ }
+
+ switch(strlen($utf8)) {
+ case 1:
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return $utf8;
+
+ case 2:
+ // return a UTF-16 character from a 2-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0x07 & (ord($utf8{0}) >> 2))
+ . chr((0xC0 & (ord($utf8{0}) << 6))
+ | (0x3F & ord($utf8{1})));
+
+ case 3:
+ // return a UTF-16 character from a 3-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr((0xF0 & (ord($utf8{0}) << 4))
+ | (0x0F & (ord($utf8{1}) >> 2)))
+ . chr((0xC0 & (ord($utf8{1}) << 6))
+ | (0x7F & ord($utf8{2})));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
+ }
+
+ /**
+ * encodes an arbitrary variable into JSON format
+ *
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
+ * if var is a strng, note that encode() always expects it
+ * to be in ASCII or UTF-8 format!
+ * @param bool $pretty pretty-print output with indents and newlines
+ *
+ * @return mixed JSON string representation of input var or an error if a problem occurs
+ * @access public
+ */
+ function encode($var, $pretty=false)
+ {
+ $this->indent = 0;
+ $this->pretty = $pretty;
+ $this->nameValSeparator = $pretty ? ': ' : ':';
+ return $this->encode2($var);
+ }
+
+ /**
+ * encodes an arbitrary variable into JSON format
+ *
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
+ * if var is a strng, note that encode() always expects it
+ * to be in ASCII or UTF-8 format!
+ *
+ * @return mixed JSON string representation of input var or an error if a problem occurs
+ * @access private
+ */
+ function encode2($var)
+ {
+ if ($this->pretty) {
+ $close = "\n" . str_repeat("\t", $this->indent);
+ $open = $close . "\t";
+ $mid = ',' . $open;
+ }
+ else {
+ $open = $close = '';
+ $mid = ',';
+ }
+
+ switch (gettype($var)) {
+ case 'boolean':
+ return $var ? 'true' : 'false';
+
+ case 'NULL':
+ return 'null';
+
+ case 'integer':
+ return (int) $var;
+
+ case 'double':
+ case 'float':
+ return (float) $var;
+
+ case 'string':
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+ $ascii = '';
+ $strlen_var = strlen($var);
+
+ /*
+ * Iterate over every character in the string,
+ * escaping with a slash or encoding to UTF-8 where necessary
+ */
+ for ($c = 0; $c < $strlen_var; ++$c) {
+
+ $ord_var_c = ord($var{$c});
+
+ switch (true) {
+ case $ord_var_c == 0x08:
+ $ascii .= '\b';
+ break;
+ case $ord_var_c == 0x09:
+ $ascii .= '\t';
+ break;
+ case $ord_var_c == 0x0A:
+ $ascii .= '\n';
+ break;
+ case $ord_var_c == 0x0C:
+ $ascii .= '\f';
+ break;
+ case $ord_var_c == 0x0D:
+ $ascii .= '\r';
+ break;
+
+ case $ord_var_c == 0x22:
+ case $ord_var_c == 0x2F:
+ case $ord_var_c == 0x5C:
+ // double quote, slash, slosh
+ $ascii .= '\\'.$var{$c};
+ break;
+
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+ // characters U-00000000 - U-0000007F (same as ASCII)
+ $ascii .= $var{$c};
+ break;
+
+ case (($ord_var_c & 0xE0) == 0xC0):
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+ $c += 1;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF0) == 0xE0):
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}));
+ $c += 2;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF8) == 0xF0):
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}));
+ $c += 3;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFC) == 0xF8):
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}),
+ ord($var{$c + 4}));
+ $c += 4;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFE) == 0xFC):
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}),
+ ord($var{$c + 4}),
+ ord($var{$c + 5}));
+ $c += 5;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+ }
+ }
+
+ return '"'.$ascii.'"';
+
+ case 'array':
+ /*
+ * As per JSON spec if any array key is not an integer
+ * we must treat the the whole array as an object. We
+ * also try to catch a sparsely populated associative
+ * array with numeric keys here because some JS engines
+ * will create an array with empty indexes up to
+ * max_index which can cause memory issues and because
+ * the keys, which may be relevant, will be remapped
+ * otherwise.
+ *
+ * As per the ECMA and JSON specification an object may
+ * have any string as a property. Unfortunately due to
+ * a hole in the ECMA specification if the key is a
+ * ECMA reserved word or starts with a digit the
+ * parameter is only accessible using ECMAScript's
+ * bracket notation.
+ */
+
+ // treat as a JSON object
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+ $this->indent++;
+ $properties = array_map(array($this, 'name_value'),
+ array_keys($var),
+ array_values($var));
+ $this->indent--;
+
+ foreach($properties as $property) {
+ if(Services_JSON::isError($property)) {
+ return $property;
+ }
+ }
+
+ return '{' . $open . join($mid, $properties) . $close . '}';
+ }
+
+ // treat it like a regular array
+ $this->indent++;
+ $elements = array_map(array($this, 'encode2'), $var);
+ $this->indent--;
+
+ foreach($elements as $element) {
+ if(Services_JSON::isError($element)) {
+ return $element;
+ }
+ }
+
+ return '[' . $open . join($mid, $elements) . $close . ']';
+
+ case 'object':
+ $vars = get_object_vars($var);
+
+ $this->indent++;
+ $properties = array_map(array($this, 'name_value'),
+ array_keys($vars),
+ array_values($vars));
+ $this->indent--;
+
+ foreach($properties as $property) {
+ if(Services_JSON::isError($property)) {
+ return $property;
+ }
+ }
+
+ return '{' . $open . join($mid, $properties) . $close . '}';
+
+ default:
+ return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
+ ? 'null'
+ : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
+ }
+ }
+
+ /**
+ * array-walking function for use in generating JSON-formatted name-value pairs
+ *
+ * @param string $name name of key to use
+ * @param mixed $value reference to an array element to be encoded
+ *
+ * @return string JSON-formatted name-value pair, like '"name":value'
+ * @access private
+ */
+ function name_value($name, $value)
+ {
+ $encoded_value = $this->encode2($value);
+
+ if(Services_JSON::isError($encoded_value)) {
+ return $encoded_value;
+ }
+
+ return $this->encode2(strval($name)) . $this->nameValSeparator . $encoded_value;
+ }
+
+ /**
+ * reduce a string by removing leading and trailing comments and whitespace
+ *
+ * @param $str string string value to strip of comments and whitespace
+ *
+ * @return string string value stripped of comments and whitespace
+ * @access private
+ */
+ function reduce_string($str)
+ {
+ $str = preg_replace(array(
+
+ // eliminate single line comments in '// ...' form
+ '#^\s*//(.+)$#m',
+
+ // eliminate multi-line comments in '/* ... */' form, at start of string
+ '#^\s*/\*(.+)\*/#Us',
+
+ // eliminate multi-line comments in '/* ... */' form, at end of string
+ '#/\*(.+)\*/\s*$#Us'
+
+ ), '', $str);
+
+ // eliminate extraneous space
+ return trim($str);
+ }
+
+ /**
+ * decodes a JSON string into appropriate variable
+ *
+ * @param string $str JSON-formatted string
+ *
+ * @return mixed number, boolean, string, array, or object
+ * corresponding to given JSON input string.
+ * See argument 1 to Services_JSON() above for object-output behavior.
+ * Note that decode() always returns strings
+ * in ASCII or UTF-8 format!
+ * @access public
+ */
+ function decode($str)
+ {
+ $str = $this->reduce_string($str);
+
+ switch (strtolower($str)) {
+ case 'true':
+ return true;
+
+ case 'false':
+ return false;
+
+ case 'null':
+ return null;
+
+ default:
+ $m = array();
+
+ if (is_numeric($str)) {
+ // Lookie-loo, it's a number
+
+ // This would work on its own, but I'm trying to be
+ // good about returning integers where appropriate:
+ // return (float)$str;
+
+ // Return float or int, as appropriate
+ return ((float)$str == (integer)$str)
+ ? (integer)$str
+ : (float)$str;
+
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+ // STRINGS RETURNED IN UTF-8 FORMAT
+ $delim = substr($str, 0, 1);
+ $chrs = substr($str, 1, -1);
+ $utf8 = '';
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
+
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+ $ord_chrs_c = ord($chrs{$c});
+
+ switch (true) {
+ case $substr_chrs_c_2 == '\b':
+ $utf8 .= chr(0x08);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\t':
+ $utf8 .= chr(0x09);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\n':
+ $utf8 .= chr(0x0A);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\f':
+ $utf8 .= chr(0x0C);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\r':
+ $utf8 .= chr(0x0D);
+ ++$c;
+ break;
+
+ case $substr_chrs_c_2 == '\\"':
+ case $substr_chrs_c_2 == '\\\'':
+ case $substr_chrs_c_2 == '\\\\':
+ case $substr_chrs_c_2 == '\\/':
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+ $utf8 .= $chrs{++$c};
+ }
+ break;
+
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+ // single, escaped unicode character
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
+ $utf8 .= $this->utf162utf8($utf16);
+ $c += 5;
+ break;
+
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+ $utf8 .= $chrs{$c};
+ break;
+
+ case ($ord_chrs_c & 0xE0) == 0xC0:
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 2);
+ ++$c;
+ break;
+
+ case ($ord_chrs_c & 0xF0) == 0xE0:
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 3);
+ $c += 2;
+ break;
+
+ case ($ord_chrs_c & 0xF8) == 0xF0:
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 4);
+ $c += 3;
+ break;
+
+ case ($ord_chrs_c & 0xFC) == 0xF8:
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 5);
+ $c += 4;
+ break;
+
+ case ($ord_chrs_c & 0xFE) == 0xFC:
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 6);
+ $c += 5;
+ break;
+
+ }
+
+ }
+
+ return $utf8;
+
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+ // array, or object notation
+
+ if ($str{0} == '[') {
+ $stk = array(SERVICES_JSON_IN_ARR);
+ $arr = array();
+ } else {
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $stk = array(SERVICES_JSON_IN_OBJ);
+ $obj = array();
+ } else {
+ $stk = array(SERVICES_JSON_IN_OBJ);
+ $obj = new stdClass();
+ }
+ }
+
+ array_push($stk, array('what' => SERVICES_JSON_SLICE,
+ 'where' => 0,
+ 'delim' => false));
+
+ $chrs = substr($str, 1, -1);
+ $chrs = $this->reduce_string($chrs);
+
+ if ($chrs == '') {
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ return $arr;
+
+ } else {
+ return $obj;
+
+ }
+ }
+
+ //print("\nparsing {$chrs}\n");
+
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
+
+ $top = end($stk);
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+ // found a comma that is not inside a string, array, etc.,
+ // OR we've reached the end of the character list
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
+ array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ // we are in an array, so just push an element onto the stack
+ array_push($arr, $this->decode($slice));
+
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+ // we are in an object, so figure
+ // out the property name and set an
+ // element in an associative array,
+ // for now
+ $parts = array();
+
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // "name":value pair
+ $key = $this->decode($parts[1]);
+ $val = $this->decode($parts[2]);
+
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // name:value pair, where name is unquoted
+ $key = $parts[1];
+ $val = $this->decode($parts[2]);
+
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ }
+
+ }
+
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+ // found a quote, and we are not inside a string
+ array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+ //print("Found start of string at {$c}\n");
+
+ } elseif (($chrs{$c} == $top['delim']) &&
+ ($top['what'] == SERVICES_JSON_IN_STR) &&
+ (($chrs{$c - 1} != '\\') ||
+ ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
+ // found a quote, we're in a string, and it's not escaped
+ array_pop($stk);
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '[') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a left-bracket, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+ //print("Found start of array at {$c}\n");
+
+ } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+ // found a right-bracket, and we're in an array
+ array_pop($stk);
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '{') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a left-brace, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+ //print("Found start of object at {$c}\n");
+
+ } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+ // found a right-brace, and we're in an object
+ array_pop($stk);
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($substr_chrs_c_2 == '/*') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a comment start, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+ $c++;
+ //print("Found start of comment at {$c}\n");
+
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+ // found a comment end, and we're in one now
+ array_pop($stk);
+ $c++;
+
+ for ($i = $top['where']; $i <= $c; ++$i)
+ $chrs = substr_replace($chrs, ' ', $i, 1);
+
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ }
+
+ }
+
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ return $arr;
+
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+ return $obj;
+
+ }
+
+ }
+ }
+ }
+
+ /**
+ * @todo Ultimately, this should just call PEAR::isError()
+ */
+ function isError($data, $code = null)
+ {
+ if (class_exists('pear')) {
+ return PEAR::isError($data, $code);
+ } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
+ is_subclass_of($data, 'services_json_error'))) {
+ return true;
+ }
+
+ return false;
+ }
+}
+
+if (class_exists('PEAR_Error')) {
+
+ class Services_JSON_Error extends PEAR_Error
+ {
+ function Services_JSON_Error($message = 'unknown error', $code = null,
+ $mode = null, $options = null, $userinfo = null)
+ {
+ parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
+ }
+ }
+
+} else {
+
+ /**
+ * @todo Ultimately, this class shall be descended from PEAR_Error
+ */
+ class Services_JSON_Error
+ {
+ function Services_JSON_Error($message = 'unknown error', $code = null,
+ $mode = null, $options = null, $userinfo = null)
+ {
+
+ }
+ }
+
+}
+
+?>
diff --git a/includes/api/ApiFormatPhp.php b/includes/api/ApiFormatPhp.php
new file mode 100644
index 000000000000..f635f4ca797a
--- /dev/null
+++ b/includes/api/ApiFormatPhp.php
@@ -0,0 +1,54 @@
+<?php
+
+
+/*
+ * Created on Oct 22, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiFormatBase.php');
+}
+
+class ApiFormatPhp extends ApiFormatBase {
+
+ public function __construct($main, $format) {
+ parent :: __construct($main, $format);
+ }
+
+ public function getMimeType() {
+ return 'application/vnd.php.serialized';
+ }
+
+ public function execute() {
+ $this->printText(serialize($this->getResultData()));
+ }
+
+ protected function getDescription() {
+ return 'Output data in serialized PHP format' . parent :: getDescription();
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiFormatWddx.php b/includes/api/ApiFormatWddx.php
new file mode 100644
index 000000000000..71f13d4a3ae4
--- /dev/null
+++ b/includes/api/ApiFormatWddx.php
@@ -0,0 +1,89 @@
+<?php
+
+
+/*
+ * Created on Oct 22, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiFormatBase.php');
+}
+
+class ApiFormatWddx extends ApiFormatBase {
+
+ public function __construct($main, $format) {
+ parent :: __construct($main, $format);
+ }
+
+ public function getMimeType() {
+ return 'text/xml';
+ }
+
+ public function execute() {
+ if (function_exists('wddx_serialize_value')) {
+ $this->printText(wddx_serialize_value($this->getResultData()));
+ } else {
+ $this->printText('<?xml version="1.0" encoding="utf-8"?>');
+ $this->printText('<wddxPacket version="1.0"><header/><data>');
+ $this->slowWddxPrinter($this->getResultData());
+ $this->printText('</data></wddxPacket>');
+ }
+ }
+
+ /**
+ * Recursivelly go through the object and output its data in WDDX format.
+ */
+ function slowWddxPrinter($elemValue) {
+ switch (gettype($elemValue)) {
+ case 'array' :
+ $this->printText('<struct>');
+ foreach ($elemValue as $subElemName => $subElemValue) {
+ $this->printText(wfElement('var', array (
+ 'name' => $subElemName
+ ), null));
+ $this->slowWddxPrinter($subElemValue);
+ $this->printText('</var>');
+ }
+ $this->printText('</struct>');
+ break;
+ case 'integer' :
+ case 'double' :
+ $this->printText(wfElement('number', null, $elemValue));
+ break;
+ case 'string' :
+ $this->printText(wfElement('string', null, $elemValue));
+ break;
+ default :
+ ApiBase :: dieDebug(__METHOD__, 'Unknown type ' . gettype($elemValue));
+ }
+ }
+
+ protected function getDescription() {
+ return 'Output data in WDDX format' . parent :: getDescription();
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiFormatXml.php b/includes/api/ApiFormatXml.php
new file mode 100644
index 000000000000..5d4e776f4a34
--- /dev/null
+++ b/includes/api/ApiFormatXml.php
@@ -0,0 +1,145 @@
+<?php
+
+
+/*
+ * Created on Sep 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiFormatBase.php');
+}
+
+class ApiFormatXml extends ApiFormatBase {
+
+ private $mRootElemName = 'api';
+
+ public function __construct($main, $format) {
+ parent :: __construct($main, $format);
+ }
+
+ public function getMimeType() {
+ return 'text/xml';
+ }
+
+ public function getNeedsRawData() {
+ return true;
+ }
+
+ public function setRootElement($rootElemName) {
+ $this->mRootElemName = $rootElemName;
+ }
+
+ public function execute() {
+ $this->printText('<?xml version="1.0" encoding="utf-8"?>');
+ $this->recXmlPrint($this->mRootElemName, $this->getResultData(), $this->getIsHtml() ? -2 : null);
+ }
+
+ /**
+ * This method takes an array and converts it into an xml.
+ * There are several noteworthy cases:
+ *
+ * If array contains a key '_element', then the code assumes that ALL other keys are not important and replaces them with the value['_element'].
+ * Example: name='root', value = array( '_element'=>'page', 'x', 'y', 'z') creates <root> <page>x</page> <page>y</page> <page>z</page> </root>
+ *
+ * If any of the array's element key is '*', then the code treats all other key->value pairs as attributes, and the value['*'] as the element's content.
+ * Example: name='root', value = array( '*'=>'text', 'lang'=>'en', 'id'=>10) creates <root lang='en' id='10'>text</root>
+ *
+ * If neither key is found, all keys become element names, and values become element content.
+ * The method is recursive, so the same rules apply to any sub-arrays.
+ */
+ function recXmlPrint($elemName, $elemValue, $indent) {
+ if (!is_null($indent)) {
+ $indent += 2;
+ $indstr = "\n" . str_repeat(" ", $indent);
+ } else {
+ $indstr = '';
+ }
+
+ switch (gettype($elemValue)) {
+ case 'array' :
+
+ if (isset ($elemValue['*'])) {
+ $subElemContent = $elemValue['*'];
+ unset ($elemValue['*']);
+ } else {
+ $subElemContent = null;
+ }
+
+ if (isset ($elemValue['_element'])) {
+ $subElemIndName = $elemValue['_element'];
+ unset ($elemValue['_element']);
+ } else {
+ $subElemIndName = null;
+ }
+
+ $indElements = array ();
+ $subElements = array ();
+ foreach ($elemValue as $subElemId => & $subElemValue) {
+ if (gettype($subElemId) === 'integer') {
+ $indElements[] = $subElemValue;
+ unset ($elemValue[$subElemId]);
+ } elseif (is_array($subElemValue)) {
+ $subElements[$subElemId] = $subElemValue;
+ unset ($elemValue[$subElemId]);
+ }
+ }
+
+ if (is_null($subElemIndName) && !empty ($indElements))
+ ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has integer keys without _element value. Use ApiResult::setIndexedTagName().");
+
+ if (!empty ($subElements) && !empty ($indElements) && !is_null($subElemContent))
+ ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has content and subelements");
+
+ if (!is_null($subElemContent)) {
+ $this->printText($indstr . wfElement($elemName, $elemValue, $subElemContent));
+ } elseif (empty ($indElements) && empty ($subElements)) {
+ $this->printText($indstr . wfElement($elemName, $elemValue));
+ } else {
+ $this->printText($indstr . wfElement($elemName, $elemValue, null));
+
+ foreach ($subElements as $subElemId => & $subElemValue)
+ $this->recXmlPrint($subElemId, $subElemValue, $indent);
+
+ foreach ($indElements as $subElemId => & $subElemValue)
+ $this->recXmlPrint($subElemIndName, $subElemValue, $indent);
+
+ $this->printText($indstr . wfCloseElement($elemName));
+ }
+ break;
+ case 'object' :
+ // ignore
+ break;
+ default :
+ $this->printText($indstr . wfElement($elemName, null, $elemValue));
+ break;
+ }
+ }
+ protected function getDescription() {
+ return 'Output data in XML format' . parent :: getDescription();
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiFormatYaml.php b/includes/api/ApiFormatYaml.php
new file mode 100644
index 000000000000..006e9733a035
--- /dev/null
+++ b/includes/api/ApiFormatYaml.php
@@ -0,0 +1,54 @@
+<?php
+
+
+/*
+ * Created on Sep 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiFormatBase.php');
+}
+
+class ApiFormatYaml extends ApiFormatBase {
+
+ public function __construct($main, $format) {
+ parent :: __construct($main, $format);
+ }
+
+ public function getMimeType() {
+ return 'application/yaml';
+ }
+
+ public function execute() {
+ $this->printText(Spyc :: YAMLDump($this->getResultData()));
+ }
+
+ protected function getDescription() {
+ return 'Output data in YAML format' . parent :: getDescription();
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiFormatYaml_spyc.php b/includes/api/ApiFormatYaml_spyc.php
new file mode 100644
index 000000000000..1ec8af488749
--- /dev/null
+++ b/includes/api/ApiFormatYaml_spyc.php
@@ -0,0 +1,861 @@
+<?php
+ /**
+ * Spyc -- A Simple PHP YAML Class
+ * @version 0.2.3 -- 2006-02-04
+ * @author Chris Wanstrath <chris@ozmm.org>
+ * @link http://spyc.sourceforge.net/
+ * @copyright Copyright 2005-2006 Chris Wanstrath
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
+ * @package Spyc
+ */
+
+ /**
+ * A node, used by Spyc for parsing YAML.
+ * @package Spyc
+ */
+ class YAMLNode {
+ /**#@+
+ * @access public
+ * @var string
+ */
+ var $parent;
+ var $id;
+ /**#@+*/
+ /**
+ * @access public
+ * @var mixed
+ */
+ var $data;
+ /**
+ * @access public
+ * @var int
+ */
+ var $indent;
+ /**
+ * @access public
+ * @var bool
+ */
+ var $children = false;
+
+ /**
+ * The constructor assigns the node a unique ID.
+ * @access public
+ * @return void
+ */
+ function YAMLNode() {
+ $this->id = uniqid('');
+ }
+ }
+
+ /**
+ * The Simple PHP YAML Class.
+ *
+ * This class can be used to read a YAML file and convert its contents
+ * into a PHP array. It currently supports a very limited subsection of
+ * the YAML spec.
+ *
+ * Usage:
+ * <code>
+ * $parser = new Spyc;
+ * $array = $parser->load($file);
+ * </code>
+ * @package Spyc
+ */
+ class Spyc {
+
+ /**
+ * Load YAML into a PHP array statically
+ *
+ * The load method, when supplied with a YAML stream (string or file),
+ * will do its best to convert YAML in a file into a PHP array. Pretty
+ * simple.
+ * Usage:
+ * <code>
+ * $array = Spyc::YAMLLoad('lucky.yml');
+ * print_r($array);
+ * </code>
+ * @access public
+ * @return array
+ * @param string $input Path of YAML file or string containing YAML
+ */
+ function YAMLLoad($input) {
+ $spyc = new Spyc;
+ return $spyc->load($input);
+ }
+
+ /**
+ * Dump YAML from PHP array statically
+ *
+ * The dump method, when supplied with an array, will do its best
+ * to convert the array into friendly YAML. Pretty simple. Feel free to
+ * save the returned string as nothing.yml and pass it around.
+ *
+ * Oh, and you can decide how big the indent is and what the wordwrap
+ * for folding is. Pretty cool -- just pass in 'false' for either if
+ * you want to use the default.
+ *
+ * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
+ * you can turn off wordwrap by passing in 0.
+ *
+ * @access public
+ * @static
+ * @return string
+ * @param array $array PHP array
+ * @param int $indent Pass in false to use the default, which is 2
+ * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
+ */
+ public static function YAMLDump($array,$indent = false,$wordwrap = false) {
+ $spyc = new Spyc;
+ return $spyc->dump($array,$indent,$wordwrap);
+ }
+
+ /**
+ * Load YAML into a PHP array from an instantiated object
+ *
+ * The load method, when supplied with a YAML stream (string or file path),
+ * will do its best to convert the YAML into a PHP array. Pretty simple.
+ * Usage:
+ * <code>
+ * $parser = new Spyc;
+ * $array = $parser->load('lucky.yml');
+ * print_r($array);
+ * </code>
+ * @access public
+ * @return array
+ * @param string $input Path of YAML file or string containing YAML
+ */
+ function load($input) {
+ // See what type of input we're talking about
+ // If it's not a file, assume it's a string
+ if (!empty($input) && (strpos($input, "\n") === false)
+ && file_exists($input)) {
+ $yaml = file($input);
+ } else {
+ $yaml = explode("\n",$input);
+ }
+ // Initiate some objects and values
+ $base = new YAMLNode;
+ $base->indent = 0;
+ $this->_lastIndent = 0;
+ $this->_lastNode = $base->id;
+ $this->_inBlock = false;
+ $this->_isInline = false;
+
+ foreach ($yaml as $linenum => $line) {
+ $ifchk = trim($line);
+
+ // If the line starts with a tab (instead of a space), throw a fit.
+ if (preg_match('/^(\t)+(\w+)/', $line)) {
+ $err = 'ERROR: Line '. ($linenum + 1) .' in your input YAML begins'.
+ ' with a tab. YAML only recognizes spaces. Please reformat.';
+ die($err);
+ }
+
+ if ($this->_inBlock === false && empty($ifchk)) {
+ continue;
+ } elseif ($this->_inBlock == true && empty($ifchk)) {
+ $last =& $this->_allNodes[$this->_lastNode];
+ $last->data[key($last->data)] .= "\n";
+ } elseif ($ifchk{0} != '#' && substr($ifchk,0,3) != '---') {
+ // Create a new node and get its indent
+ $node = new YAMLNode;
+ $node->indent = $this->_getIndent($line);
+
+ // Check where the node lies in the hierarchy
+ if ($this->_lastIndent == $node->indent) {
+ // If we're in a block, add the text to the parent's data
+ if ($this->_inBlock === true) {
+ $parent =& $this->_allNodes[$this->_lastNode];
+ $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd;
+ } else {
+ // The current node's parent is the same as the previous node's
+ if (isset($this->_allNodes[$this->_lastNode])) {
+ $node->parent = $this->_allNodes[$this->_lastNode]->parent;
+ }
+ }
+ } elseif ($this->_lastIndent < $node->indent) {
+ if ($this->_inBlock === true) {
+ $parent =& $this->_allNodes[$this->_lastNode];
+ $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd;
+ } elseif ($this->_inBlock === false) {
+ // The current node's parent is the previous node
+ $node->parent = $this->_lastNode;
+
+ // If the value of the last node's data was > or | we need to
+ // start blocking i.e. taking in all lines as a text value until
+ // we drop our indent.
+ $parent =& $this->_allNodes[$node->parent];
+ $this->_allNodes[$node->parent]->children = true;
+ if (is_array($parent->data)) {
+ $chk = $parent->data[key($parent->data)];
+ if ($chk === '>') {
+ $this->_inBlock = true;
+ $this->_blockEnd = ' ';
+ $parent->data[key($parent->data)] =
+ str_replace('>','',$parent->data[key($parent->data)]);
+ $parent->data[key($parent->data)] .= trim($line).' ';
+ $this->_allNodes[$node->parent]->children = false;
+ $this->_lastIndent = $node->indent;
+ } elseif ($chk === '|') {
+ $this->_inBlock = true;
+ $this->_blockEnd = "\n";
+ $parent->data[key($parent->data)] =
+ str_replace('|','',$parent->data[key($parent->data)]);
+ $parent->data[key($parent->data)] .= trim($line)."\n";
+ $this->_allNodes[$node->parent]->children = false;
+ $this->_lastIndent = $node->indent;
+ }
+ }
+ }
+ } elseif ($this->_lastIndent > $node->indent) {
+ // Any block we had going is dead now
+ if ($this->_inBlock === true) {
+ $this->_inBlock = false;
+ if ($this->_blockEnd = "\n") {
+ $last =& $this->_allNodes[$this->_lastNode];
+ $last->data[key($last->data)] =
+ trim($last->data[key($last->data)]);
+ }
+ }
+
+ // We don't know the parent of the node so we have to find it
+ // foreach ($this->_allNodes as $n) {
+ foreach ($this->_indentSort[$node->indent] as $n) {
+ if ($n->indent == $node->indent) {
+ $node->parent = $n->parent;
+ }
+ }
+ }
+
+ if ($this->_inBlock === false) {
+ // Set these properties with information from our current node
+ $this->_lastIndent = $node->indent;
+ // Set the last node
+ $this->_lastNode = $node->id;
+ // Parse the YAML line and return its data
+ $node->data = $this->_parseLine($line);
+ // Add the node to the master list
+ $this->_allNodes[$node->id] = $node;
+ // Add a reference to the node in an indent array
+ $this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id];
+ // Add a reference to the node in a References array if this node
+ // has a YAML reference in it.
+ if (
+ ( (is_array($node->data)) &&
+ isset($node->data[key($node->data)]) &&
+ (!is_array($node->data[key($node->data)])) )
+ &&
+ ( (preg_match('/^&([^ ]+)/',$node->data[key($node->data)]))
+ ||
+ (preg_match('/^\*([^ ]+)/',$node->data[key($node->data)])) )
+ ) {
+ $this->_haveRefs[] =& $this->_allNodes[$node->id];
+ } elseif (
+ ( (is_array($node->data)) &&
+ isset($node->data[key($node->data)]) &&
+ (is_array($node->data[key($node->data)])) )
+ ) {
+ // Incomplete reference making code. Ugly, needs cleaned up.
+ foreach ($node->data[key($node->data)] as $d) {
+ if ( !is_array($d) &&
+ ( (preg_match('/^&([^ ]+)/',$d))
+ ||
+ (preg_match('/^\*([^ ]+)/',$d)) )
+ ) {
+ $this->_haveRefs[] =& $this->_allNodes[$node->id];
+ }
+ }
+ }
+ }
+ }
+ }
+ unset($node);
+
+ // Here we travel through node-space and pick out references (& and *)
+ $this->_linkReferences();
+
+ // Build the PHP array out of node-space
+ $trunk = $this->_buildArray();
+ return $trunk;
+ }
+
+ /**
+ * Dump PHP array to YAML
+ *
+ * The dump method, when supplied with an array, will do its best
+ * to convert the array into friendly YAML. Pretty simple. Feel free to
+ * save the returned string as tasteful.yml and pass it around.
+ *
+ * Oh, and you can decide how big the indent is and what the wordwrap
+ * for folding is. Pretty cool -- just pass in 'false' for either if
+ * you want to use the default.
+ *
+ * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
+ * you can turn off wordwrap by passing in 0.
+ *
+ * @access public
+ * @return string
+ * @param array $array PHP array
+ * @param int $indent Pass in false to use the default, which is 2
+ * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
+ */
+ function dump($array,$indent = false,$wordwrap = false) {
+ // Dumps to some very clean YAML. We'll have to add some more features
+ // and options soon. And better support for folding.
+
+ // New features and options.
+ if ($indent === false or !is_numeric($indent)) {
+ $this->_dumpIndent = 2;
+ } else {
+ $this->_dumpIndent = $indent;
+ }
+
+ if ($wordwrap === false or !is_numeric($wordwrap)) {
+ $this->_dumpWordWrap = 40;
+ } else {
+ $this->_dumpWordWrap = $wordwrap;
+ }
+
+ // New YAML document
+ $string = "---\n";
+
+ // Start at the base of the array and move through it.
+ foreach ($array as $key => $value) {
+ $string .= $this->_yamlize($key,$value,0);
+ }
+ return $string;
+ }
+
+ /**** Private Properties ****/
+
+ /**#@+
+ * @access private
+ * @var mixed
+ */
+ var $_haveRefs;
+ var $_allNodes;
+ var $_lastIndent;
+ var $_lastNode;
+ var $_inBlock;
+ var $_isInline;
+ var $_dumpIndent;
+ var $_dumpWordWrap;
+ /**#@+*/
+
+ /**** Private Methods ****/
+
+ /**
+ * Attempts to convert a key / value array item to YAML
+ * @access private
+ * @return string
+ * @param $key The name of the key
+ * @param $value The value of the item
+ * @param $indent The indent of the current node
+ */
+ function _yamlize($key,$value,$indent) {
+ if (is_array($value)) {
+ // It has children. What to do?
+ // Make it the right kind of item
+ $string = $this->_dumpNode($key,NULL,$indent);
+ // Add the indent
+ $indent += $this->_dumpIndent;
+ // Yamlize the array
+ $string .= $this->_yamlizeArray($value,$indent);
+ } elseif (!is_array($value)) {
+ // It doesn't have children. Yip.
+ $string = $this->_dumpNode($key,$value,$indent);
+ }
+ return $string;
+ }
+
+ /**
+ * Attempts to convert an array to YAML
+ * @access private
+ * @return string
+ * @param $array The array you want to convert
+ * @param $indent The indent of the current level
+ */
+ function _yamlizeArray($array,$indent) {
+ if (is_array($array)) {
+ $string = '';
+ foreach ($array as $key => $value) {
+ $string .= $this->_yamlize($key,$value,$indent);
+ }
+ return $string;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns YAML from a key and a value
+ * @access private
+ * @return string
+ * @param $key The name of the key
+ * @param $value The value of the item
+ * @param $indent The indent of the current node
+ */
+ function _dumpNode($key,$value,$indent) {
+ // do some folding here, for blocks
+ if (strpos($value,"\n")) {
+ $value = $this->_doLiteralBlock($value,$indent);
+ } else {
+ $value = $this->_doFolding($value,$indent);
+ }
+
+ $spaces = str_repeat(' ',$indent);
+
+ if (is_int($key)) {
+ // It's a sequence
+ $string = $spaces.'- '.$value."\n";
+ } else {
+ // It's mapped
+ $string = $spaces.$key.': '.$value."\n";
+ }
+ return $string;
+ }
+
+ /**
+ * Creates a literal block for dumping
+ * @access private
+ * @return string
+ * @param $value
+ * @param $indent int The value of the indent
+ */
+ function _doLiteralBlock($value,$indent) {
+ $exploded = explode("\n",$value);
+ $newValue = '|';
+ $indent += $this->_dumpIndent;
+ $spaces = str_repeat(' ',$indent);
+ foreach ($exploded as $line) {
+ $newValue .= "\n" . $spaces . trim($line);
+ }
+ return $newValue;
+ }
+
+ /**
+ * Folds a string of text, if necessary
+ * @access private
+ * @return string
+ * @param $value The string you wish to fold
+ */
+ function _doFolding($value,$indent) {
+ // Don't do anything if wordwrap is set to 0
+ if ($this->_dumpWordWrap === 0) {
+ return $value;
+ }
+
+ if (strlen($value) > $this->_dumpWordWrap) {
+ $indent += $this->_dumpIndent;
+ $indent = str_repeat(' ',$indent);
+ $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
+ $value = ">\n".$indent.$wrapped;
+ }
+ return $value;
+ }
+
+ /* Methods used in loading */
+
+ /**
+ * Finds and returns the indentation of a YAML line
+ * @access private
+ * @return int
+ * @param string $line A line from the YAML file
+ */
+ function _getIndent($line) {
+ $match = array();
+ preg_match('/^\s{1,}/',$line,$match);
+ if (!empty($match[0])) {
+ $indent = substr_count($match[0],' ');
+ } else {
+ $indent = 0;
+ }
+ return $indent;
+ }
+
+ /**
+ * Parses YAML code and returns an array for a node
+ * @access private
+ * @return array
+ * @param string $line A line from the YAML file
+ */
+ function _parseLine($line) {
+ $line = trim($line);
+
+ $array = array();
+
+ if (preg_match('/^-(.*):$/',$line)) {
+ // It's a mapped sequence
+ $key = trim(substr(substr($line,1),0,-1));
+ $array[$key] = '';
+ } elseif ($line[0] == '-' && substr($line,0,3) != '---') {
+ // It's a list item but not a new stream
+ if (strlen($line) > 1) {
+ $value = trim(substr($line,1));
+ // Set the type of the value. Int, string, etc
+ $value = $this->_toType($value);
+ $array[] = $value;
+ } else {
+ $array[] = array();
+ }
+ } elseif (preg_match('/^(.+):/',$line,$key)) {
+ // It's a key/value pair most likely
+ // If the key is in double quotes pull it out
+ $matches = array();
+ if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
+ $value = trim(str_replace($matches[1],'',$line));
+ $key = $matches[2];
+ } else {
+ // Do some guesswork as to the key and the value
+ $explode = explode(':',$line);
+ $key = trim($explode[0]);
+ array_shift($explode);
+ $value = trim(implode(':',$explode));
+ }
+
+ // Set the type of the value. Int, string, etc
+ $value = $this->_toType($value);
+ if (empty($key)) {
+ $array[] = $value;
+ } else {
+ $array[$key] = $value;
+ }
+ }
+ return $array;
+ }
+
+ /**
+ * Finds the type of the passed value, returns the value as the new type.
+ * @access private
+ * @param string $value
+ * @return mixed
+ */
+ function _toType($value) {
+ $matches = array();
+ if (preg_match('/^("(.*)"|\'(.*)\')/',$value,$matches)) {
+ $value = (string)preg_replace('/(\'\'|\\\\\')/',"'",end($matches));
+ $value = preg_replace('/\\\\"/','"',$value);
+ } elseif (preg_match('/^\\[(.+)\\]$/',$value,$matches)) {
+ // Inline Sequence
+
+ // Take out strings sequences and mappings
+ $explode = $this->_inlineEscape($matches[1]);
+
+ // Propogate value array
+ $value = array();
+ foreach ($explode as $v) {
+ $value[] = $this->_toType($v);
+ }
+ } elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) {
+ // It's a map
+ $array = explode(': ',$value);
+ $key = trim($array[0]);
+ array_shift($array);
+ $value = trim(implode(': ',$array));
+ $value = $this->_toType($value);
+ $value = array($key => $value);
+ } elseif (preg_match("/{(.+)}$/",$value,$matches)) {
+ // Inline Mapping
+
+ // Take out strings sequences and mappings
+ $explode = $this->_inlineEscape($matches[1]);
+
+ // Propogate value array
+ $array = array();
+ foreach ($explode as $v) {
+ $array = $array + $this->_toType($v);
+ }
+ $value = $array;
+ } elseif (strtolower($value) == 'null' or $value == '' or $value == '~') {
+ $value = NULL;
+ } elseif (ctype_digit($value)) {
+ $value = (int)$value;
+ } elseif (in_array(strtolower($value),
+ array('true', 'on', '+', 'yes', 'y'))) {
+ $value = TRUE;
+ } elseif (in_array(strtolower($value),
+ array('false', 'off', '-', 'no', 'n'))) {
+ $value = FALSE;
+ } elseif (is_numeric($value)) {
+ $value = (float)$value;
+ } else {
+ // Just a normal string, right?
+ $value = trim(preg_replace('/#(.+)$/','',$value));
+ }
+
+ return $value;
+ }
+
+ /**
+ * Used in inlines to check for more inlines or quoted strings
+ * @access private
+ * @return array
+ */
+ function _inlineEscape($inline) {
+ // There's gotta be a cleaner way to do this...
+ // While pure sequences seem to be nesting just fine,
+ // pure mappings and mappings with sequences inside can't go very
+ // deep. This needs to be fixed.
+
+ // Check for strings
+ $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
+ $strings = array();
+ if (preg_match_all($regex,$inline,$strings)) {
+ $saved_strings[] = $strings[0][0];
+ $inline = preg_replace($regex,'YAMLString',$inline);
+ }
+ unset($regex);
+
+ // Check for sequences
+ $seqs = array();
+ if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) {
+ $inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline);
+ $seqs = $seqs[0];
+ }
+
+ // Check for mappings
+ $maps = array();
+ if (preg_match_all('/{(.+)}/U',$inline,$maps)) {
+ $inline = preg_replace('/{(.+)}/U','YAMLMap',$inline);
+ $maps = $maps[0];
+ }
+
+ $explode = explode(', ',$inline);
+
+ // Re-add the strings
+ if (!empty($saved_strings)) {
+ $i = 0;
+ foreach ($explode as $key => $value) {
+ if (strpos($value,'YAMLString')) {
+ $explode[$key] = str_replace('YAMLString',$saved_strings[$i],$value);
+ ++$i;
+ }
+ }
+ }
+
+ // Re-add the sequences
+ if (!empty($seqs)) {
+ $i = 0;
+ foreach ($explode as $key => $value) {
+ if (strpos($value,'YAMLSeq') !== false) {
+ $explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value);
+ ++$i;
+ }
+ }
+ }
+
+ // Re-add the mappings
+ if (!empty($maps)) {
+ $i = 0;
+ foreach ($explode as $key => $value) {
+ if (strpos($value,'YAMLMap') !== false) {
+ $explode[$key] = str_replace('YAMLMap',$maps[$i],$value);
+ ++$i;
+ }
+ }
+ }
+
+ return $explode;
+ }
+
+ /**
+ * Builds the PHP array from all the YAML nodes we've gathered
+ * @access private
+ * @return array
+ */
+ function _buildArray() {
+ $trunk = array();
+
+ if (!isset($this->_indentSort[0])) {
+ return $trunk;
+ }
+
+ foreach ($this->_indentSort[0] as $n) {
+ if (empty($n->parent)) {
+ $this->_nodeArrayizeData($n);
+ // Check for references and copy the needed data to complete them.
+ $this->_makeReferences($n);
+ // Merge our data with the big array we're building
+ $trunk = $this->_array_kmerge($trunk,$n->data);
+ }
+ }
+
+ return $trunk;
+ }
+
+ /**
+ * Traverses node-space and sets references (& and *) accordingly
+ * @access private
+ * @return bool
+ */
+ function _linkReferences() {
+ if (is_array($this->_haveRefs)) {
+ foreach ($this->_haveRefs as $node) {
+ if (!empty($node->data)) {
+ $key = key($node->data);
+ // If it's an array, don't check.
+ if (is_array($node->data[$key])) {
+ foreach ($node->data[$key] as $k => $v) {
+ $this->_linkRef($node,$key,$k,$v);
+ }
+ } else {
+ $this->_linkRef($node,$key);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ function _linkRef(&$n,$key,$k = NULL,$v = NULL) {
+ if (empty($k) && empty($v)) {
+ // Look for &refs
+ $matches = array();
+ if (preg_match('/^&([^ ]+)/',$n->data[$key],$matches)) {
+ // Flag the node so we know it's a reference
+ $this->_allNodes[$n->id]->ref = substr($matches[0],1);
+ $this->_allNodes[$n->id]->data[$key] =
+ substr($n->data[$key],strlen($matches[0])+1);
+ // Look for *refs
+ } elseif (preg_match('/^\*([^ ]+)/',$n->data[$key],$matches)) {
+ $ref = substr($matches[0],1);
+ // Flag the node as having a reference
+ $this->_allNodes[$n->id]->refKey = $ref;
+ }
+ } elseif (!empty($k) && !empty($v)) {
+ if (preg_match('/^&([^ ]+)/',$v,$matches)) {
+ // Flag the node so we know it's a reference
+ $this->_allNodes[$n->id]->ref = substr($matches[0],1);
+ $this->_allNodes[$n->id]->data[$key][$k] =
+ substr($v,strlen($matches[0])+1);
+ // Look for *refs
+ } elseif (preg_match('/^\*([^ ]+)/',$v,$matches)) {
+ $ref = substr($matches[0],1);
+ // Flag the node as having a reference
+ $this->_allNodes[$n->id]->refKey = $ref;
+ }
+ }
+ }
+
+ /**
+ * Finds the children of a node and aids in the building of the PHP array
+ * @access private
+ * @param int $nid The id of the node whose children we're gathering
+ * @return array
+ */
+ function _gatherChildren($nid) {
+ $return = array();
+ $node =& $this->_allNodes[$nid];
+ foreach ($this->_allNodes as $z) {
+ if ($z->parent == $node->id) {
+ // We found a child
+ $this->_nodeArrayizeData($z);
+ // Check for references
+ $this->_makeReferences($z);
+ // Merge with the big array we're returning
+ // The big array being all the data of the children of our parent node
+ $return = $this->_array_kmerge($return,$z->data);
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Turns a node's data and its children's data into a PHP array
+ *
+ * @access private
+ * @param array $node The node which you want to arrayize
+ * @return boolean
+ */
+ function _nodeArrayizeData(&$node) {
+ if (is_array($node->data) && $node->children == true) {
+ // This node has children, so we need to find them
+ $childs = $this->_gatherChildren($node->id);
+ // We've gathered all our children's data and are ready to use it
+ $key = key($node->data);
+ $key = empty($key) ? 0 : $key;
+ // If it's an array, add to it of course
+ if (is_array($node->data[$key])) {
+ $node->data[$key] = $this->_array_kmerge($node->data[$key],$childs);
+ } else {
+ $node->data[$key] = $childs;
+ }
+ } elseif (!is_array($node->data) && $node->children == true) {
+ // Same as above, find the children of this node
+ $childs = $this->_gatherChildren($node->id);
+ $node->data = array();
+ $node->data[] = $childs;
+ }
+
+ // We edited $node by reference, so just return true
+ return true;
+ }
+
+ /**
+ * Traverses node-space and copies references to / from this object.
+ * @access private
+ * @param object $z A node whose references we wish to make real
+ * @return bool
+ */
+ function _makeReferences(&$z) {
+ // It is a reference
+ if (isset($z->ref)) {
+ $key = key($z->data);
+ // Copy the data to this object for easy retrieval later
+ $this->ref[$z->ref] =& $z->data[$key];
+ // It has a reference
+ } elseif (isset($z->refKey)) {
+ if (isset($this->ref[$z->refKey])) {
+ $key = key($z->data);
+ // Copy the data from this object to make the node a real reference
+ $z->data[$key] =& $this->ref[$z->refKey];
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Merges arrays and maintains numeric keys.
+ *
+ * An ever-so-slightly modified version of the array_kmerge() function posted
+ * to php.net by mail at nospam dot iaindooley dot com on 2004-04-08.
+ *
+ * http://us3.php.net/manual/en/function.array-merge.php#41394
+ *
+ * @access private
+ * @param array $arr1
+ * @param array $arr2
+ * @return array
+ */
+ function _array_kmerge($arr1,$arr2) {
+ if(!is_array($arr1))
+ $arr1 = array();
+
+ if(!is_array($arr2))
+ $arr2 = array();
+
+ $keys1 = array_keys($arr1);
+ $keys2 = array_keys($arr2);
+ $keys = array_merge($keys1,$keys2);
+ $vals1 = array_values($arr1);
+ $vals2 = array_values($arr2);
+ $vals = array_merge($vals1,$vals2);
+ $ret = array();
+
+ foreach($keys as $key) {
+ list( /* unused */ ,$val) = each($vals);
+ // This is the good part! If a key already exists, but it's part of a
+ // sequence (an int), just keep addin numbers until we find a fresh one.
+ if (isset($ret[$key]) and is_int($key)) {
+ while (array_key_exists($key, $ret)) {
+ $key++;
+ }
+ }
+ $ret[$key] = $val;
+ }
+
+ return $ret;
+ }
+ }
+?> \ No newline at end of file
diff --git a/includes/api/ApiHelp.php b/includes/api/ApiHelp.php
new file mode 100644
index 000000000000..07108ced2541
--- /dev/null
+++ b/includes/api/ApiHelp.php
@@ -0,0 +1,55 @@
+<?php
+
+
+/*
+ * Created on Sep 6, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+class ApiHelp extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ /**
+ * Stub module for displaying help when no parameters are given
+ */
+ public function execute() {
+ $this->dieUsage('', 'help');
+ }
+
+ protected function getDescription() {
+ return array (
+ 'Display this help screen.'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiLogin.php b/includes/api/ApiLogin.php
new file mode 100644
index 000000000000..954cd1974d15
--- /dev/null
+++ b/includes/api/ApiLogin.php
@@ -0,0 +1,122 @@
+<?php
+
+
+/*
+ * Created on Sep 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+class ApiLogin extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action, 'lg');
+ }
+
+ public function execute() {
+ $name = $password = $domain = null;
+ extract($this->extractRequestParams());
+
+ $params = new FauxRequest(array (
+ 'wpName' => $name,
+ 'wpPassword' => $password,
+ 'wpDomain' => $domain,
+ 'wpRemember' => ''
+ ));
+
+ $result = array ();
+
+ $loginForm = new LoginForm($params);
+ switch ($loginForm->authenticateUserData()) {
+ case LoginForm :: SUCCESS :
+ global $wgUser;
+
+ $wgUser->setOption('rememberpassword', 1);
+ $wgUser->setCookies();
+
+ $result['result'] = 'Success';
+ $result['lguserid'] = $_SESSION['wsUserID'];
+ $result['lgusername'] = $_SESSION['wsUserName'];
+ $result['lgtoken'] = $_SESSION['wsToken'];
+ break;
+
+ case LoginForm :: NO_NAME :
+ $result['result'] = 'NoName';
+ break;
+ case LoginForm :: ILLEGAL :
+ $result['result'] = 'Illegal';
+ break;
+ case LoginForm :: WRONG_PLUGIN_PASS :
+ $result['result'] = 'WrongPluginPass';
+ break;
+ case LoginForm :: NOT_EXISTS :
+ $result['result'] = 'NotExists';
+ break;
+ case LoginForm :: WRONG_PASS :
+ $result['result'] = 'WrongPass';
+ break;
+ case LoginForm :: EMPTY_PASS :
+ $result['result'] = 'EmptyPass';
+ break;
+ default :
+ ApiBase :: dieDebug(__METHOD__, 'Unhandled case value');
+ }
+
+ $this->getResult()->addValue(null, 'login', $result);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'name' => null,
+ 'password' => null,
+ 'domain' => null
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'name' => 'User Name',
+ 'password' => 'Password',
+ 'domain' => 'Domain (optional)'
+ );
+ }
+
+ protected function getDescription() {
+ return array (
+ 'This module is used to login and get the authentication tokens.'
+ );
+ }
+
+ protected function getExamples() {
+ return array(
+ 'api.php?action=login&lgname=user&lgpassword=password'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
new file mode 100644
index 000000000000..43d1da432160
--- /dev/null
+++ b/includes/api/ApiMain.php
@@ -0,0 +1,366 @@
+<?php
+
+
+/*
+ * Created on Sep 4, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+/**
+ * This is the main API class, used for both external and internal processing.
+ */
+class ApiMain extends ApiBase {
+
+ /**
+ * When no format parameter is given, this format will be used
+ */
+ const API_DEFAULT_FORMAT = 'xmlfm';
+
+ /**
+ * List of available modules: action name => module class
+ */
+ private static $Modules = array (
+ 'help' => 'ApiHelp',
+ 'login' => 'ApiLogin',
+ 'opensearch' => 'ApiOpenSearch',
+ 'feedwatchlist' => 'ApiFeedWatchlist',
+ 'query' => 'ApiQuery'
+ );
+
+ /**
+ * List of available formats: format name => format class
+ */
+ private static $Formats = array (
+ 'json' => 'ApiFormatJson',
+ 'jsonfm' => 'ApiFormatJson',
+ 'php' => 'ApiFormatPhp',
+ 'phpfm' => 'ApiFormatPhp',
+ 'wddx' => 'ApiFormatWddx',
+ 'wddxfm' => 'ApiFormatWddx',
+ 'xml' => 'ApiFormatXml',
+ 'xmlfm' => 'ApiFormatXml',
+ 'yaml' => 'ApiFormatYaml',
+ 'yamlfm' => 'ApiFormatYaml',
+ 'rawfm' => 'ApiFormatJson'
+ );
+
+ private $mPrinter, $mModules, $mModuleNames, $mFormats, $mFormatNames;
+ private $mResult, $mShowVersions, $mEnableWrite, $mRequest, $mInternalMode, $mSquidMaxage;
+
+ /**
+ * Constructor
+ * @param $request object - if this is an instance of FauxRequest, errors are thrown and no printing occurs
+ * @param $enableWrite bool should be set to true if the api may modify data
+ */
+ public function __construct($request, $enableWrite = false) {
+
+ $this->mInternalMode = ($request instanceof FauxRequest);
+
+ // Special handling for the main module: $parent === $this
+ parent :: __construct($this, $this->mInternalMode ? 'main_int' : 'main');
+
+ $this->mModules = self :: $Modules;
+ $this->mModuleNames = array_keys($this->mModules); // todo: optimize
+ $this->mFormats = self :: $Formats;
+ $this->mFormatNames = array_keys($this->mFormats); // todo: optimize
+
+ $this->mResult = new ApiResult($this);
+ $this->mShowVersions = false;
+ $this->mEnableWrite = $enableWrite;
+
+ $this->mRequest = & $request;
+
+ $this->mSquidMaxage = 0;
+ }
+
+ public function & getRequest() {
+ return $this->mRequest;
+ }
+
+ public function getResult() {
+ return $this->mResult;
+ }
+
+ public function requestWriteMode() {
+ if (!$this->mEnableWrite)
+ $this->dieUsage('Editing of this site is disabled. Make sure the $wgEnableWriteAPI=true; ' .
+ 'statement is included in the site\'s LocalSettings.php file', 'readonly');
+ }
+
+ public function setCacheMaxAge($maxage) {
+ $this->mSquidMaxage = $maxage;
+ }
+
+ public function createPrinterByName($format) {
+ return new $this->mFormats[$format] ($this, $format);
+ }
+
+ public function execute() {
+ $this->profileIn();
+ if ($this->mInternalMode)
+ $this->executeAction();
+ else
+ $this->executeActionWithErrorHandling();
+ $this->profileOut();
+ }
+
+ protected function executeActionWithErrorHandling() {
+
+ // In case an error occurs during data output,
+ // this clear the output buffer and print just the error information
+ ob_start();
+
+ try {
+ $this->executeAction();
+ } catch (Exception $e) {
+ //
+ // Handle any kind of exception by outputing properly formatted error message.
+ // If this fails, an unhandled exception should be thrown so that global error
+ // handler will process and log it.
+ //
+
+ // Error results should not be cached
+ $this->setCacheMaxAge(0);
+
+ // Printer may not be initialized if the extractRequestParams() fails for the main module
+ if (!isset ($this->mPrinter)) {
+ $this->mPrinter = $this->createPrinterByName(self :: API_DEFAULT_FORMAT);
+ if ($this->mPrinter->getNeedsRawData())
+ $this->getResult()->setRawMode();
+ }
+
+ if ($e instanceof UsageException) {
+ //
+ // User entered incorrect parameters - print usage screen
+ //
+ $errMessage = array (
+ 'code' => $e->getCodeString(), 'info' => $e->getMessage());
+ ApiResult :: setContent($errMessage, $this->makeHelpMsg());
+
+ } else {
+ //
+ // Something is seriously wrong
+ //
+ $errMessage = array (
+ 'code' => 'internal_api_error',
+ 'info' => "Exception Caught: {$e->getMessage()}"
+ );
+ ApiResult :: setContent($errMessage, "\n\n{$e->getTraceAsString()}\n\n");
+ }
+
+ $headerStr = 'MediaWiki-API-Error: ' . $errMessage['code'];
+ if ($e->getCode() === 0)
+ header($headerStr, true);
+ else
+ header($headerStr, true, $e->getCode());
+
+ // Reset and print just the error message
+ ob_clean();
+ $this->getResult()->reset();
+ $this->getResult()->addValue(null, 'error', $errMessage);
+
+ // If the error occured during printing, do a printer->profileOut()
+ $this->mPrinter->safeProfileOut();
+ $this->printResult(true);
+ }
+
+ // Set the cache expiration at the last moment, as any errors may change the expiration.
+ // if $this->mSquidMaxage == 0, the expiry time is set to the first second of unix epoch
+ $expires = $this->mSquidMaxage == 0 ? 1 : time() + $this->mSquidMaxage;
+ header('Expires: ' . wfTimestamp(TS_RFC2822, $expires));
+ header('Cache-Control: s-maxage=' . $this->mSquidMaxage . ', must-revalidate, max-age=0');
+
+ ob_end_flush();
+ }
+
+ /**
+ * Execute the actual module, without any error handling
+ */
+ protected function executeAction() {
+ $action = $format = $version = null;
+ extract($this->extractRequestParams());
+ $this->mShowVersions = $version;
+
+ // Instantiate the module requested by the user
+ $module = new $this->mModules[$action] ($this, $action);
+
+ if (!$this->mInternalMode) {
+
+ // See if custom printer is used
+ $this->mPrinter = $module->getCustomPrinter();
+ if (is_null($this->mPrinter)) {
+ // Create an appropriate printer
+ $this->mPrinter = $this->createPrinterByName($format);
+ }
+
+ if ($this->mPrinter->getNeedsRawData())
+ $this->getResult()->setRawMode();
+ }
+
+ // Execute
+ $module->profileIn();
+ $module->execute();
+ $module->profileOut();
+
+ if (!$this->mInternalMode) {
+ // Print result data
+ $this->printResult(false);
+ }
+ }
+
+ /**
+ * Internal printer
+ */
+ protected function printResult($isError) {
+ $printer = $this->mPrinter;
+ $printer->profileIn();
+ $printer->initPrinter($isError);
+ $printer->execute();
+ $printer->closePrinter();
+ $printer->profileOut();
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'format' => array (
+ ApiBase :: PARAM_DFLT => ApiMain :: API_DEFAULT_FORMAT,
+ ApiBase :: PARAM_TYPE => $this->mFormatNames
+ ),
+ 'action' => array (
+ ApiBase :: PARAM_DFLT => 'help',
+ ApiBase :: PARAM_TYPE => $this->mModuleNames
+ ),
+ 'version' => false
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'format' => 'The format of the output',
+ 'action' => 'What action you would like to perform',
+ 'version' => 'When showing help, include version for each module'
+ );
+ }
+
+ protected function getDescription() {
+ return array (
+ '',
+ 'This API allows programs to access various functions of MediaWiki software.',
+ 'For more details see API Home Page @ http://meta.wikimedia.org/wiki/API',
+ '',
+ 'Status: ALPHA -- all features shown on this page should be working,',
+ ' but the API is still in active development, and may change at any time.',
+ ' Make sure you monitor changes to this page, wikitech-l mailing list,',
+ ' or the source code in the includes/api directory for any changes.',
+ ''
+ );
+ }
+
+ protected function getCredits() {
+ return array(
+ 'This API is being implemented by Yuri Astrakhan [[User:Yurik]] / FirstnameLastname@gmail.com',
+ 'Please leave your comments and suggestions at http://meta.wikimedia.org/wiki/API'
+ );
+ }
+
+ /**
+ * Override the parent to generate help messages for all available modules.
+ */
+ public function makeHelpMsg() {
+
+ // Use parent to make default message for the main module
+ $msg = parent :: makeHelpMsg();
+
+ $astriks = str_repeat('*** ', 10);
+ $msg .= "\n\n$astriks Modules $astriks\n\n";
+ foreach( $this->mModules as $moduleName => $unused ) {
+ $msg .= "* action=$moduleName *";
+ $module = new $this->mModules[$moduleName] ($this, $moduleName);
+ $msg2 = $module->makeHelpMsg();
+ if ($msg2 !== false)
+ $msg .= $msg2;
+ $msg .= "\n";
+ }
+
+ $msg .= "\n$astriks Formats $astriks\n\n";
+ foreach( $this->mFormats as $formatName => $unused ) {
+ $msg .= "* format=$formatName *";
+ $module = $this->createPrinterByName($formatName);
+ $msg2 = $module->makeHelpMsg();
+ if ($msg2 !== false)
+ $msg .= $msg2;
+ $msg .= "\n";
+ }
+
+ $msg .= "\n*** Credits: ***\n " . implode("\n ", $this->getCredits()) . "\n";
+
+
+ return $msg;
+ }
+
+ private $mIsBot = null;
+ public function isBot() {
+ if (!isset ($this->mIsBot)) {
+ global $wgUser;
+ $this->mIsBot = $wgUser->isAllowed('bot');
+ }
+ return $this->mIsBot;
+ }
+
+ public function getShowVersions() {
+ return $this->mShowVersions;
+ }
+
+ public function getVersion() {
+ $vers = array ();
+ $vers[] = __CLASS__ . ': $Id$';
+ $vers[] = ApiBase :: getBaseVersion();
+ $vers[] = ApiFormatBase :: getBaseVersion();
+ $vers[] = ApiQueryBase :: getBaseVersion();
+ $vers[] = ApiFormatFeedWrapper :: getVersion(); // not accessible with format=xxx
+ return $vers;
+ }
+}
+
+/**
+* @desc This exception will be thrown when dieUsage is called to stop module execution.
+*/
+class UsageException extends Exception {
+
+ private $mCodestr;
+
+ public function __construct($message, $codestr, $code = 0) {
+ parent :: __construct($message, $code);
+ $this->mCodestr = $codestr;
+ }
+ public function getCodeString() {
+ return $this->mCodestr;
+ }
+ public function __toString() {
+ return "{$this->getCodeString()}: {$this->getMessage()}";
+ }
+}
+?>
diff --git a/includes/api/ApiOpenSearch.php b/includes/api/ApiOpenSearch.php
new file mode 100644
index 000000000000..3bbcf4e24dcf
--- /dev/null
+++ b/includes/api/ApiOpenSearch.php
@@ -0,0 +1,109 @@
+<?php
+
+
+/*
+ * Created on Oct 13, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+class ApiOpenSearch extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function getCustomPrinter() {
+ return $this->getMain()->createPrinterByName('json');
+ }
+
+ public function execute() {
+ $search = null;
+ extract($this->ExtractRequestParams());
+
+ // Open search results may be stored for a very long time
+ $this->getMain()->setCacheMaxAge(1200);
+
+ $title = Title :: newFromText($search);
+ if(!$title)
+ return; // Return empty result
+
+ // Prepare nested request
+ $params = new FauxRequest(array (
+ 'action' => 'query',
+ 'list' => 'allpages',
+ 'apnamespace' => $title->getNamespace(),
+ 'aplimit' => 10,
+ 'apprefix' => $title->getDBkey()
+ ));
+
+ // Execute
+ $module = new ApiMain($params);
+ $module->execute();
+
+ // Get resulting data
+ $data = $module->getResultData();
+
+ // Reformat useful data for future printing by JSON engine
+ $srchres = array ();
+ foreach ($data['query']['allpages'] as & $pageinfo) {
+ // Note: this data will no be printable by the xml engine
+ // because it does not support lists of unnamed items
+ $srchres[] = $pageinfo['title'];
+ }
+
+ // Set top level elements
+ $result = $this->getResult();
+ $result->addValue(null, 0, $search);
+ $result->addValue(null, 1, $srchres);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'search' => null
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'search' => 'Search string'
+ );
+ }
+
+ protected function getDescription() {
+ return 'This module implements OpenSearch protocol';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=opensearch&search=Te'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php
new file mode 100644
index 000000000000..c1009ea4a200
--- /dev/null
+++ b/includes/api/ApiPageSet.php
@@ -0,0 +1,598 @@
+<?php
+
+
+/*
+ * Created on Sep 24, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiPageSet extends ApiQueryBase {
+
+ private $mAllPages; // [ns][dbkey] => page_id or 0 when missing
+ private $mTitles, $mGoodTitles, $mMissingTitles, $mMissingPageIDs, $mRedirectTitles, $mNormalizedTitles;
+ private $mResolveRedirects, $mPendingRedirectIDs;
+ private $mGoodRevIDs, $mMissingRevIDs;
+
+ private $mRequestedPageFields;
+
+ public function __construct($query, $resolveRedirects = false) {
+ parent :: __construct($query, __CLASS__);
+
+ $this->mAllPages = array ();
+ $this->mTitles = array();
+ $this->mGoodTitles = array ();
+ $this->mMissingTitles = array ();
+ $this->mMissingPageIDs = array ();
+ $this->mRedirectTitles = array ();
+ $this->mNormalizedTitles = array ();
+ $this->mGoodRevIDs = array();
+ $this->mMissingRevIDs = array();
+
+ $this->mRequestedPageFields = array ();
+ $this->mResolveRedirects = $resolveRedirects;
+ if($resolveRedirects)
+ $this->mPendingRedirectIDs = array();
+ }
+
+ public function isResolvingRedirects() {
+ return $this->mResolveRedirects;
+ }
+
+ public function requestField($fieldName) {
+ $this->mRequestedPageFields[$fieldName] = null;
+ }
+
+ public function getCustomField($fieldName) {
+ return $this->mRequestedPageFields[$fieldName];
+ }
+
+ /**
+ * Get fields that modules have requested from the page table
+ */
+ public function getPageTableFields() {
+ // Ensure we get minimum required fields
+ $pageFlds = array (
+ 'page_id' => null,
+ 'page_namespace' => null,
+ 'page_title' => null
+ );
+
+ // only store non-default fields
+ $this->mRequestedPageFields = array_diff_key($this->mRequestedPageFields, $pageFlds);
+
+ if ($this->mResolveRedirects)
+ $pageFlds['page_is_redirect'] = null;
+
+ return array_keys(array_merge($pageFlds, $this->mRequestedPageFields));
+ }
+
+ /**
+ * All Title objects provided.
+ * @return array of Title objects
+ */
+ public function getTitles() {
+ return $this->mTitles;
+ }
+
+ /**
+ * Returns the number of unique pages (not revisions) in the set.
+ */
+ public function getTitleCount() {
+ return count($this->mTitles);
+ }
+
+ /**
+ * Title objects that were found in the database.
+ * @return array page_id (int) => Title (obj)
+ */
+ public function getGoodTitles() {
+ return $this->mGoodTitles;
+ }
+
+ /**
+ * Returns the number of found unique pages (not revisions) in the set.
+ */
+ public function getGoodTitleCount() {
+ return count($this->mGoodTitles);
+ }
+
+ /**
+ * Title objects that were NOT found in the database.
+ * @return array of Title objects
+ */
+ public function getMissingTitles() {
+ return $this->mMissingTitles;
+ }
+
+ /**
+ * Page IDs that were not found in the database
+ * @return array of page IDs
+ */
+ public function getMissingPageIDs() {
+ return $this->mMissingPageIDs;
+ }
+
+ /**
+ * Get a list of redirects when doing redirect resolution
+ * @return array prefixed_title (string) => prefixed_title (string)
+ */
+ public function getRedirectTitles() {
+ return $this->mRedirectTitles;
+ }
+
+ /**
+ * Get a list of title normalizations - maps the title given
+ * with its normalized version.
+ * @return array raw_prefixed_title (string) => prefixed_title (string)
+ */
+ public function getNormalizedTitles() {
+ return $this->mNormalizedTitles;
+ }
+
+ /**
+ * Get the list of revision IDs (requested with revids= parameter)
+ * @return array revID (int) => pageID (int)
+ */
+ public function getRevisionIDs() {
+ return $this->mGoodRevIDs;
+ }
+
+ /**
+ * Revision IDs that were not found in the database
+ * @return array of revision IDs
+ */
+ public function getMissingRevisionIDs() {
+ return $this->mMissingRevIDs;
+ }
+
+ /**
+ * Returns the number of revisions (requested with revids= parameter)
+ */
+ public function getRevisionCount() {
+ return count($this->getRevisionIDs());
+ }
+
+ /**
+ * Populate from the request parameters
+ */
+ public function execute() {
+ $this->profileIn();
+ $titles = $pageids = $revids = null;
+ extract($this->extractRequestParams());
+
+ // Only one of the titles/pageids/revids is allowed at the same time
+ $dataSource = null;
+ if (isset ($titles))
+ $dataSource = 'titles';
+ if (isset ($pageids)) {
+ if (isset ($dataSource))
+ $this->dieUsage("Cannot use 'pageids' at the same time as '$dataSource'", 'multisource');
+ $dataSource = 'pageids';
+ }
+ if (isset ($revids)) {
+ if (isset ($dataSource))
+ $this->dieUsage("Cannot use 'revids' at the same time as '$dataSource'", 'multisource');
+ $dataSource = 'revids';
+ }
+
+ switch ($dataSource) {
+ case 'titles' :
+ $this->initFromTitles($titles);
+ break;
+ case 'pageids' :
+ $this->initFromPageIds($pageids);
+ break;
+ case 'revids' :
+ if($this->mResolveRedirects)
+ $this->dieUsage('revids may not be used with redirect resolution', 'params');
+ $this->initFromRevIDs($revids);
+ break;
+ default :
+ // Do nothing - some queries do not need any of the data sources.
+ break;
+ }
+ $this->profileOut();
+ }
+
+ /**
+ * Initialize PageSet from a list of Titles
+ */
+ public function populateFromTitles($titles) {
+ $this->profileIn();
+ $this->initFromTitles($titles);
+ $this->profileOut();
+ }
+
+ /**
+ * Initialize PageSet from a list of Page IDs
+ */
+ public function populateFromPageIDs($pageIDs) {
+ $this->profileIn();
+ $pageIDs = array_map('intval', $pageIDs); // paranoia
+ $this->initFromPageIds($pageIDs);
+ $this->profileOut();
+ }
+
+ /**
+ * Initialize PageSet from a rowset returned from the database
+ */
+ public function populateFromQueryResult($db, $queryResult) {
+ $this->profileIn();
+ $this->initFromQueryResult($db, $queryResult);
+ $this->profileOut();
+ }
+
+ /**
+ * Initialize PageSet from a list of Revision IDs
+ */
+ public function populateFromRevisionIDs($revIDs) {
+ $this->profileIn();
+ $revIDs = array_map('intval', $revIDs); // paranoia
+ $this->initFromRevIDs($revIDs);
+ $this->profileOut();
+ }
+
+ /**
+ * Extract all requested fields from the row received from the database
+ */
+ public function processDbRow($row) {
+
+ // Store Title object in various data structures
+ $title = Title :: makeTitle($row->page_namespace, $row->page_title);
+
+ // skip any pages that user has no rights to read
+ if ($title->userCanRead()) {
+
+ $pageId = intval($row->page_id);
+ $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
+ $this->mTitles[] = $title;
+
+ if ($this->mResolveRedirects && $row->page_is_redirect == '1') {
+ $this->mPendingRedirectIDs[$pageId] = $title;
+ } else {
+ $this->mGoodTitles[$pageId] = $title;
+ }
+
+ foreach ($this->mRequestedPageFields as $fieldName => & $fieldValues)
+ $fieldValues[$pageId] = $row-> $fieldName;
+ }
+ }
+
+ public function finishPageSetGeneration() {
+ $this->profileIn();
+ $this->resolvePendingRedirects();
+ $this->profileOut();
+ }
+
+ /**
+ * This method populates internal variables with page information
+ * based on the given array of title strings.
+ *
+ * Steps:
+ * #1 For each title, get data from `page` table
+ * #2 If page was not found in the DB, store it as missing
+ *
+ * Additionally, when resolving redirects:
+ * #3 If no more redirects left, stop.
+ * #4 For each redirect, get its links from `pagelinks` table.
+ * #5 Substitute the original LinkBatch object with the new list
+ * #6 Repeat from step #1
+ */
+ private function initFromTitles($titles) {
+
+ // Get validated and normalized title objects
+ $linkBatch = $this->processTitlesStrArray($titles);
+ if($linkBatch->isEmpty())
+ return;
+
+ $db = & $this->getDB();
+ $set = $linkBatch->constructSet('page', $db);
+
+ // Get pageIDs data from the `page` table
+ $this->profileDBIn();
+ $res = $db->select('page', $this->getPageTableFields(), $set, __METHOD__);
+ $this->profileDBOut();
+
+ // Hack: get the ns:titles stored in array(ns => array(titles)) format
+ $this->initFromQueryResult($db, $res, $linkBatch->data, true); // process Titles
+
+ // Resolve any found redirects
+ $this->resolvePendingRedirects();
+ }
+
+ private function initFromPageIds($pageids) {
+ if(empty($pageids))
+ return;
+
+ $set = array (
+ 'page_id' => $pageids
+ );
+
+ $db = & $this->getDB();
+
+ // Get pageIDs data from the `page` table
+ $this->profileDBIn();
+ $res = $db->select('page', $this->getPageTableFields(), $set, __METHOD__);
+ $this->profileDBOut();
+
+ $this->initFromQueryResult($db, $res, array_flip($pageids), false); // process PageIDs
+
+ // Resolve any found redirects
+ $this->resolvePendingRedirects();
+ }
+
+ /**
+ * Iterate through the result of the query on 'page' table,
+ * and for each row create and store title object and save any extra fields requested.
+ * @param $db Database
+ * @param $res DB Query result
+ * @param $remaining Array of either pageID or ns/title elements (optional).
+ * If given, any missing items will go to $mMissingPageIDs and $mMissingTitles
+ * @param $processTitles bool Must be provided together with $remaining.
+ * If true, treat $remaining as an array of [ns][title]
+ * If false, treat it as an array of [pageIDs]
+ * @return Array of redirect IDs (only when resolving redirects)
+ */
+ private function initFromQueryResult($db, $res, &$remaining = null, $processTitles = null) {
+ if (!is_null($remaining) && is_null($processTitles))
+ ApiBase :: dieDebug(__METHOD__, 'Missing $processTitles parameter when $remaining is provided');
+
+ while ($row = $db->fetchObject($res)) {
+
+ $pageId = intval($row->page_id);
+
+ // Remove found page from the list of remaining items
+ if (isset($remaining)) {
+ if ($processTitles)
+ unset ($remaining[$row->page_namespace][$row->page_title]);
+ else
+ unset ($remaining[$pageId]);
+ }
+
+ // Store any extra fields requested by modules
+ $this->processDbRow($row);
+ }
+ $db->freeResult($res);
+
+ if(isset($remaining)) {
+ // Any items left in the $remaining list are added as missing
+ if($processTitles) {
+ // The remaining titles in $remaining are non-existant pages
+ foreach ($remaining as $ns => $dbkeys) {
+ foreach ( $dbkeys as $dbkey => $unused ) {
+ $title = Title :: makeTitle($ns, $dbkey);
+ $this->mMissingTitles[] = $title;
+ $this->mAllPages[$ns][$dbkey] = 0;
+ $this->mTitles[] = $title;
+ }
+ }
+ }
+ else
+ {
+ // The remaining pageids do not exist
+ if(empty($this->mMissingPageIDs))
+ $this->mMissingPageIDs = array_keys($remaining);
+ else
+ $this->mMissingPageIDs = array_merge($this->mMissingPageIDs, array_keys($remaining));
+ }
+ }
+ }
+
+ private function initFromRevIDs($revids) {
+
+ if(empty($revids))
+ return;
+
+ $db = & $this->getDB();
+ $pageids = array();
+ $remaining = array_flip($revids);
+
+ $tables = array('revision');
+ $fields = array('rev_id','rev_page');
+ $where = array('rev_deleted' => 0, 'rev_id' => $revids);
+
+ // Get pageIDs data from the `page` table
+ $this->profileDBIn();
+ $res = $db->select( $tables, $fields, $where, __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
+ $revid = intval($row->rev_id);
+ $pageid = intval($row->rev_page);
+ $this->mGoodRevIDs[$revid] = $pageid;
+ $pageids[$pageid] = '';
+ unset($remaining[$revid]);
+ }
+ $db->freeResult( $res );
+ $this->profileDBOut();
+
+ $this->mMissingRevIDs = array_keys($remaining);
+
+ // Populate all the page information
+ if($this->mResolveRedirects)
+ ApiBase :: dieDebug(__METHOD__, 'revids may not be used with redirect resolution');
+ $this->initFromPageIds(array_keys($pageids));
+ }
+
+ private function resolvePendingRedirects() {
+
+ if($this->mResolveRedirects) {
+ $db = & $this->getDB();
+ $pageFlds = $this->getPageTableFields();
+
+ // Repeat until all redirects have been resolved
+ // The infinite loop is prevented by keeping all known pages in $this->mAllPages
+ while (!empty ($this->mPendingRedirectIDs)) {
+
+ // Resolve redirects by querying the pagelinks table, and repeat the process
+ // Create a new linkBatch object for the next pass
+ $linkBatch = $this->getRedirectTargets();
+
+ if ($linkBatch->isEmpty())
+ break;
+
+ $set = $linkBatch->constructSet('page', $db);
+ if(false === $set)
+ break;
+
+ // Get pageIDs data from the `page` table
+ $this->profileDBIn();
+ $res = $db->select('page', $pageFlds, $set, __METHOD__);
+ $this->profileDBOut();
+
+ // Hack: get the ns:titles stored in array(ns => array(titles)) format
+ $this->initFromQueryResult($db, $res, $linkBatch->data, true);
+ }
+ }
+ }
+
+ private function getRedirectTargets() {
+
+ $linkBatch = new LinkBatch();
+ $db = & $this->getDB();
+
+ // find redirect targets for all redirect pages
+ $this->profileDBIn();
+ $res = $db->select('pagelinks', array (
+ 'pl_from',
+ 'pl_namespace',
+ 'pl_title'
+ ), array (
+ 'pl_from' => array_keys($this->mPendingRedirectIDs
+ )), __METHOD__);
+ $this->profileDBOut();
+
+ while ($row = $db->fetchObject($res)) {
+
+ $plfrom = intval($row->pl_from);
+
+ // Bug 7304 workaround
+ // ( http://bugzilla.wikipedia.org/show_bug.cgi?id=7304 )
+ // A redirect page may have more than one link.
+ // This code will only use the first link returned.
+ if (isset ($this->mPendingRedirectIDs[$plfrom])) { // remove line when bug 7304 is fixed
+
+ $titleStrFrom = $this->mPendingRedirectIDs[$plfrom]->getPrefixedText();
+ $titleStrTo = Title :: makeTitle($row->pl_namespace, $row->pl_title)->getPrefixedText();
+ unset ($this->mPendingRedirectIDs[$plfrom]); // remove line when bug 7304 is fixed
+
+ // Avoid an infinite loop by checking if we have already processed this target
+ if (!isset ($this->mAllPages[$row->pl_namespace][$row->pl_title])) {
+ $linkBatch->add($row->pl_namespace, $row->pl_title);
+ }
+ } else {
+ // This redirect page has more than one link.
+ // This is very slow, but safer until bug 7304 is resolved
+ $title = Title :: newFromID($plfrom);
+ $titleStrFrom = $title->getPrefixedText();
+
+ $article = new Article($title);
+ $text = $article->getContent();
+ $titleTo = Title :: newFromRedirect($text);
+ $titleStrTo = $titleTo->getPrefixedText();
+
+ if (is_null($titleStrTo))
+ ApiBase :: dieDebug(__METHOD__, 'Bug7304 workaround: redir target from {$title->getPrefixedText()} not found');
+
+ // Avoid an infinite loop by checking if we have already processed this target
+ if (!isset ($this->mAllPages[$titleTo->getNamespace()][$titleTo->getDBkey()])) {
+ $linkBatch->addObj($titleTo);
+ }
+ }
+
+ $this->mRedirectTitles[$titleStrFrom] = $titleStrTo;
+ }
+ $db->freeResult($res);
+
+ // All IDs must exist in the page table
+ if (!empty($this->mPendingRedirectIDs[$plfrom]))
+ ApiBase :: dieDebug(__METHOD__, 'Invalid redirect IDs were found');
+
+ return $linkBatch;
+ }
+
+ /**
+ * Given an array of title strings, convert them into Title objects.
+ * This method validates access rights for the title,
+ * and appends normalization values to the output.
+ *
+ * @return LinkBatch of title objects.
+ */
+ private function processTitlesStrArray($titles) {
+
+ $linkBatch = new LinkBatch();
+
+ foreach ($titles as $titleString) {
+ $titleObj = Title :: newFromText($titleString);
+
+ // Validation
+ if (!$titleObj)
+ $this->dieUsage("bad title $titleString", 'invalidtitle');
+ if ($titleObj->getNamespace() < 0)
+ $this->dieUsage("No support for special page $titleString has been implemented", 'unsupportednamespace');
+ if (!$titleObj->userCanRead())
+ $this->dieUsage("No read permission for $titleString", 'titleaccessdenied');
+
+ $linkBatch->addObj($titleObj);
+
+ // Make sure we remember the original title that was given to us
+ // This way the caller can correlate new titles with the originally requested,
+ // i.e. namespace is localized or capitalization is different
+ if ($titleString !== $titleObj->getPrefixedText()) {
+ $this->mNormalizedTitles[$titleString] = $titleObj->getPrefixedText();
+ }
+ }
+
+ return $linkBatch;
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'titles' => array (
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'pageids' => array (
+ ApiBase :: PARAM_TYPE => 'integer',
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'revids' => array (
+ ApiBase :: PARAM_TYPE => 'integer',
+ ApiBase :: PARAM_ISMULTI => true
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'titles' => 'A list of titles to work on',
+ 'pageids' => 'A list of page IDs to work on',
+ 'revids' => 'A list of revision IDs to work on'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php
new file mode 100644
index 000000000000..d58cc5cae606
--- /dev/null
+++ b/includes/api/ApiQuery.php
@@ -0,0 +1,378 @@
+<?php
+
+
+/*
+ * Created on Sep 7, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+class ApiQuery extends ApiBase {
+
+ private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
+ private $mPageSet;
+
+ private $mQueryPropModules = array (
+ 'info' => 'ApiQueryInfo',
+ 'revisions' => 'ApiQueryRevisions'
+ );
+ // 'categories' => 'ApiQueryCategories',
+ // 'imageinfo' => 'ApiQueryImageinfo',
+ // 'langlinks' => 'ApiQueryLanglinks',
+ // 'links' => 'ApiQueryLinks',
+ // 'templates' => 'ApiQueryTemplates',
+
+ private $mQueryListModules = array (
+ 'allpages' => 'ApiQueryAllpages',
+ 'logevents' => 'ApiQueryLogEvents',
+ 'watchlist' => 'ApiQueryWatchlist',
+ 'recentchanges' => 'ApiQueryRecentChanges',
+ 'backlinks' => 'ApiQueryBacklinks',
+ 'embeddedin' => 'ApiQueryBacklinks',
+ 'imagelinks' => 'ApiQueryBacklinks',
+ 'usercontribs' => 'ApiQueryContributions'
+ );
+ // 'categorymembers' => 'ApiQueryCategorymembers',
+ // 'embeddedin' => 'ApiQueryEmbeddedin',
+ // 'imagelinks' => 'ApiQueryImagelinks',
+ // 'recentchanges' => 'ApiQueryRecentchanges',
+ // 'users' => 'ApiQueryUsers',
+ // 'watchlist' => 'ApiQueryWatchlist',
+
+ private $mQueryMetaModules = array (
+ 'siteinfo' => 'ApiQuerySiteinfo'
+ );
+ // 'userinfo' => 'ApiQueryUserinfo',
+
+ private $mSlaveDB = null;
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ $this->mPropModuleNames = array_keys($this->mQueryPropModules);
+ $this->mListModuleNames = array_keys($this->mQueryListModules);
+ $this->mMetaModuleNames = array_keys($this->mQueryMetaModules);
+
+ // Allow the entire list of modules at first,
+ // but during module instantiation check if it can be used as a generator.
+ $this->mAllowedGenerators = array_merge($this->mListModuleNames, $this->mPropModuleNames);
+ }
+
+ public function & getDB() {
+ if (!isset ($this->mSlaveDB)) {
+ $this->profileDBIn();
+ $this->mSlaveDB = & wfGetDB(DB_SLAVE);
+ $this->profileDBOut();
+ }
+ return $this->mSlaveDB;
+ }
+
+ public function getPageSet() {
+ return $this->mPageSet;
+ }
+
+ /**
+ * Query execution happens in the following steps:
+ * #1 Create a PageSet object with any pages requested by the user
+ * #2 If using generator, execute it to get a new PageSet object
+ * #3 Instantiate all requested modules.
+ * This way the PageSet object will know what shared data is required,
+ * and minimize DB calls.
+ * #4 Output all normalization and redirect resolution information
+ * #5 Execute all requested modules
+ */
+ public function execute() {
+ $prop = $list = $meta = $generator = $redirects = null;
+ extract($this->extractRequestParams());
+
+ //
+ // Create PageSet
+ //
+ $this->mPageSet = new ApiPageSet($this, $redirects);
+
+ // Instantiate required modules
+ $modules = array ();
+ if (isset ($prop))
+ foreach ($prop as $moduleName)
+ $modules[] = new $this->mQueryPropModules[$moduleName] ($this, $moduleName);
+ if (isset ($list))
+ foreach ($list as $moduleName)
+ $modules[] = new $this->mQueryListModules[$moduleName] ($this, $moduleName);
+ if (isset ($meta))
+ foreach ($meta as $moduleName)
+ $modules[] = new $this->mQueryMetaModules[$moduleName] ($this, $moduleName);
+
+ // Modules may optimize data requests through the $this->getPageSet() object
+ // Execute all requested modules.
+ foreach ($modules as $module) {
+ $module->requestExtraData();
+ }
+
+ //
+ // If given, execute generator to substitute user supplied data with generated data.
+ //
+ if (isset ($generator))
+ $this->executeGeneratorModule($generator, $redirects);
+
+ //
+ // Populate page information for the given pageSet
+ //
+ $this->mPageSet->execute();
+
+ //
+ // Record page information (title, namespace, if exists, etc)
+ //
+ $this->outputGeneralPageInfo();
+
+ //
+ // Execute all requested modules.
+ //
+ foreach ($modules as $module) {
+ $module->profileIn();
+ $module->execute();
+ $module->profileOut();
+ }
+ }
+
+ private function outputGeneralPageInfo() {
+
+ $pageSet = $this->getPageSet();
+ $result = $this->getResult();
+
+ // Title normalizations
+ $normValues = array ();
+ foreach ($pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr) {
+ $normValues[] = array (
+ 'from' => $rawTitleStr,
+ 'to' => $titleStr
+ );
+ }
+
+ if (!empty ($normValues)) {
+ $result->setIndexedTagName($normValues, 'n');
+ $result->addValue('query', 'normalized', $normValues);
+ }
+
+ // Show redirect information
+ $redirValues = array ();
+ foreach ($pageSet->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
+ $redirValues[] = array (
+ 'from' => $titleStrFrom,
+ 'to' => $titleStrTo
+ );
+ }
+
+ if (!empty ($redirValues)) {
+ $result->setIndexedTagName($redirValues, 'r');
+ $result->addValue('query', 'redirects', $redirValues);
+ }
+
+ //
+ // Missing revision elements
+ //
+ $missingRevIDs = $pageSet->getMissingRevisionIDs();
+ if (!empty ($missingRevIDs)) {
+ $revids = array ();
+ foreach ($missingRevIDs as $revid) {
+ $revids[$revid] = array (
+ 'revid' => $revid
+ );
+ }
+ $result->setIndexedTagName($revids, 'rev');
+ $result->addValue('query', 'badrevids', $revids);
+ }
+
+ //
+ // Page elements
+ //
+ $pages = array ();
+
+ // Report any missing titles
+ $fakepageid = -1;
+ foreach ($pageSet->getMissingTitles() as $title) {
+ $pages[$fakepageid--] = array (
+ 'ns' => $title->getNamespace(), 'title' => $title->getPrefixedText(), 'missing' => '');
+ }
+
+ // Report any missing page ids
+ foreach ($pageSet->getMissingPageIDs() as $pageid) {
+ $pages[$pageid] = array (
+ 'pageid' => $pageid,
+ 'missing' => ''
+ );
+ }
+
+ // Output general page information for found titles
+ foreach ($pageSet->getGoodTitles() as $pageid => $title) {
+ $pages[$pageid] = array (
+ 'pageid' => $pageid,
+ 'ns' => $title->getNamespace(), 'title' => $title->getPrefixedText());
+ }
+
+ if (!empty ($pages)) {
+ $result->setIndexedTagName($pages, 'page');
+ $result->addValue('query', 'pages', $pages);
+ }
+ }
+
+ protected function executeGeneratorModule($generatorName, $redirects) {
+
+ // Find class that implements requested generator
+ if (isset ($this->mQueryListModules[$generatorName])) {
+ $className = $this->mQueryListModules[$generatorName];
+ }
+ elseif (isset ($this->mQueryPropModules[$generatorName])) {
+ $className = $this->mQueryPropModules[$generatorName];
+ } else {
+ ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generatorName");
+ }
+
+ // Use current pageset as the result, and create a new one just for the generator
+ $resultPageSet = $this->mPageSet;
+ $this->mPageSet = new ApiPageSet($this, $redirects);
+
+ // Create and execute the generator
+ $generator = new $className ($this, $generatorName);
+ if (!$generator instanceof ApiQueryGeneratorBase)
+ $this->dieUsage("Module $generatorName cannot be used as a generator", "badgenerator");
+
+ $generator->setGeneratorMode();
+ $generator->requestExtraData();
+
+ // execute current pageSet to get the data for the generator module
+ $this->mPageSet->execute();
+
+ // populate resultPageSet with the generator output
+ $generator->profileIn();
+ $generator->executeGenerator($resultPageSet);
+ $resultPageSet->finishPageSetGeneration();
+ $generator->profileOut();
+
+ // Swap the resulting pageset back in
+ $this->mPageSet = $resultPageSet;
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => $this->mPropModuleNames
+ ),
+ 'list' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => $this->mListModuleNames
+ ),
+ 'meta' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => $this->mMetaModuleNames
+ ),
+ 'generator' => array (
+ ApiBase :: PARAM_TYPE => $this->mAllowedGenerators
+ ),
+ 'redirects' => false
+ );
+ }
+
+ /**
+ * Override the parent to generate help messages for all available query modules.
+ */
+ public function makeHelpMsg() {
+
+ // Use parent to make default message for the query module
+ $msg = parent :: makeHelpMsg();
+
+ // Make sure the internal object is empty
+ // (just in case a sub-module decides to optimize during instantiation)
+ $this->mPageSet = null;
+
+ $astriks = str_repeat('--- ', 8);
+ $msg .= "\n$astriks Query: Prop $astriks\n\n";
+ $msg .= $this->makeHelpMsgHelper($this->mQueryPropModules, 'prop');
+ $msg .= "\n$astriks Query: List $astriks\n\n";
+ $msg .= $this->makeHelpMsgHelper($this->mQueryListModules, 'list');
+ $msg .= "\n$astriks Query: Meta $astriks\n\n";
+ $msg .= $this->makeHelpMsgHelper($this->mQueryMetaModules, 'meta');
+
+ return $msg;
+ }
+
+ private function makeHelpMsgHelper($moduleList, $paramName) {
+
+ $moduleDscriptions = array ();
+
+ foreach ($moduleList as $moduleName => $moduleClass) {
+ $msg = "* $paramName=$moduleName *";
+ $module = new $moduleClass ($this, $moduleName, null);
+ $msg2 = $module->makeHelpMsg();
+ if ($msg2 !== false)
+ $msg .= $msg2;
+ if ($module instanceof ApiQueryGeneratorBase)
+ $msg .= "Generator:\n This module may be used as a generator\n";
+ $moduleDscriptions[] = $msg;
+ }
+
+ return implode("\n", $moduleDscriptions);
+ }
+
+ /**
+ * Override to add extra parameters from PageSet
+ */
+ public function makeHelpMsgParameters() {
+ $psModule = new ApiPageSet($this);
+ return $psModule->makeHelpMsgParameters() . parent :: makeHelpMsgParameters();
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => 'Which properties to get for the titles/revisions/pageids',
+ 'list' => 'Which lists to get',
+ 'meta' => 'Which meta data to get about the site',
+ 'generator' => 'Use the output of a list as the input for other prop/list/meta items',
+ 'redirects' => 'Automatically resolve redirects'
+ );
+ }
+
+ protected function getDescription() {
+ return array (
+ 'Query API module allows applications to get needed pieces of data from the MediaWiki databases,',
+ 'and is loosely based on the Query API interface currently available on all MediaWiki servers.',
+ 'All data modifications will first have to use query to acquire a token to prevent abuse from malicious sites.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&prop=revisions&meta=siteinfo&titles=Main%20Page&rvprop=user|comment'
+ );
+ }
+
+ public function getVersion() {
+ $psModule = new ApiPageSet($this);
+ $vers = array ();
+ $vers[] = __CLASS__ . ': $Id$';
+ $vers[] = $psModule->getVersion();
+ return $vers;
+ }
+}
+?>
diff --git a/includes/api/ApiQueryAllpages.php b/includes/api/ApiQueryAllpages.php
new file mode 100644
index 000000000000..9b5b0a798ef4
--- /dev/null
+++ b/includes/api/ApiQueryAllpages.php
@@ -0,0 +1,173 @@
+<?php
+
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryAllpages extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'ap');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ if ($resultPageSet->isResolvingRedirects())
+ $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');
+
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ wfProfileIn($this->getModuleProfileName() . '-getDB');
+ $db = & $this->getDB();
+ wfProfileOut($this->getModuleProfileName() . '-getDB');
+
+ wfProfileIn($this->getModuleProfileName() . '-parseParams');
+ $limit = $from = $namespace = $filterredir = $prefix = null;
+ extract($this->extractRequestParams());
+
+ $this->addTables('page');
+ if (!$this->addWhereIf('page_is_redirect = 1', $filterredir === 'redirects'))
+ $this->addWhereIf('page_is_redirect = 0', $filterredir === 'nonredirects');
+ $this->addWhereFld('page_namespace', $namespace);
+ if (isset ($from))
+ $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($from)));
+ if (isset ($prefix))
+ $this->addWhere("page_title LIKE '{$db->strencode(ApiQueryBase :: titleToKey($prefix))}%'");
+
+ if (is_null($resultPageSet)) {
+ $this->addFields(array (
+ 'page_id',
+ 'page_namespace',
+ 'page_title'
+ ));
+ } else {
+ $this->addFields($resultPageSet->getPageTableFields());
+ }
+
+ $this->addOption('USE INDEX', 'name_title');
+ $this->addOption('LIMIT', $limit +1);
+ $this->addOption('ORDER BY', 'page_namespace, page_title');
+
+ wfProfileOut($this->getModuleProfileName() . '-parseParams');
+
+ $res = $this->select(__METHOD__);
+
+ wfProfileIn($this->getModuleProfileName() . '-saveResults');
+
+ $data = array ();
+ $count = 0;
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->page_title));
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $vals = $this->addRowInfo('page', $row);
+ if ($vals)
+ $data[intval($row->page_id)] = $vals;
+ } else {
+ $resultPageSet->processDbRow($row);
+ }
+ }
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'p');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+
+ wfProfileOut($this->getModuleProfileName() . '-saveResults');
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'from' => null,
+ 'prefix' => null,
+ 'namespace' => array (
+ ApiBase :: PARAM_DFLT => 0,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'filterredir' => array (
+ ApiBase :: PARAM_DFLT => 'all',
+ ApiBase :: PARAM_TYPE => array (
+ 'all',
+ 'redirects',
+ 'nonredirects'
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'from' => 'The page title to start enumerating from.',
+ 'prefix' => 'Search for all page titles that begin with this value.',
+ 'namespace' => 'The namespace to enumerate.',
+ 'filterredir' => 'Which pages to list.',
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate all pages sequentially in a given namespace';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'Simple Use',
+ ' Show a list of pages starting at the letter "B"',
+ ' api.php?action=query&list=allpages&apfrom=B',
+ 'Using as Generator',
+ ' Show info about 4 pages starting at the letter "T"',
+ ' api.php?action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info',
+ ' Show content of first 2 non-redirect pages begining at "Re"',
+ ' api.php?action=query&generator=allpages&gaplimit=2&gapfilterredir=nonredirects&gapfrom=Re&prop=revisions&rvprop=content'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiQueryBacklinks.php b/includes/api/ApiQueryBacklinks.php
new file mode 100644
index 000000000000..c875df3ba3a5
--- /dev/null
+++ b/includes/api/ApiQueryBacklinks.php
@@ -0,0 +1,358 @@
+<?php
+
+
+/*
+ * Created on Oct 16, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+class ApiQueryBacklinks extends ApiQueryGeneratorBase {
+
+ private $rootTitle, $contRedirs, $contLevel, $contTitle, $contID;
+
+ // output element name, database column field prefix, database table
+ private $backlinksSettings = array (
+ 'backlinks' => array (
+ 'code' => 'bl',
+ 'prefix' => 'pl',
+ 'linktbl' => 'pagelinks'
+ ),
+ 'embeddedin' => array (
+ 'code' => 'ei',
+ 'prefix' => 'tl',
+ 'linktbl' => 'templatelinks'
+ ),
+ 'imagelinks' => array (
+ 'code' => 'il',
+ 'prefix' => 'il',
+ 'linktbl' => 'imagelinks'
+ )
+ );
+
+ public function __construct($query, $moduleName) {
+ $code = $prefix = $linktbl = null;
+ extract($this->backlinksSettings[$moduleName]);
+
+ parent :: __construct($query, $moduleName, $code);
+ $this->bl_ns = $prefix . '_namespace';
+ $this->bl_from = $prefix . '_from';
+ $this->bl_tables = array (
+ $linktbl,
+ 'page'
+ );
+ $this->bl_code = $code;
+
+ $this->hasNS = $moduleName !== 'imagelinks';
+ if ($this->hasNS) {
+ $this->bl_title = $prefix . '_title';
+ $this->bl_sort = "{$this->bl_ns}, {$this->bl_title}, {$this->bl_from}";
+ $this->bl_fields = array (
+ $this->bl_ns,
+ $this->bl_title
+ );
+ } else {
+ $this->bl_title = $prefix . '_to';
+ $this->bl_sort = "{$this->bl_title}, {$this->bl_from}";
+ $this->bl_fields = array (
+ $this->bl_title
+ );
+ }
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+ $continue = $namespace = $redirect = $limit = null;
+ extract($this->extractRequestParams());
+
+ if ($redirect)
+ ApiBase :: dieDebug(__METHOD__, 'Redirect is not yet been implemented', 'notimplemented');
+
+ $this->processContinue($continue, $redirect);
+
+ $this->addFields($this->bl_fields);
+ if (is_null($resultPageSet))
+ $this->addFields(array (
+ 'page_id',
+ 'page_namespace',
+ 'page_title'
+ ));
+ else
+ $this->addFields($resultPageSet->getPageTableFields()); // will include page_id
+
+ $this->addTables($this->bl_tables);
+ $this->addWhere($this->bl_from . '=page_id');
+
+ if ($this->hasNS)
+ $this->addWhereFld($this->bl_ns, $this->rootTitle->getNamespace());
+ $this->addWhereFld($this->bl_title, $this->rootTitle->getDBkey());
+ $this->addWhereFld('page_namespace', $namespace);
+ $this->addOption('LIMIT', $limit +1);
+ $this->addOption('ORDER BY', $this->bl_sort);
+
+ if ($redirect)
+ $this->addWhereFld('page_is_redirect', 0);
+
+ $db = & $this->getDB();
+ if (!is_null($continue)) {
+ $plfrm = intval($this->contID);
+ if ($this->contLevel == 0) {
+ // For the first level, there is only one target title, so no need for complex filtering
+ $this->addWhere($this->bl_from . '>=' . $plfrm);
+ } else {
+ $ns = $this->contTitle->getNamespace();
+ $t = $db->addQuotes($this->contTitle->getDBkey());
+ $whereWithoutNS = "{$this->bl_title}>$t OR ({$this->bl_title}=$t AND {$this->bl_from}>=$plfrm))";
+
+ if ($this->hasNS)
+ $this->addWhere("{$this->bl_ns}>$ns OR ({$this->bl_ns}=$ns AND ($whereWithoutNS)");
+ else
+ $this->addWhere($whereWithoutNS);
+ }
+ }
+
+ $res = $this->select(__METHOD__);
+
+ $count = 0;
+ $data = array ();
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ if ($redirect) {
+ $ns = $row-> {
+ $this->bl_ns };
+ $t = $row-> {
+ $this->bl_title };
+ $continue = $this->getContinueRedirStr(false, 0, $ns, $t, $row->page_id);
+ } else
+ $continue = $this->getContinueStr($row->page_id);
+ $this->setContinueEnumParameter('continue', $continue);
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $vals = $this->addRowInfo('page', $row);
+ if ($vals)
+ $data[intval($row->page_id)] = $vals;
+ } else {
+ $resultPageSet->processDbRow($row);
+ }
+ }
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, $this->bl_code);
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+ }
+
+ protected function processContinue($continue, $redirect) {
+ $pageSet = $this->getPageSet();
+ $count = $pageSet->getTitleCount();
+ if (!is_null($continue)) {
+ if ($count !== 0)
+ $this->dieUsage("When continuing the {$this->getModuleName()} query, no other titles may be provided", 'titles_on_continue');
+ $this->parseContinueParam($continue, $redirect);
+
+ // Skip all completed links
+
+ } else {
+ if ($count !== 1)
+ $this->dieUsage("The {$this->getModuleName()} query requires one title to start", 'bad_title_count');
+ $this->rootTitle = current($pageSet->getTitles()); // only one title there
+ }
+
+ // only image titles are allowed for the root
+ if (!$this->hasNS && $this->rootTitle->getNamespace() !== NS_IMAGE)
+ $this->dieUsage("The title for {$this->getModuleName()} query must be an image", 'bad_image_title');
+ }
+
+ protected function parseContinueParam($continue, $redirect) {
+ $continueList = explode('|', $continue);
+ if ($redirect) {
+ //
+ // expected redirect-mode parameter:
+ // ns|db_key|step|level|ns|db_key|id
+ // ns+db_key -- the root title
+ // step = 1 or 2 - which step to continue from - 1-titles, 2-redirects
+ // level -- how many levels to follow before starting enumerating.
+ // if level > 0 -- ns+title to continue from, otherwise skip these
+ // id = last page_id to continue from
+ //
+ if (count($continueList) > 4) {
+ $rootNs = intval($continueList[0]);
+ if (($rootNs !== 0 || $continueList[0] === '0') && !empty ($continueList[1])) {
+ $this->rootTitle = Title :: makeTitleSafe($rootNs, $continueList[1]);
+ if ($this->rootTitle && $this->rootTitle->userCanRead()) {
+
+ $step = intval($continueList[2]);
+ if ($step === 1 || $step === 2) {
+ $this->contRedirs = ($step === 2);
+
+ $level = intval($continueList[3]);
+ if ($level !== 0 || $continueList[3] === '0') {
+ $this->contLevel = $level;
+
+ if ($level === 0) {
+ if (count($continueList) === 5) {
+ $contID = intval($continueList[4]);
+ if ($contID !== 0 || $continueList[4] === '0') {
+ $this->contID = $contID;
+ return; // done
+ }
+ }
+ } else {
+ if (count($continueList) === 7) {
+ $contNs = intval($continueList[4]);
+ if (($contNs !== 0 || $continueList[4] === '0') && !empty ($continueList[5])) {
+ $this->contTitle = Title :: makeTitleSafe($contNs, $continueList[5]);
+
+ $contID = intval($continueList[6]);
+ if ($contID !== 0 || $continueList[6] === '0') {
+ $this->contID = $contID;
+ return; // done
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ //
+ // expected non-redirect-mode parameter:
+ // ns|db_key|id
+ // ns+db_key -- the root title
+ // id = last page_id to continue from
+ //
+ if (count($continueList) === 3) {
+ $rootNs = intval($continueList[0]);
+ if (($rootNs !== 0 || $continueList[0] === '0') && !empty ($continueList[1])) {
+ $this->rootTitle = Title :: makeTitleSafe($rootNs, $continueList[1]);
+ if ($this->rootTitle && $this->rootTitle->userCanRead()) {
+
+ $contID = intval($continueList[2]);
+ if ($contID !== 0) {
+ $this->contID = $contID;
+ return; // done
+ }
+ }
+ }
+ }
+ }
+
+ $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue");
+ }
+
+ protected function getContinueStr($lastPageID) {
+ return $this->rootTitle->getNamespace() .
+ '|' . $this->rootTitle->getDBkey() .
+ '|' . $lastPageID;
+ }
+
+ protected function getContinueRedirStr($isRedirPhase, $level, $ns, $title, $lastPageID) {
+ return $this->rootTitle->getNamespace() .
+ '|' . $this->rootTitle->getDBkey() .
+ '|' . ($isRedirPhase ? 1 : 2) .
+ '|' . $level .
+ ($level > 0 ? ('|' . $ns . '|' . $title) : '') .
+ '|' . $lastPageID;
+ }
+
+ protected function getAllowedParams() {
+
+ return array (
+ 'continue' => null,
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'redirect' => false,
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'continue' => 'When more results are available, use this to continue.',
+ 'namespace' => 'The namespace to enumerate.',
+ 'redirect' => 'If linking page is a redirect, find all pages that link to that redirect (not implemented)',
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ switch ($this->getModuleName()) {
+ case 'backlinks' :
+ return 'Find all pages that link to the given page';
+ case 'embeddedin' :
+ return 'Find all pages that embed (transclude) the given title';
+ case 'imagelinks' :
+ return 'Find all pages that use the given image title.';
+ default :
+ ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
+ }
+ }
+
+ protected function getExamples() {
+ static $examples = array (
+ 'backlinks' => array (
+ "api.php?action=query&list=backlinks&titles=Main%20Page",
+ "api.php?action=query&generator=backlinks&titles=Main%20Page&prop=info"
+ ),
+ 'embeddedin' => array (
+ "api.php?action=query&list=embeddedin&titles=Template:Stub",
+ "api.php?action=query&generator=embeddedin&titles=Template:Stub&prop=info"
+ ),
+ 'imagelinks' => array (
+ "api.php?action=query&list=imagelinks&titles=Image:Albert%20Einstein%20Head.jpg",
+ "api.php?action=query&generator=imagelinks&titles=Image:Albert%20Einstein%20Head.jpg&prop=info"
+ )
+ );
+
+ return $examples[$this->getModuleName()];
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiQueryBase.php b/includes/api/ApiQueryBase.php
new file mode 100644
index 000000000000..cc9a4fed7a85
--- /dev/null
+++ b/includes/api/ApiQueryBase.php
@@ -0,0 +1,373 @@
+<?php
+
+
+/*
+ * Created on Sep 7, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+abstract class ApiQueryBase extends ApiBase {
+
+ private $mQueryModule, $tables, $where, $fields, $options;
+
+ public function __construct($query, $moduleName, $paramPrefix = '') {
+ parent :: __construct($query->getMain(), $moduleName, $paramPrefix);
+ $this->mQueryModule = $query;
+ $this->resetQueryParams();
+ }
+
+ protected function resetQueryParams() {
+ $this->tables = array ();
+ $this->where = array ();
+ $this->fields = array ();
+ $this->options = array ();
+ }
+
+ protected function addTables($value) {
+ if (is_array($value))
+ $this->tables = array_merge($this->tables, $value);
+ else
+ $this->tables[] = $value;
+ }
+
+ protected function addFields($value) {
+ if (is_array($value))
+ $this->fields = array_merge($this->fields, $value);
+ else
+ $this->fields[] = $value;
+ }
+
+ protected function addFieldsIf($value, $condition) {
+ if ($condition) {
+ $this->addFields($value);
+ return true;
+ }
+ return false;
+ }
+
+ protected function addWhere($value) {
+ if (is_array($value))
+ $this->where = array_merge($this->where, $value);
+ else
+ $this->where[] = $value;
+ }
+
+ protected function addWhereIf($value, $condition) {
+ if ($condition) {
+ $this->addWhere($value);
+ return true;
+ }
+ return false;
+ }
+
+ protected function addWhereFld($field, $value) {
+ if (!is_null($value))
+ $this->where[$field] = $value;
+ }
+
+ protected function addWhereRange($field, $dir, $start, $end) {
+ $isDirNewer = ($dir === 'newer');
+ $after = ($isDirNewer ? '>=' : '<=');
+ $before = ($isDirNewer ? '<=' : '>=');
+ $db = $this->getDB();
+
+ if (!is_null($start))
+ $this->addWhere($field . $after . $db->addQuotes($start));
+
+ if (!is_null($end))
+ $this->addWhere($field . $before . $db->addQuotes($end));
+
+ $this->addOption('ORDER BY', $field . ($isDirNewer ? '' : ' DESC'));
+ }
+
+ protected function addOption($name, $value = null) {
+ if (is_null($value))
+ $this->options[] = $name;
+ else
+ $this->options[$name] = $value;
+ }
+
+ protected function select($method) {
+
+ // getDB has its own profileDBIn/Out calls
+ $db = $this->getDB();
+
+ $this->profileDBIn();
+ $res = $db->select($this->tables, $this->fields, $this->where, $method, $this->options);
+ $this->profileDBOut();
+
+ return $res;
+ }
+
+ protected function addRowInfo($prefix, $row) {
+
+ $vals = array ();
+
+ // ID
+ if ( isset( $row-> { $prefix . '_id' } ) )
+ $vals[$prefix . 'id'] = intval( $row-> { $prefix . '_id' } );
+
+ // Title
+ $title = ApiQueryBase :: addRowInfo_title($row, $prefix . '_namespace', $prefix . '_title');
+ if ($title) {
+ if (!$title->userCanRead())
+ return false;
+ $vals['ns'] = $title->getNamespace();
+ $vals['title'] = $title->getPrefixedText();
+ }
+
+ switch ($prefix) {
+
+ case 'page' :
+ // page_is_redirect
+ @ $tmp = $row->page_is_redirect;
+ if ($tmp)
+ $vals['redirect'] = '';
+
+ break;
+
+ case 'rc' :
+ // PageId
+ @ $tmp = $row->rc_cur_id;
+ if (!is_null($tmp))
+ $vals['pageid'] = intval($tmp);
+
+ @ $tmp = $row->rc_this_oldid;
+ if (!is_null($tmp))
+ $vals['revid'] = intval($tmp);
+
+ if ( isset( $row->rc_last_oldid ) )
+ $vals['old_revid'] = intval( $row->rc_last_oldid );
+
+ $title = ApiQueryBase :: addRowInfo_title($row, 'rc_moved_to_ns', 'rc_moved_to_title');
+ if ($title) {
+ if (!$title->userCanRead())
+ return false;
+ $vals['new_ns'] = $title->getNamespace();
+ $vals['new_title'] = $title->getPrefixedText();
+ }
+
+ if ( isset( $row->rc_patrolled ) )
+ $vals['patrolled'] = '';
+
+ break;
+
+ case 'log' :
+ // PageId
+ @ $tmp = $row->page_id;
+ if (!is_null($tmp))
+ $vals['pageid'] = intval($tmp);
+
+ if ($row->log_params !== '') {
+ $params = explode("\n", $row->log_params);
+ if ($row->log_type == 'move' && isset ($params[0])) {
+ $newTitle = Title :: newFromText($params[0]);
+ if ($newTitle) {
+ $vals['new_ns'] = $newTitle->getNamespace();
+ $vals['new_title'] = $newTitle->getPrefixedText();
+ $params = null;
+ }
+ }
+
+ if (!empty ($params)) {
+ $this->getResult()->setIndexedTagName($params, 'param');
+ $vals = array_merge($vals, $params);
+ }
+ }
+
+ break;
+
+ case 'rev' :
+ // PageID
+ @ $tmp = $row->rev_page;
+ if (!is_null($tmp))
+ $vals['pageid'] = intval($tmp);
+ }
+
+ // Type
+ @ $tmp = $row-> {
+ $prefix . '_type' };
+ if (!is_null($tmp))
+ $vals['type'] = $tmp;
+
+ // Action
+ @ $tmp = $row-> {
+ $prefix . '_action' };
+ if (!is_null($tmp))
+ $vals['action'] = $tmp;
+
+ // Old ID
+ @ $tmp = $row-> {
+ $prefix . '_text_id' };
+ if (!is_null($tmp))
+ $vals['oldid'] = intval($tmp);
+
+ // User Name / Anon IP
+ @ $tmp = $row-> {
+ $prefix . '_user_text' };
+ if (is_null($tmp))
+ @ $tmp = $row->user_name;
+ if (!is_null($tmp)) {
+ $vals['user'] = $tmp;
+ @ $tmp = !$row-> {
+ $prefix . '_user' };
+ if (!is_null($tmp) && $tmp)
+ $vals['anon'] = '';
+ }
+
+ // Bot Edit
+ @ $tmp = $row-> {
+ $prefix . '_bot' };
+ if (!is_null($tmp) && $tmp)
+ $vals['bot'] = '';
+
+ // New Edit
+ @ $tmp = $row-> {
+ $prefix . '_new' };
+ if (is_null($tmp))
+ @ $tmp = $row-> {
+ $prefix . '_is_new' };
+ if (!is_null($tmp) && $tmp)
+ $vals['new'] = '';
+
+ // Minor Edit
+ @ $tmp = $row-> {
+ $prefix . '_minor_edit' };
+ if (is_null($tmp))
+ @ $tmp = $row-> {
+ $prefix . '_minor' };
+ if (!is_null($tmp) && $tmp)
+ $vals['minor'] = '';
+
+ // Timestamp
+ @ $tmp = $row-> {
+ $prefix . '_timestamp' };
+ if (!is_null($tmp))
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $tmp);
+
+ // Comment
+ @ $tmp = $row-> {
+ $prefix . '_comment' };
+ if (!empty ($tmp)) // optimize bandwidth
+ $vals['comment'] = $tmp;
+
+ return $vals;
+ }
+
+ private static function addRowInfo_title($row, $nsfld, $titlefld) {
+ if ( isset( $row-> $nsfld ) ) {
+ $ns = $row-> $nsfld;
+ @ $title = $row-> $titlefld;
+ if (!empty ($title))
+ return Title :: makeTitle($ns, $title);
+ }
+ return false;
+ }
+
+ /**
+ * Override this method to request extra fields from the pageSet
+ * using $this->getPageSet()->requestField('fieldName')
+ */
+ public function requestExtraData() {
+ }
+
+ /**
+ * Get the main Query module
+ */
+ public function getQuery() {
+ return $this->mQueryModule;
+ }
+
+ protected function setContinueEnumParameter($paramName, $paramValue) {
+ $msg = array (
+ $this->encodeParamName($paramName
+ ) => $paramValue);
+ $this->getResult()->addValue('query-continue', $this->getModuleName(), $msg);
+ }
+
+ /**
+ * Get the Query database connection (readonly)
+ */
+ protected function getDB() {
+ return $this->getQuery()->getDB();
+ }
+
+ /**
+ * Get the PageSet object to work on
+ * @return ApiPageSet data
+ */
+ protected function getPageSet() {
+ return $this->mQueryModule->getPageSet();
+ }
+
+ /**
+ * This is a very simplistic utility function
+ * to convert a non-namespaced title string to a db key.
+ * It will replace all ' ' with '_'
+ */
+ public static function titleToKey($title) {
+ return str_replace(' ', '_', $title);
+ }
+
+ public static function keyToTitle($key) {
+ return str_replace('_', ' ', $key);
+ }
+
+ public static function getBaseVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
+abstract class ApiQueryGeneratorBase extends ApiQueryBase {
+
+ private $mIsGenerator;
+
+ public function __construct($query, $moduleName, $paramPrefix = '') {
+ parent :: __construct($query, $moduleName, $paramPrefix);
+ $this->mIsGenerator = false;
+ }
+
+ public function setGeneratorMode() {
+ $this->mIsGenerator = true;
+ }
+
+ /**
+ * Overrides base class to prepend 'g' to every generator parameter
+ */
+ public function encodeParamName($paramName) {
+ if ($this->mIsGenerator)
+ return 'g' . parent :: encodeParamName($paramName);
+ else
+ return parent :: encodeParamName($paramName);
+ }
+
+ /**
+ * Execute this module as a generator
+ * @param $resultPageSet PageSet: All output should be appended to this object
+ */
+ public abstract function executeGenerator($resultPageSet);
+}
+?>
diff --git a/includes/api/ApiQueryInfo.php b/includes/api/ApiQueryInfo.php
new file mode 100644
index 000000000000..07928b501296
--- /dev/null
+++ b/includes/api/ApiQueryInfo.php
@@ -0,0 +1,85 @@
+<?php
+
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryInfo extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName);
+ }
+
+ public function requestExtraData() {
+ $pageSet = $this->getPageSet();
+ $pageSet->requestField('page_is_redirect');
+ $pageSet->requestField('page_touched');
+ $pageSet->requestField('page_latest');
+ }
+
+ public function execute() {
+
+ $pageSet = $this->getPageSet();
+ $titles = $pageSet->getGoodTitles();
+ $result = $this->getResult();
+
+ $pageIsRedir = $pageSet->getCustomField('page_is_redirect');
+ $pageTouched = $pageSet->getCustomField('page_touched');
+ $pageLatest = $pageSet->getCustomField('page_latest');
+
+ foreach ( $titles as $pageid => $unused ) {
+ $pageInfo = array (
+ 'touched' => wfTimestamp(TS_ISO_8601, $pageTouched[$pageid]),
+ 'lastrevid' => intval($pageLatest[$pageid])
+ );
+
+ if ($pageIsRedir[$pageid])
+ $pageInfo['redirect'] = '';
+
+ $result->addValue(array (
+ 'query',
+ 'pages'
+ ), $pageid, $pageInfo);
+ }
+ }
+
+ protected function getDescription() {
+ return 'Get basic page information such as namespace, title, last touched date, ...';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&prop=info&titles=Main%20Page'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiQueryLogEvents.php b/includes/api/ApiQueryLogEvents.php
new file mode 100644
index 000000000000..f6d55bfce243
--- /dev/null
+++ b/includes/api/ApiQueryLogEvents.php
@@ -0,0 +1,173 @@
+<?php
+
+
+/*
+ * Created on Oct 16, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryLogEvents extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'le');
+ }
+
+ public function execute() {
+ $limit = $type = $start = $end = $dir = $user = $title = null;
+ extract($this->extractRequestParams());
+
+ $db = & $this->getDB();
+
+ list($tbl_logging, $tbl_page, $tbl_user) = $db->tableNamesN('logging', 'page', 'user');
+
+ $this->addOption('STRAIGHT_JOIN');
+ $this->addTables("$tbl_logging LEFT OUTER JOIN $tbl_page ON " .
+ "log_namespace=page_namespace AND log_title=page_title " .
+ "INNER JOIN $tbl_user ON user_id=log_user");
+
+ $this->addFields(array (
+ 'log_type',
+ 'log_action',
+ 'log_timestamp',
+ 'log_user',
+ 'user_name',
+ 'log_namespace',
+ 'log_title',
+ 'page_id',
+ 'log_comment',
+ 'log_params'
+ ));
+
+ $this->addWhereFld('log_type', $type);
+ $this->addWhereRange('log_timestamp', $dir, $start, $end);
+ $this->addOption('LIMIT', $limit +1);
+
+ if (!is_null($user)) {
+ $userid = $db->selectField('user', 'user_id', array (
+ 'user_name' => $user
+ ));
+ if (!$userid)
+ $this->dieUsage("User name $user not found", 'param_user');
+ $this->addWhereFld('log_user', $userid);
+ }
+
+ if (!is_null($title)) {
+ $titleObj = Title :: newFromText($title);
+ if (is_null($titleObj))
+ $this->dieUsage("Bad title value '$title'", 'param_title');
+ $this->addWhereFld('log_namespace', $titleObj->getNamespace());
+ $this->addWhereFld('log_title', $titleObj->getDBkey());
+ }
+
+ $data = array ();
+ $count = 0;
+ $res = $this->select(__METHOD__);
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', $row->log_timestamp);
+ break;
+ }
+
+ $vals = $this->addRowInfo('log', $row);
+ if($vals)
+ $data[] = $vals;
+ }
+ $db->freeResult($res);
+
+ $this->getResult()->setIndexedTagName($data, 'item');
+ $this->getResult()->addValue('query', $this->getModuleName(), $data);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'type' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'block',
+ 'protect',
+ 'rights',
+ 'delete',
+ 'upload',
+ 'move',
+ 'import',
+ 'renameuser',
+ 'newusers',
+ 'makebot'
+ )
+ ),
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'user' => null,
+ 'title' => null,
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'type' => 'Filter log entries to only this type(s)',
+ 'start' => 'The timestamp to start enumerating from.',
+ 'end' => 'The timestamp to end enumerating.',
+ 'dir' => 'In which direction to enumerate.',
+ 'user' => 'Filter entries to those made by the given user.',
+ 'title' => 'Filter entries to those related to a page.',
+ 'limit' => 'How many total event entries to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Get events from logs.';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=logevents'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiQueryRecentChanges.php b/includes/api/ApiQueryRecentChanges.php
new file mode 100644
index 000000000000..a25a4e0fcbc3
--- /dev/null
+++ b/includes/api/ApiQueryRecentChanges.php
@@ -0,0 +1,187 @@
+<?php
+
+
+/*
+ * Created on Oct 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryRecentChanges extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'rc');
+ }
+
+ public function execute() {
+ $limit = $prop = $namespace = $show = $dir = $start = $end = null;
+ extract($this->extractRequestParams());
+
+ $this->addTables('recentchanges');
+ $this->addWhereRange('rc_timestamp', $dir, $start, $end);
+ $this->addWhereFld('rc_namespace', $namespace);
+
+ if (!is_null($show)) {
+ $show = array_flip($show);
+ if ((isset ($show['minor']) && isset ($show['!minor'])) || (isset ($show['bot']) && isset ($show['!bot'])) || (isset ($show['anon']) && isset ($show['!anon'])))
+ $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
+
+ $this->addWhereIf('rc_minor = 0', isset ($show['!minor']));
+ $this->addWhereIf('rc_minor != 0', isset ($show['minor']));
+ $this->addWhereIf('rc_bot = 0', isset ($show['!bot']));
+ $this->addWhereIf('rc_bot != 0', isset ($show['bot']));
+ $this->addWhereIf('rc_user = 0', isset ($show['anon']));
+ $this->addWhereIf('rc_user != 0', isset ($show['!anon']));
+ }
+
+ $this->addFields(array (
+ 'rc_timestamp',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_cur_id',
+ 'rc_this_oldid',
+ 'rc_last_oldid',
+ 'rc_type',
+ 'rc_moved_to_ns',
+ 'rc_moved_to_title'
+ ));
+
+ if (!is_null($prop)) {
+ $prop = array_flip($prop);
+ $this->addFieldsIf('rc_comment', isset ($prop['comment']));
+ if (isset ($prop['user'])) {
+ $this->addFields('rc_user');
+ $this->addFields('rc_user_text');
+ }
+ if (isset ($prop['flags'])) {
+ $this->addFields('rc_minor');
+ $this->addFields('rc_bot');
+ $this->addFields('rc_new');
+ }
+ }
+
+ $this->addOption('LIMIT', $limit +1);
+ $this->addOption('USE INDEX', 'rc_timestamp');
+
+ $data = array ();
+ $count = 0;
+ $db = & $this->getDB();
+ $res = $this->select(__METHOD__);
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', $row->rc_timestamp);
+ break;
+ }
+
+ $vals = $this->addRowInfo('rc', $row);
+ if ($vals)
+ $data[] = $vals;
+ }
+ $db->freeResult($res);
+
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'rc');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'user',
+ 'comment',
+ 'flags'
+ )
+ ),
+ 'show' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'minor',
+ '!minor',
+ 'bot',
+ '!bot',
+ 'anon',
+ '!anon'
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'start' => 'The timestamp to start enumerating from.',
+ 'end' => 'The timestamp to end enumerating.',
+ 'dir' => 'In which direction to enumerate.',
+ 'namespace' => 'Filter log entries to only this namespace(s)',
+ 'prop' => 'Include additional pieces of information',
+ 'show' => array (
+ 'Show only items that meet this criteria.',
+ 'For example, to see only minor edits done by logged-in users, set show=minor|!anon'
+ ),
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate recent changes';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=recentchanges'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php
new file mode 100644
index 000000000000..4b77546a07ef
--- /dev/null
+++ b/includes/api/ApiQueryRevisions.php
@@ -0,0 +1,268 @@
+<?php
+
+
+/*
+ * Created on Sep 7, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryRevisions extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'rv');
+ }
+
+ public function execute() {
+ $limit = $startid = $endid = $start = $end = $dir = $prop = null;
+ extract($this->extractRequestParams());
+
+ // If any of those parameters are used, work in 'enumeration' mode.
+ // Enum mode can only be used when exactly one page is provided.
+ // Enumerating revisions on multiple pages make it extremelly
+ // difficult to manage continuations and require additional sql indexes
+ $enumRevMode = (!is_null($limit) || !is_null($startid) || !is_null($endid) || $dir === 'newer' || !is_null($start) || !is_null($end));
+
+ $pageSet = $this->getPageSet();
+ $pageCount = $pageSet->getGoodTitleCount();
+ $revCount = $pageSet->getRevisionCount();
+
+ // Optimization -- nothing to do
+ if ($revCount === 0 && $pageCount === 0)
+ return;
+
+ if ($revCount > 0 && $enumRevMode)
+ $this->dieUsage('The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids');
+
+ if ($pageCount > 1 && $enumRevMode)
+ $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, start, and end parameters may only be used on a single page.', 'multpages');
+
+ $this->addTables('revision');
+ $this->addFields(array (
+ 'rev_id',
+ 'rev_page',
+ 'rev_text_id',
+ 'rev_minor_edit'
+ ));
+ $this->addWhere('rev_deleted=0');
+
+ $showContent = false;
+
+ if (!is_null($prop)) {
+ $prop = array_flip($prop);
+ $this->addFieldsIf('rev_timestamp', isset ($prop['timestamp']));
+ $this->addFieldsIf('rev_comment', isset ($prop['comment']));
+ if (isset ($prop['user'])) {
+ $this->addFields('rev_user');
+ $this->addFields('rev_user_text');
+ }
+ if (isset ($prop['content'])) {
+ $this->addTables('text');
+ $this->addWhere('rev_text_id=old_id');
+ $this->addFields('old_id');
+ $this->addFields('old_text');
+ $this->addFields('old_flags');
+ $showContent = true;
+ }
+ }
+
+ $userMax = ($showContent ? 50 : 500);
+ $botMax = ($showContent ? 200 : 10000);
+
+ if ($enumRevMode) {
+
+ // This is mostly to prevent parameter errors (and optimize sql?)
+ if (!is_null($startid) && !is_null($start))
+ $this->dieUsage('start and startid cannot be used together', 'badparams');
+
+ if (!is_null($endid) && !is_null($end))
+ $this->dieUsage('end and endid cannot be used together', 'badparams');
+
+ // This code makes an assumption that sorting by rev_id and rev_timestamp produces
+ // the same result. This way users may request revisions starting at a given time,
+ // but to page through results use the rev_id returned after each page.
+ // Switching to rev_id removes the potential problem of having more than
+ // one row with the same timestamp for the same page.
+ // The order needs to be the same as start parameter to avoid SQL filesort.
+
+ if (is_null($startid))
+ $this->addWhereRange('rev_timestamp', $dir, $start, $end);
+ else
+ $this->addWhereRange('rev_id', $dir, $startid, $endid);
+
+ // must manually initialize unset limit
+ if (is_null($limit))
+ $limit = 10;
+ $this->validateLimit($this->encodeParamName('limit'), $limit, 1, $userMax, $botMax);
+
+ // There is only one ID, use it
+ $this->addWhereFld('rev_page', current(array_keys($pageSet->getGoodTitles())));
+ }
+ elseif ($pageCount > 0) {
+ // When working in multi-page non-enumeration mode,
+ // limit to the latest revision only
+ $this->addTables('page');
+ $this->addWhere('page_id=rev_page');
+ $this->addWhere('page_latest=rev_id');
+ $this->validateLimit('page_count', $pageCount, 1, $userMax, $botMax);
+
+ // Get all page IDs
+ $this->addWhereFld('page_id', array_keys($pageSet->getGoodTitles()));
+
+ $limit = $pageCount; // assumption testing -- we should never get more then $pageCount rows.
+ }
+ elseif ($revCount > 0) {
+ $this->validateLimit('rev_count', $revCount, 1, $userMax, $botMax);
+
+ // Get all revision IDs
+ $this->addWhereFld('rev_id', array_keys($pageSet->getRevisionIDs()));
+
+ $limit = $revCount; // assumption testing -- we should never get more then $revCount rows.
+ } else
+ ApiBase :: dieDebug(__METHOD__, 'param validation?');
+
+ $this->addOption('LIMIT', $limit +1);
+
+ $data = array ();
+ $count = 0;
+ $res = $this->select(__METHOD__);
+
+ $db = & $this->getDB();
+ while ($row = $db->fetchObject($res)) {
+
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ if (!$enumRevMode)
+ ApiBase :: dieDebug(__METHOD__, 'Got more rows then expected'); // bug report
+ $this->setContinueEnumParameter('startid', $row->rev_id);
+ break;
+ }
+
+ $vals = $this->addRowInfo('rev', $row);
+ if ($vals) {
+ if ($showContent)
+ ApiResult :: setContent($vals, Revision :: getRevisionText($row));
+
+ $this->getResult()->addValue(array (
+ 'query',
+ 'pages',
+ intval($row->rev_page
+ ), 'revisions'), intval($row->rev_id), $vals);
+ }
+ }
+ $db->freeResult($res);
+
+ // Ensure that all revisions are shown as '<rev>' elements
+ $result = $this->getResult();
+ if ($result->getIsRawMode()) {
+ $data =& $result->getData();
+ foreach ($data['query']['pages'] as & $page) {
+ if (is_array($page) && array_key_exists('revisions', $page)) {
+ $result->setIndexedTagName($page['revisions'], 'rev');
+ }
+ }
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'timestamp',
+ 'user',
+ 'comment',
+ 'content'
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_SML1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_SML2
+ ),
+ 'startid' => array (
+ ApiBase :: PARAM_TYPE => 'integer'
+ ),
+ 'endid' => array (
+ ApiBase :: PARAM_TYPE => 'integer'
+ ),
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => 'Which properties to get for each revision.',
+ 'limit' => 'limit how many revisions will be returned (enum)',
+ 'startid' => 'from which revision id to start enumeration (enum)',
+ 'endid' => 'stop revision enumeration on this revid (enum)',
+ 'start' => 'from which revision timestamp to start enumeration (enum)',
+ 'end' => 'enumerate up to this timestamp (enum)',
+ 'dir' => 'direction of enumeration - towards "newer" or "older" revisions (enum)'
+ );
+ }
+
+ protected function getDescription() {
+ return array (
+ 'Get revision information.',
+ 'This module may be used in several ways:',
+ ' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter.',
+ ' 2) Get revisions for one given page, by using titles/pageids with start/end/limit params.',
+ ' 3) Get data about a set of revisions by setting their IDs with revids parameter.',
+ 'All parameters marked as (enum) may only be used with a single page (#2).'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'Get data with content for the last revision of titles "API" and "Main Page":',
+ ' api.php?action=query&prop=revisions&titles=API|Main%20Page&rvprop=timestamp|user|comment|content',
+ 'Get last 5 revisions of the "Main Page":',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment',
+ 'Get first 5 revisions of the "Main Page":',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer',
+ 'Get first 5 revisions of the "Main Page" made after 2006-05-01:',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer&rvstart=20060501000000'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiQuerySiteinfo.php b/includes/api/ApiQuerySiteinfo.php
new file mode 100644
index 000000000000..ea9601f770d6
--- /dev/null
+++ b/includes/api/ApiQuerySiteinfo.php
@@ -0,0 +1,116 @@
+<?php
+
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQuerySiteinfo extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'si');
+ }
+
+ public function execute() {
+ $prop = null;
+ extract($this->extractRequestParams());
+
+ foreach ($prop as $p) {
+ switch ($p) {
+
+ case 'general' :
+
+ global $wgSitename, $wgVersion, $wgCapitalLinks, $wgRightsCode, $wgRightsText;
+ $data = array ();
+ $mainPage = Title :: newFromText(wfMsgForContent('mainpage'));
+ $data['mainpage'] = $mainPage->getText();
+ $data['base'] = $mainPage->getFullUrl();
+ $data['sitename'] = $wgSitename;
+ $data['generator'] = "MediaWiki $wgVersion";
+ $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // 'case-insensitive' option is reserved for future
+ if (isset($wgRightsCode))
+ $data['rightscode'] = $wgRightsCode;
+ $data['rights'] = $wgRightsText;
+ $this->getResult()->addValue('query', $p, $data);
+ break;
+
+ case 'namespaces' :
+
+ global $wgContLang;
+ $data = array ();
+ foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) {
+ $data[$ns] = array (
+ 'id' => $ns
+ );
+ ApiResult :: setContent($data[$ns], $title);
+ }
+ $this->getResult()->setIndexedTagName($data, 'ns');
+ $this->getResult()->addValue('query', $p, $data);
+ break;
+
+ default :
+ ApiBase :: dieDebug(__METHOD__, "Unknown prop=$p");
+ }
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_DFLT => 'general',
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'general',
+ 'namespaces'
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => array (
+ 'Which sysinfo properties to get:',
+ ' "general" - Overall system information',
+ ' "namespaces" - List of registered namespaces (localized)'
+ )
+ );
+ }
+
+ protected function getDescription() {
+ return 'Return general information about the site.';
+ }
+
+ protected function getExamples() {
+ return 'api.php?action=query&meta=siteinfo&siprop=general|namespaces';
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/api/ApiQueryUserContributions.php b/includes/api/ApiQueryUserContributions.php
new file mode 100644
index 000000000000..e0bb692463ca
--- /dev/null
+++ b/includes/api/ApiQueryUserContributions.php
@@ -0,0 +1,175 @@
+<?php
+
+
+/*
+ * Created on Oct 16, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryContributions extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'uc');
+ }
+
+ public function execute() {
+
+ //Blank all our variables
+ $limit = $user = $start = $end = $dir = null;
+
+ //Get our parameters out
+ extract($this->extractRequestParams());
+
+ //Get a database instance
+ $db = & $this->getDB();
+
+ if (is_null($user))
+ $this->dieUsage("User parameter may not be empty", 'param_user');
+ $userid = $db->selectField('user', 'user_id', array (
+ 'user_name' => $user
+ ));
+ if (!$userid)
+ $this->dieUsage("User name $user not found", 'param_user');
+
+ //Get the table names
+ list ($tbl_page, $tbl_revision) = $db->tableNamesN('page', 'revision');
+
+ //We're after the revision table, and the corresponding page row for
+ //anything we retrieve.
+ $this->addTables("$tbl_revision LEFT OUTER JOIN $tbl_page ON " .
+ "page_id=rev_page");
+
+ //We want to know the namespace, title, new-ness, and ID of a page,
+ // and the id, text-id, timestamp, minor-status, summary and page
+ // of a revision.
+ $this->addFields(array('page_namespace', 'page_title', 'page_is_new',
+ 'rev_id', 'rev_text_id', 'rev_timestamp', 'rev_minor_edit',
+ 'rev_comment', 'rev_page'));
+
+ // We only want pages by the specified user.
+ $this->addWhereFld('rev_user_text', $user);
+ // ... and in the specified timeframe.
+ $this->addWhereRange('rev_timestamp', $dir, $start, $end );
+
+ $this->addOption('LIMIT', $limit + 1);
+
+ //Initialise some variables
+ $data = array ();
+ $count = 0;
+
+ //Do the actual query.
+ $res = $this->select( __METHOD__ );
+
+ //Fetch each row
+ while ( $row = $db->fetchObject( $res ) ) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', $row->rev_timestamp);
+ break;
+ }
+
+ //There's a fancy function in ApiQueryBase that does
+ // most of the work for us. Use that for the page
+ // and revision.
+ $revvals = $this->addRowInfo('rev', $row);
+ $pagevals = $this->addRowInfo('page', $row);
+
+ //If we got data on the revision only, use only
+ // that data.
+ if($revvals && !$pagevals) {
+ $data[] = $revvals;
+ }
+ //If we got data on the page only, use only
+ // that data.
+ else if($pagevals && !$revvals) {
+ $data[] = $pagevals;
+ }
+ //... and if we got data on both the revision and
+ // the page, merge the data and send it out.
+ else if($pagevals && $revvals) {
+ $data[] = array_merge($revvals, $pagevals);
+ }
+ }
+
+ //Free the database record so the connection can get on with other stuff
+ $db->freeResult($res);
+
+ //And send the whole shebang out as output.
+ $this->getResult()->setIndexedTagName($data, 'item');
+ $this->getResult()->addValue('query', $this->getModuleName(), $data);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'user' => null,
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'limit' => 'The maximum number of contributions to return.',
+ 'start' => 'The start timestamp to return from.',
+ 'end' => 'The end timestamp to return to.',
+ 'user' => 'The user to retrieve contributions for.',
+ 'dir' => 'The direction to search (older or newer).'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Get edits by a user..';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=usercontribs&ucuser=YurikBot'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiQueryWatchlist.php b/includes/api/ApiQueryWatchlist.php
new file mode 100644
index 000000000000..e2557e95fe70
--- /dev/null
+++ b/includes/api/ApiQueryWatchlist.php
@@ -0,0 +1,234 @@
+<?php
+
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryWatchlist extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'wl');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+ global $wgUser;
+
+ if (!$wgUser->isLoggedIn())
+ $this->dieUsage('You must be logged-in to have a watchlist', 'notloggedin');
+
+ $allrev = $start = $end = $namespace = $dir = $limit = $prop = null;
+ extract($this->extractRequestParams());
+
+ $patrol = $timestamp = $user = $comment = false;
+ if (!is_null($prop)) {
+ if (!is_null($resultPageSet))
+ $this->dieUsage('prop parameter may not be used in a generator', 'params');
+
+ $user = (false !== array_search('user', $prop));
+ $comment = (false !== array_search('comment', $prop));
+ $timestamp = (false !== array_search('timestamp', $prop)); // TODO: $timestamp not currently being used.
+ $patrol = (false !== array_search('patrol', $prop));
+
+ if ($patrol) {
+ global $wgUseRCPatrol, $wgUser;
+ if (!$wgUseRCPatrol || !$wgUser->isAllowed('patrol'))
+ $this->dieUsage('patrol property is not available', 'patrol');
+ }
+ }
+
+ if (is_null($resultPageSet)) {
+ $this->addFields(array (
+ 'rc_cur_id',
+ 'rc_this_oldid',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_new',
+ 'rc_minor',
+ 'rc_timestamp'
+ ));
+
+ $this->addFieldsIf('rc_user', $user);
+ $this->addFieldsIf('rc_user_text', $user);
+ $this->addFieldsIf('rc_comment', $comment);
+ $this->addFieldsIf('rc_patrolled', $patrol);
+ }
+ elseif ($allrev) {
+ $this->addFields(array (
+ 'rc_this_oldid',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_timestamp'
+ ));
+ } else {
+ $this->addFields(array (
+ 'rc_cur_id',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_timestamp'
+ ));
+ }
+
+ $this->addTables(array (
+ 'watchlist',
+ 'page',
+ 'recentchanges'
+ ));
+
+ $userId = $wgUser->getID();
+ $this->addWhere(array (
+ 'wl_namespace = rc_namespace',
+ 'wl_title = rc_title',
+ 'rc_cur_id = page_id',
+ 'wl_user' => $userId
+ ));
+ $this->addWhereRange('rc_timestamp', $dir, $start, $end);
+ $this->addWhereFld('wl_namespace', $namespace);
+ $this->addWhereIf('rc_this_oldid=page_latest', !$allrev);
+ $this->addWhereIf("rc_timestamp > ''", !isset ($start) && !isset ($end));
+
+ $this->addOption('LIMIT', $limit +1);
+
+ $data = array ();
+ $count = 0;
+ $res = $this->select(__METHOD__);
+
+ $db = $this->getDB();
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', $row->rc_timestamp);
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $vals = $this->addRowInfo('rc', $row);
+ if($vals)
+ $data[] = $vals;
+ } else {
+ $title = Title :: makeTitle($row->rc_namespace, $row->rc_title);
+ // skip any pages that user has no rights to read
+ if ($title->userCanRead()) {
+ if ($allrev) {
+ $data[] = intval($row->rc_this_oldid);
+ } else {
+ $data[] = intval($row->rc_cur_id);
+ }
+ }
+ }
+ }
+
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $this->getResult()->setIndexedTagName($data, 'item');
+ $this->getResult()->addValue('query', $this->getModuleName(), $data);
+ }
+ elseif ($allrev) {
+ $resultPageSet->populateFromRevisionIDs($data);
+ } else {
+ $resultPageSet->populateFromPageIDs($data);
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'allrev' => false,
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'prop' => array (
+ APIBase :: PARAM_ISMULTI => true,
+ APIBase :: PARAM_TYPE => array (
+ 'user',
+ 'comment',
+ 'timestamp',
+ 'patrol'
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'allrev' => 'Include multiple revisions of the same page within given timeframe.',
+ 'start' => 'The timestamp to start enumerating from.',
+ 'end' => 'The timestamp to end enumerating.',
+ 'namespace' => 'Filter changes to only the given namespace(s).',
+ 'dir' => 'In which direction to enumerate pages.',
+ 'limit' => 'How many total pages to return per request.',
+ 'prop' => 'Which additional items to get (non-generator mode only).'
+ );
+ }
+
+ protected function getDescription() {
+ return '';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=watchlist',
+ 'api.php?action=query&list=watchlist&wlallrev',
+ 'api.php?action=query&generator=watchlist&prop=info',
+ 'api.php?action=query&generator=watchlist&gwlallrev&prop=revisions&rvprop=timestamp|user'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
diff --git a/includes/api/ApiResult.php b/includes/api/ApiResult.php
new file mode 100644
index 000000000000..b56d7ac65807
--- /dev/null
+++ b/includes/api/ApiResult.php
@@ -0,0 +1,157 @@
+<?php
+
+
+/*
+ * Created on Sep 4, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+class ApiResult extends ApiBase {
+
+ private $mData, $mIsRawMode;
+
+ /**
+ * Constructor
+ */
+ public function __construct($main) {
+ parent :: __construct($main, 'result');
+ $this->mIsRawMode = false;
+ $this->reset();
+ }
+
+ public function reset() {
+ $this->mData = array ();
+ }
+
+ /**
+ * Call this function when special elements such as '_element'
+ * are needed by the formatter, for example in XML printing.
+ */
+ public function setRawMode() {
+ $this->mIsRawMode = true;
+ }
+
+ public function getIsRawMode() {
+ return $this->mIsRawMode;
+ }
+
+ public function & getData() {
+ return $this->mData;
+ }
+
+ /**
+ * Add an output value to the array by name.
+ * Verifies that value with the same name has not been added before.
+ */
+ public static function setElement(& $arr, $name, $value) {
+ if ($arr === null || $name === null || $value === null || !is_array($arr) || is_array($name))
+ ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
+
+ if (!isset ($arr[$name])) {
+ $arr[$name] = $value;
+ }
+ elseif (is_array($arr[$name]) && is_array($value)) {
+ $merged = array_intersect_key($arr[$name], $value);
+ if (empty ($merged))
+ $arr[$name] += $value;
+ else
+ ApiBase :: dieDebug(__METHOD__, "Attempting to merge element $name");
+ } else
+ ApiBase :: dieDebug(__METHOD__, "Attempting to add element $name=$value, existing value is {$arr[$name]}");
+ }
+
+ /**
+ * Adds the content element to the array.
+ * Use this function instead of hardcoding the '*' element.
+ * @param string $subElemName when present, content element is created as a sub item of the arr.
+ * Use this parameter to create elements in format <elem>text</elem> without attributes
+ */
+ public static function setContent(& $arr, $value, $subElemName = null) {
+ if (is_array($value))
+ ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
+ if (is_null($subElemName)) {
+ ApiResult :: setElement($arr, '*', $value);
+ } else {
+ if (!isset ($arr[$subElemName]))
+ $arr[$subElemName] = array ();
+ ApiResult :: setElement($arr[$subElemName], '*', $value);
+ }
+ }
+
+ // public static function makeContentElement($tag, $value) {
+ // $result = array();
+ // ApiResult::setContent($result, )
+ // }
+ //
+ /**
+ * In case the array contains indexed values (in addition to named),
+ * all indexed values will have the given tag name.
+ */
+ public function setIndexedTagName(& $arr, $tag) {
+ // In raw mode, add the '_element', otherwise just ignore
+ if (!$this->getIsRawMode())
+ return;
+ if ($arr === null || $tag === null || !is_array($arr) || is_array($tag))
+ ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
+ // Do not use setElement() as it is ok to call this more than once
+ $arr['_element'] = $tag;
+ }
+
+ /**
+ * Add value to the output data at the given path.
+ * Path is an indexed array, each element specifing the branch at which to add the new value
+ * Setting $path to array('a','b','c') is equivalent to data['a']['b']['c'] = $value
+ */
+ public function addValue($path, $name, $value) {
+
+ $data = & $this->getData();
+
+ if (!is_null($path)) {
+ if (is_array($path)) {
+ foreach ($path as $p) {
+ if (!isset ($data[$p]))
+ $data[$p] = array ();
+ $data = & $data[$p];
+ }
+ } else {
+ if (!isset ($data[$path]))
+ $data[$path] = array ();
+ $data = & $data[$path];
+ }
+ }
+
+ ApiResult :: setElement($data, $name, $value);
+ }
+
+ public function execute() {
+ ApiBase :: dieDebug(__METHOD__, 'execute() is not supported on Result object');
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?> \ No newline at end of file
diff --git a/includes/cbt/CBTCompiler.php b/includes/cbt/CBTCompiler.php
new file mode 100644
index 000000000000..59088bed0ffe
--- /dev/null
+++ b/includes/cbt/CBTCompiler.php
@@ -0,0 +1,367 @@
+<?php
+
+/**
+ * This file contains functions to convert callback templates to other languages.
+ * The template should first be pre-processed with CBTProcessor to remove static
+ * sections.
+ */
+
+
+require_once( dirname( __FILE__ ) . '/CBTProcessor.php' );
+
+/**
+ * Push a value onto the stack
+ * Argument 1: value
+ */
+define( 'CBT_PUSH', 1 );
+
+/**
+ * Pop, concatenate argument, push
+ * Argument 1: value
+ */
+define( 'CBT_CAT', 2 );
+
+/**
+ * Concatenate where the argument is on the stack, instead of immediate
+ */
+define( 'CBT_CATS', 3 );
+
+/**
+ * Call a function, push the return value onto the stack and put it in the cache
+ * Argument 1: argument count
+ *
+ * The arguments to the function are on the stack
+ */
+define( 'CBT_CALL', 4 );
+
+/**
+ * Pop, htmlspecialchars, push
+ */
+define( 'CBT_HX', 5 );
+
+class CBTOp {
+ var $opcode;
+ var $arg1;
+ var $arg2;
+
+ function CBTOp( $opcode, $arg1, $arg2 ) {
+ $this->opcode = $opcode;
+ $this->arg1 = $arg1;
+ $this->arg2 = $arg2;
+ }
+
+ function name() {
+ $opcodeNames = array(
+ CBT_PUSH => 'PUSH',
+ CBT_CAT => 'CAT',
+ CBT_CATS => 'CATS',
+ CBT_CALL => 'CALL',
+ CBT_HX => 'HX',
+ );
+ return $opcodeNames[$this->opcode];
+ }
+};
+
+class CBTCompiler {
+ var $mOps = array();
+ var $mCode;
+
+ function CBTCompiler( $text ) {
+ $this->mText = $text;
+ }
+
+ /**
+ * Compile the text.
+ * Returns true on success, error message on failure
+ */
+ function compile() {
+ $this->mLastError = false;
+ $this->mOps = array();
+
+ $this->doText( 0, strlen( $this->mText ) );
+
+ if ( $this->mLastError !== false ) {
+ $pos = $this->mErrorPos;
+
+ // Find the line number at which the error occurred
+ $startLine = 0;
+ $endLine = 0;
+ $line = 0;
+ do {
+ if ( $endLine ) {
+ $startLine = $endLine + 1;
+ }
+ $endLine = strpos( $this->mText, "\n", $startLine );
+ ++$line;
+ } while ( $endLine !== false && $endLine < $pos );
+
+ $text = "Template error at line $line: $this->mLastError\n<pre>\n";
+
+ $context = rtrim( str_replace( "\t", " ", substr( $this->mText, $startLine, $endLine - $startLine ) ) );
+ $text .= htmlspecialchars( $context ) . "\n" . str_repeat( ' ', $pos - $startLine ) . "^\n</pre>\n";
+ } else {
+ $text = true;
+ }
+
+ return $text;
+ }
+
+ /** Shortcut for doOpenText( $start, $end, false */
+ function doText( $start, $end ) {
+ return $this->doOpenText( $start, $end, false );
+ }
+
+ function phpQuote( $text ) {
+ return "'" . strtr( $text, array( "\\" => "\\\\", "'" => "\\'" ) ) . "'";
+ }
+
+ function op( $opcode, $arg1 = null, $arg2 = null) {
+ return new CBTOp( $opcode, $arg1, $arg2 );
+ }
+
+ /**
+ * Recursive workhorse for text mode.
+ *
+ * Processes text mode starting from offset $p, until either $end is
+ * reached or a closing brace is found. If $needClosing is false, a
+ * closing brace will flag an error, if $needClosing is true, the lack
+ * of a closing brace will flag an error.
+ *
+ * The parameter $p is advanced to the position after the closing brace,
+ * or after the end. A CBTValue is returned.
+ *
+ * @private
+ */
+ function doOpenText( &$p, $end, $needClosing = true ) {
+ $in =& $this->mText;
+ $start = $p;
+ $atStart = true;
+
+ $foundClosing = false;
+ while ( $p < $end ) {
+ $matchLength = strcspn( $in, CBT_BRACE, $p, $end - $p );
+ $pToken = $p + $matchLength;
+
+ if ( $pToken >= $end ) {
+ // No more braces, output remainder
+ if ( $atStart ) {
+ $this->mOps[] = $this->op( CBT_PUSH, substr( $in, $p ) );
+ $atStart = false;
+ } else {
+ $this->mOps[] = $this->op( CBT_CAT, substr( $in, $p ) );
+ }
+ $p = $end;
+ break;
+ }
+
+ // Output the text before the brace
+ if ( $atStart ) {
+ $this->mOps[] = $this->op( CBT_PUSH, substr( $in, $p, $matchLength ) );
+ $atStart = false;
+ } else {
+ $this->mOps[] = $this->op( CBT_CAT, substr( $in, $p, $matchLength ) );
+ }
+
+ // Advance the pointer
+ $p = $pToken + 1;
+
+ // Check for closing brace
+ if ( $in[$pToken] == '}' ) {
+ $foundClosing = true;
+ break;
+ }
+
+ // Handle the "{fn}" special case
+ if ( $pToken > 0 && $in[$pToken-1] == '"' ) {
+ $this->doOpenFunction( $p, $end );
+ if ( $p < $end && $in[$p] == '"' ) {
+ $this->mOps[] = $this->op( CBT_HX );
+ }
+ } else {
+ $this->doOpenFunction( $p, $end );
+ }
+ if ( $atStart ) {
+ $atStart = false;
+ } else {
+ $this->mOps[] = $this->op( CBT_CATS );
+ }
+ }
+ if ( $foundClosing && !$needClosing ) {
+ $this->error( 'Errant closing brace', $p );
+ } elseif ( !$foundClosing && $needClosing ) {
+ $this->error( 'Unclosed text section', $start );
+ } else {
+ if ( $atStart ) {
+ $this->mOps[] = $this->op( CBT_PUSH, '' );
+ }
+ }
+ }
+
+ /**
+ * Recursive workhorse for function mode.
+ *
+ * Processes function mode starting from offset $p, until either $end is
+ * reached or a closing brace is found. If $needClosing is false, a
+ * closing brace will flag an error, if $needClosing is true, the lack
+ * of a closing brace will flag an error.
+ *
+ * The parameter $p is advanced to the position after the closing brace,
+ * or after the end. A CBTValue is returned.
+ *
+ * @private
+ */
+ function doOpenFunction( &$p, $end, $needClosing = true ) {
+ $in =& $this->mText;
+ $start = $p;
+ $argCount = 0;
+
+ $foundClosing = false;
+ while ( $p < $end ) {
+ $char = $in[$p];
+ if ( $char == '{' ) {
+ // Switch to text mode
+ ++$p;
+ $this->doOpenText( $p, $end );
+ ++$argCount;
+ } elseif ( $char == '}' ) {
+ // Block end
+ ++$p;
+ $foundClosing = true;
+ break;
+ } elseif ( false !== strpos( CBT_WHITE, $char ) ) {
+ // Whitespace
+ // Consume the rest of the whitespace
+ $p += strspn( $in, CBT_WHITE, $p, $end - $p );
+ } else {
+ // Token, find the end of it
+ $tokenLength = strcspn( $in, CBT_DELIM, $p, $end - $p );
+ $this->mOps[] = $this->op( CBT_PUSH, substr( $in, $p, $tokenLength ) );
+
+ // Execute the token as a function if it's not the function name
+ if ( $argCount ) {
+ $this->mOps[] = $this->op( CBT_CALL, 1 );
+ }
+
+ $p += $tokenLength;
+ ++$argCount;
+ }
+ }
+ if ( !$foundClosing && $needClosing ) {
+ $this->error( 'Unclosed function', $start );
+ return '';
+ }
+
+ $this->mOps[] = $this->op( CBT_CALL, $argCount );
+ }
+
+ /**
+ * Set a flag indicating that an error has been found.
+ */
+ function error( $text, $pos = false ) {
+ $this->mLastError = $text;
+ if ( $pos === false ) {
+ $this->mErrorPos = $this->mCurrentPos;
+ } else {
+ $this->mErrorPos = $pos;
+ }
+ }
+
+ function getLastError() {
+ return $this->mLastError;
+ }
+
+ function opsToString() {
+ $s = '';
+ foreach( $this->mOps as $op ) {
+ $s .= $op->name();
+ if ( !is_null( $op->arg1 ) ) {
+ $s .= ' ' . var_export( $op->arg1, true );
+ }
+ if ( !is_null( $op->arg2 ) ) {
+ $s .= ' ' . var_export( $op->arg2, true );
+ }
+ $s .= "\n";
+ }
+ return $s;
+ }
+
+ function generatePHP( $functionObj ) {
+ $fname = 'CBTCompiler::generatePHP';
+ wfProfileIn( $fname );
+ $stack = array();
+
+ foreach( $this->mOps as $op ) {
+ switch( $op->opcode ) {
+ case CBT_PUSH:
+ $stack[] = $this->phpQuote( $op->arg1 );
+ break;
+ case CBT_CAT:
+ $val = array_pop( $stack );
+ array_push( $stack, "$val . " . $this->phpQuote( $op->arg1 ) );
+ break;
+ case CBT_CATS:
+ $right = array_pop( $stack );
+ $left = array_pop( $stack );
+ array_push( $stack, "$left . $right" );
+ break;
+ case CBT_CALL:
+ $args = array_slice( $stack, count( $stack ) - $op->arg1, $op->arg1 );
+ $stack = array_slice( $stack, 0, count( $stack ) - $op->arg1 );
+
+ // Some special optimised expansions
+ if ( $op->arg1 == 0 ) {
+ $result = '';
+ } else {
+ $func = array_shift( $args );
+ if ( substr( $func, 0, 1 ) == "'" && substr( $func, -1 ) == "'" ) {
+ $func = substr( $func, 1, strlen( $func ) - 2 );
+ if ( $func == "if" ) {
+ if ( $op->arg1 < 3 ) {
+ // This should have been caught during processing
+ return "Not enough arguments to if";
+ } elseif ( $op->arg1 == 3 ) {
+ $result = "(({$args[0]} != '') ? ({$args[1]}) : '')";
+ } else {
+ $result = "(({$args[0]} != '') ? ({$args[1]}) : ({$args[2]}))";
+ }
+ } elseif ( $func == "true" ) {
+ $result = "true";
+ } elseif( $func == "lbrace" || $func == "{" ) {
+ $result = "{";
+ } elseif( $func == "rbrace" || $func == "}" ) {
+ $result = "}";
+ } elseif ( $func == "escape" || $func == "~" ) {
+ $result = "htmlspecialchars({$args[0]})";
+ } else {
+ // Known function name
+ $result = "{$functionObj}->{$func}(" . implode( ', ', $args ) . ')';
+ }
+ } else {
+ // Unknown function name
+ $result = "call_user_func(array($functionObj, $func), " . implode( ', ', $args ) . ' )';
+ }
+ }
+ array_push( $stack, $result );
+ break;
+ case CBT_HX:
+ $val = array_pop( $stack );
+ array_push( $stack, "htmlspecialchars( $val )" );
+ break;
+ default:
+ return "Unknown opcode {$op->opcode}\n";
+ }
+ }
+ wfProfileOut( $fname );
+ if ( count( $stack ) !== 1 ) {
+ return "Error, stack count incorrect\n";
+ }
+ return '
+ global $cbtExecutingGenerated;
+ ++$cbtExecutingGenerated;
+ $output = ' . $stack[0] . ';
+ --$cbtExecutingGenerated;
+ return $output;
+ ';
+ }
+}
+?>
diff --git a/includes/cbt/CBTProcessor.php b/includes/cbt/CBTProcessor.php
new file mode 100644
index 000000000000..0c34204e6674
--- /dev/null
+++ b/includes/cbt/CBTProcessor.php
@@ -0,0 +1,540 @@
+<?php
+
+/**
+ * PHP version of the callback template processor
+ * This is currently used as a test rig and is likely to be used for
+ * compatibility purposes later, where the C++ extension is not available.
+ */
+
+define( 'CBT_WHITE', " \t\r\n" );
+define( 'CBT_BRACE', '{}' );
+define( 'CBT_DELIM', CBT_WHITE . CBT_BRACE );
+define( 'CBT_DEBUG', 0 );
+
+$GLOBALS['cbtExecutingGenerated'] = 0;
+
+/**
+ * Attempting to be a MediaWiki-independent module
+ */
+if ( !function_exists( 'wfProfileIn' ) ) {
+ function wfProfileIn() {}
+}
+if ( !function_exists( 'wfProfileOut' ) ) {
+ function wfProfileOut() {}
+}
+
+/**
+ * Escape text for inclusion in template
+ */
+function cbt_escape( $text ) {
+ return strtr( $text, array( '{' => '{[}', '}' => '{]}' ) );
+}
+
+/**
+ * Create a CBTValue
+ */
+function cbt_value( $text = '', $deps = array(), $isTemplate = false ) {
+ global $cbtExecutingGenerated;
+ if ( $cbtExecutingGenerated ) {
+ return $text;
+ } else {
+ return new CBTValue( $text, $deps, $isTemplate );
+ }
+}
+
+/**
+ * A dependency-tracking value class
+ * Callback functions should return one of these, unless they have
+ * no dependencies in which case they can return a string.
+ */
+class CBTValue {
+ var $mText, $mDeps, $mIsTemplate;
+
+ /**
+ * Create a new value
+ * @param $text String: , default ''.
+ * @param $deps Array: what this value depends on
+ * @param $isTemplate Bool: whether the result needs compilation/execution, default 'false'.
+ */
+ function CBTValue( $text = '', $deps = array(), $isTemplate = false ) {
+ $this->mText = $text;
+ if ( !is_array( $deps ) ) {
+ $this->mDeps = array( $deps ) ;
+ } else {
+ $this->mDeps = $deps;
+ }
+ $this->mIsTemplate = $isTemplate;
+ }
+
+ /** Concatenate two values, merging their dependencies */
+ function cat( $val ) {
+ if ( is_object( $val ) ) {
+ $this->addDeps( $val );
+ $this->mText .= $val->mText;
+ } else {
+ $this->mText .= $val;
+ }
+ }
+
+ /** Add the dependencies of another value to this one */
+ function addDeps( $values ) {
+ if ( !is_array( $values ) ) {
+ $this->mDeps = array_merge( $this->mDeps, $values->mDeps );
+ } else {
+ foreach ( $values as $val ) {
+ if ( !is_object( $val ) ) {
+ var_dump( debug_backtrace() );
+ exit;
+ }
+ $this->mDeps = array_merge( $this->mDeps, $val->mDeps );
+ }
+ }
+ }
+
+ /** Remove a list of dependencies */
+ function removeDeps( $deps ) {
+ $this->mDeps = array_diff( $this->mDeps, $deps );
+ }
+
+ function setText( $text ) {
+ $this->mText = $text;
+ }
+
+ function getText() {
+ return $this->mText;
+ }
+
+ function getDeps() {
+ return $this->mDeps;
+ }
+
+ /** If the value is a template, execute it */
+ function execute( &$processor ) {
+ if ( $this->mIsTemplate ) {
+ $myProcessor = new CBTProcessor( $this->mText, $processor->mFunctionObj, $processor->mIgnorableDeps );
+ $myProcessor->mCompiling = $processor->mCompiling;
+ $val = $myProcessor->doText( 0, strlen( $this->mText ) );
+ if ( $myProcessor->getLastError() ) {
+ $processor->error( $myProcessor->getLastError() );
+ $this->mText = '';
+ } else {
+ $this->mText = $val->mText;
+ $this->addDeps( $val );
+ }
+ if ( !$processor->mCompiling ) {
+ $this->mIsTemplate = false;
+ }
+ }
+ }
+
+ /** If the value is plain text, escape it for inclusion in a template */
+ function templateEscape() {
+ if ( !$this->mIsTemplate ) {
+ $this->mText = cbt_escape( $this->mText );
+ }
+ }
+
+ /** Return true if the value has no dependencies */
+ function isStatic() {
+ return count( $this->mDeps ) == 0;
+ }
+}
+
+/**
+ * Template processor, for compilation and execution
+ */
+class CBTProcessor {
+ var $mText, # The text being processed
+ $mFunctionObj, # The object containing callback functions
+ $mCompiling = false, # True if compiling to a template, false if executing to text
+ $mIgnorableDeps = array(), # Dependency names which should be treated as static
+ $mFunctionCache = array(), # A cache of function results keyed by argument hash
+ $mLastError = false, # Last error message or false for no error
+ $mErrorPos = 0, # Last error position
+
+ /** Built-in functions */
+ $mBuiltins = array(
+ 'if' => 'bi_if',
+ 'true' => 'bi_true',
+ '[' => 'bi_lbrace',
+ 'lbrace' => 'bi_lbrace',
+ ']' => 'bi_rbrace',
+ 'rbrace' => 'bi_rbrace',
+ 'escape' => 'bi_escape',
+ '~' => 'bi_escape',
+ );
+
+ /**
+ * Create a template processor for a given text, callback object and static dependency list
+ */
+ function CBTProcessor( $text, $functionObj, $ignorableDeps = array() ) {
+ $this->mText = $text;
+ $this->mFunctionObj = $functionObj;
+ $this->mIgnorableDeps = $ignorableDeps;
+ }
+
+ /**
+ * Execute the template.
+ * If $compile is true, produces an optimised template where functions with static
+ * dependencies have been replaced by their return values.
+ */
+ function execute( $compile = false ) {
+ $fname = 'CBTProcessor::execute';
+ wfProfileIn( $fname );
+ $this->mCompiling = $compile;
+ $this->mLastError = false;
+ $val = $this->doText( 0, strlen( $this->mText ) );
+ $text = $val->getText();
+ if ( $this->mLastError !== false ) {
+ $pos = $this->mErrorPos;
+
+ // Find the line number at which the error occurred
+ $startLine = 0;
+ $endLine = 0;
+ $line = 0;
+ do {
+ if ( $endLine ) {
+ $startLine = $endLine + 1;
+ }
+ $endLine = strpos( $this->mText, "\n", $startLine );
+ ++$line;
+ } while ( $endLine !== false && $endLine < $pos );
+
+ $text = "Template error at line $line: $this->mLastError\n<pre>\n";
+
+ $context = rtrim( str_replace( "\t", " ", substr( $this->mText, $startLine, $endLine - $startLine ) ) );
+ $text .= htmlspecialchars( $context ) . "\n" . str_repeat( ' ', $pos - $startLine ) . "^\n</pre>\n";
+ }
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ /** Shortcut for execute(true) */
+ function compile() {
+ $fname = 'CBTProcessor::compile';
+ wfProfileIn( $fname );
+ $s = $this->execute( true );
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ /** Shortcut for doOpenText( $start, $end, false */
+ function doText( $start, $end ) {
+ return $this->doOpenText( $start, $end, false );
+ }
+
+ /**
+ * Escape text for a template if we are producing a template. Do nothing
+ * if we are producing plain text.
+ */
+ function templateEscape( $text ) {
+ if ( $this->mCompiling ) {
+ return cbt_escape( $text );
+ } else {
+ return $text;
+ }
+ }
+
+ /**
+ * Recursive workhorse for text mode.
+ *
+ * Processes text mode starting from offset $p, until either $end is
+ * reached or a closing brace is found. If $needClosing is false, a
+ * closing brace will flag an error, if $needClosing is true, the lack
+ * of a closing brace will flag an error.
+ *
+ * The parameter $p is advanced to the position after the closing brace,
+ * or after the end. A CBTValue is returned.
+ *
+ * @private
+ */
+ function doOpenText( &$p, $end, $needClosing = true ) {
+ $fname = 'CBTProcessor::doOpenText';
+ wfProfileIn( $fname );
+ $in =& $this->mText;
+ $start = $p;
+ $ret = new CBTValue( '', array(), $this->mCompiling );
+
+ $foundClosing = false;
+ while ( $p < $end ) {
+ $matchLength = strcspn( $in, CBT_BRACE, $p, $end - $p );
+ $pToken = $p + $matchLength;
+
+ if ( $pToken >= $end ) {
+ // No more braces, output remainder
+ $ret->cat( substr( $in, $p ) );
+ $p = $end;
+ break;
+ }
+
+ // Output the text before the brace
+ $ret->cat( substr( $in, $p, $matchLength ) );
+
+ // Advance the pointer
+ $p = $pToken + 1;
+
+ // Check for closing brace
+ if ( $in[$pToken] == '}' ) {
+ $foundClosing = true;
+ break;
+ }
+
+ // Handle the "{fn}" special case
+ if ( $pToken > 0 && $in[$pToken-1] == '"' ) {
+ wfProfileOut( $fname );
+ $val = $this->doOpenFunction( $p, $end );
+ wfProfileIn( $fname );
+ if ( $p < $end && $in[$p] == '"' ) {
+ $val->setText( htmlspecialchars( $val->getText() ) );
+ }
+ $ret->cat( $val );
+ } else {
+ // Process the function mode component
+ wfProfileOut( $fname );
+ $ret->cat( $this->doOpenFunction( $p, $end ) );
+ wfProfileIn( $fname );
+ }
+ }
+ if ( $foundClosing && !$needClosing ) {
+ $this->error( 'Errant closing brace', $p );
+ } elseif ( !$foundClosing && $needClosing ) {
+ $this->error( 'Unclosed text section', $start );
+ }
+ wfProfileOut( $fname );
+ return $ret;
+ }
+
+ /**
+ * Recursive workhorse for function mode.
+ *
+ * Processes function mode starting from offset $p, until either $end is
+ * reached or a closing brace is found. If $needClosing is false, a
+ * closing brace will flag an error, if $needClosing is true, the lack
+ * of a closing brace will flag an error.
+ *
+ * The parameter $p is advanced to the position after the closing brace,
+ * or after the end. A CBTValue is returned.
+ *
+ * @private
+ */
+ function doOpenFunction( &$p, $end, $needClosing = true ) {
+ $in =& $this->mText;
+ $start = $p;
+ $tokens = array();
+ $unexecutedTokens = array();
+
+ $foundClosing = false;
+ while ( $p < $end ) {
+ $char = $in[$p];
+ if ( $char == '{' ) {
+ // Switch to text mode
+ ++$p;
+ $tokenStart = $p;
+ $token = $this->doOpenText( $p, $end );
+ $tokens[] = $token;
+ $unexecutedTokens[] = '{' . substr( $in, $tokenStart, $p - $tokenStart - 1 ) . '}';
+ } elseif ( $char == '}' ) {
+ // Block end
+ ++$p;
+ $foundClosing = true;
+ break;
+ } elseif ( false !== strpos( CBT_WHITE, $char ) ) {
+ // Whitespace
+ // Consume the rest of the whitespace
+ $p += strspn( $in, CBT_WHITE, $p, $end - $p );
+ } else {
+ // Token, find the end of it
+ $tokenLength = strcspn( $in, CBT_DELIM, $p, $end - $p );
+ $token = new CBTValue( substr( $in, $p, $tokenLength ) );
+ // Execute the token as a function if it's not the function name
+ if ( count( $tokens ) ) {
+ $tokens[] = $this->doFunction( array( $token ), $p );
+ } else {
+ $tokens[] = $token;
+ }
+ $unexecutedTokens[] = $token->getText();
+
+ $p += $tokenLength;
+ }
+ }
+ if ( !$foundClosing && $needClosing ) {
+ $this->error( 'Unclosed function', $start );
+ return '';
+ }
+
+ $val = $this->doFunction( $tokens, $start );
+ if ( $this->mCompiling && !$val->isStatic() ) {
+ $compiled = '';
+ $first = true;
+ foreach( $tokens as $i => $token ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $compiled .= ' ';
+ }
+ if ( $token->isStatic() ) {
+ if ( $i !== 0 ) {
+ $compiled .= '{' . $token->getText() . '}';
+ } else {
+ $compiled .= $token->getText();
+ }
+ } else {
+ $compiled .= $unexecutedTokens[$i];
+ }
+ }
+
+ // The dynamic parts of the string are still represented as functions, and
+ // function invocations have no dependencies. Thus the compiled result has
+ // no dependencies.
+ $val = new CBTValue( "{{$compiled}}", array(), true );
+ }
+ return $val;
+ }
+
+ /**
+ * Execute a function, caching and returning the result value.
+ * $tokens is an array of CBTValue objects. $tokens[0] is the function
+ * name, the others are arguments. $p is the string position, and is used
+ * for error messages only.
+ */
+ function doFunction( $tokens, $p ) {
+ if ( count( $tokens ) == 0 ) {
+ return new CBTValue;
+ }
+ $fname = 'CBTProcessor::doFunction';
+ wfProfileIn( $fname );
+
+ $ret = new CBTValue;
+
+ // All functions implicitly depend on their arguments, and the function name
+ // While this is not strictly necessary for all functions, it's true almost
+ // all the time and so convenient to do automatically.
+ $ret->addDeps( $tokens );
+
+ $this->mCurrentPos = $p;
+ $func = array_shift( $tokens );
+ $func = $func->getText();
+
+ // Extract the text component from all the tokens
+ // And convert any templates to plain text
+ $textArgs = array();
+ foreach ( $tokens as $token ) {
+ $token->execute( $this );
+ $textArgs[] = $token->getText();
+ }
+
+ // Try the local cache
+ $cacheKey = $func . "\n" . implode( "\n", $textArgs );
+ if ( isset( $this->mFunctionCache[$cacheKey] ) ) {
+ $val = $this->mFunctionCache[$cacheKey];
+ } elseif ( isset( $this->mBuiltins[$func] ) ) {
+ $func = $this->mBuiltins[$func];
+ $val = call_user_func_array( array( &$this, $func ), $tokens );
+ $this->mFunctionCache[$cacheKey] = $val;
+ } elseif ( method_exists( $this->mFunctionObj, $func ) ) {
+ $profName = get_class( $this->mFunctionObj ) . '::' . $func;
+ wfProfileIn( "$fname-callback" );
+ wfProfileIn( $profName );
+ $val = call_user_func_array( array( &$this->mFunctionObj, $func ), $textArgs );
+ wfProfileOut( $profName );
+ wfProfileOut( "$fname-callback" );
+ $this->mFunctionCache[$cacheKey] = $val;
+ } else {
+ $this->error( "Call of undefined function \"$func\"", $p );
+ $val = new CBTValue;
+ }
+ if ( !is_object( $val ) ) {
+ $val = new CBTValue((string)$val);
+ }
+
+ if ( CBT_DEBUG ) {
+ $unexpanded = $val;
+ }
+
+ // If the output was a template, execute it
+ $val->execute( $this );
+
+ if ( $this->mCompiling ) {
+ // Escape any braces so that the output will be a valid template
+ $val->templateEscape();
+ }
+ $val->removeDeps( $this->mIgnorableDeps );
+ $ret->addDeps( $val );
+ $ret->setText( $val->getText() );
+
+ if ( CBT_DEBUG ) {
+ wfDebug( "doFunction $func args = "
+ . var_export( $tokens, true )
+ . "unexpanded return = "
+ . var_export( $unexpanded, true )
+ . "expanded return = "
+ . var_export( $ret, true )
+ );
+ }
+
+ wfProfileOut( $fname );
+ return $ret;
+ }
+
+ /**
+ * Set a flag indicating that an error has been found.
+ */
+ function error( $text, $pos = false ) {
+ $this->mLastError = $text;
+ if ( $pos === false ) {
+ $this->mErrorPos = $this->mCurrentPos;
+ } else {
+ $this->mErrorPos = $pos;
+ }
+ }
+
+ function getLastError() {
+ return $this->mLastError;
+ }
+
+ /** 'if' built-in function */
+ function bi_if( $condition, $trueBlock, $falseBlock = null ) {
+ if ( is_null( $condition ) ) {
+ $this->error( "Missing condition in if" );
+ return '';
+ }
+
+ if ( $condition->getText() != '' ) {
+ return new CBTValue( $trueBlock->getText(),
+ array_merge( $condition->getDeps(), $trueBlock->getDeps() ),
+ $trueBlock->mIsTemplate );
+ } else {
+ if ( !is_null( $falseBlock ) ) {
+ return new CBTValue( $falseBlock->getText(),
+ array_merge( $condition->getDeps(), $falseBlock->getDeps() ),
+ $falseBlock->mIsTemplate );
+ } else {
+ return new CBTValue( '', $condition->getDeps() );
+ }
+ }
+ }
+
+ /** 'true' built-in function */
+ function bi_true() {
+ return "true";
+ }
+
+ /** left brace built-in */
+ function bi_lbrace() {
+ return '{';
+ }
+
+ /** right brace built-in */
+ function bi_rbrace() {
+ return '}';
+ }
+
+ /**
+ * escape built-in.
+ * Escape text for inclusion in an HTML attribute
+ */
+ function bi_escape( $val ) {
+ return new CBTValue( htmlspecialchars( $val->getText() ), $val->getDeps() );
+ }
+}
+?>
diff --git a/includes/cbt/README b/includes/cbt/README
new file mode 100644
index 000000000000..cffcef2f21ce
--- /dev/null
+++ b/includes/cbt/README
@@ -0,0 +1,108 @@
+Overview
+--------
+
+CBT (callback-based templates) is an experimental system for improving skin
+rendering time in MediaWiki and similar applications. The fundamental concept is
+a template language which contains tags which pull text from PHP callbacks.
+These PHP callbacks do not simply return text, they also return a description of
+the dependencies -- the global data upon which the returned text depends. This
+allows a compiler to produce a template optimised for a certain context. For
+example, a user-dependent template can be produced, with the username replaced
+by static text, as well as all user preference dependent text.
+
+This was an experimental project to prove the concept -- to explore possible
+efficiency gains and techniques. TemplateProcessor was the first element of this
+experiment. It is a class written in PHP which parses a template, and produces
+either an optimised template with dependencies removed, or the output text
+itself. I found that even with a heavily optimised template, this processor was
+not fast enough to match the speed of the original MonoBook.
+
+To improve the efficiency, I wrote TemplateCompiler, which takes a template,
+preferably pre-optimised by TemplateProcessor, and generates PHP code from it.
+The generated code is a single expression, concatenating static text and
+callback results. This approach turned out to be very efficient, making
+significant time savings compared to the original MonoBook.
+
+Despite this success, the code has been shelved for the time being. There were
+a number of unresolved implementation problems, and I felt that there were more
+pressing priorities for MediaWiki development than solving them and bringing
+this module to completion. I also believe that more research is needed into
+other possible template architectures. There is nothing fundamentally wrong with
+the CBT concept, and I would encourage others to continue its development.
+
+The problems I saw were:
+
+* Extensibility. Can non-Wikimedia installations easily extend and modify CBT
+ skins? Patching seems to be necessary, is this acceptable? MediaWiki
+ extensions are another problem. Unless the interfaces allow them to return
+ dependencies, any hooks will have to be marked dynamic and thus inefficient.
+
+* Cache invalidation. This is a simple implementation issue, although it would
+ require extensive modification to the MediaWiki core.
+
+* Syntax. The syntax is minimalistic and easy to parse, but can be quite ugly.
+ Will generations of MediaWiki users curse my name?
+
+* Security. The code produced by TemplateCompiler is best stored in memcached
+ and executed with eval(). This allows anyone with access to the memcached port
+ to run code as the apache user.
+
+
+Template syntax
+---------------
+
+There are two modes: text mode and function mode. The brace characters "{"
+and "}" are the only reserved characters. Either one of them will switch from
+text mode to function mode wherever they appear, no exceptions.
+
+In text mode, all characters are passed through to the output. In function
+mode, text is split into tokens, delimited either by whitespace or by
+matching pairs of braces. The first token is taken to be a function name. The
+other tokens are first processed in function mode themselves, then they are
+passed to the named function as parameters. The return value of the function
+is passed through to the output.
+
+Example:
+ {escape {"hello"}}
+
+First brace switches to function mode. The function name is escape, the first
+and only parameter is {"hello"}. This parameter is executed. The braces around
+the parameter cause the parser to switch to text mode, thus the string "hello",
+including the quotes, is passed back and used as an argument to the escape
+function.
+
+Example:
+ {if title {<h1>{title}</h1>}}
+
+The function name is "if". The first parameter is the result of calling the
+function "title". The second parameter is a level 1 HTML heading containing
+the result of the function "title". "if" is a built-in function which will
+return the second parameter only if the first is non-blank, so the effect of
+this is to return a heading element only if a title exists.
+
+As a shortcut for generation of HTML attributes, if a function mode segment is
+surrounded by double quotes, quote characters in the return value will be
+escaped. This only applies if the quote character immediately precedes the
+opening brace, and immediately follows the closing brace, with no whitespace.
+
+User callback functions are defined by passing a function object to the
+template processor. Function names appearing in the text are first checked
+against built-in function names, then against the method names in the function
+object. The function object forms a sandbox for execution of the template, so
+security-conscious users may wish to avoid including functions that allow
+arbitrary filesystem access or code execution.
+
+The callback function will receive its parameters as strings. If the
+result of the function depends only on the arguments, and certain things
+understood to be "static", such as the source code, then the callback function
+should return a string. If the result depends on other things, then the function
+should call cbt_value() to get a return value:
+
+ return cbt_value( $text, $deps );
+
+where $deps is an array of string tokens, each one naming a dependency. As a
+shortcut, if there is only one dependency, $deps may be a string.
+
+
+---------------------
+Tim Starling 2006
diff --git a/includes/memcached-client.php b/includes/memcached-client.php
new file mode 100644
index 000000000000..2c5cc6be776a
--- /dev/null
+++ b/includes/memcached-client.php
@@ -0,0 +1,1088 @@
+<?php
+//
+// +---------------------------------------------------------------------------+
+// | memcached client, PHP |
+// +---------------------------------------------------------------------------+
+// | Copyright (c) 2003 Ryan T. Dean <rtdean@cytherianage.net> |
+// | All rights reserved. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | 1. Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | 2. Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
+// | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
+// | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
+// | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
+// | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
+// | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+// +---------------------------------------------------------------------------+
+// | Author: Ryan T. Dean <rtdean@cytherianage.net> |
+// | Heavily influenced by the Perl memcached client by Brad Fitzpatrick. |
+// | Permission granted by Brad Fitzpatrick for relicense of ported Perl |
+// | client logic under 2-clause BSD license. |
+// +---------------------------------------------------------------------------+
+//
+// $TCAnet$
+//
+
+/**
+ * This is the PHP client for memcached - a distributed memory cache daemon.
+ * More information is available at http://www.danga.com/memcached/
+ *
+ * Usage example:
+ *
+ * require_once 'memcached.php';
+ *
+ * $mc = new memcached(array(
+ * 'servers' => array('127.0.0.1:10000',
+ * array('192.0.0.1:10010', 2),
+ * '127.0.0.1:10020'),
+ * 'debug' => false,
+ * 'compress_threshold' => 10240,
+ * 'persistant' => true));
+ *
+ * $mc->add('key', array('some', 'array'));
+ * $mc->replace('key', 'some random string');
+ * $val = $mc->get('key');
+ *
+ * @author Ryan T. Dean <rtdean@cytherianage.net>
+ * @package memcached-client
+ * @version 0.1.2
+ */
+
+// {{{ requirements
+// }}}
+
+// {{{ constants
+// {{{ flags
+
+/**
+ * Flag: indicates data is serialized
+ */
+define("MEMCACHE_SERIALIZED", 1<<0);
+
+/**
+ * Flag: indicates data is compressed
+ */
+define("MEMCACHE_COMPRESSED", 1<<1);
+
+// }}}
+
+/**
+ * Minimum savings to store data compressed
+ */
+define("COMPRESSION_SAVINGS", 0.20);
+
+// }}}
+
+// {{{ class memcached
+/**
+ * memcached client class implemented using (p)fsockopen()
+ *
+ * @author Ryan T. Dean <rtdean@cytherianage.net>
+ * @package memcached-client
+ */
+class memcached
+{
+ // {{{ properties
+ // {{{ public
+
+ /**
+ * Command statistics
+ *
+ * @var array
+ * @access public
+ */
+ var $stats;
+
+ // }}}
+ // {{{ private
+
+ /**
+ * Cached Sockets that are connected
+ *
+ * @var array
+ * @access private
+ */
+ var $_cache_sock;
+
+ /**
+ * Current debug status; 0 - none to 9 - profiling
+ *
+ * @var boolean
+ * @access private
+ */
+ var $_debug;
+
+ /**
+ * Dead hosts, assoc array, 'host'=>'unixtime when ok to check again'
+ *
+ * @var array
+ * @access private
+ */
+ var $_host_dead;
+
+ /**
+ * Is compression available?
+ *
+ * @var boolean
+ * @access private
+ */
+ var $_have_zlib;
+
+ /**
+ * Do we want to use compression?
+ *
+ * @var boolean
+ * @access private
+ */
+ var $_compress_enable;
+
+ /**
+ * At how many bytes should we compress?
+ *
+ * @var interger
+ * @access private
+ */
+ var $_compress_threshold;
+
+ /**
+ * Are we using persistant links?
+ *
+ * @var boolean
+ * @access private
+ */
+ var $_persistant;
+
+ /**
+ * If only using one server; contains ip:port to connect to
+ *
+ * @var string
+ * @access private
+ */
+ var $_single_sock;
+
+ /**
+ * Array containing ip:port or array(ip:port, weight)
+ *
+ * @var array
+ * @access private
+ */
+ var $_servers;
+
+ /**
+ * Our bit buckets
+ *
+ * @var array
+ * @access private
+ */
+ var $_buckets;
+
+ /**
+ * Total # of bit buckets we have
+ *
+ * @var interger
+ * @access private
+ */
+ var $_bucketcount;
+
+ /**
+ * # of total servers we have
+ *
+ * @var interger
+ * @access private
+ */
+ var $_active;
+
+ /**
+ * Stream timeout in seconds. Applies for example to fread()
+ *
+ * @var integer
+ * @access private
+ */
+ var $_timeout_seconds;
+
+ /**
+ * Stream timeout in microseconds
+ *
+ * @var integer
+ * @access private
+ */
+ var $_timeout_microseconds;
+
+ /**
+ * Connect timeout in seconds
+ */
+ var $_connect_timeout;
+
+ /**
+ * Number of connection attempts for each server
+ */
+ var $_connect_attempts;
+
+ // }}}
+ // }}}
+ // {{{ methods
+ // {{{ public functions
+ // {{{ memcached()
+
+ /**
+ * Memcache initializer
+ *
+ * @param array $args Associative array of settings
+ *
+ * @return mixed
+ * @access public
+ */
+ function memcached ($args)
+ {
+ $this->set_servers(@$args['servers']);
+ $this->_debug = @$args['debug'];
+ $this->stats = array();
+ $this->_compress_threshold = @$args['compress_threshold'];
+ $this->_persistant = array_key_exists('persistant', $args) ? (@$args['persistant']) : false;
+ $this->_compress_enable = true;
+ $this->_have_zlib = function_exists("gzcompress");
+
+ $this->_cache_sock = array();
+ $this->_host_dead = array();
+
+ $this->_timeout_seconds = 1;
+ $this->_timeout_microseconds = 0;
+
+ $this->_connect_timeout = 0.01;
+ $this->_connect_attempts = 3;
+ }
+
+ // }}}
+ // {{{ add()
+
+ /**
+ * Adds a key/value to the memcache server if one isn't already set with
+ * that key
+ *
+ * @param string $key Key to set with data
+ * @param mixed $val Value to store
+ * @param interger $exp (optional) Time to expire data at
+ *
+ * @return boolean
+ * @access public
+ */
+ function add ($key, $val, $exp = 0)
+ {
+ return $this->_set('add', $key, $val, $exp);
+ }
+
+ // }}}
+ // {{{ decr()
+
+ /**
+ * Decriment a value stored on the memcache server
+ *
+ * @param string $key Key to decriment
+ * @param interger $amt (optional) Amount to decriment
+ *
+ * @return mixed FALSE on failure, value on success
+ * @access public
+ */
+ function decr ($key, $amt=1)
+ {
+ return $this->_incrdecr('decr', $key, $amt);
+ }
+
+ // }}}
+ // {{{ delete()
+
+ /**
+ * Deletes a key from the server, optionally after $time
+ *
+ * @param string $key Key to delete
+ * @param interger $time (optional) How long to wait before deleting
+ *
+ * @return boolean TRUE on success, FALSE on failure
+ * @access public
+ */
+ function delete ($key, $time = 0)
+ {
+ if (!$this->_active)
+ return false;
+
+ $sock = $this->get_sock($key);
+ if (!is_resource($sock))
+ return false;
+
+ $key = is_array($key) ? $key[1] : $key;
+
+ @$this->stats['delete']++;
+ $cmd = "delete $key $time\r\n";
+ if(!$this->_safe_fwrite($sock, $cmd, strlen($cmd)))
+ {
+ $this->_dead_sock($sock);
+ return false;
+ }
+ $res = trim(fgets($sock));
+
+ if ($this->_debug)
+ $this->_debugprint(sprintf("MemCache: delete %s (%s)\n", $key, $res));
+
+ if ($res == "DELETED")
+ return true;
+ return false;
+ }
+
+ // }}}
+ // {{{ disconnect_all()
+
+ /**
+ * Disconnects all connected sockets
+ *
+ * @access public
+ */
+ function disconnect_all ()
+ {
+ foreach ($this->_cache_sock as $sock)
+ fclose($sock);
+
+ $this->_cache_sock = array();
+ }
+
+ // }}}
+ // {{{ enable_compress()
+
+ /**
+ * Enable / Disable compression
+ *
+ * @param boolean $enable TRUE to enable, FALSE to disable
+ *
+ * @access public
+ */
+ function enable_compress ($enable)
+ {
+ $this->_compress_enable = $enable;
+ }
+
+ // }}}
+ // {{{ forget_dead_hosts()
+
+ /**
+ * Forget about all of the dead hosts
+ *
+ * @access public
+ */
+ function forget_dead_hosts ()
+ {
+ $this->_host_dead = array();
+ }
+
+ // }}}
+ // {{{ get()
+
+ /**
+ * Retrieves the value associated with the key from the memcache server
+ *
+ * @param string $key Key to retrieve
+ *
+ * @return mixed
+ * @access public
+ */
+ function get ($key)
+ {
+ $fname = 'memcached::get';
+ wfProfileIn( $fname );
+
+ if (!$this->_active) {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ $sock = $this->get_sock($key);
+
+ if (!is_resource($sock)) {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ @$this->stats['get']++;
+
+ $cmd = "get $key\r\n";
+ if (!$this->_safe_fwrite($sock, $cmd, strlen($cmd)))
+ {
+ $this->_dead_sock($sock);
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ $val = array();
+ $this->_load_items($sock, $val);
+
+ if ($this->_debug)
+ foreach ($val as $k => $v)
+ $this->_debugprint(@sprintf("MemCache: sock %s got %s => %s\r\n", serialize($sock), $k, $v));
+
+ wfProfileOut( $fname );
+ return @$val[$key];
+ }
+
+ // }}}
+ // {{{ get_multi()
+
+ /**
+ * Get multiple keys from the server(s)
+ *
+ * @param array $keys Keys to retrieve
+ *
+ * @return array
+ * @access public
+ */
+ function get_multi ($keys)
+ {
+ if (!$this->_active)
+ return false;
+
+ $this->stats['get_multi']++;
+ $sock_keys = array();
+
+ foreach ($keys as $key)
+ {
+ $sock = $this->get_sock($key);
+ if (!is_resource($sock)) continue;
+ $key = is_array($key) ? $key[1] : $key;
+ if (!isset($sock_keys[$sock]))
+ {
+ $sock_keys[$sock] = array();
+ $socks[] = $sock;
+ }
+ $sock_keys[$sock][] = $key;
+ }
+
+ // Send out the requests
+ foreach ($socks as $sock)
+ {
+ $cmd = "get";
+ foreach ($sock_keys[$sock] as $key)
+ {
+ $cmd .= " ". $key;
+ }
+ $cmd .= "\r\n";
+
+ if ($this->_safe_fwrite($sock, $cmd, strlen($cmd)))
+ {
+ $gather[] = $sock;
+ } else
+ {
+ $this->_dead_sock($sock);
+ }
+ }
+
+ // Parse responses
+ $val = array();
+ foreach ($gather as $sock)
+ {
+ $this->_load_items($sock, $val);
+ }
+
+ if ($this->_debug)
+ foreach ($val as $k => $v)
+ $this->_debugprint(sprintf("MemCache: got %s => %s\r\n", $k, $v));
+
+ return $val;
+ }
+
+ // }}}
+ // {{{ incr()
+
+ /**
+ * Increments $key (optionally) by $amt
+ *
+ * @param string $key Key to increment
+ * @param interger $amt (optional) amount to increment
+ *
+ * @return interger New key value?
+ * @access public
+ */
+ function incr ($key, $amt=1)
+ {
+ return $this->_incrdecr('incr', $key, $amt);
+ }
+
+ // }}}
+ // {{{ replace()
+
+ /**
+ * Overwrites an existing value for key; only works if key is already set
+ *
+ * @param string $key Key to set value as
+ * @param mixed $value Value to store
+ * @param interger $exp (optional) Experiation time
+ *
+ * @return boolean
+ * @access public
+ */
+ function replace ($key, $value, $exp=0)
+ {
+ return $this->_set('replace', $key, $value, $exp);
+ }
+
+ // }}}
+ // {{{ run_command()
+
+ /**
+ * Passes through $cmd to the memcache server connected by $sock; returns
+ * output as an array (null array if no output)
+ *
+ * NOTE: due to a possible bug in how PHP reads while using fgets(), each
+ * line may not be terminated by a \r\n. More specifically, my testing
+ * has shown that, on FreeBSD at least, each line is terminated only
+ * with a \n. This is with the PHP flag auto_detect_line_endings set
+ * to falase (the default).
+ *
+ * @param resource $sock Socket to send command on
+ * @param string $cmd Command to run
+ *
+ * @return array Output array
+ * @access public
+ */
+ function run_command ($sock, $cmd)
+ {
+ if (!is_resource($sock))
+ return array();
+
+ if (!$this->_safe_fwrite($sock, $cmd, strlen($cmd)))
+ return array();
+
+ while (true)
+ {
+ $res = fgets($sock);
+ $ret[] = $res;
+ if (preg_match('/^END/', $res))
+ break;
+ if (strlen($res) == 0)
+ break;
+ }
+ return $ret;
+ }
+
+ // }}}
+ // {{{ set()
+
+ /**
+ * Unconditionally sets a key to a given value in the memcache. Returns true
+ * if set successfully.
+ *
+ * @param string $key Key to set value as
+ * @param mixed $value Value to set
+ * @param interger $exp (optional) Experiation time
+ *
+ * @return boolean TRUE on success
+ * @access public
+ */
+ function set ($key, $value, $exp=0)
+ {
+ return $this->_set('set', $key, $value, $exp);
+ }
+
+ // }}}
+ // {{{ set_compress_threshold()
+
+ /**
+ * Sets the compression threshold
+ *
+ * @param interger $thresh Threshold to compress if larger than
+ *
+ * @access public
+ */
+ function set_compress_threshold ($thresh)
+ {
+ $this->_compress_threshold = $thresh;
+ }
+
+ // }}}
+ // {{{ set_debug()
+
+ /**
+ * Sets the debug flag
+ *
+ * @param boolean $dbg TRUE for debugging, FALSE otherwise
+ *
+ * @access public
+ *
+ * @see memcahced::memcached
+ */
+ function set_debug ($dbg)
+ {
+ $this->_debug = $dbg;
+ }
+
+ // }}}
+ // {{{ set_servers()
+
+ /**
+ * Sets the server list to distribute key gets and puts between
+ *
+ * @param array $list Array of servers to connect to
+ *
+ * @access public
+ *
+ * @see memcached::memcached()
+ */
+ function set_servers ($list)
+ {
+ $this->_servers = $list;
+ $this->_active = count($list);
+ $this->_buckets = null;
+ $this->_bucketcount = 0;
+
+ $this->_single_sock = null;
+ if ($this->_active == 1)
+ $this->_single_sock = $this->_servers[0];
+ }
+
+ /**
+ * Sets the timeout for new connections
+ *
+ * @param integer $seconds Number of seconds
+ * @param integer $microseconds Number of microseconds
+ *
+ * @access public
+ */
+ function set_timeout ($seconds, $microseconds)
+ {
+ $this->_timeout_seconds = $seconds;
+ $this->_timeout_microseconds = $microseconds;
+ }
+
+ // }}}
+ // }}}
+ // {{{ private methods
+ // {{{ _close_sock()
+
+ /**
+ * Close the specified socket
+ *
+ * @param string $sock Socket to close
+ *
+ * @access private
+ */
+ function _close_sock ($sock)
+ {
+ $host = array_search($sock, $this->_cache_sock);
+ fclose($this->_cache_sock[$host]);
+ unset($this->_cache_sock[$host]);
+ }
+
+ // }}}
+ // {{{ _connect_sock()
+
+ /**
+ * Connects $sock to $host, timing out after $timeout
+ *
+ * @param interger $sock Socket to connect
+ * @param string $host Host:IP to connect to
+ *
+ * @return boolean
+ * @access private
+ */
+ function _connect_sock (&$sock, $host)
+ {
+ list ($ip, $port) = explode(":", $host);
+ $sock = false;
+ $timeout = $this->_connect_timeout;
+ $errno = $errstr = null;
+ for ($i = 0; !$sock && $i < $this->_connect_attempts; $i++) {
+ if ($i > 0) {
+ # Sleep until the timeout, in case it failed fast
+ $elapsed = microtime(true) - $t;
+ if ( $elapsed < $timeout ) {
+ usleep(($timeout - $elapsed) * 1e6);
+ }
+ $timeout *= 2;
+ }
+ $t = microtime(true);
+ if ($this->_persistant == 1)
+ {
+ $sock = @pfsockopen($ip, $port, $errno, $errstr, $timeout);
+ } else
+ {
+ $sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);
+ }
+ }
+ if (!$sock) {
+ if ($this->_debug)
+ $this->_debugprint( "Error connecting to $host: $errstr\n" );
+ return false;
+ }
+
+ // Initialise timeout
+ stream_set_timeout($sock, $this->_timeout_seconds, $this->_timeout_microseconds);
+
+ return true;
+ }
+
+ // }}}
+ // {{{ _dead_sock()
+
+ /**
+ * Marks a host as dead until 30-40 seconds in the future
+ *
+ * @param string $sock Socket to mark as dead
+ *
+ * @access private
+ */
+ function _dead_sock ($sock)
+ {
+ $host = array_search($sock, $this->_cache_sock);
+ @list ($ip, /* $port */) = explode(":", $host);
+ $this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10));
+ $this->_host_dead[$host] = $this->_host_dead[$ip];
+ unset($this->_cache_sock[$host]);
+ }
+
+ // }}}
+ // {{{ get_sock()
+
+ /**
+ * get_sock
+ *
+ * @param string $key Key to retrieve value for;
+ *
+ * @return mixed resource on success, false on failure
+ * @access private
+ */
+ function get_sock ($key)
+ {
+ if (!$this->_active)
+ return false;
+
+ if ($this->_single_sock !== null) {
+ $this->_flush_read_buffer($this->_single_sock);
+ return $this->sock_to_host($this->_single_sock);
+ }
+
+ $hv = is_array($key) ? intval($key[0]) : $this->_hashfunc($key);
+
+ if ($this->_buckets === null)
+ {
+ foreach ($this->_servers as $v)
+ {
+ if (is_array($v))
+ {
+ for ($i=0; $i<$v[1]; $i++)
+ $bu[] = $v[0];
+ } else
+ {
+ $bu[] = $v;
+ }
+ }
+ $this->_buckets = $bu;
+ $this->_bucketcount = count($bu);
+ }
+
+ $realkey = is_array($key) ? $key[1] : $key;
+ for ($tries = 0; $tries<20; $tries++)
+ {
+ $host = $this->_buckets[$hv % $this->_bucketcount];
+ $sock = $this->sock_to_host($host);
+ if (is_resource($sock)) {
+ $this->_flush_read_buffer($sock);
+ return $sock;
+ }
+ $hv += $this->_hashfunc($tries . $realkey);
+ }
+
+ return false;
+ }
+
+ // }}}
+ // {{{ _hashfunc()
+
+ /**
+ * Creates a hash interger based on the $key
+ *
+ * @param string $key Key to hash
+ *
+ * @return interger Hash value
+ * @access private
+ */
+ function _hashfunc ($key)
+ {
+ # Hash function must on [0,0x7ffffff]
+ # We take the first 31 bits of the MD5 hash, which unlike the hash
+ # function used in a previous version of this client, works
+ return hexdec(substr(md5($key),0,8)) & 0x7fffffff;
+ }
+
+ // }}}
+ // {{{ _incrdecr()
+
+ /**
+ * Perform increment/decriment on $key
+ *
+ * @param string $cmd Command to perform
+ * @param string $key Key to perform it on
+ * @param interger $amt Amount to adjust
+ *
+ * @return interger New value of $key
+ * @access private
+ */
+ function _incrdecr ($cmd, $key, $amt=1)
+ {
+ if (!$this->_active)
+ return null;
+
+ $sock = $this->get_sock($key);
+ if (!is_resource($sock))
+ return null;
+
+ $key = is_array($key) ? $key[1] : $key;
+ @$this->stats[$cmd]++;
+ if (!$this->_safe_fwrite($sock, "$cmd $key $amt\r\n"))
+ return $this->_dead_sock($sock);
+
+ stream_set_timeout($sock, 1, 0);
+ $line = fgets($sock);
+ $match = array();
+ if (!preg_match('/^(\d+)/', $line, $match))
+ return null;
+ return $match[1];
+ }
+
+ // }}}
+ // {{{ _load_items()
+
+ /**
+ * Load items into $ret from $sock
+ *
+ * @param resource $sock Socket to read from
+ * @param array $ret Returned values
+ *
+ * @access private
+ */
+ function _load_items ($sock, &$ret)
+ {
+ while (1)
+ {
+ $decl = fgets($sock);
+ if ($decl == "END\r\n")
+ {
+ return true;
+ } elseif (preg_match('/^VALUE (\S+) (\d+) (\d+)\r\n$/', $decl, $match))
+ {
+ list($rkey, $flags, $len) = array($match[1], $match[2], $match[3]);
+ $bneed = $len+2;
+ $offset = 0;
+
+ while ($bneed > 0)
+ {
+ $data = fread($sock, $bneed);
+ $n = strlen($data);
+ if ($n == 0)
+ break;
+ $offset += $n;
+ $bneed -= $n;
+ @$ret[$rkey] .= $data;
+ }
+
+ if ($offset != $len+2)
+ {
+ // Something is borked!
+ if ($this->_debug)
+ $this->_debugprint(sprintf("Something is borked! key %s expecting %d got %d length\n", $rkey, $len+2, $offset));
+
+ unset($ret[$rkey]);
+ $this->_close_sock($sock);
+ return false;
+ }
+
+ if ($this->_have_zlib && $flags & MEMCACHE_COMPRESSED)
+ $ret[$rkey] = gzuncompress($ret[$rkey]);
+
+ $ret[$rkey] = rtrim($ret[$rkey]);
+
+ if ($flags & MEMCACHE_SERIALIZED)
+ $ret[$rkey] = unserialize($ret[$rkey]);
+
+ } else
+ {
+ $this->_debugprint("Error parsing memcached response\n");
+ return 0;
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _set()
+
+ /**
+ * Performs the requested storage operation to the memcache server
+ *
+ * @param string $cmd Command to perform
+ * @param string $key Key to act on
+ * @param mixed $val What we need to store
+ * @param interger $exp When it should expire
+ *
+ * @return boolean
+ * @access private
+ */
+ function _set ($cmd, $key, $val, $exp)
+ {
+ if (!$this->_active)
+ return false;
+
+ $sock = $this->get_sock($key);
+ if (!is_resource($sock))
+ return false;
+
+ @$this->stats[$cmd]++;
+
+ $flags = 0;
+
+ if (!is_scalar($val))
+ {
+ $val = serialize($val);
+ $flags |= MEMCACHE_SERIALIZED;
+ if ($this->_debug)
+ $this->_debugprint(sprintf("client: serializing data as it is not scalar\n"));
+ }
+
+ $len = strlen($val);
+
+ if ($this->_have_zlib && $this->_compress_enable &&
+ $this->_compress_threshold && $len >= $this->_compress_threshold)
+ {
+ $c_val = gzcompress($val, 9);
+ $c_len = strlen($c_val);
+
+ if ($c_len < $len*(1 - COMPRESSION_SAVINGS))
+ {
+ if ($this->_debug)
+ $this->_debugprint(sprintf("client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len));
+ $val = $c_val;
+ $len = $c_len;
+ $flags |= MEMCACHE_COMPRESSED;
+ }
+ }
+ if (!$this->_safe_fwrite($sock, "$cmd $key $flags $exp $len\r\n$val\r\n"))
+ return $this->_dead_sock($sock);
+
+ $line = trim(fgets($sock));
+
+ if ($this->_debug)
+ {
+ if ($flags & MEMCACHE_COMPRESSED)
+ $val = 'compressed data';
+ $this->_debugprint(sprintf("MemCache: %s %s => %s (%s)\n", $cmd, $key, $val, $line));
+ }
+ if ($line == "STORED")
+ return true;
+ return false;
+ }
+
+ // }}}
+ // {{{ sock_to_host()
+
+ /**
+ * Returns the socket for the host
+ *
+ * @param string $host Host:IP to get socket for
+ *
+ * @return mixed IO Stream or false
+ * @access private
+ */
+ function sock_to_host ($host)
+ {
+ if (isset($this->_cache_sock[$host]))
+ return $this->_cache_sock[$host];
+
+ $sock = null;
+ $now = time();
+ list ($ip, /* $port */) = explode (":", $host);
+ if (isset($this->_host_dead[$host]) && $this->_host_dead[$host] > $now ||
+ isset($this->_host_dead[$ip]) && $this->_host_dead[$ip] > $now)
+ return null;
+
+ if (!$this->_connect_sock($sock, $host))
+ return $this->_dead_sock($host);
+
+ // Do not buffer writes
+ stream_set_write_buffer($sock, 0);
+
+ $this->_cache_sock[$host] = $sock;
+
+ return $this->_cache_sock[$host];
+ }
+
+ function _debugprint($str){
+ print($str);
+ }
+
+ /**
+ * Write to a stream, timing out after the correct amount of time
+ *
+ * @return bool false on failure, true on success
+ */
+ /*
+ function _safe_fwrite($f, $buf, $len = false) {
+ stream_set_blocking($f, 0);
+
+ if ($len === false) {
+ wfDebug("Writing " . strlen( $buf ) . " bytes\n");
+ $bytesWritten = fwrite($f, $buf);
+ } else {
+ wfDebug("Writing $len bytes\n");
+ $bytesWritten = fwrite($f, $buf, $len);
+ }
+ $n = stream_select($r=NULL, $w = array($f), $e = NULL, 10, 0);
+ # $this->_timeout_seconds, $this->_timeout_microseconds);
+
+ wfDebug("stream_select returned $n\n");
+ stream_set_blocking($f, 1);
+ return $n == 1;
+ return $bytesWritten;
+ }*/
+
+ /**
+ * Original behaviour
+ */
+ function _safe_fwrite($f, $buf, $len = false) {
+ if ($len === false) {
+ $bytesWritten = fwrite($f, $buf);
+ } else {
+ $bytesWritten = fwrite($f, $buf, $len);
+ }
+ return $bytesWritten;
+ }
+
+ /**
+ * Flush the read buffer of a stream
+ */
+ function _flush_read_buffer($f) {
+ if (!is_resource($f)) {
+ return;
+ }
+ $n = stream_select($r=array($f), $w = NULL, $e = NULL, 0, 0);
+ while ($n == 1 && !feof($f)) {
+ fread($f, 1024);
+ $n = stream_select($r=array($f), $w = NULL, $e = NULL, 0, 0);
+ }
+ }
+
+ // }}}
+ // }}}
+ // }}}
+}
+
+// vim: sts=3 sw=3 et
+
+// }}}
+?>
diff --git a/includes/mime.info b/includes/mime.info
new file mode 100644
index 000000000000..9b05f089b2eb
--- /dev/null
+++ b/includes/mime.info
@@ -0,0 +1,76 @@
+#Mime type info file.
+#the first mime type in each line is the "main" mime type,
+#the others are aliases for this type
+#the media type is given in upper case and square brackets,
+#like [BITMAP], and must indicate a media type as defined by
+#the MEDIATYPE_xxx constants in Defines.php
+
+
+image/gif [BITMAP]
+image/png [BITMAP]
+image/ief [BITMAP]
+image/jpeg [BITMAP]
+image/xbm [BITMAP]
+image/tiff [BITMAP]
+image/x-icon [BITMAP]
+image/x-rgb [BITMAP]
+image/x-portable-pixmap [BITMAP]
+image/x-portable-graymap image/x-portable-greymap [BITMAP]
+image/x-bmp image/bmp application/x-bmp application/bmp [BITMAP]
+image/x-photoshop image/psd image/x-psd image/photoshop [BITMAP]
+
+image/svg image/svg+xml application/svg+xml application/svg [DRAWING]
+application/postscript [DRAWING]
+application/x-latex [DRAWING]
+application/x-tex [DRAWING]
+
+
+audio/mp3 audio/mpeg3 audio/mpeg [AUDIO]
+audio/wav audio/x-wav audio/wave [AUDIO]
+audio/midi audio/mid [AUDIO]
+audio/basic [AUDIO]
+audio/x-aiff [AUDIO]
+audio/x-pn-realaudio [AUDIO]
+audio/x-realaudio [AUDIO]
+
+video/mpeg application/mpeg [VIDEO]
+video/ogg [VIDEO]
+video/x-sgi-video [VIDEO]
+
+application/ogg application/x-ogg audio/ogg audio/x-ogg video/ogg video/x-ogg [MULTIMEDIA]
+
+application/x-shockwave-flash [MULTIMEDIA]
+audio/x-pn-realaudio-plugin [MULTIMEDIA]
+model/iges [MULTIMEDIA]
+model/mesh [MULTIMEDIA]
+model/vrml [MULTIMEDIA]
+video/quicktime [MULTIMEDIA]
+video/x-msvideo [MULTIMEDIA]
+
+text/plain [TEXT]
+text/html application/xhtml+xml [TEXT]
+application/xml text/xml [TEXT]
+text [TEXT]
+
+application/zip application/x-zip [ARCHIVE]
+application/x-gzip [ARCHIVE]
+application/x-bzip [ARCHIVE]
+application/x-tar [ARCHIVE]
+application/x-stuffit [ARCHIVE]
+
+
+text/javascript application/x-javascript application/x-ecmascript text/ecmascript [EXECUTABLE]
+application/x-bash [EXECUTABLE]
+application/x-sh [EXECUTABLE]
+application/x-csh [EXECUTABLE]
+application/x-tcsh [EXECUTABLE]
+application/x-tcl [EXECUTABLE]
+application/x-perl [EXECUTABLE]
+application/x-python [EXECUTABLE]
+
+application/pdf application/acrobat [OFFICE]
+application/msword [OFFICE]
+application/vnd.ms-excel [OFFICE]
+application/vnd.ms-powerpoint [OFFICE]
+application/x-director [OFFICE]
+text/rtf [OFFICE]
diff --git a/includes/mime.types b/includes/mime.types
new file mode 100644
index 000000000000..3a7fa39cd5dc
--- /dev/null
+++ b/includes/mime.types
@@ -0,0 +1,117 @@
+application/andrew-inset ez
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/mathml+xml mathml
+application/msword doc
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/ogg ogg ogm
+application/pdf pdf
+application/postscript ai eps ps
+application/rdf+xml rdf
+application/smil smi smil
+application/srgs gram
+application/srgs+xml grxml
+application/vnd.mif mif
+application/vnd.ms-excel xls
+application/vnd.ms-powerpoint ppt
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/voicexml+xml vxml
+application/x-bcpio bcpio
+application/x-bzip gz bz2
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar tar
+application/x-gzip gz
+application/x-hdf hdf
+application/x-jar jar
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x-xpinstall xpi
+application/xhtml+xml xhtml xht
+application/xslt+xml xslt
+application/xml xml xsl
+application/xml-dtd dtd
+application/zip zip jar xpi sxc stc sxd std sxi sti sxm stm sxw stw
+audio/basic au snd
+audio/midi mid midi kar
+audio/mpeg mpga mp2 mp3
+audio/ogg ogg
+audio/x-aiff aif aiff aifc
+audio/x-mpegurl m3u
+audio/x-ogg ogg
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm cgm
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/png png
+image/svg+xml svg
+image/tiff tiff tif
+image/vnd.djvu djvu djv
+image/vnd.wap.wbmp wbmp
+image/x-cmu-raster ras
+image/x-icon ico
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-photoshop psd
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+model/iges igs iges
+model/mesh msh mesh silo
+model/vrml wrl vrml
+text/calendar ics ifb
+text/css css
+text/html html htm
+text/plain txt
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/xml xml xsl xslt rss rdf
+text/x-setext etx
+video/mpeg mpeg mpg mpe
+video/ogg ogm ogg
+video/quicktime qt mov
+video/vnd.mpegurl mxu
+video/x-msvideo avi
+video/x-ogg ogm ogg
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice \ No newline at end of file
diff --git a/includes/normal/CleanUpTest.php b/includes/normal/CleanUpTest.php
new file mode 100644
index 000000000000..30ec6a95fccb
--- /dev/null
+++ b/includes/normal/CleanUpTest.php
@@ -0,0 +1,423 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Additional tests for UtfNormal::cleanUp() function, inclusion
+ * regression checks for known problems.
+ *
+ * Requires PHPUnit.
+ *
+ * @package UtfNormal
+ * @private
+ */
+
+if( php_sapi_name() != 'cli' ) {
+ die( "Run me from the command line please.\n" );
+}
+
+/** */
+if( isset( $_SERVER['argv'] ) && in_array( '--icu', $_SERVER['argv'] ) ) {
+ dl( 'php_utfnormal.so' );
+}
+
+#ini_set( 'memory_limit', '40M' );
+
+require_once( 'PHPUnit.php' );
+require_once( 'UtfNormal.php' );
+
+/**
+ * @package UtfNormal
+ */
+class CleanUpTest extends PHPUnit_TestCase {
+ /**
+ * @param $name String: FIXME
+ */
+ function CleanUpTest( $name ) {
+ $this->PHPUnit_TestCase( $name );
+ }
+
+ /** @todo document */
+ function setUp() {
+ }
+
+ /** @todo document */
+ function tearDown() {
+ }
+
+ /** @todo document */
+ function testAscii() {
+ $text = 'This is plain ASCII text.';
+ $this->assertEquals( $text, UtfNormal::cleanUp( $text ) );
+ }
+
+ /** @todo document */
+ function testNull() {
+ $text = "a \x00 null";
+ $expect = "a \xef\xbf\xbd null";
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+
+ /** @todo document */
+ function testLatin() {
+ $text = "L'\xc3\xa9cole";
+ $this->assertEquals( $text, UtfNormal::cleanUp( $text ) );
+ }
+
+ /** @todo document */
+ function testLatinNormal() {
+ $text = "L'e\xcc\x81cole";
+ $expect = "L'\xc3\xa9cole";
+ $this->assertEquals( $expect, UtfNormal::cleanUp( $text ) );
+ }
+
+ /**
+ * This test is *very* expensive!
+ * @todo document
+ */
+ function XtestAllChars() {
+ $rep = UTF8_REPLACEMENT;
+ global $utfCanonicalComp, $utfCanonicalDecomp;
+ for( $i = 0x0; $i < UNICODE_MAX; $i++ ) {
+ $char = codepointToUtf8( $i );
+ $clean = UtfNormal::cleanUp( $char );
+ $x = sprintf( "%04X", $i );
+ if( $i % 0x1000 == 0 ) echo "U+$x\n";
+ if( $i == 0x0009 ||
+ $i == 0x000a ||
+ $i == 0x000d ||
+ ($i > 0x001f && $i < UNICODE_SURROGATE_FIRST) ||
+ ($i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) ||
+ ($i > 0xffff && $i <= UNICODE_MAX ) ) {
+ if( isset( $utfCanonicalComp[$char] ) || isset( $utfCanonicalDecomp[$char] ) ) {
+ $comp = UtfNormal::NFC( $char );
+ $this->assertEquals(
+ bin2hex( $comp ),
+ bin2hex( $clean ),
+ "U+$x should be decomposed" );
+ } else {
+ $this->assertEquals(
+ bin2hex( $char ),
+ bin2hex( $clean ),
+ "U+$x should be intact" );
+ }
+ } else {
+ $this->assertEquals( bin2hex( $rep ), bin2hex( $clean ), $x );
+ }
+ }
+ }
+
+ /** @todo document */
+ function testAllBytes() {
+ $this->doTestBytes( '', '' );
+ $this->doTestBytes( 'x', '' );
+ $this->doTestBytes( '', 'x' );
+ $this->doTestBytes( 'x', 'x' );
+ }
+
+ /** @todo document */
+ function doTestBytes( $head, $tail ) {
+ for( $i = 0x0; $i < 256; $i++ ) {
+ $char = $head . chr( $i ) . $tail;
+ $clean = UtfNormal::cleanUp( $char );
+ $x = sprintf( "%02X", $i );
+ if( $i == 0x0009 ||
+ $i == 0x000a ||
+ $i == 0x000d ||
+ ($i > 0x001f && $i < 0x80) ) {
+ $this->assertEquals(
+ bin2hex( $char ),
+ bin2hex( $clean ),
+ "ASCII byte $x should be intact" );
+ if( $char != $clean ) return;
+ } else {
+ $norm = $head . UTF8_REPLACEMENT . $tail;
+ $this->assertEquals(
+ bin2hex( $norm ),
+ bin2hex( $clean ),
+ "Forbidden byte $x should be rejected" );
+ if( $norm != $clean ) return;
+ }
+ }
+ }
+
+ /** @todo document */
+ function testDoubleBytes() {
+ $this->doTestDoubleBytes( '', '' );
+ $this->doTestDoubleBytes( 'x', '' );
+ $this->doTestDoubleBytes( '', 'x' );
+ $this->doTestDoubleBytes( 'x', 'x' );
+ }
+
+ /**
+ * @todo document
+ */
+ function doTestDoubleBytes( $head, $tail ) {
+ for( $first = 0xc0; $first < 0x100; $first++ ) {
+ for( $second = 0x80; $second < 0x100; $second++ ) {
+ $char = $head . chr( $first ) . chr( $second ) . $tail;
+ $clean = UtfNormal::cleanUp( $char );
+ $x = sprintf( "%02X,%02X", $first, $second );
+ if( $first > 0xc1 &&
+ $first < 0xe0 &&
+ $second < 0xc0 ) {
+ $norm = UtfNormal::NFC( $char );
+ $this->assertEquals(
+ bin2hex( $norm ),
+ bin2hex( $clean ),
+ "Pair $x should be intact" );
+ if( $norm != $clean ) return;
+ } elseif( $first > 0xfd || $second > 0xbf ) {
+ # fe and ff are not legal head bytes -- expect two replacement chars
+ $norm = $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail;
+ $this->assertEquals(
+ bin2hex( $norm ),
+ bin2hex( $clean ),
+ "Forbidden pair $x should be rejected" );
+ if( $norm != $clean ) return;
+ } else {
+ $norm = $head . UTF8_REPLACEMENT . $tail;
+ $this->assertEquals(
+ bin2hex( $norm ),
+ bin2hex( $clean ),
+ "Forbidden pair $x should be rejected" );
+ if( $norm != $clean ) return;
+ }
+ }
+ }
+ }
+
+ /** @todo document */
+ function testTripleBytes() {
+ $this->doTestTripleBytes( '', '' );
+ $this->doTestTripleBytes( 'x', '' );
+ $this->doTestTripleBytes( '', 'x' );
+ $this->doTestTripleBytes( 'x', 'x' );
+ }
+
+ /** @todo document */
+ function doTestTripleBytes( $head, $tail ) {
+ for( $first = 0xc0; $first < 0x100; $first++ ) {
+ for( $second = 0x80; $second < 0x100; $second++ ) {
+ #for( $third = 0x80; $third < 0x100; $third++ ) {
+ for( $third = 0x80; $third < 0x81; $third++ ) {
+ $char = $head . chr( $first ) . chr( $second ) . chr( $third ) . $tail;
+ $clean = UtfNormal::cleanUp( $char );
+ $x = sprintf( "%02X,%02X,%02X", $first, $second, $third );
+ if( $first >= 0xe0 &&
+ $first < 0xf0 &&
+ $second < 0xc0 &&
+ $third < 0xc0 ) {
+ if( $first == 0xe0 && $second < 0xa0 ) {
+ $this->assertEquals(
+ bin2hex( $head . UTF8_REPLACEMENT . $tail ),
+ bin2hex( $clean ),
+ "Overlong triplet $x should be rejected" );
+ } elseif( $first == 0xed &&
+ ( chr( $first ) . chr( $second ) . chr( $third )) >= UTF8_SURROGATE_FIRST ) {
+ $this->assertEquals(
+ bin2hex( $head . UTF8_REPLACEMENT . $tail ),
+ bin2hex( $clean ),
+ "Surrogate triplet $x should be rejected" );
+ } else {
+ $this->assertEquals(
+ bin2hex( UtfNormal::NFC( $char ) ),
+ bin2hex( $clean ),
+ "Triplet $x should be intact" );
+ }
+ } elseif( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) {
+ $this->assertEquals(
+ bin2hex( UtfNormal::NFC( $head . chr( $first ) . chr( $second ) ) . UTF8_REPLACEMENT . $tail ),
+ bin2hex( $clean ),
+ "Valid 2-byte $x + broken tail" );
+ } elseif( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) {
+ $this->assertEquals(
+ bin2hex( $head . UTF8_REPLACEMENT . UtfNormal::NFC( chr( $second ) . chr( $third ) . $tail ) ),
+ bin2hex( $clean ),
+ "Broken head + valid 2-byte $x" );
+ } elseif( ( $first > 0xfd || $second > 0xfd ) &&
+ ( ( $second > 0xbf && $third > 0xbf ) ||
+ ( $second < 0xc0 && $third < 0xc0 ) ||
+ ( $second > 0xfd ) ||
+ ( $third > 0xfd ) ) ) {
+ # fe and ff are not legal head bytes -- expect three replacement chars
+ $this->assertEquals(
+ bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ),
+ bin2hex( $clean ),
+ "Forbidden triplet $x should be rejected" );
+ } elseif( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) {
+ $this->assertEquals(
+ bin2hex( $head . UTF8_REPLACEMENT . $tail ),
+ bin2hex( $clean ),
+ "Forbidden triplet $x should be rejected" );
+ } else {
+ $this->assertEquals(
+ bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ),
+ bin2hex( $clean ),
+ "Forbidden triplet $x should be rejected" );
+ }
+ }
+ }
+ }
+ }
+
+ /** @todo document */
+ function testChunkRegression() {
+ # Check for regression against a chunking bug
+ $text = "\x46\x55\xb8" .
+ "\xdc\x96" .
+ "\xee" .
+ "\xe7" .
+ "\x44" .
+ "\xaa" .
+ "\x2f\x25";
+ $expect = "\x46\x55\xef\xbf\xbd" .
+ "\xdc\x96" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\x44" .
+ "\xef\xbf\xbd" .
+ "\x2f\x25";
+
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+
+ /** @todo document */
+ function testInterposeRegression() {
+ $text = "\x4e\x30" .
+ "\xb1" . # bad tail
+ "\x3a" .
+ "\x92" . # bad tail
+ "\x62\x3a" .
+ "\x84" . # bad tail
+ "\x43" .
+ "\xc6" . # bad head
+ "\x3f" .
+ "\x92" . # bad tail
+ "\xad" . # bad tail
+ "\x7d" .
+ "\xd9\x95";
+
+ $expect = "\x4e\x30" .
+ "\xef\xbf\xbd" .
+ "\x3a" .
+ "\xef\xbf\xbd" .
+ "\x62\x3a" .
+ "\xef\xbf\xbd" .
+ "\x43" .
+ "\xef\xbf\xbd" .
+ "\x3f" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\x7d" .
+ "\xd9\x95";
+
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+
+ /** @todo document */
+ function testOverlongRegression() {
+ $text = "\x67" .
+ "\x1a" . # forbidden ascii
+ "\xea" . # bad head
+ "\xc1\xa6" . # overlong sequence
+ "\xad" . # bad tail
+ "\x1c" . # forbidden ascii
+ "\xb0" . # bad tail
+ "\x3c" .
+ "\x9e"; # bad tail
+ $expect = "\x67" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\x3c" .
+ "\xef\xbf\xbd";
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+
+ /** @todo document */
+ function testSurrogateRegression() {
+ $text = "\xed\xb4\x96" . # surrogate 0xDD16
+ "\x83" . # bad tail
+ "\xb4" . # bad tail
+ "\xac"; # bad head
+ $expect = "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd";
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+
+ /** @todo document */
+ function testBomRegression() {
+ $text = "\xef\xbf\xbe" . # U+FFFE, illegal char
+ "\xb2" . # bad tail
+ "\xef" . # bad head
+ "\x59";
+ $expect = "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\xef\xbf\xbd" .
+ "\x59";
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+
+ /** @todo document */
+ function testForbiddenRegression() {
+ $text = "\xef\xbf\xbf"; # U+FFFF, illegal char
+ $expect = "\xef\xbf\xbd";
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+
+ /** @todo document */
+ function testHangulRegression() {
+ $text = "\xed\x9c\xaf" . # Hangul char
+ "\xe1\x87\x81"; # followed by another final jamo
+ $expect = $text; # Should *not* change.
+ $this->assertEquals(
+ bin2hex( $expect ),
+ bin2hex( UtfNormal::cleanUp( $text ) ) );
+ }
+}
+
+
+$suite = new PHPUnit_TestSuite( 'CleanUpTest' );
+$result = PHPUnit::run( $suite );
+echo $result->toString();
+
+if( !$result->wasSuccessful() ) {
+ exit( -1 );
+}
+exit( 0 );
+?>
diff --git a/includes/normal/Makefile b/includes/normal/Makefile
new file mode 100644
index 000000000000..fcdf23807303
--- /dev/null
+++ b/includes/normal/Makefile
@@ -0,0 +1,72 @@
+.PHONY : all test testutf8 testclean icutest bench icubench clean distclean
+
+FETCH=wget
+#FETCH=fetch
+BASE=http://www.unicode.org/Public/UNIDATA
+PHP=php
+#PHP=php-cli
+
+all : UtfNormalData.inc
+
+UtfNormalData.inc : UtfNormalGenerate.php UtfNormalUtil.php UnicodeData.txt CompositionExclusions.txt NormalizationCorrections.txt DerivedNormalizationProps.txt
+ $(PHP) UtfNormalGenerate.php
+
+test : testutf8 testclean UtfNormalTest.php UtfNormalData.inc NormalizationTest.txt
+ $(PHP) UtfNormalTest.php
+
+testutf8 : Utf8Test.php UTF-8-test.txt
+ $(PHP) Utf8Test.php
+
+testclean : CleanUpTest.php
+ $(PHP) CleanUpTest.php
+
+bench : UtfNormalData.inc testdata/washington.txt testdata/berlin.txt testdata/tokyo.txt testdata/sociology.txt testdata/bulgakov.txt
+ $(PHP) UtfNormalBench.php
+
+icutest : UtfNormalData.inc NormalizationTest.txt
+ $(PHP) Utf8Test.php --icu
+ $(PHP) CleanUpTest.php --icu
+ $(PHP) UtfNormalTest.php --icu
+
+icubench : UtfNormalData.inc testdata/washington.txt testdata/berlin.txt testdata/tokyo.txt testdata/sociology.txt testdata/bulgakov.txt
+ $(PHP) UtfNormalBench.php --icu
+
+clean :
+ rm -f UtfNormalData.inc
+
+distclean : clean
+ rm -f CompositionExclusions.txt NormalizationTest.txt NormalizationCorrections.txt UnicodeData.txt DerivedNormalizationProps.txt
+
+# The Unicode data files...
+CompositionExclusions.txt :
+ $(FETCH) $(BASE)/CompositionExclusions.txt
+
+NormalizationTest.txt :
+ $(FETCH) $(BASE)/NormalizationTest.txt
+
+NormalizationCorrections.txt :
+ $(FETCH) $(BASE)/NormalizationCorrections.txt
+
+DerivedNormalizationProps.txt :
+ $(FETCH) $(BASE)/DerivedNormalizationProps.txt
+
+UnicodeData.txt :
+ $(FETCH) $(BASE)/UnicodeData.txt
+
+UTF-8-test.txt :
+ $(FETCH) http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
+
+testdata/berlin.txt :
+ mkdir -p testdata && wget -U MediaWiki/test -O testdata/berlin.txt "http://de.wikipedia.org/w/wiki.phtml?title=Berlin&oldid=2775712&action=raw"
+
+testdata/washington.txt :
+ mkdir -p testdata && wget -U MediaWiki/test -O testdata/washington.txt "http://en.wikipedia.org/w/wiki.phtml?title=Washington%2C_DC&oldid=6370218&action=raw"
+
+testdata/tokyo.txt :
+ mkdir -p testdata && wget -U MediaWiki/test -O testdata/tokyo.txt "http://ja.wikipedia.org/w/wiki.phtml?title=%E6%9D%B1%E4%BA%AC%E9%83%BD&oldid=940880&action=raw"
+
+testdata/sociology.txt :
+ mkdir -p testdata && wget -U MediaWiki/test -O testdata/sociology.txt "http://ko.wikipedia.org/w/wiki.phtml?title=%EC%82%AC%ED%9A%8C%ED%95%99&oldid=16409&action=raw"
+
+testdata/bulgakov.txt :
+ mkdir -p testdata && wget -U MediaWiki/test -O testdata/bulgakov.txt "http://ru.wikipedia.org/w/wiki.phtml?title=%D0%91%D1%83%D0%BB%D0%B3%D0%B0%D0%BA%D0%BE%D0%B2%2C_%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9_%D0%9D%D0%B8%D0%BA%D0%BE%D0%BB%D0%B0%D0%B5%D0%B2%D0%B8%D1%87&oldid=17704&action=raw"
diff --git a/includes/normal/README b/includes/normal/README
new file mode 100644
index 000000000000..f8207a1b2e3e
--- /dev/null
+++ b/includes/normal/README
@@ -0,0 +1,55 @@
+This directory contains some Unicode normalization routines. These routines
+are meant to be reusable in other projects, so I'm not tying them to the
+MediaWiki utility functions.
+
+The main function to care about is UtfNormal::toNFC(); this will convert
+a given UTF-8 string to Normalization Form C if it's not already such.
+The function assumes that the input string is already valid UTF-8; if there
+are corrupt characters this may produce erroneous results.
+
+To also check for illegal characters, use UtfNormal::cleanUp(). This will
+strip illegal UTF-8 sequences and characters that are illegal in XML, and
+if necessary convert to normalization form C.
+
+Performance is kind of stinky in absolute terms, though it should be speedy
+on pure ASCII text. ;) On text that can be determined quickly to already be
+in NFC it's not too awful but it can quickly get uncomfortably slow,
+particularly for Korean text (the hangul decomposition/composition code is
+extra slow).
+
+
+== Regenerating data tables ==
+
+UtfNormalData.inc and UtfNormalDataK.inc are generated from the Unicode
+Character Database by the script UtfNormalGenerate.php. On a *nix system
+'make' should fetch the necessary files and regenerate it if the scripts
+have been changed or you remove it.
+
+
+== Testing ==
+
+'make test' will run the conformance test (UtfNormalTest.php), fetching the
+data from from the net if necessary. If it reports failure, something is
+going wrong!
+
+
+== Benchmarks ==
+
+Run 'make bench' to download some sample texts from Wikipedia and run some
+cheap benchmarks of some of the functions. Take all numbers with large
+grains of salt.
+
+
+== PHP module extension ==
+
+There's an experimental PHP extension module which wraps the ICU library's
+normalization functions. This is *MUCH* faster than doing this work in pure
+PHP code. This is in the 'normal' directory in MediaWiki's CVS extensions
+module. It is known to work with PHP 4.3.8 and 5.0.2 on Linux/x86 but hasn't
+been thoroughly tested on other configurations.
+
+If the php_normal.so module is loaded in php.ini, the normalization functions
+will automatically use it. If you can't (or don't want to) load it in php.ini,
+you may be able to load it using the dl() function before include()ing or
+require()ing UtfNormal.php, and it will be picked up.
+
diff --git a/includes/normal/RandomTest.php b/includes/normal/RandomTest.php
new file mode 100644
index 000000000000..b86ab7c32af5
--- /dev/null
+++ b/includes/normal/RandomTest.php
@@ -0,0 +1,108 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Test feeds random 16-byte strings to both the pure PHP and ICU-based
+ * UtfNormal::cleanUp() code paths, and checks to see if there's a
+ * difference. Will run forever until it finds one or you kill it.
+ *
+ * @package UtfNormal
+ * @access private
+ */
+
+if( php_sapi_name() != 'cli' ) {
+ die( "Run me from the command line please.\n" );
+}
+
+/** */
+require_once( 'UtfNormal.php' );
+require_once( '../DifferenceEngine.php' );
+
+dl('php_utfnormal.so' );
+
+# mt_srand( 99999 );
+
+function randomString( $length, $nullOk, $ascii = false ) {
+ $out = '';
+ for( $i = 0; $i < $length; $i++ )
+ $out .= chr( mt_rand( $nullOk ? 0 : 1, $ascii ? 127 : 255 ) );
+ return $out;
+}
+
+/* Duplicate of the cleanUp() path for ICU usage */
+function donorm( $str ) {
+ # We exclude a few chars that ICU would not.
+ $str = preg_replace( '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', UTF8_REPLACEMENT, $str );
+ $str = str_replace( UTF8_FFFE, UTF8_REPLACEMENT, $str );
+ $str = str_replace( UTF8_FFFF, UTF8_REPLACEMENT, $str );
+
+ # UnicodeString constructor fails if the string ends with a head byte.
+ # Add a junk char at the end, we'll strip it off
+ return rtrim( utf8_normalize( $str . "\x01", UNORM_NFC ), "\x01" );
+}
+
+function wfMsg($x) {
+ return $x;
+}
+
+function showDiffs( $a, $b ) {
+ $ota = explode( "\n", str_replace( "\r\n", "\n", $a ) );
+ $nta = explode( "\n", str_replace( "\r\n", "\n", $b ) );
+
+ $diffs = new Diff( $ota, $nta );
+ $formatter = new TableDiffFormatter();
+ $funky = $formatter->format( $diffs );
+ $matches = array();
+ preg_match_all( '/<span class="diffchange">(.*?)<\/span>/', $funky, $matches );
+ foreach( $matches[1] as $bit ) {
+ $hex = bin2hex( $bit );
+ echo "\t$hex\n";
+ }
+}
+
+$size = 16;
+$n = 0;
+while( true ) {
+ $n++;
+ echo "$n\n";
+
+ $str = randomString( $size, true);
+ $clean = UtfNormal::cleanUp( $str );
+ $norm = donorm( $str );
+
+ echo strlen( $clean ) . ", " . strlen( $norm );
+ if( $clean == $norm ) {
+ echo " (match)\n";
+ } else {
+ echo " (FAIL)\n";
+ echo "\traw: " . bin2hex( $str ) . "\n" .
+ "\tphp: " . bin2hex( $clean ) . "\n" .
+ "\ticu: " . bin2hex( $norm ) . "\n";
+ echo "\n\tdiffs:\n";
+ showDiffs( $clean, $norm );
+ die();
+ }
+
+
+ $str = '';
+ $clean = '';
+ $norm = '';
+}
+
+?>
diff --git a/includes/normal/Utf8Test.php b/includes/normal/Utf8Test.php
new file mode 100644
index 000000000000..34ab69c8c3a1
--- /dev/null
+++ b/includes/normal/Utf8Test.php
@@ -0,0 +1,153 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Runs the UTF-8 decoder test at:
+ * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
+ *
+ * @package UtfNormal
+ * @access private
+ */
+
+/** */
+require_once 'UtfNormalUtil.php';
+require_once 'UtfNormal.php';
+mb_internal_encoding( "utf-8" );
+
+#$verbose = true;
+if( php_sapi_name() != 'cli' ) {
+ die( "Run me from the command line please.\n" );
+}
+
+$in = fopen( "UTF-8-test.txt", "rt" );
+if( !$in ) {
+ print "Couldn't open UTF-8-test.txt -- can't run tests.\n";
+ print "If necessary, manually download this file. It can be obtained at\n";
+ print "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt";
+ exit(-1);
+}
+
+$columns = 0;
+while( false !== ( $line = fgets( $in ) ) ) {
+ $matches = array();
+ if( preg_match( '/^(Here come the tests:\s*)\|$/', $line, $matches ) ) {
+ $columns = strpos( $line, '|' );
+ break;
+ }
+}
+
+if( !$columns ) {
+ print "Something seems to be wrong; couldn't extract line length.\n";
+ print "Check that UTF-8-test.txt was downloaded correctly from\n";
+ print "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt";
+ exit(-1);
+}
+
+# print "$columns\n";
+
+$ignore = array(
+ # These two lines actually seem to be corrupt
+ '2.1.1', '2.2.1' );
+
+$exceptions = array(
+ # Tests that should mark invalid characters due to using long
+ # sequences beyond what is now considered legal.
+ '2.1.5', '2.1.6', '2.2.4', '2.2.5', '2.2.6', '2.3.5',
+
+ # Literal 0xffff, which is illegal
+ '2.2.3' );
+
+$longTests = array(
+ # These tests span multiple lines
+ '3.1.9', '3.2.1', '3.2.2', '3.2.3', '3.2.4', '3.2.5',
+ '3.4' );
+
+# These tests are not in proper subsections
+$sectionTests = array( '3.4' );
+
+$section = NULL;
+$test = '';
+$failed = 0;
+$success = 0;
+$total = 0;
+while( false !== ( $line = fgets( $in ) ) ) {
+ $matches = array();
+ if( preg_match( '/^(\d+)\s+(.*?)\s*\|/', $line, $matches ) ) {
+ $section = $matches[1];
+ print $line;
+ continue;
+ }
+ if( preg_match( '/^(\d+\.\d+\.\d+)\s*/', $line, $matches ) ) {
+ $test = $matches[1];
+
+ if( in_array( $test, $ignore ) ) {
+ continue;
+ }
+ if( in_array( $test, $longTests ) ) {
+ $line = fgets( $in );
+ for( $line = fgets( $in ); !preg_match( '/^\s+\|/', $line ); $line = fgets( $in ) ) {
+ testLine( $test, $line, $total, $success, $failed );
+ }
+ } else {
+ testLine( $test, $line, $total, $success, $failed );
+ }
+ }
+}
+
+if( $failed ) {
+ echo "\nFailed $failed tests.\n";
+ echo "UTF-8 DECODER TEST FAILED\n";
+ exit (-1);
+}
+
+echo "UTF-8 DECODER TEST SUCCESS!\n";
+exit (0);
+
+
+function testLine( $test, $line, &$total, &$success, &$failed ) {
+ $stripped = $line;
+ UtfNormal::quickisNFCVerify( $stripped );
+
+ $same = ( $line == $stripped );
+ $len = mb_strlen( substr( $stripped, 0, strpos( $stripped, '|' ) ) );
+ if( $len == 0 ) {
+ $len = strlen( substr( $stripped, 0, strpos( $stripped, '|' ) ) );
+ }
+
+ global $columns;
+ $ok = $same ^ ($test >= 3 );
+
+ global $exceptions;
+ $ok ^= in_array( $test, $exceptions );
+
+ $ok &= ($columns == $len);
+
+ $total++;
+ if( $ok ) {
+ $success++;
+ } else {
+ $failed++;
+ }
+ global $verbose;
+ if( $verbose || !$ok ) {
+ print str_replace( "\n", "$len\n", $stripped );
+ }
+}
+
+?>
diff --git a/includes/normal/UtfNormal.php b/includes/normal/UtfNormal.php
new file mode 100644
index 000000000000..d8eac7b8ad3f
--- /dev/null
+++ b/includes/normal/UtfNormal.php
@@ -0,0 +1,808 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Unicode normalization routines for working with UTF-8 strings.
+ * Currently assumes that input strings are valid UTF-8!
+ *
+ * Not as fast as I'd like, but should be usable for most purposes.
+ * UtfNormal::toNFC() will bail early if given ASCII text or text
+ * it can quickly deterimine is already normalized.
+ *
+ * All functions can be called static.
+ *
+ * See description of forms at http://www.unicode.org/reports/tr15/
+ *
+ * @package UtfNormal
+ */
+
+/** */
+require_once dirname(__FILE__).'/UtfNormalUtil.php';
+
+global $utfCombiningClass, $utfCanonicalComp, $utfCanonicalDecomp;
+$utfCombiningClass = NULL;
+$utfCanonicalComp = NULL;
+$utfCanonicalDecomp = NULL;
+
+# Load compatibility decompositions on demand if they are needed.
+global $utfCompatibilityDecomp;
+$utfCompatibilityDecomp = NULL;
+
+define( 'UNICODE_HANGUL_FIRST', 0xac00 );
+define( 'UNICODE_HANGUL_LAST', 0xd7a3 );
+
+define( 'UNICODE_HANGUL_LBASE', 0x1100 );
+define( 'UNICODE_HANGUL_VBASE', 0x1161 );
+define( 'UNICODE_HANGUL_TBASE', 0x11a7 );
+
+define( 'UNICODE_HANGUL_LCOUNT', 19 );
+define( 'UNICODE_HANGUL_VCOUNT', 21 );
+define( 'UNICODE_HANGUL_TCOUNT', 28 );
+define( 'UNICODE_HANGUL_NCOUNT', UNICODE_HANGUL_VCOUNT * UNICODE_HANGUL_TCOUNT );
+
+define( 'UNICODE_HANGUL_LEND', UNICODE_HANGUL_LBASE + UNICODE_HANGUL_LCOUNT - 1 );
+define( 'UNICODE_HANGUL_VEND', UNICODE_HANGUL_VBASE + UNICODE_HANGUL_VCOUNT - 1 );
+define( 'UNICODE_HANGUL_TEND', UNICODE_HANGUL_TBASE + UNICODE_HANGUL_TCOUNT - 1 );
+
+define( 'UNICODE_SURROGATE_FIRST', 0xd800 );
+define( 'UNICODE_SURROGATE_LAST', 0xdfff );
+define( 'UNICODE_MAX', 0x10ffff );
+define( 'UNICODE_REPLACEMENT', 0xfffd );
+
+
+define( 'UTF8_HANGUL_FIRST', "\xea\xb0\x80" /*codepointToUtf8( UNICODE_HANGUL_FIRST )*/ );
+define( 'UTF8_HANGUL_LAST', "\xed\x9e\xa3" /*codepointToUtf8( UNICODE_HANGUL_LAST )*/ );
+
+define( 'UTF8_HANGUL_LBASE', "\xe1\x84\x80" /*codepointToUtf8( UNICODE_HANGUL_LBASE )*/ );
+define( 'UTF8_HANGUL_VBASE', "\xe1\x85\xa1" /*codepointToUtf8( UNICODE_HANGUL_VBASE )*/ );
+define( 'UTF8_HANGUL_TBASE', "\xe1\x86\xa7" /*codepointToUtf8( UNICODE_HANGUL_TBASE )*/ );
+
+define( 'UTF8_HANGUL_LEND', "\xe1\x84\x92" /*codepointToUtf8( UNICODE_HANGUL_LEND )*/ );
+define( 'UTF8_HANGUL_VEND', "\xe1\x85\xb5" /*codepointToUtf8( UNICODE_HANGUL_VEND )*/ );
+define( 'UTF8_HANGUL_TEND', "\xe1\x87\x82" /*codepointToUtf8( UNICODE_HANGUL_TEND )*/ );
+
+define( 'UTF8_SURROGATE_FIRST', "\xed\xa0\x80" /*codepointToUtf8( UNICODE_SURROGATE_FIRST )*/ );
+define( 'UTF8_SURROGATE_LAST', "\xed\xbf\xbf" /*codepointToUtf8( UNICODE_SURROGATE_LAST )*/ );
+define( 'UTF8_MAX', "\xf4\x8f\xbf\xbf" /*codepointToUtf8( UNICODE_MAX )*/ );
+define( 'UTF8_REPLACEMENT', "\xef\xbf\xbd" /*codepointToUtf8( UNICODE_REPLACEMENT )*/ );
+#define( 'UTF8_REPLACEMENT', '!' );
+
+define( 'UTF8_OVERLONG_A', "\xc1\xbf" );
+define( 'UTF8_OVERLONG_B', "\xe0\x9f\xbf" );
+define( 'UTF8_OVERLONG_C', "\xf0\x8f\xbf\xbf" );
+
+# These two ranges are illegal
+define( 'UTF8_FDD0', "\xef\xb7\x90" /*codepointToUtf8( 0xfdd0 )*/ );
+define( 'UTF8_FDEF', "\xef\xb7\xaf" /*codepointToUtf8( 0xfdef )*/ );
+define( 'UTF8_FFFE', "\xef\xbf\xbe" /*codepointToUtf8( 0xfffe )*/ );
+define( 'UTF8_FFFF', "\xef\xbf\xbf" /*codepointToUtf8( 0xffff )*/ );
+
+define( 'UTF8_HEAD', false );
+define( 'UTF8_TAIL', true );
+
+
+/**
+ * For using the ICU wrapper
+ */
+define( 'UNORM_NONE', 1 );
+define( 'UNORM_NFD', 2 );
+define( 'UNORM_NFKD', 3 );
+define( 'UNORM_NFC', 4 );
+define( 'UNORM_DEFAULT', UNORM_NFC );
+define( 'UNORM_NFKC', 5 );
+define( 'UNORM_FCD', 6 );
+
+define( 'NORMALIZE_ICU', function_exists( 'utf8_normalize' ) );
+
+/**
+ *
+ * @package MediaWiki
+ */
+class UtfNormal {
+ /**
+ * The ultimate convenience function! Clean up invalid UTF-8 sequences,
+ * and convert to normal form C, canonical composition.
+ *
+ * Fast return for pure ASCII strings; some lesser optimizations for
+ * strings containing only known-good characters. Not as fast as toNFC().
+ *
+ * @param string $string a UTF-8 string
+ * @return string a clean, shiny, normalized UTF-8 string
+ * @static
+ */
+ static function cleanUp( $string ) {
+ if( NORMALIZE_ICU ) {
+ # We exclude a few chars that ICU would not.
+ $string = preg_replace(
+ '/[\x00-\x08\x0b\x0c\x0e-\x1f]/',
+ UTF8_REPLACEMENT,
+ $string );
+ $string = str_replace( UTF8_FFFE, UTF8_REPLACEMENT, $string );
+ $string = str_replace( UTF8_FFFF, UTF8_REPLACEMENT, $string );
+
+ # UnicodeString constructor fails if the string ends with a
+ # head byte. Add a junk char at the end, we'll strip it off.
+ return rtrim( utf8_normalize( $string . "\x01", UNORM_NFC ), "\x01" );
+ } elseif( UtfNormal::quickIsNFCVerify( $string ) ) {
+ # Side effect -- $string has had UTF-8 errors cleaned up.
+ return $string;
+ } else {
+ return UtfNormal::NFC( $string );
+ }
+ }
+
+ /**
+ * Convert a UTF-8 string to normal form C, canonical composition.
+ * Fast return for pure ASCII strings; some lesser optimizations for
+ * strings containing only known-good characters.
+ *
+ * @param string $string a valid UTF-8 string. Input is not validated.
+ * @return string a UTF-8 string in normal form C
+ * @static
+ */
+ static function toNFC( $string ) {
+ if( NORMALIZE_ICU )
+ return utf8_normalize( $string, UNORM_NFC );
+ elseif( UtfNormal::quickIsNFC( $string ) )
+ return $string;
+ else
+ return UtfNormal::NFC( $string );
+ }
+
+ /**
+ * Convert a UTF-8 string to normal form D, canonical decomposition.
+ * Fast return for pure ASCII strings.
+ *
+ * @param string $string a valid UTF-8 string. Input is not validated.
+ * @return string a UTF-8 string in normal form D
+ * @static
+ */
+ static function toNFD( $string ) {
+ if( NORMALIZE_ICU )
+ return utf8_normalize( $string, UNORM_NFD );
+ elseif( preg_match( '/[\x80-\xff]/', $string ) )
+ return UtfNormal::NFD( $string );
+ else
+ return $string;
+ }
+
+ /**
+ * Convert a UTF-8 string to normal form KC, compatibility composition.
+ * This may cause irreversible information loss, use judiciously.
+ * Fast return for pure ASCII strings.
+ *
+ * @param string $string a valid UTF-8 string. Input is not validated.
+ * @return string a UTF-8 string in normal form KC
+ * @static
+ */
+ static function toNFKC( $string ) {
+ if( NORMALIZE_ICU )
+ return utf8_normalize( $string, UNORM_NFKC );
+ elseif( preg_match( '/[\x80-\xff]/', $string ) )
+ return UtfNormal::NFKC( $string );
+ else
+ return $string;
+ }
+
+ /**
+ * Convert a UTF-8 string to normal form KD, compatibility decomposition.
+ * This may cause irreversible information loss, use judiciously.
+ * Fast return for pure ASCII strings.
+ *
+ * @param string $string a valid UTF-8 string. Input is not validated.
+ * @return string a UTF-8 string in normal form KD
+ * @static
+ */
+ static function toNFKD( $string ) {
+ if( NORMALIZE_ICU )
+ return utf8_normalize( $string, UNORM_NFKD );
+ elseif( preg_match( '/[\x80-\xff]/', $string ) )
+ return UtfNormal::NFKD( $string );
+ else
+ return $string;
+ }
+
+ /**
+ * Load the basic composition data if necessary
+ * @private
+ * @static
+ */
+ static function loadData() {
+ global $utfCombiningClass;
+ if( !isset( $utfCombiningClass ) ) {
+ require_once( 'UtfNormalData.inc' );
+ }
+ }
+
+ /**
+ * Returns true if the string is _definitely_ in NFC.
+ * Returns false if not or uncertain.
+ * @param string $string a valid UTF-8 string. Input is not validated.
+ * @return bool
+ * @static
+ */
+ static function quickIsNFC( $string ) {
+ # ASCII is always valid NFC!
+ # If it's pure ASCII, let it through.
+ if( !preg_match( '/[\x80-\xff]/', $string ) ) return true;
+
+ UtfNormal::loadData();
+ global $utfCheckNFC, $utfCombiningClass;
+ $len = strlen( $string );
+ for( $i = 0; $i < $len; $i++ ) {
+ $c = $string{$i};
+ $n = ord( $c );
+ if( $n < 0x80 ) {
+ continue;
+ } elseif( $n >= 0xf0 ) {
+ $c = substr( $string, $i, 4 );
+ $i += 3;
+ } elseif( $n >= 0xe0 ) {
+ $c = substr( $string, $i, 3 );
+ $i += 2;
+ } elseif( $n >= 0xc0 ) {
+ $c = substr( $string, $i, 2 );
+ $i++;
+ }
+ if( isset( $utfCheckNFC[$c] ) ) {
+ # If it's NO or MAYBE, bail and do the slow check.
+ return false;
+ }
+ if( isset( $utfCombiningClass[$c] ) ) {
+ # Combining character? We might have to do sorting, at least.
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns true if the string is _definitely_ in NFC.
+ * Returns false if not or uncertain.
+ * @param string $string a UTF-8 string, altered on output to be valid UTF-8 safe for XML.
+ * @static
+ */
+ static function quickIsNFCVerify( &$string ) {
+ # Screen out some characters that eg won't be allowed in XML
+ $string = preg_replace( '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', UTF8_REPLACEMENT, $string );
+
+ # ASCII is always valid NFC!
+ # If we're only ever given plain ASCII, we can avoid the overhead
+ # of initializing the decomposition tables by skipping out early.
+ if( !preg_match( '/[\x80-\xff]/', $string ) ) return true;
+
+ static $checkit = null, $tailBytes = null, $utfCheckOrCombining = null;
+ if( !isset( $checkit ) ) {
+ # Load/build some scary lookup tables...
+ UtfNormal::loadData();
+ global $utfCheckNFC, $utfCombiningClass;
+
+ $utfCheckOrCombining = array_merge( $utfCheckNFC, $utfCombiningClass );
+
+ # Head bytes for sequences which we should do further validity checks
+ $checkit = array_flip( array_map( 'chr',
+ array( 0xc0, 0xc1, 0xe0, 0xed, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff ) ) );
+
+ # Each UTF-8 head byte is followed by a certain
+ # number of tail bytes.
+ $tailBytes = array();
+ for( $n = 0; $n < 256; $n++ ) {
+ if( $n < 0xc0 ) {
+ $remaining = 0;
+ } elseif( $n < 0xe0 ) {
+ $remaining = 1;
+ } elseif( $n < 0xf0 ) {
+ $remaining = 2;
+ } elseif( $n < 0xf8 ) {
+ $remaining = 3;
+ } elseif( $n < 0xfc ) {
+ $remaining = 4;
+ } elseif( $n < 0xfe ) {
+ $remaining = 5;
+ } else {
+ $remaining = 0;
+ }
+ $tailBytes[chr($n)] = $remaining;
+ }
+ }
+
+ # Chop the text into pure-ASCII and non-ASCII areas;
+ # large ASCII parts can be handled much more quickly.
+ # Don't chop up Unicode areas for punctuation, though,
+ # that wastes energy.
+ $matches = array();
+ preg_match_all(
+ '/([\x00-\x7f]+|[\x80-\xff][\x00-\x40\x5b-\x5f\x7b-\xff]*)/',
+ $string, $matches );
+
+ $looksNormal = true;
+ $base = 0;
+ $replace = array();
+ foreach( $matches[1] as $str ) {
+ $chunk = strlen( $str );
+
+ if( $str{0} < "\x80" ) {
+ # ASCII chunk: guaranteed to be valid UTF-8
+ # and in normal form C, so skip over it.
+ $base += $chunk;
+ continue;
+ }
+
+ # We'll have to examine the chunk byte by byte to ensure
+ # that it consists of valid UTF-8 sequences, and to see
+ # if any of them might not be normalized.
+ #
+ # Since PHP is not the fastest language on earth, some of
+ # this code is a little ugly with inner loop optimizations.
+
+ $head = '';
+ $len = $chunk + 1; # Counting down is faster. I'm *so* sorry.
+
+ for( $i = -1; --$len; ) {
+ if( $remaining = $tailBytes[$c = $str{++$i}] ) {
+ # UTF-8 head byte!
+ $sequence = $head = $c;
+ do {
+ # Look for the defined number of tail bytes...
+ if( --$len && ( $c = $str{++$i} ) >= "\x80" && $c < "\xc0" ) {
+ # Legal tail bytes are nice.
+ $sequence .= $c;
+ } else {
+ if( 0 == $len ) {
+ # Premature end of string!
+ # Drop a replacement character into output to
+ # represent the invalid UTF-8 sequence.
+ $replace[] = array( UTF8_REPLACEMENT,
+ $base + $i + 1 - strlen( $sequence ),
+ strlen( $sequence ) );
+ break 2;
+ } else {
+ # Illegal tail byte; abandon the sequence.
+ $replace[] = array( UTF8_REPLACEMENT,
+ $base + $i - strlen( $sequence ),
+ strlen( $sequence ) );
+ # Back up and reprocess this byte; it may itself
+ # be a legal ASCII or UTF-8 sequence head.
+ --$i;
+ ++$len;
+ continue 2;
+ }
+ }
+ } while( --$remaining );
+
+ if( isset( $checkit[$head] ) ) {
+ # Do some more detailed validity checks, for
+ # invalid characters and illegal sequences.
+ if( $head == "\xed" ) {
+ # 0xed is relatively frequent in Korean, which
+ # abuts the surrogate area, so we're doing
+ # this check separately to speed things up.
+
+ if( $sequence >= UTF8_SURROGATE_FIRST ) {
+ # Surrogates are legal only in UTF-16 code.
+ # They are totally forbidden here in UTF-8
+ # utopia.
+ $replace[] = array( UTF8_REPLACEMENT,
+ $base + $i + 1 - strlen( $sequence ),
+ strlen( $sequence ) );
+ $head = '';
+ continue;
+ }
+ } else {
+ # Slower, but rarer checks...
+ $n = ord( $head );
+ if(
+ # "Overlong sequences" are those that are syntactically
+ # correct but use more UTF-8 bytes than are necessary to
+ # encode a character. Naïve string comparisons can be
+ # tricked into failing to see a match for an ASCII
+ # character, for instance, which can be a security hole
+ # if blacklist checks are being used.
+ ($n < 0xc2 && $sequence <= UTF8_OVERLONG_A)
+ || ($n == 0xe0 && $sequence <= UTF8_OVERLONG_B)
+ || ($n == 0xf0 && $sequence <= UTF8_OVERLONG_C)
+
+ # U+FFFE and U+FFFF are explicitly forbidden in Unicode.
+ || ($n == 0xef &&
+ ($sequence == UTF8_FFFE)
+ || ($sequence == UTF8_FFFF) )
+
+ # Unicode has been limited to 21 bits; longer
+ # sequences are not allowed.
+ || ($n >= 0xf0 && $sequence > UTF8_MAX) ) {
+
+ $replace[] = array( UTF8_REPLACEMENT,
+ $base + $i + 1 - strlen( $sequence ),
+ strlen( $sequence ) );
+ $head = '';
+ continue;
+ }
+ }
+ }
+
+ if( isset( $utfCheckOrCombining[$sequence] ) ) {
+ # If it's NO or MAYBE, we'll have to rip
+ # the string apart and put it back together.
+ # That's going to be mighty slow.
+ $looksNormal = false;
+ }
+
+ # The sequence is legal!
+ $head = '';
+ } elseif( $c < "\x80" ) {
+ # ASCII byte.
+ $head = '';
+ } elseif( $c < "\xc0" ) {
+ # Illegal tail bytes
+ if( $head == '' ) {
+ # Out of the blue!
+ $replace[] = array( UTF8_REPLACEMENT, $base + $i, 1 );
+ } else {
+ # Don't add if we're continuing a broken sequence;
+ # we already put a replacement character when we looked
+ # at the broken sequence.
+ $replace[] = array( '', $base + $i, 1 );
+ }
+ } else {
+ # Miscellaneous freaks.
+ $replace[] = array( UTF8_REPLACEMENT, $base + $i, 1 );
+ $head = '';
+ }
+ }
+ $base += $chunk;
+ }
+ if( count( $replace ) ) {
+ # There were illegal UTF-8 sequences we need to fix up.
+ $out = '';
+ $last = 0;
+ foreach( $replace as $rep ) {
+ list( $replacement, $start, $length ) = $rep;
+ if( $last < $start ) {
+ $out .= substr( $string, $last, $start - $last );
+ }
+ $out .= $replacement;
+ $last = $start + $length;
+ }
+ if( $last < strlen( $string ) ) {
+ $out .= substr( $string, $last );
+ }
+ $string = $out;
+ }
+ return $looksNormal;
+ }
+
+ # These take a string and run the normalization on them, without
+ # checking for validity or any optimization etc. Input must be
+ # VALID UTF-8!
+ /**
+ * @param string $string
+ * @return string
+ * @private
+ * @static
+ */
+ static function NFC( $string ) {
+ return UtfNormal::fastCompose( UtfNormal::NFD( $string ) );
+ }
+
+ /**
+ * @param string $string
+ * @return string
+ * @private
+ * @static
+ */
+ static function NFD( $string ) {
+ UtfNormal::loadData();
+ global $utfCanonicalDecomp;
+ return UtfNormal::fastCombiningSort(
+ UtfNormal::fastDecompose( $string, $utfCanonicalDecomp ) );
+ }
+
+ /**
+ * @param string $string
+ * @return string
+ * @private
+ * @static
+ */
+ static function NFKC( $string ) {
+ return UtfNormal::fastCompose( UtfNormal::NFKD( $string ) );
+ }
+
+ /**
+ * @param string $string
+ * @return string
+ * @private
+ * @static
+ */
+ static function NFKD( $string ) {
+ global $utfCompatibilityDecomp;
+ if( !isset( $utfCompatibilityDecomp ) ) {
+ require_once( 'UtfNormalDataK.inc' );
+ }
+ return UtfNormal::fastCombiningSort(
+ UtfNormal::fastDecompose( $string, $utfCompatibilityDecomp ) );
+ }
+
+
+ /**
+ * Perform decomposition of a UTF-8 string into either D or KD form
+ * (depending on which decomposition map is passed to us).
+ * Input is assumed to be *valid* UTF-8. Invalid code will break.
+ * @private
+ * @param string $string Valid UTF-8 string
+ * @param array $map hash of expanded decomposition map
+ * @return string a UTF-8 string decomposed, not yet normalized (needs sorting)
+ * @static
+ */
+ static function fastDecompose( $string, $map ) {
+ UtfNormal::loadData();
+ $len = strlen( $string );
+ $out = '';
+ for( $i = 0; $i < $len; $i++ ) {
+ $c = $string{$i};
+ $n = ord( $c );
+ if( $n < 0x80 ) {
+ # ASCII chars never decompose
+ # THEY ARE IMMORTAL
+ $out .= $c;
+ continue;
+ } elseif( $n >= 0xf0 ) {
+ $c = substr( $string, $i, 4 );
+ $i += 3;
+ } elseif( $n >= 0xe0 ) {
+ $c = substr( $string, $i, 3 );
+ $i += 2;
+ } elseif( $n >= 0xc0 ) {
+ $c = substr( $string, $i, 2 );
+ $i++;
+ }
+ if( isset( $map[$c] ) ) {
+ $out .= $map[$c];
+ continue;
+ } else {
+ if( $c >= UTF8_HANGUL_FIRST && $c <= UTF8_HANGUL_LAST ) {
+ # Decompose a hangul syllable into jamo;
+ # hardcoded for three-byte UTF-8 sequence.
+ # A lookup table would be slightly faster,
+ # but adds a lot of memory & disk needs.
+ #
+ $index = ( (ord( $c{0} ) & 0x0f) << 12
+ | (ord( $c{1} ) & 0x3f) << 6
+ | (ord( $c{2} ) & 0x3f) )
+ - UNICODE_HANGUL_FIRST;
+ $l = intval( $index / UNICODE_HANGUL_NCOUNT );
+ $v = intval( ($index % UNICODE_HANGUL_NCOUNT) / UNICODE_HANGUL_TCOUNT);
+ $t = $index % UNICODE_HANGUL_TCOUNT;
+ $out .= "\xe1\x84" . chr( 0x80 + $l ) . "\xe1\x85" . chr( 0xa1 + $v );
+ if( $t >= 25 ) {
+ $out .= "\xe1\x87" . chr( 0x80 + $t - 25 );
+ } elseif( $t ) {
+ $out .= "\xe1\x86" . chr( 0xa7 + $t );
+ }
+ continue;
+ }
+ }
+ $out .= $c;
+ }
+ return $out;
+ }
+
+ /**
+ * Sorts combining characters into canonical order. This is the
+ * final step in creating decomposed normal forms D and KD.
+ * @private
+ * @param string $string a valid, decomposed UTF-8 string. Input is not validated.
+ * @return string a UTF-8 string with combining characters sorted in canonical order
+ * @static
+ */
+ static function fastCombiningSort( $string ) {
+ UtfNormal::loadData();
+ global $utfCombiningClass;
+ $len = strlen( $string );
+ $out = '';
+ $combiners = array();
+ $lastClass = -1;
+ for( $i = 0; $i < $len; $i++ ) {
+ $c = $string{$i};
+ $n = ord( $c );
+ if( $n >= 0x80 ) {
+ if( $n >= 0xf0 ) {
+ $c = substr( $string, $i, 4 );
+ $i += 3;
+ } elseif( $n >= 0xe0 ) {
+ $c = substr( $string, $i, 3 );
+ $i += 2;
+ } elseif( $n >= 0xc0 ) {
+ $c = substr( $string, $i, 2 );
+ $i++;
+ }
+ if( isset( $utfCombiningClass[$c] ) ) {
+ $lastClass = $utfCombiningClass[$c];
+ @$combiners[$lastClass] .= $c;
+ continue;
+ }
+ }
+ if( $lastClass ) {
+ ksort( $combiners );
+ $out .= implode( '', $combiners );
+ $combiners = array();
+ }
+ $out .= $c;
+ $lastClass = 0;
+ }
+ if( $lastClass ) {
+ ksort( $combiners );
+ $out .= implode( '', $combiners );
+ }
+ return $out;
+ }
+
+ /**
+ * Produces canonically composed sequences, i.e. normal form C or KC.
+ *
+ * @private
+ * @param string $string a valid UTF-8 string in sorted normal form D or KD. Input is not validated.
+ * @return string a UTF-8 string with canonical precomposed characters used where possible
+ * @static
+ */
+ static function fastCompose( $string ) {
+ UtfNormal::loadData();
+ global $utfCanonicalComp, $utfCombiningClass;
+ $len = strlen( $string );
+ $out = '';
+ $lastClass = -1;
+ $lastHangul = 0;
+ $startChar = '';
+ $combining = '';
+ $x1 = ord(substr(UTF8_HANGUL_VBASE,0,1));
+ $x2 = ord(substr(UTF8_HANGUL_TEND,0,1));
+ for( $i = 0; $i < $len; $i++ ) {
+ $c = $string{$i};
+ $n = ord( $c );
+ if( $n < 0x80 ) {
+ # No combining characters here...
+ $out .= $startChar;
+ $out .= $combining;
+ $startChar = $c;
+ $combining = '';
+ $lastClass = 0;
+ continue;
+ } elseif( $n >= 0xf0 ) {
+ $c = substr( $string, $i, 4 );
+ $i += 3;
+ } elseif( $n >= 0xe0 ) {
+ $c = substr( $string, $i, 3 );
+ $i += 2;
+ } elseif( $n >= 0xc0 ) {
+ $c = substr( $string, $i, 2 );
+ $i++;
+ }
+ $pair = $startChar . $c;
+ if( $n > 0x80 ) {
+ if( isset( $utfCombiningClass[$c] ) ) {
+ # A combining char; see what we can do with it
+ $class = $utfCombiningClass[$c];
+ if( !empty( $startChar ) &&
+ $lastClass < $class &&
+ $class > 0 &&
+ isset( $utfCanonicalComp[$pair] ) ) {
+ $startChar = $utfCanonicalComp[$pair];
+ $class = 0;
+ } else {
+ $combining .= $c;
+ }
+ $lastClass = $class;
+ $lastHangul = 0;
+ continue;
+ }
+ }
+ # New start char
+ if( $lastClass == 0 ) {
+ if( isset( $utfCanonicalComp[$pair] ) ) {
+ $startChar = $utfCanonicalComp[$pair];
+ $lastHangul = 0;
+ continue;
+ }
+ if( $n >= $x1 && $n <= $x2 ) {
+ # WARNING: Hangul code is painfully slow.
+ # I apologize for this ugly, ugly code; however
+ # performance is even more teh suck if we call
+ # out to nice clean functions. Lookup tables are
+ # marginally faster, but require a lot of space.
+ #
+ if( $c >= UTF8_HANGUL_VBASE &&
+ $c <= UTF8_HANGUL_VEND &&
+ $startChar >= UTF8_HANGUL_LBASE &&
+ $startChar <= UTF8_HANGUL_LEND ) {
+ #
+ #$lIndex = utf8ToCodepoint( $startChar ) - UNICODE_HANGUL_LBASE;
+ #$vIndex = utf8ToCodepoint( $c ) - UNICODE_HANGUL_VBASE;
+ $lIndex = ord( $startChar{2} ) - 0x80;
+ $vIndex = ord( $c{2} ) - 0xa1;
+
+ $hangulPoint = UNICODE_HANGUL_FIRST +
+ UNICODE_HANGUL_TCOUNT *
+ (UNICODE_HANGUL_VCOUNT * $lIndex + $vIndex);
+
+ # Hardcode the limited-range UTF-8 conversion:
+ $startChar = chr( $hangulPoint >> 12 & 0x0f | 0xe0 ) .
+ chr( $hangulPoint >> 6 & 0x3f | 0x80 ) .
+ chr( $hangulPoint & 0x3f | 0x80 );
+ $lastHangul = 0;
+ continue;
+ } elseif( $c >= UTF8_HANGUL_TBASE &&
+ $c <= UTF8_HANGUL_TEND &&
+ $startChar >= UTF8_HANGUL_FIRST &&
+ $startChar <= UTF8_HANGUL_LAST &&
+ !$lastHangul ) {
+ # $tIndex = utf8ToCodepoint( $c ) - UNICODE_HANGUL_TBASE;
+ $tIndex = ord( $c{2} ) - 0xa7;
+ if( $tIndex < 0 ) $tIndex = ord( $c{2} ) - 0x80 + (0x11c0 - 0x11a7);
+
+ # Increment the code point by $tIndex, without
+ # the function overhead of decoding and recoding UTF-8
+ #
+ $tail = ord( $startChar{2} ) + $tIndex;
+ if( $tail > 0xbf ) {
+ $tail -= 0x40;
+ $mid = ord( $startChar{1} ) + 1;
+ if( $mid > 0xbf ) {
+ $startChar{0} = chr( ord( $startChar{0} ) + 1 );
+ $mid -= 0x40;
+ }
+ $startChar{1} = chr( $mid );
+ }
+ $startChar{2} = chr( $tail );
+
+ # If there's another jamo char after this, *don't* try to merge it.
+ $lastHangul = 1;
+ continue;
+ }
+ }
+ }
+ $out .= $startChar;
+ $out .= $combining;
+ $startChar = $c;
+ $combining = '';
+ $lastClass = 0;
+ $lastHangul = 0;
+ }
+ $out .= $startChar . $combining;
+ return $out;
+ }
+
+ /**
+ * This is just used for the benchmark, comparing how long it takes to
+ * interate through a string without really doing anything of substance.
+ * @param string $string
+ * @return string
+ * @static
+ */
+ static function placebo( $string ) {
+ $len = strlen( $string );
+ $out = '';
+ for( $i = 0; $i < $len; $i++ ) {
+ $out .= $string{$i};
+ }
+ return $out;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/includes/normal/UtfNormalBench.php b/includes/normal/UtfNormalBench.php
new file mode 100644
index 000000000000..a5eb267e5a16
--- /dev/null
+++ b/includes/normal/UtfNormalBench.php
@@ -0,0 +1,107 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Approximate benchmark for some basic operations.
+ *
+ * @package UtfNormal
+ * @access private
+ */
+
+/** */
+if( isset( $_SERVER['argv'] ) && in_array( '--icu', $_SERVER['argv'] ) ) {
+ dl( 'php_utfnormal.so' );
+}
+
+require_once 'UtfNormalUtil.php';
+require_once 'UtfNormal.php';
+
+define( 'BENCH_CYCLES', 5 );
+
+if( php_sapi_name() != 'cli' ) {
+ die( "Run me from the command line please.\n" );
+}
+
+$testfiles = array(
+ 'testdata/washington.txt' => 'English text',
+ 'testdata/berlin.txt' => 'German text',
+ 'testdata/bulgakov.txt' => 'Russian text',
+ 'testdata/tokyo.txt' => 'Japanese text',
+ 'testdata/sociology.txt' => 'Korean text'
+);
+$normalizer = new UtfNormal;
+UtfNormal::loadData();
+foreach( $testfiles as $file => $desc ) {
+ benchmarkTest( $normalizer, $file, $desc );
+}
+
+# -------
+
+function benchmarkTest( &$u, $filename, $desc ) {
+ print "Testing $filename ($desc)...\n";
+ $data = file_get_contents( $filename );
+ $forms = array(
+# 'placebo',
+ 'cleanUp',
+ 'toNFC',
+# 'toNFKC',
+# 'toNFD', 'toNFKD',
+ 'NFC',
+# 'NFKC',
+# 'NFD', 'NFKD',
+ array( 'fastDecompose', 'fastCombiningSort', 'fastCompose' ),
+# 'quickIsNFC', 'quickIsNFCVerify',
+ );
+ foreach( $forms as $form ) {
+ if( is_array( $form ) ) {
+ $str = $data;
+ foreach( $form as $step ) {
+ $str = benchmarkForm( $u, $str, $step );
+ }
+ } else {
+ benchmarkForm( $u, $data, $form );
+ }
+ }
+}
+
+function benchTime(){
+ $st = explode( ' ', microtime() );
+ return (float)$st[0] + (float)$st[1];
+}
+
+function benchmarkForm( &$u, &$data, $form ) {
+ global $utfCanonicalDecomp;
+ #$start = benchTime();
+ for( $i = 0; $i < BENCH_CYCLES; $i++ ) {
+ $start = benchTime();
+ $out = $u->$form( $data, $utfCanonicalDecomp );
+ $deltas[] = (benchTime() - $start);
+ }
+ #$delta = (benchTime() - $start) / BENCH_CYCLES;
+ sort( $deltas );
+ $delta = $deltas[0]; # Take shortest time
+
+ $rate = intval( strlen( $data ) / $delta );
+ $same = (0 == strcmp( $data, $out ) );
+
+ printf( " %20s %6.1fms %8d bytes/s (%s)\n", $form, $delta*1000.0, $rate, ($same ? 'no change' : 'changed' ) );
+ return $out;
+}
+
+?>
diff --git a/includes/normal/UtfNormalData.inc b/includes/normal/UtfNormalData.inc
new file mode 100644
index 000000000000..6216d1a30139
--- /dev/null
+++ b/includes/normal/UtfNormalData.inc
@@ -0,0 +1,13 @@
+<?php
+/**
+ * This file was automatically generated -- do not edit!
+ * Run UtfNormalGenerate.php to create this file again (make clean && make)
+ * @package MediaWiki
+ */
+/** */
+global $utfCombiningClass, $utfCanonicalComp, $utfCanonicalDecomp, $utfCheckNFC;
+$utfCombiningClass = unserialize( 'a:384:{s:2:"̀";i:230;s:2:"́";i:230;s:2:"̂";i:230;s:2:"̃";i:230;s:2:"̄";i:230;s:2:"̅";i:230;s:2:"̆";i:230;s:2:"̇";i:230;s:2:"̈";i:230;s:2:"̉";i:230;s:2:"̊";i:230;s:2:"̋";i:230;s:2:"̌";i:230;s:2:"̍";i:230;s:2:"̎";i:230;s:2:"̏";i:230;s:2:"̐";i:230;s:2:"̑";i:230;s:2:"̒";i:230;s:2:"̓";i:230;s:2:"̔";i:230;s:2:"̕";i:232;s:2:"̖";i:220;s:2:"̗";i:220;s:2:"̘";i:220;s:2:"̙";i:220;s:2:"̚";i:232;s:2:"̛";i:216;s:2:"̜";i:220;s:2:"̝";i:220;s:2:"̞";i:220;s:2:"̟";i:220;s:2:"̠";i:220;s:2:"̡";i:202;s:2:"̢";i:202;s:2:"̣";i:220;s:2:"̤";i:220;s:2:"̥";i:220;s:2:"̦";i:220;s:2:"̧";i:202;s:2:"̨";i:202;s:2:"̩";i:220;s:2:"̪";i:220;s:2:"̫";i:220;s:2:"̬";i:220;s:2:"̭";i:220;s:2:"̮";i:220;s:2:"̯";i:220;s:2:"̰";i:220;s:2:"̱";i:220;s:2:"̲";i:220;s:2:"̳";i:220;s:2:"̴";i:1;s:2:"̵";i:1;s:2:"̶";i:1;s:2:"̷";i:1;s:2:"̸";i:1;s:2:"̹";i:220;s:2:"̺";i:220;s:2:"̻";i:220;s:2:"̼";i:220;s:2:"̽";i:230;s:2:"̾";i:230;s:2:"̿";i:230;s:2:"̀";i:230;s:2:"́";i:230;s:2:"͂";i:230;s:2:"̓";i:230;s:2:"̈́";i:230;s:2:"ͅ";i:240;s:2:"͆";i:230;s:2:"͇";i:220;s:2:"͈";i:220;s:2:"͉";i:220;s:2:"͊";i:230;s:2:"͋";i:230;s:2:"͌";i:230;s:2:"͍";i:220;s:2:"͎";i:220;s:2:"͐";i:230;s:2:"͑";i:230;s:2:"͒";i:230;s:2:"͓";i:220;s:2:"͔";i:220;s:2:"͕";i:220;s:2:"͖";i:220;s:2:"͗";i:230;s:2:"͘";i:232;s:2:"͙";i:220;s:2:"͚";i:220;s:2:"͛";i:230;s:2:"͜";i:233;s:2:"͝";i:234;s:2:"͞";i:234;s:2:"͟";i:233;s:2:"͠";i:234;s:2:"͡";i:234;s:2:"͢";i:233;s:2:"ͣ";i:230;s:2:"ͤ";i:230;s:2:"ͥ";i:230;s:2:"ͦ";i:230;s:2:"ͧ";i:230;s:2:"ͨ";i:230;s:2:"ͩ";i:230;s:2:"ͪ";i:230;s:2:"ͫ";i:230;s:2:"ͬ";i:230;s:2:"ͭ";i:230;s:2:"ͮ";i:230;s:2:"ͯ";i:230;s:2:"҃";i:230;s:2:"҄";i:230;s:2:"҅";i:230;s:2:"҆";i:230;s:2:"֑";i:220;s:2:"֒";i:230;s:2:"֓";i:230;s:2:"֔";i:230;s:2:"֕";i:230;s:2:"֖";i:220;s:2:"֗";i:230;s:2:"֘";i:230;s:2:"֙";i:230;s:2:"֚";i:222;s:2:"֛";i:220;s:2:"֜";i:230;s:2:"֝";i:230;s:2:"֞";i:230;s:2:"֟";i:230;s:2:"֠";i:230;s:2:"֡";i:230;s:2:"֢";i:220;s:2:"֣";i:220;s:2:"֤";i:220;s:2:"֥";i:220;s:2:"֦";i:220;s:2:"֧";i:220;s:2:"֨";i:230;s:2:"֩";i:230;s:2:"֪";i:220;s:2:"֫";i:230;s:2:"֬";i:230;s:2:"֭";i:222;s:2:"֮";i:228;s:2:"֯";i:230;s:2:"ְ";i:10;s:2:"ֱ";i:11;s:2:"ֲ";i:12;s:2:"ֳ";i:13;s:2:"ִ";i:14;s:2:"ֵ";i:15;s:2:"ֶ";i:16;s:2:"ַ";i:17;s:2:"ָ";i:18;s:2:"ֹ";i:19;s:2:"ֻ";i:20;s:2:"ּ";i:21;s:2:"ֽ";i:22;s:2:"ֿ";i:23;s:2:"ׁ";i:24;s:2:"ׂ";i:25;s:2:"ׄ";i:230;s:2:"ׅ";i:220;s:2:"ׇ";i:18;s:2:"ؐ";i:230;s:2:"ؑ";i:230;s:2:"ؒ";i:230;s:2:"ؓ";i:230;s:2:"ؔ";i:230;s:2:"ؕ";i:230;s:2:"ً";i:27;s:2:"ٌ";i:28;s:2:"ٍ";i:29;s:2:"َ";i:30;s:2:"ُ";i:31;s:2:"ِ";i:32;s:2:"ّ";i:33;s:2:"ْ";i:34;s:2:"ٓ";i:230;s:2:"ٔ";i:230;s:2:"ٕ";i:220;s:2:"ٖ";i:220;s:2:"ٗ";i:230;s:2:"٘";i:230;s:2:"ٙ";i:230;s:2:"ٚ";i:230;s:2:"ٛ";i:230;s:2:"ٜ";i:220;s:2:"ٝ";i:230;s:2:"ٞ";i:230;s:2:"ٰ";i:35;s:2:"ۖ";i:230;s:2:"ۗ";i:230;s:2:"ۘ";i:230;s:2:"ۙ";i:230;s:2:"ۚ";i:230;s:2:"ۛ";i:230;s:2:"ۜ";i:230;s:2:"۟";i:230;s:2:"۠";i:230;s:2:"ۡ";i:230;s:2:"ۢ";i:230;s:2:"ۣ";i:220;s:2:"ۤ";i:230;s:2:"ۧ";i:230;s:2:"ۨ";i:230;s:2:"۪";i:220;s:2:"۫";i:230;s:2:"۬";i:230;s:2:"ۭ";i:220;s:2:"ܑ";i:36;s:2:"ܰ";i:230;s:2:"ܱ";i:220;s:2:"ܲ";i:230;s:2:"ܳ";i:230;s:2:"ܴ";i:220;s:2:"ܵ";i:230;s:2:"ܶ";i:230;s:2:"ܷ";i:220;s:2:"ܸ";i:220;s:2:"ܹ";i:220;s:2:"ܺ";i:230;s:2:"ܻ";i:220;s:2:"ܼ";i:220;s:2:"ܽ";i:230;s:2:"ܾ";i:220;s:2:"ܿ";i:230;s:2:"݀";i:230;s:2:"݁";i:230;s:2:"݂";i:220;s:2:"݃";i:230;s:2:"݄";i:220;s:2:"݅";i:230;s:2:"݆";i:220;s:2:"݇";i:230;s:2:"݈";i:220;s:2:"݉";i:230;s:2:"݊";i:230;s:3:"़";i:7;s:3:"्";i:9;s:3:"॑";i:230;s:3:"॒";i:220;s:3:"॓";i:230;s:3:"॔";i:230;s:3:"়";i:7;s:3:"্";i:9;s:3:"਼";i:7;s:3:"੍";i:9;s:3:"઼";i:7;s:3:"્";i:9;s:3:"଼";i:7;s:3:"୍";i:9;s:3:"்";i:9;s:3:"్";i:9;s:3:"ౕ";i:84;s:3:"ౖ";i:91;s:3:"಼";i:7;s:3:"್";i:9;s:3:"്";i:9;s:3:"්";i:9;s:3:"ุ";i:103;s:3:"ู";i:103;s:3:"ฺ";i:9;s:3:"่";i:107;s:3:"้";i:107;s:3:"๊";i:107;s:3:"๋";i:107;s:3:"ຸ";i:118;s:3:"ູ";i:118;s:3:"່";i:122;s:3:"້";i:122;s:3:"໊";i:122;s:3:"໋";i:122;s:3:"༘";i:220;s:3:"༙";i:220;s:3:"༵";i:220;s:3:"༷";i:220;s:3:"༹";i:216;s:3:"ཱ";i:129;s:3:"ི";i:130;s:3:"ུ";i:132;s:3:"ེ";i:130;s:3:"ཻ";i:130;s:3:"ོ";i:130;s:3:"ཽ";i:130;s:3:"ྀ";i:130;s:3:"ྂ";i:230;s:3:"ྃ";i:230;s:3:"྄";i:9;s:3:"྆";i:230;s:3:"྇";i:230;s:3:"࿆";i:220;s:3:"့";i:7;s:3:"္";i:9;s:3:"፟";i:230;s:3:"᜔";i:9;s:3:"᜴";i:9;s:3:"្";i:9;s:3:"៝";i:230;s:3:"ᢩ";i:228;s:3:"᤹";i:222;s:3:"᤺";i:230;s:3:"᤻";i:220;s:3:"ᨗ";i:230;s:3:"ᨘ";i:220;s:3:"᷀";i:230;s:3:"᷁";i:230;s:3:"᷂";i:220;s:3:"᷃";i:230;s:3:"⃐";i:230;s:3:"⃑";i:230;s:3:"⃒";i:1;s:3:"⃓";i:1;s:3:"⃔";i:230;s:3:"⃕";i:230;s:3:"⃖";i:230;s:3:"⃗";i:230;s:3:"⃘";i:1;s:3:"⃙";i:1;s:3:"⃚";i:1;s:3:"⃛";i:230;s:3:"⃜";i:230;s:3:"⃡";i:230;s:3:"⃥";i:1;s:3:"⃦";i:1;s:3:"⃧";i:230;s:3:"⃨";i:220;s:3:"⃩";i:230;s:3:"⃪";i:1;s:3:"⃫";i:1;s:3:"〪";i:218;s:3:"〫";i:228;s:3:"〬";i:232;s:3:"〭";i:222;s:3:"〮";i:224;s:3:"〯";i:224;s:3:"゙";i:8;s:3:"゚";i:8;s:3:"꠆";i:9;s:3:"ﬞ";i:26;s:3:"︠";i:230;s:3:"︡";i:230;s:3:"︢";i:230;s:3:"︣";i:230;s:4:"𐨍";i:220;s:4:"𐨏";i:230;s:4:"𐨸";i:230;s:4:"𐨹";i:1;s:4:"𐨺";i:220;s:4:"𐨿";i:9;s:4:"𝅥";i:216;s:4:"𝅦";i:216;s:4:"𝅧";i:1;s:4:"𝅨";i:1;s:4:"𝅩";i:1;s:4:"𝅭";i:226;s:4:"𝅮";i:216;s:4:"𝅯";i:216;s:4:"𝅰";i:216;s:4:"𝅱";i:216;s:4:"𝅲";i:216;s:4:"𝅻";i:220;s:4:"𝅼";i:220;s:4:"𝅽";i:220;s:4:"𝅾";i:220;s:4:"𝅿";i:220;s:4:"𝆀";i:220;s:4:"𝆁";i:220;s:4:"𝆂";i:220;s:4:"𝆅";i:230;s:4:"𝆆";i:230;s:4:"𝆇";i:230;s:4:"𝆈";i:230;s:4:"𝆉";i:230;s:4:"𝆊";i:220;s:4:"𝆋";i:220;s:4:"𝆪";i:230;s:4:"𝆫";i:230;s:4:"𝆬";i:230;s:4:"𝆭";i:230;s:4:"𝉂";i:230;s:4:"𝉃";i:230;s:4:"𝉄";i:230;}' );
+$utfCanonicalComp = unserialize( 'a:1851:{s:3:"À";s:2:"À";s:3:"Á";s:2:"Á";s:3:"Â";s:2:"Â";s:3:"Ã";s:2:"Ã";s:3:"Ä";s:2:"Ä";s:3:"Å";s:2:"Å";s:3:"Ç";s:2:"Ç";s:3:"È";s:2:"È";s:3:"É";s:2:"É";s:3:"Ê";s:2:"Ê";s:3:"Ë";s:2:"Ë";s:3:"Ì";s:2:"Ì";s:3:"Í";s:2:"Í";s:3:"Î";s:2:"Î";s:3:"Ï";s:2:"Ï";s:3:"Ñ";s:2:"Ñ";s:3:"Ò";s:2:"Ò";s:3:"Ó";s:2:"Ó";s:3:"Ô";s:2:"Ô";s:3:"Õ";s:2:"Õ";s:3:"Ö";s:2:"Ö";s:3:"Ù";s:2:"Ù";s:3:"Ú";s:2:"Ú";s:3:"Û";s:2:"Û";s:3:"Ü";s:2:"Ü";s:3:"Ý";s:2:"Ý";s:3:"à";s:2:"à";s:3:"á";s:2:"á";s:3:"â";s:2:"â";s:3:"ã";s:2:"ã";s:3:"ä";s:2:"ä";s:3:"å";s:2:"å";s:3:"ç";s:2:"ç";s:3:"è";s:2:"è";s:3:"é";s:2:"é";s:3:"ê";s:2:"ê";s:3:"ë";s:2:"ë";s:3:"ì";s:2:"ì";s:3:"í";s:2:"í";s:3:"î";s:2:"î";s:3:"ï";s:2:"ï";s:3:"ñ";s:2:"ñ";s:3:"ò";s:2:"ò";s:3:"ó";s:2:"ó";s:3:"ô";s:2:"ô";s:3:"õ";s:2:"õ";s:3:"ö";s:2:"ö";s:3:"ù";s:2:"ù";s:3:"ú";s:2:"ú";s:3:"û";s:2:"û";s:3:"ü";s:2:"ü";s:3:"ý";s:2:"ý";s:3:"ÿ";s:2:"ÿ";s:3:"Ā";s:2:"Ā";s:3:"ā";s:2:"ā";s:3:"Ă";s:2:"Ă";s:3:"ă";s:2:"ă";s:3:"Ą";s:2:"Ą";s:3:"ą";s:2:"ą";s:3:"Ć";s:2:"Ć";s:3:"ć";s:2:"ć";s:3:"Ĉ";s:2:"Ĉ";s:3:"ĉ";s:2:"ĉ";s:3:"Ċ";s:2:"Ċ";s:3:"ċ";s:2:"ċ";s:3:"Č";s:2:"Č";s:3:"č";s:2:"č";s:3:"Ď";s:2:"Ď";s:3:"ď";s:2:"ď";s:3:"Ē";s:2:"Ē";s:3:"ē";s:2:"ē";s:3:"Ĕ";s:2:"Ĕ";s:3:"ĕ";s:2:"ĕ";s:3:"Ė";s:2:"Ė";s:3:"ė";s:2:"ė";s:3:"Ę";s:2:"Ę";s:3:"ę";s:2:"ę";s:3:"Ě";s:2:"Ě";s:3:"ě";s:2:"ě";s:3:"Ĝ";s:2:"Ĝ";s:3:"ĝ";s:2:"ĝ";s:3:"Ğ";s:2:"Ğ";s:3:"ğ";s:2:"ğ";s:3:"Ġ";s:2:"Ġ";s:3:"ġ";s:2:"ġ";s:3:"Ģ";s:2:"Ģ";s:3:"ģ";s:2:"ģ";s:3:"Ĥ";s:2:"Ĥ";s:3:"ĥ";s:2:"ĥ";s:3:"Ĩ";s:2:"Ĩ";s:3:"ĩ";s:2:"ĩ";s:3:"Ī";s:2:"Ī";s:3:"ī";s:2:"ī";s:3:"Ĭ";s:2:"Ĭ";s:3:"ĭ";s:2:"ĭ";s:3:"Į";s:2:"Į";s:3:"į";s:2:"į";s:3:"İ";s:2:"İ";s:3:"Ĵ";s:2:"Ĵ";s:3:"ĵ";s:2:"ĵ";s:3:"Ķ";s:2:"Ķ";s:3:"ķ";s:2:"ķ";s:3:"Ĺ";s:2:"Ĺ";s:3:"ĺ";s:2:"ĺ";s:3:"Ļ";s:2:"Ļ";s:3:"ļ";s:2:"ļ";s:3:"Ľ";s:2:"Ľ";s:3:"ľ";s:2:"ľ";s:3:"Ń";s:2:"Ń";s:3:"ń";s:2:"ń";s:3:"Ņ";s:2:"Ņ";s:3:"ņ";s:2:"ņ";s:3:"Ň";s:2:"Ň";s:3:"ň";s:2:"ň";s:3:"Ō";s:2:"Ō";s:3:"ō";s:2:"ō";s:3:"Ŏ";s:2:"Ŏ";s:3:"ŏ";s:2:"ŏ";s:3:"Ő";s:2:"Ő";s:3:"ő";s:2:"ő";s:3:"Ŕ";s:2:"Ŕ";s:3:"ŕ";s:2:"ŕ";s:3:"Ŗ";s:2:"Ŗ";s:3:"ŗ";s:2:"ŗ";s:3:"Ř";s:2:"Ř";s:3:"ř";s:2:"ř";s:3:"Ś";s:2:"Ś";s:3:"ś";s:2:"ś";s:3:"Ŝ";s:2:"Ŝ";s:3:"ŝ";s:2:"ŝ";s:3:"Ş";s:2:"Ş";s:3:"ş";s:2:"ş";s:3:"Š";s:2:"Š";s:3:"š";s:2:"š";s:3:"Ţ";s:2:"Ţ";s:3:"ţ";s:2:"ţ";s:3:"Ť";s:2:"Ť";s:3:"ť";s:2:"ť";s:3:"Ũ";s:2:"Ũ";s:3:"ũ";s:2:"ũ";s:3:"Ū";s:2:"Ū";s:3:"ū";s:2:"ū";s:3:"Ŭ";s:2:"Ŭ";s:3:"ŭ";s:2:"ŭ";s:3:"Ů";s:2:"Ů";s:3:"ů";s:2:"ů";s:3:"Ű";s:2:"Ű";s:3:"ű";s:2:"ű";s:3:"Ų";s:2:"Ų";s:3:"ų";s:2:"ų";s:3:"Ŵ";s:2:"Ŵ";s:3:"ŵ";s:2:"ŵ";s:3:"Ŷ";s:2:"Ŷ";s:3:"ŷ";s:2:"ŷ";s:3:"Ÿ";s:2:"Ÿ";s:3:"Ź";s:2:"Ź";s:3:"ź";s:2:"ź";s:3:"Ż";s:2:"Ż";s:3:"ż";s:2:"ż";s:3:"Ž";s:2:"Ž";s:3:"ž";s:2:"ž";s:3:"Ơ";s:2:"Ơ";s:3:"ơ";s:2:"ơ";s:3:"Ư";s:2:"Ư";s:3:"ư";s:2:"ư";s:3:"Ǎ";s:2:"Ǎ";s:3:"ǎ";s:2:"ǎ";s:3:"Ǐ";s:2:"Ǐ";s:3:"ǐ";s:2:"ǐ";s:3:"Ǒ";s:2:"Ǒ";s:3:"ǒ";s:2:"ǒ";s:3:"Ǔ";s:2:"Ǔ";s:3:"ǔ";s:2:"ǔ";s:4:"Ǖ";s:2:"Ǖ";s:4:"ǖ";s:2:"ǖ";s:4:"Ǘ";s:2:"Ǘ";s:4:"ǘ";s:2:"ǘ";s:4:"Ǚ";s:2:"Ǚ";s:4:"ǚ";s:2:"ǚ";s:4:"Ǜ";s:2:"Ǜ";s:4:"ǜ";s:2:"ǜ";s:4:"Ǟ";s:2:"Ǟ";s:4:"ǟ";s:2:"ǟ";s:4:"Ǡ";s:2:"Ǡ";s:4:"ǡ";s:2:"ǡ";s:4:"Ǣ";s:2:"Ǣ";s:4:"ǣ";s:2:"ǣ";s:3:"Ǧ";s:2:"Ǧ";s:3:"ǧ";s:2:"ǧ";s:3:"Ǩ";s:2:"Ǩ";s:3:"ǩ";s:2:"ǩ";s:3:"Ǫ";s:2:"Ǫ";s:3:"ǫ";s:2:"ǫ";s:4:"Ǭ";s:2:"Ǭ";s:4:"ǭ";s:2:"ǭ";s:4:"Ǯ";s:2:"Ǯ";s:4:"ǯ";s:2:"ǯ";s:3:"ǰ";s:2:"ǰ";s:3:"Ǵ";s:2:"Ǵ";s:3:"ǵ";s:2:"ǵ";s:3:"Ǹ";s:2:"Ǹ";s:3:"ǹ";s:2:"ǹ";s:4:"Ǻ";s:2:"Ǻ";s:4:"ǻ";s:2:"ǻ";s:4:"Ǽ";s:2:"Ǽ";s:4:"ǽ";s:2:"ǽ";s:4:"Ǿ";s:2:"Ǿ";s:4:"ǿ";s:2:"ǿ";s:3:"Ȁ";s:2:"Ȁ";s:3:"ȁ";s:2:"ȁ";s:3:"Ȃ";s:2:"Ȃ";s:3:"ȃ";s:2:"ȃ";s:3:"Ȅ";s:2:"Ȅ";s:3:"ȅ";s:2:"ȅ";s:3:"Ȇ";s:2:"Ȇ";s:3:"ȇ";s:2:"ȇ";s:3:"Ȉ";s:2:"Ȉ";s:3:"ȉ";s:2:"ȉ";s:3:"Ȋ";s:2:"Ȋ";s:3:"ȋ";s:2:"ȋ";s:3:"Ȍ";s:2:"Ȍ";s:3:"ȍ";s:2:"ȍ";s:3:"Ȏ";s:2:"Ȏ";s:3:"ȏ";s:2:"ȏ";s:3:"Ȑ";s:2:"Ȑ";s:3:"ȑ";s:2:"ȑ";s:3:"Ȓ";s:2:"Ȓ";s:3:"ȓ";s:2:"ȓ";s:3:"Ȕ";s:2:"Ȕ";s:3:"ȕ";s:2:"ȕ";s:3:"Ȗ";s:2:"Ȗ";s:3:"ȗ";s:2:"ȗ";s:3:"Ș";s:2:"Ș";s:3:"ș";s:2:"ș";s:3:"Ț";s:2:"Ț";s:3:"ț";s:2:"ț";s:3:"Ȟ";s:2:"Ȟ";s:3:"ȟ";s:2:"ȟ";s:3:"Ȧ";s:2:"Ȧ";s:3:"ȧ";s:2:"ȧ";s:3:"Ȩ";s:2:"Ȩ";s:3:"ȩ";s:2:"ȩ";s:4:"Ȫ";s:2:"Ȫ";s:4:"ȫ";s:2:"ȫ";s:4:"Ȭ";s:2:"Ȭ";s:4:"ȭ";s:2:"ȭ";s:3:"Ȯ";s:2:"Ȯ";s:3:"ȯ";s:2:"ȯ";s:4:"Ȱ";s:2:"Ȱ";s:4:"ȱ";s:2:"ȱ";s:3:"Ȳ";s:2:"Ȳ";s:3:"ȳ";s:2:"ȳ";s:2:"̀";s:2:"̀";s:2:"́";s:2:"́";s:2:"̓";s:2:"̓";s:4:"̈́";s:2:"̈́";s:2:"ʹ";s:2:"ʹ";s:1:";";s:2:";";s:4:"΅";s:2:"΅";s:4:"Ά";s:2:"Ά";s:2:"·";s:2:"·";s:4:"Έ";s:2:"Έ";s:4:"Ή";s:2:"Ή";s:4:"Ί";s:2:"Ί";s:4:"Ό";s:2:"Ό";s:4:"Ύ";s:2:"Ύ";s:4:"Ώ";s:2:"Ώ";s:4:"ΐ";s:2:"ΐ";s:4:"Ϊ";s:2:"Ϊ";s:4:"Ϋ";s:2:"Ϋ";s:4:"ά";s:2:"ά";s:4:"έ";s:2:"έ";s:4:"ή";s:2:"ή";s:4:"ί";s:2:"ί";s:4:"ΰ";s:2:"ΰ";s:4:"ϊ";s:2:"ϊ";s:4:"ϋ";s:2:"ϋ";s:4:"ό";s:2:"ό";s:4:"ύ";s:2:"ύ";s:4:"ώ";s:2:"ώ";s:4:"ϓ";s:2:"ϓ";s:4:"ϔ";s:2:"ϔ";s:4:"Ѐ";s:2:"Ѐ";s:4:"Ё";s:2:"Ё";s:4:"Ѓ";s:2:"Ѓ";s:4:"Ї";s:2:"Ї";s:4:"Ќ";s:2:"Ќ";s:4:"Ѝ";s:2:"Ѝ";s:4:"Ў";s:2:"Ў";s:4:"Й";s:2:"Й";s:4:"й";s:2:"й";s:4:"ѐ";s:2:"ѐ";s:4:"ё";s:2:"ё";s:4:"ѓ";s:2:"ѓ";s:4:"ї";s:2:"ї";s:4:"ќ";s:2:"ќ";s:4:"ѝ";s:2:"ѝ";s:4:"ў";s:2:"ў";s:4:"Ѷ";s:2:"Ѷ";s:4:"ѷ";s:2:"ѷ";s:4:"Ӂ";s:2:"Ӂ";s:4:"ӂ";s:2:"ӂ";s:4:"Ӑ";s:2:"Ӑ";s:4:"ӑ";s:2:"ӑ";s:4:"Ӓ";s:2:"Ӓ";s:4:"ӓ";s:2:"ӓ";s:4:"Ӗ";s:2:"Ӗ";s:4:"ӗ";s:2:"ӗ";s:4:"Ӛ";s:2:"Ӛ";s:4:"ӛ";s:2:"ӛ";s:4:"Ӝ";s:2:"Ӝ";s:4:"ӝ";s:2:"ӝ";s:4:"Ӟ";s:2:"Ӟ";s:4:"ӟ";s:2:"ӟ";s:4:"Ӣ";s:2:"Ӣ";s:4:"ӣ";s:2:"ӣ";s:4:"Ӥ";s:2:"Ӥ";s:4:"ӥ";s:2:"ӥ";s:4:"Ӧ";s:2:"Ӧ";s:4:"ӧ";s:2:"ӧ";s:4:"Ӫ";s:2:"Ӫ";s:4:"ӫ";s:2:"ӫ";s:4:"Ӭ";s:2:"Ӭ";s:4:"ӭ";s:2:"ӭ";s:4:"Ӯ";s:2:"Ӯ";s:4:"ӯ";s:2:"ӯ";s:4:"Ӱ";s:2:"Ӱ";s:4:"ӱ";s:2:"ӱ";s:4:"Ӳ";s:2:"Ӳ";s:4:"ӳ";s:2:"ӳ";s:4:"Ӵ";s:2:"Ӵ";s:4:"ӵ";s:2:"ӵ";s:4:"Ӹ";s:2:"Ӹ";s:4:"ӹ";s:2:"ӹ";s:4:"آ";s:2:"آ";s:4:"أ";s:2:"أ";s:4:"ؤ";s:2:"ؤ";s:4:"إ";s:2:"إ";s:4:"ئ";s:2:"ئ";s:4:"ۀ";s:2:"ۀ";s:4:"ۂ";s:2:"ۂ";s:4:"ۓ";s:2:"ۓ";s:6:"ऩ";s:3:"ऩ";s:6:"ऱ";s:3:"ऱ";s:6:"ऴ";s:3:"ऴ";s:6:"ো";s:3:"ো";s:6:"ৌ";s:3:"ৌ";s:6:"ୈ";s:3:"ୈ";s:6:"ୋ";s:3:"ୋ";s:6:"ୌ";s:3:"ୌ";s:6:"ஔ";s:3:"ஔ";s:6:"ொ";s:3:"ொ";s:6:"ோ";s:3:"ோ";s:6:"ௌ";s:3:"ௌ";s:6:"ై";s:3:"ై";s:6:"ೀ";s:3:"ೀ";s:6:"ೇ";s:3:"ೇ";s:6:"ೈ";s:3:"ೈ";s:6:"ೊ";s:3:"ೊ";s:6:"ೋ";s:3:"ೋ";s:6:"ൊ";s:3:"ൊ";s:6:"ോ";s:3:"ോ";s:6:"ൌ";s:3:"ൌ";s:6:"ේ";s:3:"ේ";s:6:"ො";s:3:"ො";s:6:"ෝ";s:3:"ෝ";s:6:"ෞ";s:3:"ෞ";s:6:"ཱི";s:3:"ཱི";s:6:"ཱུ";s:3:"ཱུ";s:6:"ཱྀ";s:3:"ཱྀ";s:6:"ဦ";s:3:"ဦ";s:3:"Ḁ";s:3:"Ḁ";s:3:"ḁ";s:3:"ḁ";s:3:"Ḃ";s:3:"Ḃ";s:3:"ḃ";s:3:"ḃ";s:3:"Ḅ";s:3:"Ḅ";s:3:"ḅ";s:3:"ḅ";s:3:"Ḇ";s:3:"Ḇ";s:3:"ḇ";s:3:"ḇ";s:4:"Ḉ";s:3:"Ḉ";s:4:"ḉ";s:3:"ḉ";s:3:"Ḋ";s:3:"Ḋ";s:3:"ḋ";s:3:"ḋ";s:3:"Ḍ";s:3:"Ḍ";s:3:"ḍ";s:3:"ḍ";s:3:"Ḏ";s:3:"Ḏ";s:3:"ḏ";s:3:"ḏ";s:3:"Ḑ";s:3:"Ḑ";s:3:"ḑ";s:3:"ḑ";s:3:"Ḓ";s:3:"Ḓ";s:3:"ḓ";s:3:"ḓ";s:4:"Ḕ";s:3:"Ḕ";s:4:"ḕ";s:3:"ḕ";s:4:"Ḗ";s:3:"Ḗ";s:4:"ḗ";s:3:"ḗ";s:3:"Ḙ";s:3:"Ḙ";s:3:"ḙ";s:3:"ḙ";s:3:"Ḛ";s:3:"Ḛ";s:3:"ḛ";s:3:"ḛ";s:4:"Ḝ";s:3:"Ḝ";s:4:"ḝ";s:3:"ḝ";s:3:"Ḟ";s:3:"Ḟ";s:3:"ḟ";s:3:"ḟ";s:3:"Ḡ";s:3:"Ḡ";s:3:"ḡ";s:3:"ḡ";s:3:"Ḣ";s:3:"Ḣ";s:3:"ḣ";s:3:"ḣ";s:3:"Ḥ";s:3:"Ḥ";s:3:"ḥ";s:3:"ḥ";s:3:"Ḧ";s:3:"Ḧ";s:3:"ḧ";s:3:"ḧ";s:3:"Ḩ";s:3:"Ḩ";s:3:"ḩ";s:3:"ḩ";s:3:"Ḫ";s:3:"Ḫ";s:3:"ḫ";s:3:"ḫ";s:3:"Ḭ";s:3:"Ḭ";s:3:"ḭ";s:3:"ḭ";s:4:"Ḯ";s:3:"Ḯ";s:4:"ḯ";s:3:"ḯ";s:3:"Ḱ";s:3:"Ḱ";s:3:"ḱ";s:3:"ḱ";s:3:"Ḳ";s:3:"Ḳ";s:3:"ḳ";s:3:"ḳ";s:3:"Ḵ";s:3:"Ḵ";s:3:"ḵ";s:3:"ḵ";s:3:"Ḷ";s:3:"Ḷ";s:3:"ḷ";s:3:"ḷ";s:5:"Ḹ";s:3:"Ḹ";s:5:"ḹ";s:3:"ḹ";s:3:"Ḻ";s:3:"Ḻ";s:3:"ḻ";s:3:"ḻ";s:3:"Ḽ";s:3:"Ḽ";s:3:"ḽ";s:3:"ḽ";s:3:"Ḿ";s:3:"Ḿ";s:3:"ḿ";s:3:"ḿ";s:3:"Ṁ";s:3:"Ṁ";s:3:"ṁ";s:3:"ṁ";s:3:"Ṃ";s:3:"Ṃ";s:3:"ṃ";s:3:"ṃ";s:3:"Ṅ";s:3:"Ṅ";s:3:"ṅ";s:3:"ṅ";s:3:"Ṇ";s:3:"Ṇ";s:3:"ṇ";s:3:"ṇ";s:3:"Ṉ";s:3:"Ṉ";s:3:"ṉ";s:3:"ṉ";s:3:"Ṋ";s:3:"Ṋ";s:3:"ṋ";s:3:"ṋ";s:4:"Ṍ";s:3:"Ṍ";s:4:"ṍ";s:3:"ṍ";s:4:"Ṏ";s:3:"Ṏ";s:4:"ṏ";s:3:"ṏ";s:4:"Ṑ";s:3:"Ṑ";s:4:"ṑ";s:3:"ṑ";s:4:"Ṓ";s:3:"Ṓ";s:4:"ṓ";s:3:"ṓ";s:3:"Ṕ";s:3:"Ṕ";s:3:"ṕ";s:3:"ṕ";s:3:"Ṗ";s:3:"Ṗ";s:3:"ṗ";s:3:"ṗ";s:3:"Ṙ";s:3:"Ṙ";s:3:"ṙ";s:3:"ṙ";s:3:"Ṛ";s:3:"Ṛ";s:3:"ṛ";s:3:"ṛ";s:5:"Ṝ";s:3:"Ṝ";s:5:"ṝ";s:3:"ṝ";s:3:"Ṟ";s:3:"Ṟ";s:3:"ṟ";s:3:"ṟ";s:3:"Ṡ";s:3:"Ṡ";s:3:"ṡ";s:3:"ṡ";s:3:"Ṣ";s:3:"Ṣ";s:3:"ṣ";s:3:"ṣ";s:4:"Ṥ";s:3:"Ṥ";s:4:"ṥ";s:3:"ṥ";s:4:"Ṧ";s:3:"Ṧ";s:4:"ṧ";s:3:"ṧ";s:5:"Ṩ";s:3:"Ṩ";s:5:"ṩ";s:3:"ṩ";s:3:"Ṫ";s:3:"Ṫ";s:3:"ṫ";s:3:"ṫ";s:3:"Ṭ";s:3:"Ṭ";s:3:"ṭ";s:3:"ṭ";s:3:"Ṯ";s:3:"Ṯ";s:3:"ṯ";s:3:"ṯ";s:3:"Ṱ";s:3:"Ṱ";s:3:"ṱ";s:3:"ṱ";s:3:"Ṳ";s:3:"Ṳ";s:3:"ṳ";s:3:"ṳ";s:3:"Ṵ";s:3:"Ṵ";s:3:"ṵ";s:3:"ṵ";s:3:"Ṷ";s:3:"Ṷ";s:3:"ṷ";s:3:"ṷ";s:4:"Ṹ";s:3:"Ṹ";s:4:"ṹ";s:3:"ṹ";s:4:"Ṻ";s:3:"Ṻ";s:4:"ṻ";s:3:"ṻ";s:3:"Ṽ";s:3:"Ṽ";s:3:"ṽ";s:3:"ṽ";s:3:"Ṿ";s:3:"Ṿ";s:3:"ṿ";s:3:"ṿ";s:3:"Ẁ";s:3:"Ẁ";s:3:"ẁ";s:3:"ẁ";s:3:"Ẃ";s:3:"Ẃ";s:3:"ẃ";s:3:"ẃ";s:3:"Ẅ";s:3:"Ẅ";s:3:"ẅ";s:3:"ẅ";s:3:"Ẇ";s:3:"Ẇ";s:3:"ẇ";s:3:"ẇ";s:3:"Ẉ";s:3:"Ẉ";s:3:"ẉ";s:3:"ẉ";s:3:"Ẋ";s:3:"Ẋ";s:3:"ẋ";s:3:"ẋ";s:3:"Ẍ";s:3:"Ẍ";s:3:"ẍ";s:3:"ẍ";s:3:"Ẏ";s:3:"Ẏ";s:3:"ẏ";s:3:"ẏ";s:3:"Ẑ";s:3:"Ẑ";s:3:"ẑ";s:3:"ẑ";s:3:"Ẓ";s:3:"Ẓ";s:3:"ẓ";s:3:"ẓ";s:3:"Ẕ";s:3:"Ẕ";s:3:"ẕ";s:3:"ẕ";s:3:"ẖ";s:3:"ẖ";s:3:"ẗ";s:3:"ẗ";s:3:"ẘ";s:3:"ẘ";s:3:"ẙ";s:3:"ẙ";s:4:"ẛ";s:3:"ẛ";s:3:"Ạ";s:3:"Ạ";s:3:"ạ";s:3:"ạ";s:3:"Ả";s:3:"Ả";s:3:"ả";s:3:"ả";s:4:"Ấ";s:3:"Ấ";s:4:"ấ";s:3:"ấ";s:4:"Ầ";s:3:"Ầ";s:4:"ầ";s:3:"ầ";s:4:"Ẩ";s:3:"Ẩ";s:4:"ẩ";s:3:"ẩ";s:4:"Ẫ";s:3:"Ẫ";s:4:"ẫ";s:3:"ẫ";s:5:"Ậ";s:3:"Ậ";s:5:"ậ";s:3:"ậ";s:4:"Ắ";s:3:"Ắ";s:4:"ắ";s:3:"ắ";s:4:"Ằ";s:3:"Ằ";s:4:"ằ";s:3:"ằ";s:4:"Ẳ";s:3:"Ẳ";s:4:"ẳ";s:3:"ẳ";s:4:"Ẵ";s:3:"Ẵ";s:4:"ẵ";s:3:"ẵ";s:5:"Ặ";s:3:"Ặ";s:5:"ặ";s:3:"ặ";s:3:"Ẹ";s:3:"Ẹ";s:3:"ẹ";s:3:"ẹ";s:3:"Ẻ";s:3:"Ẻ";s:3:"ẻ";s:3:"ẻ";s:3:"Ẽ";s:3:"Ẽ";s:3:"ẽ";s:3:"ẽ";s:4:"Ế";s:3:"Ế";s:4:"ế";s:3:"ế";s:4:"Ề";s:3:"Ề";s:4:"ề";s:3:"ề";s:4:"Ể";s:3:"Ể";s:4:"ể";s:3:"ể";s:4:"Ễ";s:3:"Ễ";s:4:"ễ";s:3:"ễ";s:5:"Ệ";s:3:"Ệ";s:5:"ệ";s:3:"ệ";s:3:"Ỉ";s:3:"Ỉ";s:3:"ỉ";s:3:"ỉ";s:3:"Ị";s:3:"Ị";s:3:"ị";s:3:"ị";s:3:"Ọ";s:3:"Ọ";s:3:"ọ";s:3:"ọ";s:3:"Ỏ";s:3:"Ỏ";s:3:"ỏ";s:3:"ỏ";s:4:"Ố";s:3:"Ố";s:4:"ố";s:3:"ố";s:4:"Ồ";s:3:"Ồ";s:4:"ồ";s:3:"ồ";s:4:"Ổ";s:3:"Ổ";s:4:"ổ";s:3:"ổ";s:4:"Ỗ";s:3:"Ỗ";s:4:"ỗ";s:3:"ỗ";s:5:"Ộ";s:3:"Ộ";s:5:"ộ";s:3:"ộ";s:4:"Ớ";s:3:"Ớ";s:4:"ớ";s:3:"ớ";s:4:"Ờ";s:3:"Ờ";s:4:"ờ";s:3:"ờ";s:4:"Ở";s:3:"Ở";s:4:"ở";s:3:"ở";s:4:"Ỡ";s:3:"Ỡ";s:4:"ỡ";s:3:"ỡ";s:4:"Ợ";s:3:"Ợ";s:4:"ợ";s:3:"ợ";s:3:"Ụ";s:3:"Ụ";s:3:"ụ";s:3:"ụ";s:3:"Ủ";s:3:"Ủ";s:3:"ủ";s:3:"ủ";s:4:"Ứ";s:3:"Ứ";s:4:"ứ";s:3:"ứ";s:4:"Ừ";s:3:"Ừ";s:4:"ừ";s:3:"ừ";s:4:"Ử";s:3:"Ử";s:4:"ử";s:3:"ử";s:4:"Ữ";s:3:"Ữ";s:4:"ữ";s:3:"ữ";s:4:"Ự";s:3:"Ự";s:4:"ự";s:3:"ự";s:3:"Ỳ";s:3:"Ỳ";s:3:"ỳ";s:3:"ỳ";s:3:"Ỵ";s:3:"Ỵ";s:3:"ỵ";s:3:"ỵ";s:3:"Ỷ";s:3:"Ỷ";s:3:"ỷ";s:3:"ỷ";s:3:"Ỹ";s:3:"Ỹ";s:3:"ỹ";s:3:"ỹ";s:4:"ἀ";s:3:"ἀ";s:4:"ἁ";s:3:"ἁ";s:5:"ἂ";s:3:"ἂ";s:5:"ἃ";s:3:"ἃ";s:5:"ἄ";s:3:"ἄ";s:5:"ἅ";s:3:"ἅ";s:5:"ἆ";s:3:"ἆ";s:5:"ἇ";s:3:"ἇ";s:4:"Ἀ";s:3:"Ἀ";s:4:"Ἁ";s:3:"Ἁ";s:5:"Ἂ";s:3:"Ἂ";s:5:"Ἃ";s:3:"Ἃ";s:5:"Ἄ";s:3:"Ἄ";s:5:"Ἅ";s:3:"Ἅ";s:5:"Ἆ";s:3:"Ἆ";s:5:"Ἇ";s:3:"Ἇ";s:4:"ἐ";s:3:"ἐ";s:4:"ἑ";s:3:"ἑ";s:5:"ἒ";s:3:"ἒ";s:5:"ἓ";s:3:"ἓ";s:5:"ἔ";s:3:"ἔ";s:5:"ἕ";s:3:"ἕ";s:4:"Ἐ";s:3:"Ἐ";s:4:"Ἑ";s:3:"Ἑ";s:5:"Ἒ";s:3:"Ἒ";s:5:"Ἓ";s:3:"Ἓ";s:5:"Ἔ";s:3:"Ἔ";s:5:"Ἕ";s:3:"Ἕ";s:4:"ἠ";s:3:"ἠ";s:4:"ἡ";s:3:"ἡ";s:5:"ἢ";s:3:"ἢ";s:5:"ἣ";s:3:"ἣ";s:5:"ἤ";s:3:"ἤ";s:5:"ἥ";s:3:"ἥ";s:5:"ἦ";s:3:"ἦ";s:5:"ἧ";s:3:"ἧ";s:4:"Ἠ";s:3:"Ἠ";s:4:"Ἡ";s:3:"Ἡ";s:5:"Ἢ";s:3:"Ἢ";s:5:"Ἣ";s:3:"Ἣ";s:5:"Ἤ";s:3:"Ἤ";s:5:"Ἥ";s:3:"Ἥ";s:5:"Ἦ";s:3:"Ἦ";s:5:"Ἧ";s:3:"Ἧ";s:4:"ἰ";s:3:"ἰ";s:4:"ἱ";s:3:"ἱ";s:5:"ἲ";s:3:"ἲ";s:5:"ἳ";s:3:"ἳ";s:5:"ἴ";s:3:"ἴ";s:5:"ἵ";s:3:"ἵ";s:5:"ἶ";s:3:"ἶ";s:5:"ἷ";s:3:"ἷ";s:4:"Ἰ";s:3:"Ἰ";s:4:"Ἱ";s:3:"Ἱ";s:5:"Ἲ";s:3:"Ἲ";s:5:"Ἳ";s:3:"Ἳ";s:5:"Ἴ";s:3:"Ἴ";s:5:"Ἵ";s:3:"Ἵ";s:5:"Ἶ";s:3:"Ἶ";s:5:"Ἷ";s:3:"Ἷ";s:4:"ὀ";s:3:"ὀ";s:4:"ὁ";s:3:"ὁ";s:5:"ὂ";s:3:"ὂ";s:5:"ὃ";s:3:"ὃ";s:5:"ὄ";s:3:"ὄ";s:5:"ὅ";s:3:"ὅ";s:4:"Ὀ";s:3:"Ὀ";s:4:"Ὁ";s:3:"Ὁ";s:5:"Ὂ";s:3:"Ὂ";s:5:"Ὃ";s:3:"Ὃ";s:5:"Ὄ";s:3:"Ὄ";s:5:"Ὅ";s:3:"Ὅ";s:4:"ὐ";s:3:"ὐ";s:4:"ὑ";s:3:"ὑ";s:5:"ὒ";s:3:"ὒ";s:5:"ὓ";s:3:"ὓ";s:5:"ὔ";s:3:"ὔ";s:5:"ὕ";s:3:"ὕ";s:5:"ὖ";s:3:"ὖ";s:5:"ὗ";s:3:"ὗ";s:4:"Ὑ";s:3:"Ὑ";s:5:"Ὓ";s:3:"Ὓ";s:5:"Ὕ";s:3:"Ὕ";s:5:"Ὗ";s:3:"Ὗ";s:4:"ὠ";s:3:"ὠ";s:4:"ὡ";s:3:"ὡ";s:5:"ὢ";s:3:"ὢ";s:5:"ὣ";s:3:"ὣ";s:5:"ὤ";s:3:"ὤ";s:5:"ὥ";s:3:"ὥ";s:5:"ὦ";s:3:"ὦ";s:5:"ὧ";s:3:"ὧ";s:4:"Ὠ";s:3:"Ὠ";s:4:"Ὡ";s:3:"Ὡ";s:5:"Ὢ";s:3:"Ὢ";s:5:"Ὣ";s:3:"Ὣ";s:5:"Ὤ";s:3:"Ὤ";s:5:"Ὥ";s:3:"Ὥ";s:5:"Ὦ";s:3:"Ὦ";s:5:"Ὧ";s:3:"Ὧ";s:4:"ὰ";s:3:"ὰ";s:2:"ά";s:3:"ά";s:4:"ὲ";s:3:"ὲ";s:2:"έ";s:3:"έ";s:4:"ὴ";s:3:"ὴ";s:2:"ή";s:3:"ή";s:4:"ὶ";s:3:"ὶ";s:2:"ί";s:3:"ί";s:4:"ὸ";s:3:"ὸ";s:2:"ό";s:3:"ό";s:4:"ὺ";s:3:"ὺ";s:2:"ύ";s:3:"ύ";s:4:"ὼ";s:3:"ὼ";s:2:"ώ";s:3:"ώ";s:5:"ᾀ";s:3:"ᾀ";s:5:"ᾁ";s:3:"ᾁ";s:5:"ᾂ";s:3:"ᾂ";s:5:"ᾃ";s:3:"ᾃ";s:5:"ᾄ";s:3:"ᾄ";s:5:"ᾅ";s:3:"ᾅ";s:5:"ᾆ";s:3:"ᾆ";s:5:"ᾇ";s:3:"ᾇ";s:5:"ᾈ";s:3:"ᾈ";s:5:"ᾉ";s:3:"ᾉ";s:5:"ᾊ";s:3:"ᾊ";s:5:"ᾋ";s:3:"ᾋ";s:5:"ᾌ";s:3:"ᾌ";s:5:"ᾍ";s:3:"ᾍ";s:5:"ᾎ";s:3:"ᾎ";s:5:"ᾏ";s:3:"ᾏ";s:5:"ᾐ";s:3:"ᾐ";s:5:"ᾑ";s:3:"ᾑ";s:5:"ᾒ";s:3:"ᾒ";s:5:"ᾓ";s:3:"ᾓ";s:5:"ᾔ";s:3:"ᾔ";s:5:"ᾕ";s:3:"ᾕ";s:5:"ᾖ";s:3:"ᾖ";s:5:"ᾗ";s:3:"ᾗ";s:5:"ᾘ";s:3:"ᾘ";s:5:"ᾙ";s:3:"ᾙ";s:5:"ᾚ";s:3:"ᾚ";s:5:"ᾛ";s:3:"ᾛ";s:5:"ᾜ";s:3:"ᾜ";s:5:"ᾝ";s:3:"ᾝ";s:5:"ᾞ";s:3:"ᾞ";s:5:"ᾟ";s:3:"ᾟ";s:5:"ᾠ";s:3:"ᾠ";s:5:"ᾡ";s:3:"ᾡ";s:5:"ᾢ";s:3:"ᾢ";s:5:"ᾣ";s:3:"ᾣ";s:5:"ᾤ";s:3:"ᾤ";s:5:"ᾥ";s:3:"ᾥ";s:5:"ᾦ";s:3:"ᾦ";s:5:"ᾧ";s:3:"ᾧ";s:5:"ᾨ";s:3:"ᾨ";s:5:"ᾩ";s:3:"ᾩ";s:5:"ᾪ";s:3:"ᾪ";s:5:"ᾫ";s:3:"ᾫ";s:5:"ᾬ";s:3:"ᾬ";s:5:"ᾭ";s:3:"ᾭ";s:5:"ᾮ";s:3:"ᾮ";s:5:"ᾯ";s:3:"ᾯ";s:4:"ᾰ";s:3:"ᾰ";s:4:"ᾱ";s:3:"ᾱ";s:5:"ᾲ";s:3:"ᾲ";s:4:"ᾳ";s:3:"ᾳ";s:4:"ᾴ";s:3:"ᾴ";s:4:"ᾶ";s:3:"ᾶ";s:5:"ᾷ";s:3:"ᾷ";s:4:"Ᾰ";s:3:"Ᾰ";s:4:"Ᾱ";s:3:"Ᾱ";s:4:"Ὰ";s:3:"Ὰ";s:2:"Ά";s:3:"Ά";s:4:"ᾼ";s:3:"ᾼ";s:2:"ι";s:3:"ι";s:4:"῁";s:3:"῁";s:5:"ῂ";s:3:"ῂ";s:4:"ῃ";s:3:"ῃ";s:4:"ῄ";s:3:"ῄ";s:4:"ῆ";s:3:"ῆ";s:5:"ῇ";s:3:"ῇ";s:4:"Ὲ";s:3:"Ὲ";s:2:"Έ";s:3:"Έ";s:4:"Ὴ";s:3:"Ὴ";s:2:"Ή";s:3:"Ή";s:4:"ῌ";s:3:"ῌ";s:5:"῍";s:3:"῍";s:5:"῎";s:3:"῎";s:5:"῏";s:3:"῏";s:4:"ῐ";s:3:"ῐ";s:4:"ῑ";s:3:"ῑ";s:4:"ῒ";s:3:"ῒ";s:2:"ΐ";s:3:"ΐ";s:4:"ῖ";s:3:"ῖ";s:4:"ῗ";s:3:"ῗ";s:4:"Ῐ";s:3:"Ῐ";s:4:"Ῑ";s:3:"Ῑ";s:4:"Ὶ";s:3:"Ὶ";s:2:"Ί";s:3:"Ί";s:5:"῝";s:3:"῝";s:5:"῞";s:3:"῞";s:5:"῟";s:3:"῟";s:4:"ῠ";s:3:"ῠ";s:4:"ῡ";s:3:"ῡ";s:4:"ῢ";s:3:"ῢ";s:2:"ΰ";s:3:"ΰ";s:4:"ῤ";s:3:"ῤ";s:4:"ῥ";s:3:"ῥ";s:4:"ῦ";s:3:"ῦ";s:4:"ῧ";s:3:"ῧ";s:4:"Ῠ";s:3:"Ῠ";s:4:"Ῡ";s:3:"Ῡ";s:4:"Ὺ";s:3:"Ὺ";s:2:"Ύ";s:3:"Ύ";s:4:"Ῥ";s:3:"Ῥ";s:4:"῭";s:3:"῭";s:2:"΅";s:3:"΅";s:1:"`";s:3:"`";s:5:"ῲ";s:3:"ῲ";s:4:"ῳ";s:3:"ῳ";s:4:"ῴ";s:3:"ῴ";s:4:"ῶ";s:3:"ῶ";s:5:"ῷ";s:3:"ῷ";s:4:"Ὸ";s:3:"Ὸ";s:2:"Ό";s:3:"Ό";s:4:"Ὼ";s:3:"Ὼ";s:2:"Ώ";s:3:"Ώ";s:4:"ῼ";s:3:"ῼ";s:2:"´";s:3:"´";s:3:" ";s:3:" ";s:3:" ";s:3:" ";s:2:"Ω";s:3:"Ω";s:1:"K";s:3:"K";s:2:"Å";s:3:"Å";s:5:"↚";s:3:"↚";s:5:"↛";s:3:"↛";s:5:"↮";s:3:"↮";s:5:"⇍";s:3:"⇍";s:5:"⇎";s:3:"⇎";s:5:"⇏";s:3:"⇏";s:5:"∄";s:3:"∄";s:5:"∉";s:3:"∉";s:5:"∌";s:3:"∌";s:5:"∤";s:3:"∤";s:5:"∦";s:3:"∦";s:5:"≁";s:3:"≁";s:5:"≄";s:3:"≄";s:5:"≇";s:3:"≇";s:5:"≉";s:3:"≉";s:3:"≠";s:3:"≠";s:5:"≢";s:3:"≢";s:5:"≭";s:3:"≭";s:3:"≮";s:3:"≮";s:3:"≯";s:3:"≯";s:5:"≰";s:3:"≰";s:5:"≱";s:3:"≱";s:5:"≴";s:3:"≴";s:5:"≵";s:3:"≵";s:5:"≸";s:3:"≸";s:5:"≹";s:3:"≹";s:5:"⊀";s:3:"⊀";s:5:"⊁";s:3:"⊁";s:5:"⊄";s:3:"⊄";s:5:"⊅";s:3:"⊅";s:5:"⊈";s:3:"⊈";s:5:"⊉";s:3:"⊉";s:5:"⊬";s:3:"⊬";s:5:"⊭";s:3:"⊭";s:5:"⊮";s:3:"⊮";s:5:"⊯";s:3:"⊯";s:5:"⋠";s:3:"⋠";s:5:"⋡";s:3:"⋡";s:5:"⋢";s:3:"⋢";s:5:"⋣";s:3:"⋣";s:5:"⋪";s:3:"⋪";s:5:"⋫";s:3:"⋫";s:5:"⋬";s:3:"⋬";s:5:"⋭";s:3:"⋭";s:3:"〈";s:3:"〈";s:3:"〉";s:3:"〉";s:6:"が";s:3:"が";s:6:"ぎ";s:3:"ぎ";s:6:"ぐ";s:3:"ぐ";s:6:"げ";s:3:"げ";s:6:"ご";s:3:"ご";s:6:"ざ";s:3:"ざ";s:6:"じ";s:3:"じ";s:6:"ず";s:3:"ず";s:6:"ぜ";s:3:"ぜ";s:6:"ぞ";s:3:"ぞ";s:6:"だ";s:3:"だ";s:6:"ぢ";s:3:"ぢ";s:6:"づ";s:3:"づ";s:6:"で";s:3:"で";s:6:"ど";s:3:"ど";s:6:"ば";s:3:"ば";s:6:"ぱ";s:3:"ぱ";s:6:"び";s:3:"び";s:6:"ぴ";s:3:"ぴ";s:6:"ぶ";s:3:"ぶ";s:6:"ぷ";s:3:"ぷ";s:6:"べ";s:3:"べ";s:6:"ぺ";s:3:"ぺ";s:6:"ぼ";s:3:"ぼ";s:6:"ぽ";s:3:"ぽ";s:6:"ゔ";s:3:"ゔ";s:6:"ゞ";s:3:"ゞ";s:6:"ガ";s:3:"ガ";s:6:"ギ";s:3:"ギ";s:6:"グ";s:3:"グ";s:6:"ゲ";s:3:"ゲ";s:6:"ゴ";s:3:"ゴ";s:6:"ザ";s:3:"ザ";s:6:"ジ";s:3:"ジ";s:6:"ズ";s:3:"ズ";s:6:"ゼ";s:3:"ゼ";s:6:"ゾ";s:3:"ゾ";s:6:"ダ";s:3:"ダ";s:6:"ヂ";s:3:"ヂ";s:6:"ヅ";s:3:"ヅ";s:6:"デ";s:3:"デ";s:6:"ド";s:3:"ド";s:6:"バ";s:3:"バ";s:6:"パ";s:3:"パ";s:6:"ビ";s:3:"ビ";s:6:"ピ";s:3:"ピ";s:6:"ブ";s:3:"ブ";s:6:"プ";s:3:"プ";s:6:"ベ";s:3:"ベ";s:6:"ペ";s:3:"ペ";s:6:"ボ";s:3:"ボ";s:6:"ポ";s:3:"ポ";s:6:"ヴ";s:3:"ヴ";s:6:"ヷ";s:3:"ヷ";s:6:"ヸ";s:3:"ヸ";s:6:"ヹ";s:3:"ヹ";s:6:"ヺ";s:3:"ヺ";s:6:"ヾ";s:3:"ヾ";s:3:"豈";s:3:"豈";s:3:"更";s:3:"更";s:3:"車";s:3:"車";s:3:"賈";s:3:"賈";s:3:"滑";s:3:"滑";s:3:"串";s:3:"串";s:3:"句";s:3:"句";s:3:"龜";s:3:"龜";s:3:"契";s:3:"契";s:3:"金";s:3:"金";s:3:"喇";s:3:"喇";s:3:"奈";s:3:"奈";s:3:"懶";s:4:"懶";s:3:"癩";s:3:"癩";s:3:"羅";s:3:"羅";s:3:"蘿";s:3:"蘿";s:3:"螺";s:3:"螺";s:3:"裸";s:3:"裸";s:3:"邏";s:3:"邏";s:3:"樂";s:3:"樂";s:3:"洛";s:3:"洛";s:3:"烙";s:3:"烙";s:3:"珞";s:3:"珞";s:3:"落";s:3:"落";s:3:"酪";s:3:"酪";s:3:"駱";s:3:"駱";s:3:"亂";s:3:"亂";s:3:"卵";s:3:"卵";s:3:"欄";s:3:"欄";s:3:"爛";s:3:"爛";s:3:"蘭";s:3:"蘭";s:3:"鸞";s:3:"鸞";s:3:"嵐";s:3:"嵐";s:3:"濫";s:3:"濫";s:3:"藍";s:3:"藍";s:3:"襤";s:3:"襤";s:3:"拉";s:3:"拉";s:3:"臘";s:3:"臘";s:3:"蠟";s:3:"蠟";s:3:"廊";s:4:"廊";s:3:"朗";s:4:"朗";s:3:"浪";s:3:"浪";s:3:"狼";s:3:"狼";s:3:"郎";s:3:"郎";s:3:"來";s:3:"來";s:3:"冷";s:3:"冷";s:3:"勞";s:3:"勞";s:3:"擄";s:3:"擄";s:3:"櫓";s:3:"櫓";s:3:"爐";s:3:"爐";s:3:"盧";s:3:"盧";s:3:"老";s:3:"老";s:3:"蘆";s:3:"蘆";s:3:"虜";s:4:"虜";s:3:"路";s:3:"路";s:3:"露";s:3:"露";s:3:"魯";s:3:"魯";s:3:"鷺";s:3:"鷺";s:3:"碌";s:4:"碌";s:3:"祿";s:3:"祿";s:3:"綠";s:3:"綠";s:3:"菉";s:3:"菉";s:3:"錄";s:3:"錄";s:3:"鹿";s:3:"鹿";s:3:"論";s:3:"論";s:3:"壟";s:3:"壟";s:3:"弄";s:3:"弄";s:3:"籠";s:3:"籠";s:3:"聾";s:3:"聾";s:3:"牢";s:3:"牢";s:3:"磊";s:3:"磊";s:3:"賂";s:3:"賂";s:3:"雷";s:3:"雷";s:3:"壘";s:3:"壘";s:3:"屢";s:3:"屢";s:3:"樓";s:3:"樓";s:3:"淚";s:3:"淚";s:3:"漏";s:3:"漏";s:3:"累";s:3:"累";s:3:"縷";s:3:"縷";s:3:"陋";s:3:"陋";s:3:"勒";s:3:"勒";s:3:"肋";s:3:"肋";s:3:"凜";s:3:"凜";s:3:"凌";s:3:"凌";s:3:"稜";s:3:"稜";s:3:"綾";s:3:"綾";s:3:"菱";s:3:"菱";s:3:"陵";s:3:"陵";s:3:"讀";s:3:"讀";s:3:"拏";s:3:"拏";s:3:"諾";s:3:"諾";s:3:"丹";s:3:"丹";s:3:"寧";s:4:"寧";s:3:"怒";s:3:"怒";s:3:"率";s:3:"率";s:3:"異";s:4:"異";s:3:"北";s:4:"北";s:3:"磻";s:3:"磻";s:3:"便";s:3:"便";s:3:"復";s:3:"復";s:3:"不";s:3:"不";s:3:"泌";s:3:"泌";s:3:"數";s:3:"數";s:3:"索";s:3:"索";s:3:"參";s:3:"參";s:3:"塞";s:3:"塞";s:3:"省";s:3:"省";s:3:"葉";s:3:"葉";s:3:"說";s:3:"說";s:3:"殺";s:4:"殺";s:3:"辰";s:3:"辰";s:3:"沈";s:3:"沈";s:3:"拾";s:3:"拾";s:3:"若";s:4:"若";s:3:"掠";s:3:"掠";s:3:"略";s:3:"略";s:3:"亮";s:3:"亮";s:3:"兩";s:3:"兩";s:3:"凉";s:3:"凉";s:3:"梁";s:3:"梁";s:3:"糧";s:3:"糧";s:3:"良";s:3:"良";s:3:"諒";s:3:"諒";s:3:"量";s:3:"量";s:3:"勵";s:3:"勵";s:3:"呂";s:3:"呂";s:3:"女";s:3:"女";s:3:"廬";s:3:"廬";s:3:"旅";s:3:"旅";s:3:"濾";s:3:"濾";s:3:"礪";s:3:"礪";s:3:"閭";s:3:"閭";s:3:"驪";s:3:"驪";s:3:"麗";s:3:"麗";s:3:"黎";s:3:"黎";s:3:"力";s:3:"力";s:3:"曆";s:3:"曆";s:3:"歷";s:3:"歷";s:3:"轢";s:3:"轢";s:3:"年";s:3:"年";s:3:"憐";s:3:"憐";s:3:"戀";s:3:"戀";s:3:"撚";s:3:"撚";s:3:"漣";s:3:"漣";s:3:"煉";s:3:"煉";s:3:"璉";s:3:"璉";s:3:"秊";s:3:"秊";s:3:"練";s:3:"練";s:3:"聯";s:3:"聯";s:3:"輦";s:3:"輦";s:3:"蓮";s:3:"蓮";s:3:"連";s:3:"連";s:3:"鍊";s:3:"鍊";s:3:"列";s:3:"列";s:3:"劣";s:3:"劣";s:3:"咽";s:3:"咽";s:3:"烈";s:3:"烈";s:3:"裂";s:3:"裂";s:3:"廉";s:3:"廉";s:3:"念";s:3:"念";s:3:"捻";s:3:"捻";s:3:"殮";s:3:"殮";s:3:"簾";s:3:"簾";s:3:"獵";s:3:"獵";s:3:"令";s:3:"令";s:3:"囹";s:3:"囹";s:3:"嶺";s:3:"嶺";s:3:"怜";s:3:"怜";s:3:"玲";s:3:"玲";s:3:"瑩";s:3:"瑩";s:3:"羚";s:3:"羚";s:3:"聆";s:3:"聆";s:3:"鈴";s:3:"鈴";s:3:"零";s:3:"零";s:3:"靈";s:3:"靈";s:3:"領";s:3:"領";s:3:"例";s:3:"例";s:3:"禮";s:3:"禮";s:3:"醴";s:3:"醴";s:3:"隸";s:3:"隸";s:3:"惡";s:3:"惡";s:3:"了";s:3:"了";s:3:"僚";s:3:"僚";s:3:"寮";s:3:"寮";s:3:"尿";s:3:"尿";s:3:"料";s:3:"料";s:3:"燎";s:3:"燎";s:3:"療";s:3:"療";s:3:"蓼";s:3:"蓼";s:3:"遼";s:3:"遼";s:3:"龍";s:3:"龍";s:3:"暈";s:3:"暈";s:3:"阮";s:3:"阮";s:3:"劉";s:3:"劉";s:3:"杻";s:3:"杻";s:3:"柳";s:3:"柳";s:3:"流";s:4:"流";s:3:"溜";s:3:"溜";s:3:"琉";s:3:"琉";s:3:"留";s:3:"留";s:3:"硫";s:3:"硫";s:3:"紐";s:3:"紐";s:3:"類";s:3:"類";s:3:"六";s:3:"六";s:3:"戮";s:3:"戮";s:3:"陸";s:3:"陸";s:3:"倫";s:3:"倫";s:3:"崙";s:3:"崙";s:3:"淪";s:3:"淪";s:3:"輪";s:3:"輪";s:3:"律";s:3:"律";s:3:"慄";s:3:"慄";s:3:"栗";s:3:"栗";s:3:"隆";s:3:"隆";s:3:"利";s:3:"利";s:3:"吏";s:3:"吏";s:3:"履";s:3:"履";s:3:"易";s:3:"易";s:3:"李";s:3:"李";s:3:"梨";s:3:"梨";s:3:"泥";s:3:"泥";s:3:"理";s:3:"理";s:3:"痢";s:3:"痢";s:3:"罹";s:3:"罹";s:3:"裏";s:3:"裏";s:3:"裡";s:3:"裡";s:3:"里";s:3:"里";s:3:"離";s:3:"離";s:3:"匿";s:3:"匿";s:3:"溺";s:3:"溺";s:3:"吝";s:3:"吝";s:3:"燐";s:3:"燐";s:3:"璘";s:3:"璘";s:3:"藺";s:3:"藺";s:3:"隣";s:3:"隣";s:3:"鱗";s:3:"鱗";s:3:"麟";s:3:"麟";s:3:"林";s:3:"林";s:3:"淋";s:3:"淋";s:3:"臨";s:3:"臨";s:3:"立";s:3:"立";s:3:"笠";s:3:"笠";s:3:"粒";s:3:"粒";s:3:"狀";s:3:"狀";s:3:"炙";s:3:"炙";s:3:"識";s:3:"識";s:3:"什";s:3:"什";s:3:"茶";s:3:"茶";s:3:"刺";s:3:"刺";s:3:"切";s:4:"切";s:3:"度";s:3:"度";s:3:"拓";s:3:"拓";s:3:"糖";s:3:"糖";s:3:"宅";s:3:"宅";s:3:"洞";s:3:"洞";s:3:"暴";s:3:"暴";s:3:"輻";s:3:"輻";s:3:"行";s:3:"行";s:3:"降";s:3:"降";s:3:"見";s:3:"見";s:3:"廓";s:3:"廓";s:3:"兀";s:3:"兀";s:3:"嗀";s:3:"嗀";s:3:"塚";s:3:"塚";s:3:"晴";s:3:"晴";s:3:"凞";s:3:"凞";s:3:"猪";s:3:"猪";s:3:"益";s:3:"益";s:3:"礼";s:3:"礼";s:3:"神";s:3:"神";s:3:"祥";s:3:"祥";s:3:"福";s:4:"福";s:3:"靖";s:3:"靖";s:3:"精";s:3:"精";s:3:"羽";s:3:"羽";s:3:"蘒";s:3:"蘒";s:3:"諸";s:3:"諸";s:3:"逸";s:3:"逸";s:3:"都";s:3:"都";s:3:"飯";s:3:"飯";s:3:"飼";s:3:"飼";s:3:"館";s:3:"館";s:3:"鶴";s:3:"鶴";s:3:"侮";s:4:"侮";s:3:"僧";s:4:"僧";s:3:"免";s:4:"免";s:3:"勉";s:4:"勉";s:3:"勤";s:4:"勤";s:3:"卑";s:4:"卑";s:3:"喝";s:3:"喝";s:3:"嘆";s:4:"嘆";s:3:"器";s:3:"器";s:3:"塀";s:3:"塀";s:3:"墨";s:3:"墨";s:3:"層";s:3:"層";s:3:"屮";s:4:"屮";s:3:"悔";s:4:"悔";s:3:"慨";s:3:"慨";s:3:"憎";s:4:"憎";s:3:"懲";s:4:"懲";s:3:"敏";s:4:"敏";s:3:"既";s:3:"既";s:3:"暑";s:4:"暑";s:3:"梅";s:4:"梅";s:3:"海";s:4:"海";s:3:"渚";s:3:"渚";s:3:"漢";s:3:"漢";s:3:"煮";s:3:"煮";s:3:"爫";s:3:"爫";s:3:"琢";s:3:"琢";s:3:"碑";s:3:"碑";s:3:"社";s:3:"社";s:3:"祉";s:3:"祉";s:3:"祈";s:3:"祈";s:3:"祐";s:3:"祐";s:3:"祖";s:4:"祖";s:3:"祝";s:3:"祝";s:3:"禍";s:3:"禍";s:3:"禎";s:3:"禎";s:3:"穀";s:4:"穀";s:3:"突";s:3:"突";s:3:"節";s:3:"節";s:3:"縉";s:3:"縉";s:3:"繁";s:3:"繁";s:3:"署";s:3:"署";s:3:"者";s:4:"者";s:3:"臭";s:3:"臭";s:3:"艹";s:3:"艹";s:3:"著";s:4:"著";s:3:"褐";s:3:"褐";s:3:"視";s:3:"視";s:3:"謁";s:3:"謁";s:3:"謹";s:3:"謹";s:3:"賓";s:3:"賓";s:3:"贈";s:3:"贈";s:3:"辶";s:3:"辶";s:3:"難";s:3:"難";s:3:"響";s:3:"響";s:3:"頻";s:3:"頻";s:3:"並";s:3:"並";s:3:"况";s:4:"况";s:3:"全";s:3:"全";s:3:"侀";s:3:"侀";s:3:"充";s:3:"充";s:3:"冀";s:3:"冀";s:3:"勇";s:4:"勇";s:3:"勺";s:4:"勺";s:3:"啕";s:3:"啕";s:3:"喙";s:4:"喙";s:3:"嗢";s:3:"嗢";s:3:"墳";s:3:"墳";s:3:"奄";s:3:"奄";s:3:"奔";s:3:"奔";s:3:"婢";s:3:"婢";s:3:"嬨";s:3:"嬨";s:3:"廒";s:3:"廒";s:3:"廙";s:3:"廙";s:3:"彩";s:3:"彩";s:3:"徭";s:3:"徭";s:3:"惘";s:3:"惘";s:3:"慎";s:4:"慎";s:3:"愈";s:3:"愈";s:3:"慠";s:3:"慠";s:3:"戴";s:3:"戴";s:3:"揄";s:3:"揄";s:3:"搜";s:3:"搜";s:3:"摒";s:3:"摒";s:3:"敖";s:3:"敖";s:3:"望";s:4:"望";s:3:"杖";s:3:"杖";s:3:"歹";s:3:"歹";s:3:"滛";s:3:"滛";s:3:"滋";s:4:"滋";s:3:"瀞";s:4:"瀞";s:3:"瞧";s:3:"瞧";s:3:"爵";s:4:"爵";s:3:"犯";s:3:"犯";s:3:"瑱";s:4:"瑱";s:3:"甆";s:3:"甆";s:3:"画";s:3:"画";s:3:"瘝";s:3:"瘝";s:3:"瘟";s:3:"瘟";s:3:"盛";s:3:"盛";s:3:"直";s:4:"直";s:3:"睊";s:4:"睊";s:3:"着";s:3:"着";s:3:"磌";s:4:"磌";s:3:"窱";s:3:"窱";s:3:"类";s:3:"类";s:3:"絛";s:3:"絛";s:3:"缾";s:3:"缾";s:3:"荒";s:3:"荒";s:3:"華";s:3:"華";s:3:"蝹";s:4:"蝹";s:3:"襁";s:3:"襁";s:3:"覆";s:3:"覆";s:3:"調";s:3:"調";s:3:"請";s:3:"請";s:3:"諭";s:4:"諭";s:3:"變";s:4:"變";s:3:"輸";s:4:"輸";s:3:"遲";s:3:"遲";s:3:"醙";s:3:"醙";s:3:"鉶";s:3:"鉶";s:3:"陼";s:3:"陼";s:3:"韛";s:3:"韛";s:3:"頋";s:4:"頋";s:3:"鬒";s:4:"鬒";s:4:"𢡊";s:3:"𢡊";s:4:"𢡄";s:3:"𢡄";s:4:"𣏕";s:3:"𣏕";s:3:"㮝";s:4:"㮝";s:3:"䀘";s:3:"䀘";s:3:"䀹";s:4:"䀹";s:4:"𥉉";s:3:"𥉉";s:4:"𥳐";s:3:"𥳐";s:4:"𧻓";s:3:"𧻓";s:3:"齃";s:3:"齃";s:3:"龎";s:3:"龎";s:3:"丽";s:4:"丽";s:3:"丸";s:4:"丸";s:3:"乁";s:4:"乁";s:4:"𠄢";s:4:"𠄢";s:3:"你";s:4:"你";s:3:"侻";s:4:"侻";s:3:"倂";s:4:"倂";s:3:"偺";s:4:"偺";s:3:"備";s:4:"備";s:3:"像";s:4:"像";s:3:"㒞";s:4:"㒞";s:4:"𠘺";s:4:"𠘺";s:3:"兔";s:4:"兔";s:3:"兤";s:4:"兤";s:3:"具";s:4:"具";s:4:"𠔜";s:4:"𠔜";s:3:"㒹";s:4:"㒹";s:3:"內";s:4:"內";s:3:"再";s:4:"再";s:4:"𠕋";s:4:"𠕋";s:3:"冗";s:4:"冗";s:3:"冤";s:4:"冤";s:3:"仌";s:4:"仌";s:3:"冬";s:4:"冬";s:4:"𩇟";s:4:"𩇟";s:3:"凵";s:4:"凵";s:3:"刃";s:4:"刃";s:3:"㓟";s:4:"㓟";s:3:"刻";s:4:"刻";s:3:"剆";s:4:"剆";s:3:"割";s:4:"割";s:3:"剷";s:4:"剷";s:3:"㔕";s:4:"㔕";s:3:"包";s:4:"包";s:3:"匆";s:4:"匆";s:3:"卉";s:4:"卉";s:3:"博";s:4:"博";s:3:"即";s:4:"即";s:3:"卽";s:4:"卽";s:3:"卿";s:4:"卿";s:4:"𠨬";s:4:"𠨬";s:3:"灰";s:4:"灰";s:3:"及";s:4:"及";s:3:"叟";s:4:"叟";s:4:"𠭣";s:4:"𠭣";s:3:"叫";s:4:"叫";s:3:"叱";s:4:"叱";s:3:"吆";s:4:"吆";s:3:"咞";s:4:"咞";s:3:"吸";s:4:"吸";s:3:"呈";s:4:"呈";s:3:"周";s:4:"周";s:3:"咢";s:4:"咢";s:3:"哶";s:4:"哶";s:3:"唐";s:4:"唐";s:3:"啓";s:4:"啓";s:3:"啣";s:4:"啣";s:3:"善";s:4:"善";s:3:"喫";s:4:"喫";s:3:"喳";s:4:"喳";s:3:"嗂";s:4:"嗂";s:3:"圖";s:4:"圖";s:3:"圗";s:4:"圗";s:3:"噑";s:4:"噑";s:3:"噴";s:4:"噴";s:3:"壮";s:4:"壮";s:3:"城";s:4:"城";s:3:"埴";s:4:"埴";s:3:"堍";s:4:"堍";s:3:"型";s:4:"型";s:3:"堲";s:4:"堲";s:3:"報";s:4:"報";s:3:"墬";s:4:"墬";s:4:"𡓤";s:4:"𡓤";s:3:"売";s:4:"売";s:3:"壷";s:4:"壷";s:3:"夆";s:4:"夆";s:3:"多";s:4:"多";s:3:"夢";s:4:"夢";s:3:"奢";s:4:"奢";s:4:"𡚨";s:4:"𡚨";s:4:"𡛪";s:4:"𡛪";s:3:"姬";s:4:"姬";s:3:"娛";s:4:"娛";s:3:"娧";s:4:"娧";s:3:"姘";s:4:"姘";s:3:"婦";s:4:"婦";s:3:"㛮";s:4:"㛮";s:3:"㛼";s:4:"㛼";s:3:"嬈";s:4:"嬈";s:3:"嬾";s:4:"嬾";s:4:"𡧈";s:4:"𡧈";s:3:"寃";s:4:"寃";s:3:"寘";s:4:"寘";s:3:"寳";s:4:"寳";s:4:"𡬘";s:4:"𡬘";s:3:"寿";s:4:"寿";s:3:"将";s:4:"将";s:3:"当";s:4:"当";s:3:"尢";s:4:"尢";s:3:"㞁";s:4:"㞁";s:3:"屠";s:4:"屠";s:3:"峀";s:4:"峀";s:3:"岍";s:4:"岍";s:4:"𡷤";s:4:"𡷤";s:3:"嵃";s:4:"嵃";s:4:"𡷦";s:4:"𡷦";s:3:"嵮";s:4:"嵮";s:3:"嵫";s:4:"嵫";s:3:"嵼";s:4:"嵼";s:3:"巡";s:4:"巡";s:3:"巢";s:4:"巢";s:3:"㠯";s:4:"㠯";s:3:"巽";s:4:"巽";s:3:"帨";s:4:"帨";s:3:"帽";s:4:"帽";s:3:"幩";s:4:"幩";s:3:"㡢";s:4:"㡢";s:4:"𢆃";s:4:"𢆃";s:3:"㡼";s:4:"㡼";s:3:"庰";s:4:"庰";s:3:"庳";s:4:"庳";s:3:"庶";s:4:"庶";s:4:"𪎒";s:4:"𪎒";s:3:"廾";s:4:"廾";s:4:"𢌱";s:4:"𢌱";s:3:"舁";s:4:"舁";s:3:"弢";s:4:"弢";s:3:"㣇";s:4:"㣇";s:4:"𣊸";s:4:"𣊸";s:4:"𦇚";s:4:"𦇚";s:3:"形";s:4:"形";s:3:"彫";s:4:"彫";s:3:"㣣";s:4:"㣣";s:3:"徚";s:4:"徚";s:3:"忍";s:4:"忍";s:3:"志";s:4:"志";s:3:"忹";s:4:"忹";s:3:"悁";s:4:"悁";s:3:"㤺";s:4:"㤺";s:3:"㤜";s:4:"㤜";s:4:"𢛔";s:4:"𢛔";s:3:"惇";s:4:"惇";s:3:"慈";s:4:"慈";s:3:"慌";s:4:"慌";s:3:"慺";s:4:"慺";s:3:"憲";s:4:"憲";s:3:"憤";s:4:"憤";s:3:"憯";s:4:"憯";s:3:"懞";s:4:"懞";s:3:"成";s:4:"成";s:3:"戛";s:4:"戛";s:3:"扝";s:4:"扝";s:3:"抱";s:4:"抱";s:3:"拔";s:4:"拔";s:3:"捐";s:4:"捐";s:4:"𢬌";s:4:"𢬌";s:3:"挽";s:4:"挽";s:3:"拼";s:4:"拼";s:3:"捨";s:4:"捨";s:3:"掃";s:4:"掃";s:3:"揤";s:4:"揤";s:4:"𢯱";s:4:"𢯱";s:3:"搢";s:4:"搢";s:3:"揅";s:4:"揅";s:3:"掩";s:4:"掩";s:3:"㨮";s:4:"㨮";s:3:"摩";s:4:"摩";s:3:"摾";s:4:"摾";s:3:"撝";s:4:"撝";s:3:"摷";s:4:"摷";s:3:"㩬";s:4:"㩬";s:3:"敬";s:4:"敬";s:4:"𣀊";s:4:"𣀊";s:3:"旣";s:4:"旣";s:3:"書";s:4:"書";s:3:"晉";s:4:"晉";s:3:"㬙";s:4:"㬙";s:3:"㬈";s:4:"㬈";s:3:"㫤";s:4:"㫤";s:3:"冒";s:4:"冒";s:3:"冕";s:4:"冕";s:3:"最";s:4:"最";s:3:"暜";s:4:"暜";s:3:"肭";s:4:"肭";s:3:"䏙";s:4:"䏙";s:3:"朡";s:4:"朡";s:3:"杞";s:4:"杞";s:3:"杓";s:4:"杓";s:4:"𣏃";s:4:"𣏃";s:3:"㭉";s:4:"㭉";s:3:"柺";s:4:"柺";s:3:"枅";s:4:"枅";s:3:"桒";s:4:"桒";s:4:"𣑭";s:4:"𣑭";s:3:"梎";s:4:"梎";s:3:"栟";s:4:"栟";s:3:"椔";s:4:"椔";s:3:"楂";s:4:"楂";s:3:"榣";s:4:"榣";s:3:"槪";s:4:"槪";s:3:"檨";s:4:"檨";s:4:"𣚣";s:4:"𣚣";s:3:"櫛";s:4:"櫛";s:3:"㰘";s:4:"㰘";s:3:"次";s:4:"次";s:4:"𣢧";s:4:"𣢧";s:3:"歔";s:4:"歔";s:3:"㱎";s:4:"㱎";s:3:"歲";s:4:"歲";s:3:"殟";s:4:"殟";s:3:"殻";s:4:"殻";s:4:"𣪍";s:4:"𣪍";s:4:"𡴋";s:4:"𡴋";s:4:"𣫺";s:4:"𣫺";s:3:"汎";s:4:"汎";s:4:"𣲼";s:4:"𣲼";s:3:"沿";s:4:"沿";s:3:"泍";s:4:"泍";s:3:"汧";s:4:"汧";s:3:"洖";s:4:"洖";s:3:"派";s:4:"派";s:3:"浩";s:4:"浩";s:3:"浸";s:4:"浸";s:3:"涅";s:4:"涅";s:4:"𣴞";s:4:"𣴞";s:3:"洴";s:4:"洴";s:3:"港";s:4:"港";s:3:"湮";s:4:"湮";s:3:"㴳";s:4:"㴳";s:3:"滇";s:4:"滇";s:4:"𣻑";s:4:"𣻑";s:3:"淹";s:4:"淹";s:3:"潮";s:4:"潮";s:4:"𣽞";s:4:"𣽞";s:4:"𣾎";s:4:"𣾎";s:3:"濆";s:4:"濆";s:3:"瀹";s:4:"瀹";s:3:"瀛";s:4:"瀛";s:3:"㶖";s:4:"㶖";s:3:"灊";s:4:"灊";s:3:"災";s:4:"災";s:3:"灷";s:4:"灷";s:3:"炭";s:4:"炭";s:4:"𠔥";s:4:"𠔥";s:3:"煅";s:4:"煅";s:4:"𤉣";s:4:"𤉣";s:3:"熜";s:4:"熜";s:4:"𤎫";s:4:"𤎫";s:3:"爨";s:4:"爨";s:3:"牐";s:4:"牐";s:4:"𤘈";s:4:"𤘈";s:3:"犀";s:4:"犀";s:3:"犕";s:4:"犕";s:4:"𤜵";s:4:"𤜵";s:4:"𤠔";s:4:"𤠔";s:3:"獺";s:4:"獺";s:3:"王";s:4:"王";s:3:"㺬";s:4:"㺬";s:3:"玥";s:4:"玥";s:3:"㺸";s:4:"㺸";s:3:"瑇";s:4:"瑇";s:3:"瑜";s:4:"瑜";s:3:"璅";s:4:"璅";s:3:"瓊";s:4:"瓊";s:3:"㼛";s:4:"㼛";s:3:"甤";s:4:"甤";s:4:"𤰶";s:4:"𤰶";s:3:"甾";s:4:"甾";s:4:"𤲒";s:4:"𤲒";s:4:"𢆟";s:4:"𢆟";s:3:"瘐";s:4:"瘐";s:4:"𤾡";s:4:"𤾡";s:4:"𤾸";s:4:"𤾸";s:4:"𥁄";s:4:"𥁄";s:3:"㿼";s:4:"㿼";s:3:"䀈";s:4:"䀈";s:4:"𥃳";s:4:"𥃳";s:4:"𥃲";s:4:"𥃲";s:4:"𥄙";s:4:"𥄙";s:4:"𥄳";s:4:"𥄳";s:3:"眞";s:4:"眞";s:3:"真";s:4:"真";s:3:"瞋";s:4:"瞋";s:3:"䁆";s:4:"䁆";s:3:"䂖";s:4:"䂖";s:4:"𥐝";s:4:"𥐝";s:3:"硎";s:4:"硎";s:3:"䃣";s:4:"䃣";s:4:"𥘦";s:4:"𥘦";s:4:"𥚚";s:4:"𥚚";s:4:"𥛅";s:4:"𥛅";s:3:"秫";s:4:"秫";s:3:"䄯";s:4:"䄯";s:3:"穊";s:4:"穊";s:3:"穏";s:4:"穏";s:4:"𥥼";s:4:"𥥼";s:4:"𥪧";s:4:"𥪧";s:3:"竮";s:4:"竮";s:3:"䈂";s:4:"䈂";s:4:"𥮫";s:4:"𥮫";s:3:"篆";s:4:"篆";s:3:"築";s:4:"築";s:3:"䈧";s:4:"䈧";s:4:"𥲀";s:4:"𥲀";s:3:"糒";s:4:"糒";s:3:"䊠";s:4:"䊠";s:3:"糨";s:4:"糨";s:3:"糣";s:4:"糣";s:3:"紀";s:4:"紀";s:4:"𥾆";s:4:"𥾆";s:3:"絣";s:4:"絣";s:3:"䌁";s:4:"䌁";s:3:"緇";s:4:"緇";s:3:"縂";s:4:"縂";s:3:"繅";s:4:"繅";s:3:"䌴";s:4:"䌴";s:4:"𦈨";s:4:"𦈨";s:4:"𦉇";s:4:"𦉇";s:3:"䍙";s:4:"䍙";s:4:"𦋙";s:4:"𦋙";s:3:"罺";s:4:"罺";s:4:"𦌾";s:4:"𦌾";s:3:"羕";s:4:"羕";s:3:"翺";s:4:"翺";s:4:"𦓚";s:4:"𦓚";s:4:"𦔣";s:4:"𦔣";s:3:"聠";s:4:"聠";s:4:"𦖨";s:4:"𦖨";s:3:"聰";s:4:"聰";s:4:"𣍟";s:4:"𣍟";s:3:"䏕";s:4:"䏕";s:3:"育";s:4:"育";s:3:"脃";s:4:"脃";s:3:"䐋";s:4:"䐋";s:3:"脾";s:4:"脾";s:3:"媵";s:4:"媵";s:4:"𦞧";s:4:"𦞧";s:4:"𦞵";s:4:"𦞵";s:4:"𣎓";s:4:"𣎓";s:4:"𣎜";s:4:"𣎜";s:3:"舄";s:4:"舄";s:3:"辞";s:4:"辞";s:3:"䑫";s:4:"䑫";s:3:"芑";s:4:"芑";s:3:"芋";s:4:"芋";s:3:"芝";s:4:"芝";s:3:"劳";s:4:"劳";s:3:"花";s:4:"花";s:3:"芳";s:4:"芳";s:3:"芽";s:4:"芽";s:3:"苦";s:4:"苦";s:4:"𦬼";s:4:"𦬼";s:3:"茝";s:4:"茝";s:3:"荣";s:4:"荣";s:3:"莭";s:4:"莭";s:3:"茣";s:4:"茣";s:3:"莽";s:4:"莽";s:3:"菧";s:4:"菧";s:3:"荓";s:4:"荓";s:3:"菊";s:4:"菊";s:3:"菌";s:4:"菌";s:3:"菜";s:4:"菜";s:4:"𦰶";s:4:"𦰶";s:4:"𦵫";s:4:"𦵫";s:4:"𦳕";s:4:"𦳕";s:3:"䔫";s:4:"䔫";s:3:"蓱";s:4:"蓱";s:3:"蓳";s:4:"蓳";s:3:"蔖";s:4:"蔖";s:4:"𧏊";s:4:"𧏊";s:3:"蕤";s:4:"蕤";s:4:"𦼬";s:4:"𦼬";s:3:"䕝";s:4:"䕝";s:3:"䕡";s:4:"䕡";s:4:"𦾱";s:4:"𦾱";s:4:"𧃒";s:4:"𧃒";s:3:"䕫";s:4:"䕫";s:3:"虐";s:4:"虐";s:3:"虧";s:4:"虧";s:3:"虩";s:4:"虩";s:3:"蚩";s:4:"蚩";s:3:"蚈";s:4:"蚈";s:3:"蜎";s:4:"蜎";s:3:"蛢";s:4:"蛢";s:3:"蜨";s:4:"蜨";s:3:"蝫";s:4:"蝫";s:3:"螆";s:4:"螆";s:3:"䗗";s:4:"䗗";s:3:"蟡";s:4:"蟡";s:3:"蠁";s:4:"蠁";s:3:"䗹";s:4:"䗹";s:3:"衠";s:4:"衠";s:3:"衣";s:4:"衣";s:4:"𧙧";s:4:"𧙧";s:3:"裗";s:4:"裗";s:3:"裞";s:4:"裞";s:3:"䘵";s:4:"䘵";s:3:"裺";s:4:"裺";s:3:"㒻";s:4:"㒻";s:4:"𧢮";s:4:"𧢮";s:4:"𧥦";s:4:"𧥦";s:3:"䚾";s:4:"䚾";s:3:"䛇";s:4:"䛇";s:3:"誠";s:4:"誠";s:3:"豕";s:4:"豕";s:4:"𧲨";s:4:"𧲨";s:3:"貫";s:4:"貫";s:3:"賁";s:4:"賁";s:3:"贛";s:4:"贛";s:3:"起";s:4:"起";s:4:"𧼯";s:4:"𧼯";s:4:"𠠄";s:4:"𠠄";s:3:"跋";s:4:"跋";s:3:"趼";s:4:"趼";s:3:"跰";s:4:"跰";s:4:"𠣞";s:4:"𠣞";s:3:"軔";s:4:"軔";s:4:"𨗒";s:4:"𨗒";s:4:"𨗭";s:4:"𨗭";s:3:"邔";s:4:"邔";s:3:"郱";s:4:"郱";s:3:"鄑";s:4:"鄑";s:4:"𨜮";s:4:"𨜮";s:3:"鄛";s:4:"鄛";s:3:"鈸";s:4:"鈸";s:3:"鋗";s:4:"鋗";s:3:"鋘";s:4:"鋘";s:3:"鉼";s:4:"鉼";s:3:"鏹";s:4:"鏹";s:3:"鐕";s:4:"鐕";s:4:"𨯺";s:4:"𨯺";s:3:"開";s:4:"開";s:3:"䦕";s:4:"䦕";s:3:"閷";s:4:"閷";s:4:"𨵷";s:4:"𨵷";s:3:"䧦";s:4:"䧦";s:3:"雃";s:4:"雃";s:3:"嶲";s:4:"嶲";s:3:"霣";s:4:"霣";s:4:"𩅅";s:4:"𩅅";s:4:"𩈚";s:4:"𩈚";s:3:"䩮";s:4:"䩮";s:3:"䩶";s:4:"䩶";s:3:"韠";s:4:"韠";s:4:"𩐊";s:4:"𩐊";s:3:"䪲";s:4:"䪲";s:4:"𩒖";s:4:"𩒖";s:3:"頩";s:4:"頩";s:4:"𩖶";s:4:"𩖶";s:3:"飢";s:4:"飢";s:3:"䬳";s:4:"䬳";s:3:"餩";s:4:"餩";s:3:"馧";s:4:"馧";s:3:"駂";s:4:"駂";s:3:"駾";s:4:"駾";s:3:"䯎";s:4:"䯎";s:4:"𩬰";s:4:"𩬰";s:3:"鱀";s:4:"鱀";s:3:"鳽";s:4:"鳽";s:3:"䳎";s:4:"䳎";s:3:"䳭";s:4:"䳭";s:3:"鵧";s:4:"鵧";s:4:"𪃎";s:4:"𪃎";s:3:"䳸";s:4:"䳸";s:4:"𪄅";s:4:"𪄅";s:4:"𪈎";s:4:"𪈎";s:4:"𪊑";s:4:"𪊑";s:3:"麻";s:4:"麻";s:3:"䵖";s:4:"䵖";s:3:"黹";s:4:"黹";s:3:"黾";s:4:"黾";s:3:"鼅";s:4:"鼅";s:3:"鼏";s:4:"鼏";s:3:"鼖";s:4:"鼖";s:3:"鼻";s:4:"鼻";s:4:"𪘀";s:4:"𪘀";}' );
+$utfCanonicalDecomp = unserialize( 'a:2032:{s:2:"À";s:3:"À";s:2:"Á";s:3:"Á";s:2:"Â";s:3:"Â";s:2:"Ã";s:3:"Ã";s:2:"Ä";s:3:"Ä";s:2:"Å";s:3:"Å";s:2:"Ç";s:3:"Ç";s:2:"È";s:3:"È";s:2:"É";s:3:"É";s:2:"Ê";s:3:"Ê";s:2:"Ë";s:3:"Ë";s:2:"Ì";s:3:"Ì";s:2:"Í";s:3:"Í";s:2:"Î";s:3:"Î";s:2:"Ï";s:3:"Ï";s:2:"Ñ";s:3:"Ñ";s:2:"Ò";s:3:"Ò";s:2:"Ó";s:3:"Ó";s:2:"Ô";s:3:"Ô";s:2:"Õ";s:3:"Õ";s:2:"Ö";s:3:"Ö";s:2:"Ù";s:3:"Ù";s:2:"Ú";s:3:"Ú";s:2:"Û";s:3:"Û";s:2:"Ü";s:3:"Ü";s:2:"Ý";s:3:"Ý";s:2:"à";s:3:"à";s:2:"á";s:3:"á";s:2:"â";s:3:"â";s:2:"ã";s:3:"ã";s:2:"ä";s:3:"ä";s:2:"å";s:3:"å";s:2:"ç";s:3:"ç";s:2:"è";s:3:"è";s:2:"é";s:3:"é";s:2:"ê";s:3:"ê";s:2:"ë";s:3:"ë";s:2:"ì";s:3:"ì";s:2:"í";s:3:"í";s:2:"î";s:3:"î";s:2:"ï";s:3:"ï";s:2:"ñ";s:3:"ñ";s:2:"ò";s:3:"ò";s:2:"ó";s:3:"ó";s:2:"ô";s:3:"ô";s:2:"õ";s:3:"õ";s:2:"ö";s:3:"ö";s:2:"ù";s:3:"ù";s:2:"ú";s:3:"ú";s:2:"û";s:3:"û";s:2:"ü";s:3:"ü";s:2:"ý";s:3:"ý";s:2:"ÿ";s:3:"ÿ";s:2:"Ā";s:3:"Ā";s:2:"ā";s:3:"ā";s:2:"Ă";s:3:"Ă";s:2:"ă";s:3:"ă";s:2:"Ą";s:3:"Ą";s:2:"ą";s:3:"ą";s:2:"Ć";s:3:"Ć";s:2:"ć";s:3:"ć";s:2:"Ĉ";s:3:"Ĉ";s:2:"ĉ";s:3:"ĉ";s:2:"Ċ";s:3:"Ċ";s:2:"ċ";s:3:"ċ";s:2:"Č";s:3:"Č";s:2:"č";s:3:"č";s:2:"Ď";s:3:"Ď";s:2:"ď";s:3:"ď";s:2:"Ē";s:3:"Ē";s:2:"ē";s:3:"ē";s:2:"Ĕ";s:3:"Ĕ";s:2:"ĕ";s:3:"ĕ";s:2:"Ė";s:3:"Ė";s:2:"ė";s:3:"ė";s:2:"Ę";s:3:"Ę";s:2:"ę";s:3:"ę";s:2:"Ě";s:3:"Ě";s:2:"ě";s:3:"ě";s:2:"Ĝ";s:3:"Ĝ";s:2:"ĝ";s:3:"ĝ";s:2:"Ğ";s:3:"Ğ";s:2:"ğ";s:3:"ğ";s:2:"Ġ";s:3:"Ġ";s:2:"ġ";s:3:"ġ";s:2:"Ģ";s:3:"Ģ";s:2:"ģ";s:3:"ģ";s:2:"Ĥ";s:3:"Ĥ";s:2:"ĥ";s:3:"ĥ";s:2:"Ĩ";s:3:"Ĩ";s:2:"ĩ";s:3:"ĩ";s:2:"Ī";s:3:"Ī";s:2:"ī";s:3:"ī";s:2:"Ĭ";s:3:"Ĭ";s:2:"ĭ";s:3:"ĭ";s:2:"Į";s:3:"Į";s:2:"į";s:3:"į";s:2:"İ";s:3:"İ";s:2:"Ĵ";s:3:"Ĵ";s:2:"ĵ";s:3:"ĵ";s:2:"Ķ";s:3:"Ķ";s:2:"ķ";s:3:"ķ";s:2:"Ĺ";s:3:"Ĺ";s:2:"ĺ";s:3:"ĺ";s:2:"Ļ";s:3:"Ļ";s:2:"ļ";s:3:"ļ";s:2:"Ľ";s:3:"Ľ";s:2:"ľ";s:3:"ľ";s:2:"Ń";s:3:"Ń";s:2:"ń";s:3:"ń";s:2:"Ņ";s:3:"Ņ";s:2:"ņ";s:3:"ņ";s:2:"Ň";s:3:"Ň";s:2:"ň";s:3:"ň";s:2:"Ō";s:3:"Ō";s:2:"ō";s:3:"ō";s:2:"Ŏ";s:3:"Ŏ";s:2:"ŏ";s:3:"ŏ";s:2:"Ő";s:3:"Ő";s:2:"ő";s:3:"ő";s:2:"Ŕ";s:3:"Ŕ";s:2:"ŕ";s:3:"ŕ";s:2:"Ŗ";s:3:"Ŗ";s:2:"ŗ";s:3:"ŗ";s:2:"Ř";s:3:"Ř";s:2:"ř";s:3:"ř";s:2:"Ś";s:3:"Ś";s:2:"ś";s:3:"ś";s:2:"Ŝ";s:3:"Ŝ";s:2:"ŝ";s:3:"ŝ";s:2:"Ş";s:3:"Ş";s:2:"ş";s:3:"ş";s:2:"Š";s:3:"Š";s:2:"š";s:3:"š";s:2:"Ţ";s:3:"Ţ";s:2:"ţ";s:3:"ţ";s:2:"Ť";s:3:"Ť";s:2:"ť";s:3:"ť";s:2:"Ũ";s:3:"Ũ";s:2:"ũ";s:3:"ũ";s:2:"Ū";s:3:"Ū";s:2:"ū";s:3:"ū";s:2:"Ŭ";s:3:"Ŭ";s:2:"ŭ";s:3:"ŭ";s:2:"Ů";s:3:"Ů";s:2:"ů";s:3:"ů";s:2:"Ű";s:3:"Ű";s:2:"ű";s:3:"ű";s:2:"Ų";s:3:"Ų";s:2:"ų";s:3:"ų";s:2:"Ŵ";s:3:"Ŵ";s:2:"ŵ";s:3:"ŵ";s:2:"Ŷ";s:3:"Ŷ";s:2:"ŷ";s:3:"ŷ";s:2:"Ÿ";s:3:"Ÿ";s:2:"Ź";s:3:"Ź";s:2:"ź";s:3:"ź";s:2:"Ż";s:3:"Ż";s:2:"ż";s:3:"ż";s:2:"Ž";s:3:"Ž";s:2:"ž";s:3:"ž";s:2:"Ơ";s:3:"Ơ";s:2:"ơ";s:3:"ơ";s:2:"Ư";s:3:"Ư";s:2:"ư";s:3:"ư";s:2:"Ǎ";s:3:"Ǎ";s:2:"ǎ";s:3:"ǎ";s:2:"Ǐ";s:3:"Ǐ";s:2:"ǐ";s:3:"ǐ";s:2:"Ǒ";s:3:"Ǒ";s:2:"ǒ";s:3:"ǒ";s:2:"Ǔ";s:3:"Ǔ";s:2:"ǔ";s:3:"ǔ";s:2:"Ǖ";s:5:"Ǖ";s:2:"ǖ";s:5:"ǖ";s:2:"Ǘ";s:5:"Ǘ";s:2:"ǘ";s:5:"ǘ";s:2:"Ǚ";s:5:"Ǚ";s:2:"ǚ";s:5:"ǚ";s:2:"Ǜ";s:5:"Ǜ";s:2:"ǜ";s:5:"ǜ";s:2:"Ǟ";s:5:"Ǟ";s:2:"ǟ";s:5:"ǟ";s:2:"Ǡ";s:5:"Ǡ";s:2:"ǡ";s:5:"ǡ";s:2:"Ǣ";s:4:"Ǣ";s:2:"ǣ";s:4:"ǣ";s:2:"Ǧ";s:3:"Ǧ";s:2:"ǧ";s:3:"ǧ";s:2:"Ǩ";s:3:"Ǩ";s:2:"ǩ";s:3:"ǩ";s:2:"Ǫ";s:3:"Ǫ";s:2:"ǫ";s:3:"ǫ";s:2:"Ǭ";s:5:"Ǭ";s:2:"ǭ";s:5:"ǭ";s:2:"Ǯ";s:4:"Ǯ";s:2:"ǯ";s:4:"ǯ";s:2:"ǰ";s:3:"ǰ";s:2:"Ǵ";s:3:"Ǵ";s:2:"ǵ";s:3:"ǵ";s:2:"Ǹ";s:3:"Ǹ";s:2:"ǹ";s:3:"ǹ";s:2:"Ǻ";s:5:"Ǻ";s:2:"ǻ";s:5:"ǻ";s:2:"Ǽ";s:4:"Ǽ";s:2:"ǽ";s:4:"ǽ";s:2:"Ǿ";s:4:"Ǿ";s:2:"ǿ";s:4:"ǿ";s:2:"Ȁ";s:3:"Ȁ";s:2:"ȁ";s:3:"ȁ";s:2:"Ȃ";s:3:"Ȃ";s:2:"ȃ";s:3:"ȃ";s:2:"Ȅ";s:3:"Ȅ";s:2:"ȅ";s:3:"ȅ";s:2:"Ȇ";s:3:"Ȇ";s:2:"ȇ";s:3:"ȇ";s:2:"Ȉ";s:3:"Ȉ";s:2:"ȉ";s:3:"ȉ";s:2:"Ȋ";s:3:"Ȋ";s:2:"ȋ";s:3:"ȋ";s:2:"Ȍ";s:3:"Ȍ";s:2:"ȍ";s:3:"ȍ";s:2:"Ȏ";s:3:"Ȏ";s:2:"ȏ";s:3:"ȏ";s:2:"Ȑ";s:3:"Ȑ";s:2:"ȑ";s:3:"ȑ";s:2:"Ȓ";s:3:"Ȓ";s:2:"ȓ";s:3:"ȓ";s:2:"Ȕ";s:3:"Ȕ";s:2:"ȕ";s:3:"ȕ";s:2:"Ȗ";s:3:"Ȗ";s:2:"ȗ";s:3:"ȗ";s:2:"Ș";s:3:"Ș";s:2:"ș";s:3:"ș";s:2:"Ț";s:3:"Ț";s:2:"ț";s:3:"ț";s:2:"Ȟ";s:3:"Ȟ";s:2:"ȟ";s:3:"ȟ";s:2:"Ȧ";s:3:"Ȧ";s:2:"ȧ";s:3:"ȧ";s:2:"Ȩ";s:3:"Ȩ";s:2:"ȩ";s:3:"ȩ";s:2:"Ȫ";s:5:"Ȫ";s:2:"ȫ";s:5:"ȫ";s:2:"Ȭ";s:5:"Ȭ";s:2:"ȭ";s:5:"ȭ";s:2:"Ȯ";s:3:"Ȯ";s:2:"ȯ";s:3:"ȯ";s:2:"Ȱ";s:5:"Ȱ";s:2:"ȱ";s:5:"ȱ";s:2:"Ȳ";s:3:"Ȳ";s:2:"ȳ";s:3:"ȳ";s:2:"̀";s:2:"̀";s:2:"́";s:2:"́";s:2:"̓";s:2:"̓";s:2:"̈́";s:4:"̈́";s:2:"ʹ";s:2:"ʹ";s:2:";";s:1:";";s:2:"΅";s:4:"΅";s:2:"Ά";s:4:"Ά";s:2:"·";s:2:"·";s:2:"Έ";s:4:"Έ";s:2:"Ή";s:4:"Ή";s:2:"Ί";s:4:"Ί";s:2:"Ό";s:4:"Ό";s:2:"Ύ";s:4:"Ύ";s:2:"Ώ";s:4:"Ώ";s:2:"ΐ";s:6:"ΐ";s:2:"Ϊ";s:4:"Ϊ";s:2:"Ϋ";s:4:"Ϋ";s:2:"ά";s:4:"ά";s:2:"έ";s:4:"έ";s:2:"ή";s:4:"ή";s:2:"ί";s:4:"ί";s:2:"ΰ";s:6:"ΰ";s:2:"ϊ";s:4:"ϊ";s:2:"ϋ";s:4:"ϋ";s:2:"ό";s:4:"ό";s:2:"ύ";s:4:"ύ";s:2:"ώ";s:4:"ώ";s:2:"ϓ";s:4:"ϓ";s:2:"ϔ";s:4:"ϔ";s:2:"Ѐ";s:4:"Ѐ";s:2:"Ё";s:4:"Ё";s:2:"Ѓ";s:4:"Ѓ";s:2:"Ї";s:4:"Ї";s:2:"Ќ";s:4:"Ќ";s:2:"Ѝ";s:4:"Ѝ";s:2:"Ў";s:4:"Ў";s:2:"Й";s:4:"Й";s:2:"й";s:4:"й";s:2:"ѐ";s:4:"ѐ";s:2:"ё";s:4:"ё";s:2:"ѓ";s:4:"ѓ";s:2:"ї";s:4:"ї";s:2:"ќ";s:4:"ќ";s:2:"ѝ";s:4:"ѝ";s:2:"ў";s:4:"ў";s:2:"Ѷ";s:4:"Ѷ";s:2:"ѷ";s:4:"ѷ";s:2:"Ӂ";s:4:"Ӂ";s:2:"ӂ";s:4:"ӂ";s:2:"Ӑ";s:4:"Ӑ";s:2:"ӑ";s:4:"ӑ";s:2:"Ӓ";s:4:"Ӓ";s:2:"ӓ";s:4:"ӓ";s:2:"Ӗ";s:4:"Ӗ";s:2:"ӗ";s:4:"ӗ";s:2:"Ӛ";s:4:"Ӛ";s:2:"ӛ";s:4:"ӛ";s:2:"Ӝ";s:4:"Ӝ";s:2:"ӝ";s:4:"ӝ";s:2:"Ӟ";s:4:"Ӟ";s:2:"ӟ";s:4:"ӟ";s:2:"Ӣ";s:4:"Ӣ";s:2:"ӣ";s:4:"ӣ";s:2:"Ӥ";s:4:"Ӥ";s:2:"ӥ";s:4:"ӥ";s:2:"Ӧ";s:4:"Ӧ";s:2:"ӧ";s:4:"ӧ";s:2:"Ӫ";s:4:"Ӫ";s:2:"ӫ";s:4:"ӫ";s:2:"Ӭ";s:4:"Ӭ";s:2:"ӭ";s:4:"ӭ";s:2:"Ӯ";s:4:"Ӯ";s:2:"ӯ";s:4:"ӯ";s:2:"Ӱ";s:4:"Ӱ";s:2:"ӱ";s:4:"ӱ";s:2:"Ӳ";s:4:"Ӳ";s:2:"ӳ";s:4:"ӳ";s:2:"Ӵ";s:4:"Ӵ";s:2:"ӵ";s:4:"ӵ";s:2:"Ӹ";s:4:"Ӹ";s:2:"ӹ";s:4:"ӹ";s:2:"آ";s:4:"آ";s:2:"أ";s:4:"أ";s:2:"ؤ";s:4:"ؤ";s:2:"إ";s:4:"إ";s:2:"ئ";s:4:"ئ";s:2:"ۀ";s:4:"ۀ";s:2:"ۂ";s:4:"ۂ";s:2:"ۓ";s:4:"ۓ";s:3:"ऩ";s:6:"ऩ";s:3:"ऱ";s:6:"ऱ";s:3:"ऴ";s:6:"ऴ";s:3:"क़";s:6:"क़";s:3:"ख़";s:6:"ख़";s:3:"ग़";s:6:"ग़";s:3:"ज़";s:6:"ज़";s:3:"ड़";s:6:"ड़";s:3:"ढ़";s:6:"ढ़";s:3:"फ़";s:6:"फ़";s:3:"य़";s:6:"य़";s:3:"ো";s:6:"ো";s:3:"ৌ";s:6:"ৌ";s:3:"ড়";s:6:"ড়";s:3:"ঢ়";s:6:"ঢ়";s:3:"য়";s:6:"য়";s:3:"ਲ਼";s:6:"ਲ਼";s:3:"ਸ਼";s:6:"ਸ਼";s:3:"ਖ਼";s:6:"ਖ਼";s:3:"ਗ਼";s:6:"ਗ਼";s:3:"ਜ਼";s:6:"ਜ਼";s:3:"ਫ਼";s:6:"ਫ਼";s:3:"ୈ";s:6:"ୈ";s:3:"ୋ";s:6:"ୋ";s:3:"ୌ";s:6:"ୌ";s:3:"ଡ଼";s:6:"ଡ଼";s:3:"ଢ଼";s:6:"ଢ଼";s:3:"ஔ";s:6:"ஔ";s:3:"ொ";s:6:"ொ";s:3:"ோ";s:6:"ோ";s:3:"ௌ";s:6:"ௌ";s:3:"ై";s:6:"ై";s:3:"ೀ";s:6:"ೀ";s:3:"ೇ";s:6:"ೇ";s:3:"ೈ";s:6:"ೈ";s:3:"ೊ";s:6:"ೊ";s:3:"ೋ";s:9:"ೋ";s:3:"ൊ";s:6:"ൊ";s:3:"ോ";s:6:"ോ";s:3:"ൌ";s:6:"ൌ";s:3:"ේ";s:6:"ේ";s:3:"ො";s:6:"ො";s:3:"ෝ";s:9:"ෝ";s:3:"ෞ";s:6:"ෞ";s:3:"གྷ";s:6:"གྷ";s:3:"ཌྷ";s:6:"ཌྷ";s:3:"དྷ";s:6:"དྷ";s:3:"བྷ";s:6:"བྷ";s:3:"ཛྷ";s:6:"ཛྷ";s:3:"ཀྵ";s:6:"ཀྵ";s:3:"ཱི";s:6:"ཱི";s:3:"ཱུ";s:6:"ཱུ";s:3:"ྲྀ";s:6:"ྲྀ";s:3:"ླྀ";s:6:"ླྀ";s:3:"ཱྀ";s:6:"ཱྀ";s:3:"ྒྷ";s:6:"ྒྷ";s:3:"ྜྷ";s:6:"ྜྷ";s:3:"ྡྷ";s:6:"ྡྷ";s:3:"ྦྷ";s:6:"ྦྷ";s:3:"ྫྷ";s:6:"ྫྷ";s:3:"ྐྵ";s:6:"ྐྵ";s:3:"ဦ";s:6:"ဦ";s:3:"Ḁ";s:3:"Ḁ";s:3:"ḁ";s:3:"ḁ";s:3:"Ḃ";s:3:"Ḃ";s:3:"ḃ";s:3:"ḃ";s:3:"Ḅ";s:3:"Ḅ";s:3:"ḅ";s:3:"ḅ";s:3:"Ḇ";s:3:"Ḇ";s:3:"ḇ";s:3:"ḇ";s:3:"Ḉ";s:5:"Ḉ";s:3:"ḉ";s:5:"ḉ";s:3:"Ḋ";s:3:"Ḋ";s:3:"ḋ";s:3:"ḋ";s:3:"Ḍ";s:3:"Ḍ";s:3:"ḍ";s:3:"ḍ";s:3:"Ḏ";s:3:"Ḏ";s:3:"ḏ";s:3:"ḏ";s:3:"Ḑ";s:3:"Ḑ";s:3:"ḑ";s:3:"ḑ";s:3:"Ḓ";s:3:"Ḓ";s:3:"ḓ";s:3:"ḓ";s:3:"Ḕ";s:5:"Ḕ";s:3:"ḕ";s:5:"ḕ";s:3:"Ḗ";s:5:"Ḗ";s:3:"ḗ";s:5:"ḗ";s:3:"Ḙ";s:3:"Ḙ";s:3:"ḙ";s:3:"ḙ";s:3:"Ḛ";s:3:"Ḛ";s:3:"ḛ";s:3:"ḛ";s:3:"Ḝ";s:5:"Ḝ";s:3:"ḝ";s:5:"ḝ";s:3:"Ḟ";s:3:"Ḟ";s:3:"ḟ";s:3:"ḟ";s:3:"Ḡ";s:3:"Ḡ";s:3:"ḡ";s:3:"ḡ";s:3:"Ḣ";s:3:"Ḣ";s:3:"ḣ";s:3:"ḣ";s:3:"Ḥ";s:3:"Ḥ";s:3:"ḥ";s:3:"ḥ";s:3:"Ḧ";s:3:"Ḧ";s:3:"ḧ";s:3:"ḧ";s:3:"Ḩ";s:3:"Ḩ";s:3:"ḩ";s:3:"ḩ";s:3:"Ḫ";s:3:"Ḫ";s:3:"ḫ";s:3:"ḫ";s:3:"Ḭ";s:3:"Ḭ";s:3:"ḭ";s:3:"ḭ";s:3:"Ḯ";s:5:"Ḯ";s:3:"ḯ";s:5:"ḯ";s:3:"Ḱ";s:3:"Ḱ";s:3:"ḱ";s:3:"ḱ";s:3:"Ḳ";s:3:"Ḳ";s:3:"ḳ";s:3:"ḳ";s:3:"Ḵ";s:3:"Ḵ";s:3:"ḵ";s:3:"ḵ";s:3:"Ḷ";s:3:"Ḷ";s:3:"ḷ";s:3:"ḷ";s:3:"Ḹ";s:5:"Ḹ";s:3:"ḹ";s:5:"ḹ";s:3:"Ḻ";s:3:"Ḻ";s:3:"ḻ";s:3:"ḻ";s:3:"Ḽ";s:3:"Ḽ";s:3:"ḽ";s:3:"ḽ";s:3:"Ḿ";s:3:"Ḿ";s:3:"ḿ";s:3:"ḿ";s:3:"Ṁ";s:3:"Ṁ";s:3:"ṁ";s:3:"ṁ";s:3:"Ṃ";s:3:"Ṃ";s:3:"ṃ";s:3:"ṃ";s:3:"Ṅ";s:3:"Ṅ";s:3:"ṅ";s:3:"ṅ";s:3:"Ṇ";s:3:"Ṇ";s:3:"ṇ";s:3:"ṇ";s:3:"Ṉ";s:3:"Ṉ";s:3:"ṉ";s:3:"ṉ";s:3:"Ṋ";s:3:"Ṋ";s:3:"ṋ";s:3:"ṋ";s:3:"Ṍ";s:5:"Ṍ";s:3:"ṍ";s:5:"ṍ";s:3:"Ṏ";s:5:"Ṏ";s:3:"ṏ";s:5:"ṏ";s:3:"Ṑ";s:5:"Ṑ";s:3:"ṑ";s:5:"ṑ";s:3:"Ṓ";s:5:"Ṓ";s:3:"ṓ";s:5:"ṓ";s:3:"Ṕ";s:3:"Ṕ";s:3:"ṕ";s:3:"ṕ";s:3:"Ṗ";s:3:"Ṗ";s:3:"ṗ";s:3:"ṗ";s:3:"Ṙ";s:3:"Ṙ";s:3:"ṙ";s:3:"ṙ";s:3:"Ṛ";s:3:"Ṛ";s:3:"ṛ";s:3:"ṛ";s:3:"Ṝ";s:5:"Ṝ";s:3:"ṝ";s:5:"ṝ";s:3:"Ṟ";s:3:"Ṟ";s:3:"ṟ";s:3:"ṟ";s:3:"Ṡ";s:3:"Ṡ";s:3:"ṡ";s:3:"ṡ";s:3:"Ṣ";s:3:"Ṣ";s:3:"ṣ";s:3:"ṣ";s:3:"Ṥ";s:5:"Ṥ";s:3:"ṥ";s:5:"ṥ";s:3:"Ṧ";s:5:"Ṧ";s:3:"ṧ";s:5:"ṧ";s:3:"Ṩ";s:5:"Ṩ";s:3:"ṩ";s:5:"ṩ";s:3:"Ṫ";s:3:"Ṫ";s:3:"ṫ";s:3:"ṫ";s:3:"Ṭ";s:3:"Ṭ";s:3:"ṭ";s:3:"ṭ";s:3:"Ṯ";s:3:"Ṯ";s:3:"ṯ";s:3:"ṯ";s:3:"Ṱ";s:3:"Ṱ";s:3:"ṱ";s:3:"ṱ";s:3:"Ṳ";s:3:"Ṳ";s:3:"ṳ";s:3:"ṳ";s:3:"Ṵ";s:3:"Ṵ";s:3:"ṵ";s:3:"ṵ";s:3:"Ṷ";s:3:"Ṷ";s:3:"ṷ";s:3:"ṷ";s:3:"Ṹ";s:5:"Ṹ";s:3:"ṹ";s:5:"ṹ";s:3:"Ṻ";s:5:"Ṻ";s:3:"ṻ";s:5:"ṻ";s:3:"Ṽ";s:3:"Ṽ";s:3:"ṽ";s:3:"ṽ";s:3:"Ṿ";s:3:"Ṿ";s:3:"ṿ";s:3:"ṿ";s:3:"Ẁ";s:3:"Ẁ";s:3:"ẁ";s:3:"ẁ";s:3:"Ẃ";s:3:"Ẃ";s:3:"ẃ";s:3:"ẃ";s:3:"Ẅ";s:3:"Ẅ";s:3:"ẅ";s:3:"ẅ";s:3:"Ẇ";s:3:"Ẇ";s:3:"ẇ";s:3:"ẇ";s:3:"Ẉ";s:3:"Ẉ";s:3:"ẉ";s:3:"ẉ";s:3:"Ẋ";s:3:"Ẋ";s:3:"ẋ";s:3:"ẋ";s:3:"Ẍ";s:3:"Ẍ";s:3:"ẍ";s:3:"ẍ";s:3:"Ẏ";s:3:"Ẏ";s:3:"ẏ";s:3:"ẏ";s:3:"Ẑ";s:3:"Ẑ";s:3:"ẑ";s:3:"ẑ";s:3:"Ẓ";s:3:"Ẓ";s:3:"ẓ";s:3:"ẓ";s:3:"Ẕ";s:3:"Ẕ";s:3:"ẕ";s:3:"ẕ";s:3:"ẖ";s:3:"ẖ";s:3:"ẗ";s:3:"ẗ";s:3:"ẘ";s:3:"ẘ";s:3:"ẙ";s:3:"ẙ";s:3:"ẛ";s:4:"ẛ";s:3:"Ạ";s:3:"Ạ";s:3:"ạ";s:3:"ạ";s:3:"Ả";s:3:"Ả";s:3:"ả";s:3:"ả";s:3:"Ấ";s:5:"Ấ";s:3:"ấ";s:5:"ấ";s:3:"Ầ";s:5:"Ầ";s:3:"ầ";s:5:"ầ";s:3:"Ẩ";s:5:"Ẩ";s:3:"ẩ";s:5:"ẩ";s:3:"Ẫ";s:5:"Ẫ";s:3:"ẫ";s:5:"ẫ";s:3:"Ậ";s:5:"Ậ";s:3:"ậ";s:5:"ậ";s:3:"Ắ";s:5:"Ắ";s:3:"ắ";s:5:"ắ";s:3:"Ằ";s:5:"Ằ";s:3:"ằ";s:5:"ằ";s:3:"Ẳ";s:5:"Ẳ";s:3:"ẳ";s:5:"ẳ";s:3:"Ẵ";s:5:"Ẵ";s:3:"ẵ";s:5:"ẵ";s:3:"Ặ";s:5:"Ặ";s:3:"ặ";s:5:"ặ";s:3:"Ẹ";s:3:"Ẹ";s:3:"ẹ";s:3:"ẹ";s:3:"Ẻ";s:3:"Ẻ";s:3:"ẻ";s:3:"ẻ";s:3:"Ẽ";s:3:"Ẽ";s:3:"ẽ";s:3:"ẽ";s:3:"Ế";s:5:"Ế";s:3:"ế";s:5:"ế";s:3:"Ề";s:5:"Ề";s:3:"ề";s:5:"ề";s:3:"Ể";s:5:"Ể";s:3:"ể";s:5:"ể";s:3:"Ễ";s:5:"Ễ";s:3:"ễ";s:5:"ễ";s:3:"Ệ";s:5:"Ệ";s:3:"ệ";s:5:"ệ";s:3:"Ỉ";s:3:"Ỉ";s:3:"ỉ";s:3:"ỉ";s:3:"Ị";s:3:"Ị";s:3:"ị";s:3:"ị";s:3:"Ọ";s:3:"Ọ";s:3:"ọ";s:3:"ọ";s:3:"Ỏ";s:3:"Ỏ";s:3:"ỏ";s:3:"ỏ";s:3:"Ố";s:5:"Ố";s:3:"ố";s:5:"ố";s:3:"Ồ";s:5:"Ồ";s:3:"ồ";s:5:"ồ";s:3:"Ổ";s:5:"Ổ";s:3:"ổ";s:5:"ổ";s:3:"Ỗ";s:5:"Ỗ";s:3:"ỗ";s:5:"ỗ";s:3:"Ộ";s:5:"Ộ";s:3:"ộ";s:5:"ộ";s:3:"Ớ";s:5:"Ớ";s:3:"ớ";s:5:"ớ";s:3:"Ờ";s:5:"Ờ";s:3:"ờ";s:5:"ờ";s:3:"Ở";s:5:"Ở";s:3:"ở";s:5:"ở";s:3:"Ỡ";s:5:"Ỡ";s:3:"ỡ";s:5:"ỡ";s:3:"Ợ";s:5:"Ợ";s:3:"ợ";s:5:"ợ";s:3:"Ụ";s:3:"Ụ";s:3:"ụ";s:3:"ụ";s:3:"Ủ";s:3:"Ủ";s:3:"ủ";s:3:"ủ";s:3:"Ứ";s:5:"Ứ";s:3:"ứ";s:5:"ứ";s:3:"Ừ";s:5:"Ừ";s:3:"ừ";s:5:"ừ";s:3:"Ử";s:5:"Ử";s:3:"ử";s:5:"ử";s:3:"Ữ";s:5:"Ữ";s:3:"ữ";s:5:"ữ";s:3:"Ự";s:5:"Ự";s:3:"ự";s:5:"ự";s:3:"Ỳ";s:3:"Ỳ";s:3:"ỳ";s:3:"ỳ";s:3:"Ỵ";s:3:"Ỵ";s:3:"ỵ";s:3:"ỵ";s:3:"Ỷ";s:3:"Ỷ";s:3:"ỷ";s:3:"ỷ";s:3:"Ỹ";s:3:"Ỹ";s:3:"ỹ";s:3:"ỹ";s:3:"ἀ";s:4:"ἀ";s:3:"ἁ";s:4:"ἁ";s:3:"ἂ";s:6:"ἂ";s:3:"ἃ";s:6:"ἃ";s:3:"ἄ";s:6:"ἄ";s:3:"ἅ";s:6:"ἅ";s:3:"ἆ";s:6:"ἆ";s:3:"ἇ";s:6:"ἇ";s:3:"Ἀ";s:4:"Ἀ";s:3:"Ἁ";s:4:"Ἁ";s:3:"Ἂ";s:6:"Ἂ";s:3:"Ἃ";s:6:"Ἃ";s:3:"Ἄ";s:6:"Ἄ";s:3:"Ἅ";s:6:"Ἅ";s:3:"Ἆ";s:6:"Ἆ";s:3:"Ἇ";s:6:"Ἇ";s:3:"ἐ";s:4:"ἐ";s:3:"ἑ";s:4:"ἑ";s:3:"ἒ";s:6:"ἒ";s:3:"ἓ";s:6:"ἓ";s:3:"ἔ";s:6:"ἔ";s:3:"ἕ";s:6:"ἕ";s:3:"Ἐ";s:4:"Ἐ";s:3:"Ἑ";s:4:"Ἑ";s:3:"Ἒ";s:6:"Ἒ";s:3:"Ἓ";s:6:"Ἓ";s:3:"Ἔ";s:6:"Ἔ";s:3:"Ἕ";s:6:"Ἕ";s:3:"ἠ";s:4:"ἠ";s:3:"ἡ";s:4:"ἡ";s:3:"ἢ";s:6:"ἢ";s:3:"ἣ";s:6:"ἣ";s:3:"ἤ";s:6:"ἤ";s:3:"ἥ";s:6:"ἥ";s:3:"ἦ";s:6:"ἦ";s:3:"ἧ";s:6:"ἧ";s:3:"Ἠ";s:4:"Ἠ";s:3:"Ἡ";s:4:"Ἡ";s:3:"Ἢ";s:6:"Ἢ";s:3:"Ἣ";s:6:"Ἣ";s:3:"Ἤ";s:6:"Ἤ";s:3:"Ἥ";s:6:"Ἥ";s:3:"Ἦ";s:6:"Ἦ";s:3:"Ἧ";s:6:"Ἧ";s:3:"ἰ";s:4:"ἰ";s:3:"ἱ";s:4:"ἱ";s:3:"ἲ";s:6:"ἲ";s:3:"ἳ";s:6:"ἳ";s:3:"ἴ";s:6:"ἴ";s:3:"ἵ";s:6:"ἵ";s:3:"ἶ";s:6:"ἶ";s:3:"ἷ";s:6:"ἷ";s:3:"Ἰ";s:4:"Ἰ";s:3:"Ἱ";s:4:"Ἱ";s:3:"Ἲ";s:6:"Ἲ";s:3:"Ἳ";s:6:"Ἳ";s:3:"Ἴ";s:6:"Ἴ";s:3:"Ἵ";s:6:"Ἵ";s:3:"Ἶ";s:6:"Ἶ";s:3:"Ἷ";s:6:"Ἷ";s:3:"ὀ";s:4:"ὀ";s:3:"ὁ";s:4:"ὁ";s:3:"ὂ";s:6:"ὂ";s:3:"ὃ";s:6:"ὃ";s:3:"ὄ";s:6:"ὄ";s:3:"ὅ";s:6:"ὅ";s:3:"Ὀ";s:4:"Ὀ";s:3:"Ὁ";s:4:"Ὁ";s:3:"Ὂ";s:6:"Ὂ";s:3:"Ὃ";s:6:"Ὃ";s:3:"Ὄ";s:6:"Ὄ";s:3:"Ὅ";s:6:"Ὅ";s:3:"ὐ";s:4:"ὐ";s:3:"ὑ";s:4:"ὑ";s:3:"ὒ";s:6:"ὒ";s:3:"ὓ";s:6:"ὓ";s:3:"ὔ";s:6:"ὔ";s:3:"ὕ";s:6:"ὕ";s:3:"ὖ";s:6:"ὖ";s:3:"ὗ";s:6:"ὗ";s:3:"Ὑ";s:4:"Ὑ";s:3:"Ὓ";s:6:"Ὓ";s:3:"Ὕ";s:6:"Ὕ";s:3:"Ὗ";s:6:"Ὗ";s:3:"ὠ";s:4:"ὠ";s:3:"ὡ";s:4:"ὡ";s:3:"ὢ";s:6:"ὢ";s:3:"ὣ";s:6:"ὣ";s:3:"ὤ";s:6:"ὤ";s:3:"ὥ";s:6:"ὥ";s:3:"ὦ";s:6:"ὦ";s:3:"ὧ";s:6:"ὧ";s:3:"Ὠ";s:4:"Ὠ";s:3:"Ὡ";s:4:"Ὡ";s:3:"Ὢ";s:6:"Ὢ";s:3:"Ὣ";s:6:"Ὣ";s:3:"Ὤ";s:6:"Ὤ";s:3:"Ὥ";s:6:"Ὥ";s:3:"Ὦ";s:6:"Ὦ";s:3:"Ὧ";s:6:"Ὧ";s:3:"ὰ";s:4:"ὰ";s:3:"ά";s:4:"ά";s:3:"ὲ";s:4:"ὲ";s:3:"έ";s:4:"έ";s:3:"ὴ";s:4:"ὴ";s:3:"ή";s:4:"ή";s:3:"ὶ";s:4:"ὶ";s:3:"ί";s:4:"ί";s:3:"ὸ";s:4:"ὸ";s:3:"ό";s:4:"ό";s:3:"ὺ";s:4:"ὺ";s:3:"ύ";s:4:"ύ";s:3:"ὼ";s:4:"ὼ";s:3:"ώ";s:4:"ώ";s:3:"ᾀ";s:6:"ᾀ";s:3:"ᾁ";s:6:"ᾁ";s:3:"ᾂ";s:8:"ᾂ";s:3:"ᾃ";s:8:"ᾃ";s:3:"ᾄ";s:8:"ᾄ";s:3:"ᾅ";s:8:"ᾅ";s:3:"ᾆ";s:8:"ᾆ";s:3:"ᾇ";s:8:"ᾇ";s:3:"ᾈ";s:6:"ᾈ";s:3:"ᾉ";s:6:"ᾉ";s:3:"ᾊ";s:8:"ᾊ";s:3:"ᾋ";s:8:"ᾋ";s:3:"ᾌ";s:8:"ᾌ";s:3:"ᾍ";s:8:"ᾍ";s:3:"ᾎ";s:8:"ᾎ";s:3:"ᾏ";s:8:"ᾏ";s:3:"ᾐ";s:6:"ᾐ";s:3:"ᾑ";s:6:"ᾑ";s:3:"ᾒ";s:8:"ᾒ";s:3:"ᾓ";s:8:"ᾓ";s:3:"ᾔ";s:8:"ᾔ";s:3:"ᾕ";s:8:"ᾕ";s:3:"ᾖ";s:8:"ᾖ";s:3:"ᾗ";s:8:"ᾗ";s:3:"ᾘ";s:6:"ᾘ";s:3:"ᾙ";s:6:"ᾙ";s:3:"ᾚ";s:8:"ᾚ";s:3:"ᾛ";s:8:"ᾛ";s:3:"ᾜ";s:8:"ᾜ";s:3:"ᾝ";s:8:"ᾝ";s:3:"ᾞ";s:8:"ᾞ";s:3:"ᾟ";s:8:"ᾟ";s:3:"ᾠ";s:6:"ᾠ";s:3:"ᾡ";s:6:"ᾡ";s:3:"ᾢ";s:8:"ᾢ";s:3:"ᾣ";s:8:"ᾣ";s:3:"ᾤ";s:8:"ᾤ";s:3:"ᾥ";s:8:"ᾥ";s:3:"ᾦ";s:8:"ᾦ";s:3:"ᾧ";s:8:"ᾧ";s:3:"ᾨ";s:6:"ᾨ";s:3:"ᾩ";s:6:"ᾩ";s:3:"ᾪ";s:8:"ᾪ";s:3:"ᾫ";s:8:"ᾫ";s:3:"ᾬ";s:8:"ᾬ";s:3:"ᾭ";s:8:"ᾭ";s:3:"ᾮ";s:8:"ᾮ";s:3:"ᾯ";s:8:"ᾯ";s:3:"ᾰ";s:4:"ᾰ";s:3:"ᾱ";s:4:"ᾱ";s:3:"ᾲ";s:6:"ᾲ";s:3:"ᾳ";s:4:"ᾳ";s:3:"ᾴ";s:6:"ᾴ";s:3:"ᾶ";s:4:"ᾶ";s:3:"ᾷ";s:6:"ᾷ";s:3:"Ᾰ";s:4:"Ᾰ";s:3:"Ᾱ";s:4:"Ᾱ";s:3:"Ὰ";s:4:"Ὰ";s:3:"Ά";s:4:"Ά";s:3:"ᾼ";s:4:"ᾼ";s:3:"ι";s:2:"ι";s:3:"῁";s:4:"῁";s:3:"ῂ";s:6:"ῂ";s:3:"ῃ";s:4:"ῃ";s:3:"ῄ";s:6:"ῄ";s:3:"ῆ";s:4:"ῆ";s:3:"ῇ";s:6:"ῇ";s:3:"Ὲ";s:4:"Ὲ";s:3:"Έ";s:4:"Έ";s:3:"Ὴ";s:4:"Ὴ";s:3:"Ή";s:4:"Ή";s:3:"ῌ";s:4:"ῌ";s:3:"῍";s:5:"῍";s:3:"῎";s:5:"῎";s:3:"῏";s:5:"῏";s:3:"ῐ";s:4:"ῐ";s:3:"ῑ";s:4:"ῑ";s:3:"ῒ";s:6:"ῒ";s:3:"ΐ";s:6:"ΐ";s:3:"ῖ";s:4:"ῖ";s:3:"ῗ";s:6:"ῗ";s:3:"Ῐ";s:4:"Ῐ";s:3:"Ῑ";s:4:"Ῑ";s:3:"Ὶ";s:4:"Ὶ";s:3:"Ί";s:4:"Ί";s:3:"῝";s:5:"῝";s:3:"῞";s:5:"῞";s:3:"῟";s:5:"῟";s:3:"ῠ";s:4:"ῠ";s:3:"ῡ";s:4:"ῡ";s:3:"ῢ";s:6:"ῢ";s:3:"ΰ";s:6:"ΰ";s:3:"ῤ";s:4:"ῤ";s:3:"ῥ";s:4:"ῥ";s:3:"ῦ";s:4:"ῦ";s:3:"ῧ";s:6:"ῧ";s:3:"Ῠ";s:4:"Ῠ";s:3:"Ῡ";s:4:"Ῡ";s:3:"Ὺ";s:4:"Ὺ";s:3:"Ύ";s:4:"Ύ";s:3:"Ῥ";s:4:"Ῥ";s:3:"῭";s:4:"῭";s:3:"΅";s:4:"΅";s:3:"`";s:1:"`";s:3:"ῲ";s:6:"ῲ";s:3:"ῳ";s:4:"ῳ";s:3:"ῴ";s:6:"ῴ";s:3:"ῶ";s:4:"ῶ";s:3:"ῷ";s:6:"ῷ";s:3:"Ὸ";s:4:"Ὸ";s:3:"Ό";s:4:"Ό";s:3:"Ὼ";s:4:"Ὼ";s:3:"Ώ";s:4:"Ώ";s:3:"ῼ";s:4:"ῼ";s:3:"´";s:2:"´";s:3:" ";s:3:" ";s:3:" ";s:3:" ";s:3:"Ω";s:2:"Ω";s:3:"K";s:1:"K";s:3:"Å";s:3:"Å";s:3:"↚";s:5:"↚";s:3:"↛";s:5:"↛";s:3:"↮";s:5:"↮";s:3:"⇍";s:5:"⇍";s:3:"⇎";s:5:"⇎";s:3:"⇏";s:5:"⇏";s:3:"∄";s:5:"∄";s:3:"∉";s:5:"∉";s:3:"∌";s:5:"∌";s:3:"∤";s:5:"∤";s:3:"∦";s:5:"∦";s:3:"≁";s:5:"≁";s:3:"≄";s:5:"≄";s:3:"≇";s:5:"≇";s:3:"≉";s:5:"≉";s:3:"≠";s:3:"≠";s:3:"≢";s:5:"≢";s:3:"≭";s:5:"≭";s:3:"≮";s:3:"≮";s:3:"≯";s:3:"≯";s:3:"≰";s:5:"≰";s:3:"≱";s:5:"≱";s:3:"≴";s:5:"≴";s:3:"≵";s:5:"≵";s:3:"≸";s:5:"≸";s:3:"≹";s:5:"≹";s:3:"⊀";s:5:"⊀";s:3:"⊁";s:5:"⊁";s:3:"⊄";s:5:"⊄";s:3:"⊅";s:5:"⊅";s:3:"⊈";s:5:"⊈";s:3:"⊉";s:5:"⊉";s:3:"⊬";s:5:"⊬";s:3:"⊭";s:5:"⊭";s:3:"⊮";s:5:"⊮";s:3:"⊯";s:5:"⊯";s:3:"⋠";s:5:"⋠";s:3:"⋡";s:5:"⋡";s:3:"⋢";s:5:"⋢";s:3:"⋣";s:5:"⋣";s:3:"⋪";s:5:"⋪";s:3:"⋫";s:5:"⋫";s:3:"⋬";s:5:"⋬";s:3:"⋭";s:5:"⋭";s:3:"〈";s:3:"〈";s:3:"〉";s:3:"〉";s:3:"⫝̸";s:5:"⫝̸";s:3:"が";s:6:"が";s:3:"ぎ";s:6:"ぎ";s:3:"ぐ";s:6:"ぐ";s:3:"げ";s:6:"げ";s:3:"ご";s:6:"ご";s:3:"ざ";s:6:"ざ";s:3:"じ";s:6:"じ";s:3:"ず";s:6:"ず";s:3:"ぜ";s:6:"ぜ";s:3:"ぞ";s:6:"ぞ";s:3:"だ";s:6:"だ";s:3:"ぢ";s:6:"ぢ";s:3:"づ";s:6:"づ";s:3:"で";s:6:"で";s:3:"ど";s:6:"ど";s:3:"ば";s:6:"ば";s:3:"ぱ";s:6:"ぱ";s:3:"び";s:6:"び";s:3:"ぴ";s:6:"ぴ";s:3:"ぶ";s:6:"ぶ";s:3:"ぷ";s:6:"ぷ";s:3:"べ";s:6:"べ";s:3:"ぺ";s:6:"ぺ";s:3:"ぼ";s:6:"ぼ";s:3:"ぽ";s:6:"ぽ";s:3:"ゔ";s:6:"ゔ";s:3:"ゞ";s:6:"ゞ";s:3:"ガ";s:6:"ガ";s:3:"ギ";s:6:"ギ";s:3:"グ";s:6:"グ";s:3:"ゲ";s:6:"ゲ";s:3:"ゴ";s:6:"ゴ";s:3:"ザ";s:6:"ザ";s:3:"ジ";s:6:"ジ";s:3:"ズ";s:6:"ズ";s:3:"ゼ";s:6:"ゼ";s:3:"ゾ";s:6:"ゾ";s:3:"ダ";s:6:"ダ";s:3:"ヂ";s:6:"ヂ";s:3:"ヅ";s:6:"ヅ";s:3:"デ";s:6:"デ";s:3:"ド";s:6:"ド";s:3:"バ";s:6:"バ";s:3:"パ";s:6:"パ";s:3:"ビ";s:6:"ビ";s:3:"ピ";s:6:"ピ";s:3:"ブ";s:6:"ブ";s:3:"プ";s:6:"プ";s:3:"ベ";s:6:"ベ";s:3:"ペ";s:6:"ペ";s:3:"ボ";s:6:"ボ";s:3:"ポ";s:6:"ポ";s:3:"ヴ";s:6:"ヴ";s:3:"ヷ";s:6:"ヷ";s:3:"ヸ";s:6:"ヸ";s:3:"ヹ";s:6:"ヹ";s:3:"ヺ";s:6:"ヺ";s:3:"ヾ";s:6:"ヾ";s:3:"豈";s:3:"豈";s:3:"更";s:3:"更";s:3:"車";s:3:"車";s:3:"賈";s:3:"賈";s:3:"滑";s:3:"滑";s:3:"串";s:3:"串";s:3:"句";s:3:"句";s:3:"龜";s:3:"龜";s:3:"龜";s:3:"龜";s:3:"契";s:3:"契";s:3:"金";s:3:"金";s:3:"喇";s:3:"喇";s:3:"奈";s:3:"奈";s:3:"懶";s:3:"懶";s:3:"癩";s:3:"癩";s:3:"羅";s:3:"羅";s:3:"蘿";s:3:"蘿";s:3:"螺";s:3:"螺";s:3:"裸";s:3:"裸";s:3:"邏";s:3:"邏";s:3:"樂";s:3:"樂";s:3:"洛";s:3:"洛";s:3:"烙";s:3:"烙";s:3:"珞";s:3:"珞";s:3:"落";s:3:"落";s:3:"酪";s:3:"酪";s:3:"駱";s:3:"駱";s:3:"亂";s:3:"亂";s:3:"卵";s:3:"卵";s:3:"欄";s:3:"欄";s:3:"爛";s:3:"爛";s:3:"蘭";s:3:"蘭";s:3:"鸞";s:3:"鸞";s:3:"嵐";s:3:"嵐";s:3:"濫";s:3:"濫";s:3:"藍";s:3:"藍";s:3:"襤";s:3:"襤";s:3:"拉";s:3:"拉";s:3:"臘";s:3:"臘";s:3:"蠟";s:3:"蠟";s:3:"廊";s:3:"廊";s:3:"朗";s:3:"朗";s:3:"浪";s:3:"浪";s:3:"狼";s:3:"狼";s:3:"郎";s:3:"郎";s:3:"來";s:3:"來";s:3:"冷";s:3:"冷";s:3:"勞";s:3:"勞";s:3:"擄";s:3:"擄";s:3:"櫓";s:3:"櫓";s:3:"爐";s:3:"爐";s:3:"盧";s:3:"盧";s:3:"老";s:3:"老";s:3:"蘆";s:3:"蘆";s:3:"虜";s:3:"虜";s:3:"路";s:3:"路";s:3:"露";s:3:"露";s:3:"魯";s:3:"魯";s:3:"鷺";s:3:"鷺";s:3:"碌";s:3:"碌";s:3:"祿";s:3:"祿";s:3:"綠";s:3:"綠";s:3:"菉";s:3:"菉";s:3:"錄";s:3:"錄";s:3:"鹿";s:3:"鹿";s:3:"論";s:3:"論";s:3:"壟";s:3:"壟";s:3:"弄";s:3:"弄";s:3:"籠";s:3:"籠";s:3:"聾";s:3:"聾";s:3:"牢";s:3:"牢";s:3:"磊";s:3:"磊";s:3:"賂";s:3:"賂";s:3:"雷";s:3:"雷";s:3:"壘";s:3:"壘";s:3:"屢";s:3:"屢";s:3:"樓";s:3:"樓";s:3:"淚";s:3:"淚";s:3:"漏";s:3:"漏";s:3:"累";s:3:"累";s:3:"縷";s:3:"縷";s:3:"陋";s:3:"陋";s:3:"勒";s:3:"勒";s:3:"肋";s:3:"肋";s:3:"凜";s:3:"凜";s:3:"凌";s:3:"凌";s:3:"稜";s:3:"稜";s:3:"綾";s:3:"綾";s:3:"菱";s:3:"菱";s:3:"陵";s:3:"陵";s:3:"讀";s:3:"讀";s:3:"拏";s:3:"拏";s:3:"樂";s:3:"樂";s:3:"諾";s:3:"諾";s:3:"丹";s:3:"丹";s:3:"寧";s:3:"寧";s:3:"怒";s:3:"怒";s:3:"率";s:3:"率";s:3:"異";s:3:"異";s:3:"北";s:3:"北";s:3:"磻";s:3:"磻";s:3:"便";s:3:"便";s:3:"復";s:3:"復";s:3:"不";s:3:"不";s:3:"泌";s:3:"泌";s:3:"數";s:3:"數";s:3:"索";s:3:"索";s:3:"參";s:3:"參";s:3:"塞";s:3:"塞";s:3:"省";s:3:"省";s:3:"葉";s:3:"葉";s:3:"說";s:3:"說";s:3:"殺";s:3:"殺";s:3:"辰";s:3:"辰";s:3:"沈";s:3:"沈";s:3:"拾";s:3:"拾";s:3:"若";s:3:"若";s:3:"掠";s:3:"掠";s:3:"略";s:3:"略";s:3:"亮";s:3:"亮";s:3:"兩";s:3:"兩";s:3:"凉";s:3:"凉";s:3:"梁";s:3:"梁";s:3:"糧";s:3:"糧";s:3:"良";s:3:"良";s:3:"諒";s:3:"諒";s:3:"量";s:3:"量";s:3:"勵";s:3:"勵";s:3:"呂";s:3:"呂";s:3:"女";s:3:"女";s:3:"廬";s:3:"廬";s:3:"旅";s:3:"旅";s:3:"濾";s:3:"濾";s:3:"礪";s:3:"礪";s:3:"閭";s:3:"閭";s:3:"驪";s:3:"驪";s:3:"麗";s:3:"麗";s:3:"黎";s:3:"黎";s:3:"力";s:3:"力";s:3:"曆";s:3:"曆";s:3:"歷";s:3:"歷";s:3:"轢";s:3:"轢";s:3:"年";s:3:"年";s:3:"憐";s:3:"憐";s:3:"戀";s:3:"戀";s:3:"撚";s:3:"撚";s:3:"漣";s:3:"漣";s:3:"煉";s:3:"煉";s:3:"璉";s:3:"璉";s:3:"秊";s:3:"秊";s:3:"練";s:3:"練";s:3:"聯";s:3:"聯";s:3:"輦";s:3:"輦";s:3:"蓮";s:3:"蓮";s:3:"連";s:3:"連";s:3:"鍊";s:3:"鍊";s:3:"列";s:3:"列";s:3:"劣";s:3:"劣";s:3:"咽";s:3:"咽";s:3:"烈";s:3:"烈";s:3:"裂";s:3:"裂";s:3:"說";s:3:"說";s:3:"廉";s:3:"廉";s:3:"念";s:3:"念";s:3:"捻";s:3:"捻";s:3:"殮";s:3:"殮";s:3:"簾";s:3:"簾";s:3:"獵";s:3:"獵";s:3:"令";s:3:"令";s:3:"囹";s:3:"囹";s:3:"寧";s:3:"寧";s:3:"嶺";s:3:"嶺";s:3:"怜";s:3:"怜";s:3:"玲";s:3:"玲";s:3:"瑩";s:3:"瑩";s:3:"羚";s:3:"羚";s:3:"聆";s:3:"聆";s:3:"鈴";s:3:"鈴";s:3:"零";s:3:"零";s:3:"靈";s:3:"靈";s:3:"領";s:3:"領";s:3:"例";s:3:"例";s:3:"禮";s:3:"禮";s:3:"醴";s:3:"醴";s:3:"隸";s:3:"隸";s:3:"惡";s:3:"惡";s:3:"了";s:3:"了";s:3:"僚";s:3:"僚";s:3:"寮";s:3:"寮";s:3:"尿";s:3:"尿";s:3:"料";s:3:"料";s:3:"樂";s:3:"樂";s:3:"燎";s:3:"燎";s:3:"療";s:3:"療";s:3:"蓼";s:3:"蓼";s:3:"遼";s:3:"遼";s:3:"龍";s:3:"龍";s:3:"暈";s:3:"暈";s:3:"阮";s:3:"阮";s:3:"劉";s:3:"劉";s:3:"杻";s:3:"杻";s:3:"柳";s:3:"柳";s:3:"流";s:3:"流";s:3:"溜";s:3:"溜";s:3:"琉";s:3:"琉";s:3:"留";s:3:"留";s:3:"硫";s:3:"硫";s:3:"紐";s:3:"紐";s:3:"類";s:3:"類";s:3:"六";s:3:"六";s:3:"戮";s:3:"戮";s:3:"陸";s:3:"陸";s:3:"倫";s:3:"倫";s:3:"崙";s:3:"崙";s:3:"淪";s:3:"淪";s:3:"輪";s:3:"輪";s:3:"律";s:3:"律";s:3:"慄";s:3:"慄";s:3:"栗";s:3:"栗";s:3:"率";s:3:"率";s:3:"隆";s:3:"隆";s:3:"利";s:3:"利";s:3:"吏";s:3:"吏";s:3:"履";s:3:"履";s:3:"易";s:3:"易";s:3:"李";s:3:"李";s:3:"梨";s:3:"梨";s:3:"泥";s:3:"泥";s:3:"理";s:3:"理";s:3:"痢";s:3:"痢";s:3:"罹";s:3:"罹";s:3:"裏";s:3:"裏";s:3:"裡";s:3:"裡";s:3:"里";s:3:"里";s:3:"離";s:3:"離";s:3:"匿";s:3:"匿";s:3:"溺";s:3:"溺";s:3:"吝";s:3:"吝";s:3:"燐";s:3:"燐";s:3:"璘";s:3:"璘";s:3:"藺";s:3:"藺";s:3:"隣";s:3:"隣";s:3:"鱗";s:3:"鱗";s:3:"麟";s:3:"麟";s:3:"林";s:3:"林";s:3:"淋";s:3:"淋";s:3:"臨";s:3:"臨";s:3:"立";s:3:"立";s:3:"笠";s:3:"笠";s:3:"粒";s:3:"粒";s:3:"狀";s:3:"狀";s:3:"炙";s:3:"炙";s:3:"識";s:3:"識";s:3:"什";s:3:"什";s:3:"茶";s:3:"茶";s:3:"刺";s:3:"刺";s:3:"切";s:3:"切";s:3:"度";s:3:"度";s:3:"拓";s:3:"拓";s:3:"糖";s:3:"糖";s:3:"宅";s:3:"宅";s:3:"洞";s:3:"洞";s:3:"暴";s:3:"暴";s:3:"輻";s:3:"輻";s:3:"行";s:3:"行";s:3:"降";s:3:"降";s:3:"見";s:3:"見";s:3:"廓";s:3:"廓";s:3:"兀";s:3:"兀";s:3:"嗀";s:3:"嗀";s:3:"塚";s:3:"塚";s:3:"晴";s:3:"晴";s:3:"凞";s:3:"凞";s:3:"猪";s:3:"猪";s:3:"益";s:3:"益";s:3:"礼";s:3:"礼";s:3:"神";s:3:"神";s:3:"祥";s:3:"祥";s:3:"福";s:3:"福";s:3:"靖";s:3:"靖";s:3:"精";s:3:"精";s:3:"羽";s:3:"羽";s:3:"蘒";s:3:"蘒";s:3:"諸";s:3:"諸";s:3:"逸";s:3:"逸";s:3:"都";s:3:"都";s:3:"飯";s:3:"飯";s:3:"飼";s:3:"飼";s:3:"館";s:3:"館";s:3:"鶴";s:3:"鶴";s:3:"侮";s:3:"侮";s:3:"僧";s:3:"僧";s:3:"免";s:3:"免";s:3:"勉";s:3:"勉";s:3:"勤";s:3:"勤";s:3:"卑";s:3:"卑";s:3:"喝";s:3:"喝";s:3:"嘆";s:3:"嘆";s:3:"器";s:3:"器";s:3:"塀";s:3:"塀";s:3:"墨";s:3:"墨";s:3:"層";s:3:"層";s:3:"屮";s:3:"屮";s:3:"悔";s:3:"悔";s:3:"慨";s:3:"慨";s:3:"憎";s:3:"憎";s:3:"懲";s:3:"懲";s:3:"敏";s:3:"敏";s:3:"既";s:3:"既";s:3:"暑";s:3:"暑";s:3:"梅";s:3:"梅";s:3:"海";s:3:"海";s:3:"渚";s:3:"渚";s:3:"漢";s:3:"漢";s:3:"煮";s:3:"煮";s:3:"爫";s:3:"爫";s:3:"琢";s:3:"琢";s:3:"碑";s:3:"碑";s:3:"社";s:3:"社";s:3:"祉";s:3:"祉";s:3:"祈";s:3:"祈";s:3:"祐";s:3:"祐";s:3:"祖";s:3:"祖";s:3:"祝";s:3:"祝";s:3:"禍";s:3:"禍";s:3:"禎";s:3:"禎";s:3:"穀";s:3:"穀";s:3:"突";s:3:"突";s:3:"節";s:3:"節";s:3:"練";s:3:"練";s:3:"縉";s:3:"縉";s:3:"繁";s:3:"繁";s:3:"署";s:3:"署";s:3:"者";s:3:"者";s:3:"臭";s:3:"臭";s:3:"艹";s:3:"艹";s:3:"艹";s:3:"艹";s:3:"著";s:3:"著";s:3:"褐";s:3:"褐";s:3:"視";s:3:"視";s:3:"謁";s:3:"謁";s:3:"謹";s:3:"謹";s:3:"賓";s:3:"賓";s:3:"贈";s:3:"贈";s:3:"辶";s:3:"辶";s:3:"逸";s:3:"逸";s:3:"難";s:3:"難";s:3:"響";s:3:"響";s:3:"頻";s:3:"頻";s:3:"並";s:3:"並";s:3:"况";s:3:"况";s:3:"全";s:3:"全";s:3:"侀";s:3:"侀";s:3:"充";s:3:"充";s:3:"冀";s:3:"冀";s:3:"勇";s:3:"勇";s:3:"勺";s:3:"勺";s:3:"喝";s:3:"喝";s:3:"啕";s:3:"啕";s:3:"喙";s:3:"喙";s:3:"嗢";s:3:"嗢";s:3:"塚";s:3:"塚";s:3:"墳";s:3:"墳";s:3:"奄";s:3:"奄";s:3:"奔";s:3:"奔";s:3:"婢";s:3:"婢";s:3:"嬨";s:3:"嬨";s:3:"廒";s:3:"廒";s:3:"廙";s:3:"廙";s:3:"彩";s:3:"彩";s:3:"徭";s:3:"徭";s:3:"惘";s:3:"惘";s:3:"慎";s:3:"慎";s:3:"愈";s:3:"愈";s:3:"憎";s:3:"憎";s:3:"慠";s:3:"慠";s:3:"懲";s:3:"懲";s:3:"戴";s:3:"戴";s:3:"揄";s:3:"揄";s:3:"搜";s:3:"搜";s:3:"摒";s:3:"摒";s:3:"敖";s:3:"敖";s:3:"晴";s:3:"晴";s:3:"朗";s:3:"朗";s:3:"望";s:3:"望";s:3:"杖";s:3:"杖";s:3:"歹";s:3:"歹";s:3:"殺";s:3:"殺";s:3:"流";s:3:"流";s:3:"滛";s:3:"滛";s:3:"滋";s:3:"滋";s:3:"漢";s:3:"漢";s:3:"瀞";s:3:"瀞";s:3:"煮";s:3:"煮";s:3:"瞧";s:3:"瞧";s:3:"爵";s:3:"爵";s:3:"犯";s:3:"犯";s:3:"猪";s:3:"猪";s:3:"瑱";s:3:"瑱";s:3:"甆";s:3:"甆";s:3:"画";s:3:"画";s:3:"瘝";s:3:"瘝";s:3:"瘟";s:3:"瘟";s:3:"益";s:3:"益";s:3:"盛";s:3:"盛";s:3:"直";s:3:"直";s:3:"睊";s:3:"睊";s:3:"着";s:3:"着";s:3:"磌";s:3:"磌";s:3:"窱";s:3:"窱";s:3:"節";s:3:"節";s:3:"类";s:3:"类";s:3:"絛";s:3:"絛";s:3:"練";s:3:"練";s:3:"缾";s:3:"缾";s:3:"者";s:3:"者";s:3:"荒";s:3:"荒";s:3:"華";s:3:"華";s:3:"蝹";s:3:"蝹";s:3:"襁";s:3:"襁";s:3:"覆";s:3:"覆";s:3:"視";s:3:"視";s:3:"調";s:3:"調";s:3:"諸";s:3:"諸";s:3:"請";s:3:"請";s:3:"謁";s:3:"謁";s:3:"諾";s:3:"諾";s:3:"諭";s:3:"諭";s:3:"謹";s:3:"謹";s:3:"變";s:3:"變";s:3:"贈";s:3:"贈";s:3:"輸";s:3:"輸";s:3:"遲";s:3:"遲";s:3:"醙";s:3:"醙";s:3:"鉶";s:3:"鉶";s:3:"陼";s:3:"陼";s:3:"難";s:3:"難";s:3:"靖";s:3:"靖";s:3:"韛";s:3:"韛";s:3:"響";s:3:"響";s:3:"頋";s:3:"頋";s:3:"頻";s:3:"頻";s:3:"鬒";s:3:"鬒";s:3:"龜";s:3:"龜";s:3:"𢡊";s:4:"𢡊";s:3:"𢡄";s:4:"𢡄";s:3:"𣏕";s:4:"𣏕";s:3:"㮝";s:3:"㮝";s:3:"䀘";s:3:"䀘";s:3:"䀹";s:3:"䀹";s:3:"𥉉";s:4:"𥉉";s:3:"𥳐";s:4:"𥳐";s:3:"𧻓";s:4:"𧻓";s:3:"齃";s:3:"齃";s:3:"龎";s:3:"龎";s:3:"יִ";s:4:"יִ";s:3:"ײַ";s:4:"ײַ";s:3:"שׁ";s:4:"שׁ";s:3:"שׂ";s:4:"שׂ";s:3:"שּׁ";s:6:"שּׁ";s:3:"שּׂ";s:6:"שּׂ";s:3:"אַ";s:4:"אַ";s:3:"אָ";s:4:"אָ";s:3:"אּ";s:4:"אּ";s:3:"בּ";s:4:"בּ";s:3:"גּ";s:4:"גּ";s:3:"דּ";s:4:"דּ";s:3:"הּ";s:4:"הּ";s:3:"וּ";s:4:"וּ";s:3:"זּ";s:4:"זּ";s:3:"טּ";s:4:"טּ";s:3:"יּ";s:4:"יּ";s:3:"ךּ";s:4:"ךּ";s:3:"כּ";s:4:"כּ";s:3:"לּ";s:4:"לּ";s:3:"מּ";s:4:"מּ";s:3:"נּ";s:4:"נּ";s:3:"סּ";s:4:"סּ";s:3:"ףּ";s:4:"ףּ";s:3:"פּ";s:4:"פּ";s:3:"צּ";s:4:"צּ";s:3:"קּ";s:4:"קּ";s:3:"רּ";s:4:"רּ";s:3:"שּ";s:4:"שּ";s:3:"תּ";s:4:"תּ";s:3:"וֹ";s:4:"וֹ";s:3:"בֿ";s:4:"בֿ";s:3:"כֿ";s:4:"כֿ";s:3:"פֿ";s:4:"פֿ";s:4:"𝅗𝅥";s:8:"𝅗𝅥";s:4:"𝅘𝅥";s:8:"𝅘𝅥";s:4:"𝅘𝅥𝅮";s:12:"𝅘𝅥𝅮";s:4:"𝅘𝅥𝅯";s:12:"𝅘𝅥𝅯";s:4:"𝅘𝅥𝅰";s:12:"𝅘𝅥𝅰";s:4:"𝅘𝅥𝅱";s:12:"𝅘𝅥𝅱";s:4:"𝅘𝅥𝅲";s:12:"𝅘𝅥𝅲";s:4:"𝆹𝅥";s:8:"𝆹𝅥";s:4:"𝆺𝅥";s:8:"𝆺𝅥";s:4:"𝆹𝅥𝅮";s:12:"𝆹𝅥𝅮";s:4:"𝆺𝅥𝅮";s:12:"𝆺𝅥𝅮";s:4:"𝆹𝅥𝅯";s:12:"𝆹𝅥𝅯";s:4:"𝆺𝅥𝅯";s:12:"𝆺𝅥𝅯";s:4:"丽";s:3:"丽";s:4:"丸";s:3:"丸";s:4:"乁";s:3:"乁";s:4:"𠄢";s:4:"𠄢";s:4:"你";s:3:"你";s:4:"侮";s:3:"侮";s:4:"侻";s:3:"侻";s:4:"倂";s:3:"倂";s:4:"偺";s:3:"偺";s:4:"備";s:3:"備";s:4:"僧";s:3:"僧";s:4:"像";s:3:"像";s:4:"㒞";s:3:"㒞";s:4:"𠘺";s:4:"𠘺";s:4:"免";s:3:"免";s:4:"兔";s:3:"兔";s:4:"兤";s:3:"兤";s:4:"具";s:3:"具";s:4:"𠔜";s:4:"𠔜";s:4:"㒹";s:3:"㒹";s:4:"內";s:3:"內";s:4:"再";s:3:"再";s:4:"𠕋";s:4:"𠕋";s:4:"冗";s:3:"冗";s:4:"冤";s:3:"冤";s:4:"仌";s:3:"仌";s:4:"冬";s:3:"冬";s:4:"况";s:3:"况";s:4:"𩇟";s:4:"𩇟";s:4:"凵";s:3:"凵";s:4:"刃";s:3:"刃";s:4:"㓟";s:3:"㓟";s:4:"刻";s:3:"刻";s:4:"剆";s:3:"剆";s:4:"割";s:3:"割";s:4:"剷";s:3:"剷";s:4:"㔕";s:3:"㔕";s:4:"勇";s:3:"勇";s:4:"勉";s:3:"勉";s:4:"勤";s:3:"勤";s:4:"勺";s:3:"勺";s:4:"包";s:3:"包";s:4:"匆";s:3:"匆";s:4:"北";s:3:"北";s:4:"卉";s:3:"卉";s:4:"卑";s:3:"卑";s:4:"博";s:3:"博";s:4:"即";s:3:"即";s:4:"卽";s:3:"卽";s:4:"卿";s:3:"卿";s:4:"卿";s:3:"卿";s:4:"卿";s:3:"卿";s:4:"𠨬";s:4:"𠨬";s:4:"灰";s:3:"灰";s:4:"及";s:3:"及";s:4:"叟";s:3:"叟";s:4:"𠭣";s:4:"𠭣";s:4:"叫";s:3:"叫";s:4:"叱";s:3:"叱";s:4:"吆";s:3:"吆";s:4:"咞";s:3:"咞";s:4:"吸";s:3:"吸";s:4:"呈";s:3:"呈";s:4:"周";s:3:"周";s:4:"咢";s:3:"咢";s:4:"哶";s:3:"哶";s:4:"唐";s:3:"唐";s:4:"啓";s:3:"啓";s:4:"啣";s:3:"啣";s:4:"善";s:3:"善";s:4:"善";s:3:"善";s:4:"喙";s:3:"喙";s:4:"喫";s:3:"喫";s:4:"喳";s:3:"喳";s:4:"嗂";s:3:"嗂";s:4:"圖";s:3:"圖";s:4:"嘆";s:3:"嘆";s:4:"圗";s:3:"圗";s:4:"噑";s:3:"噑";s:4:"噴";s:3:"噴";s:4:"切";s:3:"切";s:4:"壮";s:3:"壮";s:4:"城";s:3:"城";s:4:"埴";s:3:"埴";s:4:"堍";s:3:"堍";s:4:"型";s:3:"型";s:4:"堲";s:3:"堲";s:4:"報";s:3:"報";s:4:"墬";s:3:"墬";s:4:"𡓤";s:4:"𡓤";s:4:"売";s:3:"売";s:4:"壷";s:3:"壷";s:4:"夆";s:3:"夆";s:4:"多";s:3:"多";s:4:"夢";s:3:"夢";s:4:"奢";s:3:"奢";s:4:"𡚨";s:4:"𡚨";s:4:"𡛪";s:4:"𡛪";s:4:"姬";s:3:"姬";s:4:"娛";s:3:"娛";s:4:"娧";s:3:"娧";s:4:"姘";s:3:"姘";s:4:"婦";s:3:"婦";s:4:"㛮";s:3:"㛮";s:4:"㛼";s:3:"㛼";s:4:"嬈";s:3:"嬈";s:4:"嬾";s:3:"嬾";s:4:"嬾";s:3:"嬾";s:4:"𡧈";s:4:"𡧈";s:4:"寃";s:3:"寃";s:4:"寘";s:3:"寘";s:4:"寧";s:3:"寧";s:4:"寳";s:3:"寳";s:4:"𡬘";s:4:"𡬘";s:4:"寿";s:3:"寿";s:4:"将";s:3:"将";s:4:"当";s:3:"当";s:4:"尢";s:3:"尢";s:4:"㞁";s:3:"㞁";s:4:"屠";s:3:"屠";s:4:"屮";s:3:"屮";s:4:"峀";s:3:"峀";s:4:"岍";s:3:"岍";s:4:"𡷤";s:4:"𡷤";s:4:"嵃";s:3:"嵃";s:4:"𡷦";s:4:"𡷦";s:4:"嵮";s:3:"嵮";s:4:"嵫";s:3:"嵫";s:4:"嵼";s:3:"嵼";s:4:"巡";s:3:"巡";s:4:"巢";s:3:"巢";s:4:"㠯";s:3:"㠯";s:4:"巽";s:3:"巽";s:4:"帨";s:3:"帨";s:4:"帽";s:3:"帽";s:4:"幩";s:3:"幩";s:4:"㡢";s:3:"㡢";s:4:"𢆃";s:4:"𢆃";s:4:"㡼";s:3:"㡼";s:4:"庰";s:3:"庰";s:4:"庳";s:3:"庳";s:4:"庶";s:3:"庶";s:4:"廊";s:3:"廊";s:4:"𪎒";s:4:"𪎒";s:4:"廾";s:3:"廾";s:4:"𢌱";s:4:"𢌱";s:4:"𢌱";s:4:"𢌱";s:4:"舁";s:3:"舁";s:4:"弢";s:3:"弢";s:4:"弢";s:3:"弢";s:4:"㣇";s:3:"㣇";s:4:"𣊸";s:4:"𣊸";s:4:"𦇚";s:4:"𦇚";s:4:"形";s:3:"形";s:4:"彫";s:3:"彫";s:4:"㣣";s:3:"㣣";s:4:"徚";s:3:"徚";s:4:"忍";s:3:"忍";s:4:"志";s:3:"志";s:4:"忹";s:3:"忹";s:4:"悁";s:3:"悁";s:4:"㤺";s:3:"㤺";s:4:"㤜";s:3:"㤜";s:4:"悔";s:3:"悔";s:4:"𢛔";s:4:"𢛔";s:4:"惇";s:3:"惇";s:4:"慈";s:3:"慈";s:4:"慌";s:3:"慌";s:4:"慎";s:3:"慎";s:4:"慌";s:3:"慌";s:4:"慺";s:3:"慺";s:4:"憎";s:3:"憎";s:4:"憲";s:3:"憲";s:4:"憤";s:3:"憤";s:4:"憯";s:3:"憯";s:4:"懞";s:3:"懞";s:4:"懲";s:3:"懲";s:4:"懶";s:3:"懶";s:4:"成";s:3:"成";s:4:"戛";s:3:"戛";s:4:"扝";s:3:"扝";s:4:"抱";s:3:"抱";s:4:"拔";s:3:"拔";s:4:"捐";s:3:"捐";s:4:"𢬌";s:4:"𢬌";s:4:"挽";s:3:"挽";s:4:"拼";s:3:"拼";s:4:"捨";s:3:"捨";s:4:"掃";s:3:"掃";s:4:"揤";s:3:"揤";s:4:"𢯱";s:4:"𢯱";s:4:"搢";s:3:"搢";s:4:"揅";s:3:"揅";s:4:"掩";s:3:"掩";s:4:"㨮";s:3:"㨮";s:4:"摩";s:3:"摩";s:4:"摾";s:3:"摾";s:4:"撝";s:3:"撝";s:4:"摷";s:3:"摷";s:4:"㩬";s:3:"㩬";s:4:"敏";s:3:"敏";s:4:"敬";s:3:"敬";s:4:"𣀊";s:4:"𣀊";s:4:"旣";s:3:"旣";s:4:"書";s:3:"書";s:4:"晉";s:3:"晉";s:4:"㬙";s:3:"㬙";s:4:"暑";s:3:"暑";s:4:"㬈";s:3:"㬈";s:4:"㫤";s:3:"㫤";s:4:"冒";s:3:"冒";s:4:"冕";s:3:"冕";s:4:"最";s:3:"最";s:4:"暜";s:3:"暜";s:4:"肭";s:3:"肭";s:4:"䏙";s:3:"䏙";s:4:"朗";s:3:"朗";s:4:"望";s:3:"望";s:4:"朡";s:3:"朡";s:4:"杞";s:3:"杞";s:4:"杓";s:3:"杓";s:4:"𣏃";s:4:"𣏃";s:4:"㭉";s:3:"㭉";s:4:"柺";s:3:"柺";s:4:"枅";s:3:"枅";s:4:"桒";s:3:"桒";s:4:"梅";s:3:"梅";s:4:"𣑭";s:4:"𣑭";s:4:"梎";s:3:"梎";s:4:"栟";s:3:"栟";s:4:"椔";s:3:"椔";s:4:"㮝";s:3:"㮝";s:4:"楂";s:3:"楂";s:4:"榣";s:3:"榣";s:4:"槪";s:3:"槪";s:4:"檨";s:3:"檨";s:4:"𣚣";s:4:"𣚣";s:4:"櫛";s:3:"櫛";s:4:"㰘";s:3:"㰘";s:4:"次";s:3:"次";s:4:"𣢧";s:4:"𣢧";s:4:"歔";s:3:"歔";s:4:"㱎";s:3:"㱎";s:4:"歲";s:3:"歲";s:4:"殟";s:3:"殟";s:4:"殺";s:3:"殺";s:4:"殻";s:3:"殻";s:4:"𣪍";s:4:"𣪍";s:4:"𡴋";s:4:"𡴋";s:4:"𣫺";s:4:"𣫺";s:4:"汎";s:3:"汎";s:4:"𣲼";s:4:"𣲼";s:4:"沿";s:3:"沿";s:4:"泍";s:3:"泍";s:4:"汧";s:3:"汧";s:4:"洖";s:3:"洖";s:4:"派";s:3:"派";s:4:"海";s:3:"海";s:4:"流";s:3:"流";s:4:"浩";s:3:"浩";s:4:"浸";s:3:"浸";s:4:"涅";s:3:"涅";s:4:"𣴞";s:4:"𣴞";s:4:"洴";s:3:"洴";s:4:"港";s:3:"港";s:4:"湮";s:3:"湮";s:4:"㴳";s:3:"㴳";s:4:"滋";s:3:"滋";s:4:"滇";s:3:"滇";s:4:"𣻑";s:4:"𣻑";s:4:"淹";s:3:"淹";s:4:"潮";s:3:"潮";s:4:"𣽞";s:4:"𣽞";s:4:"𣾎";s:4:"𣾎";s:4:"濆";s:3:"濆";s:4:"瀹";s:3:"瀹";s:4:"瀞";s:3:"瀞";s:4:"瀛";s:3:"瀛";s:4:"㶖";s:3:"㶖";s:4:"灊";s:3:"灊";s:4:"災";s:3:"災";s:4:"灷";s:3:"灷";s:4:"炭";s:3:"炭";s:4:"𠔥";s:4:"𠔥";s:4:"煅";s:3:"煅";s:4:"𤉣";s:4:"𤉣";s:4:"熜";s:3:"熜";s:4:"𤎫";s:4:"𤎫";s:4:"爨";s:3:"爨";s:4:"爵";s:3:"爵";s:4:"牐";s:3:"牐";s:4:"𤘈";s:4:"𤘈";s:4:"犀";s:3:"犀";s:4:"犕";s:3:"犕";s:4:"𤜵";s:4:"𤜵";s:4:"𤠔";s:4:"𤠔";s:4:"獺";s:3:"獺";s:4:"王";s:3:"王";s:4:"㺬";s:3:"㺬";s:4:"玥";s:3:"玥";s:4:"㺸";s:3:"㺸";s:4:"㺸";s:3:"㺸";s:4:"瑇";s:3:"瑇";s:4:"瑜";s:3:"瑜";s:4:"瑱";s:3:"瑱";s:4:"璅";s:3:"璅";s:4:"瓊";s:3:"瓊";s:4:"㼛";s:3:"㼛";s:4:"甤";s:3:"甤";s:4:"𤰶";s:4:"𤰶";s:4:"甾";s:3:"甾";s:4:"𤲒";s:4:"𤲒";s:4:"異";s:3:"異";s:4:"𢆟";s:4:"𢆟";s:4:"瘐";s:3:"瘐";s:4:"𤾡";s:4:"𤾡";s:4:"𤾸";s:4:"𤾸";s:4:"𥁄";s:4:"𥁄";s:4:"㿼";s:3:"㿼";s:4:"䀈";s:3:"䀈";s:4:"直";s:3:"直";s:4:"𥃳";s:4:"𥃳";s:4:"𥃲";s:4:"𥃲";s:4:"𥄙";s:4:"𥄙";s:4:"𥄳";s:4:"𥄳";s:4:"眞";s:3:"眞";s:4:"真";s:3:"真";s:4:"真";s:3:"真";s:4:"睊";s:3:"睊";s:4:"䀹";s:3:"䀹";s:4:"瞋";s:3:"瞋";s:4:"䁆";s:3:"䁆";s:4:"䂖";s:3:"䂖";s:4:"𥐝";s:4:"𥐝";s:4:"硎";s:3:"硎";s:4:"碌";s:3:"碌";s:4:"磌";s:3:"磌";s:4:"䃣";s:3:"䃣";s:4:"𥘦";s:4:"𥘦";s:4:"祖";s:3:"祖";s:4:"𥚚";s:4:"𥚚";s:4:"𥛅";s:4:"𥛅";s:4:"福";s:3:"福";s:4:"秫";s:3:"秫";s:4:"䄯";s:3:"䄯";s:4:"穀";s:3:"穀";s:4:"穊";s:3:"穊";s:4:"穏";s:3:"穏";s:4:"𥥼";s:4:"𥥼";s:4:"𥪧";s:4:"𥪧";s:4:"𥪧";s:4:"𥪧";s:4:"竮";s:3:"竮";s:4:"䈂";s:3:"䈂";s:4:"𥮫";s:4:"𥮫";s:4:"篆";s:3:"篆";s:4:"築";s:3:"築";s:4:"䈧";s:3:"䈧";s:4:"𥲀";s:4:"𥲀";s:4:"糒";s:3:"糒";s:4:"䊠";s:3:"䊠";s:4:"糨";s:3:"糨";s:4:"糣";s:3:"糣";s:4:"紀";s:3:"紀";s:4:"𥾆";s:4:"𥾆";s:4:"絣";s:3:"絣";s:4:"䌁";s:3:"䌁";s:4:"緇";s:3:"緇";s:4:"縂";s:3:"縂";s:4:"繅";s:3:"繅";s:4:"䌴";s:3:"䌴";s:4:"𦈨";s:4:"𦈨";s:4:"𦉇";s:4:"𦉇";s:4:"䍙";s:3:"䍙";s:4:"𦋙";s:4:"𦋙";s:4:"罺";s:3:"罺";s:4:"𦌾";s:4:"𦌾";s:4:"羕";s:3:"羕";s:4:"翺";s:3:"翺";s:4:"者";s:3:"者";s:4:"𦓚";s:4:"𦓚";s:4:"𦔣";s:4:"𦔣";s:4:"聠";s:3:"聠";s:4:"𦖨";s:4:"𦖨";s:4:"聰";s:3:"聰";s:4:"𣍟";s:4:"𣍟";s:4:"䏕";s:3:"䏕";s:4:"育";s:3:"育";s:4:"脃";s:3:"脃";s:4:"䐋";s:3:"䐋";s:4:"脾";s:3:"脾";s:4:"媵";s:3:"媵";s:4:"𦞧";s:4:"𦞧";s:4:"𦞵";s:4:"𦞵";s:4:"𣎓";s:4:"𣎓";s:4:"𣎜";s:4:"𣎜";s:4:"舁";s:3:"舁";s:4:"舄";s:3:"舄";s:4:"辞";s:3:"辞";s:4:"䑫";s:3:"䑫";s:4:"芑";s:3:"芑";s:4:"芋";s:3:"芋";s:4:"芝";s:3:"芝";s:4:"劳";s:3:"劳";s:4:"花";s:3:"花";s:4:"芳";s:3:"芳";s:4:"芽";s:3:"芽";s:4:"苦";s:3:"苦";s:4:"𦬼";s:4:"𦬼";s:4:"若";s:3:"若";s:4:"茝";s:3:"茝";s:4:"荣";s:3:"荣";s:4:"莭";s:3:"莭";s:4:"茣";s:3:"茣";s:4:"莽";s:3:"莽";s:4:"菧";s:3:"菧";s:4:"著";s:3:"著";s:4:"荓";s:3:"荓";s:4:"菊";s:3:"菊";s:4:"菌";s:3:"菌";s:4:"菜";s:3:"菜";s:4:"𦰶";s:4:"𦰶";s:4:"𦵫";s:4:"𦵫";s:4:"𦳕";s:4:"𦳕";s:4:"䔫";s:3:"䔫";s:4:"蓱";s:3:"蓱";s:4:"蓳";s:3:"蓳";s:4:"蔖";s:3:"蔖";s:4:"𧏊";s:4:"𧏊";s:4:"蕤";s:3:"蕤";s:4:"𦼬";s:4:"𦼬";s:4:"䕝";s:3:"䕝";s:4:"䕡";s:3:"䕡";s:4:"𦾱";s:4:"𦾱";s:4:"𧃒";s:4:"𧃒";s:4:"䕫";s:3:"䕫";s:4:"虐";s:3:"虐";s:4:"虜";s:3:"虜";s:4:"虧";s:3:"虧";s:4:"虩";s:3:"虩";s:4:"蚩";s:3:"蚩";s:4:"蚈";s:3:"蚈";s:4:"蜎";s:3:"蜎";s:4:"蛢";s:3:"蛢";s:4:"蝹";s:3:"蝹";s:4:"蜨";s:3:"蜨";s:4:"蝫";s:3:"蝫";s:4:"螆";s:3:"螆";s:4:"䗗";s:3:"䗗";s:4:"蟡";s:3:"蟡";s:4:"蠁";s:3:"蠁";s:4:"䗹";s:3:"䗹";s:4:"衠";s:3:"衠";s:4:"衣";s:3:"衣";s:4:"𧙧";s:4:"𧙧";s:4:"裗";s:3:"裗";s:4:"裞";s:3:"裞";s:4:"䘵";s:3:"䘵";s:4:"裺";s:3:"裺";s:4:"㒻";s:3:"㒻";s:4:"𧢮";s:4:"𧢮";s:4:"𧥦";s:4:"𧥦";s:4:"䚾";s:3:"䚾";s:4:"䛇";s:3:"䛇";s:4:"誠";s:3:"誠";s:4:"諭";s:3:"諭";s:4:"變";s:3:"變";s:4:"豕";s:3:"豕";s:4:"𧲨";s:4:"𧲨";s:4:"貫";s:3:"貫";s:4:"賁";s:3:"賁";s:4:"贛";s:3:"贛";s:4:"起";s:3:"起";s:4:"𧼯";s:4:"𧼯";s:4:"𠠄";s:4:"𠠄";s:4:"跋";s:3:"跋";s:4:"趼";s:3:"趼";s:4:"跰";s:3:"跰";s:4:"𠣞";s:4:"𠣞";s:4:"軔";s:3:"軔";s:4:"輸";s:3:"輸";s:4:"𨗒";s:4:"𨗒";s:4:"𨗭";s:4:"𨗭";s:4:"邔";s:3:"邔";s:4:"郱";s:3:"郱";s:4:"鄑";s:3:"鄑";s:4:"𨜮";s:4:"𨜮";s:4:"鄛";s:3:"鄛";s:4:"鈸";s:3:"鈸";s:4:"鋗";s:3:"鋗";s:4:"鋘";s:3:"鋘";s:4:"鉼";s:3:"鉼";s:4:"鏹";s:3:"鏹";s:4:"鐕";s:3:"鐕";s:4:"𨯺";s:4:"𨯺";s:4:"開";s:3:"開";s:4:"䦕";s:3:"䦕";s:4:"閷";s:3:"閷";s:4:"𨵷";s:4:"𨵷";s:4:"䧦";s:3:"䧦";s:4:"雃";s:3:"雃";s:4:"嶲";s:3:"嶲";s:4:"霣";s:3:"霣";s:4:"𩅅";s:4:"𩅅";s:4:"𩈚";s:4:"𩈚";s:4:"䩮";s:3:"䩮";s:4:"䩶";s:3:"䩶";s:4:"韠";s:3:"韠";s:4:"𩐊";s:4:"𩐊";s:4:"䪲";s:3:"䪲";s:4:"𩒖";s:4:"𩒖";s:4:"頋";s:3:"頋";s:4:"頋";s:3:"頋";s:4:"頩";s:3:"頩";s:4:"𩖶";s:4:"𩖶";s:4:"飢";s:3:"飢";s:4:"䬳";s:3:"䬳";s:4:"餩";s:3:"餩";s:4:"馧";s:3:"馧";s:4:"駂";s:3:"駂";s:4:"駾";s:3:"駾";s:4:"䯎";s:3:"䯎";s:4:"𩬰";s:4:"𩬰";s:4:"鬒";s:3:"鬒";s:4:"鱀";s:3:"鱀";s:4:"鳽";s:3:"鳽";s:4:"䳎";s:3:"䳎";s:4:"䳭";s:3:"䳭";s:4:"鵧";s:3:"鵧";s:4:"𪃎";s:4:"𪃎";s:4:"䳸";s:3:"䳸";s:4:"𪄅";s:4:"𪄅";s:4:"𪈎";s:4:"𪈎";s:4:"𪊑";s:4:"𪊑";s:4:"麻";s:3:"麻";s:4:"䵖";s:3:"䵖";s:4:"黹";s:3:"黹";s:4:"黾";s:3:"黾";s:4:"鼅";s:3:"鼅";s:4:"鼏";s:3:"鼏";s:4:"鼖";s:3:"鼖";s:4:"鼻";s:3:"鼻";s:4:"𪘀";s:4:"𪘀";}' );
+$utfCheckNFC = unserialize( 'a:1216:{s:2:"̀";s:1:"N";s:2:"́";s:1:"N";s:2:"̓";s:1:"N";s:2:"̈́";s:1:"N";s:2:"ʹ";s:1:"N";s:2:";";s:1:"N";s:2:"·";s:1:"N";s:3:"क़";s:1:"N";s:3:"ख़";s:1:"N";s:3:"ग़";s:1:"N";s:3:"ज़";s:1:"N";s:3:"ड़";s:1:"N";s:3:"ढ़";s:1:"N";s:3:"फ़";s:1:"N";s:3:"य़";s:1:"N";s:3:"ড়";s:1:"N";s:3:"ঢ়";s:1:"N";s:3:"য়";s:1:"N";s:3:"ਲ਼";s:1:"N";s:3:"ਸ਼";s:1:"N";s:3:"ਖ਼";s:1:"N";s:3:"ਗ਼";s:1:"N";s:3:"ਜ਼";s:1:"N";s:3:"ਫ਼";s:1:"N";s:3:"ଡ଼";s:1:"N";s:3:"ଢ଼";s:1:"N";s:3:"གྷ";s:1:"N";s:3:"ཌྷ";s:1:"N";s:3:"དྷ";s:1:"N";s:3:"བྷ";s:1:"N";s:3:"ཛྷ";s:1:"N";s:3:"ཀྵ";s:1:"N";s:3:"ཱི";s:1:"N";s:3:"ཱུ";s:1:"N";s:3:"ྲྀ";s:1:"N";s:3:"ླྀ";s:1:"N";s:3:"ཱྀ";s:1:"N";s:3:"ྒྷ";s:1:"N";s:3:"ྜྷ";s:1:"N";s:3:"ྡྷ";s:1:"N";s:3:"ྦྷ";s:1:"N";s:3:"ྫྷ";s:1:"N";s:3:"ྐྵ";s:1:"N";s:3:"ά";s:1:"N";s:3:"έ";s:1:"N";s:3:"ή";s:1:"N";s:3:"ί";s:1:"N";s:3:"ό";s:1:"N";s:3:"ύ";s:1:"N";s:3:"ώ";s:1:"N";s:3:"Ά";s:1:"N";s:3:"ι";s:1:"N";s:3:"Έ";s:1:"N";s:3:"Ή";s:1:"N";s:3:"ΐ";s:1:"N";s:3:"Ί";s:1:"N";s:3:"ΰ";s:1:"N";s:3:"Ύ";s:1:"N";s:3:"΅";s:1:"N";s:3:"`";s:1:"N";s:3:"Ό";s:1:"N";s:3:"Ώ";s:1:"N";s:3:"´";s:1:"N";s:3:" ";s:1:"N";s:3:" ";s:1:"N";s:3:"Ω";s:1:"N";s:3:"K";s:1:"N";s:3:"Å";s:1:"N";s:3:"〈";s:1:"N";s:3:"〉";s:1:"N";s:3:"⫝̸";s:1:"N";s:3:"豈";s:1:"N";s:3:"更";s:1:"N";s:3:"車";s:1:"N";s:3:"賈";s:1:"N";s:3:"滑";s:1:"N";s:3:"串";s:1:"N";s:3:"句";s:1:"N";s:3:"龜";s:1:"N";s:3:"龜";s:1:"N";s:3:"契";s:1:"N";s:3:"金";s:1:"N";s:3:"喇";s:1:"N";s:3:"奈";s:1:"N";s:3:"懶";s:1:"N";s:3:"癩";s:1:"N";s:3:"羅";s:1:"N";s:3:"蘿";s:1:"N";s:3:"螺";s:1:"N";s:3:"裸";s:1:"N";s:3:"邏";s:1:"N";s:3:"樂";s:1:"N";s:3:"洛";s:1:"N";s:3:"烙";s:1:"N";s:3:"珞";s:1:"N";s:3:"落";s:1:"N";s:3:"酪";s:1:"N";s:3:"駱";s:1:"N";s:3:"亂";s:1:"N";s:3:"卵";s:1:"N";s:3:"欄";s:1:"N";s:3:"爛";s:1:"N";s:3:"蘭";s:1:"N";s:3:"鸞";s:1:"N";s:3:"嵐";s:1:"N";s:3:"濫";s:1:"N";s:3:"藍";s:1:"N";s:3:"襤";s:1:"N";s:3:"拉";s:1:"N";s:3:"臘";s:1:"N";s:3:"蠟";s:1:"N";s:3:"廊";s:1:"N";s:3:"朗";s:1:"N";s:3:"浪";s:1:"N";s:3:"狼";s:1:"N";s:3:"郎";s:1:"N";s:3:"來";s:1:"N";s:3:"冷";s:1:"N";s:3:"勞";s:1:"N";s:3:"擄";s:1:"N";s:3:"櫓";s:1:"N";s:3:"爐";s:1:"N";s:3:"盧";s:1:"N";s:3:"老";s:1:"N";s:3:"蘆";s:1:"N";s:3:"虜";s:1:"N";s:3:"路";s:1:"N";s:3:"露";s:1:"N";s:3:"魯";s:1:"N";s:3:"鷺";s:1:"N";s:3:"碌";s:1:"N";s:3:"祿";s:1:"N";s:3:"綠";s:1:"N";s:3:"菉";s:1:"N";s:3:"錄";s:1:"N";s:3:"鹿";s:1:"N";s:3:"論";s:1:"N";s:3:"壟";s:1:"N";s:3:"弄";s:1:"N";s:3:"籠";s:1:"N";s:3:"聾";s:1:"N";s:3:"牢";s:1:"N";s:3:"磊";s:1:"N";s:3:"賂";s:1:"N";s:3:"雷";s:1:"N";s:3:"壘";s:1:"N";s:3:"屢";s:1:"N";s:3:"樓";s:1:"N";s:3:"淚";s:1:"N";s:3:"漏";s:1:"N";s:3:"累";s:1:"N";s:3:"縷";s:1:"N";s:3:"陋";s:1:"N";s:3:"勒";s:1:"N";s:3:"肋";s:1:"N";s:3:"凜";s:1:"N";s:3:"凌";s:1:"N";s:3:"稜";s:1:"N";s:3:"綾";s:1:"N";s:3:"菱";s:1:"N";s:3:"陵";s:1:"N";s:3:"讀";s:1:"N";s:3:"拏";s:1:"N";s:3:"樂";s:1:"N";s:3:"諾";s:1:"N";s:3:"丹";s:1:"N";s:3:"寧";s:1:"N";s:3:"怒";s:1:"N";s:3:"率";s:1:"N";s:3:"異";s:1:"N";s:3:"北";s:1:"N";s:3:"磻";s:1:"N";s:3:"便";s:1:"N";s:3:"復";s:1:"N";s:3:"不";s:1:"N";s:3:"泌";s:1:"N";s:3:"數";s:1:"N";s:3:"索";s:1:"N";s:3:"參";s:1:"N";s:3:"塞";s:1:"N";s:3:"省";s:1:"N";s:3:"葉";s:1:"N";s:3:"說";s:1:"N";s:3:"殺";s:1:"N";s:3:"辰";s:1:"N";s:3:"沈";s:1:"N";s:3:"拾";s:1:"N";s:3:"若";s:1:"N";s:3:"掠";s:1:"N";s:3:"略";s:1:"N";s:3:"亮";s:1:"N";s:3:"兩";s:1:"N";s:3:"凉";s:1:"N";s:3:"梁";s:1:"N";s:3:"糧";s:1:"N";s:3:"良";s:1:"N";s:3:"諒";s:1:"N";s:3:"量";s:1:"N";s:3:"勵";s:1:"N";s:3:"呂";s:1:"N";s:3:"女";s:1:"N";s:3:"廬";s:1:"N";s:3:"旅";s:1:"N";s:3:"濾";s:1:"N";s:3:"礪";s:1:"N";s:3:"閭";s:1:"N";s:3:"驪";s:1:"N";s:3:"麗";s:1:"N";s:3:"黎";s:1:"N";s:3:"力";s:1:"N";s:3:"曆";s:1:"N";s:3:"歷";s:1:"N";s:3:"轢";s:1:"N";s:3:"年";s:1:"N";s:3:"憐";s:1:"N";s:3:"戀";s:1:"N";s:3:"撚";s:1:"N";s:3:"漣";s:1:"N";s:3:"煉";s:1:"N";s:3:"璉";s:1:"N";s:3:"秊";s:1:"N";s:3:"練";s:1:"N";s:3:"聯";s:1:"N";s:3:"輦";s:1:"N";s:3:"蓮";s:1:"N";s:3:"連";s:1:"N";s:3:"鍊";s:1:"N";s:3:"列";s:1:"N";s:3:"劣";s:1:"N";s:3:"咽";s:1:"N";s:3:"烈";s:1:"N";s:3:"裂";s:1:"N";s:3:"說";s:1:"N";s:3:"廉";s:1:"N";s:3:"念";s:1:"N";s:3:"捻";s:1:"N";s:3:"殮";s:1:"N";s:3:"簾";s:1:"N";s:3:"獵";s:1:"N";s:3:"令";s:1:"N";s:3:"囹";s:1:"N";s:3:"寧";s:1:"N";s:3:"嶺";s:1:"N";s:3:"怜";s:1:"N";s:3:"玲";s:1:"N";s:3:"瑩";s:1:"N";s:3:"羚";s:1:"N";s:3:"聆";s:1:"N";s:3:"鈴";s:1:"N";s:3:"零";s:1:"N";s:3:"靈";s:1:"N";s:3:"領";s:1:"N";s:3:"例";s:1:"N";s:3:"禮";s:1:"N";s:3:"醴";s:1:"N";s:3:"隸";s:1:"N";s:3:"惡";s:1:"N";s:3:"了";s:1:"N";s:3:"僚";s:1:"N";s:3:"寮";s:1:"N";s:3:"尿";s:1:"N";s:3:"料";s:1:"N";s:3:"樂";s:1:"N";s:3:"燎";s:1:"N";s:3:"療";s:1:"N";s:3:"蓼";s:1:"N";s:3:"遼";s:1:"N";s:3:"龍";s:1:"N";s:3:"暈";s:1:"N";s:3:"阮";s:1:"N";s:3:"劉";s:1:"N";s:3:"杻";s:1:"N";s:3:"柳";s:1:"N";s:3:"流";s:1:"N";s:3:"溜";s:1:"N";s:3:"琉";s:1:"N";s:3:"留";s:1:"N";s:3:"硫";s:1:"N";s:3:"紐";s:1:"N";s:3:"類";s:1:"N";s:3:"六";s:1:"N";s:3:"戮";s:1:"N";s:3:"陸";s:1:"N";s:3:"倫";s:1:"N";s:3:"崙";s:1:"N";s:3:"淪";s:1:"N";s:3:"輪";s:1:"N";s:3:"律";s:1:"N";s:3:"慄";s:1:"N";s:3:"栗";s:1:"N";s:3:"率";s:1:"N";s:3:"隆";s:1:"N";s:3:"利";s:1:"N";s:3:"吏";s:1:"N";s:3:"履";s:1:"N";s:3:"易";s:1:"N";s:3:"李";s:1:"N";s:3:"梨";s:1:"N";s:3:"泥";s:1:"N";s:3:"理";s:1:"N";s:3:"痢";s:1:"N";s:3:"罹";s:1:"N";s:3:"裏";s:1:"N";s:3:"裡";s:1:"N";s:3:"里";s:1:"N";s:3:"離";s:1:"N";s:3:"匿";s:1:"N";s:3:"溺";s:1:"N";s:3:"吝";s:1:"N";s:3:"燐";s:1:"N";s:3:"璘";s:1:"N";s:3:"藺";s:1:"N";s:3:"隣";s:1:"N";s:3:"鱗";s:1:"N";s:3:"麟";s:1:"N";s:3:"林";s:1:"N";s:3:"淋";s:1:"N";s:3:"臨";s:1:"N";s:3:"立";s:1:"N";s:3:"笠";s:1:"N";s:3:"粒";s:1:"N";s:3:"狀";s:1:"N";s:3:"炙";s:1:"N";s:3:"識";s:1:"N";s:3:"什";s:1:"N";s:3:"茶";s:1:"N";s:3:"刺";s:1:"N";s:3:"切";s:1:"N";s:3:"度";s:1:"N";s:3:"拓";s:1:"N";s:3:"糖";s:1:"N";s:3:"宅";s:1:"N";s:3:"洞";s:1:"N";s:3:"暴";s:1:"N";s:3:"輻";s:1:"N";s:3:"行";s:1:"N";s:3:"降";s:1:"N";s:3:"見";s:1:"N";s:3:"廓";s:1:"N";s:3:"兀";s:1:"N";s:3:"嗀";s:1:"N";s:3:"塚";s:1:"N";s:3:"晴";s:1:"N";s:3:"凞";s:1:"N";s:3:"猪";s:1:"N";s:3:"益";s:1:"N";s:3:"礼";s:1:"N";s:3:"神";s:1:"N";s:3:"祥";s:1:"N";s:3:"福";s:1:"N";s:3:"靖";s:1:"N";s:3:"精";s:1:"N";s:3:"羽";s:1:"N";s:3:"蘒";s:1:"N";s:3:"諸";s:1:"N";s:3:"逸";s:1:"N";s:3:"都";s:1:"N";s:3:"飯";s:1:"N";s:3:"飼";s:1:"N";s:3:"館";s:1:"N";s:3:"鶴";s:1:"N";s:3:"侮";s:1:"N";s:3:"僧";s:1:"N";s:3:"免";s:1:"N";s:3:"勉";s:1:"N";s:3:"勤";s:1:"N";s:3:"卑";s:1:"N";s:3:"喝";s:1:"N";s:3:"嘆";s:1:"N";s:3:"器";s:1:"N";s:3:"塀";s:1:"N";s:3:"墨";s:1:"N";s:3:"層";s:1:"N";s:3:"屮";s:1:"N";s:3:"悔";s:1:"N";s:3:"慨";s:1:"N";s:3:"憎";s:1:"N";s:3:"懲";s:1:"N";s:3:"敏";s:1:"N";s:3:"既";s:1:"N";s:3:"暑";s:1:"N";s:3:"梅";s:1:"N";s:3:"海";s:1:"N";s:3:"渚";s:1:"N";s:3:"漢";s:1:"N";s:3:"煮";s:1:"N";s:3:"爫";s:1:"N";s:3:"琢";s:1:"N";s:3:"碑";s:1:"N";s:3:"社";s:1:"N";s:3:"祉";s:1:"N";s:3:"祈";s:1:"N";s:3:"祐";s:1:"N";s:3:"祖";s:1:"N";s:3:"祝";s:1:"N";s:3:"禍";s:1:"N";s:3:"禎";s:1:"N";s:3:"穀";s:1:"N";s:3:"突";s:1:"N";s:3:"節";s:1:"N";s:3:"練";s:1:"N";s:3:"縉";s:1:"N";s:3:"繁";s:1:"N";s:3:"署";s:1:"N";s:3:"者";s:1:"N";s:3:"臭";s:1:"N";s:3:"艹";s:1:"N";s:3:"艹";s:1:"N";s:3:"著";s:1:"N";s:3:"褐";s:1:"N";s:3:"視";s:1:"N";s:3:"謁";s:1:"N";s:3:"謹";s:1:"N";s:3:"賓";s:1:"N";s:3:"贈";s:1:"N";s:3:"辶";s:1:"N";s:3:"逸";s:1:"N";s:3:"難";s:1:"N";s:3:"響";s:1:"N";s:3:"頻";s:1:"N";s:3:"並";s:1:"N";s:3:"况";s:1:"N";s:3:"全";s:1:"N";s:3:"侀";s:1:"N";s:3:"充";s:1:"N";s:3:"冀";s:1:"N";s:3:"勇";s:1:"N";s:3:"勺";s:1:"N";s:3:"喝";s:1:"N";s:3:"啕";s:1:"N";s:3:"喙";s:1:"N";s:3:"嗢";s:1:"N";s:3:"塚";s:1:"N";s:3:"墳";s:1:"N";s:3:"奄";s:1:"N";s:3:"奔";s:1:"N";s:3:"婢";s:1:"N";s:3:"嬨";s:1:"N";s:3:"廒";s:1:"N";s:3:"廙";s:1:"N";s:3:"彩";s:1:"N";s:3:"徭";s:1:"N";s:3:"惘";s:1:"N";s:3:"慎";s:1:"N";s:3:"愈";s:1:"N";s:3:"憎";s:1:"N";s:3:"慠";s:1:"N";s:3:"懲";s:1:"N";s:3:"戴";s:1:"N";s:3:"揄";s:1:"N";s:3:"搜";s:1:"N";s:3:"摒";s:1:"N";s:3:"敖";s:1:"N";s:3:"晴";s:1:"N";s:3:"朗";s:1:"N";s:3:"望";s:1:"N";s:3:"杖";s:1:"N";s:3:"歹";s:1:"N";s:3:"殺";s:1:"N";s:3:"流";s:1:"N";s:3:"滛";s:1:"N";s:3:"滋";s:1:"N";s:3:"漢";s:1:"N";s:3:"瀞";s:1:"N";s:3:"煮";s:1:"N";s:3:"瞧";s:1:"N";s:3:"爵";s:1:"N";s:3:"犯";s:1:"N";s:3:"猪";s:1:"N";s:3:"瑱";s:1:"N";s:3:"甆";s:1:"N";s:3:"画";s:1:"N";s:3:"瘝";s:1:"N";s:3:"瘟";s:1:"N";s:3:"益";s:1:"N";s:3:"盛";s:1:"N";s:3:"直";s:1:"N";s:3:"睊";s:1:"N";s:3:"着";s:1:"N";s:3:"磌";s:1:"N";s:3:"窱";s:1:"N";s:3:"節";s:1:"N";s:3:"类";s:1:"N";s:3:"絛";s:1:"N";s:3:"練";s:1:"N";s:3:"缾";s:1:"N";s:3:"者";s:1:"N";s:3:"荒";s:1:"N";s:3:"華";s:1:"N";s:3:"蝹";s:1:"N";s:3:"襁";s:1:"N";s:3:"覆";s:1:"N";s:3:"視";s:1:"N";s:3:"調";s:1:"N";s:3:"諸";s:1:"N";s:3:"請";s:1:"N";s:3:"謁";s:1:"N";s:3:"諾";s:1:"N";s:3:"諭";s:1:"N";s:3:"謹";s:1:"N";s:3:"變";s:1:"N";s:3:"贈";s:1:"N";s:3:"輸";s:1:"N";s:3:"遲";s:1:"N";s:3:"醙";s:1:"N";s:3:"鉶";s:1:"N";s:3:"陼";s:1:"N";s:3:"難";s:1:"N";s:3:"靖";s:1:"N";s:3:"韛";s:1:"N";s:3:"響";s:1:"N";s:3:"頋";s:1:"N";s:3:"頻";s:1:"N";s:3:"鬒";s:1:"N";s:3:"龜";s:1:"N";s:3:"𢡊";s:1:"N";s:3:"𢡄";s:1:"N";s:3:"𣏕";s:1:"N";s:3:"㮝";s:1:"N";s:3:"䀘";s:1:"N";s:3:"䀹";s:1:"N";s:3:"𥉉";s:1:"N";s:3:"𥳐";s:1:"N";s:3:"𧻓";s:1:"N";s:3:"齃";s:1:"N";s:3:"龎";s:1:"N";s:3:"יִ";s:1:"N";s:3:"ײַ";s:1:"N";s:3:"שׁ";s:1:"N";s:3:"שׂ";s:1:"N";s:3:"שּׁ";s:1:"N";s:3:"שּׂ";s:1:"N";s:3:"אַ";s:1:"N";s:3:"אָ";s:1:"N";s:3:"אּ";s:1:"N";s:3:"בּ";s:1:"N";s:3:"גּ";s:1:"N";s:3:"דּ";s:1:"N";s:3:"הּ";s:1:"N";s:3:"וּ";s:1:"N";s:3:"זּ";s:1:"N";s:3:"טּ";s:1:"N";s:3:"יּ";s:1:"N";s:3:"ךּ";s:1:"N";s:3:"כּ";s:1:"N";s:3:"לּ";s:1:"N";s:3:"מּ";s:1:"N";s:3:"נּ";s:1:"N";s:3:"סּ";s:1:"N";s:3:"ףּ";s:1:"N";s:3:"פּ";s:1:"N";s:3:"צּ";s:1:"N";s:3:"קּ";s:1:"N";s:3:"רּ";s:1:"N";s:3:"שּ";s:1:"N";s:3:"תּ";s:1:"N";s:3:"וֹ";s:1:"N";s:3:"בֿ";s:1:"N";s:3:"כֿ";s:1:"N";s:3:"פֿ";s:1:"N";s:4:"𝅗𝅥";s:1:"N";s:4:"𝅘𝅥";s:1:"N";s:4:"𝅘𝅥𝅮";s:1:"N";s:4:"𝅘𝅥𝅯";s:1:"N";s:4:"𝅘𝅥𝅰";s:1:"N";s:4:"𝅘𝅥𝅱";s:1:"N";s:4:"𝅘𝅥𝅲";s:1:"N";s:4:"𝆹𝅥";s:1:"N";s:4:"𝆺𝅥";s:1:"N";s:4:"𝆹𝅥𝅮";s:1:"N";s:4:"𝆺𝅥𝅮";s:1:"N";s:4:"𝆹𝅥𝅯";s:1:"N";s:4:"𝆺𝅥𝅯";s:1:"N";s:4:"丽";s:1:"N";s:4:"丸";s:1:"N";s:4:"乁";s:1:"N";s:4:"𠄢";s:1:"N";s:4:"你";s:1:"N";s:4:"侮";s:1:"N";s:4:"侻";s:1:"N";s:4:"倂";s:1:"N";s:4:"偺";s:1:"N";s:4:"備";s:1:"N";s:4:"僧";s:1:"N";s:4:"像";s:1:"N";s:4:"㒞";s:1:"N";s:4:"𠘺";s:1:"N";s:4:"免";s:1:"N";s:4:"兔";s:1:"N";s:4:"兤";s:1:"N";s:4:"具";s:1:"N";s:4:"𠔜";s:1:"N";s:4:"㒹";s:1:"N";s:4:"內";s:1:"N";s:4:"再";s:1:"N";s:4:"𠕋";s:1:"N";s:4:"冗";s:1:"N";s:4:"冤";s:1:"N";s:4:"仌";s:1:"N";s:4:"冬";s:1:"N";s:4:"况";s:1:"N";s:4:"𩇟";s:1:"N";s:4:"凵";s:1:"N";s:4:"刃";s:1:"N";s:4:"㓟";s:1:"N";s:4:"刻";s:1:"N";s:4:"剆";s:1:"N";s:4:"割";s:1:"N";s:4:"剷";s:1:"N";s:4:"㔕";s:1:"N";s:4:"勇";s:1:"N";s:4:"勉";s:1:"N";s:4:"勤";s:1:"N";s:4:"勺";s:1:"N";s:4:"包";s:1:"N";s:4:"匆";s:1:"N";s:4:"北";s:1:"N";s:4:"卉";s:1:"N";s:4:"卑";s:1:"N";s:4:"博";s:1:"N";s:4:"即";s:1:"N";s:4:"卽";s:1:"N";s:4:"卿";s:1:"N";s:4:"卿";s:1:"N";s:4:"卿";s:1:"N";s:4:"𠨬";s:1:"N";s:4:"灰";s:1:"N";s:4:"及";s:1:"N";s:4:"叟";s:1:"N";s:4:"𠭣";s:1:"N";s:4:"叫";s:1:"N";s:4:"叱";s:1:"N";s:4:"吆";s:1:"N";s:4:"咞";s:1:"N";s:4:"吸";s:1:"N";s:4:"呈";s:1:"N";s:4:"周";s:1:"N";s:4:"咢";s:1:"N";s:4:"哶";s:1:"N";s:4:"唐";s:1:"N";s:4:"啓";s:1:"N";s:4:"啣";s:1:"N";s:4:"善";s:1:"N";s:4:"善";s:1:"N";s:4:"喙";s:1:"N";s:4:"喫";s:1:"N";s:4:"喳";s:1:"N";s:4:"嗂";s:1:"N";s:4:"圖";s:1:"N";s:4:"嘆";s:1:"N";s:4:"圗";s:1:"N";s:4:"噑";s:1:"N";s:4:"噴";s:1:"N";s:4:"切";s:1:"N";s:4:"壮";s:1:"N";s:4:"城";s:1:"N";s:4:"埴";s:1:"N";s:4:"堍";s:1:"N";s:4:"型";s:1:"N";s:4:"堲";s:1:"N";s:4:"報";s:1:"N";s:4:"墬";s:1:"N";s:4:"𡓤";s:1:"N";s:4:"売";s:1:"N";s:4:"壷";s:1:"N";s:4:"夆";s:1:"N";s:4:"多";s:1:"N";s:4:"夢";s:1:"N";s:4:"奢";s:1:"N";s:4:"𡚨";s:1:"N";s:4:"𡛪";s:1:"N";s:4:"姬";s:1:"N";s:4:"娛";s:1:"N";s:4:"娧";s:1:"N";s:4:"姘";s:1:"N";s:4:"婦";s:1:"N";s:4:"㛮";s:1:"N";s:4:"㛼";s:1:"N";s:4:"嬈";s:1:"N";s:4:"嬾";s:1:"N";s:4:"嬾";s:1:"N";s:4:"𡧈";s:1:"N";s:4:"寃";s:1:"N";s:4:"寘";s:1:"N";s:4:"寧";s:1:"N";s:4:"寳";s:1:"N";s:4:"𡬘";s:1:"N";s:4:"寿";s:1:"N";s:4:"将";s:1:"N";s:4:"当";s:1:"N";s:4:"尢";s:1:"N";s:4:"㞁";s:1:"N";s:4:"屠";s:1:"N";s:4:"屮";s:1:"N";s:4:"峀";s:1:"N";s:4:"岍";s:1:"N";s:4:"𡷤";s:1:"N";s:4:"嵃";s:1:"N";s:4:"𡷦";s:1:"N";s:4:"嵮";s:1:"N";s:4:"嵫";s:1:"N";s:4:"嵼";s:1:"N";s:4:"巡";s:1:"N";s:4:"巢";s:1:"N";s:4:"㠯";s:1:"N";s:4:"巽";s:1:"N";s:4:"帨";s:1:"N";s:4:"帽";s:1:"N";s:4:"幩";s:1:"N";s:4:"㡢";s:1:"N";s:4:"𢆃";s:1:"N";s:4:"㡼";s:1:"N";s:4:"庰";s:1:"N";s:4:"庳";s:1:"N";s:4:"庶";s:1:"N";s:4:"廊";s:1:"N";s:4:"𪎒";s:1:"N";s:4:"廾";s:1:"N";s:4:"𢌱";s:1:"N";s:4:"𢌱";s:1:"N";s:4:"舁";s:1:"N";s:4:"弢";s:1:"N";s:4:"弢";s:1:"N";s:4:"㣇";s:1:"N";s:4:"𣊸";s:1:"N";s:4:"𦇚";s:1:"N";s:4:"形";s:1:"N";s:4:"彫";s:1:"N";s:4:"㣣";s:1:"N";s:4:"徚";s:1:"N";s:4:"忍";s:1:"N";s:4:"志";s:1:"N";s:4:"忹";s:1:"N";s:4:"悁";s:1:"N";s:4:"㤺";s:1:"N";s:4:"㤜";s:1:"N";s:4:"悔";s:1:"N";s:4:"𢛔";s:1:"N";s:4:"惇";s:1:"N";s:4:"慈";s:1:"N";s:4:"慌";s:1:"N";s:4:"慎";s:1:"N";s:4:"慌";s:1:"N";s:4:"慺";s:1:"N";s:4:"憎";s:1:"N";s:4:"憲";s:1:"N";s:4:"憤";s:1:"N";s:4:"憯";s:1:"N";s:4:"懞";s:1:"N";s:4:"懲";s:1:"N";s:4:"懶";s:1:"N";s:4:"成";s:1:"N";s:4:"戛";s:1:"N";s:4:"扝";s:1:"N";s:4:"抱";s:1:"N";s:4:"拔";s:1:"N";s:4:"捐";s:1:"N";s:4:"𢬌";s:1:"N";s:4:"挽";s:1:"N";s:4:"拼";s:1:"N";s:4:"捨";s:1:"N";s:4:"掃";s:1:"N";s:4:"揤";s:1:"N";s:4:"𢯱";s:1:"N";s:4:"搢";s:1:"N";s:4:"揅";s:1:"N";s:4:"掩";s:1:"N";s:4:"㨮";s:1:"N";s:4:"摩";s:1:"N";s:4:"摾";s:1:"N";s:4:"撝";s:1:"N";s:4:"摷";s:1:"N";s:4:"㩬";s:1:"N";s:4:"敏";s:1:"N";s:4:"敬";s:1:"N";s:4:"𣀊";s:1:"N";s:4:"旣";s:1:"N";s:4:"書";s:1:"N";s:4:"晉";s:1:"N";s:4:"㬙";s:1:"N";s:4:"暑";s:1:"N";s:4:"㬈";s:1:"N";s:4:"㫤";s:1:"N";s:4:"冒";s:1:"N";s:4:"冕";s:1:"N";s:4:"最";s:1:"N";s:4:"暜";s:1:"N";s:4:"肭";s:1:"N";s:4:"䏙";s:1:"N";s:4:"朗";s:1:"N";s:4:"望";s:1:"N";s:4:"朡";s:1:"N";s:4:"杞";s:1:"N";s:4:"杓";s:1:"N";s:4:"𣏃";s:1:"N";s:4:"㭉";s:1:"N";s:4:"柺";s:1:"N";s:4:"枅";s:1:"N";s:4:"桒";s:1:"N";s:4:"梅";s:1:"N";s:4:"𣑭";s:1:"N";s:4:"梎";s:1:"N";s:4:"栟";s:1:"N";s:4:"椔";s:1:"N";s:4:"㮝";s:1:"N";s:4:"楂";s:1:"N";s:4:"榣";s:1:"N";s:4:"槪";s:1:"N";s:4:"檨";s:1:"N";s:4:"𣚣";s:1:"N";s:4:"櫛";s:1:"N";s:4:"㰘";s:1:"N";s:4:"次";s:1:"N";s:4:"𣢧";s:1:"N";s:4:"歔";s:1:"N";s:4:"㱎";s:1:"N";s:4:"歲";s:1:"N";s:4:"殟";s:1:"N";s:4:"殺";s:1:"N";s:4:"殻";s:1:"N";s:4:"𣪍";s:1:"N";s:4:"𡴋";s:1:"N";s:4:"𣫺";s:1:"N";s:4:"汎";s:1:"N";s:4:"𣲼";s:1:"N";s:4:"沿";s:1:"N";s:4:"泍";s:1:"N";s:4:"汧";s:1:"N";s:4:"洖";s:1:"N";s:4:"派";s:1:"N";s:4:"海";s:1:"N";s:4:"流";s:1:"N";s:4:"浩";s:1:"N";s:4:"浸";s:1:"N";s:4:"涅";s:1:"N";s:4:"𣴞";s:1:"N";s:4:"洴";s:1:"N";s:4:"港";s:1:"N";s:4:"湮";s:1:"N";s:4:"㴳";s:1:"N";s:4:"滋";s:1:"N";s:4:"滇";s:1:"N";s:4:"𣻑";s:1:"N";s:4:"淹";s:1:"N";s:4:"潮";s:1:"N";s:4:"𣽞";s:1:"N";s:4:"𣾎";s:1:"N";s:4:"濆";s:1:"N";s:4:"瀹";s:1:"N";s:4:"瀞";s:1:"N";s:4:"瀛";s:1:"N";s:4:"㶖";s:1:"N";s:4:"灊";s:1:"N";s:4:"災";s:1:"N";s:4:"灷";s:1:"N";s:4:"炭";s:1:"N";s:4:"𠔥";s:1:"N";s:4:"煅";s:1:"N";s:4:"𤉣";s:1:"N";s:4:"熜";s:1:"N";s:4:"𤎫";s:1:"N";s:4:"爨";s:1:"N";s:4:"爵";s:1:"N";s:4:"牐";s:1:"N";s:4:"𤘈";s:1:"N";s:4:"犀";s:1:"N";s:4:"犕";s:1:"N";s:4:"𤜵";s:1:"N";s:4:"𤠔";s:1:"N";s:4:"獺";s:1:"N";s:4:"王";s:1:"N";s:4:"㺬";s:1:"N";s:4:"玥";s:1:"N";s:4:"㺸";s:1:"N";s:4:"㺸";s:1:"N";s:4:"瑇";s:1:"N";s:4:"瑜";s:1:"N";s:4:"瑱";s:1:"N";s:4:"璅";s:1:"N";s:4:"瓊";s:1:"N";s:4:"㼛";s:1:"N";s:4:"甤";s:1:"N";s:4:"𤰶";s:1:"N";s:4:"甾";s:1:"N";s:4:"𤲒";s:1:"N";s:4:"異";s:1:"N";s:4:"𢆟";s:1:"N";s:4:"瘐";s:1:"N";s:4:"𤾡";s:1:"N";s:4:"𤾸";s:1:"N";s:4:"𥁄";s:1:"N";s:4:"㿼";s:1:"N";s:4:"䀈";s:1:"N";s:4:"直";s:1:"N";s:4:"𥃳";s:1:"N";s:4:"𥃲";s:1:"N";s:4:"𥄙";s:1:"N";s:4:"𥄳";s:1:"N";s:4:"眞";s:1:"N";s:4:"真";s:1:"N";s:4:"真";s:1:"N";s:4:"睊";s:1:"N";s:4:"䀹";s:1:"N";s:4:"瞋";s:1:"N";s:4:"䁆";s:1:"N";s:4:"䂖";s:1:"N";s:4:"𥐝";s:1:"N";s:4:"硎";s:1:"N";s:4:"碌";s:1:"N";s:4:"磌";s:1:"N";s:4:"䃣";s:1:"N";s:4:"𥘦";s:1:"N";s:4:"祖";s:1:"N";s:4:"𥚚";s:1:"N";s:4:"𥛅";s:1:"N";s:4:"福";s:1:"N";s:4:"秫";s:1:"N";s:4:"䄯";s:1:"N";s:4:"穀";s:1:"N";s:4:"穊";s:1:"N";s:4:"穏";s:1:"N";s:4:"𥥼";s:1:"N";s:4:"𥪧";s:1:"N";s:4:"𥪧";s:1:"N";s:4:"竮";s:1:"N";s:4:"䈂";s:1:"N";s:4:"𥮫";s:1:"N";s:4:"篆";s:1:"N";s:4:"築";s:1:"N";s:4:"䈧";s:1:"N";s:4:"𥲀";s:1:"N";s:4:"糒";s:1:"N";s:4:"䊠";s:1:"N";s:4:"糨";s:1:"N";s:4:"糣";s:1:"N";s:4:"紀";s:1:"N";s:4:"𥾆";s:1:"N";s:4:"絣";s:1:"N";s:4:"䌁";s:1:"N";s:4:"緇";s:1:"N";s:4:"縂";s:1:"N";s:4:"繅";s:1:"N";s:4:"䌴";s:1:"N";s:4:"𦈨";s:1:"N";s:4:"𦉇";s:1:"N";s:4:"䍙";s:1:"N";s:4:"𦋙";s:1:"N";s:4:"罺";s:1:"N";s:4:"𦌾";s:1:"N";s:4:"羕";s:1:"N";s:4:"翺";s:1:"N";s:4:"者";s:1:"N";s:4:"𦓚";s:1:"N";s:4:"𦔣";s:1:"N";s:4:"聠";s:1:"N";s:4:"𦖨";s:1:"N";s:4:"聰";s:1:"N";s:4:"𣍟";s:1:"N";s:4:"䏕";s:1:"N";s:4:"育";s:1:"N";s:4:"脃";s:1:"N";s:4:"䐋";s:1:"N";s:4:"脾";s:1:"N";s:4:"媵";s:1:"N";s:4:"𦞧";s:1:"N";s:4:"𦞵";s:1:"N";s:4:"𣎓";s:1:"N";s:4:"𣎜";s:1:"N";s:4:"舁";s:1:"N";s:4:"舄";s:1:"N";s:4:"辞";s:1:"N";s:4:"䑫";s:1:"N";s:4:"芑";s:1:"N";s:4:"芋";s:1:"N";s:4:"芝";s:1:"N";s:4:"劳";s:1:"N";s:4:"花";s:1:"N";s:4:"芳";s:1:"N";s:4:"芽";s:1:"N";s:4:"苦";s:1:"N";s:4:"𦬼";s:1:"N";s:4:"若";s:1:"N";s:4:"茝";s:1:"N";s:4:"荣";s:1:"N";s:4:"莭";s:1:"N";s:4:"茣";s:1:"N";s:4:"莽";s:1:"N";s:4:"菧";s:1:"N";s:4:"著";s:1:"N";s:4:"荓";s:1:"N";s:4:"菊";s:1:"N";s:4:"菌";s:1:"N";s:4:"菜";s:1:"N";s:4:"𦰶";s:1:"N";s:4:"𦵫";s:1:"N";s:4:"𦳕";s:1:"N";s:4:"䔫";s:1:"N";s:4:"蓱";s:1:"N";s:4:"蓳";s:1:"N";s:4:"蔖";s:1:"N";s:4:"𧏊";s:1:"N";s:4:"蕤";s:1:"N";s:4:"𦼬";s:1:"N";s:4:"䕝";s:1:"N";s:4:"䕡";s:1:"N";s:4:"𦾱";s:1:"N";s:4:"𧃒";s:1:"N";s:4:"䕫";s:1:"N";s:4:"虐";s:1:"N";s:4:"虜";s:1:"N";s:4:"虧";s:1:"N";s:4:"虩";s:1:"N";s:4:"蚩";s:1:"N";s:4:"蚈";s:1:"N";s:4:"蜎";s:1:"N";s:4:"蛢";s:1:"N";s:4:"蝹";s:1:"N";s:4:"蜨";s:1:"N";s:4:"蝫";s:1:"N";s:4:"螆";s:1:"N";s:4:"䗗";s:1:"N";s:4:"蟡";s:1:"N";s:4:"蠁";s:1:"N";s:4:"䗹";s:1:"N";s:4:"衠";s:1:"N";s:4:"衣";s:1:"N";s:4:"𧙧";s:1:"N";s:4:"裗";s:1:"N";s:4:"裞";s:1:"N";s:4:"䘵";s:1:"N";s:4:"裺";s:1:"N";s:4:"㒻";s:1:"N";s:4:"𧢮";s:1:"N";s:4:"𧥦";s:1:"N";s:4:"䚾";s:1:"N";s:4:"䛇";s:1:"N";s:4:"誠";s:1:"N";s:4:"諭";s:1:"N";s:4:"變";s:1:"N";s:4:"豕";s:1:"N";s:4:"𧲨";s:1:"N";s:4:"貫";s:1:"N";s:4:"賁";s:1:"N";s:4:"贛";s:1:"N";s:4:"起";s:1:"N";s:4:"𧼯";s:1:"N";s:4:"𠠄";s:1:"N";s:4:"跋";s:1:"N";s:4:"趼";s:1:"N";s:4:"跰";s:1:"N";s:4:"𠣞";s:1:"N";s:4:"軔";s:1:"N";s:4:"輸";s:1:"N";s:4:"𨗒";s:1:"N";s:4:"𨗭";s:1:"N";s:4:"邔";s:1:"N";s:4:"郱";s:1:"N";s:4:"鄑";s:1:"N";s:4:"𨜮";s:1:"N";s:4:"鄛";s:1:"N";s:4:"鈸";s:1:"N";s:4:"鋗";s:1:"N";s:4:"鋘";s:1:"N";s:4:"鉼";s:1:"N";s:4:"鏹";s:1:"N";s:4:"鐕";s:1:"N";s:4:"𨯺";s:1:"N";s:4:"開";s:1:"N";s:4:"䦕";s:1:"N";s:4:"閷";s:1:"N";s:4:"𨵷";s:1:"N";s:4:"䧦";s:1:"N";s:4:"雃";s:1:"N";s:4:"嶲";s:1:"N";s:4:"霣";s:1:"N";s:4:"𩅅";s:1:"N";s:4:"𩈚";s:1:"N";s:4:"䩮";s:1:"N";s:4:"䩶";s:1:"N";s:4:"韠";s:1:"N";s:4:"𩐊";s:1:"N";s:4:"䪲";s:1:"N";s:4:"𩒖";s:1:"N";s:4:"頋";s:1:"N";s:4:"頋";s:1:"N";s:4:"頩";s:1:"N";s:4:"𩖶";s:1:"N";s:4:"飢";s:1:"N";s:4:"䬳";s:1:"N";s:4:"餩";s:1:"N";s:4:"馧";s:1:"N";s:4:"駂";s:1:"N";s:4:"駾";s:1:"N";s:4:"䯎";s:1:"N";s:4:"𩬰";s:1:"N";s:4:"鬒";s:1:"N";s:4:"鱀";s:1:"N";s:4:"鳽";s:1:"N";s:4:"䳎";s:1:"N";s:4:"䳭";s:1:"N";s:4:"鵧";s:1:"N";s:4:"𪃎";s:1:"N";s:4:"䳸";s:1:"N";s:4:"𪄅";s:1:"N";s:4:"𪈎";s:1:"N";s:4:"𪊑";s:1:"N";s:4:"麻";s:1:"N";s:4:"䵖";s:1:"N";s:4:"黹";s:1:"N";s:4:"黾";s:1:"N";s:4:"鼅";s:1:"N";s:4:"鼏";s:1:"N";s:4:"鼖";s:1:"N";s:4:"鼻";s:1:"N";s:4:"𪘀";s:1:"N";s:2:"̀";s:1:"M";s:2:"́";s:1:"M";s:2:"̂";s:1:"M";s:2:"̃";s:1:"M";s:2:"̄";s:1:"M";s:2:"̆";s:1:"M";s:2:"̇";s:1:"M";s:2:"̈";s:1:"M";s:2:"̉";s:1:"M";s:2:"̊";s:1:"M";s:2:"̋";s:1:"M";s:2:"̌";s:1:"M";s:2:"̏";s:1:"M";s:2:"̑";s:1:"M";s:2:"̓";s:1:"M";s:2:"̔";s:1:"M";s:2:"̛";s:1:"M";s:2:"̣";s:1:"M";s:2:"̤";s:1:"M";s:2:"̥";s:1:"M";s:2:"̦";s:1:"M";s:2:"̧";s:1:"M";s:2:"̨";s:1:"M";s:2:"̭";s:1:"M";s:2:"̮";s:1:"M";s:2:"̰";s:1:"M";s:2:"̱";s:1:"M";s:2:"̸";s:1:"M";s:2:"͂";s:1:"M";s:2:"ͅ";s:1:"M";s:2:"ٓ";s:1:"M";s:2:"ٔ";s:1:"M";s:2:"ٕ";s:1:"M";s:3:"़";s:1:"M";s:3:"া";s:1:"M";s:3:"ৗ";s:1:"M";s:3:"ା";s:1:"M";s:3:"ୖ";s:1:"M";s:3:"ୗ";s:1:"M";s:3:"ா";s:1:"M";s:3:"ௗ";s:1:"M";s:3:"ౖ";s:1:"M";s:3:"ೂ";s:1:"M";s:3:"ೕ";s:1:"M";s:3:"ೖ";s:1:"M";s:3:"ാ";s:1:"M";s:3:"ൗ";s:1:"M";s:3:"්";s:1:"M";s:3:"ා";s:1:"M";s:3:"ෟ";s:1:"M";s:3:"ီ";s:1:"M";s:3:"ᅡ";s:1:"M";s:3:"ᅢ";s:1:"M";s:3:"ᅣ";s:1:"M";s:3:"ᅤ";s:1:"M";s:3:"ᅥ";s:1:"M";s:3:"ᅦ";s:1:"M";s:3:"ᅧ";s:1:"M";s:3:"ᅨ";s:1:"M";s:3:"ᅩ";s:1:"M";s:3:"ᅪ";s:1:"M";s:3:"ᅫ";s:1:"M";s:3:"ᅬ";s:1:"M";s:3:"ᅭ";s:1:"M";s:3:"ᅮ";s:1:"M";s:3:"ᅯ";s:1:"M";s:3:"ᅰ";s:1:"M";s:3:"ᅱ";s:1:"M";s:3:"ᅲ";s:1:"M";s:3:"ᅳ";s:1:"M";s:3:"ᅴ";s:1:"M";s:3:"ᅵ";s:1:"M";s:3:"ᆨ";s:1:"M";s:3:"ᆩ";s:1:"M";s:3:"ᆪ";s:1:"M";s:3:"ᆫ";s:1:"M";s:3:"ᆬ";s:1:"M";s:3:"ᆭ";s:1:"M";s:3:"ᆮ";s:1:"M";s:3:"ᆯ";s:1:"M";s:3:"ᆰ";s:1:"M";s:3:"ᆱ";s:1:"M";s:3:"ᆲ";s:1:"M";s:3:"ᆳ";s:1:"M";s:3:"ᆴ";s:1:"M";s:3:"ᆵ";s:1:"M";s:3:"ᆶ";s:1:"M";s:3:"ᆷ";s:1:"M";s:3:"ᆸ";s:1:"M";s:3:"ᆹ";s:1:"M";s:3:"ᆺ";s:1:"M";s:3:"ᆻ";s:1:"M";s:3:"ᆼ";s:1:"M";s:3:"ᆽ";s:1:"M";s:3:"ᆾ";s:1:"M";s:3:"ᆿ";s:1:"M";s:3:"ᇀ";s:1:"M";s:3:"ᇁ";s:1:"M";s:3:"ᇂ";s:1:"M";s:3:"゙";s:1:"M";s:3:"゚";s:1:"M";}' );
+?>
diff --git a/includes/normal/UtfNormalDataK.inc b/includes/normal/UtfNormalDataK.inc
new file mode 100644
index 000000000000..0f4cd7a5e775
--- /dev/null
+++ b/includes/normal/UtfNormalDataK.inc
@@ -0,0 +1,10 @@
+<?php
+/**
+ * This file was automatically generated -- do not edit!
+ * Run UtfNormalGenerate.php to create this file again (make clean && make)
+ * @package MediaWiki
+ */
+/** */
+global $utfCompatibilityDecomp;
+$utfCompatibilityDecomp = unserialize( 'a:5389:{s:2:" ";s:1:" ";s:2:"¨";s:3:" ̈";s:2:"ª";s:1:"a";s:2:"¯";s:3:" ̄";s:2:"²";s:1:"2";s:2:"³";s:1:"3";s:2:"´";s:3:" ́";s:2:"µ";s:2:"μ";s:2:"¸";s:3:" ̧";s:2:"¹";s:1:"1";s:2:"º";s:1:"o";s:2:"¼";s:5:"1⁄4";s:2:"½";s:5:"1⁄2";s:2:"¾";s:5:"3⁄4";s:2:"À";s:3:"À";s:2:"Á";s:3:"Á";s:2:"Â";s:3:"Â";s:2:"Ã";s:3:"Ã";s:2:"Ä";s:3:"Ä";s:2:"Å";s:3:"Å";s:2:"Ç";s:3:"Ç";s:2:"È";s:3:"È";s:2:"É";s:3:"É";s:2:"Ê";s:3:"Ê";s:2:"Ë";s:3:"Ë";s:2:"Ì";s:3:"Ì";s:2:"Í";s:3:"Í";s:2:"Î";s:3:"Î";s:2:"Ï";s:3:"Ï";s:2:"Ñ";s:3:"Ñ";s:2:"Ò";s:3:"Ò";s:2:"Ó";s:3:"Ó";s:2:"Ô";s:3:"Ô";s:2:"Õ";s:3:"Õ";s:2:"Ö";s:3:"Ö";s:2:"Ù";s:3:"Ù";s:2:"Ú";s:3:"Ú";s:2:"Û";s:3:"Û";s:2:"Ü";s:3:"Ü";s:2:"Ý";s:3:"Ý";s:2:"à";s:3:"à";s:2:"á";s:3:"á";s:2:"â";s:3:"â";s:2:"ã";s:3:"ã";s:2:"ä";s:3:"ä";s:2:"å";s:3:"å";s:2:"ç";s:3:"ç";s:2:"è";s:3:"è";s:2:"é";s:3:"é";s:2:"ê";s:3:"ê";s:2:"ë";s:3:"ë";s:2:"ì";s:3:"ì";s:2:"í";s:3:"í";s:2:"î";s:3:"î";s:2:"ï";s:3:"ï";s:2:"ñ";s:3:"ñ";s:2:"ò";s:3:"ò";s:2:"ó";s:3:"ó";s:2:"ô";s:3:"ô";s:2:"õ";s:3:"õ";s:2:"ö";s:3:"ö";s:2:"ù";s:3:"ù";s:2:"ú";s:3:"ú";s:2:"û";s:3:"û";s:2:"ü";s:3:"ü";s:2:"ý";s:3:"ý";s:2:"ÿ";s:3:"ÿ";s:2:"Ā";s:3:"Ā";s:2:"ā";s:3:"ā";s:2:"Ă";s:3:"Ă";s:2:"ă";s:3:"ă";s:2:"Ą";s:3:"Ą";s:2:"ą";s:3:"ą";s:2:"Ć";s:3:"Ć";s:2:"ć";s:3:"ć";s:2:"Ĉ";s:3:"Ĉ";s:2:"ĉ";s:3:"ĉ";s:2:"Ċ";s:3:"Ċ";s:2:"ċ";s:3:"ċ";s:2:"Č";s:3:"Č";s:2:"č";s:3:"č";s:2:"Ď";s:3:"Ď";s:2:"ď";s:3:"ď";s:2:"Ē";s:3:"Ē";s:2:"ē";s:3:"ē";s:2:"Ĕ";s:3:"Ĕ";s:2:"ĕ";s:3:"ĕ";s:2:"Ė";s:3:"Ė";s:2:"ė";s:3:"ė";s:2:"Ę";s:3:"Ę";s:2:"ę";s:3:"ę";s:2:"Ě";s:3:"Ě";s:2:"ě";s:3:"ě";s:2:"Ĝ";s:3:"Ĝ";s:2:"ĝ";s:3:"ĝ";s:2:"Ğ";s:3:"Ğ";s:2:"ğ";s:3:"ğ";s:2:"Ġ";s:3:"Ġ";s:2:"ġ";s:3:"ġ";s:2:"Ģ";s:3:"Ģ";s:2:"ģ";s:3:"ģ";s:2:"Ĥ";s:3:"Ĥ";s:2:"ĥ";s:3:"ĥ";s:2:"Ĩ";s:3:"Ĩ";s:2:"ĩ";s:3:"ĩ";s:2:"Ī";s:3:"Ī";s:2:"ī";s:3:"ī";s:2:"Ĭ";s:3:"Ĭ";s:2:"ĭ";s:3:"ĭ";s:2:"Į";s:3:"Į";s:2:"į";s:3:"į";s:2:"İ";s:3:"İ";s:2:"IJ";s:2:"IJ";s:2:"ij";s:2:"ij";s:2:"Ĵ";s:3:"Ĵ";s:2:"ĵ";s:3:"ĵ";s:2:"Ķ";s:3:"Ķ";s:2:"ķ";s:3:"ķ";s:2:"Ĺ";s:3:"Ĺ";s:2:"ĺ";s:3:"ĺ";s:2:"Ļ";s:3:"Ļ";s:2:"ļ";s:3:"ļ";s:2:"Ľ";s:3:"Ľ";s:2:"ľ";s:3:"ľ";s:2:"Ŀ";s:3:"L·";s:2:"ŀ";s:3:"l·";s:2:"Ń";s:3:"Ń";s:2:"ń";s:3:"ń";s:2:"Ņ";s:3:"Ņ";s:2:"ņ";s:3:"ņ";s:2:"Ň";s:3:"Ň";s:2:"ň";s:3:"ň";s:2:"ʼn";s:3:"ʼn";s:2:"Ō";s:3:"Ō";s:2:"ō";s:3:"ō";s:2:"Ŏ";s:3:"Ŏ";s:2:"ŏ";s:3:"ŏ";s:2:"Ő";s:3:"Ő";s:2:"ő";s:3:"ő";s:2:"Ŕ";s:3:"Ŕ";s:2:"ŕ";s:3:"ŕ";s:2:"Ŗ";s:3:"Ŗ";s:2:"ŗ";s:3:"ŗ";s:2:"Ř";s:3:"Ř";s:2:"ř";s:3:"ř";s:2:"Ś";s:3:"Ś";s:2:"ś";s:3:"ś";s:2:"Ŝ";s:3:"Ŝ";s:2:"ŝ";s:3:"ŝ";s:2:"Ş";s:3:"Ş";s:2:"ş";s:3:"ş";s:2:"Š";s:3:"Š";s:2:"š";s:3:"š";s:2:"Ţ";s:3:"Ţ";s:2:"ţ";s:3:"ţ";s:2:"Ť";s:3:"Ť";s:2:"ť";s:3:"ť";s:2:"Ũ";s:3:"Ũ";s:2:"ũ";s:3:"ũ";s:2:"Ū";s:3:"Ū";s:2:"ū";s:3:"ū";s:2:"Ŭ";s:3:"Ŭ";s:2:"ŭ";s:3:"ŭ";s:2:"Ů";s:3:"Ů";s:2:"ů";s:3:"ů";s:2:"Ű";s:3:"Ű";s:2:"ű";s:3:"ű";s:2:"Ų";s:3:"Ų";s:2:"ų";s:3:"ų";s:2:"Ŵ";s:3:"Ŵ";s:2:"ŵ";s:3:"ŵ";s:2:"Ŷ";s:3:"Ŷ";s:2:"ŷ";s:3:"ŷ";s:2:"Ÿ";s:3:"Ÿ";s:2:"Ź";s:3:"Ź";s:2:"ź";s:3:"ź";s:2:"Ż";s:3:"Ż";s:2:"ż";s:3:"ż";s:2:"Ž";s:3:"Ž";s:2:"ž";s:3:"ž";s:2:"ſ";s:1:"s";s:2:"Ơ";s:3:"Ơ";s:2:"ơ";s:3:"ơ";s:2:"Ư";s:3:"Ư";s:2:"ư";s:3:"ư";s:2:"DŽ";s:4:"DŽ";s:2:"Dž";s:4:"Dž";s:2:"dž";s:4:"dž";s:2:"LJ";s:2:"LJ";s:2:"Lj";s:2:"Lj";s:2:"lj";s:2:"lj";s:2:"NJ";s:2:"NJ";s:2:"Nj";s:2:"Nj";s:2:"nj";s:2:"nj";s:2:"Ǎ";s:3:"Ǎ";s:2:"ǎ";s:3:"ǎ";s:2:"Ǐ";s:3:"Ǐ";s:2:"ǐ";s:3:"ǐ";s:2:"Ǒ";s:3:"Ǒ";s:2:"ǒ";s:3:"ǒ";s:2:"Ǔ";s:3:"Ǔ";s:2:"ǔ";s:3:"ǔ";s:2:"Ǖ";s:5:"Ǖ";s:2:"ǖ";s:5:"ǖ";s:2:"Ǘ";s:5:"Ǘ";s:2:"ǘ";s:5:"ǘ";s:2:"Ǚ";s:5:"Ǚ";s:2:"ǚ";s:5:"ǚ";s:2:"Ǜ";s:5:"Ǜ";s:2:"ǜ";s:5:"ǜ";s:2:"Ǟ";s:5:"Ǟ";s:2:"ǟ";s:5:"ǟ";s:2:"Ǡ";s:5:"Ǡ";s:2:"ǡ";s:5:"ǡ";s:2:"Ǣ";s:4:"Ǣ";s:2:"ǣ";s:4:"ǣ";s:2:"Ǧ";s:3:"Ǧ";s:2:"ǧ";s:3:"ǧ";s:2:"Ǩ";s:3:"Ǩ";s:2:"ǩ";s:3:"ǩ";s:2:"Ǫ";s:3:"Ǫ";s:2:"ǫ";s:3:"ǫ";s:2:"Ǭ";s:5:"Ǭ";s:2:"ǭ";s:5:"ǭ";s:2:"Ǯ";s:4:"Ǯ";s:2:"ǯ";s:4:"ǯ";s:2:"ǰ";s:3:"ǰ";s:2:"DZ";s:2:"DZ";s:2:"Dz";s:2:"Dz";s:2:"dz";s:2:"dz";s:2:"Ǵ";s:3:"Ǵ";s:2:"ǵ";s:3:"ǵ";s:2:"Ǹ";s:3:"Ǹ";s:2:"ǹ";s:3:"ǹ";s:2:"Ǻ";s:5:"Ǻ";s:2:"ǻ";s:5:"ǻ";s:2:"Ǽ";s:4:"Ǽ";s:2:"ǽ";s:4:"ǽ";s:2:"Ǿ";s:4:"Ǿ";s:2:"ǿ";s:4:"ǿ";s:2:"Ȁ";s:3:"Ȁ";s:2:"ȁ";s:3:"ȁ";s:2:"Ȃ";s:3:"Ȃ";s:2:"ȃ";s:3:"ȃ";s:2:"Ȅ";s:3:"Ȅ";s:2:"ȅ";s:3:"ȅ";s:2:"Ȇ";s:3:"Ȇ";s:2:"ȇ";s:3:"ȇ";s:2:"Ȉ";s:3:"Ȉ";s:2:"ȉ";s:3:"ȉ";s:2:"Ȋ";s:3:"Ȋ";s:2:"ȋ";s:3:"ȋ";s:2:"Ȍ";s:3:"Ȍ";s:2:"ȍ";s:3:"ȍ";s:2:"Ȏ";s:3:"Ȏ";s:2:"ȏ";s:3:"ȏ";s:2:"Ȑ";s:3:"Ȑ";s:2:"ȑ";s:3:"ȑ";s:2:"Ȓ";s:3:"Ȓ";s:2:"ȓ";s:3:"ȓ";s:2:"Ȕ";s:3:"Ȕ";s:2:"ȕ";s:3:"ȕ";s:2:"Ȗ";s:3:"Ȗ";s:2:"ȗ";s:3:"ȗ";s:2:"Ș";s:3:"Ș";s:2:"ș";s:3:"ș";s:2:"Ț";s:3:"Ț";s:2:"ț";s:3:"ț";s:2:"Ȟ";s:3:"Ȟ";s:2:"ȟ";s:3:"ȟ";s:2:"Ȧ";s:3:"Ȧ";s:2:"ȧ";s:3:"ȧ";s:2:"Ȩ";s:3:"Ȩ";s:2:"ȩ";s:3:"ȩ";s:2:"Ȫ";s:5:"Ȫ";s:2:"ȫ";s:5:"ȫ";s:2:"Ȭ";s:5:"Ȭ";s:2:"ȭ";s:5:"ȭ";s:2:"Ȯ";s:3:"Ȯ";s:2:"ȯ";s:3:"ȯ";s:2:"Ȱ";s:5:"Ȱ";s:2:"ȱ";s:5:"ȱ";s:2:"Ȳ";s:3:"Ȳ";s:2:"ȳ";s:3:"ȳ";s:2:"ʰ";s:1:"h";s:2:"ʱ";s:2:"ɦ";s:2:"ʲ";s:1:"j";s:2:"ʳ";s:1:"r";s:2:"ʴ";s:2:"ɹ";s:2:"ʵ";s:2:"ɻ";s:2:"ʶ";s:2:"ʁ";s:2:"ʷ";s:1:"w";s:2:"ʸ";s:1:"y";s:2:"˘";s:3:" ̆";s:2:"˙";s:3:" ̇";s:2:"˚";s:3:" ̊";s:2:"˛";s:3:" ̨";s:2:"˜";s:3:" ̃";s:2:"˝";s:3:" ̋";s:2:"ˠ";s:2:"ɣ";s:2:"ˡ";s:1:"l";s:2:"ˢ";s:1:"s";s:2:"ˣ";s:1:"x";s:2:"ˤ";s:2:"ʕ";s:2:"̀";s:2:"̀";s:2:"́";s:2:"́";s:2:"̓";s:2:"̓";s:2:"̈́";s:4:"̈́";s:2:"ʹ";s:2:"ʹ";s:2:"ͺ";s:3:" ͅ";s:2:";";s:1:";";s:2:"΄";s:3:" ́";s:2:"΅";s:5:" ̈́";s:2:"Ά";s:4:"Ά";s:2:"·";s:2:"·";s:2:"Έ";s:4:"Έ";s:2:"Ή";s:4:"Ή";s:2:"Ί";s:4:"Ί";s:2:"Ό";s:4:"Ό";s:2:"Ύ";s:4:"Ύ";s:2:"Ώ";s:4:"Ώ";s:2:"ΐ";s:6:"ΐ";s:2:"Ϊ";s:4:"Ϊ";s:2:"Ϋ";s:4:"Ϋ";s:2:"ά";s:4:"ά";s:2:"έ";s:4:"έ";s:2:"ή";s:4:"ή";s:2:"ί";s:4:"ί";s:2:"ΰ";s:6:"ΰ";s:2:"ϊ";s:4:"ϊ";s:2:"ϋ";s:4:"ϋ";s:2:"ό";s:4:"ό";s:2:"ύ";s:4:"ύ";s:2:"ώ";s:4:"ώ";s:2:"ϐ";s:2:"β";s:2:"ϑ";s:2:"θ";s:2:"ϒ";s:2:"Υ";s:2:"ϓ";s:4:"Ύ";s:2:"ϔ";s:4:"Ϋ";s:2:"ϕ";s:2:"φ";s:2:"ϖ";s:2:"π";s:2:"ϰ";s:2:"κ";s:2:"ϱ";s:2:"ρ";s:2:"ϲ";s:2:"ς";s:2:"ϴ";s:2:"Θ";s:2:"ϵ";s:2:"ε";s:2:"Ϲ";s:2:"Σ";s:2:"Ѐ";s:4:"Ѐ";s:2:"Ё";s:4:"Ё";s:2:"Ѓ";s:4:"Ѓ";s:2:"Ї";s:4:"Ї";s:2:"Ќ";s:4:"Ќ";s:2:"Ѝ";s:4:"Ѝ";s:2:"Ў";s:4:"Ў";s:2:"Й";s:4:"Й";s:2:"й";s:4:"й";s:2:"ѐ";s:4:"ѐ";s:2:"ё";s:4:"ё";s:2:"ѓ";s:4:"ѓ";s:2:"ї";s:4:"ї";s:2:"ќ";s:4:"ќ";s:2:"ѝ";s:4:"ѝ";s:2:"ў";s:4:"ў";s:2:"Ѷ";s:4:"Ѷ";s:2:"ѷ";s:4:"ѷ";s:2:"Ӂ";s:4:"Ӂ";s:2:"ӂ";s:4:"ӂ";s:2:"Ӑ";s:4:"Ӑ";s:2:"ӑ";s:4:"ӑ";s:2:"Ӓ";s:4:"Ӓ";s:2:"ӓ";s:4:"ӓ";s:2:"Ӗ";s:4:"Ӗ";s:2:"ӗ";s:4:"ӗ";s:2:"Ӛ";s:4:"Ӛ";s:2:"ӛ";s:4:"ӛ";s:2:"Ӝ";s:4:"Ӝ";s:2:"ӝ";s:4:"ӝ";s:2:"Ӟ";s:4:"Ӟ";s:2:"ӟ";s:4:"ӟ";s:2:"Ӣ";s:4:"Ӣ";s:2:"ӣ";s:4:"ӣ";s:2:"Ӥ";s:4:"Ӥ";s:2:"ӥ";s:4:"ӥ";s:2:"Ӧ";s:4:"Ӧ";s:2:"ӧ";s:4:"ӧ";s:2:"Ӫ";s:4:"Ӫ";s:2:"ӫ";s:4:"ӫ";s:2:"Ӭ";s:4:"Ӭ";s:2:"ӭ";s:4:"ӭ";s:2:"Ӯ";s:4:"Ӯ";s:2:"ӯ";s:4:"ӯ";s:2:"Ӱ";s:4:"Ӱ";s:2:"ӱ";s:4:"ӱ";s:2:"Ӳ";s:4:"Ӳ";s:2:"ӳ";s:4:"ӳ";s:2:"Ӵ";s:4:"Ӵ";s:2:"ӵ";s:4:"ӵ";s:2:"Ӹ";s:4:"Ӹ";s:2:"ӹ";s:4:"ӹ";s:2:"և";s:4:"եւ";s:2:"آ";s:4:"آ";s:2:"أ";s:4:"أ";s:2:"ؤ";s:4:"ؤ";s:2:"إ";s:4:"إ";s:2:"ئ";s:4:"ئ";s:2:"ٵ";s:4:"اٴ";s:2:"ٶ";s:4:"وٴ";s:2:"ٷ";s:4:"ۇٴ";s:2:"ٸ";s:4:"يٴ";s:2:"ۀ";s:4:"ۀ";s:2:"ۂ";s:4:"ۂ";s:2:"ۓ";s:4:"ۓ";s:3:"ऩ";s:6:"ऩ";s:3:"ऱ";s:6:"ऱ";s:3:"ऴ";s:6:"ऴ";s:3:"क़";s:6:"क़";s:3:"ख़";s:6:"ख़";s:3:"ग़";s:6:"ग़";s:3:"ज़";s:6:"ज़";s:3:"ड़";s:6:"ड़";s:3:"ढ़";s:6:"ढ़";s:3:"फ़";s:6:"फ़";s:3:"य़";s:6:"य़";s:3:"ো";s:6:"ো";s:3:"ৌ";s:6:"ৌ";s:3:"ড়";s:6:"ড়";s:3:"ঢ়";s:6:"ঢ়";s:3:"য়";s:6:"য়";s:3:"ਲ਼";s:6:"ਲ਼";s:3:"ਸ਼";s:6:"ਸ਼";s:3:"ਖ਼";s:6:"ਖ਼";s:3:"ਗ਼";s:6:"ਗ਼";s:3:"ਜ਼";s:6:"ਜ਼";s:3:"ਫ਼";s:6:"ਫ਼";s:3:"ୈ";s:6:"ୈ";s:3:"ୋ";s:6:"ୋ";s:3:"ୌ";s:6:"ୌ";s:3:"ଡ଼";s:6:"ଡ଼";s:3:"ଢ଼";s:6:"ଢ଼";s:3:"ஔ";s:6:"ஔ";s:3:"ொ";s:6:"ொ";s:3:"ோ";s:6:"ோ";s:3:"ௌ";s:6:"ௌ";s:3:"ై";s:6:"ై";s:3:"ೀ";s:6:"ೀ";s:3:"ೇ";s:6:"ೇ";s:3:"ೈ";s:6:"ೈ";s:3:"ೊ";s:6:"ೊ";s:3:"ೋ";s:9:"ೋ";s:3:"ൊ";s:6:"ൊ";s:3:"ോ";s:6:"ോ";s:3:"ൌ";s:6:"ൌ";s:3:"ේ";s:6:"ේ";s:3:"ො";s:6:"ො";s:3:"ෝ";s:9:"ෝ";s:3:"ෞ";s:6:"ෞ";s:3:"ำ";s:6:"ํา";s:3:"ຳ";s:6:"ໍາ";s:3:"ໜ";s:6:"ຫນ";s:3:"ໝ";s:6:"ຫມ";s:3:"༌";s:3:"་";s:3:"གྷ";s:6:"གྷ";s:3:"ཌྷ";s:6:"ཌྷ";s:3:"དྷ";s:6:"དྷ";s:3:"བྷ";s:6:"བྷ";s:3:"ཛྷ";s:6:"ཛྷ";s:3:"ཀྵ";s:6:"ཀྵ";s:3:"ཱི";s:6:"ཱི";s:3:"ཱུ";s:6:"ཱུ";s:3:"ྲྀ";s:6:"ྲྀ";s:3:"ཷ";s:9:"ྲཱྀ";s:3:"ླྀ";s:6:"ླྀ";s:3:"ཹ";s:9:"ླཱྀ";s:3:"ཱྀ";s:6:"ཱྀ";s:3:"ྒྷ";s:6:"ྒྷ";s:3:"ྜྷ";s:6:"ྜྷ";s:3:"ྡྷ";s:6:"ྡྷ";s:3:"ྦྷ";s:6:"ྦྷ";s:3:"ྫྷ";s:6:"ྫྷ";s:3:"ྐྵ";s:6:"ྐྵ";s:3:"ဦ";s:6:"ဦ";s:3:"ჼ";s:3:"ნ";s:3:"ᴬ";s:1:"A";s:3:"ᴭ";s:2:"Æ";s:3:"ᴮ";s:1:"B";s:3:"ᴰ";s:1:"D";s:3:"ᴱ";s:1:"E";s:3:"ᴲ";s:2:"Ǝ";s:3:"ᴳ";s:1:"G";s:3:"ᴴ";s:1:"H";s:3:"ᴵ";s:1:"I";s:3:"ᴶ";s:1:"J";s:3:"ᴷ";s:1:"K";s:3:"ᴸ";s:1:"L";s:3:"ᴹ";s:1:"M";s:3:"ᴺ";s:1:"N";s:3:"ᴼ";s:1:"O";s:3:"ᴽ";s:2:"Ȣ";s:3:"ᴾ";s:1:"P";s:3:"ᴿ";s:1:"R";s:3:"ᵀ";s:1:"T";s:3:"ᵁ";s:1:"U";s:3:"ᵂ";s:1:"W";s:3:"ᵃ";s:1:"a";s:3:"ᵄ";s:2:"ɐ";s:3:"ᵅ";s:2:"ɑ";s:3:"ᵆ";s:3:"ᴂ";s:3:"ᵇ";s:1:"b";s:3:"ᵈ";s:1:"d";s:3:"ᵉ";s:1:"e";s:3:"ᵊ";s:2:"ə";s:3:"ᵋ";s:2:"ɛ";s:3:"ᵌ";s:2:"ɜ";s:3:"ᵍ";s:1:"g";s:3:"ᵏ";s:1:"k";s:3:"ᵐ";s:1:"m";s:3:"ᵑ";s:2:"ŋ";s:3:"ᵒ";s:1:"o";s:3:"ᵓ";s:2:"ɔ";s:3:"ᵔ";s:3:"ᴖ";s:3:"ᵕ";s:3:"ᴗ";s:3:"ᵖ";s:1:"p";s:3:"ᵗ";s:1:"t";s:3:"ᵘ";s:1:"u";s:3:"ᵙ";s:3:"ᴝ";s:3:"ᵚ";s:2:"ɯ";s:3:"ᵛ";s:1:"v";s:3:"ᵜ";s:3:"ᴥ";s:3:"ᵝ";s:2:"β";s:3:"ᵞ";s:2:"γ";s:3:"ᵟ";s:2:"δ";s:3:"ᵠ";s:2:"φ";s:3:"ᵡ";s:2:"χ";s:3:"ᵢ";s:1:"i";s:3:"ᵣ";s:1:"r";s:3:"ᵤ";s:1:"u";s:3:"ᵥ";s:1:"v";s:3:"ᵦ";s:2:"β";s:3:"ᵧ";s:2:"γ";s:3:"ᵨ";s:2:"ρ";s:3:"ᵩ";s:2:"φ";s:3:"ᵪ";s:2:"χ";s:3:"ᵸ";s:2:"н";s:3:"ᶛ";s:2:"ɒ";s:3:"ᶜ";s:1:"c";s:3:"ᶝ";s:2:"ɕ";s:3:"ᶞ";s:2:"ð";s:3:"ᶟ";s:2:"ɜ";s:3:"ᶠ";s:1:"f";s:3:"ᶡ";s:2:"ɟ";s:3:"ᶢ";s:2:"ɡ";s:3:"ᶣ";s:2:"ɥ";s:3:"ᶤ";s:2:"ɨ";s:3:"ᶥ";s:2:"ɩ";s:3:"ᶦ";s:2:"ɪ";s:3:"ᶧ";s:3:"ᵻ";s:3:"ᶨ";s:2:"ʝ";s:3:"ᶩ";s:2:"ɭ";s:3:"ᶪ";s:3:"ᶅ";s:3:"ᶫ";s:2:"ʟ";s:3:"ᶬ";s:2:"ɱ";s:3:"ᶭ";s:2:"ɰ";s:3:"ᶮ";s:2:"ɲ";s:3:"ᶯ";s:2:"ɳ";s:3:"ᶰ";s:2:"ɴ";s:3:"ᶱ";s:2:"ɵ";s:3:"ᶲ";s:2:"ɸ";s:3:"ᶳ";s:2:"ʂ";s:3:"ᶴ";s:2:"ʃ";s:3:"ᶵ";s:2:"ƫ";s:3:"ᶶ";s:2:"ʉ";s:3:"ᶷ";s:2:"ʊ";s:3:"ᶸ";s:3:"ᴜ";s:3:"ᶹ";s:2:"ʋ";s:3:"ᶺ";s:2:"ʌ";s:3:"ᶻ";s:1:"z";s:3:"ᶼ";s:2:"ʐ";s:3:"ᶽ";s:2:"ʑ";s:3:"ᶾ";s:2:"ʒ";s:3:"ᶿ";s:2:"θ";s:3:"Ḁ";s:3:"Ḁ";s:3:"ḁ";s:3:"ḁ";s:3:"Ḃ";s:3:"Ḃ";s:3:"ḃ";s:3:"ḃ";s:3:"Ḅ";s:3:"Ḅ";s:3:"ḅ";s:3:"ḅ";s:3:"Ḇ";s:3:"Ḇ";s:3:"ḇ";s:3:"ḇ";s:3:"Ḉ";s:5:"Ḉ";s:3:"ḉ";s:5:"ḉ";s:3:"Ḋ";s:3:"Ḋ";s:3:"ḋ";s:3:"ḋ";s:3:"Ḍ";s:3:"Ḍ";s:3:"ḍ";s:3:"ḍ";s:3:"Ḏ";s:3:"Ḏ";s:3:"ḏ";s:3:"ḏ";s:3:"Ḑ";s:3:"Ḑ";s:3:"ḑ";s:3:"ḑ";s:3:"Ḓ";s:3:"Ḓ";s:3:"ḓ";s:3:"ḓ";s:3:"Ḕ";s:5:"Ḕ";s:3:"ḕ";s:5:"ḕ";s:3:"Ḗ";s:5:"Ḗ";s:3:"ḗ";s:5:"ḗ";s:3:"Ḙ";s:3:"Ḙ";s:3:"ḙ";s:3:"ḙ";s:3:"Ḛ";s:3:"Ḛ";s:3:"ḛ";s:3:"ḛ";s:3:"Ḝ";s:5:"Ḝ";s:3:"ḝ";s:5:"ḝ";s:3:"Ḟ";s:3:"Ḟ";s:3:"ḟ";s:3:"ḟ";s:3:"Ḡ";s:3:"Ḡ";s:3:"ḡ";s:3:"ḡ";s:3:"Ḣ";s:3:"Ḣ";s:3:"ḣ";s:3:"ḣ";s:3:"Ḥ";s:3:"Ḥ";s:3:"ḥ";s:3:"ḥ";s:3:"Ḧ";s:3:"Ḧ";s:3:"ḧ";s:3:"ḧ";s:3:"Ḩ";s:3:"Ḩ";s:3:"ḩ";s:3:"ḩ";s:3:"Ḫ";s:3:"Ḫ";s:3:"ḫ";s:3:"ḫ";s:3:"Ḭ";s:3:"Ḭ";s:3:"ḭ";s:3:"ḭ";s:3:"Ḯ";s:5:"Ḯ";s:3:"ḯ";s:5:"ḯ";s:3:"Ḱ";s:3:"Ḱ";s:3:"ḱ";s:3:"ḱ";s:3:"Ḳ";s:3:"Ḳ";s:3:"ḳ";s:3:"ḳ";s:3:"Ḵ";s:3:"Ḵ";s:3:"ḵ";s:3:"ḵ";s:3:"Ḷ";s:3:"Ḷ";s:3:"ḷ";s:3:"ḷ";s:3:"Ḹ";s:5:"Ḹ";s:3:"ḹ";s:5:"ḹ";s:3:"Ḻ";s:3:"Ḻ";s:3:"ḻ";s:3:"ḻ";s:3:"Ḽ";s:3:"Ḽ";s:3:"ḽ";s:3:"ḽ";s:3:"Ḿ";s:3:"Ḿ";s:3:"ḿ";s:3:"ḿ";s:3:"Ṁ";s:3:"Ṁ";s:3:"ṁ";s:3:"ṁ";s:3:"Ṃ";s:3:"Ṃ";s:3:"ṃ";s:3:"ṃ";s:3:"Ṅ";s:3:"Ṅ";s:3:"ṅ";s:3:"ṅ";s:3:"Ṇ";s:3:"Ṇ";s:3:"ṇ";s:3:"ṇ";s:3:"Ṉ";s:3:"Ṉ";s:3:"ṉ";s:3:"ṉ";s:3:"Ṋ";s:3:"Ṋ";s:3:"ṋ";s:3:"ṋ";s:3:"Ṍ";s:5:"Ṍ";s:3:"ṍ";s:5:"ṍ";s:3:"Ṏ";s:5:"Ṏ";s:3:"ṏ";s:5:"ṏ";s:3:"Ṑ";s:5:"Ṑ";s:3:"ṑ";s:5:"ṑ";s:3:"Ṓ";s:5:"Ṓ";s:3:"ṓ";s:5:"ṓ";s:3:"Ṕ";s:3:"Ṕ";s:3:"ṕ";s:3:"ṕ";s:3:"Ṗ";s:3:"Ṗ";s:3:"ṗ";s:3:"ṗ";s:3:"Ṙ";s:3:"Ṙ";s:3:"ṙ";s:3:"ṙ";s:3:"Ṛ";s:3:"Ṛ";s:3:"ṛ";s:3:"ṛ";s:3:"Ṝ";s:5:"Ṝ";s:3:"ṝ";s:5:"ṝ";s:3:"Ṟ";s:3:"Ṟ";s:3:"ṟ";s:3:"ṟ";s:3:"Ṡ";s:3:"Ṡ";s:3:"ṡ";s:3:"ṡ";s:3:"Ṣ";s:3:"Ṣ";s:3:"ṣ";s:3:"ṣ";s:3:"Ṥ";s:5:"Ṥ";s:3:"ṥ";s:5:"ṥ";s:3:"Ṧ";s:5:"Ṧ";s:3:"ṧ";s:5:"ṧ";s:3:"Ṩ";s:5:"Ṩ";s:3:"ṩ";s:5:"ṩ";s:3:"Ṫ";s:3:"Ṫ";s:3:"ṫ";s:3:"ṫ";s:3:"Ṭ";s:3:"Ṭ";s:3:"ṭ";s:3:"ṭ";s:3:"Ṯ";s:3:"Ṯ";s:3:"ṯ";s:3:"ṯ";s:3:"Ṱ";s:3:"Ṱ";s:3:"ṱ";s:3:"ṱ";s:3:"Ṳ";s:3:"Ṳ";s:3:"ṳ";s:3:"ṳ";s:3:"Ṵ";s:3:"Ṵ";s:3:"ṵ";s:3:"ṵ";s:3:"Ṷ";s:3:"Ṷ";s:3:"ṷ";s:3:"ṷ";s:3:"Ṹ";s:5:"Ṹ";s:3:"ṹ";s:5:"ṹ";s:3:"Ṻ";s:5:"Ṻ";s:3:"ṻ";s:5:"ṻ";s:3:"Ṽ";s:3:"Ṽ";s:3:"ṽ";s:3:"ṽ";s:3:"Ṿ";s:3:"Ṿ";s:3:"ṿ";s:3:"ṿ";s:3:"Ẁ";s:3:"Ẁ";s:3:"ẁ";s:3:"ẁ";s:3:"Ẃ";s:3:"Ẃ";s:3:"ẃ";s:3:"ẃ";s:3:"Ẅ";s:3:"Ẅ";s:3:"ẅ";s:3:"ẅ";s:3:"Ẇ";s:3:"Ẇ";s:3:"ẇ";s:3:"ẇ";s:3:"Ẉ";s:3:"Ẉ";s:3:"ẉ";s:3:"ẉ";s:3:"Ẋ";s:3:"Ẋ";s:3:"ẋ";s:3:"ẋ";s:3:"Ẍ";s:3:"Ẍ";s:3:"ẍ";s:3:"ẍ";s:3:"Ẏ";s:3:"Ẏ";s:3:"ẏ";s:3:"ẏ";s:3:"Ẑ";s:3:"Ẑ";s:3:"ẑ";s:3:"ẑ";s:3:"Ẓ";s:3:"Ẓ";s:3:"ẓ";s:3:"ẓ";s:3:"Ẕ";s:3:"Ẕ";s:3:"ẕ";s:3:"ẕ";s:3:"ẖ";s:3:"ẖ";s:3:"ẗ";s:3:"ẗ";s:3:"ẘ";s:3:"ẘ";s:3:"ẙ";s:3:"ẙ";s:3:"ẚ";s:3:"aʾ";s:3:"ẛ";s:3:"ṡ";s:3:"Ạ";s:3:"Ạ";s:3:"ạ";s:3:"ạ";s:3:"Ả";s:3:"Ả";s:3:"ả";s:3:"ả";s:3:"Ấ";s:5:"Ấ";s:3:"ấ";s:5:"ấ";s:3:"Ầ";s:5:"Ầ";s:3:"ầ";s:5:"ầ";s:3:"Ẩ";s:5:"Ẩ";s:3:"ẩ";s:5:"ẩ";s:3:"Ẫ";s:5:"Ẫ";s:3:"ẫ";s:5:"ẫ";s:3:"Ậ";s:5:"Ậ";s:3:"ậ";s:5:"ậ";s:3:"Ắ";s:5:"Ắ";s:3:"ắ";s:5:"ắ";s:3:"Ằ";s:5:"Ằ";s:3:"ằ";s:5:"ằ";s:3:"Ẳ";s:5:"Ẳ";s:3:"ẳ";s:5:"ẳ";s:3:"Ẵ";s:5:"Ẵ";s:3:"ẵ";s:5:"ẵ";s:3:"Ặ";s:5:"Ặ";s:3:"ặ";s:5:"ặ";s:3:"Ẹ";s:3:"Ẹ";s:3:"ẹ";s:3:"ẹ";s:3:"Ẻ";s:3:"Ẻ";s:3:"ẻ";s:3:"ẻ";s:3:"Ẽ";s:3:"Ẽ";s:3:"ẽ";s:3:"ẽ";s:3:"Ế";s:5:"Ế";s:3:"ế";s:5:"ế";s:3:"Ề";s:5:"Ề";s:3:"ề";s:5:"ề";s:3:"Ể";s:5:"Ể";s:3:"ể";s:5:"ể";s:3:"Ễ";s:5:"Ễ";s:3:"ễ";s:5:"ễ";s:3:"Ệ";s:5:"Ệ";s:3:"ệ";s:5:"ệ";s:3:"Ỉ";s:3:"Ỉ";s:3:"ỉ";s:3:"ỉ";s:3:"Ị";s:3:"Ị";s:3:"ị";s:3:"ị";s:3:"Ọ";s:3:"Ọ";s:3:"ọ";s:3:"ọ";s:3:"Ỏ";s:3:"Ỏ";s:3:"ỏ";s:3:"ỏ";s:3:"Ố";s:5:"Ố";s:3:"ố";s:5:"ố";s:3:"Ồ";s:5:"Ồ";s:3:"ồ";s:5:"ồ";s:3:"Ổ";s:5:"Ổ";s:3:"ổ";s:5:"ổ";s:3:"Ỗ";s:5:"Ỗ";s:3:"ỗ";s:5:"ỗ";s:3:"Ộ";s:5:"Ộ";s:3:"ộ";s:5:"ộ";s:3:"Ớ";s:5:"Ớ";s:3:"ớ";s:5:"ớ";s:3:"Ờ";s:5:"Ờ";s:3:"ờ";s:5:"ờ";s:3:"Ở";s:5:"Ở";s:3:"ở";s:5:"ở";s:3:"Ỡ";s:5:"Ỡ";s:3:"ỡ";s:5:"ỡ";s:3:"Ợ";s:5:"Ợ";s:3:"ợ";s:5:"ợ";s:3:"Ụ";s:3:"Ụ";s:3:"ụ";s:3:"ụ";s:3:"Ủ";s:3:"Ủ";s:3:"ủ";s:3:"ủ";s:3:"Ứ";s:5:"Ứ";s:3:"ứ";s:5:"ứ";s:3:"Ừ";s:5:"Ừ";s:3:"ừ";s:5:"ừ";s:3:"Ử";s:5:"Ử";s:3:"ử";s:5:"ử";s:3:"Ữ";s:5:"Ữ";s:3:"ữ";s:5:"ữ";s:3:"Ự";s:5:"Ự";s:3:"ự";s:5:"ự";s:3:"Ỳ";s:3:"Ỳ";s:3:"ỳ";s:3:"ỳ";s:3:"Ỵ";s:3:"Ỵ";s:3:"ỵ";s:3:"ỵ";s:3:"Ỷ";s:3:"Ỷ";s:3:"ỷ";s:3:"ỷ";s:3:"Ỹ";s:3:"Ỹ";s:3:"ỹ";s:3:"ỹ";s:3:"ἀ";s:4:"ἀ";s:3:"ἁ";s:4:"ἁ";s:3:"ἂ";s:6:"ἂ";s:3:"ἃ";s:6:"ἃ";s:3:"ἄ";s:6:"ἄ";s:3:"ἅ";s:6:"ἅ";s:3:"ἆ";s:6:"ἆ";s:3:"ἇ";s:6:"ἇ";s:3:"Ἀ";s:4:"Ἀ";s:3:"Ἁ";s:4:"Ἁ";s:3:"Ἂ";s:6:"Ἂ";s:3:"Ἃ";s:6:"Ἃ";s:3:"Ἄ";s:6:"Ἄ";s:3:"Ἅ";s:6:"Ἅ";s:3:"Ἆ";s:6:"Ἆ";s:3:"Ἇ";s:6:"Ἇ";s:3:"ἐ";s:4:"ἐ";s:3:"ἑ";s:4:"ἑ";s:3:"ἒ";s:6:"ἒ";s:3:"ἓ";s:6:"ἓ";s:3:"ἔ";s:6:"ἔ";s:3:"ἕ";s:6:"ἕ";s:3:"Ἐ";s:4:"Ἐ";s:3:"Ἑ";s:4:"Ἑ";s:3:"Ἒ";s:6:"Ἒ";s:3:"Ἓ";s:6:"Ἓ";s:3:"Ἔ";s:6:"Ἔ";s:3:"Ἕ";s:6:"Ἕ";s:3:"ἠ";s:4:"ἠ";s:3:"ἡ";s:4:"ἡ";s:3:"ἢ";s:6:"ἢ";s:3:"ἣ";s:6:"ἣ";s:3:"ἤ";s:6:"ἤ";s:3:"ἥ";s:6:"ἥ";s:3:"ἦ";s:6:"ἦ";s:3:"ἧ";s:6:"ἧ";s:3:"Ἠ";s:4:"Ἠ";s:3:"Ἡ";s:4:"Ἡ";s:3:"Ἢ";s:6:"Ἢ";s:3:"Ἣ";s:6:"Ἣ";s:3:"Ἤ";s:6:"Ἤ";s:3:"Ἥ";s:6:"Ἥ";s:3:"Ἦ";s:6:"Ἦ";s:3:"Ἧ";s:6:"Ἧ";s:3:"ἰ";s:4:"ἰ";s:3:"ἱ";s:4:"ἱ";s:3:"ἲ";s:6:"ἲ";s:3:"ἳ";s:6:"ἳ";s:3:"ἴ";s:6:"ἴ";s:3:"ἵ";s:6:"ἵ";s:3:"ἶ";s:6:"ἶ";s:3:"ἷ";s:6:"ἷ";s:3:"Ἰ";s:4:"Ἰ";s:3:"Ἱ";s:4:"Ἱ";s:3:"Ἲ";s:6:"Ἲ";s:3:"Ἳ";s:6:"Ἳ";s:3:"Ἴ";s:6:"Ἴ";s:3:"Ἵ";s:6:"Ἵ";s:3:"Ἶ";s:6:"Ἶ";s:3:"Ἷ";s:6:"Ἷ";s:3:"ὀ";s:4:"ὀ";s:3:"ὁ";s:4:"ὁ";s:3:"ὂ";s:6:"ὂ";s:3:"ὃ";s:6:"ὃ";s:3:"ὄ";s:6:"ὄ";s:3:"ὅ";s:6:"ὅ";s:3:"Ὀ";s:4:"Ὀ";s:3:"Ὁ";s:4:"Ὁ";s:3:"Ὂ";s:6:"Ὂ";s:3:"Ὃ";s:6:"Ὃ";s:3:"Ὄ";s:6:"Ὄ";s:3:"Ὅ";s:6:"Ὅ";s:3:"ὐ";s:4:"ὐ";s:3:"ὑ";s:4:"ὑ";s:3:"ὒ";s:6:"ὒ";s:3:"ὓ";s:6:"ὓ";s:3:"ὔ";s:6:"ὔ";s:3:"ὕ";s:6:"ὕ";s:3:"ὖ";s:6:"ὖ";s:3:"ὗ";s:6:"ὗ";s:3:"Ὑ";s:4:"Ὑ";s:3:"Ὓ";s:6:"Ὓ";s:3:"Ὕ";s:6:"Ὕ";s:3:"Ὗ";s:6:"Ὗ";s:3:"ὠ";s:4:"ὠ";s:3:"ὡ";s:4:"ὡ";s:3:"ὢ";s:6:"ὢ";s:3:"ὣ";s:6:"ὣ";s:3:"ὤ";s:6:"ὤ";s:3:"ὥ";s:6:"ὥ";s:3:"ὦ";s:6:"ὦ";s:3:"ὧ";s:6:"ὧ";s:3:"Ὠ";s:4:"Ὠ";s:3:"Ὡ";s:4:"Ὡ";s:3:"Ὢ";s:6:"Ὢ";s:3:"Ὣ";s:6:"Ὣ";s:3:"Ὤ";s:6:"Ὤ";s:3:"Ὥ";s:6:"Ὥ";s:3:"Ὦ";s:6:"Ὦ";s:3:"Ὧ";s:6:"Ὧ";s:3:"ὰ";s:4:"ὰ";s:3:"ά";s:4:"ά";s:3:"ὲ";s:4:"ὲ";s:3:"έ";s:4:"έ";s:3:"ὴ";s:4:"ὴ";s:3:"ή";s:4:"ή";s:3:"ὶ";s:4:"ὶ";s:3:"ί";s:4:"ί";s:3:"ὸ";s:4:"ὸ";s:3:"ό";s:4:"ό";s:3:"ὺ";s:4:"ὺ";s:3:"ύ";s:4:"ύ";s:3:"ὼ";s:4:"ὼ";s:3:"ώ";s:4:"ώ";s:3:"ᾀ";s:6:"ᾀ";s:3:"ᾁ";s:6:"ᾁ";s:3:"ᾂ";s:8:"ᾂ";s:3:"ᾃ";s:8:"ᾃ";s:3:"ᾄ";s:8:"ᾄ";s:3:"ᾅ";s:8:"ᾅ";s:3:"ᾆ";s:8:"ᾆ";s:3:"ᾇ";s:8:"ᾇ";s:3:"ᾈ";s:6:"ᾈ";s:3:"ᾉ";s:6:"ᾉ";s:3:"ᾊ";s:8:"ᾊ";s:3:"ᾋ";s:8:"ᾋ";s:3:"ᾌ";s:8:"ᾌ";s:3:"ᾍ";s:8:"ᾍ";s:3:"ᾎ";s:8:"ᾎ";s:3:"ᾏ";s:8:"ᾏ";s:3:"ᾐ";s:6:"ᾐ";s:3:"ᾑ";s:6:"ᾑ";s:3:"ᾒ";s:8:"ᾒ";s:3:"ᾓ";s:8:"ᾓ";s:3:"ᾔ";s:8:"ᾔ";s:3:"ᾕ";s:8:"ᾕ";s:3:"ᾖ";s:8:"ᾖ";s:3:"ᾗ";s:8:"ᾗ";s:3:"ᾘ";s:6:"ᾘ";s:3:"ᾙ";s:6:"ᾙ";s:3:"ᾚ";s:8:"ᾚ";s:3:"ᾛ";s:8:"ᾛ";s:3:"ᾜ";s:8:"ᾜ";s:3:"ᾝ";s:8:"ᾝ";s:3:"ᾞ";s:8:"ᾞ";s:3:"ᾟ";s:8:"ᾟ";s:3:"ᾠ";s:6:"ᾠ";s:3:"ᾡ";s:6:"ᾡ";s:3:"ᾢ";s:8:"ᾢ";s:3:"ᾣ";s:8:"ᾣ";s:3:"ᾤ";s:8:"ᾤ";s:3:"ᾥ";s:8:"ᾥ";s:3:"ᾦ";s:8:"ᾦ";s:3:"ᾧ";s:8:"ᾧ";s:3:"ᾨ";s:6:"ᾨ";s:3:"ᾩ";s:6:"ᾩ";s:3:"ᾪ";s:8:"ᾪ";s:3:"ᾫ";s:8:"ᾫ";s:3:"ᾬ";s:8:"ᾬ";s:3:"ᾭ";s:8:"ᾭ";s:3:"ᾮ";s:8:"ᾮ";s:3:"ᾯ";s:8:"ᾯ";s:3:"ᾰ";s:4:"ᾰ";s:3:"ᾱ";s:4:"ᾱ";s:3:"ᾲ";s:6:"ᾲ";s:3:"ᾳ";s:4:"ᾳ";s:3:"ᾴ";s:6:"ᾴ";s:3:"ᾶ";s:4:"ᾶ";s:3:"ᾷ";s:6:"ᾷ";s:3:"Ᾰ";s:4:"Ᾰ";s:3:"Ᾱ";s:4:"Ᾱ";s:3:"Ὰ";s:4:"Ὰ";s:3:"Ά";s:4:"Ά";s:3:"ᾼ";s:4:"ᾼ";s:3:"᾽";s:3:" ̓";s:3:"ι";s:2:"ι";s:3:"᾿";s:3:" ̓";s:3:"῀";s:3:" ͂";s:3:"῁";s:5:" ̈͂";s:3:"ῂ";s:6:"ῂ";s:3:"ῃ";s:4:"ῃ";s:3:"ῄ";s:6:"ῄ";s:3:"ῆ";s:4:"ῆ";s:3:"ῇ";s:6:"ῇ";s:3:"Ὲ";s:4:"Ὲ";s:3:"Έ";s:4:"Έ";s:3:"Ὴ";s:4:"Ὴ";s:3:"Ή";s:4:"Ή";s:3:"ῌ";s:4:"ῌ";s:3:"῍";s:5:" ̓̀";s:3:"῎";s:5:" ̓́";s:3:"῏";s:5:" ̓͂";s:3:"ῐ";s:4:"ῐ";s:3:"ῑ";s:4:"ῑ";s:3:"ῒ";s:6:"ῒ";s:3:"ΐ";s:6:"ΐ";s:3:"ῖ";s:4:"ῖ";s:3:"ῗ";s:6:"ῗ";s:3:"Ῐ";s:4:"Ῐ";s:3:"Ῑ";s:4:"Ῑ";s:3:"Ὶ";s:4:"Ὶ";s:3:"Ί";s:4:"Ί";s:3:"῝";s:5:" ̔̀";s:3:"῞";s:5:" ̔́";s:3:"῟";s:5:" ̔͂";s:3:"ῠ";s:4:"ῠ";s:3:"ῡ";s:4:"ῡ";s:3:"ῢ";s:6:"ῢ";s:3:"ΰ";s:6:"ΰ";s:3:"ῤ";s:4:"ῤ";s:3:"ῥ";s:4:"ῥ";s:3:"ῦ";s:4:"ῦ";s:3:"ῧ";s:6:"ῧ";s:3:"Ῠ";s:4:"Ῠ";s:3:"Ῡ";s:4:"Ῡ";s:3:"Ὺ";s:4:"Ὺ";s:3:"Ύ";s:4:"Ύ";s:3:"Ῥ";s:4:"Ῥ";s:3:"῭";s:5:" ̈̀";s:3:"΅";s:5:" ̈́";s:3:"`";s:1:"`";s:3:"ῲ";s:6:"ῲ";s:3:"ῳ";s:4:"ῳ";s:3:"ῴ";s:6:"ῴ";s:3:"ῶ";s:4:"ῶ";s:3:"ῷ";s:6:"ῷ";s:3:"Ὸ";s:4:"Ὸ";s:3:"Ό";s:4:"Ό";s:3:"Ὼ";s:4:"Ὼ";s:3:"Ώ";s:4:"Ώ";s:3:"ῼ";s:4:"ῼ";s:3:"´";s:3:" ́";s:3:"῾";s:3:" ̔";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:" ";s:1:" ";s:3:"‑";s:3:"‐";s:3:"‗";s:3:" ̳";s:3:"․";s:1:".";s:3:"‥";s:2:"..";s:3:"…";s:3:"...";s:3:" ";s:1:" ";s:3:"″";s:6:"′′";s:3:"‴";s:9:"′′′";s:3:"‶";s:6:"‵‵";s:3:"‷";s:9:"‵‵‵";s:3:"‼";s:2:"!!";s:3:"‾";s:3:" ̅";s:3:"⁇";s:2:"??";s:3:"⁈";s:2:"?!";s:3:"⁉";s:2:"!?";s:3:"⁗";s:12:"′′′′";s:3:" ";s:1:" ";s:3:"⁰";s:1:"0";s:3:"ⁱ";s:1:"i";s:3:"⁴";s:1:"4";s:3:"⁵";s:1:"5";s:3:"⁶";s:1:"6";s:3:"⁷";s:1:"7";s:3:"⁸";s:1:"8";s:3:"⁹";s:1:"9";s:3:"⁺";s:1:"+";s:3:"⁻";s:3:"−";s:3:"⁼";s:1:"=";s:3:"⁽";s:1:"(";s:3:"⁾";s:1:")";s:3:"ⁿ";s:1:"n";s:3:"₀";s:1:"0";s:3:"₁";s:1:"1";s:3:"₂";s:1:"2";s:3:"₃";s:1:"3";s:3:"₄";s:1:"4";s:3:"₅";s:1:"5";s:3:"₆";s:1:"6";s:3:"₇";s:1:"7";s:3:"₈";s:1:"8";s:3:"₉";s:1:"9";s:3:"₊";s:1:"+";s:3:"₋";s:3:"−";s:3:"₌";s:1:"=";s:3:"₍";s:1:"(";s:3:"₎";s:1:")";s:3:"ₐ";s:1:"a";s:3:"ₑ";s:1:"e";s:3:"ₒ";s:1:"o";s:3:"ₓ";s:1:"x";s:3:"ₔ";s:2:"ə";s:3:"₨";s:2:"Rs";s:3:"℀";s:3:"a/c";s:3:"℁";s:3:"a/s";s:3:"ℂ";s:1:"C";s:3:"℃";s:3:"°C";s:3:"℅";s:3:"c/o";s:3:"℆";s:3:"c/u";s:3:"ℇ";s:2:"Ɛ";s:3:"℉";s:3:"°F";s:3:"ℊ";s:1:"g";s:3:"ℋ";s:1:"H";s:3:"ℌ";s:1:"H";s:3:"ℍ";s:1:"H";s:3:"ℎ";s:1:"h";s:3:"ℏ";s:2:"ħ";s:3:"ℐ";s:1:"I";s:3:"ℑ";s:1:"I";s:3:"ℒ";s:1:"L";s:3:"ℓ";s:1:"l";s:3:"ℕ";s:1:"N";s:3:"№";s:2:"No";s:3:"ℙ";s:1:"P";s:3:"ℚ";s:1:"Q";s:3:"ℛ";s:1:"R";s:3:"ℜ";s:1:"R";s:3:"ℝ";s:1:"R";s:3:"℠";s:2:"SM";s:3:"℡";s:3:"TEL";s:3:"™";s:2:"TM";s:3:"ℤ";s:1:"Z";s:3:"Ω";s:2:"Ω";s:3:"ℨ";s:1:"Z";s:3:"K";s:1:"K";s:3:"Å";s:3:"Å";s:3:"ℬ";s:1:"B";s:3:"ℭ";s:1:"C";s:3:"ℯ";s:1:"e";s:3:"ℰ";s:1:"E";s:3:"ℱ";s:1:"F";s:3:"ℳ";s:1:"M";s:3:"ℴ";s:1:"o";s:3:"ℵ";s:2:"א";s:3:"ℶ";s:2:"ב";s:3:"ℷ";s:2:"ג";s:3:"ℸ";s:2:"ד";s:3:"ℹ";s:1:"i";s:3:"℻";s:3:"FAX";s:3:"ℼ";s:2:"π";s:3:"ℽ";s:2:"γ";s:3:"ℾ";s:2:"Γ";s:3:"ℿ";s:2:"Π";s:3:"⅀";s:3:"∑";s:3:"ⅅ";s:1:"D";s:3:"ⅆ";s:1:"d";s:3:"ⅇ";s:1:"e";s:3:"ⅈ";s:1:"i";s:3:"ⅉ";s:1:"j";s:3:"⅓";s:5:"1⁄3";s:3:"⅔";s:5:"2⁄3";s:3:"⅕";s:5:"1⁄5";s:3:"⅖";s:5:"2⁄5";s:3:"⅗";s:5:"3⁄5";s:3:"⅘";s:5:"4⁄5";s:3:"⅙";s:5:"1⁄6";s:3:"⅚";s:5:"5⁄6";s:3:"⅛";s:5:"1⁄8";s:3:"⅜";s:5:"3⁄8";s:3:"⅝";s:5:"5⁄8";s:3:"⅞";s:5:"7⁄8";s:3:"⅟";s:4:"1⁄";s:3:"Ⅰ";s:1:"I";s:3:"Ⅱ";s:2:"II";s:3:"Ⅲ";s:3:"III";s:3:"Ⅳ";s:2:"IV";s:3:"Ⅴ";s:1:"V";s:3:"Ⅵ";s:2:"VI";s:3:"Ⅶ";s:3:"VII";s:3:"Ⅷ";s:4:"VIII";s:3:"Ⅸ";s:2:"IX";s:3:"Ⅹ";s:1:"X";s:3:"Ⅺ";s:2:"XI";s:3:"Ⅻ";s:3:"XII";s:3:"Ⅼ";s:1:"L";s:3:"Ⅽ";s:1:"C";s:3:"Ⅾ";s:1:"D";s:3:"Ⅿ";s:1:"M";s:3:"ⅰ";s:1:"i";s:3:"ⅱ";s:2:"ii";s:3:"ⅲ";s:3:"iii";s:3:"ⅳ";s:2:"iv";s:3:"ⅴ";s:1:"v";s:3:"ⅵ";s:2:"vi";s:3:"ⅶ";s:3:"vii";s:3:"ⅷ";s:4:"viii";s:3:"ⅸ";s:2:"ix";s:3:"ⅹ";s:1:"x";s:3:"ⅺ";s:2:"xi";s:3:"ⅻ";s:3:"xii";s:3:"ⅼ";s:1:"l";s:3:"ⅽ";s:1:"c";s:3:"ⅾ";s:1:"d";s:3:"ⅿ";s:1:"m";s:3:"↚";s:5:"↚";s:3:"↛";s:5:"↛";s:3:"↮";s:5:"↮";s:3:"⇍";s:5:"⇍";s:3:"⇎";s:5:"⇎";s:3:"⇏";s:5:"⇏";s:3:"∄";s:5:"∄";s:3:"∉";s:5:"∉";s:3:"∌";s:5:"∌";s:3:"∤";s:5:"∤";s:3:"∦";s:5:"∦";s:3:"∬";s:6:"∫∫";s:3:"∭";s:9:"∫∫∫";s:3:"∯";s:6:"∮∮";s:3:"∰";s:9:"∮∮∮";s:3:"≁";s:5:"≁";s:3:"≄";s:5:"≄";s:3:"≇";s:5:"≇";s:3:"≉";s:5:"≉";s:3:"≠";s:3:"≠";s:3:"≢";s:5:"≢";s:3:"≭";s:5:"≭";s:3:"≮";s:3:"≮";s:3:"≯";s:3:"≯";s:3:"≰";s:5:"≰";s:3:"≱";s:5:"≱";s:3:"≴";s:5:"≴";s:3:"≵";s:5:"≵";s:3:"≸";s:5:"≸";s:3:"≹";s:5:"≹";s:3:"⊀";s:5:"⊀";s:3:"⊁";s:5:"⊁";s:3:"⊄";s:5:"⊄";s:3:"⊅";s:5:"⊅";s:3:"⊈";s:5:"⊈";s:3:"⊉";s:5:"⊉";s:3:"⊬";s:5:"⊬";s:3:"⊭";s:5:"⊭";s:3:"⊮";s:5:"⊮";s:3:"⊯";s:5:"⊯";s:3:"⋠";s:5:"⋠";s:3:"⋡";s:5:"⋡";s:3:"⋢";s:5:"⋢";s:3:"⋣";s:5:"⋣";s:3:"⋪";s:5:"⋪";s:3:"⋫";s:5:"⋫";s:3:"⋬";s:5:"⋬";s:3:"⋭";s:5:"⋭";s:3:"〈";s:3:"〈";s:3:"〉";s:3:"〉";s:3:"①";s:1:"1";s:3:"②";s:1:"2";s:3:"③";s:1:"3";s:3:"④";s:1:"4";s:3:"⑤";s:1:"5";s:3:"⑥";s:1:"6";s:3:"⑦";s:1:"7";s:3:"⑧";s:1:"8";s:3:"⑨";s:1:"9";s:3:"⑩";s:2:"10";s:3:"⑪";s:2:"11";s:3:"⑫";s:2:"12";s:3:"⑬";s:2:"13";s:3:"⑭";s:2:"14";s:3:"⑮";s:2:"15";s:3:"⑯";s:2:"16";s:3:"⑰";s:2:"17";s:3:"⑱";s:2:"18";s:3:"⑲";s:2:"19";s:3:"⑳";s:2:"20";s:3:"⑴";s:3:"(1)";s:3:"⑵";s:3:"(2)";s:3:"⑶";s:3:"(3)";s:3:"⑷";s:3:"(4)";s:3:"⑸";s:3:"(5)";s:3:"⑹";s:3:"(6)";s:3:"⑺";s:3:"(7)";s:3:"⑻";s:3:"(8)";s:3:"⑼";s:3:"(9)";s:3:"⑽";s:4:"(10)";s:3:"⑾";s:4:"(11)";s:3:"⑿";s:4:"(12)";s:3:"⒀";s:4:"(13)";s:3:"⒁";s:4:"(14)";s:3:"⒂";s:4:"(15)";s:3:"⒃";s:4:"(16)";s:3:"⒄";s:4:"(17)";s:3:"⒅";s:4:"(18)";s:3:"⒆";s:4:"(19)";s:3:"⒇";s:4:"(20)";s:3:"⒈";s:2:"1.";s:3:"⒉";s:2:"2.";s:3:"⒊";s:2:"3.";s:3:"⒋";s:2:"4.";s:3:"⒌";s:2:"5.";s:3:"⒍";s:2:"6.";s:3:"⒎";s:2:"7.";s:3:"⒏";s:2:"8.";s:3:"⒐";s:2:"9.";s:3:"⒑";s:3:"10.";s:3:"⒒";s:3:"11.";s:3:"⒓";s:3:"12.";s:3:"⒔";s:3:"13.";s:3:"⒕";s:3:"14.";s:3:"⒖";s:3:"15.";s:3:"⒗";s:3:"16.";s:3:"⒘";s:3:"17.";s:3:"⒙";s:3:"18.";s:3:"⒚";s:3:"19.";s:3:"⒛";s:3:"20.";s:3:"⒜";s:3:"(a)";s:3:"⒝";s:3:"(b)";s:3:"⒞";s:3:"(c)";s:3:"⒟";s:3:"(d)";s:3:"⒠";s:3:"(e)";s:3:"⒡";s:3:"(f)";s:3:"⒢";s:3:"(g)";s:3:"⒣";s:3:"(h)";s:3:"⒤";s:3:"(i)";s:3:"⒥";s:3:"(j)";s:3:"⒦";s:3:"(k)";s:3:"⒧";s:3:"(l)";s:3:"⒨";s:3:"(m)";s:3:"⒩";s:3:"(n)";s:3:"⒪";s:3:"(o)";s:3:"⒫";s:3:"(p)";s:3:"⒬";s:3:"(q)";s:3:"⒭";s:3:"(r)";s:3:"⒮";s:3:"(s)";s:3:"⒯";s:3:"(t)";s:3:"⒰";s:3:"(u)";s:3:"⒱";s:3:"(v)";s:3:"⒲";s:3:"(w)";s:3:"⒳";s:3:"(x)";s:3:"⒴";s:3:"(y)";s:3:"⒵";s:3:"(z)";s:3:"Ⓐ";s:1:"A";s:3:"Ⓑ";s:1:"B";s:3:"Ⓒ";s:1:"C";s:3:"Ⓓ";s:1:"D";s:3:"Ⓔ";s:1:"E";s:3:"Ⓕ";s:1:"F";s:3:"Ⓖ";s:1:"G";s:3:"Ⓗ";s:1:"H";s:3:"Ⓘ";s:1:"I";s:3:"Ⓙ";s:1:"J";s:3:"Ⓚ";s:1:"K";s:3:"Ⓛ";s:1:"L";s:3:"Ⓜ";s:1:"M";s:3:"Ⓝ";s:1:"N";s:3:"Ⓞ";s:1:"O";s:3:"Ⓟ";s:1:"P";s:3:"Ⓠ";s:1:"Q";s:3:"Ⓡ";s:1:"R";s:3:"Ⓢ";s:1:"S";s:3:"Ⓣ";s:1:"T";s:3:"Ⓤ";s:1:"U";s:3:"Ⓥ";s:1:"V";s:3:"Ⓦ";s:1:"W";s:3:"Ⓧ";s:1:"X";s:3:"Ⓨ";s:1:"Y";s:3:"Ⓩ";s:1:"Z";s:3:"ⓐ";s:1:"a";s:3:"ⓑ";s:1:"b";s:3:"ⓒ";s:1:"c";s:3:"ⓓ";s:1:"d";s:3:"ⓔ";s:1:"e";s:3:"ⓕ";s:1:"f";s:3:"ⓖ";s:1:"g";s:3:"ⓗ";s:1:"h";s:3:"ⓘ";s:1:"i";s:3:"ⓙ";s:1:"j";s:3:"ⓚ";s:1:"k";s:3:"ⓛ";s:1:"l";s:3:"ⓜ";s:1:"m";s:3:"ⓝ";s:1:"n";s:3:"ⓞ";s:1:"o";s:3:"ⓟ";s:1:"p";s:3:"ⓠ";s:1:"q";s:3:"ⓡ";s:1:"r";s:3:"ⓢ";s:1:"s";s:3:"ⓣ";s:1:"t";s:3:"ⓤ";s:1:"u";s:3:"ⓥ";s:1:"v";s:3:"ⓦ";s:1:"w";s:3:"ⓧ";s:1:"x";s:3:"ⓨ";s:1:"y";s:3:"ⓩ";s:1:"z";s:3:"⓪";s:1:"0";s:3:"⨌";s:12:"∫∫∫∫";s:3:"⩴";s:3:"::=";s:3:"⩵";s:2:"==";s:3:"⩶";s:3:"===";s:3:"⫝̸";s:5:"⫝̸";s:3:"ⵯ";s:3:"ⵡ";s:3:"⺟";s:3:"母";s:3:"⻳";s:3:"龟";s:3:"⼀";s:3:"一";s:3:"⼁";s:3:"丨";s:3:"⼂";s:3:"丶";s:3:"⼃";s:3:"丿";s:3:"⼄";s:3:"乙";s:3:"⼅";s:3:"亅";s:3:"⼆";s:3:"二";s:3:"⼇";s:3:"亠";s:3:"⼈";s:3:"人";s:3:"⼉";s:3:"儿";s:3:"⼊";s:3:"入";s:3:"⼋";s:3:"八";s:3:"⼌";s:3:"冂";s:3:"⼍";s:3:"冖";s:3:"⼎";s:3:"冫";s:3:"⼏";s:3:"几";s:3:"⼐";s:3:"凵";s:3:"⼑";s:3:"刀";s:3:"⼒";s:3:"力";s:3:"⼓";s:3:"勹";s:3:"⼔";s:3:"匕";s:3:"⼕";s:3:"匚";s:3:"⼖";s:3:"匸";s:3:"⼗";s:3:"十";s:3:"⼘";s:3:"卜";s:3:"⼙";s:3:"卩";s:3:"⼚";s:3:"厂";s:3:"⼛";s:3:"厶";s:3:"⼜";s:3:"又";s:3:"⼝";s:3:"口";s:3:"⼞";s:3:"囗";s:3:"⼟";s:3:"土";s:3:"⼠";s:3:"士";s:3:"⼡";s:3:"夂";s:3:"⼢";s:3:"夊";s:3:"⼣";s:3:"夕";s:3:"⼤";s:3:"大";s:3:"⼥";s:3:"女";s:3:"⼦";s:3:"子";s:3:"⼧";s:3:"宀";s:3:"⼨";s:3:"寸";s:3:"⼩";s:3:"小";s:3:"⼪";s:3:"尢";s:3:"⼫";s:3:"尸";s:3:"⼬";s:3:"屮";s:3:"⼭";s:3:"山";s:3:"⼮";s:3:"巛";s:3:"⼯";s:3:"工";s:3:"⼰";s:3:"己";s:3:"⼱";s:3:"巾";s:3:"⼲";s:3:"干";s:3:"⼳";s:3:"幺";s:3:"⼴";s:3:"广";s:3:"⼵";s:3:"廴";s:3:"⼶";s:3:"廾";s:3:"⼷";s:3:"弋";s:3:"⼸";s:3:"弓";s:3:"⼹";s:3:"彐";s:3:"⼺";s:3:"彡";s:3:"⼻";s:3:"彳";s:3:"⼼";s:3:"心";s:3:"⼽";s:3:"戈";s:3:"⼾";s:3:"戶";s:3:"⼿";s:3:"手";s:3:"⽀";s:3:"支";s:3:"⽁";s:3:"攴";s:3:"⽂";s:3:"文";s:3:"⽃";s:3:"斗";s:3:"⽄";s:3:"斤";s:3:"⽅";s:3:"方";s:3:"⽆";s:3:"无";s:3:"⽇";s:3:"日";s:3:"⽈";s:3:"曰";s:3:"⽉";s:3:"月";s:3:"⽊";s:3:"木";s:3:"⽋";s:3:"欠";s:3:"⽌";s:3:"止";s:3:"⽍";s:3:"歹";s:3:"⽎";s:3:"殳";s:3:"⽏";s:3:"毋";s:3:"⽐";s:3:"比";s:3:"⽑";s:3:"毛";s:3:"⽒";s:3:"氏";s:3:"⽓";s:3:"气";s:3:"⽔";s:3:"水";s:3:"⽕";s:3:"火";s:3:"⽖";s:3:"爪";s:3:"⽗";s:3:"父";s:3:"⽘";s:3:"爻";s:3:"⽙";s:3:"爿";s:3:"⽚";s:3:"片";s:3:"⽛";s:3:"牙";s:3:"⽜";s:3:"牛";s:3:"⽝";s:3:"犬";s:3:"⽞";s:3:"玄";s:3:"⽟";s:3:"玉";s:3:"⽠";s:3:"瓜";s:3:"⽡";s:3:"瓦";s:3:"⽢";s:3:"甘";s:3:"⽣";s:3:"生";s:3:"⽤";s:3:"用";s:3:"⽥";s:3:"田";s:3:"⽦";s:3:"疋";s:3:"⽧";s:3:"疒";s:3:"⽨";s:3:"癶";s:3:"⽩";s:3:"白";s:3:"⽪";s:3:"皮";s:3:"⽫";s:3:"皿";s:3:"⽬";s:3:"目";s:3:"⽭";s:3:"矛";s:3:"⽮";s:3:"矢";s:3:"⽯";s:3:"石";s:3:"⽰";s:3:"示";s:3:"⽱";s:3:"禸";s:3:"⽲";s:3:"禾";s:3:"⽳";s:3:"穴";s:3:"⽴";s:3:"立";s:3:"⽵";s:3:"竹";s:3:"⽶";s:3:"米";s:3:"⽷";s:3:"糸";s:3:"⽸";s:3:"缶";s:3:"⽹";s:3:"网";s:3:"⽺";s:3:"羊";s:3:"⽻";s:3:"羽";s:3:"⽼";s:3:"老";s:3:"⽽";s:3:"而";s:3:"⽾";s:3:"耒";s:3:"⽿";s:3:"耳";s:3:"⾀";s:3:"聿";s:3:"⾁";s:3:"肉";s:3:"⾂";s:3:"臣";s:3:"⾃";s:3:"自";s:3:"⾄";s:3:"至";s:3:"⾅";s:3:"臼";s:3:"⾆";s:3:"舌";s:3:"⾇";s:3:"舛";s:3:"⾈";s:3:"舟";s:3:"⾉";s:3:"艮";s:3:"⾊";s:3:"色";s:3:"⾋";s:3:"艸";s:3:"⾌";s:3:"虍";s:3:"⾍";s:3:"虫";s:3:"⾎";s:3:"血";s:3:"⾏";s:3:"行";s:3:"⾐";s:3:"衣";s:3:"⾑";s:3:"襾";s:3:"⾒";s:3:"見";s:3:"⾓";s:3:"角";s:3:"⾔";s:3:"言";s:3:"⾕";s:3:"谷";s:3:"⾖";s:3:"豆";s:3:"⾗";s:3:"豕";s:3:"⾘";s:3:"豸";s:3:"⾙";s:3:"貝";s:3:"⾚";s:3:"赤";s:3:"⾛";s:3:"走";s:3:"⾜";s:3:"足";s:3:"⾝";s:3:"身";s:3:"⾞";s:3:"車";s:3:"⾟";s:3:"辛";s:3:"⾠";s:3:"辰";s:3:"⾡";s:3:"辵";s:3:"⾢";s:3:"邑";s:3:"⾣";s:3:"酉";s:3:"⾤";s:3:"釆";s:3:"⾥";s:3:"里";s:3:"⾦";s:3:"金";s:3:"⾧";s:3:"長";s:3:"⾨";s:3:"門";s:3:"⾩";s:3:"阜";s:3:"⾪";s:3:"隶";s:3:"⾫";s:3:"隹";s:3:"⾬";s:3:"雨";s:3:"⾭";s:3:"靑";s:3:"⾮";s:3:"非";s:3:"⾯";s:3:"面";s:3:"⾰";s:3:"革";s:3:"⾱";s:3:"韋";s:3:"⾲";s:3:"韭";s:3:"⾳";s:3:"音";s:3:"⾴";s:3:"頁";s:3:"⾵";s:3:"風";s:3:"⾶";s:3:"飛";s:3:"⾷";s:3:"食";s:3:"⾸";s:3:"首";s:3:"⾹";s:3:"香";s:3:"⾺";s:3:"馬";s:3:"⾻";s:3:"骨";s:3:"⾼";s:3:"高";s:3:"⾽";s:3:"髟";s:3:"⾾";s:3:"鬥";s:3:"⾿";s:3:"鬯";s:3:"⿀";s:3:"鬲";s:3:"⿁";s:3:"鬼";s:3:"⿂";s:3:"魚";s:3:"⿃";s:3:"鳥";s:3:"⿄";s:3:"鹵";s:3:"⿅";s:3:"鹿";s:3:"⿆";s:3:"麥";s:3:"⿇";s:3:"麻";s:3:"⿈";s:3:"黃";s:3:"⿉";s:3:"黍";s:3:"⿊";s:3:"黑";s:3:"⿋";s:3:"黹";s:3:"⿌";s:3:"黽";s:3:"⿍";s:3:"鼎";s:3:"⿎";s:3:"鼓";s:3:"⿏";s:3:"鼠";s:3:"⿐";s:3:"鼻";s:3:"⿑";s:3:"齊";s:3:"⿒";s:3:"齒";s:3:"⿓";s:3:"龍";s:3:"⿔";s:3:"龜";s:3:"⿕";s:3:"龠";s:3:" ";s:1:" ";s:3:"〶";s:3:"〒";s:3:"〸";s:3:"十";s:3:"〹";s:3:"卄";s:3:"〺";s:3:"卅";s:3:"が";s:6:"が";s:3:"ぎ";s:6:"ぎ";s:3:"ぐ";s:6:"ぐ";s:3:"げ";s:6:"げ";s:3:"ご";s:6:"ご";s:3:"ざ";s:6:"ざ";s:3:"じ";s:6:"じ";s:3:"ず";s:6:"ず";s:3:"ぜ";s:6:"ぜ";s:3:"ぞ";s:6:"ぞ";s:3:"だ";s:6:"だ";s:3:"ぢ";s:6:"ぢ";s:3:"づ";s:6:"づ";s:3:"で";s:6:"で";s:3:"ど";s:6:"ど";s:3:"ば";s:6:"ば";s:3:"ぱ";s:6:"ぱ";s:3:"び";s:6:"び";s:3:"ぴ";s:6:"ぴ";s:3:"ぶ";s:6:"ぶ";s:3:"ぷ";s:6:"ぷ";s:3:"べ";s:6:"べ";s:3:"ぺ";s:6:"ぺ";s:3:"ぼ";s:6:"ぼ";s:3:"ぽ";s:6:"ぽ";s:3:"ゔ";s:6:"ゔ";s:3:"゛";s:4:" ゙";s:3:"゜";s:4:" ゚";s:3:"ゞ";s:6:"ゞ";s:3:"ゟ";s:6:"より";s:3:"ガ";s:6:"ガ";s:3:"ギ";s:6:"ギ";s:3:"グ";s:6:"グ";s:3:"ゲ";s:6:"ゲ";s:3:"ゴ";s:6:"ゴ";s:3:"ザ";s:6:"ザ";s:3:"ジ";s:6:"ジ";s:3:"ズ";s:6:"ズ";s:3:"ゼ";s:6:"ゼ";s:3:"ゾ";s:6:"ゾ";s:3:"ダ";s:6:"ダ";s:3:"ヂ";s:6:"ヂ";s:3:"ヅ";s:6:"ヅ";s:3:"デ";s:6:"デ";s:3:"ド";s:6:"ド";s:3:"バ";s:6:"バ";s:3:"パ";s:6:"パ";s:3:"ビ";s:6:"ビ";s:3:"ピ";s:6:"ピ";s:3:"ブ";s:6:"ブ";s:3:"プ";s:6:"プ";s:3:"ベ";s:6:"ベ";s:3:"ペ";s:6:"ペ";s:3:"ボ";s:6:"ボ";s:3:"ポ";s:6:"ポ";s:3:"ヴ";s:6:"ヴ";s:3:"ヷ";s:6:"ヷ";s:3:"ヸ";s:6:"ヸ";s:3:"ヹ";s:6:"ヹ";s:3:"ヺ";s:6:"ヺ";s:3:"ヾ";s:6:"ヾ";s:3:"ヿ";s:6:"コト";s:3:"ㄱ";s:3:"ᄀ";s:3:"ㄲ";s:3:"ᄁ";s:3:"ㄳ";s:3:"ᆪ";s:3:"ㄴ";s:3:"ᄂ";s:3:"ㄵ";s:3:"ᆬ";s:3:"ㄶ";s:3:"ᆭ";s:3:"ㄷ";s:3:"ᄃ";s:3:"ㄸ";s:3:"ᄄ";s:3:"ㄹ";s:3:"ᄅ";s:3:"ㄺ";s:3:"ᆰ";s:3:"ㄻ";s:3:"ᆱ";s:3:"ㄼ";s:3:"ᆲ";s:3:"ㄽ";s:3:"ᆳ";s:3:"ㄾ";s:3:"ᆴ";s:3:"ㄿ";s:3:"ᆵ";s:3:"ㅀ";s:3:"ᄚ";s:3:"ㅁ";s:3:"ᄆ";s:3:"ㅂ";s:3:"ᄇ";s:3:"ㅃ";s:3:"ᄈ";s:3:"ㅄ";s:3:"ᄡ";s:3:"ㅅ";s:3:"ᄉ";s:3:"ㅆ";s:3:"ᄊ";s:3:"ㅇ";s:3:"ᄋ";s:3:"ㅈ";s:3:"ᄌ";s:3:"ㅉ";s:3:"ᄍ";s:3:"ㅊ";s:3:"ᄎ";s:3:"ㅋ";s:3:"ᄏ";s:3:"ㅌ";s:3:"ᄐ";s:3:"ㅍ";s:3:"ᄑ";s:3:"ㅎ";s:3:"ᄒ";s:3:"ㅏ";s:3:"ᅡ";s:3:"ㅐ";s:3:"ᅢ";s:3:"ㅑ";s:3:"ᅣ";s:3:"ㅒ";s:3:"ᅤ";s:3:"ㅓ";s:3:"ᅥ";s:3:"ㅔ";s:3:"ᅦ";s:3:"ㅕ";s:3:"ᅧ";s:3:"ㅖ";s:3:"ᅨ";s:3:"ㅗ";s:3:"ᅩ";s:3:"ㅘ";s:3:"ᅪ";s:3:"ㅙ";s:3:"ᅫ";s:3:"ㅚ";s:3:"ᅬ";s:3:"ㅛ";s:3:"ᅭ";s:3:"ㅜ";s:3:"ᅮ";s:3:"ㅝ";s:3:"ᅯ";s:3:"ㅞ";s:3:"ᅰ";s:3:"ㅟ";s:3:"ᅱ";s:3:"ㅠ";s:3:"ᅲ";s:3:"ㅡ";s:3:"ᅳ";s:3:"ㅢ";s:3:"ᅴ";s:3:"ㅣ";s:3:"ᅵ";s:3:"ㅤ";s:3:"ᅠ";s:3:"ㅥ";s:3:"ᄔ";s:3:"ㅦ";s:3:"ᄕ";s:3:"ㅧ";s:3:"ᇇ";s:3:"ㅨ";s:3:"ᇈ";s:3:"ㅩ";s:3:"ᇌ";s:3:"ㅪ";s:3:"ᇎ";s:3:"ㅫ";s:3:"ᇓ";s:3:"ㅬ";s:3:"ᇗ";s:3:"ㅭ";s:3:"ᇙ";s:3:"ㅮ";s:3:"ᄜ";s:3:"ㅯ";s:3:"ᇝ";s:3:"ㅰ";s:3:"ᇟ";s:3:"ㅱ";s:3:"ᄝ";s:3:"ㅲ";s:3:"ᄞ";s:3:"ㅳ";s:3:"ᄠ";s:3:"ㅴ";s:3:"ᄢ";s:3:"ㅵ";s:3:"ᄣ";s:3:"ㅶ";s:3:"ᄧ";s:3:"ㅷ";s:3:"ᄩ";s:3:"ㅸ";s:3:"ᄫ";s:3:"ㅹ";s:3:"ᄬ";s:3:"ㅺ";s:3:"ᄭ";s:3:"ㅻ";s:3:"ᄮ";s:3:"ㅼ";s:3:"ᄯ";s:3:"ㅽ";s:3:"ᄲ";s:3:"ㅾ";s:3:"ᄶ";s:3:"ㅿ";s:3:"ᅀ";s:3:"ㆀ";s:3:"ᅇ";s:3:"ㆁ";s:3:"ᅌ";s:3:"ㆂ";s:3:"ᇱ";s:3:"ㆃ";s:3:"ᇲ";s:3:"ㆄ";s:3:"ᅗ";s:3:"ㆅ";s:3:"ᅘ";s:3:"ㆆ";s:3:"ᅙ";s:3:"ㆇ";s:3:"ᆄ";s:3:"ㆈ";s:3:"ᆅ";s:3:"ㆉ";s:3:"ᆈ";s:3:"ㆊ";s:3:"ᆑ";s:3:"ㆋ";s:3:"ᆒ";s:3:"ㆌ";s:3:"ᆔ";s:3:"ㆍ";s:3:"ᆞ";s:3:"ㆎ";s:3:"ᆡ";s:3:"㆒";s:3:"一";s:3:"㆓";s:3:"二";s:3:"㆔";s:3:"三";s:3:"㆕";s:3:"四";s:3:"㆖";s:3:"上";s:3:"㆗";s:3:"中";s:3:"㆘";s:3:"下";s:3:"㆙";s:3:"甲";s:3:"㆚";s:3:"乙";s:3:"㆛";s:3:"丙";s:3:"㆜";s:3:"丁";s:3:"㆝";s:3:"天";s:3:"㆞";s:3:"地";s:3:"㆟";s:3:"人";s:3:"㈀";s:5:"(ᄀ)";s:3:"㈁";s:5:"(ᄂ)";s:3:"㈂";s:5:"(ᄃ)";s:3:"㈃";s:5:"(ᄅ)";s:3:"㈄";s:5:"(ᄆ)";s:3:"㈅";s:5:"(ᄇ)";s:3:"㈆";s:5:"(ᄉ)";s:3:"㈇";s:5:"(ᄋ)";s:3:"㈈";s:5:"(ᄌ)";s:3:"㈉";s:5:"(ᄎ)";s:3:"㈊";s:5:"(ᄏ)";s:3:"㈋";s:5:"(ᄐ)";s:3:"㈌";s:5:"(ᄑ)";s:3:"㈍";s:5:"(ᄒ)";s:3:"㈎";s:8:"(가)";s:3:"㈏";s:8:"(나)";s:3:"㈐";s:8:"(다)";s:3:"㈑";s:8:"(라)";s:3:"㈒";s:8:"(마)";s:3:"㈓";s:8:"(바)";s:3:"㈔";s:8:"(사)";s:3:"㈕";s:8:"(아)";s:3:"㈖";s:8:"(자)";s:3:"㈗";s:8:"(차)";s:3:"㈘";s:8:"(카)";s:3:"㈙";s:8:"(타)";s:3:"㈚";s:8:"(파)";s:3:"㈛";s:8:"(하)";s:3:"㈜";s:8:"(주)";s:3:"㈝";s:17:"(오전)";s:3:"㈞";s:14:"(오후)";s:3:"㈠";s:5:"(一)";s:3:"㈡";s:5:"(二)";s:3:"㈢";s:5:"(三)";s:3:"㈣";s:5:"(四)";s:3:"㈤";s:5:"(五)";s:3:"㈥";s:5:"(六)";s:3:"㈦";s:5:"(七)";s:3:"㈧";s:5:"(八)";s:3:"㈨";s:5:"(九)";s:3:"㈩";s:5:"(十)";s:3:"㈪";s:5:"(月)";s:3:"㈫";s:5:"(火)";s:3:"㈬";s:5:"(水)";s:3:"㈭";s:5:"(木)";s:3:"㈮";s:5:"(金)";s:3:"㈯";s:5:"(土)";s:3:"㈰";s:5:"(日)";s:3:"㈱";s:5:"(株)";s:3:"㈲";s:5:"(有)";s:3:"㈳";s:5:"(社)";s:3:"㈴";s:5:"(名)";s:3:"㈵";s:5:"(特)";s:3:"㈶";s:5:"(財)";s:3:"㈷";s:5:"(祝)";s:3:"㈸";s:5:"(労)";s:3:"㈹";s:5:"(代)";s:3:"㈺";s:5:"(呼)";s:3:"㈻";s:5:"(学)";s:3:"㈼";s:5:"(監)";s:3:"㈽";s:5:"(企)";s:3:"㈾";s:5:"(資)";s:3:"㈿";s:5:"(協)";s:3:"㉀";s:5:"(祭)";s:3:"㉁";s:5:"(休)";s:3:"㉂";s:5:"(自)";s:3:"㉃";s:5:"(至)";s:3:"㉐";s:3:"PTE";s:3:"㉑";s:2:"21";s:3:"㉒";s:2:"22";s:3:"㉓";s:2:"23";s:3:"㉔";s:2:"24";s:3:"㉕";s:2:"25";s:3:"㉖";s:2:"26";s:3:"㉗";s:2:"27";s:3:"㉘";s:2:"28";s:3:"㉙";s:2:"29";s:3:"㉚";s:2:"30";s:3:"㉛";s:2:"31";s:3:"㉜";s:2:"32";s:3:"㉝";s:2:"33";s:3:"㉞";s:2:"34";s:3:"㉟";s:2:"35";s:3:"㉠";s:3:"ᄀ";s:3:"㉡";s:3:"ᄂ";s:3:"㉢";s:3:"ᄃ";s:3:"㉣";s:3:"ᄅ";s:3:"㉤";s:3:"ᄆ";s:3:"㉥";s:3:"ᄇ";s:3:"㉦";s:3:"ᄉ";s:3:"㉧";s:3:"ᄋ";s:3:"㉨";s:3:"ᄌ";s:3:"㉩";s:3:"ᄎ";s:3:"㉪";s:3:"ᄏ";s:3:"㉫";s:3:"ᄐ";s:3:"㉬";s:3:"ᄑ";s:3:"㉭";s:3:"ᄒ";s:3:"㉮";s:6:"가";s:3:"㉯";s:6:"나";s:3:"㉰";s:6:"다";s:3:"㉱";s:6:"라";s:3:"㉲";s:6:"마";s:3:"㉳";s:6:"바";s:3:"㉴";s:6:"사";s:3:"㉵";s:6:"아";s:3:"㉶";s:6:"자";s:3:"㉷";s:6:"차";s:3:"㉸";s:6:"카";s:3:"㉹";s:6:"타";s:3:"㉺";s:6:"파";s:3:"㉻";s:6:"하";s:3:"㉼";s:15:"참고";s:3:"㉽";s:12:"주의";s:3:"㉾";s:6:"우";s:3:"㊀";s:3:"一";s:3:"㊁";s:3:"二";s:3:"㊂";s:3:"三";s:3:"㊃";s:3:"四";s:3:"㊄";s:3:"五";s:3:"㊅";s:3:"六";s:3:"㊆";s:3:"七";s:3:"㊇";s:3:"八";s:3:"㊈";s:3:"九";s:3:"㊉";s:3:"十";s:3:"㊊";s:3:"月";s:3:"㊋";s:3:"火";s:3:"㊌";s:3:"水";s:3:"㊍";s:3:"木";s:3:"㊎";s:3:"金";s:3:"㊏";s:3:"土";s:3:"㊐";s:3:"日";s:3:"㊑";s:3:"株";s:3:"㊒";s:3:"有";s:3:"㊓";s:3:"社";s:3:"㊔";s:3:"名";s:3:"㊕";s:3:"特";s:3:"㊖";s:3:"財";s:3:"㊗";s:3:"祝";s:3:"㊘";s:3:"労";s:3:"㊙";s:3:"秘";s:3:"㊚";s:3:"男";s:3:"㊛";s:3:"女";s:3:"㊜";s:3:"適";s:3:"㊝";s:3:"優";s:3:"㊞";s:3:"印";s:3:"㊟";s:3:"注";s:3:"㊠";s:3:"項";s:3:"㊡";s:3:"休";s:3:"㊢";s:3:"写";s:3:"㊣";s:3:"正";s:3:"㊤";s:3:"上";s:3:"㊥";s:3:"中";s:3:"㊦";s:3:"下";s:3:"㊧";s:3:"左";s:3:"㊨";s:3:"右";s:3:"㊩";s:3:"医";s:3:"㊪";s:3:"宗";s:3:"㊫";s:3:"学";s:3:"㊬";s:3:"監";s:3:"㊭";s:3:"企";s:3:"㊮";s:3:"資";s:3:"㊯";s:3:"協";s:3:"㊰";s:3:"夜";s:3:"㊱";s:2:"36";s:3:"㊲";s:2:"37";s:3:"㊳";s:2:"38";s:3:"㊴";s:2:"39";s:3:"㊵";s:2:"40";s:3:"㊶";s:2:"41";s:3:"㊷";s:2:"42";s:3:"㊸";s:2:"43";s:3:"㊹";s:2:"44";s:3:"㊺";s:2:"45";s:3:"㊻";s:2:"46";s:3:"㊼";s:2:"47";s:3:"㊽";s:2:"48";s:3:"㊾";s:2:"49";s:3:"㊿";s:2:"50";s:3:"㋀";s:4:"1月";s:3:"㋁";s:4:"2月";s:3:"㋂";s:4:"3月";s:3:"㋃";s:4:"4月";s:3:"㋄";s:4:"5月";s:3:"㋅";s:4:"6月";s:3:"㋆";s:4:"7月";s:3:"㋇";s:4:"8月";s:3:"㋈";s:4:"9月";s:3:"㋉";s:5:"10月";s:3:"㋊";s:5:"11月";s:3:"㋋";s:5:"12月";s:3:"㋌";s:2:"Hg";s:3:"㋍";s:3:"erg";s:3:"㋎";s:2:"eV";s:3:"㋏";s:3:"LTD";s:3:"㋐";s:3:"ア";s:3:"㋑";s:3:"イ";s:3:"㋒";s:3:"ウ";s:3:"㋓";s:3:"エ";s:3:"㋔";s:3:"オ";s:3:"㋕";s:3:"カ";s:3:"㋖";s:3:"キ";s:3:"㋗";s:3:"ク";s:3:"㋘";s:3:"ケ";s:3:"㋙";s:3:"コ";s:3:"㋚";s:3:"サ";s:3:"㋛";s:3:"シ";s:3:"㋜";s:3:"ス";s:3:"㋝";s:3:"セ";s:3:"㋞";s:3:"ソ";s:3:"㋟";s:3:"タ";s:3:"㋠";s:3:"チ";s:3:"㋡";s:3:"ツ";s:3:"㋢";s:3:"テ";s:3:"㋣";s:3:"ト";s:3:"㋤";s:3:"ナ";s:3:"㋥";s:3:"ニ";s:3:"㋦";s:3:"ヌ";s:3:"㋧";s:3:"ネ";s:3:"㋨";s:3:"ノ";s:3:"㋩";s:3:"ハ";s:3:"㋪";s:3:"ヒ";s:3:"㋫";s:3:"フ";s:3:"㋬";s:3:"ヘ";s:3:"㋭";s:3:"ホ";s:3:"㋮";s:3:"マ";s:3:"㋯";s:3:"ミ";s:3:"㋰";s:3:"ム";s:3:"㋱";s:3:"メ";s:3:"㋲";s:3:"モ";s:3:"㋳";s:3:"ヤ";s:3:"㋴";s:3:"ユ";s:3:"㋵";s:3:"ヨ";s:3:"㋶";s:3:"ラ";s:3:"㋷";s:3:"リ";s:3:"㋸";s:3:"ル";s:3:"㋹";s:3:"レ";s:3:"㋺";s:3:"ロ";s:3:"㋻";s:3:"ワ";s:3:"㋼";s:3:"ヰ";s:3:"㋽";s:3:"ヱ";s:3:"㋾";s:3:"ヲ";s:3:"㌀";s:15:"アパート";s:3:"㌁";s:12:"アルファ";s:3:"㌂";s:15:"アンペア";s:3:"㌃";s:9:"アール";s:3:"㌄";s:15:"イニング";s:3:"㌅";s:9:"インチ";s:3:"㌆";s:9:"ウォン";s:3:"㌇";s:18:"エスクード";s:3:"㌈";s:12:"エーカー";s:3:"㌉";s:9:"オンス";s:3:"㌊";s:9:"オーム";s:3:"㌋";s:9:"カイリ";s:3:"㌌";s:12:"カラット";s:3:"㌍";s:12:"カロリー";s:3:"㌎";s:12:"ガロン";s:3:"㌏";s:12:"ガンマ";s:3:"㌐";s:12:"ギガ";s:3:"㌑";s:12:"ギニー";s:3:"㌒";s:12:"キュリー";s:3:"㌓";s:18:"ギルダー";s:3:"㌔";s:6:"キロ";s:3:"㌕";s:18:"キログラム";s:3:"㌖";s:18:"キロメートル";s:3:"㌗";s:15:"キロワット";s:3:"㌘";s:12:"グラム";s:3:"㌙";s:18:"グラムトン";s:3:"㌚";s:18:"クルゼイロ";s:3:"㌛";s:12:"クローネ";s:3:"㌜";s:9:"ケース";s:3:"㌝";s:9:"コルナ";s:3:"㌞";s:12:"コーポ";s:3:"㌟";s:12:"サイクル";s:3:"㌠";s:15:"サンチーム";s:3:"㌡";s:15:"シリング";s:3:"㌢";s:9:"センチ";s:3:"㌣";s:9:"セント";s:3:"㌤";s:12:"ダース";s:3:"㌥";s:9:"デシ";s:3:"㌦";s:9:"ドル";s:3:"㌧";s:6:"トン";s:3:"㌨";s:6:"ナノ";s:3:"㌩";s:9:"ノット";s:3:"㌪";s:9:"ハイツ";s:3:"㌫";s:18:"パーセント";s:3:"㌬";s:12:"パーツ";s:3:"㌭";s:15:"バーレル";s:3:"㌮";s:18:"ピアストル";s:3:"㌯";s:12:"ピクル";s:3:"㌰";s:9:"ピコ";s:3:"㌱";s:9:"ビル";s:3:"㌲";s:18:"ファラッド";s:3:"㌳";s:12:"フィート";s:3:"㌴";s:18:"ブッシェル";s:3:"㌵";s:9:"フラン";s:3:"㌶";s:15:"ヘクタール";s:3:"㌷";s:9:"ペソ";s:3:"㌸";s:12:"ペニヒ";s:3:"㌹";s:9:"ヘルツ";s:3:"㌺";s:12:"ペンス";s:3:"㌻";s:15:"ページ";s:3:"㌼";s:12:"ベータ";s:3:"㌽";s:15:"ポイント";s:3:"㌾";s:12:"ボルト";s:3:"㌿";s:6:"ホン";s:3:"㍀";s:15:"ポンド";s:3:"㍁";s:9:"ホール";s:3:"㍂";s:9:"ホーン";s:3:"㍃";s:12:"マイクロ";s:3:"㍄";s:9:"マイル";s:3:"㍅";s:9:"マッハ";s:3:"㍆";s:9:"マルク";s:3:"㍇";s:15:"マンション";s:3:"㍈";s:12:"ミクロン";s:3:"㍉";s:6:"ミリ";s:3:"㍊";s:18:"ミリバール";s:3:"㍋";s:9:"メガ";s:3:"㍌";s:15:"メガトン";s:3:"㍍";s:12:"メートル";s:3:"㍎";s:12:"ヤード";s:3:"㍏";s:9:"ヤール";s:3:"㍐";s:9:"ユアン";s:3:"㍑";s:12:"リットル";s:3:"㍒";s:6:"リラ";s:3:"㍓";s:12:"ルピー";s:3:"㍔";s:15:"ルーブル";s:3:"㍕";s:6:"レム";s:3:"㍖";s:18:"レントゲン";s:3:"㍗";s:9:"ワット";s:3:"㍘";s:4:"0点";s:3:"㍙";s:4:"1点";s:3:"㍚";s:4:"2点";s:3:"㍛";s:4:"3点";s:3:"㍜";s:4:"4点";s:3:"㍝";s:4:"5点";s:3:"㍞";s:4:"6点";s:3:"㍟";s:4:"7点";s:3:"㍠";s:4:"8点";s:3:"㍡";s:4:"9点";s:3:"㍢";s:5:"10点";s:3:"㍣";s:5:"11点";s:3:"㍤";s:5:"12点";s:3:"㍥";s:5:"13点";s:3:"㍦";s:5:"14点";s:3:"㍧";s:5:"15点";s:3:"㍨";s:5:"16点";s:3:"㍩";s:5:"17点";s:3:"㍪";s:5:"18点";s:3:"㍫";s:5:"19点";s:3:"㍬";s:5:"20点";s:3:"㍭";s:5:"21点";s:3:"㍮";s:5:"22点";s:3:"㍯";s:5:"23点";s:3:"㍰";s:5:"24点";s:3:"㍱";s:3:"hPa";s:3:"㍲";s:2:"da";s:3:"㍳";s:2:"AU";s:3:"㍴";s:3:"bar";s:3:"㍵";s:2:"oV";s:3:"㍶";s:2:"pc";s:3:"㍷";s:2:"dm";s:3:"㍸";s:3:"dm2";s:3:"㍹";s:3:"dm3";s:3:"㍺";s:2:"IU";s:3:"㍻";s:6:"平成";s:3:"㍼";s:6:"昭和";s:3:"㍽";s:6:"大正";s:3:"㍾";s:6:"明治";s:3:"㍿";s:12:"株式会社";s:3:"㎀";s:2:"pA";s:3:"㎁";s:2:"nA";s:3:"㎂";s:3:"μA";s:3:"㎃";s:2:"mA";s:3:"㎄";s:2:"kA";s:3:"㎅";s:2:"KB";s:3:"㎆";s:2:"MB";s:3:"㎇";s:2:"GB";s:3:"㎈";s:3:"cal";s:3:"㎉";s:4:"kcal";s:3:"㎊";s:2:"pF";s:3:"㎋";s:2:"nF";s:3:"㎌";s:3:"μF";s:3:"㎍";s:3:"μg";s:3:"㎎";s:2:"mg";s:3:"㎏";s:2:"kg";s:3:"㎐";s:2:"Hz";s:3:"㎑";s:3:"kHz";s:3:"㎒";s:3:"MHz";s:3:"㎓";s:3:"GHz";s:3:"㎔";s:3:"THz";s:3:"㎕";s:3:"μl";s:3:"㎖";s:2:"ml";s:3:"㎗";s:2:"dl";s:3:"㎘";s:2:"kl";s:3:"㎙";s:2:"fm";s:3:"㎚";s:2:"nm";s:3:"㎛";s:3:"μm";s:3:"㎜";s:2:"mm";s:3:"㎝";s:2:"cm";s:3:"㎞";s:2:"km";s:3:"㎟";s:3:"mm2";s:3:"㎠";s:3:"cm2";s:3:"㎡";s:2:"m2";s:3:"㎢";s:3:"km2";s:3:"㎣";s:3:"mm3";s:3:"㎤";s:3:"cm3";s:3:"㎥";s:2:"m3";s:3:"㎦";s:3:"km3";s:3:"㎧";s:5:"m∕s";s:3:"㎨";s:6:"m∕s2";s:3:"㎩";s:2:"Pa";s:3:"㎪";s:3:"kPa";s:3:"㎫";s:3:"MPa";s:3:"㎬";s:3:"GPa";s:3:"㎭";s:3:"rad";s:3:"㎮";s:7:"rad∕s";s:3:"㎯";s:8:"rad∕s2";s:3:"㎰";s:2:"ps";s:3:"㎱";s:2:"ns";s:3:"㎲";s:3:"μs";s:3:"㎳";s:2:"ms";s:3:"㎴";s:2:"pV";s:3:"㎵";s:2:"nV";s:3:"㎶";s:3:"μV";s:3:"㎷";s:2:"mV";s:3:"㎸";s:2:"kV";s:3:"㎹";s:2:"MV";s:3:"㎺";s:2:"pW";s:3:"㎻";s:2:"nW";s:3:"㎼";s:3:"μW";s:3:"㎽";s:2:"mW";s:3:"㎾";s:2:"kW";s:3:"㎿";s:2:"MW";s:3:"㏀";s:3:"kΩ";s:3:"㏁";s:3:"MΩ";s:3:"㏂";s:4:"a.m.";s:3:"㏃";s:2:"Bq";s:3:"㏄";s:2:"cc";s:3:"㏅";s:2:"cd";s:3:"㏆";s:6:"C∕kg";s:3:"㏇";s:3:"Co.";s:3:"㏈";s:2:"dB";s:3:"㏉";s:2:"Gy";s:3:"㏊";s:2:"ha";s:3:"㏋";s:2:"HP";s:3:"㏌";s:2:"in";s:3:"㏍";s:2:"KK";s:3:"㏎";s:2:"KM";s:3:"㏏";s:2:"kt";s:3:"㏐";s:2:"lm";s:3:"㏑";s:2:"ln";s:3:"㏒";s:3:"log";s:3:"㏓";s:2:"lx";s:3:"㏔";s:2:"mb";s:3:"㏕";s:3:"mil";s:3:"㏖";s:3:"mol";s:3:"㏗";s:2:"PH";s:3:"㏘";s:4:"p.m.";s:3:"㏙";s:3:"PPM";s:3:"㏚";s:2:"PR";s:3:"㏛";s:2:"sr";s:3:"㏜";s:2:"Sv";s:3:"㏝";s:2:"Wb";s:3:"㏞";s:5:"V∕m";s:3:"㏟";s:5:"A∕m";s:3:"㏠";s:4:"1日";s:3:"㏡";s:4:"2日";s:3:"㏢";s:4:"3日";s:3:"㏣";s:4:"4日";s:3:"㏤";s:4:"5日";s:3:"㏥";s:4:"6日";s:3:"㏦";s:4:"7日";s:3:"㏧";s:4:"8日";s:3:"㏨";s:4:"9日";s:3:"㏩";s:5:"10日";s:3:"㏪";s:5:"11日";s:3:"㏫";s:5:"12日";s:3:"㏬";s:5:"13日";s:3:"㏭";s:5:"14日";s:3:"㏮";s:5:"15日";s:3:"㏯";s:5:"16日";s:3:"㏰";s:5:"17日";s:3:"㏱";s:5:"18日";s:3:"㏲";s:5:"19日";s:3:"㏳";s:5:"20日";s:3:"㏴";s:5:"21日";s:3:"㏵";s:5:"22日";s:3:"㏶";s:5:"23日";s:3:"㏷";s:5:"24日";s:3:"㏸";s:5:"25日";s:3:"㏹";s:5:"26日";s:3:"㏺";s:5:"27日";s:3:"㏻";s:5:"28日";s:3:"㏼";s:5:"29日";s:3:"㏽";s:5:"30日";s:3:"㏾";s:5:"31日";s:3:"㏿";s:3:"gal";s:3:"豈";s:3:"豈";s:3:"更";s:3:"更";s:3:"車";s:3:"車";s:3:"賈";s:3:"賈";s:3:"滑";s:3:"滑";s:3:"串";s:3:"串";s:3:"句";s:3:"句";s:3:"龜";s:3:"龜";s:3:"龜";s:3:"龜";s:3:"契";s:3:"契";s:3:"金";s:3:"金";s:3:"喇";s:3:"喇";s:3:"奈";s:3:"奈";s:3:"懶";s:3:"懶";s:3:"癩";s:3:"癩";s:3:"羅";s:3:"羅";s:3:"蘿";s:3:"蘿";s:3:"螺";s:3:"螺";s:3:"裸";s:3:"裸";s:3:"邏";s:3:"邏";s:3:"樂";s:3:"樂";s:3:"洛";s:3:"洛";s:3:"烙";s:3:"烙";s:3:"珞";s:3:"珞";s:3:"落";s:3:"落";s:3:"酪";s:3:"酪";s:3:"駱";s:3:"駱";s:3:"亂";s:3:"亂";s:3:"卵";s:3:"卵";s:3:"欄";s:3:"欄";s:3:"爛";s:3:"爛";s:3:"蘭";s:3:"蘭";s:3:"鸞";s:3:"鸞";s:3:"嵐";s:3:"嵐";s:3:"濫";s:3:"濫";s:3:"藍";s:3:"藍";s:3:"襤";s:3:"襤";s:3:"拉";s:3:"拉";s:3:"臘";s:3:"臘";s:3:"蠟";s:3:"蠟";s:3:"廊";s:3:"廊";s:3:"朗";s:3:"朗";s:3:"浪";s:3:"浪";s:3:"狼";s:3:"狼";s:3:"郎";s:3:"郎";s:3:"來";s:3:"來";s:3:"冷";s:3:"冷";s:3:"勞";s:3:"勞";s:3:"擄";s:3:"擄";s:3:"櫓";s:3:"櫓";s:3:"爐";s:3:"爐";s:3:"盧";s:3:"盧";s:3:"老";s:3:"老";s:3:"蘆";s:3:"蘆";s:3:"虜";s:3:"虜";s:3:"路";s:3:"路";s:3:"露";s:3:"露";s:3:"魯";s:3:"魯";s:3:"鷺";s:3:"鷺";s:3:"碌";s:3:"碌";s:3:"祿";s:3:"祿";s:3:"綠";s:3:"綠";s:3:"菉";s:3:"菉";s:3:"錄";s:3:"錄";s:3:"鹿";s:3:"鹿";s:3:"論";s:3:"論";s:3:"壟";s:3:"壟";s:3:"弄";s:3:"弄";s:3:"籠";s:3:"籠";s:3:"聾";s:3:"聾";s:3:"牢";s:3:"牢";s:3:"磊";s:3:"磊";s:3:"賂";s:3:"賂";s:3:"雷";s:3:"雷";s:3:"壘";s:3:"壘";s:3:"屢";s:3:"屢";s:3:"樓";s:3:"樓";s:3:"淚";s:3:"淚";s:3:"漏";s:3:"漏";s:3:"累";s:3:"累";s:3:"縷";s:3:"縷";s:3:"陋";s:3:"陋";s:3:"勒";s:3:"勒";s:3:"肋";s:3:"肋";s:3:"凜";s:3:"凜";s:3:"凌";s:3:"凌";s:3:"稜";s:3:"稜";s:3:"綾";s:3:"綾";s:3:"菱";s:3:"菱";s:3:"陵";s:3:"陵";s:3:"讀";s:3:"讀";s:3:"拏";s:3:"拏";s:3:"樂";s:3:"樂";s:3:"諾";s:3:"諾";s:3:"丹";s:3:"丹";s:3:"寧";s:3:"寧";s:3:"怒";s:3:"怒";s:3:"率";s:3:"率";s:3:"異";s:3:"異";s:3:"北";s:3:"北";s:3:"磻";s:3:"磻";s:3:"便";s:3:"便";s:3:"復";s:3:"復";s:3:"不";s:3:"不";s:3:"泌";s:3:"泌";s:3:"數";s:3:"數";s:3:"索";s:3:"索";s:3:"參";s:3:"參";s:3:"塞";s:3:"塞";s:3:"省";s:3:"省";s:3:"葉";s:3:"葉";s:3:"說";s:3:"說";s:3:"殺";s:3:"殺";s:3:"辰";s:3:"辰";s:3:"沈";s:3:"沈";s:3:"拾";s:3:"拾";s:3:"若";s:3:"若";s:3:"掠";s:3:"掠";s:3:"略";s:3:"略";s:3:"亮";s:3:"亮";s:3:"兩";s:3:"兩";s:3:"凉";s:3:"凉";s:3:"梁";s:3:"梁";s:3:"糧";s:3:"糧";s:3:"良";s:3:"良";s:3:"諒";s:3:"諒";s:3:"量";s:3:"量";s:3:"勵";s:3:"勵";s:3:"呂";s:3:"呂";s:3:"女";s:3:"女";s:3:"廬";s:3:"廬";s:3:"旅";s:3:"旅";s:3:"濾";s:3:"濾";s:3:"礪";s:3:"礪";s:3:"閭";s:3:"閭";s:3:"驪";s:3:"驪";s:3:"麗";s:3:"麗";s:3:"黎";s:3:"黎";s:3:"力";s:3:"力";s:3:"曆";s:3:"曆";s:3:"歷";s:3:"歷";s:3:"轢";s:3:"轢";s:3:"年";s:3:"年";s:3:"憐";s:3:"憐";s:3:"戀";s:3:"戀";s:3:"撚";s:3:"撚";s:3:"漣";s:3:"漣";s:3:"煉";s:3:"煉";s:3:"璉";s:3:"璉";s:3:"秊";s:3:"秊";s:3:"練";s:3:"練";s:3:"聯";s:3:"聯";s:3:"輦";s:3:"輦";s:3:"蓮";s:3:"蓮";s:3:"連";s:3:"連";s:3:"鍊";s:3:"鍊";s:3:"列";s:3:"列";s:3:"劣";s:3:"劣";s:3:"咽";s:3:"咽";s:3:"烈";s:3:"烈";s:3:"裂";s:3:"裂";s:3:"說";s:3:"說";s:3:"廉";s:3:"廉";s:3:"念";s:3:"念";s:3:"捻";s:3:"捻";s:3:"殮";s:3:"殮";s:3:"簾";s:3:"簾";s:3:"獵";s:3:"獵";s:3:"令";s:3:"令";s:3:"囹";s:3:"囹";s:3:"寧";s:3:"寧";s:3:"嶺";s:3:"嶺";s:3:"怜";s:3:"怜";s:3:"玲";s:3:"玲";s:3:"瑩";s:3:"瑩";s:3:"羚";s:3:"羚";s:3:"聆";s:3:"聆";s:3:"鈴";s:3:"鈴";s:3:"零";s:3:"零";s:3:"靈";s:3:"靈";s:3:"領";s:3:"領";s:3:"例";s:3:"例";s:3:"禮";s:3:"禮";s:3:"醴";s:3:"醴";s:3:"隸";s:3:"隸";s:3:"惡";s:3:"惡";s:3:"了";s:3:"了";s:3:"僚";s:3:"僚";s:3:"寮";s:3:"寮";s:3:"尿";s:3:"尿";s:3:"料";s:3:"料";s:3:"樂";s:3:"樂";s:3:"燎";s:3:"燎";s:3:"療";s:3:"療";s:3:"蓼";s:3:"蓼";s:3:"遼";s:3:"遼";s:3:"龍";s:3:"龍";s:3:"暈";s:3:"暈";s:3:"阮";s:3:"阮";s:3:"劉";s:3:"劉";s:3:"杻";s:3:"杻";s:3:"柳";s:3:"柳";s:3:"流";s:3:"流";s:3:"溜";s:3:"溜";s:3:"琉";s:3:"琉";s:3:"留";s:3:"留";s:3:"硫";s:3:"硫";s:3:"紐";s:3:"紐";s:3:"類";s:3:"類";s:3:"六";s:3:"六";s:3:"戮";s:3:"戮";s:3:"陸";s:3:"陸";s:3:"倫";s:3:"倫";s:3:"崙";s:3:"崙";s:3:"淪";s:3:"淪";s:3:"輪";s:3:"輪";s:3:"律";s:3:"律";s:3:"慄";s:3:"慄";s:3:"栗";s:3:"栗";s:3:"率";s:3:"率";s:3:"隆";s:3:"隆";s:3:"利";s:3:"利";s:3:"吏";s:3:"吏";s:3:"履";s:3:"履";s:3:"易";s:3:"易";s:3:"李";s:3:"李";s:3:"梨";s:3:"梨";s:3:"泥";s:3:"泥";s:3:"理";s:3:"理";s:3:"痢";s:3:"痢";s:3:"罹";s:3:"罹";s:3:"裏";s:3:"裏";s:3:"裡";s:3:"裡";s:3:"里";s:3:"里";s:3:"離";s:3:"離";s:3:"匿";s:3:"匿";s:3:"溺";s:3:"溺";s:3:"吝";s:3:"吝";s:3:"燐";s:3:"燐";s:3:"璘";s:3:"璘";s:3:"藺";s:3:"藺";s:3:"隣";s:3:"隣";s:3:"鱗";s:3:"鱗";s:3:"麟";s:3:"麟";s:3:"林";s:3:"林";s:3:"淋";s:3:"淋";s:3:"臨";s:3:"臨";s:3:"立";s:3:"立";s:3:"笠";s:3:"笠";s:3:"粒";s:3:"粒";s:3:"狀";s:3:"狀";s:3:"炙";s:3:"炙";s:3:"識";s:3:"識";s:3:"什";s:3:"什";s:3:"茶";s:3:"茶";s:3:"刺";s:3:"刺";s:3:"切";s:3:"切";s:3:"度";s:3:"度";s:3:"拓";s:3:"拓";s:3:"糖";s:3:"糖";s:3:"宅";s:3:"宅";s:3:"洞";s:3:"洞";s:3:"暴";s:3:"暴";s:3:"輻";s:3:"輻";s:3:"行";s:3:"行";s:3:"降";s:3:"降";s:3:"見";s:3:"見";s:3:"廓";s:3:"廓";s:3:"兀";s:3:"兀";s:3:"嗀";s:3:"嗀";s:3:"塚";s:3:"塚";s:3:"晴";s:3:"晴";s:3:"凞";s:3:"凞";s:3:"猪";s:3:"猪";s:3:"益";s:3:"益";s:3:"礼";s:3:"礼";s:3:"神";s:3:"神";s:3:"祥";s:3:"祥";s:3:"福";s:3:"福";s:3:"靖";s:3:"靖";s:3:"精";s:3:"精";s:3:"羽";s:3:"羽";s:3:"蘒";s:3:"蘒";s:3:"諸";s:3:"諸";s:3:"逸";s:3:"逸";s:3:"都";s:3:"都";s:3:"飯";s:3:"飯";s:3:"飼";s:3:"飼";s:3:"館";s:3:"館";s:3:"鶴";s:3:"鶴";s:3:"侮";s:3:"侮";s:3:"僧";s:3:"僧";s:3:"免";s:3:"免";s:3:"勉";s:3:"勉";s:3:"勤";s:3:"勤";s:3:"卑";s:3:"卑";s:3:"喝";s:3:"喝";s:3:"嘆";s:3:"嘆";s:3:"器";s:3:"器";s:3:"塀";s:3:"塀";s:3:"墨";s:3:"墨";s:3:"層";s:3:"層";s:3:"屮";s:3:"屮";s:3:"悔";s:3:"悔";s:3:"慨";s:3:"慨";s:3:"憎";s:3:"憎";s:3:"懲";s:3:"懲";s:3:"敏";s:3:"敏";s:3:"既";s:3:"既";s:3:"暑";s:3:"暑";s:3:"梅";s:3:"梅";s:3:"海";s:3:"海";s:3:"渚";s:3:"渚";s:3:"漢";s:3:"漢";s:3:"煮";s:3:"煮";s:3:"爫";s:3:"爫";s:3:"琢";s:3:"琢";s:3:"碑";s:3:"碑";s:3:"社";s:3:"社";s:3:"祉";s:3:"祉";s:3:"祈";s:3:"祈";s:3:"祐";s:3:"祐";s:3:"祖";s:3:"祖";s:3:"祝";s:3:"祝";s:3:"禍";s:3:"禍";s:3:"禎";s:3:"禎";s:3:"穀";s:3:"穀";s:3:"突";s:3:"突";s:3:"節";s:3:"節";s:3:"練";s:3:"練";s:3:"縉";s:3:"縉";s:3:"繁";s:3:"繁";s:3:"署";s:3:"署";s:3:"者";s:3:"者";s:3:"臭";s:3:"臭";s:3:"艹";s:3:"艹";s:3:"艹";s:3:"艹";s:3:"著";s:3:"著";s:3:"褐";s:3:"褐";s:3:"視";s:3:"視";s:3:"謁";s:3:"謁";s:3:"謹";s:3:"謹";s:3:"賓";s:3:"賓";s:3:"贈";s:3:"贈";s:3:"辶";s:3:"辶";s:3:"逸";s:3:"逸";s:3:"難";s:3:"難";s:3:"響";s:3:"響";s:3:"頻";s:3:"頻";s:3:"並";s:3:"並";s:3:"况";s:3:"况";s:3:"全";s:3:"全";s:3:"侀";s:3:"侀";s:3:"充";s:3:"充";s:3:"冀";s:3:"冀";s:3:"勇";s:3:"勇";s:3:"勺";s:3:"勺";s:3:"喝";s:3:"喝";s:3:"啕";s:3:"啕";s:3:"喙";s:3:"喙";s:3:"嗢";s:3:"嗢";s:3:"塚";s:3:"塚";s:3:"墳";s:3:"墳";s:3:"奄";s:3:"奄";s:3:"奔";s:3:"奔";s:3:"婢";s:3:"婢";s:3:"嬨";s:3:"嬨";s:3:"廒";s:3:"廒";s:3:"廙";s:3:"廙";s:3:"彩";s:3:"彩";s:3:"徭";s:3:"徭";s:3:"惘";s:3:"惘";s:3:"慎";s:3:"慎";s:3:"愈";s:3:"愈";s:3:"憎";s:3:"憎";s:3:"慠";s:3:"慠";s:3:"懲";s:3:"懲";s:3:"戴";s:3:"戴";s:3:"揄";s:3:"揄";s:3:"搜";s:3:"搜";s:3:"摒";s:3:"摒";s:3:"敖";s:3:"敖";s:3:"晴";s:3:"晴";s:3:"朗";s:3:"朗";s:3:"望";s:3:"望";s:3:"杖";s:3:"杖";s:3:"歹";s:3:"歹";s:3:"殺";s:3:"殺";s:3:"流";s:3:"流";s:3:"滛";s:3:"滛";s:3:"滋";s:3:"滋";s:3:"漢";s:3:"漢";s:3:"瀞";s:3:"瀞";s:3:"煮";s:3:"煮";s:3:"瞧";s:3:"瞧";s:3:"爵";s:3:"爵";s:3:"犯";s:3:"犯";s:3:"猪";s:3:"猪";s:3:"瑱";s:3:"瑱";s:3:"甆";s:3:"甆";s:3:"画";s:3:"画";s:3:"瘝";s:3:"瘝";s:3:"瘟";s:3:"瘟";s:3:"益";s:3:"益";s:3:"盛";s:3:"盛";s:3:"直";s:3:"直";s:3:"睊";s:3:"睊";s:3:"着";s:3:"着";s:3:"磌";s:3:"磌";s:3:"窱";s:3:"窱";s:3:"節";s:3:"節";s:3:"类";s:3:"类";s:3:"絛";s:3:"絛";s:3:"練";s:3:"練";s:3:"缾";s:3:"缾";s:3:"者";s:3:"者";s:3:"荒";s:3:"荒";s:3:"華";s:3:"華";s:3:"蝹";s:3:"蝹";s:3:"襁";s:3:"襁";s:3:"覆";s:3:"覆";s:3:"視";s:3:"視";s:3:"調";s:3:"調";s:3:"諸";s:3:"諸";s:3:"請";s:3:"請";s:3:"謁";s:3:"謁";s:3:"諾";s:3:"諾";s:3:"諭";s:3:"諭";s:3:"謹";s:3:"謹";s:3:"變";s:3:"變";s:3:"贈";s:3:"贈";s:3:"輸";s:3:"輸";s:3:"遲";s:3:"遲";s:3:"醙";s:3:"醙";s:3:"鉶";s:3:"鉶";s:3:"陼";s:3:"陼";s:3:"難";s:3:"難";s:3:"靖";s:3:"靖";s:3:"韛";s:3:"韛";s:3:"響";s:3:"響";s:3:"頋";s:3:"頋";s:3:"頻";s:3:"頻";s:3:"鬒";s:3:"鬒";s:3:"龜";s:3:"龜";s:3:"𢡊";s:4:"𢡊";s:3:"𢡄";s:4:"𢡄";s:3:"𣏕";s:4:"𣏕";s:3:"㮝";s:3:"㮝";s:3:"䀘";s:3:"䀘";s:3:"䀹";s:3:"䀹";s:3:"𥉉";s:4:"𥉉";s:3:"𥳐";s:4:"𥳐";s:3:"𧻓";s:4:"𧻓";s:3:"齃";s:3:"齃";s:3:"龎";s:3:"龎";s:3:"ff";s:2:"ff";s:3:"fi";s:2:"fi";s:3:"fl";s:2:"fl";s:3:"ffi";s:3:"ffi";s:3:"ffl";s:3:"ffl";s:3:"ſt";s:2:"st";s:3:"st";s:2:"st";s:3:"ﬓ";s:4:"մն";s:3:"ﬔ";s:4:"մե";s:3:"ﬕ";s:4:"մի";s:3:"ﬖ";s:4:"վն";s:3:"ﬗ";s:4:"մխ";s:3:"יִ";s:4:"יִ";s:3:"ײַ";s:4:"ײַ";s:3:"ﬠ";s:2:"ע";s:3:"ﬡ";s:2:"א";s:3:"ﬢ";s:2:"ד";s:3:"ﬣ";s:2:"ה";s:3:"ﬤ";s:2:"כ";s:3:"ﬥ";s:2:"ל";s:3:"ﬦ";s:2:"ם";s:3:"ﬧ";s:2:"ר";s:3:"ﬨ";s:2:"ת";s:3:"﬩";s:1:"+";s:3:"שׁ";s:4:"שׁ";s:3:"שׂ";s:4:"שׂ";s:3:"שּׁ";s:6:"שּׁ";s:3:"שּׂ";s:6:"שּׂ";s:3:"אַ";s:4:"אַ";s:3:"אָ";s:4:"אָ";s:3:"אּ";s:4:"אּ";s:3:"בּ";s:4:"בּ";s:3:"גּ";s:4:"גּ";s:3:"דּ";s:4:"דּ";s:3:"הּ";s:4:"הּ";s:3:"וּ";s:4:"וּ";s:3:"זּ";s:4:"זּ";s:3:"טּ";s:4:"טּ";s:3:"יּ";s:4:"יּ";s:3:"ךּ";s:4:"ךּ";s:3:"כּ";s:4:"כּ";s:3:"לּ";s:4:"לּ";s:3:"מּ";s:4:"מּ";s:3:"נּ";s:4:"נּ";s:3:"סּ";s:4:"סּ";s:3:"ףּ";s:4:"ףּ";s:3:"פּ";s:4:"פּ";s:3:"צּ";s:4:"צּ";s:3:"קּ";s:4:"קּ";s:3:"רּ";s:4:"רּ";s:3:"שּ";s:4:"שּ";s:3:"תּ";s:4:"תּ";s:3:"וֹ";s:4:"וֹ";s:3:"בֿ";s:4:"בֿ";s:3:"כֿ";s:4:"כֿ";s:3:"פֿ";s:4:"פֿ";s:3:"ﭏ";s:4:"אל";s:3:"ﭐ";s:2:"ٱ";s:3:"ﭑ";s:2:"ٱ";s:3:"ﭒ";s:2:"ٻ";s:3:"ﭓ";s:2:"ٻ";s:3:"ﭔ";s:2:"ٻ";s:3:"ﭕ";s:2:"ٻ";s:3:"ﭖ";s:2:"پ";s:3:"ﭗ";s:2:"پ";s:3:"ﭘ";s:2:"پ";s:3:"ﭙ";s:2:"پ";s:3:"ﭚ";s:2:"ڀ";s:3:"ﭛ";s:2:"ڀ";s:3:"ﭜ";s:2:"ڀ";s:3:"ﭝ";s:2:"ڀ";s:3:"ﭞ";s:2:"ٺ";s:3:"ﭟ";s:2:"ٺ";s:3:"ﭠ";s:2:"ٺ";s:3:"ﭡ";s:2:"ٺ";s:3:"ﭢ";s:2:"ٿ";s:3:"ﭣ";s:2:"ٿ";s:3:"ﭤ";s:2:"ٿ";s:3:"ﭥ";s:2:"ٿ";s:3:"ﭦ";s:2:"ٹ";s:3:"ﭧ";s:2:"ٹ";s:3:"ﭨ";s:2:"ٹ";s:3:"ﭩ";s:2:"ٹ";s:3:"ﭪ";s:2:"ڤ";s:3:"ﭫ";s:2:"ڤ";s:3:"ﭬ";s:2:"ڤ";s:3:"ﭭ";s:2:"ڤ";s:3:"ﭮ";s:2:"ڦ";s:3:"ﭯ";s:2:"ڦ";s:3:"ﭰ";s:2:"ڦ";s:3:"ﭱ";s:2:"ڦ";s:3:"ﭲ";s:2:"ڄ";s:3:"ﭳ";s:2:"ڄ";s:3:"ﭴ";s:2:"ڄ";s:3:"ﭵ";s:2:"ڄ";s:3:"ﭶ";s:2:"ڃ";s:3:"ﭷ";s:2:"ڃ";s:3:"ﭸ";s:2:"ڃ";s:3:"ﭹ";s:2:"ڃ";s:3:"ﭺ";s:2:"چ";s:3:"ﭻ";s:2:"چ";s:3:"ﭼ";s:2:"چ";s:3:"ﭽ";s:2:"چ";s:3:"ﭾ";s:2:"ڇ";s:3:"ﭿ";s:2:"ڇ";s:3:"ﮀ";s:2:"ڇ";s:3:"ﮁ";s:2:"ڇ";s:3:"ﮂ";s:2:"ڍ";s:3:"ﮃ";s:2:"ڍ";s:3:"ﮄ";s:2:"ڌ";s:3:"ﮅ";s:2:"ڌ";s:3:"ﮆ";s:2:"ڎ";s:3:"ﮇ";s:2:"ڎ";s:3:"ﮈ";s:2:"ڈ";s:3:"ﮉ";s:2:"ڈ";s:3:"ﮊ";s:2:"ژ";s:3:"ﮋ";s:2:"ژ";s:3:"ﮌ";s:2:"ڑ";s:3:"ﮍ";s:2:"ڑ";s:3:"ﮎ";s:2:"ک";s:3:"ﮏ";s:2:"ک";s:3:"ﮐ";s:2:"ک";s:3:"ﮑ";s:2:"ک";s:3:"ﮒ";s:2:"گ";s:3:"ﮓ";s:2:"گ";s:3:"ﮔ";s:2:"گ";s:3:"ﮕ";s:2:"گ";s:3:"ﮖ";s:2:"ڳ";s:3:"ﮗ";s:2:"ڳ";s:3:"ﮘ";s:2:"ڳ";s:3:"ﮙ";s:2:"ڳ";s:3:"ﮚ";s:2:"ڱ";s:3:"ﮛ";s:2:"ڱ";s:3:"ﮜ";s:2:"ڱ";s:3:"ﮝ";s:2:"ڱ";s:3:"ﮞ";s:2:"ں";s:3:"ﮟ";s:2:"ں";s:3:"ﮠ";s:2:"ڻ";s:3:"ﮡ";s:2:"ڻ";s:3:"ﮢ";s:2:"ڻ";s:3:"ﮣ";s:2:"ڻ";s:3:"ﮤ";s:4:"ۀ";s:3:"ﮥ";s:4:"ۀ";s:3:"ﮦ";s:2:"ہ";s:3:"ﮧ";s:2:"ہ";s:3:"ﮨ";s:2:"ہ";s:3:"ﮩ";s:2:"ہ";s:3:"ﮪ";s:2:"ھ";s:3:"ﮫ";s:2:"ھ";s:3:"ﮬ";s:2:"ھ";s:3:"ﮭ";s:2:"ھ";s:3:"ﮮ";s:2:"ے";s:3:"ﮯ";s:2:"ے";s:3:"ﮰ";s:4:"ۓ";s:3:"ﮱ";s:4:"ۓ";s:3:"ﯓ";s:2:"ڭ";s:3:"ﯔ";s:2:"ڭ";s:3:"ﯕ";s:2:"ڭ";s:3:"ﯖ";s:2:"ڭ";s:3:"ﯗ";s:2:"ۇ";s:3:"ﯘ";s:2:"ۇ";s:3:"ﯙ";s:2:"ۆ";s:3:"ﯚ";s:2:"ۆ";s:3:"ﯛ";s:2:"ۈ";s:3:"ﯜ";s:2:"ۈ";s:3:"ﯝ";s:4:"ۇٴ";s:3:"ﯞ";s:2:"ۋ";s:3:"ﯟ";s:2:"ۋ";s:3:"ﯠ";s:2:"ۅ";s:3:"ﯡ";s:2:"ۅ";s:3:"ﯢ";s:2:"ۉ";s:3:"ﯣ";s:2:"ۉ";s:3:"ﯤ";s:2:"ې";s:3:"ﯥ";s:2:"ې";s:3:"ﯦ";s:2:"ې";s:3:"ﯧ";s:2:"ې";s:3:"ﯨ";s:2:"ى";s:3:"ﯩ";s:2:"ى";s:3:"ﯪ";s:6:"ئا";s:3:"ﯫ";s:6:"ئا";s:3:"ﯬ";s:6:"ئە";s:3:"ﯭ";s:6:"ئە";s:3:"ﯮ";s:6:"ئو";s:3:"ﯯ";s:6:"ئو";s:3:"ﯰ";s:6:"ئۇ";s:3:"ﯱ";s:6:"ئۇ";s:3:"ﯲ";s:6:"ئۆ";s:3:"ﯳ";s:6:"ئۆ";s:3:"ﯴ";s:6:"ئۈ";s:3:"ﯵ";s:6:"ئۈ";s:3:"ﯶ";s:6:"ئې";s:3:"ﯷ";s:6:"ئې";s:3:"ﯸ";s:6:"ئې";s:3:"ﯹ";s:6:"ئى";s:3:"ﯺ";s:6:"ئى";s:3:"ﯻ";s:6:"ئى";s:3:"ﯼ";s:2:"ی";s:3:"ﯽ";s:2:"ی";s:3:"ﯾ";s:2:"ی";s:3:"ﯿ";s:2:"ی";s:3:"ﰀ";s:6:"ئج";s:3:"ﰁ";s:6:"ئح";s:3:"ﰂ";s:6:"ئم";s:3:"ﰃ";s:6:"ئى";s:3:"ﰄ";s:6:"ئي";s:3:"ﰅ";s:4:"بج";s:3:"ﰆ";s:4:"بح";s:3:"ﰇ";s:4:"بخ";s:3:"ﰈ";s:4:"بم";s:3:"ﰉ";s:4:"بى";s:3:"ﰊ";s:4:"بي";s:3:"ﰋ";s:4:"تج";s:3:"ﰌ";s:4:"تح";s:3:"ﰍ";s:4:"تخ";s:3:"ﰎ";s:4:"تم";s:3:"ﰏ";s:4:"تى";s:3:"ﰐ";s:4:"تي";s:3:"ﰑ";s:4:"ثج";s:3:"ﰒ";s:4:"ثم";s:3:"ﰓ";s:4:"ثى";s:3:"ﰔ";s:4:"ثي";s:3:"ﰕ";s:4:"جح";s:3:"ﰖ";s:4:"جم";s:3:"ﰗ";s:4:"حج";s:3:"ﰘ";s:4:"حم";s:3:"ﰙ";s:4:"خج";s:3:"ﰚ";s:4:"خح";s:3:"ﰛ";s:4:"خم";s:3:"ﰜ";s:4:"سج";s:3:"ﰝ";s:4:"سح";s:3:"ﰞ";s:4:"سخ";s:3:"ﰟ";s:4:"سم";s:3:"ﰠ";s:4:"صح";s:3:"ﰡ";s:4:"صم";s:3:"ﰢ";s:4:"ضج";s:3:"ﰣ";s:4:"ضح";s:3:"ﰤ";s:4:"ضخ";s:3:"ﰥ";s:4:"ضم";s:3:"ﰦ";s:4:"طح";s:3:"ﰧ";s:4:"طم";s:3:"ﰨ";s:4:"ظم";s:3:"ﰩ";s:4:"عج";s:3:"ﰪ";s:4:"عم";s:3:"ﰫ";s:4:"غج";s:3:"ﰬ";s:4:"غم";s:3:"ﰭ";s:4:"فج";s:3:"ﰮ";s:4:"فح";s:3:"ﰯ";s:4:"فخ";s:3:"ﰰ";s:4:"فم";s:3:"ﰱ";s:4:"فى";s:3:"ﰲ";s:4:"في";s:3:"ﰳ";s:4:"قح";s:3:"ﰴ";s:4:"قم";s:3:"ﰵ";s:4:"قى";s:3:"ﰶ";s:4:"قي";s:3:"ﰷ";s:4:"كا";s:3:"ﰸ";s:4:"كج";s:3:"ﰹ";s:4:"كح";s:3:"ﰺ";s:4:"كخ";s:3:"ﰻ";s:4:"كل";s:3:"ﰼ";s:4:"كم";s:3:"ﰽ";s:4:"كى";s:3:"ﰾ";s:4:"كي";s:3:"ﰿ";s:4:"لج";s:3:"ﱀ";s:4:"لح";s:3:"ﱁ";s:4:"لخ";s:3:"ﱂ";s:4:"لم";s:3:"ﱃ";s:4:"لى";s:3:"ﱄ";s:4:"لي";s:3:"ﱅ";s:4:"مج";s:3:"ﱆ";s:4:"مح";s:3:"ﱇ";s:4:"مخ";s:3:"ﱈ";s:4:"مم";s:3:"ﱉ";s:4:"مى";s:3:"ﱊ";s:4:"مي";s:3:"ﱋ";s:4:"نج";s:3:"ﱌ";s:4:"نح";s:3:"ﱍ";s:4:"نخ";s:3:"ﱎ";s:4:"نم";s:3:"ﱏ";s:4:"نى";s:3:"ﱐ";s:4:"ني";s:3:"ﱑ";s:4:"هج";s:3:"ﱒ";s:4:"هم";s:3:"ﱓ";s:4:"هى";s:3:"ﱔ";s:4:"هي";s:3:"ﱕ";s:4:"يج";s:3:"ﱖ";s:4:"يح";s:3:"ﱗ";s:4:"يخ";s:3:"ﱘ";s:4:"يم";s:3:"ﱙ";s:4:"يى";s:3:"ﱚ";s:4:"يي";s:3:"ﱛ";s:4:"ذٰ";s:3:"ﱜ";s:4:"رٰ";s:3:"ﱝ";s:4:"ىٰ";s:3:"ﱞ";s:5:" ٌّ";s:3:"ﱟ";s:5:" ٍّ";s:3:"ﱠ";s:5:" َّ";s:3:"ﱡ";s:5:" ُّ";s:3:"ﱢ";s:5:" ِّ";s:3:"ﱣ";s:5:" ّٰ";s:3:"ﱤ";s:6:"ئر";s:3:"ﱥ";s:6:"ئز";s:3:"ﱦ";s:6:"ئم";s:3:"ﱧ";s:6:"ئن";s:3:"ﱨ";s:6:"ئى";s:3:"ﱩ";s:6:"ئي";s:3:"ﱪ";s:4:"بر";s:3:"ﱫ";s:4:"بز";s:3:"ﱬ";s:4:"بم";s:3:"ﱭ";s:4:"بن";s:3:"ﱮ";s:4:"بى";s:3:"ﱯ";s:4:"بي";s:3:"ﱰ";s:4:"تر";s:3:"ﱱ";s:4:"تز";s:3:"ﱲ";s:4:"تم";s:3:"ﱳ";s:4:"تن";s:3:"ﱴ";s:4:"تى";s:3:"ﱵ";s:4:"تي";s:3:"ﱶ";s:4:"ثر";s:3:"ﱷ";s:4:"ثز";s:3:"ﱸ";s:4:"ثم";s:3:"ﱹ";s:4:"ثن";s:3:"ﱺ";s:4:"ثى";s:3:"ﱻ";s:4:"ثي";s:3:"ﱼ";s:4:"فى";s:3:"ﱽ";s:4:"في";s:3:"ﱾ";s:4:"قى";s:3:"ﱿ";s:4:"قي";s:3:"ﲀ";s:4:"كا";s:3:"ﲁ";s:4:"كل";s:3:"ﲂ";s:4:"كم";s:3:"ﲃ";s:4:"كى";s:3:"ﲄ";s:4:"كي";s:3:"ﲅ";s:4:"لم";s:3:"ﲆ";s:4:"لى";s:3:"ﲇ";s:4:"لي";s:3:"ﲈ";s:4:"ما";s:3:"ﲉ";s:4:"مم";s:3:"ﲊ";s:4:"نر";s:3:"ﲋ";s:4:"نز";s:3:"ﲌ";s:4:"نم";s:3:"ﲍ";s:4:"نن";s:3:"ﲎ";s:4:"نى";s:3:"ﲏ";s:4:"ني";s:3:"ﲐ";s:4:"ىٰ";s:3:"ﲑ";s:4:"ير";s:3:"ﲒ";s:4:"يز";s:3:"ﲓ";s:4:"يم";s:3:"ﲔ";s:4:"ين";s:3:"ﲕ";s:4:"يى";s:3:"ﲖ";s:4:"يي";s:3:"ﲗ";s:6:"ئج";s:3:"ﲘ";s:6:"ئح";s:3:"ﲙ";s:6:"ئخ";s:3:"ﲚ";s:6:"ئم";s:3:"ﲛ";s:6:"ئه";s:3:"ﲜ";s:4:"بج";s:3:"ﲝ";s:4:"بح";s:3:"ﲞ";s:4:"بخ";s:3:"ﲟ";s:4:"بم";s:3:"ﲠ";s:4:"به";s:3:"ﲡ";s:4:"تج";s:3:"ﲢ";s:4:"تح";s:3:"ﲣ";s:4:"تخ";s:3:"ﲤ";s:4:"تم";s:3:"ﲥ";s:4:"ته";s:3:"ﲦ";s:4:"ثم";s:3:"ﲧ";s:4:"جح";s:3:"ﲨ";s:4:"جم";s:3:"ﲩ";s:4:"حج";s:3:"ﲪ";s:4:"حم";s:3:"ﲫ";s:4:"خج";s:3:"ﲬ";s:4:"خم";s:3:"ﲭ";s:4:"سج";s:3:"ﲮ";s:4:"سح";s:3:"ﲯ";s:4:"سخ";s:3:"ﲰ";s:4:"سم";s:3:"ﲱ";s:4:"صح";s:3:"ﲲ";s:4:"صخ";s:3:"ﲳ";s:4:"صم";s:3:"ﲴ";s:4:"ضج";s:3:"ﲵ";s:4:"ضح";s:3:"ﲶ";s:4:"ضخ";s:3:"ﲷ";s:4:"ضم";s:3:"ﲸ";s:4:"طح";s:3:"ﲹ";s:4:"ظم";s:3:"ﲺ";s:4:"عج";s:3:"ﲻ";s:4:"عم";s:3:"ﲼ";s:4:"غج";s:3:"ﲽ";s:4:"غم";s:3:"ﲾ";s:4:"فج";s:3:"ﲿ";s:4:"فح";s:3:"ﳀ";s:4:"فخ";s:3:"ﳁ";s:4:"فم";s:3:"ﳂ";s:4:"قح";s:3:"ﳃ";s:4:"قم";s:3:"ﳄ";s:4:"كج";s:3:"ﳅ";s:4:"كح";s:3:"ﳆ";s:4:"كخ";s:3:"ﳇ";s:4:"كل";s:3:"ﳈ";s:4:"كم";s:3:"ﳉ";s:4:"لج";s:3:"ﳊ";s:4:"لح";s:3:"ﳋ";s:4:"لخ";s:3:"ﳌ";s:4:"لم";s:3:"ﳍ";s:4:"له";s:3:"ﳎ";s:4:"مج";s:3:"ﳏ";s:4:"مح";s:3:"ﳐ";s:4:"مخ";s:3:"ﳑ";s:4:"مم";s:3:"ﳒ";s:4:"نج";s:3:"ﳓ";s:4:"نح";s:3:"ﳔ";s:4:"نخ";s:3:"ﳕ";s:4:"نم";s:3:"ﳖ";s:4:"نه";s:3:"ﳗ";s:4:"هج";s:3:"ﳘ";s:4:"هم";s:3:"ﳙ";s:4:"هٰ";s:3:"ﳚ";s:4:"يج";s:3:"ﳛ";s:4:"يح";s:3:"ﳜ";s:4:"يخ";s:3:"ﳝ";s:4:"يم";s:3:"ﳞ";s:4:"يه";s:3:"ﳟ";s:6:"ئم";s:3:"ﳠ";s:6:"ئه";s:3:"ﳡ";s:4:"بم";s:3:"ﳢ";s:4:"به";s:3:"ﳣ";s:4:"تم";s:3:"ﳤ";s:4:"ته";s:3:"ﳥ";s:4:"ثم";s:3:"ﳦ";s:4:"ثه";s:3:"ﳧ";s:4:"سم";s:3:"ﳨ";s:4:"سه";s:3:"ﳩ";s:4:"شم";s:3:"ﳪ";s:4:"شه";s:3:"ﳫ";s:4:"كل";s:3:"ﳬ";s:4:"كم";s:3:"ﳭ";s:4:"لم";s:3:"ﳮ";s:4:"نم";s:3:"ﳯ";s:4:"نه";s:3:"ﳰ";s:4:"يم";s:3:"ﳱ";s:4:"يه";s:3:"ﳲ";s:6:"ـَّ";s:3:"ﳳ";s:6:"ـُّ";s:3:"ﳴ";s:6:"ـِّ";s:3:"ﳵ";s:4:"طى";s:3:"ﳶ";s:4:"طي";s:3:"ﳷ";s:4:"عى";s:3:"ﳸ";s:4:"عي";s:3:"ﳹ";s:4:"غى";s:3:"ﳺ";s:4:"غي";s:3:"ﳻ";s:4:"سى";s:3:"ﳼ";s:4:"سي";s:3:"ﳽ";s:4:"شى";s:3:"ﳾ";s:4:"شي";s:3:"ﳿ";s:4:"حى";s:3:"ﴀ";s:4:"حي";s:3:"ﴁ";s:4:"جى";s:3:"ﴂ";s:4:"جي";s:3:"ﴃ";s:4:"خى";s:3:"ﴄ";s:4:"خي";s:3:"ﴅ";s:4:"صى";s:3:"ﴆ";s:4:"صي";s:3:"ﴇ";s:4:"ضى";s:3:"ﴈ";s:4:"ضي";s:3:"ﴉ";s:4:"شج";s:3:"ﴊ";s:4:"شح";s:3:"ﴋ";s:4:"شخ";s:3:"ﴌ";s:4:"شم";s:3:"ﴍ";s:4:"شر";s:3:"ﴎ";s:4:"سر";s:3:"ﴏ";s:4:"صر";s:3:"ﴐ";s:4:"ضر";s:3:"ﴑ";s:4:"طى";s:3:"ﴒ";s:4:"طي";s:3:"ﴓ";s:4:"عى";s:3:"ﴔ";s:4:"عي";s:3:"ﴕ";s:4:"غى";s:3:"ﴖ";s:4:"غي";s:3:"ﴗ";s:4:"سى";s:3:"ﴘ";s:4:"سي";s:3:"ﴙ";s:4:"شى";s:3:"ﴚ";s:4:"شي";s:3:"ﴛ";s:4:"حى";s:3:"ﴜ";s:4:"حي";s:3:"ﴝ";s:4:"جى";s:3:"ﴞ";s:4:"جي";s:3:"ﴟ";s:4:"خى";s:3:"ﴠ";s:4:"خي";s:3:"ﴡ";s:4:"صى";s:3:"ﴢ";s:4:"صي";s:3:"ﴣ";s:4:"ضى";s:3:"ﴤ";s:4:"ضي";s:3:"ﴥ";s:4:"شج";s:3:"ﴦ";s:4:"شح";s:3:"ﴧ";s:4:"شخ";s:3:"ﴨ";s:4:"شم";s:3:"ﴩ";s:4:"شر";s:3:"ﴪ";s:4:"سر";s:3:"ﴫ";s:4:"صر";s:3:"ﴬ";s:4:"ضر";s:3:"ﴭ";s:4:"شج";s:3:"ﴮ";s:4:"شح";s:3:"ﴯ";s:4:"شخ";s:3:"ﴰ";s:4:"شم";s:3:"ﴱ";s:4:"سه";s:3:"ﴲ";s:4:"شه";s:3:"ﴳ";s:4:"طم";s:3:"ﴴ";s:4:"سج";s:3:"ﴵ";s:4:"سح";s:3:"ﴶ";s:4:"سخ";s:3:"ﴷ";s:4:"شج";s:3:"ﴸ";s:4:"شح";s:3:"ﴹ";s:4:"شخ";s:3:"ﴺ";s:4:"طم";s:3:"ﴻ";s:4:"ظم";s:3:"ﴼ";s:4:"اً";s:3:"ﴽ";s:4:"اً";s:3:"ﵐ";s:6:"تجم";s:3:"ﵑ";s:6:"تحج";s:3:"ﵒ";s:6:"تحج";s:3:"ﵓ";s:6:"تحم";s:3:"ﵔ";s:6:"تخم";s:3:"ﵕ";s:6:"تمج";s:3:"ﵖ";s:6:"تمح";s:3:"ﵗ";s:6:"تمخ";s:3:"ﵘ";s:6:"جمح";s:3:"ﵙ";s:6:"جمح";s:3:"ﵚ";s:6:"حمي";s:3:"ﵛ";s:6:"حمى";s:3:"ﵜ";s:6:"سحج";s:3:"ﵝ";s:6:"سجح";s:3:"ﵞ";s:6:"سجى";s:3:"ﵟ";s:6:"سمح";s:3:"ﵠ";s:6:"سمح";s:3:"ﵡ";s:6:"سمج";s:3:"ﵢ";s:6:"سمم";s:3:"ﵣ";s:6:"سمم";s:3:"ﵤ";s:6:"صحح";s:3:"ﵥ";s:6:"صحح";s:3:"ﵦ";s:6:"صمم";s:3:"ﵧ";s:6:"شحم";s:3:"ﵨ";s:6:"شحم";s:3:"ﵩ";s:6:"شجي";s:3:"ﵪ";s:6:"شمخ";s:3:"ﵫ";s:6:"شمخ";s:3:"ﵬ";s:6:"شمم";s:3:"ﵭ";s:6:"شمم";s:3:"ﵮ";s:6:"ضحى";s:3:"ﵯ";s:6:"ضخم";s:3:"ﵰ";s:6:"ضخم";s:3:"ﵱ";s:6:"طمح";s:3:"ﵲ";s:6:"طمح";s:3:"ﵳ";s:6:"طمم";s:3:"ﵴ";s:6:"طمي";s:3:"ﵵ";s:6:"عجم";s:3:"ﵶ";s:6:"عمم";s:3:"ﵷ";s:6:"عمم";s:3:"ﵸ";s:6:"عمى";s:3:"ﵹ";s:6:"غمم";s:3:"ﵺ";s:6:"غمي";s:3:"ﵻ";s:6:"غمى";s:3:"ﵼ";s:6:"فخم";s:3:"ﵽ";s:6:"فخم";s:3:"ﵾ";s:6:"قمح";s:3:"ﵿ";s:6:"قمم";s:3:"ﶀ";s:6:"لحم";s:3:"ﶁ";s:6:"لحي";s:3:"ﶂ";s:6:"لحى";s:3:"ﶃ";s:6:"لجج";s:3:"ﶄ";s:6:"لجج";s:3:"ﶅ";s:6:"لخم";s:3:"ﶆ";s:6:"لخم";s:3:"ﶇ";s:6:"لمح";s:3:"ﶈ";s:6:"لمح";s:3:"ﶉ";s:6:"محج";s:3:"ﶊ";s:6:"محم";s:3:"ﶋ";s:6:"محي";s:3:"ﶌ";s:6:"مجح";s:3:"ﶍ";s:6:"مجم";s:3:"ﶎ";s:6:"مخج";s:3:"ﶏ";s:6:"مخم";s:3:"ﶒ";s:6:"مجخ";s:3:"ﶓ";s:6:"همج";s:3:"ﶔ";s:6:"همم";s:3:"ﶕ";s:6:"نحم";s:3:"ﶖ";s:6:"نحى";s:3:"ﶗ";s:6:"نجم";s:3:"ﶘ";s:6:"نجم";s:3:"ﶙ";s:6:"نجى";s:3:"ﶚ";s:6:"نمي";s:3:"ﶛ";s:6:"نمى";s:3:"ﶜ";s:6:"يمم";s:3:"ﶝ";s:6:"يمم";s:3:"ﶞ";s:6:"بخي";s:3:"ﶟ";s:6:"تجي";s:3:"ﶠ";s:6:"تجى";s:3:"ﶡ";s:6:"تخي";s:3:"ﶢ";s:6:"تخى";s:3:"ﶣ";s:6:"تمي";s:3:"ﶤ";s:6:"تمى";s:3:"ﶥ";s:6:"جمي";s:3:"ﶦ";s:6:"جحى";s:3:"ﶧ";s:6:"جمى";s:3:"ﶨ";s:6:"سخى";s:3:"ﶩ";s:6:"صحي";s:3:"ﶪ";s:6:"شحي";s:3:"ﶫ";s:6:"ضحي";s:3:"ﶬ";s:6:"لجي";s:3:"ﶭ";s:6:"لمي";s:3:"ﶮ";s:6:"يحي";s:3:"ﶯ";s:6:"يجي";s:3:"ﶰ";s:6:"يمي";s:3:"ﶱ";s:6:"ممي";s:3:"ﶲ";s:6:"قمي";s:3:"ﶳ";s:6:"نحي";s:3:"ﶴ";s:6:"قمح";s:3:"ﶵ";s:6:"لحم";s:3:"ﶶ";s:6:"عمي";s:3:"ﶷ";s:6:"كمي";s:3:"ﶸ";s:6:"نجح";s:3:"ﶹ";s:6:"مخي";s:3:"ﶺ";s:6:"لجم";s:3:"ﶻ";s:6:"كمم";s:3:"ﶼ";s:6:"لجم";s:3:"ﶽ";s:6:"نجح";s:3:"ﶾ";s:6:"جحي";s:3:"ﶿ";s:6:"حجي";s:3:"ﷀ";s:6:"مجي";s:3:"ﷁ";s:6:"فمي";s:3:"ﷂ";s:6:"بحي";s:3:"ﷃ";s:6:"كمم";s:3:"ﷄ";s:6:"عجم";s:3:"ﷅ";s:6:"صمم";s:3:"ﷆ";s:6:"سخي";s:3:"ﷇ";s:6:"نجي";s:3:"ﷰ";s:6:"صلے";s:3:"ﷱ";s:6:"قلے";s:3:"ﷲ";s:8:"الله";s:3:"ﷳ";s:8:"اكبر";s:3:"ﷴ";s:8:"محمد";s:3:"ﷵ";s:8:"صلعم";s:3:"ﷶ";s:8:"رسول";s:3:"ﷷ";s:8:"عليه";s:3:"ﷸ";s:8:"وسلم";s:3:"ﷹ";s:6:"صلى";s:3:"ﷺ";s:33:"صلى الله عليه وسلم";s:3:"ﷻ";s:15:"جل جلاله";s:3:"﷼";s:8:"ریال";s:3:"︐";s:1:",";s:3:"︑";s:3:"、";s:3:"︒";s:3:"。";s:3:"︓";s:1:":";s:3:"︔";s:1:";";s:3:"︕";s:1:"!";s:3:"︖";s:1:"?";s:3:"︗";s:3:"〖";s:3:"︘";s:3:"〗";s:3:"︙";s:3:"...";s:3:"︰";s:2:"..";s:3:"︱";s:3:"—";s:3:"︲";s:3:"–";s:3:"︳";s:1:"_";s:3:"︴";s:1:"_";s:3:"︵";s:1:"(";s:3:"︶";s:1:")";s:3:"︷";s:1:"{";s:3:"︸";s:1:"}";s:3:"︹";s:3:"〔";s:3:"︺";s:3:"〕";s:3:"︻";s:3:"【";s:3:"︼";s:3:"】";s:3:"︽";s:3:"《";s:3:"︾";s:3:"》";s:3:"︿";s:3:"〈";s:3:"﹀";s:3:"〉";s:3:"﹁";s:3:"「";s:3:"﹂";s:3:"」";s:3:"﹃";s:3:"『";s:3:"﹄";s:3:"』";s:3:"﹇";s:1:"[";s:3:"﹈";s:1:"]";s:3:"﹉";s:3:" ̅";s:3:"﹊";s:3:" ̅";s:3:"﹋";s:3:" ̅";s:3:"﹌";s:3:" ̅";s:3:"﹍";s:1:"_";s:3:"﹎";s:1:"_";s:3:"﹏";s:1:"_";s:3:"﹐";s:1:",";s:3:"﹑";s:3:"、";s:3:"﹒";s:1:".";s:3:"﹔";s:1:";";s:3:"﹕";s:1:":";s:3:"﹖";s:1:"?";s:3:"﹗";s:1:"!";s:3:"﹘";s:3:"—";s:3:"﹙";s:1:"(";s:3:"﹚";s:1:")";s:3:"﹛";s:1:"{";s:3:"﹜";s:1:"}";s:3:"﹝";s:3:"〔";s:3:"﹞";s:3:"〕";s:3:"﹟";s:1:"#";s:3:"﹠";s:1:"&";s:3:"﹡";s:1:"*";s:3:"﹢";s:1:"+";s:3:"﹣";s:1:"-";s:3:"﹤";s:1:"<";s:3:"﹥";s:1:">";s:3:"﹦";s:1:"=";s:3:"﹨";s:1:"\\";s:3:"﹩";s:1:"$";s:3:"﹪";s:1:"%";s:3:"﹫";s:1:"@";s:3:"ﹰ";s:3:" ً";s:3:"ﹱ";s:4:"ـً";s:3:"ﹲ";s:3:" ٌ";s:3:"ﹴ";s:3:" ٍ";s:3:"ﹶ";s:3:" َ";s:3:"ﹷ";s:4:"ـَ";s:3:"ﹸ";s:3:" ُ";s:3:"ﹹ";s:4:"ـُ";s:3:"ﹺ";s:3:" ِ";s:3:"ﹻ";s:4:"ـِ";s:3:"ﹼ";s:3:" ّ";s:3:"ﹽ";s:4:"ـّ";s:3:"ﹾ";s:3:" ْ";s:3:"ﹿ";s:4:"ـْ";s:3:"ﺀ";s:2:"ء";s:3:"ﺁ";s:4:"آ";s:3:"ﺂ";s:4:"آ";s:3:"ﺃ";s:4:"أ";s:3:"ﺄ";s:4:"أ";s:3:"ﺅ";s:4:"ؤ";s:3:"ﺆ";s:4:"ؤ";s:3:"ﺇ";s:4:"إ";s:3:"ﺈ";s:4:"إ";s:3:"ﺉ";s:4:"ئ";s:3:"ﺊ";s:4:"ئ";s:3:"ﺋ";s:4:"ئ";s:3:"ﺌ";s:4:"ئ";s:3:"ﺍ";s:2:"ا";s:3:"ﺎ";s:2:"ا";s:3:"ﺏ";s:2:"ب";s:3:"ﺐ";s:2:"ب";s:3:"ﺑ";s:2:"ب";s:3:"ﺒ";s:2:"ب";s:3:"ﺓ";s:2:"ة";s:3:"ﺔ";s:2:"ة";s:3:"ﺕ";s:2:"ت";s:3:"ﺖ";s:2:"ت";s:3:"ﺗ";s:2:"ت";s:3:"ﺘ";s:2:"ت";s:3:"ﺙ";s:2:"ث";s:3:"ﺚ";s:2:"ث";s:3:"ﺛ";s:2:"ث";s:3:"ﺜ";s:2:"ث";s:3:"ﺝ";s:2:"ج";s:3:"ﺞ";s:2:"ج";s:3:"ﺟ";s:2:"ج";s:3:"ﺠ";s:2:"ج";s:3:"ﺡ";s:2:"ح";s:3:"ﺢ";s:2:"ح";s:3:"ﺣ";s:2:"ح";s:3:"ﺤ";s:2:"ح";s:3:"ﺥ";s:2:"خ";s:3:"ﺦ";s:2:"خ";s:3:"ﺧ";s:2:"خ";s:3:"ﺨ";s:2:"خ";s:3:"ﺩ";s:2:"د";s:3:"ﺪ";s:2:"د";s:3:"ﺫ";s:2:"ذ";s:3:"ﺬ";s:2:"ذ";s:3:"ﺭ";s:2:"ر";s:3:"ﺮ";s:2:"ر";s:3:"ﺯ";s:2:"ز";s:3:"ﺰ";s:2:"ز";s:3:"ﺱ";s:2:"س";s:3:"ﺲ";s:2:"س";s:3:"ﺳ";s:2:"س";s:3:"ﺴ";s:2:"س";s:3:"ﺵ";s:2:"ش";s:3:"ﺶ";s:2:"ش";s:3:"ﺷ";s:2:"ش";s:3:"ﺸ";s:2:"ش";s:3:"ﺹ";s:2:"ص";s:3:"ﺺ";s:2:"ص";s:3:"ﺻ";s:2:"ص";s:3:"ﺼ";s:2:"ص";s:3:"ﺽ";s:2:"ض";s:3:"ﺾ";s:2:"ض";s:3:"ﺿ";s:2:"ض";s:3:"ﻀ";s:2:"ض";s:3:"ﻁ";s:2:"ط";s:3:"ﻂ";s:2:"ط";s:3:"ﻃ";s:2:"ط";s:3:"ﻄ";s:2:"ط";s:3:"ﻅ";s:2:"ظ";s:3:"ﻆ";s:2:"ظ";s:3:"ﻇ";s:2:"ظ";s:3:"ﻈ";s:2:"ظ";s:3:"ﻉ";s:2:"ع";s:3:"ﻊ";s:2:"ع";s:3:"ﻋ";s:2:"ع";s:3:"ﻌ";s:2:"ع";s:3:"ﻍ";s:2:"غ";s:3:"ﻎ";s:2:"غ";s:3:"ﻏ";s:2:"غ";s:3:"ﻐ";s:2:"غ";s:3:"ﻑ";s:2:"ف";s:3:"ﻒ";s:2:"ف";s:3:"ﻓ";s:2:"ف";s:3:"ﻔ";s:2:"ف";s:3:"ﻕ";s:2:"ق";s:3:"ﻖ";s:2:"ق";s:3:"ﻗ";s:2:"ق";s:3:"ﻘ";s:2:"ق";s:3:"ﻙ";s:2:"ك";s:3:"ﻚ";s:2:"ك";s:3:"ﻛ";s:2:"ك";s:3:"ﻜ";s:2:"ك";s:3:"ﻝ";s:2:"ل";s:3:"ﻞ";s:2:"ل";s:3:"ﻟ";s:2:"ل";s:3:"ﻠ";s:2:"ل";s:3:"ﻡ";s:2:"م";s:3:"ﻢ";s:2:"م";s:3:"ﻣ";s:2:"م";s:3:"ﻤ";s:2:"م";s:3:"ﻥ";s:2:"ن";s:3:"ﻦ";s:2:"ن";s:3:"ﻧ";s:2:"ن";s:3:"ﻨ";s:2:"ن";s:3:"ﻩ";s:2:"ه";s:3:"ﻪ";s:2:"ه";s:3:"ﻫ";s:2:"ه";s:3:"ﻬ";s:2:"ه";s:3:"ﻭ";s:2:"و";s:3:"ﻮ";s:2:"و";s:3:"ﻯ";s:2:"ى";s:3:"ﻰ";s:2:"ى";s:3:"ﻱ";s:2:"ي";s:3:"ﻲ";s:2:"ي";s:3:"ﻳ";s:2:"ي";s:3:"ﻴ";s:2:"ي";s:3:"ﻵ";s:6:"لآ";s:3:"ﻶ";s:6:"لآ";s:3:"ﻷ";s:6:"لأ";s:3:"ﻸ";s:6:"لأ";s:3:"ﻹ";s:6:"لإ";s:3:"ﻺ";s:6:"لإ";s:3:"ﻻ";s:4:"لا";s:3:"ﻼ";s:4:"لا";s:3:"!";s:1:"!";s:3:""";s:1:""";s:3:"#";s:1:"#";s:3:"$";s:1:"$";s:3:"%";s:1:"%";s:3:"&";s:1:"&";s:3:"'";s:1:"\'";s:3:"(";s:1:"(";s:3:")";s:1:")";s:3:"*";s:1:"*";s:3:"+";s:1:"+";s:3:",";s:1:",";s:3:"-";s:1:"-";s:3:".";s:1:".";s:3:"/";s:1:"/";s:3:"0";s:1:"0";s:3:"1";s:1:"1";s:3:"2";s:1:"2";s:3:"3";s:1:"3";s:3:"4";s:1:"4";s:3:"5";s:1:"5";s:3:"6";s:1:"6";s:3:"7";s:1:"7";s:3:"8";s:1:"8";s:3:"9";s:1:"9";s:3:":";s:1:":";s:3:";";s:1:";";s:3:"<";s:1:"<";s:3:"=";s:1:"=";s:3:">";s:1:">";s:3:"?";s:1:"?";s:3:"@";s:1:"@";s:3:"A";s:1:"A";s:3:"B";s:1:"B";s:3:"C";s:1:"C";s:3:"D";s:1:"D";s:3:"E";s:1:"E";s:3:"F";s:1:"F";s:3:"G";s:1:"G";s:3:"H";s:1:"H";s:3:"I";s:1:"I";s:3:"J";s:1:"J";s:3:"K";s:1:"K";s:3:"L";s:1:"L";s:3:"M";s:1:"M";s:3:"N";s:1:"N";s:3:"O";s:1:"O";s:3:"P";s:1:"P";s:3:"Q";s:1:"Q";s:3:"R";s:1:"R";s:3:"S";s:1:"S";s:3:"T";s:1:"T";s:3:"U";s:1:"U";s:3:"V";s:1:"V";s:3:"W";s:1:"W";s:3:"X";s:1:"X";s:3:"Y";s:1:"Y";s:3:"Z";s:1:"Z";s:3:"[";s:1:"[";s:3:"\";s:1:"\\";s:3:"]";s:1:"]";s:3:"^";s:1:"^";s:3:"_";s:1:"_";s:3:"`";s:1:"`";s:3:"a";s:1:"a";s:3:"b";s:1:"b";s:3:"c";s:1:"c";s:3:"d";s:1:"d";s:3:"e";s:1:"e";s:3:"f";s:1:"f";s:3:"g";s:1:"g";s:3:"h";s:1:"h";s:3:"i";s:1:"i";s:3:"j";s:1:"j";s:3:"k";s:1:"k";s:3:"l";s:1:"l";s:3:"m";s:1:"m";s:3:"n";s:1:"n";s:3:"o";s:1:"o";s:3:"p";s:1:"p";s:3:"q";s:1:"q";s:3:"r";s:1:"r";s:3:"s";s:1:"s";s:3:"t";s:1:"t";s:3:"u";s:1:"u";s:3:"v";s:1:"v";s:3:"w";s:1:"w";s:3:"x";s:1:"x";s:3:"y";s:1:"y";s:3:"z";s:1:"z";s:3:"{";s:1:"{";s:3:"|";s:1:"|";s:3:"}";s:1:"}";s:3:"~";s:1:"~";s:3:"⦅";s:3:"⦅";s:3:"⦆";s:3:"⦆";s:3:"。";s:3:"。";s:3:"「";s:3:"「";s:3:"」";s:3:"」";s:3:"、";s:3:"、";s:3:"・";s:3:"・";s:3:"ヲ";s:3:"ヲ";s:3:"ァ";s:3:"ァ";s:3:"ィ";s:3:"ィ";s:3:"ゥ";s:3:"ゥ";s:3:"ェ";s:3:"ェ";s:3:"ォ";s:3:"ォ";s:3:"ャ";s:3:"ャ";s:3:"ュ";s:3:"ュ";s:3:"ョ";s:3:"ョ";s:3:"ッ";s:3:"ッ";s:3:"ー";s:3:"ー";s:3:"ア";s:3:"ア";s:3:"イ";s:3:"イ";s:3:"ウ";s:3:"ウ";s:3:"エ";s:3:"エ";s:3:"オ";s:3:"オ";s:3:"カ";s:3:"カ";s:3:"キ";s:3:"キ";s:3:"ク";s:3:"ク";s:3:"ケ";s:3:"ケ";s:3:"コ";s:3:"コ";s:3:"サ";s:3:"サ";s:3:"シ";s:3:"シ";s:3:"ス";s:3:"ス";s:3:"セ";s:3:"セ";s:3:"ソ";s:3:"ソ";s:3:"タ";s:3:"タ";s:3:"チ";s:3:"チ";s:3:"ツ";s:3:"ツ";s:3:"テ";s:3:"テ";s:3:"ト";s:3:"ト";s:3:"ナ";s:3:"ナ";s:3:"ニ";s:3:"ニ";s:3:"ヌ";s:3:"ヌ";s:3:"ネ";s:3:"ネ";s:3:"ノ";s:3:"ノ";s:3:"ハ";s:3:"ハ";s:3:"ヒ";s:3:"ヒ";s:3:"フ";s:3:"フ";s:3:"ヘ";s:3:"ヘ";s:3:"ホ";s:3:"ホ";s:3:"マ";s:3:"マ";s:3:"ミ";s:3:"ミ";s:3:"ム";s:3:"ム";s:3:"メ";s:3:"メ";s:3:"モ";s:3:"モ";s:3:"ヤ";s:3:"ヤ";s:3:"ユ";s:3:"ユ";s:3:"ヨ";s:3:"ヨ";s:3:"ラ";s:3:"ラ";s:3:"リ";s:3:"リ";s:3:"ル";s:3:"ル";s:3:"レ";s:3:"レ";s:3:"ロ";s:3:"ロ";s:3:"ワ";s:3:"ワ";s:3:"ン";s:3:"ン";s:3:"゙";s:3:"゙";s:3:"゚";s:3:"゚";s:3:"ᅠ";s:3:"ᅠ";s:3:"ᄀ";s:3:"ᄀ";s:3:"ᄁ";s:3:"ᄁ";s:3:"ᆪ";s:3:"ᆪ";s:3:"ᄂ";s:3:"ᄂ";s:3:"ᆬ";s:3:"ᆬ";s:3:"ᆭ";s:3:"ᆭ";s:3:"ᄃ";s:3:"ᄃ";s:3:"ᄄ";s:3:"ᄄ";s:3:"ᄅ";s:3:"ᄅ";s:3:"ᆰ";s:3:"ᆰ";s:3:"ᆱ";s:3:"ᆱ";s:3:"ᆲ";s:3:"ᆲ";s:3:"ᆳ";s:3:"ᆳ";s:3:"ᆴ";s:3:"ᆴ";s:3:"ᆵ";s:3:"ᆵ";s:3:"ᄚ";s:3:"ᄚ";s:3:"ᄆ";s:3:"ᄆ";s:3:"ᄇ";s:3:"ᄇ";s:3:"ᄈ";s:3:"ᄈ";s:3:"ᄡ";s:3:"ᄡ";s:3:"ᄉ";s:3:"ᄉ";s:3:"ᄊ";s:3:"ᄊ";s:3:"ᄋ";s:3:"ᄋ";s:3:"ᄌ";s:3:"ᄌ";s:3:"ᄍ";s:3:"ᄍ";s:3:"ᄎ";s:3:"ᄎ";s:3:"ᄏ";s:3:"ᄏ";s:3:"ᄐ";s:3:"ᄐ";s:3:"ᄑ";s:3:"ᄑ";s:3:"ᄒ";s:3:"ᄒ";s:3:"ᅡ";s:3:"ᅡ";s:3:"ᅢ";s:3:"ᅢ";s:3:"ᅣ";s:3:"ᅣ";s:3:"ᅤ";s:3:"ᅤ";s:3:"ᅥ";s:3:"ᅥ";s:3:"ᅦ";s:3:"ᅦ";s:3:"ᅧ";s:3:"ᅧ";s:3:"ᅨ";s:3:"ᅨ";s:3:"ᅩ";s:3:"ᅩ";s:3:"ᅪ";s:3:"ᅪ";s:3:"ᅫ";s:3:"ᅫ";s:3:"ᅬ";s:3:"ᅬ";s:3:"ᅭ";s:3:"ᅭ";s:3:"ᅮ";s:3:"ᅮ";s:3:"ᅯ";s:3:"ᅯ";s:3:"ᅰ";s:3:"ᅰ";s:3:"ᅱ";s:3:"ᅱ";s:3:"ᅲ";s:3:"ᅲ";s:3:"ᅳ";s:3:"ᅳ";s:3:"ᅴ";s:3:"ᅴ";s:3:"ᅵ";s:3:"ᅵ";s:3:"¢";s:2:"¢";s:3:"£";s:2:"£";s:3:"¬";s:2:"¬";s:3:" ̄";s:3:" ̄";s:3:"¦";s:2:"¦";s:3:"¥";s:2:"¥";s:3:"₩";s:3:"₩";s:3:"│";s:3:"│";s:3:"←";s:3:"←";s:3:"↑";s:3:"↑";s:3:"→";s:3:"→";s:3:"↓";s:3:"↓";s:3:"■";s:3:"■";s:3:"○";s:3:"○";s:4:"𝅗𝅥";s:8:"𝅗𝅥";s:4:"𝅘𝅥";s:8:"𝅘𝅥";s:4:"𝅘𝅥𝅮";s:12:"𝅘𝅥𝅮";s:4:"𝅘𝅥𝅯";s:12:"𝅘𝅥𝅯";s:4:"𝅘𝅥𝅰";s:12:"𝅘𝅥𝅰";s:4:"𝅘𝅥𝅱";s:12:"𝅘𝅥𝅱";s:4:"𝅘𝅥𝅲";s:12:"𝅘𝅥𝅲";s:4:"𝆹𝅥";s:8:"𝆹𝅥";s:4:"𝆺𝅥";s:8:"𝆺𝅥";s:4:"𝆹𝅥𝅮";s:12:"𝆹𝅥𝅮";s:4:"𝆺𝅥𝅮";s:12:"𝆺𝅥𝅮";s:4:"𝆹𝅥𝅯";s:12:"𝆹𝅥𝅯";s:4:"𝆺𝅥𝅯";s:12:"𝆺𝅥𝅯";s:4:"𝐀";s:1:"A";s:4:"𝐁";s:1:"B";s:4:"𝐂";s:1:"C";s:4:"𝐃";s:1:"D";s:4:"𝐄";s:1:"E";s:4:"𝐅";s:1:"F";s:4:"𝐆";s:1:"G";s:4:"𝐇";s:1:"H";s:4:"𝐈";s:1:"I";s:4:"𝐉";s:1:"J";s:4:"𝐊";s:1:"K";s:4:"𝐋";s:1:"L";s:4:"𝐌";s:1:"M";s:4:"𝐍";s:1:"N";s:4:"𝐎";s:1:"O";s:4:"𝐏";s:1:"P";s:4:"𝐐";s:1:"Q";s:4:"𝐑";s:1:"R";s:4:"𝐒";s:1:"S";s:4:"𝐓";s:1:"T";s:4:"𝐔";s:1:"U";s:4:"𝐕";s:1:"V";s:4:"𝐖";s:1:"W";s:4:"𝐗";s:1:"X";s:4:"𝐘";s:1:"Y";s:4:"𝐙";s:1:"Z";s:4:"𝐚";s:1:"a";s:4:"𝐛";s:1:"b";s:4:"𝐜";s:1:"c";s:4:"𝐝";s:1:"d";s:4:"𝐞";s:1:"e";s:4:"𝐟";s:1:"f";s:4:"𝐠";s:1:"g";s:4:"𝐡";s:1:"h";s:4:"𝐢";s:1:"i";s:4:"𝐣";s:1:"j";s:4:"𝐤";s:1:"k";s:4:"𝐥";s:1:"l";s:4:"𝐦";s:1:"m";s:4:"𝐧";s:1:"n";s:4:"𝐨";s:1:"o";s:4:"𝐩";s:1:"p";s:4:"𝐪";s:1:"q";s:4:"𝐫";s:1:"r";s:4:"𝐬";s:1:"s";s:4:"𝐭";s:1:"t";s:4:"𝐮";s:1:"u";s:4:"𝐯";s:1:"v";s:4:"𝐰";s:1:"w";s:4:"𝐱";s:1:"x";s:4:"𝐲";s:1:"y";s:4:"𝐳";s:1:"z";s:4:"𝐴";s:1:"A";s:4:"𝐵";s:1:"B";s:4:"𝐶";s:1:"C";s:4:"𝐷";s:1:"D";s:4:"𝐸";s:1:"E";s:4:"𝐹";s:1:"F";s:4:"𝐺";s:1:"G";s:4:"𝐻";s:1:"H";s:4:"𝐼";s:1:"I";s:4:"𝐽";s:1:"J";s:4:"𝐾";s:1:"K";s:4:"𝐿";s:1:"L";s:4:"𝑀";s:1:"M";s:4:"𝑁";s:1:"N";s:4:"𝑂";s:1:"O";s:4:"𝑃";s:1:"P";s:4:"𝑄";s:1:"Q";s:4:"𝑅";s:1:"R";s:4:"𝑆";s:1:"S";s:4:"𝑇";s:1:"T";s:4:"𝑈";s:1:"U";s:4:"𝑉";s:1:"V";s:4:"𝑊";s:1:"W";s:4:"𝑋";s:1:"X";s:4:"𝑌";s:1:"Y";s:4:"𝑍";s:1:"Z";s:4:"𝑎";s:1:"a";s:4:"𝑏";s:1:"b";s:4:"𝑐";s:1:"c";s:4:"𝑑";s:1:"d";s:4:"𝑒";s:1:"e";s:4:"𝑓";s:1:"f";s:4:"𝑔";s:1:"g";s:4:"𝑖";s:1:"i";s:4:"𝑗";s:1:"j";s:4:"𝑘";s:1:"k";s:4:"𝑙";s:1:"l";s:4:"𝑚";s:1:"m";s:4:"𝑛";s:1:"n";s:4:"𝑜";s:1:"o";s:4:"𝑝";s:1:"p";s:4:"𝑞";s:1:"q";s:4:"𝑟";s:1:"r";s:4:"𝑠";s:1:"s";s:4:"𝑡";s:1:"t";s:4:"𝑢";s:1:"u";s:4:"𝑣";s:1:"v";s:4:"𝑤";s:1:"w";s:4:"𝑥";s:1:"x";s:4:"𝑦";s:1:"y";s:4:"𝑧";s:1:"z";s:4:"𝑨";s:1:"A";s:4:"𝑩";s:1:"B";s:4:"𝑪";s:1:"C";s:4:"𝑫";s:1:"D";s:4:"𝑬";s:1:"E";s:4:"𝑭";s:1:"F";s:4:"𝑮";s:1:"G";s:4:"𝑯";s:1:"H";s:4:"𝑰";s:1:"I";s:4:"𝑱";s:1:"J";s:4:"𝑲";s:1:"K";s:4:"𝑳";s:1:"L";s:4:"𝑴";s:1:"M";s:4:"𝑵";s:1:"N";s:4:"𝑶";s:1:"O";s:4:"𝑷";s:1:"P";s:4:"𝑸";s:1:"Q";s:4:"𝑹";s:1:"R";s:4:"𝑺";s:1:"S";s:4:"𝑻";s:1:"T";s:4:"𝑼";s:1:"U";s:4:"𝑽";s:1:"V";s:4:"𝑾";s:1:"W";s:4:"𝑿";s:1:"X";s:4:"𝒀";s:1:"Y";s:4:"𝒁";s:1:"Z";s:4:"𝒂";s:1:"a";s:4:"𝒃";s:1:"b";s:4:"𝒄";s:1:"c";s:4:"𝒅";s:1:"d";s:4:"𝒆";s:1:"e";s:4:"𝒇";s:1:"f";s:4:"𝒈";s:1:"g";s:4:"𝒉";s:1:"h";s:4:"𝒊";s:1:"i";s:4:"𝒋";s:1:"j";s:4:"𝒌";s:1:"k";s:4:"𝒍";s:1:"l";s:4:"𝒎";s:1:"m";s:4:"𝒏";s:1:"n";s:4:"𝒐";s:1:"o";s:4:"𝒑";s:1:"p";s:4:"𝒒";s:1:"q";s:4:"𝒓";s:1:"r";s:4:"𝒔";s:1:"s";s:4:"𝒕";s:1:"t";s:4:"𝒖";s:1:"u";s:4:"𝒗";s:1:"v";s:4:"𝒘";s:1:"w";s:4:"𝒙";s:1:"x";s:4:"𝒚";s:1:"y";s:4:"𝒛";s:1:"z";s:4:"𝒜";s:1:"A";s:4:"𝒞";s:1:"C";s:4:"𝒟";s:1:"D";s:4:"𝒢";s:1:"G";s:4:"𝒥";s:1:"J";s:4:"𝒦";s:1:"K";s:4:"𝒩";s:1:"N";s:4:"𝒪";s:1:"O";s:4:"𝒫";s:1:"P";s:4:"𝒬";s:1:"Q";s:4:"𝒮";s:1:"S";s:4:"𝒯";s:1:"T";s:4:"𝒰";s:1:"U";s:4:"𝒱";s:1:"V";s:4:"𝒲";s:1:"W";s:4:"𝒳";s:1:"X";s:4:"𝒴";s:1:"Y";s:4:"𝒵";s:1:"Z";s:4:"𝒶";s:1:"a";s:4:"𝒷";s:1:"b";s:4:"𝒸";s:1:"c";s:4:"𝒹";s:1:"d";s:4:"𝒻";s:1:"f";s:4:"𝒽";s:1:"h";s:4:"𝒾";s:1:"i";s:4:"𝒿";s:1:"j";s:4:"𝓀";s:1:"k";s:4:"𝓁";s:1:"l";s:4:"𝓂";s:1:"m";s:4:"𝓃";s:1:"n";s:4:"𝓅";s:1:"p";s:4:"𝓆";s:1:"q";s:4:"𝓇";s:1:"r";s:4:"𝓈";s:1:"s";s:4:"𝓉";s:1:"t";s:4:"𝓊";s:1:"u";s:4:"𝓋";s:1:"v";s:4:"𝓌";s:1:"w";s:4:"𝓍";s:1:"x";s:4:"𝓎";s:1:"y";s:4:"𝓏";s:1:"z";s:4:"𝓐";s:1:"A";s:4:"𝓑";s:1:"B";s:4:"𝓒";s:1:"C";s:4:"𝓓";s:1:"D";s:4:"𝓔";s:1:"E";s:4:"𝓕";s:1:"F";s:4:"𝓖";s:1:"G";s:4:"𝓗";s:1:"H";s:4:"𝓘";s:1:"I";s:4:"𝓙";s:1:"J";s:4:"𝓚";s:1:"K";s:4:"𝓛";s:1:"L";s:4:"𝓜";s:1:"M";s:4:"𝓝";s:1:"N";s:4:"𝓞";s:1:"O";s:4:"𝓟";s:1:"P";s:4:"𝓠";s:1:"Q";s:4:"𝓡";s:1:"R";s:4:"𝓢";s:1:"S";s:4:"𝓣";s:1:"T";s:4:"𝓤";s:1:"U";s:4:"𝓥";s:1:"V";s:4:"𝓦";s:1:"W";s:4:"𝓧";s:1:"X";s:4:"𝓨";s:1:"Y";s:4:"𝓩";s:1:"Z";s:4:"𝓪";s:1:"a";s:4:"𝓫";s:1:"b";s:4:"𝓬";s:1:"c";s:4:"𝓭";s:1:"d";s:4:"𝓮";s:1:"e";s:4:"𝓯";s:1:"f";s:4:"𝓰";s:1:"g";s:4:"𝓱";s:1:"h";s:4:"𝓲";s:1:"i";s:4:"𝓳";s:1:"j";s:4:"𝓴";s:1:"k";s:4:"𝓵";s:1:"l";s:4:"𝓶";s:1:"m";s:4:"𝓷";s:1:"n";s:4:"𝓸";s:1:"o";s:4:"𝓹";s:1:"p";s:4:"𝓺";s:1:"q";s:4:"𝓻";s:1:"r";s:4:"𝓼";s:1:"s";s:4:"𝓽";s:1:"t";s:4:"𝓾";s:1:"u";s:4:"𝓿";s:1:"v";s:4:"𝔀";s:1:"w";s:4:"𝔁";s:1:"x";s:4:"𝔂";s:1:"y";s:4:"𝔃";s:1:"z";s:4:"𝔄";s:1:"A";s:4:"𝔅";s:1:"B";s:4:"𝔇";s:1:"D";s:4:"𝔈";s:1:"E";s:4:"𝔉";s:1:"F";s:4:"𝔊";s:1:"G";s:4:"𝔍";s:1:"J";s:4:"𝔎";s:1:"K";s:4:"𝔏";s:1:"L";s:4:"𝔐";s:1:"M";s:4:"𝔑";s:1:"N";s:4:"𝔒";s:1:"O";s:4:"𝔓";s:1:"P";s:4:"𝔔";s:1:"Q";s:4:"𝔖";s:1:"S";s:4:"𝔗";s:1:"T";s:4:"𝔘";s:1:"U";s:4:"𝔙";s:1:"V";s:4:"𝔚";s:1:"W";s:4:"𝔛";s:1:"X";s:4:"𝔜";s:1:"Y";s:4:"𝔞";s:1:"a";s:4:"𝔟";s:1:"b";s:4:"𝔠";s:1:"c";s:4:"𝔡";s:1:"d";s:4:"𝔢";s:1:"e";s:4:"𝔣";s:1:"f";s:4:"𝔤";s:1:"g";s:4:"𝔥";s:1:"h";s:4:"𝔦";s:1:"i";s:4:"𝔧";s:1:"j";s:4:"𝔨";s:1:"k";s:4:"𝔩";s:1:"l";s:4:"𝔪";s:1:"m";s:4:"𝔫";s:1:"n";s:4:"𝔬";s:1:"o";s:4:"𝔭";s:1:"p";s:4:"𝔮";s:1:"q";s:4:"𝔯";s:1:"r";s:4:"𝔰";s:1:"s";s:4:"𝔱";s:1:"t";s:4:"𝔲";s:1:"u";s:4:"𝔳";s:1:"v";s:4:"𝔴";s:1:"w";s:4:"𝔵";s:1:"x";s:4:"𝔶";s:1:"y";s:4:"𝔷";s:1:"z";s:4:"𝔸";s:1:"A";s:4:"𝔹";s:1:"B";s:4:"𝔻";s:1:"D";s:4:"𝔼";s:1:"E";s:4:"𝔽";s:1:"F";s:4:"𝔾";s:1:"G";s:4:"𝕀";s:1:"I";s:4:"𝕁";s:1:"J";s:4:"𝕂";s:1:"K";s:4:"𝕃";s:1:"L";s:4:"𝕄";s:1:"M";s:4:"𝕆";s:1:"O";s:4:"𝕊";s:1:"S";s:4:"𝕋";s:1:"T";s:4:"𝕌";s:1:"U";s:4:"𝕍";s:1:"V";s:4:"𝕎";s:1:"W";s:4:"𝕏";s:1:"X";s:4:"𝕐";s:1:"Y";s:4:"𝕒";s:1:"a";s:4:"𝕓";s:1:"b";s:4:"𝕔";s:1:"c";s:4:"𝕕";s:1:"d";s:4:"𝕖";s:1:"e";s:4:"𝕗";s:1:"f";s:4:"𝕘";s:1:"g";s:4:"𝕙";s:1:"h";s:4:"𝕚";s:1:"i";s:4:"𝕛";s:1:"j";s:4:"𝕜";s:1:"k";s:4:"𝕝";s:1:"l";s:4:"𝕞";s:1:"m";s:4:"𝕟";s:1:"n";s:4:"𝕠";s:1:"o";s:4:"𝕡";s:1:"p";s:4:"𝕢";s:1:"q";s:4:"𝕣";s:1:"r";s:4:"𝕤";s:1:"s";s:4:"𝕥";s:1:"t";s:4:"𝕦";s:1:"u";s:4:"𝕧";s:1:"v";s:4:"𝕨";s:1:"w";s:4:"𝕩";s:1:"x";s:4:"𝕪";s:1:"y";s:4:"𝕫";s:1:"z";s:4:"𝕬";s:1:"A";s:4:"𝕭";s:1:"B";s:4:"𝕮";s:1:"C";s:4:"𝕯";s:1:"D";s:4:"𝕰";s:1:"E";s:4:"𝕱";s:1:"F";s:4:"𝕲";s:1:"G";s:4:"𝕳";s:1:"H";s:4:"𝕴";s:1:"I";s:4:"𝕵";s:1:"J";s:4:"𝕶";s:1:"K";s:4:"𝕷";s:1:"L";s:4:"𝕸";s:1:"M";s:4:"𝕹";s:1:"N";s:4:"𝕺";s:1:"O";s:4:"𝕻";s:1:"P";s:4:"𝕼";s:1:"Q";s:4:"𝕽";s:1:"R";s:4:"𝕾";s:1:"S";s:4:"𝕿";s:1:"T";s:4:"𝖀";s:1:"U";s:4:"𝖁";s:1:"V";s:4:"𝖂";s:1:"W";s:4:"𝖃";s:1:"X";s:4:"𝖄";s:1:"Y";s:4:"𝖅";s:1:"Z";s:4:"𝖆";s:1:"a";s:4:"𝖇";s:1:"b";s:4:"𝖈";s:1:"c";s:4:"𝖉";s:1:"d";s:4:"𝖊";s:1:"e";s:4:"𝖋";s:1:"f";s:4:"𝖌";s:1:"g";s:4:"𝖍";s:1:"h";s:4:"𝖎";s:1:"i";s:4:"𝖏";s:1:"j";s:4:"𝖐";s:1:"k";s:4:"𝖑";s:1:"l";s:4:"𝖒";s:1:"m";s:4:"𝖓";s:1:"n";s:4:"𝖔";s:1:"o";s:4:"𝖕";s:1:"p";s:4:"𝖖";s:1:"q";s:4:"𝖗";s:1:"r";s:4:"𝖘";s:1:"s";s:4:"𝖙";s:1:"t";s:4:"𝖚";s:1:"u";s:4:"𝖛";s:1:"v";s:4:"𝖜";s:1:"w";s:4:"𝖝";s:1:"x";s:4:"𝖞";s:1:"y";s:4:"𝖟";s:1:"z";s:4:"𝖠";s:1:"A";s:4:"𝖡";s:1:"B";s:4:"𝖢";s:1:"C";s:4:"𝖣";s:1:"D";s:4:"𝖤";s:1:"E";s:4:"𝖥";s:1:"F";s:4:"𝖦";s:1:"G";s:4:"𝖧";s:1:"H";s:4:"𝖨";s:1:"I";s:4:"𝖩";s:1:"J";s:4:"𝖪";s:1:"K";s:4:"𝖫";s:1:"L";s:4:"𝖬";s:1:"M";s:4:"𝖭";s:1:"N";s:4:"𝖮";s:1:"O";s:4:"𝖯";s:1:"P";s:4:"𝖰";s:1:"Q";s:4:"𝖱";s:1:"R";s:4:"𝖲";s:1:"S";s:4:"𝖳";s:1:"T";s:4:"𝖴";s:1:"U";s:4:"𝖵";s:1:"V";s:4:"𝖶";s:1:"W";s:4:"𝖷";s:1:"X";s:4:"𝖸";s:1:"Y";s:4:"𝖹";s:1:"Z";s:4:"𝖺";s:1:"a";s:4:"𝖻";s:1:"b";s:4:"𝖼";s:1:"c";s:4:"𝖽";s:1:"d";s:4:"𝖾";s:1:"e";s:4:"𝖿";s:1:"f";s:4:"𝗀";s:1:"g";s:4:"𝗁";s:1:"h";s:4:"𝗂";s:1:"i";s:4:"𝗃";s:1:"j";s:4:"𝗄";s:1:"k";s:4:"𝗅";s:1:"l";s:4:"𝗆";s:1:"m";s:4:"𝗇";s:1:"n";s:4:"𝗈";s:1:"o";s:4:"𝗉";s:1:"p";s:4:"𝗊";s:1:"q";s:4:"𝗋";s:1:"r";s:4:"𝗌";s:1:"s";s:4:"𝗍";s:1:"t";s:4:"𝗎";s:1:"u";s:4:"𝗏";s:1:"v";s:4:"𝗐";s:1:"w";s:4:"𝗑";s:1:"x";s:4:"𝗒";s:1:"y";s:4:"𝗓";s:1:"z";s:4:"𝗔";s:1:"A";s:4:"𝗕";s:1:"B";s:4:"𝗖";s:1:"C";s:4:"𝗗";s:1:"D";s:4:"𝗘";s:1:"E";s:4:"𝗙";s:1:"F";s:4:"𝗚";s:1:"G";s:4:"𝗛";s:1:"H";s:4:"𝗜";s:1:"I";s:4:"𝗝";s:1:"J";s:4:"𝗞";s:1:"K";s:4:"𝗟";s:1:"L";s:4:"𝗠";s:1:"M";s:4:"𝗡";s:1:"N";s:4:"𝗢";s:1:"O";s:4:"𝗣";s:1:"P";s:4:"𝗤";s:1:"Q";s:4:"𝗥";s:1:"R";s:4:"𝗦";s:1:"S";s:4:"𝗧";s:1:"T";s:4:"𝗨";s:1:"U";s:4:"𝗩";s:1:"V";s:4:"𝗪";s:1:"W";s:4:"𝗫";s:1:"X";s:4:"𝗬";s:1:"Y";s:4:"𝗭";s:1:"Z";s:4:"𝗮";s:1:"a";s:4:"𝗯";s:1:"b";s:4:"𝗰";s:1:"c";s:4:"𝗱";s:1:"d";s:4:"𝗲";s:1:"e";s:4:"𝗳";s:1:"f";s:4:"𝗴";s:1:"g";s:4:"𝗵";s:1:"h";s:4:"𝗶";s:1:"i";s:4:"𝗷";s:1:"j";s:4:"𝗸";s:1:"k";s:4:"𝗹";s:1:"l";s:4:"𝗺";s:1:"m";s:4:"𝗻";s:1:"n";s:4:"𝗼";s:1:"o";s:4:"𝗽";s:1:"p";s:4:"𝗾";s:1:"q";s:4:"𝗿";s:1:"r";s:4:"𝘀";s:1:"s";s:4:"𝘁";s:1:"t";s:4:"𝘂";s:1:"u";s:4:"𝘃";s:1:"v";s:4:"𝘄";s:1:"w";s:4:"𝘅";s:1:"x";s:4:"𝘆";s:1:"y";s:4:"𝘇";s:1:"z";s:4:"𝘈";s:1:"A";s:4:"𝘉";s:1:"B";s:4:"𝘊";s:1:"C";s:4:"𝘋";s:1:"D";s:4:"𝘌";s:1:"E";s:4:"𝘍";s:1:"F";s:4:"𝘎";s:1:"G";s:4:"𝘏";s:1:"H";s:4:"𝘐";s:1:"I";s:4:"𝘑";s:1:"J";s:4:"𝘒";s:1:"K";s:4:"𝘓";s:1:"L";s:4:"𝘔";s:1:"M";s:4:"𝘕";s:1:"N";s:4:"𝘖";s:1:"O";s:4:"𝘗";s:1:"P";s:4:"𝘘";s:1:"Q";s:4:"𝘙";s:1:"R";s:4:"𝘚";s:1:"S";s:4:"𝘛";s:1:"T";s:4:"𝘜";s:1:"U";s:4:"𝘝";s:1:"V";s:4:"𝘞";s:1:"W";s:4:"𝘟";s:1:"X";s:4:"𝘠";s:1:"Y";s:4:"𝘡";s:1:"Z";s:4:"𝘢";s:1:"a";s:4:"𝘣";s:1:"b";s:4:"𝘤";s:1:"c";s:4:"𝘥";s:1:"d";s:4:"𝘦";s:1:"e";s:4:"𝘧";s:1:"f";s:4:"𝘨";s:1:"g";s:4:"𝘩";s:1:"h";s:4:"𝘪";s:1:"i";s:4:"𝘫";s:1:"j";s:4:"𝘬";s:1:"k";s:4:"𝘭";s:1:"l";s:4:"𝘮";s:1:"m";s:4:"𝘯";s:1:"n";s:4:"𝘰";s:1:"o";s:4:"𝘱";s:1:"p";s:4:"𝘲";s:1:"q";s:4:"𝘳";s:1:"r";s:4:"𝘴";s:1:"s";s:4:"𝘵";s:1:"t";s:4:"𝘶";s:1:"u";s:4:"𝘷";s:1:"v";s:4:"𝘸";s:1:"w";s:4:"𝘹";s:1:"x";s:4:"𝘺";s:1:"y";s:4:"𝘻";s:1:"z";s:4:"𝘼";s:1:"A";s:4:"𝘽";s:1:"B";s:4:"𝘾";s:1:"C";s:4:"𝘿";s:1:"D";s:4:"𝙀";s:1:"E";s:4:"𝙁";s:1:"F";s:4:"𝙂";s:1:"G";s:4:"𝙃";s:1:"H";s:4:"𝙄";s:1:"I";s:4:"𝙅";s:1:"J";s:4:"𝙆";s:1:"K";s:4:"𝙇";s:1:"L";s:4:"𝙈";s:1:"M";s:4:"𝙉";s:1:"N";s:4:"𝙊";s:1:"O";s:4:"𝙋";s:1:"P";s:4:"𝙌";s:1:"Q";s:4:"𝙍";s:1:"R";s:4:"𝙎";s:1:"S";s:4:"𝙏";s:1:"T";s:4:"𝙐";s:1:"U";s:4:"𝙑";s:1:"V";s:4:"𝙒";s:1:"W";s:4:"𝙓";s:1:"X";s:4:"𝙔";s:1:"Y";s:4:"𝙕";s:1:"Z";s:4:"𝙖";s:1:"a";s:4:"𝙗";s:1:"b";s:4:"𝙘";s:1:"c";s:4:"𝙙";s:1:"d";s:4:"𝙚";s:1:"e";s:4:"𝙛";s:1:"f";s:4:"𝙜";s:1:"g";s:4:"𝙝";s:1:"h";s:4:"𝙞";s:1:"i";s:4:"𝙟";s:1:"j";s:4:"𝙠";s:1:"k";s:4:"𝙡";s:1:"l";s:4:"𝙢";s:1:"m";s:4:"𝙣";s:1:"n";s:4:"𝙤";s:1:"o";s:4:"𝙥";s:1:"p";s:4:"𝙦";s:1:"q";s:4:"𝙧";s:1:"r";s:4:"𝙨";s:1:"s";s:4:"𝙩";s:1:"t";s:4:"𝙪";s:1:"u";s:4:"𝙫";s:1:"v";s:4:"𝙬";s:1:"w";s:4:"𝙭";s:1:"x";s:4:"𝙮";s:1:"y";s:4:"𝙯";s:1:"z";s:4:"𝙰";s:1:"A";s:4:"𝙱";s:1:"B";s:4:"𝙲";s:1:"C";s:4:"𝙳";s:1:"D";s:4:"𝙴";s:1:"E";s:4:"𝙵";s:1:"F";s:4:"𝙶";s:1:"G";s:4:"𝙷";s:1:"H";s:4:"𝙸";s:1:"I";s:4:"𝙹";s:1:"J";s:4:"𝙺";s:1:"K";s:4:"𝙻";s:1:"L";s:4:"𝙼";s:1:"M";s:4:"𝙽";s:1:"N";s:4:"𝙾";s:1:"O";s:4:"𝙿";s:1:"P";s:4:"𝚀";s:1:"Q";s:4:"𝚁";s:1:"R";s:4:"𝚂";s:1:"S";s:4:"𝚃";s:1:"T";s:4:"𝚄";s:1:"U";s:4:"𝚅";s:1:"V";s:4:"𝚆";s:1:"W";s:4:"𝚇";s:1:"X";s:4:"𝚈";s:1:"Y";s:4:"𝚉";s:1:"Z";s:4:"𝚊";s:1:"a";s:4:"𝚋";s:1:"b";s:4:"𝚌";s:1:"c";s:4:"𝚍";s:1:"d";s:4:"𝚎";s:1:"e";s:4:"𝚏";s:1:"f";s:4:"𝚐";s:1:"g";s:4:"𝚑";s:1:"h";s:4:"𝚒";s:1:"i";s:4:"𝚓";s:1:"j";s:4:"𝚔";s:1:"k";s:4:"𝚕";s:1:"l";s:4:"𝚖";s:1:"m";s:4:"𝚗";s:1:"n";s:4:"𝚘";s:1:"o";s:4:"𝚙";s:1:"p";s:4:"𝚚";s:1:"q";s:4:"𝚛";s:1:"r";s:4:"𝚜";s:1:"s";s:4:"𝚝";s:1:"t";s:4:"𝚞";s:1:"u";s:4:"𝚟";s:1:"v";s:4:"𝚠";s:1:"w";s:4:"𝚡";s:1:"x";s:4:"𝚢";s:1:"y";s:4:"𝚣";s:1:"z";s:4:"𝚤";s:2:"ı";s:4:"𝚥";s:2:"ȷ";s:4:"𝚨";s:2:"Α";s:4:"𝚩";s:2:"Β";s:4:"𝚪";s:2:"Γ";s:4:"𝚫";s:2:"Δ";s:4:"𝚬";s:2:"Ε";s:4:"𝚭";s:2:"Ζ";s:4:"𝚮";s:2:"Η";s:4:"𝚯";s:2:"Θ";s:4:"𝚰";s:2:"Ι";s:4:"𝚱";s:2:"Κ";s:4:"𝚲";s:2:"Λ";s:4:"𝚳";s:2:"Μ";s:4:"𝚴";s:2:"Ν";s:4:"𝚵";s:2:"Ξ";s:4:"𝚶";s:2:"Ο";s:4:"𝚷";s:2:"Π";s:4:"𝚸";s:2:"Ρ";s:4:"𝚹";s:2:"Θ";s:4:"𝚺";s:2:"Σ";s:4:"𝚻";s:2:"Τ";s:4:"𝚼";s:2:"Υ";s:4:"𝚽";s:2:"Φ";s:4:"𝚾";s:2:"Χ";s:4:"𝚿";s:2:"Ψ";s:4:"𝛀";s:2:"Ω";s:4:"𝛁";s:3:"∇";s:4:"𝛂";s:2:"α";s:4:"𝛃";s:2:"β";s:4:"𝛄";s:2:"γ";s:4:"𝛅";s:2:"δ";s:4:"𝛆";s:2:"ε";s:4:"𝛇";s:2:"ζ";s:4:"𝛈";s:2:"η";s:4:"𝛉";s:2:"θ";s:4:"𝛊";s:2:"ι";s:4:"𝛋";s:2:"κ";s:4:"𝛌";s:2:"λ";s:4:"𝛍";s:2:"μ";s:4:"𝛎";s:2:"ν";s:4:"𝛏";s:2:"ξ";s:4:"𝛐";s:2:"ο";s:4:"𝛑";s:2:"π";s:4:"𝛒";s:2:"ρ";s:4:"𝛓";s:2:"ς";s:4:"𝛔";s:2:"σ";s:4:"𝛕";s:2:"τ";s:4:"𝛖";s:2:"υ";s:4:"𝛗";s:2:"φ";s:4:"𝛘";s:2:"χ";s:4:"𝛙";s:2:"ψ";s:4:"𝛚";s:2:"ω";s:4:"𝛛";s:3:"∂";s:4:"𝛜";s:2:"ε";s:4:"𝛝";s:2:"θ";s:4:"𝛞";s:2:"κ";s:4:"𝛟";s:2:"φ";s:4:"𝛠";s:2:"ρ";s:4:"𝛡";s:2:"π";s:4:"𝛢";s:2:"Α";s:4:"𝛣";s:2:"Β";s:4:"𝛤";s:2:"Γ";s:4:"𝛥";s:2:"Δ";s:4:"𝛦";s:2:"Ε";s:4:"𝛧";s:2:"Ζ";s:4:"𝛨";s:2:"Η";s:4:"𝛩";s:2:"Θ";s:4:"𝛪";s:2:"Ι";s:4:"𝛫";s:2:"Κ";s:4:"𝛬";s:2:"Λ";s:4:"𝛭";s:2:"Μ";s:4:"𝛮";s:2:"Ν";s:4:"𝛯";s:2:"Ξ";s:4:"𝛰";s:2:"Ο";s:4:"𝛱";s:2:"Π";s:4:"𝛲";s:2:"Ρ";s:4:"𝛳";s:2:"Θ";s:4:"𝛴";s:2:"Σ";s:4:"𝛵";s:2:"Τ";s:4:"𝛶";s:2:"Υ";s:4:"𝛷";s:2:"Φ";s:4:"𝛸";s:2:"Χ";s:4:"𝛹";s:2:"Ψ";s:4:"𝛺";s:2:"Ω";s:4:"𝛻";s:3:"∇";s:4:"𝛼";s:2:"α";s:4:"𝛽";s:2:"β";s:4:"𝛾";s:2:"γ";s:4:"𝛿";s:2:"δ";s:4:"𝜀";s:2:"ε";s:4:"𝜁";s:2:"ζ";s:4:"𝜂";s:2:"η";s:4:"𝜃";s:2:"θ";s:4:"𝜄";s:2:"ι";s:4:"𝜅";s:2:"κ";s:4:"𝜆";s:2:"λ";s:4:"𝜇";s:2:"μ";s:4:"𝜈";s:2:"ν";s:4:"𝜉";s:2:"ξ";s:4:"𝜊";s:2:"ο";s:4:"𝜋";s:2:"π";s:4:"𝜌";s:2:"ρ";s:4:"𝜍";s:2:"ς";s:4:"𝜎";s:2:"σ";s:4:"𝜏";s:2:"τ";s:4:"𝜐";s:2:"υ";s:4:"𝜑";s:2:"φ";s:4:"𝜒";s:2:"χ";s:4:"𝜓";s:2:"ψ";s:4:"𝜔";s:2:"ω";s:4:"𝜕";s:3:"∂";s:4:"𝜖";s:2:"ε";s:4:"𝜗";s:2:"θ";s:4:"𝜘";s:2:"κ";s:4:"𝜙";s:2:"φ";s:4:"𝜚";s:2:"ρ";s:4:"𝜛";s:2:"π";s:4:"𝜜";s:2:"Α";s:4:"𝜝";s:2:"Β";s:4:"𝜞";s:2:"Γ";s:4:"𝜟";s:2:"Δ";s:4:"𝜠";s:2:"Ε";s:4:"𝜡";s:2:"Ζ";s:4:"𝜢";s:2:"Η";s:4:"𝜣";s:2:"Θ";s:4:"𝜤";s:2:"Ι";s:4:"𝜥";s:2:"Κ";s:4:"𝜦";s:2:"Λ";s:4:"𝜧";s:2:"Μ";s:4:"𝜨";s:2:"Ν";s:4:"𝜩";s:2:"Ξ";s:4:"𝜪";s:2:"Ο";s:4:"𝜫";s:2:"Π";s:4:"𝜬";s:2:"Ρ";s:4:"𝜭";s:2:"Θ";s:4:"𝜮";s:2:"Σ";s:4:"𝜯";s:2:"Τ";s:4:"𝜰";s:2:"Υ";s:4:"𝜱";s:2:"Φ";s:4:"𝜲";s:2:"Χ";s:4:"𝜳";s:2:"Ψ";s:4:"𝜴";s:2:"Ω";s:4:"𝜵";s:3:"∇";s:4:"𝜶";s:2:"α";s:4:"𝜷";s:2:"β";s:4:"𝜸";s:2:"γ";s:4:"𝜹";s:2:"δ";s:4:"𝜺";s:2:"ε";s:4:"𝜻";s:2:"ζ";s:4:"𝜼";s:2:"η";s:4:"𝜽";s:2:"θ";s:4:"𝜾";s:2:"ι";s:4:"𝜿";s:2:"κ";s:4:"𝝀";s:2:"λ";s:4:"𝝁";s:2:"μ";s:4:"𝝂";s:2:"ν";s:4:"𝝃";s:2:"ξ";s:4:"𝝄";s:2:"ο";s:4:"𝝅";s:2:"π";s:4:"𝝆";s:2:"ρ";s:4:"𝝇";s:2:"ς";s:4:"𝝈";s:2:"σ";s:4:"𝝉";s:2:"τ";s:4:"𝝊";s:2:"υ";s:4:"𝝋";s:2:"φ";s:4:"𝝌";s:2:"χ";s:4:"𝝍";s:2:"ψ";s:4:"𝝎";s:2:"ω";s:4:"𝝏";s:3:"∂";s:4:"𝝐";s:2:"ε";s:4:"𝝑";s:2:"θ";s:4:"𝝒";s:2:"κ";s:4:"𝝓";s:2:"φ";s:4:"𝝔";s:2:"ρ";s:4:"𝝕";s:2:"π";s:4:"𝝖";s:2:"Α";s:4:"𝝗";s:2:"Β";s:4:"𝝘";s:2:"Γ";s:4:"𝝙";s:2:"Δ";s:4:"𝝚";s:2:"Ε";s:4:"𝝛";s:2:"Ζ";s:4:"𝝜";s:2:"Η";s:4:"𝝝";s:2:"Θ";s:4:"𝝞";s:2:"Ι";s:4:"𝝟";s:2:"Κ";s:4:"𝝠";s:2:"Λ";s:4:"𝝡";s:2:"Μ";s:4:"𝝢";s:2:"Ν";s:4:"𝝣";s:2:"Ξ";s:4:"𝝤";s:2:"Ο";s:4:"𝝥";s:2:"Π";s:4:"𝝦";s:2:"Ρ";s:4:"𝝧";s:2:"Θ";s:4:"𝝨";s:2:"Σ";s:4:"𝝩";s:2:"Τ";s:4:"𝝪";s:2:"Υ";s:4:"𝝫";s:2:"Φ";s:4:"𝝬";s:2:"Χ";s:4:"𝝭";s:2:"Ψ";s:4:"𝝮";s:2:"Ω";s:4:"𝝯";s:3:"∇";s:4:"𝝰";s:2:"α";s:4:"𝝱";s:2:"β";s:4:"𝝲";s:2:"γ";s:4:"𝝳";s:2:"δ";s:4:"𝝴";s:2:"ε";s:4:"𝝵";s:2:"ζ";s:4:"𝝶";s:2:"η";s:4:"𝝷";s:2:"θ";s:4:"𝝸";s:2:"ι";s:4:"𝝹";s:2:"κ";s:4:"𝝺";s:2:"λ";s:4:"𝝻";s:2:"μ";s:4:"𝝼";s:2:"ν";s:4:"𝝽";s:2:"ξ";s:4:"𝝾";s:2:"ο";s:4:"𝝿";s:2:"π";s:4:"𝞀";s:2:"ρ";s:4:"𝞁";s:2:"ς";s:4:"𝞂";s:2:"σ";s:4:"𝞃";s:2:"τ";s:4:"𝞄";s:2:"υ";s:4:"𝞅";s:2:"φ";s:4:"𝞆";s:2:"χ";s:4:"𝞇";s:2:"ψ";s:4:"𝞈";s:2:"ω";s:4:"𝞉";s:3:"∂";s:4:"𝞊";s:2:"ε";s:4:"𝞋";s:2:"θ";s:4:"𝞌";s:2:"κ";s:4:"𝞍";s:2:"φ";s:4:"𝞎";s:2:"ρ";s:4:"𝞏";s:2:"π";s:4:"𝞐";s:2:"Α";s:4:"𝞑";s:2:"Β";s:4:"𝞒";s:2:"Γ";s:4:"𝞓";s:2:"Δ";s:4:"𝞔";s:2:"Ε";s:4:"𝞕";s:2:"Ζ";s:4:"𝞖";s:2:"Η";s:4:"𝞗";s:2:"Θ";s:4:"𝞘";s:2:"Ι";s:4:"𝞙";s:2:"Κ";s:4:"𝞚";s:2:"Λ";s:4:"𝞛";s:2:"Μ";s:4:"𝞜";s:2:"Ν";s:4:"𝞝";s:2:"Ξ";s:4:"𝞞";s:2:"Ο";s:4:"𝞟";s:2:"Π";s:4:"𝞠";s:2:"Ρ";s:4:"𝞡";s:2:"Θ";s:4:"𝞢";s:2:"Σ";s:4:"𝞣";s:2:"Τ";s:4:"𝞤";s:2:"Υ";s:4:"𝞥";s:2:"Φ";s:4:"𝞦";s:2:"Χ";s:4:"𝞧";s:2:"Ψ";s:4:"𝞨";s:2:"Ω";s:4:"𝞩";s:3:"∇";s:4:"𝞪";s:2:"α";s:4:"𝞫";s:2:"β";s:4:"𝞬";s:2:"γ";s:4:"𝞭";s:2:"δ";s:4:"𝞮";s:2:"ε";s:4:"𝞯";s:2:"ζ";s:4:"𝞰";s:2:"η";s:4:"𝞱";s:2:"θ";s:4:"𝞲";s:2:"ι";s:4:"𝞳";s:2:"κ";s:4:"𝞴";s:2:"λ";s:4:"𝞵";s:2:"μ";s:4:"𝞶";s:2:"ν";s:4:"𝞷";s:2:"ξ";s:4:"𝞸";s:2:"ο";s:4:"𝞹";s:2:"π";s:4:"𝞺";s:2:"ρ";s:4:"𝞻";s:2:"ς";s:4:"𝞼";s:2:"σ";s:4:"𝞽";s:2:"τ";s:4:"𝞾";s:2:"υ";s:4:"𝞿";s:2:"φ";s:4:"𝟀";s:2:"χ";s:4:"𝟁";s:2:"ψ";s:4:"𝟂";s:2:"ω";s:4:"𝟃";s:3:"∂";s:4:"𝟄";s:2:"ε";s:4:"𝟅";s:2:"θ";s:4:"𝟆";s:2:"κ";s:4:"𝟇";s:2:"φ";s:4:"𝟈";s:2:"ρ";s:4:"𝟉";s:2:"π";s:4:"𝟎";s:1:"0";s:4:"𝟏";s:1:"1";s:4:"𝟐";s:1:"2";s:4:"𝟑";s:1:"3";s:4:"𝟒";s:1:"4";s:4:"𝟓";s:1:"5";s:4:"𝟔";s:1:"6";s:4:"𝟕";s:1:"7";s:4:"𝟖";s:1:"8";s:4:"𝟗";s:1:"9";s:4:"𝟘";s:1:"0";s:4:"𝟙";s:1:"1";s:4:"𝟚";s:1:"2";s:4:"𝟛";s:1:"3";s:4:"𝟜";s:1:"4";s:4:"𝟝";s:1:"5";s:4:"𝟞";s:1:"6";s:4:"𝟟";s:1:"7";s:4:"𝟠";s:1:"8";s:4:"𝟡";s:1:"9";s:4:"𝟢";s:1:"0";s:4:"𝟣";s:1:"1";s:4:"𝟤";s:1:"2";s:4:"𝟥";s:1:"3";s:4:"𝟦";s:1:"4";s:4:"𝟧";s:1:"5";s:4:"𝟨";s:1:"6";s:4:"𝟩";s:1:"7";s:4:"𝟪";s:1:"8";s:4:"𝟫";s:1:"9";s:4:"𝟬";s:1:"0";s:4:"𝟭";s:1:"1";s:4:"𝟮";s:1:"2";s:4:"𝟯";s:1:"3";s:4:"𝟰";s:1:"4";s:4:"𝟱";s:1:"5";s:4:"𝟲";s:1:"6";s:4:"𝟳";s:1:"7";s:4:"𝟴";s:1:"8";s:4:"𝟵";s:1:"9";s:4:"𝟶";s:1:"0";s:4:"𝟷";s:1:"1";s:4:"𝟸";s:1:"2";s:4:"𝟹";s:1:"3";s:4:"𝟺";s:1:"4";s:4:"𝟻";s:1:"5";s:4:"𝟼";s:1:"6";s:4:"𝟽";s:1:"7";s:4:"𝟾";s:1:"8";s:4:"𝟿";s:1:"9";s:4:"丽";s:3:"丽";s:4:"丸";s:3:"丸";s:4:"乁";s:3:"乁";s:4:"𠄢";s:4:"𠄢";s:4:"你";s:3:"你";s:4:"侮";s:3:"侮";s:4:"侻";s:3:"侻";s:4:"倂";s:3:"倂";s:4:"偺";s:3:"偺";s:4:"備";s:3:"備";s:4:"僧";s:3:"僧";s:4:"像";s:3:"像";s:4:"㒞";s:3:"㒞";s:4:"𠘺";s:4:"𠘺";s:4:"免";s:3:"免";s:4:"兔";s:3:"兔";s:4:"兤";s:3:"兤";s:4:"具";s:3:"具";s:4:"𠔜";s:4:"𠔜";s:4:"㒹";s:3:"㒹";s:4:"內";s:3:"內";s:4:"再";s:3:"再";s:4:"𠕋";s:4:"𠕋";s:4:"冗";s:3:"冗";s:4:"冤";s:3:"冤";s:4:"仌";s:3:"仌";s:4:"冬";s:3:"冬";s:4:"况";s:3:"况";s:4:"𩇟";s:4:"𩇟";s:4:"凵";s:3:"凵";s:4:"刃";s:3:"刃";s:4:"㓟";s:3:"㓟";s:4:"刻";s:3:"刻";s:4:"剆";s:3:"剆";s:4:"割";s:3:"割";s:4:"剷";s:3:"剷";s:4:"㔕";s:3:"㔕";s:4:"勇";s:3:"勇";s:4:"勉";s:3:"勉";s:4:"勤";s:3:"勤";s:4:"勺";s:3:"勺";s:4:"包";s:3:"包";s:4:"匆";s:3:"匆";s:4:"北";s:3:"北";s:4:"卉";s:3:"卉";s:4:"卑";s:3:"卑";s:4:"博";s:3:"博";s:4:"即";s:3:"即";s:4:"卽";s:3:"卽";s:4:"卿";s:3:"卿";s:4:"卿";s:3:"卿";s:4:"卿";s:3:"卿";s:4:"𠨬";s:4:"𠨬";s:4:"灰";s:3:"灰";s:4:"及";s:3:"及";s:4:"叟";s:3:"叟";s:4:"𠭣";s:4:"𠭣";s:4:"叫";s:3:"叫";s:4:"叱";s:3:"叱";s:4:"吆";s:3:"吆";s:4:"咞";s:3:"咞";s:4:"吸";s:3:"吸";s:4:"呈";s:3:"呈";s:4:"周";s:3:"周";s:4:"咢";s:3:"咢";s:4:"哶";s:3:"哶";s:4:"唐";s:3:"唐";s:4:"啓";s:3:"啓";s:4:"啣";s:3:"啣";s:4:"善";s:3:"善";s:4:"善";s:3:"善";s:4:"喙";s:3:"喙";s:4:"喫";s:3:"喫";s:4:"喳";s:3:"喳";s:4:"嗂";s:3:"嗂";s:4:"圖";s:3:"圖";s:4:"嘆";s:3:"嘆";s:4:"圗";s:3:"圗";s:4:"噑";s:3:"噑";s:4:"噴";s:3:"噴";s:4:"切";s:3:"切";s:4:"壮";s:3:"壮";s:4:"城";s:3:"城";s:4:"埴";s:3:"埴";s:4:"堍";s:3:"堍";s:4:"型";s:3:"型";s:4:"堲";s:3:"堲";s:4:"報";s:3:"報";s:4:"墬";s:3:"墬";s:4:"𡓤";s:4:"𡓤";s:4:"売";s:3:"売";s:4:"壷";s:3:"壷";s:4:"夆";s:3:"夆";s:4:"多";s:3:"多";s:4:"夢";s:3:"夢";s:4:"奢";s:3:"奢";s:4:"𡚨";s:4:"𡚨";s:4:"𡛪";s:4:"𡛪";s:4:"姬";s:3:"姬";s:4:"娛";s:3:"娛";s:4:"娧";s:3:"娧";s:4:"姘";s:3:"姘";s:4:"婦";s:3:"婦";s:4:"㛮";s:3:"㛮";s:4:"㛼";s:3:"㛼";s:4:"嬈";s:3:"嬈";s:4:"嬾";s:3:"嬾";s:4:"嬾";s:3:"嬾";s:4:"𡧈";s:4:"𡧈";s:4:"寃";s:3:"寃";s:4:"寘";s:3:"寘";s:4:"寧";s:3:"寧";s:4:"寳";s:3:"寳";s:4:"𡬘";s:4:"𡬘";s:4:"寿";s:3:"寿";s:4:"将";s:3:"将";s:4:"当";s:3:"当";s:4:"尢";s:3:"尢";s:4:"㞁";s:3:"㞁";s:4:"屠";s:3:"屠";s:4:"屮";s:3:"屮";s:4:"峀";s:3:"峀";s:4:"岍";s:3:"岍";s:4:"𡷤";s:4:"𡷤";s:4:"嵃";s:3:"嵃";s:4:"𡷦";s:4:"𡷦";s:4:"嵮";s:3:"嵮";s:4:"嵫";s:3:"嵫";s:4:"嵼";s:3:"嵼";s:4:"巡";s:3:"巡";s:4:"巢";s:3:"巢";s:4:"㠯";s:3:"㠯";s:4:"巽";s:3:"巽";s:4:"帨";s:3:"帨";s:4:"帽";s:3:"帽";s:4:"幩";s:3:"幩";s:4:"㡢";s:3:"㡢";s:4:"𢆃";s:4:"𢆃";s:4:"㡼";s:3:"㡼";s:4:"庰";s:3:"庰";s:4:"庳";s:3:"庳";s:4:"庶";s:3:"庶";s:4:"廊";s:3:"廊";s:4:"𪎒";s:4:"𪎒";s:4:"廾";s:3:"廾";s:4:"𢌱";s:4:"𢌱";s:4:"𢌱";s:4:"𢌱";s:4:"舁";s:3:"舁";s:4:"弢";s:3:"弢";s:4:"弢";s:3:"弢";s:4:"㣇";s:3:"㣇";s:4:"𣊸";s:4:"𣊸";s:4:"𦇚";s:4:"𦇚";s:4:"形";s:3:"形";s:4:"彫";s:3:"彫";s:4:"㣣";s:3:"㣣";s:4:"徚";s:3:"徚";s:4:"忍";s:3:"忍";s:4:"志";s:3:"志";s:4:"忹";s:3:"忹";s:4:"悁";s:3:"悁";s:4:"㤺";s:3:"㤺";s:4:"㤜";s:3:"㤜";s:4:"悔";s:3:"悔";s:4:"𢛔";s:4:"𢛔";s:4:"惇";s:3:"惇";s:4:"慈";s:3:"慈";s:4:"慌";s:3:"慌";s:4:"慎";s:3:"慎";s:4:"慌";s:3:"慌";s:4:"慺";s:3:"慺";s:4:"憎";s:3:"憎";s:4:"憲";s:3:"憲";s:4:"憤";s:3:"憤";s:4:"憯";s:3:"憯";s:4:"懞";s:3:"懞";s:4:"懲";s:3:"懲";s:4:"懶";s:3:"懶";s:4:"成";s:3:"成";s:4:"戛";s:3:"戛";s:4:"扝";s:3:"扝";s:4:"抱";s:3:"抱";s:4:"拔";s:3:"拔";s:4:"捐";s:3:"捐";s:4:"𢬌";s:4:"𢬌";s:4:"挽";s:3:"挽";s:4:"拼";s:3:"拼";s:4:"捨";s:3:"捨";s:4:"掃";s:3:"掃";s:4:"揤";s:3:"揤";s:4:"𢯱";s:4:"𢯱";s:4:"搢";s:3:"搢";s:4:"揅";s:3:"揅";s:4:"掩";s:3:"掩";s:4:"㨮";s:3:"㨮";s:4:"摩";s:3:"摩";s:4:"摾";s:3:"摾";s:4:"撝";s:3:"撝";s:4:"摷";s:3:"摷";s:4:"㩬";s:3:"㩬";s:4:"敏";s:3:"敏";s:4:"敬";s:3:"敬";s:4:"𣀊";s:4:"𣀊";s:4:"旣";s:3:"旣";s:4:"書";s:3:"書";s:4:"晉";s:3:"晉";s:4:"㬙";s:3:"㬙";s:4:"暑";s:3:"暑";s:4:"㬈";s:3:"㬈";s:4:"㫤";s:3:"㫤";s:4:"冒";s:3:"冒";s:4:"冕";s:3:"冕";s:4:"最";s:3:"最";s:4:"暜";s:3:"暜";s:4:"肭";s:3:"肭";s:4:"䏙";s:3:"䏙";s:4:"朗";s:3:"朗";s:4:"望";s:3:"望";s:4:"朡";s:3:"朡";s:4:"杞";s:3:"杞";s:4:"杓";s:3:"杓";s:4:"𣏃";s:4:"𣏃";s:4:"㭉";s:3:"㭉";s:4:"柺";s:3:"柺";s:4:"枅";s:3:"枅";s:4:"桒";s:3:"桒";s:4:"梅";s:3:"梅";s:4:"𣑭";s:4:"𣑭";s:4:"梎";s:3:"梎";s:4:"栟";s:3:"栟";s:4:"椔";s:3:"椔";s:4:"㮝";s:3:"㮝";s:4:"楂";s:3:"楂";s:4:"榣";s:3:"榣";s:4:"槪";s:3:"槪";s:4:"檨";s:3:"檨";s:4:"𣚣";s:4:"𣚣";s:4:"櫛";s:3:"櫛";s:4:"㰘";s:3:"㰘";s:4:"次";s:3:"次";s:4:"𣢧";s:4:"𣢧";s:4:"歔";s:3:"歔";s:4:"㱎";s:3:"㱎";s:4:"歲";s:3:"歲";s:4:"殟";s:3:"殟";s:4:"殺";s:3:"殺";s:4:"殻";s:3:"殻";s:4:"𣪍";s:4:"𣪍";s:4:"𡴋";s:4:"𡴋";s:4:"𣫺";s:4:"𣫺";s:4:"汎";s:3:"汎";s:4:"𣲼";s:4:"𣲼";s:4:"沿";s:3:"沿";s:4:"泍";s:3:"泍";s:4:"汧";s:3:"汧";s:4:"洖";s:3:"洖";s:4:"派";s:3:"派";s:4:"海";s:3:"海";s:4:"流";s:3:"流";s:4:"浩";s:3:"浩";s:4:"浸";s:3:"浸";s:4:"涅";s:3:"涅";s:4:"𣴞";s:4:"𣴞";s:4:"洴";s:3:"洴";s:4:"港";s:3:"港";s:4:"湮";s:3:"湮";s:4:"㴳";s:3:"㴳";s:4:"滋";s:3:"滋";s:4:"滇";s:3:"滇";s:4:"𣻑";s:4:"𣻑";s:4:"淹";s:3:"淹";s:4:"潮";s:3:"潮";s:4:"𣽞";s:4:"𣽞";s:4:"𣾎";s:4:"𣾎";s:4:"濆";s:3:"濆";s:4:"瀹";s:3:"瀹";s:4:"瀞";s:3:"瀞";s:4:"瀛";s:3:"瀛";s:4:"㶖";s:3:"㶖";s:4:"灊";s:3:"灊";s:4:"災";s:3:"災";s:4:"灷";s:3:"灷";s:4:"炭";s:3:"炭";s:4:"𠔥";s:4:"𠔥";s:4:"煅";s:3:"煅";s:4:"𤉣";s:4:"𤉣";s:4:"熜";s:3:"熜";s:4:"𤎫";s:4:"𤎫";s:4:"爨";s:3:"爨";s:4:"爵";s:3:"爵";s:4:"牐";s:3:"牐";s:4:"𤘈";s:4:"𤘈";s:4:"犀";s:3:"犀";s:4:"犕";s:3:"犕";s:4:"𤜵";s:4:"𤜵";s:4:"𤠔";s:4:"𤠔";s:4:"獺";s:3:"獺";s:4:"王";s:3:"王";s:4:"㺬";s:3:"㺬";s:4:"玥";s:3:"玥";s:4:"㺸";s:3:"㺸";s:4:"㺸";s:3:"㺸";s:4:"瑇";s:3:"瑇";s:4:"瑜";s:3:"瑜";s:4:"瑱";s:3:"瑱";s:4:"璅";s:3:"璅";s:4:"瓊";s:3:"瓊";s:4:"㼛";s:3:"㼛";s:4:"甤";s:3:"甤";s:4:"𤰶";s:4:"𤰶";s:4:"甾";s:3:"甾";s:4:"𤲒";s:4:"𤲒";s:4:"異";s:3:"異";s:4:"𢆟";s:4:"𢆟";s:4:"瘐";s:3:"瘐";s:4:"𤾡";s:4:"𤾡";s:4:"𤾸";s:4:"𤾸";s:4:"𥁄";s:4:"𥁄";s:4:"㿼";s:3:"㿼";s:4:"䀈";s:3:"䀈";s:4:"直";s:3:"直";s:4:"𥃳";s:4:"𥃳";s:4:"𥃲";s:4:"𥃲";s:4:"𥄙";s:4:"𥄙";s:4:"𥄳";s:4:"𥄳";s:4:"眞";s:3:"眞";s:4:"真";s:3:"真";s:4:"真";s:3:"真";s:4:"睊";s:3:"睊";s:4:"䀹";s:3:"䀹";s:4:"瞋";s:3:"瞋";s:4:"䁆";s:3:"䁆";s:4:"䂖";s:3:"䂖";s:4:"𥐝";s:4:"𥐝";s:4:"硎";s:3:"硎";s:4:"碌";s:3:"碌";s:4:"磌";s:3:"磌";s:4:"䃣";s:3:"䃣";s:4:"𥘦";s:4:"𥘦";s:4:"祖";s:3:"祖";s:4:"𥚚";s:4:"𥚚";s:4:"𥛅";s:4:"𥛅";s:4:"福";s:3:"福";s:4:"秫";s:3:"秫";s:4:"䄯";s:3:"䄯";s:4:"穀";s:3:"穀";s:4:"穊";s:3:"穊";s:4:"穏";s:3:"穏";s:4:"𥥼";s:4:"𥥼";s:4:"𥪧";s:4:"𥪧";s:4:"𥪧";s:4:"𥪧";s:4:"竮";s:3:"竮";s:4:"䈂";s:3:"䈂";s:4:"𥮫";s:4:"𥮫";s:4:"篆";s:3:"篆";s:4:"築";s:3:"築";s:4:"䈧";s:3:"䈧";s:4:"𥲀";s:4:"𥲀";s:4:"糒";s:3:"糒";s:4:"䊠";s:3:"䊠";s:4:"糨";s:3:"糨";s:4:"糣";s:3:"糣";s:4:"紀";s:3:"紀";s:4:"𥾆";s:4:"𥾆";s:4:"絣";s:3:"絣";s:4:"䌁";s:3:"䌁";s:4:"緇";s:3:"緇";s:4:"縂";s:3:"縂";s:4:"繅";s:3:"繅";s:4:"䌴";s:3:"䌴";s:4:"𦈨";s:4:"𦈨";s:4:"𦉇";s:4:"𦉇";s:4:"䍙";s:3:"䍙";s:4:"𦋙";s:4:"𦋙";s:4:"罺";s:3:"罺";s:4:"𦌾";s:4:"𦌾";s:4:"羕";s:3:"羕";s:4:"翺";s:3:"翺";s:4:"者";s:3:"者";s:4:"𦓚";s:4:"𦓚";s:4:"𦔣";s:4:"𦔣";s:4:"聠";s:3:"聠";s:4:"𦖨";s:4:"𦖨";s:4:"聰";s:3:"聰";s:4:"𣍟";s:4:"𣍟";s:4:"䏕";s:3:"䏕";s:4:"育";s:3:"育";s:4:"脃";s:3:"脃";s:4:"䐋";s:3:"䐋";s:4:"脾";s:3:"脾";s:4:"媵";s:3:"媵";s:4:"𦞧";s:4:"𦞧";s:4:"𦞵";s:4:"𦞵";s:4:"𣎓";s:4:"𣎓";s:4:"𣎜";s:4:"𣎜";s:4:"舁";s:3:"舁";s:4:"舄";s:3:"舄";s:4:"辞";s:3:"辞";s:4:"䑫";s:3:"䑫";s:4:"芑";s:3:"芑";s:4:"芋";s:3:"芋";s:4:"芝";s:3:"芝";s:4:"劳";s:3:"劳";s:4:"花";s:3:"花";s:4:"芳";s:3:"芳";s:4:"芽";s:3:"芽";s:4:"苦";s:3:"苦";s:4:"𦬼";s:4:"𦬼";s:4:"若";s:3:"若";s:4:"茝";s:3:"茝";s:4:"荣";s:3:"荣";s:4:"莭";s:3:"莭";s:4:"茣";s:3:"茣";s:4:"莽";s:3:"莽";s:4:"菧";s:3:"菧";s:4:"著";s:3:"著";s:4:"荓";s:3:"荓";s:4:"菊";s:3:"菊";s:4:"菌";s:3:"菌";s:4:"菜";s:3:"菜";s:4:"𦰶";s:4:"𦰶";s:4:"𦵫";s:4:"𦵫";s:4:"𦳕";s:4:"𦳕";s:4:"䔫";s:3:"䔫";s:4:"蓱";s:3:"蓱";s:4:"蓳";s:3:"蓳";s:4:"蔖";s:3:"蔖";s:4:"𧏊";s:4:"𧏊";s:4:"蕤";s:3:"蕤";s:4:"𦼬";s:4:"𦼬";s:4:"䕝";s:3:"䕝";s:4:"䕡";s:3:"䕡";s:4:"𦾱";s:4:"𦾱";s:4:"𧃒";s:4:"𧃒";s:4:"䕫";s:3:"䕫";s:4:"虐";s:3:"虐";s:4:"虜";s:3:"虜";s:4:"虧";s:3:"虧";s:4:"虩";s:3:"虩";s:4:"蚩";s:3:"蚩";s:4:"蚈";s:3:"蚈";s:4:"蜎";s:3:"蜎";s:4:"蛢";s:3:"蛢";s:4:"蝹";s:3:"蝹";s:4:"蜨";s:3:"蜨";s:4:"蝫";s:3:"蝫";s:4:"螆";s:3:"螆";s:4:"䗗";s:3:"䗗";s:4:"蟡";s:3:"蟡";s:4:"蠁";s:3:"蠁";s:4:"䗹";s:3:"䗹";s:4:"衠";s:3:"衠";s:4:"衣";s:3:"衣";s:4:"𧙧";s:4:"𧙧";s:4:"裗";s:3:"裗";s:4:"裞";s:3:"裞";s:4:"䘵";s:3:"䘵";s:4:"裺";s:3:"裺";s:4:"㒻";s:3:"㒻";s:4:"𧢮";s:4:"𧢮";s:4:"𧥦";s:4:"𧥦";s:4:"䚾";s:3:"䚾";s:4:"䛇";s:3:"䛇";s:4:"誠";s:3:"誠";s:4:"諭";s:3:"諭";s:4:"變";s:3:"變";s:4:"豕";s:3:"豕";s:4:"𧲨";s:4:"𧲨";s:4:"貫";s:3:"貫";s:4:"賁";s:3:"賁";s:4:"贛";s:3:"贛";s:4:"起";s:3:"起";s:4:"𧼯";s:4:"𧼯";s:4:"𠠄";s:4:"𠠄";s:4:"跋";s:3:"跋";s:4:"趼";s:3:"趼";s:4:"跰";s:3:"跰";s:4:"𠣞";s:4:"𠣞";s:4:"軔";s:3:"軔";s:4:"輸";s:3:"輸";s:4:"𨗒";s:4:"𨗒";s:4:"𨗭";s:4:"𨗭";s:4:"邔";s:3:"邔";s:4:"郱";s:3:"郱";s:4:"鄑";s:3:"鄑";s:4:"𨜮";s:4:"𨜮";s:4:"鄛";s:3:"鄛";s:4:"鈸";s:3:"鈸";s:4:"鋗";s:3:"鋗";s:4:"鋘";s:3:"鋘";s:4:"鉼";s:3:"鉼";s:4:"鏹";s:3:"鏹";s:4:"鐕";s:3:"鐕";s:4:"𨯺";s:4:"𨯺";s:4:"開";s:3:"開";s:4:"䦕";s:3:"䦕";s:4:"閷";s:3:"閷";s:4:"𨵷";s:4:"𨵷";s:4:"䧦";s:3:"䧦";s:4:"雃";s:3:"雃";s:4:"嶲";s:3:"嶲";s:4:"霣";s:3:"霣";s:4:"𩅅";s:4:"𩅅";s:4:"𩈚";s:4:"𩈚";s:4:"䩮";s:3:"䩮";s:4:"䩶";s:3:"䩶";s:4:"韠";s:3:"韠";s:4:"𩐊";s:4:"𩐊";s:4:"䪲";s:3:"䪲";s:4:"𩒖";s:4:"𩒖";s:4:"頋";s:3:"頋";s:4:"頋";s:3:"頋";s:4:"頩";s:3:"頩";s:4:"𩖶";s:4:"𩖶";s:4:"飢";s:3:"飢";s:4:"䬳";s:3:"䬳";s:4:"餩";s:3:"餩";s:4:"馧";s:3:"馧";s:4:"駂";s:3:"駂";s:4:"駾";s:3:"駾";s:4:"䯎";s:3:"䯎";s:4:"𩬰";s:4:"𩬰";s:4:"鬒";s:3:"鬒";s:4:"鱀";s:3:"鱀";s:4:"鳽";s:3:"鳽";s:4:"䳎";s:3:"䳎";s:4:"䳭";s:3:"䳭";s:4:"鵧";s:3:"鵧";s:4:"𪃎";s:4:"𪃎";s:4:"䳸";s:3:"䳸";s:4:"𪄅";s:4:"𪄅";s:4:"𪈎";s:4:"𪈎";s:4:"𪊑";s:4:"𪊑";s:4:"麻";s:3:"麻";s:4:"䵖";s:3:"䵖";s:4:"黹";s:3:"黹";s:4:"黾";s:3:"黾";s:4:"鼅";s:3:"鼅";s:4:"鼏";s:3:"鼏";s:4:"鼖";s:3:"鼖";s:4:"鼻";s:3:"鼻";s:4:"𪘀";s:4:"𪘀";}' );
+?>
diff --git a/includes/normal/UtfNormalGenerate.php b/includes/normal/UtfNormalGenerate.php
new file mode 100644
index 000000000000..f0eb5330d968
--- /dev/null
+++ b/includes/normal/UtfNormalGenerate.php
@@ -0,0 +1,236 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * This script generates UniNormalData.inc from the Unicode Character Database
+ * and supplementary files.
+ *
+ * @package UtfNormal
+ * @access private
+ */
+
+/** */
+
+if( php_sapi_name() != 'cli' ) {
+ die( "Run me from the command line please.\n" );
+}
+
+require_once 'UtfNormalUtil.php';
+
+$in = fopen("DerivedNormalizationProps.txt", "rt" );
+if( !$in ) {
+ print "Can't open DerivedNormalizationProps.txt for reading.\n";
+ print "If necessary, fetch this file from the internet:\n";
+ print "http://www.unicode.org/Public/UNIDATA/CompositionExclusions.txt\n";
+ exit(-1);
+}
+print "Initializing normalization quick check tables...\n";
+$checkNFC = array();
+while( false !== ($line = fgets( $in ) ) ) {
+ $matches = array();
+ if( preg_match( '/^([0-9A-F]+)(?:..([0-9A-F]+))?\s*;\s*(NFC_QC)\s*;\s*([MN])/', $line, $matches ) ) {
+ list( $junk, $first, $last, $prop, $value ) = $matches;
+ #print "$first $last $prop $value\n";
+ if( !$last ) $last = $first;
+ for( $i = hexdec( $first ); $i <= hexdec( $last ); $i++) {
+ $char = codepointToUtf8( $i );
+ $checkNFC[$char] = $value;
+ }
+ }
+}
+fclose( $in );
+
+$in = fopen("CompositionExclusions.txt", "rt" );
+if( !$in ) {
+ print "Can't open CompositionExclusions.txt for reading.\n";
+ print "If necessary, fetch this file from the internet:\n";
+ print "http://www.unicode.org/Public/UNIDATA/CompositionExclusions.txt\n";
+ exit(-1);
+}
+$exclude = array();
+while( false !== ($line = fgets( $in ) ) ) {
+ if( preg_match( '/^([0-9A-F]+)/i', $line, $matches ) ) {
+ $codepoint = $matches[1];
+ $source = codepointToUtf8( hexdec( $codepoint ) );
+ $exclude[$source] = true;
+ }
+}
+fclose($in);
+
+$in = fopen("UnicodeData.txt", "rt" );
+if( !$in ) {
+ print "Can't open UnicodeData.txt for reading.\n";
+ print "If necessary, fetch this file from the internet:\n";
+ print "http://www.unicode.org/Public/UNIDATA/UnicodeData.txt\n";
+ exit(-1);
+}
+
+$compatibilityDecomp = array();
+$canonicalDecomp = array();
+$canonicalComp = array();
+$combiningClass = array();
+$total = 0;
+$compat = 0;
+$canon = 0;
+
+print "Reading character definitions...\n";
+while( false !== ($line = fgets( $in ) ) ) {
+ $columns = split(';', $line);
+ $codepoint = $columns[0];
+ $name = $columns[1];
+ $canonicalCombiningClass = $columns[3];
+ $decompositionMapping = $columns[5];
+
+ $source = codepointToUtf8( hexdec( $codepoint ) );
+
+ if( $canonicalCombiningClass != 0 ) {
+ $combiningClass[$source] = intval( $canonicalCombiningClass );
+ }
+
+ if( $decompositionMapping === '' ) continue;
+ if( preg_match( '/^<(.+)> (.*)$/', $decompositionMapping, $matches ) ) {
+ # Compatibility decomposition
+ $canonical = false;
+ $decompositionMapping = $matches[2];
+ $compat++;
+ } else {
+ $canonical = true;
+ $canon++;
+ }
+ $total++;
+ $dest = hexSequenceToUtf8( $decompositionMapping );
+
+ $compatibilityDecomp[$source] = $dest;
+ if( $canonical ) {
+ $canonicalDecomp[$source] = $dest;
+ if( empty( $exclude[$source] ) ) {
+ $canonicalComp[$dest] = $source;
+ }
+ }
+ #print "$codepoint | $canonicalCombiningClasses | $decompositionMapping\n";
+}
+fclose( $in );
+
+print "Recursively expanding canonical mappings...\n";
+$changed = 42;
+$pass = 1;
+while( $changed > 0 ) {
+ print "pass $pass\n";
+ $changed = 0;
+ foreach( $canonicalDecomp as $source => $dest ) {
+ $newDest = preg_replace_callback(
+ '/([\xc0-\xff][\x80-\xbf]+)/',
+ 'callbackCanonical',
+ $dest);
+ if( $newDest === $dest ) continue;
+ $changed++;
+ $canonicalDecomp[$source] = $newDest;
+ }
+ $pass++;
+}
+
+print "Recursively expanding compatibility mappings...\n";
+$changed = 42;
+$pass = 1;
+while( $changed > 0 ) {
+ print "pass $pass\n";
+ $changed = 0;
+ foreach( $compatibilityDecomp as $source => $dest ) {
+ $newDest = preg_replace_callback(
+ '/([\xc0-\xff][\x80-\xbf]+)/',
+ 'callbackCompat',
+ $dest);
+ if( $newDest === $dest ) continue;
+ $changed++;
+ $compatibilityDecomp[$source] = $newDest;
+ }
+ $pass++;
+}
+
+print "$total decomposition mappings ($canon canonical, $compat compatibility)\n";
+
+$out = fopen("UtfNormalData.inc", "wt");
+if( $out ) {
+ $serCombining = escapeSingleString( serialize( $combiningClass ) );
+ $serComp = escapeSingleString( serialize( $canonicalComp ) );
+ $serCanon = escapeSingleString( serialize( $canonicalDecomp ) );
+ $serCheckNFC = escapeSingleString( serialize( $checkNFC ) );
+ $outdata = "<" . "?php
+/**
+ * This file was automatically generated -- do not edit!
+ * Run UtfNormalGenerate.php to create this file again (make clean && make)
+ * @package MediaWiki
+ */
+/** */
+global \$utfCombiningClass, \$utfCanonicalComp, \$utfCanonicalDecomp, \$utfCheckNFC;
+\$utfCombiningClass = unserialize( '$serCombining' );
+\$utfCanonicalComp = unserialize( '$serComp' );
+\$utfCanonicalDecomp = unserialize( '$serCanon' );
+\$utfCheckNFC = unserialize( '$serCheckNFC' );
+?" . ">\n";
+ fputs( $out, $outdata );
+ fclose( $out );
+ print "Wrote out UtfNormalData.inc\n";
+} else {
+ print "Can't create file UtfNormalData.inc\n";
+ exit(-1);
+}
+
+
+$out = fopen("UtfNormalDataK.inc", "wt");
+if( $out ) {
+ $serCompat = escapeSingleString( serialize( $compatibilityDecomp ) );
+ $outdata = "<" . "?php
+/**
+ * This file was automatically generated -- do not edit!
+ * Run UtfNormalGenerate.php to create this file again (make clean && make)
+ * @package MediaWiki
+ */
+/** */
+global \$utfCompatibilityDecomp;
+\$utfCompatibilityDecomp = unserialize( '$serCompat' );
+?" . ">\n";
+ fputs( $out, $outdata );
+ fclose( $out );
+ print "Wrote out UtfNormalDataK.inc\n";
+ exit(0);
+} else {
+ print "Can't create file UtfNormalDataK.inc\n";
+ exit(-1);
+}
+
+# ---------------
+
+function callbackCanonical( $matches ) {
+ global $canonicalDecomp;
+ if( isset( $canonicalDecomp[$matches[1]] ) ) {
+ return $canonicalDecomp[$matches[1]];
+ }
+ return $matches[1];
+}
+
+function callbackCompat( $matches ) {
+ global $compatibilityDecomp;
+ if( isset( $compatibilityDecomp[$matches[1]] ) ) {
+ return $compatibilityDecomp[$matches[1]];
+ }
+ return $matches[1];
+}
+
+?>
diff --git a/includes/normal/UtfNormalTest.php b/includes/normal/UtfNormalTest.php
new file mode 100644
index 000000000000..1181b6331567
--- /dev/null
+++ b/includes/normal/UtfNormalTest.php
@@ -0,0 +1,249 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Implements the conformance test at:
+ * http://www.unicode.org/Public/UNIDATA/NormalizationTest.txt
+ * @package UtfNormal
+ */
+
+/** */
+$verbose = true;
+#define( 'PRETTY_UTF8', true );
+
+if( defined( 'PRETTY_UTF8' ) ) {
+ function pretty( $string ) {
+ return preg_replace( '/([\x00-\xff])/e',
+ 'sprintf("%02X", ord("$1"))',
+ $string );
+ }
+} else {
+ /**
+ * @ignore
+ */
+ function pretty( $string ) {
+ return trim( preg_replace( '/(.)/use',
+ 'sprintf("%04X ", utf8ToCodepoint("$1"))',
+ $string ) );
+ }
+}
+
+if( isset( $_SERVER['argv'] ) && in_array( '--icu', $_SERVER['argv'] ) ) {
+ dl( 'php_utfnormal.so' );
+}
+
+require_once 'UtfNormalUtil.php';
+require_once 'UtfNormal.php';
+
+if( php_sapi_name() != 'cli' ) {
+ die( "Run me from the command line please.\n" );
+}
+
+$in = fopen("NormalizationTest.txt", "rt");
+if( !$in ) {
+ print "Couldn't open NormalizationTest.txt -- can't run tests.\n";
+ print "If necessary, manually download this file. It can be obtained at\n";
+ print "http://www.unicode.org/Public/UNIDATA/NormalizationTest.txt";
+ exit(-1);
+}
+
+$normalizer = new UtfNormal;
+
+$total = 0;
+$success = 0;
+$failure = 0;
+$ok = true;
+$testedChars = array();
+while( false !== ( $line = fgets( $in ) ) ) {
+ list( $data, $comment ) = explode( '#', $line );
+ if( $data === '' ) continue;
+ $matches = array();
+ if( preg_match( '/@Part([\d])/', $data, $matches ) ) {
+ if( $matches[1] > 0 ) {
+ $ok = reportResults( $total, $success, $failure ) && $ok;
+ }
+ print "Part {$matches[1]}: $comment";
+ continue;
+ }
+
+ $columns = array_map( "hexSequenceToUtf8", explode( ";", $data ) );
+ array_unshift( $columns, '' );
+
+ $testedChars[$columns[1]] = true;
+ $total++;
+ if( testNormals( $normalizer, $columns, $comment ) ) {
+ $success++;
+ } else {
+ $failure++;
+ # print "FAILED: $comment";
+ }
+ if( $total % 100 == 0 ) print "$total ";
+}
+fclose( $in );
+
+$ok = reportResults( $total, $success, $failure ) && $ok;
+
+$in = fopen("UnicodeData.txt", "rt" );
+if( !$in ) {
+ print "Can't open UnicodeData.txt for reading.\n";
+ print "If necessary, fetch this file from the internet:\n";
+ print "http://www.unicode.org/Public/UNIDATA/UnicodeData.txt\n";
+ exit(-1);
+}
+print "Now testing invariants...\n";
+while( false !== ($line = fgets( $in ) ) ) {
+ $cols = explode( ';', $line );
+ $char = codepointToUtf8( hexdec( $cols[0] ) );
+ $desc = $cols[0] . ": " . $cols[1];
+ if( $char < "\x20" || $char >= UTF8_SURROGATE_FIRST && $char <= UTF8_SURROGATE_LAST ) {
+ # Can't check NULL with the ICU plugin, as null bytes fail in C land.
+ # Skip other control characters, as we strip them for XML safety.
+ # Surrogates are illegal on their own or in UTF-8, ignore.
+ continue;
+ }
+ if( empty( $testedChars[$char] ) ) {
+ $total++;
+ if( testInvariant( $normalizer, $char, $desc ) ) {
+ $success++;
+ } else {
+ $failure++;
+ }
+ if( $total % 100 == 0 ) print "$total ";
+ }
+}
+fclose( $in );
+
+$ok = reportResults( $total, $success, $failure ) && $ok;
+
+if( $ok ) {
+ print "TEST SUCCEEDED!\n";
+ exit(0);
+} else {
+ print "TEST FAILED!\n";
+ exit(-1);
+}
+
+## ------
+
+function reportResults( &$total, &$success, &$failure ) {
+ $percSucc = intval( $success * 100 / $total );
+ $percFail = intval( $failure * 100 / $total );
+ print "\n";
+ print "$success tests successful ($percSucc%)\n";
+ print "$failure tests failed ($percFail%)\n\n";
+ $ok = ($success > 0 && $failure == 0);
+ $total = 0;
+ $success = 0;
+ $failure = 0;
+ return $ok;
+}
+
+function testNormals( &$u, $c, $comment, $reportFailure = false ) {
+ $result = testNFC( $u, $c, $comment, $reportFailure );
+ $result = testNFD( $u, $c, $comment, $reportFailure ) && $result;
+ $result = testNFKC( $u, $c, $comment, $reportFailure ) && $result;
+ $result = testNFKD( $u, $c, $comment, $reportFailure ) && $result;
+ $result = testCleanUp( $u, $c, $comment, $reportFailure ) && $result;
+
+ global $verbose;
+ if( $verbose && !$result && !$reportFailure ) {
+ print $comment;
+ testNormals( $u, $c, $comment, true );
+ }
+ return $result;
+}
+
+function verbosify( $a, $b, $col, $form, $verbose ) {
+ #$result = ($a === $b);
+ $result = (strcmp( $a, $b ) == 0);
+ if( $verbose ) {
+ $aa = pretty( $a );
+ $bb = pretty( $b );
+ $ok = $result ? "succeed" : " failed";
+ $eq = $result ? "==" : "!=";
+ print " $ok $form c$col '$aa' $eq '$bb'\n";
+ }
+ return $result;
+}
+
+function testNFC( &$u, $c, $comment, $verbose ) {
+ $result = verbosify( $c[2], $u->toNFC( $c[1] ), 1, 'NFC', $verbose );
+ $result = verbosify( $c[2], $u->toNFC( $c[2] ), 2, 'NFC', $verbose ) && $result;
+ $result = verbosify( $c[2], $u->toNFC( $c[3] ), 3, 'NFC', $verbose ) && $result;
+ $result = verbosify( $c[4], $u->toNFC( $c[4] ), 4, 'NFC', $verbose ) && $result;
+ $result = verbosify( $c[4], $u->toNFC( $c[5] ), 5, 'NFC', $verbose ) && $result;
+ return $result;
+}
+
+function testCleanUp( &$u, $c, $comment, $verbose ) {
+ $x = $c[1];
+ $result = verbosify( $c[2], $u->cleanUp( $x ), 1, 'cleanUp', $verbose );
+ $x = $c[2];
+ $result = verbosify( $c[2], $u->cleanUp( $x ), 2, 'cleanUp', $verbose ) && $result;
+ $x = $c[3];
+ $result = verbosify( $c[2], $u->cleanUp( $x ), 3, 'cleanUp', $verbose ) && $result;
+ $x = $c[4];
+ $result = verbosify( $c[4], $u->cleanUp( $x ), 4, 'cleanUp', $verbose ) && $result;
+ $x = $c[5];
+ $result = verbosify( $c[4], $u->cleanUp( $x ), 5, 'cleanUp', $verbose ) && $result;
+ return $result;
+}
+
+function testNFD( &$u, $c, $comment, $verbose ) {
+ $result = verbosify( $c[3], $u->toNFD( $c[1] ), 1, 'NFD', $verbose );
+ $result = verbosify( $c[3], $u->toNFD( $c[2] ), 2, 'NFD', $verbose ) && $result;
+ $result = verbosify( $c[3], $u->toNFD( $c[3] ), 3, 'NFD', $verbose ) && $result;
+ $result = verbosify( $c[5], $u->toNFD( $c[4] ), 4, 'NFD', $verbose ) && $result;
+ $result = verbosify( $c[5], $u->toNFD( $c[5] ), 5, 'NFD', $verbose ) && $result;
+ return $result;
+}
+
+function testNFKC( &$u, $c, $comment, $verbose ) {
+ $result = verbosify( $c[4], $u->toNFKC( $c[1] ), 1, 'NFKC', $verbose );
+ $result = verbosify( $c[4], $u->toNFKC( $c[2] ), 2, 'NFKC', $verbose ) && $result;
+ $result = verbosify( $c[4], $u->toNFKC( $c[3] ), 3, 'NFKC', $verbose ) && $result;
+ $result = verbosify( $c[4], $u->toNFKC( $c[4] ), 4, 'NFKC', $verbose ) && $result;
+ $result = verbosify( $c[4], $u->toNFKC( $c[5] ), 5, 'NFKC', $verbose ) && $result;
+ return $result;
+}
+
+function testNFKD( &$u, $c, $comment, $verbose ) {
+ $result = verbosify( $c[5], $u->toNFKD( $c[1] ), 1, 'NFKD', $verbose );
+ $result = verbosify( $c[5], $u->toNFKD( $c[2] ), 2, 'NFKD', $verbose ) && $result;
+ $result = verbosify( $c[5], $u->toNFKD( $c[3] ), 3, 'NFKD', $verbose ) && $result;
+ $result = verbosify( $c[5], $u->toNFKD( $c[4] ), 4, 'NFKD', $verbose ) && $result;
+ $result = verbosify( $c[5], $u->toNFKD( $c[5] ), 5, 'NFKD', $verbose ) && $result;
+ return $result;
+}
+
+function testInvariant( &$u, $char, $desc, $reportFailure = false ) {
+ $result = verbosify( $char, $u->toNFC( $char ), 1, 'NFC', $reportFailure );
+ $result = verbosify( $char, $u->toNFD( $char ), 1, 'NFD', $reportFailure ) && $result;
+ $result = verbosify( $char, $u->toNFKC( $char ), 1, 'NFKC', $reportFailure ) && $result;
+ $result = verbosify( $char, $u->toNFKD( $char ), 1, 'NFKD', $reportFailure ) && $result;
+ $result = verbosify( $char, $u->cleanUp( $char ), 1, 'cleanUp', $reportFailure ) && $result;
+ global $verbose;
+ if( $verbose && !$result && !$reportFailure ) {
+ print $desc;
+ testInvariant( $u, $char, $desc, true );
+ }
+ return $result;
+}
+
+?>
diff --git a/includes/normal/UtfNormalUtil.php b/includes/normal/UtfNormalUtil.php
new file mode 100644
index 000000000000..94224e3db87d
--- /dev/null
+++ b/includes/normal/UtfNormalUtil.php
@@ -0,0 +1,142 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Some of these functions are adapted from places in MediaWiki.
+ * Should probably merge them for consistency.
+ *
+ * @package UtfNormal
+ * @public
+ */
+
+/** */
+
+/**
+ * Return UTF-8 sequence for a given Unicode code point.
+ * May die if fed out of range data.
+ *
+ * @param $codepoint Integer:
+ * @return String
+ * @public
+ */
+function codepointToUtf8( $codepoint ) {
+ if($codepoint < 0x80) return chr($codepoint);
+ if($codepoint < 0x800) return chr($codepoint >> 6 & 0x3f | 0xc0) .
+ chr($codepoint & 0x3f | 0x80);
+ if($codepoint < 0x10000) return chr($codepoint >> 12 & 0x0f | 0xe0) .
+ chr($codepoint >> 6 & 0x3f | 0x80) .
+ chr($codepoint & 0x3f | 0x80);
+ if($codepoint < 0x110000) return chr($codepoint >> 18 & 0x07 | 0xf0) .
+ chr($codepoint >> 12 & 0x3f | 0x80) .
+ chr($codepoint >> 6 & 0x3f | 0x80) .
+ chr($codepoint & 0x3f | 0x80);
+
+ echo "Asked for code outside of range ($codepoint)\n";
+ die( -1 );
+}
+
+/**
+ * Take a series of space-separated hexadecimal numbers representing
+ * Unicode code points and return a UTF-8 string composed of those
+ * characters. Used by UTF-8 data generation and testing routines.
+ *
+ * @param $sequence String
+ * @return String
+ * @private
+ */
+function hexSequenceToUtf8( $sequence ) {
+ $utf = '';
+ foreach( explode( ' ', $sequence ) as $hex ) {
+ $n = hexdec( $hex );
+ $utf .= codepointToUtf8( $n );
+ }
+ return $utf;
+}
+
+/**
+ * Take a UTF-8 string and return a space-separated series of hex
+ * numbers representing Unicode code points. For debugging.
+ *
+ * @param $str String: UTF-8 string.
+ * @return string
+ * @private
+ */
+function utf8ToHexSequence( $str ) {
+ return rtrim( preg_replace( '/(.)/uSe',
+ 'sprintf("%04x ", utf8ToCodepoint("$1"))',
+ $str ) );
+}
+
+/**
+ * Determine the Unicode codepoint of a single-character UTF-8 sequence.
+ * Does not check for invalid input data.
+ *
+ * @param $char String
+ * @return Integer
+ * @public
+ */
+function utf8ToCodepoint( $char ) {
+ # Find the length
+ $z = ord( $char{0} );
+ if ( $z & 0x80 ) {
+ $length = 0;
+ while ( $z & 0x80 ) {
+ $length++;
+ $z <<= 1;
+ }
+ } else {
+ $length = 1;
+ }
+
+ if ( $length != strlen( $char ) ) {
+ return false;
+ }
+ if ( $length == 1 ) {
+ return ord( $char );
+ }
+
+ # Mask off the length-determining bits and shift back to the original location
+ $z &= 0xff;
+ $z >>= $length;
+
+ # Add in the free bits from subsequent bytes
+ for ( $i=1; $i<$length; $i++ ) {
+ $z <<= 6;
+ $z |= ord( $char{$i} ) & 0x3f;
+ }
+
+ return $z;
+}
+
+/**
+ * Escape a string for inclusion in a PHP single-quoted string literal.
+ *
+ * @param $string String: string to be escaped.
+ * @return String: escaped string.
+ * @public
+ */
+function escapeSingleString( $string ) {
+ return strtr( $string,
+ array(
+ '\\' => '\\\\',
+ '\'' => '\\\''
+ ));
+}
+
+?>
diff --git a/includes/proxy_check.php b/includes/proxy_check.php
new file mode 100644
index 000000000000..fb7fdb509157
--- /dev/null
+++ b/includes/proxy_check.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Command line script to check for an open proxy at a specified location
+ * @package MediaWiki
+ */
+
+if( php_sapi_name() != 'cli' ) {
+ die( 1 );
+}
+
+/**
+ *
+ */
+$output = '';
+
+/**
+ * Exit if there are not enough parameters, or if it's not command line mode
+ */
+if ( ( isset( $_REQUEST ) && array_key_exists( 'argv', $_REQUEST ) ) || count( $argv ) < 4 ) {
+ $output .= "Incorrect parameters\n";
+} else {
+ /**
+ * Get parameters
+ */
+ $ip = $argv[1];
+ $port = $argv[2];
+ $url = $argv[3];
+ $host = trim(`hostname`);
+ $output = "Connecting to $ip:$port, target $url, this hostname $host\n";
+
+ # Open socket
+ $sock = @fsockopen($ip, $port, $errno, $errstr, 5);
+ if ($errno == 0 ) {
+ $output .= "Connected\n";
+ # Send payload
+ $request = "GET $url HTTP/1.0\r\n";
+# $request .= "Proxy-Connection: Keep-Alive\r\n";
+# $request .= "Pragma: no-cache\r\n";
+# $request .= "Host: ".$url."\r\n";
+# $request .= "User-Agent: MediaWiki open proxy check\r\n";
+ $request .= "\r\n";
+ @fputs($sock, $request);
+ $response = fgets($sock, 65536);
+ $output .= $response;
+ @fclose($sock);
+ } else {
+ $output .= "No connection\n";
+ }
+}
+
+$output = escapeshellarg( $output );
+
+#`echo $output >> /home/tstarling/open/proxy.log`;
+
+?>
diff --git a/includes/templates/NoLocalSettings.php b/includes/templates/NoLocalSettings.php
new file mode 100644
index 000000000000..e71dd396fa59
--- /dev/null
+++ b/includes/templates/NoLocalSettings.php
@@ -0,0 +1,48 @@
+<?php
+# Prevent XSS
+if ( isset( $wgVersion ) ) {
+ $wgVersion = htmlspecialchars( $wgVersion );
+} else {
+ $wgVersion = 'VERSION';
+}
+# Set the path in case we hit a page such as /index.php/Main_Page
+# Could use <base href> but then we have to worry about http[s]/port #/etc.
+$path = '';
+if( isset( $_SERVER['SCRIPT_NAME'] )) {
+ $path = htmlspecialchars( preg_replace('/index.php/', '', $_SERVER['SCRIPT_NAME']) );
+}
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
+ <head>
+ <title>MediaWiki <?php echo $wgVersion ?></title>
+ <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
+ <style type='text/css' media='screen, projection'>
+ html, body {
+ color: #000;
+ background-color: #fff;
+ font-family: sans-serif;
+ text-align: center;
+ }
+
+ h1 {
+ font-size: 150%;
+ }
+ </style>
+ </head>
+ <body>
+ <img src="<?php echo $path ?>skins/common/images/mediawiki.png" alt='The MediaWiki logo' />
+
+ <h1>MediaWiki <?php echo $wgVersion ?></h1>
+ <div class='error'>
+ <?php
+ if ( file_exists( 'config/LocalSettings.php' ) ) {
+ echo( 'To complete the installation, move <tt>config/LocalSettings.php</tt> to the parent directory.' );
+ } else {
+ echo( "Please <a href=\"${path}config/index.php\" title='setup'> set up the wiki</a> first." );
+ }
+ ?>
+
+ </div>
+ </body>
+</html>
diff --git a/includes/templates/Userlogin.php b/includes/templates/Userlogin.php
new file mode 100644
index 000000000000..953fbd471390
--- /dev/null
+++ b/includes/templates/Userlogin.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Templates
+ */
+if( !defined( 'MEDIAWIKI' ) ) die( -1 );
+
+/** */
+require_once( 'includes/SkinTemplate.php' );
+
+/**
+ * HTML template for Special:Userlogin form
+ * @package MediaWiki
+ * @subpackage Templates
+ */
+class UserloginTemplate extends QuickTemplate {
+ function execute() {
+ if( $this->data['message'] ) {
+?>
+ <div class="<?php $this->text('messagetype') ?>box">
+ <?php if ( $this->data['messagetype'] == 'error' ) { ?>
+ <h2><?php $this->msg('loginerror') ?>:</h2>
+ <?php } ?>
+ <?php $this->html('message') ?>
+ </div>
+ <div class="visualClear"></div>
+<?php } ?>
+
+<div id="userloginForm">
+<form name="userlogin" method="post" action="<?php $this->text('action') ?>">
+ <h2><?php $this->msg('login') ?></h2>
+ <p id="userloginlink"><?php $this->html('link') ?></p>
+ <div id="userloginprompt"><?php $this->msgWiki('loginprompt') ?></div>
+ <?php if( @$this->haveData( 'languages' ) ) { ?><div id="languagelinks"><p><?php $this->html( 'languages' ); ?></p></div><?php } ?>
+ <table>
+ <tr>
+ <td align='right'><label for='wpName1'><?php $this->msg('yourname') ?>:</label></td>
+ <td align='left'>
+ <input type='text' class='loginText' name="wpName" id="wpName1"
+ tabindex="1"
+ value="<?php $this->text('name') ?>" size='20' />
+ </td>
+ </tr>
+ <tr>
+ <td align='right'><label for='wpPassword1'><?php $this->msg('yourpassword') ?>:</label></td>
+ <td align='left'>
+ <input type='password' class='loginPassword' name="wpPassword" id="wpPassword1"
+ tabindex="2"
+ value="<?php $this->text('password') ?>" size='20' />
+ </td>
+ </tr>
+ <?php if( $this->data['usedomain'] ) {
+ $doms = "";
+ foreach( $this->data['domainnames'] as $dom ) {
+ $doms .= "<option>" . htmlspecialchars( $dom ) . "</option>";
+ }
+ ?>
+ <tr>
+ <td align='right'><?php $this->msg( 'yourdomainname' ) ?>:</td>
+ <td align='left'>
+ <select name="wpDomain" value="<?php $this->text( 'domain' ) ?>"
+ tabindex="3">
+ <?php echo $doms ?>
+ </select>
+ </td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <td></td>
+ <td align='left'>
+ <input type='checkbox' name="wpRemember"
+ tabindex="4"
+ value="1" id="wpRemember"
+ <?php if( $this->data['remember'] ) { ?>checked="checked"<?php } ?>
+ /> <label for="wpRemember"><?php $this->msg('remembermypassword') ?></label>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td align='left' style="white-space:nowrap">
+ <input type='submit' name="wpLoginattempt" id="wpLoginattempt" tabindex="5" value="<?php $this->msg('login') ?>" />&nbsp;<?php if( $this->data['useemail'] && $this->data['canreset']) { ?><input type='submit' name="wpMailmypassword" id="wpMailmypassword"
+ tabindex="6"
+ value="<?php $this->msg('mailmypassword') ?>" />
+ <?php } ?>
+ </td>
+ </tr>
+ </table>
+<?php if( @$this->haveData( 'uselang' ) ) { ?><input type="hidden" name="uselang" value="<?php $this->text( 'uselang' ); ?>" /><?php } ?>
+</form>
+</div>
+<div id="loginend"><?php $this->msgWiki( 'loginend' ); ?></div>
+<?php
+
+ }
+}
+
+class UsercreateTemplate extends QuickTemplate {
+ function execute() {
+ if( $this->data['message'] ) {
+?>
+ <div class="<?php $this->text('messagetype') ?>box">
+ <?php if ( $this->data['messagetype'] == 'error' ) { ?>
+ <h2><?php $this->msg('loginerror') ?>:</h2>
+ <?php } ?>
+ <?php $this->html('message') ?>
+ </div>
+ <div class="visualClear"></div>
+<?php } ?>
+<div id="userlogin">
+
+<form name="userlogin2" id="userlogin2" method="post" action="<?php $this->text('action') ?>">
+ <h2><?php $this->msg('createaccount') ?></h2>
+ <p id="userloginlink"><?php $this->html('link') ?></p>
+ <?php $this->html('header'); /* pre-table point for form plugins... */ ?>
+ <?php if( @$this->haveData( 'languages' ) ) { ?><div id="languagelinks"><p><?php $this->html( 'languages' ); ?></p></div><?php } ?>
+ <table>
+ <tr>
+ <td align='right'><label for='wpName2'><?php $this->msg('yourname') ?>:</label></td>
+ <td align='left'>
+ <input type='text' class='loginText' name="wpName" id="wpName2"
+ tabindex="1"
+ value="<?php $this->text('name') ?>" size='20' />
+ </td>
+ </tr>
+ <tr>
+ <td align='right'><label for='wpPassword2'><?php $this->msg('yourpassword') ?>:</label></td>
+ <td align='left'>
+ <input type='password' class='loginPassword' name="wpPassword" id="wpPassword2"
+ tabindex="2"
+ value="<?php $this->text('password') ?>" size='20' />
+ </td>
+ </tr>
+ <?php if( $this->data['usedomain'] ) {
+ $doms = "";
+ foreach( $this->data['domainnames'] as $dom ) {
+ $doms .= "<option>" . htmlspecialchars( $dom ) . "</option>";
+ }
+ ?>
+ <tr>
+ <td align='right'><?php $this->msg( 'yourdomainname' ) ?>:</td>
+ <td align='left'>
+ <select name="wpDomain" value="<?php $this->text( 'domain' ) ?>"
+ tabindex="3">
+ <?php echo $doms ?>
+ </select>
+ </td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <td align='right'><label for='wpRetype'><?php $this->msg('yourpasswordagain') ?>:</label></td>
+ <td align='left'>
+ <input type='password' class='loginPassword' name="wpRetype" id="wpRetype"
+ tabindex="4"
+ value="<?php $this->text('retype') ?>"
+ size='20' />
+ </td>
+ </tr>
+ <tr>
+ <?php if( $this->data['useemail'] ) { ?>
+ <td align='right'><label for='wpEmail'><?php $this->msg('youremail') ?></label></td>
+ <td align='left'>
+ <input type='text' class='loginText' name="wpEmail" id="wpEmail"
+ tabindex="5"
+ value="<?php $this->text('email') ?>" size='20' />
+ </td>
+ <?php } ?>
+ <?php if( $this->data['userealname'] ) { ?>
+ </tr>
+ <tr>
+ <td align='right'><label for='wpRealName'><?php $this->msg('yourrealname') ?></label></td>
+ <td align='left'>
+ <input type='text' class='loginText' name="wpRealName" id="wpRealName"
+ tabindex="6"
+ value="<?php $this->text('realname') ?>" size='20' />
+ </td>
+ <?php } ?>
+ </tr>
+ <tr>
+ <td></td>
+ <td align='left'>
+ <input type='checkbox' name="wpRemember"
+ tabindex="7"
+ value="1" id="wpRemember"
+ <?php if( $this->data['remember'] ) { ?>checked="checked"<?php } ?>
+ /> <label for="wpRemember"><?php $this->msg('remembermypassword') ?></label>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td align='left'>
+ <input type='submit' name="wpCreateaccount" id="wpCreateaccount"
+ tabindex="8"
+ value="<?php $this->msg('createaccount') ?>" />
+ <?php if( $this->data['createemail'] ) { ?>
+ <input type='submit' name="wpCreateaccountMail" id="wpCreateaccountMail"
+ tabindex="9"
+ value="<?php $this->msg('createaccountmail') ?>" />
+ <?php } ?>
+ </td>
+ </tr>
+ </table>
+ <?php
+
+ if ($this->data['userealname'] || $this->data['useemail']) {
+ echo '<div id="login-sectiontip">';
+ if ( $this->data['useemail'] ) {
+ echo '<div>';
+ $this->msgHtml('prefs-help-email');
+ echo '</div>';
+ }
+ if ( $this->data['userealname'] ) {
+ echo '<div>';
+ $this->msgHtml('prefs-help-realname');
+ echo '</div>';
+ }
+ echo '</div>';
+ }
+
+ ?>
+<?php if( @$this->haveData( 'uselang' ) ) { ?><input type="hidden" name="uselang" value="<?php $this->text( 'uselang' ); ?>" /><?php } ?>
+</form>
+</div>
+<div id="signupend"><?php $this->msgWiki( 'signupend' ); ?></div>
+<?php
+
+ }
+}
+
+?>
diff --git a/includes/zhtable/Makefile b/includes/zhtable/Makefile
new file mode 100644
index 000000000000..30679fbbc038
--- /dev/null
+++ b/includes/zhtable/Makefile
@@ -0,0 +1,268 @@
+#
+# Creating the file ZhConversion.php used for Simplified/Traditional
+# Chinese conversion. It gets the basic conversion table from the Unihan
+# database, and construct the phrase tables using phrase libraries in
+# the SCIM packages and the libtabe package. There are also special
+# tables used to for adjustment.
+#
+
+GREP = LANG=zh_CN.UTF8 grep
+SED = LANG=zh_CN.UTF8 sed
+DIFF = LANG=zh_CN.UTF8 diff
+CC ?= gcc
+
+#installation directory
+INSTDIR = /usr/local/share/zhdaemons/
+
+all: ZhConversion.php tradphrases.notsure simpphrases.notsure wordlist toCN.dict toTW.dict toHK.dict toSG.dict
+
+Unihan.txt:
+ wget -nc ftp://ftp.unicode.org/Public/UNIDATA/Unihan.zip
+ unzip -q Unihan.zip
+
+EZ.txt.in:
+ wget -nc http://easynews.dl.sourceforge.net/sourceforge/scim/scim-tables-0.5.1.tar.gz
+ tar -xzf scim-tables-0.5.1.tar.gz -O scim-tables-0.5.1/zh/EZ.txt.in > EZ.txt.in
+
+phrase_lib.txt:
+ wget -nc http://easynews.dl.sourceforge.net/sourceforge/scim/scim-pinyin-0.5.0.tar.gz
+ tar -xzf scim-pinyin-0.5.0.tar.gz -O scim-pinyin-0.5.0/data/phrase_lib.txt > phrase_lib.txt
+
+tsi.src:
+ wget -nc http://unc.dl.sourceforge.net/sourceforge/libtabe/libtabe-0.2.3.tgz
+ tar -xzf libtabe-0.2.3.tgz -O libtabe/tsi-src/tsi.src > tsi.src
+
+wordlist: phrase_lib.txt EZ.txt.in tsi.src
+ iconv -c -f big5 -t utf8 tsi.src | $(SED) 's/# //g' | $(SED) 's/[ ][0-9].*//' > wordlist
+ $(SED) 's/\(.*\)\t[0-9][0-9]*.*/\1/' phrase_lib.txt | $(SED) '1,5d' >>wordlist
+ $(SED) '1,/BEGIN_TABLE/d' EZ.txt.in | colrm 1 8 | $(SED) 's/\t.*//' | $(GREP) "^...*" >> wordlist
+ sort wordlist | uniq | $(SED) 's/ //g' > t
+ mv t wordlist
+
+printutf8: printutf8.c
+ $(CC) -o printutf8 printutf8.c
+
+unihan.t2s.t: Unihan.txt printutf8
+ $(GREP) kSimplifiedVariant Unihan.txt | $(SED) '/#/d' | $(SED) 's/kSimplifiedVariant//' | ./printutf8 > unihan.t2s.t
+
+trad2simp.t: trad2simp.manual unihan.t2s.t
+ cp unihan.t2s.t tmp1
+ for I in `colrm 11 < trad2simp.manual` ; do $(SED) "/^$$I/d" tmp1 > tmp2; mv tmp2 tmp1; done
+ cat trad2simp.manual tmp1 > trad2simp.t
+
+unihan.s2t.t: Unihan.txt printutf8
+ $(GREP) kTraditionalVariant Unihan.txt | $(SED) '/#/d' | $(SED) 's/kTraditionalVariant//' | ./printutf8 > unihan.s2t.t
+
+simp2trad.t: unihan.s2t.t simp2trad.manual
+ cp unihan.s2t.t tmp1
+ for I in `colrm 11 < simp2trad.manual` ; do $(SED) "/^$$I/d" tmp1 > tmp2; mv tmp2 tmp1; done
+ cat simp2trad.manual tmp1 > simp2trad.t
+
+t2s_1tomany.t: trad2simp.t
+ $(GREP) -s ".\{19,\}" trad2simp.t | $(SED) 's/U+...../"/' | $(SED) 's/|U+...../"=>"/' | $(SED) 's/|U+.....//g' | $(SED) 's/|/",/' > t2s_1tomany.t
+
+t2s_1to1.t: trad2simp.t s2t_1tomany.t
+ $(SED) "/.*|.*|.*|.*/d" trad2simp.t | $(SED) 's/U+[0-9a-z][0-9a-z]*/"/' | $(SED) 's/|U+[0-9a-z][0-9a-z]*/"=>"/' | $(SED) 's/|/",/' > t2s_1to1.t
+ $(GREP) '"."=>"..",' s2t_1tomany.t | $(SED) 's/\("."\)=>".\(.\)",/"\2"=>\1,/' >> t2s_1to1.t
+ $(GREP) '"."=>"...",' s2t_1tomany.t | $(SED) 's/\("."\)=>".\(.\).",/"\2"=>\1,/' >> t2s_1to1.t
+ $(GREP) '"."=>"...",' s2t_1tomany.t | $(SED) 's/\("."\)=>"..\(.\)",/"\2"=>\1,/' >> t2s_1to1.t
+ $(GREP) '"."=>"....",' s2t_1tomany.t | $(SED) 's/\("."\)=>".\(.\)..",/"\2"=>\1,/' >> t2s_1to1.t
+ $(GREP) '"."=>"....",' s2t_1tomany.t | $(SED) 's/\("."\)=>"..\(.\).",/"\2"=>\1,/' >> t2s_1to1.t
+ $(GREP) '"."=>"....",' s2t_1tomany.t | $(SED) 's/\("."\)=>"...\(.\)",/"\2"=>\1,/' >> t2s_1to1.t
+ sort t2s_1to1.t | uniq > t
+ mv t t2s_1to1.t
+
+
+s2t_1tomany.t: simp2trad.t
+ $(GREP) -s ".\{19,\}" simp2trad.t | $(SED) 's/U+...../"/' | $(SED) 's/|U+...../"=>"/' | $(SED) 's/|U+.....//g' | $(SED) 's/|/",/' > s2t_1tomany.t
+
+s2t_1to1.t: simp2trad.t t2s_1tomany.t
+ $(SED) "/.*|.*|.*|.*/d" simp2trad.t | $(SED) 's/U+[0-9a-z][0-9a-z]*/"/' | $(SED) 's/|U+[0-9a-z][0-9a-z]*/"=>"/' | $(SED) 's/|/",/' > s2t_1to1.t
+ $(GREP) '"."=>"..",' t2s_1tomany.t | $(SED) 's/\("."\)=>".\(.\)",/"\2"=>\1,/' >> s2t_1to1.t
+ $(GREP) '"."=>"...",' t2s_1tomany.t | $(SED) 's/\("."\)=>".\(.\).",/"\2"=>\1,/' >> s2t_1to1.t
+ $(GREP) '"."=>"...",' t2s_1tomany.t | $(SED) 's/\("."\)=>"..\(.\)",/"\2"=>\1,/' >> s2t_1to1.t
+ $(GREP) '"."=>"....",' t2s_1tomany.t | $(SED) 's/\("."\)=>".\(.\)..",/"\2"=>\1,/' >> s2t_1to1.t
+ $(GREP) '"."=>"....",' t2s_1tomany.t | $(SED) 's/\("."\)=>"..\(.\).",/"\2"=>\1,/' >> s2t_1to1.t
+ $(GREP) '"."=>"....",' t2s_1tomany.t | $(SED) 's/\("."\)=>"...\(.\)",/"\2"=>\1,/' >> s2t_1to1.t
+ sort s2t_1to1.t | uniq > t
+ mv t s2t_1to1.t
+
+tphrase.t: EZ.txt.in tsi.src
+ colrm 1 8 < EZ.txt.in | $(SED) 's/\t//g' | $(GREP) "^.\{2,4\}[0-9]" | $(SED) 's/[0-9]//g' > t
+ iconv -c -f big5 -t utf8 tsi.src | $(SED) 's/ [0-9].*//g' | $(SED) 's/[# ]//g'| $(GREP) "^.\{2,4\}" >> t
+ sort t | uniq > tphrase.t
+
+alltradphrases.t: tphrase.t s2t_1tomany.t
+ for i in `cat s2t_1tomany.t | $(SED) 's/.*=>".//' | $(SED) 's/"//g' |$(SED) 's/,/\n/' | $(SED) 's/\(.\)/\1\n/g' |sort | uniq`; do $(GREP) -s $$i tphrase.t ; done > alltradphrases.t || true
+
+
+tradphrases_2.t: alltradphrases.t
+ cat alltradphrases.t | $(GREP) "^..$$" | sort | uniq > tradphrases_2.t
+
+tradphrases_3.t: alltradphrases.t
+ cat alltradphrases.t | $(GREP) "^...$$" | sort | uniq > tradphrases_3.t
+ for i in `cat tradphrases_2.t`; do $(GREP) $$i tradphrases_3.t ; done | sort | uniq > t3 || true
+ $(DIFF) t3 tradphrases_3.t | $(GREP) ">" | $(SED) 's/> //' > t
+ mv t tradphrases_3.t
+
+
+tradphrases_4.t: alltradphrases.t
+ cat alltradphrases.t | $(GREP) "^....$$" | sort | uniq > tradphrases_4.t
+ for i in `cat tradphrases_2.t`; do $(GREP) $$i tradphrases_4.t ; done | sort | uniq > t3 || true
+ $(DIFF) t3 tradphrases_4.t | $(GREP) ">" | $(SED) 's/> //' > t
+ mv t tradphrases_4.t
+ for i in `cat tradphrases_3.t`; do $(GREP) $$i tradphrases_4.t ; done | sort | uniq > t3 || true
+ $(DIFF) t3 tradphrases_4.t | $(GREP) ">" | $(SED) 's/> //' > t
+ mv t tradphrases_4.t
+
+tradphrases.t: tradphrases.manual tradphrases_2.t tradphrases_3.t tradphrases_4.t t2s_1tomany.t
+ cat tradphrases.manual tradphrases_2.t tradphrases_3.t tradphrases_4.t |sort | uniq > tradphrases.t
+ for i in `$(SED) 's/"\(.\).*/\1/' t2s_1tomany.t ` ; do $(GREP) $$i tradphrases.t ; done | $(DIFF) tradphrases.t - | $(GREP) '<' | $(SED) 's/< //' > t
+ mv t tradphrases.t
+
+tradphrases.notsure: tradphrases_2.t tradphrases_3.t tradphrases_4.t t2s_1tomany.t
+ cat tradphrases_2.t tradphrases_3.t tradphrases_4.t |sort | uniq > t
+ for i in `$(SED) 's/"\(.\).*/\1/' t2s_1tomany.t ` ; do $(GREP) $$i t; done | $(DIFF) t - | $(GREP) '>' | $(SED) 's/> //' > tradphrases.notsure
+
+
+ph.t: phrase_lib.txt
+ $(SED) 's/[\t0-9a-zA-Z]//g' phrase_lib.txt | $(GREP) "^.\{2,4\}$$" > ph.t
+
+allsimpphrases.t: ph.t
+ rm -f allsimpphrases.t
+ for i in `cat t2s_1tomany.t | $(SED) 's/.*=>".//' | $(SED) 's/"//g' | $(SED) 's/,/\n/' | $(SED) 's/\(.\)/\1\n/g' | sort | uniq `; do $(GREP) $$i ph.t >> allsimpphrases.t; done
+
+simpphrases_2.t: allsimpphrases.t
+ cat allsimpphrases.t | $(GREP) "^..$$" | sort | uniq > simpphrases_2.t
+
+simpphrases_3.t: allsimpphrases.t
+ cat allsimpphrases.t | $(GREP) "^...$$" | sort | uniq > simpphrases_3.t
+ for i in `cat simpphrases_2.t`; do $(GREP) $$i simpphrases_3.t ; done | sort | uniq > t3 || true
+ $(DIFF) t3 simpphrases_3.t | $(GREP) ">" | $(SED) 's/> //' > t
+ mv t simpphrases_3.t
+
+simpphrases_4.t: allsimpphrases.t
+ cat allsimpphrases.t | $(GREP) "^....$$" | sort | uniq > simpphrases_4.t
+ rm -f t
+ for i in `cat simpphrases_2.t`; do $(GREP) $$i simpphrases_4.t >> t; done || true
+ sort t | uniq > t3
+ $(DIFF) t3 simpphrases_4.t | $(GREP) ">" | $(SED) 's/> //' > t
+ mv t simpphrases_4.t
+ for i in `cat simpphrases_3.t`; do $(GREP) $$i simpphrases_4.t; done | sort | uniq > t3 || true
+ $(DIFF) t3 simpphrases_4.t | $(GREP) ">" | $(SED) 's/> //' > t
+ mv t simpphrases_4.t
+
+simpphrases.t:simpphrases_2.t simpphrases_3.t simpphrases_4.t t2s_1tomany.t
+ cat simpphrases_2.t simpphrases_3.t simpphrases_4.t > simpphrases.t
+ for i in `$(SED) 's/"\(.\).*/\1/' t2s_1tomany.t ` ; do $(GREP) $$i simpphrases.t ; done | $(DIFF) simpphrases.t - | $(GREP) '<' | $(SED) 's/< //' > t
+ mv t simpphrases.t
+
+
+simpphrases.notsure:simpphrases_2.t simpphrases_3.t simpphrases_4.t t2s_1tomany.t
+ cat simpphrases_2.t simpphrases_3.t simpphrases_4.t > t
+ for i in `$(SED) 's/"\(.\).*/\1/' t2s_1tomany.t ` ; do $(GREP) $$i t ; done | $(DIFF) t - | $(GREP) '>' | $(SED) 's/> //' > simpphrases.notsure
+
+trad2simp1to1.t: t2s_1tomany.t t2s_1to1.t
+ $(SED) 's/\(.......\).*/\1",/' t2s_1tomany.t > trad2simp1to1.t
+ cat t2s_1to1.t >> trad2simp1to1.t
+
+simp2trad1to1.t: s2t_1tomany.t s2t_1to1.t
+ $(SED) 's/\(.......\).*/\1",/' s2t_1tomany.t > simp2trad1to1.t
+ cat s2t_1to1.t >> simp2trad1to1.t
+
+trad2simp.php: trad2simp1to1.t tradphrases.t
+ printf '<?php\n$$trad2simp=array(' > trad2simp.php
+ cat trad2simp1to1.t >> trad2simp.php
+ printf ');\n$$str=\n"' >> trad2simp.php
+ cat tradphrases.t >> trad2simp.php
+ printf '";\n$$t=strtr($$str, $$trad2simp);\necho $$t;\n?>' >> trad2simp.php
+
+simp2trad.php: simp2trad1to1.t simpphrases.t
+ printf '<?php\n$$simp2trad=array(' > simp2trad.php
+ cat simp2trad1to1.t >> simp2trad.php
+ printf ');\n$$str=\n"' >> simp2trad.php
+ cat simpphrases.t >> simp2trad.php
+ printf '";\n$$t=strtr($$str, $$simp2trad);\necho $$t;\n?>' >> simp2trad.php
+
+simp2trad.phrases.t: trad2simp.php tradphrases.t toTW.manual
+ php -f trad2simp.php | $(SED) 's/\(.*\)/"\1" => /' > tmp1
+ cat tradphrases.t | $(SED) 's/\(.*\)/"\1",/' > tmp2
+ paste tmp1 tmp2 > simp2trad.phrases.t
+ $(SED) 's/\(.*\)\t\(.*\)/"\1"=>"\2",/' toTW.manual >> simp2trad.phrases.t
+
+trad2simp.phrases.t: simp2trad.php simpphrases.t toCN.manual
+ php -f simp2trad.php | $(SED) 's/\(.*\)/"\1" => /' > tmp1
+ cat simpphrases.t | $(SED) 's/\(.*\)/"\1",/' > tmp2
+ paste tmp1 tmp2 > trad2simp.phrases.t
+ $(SED) 's/\(.*\)\t\(.*\)/"\1"=>"\2",/' toCN.manual >> trad2simp.phrases.t
+
+toCN.dict: trad2simp1to1.t trad2simp.phrases.t
+ cat trad2simp1to1.t | $(SED) 's/[, \t]//g' | $(SED) 's/=>/\t/' > toCN.dict
+ cat trad2simp.phrases.t | $(SED) 's/[, \t]//g' | $(SED) 's/=>/\t/' >> toCN.dict
+
+toTW.dict: simp2trad1to1.t simp2trad.phrases.t
+ cat simp2trad1to1.t | $(SED) 's/[, \t]//g' | $(SED) 's/=>/\t/' > toTW.dict
+ cat simp2trad.phrases.t | $(SED) 's/[, \t]//g' | $(SED) 's/=>/\t/' >> toTW.dict
+
+toHK.dict: toHK.manual
+ cat toHK.manual | $(SED) 's/ //g' | $(SED) 's/\(^.*\)\t\(.*\)/"\1"\t"\2"/' > toHK.dict
+
+toSG.dict: toSG.manual
+ cat toSG.manual | $(SED) 's/ //g' | $(SED) 's/\(^.*\)\t\(.*\)/"\1"\t"\2"/' > toSG.dict
+
+
+
+ZhConversion.php: simp2trad1to1.t simp2trad.phrases.t trad2simp1to1.t trad2simp.phrases.t toHK.manual toSG.manual
+ printf '<?php\n/**\n * Simplified/Traditional Chinese conversion tables\n' > ZhConversion.php
+ printf ' *\n * Automatically generated using code and data in includes/zhtable/\n' >> ZhConversion.php
+ printf ' * Do not modify directly! \n *\n * @package MediaWiki\n*/\n\n' >> ZhConversion.php
+ printf '$$zh2TW=array(\n' >> ZhConversion.php
+ cat simp2trad1to1.t >> ZhConversion.php
+ echo >> ZhConversion.php
+ cat simp2trad.phrases.t >> ZhConversion.php
+ echo >> ZhConversion.php
+ echo ');' >> ZhConversion.php
+ echo >> ZhConversion.php
+ echo >> ZhConversion.php
+ printf '$$zh2CN=array(\n' >> ZhConversion.php
+ cat trad2simp1to1.t >> ZhConversion.php
+ echo >> ZhConversion.php
+ cat trad2simp.phrases.t >> ZhConversion.php
+ echo >> ZhConversion.php
+ printf ');' >> ZhConversion.php
+ echo >> ZhConversion.php
+ echo >> ZhConversion.php
+ printf '$$zh2HK=array(\n' >> ZhConversion.php
+ $(SED) 's/\(.*\)\t\(.*\)/"\1" => "\2",/' toHK.manual >> ZhConversion.php
+ echo >> ZhConversion.php
+ printf ');' >> ZhConversion.php
+ echo >> ZhConversion.php
+ echo >> ZhConversion.php
+ printf '$$zh2SG=array(\n' >> ZhConversion.php
+ $(SED) 's/\(.*\)\t\(.*\)/"\1" => "\2",/' toSG.manual >> ZhConversion.php
+ echo >> ZhConversion.php
+ printf ');' >> ZhConversion.php
+ echo >> ZhConversion.php
+ printf '?>' >> ZhConversion.php
+
+
+clean: cleantmp cleandl
+
+cleantmp:
+ # Stuff unpacked from the files fetched by wget
+ rm -f \
+ Unihan.txt \
+ EZ.txt.in \
+ phrase_lib.txt \
+ tsi.src
+ # Temporary files and other trash
+ rm -f ZhConversion.php tmp1 tmp2 tmp3 t3 *.t trad2simp.php simp2trad.php *.dict printutf8 *~ \
+ simpphrases.notsure tradphrases.notsure wordlist
+
+cleandl:
+ rm -f \
+ Unihan.zip \
+ scim-tables-0.5.1.tar.gz \
+ scim-pinyin-0.5.0.tar.gz \
+ libtabe-0.2.3.tgz
+
diff --git a/includes/zhtable/README b/includes/zhtable/README
new file mode 100644
index 000000000000..94dd341d7450
--- /dev/null
+++ b/includes/zhtable/README
@@ -0,0 +1,16 @@
+The various .manual files contains special mappings not included in the
+unihan database, and phrases not included in the SCIM package.
+
+- simp2trad.manual: Simplified to Traditional character mapping. Most
+ data adapted from
+
+ 冯寿忠,“非对称繁简字”对照表, 《语文建设通讯》1997-9第53期.
+ /http://www.yywzw.com/jt/feng/fengb01.htm
+
+- tradphrases.manual: Phrases in Traditional Chinese. A portition is obtained
+ from the TongWen package (http://tongwen.mozdev.org/)
+
+- toTW.manual, toCN.manual, toSG.manual and toHK.manual: special phrase
+ mappings.
+
+zhengzhu at gmail.com \ No newline at end of file
diff --git a/includes/zhtable/printutf8.c b/includes/zhtable/printutf8.c
new file mode 100644
index 000000000000..b6ccf17cd337
--- /dev/null
+++ b/includes/zhtable/printutf8.c
@@ -0,0 +1,99 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+/*
+ Unicode UTF8
+0x00000000 - 0x0000007F: 0xxxxxxx
+0x00000080 - 0x000007FF: 110xxx xx 10xx xxxx
+0x00000800 - 0x0000FFFF: 1110xxxx 10xxxx xx 10xx xxxx
+0x00010000 - 0x001FFFFF: 11110x xx 10xx xxxx 10xxxx xx 10xx xxxx
+0x00200000 - 0x03FFFFFF: 111110xx 10xxxx xx 10xx xxxx 10xxxx xx 10xx xxxx
+0x04000000 - 0x7FFFFFFF: 1111110x 10xx xxxx 10xxxx xx 10xx xxxx 10xxxx xx 10xx xxxx
+
+0000 0 1001 9
+0001 1 1010 A
+0010 2 1011 B
+0011 3 1100 C
+0100 4 1101 D
+0101 5 1110 E
+0110 6 1111 F
+0111 7
+1000 8
+*/
+void printUTF8(long long u) {
+ long long m;
+ if(u<0x80) {
+ printf("%c", (unsigned char)u);
+ }
+ else if(u<0x800) {
+ m = ((u&0x7c0)>>6) | 0xc0;
+ printf("%c", (unsigned char)m);
+ m = (u&0x3f) | 0x80;
+ printf("%c", (unsigned char)m);
+ }
+ else if(u<0x10000) {
+ m = ((u&0xf000)>>12) | 0xe0;
+ printf("%c",(unsigned char)m);
+ m = ((u&0xfc0)>>6) | 0x80;
+ printf("%c",(unsigned char)m);
+ m = (u & 0x3f) | 0x80;
+ printf("%c",(unsigned char)m);
+ }
+ else if(u<0x200000) {
+ m = ((u&0x1c0000)>>18) | 0xf0;
+ printf("%c", (unsigned char)m);
+ m = ((u& 0x3f000)>>12) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = ((u& 0xfc0)>>6) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = (u&0x3f) | 0x80;
+ printf("%c", (unsigned char)m);
+ }
+ else if(u<0x4000000){
+ m = ((u&0x3000000)>>24) | 0xf8;
+ printf("%c", (unsigned char)m);
+ m = ((u&0xfc0000)>>18) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = ((u&0x3f000)>>12) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = ((u&0xfc00)>>6) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = (u&0x3f) | 0x80;
+ printf("%c", (unsigned char)m);
+ }
+ else {
+ m = ((u&0x40000000)>>30) | 0xfc;
+ printf("%c", (unsigned char)m);
+ m = ((u&0x3f000000)>>24) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = ((u&0xfc0000)>>18) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = ((u&0x3f000)>>12) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = ((u&0xfc0)>>6) | 0x80;
+ printf("%c", (unsigned char)m);
+ m = (u&0x3f)| 0x80;
+ printf("%c", (unsigned char)m);
+ }
+}
+
+int main() {
+ int i,j;
+ long long n1, n2;
+ unsigned char b1[15], b2[15];
+ unsigned char buf[1024];
+ i=0;
+ while(fgets(buf, 1024, stdin)) {
+ // printf("read %s\n", buf);
+ for(i=0;i<strlen(buf); i++)
+ if(buf[i]=='U') {
+ if(buf[i+1] == '+') {
+ n1 = strtoll(buf+i+2,0,16);
+ printf("U+%05x", n1);
+ printUTF8(n1);printf("|");
+ }
+ }
+ printf("\n");
+ }
+}
+
diff --git a/includes/zhtable/simp2trad.manual b/includes/zhtable/simp2trad.manual
new file mode 100644
index 000000000000..b5e1c3aee40e
--- /dev/null
+++ b/includes/zhtable/simp2trad.manual
@@ -0,0 +1,178 @@
+U+0753b画|U+0756b畫|U+07575畵|
+U+0677f板|U+0677f板|U+095c6闆|
+U+08868表|U+08868表|U+09336錶|
+U+0624d才|U+0624d才|U+07e94纔|
+U+04e11丑|U+0919c醜|U+04e11丑|
+U+051fa出|U+051fa出|U+09f63齣|
+U+06dc0淀|U+06fb1澱|U+06dc0淀|
+U+051ac冬|U+051ac冬|U+09f15鼕|
+U+08303范|U+07bc4範|U+08303范|
+U+04e30丰|U+08c50豐|U+04e30丰|
+U+0522e刮|U+0522e刮|U+098b3颳|
+U+0540e后|U+05f8c後|U+0540e后|
+U+080e1胡|U+080e1胡|U+09b0d鬍|U+0885a衚|
+U+056de回|U+056de回|U+08ff4迴|
+U+04f19伙|U+05925夥|U+04f19伙|
+U+059dc姜|U+08591薑|U+059dc姜|
+U+0501f借|U+0501f借|U+085c9藉|
+U+0514b克|U+0514b克|U+0524b剋|
+U+056f0困|U+056f0困|U+0774f睏|
+U+06f13漓|U+06f13漓|U+07055灕|
+U+091cc里|U+091cc里|U+088e1裡|U+088cf裏|
+U+05e18帘|U+07c3e簾|U+05e18帘|
+U+09709霉|U+09709霉|U+09ef4黴|
+U+09762面|U+09762面|U+09eb5麵|
+U+08511蔑|U+08511蔑|U+0884a衊|
+U+05343千|U+05343千|U+097c6韆|
+U+079cb秋|U+079cb秋|U+097a6鞦|
+U+0677e松|U+0677e松|U+09b06鬆|
+U+054b8咸|U+054b8咸|U+09e79鹹|
+U+05411向|U+05411向|U+056ae嚮|U+066cf曏|
+U+04f59余|U+09918餘|U+04f59余|
+U+090c1郁|U+09b31鬱|U+090c1郁|
+U+05fa1御|U+05fa1御|U+079a6禦|
+U+0613f愿|U+09858願|U+0613f愿|
+U+04e91云|U+096f2雲|U+04e91云|
+U+082b8芸|U+082b8芸|U+08553蕓|
+U+06c84沄|U+06c84沄|U+06f90澐|
+U+081f4致|U+081f4致|U+07dfb緻|
+U+05236制|U+05236制|U+088fd製|
+U+06731朱|U+06731朱|U+07843硃|
+U+07b51筑|U+07bc9築|U+07b51筑|
+U+051c6准|U+06e96準|U+051c6准|
+U+05382厂|U+05ee0廠|U+05382厂|
+U+05e7f广|U+05ee3廣|U+05e7f广|
+U+08f9f辟|U+095e2闢|U+08f9f辟|
+U+0522b别|U+05225別|U+05f46彆|
+U+0535c卜|U+0535c卜|U+08514蔔|
+U+06c88沈|U+06c88沈|U+0700b瀋|
+U+051b2冲|U+06c96沖|U+0885d衝|
+U+079cd种|U+07a2e種|U+079cd种|
+U+0866b虫|U+087f2蟲|U+0866b虫|
+U+062c5担|U+064d4擔|U+062c5担|
+U+0515a党|U+09ee8黨|U+0515a党|
+U+06597斗|U+09b25鬥|U+06597斗|
+U+0513f儿|U+05152兒|U+0513f儿|
+U+05e72干|U+04e7e乾|U+05e79幹|U+05e72干|U+069a6%G榦%@|
+U+08c37谷|U+08c37谷|U+07a40穀|
+U+067dc柜|U+06ac3櫃|U+067dc柜|
+U+05408合|U+05408合|U+095a4閤|
+U+05212划|U+05283劃|U+05212划|
+U+0574f坏|U+058de壞|U+0574f坏|
+U+051e0几|U+05e7e幾|U+051e0几|
+U+07cfb系|U+07cfb系|U+07e6b繫|U+04fc2係|
+U+05bb6家|U+05bb6家|U+050a2傢|
+U+04ef7价|U+050f9價|U+04ef7价|
+U+0636e据|U+064da據|U+0636e据|
+U+05377卷|U+06372捲|U+05377卷|
+U+09002适|U+09069適|U+09002适|
+U+08721蜡|U+0881f蠟|U+08721蜡|
+U+0814a腊|U+081d8臘|U+0814a腊|
+U+04e86了|U+04e86了|U+077ad瞭|
+U+07d2f累|U+07d2f累|U+07e8d纍|
+U+04e48么|U+09ebd麽|U+04e48么|U+05e7a幺|U+09ebc麼|
+U+08499蒙|U+08499蒙|U+077c7矇|U+06fdb濛|U+061de懞|
+U+04e07万|U+0842c萬|U+04e07万|
+U+05b81宁|U+05be7寧|U+05b81宁|
+U+06734朴|U+06a38樸|U+06734朴|
+U+082f9苹|U+0860b蘋|U+082f9苹|
+U+04ec6仆|U+050d5僕|U+04ec6仆|
+U+066f2曲|U+066f2曲|U+09eaf麯|
+U+0786e确|U+078ba確|U+0786e确|
+U+0820d舍|U+0820d舍|U+06368捨|
+U+080dc胜|U+052dd勝|U+080dc胜|
+U+0672f术|U+08853術|U+0672f术|U+0672e朮|
+U+053f0台|U+053f0台|U+081fa臺|U+06aaf檯|U+098b1颱|
+U+04f53体|U+09ad4體|U+04f53体|
+U+06d82涂|U+05857塗|U+06d82涂|
+U+053f6叶|U+08449葉|U+053f6叶|
+U+05401吁|U+05401吁|U+07c72籲|
+U+065cb旋|U+065cb旋|U+0955f镟|
+U+04f63佣|U+050ad傭|U+04f63佣|
+U+04e0e与|U+08207與|U+04e0e与|
+U+06298折|U+06298折|U+0647a摺|
+U+05f81征|U+05fb5徵|U+05f81征|
+U+075c7症|U+075c7症|U+07665癥|
+U+06076恶|U+060e1惡|U+05641噁|
+U+053d1发|U+0767c發|U+09aee髮|
+U+0590d复|U+05fa9復|U+08907複|U+08986覆|
+U+06c47汇|U+0532f匯|U+05f59彙|
+U+083b7获|U+07372獲|U+07a6b穫|
+U+09965饥|U+098e2飢|U+09951饑|
+U+05c3d尽|U+076e1盡|U+05118儘|
+U+05386历|U+06b77歷|U+066c6曆|
+U+05364卤|U+06ef7滷|U+09e75鹵|
+U+05f25弥|U+05f4c彌|U+07030瀰|
+U+07b7e签|U+07c3d簽|U+07c56籖|
+U+07ea4纤|U+07e96纖|U+07e34縴|
+U+082cf苏|U+08607蘇|U+056cc囌|
+U+0575b坛|U+058c7壇|U+07f48罈|
+U+056e2团|U+05718團|U+07cf0糰|
+U+0987b须|U+09808須|U+09b1a鬚|
+U+0810f脏|U+081df臟|U+09ad2髒|
+U+053ea只|U+053ea只|U+096bb隻|
+U+0949f钟|U+09418鐘|U+0937e鍾|
+U+0836f药|U+085e5藥|U+0846f葯|
+U+0540c同|U+0540c同|U+08855衕|
+U+05fd7志|U+05fd7志|U+08a8c誌|
+U+0676f杯|U+0676f杯|U+076c3盃|
+U+05cb3岳|U+05cb3岳|U+05dbd嶽|
+U+05e03布|U+05e03布|U+04f48佈|
+U+05f53当|U+07576當|U+05679噹|
+U+0540a吊|U+05f14弔|U+0540a吊|
+U+04ec7仇|U+04ec7仇|U+08b8e讎|
+U+08574蕴|U+0860a蘊|U+085f4藴|
+U+07ebf线|U+07dda線|U+07dab綫|
+U+04e3a为|U+070ba為|U+07232爲|
+U+04ea7产|U+07522產|U+07523産|
+U+04f17众|U+0773e眾|U+08846衆|
+U+04f2a伪|U+0507d偽|U+050de僞|
+U+051eb凫|U+09ce7鳧|U+09cec鳬|
+U+05395厕|U+05ec1廁|U+053a0厠|
+U+0542f启|U+0555f啟|U+05553啓|
+U+05899墙|U+07246牆|U+058bb墻|
+U+058f3壳|U+06bbc殼|U+06bbb殻|
+U+05956奖|U+0734e獎|U+0596c奬|
+U+059ab妫|U+05aaf媯|U+05b00嬀|
+U+05e76并|U+04e26並|U+04f75併|
+U+05f55录|U+09304錄|U+09332録|
+U+060ab悫|U+06128愨|U+06164慤|
+U+06781极|U+06975極|U+06781极|
+U+06ca9沩|U+06e88溈|U+06f59潙|
+U+07618瘘|U+0763a瘺|U+0763b瘻|
+U+07877硷|U+09e7c鹼|U+07906礆|
+U+07ad6竖|U+08c4e豎|U+07aea竪|
+U+07edd绝|U+07d55絕|U+07d76絶|
+U+07ee3绣|U+07e61繡|U+07d89綉|
+U+07ee6绦|U+07d5b絛|U+07e27縧|
+U+07ef1绱|U+07dd4緔|U+0979d鞝|
+U+07ef7绷|U+07db3綳|U+07e43繃|
+U+07eff绿|U+07da0綠|U+07dd1緑|
+U+07f30缰|U+097c1韁|U+07e6e繮|
+U+082e7苧|U+082ce苎|U+085b4薴|
+U+083bc莼|U+08493蒓|U+084f4蓴|
+U+08bf4说|U+08aaa說|U+08aac説|
+U+08c23谣|U+08b20謠|U+08b21謡|
+U+08c2b谫|U+08b7e譾|U+08b2d謭|
+U+08d43赃|U+08d13贓|U+08d1c贜|
+U+08d4d赍|U+09f4e齎|U+08ceb賫|
+U+08d5d赝|U+08d17贗|U+08d0b贋|
+U+0915d酝|U+0919e醞|U+09196醖|
+U+091c7采|U+063a1採|U+091c7采|U+057f0埰|
+U+094a9钩|U+09264鉤|U+0920e鈎|
+U+094b5钵|U+07f3d缽|U+09262鉢|
+U+09508锈|U+092b9銹|U+093fd鏽|
+U+09510锐|U+092b3銳|U+092ed鋭|
+U+09528锨|U+06774杴|U+09341鍁|
+U+0954c镌|U+0942b鐫|U+093b8鎸|
+U+09562镢|U+09481钁|U+0941d鐝|
+U+09605阅|U+095b1閱|U+095b2閲|
+U+09893颓|U+09839頹|U+0983d頽|
+U+0989c颜|U+0984f顏|U+09854顔|
+U+09980馀|U+09918餘|
+U+09a82骂|U+07f75罵|U+099e1駡|
+U+09c87鲇|U+09bf0鯰|U+09b8e鮎|
+U+09c9e鲞|U+09bd7鯗|U+09b9d鮝|
+U+09cc4鳄|U+09c77鱷|U+09c10鰐|
+U+09e21鸡|U+096de雞|U+09dc4鷄|
+U+09e5a鹚|U+09dbf鶿|U+09dc0鷀|
diff --git a/includes/zhtable/toCN.manual b/includes/zhtable/toCN.manual
new file mode 100644
index 000000000000..caff9c14e37d
--- /dev/null
+++ b/includes/zhtable/toCN.manual
@@ -0,0 +1,331 @@
+記憶體 内存
+預設 默认
+預設 缺省
+串列 串行
+乙太網 以太网
+點陣圖 位图
+常式 例程
+通道 信道
+游標 光标
+光碟 光盘
+光碟機 光驱
+全形 全角
+共用 共享
+相容 兼容
+首碼 前缀
+尾碼 后缀
+載入 加载
+半形 半角
+變數 变量
+雜訊 噪声
+因數 因子
+線上 在线
+離線 脱机
+功能變數名稱 域名
+音效卡 声卡
+字型大小 字号
+字型檔 字库
+欄位 字段
+字元 字符
+存檔 存盘
+定址 寻址
+章節附註 尾注
+非同步 异步
+匯流排 总线
+括弧 括号
+介面 接口
+控制項 控件
+許可權 权限
+碟片 盘片
+矽片 硅片
+矽谷 硅谷
+硬碟 硬盘
+磁碟 磁盘
+磁軌 磁道
+程式控制 程控
+埠 端口
+運算元 算子
+演算法 算法
+晶片 芯片
+晶元 芯片
+片語 词组
+解碼 译码
+軟碟機 软驱
+快閃記憶體 闪存
+滑鼠 鼠标
+進位 进制
+互動式 交互式
+模擬 仿真
+優先順序 优先级
+感測 传感
+攜帶型 便携式
+資訊理論 信息论
+迴圈 循环
+防寫 写保护
+分散式 分布式
+解析度 分辨率
+程式 程序
+伺服器 服务器
+等於 等于
+區域網 局域网
+上傳 上载
+電腦 计算机
+巨集 宏
+掃瞄器 扫瞄仪
+寬頻 宽带
+視窗 窗口
+資料庫 数据库
+西曆 公历
+乳酪 奶酪
+鉅賈 巨商
+手電筒 手电
+萬曆 万历
+永曆 永历
+辭彙 词汇
+保全 保安
+慣用 习用
+母音 元音
+自由球 任意球
+頭槌 头球
+進球 入球
+顆進球 粒入球
+射門 打门
+蓋火鍋 火锅盖帽
+印表機 打印机
+打印機 打印机
+位元組 字节
+字節 字节
+列印 打印
+打印 打印
+硬體 硬件
+二極體 二极管
+二極管 二极管
+三極體 三极管
+三極管 三极管
+數位 数码
+數碼 数码
+軟體 软件
+軟件 软件
+網路 网络
+網絡 网络
+人工智慧 人工智能
+太空梭 航天飞机
+穿梭機 航天飞机
+網際網路 因特网
+互聯網 因特网
+機械人 机器人
+機器人 机器人
+行動電話 移动电话
+流動電話 移动电话
+調制解調器 调制解调器
+數據機 调制解调器
+短訊 短信
+簡訊 短信
+烏茲別克 乌兹别克斯坦
+查德 乍得
+乍得 乍得
+也門
+葉門 也门
+伯利茲 伯利兹
+貝里斯 伯利兹
+維德角 佛得角
+佛得角 佛得角
+克羅地亞 克罗地亚
+克羅埃西亞 克罗地亚
+岡比亞 冈比亚
+甘比亞 冈比亚
+幾內亞比紹 几内亚比绍
+幾內亞比索 几内亚比绍
+列支敦斯登 列支敦士登
+列支敦士登 列支敦士登
+利比里亞 利比里亚
+賴比瑞亞 利比里亚
+加納 加纳
+迦納 加纳
+加彭 加蓬
+加蓬 加蓬
+博茨瓦納 博茨瓦纳
+波札那 博茨瓦纳
+卡塔爾 卡塔尔
+卡達 卡塔尔
+盧旺達 卢旺达
+盧安達 卢旺达
+危地馬拉 危地马拉
+瓜地馬拉 危地马拉
+厄瓜多爾 厄瓜多尔
+厄瓜多 厄瓜多尔
+厄立特里亞 厄立特里亚
+厄利垂亞 厄立特里亚
+吉布堤 吉布提
+吉布地 吉布提
+哈薩克 哈萨克斯坦
+哥斯達黎加 哥斯达黎加
+哥斯大黎加 哥斯达黎加
+圖瓦盧 图瓦卢
+吐瓦魯 图瓦卢
+土庫曼 土库曼斯坦
+聖盧西亞 圣卢西亚
+聖露西亞 圣卢西亚
+聖吉斯納域斯 圣基茨和尼维斯
+聖克里斯多福及尼維斯 圣基茨和尼维斯
+聖文森特和格林納丁斯 圣文森特和格林纳丁斯
+聖文森及格瑞那丁 圣文森特和格林纳丁斯
+聖馬力諾 圣马力诺
+聖馬利諾 圣马力诺
+圭亞那 圭亚那
+蓋亞那 圭亚那
+坦桑尼亞 坦桑尼亚
+坦尚尼亞 坦桑尼亚
+埃塞俄比亞 埃塞俄比亚
+衣索比亞 埃塞俄比亚
+吉里巴斯 基里巴斯
+基里巴斯 基里巴斯
+塔吉克 塔吉克斯坦
+獅子山 塞拉利昂
+塞拉利昂 塞拉利昂
+塞普勒斯 塞浦路斯
+塞浦路斯 塞浦路斯
+塞舌爾 塞舌尔
+塞席爾 塞舌尔
+多明尼加共和國 多米尼加
+多明尼加 多米尼加
+多明尼加聯邦 多米尼加联邦
+多米尼克 多米尼加联邦
+安提瓜和巴布達 安提瓜和巴布达
+安地卡及巴布達 安提瓜和巴布达
+尼日利亞 尼日利亚
+奈及利亞 尼日利亚
+尼日爾 尼日尔
+尼日 尼日尔
+巴貝多 巴巴多斯
+巴巴多斯 巴巴多斯
+巴布亞新畿內亞 巴布亚新几内亚
+巴布亞紐幾內亞 巴布亚新几内亚
+布基納法索 布基纳法索
+布吉納法索 布基纳法索
+蒲隆地 布隆迪
+布隆迪 布隆迪
+希臘 希腊
+帛琉 帕劳
+義大利 意大利
+意大利 意大利
+所羅門群島 所罗门群岛
+索羅門群島 所罗门群岛
+汶萊 文莱
+斯威士蘭 斯威士兰
+史瓦濟蘭 斯威士兰
+斯洛文尼亞 斯洛文尼亚
+斯洛維尼亞 斯洛文尼亚
+新西蘭 新西兰
+紐西蘭 新西兰
+北韓 朝鲜
+格林納達 格林纳达
+格瑞那達 格林纳达
+格魯吉亞 格鲁吉亚
+喬治亞 格鲁吉亚
+梵蒂岡 梵蒂冈
+教廷 梵蒂冈
+毛里塔尼亞 毛里塔尼亚
+茅利塔尼亞 毛里塔尼亚
+毛里裘斯 毛里求斯
+模里西斯 毛里求斯
+沙地阿拉伯 沙特阿拉伯
+沙烏地阿拉伯 沙特阿拉伯
+波斯尼亞黑塞哥維那 波斯尼亚和黑塞哥维那
+波士尼亞赫塞哥維納 波斯尼亚和黑塞哥维那
+津巴布韋 津巴布韦
+辛巴威 津巴布韦
+宏都拉斯 洪都拉斯
+洪都拉斯 洪都拉斯
+特立尼達和多巴哥 特立尼达和托巴哥
+千里達托貝哥 特立尼达和托巴哥
+瑙魯 瑙鲁
+諾魯 瑙鲁
+瓦努阿圖 瓦努阿图
+萬那杜 瓦努阿图
+溫納圖 瓦努阿图
+科摩羅 科摩罗
+葛摩 科摩罗
+象牙海岸 科特迪瓦
+突尼西亞 突尼斯
+索馬里 索马里
+索馬利亞 索马里
+老撾 老挝
+寮國 老挝
+肯雅 肯尼亚
+肯亞 肯尼亚
+蘇利南 苏里南
+莫三比克 莫桑比克
+莫桑比克 莫桑比克
+萊索托 莱索托
+賴索托 莱索托
+貝寧 贝宁
+貝南 贝宁
+贊比亞 赞比亚
+尚比亞 赞比亚
+亞塞拜然 阿塞拜疆
+阿塞拜疆 阿塞拜疆
+阿拉伯聯合酋長國 阿拉伯联合酋长国
+阿拉伯聯合大公國 阿拉伯联合酋长国
+南韓 韩国
+馬爾代夫 马尔代夫
+馬爾地夫 马尔代夫
+馬爾他 马耳他
+馬里 马里
+馬利 马里
+即食麵 方便面
+快速面 方便面
+速食麵 方便面
+泡麵 方便面
+笨豬跳 蹦极跳
+绑紧跳 蹦极跳
+冷盤   凉菜
+冷菜 凉菜
+散钱 零钱
+谐星 笑星    
+夜学 夜校
+华乐 民乐
+中樂 民乐
+住屋 住房
+屋价 房价
+的士 出租车
+計程車 出租车
+巴士 公共汽车
+公車 公共汽车
+單車 自行车
+節慶 节日
+芝士 乾酪
+狗隻 犬只
+士多啤梨 草莓
+忌廉 奶油
+桌球 台球
+撞球 台球
+雪糕 冰淇淋
+衞生 卫生
+衛生 卫生
+賓士 奔驰
+平治 奔驰
+捷豹 美洲虎
+積架 美洲虎
+福斯 大众
+福士 大众
+雪鐵龍 雪铁龙
+萬事得 马自达
+馬自達 马自达
+寶獅 标志
+布殊 布什
+布希 布什
+柯林頓 克林顿
+克林頓 克林顿
+薩達姆 萨达姆
+海珊 萨达姆
+梵谷 凡高
+大衛碧咸 大卫·贝克汉姆
+米高奧雲 迈克尔·欧文
+卡佩雅蒂 珍妮弗·卡普里亚蒂
+沙芬 马拉特·萨芬
+舒麥加 迈克尔·舒马赫
+希特拉 希特勒
+戴安娜 狄安娜
+黛安娜 狄安娜
+希拉 赫拉 \ No newline at end of file
diff --git a/includes/zhtable/toHK.manual b/includes/zhtable/toHK.manual
new file mode 100644
index 000000000000..ab62345573a0
--- /dev/null
+++ b/includes/zhtable/toHK.manual
@@ -0,0 +1,211 @@
+打印机 打印機
+印表機 打印機
+字节 字節
+位元組 字節
+打印 打印
+列印 打印
+硬件 硬件
+硬體 硬件
+二极管 二極管
+二極體 二極管
+三极管 三極管
+三極體 三極管
+数码 數碼
+數位 數碼
+软件 軟件
+軟體 軟件
+网络 網絡
+網路 網絡
+人工智能 人工智能
+人工智慧 人工智能
+航天飞机 穿梭機
+太空梭 穿梭機
+因特网 互聯網
+網際網路 互聯網
+机器人 機械人
+機器人 機械人
+移动电话 流動電話
+行動電話 流動電話
+调制解调器 調制解調器
+數據機 調制解調器
+短信 短訊
+簡訊 短訊
+乍得 乍得
+查德 乍得
+也门 也門
+葉門 也門
+伯利兹 伯利茲
+貝里斯 伯利茲
+佛得角 佛得角
+維德角 佛得角
+克罗地亚 克羅地亞
+克羅埃西亞 克羅地亞
+冈比亚 岡比亞
+甘比亞 岡比亞
+几内亚比绍 幾內亞比紹
+幾內亞比索 幾內亞比紹
+列支敦士登 列支敦士登
+列支敦斯登 列支敦士登
+利比里亚 利比里亞
+賴比瑞亞 利比里亞
+加纳 加納
+迦納 加納
+加蓬 加蓬
+加彭 加蓬
+博茨瓦纳 博茨瓦納
+波札那 博茨瓦納
+卡塔尔 卡塔爾
+卡達 卡塔爾
+卢旺达 盧旺達
+盧安達 盧旺達
+危地马拉 危地馬拉
+瓜地馬拉 危地馬拉
+厄瓜多尔 厄瓜多爾
+厄瓜多 厄瓜多爾
+厄立特里亚 厄立特里亞
+厄利垂亞 厄立特里亞
+吉布提 吉布堤
+吉布地 吉布堤
+哥斯达黎加 哥斯達黎加
+哥斯大黎加 哥斯達黎加
+图瓦卢 圖瓦盧
+吐瓦魯 圖瓦盧
+圣卢西亚 聖盧西亞
+聖露西亞 聖盧西亞
+圣基茨和尼维斯 聖吉斯納域斯
+聖克里斯多福及尼維斯 聖吉斯納域斯
+圣文森特和格林纳丁斯 聖文森特和格林納丁斯
+聖文森及格瑞那丁 聖文森特和格林納丁斯
+圣马力诺 聖馬力諾
+聖馬利諾 聖馬力諾
+圭亚那 圭亞那
+蓋亞那 圭亞那
+坦桑尼亚 坦桑尼亞
+坦尚尼亞 坦桑尼亞
+埃塞俄比亚 埃塞俄比亞
+衣索比亞 埃塞俄比亞
+基里巴斯 基里巴斯
+吉里巴斯 基里巴斯
+獅子山 塞拉利昂
+塞普勒斯 塞浦路斯
+塞舌尔 塞舌爾
+塞席爾 塞舌爾
+多米尼加 多明尼加共和國
+多明尼加 多明尼加共和國
+多米尼加联邦 多明尼加聯邦
+多米尼克 多明尼加聯邦
+安提瓜和巴布达 安提瓜和巴布達
+安地卡及巴布達 安提瓜和巴布達
+尼日利亚 尼日利亞
+奈及利亞 尼日利亞
+尼日尔 尼日爾
+尼日 尼日爾
+巴巴多斯 巴巴多斯
+巴貝多 巴巴多斯
+巴布亚新几内亚 巴布亞新畿內亞
+巴布亞紐幾內亞 巴布亞新畿內亞
+布基纳法索 布基納法索
+布吉納法索 布基納法索
+布隆迪 布隆迪
+蒲隆地 布隆迪
+義大利 意大利
+所罗门群岛 所羅門群島
+索羅門群島 所羅門群島
+斯威士兰 斯威士蘭
+史瓦濟蘭 斯威士蘭
+斯洛文尼亚 斯洛文尼亞
+斯洛維尼亞 斯洛文尼亞
+新西兰 新西蘭
+紐西蘭 新西蘭
+格林纳达 格林納達
+格瑞那達 格林納達
+格鲁吉亚 格魯吉亞
+喬治亞 格魯吉亞
+梵蒂冈 梵蒂岡
+教廷 梵蒂岡
+毛里塔尼亚 毛里塔尼亞
+茅利塔尼亞 毛里塔尼亞
+毛里求斯 毛里裘斯
+模里西斯 毛里裘斯
+沙特阿拉伯 沙地阿拉伯
+沙烏地阿拉伯 沙地阿拉伯
+波斯尼亚和黑塞哥维那 波斯尼亞黑塞哥維那
+波士尼亞赫塞哥維納 波斯尼亞黑塞哥維那
+津巴布韦 津巴布韋
+辛巴威 津巴布韋
+洪都拉斯 洪都拉斯
+宏都拉斯 洪都拉斯
+特立尼达和托巴哥 特立尼達和多巴哥
+千里達托貝哥 特立尼達和多巴哥
+瑙鲁 瑙魯
+諾魯 瑙魯
+瓦努阿图 瓦努阿圖
+萬那杜 瓦努阿圖
+科摩罗 科摩羅
+葛摩 科摩羅
+索马里 索馬里
+索馬利亞 索馬里
+老挝 老撾
+寮國 老撾
+肯尼亚 肯雅
+肯亞 肯雅
+莫桑比克 莫桑比克
+莫三比克 莫桑比克
+莱索托 萊索托
+賴索托 萊索托
+贝宁 貝寧
+貝南 貝寧
+赞比亚 贊比亞
+尚比亞 贊比亞
+阿塞拜疆 阿塞拜疆
+亞塞拜然 阿塞拜疆
+阿拉伯联合酋长国 阿拉伯聯合酋長國
+阿拉伯聯合大公國 阿拉伯聯合酋長國
+马尔代夫 馬爾代夫
+馬爾地夫 馬爾代夫
+马里 馬里
+馬利 馬里
+方便面 即食麵
+快速面 即食麵
+速食麵 即食麵
+泡麵 即食麵
+土豆 薯仔
+华乐 中樂
+民乐 中樂
+計程車 的士
+出租车 的士
+公車 巴士
+公共汽车 巴士
+自行车 單車
+节日 節慶
+犬只 狗隻
+台球 桌球
+撞球 桌球
+冰淇淋 雪糕
+冰淇淋 雪糕
+卫生 衞生
+衛生 衞生
+老人 長者
+賓士 平治
+捷豹 積架
+福斯 福士
+雪铁龙 先進
+雪鐵龍 先進
+沃尓沃 富豪
+马自达 萬事得
+馬自達 萬事得
+寶獅 標致
+布什 布殊
+布希 布殊
+克林顿 克林頓
+柯林頓 克林頓
+萨达姆 薩達姆
+海珊 薩達姆
+大卫·贝克汉姆 大衛碧咸
+迈克尔·欧文 米高奧雲
+珍妮弗·卡普里亚蒂 卡佩雅蒂
+马拉特·萨芬 沙芬
+迈克尔·舒马赫 舒麥加
+希特勒 希特拉
+狄安娜 戴安娜
+黛安娜 戴安娜 \ No newline at end of file
diff --git a/includes/zhtable/toSG.manual b/includes/zhtable/toSG.manual
new file mode 100644
index 000000000000..9a399bc8810a
--- /dev/null
+++ b/includes/zhtable/toSG.manual
@@ -0,0 +1,15 @@
+方便面 快速面
+速食麵 快速面
+即食麵 快速面
+蹦极跳 绑紧跳
+笨豬跳 绑紧跳
+凉菜 冷菜
+冷盤 冷菜
+零钱 散钱
+散紙 散钱
+笑星 谐星
+夜校 夜学
+民乐 华乐
+住房 住屋
+房价 屋价
+泡麵 快速面 \ No newline at end of file
diff --git a/includes/zhtable/toTW.manual b/includes/zhtable/toTW.manual
new file mode 100644
index 000000000000..5c90dbe334ed
--- /dev/null
+++ b/includes/zhtable/toTW.manual
@@ -0,0 +1,309 @@
+内存 記憶體
+默认 預設
+缺省 預設
+串行 串列
+以太网 乙太網
+位图 點陣圖
+例程 常式
+信道 通道
+光标 游標
+光盘 光碟
+光驱 光碟機
+全角 全形
+共享 共用
+兼容 相容
+前缀 首碼
+后缀 尾碼
+加载 載入
+半角 半形
+变量 變數
+噪声 雜訊
+因子 因數
+在线 線上
+脱机 離線
+域名 功能變數名稱
+声卡 音效卡
+字号 字型大小
+字库 字型檔
+字段 欄位
+字符 字元
+存盘 存檔
+寻址 定址
+尾注 章節附註
+异步 非同步
+总线 匯流排
+括号 括弧
+接口 介面
+控件 控制項
+权限 許可權
+盘片 碟片
+硅片 矽片
+硅谷 矽谷
+硬盘 硬碟
+磁盘 磁碟
+磁道 磁軌
+程控 程式控制
+端口 埠
+算子 運算元
+算法 演算法
+芯片 晶片
+芯片 晶元
+词组 片語
+译码 解碼
+软驱 軟碟機
+闪存 快閃記憶體
+鼠标 滑鼠
+进制 進位
+交互式 互動式
+仿真 模擬
+优先级 優先順序
+传感 感測
+便携式 攜帶型
+信息论 資訊理論
+循环 迴圈
+写保护 防寫
+分布式 分散式
+分辨率 解析度
+程序 程式
+服务器 伺服器
+等于 等於
+局域网 區域網
+上载 上傳
+计算机 電腦
+宏 巨集
+扫瞄仪 掃瞄器
+宽带 寬頻
+窗口 視窗
+数据库 資料庫
+公历 西曆
+奶酪 乳酪
+巨商 鉅賈
+手电 手電筒
+万历 萬曆
+永历 永曆
+词汇 辭彙
+保安 保全
+习用 慣用
+元音 母音
+任意球 自由球
+头球 頭槌
+入球 進球
+粒入球 顆進球
+打门 射門
+火锅盖帽 蓋火鍋
+打印机 印表機
+打印機 印表機
+字节 位元組
+字節 位元組
+打印 列印
+打印 列印
+硬件 硬體
+硬件 硬體
+二极管 二極體
+二極管 二極體
+三极管 三極體
+三極管 三極體
+数码 數位
+數碼 數位
+软件 軟體
+軟件 軟體
+网络 網路
+網絡 網路
+人工智能 人工智慧
+航天飞机 太空梭
+穿梭機 太空梭
+因特网 網際網路
+互聯網 網際網路
+机器人 機器人
+機械人 機器人
+移动电话 行動電話
+流動電話 行動電話
+调制解调器 數據機
+調制解調器 數據機
+短信 簡訊
+短訊 簡訊
+乌兹别克斯坦 烏茲別克
+乍得 查德
+乍得 查德
+也门 葉門
+也門 葉門
+伯利兹 貝里斯
+伯利茲 貝里斯
+佛得角 維德角
+佛得角 維德角
+克罗地亚 克羅埃西亞
+克羅地亞 克羅埃西亞
+冈比亚 甘比亞
+岡比亞 甘比亞
+几内亚比绍 幾內亞比索
+幾內亞比紹 幾內亞比索
+列支敦士登 列支敦斯登
+列支敦士登 列支敦斯登
+利比里亚 賴比瑞亞
+利比里亞 賴比瑞亞
+加纳 迦納
+加納 迦納
+加蓬 加彭
+加蓬 加彭
+博茨瓦纳 波札那
+博茨瓦納 波札那
+卡塔尔 卡達
+卡塔爾 卡達
+卢旺达 盧安達
+盧旺達 盧安達
+危地马拉 瓜地馬拉
+危地馬拉 瓜地馬拉
+厄瓜多尔 厄瓜多
+厄瓜多爾 厄瓜多
+厄立特里亚 厄利垂亞
+厄立特里亞 厄利垂亞
+吉布提 吉布地
+吉布堤 吉布地
+哈萨克斯坦 哈薩克
+哥斯达黎加 哥斯大黎加
+哥斯達黎加 哥斯大黎加
+图瓦卢 吐瓦魯
+圖瓦盧 吐瓦魯
+土库曼斯坦 土庫曼
+圣卢西亚 聖露西亞
+聖盧西亞 聖露西亞
+圣基茨和尼维斯 聖克里斯多福及尼維斯
+聖吉斯納域斯 聖克里斯多福及尼維斯
+圣文森特和格林纳丁斯 聖文森及格瑞那丁
+聖文森特和格林納丁斯 聖文森及格瑞那丁
+圣马力诺 聖馬利諾
+聖馬力諾 聖馬利諾
+圭亚那 蓋亞那
+圭亞那 蓋亞那
+坦桑尼亚 坦尚尼亞
+坦桑尼亞 坦尚尼亞
+埃塞俄比亚 衣索比亞
+埃塞俄比亞 衣索比亞
+基里巴斯 吉里巴斯
+基里巴斯 吉里巴斯
+塔吉克斯坦 塔吉克
+塞拉利昂 獅子山
+塞拉利昂 獅子山
+塞浦路斯 塞普勒斯
+塞浦路斯 塞普勒斯
+塞舌尔 塞席爾
+塞舌爾 塞席爾
+多米尼加 多明尼加
+多明尼加共和國 多明尼加
+多米尼加联邦 多米尼克
+多明尼加聯邦 多米尼克
+安提瓜和巴布达 安地卡及巴布達
+安提瓜和巴布達 安地卡及巴布達
+尼日利亚 奈及利亞
+尼日利亞 奈及利亞
+尼日尔 尼日
+尼日爾 尼日
+巴巴多斯 巴貝多
+巴巴多斯 巴貝多
+巴布亚新几内亚 巴布亞紐幾內亞
+巴布亞新畿內亞 巴布亞紐幾內亞
+布基纳法索 布吉納法索
+布基納法索 布吉納法索
+布隆迪 蒲隆地
+布隆迪 蒲隆地
+希腊 希臘
+帕劳 帛琉
+意大利 義大利
+意大利 義大利
+所罗门群岛 索羅門群島
+所羅門群島 索羅門群島
+文莱 汶萊
+斯威士兰 史瓦濟蘭
+斯威士蘭 史瓦濟蘭
+斯洛文尼亚 斯洛維尼亞
+斯洛文尼亞 斯洛維尼亞
+新西兰 紐西蘭
+新西蘭 紐西蘭
+朝鲜 北韓
+格林纳达 格瑞那達
+格林納達 格瑞那達
+格鲁吉亚 喬治亞
+格魯吉亞 喬治亞
+梵蒂冈 教廷
+梵蒂岡 教廷
+毛里塔尼亚 茅利塔尼亞
+毛里塔尼亞 茅利塔尼亞
+毛里求斯 模里西斯
+毛里裘斯 模里西斯
+沙特阿拉伯 沙烏地阿拉伯
+沙地阿拉伯 沙烏地阿拉伯
+波斯尼亚和黑塞哥维那 波士尼亞赫塞哥維納
+波斯尼亞黑塞哥維那 波士尼亞赫塞哥維納
+津巴布韦 辛巴威
+津巴布韋 辛巴威
+洪都拉斯 宏都拉斯
+洪都拉斯 宏都拉斯
+特立尼达和托巴哥 千里達托貝哥
+特立尼達和多巴哥 千里達托貝哥
+瑙鲁 諾魯
+瑙魯 諾魯
+瓦努阿图 萬那杜
+瓦努阿圖 萬那杜
+溫納圖萬 那杜
+科摩罗 葛摩
+科摩羅 葛摩
+科特迪瓦 象牙海岸
+突尼斯 突尼西亞
+索马里 索馬利亞
+索馬里 索馬利亞
+老挝 寮國
+老撾 寮國
+肯尼亚 肯亞
+肯雅 肯亞
+苏里南 蘇利南
+莫桑比克 莫三比克
+莱索托 賴索托
+萊索托 賴索托
+贝宁 貝南
+貝寧 貝南
+赞比亚 尚比亞
+贊比亞 尚比亞
+阿塞拜疆 亞塞拜然
+阿塞拜疆 亞塞拜然
+阿拉伯联合酋长国 阿拉伯聯合大公國
+阿拉伯聯合酋長國 阿拉伯聯合大公國
+韩国 南韓
+马尔代夫 馬爾地夫
+馬爾代夫 馬爾地夫
+马耳他 馬爾他
+马里 馬利
+馬里 馬利
+方便面 速食麵
+快速面 速食麵
+即食麵 速食麵
+薯仔 土豆
+蹦极跳 笨豬跳
+绑紧跳 笨豬跳
+冷菜 冷盤
+凉菜 冷盤
+的士 計程車
+出租车 計程車
+巴士 公車
+公共汽车 公車
+台球 撞球
+桌球 撞球
+雪糕 冰淇淋
+卫生 衛生
+衞生 衛生
+平治 賓士
+奔驰 賓士
+積架 捷豹
+福士 福斯
+雪铁龙 雪鐵龍
+马自达 馬自達
+萬事得 馬自達
+布什 布希
+布殊 布希
+克林顿 柯林頓
+克林頓 柯林頓
+萨达姆 海珊
+薩達姆 海珊
+凡高 梵谷
+狄安娜 黛安娜
+戴安娜 黛安娜
+赫拉 希拉 \ No newline at end of file
diff --git a/includes/zhtable/trad2simp.manual b/includes/zhtable/trad2simp.manual
new file mode 100644
index 000000000000..da069310c675
--- /dev/null
+++ b/includes/zhtable/trad2simp.manual
@@ -0,0 +1,15 @@
+U+056a5嚥|U+054bd咽|
+U+0585a塚|U+051a2冢|
+U+05dbd嶽|U+05cb3岳|
+U+04e99亙|U+04e98亘|
+U+081e5臥|U+05367卧|
+U+04f48佈|U+05e03布|
+U+06dd2淒|U+051c4凄|
+U+06de8淨|U+051c0净|
+U+05147兇|U+051f6凶|
+U+04f48佈|U+05e03布|
+U+06c59汙|U+06c61污|
+U+056ae嚮|U+05411向|
+U+09031週|U+05468周|
+U+0904a遊|U+06e38游|
+U+06de9淩|U+051cc凌|
diff --git a/includes/zhtable/tradphrases.manual b/includes/zhtable/tradphrases.manual
new file mode 100644
index 000000000000..b2fec8152788
--- /dev/null
+++ b/includes/zhtable/tradphrases.manual
@@ -0,0 +1,149 @@
+一隻
+三隻
+四隻
+五隻
+六隻
+七隻
+八隻
+九隻
+十隻
+百隻
+千隻
+萬隻
+億隻
+並存著
+乾絲
+乾著急
+体育鍛鍊
+借著
+偷雞不著
+几絲
+划著
+划著走
+別著
+刮著
+千絲萬縷
+參与
+參与者
+參合
+參考價值
+參與
+參與人員
+參與制
+參與感
+參與者
+參觀團
+參觀團體
+參閱
+吃著不盡
+合著
+合著者
+吊帶褲
+吊掛著
+吊著
+吊褲
+吊褲帶
+向著
+嚴絲合縫
+回絲
+回著
+塗著
+壟斷價格
+壟斷資產
+壟斷集團
+姜絲
+帶團參加
+干著急
+幾絲
+彆著
+怎麼著
+憑藉著
+接著說
+擔著
+擔負著
+敘說著
+斗轉參橫
+旋繞著
+板著臉
+標志著
+正當著
+沈著
+沖著
+派團參加
+涂著
+湊合著
+瀰漫著
+為著
+煙斗絲
+率團參加
+畫著
+當著
+發著
+直接參与
+睡著了
+秋褲
+積极參与
+積极參加
+簽著
+系著
+絕對參照
+絲來線去
+絲布
+絲板
+絲瓜布
+絲絨布
+絲線
+絲織廠
+絲蟲
+緊繃著
+繃著
+繃著臉
+繃著臉兒
+繫著
+罵著
+肉絲麵
+背向著
+菌絲体
+菌絲體
+著兒
+著書立說
+著色軟體
+著重指出
+著錄
+著錄規則
+薑絲
+藉著
+蘊含著
+蘊涵著
+衝著
+被覆著
+覆著
+覆蓋著
+訴說著
+說著
+請參閱
+謝絕參觀
+豎著
+豐濱
+豐濱鄉
+象徵著
+這么著
+這麼著
+那麼著
+配合著
+醞釀著
+錄著
+鍛鍊出
+鍛鍊身体
+關係著
+雞絲
+雞絲麵
+面朝著
+面臨著
+顯著標志
+颳著
+髮絲
+鬥著
+鬧著玩儿
+鬧著玩兒
+鯰魚
diff --git a/index.php b/index.php
new file mode 100644
index 000000000000..e3b753faf603
--- /dev/null
+++ b/index.php
@@ -0,0 +1,55 @@
+<?php
+
+# Initialise common code
+require_once( './includes/WebStart.php' );
+
+# Initialize MediaWiki base class
+require_once( "includes/Wiki.php" );
+$mediaWiki = new MediaWiki();
+
+wfProfileIn( 'main-misc-setup' );
+OutputPage::setEncodings(); # Not really used yet
+
+# Query string fields
+$action = $wgRequest->getVal( 'action', 'view' );
+$title = $wgRequest->getVal( 'title' );
+
+$wgTitle = $mediaWiki->checkInitialQueries( $title,$action,$wgOut, $wgRequest, $wgContLang );
+if ($wgTitle == NULL) {
+ unset( $wgTitle );
+}
+
+#
+# Send Ajax requests to the Ajax dispatcher.
+#
+if ( $wgUseAjax && $action == 'ajax' ) {
+ require_once( $IP . '/includes/AjaxDispatcher.php' );
+
+ $dispatcher = new AjaxDispatcher();
+ $dispatcher->performAction();
+ $mediaWiki->restInPeace( $wgLoadBalancer );
+ exit;
+}
+
+
+wfProfileOut( 'main-misc-setup' );
+
+# Setting global variables in mediaWiki
+$mediaWiki->setVal( 'Server', $wgServer );
+$mediaWiki->setVal( 'DisableInternalSearch', $wgDisableInternalSearch );
+$mediaWiki->setVal( 'action', $action );
+$mediaWiki->setVal( 'SquidMaxage', $wgSquidMaxage );
+$mediaWiki->setVal( 'EnableDublinCoreRdf', $wgEnableDublinCoreRdf );
+$mediaWiki->setVal( 'EnableCreativeCommonsRdf', $wgEnableCreativeCommonsRdf );
+$mediaWiki->setVal( 'CommandLineMode', $wgCommandLineMode );
+$mediaWiki->setVal( 'UseExternalEditor', $wgUseExternalEditor );
+$mediaWiki->setVal( 'DisabledActions', $wgDisabledActions );
+
+$wgArticle = $mediaWiki->initialize ( $wgTitle, $wgOut, $wgUser, $wgRequest );
+$mediaWiki->finalCleanup ( $wgDeferredUpdateList, $wgLoadBalancer, $wgOut );
+
+# Not sure when $wgPostCommitUpdateList gets set, so I keep this separate from finalCleanup
+$mediaWiki->doUpdates( $wgPostCommitUpdateList );
+
+$mediaWiki->restInPeace( $wgLoadBalancer );
+?>
diff --git a/install-utils.inc b/install-utils.inc
new file mode 100644
index 000000000000..84fbc8e86def
--- /dev/null
+++ b/install-utils.inc
@@ -0,0 +1,153 @@
+<?php
+
+function install_version_checks() {
+ # We dare not turn output buffer _off_ since this will break completely
+ # if PHP is globally configured to run through a gzip filter.
+ @ob_implicit_flush( true );
+
+ if( !function_exists( 'version_compare' ) ) {
+ # version_compare was introduced in 4.1.0
+ echo "Your PHP version is much too old; 4.0.x will _not_ work. 5.0.0 or higher is required. ABORTING.\n";
+ die( -1 );
+ }
+ if( version_compare( phpversion(), '5.0.0' ) < 0 ) {
+ echo "PHP 5.0.0 or higher is required. ABORTING.\n";
+ die( -1 );
+ }
+
+ // Test for PHP bug which breaks PHP 5.0.x on 64-bit...
+ // As of 1.8 this breaks lots of common operations instead
+ // of just some rare ones like export.
+ $borked = str_replace( 'a', 'b', array( -1 => -1 ) );
+ if( !isset( $borked[-1] ) ) {
+ echo "PHP 5.0.x is buggy on your 64-bit system; you must upgrade to PHP 5.1.x\n" .
+ "or higher. ABORTING. (http://bugs.php.net/bug.php?id=34879 for details)\n";
+ die( -1 );
+ }
+
+ global $wgCommandLineMode;
+ $wgCommandLineMode = true;
+ umask( 000 );
+ set_time_limit( 0 );
+}
+
+function copyfile( $sdir, $name, $ddir, $perms = 0664 ) {
+ copyfileto( $sdir, $name, $ddir, $name, $perms );
+}
+
+function copyfileto( $sdir, $sname, $ddir, $dname, $perms = 0664 ) {
+ global $wgInstallOwner, $wgInstallGroup;
+
+ $d = "{$ddir}/{$dname}";
+ if ( copy( "{$sdir}/{$sname}", $d ) ) {
+ if ( isset( $wgInstallOwner ) ) { chown( $d, $wgInstallOwner ); }
+ if ( isset( $wgInstallGroup ) ) { chgrp( $d, $wgInstallGroup ); }
+ chmod( $d, $perms );
+ # print "Copied \"{$sname}\" to \"{$d}\".\n";
+ } else {
+ print "Failed to copy file \"{$sname}\" to \"{$ddir}/{$dname}\".\n";
+ exit();
+ }
+}
+
+function copydirectory( $source, $dest ) {
+ $handle = opendir( $source );
+ while ( false !== ( $f = readdir( $handle ) ) ) {
+ $fullname = "$source/$f";
+ if ( $f{0} != '.' && is_file( $fullname ) ) {
+ copyfile( $source, $f, $dest );
+ }
+ }
+}
+
+function readconsole( $prompt = '' ) {
+ static $isatty = null;
+ if ( is_null( $isatty ) ) {
+ if ( !function_exists( 'posix_isatty' ) || posix_isatty( 0 /*STDIN*/ ) ) {
+ $isatty = true;
+ } else {
+ $isatty = false;
+ }
+ }
+
+ if ( $isatty && function_exists( 'readline' ) ) {
+ return readline( $prompt );
+ } else {
+ if ( $isatty ) {
+ print $prompt;
+ }
+ if ( feof( STDIN ) ) {
+ return false;
+ }
+ $st = fgets(STDIN, 1024);
+ if ($st === false) return false;
+ $resp = trim( $st );
+ return $resp;
+ }
+}
+
+#
+# Read and execute SQL commands from a file
+#
+function dbsource( $fname, $db = false ) {
+ if ( !$db ) {
+ // Try $wgDatabase, which is used in the install and update scripts
+ global $wgDatabase;
+ if ( isset( $wgDatabase ) ) {
+ $db =& $wgDatabase;
+ } else {
+ // No? Well, we must be outside of those scripts, so use the standard method
+ $db =& wfGetDB( DB_MASTER );
+ }
+ }
+ $error = $db->sourceFile( $fname );
+ if ( $error !== true ) {
+ print $error;
+ exit(1);
+ }
+}
+
+# Obsolete, use Database::fieldExists()
+function field_exists( $table, $field ) {
+ $fname = 'Update script: field_exists';
+ $db =& wfGetDB( DB_SLAVE );
+ $res = $db->query( "DESCRIBE $table", $fname );
+ $found = false;
+
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( $row->Field == $field ) {
+ $found = true;
+ break;
+ }
+ }
+ return $found;
+}
+
+# Obsolete Database::tableExists()
+function table_exists( $db ) {
+ global $wgDBname;
+ $res = mysql_list_tables( $wgDBname );
+ if( !$res ) {
+ echo "** " . mysql_error() . "\n";
+ return false;
+ }
+ for( $i = mysql_num_rows( $res ) - 1; $i--; $i > 0 ) {
+ if( mysql_tablename( $res, $i ) == $db ) return true;
+ }
+ return false;
+}
+
+# Obsolete, use Database:fieldInfo()
+function field_info( $table, $field ) {
+ $res = mysql_query( "SELECT * FROM $table LIMIT 1" );
+ $n = mysql_num_fields( $res );
+ for( $i = 0; $i < $n; $i++ ) {
+ $meta = mysql_fetch_field( $res, $i );
+ if( $field == $meta->name ) {
+ return $meta;
+ }
+ }
+ return false;
+}
+
+?>
diff --git a/languages/.htaccess b/languages/.htaccess
new file mode 100644
index 000000000000..3a4288278871
--- /dev/null
+++ b/languages/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/languages/Language.php b/languages/Language.php
new file mode 100644
index 000000000000..fd7786e5aa89
--- /dev/null
+++ b/languages/Language.php
@@ -0,0 +1,1779 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+if( !defined( 'MEDIAWIKI' ) ) {
+ echo "This file is part of MediaWiki, it is not a valid entry point.\n";
+ exit( 1 );
+}
+
+#
+# In general you should not make customizations in these language files
+# directly, but should use the MediaWiki: special namespace to customize
+# user interface messages through the wiki.
+# See http://meta.wikipedia.org/wiki/MediaWiki_namespace
+#
+# NOTE TO TRANSLATORS: Do not copy this whole file when making translations!
+# A lot of common constants and a base class with inheritable methods are
+# defined here, which should not be redefined. See the other LanguageXx.php
+# files for examples.
+#
+
+# Read language names
+global $wgLanguageNames;
+require_once( 'Names.php' );
+
+global $wgInputEncoding, $wgOutputEncoding;
+
+/**
+ * These are always UTF-8, they exist only for backwards compatibility
+ */
+$wgInputEncoding = "UTF-8";
+$wgOutputEncoding = "UTF-8";
+
+if( function_exists( 'mb_strtoupper' ) ) {
+ mb_internal_encoding('UTF-8');
+}
+
+/* a fake language converter */
+class FakeConverter {
+ var $mLang;
+ function FakeConverter($langobj) {$this->mLang = $langobj;}
+ function convert($t, $i) {return $t;}
+ function parserConvert($t, $p) {return $t;}
+ function getVariants() { return array( $this->mLang->getCode() ); }
+ function getPreferredVariant() {return $this->mLang->getCode(); }
+ function findVariantLink(&$l, &$n) {}
+ function getExtraHashOptions() {return '';}
+ function getParsedTitle() {return '';}
+ function markNoConversion($text, $noParse=false) {return $text;}
+ function convertCategoryKey( $key ) {return $key; }
+ function convertLinkToAllVariants($text){ return array( $this->mLang->getCode() => $text); }
+ function armourMath($text){ return $text; }
+}
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class Language {
+ var $mConverter, $mVariants, $mCode, $mLoaded = false;
+
+ static public $mLocalisationKeys = array( 'fallback', 'namespaceNames',
+ 'quickbarSettings', 'skinNames', 'mathNames',
+ 'bookstoreList', 'magicWords', 'messages', 'rtl', 'digitTransformTable',
+ 'separatorTransformTable', 'fallback8bitEncoding', 'linkPrefixExtension',
+ 'defaultUserOptionOverrides', 'linkTrail', 'namespaceAliases',
+ 'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
+ 'defaultDateFormat', 'extraUserToggles', 'specialPageAliases' );
+
+ static public $mMergeableMapKeys = array( 'messages', 'namespaceNames', 'mathNames',
+ 'dateFormats', 'defaultUserOptionOverrides', 'magicWords' );
+
+ static public $mMergeableListKeys = array( 'extraUserToggles' );
+
+ static public $mMergeableAliasListKeys = array( 'specialPageAliases' );
+
+ static public $mLocalisationCache = array();
+
+ static public $mWeekdayMsgs = array(
+ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
+ 'friday', 'saturday'
+ );
+
+ static public $mWeekdayAbbrevMsgs = array(
+ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'
+ );
+
+ static public $mMonthMsgs = array(
+ 'january', 'february', 'march', 'april', 'may_long', 'june',
+ 'july', 'august', 'september', 'october', 'november',
+ 'december'
+ );
+ static public $mMonthGenMsgs = array(
+ 'january-gen', 'february-gen', 'march-gen', 'april-gen', 'may-gen', 'june-gen',
+ 'july-gen', 'august-gen', 'september-gen', 'october-gen', 'november-gen',
+ 'december-gen'
+ );
+ static public $mMonthAbbrevMsgs = array(
+ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug',
+ 'sep', 'oct', 'nov', 'dec'
+ );
+
+ /**
+ * Create a language object for a given language code
+ */
+ static function factory( $code ) {
+ global $IP;
+ static $recursionLevel = 0;
+
+ if ( $code == 'en' ) {
+ $class = 'Language';
+ } else {
+ $class = 'Language' . str_replace( '-', '_', ucfirst( $code ) );
+ // Preload base classes to work around APC/PHP5 bug
+ if ( file_exists( "$IP/languages/classes/$class.deps.php" ) ) {
+ include_once("$IP/languages/classes/$class.deps.php");
+ }
+ if ( file_exists( "$IP/languages/classes/$class.php" ) ) {
+ include_once("$IP/languages/classes/$class.php");
+ }
+ }
+
+ if ( $recursionLevel > 5 ) {
+ throw new MWException( "Language fallback loop detected when creating class $class\n" );
+ }
+
+ if( ! class_exists( $class ) ) {
+ $fallback = Language::getFallbackFor( $code );
+ ++$recursionLevel;
+ $lang = Language::factory( $fallback );
+ --$recursionLevel;
+ $lang->setCode( $code );
+ } else {
+ $lang = new $class;
+ }
+
+ return $lang;
+ }
+
+ function __construct() {
+ $this->mConverter = new FakeConverter($this);
+ // Set the code to the name of the descendant
+ if ( get_class( $this ) == 'Language' ) {
+ $this->mCode = 'en';
+ } else {
+ $this->mCode = str_replace( '_', '-', strtolower( substr( get_class( $this ), 8 ) ) );
+ }
+ }
+
+ /**
+ * Hook which will be called if this is the content language.
+ * Descendants can use this to register hook functions or modify globals
+ */
+ function initContLang() {}
+
+ /**
+ * @deprecated
+ * @return array
+ */
+ function getDefaultUserOptions() {
+ return User::getDefaultOptions();
+ }
+
+ /**
+ * Exports $wgBookstoreListEn
+ * @return array
+ */
+ function getBookstoreList() {
+ $this->load();
+ return $this->bookstoreList;
+ }
+
+ /**
+ * @return array
+ */
+ function getNamespaces() {
+ $this->load();
+ return $this->namespaceNames;
+ }
+
+ /**
+ * A convenience function that returns the same thing as
+ * getNamespaces() except with the array values changed to ' '
+ * where it found '_', useful for producing output to be displayed
+ * e.g. in <select> forms.
+ *
+ * @return array
+ */
+ function getFormattedNamespaces() {
+ $ns = $this->getNamespaces();
+ foreach($ns as $k => $v) {
+ $ns[$k] = strtr($v, '_', ' ');
+ }
+ return $ns;
+ }
+
+ /**
+ * Get a namespace value by key
+ * <code>
+ * $mw_ns = $wgContLang->getNsText( NS_MEDIAWIKI );
+ * echo $mw_ns; // prints 'MediaWiki'
+ * </code>
+ *
+ * @param int $index the array key of the namespace to return
+ * @return mixed, string if the namespace value exists, otherwise false
+ */
+ function getNsText( $index ) {
+ $ns = $this->getNamespaces();
+ return isset( $ns[$index] ) ? $ns[$index] : false;
+ }
+
+ /**
+ * A convenience function that returns the same thing as
+ * getNsText() except with '_' changed to ' ', useful for
+ * producing output.
+ *
+ * @return array
+ */
+ function getFormattedNsText( $index ) {
+ $ns = $this->getNsText( $index );
+ return strtr($ns, '_', ' ');
+ }
+
+ /**
+ * Get a namespace key by value, case insensetive.
+ *
+ * @param string $text
+ * @return mixed An integer if $text is a valid value otherwise false
+ */
+ function getNsIndex( $text ) {
+ $this->load();
+ $lctext = $this->lc($text);
+ return isset( $this->mNamespaceIds[$lctext] ) ? $this->mNamespaceIds[$lctext] : false;
+ }
+
+ /**
+ * short names for language variants used for language conversion links.
+ *
+ * @param string $code
+ * @return string
+ */
+ function getVariantname( $code ) {
+ return $this->getMessageFromDB( "variantname-$code" );
+ }
+
+ function specialPage( $name ) {
+ $aliases = $this->getSpecialPageAliases();
+ if ( isset( $aliases[$name][0] ) ) {
+ $name = $aliases[$name][0];
+ }
+ return $this->getNsText(NS_SPECIAL) . ':' . $name;
+ }
+
+ function getQuickbarSettings() {
+ $this->load();
+ return $this->quickbarSettings;
+ }
+
+ function getSkinNames() {
+ $this->load();
+ return $this->skinNames;
+ }
+
+ function getMathNames() {
+ $this->load();
+ return $this->mathNames;
+ }
+
+ function getDatePreferences() {
+ $this->load();
+ return $this->datePreferences;
+ }
+
+ function getDateFormats() {
+ $this->load();
+ return $this->dateFormats;
+ }
+
+ function getDefaultDateFormat() {
+ $this->load();
+ return $this->defaultDateFormat;
+ }
+
+ function getDatePreferenceMigrationMap() {
+ $this->load();
+ return $this->datePreferenceMigrationMap;
+ }
+
+ function getDefaultUserOptionOverrides() {
+ $this->load();
+ return $this->defaultUserOptionOverrides;
+ }
+
+ function getExtraUserToggles() {
+ $this->load();
+ return $this->extraUserToggles;
+ }
+
+ function getUserToggle( $tog ) {
+ return $this->getMessageFromDB( "tog-$tog" );
+ }
+
+ /**
+ * Get language names, indexed by code.
+ * If $customisedOnly is true, only returns codes with a messages file
+ */
+ public static function getLanguageNames( $customisedOnly = false ) {
+ global $wgLanguageNames;
+ if ( !$customisedOnly ) {
+ return $wgLanguageNames;
+ }
+
+ global $IP;
+ $messageFiles = glob( "$IP/languages/messages/Messages*.php" );
+ $names = array();
+ foreach ( $messageFiles as $file ) {
+ if( preg_match( '/Messages([A-Z][a-z_]+)\.php$/', $file, $m ) ) {
+ $code = str_replace( '_', '-', strtolower( $m[1] ) );
+ if ( isset( $wgLanguageNames[$code] ) ) {
+ $names[$code] = $wgLanguageNames[$code];
+ }
+ }
+ }
+ return $names;
+ }
+
+ /**
+ * Ugly hack to get a message maybe from the MediaWiki namespace, if this
+ * language object is the content or user language.
+ */
+ function getMessageFromDB( $msg ) {
+ global $wgContLang, $wgLang;
+ if ( $wgContLang->getCode() == $this->getCode() ) {
+ # Content language
+ return wfMsgForContent( $msg );
+ } elseif ( $wgLang->getCode() == $this->getCode() ) {
+ # User language
+ return wfMsg( $msg );
+ } else {
+ # Neither, get from localisation
+ return $this->getMessage( $msg );
+ }
+ }
+
+ function getLanguageName( $code ) {
+ global $wgLanguageNames;
+ if ( ! array_key_exists( $code, $wgLanguageNames ) ) {
+ return '';
+ }
+ return $wgLanguageNames[$code];
+ }
+
+ function getMonthName( $key ) {
+ return $this->getMessageFromDB( self::$mMonthMsgs[$key-1] );
+ }
+
+ function getMonthNameGen( $key ) {
+ return $this->getMessageFromDB( self::$mMonthGenMsgs[$key-1] );
+ }
+
+ function getMonthAbbreviation( $key ) {
+ return $this->getMessageFromDB( self::$mMonthAbbrevMsgs[$key-1] );
+ }
+
+ function getWeekdayName( $key ) {
+ return $this->getMessageFromDB( self::$mWeekdayMsgs[$key-1] );
+ }
+
+ function getWeekdayAbbreviation( $key ) {
+ return $this->getMessageFromDB( self::$mWeekdayAbbrevMsgs[$key-1] );
+ }
+
+ /**
+ * Used by date() and time() to adjust the time output.
+ * @public
+ * @param int $ts the time in date('YmdHis') format
+ * @param mixed $tz adjust the time by this amount (default false,
+ * mean we get user timecorrection setting)
+ * @return int
+ */
+ function userAdjust( $ts, $tz = false ) {
+ global $wgUser, $wgLocalTZoffset;
+
+ if (!$tz) {
+ $tz = $wgUser->getOption( 'timecorrection' );
+ }
+
+ # minutes and hours differences:
+ $minDiff = 0;
+ $hrDiff = 0;
+
+ if ( $tz === '' ) {
+ # Global offset in minutes.
+ if( isset($wgLocalTZoffset) ) {
+ $hrDiff = $wgLocalTZoffset % 60;
+ $minDiff = $wgLocalTZoffset - ($hrDiff * 60);
+ }
+ } elseif ( strpos( $tz, ':' ) !== false ) {
+ $tzArray = explode( ':', $tz );
+ $hrDiff = intval($tzArray[0]);
+ $minDiff = intval($hrDiff < 0 ? -$tzArray[1] : $tzArray[1]);
+ } else {
+ $hrDiff = intval( $tz );
+ }
+
+ # No difference ? Return time unchanged
+ if ( 0 == $hrDiff && 0 == $minDiff ) { return $ts; }
+
+ # Generate an adjusted date
+ $t = mktime( (
+ (int)substr( $ts, 8, 2) ) + $hrDiff, # Hours
+ (int)substr( $ts, 10, 2 ) + $minDiff, # Minutes
+ (int)substr( $ts, 12, 2 ), # Seconds
+ (int)substr( $ts, 4, 2 ), # Month
+ (int)substr( $ts, 6, 2 ), # Day
+ (int)substr( $ts, 0, 4 ) ); #Year
+ return date( 'YmdHis', $t );
+ }
+
+ /**
+ * This is a workalike of PHP's date() function, but with better
+ * internationalisation, a reduced set of format characters, and a better
+ * escaping format.
+ *
+ * Supported format characters are dDjlNwzWFmMntLYyaAgGhHiscrU. See the
+ * PHP manual for definitions. There are a number of extensions, which
+ * start with "x":
+ *
+ * xn Do not translate digits of the next numeric format character
+ * xN Toggle raw digit (xn) flag, stays set until explicitly unset
+ * xr Use roman numerals for the next numeric format character
+ * xx Literal x
+ * xg Genitive month name
+ *
+ * Characters enclosed in double quotes will be considered literal (with
+ * the quotes themselves removed). Unmatched quotes will be considered
+ * literal quotes. Example:
+ *
+ * "The month is" F => The month is January
+ * i's" => 20'11"
+ *
+ * Backslash escaping is also supported.
+ *
+ * @param string $format
+ * @param string $ts 14-character timestamp
+ * YYYYMMDDHHMMSS
+ * 01234567890123
+ */
+ function sprintfDate( $format, $ts ) {
+ $s = '';
+ $raw = false;
+ $roman = false;
+ $unix = false;
+ $rawToggle = false;
+ for ( $p = 0; $p < strlen( $format ); $p++ ) {
+ $num = false;
+ $code = $format[$p];
+ if ( $code == 'x' && $p < strlen( $format ) - 1 ) {
+ $code .= $format[++$p];
+ }
+
+ switch ( $code ) {
+ case 'xx':
+ $s .= 'x';
+ break;
+ case 'xn':
+ $raw = true;
+ break;
+ case 'xN':
+ $rawToggle = !$rawToggle;
+ break;
+ case 'xr':
+ $roman = true;
+ break;
+ case 'xg':
+ $s .= $this->getMonthNameGen( substr( $ts, 4, 2 ) );
+ break;
+ case 'd':
+ $num = substr( $ts, 6, 2 );
+ break;
+ case 'D':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= $this->getWeekdayAbbreviation( date( 'w', $unix ) + 1 );
+ break;
+ case 'j':
+ $num = intval( substr( $ts, 6, 2 ) );
+ break;
+ case 'l':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= $this->getWeekdayName( date( 'w', $unix ) + 1 );
+ break;
+ case 'N':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $w = date( 'w', $unix );
+ $num = $w ? $w : 7;
+ break;
+ case 'w':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'w', $unix );
+ break;
+ case 'z':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'z', $unix );
+ break;
+ case 'W':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'W', $unix );
+ break;
+ case 'F':
+ $s .= $this->getMonthName( substr( $ts, 4, 2 ) );
+ break;
+ case 'm':
+ $num = substr( $ts, 4, 2 );
+ break;
+ case 'M':
+ $s .= $this->getMonthAbbreviation( substr( $ts, 4, 2 ) );
+ break;
+ case 'n':
+ $num = intval( substr( $ts, 4, 2 ) );
+ break;
+ case 't':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 't', $unix );
+ break;
+ case 'L':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = date( 'L', $unix );
+ break;
+ case 'Y':
+ $num = substr( $ts, 0, 4 );
+ break;
+ case 'y':
+ $num = substr( $ts, 2, 2 );
+ break;
+ case 'a':
+ $s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'am' : 'pm';
+ break;
+ case 'A':
+ $s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'AM' : 'PM';
+ break;
+ case 'g':
+ $h = substr( $ts, 8, 2 );
+ $num = $h % 12 ? $h % 12 : 12;
+ break;
+ case 'G':
+ $num = intval( substr( $ts, 8, 2 ) );
+ break;
+ case 'h':
+ $h = substr( $ts, 8, 2 );
+ $num = sprintf( '%02d', $h % 12 ? $h % 12 : 12 );
+ break;
+ case 'H':
+ $num = substr( $ts, 8, 2 );
+ break;
+ case 'i':
+ $num = substr( $ts, 10, 2 );
+ break;
+ case 's':
+ $num = substr( $ts, 12, 2 );
+ break;
+ case 'c':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= date( 'c', $unix );
+ break;
+ case 'r':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $s .= date( 'r', $unix );
+ break;
+ case 'U':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ $num = $unix;
+ break;
+ case '\\':
+ # Backslash escaping
+ if ( $p < strlen( $format ) - 1 ) {
+ $s .= $format[++$p];
+ } else {
+ $s .= '\\';
+ }
+ break;
+ case '"':
+ # Quoted literal
+ if ( $p < strlen( $format ) - 1 ) {
+ $endQuote = strpos( $format, '"', $p + 1 );
+ if ( $endQuote === false ) {
+ # No terminating quote, assume literal "
+ $s .= '"';
+ } else {
+ $s .= substr( $format, $p + 1, $endQuote - $p - 1 );
+ $p = $endQuote;
+ }
+ } else {
+ # Quote at end of string, assume literal "
+ $s .= '"';
+ }
+ break;
+ default:
+ $s .= $format[$p];
+ }
+ if ( $num !== false ) {
+ if ( $rawToggle || $raw ) {
+ $s .= $num;
+ $raw = false;
+ } elseif ( $roman ) {
+ $s .= self::romanNumeral( $num );
+ $roman = false;
+ } else {
+ $s .= $this->formatNum( $num, true );
+ }
+ $num = false;
+ }
+ }
+ return $s;
+ }
+
+ /**
+ * Roman number formatting up to 3000
+ */
+ static function romanNumeral( $num ) {
+ static $table = array(
+ array( '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X' ),
+ array( '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', 'C' ),
+ array( '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', 'M' ),
+ array( '', 'M', 'MM', 'MMM' )
+ );
+
+ $num = intval( $num );
+ if ( $num > 3000 || $num <= 0 ) {
+ return $num;
+ }
+
+ $s = '';
+ for ( $pow10 = 1000, $i = 3; $i >= 0; $pow10 /= 10, $i-- ) {
+ if ( $num >= $pow10 ) {
+ $s .= $table[$i][floor($num / $pow10)];
+ }
+ $num = $num % $pow10;
+ }
+ return $s;
+ }
+
+ /**
+ * This is meant to be used by time(), date(), and timeanddate() to get
+ * the date preference they're supposed to use, it should be used in
+ * all children.
+ *
+ *<code>
+ * function timeanddate([...], $format = true) {
+ * $datePreference = $this->dateFormat($format);
+ * [...]
+ * }
+ *</code>
+ *
+ * @param mixed $usePrefs: if true, the user's preference is used
+ * if false, the site/language default is used
+ * if int/string, assumed to be a format.
+ * @return string
+ */
+ function dateFormat( $usePrefs = true ) {
+ global $wgUser;
+
+ if( is_bool( $usePrefs ) ) {
+ if( $usePrefs ) {
+ $datePreference = $wgUser->getDatePreference();
+ } else {
+ $options = User::getDefaultOptions();
+ $datePreference = (string)$options['date'];
+ }
+ } else {
+ $datePreference = (string)$usePrefs;
+ }
+
+ // return int
+ if( $datePreference == '' ) {
+ return 'default';
+ }
+
+ return $datePreference;
+ }
+
+ /**
+ * @public
+ * @param mixed $ts the time format which needs to be turned into a
+ * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
+ * @param bool $adj whether to adjust the time output according to the
+ * user configured offset ($timecorrection)
+ * @param mixed $format true to use user's date format preference
+ * @param string $timecorrection the time offset as returned by
+ * validateTimeZone() in Special:Preferences
+ * @return string
+ */
+ function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
+ $this->load();
+ if ( $adj ) {
+ $ts = $this->userAdjust( $ts, $timecorrection );
+ }
+
+ $pref = $this->dateFormat( $format );
+ if( $pref == 'default' || !isset( $this->dateFormats["$pref date"] ) ) {
+ $pref = $this->defaultDateFormat;
+ }
+ return $this->sprintfDate( $this->dateFormats["$pref date"], $ts );
+ }
+
+ /**
+ * @public
+ * @param mixed $ts the time format which needs to be turned into a
+ * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
+ * @param bool $adj whether to adjust the time output according to the
+ * user configured offset ($timecorrection)
+ * @param mixed $format true to use user's date format preference
+ * @param string $timecorrection the time offset as returned by
+ * validateTimeZone() in Special:Preferences
+ * @return string
+ */
+ function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
+ $this->load();
+ if ( $adj ) {
+ $ts = $this->userAdjust( $ts, $timecorrection );
+ }
+
+ $pref = $this->dateFormat( $format );
+ if( $pref == 'default' || !isset( $this->dateFormats["$pref time"] ) ) {
+ $pref = $this->defaultDateFormat;
+ }
+ return $this->sprintfDate( $this->dateFormats["$pref time"], $ts );
+ }
+
+ /**
+ * @public
+ * @param mixed $ts the time format which needs to be turned into a
+ * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
+ * @param bool $adj whether to adjust the time output according to the
+ * user configured offset ($timecorrection)
+
+ * @param mixed $format what format to return, if it's false output the
+ * default one (default true)
+ * @param string $timecorrection the time offset as returned by
+ * validateTimeZone() in Special:Preferences
+ * @return string
+ */
+ function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false) {
+ $this->load();
+ if ( $adj ) {
+ $ts = $this->userAdjust( $ts, $timecorrection );
+ }
+
+ $pref = $this->dateFormat( $format );
+ if( $pref == 'default' || !isset( $this->dateFormats["$pref both"] ) ) {
+ $pref = $this->defaultDateFormat;
+ }
+
+ return $this->sprintfDate( $this->dateFormats["$pref both"], $ts );
+ }
+
+ function getMessage( $key ) {
+ $this->load();
+ return isset( $this->messages[$key] ) ? $this->messages[$key] : null;
+ }
+
+ function getAllMessages() {
+ $this->load();
+ return $this->messages;
+ }
+
+ function iconv( $in, $out, $string ) {
+ # For most languages, this is a wrapper for iconv
+ return iconv( $in, $out, $string );
+ }
+
+ // callback functions for uc(), lc(), ucwords(), ucwordbreaks()
+ function ucwordbreaksCallbackAscii($matches){
+ return $this->ucfirst($matches[1]);
+ }
+
+ function ucwordbreaksCallbackMB($matches){
+ return mb_strtoupper($matches[0]);
+ }
+
+ function ucCallback($matches){
+ list( $wikiUpperChars ) = self::getCaseMaps();
+ return strtr( $matches[1], $wikiUpperChars );
+ }
+
+ function lcCallback($matches){
+ list( , $wikiLowerChars ) = self::getCaseMaps();
+ return strtr( $matches[1], $wikiLowerChars );
+ }
+
+ function ucwordsCallbackMB($matches){
+ return mb_strtoupper($matches[0]);
+ }
+
+ function ucwordsCallbackWiki($matches){
+ list( $wikiUpperChars ) = self::getCaseMaps();
+ return strtr( $matches[0], $wikiUpperChars );
+ }
+
+ function ucfirst( $str ) {
+ return self::uc( $str, true );
+ }
+
+ function uc( $str, $first = false ) {
+ if ( function_exists( 'mb_strtoupper' ) )
+ if ( $first )
+ if ( self::isMultibyte( $str ) )
+ return mb_strtoupper( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
+ else
+ return ucfirst( $str );
+ else
+ return self::isMultibyte( $str ) ? mb_strtoupper( $str ) : strtoupper( $str );
+ else
+ if ( self::isMultibyte( $str ) ) {
+ list( $wikiUpperChars ) = $this->getCaseMaps();
+ $x = $first ? '^' : '';
+ return preg_replace_callback(
+ "/$x([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
+ array($this,"ucCallback"),
+ $str
+ );
+ } else
+ return $first ? ucfirst( $str ) : strtoupper( $str );
+ }
+
+ function lcfirst( $str ) {
+ return self::lc( $str, true );
+ }
+
+ function lc( $str, $first = false ) {
+ if ( function_exists( 'mb_strtolower' ) )
+ if ( $first )
+ if ( self::isMultibyte( $str ) )
+ return mb_strtolower( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
+ else
+ return strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 );
+ else
+ return self::isMultibyte( $str ) ? mb_strtolower( $str ) : strtolower( $str );
+ else
+ if ( self::isMultibyte( $str ) ) {
+ list( , $wikiLowerChars ) = self::getCaseMaps();
+ $x = $first ? '^' : '';
+ return preg_replace_callback(
+ "/$x([A-Z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
+ array($this,"lcCallback"),
+ $str
+ );
+ } else
+ return $first ? strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 ) : strtolower( $str );
+ }
+
+ function isMultibyte( $str ) {
+ return (bool)preg_match( '/[\x80-\xff]/', $str );
+ }
+
+ function ucwords($str) {
+ if ( self::isMultibyte( $str ) ) {
+ $str = self::lc($str);
+
+ // regexp to find first letter in each word (i.e. after each space)
+ $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)| ([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
+
+ // function to use to capitalize a single char
+ if ( function_exists( 'mb_strtoupper' ) )
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordsCallbackMB"),
+ $str
+ );
+ else
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordsCallbackWiki"),
+ $str
+ );
+ }
+ else
+ return ucwords( strtolower( $str ) );
+ }
+
+ # capitalize words at word breaks
+ function ucwordbreaks($str){
+ if (self::isMultibyte( $str ) ) {
+ $str = self::lc($str);
+
+ // since \b doesn't work for UTF-8, we explicitely define word break chars
+ $breaks= "[ \-\(\)\}\{\.,\?!]";
+
+ // find first letter after word break
+ $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)|$breaks([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
+
+ if ( function_exists( 'mb_strtoupper' ) )
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordbreaksCallbackMB"),
+ $str
+ );
+ else
+ return preg_replace_callback(
+ $replaceRegexp,
+ array($this,"ucwordsCallbackWiki"),
+ $str
+ );
+ }
+ else
+ return preg_replace_callback(
+ '/\b([\w\x80-\xff]+)\b/',
+ array($this,"ucwordbreaksCallbackAscii"),
+ $str );
+ }
+
+ /**
+ * Return a case-folded representation of $s
+ *
+ * This is a representation such that caseFold($s1)==caseFold($s2) if $s1
+ * and $s2 are the same except for the case of their characters. It is not
+ * necessary for the value returned to make sense when displayed.
+ *
+ * Do *not* perform any other normalisation in this function. If a caller
+ * uses this function when it should be using a more general normalisation
+ * function, then fix the caller.
+ */
+ function caseFold( $s ) {
+ return $this->uc( $s );
+ }
+
+ function checkTitleEncoding( $s ) {
+ if( is_array( $s ) ) {
+ wfDebugDieBacktrace( 'Given array to checkTitleEncoding.' );
+ }
+ # Check for non-UTF-8 URLs
+ $ishigh = preg_match( '/[\x80-\xff]/', $s);
+ if(!$ishigh) return $s;
+
+ $isutf8 = preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
+ if( $isutf8 ) return $s;
+
+ return $this->iconv( $this->fallback8bitEncoding(), "utf-8", $s );
+ }
+
+ function fallback8bitEncoding() {
+ $this->load();
+ return $this->fallback8bitEncoding;
+ }
+
+ /**
+ * Some languages have special punctuation to strip out
+ * or characters which need to be converted for MySQL's
+ * indexing to grok it correctly. Make such changes here.
+ *
+ * @param string $in
+ * @return string
+ */
+ function stripForSearch( $string ) {
+ global $wgDBtype;
+ if ( $wgDBtype != 'mysql' ) {
+ return $string;
+ }
+
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+
+ wfProfileIn( __METHOD__ );
+ if( function_exists( 'mb_strtolower' ) ) {
+ $out = preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "'U8' . bin2hex( \"$1\" )",
+ mb_strtolower( $string ) );
+ } else {
+ list( , $wikiLowerChars ) = self::getCaseMaps();
+ $out = preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "'U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
+ $string );
+ }
+ wfProfileOut( __METHOD__ );
+ return $out;
+ }
+
+ function convertForSearchResult( $termsArray ) {
+ # some languages, e.g. Chinese, need to do a conversion
+ # in order for search results to be displayed correctly
+ return $termsArray;
+ }
+
+ /**
+ * Get the first character of a string.
+ *
+ * @param string $s
+ * @return string
+ */
+ function firstChar( $s ) {
+ preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})/', $s, $matches);
+
+ return isset( $matches[1] ) ? $matches[1] : "";
+ }
+
+ function initEncoding() {
+ # Some languages may have an alternate char encoding option
+ # (Esperanto X-coding, Japanese furigana conversion, etc)
+ # If this language is used as the primary content language,
+ # an override to the defaults can be set here on startup.
+ }
+
+ function recodeForEdit( $s ) {
+ # For some languages we'll want to explicitly specify
+ # which characters make it into the edit box raw
+ # or are converted in some way or another.
+ # Note that if wgOutputEncoding is different from
+ # wgInputEncoding, this text will be further converted
+ # to wgOutputEncoding.
+ global $wgEditEncoding;
+ if( $wgEditEncoding == '' or
+ $wgEditEncoding == 'UTF-8' ) {
+ return $s;
+ } else {
+ return $this->iconv( 'UTF-8', $wgEditEncoding, $s );
+ }
+ }
+
+ function recodeInput( $s ) {
+ # Take the previous into account.
+ global $wgEditEncoding;
+ if($wgEditEncoding != "") {
+ $enc = $wgEditEncoding;
+ } else {
+ $enc = 'UTF-8';
+ }
+ if( $enc == 'UTF-8' ) {
+ return $s;
+ } else {
+ return $this->iconv( $enc, 'UTF-8', $s );
+ }
+ }
+
+ /**
+ * For right-to-left language support
+ *
+ * @return bool
+ */
+ function isRTL() {
+ $this->load();
+ return $this->rtl;
+ }
+
+ /**
+ * A hidden direction mark (LRM or RLM), depending on the language direction
+ *
+ * @return string
+ */
+ function getDirMark() {
+ return $this->isRTL() ? "\xE2\x80\x8F" : "\xE2\x80\x8E";
+ }
+
+ /**
+ * An arrow, depending on the language direction
+ *
+ * @return string
+ */
+ function getArrow() {
+ return $this->isRTL() ? '←' : '→';
+ }
+
+ /**
+ * To allow "foo[[bar]]" to extend the link over the whole word "foobar"
+ *
+ * @return bool
+ */
+ function linkPrefixExtension() {
+ $this->load();
+ return $this->linkPrefixExtension;
+ }
+
+ function &getMagicWords() {
+ $this->load();
+ return $this->magicWords;
+ }
+
+ # Fill a MagicWord object with data from here
+ function getMagic( &$mw ) {
+ if ( !isset( $this->mMagicExtensions ) ) {
+ $this->mMagicExtensions = array();
+ wfRunHooks( 'LanguageGetMagic', array( &$this->mMagicExtensions, $this->getCode() ) );
+ }
+ if ( isset( $this->mMagicExtensions[$mw->mId] ) ) {
+ $rawEntry = $this->mMagicExtensions[$mw->mId];
+ } else {
+ $magicWords =& $this->getMagicWords();
+ if ( isset( $magicWords[$mw->mId] ) ) {
+ $rawEntry = $magicWords[$mw->mId];
+ } else {
+ # Fall back to English if local list is incomplete
+ $magicWords =& Language::getMagicWords();
+ $rawEntry = $magicWords[$mw->mId];
+ }
+ }
+
+ if( !is_array( $rawEntry ) ) {
+ error_log( "\"$rawEntry\" is not a valid magic thingie for \"$mw->mId\"" );
+ }
+ $mw->mCaseSensitive = $rawEntry[0];
+ $mw->mSynonyms = array_slice( $rawEntry, 1 );
+ }
+
+ /**
+ * Get special page names, as an associative array
+ * case folded alias => real name
+ */
+ function getSpecialPageAliases() {
+ $this->load();
+ if ( !isset( $this->mExtendedSpecialPageAliases ) ) {
+ $this->mExtendedSpecialPageAliases = $this->specialPageAliases;
+ wfRunHooks( 'LangugeGetSpecialPageAliases',
+ array( &$this->mExtendedSpecialPageAliases, $this->getCode() ) );
+ }
+ return $this->mExtendedSpecialPageAliases;
+ }
+
+ /**
+ * Italic is unsuitable for some languages
+ *
+ * @public
+ *
+ * @param string $text The text to be emphasized.
+ * @return string
+ */
+ function emphasize( $text ) {
+ return "<em>$text</em>";
+ }
+
+ /**
+ * Normally we output all numbers in plain en_US style, that is
+ * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
+ * point twohundredthirtyfive. However this is not sutable for all
+ * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
+ * Icelandic just want to use commas instead of dots, and dots instead
+ * of commas like "293.291,235".
+ *
+ * An example of this function being called:
+ * <code>
+ * wfMsg( 'message', $wgLang->formatNum( $num ) )
+ * </code>
+ *
+ * See LanguageGu.php for the Gujarati implementation and
+ * LanguageIs.php for the , => . and . => , implementation.
+ *
+ * @todo check if it's viable to use localeconv() for the decimal
+ * seperator thing.
+ * @public
+ * @param mixed $number the string to be formatted, should be an integer or
+ * a floating point number.
+ * @param bool $nocommafy Set to true for special numbers like dates
+ * @return string
+ */
+ function formatNum( $number, $nocommafy = false ) {
+ global $wgTranslateNumerals;
+ if (!$nocommafy) {
+ $number = $this->commafy($number);
+ $s = $this->separatorTransformTable();
+ if (!is_null($s)) { $number = strtr($number, $s); }
+ }
+
+ if ($wgTranslateNumerals) {
+ $s = $this->digitTransformTable();
+ if (!is_null($s)) { $number = strtr($number, $s); }
+ }
+
+ return $number;
+ }
+
+ function parseFormattedNumber( $number ) {
+ $s = $this->digitTransformTable();
+ if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
+
+ $s = $this->separatorTransformTable();
+ if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
+
+ $number = strtr( $number, array (',' => '') );
+ return $number;
+ }
+
+ /**
+ * Adds commas to a given number
+ *
+ * @param mixed $_
+ * @return string
+ */
+ function commafy($_) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ }
+
+ function digitTransformTable() {
+ $this->load();
+ return $this->digitTransformTable;
+ }
+
+ function separatorTransformTable() {
+ $this->load();
+ return $this->separatorTransformTable;
+ }
+
+
+ /**
+ * For the credit list in includes/Credits.php (action=credits)
+ *
+ * @param array $l
+ * @return string
+ */
+ function listToText( $l ) {
+ $s = '';
+ $m = count($l) - 1;
+ for ($i = $m; $i >= 0; $i--) {
+ if ($i == $m) {
+ $s = $l[$i];
+ } else if ($i == $m - 1) {
+ $s = $l[$i] . ' ' . $this->getMessageFromDB( 'and' ) . ' ' . $s;
+ } else {
+ $s = $l[$i] . ', ' . $s;
+ }
+ }
+ return $s;
+ }
+
+ # Crop a string from the beginning or end to a certain number of bytes.
+ # (Bytes are used because our storage has limited byte lengths for some
+ # columns in the database.) Multibyte charsets will need to make sure that
+ # only whole characters are included!
+ #
+ # $length does not include the optional ellipsis.
+ # If $length is negative, snip from the beginning
+ function truncate( $string, $length, $ellipsis = "" ) {
+ if( $length == 0 ) {
+ return $ellipsis;
+ }
+ if ( strlen( $string ) <= abs( $length ) ) {
+ return $string;
+ }
+ if( $length > 0 ) {
+ $string = substr( $string, 0, $length );
+ $char = ord( $string[strlen( $string ) - 1] );
+ if ($char >= 0xc0) {
+ # We got the first byte only of a multibyte char; remove it.
+ $string = substr( $string, 0, -1 );
+ } elseif( $char >= 0x80 &&
+ preg_match( '/^(.*)(?:[\xe0-\xef][\x80-\xbf]|' .
+ '[\xf0-\xf7][\x80-\xbf]{1,2})$/', $string, $m ) ) {
+ # We chopped in the middle of a character; remove it
+ $string = $m[1];
+ }
+ return $string . $ellipsis;
+ } else {
+ $string = substr( $string, $length );
+ $char = ord( $string[0] );
+ if( $char >= 0x80 && $char < 0xc0 ) {
+ # We chopped in the middle of a character; remove the whole thing
+ $string = preg_replace( '/^[\x80-\xbf]+/', '', $string );
+ }
+ return $ellipsis . $string;
+ }
+ }
+
+ /**
+ * Grammatical transformations, needed for inflected languages
+ * Invoked by putting {{grammar:case|word}} in a message
+ *
+ * @param string $word
+ * @param string $case
+ * @return string
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['en'][$case][$word]) ) {
+ return $wgGrammarForms['en'][$case][$word];
+ }
+ return $word;
+ }
+
+ /**
+ * Plural form transformations, needed for some languages.
+ * For example, where are 3 form of plural in Russian and Polish,
+ * depending on "count mod 10". See [[w:Plural]]
+ * For English it is pretty simple.
+ *
+ * Invoked by putting {{plural:count|wordform1|wordform2}}
+ * or {{plural:count|wordform1|wordform2|wordform3}}
+ *
+ * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
+ *
+ * @param integer $count
+ * @param string $wordform1
+ * @param string $wordform2
+ * @param string $wordform3 (optional)
+ * @param string $wordform4 (optional)
+ * @param string $wordform5 (optional)
+ * @return string
+ */
+ function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
+ return $count == '1' ? $w1 : $w2;
+ }
+
+ /**
+ * For translaing of expiry times
+ * @param string The validated block time in English
+ * @return Somehow translated block time
+ * @see LanguageFi.php for example implementation
+ */
+ function translateBlockExpiry( $str ) {
+
+ $scBlockExpiryOptions = $this->getMessageFromDB( 'ipboptions' );
+
+ if ( $scBlockExpiryOptions == '-') {
+ return $str;
+ }
+
+ foreach (explode(',', $scBlockExpiryOptions) as $option) {
+ if ( strpos($option, ":") === false )
+ continue;
+ list($show, $value) = explode(":", $option);
+ if ( strcmp ( $str, $value) == 0 )
+ return '<span title="' . htmlspecialchars($str). '">' .
+ htmlspecialchars( trim( $show ) ) . '</span>';
+ }
+
+ return $str;
+ }
+
+ /**
+ * languages like Chinese need to be segmented in order for the diff
+ * to be of any use
+ *
+ * @param string $text
+ * @return string
+ */
+ function segmentForDiff( $text ) {
+ return $text;
+ }
+
+ /**
+ * and unsegment to show the result
+ *
+ * @param string $text
+ * @return string
+ */
+ function unsegmentForDiff( $text ) {
+ return $text;
+ }
+
+ # convert text to different variants of a language.
+ function convert( $text, $isTitle = false) {
+ return $this->mConverter->convert($text, $isTitle);
+ }
+
+ # Convert text from within Parser
+ function parserConvert( $text, &$parser ) {
+ return $this->mConverter->parserConvert( $text, $parser );
+ }
+
+ # Check if this is a language with variants
+ function hasVariants(){
+ return sizeof($this->getVariants())>1;
+ }
+
+ # Put custom tags (e.g. -{ }-) around math to prevent conversion
+ function armourMath($text){
+ return $this->mConverter->armourMath($text);
+ }
+
+
+ /**
+ * Perform output conversion on a string, and encode for safe HTML output.
+ * @param string $text
+ * @param bool $isTitle -- wtf?
+ * @return string
+ * @todo this should get integrated somewhere sane
+ */
+ function convertHtml( $text, $isTitle = false ) {
+ return htmlspecialchars( $this->convert( $text, $isTitle ) );
+ }
+
+ function convertCategoryKey( $key ) {
+ return $this->mConverter->convertCategoryKey( $key );
+ }
+
+ /**
+ * get the list of variants supported by this langauge
+ * see sample implementation in LanguageZh.php
+ *
+ * @return array an array of language codes
+ */
+ function getVariants() {
+ return $this->mConverter->getVariants();
+ }
+
+
+ function getPreferredVariant( $fromUser = true ) {
+ return $this->mConverter->getPreferredVariant( $fromUser );
+ }
+
+ /**
+ * if a language supports multiple variants, it is
+ * possible that non-existing link in one variant
+ * actually exists in another variant. this function
+ * tries to find it. See e.g. LanguageZh.php
+ *
+ * @param string $link the name of the link
+ * @param mixed $nt the title object of the link
+ * @return null the input parameters may be modified upon return
+ */
+ function findVariantLink( &$link, &$nt ) {
+ $this->mConverter->findVariantLink($link, $nt);
+ }
+
+ /**
+ * If a language supports multiple variants, converts text
+ * into an array of all possible variants of the text:
+ * 'variant' => text in that variant
+ */
+
+ function convertLinkToAllVariants($text){
+ return $this->mConverter->convertLinkToAllVariants($text);
+ }
+
+
+ /**
+ * returns language specific options used by User::getPageRenderHash()
+ * for example, the preferred language variant
+ *
+ * @return string
+ * @public
+ */
+ function getExtraHashOptions() {
+ return $this->mConverter->getExtraHashOptions();
+ }
+
+ /**
+ * for languages that support multiple variants, the title of an
+ * article may be displayed differently in different variants. this
+ * function returns the apporiate title defined in the body of the article.
+ *
+ * @return string
+ */
+ function getParsedTitle() {
+ return $this->mConverter->getParsedTitle();
+ }
+
+ /**
+ * Enclose a string with the "no conversion" tag. This is used by
+ * various functions in the Parser
+ *
+ * @param string $text text to be tagged for no conversion
+ * @return string the tagged text
+ */
+ function markNoConversion( $text, $noParse=false ) {
+ return $this->mConverter->markNoConversion( $text, $noParse );
+ }
+
+ /**
+ * A regular expression to match legal word-trailing characters
+ * which should be merged onto a link of the form [[foo]]bar.
+ *
+ * @return string
+ * @public
+ */
+ function linkTrail() {
+ $this->load();
+ return $this->linkTrail;
+ }
+
+ function getLangObj() {
+ return $this;
+ }
+
+ /**
+ * Get the RFC 3066 code for this language object
+ */
+ function getCode() {
+ return $this->mCode;
+ }
+
+ function setCode( $code ) {
+ $this->mCode = $code;
+ }
+
+ static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
+ return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
+ }
+
+ static function getMessagesFileName( $code ) {
+ global $IP;
+ return self::getFileName( "$IP/languages/messages/Messages", $code, '.php' );
+ }
+
+ static function getClassFileName( $code ) {
+ global $IP;
+ return self::getFileName( "$IP/languages/classes/Language", $code, '.php' );
+ }
+
+ static function getLocalisationArray( $code, $disableCache = false ) {
+ self::loadLocalisation( $code, $disableCache );
+ return self::$mLocalisationCache[$code];
+ }
+
+ /**
+ * Load localisation data for a given code into the static cache
+ *
+ * @return array Dependencies, map of filenames to mtimes
+ */
+ static function loadLocalisation( $code, $disableCache = false ) {
+ static $recursionGuard = array();
+ global $wgMemc;
+
+ if ( !$code ) {
+ throw new MWException( "Invalid language code requested" );
+ }
+
+ if ( !$disableCache ) {
+ # Try the per-process cache
+ if ( isset( self::$mLocalisationCache[$code] ) ) {
+ return self::$mLocalisationCache[$code]['deps'];
+ }
+
+ wfProfileIn( __METHOD__ );
+
+ # Try the serialized directory
+ $cache = wfGetPrecompiledData( self::getFileName( "Messages", $code, '.ser' ) );
+ if ( $cache ) {
+ self::$mLocalisationCache[$code] = $cache;
+ wfDebug( "Language::loadLocalisation(): got localisation for $code from precompiled data file\n" );
+ wfProfileOut( __METHOD__ );
+ return self::$mLocalisationCache[$code]['deps'];
+ }
+
+ # Try the global cache
+ $memcKey = wfMemcKey('localisation', $code );
+ $cache = $wgMemc->get( $memcKey );
+ if ( $cache ) {
+ $expired = false;
+ # Check file modification times
+ foreach ( $cache['deps'] as $file => $mtime ) {
+ if ( !file_exists( $file ) || filemtime( $file ) > $mtime ) {
+ $expired = true;
+ break;
+ }
+ }
+ if ( self::isLocalisationOutOfDate( $cache ) ) {
+ $wgMemc->delete( $memcKey );
+ $cache = false;
+ wfDebug( "Language::loadLocalisation(): localisation cache for $code had expired due to update of $file\n" );
+ } else {
+ self::$mLocalisationCache[$code] = $cache;
+ wfDebug( "Language::loadLocalisation(): got localisation for $code from cache\n" );
+ wfProfileOut( __METHOD__ );
+ return $cache['deps'];
+ }
+ }
+ } else {
+ wfProfileIn( __METHOD__ );
+ }
+
+ # Default fallback, may be overridden when the messages file is included
+ if ( $code != 'en' ) {
+ $fallback = 'en';
+ } else {
+ $fallback = false;
+ }
+
+ # Load the primary localisation from the source file
+ $filename = self::getMessagesFileName( $code );
+ if ( !file_exists( $filename ) ) {
+ wfDebug( "Language::loadLocalisation(): no localisation file for $code, using implicit fallback to en\n" );
+ $cache = array();
+ $deps = array();
+ } else {
+ $deps = array( $filename => filemtime( $filename ) );
+ require( $filename );
+ $cache = compact( self::$mLocalisationKeys );
+ wfDebug( "Language::loadLocalisation(): got localisation for $code from source\n" );
+ }
+
+ if ( !empty( $fallback ) ) {
+ # Load the fallback localisation, with a circular reference guard
+ if ( isset( $recursionGuard[$code] ) ) {
+ throw new MWException( "Error: Circular fallback reference in language code $code" );
+ }
+ $recursionGuard[$code] = true;
+ $newDeps = self::loadLocalisation( $fallback, $disableCache );
+ unset( $recursionGuard[$code] );
+
+ $secondary = self::$mLocalisationCache[$fallback];
+ $deps = array_merge( $deps, $newDeps );
+
+ # Merge the fallback localisation with the current localisation
+ foreach ( self::$mLocalisationKeys as $key ) {
+ if ( isset( $cache[$key] ) ) {
+ if ( isset( $secondary[$key] ) ) {
+ if ( in_array( $key, self::$mMergeableMapKeys ) ) {
+ $cache[$key] = $cache[$key] + $secondary[$key];
+ } elseif ( in_array( $key, self::$mMergeableListKeys ) ) {
+ $cache[$key] = array_merge( $secondary[$key], $cache[$key] );
+ } elseif ( in_array( $key, self::$mMergeableAliasListKeys ) ) {
+ $cache[$key] = array_merge_recursive( $cache[$key], $secondary[$key] );
+ }
+ }
+ } else {
+ $cache[$key] = $secondary[$key];
+ }
+ }
+
+ # Merge bookstore lists if requested
+ if ( !empty( $cache['bookstoreList']['inherit'] ) ) {
+ $cache['bookstoreList'] = array_merge( $cache['bookstoreList'], $secondary['bookstoreList'] );
+ }
+ if ( isset( $cache['bookstoreList']['inherit'] ) ) {
+ unset( $cache['bookstoreList']['inherit'] );
+ }
+ }
+
+ # Add dependencies to the cache entry
+ $cache['deps'] = $deps;
+
+ # Replace spaces with underscores in namespace names
+ $cache['namespaceNames'] = str_replace( ' ', '_', $cache['namespaceNames'] );
+
+ # Save to both caches
+ self::$mLocalisationCache[$code] = $cache;
+ if ( !$disableCache ) {
+ $wgMemc->set( $memcKey, $cache );
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $deps;
+ }
+
+ /**
+ * Test if a given localisation cache is out of date with respect to the
+ * source Messages files. This is done automatically for the global cache
+ * in $wgMemc, but is only done on certain occasions for the serialized
+ * data file.
+ *
+ * @param $cache mixed Either a language code or a cache array
+ */
+ static function isLocalisationOutOfDate( $cache ) {
+ if ( !is_array( $cache ) ) {
+ self::loadLocalisation( $cache );
+ $cache = self::$mLocalisationCache[$cache];
+ }
+ $expired = false;
+ foreach ( $cache['deps'] as $file => $mtime ) {
+ if ( !file_exists( $file ) || filemtime( $file ) > $mtime ) {
+ $expired = true;
+ break;
+ }
+ }
+ return $expired;
+ }
+
+ /**
+ * Get the fallback for a given language
+ */
+ static function getFallbackFor( $code ) {
+ self::loadLocalisation( $code );
+ return self::$mLocalisationCache[$code]['fallback'];
+ }
+
+ /**
+ * Get all messages for a given language
+ */
+ static function getMessagesFor( $code ) {
+ self::loadLocalisation( $code );
+ return self::$mLocalisationCache[$code]['messages'];
+ }
+
+ /**
+ * Get a message for a given language
+ */
+ static function getMessageFor( $key, $code ) {
+ self::loadLocalisation( $code );
+ return isset( self::$mLocalisationCache[$code]['messages'][$key] ) ? self::$mLocalisationCache[$code]['messages'][$key] : null;
+ }
+
+ /**
+ * Load localisation data for this object
+ */
+ function load() {
+ if ( !$this->mLoaded ) {
+ self::loadLocalisation( $this->getCode() );
+ $cache =& self::$mLocalisationCache[$this->getCode()];
+ foreach ( self::$mLocalisationKeys as $key ) {
+ $this->$key = $cache[$key];
+ }
+ $this->mLoaded = true;
+
+ $this->fixUpSettings();
+ }
+ }
+
+ /**
+ * Do any necessary post-cache-load settings adjustment
+ */
+ function fixUpSettings() {
+ global $wgExtraNamespaces, $wgMetaNamespace, $wgMetaNamespaceTalk, $wgMessageCache,
+ $wgNamespaceAliases, $wgAmericanDates;
+ wfProfileIn( __METHOD__ );
+ if ( $wgExtraNamespaces ) {
+ $this->namespaceNames = $wgExtraNamespaces + $this->namespaceNames;
+ }
+
+ $this->namespaceNames[NS_PROJECT] = $wgMetaNamespace;
+ if ( $wgMetaNamespaceTalk ) {
+ $this->namespaceNames[NS_PROJECT_TALK] = $wgMetaNamespaceTalk;
+ } else {
+ $talk = $this->namespaceNames[NS_PROJECT_TALK];
+ $talk = str_replace( '$1', $wgMetaNamespace, $talk );
+
+ # Allow grammar transformations
+ # Allowing full message-style parsing would make simple requests
+ # such as action=raw much more expensive than they need to be.
+ # This will hopefully cover most cases.
+ $talk = preg_replace_callback( '/{{grammar:(.*?)\|(.*?)}}/i',
+ array( &$this, 'replaceGrammarInNamespace' ), $talk );
+ $talk = str_replace( ' ', '_', $talk );
+ $this->namespaceNames[NS_PROJECT_TALK] = $talk;
+ }
+
+ # The above mixing may leave namespaces out of canonical order.
+ # Re-order by namespace ID number...
+ ksort( $this->namespaceNames );
+
+ # Put namespace names and aliases into a hashtable.
+ # If this is too slow, then we should arrange it so that it is done
+ # before caching. The catch is that at pre-cache time, the above
+ # class-specific fixup hasn't been done.
+ $this->mNamespaceIds = array();
+ foreach ( $this->namespaceNames as $index => $name ) {
+ $this->mNamespaceIds[$this->lc($name)] = $index;
+ }
+ if ( $this->namespaceAliases ) {
+ foreach ( $this->namespaceAliases as $name => $index ) {
+ $this->mNamespaceIds[$this->lc($name)] = $index;
+ }
+ }
+ if ( $wgNamespaceAliases ) {
+ foreach ( $wgNamespaceAliases as $name => $index ) {
+ $this->mNamespaceIds[$this->lc($name)] = $index;
+ }
+ }
+
+ if ( $this->defaultDateFormat == 'dmy or mdy' ) {
+ $this->defaultDateFormat = $wgAmericanDates ? 'mdy' : 'dmy';
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ function replaceGrammarInNamespace( $m ) {
+ return $this->convertGrammar( trim( $m[2] ), trim( $m[1] ) );
+ }
+
+ static function getCaseMaps() {
+ static $wikiUpperChars, $wikiLowerChars;
+ if ( isset( $wikiUpperChars ) ) {
+ return array( $wikiUpperChars, $wikiLowerChars );
+ }
+
+ wfProfileIn( __METHOD__ );
+ $arr = wfGetPrecompiledData( 'Utf8Case.ser' );
+ if ( $arr === false ) {
+ throw new MWException(
+ "Utf8Case.ser is missing, please run \"make\" in the serialized directory\n" );
+ }
+ extract( $arr );
+ wfProfileOut( __METHOD__ );
+ return array( $wikiUpperChars, $wikiLowerChars );
+ }
+}
+
+?>
diff --git a/languages/LanguageConverter.php b/languages/LanguageConverter.php
new file mode 100644
index 000000000000..316bcb12a2c4
--- /dev/null
+++ b/languages/LanguageConverter.php
@@ -0,0 +1,814 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Zhengzhu Feng <zhengzhu@gmail.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+
+class LanguageConverter {
+ var $mPreferredVariant='';
+ var $mMainLanguageCode;
+ var $mVariants, $mVariantFallbacks;
+ var $mTablesLoaded = false;
+ var $mTables;
+ var $mTitleDisplay='';
+ var $mDoTitleConvert=true, $mDoContentConvert=true;
+ var $mTitleFromFlag = false;
+ var $mCacheKey;
+ var $mLangObj;
+ var $mMarkup;
+ var $mFlags;
+ var $mUcfirst = false;
+ /**
+ * Constructor
+ *
+ * @param string $maincode the main language code of this language
+ * @param array $variants the supported variants of this language
+ * @param array $variantfallback the fallback language of each variant
+ * @param array $markup array defining the markup used for manual conversion
+ * @param array $flags array defining the custom strings that maps to the flags
+ * @access public
+ */
+ function __construct($langobj, $maincode,
+ $variants=array(),
+ $variantfallbacks=array(),
+ $markup=array(),
+ $flags = array()) {
+ global $wgLegalTitleChars;
+ $this->mLangObj = $langobj;
+ $this->mMainLanguageCode = $maincode;
+ $this->mVariants = $variants;
+ $this->mVariantFallbacks = $variantfallbacks;
+ $this->mCacheKey = wfMemcKey( 'conversiontables', $maincode );
+ $m = array('begin'=>'-{', 'flagsep'=>'|', 'codesep'=>':',
+ 'varsep'=>';', 'end'=>'}-');
+ $this->mMarkup = array_merge($m, $markup);
+ $f = array('A'=>'A', 'T'=>'T', 'R' => 'R');
+ $this->mFlags = array_merge($f, $flags);
+ }
+
+ /**
+ * @access public
+ */
+ function getVariants() {
+ return $this->mVariants;
+ }
+
+ /**
+ * in case some variant is not defined in the markup, we need
+ * to have some fallback. for example, in zh, normally people
+ * will define zh-cn and zh-tw, but less so for zh-sg or zh-hk.
+ * when zh-sg is preferred but not defined, we will pick zh-cn
+ * in this case. right now this is only used by zh.
+ *
+ * @param string $v the language code of the variant
+ * @return string the code of the fallback language or false if there is no fallback
+ * @private
+ */
+ function getVariantFallback($v) {
+ return $this->mVariantFallbacks[$v];
+ }
+
+
+ /**
+ * get preferred language variants.
+ * @param boolean $fromUser Get it from $wgUser's preferences
+ * @return string the preferred language code
+ * @access public
+ */
+ function getPreferredVariant( $fromUser = true ) {
+ global $wgUser, $wgRequest, $wgVariantArticlePath, $wgDefaultLanguageVariant;
+
+ if($this->mPreferredVariant)
+ return $this->mPreferredVariant;
+
+ // see if the preference is set in the request
+ $req = $wgRequest->getText( 'variant' );
+ if( in_array( $req, $this->mVariants ) ) {
+ $this->mPreferredVariant = $req;
+ return $req;
+ }
+
+ // check the syntax /code/ArticleTitle
+ if($wgVariantArticlePath!=false && isset($_SERVER['SCRIPT_NAME'])){
+ // Note: SCRIPT_NAME probably won't hold the correct value if PHP is run as CGI
+ // (it will hold path to php.cgi binary), and might not exist on some very old PHP installations
+ $scriptBase = basename( $_SERVER['SCRIPT_NAME'] );
+ if(in_array($scriptBase,$this->mVariants)){
+ $this->mPreferredVariant = $scriptBase;
+ return $this->mPreferredVariant;
+ }
+ }
+
+ // get language variant preference from logged in users
+ // Don't call this on stub objects because that causes infinite
+ // recursion during initialisation
+ if( $fromUser && $wgUser->isLoggedIn() ) {
+ $this->mPreferredVariant = $wgUser->getOption('variant');
+ return $this->mPreferredVariant;
+ }
+
+ // see if default variant is globaly set
+ if($wgDefaultLanguageVariant != false && in_array( $wgDefaultLanguageVariant, $this->mVariants )){
+ $this->mPreferredVariant = $wgDefaultLanguageVariant;
+ return $this->mPreferredVariant;
+ }
+
+ # FIXME rewrite code for parsing http header. The current code
+ # is written specific for detecting zh- variants
+ if( !$this->mPreferredVariant ) {
+ // see if some supported language variant is set in the
+ // http header, but we don't set the mPreferredVariant
+ // variable in case this is called before the user's
+ // preference is loaded
+ $pv=$this->mMainLanguageCode;
+ if(array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
+ $header = str_replace( '_', '-', strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]));
+ $zh = strstr($header, $pv.'-');
+ if($zh) {
+ $pv = substr($zh,0,5);
+ }
+ }
+ // don't try to return bad variant
+ if(in_array( $pv, $this->mVariants ))
+ return $pv;
+ }
+
+ return $this->mMainLanguageCode;
+
+ }
+
+ /**
+ * dictionary-based conversion
+ *
+ * @param string $text the text to be converted
+ * @param string $toVariant the target language code
+ * @return string the converted text
+ * @private
+ */
+ function autoConvert($text, $toVariant=false) {
+ $fname="LanguageConverter::autoConvert";
+
+ wfProfileIn( $fname );
+
+ if(!$this->mTablesLoaded)
+ $this->loadTables();
+
+ if(!$toVariant)
+ $toVariant = $this->getPreferredVariant();
+ if(!in_array($toVariant, $this->mVariants))
+ return $text;
+
+ /* we convert everything except:
+ 1. html markups (anything between < and >)
+ 2. html entities
+ 3. place holders created by the parser
+ */
+ global $wgParser;
+ if (isset($wgParser))
+ $marker = '|' . $wgParser->UniqPrefix() . '[\-a-zA-Z0-9]+';
+ else
+ $marker = "";
+
+ // this one is needed when the text is inside an html markup
+ $htmlfix = '|<[^>]+$|^[^<>]*>';
+
+ // disable convert to variants between <code></code> tags
+ $codefix = '<code>.+?<\/code>|';
+ // disable convertsion of <script type="text/javascript"> ... </script>
+ $scriptfix = '<script.*?>.*?<\/script>|';
+
+ $reg = '/'.$codefix . $scriptfix . '<[^>]+>|&[a-zA-Z#][a-z0-9]+;' . $marker . $htmlfix . '/s';
+
+ $matches = preg_split($reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE);
+
+ $m = array_shift($matches);
+
+ $ret = $this->translate($m[0], $toVariant);
+ $mstart = $m[1]+strlen($m[0]);
+ foreach($matches as $m) {
+ $ret .= substr($text, $mstart, $m[1]-$mstart);
+ $ret .= $this->translate($m[0], $toVariant);
+ $mstart = $m[1] + strlen($m[0]);
+ }
+ wfProfileOut( $fname );
+ return $ret;
+ }
+
+ /**
+ * Translate a string to a variant
+ * Doesn't process markup or do any of that other stuff, for that use convert()
+ *
+ * @param string $text Text to convert
+ * @param string $variant Variant language code
+ * @return string Translated text
+ */
+ function translate( $text, $variant ) {
+ wfProfileIn( __METHOD__ );
+ if( !$this->mTablesLoaded )
+ $this->loadTables();
+ $text = $this->mTables[$variant]->replace( $text );
+ wfProfileOut( __METHOD__ );
+ return $text;
+ }
+
+ /**
+ * convert text to all supported variants
+ *
+ * @param string $text the text to be converted
+ * @return array of string
+ * @public
+ */
+ function autoConvertToAllVariants($text) {
+ $fname="LanguageConverter::autoConvertToAllVariants";
+ wfProfileIn( $fname );
+ if( !$this->mTablesLoaded )
+ $this->loadTables();
+
+ $ret = array();
+ foreach($this->mVariants as $variant) {
+ $ret[$variant] = $this->translate($text, $variant);
+ }
+
+ wfProfileOut( $fname );
+ return $ret;
+ }
+
+ /**
+ * convert link text to all supported variants
+ *
+ * @param string $text the text to be converted
+ * @return array of string
+ * @public
+ */
+ function convertLinkToAllVariants($text) {
+ if( !$this->mTablesLoaded )
+ $this->loadTables();
+
+ $ret = array();
+ $tarray = explode($this->mMarkup['begin'], $text);
+ $tfirst = array_shift($tarray);
+
+ foreach($this->mVariants as $variant)
+ $ret[$variant] = $this->translate($tfirst,$variant);
+
+ foreach($tarray as $txt) {
+ $marked = explode($this->mMarkup['end'], $txt, 2);
+
+ foreach($this->mVariants as $variant){
+ $ret[$variant] .= $this->mMarkup['begin'].$marked[0].$this->mMarkup['end'];
+ if(array_key_exists(1, $marked))
+ $ret[$variant] .= $this->translate($marked[1],$variant);
+ }
+
+ }
+
+ return $ret;
+ }
+
+
+ /**
+ * Convert text using a parser object for context
+ */
+ function parserConvert( $text, &$parser ) {
+ global $wgDisableLangConversion;
+ /* don't do anything if this is the conversion table */
+ if ( $parser->mTitle->getNamespace() == NS_MEDIAWIKI &&
+ strpos($parser->mTitle->getText(), "Conversiontable") !== false )
+ {
+ return $text;
+ }
+
+ if($wgDisableLangConversion)
+ return $text;
+
+ $text = $this->convert( $text );
+ $parser->mOutput->setTitleText( $this->mTitleDisplay );
+ return $text;
+ }
+
+ /**
+ * Parse flags with syntax -{FLAG| ... }-
+ *
+ */
+ function parseFlags($marked){
+ $flags = array();
+
+ // process flag only if the flag is valid
+ if(strlen($marked) < 2 || !(in_array($marked[0],$this->mFlags) && $marked[1]=='|' ) )
+ return array($marked,array());
+
+ $tt = explode($this->mMarkup['flagsep'], $marked, 2);
+
+ if(sizeof($tt) == 2) {
+ $f = explode($this->mMarkup['varsep'], $tt[0]);
+ foreach($f as $ff) {
+ $ff = trim($ff);
+ if(array_key_exists($ff, $this->mFlags) &&
+ !array_key_exists($this->mFlags[$ff], $flags))
+ $flags[] = $this->mFlags[$ff];
+ }
+ $rules = $tt[1];
+ }
+ else
+ $rules = $marked;
+
+ if( !in_array('R',$flags) ){
+ //FIXME: may cause trouble here...
+ //strip &nbsp; since it interferes with the parsing, plus,
+ //all spaces should be stripped in this tag anyway.
+ $rules = str_replace('&nbsp;', '', $rules);
+ }
+
+ return array($rules,$flags);
+ }
+
+ /**
+ * convert text to different variants of a language. the automatic
+ * conversion is done in autoConvert(). here we parse the text
+ * marked with -{}-, which specifies special conversions of the
+ * text that can not be accomplished in autoConvert()
+ *
+ * syntax of the markup:
+ * -{code1:text1;code2:text2;...}- or
+ * -{text}- in which case no conversion should take place for text
+ *
+ * @param string $text text to be converted
+ * @param bool $isTitle whether this conversion is for the article title
+ * @return string converted text
+ * @access public
+ */
+ function convert( $text , $isTitle=false) {
+ $mw =& MagicWord::get( 'notitleconvert' );
+ if( $mw->matchAndRemove( $text ) )
+ $this->mDoTitleConvert = false;
+
+ $mw =& MagicWord::get( 'nocontentconvert' );
+ if( $mw->matchAndRemove( $text ) ) {
+ $this->mDoContentConvert = false;
+ }
+
+ // no conversion if redirecting
+ $mw =& MagicWord::get( 'redirect' );
+ if( $mw->matchStart( $text ))
+ return $text;
+
+ if( $isTitle ) {
+
+ // use the title from the T flag if any
+ if($this->mTitleFromFlag){
+ $this->mTitleFromFlag = false;
+ return $this->mTitleDisplay;
+ }
+
+ // check for __NOTC__ tag
+ if( !$this->mDoTitleConvert ) {
+ $this->mTitleDisplay = $text;
+ return $text;
+ }
+
+ global $wgRequest;
+ $isredir = $wgRequest->getText( 'redirect', 'yes' );
+ $action = $wgRequest->getText( 'action' );
+ if ( $isredir == 'no' || $action == 'edit' ) {
+ return $text;
+ }
+ else {
+ $this->mTitleDisplay = $this->convert($text);
+ return $this->mTitleDisplay;
+ }
+ }
+
+ $plang = $this->getPreferredVariant();
+ if( isset( $this->mVariantFallbacks[$plang] ) ) {
+ $fallback = $this->mVariantFallbacks[$plang];
+ } else {
+ $fallback = $this->mMainLanguageCode;
+ }
+
+ $tarray = explode($this->mMarkup['begin'], $text);
+ $tfirst = array_shift($tarray);
+ if($this->mDoContentConvert)
+ $text = $this->autoConvert($tfirst);
+ else
+ $text = $tfirst;
+ foreach($tarray as $txt) {
+ $marked = explode($this->mMarkup['end'], $txt, 2);
+
+ // strip the flags from syntax like -{T| ... }-
+ list($rules,$flags) = $this->parseFlags($marked[0]);
+
+ // proces R flag: output raw content of -{ ... }-
+ if( in_array('R',$flags) ){
+ $disp = $rules;
+ } else if( $this->mDoContentConvert){
+ // parse the contents -{ ... }-
+ $carray = $this->parseManualRule($rules, $flags);
+
+ $disp = '';
+ if(array_key_exists($plang, $carray))
+ $disp = $carray[$plang];
+ else if(array_key_exists($fallback, $carray))
+ $disp = $carray[$fallback];
+ } else{
+ // if we don't do content convert, still strip the -{}- tags
+ $disp = $rules;
+ $flags = array();
+ }
+
+ if($disp) {
+ // use syntax -{T|zh:TitleZh;zh-tw:TitleTw}- for custom conversion in title
+ if(in_array('T', $flags)){
+ $this->mTitleFromFlag = true;
+ $this->mTitleDisplay = $disp;
+ }
+ else
+ $text .= $disp;
+
+ // use syntax -{A|zh:WordZh;zh-tw:WordTw}- to introduce a custom mapping between
+ // words WordZh and WordTw in the whole text
+ if(in_array('A', $flags)) {
+
+ /* fill in the missing variants, if any,
+ with fallbacks */
+ foreach($this->mVariants as $v) {
+ if(!array_key_exists($v, $carray)) {
+ $vf = $this->getVariantFallback($v);
+ if(array_key_exists($vf, $carray))
+ $carray[$v] = $carray[$vf];
+ }
+ }
+
+ foreach($this->mVariants as $vfrom) {
+ if(!array_key_exists($vfrom, $carray))
+ continue;
+ foreach($this->mVariants as $vto) {
+ if($vfrom == $vto)
+ continue;
+ if(!array_key_exists($vto, $carray))
+ continue;
+ $this->mTables[$vto]->setPair($carray[$vfrom], $carray[$vto]);
+ }
+ }
+ }
+ }
+ else {
+ $text .= $marked[0];
+ }
+ if(array_key_exists(1, $marked)){
+ if( $this->mDoContentConvert )
+ $text .= $this->autoConvert($marked[1]);
+ else
+ $text .= $marked[1];
+ }
+ }
+
+ return $text;
+ }
+
+ /**
+ * parse the manually marked conversion rule
+ * @param string $rule the text of the rule
+ * @return array of the translation in each variant
+ * @private
+ */
+ function parseManualRule($rules, $flags=array()) {
+
+ $choice = explode($this->mMarkup['varsep'], $rules);
+ $carray = array();
+ if(sizeof($choice) == 1) {
+ /* a single choice */
+ foreach($this->mVariants as $v)
+ $carray[$v] = $choice[0];
+ }
+ else {
+ foreach($choice as $c) {
+ $v = explode($this->mMarkup['codesep'], $c);
+ if(sizeof($v) != 2) // syntax error, skip
+ continue;
+ $carray[trim($v[0])] = trim($v[1]);
+ }
+ }
+ return $carray;
+ }
+
+ /**
+ * if a language supports multiple variants, it is
+ * possible that non-existing link in one variant
+ * actually exists in another variant. this function
+ * tries to find it. See e.g. LanguageZh.php
+ *
+ * @param string $link the name of the link
+ * @param mixed $nt the title object of the link
+ * @return null the input parameters may be modified upon return
+ * @access public
+ */
+ function findVariantLink( &$link, &$nt ) {
+ global $wgDisableLangConversion;
+ $linkBatch = new LinkBatch();
+
+ $ns=NS_MAIN;
+
+ if(is_object($nt))
+ $ns = $nt->getNamespace();
+
+ $variants = $this->autoConvertToAllVariants($link);
+ if($variants == false) //give up
+ return;
+
+ $titles = array();
+
+ foreach( $variants as $v ) {
+ if($v != $link){
+ $varnt = Title::newFromText( $v, $ns );
+ if(!is_null($varnt)){
+ $linkBatch->addObj($varnt);
+ $titles[]=$varnt;
+ }
+ }
+ }
+
+ // fetch all variants in single query
+ $linkBatch->execute();
+
+ foreach( $titles as $varnt ) {
+ if( $varnt->getArticleID() > 0 ) {
+ $nt = $varnt;
+ if( !$wgDisableLangConversion )
+ $link = $v;
+ break;
+ }
+ }
+ }
+
+ /**
+ * returns language specific hash options
+ *
+ * @access public
+ */
+ function getExtraHashOptions() {
+ $variant = $this->getPreferredVariant();
+ return '!' . $variant ;
+ }
+
+ /**
+ * get title text as defined in the body of the article text
+ *
+ * @access public
+ */
+ function getParsedTitle() {
+ return $this->mTitleDisplay;
+ }
+
+ /**
+ * a write lock to the cache
+ *
+ * @private
+ */
+ function lockCache() {
+ global $wgMemc;
+ $success = false;
+ for($i=0; $i<30; $i++) {
+ if($success = $wgMemc->add($this->mCacheKey . "lock", 1, 10))
+ break;
+ sleep(1);
+ }
+ return $success;
+ }
+
+ /**
+ * unlock cache
+ *
+ * @private
+ */
+ function unlockCache() {
+ global $wgMemc;
+ $wgMemc->delete($this->mCacheKey . "lock");
+ }
+
+
+ /**
+ * Load default conversion tables
+ * This method must be implemented in derived class
+ *
+ * @private
+ */
+ function loadDefaultTables() {
+ $name = get_class($this);
+ wfDie("Must implement loadDefaultTables() method in class $name");
+ }
+
+ /**
+ * load conversion tables either from the cache or the disk
+ * @private
+ */
+ function loadTables($fromcache=true) {
+ global $wgMemc;
+ if( $this->mTablesLoaded )
+ return;
+ wfProfileIn( __METHOD__ );
+ $this->mTablesLoaded = true;
+ $this->mTables = false;
+ if($fromcache) {
+ wfProfileIn( __METHOD__.'-cache' );
+ $this->mTables = $wgMemc->get( $this->mCacheKey );
+ wfProfileOut( __METHOD__.'-cache' );
+ }
+ if ( !$this->mTables || !isset( $this->mTables['VERSION 2'] ) ) {
+ wfProfileIn( __METHOD__.'-recache' );
+ // not in cache, or we need a fresh reload.
+ // we will first load the default tables
+ // then update them using things in MediaWiki:Zhconversiontable/*
+ global $wgMessageCache;
+ $this->loadDefaultTables();
+ foreach($this->mVariants as $var) {
+ $cached = $this->parseCachedTable($var);
+ $this->mTables[$var]->mergeArray($cached);
+ }
+
+ $this->postLoadTables();
+ $this->mTables['VERSION 2'] = true;
+
+ if($this->lockCache()) {
+ $wgMemc->set($this->mCacheKey, $this->mTables, 43200);
+ $this->unlockCache();
+ }
+ wfProfileOut( __METHOD__.'-recache' );
+ }
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Hook for post processig after conversion tables are loaded
+ *
+ */
+ function postLoadTables() {}
+
+ /**
+ * Reload the conversion tables
+ *
+ * @private
+ */
+ function reloadTables() {
+ if($this->mTables)
+ unset($this->mTables);
+ $this->mTablesLoaded = false;
+ $this->loadTables(false);
+ }
+
+
+ /**
+ * parse the conversion table stored in the cache
+ *
+ * the tables should be in blocks of the following form:
+
+ * -{
+ * word => word ;
+ * word => word ;
+ * ...
+ * }-
+ *
+ * to make the tables more manageable, subpages are allowed
+ * and will be parsed recursively if $recursive=true
+ *
+ * @private
+ */
+ function parseCachedTable($code, $subpage='', $recursive=true) {
+ global $wgMessageCache;
+ static $parsed = array();
+
+ if(!is_object($wgMessageCache))
+ return array();
+
+ $key = 'Conversiontable/'.$code;
+ if($subpage)
+ $key .= '/' . $subpage;
+
+ if(array_key_exists($key, $parsed))
+ return array();
+
+
+ $txt = $wgMessageCache->get( $key, true, true, true );
+
+ // get all subpage links of the form
+ // [[MediaWiki:conversiontable/zh-xx/...|...]]
+ $linkhead = $this->mLangObj->getNsText(NS_MEDIAWIKI) . ':Conversiontable';
+ $subs = explode('[[', $txt);
+ $sublinks = array();
+ foreach( $subs as $sub ) {
+ $link = explode(']]', $sub, 2);
+ if(count($link) != 2)
+ continue;
+ $b = explode('|', $link[0]);
+ $b = explode('/', trim($b[0]), 3);
+ if(count($b)==3)
+ $sublink = $b[2];
+ else
+ $sublink = '';
+
+ if($b[0] == $linkhead && $b[1] == $code) {
+ $sublinks[] = $sublink;
+ }
+ }
+
+
+ // parse the mappings in this page
+ $blocks = explode($this->mMarkup['begin'], $txt);
+ array_shift($blocks);
+ $ret = array();
+ foreach($blocks as $block) {
+ $mappings = explode($this->mMarkup['end'], $block, 2);
+ $stripped = str_replace(array("'", '"', '*','#'), '', $mappings[0]);
+ $table = explode( ';', $stripped );
+ foreach( $table as $t ) {
+ $m = explode( '=>', $t );
+ if( count( $m ) != 2)
+ continue;
+ // trim any trailling comments starting with '//'
+ $tt = explode('//', $m[1], 2);
+ $ret[trim($m[0])] = trim($tt[0]);
+ }
+ }
+ $parsed[$key] = true;
+
+
+ // recursively parse the subpages
+ if($recursive) {
+ foreach($sublinks as $link) {
+ $s = $this->parseCachedTable($code, $link, $recursive);
+ $ret = array_merge($ret, $s);
+ }
+ }
+
+ if ($this->mUcfirst) {
+ foreach ($ret as $k => $v) {
+ $ret[Language::ucfirst($k)] = Language::ucfirst($v);
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Enclose a string with the "no conversion" tag. This is used by
+ * various functions in the Parser
+ *
+ * @param string $text text to be tagged for no conversion
+ * @return string the tagged text
+ */
+ function markNoConversion($text, $noParse=false) {
+ # don't mark if already marked
+ if(strpos($text, $this->mMarkup['begin']) ||
+ strpos($text, $this->mMarkup['end']))
+ return $text;
+
+ $ret = $this->mMarkup['begin'] . $text . $this->mMarkup['end'];
+ return $ret;
+ }
+
+ /**
+ * convert the sorting key for category links. this should make different
+ * keys that are variants of each other map to the same key
+ */
+ function convertCategoryKey( $key ) {
+ return $key;
+ }
+ /**
+ * hook to refresh the cache of conversion tables when
+ * MediaWiki:conversiontable* is updated
+ * @private
+ */
+ function OnArticleSaveComplete($article, $user, $text, $summary, $isminor, $iswatch, $section) {
+ $titleobj = $article->getTitle();
+ if($titleobj->getNamespace() == NS_MEDIAWIKI) {
+ /*
+ global $wgContLang; // should be an LanguageZh.
+ if(get_class($wgContLang) != 'languagezh')
+ return true;
+ */
+ $title = $titleobj->getDBkey();
+ $t = explode('/', $title, 3);
+ $c = count($t);
+ if( $c > 1 && $t[0] == 'Conversiontable' ) {
+ if(in_array($t[1], $this->mVariants)) {
+ $this->reloadTables();
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Armour rendered math against conversion
+ * Wrap math into rawoutput -{R| math }- syntax
+ */
+ function armourMath($text){
+ $ret = $this->mMarkup['begin'] . 'R|' . $text . $this->mMarkup['end'];
+ return $ret;
+ }
+
+
+}
+
+?>
diff --git a/languages/Names.php b/languages/Names.php
new file mode 100644
index 000000000000..5cc89b417475
--- /dev/null
+++ b/languages/Names.php
@@ -0,0 +1,287 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+/* private */ $wgLanguageNames = array(
+ 'aa' => 'Afar', # Afar
+ 'ab' => 'Аҧсуа', # Abkhaz, should possibly add ' бысжѡа'
+ 'af' => 'Afrikaans', # Afrikaans
+ 'ak' => 'Akana', # Akan
+ 'als' => 'Alemannisch', # Alemannic -- not a valid code, for compatibility
+ 'am' => 'አማርኛ', # Amharic
+ 'an' => 'Aragonés', # Aragonese
+ 'ang' => 'Anglo Saxon', # Old English
+ 'ar' => 'العربية', # Arabic
+ 'arc' => 'ܕܥܒܪܸܝܛ', # Aramaic
+ 'as' => 'অসমীয়া', # Assamese
+ 'ast' => 'Asturianu', # Asturian
+ 'av' => 'Авар', # Avar
+ 'ay' => 'Aymar', # Aymara, should possibly be Aymará
+ 'az' => 'Azərbaycan', # Azerbaijani
+ 'ba' => 'Башҡорт', # Bashkir
+ 'bar' => 'Boarisch', # Bavarian (Austro-Bavarian and South Tyrolean)
+ 'bat-smg' => 'Žemaitėška', # Samogitian
+ 'be' => 'Беларуская', # Belarusian ''or'' Byelarussian
+ 'bg' => 'Български', # Bulgarian
+ 'bh' => 'भोजपुरी', # Bihara
+ 'bi' => 'Bislama', # Bislama
+ 'bm' => 'Bamanankan', # Bambara
+ 'bn' => 'বাংলা', # Bengali
+ 'bo' => 'བོད་ཡིག', # Tibetan
+ 'bpy' => 'ইমার ঠার/বিষ্ণুপ্রিয়া মণিপুরী', # Bishnupriya Manipuri
+ 'br' => 'Brezhoneg', # Breton
+ 'bs' => 'Bosanski', # Bosnian
+ 'bug' => 'ᨅᨔ ᨕᨘᨁᨗ', # Buginese
+ 'bxr' => 'Буряад', # Buryat (Russia)
+ 'ca' => 'Català', # Catalan
+ 'cbk-zam' => 'Zamboangueño', # Zamboanga Chavacano
+ 'cdo' => 'Mìng-dĕ̤ng-ngṳ̄', # Min Dong
+ 'ce' => 'Нохчийн', # Chechen
+ 'ceb' => 'Cebuano', # Cebuano
+ 'ch' => 'Chamoru', # Chamorro
+ 'cho' => 'Choctaw', # Choctaw
+ 'chr' => 'ᏣᎳᎩ', # Cherokee
+ 'chy' => 'Tsetsêhestâhese', # Cheyenne
+ 'co' => 'Corsu', # Corsican
+ 'cr' => 'Nēhiyaw / ᓀᐦᐃᔭᐤ', # Cree
+ 'crh' => 'Qırımtatarca', # Crimean Tatar
+ 'crh-latn' => 'Qırımtatarca (Latin)', # Crimean Tatar (Latin)
+ 'crh-cyrl' => 'Qırımtatarca (Kiril)', # Crimean Tatar (Cyrillic)
+ 'cs' => 'Česky', # Czech
+ 'csb' => 'Kaszëbsczi', # Cassubian
+ 'cu' => 'Словѣньскъ', # Old Church Slavonic (ancient language)
+ 'cv' => 'Чăвашла', # Chuvash
+ 'cy' => 'Cymraeg', # Welsh
+ 'da' => 'Dansk', # Danish
+ 'de' => 'Deutsch', # German
+ 'diq' => 'Zazaki', # Zazaki
+ 'dk' => 'Dansk', # Unused code currently redirecting to Danish, 'da' is correct for the language
+ 'dv' => 'ދިވެހިބަސް', # Dhivehi
+ 'dz' => 'ཇོང་ཁ', # Bhutani
+ 'ee' => 'Eʋegbe', # Ewe
+ 'el' => 'Ελληνικά', # Greek
+ 'eml' => 'Emilià', # Emilian-Romagnol / Sammarinese
+ 'en' => 'English', # English
+ 'eo' => 'Esperanto', # Esperanto
+ 'es' => 'Español', # Spanish
+ 'et' => 'Eesti', # Estonian
+ 'eu' => 'Euskara', # Basque
+ 'fa' => 'فارسی', # Persian
+ 'ff' => 'Fulfulde', # Fulah
+ 'fi' => 'Suomi', # Finnish
+ 'fiu-vro' => 'Võro', # Võro
+ 'fj' => 'Na Vosa Vakaviti', # Fijian
+ 'fo' => 'Føroyskt', # Faroese
+ 'fr' => 'Français', # French
+ 'frp' => 'Arpitan', # Franco-Provençal/Arpitan
+ 'fur' => 'Furlan', # Friulian
+ 'fy' => 'Frysk', # Frisian
+ 'ga' => 'Gaeilge', # Irish
+ 'gd' => 'Gàidhlig', # Scots Gaelic
+ 'gl' => 'Galego', # Gallegan
+ 'glk' => 'گیلکی', # Gilaki
+ 'gn' => 'Avañe\'ẽ', # Guarani
+ 'got' => '𐌲𐌿𐍄𐌹𐍃𐌺', # Gothic
+ 'gsw' => 'Alemannisch', # Alemannic
+ 'gu' => 'ગુજરાતી', # Gujarati
+ 'gv' => 'Gaelg', # Manx
+ 'ha' => 'هَوُسَ', # Hausa
+ 'haw' => 'Hawai`i', # Hawaiian
+ 'he' => 'עברית', # Hebrew
+ 'hi' => 'हिन्दी', # Hindi
+ 'hil' => 'Ilonggo', # Hiligaynon
+ 'ho' => 'Hiri Motu', # Hiri Motu
+ 'hr' => 'Hrvatski', # Croatian
+ 'hsb' => 'Hornjoserbsce', # Upper Sorbian
+ 'ht' => 'Krèyol ayisyen', # Haitian, common/popular form is Kreyòl
+ 'hu' => 'Magyar', # Hungarian
+ 'hy' => 'Հայերեն', # Armenian
+ 'hz' => 'Otsiherero', # Herero
+ 'ia' => 'Interlingua', # Interlingua (IALA)
+ 'id' => 'Bahasa Indonesia', # Indonesian
+ 'ie' => 'Interlingue', # Interlingue (Occidental)
+ 'ig' => 'Igbo', # Igbo
+ 'ii' => 'ꆇꉙ', # Sichuan Yi
+ 'ik' => 'Iñupiak', # Inupiak
+ 'ilo' => 'Ilokano', # Ilokano
+ 'io' => 'Ido', # Ido
+ 'is' => 'Íslenska', # Icelandic
+ 'it' => 'Italiano', # Italian
+ 'iu' => 'ᐃᓄᒃᑎᑐᑦ', # Inuktitut
+ 'ja' => '日本語', # Japanese
+ 'jbo' => 'Lojban', # Lojban
+ 'jv' => 'Basa Jawa', # Javanese
+ 'ka' => 'ქართული', # Georgian
+ 'kaa' => 'Qaraqalpaqsha', # Karakalpak
+ 'kab' => 'ثاقبايليث', # Kabyle
+ 'kg' => 'Kongo', # Kongo, (FIXME!) should probaly be KiKongo or KiKoongo
+ 'ki' => 'Gĩkũyũ', # Kikuyu, correctness not guaranteed
+ 'kj' => 'Kuanyama', # Kuanyama (FIXME!)
+ 'kk' => 'Қазақша', # Kazakh
+ 'kk-cn' => 'قازاقشا (تٴوتە)', # Kazakh Arabic
+ 'kk-kz' => 'Қазақша (кирил)', # Kazakh Cyrillic
+ 'kk-tr' => 'Qazaqşa (latın)', # Kazakh Latin
+ 'kl' => 'Kalaallisut', # Greenlandic
+ 'km' => 'ភាសាខ្មែរ', # Cambodian
+ 'kn' => 'ಕನ್ನಡ', # Kannada
+ 'ko' => '한국어', # Korean
+ 'kr' => 'Kanuri', # Kanuri (FIXME!)
+ 'ks' => 'कश्मीरी - (كشميري)', # Kashmiri
+ 'ksh' => 'Ripoarisch', # Ripuarian
+ 'ku' => 'Kurdî / كوردي', # Kurdish
+ 'kv' => 'Коми', # Komi, cyrillic is common script but also written in latin script
+ 'kw' => 'Kernewek', # Cornish
+ 'ky' => 'Кыргызча', # Kirghiz
+ 'la' => 'Latina', # Latin
+ 'lad' => 'Ladino', # Ladino
+ 'lbe' => 'Лакку', # Lak
+ 'lb' => 'Lëtzebuergesch', # Luxemburguish
+ 'lg' => 'Luganda', # Ganda
+ 'li' => 'Limburgs', # Limburgian
+ 'lij' => 'Líguru', # Ligurian
+ 'lld' => 'Ladin', # Ladin
+ 'lmo' => 'Lumbaart', # Lombard
+ 'ln' => 'Lingála', # Lingala
+ 'lo' => 'ລາວ',# Laotian
+ 'lt' => 'Lietuvių', # Lithuanian
+ 'lv' => 'Latviešu', # Latvian
+ 'lzz' => 'Lazuri Nena', #Laz
+ 'map-bms' => 'Basa Banyumasan', # Banyumasan
+ 'mg' => 'Malagasy', # Malagasy
+ 'mh' => 'Ebon', # Marshallese
+ 'mi' => 'Māori', # Maori
+ 'minnan' => 'Bân-lâm-gú', # Min-nan (also zh-min-nan)
+ 'mk' => 'Македонски', # Macedonian
+ 'ml' => 'മലയാളം', # Malayalam
+ 'mn' => 'Монгол', # Mongoloian
+ 'mo' => 'Молдовеняскэ', # Moldovan
+ 'mr' => 'मराठी', # Marathi
+ 'ms' => 'Bahasa Melayu', # Malay
+ 'mt' => 'Malti', # Maltese
+ 'mus' => 'Muscogee', # Creek, should possibly be Muskogee
+ 'my' => 'Myanmasa', # Burmese
+ 'mzn' => 'مَزِروني', # Mazandarin
+ 'na' => 'Ekakairũ Naoero', # Nauruan
+ 'nah' => 'Nahuatl', # Nahuatl, en:Wikipedia writes Nahuatlahtolli, while another form is Náhuatl
+ 'nan' => 'Bân-lâm-gú', # Min-nan -- (bug 8217) nan instead of zh-min-nan, http://www.sil.org/iso639-3/codes.asp?order=639_3&letter=n
+ 'nap' => 'Nnapulitano', # Neapolitan
+ 'nb' => 'Norsk (bokmål)', # Norwegian (Bokmal)
+ 'nds' => 'Plattdüütsch', # Low German ''or'' Low Saxon
+ 'nds-nl' => 'Nedersaksisch', # Dutch Low Saxon
+ 'ne' => 'नेपाली', # Nepali
+ 'new' => 'नेपाल भाषा', # Newar / Nepal Bhasa
+ 'ng' => 'Oshiwambo', # Ndonga
+ 'nl' => 'Nederlands', # Dutch
+ 'nn' => 'Norsk (nynorsk)' , # Norwegian (Nynorsk)
+ 'no' => 'Norsk (bokmål)', # Norwegian
+ 'non' => 'Norrǿna', # Old Norse
+ 'nov' => 'Novial', # Novial
+ 'nrm' => 'Nouormand', # Norman
+ 'nv' => 'Diné bizaad', # Navajo
+ 'ny' => 'Chi-Chewa', # Chichewa
+ 'oc' => 'Occitan', # Occitan
+ 'om' => 'Oromoo', # Oromo
+ 'or' => 'ଓଡ଼ିଆ', # Oriya
+ 'os' => 'Иронау', # Ossetic
+ 'pa' => 'ਪੰਜਾਬੀ', # Punjabi
+ 'pag' => 'Pangasinan', # Pangasinan
+ 'pam' => 'Kapampangan', # Pampanga
+ 'pap' => 'Papiamentu', # Papiamentu
+ 'pdc' => 'Deitsch', # Pennsylvania German
+ 'pih' => 'Norfuk / Pitkern', # Norfuk/Pitcairn/Norfolk
+ 'pi' => 'पािऴ', # Pali
+ 'pl' => 'Polski', # Polish
+ 'pms' => 'Piemontèis', # Piedmontese
+ 'ps' => 'پښتو', # Pashto
+ 'pt' => 'Português', # Portuguese
+ 'pt-br' => 'Português do Brasil', # Brazilian Portuguese
+ 'qu' => 'Runa Simi', # Quechua
+ 'rm' => 'Rumantsch', # Raeto-Romance
+ 'rmy' => 'Romani', # Vlax Romany
+ 'rn' => 'Kirundi', # Kirundi
+ 'ro' => 'Română', # Romanian
+ 'roa-rup' => 'Armâneashti', # Aromanian
+ 'roa-tara' => 'Tarandíne', # Tarantino
+ 'ru' => 'Русский', # Russian
+ 'ru-sib' => 'Сибирской', # Siberian/North Russian
+ 'rw' => 'Kinyarwanda', # Kinyarwanda, should possibly be Kinyarwandi
+ 'sa' => 'संस्कृत', # Sanskrit
+ 'sc' => 'Sardu', # Sardinian
+ 'scn' => 'Sicilianu', # Sicilian
+ 'sco' => 'Scots', # Scots
+ 'sd' => 'سنڌي', # Sindhi
+ 'se' => 'Sámegiella', # Northern Sami
+ 'sg' => 'Sängö', # Sango, possible alternative is Sangho
+ 'sh' => 'Srpskohrvatski / Српскохрватски', # Serbocroatian
+ 'si' => 'සිංහල', # Sinhalese
+ 'simple' => 'Simple English', # Simple English
+ 'sk' => 'Slovenčina', # Slovak
+ 'sl' => 'Slovenščina', # Slovenian
+ 'sm' => 'Gagana Samoa', # Samoan
+ 'sn' => 'chiShona', # Shona
+ 'so' => 'Soomaaliga', # Somali
+ 'sq' => 'Shqip', # Albanian
+ 'sr' => 'Српски / Srpski', # Serbian
+ 'sr-ec' => 'ћирилица', # Serbian cyrillic ekavian
+ 'sr-jc' => 'ијекавица', # Serbian cyrillic iyekvian
+ 'sr-el' => 'latinica', # Serbian latin ekavian
+ 'sr-jl' => 'ijekavica', # Serbian latin iyekavian
+ 'ss' => 'SiSwati', # Swati
+ 'st' => 'seSotho', # Southern Sotho
+ 'su' => 'Basa Sunda', # Sundanese
+ 'sv' => 'Svenska', # Swedish
+ 'sw' => 'Kiswahili', # Swahili
+ 'ta' => 'தமிழ்', # Tamil
+ 'te' => 'తెలుగు', # Telugu
+ 'tet' => 'Tetun', # Tetun
+ 'tg' => 'Тоҷикӣ', # Tajik
+ 'th' => 'ไทย', # Thai
+ 'ti' => 'ትግርኛ', # Tigrinya
+ 'tk' => 'Türkmen', # Turkmen
+ 'tl' => 'Tagalog', # Tagalog (Filipino)
+ #'tlh' => 'tlhIngan-Hol', # Klingon - no interlanguage links allowed
+ 'tn' => 'Setswana', # Setswana
+ 'to' => 'faka-Tonga', # Tonga (Tonga Islands)
+ 'tokipona' => 'Toki Pona', # Toki Pona
+ 'tp' => 'Toki Pona', # Toki Pona - non-standard language code
+ 'tpi' => 'Tok Pisin', # Tok Pisin
+ 'tr' => 'Türkçe', # Turkish
+ 'ts' => 'Xitsonga', # Tsonga
+ 'tt' => 'Tatarça', # Tatar
+ 'tum' => 'chiTumbuka', # Tumbuka
+ 'tw' => 'Twi', # Twi, (FIXME!)
+ 'ty' => 'Reo Mā`ohi', # Tahitian
+ 'tyv' => 'Тыва дыл', # Tyvan
+ 'udm' => 'Удмурт', # Udmurt
+ 'ug' => 'Oyghurque', # Uyghur
+ 'uk' => 'Українська', # Ukrainian
+ 'ur' => 'اردو', # Urdu
+ 'uz' => 'O\'zbek', # Uzbek
+ 've' => 'Tshivenda', # Venda
+ 'vec' => 'Vèneto', # Venetian
+ 'vi' => 'Tiếng Việt', # Vietnamese
+ 'vls' => 'West-Vlams', # West Flemish
+ 'vo' => 'Volapük', # Volapük
+ 'wa' => 'Walon', # Walloon
+ 'war' => 'Winaray', # Waray-Waray
+ 'wo' => 'Wollof', # Wolof
+ 'wuu' => '吴语', # Wu
+ 'xal' => 'Хальмг', # Kalmyk
+ 'xh' => 'isiXhosa', # Xhosan
+ 'yi' => 'ייִדיש', # Yiddish
+ 'yo' => 'Yorùbá', # Yoruba
+ 'za' => '(Cuengh)', # Zhuang
+ 'zea' => 'Zeêuws', # Zealandic
+ 'zh' => '中文', # (Zhōng Wén) - Chinese
+ 'zh-cfr' => '閩南語', # Min-nan alias (site is at minnan)
+ 'zh-classical' => '古文 / 文言文', # Classical Chinese/Literary Chinese
+ 'zh-cn' => '中文(简体)', # Simplified
+ 'zh-hk' => '中文(繁體)', # Traditional (Hong Kong)
+ 'zh-min-nan' => 'Bân-lâm-gú', # Min-nan -- (see bug 8217)
+ 'zh-sg' => '中文(简体)', # Simplified (Singapore)
+ 'zh-tw' => '中文(繁體)', # Traditional
+ 'zh-yue' => '粵語', # Cantonese
+ 'zu' => 'isiZulu' # Zulu
+);
+?>
diff --git a/languages/classes/LanguageAz.php b/languages/classes/LanguageAz.php
new file mode 100644
index 000000000000..d5df3ecc3e09
--- /dev/null
+++ b/languages/classes/LanguageAz.php
@@ -0,0 +1,17 @@
+<?php
+/** Azerbaijani (Azərbaycan)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageAz extends Language {
+ function ucfirst ( $string ) {
+ if ( $string[0] == 'i' ) {
+ return 'İ' . substr( $string, 1 );
+ } else {
+ return parent::ucfirst( $string );
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageBe.php b/languages/classes/LanguageBe.php
new file mode 100644
index 000000000000..553d2ad371e9
--- /dev/null
+++ b/languages/classes/LanguageBe.php
@@ -0,0 +1,89 @@
+<?php
+/** Belarusian (Беларуская мова)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @bug 1638, 2135
+ * @link http://be.wikipedia.org/wiki/Talk:LanguageBe.php
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
+ */
+
+class LanguageBe extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: родны, вінавальны, месны
+ */
+ function convertGrammar( $word, $case ) {
+ switch ( $case ) {
+ case 'родны': # genitive
+ if ( $word == 'Вікіпэдыя' ) {
+ $word = 'Вікіпэдыі';
+ } elseif ( $word == 'ВікіСлоўнік' ) {
+ $word = 'ВікіСлоўніка';
+ } elseif ( $word == 'ВікіКнігі' ) {
+ $word = 'ВікіКніг';
+ } elseif ( $word == 'ВікіКрыніца' ) {
+ $word = 'ВікіКрыніцы';
+ } elseif ( $word == 'ВікіНавіны' ) {
+ $word = 'ВікіНавін';
+ } elseif ( $word == 'ВікіВіды' ) {
+ $word = 'ВікіВідаў';
+ }
+ break;
+ case 'вінавальны': # akusative
+ if ( $word == 'Вікіпэдыя' ) {
+ $word = 'Вікіпэдыю';
+ } elseif ( $word == 'ВікіСлоўнік' ) {
+ $word = 'ВікіСлоўнік';
+ } elseif ( $word == 'ВікіКнігі' ) {
+ $word = 'ВікіКнігі';
+ } elseif ( $word == 'ВікіКрыніца' ) {
+ $word = 'ВікіКрыніцу';
+ } elseif ( $word == 'ВікіНавіны' ) {
+ $word = 'ВікіНавіны';
+ } elseif ( $word == 'ВікіВіды' ) {
+ $word = 'ВікіВіды';
+ }
+ break;
+ case 'месны': # prepositional
+ if ( $word == 'Вікіпэдыя' ) {
+ $word = 'Вікіпэдыі';
+ } elseif ( $word == 'ВікіСлоўнік' ) {
+ $word = 'ВікіСлоўніку';
+ } elseif ( $word == 'ВікіКнігі' ) {
+ $word = 'ВікіКнігах';
+ } elseif ( $word == 'ВікіКрыніца' ) {
+ $word = 'ВікіКрыніцы';
+ } elseif ( $word == 'ВікіНавіны' ) {
+ $word = 'ВікіНавінах';
+ } elseif ( $word == 'ВікіВіды' ) {
+ $word = 'ВікіВідах';
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'назоўны' (nominative) and all undefined case values
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageBg.php b/languages/classes/LanguageBg.php
new file mode 100644
index 000000000000..4884c2a8d833
--- /dev/null
+++ b/languages/classes/LanguageBg.php
@@ -0,0 +1,25 @@
+<?php
+/** Bulgarian (Български)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageBg extends Language {
+ /**
+ * ISO number formatting: 123 456 789,99.
+ * Avoid tripple grouping by numbers with whole part up to 4 digits.
+ */
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageBs.php b/languages/classes/LanguageBs.php
new file mode 100644
index 000000000000..92d000900d90
--- /dev/null
+++ b/languages/classes/LanguageBs.php
@@ -0,0 +1,137 @@
+<?php
+/** Bosnian (bosanski)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageBs extends Language {
+
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: genitiv, dativ, akuzativ, vokativ, instrumental, lokativ
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['bs'][$case][$word]) ) {
+ return $wgGrammarForms['bs'][$case][$word];
+ }
+ switch ( $case ) {
+ case 'genitiv': # genitive
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipedije';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjiga';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijesti';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitata';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikiizvora';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječnika';
+ }
+ break;
+ case 'dativ': # dative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjigama';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitatima';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijestima';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikiizvoru';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječniku';
+ }
+ break;
+ case 'akuzativ': # akusative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipediju';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjige';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitate';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijesti';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikiizvora';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječnika';
+ }
+ break;
+ case 'vokativ': # vocative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'Wikipedijo';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjige';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'Wikicitati';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'Wikivijesti';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'Wikizivoru';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'Vikirječniče';
+ }
+ break;
+ case 'instrumental': # instrumental
+ if ( $word == 'Wikipedia' ) {
+ $word = 's Wikipediom';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 's Wikiknjigama';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 's Wikicitatima';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 's Wikivijestima';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 's Wikiizvorom';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 's Vikirječnikom';
+ } else {
+ $word = 's ' . $word;
+ }
+ break;
+ case 'lokativ': # locative
+ if ( $word == 'Wikipedia' ) {
+ $word = 'o Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'o Wikiknjigama';
+ } elseif ( $word == 'Wikicitati' ) {
+ $word = 'o Wikicitatima';
+ } elseif ( $word == 'Wikivijesti' ) {
+ $word = 'o Wikivijestima';
+ } elseif ( $word == 'Wikiizvor' ) {
+ $word = 'o Wikiizvoru';
+ } elseif ( $word == 'Vikirječnik' ) {
+ $word = 'o Vikirječniku';
+ } else {
+ $word = 'o ' . $word;
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'nominativ' (nominative) and all undefined case values
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageCs.php b/languages/classes/LanguageCs.php
new file mode 100644
index 000000000000..bd2f33a3f706
--- /dev/null
+++ b/languages/classes/LanguageCs.php
@@ -0,0 +1,87 @@
+<?php
+/** Czech (česky)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageCs extends Language {
+ # Grammatical transformations, needed for inflected languages
+ # Invoked by putting {{grammar:case|word}} in a message
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['cs'][$case][$word]) ) {
+ return $wgGrammarForms['cs'][$case][$word];
+ }
+ # allowed values for $case:
+ # 1sg, 2sg, ..., 7sg -- nominative, genitive, ... (in singular)
+ switch ( $word ) {
+ case 'Wikipedia':
+ case 'Wikipedie':
+ switch ( $case ) {
+ case '3sg':
+ case '4sg':
+ case '6sg':
+ return 'Wikipedii';
+ case '7sg':
+ return 'Wikipedií';
+ default:
+ return 'Wikipedie';
+ }
+
+ case 'Wiktionary':
+ case 'Wikcionář':
+ switch ( $case ) {
+ case '2sg':
+ return 'Wikcionáře';
+ case '3sg':
+ case '5sg';
+ case '6sg';
+ return 'Wikcionáři';
+ case '7sg':
+ return 'Wikcionářem';
+ default:
+ return 'Wikcionář';
+ }
+
+ case 'Wikiquote':
+ case 'Wikicitáty':
+ switch ( $case ) {
+ case '2sg':
+ return 'Wikicitátů';
+ case '3sg':
+ return 'Wikicitátům';
+ case '6sg';
+ return 'Wikicitátech';
+ default:
+ return 'Wikicitáty';
+ }
+ }
+ # unknown
+ return $word;
+ }
+
+ # Plural form transformations, needed for some languages.
+ # Invoked by {{plural:count|wordform1|wordform2|wordform3}}
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ $count = str_replace( '\xc2\xa0', '', $count );
+ switch ( $count ) {
+ case 1:
+ return $wordform1;
+
+ case 2:
+ case 3:
+ case 4:
+ return $wordform2;
+
+ default:
+ return $wordform3;
+ };
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageCu.php b/languages/classes/LanguageCu.php
new file mode 100644
index 000000000000..f30bd2536448
--- /dev/null
+++ b/languages/classes/LanguageCu.php
@@ -0,0 +1,50 @@
+<?php
+/** Old Church Slavonic (Ѩзыкъ словѣньскъ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/* Please, see Language.php for general function comments */
+class LanguageCu extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{grammar:case|word}}
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['сu'][$case][$word]) ) {
+ return $wgGrammarForms['сu'][$case][$word];
+ }
+
+ # These rules are not perfect, but they are currently only used for site names so it doesn't
+ # matter if they are wrong sometimes. Just add a special case for your site name if necessary.
+
+ #join and array_slice instead mb_substr
+ $ar = array();
+ preg_match_all( '/./us', $word, $ar );
+ if (!preg_match("/[a-zA-Z_]/us", $word))
+ switch ( $case ) {
+ case 'genitive': #родительный падеж
+ if ((join('',array_slice($ar[0],-4))=='вики') || (join('',array_slice($ar[0],-4))=='Вики'))
+ {}
+ elseif (join('',array_slice($ar[0],-2))=='ї')
+ $word = join('',array_slice($ar[0],0,-2)).'їѩ';
+ break;
+ case 'accusative': #винительный падеж
+ #stub
+ break;
+ }
+ return $word;
+ }
+
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $wordform4, $w5) {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2: return $wordform2;
+ case 3: return $wordform3;
+ case 4: return $wordform3;
+ default: return $wordform4;
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageEo.php b/languages/classes/LanguageEo.php
new file mode 100644
index 000000000000..a62ccc9b59c2
--- /dev/null
+++ b/languages/classes/LanguageEo.php
@@ -0,0 +1,74 @@
+<?php
+/** Esperanto (Esperanto)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageEo extends Language {
+ function iconv( $in, $out, $string ) {
+ # For most languages, this is a wrapper for iconv
+ # Por multaj lingvoj, ĉi tiu nur voku la sisteman funkcion iconv()
+ # Ni ankaŭ konvertu X-sistemajn surogotajn
+ if( strcasecmp( $in, 'x' ) == 0 and strcasecmp( $out, 'utf-8' ) == 0) {
+ $xu = array (
+ 'xx' => 'x' , 'xX' => 'x' ,
+ 'Xx' => 'X' , 'XX' => 'X' ,
+ "Cx" => "\xc4\x88" , "CX" => "\xc4\x88" ,
+ "cx" => "\xc4\x89" , "cX" => "\xc4\x89" ,
+ "Gx" => "\xc4\x9c" , "GX" => "\xc4\x9c" ,
+ "gx" => "\xc4\x9d" , "gX" => "\xc4\x9d" ,
+ "Hx" => "\xc4\xa4" , "HX" => "\xc4\xa4" ,
+ "hx" => "\xc4\xa5" , "hX" => "\xc4\xa5" ,
+ "Jx" => "\xc4\xb4" , "JX" => "\xc4\xb4" ,
+ "jx" => "\xc4\xb5" , "jX" => "\xc4\xb5" ,
+ "Sx" => "\xc5\x9c" , "SX" => "\xc5\x9c" ,
+ "sx" => "\xc5\x9d" , "sX" => "\xc5\x9d" ,
+ "Ux" => "\xc5\xac" , "UX" => "\xc5\xac" ,
+ "ux" => "\xc5\xad" , "uX" => "\xc5\xad"
+ ) ;
+ return preg_replace ( '/([cghjsu]x?)((?:xx)*)(?!x)/ei',
+ 'strtr( "$1", $xu ) . strtr( "$2", $xu )', $string );
+ } else if( strcasecmp( $in, 'UTF-8' ) == 0 and strcasecmp( $out, 'x' ) == 0 ) {
+ $ux = array (
+ 'x' => 'xx' , 'X' => 'Xx' ,
+ "\xc4\x88" => "Cx" , "\xc4\x89" => "cx" ,
+ "\xc4\x9c" => "Gx" , "\xc4\x9d" => "gx" ,
+ "\xc4\xa4" => "Hx" , "\xc4\xa5" => "hx" ,
+ "\xc4\xb4" => "Jx" , "\xc4\xb5" => "jx" ,
+ "\xc5\x9c" => "Sx" , "\xc5\x9d" => "sx" ,
+ "\xc5\xac" => "Ux" , "\xc5\xad" => "ux"
+ ) ;
+ # Double Xs only if they follow cxapelutaj literoj.
+ return preg_replace( '/((?:[cghjsu]|\xc4[\x88\x89\x9c\x9d\xa4\xa5\xb4\xb5]'.
+ '|\xc5[\x9c\x9d\xac\xad])x*)/ei', 'strtr( "$1", $ux )', $string );
+ }
+ return iconv( $in, $out, $string );
+ }
+
+ function checkTitleEncoding( $s ) {
+ # Check for X-system backwards-compatibility URLs
+ $ishigh = preg_match( '/[\x80-\xff]/', $s);
+ $isutf = preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
+
+ if($ishigh and !$isutf) {
+ # Assume Latin1
+ $s = utf8_encode( $s );
+ } else {
+ if( preg_match( '/(\xc4[\x88\x89\x9c\x9d\xa4\xa5\xb4\xb5]'.
+ '|\xc5[\x9c\x9d\xac\xad])/', $s ) )
+ return $s;
+ }
+
+ //if( preg_match( '/[cghjsu]x/i', $s ) )
+ // return $this->iconv( 'x', 'utf-8', $s );
+ return $s;
+ }
+
+ function initEncoding() {
+ global $wgEditEncoding;
+ $wgEditEncoding = 'x';
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageEt.php b/languages/classes/LanguageEt.php
new file mode 100644
index 000000000000..928434061907
--- /dev/null
+++ b/languages/classes/LanguageEt.php
@@ -0,0 +1,21 @@
+<?php
+/** Estonian (Eesti)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguageEt extends Language {
+ /**
+ * Avoid grouping whole numbers between 0 to 9999
+ */
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageFi.php b/languages/classes/LanguageFi.php
new file mode 100644
index 000000000000..8fc254996d18
--- /dev/null
+++ b/languages/classes/LanguageFi.php
@@ -0,0 +1,140 @@
+<?php
+/** Finnish (Suomi)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Niklas Laxström
+ */
+class LanguageFi extends Language {
+ /**
+ * Avoid grouping whole numbers between 0 to 9999
+ */
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['fi'][$case][$word]) ) {
+ return $wgGrammarForms['fi'][$case][$word];
+ }
+
+ # These rules are not perfect, but they are currently only used for site names so it doesn't
+ # matter if they are wrong sometimes. Just add a special case for your site name if necessary.
+
+ # wovel harmony flag
+ $aou = preg_match( '/[aou][^äöy]*$/i', $word );
+
+ # append i after final consonant
+ if ( preg_match( '/[bcdfghjklmnpqrstvwxz]$/i', $word ) )
+ $word .= 'i';
+
+ switch ( $case ) {
+ case 'genitive':
+ $word .= 'n';
+ break;
+ case 'elative':
+ $word .= ($aou ? 'sta' : 'stä');
+ break;
+ case 'partitive':
+ $word .= ($aou ? 'a' : 'ä');
+ break;
+ case 'illative':
+ # Double the last letter and add 'n'
+ # mb_substr has a compatibility function in GlobalFunctions.php
+ $word = $word . mb_substr($word, -1) . 'n';
+ break;
+ case 'inessive':
+ $word .= ($aou ? 'ssa' : 'ssä');
+ break;
+ }
+ return $word;
+ }
+
+ function translateBlockExpiry( $str ) {
+ /*
+ 'ago', 'now', 'today', 'this', 'next',
+ 'first', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth',
+ 'tomorrow', 'yesterday'
+
+ $months = 'january:tammikuu,february:helmikuu,march:maaliskuu,april:huhtikuu,may:toukokuu,june:kesäkuu,' .
+ 'july:heinäkuu,august:elokuu,september:syyskuu,october:lokakuu,november:marraskuu,december:joulukuu,' .
+ 'jan:tammikuu,feb:helmikuu,mar:maaliskuu,apr:huhtikuu,jun:kesäkuu,jul:heinäkuu,aug:elokuu,sep:syyskuu,'.
+ 'oct:lokakuu,nov:marraskuu,dec:joulukuu,sept:syyskuu';
+ */
+ $weekds = array(
+ 'monday' => 'maanantai',
+ 'tuesday' => 'tiistai',
+ 'wednesday' => 'keskiviikko',
+ 'thursay' => 'torstai',
+ 'friday' => 'perjantai',
+ 'saturday' => 'lauantai',
+ 'sunday' => 'sunnuntai',
+ 'mon' => 'ma',
+ 'tue' => 'ti',
+ 'tues' => 'ti',
+ 'wed' => 'ke',
+ 'wednes' => 'ke',
+ 'thu' => 'to',
+ 'thur' => 'to',
+ 'thurs' => 'to',
+ 'fri' => 'pe',
+ 'sat' => 'la',
+ 'sun' => 'su',
+ 'next' => 'seuraava',
+ 'tomorrow' => 'huomenna',
+ 'ago' => 'sitten',
+ 'seconds' => 'sekuntia',
+ 'second' => 'sekunti',
+ 'secs' => 's',
+ 'sec' => 's',
+ 'minutes' => 'minuuttia',
+ 'minute' => 'minuutti',
+ 'mins' => 'min',
+ 'min' => 'min',
+ 'days' => 'päivää',
+ 'day' => 'päivä',
+ 'hours' => 'tuntia',
+ 'hour' => 'tunti',
+ 'weeks' => 'viikkoa',
+ 'week' => 'viikko',
+ 'fortnights' => 'tuplaviikkoa',
+ 'fortnight' => 'tuplaviikko',
+ 'months' => 'kuukautta',
+ 'month' => 'kuukausi',
+ 'years' => 'vuotta',
+ 'year' => 'vuosi',
+ 'infinite' => 'ikuisesti',
+ 'indefinite' => 'ikuisesti'
+ );
+
+ $final = '';
+ $tokens = explode ( ' ', $str);
+ foreach( $tokens as $item ) {
+ if ( !is_numeric($item) ) {
+ if ( count ( explode( '-', $item ) ) == 3 && strlen($item) == 10 ) {
+ list( $yyyy, $mm, $dd ) = explode( '-', $item );
+ $final .= ' ' . $this->date( "{$yyyy}{$mm}{$dd}00000000");
+ continue;
+ }
+ if( isset( $weekds[$item] ) ) {
+ $final .= ' ' . $weekds[$item];
+ continue;
+ }
+ }
+
+ $final .= ' ' . $item;
+ }
+ return '<span class="blockexpiry" title="' . htmlspecialchars($str). '">”' . trim( $final ) . '”</span>';
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageFr.php b/languages/classes/LanguageFr.php
new file mode 100644
index 000000000000..b150ceff6116
--- /dev/null
+++ b/languages/classes/LanguageFr.php
@@ -0,0 +1,17 @@
+<?php
+/** French (Français)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguageFr extends Language {
+ /**
+ * Use singular form for zero (see bug 7309)
+ */
+ function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
+ return $count <= '1' ? $w1 : $w2;
+ }
+}
+?>
diff --git a/languages/classes/LanguageGa.php b/languages/classes/LanguageGa.php
new file mode 100644
index 000000000000..0779e42b73d5
--- /dev/null
+++ b/languages/classes/LanguageGa.php
@@ -0,0 +1,52 @@
+<?php
+/** Irish (Gaeilge)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageGa extends Language {
+ # Convert day names
+ # Invoked with {{GRAMMAR:transformation|word}}
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['ga'][$case][$word]) ) {
+ return $wgGrammarForms['ga'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitive':
+ switch ($word) {
+ case 'Vicipéid': $word = 'Vicipéide'; break;
+ case 'Vicífhoclóir': $word = 'Vicífhoclóra'; break;
+ case 'Vicíleabhair': $word = 'Vicíleabhar'; break;
+ case 'Vicíshliocht': $word = 'Vicíshleachta'; break;
+ case 'Vicífhoinse': $word = 'Vicífhoinse'; break;
+ case 'Vicíghnéithe': $word = 'Vicíghnéithe'; break;
+ case 'Vicínuacht': $word = 'Vicínuachta'; break;
+ }
+
+ case 'ainmlae':
+ switch ($word) {
+ case 'an Domhnach':
+ $word = 'Dé Domhnaigh'; break;
+ case 'an Luan':
+ $word = 'Dé Luain'; break;
+ case 'an Mháirt':
+ $word = 'Dé Mháirt'; break;
+ case 'an Chéadaoin':
+ $word = 'Dé Chéadaoin'; break;
+ case 'an Déardaoin':
+ $word = 'Déardaoin'; break;
+ case 'an Aoine':
+ $word = 'Dé hAoine'; break;
+ case 'an Satharn':
+ $word = 'Dé Sathairn'; break;
+ }
+ }
+ return $word;
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageGsw.php b/languages/classes/LanguageGsw.php
new file mode 100644
index 000000000000..ce4e05786944
--- /dev/null
+++ b/languages/classes/LanguageGsw.php
@@ -0,0 +1,69 @@
+<?php
+/** Alemannic (Alemannisch)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageGsw extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with result
+
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['gsw'][$case][$word]) ) {
+ return $wgGrammarForms['gsw'][$case][$word];
+ }
+ switch ( $case ) {
+ case 'dativ':
+ if ( $word == 'Wikipedia' ) {
+ $word = 'vo de Wikipedia';
+ } elseif ( $word == 'Wikinorchrichte' ) {
+ $word = 'vo de Wikinochrichte';
+ } elseif ( $word == 'Wiktionaire' ) {
+ $word = 'vom Wiktionaire';
+ } elseif ( $word == 'Wikibuecher' ) {
+ $word = 'vo de Wikibuecher';
+ } elseif ( $word == 'Wikisprüch' ) {
+ $word = 'vo de Wikisprüch';
+ } elseif ( $word == 'Wikiquälle' ) {
+ $word = 'vo de Wikiquälle';
+ }
+ break;
+ case 'akkusativ':
+ if ( $word == 'Wikipedia' ) {
+ $word = 'd Wikipedia';
+ } elseif ( $word == 'Wikinorchrichte' ) {
+ $word = 'd Wikinochrichte';
+ } elseif ( $word == 'Wiktionaire' ) {
+ $word = 's Wiktionaire';
+ } elseif ( $word == 'Wikibuecher' ) {
+ $word = 'd Wikibuecher';
+ } elseif ( $word == 'Wikisprüch' ) {
+ $word = 'd Wikisprüch';
+ } elseif ( $word == 'Wikiquälle' ) {
+ $word = 'd Wikiquälle';
+ }
+ break;
+ case 'nominativ':
+ if ( $word == 'Wikipedia' ) {
+ $word = 'd Wikipedia';
+ } elseif ( $word == 'Wikinorchrichte' ) {
+ $word = 'd Wikinochrichte';
+ } elseif ( $word == 'Wiktionaire' ) {
+ $word = 's Wiktionaire';
+ } elseif ( $word == 'Wikibuecher' ) {
+ $word = 'd Wikibuecher';
+ } elseif ( $word == 'Wikisprüch' ) {
+ $word = 'd Wikisprüch';
+ } elseif ( $word == 'Wikiquälle' ) {
+ $word = 'd Wikiquälle';
+ }
+ break;
+ }
+ return $word;
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageHe.php b/languages/classes/LanguageHe.php
new file mode 100644
index 000000000000..e84d45d8cdd8
--- /dev/null
+++ b/languages/classes/LanguageHe.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Hebrew (עברית)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Rotem Liss
+ */
+
+class LanguageHe extends Language {
+ /**
+ * Convert grammar forms of words.
+ *
+ * Available cases:
+ * "prefixed" (or "תחילית") - when the word has a prefix
+ *
+ * @param string the word to convert
+ * @param string the case
+ */
+ public function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['he'][$case][$word]) ) {
+ return $wgGrammarForms['he'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'prefixed':
+ case 'תחילית':
+ # Duplicate the "Waw" if prefixed
+ if ( substr( $word, 0, 2 ) == "ו" && substr( $word, 0, 4 ) != "וו" ) {
+ $word = "ו".$word;
+ }
+
+ # Remove the "He" if prefixed
+ if ( substr( $word, 0, 2 ) == "ה" ) {
+ $word = substr( $word, 2 );
+ }
+
+ # Add a hyphen if non-Hebrew letters
+ if ( substr( $word, 0, 2 ) < "א" || substr( $word, 0, 2 ) > "ת" ) {
+ $word = "־".$word;
+ }
+ }
+
+ return $word;
+ }
+
+ /**
+ * Gets a number and uses the suited form of the word.
+ *
+ * @param integer the number of items
+ * @param string the first form (singular)
+ * @param string the second form (plural)
+ * @param string the third form (2 items, plural is used if not applicable and not specified
+ * @param not used (for compatibility with ancestor)
+ * @param not used (for compatibility with ancestor)
+ *
+ * @return string of the suited form of word
+ */
+ public function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
+ if ( $count == '1' ) {
+ return $w1;
+ } elseif ( $count == '2' && $w3 ) {
+ return $w3;
+ } else {
+ return $w2;
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageHr.php b/languages/classes/LanguageHr.php
new file mode 100644
index 000000000000..537c142ddbee
--- /dev/null
+++ b/languages/classes/LanguageHr.php
@@ -0,0 +1,26 @@
+<?php
+/** Croatian (hrvatski)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageHr extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageHsb.php b/languages/classes/LanguageHsb.php
new file mode 100644
index 000000000000..08163b7294ca
--- /dev/null
+++ b/languages/classes/LanguageHsb.php
@@ -0,0 +1,117 @@
+<?php
+/** Upper Sorbian (Hornjoserbsce)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageHsb extends Language {
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset( $wgGrammarForms['hsb'][$case][$word] ) ) {
+ return $wgGrammarForms['hsb'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitiw': # genitive
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipedije';
+ } elseif ( $word == 'Wikiknihi' ) {
+ $word = 'Wikiknih';
+ } elseif ( $word == 'Wikinowiny' ) {
+ $word = 'Wikinowin';
+ } elseif ( $word == 'Wikižórło' ) {
+ $word = 'Wikižórła';
+ } elseif ( $word == 'Wikicitaty' ) {
+ $word = 'Wikicitatow';
+ } elseif ( $word == 'Wikisłownik' ) {
+ $word = 'Wikisłownika';
+ }
+ break;
+ case 'datiw': # dativ
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Wikiknihi' ) {
+ $word = 'Wikikniham';
+ } elseif ( $word == 'Wikinowiny' ) {
+ $word = 'Wikinowinam';
+ } elseif ( $word == 'Wikižórło' ) {
+ $word = 'Wikižórłu';
+ } elseif ( $word == 'Wikicitaty' ) {
+ $word = 'Wikicitatam';
+ } elseif ( $word == 'Wikisłownik' ) {
+ $word = 'Wikisłownikej';
+ }
+ break;
+ case 'akuzativ': # akuzativ
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipediju';
+ } elseif ( $word == 'Wikiknihi' ) {
+ $word = 'Wikiknknihi';
+ } elseif ( $word == 'Wikinowiny' ) {
+ $word = 'Wikinowiny';
+ } elseif ( $word == 'Wikižórło' ) {
+ $word = 'Wikižórło';
+ } elseif ( $word == 'Wikicitaty' ) {
+ $word = 'Wikicitaty';
+ } elseif ( $word == 'Wikisłownik' ) {
+ $word = 'Wikisłownik';
+ }
+ break;
+ case 'instrumental': # instrumental
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipediju';
+ } elseif ( $word == 'Wikiknihi' ) {
+ $word = 'Wikiknihami';
+ } elseif ( $word == 'Wikinowiny' ) {
+ $word = 'Wikinowinami';
+ } elseif ( $word == 'Wikižórło' ) {
+ $word = 'Wikižórłom';
+ } elseif ( $word == 'Wikicitaty' ) {
+ $word = 'Wikicitatami';
+ } elseif ( $word == 'Wikisłownik' ) {
+ $word = 'Wikisłownikom';
+ } else {
+ $word = 'z ' . $word;
+ }
+ break;
+ case 'lokatiw': # lokatiw
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Wikiknihi' ) {
+ $word = 'Wikiknihach';
+ } elseif ( $word == 'Wikinowiny' ) {
+ $word = 'Wikinowinach';
+ } elseif ( $word == 'Wikižórło' ) {
+ $word = 'Wikižórłu';
+ } elseif ( $word == 'Wikicitaty' ) {
+ $word = 'Wikicitatach';
+ } elseif ( $word == 'Wikisłownik' ) {
+ $word = 'Wikisłowniku';
+ } else {
+ $word = 'wo ' . $word;
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'nominatiw' (nominativ) and all undefined case values
+ }
+
+ function convertPlural( $count, $singular, $dual, $plural, $pluralgen, $w5 ) {
+ switch ( abs( $count ) % 100 ) {
+ case 1:
+ return $singular;
+ case 2:
+ return $dual;
+ case 3:
+ case 4:
+ return $plural;
+ default:
+ return $pluralgen;
+ }
+ }
+}
diff --git a/languages/classes/LanguageHu.php b/languages/classes/LanguageHu.php
new file mode 100644
index 000000000000..ac6555dc34fd
--- /dev/null
+++ b/languages/classes/LanguageHu.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+#
+# Hungarian localisation for MediaWiki
+#
+
+class LanguageHu extends Language {
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms[$this->getCode()][$case][$word]) ) {
+ return $wgGrammarForms[$this->getCode()][$case][$word];
+ }
+
+ static $localForms = array(
+ 'rol' => array(
+ 'Wikipédia' => 'Wikipédiáról',
+ 'Wikidézet' => 'Wikidézetről',
+ 'Wikiszótár' => 'Wikiszótárról',
+ 'Wikikönyvek' => 'Wikikönyvekről',
+ ),
+ 'ba' => array(
+ 'Wikipédia' => 'Wikipédiába',
+ 'Wikidézet' => 'Wikidézetbe',
+ 'Wikiszótár' => 'Wikiszótárba',
+ 'Wikikönyvek' => 'Wikikönyvekbe',
+ ),
+ 'k' => array(
+ 'Wikipédia' => 'Wikipédiák',
+ 'Wikidézet' => 'Wikidézetek',
+ 'Wikiszótár' => 'Wikiszótárak',
+ 'Wikikönyvek' => 'Wikikönyvek',
+ )
+ );
+
+ if ( isset( $localForms[$case][$word] ) ) {
+ return $localForms[$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'rol':
+ return $word . 'ról';
+ case 'ba':
+ return $word . 'ba';
+ case 'k':
+ return $word . 'k';
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageJa.php b/languages/classes/LanguageJa.php
new file mode 100644
index 000000000000..800650b046cc
--- /dev/null
+++ b/languages/classes/LanguageJa.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Japanese (日本語)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageJa extends Language {
+ function stripForSearch( $string ) {
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+ $s = $string;
+
+ # Strip known punctuation ?
+ #$s = preg_replace( '/\xe3\x80[\x80-\xbf]/', '', $s ); # U3000-303f
+
+ # Space strings of like hiragana/katakana/kanji
+ $hiragana = '(?:\xe3(?:\x81[\x80-\xbf]|\x82[\x80-\x9f]))'; # U3040-309f
+ $katakana = '(?:\xe3(?:\x82[\xa0-\xbf]|\x83[\x80-\xbf]))'; # U30a0-30ff
+ $kanji = '(?:\xe3[\x88-\xbf][\x80-\xbf]'
+ . '|[\xe4-\xe8][\x80-\xbf]{2}'
+ . '|\xe9[\x80-\xa5][\x80-\xbf]'
+ . '|\xe9\xa6[\x80-\x99])';
+ # U3200-9999 = \xe3\x88\x80-\xe9\xa6\x99
+ $s = preg_replace( "/({$hiragana}+|{$katakana}+|{$kanji}+)/", ' $1 ', $s );
+
+ # Double-width roman characters: ff00-ff5f ~= 0020-007f
+ $s = preg_replace( '/\xef\xbc([\x80-\xbf])/e', 'chr((ord("$1") & 0x3f) + 0x20)', $s );
+ $s = preg_replace( '/\xef\xbd([\x80-\x99])/e', 'chr((ord("$1") & 0x3f) + 0x60)', $s );
+
+ # Do general case folding and UTF-8 armoring
+ return parent::stripForSearch( $s );
+ }
+
+ # Italic is not appropriate for Japanese script
+ # Unfortunately most browsers do not recognise this, and render <em> as italic
+ function emphasize( $text ) {
+ return $text;
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageKk.deps.php b/languages/classes/LanguageKk.deps.php
new file mode 100644
index 000000000000..22ad7ad58231
--- /dev/null
+++ b/languages/classes/LanguageKk.deps.php
@@ -0,0 +1,12 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// LanguageKk.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+require_once( dirname(__FILE__).'/LanguageKk_kz.php' );
+
+?>
diff --git a/languages/classes/LanguageKk.php b/languages/classes/LanguageKk.php
new file mode 100644
index 000000000000..46162e01adc7
--- /dev/null
+++ b/languages/classes/LanguageKk.php
@@ -0,0 +1,210 @@
+<?php
+/** Kazakh (Қазақша)
+ * converter routines
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+require_once( dirname(__FILE__).'/LanguageKk_kz.php' );
+
+class KkConverter extends LanguageConverter {
+ var $mLatinToCyrillic = array(
+ 'YA' => 'Я', 'Ya' => 'Я', 'ya' => 'я', 'YE' => 'Е', 'Ye' => 'У', 'ye' => 'е',
+ 'YO' => 'Ё', 'Yo' => 'Ё', 'yo' => 'ё', 'YU' => 'Ю', 'Yu' => 'Ю', 'yu' => 'ю',
+ 'YW' => 'Ю', 'Yw' => 'Ю', 'yw' => 'ю',
+
+ 'bʺ' => 'бъ', 'dʺ' => 'дъ', 'fʺ' => 'фъ', 'gʺ' => 'гъ', 'kʺ' => 'къ', 'lʺ' => 'лъ',
+ 'mʺ' => 'мъ', 'nʺ' => 'нъ', 'pʺ' => 'пъ', 'rʺ' => 'ръ', 'sʺ' => 'съ', 'tʺ' => 'тъ',
+ 'vʺ' => 'въ', 'zʺ' => 'зъ',
+ /* 'jʺ' => 'жъ', 'cʺ' => 'цъ', 'çʺ' => 'чъ', 'şʺ' => 'шъ', */
+
+ 'ŞÇʹ'=> 'ЩЬ', 'Şçʹ'=> 'Щь', 'Bʺ' => 'БЪ', 'Dʺ' => 'ДЪ', 'Fʺ' => 'ФЪ', 'Gʺ' => 'ГЪ', 'Kʺ' => 'КЪ', 'Lʺ' => 'ЛЪ',
+ 'Mʺ' => 'МЪ', 'Nʺ' => 'НЪ', 'Pʺ' => 'ПЪ', 'Rʺ' => 'РЪ', 'Sʺ' => 'СЪ', 'Tʺ' => 'ТЪ',
+ 'Vʺ' => 'ВЪ', 'Zʺ' => 'ЗЪ',
+ /* 'Jʺ' => 'ЖЪ', 'Cʺ' => 'ЦЪ', 'Çʺ' => 'ЧЪ', 'Şʺ' => 'ШЪ', */
+
+ 'şçʹ'=> 'щь', 'bʹ' => 'бь', 'dʹ' => 'дь', 'fʹ' => 'фь', 'gʹ' => 'гь', 'kʹ' => 'кь', 'lʹ' => 'ль',
+ 'mʹ' => 'мь', 'nʹ' => 'нь', 'pʹ' => 'пь', 'rʹ' => 'рь', 'sʹ' => 'сь', 'tʹ' => 'ть',
+ 'vʹ' => 'вь', 'zʹ' => 'зь', 'jʹ' => 'жь', 'cʹ' => 'ць', 'çʹ' => 'чь', 'şʹ' => 'шь',
+
+ 'Bʹ' => 'БЬ', 'Dʹ' => 'ДЬ', 'Fʹ' => 'ФЬ', 'Gʹ' => 'ГЬ', 'Kʹ' => 'КЬ', 'Lʹ' => 'ЛЬ',
+ 'Mʹ' => 'МЬ', 'Nʹ' => 'НЬ', 'Pʹ' => 'ПЬ', 'Rʹ' => 'РЬ', 'Sʹ' => 'СЬ', 'Tʹ' => 'ТЬ',
+ 'Vʹ' => 'ВЬ', 'Zʹ' => 'ЗЬ', 'Jʹ' => 'ЖЬ', 'Cʹ' => 'ЦЬ', 'Çʹ' => 'ЧЬ', 'Şʹ' => 'ШЬ',
+
+ 'ŞÇ' => 'Щ', 'Şç' => 'Щ', 'şç' => 'щ',
+
+ 'a' => 'а', 'ä' => 'ә', 'b' => 'б', 'c' => 'ц', 'ç' => 'ч', 'd' => 'д', 'e' => 'е',
+ 'é' => 'э', 'f' => 'ф', 'g' => 'г', 'ğ' => 'ғ', 'h' => 'һ', 'i' => 'і', 'ı' => 'ы',
+ 'ï' => 'и', 'j' => 'ж', 'k' => 'к', 'l' => 'л', 'm' => 'м', 'n' => 'н', 'ñ' => 'ң',
+ 'o' => 'о', 'ö' => 'ө', 'p' => 'п', 'q' => 'қ', 'r' => 'р', 's' => 'с', 'ş' => 'ш',
+ 't' => 'т', 'u' => 'ұ', 'ü' => 'ү', 'v' => 'в', 'w' => 'у', 'x' => 'х', 'ý' => 'й',
+ 'z' => 'з',
+
+ 'A' => 'А', 'Ä' => 'Ә', 'B' => 'Б', 'C' => 'Ц', 'Ç' => 'Ч', 'D' => 'Д', 'E' => 'Е',
+ 'É' => 'Э', 'F' => 'Ф', 'G' => 'Г', 'Ğ' => 'Ғ', 'H' => 'Һ', 'İ' => 'І', 'I' => 'Ы',
+ 'Ï' => 'И', 'J' => 'Ж', 'K' => 'К', 'L' => 'Л', 'M' => 'М', 'N' => 'Н', 'Ñ' => 'Ң',
+ 'O' => 'О', 'Ö' => 'Ө', 'P' => 'П', 'Q' => 'Қ', 'R' => 'Р', 'S' => 'С', 'Ş' => 'Ш',
+ 'T' => 'Т', 'U' => 'Ұ', 'Ü' => 'Ү', 'V' => 'В', 'W' => 'У', 'Ý' => 'Й', 'X' => 'Х',
+ 'Z' => 'З'
+ );
+
+ var $mCyrillicToLatin = array(
+ 'а' => 'a', 'ә' => 'ä', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'ғ' => 'ğ',
+ 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 'ж' => 'j', 'з' => 'z', 'и' => 'ï',
+ 'й' => 'ý', 'к' => 'k', 'қ' => 'q', 'л' => 'l', 'м' => 'm', 'н' => 'n',
+ 'ң' => 'ñ', 'о' => 'o', 'ө' => 'ö', 'п' => 'p', 'р' => 'r', 'с' => 's',
+ 'т' => 't', 'у' => 'w', 'ұ' => 'u', 'ү' => 'ü', 'ф' => 'f', 'х' => 'x',
+ 'һ' => 'h', 'ц' => 'c', 'ч' => 'ç', 'ш' => 'ş', 'щ' => 'şç', 'ъ' => 'ʺ',
+ 'ы' => 'ı', 'ь' => 'ʹ', 'і' => 'i', 'э' => 'é', 'ю' => 'yw', 'я' => 'ya',
+
+ 'А' => 'A', 'Ә' => 'Ä', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Ғ' => 'Ğ',
+ 'Д' => 'D', 'Е' => 'E', 'Ё' => 'Yo', 'Ж' => 'J', 'З' => 'Z', 'И' => 'Ï',
+ 'Й' => 'Ý', 'К' => 'K', 'Қ' => 'Q', 'Л' => 'L', 'М' => 'M', 'Н' => 'N',
+ 'Ң' => 'Ñ', 'О' => 'O', 'Ө' => 'Ö', 'П' => 'P', 'Р' => 'R', 'С' => 'S',
+ 'Т' => 'T', 'У' => 'W', 'Ұ' => 'U', 'Ү' => 'Ü', 'Ф' => 'F', 'Х' => 'X',
+ 'Һ' => 'H', 'Ц' => 'C', 'Ч' => 'Ç', 'Ш' => 'Ş', 'Щ' => 'Şç', 'Ъ' => 'ʺ',
+ 'Ы' => 'I', 'Ь' => 'ʹ', 'І' => 'İ', 'Э' => 'É', 'Ю' => 'Yw', 'Я' => 'Ya'
+ );
+
+ var $mCyrillicToArabic = array(
+ 'ла' => 'لا', 'ЛА' => 'لا', 'Ла' => 'لا',
+
+ 'а' => 'ا', 'ә' => 'ٴا', 'б' => 'ب', 'в' => 'ۆ', 'г' => 'گ', 'ғ' => 'ع',
+ 'д' => 'د', 'е' => 'ە', 'ё' => 'يو', 'ж' => 'ج', 'з' => 'ز', 'и' => 'ي',
+ 'й' => 'ي', 'к' => 'ك', 'қ' => 'ق', 'л' => 'ل', 'м' => 'م', 'н' => 'ن',
+ 'ң' => 'ڭ', 'о' => 'و', 'ө' => 'ٴو', 'п' => 'پ', 'р' => 'ر', 'с' => 'س',
+ 'т' => 'ت', 'у' => 'ۋ', 'ұ' => 'ۇ', 'ү' => 'ٴۇ', 'ф' => 'ف', 'х' => 'ح',
+ 'һ' => 'ھ', 'ц' => 'تس', 'ч' => 'چ', 'ш' => 'ش', 'щ' => 'شش', 'ъ' => 'ي',
+ 'ы' => 'ى', 'ь' => 'ي', 'і' => 'ٴى', 'э' => 'ە', 'ю' => 'يۋ', 'я' => 'يا',
+
+ 'А' => 'ا', 'Ә' => 'ٴا', 'Б' => 'ب', 'В' => 'ۆ', 'Г' => 'گ', 'Ғ' => 'ع',
+ 'Д' => 'د', 'Е' => 'ە', 'Ё' => 'يو', 'Ж' => 'ج', 'З' => 'ز', 'И' => 'ي',
+ 'Й' => 'ي', 'К' => 'ك', 'Қ' => 'ق', 'Л' => 'ل', 'М' => 'م', 'Н' => 'ن',
+ 'Ң' => 'ڭ', 'О' => 'و', 'Ө' => 'ٴو', 'П' => 'پ', 'Р' => 'ر', 'С' => 'س',
+ 'Т' => 'ت', 'У' => 'ۋ', 'Ұ' => 'ۇ', 'Ү' => 'ٴۇ', 'Ф' => 'ف', 'Х' => 'ح',
+ 'Һ' => 'ھ', 'Ц' => 'تس', 'Ч' => 'چ', 'Ш' => 'ش', 'Щ' => 'شش', 'Ъ' => 'ي',
+ 'Ы' => 'ى', 'Ь' => 'ي', 'І' => 'ٴى', 'Э' => 'ە', 'Ю' => 'يۋ', 'Я' => 'يا',
+ );
+
+ function loadDefaultTables() {
+ $this->mTables = array(
+ 'kk-kz' => new ReplacementArray( $this->mLatinToCyrillic ),
+ 'kk-tr' => new ReplacementArray( $this->mCyrillicToLatin ),
+ 'kk-cn' => new ReplacementArray( $this->mCyrillicToArabic ),
+ 'kk' => new ReplacementArray()
+ );
+ }
+
+
+ // Do not convert content on talk pages
+ function parserConvert( $text, &$parser ){
+ if(is_object($parser->mTitle) && $parser->mTitle->isTalkPage())
+ $this->mDoContentConvert=false;
+ else
+ $this->mDoContentConvert=true;
+
+ return parent::parserConvert($text, $parser );
+ }
+
+ /*
+ * A function wrapper, if there is no selected variant,
+ * leave the link names as they were
+ */
+ function findVariantLink( &$link, &$nt ) {
+ $oldlink=$link;
+ parent::findVariantLink($link,$nt);
+ if($this->getPreferredVariant()==$this->mMainLanguageCode)
+ $link=$oldlink;
+ }
+
+ /*
+ * We want our external link captions to be converted in variants,
+ * so we return the original text instead -{$text}-, except for URLs
+ */
+ function markNoConversion($text, $noParse=false) {
+ if($noParse || preg_match("/^https?:\/\/|ftp:\/\/|irc:\/\//",$text))
+ return parent::markNoConversion($text);
+ return $text;
+ }
+
+ /*
+ * An ugly function wrapper for parsing Image titles
+ * (to prevent image name conversion)
+ */
+ function autoConvert($text, $toVariant=false) {
+ global $wgTitle;
+ if($wgTitle->getNameSpace()==NS_IMAGE){
+ $imagename = $wgTitle->getNsText();
+ if(preg_match("/^$imagename:/",$text)) return $text;
+ }
+ return parent::autoConvert($text,$toVariant);
+ }
+
+ /**
+ * It translates text into variant, specials:
+ * - ommiting roman numbers
+ */
+ function translate($text, $toVariant){
+ $breaks = '[^\w\x80-\xff]';
+
+ // regexp for roman numbers
+ $roman = 'M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})';
+
+ $reg = '/^'.$roman.'$|^'.$roman.$breaks.'|'.$breaks.$roman.'$|'.$breaks.$roman.$breaks.'/';
+
+ $matches = preg_split($reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE);
+
+ $m = array_shift($matches);
+ $ret = $this->mTables[$toVariant]->replace( $m[0] );
+ $mstart = $m[1]+strlen($m[0]);
+ foreach($matches as $m) {
+ $ret .= substr($text, $mstart, $m[1]-$mstart);
+ $ret .= parent::translate($m[0], $toVariant);
+ $mstart = $m[1] + strlen($m[0]);
+ }
+
+ return $ret;
+ }
+
+}
+
+class LanguageKk extends LanguageKk_kz {
+
+ function __construct() {
+ global $wgHooks;
+ parent::__construct();
+
+ $variants = array( 'kk', 'kk-kz', 'kk-tr', 'kk-cn' );
+ $variantfallbacks = array(
+ 'kk' => 'kk-kz',
+ 'kk-kz' => 'kk-kz',
+ 'kk-tr' => 'kk-tr',
+ 'kk-cn' => 'kk-cn'
+ );
+
+ $this->mConverter = new KkConverter( $this, 'kk', $variants, $variantfallbacks );
+ $wgHooks['ArticleSaveComplete'][] = $this->mConverter;
+ }
+
+ function convertGrammar( $word, $case ) {
+ $fname="LanguageKk::convertGrammar";
+ wfProfileIn( $fname );
+
+ //always convert to kk-kz before convertGrammar
+ $w1 = $word;
+ $word = $this->mConverter->autoConvert( $word, 'kk-kz' );
+ $w2 = $word;
+ $word = parent::convertGrammar( $word, $case );
+ //restore encoding
+ if( $w1 != $w2 ) {
+ $word = $this->mConverter->translate( $word, 'kk-tr' );
+ }
+ wfProfileOut( $fname );
+ return $word;
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguageKk_kz.php b/languages/classes/LanguageKk_kz.php
new file mode 100644
index 000000000000..f01251c00dfe
--- /dev/null
+++ b/languages/classes/LanguageKk_kz.php
@@ -0,0 +1,269 @@
+<?php
+/** Kazakh (Қазақша)
+ *
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+
+class LanguageKk_kz extends Language {
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: genitive, dative, accusative, locative, ablative, comitative + possessive forms
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset( $wgGrammarForms['kk'][$case][$word] ) ) {
+ return $wgGrammarForms['kk'][$case][$word];
+ }
+ // Set up some constants...
+ // Vowels in last syllable
+ $frontVowels = array( "е", "ө", "ү", "і", "ә", "э" );
+ $backVowels = array( "а", "о", "ұ", "ы", "я", "ё" );
+ $allVowels = array( "е", "ө", "ү", "і", "ә", "э", "а", "о", "ұ", "ы", "я", "ё" );
+ // Preceding letters
+ $preVowels = $allVowels;
+ $preNasals = array( "м", "н", "ң" );
+ $preSonants = array( "и", "й", "л", "р", "у", "ю");
+ # $preVoiceds = array( "б", "в", "г", "ғ", "д", "ж", "з", "һ" );
+ # $preVoicelesses = array( "п", "ф", "к", "қ", "т", "ш", "с", "х", "ц", "ч", "щ" );
+ $preConsonants = array( "п", "ф", "к", "қ", "т", "ш", "с", "х", "ц", "ч", "щ", "б", "в", "г", "д" );
+ $preEzhZet = array( "ж", "з" );
+ $preSonorants = array( "и", "й", "л", "р", "у", "ю", "м", "н", "ң", "ж", "з");
+
+ // Possessives
+ $firsts = array( "м", "ң" ); // 1st singular, 2nd unformal
+ $seconds = array( "з" ); // 1st plural, 2nd formal
+ $thirds = array( "ы", "і" ); // 3rd
+
+ // Put the word in a form we can play with since we're using UTF-8
+ $ar = array();
+ $ar = preg_split('//u', $word, -1, PREG_SPLIT_NO_EMPTY);
+ $wordEnding = $ar[count( $ar ) - 1]; //Here's the last letter in the word
+ $wordReversed = array_reverse( $ar ); //Here's an array with the order of the letters in the word reversed so we can find a match quicker *shrug*
+
+ // Find the last vowel in the word
+ $wordLastVowel = NULL;
+ foreach ( $wordReversed as $xvalue ) {
+ foreach ( $allVowels as $yvalue ) {
+ if ( strcmp( $xvalue, $yvalue ) == 0 ) {
+ $wordLastVowel = $xvalue;
+ break;
+ } else {
+ continue;
+ }
+ }
+ if ( $wordLastVowel !== NULL ) {
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ // Now convert the word
+ switch ( $case ) {
+ case "dc1":
+ case "genitive": #ilik
+ if ( in_array( $wordEnding, $preConsonants ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "тің";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "тың";
+ }
+ } elseif ( in_array( $wordEnding, $preVowels ) || in_array( $wordEnding, $preNasals ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "нің";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "ның";
+ }
+ } elseif ( in_array( $wordEnding, $preSonants ) || in_array( $wordEnding, $preEzhZet )) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "дің";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "дың";
+ }
+ }
+ break;
+ case "dc2":
+ case "dative": #barıs
+ if ( in_array( $wordEnding, $preConsonants ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ке";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "қа";
+ }
+ } elseif ( in_array( $wordEnding, $preVowels ) || in_array( $wordEnding, $preSonorants ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ге";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "ға";
+ }
+ }
+ break;
+ case "dc21":
+ case "possessive dative": #täweldık + barıs
+ if ( in_array( $wordEnding, $firsts ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "е";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "а";
+ }
+ } elseif ( in_array( $wordEnding, $seconds ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ге";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "ға";
+ }
+ } elseif ( in_array( $wordEnding, $thirds ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "не";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "на";
+ }
+ }
+ break;
+ case "dc3":
+ case "accusative": #tabıs
+ if ( in_array( $wordEnding, $preConsonants ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ті";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "ты";
+ }
+ } elseif ( in_array( $wordEnding, $preVowels ) ) {
+ if ( in_array($wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ні";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "ны";
+ }
+ } elseif ( in_array( $wordEnding, $preSonorants) ) {
+ if ( in_array( $wordLastVowel, $frontVowels) ) {
+ $word = implode( "", $ar ) . "ді";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "ды";
+ }
+ }
+ break;
+ case "dc31":
+ case "possessive accusative": #täweldık + tabıs
+ if ( in_array( $wordEnding, $firsts ) || in_array( $wordEnding, $seconds ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ді";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "ды";
+ }
+ } elseif ( in_array( $wordEnding, $thirds ) ) {
+ $word = implode( "", $ar ) . "н";
+ }
+ break;
+ case "dc4":
+ case "locative": #jatıs
+ if ( in_array( $wordEnding, $preConsonants ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "те";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "та";
+ }
+ } elseif ( in_array( $wordEnding, $preVowels ) || in_array( $wordEnding, $preSonorants ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels) ) {
+ $word = implode( "", $ar ) . "де";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "",$ar ) . "да";
+ }
+ }
+ break;
+ case "dc41":
+ case "possessive locative": #täweldık + jatıs
+ if ( in_array( $wordEnding, $firsts ) || in_array( $wordEnding, $seconds ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "де";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "да";
+ }
+ } elseif ( in_array( $wordEnding, $thirds ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels) ) {
+ $word = implode( "", $ar ) . "нде";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "",$ar ) . "нда";
+ }
+ }
+ break;
+ case "dc5":
+ case "ablative": #şığıs
+ if ( in_array( $wordEnding, $preConsonants ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "тен";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "тан";
+ }
+ } elseif ( in_array($wordEnding, $preVowels ) || in_array($wordEnding, $preSonants ) || in_array($wordEnding, $preEzhZet ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ден";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "дан";
+ }
+ } elseif ( in_array($wordEnding, $preNasals ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "нен";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "нан";
+ }
+ }
+ break;
+ case "dc51":
+ case "possessive ablative": #täweldık + şığıs
+ if ( in_array( $wordEnding, $firsts ) || in_array( $wordEnding, $thirds ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "нен";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "нан";
+ }
+ } elseif ( in_array($wordEnding, $seconds ) ) {
+ if ( in_array( $wordLastVowel, $frontVowels ) ) {
+ $word = implode( "", $ar ) . "ден";
+ } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
+ $word = implode( "", $ar ) . "дан";
+ }
+ }
+ break;
+ case "dc6":
+ case "comitative": #kömektes
+ if ( in_array( $wordEnding, $preConsonants ) ) {
+ $word = implode( "", $ar ) . "пен";
+ } elseif ( in_array( $wordEnding, $preVowels ) || in_array( $wordEnding, $preNasals ) || in_array( $wordEnding, $preSonants ) ) {
+ $word = implode( "", $ar ) . "мен";
+ } elseif ( in_array( $wordEnding, $preEzhZet ) ) {
+ $word = implode( "", $ar ) . "бен";
+ }
+ break;
+ case "dc61":
+ case "possessive comitative": #täweldık + kömektes
+ if ( in_array( $wordEnding, $preConsonants ) ) {
+ $word = implode( "", $ar ) . "пенен";
+ } elseif ( in_array( $wordEnding, $preVowels ) || in_array( $wordEnding, $preNasals ) || in_array( $wordEnding, $preSonants ) ) {
+ $word = implode( "", $ar ) . "менен";
+ } elseif ( in_array( $wordEnding, $preEzhZet ) ) {
+ $word = implode( "", $ar ) . "бенен";
+ }
+ break;
+ default: #dc0 #nominative #ataw
+ }
+ return $word;
+ }
+
+ /**
+ * Avoid grouping whole numbers between 0 to 9999
+ */
+ function commafy( $_ ) {
+ if ( !preg_match( '/^\d{1,4}$/', $_ ) ) {
+ return strrev( (string)preg_replace( '/(\d{3})(?=\d)(?!\d*\.)/', '$1,', strrev($_) ) );
+ } else {
+ return $_;
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageKo.php b/languages/classes/LanguageKo.php
new file mode 100644
index 000000000000..55d28117636b
--- /dev/null
+++ b/languages/classes/LanguageKo.php
@@ -0,0 +1,57 @@
+<?php
+/** Korean (한국어)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageKo extends Language {
+ function firstChar( $s ) {
+ preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})/', $s, $matches);
+
+ if ( isset( $matches[1] ) ) {
+ if ( strlen( $matches[1] ) != 3 ) {
+ return $matches[1];
+ }
+ $code = (ord($matches[1]{0}) & 0x0f) << 12;
+ $code |= (ord($matches[1]{1}) & 0x3f) << 6;
+ $code |= (ord($matches[1]{2}) & 0x3f);
+ if ( $code < 0xac00 || 0xd7a4 <= $code) {
+ return $matches[1];
+ } elseif ( $code < 0xb098 ) {
+ return "\xe3\x84\xb1";
+ } elseif ( $code < 0xb2e4 ) {
+ return "\xe3\x84\xb4";
+ } elseif ( $code < 0xb77c ) {
+ return "\xe3\x84\xb7";
+ } elseif ( $code < 0xb9c8 ) {
+ return "\xe3\x84\xb9";
+ } elseif ( $code < 0xbc14 ) {
+ return "\xe3\x85\x81";
+ } elseif ( $code < 0xc0ac ) {
+ return "\xe3\x85\x82";
+ } elseif ( $code < 0xc544 ) {
+ return "\xe3\x85\x85";
+ } elseif ( $code < 0xc790 ) {
+ return "\xe3\x85\x87";
+ } elseif ( $code < 0xcc28 ) {
+ return "\xe3\x85\x88";
+ } elseif ( $code < 0xce74 ) {
+ return "\xe3\x85\x8a";
+ } elseif ( $code < 0xd0c0 ) {
+ return "\xe3\x85\x8b";
+ } elseif ( $code < 0xd30c ) {
+ return "\xe3\x85\x8c";
+ } elseif ( $code < 0xd558 ) {
+ return "\xe3\x85\x8d";
+ } else {
+ return "\xe3\x85\x8e";
+ }
+ } else {
+ return "";
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageKsh.php b/languages/classes/LanguageKsh.php
new file mode 100644
index 000000000000..5b8c10d91a96
--- /dev/null
+++ b/languages/classes/LanguageKsh.php
@@ -0,0 +1,36 @@
+<?php
+/** Ripuarian (Ripoarėsh)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Purodha Blissenbach
+ */
+
+class LanguageKsh extends Language {
+ /**
+ * Avoid grouping whole numbers between 0 to 9999
+ */
+ public function commafy( $_ ) {
+ if ( !preg_match( '/^\d{1,4}$/', $_ ) ) {
+ return strrev( (string)preg_replace( '/(\d{3})(?=\d)(?!\d*\.)/', '$1,', strrev( $_ ) ) );
+ } else {
+ return $_;
+ }
+ }
+
+ /**
+ * Handle cases of (1, other, 0) or (1, other)
+ */
+ public function convertPlural( $count, $w1, $w2, $w3, $w4, $w5 ) {
+ $count = str_replace (' ', '', $count);
+ if ( $count == '1' ) {
+ return $w1;
+ } elseif ( $count == '0' && $w3 ) {
+ return $w3;
+ } else {
+ return $w2;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageLa.php b/languages/classes/LanguageLa.php
new file mode 100644
index 000000000000..b9f6992516ea
--- /dev/null
+++ b/languages/classes/LanguageLa.php
@@ -0,0 +1,37 @@
+<?php
+/** Latin (lingua Latina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+class LanguageLa extends Language {
+ /**
+ * Convert from the nominative form of a noun to some other case
+ *
+ * Just used in a couple places for sitenames; special-case as necessary.
+ * Rules are far from complete.
+ *
+ * Cases: genitive
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['la'][$case][$word]) ) {
+ return $wgGrammarForms['la'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitive':
+ // 1st and 2nd declension singular only.
+ $in = array( '/a$/', '/u[ms]$/', '/tio$/' );
+ $out = array( 'ae', 'i', 'tionis' );
+ return preg_replace( $in, $out, $word );
+ default:
+ return $word;
+ }
+ }
+
+}
+
+
+?>
diff --git a/languages/classes/LanguageLt.php b/languages/classes/LanguageLt.php
new file mode 100644
index 000000000000..14031febc3a0
--- /dev/null
+++ b/languages/classes/LanguageLt.php
@@ -0,0 +1,22 @@
+<?php
+/** Lithuanian (Lietuvių)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguageLt extends Language {
+ /* Word forms (with examples):
+ 1 - vienas (1) lapas, dvidešimt vienas (21) lapas
+ 2 - trys (3) lapai
+ 3 - penkiolika (15) lapų
+ */
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ if ($count%10==1 && $count%100!=11) return $wordform1;
+ if ($count%10>=2 && ($count%100<10 || $count%100>=20)) return $wordform2;
+ //if third form not specified, then use second form
+ return empty($wordform3)?$wordform2:$wordform3;
+ }
+}
+?>
diff --git a/languages/classes/LanguageLv.php b/languages/classes/LanguageLv.php
new file mode 100644
index 000000000000..c45d96e4a6ad
--- /dev/null
+++ b/languages/classes/LanguageLv.php
@@ -0,0 +1,57 @@
+<?php
+/** Latvian (Latviešu)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Niklas Laxström
+ *
+ * @copyright Copyright © 2006, Niklas Laxström
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+class LanguageLv extends Language {
+ /**
+ * Plural form transformations. Using the first form for words with the last digit 1, but not for words with the last digits 11, and the second form for all the others.
+ *
+ * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
+ *
+ * @param integer $count
+ * @param string $wordform1
+ * @param string $wordform2
+ * @param string $wordform3 (not used)
+ * @return string
+ */
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5 ) {
+ return ( ( $count % 10 == 1 ) && ( $count % 100 != 11 ) ) ? $wordform1 : $wordform2;
+ }
+
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ # ģenitīvs - kā, datīvs - kam, akuzatīvs - ko, lokatīvs - kur.
+ /**
+ * Cases: ģenitīvs, datīvs, akuzatīvs, lokatīvs
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+
+ $wgGrammarForms['lv']['ģenitīvs' ]['Vikipēdija'] = 'Vikipēdijas';
+ $wgGrammarForms['lv']['ģenitīvs' ]['Vikivārdnīca'] = 'Vikivārdnīcas';
+ $wgGrammarForms['lv']['datīvs' ]['Vikipēdija'] = 'Vikipēdijai';
+ $wgGrammarForms['lv']['datīvs' ]['Vikivārdnīca'] = 'Vikivārdnīcai';
+ $wgGrammarForms['lv']['akuzatīvs']['Vikipēdija'] = 'Vikipēdiju';
+ $wgGrammarForms['lv']['akuzatīvs']['Vikivārdnīca'] = 'Vikivārdnīcu';
+ $wgGrammarForms['lv']['lokatīvs' ]['Vikipēdija'] = 'Vikipēdijā';
+ $wgGrammarForms['lv']['lokatīvs' ]['Vikivārdnīca'] = 'Vikivārdnīcā';
+
+ if ( isset($wgGrammarForms['lv'][$case][$word]) ) {
+ return $wgGrammarForms['lv'][$case][$word];
+ }
+
+ return $word;
+
+ }
+
+}
+
+?>
diff --git a/languages/classes/LanguagePt_br.php b/languages/classes/LanguagePt_br.php
new file mode 100644
index 000000000000..06dc4d9c85c4
--- /dev/null
+++ b/languages/classes/LanguagePt_br.php
@@ -0,0 +1,17 @@
+<?php
+/** Brazilian Portugese (Portuguêsi do Brasil)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+class LanguagePt_br extends Language {
+ /**
+ * Use singular form for zero (see bug 7309)
+ */
+ function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
+ return $count <= '1' ? $w1 : $w2;
+ }
+}
+?>
diff --git a/languages/classes/LanguageRmy.php b/languages/classes/LanguageRmy.php
new file mode 100644
index 000000000000..bbf22d52e4de
--- /dev/null
+++ b/languages/classes/LanguageRmy.php
@@ -0,0 +1,72 @@
+<?php
+
+class LanguageRmy extends Language {
+ /**
+ * Convert from the nominative form of a noun to some other case
+ * Invoked with {{GRAMMAR:case|word}}
+ *
+ * Cases: nominative, genitive-m-sg, genitive-f-sg, dative, locative, ablative, instrumental
+ */
+ public function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['rmy'][$case][$word]) ) {
+ return $wgGrammarForms['rmy'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitive-m-sg': # genitive (m.sg.)
+ if ( $word == 'Vikipidiya' ) {
+ $word = 'Vikipidiyako';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonaresko';
+ }
+ break;
+ case 'genitive-f-sg': # genitive (f.sg.)
+ if ( $word == 'Vikipidiya' ) {
+ $word = 'Vikipidiyaki';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareski';
+ }
+ break;
+ case 'genitive-pl': # genitive (pl.)
+ if ( $word == 'Vikipidiya' ) {
+ $word = 'Vikipidiyake';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareske';
+ }
+ break;
+ case 'dativ':
+ if ( $word == 'Vikipidiyake' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareske';
+ }
+ break;
+ case 'locative':
+ if ( $word == 'Vikipidiyate' ) {
+ $word = 'Wikipedijo';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonareste';
+ }
+ break;
+ case 'ablative':
+ if ( $word == 'Vikipidiyatar' ) {
+ $word = 'o Wikipediji';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonarestar';
+ }
+ break;
+ case 'instrumental':
+ if ( $word == 'Vikipidiyasa' ) {
+ $word = 'z Wikipedijo';
+ } elseif ( $word == 'Vikcyonaro' ) {
+ $word = 'Vikcyonaresa';
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'nominative' and all undefined case values
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageRu.php b/languages/classes/LanguageRu.php
new file mode 100644
index 000000000000..a251aa529a32
--- /dev/null
+++ b/languages/classes/LanguageRu.php
@@ -0,0 +1,87 @@
+<?php
+/** Russian (русский язык)
+ *
+ * You can contact Alexander Sigachov (alexander.sigachov at Googgle Mail)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/* Please, see Language.php for general function comments */
+class LanguageRu extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{grammar:case|word}}
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['ru'][$case][$word]) ) {
+ return $wgGrammarForms['ru'][$case][$word];
+ }
+
+ # These rules are not perfect, but they are currently only used for site names so it doesn't
+ # matter if they are wrong sometimes. Just add a special case for your site name if necessary.
+
+ #join and array_slice instead mb_substr
+ $ar = array();
+ preg_match_all( '/./us', $word, $ar );
+ if (!preg_match("/[a-zA-Z_]/us", $word))
+ switch ( $case ) {
+ case 'genitive': #родительный падеж
+ if ((join('',array_slice($ar[0],-4))=='вики') || (join('',array_slice($ar[0],-4))=='Вики'))
+ {}
+ elseif (join('',array_slice($ar[0],-1))=='ь')
+ $word = join('',array_slice($ar[0],0,-1)).'я';
+ elseif (join('',array_slice($ar[0],-2))=='ия')
+ $word=join('',array_slice($ar[0],0,-2)).'ии';
+ elseif (join('',array_slice($ar[0],-2))=='ка')
+ $word=join('',array_slice($ar[0],0,-2)).'ки';
+ elseif (join('',array_slice($ar[0],-2))=='ти')
+ $word=join('',array_slice($ar[0],0,-2)).'тей';
+ elseif (join('',array_slice($ar[0],-2))=='ды')
+ $word=join('',array_slice($ar[0],0,-2)).'дов';
+ elseif (join('',array_slice($ar[0],-3))=='ник')
+ $word=join('',array_slice($ar[0],0,-3)).'ника';
+ break;
+ case 'dative': #дательный падеж
+ #stub
+ break;
+ case 'accusative': #винительный падеж
+ #stub
+ break;
+ case 'instrumental': #творительный падеж
+ #stub
+ break;
+ case 'prepositional': #предложный падеж
+ #stub
+ break;
+ }
+ return $word;
+ }
+
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ $count = str_replace (' ', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+ /*
+ * Russian numeric format is "12 345,67" but "1234,56"
+ */
+
+ function commafy($_) {
+ if (!preg_match('/^\d{1,4}$/',$_)) {
+ return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
+ } else {
+ return $_;
+ }
+ }
+}
+?>
diff --git a/languages/classes/LanguageSk.php b/languages/classes/LanguageSk.php
new file mode 100644
index 000000000000..5b71c6aab137
--- /dev/null
+++ b/languages/classes/LanguageSk.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Slovak (Slovenčina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageSk extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: genitív, datív, akuzatív, lokál, inštrumentál
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['sk'][$case][$word]) ) {
+ return $wgGrammarForms['sk'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'genitív':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédie';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníku';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátov';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikikníh';
+ }
+ break;
+ case 'datív':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédii';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníku';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátom';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihám';
+ }
+ break;
+ case 'akuzatív':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédiu';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovník';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitáty';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihy';
+ }
+ break;
+ case 'lokál':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédii';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníku';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátoch';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihách';
+ }
+ break;
+ case 'inštrumentál':
+ if ( $word == 'Wikipédia' ) {
+ $word = 'Wikipédiou';
+ } elseif ( $word == 'Wikislovník' ) {
+ $word = 'Wikislovníkom';
+ } elseif ( $word == 'Wikicitáty' ) {
+ $word = 'Wikicitátmi';
+ } elseif ( $word == 'Wikiknihy' ) {
+ $word = 'Wikiknihami';
+ }
+ break;
+ }
+ return $word;
+ }
+
+ function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ $forms = array( $w1, $w2, $w3);
+ if ( $count == 1 ) {
+ $index = 0;
+ } elseif ( $count == 2 || $count == 3 || $count == 4 ) {
+ $index = 1;
+ } else {
+ $index = 2;
+ }
+ return $forms[$index];
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageSl.php b/languages/classes/LanguageSl.php
new file mode 100644
index 000000000000..35991caae8e6
--- /dev/null
+++ b/languages/classes/LanguageSl.php
@@ -0,0 +1,124 @@
+<?php
+/** Slovenian (Slovenščina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+class LanguageSl extends Language {
+ # Convert from the nominative form of a noun to some other case
+ # Invoked with {{GRAMMAR:case|word}}
+ /**
+ * Cases: rodilnik, dajalnik, tožilnik, mestnik, orodnik
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['sl'][$case][$word]) ) {
+ return $wgGrammarForms['sl'][$case][$word];
+ }
+
+ switch ( $case ) {
+ case 'rodilnik': # genitive
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipedije';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjig';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'Wikinovic';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'Wikinavedka';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'Wikivira';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'Wikislovarja';
+ }
+ break;
+ case 'dajalnik': # dativ
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjigam';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'Wikinovicam';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'Wikinavedku';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'Wikiviru';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'Wikislovarju';
+ }
+ break;
+ case 'tožilnik': # akuzatív
+ if ( $word == 'Wikipedija' ) {
+ $word = 'Wikipedijo';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'Wikiknjige';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'Wikinovice';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'Wikinavedek';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'Wikivir';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'Wikislovar';
+ }
+ break;
+ case 'mestnik': # locative
+ if ( $word == 'Wikipedija' ) {
+ $word = 'o Wikipediji';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'o Wikiknjigah';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'o Wikinovicah';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'o Wikinavedku';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'o Wikiviru';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'o Wikislovarju';
+ } else {
+ $word = 'o ' . $word;
+ }
+ break;
+ case 'orodnik': # instrumental
+ if ( $word == 'Wikipedija' ) {
+ $word = 'z Wikipedijo';
+ } elseif ( $word == 'Wikiknjige' ) {
+ $word = 'z Wikiknjigami';
+ } elseif ( $word == 'Wikinovice' ) {
+ $word = 'z Wikinovicami';
+ } elseif ( $word == 'Wikinavedek' ) {
+ $word = 'z Wikinavedkom';
+ } elseif ( $word == 'Wikivir' ) {
+ $word = 'z Wikivirom';
+ } elseif ( $word == 'Wikislovar' ) {
+ $word = 'z Wikislovarjem';
+ } else {
+ $word = 'z ' . $word;
+ }
+ break;
+ }
+
+ return $word; # this will return the original value for 'imenovalnik' (nominativ) and all undefined case values
+ }
+
+ function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ $forms = array( $w1, $w2, $w3, $w4, $w5 );
+ if ( $count % 100 == 1 ) {
+ $index = 0;
+ } elseif ( $count % 100 == 2 ) {
+ $index = 1;
+ } elseif ( $count % 100 == 3 || $count % 100 == 4 ) {
+ $index = 2;
+ } elseif ( $count != 0 ) {
+ $index = 3;
+ } else {
+ $index = 4;
+ }
+ return $forms[$index];
+ }
+
+
+}
+?>
diff --git a/languages/classes/LanguageSr.deps.php b/languages/classes/LanguageSr.deps.php
new file mode 100644
index 000000000000..8fe354e0a1e3
--- /dev/null
+++ b/languages/classes/LanguageSr.deps.php
@@ -0,0 +1,10 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// LanguageSr.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+require_once( dirname(__FILE__).'/LanguageSr_ec.php' );
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+?>
diff --git a/languages/classes/LanguageSr.php b/languages/classes/LanguageSr.php
new file mode 100644
index 000000000000..59d31cab528c
--- /dev/null
+++ b/languages/classes/LanguageSr.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/*
+ There are two levels of conversion for Serbian: the script level
+ (Cyrillics <-> Latin), and the variant level (ekavian
+ <->iyekavian). The two are orthogonal. So we really only need two
+ dictionaries: one for Cyrillics and Latin, and one for ekavian and
+ iyekavian.
+*/
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+require_once( dirname(__FILE__).'/LanguageSr_ec.php' );
+require_once( dirname(__FILE__).'/LanguageSr_el.php' );
+
+class SrConverter extends LanguageConverter {
+ var $mToLatin = array(
+ 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd',
+ 'ђ' => 'đ', 'е' => 'e', 'ж' => 'ž', 'з' => 'z', 'и' => 'i',
+ 'ј' => 'j', 'к' => 'k', 'л' => 'l', 'љ' => 'lj', 'м' => 'm',
+ 'н' => 'n', 'њ' => 'nj', 'о' => 'o', 'п' => 'p', 'р' => 'r',
+ 'с' => 's', 'т' => 't', 'ћ' => 'ć', 'у' => 'u', 'ф' => 'f',
+ 'х' => 'h', 'ц' => 'c', 'ч' => 'č', 'џ' => 'dž', 'ш' => 'š',
+
+ 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D',
+ 'Ђ' => 'Đ', 'Е' => 'E', 'Ж' => 'Ž', 'З' => 'Z', 'И' => 'I',
+ 'Ј' => 'J', 'К' => 'K', 'Л' => 'L', 'Љ' => 'Lj', 'М' => 'M',
+ 'Н' => 'N', 'Њ' => 'Nj', 'О' => 'O', 'П' => 'P', 'Р' => 'R',
+ 'С' => 'S', 'Т' => 'T', 'Ћ' => 'Ć', 'У' => 'U', 'Ф' => 'F',
+ 'Х' => 'H', 'Ц' => 'C', 'Ч' => 'Č', 'Џ' => 'Dž', 'Ш' => 'Š',
+ );
+
+ var $mToCyrillics = array(
+ 'a' => 'а', 'b' => 'б', 'c' => 'ц', 'č' => 'ч', 'ć' => 'ћ',
+ 'd' => 'д', 'dž' => 'џ', 'đ' => 'ђ', 'e' => 'е', 'f' => 'ф',
+ 'g' => 'г', 'h' => 'х', 'i' => 'и', 'j' => 'ј', 'k' => 'к',
+ 'l' => 'л', 'lj' => 'љ', 'm' => 'м', 'n' => 'н', 'nj' => 'њ',
+ 'o' => 'о', 'p' => 'п', 'r' => 'р', 's' => 'с', 'š' => 'ш',
+ 't' => 'т', 'u' => 'у', 'v' => 'в', 'z' => 'з', 'ž' => 'ж',
+
+ 'A' => 'А', 'B' => 'Б', 'C' => 'Ц', 'Č' => 'Ч', 'Ć' => 'Ћ',
+ 'D' => 'Д', 'Dž' => 'Џ', 'Đ' => 'Ђ', 'E' => 'Е', 'F' => 'Ф',
+ 'G' => 'Г', 'H' => 'Х', 'I' => 'И', 'J' => 'Ј', 'K' => 'К',
+ 'L' => 'Л', 'LJ' => 'Љ', 'M' => 'М', 'N' => 'Н', 'NJ' => 'Њ',
+ 'O' => 'О', 'P' => 'П', 'R' => 'Р', 'S' => 'С', 'Š' => 'Ш',
+ 'T' => 'Т', 'U' => 'У', 'V' => 'В', 'Z' => 'З', 'Ž' => 'Ж',
+
+ 'DŽ' => 'Џ', 'd!ž' => 'дж', 'D!ž'=> 'Дж', 'D!Ž'=> 'ДЖ',
+ 'Lj' => 'Љ', 'l!j' => 'лј', 'L!j'=> 'Лј', 'L!J'=> 'ЛЈ',
+ 'Nj' => 'Њ', 'n!j' => 'нј', 'N!j'=> 'Нј', 'N!J'=> 'НЈ'
+ );
+
+ function loadDefaultTables() {
+ $this->mTables = array(
+ 'sr-ec' => new ReplacementArray( $this->mToCyrillics ),
+ 'sr-jc' => new ReplacementArray( $this->mToCyrillics),
+ 'sr-el' => new ReplacementArray( $this->mToLatin),
+ 'sr-jl' => new ReplacementArray( $this->mToLatin),
+ 'sr' => new ReplacementArray()
+ );
+ }
+
+ /* rules should be defined as -{ekavian | iyekavian-} -or-
+ -{code:text | code:text | ...}-
+ update: delete all rule parsing because it's not used
+ currently, and just produces a couple of bugs
+ */
+ function parseManualRule($rule, $flags=array()) {
+ if(in_array('T',$flags)){
+ return parent::parseManualRule($rule, $flags);
+ }
+
+ // otherwise ignore all formatting
+ foreach($this->mVariants as $v) {
+ $carray[$v] = $rule;
+ }
+
+ return $carray;
+ }
+
+ // Do not convert content on talk pages
+ function parserConvert( $text, &$parser ){
+ if(is_object($parser->mTitle) && $parser->mTitle->isTalkPage())
+ $this->mDoContentConvert=false;
+ else
+ $this->mDoContentConvert=true;
+
+ return parent::parserConvert($text, $parser );
+ }
+
+ /*
+ * A function wrapper:
+ * - if there is no selected variant, leave the link
+ * names as they were
+ * - do not try to find variants for usernames
+ */
+ function findVariantLink( &$link, &$nt ) {
+ // check for user namespace
+ if(is_object($nt)){
+ $ns = $nt->getNamespace();
+ if($ns==NS_USER || $ns==NS_USER_TALK)
+ return;
+ }
+
+ $oldlink=$link;
+ parent::findVariantLink($link,$nt);
+ if($this->getPreferredVariant()==$this->mMainLanguageCode)
+ $link=$oldlink;
+ }
+
+ /*
+ * We want our external link captions to be converted in variants,
+ * so we return the original text instead -{$text}-, except for URLs
+ */
+ function markNoConversion($text, $noParse=false) {
+ if($noParse || preg_match("/^https?:\/\/|ftp:\/\/|irc:\/\//",$text))
+ return parent::markNoConversion($text);
+ return $text;
+ }
+
+ /*
+ * An ugly function wrapper for parsing Image titles
+ * (to prevent image name conversion)
+ */
+ function autoConvert($text, $toVariant=false) {
+ global $wgTitle;
+ if(is_object($wgTitle) && $wgTitle->getNameSpace()==NS_IMAGE){
+ $imagename = $wgTitle->getNsText();
+ if(preg_match("/^$imagename:/",$text)) return $text;
+ }
+ return parent::autoConvert($text,$toVariant);
+ }
+
+ /**
+ * It translates text into variant, specials:
+ * - ommiting roman numbers
+ */
+ function translate($text, $toVariant){
+ $breaks = '[^\w\x80-\xff]';
+
+ // regexp for roman numbers
+ $roman = 'M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})';
+
+ $reg = '/^'.$roman.'$|^'.$roman.$breaks.'|'.$breaks.$roman.'$|'.$breaks.$roman.$breaks.'/';
+
+ $matches = preg_split($reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE);
+
+ $m = array_shift($matches);
+ if( !isset( $this->mTables[$toVariant] ) ) {
+ throw new MWException( "Broken variant table: " . implode( ',', array_keys( $this->mTables ) ) );
+ }
+ $ret = $this->mTables[$toVariant]->replace( $m[0] );
+ $mstart = $m[1]+strlen($m[0]);
+ foreach($matches as $m) {
+ $ret .= substr($text, $mstart, $m[1]-$mstart);
+ $ret .= parent::translate($m[0], $toVariant);
+ $mstart = $m[1] + strlen($m[0]);
+ }
+
+ return $ret;
+ }
+
+}
+
+class LanguageSr extends LanguageSr_ec {
+ function __construct() {
+ global $wgHooks;
+
+ parent::__construct();
+
+ // these variants are currently UNUSED:
+ // 'sr-jc', 'sr-jl'
+ $variants = array('sr', 'sr-ec', 'sr-el');
+ $variantfallbacks = array(
+ 'sr' => 'sr-ec',
+ 'sr-ec' => 'sr',
+ 'sr-el' => 'sr',
+ );
+
+
+ $marker = array();//don't mess with these, leave them as they are
+ $flags = array(
+ 'S' => 'S', 'писмо' => 'S', 'pismo' => 'S',
+ 'W' => 'W', 'реч' => 'W', 'reč' => 'W', 'ријеч' => 'W', 'riječ' => 'W'
+ );
+ $this->mConverter = new SrConverter($this, 'sr', $variants, $variantfallbacks, $marker, $flags);
+ $wgHooks['ArticleSaveComplete'][] = $this->mConverter;
+ }
+}
+?>
diff --git a/languages/classes/LanguageSr_ec.php b/languages/classes/LanguageSr_ec.php
new file mode 100644
index 000000000000..72f56b8cc842
--- /dev/null
+++ b/languages/classes/LanguageSr_ec.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageSr_ec extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageSr_el.deps.php b/languages/classes/LanguageSr_el.deps.php
new file mode 100644
index 000000000000..f39da2f2b905
--- /dev/null
+++ b/languages/classes/LanguageSr_el.deps.php
@@ -0,0 +1,9 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// LanguageSr_el.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+require_once( dirname(__FILE__).'/LanguageSr_ec.php' );
+?>
diff --git a/languages/classes/LanguageSr_el.php b/languages/classes/LanguageSr_el.php
new file mode 100644
index 000000000000..1ecacc0e7efb
--- /dev/null
+++ b/languages/classes/LanguageSr_el.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageSr_el extends Language {
+ function convertPlural( $count, $wordform1, $wordform2, $wordform3, $w4, $w5) {
+ $count = str_replace ('.', '', $count);
+ if ($count > 10 && floor(($count % 100) / 10) == 1) {
+ return $wordform3;
+ } else {
+ switch ($count % 10) {
+ case 1: return $wordform1;
+ case 2:
+ case 3:
+ case 4: return $wordform2;
+ default: return $wordform3;
+ }
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageTr.php b/languages/classes/LanguageTr.php
new file mode 100644
index 000000000000..67d68f60cc7b
--- /dev/null
+++ b/languages/classes/LanguageTr.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Turkish (Türkçe)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageTr extends Language {
+ function ucfirst ( $string ) {
+ if ( $string[0] == 'i' ) {
+ return 'İ' . substr( $string, 1 );
+ } else {
+ return parent::ucfirst( $string );
+ }
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageTyv.php b/languages/classes/LanguageTyv.php
new file mode 100644
index 000000000000..aacfaff537f9
--- /dev/null
+++ b/languages/classes/LanguageTyv.php
@@ -0,0 +1,233 @@
+<?php
+/** Tyvan localization (Тыва дыл)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# From friends at tyvawiki.org
+
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
+class LanguageTyv extends Language {
+ /**
+ * Grammatical transformations, needed for inflected languages
+ * Invoked by putting {{grammar:case|word}} in a message
+ *
+ * @param string $word
+ * @param string $case
+ * @return string
+ */
+ function convertGrammar( $word, $case ) {
+ global $wgGrammarForms;
+ if ( isset($wgGrammarForms['tyv'][$case][$word]) ) {
+ return $wgGrammarForms['tyv'][$case][$word];
+ }
+
+
+ // Set up some constants...
+ $allVowels = array("е", "и", "э", "ө", "ү", "а", "ё", "о", "у", "ы", "ю", "я", "a", "e", "i", "o", "ö", "u", "ü", "y");
+ $frontVowels = array("е", "и", "э", "ө", "ү", "e", "i", "ö", "ü");
+ $backVowels = array("а", "ё", "о", "у", "ы", "ю", "я", "a", "o", "u", "y");
+ $unroundFrontVowels = array("е", "и", "э", "e", "i");
+ $roundFrontVowels = array("ө", "ү", "ö", "ü");
+ $unroundBackVowels = array("а", "ы", "я", "a", "y");
+ $roundBackVowels = array("ё", "о", "у", "ю", "o", "u");
+ $voicedPhonemes = array("д", "б", "з", "ж", "г", "d", "b", "z", "g");
+ $unvoicedPhonemes = array("т", "п", "с", "ш", "к", "ч", "х", "t", "p", "s", "k", "x");
+ $directiveUnvoicedStems = array("т", "п", "с", "ш", "к", "ч", "х", "л", "м", "н", "ң", "t", "p", "s", "k", "x", "l", "m", "n", "ŋ");
+ $directiveVoicedStems = array("д", "б", "з", "ж", "г", "р", "й", "d", "b", "z", "g", "r", "j");
+
+// $allSonants = array("л", "м", "н", "ң", "р", "й");
+// $allNasals = array("м", "н", "ң");
+
+ // Put the word in a form we can play with since we're using UTF-8
+ preg_match_all( '/./us', $word, $ar );
+
+ $wordEnding = $ar[0][count($ar[0]) - 1]; //Here's the last letter in the word
+ $wordReversed = array_reverse($ar[0]); //Here's an array with the order of the letters in the word reversed so we can find a match quicker *shrug*
+
+ // Find the last vowel in the word
+ $wordLastVowel = NULL;
+ foreach ( $wordReversed as $xvalue ) {
+ foreach ( $allVowels as $yvalue ) {
+ if ( strcmp($xvalue, $yvalue) == 0 ) {
+ $wordLastVowel = $xvalue;
+ break;
+ } else {
+ continue;
+ }
+ }
+ if ( $wordLastVowel !== NULL ) {
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ // Now convert the word
+ switch ( $case ) {
+ case "genitive":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "түң";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "тиң";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "туң";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "тың";
+ } else {
+ }
+ } elseif ( $wordEnding === "л" || $wordEnding === "l") {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "дүң";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "диң";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дуң";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дың";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "нүң";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ниң";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "нуң";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ның";
+ } else {
+ }
+ }
+ break;
+ case "dative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "ке";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "ка";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "ге";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "га";
+ } else {
+ }
+ }
+ break;
+ case "accusative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "тү";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ти";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ту";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ты";
+ } else {
+ }
+ } elseif ( $wordEnding === "л" || $wordEnding === "l") {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "дү";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ди";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ду";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ды";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "нү";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "ни";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ну";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "ны";
+ } else {
+ }
+ }
+ break;
+ case "locative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "те";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "та";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "де";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "да";
+ } else {
+ }
+ }
+ break;
+ case "ablative":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "тен";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "тан";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $frontVowels) ) {
+ $word = implode("",$ar[0]) . "ден";
+ } elseif ( in_array($wordLastVowel, $backVowels) ) {
+ $word = implode("",$ar[0]) . "дан";
+ } else {
+ }
+ }
+ break;
+ case "directive1":
+ if ( in_array($wordEnding, $directiveVoicedStems) ) {
+ $word = implode("",$ar[0]) . "же";
+ } elseif ( in_array($wordEnding, $directiveUnvoicedStems) ) {
+ $word = implode("",$ar[0]) . "че";
+ } else {
+ }
+ break;
+ case "directive2":
+ if ( in_array($wordEnding, $unvoicedPhonemes) ) {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "түве";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "тиве";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "туве";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "тыве";
+ } else {
+ }
+ } else {
+ if ( in_array($wordLastVowel, $roundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "дүве";
+ } elseif ( in_array($wordLastVowel, $unroundFrontVowels) ) {
+ $word = implode("",$ar[0]) . "диве";
+ } elseif ( in_array($wordLastVowel, $roundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дуве";
+ } elseif ( in_array($wordLastVowel, $unroundBackVowels) ) {
+ $word = implode("",$ar[0]) . "дыве";
+ } else {
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return $word;
+ }
+}
+?>
diff --git a/languages/classes/LanguageVi.php b/languages/classes/LanguageVi.php
new file mode 100644
index 000000000000..4f9c4da3608d
--- /dev/null
+++ b/languages/classes/LanguageVi.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Based on Language.php 1.645
+ * @package MediaWiki
+ * @subpackage Language
+ * Compatible to MediaWiki 1.5
+ * Initial translation by Trần Thế Trung and Nguyễn Thanh Quang
+ * Last update 28 August 2005 (UTC)
+ */
+
+class LanguageVi extends Language {
+ function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
+ if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
+
+ $datePreference = $this->dateFormat( $format );
+
+ $month = $this->formatMonth( substr( $ts, 4, 2 ), $datePreference );
+ $day = $this->formatDay( substr( $ts, 6, 2 ), $datePreference );
+ $year = $this->formatNum( substr( $ts, 0, 4 ), true );
+
+ switch( $datePreference ) {
+ case 3:
+ case 4: return "$day/$month/$year";
+ case MW_DATE_ISO: return substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
+ default: return "$day $month năm $year";
+ }
+ }
+
+ function timeSeparator( $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '4': return 'h';
+ default: return ':';
+ }
+ }
+
+ function timeDateSeparator( $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '0':
+ case '1':
+ case '2': return ', ';
+ default: return ' ';
+ }
+ }
+
+ function formatMonth( $month, $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '0':
+ case '1': return 'tháng ' . ( 0 + $month );
+ case '2': return 'tháng ' . $this->getSpecialMonthName( $month );
+ default: return 0 + $month;
+ }
+ }
+
+ function formatDay( $day, $format ) {
+ $datePreference = $this->dateFormat($format);
+ switch ( $datePreference ) {
+ case '0':
+ case '1':
+ case '2': return 'ngày ' . (0 + $day);
+ default: return 0 + $day;
+ }
+ }
+
+ function getSpecialMonthName( $key ) {
+ $names = 'Một, Hai, Ba, Tư, Năm, Sáu, Bảy, Tám, Chín, Mười, Mười một, Mười hai';
+ $names = explode(', ', $names);
+ return $names[$key-1];
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageWa.php b/languages/classes/LanguageWa.php
new file mode 100644
index 000000000000..541c6de8f3ac
--- /dev/null
+++ b/languages/classes/LanguageWa.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Walloon (Walon)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# NOTE: cweri après "NOTE:" po des racsegnes so des ratournaedjes
+# k' i gn a.
+
+class LanguageWa extends Language {
+ ###
+ ### Dates in Walloon are "1î d' <monthname>" for 1st of the month,
+ ### "<day> di <monthname>" for months starting by a consoun, and
+ ### "<day> d' <monthname>" for months starting with a vowel
+ ###
+ function date( $ts, $adj = false, $format = true, $tc = false ) {
+ global $wgUser;
+
+ if ( $adj ) { $ts = $this->userAdjust( $ts, $tc ); }
+ $datePreference = $this->dateFormat( $format );
+
+ # ISO (YYYY-mm-dd) format
+ #
+ # we also output this format for YMD (eg: 2001 January 15)
+ if ( $datePreference == 'ISO 8601' ) {
+ $d = substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
+ return $d;
+ }
+
+ # dd/mm/YYYY format
+ if ( $datePreference == 'walloon short' ) {
+ $d = substr($ts, 6, 2). '/' . substr($ts, 4, 2). '/' .substr($ts, 0, 4);
+ return $d;
+ }
+
+ # Walloon format
+ #
+ # we output this in all other cases
+ $m = substr( $ts, 4, 2 );
+ $n = substr( $ts, 6, 2 );
+ if ($n == 1) {
+ $d = "1î d' " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ } else if ($n == 2 || $n == 3 || $n == 20 || $n == 22 || $n == 23) {
+ $d = (0 + $n) . " d' " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ } else if ($m == 4 || $m == 8 || $m == 10) {
+ $d = (0 + $n) . " d' " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ } else {
+ $d = (0 + $n) . " di " . $this->getMonthName( $m ) .
+ " " . substr( $ts, 0, 4 );
+ }
+ return $d;
+ }
+
+ function timeanddate( $ts, $adj = false, $format = true, $tc = false ) {
+ if ( $adj ) { $ts = $this->userAdjust( $ts, $tc ); }
+ $datePreference = $this->dateFormat( $format );
+ if ( $datePreference == 'ISO 8601' ) {
+ return parent::timeanddate( $ts, $adj, $format, $tc );
+ } else {
+ return $this->date( $ts, $adj, $format, $tc ) . ' a ' .
+ $this->time( $ts, $adj, $format, $tc );
+ }
+ }
+}
+
+?>
diff --git a/languages/classes/LanguageZh.deps.php b/languages/classes/LanguageZh.deps.php
new file mode 100644
index 000000000000..1d736340f1ba
--- /dev/null
+++ b/languages/classes/LanguageZh.deps.php
@@ -0,0 +1,10 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// LanguageZh.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+require_once( dirname(__FILE__).'/LanguageZh_cn.php' );
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+?>
diff --git a/languages/classes/LanguageZh.php b/languages/classes/LanguageZh.php
new file mode 100644
index 000000000000..d4fbaf303f0f
--- /dev/null
+++ b/languages/classes/LanguageZh.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+require_once( dirname(__FILE__).'/../LanguageConverter.php' );
+require_once( dirname(__FILE__).'/LanguageZh_cn.php' );
+
+class ZhConverter extends LanguageConverter {
+ function loadDefaultTables() {
+ require( "includes/ZhConversion.php" );
+ $this->mTables = array(
+ 'zh-cn' => new ReplacementArray( $zh2CN ),
+ 'zh-tw' => new ReplacementArray( $zh2TW ),
+ 'zh-sg' => new ReplacementArray( array_merge($zh2CN, $zh2SG) ),
+ 'zh-hk' => new ReplacementArray( array_merge($zh2TW, $zh2HK) ),
+ 'zh' => new ReplacementArray
+ );
+ }
+
+ function postLoadTables() {
+ $this->mTables['zh-sg']->merge( $this->mTables['zh-cn'] );
+ $this->mTables['zh-hk']->merge( $this->mTables['zh-tw'] );
+ }
+
+ /* there shouldn't be any latin text in Chinese conversion, so no need
+ to mark anything.
+ $noParse is there for compatibility with LanguageConvert::markNoConversion
+ */
+ function markNoConversion($text, $noParse = false) {
+ return $text;
+ }
+
+ function convertCategoryKey( $key ) {
+ return $this->autoConvert( $key, 'zh-cn' );
+ }
+}
+
+
+/* class that handles both Traditional and Simplified Chinese
+ right now it only distinguish zh_cn, zh_tw, zh_sg and zh_hk.
+*/
+class LanguageZh extends LanguageZh_cn {
+
+ function __construct() {
+ global $wgHooks;
+ parent::__construct();
+ $this->mConverter = new ZhConverter($this, 'zh',
+ array('zh', 'zh-cn', 'zh-tw', 'zh-sg', 'zh-hk'),
+ array('zh'=>'zh-cn',
+ 'zh-cn'=>'zh-sg',
+ 'zh-sg'=>'zh-cn',
+ 'zh-tw'=>'zh-hk',
+ 'zh-hk'=>'zh-tw'));
+ $wgHooks['ArticleSaveComplete'][] = $this->mConverter;
+ }
+
+
+ # this should give much better diff info
+ function segmentForDiff( $text ) {
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' ' .\"$1\"", $text);
+ }
+
+ function unsegmentForDiff( $text ) {
+ return preg_replace(
+ "/ ([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "\"$1\"", $text);
+ }
+
+ // word segmentation
+ function stripForSearch( $string ) {
+ $fname="LanguageZh::stripForSearch";
+ wfProfileIn( $fname );
+
+ // eventually this should be a word segmentation
+ // for now just treat each character as a word
+ $t = preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' ' .\"$1\"", $string);
+
+ //always convert to zh-cn before indexing. it should be
+ //better to use zh-cn for search, since conversion from
+ //Traditional to Simplified is less ambiguous than the
+ //other way around
+
+ $t = $this->mConverter->autoConvert($t, 'zh-cn');
+ $t = parent::stripForSearch( $t );
+ wfProfileOut( $fname );
+ return $t;
+
+ }
+
+ function convertForSearchResult( $termsArray ) {
+ $terms = implode( '|', $termsArray );
+ $terms = implode( '|', $this->mConverter->autoConvertToAllVariants( $terms ) );
+ $ret = array_unique( explode('|', $terms) );
+ return $ret;
+ }
+
+}
+?>
diff --git a/languages/classes/LanguageZh_cn.php b/languages/classes/LanguageZh_cn.php
new file mode 100644
index 000000000000..af94cb99ad71
--- /dev/null
+++ b/languages/classes/LanguageZh_cn.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageZh_cn extends Language {
+ function stripForSearch( $string ) {
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+ # we also separate characters as "words"
+ if( function_exists( 'mb_strtolower' ) ) {
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( \"$1\" )",
+ mb_strtolower( $string ) );
+ } else {
+ list( , $wikiLowerChars ) = Language::getCaseMaps();
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
+ $string );
+ }
+ }
+}
+
+
+?>
diff --git a/languages/classes/LanguageZh_yue.php b/languages/classes/LanguageZh_yue.php
new file mode 100644
index 000000000000..0e45508c6e54
--- /dev/null
+++ b/languages/classes/LanguageZh_yue.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+class LanguageZh_yue extends Language {
+ function stripForSearch( $string ) {
+ # MySQL fulltext index doesn't grok utf-8, so we
+ # need to fold cases and convert to hex
+ # we also separate characters as "words"
+ if( function_exists( 'mb_strtolower' ) ) {
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( \"$1\" )",
+ mb_strtolower( $string ) );
+ } else {
+ list( , $wikiLowerChars ) = Language::getCaseMaps();
+ return preg_replace(
+ "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
+ "' U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
+ $string );
+ }
+ }
+}
+
+
+?>
diff --git a/languages/messages/MessagesAb.php b/languages/messages/MessagesAb.php
new file mode 100644
index 000000000000..7be9a3161799
--- /dev/null
+++ b/languages/messages/MessagesAb.php
@@ -0,0 +1,5 @@
+<?php
+
+$fallback = 'ru';
+
+?>
diff --git a/languages/messages/MessagesAf.php b/languages/messages/MessagesAf.php
new file mode 100644
index 000000000000..80efa4b7c846
--- /dev/null
+++ b/languages/messages/MessagesAf.php
@@ -0,0 +1,694 @@
+<?php
+
+$quickbarSettings = array(
+ 'Geen.', 'Links vas.', 'Regs vas.', 'Dryf links.'
+);
+
+$skinNames = array(
+ 'standard' => 'Standaard',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Keulen blou',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Spesiaal',
+ NS_MAIN => '',
+ NS_TALK => 'Bespreking',
+ NS_USER => 'Gebruiker',
+ NS_USER_TALK => 'Gebruikerbespreking',
+ # NS_PROJECT set by $wgMetaNamespace,
+ NS_PROJECT_TALK => '$1bespreking',
+ NS_IMAGE => 'Beeld',
+ NS_IMAGE_TALK => 'Beeldbespreking',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWikibespreking',
+ NS_TEMPLATE => 'Sjabloon',
+ NS_TEMPLATE_TALK => 'Sjabloonbespreking',
+ NS_HELP => 'Hulp',
+ NS_HELP_TALK => 'Hulpbespreking',
+ NS_CATEGORY => 'Kategorie',
+ NS_CATEGORY_TALK => 'Kategoriebespreking'
+);
+
+# South Africa uses space for thousands and comma for decimal
+# Reference: AWS Reël 7.4 p. 52, 2002 edition
+# glibc is wrong in this respect in some versions
+$separatorTransformTable = array( ',' => "\xc2\xa0", '.' => ',' );
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+$messages = array(
+# User Toggles
+
+"tog-underline" => "Onderstreep skakels.",
+"tog-highlightbroken" => "Wys gebroke skakels <a href=\"\" class=\"new\">so</a> of so<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Justeer paragrawe.",
+"tog-hideminor" => "Moenie klein wysigings in die nuwe wysigingslys wys nie.",
+"tog-usenewrc" => "Verbeterde nuwe wysigingslys (vir moderne blaaiers).",
+"tog-numberheadings" => "Automatiese nommer opskrifte.",
+"tog-showtoolbar" => "Show edit toolbar",
+"tog-rememberpassword" => "Onthou wagwoord oor sessies.",
+"tog-editwidth" => "Wysigingsboks met volle wydte.",
+"tog-editondblclick" => "Wysig blaaie met dubbelkliek (JavaScript).",
+"tog-watchdefault" => "Lys nuwe en gewysigde bladsye.",
+"tog-minordefault" => "Merk alle wysigings automaties as klein by verstek.",
+"tog-previewontop" => "Wys voorskou bo wysigingsboks.",
+
+# Dates
+'sunday' => 'Sondag',
+'monday' => 'Maandag',
+'tuesday' => 'Dinsdag',
+'wednesday' => 'Woensdag',
+'thursday' => 'Donderdag',
+'friday' => 'Vrydag',
+'saturday' => 'Saterdag',
+'january' => 'Januarie',
+'february' => 'Februarie',
+'march' => 'Maart',
+'april' => 'April',
+'may_long' => 'Mei',
+'june' => 'Junie',
+'july' => 'Julie',
+'august' => 'Augustus',
+'september' => 'September',
+'october' => 'Oktober',
+'november' => 'November',
+'december' => 'Desember',
+'jan' => '01',
+'feb' => '02',
+'mar' => '03',
+'apr' => '04',
+'may' => '05',
+'jun' => '06',
+'jul' => '07',
+'aug' => '08',
+'sep' => '09',
+'oct' => '10',
+'nov' => '11',
+'dec' => '12',
+
+
+# Bits of text used by many pages:
+#
+"mainpage" => "Tuisblad",
+"about" => "Omtrent",
+"aboutsite" => "Inligting oor {{SITENAME}}",
+"aboutpage" => "{{ns:4}}:Omtrent",
+"help" => "Help",
+"helppage" => "{{ns:4}}:Hulp",
+"bugreports" => "Foutrapporte",
+"bugreportspage" => "{{ns:4}}:FoutRapporte",
+"faq" => "Gewilde vrae",
+"faqpage" => "{{ns:4}}:GewildeVrae",
+"edithelp" => "Wysighulp",
+"edithelppage" => "{{ns:4}}:Hoe_word_'n_bladsy_gewysig",
+"cancel" => "Kanselleer",
+"qbfind" => "Vind",
+"qbbrowse" => "Snuffel",
+"qbedit" => "Wysig",
+"qbpageoptions" => "Bladsy opsies",
+"qbpageinfo" => "Bladsy inligting",
+"qbmyoptions" => "My opsies",
+"mypage" => "My bladsy",
+"mytalk" => "My besprekings",
+"currentevents" => "Huidige gebeure",
+"errorpagetitle" => "Fout",
+"returnto" => "Keer terug na $1.",
+"whatlinkshere" => "Bladsye wat hierheen skakel",
+"help" => "Hulp",
+"search" => "Soek",
+"searchbutton" => "Soek",
+"go" => "Wys",
+'searcharticle' => "Wys",
+"history" => "Ouer weergawes",
+"printableversion" => "Drukbare weergawe",
+"editthispage" => "Wysig hierdie bladsy",
+"deletethispage" => "Skrap bladsy",
+"protectthispage" => "Beskerm hierdie bladsy",
+"unprotectthispage" => "Laat toe dat bladsy gewysig word",
+"newpage" => "Nuwe bladsy",
+"talkpage" => "Bespreek hierdie bladsy",
+"articlepage" => "Lees artikel",
+"userpage" => "Lees gebruikersbladsy",
+"projectpage" => "Lees metabladsy",
+"imagepage" => "Lees bladsy oor prent",
+"viewtalkpage" => "Lees bespreking",
+"otherlanguages" => "Ander tale",
+"redirectedfrom" => "(Van $1 aangestuur.)",
+"lastmodifiedat" => "Laaste wysiging op $2, $1.",
+"viewcount" => "Hierdie bladsy is al $1 keer aangevra.",
+"protectedpage" => "Beskermde bladsy",
+
+"nbytes" => "$1 grepe",
+"ok" => "Aanvaar", #fixMe
+"retrievedfrom" => "Ontsluit van \"$1\"",
+"newmessageslink" => "nuwe boodskappe",
+
+# Main script and global functions
+#
+"nosuchaction" => "Ongeldige aksie",
+"nosuchactiontext" => "Onbekende aksie deur die adres gespesifeer",
+"nosuchspecialpage" => "Ongeldige spesiale bladsy",
+"nospecialpagetext" => "Ongeldige spesiale bladsy gespesifeer.",
+
+# General errors
+#
+"error" => "Fout",
+"databaseerror" => "Databasisfout",
+"dberrortext" => "Sintaksisfout in databasisnavraag.
+Die laaste navraag was:
+<blockquote><tt>$1</tt></blockquote>
+van funksie \"<tt>$2</tt>\".
+MySQL foutboodskap \"<tt>$3: $4</tt>\".",
+"noconnect" => "Kon nie met databasis op $1 konnekteer nie",
+"nodb" => "Kon nie databasis $1 selekteer nie",
+"readonly" => "Databasis gesluit",
+"enterlockreason" => "Rede vir die sluiting,
+en beraming van wanneer ontsluiting sal plaas vind",
+"readonlytext" => "Die {{SITENAME}} databasis is tans gesluit vir nuwe
+artikelwysigings, waarskynlik vir roetine databasisonderhoud,
+waarna dit terug sal wees na normaal.
+Die administreerder wat dit gesluit het se verduideliking:
+<p>$1",
+"missingarticle" => "Die databasis het nie die teks van die veronderstelde bladsy \"$1\" gekry nie.
+Nie databasisfout nie, moontlik sagtewarefout.
+Raporteer die adres asseblief aan enige administrateur.",
+"internalerror" => "Interne fout",
+"filecopyerror" => "Kon nie lêer van \"$1\" na \"$2\" kopieer nie.",
+"filerenameerror" => "Kon nie lêernaam van \"$1\" na \"$2\" wysig nie.",
+"filedeleteerror" => "Kon nie lêer \"$1\" skrap nie.",
+"filenotfound" => "Kon nie lêer \"$1\" vind nie.",
+"unexpected" => "Onverwagte waarde: \"$1\"=\"$2\".",
+"formerror" => "Fout: kon vorm nie stuur nie",
+"badarticleerror" => "Die aksie kon nie op hierdie bladsy uitgevoer word nie.",
+"cannotdelete" => "Kon nie die bladsy of prent skrap nie, iemand anders het dit miskien reeds geskrap.",
+"badtitle" => "Ongeldige titel",
+"badtitletext" => "Die bladsytitel waarvoor gevra is, is ongeldig, leeg, of
+'n verkeerd geskakelde tussen-taal of tussen-wiki titel.",
+"perfdisabled" => "Hierdie funksie is afgeskakel tydens spitstoegangsure vir verrigtingsredes, probeer weer tussen 02:00z en 14:00z (Universeel Gekoördineerde Tyd - UGT).",
+
+# Login and logout pages
+#
+"logouttitle" => "Teken uit",
+"logouttext" => "Jy is nou uitgeteken, en kan aanhou om
+{{SITENAME}} anoniem te gebruik; of jy kan inteken as dieselfde of 'n ander gebruiker.",
+
+"welcomecreation" => "<h2>Welkom, $1.</h2><p>Jou rekening is geskep;
+moenie vergeet om jou persoonlike voorkeure te stel nie.",
+
+"loginpagetitle" => "Teken in",
+"yourname" => "Jou gebruikersnaam",
+"yourpassword" => "Jou wagwoord",
+"yourpasswordagain" => "Tik weer jou wagwoord in",
+"remembermypassword" => "Onthou my wagwoord oor sessies.",
+"loginproblem" => "<b>Daar was probleme met jou intekening.</b><br />Probeer weer.",
+"alreadyloggedin" => "<strong>Gebruiker $1, jy is reeds ingeteken.</strong><br />",
+
+"login" => "Teken in",
+"userlogin" => "Teken in",
+"logout" => "Teken uit",
+"userlogout" => "Teken uit",
+"createaccount" => "Kies nuwe wagwoord",
+"badretype" => "Die wagwoorde wat jy ingetik het, is nie dieselfde nie.",
+"userexists" => "Die gebruikersnaam wat jy gebruik het, is alreeds gebruik. Kies asseblief 'n ander gebruikersnaam.",
+"youremail" => "Jou e-pos",
+"yournick" => "Jou bynaam (vir stempel)",
+"loginerror" => "Intekenfout",
+"noname" => "Ongeldige gebruikersnaam.",
+"loginsuccesstitle" => "Suksesvolle intekening",
+"loginsuccess" => "Jy is ingeteken by {{SITENAME}} as \"$1\".",
+"nosuchuser" => "Daar is geen \"$1\" gebruikersnaam nie.
+Maak seker dit is reg gespel, of gebruik die vorm hier onder om 'n nuwe rekening te skep.",
+"wrongpassword" => "Ongeldige wagwoord, probeer weer.",
+"mailmypassword" => "Stuur my wagwword na my e-pos adres.",
+"passwordremindertitle" => "Wagwoordwenk van {{SITENAME}}",
+"passwordremindertext" => "Iemand (waarskynlik jy, van IP-adres $1)
+het gevra dat ons vir jou 'n nuwe {{SITENAME}} wagwoord stuur.
+Die wagwoord vir gebruiker \"$2\" is nou \"$3\".
+Teken asseblief in en verander jou wagwoord.",
+"noemail" => "Daar is geen e-pos adres vir gebruiker \"$1\" nie.",
+"passwordsent" => "Nuwe wagwoord gestuur na e-posadres vir \"$1\".
+Teken asseblief in na jy dit ontvang het.",
+
+# Edit pages
+#
+"summary" => "Opsomming",
+"minoredit" => "Klein wysiging",
+"watchthis" => "Hou bladsy dop",
+"savearticle" => "Stoor bladsy",
+"preview" => "Voorskou",
+"showpreview" => "Wys voorskou",
+"blockedtitle" => "Gebruiker is geblokkeer",
+"blockedtext" => "Jou gebruikersnaam of IP-adres is deur $1 geblokkeer:
+<br />''$2''<p>Jy mag $1 of een van die ander [[{{ns:4}}:administreerders|administreerders]] kontak
+om dit te bespreek.",
+"newarticle" => "(Nuut)",
+"newarticletext" =>
+"Die bladsy waarna geskakel is, bestaan nie.
+Om 'n nuwe bladsy te skep, tik in die invoerboks hier onder. Lees die [[{{ns:4}}:Help|hulp bladsy]]
+vir meer inligting.
+Indien jy per ongeluk hier is, gebruik jou blaaier se '''terug''' knop.",
+"anontalkpagetext" => "---- ''Dit is die besprekingsbladsy vir 'n anonieme gebruiker wat nie 'n rekening geskep het nie. Ons moet dus hul [[IP-adres]] gebruik om hulle te identifiseer. So 'n IP-adres kan deur verskeie gebruikers gedeel word. Indien jy 'n anonieme gebruiker is wat voel dat oneerbiedige komentaar aan jou gerig is, [[Special:Userlogin|skep 'n rekening of teken in]] om verwarring te voorkom met ander anonieme gebruikers.''",
+"noarticletext" => "(Daar is tans geen inligting vir hierdie artikel nie.)",
+"updated" => "(Gewysig)",
+"note" => "<strong>Nota:</strong>",
+"previewnote" => "Onthou dat dit slegs 'n voorskou is en nog nie gestoor is nie!",
+"previewconflict" => "Hierdie voorskou reflekteer die teks in die boonste invoerboks soos dit sal lyk as jy dit stoor.",
+"editing" => "Besig om $1 te wysig",
+'editinguser' => "Besig om $1 te wysig",
+"editconflict" => "Wysigingskonflik: $1",
+"explainconflict" => "Iemand anders het hierdie bladsy gewysig sedert jy dit begin verander het.
+Die boonste invoerboks het die teks wat tans bestaan.
+Jou wysigings word in die onderste invoerboks gewys.
+Jy sal jou wysigings moet saamsmelt met die huidige teks.
+<strong>Slegs</strong> die teks in die boonste invoerboks sal gestoor word wanneer jy \"Stoor bladsy\" druk.<br />",
+"yourtext" => "Jou teks",
+"storedversion" => "Gestoorde weergawe",
+"editingold" => "<strong>Waarskuwing: jy is besig om 'n ou weergawe van hierdie bladsy te wysig.
+As jy dit stoor, sal enige wysigings sedert hierdie wysiging verloor word.</strong>",
+"yourdiff" => "Wysigings",
+/*"copyrightwarning" => "Alle bydraes aan {{SITENAME}} word beskou as beskikbaar gestel onder
+die ''GNU Free Documentation License'' (lees $1 vir meer inligting).
+As jy nie wil hê dat jou werk ongemagtig gewysig of versprei mag word nie, moet jy dit nie hier indien nie.<br />
+Jy belowe ons ook dat jy dit self geskryf het, of verkry het van 'n bron wat toelaat dat dit hier mag wees.<br />
+<strong>Moenie werk beskerm deur kopiereg sonder toestemming indien nie!</strong>",*/
+"longpagewarning" => "Waarskuwing: hierdie bladsy is $1 kilogrepe lank; sekere blaaiers
+kan probleme hê met die wysiging va blaaie langer as 32 kilogrepe. Breek asseblief die bladsy op in kleiner dele.",
+
+# History pages
+#
+"revhistory" => "Wysigingsgeskiedenis",
+"nohistory" => "Daar is geen wysigingsgeskiedenis vir hierdie bladsy nie.",
+"revnotfound" => "Wysiging nie gevind nie.",
+"revnotfoundtext" => "Die ou wysiging waarvoor jy gevra het, kon nie gevind word nie. Maak asseblief seker dat die adres wat jy gebruik
+het om toegang te kry tot hierdie bladsy, reg is.",
+"loadhist" => "Besig om bladsy wysigingsgeskiedenis te laai.",
+"currentrev" => "Huidige wysiging",
+"revisionasof" => "Wysiging soos op $1",
+"cur" => "huidige",
+"next" => "volgende",
+"last" => "vorige",
+"orig" => "oorspronklike",
+"histlegend" => "Byskrif: (huidige) = verskil van huidige weergawe,
+(vorige) = verskil van vorige weergawe, M = klein wysiging",
+
+# Diffs
+#
+"difference" => "(Verksil tussen weergawes)",
+"loadingrev" => "Besig om weergawe van verskil te laai.",
+"lineno" => "Lyn $1:",
+"editcurrent" => "Wysig die huidige weergawe van hierdie bladsy.",
+
+# Search results
+#
+"searchresults" => "soekresultate",
+"searchresulttext" => "Vir meer inligting oor {{SITENAME}} soekresultate, lees [[Project:Soek|Soek in {{SITENAME}}]].",
+"searchsubtitle" => "Vir navraag \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Vir navraag \"$1\"",
+"badquery" => "Verkeerd gestelde navraag",
+"badquerytext" => "Ons kon nie jou naavraag prosesseer nie.
+Dit is miskien omdat jy gesoek het vir iets wat minder as drie letters bevat. Jy het miskien die navraag verkeerd ingetik.",
+"matchtotals" => "Die navraag \"$1\" pas $2 artikeltitels
+en teks in $3 artikels.",
+"noexactmatch" => "Geen bladsy met hierdie presiese titel bestaan nie, probeer 'n volteksnavraag.",
+"titlematches" => "Artikeltitel resultate",
+"notitlematches" => "Geen artikeltitel resultate nie",
+"textmatches" => "Artikelteks resultate",
+"notextmatches" => "Geen artikelteks resultate nie",
+"prevn" => "vorige $1",
+"nextn" => "volgende $1",
+"viewprevnext" => "Kyk na ($1) ($2) ($3).",
+"showingresults" => "Onder <b>$1</b> resultate, beginende met #<b>$2</b>.",
+"nonefound" => "<strong>Nota</strong>: onsuksesvolle navrae word gewoonlik veroorsaak deur 'n soektog met algemene
+woorde wat nie geindekseer word nie, of spesifisering van meer as een woord (slegs blaaie wat alle navraagwoorde
+bevat, word gewys).",
+"powersearch" => "Soek",
+"powersearchtext" => "
+Search in namespaces :<br />
+$1<br />
+$2 List redirects Search for $3 $9", #fixMe
+
+
+# Preferences page
+#
+"preferences" => "Voorkeure",
+"prefsnologin" => "Nie ingeteken nie",
+"prefsnologintext" => "Jy moet [[Special:Userlogin|ingeteken wees]]
+om voorkeure te spesifiseer.",
+"prefsreset" => "Voorkeure is herstel.",
+"qbsettings" => "Snelbalkvoorkeure", #fixMe Quickbar settings
+"changepassword" => "Verander wagwoord",
+"skin" => "Omslag",
+"math" => "Verbeeld wiskunde",
+"math_failure" => "Kon nie verbeeld nie",
+"math_unknown_error" => "onbekende fout",
+"math_unknown_function" => "onbekende funksie",
+"math_lexing_error" => "leksikale fout",
+"math_syntax_error" => "sintaksfout",
+"saveprefs" => "Stoor voorkeure",
+"resetprefs" => "Herstel voorkeure",
+"oldpassword" => "Ou wagwoord",
+"newpassword" => "Nuwe wagwoord",
+"retypenew" => "Tik nuwe wagwoord weer in",
+"textboxsize" => "Grootte van invoerboks",
+"rows" => "Rye",
+"columns" => "Kolomme",
+"searchresultshead" => "Soekresultaat voorkeure",
+"resultsperpage" => "Aantal resultate om te wys",
+"contextlines" => "Aantal lyne per resultaat",
+"contextchars" => "Karakters konteks per lyn",
+"stubthreshold" => "Drempel vir verkorte artikels",
+"recentchangescount" => "Aantal titels in onlangse wysigings",
+"savedprefs" => "Jou voorkeure is gestoor.",
+"timezonetext" => "Aantal ure wat plaaslike tyd verskil van UGT.",
+"localtime" => "Plaaslike tyd",
+"timezoneoffset" => "Teenrekening",
+
+# Recent changes
+#
+"changes" => "wysigings",
+"recentchanges" => "Onlangse wysigings",
+"rcnote" => "Hier onder is die laaste <strong>$1</strong> wysigings gedurende die laaste <strong>$2</strong> dae.",
+"rcnotefrom" => "Hier onder is die wysigings sedert <b>$2</b> (tot by <b>$1</b> word gewys).",
+"rclistfrom" => "Wys nuwe wysigings en begin by $1",
+"rclinks" => "Wys die laaste $1 wysigings in die laaste $2 dae.",
+"diff" => "verskil",
+"hist" => "geskiedenis",
+"hide" => "vat weg",
+"show" => "wys",
+"minoreditletter" => "K",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => "Laai lêer",
+"uploadbtn" => "Laai lêer",
+"reupload" => "Herlaai",
+"reuploaddesc" => "Keer terug na die laaivorm.",
+"uploadnologin" => "Nie ingeteken nie",
+"uploadnologintext" => "Teken eers in [[Special:Userlogin|logged in]]
+om lêers te laai.",
+"uploaderror" => "Laaifout",
+"uploadtext" => "'''STOP!''' Voor jy hier laai, lees en volg {{SITENAME}} se
+[[Project:Image_use_policy|beleid oor prentgebruik]].
+
+Om prente wat voorheen gelaai is te sien of te soek, gaan na die
+[[Special:Imagelist|lys van gelaaide prente]].
+Laai van lêers en skrappings word aangeteken in die
+[[Project:Upload_log|laailog]].
+
+Gebruik die vorm hier onder om nuwe prente te laai wat jy ter illustrasie in jou artikels wil gebruik.
+In die meeste webblaaiers sal jy 'n \"Browse...\" knop sien, wat jou bedryfstelsel se standaard lêeroopmaak dialoogblokkie sal oopmaak.
+Deur 'n lêer in hierdie dialoogkassie te kies, vul jy die teksboks naas die knop met die naam van die lêer.
+Jy moet ook die blokkie merk om te bevestig dat jy geen kopieregte skend deur die lêer op te laai nie.
+Kliek die \"Laai\" knop om die laai af te handel.
+Dit mag dalk 'n rukkie neem as jy 'n stadige internetverbinding het.
+
+Die voorkeurformate is JPEG vir fotografiese prente, PNG vir tekeninge en ander ikoniese prente, en OGG vir klanklêers.
+Gebruik asseblief beskrywende lêername om verwarring te voorkom.
+Om die prent in 'n artikel te gebruik, gebruik 'n skakel met die formaat '''<nowiki>[[image:file.jpg]]</nowiki>''' of
+'''<nowiki>[[image:file.png|alt text]]</nowiki>''' of
+'''<nowiki>[[media:file.ogg]]</nowiki>''' vir klanklêers.
+
+Let asseblief op dat, soos met {{SITENAME}} bladsye, mag ander jou gelaaide lêers redigeer as hulle dink dit dien die ensiklopedie, en jy kan verhoed word om lêers te laai as jy die stelsel misbruik.",
+"uploadlog" => "laailog",
+"uploadlogpage" => "laai_log",
+"uploadlogpagetext" => "Hier onder is 'n lys van die mees onlangse lêers wat gelaai is.
+Alle tye is bedienertyd (UGT).
+<ul>
+</ul>",
+"filename" => "Lêernaam",
+"filedesc" => "Opsomming",
+"copyrightpage" => "{{ns:4}}:kopiereg",
+"copyrightpagename" => "{{SITENAME}} kopiereg",
+"uploadedfiles" => "Gelaaide lêers",
+"minlength" => "Prentname moet ten minste drie letters lank wees.",
+"badfilename" => "Prentnaam is verander na \"$1\".",
+"badfiletype" => "\".$1\" is nie 'n aanbevole lêerformaat vir prente nie.",
+"successfulupload" => "Laai suksesvol",
+"fileuploaded" => "Lêer \"$1\" suksesvol gelaai.
+Volg asseblief hierdie skakel: ($2) na die beskrywingsbladsy en vul inligting in oor die die lêer, soos waar dit vandaan kom, wie het dit geskep en wanneer, en enige iets anders wat jy daarvan af weet.",
+"uploadwarning" => "Laaiwaarskuwing",
+"savefile" => "Stoor lêer",
+"uploadedimage" => "Het \"[[$1]]\" gelaai",
+
+# Image list
+#
+"imagelist" => "Prentelys",
+"imagelisttext" => "Hier onder is a lys van $1 prente gesorteer $2.",
+"getimagelist" => "Besig om prentelys te haal",
+"ilsubmit" => "Soek",
+"showlast" => "Wys laaste $1 prente gesorteer $2.",
+"byname" => "volgens naam",
+"bydate" => "volgens datum",
+"bysize" => "volgens grootte",
+"imgdelete" => "skrap",
+"imgdesc" => "beskrywing",
+"imglegend" => "Legende: (beskrywing) = wys/verander prent se beskrywing.",
+"imghistory" => "Prentgeskiedenis",
+"revertimg" => "gaan terug",
+"deleteimg" => "skrap",
+"deleteimgcompletely" => "skrap",
+"imghistlegend" => "Legende: (huidig) = dit is die huidige prent, (skrap) = skrap hierdie ou weergawe, (gaan terug) = gaan terug na hierdie ou weergawe.
+<br /><i>Kliek die datum om die prent te sien wat op daardie datum gelaai is</i>.",
+"imagelinks" => "Prentskakels",
+"linkstoimage" => "Die volgende bladsye gebruik hierdie prent:",
+"nolinkstoimage" => "Daar is geen bladsye wat hierdie prent gebruik nie.",
+
+# Statistics
+#
+"statistics" => "Statistiek",
+"sitestats" => "Werfstatistiek",
+"userstats" => "Gebruikerstatistiek",
+"sitestatstext" => "Daar is 'n totaal van <b>$1</b> bladsye in die databasis.
+Dit sluit \"bespreek\" bladsye in, bladsye oor {{SITENAME}}, minimale \"verkorte\"
+bladsye, wegwysbladsye, en ander wat waarskynlik nie as artikels kwalifiseer nie.
+Uitsluitend bogenoemde, is daar <b>$2</b> bladsye wat waarskynlik ware artikels is.<p>
+Bladsye is al <b>$3</b> kere aangevra, en <b>$4</b> keer verander sedert die sagteware opgegradeer is (July 20, 2002).
+Dit werk uit op gemiddeld <b>$5</b> veranderings per bladsy, en bladsye word <b>$6</b> keer per verandering aangevra.",
+"userstatstext" => "Daar is <b>$1</b> geregistreerde gebruikers.
+<b>$2</b> van hulle is administrateurs (sien $3).",
+
+# Maintenance Page
+#
+"disambiguations" => "Bladsye wat onduidelikhede opklaar",
+"disambiguationspage" => "{{ns:4}}:Links_to_disambiguating_pages",
+"disambiguationstext" => "Die volgende artikels skakel na 'n <i>bladsy wat onduidelikhede opklaar</i>. Hulle behoort eerder na die relevante onderwerp te skakel.<br />'n Bladsy word gesien as een wat onduidelikhede opklaar as $1 daarna toe skakel.<br />Skakels van ander naamkontekste is <i>nie</i> hier gelys nie.",
+"doubleredirects" => "Dubbele aansture",
+"doubleredirectstext" => "<b>Let op:</b> Hierdie lys bevat moontlik false positiewe. Dit beteken gewoonlik dat daar nog teks met skakels onder die eerste #REDIRECT is.<br />\nElke ry bevat skakels na die eerste en die tweede aanstuur, asook die eerste reël van van die tweede aanstuurteks, wat gewoonlik die \"regte\" teikenbladsy gee waarna die eerste aanstuur behoort te wys.",
+"brokenredirects" => "Stukkende aansture",
+"brokenredirectstext" => "Die volgende aansture skakel na 'n bladsy wat nie bestaan nie.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Weesbladsye",
+"unusedimages" => "Ongebruikte prente",
+"popularpages" => "Populêre bladsye",
+"nviews" => "$1 keer aangevra",
+"wantedpages" => "Gesogte bladsye",
+"nlinks" => "$1 skakels",
+"allpages" => "Alle bladsye",
+"randompage" => "Lukrake bladsy",
+"shortpages" => "Kort bladsye",
+"longpages" => "Lang bladsye",
+"listusers" => "Gebruikerslys",
+"specialpages" => "Spesiale bladsye",
+"spheading" => "Spesiale bladsye",
+"recentchangeslinked" => "Verwante veranderings",
+"rclsub" => "(na bladsye waarna \"$1\" skakel)",
+"newpages" => "Nuwe bladsye",
+"movethispage" => "Skuif hierdie bladsy",
+"unusedimagestext" => "<p>Let asseblief op dat ander webwerwe, soos die internasionale {{SITENAME}}s, dalk met 'n direkte URL na 'n prent skakel, so die prent sal dus hier verskyn al word dit aktief gebruik.", // TODO: grammar
+"booksources" => "Boekbronne",
+"booksourcetext" => "Hier onder is 'n lys van skakels na ander werwe wat nuwe en tweede handse boeke verkoop, en wat dalk ook verdere inligting het oor boeke waarna jy soek.
+{{SITENAME}} is nie geaffilieer aan enige van hierdie besighede nie en die lys moet nie as 'n aanbeveling gesien word nie.",
+
+# Email this user
+#
+"mailnologin" => "Geen verstuuradres",
+"mailnologintext" => "Jy moet [[Special:Userlogin|ingeteken]]
+wees en 'n geldige e-posadres in jou [[Special:Preferences|voorkeure]]
+hê om e-pos aan ander gebruikers te stuur.",
+"emailuser" => "Stuur e-pos na hierdie gebruiker",
+"emailpage" => "Stuur e-pos na gebruiker",
+"emailpagetext" => "As die gerbuiker 'n geldoge e-posadres in haar of sy gebruikersvoorkeure het, sal die vorm hier onder 'n enkele boodskap stuur.
+Die e-posadres wat jy in jou gebruikersvoorkeure het sal verkyn as die \"Van\" adres van die pos, so die ontvanger sal kan terug antwoord.",
+"noemailtitle" => "Geen e-posadres",
+"noemailtext" => "Hierdie gebruiker het nie 'n geldige e-posadres gespesifiseer nie of het gekies om nie e-pos van ander gebruikers te ontvang nie.",
+"emailfrom" => "Van",
+"emailto" => "Aan",
+"emailsubject" => "Onderwerp",
+"emailmessage" => "Boodskap",
+"emailsend" => "Stuur",
+"emailsent" => "E-pos gestuur",
+"emailsenttext" => "Jou e-pos is gestuur.",
+
+# Watchlist
+#
+"watchlist" => "My dophoulys",
+"nowatchlist" => "Jy het geen items in jou dophoulys nie.",
+"watchnologin" => "Nie ingeteken nie",
+"watchnologintext" => "Jy moet [[Special:Userlogin|ingeteken]]
+wees om jou dophoulys te verander.",
+"addedwatch" => "Bygevoeg tot dophoulys",
+"addedwatchtext" => "Die bladsy \"$1\" is by jou <a href=\"" .
+ "{{localurle:Special:Watchlist}}\">dophoulys</a> gevoeg.
+Toekomstige veranderinge aan hierdie bladsye en sy geassosieerde Bespreekbladsy sal hier verskyn en die bladsy sal in <b>vetdruk</b> verskyn in die <a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">lys van onlangse wysigings</a> om dit makliker te maak om dit raak te sien.</p>
+
+<p>As jy die bladsy later van jou dophoulys wil verwyder, kliek \"Moenie meer dophou\" in die kantbalk.",
+"removedwatch" => "Afgehaal van dophoulys",
+"removedwatchtext" => "Die bladsy \"$1\" is van jou dophoulys afgehaal.",
+"watchthispage" => "Hou hierdie bladsy dop",
+"unwatchthispage" => "Moenie meer dophou",
+"notanarticle" => "Nie 'n artikel",
+
+# Delete/protect/revert
+#
+"deletepage" => "Skrap bladsy",
+"confirm" => "Bevestig",
+"confirmdelete" => "Bevestig skrapping",
+"deletesub" => "(Besig om \"$1\" te skrap)",
+"confirmdeletetext" => "Jy staan op die punt om 'n bladsy of prent asook al hulle geskiedenis uit die databasis te skrap.
+Bevestig asseblief dat jy dit wil doen, dat jy die gevolge verstaan en dat jy dit doen in ooreenstemming met die [[{{ns:4}}:Policy]].",
+"actioncomplete" => "Aksie uitgevoer",
+"deletedtext" => "\"$1\" is geskrap.
+Kyk na $2 vir 'n rekord van onlangse skrappings.",
+"deletedarticle" => "\"$1\" geskrap",
+"dellogpage" => "Skrap_log",
+"dellogpagetext" => "Hier onder is 'n lys van die mees onlangse skrappings. Alle tye is bedienertyd (UGT).
+<ul>
+</ul>",
+"deletionlog" => "skrappingslog",
+"reverted" => "Het terug gegaan na vroeëre weergawe",
+"deletecomment" => "Rede vir skrapping",
+"imagereverted" => "Terugkeer na vorige weergawe was suksesvol.",
+"rollback" => "Rol veranderinge terug",
+"rollbacklink" => "Rol terug",
+"cantrollback" => "Kan nie na verandering terug keer nie; die laaste bydraer is die enigste outer van hierdie bladsy.",
+"revertpage" => "Het teruggegaan na laaste verandering wat $1 gemaak het",
+
+# Undelete
+"undelete" => "Herstel geskrapte bladsy",
+"undeletepage" => "Bekyk en herstel geskrapte bladsye",
+"undeletepagetext" => "Die volgende bladsye is geskrap, maar hulle is nog in die argief en kan herstel word. Die argief kan periodiek skoongemaak word.",
+"undeletearticle" => "Herstel geskrapte bladsy",
+"undeleterevisions" => "$1 weergawes in argief",
+"undeletehistory" => "As jy die bladsy herstel, sal alle weergawes herstel word.
+As 'n nuwe bladsy met dieselfde naam sedert die skrapping geskep is, sal die herstelde weergawes in die nuwe bladsy se voorgeskiedenis verskyn en die huidige weergawe van die lewendige bladsy sal nie outomaties vervang word nie.",
+"undeleterevision" => "Geskrape weergawes vanaf $1",
+"undeletebtn" => "Herstel!",
+"undeletedarticle" => "het \"$1\" herstel",
+
+# Contributions
+#
+"contributions" => "Gebruikersbydraes",
+"mycontris" => "My bydraes",
+"contribsub" => "Vir $1",
+
+"nocontribs" => "Geen veranderinge wat by hierdie kriteria pas, is gevind nie.",
+"ucnote" => "Hier onder is die gebruiker se laaste <b>$1</b> veranderings in die laaste <b>$2</b> dae.",
+"uclinks" => "Bekyk die laaste $1 veranderings; bekyk die laaste $2 dae.",
+"uctop" => " (boontoe)" ,
+
+# What links here
+#
+"whatlinkshere" => "Wat skakel hierheen",
+"notargettitle" => "Geen teiken",
+"notargettext" => "Jy het nie 'n teikenbladsy of gebruiker waarmee hierdie funksie moet werk, gespesifiseer nie.",
+"linklistsub" => "(Lys van skakels)",
+"linkshere" => "Die volgende bladsye skakel hierheen:",
+"nolinkshere" => "Geen bladsye skakel hierheen nie.",
+"isredirect" => "Stuur bladsy aan",
+
+# Block/unblock IP
+#
+"blockip" => "Blok IP-adres",
+"blockiptext" => "Gebruik die vorm hier onder om skryftoegang van 'n sekere IP-adres te blok.
+Dit moet net gedoen word om vandalisme te voorkom en in ooreenstemming met [[{{ns:4}}:Policy|{{SITENAME}} policy]].
+Vul 'n spesifieke rede hier onder in (haal byvoorbeeld spesifieke bladsye wat gevandaliseer is, aan).",
+"ipaddress" => "IP-Adres",
+"ipbreason" => "Rede",
+"ipbsubmit" => "Blok hierdie adres",
+"badipaddress" => "Die IP-adres is nie in die regte formaat nie.",
+"blockipsuccesssub" => "Blokkering het geslaag",
+"blockipsuccesstext" => "Die IP-adres \"$1\" is geblok.
+<br />Kyk na [[Special:Ipblocklist|IP block list]] vir 'n oorsig van blokkerings.",
+"unblockip" => "Maak IP-adres oop",
+"unblockiptext" => "Gebruik die vorm hier onder om skryftoegang te herstel vir 'n voorheen geblokkeerde IP-adres.",
+"ipusubmit" => "Maak hierdie adres oop",
+"ipblocklist" => "Lys van geblokkeerde IP-adresse",
+'blocklistline' => '$1, $2 het $3 geblok ($4)',
+"blocklink" => "blok",
+"unblocklink" => "maak oop",
+"contribslink" => "bydraes",
+
+# Developer tools
+#
+"lockdb" => "Sluit databasis",
+"unlockdb" => "Ontsluit databasis",
+"lockdbtext" => "As jy die databasis sluit, kan geen gebruiker meer bladsye redigeer nie, voorkeure verander nie, dophoulyste verander nie, of ander aksies uitvoer wat veranderinge in die databasis verg nie.
+Bevestig asseblief dat dit is wat jy wil doen en dat jy die databasis sal ontsluit sodra jy jou instandhouding afgehandel het.",
+"unlockdbtext" => "As jy die databasis ontsluit, kan gebruikers weer bladsye redigeer, voorkeure verander, dophoulyste verander, of ander aksies uitvoer wat veranderinge in die databasis verg.
+Bevestig asseblief dat dit is wat jy wil doen.",
+"lockconfirm" => "Ja, ek wil regtig die databasis sluit.",
+"unlockconfirm" => "Ja, ek wil regtig die databasis ontsluit.",
+"lockbtn" => "Sluit die databasis",
+"unlockbtn" => "Ontsluit die databasis",
+"locknoconfirm" => "Jy het nie die bevestigblokkie gemerk nie.",
+"lockdbsuccesssub" => "Databasissluit het geslaag",
+"unlockdbsuccesssub" => "Databasisslot is verwyder",
+"lockdbsuccesstext" => "Die {{SITENAME}} databasis is gesluit.
+<br />Onthou om dit te ontsluit wanneer jou onderhoud afgehandel is.",
+"unlockdbsuccesstext" => "Die {{SITENAME}} databasis is ontsluit.",
+
+# Move page
+#
+"movepage" => "Skuif bladsy",
+"movepagetext" => "Met die vorm hier onder kan jy 'n bladsy hernoem en so al sy geskiedenis na die nuwe naam skuif.
+Die ou titel sal 'n aanstuurbladsy na die nuwe titel word.
+Skakels na die ou bladsytitel sal nie verander nie; maak seker dat jy
+check vir dubbele of gebrekte aansture.
+Dis jou verantwoordelikheid om seker te maak dat skakels steeds wys waarheen hulle moet.
+
+Let op dat 'n bladsy '''nie''' geskuif sal word as daar reeds 'n bladsy met so 'n titel bestaan nie, tensy dit leeg is off 'n aanstuurbladsy is, en dit het geen veranderingsgeskiedenis nie. Dit beteken dat jy 'n bladsy kan hernoem na sy ou titel as jy 'n fout gemaak het, en jy kan nie oor 'n bestaande bladsy skryf nie.
+
+<b>WAARSKUWING!</b>
+Hierdie kan 'n drasitiese en onverwagte verandering vir 'n populêre bladsy wees;
+maak asseblief seker dat jy die gevolge verstaan voordat jy voortgaan.",
+"movepagetalktext" => "Die geassosieerde praatbladsy, indien enige, sal outomaties saam met dit geskuif word, '''behalwe as:'''
+*Jy die bladsy oor naamkontekste heen skuif,
+*'n Bespreekbladsy wat nie leeg is nie reeds onder die nuwe naam bestaan, of
+*Jy die merk uit blokkie hier onder wegneem.
+
+In hierdie gevalle, sal jy die bladsy met die hand moet skuif of saamsmelt as jy wil.",
+"movearticle" => "Skuif bladsy",
+"movenologin" => "Nie ingeteken nie",
+"movenologintext" => "Jy moet 'n geregistreerde gebruiker wees en [[Special:Userlogin|ingeteken]]
+wees om 'n bladsy te skuif.",
+"newtitle" => "Na nuwe titel",
+"movepagebtn" => "Skuif bladsy",
+"pagemovedsub" => "Verskuiwing het geslaag",
+"pagemovedtext" => "Bladsy \"[[$1]]\" geskuif na \"[[$2]]\".",
+"articleexists" => "'n Bladsy met daardie naam bestaan reeds, of die naam wat jy gekies het, is nie geldig nie.
+Kies asseblief 'n ander naam.",
+"talkexists" => "Die bladsy self is suksesvol verskuif, maar die bespreekbladsy kon nie geskuif word nie omdat een reeds bestaan met die nuwe titel. Smelt hulle asseblief met die hand saam.",
+"movedto" => "geskuif na",
+"movetalk" => "Skuif \"bespreek\"bladsy ook, indien van toepassing.",
+"talkpagemoved" => "Die ooreenkomstige bespreekbladsy is ook geskuif.",
+"talkpagenotmoved" => "Die ooreenkomstige bespreekbladsy is <strong>nie</strong> geskuif nie.",
+
+#Math
+'mw_math_png' => "Gebruik altyd PNG.",
+'mw_math_simple' => "Gebruik HTML indien dit eenvoudig is, andersins PNG.",
+'mw_math_html' => "Gebruik HTML wanneer moontlik, andersins PNG.",
+'mw_math_source' => "Los as TeX (vir teks blaaiers).",
+'mw_math_modern' => "Moderne blaaiers.",
+'mw_math_mathml' => 'MathML',
+
+);
+
+
+
+?>
diff --git a/languages/messages/MessagesAn.php b/languages/messages/MessagesAn.php
new file mode 100644
index 000000000000..a10cd23206c1
--- /dev/null
+++ b/languages/messages/MessagesAn.php
@@ -0,0 +1,24 @@
+<?php
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Espezial',
+ NS_MAIN => '',
+ NS_TALK => 'Descusión',
+ NS_USER => 'Usuario',
+ NS_USER_TALK => 'Descusión_usuario',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Descusión_$1',
+ NS_IMAGE => 'Imachen',
+ NS_IMAGE_TALK => 'Descusión_imachen',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Descusión_MediaWiki',
+ NS_TEMPLATE => 'Plantilla',
+ NS_TEMPLATE_TALK => 'Descusión_plantilla',
+ NS_HELP => 'Aduya',
+ NS_HELP_TALK => 'Descusión_aduya',
+ NS_CATEGORY => 'Categoría',
+ NS_CATEGORY_TALK => 'Descusión_categoría',
+);
+
+?>
diff --git a/languages/messages/MessagesAr.php b/languages/messages/MessagesAr.php
new file mode 100644
index 000000000000..4704b32fcd9c
--- /dev/null
+++ b/languages/messages/MessagesAr.php
@@ -0,0 +1,608 @@
+<?php
+/** Arabic (العربية)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$linkPrefixExtension = true;
+$fallback8bitEncoding = 'windows-1256';
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+ # Underlines seriously harm legibility. Force off:
+ 'underline' => 0,
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'ملف',
+ NS_SPECIAL => 'خاص',
+ NS_MAIN => '',
+ NS_TALK => 'نقاش',
+ NS_USER => 'مستخدم',
+ NS_USER_TALK => 'نقاش_المستخدم',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'نقاش' . '_$1',
+ NS_IMAGE => 'صورة',
+ NS_IMAGE_TALK => 'نقاش_الصورة',
+ NS_MEDIAWIKI => 'ميدياويكي',
+ NS_MEDIAWIKI_TALK => 'نقاش_ميدياويكي',
+ NS_TEMPLATE => 'قالب',
+ NS_TEMPLATE_TALK => 'نقاش_قالب',
+ NS_HELP => 'مساعدة',
+ NS_HELP_TALK => 'نقاش_المساعدة',
+ NS_CATEGORY => 'تصنيف',
+ NS_CATEGORY_TALK => 'نقاش_التصنيف'
+);
+
+
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#REDIRECT' , '#تحويل' ),
+ 'notoc' => array( 0, '__NOTOC__' , '__لافهرس__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__' , '__لصق_فهرس__' ),
+ 'toc' => array( 0, '__TOC__' , '__فهرس__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__' , '__لاتحريرقسم__' ),
+ 'start' => array( 0, '__START__' , '__ابدأ__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH' , 'شهر' , 'شهر_حالي' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME' , 'اسم_شهر', 'اسم_شهر_حالي'),
+# 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN' ),
+# 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV' ),
+ 'currentday' => array( 1, 'CURRENTDAY' , 'يوم' ),
+# 'currentday2' => array( 1, 'CURRENTDAY2' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME' , 'اسم_يوم' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR' , 'عام' ),
+ 'currenttime' => array( 1, 'CURRENTTIME' , 'وقت' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES' ,'عددالمقالات' , 'عدد_المقالات'),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES' , 'عددالملفات' , 'عدد_الملفات'),
+ 'pagename' => array( 1, 'PAGENAME' , 'اسم_صفحة' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE' , 'عنوان_صفحة' ),
+ 'namespace' => array( 1, 'NAMESPACE' , 'نطاق' ),
+ 'namespacee' => array( 1, 'NAMESPACEE' , 'عنوان_نطاق' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'اسم_كامل' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE' , 'عنوان_كامل' ),
+ 'msg' => array( 0, 'MSG:' , 'رسالة:' ),
+ 'subst' => array( 0, 'SUBST:' , 'نسخ:' , 'نسخ_قالب:' ),
+ 'msgnw' => array( 0, 'MSGNW:' , 'مصدر:' , 'مصدر_قالب:' ),
+ 'end' => array( 0, '__END__' , '__نهاية__', '__إنهاء__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' , 'تصغير' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1' ,'تصغير=$1' ),
+ 'img_right' => array( 1, 'right' , 'يمين' ),
+ 'img_left' => array( 1, 'left' , 'يسار' ),
+ 'img_none' => array( 1, 'none' , 'بدون' ),
+ 'img_width' => array( 1, '$1px' , '$1بك' ),
+ 'img_center' => array( 1, 'center', 'centre' , 'وسط' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame' , 'إطار', 'اطار'),
+ 'int' => array( 0, 'INT:' , 'محتوى:' ),
+ 'sitename' => array( 1, 'SITENAME' , 'اسم_الموقع' ),
+ 'ns' => array( 0, 'NS:' , 'نط:' ),
+ 'localurl' => array( 0, 'LOCALURL:' , 'عنوان:' ),
+# 'localurle' => array( 0, 'LOCALURLE:' ),
+ 'server' => array( 0, 'SERVER' , 'العنوان' ),
+ 'servername' => array( 0, 'SERVERNAME' , 'اسم_عنوان' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH' , 'مسار' ),
+# 'grammar' => array( 0, 'GRAMMAR:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', 'لاتحويل_عنوان'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', 'لاتحويل_محتوى' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK' , 'أسبوع' ),
+ 'currentdow' => array( 1, 'CURRENTDOW' , 'رقم_يوم' ),
+ 'revisionid' => array( 1, 'REVISIONID' , 'نسخة' ),
+# 'plural' => array( 0, 'PLURAL:' ),
+ 'fullurl' => array( 0, 'FULLURL:', 'عنوان_كامل:' ),
+# 'fullurle' => array( 0, 'FULLURLE:' ),
+# 'lcfirst' => array( 0, 'LCFIRST:' ),
+# 'ucfirst' => array( 0, 'UCFIRST:' ),
+# 'lc' => array( 0, 'LC:' ),
+# 'uc' => array( 0, 'UC:' ),
+# 'raw' => array( 0, 'RAW:' ),
+);
+
+$digitTransformTable = array(
+ '0' => '٠',
+ '1' => '١',
+ '2' => '٢',
+ '3' => '٣',
+ '4' => '٤',
+ '5' => '٥',
+ '6' => '٦',
+ '7' => '٧',
+ '8' => '٨',
+ '9' => '٩',
+ '.' => '٫', // wrong table?
+ ',' => '٬'
+);
+
+$messages = array(
+# Dates
+'sunday' => 'الأحد',
+'monday' => 'الإثنين',
+'tuesday' => 'الثلاثاء',
+'wednesday' => 'الأربعاء',
+'thursday' => 'الخميس',
+'friday' => 'الجمعة',
+'saturday' => 'السبت',
+'january' => 'يناير',
+'february' => 'فبراير',
+'march' => 'مارس',
+'april' => 'ابريل',
+'may_long' => 'مايو',
+'june' => 'يونيو',
+'july' => 'يوليو',
+'august' => 'أغسطس',
+'september' => 'سبتمبر',
+'november' => 'نوفمبر',
+'december' => 'ديسمبر',
+'jan' => 'يناير',
+'feb' => 'فبراير',
+'mar' => 'مارس',
+'apr' => 'ابريل',
+'may' => 'مايو',
+'jun' => 'يونيو',
+'jul' => 'يوليو',
+'aug' => 'أغسطس',
+'sep' => 'سبتمبر',
+'nov' => 'نوفمبر',
+'dec' => 'ديسمبر',
+
+# Bits of text used by many pages:
+#
+'mainpage' => 'الصفحة الرئيسية',
+'mytalk' => 'صفحة نقاشي',
+'history_short' => 'تاريخ الصفحة',
+'edit' => 'عدل هذه الصفحة',
+'delete' => 'حذف هذه الصفحة',
+'protect' => 'صفحة محمية',
+'talk' => 'ناقش هذه الصفحة',
+
+# Watchlist
+#
+'watch' => 'راقب هذه الصفحة',
+'watchthispage' => 'راقب هذه الصفحة',
+'unwatch' => 'توقف عن مراقبة الصفحة',
+'unwatchthispage' => 'توقف عن مراقبة الصفحة',
+
+'1movedto2' => '$1 تم نقلها إلى $2',
+'1movedto2_redir' => 'تم نقل $1 فوق التحويلة $2',
+'about' => 'حول',
+'aboutpage' => '{{ns:project}}:حول',
+'accmailtext' => 'تم إرسال كلمة السر الخاصة بـ \'$1\' إلى العنوان $2.',
+'accmailtitle' => 'تم إرسال كلمة السر.',
+'acct_creation_throttle_hit' => 'معذرة، لقد أقمت $1 حساب. لا يممكنك عمل المزيد.',
+'actioncomplete' => 'انتهاء العملية',
+'addedwatch' => 'تمت الإضافة لقائمة المراقبة',
+'allmessages' => 'كافة رسائل النظام',
+'allpages' => 'كل الصفحات',
+'allpagessubmit' => 'اذهب',
+'alphaindexline' => '$1 إلى $2',
+'alreadyloggedin' => '<strong>المستخدم $1, انت مسجل للدخول من قبل!</strong><br />',
+'ancientpages' => 'المقالات القديمة',
+'anontalkpagetext' => '----
+هذه صفحة نقاش لمستخدم مجهول، وهو المستخدم الذي لم يقم بإنشاء حساب في {{SITENAME}}، أو لا يستعمل ذلك الحساب.
+لذا يتم إستعمال رقم ال IP للتعريف به. من الممكن أن يشترك عدد من المستخدمين بنفس رقم ال IP. إذا كنت مستخدم مجهول
+وترى أن رسائل خير موجهة لك قد وصلتك، من الممكن أن تقوم [[Special:Userlogin|بإنشاء حساب أو القيام بالدخول]]
+حتى يزول الخلط بينك وبين المستخدمين المجهولين الآخرين.',
+'anonymous' => 'مستخدم مجهول ل{{SITENAME}}',
+'article' => 'مقالة',
+'articleexists' => 'يوجد صفحة بهذا الإسم،
+أو أن الإسم الذي تم إختياره غير صالح.
+يرجى إختيار إسم آخر.',
+'articlepage' => 'عرض المقالة',
+'badfilename' => 'تم تغيير إسم الصورة إلى "$1".',
+'badipaddress' => 'لا يوجد مستخدم بهذا الإسم',
+'badquery' => 'نص بحث خاطئ',
+'badretype' => 'كلمات السر التي أدخلتها غير متطابقة.',
+'badtitle' => 'عنوان خاطئ',
+'blanknamespace' => 'مقالات',
+'blockedtext' => 'إسم المستخدم أو عنوان ال IP الخاص بك تم منعه من قبل $1.
+سبب المنع هو: <br />\'\'$2\'\' <p>
+من الممكن الإتصال مع $1 للنقاش حول المنع، أو من الممكن الإتصال مع أحد [[{{ns:project}}:Administrators|الإداريين]] حول ذلك.
+
+تذكر أنه لا يمكن لك إستعمال خاصية إرسال رسائل إلكترونية للمستخدمين إلا إذا كنت قد وضعت عنوان بريدي صحيح في صفحة [[Special:Preferences|التفضيلات]] الخاصة بك.
+
+عنوان ال IP الخاص بك هو $3. يرجى إضافته في أي رسالة للتساؤل حول المنع.',
+'blockedtitle' => 'المستخدم ممنوع',
+'blockip' => 'منع مستخدم',
+'blocklink' => 'منع مستخدم',
+'blocklogentry' => 'منع "$1" لفترة زمنية مدتها $2',
+'bold_sample' => 'نص عريض',
+'bold_tip' => 'نص عريض',
+'booksources' => 'مصدر كتاب',
+'brokenredirects' => 'وصلات مكسورة',
+'brokenredirectstext' => 'الوصلات التالية تشير لصفحات غير موجودة.',
+'bugreports' => 'تقارير الأخطاء',
+'bydate' => 'على التاريخ',
+'byname' => 'على الإسم',
+'bysize' => 'على الحجم',
+'cancel' => 'إلغاء العملية',
+'categories' => 'تصنيفات الصفحة',
+'categoriespagetext' => 'التصنيفات التالية موجودة في {{SITENAME}}',
+'category_header' => 'المقالات في التصنيف "$1"',
+'categoryarticlecount' => 'يوجد $1 مقال في هذا التصنيف.',
+'changepassword' => 'غير كلمة السر',
+'changes' => 'تغييرات',
+'columns' => 'أعمدة',
+'compareselectedversions' => 'قارن بين النسخ المختارة',
+'confirm' => 'تأكيد',
+'confirmdelete' => 'تأكيد الحذف',
+'confirmprotect' => 'تأكيد الحماية',
+'confirmprotecttext' => 'هل أنت متأكد انك تريد حماية هذه الصفحة؟',
+'confirmunprotect' => 'تأكيد إزالة الحماية',
+'confirmunprotecttext' => 'هل أنت متأكد انك تريد إزالة الحماية عن هذه الصفحة؟',
+'contribslink' => 'مساهمات',
+'contribsub' => 'للمستخدم $1',
+'contributions' => 'مساهمات المستخدم',
+'copyright' => 'المحتويات تحت $1.',
+'copyrightpage' => '{{ns:project}}:حقوق النسخ',
+'copyrightpagename' => 'حقوق النسخ في {{SITENAME}}',
+/*'copyrightwarning' => 'يرجى الملاحظة أن جميع المساهمات هنا خاضعة وصادرة تحت ترخيص
+جنو للوثائق الحرة (أنظر في $1 للمزيد من التفاصيل)
+إذا لم ترد أن تخضع كتابتك للتعديل والتوزيع الحر، لا تضعها هنا.
+<br />
+كما أنك تتعهد بأنك قمت بكتابة ما هو موجود بنفسك، أو قمت بنسخها
+من مصدر يخضع ضمن الملكية العامة، أو مصدر حر آخر.
+<strong>لا ترسل أي عمل ذو حقوق محفوظة بدون الإذن من صاحب الحق</strong>.',*/
+'createaccount' => 'إنشاء حساب جديد',
+'createaccountmail' => 'عبر البريد الإلكتروني',
+'cur' => 'الحالي',
+'currentevents' => 'احداث حالية',
+'currentrev' => 'النسخة الحالية',
+'databaseerror' => 'خطأ في قاعدة البيانات',
+'dateformat' => 'صيغة التاريخ',
+'deadendpages' => 'صفحات نهاية مسدودة',
+'defaultns' => 'أبحث في هذه النطاقات بشكل أفتراضي:',
+'defemailsubject' => 'رسالة من {{SITENAME}}',
+'deletecomment' => 'سبب الحذف',
+'deletedarticle' => 'تم حذف "$1"',
+'deletedtext' => '"$1" تم حذفها.
+انظر في $2 لسجل آخر عمليات الحذف.',
+'deleteimg' => 'حذف',
+'deletepage' => 'حذف الصفحة',
+'deletesub' => '(حذف "$1")',
+'deletethispage' => 'حذف هذه الصفحة',
+'deletionlog' => 'سجل الحذف',
+'dellogpage' => 'سجل_الحذف',
+'diff' => 'فرق',
+'disclaimerpage' => '{{ns:project}}:عدم_مسؤولية_عام',
+'disclaimers' => 'عدم مسؤولية',
+'doubleredirects' => 'وصلات مزدوجة',
+'editcurrent' => 'حرر النسخة الحالية من هذه الصفحة',
+'edithelp' => 'مساعدة التحرير',
+'edithelppage' => '{{ns:project}}:مساعدة التحرير',
+'editing' => 'تحرير $1',
+'editinguser' => 'تحرير $1',
+'editingold' => '<strong> تحذير: أنت تقوم الآن بتحرير نسخة قديمة من هذه الصفحة. إذا قمت بحفظها، سيتم فقدات كافة التغييرات التي حدثت بعد هذه النسخة. </strong>',
+'editsection' => 'تحرير',
+'editold' => 'تحرير',
+'editthispage' => 'عدل هذه الصفحة',
+'emailfrom' => 'من',
+'emailmessage' => 'نص الرسالة',
+'emailpage' => 'أرسل رسالة للمستخدم',
+'emailpagetext' => 'لو أن هذا المستخدم قد قام بإدخال عنوان بريدي صحيح في تفضيلاته،
+فسيتم إرسال رسالة واحدة له بالنموذج أدناه.
+العنوان الذي قمت أنت بإدخاله لك في تفضيلات المستخدم،
+سيظهر في مكان المرسل في الرسالة التي سترسل له، ليتمكن من الرد عليك.',
+'emailsend' => 'إرسال',
+'emailsent' => 'تم إرسال الرسالة',
+'emailsenttext' => 'تم إرسال رسالتك الإلكترونية.',
+'emailsubject' => 'العنوان',
+'emailto' => 'إلى',
+'emailuser' => 'أرسل رسالة لهذا المستخدم',
+'error' => 'خطأ',
+'errorpagetitle' => 'خطأ',
+'excontent' => 'المحتوى كان: \'$1\'',
+'excontentauthor' => 'المحتوى كان: \'$1\' (و المساهم الوحيد كان \'$2\')',
+'explainconflict' => 'لقد قام أحد ما بتعديل الصفحة بعد أن بدأت انت بتحريرها.
+صندوق النصوص العلوي يحتوي على النص الموجود حاليا في الصفحة.
+والتغييرات التي قمت أنت بها موجودة في الصندوق في أسفل الصفحة.
+يجب أن تقوم بدمج تغييراتك في النص الموجود حاليا.
+<b>فقط</b> ما هو موجود في الصندوق العلوي هو ما سيتم حفظه وإستعاله عند الضغط على زر "حفظ الصفحة".
+<p>',
+'export' => 'صدّر صفحات',
+'faq' => 'الأسئلة الأكثر تكرارا',
+'faqpage' => '{{ns:project}}:أسئلة متكررة',
+'filecopyerror' => 'لا يمكن نسخ الملف من "$1" إلى "$2".',
+'filedeleteerror' => 'لا يمكن حذف الملف "$1".',
+'filedesc' => 'وصف قصير',
+'filename' => 'إسم الملف',
+'filenotfound' => 'لا يمكن إيجاد الملف "$1".',
+'filerenameerror' => 'لا يمكن غيير إسم الملف من "$1" إلى "$2".',
+'filesource' => 'مصدر',
+'go' => 'إذهب',
+'searcharticle' => 'إذهب',
+'headline_sample' => 'نص عنوان رئيسي',
+'headline_tip' => 'عنوان من المستوى الثاني',
+'help' => 'مساعدة',
+'helppage' => '{{ns:project}}:مساعدة',
+'hide' => 'إخفاء',
+'hidetoc' => 'إخفاء',
+'hist' => 'تاريخ',
+'histlegend' => 'مفتاح: (الحالي) = الفرق مع النسخة الحالية
+(السابق) = الفروقات مع النسخة السابقة، ط = تغيير طفيف',
+'history' => 'تاريخ الصفحة',
+'ilsubmit' => 'بحث',
+'imagelist' => 'قائمة الصور',
+'imagepage' => 'عرض صفحة الصورة',
+'imgdelete' => 'حذف',
+'imgdesc' => 'وصف',
+'imghistory' => 'تاريخ الصورة',
+'internalerror' => 'خطأ داخلي',
+'intl' => 'وصلات بين لغات الموسوعة',
+'invert' => 'عكس الإختيار',
+'ipblocklist' => 'قائمة أسماء الأعضاء و عناوين ال IP الممنوعة',
+'ipbreason' => 'السبب',
+'isredirect' => 'صفحة تحويل',
+'italic_sample' => 'نص مائل',
+'italic_tip' => 'نص مائل',
+'last' => 'السابق',
+'lastmodifiedat' => 'أخر تعديل لهذه الصفحة كان في $2, $1.',
+'lineno' => 'سطر $1:',
+'link_sample' => 'عنوان وصلة',
+'linkshere' => 'الصفحات التالية تحتوي على وصلة إلى هنا:',
+'linkstoimage' => 'الصفحات التالية تحتوي على وصلة لهذه الصورة:',
+'listusers' => 'قائمة الأعضاء',
+'loadhist' => 'تحميل تاريخ الصفحة',
+'localtime' => 'عرض الوقت المحلي',
+'log' => 'تحميل و حذف',
+'login' => 'دخول',
+'loginerror' => 'خطأ في الدخول',
+'loginpagetitle' => 'تسجيل الدخول للمستخدم',
+'loginproblem' => '<b>حدثت مشكلة أثناء الدخول.</b><br />يرجى المحاولة مرى أخرى!',
+'loginprompt' => 'يجب أن يدعم متصفحك الكوكيز Cookies لتتمكن من الدخول.',
+'loginsuccess' => 'لقد قمت بتسجيل الدخول ل{{SITENAME}} بإسم "$1".',
+'loginsuccesstitle' => 'تم الدخول بشكل صحيح',
+'logout' => 'خروج',
+'logouttext' => 'أنت الآن غير مسجل الدخول للنظام.
+تستطيع المتابعة بإستعمال {{SITENAME}} كمجهول، أو الدخول مرة أخرى بنفس الإسم أو بإسم آخر. من الممكن أن ترى بعض الصفحات في الموسوعة كما وأنك مسجل في النظام.، وذلك بسبب إستعمال الصفحات المخبأة Cache في المنتصفح لديك.',
+'logouttitle' => 'تسجيل الخروج للمستخدم',
+'lonelypages' => 'صفحات يتيمة',
+'longpages' => 'صفحات طويلة',
+'mailmypassword' => 'أرسل لي كلمة السر عبر البريد الإلكتروني.',
+'mailnologin' => 'لا يوجد عنوان للإرسال',
+'minoredit' => 'هذا تعديل طفيف',
+'minoreditletter' => 'ط',
+'moredotdotdot' => 'المزيد...',
+'move' => 'نقل',
+'movearticle' => 'نقل صفحة',
+'movedto' => 'تم نقلها إلى',
+'movelogpage' => 'سجل النقل',
+'movenologin' => 'غير مسجل',
+'movepage' => 'نقل صفحة',
+'movepagebtn' => 'أنقل الصفحة',
+'movepagetalktext' => 'صفحة النقاش المرفقة بالمقالة سيتم نقلها كذلك، إذا وجدت. ولكن لا يتم نقل صفحة النقاش في الحالات التالية:
+* نقل الصفحة عبر نطاقات namespaces مختلفة.
+* يوجد صفحة نقاش غير فارغة تحت العنوان الجديد للمقالة.
+* قمت بإزالة إختيار نقل صفحة النقاش في الأسفل.
+
+وفي الحالات أعلاه، يجب عليك نقل أو دمج محتويات صفحة النقاش يدويا، إذا رغب في ذلك.',
+'movereason' => 'السبب',
+'movetalk' => 'أنقل صفحة \'\'\'النقاش\'\'\' أن أمكن.',
+'movethispage' => 'أنقل هذه الصفحة',
+'mycontris' => 'مساهماتي',
+'mypage' => 'صفحتي',
+'namespace' => 'النطاق:',
+'namespacesall' => 'الكل',
+'navigation' => 'تصفح',
+'nbytes' => '$1 بايت',
+'newarticle' => '(جديد)',
+'newarticletext' => 'لقد تبعت وصلة لصفحة لم يتم إنشائها بعد.
+لإنشاء هذه الصفحة إبدأ بالكتابة في الصندوق بالأسفل.
+(أنظر في [[{{ns:project}}:مساعدة|صفحة المساعدة]] للمزيد من المعلومات)
+إذا كانت زيارتك لهذه الصفحة بالخطأ، إضغم على زر \'\'رجوع\'\' في متصفح الإنترنت لديك.',
+'newimages' => 'معرض الصور الجديدة',
+'newmessageslink' => 'رسائل جديدة',
+'newpage' => 'صفحة جديدة',
+'newpageletter' => 'ج',
+'newpages' => 'صفحات جديدة',
+'newpassword' => 'كلمة السر الجديدة',
+'newtitle' => 'إلى العنوان الجديد',
+'newwindow' => '(يفتح في شباك جديد)',
+'next' => 'التالي',
+'nextn' => '$1 التالية',
+'nlinks' => '$1 وصلة',
+'noarticletext' => '(لا يوجد حاليا أي نص في هذه الصفحة)',
+'noemail' => 'لا يوجد أي عنوان بريدي مسجل للمستخدم "$1".',
+'noemailtext' => 'لم يحدد هذا المستخدم عنوان بريد إلكتروني صحيح،
+أو طلب عدم إستلام الرسائل من المستخدمين الآخرين.',
+'noemailtitle' => 'لا يوجد عنوان بريد إلكتروني',
+'noexactmatch' => 'لا يوجد صفحة بنفس العنوان، حاول البحث بشكل مفصل أكثر من خلال إستعمال صندوق البحث أدناه. بإمكانك أيضاً إنشاء [[:$1|صفحة جديدة]] بالعنوان الذي طلبته.',
+'nohistory' => 'لا يوجد تاريخ للتغييرات لهذه الصفحة.',
+'nolinkshere' => 'لا يوجد صفحات تصل لهذه الصفحة.',
+'nolinkstoimage' => 'لا يوجد صفحات تصل لهذه الصورة.',
+'noname' => 'لم تحدد إسم مستخدم صحيح.',
+'nospecialpagetext' => 'لقد طلبت صفحة خاصة لا يمكن التعرف عليها من قبل نظام الويكي.',
+'nosuchspecialpage' => 'لا يوجد صفحة خاصة بهذا الإسم',
+'nosuchuser' => 'لا يوجد مستخدم بالإسم "$1".
+تأكد من إملاء الإسم، أو إستعمل النموذج الموجود في الأسفل لإنشاء مستخدم جديد.',
+'note' => '<strong>ملاحظة:</strong>',
+'notextmatches' => 'لم يتم إيجاد أي نص مطابق',
+'notitlematches' => 'لم يتم إيجاد أي عنوان مطابق',
+'notloggedin' => 'غير مسجل',
+'nowatchlist' => 'لا يوجد شيء في قائمة مراقبتك.',
+'nowiki_tip' => 'أهمل تهيئة الويكي',
+'nstab-category' => 'تصنيف',
+'nstab-help' => 'مساعدة',
+'nstab-image' => 'صورة',
+'nstab-main' => 'مقالة',
+'nstab-mediawiki' => 'رسالة',
+'nstab-special' => 'خاص',
+'nstab-template' => 'قالب',
+'nstab-user' => 'صفحة مستخدم',
+'nstab-project' => 'حول',
+'ok' => 'موافق',
+'oldpassword' => 'كلمة السر القديمة',
+'orig' => 'الأصلي',
+'otherlanguages' => ' لغات أخرى',
+'pagecategories' => 'تصنيفات الصفحة',
+'pagemovedsub' => 'تم النقل بنجاح',
+'pagemovedtext' => 'تم نقل الصفحة "[[$1]]" إلى "[[$2]]".',
+'passwordremindertitle' => 'تذكير بكلمة السر من {{SITENAME}}',
+'passwordsent' => 'تم إرسال كلمة سر جديدة إلى العنوان البريدي المسجل للمستخدم "$1".
+يرجى محاولة تسجيل الدخول مرة أخرى عند إستلامها.',
+'popularpages' => 'الصفحات المشهورة',
+'portal' => 'بوابة المجتمع',
+'portal-url' => '{{ns:project}}:بوابة المجتمع',
+'postcomment' => 'أرسل تعليق',
+'powersearch' => 'بحث',
+'preferences' => 'تفضيلات',
+'prefsnologin' => 'غير مسجل',
+'preview' => 'عرض مسبق',
+'previewnote' => 'تذكر، هذا فقط عرض مسبق للصفحة، ولم يتم حفظه بعد!',
+'prevn' => '$1 السابقة',
+'printableversion' => 'نسخة للطباعة',
+'protectcomment' => 'سبب الحماية',
+'protectedarticle' => 'حماية [[$1]]',
+'protectedpage' => 'صفحة محمية',
+'protectlogpage' => 'سجل_الحماية',
+'protectthispage' => 'حماية هذه الصفحة',
+'qbbrowse' => 'تصفح',
+'qbedit' => 'تحرير',
+'qbfind' => 'بحث',
+'qbmyoptions' => 'صفحاتي',
+'qbpageinfo' => 'سياق النص',
+'qbpageoptions' => 'هذه الصفحة',
+'qbsettings' => 'خيارات لوحة الوصلات',
+'qbspecialpages' => 'الصفحات الخاصّة',
+'randompage' => 'صفحة عشوائية',
+'rclinks' => 'أظهر آخر $1 تعديل في آخر $2 يوم، $3',
+'rclistfrom' => 'أظهر التغييرات بدأ من $1',
+'rclsub' => '(لصفحات تصل بها الصفحة "$1")',
+'rcnote' => 'في الأسفل ستجد آخر <strong>$1</strong> تعديل في آخر <strong>$2</strong> أيام.',
+'rcnotefrom' => 'في الأسفل التغييرات منذ <b>$2</b> (ولغاية <b>$1</b>).',
+'readonly' => 'قاعدة البيانات مغلقة',
+'readonlytext' => 'قاعدة البيانات مغلقة حاليا أمام الإضافات والتعديلات، السبب غالبا ما يكون الصيانة، وستعود قاعدة البيانات للوضع الطبيعي قريبا.
+عندما تم أغلاق قاعدة البيانات أمام التعديلات والإضافات تم أعطاء السبب التالي:
+<p>$1',
+'recentchanges' => 'أحدث التغييرات',
+'recentchangescount' => 'عدد العناوين في صفحة أحدث التغييرات',
+'recentchangeslinked' => 'تغييرات ذات علاقة',
+'recentchangestext' => 'تابع آخر التغييرات في الموسوعة من هذه الصفحة.',
+'redirectedfrom' => '(تم التحويل من $1)',
+'remembermypassword' => 'تذكر كلمة السر عبر الجلسات.',
+'removechecked' => 'حذف المواد المختارة من قائمة المراقبة.',
+'removedwatch' => 'تم الحذف من قائمة المراقبة',
+'removedwatchtext' => 'تم حذف الصفحة "$1" من قائمة مراقبتك.',
+'removingchecked' => 'حذف الصفحات المطلوبة من قائمة المراقبة...',
+'returnto' => 'أرجع إلى $1.',
+'retypenew' => 'أعد كتابة كلمة السر الجديدة',
+'revertpage' => 'إسترجاع المقال حتى أخر تعديل من قبل $1',
+'revhistory' => 'تاريخ التغييرات',
+'revnotfound' => 'النسخة غير موجودة',
+'rows' => 'أسطر',
+'savearticle' => 'حفظ الصفحة',
+'savedprefs' => 'تم حفظ تفضيلاتك.',
+'savefile' => 'حفظ الملف',
+'saveprefs' => 'حفظ التفضيلات',
+'search' => 'بحث',
+'searchbutton' => 'بحث',
+'searchdisabled' => '<p>عذرا! لقد تم إيقاف ميزة البحث في النصوص بشكل مؤقت، لأسباب تتعلق بتأثيرها على الأداء العام. في الوقت الحالي من الممكن أن تستعمل محرك البحث جووجل Google بدل من خاصية البحث في النصوص. من الممكن أن لا يكون البحث في جووجل يشمل آخر التعديلات والصفحات.
+</p>',
+'searchsubtitle' => 'لصيغة البحث "[[:$1]]"',
+'searchsubtitleinvalid' => 'لصيغة البحث "$1"',
+'searchresults' => 'نتائج البحث',
+'searchresultshead' => 'خيارات نتائج البحث',
+'searchresulttext' => 'للمزيد من المعلومات حول البحث في {{SITENAME}}، راجع [[{{ns:project}}:تصفح]].',
+'servertime' => 'الوقت في الأجهزة الخادمة الآن هو',
+'shortpages' => 'صفحات قصيرة',
+'show' => 'عرض',
+'showdiff' => 'أظهر الفرق',
+'showpreview' => 'عرض التعديلات',
+'showtoc' => 'إظهار',
+'sitestats' => 'إحصاءات الموقع',
+'sitestatstext' => 'يوجد <b>$1</b> صفحة في قاعدة بيانات الموسوعة العربية، وهذا يشمل صفحات النقاش، والصفحات الخاصة بنظام {{SITENAME}}، والمقالات الصغيرة التي تحتاج تطوير، والتحويلات، وغيرها مما لا يرقى لأن يكون مقالا. إذا تم أهمال تلك الصفحات، فإن عدد الصفحات التي قد تحتوي على مقالات يكون <b>$2</b>.<p>
+تم عرض الصفحات <b>$3</b> مرة، وعدد التعديلات على الصفحات<b>$4</b> تعديل، منذ إنشاء الموسوعة العربية في يوليو/تموز 2003.
+وهذا يعني أن معدل التعديل لكل صفحة <b>$5</b> تعديل، ومعدل عرض كل صفحة <b>$6</b> عرض.',
+'sitesupport' => 'التبرعات',
+'specialpage' => 'صفحة خاصة',
+'specialpages' => 'الصفحات الخاصّة',
+'spheading' => 'الصفحات الخاصة لكل المستخدمين',
+'statistics' => 'إحصاءات',
+'storedversion' => 'النسخة المخزنة',
+'subcategories' => 'التصنيفات الفرعية',
+'subcategorycount' => 'يوجد $1 تصنيف فرعي في هذا التصنيف.',
+'subject' => 'موضوع',
+'successfulupload' => 'تحميل الملف بنجاح',
+'summary' => 'ملخص',
+'talkexists' => 'تم نقل الصفحة بنجاح، لكن لم
+يتم نقل صفحة النقاش المرافقة، بسبب وجود صفحة نقاش
+مسبقا تحت العوان الجديد.
+يرجى نقل محتويات صفحة النقاش يدويا، ودمجها مع المحتويات السابقة.',
+'talkpage' => 'ناقش هذه الصفحة',
+'talkpagemoved' => 'تم نقل صفحة النقاش أيضا.',
+'talkpagenotmoved' => '<strong>لم</strong> يتم نقل صفحة النقاش.',
+'templatesused' => 'القوالب المستخدمة في هذه الصفحة:',
+'textboxsize' => 'أبعاد صندوق النصوص',
+'thumbnail-more' => 'تكبير',
+'toc' => 'فهرست',
+'toolbox' => 'أدوات',
+'uclinks' => 'عرض آخر $1 تعديل; عرض أخر $2 يوم.',
+'ucnote' => 'في الأسفل ستجد آخر <b>$1</b> تعديل لهذا المستخدم في <b>$2</b> أيام.',
+'uctop' => ' (أعلى)',
+'unblocklink' => 'رفع المنع عن مستخدم',
+'uncategorizedcategories' => 'تصنيفات غير مصنفة',
+'uncategorizedpages' => 'صفحات غير مصنفة',
+'undelete' => 'إرجاع صفحات محذوفة',
+'unprotect' => 'أزل الحماية',
+'unprotectcomment' => 'سبب إزالة الحماية',
+'unprotectedarticle' => 'ازالة حماية [[$1]]',
+'unprotectthispage' => 'أزل الحماية عن الصفحة',
+'unusedimages' => 'صور غير مستعملة',
+'upload' => 'تحميل ملف',
+'uploadbtn' => 'تحميل الملف',
+'uploaddisabled' => 'عذرا، تم إيقاف خاصية تحميل الملفات.',
+'uploadedfiles' => 'الملفات المحملة',
+'uploadedimage' => 'تم تحميل "$1"',
+'uploaderror' => 'خطأ في التحميل',
+'uploadlogpagetext' => 'في الأسفل قائمة بأخر الملفات التي تم تحميلها.
+كل الأوقات المعروضة هي حسب توقيت الأجهزةالخادمة (UTC).
+<ul>
+</ul>',
+'uploadnologin' => 'لم تقم بتسجيل الدخول',
+'uploadwarning' => 'تحذير تحميل الملفات',
+'userexists' => 'إسم المستخدم الذي إخترته مستخدم من قبل، يرجى إختيار إسم مستخدم آخر.',
+'userlogin' => 'دخول',
+'userlogout' => 'خروج',
+'userpage' => 'عرض صفحة المستخدم',
+'userstats' => 'إحصاءات المستخدم',
+'userstatstext' => 'يوجد <b>$1</b> عضو مسجل. ومنهم <b>$2</b> إداريين. (أنظر $3)',
+'version' => 'رقم النسخة',
+'viewcount' => 'تم عرض محتويات هذه الصفحة $1 مرة.',
+'viewsource' => 'عرض المصدر للمقالة',
+'viewtalkpage' => 'عرض النقاش',
+'wantedpages' => 'صفحات مطلوبة',
+'watcheditlist' => 'فيما يلي قائمة مرتبة أبجديا للصفحات الموجودة في قائمة المراقبة لديك.
+أختر الصفحات التري تريد إزالتها من خلال الإشارة عليها من الصندوق بجانبها.
+وإضغط على زر \'حذف المختارات\' في آخر الصفحة.',
+'watchlist' => 'قائمة مراقبتي',
+'watchlistcontains' => 'تحتوي قائمة المراقبة لديك على $1 صفحة.',
+'watchmethod-list' => 'إظهار التحريرات في الصفحات المراقبة',
+'watchmethod-recent' => 'تفحص التغييرات الأخيرة في قائمة المراقة لديك',
+'watchnochange' => 'لم يتم تعديل أي صفحة في قائمة المراقبة لديك خلال الفترة المحددة.',
+'watchnologin' => 'غير مسجل',
+'watchthis' => 'راقب هذه الصفحة',
+'welcomecreation' => '<h2>أهلا بك يا , $1!</h2><p> تم إنشاء حسابك.
+لا تنسى أن تقوم بتغيير وتحديد تفضيلاتك في {{SITENAME}}.',
+'whatlinkshere' => 'ماذا يرتبط هنا؟',
+'whitelistacctitle' => 'لا يسمح لك بإنشاء إشتراك',
+'whitelistedittext' => 'يجب عليك [[Special:Userlogin|تسجيل الدخول]] لتتمكن من تعديل الصفحات.',
+'whitelistedittitle' => 'الدخول ضروري للقيام بالتعديل',
+'whitelistreadtext' => 'يجب عليك [[Special:Userlogin|تسجيل الدخول]] لتتمكن من قراءة المقالات.',
+'whitelistreadtitle' => 'تسجيل الدخول ضروري للقراءة',
+'projectpage' => 'عرض الصفحة العامة',
+'wlnote' => 'في الأسفل آخر $1 تعديل في آخر <b>$2</b> ساعة.',
+'wlsaved' => 'هذه نسخة مخزنة من قائمة المراقبة لديك.',
+'wlshowlast' => 'عرض أخر $1 ساعات $2 أيام $3',
+'wrongpassword' => 'كلمة السر التي أدخلتها غير صحيحة، يرجى إعادة المحاولة.',
+'yourdiff' => 'الفروقات',
+'youremail' => 'بريدك الإلكتروني*',
+'yourname' => 'اسمك',
+'yournick' => 'اللقب الخاص بك (للتواقيع)',
+'yourpassword' => 'كلمة السر خاصتك',
+'yourpasswordagain' => 'أعد كتابة كلمة السر',
+'yourrealname' => 'اسمك الحقيقي*',
+'yourtext' => 'النص الذي كتبته',
+);
+
+
+?>
diff --git a/languages/messages/MessagesArc.php b/languages/messages/MessagesArc.php
new file mode 100644
index 000000000000..400e7d5f3c6b
--- /dev/null
+++ b/languages/messages/MessagesArc.php
@@ -0,0 +1,15 @@
+<?php
+
+/** Aramaic ( ܕܥܒܪܸܝܛ )
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+);
+
+?>
diff --git a/languages/messages/MessagesAs.php b/languages/messages/MessagesAs.php
new file mode 100644
index 000000000000..3ab1c32ef300
--- /dev/null
+++ b/languages/messages/MessagesAs.php
@@ -0,0 +1,20 @@
+<?php
+/** Assamese (অসমীয়া)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$digitTransformTable = array(
+ '0' => '০',
+ '1' => '১',
+ '2' => '২',
+ '3' => '৩',
+ '4' => '৪',
+ '5' => '৫',
+ '6' => '৬',
+ '7' => '৭',
+ '8' => '৮',
+ '9' => '৯'
+);
+?>
diff --git a/languages/messages/MessagesAst.php b/languages/messages/MessagesAst.php
new file mode 100644
index 000000000000..5fcd7d5d727f
--- /dev/null
+++ b/languages/messages/MessagesAst.php
@@ -0,0 +1,29 @@
+<?php
+/** Asturian (Asturianu)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Especial',
+ NS_MAIN => '',
+ NS_TALK => 'Discusión',
+ NS_USER => 'Usuariu',
+ NS_USER_TALK => 'Usuariu_discusión',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_discusión',
+ NS_IMAGE => 'Imaxen',
+ NS_IMAGE_TALK => 'Imaxen_discusión',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_discusión',
+ NS_TEMPLATE => 'Plantilla',
+ NS_TEMPLATE_TALK => 'Plantilla_discusión',
+ NS_HELP => 'Ayuda',
+ NS_HELP_TALK => 'Ayuda_discusión',
+ NS_CATEGORY => 'Categoría',
+ NS_CATEGORY_TALK => 'Categoría_discusión',
+);
+
+?>
diff --git a/languages/messages/MessagesAv.php b/languages/messages/MessagesAv.php
new file mode 100644
index 000000000000..39a715bf8b93
--- /dev/null
+++ b/languages/messages/MessagesAv.php
@@ -0,0 +1,9 @@
+<?php
+/** Avar (Авар)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'ru';
+?> \ No newline at end of file
diff --git a/languages/messages/MessagesAy.php b/languages/messages/MessagesAy.php
new file mode 100644
index 000000000000..cd0d143befc5
--- /dev/null
+++ b/languages/messages/MessagesAy.php
@@ -0,0 +1,9 @@
+<?php
+/** Tahitian (Reo Mā`ohi)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'fr';
+?>
diff --git a/languages/messages/MessagesAz.php b/languages/messages/MessagesAz.php
new file mode 100644
index 000000000000..82eee6a45e0f
--- /dev/null
+++ b/languages/messages/MessagesAz.php
@@ -0,0 +1,675 @@
+<?php
+/** Azerbaijani (Azərbaycan)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Mediya',
+ NS_SPECIAL => 'Xüsusi',
+ NS_MAIN => '',
+ NS_TALK => 'Müzakirə',
+ NS_USER => 'İstifadəçi',
+ NS_USER_TALK => 'İstifadəçi_müzakirəsi',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_müzakirəsi',
+ NS_IMAGE => 'Şəkil',
+ NS_IMAGE_TALK => 'Şəkil_müzakirəsi',
+ NS_MEDIAWIKI => 'MediyaViki',
+ NS_MEDIAWIKI_TALK => 'MediyaViki_müzakirəsi',
+ NS_TEMPLATE => 'Şablon',
+ NS_TEMPLATE_TALK => 'Şablon_müzakirəsi',
+ NS_HELP => 'Kömək',
+ NS_HELP_TALK => 'Kömək_müzakirəsi',
+ NS_CATEGORY => 'Kateqoriya',
+ NS_CATEGORY_TALK => 'Kateqoriya_müzakirəsi',
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+
+$messages = array(
+
+# User preference toggles # Kullanıcı seçenekleri
+'tog-fancysig' => 'Xam imza (daxili bağlantı yaratmaz)',
+'tog-hideminor' => 'Son dəyişikliklərdə kiçik redaktələri gizlə',
+'tog-rememberpassword' => 'Parolu xatırla',
+'tog-showtoc' => 'Mündərəcat siyhəsin göstər (3 başliqdan artix ola səhifələrdə)',
+
+'underline-always' => 'Həmişə',
+'underline-default' => 'Browser default',
+'underline-never' => 'Həç zaman',
+
+'skinpreview' => '(Sınaq göstərişi)',
+
+# dates # zaman bilgileri
+'monday' => 'Bazar ertǝsi',
+'tuesday' => 'Çǝrşenbǝ axşamı',
+'wednesday' => 'Çǝrşenbǝ',
+'thursday' => 'Cümǝ axşamı',
+'friday' => 'Cümǝ',
+'saturday' => 'Şǝnbǝ',
+'sunday' => 'Bazar',
+'january' => 'Yanvar',
+'february' => 'Fevral',
+'march' => 'Mart',
+'april' => 'Aprel',
+'may_long' => 'May',
+'june' => 'Iyun',
+'july' => 'Iyul',
+'august' => 'Avqust',
+'september' => 'Sentyabr',
+'october' => 'Oktyabr',
+'november' => 'Noyabr',
+'december' => 'Dekabr',
+'jan' => 'Yanvar',
+'feb' => 'Fevral',
+'mar' => 'Mart',
+'apr' => 'Aprel',
+'may' => 'May',
+'jun' => 'Iyun',
+'jul' => 'Iyul',
+'aug' => 'Avqust',
+'sep' => 'Sentyabr',
+'oct' => 'Oktyabr',
+'nov' => 'Noyabr',
+'dec' => 'Dekabr',
+# Bits of text used by many pages: # Birçok sayfada geçen metinler
+#
+'categories' => 'Kateqoriyalar',
+'pagecategories' => 'Kateqoriyalar',
+'category_header' => '"$1" kategoriyasındaki məqalələr',
+'subcategories' => 'Alt kategoriyalar',
+
+'mainpage' => 'Ana Səhifə',
+
+'portal' => 'Kənd Meydani',
+'portal-url' => 'Project:Kənd Meydani',
+'about' => 'İzah',
+'aboutpage' => 'Project:İzah',
+'aboutsite' => '{{SITENAME}} haqqında',
+'article' => 'Mündəricat Səhifəsi',
+'help' => 'Kömək',
+'helppage' => 'Help:Mündəricət',
+'bugreports' => 'Xəta mə\'ruzəsı',
+'bugreportspage' => 'Project:Xəta_mə\'ruzəsı',
+'sitesupport' => 'Bağışlar',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => 'Redaktə kömək',
+'newwindow' => '(Yeni pəncərədə açılır)',
+'edithelppage' => 'Help:Redaktə',
+'cancel' => 'Ləğv et',
+'qbfind' => 'Tap',
+'qbbrowse' => 'Browse',
+'qbedit' => 'Redaktə',
+'qbpageoptions' => 'Bu səhifə',
+'qbpageinfo' => 'Məzmun',
+'qbmyoptions' => 'Mənim səhifələrim',
+'qbspecialpages' => 'Xüsusi səhifələr',
+'moredotdotdot' => 'More...',
+'mypage' => 'Mənim səhifəm',
+'mytalk' => 'Danişiqlarım',
+'navigation' => 'Rəhbər',
+
+# Metadata in edit box
+
+'currentevents' => 'Güncəl hadisələr',
+'currentevents-url' => 'Project:Güncəl Hadisələr',
+'disclaimers' => 'İmtina etmə',
+'errorpagetitle' => 'Xəta',
+'returnto' => '$1 səhifəsinə qayıt.',
+'go' => 'Gətir',
+'searcharticle' => 'Gətir',
+'search' => 'Axtar',
+'searchbutton' => 'Axtar',
+'history' => 'Səhifənin tarixçəsi',
+'history_short' => 'Tarixçə',
+'printableversion' => 'Çap variantı',
+'permalink' => 'Daimi bağlantı',
+'edit' => 'Redaktə',
+'editthispage' => 'Bu səhifəni redaktə edin',
+'delete' => 'Sil',
+'deletethispage' => 'Bu səhifəni sil',
+'protect' => 'Qoru',
+'protectthispage' => 'Bu səhifəni qoru',
+'unprotect' => 'Qorumanı bitir',
+'unprotectthispage' => 'Bu səhifəni qoruma',
+'newpage' => 'Yeni səhifə',
+'talkpage' => 'Bu səhifəyi müzakirə et',
+'specialpage' => 'Xüsusi səhifə',
+'postcomment' => 'Post a comment',
+'articlepage' => 'Məqaləyə get',
+'talk' => 'Müzakirə',
+'toolbox' => 'Alətlər Sandıqı',
+'userpage' => 'İstifadəçi səhifəsini göstər',
+'projectpage' => 'Layihə səhifəsini göstər',
+'viewtalkpage' => 'View discussion',
+'otherlanguages' => 'Başqa dillərdə',
+'redirectedfrom' => '($1 səhifəsindən istiqamətləndirilmişdir)',
+'redirectpagesub' => 'İstiqamətləndirmə səhifəsi',
+'lastmodifiedat' => 'Bu səhifə sonuncu dəfə $2, $1 tarixində redaktə edilib.',
+'copyright' => 'Bu məzmun $1 əhatəsindədir.',
+
+'nbytes' => '$1 bayt',
+'youhavenewmessages' => 'Hal-hazırda $1 var. ($2)',
+'newmessageslink' => 'yeni mesajlar!',
+'editsection' => 'redaktə',
+'editold' => 'redaktə',
+'toc' => 'Mündəricat',
+'showtoc' => 'göstər',
+'hidetoc' => 'gizlə',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Məqalə',
+'nstab-user' => 'İstifadəçi səhifəsi',
+'nstab-special' => 'Xüsusi',
+'nstab-project' => 'Layihə səhifəsi',
+'nstab-image' => 'Fayl',
+'nstab-mediawiki' => 'Mə\'lumat',
+'nstab-template' => 'Şablon',
+'nstab-help' => 'Kömək',
+'nstab-category' => 'Kateqoriya',
+
+# General errors
+#
+'error' => 'Xəta',
+'databaseerror' => 'Verilənlər bazası xətası',
+'readonly' => 'Verilənlər bazası kilidli',
+'internalerror' => 'Daxili xəta',
+'badtitle' => 'Yanlış başlıq',
+'viewsource' => 'Mənbə göstər',
+
+# Login and logout pages
+#
+'logouttext' => '<strong>Sistemdən çıxdınız.</strong><br /> Vikipediyanı anonim olaraq istifadə etməyə davam edəbilər, və ya eyni yaxud başqa istifadəçi adı ilə yenidən daxil ola bilərsiniz. Diqqətinizə çatdırırıq ki, ön yaddaşı (browser cache) təmizləyənə qədər bə\'zi səhifələr sistemdən çıxdığınız halda da göstərilə bilər.',
+'logouttitle' => 'İstifadəçi çıxış',
+'welcomecreation' => '== $1, xoş gəlmişsiniz! == Hesabınız yaradıldı. {{SITENAME}} nizamlamalarını dəyişdirməyi unutmayın.',
+'loginpagetitle' => 'İstifadəçi Giriş Səhifəsi',
+'yourname' => 'İstifadəçi adı',
+'yourpassword' => 'Parol',
+'yourpasswordagain' => 'Parolu təkrar yazın',
+'remembermypassword' => 'Məni xatırla',
+'alreadyloggedin' => '<strong>User $1, Siz onsuz da daxil olmusunuz!</strong><br />',
+
+'login' => 'Daxil ol',
+'loginprompt' => '{{SITENAME}}-ya daxil olmaq üçün "veb kökələrinin" (cookies) istifadəsinə icazə verilməlidir.',
+'logout' => 'Çıxış',
+'userlogin' => 'Daxil ol və ya istifadəçi yarat',
+'userlogout' => 'Çıxış',
+'nologin' => 'İstifadəçi adınız yoxdursa, $1.',
+'nologinlink' => 'hesab açın',
+'createaccount' => 'Yeni hesab aç',
+'gotaccount' => 'Giriş hesabınız varsa $1.',
+'gotaccountlink' => 'daxil olun',
+'createaccountmail' => 'e-məktub ilə',
+'username' => 'İstifadəçi adı:',
+'uid' => 'İstifadəçi ID:',
+'youremail' => 'E-məktub *',
+'yourlanguage' => 'Dil:',
+'yournick' => 'Ləqəb:',
+'yourrealname' => 'Həqiqi adınız *',
+'email' => 'E-məktub',
+'prefs-help-email' => '* E-məktub (qeyri-məcburi): Enables others to contact you through your user or user_talk page without the need of revealing your identity.',
+'loginsuccess' => '\'\'\'"$1" olaraq {{SITENAME}}-ya daxil oldunuz.\'\'\'',
+'loginsuccesstitle' => 'Daxil olundu',
+'wrongpassword' => 'Yanlış parol. Təkrar yaz.',
+'wrongpasswordempty' => 'Parol boş. Təkrar yaz.',
+'mailmypassword' => 'Parolu unutmuşam',
+'noemail' => '"$1" adlı istifadəçi e-məktub ünvanı qeyd edmemişdir.',
+'acct_creation_throttle_hit' => 'Siz artıq $1 hesab açmısınız. Daha çox hesab açabilmərsiniz.',
+'emailauthenticated' => 'E-məktub ünvanınız $1 tarixində təsdiq edilib.',
+'emailnotauthenticated' => 'Your e-mail address is not yet authenticated. No e-mail will be sent for any of the following features.',
+'emailconfirmlink' => 'E-məktubunu təsdiq et',
+'invalidemailaddress' => 'E-məktub ünvanını qeyri düzgün formatda olduğu üçün qəbul edə bilmirik. Xahiş edirik düzgün formatlı ünvan daxil edin və ya bu sahəni boş qoyun.',
+
+# Edit page toolbar
+
+'bold_sample' => 'Qalın mətn',
+'bold_tip' => 'Qalın mətn',
+'italic_sample' => 'Kursiv mətn',
+'italic_tip' => 'Kursiv mətn',
+'link_sample' => 'Bağlantı başlığı',
+'link_tip' => 'Daxili bağlantı',
+'extlink_sample' => 'http://www.misal.com başlıq',
+'extlink_tip' => 'Xarici səhifə (http:// ekini unutma)',
+'headline_sample' => 'Başlıq metni',
+'headline_tip' => '2. səviyyə başlıq',
+'image_sample' => 'Misal.jpg',
+'media_sample' => 'Misal.ogg',
+'hr_tip' => 'Horizontal cizgi',
+
+# Edit pages
+#
+'summary' => 'Qısa məzmun',
+'subject' => 'Mövzu/başlıq',
+'minoredit' => 'Kiçik redaktə',
+'watchthis' => 'Bu səhifəni izlə',
+'savearticle' => 'Səhifəni qeyd et',
+'preview' => 'Sınaq göstərişi',
+'showpreview' => 'Sınaq göstərişi',
+'showdiff' => 'Dəyişiklikləri göstər',
+'blockedtitle' => 'İstifadəçi bloklanıb',
+'whitelistacctitle' => 'You are not allowed to create an account',
+'whitelistedittitle' => 'Redaktə üçün daxil olmalısınız',
+'whitelistreadtitle' => 'Oxumaq üçün daxil olmalısınız',
+'accmailtext' => '"$1" üçün parol göndərildi bu ünvana : $2.',
+'accmailtitle' => 'Parol göndərildi.',
+'newarticle' => '(Yeni)',
+'newarticletext' => 'Mövcud olmayan səhifəyə olan keçidi izlədiniz. Aşağıdakı sahəyə məzmununu yazaraq bu səhifəni \'\'\'siz\'\'\' yarada bilərsiniz. (əlavə məlumat üçün [[Project:Help|kömək səhifəsinə]] baxın). Əgər bu səhifəyə səhvən gəlmisinizsə sadəcə olaraq brauzerin \'\'\'geri\'\'\' düyməsinə vurun.',
+'noarticletext' => 'Hal-hazırda bu səhifə boşdur. Başqa səhifələrdə [[{{ns:special}}:Search/{{PAGENAME}}|bu səhifənin adını axtara]] bilər və ya \'\'\'[{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} səhifəni siz redaktə edəbilərsiniz]\'\'\'.',
+'previewnote' => '<strong>Bu yalnız sınaq göstərişidir; dəyişikliklər hal-hazırda qeyd edilmemişdir!</strong>',
+'editing' => 'Redaktə $1',
+'editinguser' => 'Redaktə $1',
+'yourtext' => 'Metniniz',
+'yourdiff' => 'Fərqlər',
+'templatesused' => 'Bu səhifədə istifadə edilmiş şablonlar:',
+
+
+# History pages
+#
+'revhistory' => 'Versiya tarixçəsi',
+'currentrev' => 'Hal-hazırkı versiya',
+'revisionasof' => '$1 versiyası',
+'previousrevision' => '←Əvvəlki versiya',
+'nextrevision' => 'Sonrakı versiya→',
+'currentrevisionlink' => 'Hal-hazırkı versiyanı göstər',
+'cur' => 'hh',
+'next' => 'sonrakı',
+'last' => 'son',
+'orig' => 'orig',
+'histfirst' => 'Ən əvvəlki',
+'histlast' => 'Ən sonuncu',
+'histlegend' => 'Fərqləri seçmə və göstərmə: müqaisə etmək istədiyiniz versiyaların yanındakı radio qutularına işarə qoyun və daxil etmə düyməsinə(enter-a) və ya "müqaisə et" düyməsinə vurun.<br />
+Açıqlama: (hh) = hal-hazırkı versiya ilə olan fərqlər,
+(son) = əvvəlki versiya ilə olan fərqlər, K = kiçik redaktə.',
+
+# Diffs
+#
+'difference' => '(Versiyalar arasındakı fərq)',
+'lineno' => 'Sətir $1:',
+'editcurrent' => 'Bu səhifənin hal-hazırkı versiyanı redaktə et',
+'compareselectedversions' => 'Seçilən versiyaları müqaisə et',
+
+# Search results
+#
+'prevn' => 'əvvəlki $1',
+'nextn' => 'sonrakı $1',
+'viewprevnext' => 'Göstər ($1) ($2) ($3).',
+'powersearch' => 'Axtar',
+'blanknamespace' => '(Ana)',
+
+# Preferences page
+#
+'preferences' => 'Nizamlamalar',
+'changepassword' => 'Parol dəyiş',
+'math' => 'Riyaziyyat',
+'dateformat' => 'Tarix formatı',
+'datedefault' => 'Tərcih yox',
+'datetime' => 'Tarix və vaxt',
+'prefs-misc' => 'Digər tərcihlər',
+'prefs-personal' => 'İstifadəçi profili',
+'prefs-rc' => 'Son dəyişikliklər',
+'saveprefs' => 'Qeyd et',
+'resetprefs' => 'Reset',
+'oldpassword' => 'Köhne parol:',
+'newpassword' => 'Yeni parol:',
+'retypenew' => 'Yeni parolu təkrar yazın:',
+'textboxsize' => 'Redaktə',
+'searchresultshead' => 'Axtar',
+'recentchangescount' => 'Son dəyişikliklərdə başlıq sayı:',
+'savedprefs' => 'Tərcihlər qeyd edildi.',
+'timezonelegend' => 'Saat qurşağı',
+'timezonetext' => 'Server ilə vaxt fərqı. (Azərbaycan üçün +04:00)',
+'localtime' => 'Məhəlli vaxt',
+'timezoneoffset' => 'Vaxt fərqı¹',
+'servertime' => 'Server vaxtı',
+'allowemail' => 'Digər istifadəçilər mənə e-məktub göndərəbilir',
+'defaultns' => 'Search in these namespaces by default:',
+'default' => 'default',
+'files' => 'Fayllar',
+
+# User levels special page
+#
+
+# switching pan
+'userrights-lookup-user' => 'İstifadəçi qruplarını idarə et',
+'userrights-user-editname' => 'İstifadəçi adınızı yazın:',
+
+
+# Recent changes
+#
+'changes' => 'dəyişiklik',
+'recentchanges' => 'Son dəyişikliklər',
+'recentchangestext' => '\'\'\'Ən son dəyişiklikləri bu səhifədən izləyin.\'\'\'',
+'rcnote' => 'Aşağıdakı son <strong>$1</strong> dəyişiklik son <strong>$2</strong> gün ərzində edilmişdir.',
+'rcnotefrom' => 'Below are the changes since <b>$2</b> (up to <b>$1</b> shown).',
+'rclistfrom' => '$1 vaxtından başlayaraq yeni dəyişiklikləri göstər',
+'rclinks' => 'Son $2 gün ərzindəki son $1 dəyişikliyi göstər <br />$3',
+'diff' => 'fərq',
+'hist' => 'tarixçə',
+'hide' => 'gizlət',
+'show' => 'göstər',
+'minoreditletter' => 'k',
+'newpageletter' => 'Y',
+
+# Upload
+#
+'upload' => 'Qarşıya yüklə',
+'uploadbtn' => 'Sənəd yüklə',
+'reupload' => 'Təkrar yüklə',
+'reuploaddesc' => 'Return to the upload form.',
+'uploaderror' => 'Yükləyiş xətası',
+'uploadlog' => 'yükleme kaydı',
+'filename' => 'Fayl adı',
+'fileuploadsummary' => 'İzahat:',
+'filestatus' => 'Müəllif statusu',
+'filesource' => 'Mənbə',
+'copyrightpage' => 'Project:Müəllif',
+'copyrightpagename' => '{{SITENAME}} müəllif',
+'uploadwarning' => 'Yükləyiş xəbərdarlıqı',
+'savefile' => 'Faylı qeyd et',
+
+# Image list
+#
+'imagelist' => 'Fayl siyahısı',
+'showlast' => 'Show last $1 files sorted $2.',
+'bydate' => 'tarixe görə',
+'byname' => 'ada görə',
+'bysize' => 'ölçüye görə',
+'imgdesc' => 'desc',
+'imglegend' => 'Legend: (desc) = show/edit file description.',
+'imghistory' => 'Faylın tarixçəsi',
+'deleteimg' => 'sil',
+'noimage-linktext' => 'faylı yüklə',
+
+# Mime search
+#
+'mimesearch' => 'MIME axtar',
+'mimetype' => 'MIME type:',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'İzlənməyən səhifələr',
+
+# Statistics
+#
+'statistics' => 'Statistika',
+'sitestats' => '{{SITENAME}} statistika',
+'sitestatstext' => '<p style="font-size:125%;margin-bottom:0">Wikipedia-da hal-hazırda məqalələrin sayı: \'\'\'$2\'\'\'</p>
+
+Verilənlər bazasında yekun \'\'\'$1\'\'\' səhifə var. Buna müzakirələr, istifadəçi səhifələri, köməklər, wikipedia lahiye səhifələri, xüsusi səhifələr, istiqamətləndirmə səhifələri, boş səhifələr ilə fayllar v əşablonlar daxildir.
+
+There have been a total of \'\'\'$3\'\'\' page views, and \'\'\'$4\'\'\' page edits
+since the wiki was setup.
+That comes to \'\'\'$5\'\'\' average edits per page, and \'\'\'$6\'\'\' views per edit.
+
+Hal-hazırda [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] sayı: \'\'\'$7\'\'\'.',
+'userstats' => 'İstifadəçi statistika',
+'userstatstext' => 'Hal-hazırda \'\'\'$1\'\'\' istifadəçi, \'\'\'2\'\'\' (və ya \'\'\'4%\'\'\') tanesi idarəçi. (baxınız $3).',
+
+
+'doubleredirects' => 'İkiqat istiqamətləndirmələr',
+'brokenredirects' => 'Xətalı istiqamətləndirmə',
+'brokenredirectstext' => 'The following redirects link to non-existent pages:',
+
+# Miscellaneous special pages
+#
+'lonelypages' => 'Yetim səhifələr',
+'uncategorizedcategories' => 'Kateqoriyasız kateqoriyalar',
+'uncategorizedpages' => 'Kateqoriyasız səhifələr',
+'unusedcategories' => 'İstifadə edilməmiş kateqoriyalar',
+'unusedimages' => 'İstifadə edilməmiş fayllar',
+'wantedcategories' => 'Təlabat olunan kateqoriyalar',
+'wantedpages' => 'Təlabat olunan səhifələr',
+'mostcategories' => 'Kateqoriyası ən çox olan məqalələr',
+'mostrevisions' => 'Ən çox nəzərdən keçirilmiş (versiyalı) məqalələr',
+'nlinks' => '$1 bağlantı',
+'allpages' => 'Bütün səhifələr',
+'randompage' => 'İxtiyari səhifə',
+'shortpages' => 'Qısa səhifələr',
+'longpages' => 'Uzun səhifələr',
+'listusers' => 'İstifadəçi siyahı',
+'specialpages' => 'Xüsusi səhifələr',
+'spheading' => 'İstifadəçilər üçün xüsusi səhifələr',
+'restrictedpheading' => 'İdarəçilər üçün xüsusi səhifələr',
+'recentchangeslinked' => 'Əlaqəli redaktələr',
+'newpages' => 'Yeni səhifələr',
+'ancientpages' => 'Ən köhnə səhifələr',
+'move' => 'Adını dəyişdir',
+'movethispage' => 'Bu səhifənin adını dəyiş',
+'booksources' => 'Kitab mənbələri',
+'categoriespagetext' => 'Wikide aşağıdaki kateqoriyalar var.',
+'version' => 'Versiya',
+'log' => 'Loglar',
+'alllogstext' => 'Qarşıya yükləmə, silmə, qoruma, bloklama ve sistem operatoru loqlarının birləşdirilmiş göstərməsi. Log növü, istifadəçi adı veya tə\'sir edilən səhifəni seçib görüntünü kiçildə bilərsiniz.',
+
+# Special:Allpages
+'nextpage' => 'Sonrakı səhifə ($1)',
+'allpagesfrom' => 'Bu mövqedən başlayan səhifeleri göstər:',
+'allarticles' => 'Bütün məqalələr',
+'allinnamespace' => 'Bütün səhifələr ($1 səhifələri)',
+'allpagesnext' => 'Sonrakı',
+'allpagesprev' => 'Əvvəlki',
+'allpagessubmit' => 'Gətir',
+
+# E this user
+#
+'emailuser' => 'İstifadəçiyə e-məktub yolla',
+'emailpage' => 'İstifadəçiyə e-məktub yolla',
+'defemailsubject' => '{{SITENAME}} e-məktub',
+'noemailtitle' => 'E-məktub ünvanı yox',
+'emailfrom' => 'Kimdən',
+'emailsubject' => 'Mövzu',
+'emailmessage' => 'Mesaj',
+'emailsend' => 'Göndər',
+'emailsent' => 'E-məktub göndərildi',
+
+# Watchlist
+#
+'watchlist' => 'İzlədiyim səhifələr',
+'watchnologin' => 'Daxil olmamısınız',
+'addedwatch' => 'İzləmə siyahısına əlavə edildi.',
+'addedwatchtext' => '"$1" səhifəsi [[Special:Watchlist|izlədiyiniz səhifələrə]] əlavə edildi. Bu səhifədə və əlaqəli müzakirə səhifəsində olacaq dəyişikliklər orada göstəriləcək və səhifə asanlıqla seçiləbilmək üçün [[Special:Recentchanges|son dəyişikliklər]]-də qalın şriftlərlə görsənəcəkdir. <p> Səhifəni izləmə sıyahınızdan çıxarmaq üçün yan lovhədəki "izləmə" düyməsinə vurun.',
+'removedwatch' => 'İzləmə siyahısından çıxardılıb',
+'removedwatchtext' => '"$1" səhifəsi izləmə siyahınızdan çıxardıldı.',
+'watch' => 'İzlə',
+'watchthispage' => 'Bu səhifəni izlə',
+'unwatch' => 'İzləmə',
+'unwatchthispage' => 'İzləmə',
+'watchnochange' => 'Verilən vaxt ərzində heç bir izlədiyiniz səhifə redaktə edilməmişdir.',
+'watchdetails' => '* müzakirə səhifələri çıxmaq şərtilə $1 səhifəni izləyirsiniz
+* [[Special:Watchlist/edit|İzlədiyiniz səhifələrin tam siyahısının göstərilməsi və redaktəsi]]',
+'wlheader-showupdated' => '* Son ziyarətinizdən sonra edilən dəyişikliklər \'\'\'qalın şriftlərlə\'\'\' göstərilmişdir.',
+'watchmethod-recent' => 'yeni dəyişikliklər izlənilən səhifələr üçün yoxlanılır',
+'watchmethod-list' => 'izlənilən səhifələr yeni dəyişikliklər üçün yoxlanılır',
+'removechecked' => 'İşarələnənləri izləmə siyahısından çıxart',
+'watchlistcontains' => 'İzləmə siyahınızda $1 səhifə var.',
+'watcheditlist' => 'Bunlar izlədiyiniz səhifələrin əlifba sırasına görə siyahısıdır. Siyahıdan çıxartmaq istədiyiniz səhifələrin yanındakı qutuları işarələləyin və ekranın altındakı \'işarələnənləri sıyahıdan çıxart düyməsinə\' vurun(məzmun səhifəsini çıxartdıqda əlaqəli müzakirə səhifəsi də (və tərsinə) çıxardılacaqdır).',
+'removingchecked' => 'İstədikləriniz izləmə siyahısından çıxardılır...',
+'wlnote' => 'Aşağıdakılar son <b>$2</b> saatdakı son $1 dəyişiklikdir.',
+'wlshowlast' => 'Bunları göstər: son $1 saatı $2 günü $3',
+'wlsaved' => 'Bu izləmə siyahınızın qeyd edilmiş halıdır.',
+'wlhideshowown' => 'Mənim redaktələrimi $1.',
+'wlhideshowbots' => 'Bot redaktələrini $1.',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Səhifəni sil',
+'confirm' => 'Təsdiq et',
+'exblank' => 'səhifə boş',
+'confirmdelete' => 'Silmeyi təsdiq et',
+'actioncomplete' => 'Fəaliyyət tamamlandı',
+'deletedtext' => '"$1" has been deleted. See $2 for a record of recent deletions.',
+'deletedarticle' => 'silindi "[[$1]]"',
+'rollback' => 'Əvvəlki versiya',
+'rollbacklink' => 'əvvəlki halına qaytar',
+
+'confirmprotect' => 'Qorumayı təsdiq et',
+
+# Undelete
+'undelete' => 'Silinmiş səhifələri göstər',
+'viewdeletedpage' => 'Silinmiş səhifələri göstər',
+
+
+# Namespace form on various pages
+'namespace' => 'Adlar fəzası:',
+'invert' => 'Seçilən xaricindəkiləri',
+
+# Contributions
+#
+'contributions' => 'İstifadəçi köməkləri',
+'mycontris' => 'Köməklərim',
+'contribsub' => 'For $1',
+'uctop' => '(son)',
+
+# What links here
+#
+'whatlinkshere' => 'Bu səhifəyə bağlantılar',
+'linklistsub' => '(Bağlantılar siyahı)',
+
+# Block/unblock IP
+#
+'blockip' => 'İstifadəçiyi blokla',
+'ipbreason' => 'Səbəb',
+'ipbsubmit' => 'Bu istifadəçiyi əngəllə',
+'badipaddress' => 'Yanlış IP',
+'blockipsuccesssub' => 'bloklandi',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1| $1]]bloklanıb. <br />See[[{{ns:Special}}:Ipblocklist|IP blok siyahisi]] bloklanmış IP lər.',
+'ipblocklist' => 'Əngəllənmiş istifadəçilər siyahı',
+'blocklink' => 'blokla',
+'contribslink' => 'Köməklər',
+'blocklogpage' => 'Blok qeydı',
+
+# Developer tools
+#
+
+# Make sysop
+'already_sysop' => 'Bu istifadəçi hazirdə idarəçidir',
+'already_bureaucrat' => 'Bu istifadəçi hazirdə bürokratdı',
+
+# Move page
+#
+'movepage' => 'Səhifənin adını dəyiş',
+'movearticle' => 'Səhifənin adını dəyişdir',
+'newtitle' => 'Yeni başlıq',
+'movepagebtn' => 'Səhifənin adını dəyiş',
+'movetalk' => 'Bu səhifənin müzakirə səhifəsinin de adını dəyişdir.',
+'1movedto2' => '[[$1]] adı dəyişildi. Yeni adı: [[$2]]',
+'1movedto2_redir' => '[[$1]] adı və məsiri dəyişildi : [[$2]]',
+'movereason' => 'Səbəb',
+'revertmove' => 'Əvvəlki vəziyyətinə',
+'delete_and_move' => 'Sil və apar',
+
+# Export
+'export' => 'Səhifələri ixrac et',
+
+# Namespace 8 related
+'allmessages' => 'Sistem mə\'lumatları',
+'allmessagesname' => 'Ad',
+'allmessagesdefault' => 'İlkin mətn',
+'allmessagescurrent' => 'İndiki mətn',
+'allmessagestext' => 'Sistem mə\'lumatların siyahısı MediaWiki: namespace.',
+
+
+# Metadata
+
+# Attribution
+'and' => 'və',
+
+# Spam protection
+'subcategorycount' => 'Bu kategoriyada $1 alt kategoriya var.',
+'categoryarticlecount' => 'Bu kategoriyada $1 məqalə var.',
+'listingcontinuesabbrev' => '(davam)',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/*
+<pre>
+*/
+
+/* qisa yol tuşlari və kömək balunları */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Öz Səhifəm\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'The user page for the ip you\'re editing as\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Danişiq Səhifəm\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Bu IP ünvanindan redaktə olunmuş danışıqlar\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Mənim Tərcihlərim\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'İzləməyə aldığım məqalələr.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Mən redakə etdiğim məqalələr siyahəsi\');
+ta[\'pt-login\'] = new Array(\'o\',\'Hesab açmaniz tövsiə olur, ama icbar yoxdu .\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Hesab açib girişiniz tövsiyə olur, ama məndatlı dəyil.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Çixiş\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Məqalə həqqində müzakirə edib, nəzərivi bildir\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Bu səhifani redaktə edə bilərsiz. Lütfən avvəl sinaq gostəriş edin.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Bu müzakirə səhifəsində iştirak edin.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Bu səhifə qorun altindadir. Mənbəsinə baxabilərsiz.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Bu səhifənin geçmiş nüsxələri.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Bu səhifəni qoru\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Bu səhifəni sil\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Bu səhifəni silinmədən oncəki halına qaytarın\');
+ta[\'ca-move\'] = new Array(\'m\',\'Bu məqalənin adını dəyışin\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Bu səhifəni izlə\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Bu səhifənin izlənmasini bitir\');
+ta[\'search\'] = new Array(\'f\',\'Bu vikini axtarin\');
+ta[\'p-logo\'] = new Array(\'\',\'Ana Səhifə\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Ana səhifəni görüş edin\');
+ta[\'n-portal\'] = new Array(\'\',\'Projə həqqində, nələr edəbilərsiz, harda şeyləri tapa bilərsiz\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Gündəki xəbərlər ilə əlaqəli bilgilər\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Bu Wikidə Son dəyişikliklər siyahəsi.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Bir təsadufi, necə gəldi, məqaləyə baxin\');
+ta[\'n-help\'] = new Array(\'\',\'Yardım almaq üçün.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Maddi kömək\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Wikidə bu məqaləyə bağlantilar\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Bu məqaləyə ayid başqa səhifələrdə yeni dəyişikliklər \');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS feed for this page\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom feed for this page\');
+ta[\'t-contributions\'] = new Array(\'\',\'Bu üzvin redaktə etmiş məqalələr siyahəsi\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Bu istifadəçiyə bir e-məktub yolla\');
+ta[\'t-upload\'] = new Array(\'u\',\'Yeni FILE lar Wikiyə yüklə.\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Xüsusi səhifələrin siyahəsi\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'View the content page\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'View the user page\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'View the media page\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'This is a special page, you can\'t edit the page itself.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'View the project page\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'View the image page\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'View the system message\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'View the template\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Kömək səhifəsi \');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'View the category page\');
+
+/*
+</pre>
+*/',
+# image deletion
+
+# browsing diffs
+'previousdiff' => '← Əvvəlki fərq',
+'nextdiff' => 'Sonrakı fərq →',
+
+'imagemaxsize' => 'Limit images on image description pages to:',
+'thumbsize' => 'Kiçik ölçü:',
+
+'newimages' => 'Yeni faylların siyahısı',
+
+
+# 'all' in various places, this might be different for inflected languages
+'imagelistall' => 'bütün',
+'watchlistall1' => 'hamısını',
+'watchlistall2' => 'hamısını',
+'namespacesall' => 'bütün',
+
+# E-mail address confirmation
+'confirmemail' => 'E-məktubunu təsdiq et',
+'confirmemail_send' => 'Təsdiq kodu göndər',
+'confirmemail_sent' => 'Təsdiq e-məktubu göndərildi.',
+'confirmemail_success' => 'E-məktub ünvanınız indi təsdiq edildi.',
+'confirmemail_loggedin' => 'E-məktubunuz indi təsdiq edildi.',
+'confirmemail_subject' => '{{SITENAME}} e-məktub təsdiq etme',
+
+# Inputbox extension, may be useful in other contexts as well
+'createarticle' => 'Məqalə yarat',
+
+);
+?>
diff --git a/languages/messages/MessagesBa.php b/languages/messages/MessagesBa.php
new file mode 100644
index 000000000000..4cc91fc4b8bd
--- /dev/null
+++ b/languages/messages/MessagesBa.php
@@ -0,0 +1,201 @@
+<?php
+/** Bashkir (Башҡорт)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'ru';
+
+
+$namespaceNames = array(
+ NS_MEDIA => 'Медиа',
+ NS_SPECIAL => 'Ярҙамсы',
+ NS_MAIN => '',
+ NS_TALK => 'Фекер_алышыу',
+ NS_USER => 'Ҡатнашыусы',
+ NS_USER_TALK => 'Ҡатнашыусы_м-н_фекер_алышыу',
+ #NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_б-са_фекер_алышыу',
+ NS_IMAGE => 'Рәсем',
+ NS_IMAGE_TALK => 'Рәсем_б-са_фекер_алышыу',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_б-са_фекер_алышыу',
+ NS_TEMPLATE => 'Ҡалып',
+ NS_TEMPLATE_TALK => 'Ҡалып_б-са_фекер_алышыу',
+ NS_HELP => 'Белешмә',
+ NS_HELP_TALK => 'Белешмә_б-са_фекер_алышыу',
+ NS_CATEGORY => 'Категория',
+ NS_CATEGORY_TALK => 'Категория_б-са_фекер_алышыу',
+);
+
+$linkTrail = '/^((?:[a-z]|а|б|в|г|д|е|ё|ж|з|и|й|к|л|м|н|о|п|р|с|т|у|ф|х|ц|ч|ш|щ|ъ|ы|ь|э|ю|я|ә|ө|ү|ғ|ҡ|ң|ҙ|ҫ|һ|“|»)+)(.*)$/sDu';
+
+$messages = array(
+
+# User preference toggles
+'about' => 'Тасуирлау',
+'aboutpage' => '{{ns:project}}:Тасуирлама',
+'aboutsite' => '{{grammar:genitive|{{SITENAME}}}}-ның тасуирламаһы',
+'actioncomplete' => 'Ғәмәл үтәлде',
+'addedwatch' => 'Күҙәтеү исемлегенә өҫтәлде',
+'allarticles' => 'Бөтә мәҡәләләр',
+'allinnamespace' => 'Бөтә биттәр (Исемдәре «$1» арауығында)',
+'allmessagesname' => 'Хәбәр',
+'allnotinnamespace' => 'Бөтә биттәр («$1» исемдәр арауығынан башҡа)',
+'allpages' => 'Бөтә биттәр',
+'allpagesfrom' => 'Ошондай хәрефтәрҙән башланған биттәрҙе күрһәтергә:',
+'allpagesnext' => 'Киләһе',
+'allpagesprev' => 'Алдағы',
+'allpagessubmit' => 'Үтәргә',
+'alphaindexline' => '$1 алып $2 тиклем',
+'ancientpages' => 'Иң иҫке мәҡәләләр',
+'and' => 'һәм',
+'article' => 'Мәҡәлә',
+'articlepage' => 'Мәҡәләне ҡарап сығырға',
+'badarticleerror' => 'Был биттә ундай ғәмәл үтәргә ярамай',
+'badquery' => 'Һорау дөрөҫ төҙөлмәгән',
+'badquerytext' => 'Һорауығыҙҙы үтәп булмай. Моғайын, Һеҙ өс хәрефтән ҡыҫҡараҡ һүҙ эҙләйһегеҙҙер, йәки һүҙегеҙҙә хата барҙыр. Һорауығыҙҙы яңынан төҙөп ҡарағыҙ әле.',
+'badtitle' => 'Ярамаған исем',
+'blanknamespace' => 'Мәҡәләләр',
+'blockip' => 'Ҡатнашыусыны ябыу',
+'cancel' => 'Бөтөрөргә',
+'changed' => 'үҙгәртелгән',
+'changes' => 'үҙгәрештәр',
+'contributions' => 'Ҡатнашыусы өлөшө',
+'copyright' => '<p> $1 ярашлы эстәлеге менән һәр кем файҙалана ала.',
+'createaccount' => 'Яңы ҡатнашыусыны теркәү',
+'createaccountmail' => 'эл. почта буйынса',
+'currentevents' => 'Ағымдағы ваҡиғалар',
+'currentevents-url' => 'Ағымдағы ваҡиғалар',
+'delete' => 'Юҡ итергә',
+'disclaimerpage' => 'Project:Яуаплылыҡтан баш тартыу',
+'disclaimers' => 'Яуаплылыҡтан баш тартыу',
+'edit' => 'Үҙгәртергә',
+'edithelp' => 'Мөхәрирләү белешмәһе',
+'editing' => 'Мөхәрирләү $1',
+'editinguser' => 'Мөхәрирләү $1',
+'editingcomment' => 'Мөхәрирләү $1 (комментарий)',
+'editingsection' => 'Мөхәрирләү $1 (секция)',
+'edittools' => '<charinsert>[[|]] {{}} Ә ә Ө ө Ү ү Ғ ғ Ҡ ҡ Ң ң Ҙ ҙ Ҫ ҫ Һ һ «» | </charinsert>',
+'editsection' => 'үҙгәртергә',
+'editthispage' => 'Был мәҡәләне үҙгәртергә',
+'emailfrom' => 'Кемдән',
+'emailmessage' => 'Хәбәр',
+'emailto' => 'Кемгә',
+'emailuser' => 'Ҡатнашыусыға хат',
+'enotif_newpagetext' => 'Был яңы бит.',
+'error' => 'Хата',
+'errorpagetitle' => 'Хата',
+'go' => 'Күсеү',
+'searcharticle' => 'Күсеү',
+'gotaccount' => 'Әгәр Һеҙ теркәлеү үткән булһағыҙ? $1.',
+'gotaccountlink' => 'Үҙегеҙ менән таныштырығыҙ',
+'group-all' => '(бөтә)',
+'help' => 'Белешмә',
+'hidetoc' => 'йәшерергә',
+'history' => 'Тарих',
+'history_short' => 'Тарих',
+'imagelist_user' => 'Ҡатнашыусы',
+'imagelistall' => 'бөтә',
+'info_short' => 'Мәғлүмәт',
+'jumpto' => 'Унда күсергә:',
+'jumptosearch' => 'эҙләү',
+'lastmodifiedat' => 'Был биттең һуңғы тапҡыр үҙгәртелеү ваҡыты: $2, $1 .',
+'listusers' => 'Ҡатнашыусылар исемлеге',
+'login' => 'Танышыу йәки теркәлеү',
+'loginpagetitle' => 'Танышыу йәки теркәлеү',
+'loginsuccess' => 'Хәҙер һеҙ $1 исеме менән эшләйһегеҙ.',
+'loginsuccesstitle' => 'Танышыу уңышлы үтте',
+'logout' => 'Тамамлау',
+'mailmypassword' => 'Яңы пароль ебәрергә',
+'mainpage' => 'Баш бит',
+'makesysopname' => 'Ҡатнашыусы исеме:',
+'mimesearch' => 'MIME буйынса эҙләү',
+'minoredit' => 'Әҙ генә үҙгәрештәр',
+'move' => 'Яңы исем биреү',
+'mycontris' => 'ҡылған эштәр',
+'mypage' => 'Шәхси бит',
+'mytalk' => 'Минең менән фекер алышыу',
+'namespace' => 'Исемдәр арауығы:',
+'namespacesall' => 'бөтә',
+'navigation' => 'Төп йүнәлештәр',
+'newpages-username' => 'Ҡатнашыусы:',
+'newwindow' => '(яңы биттә)',
+'nologin' => 'Һеҙ әле теркәлмәгәнме? $1.',
+'nologinlink' => 'Иҫәп яҙыуын булдырырға',
+'notanarticle' => 'Мәҡәлә түгел',
+'nstab-main' => 'Мәҡәлә',
+'nstab-mediawiki' => 'MediaWiki белдереүе',
+'nstab-special' => 'Ярҙамсы бит',
+'nstab-user' => 'Ҡатнашыусы',
+'otherlanguages' => 'Башҡа телдәрҙә',
+'permalink' => 'Даими һылтау',
+'portal' => 'Берләшмә',
+'portal-url' => '{{ns:project}}:Берләшмә ҡоро',
+'preferences' => 'Көйләүҙәр',
+'prefs-help-email' => '* Электрон почта (күрһәтмәһәң дә була) башҡа ҡатнашыусылар менән туры бәйләнешкә инергә мөмкинселек бирә.',
+'preview' => 'Ҡарап сығыу',
+'previewnote' => 'Ҡарап сығыу өлгөһө, әлегә үҙгәрештәр яҙҙырылмаған!',
+'printableversion' => 'Ҡағыҙға баҫыу өлгөһө',
+'privacy' => 'Сер һаҡлау сәйәсәте',
+'protect' => 'Һаҡларға',
+'qbfind' => 'Эҙләү',
+'qbmyoptions' => 'Көйләү',
+'qbspecialpages' => 'Махсус биттәр',
+'randompage' => 'Осраҡлы мәҡәлә',
+'recentchanges' => 'Һуңғы үҙгәртеүҙәр',
+'recentchangesall' => 'бөтә',
+'recentchangeslinked' => 'Бәйле үҙгәртеүҙәр',
+'recentchangestext' => '{{grammar:genitive|{{SITENAME}}}}. биттәрендә индерелгән һуңғы үҙгәртеүҙәр исемлеге',
+'remembermypassword' => 'Парольде хәтерҙә ҡалдырырға',
+'returnto' => '$1 битенә ҡайтыу.',
+'savearticle' => 'Яҙҙырып ҡуйырға',
+'search' => 'Эҙләү',
+'searchbutton' => 'Табыу',
+'showdiff' => 'Индерелгән үҙгәрештәр',
+'showpreview' => 'Ҡарап сығырға',
+'showtoc' => 'күрһәтергә',
+'sitesupport' => 'Ярҙам итеү',
+'sitesupport-url' => '{{ns:project}}:Эскерһеҙ ярҙам',
+'siteuser' => '{{grammar:genitive|{{SITENAME}}}} - ла ҡатнашыусы $1',
+'siteusers' => '{{grammar:genitive|{{SITENAME}}}} - ла ҡатнашыусы (-лар) $1',
+'specialloguserlabel' => 'Ҡатнашыусы:',
+'specialpage' => 'Ярҙамсы бит',
+'specialpages' => 'Махсус биттәр',
+'spheading' => 'Ярҙамсы биттәр',
+'summary' => 'Үҙгәртеүҙең ҡыҫҡаса тасуирламаһы',
+'talk' => 'Фекер алышыу',
+'talkpage' => 'Фекер алышыу',
+'toc' => 'Эстәлеге',
+'toolbox' => 'Ярҙамсы йүнәлештәр',
+'unwatch' => 'Күҙәтмәҫкә',
+'unwatchedpages' => 'Бер кем дә күҙәтмәгән биттәр',
+'userlogin' => 'Танышыу йәки теркәлеү',
+'userlogout' => 'Тамамлау',
+'userstatstext' => 'Бөтәһе \'\'\'$1\'\'\' ҡатнашыусы теркәлгән, шуларҙан \'\'\'$2\'\'\' ($4 %) хәким бурыстарын үтәй ([[{{ns:project}}:Хәкимдәр|Хәкимдәр]]).',
+'watch' => 'Күҙәтергә',
+'watchlist' => 'Күҙәтеү исемлеге',
+'watchlistall1' => 'бөтә',
+'watchlistall2' => 'бөтә',
+'watchnologin' => 'Үҙегеҙҙе танытырға кәрәк',
+'watchthis' => 'Был битте күҙәтеүҙәр исемлегенә индерергә',
+'whatlinkshere' => 'Бында һылтанмалар',
+'wrongpassword' => 'Һеҙ ҡулланған пароль ҡабул ителмәй. Яңынан яҙып ҡарағыҙ.',
+'yourdiff' => 'Айырмалыҡтар',
+'yourdomainname' => 'Һеҙҙең домен',
+'youremail' => 'Электрон почта *',
+'yourlanguage' => 'Тышҡы күренештә ҡулланылған тел:',
+'yourname' => 'Ҡатнашыусы исеме',
+'yournick' => 'Һеҙҙең уйҙырма исемегеҙ/ҡушаматығыҙ (имза өсөн):',
+'yourpassword' => 'Һеҙҙең пароль',
+'yourpasswordagain' => 'Парольде ҡабаттан яҙыу',
+'yourrealname' => 'Һеҙҙең ысын исемегеҙ (*)',
+'yourtext' => 'Һеҙҙең текст',
+'yourvariant' => 'Тел төрө',
+
+);
+
+
+
+?>
diff --git a/languages/messages/MessagesBar.php b/languages/messages/MessagesBar.php
new file mode 100644
index 000000000000..786e3164f933
--- /dev/null
+++ b/languages/messages/MessagesBar.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Bavarian (Boarisch)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'de';
+
+$messages = array(
+
+'mainpage' => 'Hauptsaitn',
+
+);
+
+?>
diff --git a/languages/messages/MessagesBat_smg.php b/languages/messages/MessagesBat_smg.php
new file mode 100644
index 000000000000..f072854fc18e
--- /dev/null
+++ b/languages/messages/MessagesBat_smg.php
@@ -0,0 +1,9 @@
+<?php
+/** Samogitian (Žemaitėška)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'lt';
+?>
diff --git a/languages/messages/MessagesBe.php b/languages/messages/MessagesBe.php
new file mode 100644
index 000000000000..b3a141b35adc
--- /dev/null
+++ b/languages/messages/MessagesBe.php
@@ -0,0 +1,838 @@
+<?php
+/** Belarusian (Беларуская мова)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Не паказваць', 'Замацаваная зьлева', 'Замацаваная справа', 'Рухомая зьлева'
+);
+
+$skinNames = array(
+ 'standard' => 'Клясычны',
+ 'nostalgia' => 'Настальгія',
+ 'cologneblue' => 'Кёльнскі смутак',
+ 'davinci' => 'Да Вінчы',
+ 'mono' => 'Мона',
+ 'monobook' => 'Монакніга',
+ 'myskin' => 'MySkin',
+ 'chick' => 'Цыпа'
+);
+
+$bookstoreList = array(
+ 'OZ.by' => 'http://oz.by/search.phtml?what=books&isbn=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+$datePreferences = array(
+ 'default',
+ 'dmy',
+ 'ISO 8601',
+);
+
+$defaultDateFormat = 'dmy';
+
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j xg Y',
+ 'dmy both' => 'H:i, j xg Y',
+);
+
+$magicWords = array(
+ 'redirect' => array( 0, '#перанакіраваньне', '#redirect' ),
+ 'notoc' => array( 0, '__NOTOC__', '__БЯЗЬ_ЗЬМЕСТУ__' ),
+ 'nogallery' => array( 0, '__NOGALLERY__', '__БЕЗ_ГАЛЕРЭІ__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__ЗЬМЕСТ_ПРЫМУСАМ__' ),
+ 'toc' => array( 0, '__TOC__', '__ЗЬМЕСТ__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__БЕЗ_РЭДАГАВАНЬНЯ_СЭКЦЫІ__' ),
+ 'start' => array( 0, '__START__', '__ПАЧАТАК__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'БЯГУЧЫ_МЕСЯЦ' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'НАЗВА_БЯГУЧАГА_МЕСЯЦА' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'НАЗВА_БЯГУЧАГА_МЕСЯЦА_Ў_РОДНЫМ_СКЛОНЕ' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'СКАРОЧАНАЯ_НАЗВА_БЯГУЧАГА_МЕСЯЦА' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'БЯГУЧЫ_ДЗЕНЬ' ),
+ 'currentday2' => array( 1, 'CURRENTDAY2', 'БЯГУЧЫ_ДЗЕНЬ_2' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'НАЗВА_БЯГУЧАГА_ДНЯ' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'БЯГУЧЫ_ГОД' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'БЯГУЧЫ_ЧАС' ),
+ 'numberofpages' => array( 1, 'NUMBEROFPAGES', 'КОЛЬКАСЬЦЬ_СТАРОНАК' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'КОЛЬКАСЬЦЬ_АРТЫКУЛАЎ' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'КОЛЬКАСЬЦЬ_ФАЙЛАЎ' ),
+ 'numberofusers' => array( 1, 'NUMBEROFUSERS', 'КОЛЬКАСЬЦЬ_УДЗЕЛЬНІКАЎ' ),
+ 'pagename' => array( 1, 'PAGENAME', 'НАЗВА_СТАРОНКІ' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'НАЗВА_СТАРОНКІ_2' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'ПРАСТОРА_НАЗВАЎ' ),
+ 'namespacee' => array( 1, 'NAMESPACEE', 'ПРАСТОРА_НАЗВАЎ_2' ),
+ 'talkspace' => array( 1, 'TALKSPACE', 'ПРАСТОРА_НАЗВАЎ_АБМЕРКАВАНЬНЯ' ),
+ 'talkspacee' => array( 1, 'TALKSPACEE', 'ПРАСТОРА_НАЗВАЎ_АБМЕРКАВАНЬНЯ_2' ),
+ 'subjectspace' => array( 1, 'SUBJECTSPACE', 'ARTICLESPACE', 'ПРАСТОРА_НАЗВАЎ_ПРАДМЕТУ', 'ПРАСТОРА_НАЗВАЎ_АРТЫКУЛА' ),
+ 'subjectspacee' => array( 1, 'SUBJECTSPACEE', 'ARTICLESPACEE', 'ПРАСТОРА_НАЗВАЎ_ПРАДМЕТУ_2', 'ПРАСТОРА_НАЗВАЎ_АРТЫКУЛА_2' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'ПОЎНАЯ_НАЗВА_СТАРОНКІ' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE', 'ПОЎНАЯ_НАЗВА_СТАРОНКІ_2' ),
+ 'subpagename' => array( 1, 'SUBPAGENAME', 'НАЗВА_ПАДСТАРОНКІ' ),
+ 'subpagenamee' => array( 1, 'SUBPAGENAMEE', 'НАЗВА_ПАДСТАРОНКІ_2' ),
+ 'basepagename' => array( 1, 'BASEPAGENAME', 'НАЗВА_БАЗАВАЙ_СТАРОНКІ' ),
+ 'basepagenamee' => array( 1, 'BASEPAGENAMEE', 'НАЗВА_БАЗАВАЙ_СТАРОНКІ_2' ),
+ 'talkpagename' => array( 1, 'TALKPAGENAME', 'НАЗВА_СТАРОНКІ_АБМЕРКАВАНЬНЯ' ),
+ 'talkpagenamee' => array( 1, 'TALKPAGENAMEE', 'НАЗВА_СТАРОНКІ_АБМЕРКАВАНЬНЯ_2' ),
+ 'subjectpagename' => array( 1, 'SUBJECTPAGENAME', 'ARTICLEPAGENAME', 'НАЗВА_СТАРОНКІ_ПРАДМЕТУ', 'НАЗВА_СТАРОНКІ_АРТЫКУЛА' ),
+ 'subjectpagenamee' => array( 1, 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE', 'НАЗВА_СТАРОНКІ_ПРАДМЕТУ_2', 'НАЗВА_СТАРОНКІ_АРТЫКУЛА_2' ),
+ 'msg' => array( 0, 'MSG:', 'ПАВЕДАМЛЕНЬНЕ:' ),
+ 'subst' => array( 0, 'SUBST:', 'ПАДСТАНОЎКА:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'ПАВЕДАМЛЕНЬНЕ_БЯЗЬ_ВІКІ:' ),
+ 'end' => array( 0, '__END__', '__КАНЕЦ__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'значак', 'міні' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'значак=$1', 'міні=$1' ),
+ 'img_right' => array( 1, 'right', 'справа' ),
+ 'img_left' => array( 1, 'left', 'зьлева' ),
+ 'img_none' => array( 1, 'none', 'няма' ),
+ 'img_width' => array( 1, '$1px', '$1пкс' ),
+ 'img_center' => array( 1, 'center', 'centre', 'цэнтар' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'рамка' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'НАЗВА_САЙТУ' ),
+ 'ns' => array( 0, 'NS:', 'ПН:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'ЛЯКАЛЬНЫ_АДРАС:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'ЛЯКАЛЬНЫ_АДРАС_2:' ),
+ 'server' => array( 0, 'SERVER', 'СЭРВЭР' ),
+ 'servername' => array( 0, 'SERVERNAME', 'НАЗВА_СЭРВЭРА' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'ШЛЯХ_ДА_СКРЫПТА' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'ГРАМАТЫКА:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', '__БЕЗ_КАНВЭРТАЦЫІ_НАЗВЫ__' ),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', '__БЕЗ_КАНВЭРТАЦЫІ_ТЭКСТУ__' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'БЯГУЧЫ_ТЫДЗЕНЬ' ),
+ 'currentdow' => array( 1, 'CURRENTDOW', 'БЯГУЧЫ_ДЗЕНЬ_ТЫДНЯ' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'ID_ВЭРСІІ' ),
+ 'plural' => array( 0, 'PLURAL:', 'МНОЖНЫ_ЛІК:'),
+ 'fullurl' => array( 0, 'FULLURL:', 'ПОЎНЫ_АДРАС:' ),
+ 'fullurle' => array( 0, 'FULLURLE:', 'ПОЎНЫ_АДРАС_2:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:', 'ПЕРШАЯ_ЛІТАРА_МАЛАЯ:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:', 'ПЕРШАЯ_ЛІТАРА_ВЯЛІКАЯ:' ),
+ 'lc' => array( 0, 'LC:', 'МАЛЫМІ_ЛІТАРАМІ:' ),
+ 'uc' => array( 0, 'UC:', 'ВЯЛІКІМІ_ЛІТАРАМІ:' ),
+ 'raw' => array( 0, 'RAW:', 'НЕАПРАЦАВАНЫ:' ),
+ 'displaytitle' => array( 1, 'DISPLAYTITLE', 'АДЛЮСТРАВАНАЯ_НАЗВА' ),
+ 'rawsuffix' => array( 1, 'R', 'Н' ),
+ 'newsectionlink' => array( 1, '__NEWSECTIONLINK__', '__СПАСЫЛКА_НА_НОВУЮ_СЭКЦЫЮ__' ),
+ 'currentversion' => array( 1, 'CURRENTVERSION', 'БЯГУЧАЯ_ВЭРСІЯ' ),
+ 'urlencode' => array( 0, 'URLENCODE:' ),
+ 'currenttimestamp' => array( 1, 'CURRENTTIMESTAMP', 'МОМАНТ_ЧАСУ' ),
+ 'directionmark' => array( 1, 'DIRECTIONMARK', 'DIRMARK', 'СЫМБАЛЬ_НАПРАМКУ_ПІСЬМА' ),
+ 'language' => array( 0, '#LANGUAGE:', '#МОВА:' ),
+ 'contentlanguage' => array( 1, 'CONTENTLANGUAGE', 'CONTENTLANG', 'МОВА_ЗЬМЕСТУ' ),
+ 'pagesinnamespace' => array( 1, 'PAGESINNAMESPACE:', 'PAGESINNS:', 'КОЛЬКАСЬЦЬ_СТАРОНАК_У_ПРАСТОРЫ_НАЗВАЎ:' ),
+ 'numberofadmins' => array( 1, 'NUMBEROFADMINS', 'КОЛЬКАСЬЦЬ_АДМІНІСТРАТАРАЎ' ),
+ 'formatnum' => array( 0, 'FORMATNUM', 'ФАРМАТАВАЦЬ_ЛІК' ),
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Мэдыя',
+ NS_SPECIAL => 'Спэцыяльныя',
+ NS_MAIN => '',
+ NS_TALK => 'Абмеркаваньне',
+ NS_USER => 'Удзельнік',
+ NS_USER_TALK => 'Гутаркі_ўдзельніка',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Абмеркаваньне_$1',
+ NS_IMAGE => 'Выява',
+ NS_IMAGE_TALK => 'Абмеркаваньне_выявы',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Абмеркаваньне_MediaWiki',
+ NS_TEMPLATE => 'Шаблён',
+ NS_TEMPLATE_TALK => 'Абмеркаваньне_шаблёну',
+ NS_HELP => 'Дапамога',
+ NS_HELP_TALK => 'Абмеркаваньне_дапамогі',
+ NS_CATEGORY => 'Катэгорыя',
+ NS_CATEGORY_TALK => 'Абмеркаваньне_катэгорыі'
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+$linkTrail = '/^([абвгґджзеёжзійклмнопрстуўфхцчшыьэюяćčłńśšŭźža-z]+)(.*)$/sDu';
+
+$messages = array(
+# Belarusian Cyrillic alphabet:
+# Аа Бб Вв Гг Дд (ДЖдж ДЗдз) Ее Ёё Жж Зз Іі Йй Кк Лл Мм Нн Оо Пп Рр Сс Тт Уу Ўў Фф Хх Цц Чч Шш Ыы Ьь Ээ Юю Яя
+# Short ([^a-z]): абвгд (ДЖдж ДЗдз) еёжзійклмнопрстуўфхцчшыьэюя
+#
+# Belarusian Latin alphabet:
+# Aa Bb Cc Ćć Čč Dd (DŽdž DZdz) Ee Ff Gg Hh Ii Jj Kk Ll Łł Mm Be Ńń Oo Pp Rr Ss Śś Šš Tt Uu Ŭŭ Vv Yy Zz Źź Žž
+# Short ([^a-z]): ćč (DŽdž) łńśšŭźž
+
+# Note: use /u (unicode) and /i to turn of case-sensativity.
+
+'1movedto2' => '[[$1]] перанесеная ў [[$2]]',
+'1movedto2_redir' => '[[$1]] перанесеная ў [[$2]] з выдаленьнем перанакіраваньня',
+'about' => 'Пра',
+'aboutpage' => '{{ns:project}}:Пра {{GRAMMAR:вінавальны|{{SITENAME}}}}',
+'aboutsite' => 'Пра {{GRAMMAR:вінавальны|{{SITENAME}}}}',
+'accmailtext' => 'Пароль для «$1» быў адасланы на адрас $2.',
+'accmailtitle' => 'Пароль адасланы.',
+'accountcreated' => 'Рахунак створаны',
+'accountcreatedtext' => 'Рахунак удзельніка для $1 быў створаны.',
+'acct_creation_throttle_hit' => 'На жаль, Вы ўжо стварылі $1 рахункаў. Болей нельга.',
+'actioncomplete' => 'Дзеяньне завершанае',
+'addedwatch' => 'Дададзеная ў сьпіс назіраньня',
+'addedwatchtext' => "Артыкул «$1» быў дададзены да Вашага [[Special:Watchlist|сьпісу назіраньня]].
+Наступныя зьмены ў гэтым артыкуле і зьвязанай зь ім старонцы абмеркаваньняў будуць бачныя там, і старонка будзе выглядаць '''тлустай''' на [[Special:Recentchanges|старонцы са сьпісам апошніх зьменаў]], каб зьмены было лягчэй заўважыць.
+
+Калі Вы захочаце выдаліць артыкул са сьпісу назіраньня, націсьніце «не назіраць» у спэцыяльным радку зьверху артыкула.",
+'allarticles' => 'Усе артыкулы',
+'allinnamespace' => 'Усе старонкі (прастора назваў: $1)',
+'alllogstext' => 'Сумесны паказ журналаў загрузкі, выдаленьня, абароны, блякаваньня і адміністраваньня.
+Вы можаце адфільтраваць вынікі па тыпе журналу, удзельніку ці старонцы.',
+'allmessages' => 'Сыстэмныя паведамленьні',
+'allmessagescurrent' => 'Бягучы тэкст',
+'allmessagesdefault' => 'Тэкст па змоўчаньні',
+'allmessagesfilter' => 'Фільтар рэгулярных выразаў:',
+'allmessagesmodified' => 'Паказаць толькі зьмененыя',
+'allmessagesname' => 'Назва',
+'allmessagesnotsupportedDB' => "'''Special:AllMessages''' не падтрымліваецца, таму што адключанае '''\$wgUseDatabaseMessages'''.",
+'allmessagesnotsupportedUI' => 'Ваша цяперашняя мова <b>$1</b> інтэрфэйсу не падтрымліваецца Special:AllMessages гэтага сайту.',
+'allmessagestext' => 'Сьпіс усіх сыстэмных паведамленьняў, якія існуюць у прасторы назваў MediaWiki.',
+'allnotinnamespace' => 'Усе старонкі (не ў прасторы назваў $1)',
+'allowemail' => 'Дазволіць атрыманьне лістоў ад іншых удзельнікаў і ўдзельніц',
+'allpages' => 'Усе старонкі',
+'allpagesfrom' => 'Паказаць старонкі, пачынаючы з:',
+'allpagesnext' => 'Наступныя',
+'allpagesprefix' => 'Паказаць старонкі, назвы якіх пачынаюцца з:',
+'allpagesprev' => 'Папярэднія',
+'allpagessubmit' => 'Паказаць',
+'alphaindexline' => 'ад $1 да $2',
+'already_bureaucrat' => 'Гэты ўдзельнік ужо зьяўляецца бюракратам',
+'already_sysop' => 'Гэты ўдзельнік ужо зьяўляецца адміністратарам',
+'alreadyloggedin' => "<strong>Удзельнік $1, Вы ўжо ўвайшлі!</strong><br />",
+'alreadyrolled' => 'Немагчыма скасаваць апошнюю зьмену [[:$1]], якую зрабіў [[User:$2|$2]] ([[User talk:$2|гутаркі]]); нехта іншы ўжо зьмяніў артыкул ці скасаваў зьмены.
+
+Апошнія зьмены зробленыя [[User:$3|$3]] ([[User talk:$3|гутаркі]]).',
+'ancientpages' => 'Найстарэйшыя старонкі',
+'and' => 'і',
+'anoneditwarning' => "'''Папярэджаньне:''' Вы не ўвайшлі. Ваш IP-адрас будзе запісаны ў гісторыі гэтай старонкі.",
+'anononlyblock' => 'толькі ананімаў',
+'anontalk' => 'Гутаркі для гэтага IP-адраса',
+'anontalkpagetext' => "----''Гэта старонка гутарак ананімнага ўдзельніка, які яшчэ не стварыў сабе рахунак ці не ўжывае яго. Таму мы вымушаныя ўжываць лічбавы IP-адрас дзеля ягонай ідэнтыфікацыі. Адзін IP-адрас можа выкарыстоўвацца некалькімі ўдзельнікамі. Калі Вы — ананімны ўдзельнік і лічыце, што атрымалі не прызначаныя Вам камэнтары, калі ласка, [[Special:Userlogin|зарэгіструйцеся ці ўвайдзіце ў сыстэму]], каб у будучыні пазьбегнуць магчымай блытаніны зь іншымі ананімнымі ўдзельнікамі.''
+
+''This is the discussion page for an anonymous user who has not created an account yet or who does not use it. We therefore have to use the numerical IP address to identify him/her. Such an IP address can be shared by several users. If you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:Userlogin|create an account or log in]] to avoid future confusion with other anonymous users.''",
+'anonymous' => 'Ананімныя ўдзельнікі і ўдзельніцы {{GRAMMAR:родны|{{SITENAME}}}}',
+'apr' => '04',
+'april' => 'красавіка',
+'april-gen' => 'красавіка',
+'article' => 'Артыкул',
+'articleexists' => 'Старонка з такой назвай ужо існуе, альбо абраная Вамі назва недапушчальная.
+Калі ласка, абярыце іншую назву.',
+'articlepage' => 'Паказаць артыкул',
+'articletitles' => "Артыкулы, якія пачынаюцца з ''$1''",
+'aug' => '08',
+'august' => 'жніўня',
+'august-gen' => 'жніўня',
+'autoblocker' => "Вы аўтаматычна заблякаваныя, таму што Ваш IP-адрас нядаўна ўжываўся «[[User:$1|$1]]». Прычына блякаваньня $1 наступная: «'''$2'''»",
+'autoredircomment' => 'Перанакіроўвае на [[$1]]',
+'badaccess' => 'Памылка: не адпаведны ўзровень правоў',
+'badaccess-group0' => 'Вам не дазволена выканаць запытанае Вамі дзеяньне.',
+'badaccess-group1' => 'Запытанае Вамі дзеяньне дазволенае толькі ўдзельнікам з групы $1.',
+'badaccess-group2' => 'Запытанае Вамі дзеяньне дазволенае толькі ўдзельнікам адной з групаў $1.',
+'badaccess-groups' => 'Запытанае Вамі дзеяньне дазволенае толькі ўдзельнікам адной з групаў $1.',
+'badarticleerror' => 'Гэтае дзеяньне немагчыма выканаць на гэтай старонцы.',
+'badquerytext' => 'Мы не змаглі апрацаваць Ваш запыт. Магчыма, прычына гэтага ў тым, што Вы паспрабавалі шукаць слова, карацейшае за тры літары, што пакуль не падтрымліваецца. Магчыма таксама, што Вы зрабілі памылку ў выразе, напрыклад, «рыба і і луска». Калі ласка, паспрабуйце іншы запыт.',
+'badfilename' => 'Назва файла была зьмененая на «$1».',
+'badfiletype' => '«.$1» не зьяўляецца рэкамэндаваным фарматам для файлаў выяваў.',
+'badipaddress' => 'Некарэктны IP-адрас',
+'badquery' => 'Няслушна сфармаваны пошукавы запыт',
+'badretype' => 'Уведзеныя Вамі паролі не супадаюць.',
+'badsig' => 'Няслушны неапрацаваны подпіс; праверце HTML-тэгі.',
+'badtitle' => 'Некарэктная назва',
+'badtitletext' => 'Запытаная назва старонкі няслушная ці пустая, альбо няслушна ўказаная міжмоўная ці міжвікі назва. Яна можа ўтрымліваць сымбалі, якія нельга ўжываць у назвах.',
+'blanknamespace' => 'Артыкул',
+'blockededitsource' => "Тэкст '''Вашых зьменаў''' у '''$1''' паказаны ніжэй:",
+'blockedoriginalsource' => "Крыніца '''$1''' паказана ніжэй:",
+'blockedtext' => "<big>'''Вашае імя ўдзельніка ці IP-адрас быў заблякаваны $1.'''</big>
+
+Прычына гэтага: ''$2''.
+
+Вы можаце скантактавацца з $1 ці адным зь іншых [[{{ns:project}}:Адміністрацыя|адміністратараў]], каб абмеркаваць блякаваньне. Заўважце, што Вы ня зможаце ўжыць мажлівасьць «даслаць ліст па электроннай пошце гэтаму ўдзельніку/гэтай удзельніцы», пакуль не пазначыце сапраўдны адрас электроннай пошты ў Вашых [[Special:Preferences|устаноўках]]. Ваш IP-адрас – $3. Калі ласка, улучайце гэты адрас ва ўсе запыты, што Вы будзеце рабіць.",
+'blockedtitle' => 'Удзельнік заблякаваны',
+'blockip' => 'Блякаваньне ўдзельніка ці ўдзельніцы',
+'blockipsuccesssub' => 'Блякаваньне пасьпяховае',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] быў заблякаваны/была заблякаваная.
+<br />Глядзіце [[Special:Ipblocklist|сьпіс заблякаваных IP-адрасоў]] дзеля перагляду блякаваньняў.',
+'blockiptext' => 'Ужывайце форму ніжэй, каб заблякаваць доступ для запісу з пэўнага IP-адрасу ці імя ўдзельніка. Гэта трэба рабіць толькі прадухіленьня вандалізму і згодна з [[{{ns:project}}:Правілы|правіламі]]. Запоўніце ніжэй пэўную прычыну (напрыклад, пералічыце асобныя старонкі, на якіх былі парушэньні).',
+'blocklink' => 'заблякаваць',
+'blocklistline' => '$1, $2 заблякаваў $3 ($4)',
+'blocklogentry' => 'заблякаваны «[[$1]]» на тэрмін: $2',
+'blocklogpage' => 'Журнал блякаваньняў',
+'blocklogtext' => 'Гэта журнал уліку блякаваньняў і разблякаваньняў удзельнікаў. Аўтаматычна заблякаваныя IP-адрасы не пазначаныя. Глядзіце [[Special:Ipblocklist|сьпіс заблякаваных IP-адрасоў]], каб пабачыць дзейныя ў гэты момант блякаваньні.',
+'booksources' => 'Кнігарні',
+'boteditletter' => 'р',
+'brokenredirects' => 'Некарэктныя перанакіраваньні',
+'brokenredirectstext' => 'Наступныя перанакіраваньні спасылаюцца на неіснуючыя старонкі:',
+'bydate' => 'па даце',
+'byname' => 'па назьве',
+'bysize' => 'па памеры',
+'cachederror' => 'Наступнае — кэшаваная копія запытанай старонкі; магчыма, яна ўжо не адпавядае рэчаіснасьці.',
+'cancel' => 'Адмяніць',
+'cannotdelete' => 'Немагчыма выдаліць указаную старонку альбо выяву. (Магчыма, яна ўжо выдаленая кімсьці іншым.)',
+'cantcreateaccounttitle' => 'Немагчыма стварыць рахунак',
+'cantrollback' => 'Немагчыма скасаваць зьмену; апошні рэдактар — адзіны аўтар гэтай старонкі.',
+'categories' => 'Катэгорыі',
+'categoriespagetext' => 'У {{GRAMMAR:месны|{{SITENAME}}}} існуюць наступныя катэгорыі:',
+'category_header' => 'Артыкулы ў катэгорыі «$1»',
+'categoryarticlecount' => 'У гэтай катэгорыі ёсьць $1 {{PLURAL:$1|артыкул|артыкулы|артыкулаў}}.',
+'changepassword' => 'Зьмяніць пароль',
+'changes' => 'зьмены',
+'clearwatchlist' => 'Ачысьціць сьпіс назіраньня',
+'columns' => 'Слупкоў:',
+'compareselectedversions' => 'Параўнаць выбраныя вэрсіі',
+'confirm' => 'Пацьверджаньне',
+'confirmdelete' => 'Пацьверджаньне выдаленьня',
+'confirmemail' => 'Пацьвердзіць адрас электроннай пошты',
+'confirmprotect' => 'Пацьверджаньне абароны',
+'confirmprotecttext' => 'Вы сапраўды жадаеце абараніць гэтую старонку?',
+'confirmunprotecttext' => 'Вы сапраўды жадаеце зьняць абарону з гэтай старонкі?',
+'contribslink' => 'унёсак',
+'contribsub' => 'Для $1',
+'contributions' => 'Унёсак удзельніка/удзельніцы',
+'copyright' => 'Зьмест старонкі падпадае пад ліцэнзію $1.',
+'copyrightpage' => '{{ns:project}}:Аўтарскія правы',
+'copyrightpagename' => 'Аўтарскія правы {{GRAMMAR:родны|{{SITENAME}}}}',
+'copyrightwarning' => '<strong>НЕЛЬГА БЕЗ [[{{ns:project}}:Дазволы на выкарыстаньне матэрыялаў|ДАЗВОЛУ]] ДАДАВАЦЬ МАТЭРЫЯЛЫ, АБАРОНЕНЫЯ АЎТАРСКІМ ПРАВАМ!</strong>',
+'couldntremove' => 'Немагчыма выдаліць «$1»...',
+'createaccount' => 'Стварыць новы рахунак',
+'createaccountmail' => 'па электроннай пошце',
+'creditspage' => 'Падзякі',
+'cur' => 'бяг',
+'currentevents' => 'Бягучыя падзеі',
+'currentevents-url' => 'Бягучыя падзеі',
+'currentrev' => 'Бягучая вэрсія',
+'currentrevisionlink' => 'Бягучая вэрсія',
+'data' => 'Зьвесткі',
+'databaseerror' => 'Памылка базы зьвестак',
+'dateformat' => 'Фармат даты',
+'datetime' => 'Дата і час',
+'deadendpages' => 'Тупіковыя старонкі',
+'dec' => '12',
+'december' => 'сьнежня',
+'december-gen' => 'сьнежня',
+'default' => 'па змоўчаньні',
+'defaultns' => 'Па змоўчаньні, шукаць у наступных прасторах назваў:',
+'delete' => 'Выдаліць',
+'delete_and_move' => 'Выдаліць і перанесьці',
+'delete_and_move_confirm' => 'Так, выдаліць старонку',
+'deletecomment' => 'Прычына выдаленьня',
+'deletedarticle' => 'выдаленая «[[$1]]»',
+'deletedrev' => '[выдаленая]',
+'deletedrevision' => 'Выдаленая старая вэрсія $1.',
+'deleteimg' => 'выдаліць',
+'deleteimgcompletely' => 'Выдаліць усе вэрсіі гэтага файла',
+'deletepage' => 'Выдаліць старонку',
+'deletesub' => '(Выдаленьне «$1»)',
+'deletethispage' => 'Выдаліць гэтую старонку',
+'deletionlog' => 'журнал выдаленьняў',
+'dellogpage' => 'Журнал выдаленьняў',
+'dellogpagetext' => 'Сьпіс апошніх выдаленьняў.',
+'diff' => 'розьн',
+'difference' => '(Адрозьненьні паміж вэрсіямі)',
+'disambiguations' => 'Старонкі-неадназначнасьці',
+'disambiguationspage' => 'Шаблён:Неадназначнасьць',
+'disclaimerpage' => '{{ns:project}}:Адмова ад адказнасьці',
+'disclaimers' => 'Адмова ад адказнасьці',
+'doubleredirects' => 'Двайныя перанакіраваньні',
+'edit' => 'Рэдагаваць',
+'editconflict' => 'Канфлікт рэдагаваньня: $1',
+'editcurrent' => 'Рэдагаваць бягучую вэрсію гэтай старонкі',
+'edithelp' => 'Дапамога ў рэдагаваньні',
+'edithelppage' => 'Help:Рэдагаваньне',
+'editing' => 'Рэдагаваньне: $1',
+'editingcomment' => 'Рэдагаваньне: $1 (камэнтар)',
+'editingsection' => 'Рэдагаваньне: $1 (сэкцыя)',
+'editsection' => 'рэдагаваць',
+'editold' => 'рэдагаваць',
+'editsectionhint' => 'Рэдагаваць сэкцыю «$1»',
+'editthispage' => 'Рэдагаваць гэтую старонку',
+'editusergroup' => 'Рэдагаваць групы ўдзельнікаў і ўдзельніц',
+'email' => 'Электронная пошта',
+'emailfrom' => 'Ад',
+'emailmessage' => 'Паведамленьне',
+'emailpage' => 'Даслаць ліст ўдзельніку ці ўдзельніцы па электроннай пошце',
+'emailsend' => 'Даслаць',
+'emailsubject' => 'Тэма',
+'emailto' => 'Каму',
+'emailuser' => 'Даслаць ліст па электроннай пошце гэтаму ўдзельніку/гэтай удзельніцы',
+'enotif_newpagetext' => 'Гэта новая старонка.',
+'error' => 'Памылка',
+'errorpagetitle' => 'Памылка',
+'exblank' => 'старонка была пустая',
+'excontent' => 'колішні зьмест: «$1»',
+'exif-exifversion' => 'Вэрсія Exif',
+'exif-flash' => 'Успышка',
+'exif-gpslatitude' => 'Шырата',
+'exif-gpslongitude' => 'Даўгата',
+'exif-imagedescription' => 'Назва выявы',
+'exif-imagelength' => 'Вышыня',
+'exif-imagewidth' => 'Шырыня',
+'exif-lightsource' => 'Крыніца сьвятла',
+'exif-lightsource-0' => 'Невядомая',
+'exif-lightsource-4' => 'Успышка',
+'exif-make' => 'Вытворца фотаапарата',
+'exif-model' => 'Мадэль фотаапарата',
+'export' => 'Экспартаваць старонкі',
+'exportcuronly' => 'Экспартаваць толькі бягучую вэрсію, бяз поўнай гісторыі',
+'extlink_tip' => 'Зьнешняя спасылка (не забывайцеся пачынаць з http:// )',
+'feb' => '02',
+'february' => 'лютага',
+'february-gen' => 'лютага',
+'filecopyerror' => 'Немагчыма cкапіяваць файл «$1» у «$2».',
+'filedeleteerror' => 'Немагчыма выдаліць файл «$1».',
+'filedesc' => 'Апісаньне',
+'filename' => 'Назва файла',
+'filenotfound' => 'Немагчыма знайсьці файл «$1».',
+'filerenameerror' => 'Немагчыма перайменаваць файл «$1» у «$2».',
+'files' => 'Файлы',
+'filesource' => 'Крыніца',
+'fileuploadsummary' => 'Апісаньне:',
+'friday' => 'пятніца',
+'getimagelist' => 'атрыманьне сьпісу файлаў',
+'go' => 'Старонка',
+'gotaccount' => 'Ужо маеце рахунак? $1.',
+'gotaccountlink' => 'Увайдзіце',
+'group' => 'Група:',
+'group-all' => '(усе)',
+'group-bot' => 'Робаты',
+'group-bot-member' => 'Робат',
+'group-sysop' => 'Адміністрацыя',
+'group-sysop-member' => 'Адміністратар/Адміністратарка',
+'grouppage-bot' => '{{ns:project}}:Робаты',
+'grouppage-sysop' => '{{ns:project}}:Адміністрацыя',
+'help' => 'Дапамога',
+'helppage' => 'Help:Зьмест',
+'hide' => 'схаваць',
+'hidetoc' => 'схаваць',
+'hist' => 'гіст',
+'history' => 'Гісторыя старонкі',
+'history_short' => 'Гісторыя',
+'historywarning' => 'Папярэджаньне: у старонкі, якую Вы зьбіраецеся выдаліць, ёсьць гісторыя:&nbsp;',
+'hr_tip' => 'Гарызантальная лінія (не выкарыстоўвайце часта)',
+'ignorewarning' => 'Праігнараваць папярэджаньне і захаваць файл.',
+'illegalfilename' => 'Назва файла «$1» зьмяшчае сымбалі, якія нельга выкарыстоўваць у назвах старонак. Калі ласка, зьмяніце назву файла і паспрабуйце загрузіць яго зноў.',
+'ilsubmit' => 'Шукаць',
+'image_sample' => 'Прыклад.jpg',
+'imagelinks' => 'Спасылкі',
+'imagelist' => 'Сьпіс файлаў',
+'imagelist_date' => 'Дата',
+'imagelist_description' => 'Апісаньне',
+'imagelist_name' => 'Назва',
+'imagelist_size' => 'Памер',
+'imagelist_user' => 'Удзельнік',
+'imagelisttext' => 'Сьпіс <strong>$1</strong> файлаў, адсартаваных <strong>$2</strong>.',
+'imagepage' => 'Паказаць старонку выявы',
+'imgdelete' => 'выдаліць',
+'imgdesc' => 'апісаньне',
+'imgfile' => 'файл',
+'imghistory' => 'Гісторыя файла',
+'import' => 'Імпартаваць старонкі',
+'importfailed' => 'Немагчыма імпартаваць: $1',
+'infiniteblock' => 'назаўсёды',
+'info_short' => 'Інфармацыя',
+'infosubtitle' => 'Інфармацыя пра старонку',
+'internalerror' => 'Унутраная памылка',
+'invert' => 'Адваротны выбар',
+'ip_range_invalid' => 'Некарэктны дыяпазон IP-адрасоў.',
+'ipaddress' => 'IP-адрас',
+'ipadressorusername' => 'IP-адрас альбо імя ўдзельніка/ўдзельніцы',
+'ipbanononly' => 'Блякаваць толькі ананімаў',
+'ipbcreateaccount' => 'Забараніць стварэньне рахункаў',
+'ipbexpiry' => 'Тэрмін',
+'ipblocklist' => 'Сьпіс заблякаваных IP-адрасоў і імёнаў удзельнікаў',
+'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',
+'ipbother' => 'Іншы тэрмін',
+'ipbotheroption' => 'іншы',
+'ipbreason' => 'Прычына',
+'isredirect' => 'старонка-перанакіраваньне',
+'istemplate' => 'уключэньне',
+'jan' => '01',
+'january' => 'студзеня',
+'january-gen' => 'студзеня',
+'jul' => '07',
+'july' => 'ліпеня',
+'july-gen' => 'ліпеня',
+'jun' => '06',
+'june' => 'чэрвеня',
+'june-gen' => 'чэрвеня',
+'lastmodifiedat' => 'Гэтая старонка апошні раз рэдагавалася $2, $1.',
+'lastmodifiedatby' => 'Гэтую старонку апошні раз рэдагаваў $3 $2, $1.',
+'license' => 'Ліцэнзія',
+'lineno' => 'Радок $1:',
+'link_tip' => 'Унутраная спасылка',
+'linklistsub' => '(Сьпіс спасылак)',
+'linkshere' => 'Наступныя старонкі спасылаюцца на \'\'\'[[:$1]]\'\'\':',
+'linkstoimage' => 'Наступныя старонкі спасылаюцца на гэты файл:',
+'listingcontinuesabbrev' => " (працяг)",
+'listredirects' => 'Сьпіс перанакіраваньняў',
+'listusers' => 'Сьпіс удзельнікаў і ўдзельніц',
+'loadhist' => 'Загрузка гісторыі старонкі',
+'loadingrev' => 'Загрузка вэрсіі для параўнаньня',
+'localtime' => 'Мясцовы час',
+'log' => 'Журналы падзей',
+'login' => 'Увайсьці',
+'loginlanguagelabel' => 'Мова: $1',
+'logout' => 'Выйсьці',
+'lonelypages' => 'Старонкі-сіраціны',
+'longpages' => 'Доўгія старонкі',
+'mailmypassword' => 'Даслаць мне пароль',
+'mainpage' => 'Галоўная старонка',
+'makesysopname' => 'Імя ўдзельніка/ўдзельніцы:',
+'mar' => '03',
+'march' => 'сакавіка',
+'march-gen' => 'сакавіка',
+'math_sample' => 'Зьмясьціце тут формулу',
+'math_syntax_error' => 'сынтаксычная памылка',
+'math_tip' => 'Матэматычная формула (LaTeX)',
+'math_unknown_error' => 'невядомая памылка',
+'math_unknown_function' => 'невядомая функцыя',
+'may' => '05',
+'may-gen' => 'траўня',
+'may_long' => 'траўня',
+'media_sample' => 'Прыклад.ogg',
+'media_tip' => 'Спасылка на мэдыя-файл',
+'mimesearch' => 'Пошук па MIME',
+'mimetype' => 'Тып MIME:',
+'minlength' => 'Назва файла павінна быць не карацейшай за тры сымбалі.',
+'minoredit' => 'Гэта дробная праўка',
+'minoreditletter' => 'д',
+'missingimage' => '<b>Выява адсутнічае</b><br /><i>$1</i>',
+'monday' => 'панядзелак',
+'mostcategories' => 'Старонкі з найбольшай колькасьцю катэгорый',
+'mostimages' => 'Выявы, на якія найчасьцей спасылаюцца',
+'mostlinked' => 'Старонкі, на якія найчасьцей спасылаюцца',
+'mostlinkedcategories' => 'Катэгорыі з найбольшай колькасьцю артыкулаў',
+'mostrevisions' => 'Старонкі з найбольшай колькасьцю рэдагаваньняў',
+'move' => 'Перанесьці',
+'movearticle' => 'Перанесьці старонку',
+'movedto' => 'перанесеная ў',
+'movepage' => 'Перанесьці старонку',
+'movepagebtn' => 'Перанесьці старонку',
+'movereason' => 'Прычына',
+'movetalk' => 'Перанесьці таксама старонку абмеркаваньня.',
+'movethispage' => 'Перанесьці гэтую старонку',
+'mw_math_html' => 'HTML калі магчыма, інакш PNG',
+'mw_math_mathml' => 'MathML калі магчыма (экспэрымэнтальна)',
+'mw_math_png' => 'Заўсёды паказваць як PNG',
+'mw_math_simple' => 'HTML у простых выпадках, інакш PNG',
+'mycontris' => 'Мой унёсак',
+'mypage' => 'Мая старонка',
+'mypreferences' => 'Мае ўстаноўкі',
+'mytalk' => 'Мае размовы',
+'namespace' => 'Прастора назваў:',
+'namespacesall' => 'усе',
+'navigation' => 'Навігацыя',
+'nbytes' => '$1 {{PLURAL:$1|байт|байта|байтаў}}',
+'ncategories' => '$1 {{PLURAL:$1|катэгорыя|катэгорыі|катэгорый}}',
+'newarticle' => '(Новы)',
+'newarticletext' =>
+"Вы прыйшлі па спасылцы на старонку, якая яшчэ не існуе.
+Каб стварыць яе, напішыце тэкст у полі ніжэй (глядзіце [[Help:Зьмест|старонку дапамогі]] дзеля дадатковай інфармацыі).
+Калі Вы трапілі сюды памылкова, націсьніце '''назад''' у вашым браўзэры",
+'newbies' => 'Пачынаючыя ўдзельнікі і ўдзельніцы',
+'newimages' => 'Галерэя новых файлаў',
+'newmessagesdifflink' => 'розьніца з папярэдняй вэрсіяй',
+'newmessageslink' => 'новыя паведамленьні',
+'newpage' => 'Новая старонка',
+'newpageletter' => 'Н',
+'newpages' => 'Новыя старонкі',
+'newpages-username' => 'Імя ўдзельніка/ўдзельніцы:',
+'newpassword' => 'Новы пароль:',
+'newtitle' => 'Новая назва',
+'newwindow' => '(адчыняецца ў новым акне)',
+'nextdiff' => 'Перайсьці да наступнай зьмены →',
+'nextn' => 'наступныя $1',
+'nextpage' => 'Наступная старонка ($1)',
+'nlinks' => '$1 {{PLURAL:$1|спасылка|спасылкі|спасылак}}',
+'nmembers' => '$1 {{PLURAL:$1|элемэнт|элемэнты|элемэнтаў}}',
+'noarticletext' => 'Зараз тэкст на гэтай старонцы адсутнічае. Вы можаце [[Special:Search/{{PAGENAME}}|пашукаць гэтую назву]] ў іншых старонках альбо [{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} рэдагаваць гэтую старонку].',
+'nodb' => 'Немагчыма выбраць базу зьвестак $1',
+'noemailtitle' => 'Адрас электроннай пошты адсутнічае',
+'noexactmatch' => "'''Старонкі з гэткай назвай не існуе.''' Вы можаце '''[[:$1|стварыць гэтую старонку]]'''.",
+'nohistory' => 'Гісторыя зьменаў для гэтай старонкі адсутнічае.',
+'noimages' => 'Выявы адсутнічаюць.',
+'nolicense' => 'Не выбраная',
+'nolinkshere' => "Ніводная старонка не спасылаецца на '''[[:$1]]'''.",
+'nolinkstoimage' => 'Ніводная старонка не спасылаецца на гэты файл.',
+'nologin' => 'Ня маеце рахунку? $1.',
+'nologinlink' => 'Стварыце рахунак',
+'nosuchaction' => 'Няма такога дзеяньня',
+'nosuchspecialpage' => 'Такой спэцыяльнай старонкі не існуе',
+'nosuchuser' => 'Не існуе ўдзельніка ці ўдзельніцы «$1».
+Праверце напісаньне, альбо выкарыстайце форму ніжэй, каб стварыць новы рахунак ўдзельніка ці ўдзельніцы.',
+'nosuchusershort' => 'Не існуе ўдзельніка ці ўдзельніцы «$1». Праверце напісаньне.',
+'notanarticle' => 'Не артыкул',
+'note' => '<strong>Заўвага: </strong>',
+'nov' => '11',
+'november' => 'лістапада',
+'november-gen' => 'лістапада',
+'nowatchlist' => 'Ваш сьпіс назіраньня — пусты.',
+'nowiki_sample' => 'Пішыце сюды нефарматаваны тэкст',
+'nowiki_tip' => 'Ігнараваць вікі-фарматаваньне',
+'nrevisions' => '$1 {{PLURAL:$1|вэрсія|вэрсіі|вэрсій}}',
+'nstab-category' => 'Катэгорыя',
+'nstab-help' => 'Старонка дапамогі',
+'nstab-image' => 'Файл',
+'nstab-main' => 'Артыкул',
+'nstab-media' => 'Мэдыя',
+'nstab-mediawiki' => 'Паведамленьне',
+'nstab-project' => 'Старонка праекту',
+'nstab-special' => 'Спэцыяльная',
+'nstab-template' => 'Шаблён',
+'nstab-user' => 'Старонка ўдзельніка/ўдзельніцы',
+'numauthors' => 'Колькасьць розных аўтараў і аўтарак (артыкула): $1',
+'numedits' => 'Колькасьць зьменаў (артыкула): $1',
+'numtalkauthors' => 'Колькасьць розных аўтараў і аўтарак (старонкі абмеркаваньня): $1',
+'numtalkedits' => 'Колькасьць зьменаў (старонкі абмеркаваньня): $1',
+'numwatchers' => 'Колькасьць назіральнікаў і назіральніц: $1',
+'nviews' => '$1 {{PLURAL:$1|прагляд|прагляды|праглядаў}}',
+'oct' => '10',
+'october' => 'кастрычніка',
+'october-gen' => 'кастрычніка',
+'ok' => 'Добра',
+'oldpassword' => 'Стары пароль:',
+'orig' => 'арыг',
+'otherlanguages' => 'На іншых мовах',
+'others' => 'іншыя',
+'pagecategories' => '{{PLURAL:$1|Катэгорыя|Катэгорыі|Катэгорыі}}',
+'pagemovedtext' => 'Старонка «[[$1]]» перанесеная ў «[[$2]]».',
+'pagetitle' => '$1 - {{SITENAME}}',
+'perfcached' => 'Наступныя зьвесткі кэшаваныя і могуць быць састарэлымі.',
+'perfcachedts' => 'Наступныя зьвесткі кэшаваныя і апошні раз былі абноўленыя $1.',
+'permalink' => 'Сталая спасылка',
+'popularpages' => 'Папулярныя старонкі',
+'portal' => 'Суполка',
+'portal-url' => '{{ns:project}}:Суполка',
+'postcomment' => 'Пракамэнтаваць',
+'powersearch' => 'Пошук',
+'preferences' => 'Устаноўкі',
+'prefixindex' => 'Пошук старонак па пачатку назвы',
+'prefs-misc' => 'Рознае',
+'prefs-rc' => 'Апошнія зьмены',
+'prefs-watchlist' => 'Сьпіс назіраньня',
+'preview' => 'Прагляд',
+'previewnote' => '<strong>Гэта толькі папярэдні прагляд і зьмены яшчэ не былі захаваныя!</strong>',
+'previousdiff' => '← Перайсьці да папярэдняй зьмены',
+'prevn' => 'папярэднія $1',
+'printableversion' => 'Вэрсія для друку',
+'privacy' => 'Правілы адносна прыватнасьці',
+'privacypage' => '{{ns:project}}:Правілы адносна прыватнасьці',
+'projectpage' => 'Паказаць старонку праекту',
+'protect' => 'Абараніць',
+'protectcomment' => 'Прычына для абароны',
+'protectedarticle' => 'абароненая «[[$1]]»',
+'protectedpage' => 'Абароненая старонка',
+'protectedpagewarning' => "<strong>ПАПЯРЭДЖАНЬНЕ: Гэтая старонка была абароненая, таму толькі адміністратары могуць рэдагаваць яе. Упэўніцеся, што Вы кіруецеся [[{{ns:project}}:Рэдагаваньне абароненых старонак|правіламі рэдагаваньня абароненых старонак]].</strong>",
+'protectlogpage' => 'Журнал абаронаў',
+'protectsub' => '(Абарона «$1»)',
+'protectthispage' => 'Абараніць гэтую старонку',
+'qbbrowse' => 'Праглядзець',
+'qbedit' => 'Рэдагаваць',
+'qbfind' => 'Знайсьці',
+'qbpageoptions' => 'Гэтая старонка',
+'qbspecialpages' => 'Спэцыяльныя старонкі',
+'randompage' => 'Выпадковая старонка',
+'randomredirect' => 'Выпадковае перанакіраваньне',
+'rclinks' => "Паказаць апошнія $1 зьменаў за мінулыя $2 дзён<br />$3",
+'rclistfrom' => 'Паказаць зьмены з $1',
+'rclsub' => '(да старонак, спасылкі на якія ёсьць на «$1»)',
+'rcnote' => 'Ніжэй пададзеныя апошнія <strong>$1</strong> зьменаў у апошнія <strong>$2</strong> дзён, па стане на $3.',
+'rcnotefrom' => "Ніжэй знаходзяцца зьмены з <b>$2</b> (да <b>$1</b> на старонку).",
+'rcshowhideanons' => '$1 ананімаў',
+'rcshowhidebots' => '$1 робатаў',
+'rcshowhideliu' => '$1 зарэгістраваных',
+'rcshowhidemine' => '$1 мае праўкі',
+'rcshowhideminor' => '$1 дробныя праўкі',
+'recentchanges' => 'Апошнія зьмены',
+'recentchangesall' => 'усе',
+'recentchangeslinked' => 'Зьвязаныя праўкі',
+'recentchangestext' => 'Сачыце за апошнімі зьменамі ў {{GRAMMAR:месны|{{SITENAME}}}} на гэтай старонцы.',
+'redirectedfrom' => '(Перанакіраваная з $1)',
+'redirectpagesub' => 'Старонка-перанакіраваньне',
+'remembermypassword' => 'Запомніць мяне на гэтым кампутары',
+'removechecked' => 'Выдаліць выбраныя старонкі са сьпісу назіраньня',
+'removedwatch' => 'Выдаленая са сьпісу назіраньня',
+'removedwatchtext' => 'Старонка «[[:$1]]» была выдаленая з Вашага сьпісу назіраньня.',
+'removingchecked' => 'Выдаленьне выбраных старонак са сьпісу назіраньня...',
+'resetprefs' => 'Скінуць',
+'restorelink' => 'выдаленыя зьмены ($1)',
+'restrictedpheading' => 'Спэцыяльныя старонкі з абмежаваным доступам',
+'restriction-edit' => 'Рэдагаваньне',
+'restriction-move' => 'Перанос',
+'resultsperpage' => 'Колькасьць вынікаў на старонцы',
+'retrievedfrom' => 'Атрымана з «$1»',
+'returnto' => 'Вярнуцца да $1.',
+'retypenew' => 'Паўтарыце новы пароль:',
+'reupload' => 'Загрузіць зноў',
+'reuploaddesc' => 'Вярнуцца да формы загрузкі.',
+'revertimg' => 'вярнуць',
+'revhistory' => 'Гісторыя зьменаў',
+'revisionasof' => 'Вэрсія ад $1',
+'revnotfound' => 'Вэрсія ня знойдзеная',
+'rollback' => 'Адмяніць рэдагаваньні',
+'rows' => 'Радкоў:',
+'saturday' => 'субота',
+'savearticle' => 'Захаваць старонку',
+'savefile' => 'Захаваць файл',
+'saveprefs' => 'Захаваць',
+'saveusergroups' => 'Захаваць групы ўдзельнікаў і ўдзельніц',
+'search' => 'Пошук',
+'searcharticle' => 'Старонка',
+'searchbutton' => 'Пошук',
+'searchresults' => 'Вынікі пошуку',
+'searchresultshead' => 'Пошук',
+'searchresulttext' => 'Для атрыманьня больш падрабязнай інфармацыі пра пошук у {{GRAMMAR:месны|{{SITENAME}}}}, глядзіце [[{{ns:project}}:Пошук|Пошук у {{GRAMMAR:месны|{{SITENAME}}}}]].',
+'sep' => '09',
+'september' => 'верасьня',
+'september-gen' => 'верасьня',
+'servertime' => 'Бягучы час на сэрвэры',
+'sharedupload' => 'Гэты файл зьяўляецца агульным і можа выкарыстоўвацца іншымі праектамі.',
+'shortpages' => 'Кароткія старонкі',
+'show' => 'паказаць',
+'showbigimage' => 'Паказаць варыянт большага памеру ($1 × $2, $3 Кб)',
+'showdiff' => 'Паказаць зьмены',
+'showingresults' => "Ніжэй паданыя да <b>$1</b> вынікаў, пачынаючы з #<b>$2</b>.",
+'showlast' => 'Паказаць $1 апошніх файлаў адсартаваных $2.',
+'showpreview' => 'Праглядзець',
+'showtoc' => 'паказаць',
+'sig_tip' => 'Ваш подпіс і момант часу',
+'sitestats' => 'Статыстыка {{GRAMMAR:родны|{{SITENAME}}}}',
+'sitesupport' => 'Ахвяраваньні',
+'siteuser' => 'Удзельнік/удзельніца {{GRAMMAR:родны|{{SITENAME}}}} $1',
+'skin' => 'Афармленьне',
+'skinpreview' => '(Прагляд)',
+'spamprotectiontitle' => 'Фільтар для абароны ад спаму',
+'speciallogtitlelabel' => 'Назва:',
+'specialloguserlabel' => 'Удзельнік/удзельніца:',
+'specialpage' => 'Спэцыяльная старонка',
+'specialpages' => 'Спэцыяльныя старонкі',
+'spheading' => 'Спэцыяльныя старонкі для ўсіх удзельнікаў і ўдзельніц',
+'statistics' => 'Статыстыка',
+'storedversion' => 'Захаваная вэрсія',
+'subcategories' => 'Падкатэгорыі',
+'subcategorycount' => 'У гэтай катэгорыі ёсьць $1 {{PLURAL:$1|падкатэгорыя|падкатэгорыі|падкатэгорый}}.',
+'subject' => 'Тэма/назва',
+'summary' => 'Кароткае апісаньне зьменаў',
+'sunday' => 'нядзеля',
+'table_pager_first' => 'Першая старонка',
+'table_pager_last' => 'Апошняя старонка',
+'table_pager_next' => 'Наступная старонка',
+'table_pager_prev' => 'Папярэдняя старонка',
+'tagline' => 'Зьвесткі зь {{GRAMMAR:родны|{{SITENAME}}}}',
+'talk' => 'Гутаркі',
+'talkpage' => 'Абмеркаваць гэтую старонку',
+'talkpagemoved' => 'Адпаведная старонка абмеркаваньня таксама перанесеная.',
+'talkpagenotmoved' => 'Адпаведная старонка абмеркаваньня <strong>не</strong> перанесеная.',
+'templatesused' => 'На гэтай старонцы выкарыстаныя наступныя шаблёны:',
+'textboxsize' => 'Рэдагаваньне',
+'thisisdeleted' => 'Праглядзець ці аднавіць $1?',
+'thumbnail-more' => 'Павялічыць',
+'thursday' => 'чацьвер',
+'timezonelegend' => 'Часавы пояс',
+'toc' => 'Зьмест',
+'tog-editsection' => 'Дазволіць рэдагаваньне асобных сэкцыяў па спасылках [рэдагаваць]',
+'tog-editwidth' => 'Поле рэдагаваньня ў поўную шырыню',
+'tog-externaleditor' => 'Па змоўчаньні выкарыстоўваць зьнешні рэдактар',
+'tog-fancysig' => 'Просты подпіс (без аўтаматычнай спасылкі)',
+'tog-hideminor' => 'Хаваць дробныя зьмены ў сьпісе апошніх зьменаў',
+'tog-minordefault' => 'Па змоўчаньні пазначаць усе зьмены дробнымі',
+'tog-nocache' => 'Адключыць кэшаваньне старонак',
+'tog-numberheadings' => 'Аўтаматычная нумарацыя загалоўкаў',
+'tog-previewonfirst' => 'Папярэдні прагляд пры першым рэдагаваньні',
+'tog-rememberpassword' => 'Запомніць мяне на гэтым кампутары',
+'tog-showtoc' => 'Паказваць зьмест (для старонак з колькасьцю сэкцый болей за 3)',
+'tog-showtoolbar' => 'Паказваць панэль інструмэнтаў рэдагаваньня (патрабуе JavaScript)',
+'tog-underline' => 'Падкрэсьліваць спасылкі:',
+'tog-usenewrc' => 'Удасканалены сьпіс апошніх зьменаў (патрабуе JavaScript)',
+'toolbox' => 'Інструмэнты',
+'tooltip-diff' => 'Паказаць зробленыя Вамі зьмены ў тэксьце. [alt-v]',
+'tooltip-minoredit' => 'Пазначыць гэтую зьмену як дробную [alt-i]',
+'tooltip-preview' => 'Праглядзець Вашы зьмены. Калі ласка, выкарыстоўвайце гэтую магчымасьць перад тым, як захаваць старонку! [alt-p]',
+'tooltip-save' => 'Захаваць Вашы зьмены [alt-s]',
+'tooltip-watch' => 'Дадаць гэтую старонку ў Ваш сьпіс назіраньня [alt-w]',
+'tuesday' => 'аўторак',
+'uid' => 'ID удзельніка/удзельніцы:',
+'uncategorizedcategories' => 'Некатэгарызаваныя катэгорыі',
+'uncategorizedimages' => 'Некатэгарызаваныя файлы',
+'uncategorizedpages' => 'Некатэгарызаваныя старонкі',
+'undelete' => 'Прагляд выдаленых старонак',
+'undeletecomment' => 'Камэнтар:',
+'underline-always' => 'Заўсёды',
+'underline-never' => 'Ніколі',
+'unit-pixel' => 'пкс',
+'unprotect' => 'зьняць абарону',
+'unusedcategories' => 'Катэгорыі, якія не выкарыстоўваюцца',
+'unusedimages' => 'Файлы, якія не выкарыстоўваюцца',
+'unusedtemplates' => 'Шаблёны, якія не выкарыстоўваюцца',
+'unusedtemplateswlh' => 'іншыя спасылкі',
+'unwatch' => 'Не назіраць',
+'unwatchedpages' => 'Старонкі, за якімі ніхто не назірае',
+'unwatchthispage' => 'Перастаць назіраць',
+'upload' => 'Загрузіць файл',
+'uploadbtn' => 'Загрузіць файл',
+'uploadedfiles' => 'Загружаныя файлы',
+'uploadedimage' => 'загружаная «[[$1]]»',
+'uploadlog' => 'журнал загрузак',
+'uploadlogpage' => 'Журнал загрузак',
+'uploadlogpagetext' => 'Сьпіс апошніх загружаных файлаў.',
+'uploadtext' => "'''Перад тым, як загрузіць файл:'''
+
+* Азнаёмцеся з '''[[{{ns:project}}:Правілы выкарыстаньня файлаў|правіламі выкарыстаньня файлаў]]'''.
+* Праверце з дапамогай '''[[Special:Imagelist|сьпісу файлаў]]''', ці не загружаны гэты файл з іншай назвай.
+* Выкарыстоўвайце наступныя '''фарматы''': [[JPG]] — для фотаздымкаў; [[GIF]] — для анімацыі; [[PNG]] — для іншых выяваў; [[OGG]] — для аўдыёфайлаў.
+* Давайце файлам '''зразумелыя назвы''', якія адлюстроўваюць іх зьмест. Напрыклад: ''Janka Kupala, 1910.jpg'' замест ''JK1.jpg''. Назву файла '''немагчыма''' зьмяніць пасьля загрузкі.
+* Пытайцеся '''дазволу''' на публікацыю фотаздымка ва ўсіх людзей, якія там прысутнічаюць.
+
+'''Пасьля таго, як выява загружаная:'''
+
+* '''Абавязкова''' дадайце:
+** '''дэталёвае апісаньне зьместу''';
+** '''крыніцу''': файл створаны Вамі; адсканаваны з кнігі ''X''; узяты з Інтэрнэт па адрасу ''Y'';
+** для файлаў, якія зроблены '''ня''' Вамі, укажыце, ці атрымалі Вы '''дазвол''' на выкарыстаньне гэтага файла ў {{GRAMMAR:месны|{{SITENAME}}}};
+** '''ліцэнзіі''', згодна ўмоваў якіх магчыма распаўсюджваць файл.
+* '''Выкарыстоўвайце файл''' у артыкуле(ах). Напрыклад: <code><nowiki>[[Выява:file.jpg]]</nowiki></code> ці <code><nowiki>[[Выява:file.jpg|міні|200пкс|Апісаньне]]</nowiki></code> — для выяваў; <code><nowiki>[[Мэдыя:file.ogg]]</nowiki></code> — для аўдыёфайлаў.",
+'uploadvirus' => 'Файл утрымлівае вірус! Падрабязнасьці: $1',
+'userexists' => 'Выбранае Вамі імя ўдзельніка/ўдзельніцы ўжо выкарыстоўваецца кімсьці іншым. Калі ласка, выберыце іншае імя.',
+'userlogin' => 'Стварыць рахунак ці ўвайсьці',
+'userlogout' => 'Выйсьці',
+'username' => 'Імя ўдзельніка/ўдзельніцы:',
+'userrights-user-editname' => 'Увядзіце імя ўдзельніка:',
+'userstats' => 'Статыстыка ўдзелу',
+'userstatstext' => "Колькасьць зарэгістраваных удзельнікаў і ўдзельніц: '''$1'''.
+
+Колькасьць адміністратараў і адміністратарак: '''$2''' (ці '''$4%'''). Падрабязнасьці глядзіце ў $3.",
+'version' => 'Вэрсія',
+'viewdeleted' => 'Паказаць $1?',
+'viewdeletedpage' => 'Паказаць выдаленыя старонкі',
+'viewpagelogs' => 'Паказаць журналы падзей для гэтай старонкі',
+'viewprevnext' => 'Паказаць ($1) ($2) ($3).',
+'viewsource' => 'Паказаць крыніцу',
+'viewsourcefor' => 'для $1',
+'viewtalkpage' => 'Паказаць абмеркаваньне',
+'wantedcategories' => 'Запатрабаваныя катэгорыі',
+'wantedpages' => 'Запатрабаваныя старонкі',
+'watch' => 'Назіраць',
+'watchlist' => 'Мой сьпіс назіраньня',
+'watchlistclearbutton' => 'Ачысьціць сьпіс назіраньня',
+'watchlistfor' => "(для '''$1''')",
+'watchthis' => 'Назіраць за гэтай старонкай',
+'watchthispage' => 'Назіраць за гэтай старонкай',
+'wednesday' => 'серада',
+'whatlinkshere' => 'Адкуль спасылаюцца на старонку',
+'whitelistacctitle' => 'Вам не дазволена ствараць рахунак',
+'wlhideshowbots' => '$1 праўкі робатаў',
+'wlhideshowown' => '$1 мае праўкі',
+'youhavenewmessages' => 'Вы маеце $1 ($2).',
+'youremail' => 'Адрас электроннай пошты *:',
+'yourlanguage' => 'Мова інтэрфэйсу:',
+'yourname' => 'Імя ўдзельніка/ўдзельніцы',
+'yournick' => 'Мянушка:',
+'yourpassword' => 'Пароль',
+'yourrealname' => 'Сапраўднае імя *:',
+'yourtext' => 'Ваш тэкст',
+);
+
+?>
diff --git a/languages/messages/MessagesBg.php b/languages/messages/MessagesBg.php
new file mode 100644
index 000000000000..2b114851d6c2
--- /dev/null
+++ b/languages/messages/MessagesBg.php
@@ -0,0 +1,1379 @@
+<?php
+/** Bulgarian (Български)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$namespaceNames = array(
+ NS_MEDIA => 'Медия',
+ NS_SPECIAL => 'Специални',
+ NS_MAIN => '',
+ NS_TALK => 'Беседа',
+ NS_USER => 'Потребител',
+ NS_USER_TALK => 'Потребител_беседа',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_беседа',
+ NS_IMAGE => 'Картинка',
+ NS_IMAGE_TALK => 'Картинка_беседа',
+ NS_MEDIAWIKI => 'МедияУики',
+ NS_MEDIAWIKI_TALK => 'МедияУики_беседа',
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Шаблон_беседа',
+ NS_HELP => 'Помощ',
+ NS_HELP_TALK => 'Помощ_беседа',
+ NS_CATEGORY => 'Категория',
+ NS_CATEGORY_TALK => 'Категория_беседа'
+);
+
+$quickbarSettings = array(
+ 'Без меню', 'Неподвижно вляво', 'Неподвижно вдясно', 'Плаващо вляво', 'Плаващо вдясно'
+);
+
+$skinNames = array(
+ 'standard' => 'Класика',
+ 'nostalgia' => 'Носталгия',
+ 'cologneblue' => 'Кьолнско синьо',
+ 'smarty' => 'Падингтън',
+ 'montparnasse' => 'Монпарнас',
+ 'davinci' => 'ДаВинчи',
+ 'mono' => 'Моно',
+ 'monobook' => 'Монобук',
+ 'myskin' => 'Мой облик',
+);
+
+$datePreferences = false;
+
+$bookstoreList = array(
+ 'books.bg' => 'http://www.books.bg/ISBN/$1',
+);
+
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#redirect', '#пренасочване', '#виж' ),
+ 'notoc' => array( 0, '__NOTOC__', '__БЕЗСЪДЪРЖАНИЕ__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__СЪССЪДЪРЖАНИЕ__' ),
+ 'toc' => array( 0, '__TOC__', '__СЪДЪРЖАНИЕ__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__БЕЗ_РЕДАКТИРАНЕ_НА_РАЗДЕЛИ__' ),
+ 'start' => array( 0, '__START__', '__НАЧАЛО__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'ТЕКУЩМЕСЕЦ' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'ТЕКУЩМЕСЕЦИМЕ' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'ТЕКУЩМЕСЕЦИМЕРОД' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'ТЕКУЩМЕСЕЦСЪКР' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'ТЕКУЩДЕН' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'ТЕКУЩДЕНИМЕ' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'ТЕКУЩАГОДИНА' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'ТЕКУЩОВРЕМЕ' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'БРОЙСТАТИИ' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'БРОЙФАЙЛОВЕ' ),
+ 'pagename' => array( 1, 'PAGENAME', 'СТРАНИЦА' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'СТРАНИЦАИ' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'ИМЕННОПРОСТРАНСТВО' ),
+ 'subst' => array( 0, 'SUBST:', 'ЗАМЕСТ:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'СЪОБЩNW:' ),
+ 'end' => array( 0, '__END__', '__КРАЙ__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'мини' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'мини=$1'),
+ 'img_right' => array( 1, 'right', 'вдясно', 'дясно', 'д' ),
+ 'img_left' => array( 1, 'left', 'вляво', 'ляво', 'л' ),
+ 'img_none' => array( 1, 'none', 'н' ),
+ 'img_width' => array( 1, '$1px', '$1пкс' , '$1п' ),
+ 'img_center' => array( 1, 'center', 'centre', 'център', 'центр', 'ц' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'рамка', 'врамка' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'ИМЕНАСАЙТА' ),
+ 'ns' => array( 0, 'NS:', 'ИП:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'ЛОКАЛЕНАДРЕС:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'ЛОКАЛЕНАДРЕСИ:' ),
+ 'server' => array( 0, 'SERVER', 'СЪРВЪР' ),
+ 'servername' => array( 0, 'SERVERNAME', 'ИМЕНАСЪРВЪРА' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'ПЪТДОСКРИПТА' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'ГРАМАТИКА:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'ТЕКУЩАСЕДМИЦА'),
+ 'currentdow' => array( 1, 'CURRENTDOW' ),
+ 'revisionid' => array( 1, 'REVISIONID' ),
+);
+
+$linkTrail = '/^([a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]+)(.*)$/sDu';
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+
+$messages = array(
+
+# User toggles
+'tog-underline' => 'Подчертаване на препратките',
+'tog-highlightbroken' => 'Показване на невалидните препратки <a href="#" class="new">така</a> (алтернативно: така<a href="#" class="internal">?</a>)',
+'tog-justify' => 'Двустранно подравняване на абзаците',
+'tog-hideminor' => 'Скриване на малки редакции в последните промени',
+'tog-usenewrc' => 'Подобряване на последните промени (Javascript)',
+'tog-numberheadings' => 'Номериране на заглавията',
+'tog-showtoolbar' => 'Помощна лента за редактиране (Javascript)',
+'tog-editondblclick' => 'Редактиране при двойно щракване (Javascript)',
+'tog-editsection' =>'Възможност за редактиране на раздел чрез препратка [редактиране]',
+'tog-editsectiononrightclick' => 'Възможност за редактиране на раздел при щракване с десния бутон върху заглавие на раздел (Javascript)',
+'tog-showtoc' =>'Показване на съдържание (за страници с повече от три раздела)',
+'tog-rememberpassword' => 'Запомняне между сесиите',
+'tog-editwidth' => 'Максимална ширина на кутията за редактиране',
+'tog-watchdefault' => 'Добавяне на редактираните страници към списъка за наблюдение',
+'tog-minordefault' => 'Отбелязване на всички промени като малки по подразбиране',
+'tog-previewontop' => 'Показване на предварителния преглед преди текстовата кутия, а не след нея',
+'tog-previewonfirst' => 'Показване на предварителен преглед при първа редакция',
+'tog-nocache' => 'Без складиране на страниците',
+'tog-fancysig' => 'Без превръщане на подписа в препратка към потребителската страница',
+'tog-externaleditor' => 'Използване на външен редактор по подразбиране',
+'tog-externaldiff' => 'Използване на външна програма за разлики по подразбиране',
+
+'underline-always' => 'Винаги',
+'underline-never' => 'Никога',
+'underline-default' => 'Според настройките на браузъра',
+'skinpreview' => '(Предварителен преглед)',
+
+# Dates
+'sunday' => 'неделя',
+'monday' => 'понеделник',
+'tuesday' => 'вторник',
+'wednesday' => 'сряда',
+'thursday' => 'четвъртък',
+'friday' => 'петък',
+'saturday' => 'събота',
+'january' => 'януари',
+'february' => 'февруари',
+'march' => 'март',
+'april' => 'април',
+'may_long' => 'май',
+'june' => 'юни',
+'july' => 'юли',
+'august' => 'август',
+'september' => 'септември',
+'october' => 'октомври',
+'november' => 'ноември',
+'december' => 'декември',
+'jan' => 'яну',
+'feb' => 'фев',
+'mar' => 'мар',
+'apr' => 'апр',
+'may' => 'май',
+'jun' => 'юни',
+'jul' => 'юли',
+'aug' => 'авг',
+'sep' => 'сеп',
+'oct' => 'окт',
+'nov' => 'ное',
+'dec' => 'дек',
+
+# Bits of text used by many pages:
+#
+'categories' => 'Категории',
+'pagecategories' => 'Категории',
+'category_header' => 'Страници в категория „$1“',
+'subcategories' => 'Подкатегории',
+'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD',
+'mainpage' => 'Начална страница',
+'mainpagetext' => 'Уики-системата беше успешно инсталирана.',
+'mainpagedocfooter' => 'Моля, разгледайте [http://meta.wikimedia.org/wiki/MediaWiki_i18n документацията] и [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide ръководството] за подробна информация относно МедияУики.
+
+Актуална версия на българския езиков файл можете да откриете на [http://meta.wikimedia.org/wiki/LanguageBg.php Мета].',
+'portal' => 'Портал за общността',
+'portal-url' => 'Project:Портал',
+'about' => 'За {{SITENAME}}',
+'aboutsite' => 'За {{SITENAME}}',
+'aboutpage' => 'Project:За {{SITENAME}}',
+'article' => 'Страница',
+'help' => 'Помощ',
+'helppage' => 'Help:Съдържание',
+'bugreports' => 'Съобщения за грешки',
+'bugreportspage' => 'Project:Съобщения за грешки',
+'sitesupport' => 'Дарения',
+'sitesupport-url' => 'Project:Подкрепа',
+'faq' => 'ЧЗВ',
+'faqpage' => 'Project:ЧЗВ',
+'edithelp' => 'Помощ при редактиране',
+'newwindow' => '(отваря се в нов прозорец)',
+'edithelppage' => 'Help:Как_се_редактират_страници',
+'cancel' => 'Отказ',
+'qbfind' => 'Търсене',
+'qbbrowse' => 'Избор',
+'qbedit' => 'Редактиране',
+'qbpageoptions' => 'Настройки за страницата',
+'qbpageinfo' => 'Информация за страницата',
+'qbmyoptions' => 'Моите настройки',
+'qbspecialpages' => 'Специални страници',
+'moredotdotdot' => 'Още...',
+'mypage' => 'Моята страница',
+'mytalk' => 'Моята беседа',
+'anontalk' => 'Беседа за адреса',
+'navigation' => 'Навигация',
+
+# Metadata in edit box
+'metadata' => '<b>Метаданни</b> (<a href="$1">разяснение</a>)',
+
+'currentevents' => 'Текущи събития',
+'currentevents-url' => 'Текущи събития',
+'disclaimers' => 'Условия за ползване',
+'disclaimerpage' => 'Project:Условия за ползване',
+'errorpagetitle' => 'Грешка',
+'returnto' => 'Обратно към $1.',
+'tagline' => 'от {{SITENAME}}',
+'whatlinkshere' => 'Какво сочи насам',
+'help' => 'Помощ',
+'search' => 'Търсене',
+'searchbutton' => 'Търсене',
+'go' => 'Отваряне',
+'searcharticle' => 'Отваряне',
+'history' => 'История',
+'history_short' => 'История',
+'updatedmarker' => 'има промяна (от последното ми влизане)',
+'info_short' => 'Информация',
+'printableversion' => 'Версия за печат',
+'permalink' => 'Постоянна препратка',
+'print' => 'Печат',
+'edit' => 'Редактиране',
+'editthispage' => 'Редактиране',
+'delete' => 'Изтриване',
+'deletethispage' => 'Изтриване',
+'undelete_short' => 'Възстановяване на $1 редакции',
+'protect' => 'Защита',
+'protectthispage' => 'Защита',
+'unprotect' => 'Сваляне на защитата',
+'unprotectthispage' => 'Сваляне на защитата',
+'newpage' => 'Нова страница',
+'talkpage' => 'Дискусионна страница',
+'specialpage' => 'Специална страница',
+'personaltools' => 'Лични инструменти',
+'postcomment' => 'Оставяне на съобщение',
+'articlepage' => 'Преглед на страница',
+'talk' => 'Беседа',
+'views' => 'Прегледи',
+'toolbox' => 'Инструменти',
+'userpage' => 'Потребителска страница',
+'projectpage' => 'Основна страница',
+'imagepage' => 'Преглед на файл',
+'viewtalkpage' => 'Преглед на беседа',
+'otherlanguages' => 'На други езици',
+'redirectedfrom' => '(пренасочване от $1)',
+'lastmodifiedat' => 'Последна промяна на страницата: $2, $1.',
+'viewcount' => 'Страницата е била преглеждана $1 пъти.',
+'copyright' => 'Съдържанието е достъпно при условията на $1.',
+'protectedpage' => 'Защитена страница',
+'badaccess' => 'Грешка при достъп', # Permission error
+'versionrequired' => 'Изисква се версия $1 на МедияУики',
+'versionrequiredtext' => 'За да използвате тази страница, е необходима версия $1 на МедияУики. Вижте [[Special:Version]].',
+'nbytes' => '$1 байта',
+'ok' => 'Добре',
+'retrievedfrom' => 'Взето от „$1“.',
+'newmessageslink' => 'нови съобщения',
+'editsection' => 'редактиране',
+'editold' => 'редактиране',
+'toc' => 'Съдържание',
+'showtoc' => 'показване',
+'hidetoc' => 'скриване',
+'thisisdeleted' => 'Преглед или възстановяване на $1?',
+'viewdeleted' => 'Преглед на $1?',
+'restorelink' => '$1 изтрити редакции',
+'feedlinks' => 'Feed:',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Страница',
+'nstab-user' => 'Потребител',
+'nstab-media' => 'Медия',
+'nstab-special' => 'Специална страница',
+'nstab-project' => 'Проект',
+'nstab-image' => 'Файл',
+'nstab-mediawiki' => 'Съобщение',
+'nstab-template' => 'Шаблон',
+'nstab-help' => 'Помощ',
+'nstab-category' => 'Категория',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Няма такова действие',
+'nosuchactiontext' => 'Действието, указано от мрежовия адрес, не се разпознава от системата.',
+'nosuchspecialpage' => 'Няма такава специална страница',
+'nospecialpagetext' => 'Отправихте заявка за невалидна [[Special:Specialpages|специална страница]].',
+
+# General errors
+#
+'error' => 'Грешка',
+'databaseerror' => 'Грешка при работа с базата от данни',
+'dberrortext' => 'Възникна синтактична грешка при заявка към базата от данни.
+Последната заявка към базата от данни беше:
+<blockquote><tt>$1</tt></blockquote>
+при функцията „<tt>$2</tt>“.
+MySQL дава грешка „<tt>$3: $4</tt>“.',
+'dberrortextcl' => 'Възникна синтактична грешка при заявка към базата от данни.
+Последната заявка беше:
+„$1“
+при функцията „$2“.
+MySQL дава грешка „$3: $4“.',
+'noconnect' => '<p>В момента има технически трудности и не може да се осъществи връзка с базата от данни.</p>
+<p>$1</p>
+<p>Моля, опитайте отново по-късно. Извиняваме се за неудобството.</p>',
+'nodb' => 'Неуспех при избирането на база от данни $1',
+'cachederror' => 'Показано е складирано копие на желаната страница, което евентуално може да е остаряло.',
+'laggedslavemode' => 'Внимание: Страницата може да не съдържа последните обновявания.',
+'readonly' => 'Базата от данни е затворена за промени',
+'enterlockreason' => 'Посочете причина за затварянето, като дадете и приблизителна оценка кога базата от данни ще бъде отново отворена',
+'readonlytext' => 'Базата от данни е временно затворена за промени – вероятно за рутинна поддръжка, след която ще бъде отново на разположение.
+Администраторът, който я е затворил, дава следното обяснение:
+$1',
+'missingarticle' => 'Текстът на страницата „$1“ не беше намерен в базата от данни.
+
+Това обикновено е причинено от последване на остаряла разлика или препратка от историята към изтрита страница.
+
+Ако не това е причината, е възможно да сте открили грешка в системата.
+Моля, съобщете за това на администратор, като включите и името на страницата.',
+'readonly_lag' => 'Базата от данни беше автоматично заключена, докато подчинените сървъри успеят да се съгласуват с основния сървър.',
+'internalerror' => 'Вътрешна грешка',
+'filecopyerror' => 'Файлът „$1“ не можа да бъде копиран като „$2“.',
+'filerenameerror' => 'Файлът „$1“ не можа да бъде преименуван на „$2“.',
+'filedeleteerror' => 'Файлът „$1“ не можа да бъде изтрит.',
+'filenotfound' => 'Файлът „$1“ не беше намерен.',
+'unexpected' => 'Неочаквана стойност: „$1“=„$2“.',
+'formerror' => 'Възникна грешка при изпращане на формуляра',
+'badarticleerror' => 'Действието не може да се изпълни върху страницата.',
+'cannotdelete' => 'Указаната страница или файл не можа да бъде изтрит(а). Възможно е вече да е изтрит(а) от някой друг.',
+'badtitle' => 'Невалидно заглавие',
+'badtitletext' => 'Желаното заглавие на страница е невалидно, празно или неправилна препратка към друго уики.',
+'perfdisabled' => 'Съжаляваме! Това свойство е временно изключено,
+защото забавя базата от данни дотам, че никой не може да използва уикито.',
+'perfdisabledsub' => 'Съхранен екземпляр от $1:',
+'perfcached' => 'Следните данни са извлечени от склада и затова може да не отговарят на текущото състояние:',
+'wrong_wfQuery_params' => 'Невалидни аргументи за wfQuery()<br />
+Функция: $1<br />
+Заявка: $2',
+'viewsource' => 'Защитена страница',
+'protectedtext' => 'Страницата е затворена за промени. Съществуват няколко причини това да е така, моля, вижте [[Project:Защитена_страница]].
+
+Можете да прегледате и копирате изходния код на страницата:',
+'sqlhidden' => '(Заявка на SQL — скрита)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Излизане на потребител',
+'logouttext' => 'Излязохте от системата.
+
+Можете да продължите да използвате {{SITENAME}} анонимно или да влезете отново като друг потребител. Обърнете внимание, че някои страници все още ще се показват така, сякаш сте влезли, докато не изтриете кеш-паметта на браузъра.',
+
+'welcomecreation' => '== Добре дошли, $1! ==
+
+Вашата сметка беше успешно открита. Сега можете да промените настройките на {{SITENAME}} по Ваш вкус.',
+
+'loginpagetitle' => 'Влизане в системата',
+'yourname' => 'Потребителско име',
+'yourpassword' => 'Парола',
+'yourpasswordagain' => 'Въведете повторно парола',
+'remembermypassword' => 'Запомняне на паролата',
+'yourdomainname' => 'Домейн',
+# TODO
+'externaldberror' => 'There was either an external authentication database error or you are not allowed to update your external account.',
+'loginproblem' => '<b>Имаше проблем с влизането Ви.</b><br />Опитайте отново!',
+'alreadyloggedin' => '<strong>$1, вече сте влезли в системата!</strong>',
+'login' => 'Влизане',
+'loginprompt' => "За влизане в {{SITENAME}} е необходимо да въведете потребителското си име и парола и да натиснете бутона '''Влизане''', като за да бъде това успешно, бисквитките (cookies) трябва да са разрешени в браузъра Ви.
+
+Ако все още не сте регистрирани (нямате открита сметка), лесно можете да сторите това, като просто въведете желаните от Вас потребителско име и парола (двукратно) и щракнете върху '''Регистриране'''.",
+'userlogin' => 'Регистриране или влизане',
+'logout' => 'Излизане',
+'userlogout' => 'Излизане',
+'notloggedin' => 'Не сте влезли',
+'createaccount' => 'Регистриране',
+'createaccountmail' => 'с писмо по електронната поща',
+'badretype' => 'Въведените пароли не съвпадат.',
+'userexists' => 'Въведеното потребителско име вече се използва. Моля, изберете друго име.',
+'youremail' => 'Е-поща *',
+'yourrealname' => 'Истинско име *',
+'yourlanguage' => 'Език',
+'yourvariant' => 'Вариант',
+'yournick' => 'Псевдоним (за подписи чрез ~~~~)',
+'email' => 'Е-поща',
+'prefs-help-email' => '* <strong>Електронна поща</strong> <em>(незадължително)</em>: Позволява на хората да се свържат с Вас, без да се налага да им съобщавате адреса си, а също може да се използва, за да Ви се изпрати нова парола, ако случайно забравите сегашната си.',
+# TODO
+'prefs-help-email-enotif' => 'This address is also used to send you email notifications if you enabled the options.',
+'prefs-help-realname' => '* <strong>Истинско име</strong> <em>(незадължително)</em>: Ако го посочите, на него ще бъдат приписани Вашите приноси.',
+'loginerror' => 'Грешка при влизане',
+'nocookiesnew' => 'Потребителската сметка беше създадена, но все още не сте влезли. {{SITENAME}} използва бисквитки при влизане на потребителите. Моля, разрешете бисквитките във Вашия браузър, тъй като те са забранени, и след това влезте с потребителското си име и парола.',
+'nocookieslogin' => '{{SITENAME}} използва бисквитки (cookies) за запис на влизанията. Моля, разрешете бисквитките във Вашия браузър, тъй като те са забранени, и опитайте отново.',
+'noname' => 'Не указахте валидно потребителско име.',
+'loginsuccesstitle' => 'Успешно влизане',
+'loginsuccess' => 'Влязохте в {{SITENAME}} като „$1“.',
+'nosuchuser' => 'Няма потребител с името „$1“.
+Проверете изписването или се регистрирайте, използвайки долния формуляр.',
+'nosuchusershort' => 'Няма потребител с името „$1“. Проверете изписването.',
+'wrongpassword' => 'Въведената парола е невалидна (или липсва). Моля, опитайте отново.',
+'mailmypassword' => 'Изпращане на нова парола',
+'passwordremindertitle' => 'Напомняне за парола от {{SITENAME}}',
+'passwordremindertext' => 'Някой (най-вероятно Вие, от IP-адрес $1) помоли да Ви изпратим нова парола за влизане в {{SITENAME}}.
+Паролата за потребителя „$2“ е „$3“.
+Сега би трябвало да влезете в системата и да смените паролата си.',
+'noemail' => 'Няма записана електронна поща за потребителя „$1“.',
+'passwordsent' => 'Нова парола беше изпратена на електронната поща на „$1“.
+Моля, влезте отново, след като я получите.',
+# TODO
+'eauthentsent' => 'A confirmation email has been sent to the nominated email address.
+Before any other mail is sent to the account, you will have to follow the instructions in the email, to confirm that the account is actually yours.',
+'mailerror' => 'Грешка при изпращане на писмо: $1',
+'acct_creation_throttle_hit' => 'Съжаляваме, създали сте вече $1 сметки и нямате право на повече.',
+# TODO
+'emailauthenticated' => 'Your email address was authenticated on $1.',
+'emailnotauthenticated' => 'Your email address is not yet authenticated. No email will be sent for any of the following features.',
+'noemailprefs' => '<strong>No email address has been specified</strong>, the following features will not work.',
+'emailconfirmlink' => 'Confirm your e-mail address',
+'invalidemailaddress' => 'The email address cannot be accepted as it appears to have an invalid format. Please enter a well-formatted address or empty that field.',
+
+# Edit page toolbar
+'bold_sample' => 'Получер текст',
+'bold_tip' => 'Получер (удебелен) текст',
+'italic_sample' => 'Курсивен текст',
+'italic_tip' => 'Курсивен (наклонен) текст',
+'link_sample' => 'Име на препратка',
+'link_tip' => 'Вътрешна препратка',
+'extlink_sample' => 'http://www.primer.com Име на препратката',
+'extlink_tip' => 'Външна препратка (не забравяйте http:// отпред)',
+'headline_sample' => 'Заглавен текст',
+'headline_tip' => 'Заглавие',
+'math_sample' => 'Тук въведете формулата',
+'math_tip' => 'Математическа формула (LaTeX)',
+'nowiki_sample' => 'Тук въведете текст',
+'nowiki_tip' => 'Пренебрегване на форматиращите команди',
+'image_sample' => 'Пример.jpg',
+'image_tip' => 'Вмъкване на картинка',
+'media_sample' => 'Пример.ogg',
+'media_tip' => 'Препратка към файл',
+'sig_tip' => 'Вашият подпис заедно с времева отметка',
+'hr_tip' => 'Хоризонтална линия (използвайте пестеливо)',
+
+# Edit pages
+#
+'summary' => 'Резюме',
+'subject' => 'Тема/заглавие',
+'minoredit' => 'Това е малка промяна.',
+'watchthis' => 'Наблюдаване на страницата',
+'savearticle' => 'Съхранение',
+'preview' => 'Предварителен преглед',
+'showpreview' => 'Предварителен преглед',
+'showdiff' => 'Показване на промените',
+'blockedtitle' => 'Потребителят е блокиран',
+'blockedtext' => "Вашето потребителско име (или IP-адрес) е блокирано от $1.
+Причината за това е:<br />''$2''<p>Можете да се свържете с $1 или с някой от останалите [[Project:Администратори|администратори]], за да обсъдите това.
+
+Можете да използвате услугата „'''Пращане писмо на потребителя'''“ единствено, ако сте посочили валидна електронна поща в [[Special:Preferences|настройките]] си.
+
+Вашият IP-адрес е $3. Моля, вмъквайте този адрес във всяко питане, което правите.",
+'whitelistedittitle' => 'Необходимо е да влезете, за да може да редактирате',
+'whitelistedittext' => 'Необходимо е да [[Special:Userlogin|влезете]], за да може да редактирате страници.',
+'whitelistreadtitle' => 'Необходимо е да влезете, за да може да четете страници',
+'whitelistreadtext' => 'Необходимо е да [[Special:Userlogin|влезете]], за да може да четете страници.',
+'whitelistacctitle' => 'Не ви е позволено да създавате сметка',
+'whitelistacctext' => 'За да Ви бъде позволено създаването на сметки, трябва да [[Special:Userlogin|влезете]] и да имате подходящото разрешение.',
+'loginreqtitle' => 'Изисква се влизане',
+'loginreqlink' => 'влизане',
+'loginreqpagetext' => 'Необходимо е да $1, за да може да разглеждате други страници.',
+'accmailtitle' => 'Паролата беше изпратена.',
+'accmailtext' => 'Паролата за „$1“ беше изпратена на $2.',
+'newarticle' => '(нова)',
+'newarticletext' => "<div style=\"font-size:small; color:#033; border:thin solid #aaa; padding:.4em\">Последвали сте препратка към страница, която все още не съществува.
+За да я създадете, започнете да пишете в долната текстова кутия
+(вижте '''[[Project:Помощ|помощната страница]]''' за повече информация).
+Ако сте дошли тук погрешка, просто натиснете '''бутона за връщане''' на Вашия браузър.
+
+Вашата добавка ще бъде видима '''веднага''' след съхранението, затова ако просто искате да изпробвате как работят нещата, използвайте нашия '''[[Project:Пясъчник|пясъчник]]'''.</div>",
+'anontalkpagetext' => "----
+''Това е дискусионната страница на анонимен потребител, който все още няма сметка или не я използва. Затова се налага да използваме IP-адрес, за да го/я идентифицираме. Такъв адрес може да се споделя от няколко потребители.''
+
+''Ако сте анонимен потребител и мислите, че тези неуместни коментари са отправени към Вас, моля [[Special:Userlogin|регистрирайте се или влезте в системата]], за да избегнете евентуално бъдещо объркване с други анонимни потребители.''",
+'noarticletext' => "(Тази страница все още не съществува. Можете да я създадете, като щракнете на '''Редактиране'''.)",
+'clearyourcache' => "'''Бележка:''' След съхранението е необходимо да изтриете кеша на браузъра, за да видите промените:
+'''Mozilla / Firefox / Safari:''' натиснете бутона ''Shift'' и щракнете върху ''Презареждане'' (''Reload''), или изберете клавишната комбинация ''Ctrl-Shift-R'' (''Cmd-Shift-R'' за Apple Mac);
+'''IE:''' натиснете ''Ctrl'' и щракнете върху ''Refresh'', или клавишната комбинация ''CTRL-F5'';
+'''Konqueror:''' щракнете върху ''Презареждане'' или натиснете ''F5'';
+'''Opera:''' вероятно е необходимо да изчистите кеша през менюто ''Tools&rarr;Preferences''.",
+'usercssjsyoucanpreview' => '<strong>Съвет:</strong> Използвайте бутона „Предварителен преглед“, за да изпробвате новия код на css/js преди съхранението.',
+'usercsspreview' => "'''Не забравяйте, че това е само предварителен преглед на кода на CSS, страницата все още не е съхранена!'''",
+'userjspreview' => "'''Не забравяйте, че това е само изпробване/предварителен преглед на кода на Javascript, страницата все още не е съхранена!'''",
+'updated' => '(актуализирана)',
+'note' => '<strong>Забележка:</strong>',
+'previewnote' => 'Не забравяйте, че това е само предварителен преглед и страницата все още не е съхранена!',
+'previewconflict' => 'Този предварителен преглед отразява текста в горната текстова кутия така, както би се показал, ако съхраните.',
+'editing' => 'Редактиране на „$1“',
+'editinguser' => 'Редактиране на „$1“',
+'editingsection' => 'Редактиране на „$1“ (раздел)',
+'editingcomment' => 'Редактиране на „$1“ (нов раздел)',
+'editconflict' => 'Различна редакция: $1',
+'explainconflict' => 'Някой друг вече е променил тази страница, откакто започнахте да я редактирате.
+Горната текстова кутия съдържа текущия текст на страницата без Вашите промени, които са показани в долната кутия. За да бъдат и те съхранени, е необходимо ръчно да ги преместите в горното поле, тъй като <b>единствено</b> текстът в него ще бъде съхранен при натискането на бутона „Съхранение“.<br />',
+'yourtext' => 'Вашият текст',
+'storedversion' => 'Съхранена версия',
+'nonunicodebrowser' => '<strong>ВНИМАНИЕ: Браузърът Ви не поддържа Уникод. За да можете спокойно да редактирате страници, всички символи, невключени в ASCII-таблицата, ще бъдат заменени с шестнадесетични кодове.</strong>',
+'editingold' => '<strong>ВНИМАНИЕ: Редактирате остаряла версия на страницата.
+Ако съхраните, всякакви промени, направени след тази версия, ще бъдат изгубени.</strong>',
+'yourdiff' => 'Разлики',
+'copyrightwarning' => '<div style="color:black; background-color:#FFFFEE; border:thin solid #999; padding:0.5em">
+Моля, обърнете внимание на това, че всички приноси към {{SITENAME}} се публикуват при условията на $2 (за подробности вижте $1).
+Ако не сте съгласни Вашата писмена работа да бъде променяна и разпространявана без ограничения, не я публикувайте.<br />
+
+Също потвърждавате, че <strong>Вие</strong> сте написали материала или сте използвали <strong>свободни ресурси</strong> – <em>обществено достояние</em> или друг свободен източник.
+Ако сте ползвали чужди материали, за които имате разрешение, непременно посочете източника.
+
+<div style="color:#EE0000; background-color:#FFFFEE; font-weight:bold; font-size:1.1em; font-variant:small-caps; text-align:center;">Не публикувайте произведения с авторски права без разрешение!</div>
+</div>',
+'copyrightwarning2' => '<div style="color:black; background-color:#FFFFEE; border:thin solid #999; padding:0.5em">
+Моля, обърнете внимание на това, че всички приноси към {{SITENAME}} могат да бъдат редактирани, променяни или премахвани от останалите сътрудници.
+Ако не сте съгласни Вашата писмена работа да бъде променяна без ограничения, не я публикувайте.<br />
+Също потвърждавате, че <strong>Вие</strong> сте написали материала или сте използвали <strong>свободни ресурси</strong> – <em>обществено достояние</em> или друг свободен източник.
+Ако сте ползвали чужди материали, за които имате разрешение, непременно посочете източника.
+
+<div style="color:#ee0000; background-color:#ffffee; font-weight:bold; font-size:1.1em; font-variant:small-caps; text-align:center;">Не публикувайте произведения с авторски права без разрешение!</div>
+</div>',
+'longpagewarning' => '<strong>ВНИМАНИЕ: Страницата има размер $1 килобайта; някои браузъри могат да имат проблеми при редактиране на страници по-големи от 32 КБ.
+Моля, обмислете дали страницата не може да се раздели на няколко по-малки части.</strong>',
+'readonlywarning' => '<strong>ВНИМАНИЕ: Базата от данни беше затворена за поддръжка, затова в момента промените Ви не могат да бъдат съхранени. Ако желаете, можете да съхраните страницата като текстов файл и да се опитате да я публикувате по-късно.</strong>',
+'protectedpagewarning' => '<strong>ВНИМАНИЕ: Страницата е защитена и само администратори могат да я редактират.
+Моля, следвайте [[Project:Защитена страница|указанията за защитена страница]].</strong>',
+'templatesused' => 'Шаблони, използвани на страницата:',
+
+# History pages
+#
+'revhistory' => 'История на версиите',
+'nohistory' => 'Няма редакционна история за тази страница.',
+'revnotfound' => 'Версията не е открита',
+'revnotfoundtext' => 'Желаната стара версия на страницата не беше открита.
+Моля, проверете адреса, който използвахте за достъп до страницата.',
+'loadhist' => 'Зареждане история на страницата',
+'currentrev' => 'Текуща версия',
+'revisionasof' => 'Версия от $1',
+'previousrevision' => '←По-стара версия',
+'nextrevision' => 'По-нова версия→',
+'currentrevisionlink' => 'преглед на текущата версия',
+'cur' => 'тек',
+'next' => 'след',
+'last' => 'посл',
+'orig' => 'ориг',
+'histlegend' => '<i>Разлики:</i> Изберете версиите, които желаете да сравните, чрез превключвателите срещу тях и натиснете &lt;Enter&gt; или бутона за сравнение.<br />
+<i>Легенда:</i> (<b>тек</b>) = разлика с текущата версия, (<b>посл</b>) = разлика с предишната версия, <b>м</b>&nbsp;=&nbsp;малка промяна',
+'deletedrev' => '[изтрита]',
+'histfirst' => 'Първи',
+'histlast' => 'Последни',
+# Diffs
+#
+'difference' => '(Разлики между версиите)',
+'loadingrev' => 'зареждане на версии за функцията <em>разл</em>',
+'lineno' => 'Ред $1:',
+'editcurrent' => 'Редактиране на текущата версия на страницата',
+'selectnewerversionfordiff' => 'Избиране на нова версия за сравнение',
+'selectolderversionfordiff' => 'Избиране на стара версия за сравнение',
+'compareselectedversions' => 'Сравнение на избраните версии',
+
+# Search results
+#
+'searchresults' => 'Резултати от търсенето',
+'searchresulttext' => 'За повече информация относно {{SITENAME}}, вижте [[Project:Търсене|Търсене в {{SITENAME}}]].',
+'searchsubtitle' => 'За заявка „[[:$1]]“',
+'searchsubtitleinvalid' => 'За заявка „$1“',
+'badquery' => 'Лошо формулирана заявка за търсене',
+'badquerytext' => 'Вашата заявка не можа да бъде обработена.
+Вероятно сте се опитали да търсите дума с по-малко от три букви, което все още не се поддържа.
+Възможно е и да сте сгрешили в изписването на израза, например: „риба и и везни“.
+Моля, опитайте с нова заявка.',
+'matchtotals' => 'Заявката „$1“ отговаря на $2 заглавия на страници и на текста на $3 страници.',
+'noexactmatch' => 'В {{SITENAME}} не съществува страница с това заглавие. Можете да я \'\'\'[[:$1|създадете]]\'\'\'.',
+'titlematches' => 'Съответствия в заглавията на страници',
+'notitlematches' => 'Няма съответствия в заглавията на страници',
+'textmatches' => 'Съответствия в текста на страници',
+'notextmatches' => 'Няма съответствия в текста на страници',
+'prevn' => 'предишни $1',
+'nextn' => 'следващи $1',
+'viewprevnext' => 'Преглед ($1) ($2) ($3).',
+'showingresults' => 'Показване на до <b>$1</b> резултата, като се започва от номер <b>$2</b>.',
+'showingresultsnum' => 'Показване на <b>$3</b> резултата, като се започва от номер <b>$2</b>.',
+'nonefound' => "'''Забележка''': Безрезултатните търсения често са причинени от това, че се търсят основни думи като „има“ или „от“, които не се индексират, или от това, че се търсят повече от една думи, тъй като се показват само страници, съдържащи всички зададени понятия.",
+'powersearch' => 'Търсене',
+'powersearchtext' => '
+Търсене в именни пространства:<br />
+$1<br />
+$2 Показване на пренасочвания &nbsp; Търсене на $3 $4',
+'searchdisabled' => 'Търсенето в {{SITENAME}} е временно изключено поради голямото натоварване на сървъра. Междувременно можете да търсите чрез Google. Обърнете внимание обаче, че е възможно съхранените при тях страници да са остарели.',
+'blanknamespace' => '(Основно)',
+
+# Preferences page
+#
+'preferences' => 'Настройки',
+'prefsnologin' => 'Не сте влезли',
+'prefsnologintext' => 'Необходимо е да [[Special:Userlogin|влезете]], за да може да променяте потребителските си настройки.',
+'prefsreset' => 'Стандартните настройки бяха възстановени.',
+'qbsettings' => 'Лента за бърз избор',
+'changepassword' => 'Смяна на парола',
+'skin' => 'Облик',
+'math' => 'Математически формули',
+'dateformat' => 'Формат на датата',
+'math_failure' => 'Неуспех при разбора',
+'math_unknown_error' => 'непозната грешка',
+'math_unknown_function' => 'непозната функция',
+'math_lexing_error' => 'лексикална грешка',
+'math_syntax_error' => 'синтактична грешка',
+'math_image_error' => 'Превръщането към PNG не сполучи. Проверете дали latex, dvips и gs са правилно инсталирани.',
+'math_bad_tmpdir' => 'Невъзможно е писането или създаването на временна папка за математическите операции',
+'math_bad_output' => 'Невъзможно е писането или създаването на изходяща папка за математическите операции',
+'math_notexvc' => 'Липсва изпълнимият файл на texvc. Моля, прегледайте math/README за информация относно конфигурирането.',
+'prefs-personal' => 'Потребителски данни',
+'prefs-rc' => 'Последни промени и мъничета',
+'prefs-misc' => 'Други настройки',
+'saveprefs' => 'Съхранение',
+'resetprefs' => 'Възстановяване на стандартните настройки',
+'oldpassword' => 'Стара парола',
+'newpassword' => 'Нова парола',
+'retypenew' => 'Нова парола повторно',
+'textboxsize' => 'Редактиране',
+'rows' => 'Редове',
+'columns' => 'Колони',
+'searchresultshead' => 'Търсене',
+'resultsperpage' => 'Резултати на страница',
+'contextlines' => 'Редове за резултат',
+'contextchars' => 'Знаци от контекста на ред',
+'stubthreshold' => 'Определяне като къси страници до',
+'recentchangescount' => 'Брой заглавия в последни промени',
+'savedprefs' => 'Вашите настройки бяха съхранени.',
+'timezonelegend' => 'Времева зона',
+'timezonetext' => '¹ Броят часове, с които Вашето местно време се различава от това на сървъра (UTC).',
+'localtime' => 'Местно време',
+'timezoneoffset' => 'Отместване¹',
+'servertime' => 'Време на сървъра',
+'guesstimezone' => 'Попълване чрез браузъра',
+'defaultns' => 'Търсене в тези именни пространства по подразбиране:',
+'default' => 'по подразбиране',
+'files' => 'Файлове',
+
+# User levels special page
+
+'userrights-lookup-user' => 'Управляване на потребителските групи',#Manage user groups
+'userrights-user-editname' => 'Въведете потребителско име:', #Enter a username:
+'editusergroup' => 'Редактиране на потребителските групи', #Edit User Groups
+
+# user groups editing
+'userrights-editusergroup' => 'Редактиране на потребителските групи',#Edit user groups
+'saveusergroups' => 'Съхранение на потребителските групи',#Save User Groups
+'userrights-groupsmember' => 'Член на:',
+'userrights-groupsavailable' => 'Групи на разположение:',
+'userrights-groupshelp' => 'Изберете групите, към които искате той да бъде прибавен или от които да бъде премахнат. Неизбраните групи няма да бъдат променени. Можете да отизберете група чрез <CTRL> + ляв бутон на мишката',
+
+# Recent changes
+#
+'changes' => 'промени',
+'recentchanges' => 'Последни промени',
+'recentchangestext' => 'Проследяване на последните промени в {{SITENAME}}.
+
+Легенда: <b>тек</b> = разлика на текущата версия,
+<b>ист</b> = история на версиите, <b>м</b>&nbsp;=&nbsp;малка промяна, <b class="newpage">Н</b>&nbsp;=&nbsp;новосъздадена страница',
+'rcnote' => 'Показани са последните <strong>$1</strong> промени през последните <strong>$2</strong> дни.',
+'rcnotefrom' => 'Дадени са промените от <b>$2</b> (до <b>$1</b> показани).',
+'rclistfrom' => 'Показване на промени, като се започва от $1.',
+'rclinks' => 'Показване на последните $1 промени през последните $2 дни<br />$3',
+'diff' => 'разл',
+'hist' => 'ист',
+'hide' => 'Скриване',
+'show' => 'Показване',
+'minoreditletter' => 'м',
+'newpageletter' => 'Н',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 наблюдаващ(и) потребител(и)]',
+
+# Upload
+'upload' => 'Качване',
+'uploadbtn' => 'Качване',
+'reupload' => 'Повторно качване',
+'reuploaddesc' => 'Връщане към формуляра за качване.',
+'uploadnologin' => 'Не сте влезли',
+'uploadnologintext' => 'Необходимо е да [[Special:Userlogin|влезете]], за да може да качвате файлове.',
+'upload_directory_read_only' => 'Сървърът няма достъп за писане до папката за качване „$1“.',
+'uploaderror' => 'Грешка при качване',
+'uploadtext' => "
+Използвайте долния формуляр, за да качвате файлове, които ще можете да използвате в страниците.
+В повечето браузъри ще видите бутон „Browse...“ (ако използвате преведен интерфейс, можете да видите „Избор на файл...“, „Избор...“ и др.), който ще отвори основния за вашата операционна система диалогов прозорец за избиране на файл.
+
+За да включите картинка (файл) в страница, използвайте една от следните препратки: '''<nowiki>[[{{ns:Image}}:картинка.jpg]]</nowiki>''' или '''<nowiki>[[{{ns:Image}}:картинка.png|алтернативен текст]]</nowiki>''' или '''<nowiki>[[{{ns:Media}}:звук.ogg]]</nowiki>''' за музикални файлове.
+
+За да прегледате съществуващите в базата от данни файлове, разгледайте [[Special:Imagelist|списъка с качените файлове]].
+Качванията и изтриванията се записват в [[Special:Log/upload|дневника на качванията]].",
+'uploadlog' => 'дневник на качванията',
+'uploadlogpage' => 'Дневник на качванията',
+'uploadlogpagetext' => 'Списък на последните качвания.',
+'filename' => 'Име на файл',
+'filedesc' => 'Описание',
+'fileuploadsummary' => 'Описание:',
+'filestatus' => 'Авторско право',
+'filesource' => 'Изходен код',
+'copyrightpage' => 'Project:Авторски права',
+'copyrightpagename' => 'авторските права в {{SITENAME}}',
+'uploadedfiles' => 'Качени файлове',
+'minlength' => 'Имената на файловете трябва да съдържат поне три знака.',
+'illegalfilename' => 'Името на файла „$1“ съдържа знаци, които не са позволени в заглавия на страници. Моля, преименувайте файла и се опитайте да го качите отново.',
+'badfilename' => 'Файлът беше преименуван на „$1“.',
+'badfiletype' => 'Файловият формат „.$1“ не се препоръчва за картинки.',
+'largefile' => 'Препоръчва се файловете да не надвишават $1 байта, размерът на този файл е $2 байта.',
+'largefileserver' => 'Файлът е по-голям от допустимия от сървъра размер.',
+'emptyfile' => 'Каченият от Вас файл е празен. Това може да е предизвикано от грешка в името на файла. Моля, уверете се дали наистина искате да го качите.',
+'fileexists' => 'Вече съществува файл с това име! Моля, прегледайте $1, ако не сте сигурни дали искате да го промените.',
+'successfulupload' => 'Качването беше успешно',
+'fileuploaded' => 'Файлът „$1“ беше успешно качен.
+Моля, последвайте препратката: ($2) към страницата за описание и въведете малко информация за файла – кога и от кого е създаден и всякаква друга информация, която може да имате за него. Ако това е картинка, можете да я вмъкнете в някоя страница по следния начин: <tt><nowiki>[[Картинка:$1|мини|Описание]]</nowiki></tt>',
+'uploadwarning' => 'Предупреждение при качване',
+'savefile' => 'Съхраняване на файл',
+'uploadedimage' => 'качена „[[$1]]“',
+'uploaddisabled' => 'Съжаляваме, качванията бяха спрени.',
+'uploadscripted' => 'Файлът съдържа HTML или скриптов код, който може да бъде погрешно интерпретиран от браузъра.',
+'uploadcorrupt' => 'Файлът е повреден или е с неправилно разширение. Моля, проверете го и го качете отново.',
+'uploadvirus' => 'Файлът съдържа вирус! Подробности: $1',
+'sourcefilename' => 'Първоначално име',
+'destfilename' => 'Целево име',
+
+'license' => 'Лицензиране',
+'nolicense' => 'Нищо не е избрано',
+
+# Image list
+
+'imagelist' => 'Списък на файловете',
+'imagelisttext' => 'Списък от $1 файла, сортирани $2.',
+'getimagelist' => 'донасяне на списъка с файлове',
+'ilsubmit' => 'Търсене',
+'showlast' => 'Показване на последните $1 файла, сортирани $2.',
+'byname' => 'по име',
+'bydate' => 'по дата',
+'bysize' => 'по размер',
+'imgdelete' => 'изтр',
+'imgdesc' => 'опис',
+'imglegend' => 'Легенда: (опис) = показване/редактиране на описанието на файла.',
+'imghistory' => 'История на файла',
+'revertimg' => 'връщ',
+'deleteimg' => 'изтр',
+'deleteimgcompletely' => 'Изтриване на всички версии на файла',
+'imghistlegend' => 'Легенда: (тек) = текущият файл, (изтр) = изтриване на съответната версия, (връщ) = възвръщане към съответната версия.
+<br /><i>Щракнете върху датата, за да видите файла, качен на тази дата</i>.',
+'imagelinks' => 'Препратки към файла',
+'linkstoimage' => 'Следните страници сочат към файла:',
+'nolinkstoimage' => 'Няма страници, сочещи към файла.',
+'sharedupload' => 'Този файл е споделен и може да бъде използван от други проекти.',
+'shareduploadwiki' => 'Моля, разгледайте $1 за по-нататъшна информация.',
+'shareduploadwiki-linktext' => 'описателната страница на файла',
+'noimage' => 'Не съществува файл с това име, можете $1.',
+'noimage-linktext' => 'да го качите',
+'uploadnewversion-linktext' => 'Качване на нова версия на файла',
+
+# Statistics
+#
+'statistics' => 'Статистика',
+'sitestats' => 'Страници',
+'userstats' => 'Потребители',
+'sitestatstext' => "Базата от данни съдържа '''$1''' страници.
+Това включва всички страници от всички именни пространства в {{SITENAME}} (''Основно'', Беседа, {{ns:Project}}, Потребител, Категория, ...). Измежду тях '''$2''' страници се смятат за действителни (изключват се пренасочванията и страниците, несъдържащи препратки).
+
+Имало е '''$4''' редакции на страници откакто уикито беше пуснато. Това прави средно по '''$5''' редакции на страница.",
+'userstatstext' => "Има '''$1''' регистрирани потребители, като '''$2''' от тях (или '''$4%''') са администратори (вижте $3).",
+
+# Maintenance Page
+#
+'disambiguations' => 'Пояснителни страници',
+'disambiguationspage' => 'Шаблон:Пояснение',
+'disambiguationstext' => 'Следните страници сочат към <i>пояснителна страница</i>. Вместо това те би трябвало да сочат към съответната тема.<br /> Страница се определя като „<i>пояснителна</i>“, ако към нея се сочи от $1.<br />Тук <i>не</i> са посочени препратки от други именни пространства.',
+'doubleredirects' => 'Двойни пренасочвания',
+'doubleredirectstext' => 'Всеки ред съдържа препратки към първото и второто пренасочване, както и първия ред на текста на второто пренасочване, който обикновено посочва „<i>истинската</i>“ целева страница, към която първото пренасочване би трябвало да сочи.',
+'brokenredirects' => 'Невалидни пренасочвания',
+'brokenredirectstext' => 'Следните пренасочващи страници сочат към несъществуващи страници.',
+
+
+# Miscellaneous special pages
+#
+'lonelypages' => 'Страници сираци',
+'uncategorizedpages' => 'Некатегоризирани страници',
+'uncategorizedcategories' => 'Некатегоризирани категории',
+'unusedcategories' => 'Неизползвани категории',
+'unusedimages' => 'Неизползвани файлове',
+'popularpages' => 'Известни страници',
+'nviews' => '$1 прегледа',
+'wantedpages' => 'Желани страници',
+'mostlinked' => 'Най-препращани страници',
+'nlinks' => '$1 препратки',
+'allpages' => 'Всички страници',
+'prefixindex' => 'Азбучен списък на представки',
+'randompage' => 'Случайна страница',
+'shortpages' => 'Кратки страници',
+'longpages' => 'Дълги страници',
+'deadendpages' => 'Задънени страници',
+'listusers' => 'Списък на потребителите',
+'specialpages' => 'Специални страници',
+'spheading' => 'Специални страници за всички потребители',
+'restrictedpheading' => 'Специални страници с ограничен достъп',
+'recentchangeslinked' => 'Свързани промени',
+'rclsub' => '(на страници, сочени от „$1“)',
+'newpages' => 'Нови страници',
+'ancientpages' => 'Стари страници',
+'intl' => 'Междуезикови препратки',
+'move' => 'Преместване',
+'movethispage' => 'Преместване на страницата',
+'unusedimagestext' => 'Моля, обърнете внимание на това, че други сайтове могат да сочат към картинката чрез пряк адрес и въпреки това тя може да се намира в списъка.',
+'unusedcategoriestext' => 'Следните категории съществуват, но никоя страница или категория не ги използва.',
+'booksources' => 'Източници на книги',
+'categoriespagetext' => 'В {{SITENAME}} съществуват следните категории.',
+'data' => 'Данни',
+'userrights' => 'Управление на потребителските права',
+'groups' => 'Потребителски групи',
+
+'booksourcetext' => 'Показани са препратки към други сайтове, които продават нови и използвани книги и могат да имат допълнителна информация за книгите, които търсите.',
+'isbn' => 'ISBN',
+'alphaindexline' => 'от $1 до $2',
+'version' => 'Версия',
+'log' => 'Дневници',
+'alllogstext' => 'Смесено показване на дневниците на качванията, изтриванията, защитата, блокиранията и бюрократите.
+Можете да ограничите прегледа, като изберете вид на дневника, потребителско име или определена страница.',
+
+# Special:Allpages
+'nextpage' => 'Следваща страница ($1)',
+'allpagesfrom' => 'Показване на страниците, като се започва от:',
+'allarticles' => 'Всички страници',
+'allinnamespace' => 'Всички страници (именно пространство $1)',
+'allnotinnamespace' => 'Всички страници (без именно пространство $1)',
+'allpagesprev' => 'Предишна',
+'allpagesnext' => 'Следваща',
+'allpagessubmit' => 'Отиване',
+
+# Email this user
+#
+'mailnologin' => 'Няма електронна поща',
+'mailnologintext' => 'Необходмимо е да [[Special:Userlogin|влезете]] и да посочите валидна електронна поща в [[Special:Preferences|настройките]] си, за да може да пращате писма на други потребители.',
+'emailuser' => 'Пращане писмо на потребителя',
+'emailpage' => 'Пращане писмо на потребител',
+'emailpagetext' => 'Ако потребителят е посочил валидна електронна поща в настройките си, чрез долния формуляр можете да му изпратите съобщение. Адресът, записан в настройките Ви, ще се появи в полето „От“ на изпратеното писмо, така че получателят ще е в състояние да Ви отговори.',
+'usermailererror' => 'Пощенският обект даде грешка:', # Mail object returned error:
+'defemailsubject' => 'Писмо от {{SITENAME}}',
+'noemailtitle' => 'Няма електронна поща',
+'noemailtext' => 'Потребителят не е посочил валидна електронна поща или е избрал да не получава писма от други потребители.',
+'emailfrom' => 'От',
+'emailto' => 'До',
+'emailsubject' => 'Относно',
+'emailmessage' => 'Съобщение',
+'emailsend' => 'Изпращане',
+'emailsent' => 'Писмото е изпратено',
+'emailsenttext' => 'Писмото Ви беше изпратено.',
+
+# Watchlist
+#
+'watchlist' => 'Моят списък за наблюдение',
+'nowatchlist' => 'Списъкът Ви за наблюдение е празен.',
+'watchnologin' => 'Не сте влезли',
+'watchnologintext' => 'Необходимо е да [[Special:Userlogin|влезете]], за да може да променяте списъка си за наблюдение.',
+'addedwatch' => 'Добавено в списъка за наблюдение',
+'addedwatchtext' => "Страницата „'''$1'''“ беше добавена към [[Special:Watchlist|списъка Ви за наблюдение]].
+Нейните бъдещи промени, както и на съответната й дискусионна страница, ще се описват там, а тя ще се появява с '''удебелен шрифт''' в [[Special:Recentchanges|списъка на последните промени]], което ще направи по-лесно избирането й.
+
+Ако по-късно искате да премахнете страницата от списъка си за наблюдение, щракнете на „''Спиране на наблюдение''“.",
+'removedwatch' => 'Премахнато от списъка за наблюдение',
+'removedwatchtext' => 'Страницата „$1“ беше премахната от списъка Ви за наблюдение.',
+'watch' => 'Наблюдаване',
+'watchthispage' => 'Наблюдаване на страницата',
+'unwatch' => 'Спиране на наблюдение',
+'unwatchthispage' => 'Спиране на наблюдение',
+'notanarticle' => 'Не е страница',
+'watchnochange' => 'Никоя от наблюдаваните страници не е била редактирана в показаното време.',
+# TODO съобщението отново е съкратено, да се провери по-късно, може да е нечия грешка
+'watchdetails' => '* $1 наблюдавани страници (без дискусионни), $2 редактирани страници в избраното време
+* Метод на заявката: $3
+* [[Special:Watchlist/edit|Показване и редактиране на пълния списък]]',
+# TODO
+'wlheader-enotif' => '* Email notification is enabled.',
+'wlheader-showupdated' => "* Pages which have been changed since you last visited them are shown in '''bold'''",
+'watchmethod-recent' => 'проверка на последните промени за наблюдавани страници',
+'watchmethod-list' => 'проверка на наблюдаваните страници за скорошни редакции',
+'removechecked' => 'Премахване на избраните от списъка за наблюдение',
+'watchlistcontains' => 'Списъкът Ви за наблюдение съдържа $1 страници.',
+'watcheditlist' => 'В азбучен ред са показани наблюдаваните от Вас основни страници. Отметнете кутийките на страниците, които искате да премахнете от списъка Ви за наблюдение и натиснете бутона „Премахване на избраните“ (изтриването на основна страница предизвиква изтриването и на съответната й дискусионна страница и обратно).',
+'removingchecked' => 'Премахване на избраните от списъка за наблюдение...',
+'couldntremove' => 'Неуспех при премахването на „$1“...',
+'iteminvalidname' => 'Проблем с „$1“, грешно име...',
+'wlnote' => 'Показани са последните $1 промени през последните <b>$2</b> часа.',
+'wlshowlast' => 'Показване на последните $1 часа $2 дни $3',
+'wlsaved' => 'Това е съхранена версия на списъка Ви за наблюдение.',
+'wlhideshowown' => '$1 на моите редакции.',
+'wlhideshowbots' => '$1 на редакции на ботове.',
+
+'enotif_mailer' => '{{SITENAME}} Notification Mailer',
+'enotif_reset' => 'Отбелязване на всички страници като посетени',
+'enotif_newpagetext'=> 'Това е нова страница.',
+'changed' => 'променена',
+'created' => 'създадена',
+'enotif_subject' => '{{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED by $PAGEEDITOR',
+'enotif_lastvisited' => 'Прегледайте $1 за всички промени след последното ви посещение.',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Изтриване на страница',
+'confirm' => 'Потвърждение',
+'excontent' => 'съдържанието беше: „$1“',
+'excontentauthor' => 'съдържанието беше: „$1“ (като единственият автор беше „$2“)',
+'exbeforeblank' => 'съдържанието преди изпразването беше: „$1“',
+'exblank' => 'страницата беше празна',
+'confirmdelete' => 'Потвърждение за изтриване',
+'deletesub' => '(Изтриване на „$1“)',
+'historywarning' => 'Внимание: Страницата, която ще изтриете, има история:',
+'confirmdeletetext' => 'На път сте безвъзвратно да изтриете страница или файл, заедно с цялата й (му) история, от базата от данни.
+Моля, потвърдете, че искате това, разбирате последствията и правите това в съответствие с нашата [[Project:Линия на поведение|линия на поведение]].',
+#'confirmcheck' => 'Да, наистина искам да я изтрия.', # не се ползва
+'actioncomplete' => 'Действието беше изпълнено',
+'deletedtext' => 'Страницата „$1“ беше изтрита. Вижте $2 за запис на последните изтривания.',
+'deletedarticle' => 'изтрита „[[$1]]“',
+'dellogpage' => 'Дневник на изтриванията',
+'dellogpagetext' => 'Списък на последните изтривания.',
+'deletionlog' => 'дневника на изтриванията',
+'reverted' => 'Възвръщане към предишна версия',
+'deletecomment' => 'Причина за изтриването',
+'imagereverted' => 'Възвръщането към предишна версия беше успешно.',
+'rollback' => 'Връщане назад на промените', #Roll back edits
+'rollback_short' => 'Връщане',
+'rollbacklink' => 'връщане', #rollback
+'rollbackfailed' => 'Връщането не сполучи', #Rollback failed
+'cantrollback' => 'Промяната не може да се извърши. Последният автор е единственият собственик на страницата.',
+'alreadyrolled' => 'Редакцията на [[:$1]], направена от [[Потребител:$2|$2]] ([[Потребител беседа:$2|Беседа]]), не може да се върне назад. Някой друг вече е редактирал страницата или е върнал назад промените.
+
+Последната редакция е на [[Потребител:$3|$3]] ([[Потребител беседа:$3|Беседа]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Коментарът на редакцията е бил: „<i>$1</i>“.',
+'revertpage' => 'Премахване на [[Special:Contributions/$2|редакции на $2]], възвръщане към последната версия на $1',
+# TODO
+'sessionfailure' => 'There seems to be a problem with your login session; this action has been canceled as a precaution against session hijacking. Please hit „back“ and reload the page you came from, then try again.',
+'protectlogpage' => 'Дневник на защитата',
+'protectlogtext' => 'Списък на защитите и техните сваляния за страницата.
+За повече информация вижте [[Project:Защитена страница]].',
+'protectedarticle' => 'защитена „[[$1]]“',
+'unprotectedarticle' => 'сваляне на защитата на „[[$1]]“',
+'protectsub' => '(Защитаване на „$1“)',
+'confirmprotecttext' => 'Наистина ли искате да защитите страницата?',
+'confirmprotect' => 'Потвърдете защитата',
+'protectmoveonly' => 'Защита само от премествания',
+'protectcomment' => 'Причина за защитата',
+'unprotectsub' => '(Сваляне на защитата на „$1“)',
+'confirmunprotecttext' => 'Наистина ли искате да свалите защитата на страницата?',
+'confirmunprotect' => 'Потвърдете свалянето на защитата',
+'unprotectcomment' => 'Причина за сваляне на защитата',
+
+# Undelete
+'undelete' => 'Преглед на изтрити страници',
+'undeletepage' => 'Преглед и възстановяване на изтрити страници',
+'viewdeletedpage' => 'Преглед на изтрити страници',
+'undeletepagetext' => 'Следните страници бяха изтрити, но се намират все още
+в архива и могат да бъдат възстановени. Архивът може да се почиства от време на време.',
+'undeletearticle' => 'Възстановяване на изтрита страница',
+'undeletehistorynoadmin' => 'Тази страница е била изтрита. В резюмето отдолу е посочена причината за това, заедно с информация за потребителите, редактирали страницата преди изтриването й. Конкретното съдържание на изтритите версии е достъпно само за администратори.',
+'undeleterevisions' => '$1 версии архивирани',
+'undeletehistory' => 'Ако възстановите страницата, всички версии ще бъдат върнати в историята.
+Ако след изтриването е създадена страница със същото име, възстановените версии ще се появят като по-ранна история, а текущата версия на страницата няма да бъде автоматично заменена.',
+'undeleterevision' => 'Изтрита версия на $1',
+'undeletebtn' => 'Възстановяване!',
+'undeletedarticle' => '„[[$1]]“ беше възстановена',
+'undeletedrevisions' => '$1 версии бяха възстановени',
+
+# Namespace form on various pages
+'namespace' => 'Именно пространство:',
+'invert' => 'Обръщане на избора',
+
+# Contributions
+#
+'contributions' => 'Приноси',
+'mycontris' => 'Моите приноси',
+'contribsub' => 'За $1',
+'nocontribs' => 'Не са намерени промени, отговарящи на критерия.',
+'ucnote' => 'Показани са последните <b>$1</b> промени, извършени от този потребител през последните <b>$2</b> дни.',
+'uclinks' => 'Показване на последните $1 промени; показване на последните $2 дни.',
+'uctop' => ' (последна)',
+'newbies' => 'новаци',
+
+# What links here
+#
+'whatlinkshere' => 'Какво сочи насам',
+'notargettitle' => 'Няма цел',
+'notargettext' => 'Не указахте целева страница или потребител, върху която/който да се изпълни действието.',
+'linklistsub' => '(Списък с препратки)',
+'linkshere' => 'Следните страници сочат насам:',
+'nolinkshere' => 'Няма страници, сочещи насам.',
+'isredirect' => 'пренасочваща страница',
+
+# Block/unblock IP
+#
+'blockip' => 'Блокиране на потребител',
+'blockiptext' => 'Използвайте долния формуляр, за да забраните правото на писане
+на определен IP-адрес или потребител.
+Това трябва да се направи само, за да се предотвратят прояви на вандализъм,
+и в съответствие с [[Project:Линия_на_поведение|линията на поведение]] на {{SITENAME}}.
+Посочете също и причина за блокирането (например, заглавия на страници, станали обект на вандализъм).
+
+Срокът за изтичане на блокирането се въвежда според установения формат на ГНУ, описан в [http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html ръководството], например: „1 hour“, „2 days“, „next Wednesday“, „1 January 2017“. Неограничено блокиране може да се зададе чрез „indefinite“ или „infinite“.',
+'ipaddress' => 'IP-адрес',
+'ipadressorusername' => 'IP-адрес или потребител',
+'ipbexpiry' => 'Срок',
+'ipbreason' => 'Причина',
+'ipbsubmit' => 'Блокиране на потребителя',
+'ipbother' => 'Друг срок',
+'ipboptions' => 'Два часа:2 hours,Един ден:1 day,Три дни:3 days,Една седмица:1 week,Две седмици:2 weeks,Един месец:1 month,Три месеца:3 months,Шест месеца:6 months,Една година:1 year,Докато свят светува:infinite',
+'ipbotheroption' => 'друг',
+'badipaddress' => 'Невалиден IP-адрес или грешно име на потребител',
+'blockipsuccesssub' => 'Блокирането беше успешно',
+'blockipsuccesstext' => '„[[{{ns:Special}}:Contributions/$1|$1]]“ беше блокиран.
+<br />Вижте [[{{ns:Special}}:Ipblocklist|списъка на блокираните IP-адреси]], за да прегледате всички блокирания.',
+'unblockip' => 'Отблокиране на потребител',
+'unblockiptext' => 'Използвайте долния формуляр, за да възстановите правото на писане на по-рано блокиран IP-адрес или потребител.',
+'ipusubmit' => 'Отблокиране на адреса',
+'ipblocklist' => 'Списък на блокирани IP-адреси и потребители',
+'blocklistline' => '$1, $2 е блокирал $3 ($4)',
+'infiniteblock' => 'неограничено',
+'expiringblock' => 'изтича на $1',
+'ipblocklistempty' => 'Списъкът на блокиранията е празен.',
+'blocklink' => 'блокиране',
+'unblocklink' => 'отблокиране',
+'contribslink' => 'приноси',
+'autoblocker' => 'Бяхте автоматично блокиран, тъй като неотдавна IP-адресът ви е бил ползван от текущо блокирания потребител „$1“. Причината за неговото блокиране е: „\'\'\'$2\'\'\'“.',
+'blocklogpage' => 'Дневник на блокиранията',
+'blocklogentry' => 'блокиране на „[[$1]]“ със срок на изтичане $2',
+'blocklogtext' => 'Това е дневник на блокиранията и отблокиранията, извършени от този потребител. Автоматично блокираните IP-адреси не са показани. Вижте [[Special:Ipblocklist|списъка на блокираните IP-адреси]] за текущото състояние на блокиранията.',
+'unblocklogentry' => 'отблокиране на „$1“',
+'range_block_disabled' => 'Възможността на администраторите да задават интервали при IP-адресите е изключена.',
+'ipb_expiry_invalid' => 'Невалиден срок на изтичане.',
+'ip_range_invalid' => 'Невалиден интервал за IP-адреси.',
+'proxyblocker' => 'Блокировач на проксита',
+'proxyblockreason' => 'Вашият IP-адрес беше блокиран, тъй като е отворено прокси. Моля, свържете се с Вашия доставчик на интернет и го информирайте за този сериозен проблем в сигурността.',
+'proxyblocksuccess' => 'Готово.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Вашият IP-адрес е записан като отворено прокси в [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Вашият IP-адрес е записан като отворено прокси в [http://www.sorbs.net SORBS] DNSBL. Не можете да създадете сметка.',
+
+# Developer tools
+#
+'lockdb' => 'Заключване на базата от данни',
+'unlockdb' => 'Отключване на базата от данни',
+'lockdbtext' => 'Заключването на базата от данни ще попречи на всички потребители да редактират страници, да сменят своите настройки, да редактират своите списъци за наблюдение и на всички други техни действия, изискващи промени в базата от данни.
+Моля, потвърдете, че искате точно това и ще отключите базата от данни,
+когато привършите с работата по подръжката.',
+'unlockdbtext' => 'Отключването на базата от данни ще възстанови способността на потребителите да редактират страници, да сменят своите настройки, да редактират своите списъци за наблюдение и изпълнението на всички други действия, изискващи промени в базата от данни.
+Моля, потвърдете, че искате точно това.',
+'lockconfirm' => 'Да, наистина искам да заключа базата от данни.',
+'unlockconfirm' => 'Да, наистина искам да отключа базата от данни.',
+'lockbtn' => 'Заключване на базата от данни',
+'unlockbtn' => 'Отключване на базата от данни',
+'locknoconfirm' => 'Не сте отметнали кутийката за потвърждение.',
+'lockdbsuccesssub' => 'Заключването на базата от данни беше успешно',
+'unlockdbsuccesssub' => 'Отключването на базата от данни беше успешно',
+'lockdbsuccesstext' => 'Базата от данни на {{SITENAME}} беше заключена.
+<br />Не забравяйте да отключите базата от данни, когато привършите с работата по поддръжката.',
+'unlockdbsuccesstext' => 'Базата от данни на {{SITENAME}} беше отключена.',
+
+# Make sysop
+'makesysoptitle' => 'Превръщане на потребител в администратор',
+'makesysoptext' => 'Този формуляр се използва от бюрократи за превръщане на обикновени потребители в администратори.
+
+Въведете името на потребителя в полето и натиснете бутона, за да направите съответния потребител администратор',
+'makesysopname' => 'Име на потребителя:',
+'makesysopsubmit' => 'Превръщане на потребителя в администратор',
+'makesysopok' => '<b>Потребителят „$1“ беше направен администратор</b>.',
+'makesysopfail' => '<b>Потребителят „$1“ не беше направен администратор. (Правилно ли въведохте името?)</b>',
+'setbureaucratflag' => 'Вдигане на флага „бюрократ“',
+'rightslogtext' => 'Това е дневник на промените на потребителски права.',
+'rights' => 'Права:',
+'set_user_rights' => 'Даване на потребителски права',
+'user_rights_set' => '<b>Потребителските права на „$1“ са променени</b>',
+'set_rights_fail' => '<b>Потребителските права на „$1“ не бяха променени. (Правилно ли въведохте името?)</b>',
+'makesysop' => 'Превръщане на потребител в администратор',
+'already_sysop' => 'Този потребител беше вече администратор',
+'already_bureaucrat' => 'Този потребител беше вече бюрократ',
+
+# Move page
+#
+'movepage' => 'Преместване на страница',
+'movepagetext' => "Посредством долния формуляр можете да преименувате страница, премествайки цялата й история на новото име. Старото заглавие ще се превърне в пренасочваща страница.
+Препратките към старата страница няма да бъдат променени; затова проверете за двойни или невалидни пренасочвания.
+Вие сами би трябвало да се убедите в това, дали препратките продължават да сочат там, където се предполага.
+
+Страницата '''няма''' да бъде преместена, ако вече съществува страница с новото име, освен ако е празна или пренасочване и няма редакционна история.
+
+'''ВНИМАНИЕ!'''
+Това може да е голяма и неочаквана промяна за известна страница. Уверете се, че разбирате последствията, преди да продължите.",
+'movepagetalktext' => 'Съответната дискусионна страница, ако съществува, ще бъде автоматично преместена заедно с нея, \'\'\'освен ако:\'\'\'
+* не местите страницата от едно именно пространство в друго,
+* вече съществува непразна дискусионна страница с това име или
+* не сте отметнали долната кутийка.
+
+В тези случаи, ако желаете, ще е необходимо да преместите страницата ръчно.',
+'movearticle' => 'Преместване на страница',
+'movenologin' => 'Не сте влезли',
+'movenologintext' => 'Необходимо е да [[Special:Userlogin|влезете]], за да може да премествате страници.',
+'newtitle' => 'Към ново заглавие',
+'movepagebtn' => 'Преместване',
+'pagemovedsub' => 'Преместването беше успешно',
+'pagemovedtext' => 'Страницата „[[$1]]“ беше преместена под името „[[$2]]“.',
+'articleexists' => 'Вече съществува страница с това име или името, което сте избрали, е невалидно. Моля, изберете друго име.',
+'talkexists' => "'''Страницата беше успешно преместена, но без съответната дискусионна страница, защото под новото име има една съществуваща. Моля, обединете ги ръчно.'''",
+'movedto' => 'преместена като',
+'movetalk' => 'Преместване и на дискусионната страница, ако е приложимо.',
+'talkpagemoved' => 'Съответната дискусионна страница също беше преместена.',
+'talkpagenotmoved' => 'Съответната дискусионна страница <strong>не</strong> беше преместена.',
+'1movedto2' => '„$1“ преместена като „$2“',
+'1movedto2_redir' => '„$1“ преместена като „$2“ (върху пренасочване)',
+'movelogpage' => 'Дневник на преместванията',
+'movelogpagetext' => 'По-долу е показан списък на преместванията.',
+'movereason' => 'Причина',
+'revertmove' => 'връщане',
+'delete_and_move' => 'Изтриване и преместване',
+'delete_and_move_text' =>
+'== Наложително изтриване ==
+
+Целевата страница „[[$1]]“ вече съществува. Искате ли да я изтриете, за да освободите място за преместването?',
+'delete_and_move_reason' => 'Изтрита, за да се освободи място за преместване',
+'selfmove' => 'Страницата не може да бъде преместена, тъй като целевото име съвпада с първоначалното й заглавие.',
+'immobile_namespace' => 'Целевото заглавие е от специален тип. Не е възможно местенето на страници в това именно пространство.',
+
+# Export
+'export' => 'Изнасяне на страници',
+'exporttext' => "Тук можете да изнесете като XML текста и историята на една или повече страници. Получените данни можете да:
+* вмъкнете в друг сайт, използващ софтуера на МедияУики,
+* обработвате или
+* просто запазите за лично ползване.
+
+За да изнесете няколко страници, въвеждайте всяко ново заглавие на '''нов ред'''. След това изберете дали искате само текущата версия (заедно с информация за последната редакция) или всички версии (заедно с текущата) на страницата.
+
+Ако желаете само текущата версия, бихте могли да използвате препратка от вида [[Special:Export/България]] за страницата [[България]].",
+'exportcuronly' => 'Включване само на текущата версия, а не на цялата история',
+
+# Namespace 8 related
+
+'allmessages' => 'Системни съобщения',
+'allmessagesname' => 'Име',
+'allmessagesdefault' => 'Текст по подразбиране',
+'allmessagescurrent' => 'Текущ текст',
+'allmessagestext' => 'Това е списък на системните съобщения, намиращи се в именното пространство „МедияУики“',
+'allmessagesnotsupportedUI' => 'Текущо избраният език за интерфейса <b>$1</b> не се поддържа от <em>Специални:AllMessages</em> на сайта.',
+'allmessagesnotsupportedDB' => 'Възможността за използване на страници от именното пространство „МедияУики“ за генериране на интерфейсните съобщения е изключена (<code>LocalSettings.php: wgUseDatabaseMessages = false</code>).',
+# Thumbnails
+'thumbnail-more' => 'Увеличаване',
+'missingimage' => '<b>Липсваща картинка</b><br /><i>$1</i>',
+'filemissing' => 'Липсващ файл',
+
+# Special:Import
+'import' => 'Внасяне на страници',
+'importinterwiki' => 'Внасяне чрез Трансуики',
+'importtext' => 'Моля, изнесете файла от изходното уики, използвайки инструмента „Special:Export“, съхранете го на Вашия диск и го качете тук.',
+'importfailed' => 'Внасянето беше неуспешно: $1',
+'importnotext' => 'Празно',
+'importsuccess' => 'Внасянето беше успешно!',
+'importhistoryconflict' => 'Съществува версия от историята, която си противоречи с тази (възможно е страницата да е била вече внесена)',
+# TODO
+'importnosources' => 'No transwiki import sources have been defined and direct history uploads are disabled.',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+
+# tooltip help for the main actions
+'tooltip-search' => 'Претърсване на {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Отбелязване на промяната като малка [alt-i]',
+'tooltip-save' => 'Съхраняване на промените [alt-s]',
+'tooltip-preview' => 'Предварителен преглед, моля, използвайте го преди да съхраните! [alt-p]',
+'tooltip-diff' => 'Показване на направените от Вас промени по текста [alt-v]',
+'tooltip-compareselectedversions' => 'Показване на разликите между двете избрани версии на страницата [alt-v]',
+'tooltip-watch' => 'Добавяне на страницата към списъка Ви за наблюдение [alt-w]',
+
+# stylesheets
+'monobook.css' => '/* чрез редактиране на този файл можете да промените облика Monobook */',
+#'monobook.js' => '/* чрез редактиране на този файл можете да добавяте функции на Javascript за облика Monobook */',
+
+# TODO: превод
+# Metadata
+'nodublincore' => 'Dublin Core RDF metadata disabled for this server.',
+'nocreativecommons' => 'Creative Commons RDF metadata disabled for this server.',
+'notacceptable' => 'Сървърът не може да предостави данни във формат, който да се разпознава от клиента Ви.',
+
+# Attribution
+'anonymous' => 'Анонимен потребител(и) на {{SITENAME}}',
+'siteuser' => 'потребители на {{SITENAME}} $1',
+'lastmodifiedatby' => 'Последната промяна на страницата е извършена от $3 на $2, $1.',
+'and' => 'и',
+'othercontribs' => 'Основаващо се върху работа на $1.',
+'others' => 'други',
+'siteusers' => 'потребителите на {{SITENAME}} $1',
+'creditspage' => 'Библиография и източници',//'Page credits',
+'nocredits' => 'Няма въведени източници или библиография',//'There is no credits info available for this page.',
+
+# Spam protection
+'spamprotectiontitle' => 'Филтър за защита от спам',
+'spamprotectiontext' => 'Страницата, която искахте да съхраните, беше блокирана от филтъра против спам. Това обикновено е причинено от препратка към външен сайт.',
+'spamprotectionmatch' => 'Следният текст предизвика включването на филтъра: $1',
+'subcategorycount' => 'Тази категория има $1 подкатегории.',
+'categoryarticlecount' => 'Тази категория съдържа $1 страници.',
+'listingcontinuesabbrev' => ' продълж.',
+
+# Info page
+'infosubtitle' => 'Информация за страницата',
+'numedits' => 'Брой редакции (страница):',
+'numtalkedits' => 'Брой редакции (дискусионна страница):',
+'numwatchers' => 'Брой наблюдатели:',
+'numauthors' => 'Брой различни автори (страница):',
+'numtalkauthors' => 'Брой различни автори (дискусионна страница):',
+
+# Math
+'mw_math_png' => 'Използване винаги на PNG',
+'mw_math_simple' => 'HTML при опростен TeX, иначе PNG',
+'mw_math_html' => 'HTML по възможност, иначе PNG',
+'mw_math_source' => 'Оставяне като TeX (за текстови браузъри)',
+'mw_math_modern' => 'Препоръчително за нови браузъри',
+'mw_math_mathml' => 'MathML по възможност (експериментално)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Отбелязване като проверена версия',//'Mark as patrolled',
+'markaspatrolledtext' => 'Отбелязване на версията като проверена',//'Mark this article as patrolled',
+'markedaspatrolled' => 'Проверена версия', //'Marked as patrolled',
+'markedaspatrolledtext' => 'Избраната версия беше отбелязана като проверена.',//'The selected revision has been marked as patrolled.',
+'rcpatroldisabled' => 'Патрулът е деактивиран', //'Recent Changes Patrol disabled',
+'rcpatroldisabledtext' => 'Патрулът на последните промени е деактивиран',//'The Recent Changes Patrol feature is currently disabled.',
+
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '
+ /* чрез редактиране на този файл можете да промените някои неща на Javascript за облика Monobook */
+ /* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Вашата потребителска страница\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Потребителската страница за адреса, от който редактирате\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Вашата дискусионна страница\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Дискусия относно редакциите от този адрес\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Вашите настройки\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Списък на страници, чиито промени сте избрали да наблюдавате\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Списък на Вашите приноси\');
+ ta[\'pt-login\'] = new Array(\'o\',\'В момента не сте влезли. Насърчаваме Ви да влезете, въпреки че не е задължително.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Насърчаваме Ви да влезете, въпреки че не е задължително.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Излизане от {{SITENAME}}\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Беседа относно страницата\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Можете да редактирате страницата. Моля, използвайте бутона за предварителен преглед преди да съхраните.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Добавяне на коментар към страницата\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Страницата е защитена. Можете да разгледате изходния й код.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Предишни версии на страницата\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Защитаване на страницата\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Изтриване на страницата\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Възстановяване на изтрити редакции на страницата\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Преместване на страницата\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Добавяне на страницата към списъка Ви за наблюдение\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Премахване на страницата от списъка Ви за наблюдение\');
+ ta[\'search\'] = new Array(\'f\',\'Претърсване на {{SITENAME}}\');
+ ta[\'p-logo\'] = new Array(\'\',\'Началната страница\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Началната страница\');
+ ta[\'n-portal\'] = new Array(\'\',\'Информация за проекта\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Информация за текущите събития по света\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Списък на последните промени в {{SITENAME}}\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Случайна страница\');
+ ta[\'n-help\'] = new Array(\'\',\'Помощната страница\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Подкрепете {{SITENAME}}\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Списък на всички страници, сочещи насам\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Последните промени на страници, сочени от тази страница\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed за страницата\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed за страницата\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Показване на приносите на потребителя\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Изпращане на писмо на потребителя\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Качване на файлове\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Списък на всички специални страници\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Преглед на основната страница\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Преглед на потребителската страница\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Преглед на медийната страница\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Това е специална страница, която не може да се редактира.\');
+ ta[\'ca-nstab-project\'] = new Array(\'c\',\'Преглед на проектната страница\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Преглед на страницата на файла\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Преглед на системното съобщение\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Преглед на шаблона\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Преглед на помощната страница\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Преглед на категорийната страница\');',
+
+# image deletion
+'deletedrevision' => 'Изтрита стара версия $1.',
+
+# browsing diffs
+'previousdiff' => '← Предишна разлика',
+'nextdiff' => 'Следваща разлика →',
+
+'imagemaxsize' => 'Ограничаване на картинките на описателните им страници до:',
+'thumbsize' => 'Размери на миникартинките:',
+'showbigimage' => 'Сваляне на версия с високо качество ($1x$2, $3 КБ)',
+'newimages' => 'Галерия на новите файлове',
+'showhidebots' => '($1 на ботове)',
+'noimages' => 'Няма нищо.',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Потребител:',
+'speciallogtitlelabel' => 'Заглавие:',
+
+'passwordtooshort' => 'Паролата Ви е прекалено къса: трябва да съдържа поне $1 знака.',
+
+# Media Warning
+# TODO Превод
+'mediawarning' => '\'\'\'Внимание\'\'\': This file may contain malicious code, by executing it your system may be compromised.
+<hr />',
+
+'fileinfo' => '$1 КБ, MIME type: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Метаданни',
+# TODO Превод
+# Exif tags
+'exif-imagewidth' =>'Ширина',
+'exif-imagelength' =>'Височина',
+'exif-artist' =>'Автор',
+
+
+# external editor support
+'edit-externally' => 'Редактиране на файла чрез външно приложение',
+'edit-externally-help' => 'За повече информация прегледайте [http://meta.wikimedia.org/wiki/Help:External_editors указанията за настройките].',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'всички',
+'imagelistall' => 'всички',
+'watchlistall1' => 'всички',
+'watchlistall2' => 'всички',
+'namespacesall' => 'всички',
+
+# TODO
+# E-mail address confirmation
+'confirmemail_invalid' => 'Грешен код за потвърждение. Вероятно кодът за потвърждение е остарял.',
+'confirmemail_success' => 'Адресът ви за електронна поща беше потвърден. Вече можете да влезете и да се наслаждавате на уикито.',
+'confirmemail_loggedin' => 'Адресът ви за електронна поща беше потвърден.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Пълно и точно съвпадение',
+'searchfulltext' => 'Претърсване на целия текст',
+'createarticle' => 'Създаване на статия',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackbacks for this article:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Изтриване])',
+#'trackbacklink' => 'Trackback',
+#'trackbackdeleteok' => 'The trackback was successfully deleted.',
+
+# delete conflict
+
+'deletedwhileediting' => 'Внимание: Страницата е била изтрита, откакто сте започнали да я редактирате!',
+'confirmrecreate' => 'Потребител [[Потребител:$1|$1]] ([[Потребител беседа:$1|беседа]]) е изтрил страницата, откакто сте започнали да я редактирате, давайки следното обяснение:
+: \'\'$2\'\'
+Моля, потвърдете, че наистина желаете да създадете страницата отново.',
+'recreate' => 'Ново създаване',
+
+'unit-pixel' => 'px',
+);
+
+
+?>
diff --git a/languages/messages/MessagesBm.php b/languages/messages/MessagesBm.php
new file mode 100644
index 000000000000..8dd53fe4c8b1
--- /dev/null
+++ b/languages/messages/MessagesBm.php
@@ -0,0 +1,9 @@
+<?php
+/** Bambara (Bamanankan)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'fr';
+?>
diff --git a/languages/messages/MessagesBn.php b/languages/messages/MessagesBn.php
new file mode 100644
index 000000000000..7c4fdeeb4097
--- /dev/null
+++ b/languages/messages/MessagesBn.php
@@ -0,0 +1,133 @@
+<?php
+/** Bengali (বাংলা)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_SPECIAL => 'বিশেষ',
+ NS_MAIN => '',
+ NS_TALK => 'আলাপ',
+ NS_USER => 'ব্যবহারকারী',
+ NS_USER_TALK => 'ব্যবহারকারী_আলাপ',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_আলাপ',
+ NS_IMAGE => 'চিত্র',
+ NS_IMAGE_TALK => 'চিত্র_আলাপ',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_আলাপ'
+);
+$datePreferences = false;
+$digitTransformTable = array(
+ '0' => '০',
+ '1' => '১',
+ '2' => '২',
+ '3' => '৩',
+ '4' => '৪',
+ '5' => '৫',
+ '6' => '৬',
+ '7' => '৭',
+ '8' => '৮',
+ '9' => '৯'
+);
+
+
+$messages = array(
+# Dates
+
+'sunday' => 'রবিবার',
+'monday' => 'সোমবার',
+'tuesday' => 'মঙ্গলবার',
+'wednesday' => 'বুধবার',
+'thursday' => 'বৃহস্পতিবার',
+'friday' => 'শুক্রবার',
+'saturday' => 'শনিবার',
+'january' => 'জানুয়ারী',
+'february' => 'ফেব্রুয়ারী',
+'march' => 'মার্চ',
+'april' => 'এপ্রিল',
+'may_long' => 'মে',
+'june' => 'জুন',
+'july' => 'জুলাই',
+'august' => 'আগস্ট',
+'september' => 'সেপ্টেম্বর',
+'october' => 'অক্টোবর',
+'november' => 'নভেম্বর',
+'december' => 'ডিসেম্বর',
+'jan' => 'জানু',
+'feb' => 'ফেব্রু',
+'mar' => 'মার্চ',
+'apr' => 'এপ্রিল',
+'may' => 'মে',
+'jun' => 'জুন',
+'jul' => 'জুলাই',
+'aug' => 'আগস্ট',
+'sep' => 'সেপ্টে',
+'oct' => 'অক্টো',
+'nov' => 'নভে',
+'dec' => 'ডিসে',
+
+# Bits of text used by many pages:
+#
+
+'mainpage' => 'প্রধান পাতা',
+'about' => 'বৃত্তান্ত',
+'aboutsite' => '{{SITENAME}}র বৃত্তান্ত', // TODO: grammar
+'aboutpage' => '{{ns:project}}:বৃত্তান্ত',
+'help' => 'সহায়িকা',
+'helppage' => '{{ns:project}}:সহায়িকা',
+'bugreports' => 'ত্রুটি বিবরণী',
+'bugreportspage' => '{{ns:project}}:ত্রুটি_বিবরণী',
+'faq' => 'প্রশ্নোত্তর',
+'faqpage' => '{{ns:project}}:প্রশ্নোত্তর',
+'edithelp' => 'সম্পাদনা সহায়িকা',
+'edithelppage' => '{{ns:project}}:কিভাবে_একটি_পৃষ্ঠা_সম্পাদনা_করবেন',
+'cancel' => 'বাতিল কর',
+'qbfind' => 'খঁুজে দেখ',
+'qbbrowse' => 'ঘুরে দেখ',
+'qbedit' => 'সম্পাদনা কর',
+'qbpageoptions' => 'এ পৃষ্ঠার বিকল্পসমূহ',
+'qbpageinfo' => 'পৃষ্ঠা-সংক্রান্ত তথ্য',
+'qbmyoptions' => 'আমার পছন্দ',
+'mypage' => 'আমার পাতা',
+'mytalk' => 'আমার কথাবার্তা',
+'currentevents' => 'সমসাময়িক ঘটনা',
+'errorpagetitle' => 'ভুল',
+'returnto' => 'ফিরে যাও $1.',
+'whatlinkshere' => 'যেসব পাতা থেকে এখানে সংযোগ আছে',
+'help' => 'সহায়িকা',
+'search' => 'খঁুজে দেখ',
+'searchbutton' => 'খঁুজে দেখ',
+'go' => 'চল',
+'searcharticle' => 'চল',
+'history' => 'এ পৃষ্ঠার ইতিহাস',
+'printableversion' => 'ছাপার যোগ্য সংস্করণ',
+'editthispage' => 'এই পৃষ্ঠাটি সম্পাদনা করুন',
+'deletethispage' => 'এই পৃষ্ঠাটি মুছে ফেলুন',
+'protectthispage' => 'এই পৃষ্ঠাটি সংরক্ষণ করুন',
+'unprotectthispage' => 'এই পৃষ্ঠার সংরক্ষণ ছেড়ে দিন',
+'newpage' => 'নতুন পাতা',
+'talkpage' => 'এই পৃষ্ঠা নিয়ে আলোচনা করুন',
+'articlepage' => 'নিবন্ধ দেখুন',
+'userpage' => 'ব্যাবহারকারীর পাতা দেখুন',
+'projectpage' => 'মেটা-পাতা দেখুন',
+'imagepage' => 'ছবির পাতা দেখুন',
+'viewtalkpage' => 'আলোচনা দেখুন',
+'otherlanguages' => 'অন্যান্য ভাষা',
+'redirectedfrom' => '($1 থেকে ঘুরে এসেছে)',
+'lastmodifiedat' => 'এ পৃষ্ঠায় শেষ পরিবর্তন হয়েছিল $2, $1.',
+'viewcount' => 'এ পৃষ্ঠা দেখা হয়েছে $1 বার।',
+'nbytes' => '$1 বাইট',
+'ok' => 'ঠিক আছে',
+'retrievedfrom' => '\'$1\' থেকে আনীত',
+'newmessageslink' => 'নতুন বার্তা',
+'editsection'=>'সম্পাদনা করুন',
+'editold'=>'সম্পাদনা করুন',
+'toc' => 'সূচীপত্র',
+'showtoc' => 'দেখাও',
+'hidetoc' => 'সরিয়ে রাখ',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesBo.php b/languages/messages/MessagesBo.php
new file mode 100644
index 000000000000..ce8b4411a695
--- /dev/null
+++ b/languages/messages/MessagesBo.php
@@ -0,0 +1,20 @@
+<?php
+/** Tibetan (བོད་ཡིག)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$digitTransformTable = array(
+ '0' => '༠',
+ '1' => '༡',
+ '2' => '༢',
+ '3' => '༣',
+ '4' => '༤',
+ '5' => '༥',
+ '6' => '༦',
+ '7' => '༧',
+ '8' => '༨',
+ '9' => '༩'
+);
+?>
diff --git a/languages/messages/MessagesBpy.php b/languages/messages/MessagesBpy.php
new file mode 100644
index 000000000000..7fb73a6260a8
--- /dev/null
+++ b/languages/messages/MessagesBpy.php
@@ -0,0 +1,299 @@
+<?php
+/** Bishnupriya Manipuri (বিষ্ণুপ্রিয়া মণিপুরী)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ * @Author Uttam Singha, Dec 2006
+ */
+$rtl = false;
+$namespaceNames = array(
+ NS_MEDIA => 'মিডিয়া',
+ NS_SPECIAL => 'বিশেষ',
+ NS_MAIN => '',
+ NS_TALK => 'য়্যারী',
+ NS_USER => 'আতাকুরা',
+ NS_USER_TALK => 'আতাকুরার_য়্যারী',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_য়্যারী',
+ NS_IMAGE => 'ছবি',
+ NS_IMAGE_TALK => 'ছবি_য়্যারী',
+ NS_MEDIAWIKI => 'মিডিয়াউইকি',
+ NS_MEDIAWIKI_TALK => 'মিডিয়াউইকির_য়্যারী',
+ NS_TEMPLATE => 'মডেল',
+ NS_TEMPLATE_TALK => 'মডেলর_য়্যারী',
+ NS_HELP => 'পাংলাক',
+ NS_HELP_TALK => 'পাংলাকর_য়্যারী',
+ NS_CATEGORY => 'থাক',
+ NS_CATEGORY_TALK => 'থাকর_য়্যারী',
+);
+
+$messages = array(
+# Dates
+
+'sunday' => 'লামুইসিং',
+'monday' => 'নিংথৌকাপা',
+'tuesday' => 'লেইপাকপা',
+'wednesday' => 'ইনসাইনসা',
+'thursday' => 'সাকলসেন',
+'friday' => 'ইরেই',
+'saturday' => 'থাংচা',
+'january' => 'জানুয়ারী',
+'february' => 'ফেব্রুয়ারী',
+'march' => 'মার্চ',
+'april' => 'এপ্রিল',
+'may_long' => 'মে',
+'june' => 'জুন',
+'july' => 'জুলাই',
+'august' => 'আগস্ট',
+'september' => 'সেপ্টেম্বর',
+'october' => 'অক্টোবর',
+'november' => 'নভেম্বর',
+'december' => 'ডিসেম্বর',
+'jan' => 'জানু',
+'feb' => 'ফেব্রু',
+'mar' => 'মার্চ',
+'apr' => 'এপ্রিল',
+'may' => 'মে',
+'jun' => 'জুন',
+'jul' => 'জুলাই',
+'aug' => 'আগস্ট',
+'sep' => 'সেপ্টে',
+'oct' => 'অক্টো',
+'nov' => 'নভে',
+'dec' => 'ডিসে',
+
+# Bits of text used by many pages:
+#
+
+'about' => 'বারে',
+'aboutpage' => '{{ns:project}}:বারে',
+'aboutsite' => '{{SITENAME}}র বারে',
+'accmailtext' => '"$1"-র খন্তাচাবি(password) $2-রাঙ দিয়াপেঠৱাদেনা ইল।',
+'accmailtitle' => 'খন্তাচাবি(password) দিয়াপেঠৱা দিলাং।',
+'accountcreated' => 'একাউন্টহান হঙকরানি ইল',
+'accountcreatedtext' => 'আতাকুরা $1 -র কা একাউন্টহান হঙকরানি ইল।',
+'acct_creation_throttle_hit' => 'ঙাক্করেদিবাং, তি এবাকাপেয়া $1হান অ্যাকাউন্ট হংকরেবেলাসত৷ অতাত্ত বপ হঙকরানির য়্যাথাং নেই।৷',
+'actioncomplete' => 'কামহান লমিল।',
+'addedwatch' => 'তালাবির তালিকাহাত থনা ইল',
+'addedwatchtext' => '"$1" পাতা এহান তর [[Special:Watchlist|আহির-আরুম তালিকা]]-ত তিলকরানি ইল। পিসেদে এরে পাতা এহান বারো পাতা এহানর লগে সাকেই আসে য়্যারী পাতাত অইতই হারি জাতর পতানি এহানাত তিলকরানি অইতই। অতাবাদেউ [[Special:Recentchanges|হাদি এহানর পতানিহানি]]-ত পাতা এহানরে \'\'\'গাঢ়করা\'\'\' মেয়েকে দেহা দেনা অইতই যাতে তি নুঙিকরে পাতা এহান চিনে পারবেতা। <p>পিসেদে তি পাতা এহানরে থেইকরানি মনেইলে "আহির-আরুমেত্ত থেইকরেদে" ট্যাবগত ক্লিক করিস৷',
+'allarticles' => 'নিবন্ধহাবি',
+'allinnamespace' => 'পাতাহানি হাবি ($1 নাঙরজাগা)',
+'allmessages' => 'সিস্টেমর পৌহানি',
+'allmessagescurrent' => 'হাদি এহানর ৱাহি',
+'allmessagesmodified' => 'পতাসি অতা হুদ্দা দেহাদে',
+'allmessagesname' => 'নাং',
+'allmessagestext' => 'তলে মিডিয়াউইকি: নাঙরজাগাত পানা একরের সিস্টেম পৌহানির তালিকাহান দেনা ইল।',
+'allowemail' => 'আরতা(ব্যবহার করেকুরা)ই ইমেইল করানির য়্যাথাং দে।',
+'allpages' => 'হাবি পাতাহানি',
+'allpagesbadtitle' => 'The given page title was invalid or had an inter-language or inter-wiki prefix. It may contain one more characters which cannot be used in titles.',
+'allpagesfrom' => 'যেহাত্ত অকরিসি অহাত্ত পাতাহানি দেহাদেঃ',
+'allpagesnext' => 'থাঙনাত',
+'allpagesprefix' => 'মেয়েক এগন অকরিসি ৱাহির পাতাহানি দেহাদেঃ',
+'allpagesprev' => 'আলথকে',
+'allpagessubmit' => 'হাত',
+'alphaindexline' => '$1 ত $2',
+'already_bureaucrat' => 'আতাকুরা এগ এচুদিনে ব্যুরোক্র্যাটগ ইয়াপরিলগাহে',
+'already_sysop' => 'আতাকুরা এগ এচুদিনে ডান্ডি(প্রশাসক)গ ইয়াপরিলগাহে',
+'alreadyloggedin' => '<strong>আতাকুরা $1, তি আগেত্তর ভিতরে হমিয়া আসতগহে!</strong><br />',
+'alreadyrolled' => 'Cannot rollback last edit of [[$1]]
+by [[User:$2|$2]] ([[User talk:$2|Talk]]); someone else has edited or rolled back the page already.
+
+Last edit was by [[User:$3|$3]] ([[User talk:$3|Talk]]).',
+'ancientpages' => 'পুরানা পাতাহানি',
+'and' => 'বারো',
+'anoneditwarning' => '\'\'\'সিঙুইসঃ\'\'\' তি লগইন নাকরিসত। পতানির ইতিহাসহাত তর IP addressহান সিজিল ইতই।',
+'anontalk' => 'অচিনা এগর য়্যারির পাতা',
+'anontalkpagetext' => '<div id="anontalktext"><hr style="clear: both; margin-top:8px" /> \'\'এহান অচিনা অতার য়্যারির পাতাহান। এরে আইপি ঠিকানা (IP Address) এহানাত্ত লগ-ইন নাকরিয়া পতানিত মেইক্ষু অসিল। আক্কুস ক্ষেন্তামে আইপি ঠিকানা হামেসা বদল অর, বিশেষ করিয়া ডায়াল-আপ ইন্টারনেট, প্রক্সি সার্ভার মাহি ক্ষেত্র এতা সিলরতা, বারো আগত্ত বপ ব্যবহারকারেকুরার ক্ষেত্রত প্রযোজ্য ইতে পারে। অহানে তি নিশ্চকে এরে আইপি এহাত্ত উইকিপিডিয়াত হমিয়া কোন য়্যারী দেখর, অহান তরে নিঙকরিয়া নাউ ইতে পারে। অহানে হাবিত্ত হবা অর, তি যদি [[{{ns:Special}}:Userlogin|লগ-ইন করর, বা নৱা একাউন্ট খুলর]] অহানবুলতেউ লগ-ইন করলে কুঙগউ তর আইপি ঠিকানাহান, বারো অহানর মাতুঙে তর অবস্থানহান সুপকরেউ হার না পেইবা।\'\'<br /> [<small><span class="plainlinks">[http://www.dnsstuff.com/tools/ipall.ch?domain={{PAGENAMEE}} আইপি ঠিকানাহার পৌ] &middot; [http://www.dnsstuff.com/tools/tracert.ch?ip={{PAGENAMEE}} ট্রেসরাউট] &middot; [http://www.dnsstuff.com/tools/whois.ch?ip={{PAGENAMEE}} WHOIS] &middot; [http://www.dnsstuff.com/tools/whois.ch?server=whois.abuse.net&ip={{PAGENAMEE}} ৱাকাত] &middot; [http://www.dnsstuff.com/tools/city.ch?ip={{PAGENAMEE}} শহর] &middot; [http://www.dnsstuff.com/tools/ptr.ch?ip={{PAGENAMEE}} উল্টা ডিএনএস]</span></small>] [<small>\'\'\'আঞ্চলিক ইন্টারনেট নিবন্ধনর তালিকা\'\'\': <span class="plainlinks">[http://ws.arin.net/whois/?queryinput={{PAGENAMEE}} আমেরিকা] &middot; [http://www.ripe.net/fcgi-bin/whois?searchtext={{PAGENAMEE}} ইউরোপ] &middot; [http://www.afrinic.net/cgi-bin/whois?query={{PAGENAMEE}} আফ্রিকা] &middot; [http://www.apnic.net/apnic-bin/whois.pl?searchtext={{PAGENAMEE}} এশিয়া-প্যাসিফিক] &middot; [http://www.lacnic.net/cgi-bin/lacnic/whois?lg=EN&query={{PAGENAMEE}} লাতিন আমেরিকা ও ক্যারিবিয় এলাকা]</span></small>] </div>',
+'anonymous' => '{{SITENAME}}র বেনাঙর আতাকুরা(গি)',
+'articleexists' => 'ইতে পারে এরে শিরোনাঙর নিবন্ধহান হঙপরসেগা, নাইলে তি দিয়াসত শিরোনাং এহান দেনার য়্যাথাং নেই। কৃপা করিয়া আরাক শিরোনাং আহান দেনার হৎনা কর।',
+'articlepage' => 'নিবন্ধ চেইক',
+'articletitles' => 'যে পাতাহানি \'\'$1\'\' ন অকরাগ, অতার তালিকা',
+'autoredircomment' => '[[$1]]-ত যানার বারো-র্নিদেশ করানি ইল',
+'badaccess' => 'য়্যাথাঙে লালসে',
+'badarticleerror' => 'এরে পাতা এহান কাম এহান করানি সম্ভব নেই।',
+'badfilename' => 'ফাইলগর নাঙহান পতিয়া $1" করানি ইল।',
+'badipaddress' => 'আইপি ঠিকানাহান গ্রহনযোগ্যনাইসে',
+'badretype' => 'খন্তাচাবি (password) দ্বিয়গি না মিলের।',
+'badtitle' => 'শিরোনাঙহান গ্রহনযোগ্য নাইসে।',
+'badtitletext' => 'The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one more characters which cannot be used in titles.',
+'blanknamespace' => '(গুরি)',
+'blockedtext' => 'তর আতাকুরা নাঙহান নাইলেউ আইপি ঠিকানাহানরে $1 থেপকরানি অসে। এহানর কারণহান অসেতাইঃ:<br />\'\'$2\'\'<p>তি $1 নাইলেউ [[Project:প্রশাসকলকেই|প্রশাসকর]] মা যে কোন আগর লগে বিষয় এহান্ন য়্যারি পরি দে পারর। বিশেষ মাতিলতাঃ তর ই-মেইল ঠিকানাহান যদি [[Special:Preferences|তর পছন তালিকাত]] বরিয়া নাথার, অতা ইলে তি উইকিপিডিয়াত হের আতাকুরারে ই-মেইল করানি নুৱারবে। তর আইপি ঠিকানাহান ইলতাই $3। কৃপা করিয়া যে কোন যোগাযোগর সময়ত এরে ঠিকানা এহান যেসাদেউ বরিস।',
+'blockedtitle' => 'আতাকুরাগরে থেপ করানি অসে',
+'blockip' => 'আতাকুরাগরে থেপকর',
+'blockipsuccesssub' => 'থেপকরানিহান চুমিল',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|$1]] রে থেপকরিয়া থসি <br />থেপকরানিহান খাল করানি থকিলে,[[{{ns:Special}}:Ipblocklist| থেপকরিয়া থসি আইপি ঠিকানার তালিকাহান]] চা।',
+'blocklink' => 'থেপ কর',
+'blocklistline' => '$1 তারিখে $2, $3 ($4) রে থেপকরানি অসে।',
+'blocklogentry' => '"[[$1]]"-রে $2 মেয়াদর কা থেপকরানি অসে।',
+'blocklogpage' => 'থেপকরানির log',
+'bold_sample' => 'গাঢ়পা ৱাহি',
+'bold_tip' => 'গাঢ়পা ৱাহি',
+'booksources' => 'লেরিকর উৎসহান',
+'boteditletter' => 'ব',
+'brokenredirects' => 'বারো-নির্দেশ কামনাকরের',
+'bugreports' => 'লাল বিবরণী',
+'bugreportspage' => '{{ns:project}}:লাল_বিবরণী',
+'bydate' => 'তারিখর সিজিলন',
+'byname' => 'নাঙর সিজিলন',
+'bysize' => 'আকারহানর সিজিলন',
+'cachederror' => 'এরে পাতা এহান বা লাতলগ পুছানি নাকরল। (নিঙকরুরিতাঃ আগেদে কুঙগ আগই পুছে বেলাসিসাত)',
+'cancel' => 'বাতিল করেদে',
+'cantrollback' => 'আগেকার সঙস্করনহাত আলথকে যানা নুৱারলু, লমিলগা সম্পদনাকরেকুরা অগ পাতা অহানর আকখুলা লেখকগ।',
+'captcha-createaccount' => 'স্বয়ংক্রিয় স্প্যামর বিরুদ্ধে সুরক্ষার কা তরতা একাউন্ট খোলানির আগে তলর ছবিগর ভিতরর ৱাহিহানরে টাইপ করানি থকিতই: <br />([[Special:Captcha/help|এহান কিহান?]])',
+'categories' => 'বিষয়রথাকহানি',
+'categoriespagetext' => 'ইমারঠারর উইকিপিডিয়াত এবাকার বিষয়রথাক:',
+'category_header' => '"$1" বিষয়রথাকে আসে নিবন্ধহানি',
+'categoryarticlecount' => 'এরে বিষয়রথাকে $1হান নিবন্ধ আসে।',
+'categorypage' => 'বিষয়থাকর পাতাহানি চা',
+'categorytree-category' => 'বিষয়রথাক',
+'changed' => 'পতেসে',
+'changepassword' => 'খন্তাচাবি(password) পতা',
+'changes' => 'পতানিহানি',
+'cite' => 'উদ্ধৃত করেদে',
+'cite_article_link' => 'নিবন্ধ এহানরে উদ্ধৃত করেদে',
+'clearyourcache' => '\'\'\'খিয়াল থ:\'\'\' তর পছনহানি রক্ষা করানির থাঙনাত পতাহানি চানার কা তর ব্রাউজারর ক্যাশ লালুয়া যানা লাগতে পারে। \'\'\'মোজিলা/ফায়ারফক্স/সাফারি:\'\'\' শিফট কী চিপিয়া থয়া রিলোড-এ ক্লিক কর, নাইলে \'\'কন্ট্রোল-শিফট-R\'\'(এপল ম্যাক-এ \'\'কমান্ড-শিফট-R\'\') আকপাকে চিপা; \'\'\'ইন্টারনেট এক্সপ্লোরার:\'\'\' \'\'কন্ট্রোল\'\' চিপিয়া থয়া রিফ্রেশ-এ ক্লিক কর, নাইলে \'\'কন্ট্রোল-F5\'\' চিপা; \'\'\'কংকারার:\'\'\' হুদ্দা রিলোড ক্লিক করলে বা F5 চিপিলে চলতই; \'\'\'অপেরা\'\'\' আতাকুরাই \'\'Tools&rarr;Preferences\'\'-এ গিয়া কাশ সম্পূর্ণ ঙক্ষি করানি লাগতে পারে।',
+'columns' => 'দুরগিঃ',
+'compareselectedversions' => 'বাসাইল সংস্করণহানি তুলনা কর',
+'confirm' => 'লেপকরানি',
+'confirm_purge' => 'পাতা এহানর ক্যাশহান ঙক্ষি করানি মনারতা?
+
+$1',
+'confirm_purge_button' => 'চুমিসে',
+'confirmdelete' => 'পুসানিহান লেপকর',
+'confirmedittext' => 'যেহানউ সম্পাদনা করানির আগে তর ই-মেইল ঠিকানাহন যেসাদেউ লেপকরানি লাগতই। কৃপাকরিয়া তর ই-মেইল ঠিকানাহান [[special:Preferences|আতাকুরার পছনতালিকা]]ত চুমকরে বরা।',
+'confirmedittitle' => 'সম্পাদনা করানির কা ই-মেইল লেপকানি থকিতই',
+'confirmemail' => 'ই-মেইল ঠিকানাহান লেপকর',
+'confirmemail_invalid' => 'লেপকরেকুরা কোডগ চুম নাইসে। সম্ভবতঃ এগ পুরানা ইয়া পরসেগা।',
+'confirmemail_loggedin' => 'তর ই-মেইল ঠিকানাহার লেপকরানিহান চুমিল।',
+'confirmemail_send' => 'লেপকরেকুরা কোডগ দিয়াপেঠাদে',
+'confirmemail_sendfailed' => 'লেপকরেকুরা ই-মেইলহান দিয়াপেঠাদে নুৱাররাং। ইমেইল ঠিকানাহান চুমকরে ইকরিসত্তানাকিতা আরাক আকমু খিয়াল করিয়া চা। আলথকে আহিলঃ $1',
+'confirmemail_sent' => 'লেপকরেকুরা ই-মেইলহান দিয়াপেঠা দিলাং।',
+'confirmemail_success' => 'তর ই-মেইল ঠিকানাহার লেপ্পাহান চুমিল। তি এবাকা হমানি(log in) পারর।',
+'contribslink' => 'অবদান',
+'currentevents' => 'হাদি এহানর ঘটনা',
+'currentevents-url' => 'হাদি এহানর ঘটনাহানি',
+'currentrev' => 'হাদিএহানর পতানি',
+'currentrevisionlink' => 'হাদি এহানর পতানি',
+'delete' => 'পুসানি',
+'delete_and_move' => 'পুসানি বারো থেইকরানি',
+'delete_and_move_confirm' => 'হায়, পাতা এহান পুস',
+'deletethispage' => 'পাতা এহান পুসে বেলিক',
+'diff' => 'ফারাক',
+'edit' => 'পতানি',
+'edithelp' => 'পতানি পাংলাক',
+'edithelppage' => '{{ns:project}}:কিসাদে_পাতা_আহান_পতানি',
+'editold' => 'পতিক',
+'editsection' => 'পতিক',
+'editthispage' => 'পাতা এহান পতিক',
+'error' => 'লালুইসে',
+'errorpagetitle' => 'লাল',
+'faq' => 'প্রশ্নরজুয়াপ',
+'faqpage' => '{{ns:project}}:প্রশ্নরজুয়াপ',
+'go' => 'হাত',
+'help' => 'পাংলাক',
+'helppage' => '{{ns:project}}:পাংলাক',
+'hide' => 'আরুম',
+'hidetoc' => 'মেথেল আরুম কর',
+'hist' => 'ইতিহাসহান',
+'histfirst' => 'হাব্বিত্ত পুরানা',
+'histlast' => 'হাব্বিত্ত নুৱা',
+'histlegend' => 'ফারাক (Diff) বাছানি: যে সংস্করণহানি তুলনা করানি চার, অহান লেপকরিয়া এন্টার বা তলর খুথামগত যাতা।<br />
+নির্দেশিকা: (এব) = এবাকার সংস্করণহানর লগে ফারাক,(আ) = জানে আগে-আগে গেলগা সংস্করণহানর লগে ফারাক, হ = হুরু-মুরু (নামাতলেউ একরব অসারে) সম্পাদনাহান।',
+'history_short' => 'ইতিহাসহান',
+'ilsubmit' => 'বিসারা',
+'imagelinks' => 'জুরিসিতা',
+'imagelist' => 'ছবির তালিকা',
+'imagepage' => 'ছবির পাতাহান চেইক',
+'jumptonavigation' => 'দিশা ধরানি',
+'lastmodifiedat' => 'পাতা এহানর লমিলগা পতানিহান $2, $1.',
+'mainpage' => 'পয়লা পাতা',
+'minoredit' => 'এহান হুরু-মুরু সম্পাদনাহানহে।',
+'minoreditletter' => 'হ',
+'move' => 'থেইকরানি',
+'mycontris' => 'মর অবদান',
+'mypage' => 'মর পাতাহান',
+'mytalk' => 'মর য়্যারি-পরি',
+'navigation' => 'দিশা-ধরুনী',
+'nbytes' => '$1 বাইট',
+'newmessageslink' => 'নুৱা পৌ',
+'newpage' => 'নুৱা পাতা',
+'newpageletter' => 'নু',
+'nstab-main' => 'নিবন্ধ',
+'nstab-mediawiki' => 'পৌ',
+'nstab-project' => 'প্রকল্প পাতা',
+'nstab-special' => 'বিশেষ',
+'nstab-user' => 'আতাকুরার পাতা',
+'ok' => 'চুমিসে',
+'otherlanguages' => 'আরআর ঠারে',
+'permalink' => 'আকুবালা মিলাপ',
+'portal' => 'শিংলুপ',
+'portal-url' => '{{ns:project}}:শিংলুপ',
+'printableversion' => 'ছাপানি একরব সংস্করণ',
+'projectpage' => 'প্রকল্পর পাতাহান',
+'protectedinterface' => '[[Image:Padlock.svg|right|60px|]]পাতা এহানর মেথেল উইকি সফটওয়্যারর ইন্টারফেসর পৌহান দের, অহানে এহানরে ইতু করিয়া থনা অসে এবিউসেত্ত ঙাক্করানির কাজে।',
+'protectthispage' => 'পাতা এহান ইতু করিক',
+'qbedit' => 'পতানি',
+'qbfind' => 'বিসারিয়া চা',
+'qbbrowse' => 'বুলিয়া চা',
+'qbpageoptions' => 'পাতা এহানর সারুক',
+'qbpageinfo' => 'পাতা এহানর পৌ',
+'qbmyoptions' => 'মর পছন',
+'qbspecialpages' => 'বিশেষ পাতাহানি',
+'randompage' => 'খাংদা পাতা',
+'recentchanges' => 'হাদিএহান পতাসিতা',
+'recentchangeslinked' => 'সাকেই আসে পতা',
+'redirectedfrom' => '($1 -ত্ত পাকদিয়া আহিল)',
+'returnto' => 'আলথকে যাগা $1.',
+'retrievedfrom' => '\'$1\' -ত্ত আনানি অসে',
+'restriction-edit' => 'পতানিহান_চিয়ৌকর',
+'saturday' => 'থাংচা',
+'savefile' => 'ফাইল ইতু',
+'saveprefs' => 'ইতু',
+'search' => 'বিসারিয়া চা',
+'searcharticle' => 'হাত',
+'searchbutton' => 'বিসারানি',
+'showtoc' => 'ফংকর',
+'sitesubtitle' => 'খুলাসা বিশ্বকোষ উইকিপিডিয়াত্ত',
+'sitesupport' => 'দান দেনা',
+'sitetitle' => 'উইকিপিডিয়া',
+'specialloguserlabel' => 'আতাকুরাগ:',
+'specialpage' => 'বিশেষ পাতাহান',
+'specialpages' => 'বিশেষ পাতাহানি',
+'tagline' => 'মুক্ত বিশ্বকোষ উইকিপিডিয়াত্ত',
+'talk' => 'য়্যারী',
+'talkpage' => 'পাতা এহান্ন য়্যারি দিক',
+'toc' => 'মেথেল',
+'toolbox' => 'আতিয়ার',
+'unwatch' => 'তালাবি নেই',
+'unwatchthispage' => 'তালাবি এরাদেনা',
+'upload' => 'আপলোড ফাইল',
+'uploadbtn' => 'আপলোড',
+'unprotectthispage' => 'পাতা এহানর ইতু এরাদিক',
+'userlogin' => 'হমানি / নৱা একাউন্ট খুলানি',
+'userlogout' => 'নিকুলানি',
+'userpage' => 'আতাকুরার পাতাহান চেইক',
+'viewcount' => 'পাতা এহান $1 মাউ চানা ইল।',
+'viewtalkpage' => 'য়্যারীর পাতাহান চেইক',
+'watch' => 'তালাবি',
+'watchlist' => 'মর তালাবি',
+'watchthis' => 'পাতাএহান খিয়ালে থ',
+'watchthispage' => 'পাতাএহান খিয়ালে থ',
+'watchthisupload' => 'পাতাএহান খিয়ালে থ',
+'whatlinkshere' => 'যে পাতাহানিত্ত এহানাত মিলাপ আসে',
+'welcomecreation' => '== সম্ভাষা, $1! ==
+
+তর একাউন্টহান মুকিল। তর {{SITENAME}} পছনহান পতানি না পাহুরিস।',
+'yourdiff' => 'ফারাকহানি',
+'yourdomainname' => 'তর ডোমেইনগ',
+'youremail' => 'ই-মেইল *:',
+'yourlanguage' => 'ঠারহান:',
+'yourname' => 'আতাকুরার নাংহান (Username)',
+'yournick' => 'দাহানির নাংহান:',
+'yourpassword' => 'খন্তাচাবিগ (password)',
+'yourpasswordagain' => 'খন্তাচাবিগ (password) আরাকমু ইকর',
+'yourrealname' => 'আৱৈপা নাংহান *:',
+'yourtext' => 'তর ইকরা বিষয়হানি',
+
+);
+
+?>
diff --git a/languages/messages/MessagesBr.php b/languages/messages/MessagesBr.php
new file mode 100644
index 000000000000..8b34e30539cc
--- /dev/null
+++ b/languages/messages/MessagesBr.php
@@ -0,0 +1,1097 @@
+<?php
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Dibar',
+ NS_MAIN => '',
+ NS_TALK => 'Kaozeal',
+ NS_USER => 'Implijer',
+ NS_USER_TALK => 'Kaozeadenn_Implijer',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Kaozeadenn_$1',
+ NS_IMAGE => 'Skeudenn',
+ NS_IMAGE_TALK => 'Kaozeadenn_Skeudenn',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Kaozeadenn_MediaWiki',
+ NS_TEMPLATE => 'Patrom',
+ NS_TEMPLATE_TALK => 'Kaozeadenn_Patrom',
+ NS_HELP => 'Skoazell',
+ NS_HELP_TALK => 'Kaozeadenn_Skoazell',
+ NS_CATEGORY => 'Rummad',
+ NS_CATEGORY_TALK => 'Kaozeadenn_Rummad'
+);
+
+$quickbarSettings = array(
+ 'Hini ebet', 'Kleiz', 'Dehou', 'War-neuñv a-gleiz'
+);
+
+$skinNames = array(
+ 'standard' => 'Standard',
+ 'nostalgia' => 'Melkoni',
+ 'cologneblue' => 'Glaz Kologn',
+ 'smarty' => 'Paddington',
+ 'montparnasse' => 'Montparnasse',
+ 'davinci' => 'DaVinci',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'MySkin'
+);
+
+
+
+$bookstoreList = array(
+ 'Amazon.fr' => 'http://www.amazon.fr/exec/obidos/ISBN=$1',
+ 'alapage.fr' => 'http://www.alapage.com/mx/?tp=F&type=101&l_isbn=$1&donnee_appel=ALASQ&devise=&',
+ 'fnac.com' => 'http://www3.fnac.com/advanced/book.do?isbn=$1',
+ 'chapitre.com' => 'http://www.chapitre.com/frame_rec.asp?isbn=$1',
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'j M Y "da" H:i',
+);
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+$linkTrail = "/^([a-zàâçéèêîôûäëïöüùÇÉÂÊÎÔÛÄËÏÖÜÀÈÙ]+)(.*)$/sDu";
+
+
+$messages = array(
+
+# User Toggles
+
+'tog-editwidth' => 'Digeriñ ar prenestr aozañ en e led brasañ',
+'tog-editondblclick' => 'Daouglikañ evit kemmañ ur bajenn (JavaScript)',
+'tog-editsection' => 'Kemmañ ur rann dre al liammoù [kemmañ]',
+'tog-editsectiononrightclick' => 'Kemmañ ur rann dre glikañ a-zehou<br /> war titl ar rann',
+'tog-fancysig' => 'Sinadurioù diliamm (hep liamm emgefre)',
+'tog-hideminor' => 'Kuzhat ar <i>C\'hemmoù nevez</i> dister',
+'tog-highlightbroken' => 'Lakaat e ruz al liammoù war-du<br /> an danvezioù n\'eus ket anezho',
+'tog-justify' => 'Rannbennadoù marzhekaet',
+'tog-minordefault' => 'Sellet ouzh ar c\'hemmoù degaset ganin<br /> evel kemmoù dister dre ziouer',
+'tog-nocache' => 'Diweredekaat krubuilh ar pajennoù',
+'tog-numberheadings' => 'Niverenniñ emgefre an titloù',
+'tog-previewonfirst' => 'Rakwelet tres ar bajenn kerkent hag an aozadenn gentañ',
+'tog-previewontop' => 'Rakwelet e vo tres ar bajenn<br /> a-us ar voest skridaozañ',
+'tog-rememberpassword' => 'Derc\'hel soñj eus ma ger-temen (toupin)',
+'tog-showtoc' => 'Diskouez an daolenn<br /> (evit ar pennadoù zo ouzhpenn 3 rann enno)',
+'tog-showtoolbar' => 'Diskouez ar varrenn gant ar meuzioù aozañ',
+'tog-usenewrc' => 'Kemmoù nevez gwellaet<br /> (gant merdeerioù zo hepken)',
+'tog-underline' => 'Liammoù islinennet',
+'tog-watchdefault' => 'Evezhiañ ar pennadoù savet pe kemmet ganin',
+
+
+# Dates
+
+'sunday' => 'Sul',
+'monday' => 'Lun',
+'tuesday' => 'Meurzh',
+'wednesday' => 'Merc\'her',
+'thursday' => 'Yaou',
+'friday' => 'Gwener',
+'saturday' => 'Sadorn',
+'january' => 'Genver',
+'february' => 'C\'hwevrer',
+'march' => 'Meurzh',
+'april' => 'Ebrel',
+'may_long' => 'Mae',
+'june' => 'Mezheven',
+'july' => 'Gouere',
+'august' => 'Eost',
+'september' => 'Gwengolo',
+'october' => 'Here',
+'november' => 'Du',
+'december' => 'Kerzu',
+'jan' => 'Gen',
+'feb' => 'C\'hwe',
+'mar' => 'Meu',
+'apr' => 'Ebr',
+'may' => 'Mae',
+'jun' => 'Mez',
+'jul' => 'Gou',
+'aug' => 'Eos',
+'sep' => 'Gwe',
+'oct' => 'Her',
+'nov' => 'Du',
+'dec' => 'Kzu',
+
+
+# Bits of text used by many pages:
+#
+'categories' => 'Rummadoù ar bajenn',
+'pagecategories' => 'Rummadoù ar bajenn',
+'category_header' => 'Niver a bennadoù er rummad "$1"',
+'subcategories' => 'Isrummad',
+'uncategorizedcategories' => 'Rummadoù hep rummadoù',
+'uncategorizedpages' => 'Pajennoù hep rummad ebet',
+'subcategorycount' => '$1 isrummad zo d\'ar rummad-mañ.',
+
+'allarticles' => 'An holl bennadoù',
+'mainpage' => 'Degemer',
+'mainpagetext' => 'Meziant {{SITENAME}} staliet.',
+'portal' => 'Porched ar gumuniezh',
+'portal-url' => '{{ns:4}}:Degemer',
+'about' => 'Diwar-benn',
+'aboutsite' => 'Diwar-benn {{SITENAME}}',
+'aboutpage' => '{{ns:4}}:Diwar-benn',
+'article' => 'Pennad',
+'help' => 'Skoazell',
+'helppage' => '{{ns:4}}:Skoazell',
+'bugreports' => 'Teul an drein',
+'bugreportspage' => '{{ns:4}}:Teul an drein',
+'sitesupport' => 'Skoazellañ dre reiñ un dra bennak',
+'faq' => 'FAG',
+'faqpage' => '{{ns:4}}:FAG',
+'edithelp' => 'Skoazell',
+'edithelppage' => '{{ns:4}}:Penaos degas kemmoù en ur bajenn',
+'cancel' => 'Nullañ',
+'qbfind' => 'Klask',
+'qbbrowse' => 'Furchal',
+'qbedit' => 'Kemmañ',
+'qbpageoptions' => 'Pajenn an dibaboù',
+'qbpageinfo' => 'Pajenn gelaouiñ',
+'qbmyoptions' => 'Ma dibaboù',
+'qbspecialpages' => 'Pajennoù dibar',
+'moredotdotdot' => 'Ha muioc\'h c\'hoazh...',
+'mypage' => 'Ma zammig pajenn',
+'mytalk' => 'Ma c\'haozeadennoù',
+'anontalk' => 'Kaozeal gant ar chomlec\'h IP-mañ',
+'navigation' => 'Merdeiñ',
+'currentevents' => 'Keleier',
+'disclaimers' => 'Kemennoù',
+'disclaimerpage' => '{{ns:4}}:Kemenn hollek',
+'errorpagetitle' => 'Fazi',
+'returnto' => 'Distreiñ d\'ar bajenn $1.',
+'tagline' => 'Ur pennad tennet eus {{SITENAME}}, ar c\'helc\'hgeriadur digor.',
+'whatlinkshere' => 'Daveennoù d\'ar bajenn-mañ',
+'help' => 'Skoazell',
+'search' => 'Klask',
+'searchbutton' => 'Klask',
+'history' => 'Istor',
+'printableversion' => 'Stumm da voullañ',
+'edit' => 'Kemmañ',
+'editthispage' => 'Kemmañ ar bajenn-mañ',
+'delete' => 'Diverkañ',
+'deletethispage' => 'Diverkañ ar bajenn-mañ',
+'undelete_short' => 'Diziverkañ',
+'protect' => 'Gwareziñ',
+'protectthispage' => 'Gwareziñ ar bajenn-mañ',
+'unprotect' => 'Diwareziñ',
+'unprotectthispage' => 'Diwareziñ ar bajenn-mañ',
+'newpage' => 'Pajenn nevez',
+'talkpage' => 'Pajenn gaozeal',
+'specialpage' => 'Pajenn zibar',
+'personaltools' => 'Ostilhoù personel',
+'postcomment' => 'Ouzhpennañ e soñj',
+'articlepage' => 'Sellet ouzh ar pennad',
+'talk' => 'Kaozeadenn',
+'toolbox' => 'Boest ostilhoù',
+'userpage' => 'Pajenn implijer',
+'projectpage' => 'Pajenn meta',
+'imagepage' => 'Pajenn skeudenn',
+'viewtalkpage' => 'Pajenn gaozeal',
+'otherlanguages' => 'Yezhoù all',
+'redirectedfrom' => '(Adkaset eus $1)',
+'lastmodifiedat' => 'Kemmoù diwezhañ degaset d\'ar bajenn-mañ : $2, $1.',
+'viewcount' => 'Sellet ez eus bet ouzh ar bajenn-mañ $1 (g)wech.',
+'copyright' => 'Danvez a c\'haller implijout dindan $1.',
+'protectedpage' => 'Pajenn warezet',
+'nbytes' => '$1 eizhbit',
+'go' => 'Kas',
+'searcharticle' => 'Kas',
+'ok' => 'Mat eo',
+'history' => 'Istor ar bajenn',
+'history_short' => 'Istor',
+'retrievedfrom' => 'Adtapet diwar « $1 »',
+'editsection' => 'kemmañ',
+'editold' => 'kemmañ',
+'toc' => 'Taolenn',
+'showtoc' => 'diskouez',
+'hidetoc' => 'kuzhat',
+'thisisdeleted' => 'Diskouez pe diziverkañ $1 ?',
+'restorelink' => '1 c\'hemm diverket',
+'feedlinks' => 'Lusk:',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Pennad',
+'nstab-user' => 'Pajenn implijer',
+'nstab-media' => 'Media',
+'nstab-special' => 'Dibar',
+'nstab-project' => 'Diwar-benn',
+'nstab-image' => 'Skeudenn',
+'nstab-mediawiki' => 'Kemennadenn',
+'nstab-template' => 'Patrom',
+'nstab-help' => 'Skoazell',
+'nstab-category' => 'Rummad',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Ober dianv',
+'nosuchactiontext' => 'N\'eo ket anavezet gant ar wiki an ober spisaet en Url.',
+'nosuchspecialpage' => 'N\'eus ket eus ar bajenn zibar-mañ',
+'nospecialpagetext' => 'Goulennet hoc\'h eus ur bajenn zibar n\'eo ket anavezet gant ar wiki.',
+
+# General errors
+#
+'error' => 'Fazi',
+'badaccess' => 'Fazi aotre',
+'databaseerror' => 'Fazi bank roadennoù',
+'dberrortext' => "Fazi ereadur er bank roadennoù. Setu ar goulenn bet pledet gantañ da ziwezhañ :
+<blockquote><tt>$1</tt></blockquote>
+adal an arc\'hwel \"<tt>$2</tt>\".
+Adkaset eo bet ar fazi \"<tt>$3: $4</tt>\" gant MySQL.",
+'dberrortextcl' => 'Ur fazi ereadur zo en ur goulenn graet ouzh ar bank roadennoù. Setu ar goulenn bet pledet gantañ da ziwezhañ :
+"$1"
+graet gant an arc\'hwel "$2"
+adkaset eo bet ar fazi "$3 : $4" gant MySQL.',
+'noconnect' => "Ho tigarez! Da-heul kudennoù teknikel, n'haller ket kevreañ ouzh ar bank roadennoù evit poent.", //"Dibosupl kevreañ ouzh ar bank roadennoù war $1",
+'nodb' => 'Dibosupl dibab ar bank roadennoù $1',
+'cachederror' => 'Un eilenn eus ar bajenn goulennet eo homañ; marteze n\'eo ket bet hizivaet',
+'readonly' => 'Hizivadurioù stanket war ar bank roadennoù',
+'enterlockreason' => 'Merkit perak eo stanket hag istimit pegeit e chomo evel-henn',
+'readonlytext' => "Stanket eo an ouzhpennadennoù hag an hizivadurioù war bank roadennoù {{SITENAME}}; moarvat peogwir emeur oc\h ober war-dro ar bank. Goude-se e vo plaen pep tra en-dro. Setu perak eo bet stanket ar bank gant ar merour :
+<p>$1",
+'missingarticle' => 'N\'eo ket bet ar bank roadennoù evit kavout testenn ur bajenn zo anezhi c\'hoazh gant an titl "$1".
+N\'eo ket ur fazi gant ar bank roadennoù, un draen gant ar wiki marteze a-walc\'h.
+Kasit, ni ho ped, keloù eus an draen-mañ d\'ur merour en ur verkañ mat dezhañ chomlec\'h ar bajenn e kaoz.',
+'internalerror' => 'Fazi diabarzh',
+'filecopyerror' => 'Dibosupl eilañ « $1 » war-du « $2 ».',
+'fileinfo' => '$1Ko, seurt MIME: <tt>$2</tt>',
+'filerenameerror' => 'Dibosupl da adenvel « $1 » e « $2 ».',
+'filedeleteerror' => 'Dibosupl da ziverkañ « $1 ».',
+'filenotfound' => 'N\'haller ket kavout ar restr "$1".',
+'unexpected' => 'Talvoudenn dic\'hortoz : "$1"="$2".',
+'formerror' => 'Fazi: Dibosupl eo kinnig ar furmskrid',
+'badarticleerror' => 'N\'haller ket seveniñ an ober-mañ war ar bajenn-mañ.',
+'cannotdelete' => "Dibosupl da ziverkañ ar bajenn pe ar skeudenn spisaet.",
+'badtitle' => 'Titl fall',
+'badtitletext' => 'Faziek pe c\'houllo eo titl ar bajenn goulennet; pe neuze eo faziek al liamm etreyezhel',
+'laggedslavemode' => 'Diwallit : marteze a-walc\'h n\'emañ ket ar c\'hemmoù diwezhañ war ar bajenn-mañ',
+'readonly_lag' => 'Stanket eo bet ar bank roadennoù ent emgefre p\'emañ an eilservijerioù oc\'h adpakañ o dale e-keñver ar pennservijer',
+'perfdisabled' => 'Ho tigarez! Diweredekaet eo bet an arc\'hwel-mañ evit poent rak gorrekaat a ra ar bank roadennoù kement ha ma n\'hall ket mui den implijout ar wiki.',
+'perfdisabledsub' => 'Setu aze un eilenn savete eus $1:',
+'viewsource' => 'Sellet ouzh tarzh an destenn',
+'protectedtext' => 'Stanket eo bet ar bajenn-mañ evit ma ne vo ket degaset kemmoù warni ken. Sellet ouzh [[{{ns:4}}:Pajenn warezet]] evit gwelet an abegoù a c\'hall bezañ.',
+'allmessagesnotsupportedDB' => 'N\'haller ket kaout Special:AllMessages rak diweredekaet eo bet wgUseDatabaseMessages.',
+'allmessagesnotsupportedUI' => 'Ne zegemer ket Special:AllMessages yezh hoc\'h etrefas (<b>$1</b>) war al lec\'hienn-mañ.',
+'wrong_wfQuery_params' => 'Arventennoù faziek war an urzhiad wfQuery()<br />
+Arc\'hwel : $1<br />
+Goulenn : $2',
+'versionrequired' => 'Rekis eo Stumm $1 MediaWiki',
+'versionrequiredtext' => 'Rekis eo stumm $1 MediaWiki evit implijout ar bajenn-mañ. Sellit ouzh [[Special:Version]]',
+
+
+# Login and logout pages
+#
+'logouttitle' => 'Dilugañ',
+'logouttext' => 'Diluget oc\'h bremañ.
+Gallout a rit kenderc\'hel da implijout {{SITENAME}} en un doare dizanv, pe en em lugañ en-dro gant un anv all mar fell deoc\'h.',
+
+'welcomecreation' => "<h2>Degemer mat, $1!</h2><p>Krouet eo bet ho kont implijer.
+Na zisoñjit ket da bersonelaat ho {{SITENAME}} en ur sellet ouzh pajenn ar Penndibaboù.",
+
+'loginpagetitle' => 'Ho tisklêriadenn',
+'yourname' => 'Hoc\'h anv implijer',
+'yourpassword' => 'Ho ker-tremen',
+'yourpasswordagain' => 'Skrivit ho ker-tremen en-dro',
+'remembermypassword' => 'Derc\'hel soñj eus ma ger-tremen (toupin)',
+'loginproblem' => '<b>Kudenn zisklêriañ.</b><br />Klaskit en-dro !',
+'alreadyloggedin' => '\'\'\'Implijer $1, disklêriet oc\'h dija!\'\'\'<br />',
+
+'login' => 'Disklêriañ',
+'loginprompt' => 'Ret eo deoc\'h bezañ gweredekaet an toupinoù evit bezañ luget ouzh {{SITENAME}}.',
+'userlogin' => 'Krouiñ ur gont pe en em lugañ',
+'logout' => 'Dilugañ',
+'userlogout' => 'Dilugañ',
+'notloggedin' => 'Diluget',
+'createaccount' => 'Krouiñ ur gont nevez',
+'createaccountmail' => 'dre bostel',
+'badretype' => 'N\'eo ket peurheñvel an eil ouzh egile an daou c\'her-tremen bet lakaet ganeoc\'h.',
+'userexists' => "Implijet eo dija an anv implijer lakaet ganeoc'h. Dibabit unan all mar plij.",
+'youremail' => 'Ma chomlec\'h elektronek',
+'yournick' => 'Sinadur evit ar c\'haozeadennoù (gant ~~~)',
+'yourrealname' => 'Hoc\'h anv gwir*',
+'prefs-help-realname' => '* <strong>Hoc\'h anv</strong> (diret): ma vez spisaet ganeoc\'h e vo implijet evit merkañ ho tegasadennoù.',
+'prefs-help-email' => '* <strong>Chomlec\'h postel</strong> (diret): gantañ e vo aes mont e darempred ganeoc\'h adal al lec\'hienn o terc\'hel kuzh ho chomlec\'h, hag adkas ur ger-tremen deoc\'h ma tichañsfe deoc\'h koll ho hini.',
+'loginerror' => 'Kudenn zisklêriañ',
+'nocookiesnew' => "krouet eo bet ar gont implijer met n'hoc'h ket luget. {{SITENAME}} a implij toupinoù evit al lugañ met diweredekaet eo an toupinoù ganeoc'h. Trugarez da weredekaat anezho ha d'en em lugañ en-dro.",
+'nocookieslogin' => "{{SITENAME}} a implij toupinoù evit al lugañ met diweredekaet eo an toupinoù ganeoc'h. Trugarez da weredekaat anezho ha d'en em lugañ en-dro.",
+'noname' => "N'hoc'h eus lakaet anv implijer ebet.",
+'loginsuccesstitle' => "Disklêriet oc'h.",
+'loginsuccess' => "Luget oc'h bremañ war {{SITENAME}} evel \"$1\".",
+'nosuchuser' => "N'eus ket eus an implijer \"$1\".
+Gwiriit eo bet skrivet mat an anv ganeoc\'h pe implijit ar furmskrid a-is a-benn krouiñ ur gont implijer nevez.",
+'nosuchusershort' => 'N\'eus perzhiad ebet gantañ an anv « $1 ». Gwiriit ar reizhskrivadur.',
+'wrongpassword' => 'Ger-tremen kamm. Klaskit en-dro.',
+'mailmypassword' => 'Kasit din ur ger-tremen nevez',
+'passwordremindertitle' => "Ho ker-tremen nevez war {{SITENAME}}",
+'passwordremindertext' => "Unan bennak (c'hwi moarvat) gant ar chomlec'h IP $1 en deus goulennet ma vo kaset deoc'h ur ger-tremen nevez evit monet war ar wiki.
+Ger-tremen an implijer \"$2\" zo bremañ \"$3\".
+Erbediñ a reomp deoc'h en em lugañ ha kemmañ ar ger-termen-mañ an abretañ ar gwellañ.",
+'noemail' => "N'eus bet enrollet chomlec'h elektronek ebet evit an implijer \"$1\".",
+'passwordsent' => "Kaset ez eus bet ur ger-tremen nevez da chomlec'h elektronek an implijer \"$1\".
+Trugarez deoc'h evit en em zisklêriañ kerkent ha ma vo bet resevet ganeoc'h.",
+'mailerror' => 'Fazi en ur gas ar postel : $1',
+'acct_creation_throttle_hit' => 'Ho tigarez, krouet ez eus bet $1 (c\'h)gont ganeoc\'h dija. N\'hallit ket krouiñ unan nevez.',
+
+# Edit page toolbar
+'bold_sample' => 'Testenn dev',
+'bold_tip' => 'Testenn dev',
+'italic_sample' => 'Testenn italek',
+'italic_tip' => 'Testenn italek',
+'link_sample' => 'Liamm titl',
+'link_tip' => 'Liamm diabarzh',
+'extlink_sample' => 'http://www.example.com liamm titl',
+'extlink_tip' => 'Liamm diavaez (na zisoñjit ket http://)',
+'headline_sample' => 'Testenn istitl',
+'headline_tip' => 'Istitl live 2',
+'math_sample' => 'Lakait ho formulenn amañ',
+'math_tip' => 'Formulenn jedoniel (LaTeX)',
+'nowiki_sample' => 'Lakait an destenn anfurmadet amañ',
+'nowiki_tip' => 'Na deuler pled ouzh eradur ar wiki',
+'image_sample' => 'Skouer.jpg',
+'image_tip' => 'Skeudenn enframmet',
+'media_sample' => 'Skouer.ogg',
+'media_tip' => 'Liamm restr media',
+'sig_tip' => 'Ho sinadur gant an deiziad',
+'hr_tip' => 'Liamm a-led (arabat implijout re)',
+
+# Edit pages
+#
+'summary' => 'Diverrañ&nbsp;',
+'subject' => 'Danvez/titl',
+'minoredit' => 'Kemm dister.',
+'watchthis' => 'Evezhiañ ar pennad-mañ',
+'savearticle' => 'Enrollañ',
+'preview' => 'Rakwelet',
+'showpreview' => 'Rakwelet',
+'blockedtitle' => 'Implijer stanket',
+"blockedtext" => "Stanket eo bet ho kont implijer pe ho chomlec'h IP gant $1 evit an abeg-mañ :<br />$2<p>Gallout a rit mont e darempred gant $1 pe gant unan eus ar [[{{ns:4}}:Merourien|verourien]] all evit eskemm ganto war se.",
+'whitelistedittitle' => 'Ret eo bezañ luget evit skridaozañ',
+'whitelistedittext' => 'Ret eo deoc\'h bezañ [[Special:Userlogin|luget]] evit gallout skridaozañ',
+'whitelistreadtitle' => 'Ret eo bezañ luget evit gallout lenn',
+'whitelistreadtext' => 'Ret eo bezañ [[Special:Userlogin|luget]] evit gallout lenn ar pennadoù',
+'whitelistacctitle' => 'N\'hoc\'h ket aotreet da grouiñ ur gont',
+'whitelistacctext' => 'A-benn gallout krouiñ ur gont war ar Wiki-mañ e rankit bezañ [[Special:Userlogin|luget]] ha kaout an aotreoù rekis', // Looxix
+'loginreqtitle' => 'Anv implijer rekis',
+'accmailtitle' => 'Ger-tremen kaset.',
+'accmailtext' => 'Kaset eo bet ger-tremen « $1 » da $2.',
+
+'newarticle' => '(Nevez)',
+'newarticletext' => 'Skrivit amañ testenn ho pennad.',
+'anontalkpagetext' => "---- ''Homañ eo ar bajenn gaozeal evit un implijer(ez) dianv n'eus ket c'hoazh krouet kont ebet pe na implij ket anezhi. Setu perak e rankomp ober gant ar [[chomlec'h IP]] niverel evit disklêriañ anezhañ/i. Gallout a ra ur chomlec'h a seurt-se bezañ rannet etre meur a implijer(ez). Ma'z oc'h un implijer(ez) dianv ha ma stadit ez eus bet kaset deoc'h kemennadennoù na sellont ket ouzhoc'h, gallout a rit [[Special:Userlogin|krouiñ ur gont pe en em lugañ]] kuit a vagañ muioc'h a gemmesk.",
+'noarticletext' => "(N'eus evit poent tamm skrid ebet war ar bajenn-mañ)",
+'clearyourcache' => "'''Notenn:''' Goude bezañ enrollet ho pajenn e rankit adkargañ anezhi a-ratozh evit gwelet ar c'hemmoù : '''Internet Explorer''' : ''ctrl-f5'', '''Mozilla / Firefox''' : ''ctrl-shift-r'', '''Safari''' : ''cmd-shift-r'', '''Konqueror''' : ''f5''.",
+'updated' => '(Hizivaet)',
+'note' => '<strong>Notenn :</strong>',
+'previewnote' => "Diwallit mat, n'eus eus an destenn-mañ nemet ur rakweladenn ha n'eo ket bet enrollet c'hoazh!",
+'previewconflict' => "Gant ar rakweladenn e teu testenn ar bajenn war wel evel ma vo pa vo bet enrollet.",
+'editing' => 'oc\'h aozañ $1',
+'editinguser' => 'oc\'h aozañ $1',
+'editingsection' => 'oc\'h aozañ $1 (rann)',
+'editingcomment' => 'oc\'h aozañ $1 (soñj)',
+'editconflict' => 'tabut kemmañ : $1',
+'explainconflict' => "<b>Enrollet eo bet ar bajenn-mañ war-lerc'h m'ho pefe kroget d'he c'hemmañ.
+E-krec'h an takad aozañ emañ an destenn evel m'emañ enrollet bremañ er bank roadennoù. Ho kemmoù deoc'h a zeu war wel en takad aozañ traoñ. Ret e vo deoc'h degas ho kemmoù d'an destenn zo evit poent. N'eus nemet an destenn zo en takad krec'h a vo saveteet.<br />",
+'yourtext' => 'Ho testenn',
+'storedversion' => 'Stumm enrollet',
+"editingold" => "<strong>Diwallit : o kemm ur stumm kozh eus ar bajenn-mañ emaoc'h. Mard enrollit bremañ e vo kollet an holl gemmoù bet graet abaoe ar stumm-se.</strong>",
+"yourdiff" => "Diforc'hioù",
+/*"copyrightwarning" => "Sellet e vez ouzh an holl degasadennoù graet war {{SITENAME}} evel degasadennoù a zouj da dermenoù ar GNU Free Documentation Licence, un aotre teulioù frank a wirioù (Sellet ouzh $1 evit gouzout hiroc'h). Mar ne fell ket deoc'h e vefe embannet ha skignet ho skridoù, arabat kas anezho. Heñveldra, trugarez da gemer perzh o tegas hepken skridoù savet ganeoc'h pe skridoù tennet eus ur vammen frank a wirioù. <b>NA IMPLIJIT KET LABOURIOÙ GANT GWIRIOÙ AOZER (COPYRIGHT) HEP KAOUT UN AOTRE A-RATOZH!</b>",*/
+"longpagewarning" => "<strong>KEMENN DIWALL: $1 ko eo hed ar bajenn-mañ;
+merdeerioù zo o deus poan da verañ ar pajennoù tro-dro pe en tu all da 32 ko pa vezont savet.
+Marteze e c'hallfec'h rannañ ar bajenn e rannoù bihanoc'h.</strong>",
+"readonlywarning" => "<strong>KEMENN DIWALL: stanket eo bet ar bajenn-mañ evit bezañ trezalc'het,
+n'oc'h ket evit enrollañ ho kemmoù diouzhtu eta. Gallout a rit eilañ an destenn en ur restr hag enrollañ anezhi diwezhatoc'hik.</strong>",
+"protectedpagewarning" => "<strong>KEMENN DIWALL: stanket eo bet ar bajenn-mañ.
+N'eus nemet an implijerien ganto ar statud a verourien a c'hall degas kemmoù enni. Bezit sur ec'h heuilhit an [[Project:Pajenn_warezet|erbedadennoù a denn d'ar pajennoù gwarezet]].<strong>",
+
+# History pages
+#
+'revhistory' => 'Stummoù kent',
+'nohistory' => "Ar bajenn-mañ n'he deus tamm istor ebet.",
+'revnotfound' => 'N\'eo ket bet kavet ar stumm-mañ',
+'revnotfoundtext' => "N'eo ket bet kavet stumm kent ar bajenn-mañ. Gwiriit an URL lakaet ganeoc'h evit mont d'ar bajenn-mañ.",
+
+'loadhist' => 'O kargañ istor ar bajenn',
+'currentrev' => 'Stumm a-vremañ pe stumm red',
+'revisionasof' => 'Stumm eus an $1',
+'cur' => 'red',
+'next' => 'goude',
+'last' => 'diwez',
+'orig' => 'kent',
+'histlegend' => "Alc'hwez : (brem) = diforc'hioù gant ar stumm a-vremañ,
+(diwez) = diforc'hioù gant ar stumm kent, K = kemm bihan",
+'selectnewerversionfordiff' => 'Dibab ur stumm nevesoc\'h',
+'selectolderversionfordiff' => 'Dibab ur stumm koshoc\'h',
+'previousdiff' => '← Diforc\'h kent',
+'previousrevision' => '← Stumm kent',
+'nextdiff' => 'Diforc\'h war-lerc\'h →',
+'nextrevision' => 'Stumm war-lerc\'h →',
+
+
+# Category pages
+#
+'categoriespagetext' => "War ar wiki emañ ar rummadoù da-heul :",
+'categoryarticlecount' => "$1 pennad zo er rummad-mañ.",
+
+
+# Diffs
+#
+'difference' => '(Diforc\'hioù etre ar stummoù)',
+'loadingrev' => 'o kargañ ar stumm kent evit keñveriañ',
+'lineno' => 'Linenn $1:',
+'editcurrent' => 'Kemmañ stumm red ar bajenn-mañ',
+
+
+# Search results
+#
+'searchresults' => 'Disoc\'h ar c\'hlask',
+'searchresulttext' => "Evit kaout muioc'h a ditouroù diwar-benn ar c'hlask e {{SITENAME}}, sellet ouzh [[Project:Klask|Klask e-barzh {{SITENAME}}]].",
+'searchsubtitle' => "Evit ar goulenn \"[[:$1]]\"",
+'searchsubtitleinvalid' => "Evit ar goulenn \"$1\"",
+'badquery' => 'Goulenn savet a-dreuz',
+'badquerytext' => "N'eus ket bet gallet plediñ gant ho koulenn.
+Klasket hoc'h eus, moarvat, ur ger dindan teir lizherenn, ar pezh n'hallomp ket ober evit c'hoazh. Gallet hoc'h eus ober, ivez, ur fazi ereadur evel \"pesked ha skantenn\".
+Klaskit gant ur goulenn all.",
+'matchtotals' => "Klotañ a ra ar goulenn \"$1\" gant $2 (d/z)titl
+pennad ha gant testenn $3 (b/f)pennad.",
+'noexactmatch' => "N'eus pajenn ebet ganti an titl-mañ, esaeañ gant ar c'hlask klok.",
+'titlematches' => "Klotadurioù gant an titloù",
+'notitlematches' => "N'emañ ar ger(ioù) goulennet e titl pennad ebet",
+'textmatches' => "Klotadurioù en testennoù",
+'notextmatches' => "N'emañ ar ger(ioù) goulennet e testenn pennad ebet",
+'prevn' => '$1 kent',
+'nextn' => '$1 war-lerc\'h',
+'viewprevnext' => 'Gwelet ($1) ($2) ($3).',
+'showingresults' => "Diskouez <b>$1</b> disoc'h adal an #<b>$2</b>.",
+'showingresultsnum' => "Diskouez <b>$3</b> disoc'h adal an #<b>$2</b>.",
+'nonefound' => "<strong>Notenn</strong>: alies eo liammet an diouer a zisoc'hoù ouzh an implij a vez graet eus termenoù klask re stank, evel \"da\" pe \"ha\",
+termenoù n'int ket menegeret, pe ouzh an implij a meur a dermen klask (en disoc'hoù ne gaver nemet ar pajennoù enno an holl c'herioù spisaet).",
+'powersearch' => "Klask",
+'powersearchtext' => "
+Klask en esaouennoù :<br />
+$1<br />
+$2 Lakaat ivez ar pajennoù adkas &nbsp; Klask $3 $9",
+'searchdisabled' => "<p>Diweredekaet eo bet an arc'hwel klask war an destenn a-bezh evit ur frapad rak ur samm re vras e oa evit ar servijer. Emichañs e vo tu d'e adlakaat pa vo ur servijer galloudusoc'h ganeomp. Da c'hortoz e c'hallit klask gant Google:</p>",
+"blanknamespace" => "(Principal)", // FIXME FvdP: troet eus "(Main)"
+
+# Preferences page
+#
+'preferences' => 'Penndibaboù',
+'prefsnologin' => 'Diluget',
+'prefsnologintext' => "ret eo deoc'h bezañ [[Special:Userlogin|luget]] evit kemm ho tibaboù implijer.",
+
+'prefsreset' => 'Adlakaet eo bet ar penndibaboù diouzh ar stumm bet enrollet.',
+'qbsettings' => 'Personelaat ar varrenn ostilhoù',
+'changepassword' => 'Kemmañ ar ger-tremen',
+'skin' => 'Gwiskadur',
+'math' => 'Tres ar jedoniezh',
+'dateformat' => 'Stumm an deiziad',
+'math_failure' => 'Fazi jedoniezh',
+'math_unknown_error' => 'fazi dianv',
+'math_unknown_function' => 'kevreizhenn jedoniel dianv',
+'math_lexing_error' => 'fazi ger',
+'math_syntax_error' => 'fazi ereadur',
+'math_image_error' => "C'hwitet eo bet ar gaozeadenn e PNG, gwiriit staliadur Latex, dvips, gs ha convert",
+'math_bad_tmpdir' => "N'hall ket krouiñ pe skrivañ er c'havlec'h da c'hortoz",
+'math_bad_output' => "N'hall ket krouiñ pe skrivañ er c'havlec'h ermaeziañ",
+'math_notexvc' => "N'hall ket an erounezeg 'texvc' bezañ kavet. Lennit math/README evit he c'hefluniañ.",
+'prefs-personal' => 'Titouroù personel',
+'prefs-rc' => 'Kemmoù diwezhañ ha diskouez ar rakweladurioù',
+'prefs-misc' => 'Penndibaboù liesseurt',
+'saveprefs' => 'Enrollañ ar penndibaboù',
+'resetprefs' => 'Adlakaat ar penndibaboù kent',
+'oldpassword' => 'Ger-tremen kozh',
+'newpassword' => 'Ger-temen nevez&nbsp;',
+'retypenew' => 'Kadarnaat ar ger-tremen nevez',
+'textboxsize' => 'Ment ar prenestr kemmañ',
+'rows' => 'Renkennadoù&nbsp;',
+'columns' => 'Bannoù',
+'searchresultshead' => 'Doare diskouez disoc\'hoù an enklaskoù',
+'resultsperpage' => 'Niver a respontoù dre bajenn&nbsp;',
+'contextlines' => 'Niver a linennoù dre respont',
+'contextchars' => 'Niver a arouezennoù kendestenn dre linenn',
+'stubthreshold' => 'Ment vihanañ ar pennadoù berr',
+'recentchangescount' => 'Niver a ditloù er c\'hemmoù diwezhañ',
+'savedprefs' => 'Enrollet eo bet ar penndibaboù.',
+'timezonelegend' => 'Takad eur',
+'timezonetext' => "Mar ne resisait ket al linkadur eur e vo graet gant eur Europa ar C'hornôg dre ziouer.",
+'localtime' => 'Eur lec\'hel',
+'timezoneoffset' => 'Linkadur eur',
+'servertime' => 'Eur ar servijer',
+'guesstimezone' => 'Ober gant talvoudenn ar merdeer',
+"defaultns" => "Klask en esaouennoù-mañ dre ziouer :",
+'yourlanguage' => "Yezh an etrefas&nbsp;",
+
+# Recent changes
+#
+"changes" => "Kemmoù",
+"recentchanges" => "Kemmoù diwezhañ",
+"recentchangestext" => "War ar bajenn-mañ e c'hallot heuliañ ar c'hemmoù diwezhañ c'hoarvezet war {{SITENAME}}.
+[[{{ns:4}}:Degemer|Degemer mat]] d'ar berzhidi nevez!
+Taolit ur sell war ar pajennoù-mañ&nbsp;: [[{{ns:4}}:FAG|foar ar goulennoù]],
+[[{{ns:4}}:Erbedadennoù ha reolennoù da heuliañ|erbedadennoù ha reolennoù da heuliañ]]
+(peurgetket [[{{ns:4}}:Reolennoù envel|reolennoù envel]],
+[[{{ns:4}}:Ur savboent neptu|ur savboent neptu]]),
+hag [[{{ns:4}}:Ar fazioù stankañ|ar fazioù stankañ]].
+
+Mar fell deoc'h e rafe berzh {{SITENAME}}, trugarez da chom hep degas ennañ dafar gwarezet gant [[{{ns:4}}:Copyright|gwirioù aozer (copyrights)]]. An atebegezh wiraouel a c'hallfe ober gaou d'ar raktres.",
+'rcnote' => "Setu aze an/ar <strong>$1</strong> (g/c'h)kemm diwezhañ bet c'hoarvezet e-pad an/ar <strong>$2</strong> deiz diwezhañ.",
+'rcnotefrom' => "Setu aze roll ar c'hemmoù c'hoarvezet abaoe an/ar <strong>$2</strong> (<b>$1</b> d'ar muiañ).",
+'rclistfrom' => "Diskouez ar c'hemmoù diwezhañ abaoe an/ar $1.",
+'rclinks' => "Diskouez an/ar $1 (g/c'h)kemm diwezhañ c'hoarvezet e-pad an/ar $2 devezh diwezhañ; $3 kemmoù dister.", // Looxix
+'diff' => 'diforc\'h',
+'hist' => 'ist',
+'hide' => 'kuzhat',
+'show' => 'diskouez',
+'minoreditletter' => 'D',
+'newpageletter' => 'N',
+
+# Upload
+#
+'upload' => 'Eilañ war ar servijer',
+'uploadbtn' => 'Eilañ ur restr',
+'reupload' => 'Eilañ adarre',
+'reuploaddesc' => 'Distreiñ d\'ar furmskrid.',
+
+'uploadnologin' => 'diluget',
+'uploadnologintext' => "ret eo deoc'h bezañ [[Special:Userlogin|luget]]
+evit eilañ restroù war ar servijer.",
+'uploaderror' => "Fazi",
+'uploadtext' => "'''PAOUEZIT!''' A-raok eilañ ho restr war ar servijer,
+sellit ouzh ar [[Project:Reolennoù implijout ar skeudennoù|reolennoù implijout skeudennoù]] war {{SITENAME}} ha bezit sur e rit diouto.<br />
+Na zisoñjit ket leuniañ ar [[Project:Pajenn zeskrivañ ur skeudenn|bajenn zeskrivañ ur skeudenn]] pa vo war ar servijer.
+
+Evit gwelet ar skeudennoù bet karget war ar servijer c'hoazh pe evit klask en o zouez, kit da [[Special:Imagelist|roll ar skeudennoù]].
+Rollet eo an enporzhiadennoù hag an diverkadennoù war [[Project:Kazetenn_an_enporzhiadennoù|kazetenn an enporzhiadennoù]].
+
+Grit gant ar furmskrid a-is evit eilañ war ar servijer skeudennoù da vezañ implijet en ho pennadoù.
+War an darn vrasañ eus ar merdeerioù e welot ur bouton \"Browse...\" a zigor prenestr kendivizout boas ho reizhiad korvoiñ evit digeriñ restroù.
+Diuzit ur restr a zeuio hec'h anv war wel er vaezienn zo e-kichen ar bouton.
+Kadarnaat a rankit ober ivez, en ur askañ al log zo aze evit se, e touj eilenn ar restr-mañ d'ar gwirioù aozer.
+Klikit war ar bouton \"Kas\" a-benn echuiñ ganti.
+Mard eo gorrek ho kevreadenn e c'hall padout ur frapadig.
+
+Ar furmadoù erbedet zo JPEG evit al luc'hskeudennoù, PNG
+evit an tresadennoù hag ar skeudennoù all, hag OGG evit ar restroù son.
+Lakait anvioù deskrivañ fraezh d'ho restroù, kuit dezho da vezañ kammgemmesket.
+Evit enklozañ ar skeudenn en ur pennad, lakait er pennad-se ul liamm skrivet evel-henn :
+'''<nowiki>[[image:anv_ar_restr.jpg]]</nowiki>''' pe
+'''<nowiki>[[image:anv_ar_restr.png|testenn all]]</nowiki>''' pe
+'''<nowiki>[[media:anv_ar_restr.ogg]]</nowiki>''' evit ar sonioù.
+
+Na zisoñjit ket e c'hall bezañ degaset kemmoù er restroù eilet ganeoc'h, evel war kement pajenn zo eus {{SITENAME}}, ma soñj d'an implijidi all ez eo mat evit ar c'helc'hgeriadur. Mat eo deoc'h gouzout ivez e c'haller stankañ ouzhoc'h ar gwir da vont ouzh ar servijer ma ne implijit ket ar reizhiad evel m'eo dleet.",
+"uploadlog" => "log upload", // FIXME
+"uploadlogpage" => "Log_upload", // FIXME
+"uploadlogpagetext" => "Setu roll ar restroù diwezhañ bet eilet war ar servijer.
+An eur merket eo hini ar servijer (UTC).
+<ul>
+</ul>",
+'filename' => 'Anv&nbsp;',
+'filedesc' => 'Deskrivadur&nbsp;',
+'filestatus' => 'Statud ar gwirioù aozer',
+'filesource' => 'Mammenn',
+'copyrightpage' => "{{ns:4}}:Gwirioù aozer (Copyright)",
+'copyrightpagename' => "aotre {{SITENAME}}",
+'uploadedfiles' => "Restroù eilet",
+'minlength' => "Teir lizherenn da nebeutañ a rank bezañ lakaet da anvioù evit ar skeudennoù.",
+'illegalfilename' => 'Lakaet ez eus bet er restr « $1 » arouezennoù n\'int ket aotreet evit titl ur bajenn. Mar plij, adanvit ar restr hag adkasit anezhi.',
+'badfilename' => 'Anvet eo bet ar skeudenn « $1 ».',
+'badfiletype' => '« .$1 » n\'eo ket ur furmad erbedet evit ar restroù skeudenn.',
+'largefile' => '100Ko eo ar vent vrasañ erbedet evit ar restroù skeudenn.',
+'successfulupload' => 'Eiladenn kaset da benn vat',
+'fileuploaded' => "Eilet eo bet ar restr \"$1\" war ar servijer.
+Heuilhit al liamm-mañ : ($2) evit mont ouzh ar bajenn zeskrivañ ha reiñ titouroù diwar-benn ar restr, da skouer an orin anezhi, an deiz m'eo bet savet, an aozer anezhi, pe kement titour all a c'hall bezañ ganeoc'h.",
+'uploadwarning' => 'Diwallit!',
+'savefile' => 'Enrollañ ar restr',
+'uploadedimage' => '« [[$1]] » eilet war ar servijer',
+'uploaddisabled' => 'Ho tigarez, diweredekaet eo bet kas ar restr-mañ.',
+'uploadcorrupt' => "Brein eo ar restr-mañ, par eo he ment da netra pe fall eo an astenn anezhi.
+Gwiriit anezhi mar plij.",
+'fileexists' => "Ur restr all gant an anv-se zo c'hoazh. Trugarez da wiriañ $1. Ha sur oc'h da gaout c'hoant da gemmañ ar restr-mañ ?",
+'filemissing' => 'Restr ezvezant',
+
+
+# Image list
+#
+'imagelist' => 'Roll ar skeudennoù',
+'imagelisttext' => 'Setu ur roll $1 skeudenn rummet $2.',
+'getimagelist' => 'Oc\'h adtapout roll ar skeudennoù',
+'ilsubmit' => 'Klask',
+'showlast' => 'diskouez an/ar $1 skeudenn ziwezhañ rummet dre $2.',
+'byname' => 'dre o anv',
+'bydate' => 'dre an deiziad anezho',
+'bysize' => 'dre o ment',
+'imgdelete' => 'diverk',
+'imgdesc' => 'deskr',
+'imglegend' => "Alc'hwez: (deskr) = diskouez/kemmañ deskrivadur ar skeudenn.",
+'imghistory' => 'Istor ar skeudenn',
+'revertimg' => 'adlak',
+'deleteimg' => 'diverk',
+'deleteimgcompletely' => 'diverk',
+'imghistlegend' => "Alc'hwez: (brem) = setu ar skeudenn zo bremañ, (diverk) = diverkañ ar stumm kozh-mañ, (adlak) = adlakaat ar stumm kozh-mañ.
+<br /><i>Klikit war an deiziad evit gwelet ar skeudenn eilet d'an deiziad-se</i>.",
+'imagelinks' => 'Liammoù war-du ar skeudenn',
+'linkstoimage' => 'Ul liamm war-du ar skeudenn-mañ zo war ar pajennoù a-is :',
+'nolinkstoimage' => 'N\'eus liamm ebet war-du ar skeudenn-mañ war pajenn ebet.',
+'showbigimage' => 'Pellgargañ ur stumm uhel e bizhder ($1x$2, $3 Ko)',
+
+# Statistics
+
+'statistics' => 'Stadegoù',
+'sitestats' => 'Stadegoù al lec\'hienn',
+'userstats' => 'Stadegoù implijer',
+'sitestatstext' => '<b>$1</b> (b/f)pajenn zo er bank roadennoù evit poent.
+
+Er sifr-mañ emañ ar pajennoù "kaozeal", ar pajennoù a denn da {{SITENAME}}, ar pajennoù bihanañ ("stouvoù"), ar pajennoù adkas ha meur a seurt pajenn all n\'haller ket sellet outo evel pennadoù.
+Mar lakaer ar pajennoù-se er-maez e chom <b>$2</b> (b/f)pajenn zo moarvat gwir pennadoù.<p>
+<b>$3</b> (b/f)pajenn zo bet sellet outo ha <b>$4</b> (b/f)pajenn zo bet kemmet
+
+abaoe m\'eo bet hizivaet ar meziant (31 Here 2002).
+Ar pezh a ra ur geidenn a <b>$5</b> (g/c\'h)kemm dre bajenn ha <b>$6</b> selladenn evit ur c\'hemm.",
+"userstatstext" => "<b>$1</b> implijer enrollet zo.
+En o zouez, <b>$2</b> zo ganto ar statud merour (sellet ouzh $3).',
+
+
+# Maintenance Page
+#
+'disambiguations' => 'Pajennoù disheñvelaat',
+'disambiguationspage' => "{{ns:4}}:Liammoù_ouzh_ar_pajennoù_disheñvelaat",
+'disambiguationstext' => "Liammet eo ar pennadoù da-heul ouzh ur <i>bajenn zisheñvelaat</i>. Padal e tlefent bezañ liammet ouzh an danvez anezho.<br />Sellet e vez ouzh ur bajenn evel ouzh ur bajenn zisheñvelaat m'eo liammet adal $1.<br />ne vez ket kemeret e kont al liammoù adal <i>lec'hioù</i> all.",
+'doubleredirects' => "Adkasoù doubl",
+'doubleredirectstext' => "<b>Diwallit:</b> Gallout a ra bezañ \"pozitivoù faos\ er roll-mañ. D'ar mare-se eo moarvat peogwir ez eus testenn war bajenn an #REDIRECT kentañ ivez.<br />War bep linenn emañ al liammoù war-du pajenn an adkas 1{{añ}} hag en eil hag ivez linenn gentañ pajenn an eil adkas zo sañset reiñ ar pal \"gwirion\". War-du ar pal-se e tlefe liammañ an #REDIRECT kentañ.",
+'brokenredirects' => 'Adkasoù torret',
+'brokenredirectstext' => 'Kas a ra an adkasoù-mañ d\'ur bajenn n\'eus ket anezhi.',
+
+
+# Miscellaneous special pages
+#
+'lonelypages' => 'Pajennoù en o-unan',
+'unusedimages' => 'Skeudennoù en o-unan',
+'popularpages' => 'Pajennoù sellet ar muiañ',
+'nviews' => '$1 selladenn',
+'wantedpages' => 'Pajennoù goulennet ar muiañ',
+'nlinks' => '$1 daveenn',
+'allpages' => 'An holl bajennoù',
+'randompage' => 'Ur bajenn dre zegouezh',
+'shortpages' => 'Pennadoù berr',
+'longpages' => 'Pennadoù hir',
+'listusers' => 'Roll ar berzhidi',
+'specialpages' => 'Pajennoù dibar',
+'spheading' => 'Pajennoù dibar',
+'recentchangeslinked' => 'Heuliañ al liammoù',
+'rclsub' => "(eus ar pajennoù liammet ouzh \"$1\")",
+'newpages' => 'Pajennoù nevez',
+'ancientpages' => 'Pennadoù koshañ',
+'move' => 'adenvel',
+'movethispage' => 'Adenvel ar bajenn',
+'unusedimagestext' => "<p>Na zisoñjit e c'hall lec'hiennoù all, {{SITENAME}}où all, kaout ul liamm eeun war-du ar skeudenn-mañ hag e c'hall neuze ar skeudenn-mañ bezañ bet lakaet war ar roll-mañ tra m'emañ implijet e lec'h all.", // TODO: grammar
+'booksources' => "Oberennoù dave",
+'booksourcetext' => "Setu ur rollad liammoù etrezek lec'hiennoù all a werzh levrioù nevez pe eildorn a gavot enno, marteze, titouroù war an oberennoù a glaskit. N'eo ket stag {{SITENAME}} ouzh hini ebet eus ar c'hevredadoù-se, n'eo ket en sell e mod ebet da vrudañ anezho.",
+'alphaindexline' => '$1 da $2',
+'version' => 'Stumm',
+
+# All pages
+#
+'allinnamespace' => "An holl bajennoù (esaouenn $1)",
+'allpagesnext' => "War-lerc'h",
+'allpagesprev' => "Kent",
+'allpagessubmit' => "Kadarnaat",
+
+# Email this user
+#
+'mailnologin' => 'Chomlec\'h ebet',
+'mailnologintext' => 'Ret eo deoc\'h bezañ [[Special:Userlogin|luget]]
+ha bezañ merket ur chomlec\'h postel reizh en ho [[Special:Preferences|penndibaboù]]
+evit gallout kas ur postel d\'un implijer all.',
+'emailuser' => 'Kas ur postel d\'an implijer-mañ',
+'emailpage' => 'Postel implijer',
+'emailpagetext' => "M\'en deus an implijer-se merket ur chomlec\'h postel reizh en e benndibaboù e vo kaset ur postel dezhañ dre ar furmskrid a-is.
+E maezienn \"Kaser\" ho postel e vo merket ar chomlec'h postel resisaet ganeoc'h-c'hwi, d'ar resever da c'halloud respont deoc'h ma kar.",
+'noemailtitle' => 'Chomlec\'h elektronek ebet',
+'noemailtext' => "N'en deus ket an implijer-mañ resisaet chomlec'h postel reizh ebet pe dibabet en deus chom hep resev posteloù a-berzh an implijerien all.",
+
+'emailfrom' => 'Kaser',
+'emailto' => 'Resever',
+'emailsubject' => 'Danvez',
+'emailmessage' => 'Postel',
+'emailsend' => 'Kas',
+'emailsent' => 'Postel kaset',
+'emailsenttext' => 'Kaset eo bet ho postel.',
+'usermailererror' => 'Fazi postel :',
+'defemailsubject' => 'postel kaset eus {{SITENAME}}',
+
+# Watchlist
+#
+'watchlist' => 'Rollad evezhiañ',
+'nowatchlist' => "N'eus pennad ebet en ho rollad evezhiañ.",
+'watchnologin' => "Diluget",
+'watchnologintext' => "Ret eo deoc'h bezañ [[Special:Userlogin|luget]]
+evit kemmañ ho roll.",
+'addedwatch' => 'Ouzhpennet d\'ar roll',
+'addedwatchtext' => "<p>Ouzh ho <a href=\"{{localurl:Special:Watchlist}}\">rollad evezhiañ</a> eo bet ouzhpennet ar bajenn \"$1\".
+Kemmoù da zont ar bajenn-mañ ha re ar bajenn gaozeal stag outi a vo rollet amañ hag e teuio ar bajenn <b>e tev</b> er <a href=\"{{localurl:Special:Recentchanges}}\">roll kemmoù diwezhañ</a> evit bezañ gwelet aesoc'h ganeoc'h.</p>
+
+<p>Evit tennañ ar bajenn-mañ a-ziwar ho rollad evezhiañ. klikit war \"Paouez da evezhiañ\" er framm merdeiñ.</p>",
+'removedwatch' => "Lamet a-ziwar ar rollad evezhiañ",
+'removedwatchtext' => "Lamet eo bet ar bajenn « $1 » a-ziwar ho rollad evezhiañ.",
+'watch' => 'Evezhiañ',
+'watchthispage' => 'Evezhiañ ar bajenn-mañ',
+'unwatch' => 'paouez da evezhiañ',
+'unwatchthispage' => 'Paouez da evezhiañ',
+'notanarticle' => 'Pennad ebet',
+'watchnochange' => "Pajenn ebet eus ar re evezhiet ganeoc'h n'eo bet kemmet e-pad ar prantad spisaet",
+'watchdetails' => "Lakaet hoc'h eus $1 (b/f)pajenn dindan evezh, anez kontañ ar pajennoù kaozeal. [$4 Diskouez ha kemmañ ar roll klok].", // Looxix
+'watchmethod-recent' => "Gwiriañ ar c'hemmoù diwezhañ er pajennoù dindan evezh", // Looxix
+'watchmethod-list' => "Gwiriañ ar c'hemmoù diwezhañ evit ar pajennoù evezhiet", // Looxix
+'removechecked' => "Lemel ar pennadoù diuzet a-ziwar ar rollad evezhiañ",
+'watchlistcontains' => "$1 (b/f)pajenn zo en ho rollad evezhiañ",
+'watcheditlist' => "Setu aze ho rollad evezhiañ dre urzh al lizherenneg. Diuzit ar pajennoù hoc'h eus c'hoant da lemel a-ziwar ar roll ha klikit war ar bouton \"lemel a-ziwar ar rollad evezhiañ\" e traoñ ar skramm.",
+'removingchecked' => "Lamet eo ar pennadoù diuzet a-ziwar ho rollad evezhiañ...",
+'couldntremove' => "Dibosupl da lemel kuit ar pennad « $1 »...",
+'iteminvalidname' => "ur gudenn zo gant ar pennad « $1 » : n'eo ket mat e anv...",
+'wlnote' => "A-is emañ an/ar $1 (g/c'h)kemm diwezhañ abaoe an/ar <b>$2</b> eurvezh diwezhañ.", // Looxix
+'wlshowlast' => "diskouez an/ar $1 eurvezh $2 (z)devezh $3 diwezhañ",
+'wlsaved' => "Ne vez hizivaet ar rollad evezhiañ nemet ur wech bep eurvezh kuit da sammañ ar servijer betek re.",
+
+# Delete/protect/revert
+#
+'deletepage' => 'Diverkañ ur bajenn',
+'confirm' => 'Kadarnaat',
+'excontent' => "endalc'had '$1'",
+'exbeforeblank' => "A-raok diverkañ e oa an endalc'had : '$1'",
+'exblank' => 'pajenn c\'houllo',
+'confirmdelete' => 'Kadarnaat an diverkañ',
+'deletesub' => '(O tiverkañ "$1")',
+'historywarning' => 'Diwallit: War-nes diverkañ ur bajenn ganti un istor emaoc\'h :',
+'confirmdeletetext' => "War-nes diverkañ da vat ur bajenn pe ur skeudenn eus ar bank roadennoù emaoc'h. Diverket e vo ivez an holl stummoù kozh stag outi.
+Kadarnait, mar plij, eo mat an dra-se hoc'h eus c'hoant, e komprenit mat an heuliadoù, hag e rit se diouzh an [[{{ns:4}}:Erbedadennoù ha reolennoù da heuliañ|erbedadennoù ha reolennoù da heuliañ]].",
+'actioncomplete' => 'Diverkadenn kaset da benn',
+'deletedtext' => '"Diverket eo bet $1".
+Sellet ouzh $2 evit roll an diverkadennoù diwezhañ.',
+'deletedarticle' => 'o tiverkañ "$1"',
+'dellogpage' => 'Istor an diverkadennoù',
+'dellogpagetext' => 'Setu roll an diverkadennoù diwezhañ.
+Eur ar servijer (UTC) eo an eur merket.
+<ul>
+</ul>',
+'deletionlog' => 'istor an diverkadennoù',
+'reverted' => 'Adlakaat ar stumm kent',
+'deletecomment' => 'Abeg an diverkadenn',
+'imagereverted' => 'Adlakaet eo bet ar stumm kent.',
+'rollback' => 'disteuler ar c\'hemmoù',
+'rollback_short' => 'Disteuler',
+'rollbacklink' => 'disteuler',
+'rollbackfailed' => 'C\'hwitet eo bet an distaoladenn',
+'cantrollback' => "Dibosupl da zisteuler: an aozer diwezhañ eo an hini nemetañ da vezañ kemmet ar pennad-mañ",
+'alreadyrolled' => "Dibosupl eo disteuler ar c'hemm diwezhañ graet e [[:$1]]
+gant [[User:$2|$2]] ([[User talk:$2|Talk]]); kemmet pe distaolet eo bet c'hoazh gant unan bennak all.
+
+Ar c'hemm diwezhañ a oa gant [[User:$3|$3]] ([[User talk:$3|Talk]]).", //Looxix
+# only shown if there is an edit comment
+'editcomment' => "Diverradenn ar c'hemm a oa: \"<i>$1</i>\".", //Looxix
+'revertpage' => 'Adlakaat kemm diwezhañ $1',
+'protectlogpage' => 'Log_gwareziñ',
+'protectlogtext' => "Sellet ouzh ar [[{{ns:4}}:Pajenn warezet|c'huzulioù diwar-benn ar pajennoù gwarezet]].",
+'protectedarticle' => 'en/he deus gwarezet [[$1]]',
+'unprotectedarticle' => 'en/he deus diwarezet [[$1]]',
+
+'protectsub' => '(Stankañ "$1")',
+'confirmprotect' => 'Kadarnaat ar stankañ',
+'confirmprotecttext' => 'Ha mennet oc\'h da wareziñ ar bajenn-mañ ?',
+'protectcomment' => 'Abeg ar stankañ',
+
+'unprotectsub' => '(Distankañ "$1")',
+'confirmunprotecttext' => 'Ha mennet oc\'h da ziwareziñ ar bajenn-mañ?',
+'confirmunprotect' => 'Abeg an distankañ',
+'unprotectcomment' => 'Abeg an distankañ',
+'protectmoveonly' => 'Gwareziñ an adkasoù hepken',
+
+
+
+# Groups
+#
+'editusergroup' => 'Kemmañ ar strolladoù implijerien',
+
+# Special:Undelete
+#
+'undelete' => 'Diziverkañ ar bajenn ziverket',
+'undeletepage' => 'Gwelet ha diziverkañ ar bajenn ziverket',
+'undeletepagetext' => 'Diverket eo bet ar pajennoù-mañ, er pod-lastez emaint met er bank roadennoù emaint c\'hoazh ha gallout a reont bezañ diziverket eta.
+Ingal e c\'hall ar pod-lastez bezañ goullonderet.',
+
+'undeletearticle' => 'Diziverkañ ar pennadoù diverket',
+'undeleterevisions' => '$1 (g/c\'h)kemm diellaouet',
+'undeletehistory' => "Ma tiziverkit ar bajenn e vo diziverket an holl gemmoù bet degaset en hec'h istor.
+Ma'z eus bet krouet ur bajenn nevez dezhi an hevelep anv abaoe an diverkadenn, e teuio war wel ar c'hemmoù diziverket er rann istor a-raok, ha ne vo ket erlec'hiet ar stumm red ent emgefre.",
+"undeleterevision" => "Stumm diverket ($1)",
+'undeletebtn' => 'Diziverkañ!',
+'undeletedarticle' => "Diziverket\"$1\"",
+'undeletedrevisions' => "$1 stumm bet diziverket",
+
+# Contributions
+#
+'contributions' => 'Degasadennoù',
+'mycontris' => 'Ma degasadennnoù',
+'contribsub' => 'Evit $1',
+'nocontribs' => 'N\'eus bet kavet kemm ebet o klotañ gant an dezverkoù-se.',
+'ucnote' => "Setu an/ar <b>$1</b> (b/c'h)kemm diwezhañ bet graet gant an implijer-mañ e-pad an/ar <b>$2</b> devezh diwezhañ.",
+'uclinks' => 'diskouez an/ar $1 (g/c\'h)kemm diwezhañ; diskouez an/ar $2 devezh diwezhañ.',
+'uctop' => ' (diwezhañ)',
+
+# What links here
+#
+'whatlinkshere' => 'Pajennoù liammet',
+'notargettitle' => 'netra da gavout',
+'notargettext' => 'Merkit anv ur bajenn da gavout pe hini un implijer.',
+'linklistsub' => '(Roll al liammoù)',
+'linkshere' => 'Ar pajennoù a-is zo enno ul liamm a gas war-du ar bajenn-mañ:',
+'nolinkshere' => 'N\'eus pajenn ebet enni ul liamm war-du ar bajenn-mañ.',
+'isredirect' => 'pajenn adkas',
+
+# Block/unblock IP
+#
+'blockip' => 'Stankañ ouzh ur chomlec\'h IP',
+'blockiptext' => "Grit gant ar furmskrid a-is evit stankañ ar moned skrivañ ouzh ur chomlec'h IP bennak.
+Seurt diarbennoù n'hallont bezañ kemeret nemet evit mirout ouzh an taolioù gaou hag a-du gant an [[{{ns:4}}:Erbedadennoù ha reolennoù da heuliañ|erbedadennoù ha reolennoù da heuliañ]].
+Roit a-is an abeg resis (o verkañ, da skouer, roll ar pajennoù bet graet gaou outo).",
+'ipaddress' => 'Chomlec\'h IP',
+'ipbreason' => 'Abeg ar stankañ',
+'ipbsubmit' => 'Stankañ ouzh ar chomlec\'h-mañ',
+'badipaddress' => 'Kamm eo ar chomlec\'h IP.',
+'blockipsuccesssub' => 'Stankadenn deuet da benn vat',
+'blockipsuccesstext' => "Stanket ez eus bet ouzh chomlec'h IP \"$1\".
+<br />Gallout a rit sellet ouzh ar [[Special:Ipblocklist|bajenn-mañ]] evit gwelet roll ar chomlec'hioù IP stanket outo.",
+'unblockip' => "Distankañ ur chomlec'h IP",
+'unblockiptext' => 'Grit gant ar furmskrid a-is evit adsevel ar moned skrivañ ouzh ur chomlec\'h IP bet stanket a-gent.',
+'ipusubmit' => 'Distankañ ar chomlec\'h-mañ',
+'ipblocklist' => 'Roll ar chomlec\'hioù IP stanket outo',
+'blocklistline' => '$1, $2 en/he deus stanket $3',
+'blocklink' => 'stankañ',
+'unblocklink' => 'distankañ',
+'contribslink' => 'degasadenn',
+'autoblocker' => "Emstanket rak rannañ a rit ur chomlec'h IP gant \"$1\". Abeg : \"$2\".",
+'blocklogpage' => 'Log stankañ',
+'blocklogentry' => 'o stankañ « $1 »',
+'blocklogtext' => "Setu roud stankadennoù ha distankadennoù an implijerien. N'eo ket bet rollet ar chomlec'hioù IP bet stanket outo ent emgefre. Sellet ouzh [[Special:Ipblocklist|roll an implijerien stanket]] evit gwelet piv zo stanket e gwirionez.",
+'unblocklogentry' => 'o tistankañ "$1"',
+'ipb_expiry_invalid' => 'amzer termen direizh.',
+'ip_range_invalid' => "Stankañ IP direizh.",
+'proxyblocker' => 'Stanker proksi',
+'proxyblockreason' => "Stanket eo bet hoc'h IP rak ur proksi digor eo. Trugarez da gelaouiñ ho pourvezer moned ouzh ar Genrouedad pe ho skoazell deknikel eus ar gudenn surentez-mañ.",
+'proxyblocksuccess' => "Echu.",
+'ipbexpiry' => 'Pad ar stankadenn',
+
+# Developer tools
+#
+'lockdb' => 'Prennañ ar bank',
+'unlockdb' => 'Dibrennañ ar bank',
+'lockdbtext' => "Ma vez prennet ar bank roadennoù n'hallo ket mui implijer ebet kemmañ pajennoù, enrollañ e benndibaboù, kemmañ e rollad evezhiañ na seveniñ oberiadenn ebet a c'houlenn degas kemm pe gemm er bank roadennoù.
+Kadarnait, mar plij, eo se hoc'h eus c'hoant da ober hag e vo dibrennet ar bank ganeoc'h kerkent ha ma vo bet kaset da benn hoc'h oberiadenn drezalc'h.",
+'unlockdbtext' => "Dibrennañ ar bank a lakay adarre an holl implijerien e-tailh da gemmañ pajennoù, hizivaat o fenndibaboù hag o rollad evezhiañ ha seveniñ an holl oberiadennoù a c'houlenn ma vefe kemmet ar bank roadennoù.
+Kadarnait, mar plij, eo se hoc'h eus c'hoant da ober.",
+"lockconfirm" => "Ya, kadarnaat a ran e fell din prennañ ar bank roadennoù.",
+"unlockconfirm" => "Ya, kadarnaat a ran e fell din dibrennañ ar bank roadennoù.",
+
+'lockbtn' => 'Prennañ ar bank',
+'unlockbtn' => 'Dibrennañ ar bank',
+'locknoconfirm' => 'N\'eo ket bet asket al log kadarnaat ganeoc\'h.',
+'lockdbsuccesssub' => 'Bank prennet.',
+'unlockdbsuccesssub' => 'Bank dibrennet.',
+"lockdbsuccesstext" => "Prennet eo bank roadennnoù {{SITENAME}}.
+
+<br />Na zisoñjit ket e zibrennañ pa vo bet kaset da benn vat hoc'h oberiadenn drezalc'h.",
+'unlockdbsuccesstext' => 'Dibrennet eo bank roadennoù {{SITENAME}}.',
+
+# Special:Makesysop
+'makesysoptitle' => 'A ro ar gwirioù merañ.',
+'makesysoptext' => 'Graet e vez gant ar furmskrid-mañ gant ar Pennoù-bras a-benn reiñ ar gwirioù merañ.
+Lakait anv an implijer er voest ha pouezit war ar bouton evit reiñ ar gwirioù dezhañ/i.',
+'makesysopname' => 'Anv an implijer(ez):',
+'makesysopsubmit' => 'Reiñ ar gwirioù merañ d\'an implijer(ez)-mañ',
+'makesysopok' => "<b>An implijer(ez) \"$1\" zo bremañ merour(ez)</b>",
+'makesysopfail' => "<b>N'en/he deus ket gallet an implijer(ez) \"$1\" resev ar gwirioù merañ. (Ha skrivet hoc'h eus an anv evel m'eo dleet?)</b>",
+'rights' => 'Gwirioù:',
+'set_user_rights' => "A laka gwirioù an implijer(ez)",
+'user_rights_set' => "<b>Hizivaet eo gwirioù an implijer(ez) \"$1\"</b>",
+'setbureaucratflag' => "A ro ar gwirioù Penn-bras",
+'set_rights_fail' => "<b>N'eus ket bet gallet lakaat e plas gwirioù an implijer(ez) \"$1\". (Ha skrivet hoc'h eus an anv evel m'eo dleet?)</b>",
+'makesysop' => 'Reiñ ar gwirioù merañ d\'un implijer(ez)',
+
+
+# Spam
+#
+'spamprotectionmatch' => "Dihunet eo bet an detektour Spam: $1 gant an destenn-mañ",
+'spamprotectiontext' => "Pajenn warezet ent emgefre abalamour d'ar Spam",
+'spamprotectiontitle' => "Pajenn warezet ent emgefre abalamour d'ar Spam",
+
+# Patrolling
+#
+'markaspatrolleddiff' => 'Merkañ evel gwiriet',
+'markaspatrolledtext' => 'Merkañ ar pennad-mañ evel gwiriet',
+'markedaspatrolled' => 'Merkañ evel gwiriet',
+'markedaspatrolledtext' => 'Merket eo bet ar stumm diuzet evel gwiriet.',
+'rcpatroldisabledtext' => "Diweredekaet eo bet an arc'hwel evezhiañ ar c'hemmoù diwezhañ.",
+
+# Move page
+#
+'movepage' => 'Adenvel ur pennad',
+"movepagetext" => "Grit gant ar furmskrid a-is evit adenvel ur pennad hag adkas an holl stummoù kent anezhañ war-du an anv nevez.
+Dont a raio an titl kentañ da vezañ ur bajenn adkas war-du an titl nevez.
+Ne vo ket kemmet liammoù an titl kozh ha ne vo ket dilec'hiet ar bajenn gaozeal, ma'z eus anezhi.
+
+'''DIWALLIT!'''
+Gallout a ra kement-se bezañ ur c'hemm bras ha dic'hortoz evit ur pennad a vez sellet outi alies;
+bezit sur e komprenit mat an heuliadoù a-raok kenderc'hel ganti.",
+"movepagetalktext" => "Gant se e vo adanvet ent emgefre ar bajenn gaozeal stag, ma'z eus anezhi '''nemet ma:'''
+*ec'h adanvit ur bajenn war-du ul lec'h all,
+*ez eus ur bajenn gaozeal c'hoazh gant an anv nevez, pe
+*diweredekaet hoc'h eus ar bouton a-is.
+
+En degouezh-se e rankot adenvel pe gendeuziñ ar bajenn c'hwi hoc'h-unan ma karit.",
+
+'movearticle' => 'Dilec\'hiañ ar pennad',
+'movenologin' => 'Diluget',
+'movenologintext' => "Evit adenvel ur pennad e rankit bezañ [[Special:Userlogin|luget]] evel un implijer enrollet.",
+'newtitle' => "anv nevez",
+'movepagebtn' => "Adenvel ar pennad",
+'pagemovedsub' => "Dilec'hiadenn kaset da benn vat",
+'pagemovedtext' => "Adkaset eo bet ar pennad \"[[$1]]\" da \"[[$2]]\".",
+'articleexists' => "Ur pennad gantañ an anv-se zo dija pe n\'eo ket reizh an titl hoc\'h eus dibabet.
+Dibabit unan all mar plij.",
+'talkexists' => "Dilec'hiet mat eo bet ar bajenn hec'h-unan met chomet eo ar bajenn gaozeal rak unan all a oa dija gant an anv nevez-se. Kendeuzit anezho c'hwi hoc'h-unan mar plij.",
+'1movedto2_redir' => "$1 adkaset war-du $2 (adkas)",
+'movedto' => 'adanvet e',
+'movetalk' => 'Adenvel ivez ar bajenn "gaozeal", mar bez ret.',
+'talkpagemoved' => 'Dilec\'hiet eo bet ivez ar bajenn gaozeal stag.',
+'talkpagenotmoved' => '<strong>N\'eo ket bet</strong> dilec\'hiet ar bajenn gaozeal stag.',
+'1movedto2' => '$1 adkaset war-du $2',
+'movereason' => 'Abeg an adkas',
+
+
+# Export page
+'export' => 'Ezporzhiañ pajennoù',
+'exporttext' => "Gallout a rit ezporzhiañ en XML an destenn ha pennad istor ur bajenn pe ur strollad pajennoù; a-benn neuze e c'hall an disoc'h bezañ enporzhiet en ur wiki all a ya en-dro gant ar meziant MediaWiki, treuzfurmet pe enrollet da vezañ implijet diouzh ma karot.",
+'exportcuronly' => "Ezporzhiañ hepken ar stumm red hep an istor anezhañ",
+
+# Namespace 8 related
+
+'allmessages' => 'An holl gemennadennoù',
+'allmessagestext' => 'Setu roll an holl gemennadennoù a c\'haller kaout e bed MediaWiki',
+
+# Thumbnails
+
+'thumbnail-more' => 'Brasaat',
+'missingimage' => "<b>Skeudenn a vank</b><br /><i>$1</i>",
+
+# Special:Import
+'import' => 'Enporzhiañ pajennoù',
+'importfailed' => 'C\'hwitet eo an enporzhiadenn: $1',
+'importhistoryconflict' => 'Divankadennoù zo er pennad istor ha tabut zo gant se (marteze eo bet enporzhiet ar bajenn araozoc\'h)',
+'importnotext' => 'Goullo pe hep tamm testenn ebet',
+'importsuccess' => 'Deuet eo an enporzhiadenn da benn vat!',
+'importtext' => 'Ezporzhiit ur restr adal ar wiki orin en ur implij an arc\'hwel Special:Export, enrollit ar bajenn war ho pladenn ha degasit anezhi amañ.',
+
+# Keyboard access keys for power users
+# inherit
+
+# tooltip help for the main actions
+'tooltip-compareselectedversions' => 'Sellet ouzh an diforc\'hioù zo etre daou stumm diuzet ar bajenn-mañ. [alt-v]',
+'tooltip-minoredit' => 'Merkañ ar c\'hemm-mañ evel dister [alt-i]',
+'tooltip-preview' => 'Rakwelet ar c\'hemmoù; trugarez d\'ober gantañ a-raok enrollañ! [alt-p]',
+'tooltip-save' => 'Enrollañ ho kemmoù [alt-s]',
+'tooltip-search' => 'Klask er wiki-mañ',
+'tooltip-watch' => 'Ouzhpennañ ar bajenn-mañ ouzh ho rollad evezhiañ',
+
+# Metadata
+'nocreativecommons' => "N'eo ket gweredekaet ar roadennoù meta 'Creative Commons RDF' war ar servijer-mañ.",
+'nodublincore' => "Diweredekaet eo ar roadennoù meta 'Dublin Core RDF' war ar servijer-mañ.",
+'notacceptable' => "N'eo ket ar servijer wiki-mañ evit pourchas roadennoù eo gouest hoc'h arval da lenn.",
+
+# Attribution
+'anonymous' => 'Implijer(ez) dianv eus {{SITENAME}}',
+'siteuser' => 'Implijer(ez) $1 eus {{SITENAME}}',
+'lastmodifiedatby' => "Kemmet eo bet ar bajenn-mañ da ziwezhañ d'an/ar $2, $1 gant $3",
+'and' => 'ha(g)',
+'contributions' => 'diazezet war labour $1.',
+'siteusers' => 'Implijer(ez) $1 eus {{SITENAME}}',
+'creditspage' => 'Pajennoù kredoù',
+
+# confirmemail
+'confirmemail' => 'Kadarnaat ar postel',
+'confirmemail_text' => 'Rankout a ra ar wiki-mañ bezañ gwiriet ho chomlec\'h postel a-raok gallout implijout nep arc\'hwel postel. Implijit ar bouton a-is evit kas ur postel kadarnaat d\'ho chomlec\'h. Ul liamm ennañ ur c\'hod a vo er postel. Kargit al liamm-se en o merdeer evit kadarnaat ho chomlec\'h.',
+'confirmemail_send' => 'Kas ur c\'hod kadarnaat',
+'confirmemail_sent' => 'Postel kadarnaat kaset',
+'confirmemail_sendfailed' => 'Dibosupl kas ar postel kadarnaat. Gwiriit ho chomlec\'h.',
+'confirmemail_invalid' => 'Kod kadarnaat kamm. Marteze eo aet ar c\'hod d\'e dermen',
+'confirmemail_success' => 'Kadarnaet eo ho chomlec\'h postel. A-benn bremañ e c\'hallit en em lugañ hag ober ho mad eus ar wiki.',
+'confirmemail_loggedin' => 'Kadarnaet eo ho chomlec\'h bremañ',
+'confirmemail_error' => 'Ur gudenn zo bet e-ser enrollañ ho kadarnadenn',
+'confirmemail_subject' => '{{SITENAME}} email address confirmation',
+'confirmemail_body' => 'Unan bennak, c\'hwi moarvat, gant ar chomlec\'h postel $1 en deus enrollet ur gont "$2" gant ar chomlec\'h postel-mañ war lec\'hienn {{SITENAME}}.
+
+A-benn kadarnaat eo deoc\'h ar gont-se ha gweredekaat an arc\'hwelioù postelerezh war {{SITENAME}}, digorit, mar plij, al liamm a-is en ho merdeer :
+
+$3
+
+Ma n\'eo ket bet graet ganeoc\'h na zigorit ket al liamm. Mont a raio ar c\'hod-mañ d\'e dermen d\'an/ar $4.',
+
+
+# Math
+'mw_math_png' => "Produiñ atav ur skeudenn PNG",
+'mw_math_simple' => "HTML m'eo eeun-kenañ, a-hend-all ober gant PNG",
+'mw_math_html' => "HTML mar bez tu, a-hend-all PNG",
+'mw_math_source' => "Leuskel ar c'hod TeX orin",
+'mw_math_modern' => "Evit ar merdeerioù arnevez",
+'mw_math_mathml' => 'MathML',
+
+
+'usercssjsyoucanpreview' => "'''Tun:''' grit gant ar bouton '''Rakwelet''' evit testiñ ho follenn css/js nevez a-raok enrollañ anezhi.",
+'usercsspreview' => "'''Dalc'hit soñj emaoc'h o rakwelet ho follenn css deoc'h ha n'eo ket bet enrollet c'hoazh!'''",
+'userjspreview' => "'''Dalc'hit soñj emaoc'h o rakwelet pe o testiñ ho kod javascript deoc'h ha n'eo ket bet enrollet c'hoazh!'''",
+
+# EXIF
+'exif-imagewidth' => 'Led',
+'exif-imagelength' => 'Hed',
+'exif-compression' => 'Seurt gwaskadur',
+'exif-samplesperpixel' => 'Niver a standilhonoù',
+'exif-xresolution' => 'Pizhder led ar skeudenn',
+'exif-yresolution' => 'Pizhder hed ar skeudenn',
+'exif-jpeginterchangeformat' => 'Lec\'hiadur ar SOI JPEG',
+'exif-jpeginterchangeformatlength' => 'Ment ar roadennoù JPEG en eizhbitoù',
+'exif-transferfunction' => 'Arc\'hwel treuzkas',
+'exif-datetime' => 'Deiziad hag eur kemm restr',
+'exif-imagedescription' => 'Titl ar skeudenn',
+'exif-make' => 'Oberier ar benveg',
+'exif-model' => 'Doare ar benveg',
+'exif-software' => 'Meziant bet implijet',
+'exif-artist' => 'Aozer',
+'exif-copyright' => 'Perc\'henn ar gwirioù aozer (copyright)',
+'exif-exifversion' => 'Stumm exif',
+'exif-makernote' => 'Notennoù an oberier',
+'exif-relatedsoundfile' => 'Restr son stag',
+'exif-flash' => 'Flash',
+'exif-whitebalance' => 'Mentel ar gwennoù',
+'exif-contrast' => 'Dargemm',
+'exif-saturation' => 'Saturadur',
+'exif-compression-1' => 'Hep gwaskañ',
+'exif-orientation-1' => 'Normal',
+'exif-orientation-2' => 'Eilpennet a-hed',
+'exif-orientation-3' => 'Troet eus 180°',
+'exif-orientation-4' => 'Eilpennet a-serzh',
+'exif-orientation-5' => 'Troet eus 90° a-gleiz hag eilpennet a-serzh',
+'exif-orientation-6' => 'Troet eus 90° a-zehou',
+'exif-orientation-7' => 'Troet eus 90° a-zehou hag eilpennet a-serzh',
+'exif-orientation-8' => 'Troet eus 90° a-gleiz',
+'exif-componentsconfiguration-0' => 'n\'eus ket anezhi',
+
+
+// exifgps:
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesBs.php b/languages/messages/MessagesBs.php
new file mode 100644
index 000000000000..62bc7f8e694a
--- /dev/null
+++ b/languages/messages/MessagesBs.php
@@ -0,0 +1,1094 @@
+<?php
+
+$namespaceNames = array(
+ NS_MEDIA => 'Medija',
+ NS_SPECIAL => 'Posebno',
+ NS_MAIN => '',
+ NS_TALK => 'Razgovor',
+ NS_USER => 'Korisnik',
+ NS_USER_TALK => 'Razgovor_sa_korisnikom',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Razgovor_{{grammar:instrumental|$1}}',
+ NS_IMAGE => 'Slika',
+ NS_IMAGE_TALK => 'Razgovor_o_slici',
+ NS_MEDIAWIKI => 'MedijaViki',
+ NS_MEDIAWIKI_TALK => 'Razgovor_o_MedijaVikiju',
+ NS_TEMPLATE => 'Šablon',
+ NS_TEMPLATE_TALK => 'Razgovor_o_šablonu',
+ NS_HELP => 'Pomoć',
+ NS_HELP_TALK => 'Razgovor_o_pomoći',
+ NS_CATEGORY => 'Kategorija',
+ NS_CATEGORY_TALK => 'Razgovor_o_kategoriji',
+);
+
+$quickbarSettings = array(
+ 'Nikakva', 'Pričvršćena lijevo', 'Pričvršćena desno', 'Plutajuća lijevo'
+);
+
+$skinNames = array(
+ 'Obična', 'Nostalgija', 'Kelnsko plavo', 'Pedington', 'Monparnas'
+);
+
+$magicWords = array(
+ # ID CASE SYNONYMS
+ 'redirect' => array( 0, '#Preusmjeri', '#redirect', '#preusmjeri', '#PREUSMJERI' ),
+ 'notoc' => array( 0, '__NOTOC__', '__BEZSADRŽAJA__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__FORSIRANISADRŽAJ__' ),
+ 'toc' => array( 0, '__TOC__', '__SADRŽAJ__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__BEZ_IZMENA__', '__BEZIZMENA__' ),
+ 'start' => array( 0, '__START__', '__POČETAK__' ),
+ 'end' => array( 0, '__END__', '__KRAJ__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'TRENUTNIMJESEC' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'TRENUTNIMJESECIME' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'TRENUTNIMJESECROD' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'TRENUTNIMJESECSKR' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'TRENUTNIDAN' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'TRENUTNIDANIME' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'TRENUTNAGODINA' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'TRENUTNOVRIJEME' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'BROJČLANAKA' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'BROJDATOTEKA', 'BROJFAJLOVA' ),
+ 'pagename' => array( 1, 'PAGENAME', 'STRANICA' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'STRANICE' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'IMENSKIPROSTOR' ),
+ 'namespacee' => array( 1, 'NAMESPACEE', 'IMENSKIPROSTORI' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'PUNOIMESTRANE' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE', 'PUNOIMESTRANEE' ),
+ 'msg' => array( 0, 'MSG:', 'POR:' ),
+ 'subst' => array( 0, 'SUBST:', 'ZAMJENI:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'NVPOR:' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'mini' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'mini=$1' ),
+ 'img_right' => array( 1, 'right', 'desno', 'd' ),
+ 'img_left' => array( 1, 'left', 'lijevo', 'l' ),
+ 'img_none' => array( 1, 'none', 'n', 'bez' ),
+ 'img_width' => array( 1, '$1px', '$1piksel' , '$1p' ),
+ 'img_center' => array( 1, 'center', 'centre', 'centar', 'c' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'okvir', 'ram' ),
+ 'int' => array( 0, 'INT:', 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'IMESAJTA' ),
+ 'ns' => array( 0, 'NS:', 'IP:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'LOKALNAADRESA:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'LOKALNEADRESE:' ),
+ 'server' => array( 0, 'SERVER', 'SERVER' ),
+ 'servername' => array( 0, 'SERVERNAME', 'IMESERVERA' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'SKRIPTA' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'GRAMATIKA:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', '__BEZTC__' ),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', '__BEZCC__' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'TRENUTNASEDMICA' ),
+ 'currentdow' => array( 1, 'CURRENTDOW', 'TRENUTNIDOV' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'IDREVIZIJE' ),
+ 'plural' => array( 0, 'PLURAL:', 'MNOŽINA:' ),
+ 'fullurl' => array( 0, 'FULLURL:', 'PUNURL:' ),
+ 'fullurle' => array( 0, 'FULLURLE:', 'PUNURLE:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:', 'LCPRVI:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:', 'UCPRVI:' ),
+ 'lc' => array( 0, 'LC:', 'LC:' ),
+ 'uc' => array( 0, 'UC:', 'UC:' ),
+);
+
+$fallback8bitEncoding = "iso-8859-2";
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = '/^([a-zćčžšđž]+)(.*)$/sDu';
+
+$messages = array(
+'1movedto2' => 'stranica [[$1]] premještena u stranicu [[$2]]',
+'1movedto2_redir' => 'stranica [[$1]] premještena u stranicu [[$2]] putem preusmjerenja',
+'monobook.css' => '/*
+*/',
+'monobook.js' => '
+/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Moja korisnička stranica\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Korisnička stranica za ip koju Vi uređujete kao\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Moja stranica za razgovor\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Razgovor o doprinosu sa ove IP adrese\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Moja podešavanja\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Spisak članaka koje pratite.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Spisak mog doprinosa\');
+ta[\'pt-login\'] = new Array(\'o\',\'Prijava nije obavezna, ali donosi mnogo koristi.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Prijava nije obavezna, ali donosi mnogo koristi.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Odjava sa projekta {{SITENAME}}\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Razgovor o sadržaju\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Možete da uređujete ovaj članak. Molimo Vas, koristite dugme "Prikaži izgled" prije konačnog sačuvavanja vaših imjena.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Dodajte svoj komentar.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Ovaj članak je zaključan. Možete ga samo vidjeti ili kopirati kod.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Prethodne verzije ove stranice.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Zaštitite stranicu od budućih izmjena\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Izbrišite ovu stranicu\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Vratite izmjene koje su načinjene prije brisanja stranice\');
+ta[\'ca-move\'] = new Array(\'m\',\'Pomjerite stranicu\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Nemate dozvolu za pomjeranje ove stranice\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Dodajte stranicu u listu praćnih članaka\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Izbrišite stranicu sa liste praćnih članaka\');
+ta[\'search\'] = new Array(\'f\',\'Pretražite projekat {{SITENAME}}\');
+ta[\'p-logo\'] = new Array(\'\',\'Glavna stranica\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Posjetite glavnu stranicu\');
+ta[\'n-portal\'] = new Array(\'\',\'O projektu, kako Vi možete pomoći, i gdje da nađete potrebne stvari o projektu {{SITENAME}}\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Podaci o onome na čemu se trenutno radi\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Spisak nedavnih izmjena na projektu {{SITENAME}}.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Otvorite slučajan članak\');
+ta[\'n-help\'] = new Array(\'\',\'Naučite da uređujete projekat {{SITENAME}}.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Podržite nas\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Spisak svih članaka koji su povezani sa ovim\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Nedavne izmjene na stranicama koje su povezane sa ovom\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS za ovu stranicu\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom za ovu stranicu\');
+ta[\'t-contributions\'] = new Array(\'\',\'Pogledajte spisak doprinosa ovog korisnika\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Pošaljite pismo ovom korisniku\');
+ta[\'t-upload\'] = new Array(\'u\',\'Pošaljite slike i medija fajlove\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Spisak svih posebih stranica\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Pogledajte sadržaj članka\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Pogledajte korisničku stranicu\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Pogledajte medija fajl\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Ovo je specijalna stranica i zato je ne možete uređivati\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Pogledajte projekat stranicu\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Pogledajte stranicu slike\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Pogledajte sistemsku poruku\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Pogledajte šablon\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Pogledajte stranicu za pomoć\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Pogledajte stranicu kategorije\');',
+'about' => 'O...',
+'aboutpage' => '{{ns:4}}:O',
+'aboutsite' => 'O projektu {{SITENAME}}',
+'accmailtext' => 'Lozinka za nalog \'$1\' je poslata na adresu $2.',
+'accmailtitle' => 'Lozinka poslata.',
+'actioncomplete' => 'Akcija završena',
+'addedwatch' => 'Dodato u spisak praćenih članaka',
+'addedwatchtext' => 'Stranica "[[:$1]]" je dodata vašem [[{{ns:-1}}:Watchlist|spisku praćenih članaka]]. Buduće promjene ove stranice i njoj pridružene stranice za razgovor će biti navedene ovde, i stranica će biti <b>podebljana</b> u [[{{ns:-1}}:Recentchanges|spisku]] nedavnih izmjena da bi se lakše uočila.</p>
+<p>Ako kasnije želite da uklonite stranicu sa vašeg spiska praćenih članaka, kliknite na "prekini praćenje" na paleti.',
+'allmessages' => 'Sistemske poruke',
+'allmessagesnotsupportedDB' => '[[{{ns:-1}}:Allmessages|sistemske poruke]] nisu podržane zato što je <i>wgUseDatabaseMessages</i> isključen.',
+'allmessagesnotsupportedUI' => 'Vaš trenutni jezik interfejsa <b>$1</b> nije podržan u [[{{ns:-1}}:Allmessages|sistemskim porukama]] na ovoj viki.',
+'allmessagestext' => 'Ovo je spisak svih sistemskih poruka u {{ns:8}} imenskom prostoru.',
+'allpages' => 'Sve stranice',
+'alphaindexline' => '$1 u $2',
+'alreadyloggedin' => '<strong>Korisniče $1, već ste prijavljeni!</strong><br />',
+'alreadyrolled' => 'Ne može se vratiti poslednja izmjena [[:$1]] od korisnika [[{{ns:2}}:$2|$2]] ([[{{ns:3}}:$2|razgovor]]); neko drugi je već izmjenio ili vratio članak. Poslednja izmjena od korisnika [[{{ns:2}}:$3|$3]] ([[{{ns:3}}:$3|razgovor]]).',
+'ancientpages' => 'Najstarije stranice',
+'and' => 'i',
+'anoneditwarning' => 'Niste prijavljeni. Vaša IP adresa će biti zapisana.',
+'anontalk' => 'Razgovor za ovu IP adresu',
+'anontalkpagetext' => '----\'\'Ovo je stranica za razgovor za anonimnog korisnika koji još nije napravio nalog ili ga ne koristi. Zbog toga moramo da koristimo brojčanu [[IP adresa|IP adresu]] kako bismo odentifikovali njega ili nju. Takvu adresu može dijeliti više korisnika. Ako ste anonimni korisnik i mislite da su vam upućene nebitne primjedbe, molimo Vas da [[{{ns:-1}}:Userlogin|napravite nalog ili se prijavite]] da biste izbjegli buduću zabunu sa ostalim anonimnim korisnicima.\'\'',
+'anonymous' => 'Anonimni korisnik od {{SITENAME}}',
+'apr' => 'apr',
+'april' => 'april',
+'article' => 'Članak',
+'articleexists' => 'Stranica pod tim imenom već postoji, ili je ime koje ste izabrali neispravno. Molimo Vas da izaberete drugo ime.',
+'articlepage' => 'Pogledaj članak',
+'aug' => 'avg',
+'august' => 'avgust',
+'autoblocker' => 'Automatski ste blokirani jer dijelite IP adresu sa "$1". Razlog za blokiranje je: "\'\'\'$2\'\'\'"',
+'badarticleerror' => 'Ova akcija ne može biti izvršena na ovoj stranici.',
+'badfilename' => 'Ime slike je promjenjeno u "$1".',
+'badfiletype' => '".$1" nije preporučeni format slike.',
+'badipaddress' => 'Pogrešna IP adresa',
+'badquery' => 'Loše oblikovan upit za pretragu',
+'badquerytext' => 'Nismo mogli da obradimo vaš upit. Ovo je vjerovatno zbog toga što ste pokušali da tražite riječ kraću od tri slova, što trenutno nije podržano. Takođe je moguće da ste pogrešno ukucali izraz, na primjer "riba ii krljušti". Molimo vas da pokušate nekim drugim upitom.',
+'badretype' => 'Lozinke koje ste unijeli se ne poklapaju.',
+'badtitle' => 'Loš naslov',
+'badtitletext' => 'Zahtjevani naslov stranice je bio neispravan, prazan ili neispravno povezan međujezički ili interviki naslov.',
+'blanknamespace' => '(Glavno)',
+'blockedtext' => 'Vaše korisničko ime ili IP adresa je blokirana od strane $1.
+Dati razlog je sledeći:<br />\'\'$2\'\'<p>Možete kontaktirati $1 ili nekog drugog [[{{ns:4}}:Administratori|administratora]] da biste razgovarili o blokadi.',
+'blockedtitle' => 'Korisnik je blokiran',
+'blockip' => 'Blokiraj korisnika',
+'blockipsuccesssub' => 'Blokiranje je uspjelo',
+'blockipsuccesstext' => '[[{{ns:-1}}:Contributions/$1|$1]] je blokiran.
+<br />Pogledajte [[{{ns:-1}}:Ipblocklist|IP spisak blokiranih korisnika]] za pregled blokiranja.',
+'blockiptext' => 'Upotrebite donji upitnik da biste uklonili prava pisanja sa određene IP adrese ili korisničkog imena. Ovo bi trebalo da bude urađeno samo da bi se spriječio vandalizam, i u skladu sa [[{{ns:4}}:Smjernice|smjernicama]]. Unesite konkretan razlog ispod (na primjer, navodeći koje stranice su vandalizovane).',
+'blocklink' => 'blokirajte',
+'blocklistline' => '$1, $2 blokirao korisnika $3 ($4)',
+'blocklogentry' => 'je blokirao "$1" sa vremenom isticanja blokade od $2',
+'blocklogtext' => 'Ovo je istorija blokiranja i deblokiranja korisnika. Automatsko blokirane IP adrese nisu uspisane ovde. Pogledajte [[{{ns:-1}}:Ipblocklist|blokirane IP adrese]] za spisak trenutnih zabrana i blokiranja.',
+'bold_sample' => 'Podebljan tekst',
+'bold_tip' => 'Podebljan tekst',
+'booksources' => 'Štampani izvori',
+'booksourcetext' => 'Ispod je spisak veza na druge sajtove koji
+prodaju nove i korišćene knjige, i takođe mogu imati daljnje informacije
+o knjigama koje tražite.
+{{SITENAME}} ne sarađuje ni se jednim od ovih preduzeća, i
+ovaj spisak ne treba da se shvati kao potvrda njihovog kvaliteta.',
+'brokenredirects' => 'Pokvarena preusmjerenja',
+'brokenredirectstext' => 'Sledeća preusmjerenja su povezana na nepostojeći članak:',
+'bugreports' => 'Prijavite grešku',
+'bugreportspage' => '{{ns:4}}:Prijave_grešaka',
+'bydate' => 'po datumu',
+'byname' => 'po imenu',
+'bysize' => 'po veličini',
+'cachederror' => 'Ovo je keširana kopija zahtjevane stranice, i možda nije najnovija.',
+'cancel' => 'Poništite',
+'cannotdelete' => 'Ne može se obrisati navedena stranica ili slika. (Moguće je da ju je neko drugi već obrisao.)',
+'cantrollback' => 'Ne može se vratiti izmjena; poslednji autor je ujedno i jedini.',
+'categories' => 'Kategorije',
+'categoriespagetext' => 'Sledeće kategorije već postoje u {{SITENAME}}',
+'category_header' => 'Članaka u kategoriji "$1"',
+'changepassword' => 'Promjeni lozinku',
+'changes' => 'izmjene',
+'columns' => 'Kolona',
+'compareselectedversions' => 'Uporedite označene verzije',
+'confirm' => 'Potvrdite',
+'confirmdelete' => 'Potvrdi brisanje',
+'confirmdeletetext' => 'Na putu ste da trajno obrišete stranicu
+ili sliku zajedno sa svom njenom istorijom iz baze.
+Molimo Vas da potvrdite da namjeravate da uradite ovo, da razumijete
+poslijedice, i da ovo radite u skladu sa
+[[{{ns:4}}:Pravila|pravilima]] {{SITENAME}}.',
+'confirmemail' => 'Potvrdite adresu e-pošte',
+'confirmemail_body' => 'Neko, vjerovatno Vi, je sa IP adrese $1 registrovao nalog "$2" sa ovom adresom e-pošte na {{SITENAME}}.
+
+Da potvrdite da ovaj nalog stvarno pripada vama i da aktivirate mogućnost e-pošte na {{SITENAME}}, otvorite ovu poveznicu u vašem brauzeru:
+
+$3
+
+Ako ovo niste vi, ne pratite poveznicu. Ovaj kod za potvrdu će isteći u $4.',
+'confirmemail_error' => 'Nešto je pošlo po zlu prilikom sačuvavanja vaše potvrde.',
+'confirmemail_invalid' => 'Netačan kod za potvrdu. Moguće je da je kod istekao.',
+'confirmemail_loggedin' => 'Adresa Vaše e-pošte je potvrđena.',
+'confirmemail_send' => 'Pošaljite kod za potvrdu',
+'confirmemail_sendfailed' => 'Pošta za potvrđivanje nije poslata. Provjerite adresu zbog nepravilnih karaktera.',
+'confirmemail_sent' => 'E-pošta za potvrđivanje poslata.',
+'confirmemail_subject' => '{{SITENAME}} adresa e-pošte za potvrđivanje',
+'confirmemail_success' => 'Adresa vaše e-pošte je potvrđena. Možete sad da se prijavite i uživate u viki.',
+'confirmemail_text' => 'Ova viki zahtjeva da potvrdite adresu Vaše e-pošte prije nego što koristite mogućnosti e-pošte. Aktivirajte dugme ispod kako bi ste poslali poštu za potvrdu na Vašu adresu. Pošta uključuje poveznicu koja sadrži kod; učitajte poveznicu u Vaš brauzer da bi ste potvrdili da je adresa Vaše e-pošte validna.',
+'confirmprotect' => 'Potvrdite zaštitu',
+'confirmprotecttext' => 'Da li zaista želite da zaštitite ovu stranicu?',
+'confirmrecreate' => 'Korisnik [[{{ns:2}}:$1|$1]] ([[{{ns:3}}:$1|razgovor]]) je obrisao ovaj članak pošto ste počeli uređivanje sa razlogom:
+: \'\'$2\'\'
+
+Molimo Vas da potvrdite da stvarno želite da ponovo napravite ovaj članak.',
+'confirmunprotect' => 'Potvrdite skidanje zaštite',
+'confirmunprotecttext' => 'Da li zaista želite da skinete zaštitu sa ove stranice?',
+'contextchars' => 'Karaktera konteksta po liniji:',
+'contextlines' => 'Linija po pogotku:',
+'contribslink' => 'doprinos',
+'contribsub' => 'Za $1',
+'contributions' => 'Doprinos korisnika',
+'copyright' => 'Svi sadržaji podliježu "$1" licenci.',
+'copyrightpage' => '{{ns:4}}:Autorska_prava',
+'copyrightpagename' => '{{SITENAME}} autorska prava',
+'copyrightwarning' => 'Za sve priloge poslate na projekat {{SITENAME}} smatramo da su objavljeni pod $2 (konsultujte $1 za detalje).
+Ukoliko ne želite da vaši članci budu podložni izmjenama i slobodnom rasturanju i objavljivanju,
+nemojte ih slati ovdje. Takođe, slanje članka podrazumijeva i vašu izjavu da ste ga napisali sami, ili da ste ga kopirali iz izvora u javnom domenu ili sličnog slobodnog izvora.
+
+<strong>NEMOJTE SLATI RAD ZAŠTIĆEN AUTORSKIM PRAVIMA BEZ DOZVOLE AUTORA!</strong>',
+'couldntremove' => 'Ne može se ukloniti \'$1\'...',
+'createaccount' => 'Napravi nalog',
+'createaccountmail' => 'e-poštom',
+'cur' => 'tren',
+'currentevents' => 'Trenutni događaji',
+'currentrev' => 'Trenutna revizija',
+'databaseerror' => 'Greška u bazi',
+'dateformat' => 'Format datuma',
+'datedefault' => 'Nije bitno',
+'dberrortext' => 'Desila se sintaksna greška upita baze.
+Ovo je moguće zbog ilegalnog upita, ili moguće greške u softveru.
+Poslednji pokušani upit je bio: <blockquote><tt>$1</tt></blockquote>
+iz funkcije "<tt>$2</tt>".
+MySQL je vratio grešku "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Desila se sintaksna greška upita baze.
+Poslednji pokušani upit je bio:
+"$1"
+iz funkcije "$2".
+MySQL je vratio grešku "$3: $4".',
+'deadendpages' => 'Stranice bez internih veza',
+'dec' => 'dec',
+'december' => 'decembar',
+'defaultns' => 'Uobičajeno tražite u ovim imenskim prostorima:',
+'defemailsubject' => '{{SITENAME}} e-pošta',
+'delete' => 'Obrišite',
+'deletecomment' => 'Razlog za brisanje',
+'deletedarticle' => 'obrisan "[[$1]]"',
+'deletedtext' => 'Članak "$1" je obrisan.
+Pogledajte $2 za zapis o skorašnjim brisanjima.',
+'deleteimg' => 'obr',
+'deletepage' => 'Obrišite stranicu',
+'deletesub' => '(Briše se "$1")',
+'deletethispage' => 'Obriši ovu stranicu',
+'deletionlog' => 'istorija brisanja',
+'dellogpage' => 'istorija brisanja',
+'dellogpagetext' => 'Ispod je spisak najskorijih brisanja.',
+'diff' => 'razl',
+'difference' => '(Razlika između revizija)',
+'disambiguations' => 'Stranice za višeznačne odrednice',
+'disambiguationspage' => '{{ns:10}}:Višeznačna odrednica',
+'disambiguationstext' => 'Sledeći članci se povezuju sa <i>višeznačnom odrednicom</i>. Umjesto toga, oni bi trebali da se povezuju sa odgovarajućom temom.<br />Stranica se tretira kao višeznačna odrednica ako je povezana sa $1.<br />Poveznice iz ostalih imenskih prostora <i>nisu</i> navedene ovdje.',
+'disclaimerpage' => '{{ns:4}}:Uslovi korišćenja, pravne napomene i odricanje odgovornosti',
+'disclaimers' => 'Odricanje odgovornosti',
+'doubleredirects' => 'Dvostruka preusmjerenja',
+'doubleredirectstext' => 'Svaki red sadrži veze na prvo i drugo preusmjerenje, kao i na prvu liniju teksta drugog preusmjerenja, što obično daje "pravi" ciljni članak, na koji bi prvo preusmjerenje i trebalo da pokazuje.',
+'edit' => 'Uredite',
+'editcomment' => 'Komentar izmjene je: "<i>$1</i>".',
+'editconflict' => 'Sukobljenje izmjene: $1',
+'editcurrent' => 'Izmijenite trenutnu verziju ove stranice',
+'edithelp' => 'Pomoć pri uređivanju stranice',
+'edithelppage' => '{{ns:4}}:Uređivanje',
+'editing' => 'Uređujete $1',
+'editinguser' => 'Uređujete $1',
+'editingold' => '<strong>PAŽNJA: Vi mijenjate stariju
+reviziju ove stranice.
+Ako je snimite, sve promjene učinjene od ove revizije će biti izgubljene.</strong>',
+'editsection' => 'uredite',
+'editold' => 'uredite',
+'editthispage' => 'Uredite ovu stranicu',
+'emailfrom' => 'Od',
+'emailmessage' => 'Poruka',
+'emailpage' => 'Pošalji e-pismo korisniku',
+'emailpagetext' => 'Ako je ovaj korisnik unio ispravnu adresu e-pošte u
+cvoja korisnička podešavanja, upitnik ispod će poslati jednu poruku.
+Adresa e-pošte koju ste vi uneli u svoja korisnička podešavanja će se pojaviti
+kao "Od" adresa poruke, tako da će primalac moći da odgovori.',
+'emailsend' => 'Pošalji',
+'emailsent' => 'Poruka poslata',
+'emailsenttext' => 'Vaša poruka je poslata e-poštom.',
+'emailsubject' => 'Tema',
+'emailto' => 'Za',
+'emailuser' => 'Pošalji e-poštu ovom korisniku',
+'emptyfile' => 'Fajl koji ste poslali je prazan. Ovo je moguće zbog greške u imenu fajla. Molimo Vas da provjerite da li stvarno želite da pošaljete ovaj fajl.',
+'enotif_body' => 'Dragi $WATCHINGUSERNAME,
+
+{{SITENAME}} strana $PAGETITLE je bila $CHANGEDORCREATED $PAGEEDITDATE od strane $PAGEEDITOR,
+pogledajte {{fullurl:$PAGETITLE_RAWURL}} za trenutnu verziju.
+
+$NEWPAGE
+
+Rezime editora: $PAGESUMMARY $PAGEMINOREDIT
+
+Kontaktirajte editora:
+pošta {{fullurl:{{ns:-1}}:Emailuser|target=$PAGEEDITOR_RAWURL}}
+viki {{fullurl:User:$PAGEEDITOR_RAWURL}}
+
+Neće biti drugih obaviještenja u slučaju daljih izmjena ukoliko ne posjetite ovu stranu.
+Takođe možete da resetujete zastavice za obaviještenja za sve Vaše praćene stranice na vašem spisku praćenenih članaka.
+
+ Vaš prijateljski {{SITENAME}} sistem obaviještavanja
+
+--
+Da promjenite podešavanja vezana za spisak praćenenih članaka posjetite
+{{fullurl:{{ns:-1}}:Watchlist|edit=yes}}
+
+Fidbek i dalja pomoć:
+{{fullurl:{{ns:12}}:Sadržaj}}',
+'enotif_lastvisited' => 'Pogledajte {{fullurl:$PAGETITLE_RAWURL|diff=0&oldid=$OLDID}} za sve izmjene od vaše poslednje posjete.',
+'enotif_mailer' => '{{SITENAME}} obaviještenje o pošti',
+'enotif_newpagetext' => 'Ovo je novi članak.',
+'enotif_reset' => 'Označi sve strane kao posjećene',
+'enotif_subject' => '{{SITENAME}} strana $PAGETITLE je bila $CHANGEDORCREATED od strane $PAGEEDITOR',
+'enterlockreason' => 'Unesite razlog za zaključavanje, uključujući procijenu
+vremena otključavanja',
+'error' => 'Greška',
+'errorpagetitle' => 'Greška',
+'exbeforeblank' => 'sadržaj prije brisanja je bio: \'$1\'',
+'exblank' => 'stranica je bila prazna',
+'excontent' => 'sadržaj je bio: \'$1\'',
+'explainconflict' => 'Neko drugi je promjenio ovu stranicu otkad ste Vi počeli da je mjenjate.
+Gornje tekstualno polje sadrži tekst stranice koji trenutno postoji.
+Vaše izmjene su prikazane u donjem tekstu.
+Moraćete da unesete svoje promjene u postojeći tekst.
+<b>Samo</b> tekst u gornjem tekstualnom polju će biti snimljen kad
+pritisnete "Sačuvaj".<br />',
+'export' => 'Izvezite stranice',
+'exportcuronly' => 'Uključite samo trenutnu reviziju, ne cijelu istoriju',
+'exporttext' => 'Možete izvesti tekst i istoriju promjena određene stranice
+ili grupe stranice u XML formatu. Ovo onda može biti uvezeno u drugi viki koji koristi MedijaViki softver, transformisano, ili korišćeno za Vaše lične potrebe.',
+'extlink_sample' => 'http://www.adresa.com opis adrese',
+'extlink_tip' => 'Spoljašnja poveznica (zapamti prefiks http://)',
+'faqpage' => '{{ns:4}}:NPP',
+'feb' => 'feb',
+'february' => 'februar',
+'feedlinks' => 'Fid:',
+'filecopyerror' => 'Ne može se kopirati "$1" na "$2".',
+'filedeleteerror' => 'Ne može se izbrisati fajl "$1".',
+'filedesc' => 'Opis',
+'fileexists' => 'Fajl sa ovim imenom već postoji. Molimo Vas da provjerite $1 ako niste sigurni da li želite da ga promjenite.',
+'fileexists-forbidden' => 'Fajl sa ovim imenom već postoji; molimo Vas da se vratite i pošaljete ovaj fajl pod novim imenom. [[{{ns:6}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Fajl sa ovim imenom već postoji u zajedničkoj ostavi; molimo Vas da se vratite i pošaljete ovaj fajl pod novim imenom. [[{{ns:6}}:$1|thumb|center|$1]]',
+'fileinfo' => '$1KB, MIME tip: <code>$2</code>',
+'filemissing' => 'Nedostaje fajl',
+'filename' => 'Ime fajla',
+'filenotfound' => 'Ne može se naći fajl "$1".',
+'filerenameerror' => 'Ne može se promjeniti ime fajla "$1" to "$2".',
+'filesource' => 'Izvor',
+'filestatus' => 'Status autorskih prava',
+'fileuploaded' => 'Fajl "$1" je uspješno poslat.
+Molimo Vas da pratite ovu vezu: ($2) do stranice za opisivanje i unesite
+informacije o fajlu, kao odakle je, kad i ko ga
+je napravio, i bio šta drugo što znate o njemu.',
+'formerror' => 'Greška: ne može se poslati upitnik',
+'friday' => 'petak',
+'getimagelist' => 'pribavljam spisak slika',
+'go' => 'Idi',
+'searcharticle' => 'Idi',
+'gotaccount' => 'Imate nalog? $1.',
+'gotaccountlink' => 'Prijavi se',
+'guesstimezone' => 'Popuni iz brauzera',
+'headline_sample' => 'Naslov',
+'headline_tip' => 'Podnaslov',
+'help' => 'Pomoć',
+'helppage' => '{{ns:12}}:Sadržaj',
+'hide' => 'sakrij',
+'hidetoc' => 'sakrij',
+'hist' => 'ist',
+'histlegend' => 'Objašnjenje: (tren) = razlika sa trenutnom verziom,
+(posl) = razlika sa prethodnom verziom, M = mala izmjena',
+'history' => 'Istorija stranice',
+'history_short' => 'Istorija',
+'historywarning' => 'Pažnja: stranica koju želite da obrišete ima istoriju:',
+'hr_tip' => 'Horizontalna linija (koristite oskudno)',
+'ilsubmit' => 'Traži',
+'image_sample' => 'ime_slike.jpg',
+'image_tip' => 'Uklopljena slika',
+'imagelinks' => 'Upotreba slike',
+'imagelist' => 'Spisak slika',
+'imagelisttext' => 'Ispod je spisak $1 slika poređanih $2.',
+'imagepage' => 'Pogjedajte stranicu slike',
+'imagereverted' => 'Vraćanje na raniju verziju je uspješno.',
+'imgdelete' => 'obr',
+'imgdesc' => 'opis',
+'imghistlegend' => 'Objašnjenje: (tren) = ovo je trenutna slika, (obr) = obrišite
+ovu staru verziju, (vrt) = vrati na ovu staru verziju.
+<br /><i>Kliknite na datum da vidite sliku poslatu tog dana</i>.',
+'imghistory' => 'Istorija slike',
+'imglegend' => 'Objašnjenje: (opis) = prikaži/izmjeni opis slike.',
+'import' => 'Ivoz stranica',
+'importfailed' => 'Uvoz nije uspjeo: $1',
+'importhistoryconflict' => 'Postoji konfliktna istorija revizija',
+'importnotext' => 'Stranica je prazna, ili bez teksta',
+'importsuccess' => 'Uspješno ste uvezli stranicu!',
+'importtext' => 'Molimo Vas da izvezete fajl iz izvornog vikija koristeći [[{{ns:-1}}:Export|izvoz]], sačuvajte ga kod sebe i pošaljite ovde.',
+'internalerror' => 'Interna greška',
+'intl' => 'Međujezičke veze',
+'ip_range_invalid' => 'Netačan raspon IP adresa.',
+'ipaddress' => 'IP adresa/korisničko ime',
+'ipb_expiry_invalid' => 'Pogrešno vrijeme trajanja.',
+'ipbexpiry' => 'Trajanje',
+'ipblocklist' => 'Spisak blokiranih IP adresa i korisničkih imena',
+'ipbreason' => 'Razlog',
+'ipbsubmit' => 'Blokirajte ovog korisnika',
+'ipusubmit' => 'Deblokirajte ovog korisnika',
+'isredirect' => 'preusmjerivač',
+'italic_sample' => 'Kurzivan tekst',
+'italic_tip' => 'Kurzivan tekst',
+'iteminvalidname' => 'Problem sa \'$1\', neispravno ime...',
+'jan' => 'jan',
+'january' => 'januar',
+'jul' => 'jul',
+'july' => 'jul',
+'jun' => 'jun',
+'june' => 'jun',
+'largefile' => 'Preporučuje se da slike ne pređu veličinu od 100K.',
+'last' => 'posl',
+'lastmodifiedat' => 'Ova stranica je poslednji put izmijenjena $2, $1',
+'lastmodifiedatby' => 'Ovu stranicu je poslednji put promjenio $3, dana $3.',
+'lineno' => 'Linija $1:',
+'link_sample' => 'Naslov poveznice',
+'link_tip' => 'Unutrašnja poveznica',
+'linklistsub' => '(Spisak veza)',
+'linkshere' => 'Sledeće stranice su povezane ovdje:',
+'linkstoimage' => 'Sledeće stranice koriste ovu sliku:',
+'listusers' => 'Spisak korisnika',
+'loadhist' => 'Učitaje se istorija stranice',
+'loadingrev' => 'učitava se revizija za razliku',
+'localtime' => 'Lokalno vrijeme',
+'lockbtn' => 'Zaključajte bazu',
+'lockconfirm' => 'Da, zaista želim da zaključam bazu.',
+'lockdb' => 'Zaključajte bazu',
+'lockdbsuccesssub' => 'Baza je zaključana',
+'lockdbsuccesstext' => '{{SITENAME}} baza podataka je zaključana. <br /> Sjetite se da je otključate kad završite sa održavanjem.',
+'lockdbtext' => 'Zaključavanje baze će svim korisnicima ukinuti mogućnost izmjene stranica,
+promjene korisničkih podešavanja, izmjene praćenih članaka, i svega ostalog
+što zahtjeva promjene u bazi.
+Molimo Vas da potvrdite da je ovo zaista ono što namjeravate da uradite, i da ćete
+otkučati bazu kad završite posao oko njenog održavanja.',
+'locknoconfirm' => 'Niste potvrdili svoju namjeru.',
+'login' => 'Prijavi se',
+'loginerror' => 'Greška pri prijavljivanju',
+'loginpagetitle' => 'Prijavljivanje',
+'loginproblem' => '<b>Bilo je problema sa vašim prijavljivanjem.</b><br />Probajte ponovo!',
+'loginprompt' => 'Morate imati kolačiće (\'\'\'cookies\'\'\') omogućene da biste se prijavili na {{SITENAME}}.',
+'loginreqtitle' => 'Potrebno je [[{{ns:-1}}:Userlogin|prijavljivanje]]',
+'loginsuccess' => '\'\'\'Sad ste prijavljeni na {{SITENAME}} kao "$1".\'\'\'',
+'loginsuccesstitle' => 'Prijavljivanje uspješno',
+'logout' => 'Odjavite se',
+'logouttext' => '<strong>Sad ste odjavljeni.</strong><br />
+Možete nastaviti da koristite {{SITENAME}} anonimno, ili se ponovo prijaviti
+kao isti ili kao drugi korisnik. Obratite pažnju da neke stranice mogu nastaviti da se prikazuju kao da ste još uvijek prijavljeni, dok ne očistite keš svog brauzera.',
+'logouttitle' => 'Odjavite se',
+'lonelypages' => 'Siročići',
+'longpages' => 'Dugačke stranice',
+'longpagewarning' => '<strong>PAŽNJA: Ova stranica ima $1 kilobajta; niki
+brauzeri mogu imati problema kad uređujete stranice skoro ili veće od 32 kilobajta.
+Molimo Vas da razmotrite razbijanje stranice na manje dijelove.</strong>',
+'mailerror' => 'Greška pri slanju e-pošte: $1',
+'mailmypassword' => 'Pošalji mi moju lozinku',
+'mailnologin' => 'Nema adrese za slanje',
+'mailnologintext' => 'Morate biti [[Special:Userlogin|prijavljeni]]
+i imati ispravnu adresu e-pošte u vašim [[Special:Preferences|podešavanjima]]
+da biste slali e-poštu drugim korisnicima.',
+'mainpage' => 'Glavna stranica',
+'mainpagetext' => 'Viki softver is uspješno instaliran.',
+'makesysop' => 'Dodijeli administratorska prava korisniku',
+'makesysopfail' => '<b>Korisnik "$1" nije mogao dobiti administratorska prava. (Da li ste pravo unijeli ime?)</b>',
+'makesysopname' => 'Ime korisnika:',
+'makesysopok' => '<b>Korisnik "$1" je sad administrator</b>',
+'makesysopsubmit' => 'Dodajte ovom korisniku administratorska prava',
+'makesysoptext' => 'Ovaj formular se koristi sa strane birokrata da se obični korisnici pretvore u administratore. Unesite ime korisnika u kutiju i pritisnite dugme da bi korisnik postao administrator.',
+'makesysoptitle' => 'Pretvorite korisnika u administratora',
+'mar' => 'mar',
+'march' => 'mart',
+'markaspatrolleddiff' => 'Označi kao patrolirano',
+'markaspatrolledtext' => 'Označi ovaj članak kao patroliran',
+'markedaspatrolled' => 'Označeno kao patrolirano',
+'markedaspatrollederror' => 'Ne može se označiti kao patrolirano',
+'markedaspatrollederrortext' => 'Morate naglasiti reviziju koju treba označiti kao patroliranu.',
+'markedaspatrolledtext' => 'Izabrana revizija je označena kao patrolirana.',
+'matchtotals' => 'Upit "$1" je nađen u "$2" naslova članaka
+i tekst $3 članaka.',
+'math' => 'Prikazivanje matematike',
+'math_bad_output' => 'Ne može se napisati ili napraviti direktorijum za matematični izvještaj.',
+'math_bad_tmpdir' => 'Ne može se napisati ili napraviti privremeni matematični direktorijum',
+'math_failure' => 'Neuspjeh pri parsiranju',
+'math_image_error' => 'PNG konverzija neuspješna; provjerite tačnu instalaciju latex-a, dvips-a, gs-a i convert-a',
+'math_lexing_error' => 'riječnička greška',
+'math_notexvc' => 'Nedostaje izvršno texvc; molimo Vas da pogledate math/README da podesite.',
+'math_sample' => 'Unesite formulu ovdje',
+'math_syntax_error' => 'sintaksna greška',
+'math_tip' => 'Matematička formula (LaTeX)',
+'math_unknown_error' => 'nepoznata greška',
+'math_unknown_function' => 'nepoznata funkcija',
+'may' => 'maj',
+'media_sample' => 'ime_medija_fajla.ogg',
+'media_tip' => 'Putanja ka multimedijalnom fajlu',
+'mediawarning' => '\'\'\'Upozorenje\'\'\': Ovaj fajl sadrži loš kod, njegovim izvršavanjem možete da ugrozite Vaš sistem.
+<hr />',
+'metadata' => 'Metapodaci',
+'mimesearch' => 'MIME pretraga',
+'mimetype' => 'MIME tip:',
+'minlength' => 'Imena fajlova moraju imati bar tri slova.',
+'minoredit' => 'Ovo je mala izmjena',
+'missingarticle' => 'Baza nije mogla naći tekst stranice koji je trebala da nađe, nazvan "$1".
+
+Ovo je obično izazvano praćenjem zastarijelog "razl" ili veze ka istoriji
+stranice koja je obrisana.
+
+Ako ovo nije slučaj, možda ste pronašli grešku u softveru.
+Molimo Vas da prijaviti ovo jednom od [[{{ns:4}}:Administratori|administratora]], zajedno sa URL-om.',
+'missingimage' => '<b>Ovdje nedostaje slika</b><br /><i>$1</i>',
+'monday' => 'ponedeljak',
+'moredotdotdot' => 'Još...',
+'move' => 'Premjestite',
+'movearticle' => 'Premjestite stranicu',
+'movedto' => 'premještena na',
+'movenologin' => 'Niste prijavljeni',
+'movenologintext' => 'Morate biti registrovani korisnik i [[Special:Userlogin|prijavljeni]]
+da biste premjestili stranicu.',
+'movepage' => 'Premjestite stranicu',
+'movepagebtn' => 'premjestite stranicu',
+'movepagetalktext' => 'Odgovarajuća stranica za razgovor, ako postoji, će automatski biti premještena istovremeno \'\'\'osim:\'\'\'
+*Ako premještate stranicu preko imenskih prostora,
+*Neprazna stranica za razgovor već postoji pod novim imenom, ili
+*Odčekirajte donju kutiju.
+
+U tim slučajevima, moraćete ručno da premjestite stranicu ukoliko to želite.',
+'movepagetext' => 'Donji upitnik će preimenovati stranicu, premještajući svu
+njenu istoriju na novo ime.
+Stari naslov će postati preusmjerenje na novi naslov.
+Poveznice prema starom naslovu neće biti promijenjene; obavezno
+provjerite da li ima [[{{ns:-1}}:DoubleRedirects|dvostrukih]] ili [[{{ns:-1}}:BrokenRedirects|pokvarenih preusmjerenja]].
+Na vama je odgovornost da veze i dalje idu tamo gdje trebaju da idu.
+
+Obratite pažnju da stranica \'\'\'neće\'\'\' biti pomjerena ako već postoji
+stranica sa novim naslovom, osim ako je ona prazna ili preusmjerenje i nema
+istoriju promjena. Ovo znači da ne možete preimenovati stranicu na ono ime
+sa koga ste je preimenovali ako pogriješite, i ne možete prepisati
+postojeću stranicu.
+
+<b>PAŽNJA!</b>
+Ovo može biti drastična i neočekivana promjena za popularnu stranicu;
+molimo Vas da budete sigurni da razumijete poslijedice ovoga prije što
+nastavite.',
+'movetalk' => 'Premjestite "stranicu za razgovor" takođe, ako je moguće.',
+'movethispage' => 'Premjesti ovu stranicu',
+'mycontris' => 'Moj doprinos',
+'mypage' => 'Moja stranica',
+'mytalk' => 'Moj razgovor',
+'navigation' => 'Navigacija',
+'nbytes' => '$1 bajtova',
+'newarticle' => '(Novi)',
+'newarticletext' => '<div style="border: 1px solid #ccc; padding: 7px;">\'\'\'{{SITENAME}} nema stranicu {{PAGENAME}}.\'\'\'
+* Da započnete stranicu, koristite prostor ispod i kad završite, pritisnite "Sačuvaj". Vaše izmjene će odmah biti vidljive.
+* Ako ste novi na prjektu {{SITENAME}}, molimo Vas da pogledate [[{{ns:4}}:Pomoć|pomoćnu stranicu]], ili koristite [[{{ns:4}}:Igralište|igralište]] za eksperimentaciju.
+</div>',
+'newmessageslink' => 'novih poruka',
+'newpage' => 'Nova stranica',
+'newpages' => 'Nove stranice',
+'newpassword' => 'Nova lozinka:',
+'newtitle' => 'Novi naslov',
+'next' => 'sled',
+'nextn' => 'sledećih $1',
+'nlinks' => '$1 veza',
+'noarticletext' => '<div style="border: 1px solid #ccc; padding: 7px;">\'\'\'{{SITENAME}} još nema ovaj članak.\'\'\'
+* Da započnete članak, kliknite \'\'\'[{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} uredite ovu stranicu]\'\'\'.
+* [[{{ns:-1}}:Search/{{PAGENAME}}|Pretraži {{PAGENAME}}]] u ostalim člancima
+* [[{{ns:-1}}:Whatlinkshere/{{NAMESPACE}}:{{PAGENAME}}|Stranice koje su povezane za]] {{PAGENAME}} članak
+----
+* \'\'\'Ukoliko ste napravili ovaj članak u poslednjih nekoliko minuta i još se nije pojavio, postoji mogućnost da je server u zastoju zbog osvježavanja baze podataka.\'\'\' Molimo Vas da probate sa <span class="plainlinks">[{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=purge}} osvježavanjem]<span> ili sačekajte i provjerite kasnije ponovo prije ponovnog pravljenja članka.
+* Ako ste napravili članak pod ovim imenom ranije, moguće je da je bio izbrisan. Potražite \'\'\'{{FULLPAGENAME}}\'\'\' [{{fullurl:Special:Log|type=delete&page={{FULLPAGENAMEE}}}} u spisku brisanja]. Alternativno, provjerite [[{{ns:4}}:Zahtjevi za brisanje#{{PAGENAME}}|ovdje]].
+</div>',
+'noconnect' => 'Žao nam je! Viki ima neke tehničke poteškoće, i ne može da se poveže sa serverom baze. <br />',
+'nocontribs' => 'Nisu nađene promjene koje zadovoljavaju ove uslove.',
+'nocookieslogin' => '{{SITENAME}} koristi kolačiće (\'\'cookies\'\') da bi se korisnici prijavili. Vi ste onemogućili kolačiće na Vašem kompjuteru. Molimo Vas da ih omogućite i da pokušate ponovo sa prijavom.',
+'nocookiesnew' => 'Korisnički nalog je napravljen, ali niste prijavljeni. {{SITENAME}} koristi kolačiće (\'\'cookies\'\') da bi se korisnici prijavili. Vi ste onemogućili kolačiće na Vašem kompjuteru. molimo Vas da ih omogućite, a onda se prijavite sa svojim novim korisničkim imenom i lozinkom.',
+'nocreativecommons' => 'Creative Commons RDF metapodaci onemogućeni za ovaj server.',
+'nodb' => 'Ne mogu da izaberem bazu $1',
+'nodublincore' => 'Dublin Core RDF metapodaci onemogućeni za ovaj server.',
+'noemail' => 'Ne postoji adresa e-pošte za korisnika "$1".',
+'noemailtext' => 'Ovaj korisnik nije naveo ispravnu adresu e-pošte,
+ili je izabrao da ne prima e-poštu od drugih korisnika.',
+'noemailtitle' => 'Nema adrese e-pošte',
+'noexactmatch' => 'Nema stranice sa takvim imenom.
+
+Možete \'\'\'[[:$1|da napravite članak sa tim naslovom]]\'\'\' ili [[{{ns:4}}:Zahtjevani članci|da stavite zahtjev za ovaj članak]] ili [[{{ns:-1}}:Allpages/$1|potražite na drugim stranicama]].
+
+::*\'\'\'\'\'<u>Opomena: Nemojte da kopirate materijale za koje nemate dozvolu!</u>\'\'\'\'\'',
+'nohistory' => 'Ne postoji istorija izmjena za ovu stranicu.',
+'nolinkshere' => 'Ništa nije povezano ovdje.',
+'nolinkstoimage' => 'Nema stranica koje koriste ovu sliku.',
+'nologinlink' => 'Napravite nalog',
+'noname' => 'Niste izabrali ispravno korisničko ime.',
+'nonefound' => '\'\'\'Pažnja\'\'\': neuspješne pretrage su
+često izazvane traženjem čestih riječi kao "je" ili "od",
+koje nisu indeksirane, ili navođenjem više od jednog izraza za traženje (samo stranice
+koje sadrže sve izraze koji se traže će se pojaviti u rezultatima).',
+'nospecialpagetext' => 'Tražili ste posebnu stranicu, koju {{SITENAME}} softver nije prepoznao.',
+'nosuchaction' => 'Nema takve akcije',
+'nosuchactiontext' => 'Akcija navedena u URL-u nije
+prepoznata od strane {{SITENAME}} softvera.',
+'nosuchspecialpage' => 'Nema takve posebne stranice',
+'nosuchuser' => 'Ne postoji korisnik sa imenom "$1". Provjerite Vaše kucanje, ili upotrebite donji upitnik da napravite novi korisnički nalog.',
+'notacceptable' => 'Viki server ne može da pruži podatke u onom formatu koji Vaš klijent može da pročita.',
+'notanarticle' => 'Nije članak',
+'notargettext' => 'Niste naveli ciljnu stranicu ili korisnika
+na kome bi se izvela ova funkcija.',
+'notargettitle' => 'Nema cilja',
+'note' => '<strong>Pažnja:</strong>',
+'notextmatches' => 'Tekst članka ne odgovara',
+'notitlematches' => 'Naslov članka ne odgovara.',
+'notloggedin' => 'Niste prijavljeni',
+'nov' => 'nov',
+'november' => 'novembar',
+'nowatchlist' => 'Nemate ništa na svom spisku praćenih članaka.',
+'nowiki_sample' => 'Dodaj neformatirani tekst ovdje',
+'nowiki_tip' => 'Ignoriši viki formatiranje teksta',
+'nstab-category' => 'Kategorija',
+'nstab-help' => 'Pomoć',
+'nstab-image' => 'Slika',
+'nstab-main' => 'Članak',
+'nstab-media' => 'Medija',
+'nstab-mediawiki' => 'Poruka',
+'nstab-special' => 'Posebna',
+'nstab-template' => 'Šablon',
+'nstab-user' => 'Korisnička stranica',
+'nstab-project' => 'Članak',
+'nviews' => '$1 puta pogledano',
+'oct' => 'okt',
+'october' => 'oktobar',
+'ok' => 'da',
+'oldpassword' => 'Stara lozinka:',
+'orig' => 'orig',
+'othercontribs' => 'Bazirano na radu od strane korisnika $1.',
+'otherlanguages' => 'Ostali jezici',
+'pagecategories' => 'Kategorije',
+'pagemovedsub' => 'Premještanje uspjelo',
+'pagemovedtext' => 'Stranica "[[$1]]" premještena je na "[[$2]]".',
+'pagetitle' => '$1 - {{SITENAME}}',
+'passwordremindertext' => 'Neko (vjerovatno Vi, sa IP adrese $1)
+je zahtjevao da vam pošaljemo novu {{SITENAME}} lozinku za prijavljivanje na {{SERVERNAME}}.
+Lozinka za korisnika "$2" je sad "$3".
+Sad treba da se prijavite i promjenite lozinku.
+
+Ako je neko drugi napravio ovaj zahtjev ili ako ste se sjetili vaše lozinke i
+ne želite više da je promjenite, možete da ignorišete ovu poruku i da nastavite koristeći
+vašu staru lozinku.',
+'passwordremindertitle' => '{{SITENAME}} podsjetnik za lozinku',
+'passwordsent' => 'Nova lozinka je poslata na adresu e-pošte
+korisnika "$1".
+Molimo Vas da se prijavite pošto je primite.',
+'perfcached' => 'Sledeći podaci su keširani i možda neće biti u potpunosti ažurirani:',
+'perfdisabled' => 'Žao nam je! Ova mogućnost je privremeno onemogućena jer usporava bazu do te mjere da više niko ne može da koristi viki.',
+'perfdisabledsub' => 'Ovdje je sačuvana kopija $1:',
+'permalink' => 'Trajna veza',
+'personaltools' => 'Lični alati',
+'popularpages' => 'Popularne stranice',
+'portal' => 'Portal zajednice',
+'portal-url' => '{{ns:4}}:Portal_zajednice',
+'postcomment' => 'Pošaljite komentar',
+'powersearch' => 'Traži',
+'powersearchtext' => 'Pretraga u imenskim prostorima :<br />
+$1<br />
+$2 Izlistajte preusmjerenja &nbsp; Tražite $3 $9',
+'preferences' => 'Podešavanja',
+'prefs-help-email' => '* E-mail (optional): Enables others to contact you through your user or user_talk page without the need of revealing your identity.',
+'prefs-misc' => 'Ostala podešavanja',
+'prefs-personal' => 'Korisnički podaci',
+'prefs-rc' => 'Podešavanja nedavnih izmjena',
+'prefsnologin' => 'Niste prijavljeni',
+'prefsnologintext' => 'Morate biti [[{{ns:-1}}:Userlogin|prijavljeni]] da biste podešavali korisnička podešavanja.',
+'prefsreset' => 'Podešavanja su vraćena na prvotne vrijednosti.',
+'preview' => 'Pregled stranice',
+'previewconflict' => 'Ovaj pregled reflektuje tekst u gornjem polju
+kako će izgledati ako pritisnete "Sačuvaj članak".',
+'previewnote' => '<strong>Ovo je samo pregled; izmjene stranice nisu još sačuvane!</strong>',
+'prevn' => 'prethodnih $1',
+'print' => 'Štampa',
+'printableversion' => 'Verzija sa štampanje',
+'protect' => 'Zaštitite',
+'protect-default' => '(standardno)',
+'protect-level-autoconfirmed' => 'Blokiraj neregistrovane korisnike',
+'protect-level-sysop' => 'Samo administratori',
+'protect-text' => 'Ovdje možete gledati i izmjeniti level zaštite za stranicu <strong>$1</strong>.
+Budite sigurni da pratite [[{{ns:4}}:Zaštićena stranica|uputstva projekta]].',
+'protect-unchain' => 'Deblokirajte dozvole premještanja',
+'protect-viewtext' => 'Vaš nalog nema dozvolu da promjeni level zaštite stranica.
+Ovo su trenutna podešavanja za stranicu <strong>$1</strong>:',
+'protectcomment' => 'Razlog za zaštitu',
+'protectedarticle' => 'stranica "[[$1]]" je zaštićena',
+'protectedpage' => 'Zaštićena stranica',
+'protectedpagewarning' => '<strong>PAŽNJA: Ova stranica je zaključana tako da samo korisnici sa
+administratorkim privilegijama mogu da je mijenjaju. Uvjerite se da pratite [[{{ns:4}}:Pravila o zaštiti stranica|pravila o zaštiti stranica]]</strong>.',
+'protectedtext' => 'Ova stranica je zaključana i ne može se uređivati; moguće je da ima
+mnogo razloga za ovo, molimo Vas da pogledate [[{{ns:4}}:Zaštićena stranica]].
+
+Možete gledati i kopirati sadržaj ove stranice:',
+'protectlogpage' => 'Istorija zaključavanja',
+'protectlogtext' => 'Ispod je spisak zaštićenja stranice.
+Pogledajte [[{{ns:4}}:Zaštićena stranica]] za više informacija.',
+'protectsub' => '(Zaštićuje se "$1")',
+'protectthispage' => 'Zaštitite ovu stranicu',
+'proxyblocker' => 'Bloker proksija',
+'proxyblockreason' => 'Vaša IP adresa je blokirana jer je ona otvoreni proksi. Molimo vas da kontaktirate vašeg davatelja internetskih usluga (Internet Service Provider-a) ili tehničku podršku i obavijestite ih o ovom ozbiljnom sigurnosnom problemu.',
+'proxyblocksuccess' => 'Proksi uspješno blokiran.',
+'qbbrowse' => 'Prelistajte',
+'qbedit' => 'Izmjenite',
+'qbfind' => 'Pronađite',
+'qbmyoptions' => 'Moje opcije',
+'qbpageinfo' => 'Informacije o stranici',
+'qbpageoptions' => 'Opcije stranice',
+'qbsettings' => 'Podešavanja brze palete',
+'qbspecialpages' => 'Posebne stranice',
+'randompage' => 'Slučajna stranica',
+'range_block_disabled' => 'Administratorska mogućnost da blokira grupe je isključena.',
+'rclinks' => 'Prikaži najskorijih $1 izmjena u poslednjih $2 dana; $3',
+'rclistfrom' => 'Prikaži nove izmjene počev od $1',
+'rclsub' => '(na stranice povezane sa "$1")',
+'rcnote' => 'Ispod je najskorijih <strong>$1</strong> izmjena u poslednjih <strong>$2</strong> dana.',
+'rcnotefrom' => 'Ispod su izmjene od <b>$2</b> (do <b>$1</b> prikazano).',
+'rcshowhideanons' => '$1 anonimne korisnike',
+'rcshowhidebots' => '$1 botove',
+'rcshowhideliu' => '$1 prijavljene korisnike',
+'rcshowhidemine' => '$1 moje izmjene',
+'rcshowhideminor' => '$1 male izmjene',
+'rcshowhidepatr' => '$1 patrolirane izmjene',
+'readonly' => 'Baza je zaključana',
+'readonlytext' => 'Baza je trenutno zaključana za nove unose i ostale izmjene, vjerovatno zbog rutinskog održavanja, posle čega će biti vraćena u uobičajeno stanje.
+
+Administrator koji ju je zaključao je ponudio ovo objašnjenje: $1',
+'readonlywarning' => '<strong>PAŽNJA: Baza je zaključana zbog održavanja,
+tako da nećete moći da sačuvate svoje izmjene za sada. Možda želite da kopirate
+i nalijepite tekst u tekst editor i sačuvate ga za kasnije.</strong>',
+'recentchanges' => 'Nedavne izmjene',
+'recentchangesall' => 'sve',
+'recentchangescount' => 'Broj naslova u nedavnim izmjenama:',
+'recentchangeslinked' => 'Srodne izmjene',
+'recentchangestext' => 'Na ovoj stranici možete pratiti nedavne izmjene.',
+'redirectedfrom' => '(Preusmjereno sa $1)',
+'remembermypassword' => 'Zapamti me',
+'removechecked' => 'Uklonite označene unose iz spiska praćenih članaka',
+'removedwatch' => 'Uklonjeno iz spiska praćenih članaka',
+'removedwatchtext' => 'Stranica "$1" je uklonjena iz vašeg spiska praćenih članaka.',
+'removingchecked' => 'Uklanjaju se ove stranice sa spiska praćenih članaka...',
+'resetprefs' => 'Vrati podešavanja',
+'restorelink' => '$1 izbrisanih izmjena',
+'resultsperpage' => 'Pogodaka po stranici:',
+'retrievedfrom' => 'Dobavljeno iz "$1"',
+'returnto' => 'Povratak na $1.',
+'retypenew' => 'Ukucajte ponovo novu lozinku:',
+'reupload' => 'Ponovo pošaljite',
+'reuploaddesc' => 'Vratite se na upitnik za slanje.',
+'reverted' => 'Vraćeno na prijašnju reviziju',
+'revertimg' => 'vrt',
+'revertmove' => 'vrati',
+'revertpage' => 'Vraćene izmjene $2 na poslednju izmjenu korisnika $1',
+'revhistory' => 'Istorija izmjena',
+'revisionasof' => 'Revizija od $1',
+'revnotfound' => 'Revizija nije pronađena',
+'revnotfoundtext' => 'Starija revizija ove stranice koju ste zatražili nije nađena.
+Molimo Vas da provjerite URL pomoću kojeg ste pristupili ovoj stranici.',
+'rights' => 'Prava:',
+'rollback' => 'Vrati izmjene',
+'rollback_short' => 'Vrati',
+'rollbackfailed' => 'Vraćanje nije uspjelo',
+'rollbacklink' => 'vrati',
+'rows' => 'Redova',
+'saturday' => 'subota',
+'savearticle' => 'Sačuvaj',
+'savedprefs' => 'Vaša podešavanja su sačuvana.',
+'savefile' => 'Sačuvaj fajl',
+'saveprefs' => 'Sačuvajte podešavanja',
+'search' => 'Pretraži',
+'searchbutton' => 'Pretraži',
+'searchdisabled' => '<p>Izvinjavamo se! Puno pretraga teksta je privremeno onemogućena. U međuvremenu, možete koristiti Google za pretragu. Indeks može biti stariji.',
+'searchsubtitle' => 'Tražili ste [[:$1]] [[Special:Allpages/$1|&#x5B;Sadržaj&#x5D;]]',
+'searchsubtitleinvalid' => 'Tražili ste $1',
+'searchresults' => 'Rezultati pretrage',
+'searchresultshead' => 'Podešavanja rezultata pretrage',
+'searchresulttext' => 'Za više informacija o pretraživanju {{SITENAME}}, pogledajte [[{{ns:4}}:Pretraga|Pretraga]].',
+'selectnewerversionfordiff' => 'Izaberite noviju verziju za upoređivanje',
+'selectolderversionfordiff' => 'Izaberite stariju verziju za upoređivanje',
+'selfmove' => 'Izvorni i ciljani naziv su isti; strana ne može da se premjesti preko same sebe.',
+'semiprotectedpagewarning' => '\'\'\'Pažnja:\'\'\' Ova stranica je zaključana tako da je samo registrovani korisnici mogu uređivati.',
+'sep' => 'sep',
+'september' => 'septembar',
+'servertime' => 'Vrijeme na serveru',
+'set_rights_fail' => '<b>Korisnička prava za $"1" nisu mogla da se podese. (Da li ste pravilno unijeli ime?)</b>',
+'set_user_rights' => 'Postavi prava korisnika',
+'setbureaucratflag' => 'Postavi prava birokrate',
+'shortpages' => 'Kratke stranice',
+'show' => 'pokaži',
+'showbigimage' => 'Prikaži sliku veće rezolucije ($1x$2, $3 Kb)',
+'showdiff' => 'Prikaži izmjene',
+'showhidebots' => '($1 botove)',
+'showingresults' => 'Prikazani su <b>$1</b> rezultata počev od <b>$2</b>.',
+'showingresultsnum' => 'Prikazani su <b>$3</b> rezultati počev od <b>$2</b>.',
+'showlast' => 'Prikaži poslednjih $1 slika sortiranih po $2.',
+'showpreview' => 'Prikaži izgled',
+'showtoc' => 'prikaži',
+'sig_tip' => 'Vaš potpis sa trenutnim vremenom',
+'sitestats' => 'Statistika sajta',
+'sitestatstext' => '<p style="font-size:125%;margin-bottom:0">{{SITENAME}} trenutno ima \'\'\'$2\'\'\' članaka.</p>
+<p style="margin-top:0">Ovaj broj isključuje preusmjerenja, stranice za razgovor, stranice sa opisom slike, korisničke stranice, šablone, stranice za pomoć, članke bez poveznica, i stranice o projektu {{SITENAME}}.</p>
+<p>
+Totalni broj stranica u bazi: \'\'\'$1\'\'\'.</p>
+<p>
+Bilo je \'\'\'$3\'\'\' pogleda stranica, i \'\'\'$4\'\'\' izmjena otkad je viki bio instaliran.
+To izađe u prosjeku oko \'\'\'$5\'\'\' izmjena po stranici, i \'\'\'$6\'\'\' pogleda po izmjeni.
+</p>',
+'sitesupport' => 'Donacije',
+'sitesupport-url' => '{{ns:4}}:Donacije',
+'siteuser' => '{{SITENAME}} korisnik $1',
+'siteusers' => '{{SITENAME}} korisnik (korisnici) $1',
+'skin' => 'Koža',
+'skinpreview' => '(Pregled)',
+'spamprotectionmatch' => 'Sledeći tekst je izazvao naš filter za neželjene poruke: $1',
+'spamprotectiontext' => 'Strana koju želite da sačuvate je blokirana od strane filtera za neželjene poruke. Ovo je vjerovatno izazvao vezom ka spoljašnjem sajtu.',
+'spamprotectiontitle' => 'Filter za zaštitu od neželjenih poruka',
+'speciallogtitlelabel' => 'Naslov:',
+'specialloguserlabel' => 'Korisnik:',
+'specialpage' => 'Posebna Stranica',
+'specialpages' => 'Posebne stranice',
+'spheading' => 'Posebne stranice za sve korisnike',
+'sqlhidden' => '(SQL pretraga sakrivena)',
+'statistics' => 'Statistike',
+'storedversion' => 'Uskladištena verzija',
+'stubthreshold' => 'Granica za prikazivanje klica',
+'subcategories' => 'Potkategorije',
+'subcategorycount' => '$1 potkategorija su u ovoj kategoriji.',
+'subject' => 'Tema/naslov',
+'successfulupload' => 'Uspješno slanje',
+'summary' => 'Sažetak',
+'sunday' => 'nedelja',
+'talk' => 'Razgovor',
+'talkexists' => 'Sama stranica je uspješno premještena, ali
+stranica za razgovor nije mogla biti premještena jer takva već postoji na novom naslovu. Molimo Vas da ih spojite ručno.',
+'talkpage' => 'Razgovor o stranici',
+'talkpagemoved' => 'Odgovarajuća stranica za razgovor je takođe premještena.',
+'talkpagenotmoved' => 'Odgovarajuća stranica za razgovor <strong>nije</strong> premještena.',
+'templatesused' => 'Šabloni koji su upotrebljeni na ovoj stranici:',
+'textboxsize' => 'Veličine tekstualnog polja',
+'textmatches' => 'Tekst stranice odgovara',
+'thisisdeleted' => 'Pogledaj ili vrati $1?',
+'thumbnail-more' => 'uvećajte',
+'thumbsize' => 'Veličina umanjenog prikaza:',
+'thursday' => 'četvrtak',
+'timezonelegend' => 'Vremenska zona',
+'timezoneoffset' => 'Odstupanje',
+'timezonetext' => 'Unesite broj sati za koji se Vaše lokalno vrijeme razlikuje od serverskog vremena (UTC).',
+'titlematches' => 'Naslov članka odgovara',
+'toc' => 'Sadržaj',
+'tog-autopatrol' => 'Označi moje izmjene kao patrolirane',
+'tog-enotifminoredits' => 'Pošalji mi e-poštu takođe za male izmjene stranica',
+'tog-enotifrevealaddr' => 'Otkrij adresu moje e-pošte u porukama obaviještenja',
+'tog-enotifusertalkpages' => 'Pošalji mi e-poštu kad se promijeni moja korisnička stranica za razgovor',
+'tog-enotifwatchlistpages' => 'Pošalji mi e-poštu kad se promijene stranice',
+'tog-hideminor' => 'Sakrij male izmjene u spisku nedavnih izmjena',
+'tog-highlightbroken' => 'Formatiraj pokvarene veze <a href="" class="new">ovako</a> (alternativa: ovako<a href="" class="internal">?</a>).',
+'tog-justify' => 'Uravnjaj pasuse',
+'tog-minordefault' => 'Označi sve izmjene malim isprva',
+'tog-nocache' => 'Onemogući keširanje stranica',
+'tog-numberheadings' => 'Automatski numeriši podnaslove',
+'tog-previewonfirst' => 'Prikaži izgled pri prvoj izmjeni',
+'tog-previewontop' => 'Prikaži pretpregled prije polja za izmjenu a ne posle',
+'tog-rememberpassword' => 'Zapamti lozinku kroz više seansi',
+'tog-showjumplinks' => 'Omogući "skoči na" poveznice',
+'tog-shownumberswatching' => 'Prikaži broj korisnika koji prate',
+'tog-showtoc' => 'Prikaži sadržaj<br />(u svim stranicama sa više od tri podnaslova)',
+'tog-showtoolbar' => 'Prikaži dugmiće za izmjene (JavaScript)',
+'tog-underline' => 'Podvuci veze:',
+'tog-usenewrc' => 'Poboljšan spisak nedavnih izmjena (JavaScript)',
+'tog-watchcreations' => 'Dodaj stranice koje ja napravim u moj spisak praćenih članaka',
+'tog-watchdefault' => 'Dodaj stranice koje uređujem u moj spisak praćenih članaka',
+'toolbox' => 'Posebne funkcije',
+'tooltip-compareselectedversions' => 'Pogledajte pazlike između dvije selektovane verzije ove stranice. [alt-v]',
+'tooltip-minoredit' => 'Naznačite da se radi o maloj izmjeni [alt-i]',
+'tooltip-preview' => 'Pregledajte Vaše izmjene; molimo Vas da koristite ovo prije nego što sačuvate stranicu! [alt-p]',
+'tooltip-save' => 'Sačuvajte Vaše izmjene [alt-s]',
+'tooltip-search' => 'Pretražite projekat {{SITENAME}} [alt-f]',
+'tooltip-watch' => 'Dodajte ovu stranicu na Vaš spisak praćenih članaka [alt-w]',
+'tuesday' => 'utorak',
+'uclinks' => 'Gledaj poslednjih $1 izmjena; gledaj poslednjih $2 dana.',
+'ucnote' => 'Ispod je poslednjih <b>$1</b> izmjena u poslednjih <b>$2</b> dana.',
+'uctop' => ' (vrh)',
+'uid' => 'Korisnički ID:',
+'unblockip' => 'Odblokiraj korisnika',
+'unblockiptext' => 'Upotrebite donji upitnik da bi ste vratili
+pravo pisanja ranije blokiranoj IP adresi
+ili korisničkom imenu.',
+'unblocklink' => 'deblokiraj',
+'unblocklogentry' => 'deblokiran $1',
+'uncategorizedcategories' => 'Nekategorisane kategorije',
+'uncategorizedpages' => 'Nekategorisane stranice',
+'undelete' => 'Pogledaj izbrisane stranice',
+'undelete_short' => 'Vrati $1 obrisanih izmjena',
+'undeletearticle' => 'Vrati izbrisani članak',
+'undeletebtn' => 'Vrati!',
+'undeletedarticle' => 'vraćeno "$1"',
+'undeletedrevisions' => '$1 revizija vraćeno',
+'undeletehistory' => 'Ako vratite stranicu, sve revizije će biti vraćene njenoj istoriji.
+Ako je nova stranica istog imena napravljena od brisanja, vraćene
+revizije će se pojaviti u ranijoj istoriji, a trenutna revizija sadašnje stranice
+neće biti automatski zamijenjena.',
+'undeletehistorynoadmin' => 'Ova stranica je izbrisana. Ispod se nalazi dio istorije brisanja i istorija revizija izbrisane stranice. Tekst izbrisane stranice je vidljiv samo korisnicima koji su administratori.',
+'undeletepage' => 'Pogledaj i vrati izbrisane stranice',
+'undeletepagetext' => 'Sledeće stranice su izbrisane ali su još uvijek u arhivi i
+mogu biti vraćene. Arhiva moše biti periodično čišćena.',
+'undeleterevision' => 'Izbrisana revizija od $1',
+'undeleterevisions' => '$1 revizija arhivirano',
+'underline-always' => 'Uvijek',
+'underline-default' => 'Po podešavanjima brauzera',
+'underline-never' => 'Nikad',
+'unexpected' => 'Neočekivana vrijednost: "$1"="$2".',
+'unlockbtn' => 'Otključaj bazu',
+'unlockconfirm' => 'Da, zaista želim da otključam bazu.',
+'unlockdb' => 'Otključaj bazu',
+'unlockdbsuccesssub' => 'Baza je otključana',
+'unlockdbsuccesstext' => '{{SITENAME}} baza podataka je otključana.',
+'unlockdbtext' => 'Otključavanje baze će svim korisnicima vratiti mogućnost
+izmjene stranica, promjene korisničkih stranica, izmjene spiska praćenih članaka,
+i svega ostalog što zahtjeva promjene u bazi.
+Molimo Vas da potvrdite da je ovo zaista ono što namijeravate da uradite.',
+'unprotect' => 'odštiti',
+'unprotectcomment' => 'Razlog za skidanje zaštite',
+'unprotectedarticle' => 'odštićena "$1"',
+'unprotectsub' => '(Skidanje zaštite "$1")',
+'unprotectthispage' => 'Odštiti ovu stranicu',
+'unusedcategories' => 'Nekorišćene kategorije',
+'unusedcategoriestext' => 'Sledeće strane kategorija postoje iako ih ni jedan drugi članak ili kategorija ne koriste.',
+'unusedimages' => 'Neupotrebljene slike',
+'unusedimagestext' => '<p>Obratite pažnju da se drugi veb sajtovi, kao što su drugi
+međunarodni Vikiji, mogu povezati na sliku direktnom
+URL-om, i tako mogu još uvijek biti prikazani ovdje uprkos
+aktivnoj upotrebi.</p>',
+'unwatch' => 'Ukinite praćenje',
+'unwatchthispage' => 'Ukinite praćenje',
+'updated' => '(Osvježeno)',
+'upload' => 'Postavi datoteku',
+'uploadbtn' => 'Postavi datoteku',
+'uploaddisabled' => 'Slanje fajlova je isključeno',
+'uploadedfiles' => 'Poslati fajlovi',
+'uploadedimage' => 'poslato "[[$1]]"',
+'uploaderror' => 'Greška pri slanju',
+'uploadlog' => 'log slanja',
+'uploadlogpage' => 'istorija slanja',
+'uploadlogpagetext' => 'Ispod je spisak najskorijih slanja.',
+'uploadnologin' => 'Niste prijavljeni',
+'uploadnologintext' => 'Morate biti [[{{ns:-1}}:Userlogin|prijavljeni]]
+da bi ste slali fajlove.',
+'uploadvirus' => 'Fajl sadrži virus! Detalji: $1',
+'uploadwarning' => 'Upozorenje pri slanju',
+'user_rights_set' => '<b>Prava za korisnika "$1" promjenjena</b>',
+'usercssjsyoucanpreview' => '<strong>Pažnja:</strong> Koristite \'Prikaži izgled\' dugme da testirate svoj novi CSS/JS prije nego što sačuvate.',
+'usercsspreview' => '\'\'\'Zapamtite ovo je samo izgled vašeg CSS-a, još uvijek nije sačuvan!\'\'\'',
+'userexists' => 'Korisničko ime koje ste unijeli je već u upotrebi. Molimo Vas da izaberete drugo ime.',
+'userjspreview' => '\'\'\'Zapamtite ovo je samo izgled vaše JavaScript-e, još uvijek nije sačuvan!\'\'\'',
+'userlogin' => 'Prijavite se / Registrujte se',
+'userlogout' => 'Odjavite se',
+'usermailererror' => 'Objekat pošte je vratio grešku:',
+'username' => 'Korisničko ime:',
+'userpage' => 'Pogledaj korisničku stranicu',
+'userstats' => 'Statistike korisnika',
+'userstatstext' => 'Postoji \'\'\'$1\'\'\' registrovanih korisnika, od kojih
+su \'\'\'$2\'\'\' (ili \'\'\'$4%\'\'\') administratori.',
+'version' => 'Verzija',
+'versionrequired' => 'Verzija $1 MedijaVikija je potrebna',
+'versionrequiredtext' => 'Verzija $1 MedijaVikija je potrebna da bi se koristila ova strana. Pogledajte [[{{ns:-1}}:Version|verziju]]',
+'viewcount' => 'Ovoj stranici je pristupljeno $1 puta.',
+'viewdeleted' => 'Pogledaj $1?',
+'viewdeletedpage' => 'Pogledaj izbrisane stranice',
+'viewprevnext' => 'Pogledaj ($1) ($2) ($3).',
+'views' => 'Pregledi',
+'viewsource' => 'pogledaj kod',
+'viewtalkpage' => 'Pogledaj raspravu',
+'wantedcategories' => 'Tražene kategorije',
+'wantedpages' => 'Tražene stranice',
+'watch' => 'Prati',
+'watchdetails' => '* $1 stranica praćeno ne računajući stranice za razgovor
+* [$4 prikaži i mijenjaj potpuni spisak]',
+'watcheditlist' => 'Ovdje je abecedni spisak stranica koje
+pratite. Označite stranice koje želite da uklonite sa svog spiska i kliknite na dugme \'ukloni izabrane\' na dnu ekrana.',
+'watchlist' => 'Praćeni članci',
+'watchlistcontains' => 'Vaš spisak praćenih članaka sadrži $1 stranica.',
+'watchmethod-list' => 'provjerava se da li ima nedavnih izmjena u praćenim stranicama',
+'watchmethod-recent' => 'provjerava se da li ima praćenih stranica u nedavnim izmjenama',
+'watchnochange' => 'Ništa što pratite nije promjenjeno u prikazanom vremenu.',
+'watchnologin' => 'Niste prijavljeni',
+'watchnologintext' => 'Morate biti [[{{ns:-1}}:Userlogin|prijavljeni]] da bi ste mijenjali spisak praćenih članaka.',
+'watchthis' => 'Prati ovaj članak',
+'watchthispage' => 'Prati ovu stranicu',
+'wednesday' => 'srijeda',
+'welcomecreation' => '<h2>Dobro došli, $1!</h2><p>Vaš nalog je napravljen.
+Ne zaboravite da prilagodite sebi svoja podešavanja.',
+'whatlinkshere' => 'Šta je povezano ovdje',
+'whitelistacctext' => 'Da bi vam bilo dozvoljeno da napravite naloge na ovom Vikiju, morate da se [[{{ns:-1}}:Userlogin|prijavite]] i imate odgovarajuća ovlašćenja.',
+'whitelistacctitle' => 'Nije vam dozvoljeno da napravite nalog',
+'whitelistedittext' => 'Morate da se [[{{ns:-1}}:Userlogin|prijavite]] da bi ste uređivali stranice.',
+'whitelistedittitle' => 'Obavezno je prijavljivanje za uređivanje',
+'whitelistreadtext' => 'Morate da se [[{{ns:-1}}:Userlogin|prijavite]] da bi ste čitali članke.',
+'whitelistreadtitle' => 'Obavezno je prijavljivanje za čitanje',
+'projectpage' => 'Pogledaj stranu o ovoj strani',
+'wlheader-enotif' => '* Obavještavanje e-poštom je omogućeno.',
+'wlheader-showupdated' => '* Stranice koje su izmjenjene od kad ste ih poslednji put posjetili su prikazane \'\'\'podebljanim slovima\'\'\'',
+'wlhideshowbots' => '$1 izmjena botova.',
+'wlhideshowown' => '$1 moje izmjene.',
+'wlnote' => 'Ispod je najskorijih $1 izmjena, načinjenih u posljednjih <b>$2</b> sati.',
+'wlsaved' => 'Ovo je sačuvana verzija vašeg spiska praćenih članaka.',
+'wlshowlast' => 'Prikaži poslednjih $1 sati $2 dana $3',
+'wrong_wfQuery_params' => 'Netačni parametri za wfQuery()<br />
+Funkcija: $1<br />
+Pretraga: $2',
+'wrongpassword' => 'Unijeli ste neispravnu lozinku. Molimo Vas da pokušate ponovo.',
+'wrongpasswordempty' => 'Lozinka je bila prazna. Molimo Vas da pokušate ponovo.',
+'youhavenewmessages' => 'Imate $1 ($2).',
+'yourdiff' => 'Razlike',
+'yourdomainname' => 'Vaš domen',
+'youremail' => 'E-pošta *',
+'yourname' => 'Korisničko ime',
+'yournick' => 'Nadimak (za potpise):',
+'yourpassword' => 'Lozinka',
+'yourpasswordagain' => 'Ponovite lozinku',
+'yourrealname' => 'Vaše pravo ime *',
+'yourtext' => 'Vaš tekst',
+);
+
+
+?>
diff --git a/languages/messages/MessagesCa.php b/languages/messages/MessagesCa.php
new file mode 100644
index 000000000000..f6c4450aff8d
--- /dev/null
+++ b/languages/messages/MessagesCa.php
@@ -0,0 +1,1248 @@
+<?php
+$quickbarSettings = array(
+ "Cap", "Fixa a la dreta", "Fixa a l'esquerra", "Surant a l'esquerra"
+);
+$skinNames = array(
+ 'standard' => "Estàndard",
+ 'nostalgia' => "Nostàlgia",
+ 'cologneblue' => "Colònia blava",
+);
+
+$bookstoreList = array(
+ 'Catàleg Col·lectiu de les Universitats de Catalunya' => 'http://ccuc.cbuc.es/cgi-bin/vtls.web.gateway?searchtype=control+numcard&searcharg=$1',
+ 'Totselsllibres.com' => 'http://www.totselsllibres.com/tel/publi/busquedaAvanzadaLibros.do?ISBN=$1',
+ 'inherit' => true,
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Especial',
+ NS_MAIN => '',
+ NS_TALK => 'Discussió',
+ NS_USER => 'Usuari',
+ NS_USER_TALK => 'Usuari_Discussió',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_Discussió',
+ NS_IMAGE => 'Imatge',
+ NS_IMAGE_TALK => 'Imatge_Discussió',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_Discussió',
+ NS_TEMPLATE => 'Plantilla',
+ NS_TEMPLATE_TALK => 'Plantilla_Discussió',
+ NS_HELP => 'Ajuda',
+ NS_HELP_TALK => 'Ajuda_Discussió',
+ NS_CATEGORY => 'Categoria',
+ NS_CATEGORY_TALK => 'Categoria_Discussió'
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'H:i, M j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'H:i, j M Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'H:i, Y M j',
+);
+
+$linkTrail = '/^([a-zàèéíòóúç·ïü\']+)(.*)$/sDu';
+
+$messages = array(
+'tog-underline' => 'Subratlla els enllaços:',
+'tog-highlightbroken' => 'Formata els enllaços trencats <a href="" class="new">d\'aquesta manera</a> (altrament, es faria d\'aquesta altra manera<a href="" class="internal">?</a>).',
+'tog-justify' => 'Alineació justificada dels paràgrafs',
+'tog-hideminor' => 'Amaga les edicions menors en la pàgina de canvis recents',
+'tog-extendwatchlist' => 'Desplega la llista de seguiment per a mostrar tots els canvis afectats',
+'tog-usenewrc' => 'Presentació millorada dels canvis recents (cal JavaScript)',
+'tog-numberheadings' => 'Enumera automàticament els encapçalaments',
+'tog-showtoolbar' => 'Mostra la barra d\'eines d\'edició (cal JavaScript)',
+'tog-editondblclick' => 'Inicia l\'edició de la pàgina en pitjar-hi dues vegades (cal JavaScript)',
+'tog-editsection' => 'Activa l\'edició per seccions mitjançant enllaç específic corresponent',
+'tog-editsectiononrightclick'=> 'Activa l\'edició per seccions en pitjar sobre l\'encapçalament amb el botó dret del ratolí (cal JavaScript)',
+'tog-showtoc' => 'Mostrar l\'índex de continguts a les pàgines amb més de 3 seccions',
+'tog-rememberpassword' => 'Recorda la contrasenya entre sessions',
+'tog-editwidth' => 'Amplia al màxim la caixa d\'edició',
+'tog-watchcreations' => 'Vigila els articles que he creat',
+'tog-watchdefault' => 'Vigila els articles que he editat',
+'tog-minordefault' => 'Marca totes les contribucions com a edicions menors per defecte',
+'tog-previewontop' => 'Mostra una vista prèvia de l\'article davant del panell d\'edicions',
+'tog-previewonfirst' => 'Mostra una visualització prèvia de l\'article en la primera edició',
+'tog-nocache' => 'Desactiva la memòria cau per als articles',
+'tog-enotifwatchlistpages'=> 'Notifica\'m per correu electrònic els canvis en les pàgines que vigili',
+'tog-enotifusertalkpages'=> 'Notifica per corr-el quan hi han modificacions a la pàgina de discussió del meu compte d\'usuari',
+'tog-enotifminoredits' => 'Notifica per corr-el també en casos d\'edicions menors',
+'tog-enotifrevealaddr' => 'Mostra l\'adreça del meu corr-el en els missatges d\'avís per corr-el',
+'tog-shownumberswatching'=> 'Mostra el nombre d\'usuaris que vigilen l\'article',
+'tog-fancysig' => 'Signatures planes (sense enllaç automàtic)',
+'tog-externaleditor' => 'Recorre a un editor extern per omissió',
+'tog-externaldiff' => 'Recorre a un altre visualitzador de canvis per defecte',
+'tog-showjumplinks' => 'Activa els enllaços de dreceres d\'accessibilitat',
+'tog-uselivepreview' => 'Activa la previsualització automàtica (cal JavaScript) (experimental)',
+'tog-autopatrol' => 'Marca com a vigilades les pàgines que modifiqui',
+'tog-forceeditsummary' => 'Avisa\'m quan el camp de sumari és en blanc',
+'tog-watchlisthideown' => 'Amaga el que he contribuït de la llista de seguiment',
+'tog-watchlisthidebots' => 'Amaga de la llista de seguiment les edicions fetes per usuaris bots',
+'underline-always' => 'Sempre',
+'underline-never' => 'Mai',
+'underline-default' => 'Configuració per defecte del navegador',
+'skinpreview' => '(prova)',
+'sunday' => 'diumenge',
+'monday' => 'dilluns',
+'tuesday' => 'dimarts',
+'wednesday' => 'dimecres',
+'thursday' => 'dijous',
+'friday' => 'divendres',
+'saturday' => 'dissabte',
+'january' => 'gener',
+'february' => 'febrer',
+'march' => 'març',
+'april' => 'abril',
+'may_long' => 'maig',
+'june' => 'juny',
+'july' => 'juliol',
+'august' => 'agost',
+'september' => 'setembre',
+'october' => 'octubre',
+'november' => 'novembre',
+'december' => 'desembre',
+'jan' => 'gen',
+'feb' => 'febr',
+'mar' => 'març',
+'apr' => 'abr',
+'may' => 'maig',
+'jun' => 'juny',
+'jul' => 'jul',
+'aug' => 'ag',
+'sep' => 'set',
+'oct' => 'oct',
+'nov' => 'nov',
+'dec' => 'des',
+'categories' => 'Categories',
+'pagecategories' => '{{PLURAL:$1|Categoria|Categories}}',
+'category_header' => 'Articles a la categoria «$1»',
+'subcategories' => 'Subcategories',
+'mainpage' => 'Pàgina principal',
+'mainpagetext' => '<big>\'\'\'El programari del MediaWiki s\'hi ha instal·lat correctament.\'\'\'</big>',
+'mainpagedocfooter' => 'Consulteu la [http://meta.wikimedia.org/wiki/Help:Contents Guia d\'Usuari] per a més informació sobre com utilitzar el programa wiki.
+
+== Per a començar ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Llista de característiques configurables]
+* [http://www.mediawiki.org/wiki/Help:FAQ PMF del MediaWiki]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de correu (\'\'listserv\'\') per a anuncis del MediaWiki]',
+'portal' => 'Portal comunitari',
+'portal-url' => 'Project:Portal',
+'about' => 'Quant a',
+'aboutsite' => 'Quant al projecte de {{SITENAME}}',
+'aboutpage' => 'Project:Quant a',
+'article' => 'Contingut de la pàgina',
+'help' => 'Ajuda',
+'helppage' => 'Help:Índex',
+'bugreports' => 'Informes d\'errors del programari',
+'bugreportspage' => 'Project:Informes d\'errors',
+'sitesupport' => 'Donacions',
+'sitesupport-url' => 'Wikimedia:Donatius',
+'faq' => 'PMF',
+'faqpage' => 'Project:PMF',
+'edithelp' => 'Ajuda per a editar-n\'hi',
+'newwindow' => '(obre en una nova finestra)',
+'edithelppage' => 'Help:Com s\'edita una pàgina',
+'cancel' => 'Anul·la',
+'qbfind' => 'Cerca',
+'qbbrowse' => 'Navega',
+'qbedit' => 'Edita',
+'qbpageoptions' => 'Opcions de pàgina',
+'qbpageinfo' => 'Informació de pàgina',
+'qbmyoptions' => 'Pàgines pròpies',
+'qbspecialpages' => 'Pàgines especials',
+'moredotdotdot' => 'Més...',
+'mypage' => 'Pàgina personal',
+'mytalk' => 'Discussió',
+'anontalk' => 'Contacta amb l\'anònim que fa servir aquesta IP',
+'navigation' => 'Navegació',
+'metadata_help' => 'Metadades (vegeu [[Project:Metadata]] per a més informació):',
+'currentevents' => 'Actualitat',
+'currentevents-url' => 'Project:Actualitat',
+'disclaimers' => 'Avís general',
+'disclaimerpage' => 'Project:Avís general',
+'privacy' => 'Política de privadesa',
+'privacypage' => 'Project:Política de privadesa',
+'errorpagetitle' => 'Error',
+'returnto' => 'Torna cap a $1.',
+'tagline' => 'De {{SITENAME}}',
+'search' => 'Cerca',
+'searchbutton' => 'Cerca',
+'go' => 'Vés-hi',
+'searcharticle' => 'Vés-hi',
+'history' => 'Historial de canvis',
+'history_short' => 'Historial',
+'updatedmarker' => 'actualitzat des de la darrera visita',
+'info_short' => 'Informació',
+'printableversion' => 'Versió per a impressora',
+'permalink' => 'Enllaç permanent',
+'print' => 'Envia aquesta pàgina a la cua d\'impressió',
+'edit' => 'Edita',
+'editthispage' => 'Edita la pàgina',
+'delete' => 'Elimina',
+'deletethispage' => 'Elimina la pàgina',
+'undelete_short' => 'Recupera {{PLURAL:$1|la pàgina eliminada|$1 modificacions de la pàgina eliminada}}',
+'protect' => 'Protecció',
+'protectthispage' => 'Protecció de la pàgina',
+'unprotect' => 'Desprotecció',
+'unprotectthispage' => 'Desprotecció de la pàgina',
+'newpage' => 'Pàgina nova',
+'talkpage' => 'Discussió de la pàgina',
+'specialpage' => 'Pàgina especial',
+'personaltools' => 'Eines de l\'usuari',
+'postcomment' => 'Envia un comentari',
+'articlepage' => 'Mostra la pàgina',
+'talk' => 'Discussió',
+'views' => 'Vistes',
+'toolbox' => 'Eines',
+'userpage' => 'Mostra la pàgina d\'usuari',
+'projectpage' => 'Mostra la pàgina del projecte',
+'imagepage' => 'Mostra la pàgina de la imatge',
+'viewtalkpage' => 'Mostra la discussió',
+'otherlanguages' => 'En altres llengües',
+'redirectedfrom' => '(S\'ha redirigit des de $1)',
+'autoredircomment' => 'S\'està redirigint a [[$1]]',
+'redirectpagesub' => 'Pàgina de redireccionament',
+'lastmodifiedat' => 'Darrera modificació de la pàgina: $2, $1.',
+'viewcount' => 'Aquesta pàgina ha estat visitada {{plural:$1|una vegada|$1 vegades}}.',
+'copyright' => 'El contingut és disponible sota els termes d\'una llicència $1',
+'protectedpage' => 'Pàgina protegida',
+'jumpto' => 'Dreceres ràpides:',
+'jumptonavigation' => 'navegació',
+'jumptosearch' => 'cerca',
+'badaccess' => 'Error de permisos',
+'versionrequired' => 'Cal la versió $1 del MediaWiki',
+'versionrequiredtext' => 'Cal la versió $1 del MediaWiki per a utilitzar aquesta pàgina. Vegeu [[Special:Version]]',
+'ok' => 'D\'acord',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Obtingut de "$1"',
+'youhavenewmessages' => 'Teniu $1 ($2).',
+'newmessageslink' => 'nous missatges',
+'newmessagesdifflink' => 'darrers canvis',
+'editsection' => 'edita',
+'editold' => 'edita',
+'editsectionhint' => 'Edita la secció: $1',
+'toc' => 'Contingut',
+'showtoc' => 'desplega',
+'hidetoc' => 'amaga',
+'thisisdeleted' => 'Voleu mostrar o restaurar $1?',
+'viewdeleted' => 'Voleu mostrar $1?',
+'restorelink' => '{{PLURAL:$1|una versió esborrada|$1 versions esborrades}}',
+'feedlinks' => 'Sindicament:',
+'feed-invalid' => 'La subscripció no és vàlida pel tipus de sindicament.',
+'nstab-main' => 'Article',
+'nstab-user' => 'Pàgina d\'usuari',
+'nstab-media' => 'Pàgina de mitjans',
+'nstab-special' => 'Pàgina especial',
+'nstab-project' => 'Pàgina del projecte',
+'nstab-image' => 'Fitxer',
+'nstab-mediawiki' => 'Missatge',
+'nstab-template' => 'Plantilla',
+'nstab-help' => 'Ajuda',
+'nstab-category' => 'Categoria',
+'nosuchaction' => 'No es reconeix aquesta operació',
+'nosuchactiontext' => 'El programari wiki que fa servir {{SITENAME}} no reconeix l\'operació especificada per l\'adreça URL',
+'nosuchspecialpage' => 'No es troba la pàgina especial que busqueu',
+'nospecialpagetext' => 'La pàgina especial que demaneu no és vàlida. Vegeu la llista de pàgines especials en [[Special:Specialpages]].',
+'error' => 'Error',
+'databaseerror' => 'S\'ha produït un error en la base de dades',
+'dberrortext' => 'S\'ha produït un error de sintaxi en una consulta a la base de dades.
+Açò podria indicar un error en el programari.
+La darrera consulta que s\'ha intentat fer ha estat:
+<blockquote><tt>$1</tt></blockquote>
+des de la funció «<tt>$2</tt>».
+L\'error de retorn de MySQL ha estat «<tt>$3: $4</tt>».',
+'dberrortextcl' => 'S\'ha produït un error de sintaxi en una consulta a la base de dades.
+La darrera consulta que s\'ha intentat fer ha estat:
+<blockquote><tt>$1</tt></blockquote>
+des de la funció «<tt>$2</tt>».
+L\'error de retorn de MySQL ha estat «<tt>$3: $4</tt>».',
+'noconnect' => 'Al programari wiki hi ha algun problema tècnic, i no s\'ha pogut contactar amb el servidor de la base de dades. <br />
+$1',
+'nodb' => 'No s\'ha pogut seleccionar la base de dades $1',
+'cachederror' => 'Tot seguit és una còpia provinent de la memòria cau de la pàgina que hi heu demanat i, per això, podria no estar actualitzada.',
+'laggedslavemode' => 'Avís: La pàgina podria mancar de modificacions recents.',
+'readonly' => 'La base de dades es troba blocada',
+'enterlockreason' => 'Escrigueu un motiu pel blocatge, així com una estimació de quan tindrà lloc el desblocatge',
+'readonlytext' => 'La base de dades està temporalment blocada segurament per tasques de manteniment, després de les quals es tornarà a la normalitat.
+
+L\'administrador que l\'ha blocada ha donat aquesta explicació: $1',
+'missingarticle' => 'La base de dades no ha trobat el text d\'una
+pàgina que hauria d\'haver trobat, anomenada "$1".
+Això acostuma a passar a quan se segueix un enllaç a una pàgina que ha estat eliminada.
+
+Si aquest no és el cas, probablement es tracta d\'un error en el programari.
+Informeu-ne si us plau a un administrador, fent-ne arribar l\'adreça URL.',
+'readonly_lag' => 'S\'ha blocada la base de dades automàticament per a la sincronització dels servidors',
+'internalerror' => 'Fallida interna',
+'filecopyerror' => 'No s\'ha pogut copiar el fitxer "$1" com "$2".',
+'filerenameerror' => 'No s\'ha pogut reanomenar el fitxer "$1" com "$2".',
+'filedeleteerror' => 'No s\'ha pogut esborrar el fitxer "$1".',
+'filenotfound' => 'No s\'ha pogut trobar el fitxer "$1".',
+'unexpected' => 'S\'ha trobat un valor imprevist: "$1"="$2".',
+'formerror' => 'Error: no s\'ha pogut enviar les dades del formulari',
+'badarticleerror' => 'Aquesta operació no es pot dur a terme en aquesta pàgina',
+'cannotdelete' => 'No s\'ha pogut esborrar la pàgina o el fitxer especificat, o potser ja ha estat esborrat per algú altre.',
+'badtitle' => 'El títol no és correcte',
+'badtitletext' => 'El títol de la pàgina que heu demanada no és correcte, és en blanc o és un enllaç inter-lingüístic trencat. Podria haver-hi algun caràcter no permés per al seu ús en els títols.',
+'perfdisabled' => 'S\'ha desactivat temporalment aquesta funcionalitat perquè sobrecarrega la base de dades fins al punt d\'inutilitzar el programari wiki.',
+'perfdisabledsub' => 'Això és una còpia desada de $1:',
+'perfcached' => 'Tot seguit es mostren les dades que es troben a la memòria cau, i podria no tenir els darrers canvis del dia:',
+'perfcachedts' => 'Tot seguit es mostra les dades que es troben a la memòria cau, la darrera actualització de la qual fou el $1.',
+'wrong_wfQuery_params' => 'Paràmetres incorrectes per a wfQuery()<br />
+Funció: $1<br />
+Consulta: $2',
+'viewsource' => 'Mostra la font',
+'viewsourcefor' => 'per a $1',
+'protectedtext' => 'Aquesta pàgina ha estat protegida per a evitar modificacions; per a assabentar-se dels motius que han dut a aquesta decissió, si us plau, vegeu [[Project:Protecció de pàgines]].
+
+Mentrestant, podeu veure i copiar el contingut de la pàgina:',
+'protectedinterface' => 'Aquesta pàgina conté cadenes de text per a la interfície del programari, i és protegida per a previndre\'n abusos.',
+'editinginterface' => '\'\'\'Avís:\'\'\' Esteu editant una pàgina que conté cadenes de text per a la interfície d\'aquest programari. Tingueu en compte que els canvis que es fan a aquesta pàgina afecten a l\'aparença de la interfície d\'usuari per a tots els usuaris.',
+'sqlhidden' => '(consulta SQL oculta)',
+'logouttitle' => 'Fi de la sessió',
+'logouttext' => '<strong>Heu finalitzat la vostra sessió.</strong><br />
+Podeu continuar utilitzant {{SITENAME}} de forma anònima, o podeu iniciar una sessió una altra vegada amb el mateix o un altre usuari. Tingueu en compte que algunes pàgines poden continuar mostrant-se com si encara estiguéssiu en una sessió, fins que buideu la memòria cau del vostre navegador.',
+'welcomecreation' => '== Us donem la benvinguda, $1! ==
+
+S\'ha creat el vostre compte. No oblideu de canviar les vostres preferències.',
+'loginpagetitle' => 'Inici de sessió',
+'yourname' => 'Nom d\'usuari',
+'yourpassword' => 'Contrasenya',
+'yourpasswordagain' => 'Escriviu una altra vegada la contrasenya',
+'remembermypassword' => 'Recorda la contrasenya entre sessions.',
+'yourdomainname' => 'El vostre domini',
+'externaldberror' => 'Hi ha hagut una fallida en el servidor d\'autenticació externa de la base de dades i no teniu permís per a actualitzar el vostre compte d\'accès extern.',
+'loginproblem' => '<strong>S\'ha produït un problema en iniciar la sessió.</strong><br />Proveu-ho de nou!',
+'alreadyloggedin' => '<strong>Benvingut, usuari $1!</strong><br />',
+'login' => 'Inici de sessió',
+'loginprompt' => 'Heu de tenir les galetes activades per a poder-vos registar.',
+'userlogin' => 'Inicia una sessió / crea un compte',
+'logout' => 'Finalitza la sessió',
+'userlogout' => 'Finalitza la sessió',
+'notloggedin' => 'No us heu identificat',
+'nologin' => 'No teniu un compte? $1.',
+'nologinlink' => 'Crea un compte',
+'createaccount' => 'Crea un nou compte',
+'gotaccount' => 'Ja teniu un compte? $1.',
+'gotaccountlink' => 'Inicia una sessió',
+'createaccountmail' => 'per correu electrònic',
+'badretype' => 'Les contrasenyes que heu introduït no coincideixen.',
+'userexists' => 'El nom que heu entrat ja és en ús. Escolliu-ne un de diferent.',
+'youremail' => 'Adreça electrònica *',
+'username' => 'Nom d\'usuari:',
+'uid' => 'Identificador d\'usuari:',
+'yourrealname' => 'Nom real *',
+'yourlanguage' => 'Llengua:',
+'yourvariant' => 'Variant lingüística',
+'yournick' => 'Àlies (nom que es mostrarà):',
+'badsig' => 'La signatura que heu inserit no és vàlida; verifiqueu les etiquetes HTML que heu emprat.',
+'email' => 'Adreça electrònica',
+'prefs-help-email-enotif'=> 'Si n\'heu habilitat les opcions, l\'adreça també s\'utilitzarà per a enviar-vos notificacions per correu electrònic.',
+'prefs-help-realname' => '* Nom real (opcional): si escolliu donar aquesta informació serà utilitzada per a donar-vos l\'atribució de la vostra feina.',
+'loginerror' => 'Error d\'inici de sessió',
+'prefs-help-email' => '* Adreça electrònica (opcional): Permet als altres usuaris enviar-vos missatges de correu electrònic a través de la vostra pàgina d\'usuari o de discussió, sense que així calgui revelar la vostra identitat.',
+'nocookiesnew' => 'S\'ha creat el compte d\'usuari, però no esteu enregistrat. El projecte {{SITENAME}} usa galetes per enregistrar els usuaris. Si us plau activeu-les, per a poder enregistrar-vos amb el vostre nom d\'usuari i la clau.',
+'nocookieslogin' => 'El programari {{SITENAME}} utilitza galetes per enregistrar usuaris. Teniu les galetes desactivades. Activeu-les i torneu a provar.',
+'noname' => 'No heu especificat un nom vàlid d\'usuari.',
+'loginsuccesstitle' => 'S\'ha iniciat la sessió amb èxit',
+'loginsuccess' => 'Heu iniciat la sessió a {{SITENAME}} com a "$1".',
+'nosuchuser' => 'No hi ha cap usuari anomenat "$1".
+Reviseu-ne l\'ortografia, o creeu un nou compte d\'usuari.',
+'nosuchusershort' => 'No hi ha cap usuari anomenat "$1". Comproveu que ho hàgiu escrit correctament.',
+'nouserspecified' => 'Heu d\'especificar un nom d\'usuari.',
+'wrongpassword' => 'La contrasenya que heu introduït és incorrecta. Torneu-ho a provar.',
+'wrongpasswordempty' => 'La contrasenya que s\'ha introduït era en blanc. Torneu-ho a provar.',
+'mailmypassword' => 'Envia\'m una nova contrasenya per correu electrònic',
+'passwordremindertitle' => 'Recordatori de la contrasenya del projecte {{SITENAME}}',
+'passwordremindertext' => 'Algú (vós mateix segurament, des de l\'adreça l\'IP $1) ha sol·licitat que us enviéssim una nova contrasenya per a iniciar la sessió al projecte {{SITENAME}} ($4).
+La contrasenya per a l\'usuari «$2» és ara «$3».
+Ara hauríeu d\'iniciar la sessió i canviar la vostra contrasenya.
+
+Si algú altre hagués fet aquesta sol·licitud o si ja haguéssiu recordat la vostra contrasenya i
+no volguéssiu canviar-la, ignoreu aquest missatge i continueu utilitzant
+la vostra antiga contrasenya.',
+'noemail' => 'No hi ha cap adreça electrònica registrada de l\'usuari "$1".',
+'passwordsent' => 'S\'ha enviat una nova contrasenya a l\'adreça electrònica registrada per "$1".
+Inicieu una sessió després que la rebeu.',
+'eauthentsent' => 'S\'ha enviat un correu electrònic a l\'adreça especificada. Abans no s\'envïi cap altre correu electrònic a aquesta adreça, cal verificar que és realment vostra. Per tant, cal que seguiu les instruccions presents en el correu electrònic que se us ha enviat.',
+'mailerror' => 'S\'ha produït un error en enviar el missatge: $1',
+'acct_creation_throttle_hit'=> 'Ho sentim, no és permés de tenir-hi més de $1 comptes d\'usuari per persona.',
+'emailauthenticated' => 'S\'ha autenticat la vostra adreça electrònica a $1.',
+'emailnotauthenticated' => 'La vostra adreça de correu electrònic encara no està autentificada. No rebrà correu electrònic provinent de cap les següents funcionalitats.',
+'noemailprefs' => 'Especifiqueu una adreça electrònica per a activar aquestes característiques.',
+'emailconfirmlink' => 'Confirmeu la vostra adreça electrònica',
+'invalidemailaddress' => 'No es pot acceptar l\'adreça electrònica perquè sembla que té un format no vàlid.
+Introduïu una adreça amb un format adequat o bé buideu el camp.',
+'accountcreated' => 'S\'ha creat el compte',
+'accountcreatedtext' => 'S\'ha creat el compte d\'usuari de $1.',
+'bold_sample' => 'Text en negreta',
+'bold_tip' => 'Text en negreta',
+'italic_sample' => 'Text en cursiva',
+'italic_tip' => 'Text en cursiva',
+'link_sample' => 'Títol de l\'enllaç',
+'link_tip' => 'Enllaç intern',
+'extlink_sample' => 'http://www.exemple.cat títol de l\'enllaç',
+'extlink_tip' => 'Enllaç extern (recordeu el prefix http://)',
+'headline_sample' => 'Text per a l\'encapçalament',
+'headline_tip' => 'Encapçalat de secció de 2n nivell',
+'math_sample' => 'Inseriu una fórmula ací',
+'math_tip' => 'Fórmula matemàtica (LaTeX)',
+'nowiki_sample' => 'Inseriu ací text no formatat',
+'nowiki_tip' => 'Ignora la formatació wiki',
+'image_sample' => 'Exemple.jpg',
+'image_tip' => 'Imatge annexada',
+'media_sample' => 'Exemple.ogg',
+'media_tip' => 'Enllaç cap al fitxer multimèdia',
+'sig_tip' => 'La vostra signatura amb marca horària',
+'hr_tip' => 'Línia horitzontal (useu-lo moderadament)',
+'summary' => 'Resum',
+'subject' => 'Tema/capçalera',
+'minoredit' => 'Aquesta és una edició menor.',
+'watchthis' => 'Vigila aquest article.',
+'savearticle' => 'Desa la pàgina',
+'preview' => 'Vista prèvia',
+'showpreview' => 'Mostra una vista prèvia',
+'showlivepreview' => 'Vista ràpida',
+'showdiff' => 'Mostra els canvis',
+'anoneditwarning' => '\'\'\'Atenció:\'\'\' No esteu registrats amb un nom d\'usuari. Es desarà la vostra adreça IP en l\'historial de la pàgina.',
+'missingsummary' => '\'\'\'Recordatori\'\'\': Heu deixat en blanc el sumari d\'edició. Si torneu a clicar el botó de desar, l\'edició es desarà sense sumari.',
+'missingcommenttext' => 'Introduïu un comentari a continuació.',
+'blockedtitle' => 'L\'usuari està blocat',
+'blockedtext' => 'El vostre nom d\'usuari o adreça IP ha estat blocada per $1.
+El motiu és:<br />$2<p>Podeu contactar $1 o un dels [[Project:Administrators|administradors]] per a discutir el blocatge.
+
+Tingueu un compte que no podeu fer servir la característica «envia un missatge electrònic a l\'usuari» a menys que tingueu una adreça de correu vàlida registrada a les vostres [[Special:Preferences|preferències d\'usuari]].
+
+La vostra adreça IP és $3. Si us plau, incloeu aquesta adreça en totes les consultes que feu.',
+'blockedoriginalsource' => 'La font de \'\'\'$1\'\'\' es mostra a sota:',
+'blockededitsource' => 'El text de les vostres edicions a \'\'\'$1\'\'\' es mostra a continuació:',
+'whitelistedittitle' => 'Cal iniciar una sessió per a poder editar',
+'whitelistedittext' => 'Heu de $1 per editar pàgines.',
+'whitelistreadtitle' => 'Heu d\'iniciar una sessió per a llegir-ho',
+'whitelistreadtext' => 'Heu d\'[[Special:Userlogin|indentificar-vos]] per llegir les pàgines.',
+'whitelistacctitle' => 'No teniu permisos per a crear un compte',
+'whitelistacctext' => 'Per estar autoritzat a crear comptes en aquesta Viqui heu d\'[[Special:Userlogin|identificar-vos]] i tenir els permisos apropiats.',
+'confirmedittitle' => 'Cal una confirmació de l\'adreça electrònica per a poder editar',
+'confirmedittext' => 'Heu de confirmar la vostra adreça electrònica abans de poder editar pàgines. Definiu i valideu la vostra adreça electrònica a través de les vostres [[Special:Preferences|preferències d\'usuari]].',
+'loginreqtitle' => 'Cal que inicieu una sessió',
+'loginreqlink' => 'inicia una sessió',
+'loginreqpagetext' => 'Heu de ser $1 per a visualitzar altres pàgines.',
+'accmailtitle' => 'S\'ha enviat una contrasenya.',
+'accmailtext' => 'S\'ha enviat a $2 la contrasenya per a «$1».',
+'newarticle' => '(Nou)',
+'newarticletext' => 'Heu seguit un enllaç a una pàgina que encara no existeix.
+Per a crear-la comenceu a escriure en l\'espai d\'abaix
+(vegeu l\'[[Project:Ajuda|ajuda]] per a més informació).
+Si sou ací per error simplement cliqueu el botó "enrere" del vostre navegador.',
+'anontalkpagetext' => '----\'\'Aquesta és la pàgina de discussió d\'un usuari anònim que encara no ha creat un compte o que no usa el seu nom registrat. Per tant hem d\'emprar la seva adreça IP numèrica per identificar-lo. Una adreça IP pot ser compartida per molts usuaris. Si sou un usuari anònim i trobau que us han adreçat comentaris inoportuns, si us plau, [[Special:Userlogin|creeu-vos un compte]] per evitar futures confusions amb altres usuaris anònims.\'\'',
+'noarticletext' => 'En aquest moment no hi ha text en aquesta pàgina. Podeu [[Special:Search/{{PAGENAME}}|cercar-ne el títol]] en altres pàgines o [{{fullurl:{{FULLPAGENAME}}|action=edit}} començar a escriure-hi].',
+'clearyourcache' => '\'\'\'Nota:\'\'\' Després de desar, heu de posar al dia la memòria cau del vostre navegador per veure els canvis. \'\'\'Mozilla / Firefox / Safari:\'\'\' Premeu \'\'Shift\'\' mentre cliqueu \'\'Actualitza\'\' (Reload), o premeu \'\'Ctrl+Shift+R\'\' (\'\'Cmd+Shift+R\'\' en un Mac Apple); \'\'\'Internet Explorer:\'\'\' premeu \'\'Ctrl\'\' mentre cliqueu \'\'Actualitza\'\' (Refresh), o premeu \'\'Ctrl+F5\'\'; \'\'\'Konqueror:\'\'\': simplement cliqueu el botó \'\'Recarregar\'\' (Reload), o premeu \'\'F5\'\'; \'\'\'Opera\'\'\' haureu d\'esborrar completament la vostra memòria cau (caché) a \'\'Tools→Preferences\'\'.',
+'updated' => '(Actualitzat)',
+'note' => '<strong>Nota:</strong>',
+'previewnote' => '<strong>Adoneu-vos que això només és una vista prèvia, els canvis dels quals encara no s\'han alçat!</strong>',
+'previewconflict' => 'Aquesta previsualització reflexa el text a l\'ària
+d\'edició superior tal i com apareixerà si escolliu gravar.',
+'importing' => 'S\'està important $1',
+'editing' => 'S\'està editant $1',
+'editinguser' => 'S\'està editant $1',
+'editingsection' => 'S\'està editant $1 (secció)',
+'editingcomment' => 'S\'està editant $1 (comentari)',
+'editconflict' => 'Conflicte d\'edició: $1',
+'explainconflict' => 'Algú més ha canviat aquesta pàgina des que l\'heu editada.
+L\'ària de text superior conté el text de la pàgina com existeix actualment. Els vostres canvis es mostren a l\'ària de text inferior.
+Haureu d\'incorporar els vostres canvis en el text existent.
+<b>Sólo</b> el text a l\'ària de text superior serà gravat quan premeu
+ "Desa pàgina".<br />',
+'yourtext' => 'El vostre text',
+'storedversion' => 'Versió emmagatzemada',
+'nonunicodebrowser' => '<strong>ALERTA: El vostre navegador no és compatible amb unicode, si us plau canvieu-lo abans d\'editar articles.</strong>',
+'editingold' => '<strong>ATENCIÓ:Esteu editant una versió antiga d\'aquesta pàgina.
+Si la graveu, els canvis fets des d\'eixa revisió es perdran.</strong>',
+'yourdiff' => 'Diferències',
+'copyrightwarning2' => 'Si us plau, tingueu-se en consideració que totes les contribucions per al projecte de {{SITENAME}} són considerades com a publicades sota els termes de la Llicència de Documentació Lliure GNU (vegeu més detalls en $1). Si no desitgeu la modificació i distribució lliure dels vostres escrits sense el vostre consentiment, no els poseu ací. A més a més, en enviar-hi el vostre escrit, doneu fe en què tot és sota la vostra autoria, o copiats des de fonts en el domini públic o semblants.',
+'longpagewarning' => '<strong>ATENCIÓ: Aquesta pàgina fa $1 kB; hi ha navegadors que poden presentar problemes editant pàgines que s\'acostin o sobrepassin els 32 kB. Intenteu, si és possible, dividir la pàgina en seccions més petites.</strong>',
+'longpageerror' => '<strong>ERROR: El text que heu introduït és de $1 kB i sobrepassa el màxim permès de $2 kB. Per tant, no es desarà.</strong>',
+'readonlywarning' => '<strong>ADVERTÈNCIA: La base de dades està tancada per manteniment
+i no podeu desar les vostres contribucions en aquests moments. podeu retallar i enganxar el codi
+en un fitxer de text i desar-lo més tard.</strong>',
+'protectedpagewarning' => '<strong>ATENCIÓ: Aquesta pàgina està blocada i només pot ser editada per usuaris [[Project:Administradors|administradors]].</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Atenció:\'\'\' Aquesta pàgina està blocada i només pot ser editada per usuaris registrats.',
+'templatesused' => 'Aquesta pàgina fa servir les següents plantilles:',
+'nocreatetitle' => 'S\'ha limitat la creació de pàgines',
+'nocreatetext' => 'Està restringida la possibilitat de crear noves pàgines.
+Podeu editar les planes ja existents o bé [[Special:Userlogin|entrar en un compte d\'usuari]].',
+'revhistory' => 'Historial de revisions',
+'nohistory' => 'No hi ha un historial de revisions per a aquesta pàgina.',
+'revnotfound' => 'Revisió no trobada',
+'revnotfoundtext' => 'No s\'ha pogut trobar la revisió antiga de la pàgina que demanàveu.
+Reviseu l\'URL que heu emprat per a accedir-hi.',
+'loadhist' => 'Recuperant la història de la pàgina',
+'currentrev' => 'Revisió actual',
+'revisionasof' => 'Revisió de $1',
+'revision-info' => 'Revisió de $1; $2',
+'previousrevision' => '←Versió anterior',
+'nextrevision' => 'Versió posterior→',
+'currentrevisionlink' => 'Versió actual',
+'cur' => 'act',
+'next' => 'seg',
+'last' => 'prev',
+'histlegend' => 'Simbologia: (act) = diferència amb la versió actual,
+(prev) = diferència amb la versió prèvia, m = edició menor',
+'deletedrev' => '[suprimit]',
+'histfirst' => 'El primer',
+'histlast' => 'El darrer',
+'rev-deleted-comment' => '(s\'ha suprimit el comentari)',
+'rev-deleted-user' => '(s\'ha suprimit el nom d\'usuari)',
+'rev-delundel' => 'mostra/amaga',
+'history-feed-title' => 'Historial de revisió',
+'history-feed-description'=> 'Historial de revisió per a aquesta pàgina del wiki',
+'history-feed-item-nocomment'=> '$1 a $2',
+'revdelete-selected' => 'Revisió seleccionada de [[:$1]]',
+'revdelete-legend' => 'Defineix restriccions en la revisió:',
+'revdelete-hide-text' => 'Amaga el text de revisió',
+'revdelete-hide-comment'=> 'Amaga el comentari de l\'edició',
+'revdelete-hide-user' => 'Amaga el nom d\'usuari o la IP de l\'editor',
+'revdelete-hide-restricted'=> 'Aplica aquestes restriccions als administradors com també als altres',
+'revdelete-log' => 'Comentari del registre:',
+'revdelete-submit' => 'Aplica a la revisió seleccionada',
+'difference' => '(Diferència entre revisions)',
+'loadingrev' => 'recuperant revisió per a diff',
+'lineno' => 'Línia $1:',
+'editcurrent' => 'Edita la versió actual d\'aquesta pàgina',
+'selectnewerversionfordiff'=> 'Selecciona una nova versió per a comparar',
+'selectolderversionfordiff'=> 'Selecciona una versió més antiga per a comparar',
+'compareselectedversions'=> 'Compara les versions seleccionades',
+'searchresults' => 'Resultats de la cerca',
+'searchresulttext' => 'Per a més informació de les cerques del projecte {{SITENAME}}, aneu a [[Project:Cerca|Cerca al projecte {{SITENAME}}]].',
+'searchsubtitle' => 'Heu cercat \'\'\'[[:$1]]\'\'\'',
+'searchsubtitleinvalid' => 'Per consulta "$1"',
+'badquery' => 'Consulta de recerca formulada de manera incorrecta',
+'badquerytext' => 'No s\'ha pogut processar la recerca.
+El motiu és probablement per què heu intentat cercar una paraula de menys de tres lletres, la qual cosa encara no és possible.
+També pot ser que hàgiu comès un error en lletrejar el terme.
+Torneu-ho a provar amb una altra recerca.',
+'matchtotals' => 'La consulta "$1" ha coincidit amb $2 títols d\'articles
+i el text de $3 articles.',
+'noexactmatch' => '\'\'\'No hi ha cap pàgina anomenada «$1».\'\'\' Si voleu, podeu ajudar [[:$1|creant-la]].',
+'titlematches' => 'Coincidències de títol d\'article',
+'notitlematches' => 'No hi ha coincidències de títol d\'article',
+'textmatches' => 'Coincidències de text d\'article',
+'notextmatches' => 'No hi ha coincidències de text d\'article',
+'prevn' => '$1 anteriors',
+'nextn' => '$1 següents',
+'viewprevnext' => 'Vés a ($1) ($2) ($3).',
+'showingresults' => 'S\'està mostrant a sota <b>$1</b> resultats començant per #<b>$2</b>.',
+'nonefound' => '<strong>Nota</strong>: les recerques sense èxit són causades tot sovint
+per recerques de paraules comunes com "la" o "de",
+que no es troben a l\'índex, o per especificar més d\'una paraula a cercar (només les pàgines
+que contenen tots els termes d\'una recerca apareixeran en el resultat).',
+'powersearch' => 'Cerca',
+'powersearchtext' => '
+Cerca en espais de nom :<br />
+$1<br />
+$2 Llista redireccions Cerca $3 $9',
+'searchdisabled' => 'La cerca dins el projecte {{SITENAME}} està desactivat. Mentrestant podeu cercar a través de Google, però tingueu en compte que la seva base de dades no estarà actualitzada.',
+'blanknamespace' => '(Portada)',
+'preferences' => 'Preferències',
+'prefsnologin' => 'No heu iniciat una sessió',
+'prefsnologintext' => 'Heu d\'haver [[Special:Userlogin|entrat]] per seleccionar preferències d\'usuari.',
+'prefsreset' => 'Les preferències han estat respostes des d\'emmagatzematge.',
+'qbsettings' => 'Preferències de "Quickbar"',
+'changepassword' => 'Canvia la contrasenya',
+'skin' => 'Aparença',
+'math' => 'Com es mostren les fòrmules',
+'dateformat' => 'Format de la data',
+'datedefault' => 'Cap preferència',
+'datetime' => 'Data i hora',
+'math_failure' => 'No s\'ha pogut entendre',
+'math_unknown_error' => 'error desconegut',
+'math_unknown_function' => 'funció desconeguda',
+'math_lexing_error' => 'error de lèxic',
+'math_syntax_error' => 'error de sintaxi',
+'prefs-personal' => 'Perfil d\'usuari',
+'prefs-rc' => 'Canvis recents',
+'saveprefs' => 'Desa les preferències',
+'resetprefs' => 'Torna a preferències per defecte',
+'oldpassword' => 'Contrasenya antiga',
+'newpassword' => 'Contrasenya nova',
+'retypenew' => 'Reescriviu la nova contrasenya',
+'textboxsize' => 'Dimensions de la caixa de text',
+'rows' => 'Files',
+'columns' => 'Columnes',
+'searchresultshead' => 'Preferències de la cerca',
+'resultsperpage' => 'Resultats a mostrar per pàgina',
+'contextlines' => 'Línies a mostrar per resultat',
+'contextchars' => 'Caràcters de context per línia',
+'stubthreshold' => 'Llindar d\'article mínim',
+'recentchangescount' => 'Nombre de títols en canvis recents',
+'savedprefs' => 'Les vostres preferències han estat desades.',
+'timezonelegend' => 'Fus horari',
+'timezonetext' => 'Entreu el número d\'hores de diferència entre la vostra hora local
+i l\'hora del servidor (UTC).',
+'localtime' => 'Hora local',
+'timezoneoffset' => 'Diferència',
+'servertime' => 'Hora del servidor',
+'allowemail' => 'Habilita el correu electrònic des d\'altres usuaris',
+'default' => 'per defecte',
+'files' => 'Fitxers',
+'userrights-lookup-user'=> 'Gestiona els grups d\'usuari',
+'userrights-user-editname'=> 'Introduïu un nom d\'usuari:',
+'editusergroup' => 'Edita els grups d\'usuaris',
+'userrights-editusergroup'=> 'Edita els grups d\'usuaris',
+'userrights-groupsmember'=> 'Membre de:',
+'userrights-groupsavailable'=> 'Grups disponibles:',
+'group' => 'Grup:',
+'group-sysop' => 'Administradors',
+'group-bureaucrat' => 'Buròcrates',
+'group-all' => '(tots)',
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Administrador',
+'group-bureaucrat-member'=> 'Buròcrata',
+'grouppage-bot' => 'Project:Bots',
+'grouppage-sysop' => 'Project:Administradors',
+'grouppage-bureaucrat' => 'Project:Buròcrates',
+'changes' => 'canvis',
+'recentchanges' => 'Canvis recents',
+'recentchangestext' => 'Seguiu els canvis recents del projecte {{SITENAME}} en aquesta pàgina.',
+'rcnote' => 'A continuació hi ha els darrers <strong>$1</strong> canvis en els darrers <strong>$2</strong> dies, com de $3.',
+'rcnotefrom' => 'A sota hi ha els canvis des de <b>$2</b> (es mostren fins <b>$1</b>).',
+'rclistfrom' => 'Mostra els canvis nous des de $1',
+'rcshowhideminor' => '$1 edicions menors',
+'rcshowhidebots' => '$1 bots',
+'rcshowhideliu' => '$1 usuaris identificats',
+'rcshowhideanons' => '$1 usuaris anònims',
+'rcshowhidepatr' => '$1 edicions patrullades',
+'rcshowhidemine' => '$1 edicions pròpies',
+'rclinks' => 'Mostra els darrers $1 canvis en els darrers $2 dies<br />$3',
+'diff' => 'dif',
+'hist' => 'hist',
+'hide' => 'amaga',
+'show' => 'mostra',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[Usuaris que vigilen aquesta pàgina: $1]',
+'rc_categories' => 'Limita a les categories (separades amb "|")',
+'rc_categories_any' => 'Qualsevol',
+'upload' => 'Carrega',
+'uploadbtn' => 'Carrega un arxiu',
+'reupload' => 'Carrega de nou',
+'reuploaddesc' => 'Torna al formulari per apujar.',
+'uploadnologin' => 'No heu iniciat una sessió',
+'uploadnologintext' => 'Heu d\'[[Special:Userlogin|iniciar una sessió]]
+per a penjar-hi fitxers.',
+'upload_directory_read_only'=> 'El servidor web no pot escriure el directori de càrrega ($1)',
+'uploaderror' => 'S\'ha produït un error en l\'intent de carregar',
+'uploadtext' => 'Per a visualitzar o cercar imatges que s\'hagin apujat anteriorment, aneu a la [[Special:Imagelist|llista de fitxers carregats]].
+Les càrregues i les supressions es registren en el [[Project:Registre de càrregues|registre de càrregues]].
+
+Consulteu també la [[Project:Política d\'ús d\'imatges|política d\'ús d\'imatges]].
+
+Empreu la forma de sota per a carregar nous fitxers d\'imatges per a il·lustrar els articles.
+Amb la majoria de navegadors, veureu un botó «Navega...», que
+farà aparèixer la selecció de fitxers estàndard en el vostre sistema operatiu.
+Quan trieu un fitxer, el nom d\'aqueix fitxer apareixerà en el camp de text
+al costat del botó.
+També heu d\'activar la casella afirmant que no esteu violant cap dret d\'autor en carregar el fitxer.
+Cliqueu el botó «Carrega» per a completar la càrrega.
+Això pot trigar una estona si teniu una connexió lenta a Internet.
+
+Els formats preferits són el JPEG, per a imatges fotogràfiques, el PNG,
+per a dibuixos i imatges d\'icones, i OGG per a sons.
+Seria convenient que donéssiu noms descriptius als fitxers per a evitar així confusions.
+Per a incloure una imatge en un article, feu un enllaç de la forma
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Fitxer.jpg]]</nowiki>
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Fitxer.png|alt text]]</nowiki>
+o per a sons
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Fitxer.ogg]]</nowiki>\'\'\'
+
+Tingueu en compte, que de la mateixa manera com passa amb les pàgines de la {{SITENAME}}, hom pot
+editar-hi o suprimir-hi els fitxers que hi heu carregat si pensen que és recomanable per al projecte. També se us pot blocar, impedint-vos doncs carregar fitxers si feu un abús del sistema.',
+'uploadlog' => 'registre de càrregues',
+'uploadlogpage' => 'Registre de càrregues',
+'uploadlogpagetext' => 'A sota hi ha un llistat dels fitxers que s\'han apujat més recentment.
+Totes les hores són les del servidor (UTC).',
+'filename' => 'Nom de fitxer',
+'filedesc' => 'Sumari',
+'fileuploadsummary' => 'Resum:',
+'filesource' => 'Font',
+'copyrightpage' => 'Project:Copyrights',
+'uploadedfiles' => 'Arxius carregats',
+'ignorewarning' => 'Ignora qualsevol avís i desa el fitxer igualment.',
+'ignorewarnings' => 'Ignora qualsevol avís',
+'minlength' => 'Els noms de les imatges han de tenir un mínim de tres lletres.',
+'badfilename' => 'El nom de la imatge s\'ha canviat a "$1".',
+'badfiletype' => '".$1" no és un format recomanat d\'imatge.',
+'successfulupload' => 'El fitxer s\'ha carregat amb èxit',
+'fileuploaded' => 'L\'arxiu "$1" s\'ha carregat amb èxit.
+Seguiu aquest enllaç si us plau: ($2) a la pàgina de descripció i empleneu
+la informació necesàir sobre l\'arxiu, tal com la procedència, la data de creació
+i l\'autor, i qualsevol altra cosa que pugueu saber al respecte.',
+'uploadwarning' => 'Advertència de càrrega d\'arxiu',
+'savefile' => 'Desa el fitxer',
+'uploadedimage' => '"[[$1]]" carregat.',
+'uploadvirus' => 'El fitxer conté un virus! Detalls: $1',
+'destfilename' => 'Nom del fitxer de destinació',
+'license' => 'Llicència',
+'nolicense' => 'No s\'ha seleccionat cap',
+'imagelist' => 'Llistat d\'imatges',
+'imagelisttext' => 'Llista {{plural:$1|d\'un arxiu|de \'\'\'$1\'\'\' arxius ordenats $2}}.',
+'getimagelist' => ' obtenint el llistat d\'imatges',
+'ilsubmit' => 'Cerca',
+'showlast' => 'Mostra les darreres $1 imatges ordenades $2.',
+'byname' => 'per nom',
+'bydate' => 'per data',
+'bysize' => 'per mida',
+'imgdelete' => 'edi',
+'imglegend' => 'Simbologia: (edi) = mostra/edita la descripció de la imatge.',
+'imghistory' => 'Història de la imatge',
+'deleteimg' => 'esb',
+'deleteimgcompletely' => 'Esborra totes les versions d\'aquest arxiu',
+'imghistlegend' => 'Simbologia: (act) = aquesta és la imatge actual, (esb) = esborra
+aquesta versió antiga, (rev) = reverteix a aquesta versió antiga.
+<br /><i>Cliqueu sobre la data per veure la imatge carregada en aquesta data</i>.',
+'imagelinks' => 'Enllaços a la imatge',
+'linkstoimage' => 'Les següents pàgines enllacen a aquesta imatge:',
+'nolinkstoimage' => 'No hi ha pàgines que enllacin aquesta imatge.',
+'sharedupload' => 'Aquest fitxer està compartit i pot ser emprat per altres projectes.',
+'noimage' => 'No existeix cap fitxer amb aquest nom, però podeu $1.',
+'noimage-linktext' => 'Carrega',
+'uploadnewversion-linktext'=> 'Carrega una nova versió d\'aquest arxiu',
+'mimesearch' => 'Cercar per MIME',
+'download' => 'descarrega',
+'unwatchedpages' => 'Pàgines desateses',
+'listredirects' => 'Llista de redireccions',
+'unusedtemplates' => 'Plantilles no usades',
+'unusedtemplatestext' => 'Aquesta pàgina mostra les pàgines en l\'espai de noms de plantilles, que no estan incloses en cap altra pàgina. Recordeu de comprovar les pàgines que hi enllacen abans d\'esborrar-les.',
+'unusedtemplateswlh' => 'altres enllaços',
+'randomredirect' => 'Redirecció a l\'atzar',
+'statistics' => 'Estadístiques',
+'sitestats' => 'Estadístiques del lloc',
+'userstats' => 'Estadístiques d\'usuari',
+'sitestatstext' => 'Hi ha un total de \'\'\'$1\'\'\' pàgines en la base de dades.
+Això inclou pàgines de discussió, pàgines sobre el projecte {{SITENAME}}, pàgines mínimes,
+redireccions, i altres que probablement no es poden classificar com a articles.
+Excloent-les, hi ha \'\'\'$2\'\'\' pàgines que probablement són articles legítims.
+
+S\'han penjat \'\'\'$8\'\'\' fitxers.
+
+Hi ha hagut un total de \'\'\'$3\'\'\' visites a pàgines, i \'\'\'$4\'\'\' edicions de pàgina
+des que el programari s\'ha configurat.
+Això resulta en un promig de \'\'\'$5\'\'\' edicions per pàgina,
+i \'\'\'$6\'\'\' visites per edició.
+
+La mida de la [http://meta.wikimedia.org/wiki/Help:Job_queue cua de treballs] és \'\'\'$7\'\'\'.',
+'userstatstext' => 'Hi ha \'\'\'$1\'\'\' usuaris registrats, dels quals
+\'\'\'$2\'\'\' (o \'\'\'$4%\'\'\') són administradors (vegeu $3).',
+'disambiguations' => 'Pàgines de desambiguació',
+'disambiguationspage' => 'Template:Desambiguació',
+'disambiguationstext' => 'Els següents articles enllacen a una<i>pàgina de desambiguació</i>. Haurien d\'enllaçar al tema apropiat.
+
+<br />Una pàgina és considerada una pàgina de desambiguació si és enllaçada des de $1.<br />Enllaços des d\'altres espais de nom (Com Viquipè
+
+dia: o usuari:) <i>no</i> són llistats ací.',
+'doubleredirects' => 'Redireccions Dobles',
+'doubleredirectstext' => '<b>Atenció:</b> aquest llistat pot contenir falsos positius. Això normalment significa que hi ha text
+
+addicional amb enllaços sota el primer #REDIRECT.<br />
+Cada fila conté enllaços al segon i tercer redireccionament, així com la primera línia del
+
+segon redireccionament, la qual cosa dóna normalment l\'article "real", al que el primer redireccionamet hauria d\'apuntar.',
+'brokenredirects' => 'Redireccions trencades',
+'nbytes' => '$1 {{PLURAL:$1|octet|octets}}',
+'ncategories' => '$1 {{PLURAL:$1|categoria|categories}}',
+'nlinks' => '$1 {{PLURAL:$1|enllaç|enllaços}}',
+'nmembers' => '$1 {{PLURAL:$1|membre|membres}}',
+'nrevisions' => '$1 {{PLURAL:$1|revisió|revisions}}',
+'nviews' => '$1 {{PLURAL:$1|visita|visites}}',
+'lonelypages' => 'Pàgines orfes',
+'uncategorizedpages' => 'Pàgines sense categoria',
+'uncategorizedcategories'=> 'Categories sense categoria',
+'uncategorizedimages' => 'Imatges sense categoria',
+'unusedcategories' => 'Categories sense articles',
+'unusedimages' => 'Imatges sense ús',
+'popularpages' => 'Pàgines populars',
+'wantedcategories' => 'Categories demanades',
+'wantedpages' => 'Pàgines demanades',
+'allpages' => 'Totes les pàgines',
+'prefixindex' => 'Cercar per prefix',
+'randompage' => 'Pàgina a l\'atzar',
+'shortpages' => 'Pàgines curtes',
+'longpages' => 'Pàgines llargues',
+'listusers' => 'Llistat d\'usuaris',
+'specialpages' => 'Pàgines especials',
+'spheading' => 'Pàgines especials',
+'recentchangeslinked' => 'Seguiment d\'enllaços',
+'rclsub' => '(a pàgines enllaçades des de "$1")',
+'newpages' => 'Pàgines noves',
+'move' => 'Reanomena',
+'movethispage' => 'Trasllada la pàgina',
+'unusedimagestext' => '<p>Noteu que altres llocs web poden enllaçar una imatge amb un URL directe i estar llistada aquí tot i estar en ús actiu.</p>',
+'booksources' => 'Fonts de llibres',
+'groups' => 'Grups d\'usuaris',
+'booksourcetext' => 'A continuació hi ha un llistat d\'enllaços a altres llocs que venen llibres nous i de segona mà, i que poden contenir informació addicional sobre els llibres que esteu cercant.
+El projecte {{SITENAME}} no està afiliat amb cap d\'aquests negocis, i aquest llistat no ha de ser considerat com propaganda.',
+'version' => 'Versió',
+'nextpage' => 'Següent pàgina ($1)',
+'allarticles' => 'Tots els articles',
+'allpagesprev' => 'Anterior',
+'allpagesnext' => 'Següent',
+'allpagesprefix' => 'Mostra les pàgines amb prefix:',
+'mailnologin' => 'No enviïs l\'adreça',
+'mailnologintext' => 'Heu d\'haver [[Special:Userlogin|entrat]]
+i tenir una adreça electrònica vàlida en les vostres [[Special:Preferences|preferències]]
+per enviar un correu electrònic a altres usuaris.',
+'emailuser' => 'Envia un missatge de correu electrònic a aquest usuari',
+'emailpage' => 'Correu electrònic a usuari',
+'emailpagetext' => 'Si aquest usuari ha entrat una adreça electrònica vàlida en les vostres preferències d\'usuari, el següent formulari
+
+serveix per enviar-li un missatge.
+L\'adreça electrònica que heu entrat en les vostres preferències d\'usuari apareixerà en el remitent, de manera que el destinatari pugui
+
+respondre.',
+'noemailtitle' => 'No hi ha cap adreça electrònica',
+'noemailtext' => 'Aquest usuari no ha especificat una adreça electrònica vàlida, o ha escollit no rebre correu electrònic d\'altres usuaris
+
+.',
+'emailfrom' => 'De',
+'emailto' => 'Per',
+'emailsubject' => 'Assumpte',
+'emailmessage' => 'Missatge',
+'emailsend' => 'Envia',
+'emailsent' => 'Correu electrònic enviat',
+'emailsenttext' => 'El vostre correu electrònic ha estat enviat.',
+'watchlist' => 'Llista de seguiment',
+'nowatchlist' => 'No teniu cap element en el vostre llistat de seguiment.',
+'watchnologin' => 'No heu iniciat sessió',
+'watchnologintext' => 'Heu d\'[[Special:Userlogin|entrar]]
+per modificar el vostre llistat de seguiment.',
+'addedwatch' => 'S\'ha afegit la pàgina a la llista de seguiment',
+'addedwatchtext' => 'S\'ha afegit la pàgina "$1" a la vostra <a href="{{localurle:Especial:Watchlist}}">llista de seguiment</a>.
+
+Els canvis futurs que tindran lloc en aquesta pàgina i la seua corresponent discussió s\'avisaran a la vostra <a href="{{localurle:Especial:Watchlist}}">llista de seguiment</a>, resaltant-se també <b>en negreta</b> en la <a href="{{localurle:Especial:Recentchanges}}">llista de canvis recents</a> per adonar-se\'n més fàcilment.</p>
+
+<p>Si voleu deixar de vigilar la pàgina, cliqueu sobre l\'enllaç de "Desatén" a la barra lateral.',
+'removedwatch' => 'S\'ha extret del llistat de seguiment',
+'removedwatchtext' => 'S\'ha tret la pàgina "[[:$1]]" de la vostra llista de seguiment.',
+'watch' => 'Vigila',
+'watchthispage' => 'Vigila aquesta pàgina',
+'unwatch' => 'Desatén',
+'unwatchthispage' => 'Desatén',
+'notanarticle' => 'No és un article',
+'wldone' => 'Fet.',
+'changed' => 'modificat',
+'enotif_body' => 'Benvolgut $WATCHINGUSERNAME,
+
+La pàgina $PAGETITLE del projecte {{SITENAME}} ha estat $CHANGEDORCREATED el dia $PAGEEDITDATE per $PAGEEDITOR, vegeu $PAGETITLE_URL per la versió actual.
+
+$NEWPAGE
+
+Resum ofert per l\'editor: $PAGESUMMARY $PAGEMINOREDIT
+
+Contacteu amb l\'editor:
+correu: $PAGEEDITOR_EMAIL
+pàgina d\'usuari: $PAGEEDITOR_WIKI
+
+No rebreu més notificacions de futurs canvis si no visiteu la pàgina. També podeu canviar el mode de notificació de les pàgines que vigileu en la vostra llista de seguiment.
+
+ El servei de notificació del projecte {{SITENAME}}
+
+--
+Per a canviar les opcions de la vostra llista de seguiment aneu a:
+{{fullurl:Special:Watchlist/edit}}
+
+Suggeriments i ajuda:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Esborra aquesta pàgina',
+'confirm' => 'Confirma',
+'exblank' => 'la pàgina estava en blanc',
+'confirmdelete' => 'Confirma l\'esborrat',
+'deletesub' => '(Esborrant "$1")',
+'confirmdeletetext' => 'Esteu a punt d\'esborrar una pàgina o imatge
+de forma permanent, així com tota la seva història de la base de dades.
+Confirmeu que realment ho voleu fer, que enteneu les
+conseqüències, i que el que esteu fent està d\'acord amb [[Project:Polítiques]].',
+'actioncomplete' => 'S\'ha realitzat l\'acció de manera satisfactòria.',
+'deletedtext' => '"$1" ha estat esborrat.
+Mostra $2 per a un registre dels esborrats més recents.',
+'deletedarticle' => 'esborrat "$1"',
+'dellogpage' => 'Registre_d\'esborrats',
+'dellogpagetext' => 'A sota hi ha un llistat dels esborrats més recents.
+Tots els temps es mostren en l\'hora del servidor (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'Registre d\'esborrats',
+'reverted' => 'Invertit amb una revisió anterior',
+'deletecomment' => 'Motiu per a ser esborrat',
+'imagereverted' => 'S\'ha revertit amb èxit a una versió anterior.',
+'rollback' => 'Reverteix edicions',
+'rollbacklink' => 'Reverteix',
+'cantrollback' => 'No s\'ha pogut revertir les edicions; el darrer col·laborador és l\'únic autor d\'aquest article.',
+'revertpage' => 'Revertides les edicions de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussió]]); s\'ha recuperat la darrera versió de [[User:$1|$1]]',
+'confirmprotecttext' => 'Voleu realment protegir aquesta pàgina?',
+'confirmprotect' => 'Confirmeu la protecció',
+'restriction-edit' => 'Edita',
+'undelete' => 'Restaura una pàgina esborrada',
+'undeletepage' => 'Mostra i restaura pàgines esborrades',
+'undeletepagetext' => 'Les següents pàgines han estat esborrades però encara són a l\'arxiu i poden ser restaurades. L\'arxiu pot ser netejat
+
+periòdicament.',
+'undeletearticle' => 'Restaura l\'article esborrat',
+'undeleterevisions' => '$1 revisions arxivades',
+'undeletehistory' => 'Si restaureu una pàgina, totes les revisions seran restaurades a la història.
+Si una nova pàgina amb el mateix nom ha estat creada des de l\'esborrat, les versions restaurades apareixeran com a història anterior, i la
+
+revisió actual del la pàgina "viva" no serà substituïda automàticament.',
+'undeleterevision' => 'Revisió esborrada al $1',
+'undeletebtn' => 'Restaura!',
+'undeletedarticle' => 'restaurat "$1"',
+'undeletedrevisions' => '$1 revisions restaurades',
+'namespace' => 'Espai de noms:',
+'contributions' => 'Contribucions de l\'usuari',
+'mycontris' => 'Contribucions',
+'contribsub' => 'Per $1',
+'nocontribs' => 'No s\'ha trobat canvis que encaixessin amb aquests criteris.',
+'ucnote' => 'A sota hi ha els darrers <b>$1</b> canvis d\'aquest usuari en els darrers <b>$2</b> dies.',
+'uclinks' => 'Mostra els darrers $1 canvis; mostra els darrers $2 dies.',
+'uctop' => ' (actual)',
+'newbies' => 'novells',
+'sp-newimages-showfrom' => 'Mostra imatges des de $1',
+'sp-contributions-newer'=> '$1 anteriors',
+'sp-contributions-older'=> '$1 següents',
+'sp-contributions-newbies-sub'=> 'Per a novells',
+'whatlinkshere' => 'El que enllaça ací',
+'notargettitle' => 'No hi ha pàgina en blanc',
+'notargettext' => 'No heu especificat a quina pàgina dur a terme aquesta funció.',
+'linklistsub' => '(Llista d\'enllaços)',
+'linkshere' => 'Les següents pàgines enllacen ací:',
+'nolinkshere' => 'Ací no enllaça cap pàgina.',
+'isredirect' => 'pàgina redirigida',
+'istemplate' => 'inclosa',
+'blockip' => 'Bloca l\'usuari',
+'blockiptext' => 'Empreu el següent formulari per blocar l\'accés
+d\'escriptura des d\'una adreça IP específica o des d\'un usuari determinat.
+això només s\'hauria de fer per prevenir el vandalisme, i
+d\'acord amb la [[Project:Política|política del projecte]].
+Empleneu el diàleg de sota amb un motiu específic (per exemple, citant
+quines pàgines en concret estan sent vandalitzades).',
+'ipaddress' => 'Adreça IP',
+'ipadressorusername' => 'Adreça IP o nom de l\'usuari',
+'ipbexpiry' => 'Caducitat',
+'ipbreason' => 'Motiu',
+'ipbsubmit' => 'Bloca aquesta adreça',
+'ipbother' => 'Un altre termini',
+'ipboptions' => '2 hores:2 hours,1 dia:1 day,3 dies:3 days,1 setmana:1 week,2 setmanes:2 weeks,1 mes:1 month,3 mesos:3 months,6 mesos:6 months,1 any:1 year,infinit:infinite',
+'ipbotheroption' => 'un altre',
+'badipaddress' => 'L\'adreça IP no té el format correcte.',
+'blockipsuccesssub' => 'S\'ha blocat amb èxit',
+'blockipsuccesstext' => 'L\'usuari "[[Special:Contributions/$1|$1]]" ha estat blocat.
+<br />Vegeu la [[Special:Ipblocklist|llista d\'IP blocades]] per revisar els bloquejos.',
+'unblockip' => 'Desbloca l\'usuari',
+'unblockiptext' => 'Empreu el següent formulari per restaurar
+l\'accés a l\'escriptura a una adreça IP o un usuari prèviament blocat.',
+'ipusubmit' => 'Desbloca aquesta adreça',
+'unblocked' => 'S\'ha desblocat l\'usuari [[User:$1|$1]]',
+'ipblocklist' => 'Llista d\'adreces IP i noms d\'usuaris blocats',
+'blocklistline' => '$1, $2 bloca $3 ($4)',
+'infiniteblock' => 'infinit',
+'expiringblock' => 'venç el $1',
+'ipblocklistempty' => 'La llista està buida.',
+'blocklink' => 'bloca',
+'unblocklink' => 'desbloca',
+'contribslink' => 'contribucions',
+'autoblocker' => 'Heu estat blocat perquè compartiu adreça IP amb "$1". Motiu: "$2"',
+'blocklogpage' => 'Registre de blocatges',
+'blocklogentry' => 's\'ha blocat "[[$1]]" per a un període de $2',
+'blocklogtext' => 'Això és una relació d\'accions de blocatge i desblocatge. Les adreces IP blocades automàticament no apareixen. Vegeu la [[Special:Ipblocklist|llista d\'usuaris actualment blocats]].',
+'unblocklogentry' => 'desblocat $1',
+'range_block_disabled' => 'La facultat dels administradors per crear blocatges de rang està desactivada.',
+'ipb_expiry_invalid' => 'Data d\'acabament no vàlida.',
+'ip_range_invalid' => 'Rang d\'IP no vàlid.',
+'proxyblockreason' => 'La vostra adreça IP ha estat blocada perquè és un proxy obert. Si us plau contactau el vostre proveïdor d\'Internet o servei tècnic i informau-los d\'aquest seriós problema de seguretat.',
+'proxyblocksuccess' => 'Fet.',
+'lockdb' => 'Bloca la base de dades',
+'unlockdb' => 'Desbloca la base de dades',
+'lockdbtext' => 'Blocant la base de dades s\'anul·larà la capacitat de tots els
+usuaris d\'editar pàgines, canviar les preferències, editar els llistats de seguiments, i
+altres canvis que requereixen canvis en la base de dades.
+Confirmeu que això és el que intenteu fer, i sobretot no us oblideu
+de desblocar la base de dades quan acabeu el manteniment.',
+'unlockdbtext' => 'Desblocant la base de dades es restaurarà l\'habilitat de tots
+els usuaris d\'editar pàgines, canviar les preferències, editar els llistats de seguiment, i
+altres accions que requereixen canvis en la base de dades.
+Confirmeu que això és el que voleu fer.',
+'lockconfirm' => 'Sí, realment vull blocar la base de dades.',
+'unlockconfirm' => 'Sí, realment vull desblocar la base dades.',
+'lockbtn' => 'Bloca la base de dades',
+'unlockbtn' => 'Desbloca la base de dades',
+'locknoconfirm' => 'No heu respost al diàleg de confirmació.',
+'lockdbsuccesssub' => 'S\'ha blocat la base de dades',
+'unlockdbsuccesssub' => 'S\'ha eliminat el blocatge de la base de dades',
+'lockdbsuccesstext' => 'S\'ha blocat la base de dades del projecte {{SITENAME}}.
+<br />Recordeu-vos de treure el blocatge quan hàgiu acabat el manteniment.',
+'unlockdbsuccesstext' => 'S\'ha desblocat la base de dades del projecte {{SITENAME}}.',
+'makesysoptitle' => 'Converteix en administrador',
+'makesysoptext' => 'Aquest formulari serveix per a que els buròcrates puguin convertir un usuari en administrador.
+Escrigueu el nom de l\'usuari i premeu el botó per acceptar-ho.',
+'makesysopname' => 'Nom de l\'usuari:',
+'makesysopsubmit' => 'Converteix aquest usuari en administrador',
+'makesysopok' => '<b>L\'usuari "$1" és un administrador a partir d\'ara</b>',
+'rights' => 'Permisos:',
+'already_sysop' => 'Aquest usuari ja és un administrador',
+'rightsnone' => '(cap)',
+'movepage' => 'Reanomena la pàgina',
+'movepagetext' => 'Emprant el següent formulari reanomenareu una pàgina,
+movent tota la seva història al nou nom.
+El títol anterior es convertirà en un redireccionament al nou títol.
+Els enllaços a l\'antic títol de la pàgina no es canviaran. Assegureu-vos-en de verificar que no deixeu redireccions
+
+dobles o trencades.
+Sou el responsable de fer que els enllaços segueixin apuntant on se suposa que ho facin.
+
+Noteu que la pàgina \'\'\'no\'\'\' serà traslladada si ja existeix una pàgina amb el títol nou, a no ser que sigui una pàgina buida o un
+
+\'\'redireccionament\'\' sense història.
+Això significa que podeu reanomenar de nou una pàgina al seu títol original si cometeu un error, i que no podeu sobreescriure una pàgina
+
+existent.
+
+<b>ADVERTÈNCIA!</b>
+Això pot ser un canvi dràstic i inesperat per una pàgina popular;
+assegureu-vos-en d\'entendre les conseqüències que comporta
+abans de seguir endavant.',
+'movepagetalktext' => 'La pàgina de discussió associada, si existeix, serà traslladada automàticament \'\'\'a menys que:\'\'\'
+*Ja existeixi una pàgina de discussió no buida amb el nom nou, o
+*Hàgiu desseleccionat l\'opció de sota.
+
+En aquests casos, haureu de traslladar o fusionar la pàgina manualment si ho desitgeu.',
+'movearticle' => 'Reanomena la pàgina',
+'movenologin' => 'No sou a dins d\'una sessió',
+'movenologintext' => 'Heu de ser un usuari registrat i estar [[Special:Userlogin|dintre d\'una sessió]]
+per reanomenar una pàgina.',
+'newtitle' => 'A títol nou',
+'movepagebtn' => 'Reanomena la pàgina',
+'pagemovedsub' => 'Reanomenament amb èxit',
+'pagemovedtext' => 'Pàgina "[[$1]]" reanomenada a "[[$2]]".',
+'articleexists' => 'Ja existeix una pàgina amb aquest nom, o el nom que heu
+escollit no és vàlid.
+Escolliu un altre nom, si us plau.',
+'talkexists' => 'S\'ha reanomenat la pàgina amb èxit, però la pàgina de discussió no s\'ha pogut moure car ja no existeix en el títol nou.
+
+Incorporeu-les manualment, si us plau.',
+'movedto' => 'reanomenat a',
+'movetalk' => 'Reanomena també la pàgina de discussió si és aplicable.',
+'talkpagemoved' => 'També ha estat reanomenada la pàgina de discussió corresponent.',
+'talkpagenotmoved' => 'La pàgina de discussió corresponent <strong>no</strong> ha estat reanomenada.',
+'1movedto2' => '[[$1]] mogut a [[$2]]',
+'1movedto2_redir' => '[[$1]] mogut a [[$2]] per redirecció',
+'movelogpage' => 'Registre de reanomenaments',
+'movereason' => 'Motiu',
+'revertmove' => 'revertir',
+'delete_and_move' => 'Esborra i trasllada',
+'delete_and_move_text' => '==Cal esborrar==
+
+L\'article de destí, "[[$1]]", ja existeix. Voleu esborrar-lo per fer lloc per al trasllat?',
+'delete_and_move_confirm'=> 'Sí, esborra la pàgina',
+'export-submit' => 'Exporta',
+'allmessages' => 'Tots els missatges del sistema',
+'allmessagesname' => 'Etiqueta',
+'allmessagesdefault' => 'Text per defecte',
+'allmessagescurrent' => 'Text actual',
+'allmessagestext' => 'Tot seguit hi és una llista dels missatges del sistema que es troben a l\'espai de noms de \'\'MediaWiki\'\'.',
+'allmessagesnotsupportedUI'=> 'La llengua de la vostra interfície actual, <strong>$1</strong>, no es troba implementada en els Special:Allmessages d\'aquest lloc.',
+'allmessagesfilter' => 'Cerca etiqueta de missatge:',
+'allmessagesmodified' => 'Mostra només missatges modificats',
+'import' => 'Importa les pàgines',
+'importfailed' => 'La importació ha fallat: $1',
+'importsuccess' => 'S\'ha importat amb èxit!',
+'importnofile' => 'No s\'ha apujat cap fitxer d\'importació.',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'Cerca en el projecte {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Marca-ho com una edició menor [alt-i]',
+'tooltip-save' => 'Desa els vostres canvis [alt-s]',
+'tooltip-diff' => 'Mostra quins canvis heu fet al text. [alt-v]',
+'common.css' => '/* Editeu aquest fitxer per personalitzar totes les aparences per al lloc sencer */',
+'monobook.css' => '/* Editeu aquest fitxer per personalitzar l\'aparença del monobook per a tot el lloc sencer */',
+'notacceptable' => 'El servidor wiki no pot oferir dades en un format que el client no pot llegir.',
+'anonymous' => 'Usuaris anònims del projecte {{SITENAME}}',
+'lastmodifiedatby' => 'Va modificar-se la pàgina per darrera vegada el $2, $1 per $3.',
+'and' => 'i',
+'others' => 'altres',
+'subcategorycount' => 'Hi ha {{PLURAL:$1|una subcategoria|$1 subcategories}} dins d\'aquesta categoria.',
+'categoryarticlecount' => 'Hi ha {{PLURAL:$1|un article|$1 articles}} en aquesta categoria.',
+'infosubtitle' => 'Informació de la pàgina',
+'mw_math_png' => 'Produeix sempre PNG',
+'mw_math_simple' => 'HTML si és molt simple, si no PNG',
+'mw_math_html' => 'HTML si és possible, si no PNG',
+'mw_math_source' => 'Deixa com a TeX (per a navegadors de text)',
+'mw_math_modern' => 'Recomanat per navegadors moderns',
+'markaspatrolleddiff' => 'Marca com a vigilat',
+'markaspatrolledtext' => 'Marca l\'article com a vigilat',
+'markedaspatrolled' => 'Marca com a vigilat',
+'markedaspatrollederror'=> 'No es pot marcar com a vigilat',
+'markedaspatrollederrortext'=> 'Cal que especifiqueu una revisió per a marcar-la com a vigilada.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'La vostra pàgina d\'usuari.\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'La pàgina d\'usuari per la ip que utilitzeu\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'La vostra pàgina de discussió.\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussió sobre les edicions per aquesta adreça ip.\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Les vostres preferències.\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'La llista de pàgines de les que estau vigilant els canvis.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Llista de les vostres contribucions.\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Us animem a registrar-vos, però no és obligatori.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Us animem a registrar-vos, però no és obligatori.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Finalitza la sessió d\'usuari\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Discussió sobre el contingut d\'aquesta pàgina.\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Podeu editar aquesta pàgina. Si us plau, previsualitzeu abans de desar.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Afegeix un comentari a aquesta discussió.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Aquesta pàgina està protegida. Podeu veure el seu codi font.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Versions antigues d\'aquesta pàgina.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Protegeix aquesta pàgina.\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Esborra aquesta pàgina.\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Restaura les edicions fetes a aquesta pàgina abans de que fos esborrada.\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Reanomena aquesta pàgina.\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Afegiu aquesta pàgina a la vostra llista de seguiment.\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Llevau aquesta pàgina de la vostra llista de seguiment.\');
+ ta[\'search\'] = new Array(\'f\',\'Cerca aquesta viqui.\');
+ ta[\'p-logo\'] = new Array(\'\',\'Pàgina principal\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Visiteu la pàgina principal.\');
+ ta[\'n-portal\'] = new Array(\'\',\'Sobre el projecte, què podeu fer, on podeu trobar coses.\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Per trobar informació general sobre l\'actualitat.\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'La llista de canvis recents a la wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Vés a una pàgina aleatòria.\');
+ ta[\'n-help\'] = new Array(\'\',\'El lloc per esbrinar.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Feu-nos una donació.\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Llista de totes les pàgines viqui que enllacen ací.\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Canvis recents a pàgines que enllacen amb aquesta pàgina.\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed for this page\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed for this page\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Vegeu la llista de contribucions d\'aquest usuari.\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Envia un correu en aquest usuari.\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Càrrega d\'imatges o altres fitxers.\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Llista de totes les pàgines especials.\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vegeu el contingut de la pàgina.\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vegeu la pàgina de l\'usuari.\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'View the media page\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Aquesta pàgina és una pàgina especial, no podeu editar-la.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'View the project page\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'View the image page\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vegeu el missatge de sistema.\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vegeu la plantilla.\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vegeu la pàgina d\'ajuda.\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vegeu la pàgina de la categoria.\');',
+'previousdiff' => '← Ves a la diferència prèvia',
+'nextdiff' => 'Vés a la pròxima diferència →',
+'imagemaxsize' => 'Limita les imatges de les pàgines de descripció d\'imatges a:',
+'thumbsize' => 'Mida de la miniatura:',
+'showbigimage' => 'Abaixa la versió d\'alta resolució ($1x$2, $3 kB)',
+'newimages' => 'Galeria de nous fitxers',
+'noimages' => 'Res per veure.',
+'specialloguserlabel' => 'Usuari:',
+'speciallogtitlelabel' => 'Títol:',
+'passwordtooshort' => 'La contrasenya és massa curta. Com ha mínim ha de tenir $1 caràcters.',
+'metadata' => 'Metadades',
+'metadata-expand' => 'Mostra els detalls estesos',
+'metadata-collapse' => 'Amaga els detalls estesos',
+'exif-imagewidth' => 'Amplada',
+'exif-imagelength' => 'Alçada',
+'exif-xresolution' => 'Resolució horitzontal',
+'exif-yresolution' => 'Resolució vertical',
+'exif-stripoffsets' => 'Ubicació de les dades de la imatge',
+'exif-transferfunction' => 'Funció de transferència',
+'exif-imagedescription' => 'Títol de la imatge',
+'exif-model' => 'Model de càmera',
+'exif-software' => 'Programari utilitzat',
+'exif-artist' => 'Autor',
+'exif-exposuretime' => 'Temps d\'exposició',
+'exif-aperturevalue' => 'Obertura',
+'exif-filesource' => 'Font del fitxer',
+'exif-scenetype' => 'Tipus d\'escena',
+'exif-contrast' => 'Contrast',
+'exif-saturation' => 'Saturació',
+'exif-gpslatitude' => 'Latitud',
+'exif-gpslongitude' => 'Longitud',
+'exif-componentsconfiguration-0'=> 'no existeix',
+'exif-exposureprogram-2'=> 'Programa normal',
+'exif-meteringmode-5' => 'Patró',
+'exif-focalplaneresolutionunit-2'=> 'polzades',
+'exif-sensingmethod-1' => 'Indefinit',
+'exif-customrendered-0' => 'Procés normal',
+'exif-scenecapturetype-0'=> 'Estàndard',
+'exif-scenecapturetype-1'=> 'Paisatge',
+'exif-scenecapturetype-2'=> 'Retrat',
+'exif-scenecapturetype-3'=> 'Escena nocturna',
+'exif-gpslatitude-n' => 'Latitud nord',
+'exif-gpsspeed-k' => 'Quilòmetres per hora',
+'exif-gpsspeed-m' => 'Milles per hora',
+'edit-externally' => 'Edita aquest fitxer fent servir una aplicació externa',
+'edit-externally-help' => 'Vegeu les [http://meta.wikimedia.org/wiki/Help:External_editors instruccions de configuració] per a més informació.',
+'recentchangesall' => 'tots',
+'watchlistall1' => 'totes',
+'watchlistall2' => 'totes',
+'namespacesall' => 'tots',
+'confirmemail' => 'Confirma l\'adreça de correu electrònic',
+'confirmemail_text' => 'El programari del sistema necessita que valideu la vostra adreça de correu
+electrònic per a poder gaudir d\'algunes facilitats. Cliqueu el botó inferior
+per enviar un codi de confirmació a la vostra adreça. Seguiu l\'enllaç que
+hi haurà al missatge enviat per a confirmar que el vostre correu és correcte.',
+'confirmemail_send' => 'Envia per correu electrònic un codi de confirmació',
+'confirmemail_sent' => 'S\'ha enviat un missatge de confirmació.',
+'confirmemail_sendfailed'=> 'No s\'ha pogut enviar un missatge de confirmació. Comproveu que l\'adreça no tingui caràcters no vàlids.',
+'confirmemail_invalid' => 'El codi de confirmació no és vàlid. Aquest podria haver vençut.',
+'confirmemail_needlogin'=> 'Necessiteu $1 per a confirmar la vostra adreça electrònica.',
+'confirmemail_success' => 'S\'ha confirmat la vostra adreça electrònica. Ara podeu iniciar una sessió i gaudir del wiki.',
+'confirmemail_loggedin' => 'Ja s\'ha confirmat la vostra adreça electrònica.',
+'confirmemail_error' => 'Quelcom ha fallat en desar la vostra confirmació.',
+'confirmemail_subject' => 'Confirmació de l\'adreça electrònica del projecte {{SITENAME}}',
+'confirmemail_body' => 'Algú, segurament vós, ha registrat el compte "$2" al projecte {{SITENAME}}
+amb aquesta adreça de correu des de l\'adreça IP $1.
+
+Per a confirmar que aquest correu electrònic us pertany realment
+i així activar les opcions de correu del programari, seguiu aquest enllaç:
+
+$3
+
+Si \'\'\'no\'\'\' heu estat vós, no el cliqueu. Aquest codi de confirmació
+caducarà a $4.',
+'tryexact' => 'Prova una coincidència exacta',
+'createarticle' => 'Crea un article',
+'scarytranscludetoolong'=> '[L\'URL és massa llarg; ho sento]',
+'trackbacklink' => 'Referència',
+'deletedwhileediting' => 'Avís: S\'ha suprimit aquesta pàgina abans que haguéssiu començat a editar-la!',
+'confirmrecreate' => 'L\'usuari [[User:$1|$1]] ([[User talk:$1|discussió]]) va esborrar aquesta pàgina que havíeu creat donant -ne el següent motiu:
+: \'\'$2\'\'
+Confirmeu que realment voleu tornar-la a crear.',
+'recreate' => 'Recrea',
+'tooltip-recreate' => 'Recrea la pàgina malgrat hagi estat suprimida',
+'unit-pixel' => 'px',
+'redirectingto' => 'S\'està redirigint a [[$1]]...',
+'confirm_purge' => 'Voleu buidar la memòria cau d\'aquesta pàgina?
+
+$1',
+'confirm_purge_button' => 'D\'acord',
+'youhavenewmessagesmulti'=> 'Teniu nous missatges a $1',
+'searchcontaining' => 'Cerca articles que continguin \'\'$1\'\'.',
+'searchnamed' => 'Cerca els articles que s\'anomenin \'\'$1\'\'.',
+'articletitles' => 'Articles que comencen amb \'\'$1\'\'',
+'hideresults' => 'Amaga els resultats',
+'displaytitle' => '(Enllaça a aquesta pàgina com [[$1]])',
+'loginlanguagelabel' => 'Llengua: $1',
+);
+?>
diff --git a/languages/messages/MessagesCe.php b/languages/messages/MessagesCe.php
new file mode 100644
index 000000000000..6c3519cf95e8
--- /dev/null
+++ b/languages/messages/MessagesCe.php
@@ -0,0 +1,9 @@
+<?php
+/** Chechen (Нохчийн)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'ru';
+?>
diff --git a/languages/messages/MessagesCs.php b/languages/messages/MessagesCs.php
new file mode 100644
index 000000000000..7df3066156e6
--- /dev/null
+++ b/languages/messages/MessagesCs.php
@@ -0,0 +1,2081 @@
+<?php
+/** Czech (česky)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback8bitEncoding = 'cp1250';
+
+$namespaceNames = array(
+ NS_MEDIA => 'Média',
+ NS_SPECIAL => 'Speciální',
+ NS_MAIN => '',
+ NS_TALK => 'Diskuse',
+ NS_USER => 'Uživatel',
+ NS_USER_TALK => 'Uživatel_diskuse',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_diskuse',
+ NS_IMAGE => 'Soubor',
+ NS_IMAGE_TALK => 'Soubor_diskuse',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_diskuse',
+ NS_TEMPLATE => 'Šablona',
+ NS_TEMPLATE_TALK => 'Šablona_diskuse',
+ NS_HELP => 'Nápověda',
+ NS_HELP_TALK => 'Nápověda_diskuse',
+ NS_CATEGORY => 'Kategorie',
+ NS_CATEGORY_TALK => 'Kategorie_diskuse',
+);
+
+$quickbarSettings = array(
+ 'Žádný', 'Leží vlevo', 'Leží vpravo', 'Visí vlevo'
+);
+
+$skinNames = array(
+ 'standard' => 'Standard',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Kolínská modř',
+ 'chick' => 'Kuře'
+);
+
+# Hledání knihy podle ISBN
+# $wgBookstoreListCs = ..
+$bookstoreList = array(
+ 'Národní knihovna' => 'http://sigma.nkp.cz/F/?func=find-a&find_code=ISN&request=$1',
+ 'Státní technická knihovna' => 'http://www.stk.cz/cgi-bin/dflex/CZE/STK/BROWSE?A=01&V=$1',
+ 'inherit' => true,
+);
+
+# Note to translators:
+# Please include the English words as synonyms. This allows people
+# from other wikis to contribute more easily.
+#
+$magicWords = array(
+## ID CASE SYNONYMS
+ 'redirect' => array( 0, '#REDIRECT', '#PŘESMĚRUJ' ),
+ 'notoc' => array( 0, '__NOTOC__', '__BEZOBSAHU__' ),
+ 'nogallery' => array( 0, '__NOGALLERY__', '__BEZGALERIE__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__VŽDYOBSAH__' ),
+ 'toc' => array( 0, '__TOC__', '__OBSAH__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__BEZEDITOVATČÁST__' ),
+ 'start' => array( 0, '__START__', '__ZAČÁTEK__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'AKTUÁLNÍMĚSÍC' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'AKTUÁLNÍMĚSÍCJMÉNO' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'AKTUÁLNÍMĚSÍCGEN' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'AKTUÁLNÍMĚSÍCZKR' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'AKTUÁLNÍDEN' ),
+ 'currentday2' => array( 1, 'CURRENTDAY2', 'AKTUÁLNÍDEN2' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'AKTUÁLNÍDENJMÉNO' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'AKTUÁLNÍROK' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'AKTUÁLNÍČAS' ),
+ 'currenthour' => array( 1, 'CURRENTHOUR', 'AKTUÁLNÍHODINA' ),
+ 'localmonth' => array( 1, 'LOCALMONTH', 'MÍSTNÍMĚSÍC' ),
+ 'localmonthname' => array( 1, 'LOCALMONTHNAME', 'MÍSTNÍMĚSÍCJMÉNO' ),
+ 'localmonthnamegen' => array( 1, 'LOCALMONTHNAMEGEN','MÍSTNÍMĚSÍCGEN' ),
+ 'localmonthabbrev' => array( 1, 'LOCALMONTHABBREV', 'MÍSTNÍMĚSÍCZKR' ),
+ 'localday' => array( 1, 'LOCALDAY', 'MÍSTNÍDEN' ),
+ 'localday2' => array( 1, 'LOCALDAY2', 'MÍSTNÍDEN2' ),
+ 'localdayname' => array( 1, 'LOCALDAYNAME', 'MÍSTNÍDENJMÉNO' ),
+ 'localyear' => array( 1, 'LOCALYEAR', 'MÍSTNÍROK' ),
+ 'localtime' => array( 1, 'LOCALTIME', 'MÍSTNÍČAS' ),
+ 'localhour' => array( 1, 'LOCALHOUR', 'MÍSTNÍHODINA' ),
+ 'numberofpages' => array( 1, 'NUMBEROFPAGES', 'POČETSTRAN' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'POČETČLÁNKŮ' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'POČETSOUBORŮ' ),
+ 'numberofusers' => array( 1, 'NUMBEROFUSERS', 'POČETUŽIVATELŮ' ),
+ 'pagename' => array( 1, 'PAGENAME', 'NÁZEVSTRANY' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'NÁZEVSTRANYE' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'JMENNÝPROSTOR' ),
+ 'namespacee' => array( 1, 'NAMESPACEE', 'JMENNÝPROSTORE' ),
+ 'talkspace' => array( 1, 'TALKSPACE', 'DISKUSNÍPROSTOR' ),
+ 'talkspacee' => array( 1, 'TALKSPACEE', 'DISKUSNÍPROSTORE' ),
+ 'subjectspace' => array( 1, 'SUBJECTSPACE', 'ARTICLESPACE', 'ČLÁNEKPROSTOR' ),
+ 'subjectspacee' => array( 1, 'SUBJECTSPACEE', 'ARTICLESPACEE', 'ČLÁNEKPROSTORE' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'PLNÝNÁZEVSTRANY' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE', 'PLNÝNÁZEVSTRANYE' ),
+ 'subpagename' => array( 1, 'SUBPAGENAME', 'NÁZEVPODSTRANY' ),
+ 'subpagenamee' => array( 1, 'SUBPAGENAMEE', 'NÁZEVPODSTRANYE' ),
+ 'basepagename' => array( 1, 'BASEPAGENAME', 'NÁZEVNADSTRANY' ),
+ 'basepagenamee' => array( 1, 'BASEPAGENAMEE', 'NÁZEVNADSTRANYE' ),
+ 'talkpagename' => array( 1, 'TALKPAGENAME', 'NÁZEVDISKUSE' ),
+ 'talkpagenamee' => array( 1, 'TALKPAGENAMEE', 'NÁZEVDISKUSEE' ),
+ 'subjectpagename' => array( 1, 'SUBJECTPAGENAME', 'ARTICLEPAGENAME', 'NÁZEVČLÁNKU' ),
+ 'subjectpagenamee' => array( 1, 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE', 'NÁZEVČLÁNKUE' ),
+ 'msg' => array( 0, 'MSG:' ),
+ 'subst' => array( 0, 'SUBST:', 'VLOŽIT:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'VLOŽITNW:' ),
+ 'end' => array( 0, '__END__', '__KONEC__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'náhled' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'náhled=$1' ),
+ 'img_right' => array( 1, 'right', 'vpravo' ),
+ 'img_left' => array( 1, 'left', 'vlevo' ),
+ 'img_none' => array( 1, 'none', 'žádné' ),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre', 'střed' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'rám' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'NÁZEVSERVERU' ),
+ 'ns' => array( 0, 'NS:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'MÍSTNÍURL:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'MÍSTNÍURLE:' ),
+ 'server' => array( 0, 'SERVER' ),
+ 'servername' => array( 0, 'SERVERNAME', 'JMÉNOSERVERU' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'SKLOŇUJ:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', '__BEZKONVERZENADPISU__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', '__BEZKONVERZEOBSAHU__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'AKTUÁLNÍTÝDEN' ),
+ 'currentdow' => array( 1, 'CURRENTDOW', 'AKTUÁLNÍDENTÝDNE' ),
+ 'localweek' => array( 1, 'LOCALWEEK', 'MÍSTNÍTÝDEN' ),
+ 'localdow' => array( 1, 'LOCALDOW', 'MÍSTNÍDENTÝDNE' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'IDREVIZE' ),
+ 'revisionday' => array( 1, 'REVISIONDAY', 'DENREVIZE' ),
+ 'revisionday2' => array( 1, 'REVISIONDAY2', 'DENREVIZE2' ),
+ 'revisionmonth' => array( 1, 'REVISIONMONTH', 'MĚSÍCREVIZE' ),
+ 'revisionyear' => array( 1, 'REVISIONYEAR', 'ROKREVIZE' ),
+ 'revisiontimestamp' => array( 1, 'REVISIONTIMESTAMP','KÓDČASUREVIZE' ),
+ 'plural' => array( 0, 'PLURAL:', 'PLURÁL:' ),
+ 'fullurl' => array( 0, 'FULLURL:', 'PLNÉURL:' ),
+ 'fullurle' => array( 0, 'FULLURLE:', 'PLNÉURLE:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:', 'PRVNÍMALÉ:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:', 'PRVNÍVELKÉ:' ),
+ 'lc' => array( 0, 'LC:', 'MALÁ:' ),
+ 'uc' => array( 0, 'UC:', 'VELKÁ:' ),
+ 'raw' => array( 0, 'RAW:' ),
+ 'displaytitle' => array( 1, 'DISPLAYTITLE', 'ZOBRAZOVANÝNADPIS' ),
+ 'rawsuffix' => array( 1, 'R' ),
+ 'newsectionlink' => array( 1, '__NEWSECTIONLINK__', '__LINKPŘIDATKOMENTÁŘ__' ),
+ 'currentversion' => array( 1, 'CURRENTVERSION', 'VERZESOFTWARE' ),
+ 'urlencode' => array( 0, 'URLENCODE:' ),
+ 'anchorencode' => array( 0, 'ANCHORENCODE' ),
+ 'currenttimestamp' => array( 1, 'CURRENTTIMESTAMP', 'AKTUÁLNÍKÓDČASU' ),
+ 'localtimestamp' => array( 1, 'LOCALTIMESTAMP', 'MÍSTNÍKÓDČASU' ),
+ 'directionmark' => array( 1, 'DIRECTIONMARK', 'DIRMARK' ),
+ 'language' => array( 0, '#LANGUAGE:', '#JAZYK:' ),
+ 'contentlanguage' => array( 1, 'CONTENTLANGUAGE', 'CONTENTLANG', 'JAZYKOBSAHU' ),
+ 'pagesinnamespace' => array( 1, 'PAGESINNAMESPACE:', 'PAGESINNS:', 'STRÁNEKVEJMENNÉMPROSTORU:' ),
+ 'numberofadmins' => array( 1, 'NUMBEROFADMINS', 'POČETSPRÁVCŮ' ),
+ 'formatnum' => array( 0, 'FORMATNUM', 'FORMÁTUJČÍSLO' ),
+ 'padleft' => array( 0, 'PADLEFT', 'ZAROVNATVLEVO' ),
+ 'padright' => array( 0, 'PADRIGHT', 'ZAROVNATVPRAVO' ),
+);
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+
+# Písmena, která se mají objevit jako část odkazu ve formě '[[jazyk]]y' atd:
+$linkTrail = '/^([a-záčďéěíňóřšťúůýž]+)(.*)$/sDu';
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. n. Y',
+ 'dmy both' => 'H:i, j. n. Y',
+);
+
+$messages = array(
+
+# Části textu používané různými stránkami:
+'categories' => 'Kategorie',
+'pagecategories' => 'Kategorie',
+'category_header' => 'Články v kategorii „$1“',
+'subcategories' => 'Podkategorie',
+
+# Dates
+'sunday' => 'neděle',
+'monday' => 'pondělí',
+'tuesday' => 'úterý',
+'wednesday' => 'středa',
+'thursday' => 'čtvrtek',
+'friday' => 'pátek',
+'saturday' => 'sobota',
+
+'sun' => 'ne',
+'mon' => 'po',
+'tue' => 'út',
+'wed' => 'st',
+'thu' => 'čt',
+'fri' => 'pá',
+'sat' => 'so',
+
+'january' => 'leden',
+'february' => 'únor',
+'march' => 'březen',
+'april' => 'duben',
+'may_long' => 'květen',
+'june' => 'červen',
+'july' => 'červenec',
+'august' => 'srpen',
+'september' => 'září',
+'october' => 'říjen',
+'november' => 'listopad',
+'december' => 'prosinec',
+
+# genitive month names (see LanguageCs::getMonthNameGen)
+'january-gen' => 'ledna',
+'february-gen' => 'února',
+'march-gen' => 'března',
+'april-gen' => 'dubna',
+'may-gen' => 'května',
+'june-gen' => 'června',
+'july-gen' => 'července',
+'august-gen' => 'srpna',
+'september-gen' => 'září',
+'october-gen' => 'října',
+'november-gen' => 'listopadu',
+'december-gen' => 'prosince',
+
+'jan' => '1.',
+'feb' => '2.',
+'mar' => '3.',
+'apr' => '4.',
+'may' => '5.',
+'jun' => '6.',
+'jul' => '7.',
+'aug' => '8.',
+'sep' => '9.',
+'oct' => '10.',
+'nov' => '11.',
+'dec' => '12.',
+
+'mainpage' => 'Hlavní strana',
+'mainpagetext' => 'Wiki software úspěšně nainstalován.',
+'mainpagedocfooter' => 'Podívejte se prosím do [http://meta.wikimedia.org/wiki/Help:Contents uživatelské příručky] pro nápovědu k použití a nastavení.',
+'portal' => 'Portál {{grammar:2sg|{{SITENAME}}}}',
+'portal-url' => 'Project:Portál {{grammar:2sg|{{SITENAME}}}}',
+'about' => 'Úvod',
+'aboutsite' => 'O&nbsp;{{grammar:6sg|{{SITENAME}}}}',
+'aboutpage' => 'Project:{{SITENAME}}',
+'article' => 'Obsahová stránka',
+'help' => 'Nápověda',
+'helppage' => 'Help:Obsah',
+'bugreports' => 'Hlášení chyb',
+'bugreportspage' => 'Project:Chyby',
+'sitesupport' => 'Sponzorství',
+'sitesupport-url' => 'Project:Sponzorství',
+'faq' => 'Často kladené otázky',
+'faqpage' => 'Project:Často kladené otázky',
+'edithelp' => 'Pomoc při editování',
+'newwindow' => '(otevře se v novém okně)',
+'edithelppage' => 'Help:Jak editovat stránku',
+'cancel' => 'Storno',
+'qbfind' => 'Hledání',
+'qbbrowse' => 'Listování',
+'qbedit' => 'Editování',
+'qbpageoptions' => 'Tato stránka',
+'qbpageinfo' => 'Kontext',
+'qbmyoptions' => 'Moje volby',
+'qbspecialpages' => 'Speciální stránky',
+'moredotdotdot' => 'Další…',
+'mypage' => 'Moje stránka',
+'mytalk' => 'Moje diskuse',
+'anontalk' => 'Diskuse k této IP adrese',
+
+'navigation' => 'Navigace',
+
+'currentevents' => 'Aktuality',
+'currentevents-url' => 'Aktuality',
+
+'disclaimers' => 'Vyloučení odpovědnosti',
+'disclaimerpage' => 'Project:Vyloučení odpovědnosti',
+'privacy' => 'Ochrana osobních údajů',
+'privacypage' => 'Project:Ochrana osobních údajů',
+'errorpagetitle' => 'Chyba',
+'returnto' => 'Návrat na stránku „$1“.',
+'tagline' => 'Z {{grammar:2sg|{{SITENAME}}}}',
+'help' => 'Nápověda',
+'search' => 'Hledat',
+'searchbutton' => 'Hledat',
+'go' => 'Jít na', #FIXME
+'searcharticle' => 'Jít na', #FIXME
+'history' => 'Historie stránky',
+'history_short' => 'Historie',
+'updatedmarker' => 'změněno od poslední návštěvy',
+'info_short' => 'Informace',
+'printableversion' => 'Verze k tisku',
+'permalink' => 'Trvalý odkaz',
+'print' => 'Vytisknout',
+'edit' => 'Editovat',
+'editthispage' => 'Editovat stránku',
+'delete' => 'Smazat',
+'deletethispage' => 'Smazat stránku',
+'undelete_short' => 'Obnovit $1 {{plural:$1|verzi|verze|verzí}}',
+'protect' => 'Zamknout',
+'protectthispage' => 'Zamknout stránku',
+'unprotect' => 'Odemknout',
+'unprotectthispage' => 'Odemknout stránku',
+'newpage' => 'Nová stránka',
+'talkpage' => 'Diskusní stránka',
+'specialpage' => 'Speciální stránka',
+'personaltools' => 'Osobní nástroje',
+'postcomment' => 'Přidat komentář',
+'articlepage' => 'Prohlédnout si článek',
+'talk' => 'Diskuse',
+'views' => 'Zobrazení',
+'toolbox' => 'Nástroje',
+'userpage' => 'Prohlédnout si uživatelovu stránku',
+'projectpage' => 'Prohlédnout si stránku o projektu',
+'imagepage' => 'Prohlédnout si stránku o obrázku',
+'mediawikipage' => 'Prohlédnout si text rozhraní',
+
+'templatepage' => 'Prohlédnout si šablonu',
+
+'viewhelppage' => 'Prohlédnout si stránku nápovědy',
+
+'categorypage' => 'Prohlédnout si stránku kategorie',
+'viewtalkpage' => 'Prohlédnout si diskusi',
+'otherlanguages' => 'V jiných jazycích',
+'redirectedfrom' => '(Přesměrováno z $1)',
+'redirectpagesub' => 'Přesměrování',
+'autoredircomment' => 'Přesměrováno na [[$1]]',
+'lastmodifiedat' => ' Stránka byla naposledy editována v $2, $1.',
+'viewcount' => 'Stránka byla zobrazena $1krát.',
+'copyright' => 'Obsah je dostupný pod $1.',
+'protectedpage' => 'Zamčená stránka',
+'jumpto' => 'Přejít na:',
+'jumptonavigation' => 'navigace',
+'jumptosearch' => 'hledání',
+
+'badaccess' => 'Nedostatečná oprávnění',
+'badaccess-group0' => 'Nemáte oprávnění k provedené požadované činnosti.',
+'badaccess-group1' => 'Požadovanou činnost smějí provádět jen uživatelé ve skupině $1.',
+'badaccess-group2' => 'Požadovanou činnost smějí provádět jen uživatelé ve skupinách $1.',
+'badaccess-groups' => 'Požadovanou činnost smějí provádět jen uživatelé ve skupinách $1.',
+
+'versionrequired' => 'Vyžadováno MediaWiki verze $1',
+'versionrequiredtext' => 'Pro použití této stránky je vyžadováno MediaWiki verze $1. Vizte [[{{ns:-1}}:Version]].',
+
+'nbytes' => '$1 {{plural:$1|bajt|bajty|bajtů}}',
+'ncategories' => '$1 {{plural:$1|kategorie|kategorie|kategorií}}',
+'nlinks' => '$1 {{plural:$1|odkaz|odkazy|odkazů}}',
+'nmembers' => '$1 {{plural:$1|stránka|stránky|stránek}}',
+'nrevisions' => '$1 {{plural:$1|revize|revize|revizí}}',
+'nviews' => '$1 zobrazení',
+
+'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Citováno z „$1“', #FIXME: Ukazuje se po tisku strany
+'youhavenewmessages' => 'Máte $1 ($2).',
+'newmessageslink' => 'nové zprávy',
+'newmessagesdifflink' => 'rozdíl oproti předchozí verzi',
+'editsection'=>'editovat',
+'editold'=>'editovat',
+'editsectionhint' => 'Editace části $1',
+'toc' => 'Obsah',
+'showtoc' => 'zobrazit',
+'hidetoc' => 'skrýt',
+'thisisdeleted' => 'Prohlédnout nebo obnovit $1?',
+'viewdeleted' => 'Zobrazit $1?',
+'restorelink' => '{{plural:$1|smazanou editaci|$1 smazané editace|$1 smazaných editací}}',
+'feedlinks' => 'Kanály:',
+'feed-invalid' => 'Neplatný typ kanálu.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Článek',
+'nstab-user' => 'Uživatelova stránka',
+'nstab-media' => 'Soubor',
+'nstab-special' => 'Speciální',
+'nstab-project' => '{{SITENAME}}',
+'nstab-image' => 'Soubor',
+'nstab-mediawiki' => 'Hlášení',
+'nstab-template' => 'Šablona',
+'nstab-help' => 'Nápověda',
+'nstab-category' => 'Kategorie',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Neznámý úkon',
+'nosuchactiontext' => 'Tato wiki nezná činnost (action) uvedenou v URL.',
+'nosuchspecialpage' => 'Neexistující speciální stránka',
+'nospecialpagetext' => 'Žádaná speciální stránka na této wiki neexistuje.',
+
+# General errors
+#
+'error' => 'Chyba',
+'databaseerror' => 'Databázová chyba',
+'dberrortext' => 'Při dotazu do databáze došlo k syntaktické chybě.
+Příčinou může být chyba v programu.
+Poslední dotaz byl:
+<blockquote><tt>$1</tt></blockquote>
+z funkce \'<tt>$2</tt>\'.
+MySQL vrátil chybu \'<tt>$3: $4</tt>\'.',
+'dberrortextcl' => 'Při dotazu do databáze došlo k syntaktické chybě.
+Poslední dotaz byl:
+<blockquote><tt>$1</tt></blockquote>
+z funkce \'<tt>$2</tt>\'.
+MySQL vrátil chybu \'<tt>$3: $4</tt>\'.',
+'noconnect' => 'Promiňte! Tato wiki má nějaké technické potíže a nepodařilo se připojit k databázovém serveru.<br />
+$1',
+'nodb' => 'Nebylo možné vybrat databázi $1',
+'cachederror' => 'Následuje kopie požadované stránky z cache, která nemusí být aktuální.',
+'laggedslavemode' => 'Upozornění: Stránka nemusí být zcela aktuální.',
+'readonly' => 'Databáze je uzamčena',
+'enterlockreason' => 'Udejte důvod zamčení, včetně odhadu, za jak dlouho dojde k odemčení.',
+'readonlytext' => 'Databáze je nyní uzamčena, takže nelze ukládat nové doplňky a změny.
+
+Důvodem je pravděpodobně pravidelná údržba, po které se vše vrátí do normálního stavu.
+Správce, který databázi zamkl, zanechal následující zprávu: $1',
+'missingarticle' => 'Databáze nenašla text článku, který měla najít, nazvaného „$1“.
+
+Důvodem je obvykle zastaralý odkaz do historie smazané stránky.
+
+V jiném případě jste možná narazil(a) na chybu v programu. Oznamte to prosím správci systému (zapamatujte si použité URL).',
+'readonly_lag' => 'Databáze byla automaticky dočasně uzamčena kvůli zpoždění ostatních databázových servery proti hlavnímu',
+'internalerror' => 'Vnitřní chyba',
+'filecopyerror' => 'Nebylo možné zkopírovat soubor „$1“ na „$2“.',
+'filerenameerror' => 'Nebylo možné přejmenovat soubor „$1“ na „$2“.',
+'filedeleteerror' => 'Nebylo možné smazat soubor „$1“.',
+'filenotfound' => 'Nebylo možné najít soubor „$1“.',
+'unexpected' => 'Neočekávaná hodnota: "$1"="$2".',
+'formerror' => 'Chyba: nebylo možné odeslat formulář',
+'badarticleerror' => 'Tento úkon nelze použít na tento článek.',
+'cannotdelete' => 'Nebylo možné smazat zvolenou stránku ani soubor. (Možná už byla smazána někým jiným.)',
+'badtitle' => 'Neplatný název',
+'badtitletext' => 'Požadovaný název stránky byl neplatný, prázdný nebo obsahoval nesprávnou předponu mezijazykového či interwiki odkazu. Možná obsahoval znaky, které v názvu nejsou dovoleny.',
+
+'perfdisabled' => 'Omlouváme se. Tato služba byla dočasně znepřístupněna, protože zpomalovala databázi natolik, že nikdo nemohl používat wiki.',
+'perfdisabledsub' => 'Tady je uložená kopie z $1:', # obsolete?
+'perfcached' => 'Následující data jsou z cache a nemusí být plně aktuální:',
+'perfcachedts' => 'Následující data jsou z cache, která byla naposledy aktualizována $1.',
+'wrong_wfQuery_params' => 'Nesprávné parametry do wfQuery()<br />
+Funkce: $1<br />
+Dotaz: $2',
+'viewsource' => ' Ukázat zdroj',
+'viewsourcefor' => 'stránky $1',
+'protectedtext' => 'Tato stránka byla zamčena, takže ji nelze editovat. Můžete si prohlédnout a okopírovat zdrojový text této stránky:',
+'protectedinterface' => 'Tato stránka obsahuje text softwarového rozhraní a smějí ji editovat jen správci.',
+'editinginterface' => "'''Upozornění:''' Editujete stránku, která definuje texty rozhraní. Změny této stránky ovlivní vzhled uživatelského rozhraní všem uživatelům.",
+'sqlhidden' => '(SQL dotaz skryt)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Na shledanou!',
+'logouttext' => 'Nyní jste odhlášeni.<br />
+Tento počítač může být používán k prohlížení a editaci {{grammar:2sg|{{SITENAME}}}} bez uživatelského jména, nebo pro přihlášení jiného uživatele. Upozorňujeme, že některé stránky se mohou i nadále zobrazovat, jako byste byli dosud přihlášeni. Tento jev potrvá do smazání cache vašeho prohlížeče.',
+
+'welcomecreation' => '== Vítejte, $1! ==
+Váš účet byl vytvořen. Nezapomeňte si upravit své [[Special:Preferences|nastavení]]!',
+
+'loginpagetitle' => 'Přihlaste se', #FIXME
+'yourname' => 'Název vašeho účtu', #FIXME buď heslo nebo jméno uživatele nebo název účtu atd.?
+'yourpassword' => 'Vaše heslo',
+'yourpasswordagain' => 'Napište heslo znovu',
+'remembermypassword' => 'Trvalé přihlášení',
+'yourdomainname' => 'Vaše doména',
+'externaldberror' => 'Buď nastalo chyba v databázi pro externí autentikaci, nebo nemáte dovoleno měnit svůj externí účet.',
+'loginproblem' => '<b>Nastal problém při vašem přihlášení.</b><br />Zkuste to znovu!',
+'alreadyloggedin' => "<strong>Uživateli $1, již jste přihlášen!</strong><br />",
+
+'login' => 'Přihlaste se', #FIXME, what exactly do the following go to?
+'loginprompt' => 'K přihlášení do {{grammar:2sg|{{SITENAME}}}} musíte mít povoleny cookies.',
+'userlogin' => 'Přihlaste se',
+'logout' => 'Odhlásit se',
+'userlogout' => 'Na shledanou',
+'notloggedin' => 'Nejste přihlášen(a)',
+'nologin' => 'Dosud nemáte účet? $1.',
+'nologinlink' => 'Zaregistrujte se',
+'createaccount' => 'Vytvořit nový účet',
+'gotaccount' => 'Už jste registrováni? $1.',
+'gotaccountlink' => 'Přihlaste se',
+'createaccountmail' => 'pomocí e-mailu',
+'badretype' => 'Vámi napsaná hesla nesouhlasí.',
+'userexists' => 'Uživatel se stejným jménem je už registrován. Zvolte jiné jméno.',
+'youremail' => 'Vaše e-mailová adresa: *)',
+'username' => 'Uživatelské jméno:',
+'uid' => 'Uživatelské ID:',
+'yourrealname' => 'Vaše skutečné jméno: **)',
+'yourlanguage' => 'Jazyk rozhraní',
+'yourvariant' => 'Jazyková varianta',
+'yournick' => 'Alternativní podpis',
+'badsig' => 'Chybný podpis, zkontrolujte syntaxi HTML.',
+'email' => 'E-mail',
+'prefs-help-email-enotif' => 'Na tuto adresu vám budou zasílány informace o změně stránek, pokud o ně požádáte.',
+'prefs-help-realname' => '**) Skutečné jméno (volitelné): pokud ho zadáte, bude použito pro označení autorství vaší práce.<br />',
+'loginerror' => 'Chyba při přihlašování',
+'prefs-help-email' => '*) E-mail (volitelný): Umožní ostatním uživatelům vás kontaktovat, aniž by tato adresa byla zobrazena; také vám na tuto adresu může být zasláno nové heslo v případě, že své heslo zapomenete.',
+'nocookiesnew' => 'Uživatelský účet byl vytvřen, ale nejste přihlášeni. {{SITENAME}} používá cookies k přihlášení uživatelů. Vy máte cookies vypnuty. Prosím zapněte je a přihlaste se znovu s vaším novým uživatelským jménem a heslem.',
+'nocookieslogin' => '{{SITENAME}} používá cookies k přihlášení uživatelů. Vy máte cookies vypnuty. Prosím zapněte je a zkuste znovu.',
+'noname' => 'Musíte uvést jméno svého účtu.',
+'loginsuccesstitle' => 'Přihlášení uspělo',
+'loginsuccess' => 'Nyní jste přihlášen na {{grammar:6sg|{{SITENAME}}}} jako uživatel „$1“.',
+'nosuchuser' => 'Neexistuje uživatel se jménem „$1“. Zkontrolujte zápis, nebo si vytvořte nový účet.',
+'nosuchusershort' => 'Neexistuje uživatel se jménem „$1“. Zkontrolujte zápis.',
+'nouserspecified' => 'Musíte zadat uživatelské jméno.',
+'wrongpassword' => 'Vámi uvedené heslo nesouhlasí. Zkuste to znovu.',
+'wrongpasswordempty' => 'Zadané heslo bylo prázdné. Zkuste to znovu.',
+'mailmypassword' => 'Poslat e-mailem dočasné heslo',
+'passwordremindertitle' => 'Připomenutí ztraceného hesla z {{grammar:2sg|{{SITENAME}}}}',
+'passwordremindertext' => 'Někdo (patrně Vy, z IP adresy $1) žádal, abychom Vám poslali nové heslo pro přihlášení do {{SITENAME}} ($4). Heslo pro uživatele "$2" je nyní "$3". Doporučujeme přihlásit se nyní a změnit heslo.
+
+Pokud jste o změnu hesla nežádali nebo jste si na původní heslo již vzpomněli a už ho změnit
+nechcete, můžete tuto zprávu ignorovat a používat staré heslo.',
+'noemail' => 'Uživatel „$1“ nemá zaregistrovanou e-mailovou adresu.',
+'passwordsent' => 'Dočasné heslo bylo zasláno na e-mailovou adresu registrovanou pro „$1“. Přihlaste se, prosím, znovu, jakmile ho obdržíte.',
+'eauthentsent' => 'Potvrzovací e-mail byl zaslán na zadanou adresu.
+Před tím, než vám na tuto adresu budou moci být zasílány další zprávy, následujte instrukce
+v e-mailu, abyste potvrdili, že tato adresa skutečně patří vám.',
+
+'mailerror' => 'Chyba při zasílání e-mailu: $1',
+'acct_creation_throttle_hit' => 'Omlouváme se, ale už jste vyrobil(a) $1 účtů. Žádný další už nemůžete vytvořit.',
+'emailauthenticated' => 'Vaše e-mailová adresa byla ověřena $1.',
+'emailnotauthenticated' => 'Vaše e-mailová adresa dosud nebyla ověřena a e-mailové funkce do té doby nejsou dostupné.',
+'noemailprefs' => 'Pro zprovoznění následujících možností musíte zadat svou e-mailovou adresu.',
+'emailconfirmlink' => 'Podvrďte svou e-mailovou adresu',
+'invalidemailaddress' => 'Zadaná e-mailová adresa nemůže být přijata, neboť nemá správný formát. Zadejte laskavě platnou e-mailovou adresu, nebo obsah tohoto pole vymažte.',
+'accountcreated' => 'Účet vytvořen',
+'accountcreatedtext' => 'Uživatelský účet $1 byl vytvořen.',
+
+# Edit page toolbar
+'bold_sample'=>'Tučný text',
+'bold_tip'=>' Tučný text',
+'italic_sample'=>'Kurzíva',
+'italic_tip'=>'Kurzíva',
+'link_sample'=>'Název odkazu',
+'link_tip'=>'Vnitřní odkaz',
+'extlink_sample'=>'http://www.example.com Titulek odkazu',
+'extlink_tip'=>'Externí odkaz (nezapomeňte na předponu http://)',
+'headline_sample'=>'Text nadpisu',
+'headline_tip'=>'Nadpis druhé úrovně',
+'math_sample'=>'Vložit sem vzorec',
+'math_tip'=>'Matematický vzorec (LaTeX)',
+'nowiki_sample'=>' Vložit sem neformátovaný text',
+'nowiki_tip'=>'Ignorovat formátování wiki',
+'image_sample'=>'Příklad.jpg',
+'image_tip'=>'Vložený obrázek',
+'media_sample'=>'Příklad.ogg',
+'media_tip'=>'Odkaz na mediální soubor',
+'sig_tip'=>'Váš podpis s časovým údajem',
+'hr_tip'=>'Vodorovná čára (používejte střídmě)',
+
+# Edit pages
+#
+'summary' => '<a href="{{LOCALURLE:Project:Shrnutí editace}}" class="internal" title="Stručně popište změny, které jste zde učinili">Shrnutí editace</a>',
+'subject' => 'Předmět/nadpis',
+'minoredit' => 'Tato změna je malá editace.',
+'watchthis' => 'Sledovat tento článek',
+'savearticle' => 'Uložit změny',
+'preview' => 'Náhled',
+'showlivepreview' => 'Rychlý náhled',
+'showpreview' => 'Ukázat náhled',
+'showdiff' => 'Ukázat změny',
+'anoneditwarning' => "'''Varování:''' Nejste přihlášen(a). Vaše IP adresa bude zveřejněna v historii této stránky.",
+'missingsummary' => "'''Připomenutí:''' Nezadali jste shrnutí editace. Pokud ještě jednou kliknete na Uložit změny, bude vaše editace zapsána bez shrnutí.",
+'missingcommenttext' => 'Zadejte komentář',
+'blockedtitle' => 'Uživatel zablokován',
+'blockedtext' => "<big>'''Vaší IP adrese či uživatelskému jménu byla zablokována možnost editace.'''</big>
+
+Pokoušíte se editovat stránku, ať už kliknutím na tlačítko ''Editovat stránku'', nebo na červený odkaz. Vaše uživatelské jméno nebo IP adresa však byla zablokována správcem s uživatelským jménem „$1“. Jako důvod blokování uvedl: '''$2'''.
+
+Pokud chcete zablokování prodiskutovat, můžete [[Special:Emailuser/$1|kontaktovat]] uživatele $1 či jiného [[Special:Listadmins|správce]]. Uvědomte si, že nemůžete použít nabídku „Poslat e-mail“, jestliže nemáte na {{grammar:6sg|{{SITENAME}}}} účet a ve svém [[Special:Preferences|nastavení]] uvedenu platnou e-mailovou adresu.
+
+Vaše IP adresa je '''$3'''; tento údaj budete muset uvést ve všech žádostech o odblokování.
+
+Pokud chcete vědět, kdy zablokování vyprší, podívejte se na [[Special:Ipblocklist|seznam blokovaných uživatelů]].
+
+== Chcete jen číst? ==
+Blokování nebrání čtení stránek, jen jejich editaci. Pokud jste si chtěli jen
+přečíst stránku a vidíte tuto zprávu, pravděpodobně jste klikli na červený odkaz.
+To je odkaz na stránku, která zatím neexistuje, takže se uživateli otevře editační
+okénko. Tento problém mít nebudete, pokud budete klikat jen na modré odkazy.",
+'blockedoriginalsource' => "Zdrojový text stránky '''$1''' následuje:",
+'blockededitsource' => "Text '''vašich editací''' stránky '''$1''' následuje:",
+'whitelistedittitle' => 'Pro editaci je vyžadováno přihlášení',
+'whitelistedittext' => 'Pro editaci se musíte $1.',
+'whitelistreadtitle' => 'Vyžadováno přihlášení',
+'whitelistreadtext' => 'Pro čtení článků se musíte [[Special:Userlogin|přihlásit]].',
+'whitelistacctitle' => 'Není vám dovoleno vytvářet uživatelské účty',
+'whitelistacctext' => 'Abyste na této wiki mohl(a) vytvářet uživatelské účty, musíte se [[Special:Userlogin|přihlásit]] a mít příslušná oprávnění.',
+'confirmedittitle' => 'Vyžadováno e-mailové potvrzení',
+'confirmedittext' => 'Pro editaci stránek je vyžadováno potvrzení vaší e-mailové adresy. Na stránce [[Special:Preferences|nastavení]] zadejte a nechte potvrdit svou e-mailovou adresu.',
+'loginreqtitle' => 'Vyžadováno přihlášení',
+'loginreqlink' => 'přihlásit',
+'loginreqpagetext' => ' K prohlížení jiných stránek se musíte $1.',
+'accmailtitle' => 'Heslo odesláno.',
+'accmailtext' => 'Heslo pro „$1“ bylo odesláno na $2.',
+'newarticle' => '(Nový)',
+'newarticletext' => "Následovali jste odkaz na stránku, která dosud neexistuje.
+Pokud ji chcete vytvořit, napište text do rámečku níže a stiskněte tlačítko ''Uložit změny''. Další rady najdete v [[Nápověda:Obsah|nápovědě]].
+Pokud jste zde omylem, stiskněte ve svém prohlížeči tlačítko ''Zpět''.",
+'anontalkpagetext' => "---- ''Toto je diskusní stránka anonymního uživatele, který si dosud nevytvořil účet nebo ho nepoužívá. Musíme proto použít číselnou [[w:cs:IP adresa|IP adresu]] k jeho identifikaci. Taková IP adresa může být sdílena několika uživateli. Pokud jste anonymní uživatel a cítíte, že jsou Vám adresovány irrelevantní komentáře, prosím [[Special:Userlogin|vytvořte si účet nebo se přihlaste]] a tím se vyhnete budoucí záměně s jinými anonymními uživateli.''",
+'noarticletext' => 'Tato stránka zatím neobsahuje žádný text, můžete [[Special:Search/{{PAGENAME}}|zkusit tento název vyhledat]] na jiných stránkách, nebo [{{fullurl:{{FULLPAGENAME}}|action=edit}} tuto stránku založit].',
+'clearyourcache' => "'''Poznámka:''' Po uložení musíte smazat cache vašeho prohlížeče, jinak změny neuvidíte: '''Mozilla / Firefox:''' ''Ctrl-Shift-R'', '''IE:''' ''Ctrl-F5'', '''Safari:''' ''Cmd-Shift-R'', '''Konqueror''': ''F5''.",
+'usercssjsyoucanpreview' => '<strong>Tip:</strong> Použijte tlačítko „Ukázat náhled“ k testování vašeho nového css/js před uložením.',
+'usercsspreview' => "'''Pamatujte, že si prohlížíte jen náhled vašeho uživatelského css, neboť ještě nebylo uloženo!'''",
+'userjspreview' => "'''Pamatujte, že testujete a prohlížíte pouze náhled vašeho uživatelského javascriptu, dosud nebyl uložen!'''",
+'userinvalidcssjstitle' => "'''Varování:''' Vzhled „$1“ neexistuje. Nezapomeňte, že uživatelské .css a .js soubory používají malá písmena, např. {{ns:User}}:{{BASEPAGENAME}}/monobook.css, nikoli {{ns:User}}:{{BASEPAGENAME}}/Monobook.css.",
+'updated' => '(Změna uložena)', #FIXME: ?
+'note' => '<strong>Poznámka:</strong>&nbsp;', #FIXME: Where does this come from?
+'previewnote' => 'Pamatujte, že toto je pouze náhled, ne uložení!',
+'session_fail_preview' => '<strong>Omlouváme se, ale váš požadavek se nepodařilo zpracovat. Zkuste to prosím znovu. Pokud se tento problém bude opakovat, zkuste se odhlásit a znovu přihlásit.</strong>',
+'session_fail_preview_html' => '<strong>Omlouváme se, ale váš požadavek se nepodařilo zpracovat.</strong>
+
+\'\'Jelikož tato wiki má povoleno libovolné HTML, není zobrazen náhled jako prevence proti útokům JavaScriptem.\'\'
+
+Pokud jde o zamýšlenou editaci, zkuste to prosím znovu. Pokud se tento problém bude opakovat, zkuste se odhlásit a znovu přihlásit.</strong>',
+'previewconflict' => 'Tento náhled ukazuje text tak, jak bude vypadat po uložení stránky.', #FIXME
+'importing' => 'Import stránky $1',
+'editing' => 'Editace stránky $1',
+'editinguser' => 'Editace stránky $1',
+'editingsection' => 'Editace stránky $1 (část)',
+'editingcomment' => 'Editace stránky $1 (komentář)',
+'editconflict' => 'Editační konflikt: $1',
+'explainconflict' => 'Někdo změnil stránku po započetí vaší editace. Výše vidíte aktuální text článku. Vaše změny jsou uvedeny dole. Musíte sloučit své změny se stávajícím článkem. <b>Pouze</b> výše uvedený text zůstane uchován po kliknutí na „Uložit“. <br />',
+'yourtext' => 'Váš text',
+'storedversion' => ' Uložená verze',
+'nonunicodebrowser' => '<strong>UPOZORNĚNÍ: Váš prohlížeč není schopen pracovat se znaky [[w:cs:Unicode|Unicode]], pro editaci stránek prosím použijte nějaký jiný.</strong>',
+'editingold' => '<strong>VAROVÁNÍ: Nyní editujete zastaralou verzi této stránky. Když ji uložíte, všechny změny provedené mezitím se ztratí.</strong>',
+'yourdiff' => 'Rozdíly',
+'copyrightwarning' => 'Všechny příspěvky do {{grammar:2sg|{{SITENAME}}}} jsou zveřejňovány podle $2 (podrobnosti najdete na $1). Pokud si nepřejete, aby váš text byl nemilosrdně upravován a volně šířen, pak ho do {{grammar:2sg|{{SITENAME}}}} neukládejte.<br />
+Uložením příspěvku se zavazujete, že je vaším dílem nebo je zkopírován ze zdrojů, které [[w:cs:volné dílo|nejsou chráněny]] autorským právem (tzv. <em>public domain</em>). <strong>Nekopírujte díla chráněná autorským právem bez dovolení!</strong>',
+'copyrightwarning2' => 'Uvědomte si, že všechny příspěvky do {{grammar:2sg|{{SITENAME}}}} mohou být ostatními uživateli upraveny, pozměněny či odstraněny. Pokud si nepřejete, aby váš text byl nemilosrdně upravován, pak ho do {{grammar:2sg|{{SITENAME}}}} neukládejte.<br />
+Uložením příspěvku se zavazujete, že je vaším dílem nebo je zkopírován ze zdrojů, které [[w:cs:volné dílo|nejsou chráněny]] autorským právem (tzv. <em>public domain</em>), podrobnosti najdete na $1. <strong>Nekopírujte díla chráněná autorským právem bez dovolení!</strong>',
+'longpagewarning' => 'VAROVÁNÍ: Tato stránka je $1 KB dlouhá; některé prohlížeče mohou mít problémy s editováním stran, které se blíží nebo jsou delší než 32 KB. Prosím zvažte rozdělení stránky na více částí.',
+'longpageerror' => '<strong>CHYBA: Pokoušíte se uložit text o velikosti $1 KB, přičemž dovolené maximum je $2 KB. Vaše editace nemůže být uložena.</strong>',
+'readonlywarning' => 'VAROVÁNÍ: Databáze byla uzamčena kvůli údržbě, takže nebudete moci uložit své změny. Můžete si okopírovat text do souboru a uložit ho na později.',
+'protectedpagewarning' => '<strong>Varování:</strong> Tato stránka byla zamčena, takže ji mohou editovat pouze správci.',
+'semiprotectedpagewarning' => '<strong>Poznámka:</strong> Tato stránka byla zamčena, takže ji mohou editovat pouze registrovaní uživatelé.',
+'templatesused' => 'Šablony používané na této stránce:',
+'edittools' => '<!-- Tento text bude zobrazen pod formuláři pro editaci stránek a načítání souborů. -->',
+'nocreatetitle' => 'Vytváření nových stránek je omezeno',
+'nocreatetext' => 'Na tomto serveru je možnost vytváření nových stránek omezena.
+Můžete se vrátit a editovat již existující stránku, nebo [[Special:Userlogin|se přihlásit či se registrovat]].',
+'cantcreateaccounttitle' => 'Nelze vytvořit uživatelský účet',
+'cantcreateaccounttext' => 'Tvorba účtů z této IP adresy (<b>$1</b>) byla zablokována. Je to pravděpodobně způsobeno opakovaným vandalismem uživatelů stejného poskytovatele internetového připojení či školy.',
+
+# History pages
+#
+'revhistory' => 'Historie editací',
+'viewpagelogs' => 'Zobrazit protokolovací záznamy k této stránce',
+'nohistory' => 'O této stránce neexistuje historie editací.',
+'revnotfound' => 'Verze nenalezena',
+'revnotfoundtext' => 'Nelze najít starou verzi, kterou žádáte. Zkuste prosím zkontrolovat URL hledané stránky.\b',
+'loadhist' => 'Načítá se stránka historie editací', #FIXME Apparently not used
+'currentrev' => 'Aktuální verze',
+'revisionasof' => 'Verze z $1',
+'revision-info' => 'Verze z $1; $2',
+'previousrevision' => '← Starší verze',
+'nextrevision' => 'Novější verze →',
+'currentrevisionlink' => 'zobrazit aktuální verzi',
+'cur' => 'teď',
+'next' => 'násl',
+'last' => 'předchozí',
+'orig' => 'původní',
+'histlegend' => '(teď) = rozdíly oproti nynější verzi, (předchozí) = rozdíly oproti předchozí verzi, <b>m</b> = malá editace',
+'deletedrev' => '[smazáno]',
+'histfirst' => 'Nejstarší',
+'histlast' => 'Nejnovější',
+'rev-deleted-comment' => '(komentář odstraněn)',
+'rev-deleted-user' => '(uživatelské jméno odstraněno)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Tato revize byla odstraněna z veřejného archivu.
+Podrobnosti o smazání mohou být uvedeny v [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} knize smazaných stránek].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Tato revize byla odstraněna z veřejného archivu.
+Jako správce si ji však můžete prohlédnout;
+podrobnosti o smazání mohou být uvedeny v [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} knize smazaných stránek].
+</div>',
+'rev-delundel' => 'skrýt/zobrazit',
+
+'history-feed-title' => 'Historie editací',
+'history-feed-description' => 'Historie editací této stránky',
+'history-feed-item-nocomment' => '$1 v $2',
+'history-feed-empty' => 'Požadovaná stránka neexistuje.
+Mohla být smazána či přejmenována.
+Zkuste [[Special:Search|hledání]].',
+
+# Revision deletion
+#
+'revisiondelete' => 'Smazat/obnovit revize',
+'revdelete-nooldid-title' => 'Nezadána revize',
+'revdelete-nooldid-text' => 'Nezvolili jste revize, na které chcete tuto funkci použít.',
+'revdelete-selected' => 'Zvolené revize [[:$1]]:',
+'revdelete-text' => 'Smazané revize budou nadále zobrazeny v historii stránky, ale jejich text nebude veřejně dostupný.
+
+Ostatní správci této wiki si budou moci skrytý obsah prohlížet a pomocí stejného rozhraní jej také obnovit,
+pokud to provozovatel serveru nezakázal.',
+'revdelete-legend' => 'Nastavit omezení k revizi:',
+'revdelete-hide-text' => 'Skrýt text revize',
+'revdelete-hide-comment' => 'Skrýt editační komentář',
+'revdelete-hide-user' => 'Skrýt uživatelovu IP adresu',
+'revdelete-hide-restricted' => 'Tato omezení aplikovat i na správce',
+'revdelete-log' => 'Komentář:',
+'revdelete-submit' => 'Aplikovat nastavení',
+'revdelete-logentry' => 'změnil viditelnost revizí u [[$1]]',
+
+# Diffs
+#
+'difference' => '(Rozdíly mezi verzemi)',
+'loadingrev' => 'načítají se verze pro zjištění rozdílů', #FIXME Apparently not used
+'lineno' => 'Řádka $1:',
+'editcurrent' => ' Editovat nynější verzi této stránky',
+'selectnewerversionfordiff' => 'Vyberte novější verzi pro porovnání',
+'selectolderversionfordiff' => 'Vyberte starší verzi pro porovnání',
+'compareselectedversions' => 'Porovnat vybrané verze',
+
+# Search results
+#
+'searchresults' => 'Výsledky hledání',
+'searchresulttext' => 'Pro více informací o tom, jak hledat na {{grammar:6sg|{{SITENAME}}}}, se podívejte na [[Nápověda:Hledání]].',
+'searchsubtitle' => 'Hledáno „[[:$1]]“',
+'searchsubtitleinvalid' => 'Hledáno „$1“',
+'badquery' => 'Špatně vytvořený vyhledávací dotaz',
+'badquerytext' => 'Nemůžeme zpracovat vaše zadání. Je to pravděpodobně tím, že hledáte slovo kratší než tři písmena, což zatím není podporováno. Může to být také tím, že zadání bylo napsáno nesprávně. Prosím zkuste jiné zadání.',
+'matchtotals' => 'Zadanému „$1“ odpovídá $2 {{plural:$2|název strany|názvy stran|názvů stran}} a text $3 {{plural:$3|strany|stran|stran}}.',
+'noexactmatch' => "'''Neexistuje žádná stránka s názvem „$1“.''' Můžete tuto stránku [[:$1|založit]].",
+'titlematches' => 'Stránky s odpovídajícím názvem',
+'notitlematches' => 'Žádné stránky názvem neodpovídají.',
+'textmatches' => 'Stránky s odpovídajícím textem',
+'notextmatches' => 'Žádné stránky textem neodpovídají.',
+'prevn' => '$1 předchozích',
+'nextn' => '$1 následujících',
+'viewprevnext' => 'Ukázat ($1) ($2) ($3).',
+'showingresults' => 'Zobrazuji <strong>$1</strong> {{plural:$1|výsledek|výsledky|výsledků}} počínaje od <strong>$2</strong>.',
+'showingresultsnum' => 'Zobrazuji <strong>$3</strong> {{plural:$3|výsledek|výsledky|výsledků}} počínaje od <strong>$2</strong>.',
+'nonefound' => '<strong>Poznámka</strong>: neúspěšná hledání jsou často důsledkem zadání slov, která nejsou indexována, nebo uvedením mnoha slov najednou (ve výsledku se objeví jen ty stránky, které obsahují všechna zadaná slova).',
+'powersearch' => 'Hledání',
+'powersearchtext' => 'Hledat',
+'powersearchtext' => '
+Hledat ve jmenných prostorech:<br />
+$1<br />
+$2 Vypsat přesměrování &nbsp; Hledat $3 $9',
+'searchdisabled' => '<p>Omlouváme se. Plnotextové vyhledávání je dočasně nedostupné. Zatím můžete zkusit vyhledávání Googlem; je ale možné, že jeho výsledky nemusí být aktuální.</p>',
+'blanknamespace' => '(Hlavní)',
+
+# Preferences page
+#
+'preferences' => 'Nastavení',
+'mypreferences' => 'Nastavení',
+'prefsnologin' => 'Nejste přihlášen(a)!',
+'prefsnologintext' => 'Pro nastavení se musíte [[Special:Userlogin|přihlásit]].',
+'prefsreset' => 'Nastavení vráceno.', #FIXME: Hmm...
+'qbsettings' => 'Nastavení lišty nástrojů',
+'changepassword' => 'Změna hesla',
+'skin' => 'Styl',
+'math' => 'Matematika',
+'dateformat' => 'Formát data',
+'datedefault' => 'Implicitní',
+'datetime' => 'Datum a čas',
+'math_failure' => 'Nelze pochopit',
+'math_unknown_error' => 'neznámá chyba',
+'math_unknown_function' => 'neznámá funkce',
+'math_lexing_error' => 'chyba při lexingu', #FIXME
+'math_syntax_error' => 'syntaktická chyba',
+'math_image_error' => 'Selhala konverze do PNG; zkontrolujte správnou instalaci latexu, dvips, gs a convertu',
+'math_bad_tmpdir' => 'Nelze zapsat nebo vytvořit dočasný adresář pro matematiku',
+'math_bad_output' => 'Nelze zapsat nebo vytvořit adresář pro výstup matematiky',
+'math_notexvc' => 'Chybí spustitelný texvc; podívejte se prosím do math/README na konfiguraci.',
+'prefs-personal' => 'Údaje o uživateli',
+'prefs-rc' => ' Poslední změny',
+'prefs-watchlist' => 'Sledované stránky',
+'prefs-watchlist-days' => 'Počet dní zobrazených ve sledovaných stránkách:',
+'prefs-watchlist-edits' => 'Počet editací zobrazených na zdokonalených sledovaných stránkách:',
+'prefs-misc' => ' Různé',
+'saveprefs' => 'Uložit nastavení',
+'resetprefs' => 'Vrátit původní nastavení',
+'oldpassword' => 'Staré heslo',
+'newpassword' => 'Nové heslo',
+'retypenew' => 'Napište znovu nové heslo',
+'textboxsize' => 'Editace',
+'rows' => 'Řádky',
+'columns' => 'Sloupce',
+'searchresultshead' => 'Vyhledávání',
+'resultsperpage' => 'Počet nalezených článků na jednu stránku výsledků',
+'contextlines' => ' Počet řádek zobrazených z každé nalezené stránky',
+'contextchars' => ' Počet znaků kontextu na každé řádce',
+'stubthreshold' => 'Hranice pro zobrazení pahýlu',
+'recentchangescount' => 'Počet zobrazených záznamů v posledních změnách',
+'savedprefs' => 'Vaše nastavení bylo uloženo.',
+'timezonelegend' => 'Časové pásmo',
+'timezonetext' => 'Označte, o kolik se vaše časové pásmo liší od serveru (UTC). Například pro středoevropské časové pásmo (SEČ) vyplňte „01:00“ v zimě, „02:00“ v období platnosti letního času.',
+'localtime' => 'Místní časové pásmo',
+'timezoneoffset' => 'Posun',
+'servertime' => 'Aktuální čas na serveru',
+'guesstimezone' => 'Načíst z prohlížeče',
+'allowemail' => 'Dovolit e-mail od ostatních uživatelů',
+'defaultns' => 'Implicitně hledat v těchto jmenných prostorech:',
+'default' => 'implicitní',
+'files' => 'Soubory',
+
+# User levels special page
+#
+'userrights-lookup-user' => 'Spravovat uživatelské skupiny',
+'userrights-user-editname' => 'Zadejte uživatelské jméno:',
+'editusergroup' => 'Upravit uživatelskou skupinu',
+
+# user groups editing
+'userrights-editusergroup' => 'Upravit uživatelské skupiny',
+'saveusergroups' => 'Uložit uživatelské skupiny',
+'userrights-groupsmember' => 'Člen skupin:',
+'userrights-groupsavailable' => 'Dostupné skupiny:',
+'userrights-groupshelp' => 'Zvolte skupiny, do/ze kterých chcete uživatele přidat/odebrat.
+Nezvolené skupiny nebudou změněny. Skupinu můžete vyřadit z vybraných pomocí CTRL + Levé tlačítko myši',
+
+# Default group names and descriptions
+#
+'group' => 'Skupina:',
+'group-bot' => 'Boti',
+'group-sysop' => 'Správci',
+'group-bureaucrat' => 'Byrokraté',
+'group-all' => '(všichni)',
+
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Správce',
+'group-bureaucrat-member' => 'Byrokrat',
+
+'grouppage-bot' => '{{ns:Project}}:Boti',
+'grouppage-sysop' => '{{ns:Project}}:Správci',
+'grouppage-bureaucrat' => '{{ns:Project}}:Byrokraté',
+
+# Recent changes
+#
+'changes' => 'změny',
+'recentchanges' => 'Poslední změny',
+'recentchangestext' => 'Sledujte poslední změny na {{grammar:6sg|{{SITENAME}}}} na této stránce.',
+'rcnote' => 'Níže {{plural:$1|je poslední|jsou poslední|je posledních}} <strong>$1</strong> {{plural:$1|změna|změny|změn}} za {{plural:$2|poslední|poslední|posledních}} <strong>$2</strong> {{plural:$2|den|dny|dnů}} před $3.',
+'rcnotefrom' => 'Níže {{plural:$1|je|jsou|je}} nejvýše <b>$1</b> {{plural:$1|změna|změny|změn}} od <b>$2</b>.',
+'rclistfrom' => 'Ukázat nové změny, počínaje od $1',
+'rcshowhideminor' => '$1 malé editace',
+'rcshowhidebots' => '$1 roboty',
+'rcshowhideliu' => '$1 přihlášené uživatele',
+'rcshowhideanons' => '$1 anonymní uživatele',
+'rcshowhidepatr' => '$1 prověřené editace',
+'rcshowhidemine' => '$1 moje editace',
+'rclinks' => 'Ukázat $1 posledních změn během posledních $2 dnů; $3.',
+'diff' => 'rozdíl',
+'hist' => 'historie',
+'hide' => 'skrýt',
+'show' => 'ukázat',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'number_of_watching_users_pageview' => '[$1 {{plural:$1|sledující uživatel|sledující uživatelé|sledujících uživatelů}}]',
+'rc_categories' => 'Omezit na kategorie (oddělené „|“)',
+'rc_categories_any' => 'Všechny',
+
+# Upload
+#
+'upload' => 'Načíst soubor',
+'uploadbtn' => 'Načíst soubor',
+'reupload' => 'Načíst znovu',
+'reuploaddesc' => 'Vrátit se k načtení.',
+'uploadnologin' => 'Nejste přihlášen(a)',
+'uploadnologintext' => 'Pro načtení souboru se musíte [[Special:Userlogin|přihlásit]].',
+'upload_directory_read_only' => 'Do adresáře pro načítané soubory ($1) nemá webserver právo zápisu.',
+'uploaderror' => 'Při načítání došlo k chybě',
+'uploadtext' => "
+'''POZOR!''' Před nahráváním souborů si zcela určitě přečtěte
+[[Project:Pravidla použití obrázků|pravidla použití obrázků]]
+a dodržujte je.
+
+Pro prohlížení a hledání již dříve nahraných souborů se podívejte
+na [[Special:Imagelist|seznam načtených souborů]], popř.
+[[Special:Newimages|galerii nových obrázků]]. Všechna načtení
+a smazání jsou zaznamenány v [[Special:Log|protokolovacích záznamech]].
+
+Pomocí níže uvedeného formuláře můžete na wiki nahrát obrázky a jiné
+soubory, které poté budete moci použít v článcích. Ve většině prohlížečů
+je zobrazeno tlačítko „Procházet…“, pomocí kterého budete moci
+vybrat soubor k načtení, jehož jméno se poté objeví v políčku
+vedle tlačítka. Poté stiskněte tlačítko „Načíst soubor“ k
+dokončení načtení. Buďte trpěliví, nahrávání může chvíli trvat.
+
+Preferované formáty jsou JPEG pro fotografie, PNG pro schémata
+a OGG pro zvuky. Používejte laskavě smysluplná jména souborů,
+soubor po načtení nelze přejmenovat.
+
+Pro vložení obrázku do stránky použijte syntaxi
+<code><nowiki>[[{{ns:6}}:soubor.jpg]]</nowiki></code> nebo
+<code><nowiki>[[{{ns:6}}:soubor.png|popisek]]</nowiki></code>, popř.
+<code><nowiki>[[{{ns:-2}}:soubor.ogg]]</nowiki></code> pro zvuky.
+
+Uvědomte si laskavě, že stejně jako u ostatních wikistránek mohou
+ostatní uživatelé vámi nahraný soubor smazat či upravit, pokud to
+uznají za vhodné; pokud budete tuto funkci zneužívat, může být
+váš uživatelský účet zablokován.",
+'uploadlog' => 'kniha nahrávek',
+'uploadlogpage' => 'Kniha nahrávek',
+'uploadlogpagetext' => 'Níže najdete seznam nejnovějších souborů.',
+'filename' => 'Soubor',
+'filedesc' => 'Popis',
+'fileuploadsummary' => 'Popis:',
+'filestatus' => 'Autorská práva',
+'filesource' => 'Zdroj',
+'copyrightpage' => '{{ns:4}}:Autorské právo',
+'copyrightpagename' => 'podmínek {{grammar:2sg|{{SITENAME}}}}',
+'uploadedfiles' => 'Načtené soubory',
+'ignorewarning' => 'Ignorovat varování a načíst soubor.',
+'ignorewarnings' => 'Ignorovat všechna varování',
+'minlength' => 'Jméno souboru se musí skládat nejméně ze tří písmen.',
+'illegalfilename' => 'Název souboru "$1" obsahuje znaky, které nejsou povoleny v názvech stránek. Prosím přejmenujte soubor a zkuste jej nahrát znovu.',
+'badfilename' => 'Jméno souboru bylo změněno na „$1“.',
+'badfiletype' => '„.$1“ není jeden z dovolených typů souborů.',
+'largefile' => 'Doporučuje se, aby délka souboru nepřesahovala $1&nbsp;B, tento soubor má $2&nbsp;B.',
+'largefileserver' => 'Velikost tohoto souboru překračuje limit nastavený na serveru.',
+'emptyfile' => 'Soubor, který jste vložili, se zdá být prázdný. Mohl to způsobit překlep v názvu souboru. Prosím zkontrolujte, zda jste opravdu chtěli vložit tento soubor.',
+'fileexists' => ' Soubor s tímto jménem již existuje, prosím podívejte se na $1, pokud nevíte jistě, zda chcete tento soubor nahradit.',
+'fileexists-forbidden' => 'Soubor s tímto názvem již existuje; vraťte se a zvolte jiný název. [[Soubor:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Soubor s tímto názvem již existuje ve sdíleném úložišti; vraťte se a zvolte jiný název. [[Soubor:$1|thumb|center|$1]]',
+'successfulupload' => 'Načtení úspěšně provedeno!',
+'fileuploaded' => 'Soubor „$1“ byl úspěšně načten. Prosím klikněte na tento odkaz: ($2), který vede na stránku popisu a napište tam informace o souboru: odkud pochází, kdy byl vytvořen a kým; a cokoliv dalšího, co o něm můžete vědět. Pokud je to obrázek, můžete ho do stránek vložit takto: <tt><nowiki>[[</nowiki>{{ns:6}}:$1|thumb|Nadpis]]</tt>',
+'uploadwarning' => 'Varování',
+'savefile' => 'Uložit soubor',
+'uploadedimage' => 'načítá „[[$1]]“',
+'uploaddisabled' => 'Načítání souborů vypnuto.',
+'uploaddisabledtext' => 'Promiňte, ale načítání souborů je na této wiki vypnuto.',
+'uploadscripted' => 'Tento soubor obsahuje HTML nebo kód skriptu, který by mohl být prohlížečem chybně interpretován.',
+'uploadcorrupt' => 'Soubor je poškozen nebo nemá správnou příponu. Zkontrolujte prosím soubor a zkuste ho načíst znovu.',
+'uploadvirus' => 'Tento soubor obsahuje virus! Podrobnosti: $1',
+'sourcefilename' => 'Jméno zdrojového souboru',
+'destfilename' => 'Cílové jméno',
+'watchthisupload' => 'Sledovat tuto stránku',
+'filewasdeleted' => 'Soubor stejného jména byl již dříve načten a posléze smazán. Podrobnosti obsahuje $1.', #TODO: grammar...??
+
+'license' => 'Licence',
+'nolicense' => 'Bez udání licence',
+'upload_source_url' => ' (platné, veřejně přístupné URL)',
+'upload_source_file' => ' (soubor na vašem počítači)',
+
+# Image list
+#
+'imagelist' => 'Seznam načtených obrázků',
+'imagelisttext' => 'Níže je seznam $1 obrázků, seřazených $2.',
+'imagelistforuser' => 'Tento seznam obsahuje jen soubory načtené uživatelem $1.',
+'getimagelist' => 'načítám seznam obrázků',
+'ilsubmit' => 'Hledat',
+'showlast' => 'Ukázat posledních $1 obrázků řazených $2.',
+'byname' => 'podle jména',
+'bydate' => 'podle data',
+'bysize' => 'podle velikosti',
+'imgdelete' => 'smazat',
+'imgdesc' => 'popis',
+'imgfile' => 'soubor',
+'imglegend' => '(popis) = ukázat / editovat popis souboru.',
+'imghistory' => 'Historie načtených souborů',
+'revertimg' => 'vrátit',
+'deleteimg' => 'smazat',
+'deleteimgcompletely' => 'smazat úplně',
+'imghistlegend' => '(teď) = toto je současná verze souboru, (smazat úplně) = smazat všechny verze tohoto souboru, (smazat) = smazat jen tuto verzi, (vrátit) = obnovit starou verzi. <br /> <i>Klikněte na datum pro zobrazení obrázku, který byl uložen v ten den.</i>',
+'imagelinks' => 'Odkazy k souboru',
+'linkstoimage' => 'Na soubor odkazují tyto stránky:',
+'nolinkstoimage' => 'Na tento soubor neodkazuje žádná stránka.',
+'sharedupload' => 'Tento soubor je sdílený a může být používán ostatními projekty.',
+'shareduploadwiki' => 'Více informací najdete na $1.',
+'shareduploadwiki-linktext' => 'stránce s popisem',
+'noimage' => 'Soubor s tímto jménem neexistuje, můžete ho $1',
+'noimage-linktext' => 'načíst',
+'uploadnewversion-linktext' => 'Načíst novou verzi tohoto souboru',
+'imagelist_date' => 'Datum',
+'imagelist_name' => 'Název',
+'imagelist_user' => 'Uživatel',
+'imagelist_size' => 'Velikost (bajtů)',
+'imagelist_description' => 'Popis',
+'imagelist_search_for' => 'Hledat obrázek podle názvu:',
+
+# Mime search
+#
+'mimesearch' => 'Hledání podle MIME typu',
+'mimetype' => 'MIME typ:',
+'download' => 'download',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Nesledované stránky',
+
+# List redirects
+'listredirects' => 'Seznam přesměrování',
+
+# Unused templates
+'unusedtemplates' => 'Nepoužívané šablony',
+'unusedtemplatestext' => 'Tato stránka obsahuje seznam všech stran ve jmenném prostoru {{ns:-1}}, které nejsou vloženy do žádné jiné strany. Před jejich smazáním nezapomeňte zkontrolovat ostatní odkazy.',
+'unusedtemplateswlh' => 'ostatní odkazy',
+
+# Random redirect
+'randomredirect' => 'Náhodné přesměrování',
+
+# Statistics
+'statistics' => 'Statistika',
+'sitestats' => 'O serveru',
+'userstats' => 'O uživatelích',
+'sitestatstext' => "V databázi je celkem '''$1''' {{plural:$1|stránka|stránky|stránek}}. Toto číslo zahrnuje diskusní stránky, stránky o {{grammar:6sg|{{SITENAME}}}}, pahýly, přesměrování a další, které nejsou články v pravém slova smyslu. Kromě nich zbývá '''$2''' pravděpodobně {{plural:$2|skutečný článek|skutečné články|skutečných článků}}.
+
+{{plural:$8|Byl načten|Byly načteny|Bylo načteno}} '''$8''' {{plural:$8|obrázek|obrázky|obrázků}}.
+
+Od založení wiki bylo navštíveno celkem '''$3''' stránek a editováno '''$4'''krát. To činí v průměru '''$5''' editací na stránku a '''$6''' návštěv na editaci.
+
+Aktuální délka fronty údržby je '''$7'''.",
+'userstatstext' => "Je zde '''$1''' {{plural:$1|registrovaný uživatel|registrovaní uživatelé|registrovaných uživatelů}}, z toho '''$2''' ($4&nbsp;%) {{plural:$2|je správce|jsou $5|jsou $5}}.",
+'statistics-mostpopular' => 'Nejčtenější stránky',
+
+# Maintenance Page
+#
+'disambiguations' => 'Stránky odkazující na rozcestníky',
+'disambiguationspage' => '{{ns:10}}:Rozcestník',
+'disambiguationstext' => 'Následující články odkazují na rozcestník. Místo toho by měly by odkazovat na příslušný článek s konkrétním významem.<br /> Článek je považován za rozcestník v případě, že odkazuje na $1. Stránky z jiných jmenných prostorů zde <em>nejsou</em> uvedeny.',
+'doubleredirects' => 'Dvojitá přesměrování',
+'doubleredirectstext' => 'Každý řádek obsahuje odkaz na první a druhé přesměrování, plus první řádek textu druhého přesměrování, který obvykle ukazuje jméno „skutečného“ hlavního článku, na který by mělo první přesměrování odkazovat.',
+'brokenredirects' => 'Přerušená přesměrování',
+'brokenredirectstext' => ' Tato přesměrování vedou na neexistující články.',
+
+# Miscellaneous special pages
+#
+'lonelypages' => 'Sirotčí články',
+'lonelypagestext' => 'Na následující stránky na této wiki neodkazuje žádná jiná stránka.',
+'uncategorizedpages' => 'Nekategorizované stránky',
+'uncategorizedcategories' => 'Nekategorizované kategorie',
+'uncategorizedimages' => 'Nekategorizované soubory',
+'unusedimages' => 'Nepoužívané obrázky a soubory',
+'unusedcategories' => 'Nepoužívané kategorie',
+'popularpages' => 'Nejnavštěvovanější stránky',
+'wantedcategories' => 'Žádané kategorie',
+'wantedpages' => 'Žádoucí články',
+'mostlinked' => 'Nejodkazovanější stránky',
+'mostlinkedcategories' => 'Nejpoužívanější kategorie',
+'mostcategories' => 'Články s nejvyšším počtem kategorií',
+'mostimages' => 'Nejpoužívanější soubory',
+'mostrevisions' => 'Stránky s nejvíce revizemi',
+'allpages' => 'Všechny stránky',
+'prefixindex' => 'Seznam stránek podle začátku názvu',
+'randompage' => 'Náhodná stránka',
+'shortpages' => 'Nejkratší články',
+'longpages' => 'Nejdelší články',
+'deadendpages' => 'Slepé články',
+'deadendpagestext' => 'Následující stránky neodkazují na žádnou jinou stránku této wiki.',
+'listusers' => 'Uživatelé',
+'specialpages' => 'Speciální stránky',
+'spheading' => 'Speciální stránky pro všechny uživatele',
+'restrictedpheading' => 'Speciální stránky s omezeným přístupem',
+'recentchangeslinked' => 'Související změny',
+'rclsub' => '(stránek odkazovaných z „$1“)',
+'newpages' => 'Nejnovější články',
+'newpages-username' => 'Uživatelské jméno:',
+'ancientpages' => 'Nejdéle needitované stránky',
+'intl' => 'Mezijazykové odkazy',
+'move' => 'Přesunout',
+'movethispage' => 'Přesunout stránku',
+'unusedimagestext' => '<p>Jiné WWW stránky mohou odkazovat přímo pomocí URL, na takové odkazy se v tomto seznamu nebere zřetel.',
+'unusedcategoriestext' => 'Následující kategorie mají své stránky, ačkoli je žádná stránka ani jiná kategorie nepoužívá.',
+'booksources' => 'Zdroje knih',
+'categoriespagetext' => 'Ve wiki existují následující kategorie:',
+'data' => 'Data',
+'userrights' => 'Správa uživatelských skupin',
+'groups' => 'Uživatelské skupiny',
+'booksourcetext' => 'Následují odkazy na jiné WWW stránky, na kterých se prodávají knihy, nebo které mohou obsahovat další informace o knize, kterou hledáte. {{SITENAME}} nemá s těmito prodejnami žádný vztah, tyto odkazy nelze chápat jako doporučení.',
+'isbn' => 'ISBN',
+'alphaindexline' => 'od $1 do $2',
+'version' => 'Verze',
+'log' => 'Protokolovací záznamy',
+'alllogstext' => 'Společné zobrazení knihy nahrávek, smazání, zamčení, zablokování a uživatelských práv.
+Zobrazení můžete zůžit výběrem typu záznamu, uživatelského jména nebo dotčené stránky.',
+'logempty' => 'Protokol neobsahuje žádný odpovídající záznam.',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Uživatel:',
+'speciallogtitlelabel' => 'Název:',
+
+# Special:Allpages
+'nextpage' => 'Další stránka ($1)',
+'allpagesfrom' => 'Všechny stránky počínaje od:',
+'allarticles' => 'Všechny články',
+'allinnamespace' => 'Všechny stránky (jmenný prostor $1)',
+'allnotinnamespace' => 'Všechny stránky (mimo jmenný prostor $1)',
+'allpagesprev' => 'Předchozí',
+'allpagesnext' => 'Následující',
+'allpagessubmit' => 'Přejít',
+'allpagesprefix' => 'Zobrazit stránky začínající:',
+'allpagesbadtitle' => 'Zadaný název stránky nebyl platný nebo obsahoval předponu mezijazykového či interwiki odkazu. Možná obsahoval znaky, které v názvu nejsou dovoleny.',
+
+# Special:Listusers
+'listusersfrom' => 'Zobrazit uživatele počínaje od:',
+
+# Email this user
+#
+'mailnologin' => 'Bez odesílací adresy',
+'mailnologintext' => 'Pokud chcete posílat e-maily jiným uživatelům, musíte se [[Special:Userlogin|přihlásit]] a mít platnou e-mailovou adresu ve svém [[Special:Preferences|nastavení]].',
+'emailuser' => 'Poslat e-mail',
+'emailpage' => 'Poslat e-mail',
+'emailpagetext' => 'Pokud tento uživatel uvedl platnou e-mailovou adresu ve svém nastavení, tímto formulářem mu lze poslat zprávu. E-mailová adresa, kterou máte uvedenu v nastavení, se objeví jako adresa odesílatele pošty, aby adresát mohl odpovědět.',
+'usermailererror' => 'Chyba poštovního programu:',
+'defemailsubject' => 'E-mail z {{grammar:2sg|{{SITENAME}}}}',
+'noemailtitle' => 'Bez e-mailové adresy',
+'noemailtext' => 'Tento uživatel buď nezadal platnou adresu nebo zakázal přijímat zprávy od jiných uživatelů.',
+'emailfrom' => 'Od',
+'emailto' => 'Komu',
+'emailsubject' => 'Předmět',
+'emailmessage' => 'Zpráva',
+'emailsend' => 'Odeslat',
+'emailsent' => 'Zpráva odeslána',
+'emailsenttext' => 'Váš e-mail byl odeslán.',
+
+# Watchlist
+#
+'watchlist' => 'Sledované stránky',
+'watchlistfor' => "(uživatele '''$1''')",
+'nowatchlist' => 'Na svém seznamu sledovaných stránek nemáte žádné položky.',
+'watchlistanontext' => 'Pro prohlížení či úpravu seznamu sledovaných stránek se musíte $1.',
+'watchlistcount' => "'''Na svém seznamu sledovaných stránek máte $1 {{plural:$1|položku|položky|položek}} včetně diskusí.'''",
+'clearwatchlist' => 'Smazat seznam sledovaných stránek',
+'watchlistcleartext' => 'Jste si jisti, že chcete odstranit tyto položky?',
+'watchlistclearbutton' => 'Smazat',
+'watchlistcleardone' => 'Váš seznam sledovaných stránek byl smazán, {{plural:$1|byla odstraněna jedna položka|byly odstraněny $1 položky|bylo odstraněno $1 položek}}.',
+'watchnologin' => 'Nejste přihlášen(a)',
+'watchnologintext' => 'Pro sledování oblíbených stránek se musíte [[Special:Userlogin|přihlásit]].',
+'addedwatch' => 'Přidáno k oblíbeným',
+'addedwatchtext' => 'Stránka „[[:$1]]“ byla přidána mezi stránky, které [[Special:Watchlist|sledujete]]. Budoucí změny této stránky se objeví <b>tučně</b> v [[Special:Recentchanges|seznamu posledních změn]], aby bylo snadnější si jí povšimnout. Pokud budete později chtít stránku ze seznamu sledovaných smazat, klikněte na „Nesledovat tuto stránku“ v liště nástrojů.',
+'removedwatch' => 'Vyřazeno ze seznamu sledovaných stránek',
+'removedwatchtext' => 'Stránka „$1“ byla vyřazena z vašeho seznamu sledovaných stránek.',
+'watch' => 'Sledovat',
+'watchthispage' => 'Sledovat tuto stránku',
+'unwatch' => 'Nesledovat',
+'unwatchthispage' => 'Nesledovat tuto stránku',
+'notanarticle' => 'Toto není článek',
+'watchnochange' => 'Žádná ze sledovaných položek nebyla editována v době, která je zobrazena.',
+'watchdetails' => '* Na svém seznamu sledovaných stránek máte $1 {{plural:$1|stránku|stránky|stránek}}
+* [[Special:Watchlist/edit|Ukázat a editovat kompletní seznam]].
+* [[Special:Watchlist/clear|Odstranit všechny položky]]',
+'wlheader-enotif' => '* Upozorňování e-mailem je zapnuto.',
+'wlheader-showupdated' => "* Stránky, které se změnily od vaší poslední návštěvy, jsou zobrazeny '''tučně'''",
+'watchmethod-recent'=> 'hledají se sledované stránky mezi posledními změnami',
+'watchmethod-list' => 'hledají se nejnovější editace sledovaných stránek',
+'removechecked' => 'Vyřadit označené položky ze seznamu sledovaných',
+'watchlistcontains' => 'Na svém seznamu sledovaných stránek máte $1 {{plural:$1|položku|položky|položek}}.',
+'watcheditlist' => 'Tady je abecední seznam vašich sledovaných stránek. Zaškrtněte stránky, které chcete smazat z vašeho seznamu a klikněte na tlačítko „vyřadit označené“ na konci obrazovky. S každou stránkou je vždy sledována i její diskusní stránka a naopak.',
+'removingchecked' => 'Požadované položky se odstraňují ze seznamu sledovaných…',
+'couldntremove' => 'Nepodařilo se odstranit položku „$1“…',
+'iteminvalidname' => 'Problém s položkou „$1“, neplatný název…',
+'wlnote' => 'Níže je {{plural:$1|poslední změna|poslední $1 změny|posledních $1 změn}} za {{plural:$2|poslední|poslední|posledních}} <b>$2</b> {{plural:$2|hodinu|hodiny|hodin}}.',
+'wlshowlast' => 'Ukázat posledních $1 hodin $2 dnů $3',
+'wlsaved' => 'Toto je uložená verze vašeho seznamu sledovaných stránek.',
+'wlhideshowown' => '$1 moje editace.',
+'wlhideshowbots' => '$1 roboty.',
+'wldone' => 'Hotovo.',
+
+'enotif_mailer' => 'Zasílač hlášení {{grammar:2sg|{{SITENAME}}}}',
+'enotif_reset' => 'Vynulovat všechny příznaky (nastavit stav na „navštíveno“)',
+'enotif_newpagetext'=> 'Toto je nová stránka.',
+'changed' => 'změněno',
+'created' => 'vytvořeno',
+'enotif_subject' => '$PAGEEDITOR upravil stránku $PAGETITLE na {{grammar:6sg|{{SITENAME}}}}.',
+'enotif_lastvisited' => 'Vizte $1 pro seznam všech změn od minulé návštěvy.',
+'enotif_body' => 'Vážený uživateli $WATCHINGUSERNAME,
+
+$PAGEEDITDATE upravil $PAGEEDITOR stránku $PAGETITLE, vizte $PAGETITLE_URL pro aktuální verzi.
+
+$NEWPAGE
+
+Shrnutí editace: $PAGESUMMARY $PAGEMINOREDIT
+Uživatele, který změnu provedl, můžete kontaktovat:
+e-mailem: $PAGEEDITOR_EMAIL
+na wiki: $PAGEEDITOR_WIKI
+
+Dokud stránku nenavštívíte, nebudou vám zasílána další oznámení o změnách této stránky, případně do doby, než vynulujete příznaky ve svém seznamu sledovaných stránek.
+
+ S pozdravem váš zasílač hlášení {{grammar:2sg|{{SITENAME}}}}
+
+--
+Pro změnu nastavení navštivte
+{{fullurl:Special:Watchlist/edit}}
+
+Rady a kontakt:
+{{fullurl:Project:Potřebuji pomoc}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Smazat stránku',
+'confirm' => 'Potvrdit',
+'excontent' => 'obsah byl: „$1“',
+'excontentauthor' => "obsah byl: „$1“ (a jediným přispěvatelem byl „$2“)",
+'exbeforeblank' => 'obsah před vyprázdněním byl: „$1“',
+'exblank' => 'stránka byla prázdná',
+'confirmdelete' => 'Potvrdit smazání',
+'deletesub' => '(Maže se „$1“)',
+'historywarning' => ' Varování: Stránka, kterou chcete smazat, má historii:&nbsp;',
+'confirmdeletetext' => 'Chystáte se trvale smazat z databáze stránku nebo obrázek s celou jeho historií. Prosím potvrďte, že to opravdu chcete učinit, že si uvědomujete důsledky a že je to v souladu s [[Project:Pravidla|pravidly]].',
+'actioncomplete' => 'Provedeno',
+'deletedtext' => ' Stránka nebo soubor „$1“ byla smazána; $2 zaznamenává poslední smazání.',
+'deletedarticle' => 'maže „$1“',
+'dellogpage' => 'Kniha smazaných stránek',
+'dellogpagetext' => 'Zde je seznam posledních smazaných z databáze. Všechny časové údaje uvedeny podle časového pásma serveru (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'Kniha smazaných stránek',
+'reverted' => 'Obnovení předchozí verze',
+'deletecomment' => 'Důvod smazání',
+'imagereverted' => 'Obnovení předchozí verze úspěšně provedeno.',
+'rollback' => 'Vrátit zpět editace',
+'rollback_short' => 'Vrátit zpět',
+'rollbacklink' => 'vrácení zpět',
+'rollbackfailed' => 'Nešlo vrátit zpět',
+'cantrollback' => 'Nelze vrátit zpět poslední editaci, neboť poslední přispěvatel je jediným autorem tohoto článku.',
+'alreadyrolled' => 'Nelze vrátit zpět poslední editaci [[:$1]] od [[User:$2|$2]] ([[User talk:$2|Diskuse]]), protože někdo jiný již článek editoval nebo vrátil tuto změnu zpět. Poslední editace byla od [[User:$3|$3]] ([[User talk:$3|Diskuse]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Shrnutí editace bylo: „<i>$1</i>“.',
+'revertpage' => 'Editace uživatele „$2“ vrácena do předchozího stavu, jehož autorem je „$1“.',
+'sessionfailure' => 'Zřejmě je nějaký problém s vaším přihlášením;
+vámi požadovaná činnost byla stornována jako prevence před neoprávněným přístupem.
+Stiskněte tlačítko „zpět“, obnovte stránku, ze které jste přišli a zkuste činnost znovu.',
+'protectlogpage' => 'Kniha zamčení',
+'protectlogtext' => 'Níže je uveden seznam všech zamčení a odemčení stránek.',
+'protectedarticle' => 'zamyká „[[$1]]“',
+'unprotectedarticle' => 'odemyká „[[$1]]“',
+'protectsub' =>'(Zamyká se „$1“)',
+'confirmprotecttext' => 'Opravdu chcete zamknout tuto stránku?',
+'confirmprotect' => 'Potvrdit zamčení',
+'protectmoveonly' => 'Bránit pouze proti přesunutí',
+'protectcomment' => 'Důvod zamčení',
+'unprotectsub' => '(Odemyká se „$1“)',
+'confirmunprotecttext' => 'Opravdu chcete odemknout tuto stránku?',
+'confirmunprotect' => 'Potvrdit odemčení',
+'unprotectcomment' => 'Důvod odemčení',
+'protect-unchain' => 'Oddělené ovládání zámku přesunů',
+'protect-text' => 'Zde si můžete prohlédnout či změnit nastavení zámků stránky <strong>$1</strong>.',
+'protect-viewtext' => 'Nemáte dostatečná oprávnění ke změně zámků stran. Zde si můžete prohlédnout aktuální nastavení stránky [[$1]]:',
+'protect-default' => '(odemčeno)',
+'protect-level-autoconfirmed' => 'Pouze registrovaní',
+'protect-level-sysop' => 'Pouze správci',
+
+# restrictions (nouns)
+'restriction-edit' => 'Editace',
+'restriction-move' => 'Přesun',
+
+# Undelete
+'undelete' => 'Smazané stránky',
+'undeletepage' => 'Prohlédnout si a obnovit smazanou stránku',
+'viewdeletedpage' => 'Zobrazení smazané stránky',
+'undeletepagetext' => 'Tyto stránky jsou smazány, avšak dosud archivovány, a proto je možno je obnovit. Archiv může být pravidelně vyprazdňován.',
+'undeleteextrahelp' => "Pro úplné obnovení stránky s kompletní historií ponechte všechny čtverečky nezaškrtnuté a klikněte na '''''Obnovit'''''. Pro částečné obnovení zašrktněte čtverečky u obnovovaných revizí a klikněte na '''''Obnovit'''''. Kliknutí na '''''Reset''''' vyprázdní komentář a zruší všechna zaškrtnutí.",
+'undeletearticle' => 'Obnovit smazaný článek',
+'undeleterevisions' => '$1 {{plural:$1|verze|verze|verzí}} je archivováno',
+'undeletehistory' => 'Pokud stránku obnovíte, všechny revize budou v historii obnoveny. Pokud byla vytvořena nová stránka se stejným jménem jako smazaná, obnovené revize se zapíší na starší místo v historii a nová stránka nebude nahrazena.',
+'undeletehistorynoadmin' => 'Tato stránka byla smazána. Důvod smazání je uveden níže, spolu s informacemi o uživatelích, kteří tuto stránku před smazáním editovali. Samotný text stránky je dostupný pouze správcům.',
+'undeleterevision' => 'Smazaná verze z $1',
+'undeletebtn' => 'Obnovit',
+'undeletereset' => 'Reset',
+'undeletecomment' => 'Komentář:',
+'undeletedarticle' => 'obnovuje „[[$1]]“',
+'undeletedrevisions' => '{{plural:$1|Obnovena $1 verze|Obnoveny $1 verze|Obnoveno $1 verzí}}',
+'undeletedrevisions-files' => '{{plural:$1|Obnovena $1 verze|Obnoveny $1 verze|Obnoveno $1 verzí}} a $2 {{plural:$2|soubor|soubory|souborů}}',
+'undeletedpage' => '<big>Stránka $1 byla obnovena</big>
+
+Záznam o posledních mazáních a obnoveních najdete v [[Special:Log/delete|knize smazaných stránek]].',
+'undeletedfiles' => '{{plural:$1|Obnoven jeden soubor|Obnoveny $1 soubory|Obnoveno $1 souborů}}',
+'cannotundelete' => 'Stránku se nepodařilo obnovit; někdo jiný ji již možná obnovil.',
+
+# Namespace form on various pages
+'namespace' => 'Jmenný prostor:',
+'invert' => 'Obrátit výběr',
+
+# Contributions
+#
+'contributions' => 'Příspěvky uživatele',
+'mycontris' => 'Mé příspěvky',
+'contribsub' => '$1',
+'nocontribs' => 'Nenalezeny žádné změny vyhovující kritériím.',
+'ucnote' => 'Níže jsou uživatelovy poslední <strong>$1</strong> změny během {{plural:$1|posledního|posledních|posledních}} <strong>$2</strong> {{plural:$1|dne|dnů|dnů}}.',
+'uclinks' => 'Ukaž posledních $1 změn; ukaž posledních $2 dnů.',
+'uctop' => ' (aktuální)',
+'newbies' => 'nováčci',
+
+'sp-newimages-showfrom' => 'Zobrazit nové obrázky počínaje od $1',
+
+'sp-contributions-newest' => 'Nejnovější',
+'sp-contributions-oldest' => 'Nejstarší',
+'sp-contributions-newer' => '$1 novějších',
+'sp-contributions-older' => '$1 starších',
+'sp-contributions-newbies-sub' => 'Noví uživatelé',
+
+# What links here
+#
+'whatlinkshere' => 'Odkazuje sem',
+'notargettitle' => 'Bez cílové stránky',
+'notargettext' => 'Této funkci musíte určit cílovou stránku nebo uživatele.',
+'linklistsub' => '(Seznam odkazů)',
+'linkshere' => "Na '''[[:$1]]''' odkazují tyto stránky:",
+'nolinkshere' => "Žádná stránka na '''[[:$1]]''' neodkazuje.",
+'isredirect' => 'přesměrování',
+'istemplate' => 'vložení',
+
+# Block/unblock IP
+#
+'blockip' => 'Zablokovat uživatele',
+'blockiptext' => 'Tento formulář slouží k zablokování editací z konkrétní IP adresy nebo uživatelského jména. Toto by mělo být používáno jen v souladu s [[{{ns:4}}:blokování|pravidly blokování]]. Udejte přesný důvod níže (například ocitujte, které stránky byly poškozeny). Pro odblokování se podívejte na [[Special:Ipblocklist|seznam blokovaných IP adres]].',
+'ipaddress' => 'IP adresa',
+'ipadressorusername' => 'IP adresa nebo uživatelské jméno',
+'ipbexpiry' => 'Čas vypršení',
+'ipbreason' => 'Důvod',
+'ipbanononly' => 'Zablokovat pouze anonymní uživatele',
+'ipbcreateaccount' => 'Nedovolit registraci nových uživatelů',
+'ipbsubmit' => 'Zablokovat',
+'ipbother' => 'Jiný čas vypršení',
+'ipboptions' => '2 hodiny:2 hours,1 den:1 day,3 dny:3 days,1 týden:1 week,2 týdny:2 weeks,1 měsíc:1 month,3 měsíce:3 months,6 měsíců:6 months,1 rok:1 year,do odvolání:infinite',
+'ipbotheroption' => 'jiný',
+'badipaddress' => 'Neplatná IP adresa',
+'blockipsuccesssub' => 'Zablokování uspělo',
+'blockipsuccesstext' => 'Uživatel „[[Special:Contributions/$1|$1]]“ je zablokován. <br />Podívejte se na [[Special:Ipblocklist|seznam zablokovaných]], [[Special:Log/block|kniha zablokování]] zaznamenává všechny podobné úkony.',
+'unblockip' => 'Odblokovat uživatele',
+'unblockiptext' => 'Tímto formulářem je možno obnovit právo blokované IP adresy či uživatele opět přispívat do {{grammar:2sg|{{SITENAME}}}}.',
+'ipusubmit' => 'Odblokovat',
+'unblocked' => '[[User:$1|$1]] byl odblokován',
+'ipblocklist' => 'Seznam blokovaných IP adres',
+'blocklistline' => '$1 $2 zablokoval $3 ($4)',
+'infiniteblock' => 'do odvolání',
+'expiringblock' => 'čas vypršení: $1',
+'anononlyblock' => 'jen anonymové',
+'createaccountblock' => 'tvorba účtů zakázána',
+'ipblocklistempty' => 'Seznam blokování je momentálně prázdný.',
+'blocklink' => 'zablokovat',
+'unblocklink' => 'uvolnit',
+'contribslink' => 'příspěvky',
+'autoblocker' => 'Automaticky zablokováno, protože sdílíte IP adresu s „$1“. Důvod zablokování tohoto uživatele: „$2“.',
+'blocklogpage' => 'Kniha zablokování',
+'blocklogentry' => 'zablokovává „[[$1]]“ s časem vypršení $2',
+'blocklogtext' => 'Toto je kniha úkonů blokování a odblokování uživatelů. Automaticky blokované IP adresy nejsou vypsány. Podívejte se na [[Special:Ipblocklist|seznam blokování IP]] s výčtem aktuálních zákazů a blokování.',
+'unblocklogentry' => 'odblokovává „$1“',
+'range_block_disabled' => 'Blokování rozsahů IP adres je zakázáno.',
+'ipb_expiry_invalid' => 'Neplatný čas vypršení.',
+'ipb_already_blocked' => '„$1“ již je zablokován.',
+'ip_range_invalid' => 'Neplatný IP rozsah.',
+'proxyblocker' => 'Blokování proxy serverů',
+'ipb_cant_unblock' => 'Chyba: Blokování s ID $1 nebylo nalezeno. Uživatel již možná byl odblokován.',
+'proxyblockreason' => 'Vaše IP adresa byla zablokována, protože funguje jako [[w:cs:Otevřený proxy server|otevřený proxy server]]. Kontaktujte svého poskytovatele internetového připojení nebo technickou podporu a informujte je o tomto vážném bezpečnostním problému.',
+'proxyblocksuccess' => 'Hotovo.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Vaše IP adresa je uvedena na seznamu [http://www.sorbs.net/ SORBS] DNSBL jako [[w:cs:Otevřený proxy server|otevřený proxy server]].',
+'sorbs_create_account_reason' => 'Vaše IP adresa je uvedena na seznamu [http://www.sorbs.net/ SORBS] DNSBL jako [[w:cs:Otevřený proxy server|otevřený proxy server]]. Z této adresy si nemůžete založit účet',
+
+# Developer tools
+#
+'lockdb' => 'Zamknout databázi',
+'unlockdb' => 'Odemknout databázi',
+'lockdbtext' => 'Pokud zamknete databázi, znemožníte ostatním editovat, upravovat nastavení, sledované stránky apod. Potvrďte, že to opravdu chcete udělat a že odemknete databázi hned po opravách.',
+'unlockdbtext' => ' Pokud odemknete databázi, umožníte ostatním editovat, upravovat nastavení, sledované stránky apod. Potvrďte, že to opravdu chcete udělat.',
+'lockconfirm' => 'Ano, opravdu chci zamknout databázi.',
+'unlockconfirm' => 'Ano, opravdu chci odemknout databázi.',
+'lockbtn' => 'Zamknout databázi',
+'unlockbtn' => 'Odemknout databázi',
+'locknoconfirm' => 'Nebylo zaškrtnuto políčko potvrzení.',
+'lockdbsuccesssub' => 'Databáze uzamčena',
+'unlockdbsuccesssub' => 'Databáze odemčena',
+'lockdbsuccesstext' => 'Databáze {{grammar:2sg|{{SITENAME}}}} byla úspěšně uzamčena.
+<br />Nezapomeňte ji po dokončení údržby [[Special:Unlockdb|odemknout]].',
+'unlockdbsuccesstext' => 'Databáze {{grammar:2sg|{{SITENAME}}}} je odemčena.',
+'lockfilenotwritable' => 'Do souboru zámku databáze nelze zapisovat. Pro zamčení či odemčení databáze musí mít webový server právo zápisu do tohoto souboru.',
+'databasenotlocked' => 'Databáze není uzamčena.',
+
+# Make sysop
+'makesysoptitle' => 'Učinit uživatele správcem',
+'makesysoptext' => 'Tento formulář je používán byrokraty pro změnu obyčejného uživatele na správce. Vepište jméno uživatele do políčka a stiskněte tlačítko.',
+'makesysopname' => 'Jméno uživatele:',
+'makesysopsubmit' => 'Učinit tohoto uživatele správcem',
+'makesysopok' => '<b>Uživatel „$1“ nyní patří mezi správce</b>',
+'makesysopfail' => '<b>Uživatel „$1“ nemůže být učiněn správcem. (Vložili jste jeho jméno správně?)</b>',
+'setbureaucratflag' => 'Nastavit příznak byrokrata',
+'rightslogtext' => 'Toto je záznam změn uživatelských oprávnění.',
+'rightslog' => 'Kniha práv uživatelů',
+'rightslogtext' => 'Toto je záznam změn uživatelských práv.',
+'rightslogentry' => 'změnil pro $1 členství ve skupinách z $2 na $3',
+'rights' => 'Oprávnění:',
+'set_user_rights' => 'Nastavit uživatelova oprávnění',
+'user_rights_set' => '<b>Uživatelova práva k „$1“ aktualizována</b>',
+'set_rights_fail' => '<b>Uživatelova práva k „$1“ nemohla být nastavena. (Vložili jste jeho jméno správně?)</b>',
+'makesysop' => 'Učinit uživatele správcem',
+'already_sysop' => 'Tento uživatel už je správce.',
+'already_bureaucrat' => 'Tento uživatel už je byrokrat.',
+'rightsnone' => '(žádné)',
+
+# Move page
+#
+'movepage' => 'Přesunout stránku',
+'movepagetext' => 'Pomocí tohoto formuláře změníte název stránky a přesunete i celou její historii pod nový název. Původní název se stane přesměrováním na nový název. Odkazy na předchozí název <i>nebudou</i> změněny. <b>VAROVÁNÍ!</b> Toto může drastická a nečekaná změna pro oblíbené stránky. Ujistěte se, prosím, že chápete důsledky vašeho kroku před tím, než změnu provedete.',
+'movepagetalktext' => "Přidružená diskusní stránka, pokud existuje, bude automaticky přesunuta společně se stránkou, '''pokud:'''
+* Dosud neexistuje neprázdná diskusní stránka pod novým jménem a
+* nezrušíte křížek ve formuláři.
+
+V těchto případech musíte přesunout nebo sloučit stránky manuálně, jestliže si to přejete.",
+'movearticle' => 'Přesunout stránku',
+'movenologin' => 'Nejste přihlášen(a)!',
+'movenologintext' => 'Pro přesouvání stránek se musíte [[Special:Userlogin|přihlásit]].',
+'newtitle' => 'Na nový název',
+'movepagebtn' => 'Přesunout stránku',
+'pagemovedsub' => 'Úspěšně přesunuto',
+'pagemovedtext' => "Stránka „[[$1]]“ přesunuta na „[[$2]]“.
+
+'''Nyní''' následujte odkaz [[{{ns:-1}}:Whatlinkshere/$1]]: pokud se v seznamu vyskytnou nějaké přesměrovače, je třeba je upravit tak, aby ukazovaly na nový název ($2), jinak nebudou fungovat.",
+'articleexists' => 'Takto nazvaná stránka již existuje, nebo Vámi zvolený název je neplatný. Zvolte jiný název.',
+'talkexists' => 'Stránka byla přesunuta úspěšně, ale diskusní stránka přesunuta být nemohla, neboť pod novým názvem již nějaká stránka existuje. Proveďte prosím ruční sloučení.',
+'movedto' => 'přesunuto na',
+'movetalk' => 'Přesunout také diskusní stránku, existuje-li.',
+'talkpagemoved' => 'Diskusní stránka byla také přesunuta.',
+'talkpagenotmoved' => 'Diskusní stránka <strong>nebyla</strong> přesunuta.',
+'1movedto2' => 'Stránka [[$1]] přemístěna na stránku [[$2]]',
+'1movedto2_redir' => 'Stránka [[$1]] přemístěna na stránku [[$2]] s výměnou přesměrování',
+'movelogpage' => 'Kniha přesunů',
+'movelogpagetext' => 'Toto je záznam všech přesunů stránek.',
+'movereason' => 'Důvod',
+'revertmove' => 'vrátit',
+'delete_and_move' => 'Smazat a přesunout',
+'delete_and_move_text' =>
+'==Je potřeba smazání==
+
+Cílová stránka „[[$1]]“ již existuje. Přejete si ji smazat pro uvolnění místa pro přesun?',
+'delete_and_move_confirm' => 'Ano, smazat cílovou stránku',
+'delete_and_move_reason' => 'Smazáno pro umožnění přesunu',
+'selfmove' => 'Původní a nový název jsou stejné; nelze stránku přesunout na sebe samu.',
+'immobile_namespace' => 'Nový název je speciálního druhu; z a do tohoto jmenného prostoru nelze stránky přesouvat.',
+
+# Export
+
+'export' => 'Exportovat stránky',
+'exporttext' => 'Můžete exportovat text a historii editací některé stránky nebo sady stránek zabalené v XML. Výsledný soubor lze naimportovat do jiné wiki, která běží na software MediaWiki, pomocí stránky [[{{ns:Special}}:Import]].
+
+Do níže uvedeného editačního pole zadejte názvy stránek, které chcete exportovat; každý řádek jeden název. Zvolte také, zda se mají exportovat i starší verze stránky včetně informací v historii editací, nebo jen aktuální verze s informací o poslední editaci.',
+'exportcuronly' => 'Zahrnout jen současnou verzi, ne plnou historii',
+'exportnohistory' => "----
+'''Poznámka:''' export plných historií protřednictvím tohoto formuláře byl z výkonnostních důvodů zakázán.",
+'export-submit' => 'Exportovat',
+
+# Namespace 8 related
+
+'allmessages' => 'Všechna systémová hlášení',
+'allmessagesname' => 'Označení hlášení',
+'allmessagesdefault' => 'Původní text',
+'allmessagescurrent' => 'Aktuální text',
+'allmessagestext' => 'Toto je seznam všech hlášení dostupných ve jmenném prostoru MediaWiki.',
+'allmessagesnotsupportedUI' => 'Váš aktuální jazyk rozhraní <b>$1</b> není na tomto serveru pro {{ns:-1}}:AllMessages podporován.',
+'allmessagesnotsupportedDB' => '{{ns:-1}}:AllMessages není podporováno, neboť wgUseDatabaseMessages je vypnuto.',
+'allmessagesfilter' => 'Filtr názvů hlášení:',
+'allmessagesmodified' => 'Zobrazit pouze upravená hlášení',
+
+# Thumbnails
+
+'thumbnail-more' => 'Zvětšit',
+'missingimage' => "<b>Chybějící obrázek</b><br /><i>$1</i>",
+'filemissing' => 'Chybějící soubor',
+'thumbnail_error' => 'Chyba při vytváření náhledu: $1',
+
+# Special:Import
+'import' => 'Importovat stránky',
+'importinterwiki' => 'Import mezi wiki',
+'import-interwiki-text' => 'Pro import zvolte zdrojovou wiki a název stránky. Data revizí a jména autorů budou zachována. Všechny importy se zaznamenávají do [[Special:Log/import|knihy importů]].',
+'import-interwiki-history' => 'Zkopírovat všechny historické verze této stránky',
+'import-interwiki-submit' => 'Importovat',
+'import-interwiki-namespace' => 'Stránky přenést do jmenného prostoru:',
+'importtext' => 'Prosím exportujte soubor ze zdrojové wiki pomocí nástroje {{ns:-1}}:Export, uložte ji na svůj disk a nahrajte ji sem.',
+'importstart' => 'Stránky se importují…',
+'import-revision-count' => '$1 {{PLURAL:$1|revize|revize|revizí}}',
+'importnopages' => 'Není co importovat.',
+'importfailed' => 'Import selhal: $1',
+'importunknownsource' => 'Neznámý typ zdroje importu',
+'importcantopen' => 'Nepodařilo se otevřít importní soubor',
+'importbadinterwiki' => 'Neplatný interwiki odkaz',
+'importnotext' => 'Prázdný nebo žádný text',
+'importsuccess' => 'Import byl úspěšný!',
+'importhistoryconflict' => 'Existuje konflikt mezi historiemi verzí. Možná, že tato stránka byla již importována dříve.',
+'importnosources' => 'Nebyly definovány žádné zdroje pro import mezi wiki a přímé načítání historie je vypnuto.',
+'importnofile' => 'Nebyl načten importní soubor.',
+'importuploaderror' => 'Nepodařilo se načíst importní soubor; možná jeho velikost přesahuje dovolenou mez.',
+
+# import log
+'importlogpage' => 'Kniha importů',
+'importlogpagetext' => 'Na této stránce se zobrazují správcovské importy stránek včetně historie editací z jiných wiki.',
+'import-logentry-upload' => 'naimportoval [[$1]] načtením souboru',
+'import-logentry-upload-detail' => '$1 {{PLURAL:$1|revizi|revize|revizí}}',
+'import-logentry-interwiki' => 'přenesl $1',
+'import-logentry-interwiki-detail' => '$1 {{PLURAL:$1|revizi|revize|revizí}} z $2',
+
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-watch' => 'w',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Hledat na této wiki [alt-f]',
+'tooltip-minoredit' => 'Označit jako malou editaci [alt-i]',
+'tooltip-save' => 'Uložit vaše úpravy [alt-s]',
+'tooltip-preview' => 'Prohlédnout vaše úpravy, prosíme použijte tuto funkci před uložením! [alt-p]',
+'tooltip-diff' => 'Zobrazit, jaké změny jste v textu provedli. [alt-v]',
+'tooltip-compareselectedversions' => 'Porovnat rozdíly mezi zvolenými verzemi této stránky. [alt-v]',
+'tooltip-watch' => 'Přidat stránku do seznamu sledovaných [alt-w]',
+
+# stylesheets
+'common.css' => '/* Zde uvedené CSS bude ovlivňovat všechny styly */',
+'monobook.css' => '/* Zde uvedené CSS bude ovlivňovat pouze styl „monobook“ */',
+
+# Metadata
+'nodublincore' => 'Na tomto serveru je vypnuto generování metadat Dublin Core RDF.',
+'nocreativecommons' => 'Na tomto server je vypnuto generování metadat Creative Commons RDF.',
+'notacceptable' => 'Tento wiki server není schopen poskytnout data ve formátu, který by váš klient byl schopen přečíst.',
+
+# Attribution
+
+'anonymous' => "Anonymní uživatel(é) {{SITENAME}}",
+'siteuser' => "Uživatel {{SITENAME}} $1",
+'lastmodifiedatby' => 'Tuto stránku naposledy měnil $3 v $2, $1.',
+'and' => 'a',
+'othercontribs' => 'Založeno na textu od uživatele $1.',
+'others' => 'další',
+'siteusers' => "Uživatel(é) {{SITENAME}} $1",
+'creditspage' => 'Zásluhy za stránku',
+'nocredits' => 'K této stránce neexistuje informace o zásluhách.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Protispamový filtr',
+'spamprotectiontext' => 'Stránka, kterou jste se pokusil(a) uložit, byla zablokována protispamovým filtrem. Pravděpodobnou příčinou je odkaz na externí stránky. Může vás zajímat následující regulární výraz, který označuje v současné době blokované stránky:',
+'spamprotectionmatch' => 'Následující text spustil náš filtr proti spamu: $1',
+'spambot_username' => 'Systémový čistič spamu',
+'spam_reverting' => 'Revert na poslední verzi neobsahující odkazy na $1',
+'spam_blanking' => 'Všechny revize obsahovaly odkazy na $1, vyprázdněno',
+
+# Categories
+
+'subcategorycount' => 'Tato kategorie obsahuje $1 {{plural:$1|podkategorii|podkategorie|podkategorií}}.',
+'categoryarticlecount' => 'Tato kategorie obsahuje $1 {{plural:$1|článek|články|článků}}.',
+'listingcontinuesabbrev' => 'pokrač.',
+
+# Info page
+'infosubtitle' => 'Informace o stránce',
+'numedits' => 'Počet editací (článek): $1',
+'numtalkedits' => 'Počet editací (diskusní stránka): $1',
+'numwatchers' => 'Počet sledujících uživatelů: $1',
+'numauthors' => 'Počet různých autorů (článek): $1',
+'numtalkauthors' => 'Počet různých autorů (diskusní stránka): $1',
+
+# Math options
+'mw_math_png' => 'Vždy jako PNG',
+'mw_math_simple' => 'Jednoduché jako HTML, jinak PNG',
+'mw_math_html' => 'HTML pokud je to možné, jinak PNG',
+'mw_math_source' => 'Ponechat jako TeX (pro textové prohlížeče)',
+'mw_math_modern' => 'Doporučené nastavení pro moderní prohlížeče',
+'mw_math_mathml' => 'MathML pokud je podporováno (experimentální)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Označit jako prověřené',
+'markaspatrolledtext' => 'Označit tento článek jako prověřený',
+'markedaspatrolled' => 'Označeno jako prověřené',
+'markedaspatrolledtext' => 'Vybraná verze byla označena jako prověřená.',
+'rcpatroldisabled' => 'Hlídka posledních změn vypnuta',
+'rcpatroldisabledtext' => 'Hlídka posledních změn je momentálně vypnuta.',
+'markedaspatrollederror' => 'Nelze označit za prověřené',
+'markedaspatrollederrortext' => 'Musíte zvolit revizi, která má být označena jako prověřená.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* tooltips and access keys */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','Moje uživatelská stránka');
+ta['pt-anonuserpage'] = new Array('.','Uživatelská stránka pro IP adresu, ze které editujete');
+ta['pt-mytalk'] = new Array('n','Moje diskusní stránka');
+ta['pt-anontalk'] = new Array('n','Diskuse o editacích provedených z této IP adresy');
+ta['pt-preferences'] = new Array('','Moje preference');
+ta['pt-watchlist'] = new Array('l','Seznam stránek, jejichž změny sleduji');
+ta['pt-mycontris'] = new Array('y','Seznam mých příspěvků');
+ta['pt-login'] = new Array('o','Doporučujeme vám přihlásit se, ovšem není to povinné.');
+ta['pt-anonlogin'] = new Array('o','Doporučujeme vám přihlásit se, ovšem není to povinné.');
+ta['pt-logout'] = new Array('','Odhlásit se');
+ta['ca-talk'] = new Array('t','Diskuse ke stránce');
+ta['ca-edit'] = new Array('e','Tuto stránku můžete editovat. Prosíme použijte tlačítko Ukázat náhled před uložením.');
+ta['ca-addsection'] = new Array('+','Přidat k této diskusi svůj komentář.');
+ta['ca-viewsource'] = new Array('e','Tato stránka je zamčena. Můžete si prohlédnout její zdrojový kód.');
+ta['ca-history'] = new Array('h','Starší verze této stránky.');
+ta['ca-protect'] = new Array('=','Zamknout tuto stránku.');
+ta['ca-delete'] = new Array('d','Smazat tuto stránku.');
+ta['ca-undelete'] = new Array('d','Obnovit editace této stránky provedené před jejím smazáním.');
+ta['ca-move'] = new Array('m','Přesunout tuto stránku');
+ta['ca-watch'] = new Array('w','Přidat tuto stránku mezi sledované');
+ta['ca-unwatch'] = new Array('w','Vyjmout tuto stránku ze sledovaných');
+ta['search'] = new Array('f','Hledat na této wiki');
+ta['p-logo'] = new Array('','Hlavní strana');
+ta['n-mainpage'] = new Array('z','Navštívit Hlavní stranu');
+ta['n-portal'] = new Array('','O projektu, jak můžete pomoci, kde hledat');
+ta['n-currentevents'] = new Array('','Informace o aktuálních událostech');
+ta['n-recentchanges'] = new Array('r','Seznam posledních změn na této wiki');
+ta['n-randompage'] = new Array('x','Přejít na náhodně vybranou stránku');
+ta['n-help'] = new Array('','Místo, kde najdete pomoc');
+ta['n-sitesupport'] = new Array('','Podpořte nás');
+ta['t-whatlinkshere'] = new Array('j','Seznam všech wikistránek, které sem odkazují');
+ta['t-recentchangeslinked'] = new Array('k','Nedávné změny stránek, které sem odkazují');
+ta['feed-rss'] = new Array('','RSS kanál pro tuto stránku');
+ta['feed-atom'] = new Array('','Atom kanál pro tuto stránku');
+ta['t-contributions'] = new Array('','Prohlédnout si seznam příspěvků tohoto uživatele');
+ta['t-emailuser'] = new Array('','Poslat e-mail tomuto uživateli');
+ta['t-upload'] = new Array('u','Nahrát obrázky či jiná multimédia');
+ta['t-specialpages'] = new Array('q','Seznam všech speciálních stránek');
+ta['ca-nstab-main'] = new Array('c','Zobrazit článek');
+ta['ca-nstab-user'] = new Array('c','Zobrazit uživatelovu stránku');
+ta['ca-nstab-media'] = new Array('c','Zobrazit stránku souboru');
+ta['ca-nstab-special'] = new Array('','Toto je speciální stránka, kterou nelze editovat.');
+ta['ca-nstab-project'] = new Array('a','Zobrazit stránku o wiki.');
+ta['ca-nstab-image'] = new Array('c','Zobrazit stránku obrázku.');
+ta['ca-nstab-mediawiki'] = new Array('c','Zobrazit systémovou zprávu.');
+ta['ca-nstab-template'] = new Array('c','Zobrazit šablonu.');
+ta['ca-nstab-help'] = new Array('c','Zobrazit stránku nápovědy.');
+ta['ca-nstab-category'] = new Array('c','Zobrazit kategorii.');",
+
+# preferences
+'tog-underline' => 'Podtrhnout odkazy',
+'tog-highlightbroken' => 'Formátovat odkazy na neexistující články <a href="#" class="new">takto</a> (alternativa: takto<a href="#" class="broken">?</a>).',
+'tog-justify' => 'Zarovnat odstavce do bloku',
+'tog-hideminor' => 'Skrýt malé editace v posledních změnách',
+'tog-extendwatchlist' => 'Rozšířený seznam sledovaných stránek',
+'tog-usenewrc' => 'Zdokonalené poslední změny (JavaScript)',
+'tog-numberheadings' => 'Automaticky číslovat nadpisy',
+'tog-showtoolbar' => 'Ukázat lištu s nástroji při editaci',
+'tog-editondblclick' => 'Editovat dvojklikem (JavaScript)',
+'tog-editsection' => 'Zapnout možnost editace části článku pomocí odkazu [editovat]',
+'tog-editsectiononrightclick' => 'Zapnout možnost editace části článku pomocí kliknutí pravým tlačítkem na nadpisy v článku (JavaScript)',
+'tog-showtoc' => 'Ukázat obsah článku (pokud má článek více než tři nadpisy)',
+'tog-rememberpassword' => 'Pamatovat si mé heslo mezi návštěvami',
+'tog-editwidth' => 'Roztáhnout editační okno na celou šířku',
+'tog-watchcreations' => 'Přidávat mnou založené stránky ke sledovaným',
+'tog-watchdefault' => 'Přidávat mnou editované stránky ke sledovaným',
+'tog-minordefault' => 'Označit editaci implicitně jako malá editace',
+'tog-previewontop' => 'Zobrazovat náhled před editačním oknem (ne za ním)',
+'tog-previewonfirst' => 'Zobrazit při první editaci náhled',
+'tog-nocache' => 'Nepoužívat cache',
+'tog-enotifwatchlistpages' => 'Poslat e-mail při změně sledované stránky',
+'tog-enotifusertalkpages' => 'Poslat e-mail při změně mé diskusní stránky',
+'tog-enotifminoredits' => 'Poslat e-mail i pro menší editace (které jinak nezpůsobují odeslání e-mailu)',
+'tog-enotifrevealaddr' => 'Prozradit mou e-mailovou adresu v upozorňujících e-mailech',
+'tog-shownumberswatching' => 'Zobrazovat počet sledujících uživatelů',
+'tog-fancysig' => 'Neupravovat podpis (nevkládat automaticky odkaz)',
+'tog-externaleditor' => 'Implicitně používat externí editor',
+'tog-externaldiff' => 'Implicitně používat externí porovnávací program',
+'tog-showjumplinks' => 'Používat odkazy „skočit na“ pro vyšší přístupnost',
+'tog-uselivepreview' => 'Používat rychlý náhled (JavaScript) (Experimentální)',
+'tog-autopatrol' => 'Označovat moje editace jako prověřené',
+'tog-forceeditsummary' => 'Upozornit, když nevyplním shrnutí editace',
+'tog-watchlisthideown' => 'Na seznamu sledovaných stránek skrýt moje editace',
+'tog-watchlisthidebots' => 'Na seznamu sledovaných stránek skrýt editace botů',
+
+'underline-always' => 'Vždy',
+'underline-never' => 'Nikdy',
+'underline-default' => 'Podle prohlížeče',
+
+'skinpreview' => '(Náhled)',
+
+# image deletion
+'deletedrevision' => 'Smazána stará verze $1.',
+
+# browsing diffs
+'previousdiff' => '← Předchozí porovnání',
+'nextdiff' => 'Následující porovnání →',
+
+'imagemaxsize' => 'Omezit obrázky na stránkách s popiskem na:',
+'thumbsize' => 'Velikost náhledu:',
+'showbigimage' => 'Stáhnout verzi s vysokým rozlišením ($1&times;$2, $3 KB)',
+
+'newimages' => 'Galerie nových obrázků',
+'showhidebots' => '($1 roboty)',
+'noimages' => 'Není co zobrazit.',
+
+'passwordtooshort' => 'Vaše heslo je příliš krátké. Musí obsahovat nejméně $1 {{plural:$1|znak|znaky|znaků}}.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Upozornění\'\'\': Tento soubor může obsahovat škodlivý kód, spuštěním můžete ohrozit svůj počítač.<hr />',
+
+'fileinfo' => '$1 KB, MIME typ: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadata',
+'metadata_help' => 'Metadata (vysvětlení najdete na [[{{ns:project}}:Metadata]]):',
+'metadata-help' => 'Tento soubor obsahuje dodatečné informace, poskytnuté zřejmě digitálním fotoaparátem nebo scannerem, kterým byl pořízen. Pokud byl soubor od té doby změněn, některé údaje mohou být neplatné.',
+'metadata-expand' => 'Zobrazit podrobnosti',
+'metadata-collapse' => 'Skrýt podrobnosti',
+'metadata-fields' => 'Pole EXIF uvedená v této zprávě budou na stránce s popisem vypsána vždy. Pro zobrazení ostatních bude třeba kliknout na „zobrazit podrobnosti“.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# Exif tags
+# TODO: zkontrolovat překlad, profesionální fotograf/grafik by bodnul
+'exif-imagewidth' =>'Šířka',
+'exif-imagelength' =>'Výška',
+'exif-bitspersample' =>'Bitů na složku',
+'exif-compression' =>'Druh komprese',
+'exif-photometricinterpretation' =>'Barevný prostor',
+'exif-orientation' =>'Orientace',
+'exif-samplesperpixel' =>'Počet složek',
+'exif-planarconfiguration' =>'Uspořádání dat',
+'exif-ycbcrsubsampling' =>'Poměr podvzorkování Y ku C',
+'exif-ycbcrpositioning' =>'Umístění Y a C',
+'exif-xresolution' =>'Rozlišení obrázku na šířku',
+'exif-yresolution' =>'Rozlišení obrázku na výšku',
+'exif-resolutionunit' =>'Jednotky rozlišení',
+'exif-stripoffsets' =>'Umístění dat obrázku',
+'exif-rowsperstrip' =>'Počet řádků na pás',
+'exif-stripbytecounts' =>'Počet bajtů na komprimovaný pás',
+'exif-jpeginterchangeformat' =>'Ofset k JPEG SOI',
+'exif-jpeginterchangeformatlength' =>'Počet bajtů JPEG dat',
+'exif-transferfunction' =>'Přenosová funkce',
+'exif-whitepoint' =>'Chroma bílého bodu',
+'exif-primarychromaticities' =>'Chroma primárních barev',
+'exif-ycbcrcoefficients' =>'Koeficienty matice pro transformaci barevných prostorů',
+'exif-referenceblackwhite' =>'Světlost referenčního černého a bílého bodu',
+'exif-datetime' =>'Datum a čas vytvoření obrázku',
+'exif-imagedescription' =>'Název obrázku',
+'exif-make' =>'Značka fotoaparátu',
+'exif-model' =>'Model fotoaparátu',
+'exif-software' =>'Použitý software',
+'exif-artist' =>'Autor',
+'exif-copyright' =>'Držitel autorských práv',
+'exif-exifversion' =>'Verze Exif',
+'exif-flashpixversion' =>'Podporovaná verze Flashpix',
+'exif-colorspace' =>'Barevný prostor',
+'exif-componentsconfiguration' =>'Význam jednotlivých složek',
+'exif-compressedbitsperpixel' =>'Komprimační režim',
+'exif-pixelydimension' =>'Platná šířka obrazu',
+'exif-pixelxdimension' =>'Platná výška obrazu',
+'exif-makernote' =>'Poznámky výrobce',
+'exif-usercomment' =>'Uživatelské poznámky',
+'exif-relatedsoundfile' =>'Související zvukový soubor',
+'exif-datetimeoriginal' =>'Datum a čas pořízení obrázku',
+'exif-datetimedigitized' =>'Datum a čas digitalizace',
+'exif-subsectime' =>'zlomky sekundy pro DateTime',
+'exif-subsectimeoriginal' =>'zlomky sekundy pro DateTimeOriginal',
+'exif-subsectimedigitized' =>'zlomky sekundy pro DateTimeDigitized',
+'exif-exposuretime' =>'Expozice',
+'exif-exposuretime-format' => '$1 s ($2)',
+'exif-fnumber' =>'Clona',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'Expoziční program',
+'exif-spectralsensitivity' =>'Spektrální citlivost',
+'exif-isospeedratings' =>'Nastavení ISO citlivosti',
+'exif-oecf' =>'Optoelectronická převodní funkce (OECF)',
+'exif-shutterspeedvalue' =>'Rychlost závěrky',
+'exif-aperturevalue' =>'Clona',
+'exif-brightnessvalue' =>'Světlost',
+'exif-exposurebiasvalue' =>'Změna expozice',
+'exif-maxaperturevalue' =>'Nejmenší clona',
+'exif-subjectdistance' =>'Vzdálenost k předmětu',
+'exif-meteringmode' =>'Způsob měření',
+'exif-lightsource' =>'Světelný zdroj',
+'exif-flash' =>'Blesk',
+'exif-focallength' =>'Ohnisková vzdálenost',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' =>'Umístění předmětu',
+'exif-flashenergy' =>'Výkon blesku',
+'exif-spatialfrequencyresponse' =>'Odezva prostorové frekvence',
+'exif-focalplanexresolution' =>'X rozlišení ohniskové roviny',
+'exif-focalplaneyresolution' =>'Y rozlišení ohniskové roviny',
+'exif-focalplaneresolutionunit' =>'Jednotka rozlišení ohniskové roviny',
+'exif-subjectlocation' =>'Umístění předmětu',
+'exif-exposureindex' =>'Expoziční index',
+'exif-sensingmethod' =>'Senzor',
+'exif-filesource' =>'Zdroj souboru',
+'exif-scenetype' =>'Druh scény',
+'exif-cfapattern' =>'Geometrické uspořádání senzoru',
+'exif-customrendered' =>'Uživatelské zpracování',
+'exif-exposuremode' =>'Expoziční režim',
+'exif-whitebalance' =>'Vyvážení bílé',
+'exif-digitalzoomratio' =>'Digitální zoom',
+'exif-focallengthin35mmfilm' =>'Ekvivalent ohniskové délky pro 35mm film',
+'exif-scenecapturetype' =>'Druh scény',
+'exif-gaincontrol' =>'Úprava světlosti',
+'exif-contrast' =>'Kontrast',
+'exif-saturation' =>'Sytost',
+'exif-sharpness' =>'Ostrost',
+'exif-devicesettingdescription' =>'Popis nastavení zařízení',
+'exif-subjectdistancerange' =>'Vzdálenost k předmětu',
+'exif-imageuniqueid' =>'Unikátní ID obrázku',
+'exif-gpsversionid' =>'Verze GPS tagu',
+'exif-gpslatituderef' =>'Severní/jižní zeměpisná šířka',
+'exif-gpslatitude' =>'Zeměpisná šířka',
+'exif-gpslongituderef' =>'Východní/západní zeměpisná délka',
+'exif-gpslongitude' =>'Zeměpisná délka',
+'exif-gpsaltituderef' =>'Nad/podmořská výška/hloubka',
+'exif-gpsaltitude' =>'Nadmořská výška',
+'exif-gpstimestamp' =>'GPS čas (podle atomových hodin)',
+'exif-gpssatellites' =>'Satelity použité pro měření',
+'exif-gpsstatus' =>'Stav přijímače',
+'exif-gpsmeasuremode' =>'Režim měření',
+'exif-gpsdop' =>'Přesnost měření',
+'exif-gpsspeedref' =>'Jednotka rychlosti',
+'exif-gpsspeed' =>'Rychlost GPS přijímače',
+'exif-gpstrackref' =>'Reference pro směr pohybu',
+'exif-gpstrack' =>'Směr pohybu',
+'exif-gpsimgdirectionref' =>'Reference pro orientaci obrázku',
+'exif-gpsimgdirection' =>'Orientace obrázku',
+'exif-gpsmapdatum' =>'Použitý geodetický systém',
+'exif-gpsdestlatituderef' =>'Severní/jižní zeměpisná šířka předmětu',
+'exif-gpsdestlatitude' =>'Zeměpisná šířka předmětu',
+'exif-gpsdestlongituderef' =>'Východní/západní zeměpisná délka předmětu',
+'exif-gpsdestlongitude' =>'Zeměpisná délka předmětu',
+'exif-gpsdestbearingref' =>'Reference pro směr k předmětu',
+'exif-gpsdestbearing' =>'Směr k předmětu',
+'exif-gpsdestdistanceref' =>'Jednotka vzdálenosti k předmětu',
+'exif-gpsdestdistance' =>'Vzdálenost k předmětu',
+'exif-gpsprocessingmethod' =>'Označení metody zpracování GPS dat',
+'exif-gpsareainformation' =>'Označení GPS oblasti',
+'exif-gpsdatestamp' =>'Datum podle GPS',
+'exif-gpsdifferential' =>'Diferenciální korekce GPS',
+
+# Exif attributes
+
+'exif-compression-1' => 'Nekomprimovaný',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normální', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Vodorovně převráceno', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Otočeno o 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Svisle převráceno', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Otočeno o 90° proti směru hodinových ručiček a svisle převráceno', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Otočeno o 90° ve směru hodinových ručiček', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Otočeno o 90° ve směru hodinových ručiček a svisle převráceno', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Otočeno o 90° proti směru hodinových ručiček', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'chunky',
+'exif-planarconfiguration-2' => 'planar',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'neexistuje',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Neuvedeno',
+'exif-exposureprogram-1' => 'Ruční',
+'exif-exposureprogram-2' => 'Normální',
+'exif-exposureprogram-3' => 'Priorita clony',
+'exif-exposureprogram-4' => 'Priorita závěrky',
+'exif-exposureprogram-5' => 'Kreativní (lepší hloubka ostrosti)',
+'exif-exposureprogram-6' => 'Akce (rychlejší závěrka)',
+'exif-exposureprogram-7' => 'Portrét (detailní fotografie s neostrým pozadím)',
+'exif-exposureprogram-8' => 'Krajina (fotografie krajiny s ostrým pozadím)',
+
+'exif-subjectdistance-value' => '$1 m',
+
+'exif-meteringmode-0' => 'Není známo',
+'exif-meteringmode-1' => 'Průměrové',
+'exif-meteringmode-2' => 'Vážený průměr',
+'exif-meteringmode-3' => 'Bodové',
+'exif-meteringmode-4' => 'Zónové',
+'exif-meteringmode-5' => 'Vzorové',
+'exif-meteringmode-6' => 'Částečné',
+'exif-meteringmode-255' => 'Jiné',
+
+'exif-lightsource-0' => 'Není známo',
+'exif-lightsource-1' => 'Denní světlo',
+'exif-lightsource-2' => 'Fluorescentní',
+'exif-lightsource-3' => 'Žárovka',
+'exif-lightsource-4' => 'Blesk',
+'exif-lightsource-9' => 'Jasno',
+'exif-lightsource-10' => 'Zamračeno',
+'exif-lightsource-11' => 'Stín',
+'exif-lightsource-12' => 'Zářivka denní světlo (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Zářivka bílé denní světlo (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Zářivka studená bílá (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Bílá zářivka (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standardní osvětlení A',
+'exif-lightsource-18' => 'Standardní osvětlení B',
+'exif-lightsource-19' => 'Standardní osvětlení C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO studiová žárovka',
+'exif-lightsource-255' => 'Jiný světelný zdroj',
+
+'exif-focalplaneresolutionunit-2' => 'in',
+
+'exif-sensingmethod-1' => 'Není známo',
+'exif-sensingmethod-2' => 'Jednočipový plošný senzor',
+'exif-sensingmethod-3' => 'Dvoučipový plošný senzor',
+'exif-sensingmethod-4' => 'Tříčipový plošný senzor',
+'exif-sensingmethod-5' => 'Sekvenční plošný senzor',
+'exif-sensingmethod-7' => 'Trilineární senzor',
+'exif-sensingmethod-8' => 'Sekvenční lineární senzor',
+
+'exif-filesource-3' => 'Digitální fotoaparát',
+
+'exif-scenetype-1' => 'Přímo fotografováno',
+
+'exif-customrendered-0' => 'Běžné zpracování',
+'exif-customrendered-1' => 'Uživatelské zpracování',
+
+'exif-exposuremode-0' => 'Automatická expozice',
+'exif-exposuremode-1' => 'Ruční expozice',
+'exif-exposuremode-2' => 'Bracketing',
+
+'exif-whitebalance-0' => 'Automatické vyvážení bílé',
+'exif-whitebalance-1' => 'Ruční vyvážení bílé',
+
+'exif-scenecapturetype-0' => 'Standardní',
+'exif-scenecapturetype-1' => 'Na šířku', # TODO: ?? portrét/krajina, nebo na šířku/na výšku -- co ta noční scéna?
+'exif-scenecapturetype-2' => 'Na výšku',
+'exif-scenecapturetype-3' => 'Noční scéna',
+
+'exif-gaincontrol-0' => 'Žádná',
+'exif-gaincontrol-1' => 'Mírné zvýšení jasu',
+'exif-gaincontrol-2' => 'Výrazné zvýšení jasu',
+'exif-gaincontrol-3' => 'Mírné snížení jasu',
+'exif-gaincontrol-4' => 'Výrazné snížení jasu',
+
+'exif-contrast-0' => 'Normální',
+'exif-contrast-1' => 'Měkký',
+'exif-contrast-2' => 'Tvrdý',
+
+'exif-saturation-0' => 'Normální',
+'exif-saturation-1' => 'Nízká sytost',
+'exif-saturation-2' => 'Vysoká sytost',
+
+'exif-sharpness-0' => 'Normální',
+'exif-sharpness-1' => 'Měkká',
+'exif-sharpness-2' => 'Tvrdá',
+
+'exif-subjectdistancerange-0' => 'Není známo',
+'exif-subjectdistancerange-1' => 'Makro',
+'exif-subjectdistancerange-2' => 'Detail',
+'exif-subjectdistancerange-3' => 'Pohled zdálky',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Severní šířka',
+'exif-gpslatitude-s' => 'Jižní šířka',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Východní délka',
+'exif-gpslongitude-w' => 'Západní délka',
+
+'exif-gpsstatus-a' => 'Probíhá měření',
+'exif-gpsstatus-v' => 'Měření mimo provoz',
+
+'exif-gpsmeasuremode-2' => 'Dvourozměrné měření',
+'exif-gpsmeasuremode-3' => 'Trojrozměrné měření',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'km/h',
+'exif-gpsspeed-m' => 'mph',
+'exif-gpsspeed-n' => 'kt',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Pravý kurs',
+'exif-gpsdirection-m' => 'Magnetický kurs',
+
+# external editor support
+'edit-externally' => 'Editovat tento soubor v externím programu',
+'edit-externally-help' => 'Více informací najdete v [http://meta.wikimedia.org/wiki/Help:External_editors nápovědě pro nastavení].',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'všechny',
+'imagelistall' => 'všechny',
+'watchlistall1' => 'všechny',
+'watchlistall2' => 'všechny',
+'namespacesall' => 'všechny',
+
+# E-mail address confirmation
+'confirmemail' => 'Potvrzení e-mailové adresy',
+'confirmemail_noemail' => 'Ve svém [[Special:Preferences|uživatelském nastavení]] jste nezadali platnou e-mailovou adresu.',
+'confirmemail_text' => 'Tato wiki vyžaduje, abyste potvrdili svou e-mailovou adresu
+před využíváním některých funkcí. Kliknutím na níže umístěné tlačítko dojde k odeslání
+potvrzovacího e-mailu na vámi uvedeno adresu. Tento mail obsahuje odkaz a potvrzovací kód;
+přejděte na odkazovanou stránku svým internetovým prohlížečem, tím potvrdíte, že
+zadaná adresa je platná.',
+'confirmemail_send' => 'Odeslat potvrzovací kód',
+'confirmemail_sent' => 'Potvrzovací e-mail byl odeslán',
+'confirmemail_sendfailed' => 'Nepodařilo se odeslat potvrzovací e-mail. Zkontrolujte, zda adresa neobsahuje chybné znaky.',
+'confirmemail_invalid' => 'Neplatný potvrzovací kód. Možná již vypršela platnost kódu.',
+'confirmemail_success' => 'Vaše e-mailová adresa byla potvrzena. Nyní se můžete přihlásit a používat wiki.',
+'confirmemail_loggedin' => 'Vaše e-mailová adresa byla potvrzena.',
+'confirmemail_error' => 'Nepodařilo se uložit vaše potvrzení.',
+'confirmemail_needlogin' => 'Pro potvrzení své e-mailové adresy se musíte $1.',
+
+'confirmemail_subject' => 'Potvrzení e-mailové adresy pro {{grammar:4sg|{{SITENAME}}}}',
+'confirmemail_body' => 'Někdo (patrně vy, z IP adresy $1) si registroval účet se jménem "$2" a touto e-mailovou adresou na {{grammar:6sg|{{SITENAME}}}}.
+
+Pokud si přejete aktivovat e-mailové funkce na {{grammar:6sg|{{SITENAME}}}}, tak pro potvrzení,
+že tato adresa opravdu patří vám, přejděte svým internetovým prohlížečem na následující adresu:
+
+$3
+
+Pokud jste o toto potvrzení *nežádali*, neklikejte na předchozí odkaz. Platnost tohoto potvrzovacího
+kódu vyprší $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Vyzkoušet přesné hledání',
+'searchfulltext' => 'Plnotextové hledání',
+'createarticle' => 'Vytvořit článek',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Vkládání šablon mezi wiki je vypnuto]',
+'scarytranscludefailed' => '[Nepodařilo se načíst šablonu pro $1; je mi líto]',
+'scarytranscludetoolong' => '[Příliš dlouhé URL; je mi líto]',
+
+# Trackbacks
+'trackbackbox' => "<div id='mw_trackbacks'>
+Zpětné odkazy k tomuto článku:<br />
+$1
+</div>",
+'trackbackremove' => ' ([$1 Smazat])',
+'trackbacklink' => 'Zpětný odkaz',
+'trackbackdeleteok' => 'Zpětný odkaz byl úspěšně smazán.',
+
+# delete conflict
+'deletedwhileediting' => 'Upozornění: V průběhu vaší editace byla tato stránka smazána!',
+'confirmrecreate' => 'Uživatel [[User:$1|$1]] ([[User talk:$1|diskuse]]) tuto stránku smazal poté, co jste začali editovat, s odůvodněním:
+: „$2“
+Opravdu si přejete znovu tuto stránku založit?',
+'recreate' => 'Znovu založit',
+'tooltip-recreate' => 'Znovu založit stránku i přesto, že byla smazána',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Přesměrovává se na [[$1]]…',
+
+# action=purge
+'confirm_purge' => "Aktualizovat cachovanou verzi této stránky?\n\n$1",
+'confirm_purge_button' => 'OK',
+
+'youhavenewmessagesmulti' => 'Na $1 máte nové zprávy',
+
+'searchcontaining' => "Hledat články obsahující ''$1''.",
+'searchnamed' => "Hledat články pojmenované ''$1''.",
+'articletitles' => "Články začínající ''$1''",
+'hideresults' => 'Skrýt výsledky',
+
+# DISPLAYTITLE
+'displaytitle' => '(Na tuto stránku odkazujte pomocí [[$1]])',
+
+'loginlanguagelabel' => 'Jazyk: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; předchozí stránka',
+'imgmultipagenext' => 'následující stránka &rarr;',
+'imgmultigo' => 'Jít!',
+'imgmultigotopre' => 'Přejít na stránku',
+
+# Table pager
+'ascending_abbrev' => 'vzestupně',
+'descending_abbrev' => 'sestupně',
+'table_pager_next' => 'Následující stránka',
+'table_pager_prev' => 'Předchozí stránka',
+'table_pager_first' => 'První stránka',
+'table_pager_last' => 'Poslední stránka',
+'table_pager_limit' => 'Zobrazit $1 položek na stránku',
+'table_pager_limit_submit' => 'Zobrazit',
+'table_pager_empty' => 'Nic nebylo nalezeno',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesCsb.php b/languages/messages/MessagesCsb.php
new file mode 100644
index 000000000000..2d7d3a58d5d4
--- /dev/null
+++ b/languages/messages/MessagesCsb.php
@@ -0,0 +1,327 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Specjalnô',
+ NS_MAIN => '',
+ NS_TALK => 'Diskùsëjô',
+ NS_USER => 'Brëkòwnik',
+ NS_USER_TALK => 'Diskùsëjô_brëkòwnika',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Diskùsëjô_$1',
+ NS_IMAGE => 'Òbrôzk',
+ NS_IMAGE_TALK => 'Diskùsëjô_òbrôzków',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Diskùsëjô_MediaWiki',
+ NS_TEMPLATE => 'Szablóna',
+ NS_TEMPLATE_TALK => 'Diskùsëjô_Szablónë',
+ NS_HELP => 'Pòmòc',
+ NS_HELP_TALK => 'Diskùsëjô_Pòmòcë',
+ NS_CATEGORY => 'Kategòrëjô',
+ NS_CATEGORY_TALK => 'Diskùsëjô_Kategòrëji'
+);
+
+$messages = array(
+'1movedto2' => '$1 przeniesłé do $2',
+'aboutpage' => '{{ns:4}}:Ò_{{SITENAME}}',
+'aboutsite' => 'Ò {{SITENAME}}',
+'actioncomplete' => 'Òperacëjô wëkònónô',
+'addedwatch' => 'Dodónô do lëstë ùzérónëch',
+'allmessages' => 'Wszëtczé systemòwé ògłosë',
+'ancientpages' => 'Nôstarszé starnë',
+'and' => 'ë',
+'anontalk' => 'Diskùsëjô dlô ti IP-adresë',
+'anonymous' => 'Anonimòwi brëkòwnik/-cë {{SITENAME}}',
+'april-gen' => 'Łżëkwiôta',
+'april' => 'Łżëkwiôt',
+'august-gen' => 'Zélnika',
+'august' => 'Zélnik',
+'badfilename' => 'Miono òbrôzka zmienioné na "$1".',
+'badfiletype' => '".$1" nie je nôlepszim fòrmatã lopka.',
+'badipaddress' => 'IP-adresa nie je richtich pòdónô.',
+'blockedtext' => 'Twòje kònto abò/ ë IP-adresa òstałë zascëgòwóné przez $1.\nPòdónô przëczëna to:<br />$2.<p>Bë wëjasnic sprawã zablokòwaniégò mòżesz skòntaktowac sã z $1 abò jińszim [[{{ns:4}}:Administratorzë|administratorã]].',
+'blockip' => 'Zascëgôj IP-adresã',
+'booksources' => 'Ksążczi',
+'brokenredirects' => 'Zerwóné przeczerowania',
+'bydate' => 'wedle datumù',
+'byname' => 'wedle miona',
+'bysize' => 'wedle wiôlgòscë',
+'categories' => 'Kategòrëje',
+'categoryarticlecount' => 'W ny kategòrëje je $1 artiklów.',
+'category_header' => 'Artikle w kategòrëji "$1"',
+'changepassword' => 'Zmiana parolë',
+'compareselectedversions' => 'Przërównôj wëbróné wersëje',
+'confirmdelete' => 'Pòcwierdzë rëmónié',
+'confirm' => 'Pòcwierdzë',
+'confirmprotect' => 'Pòcwierdzë zazychrowanié',
+'confirmprotecttext' => 'Jes Të gwës, że chcesz zazychrowac ną starnã?',
+'confirmunprotect' => 'Pòcwierdzë òdzychrowónié',
+'confirmunprotecttext' => 'Jes Të gwës, że chcesz òdzychrowac ną starnã?',
+'contribslink' => 'wkłôd',
+'contribsub' => 'Dlô brëkòwnika $1',
+'contributions' => 'Wkłôd brëkòwników',
+/*'copyrightwarning' => "Prosymë wdôrzëc, że przëjimô sã, ëż wszelejaczi\nwkłôd do {{SITENAME}} je ùżëczóny wedle reglów <i>GNU Free Documentation License</i>\n(szczegóły w $1). <br />Jeżle nie chcesz, bë Twój tekst bëł dowòlno zmieniwóny przez kòżdégò ë rozpòmiónowóny bez ògrańczeniów, tej nie dôwôj do niegò doprzińdzeniô w {{SITENAME}}. Równoczasno òswiôdczôsz, że nen tekst je Twòjim dokazã, abò pòchôdô z materiałów ôrtu <i>public domain</i> abò\n<i>GNU Free Documentation License</i>, abò téż kòmpatibilnégò ôrtu.\n<br /><strong>PROSYMË NIE ÙŻIWAC BEZ ZEZWÒLENIÉGÒ MATERIAŁÓW ÒBJIMNIÃTËCH AUTORSCZIM PRAWÃ!</strong>",*/
+'copyright' => 'Zamkłosc hewòtny starnë je ùżëczónô wedle reglów $1.',
+'couldntremove' => 'Ni móg rëmac pòzycëje "$1"...',
+'createaccount' => 'Założë nowé kònto',
+'cur' => 'aktualnô',
+'databaseerror' => 'Fela w pòdôwkòwi baze',
+'dateformat' => 'Fòrmat datumù',
+'december-gen' => 'Gòdnika',
+'december' => 'Gòdnik',
+'defaultns' => 'Domëslno przeszëkùjë nôslédné rëmnotë mionów:',
+'defemailsubject' => 'E-mail òd {{SITENAME}}',
+'deletecomment' => 'Przëczëna rëmaniô',
+'deleteimg' => 'rëmôj nen òbrôzk',
+'deletepage' => 'Rëmôj starnã',
+'delete' => 'Rëmôj',
+'deletionlog' => 'register rëmaniów',
+'dellogpage' => 'Rëmóné',
+'difference' => '(różnice midzë wersëjama)',
+'disambiguationspage' => '{{ns:4}}:Starnë_ùjednoznacznieniô',
+'disclaimerpage' => '{{ns:4}}:General_disclaimer',
+'disclaimers' => 'Prawné zastrzedżi',
+'doubleredirects' => 'Dëbeltné przeczérowania',
+'editcurrent' => 'Editëjë aktualną wersëjã ny starnë',
+'edit' => 'Edicëjô',
+'editold' => 'Edicëjô',
+'editsection' => 'Edicëjô',
+'editthispage' => 'Editëjë ną starnã',
+'emailfrom' => 'Òd',
+'emailmessage' => 'Wiadło',
+'emailpage' => 'Sélajë e-mail do brëkòwnika',
+'emailsend' => 'Wëslë',
+'emailsubject' => 'Téma',
+'emailto' => 'Do',
+'emailuser' => 'Wëslë e-maila do negò brëkòwnika',
+'errorpagetitle' => 'Brida',
+'excontent' => 'Zamkłosc starnë "$1"',
+'explainconflict' => 'Chtos sfórtowôł wprowadzëc swòją wersëjã artikla òbczôs Twòji edicëji. Górné pòle edicëji zamëkô w se tekst starnë aktualno zapisóny w pòdôwkòwi baze. Twòje zmianë są w dólnym pòlu edicëji. Bë wprowadzëc swòje zmianë mùszisz zmòdifikòwac tekst z górnégò pòla. <b>Blós</b> tekst z górnégò pòla mdze zapisóny w baze czej wcësniesz "Zapiszë".',
+'export' => 'Ekspòrt starnów',
+'faqpage' => '{{ns:4}}:FAQ',
+'february-gen' => 'Gromicznika',
+'february' => 'Gromicznik',
+'filecopyerror' => 'Ni mòże skòpérowac lopka "$1" do "$2".',
+'filedeleteerror' => 'Ni mòże rëmac lopka "$1".',
+'filedesc' => 'Òpisënk',
+'filename' => 'Miono lopka',
+'filenotfound' => 'Ni mòże nalezc lopka "$1".',
+'filerenameerror' => 'Ni mòże zmienic miona lopka "$1" na "$2".',
+'filesource' => 'Zdrój',
+'fileuploaded' => 'Lopk"$1" òstôł wladowóny.\nBiôj, prosymë, do starnë òpisënkù lopka ($2) ë pòdôj tikającé gò infòrmacëje\ntaczé jak: pòchòdzenié lopka, czedë ë przez kògò òstôł ùtworzony, ôs dëcht co le ò nim wiész, a wëdôwô Cë sã wôżné.',
+'formerror' => 'Fela: ni mòże wëslac fòrmùlara',
+'getimagelist' => 'zladënk lëstë lopków',
+'go' => 'Biôj!',
+'searcharticle' => 'Biôj!',
+'guesstimezone' => 'Wezmi z przezérnika',
+'help' => 'Pòmòc',
+'hidetoc' => 'zatacë',
+'hide' => 'zatacë',
+'histlegend' => "Legenda: (aktualnô) = różnice w przërównanim do aktualny wersëje,\n(wczasniészô) = różnice w przërównanim do wczasniészi wersëje, D = drobné edicëje",
+'history' => 'Historëjô starnë',
+'history_short' => 'Historëjô',
+'hr_tip' => 'Wòdorównô (horizontalnô) linijô (brëkùjë szpôrowno)',
+'ilsubmit' => 'Szëkôj',
+'imagelinks' => 'Lënczi do lopka',
+'imagelist' => 'Lësta òbrôzków',
+'imagepage' => 'Starna òbrôzka',
+'imagereverted' => 'Przëwôrcenié wczasniészi wersëje darzëło sã.',
+'imgdelete' => 'rëmôj',
+'imgdesc' => 'òpisënk',
+'imghistlegend' => "Legenda: (aktualny) = to je aktualny lopk, (rëmôj) = rëmôj\nną starszą wersëjã, (przëwôrcë) = przëwôrcë ną starszą wersëjã.\n<br /><i>Klëkni na datum bë òbôczëc jaczé lopczi bëlë wladowóné òb nen dzéń</i>.",
+'imghistory' => 'Historëjô lopka',
+'import' => 'Impòrtëjë starnë',
+'internalerror' => 'Bënowô fela',
+'ipbreason' => 'Przëczëna',
+'isredirect' => 'starna przeczerowaniô',
+'january-gen' => 'stëcznika',
+'january' => 'stëcznik',
+'july-gen' => 'Lëpinca',
+'july' => 'Lëpinc',
+'june' => 'Czerwińc',
+'june-gen' => 'Czerwińca',
+'largefile' => 'Nôlepi bë lopk ni miôł wicy jak $1 bajtów.',
+'lastmodifiedatby' => 'Na starna bëła slédno editowónô $2, $1 przez $3.',
+'lastmodifiedat' => 'Na starna bëła slédno editowónô ò $2, $1;',
+'last' => 'pòslédnô',
+'lineno' => 'Lëniô $1:',
+'linkshere' => 'Do ny starnë òdwòłëją sã hewòtné starnë:',
+'linkstoimage' => 'Hewò są starnë, jaczé òdwòłëją sã do negò lopka:',
+'listusers' => 'Lësta brëkòwników',
+'loadhist' => 'Zladënk historëji ny starnë',
+'localtime' => 'Twòja czasowô cona',
+'lockbtn' => 'Zascëgôj bazã pòdôwków',
+'loginerror' => 'Fela logòwaniô',
+'loginpagetitle' => 'Logòwanié brëkòwnika',
+'loginprompt' => 'Brëkùjesz miec \'\'cookies\'\' (kùszczi) włączoné bë sã wlogòwac do {{SITENAME}}.',
+'loginsuccess' => 'Të jes wlogòwóny do {{SITENAME}} jakno "$1".',
+'loginsuccesstitle' => 'ùdałé logòwanié',
+'login' => 'Wlogùjë mie',
+'logouttext' => 'Të jes ju wëlogòwóny. Mòżesz prôcowac z {{SITENAME}} jakno anonimòwi brëkòwnik abò wlogòwac sã jakno zaregistrowóny brëkòwnik.',
+'logouttitle' => 'Wëlogòwanié brëkòwnika',
+'logout' => 'Wëlogùjë mie',
+'lonelypages' => 'Niechóné starnë',
+'longpages' => 'Nôdłëgszé starnë',
+'mainpage' => 'Przédnô starna',
+'march-gen' => 'strumiannika',
+'march' => 'strumiannik',
+'math_failure' => 'Parser nie rozmiôł rozpòznac',
+'may-gen' => 'Môja',
+'may_long' => 'Môj',
+'minlength' => 'Miono òbrôzka brëkùje miec przënomni trzë lëterë.',
+'minoredit' => 'Drobnô edicëjô.',
+'minoreditletter' => 'D',
+'missingarticle' => 'Programa ni mô nalôzłé tekstu starnë, chtërnô bë mùsza bëc w baze, to je starnë "$1".<p>Colemało mô to plac, czej òstónie wëbróné sparłãczenié\ndo rëmóny starnë, np. stôrszi wersëji jińszi starnë.</p><p>Jińszé leżnosce mògą znaczëc, że w soft-wôrze je fela. W taczim przëtrôfkù prosymë zameldowac nen fakt administratorowi pòdającë hewòtną adresã.',
+'missingimage' => '<b>Felëjący òbrôzk</b><br /><i>$1</i>',
+'moredotdotdot' => 'Wicy...',
+'movearticle' => 'Przeniesë artikel',
+'movedto' => 'przeniesłô do',
+'movenologin' => 'Felënk logòwaniô',
+'movepagebtn' => 'Przeniesë starnã',
+'movepage' => 'Przeniesë starnã',
+'move' => 'Przeniesë',
+'movetalk' => 'Przeniesë téż starnã <i>Diskùsëje</i>, jeżle je to mòżlëwé.',
+'movethispage' => 'Przeniesë',
+'mycontris' => 'Mòje edicëje',
+'navigation' => 'Nawigacëjô',
+'newpages' => 'Nowé starnë',
+'newpassword' => 'Nowô parola',
+'newwindow' => '(òtmëkô sã w nowim òczenkù)',
+'nlinks' => '$1 lënków',
+'noemailtitle' => 'Felënk email-adresë',
+'noemail' => 'W baze ni ma email-adresë dlô brëkòwnika "$1".',
+'noexactmatch' => 'Nie da starnë z dokładno taczim titlã. Spróbùjë fùl szëkbë.',
+'nolinkstoimage' => 'Niżódnô starna nie òdwòłëje sã do negò lopka.',
+'nosuchactiontext' => 'Programa Mediawiki nie rozpòznôwô taczi òperacëji jakô je w URL',
+'nosuchspecialpage' => 'Nie da taczi specjalny starnë',
+'nosuchuser' => 'Nie da taczégò brëkòwnika "$1". Sprôwdzë pisënk abò wëfùlujë fòrmular bë założëc nowé kònto.',
+'notanarticle' => 'To nie je artikel',
+'notargettitle' => 'Nie da taczi starnë',
+'notloggedin' => 'Felëje logòwóniô',
+'november-gen' => 'Lëstopadnika',
+'november' => 'Lëstopadnik',
+'nowiki_sample' => 'Wstôw tuwò niesfòrmatowóny tekst',
+'nowiki_tip' => 'Ignorëjë wiki-fòrmatowanié',
+'nstab-category' => 'Kategòrëjô',
+'nstab-help' => 'Pòmòc',
+'nstab-image' => 'Òbrôzk',
+'nstab-main' => 'Artikel',
+'nstab-mediawiki' => 'ògłosënk',
+'nstab-special' => 'Specjalnô',
+'nstab-template' => 'Szablóna',
+'nstab-user' => 'Starna brëkòwnika',
+'nstab-project' => 'meta-starna',
+'october-gen' => 'Rujana',
+'october' => 'Rujan',
+'ok' => 'Jo!',
+'othercontribs' => 'Òpiarté na prôcë $1.',
+'pagecategories' => '{{PLURAL:$1|Kategòrëjô|Kategòrëje}}',
+'pagemovedsub' => 'Przeniesenié darzëło sã',
+'pagemovedtext' => 'Starna "[[$1]]" òsta przeniesłô do "[[$2]]".',
+'pagetitle' => '$1 - {{SITENAME}}',
+'passwordremindertext' => 'Chtos (prôwdëjuwerno Të, z adresë $1) pòprosëł ò wësłanié nowi parolë dopùscënkù do {{SITENAME}} ($4). Aktualnô parola dlô brëkòwnika "$2" je "$3". Nôlepi mdze czej wlogùjesz sã terô ë zarô zmienisz parolã.',
+'personaltools' => 'Priwatné przërëchtënczi',
+'popularpages' => 'Nôwidzalszé starnë',
+'portal' => 'Pòrtal wëcmaniznë',
+'portal-url' => '{{ns:4}}:Pòrtal wëcmaniznë',
+'postcomment' => 'Dôj dopòwiesc',
+'powersearch' => 'Szëkba',
+'preferences' => 'Preferencëje',
+'prefsnologin' => 'Felënk logòwóniô',
+'prefs-personal' => 'Pòdôwczi brëkòwnika',
+'previewnote' => 'To je blós pòdzérk - artikel jesz nie je zapisóny!',
+'preview' => 'Pòdzérk',
+'protectcomment' => 'Przëczëna zazychrowóniô',
+'protectedarticle' => 'zazychrowónô [[$1]]',
+'protectedpage' => 'Starna je zazychrowónô',
+'protect' => 'Zazychrëjë',
+'proxyblocksuccess' => 'Fertich.',
+'qbfind' => 'Nalézë',
+'qbmyoptions' => 'Mòje òptacëje',
+'qbspecialpages' => 'Specjalné starnë',
+'randompage' => 'Kawlowô starna',
+'readonly' => 'Baza pòdôwków je zablokòwónô',
+'readonlywarning' => 'BÔCZËNK: Pòdôwkòwô baza òsta sztërkòwô zablokòwónô dlô administracëjnëch célów. Nie mòże tej timczasã zapisac nowi wersëje artikla. Bédëjemë przeniesc ji tekst do priwatnégò lopka
+(wëtnij/wstôw) ë zachòwac na pózni.',
+'recentchangescount' => 'Wielëna pòzycëji na lësce slédnëch edicëji',
+'recentchangeslinked' => 'Zmianë w dolënkòwónëch',
+'recentchanges' => 'Slédné edicëje',
+'recentchangestext' => 'Na starna prezentérëje historëjã slédnëch edicëjów w {{SITENAME}}.\n\nWitôj! Jeżle Të jes tuwò dopiérze pierszi rôz, przeczëtôj né starnë: [[{{ns:4}}:FAQ|FAQ]], [[{{ns:4}}:Nazëwizna|konwencëje nazëwaniégò starnów]].',
+'redirectedfrom' => '(Przeczerowóné z $1)',
+'removedwatch' => 'Rëmóné z lëstë ùzérónëch',
+'returnto' => 'Wôrcë sã do starnë: $1.',
+'reupload' => 'Wëslë jesz rôz',
+'revertimg' => 'przëwôrcë',
+'rights' => 'Prawa:',
+'rollback' => 'Copnij edicëjã',
+'rollbackfailed' => 'Nie szło copnąc zmianë',
+'rollbacklink' => 'copnij',
+'savearticle' => 'Zapiszë artikel',
+'savefile' => 'Zapiszë lôpk',
+'search' => 'Szëkba',
+'searchbutton' => 'Szëkba',
+'september-gen' => 'Séwnika',
+'september' => 'Séwnik',
+'servertime' => 'Aktualny czas serwera',
+'shortpages' => 'Nôkrótszé starnë',
+'show' => 'pokôż',
+'showpreview' => 'Pòdzérk',
+'showtoc' => 'pokôż',
+'sitestats' => 'Statistika artiklów',
+'sitestatstext' => 'W pòdôwkòwi baze je w sëmie <b>$1</b> starn. Na wielëna zamëkô w se starnë <i>Diskùsëji</i>, starnë ò {{SITENAME}}, starnë ôrtë <i>stub</i> (ùzémk), starnë przeczerowóniô, ë jińszé, chtërné grãdo je klasyfikòwac jakno artikle. Bez nëch to prôwdëjuwerno da <b>$2</b> starn artiklów.<p>\nBëło w sëmie <b>$3</b> òdwiôdënów ë <b>$4</b> edicëji òd sztótu, czej miôł plac\nupgrade soft-wôrë.\nDôwó to strzédno <b>$5</b> edicëji na jedną starnã ë <b>$6</b> òdwiôdënów na jedną edicëjã.',
+'siteuser' => 'Brëkòwnik {{SITENAME}} $1',
+'skin' => 'Wëzdrzatk',
+'spamprotectiontitle' => 'Anti-spamòwi filter',
+'specialpage' => 'Specjalnô starna',
+'specialpages' => 'Specjalné starnë',
+'spheading' => 'Specjalné nôpisma',
+'successfulupload' => 'Wladënk darzëł sã',
+'talk' => 'Diskùsëjô',
+'timezonelegend' => 'Czasowô cona',
+'toc' => 'Spisënk zamkłoscë',
+'toolbox' => 'Przërëchtënczi',
+'tooltip-watch' => 'Dodôj ną starnã do lëstë ùzérónëch [alt-w]',
+'ucnote' => 'Hewò je lësta slédnëch <b>$1</b> edicëjów dokònónëch przez\nbrëkòwnika òbczôs òstatnëch <b>$2</b> dni.',
+'unprotectcomment' => 'Przëczëna òdzychrowaniô',
+'unprotectedarticle' => 'òdzychrowóny [[$1]]',
+'unprotect' => 'Òdzychrëjë',
+'unusedimages' => 'Nie wëzwëskóné òbrôzczi',
+'unwatch' => 'Òprzestôj ùzerac',
+'unwatchthispage' => 'Òprzestôj ùzerac ną starnã',
+'uploaddisabled' => 'Przeprôszómë! Mòżlëwòta wladënkù lopków na nen serwer òsta wëłączonô.',
+'uploadedfiles' => 'Wladowóné lopczi',
+'uploadedimage' => 'wladënk: "$1"',
+'uploadlog' => 'Lësta wladënków',
+'uploadlogpage' => 'Dołączoné',
+'uploadlogpagetext' => 'Hewò je lësta slédno wladowónëch lopków.\nWszëtczé gòdzënë tikają conë ùniwersalnégò czasë (UTC).\n<ul>\n</ul>',
+'uploadnologin' => 'Felënk logòwaniô',
+'uploadtext' => '<strong>STOP!</strong> Nigle wladëjesz jaczi lopk,\nprzeczëtôj [[{{ns:4}}:Regle_wladowaniô_lopków|regle wladowaniô lopków]] ë ùgwësnij sã, że wladëwającë gò òstóniesz z\nnima w zgòdze.\n<p>Jeżle chcesz przezdrzec abò przeszëkac do terô wladowóné lopczi,\nprzeńdzë do [[Specjalnô:Imagelist|lëstë wladowónëch lopków]].\nWszëtczé wladënczi ë rëmania są òdnotérowóné w\nspecjalnëch zestôwkach: [[{{ns:4}}:wladënczi|wladënczi]] ë [[{{ns:4}}:Rëmóné|rëmóné]].\n<p>Bë wëslac nowi lopk do zòbrazowaniô Twòjégò artikla wëzwëskùj \nhewòtny fòrmùlar.\nW wikszoscë przezérników ùzdrzesz knąpã <i>Browse...</i>\nabò <i>Przezérôj...</i>, chtëren ùmożlëwi Cë òtemkniãcé sztandardowégò\nòkna wëbiérkù lopka. Wëbranié lopka sprawi wstôwienié jegò miona\nw tekstowim pòlu kòl knąpë.\nZaznaczającë pasowné pòle, mùszisz téż pòcwierdzëc, ëż sélającë\nlopk nie gwôłcësz nikògò autorsczich praw.\nWladënk zacznie sã pò wcësniãcym <i>Wladëjë lopk</i>.\nTo mòże sztërk zdérowac, òsoblëwò jeżle ni môsz chùtczégò dopùscënkù do internetu.\n<p>Preferowónyma fòrmatama są: JPEG dlô òdjimków, PNG dlô céchùnków\në òbrôzków ze znankama ikònów, ôs OGG dlô zwãków. Bë nie dac przińc do lëchòrozmieniów nadôwôj lopkom miona sparłãczóné z jich zamkłoscą.\nBë wstôwic òbrôzk do artikla, wpiszë lënk:\n<b>[[òbrôzk:miono.jpg]]</b> abò <b>[[òbrôzk:miono.png|òpcjonalny tekst]]</b>.\nDlô zwãkòwëch lopków lënk mdze wëzdrzôł tak: <b>[[media:file.ogg]]</b>.\n<p>Prosymë wdarzëc, ëż tak samò jak w przëtrôfkù zwëczajnëch starnów {{SITENAME}},\njińszi brëkòwnicë mògą editowac abò rëmac wladowóné przez Ce lopczi,\njeżle mdą dbë, że to mdze lepi służëc całi ùdbie {{SITENAME}}.\nTwòje prawò do sélaniégò lopków mòże bëc Cë òdebróné, eżle nadùżëjesz systemë.',
+'uploadwarning' => 'Òstrzega ò wladënkù',
+'upload' => 'Wladënk lopka',
+'userlogin' => 'Logòwanié',
+'userlogout' => 'Wëlogòwanié',
+'userstats' => 'Statistika brëkòwników',
+'version' => 'Wersëjô',
+'wantedpages' => 'Nônótniészé starnë',
+'watchlistcontains' => 'Wielëna artiklów na Twòji lësce ùzérónëch: $1.',
+'watchlist' => 'Lësta ùzérónëch artiklów',
+'watchmethod-list' => 'szëkba ùzérónëch artiklów westrzód pòslédnëch edicëjów',
+'watchnologin' => 'Felënk logòwóniô',
+'watchthispage' => 'Ùzérôj ną starnã',
+'watchthis' => 'Ùzérôj',
+'watch' => 'Ùzérôj',
+'whatlinkshere' => 'Lënkùjącé',
+'whitelistedittitle' => 'Bë editowac je nót sã wlogòwac',
+'whitelistreadtitle' => 'Bë czëtac je nót sã wlogòwac',
+'yourlanguage' => 'Kaszëbsczi',
+'yourpasswordagain' => 'Pòwtórzë parolã',
+'yourpassword' => 'Twòja parola',
+'yourrealname' => 'Twòje jistné miono*',
+);
+
+
+?>
diff --git a/languages/messages/MessagesCu.php b/languages/messages/MessagesCu.php
new file mode 100644
index 000000000000..765ee002a6d2
--- /dev/null
+++ b/languages/messages/MessagesCu.php
@@ -0,0 +1,141 @@
+<?php
+/** Old Church Slavonic (Ѩзыкъ словѣньскъ)
+ */
+
+$separatorTransformTable = array(
+ ',' => ".",
+ '.' => ','
+);
+
+$linkPrefixExtension = true;
+
+$namespaceNames = array(
+ NS_MEDIA => 'Срѣдьства',
+ NS_SPECIAL => 'Нарочьна',
+ NS_MAIN => '',
+ NS_TALK => 'Бесѣда',
+ NS_USER => 'Польѕевател҄ь',
+ NS_USER_TALK => 'Польѕевател_бесѣда',
+ #NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '{{grammar:genitive|$1}}_бесѣда',
+ NS_IMAGE => 'Видъ',
+ NS_IMAGE_TALK => 'Вида_бесѣда',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_бесѣда',
+ NS_TEMPLATE => 'Образьць',
+ NS_TEMPLATE_TALK => 'Образьца_бесѣда',
+ NS_HELP => 'Помощь',
+ NS_HELP_TALK => 'Помощи_бесѣда',
+ NS_CATEGORY => 'Катигорї',
+ NS_CATEGORY_TALK => 'Катигорїѩ_бесѣда',
+);
+
+$defaultDateFormat = 'mdy';
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'xg j числа, Y',
+ 'mdy both' => 'H:i, xg j числа, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F Y',
+ 'dmy both' => 'H:i, j F Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y F j',
+ 'ymd both' => 'H:i, Y F j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+$linkTrail = '/^([a-zабвгдеєжѕзїіıићклмнопсстѹфхѡѿцчшщъыьѣюѥѧѩѫѭѯѱѳѷѵґѓђёјйљњќуўџэ҄я“»]+)(.*)$/sDu';
+
+$messages = array(
+'linkprefix' => '/^(.*?)(„|«)$/sD',
+
+'january' => 'їанѹарїи',
+'february' => 'феврѹарїи',
+'march' => 'мартїи',
+'april' => 'апрїлїи',
+'may_long' => 'маїи',
+'june' => 'їѹнїи',
+'july' => 'їѹлїи',
+'august' => 'аѵгѹстъ',
+'september' => 'септемврїи',
+'october' => 'октѡврїи',
+'november' => 'ноемврїи',
+'december' => 'декемврїи',
+'january-gen' => 'їанѹарї',
+'february-gen' => 'феврѹарї',
+'march-gen' => 'мартї',
+'april-gen' => 'апрїлї',
+'may-gen' => 'маї',
+'june-gen' => 'їѹнї',
+'july-gen' => 'їѹлї',
+'august-gen' => 'аѵгѹста',
+'september-gen' => 'септемврї',
+'october-gen' => 'октѡврї',
+'november-gen' => 'ноемврї',
+'december-gen' => 'декемврї',
+
+'1movedto2_redir' => '[[$1]] нареченъ [[$2]] врьхѹ прѣнаправлѥни ѥстъ.',
+'blockip' => 'Загради польѕеватель',
+'cite_article_link' => 'Приведи статїѭ',
+'contributions' => 'Добродѣни польѕевател',
+'createaccount' => 'Cъзижди си мѣсто',
+'currentevents' => 'Текѫща събыти',
+'delete' => 'ничьжи',
+'edit' => 'исправи',
+'editold' => 'исправи',
+'editsection' => 'исправи',
+'emailuser' => 'Посъли епїстолѫ',
+'go' => 'Прѣиди',
+'help' => 'Помощь',
+'history_short' => 'Їстѡрї',
+'ilsubmit' => 'Ищи',
+'login' => 'Въниди',
+'logout' => 'иходъ',
+'mainpage' => 'Главьна страница',
+'makebot-search' => 'Прѣиди',
+'move' => 'прѣименѹи',
+'mycontris' => 'Мо добродѣни',
+'mypreferences' => 'мои строи',
+'mytalk' => 'Мо бесѣда',
+'navigation' => 'плаваниѥ',
+'nstab-main' => 'статї',
+'nstab-project' => 'съвѣтъ',
+'nstab-special' => 'Нарочьна',
+'nstab-user' => 'польѕеватель',
+'permalink' => 'Ѹставьна съвѧзь',
+'portal' => 'Обьщины съвѣтъ',
+'powersearch' => 'Ищи',
+'printableversion' => 'Печатьнъ образъ',
+'protect' => 'забрани',
+'qbedit' => 'исправи',
+'qbspecialpages' => 'Нарочьны страницѧ',
+'recentchanges' => 'Послѣдьнѩ мѣны',
+'recentchangeslinked' => 'Вѧзаны мѣны',
+'restriction-edit' => 'исправи',
+'search' => 'поискъ',
+'searcharticle' => 'Прѣиди',
+'searchbutton' => 'Ищи',
+'sitesupport' => 'Дани',
+'specialpage' => 'нарочьна страница',
+'specialpages' => 'Нарочьны страницѧ',
+'talk' => 'бесѣда',
+'toolbox' => 'Орѫди',
+'unprotect' => 'пѹсти',
+'unwatch' => 'остави блюдениѥ',
+'upload' => 'Положи дѣло',
+'uploadbtn' => 'Положи дѣло',
+'userlogin' => 'Въниди / съзижди си мѣсто',
+'userlogout' => 'иходъ',
+'watch' => 'блюди',
+'watchlist' => 'Мо блюдени',
+'whatlinkshere' => ' Досьдещьнѩ съвѧзи',
+
+);
+
+?>
diff --git a/languages/messages/MessagesCv.php b/languages/messages/MessagesCv.php
new file mode 100644
index 000000000000..fc540f2e753a
--- /dev/null
+++ b/languages/messages/MessagesCv.php
@@ -0,0 +1,245 @@
+<?php
+
+/**
+ * Chuvash stub localization; default to Russian instead of English.
+ */
+$fallback = 'ru';
+$linkPrefixExtension = true;
+
+$namespaceNames = array(
+ NS_MEDIA => 'Медиа',
+ NS_SPECIAL => 'Ятарлă',
+ NS_MAIN => '',
+ NS_TALK => 'Сӳтсе явасси',
+ NS_USER => 'Хутшăнакан',
+ NS_USER_TALK => 'Хутшăнаканăн_канашлу_страници',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_сӳтсе_явмалли',
+ NS_IMAGE => 'Ӳкерчĕк',
+ NS_IMAGE_TALK => 'Ӳкерчĕке_сӳтсе_явмалли',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_сӳтсе_явмалли',
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Шаблона_сӳтсе_явмалли',
+ NS_HELP => 'Пулăшу',
+ NS_HELP_TALK => 'Пулăшăва_сӳтсе_явмалли',
+ NS_CATEGORY => 'Категори',
+ NS_CATEGORY_TALK => 'Категорине_сӳтсе_явмалли',
+);
+
+$linkTrail = '/^([a-zа-яĕçăӳ"»]+)(.*)$/sDu';
+
+$messages = array(
+
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Пользователь страници\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'The user page for the ip you\'re editing as\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'My talk page\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussion about edits from this ip address\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Настройкӑсем\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'The list of pages you\'re monitoring for changes.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'List of my contributions\');
+ta[\'pt-login\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Log out\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Статьяна сӳтсе явасси\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Эсир ку страницӑна тӳрлетме пултаратӑр. Тархасшӑн ҫырса хӑваричен страницӑ мӗнле пулассине пӑхӑр.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Кӗске ӑнлантару хушма пултаратӑр.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Ку страницӑна эсир улӑштарма пултараймастӑр. Ӑна мӗнле ҫырнине кӑна пӑхма пултаратӑр.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Past versions of this page.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Улӑшратусенчен сыхласси\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Страницӑна кӑларса пӑрахмалли\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Restore the edits done to this page before it was deleted\');
+ta[\'ca-move\'] = new Array(\'m\',\'Страницӑна урӑх ҫӗре куҫарасси\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Эсир ку страницӑна урӑх ҫӗре куҫараймастӑр\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Ку страницӑ хыҫҫӑн сӑнама пуҫласси\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Ку страницӑ хыҫҫӑн урӑх сӑнамалла мар\');
+ta[\'search\'] = new Array(\'f\',\'Search this wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Тӗп страницӑ\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Visit the Main Page\');
+ta[\'n-portal\'] = new Array(\'\',\'About the project, what you can do, where to find things\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Find background information on current events\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'The list of recent changes in the wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Load a random page\');
+ta[\'n-help\'] = new Array(\'\',\'The place to find out.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Support us\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'List of all wiki pages that link here\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Recent changes in pages linked from this page\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS feed for this page\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom feed for this page\');
+ta[\'t-contributions\'] = new Array(\'\',\'View the list of contributions of this user\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Send a mail to this user\');
+ta[\'t-upload\'] = new Array(\'u\',\'Upload images or media files\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'List of all special pages\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'View the content page\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'View the user page\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'View the media page\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'This is a special page, you can\'t edit the page itself.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'View the project page\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'View the image page\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'View the system message\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'View the template\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'View the help page\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'View the category page\');',
+
+'january' => 'Кăрлач',
+'jan' => 'Кăр',
+'trackbackremove' => ' ([$1 кăларса пăрах])',
+'history_short' => 'Истори',
+'deletedrev' => '[кăларса пăрахнă]',
+'ancientpages' => 'Чи кивĕ статьясем',
+'editingcomment' => '$1 тӳрлетни (кӗске анлантарӑвӗ)',
+'servertime' => 'Сервер вăхăчě',
+'listingcontinuesabbrev' => '(малалли)',
+'show' => 'кăтартмалла',
+'talkpagemoved' => 'Сӳтсе явмалли страницăн ятне те улăштартăмăр.',
+'textboxsize' => 'Тӳрлетни',
+'editing' => '$1 тӳрлетни',
+'editinguser' => '$1 тӳрлетни',
+'uploadedfiles' => 'Кĕртнĕ файлсем',
+'hide' => 'кăтартмалла мар',
+'and' => 'тата',
+'qbspecialpages' => 'Ятарлӑ страницӑсем',
+'helppage' => '{{ns:project}}:Пулăшу',
+'uploaddisabled' => 'Каçарăр та сайта халĕ нимĕн те кĕртме юрамаст.',
+'next' => 'тепěр',
+'ipbreason' => 'Сăлтавĕ',
+'previewnote' => 'Ку страницăна халлěхе çырса хуман. Эсир ку страницă мěнле пулассине кăна куратăр!!',
+'editingsection' => '$1 тӳрлетни (статья разделě)',
+'august' => 'Çурла',
+'edithelp' => 'Улшăнусене кĕртме пулăшакан пулăшу',
+'others' => 'ыттисем',
+'jumptonavigation' => 'навигаци',
+'createarticle' => 'Çĕнĕ статья çыр',
+'aboutsite' => '{{SITENAME}} çинчен',
+'templatesused' => 'Ку страница çинче усă курнă шаблонсем:',
+'dec' => 'Раш',
+'permalink' => 'Яланхи вырăн',
+'tooltip-watch' => 'Çак страницăна пăхса тăмаллисем шутне хуш [alt-w]',
+'rightslogtext' => 'Ку пользовательсен прависене улăштарниссен журналě',
+'nextpage' => 'Тепěр страницă ($1)',
+'undeleterevisions' => 'Архивра пурĕ $1 верси',
+'allpages' => 'Пěтěм страницăсем',
+'watchthis' => 'Ку страницăна кěртекен улшăнусем хыççăн сăнамалла',
+'nstab-special' => 'Ятарлă',
+'newpages' => 'Çěнě страницăсем',
+'nstab-help' => 'пулăшу',
+'tuesday' => 'Ытларикун',
+'nstab-user' => 'Хутшăнакан страници',
+'go' => 'Куç',
+'searcharticle' => 'Куç',
+'nviews' => '$1 хут пăхнă',
+'newpassword' => 'Çěнě пароль',
+'monday' => 'Тунтикун',
+'specialpages' => 'Ятарлă страницăсем',
+'specialpage' => 'Ятарлă страницă',
+'printableversion' => 'Пичетлемелли верси',
+'edithelppage' => '{{ns:project}}:Улшăнусене кĕртме пулăшакан пулăшу',
+'unblocklogentry' => '«$1» блокировкăран кăларнă',
+'rclinks' => 'Юлашки $2 кун хушшинче тунă $1 улшăнусене кăтартмалла<br />$3',
+'delete_and_move' => 'Кăларса пăрахса куçарасси',
+'1movedto2' => '$1 $2 çине куçарнă',
+'mainpage' => 'Тĕп страницă',
+'laggedslavemode' => 'Асăрхăр! Страница çинче юлашки улшăнусене кăтартмасăр пултарнă.',
+'movepage' => 'Страницăна куçарнă',
+'sitesupport' => 'Пожертвованисем',
+'undelete' => 'Кăларса пăрахнă страницăсене пăх',
+'talk' => 'Сӳтсе явасси',
+'jun' => 'Çěр',
+'uploadlog' => 'Файлсене кĕртнин логĕ',
+'thursday' => 'Кĕçнерникун',
+'lastmodifiedat' => 'Ку страницăна юлашки улăштарнă вăхăт: $2, $1.',
+'toc' => 'Тупмалли',
+'rights' => 'Тума пултарать:',
+'allmessagesfilter' => 'Regular expression filter:',
+'oct' => 'Юпа',
+'undeletebtn' => 'Каялла тавăр!',
+'mar' => 'Пуш',
+'rcnote' => 'Юлашки <strong>$2</strong> кун хушшинчи <strong>$1</strong> улшăнусем. Халě пěтěмпе <strong>{{NUMBEROFARTICLES}}</strong> статья.',
+'whatlinkshere' => 'Кунта килекен ссылкăсем',
+'currentevents' => 'Хыпарсем',
+'currentevents-url' => 'Хыпарсем',
+'oldpassword' => 'Кивě пароль',
+'uncategorizedcategories' => 'Каталога кĕртмен категорисем',
+'december' => 'Раштав',
+'talkpagenotmoved' => 'Сӳтсе явмалли страницăн ятне улăштарма пултараймарăмăр.',
+'unblocklink' => 'блокировкăран кăлар',
+'july' => 'Утă',
+'may' => 'Çу',
+'rollbackfailed' => 'Каялла куçарнă çухна йăнăш тухнă',
+'deadendpages' => 'Ниăçта та урăх ертмен страницăсем',
+'histfirst' => 'Пĕрремĕш',
+'november' => 'Чӳк',
+'uncategorizedpages' => 'Каталогсăр страницăсем',
+'uclinks' => 'Юлашки $1 улшăнусене пăх; юлашки $2 кун хушшинче тунисене пăх.',
+'recentchangeslinked' => 'Çыхăннă улшăнусем',
+'delete' => 'Кăларса пăрахасси',
+'toolbox' => 'Ĕç хатĕрĕсем',
+'pagemovedsub' => 'Куçарас ěç тěрěс иртрě',
+'minoredit' => 'Кунта пěчěк улшăнусем кăна кěртнě',
+'aug' => 'Çур',
+'upload' => 'Файла кĕртесси',
+'ilsubmit' => 'Шырамалла',
+'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff«"]+)$/sD',
+'spheading' => 'Пěтěм пользовательсем валли ятарлă страницăсем',
+'recentchanges' => 'Юлашки улшăнусем',
+'imagelist' => 'Ӳкерчěксен списокě',
+'nextrevision' => 'Çěнěрех верси→',
+'aboutpage' => '{{ns:project}}:çинчен',
+'unblockip' => 'IP-адреса блокировкăран калар',
+'rows' => 'Йěркесем',
+'rollback' => 'Тÿрлетÿсене каялла куçарасси',
+'june' => 'Çěртме',
+'otherlanguages' => 'Урăх чěлхесем',
+'apr' => 'Ака',
+'newpageletter' => 'Ç',
+'notargettitle' => 'Тĕллевне кăтартман',
+'history' => 'Истори',
+'editthispage' => 'Страницăна тӳрлетесси',
+'uctop' => ' (пуçламăш)',
+'friday' => 'Эрнекун',
+'data' => 'Кун',
+'undeletedarticle' => '«[[$1]]» каялла тавăрнă',
+'deletepage' => 'Кăларса парахнă статьясем',
+'underline-always' => 'Яланах',
+'randompage' => 'Ăнсăртран илнě страницă',
+'jumptosearch' => 'Шырав',
+'nov' => 'Чӳк',
+'october' => 'Юпа',
+'talkpage' => 'Сӳтсе явасси',
+'categories' => 'Категорисем',
+'pagecategories' => 'Категорисем',
+'hidetoc' => 'кӑтартмалла мар',
+'april' => 'Ака',
+'listusers' => 'Хутшăнакансен списокĕ',
+'ignorewarnings' => 'Асăрхаттарусене шута илмелле мар',
+'files' => 'Файлсем',
+'previousrevision' => '&larr;Малтанхи верси',
+'histlast' => 'Юлашки',
+'march' => 'Пуш',
+'linklistsub' => '(ссылкăсен списокĕ)',
+'undeletedrevisions' => '$1 кăларса пăрахнă тӳрлетӳсене каялла тавăрнă',
+'tooltip-search' => 'Шырав [alt-f]',
+'may_long' => 'Çу',
+'rclistfrom' => 'Юлашки улшăнусене $1 вăхăтран пуçласа кăтартнă',
+'allpagesnext' => 'Тепěр',
+'localtime' => 'Вырăнти вăхăт',
+'undeletearticle' => 'Кăларса парахнă страницăна каялла тавăр',
+'edit' => 'Тӳрлетӳ',
+'numedits' => 'Улшăнусен шучĕ (статьясем): $1',
+'tooltip-save' => 'Тӳрлетӳсене астуса хăвармалла [alt-s]',
+'search' => 'Шырасси',
+'searchbutton' => 'Шырасси',
+'jul' => 'Утă',
+'showingresults' => 'Аяларах эсир <b>#$2</b> пуçласа кăтартнă <b>$1</b> йĕркене куратăр.',
+'rollback_short' => 'Каялла куçарасси',
+'thumbnail-more' => 'Пысăклатмалли',
+'september' => 'Авăн',
+'undelete_short' => '$1 тӳрлетӳсене каялла тавăр',
+'help' => 'Пулăшу',
+'sep' => 'Авн',
+);
+
+
+?>
diff --git a/languages/messages/MessagesCy.php b/languages/messages/MessagesCy.php
new file mode 100644
index 000000000000..08ab035a38e1
--- /dev/null
+++ b/languages/messages/MessagesCy.php
@@ -0,0 +1,846 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+/* Cymraeg - Welsh */
+
+$namespaceNames = array(
+ NS_MEDIA => "Media",
+ NS_SPECIAL => "Arbennig",
+ NS_MAIN => "",
+ NS_TALK => "Sgwrs",
+ NS_USER => "Defnyddiwr",
+ NS_USER_TALK => "Sgwrs_Defnyddiwr",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => "Sgwrs_$1",
+ NS_IMAGE => "Delwedd",
+ NS_IMAGE_TALK => "Sgwrs_Delwedd",
+ NS_MEDIAWIKI => "MediaWici",
+ NS_MEDIAWIKI_TALK => "Sgwrs_MediaWici",
+ NS_TEMPLATE => "Nodyn",
+ NS_TEMPLATE_TALK => "Sgwrs_Nodyn",
+ NS_CATEGORY => "Categori",
+ NS_CATEGORY_TALK => "Sgwrs_Categori",
+ NS_HELP => "Cymorth",
+ NS_HELP_TALK => "Sgwrs Cymorth"
+);
+
+$quickbarSettings = array(
+ "Dim", "Sefydlog chwith", "Sefydlog de", "Arnawf de"
+);
+
+$skinNames = array(
+ 'standard' => "Safonol",
+ 'nostalgia' => "Hiraeth",
+ 'cologneblue' => "Glas Cwlen",
+);
+
+$datePreferences = false;
+
+$bookstoreList = array(
+ "AddALL" => "http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN",
+ "PriceSCAN" => "http://www.pricescan.com/books/bookDetail.asp?isbn=$1",
+ "Barnes & Noble" => "http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1",
+ "Amazon.com" => "http://www.amazon.com/exec/obidos/ISBN=$1",
+ "Amazon.co.uk" => "http://www.amazon.co.uk/exec/obidos/ISBN=$1"
+);
+
+
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, "#redirect", "#ail-cyfeirio" ),
+ 'notoc' => array( 0, "__NOTOC__", "__DIMTAFLENCYNNWYS__" ),
+ 'noeditsection' => array( 0, "__NOEDITSECTION__", "__DIMADRANGOLYGU__" ),
+ 'start' => array( 0, "__START__", "__DECHRAU__" ),
+ 'currentmonth' => array( 1, "CURRENTMONTH", "MISCYFOES" ),
+ 'currentmonthname' => array( 1, "CURRENTMONTHNAME", "ENWMISCYFOES" ),
+ 'currentday' => array( 1, "CURRENTDAY", "DYDDIADCYFOES" ),
+ 'currentdayname' => array( 1, "CURRENTDAYNAME", "ENWDYDDCYFOES" ),
+ 'currentyear' => array( 1, "CURRENTYEAR", "FLWYDDYNCYFOES" ),
+ 'currenttime' => array( 1, "CURRENTTIME", "AMSERCYFOES" ),
+ 'numberofarticles' => array( 1, "NUMBEROFARTICLES","NIFEROERTHYGLAU" ),
+ 'currentmonthnamegen' => array( 1, "CURRENTMONTHNAMEGEN", "GENENWMISCYFOES" ),
+ 'subst' => array( 1, "SUBST:" ),
+ 'msgnw' => array( 0, "MSGNW:" ),
+ 'end' => array( 0, "__DIWEDD__" ),
+ 'img_thumbnail' => array( 1, "ewin bawd", "bawd", "thumb", "thumbnail" ),
+ 'img_right' => array( 1, "de", "right" ),
+ 'img_left' => array( 1, "chwith", "left" ),
+ 'img_none' => array( 1, "dim", "none" ),
+ 'img_width' => array( 1, "$1px" ),
+ 'img_center' => array( 1, "canol", "centre", "center" ),
+ 'int' => array( 0, "INT:" )
+
+);
+$linkTrail = "/^([àáâèéêìíîïòóôûŵŷa-z]+)(.*)\$/sDu";
+
+$messages = array(
+# User Toggles
+
+"tog-underline" => "Tanllinellu cysylltiadau",
+"tog-highlightbroken" => "Fformatio cysylltiadau wedi'i dorri <a href=\"\" class=\"new\">fel hyn</a> (dewis arall: fel hyn<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Unioni paragraffau",
+"tog-hideminor" => "Cuddiwch golygiadau bach mewn newidiadau diweddar",
+"tog-usenewrc" => "Newidiadau diweddar mwyhad (nid am pob porwr)",
+"tog-numberheadings" => "Rhifwch teiltau yn awtomatig",
+"tog-showtoolbar"=> "Dangos bar erfynbocs golygu",
+"tog-editondblclick" => "Golygu tudalennau gyda clic dwbwl (JavaScript)",
+"tog-editwidth" => "Mae gan bocs golygu lled llon",
+"tog-editsection" => "Galluogwch golygu adrannau trwy cysylltiadau [golygu]",
+"tog-editsectiononrightclick" => "Galluogwch golygu adrannau trwy dde-clicio ar teitlau adran (JavaScript)",
+"tog-showtoc" => "Dangoswch Taflen Cynnwys (am erthyglau gyda mwy na 3 pennawdau",
+"tog-rememberpassword" => "Cofiwch allweddair dros sesiwnau",
+"tog-watchdefault" => "Gwiliwch erthyglau newydd ac wedi adnewid",
+"tog-minordefault" => "Marciwch pob golygiad fel un bach",
+"tog-previewontop" => "Dangos blaenwelediad cyn y bocs golygu, nid ar ol e",
+"tog-nocache" => "Anablwch casio tudanlen",
+
+# Dates
+'sunday' => 'Dydd Sul',
+'monday' => 'Dydd Llun',
+'tuesday' => 'Dydd Mawrth',
+'wednesday' => 'Dydd Mercher',
+'thursday' => 'Dydd Iau',
+'friday' => 'Dydd Gwener',
+'saturday' => 'Dydd Sadwrn',
+'january' => 'Ionawr',
+'february' => 'Chwefror',
+'march' => 'Mawrth',
+'april' => 'Ebrill',
+'may_long' => 'Mai',
+'june' => 'Mehefin',
+'july' => 'Gorffennaf',
+'august' => 'Awst',
+'september' => 'Medi',
+'october' => 'Hydref',
+'november' => 'Tachwedd',
+'december' => 'Rhagfyr',
+'jan' => 'Ion',
+'feb' => 'Chwe',
+'mar' => 'Maw',
+'apr' => 'Ebr',
+'may' => 'Mai',
+'jun' => 'Meh',
+'jul' => 'Gor',
+'aug' => 'Aws',
+'sep' => 'Med',
+'oct' => 'Hyd',
+'nov' => 'Tach',
+'dec' => 'Rhag',
+
+
+# Bits of text used by many pages:
+#
+"categories" => "Categorïau tudalen",
+"pagecategories" => "Categorïau tudalen",
+"category_header" => "Erthyglau mewn categori \"$1\"",
+"subcategories" => "Is-categorïau",
+"mainpage" => "Prif tudalen",
+"mainpagetext" => "Meddalwedd {{SITENAME}} wedi sefydlu'n llwyddiannus",
+"about" => "Amdano",
+"aboutsite" => "Amdano {{SITENAME}}",
+"aboutpage" => "{{ns:project}}:Amdano",
+"help" => "Help",
+"helppage" => "{{ns:project}}:Help",
+"bugreports" => "Adroddiadau diffygion",
+"bugreportspage" => "{{ns:project}}:Adroddiadau_diffygion",
+"sitesupport" => "Rhoddion",
+"faq" => "COF",
+"faqpage" => "{{ns:project}}:COF",
+"edithelp" => "Help gyda golygu",
+"edithelppage" => "{{ns:project}}:Sut_ydy_chi'n_golygu_tudalen",
+"cancel" => "Dirymu",
+"qbfind" => "Cael",
+"qbbrowse" => "Pori",
+"qbedit" => "Golygu",
+"qbpageoptions" => "Dewysiadau tudalen",
+"qbpageinfo" => "Gwybodaeth tudalen",
+"qbmyoptions" => "Fy dewysiadau",
+"qbspecialpages" => "Tudalennau arbennig",
+"moredotdotdot" => "Mwy...",
+"mypage" => "Fy nhudalen",
+"mytalk" => "Sgwrs fi",
+"disclaimers" => "Gwadiadau",
+"disclaimerpage" => "{{ns:project}}:Gwadiad_cyffredin",
+"currentevents" => "Digwyddiadau presennol",
+"errorpagetitle" => "Gwall",
+"returnto" => "Ewch yn ôl i $1.",
+"whatlinkshere" => "Tudalennau sydd yn cysyllti fan hyn",
+"help" => "Help",
+"search" => "Chwilio",
+"searchbutton" => "Chwilio",
+"go" => "Mynd",
+'searcharticle' => "Mynd",
+"history" => "Hanes y tudalen",
+"printableversion" => "Fersiwn argraffiol",
+"editthispage" => "Golygwch y tudalen hon",
+"deletethispage" => "Dileuwch y tudalen hon",
+"protectthispage" => "Amddiffynwch y tudalen hon",
+"unprotectthispage" => "Di-amddiffynwch y tudalen hon",
+"newpage" => "Tudalen newydd",
+"talkpage" => "Sgwrsio amdano'r tudalen hon",
+"postcomment" => "Postiwch esboniad",
+"articlepage" => "Gwyliwch erthygl",
+"userpage" => "Gwyliwch tudalen defnyddiwr",
+"projectpage" => "Gwyliwch tudalen meta",
+"imagepage" => "Gwyliwch tudalen llun",
+"viewtalkpage" => "Gwyliwch sgwrs",
+"otherlanguages" => "Ieithoed eraill",
+"redirectedfrom" => "(Ail-cyfeiriad oddiwrth $1)",
+"lastmodifiedat" => "Pryd cafodd ei newid diwethaf $2, $1.",
+"viewcount" => "Mae'r tudalen hyn wedi cael ei gweld $1 o weithiau.",
+"protectedpage" => "Tudalen amddiffyniol",
+"nbytes" => "$1 bytes",
+"ok" => "OK",
+"retrievedfrom" => "Wedi dod o \"$1\"",
+"newmessageslink" => "Neges(eueon) newydd",
+"editsection" => "golygu",
+"editold" => "golygu",
+"toc" => "Taflen Cynnwys",
+"showtoc" => "dangos",
+"hidetoc" => "cuddio",
+"thisisdeleted" => "Edrychwch at, neu atgyweirio $1?",
+"restorelink" => "$1 golygiadau wedi eu dileuo",
+
+# Main script and global functions
+#
+"nosuchaction" => "Does dim gweithred",
+"nosuchactiontext" => "Dydy'r meddalwedd Mediawiki ddim yn deallt y gweithrediad mae'r URL yn gofyn iddo fe gwneud",
+"nosuchspecialpage" => "Does dim tudalen arbennig",
+"nospecialpagetext" => "Yr ydych wedi gofyn am tudalen arbennig dydy'r meddalwedd Mediawiki ddim yn adnabod.",
+
+# General errors
+#
+"error" => "Gwall",
+"databaseerror" => "Databas ar gam",
+"dberrortext" => "Mae gwall cystrawen wedi digwydd ar y databas.
+Y gofyniad olaf triodd y databas oedd:
+<blockquote><tt>$1</tt></blockquote>
+oddiwrth ffwythiant \"<tt>$2</tt>\".
+Dwedodd MySQL mae 'ne côd gwall \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Mae gwall cystrawen wedi digwydd ar y databas.
+Y gofyniad olaf triodd y databas oedd:
+\"$1\"
+oddiwrth ffwythiant \"$2\".
+Dwedodd MySQL mae 'ne côd gwall \"$3: $4\".",
+"noconnect" => "Ddim yn gallu cysylltu i'r databas ar $1",
+"nodb" => "Ddim yn gallu dewis databas $1",
+"cachederror" => "Dyma copi o'r stôr o'r tudalen rydych wedi gofyn, ac efallai dydi hi ddim yn cyfoes.",
+"readonly" => "Databas ar gloi",
+"enterlockreason" => "Rhowch reswm am paham mae'r databas yn cael eu gloi, yn cynnwys amcangyfrif pryd fydd y databas yn cael eu di-gloi",
+"readonlytext" => "Mae'r databas {{SITENAME}} wedi eu cloi yn erbyn erthyglau newydd ac adnewidiadau eraill, yn tebygol am gofalaeth trefn y databas -- fydd y databas yn ôl cyn bo hir.
+Mae'r gweinyddwr wedi dweud yr achos cloi'r databas oedd:
+<p>$1",
+"missingarticle" => "Dydi'r databas ddim wedi dod o hyd i testun tudalen ddyler hi ffindio, sef \"$1\".
+Dydi hwn ddim yn gwall y databas, ond debyg byg yn y meddalwedd.
+Adroddwch hwn i gweinyddwr os gwelwch yn dda, a cofiwch sylwi'r URL.",
+"internalerror" => "Gwall mewnol",
+"filecopyerror" => "Ddim yn gallu copïo ffeil \"$1\" i \"$2\".",
+"filerenameerror" => "Ddim yn gallu ail-enw ffeil \"$1\" i \"$2\".",
+"filedeleteerror" => "Ddim yn gallu dileu ffeil \"$1\".",
+"filenotfound" => "Ddim yn gallu ffeindio ffeil \"$1\".",
+"unexpected" => "Gwerth annisgwyl: \"$1\"=\"$2\".",
+"formerror" => "Gwall: ddim yn medru ymostwng y ffurflen",
+"badarticleerror" => "Mae'n amhosib perfformio'r gweithred hwn ar tudalen hon.",
+"cannotdelete" => "Mae'n amhosib dileu y tudalen neu llun hwn. (Wyrach mae rhywun arall eisoes wedi eu dileu.)",
+"badtitle" => "Teitl drwg",
+"badtitletext" => "Mae'r teitl rydych wedi gofyn yn anilys, gwag, neu cysylltu'n anghywir rhwng ieithoedd neu wicïau.",
+"perfdisabled" => "Sori! Mae'r nodwedd hon wedi cael eu anablo am achosion perfformiadau yn yr amserau brysyrach; dewch yn ôl rhwng 02:00 a 14:00 GMT a triwch eto.",
+"perfdisabledsub" => "Dyma copi rydym wedi cadw ers $1:",
+"wrong_wfQuery_params" => "Incorrect parameters to wfQuery()<br />
+Function: $1<br />
+Query: $2",
+"viewsource" => "Gwyliwch y ffynhonnell",
+"protectedtext" => "Mae tudalen hon wedi cael eu gloi i gwahardd golygu'r tudalen. Mae nifer o rheswmau paham mae hwn wedi digwydd, gwelwch y tudalen
+[[{{ns:project}}:Protected page]].
+
+Ellwch gweld a copïo'r ffynhonnell y tudalen hon:",
+
+# Login and logout pages
+#
+"logouttitle" => "Allgofnodi'r defnyddwr",
+"logouttext" => "Yr ydych wedi allgofnodi.
+Gallwch chi defnyddio'r {{SITENAME}} yn anhysbys, neu gallwch chi mewngofnodi eto fel yr un defnyddwr neu un arall.",
+
+"welcomecreation" => "<h2>Croeso, $1!</h2><p>Mae eich accownt wedi gael eu creu. Peidiwch ac anghofio i personaleiddio eich ffafraethau defnyddwr {{SITENAME}}.",
+"loginpagetitle" => "Mewngofnodi'r defnyddwr",
+"yourname" => "Eich enw defnyddwr",
+"yourpassword" => "Eich allweddair",
+"yourpasswordagain" => "Ail-teipiwch allweddair",
+"remembermypassword" => "Cofiwch fy allweddair dros mwy nag un sesiwn.",
+"loginproblem" => "<b>Mae problem efo'ch mewngofnodi.</b><br />Triwch eto!",
+"alreadyloggedin" => "<strong>Defnyddwr $1, yr ydych eisioes wedi mewngofnodi!</strong><br />",
+
+"login" => "Mewngofnodi",
+"loginprompt" => "Rhaid i chi galluogi cwcis i mewngofnodi i {{SITENAME}}.",
+"userlogin" => "Mewngofnodi",
+"logout" => "Allgofnodi",
+"userlogout" => "Allgofnodi",
+"notloggedin" => "Nid wedi mewngofnodi",
+"createaccount" => "Creuwch accownt newydd",
+"createaccountmail" => "gan e-post",
+"badretype" => "Dydy'r allweddgeiriau ddim yn cymharu.",
+"userexists" => "Mae rhywun arall wedi dewis yr enw defnyddwr. Dewiswch un arall os gwelwch yn dda.",
+"youremail" => "Eich cyfeiriad e-bost",
+"yournick" => "Eich llysenw (am llofnod)",
+"loginerror" => "Problem mewngofnodi",
+"nocookiesnew" => "Mae'r accownt defnyddiwr wedi gael eu creu, ond dydwch chi ddim wedi mewngofnodi. Mae {{SITENAME}} yn defnyddio cwcis i mewngofnodi defnyddwyr. Rydych chi wedi anablo cwcis. Galluogwch nhw os welwch yn dda, felly mewngofnodwch gyda'ch enw defnyddiwr a cyfrinair newydd.",
+"nocookieslogin" => "Mae {{SITENAME}} yn defnyddio cwcis i mewngofnodi defnyddwyr. Rydych chi wedi anablo cwcis. Galluogwch nhw os welwch yn dda, a triwch eto.",
+"noname" => "Dydi chi ddim wedi enwi enw defnyddwr dilys.",
+"loginsuccesstitle" => "Mewngofnod llwyddiannus",
+"loginsuccess" => "Yr ydych wedi mewngofnodi i {{SITENAME}} fel \"$1\".",
+"nosuchuser" => "Does dim defnyddwr gyda'r enw \"$1\".
+Sicrhau rydych chi wedi sillafu'n iawn, neu creuwch accownt newydd gyda'r ffurflen isod.",
+"wrongpassword" => "Mae'r allweddair rydych wedi teipio ddim yn cywir. Triwch eto, os gwelwch yn dda.",
+"mailmypassword" => "E-postiwch allweddair newydd i fi",
+"passwordremindertitle" => "Nodyn atgoffa allweddair oddiwrth {{SITENAME}}",
+"passwordremindertext" => "Mae rhywun (chi, yn tebygol, oddiwrth cyfeiriad IP $1) wedi gofyn iddi ni danfon allweddair mewngofnodi newydd {{SITENAME}}.
+Allweddair defnyddwr \"$2\" rwan yw \"$3\". Ddylwch chi mewngofnodi rwan a newid yr allweddair.",
+"noemail" => "Does dim cyfeiriad e-bost wedi cofrestru dros defnyddwr \"$1\".",
+"passwordsent" => "Mae allweddair newydd wedi gael eu ddanfon at y cyfeiriad e-bost cofrestredig am \"$1\". Mewngofnodwch eto, os gwelwch yn dda, ar ol i chi dderbyn yr allweddair.",
+
+# Edit page toolbar
+"bold_sample" => "Testun cryf",
+"bold_tip" => "Testun cryf",
+"italic_sample" => "Testun italig",
+"italic_tip" => "Testun italig",
+"link_sample" => "Teitl cyswllt",
+"link_tip" => "Cyswllt mewnol",
+"extlink_sample" => "http://www.example.com cyswllt teitl",
+"extlink_tip" => "Cyswllt allanol (cofiwch y rhagddodiad http:// )",
+"headline_sample" => "Testun pennawd",
+"headline_tip" => "Pennawd safon 2",
+"math_sample" => "Mewnosodwch fformwla yma",
+"math_tip" => "Fformwla mathemategol (LaTeX)",
+"nowiki_sample" => "Mewnosodwch testun di-fformatedig yma",
+"nowiki_tip" => "Anwybyddwch fformatiaeth wiki",
+"image_sample" => "Example.jpg",
+"image_tip" => "Delwedd mewnosod",
+"media_sample" => "Example.mp3",
+"media_tip" => "Cyswllt ffeil media",
+"sig_tip" => "Eich llofnod gyda stamp amser",
+"hr_tip" => "Llinell llorweddol (defnyddiwch yn cynnil)",
+
+# Edit pages
+#
+"summary" => "Crynodeb",
+"subject" => "Testun/pennawd",
+"minoredit" => "Mae hwn yn golygiad bach",
+"watchthis" => "Gwyliwch erthygl hon",
+"savearticle" => "Cadw tudalen",
+"preview" => "Blaenwelediad",
+"showpreview" => "Gweler blaenwelediad",
+"blockedtitle" => "Mae'r defnyddwr wedi gael eu blocio",
+"blockedtext" => "Mae eich enw defnyddwr neu cyfeiriad IP wedi gael eu blocio gan $1. Y rheswm yw:<br />''$2''<p>Ellwch cysylltu $1 neu un o'r
+[[{{ns:project}}:administrators|swyddogion]] eraill i trafodi'r bloc.",
+"whitelistedittitle" => "Rhaid mewngofnodi i golygu",
+"whitelistedittext" => "Rhaid i chi [[Special:Userlogin|mewngofnodi]] i olygu erthyglau.",
+"whitelistreadtitle" => "Rhaid mewngofnodi i ddarllen",
+"whitelistreadtext" => "Rhaid i chi [[Special:Userlogin|mewngofnodi]] i ddarllen erthyglau.",
+"whitelistacctitle" => "Ni chaniateir creu accownt",
+"whitelistacctext" => "I gael caniatâd i creu accownt yn y wiki hon, rhaid i chi [[Special:Userlogin|mewngofnodi]] a chael y caniatâd priodol.",
+"accmailtitle" => "Wedi danfon cyfrinair.",
+"accmailtext" => "Mae'r cyfrinair am '$1' wedi danfon i $2.",
+"newarticle" => "(Newydd)",
+"newarticletext" =>
+"Yr ydych wedi dilyn cysylltiad i tudalen sydd ddim wedi gael eu creu eto.
+I creuo'r tudalen, dechreuwch teipio yn y bocs isaf
+(gwelwch y [[{{ns:project}}:Help|tudalen help]] am mwy o hysbys).
+Os ydych yma trwy camgymeriad, cliciwch eich botwm '''nol'''.",
+"anontalkpagetext" => "---- ''Dyma tudalen sgwrsio am defnyddwr sydd ddim eto wedi creu accownt, neu ddim yn eu defnyddio. Rhaid i ni defnyddio'r [[cyfeiriad IP]] rhifiadol i adnabod fe neu hi. Mae'n posib i llawer o bobl siario'r un cyfeiriad IP. Os ydych chi'n defnyddwr anhysbys ac yn teimlo mae esboniadau amherthynol wedi cael eu gwneud arnach chi, creuwch accownt neu mewngofnodwch i osgoi anhrefn gyda defnyddwyr anhysbys yn y dyfodol.''",
+"noarticletext" => "(Does dim testun yn y tudalen hon eto)",
+"updated" => "(Diweddariad)",
+"note" => "<strong>Sylwch:</strong>",
+"previewnote" => "Cofiwch blaenwelediad ydi hwn, a dydi e ddim wedi cael eu chadw!",
+"previewconflict" => "Mae blaenwelediad hwn yn dangos y testun yn yr ardal golygu uchaf, fel y fydd hi'n edrych os dewyswch chi arbed.",
+"editing" => "Yn golygu $1",
+'editinguser' => "Yn golygu $1",
+"editingsection" => "Yn golygu $1 (rhan)",
+"editingcomment" => "Yn golygu $1 (esboniad)",
+"editconflict" => "Croestynnu golygyddol: $1",
+"explainconflict" => "Mae rhywun arall wedi newid y tudalen hon ers i chi dechrau golygu hi. Mae'r ardal testun uchaf yn cynnwys testun y tudalen fel y mae hi rwan. Mae eich newidiadau yn ddangos yn yr ardal testun isaf.
+Fydd rhaid i chi ymsoddi eich newidiadau i mewn i'r testun sydd mewn bod.
+<b>Dim ond</b> y testun yn yr ardal testun uchaf fydd yn cael eu cadw pan rydwch yn gwasgu \"Cadw tudalen\".<br />",
+"yourtext" => "Eich testun",
+"storedversion" => "Fersiwn wedi cadw",
+"editingold" => "<strong>RHYBUDD: Rydych yn golygu hen fersiwn y tudalen hon. Os cadwch hi, fydd unrhyw newidiadau hwyrach yn gael eu colli!.</strong>",
+"yourdiff" => "Gwahaniaethau",
+/*"copyrightwarning" => "Sylwch mae pob cyfraniad i {{SITENAME}} yn gael eu rhyddhau o dan termau'r Trwydded Dogfen Rhydd GNU (gwelwch $1 am manylion).
+Os nid ydych chi'n fodlon cael eich ysgrifeniad eu golygu heb trugaredd, a creu copïau dros y wê, peidiwch cyfranu'r ysgrifeniad yma.<br />
+Hefyd, rydych chi'n addo chi yw'r awdur y cyfraniad, neu rydych chi wedi copïo fe oddiwrth y parth cyhoeddus neu rhyw modd rhydd tebyg.
+<strong>PEIDIWCH CYFRANNU GWAITH O DAN HAWLFRAINT HEB CANIATÂD!</strong>",*/
+"longpagewarning" => "<strong>RHYBUDD: Mae hyd y tudalen hon yn $1 kilobyte; mae rhai porwyr yn cael problemau yn golygu tudalennau hirach na 32kb.<br />
+Ystyriwch torri'r tudalen i mewn i ddarnau llai, os gwelwch yn dda.</strong>",
+"readonlywarning" => "<strong>RHYBUDD: Mae'r databas wedi cloi i gael eu trwsio,
+felly fyddwch chi ddim yn medru cadw eich olygiadau rwan. Efalle fyddwch chi'n eisio tori-a-pastio'r
+testun i mewn i ffeil testun, a cadw hi tan hwyrach.</strong>",
+"protectedpagewarning" => "<strong>RHYBUDD: Mae tudalen hon wedi eu gloi -- dim ond defnyddwyr
+gyda braintiau 'sysop' sy'n medru eu olygu. Byddwch yn siwr rydych yn dilyn y
+[[Project:Protected_page_guidelines|gwifrau tywys tudalen amddiffyn]].</strong>",
+
+# History pages
+#
+"revhistory" => "Hanes cywiriadau",
+"nohistory" => "Does dim hanes cywiriadau am tudalen hon.",
+"revnotfound" => "Cywiriad nid wedi darganfod",
+"revnotfoundtext" => "Ni ellir darganfod yr hen cywiriad y tudalen rydych wedi gofyn amdano. Gwiriwch yr URL rydych wedi defnyddio i darganfod y tudalen hon.",
+"loadhist" => "Yn llwytho hanes y tudalen",
+"currentrev" => "Diwygiad cyfoes",
+"revisionasof" => "Diwygiad $1",
+"cur" => "cyf",
+"next" => "nesaf",
+"last" => "olaf",
+"orig" => "gwreidd",
+"histlegend" => "Eglurhad: (cyf) = gwahaniaeth gyda fersiwn cyfoes,
+(olaf) = gwahaniaeth gyda fersiwn gynt, M = golygiad mân",
+
+# Diffs
+#
+"difference" => "(Gwahaniaethau rhwng fersiwnau)",
+"loadingrev" => "yn llwytho diwygiad am wahaniaeth",
+"lineno" => "Llinell $1:",
+"editcurrent" => "Golygwch fersiwn cyfoes tudalen hon",
+
+# Search results
+#
+"searchresults" => "Canlyniadau chwiliad",
+"searchresulttext" => "Am mwy o hysbys amdano chwilio {{SITENAME}}, gwelwch [[{{ns:project}}:Yn chwilio|Yn chwilio {{SITENAME}}]].",
+"searchsubtitle" => "Am gofyniad \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Am gofyniad \"$1\"",
+"badquery" => "Gofyniad chwilio drwg",
+"badquerytext" => "Roedd yn amhosibl i prosesu'ch gofyniad.
+Mae'n tebygol roedd hyn am achos yr ydych wedi trio chwilio a gair gyda llai na tri llythyrau. Hefyd, wyrach rydych wedi cam-teipio'r gofyniad. Triwch gofyniad arall.",
+"matchtotals" => "Mae'r gofyniad \"$1\" wedi cyfatebu $2 teitlau erthyglau, a'r testun oddiwrth $3 erthyglau.",
+"titlematches" => "Teitlau erthygl yn cyfateb",
+"notitlematches" => "Does dim teitlau erthygl yn cyfateb",
+"textmatches" => "Testun erthygl yn cyfateb",
+"notextmatches" => "Does dim testun erthyglau yn cyfateb",
+"prevn" => "$1 gynt",
+"nextn" => "$1 nesaf",
+"viewprevnext" => "Gweler ($1) ($2) ($3).",
+"showingresults" => "Yn dangos isod y <b>$1</b> canlyniadau yn dechrau gyda #<b>$2</b>.",
+"nonefound" => "<strong>Sylwch</strong>: mae chwiliadau yn aml yn anlwyddiannus am achos mae'r chwiliad yn edrych a geiriau cyffredin fel \"y\" ac \"ac\",
+sydd ddim yn cael eu mynegai.",
+"powersearch" => "Chwilio",
+"powersearchtext" => "
+Edrychwch mewn lle-enw:<br />
+$1<br />
+$2 Rhestrwch ail-cyfeiriadau &nbsp; Chwiliwch am $3 $9",
+"searchdisabled" => "<p>Mae'r peiriant chwilio'r holl databas wedi cael eu troi i ffwrdd i gwneud pethau'n hawddach ar y gwasanaethwr. Gobeithiwn fydd yn bosibl i troi'r peiriant ymlaen cyn bo hir, ond yn y cyfamser mae'n posibl gofyn Google:</p>",
+"blanknamespace" => "(Prif)",
+
+
+# Preferences page
+#
+"preferences" => "ffafraethau",
+"prefsnologin" => "Nid wedi mewngofnodi",
+"prefsnologintext" => "Rhaid i chi [[Special:Userlogin|mewngofnodi]]
+i setio ffafraethau defnyddwr.",
+"prefsreset" => "Mae ffafraethau wedi gael eu ail-setio oddiwrth y storfa.",
+"qbsettings" => "Gosodiadau bar-gyflym",
+"changepassword" => "Newydwch allweddair",
+"skin" => "Croen",
+"math" => "Rendro mathemateg",
+"math_failure" => "wedi methu dosbarthu",
+"math_unknown_error" => "gwall anhysbys",
+"math_unknown_function" => "ffwythiant anhysbys",
+"math_lexing_error" => "gwall lecsio",
+"math_syntax_error" => "gwall cystrawen",
+"saveprefs" => "Cadw ffafraethau",
+"resetprefs" => "Ail-setio ffafraethau",
+"oldpassword" => "Hen allweddair",
+"newpassword" => "Allweddair newydd",
+"retypenew" => "Ail-teipiwch yr allweddair newydd",
+"textboxsize" => "Maint y bocs testun",
+"rows" => "Rhesi",
+"columns" => "Colofnau",
+"searchresultshead" => "Sefydliadau canlyniadau chwilio",
+"resultsperpage" => "Hitiau i ddangos ar pob tudalen",
+"contextlines" => "Llinellau i ddangos ar pob hit",
+"contextchars" => "Characters of context per line",
+"stubthreshold" => "Threshold for stub display",
+"recentchangescount" => "Nifer o teitlau yn newidiadau diweddar",
+"savedprefs" => "Mae eich ffafraethau wedi cael eu chadw.",
+"timezonetext" => "Teipiwch y nifer o oriau mae eich amsel lleol yn wahân o'r amser y gwasanaethwr (UTC/GMT).",
+"localtime" => "Amser lleol",
+"timezoneoffset" => "Atred",
+"servertime" => "Amser y gwasanaethwr yw",
+"guesstimezone" => "Llenwch oddiwrth y porwr",
+"defaultns" => "Gwyliwch yn llefydd-enw rhain:",
+
+# Recent changes
+#
+"changes" => "newidiadau",
+"recentchanges" => "Newidiadau diweddar",
+"recentchangestext" => "Traciwch y newidiadau mor diweddar i'r {{SITENAME}} ac i'r tudalen hon.",
+"rcnote" => "Isod yw'r newidiadau <strong>$1</strong> olaf yn y <strong>$2</strong> dyddiau olaf.",
+"rcnotefrom" => "Isod yw'r newidiadau ers <b>$2</b> (dangosir i fynu i <b>$1</b>).",
+"rclistfrom" => "Dangos newidiadau newydd yn dechrau oddiwrth $1",
+"rclinks" => "Dangos y $1 newidiadau olaf yn y $2 dyddiau olaf.",
+"diff" => "gwahan",
+"hist" => "hanes",
+"hide" => "cuddio",
+"show" => "dangos",
+"minoreditletter" => "B",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => "Llwytho ffeil i fynu",
+"uploadbtn" => "Llwytho ffeil i fynu",
+"reupload" => "Ail-llwytho i fynu",
+"reuploaddesc" => "Return to the upload form.",
+"uploadnologin" => "Nid wedi mewngofnodi",
+"uploadnologintext" => "Rhaid i chi bod wedi [[Special:Userlogin|mewngofnodi]]
+i lwytho ffeiliau i fynu.",
+"uploaderror" => "Gwall yn llwytho ffeil i fynu",
+"uploadtext" => "'''STOPIWCH!''' Cyn iddich chi llwytho lluniau yma, darllenwch a dilynwch [[Project:Polisi_defnyddio_lluniau|polisi defnyddio lluniau]] {{SITENAME}} os gwelwch yn dda.
+
+I gweld neu chwilio hen lluniau ewch i'r
+[[Arbennig:Imagelist|rhestr lluniau wedi llwytho]].
+Mae pob llwyth a dileuo ffeil yn cael eu recordio ar y
+[[Project:Upload_log||log llwytho]].
+
+Defnyddwch y ffurflen isod i llwytho ffeil llun newydd i darluno eich erthyglau.
+Ar y mwyafrif o porwyr, fyddwch yn gweld botwm \"Pori/Browse...\" i agor y dialog agor ffeil arferol.
+Fydd dewis ffeil y llenwi enw'r ffeil yn y cae testun nesaf i'r botwm.
+Mae rhaid i chi hefyd ticio'r blaidd i addo rydych chi ddim yn torri hawlfraintiau rhywun arall trwy llwytho'r ffeil.
+Gwasgwch y botwm \"Llwytho/Upload\" i gorffen y llwyth.
+Ellith hwn cymyd dipyn o amser os mae gennych chi cysylltiad rhyngrwyd araf.
+
+Y fformatiau gwell gennym ni yw JPEG am lluniau ffotograffiaeth, PNG
+am lluniadau a delweddau iconydd eraill, ag OGG am seiniau.
+Enwch eich ffeil yn disgrifiadol i osgoi anhrefn os gwelwch yn dda.
+I cynnwys y llun mewn erthygl, defnyddwch cysylltiad yn y ffurf
+'''<nowiki>[[llun:ffeil.jpg]]</nowiki>''' neu
+'''<nowiki>[[llun:ffeil.png|testun arall]]</nowiki>''' neu
+'''<nowiki>[[media:ffeil.ogg]]</nowiki>''' am sain.
+
+Sylwch -- fel efo tudalennau {{SITENAME}}, ellith pobl eraill golygu neu dileu eich ffeil os ydyn nhw'n meddwl fyddynt yn helpu'r gwyddoniadur, ac ellwch chi cael eich gwaharddio os ydych chi'n sarhau'r system.",
+"uploadlog" => "log llwytho i fynu",
+"uploadlogpage" => "log_llwytho_i_fynu",
+"uploadlogpagetext" => "Isod mae rhestr o'r llwythu ffeil diweddarach.
+Pob amser sy'n dangos yw amser y gwasanaethwr (UTC).
+<ul>
+</ul>",
+"filename" => "Enw ffeil",
+"filedesc" => "Crynodeb",
+"filestatus" => "Statws hawlfraint",
+"filesource" => "Ffynhonnell",
+"copyrightpage" => "{{ns:project}}:Hawlfraint",
+"copyrightpagename" => "Hawlfraint {{SITENAME}}",
+"uploadedfiles" => "Ffeiliau wedi llwytho i fynu",
+"minlength" => "Rhaid enwau lluniau bod o leia tri llythrennau.",
+"badfilename" => "Mae enw'r llun wedi newid i \"$1\".",
+"badfiletype" => "Nid yw \".$1\" yn fformat ffeil lluniau cymeradwy.",
+"largefile" => "Mae'n cymeradwy dydy lluniau nid mwy na 100k o faint.",
+"successfulupload" => "Llwyth i fynu yn llwyddiannus",
+"fileuploaded" => "Mae ffeil \"$1\" wedi llwytho'n llwyddiannnus.
+Dilynwch y cyswllt hon: ($2) i'r tudalen disgrifiad a llenwch gwybodaeth amdano'r ffeil (ble mae'n dod o, pwy a creu o, beth bynnag arall rydych chi'n gwybod amdano'r ffeil.",
+"uploadwarning" => "Rhybudd llwytho i fynu",
+"savefile" => "Cadw ffeil",
+"uploadedimage" => "\"[[$1]]\" wedi llwytho",
+"uploaddisabled" => "Mae ddrwg gennym ni, mae uwchllwytho wedi anablo.",
+
+# Image list
+#
+"imagelist" => "Rhestr delweddau",
+"imagelisttext" => "Isod mae rhestr o $1 delweddau wedi trefnu $2.",
+"getimagelist" => "yn nôl rhestr delweddau",
+"ilsubmit" => "Chwilio",
+"showlast" => "Dangos y $1 delweddau olaf wedi trefnu $2.",
+"byname" => "gan enw",
+"bydate" => "gan dyddiad",
+"bysize" => "gan maint",
+"imgdelete" => "difl",
+"imgdesc" => "disg",
+"imglegend" => "Eglurhad: (disg) = dangos/golygu disgrifiad y delwedd.",
+"imghistory" => "Hanes y delwedd",
+"revertimg" => "dych",
+"deleteimg" => "dil",
+"deleteimgcompletely" => "dil",
+"imghistlegend" => "Eglurhad: (cyf) = hon yw'r delwedd cyfoes, (dil) = dilewch yr hen fersiwn hon, (dych) = dychwelio i hen fersiwn hon.
+<br /><i>Cliciwch ar dyddiad i weld y delwedd ag oedd llwythiad ar y dyddiad hon</i>.",
+"imagelinks" => "Cysylltiadau delwedd",
+"linkstoimage" => "Mae'r tudalennau isod yn cysylltu i'r delwedd hon:",
+"nolinkstoimage" => "Does dim tudalen yn cysylltu i'r delwedd hon.",
+
+# Statistics
+#
+"statistics" => "Ystadegau",
+"sitestats" => "Ystadegau'r seit",
+"userstats" => "Ystadegau defnyddwyr",
+"sitestatstext" => "Mae <b>$1</b> tudalennau ar y databas.
+Mae hyn yn cynnwys tudalennau \"sgwrs\", tudalennau amdano {{SITENAME}}, tudalennau \"stwbyn\" bach, ail-cyfeirnodau, ac eraill sydd dim yn cymwysoli fel erthyglau. Ag eithrio y rheini, mae <b>$2</b> tudalennau yn tebyg yn erthyglau iawn.<p>
+Mae 'ne wedi bod <b>$3</b> golygon o tudalennau, a <b>$4</b> tudalennau wedi golygu ers i'r meddalwedd gael eu sefydliad (12 Gorffennaf 2003).
+Sef <b>$5</b> golygiadau pob tudalen, ar gyfartaledd, a <b>$6</b> golygon o bob golygiad.",
+"userstatstext" => "Mae 'ne <b>$1</b> defnyddwyr wedi cofrestru.
+(Mae <b>$2</b> yn gweinyddwyr (gwelwch $3)).",
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Erthyglau heb cysylltiadau",
+"unusedimages" => "Lluniau di-defnyddio",
+"popularpages" => "Erthyglau poblogol",
+"nviews" => "$1 golwgfeydd",
+"wantedpages" => "Erthyglau mewn eisiau",
+"nlinks" => "$1 cysylltiadau",
+"allpages" => "Pob tudalennau",
+"randompage" => "Erthygl hapgyrch",
+"shortpages" => "Erthyglau byr",
+"longpages" => "Erthyglau hir",
+"deadendpages" => "Tudalennau heb cysylltiadau",
+"listusers" => "Rhestr defnyddwyr",
+"specialpages" => "Erthyglau arbennig",
+"spheading" => "Erthyglau arbennig",
+"recentchangeslinked" => "Newidiadau perthnasol",
+"rclsub" => "(i erthyglau cysyllt oddiwrth \"$1\")",
+"newpages" => "Erthyglau newydd",
+"ancientpages" => "Erthyglau hynach",
+"intl" => "Cysylltiadau rhwng ieithau",
+"movethispage" => "Symydwch tudalen hon",
+"unusedimagestext" => "<p>Sylwch mae gwefannau eraill, e.e. y {{SITENAME}}u Rhwngwladol, yn medru cysylltu at llun gyda URL uniongychol, felly mae'n bosibl dangos enw ffeil yma er gwaethaf mae hi'n dal mewn iws.", // TODO: grammar
+"booksources" => "Ffynonellau llyfrau",
+"booksourcetext" => "Isod mae rhestr cysylltiadau i gwefannau eraill sydd yn gwerthu llyfrau newydd ac ail-law, ac wyrach mae ganddynt gwybodaeth am y llyfrau rydych yn chwilio amdano.
+Does gan {{SITENAME}} dim cysylltiad gyda unrhyw o'r masnachau, a dydy rhestr hon ddim yn cymeradwyaeth o honnynt.",
+"alphaindexline" => "$1 i $2",
+"version" => "Fersiwn",
+
+# Email this user
+#
+"mailnologin" => "Dim cyfeiriad i anfon",
+"mailnologintext" => "Rhaid i chi wedi [[Arbennig:Mewngofnodidefnyddwr|mewngofnodi]]
+a rhoi cyfeiriad e-bost dilyn yn eich [[Arbennig:Ffafraethau|ffafraethau]]
+i anfon e-bost i ddefnyddwyr eraill.",
+"emailuser" => "Anfon e-bost i defnyddwr hwn",
+"emailpage" => "Anfon e-bost i defnyddwr",
+"emailpagetext" => "Os yw defnyddwr hwn wedi rhoi cyfeiriad e-bost yn eu ffafraethau, fydd y ffurf isod yn anfon un neges iddo ef. Fydd y cyfeiriad e-bost rydych chi wedi rhoi yn eich ffafraethau yn dangos yn yr \"Oddiwrth\" cyfeiriad yr e-bost, felly fydd y defnyddwr arall yn gallu ateb.",
+"defemailsubject" => "e-post {{SITENAME}}",
+"noemailtitle" => "Dim cyfeiriad e-bost",
+"noemailtext" => "Dydy defnyddwr hwn ddim wedi rhoi cyfeiriad e-bost dilys, neu mae e wedi dewis nid i dderbyn e-bost oddiwrth defnyddwyr eraill.",
+"emailfrom" => "Oddiwrth",
+"emailto" => "I",
+"emailsubject" => "Pwnc",
+"emailmessage" => "Neges",
+"emailsend" => "Anfon",
+"emailsent" => "Neges e-bost wedi danfon",
+"emailsenttext" => "Mae eich neges e-bost wedi gael ei anfon.",
+
+# Watchlist
+#
+"watchlist" => "Fy rhestr gwylio",
+"nowatchlist" => "Does ganddoch chi ddim eitem ar eich rhestr gwylio.",
+"watchnologin" => "Dydych chi ddim wedi mewngofnodi",
+"watchnologintext" => "Rhaid i chi bod wedi [[Special:Userlogin|mewngofnodi]]
+i adnewid eich rhestr gwylio.",
+"addedwatch" => "Wedi adio i'ch rhestr gwylio",
+"addedwatchtext" => "Mae tudalen \"$1\" wedi gael eu ychwanegu i eich <a href=\"" .
+ "{{localurle:Arbennig:Rhestr_gwylio}}\">rhestr gwylio</a>.
+Pan fydd y tudalen hon, a'i tudalen Sgwrs, yn newid, fyddynt yn dangos <b>yn cryf</b> yn y <a href=\"" .
+ "{{localurle:Arbennig:Newidiadau_diweddar}}\">rhestr newidiadau diweddar</a>, i bod yn hawsach i gweld.</p>
+
+<p>Os ydych chi'n eisiau cael gwared ar y tudalen yn hwyrach, cliciwch ar \"Stopiwch gwylio\" yn y bar ar y chwith.",
+"removedwatch" => "Wedi diswyddo oddiwrth y rhestr gwylio",
+"removedwatchtext" => "Mae tudalen \"$1\" wedi cael ei diswyddo oddiwrth eich rhestr gwylio.",
+"watchthispage" => "Gwyliwch y tudalen hon",
+"unwatchthispage" => "Stopiwch gwylio",
+"notanarticle" => "Nid erthygl",
+"watchnochange" => "Does dim o'r erthyglau rydych chi'n gwylio wedi golygu yn yr amser sy'n dangos.",
+"watchdetails" => "(Yn gwylio $1 tudalennau, nid yn cyfri tudalennau sgwrs;
+wedi olygu $2 tudalennau ers y toriad;
+$3...
+[$4 dangos ac olygu y rhestr cyfan].)",
+"watchmethod-recent"=> "gwiriwch golygiadau diweddar am tudalennau gwyliad",
+"watchmethod-list" => "yn gwirio tudalennau gwyliad am olygiadau diweddar",
+"removechecked" => "Dileuwch eitemau sydd gyda tic o'ch rhestr gwylio",
+"watchlistcontains" => "Mae eich rhestr gwylio yn cynnwys $1 tudalennau.",
+"watcheditlist" => "Dyma rhestr wyddorol o'r tudalennau rydych yn wylio.
+Ticiwch blwchau y tudalennau rydych eisiau symud o'ch rhestr gwylio, a cliciwch
+y botwm 'dileu' ar gwaelod y sgrîn.",
+"removingchecked" => "Yn dileu'r eitemau rydych wedi gofyn o'ch rhestr gwylio...",
+"couldntremove" => "Wedi methu dileu eitem '$1'...",
+"iteminvalidname" => "Problem gyda eitem '$1', enw annilys...",
+"wlnote" => "Isod yw'r $1 newidiadau olaf yn y <b>$2</b> oriau diwethaf.",
+"wlshowlast" => "Dangos y $1 oriau $2 dyddiau $3 diwethaf",
+"wlsaved" => "Dyma copi o'ch rhestr gwylio rydym ni wedi cadw.",
+
+# Delete/protect/revert
+#
+"deletepage" => "Dileuwch y tudalen",
+"confirm" => "Cadarnhau",
+"excontent" => "y cynnwys oedd: '$1'",
+"exbeforeblank" => "y cynnwys cyn blancio oedd: '$1'",
+"exblank" => "y tudalen oedd yn wâg",
+"confirmdelete" => "Cadarnhaewch y dileuad",
+"deletesub" => "(Yn dileuo \"$1\")",
+"historywarning" => "Rhubydd: Mae hanes gan y tudalen yr ydych yn mynd i dileuo:",
+"confirmdeletetext" => "Rydych chi'n mynd i dileu erthygl neu llun yn parhaol, hefyd gyda'u hanes, oddiwrth y databas.
+Cadarnhaewch yr ydych yn bwriadu gwneud hwn, ac yr ydych yn ddeallt y canlyniad, ac yr ydych yn gwneud hwn yn ôl [[{{ns:project}}:Polisi]].",
+"actioncomplete" => "Gweithred llwyr",
+"deletedtext" => "Mae \"$1\" wedi eu dileu.
+Gwelwch $2 am cofnod o dileuon diweddar.",
+"deletedarticle" => "wedi dileu \"$1\"",
+"dellogpage" => "Log_dileuo",
+"dellogpagetext" => "Isod mae rhestr o'r dileuon diweddarach.
+<ul>
+</ul>",
+"deletionlog" => "Log dileuon",
+"reverted" => "Wedi mynd nôl i fersiwn gynt",
+"deletecomment" => "Achos dileuad",
+"imagereverted" => "Gwrthdroad i fersiwn gynt yn llwyddiannus.",
+"rollback" => "Roliwch golygon yn ôl",
+"rollbacklink" => "rolio nôl",
+"cantrollback" => "Ddim yn gallu gwrthdroi golygiad; y cyfrannwr olaf oedd yr unrhyw awdur yr erthygl hon.",
+"alreadyrolled" => "Amhosib rolio nôl golygiad olaf [[:$1]]
+gan [[Defnyddwr:$2|$2]] ([[Sgwrs defnyddwr:$2|Sgwrs]]); mae rhywun arall yn barod wedi olygu neu rolio nôl yr erthygl.
+
+[[Defnyddwr:$3|$3]] ([[Sgwrs defnyddwr:$3|Sgwrs]] gwneuthoedd yr olygiad olaf).",
+# only shown if there is an edit comment
+"editcomment" => "Crynodeb y golygiad oedd: \"<i>$1</i>\".",
+"revertpage" => "Wedi gwrthdroi i golygiad olaf gan $1",
+"protectlogpage" => "Log_amdiffyno",
+"protectlogtext" => "Isod mae rhestr o cloion/datgloion tudalennau.
+Gwelwch [[{{ns:project}}:Tudalen amddiffynol]] am mwy o wybodaeth.",
+"protectedarticle" => "wedi amddiffyno [[$1]]",
+"unprotectedarticle" => "wedi di-amddiffyno [[$1]]",
+
+# Undelete
+"undelete" => "Gwrthdroi tudalen wedi dileuo",
+"undeletepage" => "Gwyliwch ac adferiwch tudalennau wedi dileuo",
+"undeletepagetext" => "Mae'r tudalennau isod wedi cael eu dileuo ond mae nhw'n dal yn yr archif ac maen bosibl adferio nhw. Mae'r archif yn cael eu glanhau o dro i dro.",
+"undeletearticle" => "Adferiwch erthygl wedi dileu",
+"undeleterevisions" => "$1 fersiwnau yn yr archif",
+"undeletehistory" => "Os adferiwch y tudalen, fydd holl y fersiwnau yn gael eu adferio yn yr hanes. Os mae tudalen newydd wedi gael eu creu ers i'r tudalen bod yn dileu, fydd y fersiwnau adferol yn dangos yn yr hanes gynt ond ni fydd y fersiwn cyfoes yn gael eu allosodi.",
+"undeleterevision" => "wedi dileu fersiwn $1",
+"undeletebtn" => "Adferiwch!",
+"undeletedarticle" => "wedi adferio \"$1\"",
+
+
+# Contributions
+#
+"contributions" => "Cyfraniadau defnyddwr",
+"mycontris" => "Fy nghyfraniadau",
+"contribsub" => "Dros $1",
+"nocontribs" => "Dim wedi dod o hyd i newidiadau gyda criterion hyn.",
+"ucnote" => "Isod mae y <b>$1</b> newidiadau yn y <b>$2</b> dyddiau olaf am defnyddwr hwn.",
+"uclinks" => "Gwelwch y $1 newidiadau olaf; gwelwch y $2 dyddiau olaf.",
+"uctop" => " (top)" ,
+
+# What links here
+#
+"whatlinkshere" => "Beth sy'n cysylltu yma",
+"notargettitle" => "Dim targed",
+"notargettext" => "Dydych chi ddim wedi dewis tudalen targed neu defnyddwr.",
+"linklistsub" => "(Rhestr cysylltiadau)",
+"linkshere" => "Mae'r tudalennau isod yn cysylltu yma:",
+"nolinkshere" => "Does dim tudalennau yn cysylltu yma.",
+"isredirect" => "tudalen ail-cyfeirnod",
+
+# Block/unblock IP
+#
+"blockip" => "Blociwch cyfeiriad IP",
+"blockiptext" => "Defnyddwch y ffurflen isod i blocio mynedfa ysgrifenol oddiwrth cyfeiriad IP cymharol.
+Ddylwch dim ond gwneud hwn i stopio fandaliaeth, yn dilyn a [[{{ns:project}}:Polisi|polisi {{SITENAME}}]].
+Llenwch rheswm am y bloc, isod (e.e. enwch y tudalennau a oedd wedi fandalo).",
+"ipaddress" => "Cyfeiriad IP",
+"ipbexpiry" => "Diwedd",
+"ipbreason" => "Achos",
+"ipbsubmit" => "Blociwch y cyfeiriad hwn",
+"badipaddress" => "Dydy'r cyfeiriad IP ddim yn ddilys.",
+"blockipsuccesssub" => "Bloc yn llwyddiannus",
+"blockipsuccesstext" => "Mae cyfeiriad IP \"$1\" wedi cael eu blocio.
+<br />Gwelwch [[Arbennig:Ipblocklist|rhestr bloc IP]] i arolygu blociau.",
+"unblockip" => "Di-blociwch cyfeiriad IP",
+"unblockiptext" => "Defnyddwch y ffurflen isod i di-blocio mynedfa ysgrifenol i cyfeiriad IP sydd wedi cael eu blocio'n gynt.",
+"ipusubmit" => "Di-blociwch y cyfeiriad hwn",
+"ipblocklist" => "Rhestr cyfeiriadau IP wedi blocio",
+"blocklistline" => "$1, $2 wedi blocio $3 ($4)",
+"blocklink" => "bloc",
+"unblocklink" => "di-bloc",
+"contribslink" => "cyfraniadau",
+"autoblocker" => "Wedi cloi'n awtomatig am achos rydych chi'n rhannu cyfeiriad IP gyda \"$1\". Rheswm \"$2\".",
+"blocklogpage" => "Log_blociau",
+"blocklogentry" => 'wedi blocio "$1" efo amser diwedd o $2',
+"blocklogtext" => "Dyma log o pryd mae cyfeiriadau wedi cael eu blocio a datblocio. Dydy cyfeiriad
+a sydd wedi blocio'n awtomatig ddim yn cael eu ddangos yma. Gwelwch [[Special:Ipblocklist|rhestr block IP]] am
+y rhestr o blociau a gwaharddiadau sydd yn effeithiol rwan.",
+"unblocklogentry" => 'wedi datblocio "$1"',
+"range_block_disabled" => "Mae gallu sysop i creu dewis o blociau wedi anablo.",
+"ipb_expiry_invalid" => "Amser diwedd ddim yn dilys.",
+"ip_range_invalid" => "Dewis IP annilys.",
+
+
+# Make sysop
+"makesysoptitle" => "Gwnewch sysop allan o defnyddiwr",
+"makesysoptext" => "Defnyddiwch y ffurflen hon i troi defnyddiwr cyffredin i gweinyddwr.
+Teipiwch enw'r defnyddiwr yn y blwch a cliciwch y botwm i troi'r defnyddiwr i gweinyddwr",
+"makesysopname" => "Enw'r defnyddiwr:",
+"makesysopsubmit" => "Gwnewch y defnyddiwr hwn yn gweinyddwr",
+"makesysopok" => "<b>Mae defnyddwr '$1' rwan yn gweinyddwr</b>",
+"makesysopfail" => "<b>Wedi methu troi defnyddwr '$1' i gweinyddwr. (Ydych chi wedi sillafu'r enw'n iawn?)</b>",
+"setbureaucratflag" => "Gosod y fflag biwrocrat",
+
+# Move page
+#
+"movepage" => "Symud tudalen",
+"movepagetext" => "Fydd defnyddio'r ffurflen isod yn ail-enwi tudalen, symud eu hanes gyfan i'r enw newydd.
+Fydd yr hen teitl yn dod tudalen ail-cyfeiriad i'r teitl newydd.
+Ni fydd cysylltiadau i'r hen teitl yn newid; mae rhaid i chi gwirio mae cysylltau'n dal yn mynd i'r lle mae angen iddyn nhw mynd!
+
+Sylwch fydd y tudalen '''ddim''' yn symud os mae 'ne tudalen efo'r enw newydd yn barod ar y databas (sef os mae hi'n gwâg neu yn ail-cyfeiriad heb unrhyw hanes golygu). Mae'n posibl i chi ail-enwi tudalen yn ôl i lle oedd hi os ydych chi wedi gwneud camgymeriad, ac mae'n amhosibl i ysgrifennu dros tudalen sydd barod yn bodoli.
+
+<b>RHYBUDD!</b>
+Ellith hwn bod newid sydyn a llym i tudalen poblogol; byddwch yn siwr rydych chi'n deallt y canlyniadau cyn iddich chi mynd ymlaen gyda hwn.",
+"movepagetalktext" => "Fydd y tudalen sgwrs , os oes ne un, yn symud gyda tudalen hon '''ac eithrio:'''
+*rydych yn symud y tudalen wrth llefydd-enw,
+*mae tudalen sgwrs di-wâg yn barod efo'r enw newydd, neu
+*rydych chi'n di-ticio'r blwch isod.",
+"movearticle" => "Symud tudalen",
+"movenologin" => "Nid wedi mewngofnodi",
+"movenologintext" => "Rhaid i chi bod defnyddwr cofrestredig ac wedi [[Arbennig:Userlogin|mewngofnodi]]
+to move a page.",
+"newtitle" => "i teitl newydd",
+"movepagebtn" => "Symud tudalen",
+"pagemovedsub" => "Symud yn llwyddiannus",
+"pagemovedtext" => "Mae tudalen \"[[$1]]\" wedi symud i \"[[$2]]\".",
+"articleexists" => "Mae tudalen gyda'r enw newydd yn bodoli'n barod, neu mae eich enw newydd ddim yn dilys.
+Dewiswch enw newydd os gwelwch yn dda.",
+"talkexists" => "Mae'r tudalen wedi symud yn llwyddiannus, ond roedd hi'n amhosibl symud y tudalen sgwrs am achos roedd ne un efo'r teitl newydd yn bodoli'n barod. Cysylltwch nhw eich hun, os gwelwch yn dda.",
+"movedto" => "symud i",
+"movetalk" => "Symud tudalen \"sgwrs\" hefyd, os oes un.",
+"talkpagemoved" => "Mae'r tudalen sgwrs hefyd wedi symud.",
+"talkpagenotmoved" => "Dydy'r tudalen sgwrs <strong>ddim</strong> wedi symud.",
+"1movedto2" => "$1 wedi symud i $2",
+
+# Export
+
+"export" => "Export pages",
+"exporttext" => "You can export the text and editing history of a particular
+page or set of pages wrapped in some XML; this can then be imported into another
+wiki running MediaWiki software, transformed, or just kept for your private
+amusement.",
+"exportcuronly" => "Include only the current revision, not the full history",
+
+# Namespace 8 related
+
+"allmessages" => "Holl_negeseuon",
+"allmessagestext" => "Dyma rhestr holl y negeseuon ar gael yn y lle-enw MediaWiki:",
+
+# Thumbnails
+
+"thumbnail-more" => "Helaethwch",
+
+#Math
+'mw_math_png' => "Rendrwch PNG o hyd",
+'mw_math_simple' => "HTML os yn syml iawn, PNG fel arall",
+'mw_math_html' => "HTML os bosibl, PNG fel arall",
+'mw_math_source' => "Gadewch fel TeX (am porwyr testun)",
+'mw_math_modern' => "Cymeradwedig am porwyr modern",
+'mw_math_mathml' => 'MathML',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesDa.php b/languages/messages/MessagesDa.php
new file mode 100644
index 000000000000..6a4d5119a789
--- /dev/null
+++ b/languages/messages/MessagesDa.php
@@ -0,0 +1,1341 @@
+<?php
+/** Danish (Dansk)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciel',
+ NS_MAIN => '',
+ NS_TALK => 'Diskussion',
+ NS_USER => 'Bruger',
+ NS_USER_TALK => 'Brugerdiskussion',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1-diskussion',
+ NS_IMAGE => 'Billede',
+ NS_IMAGE_TALK => 'Billeddiskussion',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki-diskussion',
+ NS_TEMPLATE => 'Skabelon',
+ NS_TEMPLATE_TALK => 'Skabelondiskussion',
+ NS_HELP => 'Hjælp',
+ NS_HELP_TALK => 'Hjælp-diskussion',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Kategoridiskussion'
+
+);
+
+$quickbarSettings = array(
+ 'Ingen', 'Fast venstre', 'Fast højre', 'Flydende venstre'
+);
+
+$skinNames = array(
+ 'standard' => 'Klassisk',
+ 'nostalgia' => 'Nostalgi',
+ 'cologneblue' => 'Cologne-blå',
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. M Y',
+ 'dmy both' => 'j. M Y "kl." H:i',
+);
+
+$bookstoreList = array(
+ "Bibliotek.dk" => "http://bibliotek.dk/vis.php?base=dfa&origin=kommando&field1=ccl&term1=is=$1&element=L&start=1&step=10",
+ "Bogguide.dk" => "http://www.bogguide.dk/find_boeger_bog.asp?ISBN=$1",
+ 'inherit' => true,
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = '/^([a-zæøå]+)(.*)$/sDu';
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+
+$messages = array(
+# User preference toggles
+"tog-underline" => "Understreg henvisninger",
+"tog-highlightbroken" => "Brug røde henvisninger til tomme sider",
+"tog-justify" => "Justér afsnit",
+"tog-hideminor" => "Skjul mindre ændringer i seneste ændringer listen",
+"tog-extendwatchlist" => "Udvidet liste med seneste ændringer",
+"tog-usenewrc" => "Udvidet seneste ændringer liste<br />(ikke for alle browsere)",
+"tog-numberheadings" => "Automatisk nummerering af overskrifter",
+"tog-showtoolbar" => "Vis værktøjslinje til redigering",
+"tog-editondblclick" => "Redigér sider med dobbeltklik (JavaScript)",
+"tog-editsection"=>"Redigér afsnit ved hjælp af [redigér]-henvisning",
+"tog-editsectiononrightclick"=>"Redigér afsnit ved at højreklikke<br /> på afsnittets titel (JavaScript)",
+"tog-showtoc"=>"Vis indholdsfortegnelse<br />(for artikler med mere end tre afsnit)",
+"tog-rememberpassword" => "Husk adgangskode til næste besøg",
+"tog-editwidth" => "Redigeringsboksen har fuld bredde",
+"tog-watchdefault" => "Overvåg nye og ændrede artikler",
+"tog-minordefault" => "Markér som standard alle ændringer som mindre",
+"tog-previewontop" => "Vis forhåndsvisning før redigeringsboksen",
+'tog-previewonfirst' => 'Vis forhåndsvisning når du starter med at redigere',
+"tog-nocache" => "Husk ikke siderne til næste besøg",
+'tog-enotifwatchlistpages' => 'Send mig en e-mail med sideændringer (bemærk: eksisterende beskedmarkeringer skal fjernes manuelt i overvågningslisten)',
+'tog-enotifusertalkpages' => 'Send mig en e-mail når min brugerdiskussionsside ændres (bemærk: eksisterende beskedmarkeringer skal fjernes manuelt i overvågningslisten)',
+'tog-enotifminoredits' => 'Send mig også en e-mail for mindre ændringer af sider (der normalt ikke udløser mails med besked om ændringer)',
+'tog-enotifrevealaddr' => 'Offentliggør min e-mail-adresse i mails med besked om ændringer (når jeg ændrer en side kan brugere, der overvåger siden, hurtigt komme i kontakt med mig)',
+'tog-shownumberswatching' => 'Vis antal brugere, der overvåger (i seneste ændringer-visning, overvågningslisten og i bunden af artikelsider)',
+'tog-fancysig' => 'Signaturer uden automatisk link',
+'tog-externaleditor' => 'Brug ekstern editor automatisk',
+'tog-externaldiff' => 'Brug ekstern forskelsvisning automatisk',
+
+# dates
+'sunday' => 'søndag',
+'monday' => 'mandag',
+'tuesday' => 'tirsdag',
+'wednesday' => 'onsdag',
+'thursday' => 'torsdag',
+'friday' => 'fredag',
+'saturday' => 'lørdag',
+'january' => 'januar',
+'february' => 'februar',
+'march' => 'marts',
+'april' => 'april',
+'may_long' => 'maj',
+'june' => 'juni',
+'july' => 'juli',
+'august' => 'august',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'december',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'maj',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dec',
+
+# Bits of text used by many pages:
+#
+"categories" => "Kategorier",
+"pagecategories" => "Kategorier",
+"category_header" => 'Artikler i kategorien "$1"',
+"subcategories" => "Underkategorier",
+
+"mainpage" => "Forside",
+"mainpagetext" => "MediaWiki er nu installeret.",
+"mainpagedocfooter" => "Se vores engelsksprogede [http://meta.wikimedia.org/wiki/MediaWiki_i18n dokumentation om tilpasning af brugergrænsefladen]
+og [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide brugervejledningen] for oplysninger om opsætning og anvendelse.",
+
+'portal' => 'Forside for skribenter',
+'portal-url' => '{{ns:4}}:Forside',
+"about" => "Om",
+"aboutsite" => "Om {{SITENAME}}",
+"aboutpage" => "{{ns:4}}:Om",
+'article' => 'Artikel',
+"help" => "Hjælp",
+"helppage" => "{{ns:4}}:Hjælp",
+"bugreports" => "Fejlrapporter",
+"bugreportspage" => "{{ns:4}}:Fejlrapporter",
+"sitesupport" => "Donation",
+'sitesupport-url' => '{{ns:4}}:Donation',
+"faq" => "OSS",
+"faqpage" => "{{ns:4}}:OSS",
+"edithelp" => "Hjælp til redigering",
+"newwindow" => "(åbner i et nyt vindue)",
+"edithelppage" => "{{ns:4}}:Hvordan redigerer jeg en side",
+"cancel" => "Afbryd",
+"qbfind" => "Find",
+"qbbrowse" => "Gennemse",
+"qbedit" => "Redigér",
+"qbpageoptions" => "Indstillinger for side",
+"qbpageinfo" => "Information om side",
+"qbmyoptions" => "Mine indstillinger",
+'qbspecialpages' => 'Specielle sider',
+'moredotdotdot' => 'Mere...',
+"mypage" => "Min side",
+"mytalk" => "Min diskussion",
+'anontalk' => 'Diskussionsside for denne IP-adresse',
+'navigation' => 'Navigation',
+
+# Metadata in edit box
+'metadata' => '<b>Metadata</b> (for en foklaring se <a href="$1">her</a>)',
+
+"currentevents" => "Aktuelle begivenheder",
+'currentevents-url' => 'Aktuelle begivenheder',
+
+'disclaimers' => 'Forbehold',
+"disclaimerpage" => "{{ns:4}}:Generelle forbehold",
+"errorpagetitle" => "Fejl",
+"returnto" => "Tilbage til $1.",
+"whatlinkshere" => "Hvad henviser hertil",
+"help" => "Hjælp",
+"search" => "Søg",
+"searchbutton" => "Søg",
+"go" => "Gå til",
+'searcharticle' => "Gå til",
+"history" => "Historik",
+'history_short' => 'Historik',
+'info_short' => 'Information',
+"printableversion" => "Udskriftsvenlig udgave",
+'edit' => 'Redigér',
+"editthispage" => "Redigér side",
+'delete' => 'Slet',
+"deletethispage" => "Slet side",
+"undelete_short" => "Fortryd sletning af $1 versioner",
+'protect' => 'Beskyt',
+"protectthispage" => "Beskyt side",
+'unprotect' => 'Fjern beskyttelse',
+"unprotectthispage" => "Fjern beskyttelse af side",
+"newpage" => "Ny side",
+"talkpage" => "Diskussionssiden",
+'specialpage' => 'Speciel side',
+'personaltools' => 'Personlige værktøjer',
+"postcomment" => "Tilføj en kommentar",
+"articlepage" => "Se artiklen",
+'talk' => 'Diskussion',
+'toolbox' => 'Værktøjer',
+"userpage" => "Se brugersiden",
+"projectpage" => "Se metasiden",
+"imagepage" => "Se billedsiden",
+"viewtalkpage" => "Se diskussion",
+"otherlanguages" => "Andre sprog",
+"redirectedfrom" => "(Omdirigeret fra $1)",
+"lastmodifiedat" => "Denne side blev senest ændret den $2, $1.",
+"viewcount" => "Siden er vist i alt $1 gange.",
+'copyright' => 'Indholdet&nbsp;er&nbsp;udgivet&nbsp;under&nbsp;$1.',
+"protectedpage" => "Beskyttet side",
+'badaccess' => 'Permission error',
+
+'nbytes' => '$1 bytes',
+"go" => "Gå til",
+'searcharticle' => "Gå til",
+"ok" => "OK",
+"retrievedfrom" => "Hentet fra \"$1\"",
+"newmessageslink" => "nye beskeder",
+"editsection"=>"redigér",
+"editold"=>"redigér",
+"toc" => "Indholdsfortegnelse",
+"showtoc" => "vis",
+"hidetoc" => "skjul",
+"thisisdeleted" => "Se eller gendan $1?",
+"restorelink" => "$1 slettede ændringer",
+'feedlinks' => 'Feed:',
+'tagline' => 'Fra {{SITENAME}}',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Artikel',
+'nstab-user' => 'Brugerside',
+'nstab-media' => 'Medie',
+'nstab-special' => 'Speciel',
+'nstab-project' => 'Om',
+'nstab-image' => 'Billede',
+'nstab-mediawiki' => 'Besked',
+'nstab-template' => 'Skabelon',
+'nstab-help' => 'Hjælp',
+'nstab-category' => 'Kategori',
+
+# Main script and global functions
+#
+"nosuchaction" => "Funktionen findes ikke",
+"nosuchactiontext" => "Funktion angivet i URL'en kan ikke
+genkendes af MediaWiki-softwaren",
+"nosuchspecialpage" => "En sådan specialside findes ikke",
+"nospecialpagetext" => "Du har bedt om en specialside, der ikke kan
+genkendes af MediaWiki-softwaren.",
+
+# General errors
+#
+"error" => "Fejl",
+"databaseerror" => "Databasefejl",
+"dberrortext" => "Der er opstået en syntaksfejl i en databaseforespørgsel.
+Dette kan være på grund af en ugyldig forespørgsel (se $5),
+eller det kan betyde en fejl i softwaren.
+Den seneste forsøgte databaseforespørgsel var:
+<blockquote><tt>$1</tt></blockquote>
+fra funktionen \"<tt>$2</tt>\".
+MySQL returnerede fejlen \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Der er opstået en syntaksfejl i en databaseforespørgsel.
+Den seneste forsøgte databaseforespørgsel var:
+\"$1\"
+fra funktionen \"$2\".
+MySQL returnerede fejlen \"$3: $4\".",
+'noconnect' => 'Der er problemer med {{SITENAME}}s database, vi kan desværre ikke komme i kontakt med den for øjeblikket. Prøv igen senere. <br />
+$1',
+"nodb" => "Kunne ikke vælge databasen $1",
+"cachederror" => "Det følgende er en gemt kopi af den ønskede side, og er måske ikke helt opdateret.",
+"readonly" => "Databasen er skrivebeskyttet",
+"enterlockreason" => "Skriv en begrundelse for skrivebeskyttelsen, også indeholdende et estimat
+på hvornår skrivebeskyttelsen vil blive ophævet igen",
+"readonlytext" => "{{SITENAME}}databasen er for øjeblikket skrivebeskyttet,
+hvilket forhindrer oprettelse af nye sider og andre ændringer,
+sandsynligvis på grund af rutinemæssig databasevedligeholdelse,
+hvorefter den vil returnere til normaldrift. Administratoren der
+skrivebeskyttede databasen har denne forklaring:
+<p>$1",
+"missingarticle" => "Databasen fandt ikke teksten på en side,
+som den skulle have fundet, med navnet \"$1\".
+
+<p>Dette er ikke en databasefejl, men sandsynligvis en fejl i softwaren.
+
+<p>Send venligst en rapport om dette til en administrator,
+hvor du også nævner URL'en.",
+'readonly_lag' => "Databasen er automatisk blevet låst mens slave database serverne synkronisere med master databasen",
+"internalerror" => "Intern fejl",
+"filecopyerror" => "Kunne ikke kopiere filen \"$1\" til \"$2\".",
+"filerenameerror" => "Kunne ikke omdøbe filen \"$1\" til \"$2\".",
+"filedeleteerror" => "Kunne ikke slette filen \"$1\".",
+"filenotfound" => "Kunne ikke finde filen \"$1\".",
+"unexpected" => "Uventet værdi: \"$1\"=\"$2\".",
+"formerror" => "Fejl: Kunne ikke afsende formular",
+"badarticleerror" => "Denne funktion kan ikke udføres på denne side.",
+"cannotdelete" => "Kunne ikke slette siden eller filen der blev angivet.",
+"badtitle" => "Forkert titel",
+"badtitletext" => "Den ønskede sides titel var ikke tilladt, tom eller siden
+er forkert henvist fra en {{SITENAME}} på et andet sprog.",
+"perfdisabled" => "Denne funktion er desværre midlertidigt afbrudt,
+fordi den belaster databasen meget hårdt og i en sådan grad,
+at siden bliver meget langsom. Funktionen bliver forhåbentlig
+omskrevet i den nærmeste fremtid (måske af dig, det er jo open source!).",
+"perfdisabledsub" => "Her er en gemt kopi fra $1:",
+'perfcached' => 'Følgende data er gemt i cachen, det er muligvis ikke helt opdateret:',
+'wrong_wfQuery_params' => "Ugyldig parameter til wfQuery()<br />
+Funktion: $1<br />
+Forespørgsel: $2",
+'viewsource' => 'Vis kilden',
+'protectedtext' => "Denne side er skrivebeskyttet for at forhindre ændringer;
+der kan være flere årsager til at det er sket,
+se [[{{ns:4}}:Liste over beskyttede sider|listen over beskyttede sider]].
+
+Du kan sé og kopiere sidens indhold:",
+'sqlhidden' => '(SQL forespørgsel gemt)',
+
+# Login and logout pages
+#
+"logouttitle" => "Bruger-log-af",
+"logouttext" => "Du er nu logget af.
+Du kan fortsætte med at bruge {{SITENAME}} anonymt, eller du kan logge på
+igen som den samme eller en anden bruger.",
+
+"welcomecreation" => "== Velkommen, $1! ==
+
+Din konto er blevet oprettet. Glem ikke at personliggøre dine {{SITENAME}}-indstillinger.",
+
+"loginpagetitle" => "Bruger log på",
+"yourname" => "Dit brugernavn",
+"yourpassword" => "Din adgangskode",
+"yourpasswordagain" => "Gentag adgangskode",
+"remembermypassword" => "Husk min adgangskode til næste gang.",
+'yourdomainname' => 'Your domain',
+'externaldberror' => 'There was either an external authentication database error or you are not allowed to update your external account.',
+"loginproblem" => "<b>Der har været et problem med at få dig logget på.</b><br />Prøv igen!",
+"alreadyloggedin" => "<strong>Bruger $1, du er allerede logget på!</strong><br />",
+
+"login" => "Log på",
+'loginprompt' => "Du skal have cookies slået til for at kunne logge på {{SITENAME}}.",
+"userlogin" => "Opret en konto eller log på",
+"logout" => "Log af",
+"userlogout" => "Log af",
+"notloggedin" => "Ikke logget på",
+"createaccount" => "Opret en ny konto",
+'createaccountmail' => 'via e-mail',
+"badretype" => "De indtastede adgangskoder er ikke ens.",
+"userexists" => "Det brugernavn du har valgt er allerede i brug. Vælg
+venligst et andet brugernavn.",
+"youremail" => "Din e-mail-adresse *",
+'yourrealname' => 'Dit rigtige navn*',
+'yourlanguage' => 'Grænsefladesprog',
+'yourvariant' => 'Sprogvariant',
+"yournick" => "Dit kaldenavn (til signaturer)",
+'prefs-help-email' => '** <strong>E-mail-adresse</strong> (valgfrit): Giver andre mulighed for at kontakte dig, uden du behøver at afsløre din e-mail-adresse. Det kan også bruges til at fremsende en ny adgangskode til dig, hvis du glemmer den du har.',
+'prefs-help-email-enotif' => 'Denne e-mail-adresse bruges også til at sende beskeder til dig via e-mail, hvis du har aktiveret funktionerne.',
+'prefs-help-realname' => '* <strong>Dit rigtige navn</strong> (valgfrit): Hvis du vælger at oplyse dit navn vil dette blive brugt til at tilskrive dig dit arbejde.',
+"loginerror" => "Fejl med at logge på",
+'nocookiesnew' => "Din brugerkonto er nu oprettet, men du er ikke logget på. {{SITENAME}} bruger cookies til at logge brugere på. Du har slået cookies fra. Vær venlig at slå cookies til, og derefter kan du logge på med dit nye brugernavn og kodeord.",
+"nocookieslogin" => "{{SITENAME}} bruger cookies til at logge brugere på. Du har slået cookies fra. Slå dem venligst til og prøv igen.",
+"noname" => "Du har ikke angivet et gyldigt brugernavn.",
+"loginsuccesstitle" => "Logget på med succes",
+"loginsuccess" => "Du er nu logget på {{SITENAME}} som \"$1\".",
+"nosuchuser" => "Der er ingen bruger med navnet \"$1\".
+Kontrollér stavemåden igen, eller brug formularen herunder til at oprette en ny brugerkonto.",
+'nosuchusershort' => "Der er ingen bruger ved navn \"$1\". Tjek din stavning.",
+"wrongpassword" => "Den indtastede adgangskode var forkert. Prøv igen.",
+"mailmypassword" => "Send en ny adgangskode til min e-mail-adresse",
+"passwordremindertitle" => "Ny adgangskode fra {{SITENAME}}",
+"passwordremindertext" => "Nogen (sandsynligvis dig, fra IP-adressen $1)
+har bedt om at vi sender dig en ny adgangskode til at logge på {{SITENAME}}.
+Den nye adgangskode for bruger \"$2\" er nu \"$3\".
+Du bør logge på nu og ændre din adgangskode.",
+"noemail" => "Der er ikke oplyst en e-mail-adresse for bruger \"$1\".",
+"passwordsent" => "En ny adgangskode er sendt til e-mail-adressen,
+som er registreret for \"$1\".
+Du bør logge på og ændre din adgangskode straks efter du har modtaget e-mail'en.",
+'mailerror' => "Fejl ved afsendelse af e-mail: $1",
+'acct_creation_throttle_hit' => 'Du har allerede oprettet $1 kontoer. Du kan ikke oprette flere.',
+'emailauthenticated' => 'Din e-mail-adresse blev bekræftet på $1.',
+'emailnotauthenticated' => 'Din e-mail-adresse er endnu ikke bekræftet og de avancerede e-mail-funktioner er slået fra indtil bekræftelse har fundet sted (d.u.a.).
+Log ind med den midlertidige adgangskode, der er blevet sendt til dig, for at bekræfte, eller bestil et nyt på loginsiden.',
+'invalidemailaddress' => 'E-mail-adressen kan ikke accepteres da den tilsyneladende har et ugyldigt format. Skriv venligst en e-mail-adresse med et korrekt format eller tøm feltet.',
+
+# Edit page toolbar
+'bold_sample'=>'Fed tekst',
+'bold_tip'=>'Fed tekst',
+'italic_sample'=>'Kursiv tekst',
+'italic_tip'=>'Kursiv tekst',
+'link_sample'=>'Henvisning',
+'link_tip'=>'Intern henvisning',
+'extlink_sample'=>'http://www.eksempel.dk Titel på henvisning',
+'extlink_tip'=>'Ekstern henvisning (husk http:// præfiks)',
+'headline_sample'=>'Tekst til overskrift',
+'headline_tip'=>'Type 2 overskrift',
+'math_sample'=>'Indsæt formel her (LaTeX)',
+'math_tip'=>'Matematisk formel (LaTeX)',
+'nowiki_sample'=>'Indsæt tekst her som ikke skal wikiformateres',
+'nowiki_tip'=>'Ignorer wikiformatering',
+'image_sample'=>'Eksempel.jpg',
+'image_tip'=>'Indlejret billede',
+'media_sample'=>'Eksempel.mp3',
+'media_tip'=>'Henvisning til multimediefil',
+'sig_tip'=>'Din signatur med tidsstempel',
+'hr_tip'=>'Horisontal linje (brug den sparsomt)',
+
+# Edit pages
+#
+'summary' => '<a href="{{fullurl:{{ns:4}}}}:Beskrivelse" title="Giv venligst en kort beskrivelse af din ændring">Beskrivelse</a>',
+"subject" => "Emne/overskrift",
+"minoredit" => "Dette er en mindre ændring.",
+"watchthis" => "Overvåg denne artikel",
+"savearticle" => "Gem side",
+"preview" => "Forhåndsvisning",
+"showpreview" => "Forhåndsvisning",
+'showdiff' => 'Vis ændringer',
+"blockedtitle" => "Brugeren er blokeret",
+"blockedtext" => "Dit brugernavn eller din IP-adresse er blevet blokeret af
+$1. Begrundelsen er denne:<br />$2<p>Du kan kontakte $1
+eller en af de andre [[{{ns:project}}:Administratorer|administratorer]] for at diskutere blokeringen.
+
+Din IP-adresse er $3.
+Sørg venligst for at medtage denne IP-adresse i alle henvendelser til en administrator.",
+'whitelistedittitle' => 'Log på for at redigere',
+'whitelistedittext' => 'Du skal [[Special:Userlogin|logge på]] for at kunne rette artikler.',
+'whitelistreadtitle' => 'Log på for at læse',
+'whitelistreadtext' => 'Du skal [[Special:Userlogin|logge på]] for at læse artikler.',
+'whitelistacctitle' => 'Du har ikke lov til at oprette en konto',
+'whitelistacctext' => 'For at få lov til at lave en konto på denne wiki skal du [[Speciel:Userlogin|logge på]] og have passende rettigheder.',
+'loginreqtitle' => 'Log på nødvendigt',
+'loginreqlink' => 'logge på',
+'loginreqpagetext' => 'Du skal $1 for at se andre sider.',
+'accmailtitle' => 'Adgangskode sendt.',
+'accmailtext' => "Adgangskoden for '$1' er sendt til $2.",
+"newarticle" => "(Ny)",
+"newarticletext" => "<div style=\"font-size:small;color:\#003333;border-width:1px;border-style:solid;border-color:\#aaaaaa;padding:3px\">'''{{SITENAME}} har endnu ikke nogen {{NAMESPACE}}-side ved navn {{PAGENAME}}.'''<br /> Du kan begynde en side ved at skrive i boksen herunder. (se [[{{ns:4}}:Hjælp|hjælpen]] for yderligere oplysninger).<br /> Eller du kan [[{{ns:-1}}:Search/{{PAGENAME}}|søge efter {{PAGENAME}} i {{SITENAME}}]].<br /> Hvis det ikke var din mening, så tryk på '''Tilbage'''- eller '''Back'''-knappen. '''Dit bidrag til {{SITENAME}} vil fremkomme omgående''', så hvis du bare vil teste tingene, så brug venligst [[{{ns:4}}:Sandkassen|sandkassen]]!</div>",
+"anontalkpagetext" => "---- ''Dette er en diskussionsside for en anonym bruger, der ikke har oprettet en konto endnu eller ikke bruger den. Vi er derfor nødt til at bruge den nummeriske [[IP-adresse]] til at identificere ham eller hende. En IP-adresse kan være delt mellem flere brugere. Hvis du er en anonym bruger og synes, at du har fået irrelevante kommentarer på sådan en side, så vær venlig at oprette en brugerkonto og [[Speciel:Userlogin|logge på]], så vi undgår fremtidige forvekslinger med andre anonyme brugere.''",
+"noarticletext" => "<div style=\"border: 1px solid \#ccc; padding: 7px; background-color: \#fff; color: \#000\">'''{{SITENAME}} har ikke nogen side med præcis dette navn.''' * Du kan se om {{PAGENAME}} findes i [[Wiktionary:{{NAMESPACE}}:{{PAGENAME}}|wikiordbogen]] eller på '''[[:no:{{PAGENAME}}|norsk]]''', '''[[:nn:{{PAGENAME}}|nynorsk]]''', eller '''[[:sv:{{PAGENAME}}|svensk]]'''. * Du kan '''[{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} starte siden {{PAGENAME}}]''' * Eller [[{{ns:special}}:Search/{{PAGENAME}}|søge efter {{PAGENAME}}]] i andre artikler ---- * Hvis du har oprettet denne artikel indenfor de sidste få minutter, så kan de skyldes at der er lidt forsinkelse i opdateringen af {{SITENAME}}s cache. Vent venligst og tjek igen senere om artiklen dukker op, inden du forsøger at oprette artiklen igen. </div>",
+'clearyourcache' => "'''Bemærk''', efter at have gemt, er du nødt til at tømme din browsers cache for at kunne se ændringerne. '''Mozilla / Firefox / Safari''': hold ''shifttasten'' nede og klik på ''reload'' eller tryk på ''control-shift-r'' (Mac: ''cmd-shift-r''); '''Internet Explorer''': hold ''controltasten'' nede og klik på ''refresh'' eller tryk på ''control-F5''; '''Konqueror''': klik på ''reload'' eller tryk på ''F5''",
+'usercssjsyoucanpreview' => "<strong>Tip:</strong> Brug knappen 'forhåndsvisning' til at teste dit nye css/js før du gemmer.",
+'usercsspreview' => "'''Husk at du kun tester/forhåndsviser dit eget css, den er ikke gemt endnu!'''",
+'userjspreview' => "'''Husk at du kun tester/forhåndsviser dit eget javascript, det er ikke gemt endnu!'''",
+"updated" => "(Opdateret)",
+'note' => '<strong>Bemærk:</strong>',
+"previewnote" => "Husk at dette er kun en forhåndsvisning, siden er ikke
+gemt endnu!",
+"previewconflict" => "Denne forhåndsvisning er resultatet af den
+redigérbare tekst ovenfor,
+sådan vil det komme til at se ud hvis du vælger at gemme teksten.",
+"editing" => "Redigerer $1",
+'editinguser' => "Redigerer $1",
+"editingsection" => "Redigerer $1 (afsnit)",
+"editingcomment" => "Redigerer $1 (kommentar)",
+"editconflict" => "Redigeringskonflikt: $1",
+"explainconflict" => "Nogen har ændret denne side, efter du
+startede på at redigere den.
+Den øverste tekstboks indeholder den nuværende tekst.
+Dine ændringer er vist i den nederste tekstboks.
+Du er nødt til at sammenflette dine ændringer med den eksisterende tekst.
+<b>Kun</b> teksten i den øverste tekstboks vil blive gemt når du
+trykker \"Gem side\".<br />",
+"yourtext" => "Din tekst",
+"storedversion" => "Den gemte version",
+'nonunicodebrowser' => "<strong>Advarsel: Din browser er ikke unicode-kompatibel, skift eller opdater din browser før du redigerer en artikel.</strong>",
+"editingold" => "<strong>ADVARSEL: Du redigerer en gammel version
+af denne side.
+Hvis du gemmer den, vil alle ændringer foretaget siden denne revision blive
+overskrevet.</strong>",
+"yourdiff" => "Forskelle",
+/*"copyrightwarning" => "*Bemærk at alle bidrag til {{SITENAME}} er at betragte som udgivet under GNU Free Documentation License (se $1 for flere oplysninger). *Hvis du ikke ønsker at din tekst skal udsættes for nådesløse redigeringer og at den kan blive kopieret efter forgodtbefindende, så skal du ikke placere den her. *Du lover os også, at du selv har forfattet teksten, kopieret den fra en public domain-kilde eller tilsvarende fri kilde. <strong><big>LÆG ALDRIG MATERIALE HER SOM ER BESKYTTET AF ANDRES OPHAVSRET UDEN DERES TILLADELSE!</big></strong>",*/
+"longpagewarning" => "<strong>ADVARSEL: Denne side er $1 kilobyte stor; nogle browsere kan have problemer med at redigere sider der nærmer sig eller er større end 32 Kb. Overvej om siden kan opdeles i mindre dele.</strong>",
+"readonlywarning" => "<strong>ADVARSEL: Databasen er låst på grund af vedligeholdelse,
+så du kan ikke gemme dine ændringer lige nu. Det kan godt være en god ide at
+kopiere din tekst til en tekstfil, så du kan gemme den til senere.</strong>",
+"protectedpagewarning" => "<strong>ADVARSEL: Denne side er låst, så kun administratorer
+kan redigere den. Sørg for at du følger
+[[Project:Politik_for_beskyttede_sider|politiken for beskyttede sider]].</strong>",
+'templatesused' => 'Skabeloner der er brugt på denne side:',
+
+# History pages
+#
+"revhistory" => "Versionshistorik",
+"nohistory" => "Der er ingen versionshistorik for denne side.",
+"revnotfound" => "Versionen er ikke fundet",
+"revnotfoundtext" => "Den gamle version af den side du spurgte efter kan
+ikke findes. Kontrollér den URL du brugte til at få adgang til denne side.",
+"loadhist" => "Indlæser sidens historik",
+"currentrev" => "Nuværende version",
+"revisionasof" => "Versionen fra $1",
+'previousrevision' => '←Ældre version',
+'nextrevision' => 'Nyere version→',
+'currentrevisionlink' => 'se nuværende version',
+"cur" => "nuværende",
+"next" => "næste",
+"last" => "forrige",
+"orig" => "originale",
+"histlegend" => "Forklaring: (nuværende) = forskel til den nuværende
+version, (forrige) = forskel til den forrige version, M = mindre ændring",
+'deletedrev' => '[slettet]',
+
+# Diffs
+#
+"difference" => "(Forskelle mellem versioner)",
+"loadingrev" => "indlæser version for at se forskelle",
+"lineno" => "Linje $1:",
+"editcurrent" => "Redigér den nuværende version af denne side",
+'selectnewerversionfordiff' => 'Vælg en nyere version til sammenligning',
+'selectolderversionfordiff' => 'Vælg en ældre version til sammenligning',
+'compareselectedversions' => 'Sammenlign valgte versioner',
+
+# Search results
+#
+"searchresults" => "Søgeresultater",
+"searchresulttext" => "For mere information om søgning på {{SITENAME}}, se [[Project:Søgning|Søgning på {{SITENAME}}]].",
+"badquery" => "Forkert udformet forespørgsel",
+"badquerytext" => "Vi kunne ikke udføre din forespørgsel.
+Det er sandsynligvis fordi du har forsøgt at søge efter et ord med
+færre end tre bogstaver, hvilket ikke understøttes endnu.
+Det kan også være du har skrevet forkert, for
+eksempel \"fisk og og skaldyr\".
+Prøv en anden forespørgsel.",
+"matchtotals" => "Forespørgslen \"$1\" opfyldte $2 artikeltitler
+og teksten i $3 artikler.",
+"noexactmatch" => "{{SITENAME}} har ingen artikel med dette navn. Du kan [[:$1|oprette en artikel med dette navn]] eller [[{{ns:4}}:Efterspurgte_artikler|efterspørge den]]. For at undgå flere artikler om samme emne, bedes du inden oprettelsen søge efter artiklen under alternative navne og stavemåder.",
+"titlematches" => "Artikeltitler der opfyldte forespørgslen",
+"notitlematches" => "Ingen artikeltitler opfyldte forespørgslen",
+"textmatches" => "Artikeltekster der opfyldte forespørgslen",
+"notextmatches" => "Ingen artikeltekster opfyldte forespørgslen",
+"prevn" => "forrige $1",
+"nextn" => "næste $1",
+"viewprevnext" => "Vis ($1) ($2) ($3).",
+"showingresults" => "Nedenfor vises <b>$1</b> resultater startende med
+nummer <b>$2</b>.",
+"showingresultsnum" => "Herunder vises <b>$3</b> resultater startende med nummer <b>$2</b>.",
+"nonefound" => "<strong>Bemærk</strong>: Søgning uden resultat skyldes at man søger efter almindelige ord som \"har\" og \"fra\", der ikke er indekseret, eller at man har angivet mere end ét søgeord (da kun sider indeholdende alle søgeordene vil blive fundet).",
+"powersearch" => "Søg",
+"powersearchtext" => "
+Søg i navnerum:<br />
+$1<br />
+$2 List omdirigeringer &nbsp; Søg efter $3 $9",
+"searchdisabled" => "<p>Beklager! Fuldtekstsøgningen er midlertidigt afbrudt på grund af for stor belastning på serverne. I mellemtidem kan du anvende Google- eller Yahoo!-søgefelterne herunder. Bemærk at deres kopier af {{SITENAME}}s indhold kan være forældet.</p>",
+"blanknamespace" => "(Artikler)",
+
+# Preferences page
+#
+"preferences" => "Indstillinger",
+"prefsnologin" => "Ikke logget på",
+"prefsnologintext" => "Du skal være [[Speciel:Userlogin|logget på]]
+for at ændre brugerindstillinger.",
+"prefsreset" => "Indstillingerne er blevet gendannet fra lageret.",
+"qbsettings" => "Hurtigmenu",
+"changepassword" => "Skift adgangskode",
+"skin" => "Udseende",
+"math" => "Matematiske formler",
+"dateformat" => "Datoformat",
+"math_failure" => "Fejl i matematikken",
+"math_unknown_error" => "ukendt fejl",
+"math_unknown_function" => "ukendt funktion",
+"math_lexing_error" => "lexerfejl",
+"math_syntax_error" => "syntaksfejl",
+'math_image_error' => 'PNG-konvertering mislykkedes; undersøg om latex, dvips, gs og convert er installeret korrekt',
+'math_bad_tmpdir' => 'Kan ikke skrive til eller oprette temp-mappe til math',
+'math_bad_output' => 'Kan ikke skrive til eller oprette uddata-mappe til math',
+'math_notexvc' => 'Manglende eksekvérbar texvc; se math/README for opsætningsoplysninger.',
+'prefs-personal' => 'Brugerdata',
+'prefs-rc' => 'Seneste ændringer og artikelstumper',
+'prefs-misc' => 'Forskelligt',
+'prefs-watchlist-edits' => 'Antal redigeringer der vises i udvidet overvågningsliste:',
+"saveprefs" => "Gem indstillinger",
+"resetprefs" => "Gendan indstillinger",
+"oldpassword" => "Gammel adgangskode",
+"newpassword" => "Ny adgangskode",
+"retypenew" => "Gentag ny adgangskode",
+"textboxsize" => "Redigering",
+"rows" => "Rækker",
+"columns" => "Kolonner",
+"searchresultshead" => "Søgeresultater",
+"resultsperpage" => "Resultater pr. side",
+"contextlines" => "Linjer pr. resultat",
+"contextchars" => "Tegn pr. linje i resultatet",
+"stubthreshold" => "Grænse for visning af artikelstumper",
+"recentchangescount" => "Antallet af titler på siden \"seneste ændringer\"",
+"savedprefs" => "Dine indstillinger er blevet gemt.",
+'timezonelegend' => 'Tidszone',
+"timezonetext" => "Indtast antal timer din lokale tid er forskellig
+fra serverens tid (UTC). Der bliver automatisk tilpasset til dansk tid,
+ellers skulle man for eksempel for dansk vintertid, indtaste \"1\"
+(og \"2\" når vi er på sommertid).",
+"localtime" => "Lokaltid",
+"timezoneoffset" => "Forskel",
+"servertime" => "Serverens tid er nu",
+"guesstimezone" => "Hent tidszone fra browseren",
+"defaultns" => "Søg som standard i disse navnerum:",
+'default' => 'standard',
+'files' => 'Filer',
+
+# User levels special page
+#
+
+# switching pan
+
+'userrights-lookup-user' => 'Administrér brugergrupper',
+'userrights-user-editname' => 'Skriv et brugernavn:',
+'editusergroup' => 'Redigér brugergrupper',
+
+# user groups editing
+#
+'userrights-editusergroup' => 'Redigér brugergrupper',
+'saveusergroups' => 'Gem brugergrupper',
+'userrights-groupsmember' => 'Medlem af:',
+'userrights-groupsavailable' => 'Tilgængelige grupper:',
+'userrights-groupshelp' => 'Vælg grupper som du ønsker brugeren skal fjernes fra eller føjes til.
+Grupper som ikke er valgt, vil ikke blive ændret. Du kan ophæve valget af en gruppe ved hjælp af CTRL-tasten og et venstreklik.',
+
+# Recent changes
+#
+"changes" => "ændringer",
+"recentchanges" => "Seneste ændringer",
+"rcnote" => "Nedenfor er de seneste <strong>$1</strong> ændringer i de
+sidste <strong>$2</strong> dage.",
+"rcnotefrom" => "Nedenfor er ændringerne fra <b>$2</b> indtil <b>$1</b> vist.",
+"rclistfrom" => "Vis nye ændringer startende fra $1",
+"rclinks" => "Vis seneste $1 ændringer i de sidste $2 dage<br />$3",
+"diff" => "forskel",
+"hist" => "historik",
+"hide" => "skjul",
+"show" => "vis",
+"minoreditletter" => "m",
+"newpageletter" => "N",
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 overvågende bruger/e]',
+
+# Upload
+#
+"upload" => "Læg en fil op",
+"uploadbtn" => "Læg en fil op",
+"reupload" => "Læg en fil op igen",
+"reuploaddesc" => "Tilbage til formularen til at lægge filer op.",
+"uploadnologin" => "Ikke logget på",
+"uploadnologintext" => "Du skal være [[Speciel:Userlogin|logget på]] for at kunne lægge filer op.",
+"uploaderror" => "Fejl under oplægning af fil",
+"uploadtext" => "<div style=\"border: 1px solid grey; background: \#ddf; padding: 7px; margin: 0 auto;\">
+<strong>STOP!</strong> Før du lægger filer op her,
+så vær sikker på du har læst og følger {{SITENAME}}s
+[[{{NS:4}}:Politik om brug af billeder|politik om brug af billeder]].
+
+Følg venligst disse retningslinjer:
+<ul>
+<li>Angiv tydeligt hvor filen stammer fra</li>
+<li>Angiv tydeligt hvilken licens filen er omfattet af, ved at tilføje en af skabelonerne <tt>&#123;{GFDL}}</tt> eller <tt>&#123;{PD}}</tt> eller en af de andre du kan finde på [[{{NS:4}}:Skabeloner#Ophavsret|skabelonsiden]].</li>
+<li>Brug et beskrivende filnavn, så det er til at se hvad filen indeholder</li>
+<li>Tjek i [[Speciel:Imagelist|listen over filer]] om filen allerede er lagt op</li>
+</ul>
+</div>
+<p>Brug formularen herunder til at lægge nye filer op, som kan bruges i dine artikler.
+På de fleste browsere vil du se en \"Browse...\" knap eller en
+\"Gennemse...\" knap, som vil
+bringe dig til dit styresystems standard-dialog til åbning af filer.
+Når du vælger en fil, vil navnet på filen dukke op i tekstfeltet
+ved siden af knappen.
+Du skal også bekræfte, at du ikke er ved at bryde nogens ophavsret.
+Det gør du ved at sætte et mærke i tjekboksen.
+Vælg \"Læg en fil op\"-knappen for at lægge filen op.
+Dette kan godt tage lidt tid hvis du har en langsom internetforbindelse.
+
+<p>De foretrukne formater er JPEG til fotografiske billeder, PNG
+til tegninger og andre små billeder, og OGG til lyd.
+For at bruge et billede i en artikel, så brug et link af denne type
+'''<nowiki>[[billede:fil.jpg]]</nowiki>''' eller
+'''<nowiki>[[billede:fil.png|alternativ tekst]]</nowiki>''' eller
+'''<nowiki>[[media:fil.ogg]]</nowiki>''' for lyd.
+
+<p>Læg mærke til at præcis som med alle andre sider, så kan og må andre gerne
+redigere eller
+slette de filer, du har lagt op, hvis de mener det hjælper {{SITENAME}}, og
+du kan blive blokeret fra at lægge op hvis du misbruger systemet.",
+"uploadlog" => "oplægningslog",
+"uploadlogpage" => "Oplægningslog",
+"uploadlogpagetext" => "Herunder en liste over de senest oplagte filer. Alle de viste tider er serverens tid (UTC).",
+"filename" => "Filnavn",
+"filedesc" => "Beskrivelse",
+'filestatus' => 'Status på ophavsret',
+'filesource' => 'Kilde',
+"copyrightpage" => "{{ns:project}}:Ophavsret",
+"copyrightpagename" => "{{SITENAME}} ophavsret",
+"uploadedfiles" => "Filer som er lagt op",
+"minlength" => "Navnet på filen skal være på mindst tre bogstaver.",
+'illegalfilename' => 'Filnavnet "$1" indeholder tegn, der ikke er tilladte i sidetitler. Omdøb filen og prøv at lægge den op igen.',
+"badfilename" => "Navnet på filen er blevet ændret til \"$1\".",
+"badfiletype" => "\".$1\" er ikke et af de anbefalede filformater.",
+"largefile" => "Det anbefales, at filer ikke fylder mere end $1kb ($2).",
+'emptyfile' => 'Filen du lagde op lader til at være tom. Det kan skyldes en slåfejl i filnavnet. Kontroller om du virkelig ønsker at lægge denne fil op.',
+'fileexists' => 'En fil med det navn findes allerede, tjek venligst $1 om du er sikker på du vil ændre den.',
+"successfulupload" => "Oplægning er gennemført med succes",
+"fileuploaded" => "Filen \"$1\" er lagt op med succes.
+Følg dette link: ($2) til siden med beskrivelse, og udfyld
+information omkring filen, såsom hvor den kom fra, hvornår den er lavet
+og af hvem, og andre ting du ved om filen.",
+"uploadwarning" => "Oplægningsadvarsel",
+"savefile" => "Gem fil",
+"uploadedimage" => "Lagde \"[[$1]]\" op",
+"uploaddisabled" => "Desværre er funktionen til at lægge billeder op afbrudt på denne server.",
+'uploadscripted' => 'Denne fil indeholder HTML eller script-kode, der i visse tilfælde can fejlfortolkes af en browser.',
+'uploadcorrupt' => 'Denne fil er beskadiget eller forsynet med en forkert endelse. Kontroller venligst filen og prøv at lægge den op igen.',
+'uploadvirus' => 'Denne fil indeholder en virus! Virusnavn: $1',
+
+# Image list
+#
+"imagelist" => "Liste over billeder",
+"imagelisttext" => "Herunder er en liste med $1 billeder sorteret $2.",
+"getimagelist" => "henter billedliste",
+"ilsubmit" => "Søg",
+"showlast" => "Vis de sidste $1 billeder sorteret $2.",
+"byname" => "efter navn",
+"bydate" => "efter dato",
+"bysize" => "efter størrelse",
+"imgdelete" => "slet",
+"imgdesc" => "beskrivelse",
+"imglegend" => "Forklaring: (beskrivelse) = vis/redigér billedebeskrivelse.",
+"imghistory" => "Billedhistorik",
+"revertimg" => "gendan",
+"deleteimg" => "slet",
+"deleteimgcompletely" => "Slet alle revisioner af dette billede",
+"imghistlegend" => "Forklaring: (nuværende) = dette er det nuværende billede,
+(slet) = slet denne gamle version, (gendan) = gendan en gammel version.
+<br /><i>Klik på en dato for at se billedet, som er lagt op den dag</i>.",
+"imagelinks" => "Billedehenvisninger",
+"linkstoimage" => "De følgende sider henviser til dette billede:",
+"nolinkstoimage" => "Der er ingen sider der henviser til dette billede.",
+'shareduploadwiki' => 'Se venligst $1 for yderligere information.',
+'shareduploadwiki-linktext' => 'siden med billedbeskrivelsen',
+'noimage' => 'Der eksisterer ingen fil med dette navn, du kan $1',
+'noimage-linktext' => 'lægge den op',
+'uploadnewversion-linktext' => 'Læg en ny version af denne fil op',
+
+# Statistics
+#
+"statistics" => "Statistik",
+"sitestats" => "Statistiske oplysninger om {{SITENAME}}",
+"userstats" => "Statistik om brugere på {{SITENAME}}",
+"sitestatstext" => "Der er i alt '''$1''' sider i databasen.
+Dette tal indeholder \"diskussion\"-sider, sider om {{SITENAME}}, omdirigeringssider og andre sider der sikkert ikke kan kaldes artikler.
+Hvis man udelader disse, så er der '''$2''' sider som sandsynligvis er rigtige artikler.
+Der har i alt været '''$4''' sideredigeringer siden programmellet blev opdateret den 25. september 2002.
+Det vil sige, at der har været '''$5''' gennemsnitlige redigeringer pr. side.",
+
+# Maintenance Page
+#
+"disambiguations" => "Artikler med flertydige titler",
+"disambiguationspage" => "Project:Henvisninger til artikler med flertydige titler",
+"disambiguationstext" => "De følgende artikler henviser til
+<i>artikler med flertydige titler</i>. De skulle henvise til en ikke-flertydig
+titel i stedet for.<br />En artikel bliver behandlet som flertydig, hvis den er
+henvist fra $1.<br />Henvisninger fra andre navnerum er <i>ikke</i> listet her.",
+"doubleredirects" => "Dobbelte omdirigeringer",
+"doubleredirectstext" => "<b>Bemærk:</b> Denne liste kan indeholde forkerte
+resultater. Det er som regel, fordi siden indeholder ekstra tekst under den
+første #REDIRECT.<br />\nHver linje indeholder henvisninger til den første og den
+anden omdirigering, og den første linje fra den anden omdirigeringstekst,
+det giver som regel den \"rigtige\" målartikel, som den første omdirigering
+skulle have peget på.",
+"brokenredirects" => "Dårlige omdirigeringer",
+"brokenredirectstext" => "De følgende omdirigeringer peger på en side der
+ikke eksisterer.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Forældreløse artikler",
+'uncategorizedpages' => 'Ukategoriserede sider',
+'uncategorizedcategories' => 'Ukategoriserede kategorier',
+"unusedimages" => "Ubrugte billeder",
+"popularpages" => "Populære artikler",
+"nviews" => "$1 visninger",
+"wantedpages" => "Ønskede artikler",
+"nlinks" => "$1 henvisninger",
+"allpages" => "Alle artikler",
+"randompage" => "Tilfældig artikel",
+"shortpages" => "Korte artikler",
+"longpages" => "Lange artikler",
+'deadendpages' => 'Blindgydesider',
+"listusers" => "Liste over brugere",
+"specialpages" => "Specielle sider",
+"spheading" => "Specielle sider for alle brugere",
+'restrictedpheading' => 'Specielle sider med begrænset adgang',
+"recentchangeslinked" => "Relaterede ændringer",
+"rclsub" => "(til sider henvist fra \"$1\")",
+"newpages" => "Nyeste artikler",
+"ancientpages" => "Ældste artikler",
+"intl" => "Sproghenvisninger",
+"movethispage" => "Flyt side",
+"unusedimagestext" => "<p>Læg mærke til, at andre websider
+såsom de andre internationale {{SITENAME}}er måske henviser til et billede med
+en direkte URL, så det kan stadig være listet her, selvom det er
+i aktivt brug.",
+"booksources" => "Bogkilder",
+'categoriespagetext' => 'De følgende kategorier eksisterer på {{SITENAME}}.',
+'data' => 'Data',
+
+# FIXME: Other sites, of course, may have affiliate relations with the booksellers list
+"booksourcetext" => "Herunder er en liste af henvisninger til steder der
+udlåner og/eller sælger nye og brugte bøger, og som måske også har
+yderligere oplysninger om bøger du leder efter.
+{{SITENAME}} er ikke associeret med nogen af disse steder,
+og denne liste skal ikke ses som en anbefaling af disse.",
+'isbn' => 'ISBN',
+"alphaindexline" => "$1 til $2",
+'version' => 'Information om MediaWiki',
+'log' => 'Logs',
+'alllogstext' => 'Samlet visning af oplægningslog, sletningslog, blokeringslog, bureaukratlog og listen over beskyttede sider.
+Du kan sortere i visningen ved at vælge type, brugernavn og/eller en udvalgt side.',
+
+# Special:Allpages
+'nextpage' => 'Næste side ($1)',
+'allpagesfrom' => 'Vis sider startende fra: $1',
+'allarticles' => 'Alle artikler',
+'allinnamespace' => 'Alle sider (i $1 navnerummet)',
+'allnotinnamespace' => 'Alle sider (ikke i $1 navnerummet)',
+'allpagesprev' => 'Forrige',
+'allpagesnext' => 'Næste',
+'allpagessubmit' => 'Vis',
+
+# Email this user
+#
+"mailnologin" => "Ingen afsenderadresse",
+"mailnologintext" => "Du skal være [[Speciel:Userlogin|logget på]] og have en gyldig e-mailadresse sat i dine [[Speciel:Preferences|indstillinger]] for at sende e-mail til andre brugere.",
+"emailuser" => "E-mail til denne bruger",
+"emailpage" => "E-mail bruger",
+"emailpagetext" => "Hvis denne bruger har sat en gyldig e-mail-adresse i
+sine brugerindstillinger, så vil formularen herunder sende en enkelt
+besked.
+Den e-mailadresse, du har sat i dine brugerindstillinger, vil dukke op
+i \"Fra\" feltet på denne mail, så modtageren er i stand til at svare.",
+'usermailererror' => 'E-mail-modulet returnerede en fejl:',
+'defemailsubject' => "{{SITENAME}} e-mail",
+"noemailtitle" => "Ingen e-mail-adresse",
+"noemailtext" => "Denne bruger har ikke angivet en gyldig e-mail-adresse,
+eller har valgt ikke at modtage e-mail fra andre brugere.",
+"emailfrom" => "Fra",
+"emailto" => "Til",
+"emailsubject" => "Emne",
+"emailmessage" => "Besked",
+"emailsend" => "Send",
+"emailsent" => "E-mail sendt",
+"emailsenttext" => "Din e-mail er blevet sendt.",
+
+# Watchlist
+#
+"watchlist" => "Overvågningsliste",
+"nowatchlist" => "Du har ingenting i din overvågningsliste.",
+"watchnologin" => "Ikke logget på",
+"watchnologintext" => "Du skal være [[Speciel:Userlogin|logget på]] for at kunne ændre din overvågningsliste.",
+"addedwatch" => "Tilføjet til din overvågningsliste",
+"addedwatchtext" => "Siden \"$1\" er blevet tilføjet til din [[Speciel:Watchlist|overvågningsliste]]. Fremtidige ændringer til denne side og den tilhørende diskussionsside vil blive listet der, og siden vil fremstå '''fremhævet''' i [[Speciel:Recentchanges|listen med de seneste ændringer]] for at gøre det lettere at finde den. Hvis du senere vil fjerne siden fra din overvågningsliste, så klik \"Fjern overvågning\".",
+"removedwatch" => "Fjernet fra overvågningsliste",
+"removedwatchtext" => "Siden \"$1\" er blevet fjernet fra din
+overvågningsliste.",
+'watch' => 'Overvåg',
+"watchthispage" => "Overvåg side",
+'unwatch' => 'Fjern overvågning',
+"unwatchthispage" => "Fjern overvågning",
+"notanarticle" => "Ikke en artikel",
+"watchnochange" => "Ingen af siderne i din overvågningsliste er ændret i den valgte periode.",
+"watchdetails" => "* Du har $1 sider på din overvågningsliste (fratrukket alle diskussionssider).
+* I tidsintervallet valgt herunder, har brugerne foretaget $2 redigeringer i {{SITENAME}}.
+* $3
+* Du kan [[Special:Watchlist/edit|vise og redigere den komplette liste]].",
+'wlheader-enotif' => "* E-mail underretning er slået til.",
+'wlheader-showupdated' => "* Sider der er ændret siden dit sidste besøg er '''fremhævet'''",
+"watchmethod-recent" => "Tjekker seneste ændringer for sider i din overvågningsliste",
+"watchmethod-list" => "Tjekker seneste ændringer for sider i din overvågningsliste",
+"removechecked" => "Fjern valgte sider fra min overvågningsliste",
+"watchlistcontains" => "Din overvågningsliste indeholder $1 sider.",
+"watcheditlist" => "Her er en alfabetisk liste over siderne i din overvågningsliste.
+Vælg de sider du vil fjerne fra din overvågningsliste
+og klik på 'fjern valgte sider fra min overvågningsliste' knappen
+i bunden af skærmen.",
+"removingchecked" => "Fjerner de valgte sider fra din overvågningsliste...",
+"couldntremove" => "Kunne ikke fjerne '$1'...",
+"iteminvalidname" => "Problem med '$1', ugyldigt navn...",
+"wlnote" => "Nedenfor er de seneste $1 ændringer i de sidste <b>$2</b> timer.",
+'wlshowlast' => "Vis de seneste $1 timer $2 dage $3",
+'wlsaved' => 'Dette er en gemt version af din overvågningsliste.',
+'wlhideshowown' => '$1 mine redigeringer.',
+'wlhideshowbots' => '$1 robotredigeringer.',
+'wldone' => 'Gennemført.',
+
+'enotif_mailer' => '{{SITENAME}} informationsmail',
+'enotif_reset' => 'Marker alle sider som besøgt',
+'enotif_newpagetext'=> 'Dette er en ny side.',
+'changed' => 'ændret',
+'created' => 'oprettet',
+'enotif_subject' => '{{SITENAME}}-siden $PAGETITLE_QP er blevet ændret af $PAGEEDITOR_QP',
+'enotif_lastvisited' => 'Se $1 for alle ændringer siden dit sidste besøg.',
+'enotif_body' => 'Kære $WATCHINGUSERNAME,
+
+{{SITENAME}}-siden $PAGETITLE er blevet ændret den $PAGEEDITDATE af $PAGEEDITOR, se $PAGETITLE_URL for den nyeste version.
+
+$NEWPAGE
+
+Bidragyderens beskrivelse: $PAGESUMMARY $PAGEMINOREDIT
+Kontakt bidragyderen:
+mail $PAGEEDITOR_EMAIL
+wiki $PAGEEDITOR_WIKI
+
+Du vil ikke modtage flere beskeder om yderligere ændringer af denne side med mindre du besøger den. På din overvågningsliste kan du også nulstille alle markeringer på de sider, du overvåger.
+
+ Med venlig hilsen {{SITENAME}}s informationssystem
+
+--
+Besøg {{fullurl:Special:Watchlist/edit}} for at ændre indstillingerne for din overvågningsliste
+
+Tilbagemelding og yderligere hjælp:
+{{fullurl:Landsbybrønden}}',
+
+# Delete/protect/revert
+#
+"deletepage" => "Slet side",
+"confirm" => "Bekræft",
+"excontent" => "indholdet var: '$1'",
+"excontentauthor" => "indholdet var: '$1' (og den eneste forfatter var '$2')",
+"exbeforeblank" => "indholdet før siden blev tømt var: '$1'",
+"exblank" => "siden var tom",
+"confirmdelete" => "Bekræft sletning",
+"deletesub" => "(Sletter \"$1\")",
+"historywarning" => "Advarsel: Siden du er ved at slette har en historie:",
+"confirmdeletetext" => "Du er ved permanent at slette en side
+eller et billede sammen med hele den tilhørende historie fra databasen.
+Bekræft venligst at du virkelig vil gøre dette, at du forstår
+konsekvenserne, og at du gør dette i overensstemmelse med
+[[Project:Politik]].",
+"actioncomplete" => "Gennemført",
+"deletedtext" => "\"$1\" er slettet.
+Se $2 for en fortegnelse over de nyeste sletninger.",
+"deletedarticle" => "slettede \"$1\"",
+"dellogpage" => "Sletningslog",
+"dellogpagetext" => "Herunder er en liste over de nyeste sletninger.
+Alle tider er serverens tid (UTC).",
+"deletionlog" => "sletningslog",
+"reverted" => "Gendannet en tidligere version",
+"deletecomment" => "Begrundelse for sletning",
+"imagereverted" => "Gendannelse af en tidligere version gennemført med
+succes.",
+"rollback" => "Fjern redigeringer",
+'rollback_short' => 'Fjern redigering',
+"rollbacklink" => "fjern redigering",
+"rollbackfailed" => "Kunne ikke fjerne redigeringen",
+"cantrollback" => "Kan ikke fjerne redigering;
+den sidste bruger er den eneste forfatter.",
+"alreadyrolled" => "Kan ikke fjerne den seneste redigering af [[:$1]] foretaget af [[Bruger:$2|$2]] ([[Bruger diskussion:$2|diskussion]]); en anden har allerede redigeret siden eller fjernet redigeringen. Den seneste redigering er foretaget af [[Bruger:$3|$3]] ([[Bruger diskussion:$3|diskussion]]).",
+# only shown if there is an edit comment
+"editcomment" => "Kommentaren til redigeringen var: \"<i>$1</i>\".",
+"revertpage" => "Gendannelse til seneste version ved $1, fjerner ændringer fra $2",
+'sessionfailure' => 'There seems to be a problem with your login session;
+this action has been canceled as a precaution against session hijacking.
+Please hit "back" and reload the page you came from, then try again.',
+"protectlogpage" => "Liste_over_beskyttede_sider",
+"protectlogtext" => "Herunder er en liste over sider der er blevet beskyttet/har fået fjernet beskyttelsen.
+Se [[Project:Beskyttet side]] for mere information.",
+"protectedarticle" => "[[$1]] beskyttet",
+"unprotectedarticle" => "fjernet beskyttelse af [[$1]]",
+'protectsub' =>"(Beskytter \"$1\")",
+'confirmprotecttext' => 'Vil du virkelig beskytte denne side?',
+'confirmprotect' => 'Bekræft beskyttelse',
+'protectmoveonly' => 'Beskyt kun fra at blive flyttet',
+'protectcomment' => 'Begrundelse for beskyttelse',
+'unprotectsub' =>"(Fjern beskyttelse af \"$1\")",
+'confirmunprotecttext' => 'Vil du virkelig fjerne beskyttelsen fra denne side?',
+'confirmunprotect' => 'Bekræft fjernelse af beskyttelse',
+'unprotectcomment' => 'Begrundelse for fjernet beskyttelse',
+
+# Undelete
+"undelete" => "Gendan en slettet side",
+"undeletepage" => "Se og gendan slettede sider",
+"undeletepagetext" => "De følgende sider er slettede, men de findes
+stadig i arkivet og kan gendannes. Arkivet blivet periodevis slettet.",
+"undeletearticle" => "Gendan slettet artikel",
+"undeleterevisions" => "$1 revisioner arkiveret",
+"undeletehistory" => "Hvis du gendanner siden, vil alle de historiske
+revisioner også blive gendannet. Hvis en ny side med det samme navn
+er oprettet siden denne blev slettet, så vil de gendannede revisioner
+dukke op i den tidligere historie, og den nyeste revision vil forblive
+på siden.",
+"undeleterevision" => "Slettet version fra $1",
+"undeletebtn" => "Gendan!",
+"undeletedarticle" => "gendannede \"$1\"",
+'undeletedrevisions' => "$1 versioner gendannet",
+
+# Namespace form on various pages
+'namespace' => 'Namvnerum:',
+'invert' => 'Invert selection',
+
+# Contributions
+#
+"contributions" => "Brugerbidrag",
+"mycontris" => "Mine bidrag",
+"contribsub" => "For $1",
+"nocontribs" => "Ingen ændringer er fundet som opfylder disse kriterier.",
+"ucnote" => "Herunder er denne brugers sidste <b>$1</b> ændringer i de
+sidste <b>$2</b> dage.",
+"uclinks" => "Vis de sidste $1 ændringer; vis de sidste $2 dage.",
+"uctop" => " (top)" ,
+'newbies' => 'nybegyndere',
+
+# What links here
+#
+"whatlinkshere" => "Hvad henviser hertil",
+"notargettitle" => "Intet mål",
+"notargettext" => "Du har ikke angivet en målside eller bruger at udføre denne funktion på.",
+"linklistsub" => "(Liste over henvisninger)",
+"linkshere" => "De følgende sider henviser her til:",
+"nolinkshere" => "Ingen sider henviser her til.",
+"isredirect" => "omdirigeringsside",
+
+# Block/unblock IP
+#
+"blockip" => "Bloker bruger",
+"blockiptext" => "Brug formularen herunder til at blokere for skriveadgangen fra en specifik IP-adresse eller et brugernavn. Dette må kun gøres for at forhindre vandalisme og skal være i overensstemmelse med [[{{ns:4}}:Politik|{{SITENAME}}s politik]]. Angiv en specifik begrundelse herunder (for eksempel med angivelse af sider der har været udsat for vandalisme). Udløbet (expiry) angives i GNUs standardformat, som er beskrevet i [http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html vejledningen til tar] (på engelsk), fx \"1 hour\", \"2 days\", \"next Wednesday\", \"1 January 2017\". Alternativt kan en blokering gøres uendelig (skriv \"indefinite\" eller \"infinite\"). For oplysninger om blokering af IP-adresseblokke, se [[meta:Range blocks|IP-adresseblokke]] (på engelsk). For at ophæve en blokering, se [[Speciel:Ipblocklist|listen over blokerede IP-adresser og brugernavne]].",
+"ipaddress" => "IP-adresse/brugernavn",
+'ipbexpiry' => 'Udløb',
+"ipbreason" => "Begrundelse",
+"ipbsubmit" => "Bloker denne bruger",
+"badipaddress" => "IP-adressen/brugernavnet er udformet forkert eller eksistere ikke.",
+"blockipsuccesssub" => "Blokering udført med succes",
+"blockipsuccesstext" => "\"$1\" er blevet blokeret.
+<br />Se [[Speciel:Ipblocklist|IP blokeringslisten]] for alle blokeringer.",
+"unblockip" => "Ophæv blokering af bruger",
+"unblockiptext" => "Brug formularen herunder for at gendanne skriveadgangen
+for en tidligere blokeret IP-adresse eller bruger.",
+"ipusubmit" => "Ophæv blokeringen af denne adresse",
+"ipblocklist" => "Liste over blokerede IP-adresser og brugernavne",
+'blocklistline' => '$1, $2 blokerede $3 ($4)',
+'infiniteblock' => 'udløber infinite', //fixme
+'expiringblock' => 'udløber $1',
+"blocklink" => "bloker",
+"unblocklink" => "ophæv blokering",
+"contribslink" => "bidrag",
+"autoblocker" => "Automatisk blokeret fordi du deler IP-adresse med \"$1\". Begrundelse \"$2\".",
+'blocklogpage' => 'Blokeringslog',
+'blocklogentry' => 'blokerede "$1" med $2 som udløbstid',
+'blocklogtext' => 'Dette er en liste over blokerede brugere og ophævede blokeringer af brugere. Automatisk blokerede IP-adresser er ikke anført her. Se [[Speciel:Ipblocklist|blokeringslisten]] for den nuværende liste over blokerede brugere.',
+'unblocklogentry' => 'ophævede blokering af "$1"',
+'range_block_disabled' => 'Sysop-muligheden for at oprette blokeringsklasser er slået fra.',
+'ipb_expiry_invalid' => 'Udløbstiden er ugyldig.',
+'ip_range_invalid' => "Ugyldigt IP-interval.",
+'proxyblocker' => 'Proxy-blokering',
+'proxyblockreason' => 'Din IP-adresse er blevet blokeret fordi den er en såkaldt \'\'åben proxy\'\'. Kontakt din Internet-udbyder eller tekniske hotline og oplyse dem om dette alvorlige sikkerhedsproblem.',
+'proxyblocksuccess' => "Færdig.",
+
+# Developer tools
+#
+"lockdb" => "Lås database",
+"unlockdb" => "Lås database op",
+"lockdbtext" => "At låse databasen vil forhindre alle brugere i at kunne redigere sider, ændre indstillinger, redigere overvågningslister og andre ting der kræver ændringer i databasen. Bekræft venligst at du har til hensigt at gøre dette, og at du vil låse databasen op, når din vedligeholdelse er overstået.",
+"unlockdbtext" => "At låse databasen op vil gøre, at alle brugere igen
+kan redigere sider, ændre deres indstillinger, redigere deres
+overvågningsliste, og andre ting der kræver ændringer i databasen.
+Bekræft venligst at du har til hensigt at gøre dette.",
+"lockconfirm" => "Ja, jeg vil virkelig låse databasen.",
+"unlockconfirm" => "Ja, jeg vil virkelig låse databasen op.",
+"lockbtn" => "Lås databasen",
+"unlockbtn" => "Lås databasen op",
+"locknoconfirm" => "Du har ikke bekræftet handlingen.",
+"lockdbsuccesssub" => "Databasen er nu låst",
+"unlockdbsuccesssub" => "Databasen er nu låst op",
+"lockdbsuccesstext" => "Mediawikidatabasen er låst. <br />Husk at fjerne låsen når du er færdig med din vedligeholdelse.",
+"unlockdbsuccesstext" => "Mediawikidatabasen er låst op.",
+
+# Make sysop
+'makesysoptitle' => 'Gør en bruger til administrator - sysop',
+'makesysoptext' => 'Denne formular bruges af bureaukrater til at gøre almindelige brugere til administratorer og/eller tildele andre rettigheder til en bruger.
+Indsæt navnet på brugeren i tekstboksen og tryk på knappen for at ændre rettighederne (i.e. gøre brugeren til administrator',
+'makesysopname' => 'Brugerens navn:',
+'makesysopsubmit' => 'Gør denne bruger til administrator',
+'makesysopok' => "<b>Bruger \"$1\" er nu administrator</b>",
+'makesysopfail' => "<b>Bruger \"$1\" kunne ikke gøres til administrator. (Har du stavet navnet rigtigt?)</b>",
+'setbureaucratflag' => 'Sæt bureaukratflag',
+'rightslogtext' => 'Dette er en log over ændringer i brugeres rettigheder.',
+'rights' => 'Rettigheder:',
+'set_user_rights' => 'Tildel brugerrettigheder',
+'user_rights_set' => "<b>Rettigheder for bruger \"$1\" er opdateret</b>",
+'set_rights_fail' => "<b>Der kunne ikke tildeles brugerrettigheder til \"$1\". (Er navnet korrekt?)</b>",
+'makesysop' => 'Tildel brugerrettigheder',
+'already_sysop' => 'Denne bruger er allerede administrator',
+'already_bureaucrat' => 'Denne bruger er allerede bureaucrat',
+
+# Move page
+#
+"movepage" => "Flyt side",
+"movepagetext" => "Når du bruger formularen herunder vil du få omdøbt en
+side og flyttet hele sidens historie til det nye navn.
+Den gamle titel vil blive en omdirigeringsside til den nye titel.
+Henvisninger til den gamle titel vil ikke blive ændret. Sørg for at
+tjekke for dobbelte eller dårlige omdirigeringer.
+Du er ansvarlig for, at alle henvisninger stadig peger derhen, hvor det er
+meningen de skal pege.
+
+Bemærk at siden '''ikke''' kan flyttes hvis der allerede er en side
+med den nye titel, medmindre den side er tom eller er en omdirigering
+uden nogen historie. Det betyder at du kan flytte en side tilbage hvor
+den kom fra, hvis du kommer til at lave en fejl.
+
+<b>ADVARSEL!</b>
+Dette kan være en drastisk og uventet ændring for en populær side;
+vær sikker på, at du forstår konsekvenserne af dette før du
+fortsætter.",
+"movepagetalktext" => "Den tilhørende diskussionsside, hvis der er en,
+vil automatisk blive flyttet med siden '''medmindre:'''
+*Du flytter siden til et andet navnerum,
+*En ikke-tom diskussionsside allerede eksisterer under det nye navn, eller
+*Du fjerner markeringen i boksen nedenunder.
+
+I disse tilfælde er du nødt til at flytte eller sammenflette siden manuelt.",
+"movearticle" => "Flyt side",
+"movenologin" => "Ikke logget på",
+"movenologintext" => "Du skal være registreret bruger og være [[Speciel:Userlogin|logget på]]
+for at flytte en side.",
+"newtitle" => "Til ny titel",
+"movepagebtn" => "Flyt side",
+"pagemovedsub" => "Flytning gennemført",
+"pagemovedtext" => "Siden \"[[$1]]\" er flyttet til \"[[$2]]\".",
+"articleexists" => "En side med det navn eksisterer allerede, eller det
+navn du har valgt er ikke gyldigt. Vælg et andet navn.",
+"talkexists" => "Siden blev flyttet korrekt, men den tilhørende
+diskussionsside kunne ikke flyttes, fordi der allerede eksisterer en
+med den nye titel. Du er nødt til at flette dem sammen manuelt.",
+"movedto" => "flyttet til",
+"movetalk" => "Flyt også \"diskussionssiden\", hvis den eksisterer.",
+"talkpagemoved" => "Den tilhørende diskussionsside blev også flyttet.",
+"talkpagenotmoved" => "Den tilhørende diskussionsside blev
+<strong>ikke</strong> flyttet.",
+'1movedto2' => "$1 flyttet til $2",
+'1movedto2_redir' => '$1 flyttet til $2 over en omdirigering',
+'movelogpage' => 'Flyttelog',
+'movelogpagetext' => 'Nedenfor er en liste over flyttede sider.',
+'movereason' => 'Begrundelse',
+'revertmove' => 'gendan',
+'delete_and_move' => 'Slet og flyt',
+'delete_and_move_text' =>
+'==Sletning nødvendig==
+
+Målartiklen "[[$1]]" eksisterer allerede. Vil du slette den for at lave plads til flytningen?',
+'delete_and_move_reason' => 'Slet for at lave plads til flyningen',
+'selfmove' => "Begge sider har samme navn. Man kan ikke flytte en side oven i sig selv.",
+'immobile_namespace' => "Måltitlen er en speciel type; man kan ikke flytte sider ind i det navnerum.",
+
+# Export
+
+'export' => 'Eksportér sider',
+'exporttext' => 'Du kan eksportere teksten og historikken fra en eller flere sider i et simpelt XML format. Dette kan bruges til at indsætte siderne i en anden wiki der bruger MediaWiki softwaren, eller du kan beholde den for din egen fornøjelses skyld',
+'exportcuronly' => 'Eksportér kun den nuværende version, ikke hele historikken',
+
+# Namespace 8 related
+
+'allmessages' => 'Alle beskeder',
+'allmessagesname' => 'Navn',
+'allmessagesdefault' => 'Standard tekst',
+'allmessagescurrent' => 'Nuværende tekst',
+'allmessagestext' => 'Dette er en liste over alle beskeder i MediaWiki: navnerummet.',
+'allmessagesnotsupportedUI' => 'Dit aktuelle grænsefladesprog <b>$1</b> er ikke understøttet af Special:AllMessages på dette websted.',
+'allmessagesnotsupportedDB' => 'Special:AllMessages ikke understøttet fordi wgUseDatabaseMessages er slået fra.',
+
+# Thumbnails
+
+'thumbnail-more' => 'Forstør',
+'missingimage' => "<b>Mangler billede</b><br /><i>$1</i>",
+'filemissing' => 'Filen mangler',
+
+# Special:Import
+'import' => 'Importere sider',
+'importinterwiki' => 'Transwiki import',
+'importtext' => 'Eksportér filen fra kilde-wiki\'en ved hjælp af værktøjet Special:Export, gem den på din harddisk og læg den op her.',
+'importfailed' => "Importering fejlede: $1",
+'importnotext' => 'Tom eller ingen tekst',
+'importsuccess' => 'Importen lykkedes!',
+'importhistoryconflict' => 'Der er en konflikt i versionhistorikken (siden kan have været importeret før)',
+'importnosources' => 'No transwiki import sources have been defined and direct history uploads are disabled.',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Søg i {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Marker dette som en mindre ændring [alt-i]',
+'tooltip-save' => 'Gem dine ændringer [alt-s]',
+'tooltip-preview' => 'Forhåndsvis dine ændringer, brug venligst denne funktion inden du gemmer! [alt-p]',
+'tooltip-diff' => 'Vis hvilke ændringer du har lavet i teksten. [alt-v]',
+'tooltip-compareselectedversions' => 'Se forskellene imellem de to valgte versioner af denne side. [alt-v]',
+'tooltip-watch' => 'Tilføj denne side til din overvågningsliste [alt-w]',
+
+# stylesheets
+#'monobook.css' => '/* edit this file to customize the monobook skin for the entire site */',
+#'monobook.js' => '/* redigér denne fil for at ændre js-indstillinger i monobook-udseendet */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF-metadata er slået fra på denne server.',
+'nocreativecommons' => 'Creative Commons RDF-metadata er slået fra på denne server.',
+'notacceptable' => 'Wiki-serveren kan ikke levere data i et format, som din klient understøtter.',
+
+# Attribution
+
+'anonymous' => "Anonym(e) bruger(e) af {{SITENAME}}",
+'siteuser' => "{{SITENAME}} bruger $1",
+'lastmodifiedatby' => "Denne side blev senest ændret $2, $1 af $3.",
+'and' => 'og',
+'othercontribs' => "Baseret på arbejde af $1.",
+'others' => 'andre',
+'siteusers' => "{{SITENAME}} bruger(e) $1",
+'creditspage' => 'Sidens forfattere',
+'nocredits' => 'Der er ingen forfatteroplysninger om denne side.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Spambeskyttelsesfilter',
+'spamprotectiontext' => 'Siden du prøver at få adgang til er blokeret af spamfilteret. Dette skyldes sandsynligvis et link til et eksternt websted. Se [[m:spam blacklist]] for en komplet liste af blokerede websteder. Hvis du mener at spamfilteret blokerede redigeringen ved en fejl, så kontakt en [[m:Special:Listadmins|m:administrator]]. Det følgende er et udtræk af siden der bevirkede blokeringen:',
+'spamprotectionmatch' => 'Følgende tekst udløste vores spamfilter: $1',
+'subcategorycount' => "Der er $1 underkategorier i denne kategori.",
+'categoryarticlecount' => "Der er $1 artikler i denne kategori.",
+'listingcontinuesabbrev' => " forts.",
+
+# Info page
+"infosubtitle" => "Information om siden",
+"numedits" => "Antal redigeringer (artikel): $1",
+"numtalkedits" => "Antal redigeringer (diskussionsside): $1",
+"numwatchers" => "Antal overvågere: $1",
+"numauthors" => "Antal forskellige forfattere (artikel): $1",
+"numtalkauthors" => "Antal forskellige forfattere (diskussionsside): $1",
+
+# Math options
+'mw_math_png' => "Vis altid som PNG",
+'mw_math_simple' => "HTML hvis meget simpel ellers PNG",
+'mw_math_html' => "HTML hvis muligt ellers PNG",
+'mw_math_source' => "Lad være som TeX (for tekstbrowsere)",
+'mw_math_modern' => "Anbefalet til moderne browsere",
+'mw_math_mathml' => "MathML hvis muligt",
+
+# Patrolling
+'markaspatrolleddiff' => "Markér som patruljeret",
+'markaspatrolledtext' => "Markér denne artikel som patruljeret",
+'markedaspatrolled' => "Markeret som patruljeret",
+'markedaspatrolledtext' => "Den valgte revision er nu markeret som patruljeret.",
+'rcpatroldisabled' => "Seneste ændringer-patruljeringen er slået fra",
+'rcpatroldisabledtext' => "Funktionen til seneste ændringer-patruljeringen er pt. slået fra.",
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Min brugerside\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Brugersiden for den ip-adresse du redigerer som\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Min diskussionsside\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskussion om redigeringer fra denne ip-adresse\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Mine indstillinger\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Listen over sider du overvåger for ændringer.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Listen over dine bidrag\');
+ta[\'pt-login\'] = new Array(\'o\',\'Du opfordres til at logge på, men det er ikke obligatorisk.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Du opfordres til at logge på, men det er ikke obligatorisk\');
+ta[\'pt-logout\'] = new Array(\'\',\'Log af\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Diskussion om indholdet på siden\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Du kan redigere denne side. Brug venligst forhåndsvisning før du gemmer.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Tilføj en kommentar til denne diskussion.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Denne side er beskyttet. Du kan kigge på kildekoden.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Tidligere versioner af denne side.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Beskyt denne side\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Slet denne side\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Gendan de redigeringer der blev lavet på denne side før den blev slettet\');
+ta[\'ca-move\'] = new Array(\'m\',\'Flyt denne side\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Sæt denne side på din overvågningsliste\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Fjern denne side fra din overvågningsliste\');
+ta[\'search\'] = new Array(\'f\',\'Søg på denne wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Forsiden\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Besøg forsiden\');
+ta[\'n-portal\'] = new Array(\'\',\'Om projektet, hvad du kan gøre, hvor tingene findes\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Find baggrundsinformation om aktuelle begivenheder\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Listen over de seneste ændringer i wikien.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Gå til en tilfældig artikel\');
+ta[\'n-help\'] = new Array(\'\',\'Hvordan gør jeg ...\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Støt os\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Liste med alle sider som henviser hertil\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Seneste ændringer i sider som denne side henviser til\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS-feed for denne side\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom-feed for denne side\');
+ta[\'t-contributions\'] = new Array(\'\',\'Se denne brugers bidrag\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Send en e-mail til denne bruger\');
+ta[\'t-upload\'] = new Array(\'u\',\'Upload et billede eller anden mediafil\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Liste med alle specielle sider\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Se indholdet\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Se brugersiden\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Se mediasiden\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Dette er en speciel side; man kan ikke redigere sådanne sider.\');
+/*ta[\'ca-nstab-project\'] = new Array(\'a\',\'Se Wikipediasiden\');*/
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Se billedsiden\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Se systembeskeden\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Se skabelonen\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Se hjælpesiden\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Se kategorisiden\');',
+
+# image deletion
+'deletedrevision' => 'Slettede gammel version $1.',
+
+# browsing diffs
+'previousdiff' => '← Gå til forrige forskel',
+'nextdiff' => 'Gå til næste forskel →',
+
+'imagemaxsize' => 'Begræns størrelsen af billeder på billedsiderne til:',
+'thumbsize' => 'Thumbnail størrelse :',
+'showbigimage' => 'Download en version i høj opløsning ($1x$2, $3 KB)',
+
+'newimages' => 'Galleri med de nyeste billeder',
+'noimages' => 'Ingenting at se.',
+
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Bruger:',
+'speciallogtitlelabel' => 'Titel:',
+
+'passwordtooshort' => 'Dit kodeord er for kort. Det skal være mindst $1 tegn langt.',
+
+# Media Warning
+'mediawarning' => "'''Advarsel''', denne filtype kan muligvis indeholde skadelig kode, du kan beskadige dit system hvis du udfører den.
+<hr />",
+# external editor support
+'edit-externally' => 'Rediger denne fil med en ekstern editor',
+'edit-externally-help' => 'Se [http://meta.wikimedia.org/wiki/Help:External_editors setup instruktionerne] for mere information.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'alle',
+'imagelistall' => 'alle',
+'watchlistall1' => 'alle',
+'watchlistall2' => 'alle',
+'namespacesall' => 'alle',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesDe.php b/languages/messages/MessagesDe.php
new file mode 100644
index 000000000000..19537cadf244
--- /dev/null
+++ b/languages/messages/MessagesDe.php
@@ -0,0 +1,2186 @@
+<?php
+/**
+ * German (Deutsch)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Jimmy Collins <jimmy.collins@web.de>
+ */
+
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Spezial',
+ NS_MAIN => '',
+ NS_TALK => 'Diskussion',
+ NS_USER => 'Benutzer',
+ NS_USER_TALK => 'Benutzer_Diskussion',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_Diskussion',
+ NS_IMAGE => 'Bild',
+ NS_IMAGE_TALK => 'Bild_Diskussion',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_Diskussion',
+ NS_TEMPLATE => 'Vorlage',
+ NS_TEMPLATE_TALK => 'Vorlage_Diskussion',
+ NS_HELP => 'Hilfe',
+ NS_HELP_TALK => 'Hilfe_Diskussion',
+ NS_CATEGORY => 'Kategorie',
+ NS_CATEGORY_TALK => 'Kategorie_Diskussion'
+);
+
+$quickbarSettings = array(
+ 'Keine', 'Links, fest', 'Rechts, fest', 'Links, schwebend'
+);
+
+$skinNames = array(
+ 'standard' => 'Klassik',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Kölnisch Blau',
+ 'smarty' => 'Paddington',
+ 'montparnasse' => 'Montparnasse',
+ 'davinci' => 'DaVinci',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'MySkin',
+ 'chick' => 'Küken'
+);
+
+
+$bookstoreList = array(
+ 'abebooks.de' => 'http://www.abebooks.de/servlet/BookSearchPL?ph=2&isbn=$1',
+ 'amazon.de' => 'http://www.amazon.de/exec/obidos/ISBN=$1',
+ 'buch.de' => 'http://www.buch.de/de.buch.shop/shop/1/home/schnellsuche/buch/?fqbi=$1',
+ 'buchhandel.de' => 'http://www.buchhandel.de/vlb/vlb.cgi?type=voll&isbn=$1',
+ 'Karlsruher Virtueller Katalog (KVK)' => 'http://www.ubka.uni-karlsruhe.de/kvk.html?SB=$1',
+ 'Lehmanns Fachbuchhandlung' => 'http://www.lob.de/cgi-bin/work/suche?flag=new&stich1=$1'
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = '/^([äöüßa-z]+)(.*)$/sDu';
+
+/**
+ * Alternate names of special pages. All names are case-insensitive. The first
+ * listed alias will be used as the default. Aliases from the fallback
+ * localisation (usually English) will be included by default.
+ *
+ * This array may be altered at runtime using the LangugeGetSpecialPageAliases
+ * hook.
+ */
+$specialPageAliases = array(
+ 'DoubleRedirects' => array( 'Doppelte_Weiterleitungen' ),
+ 'BrokenRedirects' => array( 'Kaputte_Weiterleitungen' ),
+ 'Disambiguations' => array( 'Begriffsklärungsverweise' ),
+ 'Userlogin' => array( 'Anmelden' ),
+ 'Userlogout' => array( 'Abmelden' ),
+ 'Preferences' => array( 'Einstellungen' ),
+ 'Watchlist' => array( 'Beobachtungsliste' ),
+ 'Recentchanges' => array( 'Letzte_Änderungen' ),
+ 'Upload' => array( 'Hochladen' ),
+ 'Imagelist' => array( 'Dateien', 'Dateiliste' ),
+ 'Newimages' => array( 'Neue_Dateien' ),
+ 'Listusers' => array( 'Benutzer' ),
+ 'Statistics' => array( 'Statistik' ),
+ 'Randompage' => array( 'Zufällige_Seite' ),
+ 'Lonelypages' => array( 'Verwaiste_Seiten' ),
+ 'Uncategorizedpages' => array( 'Nicht_kategorisierte_Seiten' ),
+ 'Uncategorizedcategories' => array( 'Nicht_kategorisierte_Kategorien' ),
+ 'Uncategorizedimages' => array( 'Nicht_kategorisierte_Dateien' ),
+ 'Unusedcategories' => array( 'Unbenutzte_Kategorien' ),
+ 'Unusedimages' => array( 'Unbenutzte_Dateien' ),
+ 'Wantedpages' => array( 'Gewünschte_Seiten' ),
+ 'Wantedcategories' => array( 'Gewünschte_Kategorien' ),
+ 'Mostlinked' => array( 'Meistverlinkte_Seiten' ),
+ 'Mostlinkedcategories' => array( 'Meistbenutzte_Kategorien' ),
+ 'Mostcategories' => array( 'Meistkategorisierte_Seiten' ),
+ 'Mostimages' => array( 'Meistbenutzte_Dateien' ),
+ 'Mostrevisions' => array( 'Meistbearbeitete_Seiten' ),
+ 'Shortpages' => array( 'Kürzeste_Seiten' ),
+ 'Longpages' => array( 'Längste_Seiten' ),
+ 'Newpages' => array( 'Neue_Seiten' ),
+ 'Ancientpages' => array( 'Älteste_Seiten' ),
+ 'Deadendpages' => array( 'Sackgassenseiten' ),
+ 'Allpages' => array( 'Alle_Seiten' ),
+ 'Prefixindex' => array( 'Präfixindex' ) ,
+ 'Ipblocklist' => array( 'Gesperrte_IPs' ),
+ 'Specialpages' => array( 'Spezialseiten' ),
+ 'Contributions' => array( 'Beiträge' ),
+ 'Emailuser' => array( 'E-Mail' ),
+ 'Whatlinkshere' => array( 'Verweisliste' ),
+ 'Recentchangeslinked' => array( 'Änderungen_an_verlinkten_Seiten' ),
+ 'Movepage' => array( 'Verschieben' ),
+ 'Blockme' => array( 'Proxy-Sperre' ),
+ 'Booksources' => array( 'ISBN-Suche' ),
+ 'Categories' => array( 'Kategorien' ),
+ 'Export' => array( 'Exportieren' ),
+ 'Version' => array( 'Version' ),
+ 'Allmessages' => array( 'MediaWiki-Systemnachrichten' ),
+ 'Log' => array( 'Logbuch' ),
+ 'Blockip' => array( 'Sperren' ),
+ 'Undelete' => array( 'Wiederherstellen' ),
+ 'Import' => array( 'Importieren' ),
+ 'Lockdb' => array( 'Datenbank_sperren' ),
+ 'Unlockdb' => array( 'Datenbank_entsperren' ),
+ 'Userrights' => array( 'Benutzerrechte' ),
+ 'MIMEsearch' => array( 'MIME-Typ-Suche' ),
+ 'Unwatchedpages' => array( 'Ignorierte_Seiten', 'Unbeobachtete_Seiten' ),
+ 'Listredirects' => array( 'Weiterleitungen' ),
+ 'Revisiondelete' => array( 'Versionslöschung' ),
+ 'Unusedtemplates' => array( 'Unbenutzte_Vorlagen' ),
+ 'Randomredirect' => array( 'Zufällige_Weiterleitung' ),
+ 'Mypage' => array( 'Meine_Benutzerseite' ),
+ 'Mytalk' => array( 'Meine_Diskussionsseite' ),
+ 'Mycontributions' => array( 'Meine_Beiträge' ),
+ 'Listadmins' => array( 'Administratoren' ),
+ 'Search' => array( 'Suche' ),);
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j. Y',
+ 'mdy both' => 'H:i, M j. Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. F Y',
+ 'dmy both' => 'H:i, j. M. Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'H:i, Y M j',
+);
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'Verweise unterstreichen:',
+'tog-highlightbroken' => 'Verweise auf leere Seiten hervorheben',
+'tog-justify' => 'Text als Blocksatz',
+'tog-hideminor' => 'Kleine Änderungen ausblenden',
+'tog-extendwatchlist' => 'Erweiterte Beobachtungsliste',
+'tog-usenewrc' => 'Erweiterte Darstellung (benötigt JavaScript)',
+'tog-numberheadings' => 'Überschriften automatisch nummerieren',
+'tog-showtoolbar' => 'Bearbeiten-Werkzeugleiste anzeigen',
+'tog-editondblclick' => 'Seiten mit Doppelklick bearbeiten (JavaScript)',
+'tog-editsection' => 'Links zum Bearbeiten einzelner Absätze anzeigen',
+'tog-editsectiononrightclick' => 'Einzelne Absätze per Rechtsklick bearbeiten (JavaScript)',
+'tog-showtoc' => 'Anzeigen eines Inhaltsverzeichnisses bei Seiten mit mehr als 3 Überschriften',
+'tog-rememberpassword' => 'Benutzer soll auf diesem Computer dauerhaft angemeldet bleiben',
+'tog-editwidth' => 'Text-Eingabefeld mit voller Breite',
+'tog-watchcreations' => 'Selbst erstellte Seiten automatisch beobachten',
+'tog-watchdefault' => 'Selbst geänderte und neu erstellte Seiten automatisch beobachten',
+'tog-watchmoves' => 'Selbst verschobene Seiten automatisch beobachten',
+'tog-watchdeletion' => 'Selbst gelöschte Seiten automatisch beobachten',
+'tog-minordefault' => 'Alle eigenen Änderungen als geringfügig markieren',
+'tog-previewontop' => 'Vorschau oberhalb des Bearbeitungsfensters anzeigen',
+'tog-previewonfirst' => 'Beim ersten Bearbeiten immer die Vorschau anzeigen',
+'tog-nocache' => 'Seitencache deaktivieren',
+'tog-enotifwatchlistpages' => 'Bei Änderungen an beobachteten Seiten E-Mails senden.',
+'tog-enotifusertalkpages' => 'Bei Änderungen an meiner Benutzer-Diskussionsseite E-Mails senden.',
+'tog-enotifminoredits' => 'Auch bei kleinen Änderungen an beobachteten Seiten E-Mails senden.',
+'tog-enotifrevealaddr' => 'Ihre E-Mail-Adresse wird in Benachrichtigungsmails gezeigt',
+'tog-shownumberswatching' => 'Anzahl der beobachtenden Benutzer anzeigen',
+'tog-fancysig' => 'Signatur ohne Verlinkung zur Benutzerseite',
+'tog-externaleditor' => 'Externen Editor als Standard benutzen',
+'tog-externaldiff' => 'Externes Diff-Programm als Standard benutzen',
+'tog-showjumplinks' => '„Wechseln-zu“-Links ermöglichen',
+'tog-uselivepreview' => 'Live-Vorschau nutzen (JavaScript) (experimentell)',
+'tog-forceeditsummary' => 'Warnen, wenn beim Speichern die Zusammenfassung fehlt',
+'tog-watchlisthideown' => 'Eigene Bearbeitungen in der Beobachtungsliste ausblenden',
+'tog-watchlisthidebots' => 'Bearbeitungen durch Bots in der Beobachtungsliste ausblenden',
+'tog-watchlisthideminor' => 'Kleine Bearbeitungen in der Beobachtungsliste ausblenden',
+'tog-nolangconversion' => 'Konvertierung von Sprachvarianten deaktivieren',
+'tog-ccmeonemails' => 'Schicke mir Kopien der E-Mails, die ich anderen Benutzern sende.',
+
+'underline-always' => 'immer',
+'underline-never' => 'nie',
+'underline-default' => 'von Browsereinstellung abhängig',
+
+'skinpreview' => '(Vorschau)',
+
+# Dates
+'sunday' => 'Sonntag',
+'monday' => 'Montag',
+'tuesday' => 'Dienstag',
+'wednesday' => 'Mittwoch',
+'thursday' => 'Donnerstag',
+'friday' => 'Freitag',
+'saturday' => 'Samstag',
+'sun' => 'So',
+'mon' => 'Mo',
+'tue' => 'Di',
+'wed' => 'Mi',
+'thu' => 'Do',
+'fri' => 'Fr',
+'sat' => 'Sa',
+'january' => 'Januar',
+'february' => 'Februar',
+'march' => 'März',
+'april' => 'April',
+'may_long' => 'Mai',
+'june' => 'Juni',
+'july' => 'Juli',
+'august' => 'August',
+'september' => 'September',
+'october' => 'Oktober',
+'november' => 'November',
+'december' => 'Dezember',
+'january-gen' => 'Januars',
+'february-gen' => 'Februars',
+'march-gen' => 'Märzes',
+'april-gen' => 'Aprils',
+'may-gen' => 'Mais',
+'june-gen' => 'Junis',
+'july-gen' => 'Julis',
+'august-gen' => 'Augusts',
+'september-gen' => 'Septembers',
+'october-gen' => 'Oktobers',
+'november-gen' => 'Novembers',
+'december-gen' => 'Dezembers',
+'jan' => 'Jan',
+'feb' => 'Feb',
+'mar' => 'Mär',
+'apr' => 'Apr',
+'may' => 'Mai',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Aug',
+'sep' => 'Sep',
+'oct' => 'Okt',
+'nov' => 'Nov',
+'dec' => 'Dez',
+
+# Bits of text used by many pages
+'categories' => 'Kategorien',
+'pagecategories' => '{{PLURAL:$1|Kategorie|Kategorien}}',
+'category_header' => 'Seiten in der Kategorie „$1“',
+'subcategories' => 'Unterkategorien',
+'category-media-header' => 'Medien in der Kategorie „$1“',
+
+'mainpage' => 'Hauptseite',
+'mainpagetext' => 'MediaWiki wurde erfolgreich installiert.',
+'mainpagedocfooter' => 'Hilfe zur Benutzung und Konfiguration der Wiki Software finden Sie im [http://meta.wikimedia.org/wiki/Help:Contents Benutzerhandbuch].',
+
+'portal' => '{{SITENAME}}-Portal',
+'portal-url' => '{{ns:project}}:Portal',
+'about' => 'Über',
+'aboutsite' => 'Über {{SITENAME}}',
+'aboutpage' => '{{ns:project}}:Über_{{SITENAME}}',
+'article' => 'Seite',
+'help' => 'Hilfe',
+'helppage' => '{{ns:project}}:Hilfe',
+'bugreports' => 'Kontakt',
+'bugreportspage' => '{{ns:project}}:Kontakt',
+'sitesupport' => 'Spenden',
+'sitesupport-url' => '{{ns:project}}:Spenden',
+'faq' => 'FAQ',
+'faqpage' => '{{ns:project}}:FAQ',
+'edithelp' => 'Bearbeitungshilfe',
+'newwindow' => '(öffnet ein neues Fenster)',
+'edithelppage' => '{{ns:project}}:Bearbeitungshilfe',
+'cancel' => 'Abbrechen',
+'qbfind' => 'Finden',
+'qbbrowse' => 'Blättern',
+'qbedit' => 'Ändern',
+'qbpageoptions' => 'Seitenoptionen',
+'qbpageinfo' => 'Seitendaten',
+'qbmyoptions' => 'Einstellungen',
+'qbspecialpages' => 'Spezialseiten',
+'moredotdotdot' => 'Mehr…',
+'mypage' => 'Eigene Seite',
+'mytalk' => 'Eigene Diskussion',
+'anontalk' => 'Diskussionsseite dieser IP',
+'navigation' => 'Navigation',
+
+# Metadata in edit box
+'metadata_help' => 'Metadaten:',
+
+'currentevents' => 'Aktuelle Ereignisse',
+'currentevents-url' => 'Aktuelle Ereignisse',
+
+'disclaimers' => 'Impressum',
+'disclaimerpage' => '{{ns:project}}:Impressum',
+'privacy' => 'Datenschutz',
+'privacypage' => '{{ns:project}}:Datenschutz',
+'errorpagetitle' => 'Fehler',
+'returnto' => 'Zurück zur Seite $1.',
+'tagline' => 'Aus {{SITENAME}}',
+'search' => 'Suche',
+'searchbutton' => 'Suche',
+'go' => 'Ausführen',
+'searcharticle' => 'Seite',
+'history' => 'Versionen',
+'history_short' => 'Versionen/Autoren',
+'updatedmarker' => '(geändert)',
+'info_short' => 'Information',
+'printableversion' => 'Druckversion',
+'permalink' => 'Permanentlink',
+'print' => 'Drucken',
+'edit' => 'bearbeiten',
+'editthispage' => 'Seite bearbeiten',
+'delete' => 'löschen',
+'deletethispage' => 'Diese Seite löschen',
+'undelete_short' => '{{PLURAL:$1|eine Änderung|$1 Änderungen}} wiederherstellen',
+'protect' => 'schützen',
+'protectthispage' => 'Seite schützen',
+'unprotect' => 'freigeben',
+'unprotectthispage' => 'Schutz aufheben',
+'newpage' => 'Neue Seite',
+'talkpage' => 'Diskussion',
+'specialpage' => 'Spezialseite',
+'personaltools' => 'Persönliche Werkzeuge',
+'postcomment' => 'Kommentar hinzufügen',
+'articlepage' => 'Seite',
+'talk' => 'Diskussion',
+'views' => 'Ansichten',
+'toolbox' => 'Werkzeuge',
+'userpage' => 'Benutzerseite',
+'projectpage' => 'Meta-Text',
+'imagepage' => 'Bildseite',
+'mediawikipage' => 'Inhaltsseite anzeigen',
+'templatepage' => 'Vorlagenseite anzeigen',
+'viewhelppage' => 'Hilfeseite anzeigen',
+'categorypage' => 'Kategorieseite anzeigen',
+'viewtalkpage' => 'Diskussion',
+'otherlanguages' => 'Andere Sprachen',
+'redirectedfrom' => '(Weitergeleitet von $1)',
+'redirectpagesub' => 'Weiterleitung',
+'lastmodifiedat' => 'Diese Seite wurde zuletzt am $1 um $2 Uhr geändert.', # $1 date, $2 time
+'viewcount' => 'Diese Seite wurde bisher $1 mal abgerufen.',
+'copyright' => 'Inhalt ist verfügbar unter der $1.',
+'protectedpage' => 'Geschützte Seite',
+'jumpto' => 'Wechseln zu:',
+'jumptonavigation' => 'Navigation',
+'jumptosearch' => 'Suche',
+
+'badaccess' => 'Keine ausreichenden Rechte.',
+'badaccess-group0' => 'Sie haben nicht die erforderliche Berechtigung für diese Aktion.',
+'badaccess-group1' => 'Diese Aktion ist beschränkt auf Benutzer, die der Gruppe $1 angehören.',
+'badaccess-group2' => 'Diese Aktion ist beschränkt auf Benutzer, die einer der Gruppen $1 angehören.',
+'badaccess-groups' => 'Diese Aktion ist beschränkt auf Benutzer, die einer der Gruppen $1 angehören.',
+
+'versionrequired' => 'Version $1 von MediaWiki ist erforderlich',
+'versionrequiredtext' => 'Version $1 von MediaWiki ist erforderlich, um diese Seite zu nutzen. Siehe [[{{ns:special}}:Version]]',
+
+'ok' => 'Suche',
+'pagetitle' => '$1 − {{SITENAME}}',
+'retrievedfrom' => 'Von „$1“',
+'youhavenewmessages' => 'Sie haben $1 ($2).',
+'newmessageslink' => 'neue Nachrichten',
+'newmessagesdifflink' => 'letzte Änderung',
+'editsection' => 'bearbeiten',
+'editold' => 'bearbeiten',
+'editsectionhint' => 'Abschnitt bearbeiten: $1',
+'toc' => 'Inhaltsverzeichnis',
+'showtoc' => 'Anzeigen',
+'hidetoc' => 'Verbergen',
+'thisisdeleted' => '$1 ansehen oder wiederherstellen?',
+'viewdeleted' => '$1 anzeigen?',
+'restorelink' => '$1 {{PLURAL:$1|gelöschte Version|gelöschte Versionen}}',
+'feedlinks' => 'Feed:',
+'feed-invalid' => 'Ungültiger Abonnement-Typ.',
+'feed-atom' => 'Atom',
+'feed-rss' => 'RSS',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Seite',
+'nstab-user' => 'Benutzerseite',
+'nstab-media' => 'Media',
+'nstab-special' => 'Spezialseite',
+'nstab-project' => 'Portalseite',
+'nstab-image' => 'Datei',
+'nstab-mediawiki' => 'MediaWiki-Systemtext',
+'nstab-template' => 'Vorlage',
+'nstab-help' => 'Hilfeseite',
+'nstab-category' => 'Kategorie',
+
+# Main script and global functions
+'nosuchaction' => 'Diese Aktion gibt es nicht',
+'nosuchactiontext' => 'Die in der URL angegebene Aktion wird von der MediaWiki-Software nicht unterstützt.',
+'nosuchspecialpage' => 'Diese Spezialseite gibt es nicht',
+'nospecialpagetext' => 'Die aufgerufene Spezialseite ist nicht vorhanden. Eine Liste aller verfügbaren Spezialseiten findet sich unter [[{{ns:special}}:Specialpages]].',
+
+# General errors
+'error' => 'Fehler',
+'databaseerror' => 'Fehler in der Datenbank',
+'dberrortext' => 'Es gab einen Syntaxfehler in der Datenbankabfrage.
+Die letzte Datenbankabfrage lautete: <blockquote><tt>$1</tt></blockquote> aus der Funktion „<tt>$2</tt>“.
+MySQL meldete den Fehler „<tt>$3: $4</tt>“.',
+'dberrortextcl' => 'Es gab einen Syntaxfehler in der Datenbankabfrage.
+Die letzte Datenbankabfrage lautete: „$1“ aus der Funktion „<tt>$2</tt>“.
+MySQL meldete den Fehler: „<tt>$3: $4</tt>“.',
+'noconnect' => 'Konnte keine Verbindung zur Datenbank auf $1 herstellen',
+'nodb' => 'Konnte Datenbank $1 nicht auswählen',
+'cachederror' => 'Das Folgende ist eine Kopie aus dem Cache und möglicherweise nicht aktuell.',
+'laggedslavemode' => 'Achtung: Die angezeigte Seite enthält unter Umständen nicht die jüngsten Bearbeitungen.',
+'readonly' => 'Datenbank ist gesperrt',
+'enterlockreason' => 'Bitte geben Sie einen Grund ein, warum die Datenbank gesperrt werden soll und eine Abschätzung über die Dauer der Sperrung',
+'readonlytext' => 'Die Datenbank ist vorübergehend für Neueinträge und Änderungen gesperrt. Bitte versuchen Sie es später noch einmal.
+
+Grund der Sperrung: $1',
+'missingarticle' => 'Der Text für „$1“ wurde nicht in der Datenbank gefunden.
+
+Die Seite ist möglicherweise gelöscht oder verschoben worden.
+
+Falls dies nicht der Fall ist, haben Sie eventuell einen Fehler in der Software gefunden. Bitte melden Sie dies einem [[{{ns:project}}:Administrator]] unter Nennung der URL.',
+'readonly_lag' => 'Die Datenbank wurde kurzzeitig automatisch gesperrt, damit sich die Datenbanken abgleichen können.',
+'internalerror' => 'Interner Fehler',
+'filecopyerror' => 'Die Datei „$1“ konnte nicht nach „$2“ kopiert werden.',
+'filerenameerror' => 'Die Datei „$1“ konnte nicht nach „$2“ umbenannt werden.',
+'filedeleteerror' => 'Die Datei „$1“ konnte nicht gelöscht werden.',
+'filenotfound' => 'Die Datei „$1“ wurde nicht gefunden.',
+'unexpected' => 'Unerwarteter Wert: „$1“=„$2“.',
+'formerror' => 'Fehler: Die Eingaben konnten nicht verarbeitet werden.',
+'badarticleerror' => 'Diese Aktion kann auf diese Seite nicht angewendet werden.',
+'cannotdelete' => 'Die gewählte Seite kann nicht gelöscht werden. Möglicherweise wurde sie bereits gelöscht.',
+'badtitle' => 'Ungültiger Titel',
+'badtitletext' => 'Der Titel der angeforderten Seite ist ungültig, leer oder ein ungültiger Sprachlink von einem anderen Wiki.',
+'perfdisabled' => "'''Entschuldigung!''' Diese Funktion wurde wegen Überlastung des Servers vorübergehend deaktiviert.",
+'perfdisabledsub' => 'Hier ist eine gespeicherte Kopie von $1:', # obsolete?
+'perfcached' => 'Die folgenden Daten stammen aus dem Cache und sind möglicherweise nicht aktuell:',
+'perfcachedts' => 'Diese Daten stammen aus dem Cache, letztes Update: $1',
+'querypage-no-updates' => 'Die Aktualisierungsfunktion für diese Seite ist zur Zeit deaktiviert. Die Daten werden bis auf weiteres nicht erneuert.',
+'wrong_wfQuery_params' => 'Falsche Parameter für wfQuery()<br />
+Funktion: $1<br />
+Abfrage: $2',
+'viewsource' => 'Quelltext betrachten',
+'viewsourcefor' => 'für $1',
+'protectedpagetext' => 'Diese Seite ist für das Bearbeiten gesperrt.',
+'viewsourcetext' => 'Sie können jedoch den Quelltext dieser Seite betrachten und kopieren:',
+'protectedinterface' => 'Diese Seite enthält Text für das Sprach-Interface der Software und ist gesperrt, um Missbrauch zu verhindern.',
+'editinginterface' => "'''Warnung:''' Diese Seite enthält von der MediaWiki-Software benutzten Text. Änderungen wirken sich auf die Benutzeroberfläche aus.",
+'sqlhidden' => '(SQL-Abfrage versteckt)',
+
+# Login and logout pages
+'logouttitle' => 'Benutzer-Abmeldung',
+'logouttext' => 'Sie sind nun abgemeldet.
+Sie können {{SITENAME}} jetzt anonym weiterbenutzen, oder sich unter dem selben oder einem anderen Benutzernamen wieder anmelden.',
+'welcomecreation' => '== Willkommen, $1! ==
+
+Ihr Benutzerkonto wurde eingerichtet. Vergessen Sie nicht, Ihre Einstellungen anzupassen.',
+'loginpagetitle' => 'Benutzer-Anmeldung',
+'yourname' => 'Benutzername',
+'yourpassword' => 'Passwort',
+'yourpasswordagain' => 'Passwort wiederholen',
+'remembermypassword' => 'Benutzer auf diesem Computer dauerhaft anmelden',
+'yourdomainname' => 'Ihre Domain',
+'externaldberror' => 'Entweder es liegt ein Fehler bei der externen Authentifizierung vor, oder Sie dürfen Ihr externes Benutzerkonto nicht aktualisieren.',
+'loginproblem' => "'''Es gab ein Problem mit Ihrer Anmeldung.'''<br />Bitte versuchen Sie es nochmal!",
+'alreadyloggedin' => "'''Benutzer $1, Sie sind bereits angemeldet!'''<br />",
+'login' => 'Anmelden',
+'loginprompt' => 'Um sich bei {{SITENAME}} anmelden zu können, müssen Cookies aktiviert sein.',
+'userlogin' => 'Anmelden',
+'logout' => 'Abmelden',
+'userlogout' => 'Abmelden',
+'notloggedin' => 'Nicht angemeldet',
+'nologin' => 'Sie haben kein Benutzerkonto? $1.',
+'nologinlink' => 'Neues Benutzerkonto anlegen',
+'createaccount' => 'Benutzerkonto anlegen',
+'gotaccount' => 'Sie haben bereits ein Benutzerkonto? $1.',
+'gotaccountlink' => 'Anmelden',
+'createaccountmail' => 'über E-Mail',
+'badretype' => 'Die beiden Passwörter stimmen nicht überein.',
+'userexists' => 'Dieser Benutzername ist schon vergeben. Bitte wählen Sie einen anderen.',
+'youremail' => 'E-Mail-Adresse**:',
+'username' => 'Benutzername:',
+'uid' => 'Benutzer-ID:',
+'yourrealname' => 'Echter Name*:',
+'yourlanguage' => 'Sprache der Benutzeroberfläche:',
+'yourvariant' => 'Variante',
+'yournick' => 'Unterschrift:',
+'badsig' => 'Die Syntax der Unterschrift ist ungültig; bitte HTML überprüfen.',
+'email' => 'E-Mail',
+'prefs-help-email-enotif' => 'An diese Adresse werden auch die Benachrichtigungsmails geschickt, sofern Sie das eingeschaltet haben.',
+'prefs-help-realname' => '* <strong>Echter Name</strong> (optional): Für anerkennende Nennungen Ihres Namens im Zusammenhang mit Ihren Beiträgen.',
+'loginerror' => 'Fehler bei der Anmeldung',
+'prefs-help-email' => '** <strong>E-Mail-Adresse</strong> (optional): Erlaubt anderen Benutzern Sie über Ihre Benutzerseite zu kontaktieren,
+ohne dass Sie Ihre E-Mail-Adresse veröffentlichen müssen.
+Für den Fall, dass Sie Ihr Passwort vergessen haben, kann Ihnen ein temporäres Einmal-Passwort zugesendet werden.',
+'nocookiesnew' => 'Der Benutzerzugang wurde erstellt, aber Sie sind nicht eingeloggt. {{SITENAME}} benötigt für diese Funktion Cookies, bitte aktivieren Sie diese und loggen sich dann mit Ihrem neuen Benutzernamen und dem Passwort ein.',
+'nocookieslogin' => '{{SITENAME}} benutzt Cookies zum Einloggen der Benutzer. Sie haben Cookies deaktiviert, bitte aktivieren Sie diese und versuchen es erneut.',
+'noname' => 'Sie müssen einen gültigen Benutzernamen angeben.',
+'loginsuccesstitle' => 'Anmeldung erfolgreich',
+'loginsuccess' => 'Sie sind jetzt als „$1“ bei {{SITENAME}} angemeldet.',
+'nosuchuser' => 'Der Benutzername „$1“ existiert nicht. Überprüfen Sie die Schreibweise oder legen Sie ein neues Benutzerkonto an.',
+'nosuchusershort' => 'Der Benutzername „$1“ existiert nicht. Bitte überprüfen Sie die Schreibweise.',
+'nouserspecified' => 'Bitte geben Sie einen Benutzernamen an.',
+'wrongpassword' => 'Das Passwort ist falsch (oder fehlt). Bitte versuchen Sie es erneut.',
+'wrongpasswordempty' => 'Das eingegebene Passwort war leer. Bitte versuchen Sie es erneut.',
+'mailmypassword' => 'Neues Passwort zusenden',
+'passwordremindertitle' => 'Neues Passwort für ein {{SITENAME}}-Benutzerkonto',
+'passwordremindertext' => 'Jemand mit der IP-Adresse $1, wahrscheinlich Sie selbst, hat ein neues Passwort für die Anmeldung bei {{SITENAME}} ($4) angefordert.
+
+Das automatisch generierte Passwort für Benutzer $2 lautet nun: $3
+
+Sie sollten sich jetzt anmelden und das Passwort ändern: {{fullurl:{{ns:special}}}}:Userlogin
+
+Bitte ignoriesen Sie diese E-Mail, falls Sie diese nicht selbst angefordert haben. Das alte Passwort bleibt weiterhin gültig.',
+'noemail' => 'Benutzer „$1“ hat keine E-Mail-Adresse angegeben.',
+'passwordsent' => 'Ein temporäres Passwort wurde an die E-Mail-Adresse von Benutzer „$1“ gesendet.
+Bitte melden Sie sich damit an, sobald Sie es erhalten.
+Das alte Passwort bleibt weiterhin gültig.',
+'blocked-mailpassword' => 'Die von Ihnen verwendete IP-Adresse ist für das Ändern von Seiten gesperrt. Um einen Missbrauch zu verhindern, wurde die Möglichkeit zur Anforderung eines neuen Passwortes ebenfalls gesperrt.',
+'eauthentsent' => 'Eine Bestätigungsmail wurde an die angegebene E-Mail-Adresse verschickt.
+
+Bevor eine E-Mail von anderen Benutzern über die {{SITENAME}}-Mailfunktion empfangen werden kann, muss die Adresse und ihre tatsächliche Zugehörigkeit zu diesem Benutzerkonto erst bestätigt werden. Bitte befolgen Sie die Hinweise in der Bestätigungsmail.',
+'throttled-mailpassword' => 'Es wurde innerhalb der letzten $1 Stunden bereits ein neues Passwort angefordert. Um einen Missbrauch der Funktion zu verhindern, kann nur alle $1 Stunden ein neues Passwort angefordert werden.',
+'mailerror' => 'Fehler beim Senden der E-Mail: $1',
+'acct_creation_throttle_hit' => 'Sie haben schon $1 Benutzerkonten und können jetzt keine weiteren mehr anlegen.',
+'emailauthenticated' => 'Ihre E-Mail-Adresse wurde bestätigt: $1.',
+'emailnotauthenticated' => 'Ihre E-Mail-Adresse ist noch nicht bestätigt. Es wird Ihnen keine E-Mail für eine der folgenden Funktionen zugesendet.',
+'noemailprefs' => 'Geben Sie eine E-Mail-Adresse an, damit die nachfolgenden Funktionen zur Verfügung stehen.',
+'emailconfirmlink' => 'E-Mail-Adresse bestätigen (authentifizieren).',
+'invalidemailaddress' => 'Die E-Mail-Adresse wurde nicht akzeptiert, da sie ein ungültiges Format aufzuweisen scheint. Bitte geben Sie eine Adresse in einem gültigen Format ein, oder leeren Sie das Feld.',
+'accountcreated' => 'Benutzerkonto erstellt',
+'accountcreatedtext' => 'Das Benutzerkonto $1 wurde eingerichtet.',
+
+# Password reset dialog
+'resetpass' => 'Passwort für Benutzerkonto zurücksetzen',
+'resetpass_announce' => 'Anmeldung mit dem per E-Mail zugesandten Code. Um die Anmeldung abzuschließen, müssen Sie jetzt ein neues Passwort wählen.',
+'resetpass_text' => '<!-- Add text here -->',
+'resetpass_header' => 'Passwort zurücksetzen',
+'resetpass_submit' => 'Passwort übermitteln und anmelden',
+'resetpass_success' => 'Ihr Passwort wurde erfolgreich geändert. Es folgt die Anmeldung…',
+'resetpass_bad_temporary' => 'Ungültiges vorläufiges Passwort. Sie haben bereits Ihr Passwort erfolgreich geändert oder ein neues, vorläufiges Passwort angefordert.',
+'resetpass_forbidden' => 'Das Passwort kann in {{SITENAME}} nicht geändert werden.',
+'resetpass_missing' => 'Leeres Formular.',
+
+# Edit page toolbar
+'bold_sample' => 'Fetter Text',
+'bold_tip' => 'Fetter Text',
+'italic_sample' => 'Kursiver Text',
+'italic_tip' => 'Kursiver Text',
+'link_sample' => 'Link-Text',
+'link_tip' => 'Interner Link',
+'extlink_sample' => 'http://www.beispiel.de Link-Text',
+'extlink_tip' => 'Externer Link (http:// beachten)',
+'headline_sample' => 'Ebene 2 Überschrift',
+'headline_tip' => 'Ebene 2 Überschrift',
+'math_sample' => 'Formel hier einfügen',
+'math_tip' => 'Mathematische Formel (LaTeX)',
+'nowiki_sample' => 'Unformatierten Text hier einfügen',
+'nowiki_tip' => 'Unformatierter Text',
+'image_sample' => 'Beispiel.jpg',
+'image_tip' => 'Bildverweis',
+'media_sample' => 'Beispiel.ogg',
+'media_tip' => 'Mediendatei-Verweis',
+'sig_tip' => 'Ihre Signatur mit Zeitstempel',
+'hr_tip' => 'Horizontale Linie (sparsam verwenden)',
+
+# Edit pages
+'summary' => 'Zusammenfassung',
+'subject' => 'Betreff',
+'minoredit' => 'Nur Kleinigkeiten wurden verändert',
+'watchthis' => 'Diese Seite beobachten',
+'savearticle' => 'Seite speichern',
+'preview' => 'Vorschau',
+'showpreview' => 'Vorschau zeigen',
+'showlivepreview' => 'Live-Vorschau',
+'showdiff' => 'Änderungen zeigen',
+'anoneditwarning' => 'Sie bearbeiten diese Seite ohne angemeldet zu sein. Statt eines Benutzernamens wird die IP-Adresse in der Versionsgeschichte aufgezeichnet.',
+'missingsummary' => "'''Hinweis:''' Sie haben keine Zusammenfassung angegeben. Wenn Sie erneut „Speichern“ klicken, wird Ihre Änderung ohne Zusammenfassung übernommen.",
+'missingcommenttext' => 'Bitte geben Sie eine Zusammenfassung ein.',
+'missingcommentheader' => "'''ACHTUNG:''' Sie haben keine Überschrift im Feld „Betreff:“ eingegeben. Wenn Sie erneut auf „Seite speichern“ klicken, wird Ihre Bearbeitung ohne Überschrift gespeichert.",
+'summary-preview' => 'Vorschau der Zusammenfassungszeile',
+'subject-preview' => 'Vorschau des Betreffs',
+'blockedtitle' => 'Benutzer ist blockiert',
+'blockedtext' => 'Ihr Benutzername oder Ihre IP-Adresse wurde von $1 blockiert.
+
+Folgender Grund wurde angegeben: $2
+
+Sie können $1 oder die [[{{ns:project}}:Administratoren]] kontaktieren, um über die Blockierung zu diskutieren.
+
+Bitte geben Sie Ihre IP-Adresse $3 und die Block-ID #$5 in allen Ihren Anfragen mit an.',
+'blockedoriginalsource' => "Der Quelltext von '''$1''' wird hier angezeigt:",
+'blockededitsource' => "Der Quelltext von '''Ihren Änderungen''' an '''$1''':",
+'whitelistedittitle' => 'Zum Bearbeiten ist es erforderlich, angemeldet zu sein',
+'whitelistedittext' => 'Sie müssen sich $1, um Seiten bearbeiten zu können.',
+'whitelistreadtitle' => 'Zum Lesen ist es erforderlich, angemeldet zu sein',
+'whitelistreadtext' => 'Sie müssen sich [[{{ns:special}}:Userlogin|hier anmelden]], um Seiten lesen zu können.',
+'whitelistacctitle' => 'Sie sind nicht berechtigt, ein Benutzerkonto anzulegen.',
+'whitelistacctext' => 'Um in {{SITENAME}} Benutzer anlegen zu dürfen, müssen Sie sich [[{{ns:special}}:Userlogin|hier anmelden]] und die nötigen Berechtigungen haben.',
+'confirmedittitle' => 'Zum Bearbeiten ist die E-Mail-Bestätigung erforderlich.',
+'confirmedittext' => 'Sie müssen Ihre E-Mail-Adresse erst bestätigen, bevor Sie bearbeiten können. Bitte ergänzen und bestätigen Sie Ihre E-Mail-Adresse in den [[{{ns:special}}:Preferences|Einstellungen]].',
+'loginreqtitle' => 'Anmeldung erforderlich',
+'loginreqlink' => 'anmelden',
+'loginreqpagetext' => 'Sie müssen sich $1, um Seiten lesen zu können.',
+'accmailtitle' => 'Passwort wurde verschickt.',
+'accmailtext' => 'Das Passwort von $1 wurde an $2 geschickt.',
+'newarticle' => '(Neu)',
+'newarticletext' => 'Hier den Text der neuen Seite eintragen. Bitte nur in ganzen Sätzen schreiben und keine urheberrechtsgeschützten Texte anderer kopieren.',
+'anontalkpagetext' => "---- ''Diese Seite dient dazu, einem nicht angemeldeten Benutzer Nachrichten zu hinterlassen. Wenn Sie mit den Kommentaren auf dieser Seite nichts anfangen können, richten sie sich vermutlich an einen früheren Inhaber Ihrer IP-Adresse und Sie können sie ignorieren. Wenn Sie ein anonymer Benutzer sind und denken, dass irrelevante Kommentare an Sie gerichtet wurden, [[{{ns:special}}:Userlogin|melden Sie sich bitte an]], um zukünftige Verwirrung zu vermeiden. ''",
+'noarticletext' => '(Diese Seite enthält momentan noch keinen Text)',
+'clearyourcache' => "'''Hinweis:''' Nach dem Speichern muss der Browserchache geleert werden, um die Änderungen zu sehen:<br />
+'''Mozilla/Firefox:''' ''Strg-Shift-R'', '''Internet Explorer:''' ''Strg-F5'', '''Opera:''' ''F5'', '''Safari:''' ''Cmd-Shift-R'', '''Konqueror:''' ''F5''.",
+'usercssjsyoucanpreview' => '<strong>Tipp:</strong> Benutzen Sie den Vorschau-Button, um Ihr neues css/js vor dem Speichern zu testen.',
+'usercsspreview' => "== Vorschau Ihres Benutzer-CSS ==
+'''Beachten Sie:''' Nach dem Speichern müssen Sie Ihren Browser anweisen, die neue Version zu laden: '''Mozilla/Firefox:''' ''Strg-Shift-R'', '''Internet Explorer:''' ''Strg-F5'', '''Opera:''' ''F5'', '''Safari:''' ''Cmd-Shift-R'', '''Konqueror:''' ''F5''.",
+'userjspreview' => "== Vorschau Ihres Benutzer-JavaScript ==
+'''Beachten Sie:''' Nach dem Speichern müssen Sie Ihren Browser anweisen, die neue Version zu laden: '''Mozilla/Firefox:''' ''Strg-Shift-R'', '''Internet Explorer:''' ''Strg-F5'', '''Opera:''' ''F5'', '''Safari:''' ''Cmd-Shift-R'', '''Konqueror:''' ''F5''.",
+'userinvalidcssjstitle' => "'''Warnung:''' Es existiert kein Skin „$1“. Bitte bedenken Sie, dass benutzerspezifische .css- und .js-Seiten mit einem Kleinbuchstaben anfangen müssen, also z.B. ''Benutzer:Mustermann/monobook.css'' an Stelle von ''Benutzer:Mustermann/Monobook.css''.",
+'updated' => '(Geändert)',
+'note' => '<strong>Hinweis:</strong>',
+'previewnote' => 'Dies ist nur eine Vorschau, die Seite wurde noch nicht gespeichert!',
+'previewconflict' => 'Diese Vorschau gibt den Inhalt des oberen Textfeldes wieder; so wird die Seite aussehen, wenn Sie jetzt speichern.',
+'session_fail_preview' => '<strong>Ihre Bearbeitung konnte nicht gespeichert werden, da Ihre Sitzungsdaten verloren gegangen sind.
+Bitte versuchen Sie es erneut. Sollte das Problem bestehen bleiben, loggen Sie sich kurz aus und wieder ein.</strong>',
+'session_fail_preview_html' => "<strong>Ihre Bearbeitung konnte nicht gespeichert werden, da Ihre Sitzungsdaten verloren gegangen sind.</strong>
+
+''Da in diesem Wiki reines HTML aktiviert ist, wurde die Vorschau ausgeblendet um JavaScript Attacken vorzubeugen.''
+
+<strong>Bitte versuchen Sie es erneut. Sollte das Problem bestehen bleiben, melden Sie sich kurz ab und wieder an.</strong>",
+'importing' => 'importiere $1',
+'editing' => 'Bearbeiten von $1',
+'editinguser' => 'Bearbeiten von Benutzer <b>$1</b>',
+'editingsection' => 'Bearbeiten von $1 (Absatz)',
+'editingcomment' => 'Bearbeiten von $1 (Kommentar)',
+'editconflict' => 'Bearbeitungskonflikt: $1',
+'explainconflict' => 'Jemand anders hat diese Seite geändert, nachdem Sie angefangen haben diese zu bearbeiten.
+Das obere Textfeld enthält den aktuellen Stand.
+Das untere Textfeld enthält Ihre Änderungen.
+Bitte fügen Sie Ihre Änderungen in das obere Textfeld ein.
+<b>Nur</b> der Inhalt des oberen Textfeldes wird gespeichert, wenn Sie auf „Speichern“ klicken!<br />',
+'yourtext' => 'Ihr Text',
+'storedversion' => 'Gespeicherte Version',
+'nonunicodebrowser' => '<strong>Achtung:</strong> Ihr Browser kann Unicode-Zeichen nicht richtig verarbeiten. Bitte verwenden Sie einen anderen Browser um Seiten zu bearbeiten.',
+'editingold' => '<strong>ACHTUNG: Sie bearbeiten eine alte Version dieser Seite.
+Wenn Sie speichern, werden alle neueren Versionen überschrieben.</strong>',
+'yourdiff' => 'Unterschiede',
+'copyrightwarning' => '<strong>Bitte <big>kopieren Sie keine Webseiten</big>, die nicht Ihre eigenen sind, benutzen Sie <big>keine urheberrechtlich geschützten Werke</big> ohne Erlaubnis des Copyright-Inhabers!</strong><br />
+Sie geben uns hiermit Ihre Zusage, dass Sie den Text <strong>selbst verfasst</strong> haben, dass der Text Allgemeingut (<strong>public domain</strong>) ist, oder dass der <strong>Copyright-Inhaber</strong> seine <strong>Zustimmung</strong> gegeben hat. Falls dieser Text bereits woanders veröffentlicht wurde, weisen Sie bitte auf der Diskussionsseite darauf hin.
+<i>Bitte beachten Sie, dass alle {{SITENAME}}-Beiträge automatisch unter der „$2“ stehen (siehe $1 für Details). Falls Sie nicht möchten, dass Ihre Arbeit hier von anderen verändert und verbreitet wird, dann drücken Sie nicht auf „Speichern“.</i>',
+'copyrightwarning2' => 'Bitte beachten Sie, dass alle Beiträge zu {{SITENAME}} von anderen Mitwirkenden bearbeitet, geändert oder gelöscht werden können.
+Reichen Sie hier keine Texte ein, falls Sie nicht wollen dass diese ohne Einschränkung geändert werden können.
+
+Sie bestätigen hiermit auch, dass Sie diese Texte selbst geschrieben haben oder diese von einer gemeinfreien Quelle kopiert haben
+(siehe $1 für weitere Details). <strong>ÜBERTRAGEN SIE OHNE GENEHMIGUNG KEINE URHEBERRECHTLICH GESCHÜTZEN INHALTE!</strong>',
+'longpagewarning' => '<strong>WARNUNG: Diese Seite ist $1 kB groß; einige Browser könnten Probleme haben, Seiten zu bearbeiten, die größer als 32 kB sind.
+Überlegen Sie bitte, ob eine Aufteilung der Seite in kleinere Abschnitte möglich ist.</strong>',
+'longpageerror' => '<strong>FEHLER: Der Text, den Sie zu speichern versuchen, ist $1 kB groß. Das ist größer als das erlaubte Maximum von $2 kB. Speicherung nicht möglich.</strong>',
+'readonlywarning' => '<strong>WARNUNG: Die Datenbank wurde während dem Ändern der
+Seite für Wartungsarbeiten gesperrt, so dass Sie die Seite im Moment nicht
+speichern können. Sichern Sie sich den Text und versuchen Sie die Änderungen
+später einzuspielen.</strong>',
+'protectedpagewarning' => "'''ACHTUNG: Diese Seite wurde gesperrt, so dass sie nur durch Benutzer mit Admninistratorrechten bearbeitet werden kann.'''",
+'semiprotectedpagewarning' => "'''Halbsperrung:''' Die Seite wurde so gesperrt, dass nur registrierte Benutzer diese ändern können.",
+'templatesused' => 'Folgende Vorlagen werden von dieser Seite verwendet:',
+'templatesusedpreview' => 'Folgende Vorlagen werden von dieser Artikelvorschau verwendet:',
+'templatesusedsection' => 'Folgende Vorlagen werden von diesem Abschnitt verwendet:',
+'template-protected' => '(gesperrt)',
+'template-semiprotected' => '(halbgesperrt)',
+'edittools' => '<!-- Dieser Text wird unter dem „Bearbeiten“-Formular sowie dem "Hochladen"-Formular angezeigt. -->',
+'nocreatetitle' => 'Die Erstellung neuer Seiten ist eingeschränkt.',
+'nocreatetext' => 'Der Server hat das Erstellen neuer Seiten eingeschränkt. Sie können bestehende Seiten ändern oder sich [[{{ns:special}}:Userlogin|anmelden]].',
+
+# "Undo" feature
+'undo-success' => 'Die Bearbeitung konnte erfolgreich entfernt werden. Bitte die Änderung in der Vergleichsansicht kontrollieren und dann auf auf „Seite speichern“ klicken, um die Änderung zu speichern.',
+'undo-failure' => '<span class="error">Die Bearbeitung konnte nicht entfernt werden, da der betroffene Abschnitt zwischenzeitlich verändert wurde.</span>',
+'undo-summary' => 'Version $1 von [[{{ns:special}}:Contributions/$2|$2]] ({{ns:user_talk}}:$2]]) wurde entfernt.',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'Benutzerkonto kann nicht erstellt werden.',
+'cantcreateaccounttext' => 'Die Erstellung eines Benutzerkontos von der IP-Adresse <b>$1</b> wurde gesperrt.
+Dies geschah vermutlich auf Grund von wiederholtem Vandalismus von Besuchern der Bildungseinrichtung oder anderen Benutzern des Internet-Service-Providers.',
+
+# History pages
+'revhistory' => 'Frühere Versionen',
+'viewpagelogs' => 'Logbücher für diese Seite anzeigen',
+'nohistory' => 'Es gibt keine früheren Versionen dieser Seite.',
+'revnotfound' => 'Diese Version wurde nicht gefunden.',
+'revnotfoundtext' => 'Die Version dieser Seite, nach der Sie suchen, konnte nicht gefunden werden. Bitte überprüfen Sie die URL dieser Seite.',
+'loadhist' => 'Lade Liste mit früheren Versionen',
+'currentrev' => 'Aktuelle Version',
+'revisionasof' => 'Version vom $1',
+'revision-info' => 'Version vom $1 von $2',
+'previousrevision' => '← Nächstältere Version',
+'nextrevision' => 'Nächstjüngere Version →',
+'currentrevisionlink' => 'Aktuelle Version',
+'cur' => 'Aktuell',
+'next' => 'Nächste',
+'last' => 'Vorherige',
+'orig' => 'Original',
+'histlegend' => 'Zur Anzeige der Änderungen einfach die zu vergleichenden Versionen auswählen und die Schaltfläche „{{int:compareselectedversions}}“ klicken.<br />
+* (Aktuell) = Unterschied zur aktuellen Version, (Vorherige) = Unterschied zur vorherigen Version
+* Uhrzeit/Datum = Version zu dieser Zeit, Benutzername/IP-Adresse des Bearbeiters, K = Kleine Änderung',
+'deletedrev' => '[gelöscht]',
+'histfirst' => 'Älteste',
+'histlast' => 'Neueste',
+'rev-deleted-comment' => '(Kommentar entfernt)',
+'rev-deleted-user' => '(Benutzername entfernt)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks"> Diese Version wurde gelöscht und ist nicht mehr öffentlich einsehbar.
+Nähere Angaben zum Löschvorgang sowie eine Begründung finden sich im [{{fullurl:Spezial:Log/delete|page={{PAGENAMEE}}}} Lösch-Logbuch].</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">Diese Version wurde gelöscht und ist nicht mehr öffentlich einsehbar.
+Als Administrator können Sie sie weiterhin einsehen.
+Nähere Angaben zum Löschvorgang sowie eine Begründung finden sich im [{{fullurl:Spezial:Log/delete|page={{PAGENAMEE}}}} Lösch-Logbuch].</div>',
+'rev-delundel' => 'zeige/verstecke',
+
+'history-feed-title' => 'Versionsgeschichte',
+'history-feed-description' => 'Versionsgeschichte für diese Seite in {{SITENAME}}',
+'history-feed-item-nocomment' => '$1 um $2', # user at time
+'history-feed-empty' => 'Die angeforderte Seite existiert nicht.
+Vielleicht wurde sie gelöscht oder verschoben.
+[[{{ns:special}}:Search|Durchsuchen]] Sie {{SITENAME}} für passende neue Seiten.',
+
+# Revision deletion
+'revisiondelete' => 'Versionen löschen/wiederherstellen',
+'revdelete-nooldid-title' => 'Keine Version angegeben',
+'revdelete-nooldid-text' => 'Sie haben keine Version angegeben, auf die diese Aktion ausgeführt werden soll.',
+'revdelete-selected' => 'Ausgewählte Version von [[:$1]]:',
+'revdelete-text' => 'Der Inhalt oder andere Bestandteile gelöschter Versionen sind nicht mehr öffentlich einsehbar, erscheinen jedoch weiterhin als Einträge in der Versionsgeschichte.
+
+Administroren können den entfernten Inhalt oder andere entfernte Bestandteile weiterhin einsehen und wiederherstellen, es sei denn, es wurde festgelegt, dass die Zugangsbeschränkungen auch für Administratoren gelten.',
+'revdelete-legend' => 'Einschränkungen für die Versionen festlegen:',
+'revdelete-hide-text' => 'Verstecke den Text der Version',
+'revdelete-hide-comment' => 'Bearbeitungskommentar verstecken',
+'revdelete-hide-user' => 'Verstecke den Benutzernamen/die IP des Bearbeiters.',
+'revdelete-hide-restricted' => 'Diese Einschränkungen gelten auch für Administratoren (nicht nur für „normale“ Benutzer).',
+'revdelete-log' => 'Kommentar/Begründung (erscheint im Logbuch):',
+'revdelete-submit' => 'Auf ausgewählte Version anwenden',
+'revdelete-logentry' => 'Versionszugang geändert für [[$1]]',
+
+# Diffs
+'difference' => '(Unterschied zwischen Versionen)',
+'loadingrev' => 'Lade Versionen zur Unterscheidung',
+'lineno' => 'Zeile $1:',
+'editcurrent' => 'Die aktuelle Version dieser Seite bearbeiten',
+'selectnewerversionfordiff' => 'Eine neuere Version zum Vergleich auswählen',
+'selectolderversionfordiff' => 'Eine ältere Version zum Vergleich auswählen',
+'compareselectedversions' => 'Gewählte Versionen vergleichen',
+'editundo' => 'Entfernen',
+'diff-multi' => '(Der Versionsvergleich bezieht {{plural:$1|eine dazwischen liegende Version|$1 dazwischen liegende Versionen}} mit ein.)',
+
+# Search results
+'searchresults' => 'Suchergebnisse',
+'searchresulttext' => 'Für mehr Informationen zur Suche siehe „[[{{ns:project}}:Suche|{{SITENAME}} durchsuchen]]“.',
+'searchsubtitle' => 'Für Ihre Suchanfrage „[[:$1]]“.',
+'searchsubtitleinvalid' => 'Für Ihre Suchanfrage „$1“.',
+'badquery' => 'Falsche Suchanfrage',
+'badquerytext' => 'Wir konnten Ihre Suchanfrage nicht verarbeiten.
+Vermutlich haben Sie versucht, ein Wort zu suchen, das kürzer als vier Buchstaben ist.
+Dies funktioniert im Moment noch nicht.
+Möglicherweise haben Sie auch die Anfrage falsch formuliert, z.B.
+„Lohn und und Steuern“.
+Bitte versuchen Sie eine anders formulierte Suchanfrage.',
+'matchtotals' => 'Die Suchanfrage „$1“ stimmt mit $2 Seitentiteln und dem Inhalt von $3 Seiten überein.',
+'noexactmatch' => "'''Es existiert keine Seite mit dem Titel „$1“.'''
+
+Versuchen Sie es über die Volltextsuche.
+Alternativ können Sie auch den [[{{ns:special}}:Allpages|alphabetischen Index]] nach ähnlichen Begriffen durchsuchen.
+
+Wenn Sie sich mit dem Thema auskennen, können Sie selbst die Seite „[[$1]]“ verfassen.",
+'titlematches' => 'Übereinstimmungen mit Seitentiteln',
+'notitlematches' => 'Keine Übereinstimmungen mit Seitentiteln',
+'textmatches' => 'Übereinstimmungen mit Inhalten',
+'notextmatches' => 'Keine Übereinstimmungen mit Inhalten',
+'prevn' => 'vorherige $1',
+'nextn' => 'nächste $1',
+'viewprevnext' => 'Zeige ($1) ($2) ($3).',
+'showingresults' => 'Hier sind <b>$1</b> Ergebnisse, beginnend mit Nummer <b>$2</b>.',
+'showingresultsnum' => 'Hier sind <b>$3</b> Ergebnisse, beginnend mit Nummer <b>$2</b>.',
+'nonefound' => '<strong>Hinweis</strong>: Erfolglose Suchanfragen werden häufig dadurch verursacht, dass mehr als ein Suchbegriff angegeben wurde. Nur Seiten die alle Suchbegriffe enthalten werden hier angezeigt. Versuchen Sie in diesem Fall die Anzahl der Suchbegriffe zu verringern.',
+'powersearch' => 'Suche',
+'powersearchtext' => 'Suche in Namensräumen:<br />$1<br />$2 Weiterleitungen anzeigen<br />Suche nach: $3 $9',
+'searchdisabled' => 'Die {{SITENAME}} Suche wurde deaktiviert. Sie können unterdessen über Google suchen. Bitte bedenken Sie, dass der Suchindex für {{SITENAME}} veraltet sein kann.',
+'blanknamespace' => '(Seiten)',
+
+# Preferences page
+'preferences' => 'Einstellungen',
+'preferences-summary' => 'Auf dieser Spezialseite können Sie Ihre Zugangsdaten ändern und bestimmte Teile der Oberfläche individuell anpassen ',
+'mypreferences' => 'Einstellungen',
+'prefsnologin' => 'Nicht angemeldet',
+'prefsnologintext' => 'Sie müssen [[{{ns:special}}:Userlogin|angemeldet]] sein, um Ihre Einstellungen ändern zu können.',
+'prefsreset' => 'Die Eingaben wurden verworfen, es erfolgte keine Speicherung.',
+'qbsettings' => 'Seitenleiste',
+'changepassword' => 'Passwort ändern',
+'skin' => 'Skin',
+'math' => 'TeX',
+'dateformat' => 'Datumsformat',
+'datedefault' => 'Standard',
+'datetime' => 'Datum und Zeit',
+'math_failure' => 'Parser-Fehler',
+'math_unknown_error' => 'Unbekannter Fehler',
+'math_unknown_function' => 'Unbekannte Funktion',
+'math_lexing_error' => "'Lexing'-Fehler",
+'math_syntax_error' => 'Syntaxfehler',
+'math_image_error' => 'die PNG-Konvertierung schlug fehl.',
+'math_bad_tmpdir' => 'Kann das Temporärverzeichnis für mathematische Formeln nicht anlegen oder beschreiben.',
+'math_bad_output' => 'Kann das Zielverzeichnis für mathematische Formeln nicht anlegen oder beschreiben.',
+'math_notexvc' => 'Das texvc-Programm kann nicht gefunden werden. Bitte beachten Sie math/README.',
+'prefs-personal' => 'Benutzerdaten',
+'prefs-rc' => 'Anzeige von „Letzte Änderungen“',
+'prefs-watchlist' => 'Beobachtungsliste',
+'prefs-watchlist-days' => 'Anzahl der Tage, die die Beobachtungsliste standardmäßig umfassen soll:',
+'prefs-watchlist-edits' => 'Anzahl der Einträge in der erweiterten Beobachtungsliste:',
+'prefs-misc' => 'Verschiedenes',
+'saveprefs' => 'Einstellungen speichern',
+'resetprefs' => 'Eingaben verwerfen',
+'oldpassword' => 'Altes Passwort:',
+'newpassword' => 'Neues Passwort:',
+'retypenew' => 'Neues Passwort (nochmal):',
+'textboxsize' => 'Bearbeiten',
+'rows' => 'Zeilen',
+'columns' => 'Spalten',
+'searchresultshead' => 'Suche',
+'resultsperpage' => 'Treffer pro Seite:',
+'contextlines' => 'Zeilen pro Treffer:',
+'contextchars' => 'Zeichen pro Zeile:',
+'stubthreshold' => 'Kleine Seiten markieren bis (Byte):',
+'recentchangescount' => 'Anzahl der Einträge in „Letzte Änderungen“ und „Neue Artikel“:',
+'savedprefs' => 'Ihre Einstellungen wurden gespeichert.',
+'timezonelegend' => 'Zeitzone',
+'timezonetext' => 'Geben Sie die Anzahl der Stunden ein, die zwischen Ihrer Zeitzone und UTC liegen.',
+'localtime' => 'Ortszeit:',
+'timezoneoffset' => 'Unterschied¹:',
+'servertime' => 'Aktuelle Zeit auf dem Server:',
+'guesstimezone' => 'Vom Browser übernehmen',
+'allowemail' => 'E-Mail-Empfang von anderen Benutzern ermöglichen.',
+'defaultns' => 'In diesen Namensräumen soll standardmäßig gesucht werden:',
+'default' => 'Voreinstellung',
+'files' => 'Dateien',
+
+# User rights
+'userrights-lookup-user' => 'Verwalte Gruppenzugehörigkeit ',
+'userrights-user-editname' => 'Benutzername:',
+'editusergroup' => 'Benutzerrechte bearbeiten',
+'userrights-editusergroup' => 'Bearbeite Gruppenzugehörigkeit des Benutzers',
+'saveusergroups' => 'Gruppenzugehörigkeiten speichern',
+'userrights-groupsmember' => 'Mitglied von:',
+'userrights-groupsavailable' => 'Verfügbare Gruppen:',
+'userrights-groupshelp' => "Wählen Sie die Gruppen, aus denen der Benutzer entfernt oder zu denen er hinzugefügt werden soll.
+Nicht selektierte Gruppen werden nicht geändert. Eine Selektion kann mit '''Strg + Linksklick''' (bzw. Ctrl + Linksklick) entfernt werden.",
+
+# Groups
+'group' => 'Gruppe:',
+'group-bot' => 'Bots',
+'group-sysop' => 'Administratoren',
+'group-bureaucrat' => 'Bürokraten',
+'group-all' => '(alle)',
+
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Administrator',
+'group-bureaucrat-member' => 'Bürokrat',
+
+'grouppage-bot' => '{{ns:project}}:Bots',
+'grouppage-sysop' => '{{ns:project}}:Administratoren',
+'grouppage-bureaucrat' => '{{ns:project}}:Bürokraten',
+
+# Recent changes
+'changes' => 'Änderungen',
+'recentchanges' => 'Letzte Änderungen',
+'recentchangestext' => "Auf dieser Seite können Sie die letzten Änderungen auf '''{{SITENAME}}''' nachverfolgen.",
+'recentchanges-feed-description' => 'Verfolge mit diesem Feed die letzten Änderungen in {{SITENAME}}.',
+'rcnote' => "Angezeigt werden die letzten <b>$1</b> Änderungen der letzten <b>$2</b> Tage. Stand: $3. (<b><tt>Neu</tt></b>&nbsp;– neuer Eintrag; <b><tt>K</tt></b>&nbsp;– kleine Änderung; <b><tt>B</tt></b>&nbsp;– Änderung durch einen Bot; ''(± Zahl)''&nbsp;– Größenänderung in Byte)",
+'rcnotefrom' => 'Angezeigt werden die Änderungen seit <b>$2</b> (max. <b>$1</b> Einträge).',
+'rclistfrom' => 'Nur Änderungen seit $1 zeigen.',
+'rcshowhideminor' => 'Kleine Änderungen $1',
+'rcshowhidebots' => 'Bots $1',
+'rcshowhideliu' => 'Angemeldete Benutzer $1',
+'rcshowhideanons' => 'Anonyme Benutzer $1',
+'rcshowhidepatr' => 'Überprüfte Änderungen $1',
+'rcshowhidemine' => 'Eigene Beiträge $1',
+'rclinks' => 'Zeige die letzten $1 Änderungen der letzten $2 Tage.<br />$3',
+'diff' => 'Unterschied',
+'hist' => 'Versionen',
+'hide' => 'ausblenden',
+'show' => 'einblenden',
+'minoreditletter' => 'K',
+'newpageletter' => 'N',
+'boteditletter' => 'B',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 beobachtende/r Benutzer]',
+'rc_categories' => 'Nur Kategorien (getrennt mit „|“):',
+'rc_categories_any' => 'Alle',
+'rc-change-size' => '$1',
+
+# Upload
+'upload' => 'Hochladen',
+'uploadbtn' => 'Datei hochladen',
+'reupload' => 'Abbrechen',
+'reuploaddesc' => 'Zurück zur Hochladen-Seite.',
+'uploadnologin' => 'Nicht angemeldet',
+'uploadnologintext' => 'Sie müssen [[{{ns:special}}:Userlogin|angemeldet sein]], um Dateien hochladen zu können.',
+'upload_directory_read_only' => 'Der Webserver hat keine Schreibrechte für das Upload-Verzeichnis ($1).',
+'uploaderror' => 'Fehler beim Hochladen',
+'uploadtext' => "Gehen Sie zu der [[{{ns:special}}:Imagelist|Liste hochgeladener Dateien]], um vorhandene Dateien zu suchen und anzuzeigen.
+
+Benutzen Sie dieses Formular, um neue Dateien hochzuladen. Klicken Sie auf '''„Durchsuchen...“''', um einen Dateiauswahl-Dialog zu öffnen.
+Nach der Auswahl einer Datei wird der Dateiname im Textfeld '''„Quelldatei“''' angezeigt.
+Bestätigen Sie dann die Copyright-Vereinbarung und klicken anschließend auf '''„Datei hochladen“'''.
+Dies kann eine Weile dauern, besonders bei einer langsamen Internet-Verbindung.
+
+Um ein '''Bild''' in einer Seite zu verwenden, schreiben Sie an Stelle des Bildes zum Beispiel:
+* '''<tt><nowiki>[[{{ns:image}}:Datei.jpg]]</nowiki></tt>'''
+* '''<tt><nowiki>[[{{ns:image}}:Datei.jpg|Link-Text]]</nowiki></tt>'''
+
+Um '''Mediendateien''' einzubinden, verwenden Sie zum Beispiel:
+* '''<tt><nowiki>[[{{ns:media}}:Datei.ogg]]</nowiki></tt>'''
+* '''<tt><nowiki>[[{{ns:media}}:Datei.ogg|Link-Text]]</nowiki></tt>'''
+
+Bitte beachten Sie, dass, genau wie bei normalen Seiteninhalten, andere Benutzer Ihre Dateien löschen oder verändern können.",
+'uploadlog' => 'Datei-Logbuch',
+'uploadlogpage' => 'Datei-Logbuch',
+'uploadlogpagetext' => 'Hier ist die Liste der letzten hochgeladenen Dateien, siehe auch [[{{ns:spezial}}:Newimages]].',
+'filename' => 'Dateiname',
+'filedesc' => 'Beschreibung',
+'fileuploadsummary' => 'Beschreibung/Quelle:',
+'filestatus' => 'Copyright-Status',
+'filesource' => 'Quelle',
+'copyrightpage' => '{{ns:project}}:Urheberrecht',
+'copyrightpagename' => '{{SITENAME}} Urheberrecht',
+'uploadedfiles' => 'Hochgeladene Dateien',
+'ignorewarning' => 'Warnung ignorieren und Datei speichern.',
+'ignorewarnings' => 'Warnungen ignorieren',
+'minlength' => 'Dateinamen müssen mindestens drei Buchstaben lang sein.',
+'illegalfilename' => 'Der Dateiname „$1“ enthält mindestens ein nicht erlaubtes Zeichen. Bitte benennen Sie die Datei um und versuchen Sie diese erneut hochzuladen.',
+'badfilename' => 'Der Dateiname wurde in „$1“ geändert.',
+'badfiletype' => '„.$1“ ist kein empfohlenes Dateiformat.',
+'large-file' => 'Die Dateigröße sollte nach Möglichkeit $1 nicht überschreiten. Diese Datei ist $2 groß.',
+'largefileserver' => 'Die Datei ist größer als die vom Server eingestellte Maximalgröße.',
+'emptyfile' => 'Die hochgeladene Datei ist leer. Der Grund kann ein Tippfehler im Dateinamen sein. Bitte kontrollieren Sie, ob Sie die Datei wirklich hochladen wollen.',
+'fileexists' => 'Eine Datei mit diesem Namen existiert bereits. Wenn Sie auf „Datei speichern“ klicken, wird die Datei überschrieben. Bitte prüfen Sie $1, wenn Sie sich nicht sicher sind.',
+'fileexists-forbidden' => 'Mit diesem Namen existiert bereits eine Datei. Bitte gehen Sie zurück und laden Ihre Datei unter einem anderen Namen hoch. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Mit diesem Namen existiert bereits eine Datei. Bitte gehen Sie zurück und laden Sie diese Datei unter einem anderen Namen hoch. [[{{ns:image}:$1|thumb|center|$1]]',
+'successfulupload' => 'Erfolgreich hochgeladen',
+'fileuploaded' => 'Die Datei „$1“ wurde erfolgreich hochgeladen. Bitte folgen Sie dem Link $2 zur Beschreibungsseite und geben Sie weitere Informationen zur Datei an.
+
+Falls es sich um ein Bild gehandelt hat, so können Sie mit <tt><nowiki>[[{{ns:image}}:$1|thumb|Description]]</nowiki></tt> ein Vorschaubild auf der Seite erzeugen lassen.',
+'uploadwarning' => 'Warnung',
+'savefile' => 'Datei speichern',
+'uploadedimage' => 'hat [[$1]] hochgeladen',
+'uploaddisabled' => 'Entschuldigung, das Hochladen ist deaktiviert.',
+'uploaddisabledtext' => 'Das Hochladen von Dateien ist in {{SITENAME}} deaktiviert.',
+'uploadscripted' => 'Diese Datei enthält HTML- oder Scriptcode, der irrtümlich von einem Webbrowser ausgeführt werden könnte.',
+'uploadcorrupt' => 'Die Datei ist beschädigt oder hat einen falschen Namen. Bitte überprüfen Sie die Datei und laden Sie sie erneut hoch.',
+'uploadvirus' => 'Diese Datei enthält einen Virus! Details: $1',
+'sourcefilename' => 'Quelldatei',
+'destfilename' => 'Dateiname ändern',
+'watchthisupload' => 'Diese Seite beobachten',
+'filewasdeleted' => 'Eine Datei mit diesem Namen wurde schon einmal hochgeladen und zwischenzeitlich wieder gelöscht. Bitte prüfen Sie zuerst den Eintrag im $1, bevor Sie die Datei wirklich speichern.',
+
+'upload-proto-error' => 'Falsches Protokoll',
+'upload-proto-error-text' => 'Die URL muss mit <code>http://</code> oder <code>ftp://</code> beginnen.',
+'upload-file-error' => 'Interner Fehler',
+'upload-file-error-text' => 'Bei der Erstellung einer temporären Datei auf dem Server ist ein interner Fehler aufgetreten. Bitte informieren Sie einen System-Administrator.',
+'upload-misc-error' => 'Unbekannter Fehler beim Hochladen',
+'upload-misc-error-text' => 'Beim Hochladen ist ein unbekannter Fehler aufgetreten. Prüfen Sie die URL auf Fehler, den Online-Status der Seite und versuchen Sie es erneut. Wenn das Problem weiterbesteht, informieren Sie einen System-Administrator.',
+
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => 'URL ist nicht erreichbar',
+'upload-curl-error6-text' => 'Die angegebene URL ist nicht erreichbar. Prüfen Sie sowohl die URL auf Fehler als auch den Online-Status der Seite.',
+'upload-curl-error28' => 'Zeitüberschreitung beim Hochladen',
+'upload-curl-error28-text' => 'Die Seite braucht zu lange für eine Antwort. Prüfen Sie, ob die Seite online ist, warten Sie einen kurzen Moment und versuchen Sie es dann erneut. Es kann sinnvoll sein, einen erneuten Versuch zu einer anderen Zeit zu probieren..',
+
+'license' => 'Lizenz',
+'nolicense' => 'keine Vorauswahl',
+'upload_source_url' => ' (gültige, öffentlich zugängliche URL)',
+'upload_source_file' => ' (eine Datei auf Ihrem Computer)',
+
+# Image list
+'imagelist' => 'Dateiliste',
+'imagelist-summary' => 'Diese Spezialseite listet alle hochgeladenen Dateien auf. Standardmäßig werden die zuletzt hochgeladenen Dateien zuerst angezeigt. Durch einen Klick auf die Spaltenüberschriften kann die Sortierung umgedreht werden oder es kann nach einer anderen Spalte sortiert werden.',
+'imagelisttext' => "Hier ist eine Liste von '''$1''' {{PLURAL:$1|Datei|Dateien}}, sortiert $2.",
+'imagelistforuser' => 'Diese Seite zeigt nur Dateien, die von $1 hochgeladen wurden.',
+'getimagelist' => 'Lade Dateiliste',
+'ilsubmit' => 'Suche',
+'showlast' => 'Zeige die letzten $1 Dateien, sortiert nach $2.',
+'byname' => 'nach Name',
+'bydate' => 'nach Datum',
+'bysize' => 'nach Größe',
+'imgdelete' => 'Löschen',
+'imgdesc' => 'Beschreibung',
+'imgfile' => 'Datei',
+'imglegend' => 'Legende: (Beschreibung) = Zeige/Bearbeite Dateibeschreibung.',
+'imghistory' => 'Dateiversionen',
+'revertimg' => 'Zurücksetzen',
+'deleteimg' => 'Löschen',
+'deleteimgcompletely' => 'Alle Versionen dieser Datei löschen',
+'imghistlegend' => 'Legende: (Aktuell) = Dies ist die aktuelle Datei, (Löschen) = lösche diese alte Version, (Zurücksetzen) = verwende wieder diese alte Version.',
+'imagelinks' => 'Dateiverweise',
+'linkstoimage' => 'Die folgenden Seiten benutzen diese Datei:',
+'nolinkstoimage' => 'Keine Seite benutzt diese Datei.',
+'sharedupload' => 'Diese Datei ist ein gemeinsam genutzter Upload und kann von anderen Projekten verwendet werden.',
+'shareduploadwiki' => 'Für weitere Informationen siehe $1.',
+'shareduploadwiki-linktext' => 'Datei-Beschreibungsseite',
+'noimage' => 'Eine Datei mit diesem Namen existiert nicht, Sie können sie jedoch $1.',
+'noimage-linktext' => 'hochladen',
+'uploadnewversion-linktext' => 'Eine neue Version dieser Datei hochladen',
+'imagelist_date' => 'Datum',
+'imagelist_name' => 'Name',
+'imagelist_user' => 'Benutzer',
+'imagelist_size' => 'Größe (Byte)',
+'imagelist_description' => 'Beschreibung',
+'imagelist_search_for' => 'Suche nach Datei:',
+
+# MIME search
+'mimesearch' => 'Suche nach MIME-Typ',
+'mimetype' => 'MIME-Typ:',
+'download' => 'Herunterladen',
+
+# Unwatched pages
+'unwatchedpages' => 'Nicht beobachtete Seiten',
+'unwatchedpages-summary' => 'Diese Spezialseite zeigt alle Seiten, die von keinem Benutzer auf einer Beobachtungsliste stehen.',
+
+# List redirects
+'listredirects' => 'Weiterleitungsliste',
+'listredirects-summary' => 'Diese Spezialseite listet Weiterleitungen auf.',
+
+# Unused templates
+'unusedtemplates' => 'Nicht benutzte Vorlagen',
+'unusedtemplates-summary' => 'Diese Seite listet alle Vorlagen auf, die nicht in anderen Seiten eingebunden sind. Überprüfen Sie andere Links zu den Vorlagen, bevor Sie diese löschen.',
+'unusedtemplatestext' => '',
+'unusedtemplateswlh' => 'Andere Verweise',
+
+# Random redirect
+'randomredirect' => 'Zufällige Weiterleitung',
+
+# Statistics
+'statistics' => 'Statistik',
+'sitestats' => 'Seitenstatistik',
+'userstats' => 'Benutzerstatistik',
+'sitestatstext' => "Es gibt insgesamt '''$1''' Seiten in der Datenbank.
+Das schliesst Diskussionsseiten, Seiten über {{SITENAME}}, kleine Seiten, Weiterleitungen und andere Seiten ein,
+die eventuell nicht als Seiten gewertet werden können.
+
+Diese ausgenommen gibt es '''$2''' Seiten, die als Seite gewertet werden können.
+
+Insgesamt wurden '''$8''' Dateien hochgeladen.
+
+Insgesamt gab es '''$3''' Seitenabrufe und '''$4''' Seitenbearbeitungen seit dieses Wiki eingerichtet wurde.
+Daraus ergeben sich '''$5''' Bearbeitungen pro Seite und '''$6''' Seitenabrufe pro Bearbeitung.
+
+Länge der „Job queue“: '''$7'''",
+'userstatstext' => "Es gibt '''$1''' registrierte [[{{ns:special}}:Listusers|Benutzer]].
+Davon haben '''$2''' (=$4%) $5-Rechte.",
+'statistics-mostpopular' => 'Meist besuchte Seiten',
+
+'disambiguations' => 'Begriffsklärungsseiten',
+'disambiguations-summary' => '',
+'disambiguationspage' => '{{ns:project}}:Begriffsklärung',
+'disambiguationstext' => 'Die folgenden Seiten verweisen auf eine <i>Seite zur Begriffsklärung</i>. Sie sollten statt dessen auf die eigentlich gemeinte Seite verweisen.<br />Eine Seite wird als Begriffsklärungsseite behandelt, wenn $1 auf sie verweist.<br />Verweise aus Namensräumen werden hier <i>nicht</i> aufgelistet.',
+
+'doubleredirects' => 'Doppelte Weiterleitungen',
+'doubleredirects-summary' => '<b>Achtung:</b> Diese Liste kann „falsche Positive“ enthalten. Das ist dann der Fall, wenn eine Weiterleitung außer dem Weiterleitungs-Verweis noch weiteren Text mit anderen Verweisen enthält. Letztere sollten dann entfernt werden.',
+'doubleredirectstext' => '',
+
+'brokenredirects' => 'Kaputte Weiterleitungen',
+'brokenredirects-summary' => 'Diese Spezialseite listet Weiterleitungen auf nicht existierende Artikel auf.',
+'brokenredirectstext' => '',
+
+# Miscellaneous special pages
+'nbytes' => '$1 {{PLURAL:$1|Byte|Bytes}}',
+'ncategories' => '$1 {{PLURAL:$1|Kategorie|Kategorien}}',
+'nlinks' => '{{PLURAL:$1|ein Verweis|$1 Verweise}}',
+'nmembers' => '{{PLURAL:$1|ein Eintrag|$1 Einträge}}',
+'nrevisions' => '{{PLURAL:$1|eine Bearbeitung|$1 Bearbeitungen}}',
+'nviews' => '{{PLURAL:$1|eine Abfrage|$1 Abfragen}}',
+'lonelypages' => 'Verwaiste Seiten',
+'lonelypages-summary' => 'Diese Spezialseite zeigt Seiten, auf die von keiner anderen Seite verlinkt wird. Diese verwaisten Seiten sind deshalb nicht erwünscht, oder eventuell fragwürdig, weil sie über die normale Navigation durch {{SITENAME}} nie aufgerufen werden können. ',
+'lonelypagestext' => '',
+'uncategorizedpages' => 'Nicht kategorisierte Seiten',
+'uncategorizedpages-summary' => 'Diese Spezialseite zeigt alle Seiten, die noch keiner Kategorie zugewiesen wurden.',
+'uncategorizedcategories' => 'Nicht kategorisierte Kategorien',
+'uncategorizedcategories-summary' => 'Diese Spezialseite zeigt alle Kategorien, die selbst noch keiner Kategorie zugewiesen wurden.',
+'uncategorizedimages' => 'Nicht kategorisierte Dateien',
+'uncategorizedimages-summary' => 'Diese Spezialseite zeigt alle Bilder, die keiner Kategorie zugewiesen wurden.',
+'unusedcategories' => 'Verwaiste Kategorien',
+'unusedimages' => 'Verwaiste Dateien',
+'popularpages' => 'Beliebte Seiten',
+'wantedcategories' => 'Benutzte, aber nicht angelegte Kategorien',
+'wantedcategories-summary' => 'Diese Spezialseite listet Kategorien auf, die zwar in Seiten verwendet werden, welche aber nicht als Kategorie angelegt worden sind.',
+'wantedpages' => 'Gewünschte Seiten',
+'wantedpages-summary' => 'Diese Spezialseite listet alle Seiten auf, die noch nicht existieren, auf die aber von bestehenden Seiten bereits verlinkt wird.',
+'mostlinked' => 'Häufig verlinkte Seiten',
+'mostlinked-summary' => 'Diese Spezialseite zeigt, unabhängig vom Namensraum, alle besonders häufig verlinkten Seiten an.',
+'mostlinkedcategories' => 'Meistbenutzte Kategorien',
+'mostlinkedcategories-summary' => 'Diese Spezialseite zeigt eine Liste der meistbenutzten Kategorien.',
+'mostcategories' => 'Meistkategorisierte Seiten',
+'mostcategories-summary' => 'Diese Spezialseite zeigt besonders häufig kategorisierte Seiten an.',
+'mostimages' => 'Meistbenutzte Dateien',
+'mostimages-summary' => 'Diese Spezialseite zeigt eine Liste der meistbenutzten Dateien.',
+'mostrevisions' => 'Seiten mit den meisten Versionen',
+'mostrevisions-summary' => 'Diese Spezialseite zeigt eine Liste von Seiten mit den meisten Bearbeitungen.',
+'allpages' => 'Alle Seiten',
+'allpages-summary' => "Diese Spezialseite listet den Seitenbestand von {{SITENAME}} von A bis Z auf. Sortiert wird alphabetisch, erst Zahlen, dann Großbuchstaben, Kleinbuchstaben und schließlich Sonderzeichen. ''A&nbsp;10'' findet sich vor ''AZ'', der ''Aal'' ist jedoch noch dahinter eingeordnet.",
+'prefixindex' => 'Alle Seiten (mit Präfix)',
+'prefixindex-summary' => 'Diese Spezialseite zeigt alle Seiten, die mit der eingegebenen Zeichenfolge („Präfix“) beginnen. Die Ausgabe kann auf einen Namensraum eingeschränkt werden.',
+'randompage' => 'Zufällige Seite',
+'shortpages' => 'Kurze Seiten',
+'shortpages-summary' => 'Diese Liste zeigt die kürzesten Seiten im Hauptnamensraum an. Gezählt werden die Zeichen des Textes wie er im Bearbeitungsfenster dargestellt wird, also in Wiki-Syntax und ohne die Inhalte eingebundener Vorlagen. Grundlage der Zählung ist der UTF-8-kodierte Text, nach dem beispielsweise deutsche Umlaute als zwei Zeichen gelten.',
+'longpages' => 'Lange Seiten',
+'longpages-summary' => 'Diese Liste zeigt die längsten Seiten im Hauptnamensraum an. Gezählt werden die Zeichen des Textes wie er im Bearbeitungsfenster dargestellt wird, also in Wiki-Syntax und ohne die Inhalte eingebundener Vorlagen. Grundlage der Zählung ist der UTF-8-kodierte Text, nach dem beispielsweise deutsche Umlaute als zwei Zeichen gelten.',
+'deadendpages' => 'Sackgassenseiten',
+'deadendpages-summary' => 'Diese Spezialseite zeigt eine Liste von Seiten, die keine Links auf andere Seiten oder nur Links auf noch nicht vorhandene Seiten enthalten.',
+'deadendpagestext' => '',
+'listusers' => 'Benutzerverzeichnis',
+'listusers-summary' => "Diese Spezialseite listet alle registrierten Benutzer auf; die Gesamtzahl kann [[Special:Statistics|hier]] eingesehen werden. Über das Auswahlfeld ''Gruppe'' lässt sich die Abfrage auf bestimmte Benutzergruppen einschränken.",
+'specialpages' => 'Spezialseiten',
+'specialpages-summary' => 'Diese Seite bietet einen Überblick aller Spezialseiten. Diese werden automatisch generiert und können nicht bearbeitet werden.',
+'spheading' => 'Spezialseiten für alle Benutzer',
+'restrictedpheading' => 'Spezialseiten für Administratoren',
+'recentchangeslinked' => 'Änderungen an verlinkten Seiten',
+'rclsub' => '(auf Seiten von „$1“)',
+'newpages' => 'Neue Seiten',
+'newpages-summary' => 'Diese Spezialseite listet alle neu erstellten Seiten der letzten 30 Tage auf. Die Ausgabe kann auf einen Namensraum und/oder Benutzernamen eingeschränkt werden.',
+'newpages-username' => 'Benutzername:',
+'ancientpages' => 'Seit längerem unbearbeitete Artikel',
+'ancientpages-summary' => 'Diese Spezialseite zeigt eine Liste von Seiten, die am längsten nicht mehr geändert worden sind.',
+'intl' => 'Interwiki-Links',
+'move' => 'verschieben',
+'movethispage' => 'Seite verschieben',
+'unusedimagestext' => '<p>Bitte beachten Sie, dass andere Wikis möglicherweise einige dieser Dateien verwenden.',
+'unusedcategoriestext' => 'Diese Spezialseite zeigt alle Kategorien, die selber keiner Kategorie zugewiesen wurden.',
+
+# Book sources
+'booksources' => 'ISBN-Suche',
+'booksources-summary' => 'Auf dieser Spezialseite können Sie eine ISBN eingeben und erhalten dann eine Liste mit Informations- und Bezugsmöglichkeiten zur gesuchten ISBN. Bindestriche oder Leerzeichen zwischen den Ziffern spielen für die Suche keine Rolle.',
+'booksources-search-legend' => 'Suche nach Bezugsquellen für Bücher',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => 'Suche',
+'booksources-text' => 'Dies ist eine Liste mit Links zu Internetseiten, die neue und gebrauchte Bücher verkaufen. Dort kann es auch weitere Informationen über die Bücher geben. Wikipedia ist mit keinem dieser Anbieter geschäftlich verbunden.',
+
+'categoriespagetext' => 'Die folgenden Kategorien existieren in {{SITENAME}}.',
+'data' => 'Daten',
+'userrights' => 'Benutzerrechteverwaltung',
+'groups' => 'Benutzergruppen',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 bis $2',
+'version' => 'Version',
+'log' => 'Logbücher',
+'alllogstext' => 'Kombinierte Anzeige der Datei-, Lösch-, Seitenschutz-, Benutzerblockaden- und Rechte-Logbücher.<br />Sie können die Anzeige durch die Auswahl des Logbuchtyps, des Benutzers oder des Seitentitels einschränken.',
+'logempty' => 'Keine passenden Einträge.',
+
+# Special:Allpages
+'nextpage' => 'Nächste Seite ($1)',
+'prevpage' => 'Vorherige Seite ($1)',
+'allpagesfrom' => 'Seiten anzeigen ab:',
+'allarticles' => 'Alle Seiten',
+'allinnamespace' => 'Alle Seiten (Namensraum: $1)',
+'allnotinnamespace' => 'Alle Seiten (nicht im $1 Namensraum)',
+'allpagesprev' => 'Vorherige',
+'allpagesnext' => 'Nächste',
+'allpagessubmit' => 'Anwenden',
+'allpagesprefix' => 'Seiten anzeigen mit Präfix:',
+'allpagesbadtitle' => 'Der eingegebene Seitenname ist ungültig: Er hat entweder ein vorangestelltes Sprach-, ein Interwiki-Kürzel oder enthält ein oder mehrere Zeichen, welche in Seitennamen nicht verwendet werden dürfen.',
+
+# Special:Listusers
+'listusersfrom' => 'Zeige Benutzer ab:',
+
+# E-mail user
+'mailnologin' => 'Sie sind nicht angemeldet.',
+'mailnologintext' => 'Sie müssen [[{{ns:special}}:Userlogin|angemeldet sein]] und eine gültige E-Mail-Adresse haben, um anderen Benutzern E-Mails schicken zu können.',
+'emailuser' => 'E-Mail an diesen Benutzer',
+'emailpage' => 'E-Mail an Benutzer',
+'emailpagetext' => 'Wenn dieser Benutzer eine gültige E-Mail-Adresse angegeben hat, können Sie ihm mit dem untenstehenden Formular eine E-Mail senden. Als Absender wird die E-Mail-Adresse aus Ihren Einstellungen eingetragen, damit der Benutzer Ihnen antworten kann.',
+'usermailererror' => 'Das E-Mail-Objekt gab einen Fehler zurück:',
+'defemailsubject' => '{{SITENAME}}-E-Mail',
+'noemailtitle' => 'Keine E-Mail-Adresse',
+'noemailtext' => 'Dieser Benutzer hat keine gültige E-Mail-Adresse angegeben oder möchte keine E-Mail von anderen Benutzern empfangen.',
+'emailfrom' => 'Von',
+'emailto' => 'An',
+'emailsubject' => 'Betreff',
+'emailmessage' => 'Nachricht',
+'emailsend' => 'Senden',
+'emailccme' => 'Sende eine Kopie der E-Mail an mich',
+'emailccsubject' => 'Kopie Ihrer Nachricht an $1: $2',
+'emailsent' => 'E-Mail verschickt',
+'emailsenttext' => 'Ihre E-Mail wurde verschickt.',
+
+# Watchlist
+'watchlist' => 'Beobachtungsliste',
+'watchlistfor' => "(für '''$1''')",
+'nowatchlist' => 'Sie haben keine Einträge auf Ihrer Beobachtungsliste.',
+'watchlistanontext' => 'Sie müssen sich $1, um Ihre Beobachtungsliste zu sehen oder Einträge auf ihr zu bearbeiten.',
+'watchlistcount' => "'''Sie haben {{PLURAL:$1|einen Eintrag|$1 Einträge}} auf Ihrer Beobachtungsliste (inkl. Diskussionsseiten).'''",
+'clearwatchlist' => 'Beobachtungsliste löschen',
+'watchlistcleartext' => 'Sind Sie sicher, dass Sie diese vollständig löschen wollen?',
+'watchlistclearbutton' => 'Beobachtungsliste löschen',
+'watchlistcleardone' => 'Ihre Beobachtungsliste wurde gelöscht. {{PLURAL:$1|Ein Eintrag wurde|$1 Einträge wurden}} entfernt.',
+'watchnologin' => 'Sie sind nicht angemeldet',
+'watchnologintext' => 'Sie müssen [[{{ns:special}}:Userlogin|angemeldet]]
+sein, um Ihre Beobachtungsliste zu bearbeiten.',
+'addedwatch' => 'Zur Beobachtungsliste hinzugefügt',
+'addedwatchtext' => 'Die Seite „$1“ wurde zu Ihrer [[{{ns:special}}:Watchlist|Beobachtungsliste]] hinzugefügt.
+
+Spätere Änderungen an dieser Seite und der dazugehörigen Diskussionsseite werden dort gelistet und
+in der Übersicht der [[{{ns:special}}:Recentchanges|letzten Änderungen]] in Fettschrift dargestellt.
+
+Wenn Sie die Seite wieder von Ihrer Beobachtungsliste entfernen möchten, klicken Sie auf der jeweiligen Seite auf „nicht mehr beobachten“.',
+'removedwatch' => 'Von der Beobachtungsliste entfernt',
+'removedwatchtext' => 'Die Seite „$1“ wurde von Ihrer Beobachtungsliste entfernt.',
+'watch' => 'beobachten',
+'watchthispage' => 'Seite beobachten',
+'unwatch' => 'nicht mehr beobachten',
+'unwatchthispage' => 'Nicht mehr beobachten',
+'notanarticle' => 'Keine Seite',
+'watchnochange' => 'Keine der von Ihnen beobachteten Seiten wurde während des angezeigten Zeitraums bearbeitet.',
+'watchdetails' => 'Sie beobachten {{PLURAL:$1|eine Seite|$1 Seiten}} | [[{{ns:special}}:Watchlist/edit|Komplette Liste zeigen und bearbeiten]] | [[{{ns:special}}:Watchlist/clear|Komplette Liste leeren]]',
+'wlheader-enotif' => 'Der E-Mail-Benachrichtigungsdienst ist aktiviert.<br />',
+'wlheader-showupdated' => "Seiten mit noch nicht gesehenen Änderungen werden '''fett''' dargestellt.<br />",
+'watchmethod-recent' => 'Überprüfen der letzten Bearbeitungen für die Beobachtungsliste',
+'watchmethod-list' => 'Überprüfen der Beobachtungsliste nach letzten Bearbeitungen',
+'removechecked' => 'Markierte Einträge löschen',
+'watchlistcontains' => 'Ihre Beobachtungsliste enthält $1 Seiten.',
+'watcheditlist' => 'Dies ist eine alphabetische und nach Namensräumen gruppierte Liste aller von Ihnen beobachteten Seiten. Wenn Sie Einträge von der Beobachtungsliste wieder entfernen möchten, markieren Sie diese und klicken auf die Schaltfläche „Markierte Einträge löschen“ am Ende dieser Seite.',
+'removingchecked' => 'Die ausgewählten Einträge werden aus der Beobachtungsliste entfernt...',
+'couldntremove' => 'Der Eintrag „$1“ kann nicht gelöscht werden.',
+'iteminvalidname' => 'Problem mit dem Eintrag „$1“, ungültiger Name.',
+'wlnote' => 'Es folgen die letzten $1 Änderungen der letzten <b>$2</b> Stunden.',
+'wlshowlast' => 'Zeige die Änderungen der letzten $1 Stunden, $2 Tage oder $3 (in den letzten 30 Tagen).',
+'wlsaved' => 'Dies ist eine gespeicherte Version Ihrer Beobachtungsliste.',
+'watchlist-show-bots' => 'Bot-Änderungen einblenden',
+'watchlist-hide-bots' => 'Bot-Änderungen ausblenden',
+'watchlist-show-own' => 'eigene Änderungen einblenden',
+'watchlist-hide-own' => 'eigene Änderungen ausblenden',
+'watchlist-show-minor' => 'kleine Änderungen einblenden',
+'watchlist-hide-minor' => 'kleine Änderungen ausblenden',
+'wldone' => 'Erfolgreich ausgeführt.',
+
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => 'Beobachten',
+'unwatching' => 'Nicht beobachten',
+
+'enotif_mailer' => '{{SITENAME}} E-Mail-Benachrichtigungsdienst',
+'enotif_reset' => 'Alle Seiten als besucht markieren',
+'enotif_newpagetext' => 'Das ist eine neue Seite.',
+'changed' => 'geändert',
+'created' => 'erzeugt',
+'enotif_subject' => '[{{SITENAME}}] Die Seite "$PAGETITLE" wurde von $PAGEEDITOR $CHANGEDORCREATED',
+'enotif_lastvisited' => 'Alle Änderungen auf einen Blick: $1',
+'enotif_body' => 'Liebe/r $WATCHINGUSERNAME,
+
+die {{SITENAME}} Seite "$PAGETITLE" wurde von $PAGEEDITOR am $PAGEEDITDATE $CHANGEDORCREATED.
+
+Aktuelle Version: $PAGETITLE_URL
+
+$NEWPAGE
+
+Zusammenfassung des Bearbeiters: $PAGESUMMARY $PAGEMINOREDIT
+
+Kontakt zum Bearbeiter:
+E-Mail: $PAGEEDITOR_EMAIL
+Wiki: $PAGEEDITOR_WIKI
+
+Es werden solange keine weiteren Benachrichtigungsmails gesendet, bis Sie die Seite wieder besucht haben. Auf Ihrer Beobachtungsseite können Sie alle Benachrichtigungsmarker zusammen zurücksetzen.
+
+ Ihr freundliches {{SITENAME}} Benachrichtigungssystem
+
+--
+Um die Einstellungen Ihrer Beobachtungsliste anzupassen besuchen Sie: {{fullurl:Special:Watchlist/edit}}',
+
+# Delete/protect/revert
+'deletepage' => 'Seite löschen',
+'confirm' => 'Bestätigen',
+'excontent' => "Alter Inhalt: '$1'",
+'excontentauthor' => "Inhalt war: '$1' (einziger Bearbeiter: '[[{{ns:user}}:$2]]') - [[{{ns:user_talk}}:$2]]",
+'exbeforeblank' => "Inhalt vor dem Leeren der Seite: '$1'",
+'exblank' => 'Seite war leer',
+'confirmdelete' => 'Löschen bestätigen',
+'deletesub' => '(Lösche „$1“)',
+'historywarning' => 'WARNUNG: Die Seite, die Sie löschen wollen, hat eine Versionsgeschichte:',
+'confirmdeletetext' => 'Sie sind dabei, eine Seite oder eine Datei und alle zugehörigen älteren Versionen
+zu löschen. Bitte bestätigen Sie dazu, dass Sie sich der Konsequenzen bewusst sind
+und dass Sie in Übereinstimmung mit den [[{{ns:project}}:Löschregeln|Löschregeln]] handeln.',
+'actioncomplete' => 'Aktion beendet',
+'deletedtext' => '„$1“ wurde gelöscht. Im $2 finden Sie eine Liste der letzten Löschungen.',
+'deletedarticle' => 'hat „$1“ gelöscht',
+'dellogpage' => 'Lösch-Logbuch',
+'dellogpagetext' => 'Hier ist eine Liste der letzten Löschungen (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'Lösch-Logbuch',
+'reverted' => 'Auf eine alte Version zurückgesetzt',
+'deletecomment' => 'Grund der Löschung',
+'imagereverted' => 'Auf eine alte Version zurückgesetzt.',
+'rollback' => 'Zurücksetzen der Änderungen',
+'rollback_short' => 'Zurücksetzen',
+'rollbacklink' => 'Zurücksetzen',
+'rollbackfailed' => 'Zurücksetzen gescheitert',
+'cantrollback' => 'Die Änderung kann nicht zurückgesetzt werden, da es keine früheren Autoren gibt.',
+'alreadyrolled' => 'Das Zurücksetzen der Änderungen von [[{{ns:user}}:$2|$2]] <small>([[{{ns:user_talk}}:$2|Diskussion]],
+[[{{ns:special}}:Contributions/$2|Beiträge]])</small> am Artikel [[:$1]] war nicht erfolgreich, da in der Zwischenzeit bereits ein anderer Benutzer
+Änderungen an diesem Artikel vorgenommen hat.<br />Die letzte Änderung stammt von [[{{ns:user}}:$3|$3]] <small>([[{{ns:user_talk}}:$3|Diskussion]])</small>.',
+'editcomment' => 'Der Änderungskommentar lautet: „<i>$1</i>“.', # only shown if there is an edit comment
+'revertpage' => 'Änderungen von [[{{ns:user}}:$2]] ([[{{ns:special}}:Contributions/$2|Beiträge]]) rückgängig gemacht und letzte Version von [[{{ns:user}}:$1]] wiederhergestellt',
+'sessionfailure' => 'Es gab ein Problem mit Ihrer Benutzersitzung.
+Diese Aktion wurde aus Sicherheitsgründen abgebrochen, um eine falsche Zuordnung Ihrer Änderungen zu einem anderen Benutzer zu verhindern.
+Bitte gehen Sie zurück und versuchen den Vorgang erneut auszuführen.',
+'protectlogpage' => 'Seitenschutz-Logbuch',
+'protectlogtext' => 'Dies ist eine Liste der blockierten Seiten.',
+'protectedarticle' => 'änderte den Seitenschutzstatus von [[$1]]',
+'unprotectedarticle' => 'hob den Schutz von $1 auf',
+'protectsub' => '(Sperren von „$1“)',
+'confirmprotecttext' => 'Soll diese Seite wirklich geschützt werden?',
+'confirmprotect' => 'Seitenschutzstatus ändern',
+'protectmoveonly' => 'Nur vor dem Verschieben schützen',
+'protectcomment' => 'Grund der Sperrung/Entsperrung:',
+'unprotectsub' => '(Aufhebung der Sperrung von „$1“)',
+'confirmunprotecttext' => 'Wollen Sie wirklich die Sperrung dieser Seite aufheben?',
+'confirmunprotect' => 'Aufhebung der Sperrung bestätigen',
+'unprotectcomment' => 'Grund für das Aufheben der Sperrung',
+'protect-unchain' => 'Verschiebeschutz ändern',
+'protect-text' => "Hier können Sie den Schutzstatus für die Seite '''$1''' einsehen und ändern.",
+'protect-viewtext' => 'Sie sind nicht berechtigt, den Seitenschutzstatus zu ändern. Hier ist der aktuelle Schutzstatus der Seite: [[$1]]',
+'protect-default' => 'Alle (Standard)',
+'protect-level-autoconfirmed' => 'Sperrung für nicht registrierte Benutzer',
+'protect-level-sysop' => 'Nur Administratoren',
+
+# Restrictions (nouns)
+'restriction-edit' => 'bearbeiten',
+'restriction-move' => 'verschieben',
+
+# Undelete
+'undelete' => 'Gelöschte Seite wiederherstellen',
+'undeletepage' => 'Gelöschte Seiten wiederherstellen',
+'viewdeletedpage' => 'Gelöschte Seiten anzeigen',
+'undeletepagetext' => 'Die folgenden Seiten wurden gelöscht, sind aber immer noch
+gespeichert und können von Administratoren wiederhergestellt werden.',
+'undeleteextrahelp' => '* Um die Seite komplett mit allen Versionen wiederherzustellen, geben Sie bitte eine Begründung an und klicken auf „Wiederherstellen“.
+* Möchten Sie nur bestimmte Versionen wiederherstellen, so wählen Sie diese bitte einzeln an Hand der Markierungen aus,
+geben eine Begründung an und klicken dann auf „Wiederherstellen“.
+* „Zurücksetzen“ leert das Kommentarfeld und entfernt alle Markierungen bei den Versionen.',
+'undeletearticle' => 'Gelöschte Seiten wiederherstellen',
+'undeleterevisions' => '$1 Versionen archiviert',
+'undeletehistory' => 'Wenn Sie diese Seite wiederherstellen, werden auch alle alten
+Versionen wiederhergestellt. Wenn seit der Löschung eine neue Seite gleichen
+namens erstellt wurde, werden die wiederhergestellten Versionen als alte Versionen
+dieser Seite erscheinen.',
+'undeletehistorynoadmin' => 'Diese Seite wurde gelöscht. Der Grund für die Löschung ist in der Zusammenfassung angegeben,
+genauso wie Details zum letzten Benutzer der diese Seite vor der Löschung bearbeitet hat.
+Der aktuelle Text der gelöschten Seite ist nur Administratoren zugänglich.',
+'undeleterevision' => 'Gelöschte Version vom $1',
+'undeleterevision-missing' => 'Ungültige oder fehlende Version. Entweder ist der Link falsch oder die Version wurde aus dem Archiv wiederhergestellt oder entfernt.',
+'undeletebtn' => 'Wiederherstellen',
+'undeletereset' => 'Abbrechen',
+'undeletecomment' => 'Begründung:',
+'undeletedarticle' => 'hat $1 wiederhergestellt',
+'undeletedrevisions' => 'hat $1 Versionen wiederhergestellt',
+'undeletedrevisions-files' => 'hat $1 Versionen und $2 Dateien wiederhergestellt',
+'undeletedfiles' => 'hat $1 Dateien wiederhergestellt',
+'cannotundelete' => 'Wiederherstellung fehlgeschlagen; jemand anderes hat die Seite bereits wiederhergestellt.',
+'undeletedpage' => "<big>'''$1 wurde wiederhergestellt'''</big>
+
+Im [[{{ns:special}}:Log/delete|Lösch-Logbuch]] finden Sie eine Übersicht von kürzlich gelöschten und wiederhergestellten Seiten.",
+
+# Namespace form on various pages
+'namespace' => 'Namensraum:',
+'invert' => 'Auswahl umkehren',
+
+# Contributions
+'contributions' => 'Benutzerbeiträge',
+'mycontris' => 'Eigene Beiträge',
+'contribsub' => 'Für $1',
+'nocontribs' => 'Es wurden keine Änderungen für diese Kriterien gefunden.',
+'ucnote' => 'Dies sind die letzten <b>$1</b> Beiträge des Benutzers in den letzten <b>$2</b> Tagen.',
+'uclinks' => 'Zeige die letzten $1 Beiträge; zeige die letzten $2 Tage.',
+'uctop' => ' (aktuell)',
+'newbies' => 'Neulinge',
+
+'sp-contributions-newest' => 'Jüngste',
+'sp-contributions-oldest' => 'Älteste',
+'sp-contributions-newer' => 'Jüngere $1',
+'sp-contributions-older' => 'Ältere $1',
+'sp-contributions-newbies-sub' => 'Für Neulinge',
+'sp-contributions-blocklog' => 'Blockadelogbuch',
+
+'sp-newimages-showfrom' => 'Zeige neue Dateien ab $1',
+
+# What links here
+'whatlinkshere' => 'Links auf diese Seite',
+'whatlinkshere-summary' => 'Diese Spezialseite listet alle internen Links auf eine bestimmte Seite auf. Die möglichen Zusätze „(Vorlageneinbindung)“ und „(Weiterleitungsseite)“ zeigen jeweils an, dass die Seite nicht durch einen normalen Wikilink eingebunden ist. ',
+'notargettitle' => 'Keine Seite angegeben',
+'notargettext' => 'Sie haben nicht angegeben, auf welche Seite diese Funktion angewendet werden soll.',
+'linklistsub' => '(Liste der Verweise)',
+'linkshere' => "Die folgenden Seiten verweisen auf '''[[:$1]]''':",
+'nolinkshere' => "Keine Seite verweist auf '''[[:$1]]'''.",
+'isredirect' => 'Weiterleitungsseite',
+'istemplate' => 'Vorlageneinbindung',
+
+# Block/unblock
+'blockip' => 'IP-Adresse/Benutzer blockieren',
+'blockiptext' => 'Benutzen Sie das Formular, um einen Benutzer oder eine IP-Adresse zu blockieren.
+Dies sollte nur erfolgen, um Vandalismus zu verhindern und in Übereinstimmung mit unseren [[{{ns:project}}:Leitlinien|Leitlinien]] geschehen.
+Bitte geben Sie den Grund für die Blockade an.',
+'ipaddress' => 'IP-Adresse oder Benutzername',
+'ipadressorusername' => 'IP-Adresse oder Benutzername',
+'ipbexpiry' => 'Sperrdauer',
+'ipbreason' => 'Begründung',
+'ipbanononly' => 'Nur anonyme Benutzer sperren',
+'ipbcreateaccount' => 'Erstellung von Benutzerkonten verhindern',
+'ipbenableautoblock' => 'Sperre die aktuell von diesem Benutzer genutzte IP-Adresse sowie automatisch alle folgenden, von denen aus er Bearbeitungen oder das Anlegen von Benutzeraccounts versucht',
+'ipbsubmit' => 'IP-Adresse/Benutzer blockieren',
+'ipbother' => 'Andere Dauer (englisch)',
+'ipboptions' => '1 Stunde:1 hour,2 Stunden:2 hours,6 Stunden:6 hours,1 Tag:1 day,3 Tage:3 days,1 Woche:1 week,2 Wochen:2 weeks,1 Monat:1 month,3 Monate:3 months,1 Jahr:1 year,Unbeschränkt:indefinite',
+'ipbotheroption' => 'Andere Dauer',
+'badipaddress' => 'Die IP-Adresse hat ein falsches Format.',
+'blockipsuccesssub' => 'Blockade erfolgreich',
+'blockipsuccesstext' => 'Der Benutzer/die IP-Adresse [[{{ns:special}}:Contributions/$1|$1]] wurde blockiert.
+
+Beachten Sie die [[{{ns:special}}:Ipblocklist|{{int:ipblocklist}}]] für alle aktiven Blockaden.',
+'unblockip' => 'IP-Adresse freigeben',
+'unblockiptext' => 'Benutzen Sie das Formular, um eine IP-Adresse oder einen Benutzer freizugeben.',
+'ipusubmit' => 'Diese Adresse freigeben',
+'unblocked' => '[[{{ns:user}}:$1|$1]] wurde freigegeben',
+'ipblocklist' => 'Liste gesperrter Benutzer/IP-Adressen',
+'ipblocklist-summary' => "Diese Spezialseite führt – ergänzend zum [[{{ns:sSpecial}}:Log/block|Benutzerblockaden-Logbuch]], das sämtliche, manuell vorgenommenen Sperrungen und Entsperrungen protokolliert – alle '''aktuell''' (noch) gesperrten Benutzer auf, einschließlich automatisch geblockter IP-Adressen in anonymisierter Form.",
+'blocklistline' => '$1, $2 blockierte $3 (bis $4)',
+'infiniteblock' => 'unbegrenzt',
+'expiringblock' => 'erlischt $1',
+'anononlyblock' => 'nur anonyme',
+'noautoblockblock' => 'Autoblock deaktiviert',
+'createaccountblock' => 'Erstellung von Benutzerkonten gesperrt',
+'ipblocklistempty' => 'Die Liste der Benutzersperrungen hat keine Einträge.',
+'blocklink' => 'blockieren',
+'unblocklink' => 'freigeben',
+'contribslink' => 'Beiträge',
+'autoblocker' => 'Automatische Blockierung, da Sie eine gemeinsame IP-Adresse mit „$1“ benutzen. Grund: „$2“.',
+'blocklogpage' => 'Benutzerblockaden-Logbuch',
+'blocklogentry' => 'blockiert [[{{ns:user}}:$1]] für einen Zeitraum von: $2',
+'blocklogtext' => 'Dies ist ein Log über Sperrungen und Entsperrungen von Benutzern. Automatisch geblockte IP-Adressen werden nicht erfasst. Siehe [[{{ns:special}}:Ipblocklist|IP block list]] für eine Liste der gesperrten Benutzern.',
+'unblocklogentry' => 'hat Blockade von [[$1]] aufgehoben',
+'range_block_disabled' => 'Die Möglichkeit, ganze Adressräume zu sperren, ist nicht aktiviert.',
+'ipb_expiry_invalid' => 'Die eingegebene Dauer ist ungültig.',
+'ipb_already_blocked' => '„$1“ wurde bereits gesperrt',
+'ip_range_invalid' => 'Ungültiger IP-Addressbereich.',
+'proxyblocker' => 'Proxyblocker',
+'ipb_cant_unblock' => 'Fehler: Block-ID $1 nicht gefunden. Die Sperre wurde bereits aufgehoben.',
+'proxyblockreason' => 'Ihre IP-Adresse wurde gesperrt, da sie ein offener Proxy ist. Bitte kontaktieren Sie Ihren Provider oder Ihre Systemtechnik und informieren Sie sie über dieses mögliche Sicherheitsproblem.',
+'proxyblocksuccess' => 'Fertig.',
+'sorbs' => 'SORBS DNSbl',
+'sorbsreason' => 'Ihre IP-Adresse ist bei [http://www.sorbs.net SORBS] DNSbl als offener PROXY gelistet.',
+'sorbs_create_account_reason' => 'Ihre IP-Adresse ist bei [http://www.sorbs.net SORBS] DNSbl als offener PROXY gelistet. Sie können keinen Benutzer anlegen.',
+
+# Developer tools
+'lockdb' => 'Datenbank sperren',
+'unlockdb' => 'Datenbank freigeben',
+'lockdbtext' => 'Mit dem Sperren der Datenbank werden alle Änderungen an Benutzereinstellungen, Beobachtungslisten, Seiten usw. verhindert. Bitte die Sperrung bestätigen.',
+'unlockdbtext' => 'Das Aufheben der Datenbank-Sperre wird alle Änderungen wieder zulassen. Bitte die Aufhebung bestätigen.',
+'lockconfirm' => 'Ja, ich möchte die Datenbank sperren.',
+'unlockconfirm' => 'Ja, ich möchte die Datenbank freigeben.',
+'lockbtn' => 'Datenbank sperren',
+'unlockbtn' => 'Datenbank freigeben',
+'locknoconfirm' => 'Sie haben das Bestätigungsfeld nicht markiert.',
+'lockdbsuccesssub' => 'Datenbank wurde erfolgreich gesperrt',
+'unlockdbsuccesssub' => 'Datenbank wurde erfolgreich freigegeben',
+'lockdbsuccesstext' => 'Die {{SITENAME}}-Datenbank wurde gesperrt.
+<br />Bitte geben Sie die Datenbank [[Special:Unlockdb|wieder frei]], sobald die Wartung abgeschlossen ist.',
+'unlockdbsuccesstext' => 'Die {{SITENAME}}-Datenbank wurde freigegeben.',
+'lockfilenotwritable' => 'Die Datenbank-Sperrdatei ist nicht beschreibbar. Zum Sperren oder Freigeben der Datenbank muss diese für den Webserver beschreibbar sein.',
+'databasenotlocked' => 'Die Datenbank ist nicht gesperrt.',
+
+# Make sysop
+'makesysoptitle' => 'Mache einen Benutzer zum Administrator',
+'makesysoptext' => 'Diese Maske wird von Bürokraten benutzt, um normale Benutzer zu Administratoren zu machen.',
+'makesysopname' => 'Name des Benutzers:',
+'makesysopsubmit' => 'Mache diesen Benutzer zu einem Administrator',
+'makesysopok' => '<b>Benutzer „$1“ ist nun ein Administrator.</b>',
+'makesysopfail' => '<b>Benutzer „$1“ konnte nicht zu einem Administrator gemacht werden. (Haben Sie den Namen richtig geschrieben?)</b>',
+'setbureaucratflag' => 'Mache Benutzer auch zum Bürokraten',
+'rightslog' => 'Benutzerrechte-Logbuch',
+'rightslogtext' => 'Dies ist das Logbuch der Änderungen der Benutzerrechte.',
+'rightslogentry' => 'änderte die Gruppenzugehörigkeit für „[[$1]]“ von „$2“ auf „$3“.',
+'rights' => 'Rechte:',
+'set_user_rights' => 'Benutzerrechte setzen',
+'user_rights_set' => '<b>Benutzerrechte für „$1“ aktualisiert</b>',
+'set_rights_fail' => '<b>Benutzerrechte für „$1“ konnten nicht gesetzt werden. (Wurde der Name korrekt eingegeben?)</b>',
+'makesysop' => 'Mache einen Benutzer zum Administrator',
+'already_sysop' => 'Dieser Benutzer ist bereits Administrator.',
+'already_bureaucrat' => 'Dieser Benutzer ist bereits Bürokrat.',
+'rightsnone' => '(nichts)',
+
+# Move page
+'movepage' => 'Seite verschieben',
+'movepagetext' => 'Mit diesem Formular können Sie eine Seite umbenennen (mitsamt allen Versionen). Der alte Titel wird zum neuen weiterleiten. Verweise auf den alten Titel werden nicht geändert, und die Diskussionsseite wird ebenfalls nicht mitverschoben.',
+'movepagetalktext' => "Die dazugehörige Diskussionsseite wird mitverschoben, '''es sei denn:'''
+*Es existiert bereits eine Diskussionsseite mit diesem Namen, oder
+*Sie wählen die untenstehende Option ab.
+
+In diesen Fällen müssen Sie, falls gewünscht, den Inhalt der Seite von Hand verschieben oder zusammenführen.",
+'movearticle' => 'Seite verschieben',
+'movenologin' => 'Sie sind nicht angemeldet',
+'movenologintext' => 'Sie müssen ein registrierter Benutzer und
+[[{{ns:special}}:Userlogin|angemeldet]] sein,
+um eine Seite zu verschieben.',
+'newtitle' => 'Ziel',
+'move-watch' => 'Diese Seite beobachten',
+'movepagebtn' => 'Seite verschieben',
+'pagemovedsub' => 'Verschiebung erfolgreich',
+'pagemovedtext' => 'Seite „[[$1]]“ wurde nach „[[$2]]“ verschoben.',
+'articleexists' => 'Unter diesem Namen existiert bereits eine Seite.
+Bitte wählen Sie einen anderen Namen.',
+'talkexists' => 'Die Seite selbst wurde erfolgreich verschoben, aber die zugehörige Diskussions-Seite nicht, da bereits eine mit dem neuen Titel existiert. Bitte gleichen Sie die Inhalte von Hand ab.',
+'movedto' => 'verschoben nach',
+'movetalk' => 'Die Diskussionsseite mitverschieben, wenn möglich.',
+'talkpagemoved' => 'Die Diskussionsseite wurde ebenfalls verschoben.',
+'talkpagenotmoved' => 'Die Diskussionsseite wurde <strong>nicht</strong> verschoben.',
+'1movedto2' => 'hat [[$1]] nach [[$2]] verschoben',
+'1movedto2_redir' => 'hat [[$1]] nach [[$2]] verschoben und dabei eine Weiterleitung überschrieben.',
+'movelogpage' => 'Verschiebungs-Logbuch',
+'movelogpagetext' => 'Dies ist eine Liste aller verschobenen Seiten.',
+'movereason' => 'Begründung',
+'revertmove' => 'zurück verschieben',
+'delete_and_move' => 'Löschen und Verschieben',
+'delete_and_move_text' => '==Zielseite vorhanden, löschen?==
+
+Die Seite „[[$1]]“ existiert bereits. Möchten Sie diese löschen, um die Seite verschieben zu können?',
+'delete_and_move_confirm' => 'Zielseite für die Verschiebung löschen',
+'delete_and_move_reason' => 'gelöscht, um Platz zu machen für Verschiebung',
+'selfmove' => 'Ursprungs- und Zielname sind gleich; eine Seite kann nicht zu sich selbst verschoben werden.',
+'immobile_namespace' => 'Der Quell- oder Zielnamensraum ist geschützt; Verschiebungen in diesen Namensraum hinein oder aus diesem heraus sind nicht möglich.',
+
+# Export
+'export' => 'Seiten exportieren',
+'exporttext' => 'Mit dieser Spezialseite können Sie den Text (und die Bearbeitungs-/Versionsgeschichte) einzelner Seiten nach XML exportieren.
+Das Ergebnis kann in ein anderes Wiki mit MediaWiki-Software eingespielt, bearbeitet oder archiviert werden.
+
+Tragen Sie einfach den oder die entsprechenden Seitentitel in das folgende Textfeld ein (pro Zeile jeweils nur für eine Seite).
+
+Alternativ ist der Export auch mit der Syntax <tt><nowiki>[[Spezial:Export/Seitentitel]]</nowiki></tt> möglich, zum Beispiel [[{{ns:special}}:Export/{{Mediawiki:mainpage}}]] für die [[{{Mediawiki:mainpage}}]].',
+'exportcuronly' => 'Nur die aktuelle Version der Seite exportieren',
+'exportnohistory' => "----
+'''Hinweis:''' Der Export kompletter Versionsgeschichten ist aus Performancegründen bis auf Weiteres nicht möglich.",
+'export-submit' => 'Seiten exportieren',
+
+# Namespace 8 related
+'allmessages' => 'MediaWiki-Systemtexte',
+'allmessagesname' => 'Name',
+'allmessagesdefault' => 'Standardtext',
+'allmessagescurrent' => 'Aktueller Text',
+'allmessagestext' => 'Dies ist eine Liste der MediaWiki-Systemtexte.',
+'allmessagesnotsupportedUI' => 'Your current interface language <b>$1</b> is not supported by Special:Allmessages at this site.', # Do not translate this message
+'allmessagesnotsupportedDB' => '\'\'\'{{ns:special}}:Allmessages\'\'\' ist momentan nicht möglich, weil die Datenbank offline ist.',
+'allmessagesfilter' => 'Filter für Systemtexte:',
+'allmessagesmodified' => 'Nur geänderte zeigen',
+
+# Thumbnails
+'thumbnail-more' => 'vergrößern',
+'missingimage' => '<b>Fehlendes Bild</b><br /><i>$1</i>',
+'filemissing' => 'Datei fehlt',
+'thumbnail_error' => 'Fehler beim Erstellen des Vorschaubildes: $1',
+
+# Special:Import
+'import' => 'Seiten importieren',
+'importinterwiki' => 'Transwiki-Import',
+'import-interwiki-text' => 'Wählen Sie ein Wiki und eine Seite zum Importieren aus.
+Das Datum der jeweiligen Versionen und die Autoren bleiben erhalten.
+Alle Transwiki Import-Aktionen werden im [[{{ns:special}}:Log/import|Import-Logbuch]] protokolliert.',
+'import-interwiki-history' => 'Importiere alle Versionen dieser Seite',
+'import-interwiki-submit' => 'Import',
+'import-interwiki-namespace' => 'Importiere die Seite in den Namensraum:',
+'importtext' => 'Auf dieser Spezialseite können über [[{{ns:special}}:Export]] exportierte Seiten in dieses Wiki importiert werden.',
+'importstart' => 'Importiere Seiten…',
+'import-revision-count' => '{{PLURAL:$1|eine Version|$1 Versionen}}',
+'importnopages' => 'Keine Seiten zum Importieren vorhanden.',
+'importfailed' => 'Import fehlgeschlagen: $1',
+'importunknownsource' => 'Unbekannte Importquelle',
+'importcantopen' => 'Importdatei konnte nicht geöffnet werden',
+'importbadinterwiki' => 'Falscher Interwiki-Link',
+'importnotext' => 'Leer oder kein Text',
+'importsuccess' => 'Import erfolgreich!',
+'importhistoryconflict' => 'Es existieren bereits ältere Versionen, welche mit diesen kollidieren. Möglicherweise wurde die Seite bereits vorher importiert.',
+'importnosources' => 'Für den Transwiki Import sind keine Quellen definiert. Das direkte Hochladen von Versionen ist blockiert.',
+'importnofile' => 'Es ist keine Importdatei ausgewählt worden!',
+'importuploaderror' => 'Das Hochladen der Importdatei ist fehlgeschlagen. Vielleicht ist die Datei größer als erlaubt.',
+
+# Import log
+'importlogpage' => 'Import-Logbuch',
+'importlogpagetext' => 'Administrativer Import von Seiten mit Versionsgeschichte von anderen Wikis.',
+'import-logentry-upload' => '[[$1]] wurde importiert',
+'import-logentry-upload-detail' => '{{PLURAL:$1|eine Version|$1 Versionen}}',
+'import-logentry-interwiki' => '[[$1]] wurde importiert (Transwiki)',
+'import-logentry-interwiki-detail' => '{{PLURAL:$1|eine Version|$1 Versionen}} von $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Suchen [alt-f]',
+'tooltip-minoredit' => 'Diese Änderung als klein markieren. [alt-i]',
+'tooltip-save' => 'Änderungen speichern [alt-s]',
+'tooltip-preview' => 'Vorschau der Änderungen an dieser Seite. Bitte vor dem Speichern benutzen! [alt-p]',
+'tooltip-diff' => 'Zeigt Änderungen am Text tabellarisch an [alt-v]',
+'tooltip-compareselectedversions' => 'Unterschiede zwischen zwei ausgewählten Versionen dieser Seite vergleichen. [alt-v]',
+'tooltip-watch' => 'Diese Seite beobachten. [alt-w]',
+
+# Stylesheets
+'common.css' => '/** CSS an dieser Stelle wirkt sich auf alle Skins aus */',
+'monobook.css' => '/** Kleinschreibung nicht erzwingen */
+.portlet h5,
+.portlet h6,
+#p-personal ul,
+#p-cactions li a {
+ text-transform: none;
+}',
+
+# Metadata
+'nodublincore' => 'Dublin-Core-RDF-Metadaten sind für diesen Server deaktiviert.',
+'nocreativecommons' => 'Creative-Commons-RDF-Metadaten sind für diesen Server deaktiviert.',
+'notacceptable' => 'Der Wiki-Server kann die Daten nicht für Ihr Ausgabegerät aufbereiten.',
+
+# Attribution
+'anonymous' => 'Anonyme(r) Benutzer auf {{SITENAME}}',
+'siteuser' => '{{SITENAME}}-Benutzer $1',
+'lastmodifiedatby' => 'Diese Seite wurde zuletzt am $1 um $2 Uhr von $3 geändert.', # $1 date, $2 time, $3 user
+'and' => 'und',
+'othercontribs' => 'Basiert auf der Arbeit von $1',
+'others' => 'andere',
+'siteusers' => '{{SITENAME}}-Benutzer $1',
+'creditspage' => 'Seiteninformationen',
+'nocredits' => 'Für diese Seite sind keine Informationen vorhanden.',
+
+# Spam protection
+'spamprotectiontitle' => 'Spamschutzfilter',
+'spamprotectiontext' => 'Die Seite die Sie speichern wollten wurde vom Spamschutzfilter blockiert. Das liegt wahrscheinlich an einem Link zu einer externen Seite.',
+'spamprotectionmatch' => 'Der folgende Text wurde von dem Spam-Filter gefunden: $1',
+'subcategorycount' => '{{PLURAL:$1|Es wird $1 Unterkategorie|Es werden $1 Unterkategorien}} angezeigt.',
+'categoryarticlecount' => 'Es {{PLURAL:$1|wird $1 Seite|werden $1 Seiten}} aus dieser Kategorie angezeigt.',
+'category-media-count' => 'Es {{PLURAL:$1|wird $1 Datei|werden $1 Dateien}} aus dieser Kategorie angezeigt.',
+'listingcontinuesabbrev' => '(Forts.)',
+'spambot_username' => 'MediaWiki Spam-Säuberung',
+'spam_reverting' => 'Letzte Version ohne Links zu $1 wiederhergestellt.',
+'spam_blanking' => 'Alle Versionen enthielten Links zu $1, bereinigt.',
+
+# Info page
+'infosubtitle' => 'Seiteninformation',
+'numedits' => 'Anzahl der Seitenänderungen: $1',
+'numtalkedits' => 'Anzahl der Diskussionsänderungen: $1',
+'numwatchers' => 'Anzahl der Beobachter: $1',
+'numauthors' => 'Anzahl der Autoren: $1',
+'numtalkauthors' => 'Anzahl der Diskussionsteilnehmer: $1',
+
+# Math options
+'mw_math_png' => 'Immer als PNG darstellen',
+'mw_math_simple' => 'Einfaches TeX als HTML darstellen, sonst PNG',
+'mw_math_html' => 'Wenn möglich als HTML darstellen, sonst PNG',
+'mw_math_source' => 'Als TeX belassen (für Textbrowser)',
+'mw_math_modern' => 'Empfehlenswert für moderne Browser',
+'mw_math_mathml' => 'MathML (experimentell)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Als geprüft markieren',
+'markaspatrolledtext' => 'Diese Seitenänderung als geprüft markieren',
+'markedaspatrolled' => 'Als geprüft markiert',
+'markedaspatrolledtext' => 'Die ausgewählte Seitenänderung wurde als geprüft markiert.',
+'rcpatroldisabled' => 'Prüfung der letzten Änderungen gesperrt',
+'rcpatroldisabledtext' => 'Die Prüfung der letzten Änderungen ist zur Zeit gesperrt.',
+'markedaspatrollederror' => 'Markierung als „geprüft“ nicht möglich.',
+'markedaspatrollederrortext' => 'Sie müssen eine Seitenänderung auswählen.',
+'markedaspatrollederror-noautopatrol' => 'Es ist Ihnen nicht erlaubt, eigene Bearbeitungen als geprüft zu markieren.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* tooltips and access keys */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','Eigene Benutzerseite');
+ta['pt-anonuserpage'] = new Array('.','Benutzerseite der IP-Adresse von der aus Sie Änderungen durchführen');
+ta['pt-mytalk'] = new Array('n','Eigene Diskussionsseite');
+ta['pt-anontalk'] = new Array('n','Diskussion über Änderungen von dieser IP-Adresse');
+ta['pt-preferences'] = new Array('','Eigene Einstellungen');
+ta['pt-watchlist'] = new Array('l','Liste der beobachteten Seiten');
+ta['pt-mycontris'] = new Array('y','Liste eigener Beiträge');
+ta['pt-login'] = new Array('o','Sich einzuloggen wird zwar gerne gesehen, ist aber keine Pflicht.');
+ta['pt-anonlogin'] = new Array('o','Sich einzuloggen wird zwar gerne gesehen, ist aber keine Pflicht.');
+ta['pt-logout'] = new Array('','Abmelden');
+ta['ca-talk'] = new Array('t','Diskussion zum Seiteninhalt');
+ta['ca-edit'] = new Array('e','Seite bearbeiten. Bitte benutzen Sie vor dem Speichern die Vorschaufunktion.');
+ta['ca-addsection'] = new Array('+','Einen Kommentar zu dieser Diskussion hinzufügen.');
+ta['ca-viewsource'] = new Array('e','Diese Seite ist geschützt. Sie können sich den Quelltext ansehen.');
+ta['ca-history'] = new Array('h','Frühere Versionen dieser Seite');
+ta['ca-protect'] = new Array('=','Diese Seite schützen');
+ta['ca-delete'] = new Array('d','Diese Seite löschen');
+ta['ca-undelete'] = new Array('d','Einträge wiederherstellen, bevor diese Seite gelöscht wurde');
+ta['ca-move'] = new Array('m','Diese Seite verschieben');
+ta['ca-watch'] = new Array('w','Diese Seite zu Ihrer Beobachtungsliste hinzufügen');
+ta['ca-unwatch'] = new Array('w','Diese Seite von Ihrer Beobachtungsliste entfernen');
+ta['search'] = new Array('f','Dieses Wiki durchsuchen');
+ta['p-logo'] = new Array('','Hauptseite');
+ta['n-mainpage'] = new Array('z','Hauptseite anzeigen');
+ta['n-portal'] = new Array('','Über das Portal, was Sie tun können, wo was zu finden ist');
+ta['n-currentevents'] = new Array('','Hintergrundinformationen zu aktuellen Ereignissen');
+ta['n-recentchanges'] = new Array('r','Liste der letzten Änderungen in diesem Wiki.');
+ta['n-randompage'] = new Array('x','Zufällige Seite');
+ta['n-help'] = new Array('','Hilfeseite anzeigen');
+ta['n-sitesupport'] = new Array('','Unterstützen Sie uns');
+ta['t-whatlinkshere'] = new Array('j','Liste aller Seiten, die hierher zeigen');
+ta['t-recentchangeslinked'] = new Array('k','Letzte Änderungen an Seiten, die von hier verlinkt sind');
+ta['feed-rss'] = new Array('','RSS-Feed für diese Seite');
+ta['feed-atom'] = new Array('','Atom-Feed für diese Seite');
+ta['t-contributions'] = new Array('','Liste der Beiträge von diesem Benutzer ansehen');
+ta['t-emailuser'] = new Array('','Eine E-Mail an diesen Benutzer senden');
+ta['t-upload'] = new Array('u','Dateien hochladen');
+ta['t-specialpages'] = new Array('q','Liste aller Spezialseiten');
+ta['ca-nstab-main'] = new Array('c','Seiteninhalt anzeigen');
+ta['ca-nstab-user'] = new Array('c','Benutzerseite anzeigen');
+ta['ca-nstab-media'] = new Array('c','Mediendateienseite anzeigen');
+ta['ca-nstab-special'] = new Array('','Dies ist eine Spezialseite. Sie können diese nicht ändern.');
+ta['ca-nstab-project'] = new Array('a','Portalseite anzeigen');
+ta['ca-nstab-image'] = new Array('c','Bilderseite anzeigen');
+ta['ca-nstab-mediawiki'] = new Array('c','MediaWiki-Systemtext anzeigen');
+ta['ca-nstab-template'] = new Array('c','Vorlage anzeigen');
+ta['ca-nstab-help'] = new Array('c','Hilfeseite anzeigen');
+ta['ca-nstab-category'] = new Array('c','Kategorieseite anzeigen');",
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Jedes JavaScript hier wird für alle Benutzer für jede Seite geladen. */',
+
+# Image deletion
+'deletedrevision' => 'Alte Version $1 gelöscht.',
+
+# Browsing diffs
+'previousdiff' => '← Zum vorherigen Versionsunterschied',
+'nextdiff' => 'Zum nächsten Versionsunterschied →',
+
+'imagemaxsize' => 'Maximale Bildgröße auf Bildbeschreibungsseiten:',
+'thumbsize' => 'Standardgröße der Vorschaubilder (thumbnails):',
+'showbigimage' => 'Version mit hoher Auflösung herunterladen ($1 x $2 Pixel, $3 kB)',
+
+'newimages' => 'Neue Dateien',
+'newimages-summary' => 'Diese Spezialseite zeigt die zuletzt hochgeladenen Bilder und Dateien an.',
+'showhidebots' => '(Bots $1)',
+'noimages' => 'Keine Dateien gefunden.',
+
+# List interwikis
+'listinterwikis' => 'Liste der Interwikis',
+
+/*
+Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language
+*/
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+
+# Variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+
+# Variants for Kazakh language
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-cn' => 'kk-cn',
+'variantname-kk' => 'kk',
+
+# Labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Benutzer:',
+'speciallogtitlelabel' => 'Titel:',
+
+'passwordtooshort' => 'Das Passwort ist zu kurz. Es muss mindestens $1 Zeichen lang sein.',
+
+# Media Warning
+'mediawarning' => "'''Warnung:''' Diese Art von Datei kann böswilligen Programmcode enthalten. Durch das Herunterladen oder Öffnen der Datei kann Ihr Computer beschädigt werden.<hr />",
+
+'fileinfo' => '$1 kB, MIME Typ: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadaten',
+'metadata-help' => 'Diese Datei enthält weitere Informationen, die in der Regel von der Digitalkamera oder dem verwendeten Scanner stammen. Durch nachträgliche Bearbeitung der Originaldatei können einige Details verändert worden sein.',
+'metadata-expand' => 'Erweiterte Details einblenden',
+'metadata-collapse' => 'Erweiterte Details ausblenden',
+'metadata-fields' => 'Die folgenden Felder der EXIF-Metadaten in diesem MediaWiki-Systemtext werden auf Bildbeschreibungsseiten angezeigt; weitere standardmäßig „eingeklappte“ Details können angezeigt werden.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# EXIF tags
+'exif-imagewidth' => 'Breite',
+'exif-imagelength' => 'Länge',
+'exif-bitspersample' => 'Bits pro Farbkomponente',
+'exif-compression' => 'Art der Kompression',
+'exif-photometricinterpretation' => 'Pixelzusammensetzung',
+'exif-orientation' => 'Kameraausrichtung',
+'exif-samplesperpixel' => 'Anzahl Komponenten',
+'exif-planarconfiguration' => 'Datenausrichtung',
+'exif-ycbcrsubsampling' => 'Subsampling Rate von Y bis C',
+'exif-ycbcrpositioning' => 'Y und C Positionierung',
+'exif-xresolution' => 'Horizontale Auflösung',
+'exif-yresolution' => 'Vertikale Auflösung',
+'exif-resolutionunit' => 'Maßeinheit der Auflösung',
+'exif-stripoffsets' => 'Bilddaten-Versatz',
+'exif-rowsperstrip' => 'Anzahl Zeilen pro Streifen',
+'exif-jpeginterchangeformat' => 'Offset zu JPEG SOI',
+'exif-jpeginterchangeformatlength' => 'Größe der JPEG-Daten in Bytes',
+'exif-transferfunction' => 'Übertragungsfunktion',
+'exif-whitepoint' => 'Manuell mit Messung',
+'exif-ycbcrcoefficients' => 'YCbCr-Koeffizienten',
+'exif-referenceblackwhite' => 'Schwarz/Weiß-Referenzpunkte',
+'exif-datetime' => 'Speicherzeitpunkt',
+'exif-imagedescription' => 'Bildtitel',
+'exif-make' => 'Hersteller',
+'exif-model' => 'Modell',
+'exif-software' => 'Software',
+'exif-artist' => 'Fotograf',
+'exif-copyright' => 'Urheberrechte',
+'exif-exifversion' => 'Exif-Version',
+'exif-flashpixversion' => 'unterstützte Flashpix-Version',
+'exif-colorspace' => 'Farbraum',
+'exif-componentsconfiguration' => 'Bedeutung einzelner Komponenten',
+'exif-compressedbitsperpixel' => 'Komprimierte Bits pro Pixel',
+'exif-pixelydimension' => 'Gültige Bildbreite',
+'exif-pixelxdimension' => 'Gültige Bildhöhe',
+'exif-makernote' => 'Herstellernotiz',
+'exif-usercomment' => 'Benutzerkommentare',
+'exif-relatedsoundfile' => 'Zugehörige Tondatei',
+'exif-datetimeoriginal' => 'Erfassungszeitpunkt',
+'exif-datetimedigitized' => 'Digitalisierungszeitpunkt',
+'exif-subsectime' => 'Speicherzeitpunkt (1/100 s)',
+'exif-subsectimeoriginal' => 'Erfassungszeitpunkt (1/100 s)',
+'exif-subsectimedigitized' => 'Digitalisierungszeitpunkt (1/100 s)',
+'exif-exposuretime' => 'Belichtungsdauer',
+'exif-exposuretime-format' => '$1 Sekunden ($2)',
+'exif-fnumber' => 'Blende',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Belichtungsprogramm',
+'exif-spectralsensitivity' => 'Spectral Sensitivity',
+'exif-isospeedratings' => 'Film- oder Sensorempfindlichkeit (ISO)',
+'exif-oecf' => 'Optoelektronischer Umrechnungsfaktor',
+'exif-shutterspeedvalue' => 'Belichtungszeitwert',
+'exif-aperturevalue' => 'Blendenwert',
+'exif-brightnessvalue' => 'Helligkeitswert',
+'exif-exposurebiasvalue' => 'Belichtungsvorgabe',
+'exif-maxaperturevalue' => 'Größte Blende',
+'exif-subjectdistance' => 'Entfernung',
+'exif-meteringmode' => 'Messverfahren',
+'exif-lightsource' => 'Lichtquelle',
+'exif-flash' => 'Blitz',
+'exif-focallength' => 'Brennweite',
+'exif-focallength-format' => '$1 mm',
+'exif-subjectarea' => 'Bereich',
+'exif-flashenergy' => 'Blitzstärke',
+'exif-focalplanexresolution' => 'Sensorauflösung horizontal',
+'exif-focalplaneyresolution' => 'Sensorauflösung vertikal',
+'exif-focalplaneresolutionunit' => 'Einheit der Sensorauflösung',
+'exif-subjectlocation' => 'Motivstandort',
+'exif-exposureindex' => 'Belichtungsindex',
+'exif-sensingmethod' => 'Messmethode',
+'exif-filesource' => 'Quelle der Datei',
+'exif-scenetype' => 'Szenentyp',
+'exif-cfapattern' => 'CFA-Muster',
+'exif-customrendered' => 'Benutzerdefinierte Bildverarbeitung',
+'exif-exposuremode' => 'Belichtungsmodus',
+'exif-whitebalance' => 'Weißabgleich',
+'exif-digitalzoomratio' => 'Digitalzoom',
+'exif-focallengthin35mmfilm' => 'Brennweite (Kleinbildäquivalent)',
+'exif-scenecapturetype' => 'Aufnahmeart',
+'exif-gaincontrol' => 'Verstärkung',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Sättigung',
+'exif-sharpness' => 'Schärfe',
+'exif-devicesettingdescription' => 'Geräteeinstellung',
+'exif-subjectdistancerange' => 'Motiventfernung',
+'exif-imageuniqueid' => 'Bild-ID',
+'exif-gpsversionid' => 'GPS-Tag-Version',
+'exif-gpslatituderef' => 'nördl. oder südl. Breite',
+'exif-gpslatitude' => 'Geografische Breite',
+'exif-gpslongituderef' => 'östl. oder westl. Länge',
+'exif-gpslongitude' => 'Geografische Länge',
+'exif-gpsaltituderef' => 'Bezugshöhe',
+'exif-gpsaltitude' => 'Höhe',
+'exif-gpstimestamp' => 'GPS-Zeit',
+'exif-gpssatellites' => 'Für die Messung benutzte Satelliten',
+'exif-gpsstatus' => 'Empfängerstatus',
+'exif-gpsmeasuremode' => 'Messverfahren',
+'exif-gpsdop' => 'Maßpräzision',
+'exif-gpsspeedref' => 'Geschwindigkeitseinheit',
+'exif-gpsspeed' => 'Geschwindigkeit des GPS-Empfängers',
+'exif-gpstrackref' => 'Referenz für Bewegungsrichtung',
+'exif-gpstrack' => 'Bewegungsrichtung',
+'exif-gpsimgdirectionref' => 'Referenz für die Ausrichtung des Bildes',
+'exif-gpsimgdirection' => 'Bildrichtung',
+'exif-gpsmapdatum' => 'Geodätisches Datum benutzt',
+'exif-gpsdestlatituderef' => 'Referenz für die Breite',
+'exif-gpsdestlatitude' => 'Breite',
+'exif-gpsdestlongituderef' => 'Referenz für die Länge',
+'exif-gpsdestlongitude' => 'Länge',
+'exif-gpsdestbearingref' => 'Referenz für Motivrichtung',
+'exif-gpsdestbearing' => 'Motivrichtung',
+'exif-gpsdestdistanceref' => 'Referenz für die Motiventfernung',
+'exif-gpsdestdistance' => 'Motiventfernung',
+'exif-gpsprocessingmethod' => 'Name des GPS-Verfahrens',
+'exif-gpsareainformation' => 'Name des GPS-Gebietes',
+'exif-gpsdatestamp' => 'GPS-Datum',
+'exif-gpsdifferential' => 'GPS-Differentialkorrektur',
+
+# EXIF attributes
+'exif-compression-1' => 'Unkomprimiert',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-unknowndate' => 'Unbekanntes Datum',
+
+'exif-orientation-1' => 'Normal', # 0th row: top; 0th column: left
+'exif-orientation-2' => 'Horizontal gedreht', # 0th row: top; 0th column: right
+'exif-orientation-3' => 'Um 180° gedreht', # 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Vertikal gedreht', # 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Entgegen dem Uhrzeigersinn um 90° gedreht und vertikal gewendet', # 0th row: left; 0th column: top
+'exif-orientation-6' => 'Um 90° in Uhrzeigersinn gedreht', # 0th row: right; 0th column: top
+'exif-orientation-7' => 'Um 90° in Uhrzeigersinn gedreht und vertikal gewendet', # 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Um 90° entgegen dem Uhrzeigersinn gedreht', # 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'Grobformat',
+'exif-planarconfiguration-2' => 'Planarformat',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'Existiert nicht',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Unbekannt',
+'exif-exposureprogram-1' => 'Manuell',
+'exif-exposureprogram-2' => 'Standardprogramm',
+'exif-exposureprogram-3' => 'Zeitautomatik',
+'exif-exposureprogram-4' => 'Blendenautomatik',
+'exif-exposureprogram-5' => 'Kreativprogramm mit Bevorzugung hoher Schärfentiefe',
+'exif-exposureprogram-6' => 'Action-Programm mit Bevorzugung einer kurzen Belichtungszeit',
+'exif-exposureprogram-7' => 'Portrait-Programm',
+'exif-exposureprogram-8' => 'Landschaftsaufnahmen',
+
+'exif-subjectdistance-value' => '$1 Meter',
+
+'exif-meteringmode-0' => 'Unbekannt',
+'exif-meteringmode-1' => 'Durchschnittlich',
+'exif-meteringmode-2' => 'Mittenzentriert',
+'exif-meteringmode-3' => 'Spotmessung',
+'exif-meteringmode-4' => 'Mehrfachspotmessung',
+'exif-meteringmode-5' => 'Muster',
+'exif-meteringmode-6' => 'Bildteil',
+'exif-meteringmode-255' => 'Unbekannt',
+
+'exif-lightsource-0' => 'Unbekannt',
+'exif-lightsource-1' => 'Tageslicht',
+'exif-lightsource-2' => 'Fluoreszierend',
+'exif-lightsource-3' => 'Glühlampe',
+'exif-lightsource-4' => 'Blitz',
+'exif-lightsource-9' => 'Schönes Wetter',
+'exif-lightsource-10' => 'Bewölkt',
+'exif-lightsource-11' => 'Schatten',
+'exif-lightsource-12' => 'Tageslicht fluoreszierend (D 5700–7100 K)',
+'exif-lightsource-13' => 'Tagesweiß fluoreszierend (N 4600–5400 K)',
+'exif-lightsource-14' => 'Kaltweiß fluoreszierend (W 3900–4500 K)',
+'exif-lightsource-15' => 'Weiß fluoreszierend (WW 3200–3700 K)',
+'exif-lightsource-17' => 'Standardlicht A',
+'exif-lightsource-18' => 'Standardlicht B',
+'exif-lightsource-19' => 'Standardlicht C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO Studio Kunstlicht',
+'exif-lightsource-255' => 'Andere Lichtquelle',
+
+'exif-focalplaneresolutionunit-2' => 'Zoll',
+
+'exif-sensingmethod-1' => 'Undefiniert',
+'exif-sensingmethod-2' => 'Ein-Chip-Farbsensor',
+'exif-sensingmethod-3' => 'Zwei-Chip-Farbsensor',
+'exif-sensingmethod-4' => 'Drei-Chip-Farbsensor',
+'exif-sensingmethod-7' => 'Trilinearer Sensor',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'Normal',
+
+'exif-customrendered-0' => 'Standard',
+'exif-customrendered-1' => 'Benutzerdefiniert',
+
+'exif-exposuremode-0' => 'Automatische Belichtung',
+'exif-exposuremode-1' => 'Manuelle Belichtung',
+'exif-exposuremode-2' => 'Belichtungsreihe',
+
+'exif-whitebalance-0' => 'Automatisch',
+'exif-whitebalance-1' => 'Manuell',
+
+'exif-scenecapturetype-0' => 'Standard',
+'exif-scenecapturetype-1' => 'Landschaft',
+'exif-scenecapturetype-2' => 'Portrait',
+'exif-scenecapturetype-3' => 'Nachtszene',
+
+'exif-gaincontrol-0' => 'Keine',
+'exif-gaincontrol-1' => 'Gering',
+'exif-gaincontrol-2' => 'High gain up',
+'exif-gaincontrol-3' => 'Low gain down',
+'exif-gaincontrol-4' => 'High gain down',
+
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'Schwach',
+'exif-contrast-2' => 'Stark',
+
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Gering',
+'exif-saturation-2' => 'Hoch',
+
+'exif-sharpness-0' => 'Normal',
+'exif-sharpness-1' => 'Gering',
+'exif-sharpness-2' => 'Stark',
+
+'exif-subjectdistancerange-0' => 'Unbekannt',
+'exif-subjectdistancerange-1' => 'Makro',
+'exif-subjectdistancerange-2' => 'Nah',
+'exif-subjectdistancerange-3' => 'Entfernt',
+
+# Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'nördl. Breite',
+'exif-gpslatitude-s' => 'südl. Breite',
+
+# Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'östl. Länge',
+'exif-gpslongitude-w' => 'westl. Länge',
+
+'exif-gpsstatus-a' => 'Messung läuft',
+
+'exif-gpsmeasuremode-2' => '2-dimensionale Messung',
+'exif-gpsmeasuremode-3' => '3-dimensionale Messung',
+
+# Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'km/h',
+'exif-gpsspeed-m' => 'mph',
+'exif-gpsspeed-n' => 'Knoten',
+
+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Tatsächliche Richtung',
+'exif-gpsdirection-m' => 'Magnetische Richtung',
+
+# External editor support
+'edit-externally' => 'Diese Datei mit einem externen Programm bearbeiten',
+'edit-externally-help' => 'Siehe die [[meta:Help:External editors|Installationsanweisungen]] für weitere Informationen',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'alle',
+'imagelistall' => 'alle',
+'watchlistall1' => 'alle',
+'watchlistall2' => 'alle',
+'namespacesall' => 'alle',
+
+# E-mail address confirmation
+'confirmemail' => 'E-Mail-Adresse bestätigen (Authentifizierung)',
+'confirmemail_noemail' => 'Sie haben keine gültige E-Mail-Adresse in Ihrem [[{{ns:special}}:Preferences|Benutzerprofil]] eingetragen.',
+'confirmemail_text' => 'Dieses Wiki erfordert, dass Sie Ihre E-Mail-Adresse bestätigen (authentifizieren), bevor Sie die erweiterten E-Mail-Funktionen benutzen können. Durch einen Klick auf die Schaltfläche unten wird eine E-Mail an Sie gesendet. Diese E-Mail enthält einen Link mit einem Bestätigungs-Code. Durch Klicken auf diesen Link wird bestätigt, dass Ihre E-Mail-Adresse gültig ist.',
+'confirmemail_pending' => '<div class="error">Es wurde Ihnen bereits ein Bestätigungs-Code per E-Mail zugeschickt. Wenn Sie Ihr Benutzerkonto erst vor kurzem erstellt haben, warten Sie bitte noch ein paar Minuten auf die E-Mail, bevor Sie einen neuen Code anfordern.</div>', 'confirmemail_send' => 'Bestätigungscode zuschicken',
+'confirmemail_sent' => 'Bestätigungs-E-Mail wurde verschickt.',
+'confirmemail_oncreate' => 'Ein Bestätigungs-Code wurde an Ihre E-Mail-Adresse gesandt. Dieser Code wird für die Anmeldung nicht benötigt, jedoch wird er zur Aktivierung der E-Mail-Funktionen innerhalb des Wikis gebraucht.',
+'confirmemail_sendfailed' => 'Die Bestätigungs-E-Mail konnte nicht versendet werden. Bitte prüfen Sie die E-Mail-Adresse auf ungültige Zeichen.
+
+Rückmeldung des Mailservers: $1',
+'confirmemail_invalid' => 'Ungültiger Bestätigungs-Code. Die Gültigkeitsdauer des Codes ist eventuell abgelaufen.',
+'confirmemail_needlogin' => 'Sie müssen sich $1 um Ihre E-Mail-Adresse zu bestätigen.',
+'confirmemail_success' => 'Ihre E-Mail-Adresse wurde erfolgreich bestätigt. Sie können sich jetzt einloggen.',
+'confirmemail_loggedin' => 'Ihre E-Mail-Adresse wurde erfolgreich bestätigt.',
+'confirmemail_error' => 'Es gab einen Fehler bei der Bestätigung Ihrer E-Mail-Adresse.',
+'confirmemail_subject' => '[{{SITENAME}}] - Bestätigung der E-Mail-Adresse',
+'confirmemail_body' => 'Hallo,
+
+jemand mit der IP-Adresse $1, wahrscheinlich Sie selbst, hat eine Bestätigung dieser E-Mail-Adresse für das Benutzerkonto "$2" für {{SITENAME}} angefordert.
+
+Um die E-Mail-Funktion für {{SITENAME}} (wieder) zu aktivieren und um zu bestätigen, dass dieses Benutzerkonto wirklich zu Ihrer E-Mail-Adresse und damit zu Ihnen gehört, öffnen Sie bitte folgenden Link in Ihrem Browser: $3
+
+Der Bestätigungscode ist bis zu folgendem Zeitpunkt gültig: $4
+
+Wenn diese E-Mail-Adresse *nicht* zu dem genannten Benutzerkonto gehört, folgen Sie diesem Link bitte *nicht*.
+
+--
+{{SITENAME}}: {{fullurl:{{Mediawiki:mainpage}}}}',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Versuche exakte Suche:',
+'searchfulltext' => 'Gesamten Text durchsuchen',
+'createarticle' => 'Seite anlegen',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Interwiki-Einbindung ist deaktiviert]',
+'scarytranscludefailed' => '[Vorlageneinbindung für $1 ist gescheitert]',
+'scarytranscludetoolong' => '[URL ist zu lang; Entschuldigung]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackbacks für diese Seite:<br />
+$1
+</div>',
+'trackbackremove' => '([$1 löschen])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'Trackback wurde erfolgreich gelöscht.',
+
+# Delete conflict
+'deletedwhileediting' => '<span class="error">Achtung: Diese Seite wurde gelöscht, nachdem Sie angefangen haben, sie zu bearbeiten!
+Sehen Sie im [{{fullurl:{{ns:special}}:Log|type=delete&page=}}{{FULLPAGENAMEE}} Lösch-Logbuch] nach,
+warum die Seite gelöscht wurde. Wenn Sie die Seite speichern, wird sie neu angelegt.</span>
+',
+'confirmrecreate' => "Benutzer [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|Diskussion]]) hat diese Seite gelöscht, nachdem Sie angefangen haben ihn zu bearbeiten. Die Begründung lautete:
+''$2''
+Bitte bestätigen Sie, dass Sie diese Seite wirklich neu erstellen möchten.",
+'recreate' => 'Wiederherstellen',
+'tooltip-recreate' => 'Seite neu erstellen, obwohl sie gelöscht wurde.',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Weitergeleitet nach [[$1]]',
+
+# action=purge
+'confirm_purge' => 'Den Cache dieser Seite leeren? $1',
+'confirm_purge_button' => 'OK',
+
+'youhavenewmessagesmulti' => 'Sie haben neue Nachrichten: $1',
+
+'searchcontaining' => "Suche nach Seiten, in denen ''$1'' vorkommt.",
+'searchnamed' => "Suche nach Seiten, deren Name ''$1'' enthält.",
+'articletitles' => "Seiten, die mit ''$1'' beginnen",
+'hideresults' => 'Verbergen',
+
+# DISPLAYTITLE
+'displaytitle' => '(Link zu dieser Seite als [[$1]])',
+
+'loginlanguagelabel' => 'Sprache: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '← vorige Seite',
+'imgmultipagenext' => 'nächste Seite →',
+'imgmultigo' => 'OK',
+'imgmultigotopre' => 'Gehe zu Seite',
+
+# Table pager
+'ascending_abbrev' => 'auf',
+'descending_abbrev' => 'ab',
+'table_pager_next' => 'Nächste Seite',
+'table_pager_prev' => 'Vorherige Seite',
+'table_pager_first' => 'Erste Seite',
+'table_pager_last' => 'Letzte Seite',
+'table_pager_limit' => 'Zeige $1 Einträge pro Seite',
+'table_pager_limit_submit' => 'Los',
+'table_pager_empty' => 'Keine Ergebnisse',
+
+# Auto-summaries
+'autosumm-blank' => 'Die Seite wurde geleert.',
+'autosumm-replace' => "Der Seiteninhalt wurde durch einen anderen Text ersetzt: '$1'",
+'autoredircomment' => 'Weiterleitung nach [[$1]] erstellt', # This should be changed to the new naming convention, but existed beforehand
+'autosumm-new' => 'Die Seite wurde neu angelegt: $1',
+
+# Size units
+'size-bytes' => '$1 B',
+'size-kilobytes' => '$1 KB',
+'size-megabytes' => '$1 MB',
+'size-gigabytes' => '$1 GB',
+
+);
+
+?>
diff --git a/languages/messages/MessagesDv.php b/languages/messages/MessagesDv.php
new file mode 100644
index 000000000000..47806a05c678
--- /dev/null
+++ b/languages/messages/MessagesDv.php
@@ -0,0 +1,9 @@
+<?php
+/** Dhivehi language file ( ދިވެހިބަސް', )
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$rtl = true;
+?>
diff --git a/languages/messages/MessagesDz.php b/languages/messages/MessagesDz.php
new file mode 100644
index 000000000000..cda23ec5ab7d
--- /dev/null
+++ b/languages/messages/MessagesDz.php
@@ -0,0 +1,22 @@
+<?php
+/** Dzongkha (རྫོང་ཁ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+$digitTransformTable = array(
+ '0' => '༠',
+ '1' => '༡',
+ '2' => '༢',
+ '3' => '༣',
+ '4' => '༤',
+ '5' => '༥',
+ '6' => '༦',
+ '7' => '༧',
+ '8' => '༨',
+ '9' => '༩'
+);
+
+?>
diff --git a/languages/messages/MessagesEl.php b/languages/messages/MessagesEl.php
new file mode 100644
index 000000000000..170fa69979fa
--- /dev/null
+++ b/languages/messages/MessagesEl.php
@@ -0,0 +1,1770 @@
+<?php
+/** Greek (Ελληνικά)
+ *
+ * Translation by Pasok Internet Volunteers
+ * http://forum.pasok.gr
+ * version 1.0 (initial release)
+ *
+ *The project for the translation of MediaWiki into Greek
+ *was undertaken by a group of ICT volunteers working under
+ *the auspices of the Greek political party PASOK.
+ *
+ *The idea behind this effort was to provide an extensible,
+ *easy-to-use and non-intimidating tool for content development
+ *and project management, to be used throughout the administrative
+ *and political structure of PASOK by staff, volunteers, party members
+ *and elected officials (all of whom possess varying degrees of ICT skills).
+ *
+ *The PASOK ICT team and the volunteers who worked on this project are
+ *now returning the translated interface to the Open-Source Community
+ *with over 98% of the messages translated into user-friendly Greek.
+ *
+ *We hope that it will be used as a tool by other civil society organizations
+ *in Greece, and that it will enhance the collective creation and the dissemination
+ *of knowledge - an essential component of the democratic process.
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Μέσον',
+ NS_SPECIAL => 'Ειδικό',
+ NS_MAIN => '',
+ NS_TALK => 'Συζήτηση',
+ NS_USER => 'Χρήστης',
+ NS_USER_TALK => 'Συζήτηση_χρήστη',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_συζήτηση',
+ NS_IMAGE => 'Εικόνα',
+ NS_IMAGE_TALK => 'Συζήτηση_εικόνας',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
+ NS_TEMPLATE => 'Πρότυπο',
+ NS_TEMPLATE_TALK => 'Συζήτηση_προτύπου',
+ NS_HELP => 'Βοήθεια',
+ NS_HELP_TALK => 'Συζήτηση_βοήθειας',
+ NS_CATEGORY => 'Κατηγορία',
+ NS_CATEGORY_TALK => 'Συζήτηση_κατηγορίας',
+);
+$fallback8bitEncoding = 'iso-8859-7';
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = '/^([a-z]+)(.*)$/sD';
+
+$messages = array(
+
+# User preference toggles
+#----------------------------------------#
+'tog-underline' => 'Υπογράμμιση συνδέσμων',
+'tog-highlightbroken' => 'Κατεστραμένοι σύνδεσμοι μορφοποίησης <a href="" class="new">όπως αυτός</a> (εναλλακτικά: όπως αυτός<a href="" class="internal">?</a>).',
+'tog-justify' => 'Στοίχιση παραγράφων',
+'tog-hideminor' => 'Απόκρυψη αλλαγών μικρής κλίμακας',
+'tog-usenewrc' => 'Ανάδειξη πρόσφατων αλλαγών (δεν λειτουργεί σε όλους τους browser)',
+'tog-numberheadings' => 'Αυτόματη αρίθμιση τίτλων',
+'tog-showtoolbar' => 'Εμφάνιση μπάρας εργαλείων επεξεργασίας',
+'tog-editondblclick' => 'Επεξεργασία σελίδων με διπλό κλικ (JavaScript)',
+'tog-editsection' => 'Ενεργοποίηση επεξεργασίας τμημάτων μέσω των συνδέσμων [επεξεργασία]',
+'tog-editsectiononrightclick' => 'Ενεργοποίηση επεξεργασίας τμήματος με δεξύ κλικ<br /> στους τίτλους των τμημάτων (JavaScript)',
+'tog-showtoc' => 'Εμφάνιση πίνακα περιεχομένων <br />(για σελίδες με περισσότερες από τρεις κεφαλίδες)',
+'tog-rememberpassword' => 'Διατήρηση του κωδικού πρόσβασης σε αυτό τον υπολογιστή',
+'tog-editwidth' => 'Πλαίσιο επεξεργασίας στο μέγιστο πλάτος',
+'tog-watchdefault' => 'Προσθήκη των σελίδων που επεξεργάζεστε στη λίστα παρακολούθησης.',
+'tog-minordefault' => 'Προκαθορίστε να χαρακτηρίζονται όλες οι αλλαγές "μικρής κλίμακας".',
+'tog-previewontop' => 'Εμφάνιση προεπισκόπησης πριν από το πλαίσο επεξεργασίας και όχι μετά',
+'tog-previewonfirst' => 'Εμφάνιση προεπισκόπησης κατά την πρώτη επεξεργασία',
+'tog-nocache' => 'Απενεργοποίηση της δυνατότητας δημιουργίας cache των σελίδων',
+'tog-enotifwatchlistpages' => 'Ειδοποίηση με e-mail σχετικά με αλλαγές στις σελίδες που παρακολουθώ.',
+'tog-enotifusertalkpages' => 'Ειδοποίηση με e-mail σχετικά με αλλαγές στη συζήτηση της δικής μου σελίδας χρήστη',
+'tog-enotifminoredits' => 'Ειδοποίηση με e-mail και για τις αλλαγές μικρής κλίμακας σε αυτή τη σελίδα',
+'tog-enotifrevealaddr' => 'Εμφάνιση της ηλεκτρονικής μου διεύθυνσης στις ειδοποιήσεις που μου αποστέλλονται.',
+'tog-shownumberswatching' => 'Εμφάνιση του αριθμού των συνδεδεμένων χρηστών',
+'tog-fancysig' => 'Απλή υπογραφή (χωρίς τη χρήση αυτόματου συνδέσμου)',
+'tog-externaleditor' => 'Εξ αρχής χρήση εξωτερικού επεξεργαστή κειμένου',
+'tog-externaldiff' => 'Εξ αρχής χρήση εξωτερικού λογισμικού αντιπαραβολής (diffing)',
+
+'underline-always' => 'Πάντα',
+'underline-never' => 'Ποτέ',
+'underline-default' => 'Όπως ορίζεται από το browser σας.',
+
+'skinpreview' => '(προεπισκόπηση)',
+
+#Months
+#-----------#
+'jan' => 'Ιαν',
+'january' => 'Ιανουαρίου',
+'feb' => 'Φεβρ',
+'february' => 'Φεβρουαρίου',
+'mar' => 'Μαρτ',
+'march' => 'Μαρτίου',
+'apr' => 'Απρ',
+'april' => 'Απριλίου',
+'may' => 'Μαΐου',
+'may_long' => 'Μαΐου',
+'jun' => 'Ιουν',
+'june' => 'Ιουνίου',
+'jul' => 'Ιουλ',
+'july' => 'Ιουλίου',
+'aug' => 'Αυγ',
+'august' => 'Αυγούστου',
+'sep' => 'Σεπτ',
+'september' => 'Σεπτεμβρίου',
+'oct' => 'Οκτ',
+'october' => 'Οκτωβρίου',
+'nov' => 'Νοε',
+'november' => 'Νοεμβρίου',
+'dec' => 'Δεκ',
+'december' => 'Δεκεμβρίου',
+
+#Days
+#-------#
+'sunday' => 'Κυριακή',
+'monday' => 'Δευτέρα',
+'tuesday' => 'Τρίτη',
+'wednesday' => 'Τετάρτη',
+'thursday' => 'Πέμπτη',
+'friday' => 'Παρασκευή',
+'saturday' => 'Σαββάτο',
+
+
+# Bits of text used by many pages:
+#----------------------------------------------------#
+'categories' => 'Κατηγορίες',
+'pagecategories' => 'Κατηγορίες',
+'category_header' => 'Άρθρα στην κατηγορία "$1"',
+'subcategories' => 'Υποκατηγορίες',
+
+'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD',
+'mainpage' => 'Αρχική σελίδα',
+'mainpagetext' => 'To λογισμικό Wiki εγκαταστάθηκε επιτυχώς.',
+
+'mainpagedocfooter' => 'Περισσότερες πληροφορίες σχετικά με τη χρήση και με τη ρύθμιση παραμέτρων θα βρείτε στους συνδέσμους: [http://meta.wikimedia.org/wiki/MediaWiki_i18n Οδηγίες για τροποποίηση του περιβάλλοντος εργασίας] και [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Εγχειρίδιο χρήστη].',
+
+'portal' => 'Ο ιστοχώρος της κοινότητας',
+'portal-url' => '{{ns:4}}:Ο_ιστοχώρος_της_κοινότητας',
+'about' => 'Σχετικά με',
+'aboutsite' => 'Σχετικά με το {{SITENAME}}',
+'aboutpage' => '{{ns:4}}:Σχετικά με',
+'article' => 'Σελίδα κειμένου (ή άλλου περιεχομένου)',
+'help' => 'Βοήθεια',
+'helppage' => '{{ns:12}}:Περιεχόμενα',
+#'wikititlesuffix' => '{{SITENAME}}',
+'bugreports' => 'Αναφορές σφαλμάτων',
+'bugreportspage' => '{{ns:4}}:Αναφορά_σφάλματος',
+'sitesupport' => 'Υποστήριξη ιστοχώρου',
+'sitesupport-url' => '{{ns:4}}:Υποστήριξη_ιστοχώρου',
+'faq' => 'Συνήθεις ερωτήσεις (FAQ)',
+'faqpage' => '{{ns:12}}:Συνήθεις ερωτήσεις (FAQ)',
+'edithelp' => 'Βοήθεια σχετικά με την επεξεργασία',
+'newwindow' => '(ανοίγει σε ξεχωριστό παράθυρο)',
+'edithelppage' => '{{ns:12}}:Επεξεργασία',
+'cancel' => 'Ακύρωση',
+'qbfind' => 'Εύρεση',
+'qbbrowse' => 'Περιήγηση',
+'qbedit' => 'Επεξεργασία',
+'qbpageoptions' => 'Αυτή η σελίδα',
+'qbpageinfo' => 'Συμφραζόμενα',
+'qbmyoptions' => 'Οι σελίδες μου',
+'qbspecialpages' => 'Σελίδες λειτουργιών',
+'moredotdotdot' => 'Περισσότερα...',
+'mypage' => 'Η σελίδα μου',
+'mytalk' => 'Οι συζητήσεις μου',
+'anontalk' => 'Οι συζητήσεις αυτής της διεύθυνσης IP',
+'navigation' => 'Πλοήγηση',
+
+
+# Metadata in edit box
+#---------------------------------#
+'metadata' => '<b>Μεταδεδομένα</b> (επεξήγηση στο σύνδεσμο <a href="$1">here</a>)',
+
+'currentevents' => 'Τρέχοντα γεγονότα',
+'currentevents-url' => 'Τρέχοντα γεγονότα',
+
+'disclaimers' => 'Αποποίηση ευθυνών',
+'disclaimerpage' => '{{ns:4}}:Αποποίηση_ευθύνης',
+
+'errorpagetitle' => 'Σφάλμα',
+'returnto' => 'Επιστροφή στη σελίδα $1.',
+'tagline' => 'Από {{SITENAME}}',
+'whatlinkshere' => 'Αναφορές στη σελίδα',
+'help' => 'Βοήθεια',
+'search' => 'Αναζήτηση',
+'searchbutton' => 'Αναζήτηση',
+'go' => 'Μετάβαση',
+'searcharticle' => 'Μετάβαση',
+'history_short' => 'Ιστορικό',
+'info_short' => 'Πληροφορίες',
+'printableversion' => 'Εκτυπώσιμη έκδοση',
+'print' => 'Εκτύπωση',
+'edit' => 'Επεξεργασία',
+'editthispage' => 'Επεξεργασία αυτής της σελίδας',
+'delete' => 'Διαγραφή',
+'deletethispage' => 'Διαγραφή αυτής της σελίδας',
+'undelete_short' => 'Να αναστραφεί η διαγραφή $1 επεξεργασιών.',
+'protect' => 'Προστασία',
+'protectthispage' => 'Κλείδωμα της σελίδας',
+'unprotect' => 'Άρση προστασίας',
+'unprotectthispage' => 'Άρση προστασίας αυτής της σελίδας',
+'newpage' => 'Νέα σελίδα',
+'talkpage' => 'Συζήτηση για αυτή τη σελίδα',
+'specialpage' => 'Σελίδα λειτουργιών',
+'personaltools' => 'Προσωπικά εργαλεία',
+'postcomment' => 'Καταχωρίστε ένα σχόλιο.',
+'articlepage' => 'Εμφάνιση σελίδας κειμένου',
+'talk' => 'Συζήτηση',
+'views' => 'Εμφανίσεις',
+'toolbox' => 'Εργαλεία',
+'userpage' => 'Εμφάνιση σελίδας χρήστη',
+'projectpage' => 'Εμφάνιση σελίδας βοήθειας',
+'imagepage' => 'Εμφάνιση σελίδας εικόνων',
+'viewtalkpage' => 'Εμφάνιση συζήτησης',
+'otherlanguages' => 'Άλλες γλώσσες',
+'redirectedfrom' => '(Ανακατεύθυνση από $1)',
+'lastmodifiedat' => 'Η σελίδα αυτή τροποποιήθηκε τελευταία φορά στις $2, $1.',
+'viewcount' => 'Αυτή η σελίδα έχει προσπελαστεί $1 φορές.',
+'copyright' => 'Το περιεχόμενο είναι διαθέσιμο σύμφωνα με την $1.',
+'protectedpage' => 'Κλειδωμένη σελίδα',
+
+'badaccess' => 'Ακατάλληλη άδεια',
+
+'versionrequired' => 'Απαιτείται η έκδοση $1 του MediaWiki.',
+'versionrequiredtext' => 'Για να χρησιμοποιήσετε αυτή τη σελίδα απαιτείται η έκδοση $1 του MediaWiki . Βλ. [[Special:Έκδοση]]',
+'nbytes' => '$1 bytes',
+'retrievedfrom' => 'Ανακτήθηκε από το "$1".',
+'newmessageslink' => 'νέο μήνυμα',
+'editsection' => 'επεξεργασία',
+'editold' => 'επεξεργασία',
+'toc' => 'Πίνακας περιεχομένων',
+'showtoc' => 'εμφάνιση',
+'hidetoc' => 'απόκρυψη',
+'thisisdeleted' => 'Εμφάνιση ή αποκατάσταση της $1;',
+'restorelink' => '$1 επεξεργασίες έχουν διαγραφεί.',
+'feedlinks' => 'Ροή δεδομένων:',
+
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+#---------------------------------------------------------------------------------------------------------------------------------#
+'nstab-main' => 'Άρθρο',
+'nstab-user' => 'Σελίδα χρήστη',
+'nstab-media' => 'Ηλεκτρονικά μέσα',
+'nstab-special' => 'Σελίδα λειτουργιών',
+'nstab-project' => 'Σχετικά με',
+'nstab-image' => 'Εικόνα',
+'nstab-mediawiki' => 'Μήνυμα',
+'nstab-template' => 'Πρότυπο',
+'nstab-help' => 'Βοήθεια',
+'nstab-category' => 'Κατηγορία',
+
+# Main script and global functions
+#--------------------------------------------------#
+'nosuchaction' => 'Δεν υπάρχει τέτοια ενέργεια.',
+'nosuchactiontext' => 'Η ενέργεια που καθορίστηκε από την διεύθυνση URL δεν αναγνωρίζεται από το Wiki.',
+'nosuchspecialpage' => 'Δεν υπάρχει τέτοια σελίδα λειτουργιών.',
+'nospecialpagetext' => 'Έχετε ζητήσει μια ειδική σελίδα που δεν αναγνωρίζεται από το Wiki.',
+
+# General errors
+#------------------------#
+'error' => 'Σφάλμα',
+'databaseerror' => 'Σφάλμα στη βάση δεδομένων',
+
+'dberrortext' => 'Σημειώθηκε συντακτικό σφάλμα σε αίτημα προς τη βάση δεδομένων. Πιθανόν να πρόκειται για ένδειξη σφάλματος στο λογισμικό. Το τελευταίο αίτημα προς τη βάση δεδομένων που επιχειρήθηκε ήταν: <blockquote><tt>$1</tt></blockquote> μέσα από τη λειτουργία "<tt>$2</tt>". Το MySQL επέστρεψε σφάλμα "<tt>$3: $4</tt>".',
+
+'dberrortextcl' => 'Σημειώθηκε συντακτικό σφάλμα σε αίτημα προς τη βάση δεδομένων. Το τελευταίο αίτημα που επιχειρήθηκε ήταν: "$1" μέσα από τη λειτουργία "$2". Το MySQL επέστρεψε σφάλμα "$3: $4".',
+'noconnect' => 'Λυπούμαστε! Λόγω τεχνικών δυσκολιών το Wiki δεν μπορεί να επικοινωνήσει με τον server της βάσης δεδομένων. <br />
+
+$1',
+
+'nodb' => 'Αδύνατη η επιλογή της βάσης δεδομένων $1',
+'cachederror' => 'Το ακόλουθο κείμενο προέρχεται από το προσωρινό αρχείο (cache) και πιθανόν να μην περιέχει τις πιο πρόσφατες αλλαγές.',
+'laggedslavemode' => 'Προειδοποίηση: Η σελίδα μπορεί να μην έχει ενημερωθεί με τις πρόσφατες αλλαγές.<br />',
+'readonly' => 'Κλειδωμένη βάση δεδομένων',
+'enterlockreason' => 'Εξηγήστε τους λόγους για το κλείδωμα και το πότε, κατά την εκτίμησή σας, το κλείδωμα αυτό θα αναιρεθεί.',
+
+'readonlytext' => 'Η βάση δεδομένων είναι προσωρινά κλειδωμένη και δεν μπορεί να δεχθεί νέα λήμματα και άλλες τροποποιήσεις -πιθανότατα λόγω συντήρησης. Μετά τη συντήρηση θα επανέλθει σε κανονική λειτουργία. Η αιτιολογία για το κλείδωμα της βάσης δεδομένων ήταν η εξής: <p>$1',
+
+'missingarticle' => 'Η βάση δεδομένων δεν βρήκε το αναμενόμενο περιεχόμενο σελίδας κάτω από το όνομα "$1".
+
+<p> Αυτό συμβαίνει όταν ακολουθούμε συνδέσμους μιας παλιάς \'αντιπαραβολής\' ή \'ίστορικού\' σε σελίδες που έχουν διαγραφεί. Αν δεν πρόκειται για τέτοια περίπτωση, είναι πιθανόν να υπάρχει σφάλμα στο λογισμικό. Σας παρακαλούμε να το αναφέρετε στους διαχειριστές, παραπέμποντας στο συγκεκριμένο URL.',
+
+'readonly_lag' => 'Η βάση δεδομένων έχει κλειδωθεί αυτόματα για να μπορέσουν οι επιμέρους servers των αντιγράφων της βάσης δεδομένων (slaves) να καλύψουν τη διαφορά με τον κεντρικό server του πρωτοτύπου της βάσης (master).',
+
+'internalerror' => 'Εσωτερικό σφάλμα',
+'filecopyerror' => 'Δεν ήταν δυνατή η αντιγραφή του αρχείου "$1" στο "$2".',
+'filerenameerror' => 'Δεν είναι δυνατή η μετονομασία του αρχείου "$1" σε "$2".',
+'filedeleteerror' => 'Δεν ήταν δυνατή η διαγραφή του αρχείου "$1".',
+'filenotfound' => 'Δεν είναι δυνατή η ανεύρεση του αρχείου "$1".',
+'unexpected' => 'Μη προσδοκώμενη τιμή: "$1"="$2"',
+'formerror' => 'Λάθος: Δεν ολοκληρώθηκε η υποβολή της φόρμας!',
+'badarticleerror' => 'Η ενέργεια αυτή δεν μπορεί να εκτελεσθεί στη συγκεκριμένη σελίδα.',
+'cannotdelete' => 'Αδύνατη η διαγραφή της συγκεκριμένης σελίδας ή εικόνας (Ενδεχομένως να έχει ήδη διαγραφεί από άλλο χρήστη.)',
+'badtitle' => 'Ακατάλληλος τίτλος',
+'badtitletext' => 'Ο τίτλος της σελίδας που ζητήσατε είναι άκυρος ή κενός ή πρόκειται για έναν εσφαλμένα συνδεδεμένο διαγλωσσικό τίτλο (ή εσφαλμένα συνδεδεμένο τίτλο ανάμεσα σε διαφορετικά Wiki).',
+'perfdisabled' => 'Λυπούμαστε! Αυτή η λειτουργία έχει προσωρινά απενεργοποιηθεί επειδή επιβραδύνει τη βάση δεδομένων σε βαθμό που κανένας χρήστης δεν μπορεί να χρησιμοποιήσει το Wiki.',
+'perfdisabledsub' => 'Αυτό είναι ένα αποθηκευμένο αντίγραφο της $1:',
+'perfcached' => 'Τα δεδομένα που ακολουθούν είναι cached και είνα πιθανόν να μην είναι πλήρως ενημερωμένα:',
+
+'wrong_wfQuery_params' => 'Λανθανσμένες παράμετροι στο wfQuery()<br />
+Λειτουργία: $1<br />
+Αίτημα: $2',
+
+'viewsource' => 'Εμφάνιση κώδικα',
+
+'protectedtext' => 'Η σελίδα αυτή είναι κλειδωμένη και δεν είναι δυνατή η επεξεργασία της. Για περισσότερες πληροφορίες σχετικά με τους λόγους για τους οποίους προστατεύεται η σελίδα, παρακαλούμε επισκεφθείτε το σύνδεσμο
+[[{{ns:4}}:Κλειδωμένες_σελίδες]].
+
+Μπορείτε να δείτε και να αντιγράψετε τον πηγαίο κώδικα αυτής σελίδας:',
+
+'sqlhidden' => '(το αίτημα SQL δεν εμφανίζεται)',
+
+
+# Login and logout pages
+#-------------------------------------#
+'logouttitle' => 'Έξοδος χρήστη',
+'logouttext' => 'Έχετε αποσυνδεθεί.
+Μπορείτε να παραμείνετε στο {{SITENAME}} ανώνυμα, ή μπορείτε να συνδεθείτε ξανά με το ίδιο ή με διαφορετικό (εάν έχετε) όνομα χρήστη. Έχετε υπ\' όψη σας πως αρκετές σελίδες θα συνεχίσουν να εμφανίζονται κανονικά, σαν να μην έχετε αποσυνδεθεί, μέχρι να καθαρίσετε το cache του browser σας.',
+
+'welcomecreation' => '== Καλώς ήλθατε, $1! ==
+
+Ο λογαριασμός σας έχει δημιουργθεί. Μπορείτε να εξατομικεύσετε το {{SITENAME}} σύμφωνα με τις ανάγκες σας μέσα από το σύνδεσμο [[Special:Preferences|Προτιμήσεις]].',
+
+'loginpagetitle' => 'Είσοδος χρήστη',
+'yourname' => 'Όνομα χρήστη',
+'yourpassword' => 'Κωδικός',
+'yourpasswordagain' => 'Πληκτρολογήστε ξανά τον κωδικό',
+'remembermypassword' => 'Διατήρηση του κωδικού πρόσβασης σε αυτόν τον υπολογιστή',
+#'yourdomainname' => 'Your domain',
+'externaldberror' => 'Συνέβη εξωτερικό σφάλμα πιστοποίησης στη βάση δεδομένων ή δεν σας έχει επιτραπεί να ενημερώσετε τον εξωτερικό σας λογαριασμό.',
+'loginproblem' => '<b>Εμφανίστηκε πρόβλημα κατά την είσοδό σας.</b><br />Παρακαλούμε δοκιμάστε ξανά!',
+'alreadyloggedin' => '<strong>Ο χρήστης $1, είναι ήδη συνδεδεμένος!</strong><br />',
+'login' => 'Είσοδος',
+'loginprompt' => 'Πρέπει να έχετε ενεργοποιήσει τα cookies για να συνδεθείτε στο {{SITENAME}}.',
+'userlogin' => 'Δημιουργία Λογαριασμού/Είσοδος',
+'logout' => 'Έξοδος',
+'userlogout' => 'Έξοδος χρήστη',
+'notloggedin' => 'Δεν έχετε συνδεθεί.',
+'createaccount' => 'Δημιουργία νέου λογαριασμού',
+'createaccountmail' => 'Με ηλεκτρονικό ταχυδρομείο',
+'badretype' => 'Οι κωδικοί που έχετε δηλώσει δεν συμφωνούν μεταξύ τους.',
+'userexists' => 'Το όνομα χρήστη που συμπληρώσατε είναι ήδη σε χρήση. Παρακαλούμε διαλέξτε ένα άλλο όνομα.',
+'youremail' => 'Ηλεκτρονική διεύθυνση*',
+'yourrealname' => 'Όνομα και επώνυμο*',
+'yourlanguage' => 'Γλώσσα διασύνδεσης',
+'yourvariant' => 'Η γλώσσα που χρησιμοποιείτε',
+'yournick' => 'Το ψευδώνυμό σας (για την υπογραφή)',
+'email' => 'αλληλογραφία',
+
+'prefs-help-email-enotif' => 'Αυτή η διεύθυνση χρησιμοποιείται για να σας αποστέλλονται ειδοποιήσεις εφόσον έχετε ενεργοποιήσει τις σχετικές επιλογές.',
+'prefs-help-realname' => '* Πραγματικό όνομα (προαιρετικό): εφόσον εισάγετε το όνομά σας, αυτό θα μπορεί να χρησιμοποιηθεί για να αναγνωριστεί ευρύτερα η δουλειά σας.',
+'loginerror' => 'Λάθος σύνδεσης',
+
+'prefs-help-email' => '* Email (προαιρετικό): Δίνει τη δυνατότητα σε άλλους χρήστες να επικοινωνήσουν μαζί σας μέσω της σελίδας χρήστη (ή της συζήτησης για την σελίδα χρήστη) χωρίς να εμφανίζεται η ταυτότητά σας.',
+
+'nocookiesnew' => 'Ο λογαριασμός χρήστη έχει δημιουργηθεί, αλλά δεν έχετε ακόμα συνδεθεί. Το {{SITENAME}} χρησιμοποιεί cookies κατά τη σύνδεση των χρηστών. Τα cookies είναι απενεργοποιημένα στον υπολογιστή σας. Παρακαλούμε ενεργοποιήστε τα και στη συνέχεια συνδεθείτε χρησιμοποιώντας το νέο όνομα χρήστη σας και τον κωδικό σας.',
+
+'nocookieslogin' => 'Το {{SITENAME}} χρησιμοποιεί cookies κατά τη σύνδεση των χρηστών. Τα cookies είναι απενεργοποιημένα στον υπολογιστή σας. Παρακαλούμε ενεργοποιήστε τα και ξαναδοκιμάστε!',
+'noname' => 'Το όνομα χρήστη που έχετε καθορίσει δεν είναι έγκυρο.',
+'loginsuccesstitle' => 'Επιτυχής σύνδεση',
+'loginsuccess' => 'Είστε συνδεδεμένος(-η) στο {{SITENAME}} ως "$1".',
+
+'nosuchuser' => 'Δεν υπάρχει χρήστης με το όνομα "$1".
+Ελέγξτε την ορθογραφία ή χρησιμοποιείστε την παρακάτω φόρμα για να δημιουργήσετε ένα νέο λογαριασμό.',
+
+'nosuchusershort' => 'Δεν υπάρχει χρήστης με το όνομα "$1". Παρακαλούμε ελέγξτε την ορθογραφία.',
+'wrongpassword' => 'Ο κωδικός που πληκτρολογήσατε είναι λανθασμένος. Παρακαλούμε προσπαθήστε ξανά.',
+'mailmypassword' => 'Στείλτε μου ένα νέο κωδικό.',
+'passwordremindertitle' => 'Υπενθύμιση κωδικού από το {{SITENAME}}',
+
+'passwordremindertext' => 'Κάποιος (πιθανώς εσείς) με διεύθυνση IP $1, ζήτησε να σας στείλουμε ένα νέο κωδικό πρόσβασης στο {{SITENAME}}. Ο κωδικός πρόσβασης για το χρήστη "$2" είναι αυτή τη στιγμή "$3". Συνιστούμε να συνδεθείτε και να αλλάξετε αυτόν τον κωδικό το συντομότερο δυνατόν.',
+
+'noemail' => 'Δεν υπάρχει ηλεκτρονική διεύθυνση για το χρήστη "$1".',
+
+'passwordsent' => 'Σας έχει σταλεί ένας νέος κωδικός στην ηλεκτρονική διέθυνση που δηλώσατε για "$1".
+Σας παρακαλούμε να ξανασυνδεθείτε μόλις τον λάβετε.',
+
+'eauthentsent' => 'Ένα μήνυμα επαλήθευσης έχει σταλεί στην ηλεκτρονική διεύθυνση που έχετε δηλώσει στο σύστημα. Πριν αρχίσει η αποστολή μηνυμάτων στη συγκεκριμένη διεύθυνση, πρέπει να ακολουθήσετε τις οδηγίες που βρίσκονται στο μήνυμα που σας έχει σταλεί για να επαληθεύσετε ότι η συγκεκριμένη ηλεκτρονική διεύθυνση ανήκει πραγματικά σε εσάς.',
+
+'mailerror' => 'Λάθος στην αποστολή του μηνύματος: $1',
+'acct_creation_throttle_hit' => 'Λυπούμαστε, έχετε ήδη δημιουργήσει $1 λογαριασμούς και δεν μπορείτε να δημιουργήσετε άλλους.',
+'emailauthenticated' => 'Η ηλεκτρονική σας διεύθυνση επιβεβαιώθηκε στις $1.',
+
+'emailnotauthenticated' => 'Η ηλεκτρονική σας διεύθυνση δεν έχει επαληθευθεί ακόμα. Μέχρι να ολοκληρώσετε την επαλήθευση της διεύθυνσής σας, δεν είναι δυνατόν το σύστημα να σας αποστείλει αλληλογραφία για καμμία από τις ακόλουθες λειτορυγίες.',
+
+'noemailprefs' => '<strong>Δεν έχει ορισθεί ηλεκτρονική διέυθυνση</strong>, οι λειτουργίες που ακολουθούν δεν θα είναι δυνατόν να ολοκληρωθούν.',
+'emailconfirmlink' => 'Επαληθεύστε την ηλεκτρονική σας διεύθυνση',
+'invalidemailaddress' => 'Η ηλεκτρονική διεύθυνση δεν έγινε δεκτή γιατί ενδεχομένως δεν είχε έγκυρη μορφή. Παρακαλούμε συμπληρώστε μια σωστά διαμορφωμένη διεύθυνση ή αφήστε το πεδίο κενό.',
+
+
+# Edit page toolbar
+#----------------------------#
+'bold_sample' => 'Έντονο κείμενο',
+'bold_tip' => 'Έντονο κείμενο',
+
+'italic_sample' => 'Κείμενο με πλάγιους χαρακτήρες',
+'italic_tip' => 'Κείμενο με πλάγιους χαρακτήρες',
+
+'link_sample' => 'Τίτλος συνδέσμου',
+'link_tip' => 'Εσωτερικός σύνδεσμος',
+
+'extlink_sample' => 'http://www.paradeigma.com τίτλος συνδέσμου',
+'extlink_tip' => 'Εξωτερικός σύνδεσμος (μην ξεχάστε το πρόθεμα http:// )',
+
+'headline_sample' => 'Κείμενο τίτλου',
+'headline_tip' => 'Δεύτερος τίτλος (επίπεδο 2)',
+
+'math_sample' => 'Εισαγωγή τύπου εδώ',
+'math_tip' => 'Μαθηματικός τύπος (LaTeX)',
+
+'nowiki_sample' => 'Εισάγετε εδώ το μη μορφοποιημένο κείμενο.',
+'nowiki_tip' => 'Να αγνοηθεί η μορφοποίηση Wiki.',
+
+'image_sample' => 'paradeigma.jpg',
+'image_tip' => 'Ενσωματωμένη εικόνα',
+
+'media_sample' => 'paradeigma.mp3',
+'media_tip' => 'Σύνδεσμος αρχείου πολυμέσων',
+
+'sig_tip' => 'Υπογραφή με ημερομηνία',
+'hr_tip' => 'Οριζόντια γραμμή (να χρησιμοποιείται με μέτρο!)',
+
+
+# Edit pages
+#-----------------#
+'summary' => 'Σύνοψη',
+'subject' => 'Θέμα/επικεφαλίδα',
+'minoredit' => 'Αλλαγή μικρής κλίμακας',
+'watchthis' => 'Παρακολούθηση αυτής της σελίδας',
+'savearticle' => 'Αποθήκευση σελίδας',
+'preview' => 'Προεπισκόπηση',
+'showpreview' => 'Προεπισκόπηση',
+'showdiff' => 'Δείτε τις αλλαγές',
+'blockedtitle' => 'Ο χρήστης έχει υποστεί φραγή.',
+
+'blockedtext' => 'Το όνομα χρήστη ή η διεύθυνση IP σας έχει υποστεί φραγή από τον/την $1 με την αιτιολογία :<br />\'\'$2\'\'<p> Μπορείτε να απευθυνθείτε στον/στην $1 ή σε κάποιον άλλον από τους [[{{ns:4}}:Διαχειριστές |διαχειριστές]] για να συζητήσετε το πρόβλημα.
+
+Έχετε υπ\' όψη σας ότι δεν μπορείτε να χρησιμοποιήσετε τη δυνατότητα "αποστολή e-mail σε χρήστη" εκτός αν έχετε μια έγκυρη διεύθυνση e-mail δηλωμένη στις [[Special:Preferences|Προτιμήσεις χρήστη]].
+
+<br />
+<br />Η διεύθυνση IP σας είναι: $3. Παρακαλούμε να την αναφέρετε σε κάθε σας αίτημα.',
+
+'whitelistedittitle' => 'Για να επεξεργαστείτε μια σελίδα πρέπει πρώτα να συνδεθείτε.',
+'whitelistedittext' => 'Πρέπει να [[Special:Userlogin|συνδεθείτε]] για να επεξεργαστείτε μια σελίδα.',
+'whitelistreadtitle' => 'Για να διαβάσετε πρέπει πρώτα να συνδεθείτε.',
+'whitelistreadtext' => 'Πρέπει να [[Special:Userlogin|συνδεθείτε]] για να διαβάσετε σελίδες.',
+'whitelistacctitle' => 'Δεν έχετε το δικαίωμα να δημιουργήσετε λογαριασμό.',
+'whitelistacctext' => 'Για να σας επιτραπεί η δημιουργία λογαριασμού σε αυτό το Wiki πρέπει να [[Special:Userlogin|συνδεθείτε]] και να κατέχετε την κατάλληλη άδεια.',
+'loginreqtitle' => 'Απαιτείται η σύνδεση του χρήστη.',
+'accmailtitle' => 'Ο κωδικός έχει σταλεί.',
+'accmailtext' => 'Ο κωδικός για τον/την \'$1\' έχει σταλεί στο $2.',
+'newarticle' => '(Νέο)',
+
+'newarticletext' => 'Έχετε ακολουθήσει ένα σύνδεσμο που δεν υπάρχει ακόμα. Για να δημιουργήσετε μια νέα σελίδα εδώ, αρχίστε να γράφετε το κείμενό σας στο πλαίσιο.(Βλ. [[{{ns:12}}:Περιεχόμενα|Σελίδα βοήθειας]] για περισσότερες πληροφορίες).
+Αν έχετε βρεθεί εδώ κατά λάθος, απλώς πατήστε \'\'\'επιστροφή (back)\'\'\' στον browser του υπολογιστή σας.',
+
+
+'anontalkpagetext' => '----\'\'Αυτή η σελίδα συζήτησης προορίζεται για ανώνυμους χρήστες που δεν έχουν δημιουργήσει ακόμα λογαριασμό (ή που δεν τον χρησιμοποιούν). Έτσι για την ταυτοποίηση ενός ανώνυμου χρήστη χρησιμοποιείται η [[{{ns:12}}:διεύθυνση IP |διεύθυνση IP ]] του. Είναι όμως πιθανόν η διεύθυνση αυτή να είναι κοινή για πολλούς διαφορετικούς χρήστες (όπως π.χ. για τους χρήστες ενός Internet Cafe ή ενός [[{{ns:12}}:proxy server|proxy server]]). Αν είστε ανώνυμος χρήστης και έχετε δεχθεί σχόλια άσχετα με τα θέματά σας (κάτι που μπορεί να συμβεί αν χρησιμοποιείτε την ίδια [[{{ns:12}}:διεύθυνση IP|διεύθυνση IP]] με κάποιον άλλο ανώνυμο χρήστη) θα ήταν καλό να [[Special:Userlogin|δημιουργήσετε ένα λογαριασμό χρήστη ή να συνδεθείτε]] για να αποφεύγεται η σύγχυση\'\'.',
+
+'noarticletext' => '(Δεν υπάρχει κείμενο στη σελίδα)',
+
+'clearyourcache' => '\'\'\'Σημείωση:\'\'\' Μετά την αποθήκευση, θα χρειαστεί να καθαρίσετε το cache στον browser για να μπορέσετε να δείτε τις αλλαγές: \'\'\'Mozilla:\'\'\' click \'\'Reload\'\' (or \'\'Ctrl-R\'\'), \'\'\'IE / Opera:\'\'\' \'\'Ctrl-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-R\'\', \'\'\'Konqueror\'\'\' \'\'Ctrl-R\'\'.<br />',
+
+'usercssjsyoucanpreview' => '<strong>Χρήσιμη συμβουλή:</strong> Χρησιμοποιήστε το κουμπί "Προεπισκόπηση" για να ελέγξτε τα νέα σας CSS/JS πριν τα αποθηκεύσετε.',
+'usercsspreview' => '\'\'\'Σας υπενθυμίζουμε ότι κάνετε απλώς έλεγχο/προεπισκόπηση του CSS του χρήστη -δεν το έχετε ακόμα αποθηκεύσει! \'\'\'',
+'userjspreview' => '\'\'\'Σας υπενθυμίζουμε ότι κάνετε απλώς έλεγχο/προεπισκόπηση του JavaScript του χρήστη -δεν το έχετε ακόμα αποθηκεύσει!\'\'\'',
+'updated' => '(Ενημερώθηκε.)',
+'note' => '<strong>Προσοχή: </strong>',
+'previewnote' => 'Σας υπενθυμίζουμε ότι βλέπετε μόνον την προεπισκόπηση -δεν έχετε ακόμα αποθηκεύσει τις αλλαγές σας!',
+'previewconflict' => 'Αυτή η προεπισκόπηση απεικονίζει το κείμενο στην επάνω περιοχή επεξεργασίας κειμένου, όπως θα εμφανιστεί εάν επιλέξετε να το αποθηκεύσετε.',
+'editing' => 'Επεξεργασία $1',
+'editinguser' => 'Επεξεργασία $1',
+'editingsection' => 'Επεξεργασία $1 (τμήμα)',
+'editingcomment' => 'Επεξεργασία $1 (σχόλια)',
+'editconflict' => 'Ανταγωνιστικές επεξεργασίες: $1',
+
+'explainconflict' => 'Κάποιος άλλος χρήστης έχει αλλάξει αυτή τη σελίδα από τότε που αρχίσατε να την επεξεργάζεστε. Στο επάνω τμήμα βρίσκεται το τρέχον κείμενο της σελίδας. Οι δικές σας αλλαγές εμφανίζονται στο κάτω τμήμα. Θα πρέπει να ενσωματώσετε εσείς τις αλλαγές σας στο τρέχον κείμενο. <b>Μόνον</b> το επάνω τμήμα θα αποθηκευθεί όταν πατήσετε "Αποθήκευση σελίδας".<p>',
+
+'yourtext' => 'Το κείμενό σας',
+'storedversion' => 'Αποθηκευμένη έκδοση',
+
+'nonunicodebrowser' => '<strong>ΠΡΟΣΟΧΗ! Ο browser σας δεν είναι συμβατός με unicode. Παρακαλούμε χρησιμοποιήστε έναν άλλο browser για επεξεργαστείστε αυτό το άρθρο έτσι ώστε να αποδοθούν σωστά όλοι οι ελληνικοί χαρακτήρες. </strong><br />',
+
+'editingold' => '<strong>ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Επεξεργάζεστε μια παλιότερη αναθεώρηση αυτής της σελίδας. Αν προσπαθείστε να την αποθηκεύσετε, όσες αλλαγές έχουν γίνει πριν από αυτή την αναθεώρηση θα χαθούν.</strong><br />',
+
+'yourdiff' => 'Διαφορές',
+
+'copyrightwarning' => 'Ολες οι προσθήκες/ αλλαγές στο {{SITENAME}} θα πρέπει να συμφωνούν με την $2 (Βλ. $1 για λεπτομέρειες).
+Αν δεν επιθυμείτε τα κείμενά σας να τα επεξεργαστούν κατά την κρίση τους άλλοι χρήστες και να τα διαδώσουν κατά βούληση παρακαλούμε να μην τα αναρτήσετε σε αυτό το χώρο. Ότι συνεισφέρετε στο χώρο αυτό σε κείμενα, διαγράμματα, στοιχεία ή εικόνες πρέπει να είναι δικά σας έργα ή να ανήκουν στο δημόσιο τομέα (public domain) ή να προέρχονται από ελεύθερες ή ανοιχτές πηγές με ρητή άδεια αναδημοσίευσης. <br />
+
+Τέλος μας υπόσχεστε και δηλώνετε πως ότι γράφετε σε αυτό τον χώρο είναι πρωτότυπο δικό σας έργο και, άσχετα με την έκτασή του, δεν έχει εκχωρηθεί σε τρίτους η δημοσίευση και η εκμετάλλευσή του.
+<strong>ΠΑΡΑΚΑΛΟΥΜΕ ΝΑ ΜΗΝ ΑΝΑΡΤΗΣΕΤΕ ΚΕΙΜΕΝΑ ΤΡΙΤΩΝ ΕΑΝ ΔΕΝ ΕΧΕΤΕ ΤΗΝ ΑΔΕΙΑ ΤΟΥ ΙΔΙΟΚΤΗΤΗ ΤΟΥ COPYRIGHT!</strong>',
+
+'copyrightwarning2' => 'Έχετε υπ\' όψη σας ότι όλες οι προσθήκες/αλλαγές που κάνετε στο {{SITENAME}} μπορούν να υποστούν επεξεργασία και αλλαγές ή ακόμα και να διαγραφούν από άλλους χρήστες.
+Αν δεν επιθυμείτε τα κείμενά σας να τα επεξεργαστούν κατά την κρίση τους άλλοι χρήστες και να τα διαδώσουν κατά βούληση παρακαλούμε να μην τα αναρτήσετε σε αυτό το χώρο. Ότι συνεισφέρετε στο χώρο αυτό σε κείμενα, διαγράμματα, στοιχεία ή εικόνες πρέπει να είναι δικά σας έργα ή να ανήκουν στο δημόσιο τομέα (public domain) ή να προέρχονται από ελεύθερες ή ανοιχτές πηγές με ρητή άδεια αναδημοσίευσης. <br />
+Τέλος μας υπόσχεστε και δηλώνετε πως ότι γράφετε σε αυτό τον χώρο είναι πρωτότυπο δικό σας έργο και, άσχετα με την έκτασή του, δεν έχει εκχωρηθεί σε τρίτους η δημοσίευση και η εκμετάλλευσή του.
+<strong>ΠΑΡΑΚΑΛΟΥΜΕ ΝΑ ΜΗΝ ΑΝΑΡΤΗΣΕΤΕ ΚΕΙΜΕΝΑ ΤΡΙΤΩΝ ΕΑΝ ΔΕΝ ΕΧΕΤΕ ΤΗΝ ΑΔΕΙΑ ΤΟΥ ΙΔΙΟΚΤΗΤΗ ΤΟΥ COPYRIGHT!</strong>',
+
+'longpagewarning' => 'ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η σελίδα έχει μέγεθος $1kb. Είναι πιθανόν μερικοί browser να παρουσιάσουν προβλήματα στην επεξεργασία σελίδων της τάξης των 32kb και άνω. Μπορείτε να αποφύγετε το πρόβλημα κόβωντας τη σελίδα σε μικρότερα τμήματα.<br />',
+
+'readonlywarning' => 'ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η βάση δεδομένων έχει κλειδωθεί προσωρινά για συντήρηση και δεν θα μπορέσετε να αποθηκεύσετε αυτά που έχετε επεξεργαστεί. Μπορείτε αν θέλετε να αποθηκεύσετε το κείμενο στον υπολογιστή σας (με αποκοπή-και-επικόλληση) και να το ξαναχρησιμοποιήσετε αργότερα όταν η συντήρηση θα έχει ολοκληρωθεί.',
+
+'protectedpagewarning' => 'ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η σελίδα αυτή έχει κλειδωθεί -η οποιαδήποτε επεξεργασία της μπορεί να γίνει μόνον από διαχειριστές. Βεβαιωθείτε πως ακολουθείτε [[{{ns:4}}:Σελίδες_υπό_προστασία|τους κανόνες για τις υπό προστασία σελίδες]].<br />',
+
+'templatesused' => 'Πρότυπα που χρησιμοποιήθηκαν στη σελίδα αυτή:',
+
+
+# History pages
+#----------------------#
+'revhistory' => 'Ιστορικό αναθεωρήσεων',
+'nohistory' => 'Δεν υπάρχει ιστορικό επεξεργασίας για αυτή τη σελίδα.',
+'revnotfound' => 'Η αναθεώρηση δεν βρέθηκε.',
+'revnotfoundtext' => 'Η παλιά αναθεώρηση της σελίδας που ζητήσατε δεν ήταν δυνατόν να βρεθεί. Παρακαλούμε ελέγξτε τo URL που χρησιμοποιήσατε για να φτάσετε σε αυτήν τη σελίδα.',
+'loadhist' => 'Φόρτωση ιστορικού σελίδας',
+'currentrev' => 'Τρέχουσα αναθεώρηση',
+'revisionasof' => 'Αναθεώρηση της $1',
+'previousrevision' => '&larr;Παλιότερη αναθεώρηση',
+'nextrevision' => 'Νεώτερη αναθεώρηση&rarr;',
+'currentrevisionlink' => 'εμφάνιση της τρέχουσας αναθεώρησης',
+'cur' => 'τρέχουσα',
+'next' => 'επόμενη',
+'last' => 'τελευταία',
+'orig' => '\'πρωτότυπη\'',
+
+'histlegend' => 'Σύγκριση διαφορών: Επιλέξτε τις εκδόσεις που θέλετε να συγκρίνετε και πατήστε enter ή κάντε κλικ στην μπάρα "Σύγκριση...". <br />
+Υπόμνημα: (τρέχον) = διαφορές με την τρέχουσα έκδοση,
+(τελευταίο) = διαφορές με την προηγούμενη έκδοση, μ = αλλαγές μικρής κλίμακας.',
+
+'deletedrev' => '[διαγράφτηκε]',
+'histfirst' => 'Η πιο παλιά',
+'histlast' => 'Η πιο πρόσφατη',
+
+
+# Diffs
+#--------#
+'difference' => '(Διαφορές μεταξύ αναθεωρήσεων)',
+'loadingrev' => 'φόρτωση αναθεώρησης για \'σύγκριση\'',
+'lineno' => 'Γραμμή $1:',
+'editcurrent' => 'Επεξεργασία της τρέχουσας έκδοσης της σελίδας',
+'selectnewerversionfordiff' => 'Επιλέξτε μια πιο πρόσφατη έκδοση για σύγκριση.',
+'selectolderversionfordiff' => 'Επιλέξτε μια παλιότερη έκδοση για σύγκριση.',
+'compareselectedversions' => 'Σύγκριση των εκδόσεων που έχουν επιλεγεί',
+
+
+# Search results
+#------------------------#
+'searchresults' => 'Αποτελέσματα αναζήτησης',
+'searchresulttext' => 'Για περισσότερες πληροφορίες σχετικά με την αναζήτηση στο {{SITENAME}}, βλ. [[{{ns:12}}:Αναζήτηση|Αναζήτηση στο {{SITENAME}}]].',
+'searchsubtitle' => 'Κριτήρια αναζήτησης: "[[:$1]]"',
+'searchsubtitleinvalid' => 'Κριτήρια αναζήτησης: "$1"',
+'badquery' => 'Λανθασμένη μορφή αιτήματος αναζήτησης',
+
+'badquerytext' => 'Το σύστημα δεν μπόρεσε να επεξεργαστεί το αίτημα σας. Αυτό πιθανόν οφείλεται στο ότι αναζητήσατε μια λέξη με λιγότερα από τρία γράμματα (κάτι που δεν υποστηρίζεται προς το παρόν). Μπορεί επίσης να οφείλεται σε λάθος πληκτρολόγησης π.χ. "Διάλογος και διαλούβευση". Παρακαλoύμε δοκιμάστε πάλι.',
+
+'matchtotals' => 'Το αίτημα "$1" βρήκε $2 παρόμοιους τίτλους σελίδων και παρόμοιο κείμενο σε $3 σελίδες',
+'noexactmatch' => 'Δεν υπάρχει καμμία σελίδα με αυτόν ακριβώς τον τίτλο -έγινε αναζήτηση με το πλήρες κείμενο.',
+'titlematches' => 'Τίτλοι άρθρων που ανταποκρίνονται',
+'notitlematches' => 'Δεν υπάρχουν αντίστοιχοι τίτλοι σελίδων.',
+'textmatches' => 'Κείμενα σελίδων που ανταποκρίνονται:',
+'notextmatches' => 'Δεν υπάρχουν αντίστοιχα κείμενα σελίδων.',
+'prevn' => '$1 προηγουμένων',
+'nextn' => '$1 επομένων',
+'viewprevnext' => 'Εμφάνιση ($1) ($2) ($3).',
+'showingresults' => 'Εμφάνιση <b>$1</b> αποτελεσμάτων που αρχίζουν με #<b>$2</b>',
+'showingresultsnum' => 'Εμφάνιση <b>$3</b> αποτελεσμάτων που αρχίζουν με #<b>$2</b>',
+
+'nonefound' => '\'\'\'Σημείωση\'\'\': Οι ανεπιτυχείς αναζητήσεις οφείλονται συνήθως στο ότι έχουμε συμπεριλάβει στα κριτήρια πολύ συνηθισμένες λέξεις, όπως "έχει" ή "από" (που δεν υπάρχουν στο ευρετήριο) ή στο ότι προκαθορίσαμε πολλά κριτήρια αναζήτησης ταυτοχρόνως. (Στην τελευταία περίπτωση, μόνον οι σελίδες που περιέχουν \'\'όλα\'\' τα κριτήρια αναζήτησης θα εμφανιστούν στα αποτελέσματα).<br />',
+
+'powersearch' => 'Αναζήτηση',
+
+'powersearchtext' => 'Αναζήτηση στις περιοχές :<br />
+
+$1<br />
+$2 Εμφάνιση ανακατευθύνσεων &nbsp; Κριτήρια αναζήτησης $3 $9',
+
+'blanknamespace' => '(Αρχική περιοχή)',
+
+
+# Preferences page
+#-----------------------------#
+'preferences' => 'Προτιμήσεις',
+'prefsnologin' => 'Δεν έχετε συνδεθεί.',
+
+'prefsnologintext' => 'Πρέπει να έχετε [[Special:Userlogin|συνδεθεί]]
+για να καθορίσετε τις προτιμήσεις χρήστη.',
+
+
+'prefsreset' => 'Οι προτιμήσεις σας έχουν αποκατασταθεί σύμφωνα με την αποθηκευμένη έκδοσή τους.',
+'changepassword' => 'Αλλαγή κωδικού',
+'skin' => 'Οπτική οργάνωση (skin)',
+'math' => 'Απόδοση μαθηματικών',
+'dateformat' => 'Μορφή ημερομηνίας',
+'math_failure' => 'Δεν μπόρεσε να γίνει ανάλυση του όρου.',
+'math_unknown_error' => 'Άγνωστο λάθος',
+'math_unknown_function' => 'άγνωστη συνάρτηση',
+'math_lexing_error' => 'Σφάλμα στην λεξική ανάλυση',
+'math_syntax_error' => 'Λάθος σύνταξης',
+'math_image_error' => 'Η μετατροπή σε PNG απέτυχε. Παρακαλούμε ελέγξτε ότι έχουν εγκατασταθεί σωστά τα latex, dvips, gs, και ξαναπροσπαθήστε!',
+'math_bad_tmpdir' => 'Δεν είναι δυνατή η δημιουργία μαθηματικών δεδομένων (ή η εγγραφή σε προσωρινό κατάλογο)',
+'math_bad_output' => 'Δεν είναι δυνατή η δημιουργία μαθηματικών δεδομένων (ή η εγγραφή σε κατάλογο εξόδου)',
+'math_notexvc' => 'Αγνοείται το εκτελέσιμο texvc -παρακαλούμε συμβουλευτείτε το math/README για να ρυθμίσετε τις παραμέτρους.',
+'prefs-personal' => 'Στοιχεία χρήστη',
+'prefs-rc' => 'Πρόσφατες αλλαγές και εμφάνιση πολύ σύντομων άρθρων',
+'prefs-misc' => 'Διάφορες ρυθμίσεις',
+'saveprefs' => 'Αποθήκευση προτιμήσεων',
+'resetprefs' => 'Επαναφορά προτιμήσεων',
+'oldpassword' => 'Παλιός κωδικός',
+'newpassword' => 'Νέος κωδικός πρόσβασης',
+'retypenew' => 'Πληκτρολογήστε ξανά το νέο κωδικό.',
+'textboxsize' => 'Επεξεργασία',
+'rows' => 'Σειρές',
+'columns' => 'Στήλες',
+'searchresultshead' => 'Αποτελέσματα αναζήτησης/Ρυθμίσεις',
+'resultsperpage' => 'Αποτελέσματα ανά σελίδα',
+'contextlines' => 'Σειρές που θα εμφανίζονται ανά αποτέλεσμα',
+'contextchars' => 'Αριθμός χαρακτήρων στο εμφανιζόμενο κείμενο',
+'stubthreshold' => 'Ελάχιστο μέγεθος πολύ σύντομων σελίδων (stub)',
+'recentchangescount' => 'Αριθμός τίτλων στις πρόσφατες αλλαγές',
+'savedprefs' => 'Οι προτιμήσεις σας έχουν αποθηκευθεί.',
+'timezonelegend' => 'Ζώνη ώρας (Time zone)',
+'timezonetext' => 'Συμπληρώστε τον αριθμό των ωρών κατά τις οποίες η τοπική σας ώρα διαφέρει από την ώρα του server (UTC).',
+'localtime' => 'Εμφάνιση τοπικής ώρας',
+'timezoneoffset' => 'Διαφορά ωρών',
+'servertime' => 'Η ώρα του server είναι:',
+'guesstimezone' => 'Συμπλήρωση μέσω του browser',
+'defaultns' => 'Προκαθορισμένη αναζήτηση στις περιοχές:',
+'default' => 'Προκαθορισμένο',
+'files' => 'Αρχεία',
+
+
+# User levels special page
+#--------------------------------------#
+
+# switching pan
+
+'userrights-lookup-user' => 'Διαχείριση ομάδων χρηστών',
+'userrights-user-editname' => 'Δηλώστε όνομα χρήστη:',
+'editusergroup' => 'Επεξεργασία \'Ομάδα Χρηστών\'',
+
+# user groups editing
+#
+'userrights-editusergroup' => 'Επεξεργασία ομάδων χρηστών',
+'saveusergroups' => 'Αποθήκευση ομάδων χρηστών',
+'userrights-groupsmember' => 'Μελος της ομάδας:',
+'userrights-groupsavailable' => 'Υπάρχουσες ομάδες:',
+
+'userrights-groupshelp' => 'Επιλέξτε όμάδες στις οποίες επιθυμείτε να προστεθεί ο χρήστης ή ομάδες από τις οποίες επιθυμείτε να αφαιρεθεί ο χρήστης. Μπορείτε να αναιρέσετε την επιλογή μιας ομάδας με το πλήκτο CTRL + αριστερό κλικ',
+
+# Recent changes
+#--------------------------#
+'changes' => 'αλλαγές',
+'recentchanges' => 'Πρόσφατες αλλαγές',
+'recentchangestext' => 'Παρακολουθείστε σε αυτή τη σελίδα τις πιο πρόσφατες αλλαγές στο Wiki.',
+'rcnote' => 'Ακολουθούν οι <strong>$1</strong> πιο πρόσφατες αλλαγές στο διάστημα των τελευταίων <strong>$2</strong> ημερών.',
+'rcnotefrom' => 'Ακολουθούν οι αλλαγές από <b>$2</b> (εμφάνιση <b>$1</b> αλλαγών max).',
+'rclistfrom' => 'Εμφάνιση νέων αλλαγών αρχίζοντας από $1',
+'rclinks' => 'Εμφάνιση των τελευταίων $1 αλλαγών στο διάστημα των τελευταίων $2 ημερών <br />$3',
+'diff' => '\'διαφορά\'',
+'hist' => '\'ιστορικό\'',
+'hide' => 'απόκρυψη',
+'show' => 'εμφάνιση',
+'minoreditletter' => 'μ',
+'newpageletter' => 'N',
+#'sectionlink' => '&rarr;',
+'number_of_watching_users_pageview' => '[$1 χρήστης (-ες) που παρακολουθούν]',
+
+
+# Upload
+#------------#
+'upload' => 'Φόρτωση αρχείου',
+'uploadbtn' => 'Φόρτωση αρχείου',
+'reupload' => 'Επανάληψη φόρτωσης',
+'reuploaddesc' => 'Επιστροφή στη φόρμα φόρτωσης',
+'uploadnologin' => 'Δεν έχετε συνδεθεί!',
+'uploadnologintext' => 'Για να φορτώσετε αρχεία πρέπει πρώτα να [[Special:Userlogin|συνδεθείτε]].',
+'upload_directory_read_only' => 'Δεν είναι δυνατή η εγγραφή στον κατάλογο ($1) από τον server.',
+'uploaderror' => 'Σφάλμα στη φόρτωση αρχείου',
+
+'uploadtext' => '\'\'\'ΠΕΡΙΜΕΝΕΤΕ!\'\'\' Πριν προχωρήσετε στη φόρτωση αρχείων σε αυτό το χώρο βεβαιωθείτε πως διαβάσατε και πως ακολουθείτε τους [[{{ns:4}}:Κανόνες_χρήσης_εικόνων|Κανόνες χρήσης εικόνων]].
+
+Μπορείτε να δείτε ή να αναζητήσετε εικόνες που έχουν φορτωθεί κατά το παρελθόν κάτω από το σύνδεσμο [[Special:Imagelist|Κατάλογος εικόνων που έχουν φορτωθεί]].
+Οι φορτώσεις και οι διαγραφές έχουν καταγραφεί στη σελίδα
+[[{{ns:4}}:Καταγραφές_φόρτωσης|Καταγραφές φόρτωσης]].
+
+Χρησιμοποιήστε την παρακάτω φόρμα για να φορτώσετε νέα αρχεία εικόνας που θα χρησιμοποιηθούν στον οπτικό εμπλουτισμό των σελίδων. Στους περισσότερους browsers υπάρχει ένα κουμπί "Browse..." το οποίο εμφανίζει το πεδίο διαλόγου του συστήματός σας για το άνοιγμα αρχείων. Αν επιλέξετε ένα αρχείο, το όνομά τoυ θα συμπληρωθέι αυτόματα στο πεδίο κειμένου που βρίσκεται δίπλα στο κουμπί. Μην ξεχάστε να επιβεβαιώσετε (σημειώνοντας το ανάλογο κουτάκι) πως με τη φόρτωση του συγκεκριμένου αρχείου δεν παραβιάζετε πνευματικά δικαιώματα.
+
+Πατήστε το κουμπί "Upload" για να ολοκληρωθέι η φόρτωση.
+Η διαδικασία μπορεί να διαρκέσει λίγο περισσότερο αν διαθέτετε αργή σύνδεση με το internet.
+
+Οι προτιμώμενες μορφές αρχείου είναι: JPEG για φωτογραφίες, PNG για σχήματα και άλλες εικόνες και OGG για αρχεία ήχου. Δώστε περιγραφικά ονόματα στα αρχεία σας για να αποφευχθεί τυχόν σύγχυση.
+
+Για να συμπεριληφθεί μια εικόνα σε μια σελίδα, χρησιμοποιήστε συνδέσμους της μορφής
+\'\'\'<nowiki>[[{{ns:6}}:file.jpg]]</nowiki>\'\'\' ή
+\'\'\'<nowiki>[[{{ns:6}}:file.png|alt text]]</nowiki>\'\'\' ή
+\'\'\'<nowiki>[[{{ns:-2}}:file.ogg]]</nowiki>\'\'\' για αρχεία ήχου.
+
+Σας παρακαλούμε να λάβετε υπ΄όψη σας ότι, ακριβώς όπως συμβαίνει με τις σελίδες Wiki, είναι δυνατόν άλλοι χρήστες να επεξεργαστούν ή να διαγράψουν κατά την κρίση τους αρχεία που έχετε φορτώσει. Έχετε επίσης υπ΄όψη σας πως είναι δυνατόν να υποστείτε φραγή σαν χρήστης αν διαπιστωθεί πως έχετε κάνει κατάχρηση του συστήματος.<br />',
+
+'uploadlog' => 'Φόρτωση αρχείου γεγονότων',
+'uploadlogpage' => 'Καταγραφές φόρτωσης',
+'uploadlogpagetext' => 'Ακολουθεί κατάλογος των αρχείων που έχουν φορτωθεί πρόσφατα.',
+'filename' => 'Όνομα αρχείου',
+'filedesc' => 'Σύνοψη',
+'filestatus' => 'Κατάσταση του copyright',
+'filesource' => 'Πηγή',
+'copyrightpage' => 'Project:Copyrights',
+'copyrightpagename' => '{{SITENAME}} copyright',
+'uploadedfiles' => 'Αρχεία που έχουν φορτωθεί',
+'minlength' => 'Τα ονόματα εικόνων δεν πρέπει να περιέχουν λιγότερους από τρεις χαρακτήρες.',
+'illegalfilename' => 'Το όνομα του αρχείου "$1" περιέχει χαρακτήρες που δεν επιτρέπονται στους τίτλους των σελίδων. Παρακαλούμε δώστε άλλο όνομα στο αρχείο και προσπαθήστε ξανά να το ανεβάσετε.',
+'badfilename' => 'Το όνομα της εικόνας άλλαξε σε "$1".',
+'badfiletype' => 'Το ".$1" δεν είναι προτεινόμενος τύπος εικόνας.',
+'largefile' => 'Συνιστούμε οι εικόνες να μην υπερβαίνουν σε μέγεθος τα 100k .',
+
+'emptyfile' => 'Το αρχείο που φορτώσατε φαίνεται να είναι κενό. Αυτό μπορεί να οφείλεται σε λάθος πληκτρολόγησης του ονόματος του αρχείου. Παρακαλούμε ελέγξτε εαν αυτό είναι πραγματικά το αρχείο που θέλετε να φορτώσετε.',
+
+'fileexists' => 'Υπάρχει ήδη αρχείο με αυτό το όνομα -παρακαλούμε ελέγξτε στο $1. Είστε βέβαιος (-η) πως θέλετε να αλλάξετε το όνομα του αρχείου;',
+'successfulupload' => 'Επιτυχής φόρτωση',
+
+'fileuploaded' => 'Το αρχείο $1 φορτώθηκε επιτυχώς!
+Παρακαλούμε ακολουθήστε το σύνδεσμο: $2 προς τη σελίδα της περιγραφής και συμπληρώστε πληροφορίες σχετικές με το αρχείο, όπως το από πού προήλθε, πότε δημιουργήθηκε και από ποιόν, και οτιδήποτε άλλο γνωρίζετε σχετικά με αυτό. Αν πρόκειται για εικόνα μπορείτε να την ενθέσετε με τον εξής τρόπο: <tt><nowiki>[[{{ns:6}}:$1|thumb|Description]]</nowiki></tt>',
+
+'uploadwarning' => 'Προειδοιποίηση φόρτωσης',
+'savefile' => 'Αποθήκευση αρχείου',
+'uploadedimage' => 'Η φόρτωση του "$1" ολοκληρώθηκε.',
+'uploaddisabled' => 'Λυπούμαστε, η φόρτωση έχει απενεργοποιηθεί.',
+'uploadscripted' => 'Αυτό το αρχείο περιέχει κώδικα HTML ή script που μπορεί να παρερμηνευθεί από μερικούς browser.',
+'uploadcorrupt' => 'Το αρχείο είναι κατεστραμένο ή έχει κάποια λανθασμένη επέκταση. Παρακαλούμε ελέγξτε το και ξαναδοκιμάστε να το ανεβάσετε.',
+'uploadvirus' => 'Το αρχείο περιέχει ιό! Λεπτομέρειες: $1',
+'sourcefilename' => 'Όνομα πηγαίου αρχείου',
+'destfilename' => 'Όνομα αρχείου προορισμού',
+
+
+# Image list
+#----------------#
+'imagelist' => 'Κατάλογος εικόνων',
+'imagelisttext' => 'Ακολουθεί κατάλογος $1 εικόνων ταξινομημένων κατά σειρά $2.',
+'getimagelist' => 'Προσκόμιση καταλόγου εικόνων',
+'ilsubmit' => 'Αναζήτηση',
+'showlast' => 'Εμφάνιση των $1 πιο πρόσφατων εικόνων κατά σειρά $2.',
+'byname' => 'ονόματος',
+'bydate' => 'ημερομηνίας',
+'bysize' => 'μεγέθους',
+'imgdelete' => '\'διαγραφή\'',
+'imgdesc' => '\'περιγραφή\'',
+'imglegend' => 'Υπόμνημα: (\'περιγραφή\') = εμφάνιση/επεξεργασία της περιγραφής εικόνας',
+'imghistory' => 'Ιστορικό εικόνας',
+'revertimg' => '\'επαναφορά\'',
+'deleteimg' => '\'διαγραφή\'',
+'deleteimgcompletely' => 'Διαγραφή όλων των αναθεωρήσεων',
+
+'imghistlegend' => 'Υπόμνημα: (\'τρέχον\') = αυτή είναι η τρέχουσα εικόνα, (\'διαγραφή\') = διαγραφή αυτής της παλιότερης έκδοσης, (\'επαναφορά\') = επαναφορά σε αυτή την παλιότερη έκδοση
+
+<br /><i>Κάνοντας κλικ στην ημερομηνία θα δείτε την εικόνα που φορτώθηκε εκείνη την ημέρα</i>.',
+
+'imagelinks' => 'Σύνδεσμοι εικόνων',
+'linkstoimage' => 'Οι ακόλουθες σελίδες συνδέονται με αυτή την εικόνα:',
+'nolinkstoimage' => 'Δεν υπάρχουν σελίδες που συνδέονται με αυτήν την εικόνα.',
+'sharedupload' => 'Το αρχείο αυτό φορτώθηκε για κοινή χρήση και είναι δυνατόν να χρησιμοποιείται ταυτοχρόνως σε περισσότερα από ένα έργα.',
+'shareduploadwiki' => 'Παρακαλούμε συμβουλευθείτε την [$1 σελίδα περιγραφής αρχείου] για περισσότερες πληροφορίες.',
+'noimage' => 'Δεν υπάρχει αρχείο με αυτό το όνομα, μπορείτε να [$1 το φορτώσετε].',
+'uploadnewversion-linktext' => 'Φορτώστε μια νέα έκδοση αυτού του αρχείου',
+
+
+# Statistics
+#---------------#
+'statistics' => 'Στατιστικές',
+'sitestats' => 'Στατιστικές ιστοχώρου',
+'userstats' => 'Στατιστικές χρηστών',
+
+'sitestatstext' => 'Υπάρχουν συνολικά \'\'\'$1\'\'\' σελίδες στη βάση δεδομένων. Σε αυτές συμπεριλαμβάνονται και οι σελίδες "συζήτησης", σελίδες σχετικά με το {{SITENAME}}, σελίδες με πολύ σύντομο κείμενο (stub), ανακατευθύνσεις, και άλλες που πιθανόν να μην χαρακτηρίζονται σελίδες-με- κείμενο (ή περιεχόμενο).
+Επιπλέον υπάρχουν και \'\'\'$2\'\'\' άλλες σελίδες που πληρούν τα κριτήρια και χαρακτηρίζονται, επίσης, σελίδες περιεχομένου.
+
+Από τη στιγμή που δημιουργήθηκε αυτό το Wiki έχουν καταγραφεί \'\'\'$3\'\'\' επισκέψεις σε σελίδες και \'\'\'$4\'\'\' επεξεργασίες σε σελίδες.
+Ο μέσος όρος κατά την τελευταία ενημέρωση ήταν \'\'\'$5\'\'\' επεξεργασίες ανά σελίδα και \'\'\'$6\'\'\' επισκέψεις ανά επεξεργασία.',
+
+'userstatstext' => 'Υπάρχουν \'\'\'$1\'\'\' εγγεγραμένοι χρήστες.
+\'\'\'$2\'\'\' από αυτούς είναι διαχειριστές (βλ. $3 | διαχειριστές).',
+
+
+# Maintenance Page
+#-----------------------------#
+'disambiguations' => 'Σελίδες αποσαφήνισης',
+'disambiguationspage' => '{{ns:4}}:Σύνδεσμοι_προς_τις_σελίδες_αποσαφήνισης',
+
+'disambiguationstext' => 'Οι σελίδες που ακολουθούν συνδέονται με μια <i>σελίδα αποσαφήνισης</i> ενώ θα έπρεπε κανονικά να συνδέονται με το αντίστοιχο θέμα.<br />Μια σελίδα θεωρείται σελίδα αποσαφήνισης όταν συνδέεται μέσω της $1.<br />Σύνδεσμοι μέσα από άλλες περιοχές <i>δεν</i> περιλαμβάνονται σε αυτό τον κατάλογο.',
+
+'doubleredirects' => 'Διπλές ανακατευθύνσεις',
+
+'doubleredirectstext' => 'Κάθε σειρά περιέχει συνδέσμους προς την πρώτη και τη δεύτερη σελίδα ανακατεύθυνσης, όπως επίσης και την πρώτη αράδα του κειμένου στη δεύτερη σελίδα ανακατεύθυνσης η οποία και είναι, κανονικά, ο πραγματικός προορισμός της ανακατεύθυνσης -εκεί δηλαδή όπου θα έπρεπε να είχατε οδηγηθεί από την αρχή.',
+
+'brokenredirects' => 'Κατεστραμένες ανακατευθύνσεις',
+'brokenredirectstext' => 'Οι παρακάτω ανακατευθύνσεις οδηγούν σε σελίδες που δεν υπάρχουν.',
+
+# Miscellaneous special pages
+#
+'lonelypages' => 'Ορφανές σελίδες',
+'uncategorizedpages' => 'Αταξινόμητες σελίδες',
+'uncategorizedcategories' => 'Αταξινόμητες κατηγορίες',
+'unusedcategories' => 'Κενές κατηγορίες',
+'unusedimages' => 'Αχρησιμοποίητες εικόνες',
+'popularpages' => 'Δημοφιλείς σελίδες',
+'nviews' => '$1 επισκέψεις',
+'wantedpages' => 'Σελίδες σε ζήτηση',
+'mostlinked' => 'Οι σελίδες με τις περισσότερες αναφορές',
+'nlinks' => '$1 σύνδεσμοι',
+'allpages' => 'Όλες οι σελίδες',
+'randompage' => 'Σελίδα στην τύχη',
+'shortpages' => 'Σύντομες σελίδες',
+'longpages' => 'Εκτενείς σελίδες',
+'deadendpages' => 'Αδιέξοδες σελίδες',
+'listusers' => 'Κατάλογος χρηστών',
+'specialpages' => 'Σελίδες λειτουργιών',
+'spheading' => 'Σελίδες λειτουργιών για όλους τους χρήστες',
+'restrictedpheading' => 'Ειδικές σελίδες με περιορισμούς πρόσβασης',
+'recentchangeslinked' => 'Σχετικές αλλαγές',
+'rclsub' => '(σε σελίδες που συνδέονται από το "$1")',
+'newpages' => 'Νέες σελίδες',
+'ancientpages' => 'Οι παλιότερες σελίδες',
+'intl' => 'Διαγλωσσικοί σύνδεσμοι',
+'move' => 'Μετακίνηση',
+'movethispage' => 'Μετακίνηση αυτής της σελίδας',
+
+'unusedimagestext' => '<p>Παρακαλούμε να λάβετε υπ` όψη σας πως άλλες ιστοσελίδες είναι δυνατόν να συνδέονται με μια εικόνα με απευθείας URL - για το λόγο αυτό μπορεί μερικές εικόνες να εμφανίζονται ακόμα εδώ παρόλο που στην πραγματικότητα είναι σε χρήση.</p>',
+
+'unusedcategoriestext' => 'Οι ακόλουθες κατηγοριοποιημένες σελίδες δεν συνδέονται με άλλο άρθρο ή κατηγορία.',
+'booksources' => 'Πηγές βιβλίων',
+'categoriespagetext' => 'Υπάρχουν οι ακόλουθες κατηγορίες στο Wiκi.',
+'data' => 'Δεδομένα',
+'userrights' => 'Διαχείριση δικαιωμάτων χρηστών',
+'groups' => 'Ομάδες χρηστών',
+
+'booksourcetext' => 'Ακολουθούν σύνδεσμοι για διαδικτυακούς τόπους που εμπορεύονται καινούργια ή μεταχειρισμένα βιβλία και όπου μπορείτε να αναζητήσετε τα βιβλία που σας ενδιαφέρουν. Το {{SITENAME}} δεν έχει σχέση με αυτές τις επιχειρήσεις και ο κατάλογος αυτός δεν αποτελεί κατά κανένα τρόπο προώθηση ή διαφήμισή τους.',
+
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 έως $2',
+'version' => 'Έκδοση',
+'log' => 'Καταγραφές γεγονότων',
+
+'alllogstext' => 'Εποπτική εμφάνιση όλων των ενεργειών φόρτωσης αρχείων, διαγραφής, προστασίας, φραγής και όλων των καταγραφών των διαχειριστών στο αρχείο γεγονότων. Μπορείτε να περιορίσετε τα αποτελέσματα που εμφανίζονται επιλέγοντας συγκεκριμένο είδος γεγονότων, όνομα χρήστη ή τη σελίδα που επηρεάστηκε.',
+
+
+# Special:Allpages
+#--------------------------#
+'nextpage' => 'Επόμενη σελίδα ($1)',
+'allpagesfrom' => 'Εμφάνιση όλων των σελίδων που αρχίζουν στο:',
+'allarticles' => 'Όλα τα άρθρα',
+'allinnamespace' => 'Όλες οι σελίδες (στην περιοχή $1)',
+'allnotinnamespace' => 'Όλες οι σελίδες (που δεν βρίσκονται στην περιοχή $1)',
+'allpagesprev' => 'Προηγούμενες',
+'allpagesnext' => 'Επόμενες',
+'allpagessubmit' => 'Μετάβαση',
+
+
+# E this user
+#-----------------#
+'mailnologin' => 'Δεν υπάρχει διεύθυνση παραλήπτη.',
+
+'mailnologintext' => 'Πρέπει να έχετε [[Special:Userlogin|συνδεθεί]] και να έχετε δηλώσει
+μια έγκυρη ηλεκτρονική διεύθυνση στις [[Special:Preferences|Προτιμήσεις]]
+για να στείλετε e-mail σε άλλους χρήστες.',
+
+'emailuser' => 'Στείλτε e-mail σε αυτόν το χρήστη',
+'emailpage' => 'Αποστολή e-mail σε χρήστη',
+
+'emailpagetext' => 'Συπληρώνοντας την παρακάτω φόρμα θα στείλετε ένα μήνυμα εφόσον ο παραλήπτης έχει δηλώσει μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου στις \'προτιμήσεις χρήστη\'. Η διεύθυνση ηλεκτρονικού ταχυδρομείου που έχετε δηλώσει στις δικές σας \'προτιμήσεις χρήστη\' θα εμφανιστεί ως διεύθυνση αποστολέα του μηνύματος, ούτως ώστε ο παραλήπτης να μπορέσει να σας απαντήσει.',
+
+'usermailererror' => 'Σφάλμα ηλεκτρονικού ταχυδρομείου:',
+'defemailsubject' => 'Ηλεκτρονικό ταχυδρομείο {{SITENAME}}',
+'noemailtitle' => 'Δεν υπάρχει ηλεκτρονική διεύθυνση.',
+'noemailtext' => 'Ο χρήστης αυτός δεν έχει δηλώσει την ηλεκτρονική του διέθυνση ή έχει επιλέξει να μην δέχεται μηνύματα από άλλους χρήστες.',
+'emailfrom' => 'Αποστολέας',
+'emailto' => 'Προς',
+'emailsubject' => 'Θέμα',
+'emailmessage' => 'Μήνυμα',
+'emailsend' => 'Αποστολή',
+'emailsent' => 'Το μήνυμα έχει σταλεί',
+'emailsenttext' => 'Το μήνυμά σας έχει σταλεί.',
+
+
+# Watchlist
+#---------------#
+'watchlist' => 'Λίστα παρακολούθησης',
+'nowatchlist' => 'Δεν υπάρχουν εγγραφές στη λίστα παρακολούθησης.',
+'watchnologin' => 'Δεν έχετε συνδεθεί.',
+'watchnologintext' => 'Για να κάνετε αλλαγές στη λίστα παρακολούθησης πρέπει να <a href="{{localurl:Special:Userlogin}}"> συνδεθείτε </a>.',
+'addedwatch' => 'Η σελίδα έχει προστεθεί στη λίστα παρακολούθησης.',
+
+'addedwatchtext' => 'Η σελίδα "$1" έχει προστεθεί στη [[Special:Watchlist|λίστα παρακολούθησης]].
+Μελλοντικές αλλαγές στη σελίδα καθώς και στη σχετική με τη σελίδα συζήτηση θα φαίνονται \'\'\'με έντονα γράμματα\'\'\' στη [[Special:Recentchanges|λίστα πρόσφατων αλλαγών]] έτσι ώστε να διευκολύνεται η παρακολούθηση.
+
+
+<p>Αν θελήσετε να αφαιρέσετε τη σελίδα αυτή από τη λίστα παρακολούθησης, κάνετε κλικ στην επιλογή "παύση παρακολούθησης" στην μπάρα ενεργειών.',
+
+'removedwatch' => 'Αφαιρέθηκε απο τη λίστα παρακολούθησης.',
+'removedwatchtext' => 'Η σελίδα "$1" έχει αφαιρεθεί από τη λίστα παρακολούθησής σας.',
+'watch' => 'Παρακολούθηση',
+'watchthispage' => 'Παρακολούθηση αυτής της σελίδας',
+'unwatch' => 'Παύση παρακολούθησης',
+'unwatchthispage' => 'Παύση παρακολούθησης αυτής της σελίδας',
+'notanarticle' => 'Η σελίδα αυτή δεν είναι σελίδα περιεχομένου.',
+'watchnochange' => 'Δεν υπήρξε δραστηριότητα επεξεργασίας στις σελίδες που παρακολουθείτε κατά την εμφανιζόμενη χρονική περίοδο.',
+'watchdetails' => '(Υπό παρακολούθηση: $1 σελίδες, χωρίς τις σελίδες συζήτησης. $2 συνολικά σελίδες έχουν υποστεί επεξεργασία. $3... <a href="$4">Προβολή και επεξεργασία ολόκληρης της λίστας </a>)',
+'wlheader-enotif' => '* Η ειδοποίηση με ηλεκτρονικό ταχυδρομείο έχει ενεργοποιηθεί.',
+'wlheader-showupdated' => '* Σελίδες που έχουν υποστεί αλλαγές από την τελευταία φορά που τις επισκεφθήκατε εμφανίζονται με \'\'\'έντονους χαρακτήρες\'\'\'.',
+'watchmethod-recent' => 'Έλεγχος πρόσφατων αλλαγών σε σελίδες υπό παρακολούθηση',
+'watchmethod-list' => 'Έλεγχος σελίδων υπό παρακολούθηση για πρόσφατες αλλαγές',
+'removechecked' => 'Αφαίρεση επιλεγμένων σελίδων από τη λίστα παρακολούθησης',
+'watchlistcontains' => 'Η λίστα παρακολούθησής σας περιέχει $1 σελίδες.',
+
+'watcheditlist' => 'Ακολουθεί μια λίστα των σελίδων που παρακολουθείτε (κατά αλφαβητική σειρά). Σημειώστε τις σελίδες που επιθυμείτε να αφαιρέσετε από τη λίστα σας και επικυρώστε με ένα κλικ στο κουμπί \'αφαίρεση σελίδων\' στο κάτω μέρος της οθόνης.',
+
+'removingchecked' => 'Εξάλειψη των αντικειμένων που ζητήσατε να αφαιρεθούν από τη λίστα παρακολούθησης...',
+'couldntremove' => 'Δεν ήταν δυνατόν να εξαλειφθεί το στοιχείο $1...',
+'iteminvalidname' => 'Πρόβλημα με το στοιχείο "$1", άκυρο όνομα...',
+'wlnote' => 'Ακολουθούν οι $1 πιο πρόσφατες αλλαγές κατά τη διάρκεια των τελευταίων <b>$2</b> ωρών.',
+'wlshowlast' => 'Εμφάνιση των τελευταίων $1 ωρών $2 ημερών $3',
+'wlsaved' => 'Αποθηκευμένη έκδοση της λίστας παρακολούθησης',
+'wlhideshowown' => '$1 από τις επεξεργασίες μου',
+'enotif_mailer' => 'Σύστημα ειδοποίησης μέσω αλληλογραφίας του {{SITENAME}}',
+'enotif_reset' => 'Σημειώστε όλες τις σελίδες ως αναγνωσμένες.',
+'enotif_newpagetext' => 'Αυτή είναι μια νέα σελίδα.',
+'changed' => 'έχει αλλάξει',
+'created' => 'δημιουργήθηκε',
+'enotif_subject' => 'Η σελίδα $PAGETITLE του {{SITENAME}}έχει $CHANGEDORCREATED από το χρήστη $PAGEEDITOR',
+'enotif_lastvisited' => 'Δείτε το $1 για όλες τις αλλαγές που έγιναν από την τελευταία σας επίσκεψη.',
+'enotif_body' => 'Αγαπητέ $WATCHINGUSERNAME...
+
+Η σελίδα $PAGETITLE του {{SITENAME}}έχει $CHANGEDORCREATED στις $PAGEEDITDATE από το χρήστη $PAGEEDITOR -ακολουθήστε το σύνδεσμο $PAGETITLE_URL για να δείτε την τρέχουσα αναθεώρηση.
+
+$NEWPAGE
+
+Περιγραφή: $PAGESUMMARY $PAGEMINOREDIT
+
+Επικοινωνήστε με το συγκεκριμένο χρήστη:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Δεν θα υπάρξει άλλη ειδοποίηση για περαιτέρω αλλαγές αν δεν επισκεφθείτε τη σελίδα. Μπορείτε επίσης να επαναφέρετε την επιλογή ειδοποίησης για όλες τις σελίδες στη λίστα παρακολούθησής σας.
+
+Φιλικά,<<br />
+Tο σύστημα ειδοποίησης του {{SITENAME}}
+
+--
+Για να αλλάξετε τις προτιμήσεις της λίστας παρακολούθησής σας, ακολουθήστε το σύνδεσμο:
+{{fullurl:Special:Watchlist/edit}}
+
+Ερωτήσεις και περισσότερες πληροφορίες:
+{{fullurl:{{ns:12}}:Περιεχόμενα}}',
+
+
+# Delete/protect/revert
+#----------------------------------#
+'deletepage' => 'Διαγραφή σελίδας',
+'confirm' => 'Επιβεβαίωση',
+'excontent' => 'το περιεχόμενο ήταν:',
+'excontentauthor' => 'το περιεχόμενο ήταν: \'$1\' (και οι μοναδικές συνεισφορές ήταν του \'$2\')',
+'exbeforeblank' => 'το περιεχόμενο πριν απο την εκκαθάριση ήταν:',
+'exblank' => 'η σελίδα ήταν κενή',
+'confirmdelete' => 'Επιβεβαίωση διαγραφής',
+'deletesub' => '(Διαγραφή της "$1")',
+'historywarning' => 'ΠΡΟΕΙΔΟΠΟΙΗΣΗ! Η σελίδα που πρόκειται να διαγράψετε έχει ιστορικό.<br />',
+'confirmdeletetext' => 'Πρόκειται να διαγράψετε οριστικά από τη βάση δεδομένων μια σελίδα (ή μια εικόνα) μαζί με το ιστορικό της. Παρακαλούμε επιβεβαιώστε ότι θέλετε πραγματικά να το κάνετε, ότι αντιλαμβάνεσθε τις συνέπειες και ότι το κάνετε σύμφωνα με τους [[{{ns:4}}:Κανόνες|Κανόνες]].',
+'actioncomplete' => 'Η ενέργεια ολοκληρώθηκε.',
+'deletedtext' => 'Η "$1" έχει διαγραφεί.
+Για το ιστορικό των πρόσφατων διαγραφών ανατρέξτε στο σύνδεσμο $2',
+'deletedarticle' => 'Η $1 διαγράφτηκε.',
+'dellogpage' => 'Καταγραφές διαγραφών',
+'dellogpagetext' => 'Λίστα των πιο πρόσφατων διαγραφών',
+'deletionlog' => 'Καταγραφές διαγραφών',
+'reverted' => 'Επαναφορά σε προηγούμενη αναθεώρηση',
+'deletecomment' => 'Αιτιολογία διαγραφής',
+'imagereverted' => 'Η επαναφορά σε παλιότερη έκδοση ήταν επιτυχής.',
+'rollback' => 'Επαναφορά επεξεργασιών',
+'rollback_short' => 'Επαναφορά',
+'rollbacklink' => 'Επαναφορά στην προηγούμενη',
+'rollbackfailed' => 'Η επαναφορά απέτυχε.',
+'cantrollback' => 'Δεν είναι δυνατή η αναίρεση αυτής της αλλαγής, πρόκειται για την αρχική ενέργεια δημιουργίας της σελίδας.',
+
+'alreadyrolled' => 'Αδύνατον να αναιρεθεί η τελευταία αλλαγή της σελίδας [[:$1]]
+από το χρήστη [[User:$2|$2]] ([[User talk:$2|Συζήτηση]]), κάποιος έχει ήδη αναιρέσει την αλλαγή ή έχει αλλάξει εκ νέου τη σελίδα.
+
+Τελευταία αλλαγή από το χρήστη [[User:$3|$3]] ([[User talk:$3|Συζήτηση]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Το σχόλιο της επεξεργασίας ήταν: "<i>$1</i>".',
+'revertpage' => 'Ανάκληση των αλλαγών $2 (επιστροφή στην προηγούμενη αναθεώρηση $1)',
+
+'sessionfailure' => 'Υπάρχει πρόβλημα με τη σύνδεσή σας -η ενέργεια αυτή ακυρώθηκε προληπτικά για την αντιμετώπιση τυχόν πειρατείας συνόδου (session hijacking). Παρακαλoύμε πατήστε "Επιστροφή", ξαναφορτώστε τη σελίδα από την οποία φθάσατε εδώ και προσπαθήστε ξανά.',
+
+'protectlogpage' => 'Καταγραφές προστασίας (κλειδώματος)',
+
+'protectlogtext' => 'Ακολουθεί κατάλογος ενεργειών κλειδώματος και ξεκλειδώματος σελίδων.
+(Βλ. [[{{ns:4}}:Σελίδες_υπό_προστασία]] για περισσότερες πληροφορίες).',
+
+'protectedarticle' => 'Κλειδωμένο $1',
+'unprotectedarticle' => 'έχει αρθεί η προστασία του $1',
+'protectsub' => '(Κλειδώνεται η "$1")',
+'confirmprotecttext' => 'Θέλετε πραγματικά να κλειδώσετε αυτή τη σελίδα;',
+'confirmprotect' => 'Επιβεβαίωση κλειδώματος',
+'protectmoveonly' => 'Προστασία μόνον από μετακινήσεις',
+'protectcomment' => 'Αιτιολογία προστασίας',
+'unprotectsub' => '(Άρση προστασίας για το "$1")',
+'confirmunprotecttext' => 'Θέλετε πραγματικά να ξεκλειδώσετε αυτή τη σελίδα;',
+'confirmunprotect' => 'Επιβεβαίωση ξεκλειδώματος',
+'unprotectcomment' => 'Αιτιολογία για την άρση προστασίας',
+
+
+# Undelete
+#---------------#
+'undelete' => 'Αποκατάσταση σελίδων που έχουν διαγραφεί',
+'undeletepage' => 'Εμφάνιση και αποκατάσταση σελίδων που έχουν διαγραφεί',
+'undeletepagetext' => 'Οι σελίδες που ακολουθούν έχουν διαγραφεί αλλά βρίσκονται ακόμα αποθηκευμένες στο αρχείο και μπορούν να αποκατασταθούν. (Κατά καιρούς γίνεται εκκαθάριση του αρχείου.)',
+'undeletearticle' => 'Αποκατάσταση σελίδας που έχει διαγραφεί',
+'undeleterevisions' => '$1 αναθεωρήσεις έχουν αρχειοθετηθεί.',
+
+'undeletehistory' => 'Αν αποκαταστήσετε αυτή τη σελίδα, όλες οι αναθεωρήσεις θα αποκατασταθούν στο ιστορικό. Αν μετά τη διαγραφή αυτής της σελίδας έχει δημιουργηθεί μια νέα σελίδα με το ίδιο όνομα, οι αναθεωρήσεις που αποκαταστάθηκαν θα εμφανιστούν στο πρότερο ιστορικό και η τρέχουσα αναθεώρηση της σελίδας δεν θα αντικαταστθεί αυτομάτως.',
+
+'undeleterevision' => 'Αναθεώρηση που έχει διαγραφεί στις $1',
+'undeletebtn' => 'Αποκατάσταση!',
+'undeletedarticle' => 'αποκατάσταση "$1"',
+'undeletedrevisions' => 'Αποκατάσταση $1 αναθεωρήσεων',
+
+
+# Namespace form on various pages
+#-------------------------------------------------------#
+'namespace' => 'Περιοχή:',
+'invert' => 'Αντιστροφή της επιλογής',
+
+
+# Contributions
+#---------------------#
+'contributions' => 'Συνεισφορές χρήστη',
+'mycontris' => 'Οι προσθήκες μου',
+'contribsub' => 'Για τον/την $1',
+'nocontribs' => 'Δεν βρέθηκαν αλλαγές με αυτά τα κριτήρια.',
+'ucnote' => 'Ακολουθούν οι τελευταίες <b>$1</b> αλλαγές του χρήστη κατά τη διάρκεια των τελευταίων <b>$2</b> ημερών.',
+'uclinks' => 'Εμφάνιση των τελευταίων $1 αλλαγών - Εμφάνιση των τελευταίων $2 ημερών',
+'uctop' => ' (τελευταία)',
+'newbies' => 'νέοι χρήστες',
+
+
+# What links here
+#-------------------------#
+'whatlinkshere' => 'Αναφορές στη σελίδα',
+'notargettitle' => 'Δεν έχει καθοριστεί προορισμός.',
+'notargettext' => 'Δεν έχετε καθορίσει ένα χρήστη ή μια σελίδα προορισμού για να εκτελεσθεί αυτή η λειτουργία.',
+'linklistsub' => '(Κατάλογος συνδέσμων)',
+'linkshere' => 'Εδώ παραπέμπουν οι ακόλουθες σελίδες:',
+'nolinkshere' => 'Δεν υπάρχουν σελίδες με συνδέσεις προς τα εδώ.',
+'isredirect' => 'ανακατεύθυνση σελίδας',
+
+
+# Block/unblock IP
+#--------------------------#
+'blockip' => 'Φραγή χρήστη ή διεύθυνσης IP',
+
+'blockiptext' => 'Χρησιμοποιήστε την παρακάτω φόρμα για να εμποδίσετε παρεμβάσεις στο κείμενο από μια συγκεκριμένη διεύθυνση IP ή όνομα χρήστη.
+Το μέτρο αυτό πρέπει να λαμβάνεται μόνο σε περιπτώσεις βανδαλισμού σελίδων και πάντα σύμφωνα με τους [[{{ns:4}}:Κανόνες|Κανόνες]].
+Παρακαλούμε να αιτιολογήσετε την ενέργειά σας (παραπέμποντας π.χ. σε συγκεκριμένες σελίδες που υπέστησαν βανδαλισμό).',
+
+'ipaddress' => 'Διεύθυνση IP/όνομα χρήστη',
+'ipadressorusername' => 'Διεύθυνση IP ή όνομα χρήστη',
+'ipbexpiry' => 'Λήξη',
+'ipbreason' => 'Αιτιολογία',
+'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',
+'ipbotheroption' => 'άλλη',
+'badipaddress' => 'Άκυρη διεύθυνση IP.',
+'blockipsuccesssub' => 'Η φραγή ολοκληρώθηκε επιτυχώς.',
+'blockipsuccesstext' => 'Η διεύθυνση "$1" έχει υποστεί φραγή. <br />Δείτε τη [[Special:Ipblocklist|λίστα διευθύνσεων IP που έχουν υποστεί φραγή]] για να το επιβεβαιώσετε.',
+'unblockip' => 'Άρση φραγής χρήστη',
+'unblockiptext' => 'Χρησιμοποιήστε την παρακάτω φόρμα για να αποκαταστήσετε την πρόσβαση σε επεξεργασία, σε μια διεύθυνση IP ή σε ένα χρήστη που είχε αποκλειστεί με φραγή.',
+'ipusubmit' => 'Άρση φραγής αυτής της διεύθυνσης',
+'ipblocklist' => 'Λίστα διευθύνσεων IP και ονομάτων χρηστών που έχουν υποστεί φραγή.',
+'blocklistline' => 'Φραγή του/της $3 από τους $1, $2 (λήγει $4)',
+'blocklink' => 'φραγή',
+'unblocklink' => 'Άρση φραγής',
+'contribslink' => 'Συνεισφορές/Προσθήκες',
+'autoblocker' => 'Έχετε υποστεί αυτόματα φραγή από το σύστημα επειδή χρησιμοποιείτε την ίδια διεύθυνση IP με το χρήστη "$1". Αιτιολογία "$2".',
+'blocklogpage' => 'Καταγραφές φραγής',
+'blocklogentry' => 'Φραγή του/της "$1" με χρόνο λήξης $2',
+
+'blocklogtext' => 'Σε αυτή τη σελίδα υπάρχουν οι καταγραφές φραγής και κατάργησης φραγής των χρηστών (αρχείο γεγονότων).
+
+<br />Δεν συμπεριλαμβάνονται οι διευθύνσεις IP που υπέστησαν αυτόματα φραγή. <br />Στο σύνδεσμο [[Special:Ipblocklist|διευθύνεις IP που έχουν υποστεί φραγή]] θα βρείτε τον πλήρη κατάλογο με τις τρέχουσες φραγές.',
+
+'unblocklogentry' => 'Άρση φραγής του "$1"',
+'range_block_disabled' => 'Η δυνατότητα του διαχειριστή να δημιουργεί περιοχές φραγής είναι απενεργοποιημένη.',
+'ipb_expiry_invalid' => 'Άκυρος χρόνος λήξης',
+'ip_range_invalid' => 'Το εύρος των διευθύνσεων IP δεν είναι έγκυρο.',
+'proxyblocker' => 'Εργαλείο φραγής διακομιστών (proxy blocker)',
+
+'proxyblockreason' => 'Η διεύθυνσήη IP σας έχει υποστεί φραγή γιατί είναι open proxy. Παρακαλούμε επικοινωνείστε με την υπηρεσία παροχής Internet που χρησιμοποιείτε ή με την τεχνική υποστήριξη, για να θέσετε υπ΄ όψη τους αυτό το σοβαρό θέμα ασφάλειας.',
+
+'proxyblocksuccess' => 'Ολοκληρώθηκε!',
+#'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Η διεύθνυση IP σας έχει χαρακτηρισθεί ως open proxy στο [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Η διεύθυνση IP σας έχει χαρακτηρισθεί open proxy στο [http://www.sorbs.net SORBS] DNSBL. Δεν μπορείτε να δημιουργήσετε λογαριασμό χρήστη.',
+
+
+# Developer tools
+#-------------------------#
+'lockdb' => 'Κλείδωμα βάσης δεδομένων',
+'unlockdb' => 'Ξεκλείδωμα βάσης δεδομένων',
+
+'lockdbtext' => 'Το κλείδωμα της βάσης δεδομένων αναιρεί τη δυνατότητα όλων των χρηστών να επεξεργαστούν σελίδες, να αλλάξουν τις προτιμήσεις τους, να επεξεργαστούν τις λίστες παρακολούθησης και να εκτελέσουν οποιαδήποτε ενέργεια επηρεάζει τη βάση δεδομένων. Παρακαλούμε να επιβεβαιώσετε ότι γνωρίζετε τις επιπτώσεις της ενέργειάς σας και ότι θα ξεκλειδώσετε τη βάση δεδομένων μόλις ολοκληρωθεί η συντήρηση.',
+
+'unlockdbtext' => 'Το ξεκλείδωμα της βάσης δεδομένων θα αποκαταστήσει τη δυνατότητα των χρηστών να επεξεργάζονται σελίδες, να αλλάζουν τις προτιμήσεις τους, να τροποποιούν τις λίστες παρακολούθησης και να προβαίνουν γενικότερα σε ενέργειες που επιφέρουν αλλαγές στη βάση δεδομένων. Παρακαλούμε επιβεβαιώστε πως θέλετε να προχωρήσετε.',
+
+'lockconfirm' => 'Ναι, επιθυμώ να κλειδώσω τη βάση δεδομένων.',
+'unlockconfirm' => 'Ναι, επιθυμώ να ξεκλειδώσω τη βάση δεδομένων.',
+'lockbtn' => 'Κλείδωμα βάσης δεδομένων',
+'unlockbtn' => 'Ξεκλείδωμα βάσης δεδομένων',
+'locknoconfirm' => 'Δεν έχετε σημειώσει το κουτάκι της επιβεβαίωσης.',
+'lockdbsuccesssub' => 'Η βάση δεδομένων κλειδώθηκε επιτυχώς.',
+'unlockdbsuccesssub' => 'Άρση κλειδώματος τη βάσης δεδομένων',
+
+
+# Make sysop
+#-------------------#
+'lockdbsuccesstext' => 'Η βάση δεδομένων έχει κλειδωθεί.
+<br />Μην ξεχάσετε να την ξεκλειδώσετε όταν τελειώσετε τη συντήρηση.',
+
+'makesysoptitle' => 'Κάντε ένα χρήστη διαχειριστή',
+
+'makesysoptext' => 'Η φόρμα αυτή απευθύνεται στους διαχειριστές και χρησιμεύει στο να χαρακτηρισθεί ένας χρήστης \'διαχειριστής\'. Πληκτρολογήστε το όνομα του χρήστη στο πεδίο κειμένου και επικυρώστε πατώντας το αντίστοιχο κουμπί.',
+
+'makesysopname' => 'Όνομα χρήστη:',
+'makesysopsubmit' => 'Κάνετε αυτό το χρήστη διαχειριστή',
+'makesysopok' => '<b>Ο χρήστης "$1" είναι εφεξής διαχειριστής</b>',
+'makesysopfail' => '<b>Ο χαρακτηρισμός του χρήστη "$1" σε διαχειριστή δεν ολοκληρώθηκε. (Βεβαιωθείτε πως δεν υπήρχαν λάθη στην πληκτρολόγηση του ονόματός του.)</b>',
+'setbureaucratflag' => 'Σηματοδότηση διαχειριστή (flag)',
+'rightslogtext' => 'Καταγραφές των αλλαγών στα δικαιώματα χρηστών.',
+'rights' => 'Δικαιώματα:',
+'set_user_rights' => 'Καθορισμός δικαιωμάτων χρήστη',
+'user_rights_set' => '<b>Τα δικαιώματα χρήστη για τον/την "$1" έχουν ενημερωθεί.</b>',
+'set_rights_fail' => '<b>Δεν ήταν δυνατή η ρύθμιση των δικαιωμάτων για το χρήστη "$1". Βεβαιωθείτε πως έχετε πληκτρολογήσει σωστά το όνομα.</b>',
+'makesysop' => 'Χαρακτηρισμός χρήστη ως διαχειριστή',
+'already_sysop' => 'Ο χρήστης αυτός είναι ήδη διαχειριστής.',
+'already_bureaucrat' => 'Ο χρήστης αυτός είναι ήδη διαχειριστής.',
+
+
+
+
+# Move page
+#-----------------#
+'movepage' => 'Μετακίνηση σελίδας',
+
+'movepagetext' => 'Χρησιμοποιήστε τη φόρμα που ακολουθεί για να μετονομάσετε σελίδες και για να μεταφέρετε όλο το ιστορικό τους κάτω από το νέο όνομα. Κάτω από τον παλιό τίτλο της σελίδας θα παραμείνει μια σελίδα ανακατεύθυνσης στο νέο τίτλο. Οι τυχόν σύνδεσμοι που οδηγούσαν στην παλιά σελίδα δεν θα επηρεαστούν. Βεβαιωθείτε πως [[Special:Maintenance|ελέγξατε]] τα διπλά διαστήματα και τους κατεστραμένους συνδέσμους. Αναλαμβάνετε την ευθύνη να επιβεβαιώσετε ότι οι συνδεσμοι εξακολουθούν να οδηγούν προς τις κατευθύνσεις που πρέπει.
+
+Λάβετε υπ` όψη σας ότι η σελίδα \'\'\'δεν\'\'\' θα μετακινηθεί αν υπάρχει ήδη μια άλλη σελίδα κάτω από το νέο τίτλο, εκτός αν η σελίδα αυτή είναι κενή \'\'\'και\'\'\' χωρίς ιστορικό επεξεργασίας. Αυτό σημαίνει ότι, στην περίπτωση που έχετε κάνει λάθος, μπορείτε να μετονομάσετε μια σελίδα ξαναδίνοντας της την αρχική της ονομασία αλλά δεν μπορείτε να αντικαταστήσετε μια υπάρχουσα σελίδα.
+
+
+<b>ΠΡΟΣΟΧΗ!</b>
+Η μετονομασία σελίδας είναι μια αιφνίδια και δραστική αλλαγή όταν πρόκειται για δημοφιλείς σελίδες. Παρακαλούμε, πριν το αποφασίσετε, να εξετάσετε προσεκτικά τις πιθανές επιπτώσεις αυτής της ενέργειας .',
+
+'movepagetalktext' => 'Η σελίδα συζήτησης που αντιστοιχεί, εάν υπάρχει, θα μετακινηθεί αυτόματα μαζί με αυτήν \'\'\'έκτός αν:\'\'\'
+*Μετακινείτε τη σελίδα σε διαφορετική περιοχή (namespace),
+*Υπάρχει κάτω από το νέο όνομα μια σελίδα συζήτησης που δεν είναι κενή, ή
+*Έχετε αφαιρέσει τη σημείωση (check) από το κουτάκι που υπάρχει παρακάτω.
+
+Σε αυτές τις περιπτώσεις, θα πρέπει να μετακινήσετε (ή να ενσωματώσετε αν το θέλετε) τη σελίδα με αντιγραφή-και-επικόλληση.',
+
+'movearticle' => 'Μετακίνηση σελίδας',
+'movenologin' => 'Δεν έχετε συνδεθεί.',
+'movenologintext' => 'Για να μετακινήσετε μια σελίδα πρέπει να είστε εγγεγραμένος χρήστης και [[Special:Userlogin|να έχετε συνδεθεί]] στο Wiκi.',
+'newtitle' => 'νέος τίτλος',
+'movepagebtn' => 'Μετακίνηση σελίδας',
+'pagemovedsub' => 'Η μετακίνηση ήταν επιτυχής',
+'pagemovedtext' => 'Η σελίδα "[[$1]]" μετακινήθηκε στη "[[$2]]".',
+'articleexists' => 'Υπάρχει ήδη σελίδα με αυτό το όνομα. Παρακαλούμε δώστε άλλο όνομα στη σελίδα.',
+'talkexists' => 'Η ίδια η σελίδα μετακινήθηκε επιτυχώς αλλά όχι και η σελίδα συζήτησης, λόγω του ότι υπάρχει ήδη άλλη σελίδα συζήτησης κάτω από το νέο τίτλο. Παρακαλούμε ενοποιήστε τις δύο σελίδες με \'αντιγραφή-και-επικόλληση\'.',
+'movedto' => 'Μεκακινήθηκε στο',
+'movetalk' => 'Μετακίνηση της σελίδας "συζήτηση" (εάν υπάρχει)',
+'talkpagemoved' => 'Η αντίστοιχη σελίδα συζήτησης έχει επίσης μεταφερθεί.',
+'talkpagenotmoved' => 'Η σελίδα συζήτησης που αντιστοιχεί <strong>δεν</strong> έχει μεταφερθεί.',
+'1movedto2' => 'Η $1 μετονομάστηκε σε $2',
+'1movedto2_redir' => 'Η $1 μετακινήθηκε στη θέση $2 (με ανακατεύθυνση)',
+'movelogpage' => '΄Μετακίνηση αρχείου καταγραφών',
+'movelogpagetext' => 'Ακολουθεί η λίστα με τις σελίδες που έχουν μετακινηθεί.',
+'movereason' => 'Αιτιολογία',
+'revertmove' => 'έπαναφορά',
+'delete_and_move' => 'Διαγραφή και μετακίνηση',
+
+'delete_and_move_text' => '==Χρειάζεται διαγραφή.==
+
+Το άρθρο [[$1]] υπάρχει ήδη. Θέλετε να το διαγράψετε για να εκτελεσθεί η μετακίνηση;',
+
+'delete_and_move_reason' => 'Διαγράφτηκε για να εκτελεθεί η μετακίνηση.',
+'selfmove' => 'Ο τίτλος προέλευσης είναι ο ίδιος με τον τίτλο προορισμού -δεν είναι δυνατόν να μετακινηθεί μια σελίδα προς τον εαυτό της.',
+
+'immobile_namespace' => 'Ο τίτλος του προορισμού είναι ειδικού τύπου -δεν είναι δυνατή η μετακίνηση σελίδων σε εκείνη την περιοχή.',
+
+
+# Export
+#----------#
+'export' => 'Εξαγωγή σελίδων',
+
+'exporttext' => 'Μπορείτε να κάνετε εξαγωγή του κειμένου και του ιστορικού επεξεργασίας μιας συγκεκριμένης σελίδας (ή περισσοτέρων σελίδων που έχουν ομαδοποιηθεί με χρήση XML).
+
+Για την εξαγωγή ολόκληρων άρθρων, συμπληρώστε τους τίτλους στο παρακάτω πλαίσιο (ένα τίτλο σε κάθε σειρά) και επιλέξτε ανάμεσα από το να εξαγάγετε μόνο την τρέχουσα έκδοση (με τις πληροφορίες της πιο πρόσφατης επεξεργασίας) ή εναλλακτικά και τις παλιότερες εκδόσεις (με τις αντίστοιχες καταγραφές στη σελιδα του ιστορικού).
+
+Στην τελευταία περίπτωση μπορείτε να κάνετε και χρήση συνδέσμου, π.χ. [[{{ns:Special}}:Export/Train]] για το άρθρο [[Train]].',
+
+'exportcuronly' => 'Να συμπεριληφθεί μόνον η τρέχουσα αναθεώρηση, όχι το πλήρες ιστορικό.',
+
+
+# Namespace 8 related
+#----------------------------------#
+'allmessages' => 'Όλα τα μηνύματα του συστήματος',
+'allmessagesname' => 'Όνομα',
+'allmessagesdefault' => 'Προκαθορισμένο κείμενο',
+'allmessagescurrent' => 'Παρόν κείμενο',
+'allmessagestext' => 'Η λίστα με όλα τα μηνύματα συστήματος που βρίσκονται στην περιοχή MediaWiki:',
+'allmessagesnotsupportedUI' => 'Η τρέχουσα γλώσσα διασύνδεσής σας <b>$1</b> δεν υποστηρίζεται από το Special:AllMessages σε αυτό τον ιστοχώρο.',
+'allmessagesnotsupportedDB' => 'Special:Το AllMessages δεν υποστηρίζεται επειδή το wgUseDatabaseMessages είναι απενεργοποιημένο.',
+
+
+# Thumbnails
+#------------------#
+'thumbnail-more' => 'Μεγέθυνση',
+'missingimage' => '<b>Αγνοούμενη εικόνα</b><br /><i>$1</i>',
+'filemissing' => 'Αγνοούμενο αρχείο',
+
+
+# Special:Import
+#----------------------#
+'import' => 'Εισαγωγή σελίδων',
+'importinterwiki' => 'Εισαγωγή από άλλο Wiki',
+'importtext' => 'Παρακαλούμε εξάγετε το αρχείο από το πηγαίο Wiki (χρησιμοποιώντας Special:Export), αποθηκεύστε το στο δίσκο του υπολογιστή σας και φορτώστε το από εκεί.',
+'importfailed' => 'Η εισαγωγή απέτυχε: $1',
+'importnotext' => 'Κενό (-ή) ή χωρίς κείμενο',
+'importsuccess' => 'Η εισαγωγή επέτυχε!',
+'importhistoryconflict' => 'Υπάρχει αντιφατικό ιστορικό αναθεωρήσεων (μπορεί να έχετε κάνει παλιότερα εισαγωγή αυτής της σελίδας).',
+'importnosources' => 'Δεν έχουν καθοριστεί πηγές για την εισαγωγή από άλλο Wiki και η απευθείας φόρτωση στο ιστορικό έχει απενεργοποιηθεί.',
+
+
+# Keyboard access keys for power users
+#------------------------------------------------------------#
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+
+
+# Tooltip help for some actions, most are in Monobook.js
+#--------------------------------------------------------------------------------------#
+'tooltip-search' => 'Αναζήτηση στο Wiki [alt-f]',
+'tooltip-minoredit' => 'Χαρακτηρήστε τις αλλαγές "μικρής κλίμακας" [alt-i]',
+'tooltip-save' => 'Αποθήκευση αλλαγών [alt-s]',
+'tooltip-preview' => 'Προεπισκόπηση - Παρακαλούμε να χρησιμοποιήτε αυτή την επιλογή πριν αποθηκεύσετε τις αλλαγές σας! [alt-p]',
+'tooltip-diff' => 'Προβολή των αλλαγών που κάνατε στο κείμενο. [alt-v]',
+'tooltip-compareselectedversions' => 'Εμφάνιση των διαφορών ανάμεσα στις δύο αναθεωρήσεις της σελίδας που έχετε επιλέξει. [alt-v]',
+'tooltip-watch' => 'Προσθήκη της σελίδας στη λίστα παρακολούθησης [alt-w]',
+
+
+# stylesheets
+#-------------------#
+'monobook.css' => '/* edit this file to customize the monobook skin for the entire site */',
+#'monobook.js' => '/* edit this file to change js things in the monobook skin */',
+
+
+# Metadata
+#---------------#
+'nodublincore' => 'Τα μεταδεδομένα RDF που αφορούν στο Dublin Core έχουν απενεργοποιηθεί σε αυτό τον server.',
+'nocreativecommons' => 'Τα μεταδεδομένα RDF που αφορούν στο Creative Commons έχουν απενεργοποιηθεί σε αυτό τον server.',
+'notacceptable' => 'Ο server του Wiki δεν μπορεί να αποδόσει δεδομένα σε μορφή που τα διαβάζει ο client',
+
+
+# Attribution
+#-----------------#
+'anonymous' => 'Ανώνυμος(-οι) χρήστης(-ες) του {{SITENAME}}',
+'siteuser' => '{{SITENAME}} χρήστης $1',
+'lastmodifiedatby' => 'Η σελίδα αυτή τροποποιήθηκε τελευταία φορά στις $2, $1 από το χρήστη $3.',
+'and' => 'και',
+'othercontribs' => 'Βασισμένο στη δουλειά του/της $1',
+'others' => 'άλλοι',
+'siteusers' => '{{SITENAME}} χρήστης (-ες) $1',
+'creditspage' => 'Αναγνώριση συνεισφοράς στη σελίδα',
+'nocredits' => 'Δεν υπάρχουν πληροφορίες σχετικά με την αναγνώριση συνεισφοράς σε αυτή τη σελίδα.',
+
+
+# Spam protection
+#--------------------------#
+'spamprotectiontitle' => 'Φίλτρο προστασίας από spam',
+'spamprotectiontext' => 'Η σελίδα που επιχειρήσατε να αποθηκεύσετε απομονώθηκε από το φίλτρο spam. Αυτό οφείλεται, πιθανότατα, στην ύπαρξη ενός (ή περισσότερων) συνδέσμων προς εξωτερικές σελίδες.',
+'spamprotectionmatch' => 'Το φίλτρο spam έχει τεθεί σε ενέργεια εξ αιτίας του εξής κειμένου: $1',
+'subcategorycount' => 'Υπάρχουν $1 υποκατηγορίες σε αυτή την κατηγορία.',
+'categoryarticlecount' => 'Υπάρχουν $1 άρθρα σε αυτή την κατηγορία.',
+
+
+'listingcontinuesabbrev' => 'συνεχίζεται...',
+
+
+# Info page
+#---------------#
+'infosubtitle' => 'Πληροφορίες για τη σελίδα',
+'numedits' => 'Αριθμός επεξεργασιών (στο άρθρο): $1',
+'numtalkedits' => 'Αριθμός επεξεργασιών (στη σελίδα συζήτησης): $1',
+'numwatchers' => 'Αριθμός παρακολουθήσεων: $1',
+'numauthors' => 'Αριθμός διακριτών συγγραφέων (στο άρθρο): $1',
+'numtalkauthors' => 'Αριθμός διακριτών συγγραφέων (στη σελίδα συζήτησης): $1',
+
+
+# Math options
+#---------------------#
+'mw_math_png' => 'Απόδοση πάντα σε PNG',
+'mw_math_simple' => 'HTML αν είναι αρκετά απλό, διαφορετικά PNG',
+'mw_math_html' => 'HTML αν είναι δυνατόν, διαφορετικά PNG',
+'mw_math_source' => 'Να παραμείνει ως TeX (για text browsers)',
+'mw_math_modern' => 'Προτεινόμενο για σύγχρονους browser',
+'mw_math_mathml' => 'MathML όποτε είναι δυνατόν (πειραματικό)',
+
+
+# Patrolling
+#--------------#
+'markaspatrolleddiff' => 'Να σημειωθεί \'υπό παρακολούθηση\'',
+'markaspatrolledtext' => 'Να σημειωθεί αυτό το άρθρο ως \'υπό παρακολούθηση\'.',
+'markedaspatrolled' => 'Σημειωμένο ως \'υπό παρακολούθηση\'',
+'markedaspatrolledtext' => 'Η αναθεώρηση που έχει επιλεγεί έχει σημειωθεί ως \'υπό παρακολούθηση\'.',
+'rcpatroldisabled' => 'Η λειτουργία \'Παρακολούθηση Πρόσφατων Αλλαγών\' έχει απενεργοποιηθεί.',
+'rcpatroldisabledtext' => 'Η λειτουργία \'Παρακολούθηση Πρόσφατων Αλλαγών\' είναι αυτή τη στιγμή απενεργοποιημένη.',
+
+
+# Monobook.js: tooltips and access keys for monobook
+#------------------------------------------------------------------------------------#
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Η προσωπική μου σελίδα στο Wiκi\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Η σελίδα χρήστη στον οποίο αντιστοιχεί η διεύθυνση IP που έχετε\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Η σελίδα συζητήσεών μου\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Συζήτηση σχετικά με τις αλλαγές που έγιναν από αυτή τη διεύθυνση IP\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Οι προτιμήσεις μου\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Η λίστα με τις σελίδες που παρακολουθείτε για αλλαγές\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Κατάλογος των συνεισφορών μου\');
+ta[\'pt-login\'] = new Array(\'o\',\'Σας προτείνουμε να συνδεθείτε παρόλο που δεν είναι αναγκαίο.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Σας προτείνουμε να συνδεθείτε παρόλο που δεν είναι αναγκαίο.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Αποσύνδεση\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Συζήτηση για το παρόν άρθρο\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Μπορείτε να επεξεργαστείτε αυτό το άρθρο. Χρησιμοποιείστε την "Προεπισκόπηση" πριν αποθηκεύσετε.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Προσθέστε σχόλιο στη συζήτηση.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Αυτό το άρθρο είναι κλειδωμένο. Μπορείτε να δείτε τον πηγαίο κώδικά του.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Παλιές αναθεωρήσεις του άρθρου.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Κλείδωμα αυτού του άρθρου\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Διαγραφή αυτής της σελίδας\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Αποκαταστήστε τις αλλαγές που έγιναν σε αυτή τη σελίδα πριν διαγραφεί.\');
+ta[\'ca-move\'] = new Array(\'m\',\'Μετακινήστε αυτή τη σελίδα\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Δεν έχετε εξουσιοδότηση να μετακινήσετε αυτή τη σελίδα.\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Προσθήκη της σελίδας στη λίστα παρακολούθησης\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Αφαίρεση της σελίδας από τη λίστα παρακολούθησης\');
+ta[\'search\'] = new Array(\'f\',\'Αναζήτηση στο WiKi\');
+ta[\'p-logo\'] = new Array(\'\',\'Αρχική σελίδα\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Δείτε την Αρχική σελίδα\');
+ta[\'n-portal\'] = new Array(\'\',\'Σχετικά με το Wiκi - πώς μπορείτε να βοηθήσετε, πού μπορείτε να απευθυνθείτε\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Πληροφορίες για πρόσφατα γεγονότα\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Η λίστα με τις πρόσφατες αλλαγές στο WiKi\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Επισκεφθείτε μια τυχαία σελίδα του Wiκi\');
+ta[\'n-help\'] = new Array(\'\',\'Το μέρος για να βρείτε τις απαντήσεις που ψάχνετε.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Βοηθήστε το έργο.\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Λίστα από άρθρα που αναφέρουν το παρόν άρθρο\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Πρόσφατες αλλαγές σε άρθρα που συνδέονται με το παρόν\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS feed για\' αυτή την σελίδα\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom feed για\' αυτή την σελίδα\');
+ta[\'t-contributions\'] = new Array(\'\',\'Δείτε τη λίστα με τις συνεισφορές αυτού του χρήστη στο Wiκi\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Αποστολή μηνύματος σε αυτό το χρήστη\');
+ta[\'t-upload\'] = new Array(\'u\',\'Φόρτωση εικόνας ή αρχείου πολυμέσων\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Η λίστα με όλες τις σελίδες λειτουργιών\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Άρθρο\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Δείτε τη σελίδα του χρήστη\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Δείτε τη σελίδα πολυμέσων\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Αυτή είναι ειδική σελίδα και δεν μπορείτε να την επεξεργαστείτε.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Δείτε τη σελίδα του συστήματος\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Δείτε την εικόνα\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Δείτε το μήνυμα του συστήματος\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Δείτε το πρότυπο\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Δείτε τη σελίδα βοήθειας\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Δείτε τη σελίδα κατηγοριών\');',
+
+
+# image deletion
+#------------------------#
+'deletedrevision' => 'Η παλιά έκδοση της $1 διαγράφτηκε.',
+
+
+# browsing diffs
+#----------------------#
+'previousdiff' => '&larr; Δείτε την προηγούμενη \'διαφορά\'',
+'nextdiff' => 'Μετάβαση στην επόμενη \'διαφορά\' &rarr;',
+
+'imagemaxsize' => 'Περιορισμός του μεγέθους των εικόνων (στις σελίδες περιγραφής εικόνων) σε:',
+'thumbsize' => 'Μεγεθος μινιατούρας:',
+'showbigimage' => 'Κατέβασμα του αρχείου υψηλής ανάλυσης ($1x$2, $3 KB)',
+
+'newimages' => 'Πινακοθήκη νέων εικόνων',
+'noimages' => 'Δεν υπάρχουν εικόνες.',
+
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+
+
+# labels for User: and Title: on Special:Log pages
+#--------------------------------------------------------------------------#
+'specialloguserlabel' => 'Χρήστης:',
+'speciallogtitlelabel' => 'Τίτλος:',
+'passwordtooshort' => 'Ο κωδικός σας είναι πολύ σύντομος. Πρέπει να περιέχει τουλάχιστον $1 χαρακτήρες.',
+
+# Media Warning
+#-----------------------#
+'mediawarning' => '\'\'\'Προειδοποίηση\'\'\': Το αρχείο αυτό μπορεί να περιέχει κακοπροαίρετο κώδικα που μπορεί να βλάψει το σύστημα του υπολογιστή σας.
+
+<hr />',
+
+'fileinfo' => '$1KB, MIME type: <code>$2</code>',
+
+# Metadata
+#---------------#
+'metadata' => 'Μεταδεδομένα',
+
+
+# Exif tags
+#-------------#
+'exif-imagewidth' => 'Πλάτος',
+'exif-imagelength' => 'Υψος',
+'exif-bitspersample' => 'Bits ανά στοιχείο',
+'exif-compression' => 'Σχήμα συμπίεσης',
+'exif-photometricinterpretation' => 'Σύνθεση των pixel',
+'exif-orientation' => 'Προσαντολισμός',
+'exif-samplesperpixel' => 'Αριθμός στοιχείων',
+'exif-planarconfiguration' => 'Διάταξη δεδομένων',
+'exif-ycbcrsubsampling' =>'Αναλογικό δείγμα σε φωτεινότητα και χρώμα',
+'exif-ycbcrpositioning' =>'Ρύθμιση φωτεινότητας και χρώματος',
+'exif-xresolution' => 'Οριζόντια ανάλυση',
+'exif-yresolution' => 'Κατακόρυφη ανάλυση',
+'exif-resolutionunit' => 'Μονάδα μέτρησης ανάλυσης X και Y',
+'exif-stripoffsets' => 'Τοποθέτηση δεδομένων εικόνας',
+'exif-rowsperstrip' =>'Αριθμός σειρών ανά λωρίδα',
+'exif-stripbytecounts' =>'Bytes ανά συμπιεσμένη λωρίδα',
+'exif-jpeginterchangeformat' => 'Μετάθεση σε JPEG SOI',
+'exif-jpeginterchangeformatlength' => 'Bytes δεδομένων JPEG',
+'exif-transferfunction' => 'Λειτουργία μεταφοράς',
+'exif-whitepoint' =>'Χρωματικός προσδιορισμός λευκού',
+'exif-primarychromaticities' =>'Πρωτεύοντες χρωματισμοί',
+'exif-ycbcrcoefficients' =>'Συντελεστές μητρών μετασχηματισμού χρώματος',
+'exif-referenceblackwhite' => 'Ζεύγος μαύρων και άσπρων αξιών αναφοράς',
+'exif-datetime' => 'Δηλώστε την ημερομηνία και την ώρα της επεξεργασίας.',
+'exif-imagedescription' => 'Τίτλος εικόνας',
+'exif-make' => 'Κατασκευαστής φωτογραφικής μηχανής',
+'exif-model' => 'Μοντέλο φωτογραφικής μηχανής',
+'exif-software' => 'Λογισμικό που χρησιμοποιήθηκε',
+'exif-artist' => 'Δημιουργός',
+'exif-copyright' => 'Ιδιοκτήτης του copyright',
+'exif-exifversion' => 'Έκδοση exif',
+'exif-flashpixversion' => 'Υποστηριζόμενη έκδοση Flashpix',
+'exif-colorspace' => 'Χρωματική περιοχή',
+'exif-componentsconfiguration' => 'Νόημα του κάθε στοιχείου',
+'exif-compressedbitsperpixel' => 'Κατάσταση συμπίεσης εικόνας',
+'exif-pixelydimension' => 'Έγκυρο πλάτος εικόνας',
+'exif-pixelxdimension' => 'Έγκυρο ύψος εικόνας',
+'exif-makernote' => 'Σημειώσεις του κατασκευαστή',
+'exif-usercomment' => 'Σχόλια χρήστη',
+'exif-relatedsoundfile' => 'Σχετικό αρχείο ήχου',
+'exif-datetimeoriginal' => 'Ημερομηνία και ώρα της παραγωγής ψηφιακών δεδομένων',
+'exif-datetimedigitized' => 'Ημερομηνία και ώρα της μετατροπής σε ψηφιακή μορφή',
+#'exif-subsectime' =>'DateTime subseconds',
+#'exif-subsectimeoriginal' =>'DateTimeOriginal subseconds',
+#'exif-subsectimedigitized' =>'DateTimeDigitized subseconds',
+'exif-exposuretime' => 'Χρόνος έκθεσης',
+'exif-fnumber' => 'Αριθμός F',
+'exif-exposureprogram' => 'Πρόγραμμα έκθεσης',
+'exif-spectralsensitivity' => 'Ευαισθησία φάσματος',
+'exif-isospeedratings' => 'Βαθμολόγηση ταχύτητας ISO',
+'exif-oecf' => 'Οπτικοηλεκτρονικός συντελεστής μετατροπής',
+'exif-shutterspeedvalue' => 'Ταχύτητα κλείστρου',
+'exif-aperturevalue' => 'Διάφραγμα',
+'exif-brightnessvalue' => 'Φωτεινότητα',
+'exif-exposurebiasvalue' => 'Προτεραιότητα έκθεσης',
+'exif-maxaperturevalue' => 'Μέγιστο διάφραγμα ξηράς',
+'exif-subjectdistance' => 'Απόσταση αντικειμένου',
+'exif-meteringmode' => 'Κατάσταση λειτουργίας φωτόμετρου',
+'exif-lightsource' => 'Πηγή φωτός',
+'exif-flash' => 'Φλας',
+'exif-focallength' => 'Εστιακή απόσταση του φακού',
+'exif-subjectarea' => 'Θεματική περιοχή',
+'exif-flashenergy' => 'Ενέργεια του φλας',
+'exif-spatialfrequencyresponse' =>'Χωρική απόκριση συχνότητας',
+'exif-focalplanexresolution' => 'Ανάλυση εστιακού επιπέδου Χ',
+'exif-focalplaneyresolution' => 'Ανάλυση εστιακού πειπέδου Υ',
+'exif-focalplaneresolutionunit' => 'Μονάδα μέτρησης ανάλυσης εστιακού επιπέδου',
+'exif-subjectlocation' => 'Τοποθέτηση του αντικειμένου',
+'exif-exposureindex' => 'Δείκτης έκθεσης',
+'exif-sensingmethod' => 'Μέθοδος αισθητήρα',
+'exif-filesource' => 'Πηγή αρχείου',
+'exif-scenetype' => 'Τύπος σκηνής',
+'exif-cfapattern' => 'CFA pattern',
+'exif-customrendered' => 'Ειδική επεξεργασία εικόνας',
+'exif-exposuremode' => 'Κατάσταση λειτουργίας έκθεσης',
+'exif-whitebalance' => 'Ισορροπία των λευκών',
+'exif-digitalzoomratio' => 'Αναλογία ψηφιακού zoom',
+'exif-focallengthin35mmfilm' => 'Εστιακή απόσταση σε φιλμ 35 mm',
+'exif-scenecapturetype' => 'Τύπος σύλληψης της σκηνής',
+'exif-gaincontrol' => 'Έλεγχος πεδίου',
+'exif-contrast' => 'Αντίθεση',
+'exif-saturation' => 'Κορεσμός',
+'exif-sharpness' => 'Όξυνση',
+'exif-devicesettingdescription' => 'Περιγραφή των ρυθμίσεων του μηχανήματος',
+'exif-subjectdistancerange' => 'Περιοχή διακύμανσης της απόστασης του αντικειμένου',
+'exif-imageuniqueid' => 'Μονοσήμαντη ταυτοποίηση εικόνας',
+'exif-gpsversionid' => 'Έκδοση με GPS tag',
+'exif-gpslatituderef' => 'Βόρειο ή Νότιο γεωγραφικό πλάτος',
+'exif-gpslatitude' => 'Γεωγραφικό πλάτος',
+'exif-gpslongituderef' => 'Ανατολικό ή Δυτικό γεωγραφικό μήκος',
+'exif-gpslongitude' => 'Γεωγραφικό μήκος',
+'exif-gpsaltituderef' => 'Αναφορές υψομέτρου',
+'exif-gpsaltitude' => 'Υψόμετρο',
+'exif-gpstimestamp' => 'Ώρα GPS (ατομικό ρολόι)',
+'exif-gpssatellites' => 'Δορυφόροι που χρησιμοποιήθηκαν για τις μετρήσεις',
+'exif-gpsstatus' => 'Κατάσταση δέκτη',
+'exif-gpsmeasuremode' => 'Τρόπος λειτουργίας μετρήσεων',
+'exif-gpsdop' => 'Ακρίβεια μέτρησης',
+'exif-gpsspeedref' => 'Μονάδα μέτρησης ταχύτητας',
+'exif-gpsspeed' => 'Ταχύτητα δέκτη GPS',
+'exif-gpstrackref' => 'Αναφορές για την κατεύθυνση της κίνησης',
+'exif-gpstrack' => 'Κατεύθυνση κίνησης',
+'exif-gpsimgdirectionref' => 'Αναφορές για την κατεύθυνση της εικόνας',
+'exif-gpsimgdirection' => 'Κατεύθυνση της εικόνας',
+'exif-gpsmapdatum' => 'Στοιχεία γεωδετικών μετρήσεων ΄που έχουν χρησιμοποιηθεί',
+'exif-gpsdestlatituderef' => 'Αναφορές για το γεωγραφικό πλάτος του προορισμού',
+'exif-gpsdestlatitude' => 'Αναφορές γεωγραφικού πλάτους',
+'exif-gpsdestlongituderef' => 'Αναφορές για το γεωγραφικό μήκος του προορισμού',
+'exif-gpsdestlongitude' => 'Γεωγραφικό πλάτος προορισμού',
+'exif-gpsdestbearingref' => 'Αναφορές για τις συντεταγμένες προορισμού',
+'exif-gpsdestbearing' => 'Συντεταγμένες προορισμού',
+'exif-gpsdestdistanceref' => 'Αναφορές για την απόσταση μέχρι τον προορισμό',
+'exif-gpsdestdistance' => 'Απόσταση μέχρι τον προορισμό',
+'exif-gpsprocessingmethod' => 'Όνομα μεθόδου επεξεργασίας GPS',
+'exif-gpsareainformation' => 'Όνομα περιοχής GPS',
+'exif-gpsdatestamp' => 'Ημερομηνία GPS',
+'exif-gpsdifferential' => 'Διαφορική διόρθωση GPS',
+
+'exif-compression-1' => 'Έχει αποσυμπιεστεί.',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Φυσικός', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Έχει αντιστραφεί οριζόντια.', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Έχει περιστραφεί κατά 180° μοίρες.', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Έχει αντιστραφεί κατακόρυφα.', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Έχει περιστραφεί κατά 90° μοίρες με φορά αντίθετα προς τη φορά των δεικτών του ρολογιού και έχει αντιστραφεί κατακόρυφα.', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Έχει περιστραφεί κατά 90° μοίρες κατά τη φορά των δεικτών του ρολογιού.', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Έχει περιστραφεί κατά 90° μοίρες κατά τη φορά των δεικτών του ρολογιού και έχει αντιστραφεί κατακόρυφα.', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Έχει περιστραφή κατά 90° μοίρες αντίθετα προς τη φορά των δεικτών του ρολογιού.', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'πεπλατυσμένος σχηματισμός',
+'exif-planarconfiguration-2' => 'επίπεδος σχηματισμός',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+'exif-componentsconfiguration-0' => 'δεν υπάρχει',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Δεν έχει προκαθοριστεί',
+'exif-exposureprogram-1' => 'Χειροκίνητο',
+'exif-exposureprogram-2' => 'Κανονικό πρόγραμμα',
+'exif-exposureprogram-3' => 'Προτεραιότητα διαφράγματος',
+'exif-exposureprogram-4' => 'Προτεραιότητα κλείστρου',
+'exif-exposureprogram-5' => 'Δημιουργικό πρόγραμμα (με προτεραιότητα το βάθος πεδίου)',
+'exif-exposureprogram-6' => 'Δημιουργικό πρόγραμμα (με προτεραιόττηα την ταχύτητα του κλείστρου)',
+'exif-exposureprogram-7' => 'Επιλογή λειτουργίας "πορτραίτου" (για φωτογραφίες closeup με το φόντο εκτός εστίασης)',
+'exif-exposureprogram-8' => 'Επιλογή λειτουργίας "τοπίου" (για φωτογραφίες τοπίου με εστιασμένο φόντο)',
+
+'exif-subjectdistance-value' => '$1 μέτρα',
+'exif-meteringmode-0' => 'Άγνωστη',
+'exif-meteringmode-1' => 'Μέση τιμή',
+'exif-meteringmode-2' => 'Μέση τιμή με έμφαση στο κέντρο',
+'exif-meteringmode-3' => 'Ένα σημείο',
+'exif-meteringmode-4' => 'Πολλά σημεία',
+'exif-meteringmode-5' => 'Μοτίβο',
+'exif-meteringmode-6' => 'Μερική',
+'exif-meteringmode-255' => 'Άλλο',
+'exif-lightsource-0' => 'Άγνωστη',
+'exif-lightsource-1' => 'Φως ημέρας',
+'exif-lightsource-2' => 'Φωσφορίζον',
+'exif-lightsource-3' => 'Tungsten (φωτισμός από λυχνίες πυράκτωσης)',
+'exif-lightsource-4' => 'Φλας',
+'exif-lightsource-9' => 'Αίθριος καιρός',
+'exif-lightsource-10' => 'Συννεφιά',
+'exif-lightsource-11' => 'Σκιά',
+'exif-lightsource-12' => 'Φως ημέρας φωσφορίζον (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Λευκό φως ημέρας (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Κρύο λευκό φως fluorescent (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Λευκό φως φωσφορίζον (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Τυποποιημένος φωτισμός A',
+'exif-lightsource-18' => 'Τυποποιημένος φωτισμός B',
+'exif-lightsource-19' => 'Τυποποιημένος φωτισμός C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+#'exif-lightsource-24' => 'ISO studio tungsten',
+'exif-lightsource-255' => 'Άλλη πηγή φωτός',
+
+'exif-focalplaneresolutionunit-2' => 'ίντσες',
+
+'exif-sensingmethod-1' => 'Δεν έχει καθοριστεί',
+'exif-sensingmethod-2' => 'One-chip color area sensor',
+'exif-sensingmethod-3' => 'Two-chip color area sensor',
+'exif-sensingmethod-4' => 'Three-chip color area sensor',
+'exif-sensingmethod-5' => 'Color sequential area sensor',
+'exif-sensingmethod-7' => 'Trilinear sensor',
+'exif-sensingmethod-8' => 'Color sequential linear sensor',
+
+'exif-filesource-3' => 'DSC',
+'exif-scenetype-1' => 'Εικόνα που φωτογραφήθηκε απ` ευθείας',
+
+'exif-customrendered-0' => 'Κανονική επεξεργασία',
+'exif-customrendered-1' => 'Ειδική επεξεργασία',
+
+'exif-exposuremode-0' => 'Αυτόματη έκθεση',
+'exif-exposuremode-1' => 'Χειροκίνητη έκθεση',
+'exif-exposuremode-2' => 'Αυτόματο bracket',
+
+'exif-whitebalance-0' => 'Αυτόματη ισορροπία των λευκών',
+'exif-whitebalance-1' => 'Χειροκίνητη ισορροπία των λευκών',
+
+'exif-scenecapturetype-0' => 'Συνήθης',
+'exif-scenecapturetype-1' => 'Τοπίο',
+'exif-scenecapturetype-2' => 'Πορτραίτο',
+'exif-scenecapturetype-3' => 'Νυκτερινή σκηνή',
+
+'exif-gaincontrol-0' => 'Κανένα',
+'exif-gaincontrol-1' => 'Χαμηλό κέρδος επάνω',
+'exif-gaincontrol-2' => 'Υψηλό κέρδος επάνω',
+'exif-gaincontrol-3' => 'Χαμηλό κέρδος κάτω',
+'exif-gaincontrol-4' => 'Υψηλό κέρδος κατω',
+
+'exif-contrast-0' => 'Φυσικό',
+'exif-contrast-1' => 'Απαλό',
+'exif-contrast-2' => 'Ισχυρό',
+
+'exif-saturation-0' => 'Φυσικός',
+'exif-saturation-1' => 'Χαμηλός κορεσμός',
+'exif-saturation-2' => 'Υψηλός κορεσμός',
+
+'exif-sharpness-0' => 'Φυσική',
+'exif-sharpness-1' => 'Απαλή',
+'exif-sharpness-2' => 'Σκληρή',
+
+'exif-subjectdistancerange-0' => 'Άγνωστη',
+'exif-subjectdistancerange-1' => 'Macro',
+'exif-subjectdistancerange-2' => 'Κοντινή λήψη',
+'exif-subjectdistancerange-3' => 'Μακρίνή λήψη',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Βόρειο γεωγραφικό πλάτος',
+'exif-gpslatitude-s' => 'Νότιο γεωγραφικό πλάτος',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Ανατολικό γεωγραφικό μήκος',
+'exif-gpslongitude-w' => 'Δυτικό γεωγραφικό μήκος',
+
+'exif-gpsstatus-a' => 'Μέτρηση εν εξελίξει',
+'exif-gpsstatus-v' => 'Διαλειτουργικότητα μετρήσεων',
+
+'exif-gpsmeasuremode-2' => 'μέτρηση δύο διαστάσεων',
+'exif-gpsmeasuremode-3' => 'μέτρηση τριών διαστάσεων',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Χιλιόμετρα/ώρα',
+'exif-gpsspeed-m' => 'Μίλια/ώρα',
+'exif-gpsspeed-n' => 'Κόμβοι',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Πραγματική κατεύθυνση',
+'exif-gpsdirection-m' => 'Μαγνητική κατεύθυνση',
+
+
+# external editor support
+#-------------------------------------#
+'edit-externally' => 'Επεξεργαστείτε το συγκεκριμένο αρχείο χρησιμοποιώντας μια από τις εξωτερικές εφαρμογές.',
+'edit-externally-help' => 'Για περισσότερες πληροφορίες ακολουθήστε το σύνδεσμο: [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions].',
+
+
+# 'all' in various places, this might be different for inflected languages
+#---------------------------------------------------------------------------------------------------------#
+'recentchangesall' => 'όλες',
+'imagelistall' => 'όλες',
+'watchlistall1' => 'όλες',
+'watchlistall2' => 'όλες',
+
+
+# E-mail address confirmation
+#--------------------------------------------#
+'confirmemail' => 'Επαλήθευση διεύθυνσης e-mail',
+
+'confirmemail_text' => 'Το σύστημα χρειάζεται να επαληθεύσει τη διεύθυνση e-mail που δώσατε για να χρησιμοποιήσετε τις δυνατότητες αλληλογραφίας. Κάνετε κλικ στο παρακάτω κουμπί και θα σας αποσταλεί μήνυμα επαλήθευσης στη διεύθυνσή σας. Στο μήνυμα αυτό θα εμφανίζεται ένας σύνδεσμος που Θα περιέχει τον κωδικό επαλήθευσης -ακολουθήστε το σύνδεσμο αυτό για να μπορέσει το σύστημα να επαληθεύσει τη διεύθυνση αλληλογραφίας σας.',
+
+'confirmemail_send' => 'Αποστολή κωδικού επαλήθευσης με e-mail .',
+'confirmemail_sent' => 'Το μήνυμα επαλήθευσης έχει σταλεί, ελέγξτε την αλληλογραφία σας.',
+'confirmemail_sendfailed' => 'Δεν ήταν δυνατή η αποστολή του μηνύματος επαλήθευσης. Ελέγξτε την ηλεκτρονική διεύθυνση που συμπληρώσατε για πιθανά λάθη πληκτρολόγησης.',
+'confirmemail_invalid' => 'Λάθος κωδικός επαλήθευσης. Είναι πιθανόν ο κωδικός σας να έχει λήξει.',
+'confirmemail_success' => 'Η ηλεκτρονική σας διεύθυνση σας επαληθεύτηκε. Μπορείτε πλέον να συνδεθείτε και να απολαύσετε τις δυνατότητες του Wiκi.',
+'confirmemail_loggedin' => 'Η ηλεκτρονική σας διεύθυνση επαληθεύτηκε.',
+'confirmemail_error' => 'Παρουσιάστηκε λάθος κατά την αποθήκευση των ρυθμίσεών σας.',
+'confirmemail_subject' => 'Επαλήθευση ηλεκτρονικής διεύθυνσης του {{SITENAME}}',
+
+'confirmemail_body' => 'Κάποιος, πιθανόν εσείς από τη διεύθυνση IP $1, δημιούργησε στο {{SITENAME}} ένα λογαριασμό χρήστη "$2" με τη συγκεκριμένη ηλεκτρονική διεύθυνση.
+
+Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε εσάς και για να ενεργοποιηθούν οι δυνατότητες e-mail του {{SITENAME}}, ακολουθήστε αυτό το σύνδεσμο:
+
+$3
+
+Αν ο χρήστης που δημιούργησε το συγκεκριμένο λογαριασμό δεν είστε εσείς, μην ακολουθήστε το σύνδεσμο. Ο κωδικός επιβεβαίωσης θα λήξει στις $4',
+
+
+
+# Inputbox extension, may be useful in other contexts as well
+#----------------------------------------------------------------------------------------------#
+'tryexact' => 'Δοκιμάστε την επακριβή αντιστοιχία.',
+'searchfulltext' => 'Αναζήτηση με το πλήρες κείμενο',
+'createarticle' => 'Δημιουργία άρθρου',
+
+
+# Scary transclusion
+#------------------------------#
+'scarytranscludedisabled' => '[Η ενσωμάτωση εξωτερικών ιστοσελίδων σε αυτό το Wiki είναι απενεργοποιημένη.]',
+'scarytranscludefailed' => '[Λυπούμαστε, η προσκόμιση προτύπου για το $1 απέτυχε.]',
+'scarytranscludetoolong' => '[Λυπούμαστε η διεύθυνση URL είναι πολύ μεγάλη.]',
+
+
+# Trackbacks
+#------------------#
+/*'trackbackbox' => '<div id=\'mw_trackbacks\'>
+Trackbacks for this article:<br />
+$1
+</div>',
+*/
+'trackbackremove' => ' ([$1΄- Διαγραφή])',
+'trackbacklink' => 'Επιστροφή για αναζήτηση',
+'trackbackdeleteok' => 'Η επιστροφή για αναζήτηση έχει διαγραφεί επιτυχώς.',
+
+
+);
+
+
+
+?>
diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php
new file mode 100644
index 000000000000..209d921791df
--- /dev/null
+++ b/languages/messages/MessagesEn.php
@@ -0,0 +1,2711 @@
+<?php
+/**
+ * This is the default English localisation file
+ *
+ * END USERS: DO NOT EDIT THIS FILE DIRECTLY!
+ *
+ * REPEAT!
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY!
+ * NOTHING WILL HAPPEN WHEN YOU DO THAT!
+ *
+ * You can make your customizations on the wiki.
+ * While logged in as a sysop user, go to [[Special:Allmessages]]
+ * and edit the MediaWiki:* pages listed there.
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY OR YOU WILL JUST BE CONFUSED!
+ */
+
+
+/**
+ * Fallback language, used for all unspecified messages and behaviour. This
+ * is English by default, for all files other than this one.
+ *
+ * Do NOT set this to false in any other message file! Leave the line out to
+ * accept the default fallback to "en".
+ */
+$fallback = false;
+
+/**
+ * Is the language written right-to-left?
+ * Note that right-to-left languages generally also specify
+ * $defaultUserOptionOverrides = array( 'quickbar' => 2 );
+ */
+$rtl = false;
+
+/**
+ * Optional array mapping ASCII digits 0-9 to local digits.
+ */
+$digitTransformTable = null;
+
+/**
+ * Transform table for decimal point '.' and thousands separator ','
+ */
+$separatorTransformTable = null;
+
+/**
+ * Overrides for the default user options. This is mainly used by RTL languages.
+ */
+$defaultUserOptionOverrides = array();
+
+/**
+ * Extra user preferences which will be shown in Special:Preferences as
+ * checkboxes. Extra settings in derived languages will automatically be
+ * appended to the array of the fallback languages.
+ */
+$extraUserToggles = array();
+
+/**
+ * URLs do not specify their encoding. UTF-8 is used by default, but if the
+ * URL is not a valid UTF-8 sequence, we have to try to guess what the real
+ * encoding is. The encoding used in this case is defined below, and must be
+ * supported by iconv().
+ */
+$fallback8bitEncoding = 'windows-1252';
+
+/**
+ * To allow "foo[[bar]]" to extend the link over the whole word "foobar"
+ */
+$linkPrefixExtension = false;
+
+/**
+ * Namespace names. NS_PROJECT is always set to $wgMetaNamespace after the
+ * settings are loaded, it will be ignored even if you specify it here.
+ *
+ * NS_PROJECT_TALK will be set to $wgMetaNamespaceTalk if that variable is
+ * set, otherwise the string specified here will be used. The string may
+ * contain "$1", which will be replaced by the name of NS_PROJECT. It may
+ * also contain a grammatical transformation, e.g.
+ *
+ * NS_PROJECT_TALK => 'Keskustelu_{{grammar:elative|$1}}'
+ *
+ * Only one grammatical transform may be specified in the string. For
+ * performance reasons, this transformation is done locally by the language
+ * module rather than by the full wikitext parser. As a result, no other
+ * parser features are available.
+ */
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Talk',
+ NS_USER => 'User',
+ NS_USER_TALK => 'User_talk',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_talk',
+ NS_IMAGE => 'Image',
+ NS_IMAGE_TALK => 'Image_talk',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Template_talk',
+ NS_HELP => 'Help',
+ NS_HELP_TALK => 'Help_talk',
+ NS_CATEGORY => 'Category',
+ NS_CATEGORY_TALK => 'Category_talk',
+);
+
+/**
+ * Array of namespace aliases, mapping from name to NS_xxx index
+ */
+$namespaceAliases = array();
+
+/**
+ * Labels of the quickbar settings in Special:Preferences
+ */
+$quickbarSettings = array(
+ 'None', 'Fixed left', 'Fixed right', 'Floating left', 'Floating right'
+);
+
+/**
+ * Skin names. If any key is not specified, the English one will be used.
+ */
+$skinNames = array(
+ 'standard' => 'Classic',
+ 'nostalgia' => 'Nostalgia',
+ 'cologneblue' => 'Cologne Blue',
+ 'davinci' => 'DaVinci',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'MySkin',
+ 'chick' => 'Chick'
+);
+
+/**
+ * Deprecated, use the message array
+ */
+$mathNames = array(
+ MW_MATH_PNG => 'mw_math_png',
+ MW_MATH_SIMPLE => 'mw_math_simple',
+ MW_MATH_HTML => 'mw_math_html',
+ MW_MATH_SOURCE => 'mw_math_source',
+ MW_MATH_MODERN => 'mw_math_modern',
+ MW_MATH_MATHML => 'mw_math_mathml'
+);
+
+/**
+ * A list of date format preference keys which can be selected in user
+ * preferences. New preference keys can be added, provided they are supported
+ * by the language class's timeanddate(). Only the 5 keys listed below are
+ * supported by the wikitext converter (DateFormatter.php).
+ *
+ * The special key "default" is an alias for either dmy or mdy depending on
+ * $wgAmericanDates
+ */
+$datePreferences = array(
+ 'default',
+ 'mdy',
+ 'dmy',
+ 'ymd',
+ 'ISO 8601',
+);
+
+/**
+ * The date format to use for generated dates in the user interface.
+ * This may be one of the above date preferences, or the special value
+ * "dmy or mdy", which uses mdy if $wgAmericanDates is true, and dmy
+ * if $wgAmericanDates is false.
+ */
+$defaultDateFormat = 'dmy or mdy';
+
+/**
+ * Associative array mapping old numeric date formats, which may still be
+ * stored in user preferences, to the new string formats.
+ */
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'mdy',
+ 'dmy',
+ 'ymd'
+);
+
+/**
+ * These are formats for dates generated by MediaWiki (as opposed to the wikitext
+ * DateFormatter). Documentation for the format string can be found in
+ * Language.php, search for sprintfDate.
+ *
+ * This array is automatically inherited by all subclasses. Individual keys can be
+ * overridden.
+ */
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'F j, Y',
+ 'mdy both' => 'H:i, F j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F Y',
+ 'dmy both' => 'H:i, j F Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y F j',
+ 'ymd both' => 'H:i, Y F j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+/**
+ * Default list of book sources
+ */
+$bookstoreList = array(
+ 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
+ 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
+ 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+/**
+ * Magic words
+ * Customisable syntax for wikitext and elsewhere
+ *
+ * Note to translators:
+ * Please include the English words as synonyms. This allows people
+ * from other wikis to contribute more easily.
+ *
+ * This array can be modified at runtime with the LanguageGetMagic hook
+ */
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#REDIRECT' ),
+ 'notoc' => array( 0, '__NOTOC__' ),
+ 'nogallery' => array( 0, '__NOGALLERY__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__' ),
+ 'toc' => array( 0, '__TOC__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__' ),
+ 'start' => array( 0, '__START__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV' ),
+ 'currentday' => array( 1, 'CURRENTDAY' ),
+ 'currentday2' => array( 1, 'CURRENTDAY2' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR' ),
+ 'currenttime' => array( 1, 'CURRENTTIME' ),
+ 'currenthour' => array( 1, 'CURRENTHOUR' ),
+ 'localmonth' => array( 1, 'LOCALMONTH' ),
+ 'localmonthname' => array( 1, 'LOCALMONTHNAME' ),
+ 'localmonthnamegen' => array( 1, 'LOCALMONTHNAMEGEN' ),
+ 'localmonthabbrev' => array( 1, 'LOCALMONTHABBREV' ),
+ 'localday' => array( 1, 'LOCALDAY' ),
+ 'localday2' => array( 1, 'LOCALDAY2' ),
+ 'localdayname' => array( 1, 'LOCALDAYNAME' ),
+ 'localyear' => array( 1, 'LOCALYEAR' ),
+ 'localtime' => array( 1, 'LOCALTIME' ),
+ 'localhour' => array( 1, 'LOCALHOUR' ),
+ 'numberofpages' => array( 1, 'NUMBEROFPAGES' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES' ),
+ 'numberofusers' => array( 1, 'NUMBEROFUSERS' ),
+ 'pagename' => array( 1, 'PAGENAME' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE' ),
+ 'namespace' => array( 1, 'NAMESPACE' ),
+ 'namespacee' => array( 1, 'NAMESPACEE' ),
+ 'talkspace' => array( 1, 'TALKSPACE' ),
+ 'talkspacee' => array( 1, 'TALKSPACEE' ),
+ 'subjectspace' => array( 1, 'SUBJECTSPACE', 'ARTICLESPACE' ),
+ 'subjectspacee' => array( 1, 'SUBJECTSPACEE', 'ARTICLESPACEE' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE' ),
+ 'subpagename' => array( 1, 'SUBPAGENAME' ),
+ 'subpagenamee' => array( 1, 'SUBPAGENAMEE' ),
+ 'basepagename' => array( 1, 'BASEPAGENAME' ),
+ 'basepagenamee' => array( 1, 'BASEPAGENAMEE' ),
+ 'talkpagename' => array( 1, 'TALKPAGENAME' ),
+ 'talkpagenamee' => array( 1, 'TALKPAGENAMEE' ),
+ 'subjectpagename' => array( 1, 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ),
+ 'subjectpagenamee' => array( 1, 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ),
+ 'msg' => array( 0, 'MSG:' ),
+ 'subst' => array( 0, 'SUBST:' ),
+ 'msgnw' => array( 0, 'MSGNW:' ),
+ 'end' => array( 0, '__END__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1'),
+ 'img_right' => array( 1, 'right' ),
+ 'img_left' => array( 1, 'left' ),
+ 'img_none' => array( 1, 'none' ),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame' ),
+ 'img_page' => array( 1, 'page=$1', 'page $1' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME' ),
+ 'ns' => array( 0, 'NS:' ),
+ 'localurl' => array( 0, 'LOCALURL:' ),
+ 'localurle' => array( 0, 'LOCALURLE:' ),
+ 'server' => array( 0, 'SERVER' ),
+ 'servername' => array( 0, 'SERVERNAME' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH' ),
+ 'grammar' => array( 0, 'GRAMMAR:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK' ),
+ 'currentdow' => array( 1, 'CURRENTDOW' ),
+ 'localweek' => array( 1, 'LOCALWEEK' ),
+ 'localdow' => array( 1, 'LOCALDOW' ),
+ 'revisionid' => array( 1, 'REVISIONID' ),
+ 'revisionday' => array( 1, 'REVISIONDAY' ),
+ 'revisionday2' => array( 1, 'REVISIONDAY2' ),
+ 'revisionmonth' => array( 1, 'REVISIONMONTH' ),
+ 'revisionyear' => array( 1, 'REVISIONYEAR' ),
+ 'revisiontimestamp' => array( 1, 'REVISIONTIMESTAMP' ),
+ 'plural' => array( 0, 'PLURAL:' ),
+ 'fullurl' => array( 0, 'FULLURL:' ),
+ 'fullurle' => array( 0, 'FULLURLE:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:' ),
+ 'lc' => array( 0, 'LC:' ),
+ 'uc' => array( 0, 'UC:' ),
+ 'raw' => array( 0, 'RAW:' ),
+ 'displaytitle' => array( 1, 'DISPLAYTITLE' ),
+ 'rawsuffix' => array( 1, 'R' ),
+ 'newsectionlink' => array( 1, '__NEWSECTIONLINK__' ),
+ 'currentversion' => array( 1, 'CURRENTVERSION' ),
+ 'urlencode' => array( 0, 'URLENCODE:' ),
+ 'anchorencode' => array( 0, 'ANCHORENCODE' ),
+ 'currenttimestamp' => array( 1, 'CURRENTTIMESTAMP' ),
+ 'localtimestamp' => array( 1, 'LOCALTIMESTAMP' ),
+ 'directionmark' => array( 1, 'DIRECTIONMARK', 'DIRMARK' ),
+ 'language' => array( 0, '#LANGUAGE:' ),
+ 'contentlanguage' => array( 1, 'CONTENTLANGUAGE', 'CONTENTLANG' ),
+ 'pagesinnamespace' => array( 1, 'PAGESINNAMESPACE:', 'PAGESINNS:' ),
+ 'numberofadmins' => array( 1, 'NUMBEROFADMINS' ),
+ 'formatnum' => array( 0, 'FORMATNUM' ),
+ 'padleft' => array( 0, 'PADLEFT' ),
+ 'padright' => array( 0, 'PADRIGHT' ),
+ 'special' => array( 0, 'special', ),
+ 'defaultsort' => array( 1, 'DEFAULTSORT:' ),
+);
+
+/**
+ * Alternate names of special pages. All names are case-insensitive. The first
+ * listed alias will be used as the default. Aliases from the fallback
+ * localisation (usually English) will be included by default.
+ *
+ * This array may be altered at runtime using the LangugeGetSpecialPageAliases
+ * hook.
+ */
+$specialPageAliases = array(
+ 'DoubleRedirects' => array( 'DoubleRedirects' ),
+ 'BrokenRedirects' => array( 'BrokenRedirects' ),
+ 'Disambiguations' => array( 'Disambiguations' ),
+ 'Userlogin' => array( 'Userlogin' ),
+ 'Userlogout' => array( 'Userlogout' ),
+ 'Preferences' => array( 'Preferences' ),
+ 'Watchlist' => array( 'Watchlist' ),
+ 'Recentchanges' => array( 'Recentchanges' ),
+ 'Upload' => array( 'Upload' ),
+ 'Imagelist' => array( 'Imagelist' ),
+ 'Newimages' => array( 'Newimages' ),
+ 'Listusers' => array( 'Listusers', 'Userlist' ),
+ 'Statistics' => array( 'Statistics' ),
+ 'Randompage' => array( 'Random', 'Randompage' ),
+ 'Lonelypages' => array( 'Lonelypages' ),
+ 'Uncategorizedpages' => array( 'Uncategorizedpages' ),
+ 'Uncategorizedcategories' => array( 'Uncategorizedcategories' ),
+ 'Uncategorizedimages' => array( 'Uncategorizedimages' ),
+ 'Unusedcategories' => array( 'Unusedcategories' ),
+ 'Unusedimages' => array( 'Unusedimages' ),
+ 'Wantedpages' => array( 'Wantedpages' ),
+ 'Wantedcategories' => array( 'Wantedcategories' ),
+ 'Mostlinked' => array( 'Mostlinked' ),
+ 'Mostlinkedcategories' => array( 'Mostlinkedcategories' ),
+ 'Mostcategories' => array( 'Mostcategories' ),
+ 'Mostimages' => array( 'Mostimages' ),
+ 'Mostrevisions' => array( 'Mostrevisions' ),
+ 'Shortpages' => array( 'Shortpages' ),
+ 'Longpages' => array( 'Longpages' ),
+ 'Newpages' => array( 'Newpages' ),
+ 'Ancientpages' => array( 'Ancientpages' ),
+ 'Deadendpages' => array( 'Deadendpages' ),
+ 'Allpages' => array( 'Allpages' ),
+ 'Prefixindex' => array( 'Prefixindex' ) ,
+ 'Ipblocklist' => array( 'Ipblocklist' ),
+ 'Specialpages' => array( 'Specialpages' ),
+ 'Contributions' => array( 'Contributions' ),
+ 'Emailuser' => array( 'Emailuser' ),
+ 'Whatlinkshere' => array( 'Whatlinkshere' ),
+ 'Recentchangeslinked' => array( 'Recentchangeslinked' ),
+ 'Movepage' => array( 'Movepage' ),
+ 'Blockme' => array( 'Blockme' ),
+ 'Booksources' => array( 'Booksources' ),
+ 'Categories' => array( 'Categories' ),
+ 'Export' => array( 'Export' ),
+ 'Version' => array( 'Version' ),
+ 'Allmessages' => array( 'Allmessages' ),
+ 'Log' => array( 'Log', 'Logs' ),
+ 'Blockip' => array( 'Blockip' ),
+ 'Undelete' => array( 'Undelete' ),
+ 'Import' => array( 'Import' ),
+ 'Lockdb' => array( 'Lockdb' ),
+ 'Unlockdb' => array( 'Unlockdb' ),
+ 'Userrights' => array( 'Userrights' ),
+ 'MIMEsearch' => array( 'MIMEsearch' ),
+ 'Unwatchedpages' => array( 'Unwatchedpages' ),
+ 'Listredirects' => array( 'Listredirects' ),
+ 'Listinterwikis' => array( 'Listinterwikis' ),
+ 'Revisiondelete' => array( 'Revisiondelete' ),
+ 'Unusedtemplates' => array( 'Unusedtemplates' ),
+ 'Randomredirect' => array( 'Randomredirect' ),
+ 'Mypage' => array( 'Mypage' ),
+ 'Mytalk' => array( 'Mytalk' ),
+ 'Mycontributions' => array( 'Mycontributions' ),
+ 'Listadmins' => array( 'Listadmins' ),
+ 'Popularpages' => array( 'Popularpages' ),
+ 'Search' => array( 'Search' ),
+ 'Resetpass' => array( 'Resetpass' ),
+);
+
+/**
+ * Regular expression matching the "link trail", e.g. "ed" in [[Toast]]ed, as
+ * the first group, and the remainder of the string as the second group.
+ */
+$linkTrail = '/^([a-z]+)(.*)$/sD';
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+# Allowed characters in keys are: A-Z, a-z, 0-9, underscore (_) and
+# hyphen (-). If you need more characters, you may be able to change
+# the regex in MagicWord::initRegex
+
+$messages = array(
+/*
+The sidebar for MonoBook is generated from this message, lines that do not
+begin with * or ** are discarded, furthermore lines that do begin with ** and
+do not contain | are also discarded, but don't depend on this behaviour for
+future releases. Also note that since each list value is wrapped in a unique
+XHTML id it should only appear once and include characters that are legal
+XHTML id names.
+
+Note to translators: Do not include this message in the language files you
+submit for inclusion in MediaWiki, it should always be inherited from the
+parent class in order maintain consistency across languages.
+*/
+'sidebar' => '
+* navigation
+** mainpage|mainpage
+** portal-url|portal
+** currentevents-url|currentevents
+** recentchanges-url|recentchanges
+** randompage-url|randompage
+** helppage|help
+** sitesupport-url|sitesupport',
+
+# User preference toggles
+'tog-underline' => 'Underline links:',
+'tog-highlightbroken' => 'Format broken links <a href="" class="new">like this</a> (alternative: like this<a href="" class="internal">?</a>).',
+'tog-justify' => 'Justify paragraphs',
+'tog-hideminor' => 'Hide minor edits in recent changes',
+'tog-extendwatchlist' => 'Expand watchlist to show all applicable changes',
+'tog-usenewrc' => 'Enhanced recent changes (JavaScript)',
+'tog-numberheadings' => 'Auto-number headings',
+'tog-showtoolbar' => 'Show edit toolbar (JavaScript)',
+'tog-editondblclick' => 'Edit pages on double click (JavaScript)',
+'tog-editsection' => 'Enable section editing via [edit] links',
+'tog-editsectiononrightclick' => 'Enable section editing by right clicking<br /> on section titles (JavaScript)',
+'tog-showtoc' => 'Show table of contents (for pages with more than 3 headings)',
+'tog-rememberpassword' => 'Remember my login on this computer',
+'tog-editwidth' => 'Edit box has full width',
+'tog-watchcreations' => 'Add pages I create to my watchlist',
+'tog-watchdefault' => 'Add pages I edit to my watchlist',
+'tog-watchmoves' => 'Add pages I move to my watchlist',
+'tog-watchdeletion' => 'Add pages I delete to my watchlist',
+'tog-minordefault' => 'Mark all edits minor by default',
+'tog-previewontop' => 'Show preview before edit box',
+'tog-previewonfirst' => 'Show preview on first edit',
+'tog-nocache' => 'Disable page caching',
+'tog-enotifwatchlistpages' => 'E-mail me when a page I\'m watching is changed',
+'tog-enotifusertalkpages' => 'E-mail me when my user talk page is changed',
+'tog-enotifminoredits' => 'E-mail me also for minor edits of pages',
+'tog-enotifrevealaddr' => 'Reveal my e-mail address in notification mails',
+'tog-shownumberswatching' => 'Show the number of watching users',
+'tog-fancysig' => 'Raw signatures (without automatic link)',
+'tog-externaleditor' => 'Use external editor by default',
+'tog-externaldiff' => 'Use external diff by default',
+'tog-showjumplinks' => 'Enable "jump to" accessibility links',
+'tog-uselivepreview' => 'Use live preview (JavaScript) (Experimental)',
+'tog-forceeditsummary' => 'Prompt me when entering a blank edit summary',
+'tog-watchlisthideown' => 'Hide my edits from the watchlist',
+'tog-watchlisthidebots' => 'Hide bot edits from the watchlist',
+'tog-watchlisthideminor' => 'Hide minor edits from the watchlist',
+'tog-nolangconversion' => 'Disable variants conversion',
+'tog-ccmeonemails' => 'Send me copies of emails I send to other users',
+
+'underline-always' => 'Always',
+'underline-never' => 'Never',
+'underline-default' => 'Browser default',
+
+'skinpreview' => '(Preview)',
+
+# dates
+'sunday' => 'Sunday',
+'monday' => 'Monday',
+'tuesday' => 'Tuesday',
+'wednesday' => 'Wednesday',
+'thursday' => 'Thursday',
+'friday' => 'Friday',
+'saturday' => 'Saturday',
+'sun' => 'Sun',
+'mon' => 'Mon',
+'tue' => 'Tue',
+'wed' => 'Wed',
+'thu' => 'Thu',
+'fri' => 'Fri',
+'sat' => 'Sat',
+'january' => 'January',
+'february' => 'February',
+'march' => 'March',
+'april' => 'April',
+'may_long' => 'May',
+'june' => 'June',
+'july' => 'July',
+'august' => 'August',
+'september' => 'September',
+'october' => 'October',
+'november' => 'November',
+'december' => 'December',
+'january-gen' => 'January',
+'february-gen' => 'February',
+'march-gen' => 'March',
+'april-gen' => 'April',
+'may-gen' => 'May',
+'june-gen' => 'June',
+'july-gen' => 'July',
+'august-gen' => 'August',
+'september-gen' => 'September',
+'october-gen' => 'October',
+'november-gen' => 'November',
+'december-gen' => 'December',
+'jan' => 'Jan',
+'feb' => 'Feb',
+'mar' => 'Mar',
+'apr' => 'Apr',
+'may' => 'May',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Aug',
+'sep' => 'Sep',
+'oct' => 'Oct',
+'nov' => 'Nov',
+'dec' => 'Dec',
+# Bits of text used by many pages:
+#
+'categories' => 'Categories',
+'pagecategories' => '{{PLURAL:$1|Category|Categories}}',
+'pagecategorieslink' => 'Special:Categories',
+'category_header' => 'Articles in category "$1"',
+'subcategories' => 'Subcategories',
+'category-media-header' => 'Media in category "$1"',
+
+
+'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD',
+'mainpage' => 'Main Page',
+'mainpagetext' => "<big>'''MediaWiki has been successfully installed.'''</big>",
+'mainpagedocfooter' => "Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
+
+== Getting started ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]",
+
+'portal' => 'Community portal',
+'portal-url' => 'Project:Community Portal',
+'about' => 'About',
+'aboutsite' => 'About {{SITENAME}}',
+'aboutpage' => 'Project:About',
+'article' => 'Content page',
+'help' => 'Help',
+'helppage' => 'Help:Contents',
+'bugreports' => 'Bug reports',
+'bugreportspage' => 'Project:Bug_reports',
+'sitesupport' => 'Donations',
+'sitesupport-url' => 'Project:Site support',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => 'Editing help',
+'newwindow' => '(opens in new window)',
+'edithelppage' => 'Help:Editing',
+'cancel' => 'Cancel',
+'qbfind' => 'Find',
+'qbbrowse' => 'Browse',
+'qbedit' => 'Edit',
+'qbpageoptions' => 'This page',
+'qbpageinfo' => 'Context',
+'qbmyoptions' => 'My pages',
+'qbspecialpages' => 'Special pages',
+'moredotdotdot' => 'More...',
+'mypage' => 'My page',
+'mytalk' => 'My talk',
+'anontalk' => 'Talk for this IP',
+'navigation' => 'Navigation',
+
+# Metadata in edit box
+'metadata_help' => 'Metadata (see [[{{ns:project}}:Metadata]] for an explanation):',
+
+'currentevents' => 'Current events',
+'currentevents-url' => 'Current events',
+
+'disclaimers' => 'Disclaimers',
+'disclaimerpage' => 'Project:General_disclaimer',
+'privacy' => 'Privacy policy',
+'privacypage' => 'Project:Privacy_policy',
+'errorpagetitle' => 'Error',
+'returnto' => 'Return to $1.',
+'tagline' => 'From {{SITENAME}}',
+'help' => 'Help',
+'search' => 'Search',
+'searchbutton' => 'Search',
+'go' => 'Go',
+'searcharticle' => 'Go',
+'history' => 'Page history',
+'history_short' => 'History',
+'updatedmarker' => 'updated since my last visit',
+'info_short' => 'Information',
+'printableversion' => 'Printable version',
+'permalink' => 'Permanent link',
+'print' => 'Print',
+'edit' => 'Edit',
+'editthispage' => 'Edit this page',
+'delete' => 'Delete',
+'deletethispage' => 'Delete this page',
+'undelete_short' => 'Undelete {{PLURAL:$1|one edit|$1 edits}}',
+'protect' => 'Protect',
+'protectthispage' => 'Protect this page',
+'unprotect' => 'unprotect',
+'unprotectthispage' => 'Unprotect this page',
+'newpage' => 'New page',
+'talkpage' => 'Discuss this page',
+'specialpage' => 'Special Page',
+'personaltools' => 'Personal tools',
+'postcomment' => 'Post a comment',
+'addsection' => '+',
+'articlepage' => 'View content page',
+'talk' => 'Discussion',
+'views' => 'Views',
+'toolbox' => 'Toolbox',
+'userpage' => 'View user page',
+'projectpage' => 'View project page',
+'imagepage' => 'View image page',
+'mediawikipage' => 'View message page',
+'templatepage' => 'View template page',
+'viewhelppage' => 'View help page',
+'categorypage' => 'View category page',
+'viewtalkpage' => 'View discussion',
+'otherlanguages' => 'In other languages',
+'redirectedfrom' => '(Redirected from $1)',
+'redirectpagesub' => 'Redirect page',
+'lastmodifiedat' => 'This page was last modified $2, $1.', //$1 date, $2 time
+'viewcount' => 'This page has been accessed {{plural:$1|one time|$1 times}}.',
+'copyright' => 'Content is available under $1.',
+'protectedpage' => 'Protected page',
+'jumpto' => 'Jump to:',
+'jumptonavigation' => 'navigation',
+'jumptosearch' => 'search',
+
+'badaccess' => 'Permission error',
+'badaccess-group0' => 'You are not allowed to execute the action you have requested.',
+'badaccess-group1' => 'The action you have requested is limited to users in the group $1.',
+'badaccess-group2' => 'The action you have requested is limited to users in one of the groups $1.',
+'badaccess-groups' => 'The action you have requested is limited to users in one of the groups $1.',
+
+'versionrequired' => 'Version $1 of MediaWiki required',
+'versionrequiredtext' => 'Version $1 of MediaWiki is required to use this page. See [[Special:Version]]',
+
+'widthheight' => '$1×$2',
+'ok' => 'OK',
+'sitetitle' => '{{SITENAME}}',
+'pagetitle' => '$1 - {{SITENAME}}',
+'sitesubtitle' => '',
+'retrievedfrom' => 'Retrieved from "$1"',
+'youhavenewmessages' => 'You have $1 ($2).',
+'newmessageslink' => 'new messages',
+'newmessagesdifflink' => 'last change',
+'editsection'=>'edit',
+'editold'=>'edit',
+'editsectionhint' => 'Edit section: $1',
+'toc' => 'Contents',
+'showtoc' => 'show',
+'hidetoc' => 'hide',
+'thisisdeleted' => 'View or restore $1?',
+'viewdeleted' => 'View $1?',
+'restorelink' => '{{PLURAL:$1|one deleted edit|$1 deleted edits}}',
+'feedlinks' => 'Feed:',
+'feed-invalid' => 'Invalid subscription feed type.',
+'feed-atom' => 'Atom',
+'feed-rss' => 'RSS',
+'sitenotice' => '-', # the equivalent to wgSiteNotice
+'anonnotice' => '-',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Article',
+'nstab-user' => 'User page',
+'nstab-media' => 'Media page',
+'nstab-special' => 'Special',
+'nstab-project' => 'Project page',
+'nstab-image' => 'File',
+'nstab-mediawiki' => 'Message',
+'nstab-template' => 'Template',
+'nstab-help' => 'Help page',
+'nstab-category' => 'Category',
+
+# Main script and global functions
+#
+'nosuchaction' => 'No such action',
+'nosuchactiontext' => 'The action specified by the URL is not
+recognized by the wiki',
+'nosuchspecialpage' => 'No such special page',
+'nospecialpagetext' => 'You have requested an invalid special page, a list of valid special pages may be found at [[{{ns:special}}:Specialpages]].',
+
+# General errors
+#
+'error' => 'Error',
+'databaseerror' => 'Database error',
+'dberrortext' => 'A database query syntax error has occurred.
+This may indicate a bug in the software.
+The last attempted database query was:
+<blockquote><tt>$1</tt></blockquote>
+from within function "<tt>$2</tt>".
+MySQL returned error "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'A database query syntax error has occurred.
+The last attempted database query was:
+"$1"
+from within function "$2".
+MySQL returned error "$3: $4"',
+'noconnect' => 'Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server. <br />
+$1',
+'nodb' => 'Could not select database $1',
+'cachederror' => 'The following is a cached copy of the requested page, and may not be up to date.',
+'laggedslavemode' => 'Warning: Page may not contain recent updates.',
+'readonly' => 'Database locked',
+'enterlockreason' => 'Enter a reason for the lock, including an estimate
+of when the lock will be released',
+'readonlytext' => 'The database is currently locked to new entries and other modifications, probably for routine database maintenance, after which it will be back to normal.
+
+The administrator who locked it offered this explanation: $1',
+'missingarticle' => 'The database did not find the text of a page that it should have found, named "$1".
+
+This is usually caused by following an outdated diff or history link to a
+page that has been deleted.
+
+If this is not the case, you may have found a bug in the software.
+Please report this to an administrator, making note of the URL.',
+'readonly_lag' => 'The database has been automatically locked while the slave database servers catch up to the master',
+'internalerror' => 'Internal error',
+'filecopyerror' => 'Could not copy file "$1" to "$2".',
+'filerenameerror' => 'Could not rename file "$1" to "$2".',
+'filedeleteerror' => 'Could not delete file "$1".',
+'filenotfound' => 'Could not find file "$1".',
+'unexpected' => 'Unexpected value: "$1"="$2".',
+'formerror' => 'Error: could not submit form',
+'badarticleerror' => 'This action cannot be performed on this page.',
+'cannotdelete' => 'Could not delete the page or file specified. (It may have already been deleted by someone else.)',
+'badtitle' => 'Bad title',
+'badtitletext' => 'The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.',
+'perfdisabled' => 'Sorry! This feature has been temporarily disabled because it slows the database down to the point that no one can use the wiki.',
+'perfdisabledsub' => 'Here is a saved copy from $1:', # obsolete?
+'perfcached' => 'The following data is cached and may not be up to date.',
+'perfcachedts' => 'The following data is cached, and was last updated $1.',
+'querypage-no-updates' => 'Updates for this page are currently disabled. Data here will not presently be refreshed.',
+'wrong_wfQuery_params' => 'Incorrect parameters to wfQuery()<br />
+Function: $1<br />
+Query: $2',
+'viewsource' => 'View source',
+'viewsourcefor' => 'for $1',
+'protectedpagetext' => 'This page has been locked to prevent editing.',
+'viewsourcetext' => 'You can view and copy the source of this page:',
+'protectedinterface' => 'This page provides interface text for the software, and is locked to prevent abuse.',
+'editinginterface' => "'''Warning:''' You are editing a page which is used to provide interface text for the software. Changes to this page will affect the appearance of the user interface for other users.",
+'sqlhidden' => '(SQL query hidden)',
+
+# Login and logout pages
+#
+'logouttitle' => 'User logout',
+'logouttext' => '<strong>You are now logged out.</strong><br />
+You can continue to use {{SITENAME}} anonymously, or you can log in
+again as the same or as a different user. Note that some pages may
+continue to be displayed as if you were still logged in, until you clear
+your browser cache.',
+
+'welcomecreation' => "== Welcome, $1! ==
+
+Your account has been created. Don't forget to change your {{SITENAME}} preferences.",
+
+'loginpagetitle' => 'User login',
+'yourname' => 'Username',
+'yourpassword' => 'Password',
+'yourpasswordagain' => 'Retype password',
+'remembermypassword' => 'Remember my login on this computer',
+'yourdomainname' => 'Your domain',
+'externaldberror' => 'There was either an external authentication database error or you are not allowed to update your external account.',
+'loginproblem' => '<b>There has been a problem with your login.</b><br />Try again!',
+'alreadyloggedin' => "<strong>User $1, you are already logged in!</strong><br />",
+
+'login' => 'Log in',
+'loginprompt' => 'You must have cookies enabled to log in to {{SITENAME}}.',
+'userlogin' => 'Log in / create account',
+'logout' => 'Log out',
+'userlogout' => 'Log out',
+'notloggedin' => 'Not logged in',
+'nologin' => 'Don\'t have a login? $1.',
+'nologinlink' => 'Create an account',
+'createaccount' => 'Create account',
+'gotaccount' => 'Already have an account? $1.',
+'gotaccountlink' => 'Log in',
+'createaccountmail' => 'by e-mail',
+'badretype' => 'The passwords you entered do not match.',
+'userexists' => 'Username entered already in use. Please choose a different name.',
+'youremail' => 'E-mail *:',
+'username' => 'Username:',
+'uid' => 'User ID:',
+'yourrealname' => 'Real name *:',
+'yourlanguage' => 'Language:',
+'yourvariant' => 'Variant',
+'yournick' => 'Nickname:',
+'badsig' => 'Invalid raw signature; check HTML tags.',
+'email' => 'E-mail',
+'prefs-help-email-enotif' => 'This address is also used to send you e-mail notifications if you enabled the options.',
+'prefs-help-realname' => '* Real name (optional): if you choose to provide it this will be used for giving you attribution for your work.',
+'loginerror' => 'Login error',
+'prefs-help-email' => '* E-mail (optional): Enables others to contact you through your user or user_talk page without needing to reveal your identity.',
+'nocookiesnew' => 'The user account was created, but you are not logged in. {{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them, then log in with your new username and password.',
+'nocookieslogin' => '{{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them and try again.',
+'noname' => 'You have not specified a valid user name.',
+'loginsuccesstitle' => 'Login successful',
+'loginsuccess' => "'''You are now logged in to {{SITENAME}} as \"$1\".'''",
+'nosuchuser' => 'There is no user by the name "$1". Check your spelling, or create a new account.',
+'nosuchusershort' => 'There is no user by the name "$1". Check your spelling.',
+'nouserspecified' => 'You have to specify a username.',
+'wrongpassword' => 'Incorrect password entered. Please try again.',
+'wrongpasswordempty' => 'Password entered was blank. Please try again.',
+'mailmypassword' => 'E-mail password',
+'passwordremindertitle' => 'Password reminder from {{SITENAME}}',
+'passwordremindertext' => 'Someone (probably you, from IP address $1)
+requested that we send you a new password for {{SITENAME}} ($4).
+The password for user "$2" is now "$3".
+You should log in and change your password now.
+
+If someone else made this request or if you have remembered your password and
+you no longer wish to change it, you may ignore this message and continue using
+your old password.',
+'noemail' => 'There is no e-mail address recorded for user "$1".',
+'passwordsent' => 'A new password has been sent to the e-mail address
+registered for "$1".
+Please log in again after you receive it.',
+'blocked-mailpassword' => 'Your IP address is blocked from editing, and so
+is not allowed to use the password recovery function to prevent abuse.',
+'eauthentsent' => 'A confirmation e-mail has been sent to the nominated e-mail address.
+Before any other mail is sent to the account, you will have to follow the instructions in the e-mail,
+to confirm that the account is actually yours.',
+'throttled-mailpassword' => 'A password reminder has already been sent, within the
+last $1 hours. To prevent abuse, only one password reminder will be sent per
+$1 hours.',
+'loginend' => '',
+'signupend' => '{{int:loginend}}',
+'mailerror' => 'Error sending mail: $1',
+'acct_creation_throttle_hit' => 'Sorry, you have already created $1 accounts. You can\'t make any more.',
+'emailauthenticated' => 'Your e-mail address was authenticated on $1.',
+'emailnotauthenticated' => 'Your e-mail address is not yet authenticated. No e-mail
+will be sent for any of the following features.',
+'noemailprefs' => 'Specify an e-mail address for these features to work.',
+'emailconfirmlink' => 'Confirm your e-mail address',
+'invalidemailaddress' => 'The e-mail address cannot be accepted as it appears to have an invalid
+format. Please enter a well-formatted address or empty that field.',
+'accountcreated' => 'Account created',
+'accountcreatedtext' => 'The user account for $1 has been created.',
+
+# Password reset dialog
+'resetpass' => 'Reset account password',
+'resetpass_announce' => 'You logged in with a temporary e-mailed code. To finish logging in, you must set a new password here:',
+'resetpass_text' => "<!-- Add text here -->",
+'resetpass_header' => 'Reset password',
+'resetpass_submit' => 'Set password and log in',
+'resetpass_success' => 'Your password has been changed successfully! Now logging you in...',
+'resetpass_bad_temporary' => 'Invalid temporary password. You may have already successfully changed your password or requested a new temporary password.',
+'resetpass_forbidden' => 'Passwords cannot be changed on this wiki',
+'resetpass_missing' => 'No form data.',
+
+
+# Edit page toolbar
+'bold_sample'=>'Bold text',
+'bold_tip'=>'Bold text',
+'italic_sample'=>'Italic text',
+'italic_tip'=>'Italic text',
+'link_sample'=>'Link title',
+'link_tip'=>'Internal link',
+'extlink_sample'=>'http://www.example.com link title',
+'extlink_tip'=>'External link (remember http:// prefix)',
+'headline_sample'=>'Headline text',
+'headline_tip'=>'Level 2 headline',
+'math_sample'=>'Insert formula here',
+'math_tip'=>'Mathematical formula (LaTeX)',
+'nowiki_sample'=>'Insert non-formatted text here',
+'nowiki_tip'=>'Ignore wiki formatting',
+'image_sample'=>'Example.jpg',
+'image_tip'=>'Embedded image',
+'media_sample'=>'Example.ogg',
+'media_tip'=>'Media file link',
+'sig_tip'=>'Your signature with timestamp',
+'hr_tip'=>'Horizontal line (use sparingly)',
+
+# Edit pages
+#
+'summary' => 'Summary',
+'subject' => 'Subject/headline',
+'minoredit' => 'This is a minor edit',
+'watchthis' => 'Watch this page',
+'savearticle' => 'Save page',
+'preview' => 'Preview',
+'showpreview' => 'Show preview',
+'showlivepreview' => 'Live preview',
+'showdiff' => 'Show changes',
+'anoneditwarning' => "'''Warning:''' You are not logged in. Your IP address will be recorded in this page's edit history.",
+'missingsummary' => "'''Reminder:''' You have not provided an edit summary. If you click Save again, your edit will be saved without one.",
+'missingcommenttext' => 'Please enter a comment below.',
+'missingcommentheader' => "'''Reminder:''' You have not provided a subject/headline for this comment. If you click Save again, your edit will be saved without one.",
+'summary-preview' => 'Summary preview',
+'subject-preview' => 'Subject/headline preview',
+'blockedtitle' => 'User is blocked',
+'blockedtext' => "<big>'''Your user name or IP address has been blocked.'''</big>
+
+The block was made by $1. The reason given is ''$2''.
+
+You can contact $1 or another [[{{ns:project}}:Administrators|administrator]] to discuss the block.
+You cannot use the 'email this user' feature unless a valid email address is specified in your
+[[Special:Preferences|account preferences]]. Your current IP address is $3, and the block ID is #$5. Please include either or both of these in any queries.",
+'blockedoriginalsource' => "The source of '''$1''' is shown below:",
+'blockededitsource' => "The text of '''your edits''' to '''$1''' is shown below:",
+'whitelistedittitle' => 'Login required to edit',
+'whitelistedittext' => 'You have to $1 to edit pages.',
+'whitelistreadtitle' => 'Login required to read',
+'whitelistreadtext' => 'You have to [[Special:Userlogin|login]] to read pages.',
+'whitelistacctitle' => 'You are not allowed to create an account',
+'whitelistacctext' => 'To be allowed to create accounts in this Wiki you have to [[Special:Userlogin|log]] in and have the appropriate permissions.',
+'confirmedittitle' => 'E-mail confirmation required to edit',
+'confirmedittext' => 'You must confirm your e-mail address before editing pages. Please set and validate your e-mail address through your [[Special:Preferences|user preferences]].',
+'loginreqtitle' => 'Login Required',
+'loginreqlink' => 'log in',
+'loginreqpagetext' => 'You must $1 to view other pages.',
+'accmailtitle' => 'Password sent.',
+'accmailtext' => 'The password for "$1" has been sent to $2.',
+'newarticle' => '(New)',
+'newarticletext' =>
+"You've followed a link to a page that doesn't exist yet.
+To create the page, start typing in the box below
+(see the [[{{ns:help}}:Contents|help page]] for more info).
+If you are here by mistake, just click your browser's '''back''' button.",
+'newarticletextanon' => '{{int:newarticletext}}',
+'talkpagetext' => '<!-- MediaWiki:talkpagetext -->',
+'anontalkpagetext' => "----''This is the discussion page for an anonymous user who has not created an account yet or who does not use it. We therefore have to use the numerical IP address to identify him/her. Such an IP address can be shared by several users. If you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:Userlogin|create an account or log in]] to avoid future confusion with other anonymous users.''",
+'noarticletext' => 'There is currently no text in this page, you can [[{{ns:special}}:Search/{{PAGENAME}}|search for this page title]] in other pages or [{{fullurl:{{FULLPAGENAME}}|action=edit}} edit this page].',
+'noarticletextanon' => '{{int:noarticletext}}',
+'clearyourcache' => "'''Note:''' After saving, you may have to bypass your browser's cache to see the changes. '''Mozilla / Firefox / Safari:''' hold down ''Shift'' while clicking ''Reload'', or press ''Ctrl-Shift-R'' (''Cmd-Shift-R'' on Apple Mac); '''IE:''' hold ''Ctrl'' while clicking ''Refresh'', or press ''Ctrl-F5''; '''Konqueror:''': simply click the ''Reload'' button, or press ''F5''; '''Opera''' users may need to completely clear their cache in ''Tools→Preferences''.",
+'usercssjsyoucanpreview' => '<strong>Tip:</strong> Use the \'Show preview\' button to test your new CSS/JS before saving.',
+'usercsspreview' => '\'\'\'Remember that you are only previewing your user CSS, it has not yet been saved!\'\'\'',
+'userjspreview' => '\'\'\'Remember that you are only testing/previewing your user JavaScript, it has not yet been saved!\'\'\'',
+'userinvalidcssjstitle' => "'''Warning:''' There is no skin \"$1\". Remember that custom .css and .js pages use a lowercase title, e.g. User:Foo/monobook.css as opposed to User:Foo/Monobook.css.",
+'updated' => '(Updated)',
+'note' => '<strong>Note:</strong>',
+'previewnote' => '<strong>This is only a preview; changes have not yet been saved!</strong>',
+'session_fail_preview' => '<strong>Sorry! We could not process your edit due to a loss of session data.
+Please try again. If it still doesn\'t work, try logging out and logging back in.</strong>',
+'previewconflict' => 'This preview reflects the text in the upper text editing area as it will appear if you choose to save.',
+'session_fail_preview_html' => '<strong>Sorry! We could not process your edit due to a loss of session data.</strong>
+
+\'\'Because this wiki has raw HTML enabled, the preview is hidden as a precaution against JavaScript attacks.\'\'
+
+<strong>If this is a legitimate edit attempt, please try again. If it still doesn\'t work, try logging out and logging back in.</strong>',
+'importing' => 'Importing $1',
+'editing' => 'Editing $1',
+'editinguser' => 'Editing user <b>$1</b>',
+'editingsection' => 'Editing $1 (section)',
+'editingcomment' => 'Editing $1 (comment)',
+'editconflict' => 'Edit conflict: $1',
+'explainconflict' => 'Someone else has changed this page since you started editing it.
+The upper text area contains the page text as it currently exists.
+Your changes are shown in the lower text area.
+You will have to merge your changes into the existing text.
+<b>Only</b> the text in the upper text area will be saved when you
+press "Save page".<br />',
+'yourtext' => 'Your text',
+'storedversion' => 'Stored version',
+'nonunicodebrowser' => "<strong>WARNING: Your browser is not unicode compliant. A workaround is in place to allow you to safely edit articles: non-ASCII characters will appear in the edit box as hexadecimal codes.</strong>",
+'editingold' => "<strong>WARNING: You are editing an out-of-date
+revision of this page.
+If you save it, any changes made since this revision will be lost.</strong>",
+'yourdiff' => 'Differences',
+'copyrightwarning' => 'Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details). If you don\'t want your writing to be edited mercilessly and redistributed at will, then don\'t submit it here.<br />
+You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
+<strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong>',
+'copyrightwarning2' => 'Please note that all contributions to {{SITENAME}} may be edited, altered, or removed by other contributors. If you don\'t want your writing to be edited mercilessly, then don\'t submit it here.<br />
+You are also promising us that you wrote this yourself, or copied it from a
+public domain or similar free resource (see $1 for details).
+<strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong>',
+'longpagewarning' => "<strong>WARNING: This page is $1 kilobytes long; some
+browsers may have problems editing pages approaching or longer than 32kb.
+Please consider breaking the page into smaller sections.</strong>",
+'longpageerror' => "<strong>ERROR: The text you have submitted is $1 kilobytes
+long, which is longer than the maximum of $2 kilobytes. It cannot be saved.</strong>",
+'readonlywarning' => '<strong>WARNING: The database has been locked for maintenance,
+so you will not be able to save your edits right now. You may wish to cut-n-paste
+the text into a text file and save it for later.</strong>',
+'protectedpagewarning' => "<strong>WARNING: This page has been locked so that only users with sysop privileges can edit it.</strong>",
+'semiprotectedpagewarning' => "'''Note:''' This page has been locked so that only registered users can edit it.",
+'templatesused' => 'Templates used on this page:',
+'templatesusedpreview' => 'Templates used in this preview:',
+'templatesusedsection' => 'Templates used in this section:',
+'template-protected' => '(protected)',
+'template-semiprotected' => '(semi-protected)',
+'edittools' => '<!-- Text here will be shown below edit and upload forms. -->',
+'nocreatetitle' => 'Page creation limited',
+'nocreatetext' => 'This site has restricted the ability to create new pages.
+You can go back and edit an existing page, or [[Special:Userlogin|log in or create an account]].',
+
+# "Undo" feature
+'undo-success' => 'The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.',
+'undo-failure' => 'The edit could not be undone due to conflicting intermediate edits.',
+'undo-summary' => 'Undo revision $1 by [[Special:Contributions/$2]] ([[User talk:$2]])',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'Can\'t create account',
+'cantcreateaccounttext' => 'Account creation from this IP address (<b>$1</b>) has been blocked.
+This is probably due to persistent vandalism from your school or Internet service
+provider.',
+
+# History pages
+#
+'revhistory' => 'Revision history',
+'viewpagelogs' => 'View logs for this page',
+'nohistory' => 'There is no edit history for this page.',
+'revnotfound' => 'Revision not found',
+'revnotfoundtext' => "The old revision of the page you asked for could not be found.
+Please check the URL you used to access this page.",
+'loadhist' => 'Loading page history',
+'currentrev' => 'Current revision',
+'revisionasof' => 'Revision as of $1',
+'revision-info' => 'Revision as of $1 by $2',
+'revision-nav' => '($1) $2 | $3 ($4) | $5 ($6)',
+'previousrevision' => '←Older revision',
+'nextrevision' => 'Newer revision→',
+'currentrevisionlink' => 'Current revision',
+'cur' => 'cur',
+'next' => 'next',
+'last' => 'last',
+'orig' => 'orig',
+'histlegend' => 'Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.<br />
+Legend: (cur) = difference with current version,
+(last) = difference with preceding version, M = minor edit.',
+'history_copyright' => '-',
+'deletedrev' => '[deleted]',
+'histfirst' => 'Earliest',
+'histlast' => 'Latest',
+'rev-deleted-comment' => '(comment removed)',
+'rev-deleted-user' => '(username removed)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+This page revision has been removed from the public archives.
+There may be details in the [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} deletion log].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+This page revision has been removed from the public archives.
+As an administrator on this site you can view it;
+there may be details in the [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} deletion log].
+</div>',
+#'rev-delundel' => 'del/undel',
+'rev-delundel' => 'show/hide',
+
+
+'history-feed-title' => 'Revision history',
+'history-feed-description' => 'Revision history for this page on the wiki',
+'history-feed-item-nocomment' => '$1 at $2', # user at time
+'history-feed-empty' => 'The requested page doesn\'t exist.
+It may have been deleted from the wiki, or renamed.
+Try [[Special:Search|searching on the wiki]] for relevant new pages.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Delete/undelete revisions',
+'revdelete-nooldid-title' => 'No target revision',
+'revdelete-nooldid-text' => 'You have not specified target revision or revisions
+to perform this function on.',
+'revdelete-selected' => 'Selected revision of [[:$1]]:',
+'revdelete-text' => "Deleted revisions will still appear in the page history,
+but their text contents will be inaccessible to the public.
+
+Other admins on this wiki will still be able to access the hidden content and can
+undelete it again through this same interface, unless an additional restriction
+is placed by the site operators.",
+'revdelete-legend' => 'Set revision restrictions:',
+'revdelete-hide-text' => 'Hide revision text',
+'revdelete-hide-comment' => 'Hide edit comment',
+'revdelete-hide-user' => 'Hide editor\'s username/IP',
+'revdelete-hide-restricted' => 'Apply these restrictions to sysops as well as others',
+'revdelete-log' => 'Log comment:',
+'revdelete-submit' => 'Apply to selected revision',
+'revdelete-logentry' => 'changed revision visibility for [[$1]]',
+
+# Diffs
+#
+'difference' => '(Difference between revisions)',
+'loadingrev' => 'loading revision for diff',
+'lineno' => "Line $1:",
+'editcurrent' => 'Edit the current version of this page',
+'selectnewerversionfordiff' => 'Select a newer version for comparison',
+'selectolderversionfordiff' => 'Select an older version for comparison',
+'compareselectedversions' => 'Compare selected versions',
+'editundo' => 'undo',
+'diff-multi' => "({{plural:$1|One intermediate revision|$1 intermediate revisions}} not shown.)",
+
+# Search results
+#
+'searchresults' => 'Search results',
+'searchresulttext' => "For more information about searching {{SITENAME}}, see [[{{ns:project}}:Searching|Searching {{SITENAME}}]].",
+'searchsubtitle' => "You searched for '''[[:$1]]'''",
+'searchsubtitleinvalid' => "You searched for '''$1'''",
+'badquery' => 'Badly formed search query',
+'badquerytext' => 'We could not process your query.
+This is probably because you have attempted to search for a
+word fewer than three letters long, which is not yet supported.
+It could also be that you have mistyped the expression, for
+example "fish and and scales".
+Please try another query.',
+'matchtotals' => "The query \"$1\" matched $2 page titles
+and the text of $3 pages.",
+'noexactmatch' => "'''There is no page titled \"$1\".''' You can [[:$1|create this page]].",
+'titlematches' => 'Article title matches',
+'notitlematches' => 'No page title matches',
+'textmatches' => 'Page text matches',
+'notextmatches' => 'No page text matches',
+'prevn' => "previous $1",
+'nextn' => "next $1",
+'viewprevnext' => "View ($1) ($2) ($3).",
+'showingresults' => "Showing below up to <b>$1</b> results starting with #<b>$2</b>.",
+'showingresultsnum' => "Showing below <b>$3</b> results starting with #<b>$2</b>.",
+'nonefound' => "'''Note''': Unsuccessful searches are
+often caused by searching for common words like \"have\" and \"from\",
+which are not indexed, or by specifying more than one search term (only pages
+containing all of the search terms will appear in the result).",
+'powersearch' => 'Search',
+'powersearchtext' => "Search in namespaces:<br />$1<br />$2 List redirects<br />Search for $3 $9",
+'searchdisabled' => '{{SITENAME}} search is disabled. You can search via Google in the meantime. Note that their indexes of {{SITENAME}} content may be out of date.',
+
+'googlesearch' => '
+<form method="get" action="http://www.google.com/search" id="googlesearch">
+ <input type="hidden" name="domains" value="{{SERVER}}" />
+ <input type="hidden" name="num" value="50" />
+ <input type="hidden" name="ie" value="$2" />
+ <input type="hidden" name="oe" value="$2" />
+
+ <input type="text" name="q" size="31" maxlength="255" value="$1" />
+ <input type="submit" name="btnG" value="$3" />
+ <div>
+ <input type="radio" name="sitesearch" id="gwiki" value="{{SERVER}}" checked="checked" /><label for="gwiki">{{SITENAME}}</label>
+ <input type="radio" name="sitesearch" id="gWWW" value="" /><label for="gWWW">WWW</label>
+ </div>
+</form>',
+'blanknamespace' => '(Main)',
+
+# Preferences page
+#
+'preferences' => 'Preferences',
+'preferences-summary' => '',
+'mypreferences' => 'My preferences',
+'prefsnologin' => 'Not logged in',
+'prefsnologintext' => "You must be [[Special:Userlogin|logged in]] to set user preferences.",
+'prefsreset' => 'Preferences have been reset from storage.',
+'qbsettings' => 'Quickbar',
+'changepassword' => 'Change password',
+'skin' => 'Skin',
+'math' => 'Math',
+'dateformat' => 'Date format',
+'datedefault' => 'No preference',
+'datetime' => 'Date and time',
+'math_failure' => 'Failed to parse',
+'math_unknown_error' => 'unknown error',
+'math_unknown_function' => 'unknown function',
+'math_lexing_error' => 'lexing error',
+'math_syntax_error' => 'syntax error',
+'math_image_error' => 'PNG conversion failed; check for correct installation of latex, dvips, gs, and convert',
+'math_bad_tmpdir' => 'Can\'t write to or create math temp directory',
+'math_bad_output' => 'Can\'t write to or create math output directory',
+'math_notexvc' => 'Missing texvc executable; please see math/README to configure.',
+'prefs-personal' => 'User profile',
+'prefs-rc' => 'Recent changes',
+'prefs-watchlist' => 'Watchlist',
+'prefs-watchlist-days' => 'Number of days to show in watchlist:',
+'prefs-watchlist-edits' => 'Number of edits to show in expanded watchlist:',
+'prefs-misc' => 'Misc',
+'saveprefs' => 'Save',
+'resetprefs' => 'Reset',
+'oldpassword' => 'Old password:',
+'newpassword' => 'New password:',
+'retypenew' => 'Retype new password:',
+'textboxsize' => 'Editing',
+'rows' => 'Rows:',
+'columns' => 'Columns:',
+'searchresultshead' => 'Search',
+'resultsperpage' => 'Hits per page:',
+'contextlines' => 'Lines per hit:',
+'contextchars' => 'Context per line:',
+'stubthreshold' => 'Threshold for stub display:',
+'recentchangescount' => 'Titles in recent changes:',
+'savedprefs' => 'Your preferences have been saved.',
+'timezonelegend' => 'Time zone',
+'timezonetext' => 'The number of hours your local time differs from server time (UTC).',
+'localtime' => 'Local time',
+'timezoneoffset' => 'Offset¹',
+'servertime' => 'Server time',
+'guesstimezone' => 'Fill in from browser',
+'allowemail' => 'Enable e-mail from other users',
+'defaultns' => 'Search in these namespaces by default:',
+'default' => 'default',
+'files' => 'Files',
+
+# User rights
+'userrights-lookup-user' => 'Manage user groups',
+'userrights-user-editname' => 'Enter a username:',
+'editusergroup' => 'Edit User Groups',
+
+'userrights-editusergroup' => 'Edit user groups',
+'saveusergroups' => 'Save User Groups',
+'userrights-groupsmember' => 'Member of:',
+'userrights-groupsavailable' => 'Available groups:',
+'userrights-groupshelp' => 'Select groups you want the user to be removed from or added to.
+Unselected groups will not be changed. You can deselect a group with CTRL + Left Click',
+
+# Groups
+'group' => 'Group:',
+'group-bot' => 'Bots',
+'group-sysop' => 'Sysops',
+'group-bureaucrat' => 'Bureaucrats',
+'group-all' => '(all)',
+
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Sysop',
+'group-bureaucrat-member' => 'Bureaucrat',
+
+'grouppage-bot' => '{{ns:project}}:Bots',
+'grouppage-sysop' => '{{ns:project}}:Administrators',
+'grouppage-bureaucrat' => '{{ns:project}}:Bureaucrats',
+
+# Recent changes
+#
+'changes' => 'changes',
+'recentchanges' => 'Recent changes',
+'recentchanges-url' => 'Special:Recentchanges',
+'recentchangestext' => 'Track the most recent changes to the wiki on this page.',
+'recentchanges-feed-description' => 'Track the most recent changes to the wiki in this feed.',
+'rcnote' => "Below are the last <strong>$1</strong> changes in the last <strong>$2</strong> days, as of $3.",
+'rcnotefrom' => "Below are the changes since <b>$2</b> (up to <b>$1</b> shown).",
+'rclistfrom' => "Show new changes starting from $1",
+'rcshowhideminor' => '$1 minor edits',
+'rcshowhidebots' => '$1 bots',
+'rcshowhideliu' => '$1 logged-in users',
+'rcshowhideanons' => '$1 anonymous users',
+'rcshowhidepatr' => '$1 patrolled edits',
+'rcshowhidemine' => '$1 my edits',
+'rclinks' => "Show last $1 changes in last $2 days<br />$3",
+'diff' => 'diff',
+'hist' => 'hist',
+'hide' => 'Hide',
+'show' => 'Show',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_RCview' => '[$1]',
+'number_of_watching_users_pageview' => '[$1 watching user/s]',
+'rc_categories' => 'Limit to categories (separate with "|")',
+'rc_categories_any' => 'Any',
+'rc-change-size' => '$1',
+
+# Upload
+#
+'upload' => 'Upload file',
+'uploadbtn' => 'Upload file',
+'reupload' => 'Re-upload',
+'reuploaddesc' => 'Return to the upload form.',
+'uploadnologin' => 'Not logged in',
+'uploadnologintext' => "You must be [[Special:Userlogin|logged in]]
+to upload files.",
+'upload_directory_read_only' => 'The upload directory ($1) is not writable by the webserver.',
+'uploaderror' => 'Upload error',
+'uploadtext' => "Use the form below to upload files, to view or search previously uploaded images go to the [[Special:Imagelist|list of uploaded files]], uploads and deletions are also logged in the [[Special:Log/upload|upload log]].
+
+To include the image in a page, use a link in the form
+'''<nowiki>[[{{ns:image}}:File.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:File.png|alt text]]</nowiki>''' or
+'''<nowiki>[[{{ns:media}}:File.ogg]]</nowiki>''' for directly linking to the file.",
+'uploadlog' => 'upload log',
+'uploadlogpage' => 'Upload log',
+'uploadlogpagetext' => 'Below is a list of the most recent file uploads.',
+'filename' => 'Filename',
+'filedesc' => 'Summary',
+'fileuploadsummary' => 'Summary:',
+'filestatus' => 'Copyright status',
+'filesource' => 'Source',
+'copyrightpage' => "Project:Copyrights",
+'copyrightpagename' => "{{SITENAME}} copyright",
+'uploadedfiles' => 'Uploaded files',
+'ignorewarning' => 'Ignore warning and save file anyway.',
+'ignorewarnings' => 'Ignore any warnings',
+'minlength' => 'File names must be at least three letters.',
+'illegalfilename' => 'The filename "$1" contains characters that are not allowed in page titles. Please rename the file and try uploading it again.',
+'badfilename' => 'File name has been changed to "$1".',
+'badfiletype' => "\".$1\" is not a recommended image file format.",
+'large-file' => 'It is recommended that files are no larger than $1; this file is $2.',
+'largefileserver' => 'This file is bigger than the server is configured to allow.',
+'emptyfile' => 'The file you uploaded seems to be empty. This might be due to a typo in the file name. Please check whether you really want to upload this file.',
+'fileexists' => 'A file with this name exists already, please check $1 if you are not sure if you want to change it.',
+'fileexists-forbidden' => 'A file with this name exists already; please go back and upload this file under a new name. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'A file with this name exists already in the shared file repository; please go back and upload this file under a new name. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Successful upload',
+'fileuploaded' => "File $1 uploaded successfully.
+Please follow this link: $2 to the description page and fill
+in information about the file, such as where it came from, when it was
+created and by whom, and anything else you may know about it. If this is an image, you can insert it like this: <tt><nowiki>[[Image:$1|thumb|Description]]</nowiki></tt>",
+'uploadwarning' => 'Upload warning',
+'savefile' => 'Save file',
+'uploadedimage' => "uploaded \"[[$1]]\"",
+'uploaddisabled' => 'Uploads disabled',
+'uploaddisabledtext' => 'File uploads are disabled on this wiki.',
+'uploadscripted' => 'This file contains HTML or script code that may be erroneously be interpreted by a web browser.',
+'uploadcorrupt' => 'The file is corrupt or has an incorrect extension. Please check the file and upload again.',
+'uploadvirus' => 'The file contains a virus! Details: $1',
+'sourcefilename' => 'Source filename',
+'destfilename' => 'Destination filename',
+'watchthisupload' => 'Watch this page',
+'filewasdeleted' => 'A file of this name has been previously uploaded and subsequently deleted. You should check the $1 before proceeding to upload it again.',
+
+'upload-proto-error' => 'Incorrect protocol',
+'upload-proto-error-text' => 'Remote upload requires URLs beginning with <code>http://</code> or <code>ftp://</code>.',
+'upload-file-error' => 'Internal error',
+'upload-file-error-text' => 'An internal error occurred when attempting to create a temporary file on the server. Please contact a system administrator.',
+'upload-misc-error' => 'Unknown upload error',
+'upload-misc-error-text' => 'An unknown error occurred during the upload. Please verify that the URL is valid and accessible and try again. If the problem persists, contact a system administrator.',
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => "Couldn't reach URL",
+'upload-curl-error6-text' => 'The URL provided could not be reached. Please double-check that the URL is correct and the site is up.',
+'upload-curl-error28' => 'Upload timeout',
+'upload-curl-error28-text' => 'The site took too long to respond. Please check the site is up, wait a short while and try again. You may want to try at a less busy time.',
+
+'license' => 'Licensing',
+'nolicense' => 'None selected',
+'licenses' => '-', # Don't duplicate this in translations
+'upload_source_url' => ' (a valid, publicly accessible URL)',
+'upload_source_file' => ' (a file on your computer)',
+
+# Image list
+#
+'imagelist' => 'File list',
+'imagelist-summary' => '',
+'imagelisttext' => "Below is a list of '''$1''' {{plural:$1|file|files}} sorted $2.",
+'imagelistforuser' => "This shows only images uploaded by $1.",
+'getimagelist' => 'fetching file list',
+'ilsubmit' => 'Search',
+'showlast' => 'Show last $1 files sorted $2.',
+'byname' => 'by name',
+'bydate' => 'by date',
+'bysize' => 'by size',
+'imgdelete' => 'del',
+'imgdesc' => 'desc',
+'imgfile' => 'file',
+'imglegend' => 'Legend: (desc) = show/edit file description.',
+'imghistory' => 'File history',
+'revertimg' => 'rev',
+'deleteimg' => 'del',
+'deleteimgcompletely' => 'Delete all revisions of this file',
+'imghistlegend' => 'Legend: (cur) = this is the current file, (del) = delete
+this old version, (rev) = revert to this old version.
+<br /><i>Click on date to see the file uploaded on that date</i>.',
+'imagelinks' => 'Links',
+'linkstoimage' => 'The following pages link to this file:',
+'nolinkstoimage' => 'There are no pages that link to this file.',
+'sharedupload' => 'This file is a shared upload and may be used by other projects.',
+'shareduploadwiki' => 'Please see the $1 for further information.',
+'shareduploadwiki-linktext' => 'file description page',
+'shareddescriptionfollows' => '-',
+'noimage' => 'No file by this name exists, you can $1.',
+'noimage-linktext' => 'upload it',
+'uploadnewversion-linktext' => 'Upload a new version of this file',
+'imagelist_date' => 'Date',
+'imagelist_name' => 'Name',
+'imagelist_user' => 'User',
+'imagelist_size' => 'Size (bytes)',
+'imagelist_description' => 'Description',
+'imagelist_search_for' => 'Search for image name:',
+
+# Mime search
+#
+'mimesearch' => 'MIME search',
+'mimesearch-summary' => '',
+'mimetype' => 'MIME type:',
+'download' => 'download',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Unwatched pages',
+'unwatchedpages-summary' => '',
+
+# List redirects
+'listredirects' => 'List redirects',
+'listredirects-summary' => '',
+
+# Unused templates
+'unusedtemplates' => 'Unused templates',
+'unusedtemplates-summary' => '',
+'unusedtemplatestext' => 'This page lists all pages in the template namespace which are not included in another page. Remember to check for other links to the templates before deleting them.',
+'unusedtemplateswlh' => 'other links',
+
+# Random redirect
+'randomredirect' => 'Random redirect',
+
+# Statistics
+#
+'statistics' => 'Statistics',
+'sitestats' => '{{SITENAME}} statistics',
+'userstats' => 'User statistics',
+'sitestatstext' => "There are '''$1''' total pages in the database.
+This includes \"talk\" pages, pages about {{SITENAME}}, minimal \"stub\"
+pages, redirects, and others that probably don't qualify as content pages.
+Excluding those, there are '''$2''' pages that are probably legitimate
+content pages.
+
+'''$8''' files have been uploaded.
+
+There have been a total of '''$3''' page views, and '''$4''' page edits
+since the wiki was setup.
+That comes to '''$5''' average edits per page, and '''$6''' views per edit.
+
+The [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] length is '''$7'''.",
+'userstatstext' => "There are '''$1''' registered users, of which
+'''$2''' (or '''$4%''') are $5.",
+'statistics-mostpopular' => 'Most viewed pages',
+
+'disambiguations' => 'Disambiguation pages',
+'disambiguations-summary' => '',
+'disambiguationspage' => 'Template:disambig',
+'disambiguationstext' => "The following pages link to a <i>disambiguation page</i>. They should link to the appropriate topic instead.<br />A page is treated as disambiguation if it is linked from $1.<br />Links from other namespaces are <i>not</i> listed here.",
+
+'doubleredirects' => 'Double redirects',
+'doubleredirects-summary' => '',
+'doubleredirectstext' => "Each row contains links to the first and second redirect, as well as the first line of the second redirect text, usually giving the \"real\" target page, which the first redirect should point to.",
+
+'brokenredirects' => 'Broken redirects',
+'brokenredirects-summary' => '',
+'brokenredirectstext' => 'The following redirects link to non-existent pages:',
+
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
+'ncategories' => '$1 {{PLURAL:$1|category|categories}}',
+'nlinks' => '$1 {{PLURAL:$1|link|links}}',
+'nmembers' => '$1 {{PLURAL:$1|member|members}}',
+'nrevisions' => '$1 {{PLURAL:$1|revision|revisions}}',
+'nviews' => '$1 {{PLURAL:$1|view|views}}',
+
+'lonelypages' => 'Orphaned pages',
+'lonelypages-summary' => '',
+'lonelypagestext' => 'The following pages are not linked from other pages in this wiki.',
+'uncategorizedpages' => 'Uncategorized pages',
+'uncategorizedpages-summary' => '',
+'uncategorizedcategories' => 'Uncategorized categories',
+'uncategorizedcategories-summary' => '',
+'uncategorizedimages' => 'Uncategorized images',
+'uncategorizedimages-summary' => '',
+'unusedcategories' => 'Unused categories',
+'unusedimages' => 'Unused files',
+'popularpages' => 'Popular pages',
+'popularpages-summary' => '',
+'wantedcategories' => 'Wanted categories',
+'wantedcategories-summary' => '',
+'wantedpages' => 'Wanted pages',
+'wantedpages-summary' => '',
+'mostlinked' => 'Most linked to pages',
+'mostlinked-summary' => '',
+'mostlinkedcategories' => 'Most linked to categories',
+'mostlinkedcategories-summary' => '',
+'mostcategories' => 'Articles with the most categories',
+'mostcategories-summary' => '',
+'mostimages' => 'Most linked to images',
+'mostimages-summary' => '',
+'mostrevisions' => 'Articles with the most revisions',
+'mostrevisions-summary' => '',
+'allpages' => 'All pages',
+'allpages-summary' => '',
+'prefixindex' => 'Prefix index',
+'prefixindex-summary' => '',
+'randompage' => 'Random page',
+'randompage-url'=> 'Special:Random',
+'shortpages' => 'Short pages',
+'shortpages-summary' => '',
+'longpages' => 'Long pages',
+'longpages-summary' => '',
+'deadendpages' => 'Dead-end pages',
+'deadendpages-summary' => '',
+'deadendpagestext' => 'The following pages do not link to other pages in this wiki.',
+'listusers' => 'User list',
+'listusers-summary' => '',
+'specialpages' => 'Special pages',
+'specialpages-summary' => '',
+'spheading' => 'Special pages for all users',
+'restrictedpheading' => 'Restricted special pages',
+'recentchangeslinked' => 'Related changes',
+'rclsub' => "(to pages linked from \"$1\")",
+'newpages' => 'New pages',
+'newpages-summary' => '',
+'newpages-username' => 'Username:',
+'ancientpages' => 'Oldest pages',
+'ancientpages-summary' => '',
+'intl' => 'Interlanguage links',
+'move' => 'Move',
+'movethispage' => 'Move this page',
+'unusedimagestext' => '<p>Please note that other web sites may link to an image with
+a direct URL, and so may still be listed here despite being
+in active use.</p>',
+'unusedcategoriestext' => 'The following category pages exist although no other article or category make use of them.',
+
+# Book sources
+'booksources' => 'Book sources',
+'booksources-summary' => '',
+'booksources-search-legend' => 'Search for book sources',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => 'Go',
+'booksources-text' => 'Below is a list of links to other sites that sell new and used books, and may also have
+further information about books you are looking for:',
+
+'categoriespagetext' => 'The following categories exist in the wiki.',
+'data' => 'Data',
+'userrights' => 'User rights management',
+'userrights-summary' => '',
+'groups' => 'User groups',
+
+'isbn' => 'ISBN',
+'rfcurl' => 'http://www.ietf.org/rfc/rfc$1.txt',
+'pubmedurl' => 'http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=$1',
+'alphaindexline' => "$1 to $2",
+'version' => 'Version',
+'log' => 'Logs',
+'alllogstext' => 'Combined display of upload, deletion, protection, blocking, and sysop logs.
+You can narrow down the view by selecting a log type, the user name, or the affected page.',
+'logempty' => 'No matching items in log.',
+
+
+# Special:Allpages
+'nextpage' => 'Next page ($1)',
+'prevpage' => 'Previous page ($1)',
+'allpagesfrom' => 'Display pages starting at:',
+'allarticles' => 'All articles',
+'allinnamespace' => 'All pages ($1 namespace)',
+'allnotinnamespace' => 'All pages (not in $1 namespace)',
+'allpagesprev' => 'Previous',
+'allpagesnext' => 'Next',
+'allpagessubmit' => 'Go',
+'allpagesprefix' => 'Display pages with prefix:',
+'allpagesbadtitle' => 'The given page title was invalid or had an inter-language or inter-wiki prefix. It may contain one or more characters which cannot be used in titles.',
+
+# Special:Listusers
+'listusersfrom' => 'Display users starting at:',
+
+# Email this user
+#
+'mailnologin' => 'No send address',
+'mailnologintext' => "You must be [[Special:Userlogin|logged in]]
+and have a valid e-mail address in your [[Special:Preferences|preferences]]
+to send e-mail to other users.",
+'emailuser' => 'E-mail this user',
+'emailpage' => 'E-mail user',
+'emailpagetext' => 'If this user has entered a valid e-mail address in
+his or her user preferences, the form below will send a single message.
+The e-mail address you entered in your user preferences will appear
+as the "From" address of the mail, so the recipient will be able
+to reply.',
+'usermailererror' => 'Mail object returned error:',
+'defemailsubject' => "{{SITENAME}} e-mail",
+'noemailtitle' => 'No e-mail address',
+'noemailtext' => 'This user has not specified a valid e-mail address,
+or has chosen not to receive e-mail from other users.',
+'emailfrom' => 'From',
+'emailto' => 'To',
+'emailsubject' => 'Subject',
+'emailmessage' => 'Message',
+'emailsend' => 'Send',
+'emailccme' => 'E-mail me a copy of my message.',
+'emailccsubject'=> 'Copy of your message to $1: $2',
+'emailsent' => 'E-mail sent',
+'emailsenttext' => 'Your e-mail message has been sent.',
+
+# Watchlist
+'watchlist' => 'My watchlist',
+'watchlistfor' => "(for '''$1''')",
+'nowatchlist' => 'You have no items on your watchlist.',
+'watchlistanontext' => 'Please $1 to view or edit items on your watchlist.',
+'watchlistcount' => "'''You have {{PLURAL:$1|$1 item|$1 items}} on your watchlist, including talk pages.'''",
+'clearwatchlist' => 'Clear watchlist',
+'watchlistcleartext' => 'Are you sure you wish to remove them?',
+'watchlistclearbutton' => 'Clear watchlist',
+'watchlistcleardone' => 'Your watchlist has been cleared. {{PLURAL:$1|$1 item was|$1 items were}} removed.',
+'watchnologin' => 'Not logged in',
+'watchnologintext' => 'You must be [[Special:Userlogin|logged in]] to modify your watchlist.',
+'addedwatch' => 'Added to watchlist',
+'addedwatchtext' => "The page \"[[:$1]]\" has been added to your [[Special:Watchlist|watchlist]].
+Future changes to this page and its associated Talk page will be listed there,
+and the page will appear '''bolded''' in the [[Special:Recentchanges|list of recent changes]] to
+make it easier to pick out.
+
+If you want to remove the page from your watchlist later, click \"Unwatch\" in the sidebar.",
+'removedwatch' => 'Removed from watchlist',
+'removedwatchtext' => "The page \"[[:$1]]\" has been removed from your watchlist.",
+'watch' => 'Watch',
+'watchthispage' => 'Watch this page',
+'unwatch' => 'Unwatch',
+'unwatchthispage' => 'Stop watching',
+'notanarticle' => 'Not a content page',
+'watchnochange' => 'None of your watched items was edited in the time period displayed.',
+'watchdetails' => '* {{PLURAL:$1|$1 page|$1 pages}} watched not counting talk pages
+* [[Special:Watchlist/edit|Show and edit complete watchlist]]
+* [[Special:Watchlist/clear|Remove all pages]]',
+'wlheader-enotif' => "* E-mail notification is enabled.",
+'wlheader-showupdated' => "* Pages which have been changed since you last visited them are shown in '''bold'''",
+'watchmethod-recent'=> 'checking recent edits for watched pages',
+'watchmethod-list' => 'checking watched pages for recent edits',
+'removechecked' => 'Remove checked items from watchlist',
+'watchlistcontains' => "Your watchlist contains $1 pages.",
+'watcheditlist' => 'Here\'s an alphabetical list of your
+watched content pages. Check the boxes of pages you want to remove from your watchlist and click the \'remove checked\' button
+at the bottom of the screen (deleting a content page also deletes the accompanying talk page and vice versa).',
+'removingchecked' => 'Removing requested items from watchlist...',
+'couldntremove' => "Couldn't remove item '$1'...",
+'iteminvalidname' => "Problem with item '$1', invalid name...",
+'wlnote' => 'Below are the last $1 changes in the last <b>$2</b> hours.',
+'wlshowlast' => 'Show last $1 hours $2 days $3',
+'wlsaved' => 'This is a saved version of your watchlist.',
+'watchlist-show-bots' => 'Show bot edits',
+'watchlist-hide-bots' => 'Hide bot edits',
+'watchlist-show-own' => 'Show my edits',
+'watchlist-hide-own' => 'Hide my edits',
+'watchlist-show-minor' => 'Show minor edits',
+'watchlist-hide-minor' => 'Hide minor edits',
+'wldone' => 'Done.',
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => 'Watching...',
+'unwatching' => 'Unwatching...',
+
+'enotif_mailer' => '{{SITENAME}} Notification Mailer',
+'enotif_reset' => 'Mark all pages visited',
+'enotif_newpagetext'=> 'This is a new page.',
+'changed' => 'changed',
+'created' => 'created',
+'enotif_subject' => '{{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED by $PAGEEDITOR',
+'enotif_lastvisited' => 'See $1 for all changes since your last visit.',
+'enotif_body' => 'Dear $WATCHINGUSERNAME,
+
+the {{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED on $PAGEEDITDATE by $PAGEEDITOR, see $PAGETITLE_URL for the current version.
+
+$NEWPAGE
+
+Editor\'s summary: $PAGESUMMARY $PAGEMINOREDIT
+
+Contact the editor:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+There will be no other notifications in case of further changes unless you visit this page. You could also reset the notification flags for all your watched pages on your watchlist.
+
+ Your friendly {{SITENAME}} notification system
+
+--
+To change your watchlist settings, visit
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Feedback and further assistance:
+{{fullurl:{{ns:help}}:Contents}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Delete page',
+'confirm' => 'Confirm',
+'excontent' => "content was: '$1'",
+'excontentauthor' => "content was: '$1' (and the only contributor was '[[Special:Contributions/$2|$2]]')",
+'exbeforeblank' => "content before blanking was: '$1'",
+'exblank' => 'page was empty',
+'confirmdelete' => 'Confirm delete',
+'deletesub' => "(Deleting \"$1\")",
+'historywarning' => 'Warning: The page you are about to delete has a history:',
+'confirmdeletetext' => "You are about to permanently delete a page
+or image along with all of its history from the database.
+Please confirm that you intend to do this, that you understand the
+consequences, and that you are doing this in accordance with
+[[{{ns:project}}:Policy]].",
+'actioncomplete' => 'Action complete',
+'deletedtext' => "\"$1\" has been deleted.
+See $2 for a record of recent deletions.",
+'deletedarticle' => "deleted \"[[$1]]\"",
+'dellogpage' => 'Deletion log',
+'dellogpagetext' => 'Below is a list of the most recent deletions.',
+'deletionlog' => 'deletion log',
+'reverted' => 'Reverted to earlier revision',
+'deletecomment' => 'Reason for deletion',
+'imagereverted' => 'Revert to earlier version was successful.',
+'rollback' => 'Roll back edits',
+'rollback_short' => 'Rollback',
+'rollbacklink' => 'rollback',
+'rollbackfailed' => 'Rollback failed',
+'cantrollback' => 'Cannot revert edit; last contributor is only author of this page.',
+'alreadyrolled' => "Cannot rollback last edit of [[:$1]]
+by [[User:$2|$2]] ([[User talk:$2|Talk]]); someone else has edited or rolled back the page already.
+
+Last edit was by [[User:$3|$3]] ([[User talk:$3|Talk]]).",
+# only shown if there is an edit comment
+'editcomment' => "The edit comment was: \"<i>$1</i>\".",
+'revertpage' => "Reverted edits by [[Special:Contributions/$2|$2]] ([[User_talk:$2|Talk]]); changed back to last version by [[User:$1|$1]]",
+'sessionfailure' => 'There seems to be a problem with your login session;
+this action has been canceled as a precaution against session hijacking.
+Please hit "back" and reload the page you came from, then try again.',
+'protectlogpage' => 'Protection log',
+'protectlogtext' => "Below is a list of page locks and unlocks.",
+'protectedarticle' => 'protected "[[$1]]"',
+'unprotectedarticle' => 'unprotected "[[$1]]"',
+'protectsub' => '(Protecting "$1")',
+'confirmprotecttext' => 'Do you really want to protect this page?',
+'confirmprotect' => 'Confirm protection',
+'protectmoveonly' => 'Protect from moves only',
+'protectcomment' => 'Reason for protecting',
+'unprotectsub' =>"(Unprotecting \"$1\")",
+'confirmunprotecttext' => 'Do you really want to unprotect this page?',
+'confirmunprotect' => 'Confirm unprotection',
+'unprotectcomment' => 'Reason for unprotecting',
+'protect-unchain' => 'Unlock move permissions',
+'protect-text' => 'You may view and change the protection level here for the page <strong>$1</strong>.',
+'protect-viewtext' => 'Your account does not have permission to change
+page protection levels. Here are the current settings for the page <strong>$1</strong>:',
+'protect-default' => '(default)',
+'protect-level-autoconfirmed' => 'Block unregistered users',
+'protect-level-sysop' => 'Sysops only',
+
+# restrictions (nouns)
+'restriction-edit' => 'Edit',
+'restriction-move' => 'Move',
+
+
+# Undelete
+'undelete' => 'View deleted pages',
+'undeletepage' => 'View and restore deleted pages',
+'viewdeletedpage' => 'View deleted pages',
+'undeletepagetext' => 'The following pages have been deleted but are still in the archive and
+can be restored. The archive may be periodically cleaned out.',
+'undeleteextrahelp' => "To restore the entire page, leave all checkboxes deselected and
+click '''''Restore'''''. To perform a selective restoration, check the boxes corresponding to the
+revisions to be restored, and click '''''Restore'''''. Clicking '''''Reset''''' will clear the
+comment field and all checkboxes.",
+'undeletearticle' => 'Restore deleted page',
+'undeleterevisions' => "$1 revisions archived",
+'undeletehistory' => 'If you restore the page, all revisions will be restored to the history.
+If a new page with the same name has been created since the deletion, the restored
+revisions will appear in the prior history, and the current revision of the live page
+will not be automatically replaced.',
+'undeletehistorynoadmin' => 'This article has been deleted. The reason for deletion is
+shown in the summary below, along with details of the users who had edited this page
+before deletion. The actual text of these deleted revisions is only available to administrators.',
+'undeleterevision' => "Deleted revision as of $1",
+'undeleterevision-missing' => "Invalid or missing revision. You may have a bad link, or the
+revision may have been restored or removed from the archive.",
+'undeletebtn' => 'Restore',
+'undeletereset' => 'Reset',
+'undeletecomment' => 'Comment:',
+'undeletedarticle' => "restored \"[[$1]]\"",
+'undeletedrevisions' => "$1 revisions restored",
+'undeletedrevisions-files' => "$1 revisions and $2 file(s) restored",
+'undeletedfiles' => "$1 file(s) restored",
+'cannotundelete' => 'Undelete failed; someone else may have undeleted the page first.',
+'undeletedpage' => "<big>'''$1 has been restored'''</big>
+
+Consult the [[Special:Log/delete|deletion log]] for a record of recent deletions and restorations.",
+
+# Namespace form on various pages
+'namespace' => 'Namespace:',
+'invert' => 'Invert selection',
+
+# Contributions
+#
+'contributions' => 'User contributions',
+'mycontris' => 'My contributions',
+'contribsub' => "For $1",
+'nocontribs' => 'No changes were found matching these criteria.',
+'ucnote' => "Below are this user's last <b>$1</b> changes in the last <b>$2</b> days.",
+'uclinks' => "View the last $1 changes; view the last $2 days.",
+'uctop' => ' (top)' ,
+'newbies' => 'newbies',
+
+'sp-contributions-newest' => 'Newest',
+'sp-contributions-oldest' => 'Oldest',
+'sp-contributions-newer' => 'Newer $1',
+'sp-contributions-older' => 'Older $1',
+'sp-contributions-newbies-sub' => 'For newbies',
+'sp-contributions-blocklog' => 'Block log',
+
+'sp-newimages-showfrom' => 'Show new images starting from $1',
+
+# What links here
+#
+'whatlinkshere' => 'What links here',
+'whatlinkshere-summary' => '',
+'whatlinkshere-barrow' => '&lt;',
+'notargettitle' => 'No target',
+'notargettext' => 'You have not specified a target page or user
+to perform this function on.',
+'linklistsub' => '(List of links)',
+'linkshere' => "The following pages link to '''[[:$1]]''':",
+'nolinkshere' => "No pages link to '''[[:$1]]'''.",
+'isredirect' => 'redirect page',
+'istemplate' => 'inclusion',
+
+# Block/unblock IP
+#
+'blockip' => 'Block user',
+'blockiptext' => "Use the form below to block write access
+from a specific IP address or username.
+This should be done only only to prevent vandalism, and in
+accordance with [[{{ns:project}}:Policy|policy]].
+Fill in a specific reason below (for example, citing particular
+pages that were vandalized).",
+'ipaddress' => 'IP Address',
+'ipadressorusername' => 'IP Address or username',
+'ipbexpiry' => 'Expiry',
+'ipbreason' => 'Reason',
+'ipbanononly' => 'Block anonymous users only',
+'ipbcreateaccount' => 'Prevent account creation',
+'ipbenableautoblock' => 'Automatically block the last IP address used by this user, and any subsequent addresses they try to edit from',
+'ipbsubmit' => 'Block this user',
+'ipbother' => 'Other time',
+'ipboptions' => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
+'ipbotheroption' => 'other',
+'badipaddress' => 'Invalid IP address',
+'blockipsuccesssub' => 'Block succeeded',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|$1]] has been blocked.
+<br />See [[{{ns:Special}}:Ipblocklist|IP block list]] to review blocks.',
+'unblockip' => 'Unblock user',
+'unblockiptext' => 'Use the form below to restore write access
+to a previously blocked IP address or username.',
+'ipusubmit' => 'Unblock this address',
+'unblocked' => '[[User:$1|$1]] has been unblocked',
+'ipblocklist' => 'List of blocked IP addresses and usernames',
+'ipblocklist-summary' => '',
+'blocklistline' => "$1, $2 blocked $3 ($4)",
+'infiniteblock' => 'infinite',
+'expiringblock' => 'expires $1',
+'anononlyblock' => 'anon. only',
+'noautoblockblock' => 'autoblock disabled',
+'createaccountblock' => 'account creation blocked',
+'ipblocklistempty' => 'The blocklist is empty.',
+'blocklink' => 'block',
+'unblocklink' => 'unblock',
+'contribslink' => 'contribs',
+'autoblocker' => 'Autoblocked because your IP address has been recently used by "[[User:$1|$1]]". The reason given for $1\'s block is: "\'\'\'$2\'\'\'"',
+'blocklogpage' => 'Block log',
+'blocklogentry' => 'blocked "[[$1]]" with an expiry time of $2',
+'blocklogtext' => 'This is a log of user blocking and unblocking actions. Automatically
+blocked IP addresses are not listed. See the [[Special:Ipblocklist|IP block list]] for
+the list of currently operational bans and blocks.',
+'unblocklogentry' => 'unblocked $1',
+'range_block_disabled' => 'The sysop ability to create range blocks is disabled.',
+'ipb_expiry_invalid' => 'Expiry time invalid.',
+'ipb_already_blocked' => '"$1" is already blocked',
+'ip_range_invalid' => 'Invalid IP range.',
+'proxyblocker' => 'Proxy blocker',
+'ipb_cant_unblock' => 'Error: Block ID $1 not found. It may have been unblocked already.',
+'proxyblockreason' => 'Your IP address has been blocked because it is an open proxy. Please contact your Internet service provider or tech support and inform them of this serious security problem.',
+'proxyblocksuccess' => 'Done.',
+'sorbs' => 'DNSBL',
+'sorbsreason' => 'Your IP address is listed as an open proxy in the DNSBL used by this site.',
+'sorbs_create_account_reason' => 'Your IP address is listed as an open proxy in the DNSBL used by this site. You cannot create an account',
+
+
+# Developer tools
+#
+'lockdb' => 'Lock database',
+'unlockdb' => 'Unlock database',
+'lockdbtext' => 'Locking the database will suspend the ability of all
+users to edit pages, change their preferences, edit their watchlists, and
+other things requiring changes in the database.
+Please confirm that this is what you intend to do, and that you will
+unlock the database when your maintenance is done.',
+'unlockdbtext' => 'Unlocking the database will restore the ability of all
+users to edit pages, change their preferences, edit their watchlists, and
+other things requiring changes in the database.
+Please confirm that this is what you intend to do.',
+'lockconfirm' => 'Yes, I really want to lock the database.',
+'unlockconfirm' => 'Yes, I really want to unlock the database.',
+'lockbtn' => 'Lock database',
+'unlockbtn' => 'Unlock database',
+'locknoconfirm' => 'You did not check the confirmation box.',
+'lockdbsuccesssub' => 'Database lock succeeded',
+'unlockdbsuccesssub' => 'Database lock removed',
+'lockdbsuccesstext' => 'The database has been locked.
+<br />Remember to [[Special:Unlockdb|remove the lock]] after your maintenance is complete.',
+'unlockdbsuccesstext' => 'The database has been unlocked.',
+'lockfilenotwritable' => 'The database lock file is not writable. To lock or unlock the database, this needs to be writable by the web server.',
+'databasenotlocked' => 'The database is not locked.',
+
+# Make sysop
+'makesysoptitle' => 'Make a user into a sysop',
+'makesysoptext' => 'This form is used by bureaucrats to turn ordinary users into administrators.
+Type the name of the user in the box and press the button to make the user an administrator',
+'makesysopname' => 'Name of the user:',
+'makesysopsubmit' => 'Make this user into a sysop',
+'makesysopok' => "<b>User \"$1\" is now a sysop</b>",
+'makesysopfail' => "<b>User \"$1\" could not be made into a sysop. (Did you enter the name correctly?)</b>",
+'setbureaucratflag' => 'Set bureaucrat flag',
+'rightslog' => 'User rights log',
+'rightslogtext' => 'This is a log of changes to user rights.',
+'rightslogentry' => 'changed group membership for $1 from $2 to $3',
+'rights' => 'Rights:',
+'set_user_rights' => 'Set user rights',
+'user_rights_set' => "<b>User rights for \"$1\" updated</b>",
+'set_rights_fail' => "<b>User rights for \"$1\" could not be set. (Did you enter the name correctly?)</b>",
+'makesysop' => 'Make a user into a sysop',
+'already_sysop' => 'This user is already an administrator',
+'already_bureaucrat' => 'This user is already a bureaucrat',
+'rightsnone' => '(none)',
+
+# Move page
+#
+'movepage' => 'Move page',
+'movepagetext' => 'Using the form below will rename a page, moving all
+of its history to the new name.
+The old title will become a redirect page to the new title.
+Links to the old page title will not be changed; be sure to
+check for double or broken redirects.
+You are responsible for making sure that links continue to
+point where they are supposed to go.
+
+Note that the page will \'\'\'not\'\'\' be moved if there is already
+a page at the new title, unless it is empty or a redirect and has no
+past edit history. This means that you can rename a page back to where
+it was just renamed from if you make a mistake, and you cannot overwrite
+an existing page.
+
+<b>WARNING!</b>
+This can be a drastic and unexpected change for a popular page;
+please be sure you understand the consequences of this before
+proceeding.',
+'movepagetalktext' => 'The associated talk page will be automatically moved along with it \'\'\'unless:\'\'\'
+*A non-empty talk page already exists under the new name, or
+*You uncheck the box below.
+
+In those cases, you will have to move or merge the page manually if desired.',
+'movearticle' => 'Move page',
+'movenologin' => 'Not logged in',
+'movenologintext' => "You must be a registered user and [[Special:Userlogin|logged in]]
+to move a page.",
+'newtitle' => 'To new title',
+'move-watch' => 'Watch this page',
+'movepagebtn' => 'Move page',
+'pagemovedsub' => 'Move succeeded',
+'pagemovedtext' => "Page \"[[$1]]\" moved to \"[[$2]]\".",
+'articleexists' => 'A page of that name already exists, or the
+name you have chosen is not valid.
+Please choose another name.',
+'talkexists' => "'''The page itself was moved successfully, but the talk page could not be moved because one already exists at the new title. Please merge them manually.'''",
+'movedto' => 'moved to',
+'movetalk' => 'Move associated talk page',
+'talkpagemoved' => 'The corresponding talk page was also moved.',
+'talkpagenotmoved' => 'The corresponding talk page was <strong>not</strong> moved.',
+'1movedto2' => '[[$1]] moved to [[$2]]',
+'1movedto2_redir' => '[[$1]] moved to [[$2]] over redirect',
+'movelogpage' => 'Move log',
+'movelogpagetext' => 'Below is a list of page moved.',
+'movereason' => 'Reason',
+'revertmove' => 'revert',
+'delete_and_move' => 'Delete and move',
+'delete_and_move_text' =>
+'==Deletion required==
+
+The destination article "[[$1]]" already exists. Do you want to delete it to make way for the move?',
+'delete_and_move_confirm' => 'Yes, delete the page',
+'delete_and_move_reason' => 'Deleted to make way for move',
+'selfmove' => "Source and destination titles are the same; can't move a page over itself.",
+'immobile_namespace' => "Source or destination title is of a special type; cannot move pages from and into that namespace.",
+
+# Export
+
+'export' => 'Export pages',
+'exporttext' => 'You can export the text and editing history of a particular page or
+set of pages wrapped in some XML. This can be imported into another wiki using MediaWiki
+via the Special:Import page.
+
+To export pages, enter the titles in the text box below, one title per line, and
+select whether you want the current version as well as all old versions, with the page
+history lines, or just the current version with the info about the last edit.
+
+In the latter case you can also use a link, e.g. [[{{ns:Special}}:Export/{{int:mainpage}}]] for the page {{int:mainpage}}.',
+'exportcuronly' => 'Include only the current revision, not the full history',
+'exportnohistory' => "----
+'''Note:''' Exporting the full history of pages through this form has been disabled due to performance reasons.",
+'export-submit' => 'Export',
+
+# Namespace 8 related
+
+'allmessages' => 'System messages',
+'allmessagesname' => 'Name',
+'allmessagesdefault' => 'Default text',
+'allmessagescurrent' => 'Current text',
+'allmessagestext' => 'This is a list of system messages available in the MediaWiki namespace.',
+'allmessagesnotsupportedUI' => 'Your current interface language <b>$1</b> is not supported by Special:Allmessages at this site.',
+'allmessagesnotsupportedDB' => '\'\'\'Special:Allmessages\'\'\' cannot be used because \'\'\'$wgUseDatabaseMessages\'\'\' is switched off.',
+'allmessagesfilter' => 'Message name filter:',
+'allmessagesmodified' => 'Show only modified',
+
+
+# Thumbnails
+
+'thumbnail-more' => 'Enlarge',
+'missingimage' => '<b>Missing image</b><br /><i>$1</i>',
+'filemissing' => 'File missing',
+'thumbnail_error' => 'Error creating thumbnail: $1',
+
+# Special:Import
+'import' => 'Import pages',
+'importinterwiki' => 'Transwiki import',
+'import-interwiki-text' => 'Select a wiki and page title to import.
+Revision dates and editors\' names will be preserved.
+All transwiki import actions are logged at the [[Special:Log/import|import log]].',
+'import-interwiki-history' => 'Copy all history versions for this page',
+'import-interwiki-submit' => 'Import',
+'import-interwiki-namespace' => 'Transfer pages into namespace:',
+'importtext' => 'Please export the file from the source wiki using the Special:Export utility, save it to your disk and upload it here.',
+'importstart' => "Importing pages...",
+'import-revision-count' => '$1 {{PLURAL:$1|revision|revisions}}',
+'importnopages' => "No pages to import.",
+'importfailed' => "Import failed: $1",
+'importunknownsource' => "Unknown import source type",
+'importcantopen' => "Couldn't open import file",
+'importbadinterwiki' => "Bad interwiki link",
+'importnotext' => 'Empty or no text',
+'importsuccess' => 'Import succeeded!',
+'importhistoryconflict' => 'Conflicting history revision exists (may have imported this page before)',
+'importnosources' => 'No transwiki import sources have been defined and direct history uploads are disabled.',
+'importnofile' => 'No import file was uploaded.',
+'importuploaderror' => 'Upload of import file failed; perhaps the file is bigger than the allowed upload size.',
+
+# import log
+'importlogpage' => 'Import log',
+'importlogpagetext' => 'Administrative imports of pages with edit history from other wikis.',
+'import-logentry-upload' => 'imported [[$1]] by file upload',
+'import-logentry-upload-detail' => '$1 revision(s)',
+'import-logentry-interwiki' => 'transwikied $1',
+'import-logentry-interwiki-detail' => '$1 revision(s) from $2',
+
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Search {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Mark this as a minor edit [alt-i]',
+'tooltip-save' => 'Save your changes [alt-s]',
+'tooltip-preview' => 'Preview your changes, please use this before saving! [alt-p]',
+'tooltip-diff' => 'Show which changes you made to the text. [alt-v]',
+'tooltip-compareselectedversions' => 'See the differences between the two selected versions of this page. [alt-v]',
+'tooltip-watch' => 'Add this page to your watchlist [alt-w]',
+
+# stylesheets
+'common.css' => '/** CSS placed here will be applied to all skins */',
+'monobook.css' => '/* CSS placed here will affect users of the Monobook skin */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF metadata disabled for this server.',
+'nocreativecommons' => 'Creative Commons RDF metadata disabled for this server.',
+'notacceptable' => 'The wiki server can\'t provide data in a format your client can read.',
+
+# Attribution
+
+'anonymous' => 'Anonymous user(s) of {{SITENAME}}',
+'siteuser' => '{{SITENAME}} user $1',
+'lastmodifiedatby' => 'This page was last modified $2, $1 by $3.', // $1 date, $2 time. $3 user
+'and' => 'and',
+'othercontribs' => 'Based on work by $1.',
+'others' => 'others',
+'siteusers' => '{{SITENAME}} user(s) $1',
+'creditspage' => 'Page credits',
+'nocredits' => 'There is no credits info available for this page.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Spam protection filter',
+'spamprotectiontext' => 'The page you wanted to save was blocked by the spam filter. This is probably caused by a link to an external site.',
+'spamprotectionmatch' => 'The following text is what triggered our spam filter: $1',
+'subcategorycount' => "There {{PLURAL:$1|is one subcategory|are $1 subcategories}} to this category.",
+'categoryarticlecount' => "There {{PLURAL:$1|is one article|are $1 articles}} in this category.",
+'category-media-count' => "There {{PLURAL:$1|is one file|are $1 files}} in this category.",
+'listingcontinuesabbrev' => " cont.",
+'spambot_username' => 'MediaWiki spam cleanup',
+'spam_reverting' => 'Reverting to last version not containing links to $1',
+'spam_blanking' => 'All revisions contained links to $1, blanking',
+
+# Info page
+'infosubtitle' => 'Information for page',
+'numedits' => 'Number of edits (article): $1',
+'numtalkedits' => 'Number of edits (discussion page): $1',
+'numwatchers' => 'Number of watchers: $1',
+'numauthors' => 'Number of distinct authors (article): $1',
+'numtalkauthors' => 'Number of distinct authors (discussion page): $1',
+
+# Math options
+'mw_math_png' => 'Always render PNG',
+'mw_math_simple' => 'HTML if very simple or else PNG',
+'mw_math_html' => 'HTML if possible or else PNG',
+'mw_math_source' => 'Leave it as TeX (for text browsers)',
+'mw_math_modern' => 'Recommended for modern browsers',
+'mw_math_mathml' => 'MathML if possible (experimental)',
+
+# Patrolling
+'markaspatrolleddiff' => "Mark as patrolled",
+'markaspatrolledlink' => "[$1]",
+'markaspatrolledtext' => "Mark this article as patrolled",
+'markedaspatrolled' => "Marked as patrolled",
+'markedaspatrolledtext' => "The selected revision has been marked as patrolled.",
+'rcpatroldisabled' => "Recent Changes Patrol disabled",
+'rcpatroldisabledtext' => "The Recent Changes Patrol feature is currently disabled.",
+'markedaspatrollederror' => "Cannot mark as patrolled",
+'markedaspatrollederrortext' => "You need to specify a revision to mark as patrolled.",
+'markedaspatrollederror-noautopatrol' => 'You are not allowed to mark your own changes as patrolled.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'My user page\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'The user page for the ip you\\\'re editing as\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'My talk page\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussion about edits from this ip address\');
+ta[\'pt-preferences\'] = new Array(\'\',\'My preferences\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'The list of pages you\\\'re monitoring for changes.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'List of my contributions\');
+ta[\'pt-login\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Log out\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Discussion about the content page\');
+ta[\'ca-edit\'] = new Array(\'e\',\'You can edit this page. Please use the preview button before saving.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Add a comment to this discussion.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'This page is protected. You can view its source.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Past versions of this page.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Protect this page\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Delete this page\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Restore the edits done to this page before it was deleted\');
+ta[\'ca-move\'] = new Array(\'m\',\'Move this page\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Add this page to your watchlist\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Remove this page from your watchlist\');
+ta[\'search\'] = new Array(\'f\',\'Search this wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Main Page\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Visit the Main Page\');
+ta[\'n-portal\'] = new Array(\'\',\'About the project, what you can do, where to find things\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Find background information on current events\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'The list of recent changes in the wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Load a random page\');
+ta[\'n-help\'] = new Array(\'\',\'The place to find out.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Support us\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'List of all wiki pages that link here\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Recent changes in pages linked from this page\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS feed for this page\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom feed for this page\');
+ta[\'t-contributions\'] = new Array(\'\',\'View the list of contributions of this user\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Send a mail to this user\');
+ta[\'t-upload\'] = new Array(\'u\',\'Upload images or media files\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'List of all special pages\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'View the content page\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'View the user page\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'View the media page\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'This is a special page, you can\\\'t edit the page itself.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'View the project page\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'View the image page\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'View the system message\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'View the template\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'View the help page\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'View the category page\');',
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Any JavaScript here will be loaded for all users on every page load. */',
+
+# image deletion
+'deletedrevision' => 'Deleted old revision $1.',
+
+# browsing diffs
+'previousdiff' => '← Previous diff',
+'nextdiff' => 'Next diff →',
+
+'imagemaxsize' => 'Limit images on image description pages to:',
+'thumbsize' => 'Thumbnail size:',
+'showbigimage' => 'Download high resolution version ($1x$2, $3 KB)',
+
+'newimages' => 'Gallery of new files',
+'newimages-summary' => '',
+'showhidebots' => '($1 bots)',
+'noimages' => 'Nothing to see.',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+# variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+# variants for Kazakh language
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-cn' => 'kk-cn',
+'variantname-kk' => 'kk',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'User:',
+'speciallogtitlelabel' => 'Title:',
+
+'passwordtooshort' => 'Your password is too short. It must have at least $1 characters.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Warning\'\'\': This file may contain malicious code, by executing it your system may be compromised.<hr />',
+
+'fileinfo' => '$1KB, MIME type: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadata',
+'metadata-help' => 'This file contains additional information, probably added from the digital camera or scanner used to create or digitize it. If the file has been modified from its original state, some details may not fully reflect the modified image.',
+'metadata-expand' => 'Show extended details',
+'metadata-collapse' => 'Hide extended details',
+'metadata-fields' => 'EXIF metadata fields listed in this message will
+be included on image page display when the metadata table
+is collapsed. Others will be hidden by default.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# Exif tags
+'exif-imagewidth' =>'Width',
+'exif-imagelength' =>'Height',
+'exif-bitspersample' =>'Bits per component',
+'exif-compression' =>'Compression scheme',
+'exif-photometricinterpretation' =>'Pixel composition',
+'exif-orientation' =>'Orientation',
+'exif-samplesperpixel' =>'Number of components',
+'exif-planarconfiguration' =>'Data arrangement',
+'exif-ycbcrsubsampling' =>'Subsampling ratio of Y to C',
+'exif-ycbcrpositioning' =>'Y and C positioning',
+'exif-xresolution' =>'Horizontal resolution',
+'exif-yresolution' =>'Vertical resolution',
+'exif-resolutionunit' =>'Unit of X and Y resolution',
+'exif-stripoffsets' =>'Image data location',
+'exif-rowsperstrip' =>'Number of rows per strip',
+'exif-stripbytecounts' =>'Bytes per compressed strip',
+'exif-jpeginterchangeformat' =>'Offset to JPEG SOI',
+'exif-jpeginterchangeformatlength' =>'Bytes of JPEG data',
+'exif-transferfunction' =>'Transfer function',
+'exif-whitepoint' =>'White point chromaticity',
+'exif-primarychromaticities' =>'Chromaticities of primarities',
+'exif-ycbcrcoefficients' =>'Color space transformation matrix coefficients',
+'exif-referenceblackwhite' =>'Pair of black and white reference values',
+'exif-datetime' =>'File change date and time',
+'exif-imagedescription' =>'Image title',
+'exif-make' =>'Camera manufacturer',
+'exif-model' =>'Camera model',
+'exif-software' =>'Software used',
+'exif-artist' =>'Author',
+'exif-copyright' =>'Copyright holder',
+'exif-exifversion' =>'Exif version',
+'exif-flashpixversion' =>'Supported Flashpix version',
+'exif-colorspace' =>'Color space',
+'exif-componentsconfiguration' =>'Meaning of each component',
+'exif-compressedbitsperpixel' =>'Image compression mode',
+'exif-pixelydimension' =>'Valid image width',
+'exif-pixelxdimension' =>'Valid image height',
+'exif-makernote' =>'Manufacturer notes',
+'exif-usercomment' =>'User comments',
+'exif-relatedsoundfile' =>'Related audio file',
+'exif-datetimeoriginal' =>'Date and time of data generation',
+'exif-datetimedigitized' =>'Date and time of digitizing',
+'exif-subsectime' =>'DateTime subseconds',
+'exif-subsectimeoriginal' =>'DateTimeOriginal subseconds',
+'exif-subsectimedigitized' =>'DateTimeDigitized subseconds',
+'exif-exposuretime' =>'Exposure time',
+'exif-exposuretime-format' => '$1 sec ($2)',
+'exif-fnumber' =>'F Number',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'Exposure Program',
+'exif-spectralsensitivity' =>'Spectral sensitivity',
+'exif-isospeedratings' =>'ISO speed rating',
+'exif-oecf' =>'Optoelectronic conversion factor',
+'exif-shutterspeedvalue' =>'Shutter speed',
+'exif-aperturevalue' =>'Aperture',
+'exif-brightnessvalue' =>'Brightness',
+'exif-exposurebiasvalue' =>'Exposure bias',
+'exif-maxaperturevalue' =>'Maximum land aperture',
+'exif-subjectdistance' =>'Subject distance',
+'exif-meteringmode' =>'Metering mode',
+'exif-lightsource' =>'Light source',
+'exif-flash' =>'Flash',
+'exif-focallength' =>'Lens focal length',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' =>'Subject area',
+'exif-flashenergy' =>'Flash energy',
+'exif-spatialfrequencyresponse' =>'Spatial frequency response',
+'exif-focalplanexresolution' =>'Focal plane X resolution',
+'exif-focalplaneyresolution' =>'Focal plane Y resolution',
+'exif-focalplaneresolutionunit' =>'Focal plane resolution unit',
+'exif-subjectlocation' =>'Subject location',
+'exif-exposureindex' =>'Exposure index',
+'exif-sensingmethod' =>'Sensing method',
+'exif-filesource' =>'File source',
+'exif-scenetype' =>'Scene type',
+'exif-cfapattern' =>'CFA pattern',
+'exif-customrendered' =>'Custom image processing',
+'exif-exposuremode' =>'Exposure mode',
+'exif-whitebalance' =>'White Balance',
+'exif-digitalzoomratio' =>'Digital zoom ratio',
+'exif-focallengthin35mmfilm' =>'Focal length in 35 mm film',
+'exif-scenecapturetype' =>'Scene capture type',
+'exif-gaincontrol' =>'Scene control',
+'exif-contrast' =>'Contrast',
+'exif-saturation' =>'Saturation',
+'exif-sharpness' =>'Sharpness',
+'exif-devicesettingdescription' =>'Device settings description',
+'exif-subjectdistancerange' =>'Subject distance range',
+'exif-imageuniqueid' =>'Unique image ID',
+'exif-gpsversionid' =>'GPS tag version',
+'exif-gpslatituderef' =>'North or South Latitude',
+'exif-gpslatitude' =>'Latitude',
+'exif-gpslongituderef' =>'East or West Longitude',
+'exif-gpslongitude' =>'Longitude',
+'exif-gpsaltituderef' =>'Altitude reference',
+'exif-gpsaltitude' =>'Altitude',
+'exif-gpstimestamp' =>'GPS time (atomic clock)',
+'exif-gpssatellites' =>'Satellites used for measurement',
+'exif-gpsstatus' =>'Receiver status',
+'exif-gpsmeasuremode' =>'Measurement mode',
+'exif-gpsdop' =>'Measurement precision',
+'exif-gpsspeedref' =>'Speed unit',
+'exif-gpsspeed' =>'Speed of GPS receiver',
+'exif-gpstrackref' =>'Reference for direction of movement',
+'exif-gpstrack' =>'Direction of movement',
+'exif-gpsimgdirectionref' =>'Reference for direction of image',
+'exif-gpsimgdirection' =>'Direction of image',
+'exif-gpsmapdatum' =>'Geodetic survey data used',
+'exif-gpsdestlatituderef' =>'Reference for latitude of destination',
+'exif-gpsdestlatitude' =>'Latitude destination',
+'exif-gpsdestlongituderef' =>'Reference for longitude of destination',
+'exif-gpsdestlongitude' =>'Longitude of destination',
+'exif-gpsdestbearingref' =>'Reference for bearing of destination',
+'exif-gpsdestbearing' =>'Bearing of destination',
+'exif-gpsdestdistanceref' =>'Reference for distance to destination',
+'exif-gpsdestdistance' =>'Distance to destination',
+'exif-gpsprocessingmethod' =>'Name of GPS processing method',
+'exif-gpsareainformation' =>'Name of GPS area',
+'exif-gpsdatestamp' =>'GPS date',
+'exif-gpsdifferential' =>'GPS differential correction',
+
+# Make & model, can be wikified in order to link to the camera and model name
+
+'exif-make-value' => '$1',
+'exif-model-value' =>'$1',
+'exif-software-value' => '$1',
+
+# Exif attributes
+
+'exif-compression-1' => 'Uncompressed',
+'exif-compression-6' => 'JPEG',
+
+'exif-unknowndate' => 'Unknown date',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normal', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Flipped horizontally', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Rotated 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Flipped vertically', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Rotated 90° CCW and flipped vertically', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Rotated 90° CW', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Rotated 90° CW and flipped vertically', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Rotated 90° CCW', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'chunky format',
+'exif-planarconfiguration-2' => 'planar format',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'does not exist',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Not defined',
+'exif-exposureprogram-1' => 'Manual',
+'exif-exposureprogram-2' => 'Normal program',
+'exif-exposureprogram-3' => 'Aperture priority',
+'exif-exposureprogram-4' => 'Shutter priority',
+'exif-exposureprogram-5' => 'Creative program (biased toward depth of field)',
+'exif-exposureprogram-6' => 'Action program (biased toward fast shutter speed)',
+'exif-exposureprogram-7' => 'Portrait mode (for closeup photos with the background out of focus)',
+'exif-exposureprogram-8' => 'Landscape mode (for landscape photos with the background in focus)',
+
+'exif-subjectdistance-value' => '$1 metres',
+
+'exif-meteringmode-0' => 'Unknown',
+'exif-meteringmode-1' => 'Average',
+'exif-meteringmode-2' => 'CenterWeightedAverage',
+'exif-meteringmode-3' => 'Spot',
+'exif-meteringmode-4' => 'MultiSpot',
+'exif-meteringmode-5' => 'Pattern',
+'exif-meteringmode-6' => 'Partial',
+'exif-meteringmode-255' => 'Other',
+
+'exif-lightsource-0' => 'Unknown',
+'exif-lightsource-1' => 'Daylight',
+'exif-lightsource-2' => 'Fluorescent',
+'exif-lightsource-3' => 'Tungsten (incandescent light)',
+'exif-lightsource-4' => 'Flash',
+'exif-lightsource-9' => 'Fine weather',
+'exif-lightsource-10' => 'Cloudy weather',
+'exif-lightsource-11' => 'Shade',
+'exif-lightsource-12' => 'Daylight fluorescent (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Day white fluorescent (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Cool white fluorescent (W 3900 – 4500K)',
+'exif-lightsource-15' => 'White fluorescent (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standard light A',
+'exif-lightsource-18' => 'Standard light B',
+'exif-lightsource-19' => 'Standard light C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO studio tungsten',
+'exif-lightsource-255' => 'Other light source',
+
+'exif-focalplaneresolutionunit-2' => 'inches',
+
+'exif-sensingmethod-1' => 'Undefined',
+'exif-sensingmethod-2' => 'One-chip color area sensor',
+'exif-sensingmethod-3' => 'Two-chip color area sensor',
+'exif-sensingmethod-4' => 'Three-chip color area sensor',
+'exif-sensingmethod-5' => 'Color sequential area sensor',
+'exif-sensingmethod-7' => 'Trilinear sensor',
+'exif-sensingmethod-8' => 'Color sequential linear sensor',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'A directly photographed image',
+
+'exif-customrendered-0' => 'Normal process',
+'exif-customrendered-1' => 'Custom process',
+
+'exif-exposuremode-0' => 'Auto exposure',
+'exif-exposuremode-1' => 'Manual exposure',
+'exif-exposuremode-2' => 'Auto bracket',
+
+'exif-whitebalance-0' => 'Auto white balance',
+'exif-whitebalance-1' => 'Manual white balance',
+
+'exif-scenecapturetype-0' => 'Standard',
+'exif-scenecapturetype-1' => 'Landscape',
+'exif-scenecapturetype-2' => 'Portrait',
+'exif-scenecapturetype-3' => 'Night scene',
+
+'exif-gaincontrol-0' => 'None',
+'exif-gaincontrol-1' => 'Low gain up',
+'exif-gaincontrol-2' => 'High gain up',
+'exif-gaincontrol-3' => 'Low gain down',
+'exif-gaincontrol-4' => 'High gain down',
+
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'Soft',
+'exif-contrast-2' => 'Hard',
+
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Low saturation',
+'exif-saturation-2' => 'High saturation',
+
+'exif-sharpness-0' => 'Normal',
+'exif-sharpness-1' => 'Soft',
+'exif-sharpness-2' => 'Hard',
+
+'exif-subjectdistancerange-0' => 'Unknown',
+'exif-subjectdistancerange-1' => 'Macro',
+'exif-subjectdistancerange-2' => 'Close view',
+'exif-subjectdistancerange-3' => 'Distant view',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'North latitude',
+'exif-gpslatitude-s' => 'South latitude',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'East longitude',
+'exif-gpslongitude-w' => 'West longitude',
+
+'exif-gpsstatus-a' => 'Measurement in progress',
+'exif-gpsstatus-v' => 'Measurement interoperability',
+
+'exif-gpsmeasuremode-2' => '2-dimensional measurement',
+'exif-gpsmeasuremode-3' => '3-dimensional measurement',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometres per hour',
+'exif-gpsspeed-m' => 'Miles per hour',
+'exif-gpsspeed-n' => 'Knots',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'True direction',
+'exif-gpsdirection-m' => 'Magnetic direction',
+
+# external editor support
+'edit-externally' => 'Edit this file using an external application',
+'edit-externally-help' => 'See the [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] for more information.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'all',
+'imagelistall' => 'all',
+'watchlistall1' => 'all',
+'watchlistall2' => 'all',
+'namespacesall' => 'all',
+
+# E-mail address confirmation
+'confirmemail' => 'Confirm E-mail address',
+'confirmemail_noemail' => 'You do not have a valid email address set in your [[Special:Preferences|user preferences]].',
+'confirmemail_text' => "This wiki requires that you validate your e-mail address
+before using e-mail features. Activate the button below to send a confirmation
+mail to your address. The mail will include a link containing a code; load the
+link in your browser to confirm that your e-mail address is valid.",
+'confirmemail_pending' => '<div class="error">
+A confirmation code has already been e-mailed to you; if you recently
+created your account, you may wish to wait a few minutes for it to
+arrive before trying to request a new code.
+</div>',
+'confirmemail_send' => 'Mail a confirmation code',
+'confirmemail_sent' => 'Confirmation e-mail sent.',
+'confirmemail_oncreate' => 'A confirmation code was sent to your e-mail address.
+This code is not required to log in, but you will need to provide it before
+enabling any e-mail-based features in the wiki.',
+'confirmemail_sendfailed' => 'Could not send confirmation mail. Check address for invalid characters.
+
+Mailer returned: $1',
+'confirmemail_invalid' => 'Invalid confirmation code. The code may have expired.',
+'confirmemail_needlogin' => 'You need to $1 to confirm your email address.',
+'confirmemail_success' => 'Your e-mail address has been confirmed. You may now log in and enjoy the wiki.',
+'confirmemail_loggedin' => 'Your e-mail address has now been confirmed.',
+'confirmemail_error' => 'Something went wrong saving your confirmation.',
+
+'confirmemail_subject' => '{{SITENAME}} e-mail address confirmation',
+'confirmemail_body' => "Someone, probably you from IP address $1, has registered an
+account \"$2\" with this e-mail address on {{SITENAME}}.
+
+To confirm that this account really does belong to you and activate
+e-mail features on {{SITENAME}}, open this link in your browser:
+
+$3
+
+If this is *not* you, don't follow the link. This confirmation code
+will expire at $4.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Try exact match',
+'searchfulltext' => 'Search full text',
+'createarticle' => 'Create article',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Interwiki transcluding is disabled]',
+'scarytranscludefailed' => '[Template fetch failed for $1; sorry]',
+'scarytranscludetoolong' => '[URL is too long; sorry]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackbacks for this article:<br />
+$1
+</div>',
+'trackback' => '; $4$5 : [$2 $1]',
+'trackbackexcerpt' => '; $4$5 : [$2 $1]: <nowiki>$3</nowiki>',
+'trackbackremove' => ' ([$1 Delete])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'The trackback was successfully deleted.',
+
+
+# delete conflict
+
+'deletedwhileediting' => 'Warning: This page has been deleted after you started editing!',
+'confirmrecreate' => 'User [[User:$1|$1]] ([[User talk:$1|talk]]) deleted this page after you started editing with reason:
+: \'\'$2\'\'
+Please confirm that really want to recreate this page.',
+'recreate' => 'Recreate',
+'tooltip-recreate' => 'Recreate the page despite it has been deleted',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Redirecting to [[$1]]...',
+
+# action=purge
+'confirm_purge' => "Clear the cache of this page?\n\n$1",
+'confirm_purge_button' => 'OK',
+
+'youhavenewmessagesmulti' => "You have new messages on $1",
+'newtalkseperator' => ',_',
+'searchcontaining' => "Search for articles containing ''$1''.",
+'searchnamed' => "Search for articles named ''$1''.",
+'articletitles' => "Articles starting with ''$1''",
+'hideresults' => 'Hide results',
+
+# DISPLAYTITLE
+'displaytitle' => '(Link to this page as [[$1]])',
+
+# Separator for categories in page lists
+# Please don't localise this
+'catseparator' => '|',
+
+'loginlanguagelabel' => 'Language: $1',
+
+# Don't duplicate this in translations; defaults should remain consistent
+'loginlanguagelinks' => "* Deutsch|de
+* English|en
+* Esperanto|eo
+* Français|fr
+* Español|es
+* Italiano|it
+* Nederlands|nl",
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; previous page',
+'imgmultipagenext' => 'next page &rarr;',
+'imgmultigo' => 'Go!',
+'imgmultigotopre' => 'Go to page',
+'imgmultigotopost' => '',
+
+# Table pager
+'ascending_abbrev' => 'asc',
+'descending_abbrev' => 'desc',
+'table_pager_next' => 'Next page',
+'table_pager_prev' => 'Previous page',
+'table_pager_first' => 'First page',
+'table_pager_last' => 'Last page',
+'table_pager_limit' => 'Show $1 items per page',
+'table_pager_limit_submit' => 'Go',
+'table_pager_empty' => 'No results',
+
+# Auto-summaries
+'autosumm-blank' => 'Removing all content from page',
+'autosumm-replace' => 'Replacing page with \'$1\'',
+'autoredircomment' => 'Redirecting to [[$1]]', # This should be changed to the new naming convention, but existed beforehand.
+'autosumm-new' => 'New page: $1',
+
+# Autoblock whitelist
+'autoblock_whitelist' => 'AOL http://webmaster.info.aol.com/proxyinfo.html
+*64.12.96.0/19
+*149.174.160.0/20
+*152.163.240.0/21
+*152.163.248.0/22
+*152.163.252.0/23
+*152.163.96.0/22
+*152.163.100.0/23
+*195.93.32.0/22
+*195.93.48.0/22
+*195.93.64.0/19
+*195.93.96.0/19
+*195.93.16.0/20
+*198.81.0.0/22
+*198.81.16.0/20
+*198.81.8.0/23
+*202.67.64.128/25
+*205.188.192.0/20
+*205.188.208.0/23
+*205.188.112.0/20
+*205.188.146.144/30
+*207.200.112.0/21',
+
+# Size units
+'size-bytes' => '$1 B',
+'size-kilobytes' => '$1 KB',
+'size-megabytes' => '$1 MB',
+'size-gigabytes' => '$1 GB',
+
+);
+
+?>
diff --git a/languages/messages/MessagesEnRTL.php b/languages/messages/MessagesEnRTL.php
new file mode 100644
index 000000000000..9b557cd64d33
--- /dev/null
+++ b/languages/messages/MessagesEnRTL.php
@@ -0,0 +1,5 @@
+<?php
+
+$rtl = true;
+
+?>
diff --git a/languages/messages/MessagesEo.php b/languages/messages/MessagesEo.php
new file mode 100644
index 000000000000..e432246854cf
--- /dev/null
+++ b/languages/messages/MessagesEo.php
@@ -0,0 +1,1251 @@
+<?php
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciala',
+ NS_MAIN => '',
+ NS_TALK => 'Diskuto',
+ NS_USER => 'Vikipediisto', # FIXME: Generalize v-isto kaj v-io
+ NS_USER_TALK => 'Vikipediista_diskuto',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_diskuto',
+ NS_IMAGE => 'Dosiero', #FIXME: Check the magic for Image: and Media:
+ NS_IMAGE_TALK => 'Dosiera_diskuto',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_diskuto',
+ NS_TEMPLATE => 'Ŝablono',
+ NS_TEMPLATE_TALK => 'Ŝablona_diskuto',
+ NS_HELP => 'Helpo',
+ NS_HELP_TALK => 'Helpa_diskuto',
+ NS_CATEGORY => 'Kategorio',
+ NS_CATEGORY_TALK => 'Kategoria_diskuto',
+);
+
+$quickbarSettings = array(
+ 'Nenia', 'Fiksiĝas maldekstre', 'Fiksiĝas dekstre', 'Ŝvebas maldekstre'
+);
+
+$skinNames = array(
+ 'standard' => 'Klasika',
+ 'nostalgia' => 'Nostalgio',
+ 'cologneblue' => 'Kolonja Bluo',
+ 'mono' => 'Senkolora',
+ 'monobook' => 'Librejo',
+ 'chick' => 'Kokido',
+);
+
+$separatorTransformTable = array(',' => ' ', '.' => ',' );
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. M Y',
+ 'dmy both' => 'H:i, j. M Y',
+);
+
+
+$messages = array(
+'tog-underline' => 'Substreku ligilojn',
+'tog-highlightbroken' => 'Ruĝigu ligilojn al neekzistantaj paĝoj',
+'tog-justify' => 'Alkadrigu liniojn',
+'tog-hideminor' => 'Kaŝu malgrandajn redaktetojn ĉe <i>Lastaj ŝanĝoj</i>',
+'tog-usenewrc' => 'Novstila Lastaj Ŝanĝoj (bezonas JavaSkripton)',
+'tog-numberheadings' => 'Aŭtomate numeru sekciojn',
+'tog-showtoolbar' => 'Montru eldonilaron',
+'tog-editondblclick' => 'Redaktu per duobla alklako (JavaScript)',
+'tog-editsection' => 'Montru [redaktu]-ligiloj por sekcioj',
+'tog-editsectiononrightclick'=> 'Redaktu sekciojn per dekstra musklako',
+'tog-showtoc' => 'Montru liston de enhavoj',
+'tog-rememberpassword' => 'Memoru mian pasvorton',
+'tog-editwidth' => 'Redaktilo estu plenlarĝa',
+'tog-watchcreations' => 'Aldonu de mi kreitajn paĝojn al mia atentaro',
+'tog-watchdefault' => 'Priatentu paĝojn de vi redaktintajn',
+'tog-minordefault' => 'Marku ĉiujn redaktojn malgrandaj',
+'tog-previewontop' => 'Montru antaŭrigardon antaŭ redaktilo',
+'tog-previewonfirst' => 'Montru antaŭrigardon je unua redakto',
+'tog-nocache' => 'Malaktivigu kaŝmemorigon de paĝoj.',
+'tog-enotifwatchlistpages'=> 'Sendu al mi retmesaĝon kiam tiu paĝo estas ŝanĝita',
+'tog-enotifusertalkpages'=> 'Sendu al mi retmesaĝon kiam mia diskutpaĝo estas ŝanĝita',
+'tog-shownumberswatching'=> 'Montru la nombron da priatentaj uzantoj',
+'tog-fancysig' => 'Simpla subskribo (sen aŭtomata ligo)',
+'tog-externaleditor' => 'Uzu defaŭlte eksteran tekstprilaborilon',
+'tog-externaldiff' => 'Uzu defaŭlte eksteran ŝanĝmontrilon',
+'tog-showjumplinks' => 'Ebligi alirligojn "salti al"
+<!-- Bonvolu kontroli ĉu ĝustas la traduko de : Enable "jump to" accessibility links -->',
+'tog-watchlisthideown' => 'Kaŝu miajn redaktojn de la atentaro',
+'tog-watchlisthidebots' => 'Kaŝu bot-redaktojn de la atentaro',
+'underline-always' => 'Ĉiam',
+'underline-never' => 'Neniam',
+'underline-default' => 'Defaŭlte laŭ foliumilo',
+'skinpreview' => '(Antaŭrigardo)',
+'sunday' => 'dimanĉo',
+'monday' => 'lundo',
+'tuesday' => 'mardo',
+'wednesday' => 'merkredo',
+'thursday' => 'ĵaŭdo',
+'friday' => 'vendredo',
+'saturday' => 'sabato',
+'january' => 'januaro',
+'february' => 'februaro',
+'march' => 'marto',
+'april' => 'aprilo',
+'may_long' => 'majo',
+'june' => 'junio',
+'july' => 'julio',
+'august' => 'aŭgusto',
+'september' => 'septembro',
+'october' => 'oktobro',
+'november' => 'novembro',
+'december' => 'decembro',
+'may' => 'Maj',
+'aug' => 'Aŭg',
+'oct' => 'Okt',
+'categories' => 'Kategorioj',
+'pagecategories' => '{{PLURAL:$1|Kategorio|Kategorioj}}',
+'category_header' => 'Artikoloj en kategorio "$1"',
+'subcategories' => 'Subkategorioj',
+'mainpage' => 'Ĉefpaĝo',
+'mainpagetext' => 'Vikisoftvaro sukcese instaliĝis.',
+'mainpagedocfooter' => 'Consult the [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide User\'s Guide] for information on using the wiki software.
+
+== Getting started ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikipedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]',
+'portal' => 'Komunuma portalo',
+'portal-url' => 'Project:Komunuma portalo',
+'about' => 'Enkonduko',
+'aboutsite' => 'Pri {{SITENAME}}',
+'aboutpage' => '{{SITENAME}}:Enkonduko',
+'article' => 'Artikolo',
+'help' => 'Helpo',
+'helppage' => 'Help:Enhavo',
+'bugreports' => 'Raportu cimojn',
+'bugreportspage' => 'Project:Raportu cimojn',
+'sitesupport' => 'Subteno',
+'sitesupport-url' => 'Project:Subteno',
+'faq' => 'Oftaj demandoj',
+'faqpage' => 'Project:Oftaj demandoj',
+'edithelp' => 'Helpo pri redaktado',
+'newwindow' => '(en nova fenestro)',
+'edithelppage' => 'Help:Kiel redakti paĝon',
+'cancel' => 'Nuligu',
+'qbfind' => 'Trovu',
+'qbbrowse' => 'Foliumado',
+'qbedit' => 'Redaktado',
+'qbpageoptions' => 'Paĝagado',
+'qbpageinfo' => 'Paĝinformoj',
+'qbmyoptions' => 'Personaĵoj',
+'qbspecialpages' => 'Specialaj paĝoj',
+'moredotdotdot' => 'Pli...',
+'mypage' => 'Mia paĝo',
+'mytalk' => 'Mia diskuto',
+'anontalk' => 'Diskutpaĝo por tiu ĉi IP',
+'navigation' => 'Navigado',
+'currentevents' => 'Aktualaĵoj',
+'currentevents-url' => 'Aktualaĵoj',
+'disclaimers' => 'Malgarantio',
+'disclaimerpage' => 'Malgarantia paĝo',
+'privacy' => 'Regularo pri respekto de la privateco',
+'privacypage' => 'Project:Respekto de la privateco',
+'errorpagetitle' => 'Eraro',
+'returnto' => 'Revenu al $1.',
+'tagline' => 'El {{SITENAME}}',
+'search' => 'Serĉu',
+'searchbutton' => 'Serĉu',
+'go' => 'Ek!',
+'searcharticle' => 'Ek!',
+'history' => 'Malnovaj versioj',
+'history_short' => 'Historio',
+'updatedmarker' => 'ĝisdatita de post mia lasta vizito',
+'info_short' => 'Informo',
+'printableversion' => 'Presebla versio',
+'permalink' => 'Konstanta ligilo',
+'edit' => 'Redaktu',
+'editthispage' => 'Redaktu la paĝon',
+'delete' => 'Forigu',
+'deletethispage' => 'Forigu la paĝon',
+'undelete_short' => 'Malforigu $1 redaktojn',
+'protect' => 'Protektu',
+'protectthispage' => 'Protektu la paĝon',
+'unprotect' => 'Malprotektu',
+'unprotectthispage' => 'Malprotektu la paĝon',
+'newpage' => 'Nova paĝo',
+'talkpage' => 'Diskutu la paĝon',
+'specialpage' => 'Speciala Paĝo',
+'personaltools' => 'Personaj iloj',
+'postcomment' => 'Afiŝu komenton',
+'articlepage' => 'Vidu la artikolon',
+'talk' => 'Diskuto',
+'views' => 'Vidoj',
+'toolbox' => 'Iloj',
+'userpage' => 'Vidu personan paĝon',
+'imagepage' => 'Vidu dosieropaĝon',
+'viewtalkpage' => 'Vidu diskutopaĝon',
+'otherlanguages' => 'Aliaj lingvoj',
+'redirectedfrom' => '(Alidirektita el $1)',
+'redirectpagesub' => 'Redirekta paĝo',
+'lastmodifiedat' => 'Laste redaktita je $2, $1.',
+'viewcount' => 'Montrita $1-foje.',
+'copyright' => 'La enhavo estas havebla sub $1.',
+'protectedpage' => 'Protektita paĝo',
+'jumpto' => 'Saltu al:',
+'jumptonavigation' => 'navigado',
+'jumptosearch' => 'serĉo',
+'badaccess' => 'Vi ne havas sufiĉe da redaktorajtoj por tiu paĝo.',
+'versionrequired' => 'Versio $1 de MediaWiki nepras',
+'versionrequiredtext' => 'La versio $1 de MediaWiki estas necesa por uzi ĉi tiun paĝon. Vidu [[Special:Version]]',
+'ok' => 'Ek!',
+'retrievedfrom' => 'Elŝutita el "$1"',
+'youhavenewmessages' => 'Por vi estas $1 ($2).',
+'newmessageslink' => 'nova mesaĝo',
+'newmessagesdifflink' => 'ŝanĝoj kompare kun antaŭlasta versio',
+'editsection' => '<small>redaktu</small>',
+'editsectionhint' => 'Redaktu sekcion: $1',
+'toc' => 'Enhavo',
+'showtoc' => 'montru',
+'hidetoc' => 'kaŝu',
+'thisisdeleted' => 'Vidu aŭ restarigu $1?',
+'viewdeleted' => 'Rigardu $1?',
+'restorelink' => '$1 forigita(j)n versio(j)n',
+'feedlinks' => 'Nutro:',
+'nstab-main' => 'Artikolo',
+'nstab-user' => '**** root {{lcfirst:ns:user}}a / Vikipediista paĝo',
+'nstab-media' => 'Media paĝo',
+'nstab-special' => 'Speciala',
+'nstab-image' => 'Bildo',
+'nstab-mediawiki' => 'Sistema mesaĝo',
+'nstab-template' => 'Ŝablono',
+'nstab-help' => 'Helpo',
+'nstab-category' => 'Kategorio',
+'nosuchaction' => 'Ne ekzistas tia ago',
+'nosuchactiontext' => 'La agon (\'action\') nomitan de la URL
+ne agnoskas la programaro de {{SITENAME}}',
+'nosuchspecialpage' => 'Ne ekzistas tia speciala paĝo',
+'nospecialpagetext' => 'Vi petis [[Special:Specialpages|specialan paĝon]] kiun ne agnoskas la programaro de {{SITENAME}}.',
+'error' => 'Eraro',
+'databaseerror' => 'Datumbaza eraro',
+'dberrortext' => 'Sintakseraro okazis en informpeto al la datumaro.
+Jen la plej laste provita informmendo:
+<blockquote><tt>$1</tt></blockquote>
+el la funkcio "<tt>$2</tt>".
+MySQL redonis eraron "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Okazis sintaksa eraro en la informpeto al la datumaro.
+La lasta provita peto estis:
+"$1"
+el la funkcio "$2".
+\'\'MySQL\'\' resendis la erarmesaĝon "$3: $4".',
+'noconnect' => 'Neeblis konekti al la datumbazo; estas ia erarao aŭ oni riparadas la servilon.
+<br />
+$1',
+'nodb' => 'Neeblis elekti datumaron $1',
+'cachederror' => 'Intertempe, jen konservita kopio de la petita paĝo (ĝi eble ne estas ĝisdata).',
+'readonly' => 'Datumaro ŝlosita, nurlega',
+'enterlockreason' => 'Bonvolu klarigi, kial oni ŝlosas la datumaron, kaj
+la estimatan tempon de malŝlosado.',
+'readonlytext' => 'La datumaro de {{SITENAME}} estas nun ŝlosita kontraŭ
+novaj aldonaj kaj aliaj ŝanĝoj, probable pro laŭkutima flegado de la datumaro.
+Bonvolu reprovu post iom da tempo.
+
+La ŝlosinto lasis la jenan mesaĝon:
+<p>$1</p>',
+'missingarticle' => 'La datumbazo ne trovis la tekston de
+artikolo, kiun ĝi devus trovi, nomita "$1".
+Ĉi tio ne estas eraro de la datumbazo, sed probable cimo en la programo.
+Bonvolu raporti ĉi tion al iu sistemestro, kaj rimarkigi la retadreson (URL).',
+'internalerror' => 'Interna eraro',
+'filecopyerror' => 'Neeblis kopii dosieron "$1" al "$2".',
+'filerenameerror' => 'Neeblis alinomi dosieron "$1" al "$2".',
+'filedeleteerror' => 'Neeblis forigi dosieron "$1".',
+'filenotfound' => 'Neeblis trovi dosieron "$1".',
+'unexpected' => 'Neatendita valuto: "$1"="$2".',
+'formerror' => 'Eraro: neeblis liveri formulon',
+'badarticleerror' => 'Tiun ĉi agon oni ne povas apliki al tiu ĉi artikolo.',
+'cannotdelete' => 'Neeblis forigi la elektitan paĝon aŭ dosieron.',
+'badtitle' => 'Nevalida titolo',
+'badtitletext' => 'La petita paĝotitolo estas nevalida, malplena, aŭ
+malĝuste ligita interlingva aŭ intervikia titolo.',
+'perfdisabled' => 'Ni petas pardonon! La petita funkcio estas malebligita
+provizore por konservi la rapidecon de la servilo.',
+'perfdisabledsub' => 'Jen konservita kopio laŭ $1:',
+'perfcached' => 'La sekvantaj informoj venas el kaŝmemoro kaj eble ne estas ĝisdataj :',
+'wrong_wfQuery_params' => 'Malĝustaj parametroj por wfQuery()<br />
+Funkcio: $1<br />
+Peto: $2',
+'viewsource' => 'Vidu vikitekston',
+'viewsourcefor' => 'por $1',
+'protectedtext' => 'Tiu ĉi paĝo estas ŝlosita kontraŭ redaktado; estas diversaj eblaj kialoj por tio. Bv legi [[Project:Ŝlositaj paĝoj]].
+
+Vi ja rajtas vidi kaj kopii la fontotekston de la vikipaĝo:',
+'editinginterface' => '\'\'\'Atentu:\'\'\' Vi redaktas paĝon, kiu estas uzata kiel interfaca teksto por la softvaro. Ŝanĝoj de tiu ĉi teksto povas ŝanĝi aspekton de la interfaco por aliaj uzantoj.',
+'logouttitle' => 'Elsalutu!',
+'logouttext' => '<strong>Vi elsalutis kaj finis vian seancon.</strong><br />
+Vi rajtas daŭre vikiumi sennome, aŭ vi povas reensaluti kiel la sama aŭ kiel alia uzanto.',
+'welcomecreation' => '<h2>Bonvenon, $1!</h2> Via konto estas kreita.
+<span style="color:#ff0000">Ne forgesu fari viajn {{SITENAME}}-preferojn!</span>',
+'loginpagetitle' => 'Ensalutu / enskribu',
+'yourname' => 'Via salutnomo',
+'yourpassword' => 'Via pasvorto',
+'yourpasswordagain' => 'Retajpu pasvorton',
+'remembermypassword' => 'Rememoru mian pasvorton.',
+'yourdomainname' => 'Via domajno',
+'externaldberror' => 'Aŭ estis datenbaza eraro rilate al ekstera aŭtentikigado, aŭ vi ne permesas ĝisdatigi vian eksteran konton.',
+'loginproblem' => '<b>Okazis problemo pri via ensalutado.</b><br />Bonvolu reprovi!',
+'alreadyloggedin' => '<strong>$1, vi jam estas ensalutinta!</strong><br />',
+'login' => 'Ensalutu',
+'loginprompt' => 'Necesas ke via foliumilo permesu kuketojn por ensaluti en la {{SITENAME}}.',
+'userlogin' => 'Ensalutu',
+'logout' => 'Elsalutu',
+'userlogout' => 'Elsalutu',
+'notloggedin' => 'Ne ensalutinta',
+'nologin' => 'Ĉu vi ne jam havas salutnomon? $1.',
+'nologinlink' => 'Kreu konton',
+'createaccount' => 'Kreu novan konton',
+'createaccountmail' => 'retpoŝte',
+'badretype' => 'La pasvortoj kiujn vi tajpis ne egalas.',
+'userexists' => 'Jam estas uzanto kun la nomo kiun vi elektis. Bonvolu elekti alian nomon.',
+'youremail' => 'Via retpoŝtadreso',
+'username' => 'Salutnomo:',
+'uid' => 'Uzantnumero:',
+'yourrealname' => 'Vera nomo¹',
+'yourlanguage' => 'Lingvo',
+'yourvariant' => 'Varianto',
+'yournick' => 'Via kaŝnomo (por subskriboj)',
+'badsig' => 'La kruda identigaĵo nevalidas; kontrolu la HTML-etikedojn.',
+'email' => 'Retpoŝto',
+'prefs-help-realname' => '* Vera nomo (opcia) : se vi elektas sciigi ĝin, ĝi estos uzita por aŭtorigi vin pri viaj kontribuoj.',
+'loginerror' => 'Ensaluta eraro',
+'prefs-help-email' => '* Retpoŝto (opcia) : ebligas al aliaj kontakti vin tra via uzantpaĝo aŭ diskutpaĝo sen neceso malkaŝi vian identecon.',
+'nocookiesnew' => 'La uzantokonto estis kreita sed vi ne estas ensalutinta. *** E-igo lcfirst {{SITENAME}} uzas kuketojn por akcepti uzantojn. Kuketoj esta malaktivigitaj ĉe vi. Bonvolu aktivigi ilin kaj ensalutu per viaj novaj salutnomo kaj pasvorto.',
+'nocookieslogin' => '{{SITENAME}} uzas kuketojn por akcepti uzantojn. Kuketoj esta malaktivigitaj ĉe vi. Bonvolu aktivigi ilin kaj provu denove.',
+'noname' => 'Vi ne tajpis validan salutnomon.',
+'loginsuccesstitle' => 'Ensalutado sukcesis',
+'loginsuccess' => 'Vi nun estas en la {{SITENAME}} kiel uzanto "$1".',
+'nosuchuser' => 'Neniu uzanto nomiĝas "$1".
+Bonvolu kontroli vian literumadon, aŭ uzu la malsupran formularon por krei novan konton.',
+'nosuchusershort' => 'Ne ekzistas uzanto kun la nomo "$1". Bonvolu kontroli vian ortografion.',
+'wrongpassword' => 'Vi tajpis malĝustan pasvorton. Bonvolu provi denove.',
+'wrongpasswordempty' => 'Vi tajpis malplenan pasvorton. Bonvolu provi denove.',
+'mailmypassword' => 'Retpoŝtu al mi novan pasvorton',
+'passwordremindertitle' => 'Rememorigo el {{SITENAME}} pri perdita pasvorto',
+'passwordremindertext' => 'Iu (probable vi, el IP-adreso $1)
+petis, ke ni sendu al vi novan pasvorton por ensaluti {{SITENAME}}n ($4).
+La pasvorto por uzanto "$2" nun estas "$3".
+Ni rekomendas, ke vi nun ensalutu kaj ŝanĝu vian pasvorton.',
+'noemail' => 'Retpoŝtadreso ne estas registrita por uzanto "$1".',
+'passwordsent' => 'Oni sendis novan pasvorton al la retpoŝtadreso
+registrita por "$1".
+Bonvolu saluti denove ricevinte ĝin.',
+'eauthentsent' => 'Konfirma retmesaĝo estas sendita al la nomita retadreso. Antaŭ ol iu ajn alia mesaĝo estos sendita al la konto, vi devos sekvi la instrukciojn en la mesaĝo por konfirmi ke la konto ja estas la via.',
+'acct_creation_throttle_hit'=> 'Ni pardonpetas - vi jam kreis $1 kontojn. Vi ne povas krei pli.',
+'emailauthenticated' => 'Via retpoŝta adreso estis autentikigita ĉe $1.',
+'emailnotauthenticated' => 'Via retadreso ne jam estas aŭtentigita. Neniu retmesaĝo estos sendita al iu el la sekvantaj adresoj.',
+'emailconfirmlink' => 'Konfirmu vian retpoŝtan adreson',
+'invalidemailaddress' => 'La retpoŝt-adreso ne estas akceptebla ĉar ĝi ŝajne havas nevalidan formaton. Bonvole entajpu ĝust-formatan adreson, aŭ malplenigu la zonon.',
+'accountcreated' => 'Konto kreita',
+'accountcreatedtext' => 'La uzanto-konto por $1 estas kreita.',
+'bold_sample' => 'Grasa teksto',
+'bold_tip' => 'Grasa teksto',
+'italic_sample' => 'Kursiva teksto',
+'italic_tip' => 'Kursiva teksto',
+'link_sample' => 'Ligtitolo',
+'link_tip' => 'Interna ligo',
+'extlink_sample' => 'http://www.ekzemplo.com ligtitolo',
+'extlink_tip' => 'Ekstera ligo (memoru http:// prefikson)',
+'headline_sample' => 'Titola teksto',
+'headline_tip' => 'Titololinio je dua nivelo',
+'math_sample' => 'Enmetu formulon ĉi tien',
+'math_tip' => 'Matematika formulo (LaTeX)',
+'nowiki_sample' => ' Enmetu ne formatitan tekston ĉi tien',
+'nowiki_tip' => 'Ignoru vikiformatadon',
+'image_sample' => 'Ekzemplo.jpg',
+'image_tip' => 'Enŝutita bildo',
+'media_sample' => 'Ekzemplo.mp3',
+'media_tip' => 'Ligo al dosiero sona ...',
+'sig_tip' => 'Via subskribo kun tempstampo',
+'hr_tip' => 'Horizontala linio (uzu ŝpareme)',
+'summary' => 'Resumo',
+'subject' => 'Temo/subtitolo',
+'minoredit' => 'Ĉi tiu ŝanĝo estas redakteto',
+'watchthis' => 'Atentadu la artikolon',
+'savearticle' => 'Konservu ŝanĝojn',
+'preview' => 'Antaŭrigardo',
+'showpreview' => 'Antaŭrigardu',
+'showdiff' => 'Montru ŝanĝojn',
+'anoneditwarning' => 'Vi ne estas ensalutinta. Via IP-adreso enregistriĝos en la ŝango-historio de tiu ĉi paĝo.',
+'missingsummary' => '\'\'\'Rememorigilo:\'\'\' Vi ne provizis redaktan resumon. Se vi alklakos denove la savan butonon, via redaktaĵo estos storata sen resumo.',
+'missingcommenttext' => 'Bonvolu entajpi komenton malsupre.',
+'blockedtitle' => 'La uzanto estas forbarita.',
+'blockedtext' => 'Via konto aŭ IP-adreso estis forbarita fare de $1,
+kiu priskribis la kialon jene:<br />
+$2<br />
+Vi rajtas kontakti tiun administranton por pridiskuti la forbaradon.
+
+Via IP-adreso estas $3. Bonvolu mencii ĝin en ajna plendo.',
+'whitelistedittitle' => 'Ensalutado devigata por redakti',
+'whitelistedittext' => 'Vi devas $1 por redakti paĝojn.',
+'whitelistreadtitle' => 'Ensalutado devigata por legi',
+'whitelistreadtext' => 'Vi devas [[Special:Userlogin|ensaluti]] por legi paĝojn.',
+'whitelistacctitle' => 'Vi ne rajtas krei konton',
+'whitelistacctext' => 'Por rajti krei konton en ĉi tiu vikio vi devas [[Special:Userlogin|ensaluti]] kaj havi la taŭgajn permesojn.',
+'confirmedittitle' => 'Nepras konfirmi per retpoŝto por redakti',
+'confirmedittext' => 'Vi devas konfirmi vian retpoŝtan adreson antaŭ ol redakti paĝojn. Bonvolu agordi kaj validigi vian retadreson per viaj [[Special:Preferences|uzulaj preferoj]].',
+'loginreqtitle' => 'Nepre ensalutu',
+'loginreqlink' => 'login',
+'loginreqpagetext' => 'Vi devas $1 por rigardi aliajn paĝojn.',
+'accmailtitle' => 'Pasvorto sendita.',
+'accmailtext' => 'La pasvorto por \'$1\' estis sendita al $2.',
+'newarticle' => '(Nova)',
+'newarticletext' => 'Vi sekvis ligilon al paĝo jam ne ekzistanta. Se vi volas krei ĝin, ektajpu sube (vidu la [[Project:Helpo|helpopaĝo]] por klarigoj.) Se vi malintence alvenis ĉi tien, simple alklaku la retrobutonon de via retumilo.',
+'anontalkpagetext' => '---- \'\'Jen diskutopaĝo por iu anonima kontribuanto kiu ne jam kreis konton aŭ ne uzas ĝin. Ni tial devas uzi la cifran [[IP-adreso]] por identigi lin. la sama [[IP-adreso]] povas estis samtempte uzata de pluraj uzantoj. Se vi estas anonimulo kaj preferus eviti tiajn mistrafajn komentojn kaj konfuziĝon kun aliaj anonimuloj de via retejo, bonvolu [[Special:Userlogin|krei konton aŭ ensaluti]].\'\'',
+'noarticletext' => '(La paĝo nun estas malplena. Se vi ĵus kreis tiun ĉi paĝon klaku [{{fullurl:{{FULLPAGENAME}}|action=purge}} ĉi tien].)',
+'clearyourcache' => '\'\'\'Notu:\'\'\' Post konservado vi forviŝu la kaŝmemoron de via foliumilo por vidi la ŝanĝojn : \'\'\'Mozilo:\'\'\' alklaku \'\'Reŝarĝi\'\' (aŭ \'\'Stir-Shift-R\'\'), \'\'\'IE / Opera:\'\'\' \'\'Stir-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-R\'\', \'\'\'Konqueror\'\'\' \'\'Stir-R\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Konsileto:</strong> Uzu la "Antaŭrigardan" butonon por provi vian novan css/js antaŭ konservi.',
+'usercsspreview' => '\'\'\'Memoru ke vi nur antaŭrigardas vian uzulan [[CSS]]. Ĝi ne jam estas konservita!\'\'\'',
+'userjspreview' => '\'\'\'Memoru ke vi nun nur provas kaj antaŭrigardas vian uzantan javaskripton, ĝi ne estas jam konservita\'\'\'',
+'updated' => '(Ŝanĝo registrita)',
+'note' => '<strong>Noto:</strong>',
+'previewnote' => 'Memoru, ke ĉi tio estas nur antaŭrigardo kaj ankoraŭ ne konservita!',
+'session_fail_preview' => '<strong>Bedaŭrinde ne eblis trakti vian redakton pro manko de sesiaj datenoj. Bonvolu provi refoje. Se ankoraŭ ne efikas post tio, elsalutu kaj poste re-ensalutu.</strong>',
+'previewconflict' => 'La jena antaŭrigardo montras la tekston el la supra tekstujo,
+kiel ĝi aperos se vi elektos konservi la paĝon.',
+'editing' => 'Redaktante $1',
+'editinguser' => 'Redaktante $1',
+'editingsection' => 'Redaktante $1 (sekcion)',
+'editingcomment' => 'Redaktante $1 (komenton)',
+'editconflict' => 'Redakta konflikto: $1',
+'explainconflict' => 'Iu alia ŝanĝis la paĝon post kiam vi ekredaktis.
+La supra tekstujo enhavas la aktualan tekston de la artikolo.
+Viaj ŝanĝoj estas en la malsupra tekstujo.
+Vi devas mem kunfandi viajn ŝanĝojn kaj la jaman tekston.
+<b>Nur</b> la teksto en la supra tekstujo estos konservita kiam
+vi alklakos "Konservu".<br />',
+'yourtext' => 'Via teksto',
+'storedversion' => 'Registrita versio',
+'nonunicodebrowser' => '<strong>ATENTU: Via foliumilo ne eltenas unikodon, bonvolu ŝanĝi ĝin antaŭ ol redakti artikolon.</strong>',
+'editingold' => '<strong>AVERTO: Vi nun redaktas malnovan version de tiu ĉi artikolo.
+Se vi konservos vian redakton, ĉiuj ŝanĝoj faritaj post tiu versio perdiĝos.</strong>',
+'yourdiff' => 'Malsamoj',
+'copyrightwarning' => 'Bonvolu noti, ke ĉiu kontribuaĵo al la {{SITENAME}} estu rigardata kiel eldonita laŭ $2 (vidu je $1). Se vi volas, ke via verkaĵo ne estu redaktota senkompate kaj disvastigota laŭvole, ne alklaku "Konservu".<br />
+Vi ankaŭ ĵuras, ke vi mem verkis la tekston, aŭ ke vi kopiis ĝin el fonto senkopirajta.
+<strong>NE UZU KOPIRAJTAJN VERKOJN SENPERMESE!</strong>',
+'copyrightwarning2' => 'Bonvolu noti ke ĉiuj kontribuoj al {{SITENAME}} povas esti reredaktita, ŝanĝita aŭ forigita de aliaj kontribuantoj. Se vi ne deziras ke viaj verkoj estu senkompate reredaktitaj, ne publikigu ilin ĉi tie. <br />
+Vi ankaŭ promesu al ni ke vi verkis tion mem aŭ kopiis el publika domajno aŭ simila libera fonto (vidu $1 por detaloj).
+<strong>NE PROPONU KOPIRAJTITAJN VERKOJN SEN PERMESO! </strong>',
+'longpagewarning' => '<strong>AVERTO: Tiu ĉi paĝo longas $1 kilobitokojn; kelkaj retumiloj
+povas fuŝi redaktante paĝojn je longo proksime aŭ preter 32kb.
+Se eble, bonvolu disigi la paĝon al malpli grandajn paĝerojn.</strong>',
+'longpageerror' => '<strong>Eraro: La teksto, kiun vi prezentis, longas $1 kilobajtojn, kio estas pli longa ol la maksimumo de $2 kilobajtoj. Ĝi ne povas esti storata.</strong>',
+'readonlywarning' => '<strong>AVERTO: La datumbazo estas ŝlosita por teknika laboro;
+pro tio neeblas nun konservi vian redaktadon. Vi povas elkopii kaj englui
+la tekston al tekstdosiero por poste reenmeti ĝin al la vikio.</strong>',
+'protectedpagewarning' => '<strong>AVERTO: Tiu ĉi paĝo estas ŝlosita kontraŭ redaktado krom de administrantoj (t.e., vi). Bv certiĝi, ke vi sekvas la normojn de la komunumo per via redaktado. Vidu [[Project:Ŝlositaj paĝoj|Ŝlositaj paĝoj]].</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Notu:\'\'\' Ĉi paĝo estas protektita tiel ke nur [[Special:Userlogin|ensalutintaj]] uzuloj povas redakti ĝin.',
+'templatesused' => 'Ŝablonoj uzitaj sur ĉi paĝo:',
+'revhistory' => 'Historio de redaktoj',
+'nohistory' => 'Ne ekzistas historio de redaktoj por ĉi tiu paĝo.',
+'revnotfound' => 'Ne ekzistas malnova versio de la artikolo',
+'revnotfoundtext' => 'Ne eblis trovi malnovan version de la artikolo kiun vi petis.
+Bonvolu kontroli la retadreson (URL) kiun vi uzis por atingi la paĝon.\b',
+'loadhist' => 'Ŝarĝas redaktohistorion',
+'currentrev' => 'Aktuala versio',
+'revisionasof' => 'Kiel registrite je $1',
+'previousrevision' => '← Antaŭa versio',
+'nextrevision' => 'Sekva versio →',
+'currentrevisionlink' => 'vidu nunan version',
+'cur' => 'nun',
+'next' => 'sekv',
+'last' => 'ant',
+'histlegend' => 'Klarigo: (nun) = vidu malsamojn kompare kun la nuna versio,
+(ant) = malsamojn kompare kun la antaŭa versio, M = malgranda redakteto',
+'deletedrev' => '[forigita]',
+'histfirst' => 'plej frua',
+'histlast' => 'plej lasta',
+'difference' => '(Malsamoj inter versioj)',
+'loadingrev' => 'ŝarĝas version por malsamoj',
+'lineno' => 'Linio $1:',
+'editcurrent' => 'Redaktu la nunan version de la paĝo',
+'selectnewerversionfordiff'=> 'Elektu la pli novan version por kompari.',
+'selectolderversionfordiff'=> 'Elektu malpli novan version por kompari.',
+'compareselectedversions'=> 'Komparu la selektitajn versiojn',
+'searchresults' => 'Serĉrezultoj',
+'searchresulttext' => 'Por pliaj informoj kiel priserĉi la {{SITENAME}}n, vidu [[Project:Serĉado|serĉi en {{SITENAME}}]].',
+'searchsubtitle' => 'Serĉmendo "[[:$1]]"',
+'searchsubtitleinvalid' => 'Serĉmendo "$1"',
+'badquery' => 'Misformita serĉmendo',
+'badquerytext' => 'Via serĉmendo ne estis plenumebla.
+Eble vi provis serĉi vorton kun malpli ol tri literoj.
+Tion la oni ankoraŭ ne povas fari. Ankaŭ eblas, ke vi mistajpis la
+esprimon. Bonvolu reserĉi.',
+'matchtotals' => 'La serĉmendo "$1" liveris $2 artikolojn laŭ titolo
+kaj $3 artikolojn laŭ enhavo.',
+'titlematches' => 'Trovitaj laŭ titolo',
+'notitlematches' => 'Neniu trovita laŭ titolo',
+'textmatches' => 'Trovitaj laŭ enhavo',
+'notextmatches' => 'Neniu trovita laŭ enhavo',
+'prevn' => '$1 antaŭajn',
+'nextn' => '$1 sekvajn',
+'viewprevnext' => 'Montru ($1) ($2) ($3).',
+'showingresults' => 'Montras <b>$1</b> trovitajn ekde la <b>$2</b>-a.',
+'showingresultsnum' => 'Montras <b>$3</b> trovitajn ekde la <b>$2</b>-a.',
+'nonefound' => '<strong>Noto</strong>: malsukcesaj serĉoj ofte
+okazas ĉar oni serĉas tro da ofte uzataj vortoj, kiujn ne enhavas la indekso,
+aŭ ĉar oni petas tro da serĉvortoj (nur paĝoj kiuj enhavas ĉiun serĉvorton
+montriĝos en la rezulto).',
+'powersearch' => 'Trovu',
+'powersearchtext' => '
+Serĉu en sekcioj: :<br />
+$1<br />
+$2 Kun alidirektiloj Serĉu $3 $9',
+'searchdisabled' => '<p>Oni provizore malŝaltis serĉadon per la plenteksta
+indekso pro troŝarĝita servilo. Intertempe, vi povas serĉi per <i>guglo</i> aŭ per <i>jahu!</i>:</p>',
+'blanknamespace' => '(Artikoloj)',
+'preferences' => 'Preferoj',
+'prefsnologin' => 'Ne jam salutis!',
+'prefsnologintext' => '[[Special:Userlogin|Ensalutu]] kaj vi povos ŝanĝi viajn preferojn.',
+'prefsreset' => 'Preferoj reprenitaj el la registro.',
+'qbsettings' => 'Preferoj pri ilaro',
+'changepassword' => 'Ŝanĝu pasvorton',
+'skin' => 'Aspekto',
+'math' => 'Tradukas matematikaĵon',
+'dateformat' => 'Datformato',
+'datedefault' => 'Nenia prefero',
+'datetime' => 'Dato kaj horo',
+'math_failure' => 'Malsukcesis analizi formulon',
+'math_unknown_error' => 'Nekonata eraro',
+'math_unknown_function' => 'Nekonata funkcio',
+'math_lexing_error' => 'Leksika analizo malsukcesis',
+'math_syntax_error' => 'Sintakseraro',
+'math_image_error' => 'Konverto al PNG malsukcesis',
+'prefs-personal' => 'Uzulaj datumoj',
+'prefs-rc' => 'Lastaj ŝanĝoj kaj elmontro de stumpoj',
+'prefs-misc' => 'Miksitaĵoj',
+'saveprefs' => 'Konservu preferojn',
+'resetprefs' => 'Restarigi antaŭajn preferojn',
+'oldpassword' => 'Malnova pasvorto',
+'newpassword' => 'Nova pasvorto',
+'retypenew' => 'Retajpu novan pasvorton',
+'textboxsize' => 'Grandeco de redakta tekstujo',
+'rows' => 'Linioj',
+'columns' => 'Kolumnoj',
+'searchresultshead' => 'Agordaĵoj pri serĉorezulto',
+'resultsperpage' => 'Montru trovitajn po',
+'contextlines' => 'Montru liniojn el paĝoj po',
+'contextchars' => 'Montru literojn el linioj ĝis po',
+'stubthreshold' => 'Indiku paĝojn malpli grandajn ol',
+'recentchangescount' => 'Montru kiom da titoloj en \'Lastaj ŝanĝoj\'',
+'savedprefs' => 'Viaj preferoj estas konservitaj.',
+'timezonelegend' => 'Horzono',
+'timezonetext' => 'Indiku je kiom da horoj via
+loka horzono malsamas disde tiu de la servilo (UTC).
+Ekzemple, por la Centra Eŭropa Horzono, indiku "1" vintre aŭ "2" dum somertempo.',
+'localtime' => 'Loka horzono',
+'timezoneoffset' => 'Malsamo',
+'servertime' => 'Loka horzono (UTC)',
+'guesstimezone' => 'Plenigita el la foliumilo',
+'allowemail' => 'Ricevu retmesaĝojn de aliaj uzantoj.',
+'defaultns' => 'Serĉu la jenajn sekciojn:',
+'default' => 'defaŭlte',
+'files' => 'Dosieroj',
+'userrights-lookup-user'=> 'Administru uzantogrupojn',
+'userrights-user-editname'=> 'Entajpu uzantonomon:',
+'editusergroup' => 'Redaktu Uzantgrupojn',
+'userrights-editusergroup'=> 'Redaktu uzantogrupojn.',
+'saveusergroups' => 'Konservu uzulan grupon',
+'userrights-groupsmember'=> 'Membro de:',
+'userrights-groupsavailable'=> 'Disponeblaj grupoj:',
+'userrights-groupshelp' => 'Selektu grupojn el kiuj vi volas forigi aŭ al kiuj vi volas aldoni uzanton. Neselektitaj grupoj ne estos ŝanĝitaj. Vi povas malselekti grupon per STR.',
+'group' => 'Grupo:',
+'group-sysop' => 'Sisopoj',
+'group-bureaucrat' => 'Burokratoj',
+'group-all' => '(ĉiuj)',
+'group-sysop-member' => 'Sisopo',
+'group-bureaucrat-member'=> 'Burokrato',
+'grouppage-bureaucrat' => 'Project:Burokratoj',
+'changes' => 'ŝanĝoj',
+'recentchanges' => 'Lastaj ŝanĝoj',
+'recentchangestext' => '\'\'\'[[{{ns:project}}:Bonvenon al la {{SITENAME}}|Bonvenon al la {{SITENAME}}]]!\'\'\' Sekvu la plej lastajn ŝanĝojn en la {{SITENAME}} per ĉi tiu paĝo.
+Utile povas esti legi ĉi tiujn paĝojn: [[{{ns:project}}:Oftaj demandoj|Oftaj demandoj]], ****',
+'rcnote' => 'Jen la plej lastaj <strong>$1</strong> ŝanĝoj dum la lastaj <strong>$2</strong> tagoj gxis la <strong>$3</strong>.',
+'rcnotefrom' => 'Jen la ŝanĝoj ekde <b>$2</b> (lastaj ĝis <b>$1</b>).',
+'rclistfrom' => 'Montru novajn ŝanĝojn ekde $1',
+'rcshowhideminor' => '$1 redaktetojn',
+'rcshowhidebots' => '$1 robotojn',
+'rcshowhideliu' => '$1 ensalutantojn',
+'rcshowhideanons' => '$1 anonimajn redaktojn',
+'rcshowhidepatr' => '$1 patrolitajn redaktojn',
+'rcshowhidemine' => '$1 miajn redaktojn',
+'rclinks' => 'Montru $1 lastajn ŝanĝojn; montru la ŝanĝojn dum la $2 lastaj tagoj.<br />$3',
+'diff' => 'malsamoj',
+'hist' => 'historio',
+'hide' => 'kaŝu',
+'show' => 'montru',
+'minoreditletter' => 'M',
+'upload' => 'Alŝutu dosieron',
+'uploadbtn' => 'Alŝutu dosieron',
+'reupload' => 'Realŝutu',
+'reuploaddesc' => 'Revenu al la alŝuta formularo.',
+'uploadnologin' => 'Ne ensalutinta',
+'uploadnologintext' => 'Se vi volas alŝuti dosierojn, vi devas [[Special:Userlogin|ensaluti]].',
+'upload_directory_read_only'=> 'La TTT-servilo ne povas alskribi la alŝuto-dosierujon ($1).',
+'uploaderror' => 'Eraro okazis dum alŝuto',
+'uploadtext' => '<p>Por okulumi aŭ serĉi jam alŝutitajn dosierojn, aliru la [[Special:Imagelist|liston de alŝutaĵoj]]. Ĉiuj alŝutoj kaj forigoj estas registrataj en la [[Special:Log/upload|alŝuta loglibro]].</p>
+
+<p>Uzu ĉi tiun formularon por alŝuti novajn bildojn kaj aliajn dosierojn por ilustrado de viaj artikoloj. Ĉe kutimaj retumiloj, vi vidos ĉi-sube butonon "Foliumi..." aŭ simile; tiu malfermas la dosierelektilon de via operaciumo. Kiam vi elektos dosieron, ĝia nomo plenigos la tekstujon apud la butono. Vi ankaŭ nepre devas klakjesi la skatolon por aserti, ke vi ne malobeas la leĝan kopirajton de aliuloj per alŝuto de la dosiero. Por plenumi la alŝutadon, alklaku la butono "Alŝutu". Tio ĉi eble iomete longe daŭros, se estas granda dosiero kaj se via interreta konekto malrapidas.</p>
+
+<p>La dosiertipoj preferataj ĉe {{SITENAME}} estas JPEG por fotografaĵoj, PNG por grafikaĵoj, diagramoj, ktp; kaj OGG por sonregistraĵoj. Bonvolu doni al via dosiero nomon informan, por eviti konfuzon. Por enmeti la dosieron en artikolon, skribu ligilon laŭ la formoj</p>
+
+* <nowiki>[[Image:Dosiero.jpg]]</nowiki>
+* <nowiki>[[Image:Bildo.png|teksto por retumiloj negrafikaj]]</nowiki>
+aŭ por sono
+* <nowiki>[[Media:Dosiero.ogg]]</nowiki>
+
+<p>Bonvolu rimarki, ke same kiel artikoloj en la {{SITENAME}}, aliaj uzantoj rajtas redakti, anstataŭigi, aŭ forigi viajn alŝutaĵojn se ili pensas, ke tio servus la vikion. Se vi aĉe misuzas la sistemon, eblas ke vi estos forbarita.</p>',
+'uploadlog' => 'loglibro de alŝutaĵoj',
+'uploadlogpage' => 'Loglibro_de_alŝutaĵoj',
+'uploadlogpagetext' => 'Jen la plej laste alŝutitaj dosieroj.
+Ĉiuj tempoj montriĝas laŭ la horzono UTC.
+<ul>
+</ul>',
+'filename' => 'Dosiernomo',
+'filedesc' => 'Priskribo',
+'fileuploadsummary' => 'Resumo:',
+'filestatus' => 'Kopirajta statuso',
+'filesource' => 'Fonto',
+'copyrightpage' => 'Project:Kopirajto',
+'copyrightpagename' => 'permesilo **** GFDL **** uzata por la {{SITENAME}}',
+'uploadedfiles' => 'Alŝutitaj dosieroj',
+'ignorewarning' => 'Ignoru averton kaj konservu dosieron ĉiukaze',
+'ignorewarnings' => 'Ignoru ĉiajn avertojn',
+'minlength' => 'Dosiernomo devas havi pli ol du literojn.',
+'illegalfilename' => 'La dosiernomo $1 entenas karaktrojn kiuj ne estas permesitaj en paĝaj titoloj. Bonvolu renomi la dosieron kaj provu denove alŝuti ĝin.',
+'badfilename' => 'Dosiernomo estis ŝanĝita al "$1".',
+'badfiletype' => '".$1" estas neakceptata dosiertipo.',
+'largefile' => 'Oni rekomendas, ke dosieroj ne superu grandon de $1 bitokoj; tiu ĉi enhavas $2 bitokojn.',
+'largefileserver' => 'Ĉi tiu dosiero estas pli granda ol permesas la servilaj preferoj.',
+'emptyfile' => 'La dosiero kiun vi alŝutis ŝajnas malplena. Tio povas esti kaŭzita sde tajperaro en la titolo. Bonvolu kontroli ĉu vi vere volas alŝuti tiun dosieron.',
+'fileexists' => 'Dosiero kun tia ĉi nomo jam ekzistas. Bonvolu kontroli $1 krom se vi certas ke vi konscie volas ŝanĝi ĝuste tiun.',
+'fileexists-forbidden' => 'Dosiero kun tia ĉi nomo jam ekzistas; bonvole realŝutu ĉi tiun dosieron per nova nomo. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Dosiero kun tia ĉi nomo jam ekzistas en la komuna dosiero-deponejo; bonvole realŝutu ĉi tiun dosieron per nova nomo. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Alŝuto sukcesis!',
+'fileuploaded' => 'Vi sukcese alŝutis dosieron "$1".
+Bonvolu sekvi la jenan ligilo: ($2) al la priskrib-paĝo kaj
+verki iom da informo pri la dosiero. Ekzemple, de kie ĝi devenas;
+kiam ĝi estis kreita, kaj kiu kreis ĝin; kaj ion ajn, kion vi scias pri ĝi.',
+'uploadwarning' => 'Averto',
+'savefile' => 'Konservu dosieron',
+'uploadedimage' => 'alŝutis "[[$1]]"',
+'uploaddisabled' => 'Ni petas pardonon, sed oni malebligis alŝutadon.',
+'uploaddisabledtext' => 'Alŝutado de dosieroj estas malfunkciigita je tiu ĉi vikio.',
+'uploadscripted' => 'HTML-aĵo aŭ skriptokodaĵo troviĝas en tiu ĉi dosiero, kiun TTT-foliumilo eble interpretus erare.',
+'uploadcorrupt' => 'La dosiero estas difektita aŭ havas malĝustan finaĵon. Bonvolu kontroli la dosieron kaj refoje alŝuti ĝin.',
+'uploadvirus' => 'Viruso troviĝas en la dosiero! Detaloj: $1',
+'sourcefilename' => 'Fonta dosiernomo',
+'destfilename' => 'Celdosiernomo',
+'imagelist' => 'Listo de alŝutitaj dosieroj',
+'imagelisttext' => 'Jen listo de $1 alŝutaĵoj, ordigitaj laŭ $2.',
+'getimagelist' => 'akiras dosierliston',
+'ilsubmit' => 'Trovu!',
+'showlast' => 'Montru la $1 lastajn bildojn laŭ $2.',
+'byname' => 'nomo',
+'bydate' => 'dato',
+'bysize' => 'grandeco',
+'imgdelete' => 'forigu',
+'imgdesc' => 'pri',
+'imglegend' => '(pri) = montru/redaktu priskribon de dosiero.',
+'imghistory' => 'Historio de alŝutoj',
+'revertimg' => 'res',
+'deleteimg' => 'for',
+'deleteimgcompletely' => 'for',
+'imghistlegend' => '(nun) = ĉi tiu estas la nuna versio de la dosiero, (for) = forigu
+ĉi tiun malnovan version, (res) = restarigu ĉi tiun malnovan version.
+<br /><i>Por vidi la dosieron laŭdate, alklaku la daton</i>.',
+'imagelinks' => 'Ligiloj al la dosiero',
+'linkstoimage' => 'La jenaj paĝoj ligas al ĉi tiu dosiero:',
+'nolinkstoimage' => 'Neniu paĝo ligas al ĉi tiu dosiero.',
+'sharedupload' => 'This file is a shared upload and may be used by other projects.',
+'noimage' => 'Ne ekzistas dosiero kun tia nomo vi povas [$1 alŝuti ĝin].',
+'noimage-linktext' => 'alŝutu ĝin',
+'uploadnewversion-linktext'=> 'Alŝutu novan version de ĉi tiu dosiero',
+'mimesearch' => 'MIME-serĉilo',
+'download' => 'elŝutu',
+'unwatchedpages' => 'Neatentataj paĝoj',
+'listredirects' => 'Listo de redirektiloj',
+'unusedtemplates' => 'Neuzitaj ŝablonoj',
+'unusedtemplatestext' => 'Ĉi paĝo listigas ĉiujn paĝojn en la nomspaco "Ŝablono" kiuj ne estas enmetitaj en alia paĝo. Bonvolu kontroli aliajn ligilojn al la ŝablonoj antaŭ ol forigi ilin.',
+'unusedtemplateswlh' => 'aliaj ligiloj',
+'randomredirect' => 'Hazarda alidirekto',
+'statistics' => 'Statistiko',
+'sitestats' => 'Pri la retejo',
+'userstats' => 'Pri la uzantaro',
+'sitestatstext' => 'Troviĝas en nia datumaro sume \'\'\'$1\'\'\' paĝoj.
+Tiu nombro enhavas "diskutpaĝojn", paĝojn pri {{SITENAME}}, "artikoletetojn", alidirektilojn, kaj aliajn, kiuj eble ne vere estas artikoloj. Malatentante ilin, oni povas nombri \'\'\'$2\'\'\' probablajn ĝustajn artikolojn.
+
+\'\'\'$8\'\'\' dosieroj estis alŝutitaj.
+
+Oni vidis sume \'\'\'$3\'\'\' paĝojn, kaj redaktis sume \'\'\'$4\'\'\' plural paĝojn
+ekde la starigo de la vikio.
+Tio estas meznombre po unu paĝo por \'\'\'$5\'\'\' paĝoj viditaj, kaj por \'\'\'$6\'\'\' redaktoj.
+
+La nuna longeco de la [http://meta.wikimedia.org/wiki/Help:Job_queue laborenda vico] estas \'\'\'$7\'\'\'.',
+'userstatstext' => 'Enskribiĝis \'\'\'$1\'\'\' uzantoj. El tiuj, \'\'\'$2\'\'\' (aŭ \'\'\'$4%\'\'\') estas administrantoj (vidu $3).',
+'disambiguations' => 'Misligitaj apartigiloj',
+'disambiguationspage' => 'Template:Apartigilo',
+'disambiguationstext' => 'La jenaj paĝoj alligas <i>paĝon-apartigilon</i>. Ili devus anstataŭe alligi la ĝustan temon.<br />Oni konsideras tiujn paĝojn, kiujn alligas $1 apartigiloj.<br />Ligado el ne-artikolaj sekcioj <i>ne</i> listiĝas ĉi tie.',
+'doubleredirects' => 'Duoblaj alidirektadoj',
+'doubleredirectstext' => '<b>Atentu:</b> Eblas, ke la jena listo enhavas falsajn rezultojn. Ĝenerale, tio signifas, ke estas plua teksto kun ligiloj post la #REDIRECT.<br />
+Ĉiu linio montras ligilojn ĉe la unua kaj dua alidirektadoj, kaj la unua linio de la teksto de la dua alidirektado, kiu ĝenerale montras la "veran" artikolon, kiu devus celi la unuan alidirektadon.',
+'brokenredirects' => 'Rompitaj alidirektadoj',
+'brokenredirectstext' => 'La jenaj alidirektadoj ligas al neekzistantaj artikoloj.',
+'nbytes' => '$1 {{PLURAL:$1|bitoko|bitokoj}}',
+'ncategories' => '$1 categories',
+'nlinks' => '$1 {{PLURAL:$1|ligilo|ligiloj}}',
+'nrevisions' => '$1 {{PLURAL:$1|revizio|revizioj}}',
+'nviews' => '$1-foje',
+'lonelypages' => 'Neligitaj paĝoj',
+'uncategorizedpages' => 'Neenkategoriitaj paĝoj',
+'uncategorizedcategories'=> 'Neenkategoriitaj kategorioj',
+'unusedcategories' => 'Neuzitaj kategorioj',
+'unusedimages' => 'Neuzataj bildoj',
+'popularpages' => 'Plej vizitataj paĝoj',
+'wantedcategories' => 'Dezirataj kategorioj',
+'wantedpages' => 'Dezirataj paĝoj',
+'mostlinked' => 'Plej ligitaj paĝoj',
+'mostlinkedcategories' => 'Plej ligitaj kategorioj',
+'mostcategories' => 'Artikoloj kun la plej multaj kategorioj',
+'mostimages' => 'Plej ligitaj bildoj',
+'mostrevisions' => 'Artikoloj kun la plej multaj revizioj',
+'allpages' => 'Ĉiuj paĝoj',
+'prefixindex' => 'Indeksa prefikso',
+'randompage' => 'Hazarda paĝo',
+'shortpages' => 'Paĝetoj',
+'longpages' => 'Paĝegoj',
+'deadendpages' => 'Seneliraj paĝoj',
+'listusers' => 'Uzantaro',
+'specialpages' => 'Specialaj paĝoj',
+'spheading' => 'Specialaj paĝoj',
+'restrictedpheading' => 'Alirlimigitaj specialaj paĝoj',
+'recentchangeslinked' => 'Rilataj paĝoj',
+'rclsub' => '(al paĝoj ligitaj de "$1")',
+'newpages' => 'Novaj paĝoj',
+'ancientpages' => 'Plej malnovaj artikoloj',
+'intl' => 'Interlingvaj ligiloj',
+'move' => 'Movu',
+'movethispage' => 'Movu la paĝon',
+'unusedimagestext' => 'Notu, ke aliaj TTT-ejoj, ekzemple
+la alilingvaj {{SITENAME}}j, povas rekte ligi al dosiero per URL.
+Tio ne estus enkalkutita en la jena listo.',
+'unusedcategoriestext' => 'La paĝoj de la sekvanta kategorio jam ekzistas, sed neniu alia artikolo aŭ kategorio rilatas al ĝi.',
+'booksources' => 'Libroservoj',
+'categoriespagetext' => 'La sekvantaj kategorioj ekzistas jam en la vikio.',
+'userrights' => 'Prizorgo de uzulaj rajtoj',
+'groups' => 'Uzulaj grupoj',
+'booksourcetext' => 'Jen ligilaro al aliaj TTT-ejoj, kiuj vendas librojn,
+kaj/aŭ informumos pri la libro ligita.
+La {{SITENAME}} ne estas komerce ligita al tiuj vendejoj, kaj la listo ne estu
+komprenata kiel rekomendo aŭ reklamo.',
+'alphaindexline' => '$1 ĝis $2',
+'version' => 'Versio',
+'log' => 'Loglibroj',
+'alllogstext' => 'Suma kompilaĵo de ĉiuj alŝutoj, forigoj, protektoj, blokadoj kaj agoj de administrantoj. Vi povas pliprecizigi la kompilaĵon laŭ loglibra tipo, **** vikipediista **** nomo aŭ koncernita paĝo.',
+'nextpage' => 'Sekvanta paĝo ($1)',
+'allpagesfrom' => 'Montru paĝojn ekde :',
+'allarticles' => 'Ĉiuj artikoloj',
+'allinnamespace' => 'Ĉiuj paĝoj ($1 nomspaco)',
+'allnotinnamespace' => 'Ĉiuj paĝoj (ne en nomspaco $1)',
+'allpagesprev' => 'Antaŭen',
+'allpagesnext' => 'Sekven',
+'allpagessubmit' => 'Ek!',
+'allpagesprefix' => 'Montru paĝojn kun prefikso:',
+'mailnologin' => 'Neniu alsendota adreso',
+'mailnologintext' => 'Vi nepre estu [[Special:Userlogin|salutanta]] kaj havanta validan retpoŝtadreson en viaj [[Special:Preferences|preferoj]] por retpoŝti al aliaj uzantoj.',
+'emailuser' => 'Retpoŝtu',
+'emailpage' => 'Retpoŝtu',
+'emailpagetext' => 'Se la alsendota uzanto donis validan retpoŝtadreson en la preferoj, vi povas sendi unu mesaĝon per la jena formulo. La retpoŝtadreso, kiun vi metis en la preferoj, aperos kiel "El"-adreso de la poŝto, por ke la alsendonto povos respondi.',
+'usermailererror' => 'Resendita retmesaĝa erarsubjekto :',
+'defemailsubject' => '{{SITENAME}} ****-retmesaĝo',
+'noemailtitle' => 'Neniu retpoŝtadreso',
+'noemailtext' => 'Ĉi tiu uzanto aŭ ne donis validan retpoŝtadreson aŭ elektis ne ricevi retpoŝton de aliaj uzantoj.',
+'emailfrom' => 'El',
+'emailto' => 'Al',
+'emailsubject' => 'Subjekto',
+'emailmessage' => 'Mesaĝo',
+'emailsend' => 'Sendu',
+'emailsent' => 'Retmesaĝo sendita',
+'emailsenttext' => 'Via retmesaĝo estas sendita.',
+'watchlist' => 'Atentaro',
+'nowatchlist' => 'Vi ne jam elektis priatenti iun ajn paĝon.',
+'watchlistcount' => '\'\'\'Vi atentas $1 aĵojn en via atentaro, inkluzive de diskutpaĝoj.\'\'\'',
+'clearwatchlist' => 'Malplenigu atentaron',
+'watchlistcleartext' => 'Ĉu vi certas, ke vi volas forigi ilin?',
+'watchlistclearbutton' => 'Malplenigi atentaron',
+'watchlistcleardone' => 'Via atentaro estis malplenigita. $1 eroj estis forigitaj.',
+'watchnologin' => 'Ne ensalutinta',
+'watchnologintext' => 'Nepras [[Special:Userlogin|ensaluti]] por ŝanĝi vian atentaron.',
+'addedwatch' => 'Aldonis al atentaro',
+'addedwatchtext' => 'La paĝo "[[:$1]]" estis aldonita al via [[Special:Watchlist|atentaro]]. Estontaj ŝanĝoj de tiu ĉi paĝo aperos en \'\'\'grasa tiparo\'\'\' en la [[Special:Recentchanges|listo de Lastaj Ŝanĝoj]], kaj estos listigitaj en via atentaro. Se vi poste volos forigi la paĝon el via atentaro, alklaku "Malatentu paĝon" en la ilobreto.',
+'removedwatch' => 'Forigis el atentaro',
+'removedwatchtext' => 'La paĝo "[[:$1]]" estas forigita el via atentaro.',
+'watch' => 'Atentu',
+'watchthispage' => 'Priatentu paĝon',
+'unwatch' => 'Malatentu',
+'unwatchthispage' => 'Malatentu paĝon',
+'notanarticle' => 'Ne estas artikolo',
+'watchnochange' => 'Neniu artikolo en via atentaro redaktiĝis dum la prispektita tempoperiodo.',
+'watchdetails' => '(Vi priatentas $1 paĝojn [krom diskutopaĝoj];
+laste $2 paĝoj entute redaktiĝis en la vikio; $3...
+[$4 redaktu vian atentaron].)',
+'wlheader-enotif' => '* Retpoŝta sciigo estas ebligita',
+'wlheader-showupdated' => '* Montriĝas per \'\'\'dikaj literoj\'\'\' tiuj paĝoj, kiujn oni ŝanĝis ekde kiam vi laste vizitis ilin',
+'watchmethod-recent' => 'traserĉas lastajn redaktojn',
+'watchmethod-list' => 'traserĉas priatentitajn',
+'removechecked' => 'Forprenu elektitajn el la listo',
+'watchlistcontains' => 'Via atentaro enhavas $1 paĝojn.',
+'watcheditlist' => 'Jen listo de ĉiu paĝtitolo en via atentaro.
+Elektu forigotajn paĝojn kaj alklaku "forprenu elektitajn" sube.',
+'removingchecked' => 'Forprenas elektitajn...',
+'couldntremove' => 'Neeblas forigi titolon "$1"...',
+'iteminvalidname' => 'Ia eraro pri "$1", nevalida titolo...',
+'wlnote' => 'Jen la plej lastaj $1 redaktoj dum la lastaj <b>$2</b> horoj.',
+'wlshowlast' => 'Montru el lastaj $1 horoj $2 tagoj $3',
+'wlsaved' => 'Jen konservita versio de via atentaro.',
+'wlhideshowown' => '$1 miajn redaktojn.',
+'wlhideshowbots' => '$1 robotajn redaktojn',
+'wldone' => 'Farita.',
+'enotif_mailer' => 'Averta retmesaĝo de {{SITENAME}}',
+'enotif_reset' => 'Marku ĉiujn vizititajn paĝojn',
+'enotif_newpagetext' => 'Tiu ĉi estas nova paĝo',
+'changed' => 'ŝanĝita',
+'enotif_subject' => 'la paĝo $PAGETITLE de {{SITENAME}} estis $CHANGEDORCREATED de $PAGEEDITOR',
+'enotif_lastvisited' => 'Vidu $1 por ĉiuj ŝanĝoj de post via lasta vizito.',
+'enotif_body' => 'Kara $WATCHINGUSERNAME,
+
+la paĝo $PAGETITLE de {{SITENAME}} estis $CHANGEDORCREATED je $PAGEEDITDATE de $PAGEEDITOR, vidu {{fullurl:$PAGETITLE RAWURL}} por la nuna versio.
+
+$NEWPAGE
+
+Redakta resumo : $PAGESUMMARY $PAGEMINOREDIT
+
+Kontaktu la redaktinton:
+retpoŝto {{fullurl:Special:Emailuser/$PAGEEDITOR RAWURL}}
+vikio {{fullurl:User:$PAGEEDITOR RAWURL}}
+
+Ne estos aliaj avertoj kaze de sekvaj ŝanĝoj krom se vi vizitas la paĝon. Vi povas ankaŭ malaktivigi la avertsignalon por ĉiuj priatentitaj paĝoj de via atentaro.
+
+ Sincere via, la avertsistemo de {{SITENAME}}
+
+--
+Por ŝanĝi la elektojn de via atentaro, bv viziti
+{{fullurl:Special:Watchlist/edit}}
+
+Reagoj kaj plia helpo :
+{{fullurl:Help:Enhavo}}',
+'deletepage' => 'Forigu paĝon',
+'confirm' => 'Konfirmu',
+'excontent' => 'enhavis: \'$1\'',
+'excontentauthor' => 'la enteno estis : \'$1\' (kaj la sola kontribuinto estis \'$2\')',
+'exbeforeblank' => 'antaŭ malplenigo enhavis: \'$1\'',
+'exblank' => 'estis malplena',
+'confirmdelete' => 'Konfirmu forigadon',
+'deletesub' => '(Forigas "$1")',
+'historywarning' => 'Averto: la forigota paĝo havas historion:',
+'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 [[Project:Reguloj pri forigado|regulojn pri forigado]].',
+'actioncomplete' => 'Ago farita',
+'deletedtext' => '"$1" estas forigita.
+Vidu la paĝon $2 por registro de lastatempaj forigoj.',
+'deletedarticle' => 'forigis "$1"',
+'dellogpage' => 'Loglibro de forigoj',
+'dellogpagetext' => 'Jen listo de la plej lastaj forigoj el la datumaro.
+Ĉiuj tempoj sekvas la horzonon UTC.
+<ul>
+</ul>',
+'deletionlog' => 'listo de forigoj',
+'reverted' => 'Restarigis antaŭan version',
+'deletecomment' => 'Kialo por forigo',
+'imagereverted' => 'Restarigo de antaŭa versio sukcesis.',
+'rollback' => 'Restarigu antaŭan redakton',
+'rollback_short' => 'Restarigo',
+'rollbacklink' => 'restarigu antaŭan',
+'rollbackfailed' => 'Restarigo malsukcesis',
+'cantrollback' => 'Neeblas restarigi antaŭan redakton; la redaktinto lasta estas la sola de la paĝo.',
+'alreadyrolled' => 'Ne eblas restarigi la lastan redakton de [[:$1]] de la [[User:$2|$2]] ([[User talk:$2|diskuto]]) pro tio, ke oni intertempe redaktis la paĝon. La lasta redaktinto estas [[User:$3|$3]] ([[User talk:$3|diskuto]]).',
+'editcomment' => 'La komento estis: \'<i>$1</i>\'.',
+'revertpage' => 'Restarigis redaktojn de [[Special:Contributions/$2|$2]] ([[User talk:$2|diskuto]]); restarigis al la lasta versio de [[User:$1|$1]]',
+'sessionfailure' => 'Ŝajnas ke estas problemo kun via ensalutado;
+Ĉi ago estis nuligita por malhelpi fiensalutadon.
+Bonvolu alklalki la reirbutonon kaj reŝarĝi la paĝon el kiu vi venas, kaj provu denove.',
+'protectlogpage' => 'Protektloglibro',
+'protectlogtext' => 'Sube estas listo de paĝ-ŝlosoj kaj malŝlosoj.
+Vidu [[Project:Ŝlositaj paĝoj]] por pli da informoj.',
+'protectedarticle' => 'protektita [[:$1]]',
+'unprotectedarticle' => 'malprotektita [[$1]]',
+'protectsub' => '(Protektante "$1")',
+'confirmprotecttext' => 'Ĉu vi vere volas protekti ĉi paĝon ?',
+'confirmprotect' => 'Konfirmu protektadon',
+'protectmoveonly' => 'Protektu nur kontraŭ movoj',
+'protectcomment' => 'Kialo por protekti',
+'unprotectsub' => '(Malprotektanta "$1")',
+'confirmunprotecttext' => 'Ĉu vi vere volas malprotekti ĉi paĝon ?',
+'confirmunprotect' => 'Konfirmu malprotektadon',
+'unprotectcomment' => 'Kialo de malprotekto',
+'protect-unchain' => 'Malŝlosu movpermesojn',
+'protect-text' => 'Vi povas ĉi tie vidi kaj ŝanĝi la protektnivelon de la paĝo [[$1]]. Bonvolu certiĝi ke vi respektas la [[Project:Protektitaj paĝoj|gvidliniojn de la projekto]].',
+'protect-viewtext' => 'Via konto ne havas rajtojn por ŝanĝi la protektnivelon de la paĝo. Jen la nunaj ecoj <!-- settings --> por la paĝo [[$1]]',
+'protect-default' => '(defaŭlte)',
+'protect-level-autoconfirmed'=> 'Bloki neensalutintajn uzantojn',
+'protect-level-sysop' => 'Nur administrantoj',
+'undelete' => 'Restarigu forigitan paĝon',
+'undeletepage' => 'Montru kaj restarigu forigitajn paĝojn',
+'viewdeletedpage' => 'Rigardu forigitajn paĝojn',
+'undeletepagetext' => 'La jenaj paĝoj estis forigitaj, sed ankoraŭ restas arkivitaj,
+kaj oni povas restarigi ilin. La arkivo povas esti malplenigita periode.',
+'undeleteextrahelp' => 'Por restarigi la tuton de la paĝo, marku neniun markobutonon kaj klaku la butonon \'\'\'\'\'Restarigu\'\'\'\'\'. Por restarigi selektitajn versiojn de la paĝo, marku la butonojn konformajn al la dezirataj versioj, kaj klaku la butonon \'\'\'\'\'Restarigu\'\'\'\'\'. Klako je \'\'\'\'\'Restarigu\'\'\'\'\' malplenigos la komentozonon kaj malmarkos ĉiujn la markobutonojn.',
+'undeletearticle' => 'Restarigu forigitan artikolon',
+'undeleterevisions' => '$1 versioj arkivitaj',
+'undeletehistory' => 'Se vi restarigos la paĝon, ĉiuj versioj estos restarigitaj
+en la historio. Se nova paĝo kun la sama nomo estis kreita post la forigo, la restarigitaj
+versioj aperos antaŭe en la historio, kaj la aktuala versio ne estos anstataŭigita.',
+'undeletehistorynoadmin'=> 'Ĉi tiu artikolo estis forigita. La kaŭzo por la forigo estas montrata en la malsupra resumo, kune kun detaloj pri la uzantoj, kiuj redaktis ĉi tiun paĝon antaŭ la forigo. La aktuala teksto de ĉi tiuj forigitaj revizioj estas atingebla nur por administrantoj.',
+'undeleterevision' => 'Forigita versio de $1',
+'undeletebtn' => 'Restarigu!',
+'undeletereset' => 'Reŝarĝu',
+'undeletecomment' => 'Komento:',
+'undeletedarticle' => 'restarigis "$1"',
+'undeletedrevisions' => '$1 restarigita(j) versio(j)',
+'undeletedrevisions-files'=> '$1 revizioj kaj $2 dosiero(j) restarigitaj',
+'undeletedfiles' => '$1 dosiero(j) restarigita(j)',
+'undeletedpage' => '<big>\'\'\'$1 estis restarigita\'\'\'</big>
+
+Konsultu la [[Special:Log/delete|deletion log]] por protokolo pri la lastatempaj forigoj kaj restarigoj.',
+'namespace' => 'Nomspaco:',
+'invert' => 'Inversu selektaĵon',
+'contributions' => 'Kontribuoj de uzanto',
+'mycontris' => 'Miaj kontribuoj',
+'contribsub' => 'De $1',
+'nocontribs' => 'Trovis neniajn redaktojn laŭ tiu kriterio.',
+'ucnote' => 'Jen la <b>$1</b> lastaj redaktoj de tiu uzanto dum la <b>$2</b> lastaj tagoj.',
+'uclinks' => 'Montru la $1 lastajn redaktojn; montru la $2 lastajn tagojn.',
+'uctop' => ' (lasta)',
+'newbies' => 'novaĵoj',
+'sp-newimages-showfrom' => 'Montru novajn bildojn komencante de $1',
+'sp-contributions-newest'=> 'Plej novaj',
+'sp-contributions-oldest'=> 'Plej malnovaj',
+'sp-contributions-newer'=> '$1 pli novajn',
+'sp-contributions-older'=> '$1 pli malnovajn',
+'sp-contributions-newbies-sub'=> 'Kontribuoj de novaj uzuloj. Forigitaj paĝoj ne estas montritaj.',
+'whatlinkshere' => 'Ligiloj ĉi tien',
+'notargettitle' => 'Sen celpaĝo',
+'notargettext' => 'Vi ne precizigis, kiun paĝon aŭ uzanton priumi.',
+'linklistsub' => '(Listo de ligiloj)',
+'linkshere' => 'La jenaj paĝoj ligas ĉi tien:',
+'nolinkshere' => 'Neniu paĝo ligas ĉi tien.',
+'isredirect' => 'alidirekto',
+'blockip' => 'Forbaru IP-adreson/nomon',
+'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 [[Project:Reguloj pri forbarado|regulojn pri forbarado]]. Klarigu la precizan kialon malsupre (ekzemple, citu paĝojn, kiuj estis vandaligitaj).',
+'ipaddress' => 'IP-adreso/nomo',
+'ipadressorusername' => 'IP adreso aŭ uzula nomo',
+'ipbexpiry' => 'Blokdaŭro',
+'ipbreason' => 'Kialo',
+'ipbsubmit' => 'Forbaru la adreson',
+'ipbother' => 'Alia daŭro',
+'ipboptions' => '2 horoj:2 hours,1 tago:1 day,3 tagoj:3 days,1 semajno:1 week,2 semajnoj:2 weeks,1 monato:1 month,3 monatoj:3 months,6 monatoj:6 months,1 jaro:1 year,porĉiam:infinite',
+'ipbotheroption' => 'alia',
+'badipaddress' => 'Neniu uzanto, aŭ la IP-adreso estas misformita.',
+'blockipsuccesssub' => 'Oni sukcese forbaris la adreson/nomon.',
+'blockipsuccesstext' => '"$1" estas forbarita. <br />Vidu la [[Special:Ipblocklist|liston de IP-forbaroj]].',
+'unblockip' => 'Malforbaru IP-adreson/nomon',
+'unblockiptext' => 'Per la jena formulo vi povas repovigi al iu
+forbarita IP-adreso/nomo la povon enskribi en la vikio.',
+'ipusubmit' => 'Malforbaru la adreson',
+'ipblocklist' => 'Listo de forbaritaj IP-adresoj/nomoj',
+'blocklistline' => 'Je $1, $2 forbaris $3 ($4)',
+'infiniteblock' => 'senfina',
+'expiringblock' => 'finiĝas je $1',
+'ipblocklistempty' => 'La blokada listo estas malplena.',
+'blocklink' => 'forbaru',
+'unblocklink' => 'malforbaru',
+'contribslink' => 'kontribuoj',
+'autoblocker' => 'Provizore forbarita aŭtomate pro tio, ke vi uzas la saman [[IP-adreso]]n kiel "$1", kiu estis forbarita pro : "$2".',
+'blocklogpage' => 'Forbarlibro',
+'blocklogentry' => 'forbaris "$1" por daŭro de "$2"',
+'blocklogtext' => 'Ĉi tio estas loglibro pri uzanto-forbaraj kaj malforbaraj agoj. Aŭtomate forbaritaj IP adresoj ne estas listigitaj. Vidu la [[Special:Ipblocklist|IP forbarliston]] por ĉi-momente fobaritaj uzulantoj kaj IPoj.',
+'unblocklogentry' => '$1 estis malbarita',
+'ipb_expiry_invalid' => 'Nevalida blokdaŭro.',
+'lockdb' => 'Ŝlosi datumaron',
+'unlockdb' => 'Malŝlosi datumaron',
+'lockdbtext' => 'Se vi ŝlosos la datumaron, tio malebligos al ĉiuj uzantoj
+redakti paĝojn, ŝanĝi preferojn, priumi atentarojn, kaj fari diversajn aliajn
+aferojn, por kiuj nepras ŝanĝi la datumaron.
+Bonvolu certigu, ke vi efektive intencas tion fari, kaj ke vi ja malŝlosos
+la datumaron post ol vi finos vian riparadon.',
+'unlockdbtext' => 'Se vi malŝlosos la datumaron, tio reebligos al ĉiuj uzantoj
+redakti paĝojn, ŝanĝi preferojn, priumi la atentaron, kaj fari aliajn aferojn,
+por kiuj nepras ŝanĝi al la datumaro.
+Bonvolu certigu, ke vi efektive intencas tion fari.',
+'lockconfirm' => 'Jes, mi vere volas ŝlosi la datumaron.',
+'unlockconfirm' => 'Jes, mi vere volas malŝlosi la datumaron.',
+'lockbtn' => 'Ŝlosi datumaron',
+'unlockbtn' => 'Malŝlosi datumaron',
+'locknoconfirm' => 'Vi ne konfirmis.',
+'lockdbsuccesssub' => 'Datumaro ŝlosita',
+'unlockdbsuccesssub' => 'Datumaro malŝlosita',
+'lockdbsuccesstext' => 'La datumaro de {{SITENAME}} estas ŝlosita.
+<br />Ne forgesu malŝlosi ĝin post kiam vi finos la riparadon.',
+'unlockdbsuccesstext' => 'La datumaro de {{SITENAME}} estas malŝlosita.',
+'makesysoptitle' => 'Igu uzanton administranto',
+'makesysoptext' => 'Ĉi formularo estas uzita de burokratoj por igi ordinarajn uzantojn administrantoj.
+Bonvlolu tajpi la nomon de la uzanto en la skatoleton kaj premu la butonon por igi la uzanton administranto.',
+'makesysopname' => 'Nomo de la uzanto :',
+'makesysopsubmit' => 'Igu ĉi uzanton administranto',
+'makesysopok' => '<b>Uzanto "$1" nun estas administranto</b>',
+'makesysopfail' => '<b>Uzanto "$1" ne povis esti admnistrantigita. (Ĉu vi ĝuste tajis ties nomon ?)</b>',
+'setbureaucratflag' => 'Aldonu burokratan markilon',
+'rightslogtext' => 'Ĉi tio estas loglibro de uzulaj rajtŝanĝoj.',
+'rightslogentry' => 'ŝanĝis grupan membrecon por $1 de $2 al $3',
+'rights' => 'Rajtoj:',
+'set_user_rights' => 'Ŝanĝu uzulajn rajtojn',
+'user_rights_set' => '<b>Uzulaj rajtoj por "$1" ĝisdatigitaj</b>',
+'set_rights_fail' => '<b>Uzantorajtoj por "$1" ne povis esti difinataj. (Ĉu vi entajpis la nomon korekte?)</b>',
+'makesysop' => 'Igu uzanton administranto',
+'already_sysop' => 'Tiu ĉi uzanto jam estas administranto.',
+'already_bureaucrat' => 'Tiu ĉi uzanto jam estas burokrato',
+'movepage' => 'Movu paĝon',
+'movepagetext' => 'Per la jena formulo vi povas ŝanĝi la nomon de iu paĝo, kunportante
+ĝian historion de redaktoj je la nova nomo.
+La antaŭa titolo fariĝos alidirektilo al la nova titolo.
+Ligiloj al la antaŭa titolo <i>ne</i> estos ŝanĝitaj; uzu
+la riparilojn kaj zorgilojn por certigi,
+ke ne restos duoblaj aŭ fuŝitaj alidirektiloj.
+Kiel movanto, vi respondecas pri ĝustigado de fuŝitaj ligiloj.
+
+Notu, ke la paĝo \'\'\'ne\'\'\' estos movita se jam ekzistas paĝo
+ĉe la nova titolo, krom se ĝi estas malplena aŭ alidirektilo
+al ĉi tiu paĝo, kaj sen antaŭa redaktohistorio. Pro tio, vi ja
+povos removi la paĝon je la antaŭa titolo se vi mistajpus, kaj
+neeblas ke vi neintence forviŝus ekzistantan paĝon per movo.
+
+<b>AVERTO!</b>
+Tio povas esti drasta kaj neatendita ŝanĝo por populara paĝo;
+bonvolu certigi vin, ke vi komprenas ties konsekvencojn antaŭ
+ol vi antaŭeniru.',
+'movepagetalktext' => 'La movo aŭtomate kunportos la diskuto-paĝon, se tia ekzistas, \'\'\'krom se:\'\'\'
+*Vi movas la paĝon tra nomspacoj (ekz de \'\'Nomo\'\' je \'\'User:Nomo\'\'),
+*Ne malplena diskuto-paĝo jam ekzistas je la nova nomo, aŭ
+*Vi malelektas la suban ŝaltilon.
+
+Tiujokaze, vi nepre permane kunigu la diskuto-paĝojn se vi tion deziras.',
+'movearticle' => 'Movu paĝon',
+'movenologin' => 'Ne ensalutinta',
+'movenologintext' => 'Vi nepre estu registrita uzanto kaj [[Special:Userlogin|ensalutu]] por rajti movi paĝojn.',
+'newtitle' => 'Al nova titolo',
+'movepagebtn' => 'Movu paĝon',
+'pagemovedsub' => 'Sukcesis movi',
+'pagemovedtext' => 'Paĝo "[[$1]]" estas movita al "[[$2]]".',
+'articleexists' => 'Paĝo kun tiu nomo jam ekzistas, aŭ la nomo kiun vi elektis ne validas.
+Bonvolu elekti alian nomon.',
+'talkexists' => 'Oni ja sukcesis movi la paĝon mem, sed
+ne movis la diskuto-paĝon ĉar jam ekzistas tia ĉe la nova titolo.
+Bonvolu permane kunigi ilin.',
+'movedto' => 'movita al',
+'movetalk' => 'Movu ankaŭ la "diskuto"-paĝon, se ĝi ekzistas.',
+'talkpagemoved' => 'Ankaŭ la diskutpaĝo estas movita.',
+'talkpagenotmoved' => 'La diskutpaĝo <strong>ne</strong> estas movita.',
+'1movedto2' => '[[:$1|$1]] movita al [[:$2|$2]]',
+'1movedto2_redir' => '[[:$1|$1]] movita al [[:$2|$2]], redirekto lasita',
+'movelogpage' => 'Loglibro de paĝmovoj',
+'movelogpagetext' => 'Jen listo de movitaj paĝoj',
+'movereason' => 'Kialo',
+'revertmove' => 'restarigu',
+'delete_and_move' => 'Forigu kaj movu',
+'delete_and_move_text' => '==Forigo nepras==
+
+La celartikolo "[[$1]]" jam ekzistas. Ĉu vi volas forigi ĝin por krei spacon por la movo?',
+'delete_and_move_confirm'=> 'Jes, forigu la paĝon',
+'delete_and_move_reason'=> 'Forigita por ebligi movon',
+'selfmove' => 'Font- kaj cel-titoloj samas; ne eblas movi paĝon sur ĝin mem.',
+'immobile_namespace' => 'La celtitolo estas de speciala speco; ne eblas movi paĝojn en tiun nomspacon.',
+'export' => 'Eksportu paĝojn',
+'exporttext' => 'Vi povas eksporti la tekston kaj la redaktohistorion de aparta paĝo aŭ de paĝaro kolektita en ia XML ; tio povas esti importita en alian programon funkciantan per MediaWiki-softvaro, ŝanĝita, aŭ nur prenita por propra privata uzo.',
+'exportcuronly' => 'Entenas nur la aktualan version, ne la malnovajn.',
+'allmessages' => 'Ĉiuj mesaĝoj',
+'allmessagesname' => 'Nomo',
+'allmessagesdefault' => 'Defaŭlta teksto',
+'allmessagescurrent' => 'Nuna teksto',
+'allmessagestext' => 'Ĉi tio estas listo de ĉiuj mesaĝoj haveblaj en la MediaWiki: nomspaco',
+'allmessagesnotsupportedUI'=> 'La nuna lingvo de interfaco <b>$1</b> ne estas subtenata en Special:Allmessages de tiu ĉi paĝaro.',
+'allmessagesnotsupportedDB'=> 'Speciala:Allmessages ne subtenata ĉar la variablo wgUseDatabaseMessages estas malkonektita.',
+'allmessagesfilter' => 'Filtrilo laŭ racia esprimo :',
+'allmessagesmodified' => 'Montru nur ŝanĝitajn',
+'thumbnail-more' => 'Pligrandigu',
+'missingimage' => '<b>Mankanta bildo</b><br /><i>$1</i>',
+'filemissing' => 'Mankanta dosiero',
+'thumbnail_error' => 'Okazis eraro kreante antaŭvidan bildeton: $1',
+'import' => 'Importitaj paĝoj',
+'importinterwiki' => 'Transvikia importo',
+'importtext' => 'Bonvole eksportu la dosieron el la fonta vikio per la ilo Speciala:Export, konservu ĝin sur via disko kaj poste alŝutu ĝin tien ĉi.',
+'importfailed' => 'Malsukcesis la importo: $1',
+'importnotext' => 'Malplena aŭ senteksta',
+'importsuccess' => 'La importo sukcesis!',
+'importhistoryconflict' => 'Malkongrua historia versio ekzistas (eble la paĝo importiĝis antaŭe)',
+'importnosources' => 'Neniu transvikia importfonto estis difinita kaj rekta historio de alŝutoj estas malaktivigita.',
+'tooltip-search' => 'Traserĉu ĉi tiun vikion [alt-f]',
+'tooltip-minoredit' => 'Marku tiun ŝanĝon kiel malgrava [alt-i]',
+'tooltip-save' => 'Konservu viajn ŝanĝojn [alt-s]',
+'tooltip-preview' => 'Antaŭrigardu viajn ŝanĝojn. Bonvolu uzi tion antaŭ ol konservi ilin! [alt-p]',
+'tooltip-diff' => 'Show which changes you made to the text. [alt-v]',
+'tooltip-compareselectedversions'=> 'Vidu la malsamojn inter ambaŭ selektitaj versioj de ĉi paĝo. [alt-v]',
+'tooltip-watch' => 'Aldonu ĉi paĝon al via atentaro [alt-w]',
+'monobook.css' => '/* CSS placed here will affect users of the Monobook skin */',
+'anonymous' => 'Anonima(j) uzanto(j) de {{SITENAME}}',
+'siteuser' => '{{SITENAME}} uzanto $1',
+'lastmodifiedatby' => 'Ĉi paĝo estis laste ŝanĝita je $2, $1 de $3.',
+'and' => 'kaj',
+'othercontribs' => 'Bazita sur la laboro de $1.',
+'others' => 'aliaj',
+'siteusers' => '{{SITENAME}} uzanto(j) $1',
+'spamprotectiontitle' => 'Filtrilo kontraŭ spamo',
+'spamprotectiontext' => 'La paĝo kiun vi trovis konservi estis blokita per la spam-filtrilo. Ĉi tia eraro estas kaŭzata pro ekstera ligilo al malpermesata retejo.',
+'spamprotectionmatch' => 'La jena teksto ekagigis la spam-filtrilon: $1',
+'subcategorycount' => 'Estas {{PLURAL:$1|unu subkategorio|$1 subkategorioj}} en tiu kategorio.',
+'categoryarticlecount' => 'Estas {{PLURAL:$1|unu artikolo|$1 artikoloj}} en tiu kategorio.',
+'listingcontinuesabbrev'=> ' daŭrigo',
+'spambot_username' => 'Trudmesaĝa forigo de MediaWiki',
+'spam_reverting' => 'Restarigo de lasta versio ne entenante ligilojn al $1',
+'spam_blanking' => 'Forviŝo de ĉiuj versioj entenate ligilojn al $1',
+'infosubtitle' => 'Informoj por paĝo',
+'mw_math_png' => 'Ĉiam krei PNG-bildon',
+'mw_math_simple' => 'HTMLigu se simple, aŭ PNG',
+'mw_math_html' => 'HTMLigu se eble, aŭ PNG',
+'mw_math_source' => 'Lasu TeX-fonton (por tekstfoliumiloj)',
+'mw_math_modern' => 'Rekomendita por modernaj foliumiloj',
+'mw_math_mathml' => 'MathML seeble (provizora)',
+'markaspatrolleddiff' => 'Marku kiel patrolita',
+'markaspatrolledtext' => 'Marku ĉi artikolon patrolita',
+'markedaspatrolled' => 'Markita kiel patrolita',
+'markedaspatrolledtext' => 'La elektita versio estas markita kiel patrolita.',
+'rcpatroldisabled' => 'Patrolado de lastaj ŝanĝoj malaktivigita',
+'rcpatroldisabledtext' => 'La funkcio patrolado de la lastaj ŝanĝoj estas nun malaktivigita.',
+'monobook.js' => '/* iletikedoj kaj rektaj klavoj */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Mia uzantopaĝo\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'La uzantopaĝo por la IP adreso sub kiu vi estas redaktanta\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Mia diskutpaĝo\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskuto pri redaktoj sub tiu ĉi IP adreso\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Miaj preferoj\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Listo de paĝoj kies ŝanĝojn vi priatentas.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Listo de miaj kontribuoj\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Vi estas invitita ensaluti, tamen ne estas devige.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Vi estas invitita ensaluti, tamen ne estas devige.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Elsalutu\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskuto pri la artikolo\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Vi povas redakti tiun ĉi paĝon. Bv uzi la antaŭvidbutonon antaŭ ol konservi.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Aldonu komenton al tiu diskuto.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Tiu paĝo estas protektita. Vi povas nur rigardi ties fonton.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Antaŭaj versioj de tiu ĉi paĝo.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Protektu tiun ĉi paĝon\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Forigu tiun ĉi paĝon\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Restarigu la redaktojn faritajn al tiu ĉi paĝo antaŭ ties forigo\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Movu tiun ĉi paĝon\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Vi ne rajtas movi tiun ĉi paĝon\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Aldonu tiun ĉi paĝon al via atentaro\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Forigu tiun ĉi paĝon el via atentaro\');
+ ta[\'search\'] = new Array(\'f\',\'Traserĉu tiun ĉi vikion\');
+ ta[\'p-logo\'] = new Array(\'\',\'Ĉefpaĝo\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Vizitu la Ĉefpaĝon\');
+ ta[\'n-portal\'] = new Array(\'\',\'Pri la projekto, kion vi povas fari, kie vi povas trovi ion\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Trovu fonajn informojn pri nunaj eventoj\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Listo de la lastaj ŝanĝoj en la vikio.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Vidu hazardan paĝon\');
+ ta[\'n-help\'] = new Array(\'\',\'Serĉopaĝo.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Subtenu nin per mono\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Listo de ĉiuj vikiaj paĝoj kij ligas ĉi tien\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Lastaj ŝanĝoj en paĝoj kiuj ligas al tiu ĉi paĝo\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS-fonto por tiu ĉi paĝo\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom-fonto por ĉi paĝo\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Vidu la liston de kontribuoj de tiu ĉi uzanto\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Sendu retmesaĝon al tiu ĉi uzanto\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Alŝutu bildojn aŭ dosierojn\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Listo de ĉiuj specialaj paĝoj\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vidu la artikolon\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vidu la personan paĝon de la uzanto\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Vidu la paĝon de la dosiero\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Estas speciala paĝo, vi ne rajtas redakti ĝin.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Vidu la paĝon de la projekto\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Vidu la paĝon de la bildo\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vidu la sisteman mesaĝon\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vidu la ŝablonon\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vidu la helppaĝon\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vidu la paĝon de kategorioj\');',
+'deletedrevision' => 'Forigita malnova versio $1.',
+'previousdiff' => '← Iru al antaŭa ŝanĝo',
+'nextdiff' => 'Iru al sekvanta ŝanĝo →',
+'imagemaxsize' => 'Elmontru bildojn en bildpriskribaj paĝoj je maksimume :',
+'thumbsize' => 'Grandeco de bildetoj :',
+'showbigimage' => 'Elŝutu version altdistingive ($1 X $2, $3 KB)',
+'newimages' => 'Aro da novaj bildoj',
+'noimages' => 'Nenio videbla.',
+'specialloguserlabel' => 'Uzanto:',
+'speciallogtitlelabel' => 'Titolo:',
+'passwordtooshort' => 'Via pasvorto estas tro mallonga. Ĝi entenu minimume $1 karaktrojn.',
+'mediawarning' => '\'\'\'Warning\'\'\': This file may contain malicious code, by executing it your system may be compromised.
+<hr />',
+'metadata-expand' => 'Montru etendajn detalojn',
+'metadata-collapse' => 'Kaŝu etendajn detalojn',
+'exif-artist' => 'Kreinto',
+'exif-pixelxdimension' => 'Valind image height',
+'exif-aperturevalue' => 'Aperturo',
+'exif-brightnessvalue' => 'Heleco',
+'exif-contrast' => 'Kontrasto',
+'exif-componentsconfiguration-0'=> 'ne ekzistas',
+'edit-externally' => 'Ŝanĝu ĉi dosieron per ekstera softvaro',
+'edit-externally-help' => 'Vidu la [http://meta.wikimedia.org/wiki/Help:External_editors instalinstrukciojn] por pliaj informoj \'\'(angle)\'\'.',
+'recentchangesall' => 'ĉiuj',
+'imagelistall' => 'ĉiuj',
+'watchlistall1' => 'ĉiuj',
+'watchlistall2' => 'ĉiuj',
+'namespacesall' => 'ĉiuj',
+'confirmemail' => 'Konfirmu retpoŝtadreson',
+'confirmemail_text' => 'Ĉi tiu vikio postulas ke vi validigu vian retadreson antaŭ ol uzadi la retmesaĝpreferojn. Bonvolu alklaki la suban butonon por sendi konfirmesaĝon al via adreso. La mesaĝo entenos ligilon kun kodo; bonvolu alŝuti la ligilon en vian foliumilon por konfirmi ke via retadreso validas.',
+'confirmemail_send' => 'Retmesaĝi konfirmkodon',
+'confirmemail_sent' => 'Konfirma retmesaĝo estas sendita.',
+'confirmemail_sendfailed'=> 'Ne eblis sendi konfirmretmesaĝon. Bonvolu kontroli ĉu en la adreso ne estus nevalidaj karaktroj.',
+'confirmemail_invalid' => 'Nevalida konfirmkodo. La kodo eble ne plu validas.',
+'confirmemail_needlogin'=> 'Vi devas $1 por konfirmi vian retpoŝtan adreson.',
+'confirmemail_success' => 'Via retadreso estas konfirmita. Vi povas nun ensaluti kaj ĝui la vikion.',
+'confirmemail_loggedin' => 'Via retadreso estas nun konfirmita.',
+'confirmemail_error' => 'Io misokazis dum konservo de via konfirmo.',
+'confirmemail_body' => 'Iu, verŝajne vi ĉe la IP-adreso $1, enregistrigis per tiu
+ĉi retpoŝtadreso la konton "$2" ĉe {{SITENAME}}.
+
+Malfermu tiun ĉi ligon en via retumilo, por konfirmi ke la
+konto ja apartenas al vi kaj por malŝlosi retpoŝtajn
+kapablojn ĉe {{SITENAME}}:
+
+$3
+
+Se vi ne mendis ĉi tiun mesaĝon, ne alklaku la ligon. Tiu
+ĉi konfirmokodo eksvalidiĝos je $4.',
+'tryexact' => 'Provu ekzaktan trafon',
+'searchfulltext' => 'Serĉu plentekste',
+'createarticle' => 'Kreu artikolon',
+'scarytranscludetoolong'=> '[Bedaŭrinde la URL estas tro longa]',
+'trackbackbox' => '<div id=\'mw_trackbacks\'>
+Postspuroj por ĉi artikolo:<br />p
+$1
+</div>',
+'trackbackremove' => ' ([$1 Forigu])',
+'trackbacklink' => 'Postspurado',
+'trackbackdeleteok' => 'La postspurado esti sukcese forigita.',
+'deletedwhileediting' => 'Averto: Oni forigis ĉi tiun paĝon post tiam, kiam vi ekredaktis ĝin!',
+'recreate' => 'Rekreu',
+'redirectingto' => 'Redirektante al [[:$1]]...',
+'confirm_purge' => 'Ĉu forviŝiĝu la enhavo de tiu ĉi paĝo?
+
+$1',
+'confirm_purge_button' => 'Bone',
+'youhavenewmessagesmulti'=> 'Vi havas novajn mesaĝojn ĉe $1',
+'articletitles' => 'Artikoloj komencante de \'\'$1\'\'',
+'hideresults' => 'Kaŝu rezultojn',
+);
+?>
diff --git a/languages/messages/MessagesEs.php b/languages/messages/MessagesEs.php
new file mode 100644
index 000000000000..7b82e001ac3c
--- /dev/null
+++ b/languages/messages/MessagesEs.php
@@ -0,0 +1,1711 @@
+<?php
+/** Spanish (Español)
+ *
+ * @bug 4401
+ * @bug 4424
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Ninguna', 'Fija a la izquierda', 'Fija a la derecha', 'Flotante a la izquierda'
+);
+
+$skinNames = array(
+ 'standard' => 'Estándar',
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Especial',
+ NS_MAIN => '',
+ NS_TALK => 'Discusión',
+ NS_USER => 'Usuario',
+ NS_USER_TALK => 'Usuario_Discusión',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_Discusión',
+ NS_IMAGE => 'Imagen',
+ NS_IMAGE_TALK => 'Imagen_Discusión',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_Discusión',
+ NS_TEMPLATE => 'Plantilla',
+ NS_TEMPLATE_TALK => 'Plantilla_Discusión',
+ NS_HELP => 'Ayuda',
+ NS_HELP_TALK => 'Ayuda_Discusión',
+ NS_CATEGORY => 'Categoría',
+ NS_CATEGORY_TALK => 'Categoría_Discusión',
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'H:i j M Y',
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = '/^([a-záéíóúñ]+)(.*)$/sDu';
+
+
+
+
+$messages = array(
+'tog-underline' => 'Subrayar enlaces',
+'tog-highlightbroken' => 'Destacar enlaces a artículos vacíos <a href="" class="new">como este</a> (alternativa: como éste<a href="" class="internal">?</a>).',
+'tog-justify' => 'Ajustar párrafos',
+'tog-hideminor' => 'Esconder ediciones menores en «cambios recientes»',
+'tog-extendwatchlist' => 'Expandir la lista de seguimiento a todos los cambios aplicables',
+'tog-usenewrc' => 'Cambios recientes realzados (no para todos los navegadores)',
+'tog-numberheadings' => 'Auto-numerar encabezados',
+'tog-showtoolbar' => 'Mostrar barra de edición',
+'tog-editondblclick' => 'Editar páginas con doble clic (JavaScript)',
+'tog-editsection' => 'Habilitar la edición de secciones usando el enlace [editar]',
+'tog-editsectiononrightclick'=> 'Habilitar la edición de secciones presionando el botón de la derecha<br /> en los títulos de secciones (JavaScript)',
+'tog-showtoc' => 'Mostrar la tabla de contenidos (para paginas con más de 3 encabezados)',
+'tog-rememberpassword' => 'Recordar la contraseña entre sesiones',
+'tog-editwidth' => 'La caja de edición tiene el ancho máximo',
+'tog-watchcreations' => 'Vigilar las páginas que yo cree.',
+'tog-watchdefault' => 'Vigilar las páginas que yo modifique',
+'tog-minordefault' => 'Marcar todas las ediciones como menores por defecto',
+'tog-previewontop' => 'Mostrar la previsualización antes de la caja de edición en lugar de después',
+'tog-previewonfirst' => 'Mostrar previsualización al comenzar a editar',
+'tog-nocache' => 'Inhabilitar el \'\'cache\'\' de páginas',
+'tog-enotifwatchlistpages'=> 'Enviame un correo cuando haya cambios de página',
+'tog-enotifusertalkpages'=> 'Notifícame cuando cambia mi página de discusión de usuario',
+'tog-enotifminoredits' => 'Notifícame también los cambios menores de página',
+'tog-enotifrevealaddr' => 'Revela mi dirección electrónica en los correos de notificación',
+'tog-shownumberswatching'=> 'Mostrar el número de usuarios que la vigilan',
+'tog-fancysig' => 'Firma sin enlace automático',
+'tog-externaleditor' => 'Utilizar editor externo por defecto',
+'tog-externaldiff' => 'Utilizar \'\'diff\'\' externo por defecto',
+'tog-showjumplinks' => 'Habilitar enlaces de accesibilidad «saltar a»',
+'tog-autopatrol' => 'Marcar mis ediciones como patrulladas',
+'tog-forceeditsummary' => 'Alertar al grabar sin resumen de edición.',
+'tog-watchlisthideown' => 'No mostrar mis ediciones en la lista de seguimiento',
+'tog-watchlisthidebots' => 'No mostrar ediciones de bots en la lista de seguimiento',
+'underline-always' => 'Siempre',
+'underline-never' => 'Nunca',
+'underline-default' => 'Valor por defecto del navegador',
+'skinpreview' => '(Ver cómo queda)',
+'sunday' => 'Domingo',
+'monday' => 'Lunes',
+'tuesday' => 'Martes',
+'wednesday' => 'Miércoles',
+'thursday' => 'Jueves',
+'friday' => 'Viernes',
+'saturday' => 'Sábado',
+'january' => 'enero',
+'february' => 'febrero',
+'march' => 'marzo',
+'april' => 'abril',
+'may_long' => 'mayo',
+'june' => 'junio',
+'july' => 'julio',
+'august' => 'agosto',
+'september' => 'septiembre',
+'october' => 'octubre',
+'november' => 'noviembre',
+'december' => 'diciembre',
+'jan' => 'ene',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'abr',
+'may' => 'may',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'ago',
+'sep' => 'sep',
+'oct' => 'oct',
+'nov' => 'nov',
+'dec' => 'dic',
+'categories' => 'Categorías',
+'pagecategories' => '{{PLURAL:$1|Categoría|Categorías}}',
+'category_header' => 'Artículos en la categoría "$1"',
+'subcategories' => 'Subcategorías',
+'mainpage' => 'Portada',
+'mainpagetext' => 'Software wiki instalado con éxito.',
+'mainpagedocfooter' => 'Por favor, lee [http://meta.wikimedia.org/wiki/MediaWiki_i18n documentation on customizing the interface] y [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide User\'s Guide] para conocer su configuración y uso.',
+'portal' => 'Portal de la comunidad',
+'portal-url' => 'Project:Portal de la comunidad',
+'about' => 'Acerca de',
+'aboutsite' => 'Acerca de {{SITENAME}}',
+'aboutpage' => 'Project:Acerca de',
+'article' => 'Artículo',
+'help' => 'Ayuda',
+'helppage' => 'Project:Ayuda',
+'bugreports' => 'Informes de error de software',
+'bugreportspage' => 'Project:Informes de error',
+'sitesupport' => 'Donaciones',
+'sitesupport-url' => 'Project:Apoyo al proyecto',
+'faqpage' => 'Project:FAQ',
+'edithelp' => 'Ayuda de edición',
+'newwindow' => '(Se abre en una ventana nueva)',
+'edithelppage' => 'Help:Cómo se edita una página',
+'cancel' => 'Cancelar',
+'qbfind' => 'Encontrar',
+'qbbrowse' => 'Hojear',
+'qbedit' => 'Editar',
+'qbpageoptions' => 'Opciones de página',
+'qbpageinfo' => 'Información de página',
+'qbmyoptions' => 'Mis opciones',
+'qbspecialpages' => 'Páginas especiales',
+'moredotdotdot' => 'Más...',
+'mypage' => 'Mi página',
+'mytalk' => 'Mi discusión',
+'anontalk' => 'Discusión para esta IP',
+'navigation' => 'Navegación',
+'currentevents' => 'Actualidad',
+'currentevents-url' => 'Actualidad',
+'disclaimers' => 'Aviso legal',
+'disclaimerpage' => 'Project:Limitación general de responsabilidad',
+'privacy' => 'Política de protección de datos',
+'privacypage' => 'Project:Política de protección de datos',
+'returnto' => 'Regresa a $1.',
+'tagline' => 'De {{SITENAME}}',
+'search' => 'Buscar',
+'searchbutton' => 'Buscar',
+'go' => 'Ir',
+'searcharticle' => 'Ir',
+'history' => 'Historial',
+'history_short' => 'Historial',
+'updatedmarker' => 'actualizado desde mi última visita',
+'info_short' => 'Información',
+'printableversion' => 'Versión para imprimir',
+'permalink' => 'Enlace permanente',
+'print' => 'Imprimir',
+'edit' => 'Editar',
+'editthispage' => 'Editar esta página',
+'delete' => 'Borrar',
+'deletethispage' => 'Borrar esta página',
+'undelete_short' => 'Restaurar {{PLURAL:$1|una edición|$1 ediciones}}',
+'protect' => 'Proteger',
+'protectthispage' => 'Proteger esta página',
+'unprotect' => 'Desproteger',
+'unprotectthispage' => 'Desproteger esta página',
+'newpage' => 'Página nueva',
+'talkpage' => 'Discutir esta página',
+'specialpage' => 'Página Especial',
+'personaltools' => 'Herramientas personales',
+'postcomment' => 'Poner un comentario',
+'articlepage' => 'Ver artículo',
+'talk' => 'Discusión',
+'views' => 'Vistas',
+'toolbox' => 'Herramientas',
+'userpage' => 'Ver página de usuario',
+'projectpage' => 'Ver página meta',
+'imagepage' => 'Ver página de imagen',
+'viewtalkpage' => 'Ver discusión',
+'otherlanguages' => 'Otros idiomas',
+'redirectedfrom' => '(Redirigido desde $1)',
+'redirectpagesub' => 'Página redirigida',
+'lastmodifiedat' => 'Esta página fue modificada por última vez el $2, $1.',
+'viewcount' => 'Esta página ha sido visitada {{PLURAL:$1|una vez|$1 veces}}.',
+'copyright' => 'El contenido está disponible bajo los términos de la <i>$1</i>',
+'protectedpage' => 'Página protegida',
+'jumpto' => 'Saltar a',
+'jumptonavigation' => 'navegación',
+'jumptosearch' => 'búsqueda',
+'badaccess' => 'Error de permisos',
+'versionrequired' => 'La versión $1 de MediaWiki es necesaria para emplear esta página',
+'versionrequiredtext' => 'Se necesita utilizar la versión $1 de MediaWiki para utilizar esta página. Para más información, consulta [[Special:Version]]',
+'retrievedfrom' => 'Obtenido de "$1"',
+'youhavenewmessages' => 'Tienes $1 ($2).',
+'newmessageslink' => 'mensajes nuevos',
+'newmessagesdifflink' => 'dif. entre las dos últimas versiones',
+'editsection' => 'editar',
+'editold' => 'editar',
+'editsectionhint' => 'Editar sección: $1',
+'toc' => 'Tabla de contenidos',
+'showtoc' => 'mostrar',
+'hidetoc' => 'esconder',
+'thisisdeleted' => '¿Ver o restaurar $1?',
+'viewdeleted' => '¿Deseas ver $1?',
+'restorelink' => '{{PLURAL:$1|una edición borrada|$1 ediciones borradas}}',
+'feedlinks' => 'Sindicación:',
+'nstab-main' => 'Artículo',
+'nstab-user' => 'Usuario',
+'nstab-media' => 'Media',
+'nstab-special' => 'Especial',
+'nstab-project' => 'Página del proyecto',
+'nstab-image' => 'Imagen',
+'nstab-mediawiki' => 'Mensaje',
+'nstab-template' => 'Plantilla',
+'nstab-help' => 'Ayuda',
+'nstab-category' => 'Categoría',
+'nosuchaction' => 'No existe tal acción',
+'nosuchactiontext' => 'La acción especificada por el URL no es
+reconocida por el software de {{SITENAME}}',
+'nosuchspecialpage' => 'No existe esa página especial',
+'nospecialpagetext' => 'Has requerido una página especial que no es
+reconocida por el software de {{SITENAME}}.',
+'databaseerror' => 'Error de la base de datos',
+'dberrortext' => 'Ha ocurrido un error de sintaxis en una consulta
+a la base de datos.
+Esto puede indicar un error en el software.
+La última consulta que se intentó fue:
+<blockquote><tt>$1</tt></blockquote> dentro de la función "<tt>$2</tt>". El error de retorno de
+MySQL fue"<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Ha ocurrido un error de sintaxis en una consulta
+a la base de datos.
+La última consulta que se intentó fue:
+"$1"
+desde la función "$2".
+MySQL retornó el error "$3: $4".',
+'noconnect' => 'No se pudo conectar a la base de datos en $1',
+'nodb' => 'No se pudo seleccionar la base de datos $1',
+'cachederror' => 'Esta es una copia guardada en el cache de la página requerida, y puede no estar actualizada.',
+'laggedslavemode' => 'Aviso: a la página le pueden faltar las actualizaciones recientes.',
+'readonly' => 'Base de datos bloqueada',
+'enterlockreason' => 'Explica el motivo del bloqueo, incluyendo una estimación de cuándo se producirá el desbloqueo',
+'readonlytext' => 'La base de datos de {{SITENAME}} está temporalmente
+bloqueada para nuevas entradas u otras modificaciones, probablemente
+para mantenimiento de rutina, después de lo cual volverá a la normalidad.
+El administrador que la bloqueó ofreció esta explicación:
+<p>$1',
+'missingarticle' => 'La base de datos no encontró el texto de una
+página que debería haber encontrado, llamada "$1".
+
+Esto es causado usualmente por seguir un enlace a una diferencia de páginas o historial obsoleto a una página que ha sido borrada.
+
+Si esta no es la causa, puedes haber encontrado un error en el software. Por favor, informa de esto a un administrador,
+incluyendo el URL.',
+'readonly_lag' => 'La base de datos ha sido bloqueada automáticamente mientras los servidores esclavos de la base de datos alcanzan al amo',
+'internalerror' => 'Error interno',
+'filecopyerror' => 'No se pudo copiar el archivo "$1" a "$2".',
+'filerenameerror' => 'No se pudo renombrar el archivo "$1" a "$2".',
+'filedeleteerror' => 'No se pudo borrar el archivo "$1".',
+'filenotfound' => 'No se pudo encontrar el archivo "$1".',
+'unexpected' => 'Valor no esperado: "$1"="$2".',
+'formerror' => 'Error: no se pudo enviar el formulario',
+'badarticleerror' => 'Esta acción no se puede llevar a cabo en esta página.',
+'cannotdelete' => 'No se pudo borrar la página o imagen especificada. (Puede haber sido borrada por alguien antes)',
+'badtitle' => 'Título incorrecto',
+'badtitletext' => 'El título de la página solicitada esta vacío, es inválido, o es un enlace interlenguaje o interwiki incorrecto.',
+'perfdisabled' => 'Lo siento, esta función está temporalmente desactivada porque enlentece la base de datos a tal punto que nadie puede usar el wiki.',
+'perfdisabledsub' => 'Aquí hay una copia grabada de $1:',
+'perfcached' => 'Los siguientes datos están en cache y por tanto pueden estar desactualizados:',
+'perfcachedts' => 'Estos datos están almacenados. Su última actualización fue el $1.',
+'wrong_wfQuery_params' => 'Parámetros incorrectos para wfQuery()<br />
+Funcción: $1<br />
+Consulta: $2',
+'viewsource' => 'Ver código fuente',
+'protectedtext' => 'Esta página ha sido protegida para impedir su modificación; hay varias razones para que esto sea así, por favor vea
+[[Project:Esta página está protegida]].
+
+Puedes ver y copiar el texto fuente de esta página:',
+'sqlhidden' => '(Consulta SQL oculta)',
+'logouttitle' => 'Fin de sesión',
+'logouttext' => 'Has terminado tu sesión.
+Puedes continuar usando {{SITENAME}} en forma anónima, o puedes
+iniciar sesión otra vez como el mismo u otro usuario.',
+'welcomecreation' => '== ¡Bienvenido(a), $1! ==
+
+Tu cuenta ha sido creada. No olvides personalizar [[Special:Preferences|tus preferencias]] de {{SITENAME}}.',
+'loginpagetitle' => 'Registrarse/Entrar',
+'yourname' => 'Tu nombre de usuario',
+'yourpassword' => 'Tu contraseña',
+'yourpasswordagain' => 'Repite tu contraseña',
+'remembermypassword' => 'Quiero que me recuerden entre sesiones.',
+'yourdomainname' => 'Tu dominio',
+'externaldberror' => 'Hubo un error de autenticación externa de la base de datos o bien tú no está autorizado a actualizar tu cuenta externa.',
+'loginproblem' => '<b>Hubo un problema con tu entrada.</b><br />¡Inténtalo otra vez!',
+'alreadyloggedin' => '<strong>Usuario $1, ¡ya entraste!</strong><br />',
+'login' => 'Registrarse/Entrar',
+'loginprompt' => 'Necesitas tener cookies permitidos para registrarte en {{SITENAME}}.',
+'userlogin' => 'Registrarse/Entrar',
+'logout' => 'Salir',
+'userlogout' => 'Salir',
+'notloggedin' => 'No has entrado',
+'nologin' => '¿No tienes una cuenta? $1.',
+'nologinlink' => 'Créala',
+'createaccount' => 'Crea una nueva cuenta',
+'gotaccount' => '¿Ya tienes una cuenta? $1.',
+'gotaccountlink' => 'Ingresar',
+'createaccountmail' => 'por correo',
+'badretype' => 'Las contraseñas que ingresaste no concuerdan.',
+'userexists' => 'El nombre que entraste ya está en uso. Por favor, elige un nombre diferente.',
+'youremail' => 'Tu dirección de correo electrónico',
+'username' => 'Nombre de usuario:',
+'uid' => 'ID de usuario:',
+'yourrealname' => 'Tu nombre real *',
+'yourlanguage' => 'Idioma:',
+'yourvariant' => 'Variante lingüística',
+'yournick' => 'Tu apodo (para firmas)',
+'badsig' => 'Firma en crudo inválida; comprueba las etiquetas HTML.',
+'email' => 'Correo electrónico',
+'prefs-help-email-enotif'=> 'Esta dirección también se usa para mandarte notificaciones por correo si tienes habilitadas las opciones correspondientes.',
+'prefs-help-realname' => '* Nombre real (opcional): si optas por proporcionarlo, se usará para dar atribución a tu trabajo.',
+'loginerror' => 'Error de inicio de sesión',
+'prefs-help-email' => '* Correo (opcional): Permite a otros usuarios escribirte por correo desde tu página de usuario o tu página de discusión sin la necesidad de revelar tu identidad.',
+'nocookiesnew' => 'La cuenta de usuario ha sido creada, pero ahora mismo no estás identificado. {{SITENAME}} usa <em>cookies</em> para identificar a los usuarios registrados, pero tú las tienes deshabilitadas. Por favor, habilítalas, e ingresa con tu nuevo nombre y contraseña.',
+'nocookieslogin' => '{{SITENAME}} utiliza <em>cookies</em> para el ingreso de los usuarios. Tienes las <em>cookies</em> deshabilitadas en el navegador. Por favor, actívalas e inténtalo de nuevo.',
+'noname' => 'No has especificado un nombre de usuario válido.',
+'loginsuccesstitle' => 'Inicio de sesión exitoso',
+'loginsuccess' => 'Has iniciado tu sesión en {{SITENAME}} como "$1".',
+'nosuchuser' => 'No existe usuario alguno llamado "$1".
+Revisa tu escritura, o usa el formulario de abajo para crear una nueva cuenta de usuario.',
+'nosuchusershort' => 'No hay un usuario con el nombre "$1". Revisa cómo lo has escrito.',
+'wrongpassword' => 'La contraseña que ingresaste es incorrecta. Por favor inténtalo de nuevo.',
+'wrongpasswordempty' => 'No has escrito una contraseña, inténtalo de nuevo.',
+'mailmypassword' => 'Envíame una nueva contraseña por correo electrónico',
+'passwordremindertitle' => 'Recordatorio de contraseña de {{SITENAME}}',
+'passwordremindertext' => 'Alguien (probablemente tú, desde la dirección IP $1)
+solicitó que te enviáramos una nueva contraseña para iniciar sesión en {{SITENAME}} ($4).
+La contraseña para el usuario "$2" es ahora "$3".
+Ahora deberías iniciar sesión y cambiar tu contraseña.
+
+Si fue alguien más quien solicitó este mensaje o has recordado tu contraseña y ya no deseas cambiarla, puedes ignorar este mensaje y seguir usando tu contraseña original.',
+'noemail' => 'No hay dirección electrónica (e-mail) registrada para "$1".',
+'passwordsent' => 'Una nueva contraseña ha sido enviada a la dirección electrónica registrada para "$1".
+Por favor entra otra vez después de que la recibas.',
+'eauthentsent' => 'Un correo electrónico de confirmación ha sido enviado a la
+dirección especificada. Antes de que se envíe algún otro correo,
+sigue por favor las instrucciones enviadas en el mensaje, para confirmar que la dirección te pertenece.',
+'mailerror' => 'Error al enviar correo: $1',
+'acct_creation_throttle_hit'=> 'Lo sentimos, ya has creado $1 cuentas. No puedes crear otra.',
+'emailauthenticated' => 'Tu dirección electrónica fue autentificada en $1.',
+'emailnotauthenticated' => 'Aún no has confirmado tu durección de correo.
+Hasta que lo hagas, las siguientes funciones no estarán disponibles.',
+'noemailprefs' => '<strong>Especifica una dirección electrónica para que funcionen estas características.</strong>',
+'emailconfirmlink' => 'Confirma tu dirección de correo electrónico',
+'invalidemailaddress' => 'La dirección electrónica no puede ser aceptada pues parece que tiene un formato no válido. Por favor, escribe una dirección bien formada o vacía el campo.',
+'accountcreated' => 'Cuenta creada',
+'accountcreatedtext' => 'La cuenta de usuario para $1 ha sido creada.',
+'bold_sample' => 'Texto en negrita',
+'bold_tip' => 'Texto en negrita',
+'italic_sample' => 'Texto en cursiva',
+'italic_tip' => 'Texto en cursiva',
+'link_sample' => 'Título del enlace',
+'link_tip' => 'Enlace interno',
+'extlink_sample' => 'http://www.ejemplo.com Título del enlace',
+'extlink_tip' => 'Enlace externo (recuerda añadir el prefijo http://)',
+'headline_sample' => 'Texto de titular',
+'headline_tip' => 'Titular de nivel 2',
+'math_sample' => 'Escribe aquí una fórmula',
+'math_tip' => 'Fórmula matemática (LaTeX)',
+'nowiki_sample' => 'Aquí inserta texto sin formato',
+'nowiki_tip' => 'Pasar por alto el formato wiki',
+'image_sample' => 'Ejemplo.jpg',
+'image_tip' => 'Imagen incorporada',
+'media_sample' => 'Ejemplo.ogg',
+'media_tip' => 'Enlace a archivo multimedia',
+'sig_tip' => 'Firma, fecha y hora',
+'hr_tip' => 'Línea horizontal (utilízala con moderación)',
+'summary' => 'Resumen',
+'subject' => 'Tema/título',
+'minoredit' => 'Esta es una edición menor',
+'watchthis' => 'Vigilar este artículo',
+'savearticle' => 'Grabar la página',
+'preview' => 'Previsualizar',
+'showpreview' => 'Mostrar previsualización',
+'showdiff' => 'Mostrar cambios',
+'blockedtitle' => 'El usuario está bloqueado',
+'blockedtext' => 'Tu nombre de usuario o dirección IP ha sido bloqueada por $1.
+La razón dada es la que sigue:<br />$2<br /> Puedes contactar a $1 o a otro de los [[Project:Administradores|administradores]] para
+discutir el bloqueo.
+
+Nota que no podrás usar el enlace "enviar correo electrónico a este usuario" si no has registrado una dirección válida de correo electrónico en tus [[Special:Preferences|preferencias]].
+
+Tu dirección IP es $3. Por favor, menciona esta dirección en cualquier consulta que hagas.',
+'whitelistedittitle' => 'Se requiere ingresar para editar.',
+'whitelistedittext' => 'Tienes que $1 para editar artículos.',
+'whitelistreadtitle' => 'Se requiere ingresar para leer',
+'whitelistreadtext' => 'Tienes que [[Special:Userlogin|registrarte]] para leer artículos.',
+'whitelistacctitle' => 'No se te permite crear una cuenta',
+'whitelistacctext' => 'Para que se te permita crear cuentas en este wiki tienes que [[Special:Userlogin|iniciar sesión]] y tener los permisos apropiados.',
+'loginreqtitle' => 'Se requiere ingresar',
+'loginreqlink' => 'ingresar',
+'loginreqpagetext' => 'Debes $1 para ver otras páginas.',
+'accmailtitle' => 'La contraseña ha sido enviada.',
+'accmailtext' => 'La contraseña para «$1» se ha enviado a $2.',
+'newarticle' => '(Nuevo)',
+'newarticletext' => 'Has seguido un enlace a una página que aún no existe. Si lo que quieres es crear esta página, empieza a escribir en la caja que sigue. Para más información consulta la [[Project:Ayuda|página de ayuda]]. Si llegaste aquí por error, presiona la tecla para volver a la página anterior de tu navegador.',
+'anontalkpagetext' => '---- \'\'Esta es la página de discusión para un usuario anónimo que aún no ha creado una cuenta (o no la usa). Por lo tanto, tenemos que usar su dirección IP para identificarlo. Una dirección IP puede ser compartida por varios usuarios. Si eres un usuario anónimo y sientes que te han dirigido comentarios irrelevantes, por favor [[Special:Userlogin|crea una cuenta o entra]] para evitar confusiones futuras con otros usuarios anónimos.\'\'',
+'noarticletext' => '(En este momento no hay texto en esta página)',
+'clearyourcache' => '\'\'\'Nota:\'\'\' Tras salvar el archivo, debes refrescar la caché de tu navegador para ver los cambios:
+*\'\'\'Mozilla:\'\'\' \'\'ctrl-shift-r\'\',
+*\'\'\'Internet Explorer:\'\'\' \'\'ctrl-f5\'\',
+*\'\'\'Safari:\'\'\' \'\'cmd-shift-r\'\',
+*\'\'\'Konqueror\'\'\' \'\'f5\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Consejo:</strong> Usa el botón «Mostrar previsualización» para probar tu nuevo css/js antes de grabarlo.',
+'usercsspreview' => '\'\'\'¡Recuerda que sólo estás previsualizando tu css de usuario, aún no se ha grabado!\'\'\'',
+'userjspreview' => '\'\'\'¡Recuerda que sólo estás previsualizando tu javascript de usuario, y que todavía no se ha grabado!\'\'\'',
+'updated' => '(Actualizado)',
+'note' => '<strong>Nota:</strong>',
+'previewnote' => '¡Recuerda que esto es sólo una previsualización, y no ha sido grabada todavía!',
+'session_fail_preview' => '<strong>Lo sentimos, no pudimos procesar tu edición debido a una pérdida de los datos de sesión. Por favor, prueba de nuevo, y si no funciona, prueba a salir y volver a ingresar.</strong>',
+'previewconflict' => 'Esta previsualización refleja el texto en el área
+de edición superior como aparecerá si eliges grabar.',
+'importing' => 'Importando $1',
+'editing' => 'Editando $1',
+'editinguser' => 'Editando $1',
+'editingsection' => 'Editando $1 (sección)',
+'editingcomment' => 'Editando $1 (comentario)',
+'editconflict' => 'Conflicto de edición: $1',
+'explainconflict' => 'Alguien más ha cambiado esta página desde que empezaste
+a editarla.
+El área de texto superior contiene el texto de la página como existe
+actualmente. Tus cambios se muestran en el área de texto inferior.
+Vas a tener que incorporar tus cambios en el texto existente.
+<b>Sólo</b> el texto en el área de texto superior será grabado cuando presiones
+ "Grabar página".<br />',
+'yourtext' => 'Tu texto',
+'storedversion' => 'Versión almacenada',
+'nonunicodebrowser' => '<strong>AVISO: Tu navegador no cumple la norma Unicode. Se ha activado un sistema de edición alternativo que te permitirá editar artículos con seguridad: los caracteres no ASCII aparecerán en la caja de edición como códigos hexadecimales.</strong>',
+'editingold' => '<strong>ADVERTENCIA: Estás editando una versión antigua
+ de esta página.
+Si la grabas, los cambios hechos desde esa revisión se perderán.</strong>',
+'yourdiff' => 'Diferencias',
+'copyrightwarning' => 'Por favor observa que todas las contribuciones a {{SITENAME}} se consideran hechas públicas bajo la $2 (ver detalles en $1). Si no deseas que la gente corrija tus escritos sin piedad y los distribuya libremente, entonces no los pongas aquí. También tú nos aseguras que escribiste este texto tú mismo y eres dueño de los derechos de autor, o lo copiaste desde el dominio público u otra fuente libre.<strong>¡NO USES ESCRITOS CON COPYRIGHT SIN PERMISO!<br />',
+'copyrightwarning2' => 'Por favor, ten en cuenta que todas las contribuciones a {{SITENAME}} pueden ser editadas, modificadas o eliminadas por otros colaboradores. Si no deseas que la gente corrija tus escritos sin piedad y los distribuya libremente, entonces no los pongas aquí. <br />También tú nos aseguras que escribiste esto tú mismo y eres dueño de los derechos de autor, o lo copiaste desde el dominio público u otra fuente libre. (véase $1 para detalles). <br /><strong>¡NO USES ESCRITOS CON COPYRIGHT SIN PERMISO!</strong>',
+'longpagewarning' => '<strong>ADVERTENCIA: Esta página tiene un tamaño de $1 kilobytes; algunos navegadores pueden tener problemas editando páginas de 32kb o más.
+Por favor considera la posibilidad de descomponer esta página en secciones más pequeñas.</strong>',
+'readonlywarning' => '<strong>ADVERTENCIA: La base de datos ha sido bloqueada para mantenimiento, así que no podrás grabar tus modificaciones en este momento.
+Puedes "cortar y pegar" a un archivo de texto en tu computador, y grabarlo para
+intentarlo después.</strong>',
+'protectedpagewarning' => '<strong>ADVERTENCIA: Esta página ha sido protegida de manera que sólo usuarios con permisos de administrador pueden editarla. Asegúrate de que estás siguiendo las [[Project:Políticas de bloqueo de páginas|gPolíticas de bloqueo de páginas]].</strong>
+__NOEDITSECTION__<h3>La edición de esta página está [[Project:Esta página está protegida|protegida]].</h3>
+* Puedes opinar sobre este bloqueo en la [[{{TALKPAGENAME}}|página de discusión]] del artículo.<br />',
+'templatesused' => 'Plantillas usadas en esta página:',
+'edittools' => '<!-- Este texto aparecerá bajo los formularios de edición y subida. -->',
+'nocreatetitle' => 'Creación de páginas limitada',
+'nocreatetext' => 'Este wiki ha restringido la posibilidad de crear nuevas páginas. Puedes volver atrás y editar una página existente, o [[Special:Userlogin|ingresar o crear una cuenta]].',
+'revhistory' => 'Historial de revisiones',
+'nohistory' => 'No hay un historial de ediciones para esta página.',
+'revnotfound' => 'Revisión no encontrada',
+'revnotfoundtext' => 'La revisión antigua de la página por la que preguntaste no se pudo encontrar.
+Por favor revisa el URL que usaste para acceder a esta página.',
+'loadhist' => 'Recuperando el historial de la página',
+'currentrev' => 'Revisión actual',
+'revisionasof' => 'Revisión de $1',
+'previousrevision' => '← Revisión anterior',
+'nextrevision' => 'Revisión siguiente →',
+'currentrevisionlink' => 'Ver revisión actual',
+'cur' => 'act',
+'next' => 'sig',
+'last' => 'prev',
+'histlegend' => 'Leyenda: (act) = diferencia con la versión actual,
+(prev) = diferencia con la versión previa, M = edición menor',
+'deletedrev' => '[borrado]',
+'histfirst' => 'Primeras',
+'histlast' => 'Últimas',
+'difference' => '(Diferencia entre revisiones)',
+'loadingrev' => 'recuperando revisión para diff',
+'lineno' => 'Línea $1:',
+'editcurrent' => 'Edita la versión actual de esta página',
+'selectnewerversionfordiff'=> 'Selecciona una versión más reciente para comparar',
+'selectolderversionfordiff'=> 'Selecciona una versión más antigua para comparar',
+'compareselectedversions'=> 'Comparar versiones seleccionadas',
+'searchresults' => 'Resultados de búsqueda',
+'searchresulttext' => 'Para más información acerca de búsquedas en {{SITENAME}}, ve a [[Project:Búsqueda|Buscando en {{SITENAME}}]].',
+'searchsubtitle' => 'Has consultado por \'\'\'[[:$1]]\'\'\'',
+'searchsubtitleinvalid' => 'Para consulta "$1"',
+'badquery' => 'Consulta de búsqueda formateada en forma incorrecta',
+'badquerytext' => 'No pudimos procesar tu búsqueda.
+Esto es probablemente porque intentaste buscar una palabra de menos de tres letras, lo que todavía no es posible.
+También puede ser que hayas cometido un error de escritura en la expresión.
+Por favor, intenta una búsqueda diferente.',
+'matchtotals' => 'La consulta "$1" coincidió con $2 títulos de artículos
+y el texto de $3 artículos.',
+'titlematches' => 'Coincidencias de título de artículo',
+'notitlematches' => 'No hay coincidencias de título de artículo',
+'textmatches' => 'Coincidencias de texto de artículo',
+'notextmatches' => 'No hay coincidencias de texto de artículo',
+'prevn' => '$1 previos',
+'nextn' => '$1 siguientes',
+'viewprevnext' => 'Ver ($1) ($2) ($3).',
+'showingresults' => 'Abajo se muestran hasta <b>$1</b> resultados empezando por el nº<b>$2</b>.',
+'showingresultsnum' => 'Abajo se muestran los <b>$3</b> resultados empezando por el nº<b>$2</b>.',
+'nonefound' => '<strong>Nota</strong>: a menudo el fracaso en una búsqueda se debe a intentar buscar palabras comunes como "la" o "de",
+que no están en el índice, o por especificar más de una palabra a buscar (sólo las páginas
+que contengan todos los términos de una búsqueda aparecerán en el resultado).',
+'powersearch' => 'Búsqueda',
+'powersearchtext' => '
+Buscar en espacios de nombre:<br />
+$1<br />
+$2 Listar redirecciones Buscar $3 $9',
+'searchdisabled' => 'La búsqueda en {{SITENAME}} está temporalmente deshabilitada. Mientras tanto puedes buscar mediante estos buscadores externos, pero ten en cuenta que sus índices del contenido de {{SITENAME}} pueden estar desactualizados.',
+'blanknamespace' => '(Principal)',
+'preferences' => 'Preferencias',
+'prefsnologin' => 'No has entrado',
+'prefsnologintext' => 'Debes [[Special:Userlogin|entrar]] para cambiar las preferencias de usuario.',
+'prefsreset' => 'Las preferencias han sido repuestas a sus valores almacenados.',
+'qbsettings' => 'Preferencias de "Quickbar"',
+'changepassword' => 'Cambiar contraseña',
+'skin' => 'Piel',
+'math' => 'Fórmulas',
+'dateformat' => 'Formato de fecha',
+'datedefault' => 'Sin preferencia',
+'datetime' => 'Fecha y hora',
+'math_failure' => 'No se pudo entender',
+'math_unknown_error' => 'error desconocido',
+'math_unknown_function' => 'función desconocida',
+'math_lexing_error' => 'error de léxico',
+'math_syntax_error' => 'error de sintaxis',
+'math_image_error' => 'La conversión a PNG ha sido errónea',
+'math_bad_tmpdir' => 'No se puede escribir o crear el directorio temporal de math',
+'math_bad_output' => 'No se puede escribir o crear el directorio de salida de math',
+'math_notexvc' => 'Falta el ejecutalbe de texvc; por favor, lee math/README para configurarlo.',
+'prefs-personal' => 'Datos personales',
+'prefs-rc' => 'Cambios recientes',
+'prefs-misc' => 'Miscelánea',
+'saveprefs' => 'Grabar preferencias',
+'resetprefs' => 'Volver a preferencias por defecto',
+'oldpassword' => 'Contraseña antigua:',
+'newpassword' => 'Contraseña nueva:',
+'retypenew' => 'Reescribe la nueva contraseña:',
+'textboxsize' => 'Edición',
+'rows' => 'Filas:',
+'columns' => 'Columnas:',
+'searchresultshead' => 'Búsquedas',
+'resultsperpage' => 'Resultados para mostrar por página',
+'contextlines' => 'Líneas para mostrar por resultado',
+'contextchars' => 'Caracteres de contexto por línea',
+'stubthreshold' => 'Umbral para mostrar esbozos:',
+'recentchangescount' => 'Número de títulos en cambios recientes',
+'savedprefs' => 'Tus preferencias han sido grabadas.',
+'timezonelegend' => 'Huso horario',
+'timezonetext' => 'Entra el número de horas de diferencia entre tu hora local
+y la hora del servidor (UTC).',
+'localtime' => 'Hora local',
+'timezoneoffset' => 'Diferencia',
+'servertime' => 'La hora en el servidor es',
+'guesstimezone' => 'Obtener la hora del navegador',
+'allowemail' => 'Habilitar la recepción de correo de otros usuarios',
+'defaultns' => 'Buscar en estos espacios de nombres por defecto:',
+'default' => 'por defecto',
+'files' => 'Archivos',
+'userrights-lookup-user'=> 'Configurar grupos de usuarios',
+'userrights-user-editname'=> 'Escribe un nombre de usuario:',
+'editusergroup' => 'Modificar grupos de usuarios',
+'userrights-editusergroup'=> 'Modificar grupos de usuarios',
+'saveusergroups' => 'Guardar grupos de usurarios',
+'userrights-groupsmember'=> 'Miembro de:',
+'userrights-groupsavailable'=> 'Grupos disponibles:',
+'userrights-groupshelp' => 'Selecciona los grupos a los que quieres unir al usuario (o de los que le quieres dar de baja).
+Los grupos no seleccionados no cambiarán. Puedes deseleccionar con CTRL + clic izquierdo',
+'changes' => 'cambios',
+'recentchanges' => 'Cambios recientes',
+'recentchangestext' => 'Sigue los cambios más recientes al wiki en esta página.',
+'rcnote' => 'Abajo están los últimos <b>$1</b> cambios en los últimos <b>$2</b> días, actualizados $3',
+'rcnotefrom' => 'Abajo están los cambios desde <b>$2</b> (se muestran hasta <b>$1</b>).',
+'rclistfrom' => 'Mostrar cambios nuevos desde $1',
+'rclinks' => 'Ver los últimos $1 cambios en los últimos $2 días.<br />$3',
+'diff' => 'dif',
+'hide' => 'esconder',
+'show' => 'mostrar',
+'number_of_watching_users_pageview'=> '[$1 usuarios vigilando]',
+'upload' => 'Subir archivo',
+'uploadbtn' => 'Subir un archivo',
+'reupload' => 'Subir otra vez',
+'reuploaddesc' => 'Regresar al formulario para subir.',
+'uploadnologin' => 'No has iniciado sesión',
+'uploadnologintext' => 'Tienes que [[Special:Userlogin|iniciar sesión]] para poder subir archivos.',
+'upload_directory_read_only'=> 'El directorio para subida de archivos ($1) no puede ser escrito por el servidor web.',
+'uploaderror' => 'Error al intentar subir archivo',
+'uploadtext' => 'Para ver o buscar imágenes que se hayan subido previamente, ve a la [[Special:Imagelist|lista de imágenes subidas]]. Los archivos subidos y borrados son registrados en el [[Special:Log/upload|registro de subidas]]. Consulta también la [[Project:Política de uso de imágenes|política de uso de imágenes]]. Usa el formulario siguiente para subir nuevos archivos de imágenes que vas a usar para ilustrar tus artículos. En la mayoría de los navegadores, verás un botón "Browse...", que abrirá el diálogo de selección de archivos estándar de tu sistema operativo. Cuando hayas elegido un archivo, su nombre aparecerá en el campo de texto al lado del botón "Examinar...". También debes marcar la caja afirmando que no estás violando ningún copyright al subir el archivo. Presiona el botón "Subir" para completar la subida. Esto puede tomar algún tiempo si tienes una conexión a Internet lenta. Los formatos preferidos son JPEG para imágenes fotográficas, PNG para dibujos y diagramas, y OGG para sonidos. Por favor, dale a tus archivos nombres descriptivos para evitar confusiones. Para incluir la imagen en un artículo, usa un enlace de la forma
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Archivo.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Archivo.png|alt text]]</nowiki>\'\'\'
+o para sonidos
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Archivo.ogg]]</nowiki>\'\'\'
+Por favor recuerda que, al igual que con las páginas {{SITENAME}}, otros pueden editar o borrar los archivos que has subido si piensan que es bueno para el proyecto, y se te puede bloquear, impidiéndote subir más archivos si abusas del sistema.',
+'uploadlog' => 'registro de subidas',
+'uploadlogpage' => 'Registro de subidas',
+'uploadlogpagetext' => 'Abajo hay una lista de los archivos que se han
+subido recientemente. Todas las horas son del servidor (UTC).
+<ul>
+</ul>',
+'filename' => 'Nombre del archivo',
+'filedesc' => 'Sumario',
+'fileuploadsummary' => 'Descripción:',
+'filestatus' => 'Estado de copyright',
+'filesource' => 'Fuente',
+'copyrightpage' => 'Project:Copyrights',
+'copyrightpagename' => 'Copyright de {{SITENAME}}',
+'uploadedfiles' => 'Archivos subidos',
+'ignorewarning' => 'Ignorar aviso y guardar de todos modos',
+'ignorewarnings' => 'Ignorar cualquier aviso',
+'minlength' => 'Los nombres de imágenes deben ser al menos de tres letras.',
+'illegalfilename' => 'El nombre de archivo «$1» contiene caracteres que no están permitidos en títulos de páginas. Por favor, renombra el archivo e intenta volver a subirlo.',
+'badfilename' => 'El nombre de la imagen se ha cambiado a "$1".',
+'badfiletype' => '".$1" no es un formato de imagen recomendado.',
+'largefile' => 'Se recomienda que las imágenes no excedan los $1 bytes de tamaño. Esta imágen tiene $2',
+'largefileserver' => 'El tamaño de este archivo es mayor del que este servidor admite por configuración.',
+'emptyfile' => 'El archivo que has intentado subir parece estar vacío; por favor, verifica que realmente se trate del archivo que intentabas subir.',
+'fileexists' => 'Ya existe un archivo con este nombre, por favor comprueba el existente $1 si no estás seguro de querer reemplazarlo.
+
+
+\'\'\'Nota:\'\'\' Si finalmente sustituyes el archivo, debes refrescar la caché de tu navegador para ver los cambios:
+*\'\'\'Mozilla\'\'\' / \'\'\'Firefox\'\'\': Pulsa el botón \'\'\'Recargar\'\'\' (o \'\'\'ctrl-r\'\'\')
+*\'\'\'Internet Explorer\'\'\' / \'\'\'Opera\'\'\': \'\'\'ctrl-f5\'\'\'
+*\'\'\'Safari\'\'\': \'\'\'cmd-r\'\'\'
+*\'\'\'Konqueror\'\'\': \'\'\'ctrl-r\'\'',
+'fileexists-forbidden' => 'Ya existe un archivo con este nombre. Por favor, vuelve atrás y sube este archivo con un nuevo nombre. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Ya existe en \'\'[[Commons:Portada|Commons]]\'\' un archivo con el mismo nombre. Por favor regresa a la página anterior y sube tu archivo con otro nombre. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Subida con éxito',
+'fileuploaded' => 'El archivo "$1" se subió con éxito.
+Por favor sigue este enlace: ($2) a la página de descripción y escribe
+la información acerca del archivo, tal como de dónde viene, cuándo fue
+creado y por quién, y cualquier otra cosa que puedas saber al respecto.',
+'uploadwarning' => 'Advertencia de subida de archivo',
+'savefile' => 'Grabar archivo',
+'uploadedimage' => 'subió "[[$1]]".',
+'uploaddisabled' => 'Lo sentimos, la capacidad de subir archivos está desactivada.',
+'uploadscripted' => 'Este archivo contiene HTML o código de script que puede ser interpretado erroneamente por un navegador web.',
+'uploadcorrupt' => 'Este archivo está corrupto o tiene una extensión incorrecta. Por favor, comprueba el archivo y súbleo de nuevo.',
+'uploadvirus' => '¡El archivo contiene un virus! Detalles: $1',
+'sourcefilename' => 'Nombre de origen',
+'destfilename' => 'Nombre de destino',
+'license' => 'Licencia',
+'nolicense' => 'Ninguna seleccionada',
+'imagelist' => 'Lista de imágenes',
+'imagelisttext' => 'Abajo hay una lista de $1 imágenes ordenadas $2.',
+'getimagelist' => ' obteniendo la lista de imágenes',
+'ilsubmit' => 'Búsqueda',
+'showlast' => 'Mostrar las últimas $1 imágenes ordenadas $2.',
+'byname' => 'por nombre',
+'bydate' => 'por fecha',
+'bysize' => 'por tamaño',
+'imgdelete' => 'borr',
+'imglegend' => 'Leyenda: (desc) = mostrar/editar la descripción de la imagen.',
+'imghistory' => 'Historial de la imagen',
+'deleteimg' => 'borr',
+'deleteimgcompletely' => 'Borrar todas las revisiones',
+'imghistlegend' => 'Leyenda: (act) = esta es la imagen actual, (borr) = borrar
+esta versión antigua, (rev) = revertir a esta versión antigua.
+<br /><i>Clic en la fecha para ver imagen subida en esa fecha</i>.',
+'imagelinks' => 'Enlaces a la imagen',
+'linkstoimage' => 'Las siguientes páginas enlazan a esta imagen:',
+'nolinkstoimage' => 'No hay páginas que enlacen a esta imagen.',
+'sharedupload' => 'Este archivo está compartido y puede usarse desde otros proyectos.',
+'shareduploadwiki' => 'Puedes consultar $1 para más información.',
+'shareduploadwiki-linktext'=> 'página de descripción del archivo',
+'noimage' => 'No existe un archivo con este nombre, puedes $1.',
+'noimage-linktext' => 'subirlo',
+'uploadnewversion-linktext'=> 'Subir una nueva versión de este archivo',
+'mimesearch' => 'Búsqueda MIME',
+'mimetype' => 'Tipo MIME:',
+'download' => 'descargar',
+'unwatchedpages' => 'Páginas no vigiladas',
+'statistics' => 'Estadísticas',
+'sitestats' => 'Estadísticas del sitio',
+'userstats' => 'Estadísticas de usuario',
+'sitestatstext' => 'Hay un total de \'\'\'$1\'\'\' páginas en la base de datos
+Esto incluye páginas de discusión, páginas sobre {{SITENAME}}, esbozos, redirecciones y otras que probablmente no califican como artículos.
+Excluyéndolas, hay \'\'\'$2\'\'\' páginas que, probablmente, son artículos legítimos.
+
+\'\'\'$8\'\'\' archivos fueron almacenados en el servidor.
+
+Han habido un total de \'\'\'$3\'\'\' visitas y \'\'\'$4\'\'\' ediciones de página desde que el wiki fue instalado.
+Esto resulta en un promedio de \'\'\'$5\'\'\' ediciones por página y \'\'\'$6\'\'\' visitas por edición.
+
+La longitud de [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] es de \'\'\'$7\'\'\'',
+'userstatstext' => 'Hay \'\'\'$1\'\'\' usuarios registrados.
+de los cuales \'\'\'$2\'\'\' (o \'\'\'$4%\'\'\') son administradores (ver $3).',
+'disambiguations' => 'Páginas de desambiguación',
+'disambiguationspage' => 'Template:Desambiguación',
+'disambiguationstext' => 'Los siguientes artículos enlazan a una <i>página de desambiguación</i>. Deberían enlazar al artículo apropiado.<br />Una página es considerada de desambiguación si está enlazada desde $1.<br />Enlaces desde otros espacios de nombre <b>no</b> son listados aquí.',
+'doubleredirects' => 'Redirecciones dobles',
+'doubleredirectstext' => '<b>Atención:</b> Esta lista puede contener falsos positivos. Eso significa usualmente que hay texto adicional con enlaces bajo el primer #REDIRECT.<br />
+Cada fila contiene enlaces al segundo y tercer redirect, así como la primera línea del segundo redirect, en la que usualmente se encontrará el artículo "real" al que el primer redirect debería apuntar.',
+'brokenredirects' => 'Redirecciones incorrectas',
+'brokenredirectstext' => 'Las redirecciones siguientes enlazan a un artículo que no existe.',
+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
+'ncategories' => '$1 {{PLURAL:$1|categoría|categorías}}',
+'nlinks' => '$1 {{PLURAL:$1|enlace|enlaces}}',
+'nmembers' => '$1 {{PLURAL:$1|artículo|artículos}}',
+'nrevisions' => '$1 {{PLURAL:$1|revisión|revisiones}}',
+'nviews' => '$1 {{PLURAL:$1|vista|vistas}}',
+'lonelypages' => 'Páginas huérfanas',
+'uncategorizedpages' => 'Páginas sin categorizar',
+'uncategorizedcategories'=> 'Categorías sin categorizar',
+'unusedcategories' => 'Categorías sin uso',
+'unusedimages' => 'Imágenes sin uso',
+'popularpages' => 'Páginas populares',
+'wantedcategories' => 'Categorías requeridas',
+'wantedpages' => 'Páginas requeridas',
+'mostlinked' => 'Artículos más enlazados',
+'mostlinkedcategories' => 'Categorías más enlazadas',
+'mostcategories' => 'Páginas con más categorías',
+'mostimages' => 'Imágenes más usadas',
+'mostrevisions' => 'Artículos con más ediciones',
+'allpages' => 'Todas las páginas',
+'prefixindex' => 'Páginas por prefijo',
+'randompage' => 'Página aleatoria',
+'shortpages' => 'Páginas cortas',
+'longpages' => 'Páginas largas',
+'deadendpages' => 'Páginas sin salida',
+'listusers' => 'Lista de usuarios',
+'specialpages' => 'Páginas especiales',
+'spheading' => 'Páginas especiales',
+'restrictedpheading' => 'Páginas especiales restringidas',
+'recentchangeslinked' => 'Seguimiento de enlaces',
+'rclsub' => '(a páginas enlazadas desde "$1")',
+'newpages' => 'Páginas nuevas',
+'ancientpages' => 'Artículos más antiguos',
+'intl' => 'Enlaces interlenguaje',
+'move' => 'Trasladar',
+'movethispage' => 'Trasladar esta página',
+'unusedimagestext' => '<p>Por favor note que otros sitios web
+tales como otras {{SITENAME}}s pueden enlazar a una imagen
+con un URL directo, y de esa manera todavía estar listada aquí
+a pesar de estar en uso activo.',
+'unusedcategoriestext' => 'Las siguientes categorías han sido creadas, pero ningún artículo o categoría las emplea.',
+'booksources' => 'Fuentes de libros',
+'categoriespagetext' => 'Existen las siguientes categorías en este wiki.',
+'data' => 'Datos',
+'userrights' => 'Configuración de permisos de usuarios',
+'groups' => 'Grupos de usuarios',
+'booksourcetext' => 'A continuación hay una lista de enlaces a otros sitios que venden libros nuevos y usados, y también pueden contener información adicional acerca de los libros que estás buscando.
+{{SITENAME}} no está relacionada con ninguno de estos negocios, y esta lista no debe ser considerada un patrocinio de los mismos.',
+'alphaindexline' => '$1 a $2',
+'version' => 'Versión',
+'log' => 'Registros',
+'alllogstext' => 'Presentación combinada de los registros de subidas, borrados, protecciones, bloqueos y administradores.
+Puedes filtrar esta vista seleccionando el tipo de registro, el nombre de usuario, o la página afectada.',
+'logempty' => 'No hay elementos en el registro con esas condiciones.',
+'nextpage' => 'Siguiente página ($1)',
+'allpagesfrom' => 'Mostrar páginas comenzando en:',
+'allarticles' => 'Todos los artículos',
+'allinnamespace' => 'Todas las páginas (espacio $1)',
+'allnotinnamespace' => 'Todas las páginas (fuera del espacio $1)',
+'allpagesprev' => 'Anterior',
+'allpagesnext' => 'Siguiente',
+'allpagessubmit' => 'Mostrar',
+'allpagesprefix' => 'Mostrar páginas con el prefijo:',
+'mailnologin' => 'No enviar dirección',
+'mailnologintext' => 'Debes [[Special:Userlogin|iniciar sesión]] y tener una dirección electrónica válida en tus [[Special:Preferences|preferencias]] para enviar un correo electrónico a otros usuarios.',
+'emailuser' => 'Enviar correo electrónico a este usuario',
+'emailpage' => 'Correo electrónico a usuario',
+'emailpagetext' => 'Si este usuario ha registrado una dirección electrónica válida en sus preferencias de usuario, el siguiente formulario sirve para enviarle un mensaje.
+La dirección electrónica que indicaste en tus preferencias de usuario aparecerá en el remitente para que el destinatario te pueda responder.',
+'usermailererror' => 'El objeto de correo devolvió un error:',
+'defemailsubject' => 'Correo de {{SITENAME}}',
+'noemailtitle' => 'No hay dirección electrónica',
+'noemailtext' => 'Este usuario no ha especificado una dirección electrónica válida, o ha elegido no recibir correo electrónico de otros usuarios.',
+'emailfrom' => 'De',
+'emailto' => 'Para',
+'emailsubject' => 'Asunto',
+'emailmessage' => 'Mensaje',
+'emailsend' => 'Enviar',
+'emailsent' => 'Correo electrónico enviado',
+'emailsenttext' => 'Tu correo electrónico ha sido enviado.',
+'watchlist' => 'Lista de seguimiento',
+'nowatchlist' => 'No tienes ninguna página en tu lista de seguimiento.',
+'watchnologin' => 'No has iniciado sesión',
+'watchnologintext' => 'Debes [[Special:Userlogin|iniciar sesión]] para modificar tu lista de seguimiento.',
+'addedwatch' => 'Añadido a la lista de seguimiento',
+'addedwatchtext' => 'La página «[[:$1]]» ha sido añadida a tu [[Special:Watchlist|lista se seguimiento]]. Cambios futuros en esta página y su página de discusión asociada se indicarán ahí, y la página aparecerá \'\'\'en negritas\'\'\' en la [[Special:Recentchanges|lista de cambios recientes]] para hacerla más fácil de detectar. <p>Cuando quieras eliminar la página de tu lista de seguimiento, presiona "Dejar de vigilar" en el menú.',
+'removedwatch' => 'Eliminada de la lista de seguimiento',
+'removedwatchtext' => 'La página "[[:$1]]" ha sido eliminada de tu lista de seguimiento.',
+'watch' => 'Vigilar',
+'watchthispage' => 'Vigilar esta página',
+'unwatch' => 'Dejar de vigilar',
+'unwatchthispage' => 'Dejar de vigilar',
+'notanarticle' => 'No es un artículo',
+'watchnochange' => 'Ninguno de los artículos en tu lista de seguimiento fue editado en el periodo de tiempo mostrado.',
+'watchdetails' => '* $1 páginas vigiladas, sin contar las de discusión
+* [[Special:Watchlist/edit|Mostrar y editar la lista de seguimiento]]',
+'wlheader-enotif' => '* La notificación por correo electrónico está habilitada',
+'wlheader-showupdated' => '* Las páginas modificadas desde tu última visita aparecen en \'\'\'negrita\'\'\'',
+'watchmethod-recent' => 'chequeando ediciones recientes en la lista de seguimiento',
+'watchmethod-list' => 'buscando ediciones recientes en la lista de seguimiento',
+'removechecked' => 'Borrar artículos seleccionados de la lista de seguimiento',
+'watchlistcontains' => 'Tu lista de seguimiento posee $1 páginas.',
+'watcheditlist' => 'Aquí está un listado alfabético de tu lista de seguimiento.
+Selecciona los artículos que deseas eliminar de tu lista de seguimiento y
+pulsa el botón \'Eliminar artículos seleccionados\' al final de la página.',
+'removingchecked' => 'Eliminando los artículos solicitados de la lista de seguimiento...',
+'couldntremove' => 'No se pudo borrar el artículo \'$1\'...',
+'iteminvalidname' => 'Problema con el artículo \'$1\', nombre inválido...',
+'wlnote' => 'Abajo están los últimos $1 cambios en las últimas <b>$2</b> horas.',
+'wlshowlast' => 'Mostrar las últimas $1 horas $2 días $3',
+'wlsaved' => 'Esta es una versión guardada de tu lista de seguimiento.',
+'watchlist-show-bots' => 'Mostrar ediciones de bots',
+'watchlist-hide-bots' => 'Esconder ediciones de bots',
+'watchlist-show-own' => 'Mostrar mis ediciones',
+'watchlist-hide-own' => 'Esconder mis ediciones',
+
+'enotif_mailer' => 'Notificación por correo de {{SITENAME}}',
+'enotif_reset' => 'Marcar todas las páginas visitadas',
+'enotif_newpagetext' => 'Se trata de una nueva página.',
+'changed' => 'modificada',
+'created' => 'creada',
+'enotif_subject' => 'La página $PAGETITLE de {{SITENAME}} ha sido $CHANGEDORCREATED por $PAGEEDITOR',
+'enotif_lastvisited' => 'Vaya a $1 para ver todos los cambios desde su última visita.',
+'enotif_body' => 'Estimado/a $WATCHINGUSERNAME,
+
+La página de {{SITENAME}} «$PAGETITLE»
+ha sido $CHANGEDORCREATED por el usuario $PAGEEDITOR el $PAGEEDITDATE.
+La versión actual se encuentra en {{fullurl:$PAGETITLE_RAWURL}}
+
+$NEWPAGE
+
+El resumen de edición es: $PAGESUMMARY $PAGEMINOREDIT
+
+Para comunicarse con el usuario:
+por correo: {{fullurl:Especial:Emailuser|target=$PAGEEDITOR_RAWURL}}
+en el wiki: {{fullurl:Usuaro:$PAGEEDITOR_RAWURL}}
+
+Para recibir nuevas notificaciones de cambios de esta página, deberá vistarla nuevamente.
+También puede, en su lista de seguimiento, modificar las opciones de notificación de sus
+páginas vigiladas.
+
+ El sistema de notificación de {{SITENAME}}.
+
+--
+Cambie las opciones de su lista de seguimiento en:
+{{fullurl:Especial:Watchlist|edit=yes}}',
+'deletepage' => 'Borrar esta página',
+'confirm' => 'Confirmar',
+'excontent' => 'El contenido era: \'$1\'',
+'excontentauthor' => 'El contenido era: \'$1\' (y el único autor fue \'$2\')',
+'exbeforeblank' => 'contenido antes de borrar era: \'$1\'',
+'exblank' => 'página estaba vacía',
+'confirmdelete' => 'Confirma el borrado',
+'deletesub' => '(Borrando "$1")',
+'historywarning' => 'Atención: La página que estás por borrar tiene un historial:',
+'confirmdeletetext' => 'Estás a punto de borrar una página o imagen
+en forma permanente,
+así como todo su historial, de la base de datos.
+Por favor, confirma que realmente quieres hacer eso, que entiendes las
+consecuencias, y que lo estás haciendo de acuerdo con [[Project:Políticas]].',
+'actioncomplete' => 'Acción completa',
+'deletedtext' => '"$1" ha sido borrado.
+Véase $2 para un registro de los borrados recientes.',
+'deletedarticle' => 'borrado "$1"',
+'dellogpage' => 'Registro de borrados',
+'dellogpagetext' => 'Abajo hay una lista de los borrados más recientes.
+Todos los tiempos se muestran en hora del servidor (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'registro de borrados',
+'reverted' => 'Recuperar una revisión anterior',
+'deletecomment' => 'Razón para el borrado',
+'imagereverted' => 'Revertido a una versión anterior tuvo éxito.',
+'rollback' => 'Revertir ediciones',
+'rollback_short' => 'Revertir',
+'rollbacklink' => 'Revertir',
+'rollbackfailed' => 'Reversión fallida',
+'cantrollback' => 'No se pueden revertir las ediciones; el último colaborador es el único autor de este artículo.',
+'alreadyrolled' => 'No se puede revertir la última edición de [[:$1]] por [[User:$2|$2]] ([[User talk:$2|discusión]]); alguien más ya ha editado o revertido esa página. La última edición fue hecha por [[User:$3|$3]] ([[User talk:$3|discusión]]).',
+'editcomment' => 'El resumen de la edición fue: "<i>$1</i>".',
+'revertpage' => 'Revertidas las ediciones realizadas por [[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]); hacia la última versión por [[User:$1|$1]]',
+'sessionfailure' => 'Parece que hay un problema con tu sesión;
+esta acción ha sido cancelada como medida de precaución contra secuestros de sesión.
+Por favor, pulsa "Retroceder", recarga la página de la que viniste e inténtalo de nuevo.',
+'protectlogpage' => 'Protecciones de páginas',
+'protectlogtext' => 'Abajo se presenta una lista de protección y desprotección de página.
+Véase [[Project:Esta página está protegida]] para más información.',
+'protectedarticle' => 'protegió [[$1]]',
+'unprotectedarticle' => 'desprotegió [[$1]]',
+'protectsub' => '(Protegiendo "$1")',
+'confirmprotecttext' => '¿Realmente deseas proteger esta página?',
+'confirmprotect' => 'Confirmar protección',
+'protectmoveonly' => 'Proteger sólo contra traslados',
+'protectcomment' => 'Razón para proteger',
+'unprotectsub' => '(Desprotegiendo "$1")',
+'confirmunprotecttext' => '¿Realmente deseas desproteger esta página?',
+'confirmunprotect' => 'Confirmar la desprotección.',
+'unprotectcomment' => 'Razón para desproteger',
+'protect-unchain' => 'Configurar permisos para traslados',
+'protect-text' => 'Puedes visualizar y modificar el nivel de protección de [[$1]].
+Por favor, asegúrate de que sigues las [[Project:Políticas de protección de páginas|políticas de protección de páginas]].',
+'protect-viewtext' => 'No tienes permiso para modificar los niveles de protección de esta página. Los niveles de protección actuales para [[$1]] son:',
+'protect-default' => '(por defecto)',
+'protect-level-autoconfirmed'=> 'Bloquear usuarios no registrados',
+'protect-level-sysop' => 'Sólo administradores',
+'undelete' => 'Restaurar una página borrada',
+'undeletepage' => 'Ver y restaurar páginas borradas',
+'viewdeletedpage' => 'Ver páginas borradas',
+'undeletepagetext' => 'Las siguientes páginas han sido borradas pero aún están en el archivo y pueden ser restauradas. El archivo puede ser limpiado periódicamente.',
+'undeletearticle' => 'Restaurar página borrada',
+'undeleterevisions' => '$1 revisiones archivadas',
+'undeletehistory' => 'Si restauras una página, todas las revisiones serán restauradas al historial.
+Si una nueva página con el mismo nombre ha sido creada desde el borrado, las versiones restauradas aparecerán como historial anterior, y la revisión actual de la página "viva" no será automáticamente reemplazada.',
+'undeletehistorynoadmin'=> 'El artículo ha sido borrado. La razón de su eliminación se indica abajo en el sumario, así como el detalle de las ediciones realizadas antes del borrado. El texto completo del artículo está disponible sólo para usuarios con permisos de [[Project:Administradores|administrador]].',
+'undeleterevision' => 'Revisión borrada al $1',
+'undeletebtn' => '¡Restaurar!',
+'undeletedarticle' => 'restaurado "$1"',
+'undeletedrevisions' => '{{PLURAL:$1|Una edición restaurada|$1 ediciones restauradas}}',
+'namespace' => 'Espacio de nombres:',
+'invert' => 'Invertir selección',
+'contributions' => 'Contribuciones del usuario',
+'mycontris' => 'Mis contribuciones',
+'contribsub' => '$1',
+'nocontribs' => 'No se encontraron cambios que cumplieran estos criterios.',
+'ucnote' => 'Abajo están los últimos <b>$1</b> cambios de este usuario en los últimos <b>$2</b> días.',
+'uclinks' => 'Ver los últimos $1 cambios; ver los últimos $2 días.',
+'uctop' => ' (última modificación)',
+'newbies' => 'noveles',
+'whatlinkshere' => 'Lo que enlaza aquí',
+'notargettitle' => 'No hay página objetivo',
+'notargettext' => 'No has especificado en qué página
+llevar a cabo esta función.',
+'linklistsub' => '(Lista de enlaces)',
+'linkshere' => 'Las siguientes páginas enlazan aquí:',
+'nolinkshere' => 'Ninguna página enlaza aquí.',
+'isredirect' => 'página redirigida',
+'blockip' => 'Bloquear usuario',
+'blockiptext' => 'Usa el formulario siguiente para bloquear el
+acceso de escritura desde una dirección IP específica o un nombre de usuario.
+Esto debería hacerse sólo para prevenir vandalismos, y de
+acuerdo a las [[Project:Políticas|políticas de {{SITENAME}}]].
+Explica la razón específica del bloqueo (por ejemplo, citando
+las páginas en particular que han sido objeto de vandalismo).',
+'ipaddress' => 'Dirección IP',
+'ipadressorusername' => 'Dirección IP o nombre de usuario',
+'ipbexpiry' => 'Caduca dentro de',
+'ipbreason' => 'Razón',
+'ipbsubmit' => 'Bloquear esta dirección',
+'ipbother' => 'Especificar caducidad',
+'ipboptions' => '15 minutos:15 minutes,media hora:30 minutes,una hora:1 hour,2 horas:2 hours,un día:1 day,3 días:3 days,una semana:1 week,2 semanas:2 weeks,un mes:1 month,para siempre:infinite',
+'ipbotheroption' => 'Otro tiempo',
+'badipaddress' => 'La dirección IP no tiene el formato correcto.',
+'blockipsuccesssub' => 'Bloqueo exitoso',
+'blockipsuccesstext' => 'La dirección IP "$1" ha sido bloqueada. <br />Ver [[Special:Ipblocklist|lista de IP bloqueadas]] para revisar bloqueos.',
+'unblockip' => 'Desbloquear usuario',
+'unblockiptext' => 'Usa el formulario que sigue para restaurar el
+acceso de escritura a una dirección IP previamente bloqueada.',
+'ipusubmit' => 'Desbloquear esta dirección',
+'ipblocklist' => 'Lista de direcciones IP bloqueadas',
+'blocklistline' => '$1, $2 bloquea $3 ($4)',
+'infiniteblock' => 'infinito',
+'expiringblock' => 'expira $1',
+'ipblocklistempty' => 'La lista de bloqueo está vacía.',
+'blocklink' => 'bloquear',
+'unblocklink' => 'desbloquear',
+'contribslink' => 'contribuciones',
+'autoblocker' => 'Has sido bloqueado automáticamente porque tu dirección IP ha sido usada recientemente por "[[User:$1|$1]]". La razón esgrimida para bloquear a "[[User:$1|$1]]" fue "$2".',
+'blocklogpage' => 'Bloqueos de usuarios',
+'blocklogentry' => 'bloqueó a "$1" durante un plazo de "$2".',
+'blocklogtext' => 'Esto es un registro de bloqueos y desbloqueos de usuarios. Las direcciones bloqueadas automáticamente no están listadas. Vea el [[Special:Ipblocklist|listado de bloqueos de IP]] para la lista de prohibiciones y bloqueos actualmente vigente.',
+'unblocklogentry' => 'desbloqueó a "$1"',
+'range_block_disabled' => 'La facultad de administrador de crear bloqueos de rango está deshabilitada.',
+'ipb_expiry_invalid' => 'Tiempo de caducidad no válido.',
+'ip_range_invalid' => 'Rango de IP no es válido.',
+'proxyblocker' => 'Bloqueador de proxies',
+'proxyblockreason' => 'Tu dirección IP ha sido bloqueada porque es un proxy abierto. Por favor, contacta con tu proveedor de servicios de Internet o con tu servicio de asistencia técnica e infórmales de este grave problema de seguridad.',
+'proxyblocksuccess' => 'Hecho.',
+'sorbsreason' => 'Tu dirección IP está listada como proxy abierto en [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason'=> 'Tu dirección IP está listada como proxy abierto en [http://www.sorbs.net SORBS] DNSBL. No puedes crear una cuenta',
+'lockdb' => 'Bloquear la base de datos',
+'unlockdb' => 'Desbloquear la base de datos',
+'lockdbtext' => 'El bloqueo de la base de datos impedirá a todos los usuarios editar páginas, cambiar sus preferencias, modificar sus listas de seguimiento y cualquier otra función que requiera realizar cambios en la base de datos. Por favor, confirma que ésto es precisamente lo que quieres hacer y que desbloquearás la base de datos tan pronto hayas finalizado las operaciones de mantenimiento.',
+'unlockdbtext' => 'El desbloqueo de la base de datos permitirá a todos los usuarios editar páginas, cambiar sus preferencias, modificar sus listas de seguimiento y cualesquiera otras funciones que impliquen modificar la base de datos. Por favor, confirma que esto es precisamente lo que quieres hacer.',
+'lockconfirm' => 'Sí, realmente quiero bloquear la base de datos.',
+'unlockconfirm' => 'Sí, realmente quiero desbloquear la base de datos.',
+'lockbtn' => 'Bloquear la base de datos',
+'unlockbtn' => 'Desbloquear la base de datos',
+'locknoconfirm' => 'No has confirmado lo que deseas hacer.',
+'lockdbsuccesssub' => 'El bloqueo se ha realizado con éxito',
+'unlockdbsuccesssub' => 'El desbloqueo se ha realizado con éxito',
+'lockdbsuccesstext' => 'La base de datos de {{SITENAME}} ha sido bloqueada.
+<br />Recuerda retirar el bloqueo después de completar las tareas de mantenimiento.',
+'unlockdbsuccesstext' => 'La base de datos de {{SITENAME}} ha sido desbloqueada.',
+'makesysoptitle' => 'Convertir a este usuario en administrador',
+'makesysoptext' => 'Con este formulario los burócratas pueden convertir usuarios normales en administradores.
+Escribe el nombre del usuario en la caja y pulsa el botón para convertir a este usuario en administrador.',
+'makesysopname' => 'Nombre del usuario:',
+'makesysopsubmit' => 'Convertir en administrador',
+'makesysopok' => '<b>El usuario "$1" es ahora un administrador</b>',
+'makesysopfail' => '<b>No se pudo convertir al usuario "$1" en administrador. (¿Escribiste su nombre correctamente?)</b>',
+'setbureaucratflag' => 'Establecer la condición de burócrata',
+'rightslogtext' => 'Este es un registro de cambios a los permisos de usuarios.',
+'rights' => 'Permisos:',
+'set_user_rights' => 'Establecer permisos de usuario',
+'user_rights_set' => '<b>Permisos para "$1" actualizados</b>',
+'set_rights_fail' => '<b>Permisos para "$1" no se han podido establecer. (¿Escribiste su nombre correctamente?)</b>',
+'makesysop' => 'Convertir a un usuario en administrador',
+'already_sysop' => 'Este usuario ya es un administrador',
+'already_bureaucrat' => 'Este usuario ya es un burócrata',
+'movepage' => 'Renombrar página',
+'movepagetext' => 'Usando el formulario que sigue renombrará una página,
+moviendo todo su historial al nombre nuevo.
+El título anterior se convertirá en un redireccionamiento al nuevo título.
+Los enlaces al antiguo título de la página no se cambiarán. Asegúrate de no dejar redirecciones dobles o rotas.
+Tú eres responsable de hacer que los enlaces sigan apuntando adonde se supone que lo deberían hacer.
+
+Recuerda que la página \'\'\'no\'\'\' será renombrada si ya existe una página con el nuevo título, a no ser que sea una página vacía o un \'\'redirect\'\' sin historial.
+Esto significa que podrás renombrar una página a su título original si has cometido un error, pero que no podrás sobreescribir una página existente.
+
+<b>¡ADVERTENCIA!</b>
+Este puede ser un cambio drástico e inesperado para una página popular;
+por favor, asegúrate de entender las consecuencias que acarreará
+antes de seguir adelante.',
+'movepagetalktext' => 'La página de discusión asociada, si existe, será renombrada automáticamente \'\'\'a menos que:\'\'\'
+*Estés moviendo la página entre espacios de nombre diferentes,
+*Una página de discusión no vacía ya existe con el nombre nuevo, o
+*Desactivaste la opción "Renombrar la página de discusión también".
+
+En estos casos, deberás trasladar manualmente el contenido de la página de discusión.',
+'movearticle' => 'Renombrar página',
+'movenologin' => 'No has iniciado sesión',
+'movenologintext' => 'Es necesario ser usuario registrado y [[Special:Userlogin|haber iniciado sesión]] para renombrar una página.',
+'newtitle' => 'A título nuevo',
+'movepagebtn' => 'Renombrar página',
+'pagemovedsub' => 'Renombrado realizado',
+'pagemovedtext' => 'Página "[[$1]]" renombrada a "[[$2]]".',
+'articleexists' => 'Ya existe una página con ese nombre, o el nombre que has
+escogido no es válido.
+Por favor, elige otro nombre.',
+'talkexists' => 'La página fue renombrada con éxito, pero la página de discusión no se pudo mover porque ya existe una en el título nuevo. Por favor incorpora su contenido manualmente.',
+'movedto' => 'renombrado a',
+'movetalk' => 'Renombrar la página de discusión también, si es aplicable.',
+'talkpagemoved' => 'La página de discusión correspondiente también fue renombrada.',
+'talkpagenotmoved' => 'La página de discusión correspondiente <strong>no</strong> fue renombrada.',
+'1movedto2' => '[[$1]] trasladada a [[$2]]',
+'1movedto2_redir' => '[[$1]] trasladada a [[$2]] sobre una redirección',
+'movelogpage' => 'Registro de renombrados',
+'movelogpagetext' => 'Abajo se encuentra una lista de páginas renombradas.',
+'movereason' => 'Motivo',
+'revertmove' => 'revertir',
+'delete_and_move' => 'Borrar y trasladar',
+'delete_and_move_text' => '==Se necesita borrado==
+
+La página de destino ("[[$1]]") ya existe. ¿Quieres borrarla para dejar paso al traslado?',
+'delete_and_move_reason'=> 'Borrada para dejar paso al traslado',
+'selfmove' => 'Los títulos de origen y destino son los mismos; no se puede trasladar un página sobre sí misma.',
+'immobile_namespace' => 'El título de destino es de un tipo especial; no se pueden trasladar página a ese espacio de nombres.',
+'export' => 'Exportar páginas',
+'exporttext' => 'Puedes exportar el texto y el historial de edición de una página en particular o de un conjunto de páginas a un texto XML. En el futuro, este texto podría posteriormente importarse en otro wiki que ejecutase MediaWiki, sin embargo esta capacidad no está aún disponible en la versión actual.
+
+Para exportar páginas, escribe los títulos en la caja de texto de abajo, un título por línea, y selecciona si quieres la versión actual junto a las versiones anteriores, con las líneas del historial, o sólo la versión actual con la información sobre la última edición.
+
+En el último caso puedes usar un enlace, por ejemplo [[Special:Export/{{Mediawiki:Mainpage}}]] for the page {{Mediawiki:Mainpage}}.',
+'exportcuronly' => 'Sólo incluir la revisión actual, no el historial completo',
+'allmessages' => 'Todos los mensajes de MediaWiki',
+'allmessagesname' => 'Nombre',
+'allmessagesdefault' => 'Texto predeterminado',
+'allmessagescurrent' => 'Texto actual',
+'allmessagestext' => 'Esta es una lista de mensajes del sistema disponibles en el espacio de nombres MediaWiki:.',
+'allmessagesnotsupportedUI'=> 'Tu lengua de interfaz actual (<b>$1</b>) no está disponible en Special:AllMessages en este sitio.',
+'allmessagesnotsupportedDB'=> 'Special:AllMessages no está disponible porque wgUseDatabaseMessages está deshabilitado.',
+'thumbnail-more' => 'Aumentar',
+'missingimage' => '<b>Falta imagen</b><br /><i>$1</i>',
+'filemissing' => 'Falta archivo',
+'import' => 'Importar páginas',
+'importinterwiki' => 'Importación transwiki',
+'importtext' => 'Por favor, exporta el archivo desde el wiki de origen usando la utilidad Special:Export, guárdalo en tu disco y súbelo aquí.',
+'importfailed' => 'La importación ha fallado: $1',
+'importnotext' => 'Vacío o sin texto',
+'importsuccess' => '¡La importación tuvo éxito!',
+'importhistoryconflict' => 'Existen revisiones en el historial con conflicto (puede que se haya importado esta página antes)',
+'importnosources' => 'No hay fuentes de importación transwiki y las subidas directas de historial están deshabilitadas.',
+'importnofile' => 'No se subieron archivos de importación.',
+'importuploaderror' => 'La subida del archivo de importación ha fallado; quizá el archivo es mayor que el tamaño de subida permitido.',
+'tooltip-search' => 'Buscar en este wiki [alt-f]',
+'tooltip-minoredit' => 'Marcar este cambio como menor [alt-i]',
+'tooltip-save' => 'Guardar tus cambios [alt-s]',
+'tooltip-preview' => 'Previsualiza tus cambios, ¡por favor, usa esto antes de grabar! [alt-p]',
+'tooltip-diff' => 'Muestra los cambios que has introducido en el texto. [alt-v]',
+'tooltip-compareselectedversions'=> 'Ver las diferencias entre las dos versiones seleccionadas de esta página. [alt-v]',
+'tooltip-watch' => 'Añadir esta página a tu lista de seguimiento [alt-w]',
+'monobook.css' => '/* cambia este archivo para personalizar la piel monobook para el sitio entero */',
+'nodublincore' => 'Metadatos Dublin Core RDF deshabilitados en este servidor.',
+'nocreativecommons' => 'Metadatos Creative Commons RDF deshabilitados en este servidor.',
+'notacceptable' => 'El servidor wiki no puede proveer los datos en un formato que tu cliente (navegador) pueda entender.',
+'anonymous' => 'Usuario(s) anónimo(s) de {{SITENAME}}',
+'siteuser' => 'Usuario $1 de {{SITENAME}}',
+'lastmodifiedatby' => 'Esta página fue modificada por última vez en $2, $1 por $3.',
+'and' => 'y',
+'othercontribs' => 'Basado en el trabajo de $1.',
+'others' => 'otros',
+'siteusers' => 'Usuario(s) $1 de {{SITENAME}}',
+'creditspage' => 'Créditos de la página',
+'nocredits' => 'Hay información de créditos para esta página.',
+'spamprotectiontitle' => 'Filtro de protección contra spam',
+'spamprotectiontext' => 'La página que intentas guardar ha sido bloqueada por el filtro de spam. Esto se debe probablemente a alguno de los un enlaces externos incluidos en ella.
+
+La siguiente expresión regular define los enlaces que se encuentran bloqueados en este momento:',
+'spamprotectionmatch' => 'El siguiente texto es el que activó nuestro filtro \'\'anti-spam\'\' (contra la publicidad no solicitada): $1',
+'subcategorycount' => 'Hay {{PLURAL:$1|una subcategoría|$1 subcategorías}} en esta categoría.',
+'categoryarticlecount' => 'Hay $1 {{PLURAL:$1|artículo|artículos}} en esta categoría.',
+'infosubtitle' => 'Información de la página',
+'numedits' => 'Número de ediciones (artículo): $1',
+'numtalkedits' => 'Número de ediciones (página de discusión): $1',
+'numwatchers' => 'Número de usuarios vigilándola: $1',
+'numauthors' => 'Número de autores distintos (artículo): $1',
+'numtalkauthors' => 'Número de autores distintos (página de discusión): $1',
+'mw_math_png' => 'Producir siempre PNG',
+'mw_math_simple' => 'HTML si es muy simple, si no, PNG',
+'mw_math_html' => 'HTML si es posible, si no, PNG',
+'mw_math_source' => 'Dejar como TeX (para navegadores de texto)',
+'mw_math_modern' => 'Recomendado para navegadores modernos',
+'mw_math_mathml' => 'MathML',
+'markaspatrolleddiff' => 'Marcar como revisado',
+'markaspatrolledtext' => 'Marcar este artículo como revisado',
+'markedaspatrolled' => 'Marcar como revisado',
+'markedaspatrolledtext' => 'La versión seleccionada ha sido marcada como revisada.',
+'rcpatroldisabled' => 'Revisión de los Cambios Recientes deshabilitada',
+'rcpatroldisabledtext' => 'La capacidad de revisar los Cambios Recientes está deshabilitada en este momento.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Mi página de usuario\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'La página de usuario de la IP desde la que editas\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Mi página de discusión\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Discusión sobre ediciones hechas desde esta dirección IP\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Mis preferencias\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'La lista de páginas para las que estás vigilando los cambios\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Lista de mis contribuciones\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Te animamos a registrarte, aunque no es obligatorio\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Te animamos a registrarte, aunque no es obligatorio\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Salir de la sesión\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Discusión acerca del artículo\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Puedes editar esta página. Por favor, usa el botón de previsualización antes de grabar.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Añade un comentario a esta discusión\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Esta página está protegida, sólo puedes ver su código fuente\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Versiones anteriores de esta página y sus autores\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Proteger esta página\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Borrar esta página\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Restaurar las ediciones hechas a esta página antes de que fuese borrada\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Trasladar (renombrar) esta página\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Añadir esta página a tu lista de seguimiento\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Borrar esta página de tu lista de seguimiento\');
+ ta[\'search\'] = new Array(\'f\',\'Buscar en este wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Portada\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Visitar la Portada\');
+ ta[\'n-portal\'] = new Array(\'\',\'Acerca del proyecto, qué puedes hacer, dónde encontrar información\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Información de contexto sobre acontecimientos actuales\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'La lista de cambios recientes en el wiki\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Cargar una página aleatoriamente\');
+ ta[\'n-help\'] = new Array(\'\',\'El lugar para aprender\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Respáldanos\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lista de todas las páginas del wiki que enlazan con ésta\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Cambios recientes en las páginas que enlazan con esta otra\');
+ ta[\'feed-rss\'] = new Array(\'\',\'Sindicación RSS de esta página\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Sindicación Atom de esta página\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Ver la lista de contribuciones de este usuario\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Enviar un mensaje de correo a este usuario\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Subir imágenes o archivos multimedia\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lista de todas las páginas especiales\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Ver el artículo\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Ver la página de usuario\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Ver la página de multimedia\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Esta es una página especial, no se puede editar la página en sí\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Ver la página de proyecto\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Ver la página de la imagen\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Ver el mensaje de sistema\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Ver la plantilla\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Ver la página de ayuda\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Ver la página de categoría\');',
+'deletedrevision' => 'Borrada revisión antigua $1.',
+'previousdiff' => '← Ir a diferencia anterior',
+'nextdiff' => 'Ir a siguiente diferencia →',
+'imagemaxsize' => 'Limitar imágenes en las páginas de descripción a:',
+'thumbsize' => 'Tamaño de diapositivas:',
+'showbigimage' => 'Descargar versión de alta resolución ($1×$2, $3 KB)',
+'newimages' => 'Galería de imágenes nuevas',
+'noimages' => 'No hay nada que ver.',
+'specialloguserlabel' => 'Usuario:',
+'speciallogtitlelabel' => 'Título:',
+'passwordtooshort' => 'Tu contraseña es muy corta. Debe tener al menos $1 caracteres.',
+'mediawarning' => '\'\'\'Aviso\'\'\': Este archivo podría contener código malicioso, ejecutándolo tu sistema podría resultar comprometido.<hr />',
+'fileinfo' => '$1KB, tipo MIME: <code>$2</code>',
+'metadata' => 'Metadatos',
+'metadata-help' => 'Este archivo contiene información adicional (metadatos), probablemente añadida por la cámara digital, el escáner o el programa usado para crearlo o digitalizarlo. Si el archivo ha sido modificado desde su estado original, pueden haberse perdido algunos detalles.',
+'metadata-expand' => 'Mostrar datos detallados',
+'metadata-collapse' => 'Ocultar datos detallados',
+'exif-imagewidth' => 'Anchura',
+'exif-imagelength' => 'Altura',
+'exif-bitspersample' => 'Bits por componente',
+'exif-compression' => 'Esquema de compresión',
+'exif-photometricinterpretation'=> 'Composición de pixel',
+'exif-orientation' => 'Orientación',
+'exif-samplesperpixel' => 'Número de componentes',
+'exif-planarconfiguration'=> 'Distribución de datos',
+'exif-ycbcrsubsampling' => 'Razón de submuestreo de Y a C',
+'exif-ycbcrpositioning' => 'Posicionamientos Y y C',
+'exif-xresolution' => 'Resolución horizontal',
+'exif-yresolution' => 'Resolución vertical',
+'exif-resolutionunit' => 'Unidad de resolución X e Y',
+'exif-stripoffsets' => 'Localización de datos de imagen',
+'exif-rowsperstrip' => 'Número de filas por banda',
+'exif-stripbytecounts' => 'Bytes por banda comprimida',
+'exif-jpeginterchangeformat'=> 'Desplazamiento al JPEG SOI',
+'exif-jpeginterchangeformatlength'=> 'Bytes de datos JPEG',
+'exif-transferfunction' => 'Función de transferencia',
+'exif-whitepoint' => 'Cromaticidad de punto blanco',
+'exif-primarychromaticities'=> 'Cromaticidades de primaridades',
+'exif-ycbcrcoefficients'=> 'Coeficientes de matriz de transformación de espacio de color',
+'exif-referenceblackwhite'=> 'Pareja de valores negro y blanco de referencia',
+'exif-datetime' => 'Fecha y hora de modificación del archivo',
+'exif-imagedescription' => 'Título de la imagen',
+'exif-make' => 'Fabricante de la cámara',
+'exif-model' => 'Modelo de cámara',
+'exif-software' => 'Software usado',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Titular de los derechos de autor',
+'exif-exifversion' => 'Versión Exif',
+'exif-flashpixversion' => 'Versión admitida de Flashpix',
+'exif-colorspace' => 'Espacio de color',
+'exif-componentsconfiguration'=> 'Significado de cada componente',
+'exif-compressedbitsperpixel'=> 'Modo de compresión de la imagen',
+'exif-pixelydimension' => 'Anchura de imagen válida',
+'exif-pixelxdimension' => 'Altura de imagen válida',
+'exif-makernote' => 'Notas del fabricante',
+'exif-usercomment' => 'Comentarios de usuario',
+'exif-relatedsoundfile' => 'Archivo de audio relacionado',
+'exif-datetimeoriginal' => 'Fecha y hora de la generación de los datos',
+'exif-datetimedigitized'=> 'Fecha y hora de la digitalización',
+'exif-exposuretime' => 'Tiempo de exposición',
+'exif-fnumber' => 'Número F',
+'exif-exposureprogram' => 'Programa de exposición',
+'exif-spectralsensitivity'=> 'Sensibilidad espectral',
+'exif-isospeedratings' => 'Calificación de velocidad ISO',
+'exif-oecf' => 'Factor de conversión optoelectrónica',
+'exif-shutterspeedvalue'=> 'Velocidad de obturador',
+'exif-aperturevalue' => 'Apertura',
+'exif-brightnessvalue' => 'Luminosidad',
+'exif-exposurebiasvalue'=> 'Sesgo de exposición',
+'exif-maxaperturevalue' => 'Apertura máxima de tierra',
+'exif-subjectdistance' => 'Distancia al sujeto',
+'exif-meteringmode' => 'Modo de medición',
+'exif-lightsource' => 'Fuente de luz',
+'exif-focallength' => 'Longitud de la lente focal',
+'exif-subjectarea' => 'Área del sujeto',
+'exif-flashenergy' => 'Energía del flash',
+'exif-spatialfrequencyresponse'=> 'Respuesta de frecuencia espacial',
+'exif-focalplanexresolution'=> 'Resolución X plano focal',
+'exif-focalplaneyresolution'=> 'Resolución Y plano focal',
+'exif-focalplaneresolutionunit'=> 'Unidad de resolución del plano focal',
+'exif-subjectlocation' => 'Localización del sujeto',
+'exif-exposureindex' => 'Índice de exposición',
+'exif-sensingmethod' => 'Método de sensor',
+'exif-filesource' => 'Fuente de archivo',
+'exif-scenetype' => 'Tipo de escena',
+'exif-cfapattern' => 'Patrón CFA',
+'exif-customrendered' => 'Procesador personalizado de imagen',
+'exif-exposuremode' => 'Modo de exposición',
+'exif-whitebalance' => 'Balance de blanco',
+'exif-digitalzoomratio' => 'Razón de zoom digital',
+'exif-focallengthin35mmfilm'=> 'Longitud focal en película de 35 mm',
+'exif-scenecapturetype' => 'Tipo de captura de escena',
+'exif-gaincontrol' => 'Control de escena',
+'exif-contrast' => 'Contraste',
+'exif-saturation' => 'Saturación',
+'exif-sharpness' => 'Agudeza',
+'exif-devicesettingdescription'=> 'Descripción de los ajustes del dispositivo',
+'exif-subjectdistancerange'=> 'Rango de distancia al sujeto',
+'exif-imageuniqueid' => 'ID único de imagen',
+'exif-gpslatituderef' => 'Latitud norte o sur',
+'exif-gpslatitude' => 'Latitud',
+'exif-gpslongituderef' => 'Longitud este u oeste',
+'exif-gpslongitude' => 'Longitud',
+'exif-gpsaltituderef' => 'Refencia de altitud',
+'exif-gpsaltitude' => 'Altitud',
+'exif-gpssatellites' => 'Satélites usados para la medición',
+'exif-gpsmeasuremode' => 'Modo de medición',
+'exif-gpsdop' => 'Precisión de medición',
+'exif-gpsspeedref' => 'Unidad de velocidad',
+'exif-gpsspeed' => 'Velocidad del receptor GPS',
+'exif-gpsimgdirectionref'=> 'Referencia de la dirección de imágen',
+'exif-gpsimgdirection' => 'Dirección de imágen',
+'exif-gpsdestlatituderef'=> 'Referencia para la latitud del destino',
+'exif-gpsdestlatitude' => 'Destino de latitud',
+'exif-gpsdestlongituderef'=> 'Referencia para la longitud del destino',
+'exif-gpsdestlongitude' => 'Longitud del destino',
+'exif-gpsdestbearingref'=> 'Referencia para la orientación al destino',
+'exif-gpsdestbearing' => 'Orientación del destino',
+'exif-gpsdestdistanceref'=> 'Referencia para distancia al destination',
+'exif-gpsdestdistance' => 'Distancia al destino',
+'exif-gpsprocessingmethod'=> 'Nombre del método de procesado GPS',
+'exif-gpsareainformation'=> 'Nombre de la área GPS',
+'exif-gpsdatestamp' => 'Fecha GPS',
+'exif-gpsdifferential' => 'Corrección diferencial de GPS',
+'exif-compression-1' => 'No comprimida',
+'exif-orientation-2' => 'Volteada horizontalmente',
+'exif-orientation-3' => 'Rotada 180°',
+'exif-orientation-4' => 'Volteada verticalmente',
+'exif-orientation-5' => 'Rotada 90° CCW y volteada verticalmente',
+'exif-orientation-6' => 'Rotada 90° CW',
+'exif-orientation-7' => 'Rotada 90° CW y volteada verticalmente',
+'exif-orientation-8' => 'Rotada 90° CCW',
+'exif-planarconfiguration-1'=> 'formato rechoncho (chunky)',
+'exif-planarconfiguration-2'=> 'formato plano',
+'exif-componentsconfiguration-0'=> 'no existe',
+'exif-exposureprogram-0'=> 'No definido',
+'exif-exposureprogram-2'=> 'Programa normal',
+'exif-exposureprogram-3'=> 'Prioridad de apertura',
+'exif-exposureprogram-4'=> 'Prioridad de obturador',
+'exif-exposureprogram-5'=> 'Programa creativo (sesgado hacia la profundidad de campo)',
+'exif-exposureprogram-6'=> 'Action program (sesgado hacia alta velocidad de obturador)',
+'exif-exposureprogram-7'=> 'Modo retrato (para primeros planos con el fondo desenfocado)',
+'exif-exposureprogram-8'=> 'Modo panorama (para fotos panorámicas con el fondo enfocado)',
+'exif-subjectdistance-value'=> '$1 metros',
+'exif-meteringmode-0' => 'Desconocido',
+'exif-meteringmode-1' => 'Media',
+'exif-meteringmode-5' => 'Patrón',
+'exif-meteringmode-6' => 'Parcial',
+'exif-meteringmode-255' => 'Otro',
+'exif-lightsource-0' => 'Desconocido',
+'exif-lightsource-1' => 'Luz diurna',
+'exif-lightsource-2' => 'Fluorescente',
+'exif-lightsource-3' => 'Tungsteno (luz incandescente)',
+'exif-lightsource-9' => 'Buen tiempo',
+'exif-lightsource-10' => 'Tiempo nublado',
+'exif-lightsource-11' => 'Penumbra',
+'exif-lightsource-12' => 'Fluorescente de luz diurna (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Fluorescente de día soleado (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Fluorescente blanco frío (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Fluroescente blanco (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Luz estándar A',
+'exif-lightsource-18' => 'Luz estándar B',
+'exif-lightsource-19' => 'Luz estándar C',
+'exif-lightsource-24' => 'Tungsteno de estudio ISO',
+'exif-lightsource-255' => 'Otra fuente de luz',
+'exif-focalplaneresolutionunit-2'=> 'pulgadas',
+'exif-sensingmethod-1' => 'No definido',
+'exif-sensingmethod-2' => 'Sensor de área de color de un chip',
+'exif-sensingmethod-3' => 'Sensor de área de color de dos chips',
+'exif-sensingmethod-4' => 'Sensor de área de color de tres chips',
+'exif-sensingmethod-5' => 'Sensor de área secuencial de color',
+'exif-sensingmethod-7' => 'Sensor trilineal',
+'exif-sensingmethod-8' => 'Sensor lineal secuencial de color',
+'exif-scenetype-1' => 'Una imagen directamente fotografiada',
+'exif-customrendered-0' => 'Proceso normal',
+'exif-customrendered-1' => 'Proceso personalizado',
+'exif-exposuremode-0' => 'Exposición automática',
+'exif-exposuremode-1' => 'Exposición manual',
+'exif-whitebalance-0' => 'Balance de blanco automático',
+'exif-whitebalance-1' => 'Balance de blanco manual',
+'exif-scenecapturetype-0'=> 'Estándar',
+'exif-scenecapturetype-1'=> 'Paisaje',
+'exif-scenecapturetype-2'=> 'Retrato',
+'exif-scenecapturetype-3'=> 'Escena nocturna',
+'exif-gaincontrol-0' => 'Ninguna',
+'exif-contrast-1' => 'Suave',
+'exif-contrast-2' => 'Duro',
+'exif-saturation-1' => 'Baja saturación',
+'exif-saturation-2' => 'Alta saturación',
+'exif-sharpness-1' => 'Suave',
+'exif-sharpness-2' => 'Dura',
+'exif-subjectdistancerange-0'=> 'Desconocida',
+'exif-subjectdistancerange-2'=> 'Vista cercana',
+'exif-subjectdistancerange-3'=> 'Vista lejana',
+'exif-gpslatitude-n' => 'Latitud norte',
+'exif-gpslatitude-s' => 'Latitud sur',
+'exif-gpslongitude-e' => 'Longitud este',
+'exif-gpslongitude-w' => 'Longitud oeste',
+'exif-gpsmeasuremode-2' => 'Medición bidimensional',
+'exif-gpsmeasuremode-3' => 'Medición tridimensional',
+'exif-gpsspeed-k' => 'Kilómetros por hora',
+'exif-gpsspeed-m' => 'Millas por hora',
+'exif-gpsspeed-n' => 'Nudos',
+'exif-gpsdirection-t' => 'Dirección real',
+'exif-gpsdirection-m' => 'Dirección magnética',
+'edit-externally' => 'Editar este archivo usando una aplicación externa',
+'edit-externally-help' => 'Ver las [http://meta.wikimedia.org/wiki/Help:External_editors instrucciones de configuración] para más información.',
+'recentchangesall' => 'todos',
+'imagelistall' => 'todos',
+'watchlistall1' => 'todos',
+'watchlistall2' => 'todos',
+'namespacesall' => 'todos',
+'confirmemail' => 'Confirmar dirección de correo',
+'confirmemail_text' => 'Este wiki requiere que valides tu dirección de correo antes de usarlo. Pulsa el botón de abajo para enviar la confirmación.
+El correo incluirá un enlace con un código; cárgalo para confirmar la validez de tu dirección.',
+'confirmemail_send' => 'Envía el código de confimación.',
+'confirmemail_sent' => 'Confirmación de correo enviada.',
+'confirmemail_sendfailed'=> 'No fue posible enviar el correo de confirmación. Por favor, comprueba que no haya caracteres inválidos en la dirección de correo que has ingresado.',
+'confirmemail_invalid' => 'Código de confirmación incorrecto. El código debe de haber expirado.',
+'confirmemail_success' => 'Tu dirección de correo ha sido confirmada. Ahora puedes registrarte y colaborar en el wiki.',
+'confirmemail_loggedin' => 'Tu dirección de correo ha sido confirmada.',
+'confirmemail_error' => 'Algo salió mal al guardar tu confirmación.',
+'confirmemail_subject' => 'confirmación de la dirección de correo de {{SITENAME}}',
+'confirmemail_body' => 'Alguien, probablemente tú mismo, ha registrado una
+cuenta "$2" con esta dirección de correo en {{SITENAME}},
+desde la dirección IP $1.
+
+Para confirmar que esta cuenta realmente te pertenece y
+activar el correo en {{SITENAME}}, abre este enlace:
+
+$3
+
+Si la cuenta no es tuya, no sigas el enlace. El código de confirmación expirará en $4.',
+'tryexact' => 'Probar con coincidencia exacta',
+'searchfulltext' => 'Buscar por texto completo',
+'createarticle' => 'Crear artículo',
+'scarytranscludedisabled'=> '[Transclusión interwiki está deshabilitada]',
+'scarytranscludefailed' => '[Obtención de plantilla falló para $1; lo sentimos]',
+'scarytranscludetoolong'=> '[URL es demasiado larga; lo sentimos]',
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackbacks para este artículo:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Borrar])',
+'trackbackdeleteok' => 'El trackback se borró correctamente.',
+'deletedwhileediting' => 'Aviso: ¡Esta página ha sido borrada después de que iniciases la edición!',
+'confirmrecreate' => 'El usuario [[User:$1|$1]] ([[User talk:$1|discusión]]) borró este artículo después de que tú empezaces a editarlo y dio esta razón: \'\'$2\'\' Por favor, confirma que realmente deseas crear de nuevo el artículo.',
+'recreate' => 'Crear de nuevo',
+'tooltip-recreate' => 'Recupera una página que ha sido borrada',
+'redirectingto' => 'Redirigiendo a [[$1]]...',
+'confirm_purge' => '¿Vaciar la cache de esta página?
+
+$1',
+'confirm_purge_button' => 'Aceptar',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-diff' => 'v',
+'accesskey-minoredit' => 'i',
+'accesskey-preview' => 'p',
+'accesskey-save' => 's',
+'accesskey-search' => 'f',
+'accesskey-watch' => 'w',
+'allmessagesfilter' => 'Filtrar por nombre del mensaje:',
+'allmessagesmodified' => 'Mostrar sólo los modificados',
+'allpagesbadtitle' => 'El título dado era inválido o tenía un prefijo de enlace inter-idioma o inter-wiki. Puede contener uno o más caracteres que no se pueden usar en títulos.',
+'anoneditwarning' => 'No has introducido tu nombre de usuario. Tu dirección IP se guardará en el historial de edición de la página.',
+'anononlyblock' => 'sólo anon.',
+'april-gen' => 'abril',
+'articletitles' => 'Artículos que comienzan por \'\'$1\'\'',
+'august-gen' => 'agosto',
+'autoredircomment' => 'Redirigiendo a [[$1]]',
+'badaccess-group0' => 'No estás autorizado a ejecutar la acción que has solicitado.',
+'badaccess-group1' => 'La acción que has solicitado está restringida a los usuarios de uno de estos grupos: $1.',
+'badaccess-group2' => 'La acción que has solicitado está restringida a los usuarios de uno de estos grupos: $1.',
+'badaccess-groups' => 'La acción que has solicitado está restringida a los usuarios de uno de estos grupos: $1.',
+'blockededitsource' => 'El texto de \'\'\'tus ediciones\'\'\' a \'\'\'$1\'\'\' se muestran a continuación:',
+'blockedoriginalsource' => 'El código fuente de \'\'\'$1\'\'\' se muestra a continuación:',
+'boteditletter' => 'b',
+'cannotundelete' => 'Ha fallado el deshacer el borrado; alguien más puede haber deshecho el borrado antes.',
+'cantcreateaccounttext' => 'La creación de cuentas desde esta dirección IP (<b>$1</b>) ha sido bloqueada.
+Esto se debe probablemente a vandalismos persistentes desde tu escuela o tu proveedor de servicios de Internet.',
+'cantcreateaccounttitle' => 'No se puede crear la cuenta',
+'categorypage' => 'Ver página de categoría',
+'clearwatchlist' => 'Limpiar lista de seguimiento',
+'common.css' => '/* Los estilos CSS definidos aquí aplicarán a todas las pieles (skins) */',
+'confirmedittext' => 'Debes confirmar tu dirección electrónica antes de editar páginas. Por favor, establece y valida una dirección electrónica a través de tus [[Special:Preferences|preferencias de usuario]].',
+'confirmedittitle' => 'Se requiere confirmación de dirección electrónica para editar',
+'confirmemail_needlogin' => 'Necesitas $1 para confirmar tu dirección electrónica.',
+'createaccountblock' => 'Creación de cuenta bloqueada.',
+'databasenotlocked' => 'La base de datos no está bloqueada.',
+'december-gen' => 'diciembre',
+'delete_and_move_confirm' => 'Sí, borrar la página',
+'displaytitle' => '(Link to this page as [[$1]])',
+'editinginterface' => '\'\'\'Aviso:\'\'\' Estás editando una página usada para proporcionar texto a la interfaz de {{SITENAME}}. Los cambios en esta página afectarán a la apariencia de la interfaz para los demás usuarios.',
+'error' => 'Error',
+'errorpagetitle' => 'Error',
+'exportnohistory' => '----
+\'\'\'Nota:\'\'\' Exportar el historial completo de páginas a través de este formulario ha sido deshabilitado debido a problemas de rendimiento del servidor.',
+'export-submit' => 'Exportar',
+'faq' => 'FAQ',
+'february-gen' => 'febrero',
+'feed-invalid' => 'Tipo de subscripción a sindicación de noticias inválida.',
+'filewasdeleted' => 'Un archivo con este nombre se subió con anterioridad y posteriormente ha sido borrado. Deberías revisar el $1 antes de subirlo de nuevo.',
+'fri' => 'vie',
+'group' => 'Grupo:',
+'group-all' => '(todos)',
+'group-bot' => 'Bots',
+'group-bot-member' => 'Bot',
+'group-bureaucrat' => 'Burócratas',
+'group-bureaucrat-member' => 'Burócrata',
+'grouppage-bot' => 'Project:Bot',
+'grouppage-bureaucrat' => 'Project:Burócratas',
+'grouppage-sysop' => 'Project:Administradors',
+'group-sysop' => 'Administradores',
+'group-sysop-member' => 'Administrador',
+'hideresults' => 'Ocultar resultados',
+'hist' => 'hist',
+'history-feed-description' => 'Historial de revisiones para esta página en el wiki',
+'history-feed-empty' => 'La página solicitada no existe.
+Puede haber sido borrada del wiki o renombrada.
+Prueba a [[Special:Search|buscar en el wiki]] nuevas páginas relevantes.',
+'history-feed-item-nocomment' => '$1 en $2',
+'history-feed-title' => 'Historial de revisiones',
+'imagelistforuser' => 'Esto sólo muestra imágenes subidas por $1.',
+'imgdesc' => 'desc',
+'importbadinterwiki' => 'Enlace interwiki anómalo',
+'importcantopen' => 'No se puedo importar este archivo',
+'import-interwiki-history' => 'Copiar todas las versiones históricas para esta página',
+'import-interwiki-namespace' => 'Transferir páginas al espacio de nombres:',
+'import-interwiki-submit' => 'Importar',
+'import-interwiki-text' => 'Selecciona un wiki y un título de página para importar.
+Las fechas de revisiones y los nombres de editores se preservarán.
+Todas las importaciones transwiki se registran en el [[Special:Log/import|registro de importaciones]].',
+'import-logentry-interwiki' => 'transwikificada $1',
+'import-logentry-interwiki-detail' => '$1 revisión/ones desde $2',
+'import-logentry-upload' => 'importada [[$1]] por subida de archivo',
+'import-logentry-upload-detail' => '$1 revisión/ones',
+'importlogpage' => 'Registro de importaciones',
+'importlogpagetext' => 'Importaciones administrativas de páginas con historial desde otros wikis.',
+'importnopages' => 'No hay páginas que importar.',
+'import-revision-count' => '$1 revisión/ones',
+'importstart' => 'Importando páginas...',
+'importunknownsource' => 'Tipo de fuente de importación desconocida',
+'ipb_already_blocked' => '"$1" ya se encuentra bloqueado.',
+'ipbanononly' => 'Bloquear usuarios anónimos solamente',
+'ipb_cant_unblock' => '\'\'\'Error\'\'\': Número ID $1 de bloqueo no encontrado. Pudo haber sido desbloqueado ya.',
+'ipbcreateaccount' => 'Prevenir creación de cuenta de usuario.',
+'isbn' => 'ISBN',
+'istemplate' => 'inclusión',
+'january-gen' => 'enero',
+'july-gen' => 'julio',
+'june-gen' => 'junio',
+'listingcontinuesabbrev' => ' cont.',
+'listredirects' => 'Lista de redirecciones',
+'lockfilenotwritable' => 'El archivo-cerrojo de la base de datos no tiene permiso de escritura. Para bloquear o desbloquear la base de datos, este archivo tiene que ser escribible por el sesrvidor web.',
+'loginlanguagelabel' => 'Idioma: $1',
+'longpageerror' => '<strong>ERROR: El testo que has enviado ocupa $1 kilobytes, lo cual es mayor que $2 kilobytes. No se puede guardar.</strong>',
+'march-gen' => 'marzo',
+'markedaspatrollederror' => 'No se puede marcar como patrullada',
+'markedaspatrollederrortext' => 'Debes especificar una revisión para marcarla como patrullada.',
+'may-gen' => 'mayo',
+'mediawikipage' => 'Ver página de mensaje',
+'metadata-fields' => 'Los campos de metadatos EXIF que se listan en este mensaje se mostrarán en la página de descripción de la imagen aún cuando la tabla de metadatos esté plegada. Existen otros campos que se mantendrán ocultos por defecto y que podrán desplegarse.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+'metadata_help' => 'Metadata (see [[{{ns:project}}:Metadata]] for an explanation):',
+'minoreditletter' => 'm',
+'missingcommenttext' => 'Por favor introduce texto debajo.',
+'missingsummary' => '\'\'\'Atención:\'\'\' No has escrito un resumen de edición. Si haces clic nuevamente en «{{MediaWiki:Savearticle}}» tu edición se grabará sin él.',
+'mon' => 'lun',
+'newpageletter' => 'N',
+'newpages-username' => 'Nombre de usuario',
+'noexactmatch' => '<div style="border: 1px solid #ccc; padding: 7px;"><div style="background: #F9F9F9; padding: 7px">
+<div style="font-size:115%"><b>No existe ningún artículo con el título que has escrito.</b></div>
+<hr />
+<ul>
+<li>Posibles causas:
+<ul>
+<li>Puede que lo hayas <b>tecleado mal</b> o con alguna <b>falta de ortografía</b>. Comprueba el texto (recuerda que mayúsculas y acentos afectan a la búsqueda) o consulta [[{{ns:project}}:Búsqueda]]<!-- /a -->. </li>
+<li>Puede que el artículo que buscas <b>tenga otro título</b>. Prueba a repetir tu búsqueda utilizando el botón "Búsqueda" de más arriba.
+</li>
+</ul>
+</li>
+
+<li>
+Ten en cuenta que {{SITENAME}} es un wiki en desarrollo que va siendo construido poco a poco por sus visitantes. Si el artículo que buscas aún no existe, puedes crearlo siguiendo <b>[[$1|este enlace]]</b>. Puede que así otra gente vea el artículo y trate de completarlo.
+</li>
+</ul></div>
+<div style="font-size:90%; padding-left: 7px">
+<b>Muy importante:</b> en {{SITENAME}} <b>no se aceptan en ningún caso</b> textos con copyright sin el permiso explícito de sus autores. En particular, la mayoría de las páginas web (indiquen o no su autor o copyright) tienen copyright, por lo que su contenido es inadmisible aquí. Ten en cuenta que copiar este tipo de materiales <b>puede causar serios daños al proyecto</b>. Para más información, puedes leer <b>[[{{ns:project}}:Copyrights]]</b>
+</div>
+</div>',
+'nouserspecified' => 'Debes especificar un nombre de usuario.',
+'november-gen' => 'noviembre',
+'october-gen' => 'octubre',
+'ok' => 'OK',
+'revision-info' => 'Revisión a fecha de $1; $2',
+'orig' => 'orig',
+'pagetitle' => '$1 - {{SITENAME}}',
+'prefs-watchlist' => 'Seguimiento',
+'prefs-watchlist-days' => 'Número de días a mostrar en la lista de seguimiento:',
+'prefs-watchlist-edits' => 'Número de ediciones a mostrar en la lista extendida:',
+'protectedinterface' => 'Esta página provee texto del interfaz del software. Está bloqueada para evitar [[{{ns:project}}:vandalismo|vandalismos]]. Si cree que debería cambiarse el texto, hable con un [[{{ns:project}}:Administradors|Administrador]].',
+'randomredirect' => 'Ir a una redirección cualquiera',
+'rc_categories' => 'Limitar a categorías (separadas por "|")',
+'rc_categories_any' => 'Any',
+'rcshowhideanons' => '$1 usuarios anónimos',
+'rcshowhidebots' => '$1 bots',
+'rcshowhideliu' => '$1 usuarios registrados',
+'rcshowhidemine' => '$1 mis ediciones',
+'rcshowhideminor' => '$1 ediciones menores',
+'rcshowhidepatr' => '$1 ediciones patrulladas',
+'restriction-edit' => 'Pueden editar',
+'restriction-move' => 'Pueden trasladar',
+'rev-deleted-comment' => '(comentario eliminado)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Esta revisión de la página ha sido eliminada de los archivos públicos.
+puede haber detalles en el [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} registro de borrado].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Esta revisión de la página ha sido eliminada de los archivos públicos.
+Como administrador de este wiki puedes verla;
+puede haber detalles en el [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} registro de borrado].
+</div>',
+'rev-deleted-user' => '(nombre de usuario eliminado)',
+'revdelete-hide-comment' => 'Ocultar comentario de edición',
+'revdelete-hide-restricted' => 'Aplicar estas restricciones a los administradores tal como al resto',
+'revdelete-hide-text' => 'Ocultar el texto de la revisión',
+'revdelete-hide-user' => 'Ocultar el nombre/IP del editor',
+'revdelete-legend' => 'Establecer restricciones de revisión:',
+'revdelete-log' => 'Comentario de registro:',
+'revdelete-logentry' => 'cambiada la visibilidad de la revisión para [[$1]]',
+'revdelete-selected' => 'Revisión seleccionada de [[:$1]]:',
+'revdelete-submit' => 'Aplicar a la revisión seleccionada',
+'revdelete-text' => 'Las revisiones borradas aún aparecerán en el historial de la página,
+pero sus contenidos no serán accesibles al público.
+
+Otros administradores de este wiki aún podrán acceder al contenido oculto y podrán deshacer el borrado a través de la misma interfaz, a menos los operadores del sitio establezcan una restricción adicional.',
+'rev-delundel' => 'mostrar/ocultar',
+'revertimg' => 'rev',
+'revisiondelete' => 'Borrar/deshacer borrado revisiones',
+'rightslog' => 'Cambios de perfil de usuarios',
+'rightslogentry' => 'modificó los grupos a los que pertenece $1: de $2 a $3',
+'rightsnone' => 'ninguno',
+'sat' => 'sab',
+'searchcontaining' => 'Buscar artículos que contengan \'\'$1\'\'.',
+'searchnamed' => 'Buscar artículos con este nombre \'\'$1\'\'.',
+'sectionlink' => '→',
+'semiprotectedpagewarning' => '\'\'\'Nota:\'\'\' Esta página ha sido protegida para que sólo usuarios registrados puedan editarla.',
+'september-gen' => 'septiembre',
+'session_fail_preview_html' => '<strong>Lo sentimos, no hemos podido procesar tu cambio debido a una pérdida de datos de sesión.</strong>
+
+\'\'Puesto que este wiki tiene el HTML puro habilitado, la visión preliminar está oculta para prevenirse contra ataques en JavaScript.\'\'
+
+<strong>If this is a legitimate edit attempt, please try again. If it still doesn\'t work, try logging out and logging back in.</strong>',
+'showhidebots' => '($1 bots)',
+'showlivepreview' => 'Live preview',
+'sorbs' => 'SORBS DNSBL',
+'spam_blanking' => 'Todas las revisiones contienen enlaces a $1, blanqueando',
+'spambot_username' => 'Limpieza de spam de MediaWiki',
+'spam_reverting' => 'Revirtiendo a la última versión que no contenga enlaces a $1',
+'sp-contributions-newbies-sub' => 'Para nuevos',
+'sp-contributions-newer' => '< $1 posteriores',
+'sp-contributions-newest' => 'Últimas',
+'sp-contributions-older' => '$1 previas >',
+'sp-contributions-oldest' => 'Primeras',
+'sp-newimages-showfrom' => 'Mostrar nuevas imágines empezando por $1',
+'statistics-mostpopular' => 'Páginas más vistas',
+'sun' => 'dom',
+'templatepage' => 'Ver página de plantilla',
+'thu' => 'jue',
+'thumbnail_error' => 'Error al crear miniatura: $1',
+'tog-uselivepreview' => 'Usar live preview (JavaScript) (Experimental)',
+'trackbacklink' => 'Trackback',
+'tue' => 'mar',
+'unblocked' => '[[User:$1|$1]] ha sido desbloqueado',
+'uncategorizedimages' => 'Imágenes sin categorizar',
+'undeletecomment' => 'Razón para restaurar:',
+'undeletedfiles' => '$1 archivo(s) restaurados',
+'undeletedpage' => '<big>\'\'\'Se ha restaurado $1\'\'\'</big>
+
+Consulta el [[Special:Log/delete|registro de borrados]] para ver una lista de los últimos borrados / restauraciones.',
+'undeletedrevisions-files' => '$1 revisions and $2 file(s) restored',
+'undeleteextrahelp' => 'Para restaurar todas las revisiones, deja todas las casillas sin seleccionar y pulsa \'\'\'¡Restaurar!\'\'\'. Para restaurar sólo algunas revisiones, marca las revisiones que quieres restaurar y pulsa \'\'\'¡Restaurar!\'\'\'. Haciendo clic en al botón \'\'\'Nada\'\'\', se deseleccionarán todas las casillas y eliminará el comentario actual.',
+'undeletereset' => 'Nada',
+'unit-pixel' => 'px',
+'unusedtemplates' => 'Plantillas sin uso',
+'unusedtemplatestext' => 'Aquí se enumeran todas las páginas en la zona de plantillas que no están incluidas en otras páginas. Recuerda mirar lo que enlaza a las plantillas antes de borrarlas.',
+'unusedtemplateswlh' => 'otros enlaces',
+'uploaddisabledtext' => 'Las subidas de archivos están deshabilitadas en este wiki',
+'userinvalidcssjstitle' => '\'\'\'Aviso:\'\'\' No existe la piel "$1". Recuerda que las páginas personalizadas .css y .js tienen un título en minúsculas, p.e. Usuario:Foo/monobook.css en vez de Usuario:Foo/Monobook.css.',
+'variantname-sr' => 'sr',
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-zh' => 'zh',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh-tw' => 'tw',
+'viewhelppage' => 'Ver página de ayuda',
+'viewpagelogs' => 'Ver los registros de esta página',
+'viewsourcefor' => 'para $1',
+'watchlistanontext' => 'Para ver o editar las entradas de tu lista de seguimiento debes $1.',
+'watchlistclearbutton' => 'Vaciar la lista de seguimiento',
+'watchlistcleardone' => 'Tu lista de seguimiento ha sido borrada. Se eliminaron $1 elementos.',
+'watchlistcleartext' => '¿Estás seguro de querer borrarlos?',
+'watchlistcount' => '\'\'\'Tienes $1 páginas en tu lista de seguimiento, incluyendo las de discusión.\'\'\'',
+'watchlistfor' => '(para \'\'\'$1\'\'\')',
+'wed' => 'mie',
+'wldone' => 'Hecho.',
+'youhavenewmessagesmulti' => 'Tienes nuevos mensajes en $1',
+
+);
+?>
diff --git a/languages/messages/MessagesEt.php b/languages/messages/MessagesEt.php
new file mode 100644
index 000000000000..b4464eb59460
--- /dev/null
+++ b/languages/messages/MessagesEt.php
@@ -0,0 +1,898 @@
+<?php
+
+/** Estonian (Eesti)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Meedia',
+ NS_SPECIAL => 'Eri',
+ NS_MAIN => '',
+ NS_TALK => 'Arutelu',
+ NS_USER => 'Kasutaja',
+ NS_USER_TALK => 'Kasutaja_arutelu',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_arutelu',
+ NS_IMAGE => 'Pilt',
+ NS_IMAGE_TALK => 'Pildi_arutelu',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_arutelu',
+ NS_TEMPLATE => 'Mall',
+ NS_TEMPLATE_TALK => 'Malli_arutelu',
+ NS_HELP => 'Juhend',
+ NS_HELP_TALK => 'Juhendi_arutelu',
+ NS_CATEGORY => 'Kategooria',
+ NS_CATEGORY_TALK => 'Kategooria_arutelu'
+);
+
+$skinNames = array(
+ 'standard' => 'Standard',
+ 'nostalgia' => 'Nostalgia',
+ 'cologneblue' => 'Kölni sinine',
+ 'smarty' => 'Paddington',
+ 'montparnasse' => 'Montparnasse',
+ 'davinci' => 'DaVinci',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'Mu oma nahk'
+);
+
+$quickbarSettings = array(
+ 'Ei_ole', 'Püsivalt_vasakul', 'Püsivalt paremal', 'Ujuvalt vasakul'
+);
+
+#Lisasin eestimaised poed, aga võõramaiseid ei julenud kustutada.
+
+$bookstoreList = array(
+ 'Apollo' => 'http://www.apollo.ee/search.php?keyword=$1&search=OTSI',
+ 'minu Raamat' => 'http://www.raamat.ee/advanced_search_result.php?keywords=$1',
+ 'Raamatukoi' => 'http://www.raamatukoi.ee/cgi-bin/index?valik=otsing&paring=$1',
+ 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
+ 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
+ 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+
+$magicWords = array(
+ # ID CASE SYNONYMS
+ 'redirect' => array( 0, '#redirect', "#suuna" ),
+);
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+$datePreferences = array(
+ 'default',
+ 'et numeric',
+ 'dmy',
+ 'et roman',
+ 'ISO 8601'
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'et numeric',
+ 'dmy',
+ 'et roman',
+);
+
+$defaultDateFormat = 'dmy';
+
+$dateFormats = array(
+ 'et numeric time' => 'H:i',
+ 'et numeric date' => 'd.m.Y',
+ 'et numeric both' => 'd.m.Y, "kell" H:i',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. F Y',
+ 'dmy both' => 'j. F Y, "kell" H:i',
+
+ 'et roman time' => 'H:i',
+ 'et roman date' => 'j. xrm Y',
+ 'et roman both' => 'j. xrm Y, "kell" H:i',
+);
+
+$messages = array(
+"tog-underline" => "Lingid alla kriipsutada",
+"tog-highlightbroken" => "Vorminda lingirikked<a href=\"\" class=\"new\">nii</a> (alternatiiv: nii<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Lõikude rööpjoondus",
+"tog-hideminor" => "Peida pisiparandused viimastes muudatustes",
+"tog-usenewrc" => "Laiendatud viimased muudatused (mitte kõikide brauserite puhul)",
+"tog-numberheadings" => "Pealkirjade automaatnummerdus",
+"tog-showtoolbar" => "Redigeerimise tööriistariba näitamine",
+"tog-rememberpassword" => "Parooli meeldejätmine tulevasteks seanssideks",
+"tog-editwidth" => "Redaktoriboksil on täislaius",
+"tog-editondblclick" => "Artiklite redigeerimine topeltklõpsu peale (JavaScript)",
+"tog-watchdefault" => "Jälgi uusi ja muudetud artikleid",
+"tog-minordefault" => "Märgi kõik parandused vaikimisi pisiparandusteks",
+"tog-previewontop" => "Näita eelvaadet redaktoriboksi ees, mitte järel",
+
+# Dates
+'sunday' => 'pühapäev',
+'monday' => 'esmaspäev',
+'tuesday' => 'teisipäev',
+'wednesday' => 'kolmapäev',
+'thursday' => 'neljapäev',
+'friday' => 'reede',
+'saturday' => 'laupäev',
+'january' => 'jaanuar',
+'february' => 'veebruar',
+'march' => 'märts',
+'april' => 'aprill',
+'may_long' => 'mai',
+'june' => 'juuni',
+'july' => 'juuli',
+'august' => 'august',
+'september' => 'september',
+'october' => 'oktoober',
+'november' => 'november',
+'december' => 'detsember',
+'jan' => 'jaan',
+'feb' => 'veebr',
+'mar' => 'märts',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'juuni',
+'jul' => 'juuli',
+'aug' => 'aug',
+'sep' => 'sept',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dets',
+
+# Bits of text used by many pages:
+#
+'categories' => 'Kategooriad',
+'pagecategories' => 'Kategooriad',
+'category_header' => 'Selles kategoorias on "$1" artiklit',
+'subcategories' => 'Alamkategooriad',
+
+
+"mainpage" => "Esileht",
+"mainpagetext" => "Wiki tarkvara installeeritud.",
+"mainpagedocfooter" => "Juhiste saamiseks kasutamise ning konfigureerimise kohta vaata palun inglisekeelset [http://meta.wikimedia.org/wiki/MediaWiki_i18n dokumentatsiooni liidese kohaldamisest]
+ning [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide kasutusjuhendit].",
+'portal' => 'Kogukonnavärav', # Kirjutajate portaal?
+'portal-url' => '{{ns:4}}:Kogukonnavärav',
+"about" => "Tiitelandmed",
+"aboutsite" => "{{SITENAME}} tiitelandmed",
+"aboutpage" => "{{ns:4}}:Tiitelandmed",
+"article" => "Sisu", # või "Artikkel" nagu praegu Vikipeedias?
+"help" => "Juhend", # Vikipeedias "Spikker"
+"helppage" => "{{ns:12}}:Juhend",
+"bugreports" => "Teated programmivigadest",
+"bugreportspage" => "{{ns:4}}:Teated_programmivigadest",
+'sitesupport' => 'Annetused', # Set a URL in $wgSiteSupportPage in LocalSettings.php
+"faq" => "KKK",
+"faqpage" => "{{ns:4}}:KKK",
+"edithelp" => "Redigeerimisjuhend",
+"newwindow" => "(avaneb uues aknas)",
+"edithelppage" => "{{ns:12}}:Kuidas_artiklit_redigeerida",
+"cancel" => "Tühista",
+"qbfind" => "Otsi",
+"qbbrowse" => "Sirvi",
+"qbedit" => "Redigeeri",
+"qbpageoptions" => "Lehekülje suvandid", // en: this page
+"qbpageinfo" => "Lehekülje andmed", // en: context
+"qbmyoptions" => "Minu suvandid", // en: my pages
+"qbspecialpages" => "Erileheküljed",
+'moredotdotdot' => 'Veel...',
+"mypage" => "Minu lehekülg",
+"mytalk" => "Minu arutelu",
+'anontalk' => 'Arutelu selle IP jaoks',
+"currentevents" => "Jooksvad sündmused",
+"navigation" => "Navigeerimine",
+"errorpagetitle" => "Viga",
+'disclaimers' => 'Hoiatused',
+"disclaimerpage" => "{{ns:4}}:Üldised_hoiatused", # lihtsalt "Hoiatused"?
+"returnto" => "Naase $1 juurde",
+"tagline" => "Allikas: {{SITENAME}}",
+"whatlinkshere" => "Siia viitavad artiklid",
+"help" => "Juhend",
+"search" => "Otsi",
+"searchbutton" => "Otsi",
+"go" => "Mine",
+'searcharticle' => "Mine",
+"history" => "Artikli ajalugu",
+'history_short' => 'Ajalugu',
+'info_short' => 'Info',
+"printableversion" => "Prinditav versioon",
+"editthispage" => "Redigeeri seda artiklit",
+'edit' => 'Redigeeri',
+
+"delete" => "Kustuta",
+"deletethispage" => "Kustuta see artikkel",
+"undelete_short" => "Taasta $1 muudatust",
+"protect" => "Kaitse",
+"protectthispage" => "Kaitse seda artiklit",
+"unprotect" => "Ära kaitse",
+"unprotectthispage" => "Ära kaitse seda artiklit",
+"newpage" => "Uus artikkel",
+"talkpage" => "Selle artikli arutelu",
+'specialpage' => 'Erilehekülg',
+'personaltools' => 'Personaalsed tööriistad',
+'postcomment' => 'Lisa kommentaar',
+"articlepage" => "Artiklilehekülg",
+'talk' => 'Arutelu',
+'toolbox' => 'Tööriistakast',
+"userpage" => "Kasutajalehekülg",
+"projectpage" => "Metalehekülg",
+"imagepage" => "Pildilehekülg",
+"viewtalkpage" => "Arutelulehekülg",
+"otherlanguages" => "Teised keeled",
+"redirectedfrom" => "(Ümber suunatud artiklist $1)",
+"lastmodifiedat" => "Viimane muutmine: $2, $1",
+"viewcount" => "Seda lehekülge on külastatud $1 korda.",
+# aegunud, võib vist eemaldada, asendada järgmisega:
+"copyright" => "Kogu tekst on kasutatav litsentsi $1 tingimustel.",
+"protectedpage" => "Kaitstud artikkel",
+"nbytes" => "$1 baiti",
+"ok" => "OK",
+"retrievedfrom" => "Välja otsitud andmebaasist \"$1\"", # parandaks sõnastust?
+'editsection'=>'redigeeri',
+'editold'=>'redigeeri',
+'toc' => 'Sisukord',
+'showtoc' => 'näita',
+'hidetoc' => 'peida',
+'thisisdeleted' => "Vaata või taasta $1?", # View or restore...
+'restorelink' => "Kustutatud muudatuste arv: $1",
+'feedlinks' => 'Sööde:', # See sõna ei meeldi, aga paremat ei tea.
+
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Artikkel',
+'nstab-user' => 'Kasutaja',
+'nstab-media' => 'Meedia',
+'nstab-special' => 'Eri',
+'nstab-project' => 'Tiitelandmed', # about
+'nstab-image' => 'Pilt',
+'nstab-mediawiki' => 'Sõnum', # Message
+'nstab-template' => 'Mall',
+'nstab-help' => 'Juhend',
+'nstab-category' => 'Kategooria',
+
+# Main script and global functions
+#
+"nosuchaction" => "Sellist toimingut pole.",
+"nosuchactiontext" => "Wiki ei tunne sellele aadressile vastavat toimingut.",
+"nosuchspecialpage" => "Sellist erilehekülge pole.",
+"nospecialpagetext" => "Wiki ei tunne sellist erilehekülge.",
+
+
+# General errors
+#
+"error" => "Viga",
+"databaseerror" => "Andmebaasi viga",
+"dberrortext" => "Andmebaasipäringus oli süntaksiviga.
+Otsingupäring oli ebakorrektne (vaata $5) või on tarkvaras viga.
+Viimane andmebaasipäring oli:
+<blockquote><tt>$1</tt></blockquote>
+ja see kutsuti funktsioonist \"<tt>$2</tt>\".
+MySQL andis vea \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Andmebaasipäringus oli süntaksiviga.
+Viimane andmebaasipäring oli:
+\"$1\"
+ja see kutsuti funktsioonist \"$2\".
+MySQL andis vea \"$3: $4\".",
+"noconnect" => "Vabandame! Wikil on tehnilisi probleeme ning ta ei saa andmebaasiserveriga $1 ühendust",
+"nodb" => "Andmebaasi $1 ei õnnestunud kätte saada",
+'cachederror' => 'Järgnev lehekülg on puhverdatud koopia soovitud leheküljest ja ei pruugi seega olla värskeim.',
+"readonly" => "Andmebaas on hetkel kirjutuskaitse all", # 'Database locked', võimalik et siiski "Andmebaas kaitse alla"
+"enterlockreason" => "Sisesta lukustamise põhjus ning juurdepääsu taastamise ligikaudne aeg",
+"readonlytext" => "Andmebaas on praegu kirjutuskaitse all, tõenäoliselt andmebaasi rutiinseks hoolduseks, mille lõppedes normaalne olukord taastub.
+Administraator, kes selle kaitse alla võttis, andis järgmise selgituse:
+<p>$1",
+"missingarticle" => "Andmebaas ei leidnud lehekülje \"$1\" teksti, kuigi see oleks pidanud olema leitav.
+
+<p>Tavaliselt on selle põhjuseks vananenud sisuerinevuste- või ajaloolink leheküljele, mis on kustutatud.
+
+<p>Kui ei ole tegemist sellise juhtumiga, siis võib olla tegemist tarkvaraveaga. Palun teatage sellest administraatorile, märkides ära kasutatud aadressi.",
+"internalerror" => "Sisemine viga",
+"filecopyerror" => "Ei saanud faili \"$1\" failiks \"$2\" kopeerida.",
+"filerenameerror" => "Ei saanud faili \"$1\" failiks \"$2\" ümber nimetada.",
+"filedeleteerror" => "Faili nimega \"$1\" ei ole võimalik kustutada.",
+"filenotfound" => "Faili nimega \"$1\" ei leitud.",
+"unexpected" => "Ootamatu väärtus: \"$1\"=\"$2\".",
+"formerror" => "Viga: vormi ei saanud salvestada",
+"badarticleerror" => "Seda toimingut ei saa sellel leheküljel sooritada.",
+"cannotdelete" => "Seda lehekülge või pilti ei ole võimalik kustutada. (Võib-olla keegi teine juba kustutas selle.)",
+"badtitle" => "Vigane pealkiri",
+"badtitletext" => "Küsitud artiklipealkiri oli kas vigane, tühi või siis
+valesti viidatud keelte- või wikidevaheline pealkiri.",
+"perfdisabled" => "Vabandage! See funktsioon ajutiselt ei tööta, sest ta aeglustab andmebaasi kasutamist võimatuseni. Sellepärast täiustatakse vastavat programmi lähitulevikus. Võib-olla teete seda Teie!",
+'perfdisabledsub' => "Siin on salvestatud koopia $1-st:", # obsolete?
+'perfcached' => 'Järgnevad andmed on puhverdatud ja ei pruugi olla kõige värskemad:',
+'wrong_wfQuery_params' => "Valed parameeterid funktsioonile wfQuery()<br />
+Funktsioon: $1<br />
+Päring: $2",
+'viewsource' => 'Vaata lähteteksti',
+'protectedtext' => "See lehekülg on lukustatud, et muudatusi vältida. Selleks võib olla
+mitmesuguseid põhjusi, vaata palun artiklit
+[[{{ns:4}}:Lukustatud lehekülg]].
+Sa saad aga vaadata ja kopeerida selle lehekülje lähteteksti --",
+
+
+
+
+# Login and logout pages
+#
+"logouttitle" => "Väljalogimine",
+"logouttext" => "Te olete välja loginud.
+Võite kasutada süsteemi anonüümselt, aga ka sama või mõne teise kasutajana uuesti sisse logida.",
+ # rookisin Vikipeedia välja, {{SITENAME}} oleks õige, aga vajab ümbersõnastamist.
+
+"welcomecreation" => "<h2>Tere tulemast, $1!</h2><p>Teie konto on loodud. Ärge unustage seada oma eelistusi.",
+
+"loginpagetitle" => "Sisselogimine",
+"yourname" => "Teie kasutajanimi",
+"yourpassword" => "Teie parool",
+"yourpasswordagain" => "Sisestage parool uuesti",
+"remembermypassword" => "Parooli meeldejätmine tulevasteks seanssideks.",
+"loginproblem" => "<b>Sisselogimine ei õnnestunud.</b><br />Proovige uuesti!",
+"alreadyloggedin" => "<strong>Kasutaja $1, Te olete juba sisse loginud!</strong><br />",
+
+"login" => "Logi sisse",
+'loginprompt' => "{{SITENAME}} võimaldab sisselogimist vaid siis kui küpsised on lubatud.",
+"userlogin" => "Logi sisse",
+"logout" => "Logi välja",
+"userlogout" => "Logi välja",
+"createaccount" => "Loo uus konto",
+'createaccountmail' => 'meili teel',
+"badretype" => "Sisestatud paroolid ei lange kokku.",
+"userexists" => "Sisestatud kasutajanimi on juba kasutusel. Valige uus nimi.",
+"youremail" => "Teie e-posti aadress*",
+"yournick" => "Teie hüüdnimi (allakirjutamiseks)",
+'prefs-help-realname' => '* <strong>Tegelik nimi</strong> (pole kohustuslik): kui otsustate selle avaldada, kasutatakse seda Teie tööpanuse seostamiseks Teiega.<br />',
+'prefs-help-email' => '* <strong>E-post</strong> (pole kohustuslik): Võimaldab inimestel Teiega veebisaidi kaudu ühendust võtta, ilma et Te peaksite neile oma meiliaadressi avaldama, samuti on sellest kasu, kui unustate parooli.',
+
+"loginerror" => "Viga sisselogimisel",
+'nocookiesnew' => "Kasutajakonto loodi, aga sa ei ole sisse logitud, sest {{SITENAME}} kasutab kasutajate tuvastamisel küpsiseid. Sinu brauseris on küpsised keelatud. Palun sea küpsised lubatuks ja logi siis oma vastse kasutajanime ning parooliga sisse.",
+"nocookieslogin" => "{{SITENAME}} kasutab kasutajate tuvastamisel küpsiseid. Sinu brauseris on küpsised keelatud. Palun sea küpsised lubatuks ja proovi siis uuesti.",
+"noname" => "Sa ei sisestanud kasutajanime lubataval kujul.",
+"loginsuccesstitle" => "Sisselogimine õnnestus",
+"loginsuccess" => "Te olete sisse loginud. Teie kasutajanimi on \"$1\".",
+"nosuchuser" => "Kasutajat nimega \"$1\" ei ole olemas. Kontrollige kirjapilti või kasutage alljärgnevat vormi uue kasutajakonto loomiseks.",
+"wrongpassword" => "Vale parool. Proovige uuesti.",
+"mailmypassword" => "Saada mulle meili teel uus parool",
+"passwordremindertitle" => "{{SITENAME}} - unustatud salasõna",
+"passwordremindertext" => "Keegi (tõenäoliselt Teie, IP-aadressilt $1),
+palus, et me saadaksime Teile uue parooli süsteemi sisselogimiseks.
+Kasutaja \"$2\" parool on nüüd \"$3\".
+Võiksid sisse logida ja selle ajutise parooli ära muuta. <br \>
+
+Sinu {{SITENAME}}.",
+"noemail" => "Kasutaja \"$1\" meiliaadressi meil kahjuks pole.",
+"passwordsent" => "Uus parool on saadetud kasutaja \"$1\" registreeritud meiliaadressil.
+Pärast parooli saamist logige palun sisse.",
+'mailerror' => "Viga kirja saatmisel: $1",
+'acct_creation_throttle_hit' => 'Vabandame, aga te olete loonud juba $1 kontot. Rohkem te ei saa.',
+
+
+# Edit page toolbar
+'bold_sample'=>'Rasvane kiri',
+'bold_tip'=>'Rasvane kiri',
+'italic_sample'=>'Kursiiv',
+'italic_tip'=>'Kursiiv',
+'link_sample'=>'Lingitav pealkiri',
+'link_tip'=>'Siselink',
+'extlink_sample'=>'http://www.välislink.com Lingi nimi',
+'extlink_tip'=>'Välislink (ära unusta prefiksit http://)',
+'headline_sample'=>'Pealkiri',
+'headline_tip'=>'Teise taseme pealkiri',
+'math_sample'=>'Sisesta valem siia',
+'math_tip'=>'Matemaatiline tekst (LaTeX)',
+'nowiki_sample'=>'Sisesta formaatimata tekst',
+'nowiki_tip'=>'Ignoreeri viki vormindust',
+'image_sample'=>'Näidis.jpg',
+'image_tip'=>'Pilt',
+'media_sample'=>'Näidis.mp3',
+'media_tip'=>'Meediafail',
+'sig_tip'=>'Sinu allkiri koos ajatempliga',
+'hr_tip'=>'Horisontaaljoon',
+
+# Edit pages
+#
+"summary" => "Resümee",
+'subject' => 'Pealkiri',
+"minoredit" => "See on pisiparandus",
+"watchthis" => "Jälgi seda artiklit",
+"savearticle" => "Salvesta",
+"preview" => "Vaata",
+"showpreview" => "Näita eelvaadet",
+"blockedtitle" => "Kasutaja on blokeeritud",
+"blockedtext" => "Teie kasutajanime või IP-aadressi blokeeris $1.
+Tema põhjendus on järgmine:<br />''$2''<p>Küsimuse arutamiseks võite pöörduda $1 või mõne teise
+[[{{ns:4}}:administraatorid|administraatori]] poole.
+
+Pange tähele, et Te ei saa sellele kasutajale teadet saata, kui Te pole registreerinud oma [[Eri:Eelistused|eelistuste lehel]] kehtivat e-posti aadressi.
+
+Teie IP on $3. Lisage see aadress kõigile järelpärimistele, mida kavatsete teha.",
+
+'whitelistedittitle' => 'Toimetamiseks on vaja sisse logida',
+'whitelistedittext' => 'Lehekülgede toimetamiseks peate [[Eri:Userlogin|sisse logima]].',
+'whitelistreadtitle' => 'Lugemiseks peate olema sisse logitud',
+'whitelistreadtext' => 'Lehekülgede lugemiseks peate [[Eri:Userlogin|sisse logima]].',
+'whitelistacctitle' => 'Teil pole õigust kasutajakontot luua',
+'whitelistacctext' => 'Et selles Vikis kontosid luua, peate olema [[Eri:Userlogin|sisse logitud]] ja omama vastavaid õigusi.',
+
+'loginreqtitle' => 'Vajalik on sisselogimine',
+'loginreqlink' => 'sisse logima',
+'loginreqpagetext' => 'Lehekülgede vaatamiseks peate $1.',
+'accmailtitle' => 'Saadeti parool.',
+'accmailtext' => "Kasutaja '$1' parool saadeti aadressile $2.",
+
+"newarticle" => "(Uus)",
+"newarticletext" =>
+"Seda lehekülge veel ei ole.
+Lehekülje loomiseks hakake kirjutama all olevasse boksi
+(lisainfo saamiseks vaadake [[{{ns:4}}:Juhend|juhendit]]).
+Kui sattusite siia kogemata, klõpsake lihtsalt brauseri ''back''-nupule.",
+"anontalkpagetext" => "---- ''See on arutelulehekülg anonüümse kasutaja kohta, kes ei ole loonud kontot või ei kasuta seda. Sellepärast tuleb meil kasutaja identifitseerimiseks kasutada tema [[IP-aadress]]i. See IP-aadress võib olla mitmele kasutajale ühine. Kui olete anonüümne kasutaja ning leiate, et kommentaarid sellel leheküljel ei ole mõeldud Teile, siis palun [[{{ns:4}}:Kasutaja sisselogimine|looge konto või logige sisse]], et edaspidi arusaamatusi vältida.''",
+"noarticletext" => "(See lehekülg on praegu tühi)",
+'clearyourcache' => "'''Märkus:''' Pärast salvestamist pead sa muudatuste nägemiseks oma brauseri puhvri tühjendama: '''Mozilla:''' ''ctrl-shift-r'', '''IE:''' ''ctrl-f5'', '''Safari:''' ''cmd-shift-r'', '''Konqueror''' ''f5''.",
+'usercssjsyoucanpreview' => "<strong>Vihje:</strong> Kasuta nuppu 'Näita eelvaadet' oma uue css/js testimiseks enne salvestamist.",
+'usercsspreview' => "'''Ärge unustage, et seda versiooni teie isiklikust stiililehest pole veel salvestatud!'''",
+'userjspreview' => "'''Ärge unustage, et see versioon teie isiklikust javascriptist on alles salvestamata!'''",
+
+"updated" => "(Värskendatud)",
+"note" => "<strong>Meeldetuletus:</strong>",
+"previewnote" => "Ärge unustage, et see versioon ei ole veel salvestatud!",
+"previewconflict" => "See eelvaade näitab, kuidas ülemises toimetuskastis olev tekst hakkab välja nägema, kui otsustate salvestada.", ## redaktoriboks?
+"editing" => "Redigeerimisel on $1",
+'editinguser' => "Redigeerimisel on $1",
+"editconflict" => "Redigeerimiskonflikt: $1",
+"explainconflict" => "Keegi teine on muutnud seda lehekülge pärast seda, kui Teie seda redigeerima hakkasite.
+Ülemine toimetuskast sisaldab teksti viimast versiooni.
+Teie muudatused on alumises kastis.
+Teil tuleb need viimasesse versiooni üle viia.
+Kui Te klõpsate nupule
+ \"Salvesta\", siis salvestub <b>ainult</b> ülemises toimetuskastis olev tekst.<br />",
+"yourtext" => "Teie tekst",
+"storedversion" => "Salvestatud redaktsioon",
+"editingold" => "<strong>ETTEVAATUST! Te redigeerite praegu selle lehekülje vana redaktsiooni.
+Kui Te selle salvestate, siis lähevad kõik vahepealsed muudatused kaduma.</strong>",
+"yourdiff" => "Erinevused",
+/*"copyrightwarning" => "Pidage silmas, et kõik kaastööd loetakse avaldatuks vastavalt GNU Vaba Dokumentatsiooni Litsentsile
+(Üksikasjad on leheküljel $1).
+Kui Te ei soovi, et Teie poolt kirjutatut halastamatult redigeeritakse ja omal äranägemisel kasutatakse, siis ärge seda siia salvestage.<br />
+Te kinnitate ka, et kirjutasite selle ise või võtsite selle kopeerimiskitsenduseta allikast.
+<strong>ÄRGE SAATKE AUTORIÕIGUSTEGA KAITSTUD MATERJALI ILMA LOATA!</strong>", # Vikipeedia võtsin välja, {{SITENAME}} paigutada kuidagi?*/
+"longpagewarning" => "<strong>HOIATUS: Selle lehekülje pikkus ületab $1 kilobaiti. Mõne brauseri puhul valmistab raskusi juba 32-le kilobaidile läheneva pikkusega lehekülgede redigeerimine. Palun kaaluge selle lehekülje sisu jaotamist lühemate lehekülgede vahel.</strong>",
+"readonlywarning" => "<strong>HOIATUS: Andmebaas on lukustatud hooldustöödeks, nii et praegu ei saa parandusi salvestada. Võite teksti alal hoida tekstifailina ning salvestada hiljem.</strong>",
+"protectedpagewarning" => "<strong>HOIATUS: See lehekülg on lukustatud, nii et seda saavad redigeerida ainult süsteemi operaatori õigustega kasutajad. Järgige juhtnööre leheküljel
+[[Project:Juhtnöörid_kaitstud_lehekülje_kohta]]</strong>.",
+
+# History pages
+#
+"revhistory" => "Redigeerimislugu",
+"nohistory" => "Sellel leheküljel ei ole eelmisi redaktsioone.",
+"revnotfound" => "Redaktsiooni ei leitud",
+"revnotfoundtext" => "Teie poolt päritud vana redaktsiooni ei leitud.
+Palun kontrollige aadressi, millel Te seda lehekülge leida püüdsite.",
+"loadhist" => "Lehekülje ajaloo laadimine",
+"currentrev" => "Viimane redaktsioon",
+"revisionasof" => "Redaktsioon: $1",
+"cur" => "viim",
+"next" => "järg",
+"last" => "eel",
+"orig" => "orig",
+"histlegend" => "Märgi versioonid, mida tahad võrrelda ja vajuta võrdlemisnupule.
+Legend: (viim) = erinevused võrreldes viimase redaktsiooniga,
+(eel) = erinevused võrreldes eelmise redaktsiooniga, P = pisimuudatus",
+# Diffs
+#
+"difference" => "(Erinevused redaktsioonide vahel)",
+"loadingrev" => "Redaktsiooni laadimine erinevustelehekülje jaoks",
+"lineno" => "Rida $1:",
+"editcurrent" => "Redigeeri selle lehekülje viimast redaktsiooni",
+'selectnewerversionfordiff' => 'Vali võrdlemiseks uuem versioon',
+'selectolderversionfordiff' => 'Vali võrdlemiseks vanem versioon',
+'compareselectedversions' => 'Võrdle valitud versioone',
+# Search results
+#
+"searchresults" => "Otsingu tulemid",
+"searchresulttext" => "Lisainfot otsimise kohta vaata $1.",
+"searchsubtitle" => "Päring \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Päring \"$1\"",
+"badquery" => "Vigane päring",
+"badquerytext" => "Teie päringut ei saanud menetleda.
+Tõenäoliselt püüdsite otsida vähem kui kolme-tähelist sõna.
+Selline otsing ei ole praegu veel võimalik. Võib ka olla,
+et päring oli vigane, nt. \"koer and and kass\" ei ole lubatav.
+Palun proovige teistsugust päringut.",
+"matchtotals" => "Otsitud sõna \"$1\" leidub $2 artikli pealkirjas
+ning $3 artikli tekstis.",
+"titlematches" => "Tabamused artiklipealkirjades",
+"notitlematches" => "Artiklipealkirjades tabamusi ei ole",
+"textmatches" => "Tabamused artiklitekstides",
+"notextmatches" => "Artiklitekstides tabamusi ei ole",
+"prevn" => "eelmised $1",
+"nextn" => "järgmised $1",
+"viewprevnext" => "Näita ($1) ($2) ($3).",
+"showingresults" => "Allpool näitame <b>$1</b> tulemit alates tulemist #<b>$2</b>.",
+"nonefound" => "<strong>Märkus</strong>: otsingute ebaõnnestumise sagedaseks põhjuseks on asjaolu,
+et väga sageli esinevaid sõnu ei võta süsteem otsimisel arvesse. Teine põhjus võib olla
+mitme otsingusõna kasutamine (tulemusena ilmuvad ainult leheküljed, mis sisaldavad kõiki otsingusõnu).",
+"powersearch" => "Otsi",
+"powersearchtext" => "
+Otsing nimeruumidest :<br />
+$1<br />
+$2 Loetle ümbersuunamisi &nbsp; Otsi $3 $9",
+
+
+# Preferences page
+#
+"preferences" => "Teie eelistused",
+"prefsnologin" => "Te ei ole sisse loginud",
+"prefsnologintext" => "Et oma eelistusi seada, [[Special:Userlogin|tuleb Teil]]
+sisse logida.",
+"prefsreset" => "Teie eelistused on arvutimälu järgi taastatud.",
+"qbsettings" => "Kiirriba sätted",
+"changepassword" => "Muuda parool",
+"skin" => "Nahk",
+"math" => "Valemite näitamine",
+"dateformat" => "Kuupäeva formaat",
+'datedefault' => 'Eelistus puudub',
+"math_failure" => "Arusaamatu süntaks",
+"math_unknown_error" => "Tundmatu viga",
+"math_unknown_function" => "Tundmatu funktsioon",
+"math_lexing_error" => "Väljalugemisviga",
+"math_syntax_error" => "Süntaksiviga",
+"saveprefs" => "Salvesta eelistused",
+"resetprefs" => "Lähtesta eelistused",
+"oldpassword" => "Vana parool",
+"newpassword" => "Uus parool",
+"retypenew" => "Sisestage uus parool uuesti",
+"textboxsize" => "Redaktoriboksi suurus",
+"rows" => "Ridade arv",
+"columns" => "Veergude arv",
+"searchresultshead" => "Otsingutulemite sätted",
+"resultsperpage" => "Tulemeid leheküljel",
+"contextlines" => "Ridu tulemis",
+"contextchars" => "Konteksti pikkus real",
+"stubthreshold" => "Nupu näitamise lävi",
+"recentchangescount" => "Pealkirjade arv viimastes muudatustes",
+"savedprefs" => "Teie eelistused on salvestatud.",
+"timezonetext" => "Kohaliku aja ja serveri aja (maailmaaja) vahe tundides.",
+"localtime" => "Kohalik aeg",
+"timezoneoffset" => "Ajavahe",
+
+
+# Recent changes
+#
+"changes" => "muudatused",
+"recentchanges" => "Viimased muudatused",
+"recentchangestext" => "Jälgige sellel leheküljel viimaseid muudatusi.",
+"rcnote" => "Allpool on esitatud viimased <strong>$1</strong> muudatust viimase <strong>$2</strong> päeva jooksul.",
+"rcnotefrom" => "Allpool on esitatud muudatused alates <b>$2</b> (näidatakse kuni <b>$1</b> muudatust).",
+"rclistfrom" => "Näita muudatusi alates $1",
+"rclinks" => "Näita viimast $1 muudatust viimase $2 päeva jooksul.",
+"diff" => "erin",
+"hist" => "ajal",
+"hide" => "peida",
+"show" => "näita",
+"minoreditletter" => "P",
+"newpageletter" => "U",
+
+# Upload
+#
+"upload" => "Faili üleslaadimine",
+"uploadbtn" => "Üleslaadimine",
+"reupload" => "Uuesti üleslaadimine",
+"reuploaddesc" => "Tagasi üleslaadimise vormi juurde.",
+"uploadnologin" => "sisse logimata",
+"uploadnologintext" => "Kui Te soovite faile üles laadida, peate [[Special:Userlogin|sisse logima]].",
+"uploaderror" => "Viga üleslaadimisel",
+"uploadtext" => "<strong>STOPP!</strong> Enne kui sooritad üleslaadimise,
+peaksid tagama, et see järgib siinset [[{{ns:4}}:Image_use_policy|piltide kasutamise korda]].
+
+Et näha või leida eelnevalt üleslaetud pilte,
+mine vaata [[Special:Imagelist|piltide nimekirja]].
+Üleslaadimised ning kustutamised logitakse [[Special:Log/upload|üleslaadimise logis]].
+
+Järgneva vormi abil saad laadida üles uusi pilte
+oma artiklite illustreerimiseks.
+Enamikul brauseritest, näed nuppu \"Browse...\", mis viib sind
+sinu operatsioonisüsteemi standardsesse failiavamisaknasse.
+Faili valimisel sisestatakse selle faili nimi tekstiväljale
+nupu kõrval.
+Samuti pead märgistama kastikese, kinnitades sellega,
+et sa ei riku seda faili üleslaadides kellegi autoriõigusi.
+Üleslaadimise lõpuleviimiseks vajuta nupule \"Üleslaadimine\".
+See võib võtta pisut aega, eriti kui teil on aeglane internetiühendus.
+
+Eelistatud formaatideks on fotode puhul JPEG , joonistuste
+ja ikoonilaadsete piltide puhul PNG, helide jaoks aga OGG.
+Nimeta oma failid palun nõnda, et nad kirjeldaksid arusaadaval moel faili sisu, see aitab segadusi vältida.
+Pildi lisamiseks artiklile, kasuta linki kujul:
+<b><nowiki>[[image:pilt.jpg]]</nowiki></b> või <b><nowiki>[[image:pilt.png|alt. tekst]]</nowiki></b>.
+Helifaili puhul: <b><nowiki>[[media:fail.ogg]]</nowiki></b>.
+
+Pane tähele, et nagu ka ülejäänud siinsete lehekülgede puhul,
+võivad teised sinu poolt laetud faile saidi huvides
+muuta või kustutada ning juhul kui sa süsteemi kuritarvitad
+võidakse sinu ligipääs sulgeda.",
+"uploadlog" => "üleslaadimise logi",
+"uploadlogpage" => "Upload_log",
+"uploadlogpagetext" => "Järgnev on nimekiri viimastest üleslaadimistest.
+Kellaajad on märgitud serveri ajaarvamise järele (UTC).
+<ul>
+</ul>",
+"filename" => "Faili nimi",
+"filedesc" => "Lühikirjeldus",
+"copyrightpage" => "{{ns:4}}:Autoriõigused",
+"copyrightpagename" => "{{SITENAME}} ja autoriõigused",
+"uploadedfiles" => "Üleslaetud failid",
+"minlength" => "Pildi nimi peab sisaldama vähemalt kolme tähte.",
+"badfilename" => "Pildi nimi on muudetud. Uus nimi on \"$1\".",
+"badfiletype" => "\".$1\" ei ole soovitatav formaat.",
+"largefile" => "Soovitame mitte saata faile, mille suurus ületab 100 kilobaiti.",
+"successfulupload" => "Üleslaadimine õnnestus",
+"fileuploaded" => "Fail nimega \"$1\" õnnestus üles laadida.
+Palun järgi seda linki: ($2). See viib su kirjelduslehele, et saaksid esita
+asjassepuutuvad andmed faili kohta: kust on ta pärit, millal
+ja kelle poolt ta loodi, jne.",
+"uploadwarning" => "Hoiatus üleslaadimise asjus",
+"savefile" => "Salvesta fail",
+"uploadedimage" => "laadisin üles \"[[$1]]\"",
+
+# Image list
+#
+"imagelist" => "Piltide loend",
+"imagelisttext" => "Piltide arv järgnevas loendis: $1. Sorteeritud $2.", # $2 -- nt. "kuupäeva järgi".
+"getimagelist" => "hangin piltide nimekirja",
+"ilsubmit" => "Otsi",
+"showlast" => "Näita viimast $1 pilti sorteerituna $2.", # $2 nt. "nime järgi"
+"byname" => "nime järgi",
+"bydate" => "kuupäeva järgi",
+"bysize" => "suuruse järgi",
+"imgdelete" => "del",
+"imgdesc" => "kirj",
+"imglegend" => "Legend: (kirj) = näita/redigeeri pildi kirjeldust.",
+"imghistory" => "Pildi ajalugu",
+"revertimg" => "taas",
+"deleteimg" => "del",
+"deleteimgcompletely" => "del",
+"imghistlegend" => "Legend: (viim) = see on pildi viimane versioon, (del) = kustuta
+see vana versioon, (taas) = taasta see vana versioon.
+<br /><i>Klõpsa kuupäevale, et näha tookord laetud pilti.</i>.",
+"imagelinks" => "Pildilingid",
+"linkstoimage" => "Sellele pildile viitavad järgmised leheküljed:",
+"nolinkstoimage" => "Selle pildile ei viita ükski lehekülg.",
+
+# Statistics
+#
+"statistics" => "Statistika",
+"sitestats" => "Saidi statistika",
+"userstats" => "Kasutaja statistika",
+"sitestatstext" => "Lehekülgede koguarv andmebaasis: <b>$1</b>.
+
+See arv hõlmab ka arutelulehekülgi, abiartikleid Vikipeedia kohta, väga lühikesi lehekülgi (nuppe), ümbersuunamislehekülgi ning muid lehekülgi, millel tõenäoliselt ei ole entsüklopeediaartikleid. Ilma neid arvestamata on Vikipeedias praegu <b>$2</b> lehekülge, mida võib pidada artikliteks.
+
+Alates uuele programmile üleminekust 18. detsembril 2003 on lehekülgi vaadatud kokku <b>$3</b> korda ja redigeeritud kokku <b>$4</b> korda. Seega on lehekülje kohta tehtud <b>$5</b> parandust ja iga paranduse kohta tuleb <b>$5</b> vaatamist.", # viimase lausepoole võiks kohalikes seadetes eemaldada,
+ # sest see kipub mingil põhjusel olema null, tõenäoliselt praegu külastusi lihtsalt kokku ei loeta.
+ # enamasti on arvud.
+ # Võiks veel ainsust silmas pidades ühtteist ümber sõnastada, aga see esineb tõesti üliharva.
+"userstatstext" => "Registreeritud kasutajate arv: <b>$1</b>.
+Administraatori staatuses kasutajaid: <b>$2</b> (vt $3).",
+# Maintenance Page
+#
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Üksildased artiklid",
+"unusedimages" => "Kasutamata pildid",
+"popularpages" => "Populaarsed leheküljed",
+"nviews" => "Külastuste arv: $1",
+"wantedpages" => "Kõige oodatumad artiklid",
+"nlinks" => "Linkide arv: $1",
+"allpages" => "Kõik artiklid",
+"randompage" => "Juhuslik artikkel",
+"shortpages" => "Lühikesed artiklid",
+"longpages" => "Pikad artiklid",
+"listusers" => "Kasutajad",
+"specialpages" => "Erileheküljed",
+"spheading" => "Erileheküljed",
+"recentchangeslinked" => "Seotud muudatused",
+"rclsub" => "(lehekülgedel, millele \"$1\" viitab)", #
+"newpages" => "Uued leheküljed",
+'ancientpages' => 'Vanimad leheküljed',
+"intl" => "Keeltevahelised lingid",
+'move' => 'Teisalda',
+"movethispage" => "Teisalda lehekülg",
+"unusedimagestext" => "<p>Pange palun tähele, et teised
+veebisaidid, nagu nt. rahvusvahelised Vikipeediad, võivad
+linkida lehekülgedele otselinginga ja seega võivad
+siin esitatud pildid olla ikkagi aktiivses kasutuses.",
+"booksources" => "Raamatud",
+"booksourcetext" => "All on esitatud linkide loend teistesse
+saitidesse, mis müüvad uusi ja kasutatud raamatuid ning võivad
+omada lisainfot otsitavate raamatute kohta.
+{{ns:4}} ei ole nende ettevõtmistega seotud ja seda nimekirja
+ei tohiks konstrueerida reklaami tegemiseks.",
+
+# Email this user
+#
+"emailsubject" => "Subject",
+"emailmessage" => "Sõnum",
+"emailsend" => "Saada",
+"emailsent" => "E-post saadetud",
+"emailsenttext" => "Teie sõnum on saadetud.",
+
+# Watchlist
+#
+"watchlist" => "Minu jälgimisloend",
+"nowatchlist" => "Teie jälgimisloend on tühi.",
+"watchnologin" => "Ei ole sisse loginud",
+"watchnologintext" => "Jälgimisloendi muutmiseks peate [[Special:Userlogin|sisse logima]].",
+"addedwatch" => "Lisatud jälgimisloendile",
+"addedwatchtext" => "Lehekülg \"$1\" on lisatud Teie [[Special:Watchlist|jälgimisloendile]].
+Edasised muudatused sellel lehel ja sellega seotud aruteluküljel reastatakse siin
+ning [[Special:Recentchanges||viimaste muudatuste lehel]] tuuakse ta esile
+<b>rasvase</b> kirja abil.</p>
+<p>Kui tahad seda lehte hiljem jälgimisloendist eemaldada, klõpsa päisenupule \"Lõpeta jälgimine\".",
+"removedwatch" => "Jälgimisloendist eemaldatud",
+"removedwatchtext" => "Lehekülg pealkirjaga \"$1\" on Teie jälgimisloendist eemaldatud.",
+'watch' => 'Jälgi',
+"watchthispage" => "Jälgi seda lehekülge",
+"unwatchthispage" => "Lõpeta jälgimine",
+"notanarticle" => "Pole artikkel",
+
+# Delete/protect/revert
+#
+"deletepage" => "Kustuta lehekülg",
+"confirm" => "Kinnita",
+"confirmdelete" => "Kinnita kustutamine",
+"deletesub" => "(Kustutan lehekülje \"$1\")",
+"confirmdeletetext" => "Sa oled andmebaasist jäädavalt kustutamas lehte või pilti
+koos kogu tema ajalooga. Palud kinnita, et sa tahad seda tõepoolest teha, et
+sa mõistad tagajärgi ja et sinu tegevus on kooskõlas siinse
+[[{{ns:4}}:Policy|sisekorraga]].", # Project:Policy tuleks ka tõlkida
+"actioncomplete" => "Toiming sooritatud",
+"deletedtext" => "\"$1\" on kustutatud.
+Viimaste kustutuste loendit näed siit: $2.",
+"deletedarticle" => "\"$1\" kustutatud",
+"dellogpage" => "Kustutatud_leheküljed",
+"dellogpagetext" => "Allpool on esitatud nimekiri viimastest kustutamistest.
+Kõik toodud kellaajad järgivad serveriaega (UTC).
+<ul>
+</ul>",
+"deletionlog" => "Kustutatud leheküljed",
+"reverted" => "Pöörduti tagasi varasemale versioonile",
+"deletecomment" => "Kustutamise põhjus",
+"imagereverted" => "Varasemale versioonile tagasipöördumine õnnestus.",
+"rollback" => "Pöördu varasemale versioonile",
+"rollbacklink" => "taasta varasem versioon",
+"cantrollback" => "Ei saa muudatusi tagasi pöörata; viimane kaastööline on artikli ainus autor.",
+"revertpage" => "Pöörduti tagasi viimasele muudatusele, mille tegi $1",
+
+# Undelete
+"undelete" => "Taasta kustutatud lehekülg",
+"undeletepage" => "Kustutatud lehekülgede vaatamine ja taastamine",
+"undeletepagetext" => "Järgnevad leheküljed on kustutatud, kuis arhiivis
+veel olemas, neid saab taastada. Arhiivi sisu vistatakse aegajalt üle parda.",
+"undeletearticle" => "Taasta kustutatud artikkel",
+"undeleterevisions" => "Arhiveeritud versioone on $1.",
+"undeletehistory" => "Kui taastate lehekülje, taastuvad kõik versioonid artikli
+ajaloona. Kui vahepeal on loodud uus samanimeline lehekülg, ilmuvad taastatud
+versioonid varasema ajaloona. Kehtivat versiooni automaatselt välja ei vahetata.",
+"undeleterevision" => "Kustutatud versioon seisuga $1",
+"undeletebtn" => "Taasta!",
+"undeletedarticle" => "\"$1\" taastatud",
+
+# Contributions
+#
+"contributions" => "Kasutaja kaastööd",
+"mycontris" => "Minu kaastöö",
+"contribsub" => "Kasutaja \"$1\" jaoks",
+"nocontribs" => "Antud kriteeriumile vastavaid muudatusi ei leidnud.",
+"ucnote" => "Esitatakse selle kasutaja tehtud viimased <b>$1</b> muudatust viimase <b>$2</b> päeva jooksul.",
+"uclinks" => "Näita viimast $1 muudatust; viimase $2 päeva jooksul.",
+"uctop" => " (üles)" ,
+
+# What links here
+#
+"whatlinkshere" => "Viidad siia",
+"notargettitle" => "Puudub sihtlehekülg",
+"notargettext" => "Sa ei ole esitanud sihtlehekülge ega kasutajat, kelle kallal seda operatsiooni toime panna.",
+"linklistsub" => "(Linkide loend)",
+"linkshere" => "Siia viitavad järgmised leheküljed:",
+"nolinkshere" => "Siia ei viita ükski lehekülg.",
+"isredirect" => "ümbersuunamislehekülg",
+
+# Block/unblock IP
+#
+"blockip" => "Blokeeri IP-aadress",
+"blockiptext" => "Use the form below to block write access
+from a specific IP address.
+This should be done only only to prevent vandalism, and in
+accordance with [[{{ns:project}}:Policy|{{SITENAME}} policy]].
+Fill in a specific reason below (for example, citing particular
+pages that were vandalized).",
+"ipaddress" => "IP-aadress",
+"ipbreason" => "Põhjus",
+"ipbsubmit" => "Blokeeri see aadress",
+"badipaddress" => "The IP address is badly formed.",
+"blockipsuccesssub" => "Block succeeded",
+"blockipsuccesstext" => "IP-aadress \"$1\" on blokeeritud.
+<br />See [[Special:Ipblocklist|IP block list]] to review blocks.",
+"unblockip" => "Unblock IP address",
+"unblockiptext" => "Use the form below to restore write access
+to a previously blocked IP address.",
+"ipusubmit" => "Unblock this address",
+"ipblocklist" => "Blokeeritud IP-aadresside loend",
+"blocklistline" => "$1, $2 blocked $3 ($4)",
+"blocklink" => "blokeeri",
+"unblocklink" => "unblock",
+"contribslink" => "contribs",
+
+# Developer tools
+#
+"lockdb" => "Lukusta andmebaas",
+"unlockdb" => "Tee andmebaas lukust lahti",
+"lockbtn" => "Võta andmebaas kirjutuskaitse alla",
+"unlockbtn" => "Taasta andmebaasi kirjutuspääs",
+"locknoconfirm" => "You did not check the confirmation box.",
+"lockdbsuccesssub" => "Andmebaas kirjutuskaitse all",
+"unlockdbsuccesssub" => "Kirjutuspääs taastatud",
+"lockdbsuccesstext" => "Andmebaas on nüüd kirjutuskaitse all.
+<br />Kui Teie hooldustöö on läbi, ärge unustage kirjutuspääsu taastada!",
+"unlockdbsuccesstext" => "Andmebaasi kirjutuspääs on taastatud.",
+
+# Move page
+#
+"movepage" => "Teisalda artikkel",
+"movepagetext" => "Using the form below will rename a page, moving all
+of its history to the new name.
+The old title will become a redirect page to the new title.
+Links to the old page title will not be changed; be sure to
+check for double or broken redirects.
+You are responsible for making sure that links continue to
+point where they are supposed to go.
+
+Note that the page will '''not''' be moved if there is already
+a page at the new title, unless it is empty or a redirect and has no
+past edit history. This means that you can rename a page back to where
+it was just renamed from if you make a mistake, and you cannot overwrite
+an existing page.
+
+<b>ETTEVAATUST!</b>
+Võimalik, et olete tegemas ootamatut ning drastilist muudatust väga loetavasse artiklisse;
+enne muudatuse tegemist mõelge palun järele, milised võivad olla selle tagajärjed.",
+"movepagetalktext" => "Koos artiklileheküljega teisaldatakse automaatselt ka arutelulehekülg, '''välja arvatud juhtudel, kui:'''
+*liigutate lehekülge ühest nimeruumist teise,
+*uue nime all on juba olemas mittetühi arutelulehekülg või
+*jätate alumise kastikese märgistamata.
+
+Neil juhtudel teisaldage arutelulehekülg soovi korral eraldi või ühendage ta omal käel uue aruteluleheküljega.",
+"movearticle" => "Teisalda artiklilehekülg",
+"movenologin" => "Te ei ole sisse loginud",
+"movenologintext" => "Et lehekülge teisaldada, peate registreeruma
+kasutajaks ja [[Special:Userlogin|sisse logima]]",
+"newtitle" => "Uue pealkirja alla",
+"movepagebtn" => "Teisalda artikkel",
+"pagemovedsub" => "Artikkel on teisaldatud",
+"pagemovedtext" => "Artikkel \"[[$1]]\" on teisaldatud pealkirja \"[[$2]]\" alla.",
+"articleexists" => "Selle nimega artikkel on juba olemas või pole valitud nimi lubatav. Palun valige uus nimi.",
+"talkexists" => "Artikkel on teisaldatud, kuid arutelulehekülge ei saanud teisaldada, sest uue nime all on arutelulehekülg juba olemas. Palun ühendage aruteluleheküljed ise.",
+"movedto" => "Teisaldatud pealkirja alla:",
+"movetalk" => "Teisalda ka \"arutelu\", kui saab.",
+"talkpagemoved" => "Ka vastav arutelulehekülg on teisaldatud.",
+"talkpagenotmoved" => "Vastav arutelulehekülg jäi teisaldamata.",
+ #Math
+ 'mw_math_png' => "Alati PNG",
+ 'mw_math_simple' => "Kui väga lihtne, siis HTML, muidu PNG",
+ 'mw_math_html' => "Võimaluse korral HTML, muidu PNG",
+ 'mw_math_source' => "Säilitada TeX (tekstibrauserite puhul)",
+ 'mw_math_modern' => "Soovitatav moodsate brauserite puhul",
+ 'mw_math_mathml' => 'MathML',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesEu.php b/languages/messages/MessagesEu.php
new file mode 100644
index 000000000000..5f2117014797
--- /dev/null
+++ b/languages/messages/MessagesEu.php
@@ -0,0 +1,1906 @@
+<?php
+/** Basque (Euskara)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Ezein ere', 'Eskuinean', 'Ezkerrean', 'Ezkerrean mugikor'
+);
+
+$skinNames = array(
+ 'standard' => 'Lehenetsia',
+ 'nostalgia' => 'Nostalgia',
+ 'cologneblue' => 'Cologne Blue',
+ 'smarty' => 'Paddington',
+ 'montparnasse' => 'Montparnasse'
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Aparteko',
+ NS_MAIN => '',
+ NS_TALK => 'Eztabaida',
+ NS_USER => 'Lankide',
+ NS_USER_TALK => 'Lankide_eztabaida',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_eztabaida',
+ NS_IMAGE => 'Irudi',
+ NS_IMAGE_TALK => 'Irudi_eztabaida',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_eztabaida',
+ NS_TEMPLATE => 'Txantiloi',
+ NS_TEMPLATE_TALK => 'Txantiloi_eztabaida',
+ NS_HELP => 'Laguntza',
+ NS_HELP_TALK => 'Laguntza_eztabaida',
+ NS_CATEGORY => 'Kategoria',
+ NS_CATEGORY_TALK => 'Kategoria_eztabaida',
+);
+
+$messages = array(
+'tog-underline' => 'Loturak azpimarratu:',
+'tog-highlightbroken' => 'Lotura hautsiak <a href="" class="new">horrela</a> erakutsi (bestela, honela<a href="" class="internal">?</a>).',
+'tog-justify' => 'Paragrafoak justifikatu',
+'tog-hideminor' => 'Azken aldaketetan aldaketa txikiak ezkutatu',
+'tog-extendwatchlist' => 'Jarraipen zerrenda zabaldu aldaketa guztiak ikusteko',
+'tog-usenewrc' => 'Hobetutako azken aldaketak (JavaScript)',
+'tog-numberheadings' => 'Goiburukoak automatikoki zenbakitu',
+'tog-showtoolbar' => 'Aldaketen tresna-barra erakutsi (JavaScript)',
+'tog-editondblclick' => 'Klik bikoitzaren bitartez orrialdeak aldatu (JavaScript)',
+'tog-editsection' => 'Atalak [aldatu] loturen bitartez aldatzeko aukera gaitu',
+'tog-editsectiononrightclick' => 'Atalen izenburuetan klik eginez atala<br />aldatzea gaitu (JavaScript)',
+'tog-showtoc' => 'Edukien taula erakutsi (3 goiburukotik gorako orrialdeentzako)',
+'tog-rememberpassword' => 'Nire saioa ordenagailu honetan gogoratu',
+'tog-editwidth' => 'Zabalera osoko aldaketa koadroa',
+'tog-watchcreations' => 'Sortzen ditudan orrialdeak jarraipen zerrendara gehitu',
+'tog-watchdefault' => 'Aldatzen ditudan orrialdeak jarraipen zerrendara gehitu',
+'tog-minordefault' => 'Lehenetsi bezala aldaketa txiki bezala markatu guztiak',
+'tog-previewontop' => 'Aurrebista aldaketa koadroaren aurretik erakutsi',
+'tog-previewonfirst' => 'Lehen aldaketan aurrebista erakutsi',
+'tog-nocache' => 'Orrialdeen katxea ezgaitu',
+'tog-enotifwatchlistpages' => 'Jarraitzen ari naizen orrialde baten aldaketak daudenean e-posta jaso',
+'tog-enotifusertalkpages' => 'Nire eztabaida orrialdea aldatzen denean e-posta jaso',
+'tog-enotifminoredits' => 'Aldaketa txikiak direnean ere e-posta jaso',
+'tog-enotifrevealaddr' => 'Jakinarazpen mezuetan nire e-posta helbidea erakutsi',
+'tog-shownumberswatching' => 'Jarraitzen duen erabiltzaile kopurua erakutsi',
+'tog-fancysig' => 'Lotura automatikorik gabeko sinadura',
+'tog-externaleditor' => 'Lehenetsi bezala kanpoko editore bat erabili',
+'tog-externaldiff' => 'Lehenetsi bezala kanpoko diff erreminta erabili',
+'tog-showjumplinks' => '"Hona jo" irisgarritasun loturak gaitu',
+'tog-uselivepreview' => 'Zuzeneko aurrebista erakutsi (JavaScript) (Proba fasean)',
+'tog-autopatrol' => 'Mark edits I make as patrolled', // Zalantza
+'tog-forceeditsummary' => 'Aldaketaren laburpena zuri uzterakoan ohartarazi',
+'tog-watchlisthideown' => 'Jarraipen zerrendan nire aldaketak ezkutatu',
+'tog-watchlisthidebots' => 'Jarraipen zerrendan bot-en aldaketak ezkutatu',
+
+'underline-always' => 'Beti',
+'underline-never' => 'Inoiz ez',
+'underline-default' => 'Nabigatzailearen lehenetsitako balioa',
+
+'skinpreview' => '(Aurrebista)',
+
+# dates
+'sunday' => 'Igandea',
+'monday' => 'Astelehena',
+'tuesday' => 'Asteartea',
+'wednesday' => 'Asteazkena',
+'thursday' => 'Osteguna',
+'friday' => 'Ostirala',
+'saturday' => 'Larunbata',
+'sun' => 'Iga',
+'mon' => 'Asl',
+'tue' => 'Asr',
+'wed' => 'Asz',
+'thu' => 'Osg',
+'fri' => 'Osr',
+'sat' => 'Lar',
+'january' => 'Urtarrila',
+'february' => 'Otsaila',
+'march' => 'Martxoa',
+'april' => 'Apirila',
+'may_long' => 'Maiatza',
+'june' => 'Ekaina',
+'july' => 'Uztaila',
+'august' => 'Abuztua',
+'september' => 'Iraila',
+'october' => 'Urria',
+'november' => 'Azaroa',
+'december' => 'Abendua',
+'january-gen' => 'Urtarril',
+'february-gen' => 'Otsail',
+'march-gen' => 'Martxo',
+'april-gen' => 'Apiril',
+'may-gen' => 'Maiatz',
+'june-gen' => 'Ekain',
+'july-gen' => 'Uztail',
+'august-gen' => 'Abuztu',
+'september-gen' => 'Irail',
+'october-gen' => 'Urri',
+'november-gen' => 'Azaro',
+'december-gen' => 'Abendu',
+'jan' => 'Urt',
+'feb' => 'Ots',
+'mar' => 'Mar',
+'apr' => 'Api',
+'may' => 'Mai',
+'jun' => 'Eka',
+'jul' => 'Uzt',
+'aug' => 'Abu',
+'sep' => 'Ira',
+'oct' => 'Urr',
+'nov' => 'Aza',
+'dec' => 'Abe',
+# Bits of text used by many pages:
+#
+'categories' => '{{PLURAL:$1|Kategoria|Kategoriak}}',
+'category_header' => '"$1" kategoriako artikuluak',
+'subcategories' => 'Azpikategoriak',
+
+
+'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD',
+'mainpage' => 'Azala',
+'mainpagetext' => "<big>'''MediaWiki arrakastaz instalatu da.'''</big>",
+'mainpagedocfooter' => "Ikus [http://meta.wikimedia.org/wiki/Help:Contents Erabiltzaile Gida] wiki softwarea erabiltzen hasteko informazio gehiagorako.
+
+== Nola hasi ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Konfigurazio balioen zerrenda]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ (Maiz egindako galderak)]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWikiren argitalpenen posta zerrenda]",
+
+'portal' => 'Wikipediako txokoa',
+'portal-url' => 'Project:Txokoa',
+'about' => 'Honi Buruz',
+'aboutsite' => '{{SITENAME}}(e)ri buruz',
+'aboutpage' => 'Project:Honi_buruz',
+'article' => 'Artikulua',
+'help' => 'Laguntza',
+'helppage' => 'Help:Contents',
+'bugreports' => 'Programazio-erroreen jakinarazpenak',
+'bugreportspage' => 'Project:Programazio-erroreen jakinarazpenak',
+'sitesupport' => 'Dohaintzak',
+'sitesupport-url' => 'Project:Gune laguntza',
+'faq' => 'Maiz egindako galderak',
+'faqpage' => 'Project:Maiz egindako galderak',
+'edithelp' => 'Aldaketak egiteko laguntza',
+'newwindow' => '(leiho berrian irekitzen da)',
+'edithelppage' => 'Help:Aldaketak egiteko laguntza',
+'cancel' => 'Bertan behera utzi',
+'qbfind' => 'Aurkitu',
+'qbbrowse' => 'Arakatu',
+'qbedit' => 'Aldatu',
+'qbpageoptions' => 'Orrialde hau',
+'qbpageinfo' => 'Testuingurua',
+'qbmyoptions' => 'Nire orrialdeak',
+'qbspecialpages' => 'Aparteko orrialdeak',
+'moredotdotdot' => 'Gehiago...',
+'mypage' => 'Nire orrialdea',
+'mytalk' => 'Nire eztabaida',
+'anontalk' => 'IP honen eztabaida',
+'navigation' => 'Nabigazioa',
+
+# Metadata in edit box
+'metadata_help' => 'Metadata (ikus [[{{ns:project}}:Metadata]] azalpen baterako):',
+
+'currentevents' => 'Albisteak',
+'currentevents-url' => 'Albisteak',
+
+'disclaimers' => 'Mugaketak',
+'disclaimerpage' => 'Project:Erantzukizunen mugaketa orokorra',
+'privacy' => 'Pribatutasun politika',
+'privacypage' => 'wikimedia:Pribatutsan politika',
+'errorpagetitle' => 'Errorea',
+'returnto' => '$1(e)ra itzuli.',
+'tagline' => '{{SITENAME}}(e)tik',
+'help' => 'Laguntza',
+'search' => 'Bilatu',
+'searchbutton' => 'Bilatu',
+'go' => 'Joan',
+'searcharticle' => 'Joan',
+'history' => 'Orrialdearen historia',
+'history_short' => 'Historia',
+'updatedmarker' => 'nire azkeneko bisitaz geroztik eguneratuta',
+'info_short' => 'Informazioa',
+'printableversion' => 'Inprimatzeko bertsioa',
+'permalink' => 'Lotura finkoa',
+'print' => 'Inprimatu',
+'edit' => 'Aldatu',
+'editthispage' => 'Orrialde hau aldatu',
+'delete' => 'Ezabatu',
+'deletethispage' => 'Orrialde hau ezabatu',
+'undelete_short' => 'Berreskuratu {{PLURAL:$1|aldaketa bat|$1 aldaketa}}',
+'protect' => 'Babestu',
+'protectthispage' => 'Orrialde hau babestu',
+'unprotect' => 'Babesa kendu',
+'unprotectthispage' => 'Orrialde honi babesa kendu',
+'newpage' => 'Orrialde berria',
+'talkpage' => 'Orrialde honi buruz eztabaidatu',
+'specialpage' => 'Aparteko orrialdea',
+'personaltools' => 'Tresna pertsonalak',
+'postcomment' => 'Azalpen bat bidali',
+'articlepage' => 'Artikulua ikusi',
+'talk' => 'Eztabaida',
+'views' => 'Bistaratzeak',
+'toolbox' => 'Tresna taula',
+'userpage' => 'Lankide orrialdea ikusi',
+'projectpage' => 'Proiektuaren orrialdea ikusi',
+'imagepage' => 'Irudiaren orrialdea ikusi',
+'mediawikipage' => 'Mezu orrialdea ikusi',
+'templatepage' => 'Txantiloi orrialdea ikusi',
+'viewhelppage' => 'Laguntza orrialdea ikusi',
+'categorypage' => 'Kategoria orrialdea ikusi',
+'viewtalkpage' => 'Eztabaida ikusi',
+'otherlanguages' => 'Beste hizkuntzetan',
+'redirectedfrom' => '($1(e)tik birzuzenduta)',
+'autoredircomment' => '[[$1]] orrialdera birzuzentzentzen',
+'redirectpagesub' => 'Birzuzenketa orria',
+'lastmodifiedat' => 'Orrialdearen azken aldaketa: $2, $1.', //$1 date, $2 time
+'viewcount' => 'Orrialde hau {{plural:$1|behin|$1 aldiz}} bisitatu da.',
+'copyright' => 'Eduki guztia $1(r)en babespean dago.',
+'protectedpage' => 'Babestutako orrialdea',
+'jumpto' => 'Hona jo:',
+'jumptonavigation' => 'nabigazioa',
+'jumptosearch' => 'bilatu',
+
+'badaccess' => 'Baimen errorea',
+'badaccess-group0' => 'Ez daukazu ekintza hori burutzeko baimenik.',
+'badaccess-group1' => 'Ekintza hori $1 taldeko erabiltzaileei mugatuta dago.',
+'badaccess-group2' => 'Ekintza hori $1 taldeetako bateko erabiltzaileei mugatuta dago.',
+'badaccess-groups' => 'Ekintza hori $1 taldeetako batetako erabiltzaileei mugatuta dago.',
+
+'versionrequired' => 'MediaWikiren $1 bertsioa beharrezkoa da',
+'versionrequiredtext' => 'MediaWikiren $1 bertsioa beharrezkoa da orrialde hau erabiltzeko. Ikus [[Special:Version]]',
+
+'ok' => 'Ados',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => '"$1"(e)tik jasota',
+'youhavenewmessages' => '$1 dauzkazu ($2).',
+'newmessageslink' => 'Mezu berriak',
+'newmessagesdifflink' => 'azken aldaketa ikusi',
+'editsection'=>'aldatu',
+'editold'=>'aldatu',
+'editsectionhint' => 'Atala aldatu: $1',
+'toc' => 'Edukiak',
+'showtoc' => 'erakutsi',
+'hidetoc' => 'ezkutatu',
+'thisisdeleted' => '$1 ikusi edo leheneratu?',
+'viewdeleted' => '$1 ikusi?',
+'restorelink' => '{{PLURAL:$1|ezabatutako aldaketa bat|ezabatutako $1 aldaketa}}',
+'feedlinks' => 'Jarioa:',
+'feed-invalid' => 'Baliogabeko harpidetza jario mota.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Artikulua',
+'nstab-user' => 'Erabiltzaile orrialdea',
+'nstab-media' => 'Media orrialdea',
+'nstab-special' => 'Apartekoa',
+'nstab-project' => 'Proiektu orrialdea',
+'nstab-image' => 'Fitxategia',
+'nstab-mediawiki' => 'Mezua',
+'nstab-template' => 'Txantiloia',
+'nstab-help' => 'Laguntza orrialdea',
+'nstab-category' => 'Kategoria',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Ekintza hori ez da existitizen',
+'nosuchactiontext' => 'URL bidez zehaztutako ekintza ez du wikiak ezagutzen',
+'nosuchspecialpage' => 'Ez da aparteko orrialde hori existitzen',
+'nospecialpagetext' => 'Baliogabeko aparteko orrialde bat eskatu duzu; existitzen direnen zerrenda ikus dezakezu [[{{ns:special}}:Specialpages]] orrialdean.',
+
+# General errors
+#
+'error' => 'Errorea',
+'databaseerror' => 'Datu-base errorea',
+'dberrortext' => 'Datu-basean kontsulta egiterakoan sintaxi errore bat gertatu da. Baliteke softwareak bug bat izatea. Datu-basean egindako azken kontsulta:
+<blockquote><tt>$1</tt></blockquote>
+Funtzio honekin: "<tt>$2</tt>".
+MySQLk emandako errore informazioa: "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Datu-basean kontsulta egiterakoan sintaxi errore bat gertatu da. Datu-basean egindako azken kontsulta:
+"$1"
+Funtzio honekin: "$2".
+MySQLk emandako errore informazioa: "$3: $4"',
+'noconnect' => 'Sentitzen dugu! Wikian arazo teknikoak direla-eta, ezin izan da datu-basera konektatu. <br />
+$1',
+'nodb' => 'Ezin izan da $1 datu-basea hautatu',
+'cachederror' => 'Honako hau eskatutako orrialdearen katxeko kopia da, litekeena da eguneratuta ez azaltzea.',
+'laggedslavemode' => 'Oharra: Baliteke orrialde honetan azken aldaketak ez erakustea.',
+'readonly' => 'Datu-basea blokeatuta dago',
+'enterlockreason' => 'Zehaztu blokeatzeko arrazoia, noiz kenduko den jakinaraziz',
+'readonlytext' => 'Datu-basea artikulu berriak sortu edo aldaketak ez egiteko blokeatuta dago, seguruenik mantenu lanak direla-eta. Blokeo hori kentzerakoan beti bezala egongo da berriz.
+
+Blokeatu duen administratzaileak azalpen hau eman du: $1',
+'missingarticle' => 'Datu-baseak ez du aurkitu beharko lukeen orrialde baten testua aurkitu, "$1" izena duena.
+
+Arrazoia iraungitako diff bat edo ezabatutako orrialde baten historia lotura jarraitzea izan liteke.
+
+Hau ez bada zure egoera, baliteke softwarean bug bat aurkitu izana.
+Mesedez, administratzaileari jakinarazi, URLa bidaliz.',
+'readonly_lag' => 'Datu-basea automatikoki blokeatu da menpeko zerbitzariak nagusiarekin sinkronizatu bitartean',
+'internalerror' => 'Barne errorea',
+'filecopyerror' => 'Ezin izan da "$1" fitxategia "$2"(e)ra kopiatu.',
+'filerenameerror' => 'Ezin izan zaio "$1" fitxategiari "$2" izen berria eman.',
+'filedeleteerror' => 'Ezin izan da "$1" fitxategia ezabatu.',
+'filenotfound' => 'Ezin izan da "$1" fitxategia aurkitu.',
+'unexpected' => 'Espero ez zen balioa: "$1"="$2".',
+'formerror' => 'Errorea: ezin izan da formularioa bidali',
+'badarticleerror' => 'Ezin da ekintza hau orrialde honetan burutu.',
+'cannotdelete' => 'Ezin izan da zehaztutako orrialde edo fitxategia ezabatu. (Baliteke beste norbaitek ezabatu izana.)',
+'badtitle' => 'Izenburu ezegokia',
+'badtitletext' => 'Eskatutako orrialde izenburua ez da baliozkoa, hutsik dago, edo gaizki lotutako hizkuntzen arteko lotura da. Baliteke izenburuetan erabili ezin den karaktereren bat izatea.',
+'perfdisabled' => 'Sentitzen dugu! Ezaugarri hau denbora batez ezgaituta dago, wikian arazoak sortzen baititu, datu-basea motelduz.',
+'perfdisabledsub' => 'Hemen duzu $1(e)tik gordetako kopia:', # obsolete?
+'perfcached' => 'Hurrengo datuak katxean gordeta daude eta litekeena da guztiz eguneratuta ez egotea:',
+'perfcachedts' => 'Hurrengo datuak katxean daude, $1 eguneratu zen azkenekoz.',
+'wrong_wfQuery_params' => 'Baliogabeko parametroak eman zaizkio wfQuery() funtzioari<br />
+Funtzioa: $1<br />
+Kontsulta: $2',
+'viewsource' => 'Kodea ikusi',
+'viewsourcefor' => '$1',
+'protectedtext' => 'Orrialde hau blokeatu egin da aldaketak ekiditeko.
+
+Orrialde honen kodea ikusi eta kopiatu dezakezu:',
+'protectedinterface' => 'TOrrialde honek softwarearentzako interfaze testua gordetzen du eta blokeatuta dago bandalismoak saihesteko.',
+'editinginterface' => "'''Oharra:''' Softwarearentzako interfaze testua duen orrialde bat aldatzen ari zara. Orrialde honetako aldaketek erabiltzaile guztiei eragingo die.",
+'sqlhidden' => '(ezkutuko SQL kontsulta)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Saioa ixtea',
+'logouttext' => '<strong>Saioa itxi egin duzu.</strong><br />
+Erabiltzaile anonimo bezala jarraitu dezakezu {{SITENAME}} erabiltzen, edo saioa has dezakezu berriz erabiltzaile berdinarekin edo ezberdin batekin. Kontuan izan orrialde batzuk saioa hasita bazenu bezala ikus ditzakezula nabigatzailearen katxea garbitu arte.',
+
+'welcomecreation' => "== Ongi etorri, $1! ==
+
+Zure kontua sortu egin da. Ez ahaztu {{SITENAME}}(e)ko hobespenak aldatzea.",
+
+'loginpagetitle' => 'Saio hasiera',
+'yourname' => 'Erabiltzaile izena',
+'yourpassword' => 'Pasahitza',
+'yourpasswordagain' => 'Pasahitza berriz',
+'remembermypassword' => 'Nire saioa ordenagailu honetan gogoratu',
+'yourdomainname' => 'Zure domeinua',
+'externaldberror' => 'There was either an external authentication database error or you are not allowed to update your external account.', // Zalantza
+'loginproblem' => '<b>Arazoa gertatu da saioa hasterakoan.</b><br />Saiatu berriz!',
+'alreadyloggedin' => "<strong>$1, saioa hasi duzu jada!</strong><br />",
+
+'login' => 'Saioa hasi',
+'loginprompt' => 'Cookieak gaituta izatea beharrezkoa da {{SITENAME}}(e)n saioa hasteko.',
+'userlogin' => 'Saioa hasi / kontua sortu',
+'logout' => 'Saioa itxi',
+'userlogout' => 'Saioa itxi',
+'notloggedin' => 'Saioa hasi gabe',
+'nologin' => 'Ez duzu erabiltzaile konturik? $1.',
+'nologinlink' => 'Kontua sortu',
+'createaccount' => 'Kontua sortu',
+'gotaccount' => 'Baduzu erabiltzaile kontua? $1.',
+'gotaccountlink' => 'Saioa hasi',
+'createaccountmail' => 'e-postaz',
+'badretype' => 'Idatzitako pasahitzak ez dira berdinak.',
+'userexists' => 'Aukeratutako erabiltzaile izena hartuta dago. Mesedez, ezberdin bat aukeratu.',
+'youremail' => 'E-posta *:',
+'username' => 'Erabiltzaile izena:',
+'uid' => 'Erabiltzaile IDa:',
+'yourrealname' => 'Benetako izena *:',
+'yourlanguage' => 'Hizkuntza:',
+'yourvariant' => 'Aldaera',
+'yournick' => 'Erabiltzaile izena:',
+'badsig' => 'Baliogabeko sinadura; egiaztatu HTML etiketak.',
+'email' => 'E-posta',
+'prefs-help-email-enotif' => 'Helbide hau e-posta bidezko ohartarazpenak bidaltzeko ere erabiltzen da, hobespenetan gaituz gero.',
+'prefs-help-realname' => '* Benetako izena (aukerakoa): zehaztea erabakiz gero, zure lanarentzako atribuzio bezala balioko du.',
+'loginerror' => 'Errorea saioa hastean',
+'prefs-help-email' => '* E-posta (aukerakoa): Beste lankideak zurekin harremanetan jartzeko, zure nortasuna ezagutzera eman gabe.',
+'nocookiesnew' => 'Erabiltzaile kontua sortu da, baina ez da saioa hasi. {{SITENAME}}(e)k cookieak erabiltzen ditu saioekin eta ezgaituta dauzkazu. Gaitu itzazu mesedez, eta ondoren saiatu saioa hasten zure erabiltzaile izen eta pasahitz berriak erabiliz.',
+'nocookieslogin' => '{{SITENAME}}(e)k cookieak erabiltzen ditu saioekin eta ezgaituta dauzkazu. Gaitu itzazu mesedez, eta saiatu berriz.',
+'noname' => 'Ez duzu baliozko erabiltzaile izen bat zehaztu.',
+'loginsuccesstitle' => 'Saio hasiera egina',
+'loginsuccess' => "'''Saioa hasi duzu {{SITENAME}}(e)n \"$1\" izenarekin.'''",
+'nosuchuser' => 'Ez dago "$1" izena duen lankiderik. Mesedez, egiaztatu ondo idatzi duzun edo kontu berria sor ezazu.',
+'nosuchusershort' => 'Ez dago "$1" izena duen erabiltzailerik. Egiaztatu ongi idatzi duzula.',
+'nouserspecified' => 'Erabiltzaile izena zehaztu beharra daukazu.',
+'wrongpassword' => 'Pasahitza ez da zuzena. Saiatu berriz.',
+'wrongpasswordempty' => 'Pasahitza hutsik dago. Saiatu berriz.',
+'mailmypassword' => 'Pasahitza e-postaz bidali',
+'passwordremindertitle' => 'Pasahitzaren gogorarazpena {{SITENAME}}(e)tik',
+'passwordremindertext' => 'Norbaitek (zuk ziurrenik, $1 IP helbidetik)
+{{SITENAME}}(e)ko pasahitza zuri bidaltzea eskatu du ($4).
+"$2" erabiltzailearen pasahitza "$3" da orain.
+Saioa hasi eta pasahitza aldatu beharko zenuke orain.
+
+Eskaera hau beste norbaitek egin badu edo jada pasahitza gogoratu baduzu eta ez baduzu aldatu nahi, mezu honi kasurik ez egin eta jarraitu zuri pasahitz zaharra erabiltzen.',
+'noemail' => 'Ez dago "$1" erabiltzailearen e-posta helbiderik gordeta.',
+'passwordsent' => 'Pasahitz berria bidali da "$1" erabiltzailearen e-posta helbidera.
+Mesedez, saioa hasi jasotakoan.',
+'eauthentsent' => 'Egiaztapen mezu bat bidali da zehaztutako e-posta helbidera.
+Helbide horretara beste edozein mezu bidali aurretik, bertan azaltzen diren argibideak jarraitu behar dituzu, e-posta hori zurea dela egiaztatzeko.',
+'mailerror' => 'Errorea mezua bidaltzerakoan: $1',
+'acct_creation_throttle_hit' => 'Sentitzen dugu, $1 erabiltzaile kontu sortu dituzu dagoeneko. Ezin duzu gehiago sortu.',
+'emailauthenticated' => 'Zure e-posta helbidea egiaztatu zeneko data: $1.',
+'emailnotauthenticated' => 'Zure posta helbidea egiaztatu gabe dago. Ez da mezurik bidaliko hurrengo ezaugarrientzako.',
+'noemailprefs' => 'Zehaztu e-posta helbide bat ezaugarri hauek erabili ahal izateko.',
+'emailconfirmlink' => 'Egiaztatu zure e-posta helbidea',
+'invalidemailaddress' => 'Ezin da e-posta helbide hori ontzat eman baliogabeko formatua duela dirudielako. Mesedez, formatu egokia duen helbide bat zehaztu, edo hutsik utzi.',
+'accountcreated' => 'Kontua sortuta',
+'accountcreatedtext' => '$1 erabiltzaile kontua sortu egin da.',
+
+# Edit page toolbar
+'bold_sample'=>'Testu beltza',
+'bold_tip'=>'Testu beltza',
+'italic_sample'=>'Testu etzana',
+'italic_tip'=>'Testu etzana',
+'link_sample'=>'Loturaren izenburua',
+'link_tip'=>'Barne lotura',
+'extlink_sample'=>'http://www.adibidea.com loturaren izenburua',
+'extlink_tip'=>'Kanpo lotura (gogoratu http:// aurrizkia)',
+'headline_sample'=>'Goiburuko testua',
+'headline_tip'=>'2. mailako goiburukoa',
+'math_sample'=>'Formula hemen idatzi',
+'math_tip'=>'Formula matematikoa (LaTeX)',
+'nowiki_sample'=>'Formatu gabeko testua idatzi hemen',
+'nowiki_tip'=>'Ez egin jaramonik wiki formatuari',
+'image_sample'=>'Adibidea.jpg',
+'image_tip'=>'Txertatutako irudia',
+'media_sample'=>'Adibidea.ogg',
+'media_tip'=>'Media fitxategi lotura',
+'sig_tip'=>'Zure sinadura data eta orduarekin',
+'hr_tip'=>'Lerro horizontala (gutxitan erabili)',
+
+# Edit pages
+#
+'summary' => 'Laburpena',
+'subject' => 'Izenburua',
+'minoredit' => 'Hau aldaketa txikia da',
+'watchthis' => 'Orrialde hau jarraitu',
+'savearticle' => 'Orrialdea gorde',
+'preview' => 'Aurrebista',
+'showpreview' => 'Aurrebista erakutsi',
+'showlivepreview' => 'Zuzeneko aurrebista',
+'showdiff' => 'Aldaketak erakutsi',
+'anoneditwarning' => "'''Oharra:''' Ez duzu saioa hasi. Zure IP helbidea orrialde honetako historian gordeko da.",
+'missingsummary' => "'''Gogorarazpena:''' Ez duzu aldaketa laburpen bat zehaztu. Berriz ere gordetzeko aukeratzen baduzu, laburpen mezurik gordeko da.",
+'missingcommenttext' => 'Mesedez, iruzkin bat idatzi jarraian.',
+'blockedtitle' => 'Erabiltzailea blokeatuta dago',
+'blockedtext' => "Zure erabiltzaile izena edo IP helbidea $1(e)k blokeatu du. Emandako arrazoia honako hau da: ''$2'' $1 edo Wikipediako beste [[Wikipedia:Administratzaileak|administratzaile]] batekin harremanetan jarri beharko zinateke zure blokeoa eztabaidatzeko. Kontuan izan ezingo duzula \"Erabiltzaile honi e-posta bidali\" aukera erabili zure [[Aparteko:Preferences|Hobespenetan]] baliozko e-posta helbide bat definitu ezean. Zure IP helbidea $3 da. Mesedez, edozein kontsulta egiterakoan, helbide hori aipatu.",
+'blockedoriginalsource' => "Jarraian ikus daiteke '''$1'''(r)en kodea:",
+'blockededitsource' => "Jarraian ikus daitezke '''$1'''(e)n egin dituzun aldaketak:",
+'whitelistedittitle' => 'Saioa hastea beharrezkoa da aldaketak egiteko',
+'whitelistedittext' => '$1 behar duzu orrialdeak aldatu ahal izateko..',
+'whitelistreadtitle' => 'Saioa hastea beharrezkoa da irakurtzeko',
+'whitelistreadtext' => '[[Special:Userlogin|Saioa hasi]] behar duzu orrialdeak irakurtzeko.',
+'whitelistacctitle' => 'Ez daukazu kontu berri bat sortzeko baimenik',
+'whitelistacctext' => 'Wiki honetan kontu berriak sortu ahal izateko [[Special:Userlogin|saioa hasi]] eta baimena izatea beharrezko da.',
+'confirmedittitle' => 'E-posta egiaztatzea beharrezkoa da aldaketak egiteko',
+'confirmedittext' => 'Orrialdeetan aldaketak egin aurretik zure e-posta helbidea egiaztatu beharra daukazu. Mesedez, zehaztu eta egiaztatu zure e-posta helbidea [[Aparteko:Preferences|hobespenetan]].',
+'loginreqtitle' => 'Saioa hastea beharrezkoa',
+'loginreqlink' => 'saioa hasi',
+'loginreqpagetext' => 'Beste orrialde batzuk ikusteko $1 beharra daukazu..',
+'accmailtitle' => 'Pasahitza bidali da.',
+'accmailtext' => '"$1"(r)en pasahitza $2(e)ra bidali da.',
+'newarticle' => '(Berria)',
+'newarticletext' =>
+"Orrialde hau ez da existitzen oraindik. Orrialde sortu nahi baduzu, beheko koadroan idazten hasi zaitezke (ikus [[{{ns:help}}:Contents|laguntza orrialdea]] informazio gehiagorako). Hona nahi gabe etorri bazara, nabigatzaileko '''atzera''' botoian klik egin.",
+'anontalkpagetext' => "----''Honako hau konturik sortu ez edo erabiltzen ez duen erabiltzaile anonimo baten eztabaida orria da. Bere [[IP helbide]]a erabili beharko da beraz identifikatzeko. Erabiltzaile batek baino gehiagok IP bera erabil dezakete ordea. Erabiltzaile anonimoa bazara eta zurekin zerikusirik ez duten mezuak jasotzen badituzu, mesedez [[Aparteko:Userlogin|Izena eman edo saioa hasi]] etorkizunean horrelakoak gerta ez daitezen.''",
+'noarticletext' => 'Oraindik ez dago testurik orrialde honetan; beste orrialde batzuetan [[{{ns:special}}:Search/{{PAGENAME}}|bilatu dezakezu izenburu hau]] edo [{{fullurl:{{FULLPAGENAME}}|action=edit}} berau aldatu ere egin dezakezu].',
+'clearyourcache' => "'''Oharra:''' Gorde ondoren zure nabigatzailearen katxea ekidin beharko duzu aldaketak ikusteko. '''Mozilla / Firefox / Safari:''' ''Shift'' tekla sakatu birkargatzeko momentuan, edo ''Ctrl-Shift-R'' sakatu (''Cmd-Shift-R'' Apple Mac baten); '''IE:''' ''Ctrl'' tekla sakatu birkargatzeko momentuan, edo ''Ctrl-F5'' sakatu; '''Konqueror:''': Birkargatzeko klik egin, edo F5 sakatu, besterik ez; '''Opera''' erabiltzaileek ''Tresnak-Hobespenak'' atalera jo eta katxea garbitzeko aukera hautatu.",
+'usercssjsyoucanpreview' => '<strong>Laguntza:</strong> Zure CSS/JS berria gorde aurretik probatzeko \'Aurrebista erakutsi\' botoia erabili.',
+'usercsspreview' => '\'\'\'Ez ahaztu zure CSS kodea aurreikusten zabiltzala, oraindik ez dela gorde!\'\'\'',
+'userjspreview' => '\'\'\'Gogoratu zure JavaScript kodea probatu/aurreikusten zabiltzala, oraindik ez da gorde!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Oharra:\'\'\' Ez da "$1" itxura existitzen. Kontuan izan .css eta .js fitxategi pertsonalizatuen izenak letra xehez idatzi behar direla; adibidez, Lankide:Adibide/monobook.css, eta ez Lankide:Adibide/Monobook.css.',
+'updated' => '(Eguneratua)',
+'note' => '<strong>Oharra:</strong>',
+'previewnote' => '<strong>Gogoratu hau aurreikusketa bat dela, beraz gorde egin beharko duzu!</strong>',
+'session_fail_preview' => '<strong>Sentitzen dugu! Ezin izan da zure aldaketa prozesatu, saioko datu batzuen galera dela-eta. Mesedez, saiatu berriz. Arazoak jarraitzen badu, saiatu saioa amaitu eta berriz hasten.</strong>',
+'previewconflict' => 'Aurreikuspenak aldaketen koadroan idatzitako testua erakusten du, gorde ondoren agertuko den bezala.',
+'session_fail_preview_html' => '<strong>Sentitzen dugu! Ezin izan dugu zure aldaketa burutu, saio datu galera bat medio.</strong>
+
+\'\'Wiki honek HTML kodea onartzen duenez, aurreikuspena ezgaituta dago JavaScript erasoak saihestu asmoz.\'\'
+
+<strong>Aldaketa saiakera hau zuzena baldin bada, saiatu berriro mesedez. Arazoak jarraitzen badu, saiatu saioa itxi eta berriz hasten.</strong>',
+'importing' => '$1 inportatzen',
+'editing' => '$1 aldatzen',
+'editinguser' => '<b>$1</b> erabiltzailea aldatzen',
+'editingsection' => '$1 aldatzen (atala)',
+'editingcomment' => '$1 aldatzen (iruzkina)',
+'editconflict' => 'Aldaketa gatazka: $1',
+'explainconflict' => 'Zu orrialdea aldatzen hasi ondoren beste norbaitek ere aldaketak egin ditu. Goiko testu koadroan ikus daiteke orrialdeak uneotan duen edukia. Zure aldaketak beheko testu koadroan ikus daitezke. Zure testua dagoenarekin elkartu beharko duzu. Orrialdea gordetzeko erabakitzen duzun unean goiko koadroko edukia <b>bakarrik</b> gordeko da.<br />',
+'yourtext' => 'Zure testua',
+'storedversion' => 'Gordetako bertsioa',
+'nonunicodebrowser' => "<strong>OHARRA: Zure nabigatzailea ez dator Unicode arauarekin bat. Artikuluak modu seguruan aldatu ahal izateko beste sistema bat gaitu da: ASCII ez diren karaktereak kode hamaseitar bezala agertuko dira aldaketa koadroan.</strong>",
+'editingold' => "<strong>KONTUZ: Artikulu honen bertsio zahar bat aldatzen ari zara. Gorde egiten baduzu, azkenengo aldaketa baino lehenagoko aldakuntzak, ezabatuak izango dira.</strong>",
+'yourdiff' => 'Ezberdintasunak',
+'copyrightwarning' => 'Kontuan izan {{SITENAME}}(e)n egindako ekarpen guztiak $2 baldintzapean argitaratzen direla (ikus $1 informazio gehiagorako). Zure testua banatzeko baldintza hauekin ados ez bazaude, ez ezazu bidali.<br />
+Era berean, bidaltzen ari zaren edukia zuk zeuk idatzitakoa dela edo jabetza publikoko edo baliabide aske batetik kopiatu duzula zin egin ari zara.
+<strong>EZ BIDALI BAIMENIK GABEKO COPYRIGHTDUN EDUKIRIK!</strong>',
+'copyrightwarning2' => 'Mesedez, kontuan izan {{SITENAME}}(e)n egindako ekarpen guztiak besteek aldatu edo ezabatu ditzaketela. Ez baduzu besteek aldaketak egitea nahi, ez ezazu bidali.<br />
+Era berean, bidaltzen ari zaren edukia zuk zeuk idatzitakoa dela edo jabetza publikoko edo baliabide aske batetik kopiatu duzula zin egin ari zara (ikus $1 informazio gehiagorako).
+<strong>EZ BIDALI BAIMENIK GABEKO COPYRIGHTDUN EDUKIRIK!</strong>',
+'longpagewarning' => '<strong>OHARRA: Orrialde honek $1 kilobyteko tamaina du; nabigatzaile batzuek arazoak izan litzakete 32kb-tik gorako testuekin. Mesedez, saiatu orrialdea atal txikiagoetan banatzen.</strong>',
+'longpageerror' => "<strong>ERROREA: Bidali duzun testuak $1 kilobyteko luzera du, eta $2 kilobyteko maximoa baino luzeagoa da. Ezin da gorde.</strong>",
+'readonlywarning' => '<strong>OHARRA: Datu-basea blokeatu egin da mantenu lanak burutzeko, beraz ezingo dituzu orain zure aldaketak gorde. Testua fitxategi baten kopiatu dezakezu, eta beranduago erabiltzeko gorde.</strong>',
+'protectedpagewarning' => "<strong>OHARRA: Orri hau blokeaturik dago, administratzaileek soilik eraldatu dezakete. Ikusi [[Project:Babestutako orria|Babestutako Orria]].</strong>",
+'semiprotectedpagewarning' => "<strong>Oharra: Orrialde hau erregistratutako erabiltzaileek bakarrik aldatzeko babestuta dago.</strong>",
+'templatesused' => 'Orrialde honetan erabiltzen diren txantiloiak:',
+'edittools' => '<!-- Hemen jarritako testua aldaketa eta igoera formularioen azpian agertuko da. -->',
+'nocreatetitle' => 'Orrialdeak sortzea mugatuta',
+'nocreatetext' => 'Gune honek orrialde berriak sortzeko gaitasuna mugatu du. Atzera egin dezakezu existitzen den orrialde bat aldatzeko, edo [[Special:Userlogin|saio hasi edo kontua sortu]].',
+'cantcreateaccounttitle' => 'Ezin izan da kontua sortu',
+'cantcreateaccounttext' => 'IP helbide honetatik (<b>$1</b>) izena emateko aukera blokeatu egin da. Baliteke zauden eskolan edo Interneteko Zerbitzu Hornitzailean gertatuko bandalismoren batengatik gertatzea hau.',
+
+# History pages
+#
+'revhistory' => 'Berrikuspenen historiala',
+'viewpagelogs' => 'Orrialde honen erregistroak ikusi',
+'nohistory' => 'Orrialde honek ez dauka aldaketa historiarik.',
+'revnotfound' => 'Ezin izan da berrikuspena aurkitu',
+'revnotfoundtext' => "Ezin izan da eskatzen ari zaren orrialdearen berrikuspen zaharra aurkitu. Mesedez, egiaztatu orrialde honetara iristeko erabili duzun URLa.",
+'loadhist' => 'Orrialdearen historia kargatzen',
+'currentrev' => 'Oraingo berrikuspena',
+'revisionasof' => '$1(e)ko berrikuspena',
+'previousrevision' => '←Berrikuspen zaharragoa',
+'nextrevision' => 'Berrikuspen berriagoa→',
+'currentrevisionlink' => 'Oraingo berrikuspena ikusi',
+'cur' => 'orain',
+'next' => 'hurrengoa',
+'last' => 'azkena',
+'orig' => 'orij',
+'histlegend' => 'Diff hautapena: hautatu alderatu nahi dituzun bi bertsioak eta beheko botoian klik egin.<br />
+Legenda: (orain) = oraingo bertsioarekiko ezberdintasuna,
+(azkena) = aurreko bertsioarekiko ezberdintasuna, t = aldaketa txikia.',
+'deletedrev' => '[ezabatuta]',
+'histfirst' => 'Lehena',
+'histlast' => 'Azkena',
+'rev-deleted-comment' => '(iruzkina ezabatu da)',
+'rev-deleted-user' => '(erabiltzailea ezabatu da)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Orrialdearen berrikuspen hau artxibo publikoetatik kendu da. Xehetasunak [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} ezabaketa erregistroan] ikus daitezke.
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Orrialdearen berrikuspen hau artxibo publikoetatik kendu da. Guneko administratzaile bezala ikusteko aukera daukazu ordea; xehetasunak [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} ezabaketa erregistroan] ikus ditzakezu.
+</div>',
+'rev-delundel' => 'erakutsi/ezkutatu',
+
+'history-feed-title' => 'Berrikuspenen historia',
+'history-feed-description' => 'Wikiko orrialde honen berrikuspenen historia',
+'history-feed-item-nocomment' => 'nork: $1 noiz: $2', # user at time
+'history-feed-empty' => 'Eskatutako orrialdea ez da existitzen. Baliteke wikitik ezabatu edo izenez aldatu izana. Saiatu [[Special:Search|wikian zerikusia duten orrialdeak bilatzen]].',
+
+# Revision deletion
+#
+'revisiondelete' => 'Berrikuspenak ezabatu/leheneratu',
+'revdelete-nooldid-title' => 'Helburu berrikuspenik ez',
+'revdelete-nooldid-text' => 'Ez d(it)uzu eragiketa hau burutzeko helburu berrikuspena(k) zehaztu.',
+'revdelete-selected' => '[[:$1]](r)en hautatutako berrikuspena:',
+'revdelete-text' => "Ezabatutako berrikuspenek orrialdearen historian agertzen jarraituko dute, baina bere edukiak ez dira publikoki eskuratu ahal izango.
+
+Wiki honetako beste administratzaileek ezkutuko eduki hau ikusteko aukera izango dute, eta baita leheneratzeko ere, gunearen arduradunek beste mugapenen bat ezartzen ez badute behintzat.",
+'revdelete-legend' => 'Berrikuspen mugapenak ezarri:',
+'revdelete-hide-text' => 'Berrikuspenaren testua ezkutatu',
+'revdelete-hide-comment' => 'Aldaketaren iruzkina ezkutatu',
+'revdelete-hide-user' => 'Egilearen erabiltzaile izena/IPa ezkutatu',
+'revdelete-hide-restricted' => 'Mugapen hauek administratzaileei zein besteei aplikatu',
+'revdelete-log' => 'Erregistroaren iruzkina:',
+'revdelete-submit' => 'Hautatutako berrikuspenari aplikatu',
+'revdelete-logentry' => '[[$1]](r)entzako berriskupen ikusgaitasuna aldatu da',
+
+# Diffs
+#
+'difference' => '(Bertsioen arteko ezberdintasunak)',
+'loadingrev' => 'diff-entzako berrikuspena eskuratzen',
+'lineno' => "$1. lerroa:",
+'editcurrent' => 'Orrialdearen oraingo bertsioa aldatu',
+'selectnewerversionfordiff' => 'Hautatu bertsio berriago bat konparaketa egiteko',
+'selectolderversionfordiff' => 'Hautatu bertsio zaharrago bat konparaketa egiteko',
+'compareselectedversions' => 'Hautatutako bertsioak alderatu',
+
+# Search results
+#
+'searchresults' => 'Bilaketaren emaitzak',
+'searchresulttext' => "{{SITENAME}}(e)n bilaketak egiteko informazio gehiagorako, ikus [[Project:Bilaketa|{{SITENAME}}(e)n bilatzen]].",
+'searchsubtitle' => "'''[[:$1]]''' bilatu duzu",
+'searchsubtitleinvalid' => "'''$1''' bilatu duzu",
+'badquery' => 'Gaizki osatutako bilaketa katea',
+'badquerytext' => 'Ezin izan dugu zure kontsulta burutu. Baliteke hau hiru letra baino laburragoa den hitz bat bilatzen saiatzeagatik izatea, eta hori ezin da egin. Litekeena da ere adierazpena gaizki idatzi izana, adibidez "euskal euskal herria". Saiatu beste kontsulta batekin mesedez.',
+'matchtotals' => "\"$1\" bilaketak $2 orrialde izenburu eta $3 orrialderen testu aurkitu ditu.",
+'noexactmatch' => "'''Ez dago \"$1\" izenburua duen orrialderik.''' [[:$1|Orrialde hau]] sortu dezakezu.",
+'titlematches' => 'Emaitzak artikuluen izenburuetan',
+'notitlematches' => 'Ez dago bat datorren orrialde izenbururik',
+'textmatches' => 'Emaitza orrialde testuetan',
+'notextmatches' => 'Ez dago bat datorren orrialde testurik',
+'prevn' => "aurreko $1ak",
+'nextn' => "hurrengo $1ak",
+'viewprevnext' => "Ikusi ($1) ($2) ($3).",
+'showingresults' => "Jarraian <b>$1</b> emaitz ikus daitezke, <b>$2</b>.etik hasita.",
+'showingresultsnum' => "Hasieran #<b>$2</b> duten <b>$3</b> emaitza erakusten dira jarraian.",
+'nonefound' => "'''Oharra''': Arrakastarik gabeko bilaketen arrazoi nagusietako bat \"dute\" eta \"da\" bezalako hitz arruntak bilatzea izan ohi da, edo baita bilaketan hitz gehiegi zehazteagatik ere (emaitzetan hitz guztiak dituzten emaitzak baino ez dira azalduko).",
+'powersearch' => 'Bilatu',
+'powersearchtext' => "Izen-tarte hauetan bilatu:<br />$1<br />$2 Birzuzenketen zerrenda<br />$3 $9 bilatu",
+'searchdisabled' => '{{SITENAME}}(e)n ezgaituta dago bilaketa. Dena dela, Google erabiliz ere egin dezakezu bilaketa. Kontuan izan bertan dituzten {{SITENAME}}(e)ko emaitzak zaharkituta egon daitezkeela.',
+
+'blanknamespace' => '(Nagusia)',
+
+# Preferences page
+#
+'preferences' => 'Hobespenak',
+'mypreferences' => 'Nire hobespenak',
+'prefsnologin' => 'Saioa hasi gabe',
+'prefsnologintext' => "[[Special:Userlogin|Saioa hasi behar duzu]] zure hobespenak ezartzeko.",
+'prefsreset' => 'Hobespenak hasieratu egin dira.',
+'qbsettings' => 'Laster-barra',
+'changepassword' => 'Pasahitza aldatu',
+'skin' => 'Itxura',
+'math' => 'Math',
+'dateformat' => 'Data formatua',
+'datedefault' => 'Hobespenik ez',
+'datetime' => 'Data eta ordua',
+'math_failure' => 'Interpretazio errorea',
+'math_unknown_error' => 'errore ezezaguna',
+'math_unknown_function' => 'funtzio ezezaguna',
+'math_lexing_error' => 'errore lexikoa',
+'math_syntax_error' => 'sintaxi errorea',
+'math_image_error' => 'PNG bilakatze errorea; egiaztatu latex, dvips, gs eta convert ongi instalatuta daudela',
+'math_bad_tmpdir' => 'Ezin da math direktorio tenporala sortu edo bertan idatzi',
+'math_bad_output' => 'Ezin da math direktorioa sortu edo bertan idatzi',
+'math_notexvc' => 'texvc exekutagarria falta da; mesedez, ikus math/README konfiguratzeko.',
+'prefs-personal' => 'Erabiltzaile profila',
+'prefs-rc' => 'Azken aldaketak',
+'prefs-watchlist' => 'Jarraipen zerrenda',
+'prefs-watchlist-days' => 'Jarraipen zerrendan erakutsi beharreko egun kopurua:',
+'prefs-watchlist-edits' => 'Jarraipen zerrendan erakutsi beharreko aldaketa kopurua:',
+'prefs-misc' => 'Denetarik',
+'saveprefs' => 'Gorde',
+'resetprefs' => 'Hasieratu',
+'oldpassword' => 'Pasahitz zaharra:',
+'newpassword' => 'Pasahitz berria:',
+'retypenew' => 'Pasahitz berria berriz idatzi:',
+'textboxsize' => 'Aldatzen',
+'rows' => 'Lerroak:',
+'columns' => 'Zutabeak:',
+'searchresultshead' => 'Bilaketa',
+'resultsperpage' => 'Emaitza orrialdeko:',
+'contextlines' => 'Lerro emaitzako:',
+'contextchars' => 'Lerro bakoitzeko karaktere kopurua:',
+'stubthreshold' => 'Zirriborroak erakusteko muga:',
+'recentchangescount' => 'Aldaketa berrietako izenburu kopurua:',
+'savedprefs' => 'Zure hobespenak gorde egin dira.',
+'timezonelegend' => 'Ordu zona',
+'timezonetext' => 'Zure ordu lokala eta zerbitzariaren orduaren (UTC) arteko ezberdintasuna.',
+'localtime' => 'Ordu lokala',
+'timezoneoffset' => 'Ezberdintasuna¹',
+'servertime' => 'Zerbitzariko ordua',
+'guesstimezone' => 'Nabigatzailetik jaso',
+'allowemail' => 'Beste erabiltzaileengandik e-posta mezuak jasotzea gaitu',
+'defaultns' => 'Izen-tarte hauetan bilatu lehenetsitzat:',
+'default' => 'lehenetsia',
+'files' => 'Fitxategiak',
+
+# User rights
+'userrights-lookup-user' => 'Erabiltzaile taldeak kudeatu',
+'userrights-user-editname' => 'Erabiltzaile izena idatzi:',
+'editusergroup' => 'Erabiltzaile taldeak editatu',
+
+'userrights-editusergroup' => 'Erabiltzaile taldeak editatu',
+'saveusergroups' => 'Erabiltzaile taldeak gorde',
+'userrights-groupsmember' => 'Partaide da hemen:',
+'userrights-groupsavailable' => 'Existitzen diren taldeak:',
+'userrights-groupshelp' => 'Hautatu erabiltzaileari gehitu edo kendu nahi dizkiozun taldeak. Deshautatutako taldeak ez dira aldatuko. Talde bat deshautatu dezakezu CTRL + Ezker Klika eginez',
+
+# Groups
+'group' => 'Taldea:',
+'group-bot' => 'Bot-ak',
+'group-sysop' => 'Administratzaileak',
+'group-bureaucrat' => 'Burokratak',
+'group-all' => '(guztiak)',
+
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Administratzaile',
+'group-bureaucrat-member' => 'Burokrata',
+
+'grouppage-bot' => '{{ns:project}}:Bot-ak',
+'grouppage-sysop' => '{{ns:project}}:Administratzaileak',
+'grouppage-bureaucrat' => '{{ns:project}}:Burokratak',
+
+# Recent changes
+#
+'changes' => 'aldaketak',
+'recentchanges' => 'Aldaketa berriak',
+'recentchangestext' => 'Orrialde honetan wiki honetan egindako azken aldaketak erakusten dira.',
+'rcnote' => "Jarraian azken <strong>$2</strong> egunetako azken <strong>$1</strong> aldaketak erakusten dira, $3 eguneratuta.",
+'rcnotefrom' => "Jarraian azaltzen diren aldaketak data honetatik aurrerakoak dira: <b>$2</b> (gehienez <b>$1</b> erakusten dira).",
+'rclistfrom' => "Erakutsi $1 ondorengo aldaketa berriak",
+'rcshowhideminor' => '$1 aldaketa txikiak',
+'rcshowhidebots' => '$1 bot-ak',
+'rcshowhideliu' => '$1 erabiltzaile erregistratuak',
+'rcshowhideanons' => '$1 anonimoak',
+'rcshowhidepatr' => '$1 patruilatutako aldaketak',
+'rcshowhidemine' => '$1 nire aldaketak',
+'rclinks' => "Erakutsi azken $1 aldaketak $2 egunetan.<br>$3",
+'diff' => 'ezb',
+'hist' => 'hist',
+'hide' => 'Ezkutatu',
+'show' => 'Erakutsi',
+'minoreditletter' => 't',
+'newpageletter' => 'B',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 jarraitzaile]',
+'rc_categories' => 'Kategorietara mugatu ("|" karaktereaz banandu)',
+'rc_categories_any' => 'Edozein',
+
+# Upload
+#
+'upload' => 'Fitxategia igo',
+'uploadbtn' => 'Fitxategia igo',
+'reupload' => 'Berriz igo',
+'reuploaddesc' => 'Igotzeko formulariora itzuli.',
+'uploadnologin' => 'Saioa hasi gabe',
+'uploadnologintext' => "Fitxategiak igotzeko [[Aparteko:Userlogin|saioa hasi]] behar duzu.",
+'upload_directory_read_only' => 'Web zerbitzariak ez dauka igoera direktorioan ($1) idazteko baimenik.',
+'uploaderror' => 'Errorea igotzerakoan',
+'uploadtext' => "Fitxategiak igotzeko beheko formularioa erabil dezakezu. Aurretik igotako irudiak ikusi edo bilatzeko [[Special:Imagelist|igotako fitxategien zerrendara]] jo. Igoerak eta ezabatutakoak [[Special:Log/upload|igoera erregistroan]] zerrendatzen dira.
+
+Orrialde baten irudi bat txertatzeko, erabili kode hauetako bat:
+'''<nowiki>[[{{ns:image}}:Fitxategia.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:Fitxategia.png|testu alternatiboa]]</nowiki>''' edo
+'''<nowiki>[[{{ns:media}}:Fitxategia.ogg]]</nowiki>''' irudia zuzenean erabiltzeko.",
+'uploadlog' => 'igoera erregistroa',
+'uploadlogpage' => 'Igoera erregistroa',
+'uploadlogpagetext' => 'Jarraian azken igoeren zerrenda ikus daiteke.',
+'filename' => 'Fitxategi izena',
+'filedesc' => 'Laburpena',
+'fileuploadsummary' => 'Laburpena:',
+'filestatus' => 'Copyright egoera',
+'filesource' => 'Iturria',
+'copyrightpage' => "Project:Eskubideak",
+'copyrightpagename' => "{{SITENAME}} copyright",
+'uploadedfiles' => 'Igotako fitxategiak',
+'ignorewarning' => 'Oharra ezikusi eta fitxategia gorde.',
+'ignorewarnings' => 'Edozein ohar ezikusi.',
+'minlength' => 'Fitxategi izenak hiru karaktere izan behar ditu gutxienez.',
+'illegalfilename' => '"$1" fitxategiaren izenak orrialdeen izenburuetan erabili ezin diren karaktereak ditu. Mesedez, fitxategiari izena aldatu eta saiatu berriz igotzen.',
+'badfilename' => 'Irudiaren izena aldatu da: "$1".',
+'badfiletype' => "\".$1\" ez da gomendatutako irudi fitxategi formatua.",
+'largefile' => 'Ez da gomendagarria fitxategiak $1 bytetik gorakoak izatea; fitxategi honek $2 byte ditu',
+'largefileserver' => 'Fitxategi hau zerbitzariak baimentzen duena baino handiagoa da.',
+'emptyfile' => 'Badirudi igotzen ari zaren fitxategia hutsik dagoela. Mesedez, egiaztatu fitxategi hori dela igo nahi duzuna.',
+'fileexists' => 'Badago izen hori daukan fitxategi bat; mesedez, ikusi existitzen den $1 fitxategia aldatu nahi duzun egiaztatzeko.',
+'fileexists-forbidden' => 'Badago izen hori daukan fitxategi bat; mesedez, atzera itzuli eta igo fitxategia izen ezberdin batekin. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Badago izen hori daukan fitxategi bat elkarbanatutako fitxategi-biltegian; mesedez, atzera itzuli eta igo fitxategia izen ezberdin batekin. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Igoera arrakastatsua',
+'fileuploaded' => "$1 fitxategia igo da. Mesedez, jarraitu hurrengo lotura hau: jo $2 deskribapen orrialdera eta fitxategiaren inguruko informazioa osatu, hala nola bere jatorria, noiz sortu den eta nork, eta fitxategiaren inguruan jakin beharko litzatekeen beste edozein datu. Hau irudi bat bada, honela txertatu dezakezu: <tt><nowiki>[[Irudi:$1|thumb|Deskribapena]]</nowiki></tt>",
+'uploadwarning' => 'Igotzeko oharra',
+'savefile' => 'Fitxategia gorde',
+'uploadedimage' => "\"[[$1]]\" igo da",
+'uploaddisabled' => 'Igoerak ezgaituta daude',
+'uploaddisabledtext' => 'Fitxategiak igotzea ezgaituta dago wiki honetan.',
+'uploadscripted' => 'Fitxategi honek web zerbitzariak modu ezegokian interpretatu lezakeen HTML edo script kodea dauka.',
+'uploadcorrupt' => 'Fitxategiak akatsak ditu edo luzapena ezegokia da. Mesedez, egiaztatu fitxategia ondo dagoela eta berriz igo.',
+'uploadvirus' => 'Fitxategiak birusa dauka! Xehetasunak: $1',
+'sourcefilename' => 'Iturri-fitxategiaren izena',
+'destfilename' => 'Helburu fitxategi izena',
+'watchthisupload' => 'Orrialde hau jarraitu',
+'filewasdeleted' => 'Izen hau duen fitxategi bat igo eta ezabatu da jada. $1 aztertu beharko zenuke berriz igo aurretik.',
+
+'license' => 'Lizentzia',
+'nolicense' => 'Hautatu gabe',
+'upload_source_url' => ' (baliozko URL publikoa)',
+'upload_source_file' => ' (zure ordenagailuko fitxategi bat)',
+
+# Image list
+#
+'imagelist' => 'Fitxategien zerrenda',
+'imagelisttext' => "Jarraian duzu $2(e)z ordenatutako {{plural:$1|fitxategi baten|'''$1''' fitxategiren}} zerrenda.",
+'imagelistforuser' => "Honek $1(e)k igotako irudiak bakarrik erakusten ditu.",
+'getimagelist' => 'fitxategi zerrenda jasotzen',
+'ilsubmit' => 'Bilatu',
+'showlast' => 'Erakutsi azken $1 fitxategiak $2 ordenatuta.',
+'byname' => 'izenaren arabera',
+'bydate' => 'dataren arabera',
+'bysize' => 'tamainaren arabera',
+'imgdelete' => 'ezb',
+'imgdesc' => 'desk',
+'imgfile' => 'fitxategia',
+'imglegend' => 'Legenda: (desk) = fitxategiaren deskribapena erakutsi/aldatu.',
+'imghistory' => 'Fitxategiaren historia',
+'revertimg' => 'des',
+'deleteimg' => 'ezb',
+'deleteimgcompletely' => 'Fitxategi honen bertsio guztiak ezabatu',
+'imghistlegend' => 'Legenda: (orain) = oraingo fitxategia, (ezab) = ezabatu bertsio zahar hau, (ber) = bertsio zahar honetara itzuli. <br /><i>Dataren gainean klik egin egun hartan igotako fitxategia ikusteko</i>.',
+'imagelinks' => 'Loturak',
+'linkstoimage' => 'Hurrengo orrialdeek dute fitxategi honetarako lotura:',
+'nolinkstoimage' => 'Ez dago fitxategi honetara lotura egiten duen orrialderik.',
+'sharedupload' => 'Fitxategi hau elkarbanatutako igoera bat da eta beste proiektuek ere erabil dezakete.',
+'shareduploadwiki' => 'Informazio gehiagorako $1 ikusi mesedez.',
+'shareduploadwiki-linktext' => 'fitxategiaren deskribapen orrialdea',
+'noimage' => 'Ez dago fitxategirik izen honekin, $1 dezakezu nahi baduzu.',
+'noimage-linktext' => 'igo egin',
+'uploadnewversion-linktext' => 'Fitxategi honen bertsio berri bat igo',
+'imagelist_date' => 'Data',
+'imagelist_name' => 'Izena',
+'imagelist_user' => 'Erabiltzailea',
+'imagelist_size' => 'Tamaina (byte)',
+'imagelist_description' => 'Deskribapena',
+'imagelist_search_for' => 'Irudiaren izenagatik bilatu:',
+
+# Mime search
+#
+'mimesearch' => 'MIME bilaketa',
+'mimetype' => 'MIME mota:',
+'download' => 'deskargatu',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Jarraitu gabeko orrialdeak',
+
+# List redirects
+'listredirects' => 'Birzuzenketen zerrenda',
+
+# Unused templates
+'unusedtemplates' => 'Erabili gabeko txantiloiak',
+'unusedtemplatestext' => 'Orrialde honetan beste edozein orrialdetan erabiltzen ez diren txantiloi izen-tarteko orrialdeak zerrendatzen dira. Ez ahaztu txantiloietara egon daitezkeen loturak egiaztatzeaz ezabatu aurretik.',
+'unusedtemplateswlh' => 'beste loturak',
+
+# Random redirect
+'randomredirect' => 'Ausazko birzuzenketa',
+
+# Statistics
+#
+'statistics' => 'Estatistikak',
+'sitestats' => '{{SITENAME}}(e)ko estatistikak',
+'userstats' => 'Erabiltzaile estatistikak',
+'sitestatstext' => "Datu-basean guztira '''$1''' orrialde daude.
+Kopuru horretan \"eztabaida\" orrialdeak, {{SITENAME}}(r)i buruzko orrialdeak, zirriborroak, birzuzenketak eta eduki orrialde bezala kontsideratu ezin diren beste batzuk ere kontuan hartzen dira. Horiek baztertuz, '''$2''' orrialde daude ziurrenik edukia daukatenak.
+
+'''$8''' fitxategi igo dira.
+
+Guztira '''$3''' orrialde irakurketa egon dira, eta '''$4''' orrialde aldaketa wikia abian jarri zenez geroztik.
+Horren arabera, '''$5''' aldaketa egin dira orrialde bakoitzeko bataz beste, eta aldaketa bakoitzeko '''$6''' irakurketa egin dira.
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue Atazen zerrendaren] luzera '''$7'''(e)koa da.",
+'userstatstext' => "'''$1''' erabiltzaile daude izen emanda, horietatik '''$2''' (edo '''$4%''') $5 direlarik.",
+'statistics-mostpopular' => 'Orrialde bisitatuenak',
+
+'disambiguations' => 'Argipen orrialdeak',
+'disambiguationspage' => 'Template:argipen',
+'disambiguationstext' => "Jarraian zerrendatutako orrialdeek <i>argipen orrialde</i> baterako lotura daukate. Horrez ordez, lotura egokia ipini beharko litzaieke.<br /> Orrialde bat argipen bezala antzematen da $1(e)tik lotura baldin badauka.<br />Beste izen-tarte batzutatik datozen loturak <i>ez</i> dira erakusten.",
+
+'doubleredirects' => 'Birzuzenketa bikoitzak',
+'doubleredirectstext' => "Lerro bakoitzean lehen eta bigarren birzuzenketetarako loturak ikus daitezke, eta baita edukia daukan edo eduki beharko lukeen orrialderako lotura ere. Lehen birzuzenketak azken honetara zuzendu beharko luke.",
+
+'brokenredirects' => 'Hautsitako birzuzenketak',
+'brokenredirectstext' => 'Jarraian zerrendatutako birzuzenketak existitzen ez diren orrialdeetara zuzenduta daude:',
+
+# Miscellaneous special pages
+#
+'nbytes' => '{{PLURAL:$1|byte 1|$1 byte}}',
+'ncategories' => '{{PLURAL:$1|kategoria 1|$1 kategoria}}',
+'nlinks' => '{{PLURAL:$1|lotura 1|$1 lotura}}',
+'nmembers' => '{{PLURAL:$1|partaide 1|$1 partaide}}',
+'nrevisions' => '{{PLURAL:$1|berrikuspen 1|$1 berrikuspen}}',
+'nviews' => '{{PLURAL:$1|ikusketa 1|$1 ikusketa}}',
+
+'lonelypages' => 'Orrialde umezurtzak',
+'lonelypagestext' => 'Jarraian zerrendatutako orrialdeek ez daukate wikiko beste orrialdeetatik loturarik.',
+'uncategorizedpages' => 'Kategorizatu gabeko orrialdeak',
+'uncategorizedcategories' => 'Kategorizatu gabeko kategoriak',
+'uncategorizedimages' => 'Kategorizatu gabeko irudiak',
+'unusedcategories' => 'Erabili gabeko kategoriak',
+'unusedimages' => 'Erabili gabeko fitxategiak',
+'popularpages' => 'Orrialde bisitatuenak',
+'wantedcategories' => 'Eskatutako kategoriak',
+'wantedpages' => 'Eskatutako orrialdeak',
+'mostlinked' => 'Gehien lotutako orrialdeak',
+'mostlinkedcategories' => 'Gehien lotutako kategoriak',
+'mostcategories' => 'Sailkapenean kategoria gehien dituzten orrialdeak',
+'mostimages' => 'Gehien lotutako irudiak',
+'mostrevisions' => 'Berrikuspen gehien dituzten orrialdeak',
+'allpages' => 'Orrialde guztiak',
+'prefixindex' => 'Aurrizkien aurkibidea',
+'randompage' => 'Ausazko orrialdea',
+'shortpages' => 'Orrialde laburrak',
+'longpages' => 'Orrialde luzeak',
+'deadendpages' => 'Orrialde itsuak',
+'deadendpagestext' => 'Jarraian zerrendatutako orrialdeek ez daukate wikiko beste edozein orrialdetarako loturarik.',
+'listusers' => 'Erabiltzaileen zerrenda',
+'specialpages' => 'Aparteko orrialdeak',
+'spheading' => 'Erabiltzaile guztientzako aparteko orrialdeak',
+'restrictedpheading' => 'Mugatutako aparteko orrialdeak',
+'recentchangeslinked' => 'Lotutako orrialdeen aldaketak',
+'rclsub' => "(\"$1\"(e)tik lotutako orrialdeetara)",
+'newpages' => 'Orrialde berriak',
+'newpages-username' => 'Erabiltzaile izena:',
+'ancientpages' => 'Orrialde zaharrenak',
+'intl' => 'Hizkuntzen arteko loturak',
+'move' => 'Move',
+'movethispage' => 'Orrialde hau mugitu',
+'unusedimagestext' => '<p>Mesedez, kontuan izan beste webgune batzutatik URL zuzena erabiliz lotura izan dezaketela irudira, eta kasu horretan ez lirateke hemengo zerrendetan azalduko.</p>',
+'unusedcategoriestext' => 'Hurrengo kategoria orrialde guztiak datu-basean existitzen dira, baina ez du inongo orrialde edo kategoriak erabiltzen.',
+
+'booksources' => 'Iturri liburuak',
+'categoriespagetext' => 'Hurrengo kategoriak daude wiki honetan:',
+'data' => 'Datuak',
+'userrights' => 'Erabiltzaile baimenen kudeaketa',
+'groups' => 'Erabiltzaile taldeak',
+
+'booksources-text' => "Jarraian liburu berri eta erabiliak saltzen dituzten guneetarako loturen zerrenda bat ikus dezakezu, bilatzen ari zaren liburu horientzako informazio gehigarria aurkitzeko lagungarria izan daitekeena:",
+'isbn' => 'ISBN',
+'alphaindexline' => "$1(e)tik $2(e)raino",
+'version' => 'Bertsioa',
+'log' => 'Erregistroak',
+'alllogstext' => 'Igoera, ezabaketa, babes, blokeaketa eta administratzaile erregistroen erakusketa. Zerrenda mugatu dezakezu erregistro mota, erabiltzaile izena edo eragindako orrialdea aukeratuz.',
+'logempty' => 'Ez dago emaitzarik erregistroan.',
+
+
+# Special:Allpages
+'nextpage' => 'Hurrengo orrialdea ($1)',
+'allpagesfrom' => 'Honela hasten diren orrialdeak erakutsi:',
+'allarticles' => 'Artikulu guztiak',
+'allinnamespace' => 'Orrialde guztiak ($1 izen-tartea)',
+'allnotinnamespace' => 'Orrialde guztiak ($1 izen-tartean ez daudenak)',
+'allpagesprev' => 'Aurrekoa',
+'allpagesnext' => 'Hurrengoa',
+'allpagessubmit' => 'Joan',
+'allpagesprefix' => 'Aurrizki hau duten orrialdeak bistaratu:',
+'allpagesbadtitle' => 'Orrialdearen izena baliogabekoa da edo interwiki edo hizkuntzen arteko aurrizkia dauka. Izenburuetan erabili ezin daitezkeen karaktere bat edo gehiago izan ditzake.',
+
+# Special:Listusers
+'listusersfrom' => 'Hemendik aurrerako erabiltzaileak bistaratu:',
+
+# E this user
+#
+'mailnologin' => 'Bidalketa helbiderik ez',
+'mailnologintext' => "Beste erabiltzaileei e-posta mezuak bidaltzeko [[Special:Userlogin|saioa hasi]] eta baliozko e-posta helbidea behar duzu izan zure [[Special:Preferences|hobespenetan]].",
+'emailuser' => 'Erabiltzaile honi e-posta bidali',
+'emailpage' => 'Erabiltzaileari e-posta bidali',
+'emailpagetext' => 'Erabiltzaile honek baliozko e-posta helbide bat ezarri badu bere hobespenetan, beheko formularioa erabiliz mezu bat bidal dakioke. Hobespenetan daukazun e-posta helbidea azalduko da mezuaren bidaltzaile bezala eta beraz erantzun ahal izango dizu.',
+'usermailererror' => 'Mail objektuak errore hau itzuli du:',
+'defemailsubject' => "E-posta {{SITENAME}}(e)tik",
+'noemailtitle' => 'Posta helbiderik ez',
+'noemailtext' => 'Erabiltzaile honek ez du baliozko posta helbiderik zehaztu edo beste erabiltzaileengandik mezurik ez jasotzea aukeratu du.',
+'emailfrom' => 'Nork',
+'emailto' => 'Nori',
+'emailsubject' => 'Gaia',
+'emailmessage' => 'Mezua',
+'emailsend' => 'Mezua',
+'emailsent' => 'Mezua bidali egin da',
+'emailsenttext' => 'Zure e-posta mezua bidali egin da.',
+
+# Watchlist
+'watchlist' => 'Nire jarraipen zerrenda',
+'watchlistfor' => "('''$1''')",
+'nowatchlist' => 'Zure jarraipen zerrenda hutsik dago.',
+'watchlistanontext' => 'Mesedez $1 zure jarraipen zerrendako orrialdeak ikusi eta aldatu ahal izateko.',
+'watchlistcount' => "'''$1 elementu dituzu zure jarraipen zerrendan, eztabaida orrialdeak barne.'''",
+'clearwatchlist' => 'Jarraipen zerrenda garbitu',
+'watchlistcleartext' => 'Ziur zaude ezabatu nahi dituzula?',
+'watchlistclearbutton' => 'Jarraipen zerrenda garbitu',
+'watchlistcleardone' => 'Zure jarraipen zerrenda garbitu egin da. $1 elementu ezabatu dira.',
+'watchnologin' => 'Saioa hasi gabe',
+'watchnologintext' => '[[Special:Userlogin|Saioa hasi]] behar duzu zure jarraipen zerrenda aldatzeko.',
+'addedwatch' => 'Jarraipen zerrendan gehitu da',
+'addedwatchtext' => "\"$1\" orrialdea zure [[Special:Watchlist|jarraipen edo zelatatuen zerrendara]] erantsi da. Orrialde honen hurrengo aldaketak zerrenda horretan ageriko dira aurrerantzean, eta gainera [[Special:Recentchanges|aldaketa berrien zerrendan]] beltzez ageriko da, erraztasunez antzeman ahal izateko.
+
+Jarraipen zerrendatik artikulua kentzeko, artikuluan ''ez jarraitu''ri eman.",
+'removedwatch' => 'Jarraipen zerrendatik ezabatuta',
+'removedwatchtext' => "\"[[:$1]]\" orrialdea zure jarraipen zerrendatik kendu da.",
+'watch' => 'Jarraitu',
+'watchthispage' => 'Orrialde hau jarraitu',
+'unwatch' => 'Ez jarraitu',
+'unwatchthispage' => 'Jarraitzeari utzi',
+'notanarticle' => 'Ez da eduki orrialdea',
+'watchnochange' => 'Hautatutako denbora tartean ez da aldaketarik izan zure jarraipen zerrendako orrialdeetan.',
+'watchdetails' => '* $1 orrialde jarraitzen, eztabaida orrialdeak kontuan hartu gabe
+* [[Special:Watchlist/edit|Jarraipen zerrenda osoa erakutsi eta editatu]]
+* [[Special:Watchlist/clear|Orrialde guztiak kendu]]',
+'wlheader-enotif' => "* Posta bidezko ohartarazpena gaituta dago.",
+'wlheader-showupdated' => "* Bisitatu zenituen azken alditik aldaketak izan dituzten orrialdeak '''beltzez''' nabarmenduta daude",
+'watchmethod-recent'=> 'Aldaketa berriak aztertzen jarraipen zerrendako orrialdeen bila',
+'watchmethod-list' => 'jarraipen zerrendako orrialdeak aldaketa berrien bila aztertzen',
+'removechecked' => 'Hautatutakoak jarraipen zerrendatik ezabatu',
+'watchlistcontains' => "Zure jarraipen zerrendak $1 orrialde ditu.",
+'watcheditlist' => 'Hona hemen jarraitzen ari zaren orrialdeen zerrenda alfabetikoa. Zerrendatik kendu nahi dituzun orrialdeak hautatu eta \'hautatutakoak ezabatu\' botoian klik egin (eduki orrialde bat kentzeak bere eztabaida orrialdea kentzea ere suposatzen du, eta alderantziz).',
+'removingchecked' => 'Jarraipen zerrendatik eskatutakoak ezabatzen...',
+'couldntremove' => "Ezin izan da '$1' ezabatu...",
+'iteminvalidname' => "Arazoa '$1' elementuarekin, baliogabeko izena...",
+'wlnote' => 'Jarraian ikus daitezke azken \'\'\'$2\'\'\' egunetako azken $1 aldaketak.',
+'wlshowlast' => 'Erakutsi azken $1 orduak $2 egunak $3',
+'wlsaved' => 'Honako hau zure jarraipen zerrendaren gordetako bertsio bat da.',
+'wlhideshowown' => '$1 nire aldaketak',
+'wlhideshowbots' => '$1 bot-en aldaketak',
+'wldone' => 'Egina.',
+
+'enotif_mailer' => '{{SITENAME}}(e)ko Oharpen Postaria',
+'enotif_reset' => 'Orrialde guztiak bisitatu bezala markatu',
+'enotif_newpagetext'=> 'Honako hau orrialde berria da.',
+'changed' => 'aldatu',
+'created' => 'sortu',
+'enotif_subject' => '{{SITENAME}}(e)ko $PAGETITLE orrialdea $PAGEEDITOR(e)k $CHANGEDORCREATED du',
+'enotif_lastvisited' => 'Jo $1 orrialdera zure azken bisitaz geroztik izandako aldaketa guztiak ikusteko.',
+'enotif_body' => 'Kaixo $WATCHINGUSERNAME,
+
+{{SITENAME}}(e)ko $PAGETITLE orrialdea $CHANGEDORCREATED egin du $PAGEEDITOR(e)k une honetan: $PAGEEDITDATE, ikus $PAGETITLE_URL azken bertsiorako.
+
+$NEWPAGE
+
+Egilearen laburpena: $PAGESUMMARY $PAGEMINOREDIT
+
+Egilearekin harremanetan jarri:
+e-posta: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Ez dira oharpen gehiago bidaliko orrialde hau berriz bisitatzen ez baduzu. Horrez gain, orrialdeen oharpen konfigurazioa leheneratu dezakezu jarraipen zerrendatik.
+
+ {{SITENAME}}(e)ko oharpen sistema
+
+--
+Zure jarraipen zerrendako konfigurazioa aldatzeko, ikus
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Laguntza:
+{{fullurl:{{ns:help}}:Contents}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Orrialdea ezabatu',
+'confirm' => 'Baieztatu',
+'excontent' => "edukia honakoa zen: '$1'",
+'excontentauthor' => "edukia honakoa zen: '$1' (parte hartu duen lankide bakarra: '$2')",
+'exbeforeblank' => "hustu aurreko edukiera: '$1'",
+'exblank' => 'orrialdea hutsik zegoen',
+'confirmdelete' => 'Ezabaketa baieztatu',
+'deletesub' => "(\"$1\" ezabatzen)",
+'historywarning' => 'Kontuz! Ezabatuko duzun orrialdeak honako historia du:',
+'confirmdeletetext' => "Orrialde edo irudi bat eta beste historia guztia datu-basetik ezabatzear zaude. Mesedez, egiaztatu hori egin nahi duzula, ondorioak zeintzuk diren badakizula, eta [[{{ns:project}}:Politikak|politikak]] errespetatuz egingo duzula.",
+'actioncomplete' => 'Ekintza burutu da',
+'deletedtext' => "\"$1\" ezabatu egin da. Ikus $2 azken ezabaketen erregistroa ikusteko.",
+'deletedarticle' => "\"[[$1]]\" ezabatu da",
+'dellogpage' => 'Ezabaketa erregistroa',
+'dellogpagetext' => 'Behean ikus daiteke azken ezabaketen zerrenda.',
+'deletionlog' => 'ezabaketa erregistroa',
+'reverted' => 'Lehenagoko berrikuspen batera itzuli da',
+'deletecomment' => 'Ezabatzeko arrazoia',
+'imagereverted' => 'Lehenagoko bertsiora leheneratu egin da.',
+'rollback' => 'Aldaketak desegin',
+'rollback_short' => 'Desegin',
+'rollbacklink' => 'desegin',
+'rollbackfailed' => 'Desegiteak huts egin dud',
+'cantrollback' => 'Ezin da aldaketa desegin; erabiltzaile bakarrak hartu du parte.',
+'alreadyrolled' => "Ezin da [[Lankide:$2|$2]](e)k ([[Lankide eztabaida:$2|Eztabaida]]) [[$1]](e)n egindako azken aldaketa desegin; beste norbaitek editatu du edo jada desegin du. Azken aldaketa [[Lankide:$3|$3]](e)k ([[Lankide eztabaida:$3|Eztabaida]]) egin du.",
+# only shown if there is an edit comment
+'editcomment' => "Aldaketaren iruzkina: \"<i>$1</i>\".",
+'revertpage' => "$2ren aldaketak ezabatu dira, $1ren azken bertsiora itzuliz.",
+'sessionfailure' => 'Badirudi saioarekin arazoren bat dagoela; bandalismoak saihesteko ekintza hau ezeztatu egin da. Mesedez, nabigatzaileko "atzera" botoian klik egin, hona ekarri zaituen orrialde hori berriz kargatu, eta saiatu berriz.',
+'protectlogpage' => 'Babes erregistroa',
+'protectlogtext' => "Orrialdeen blokeo eta desblokeo zerrenda azaltzen da jarraian.",
+'protectedarticle' => '"[[$1]]" babestu da"',
+'unprotectedarticle' => '"[[$1]]"(r)i babesa kendu zaio',
+'protectsub' => '("$1" babesten)',
+'confirmprotecttext' => 'Ziur zaude orrialde hau babestu nahi duzula?',
+'confirmprotect' => 'Babesa baieztatu',
+'protectmoveonly' => 'Mugitzea babestu bakarrik',
+'protectcomment' => 'Babesteko arrazoia',
+'unprotectsub' =>"(babesa kentzen: \"$1\")",
+'confirmunprotecttext' => 'Ziur zaude orrialde honi babesa kendu nahi diozula?',
+'confirmunprotect' => 'Babesa kentzea baieztatu',
+'unprotectcomment' => 'Babesa kentzeko arrazoia',
+'protect-unchain' => 'Mugitzeko blokeoa kendu',
+'protect-text' => '<strong>$1</strong> orrialdearen babes maila ikusi eta aldatu egin beharko zenuke.',
+'protect-viewtext' => 'Ez daukazu babesak aldatzeko baimenik. Hemen duzu <strong>$1</strong> orrialdearen oraingo konfigurazioa:',
+'protect-default' => '(lehenetsia)',
+'protect-level-autoconfirmed' => 'Erregistratu gabeko erabiltzaileak blokeatu',
+'protect-level-sysop' => 'Administratzaileak bakarrik',
+
+# restrictions (nouns)
+'restriction-edit' => 'Aldatu',
+'restriction-move' => 'Mugitu',
+
+# Undelete
+'undelete' => 'Ezabatutako orrialdeak ikusi',
+'undeletepage' => 'Ezabatutako orrialdeak ikusi eta leheneratu',
+'viewdeletedpage' => 'Ezabatutako orrialdeak ikusi',
+'undeletepagetext' => 'Jarraian zerrendatzen diren orrialdeak ezabatu egin dira baina oraindik artxiboa gordeta daude eta leheneratu egin daitezke. Artxiboa noizean behin hustu egin liteke.',
+'undeleteextrahelp' => "Orrialde osoa leheneratzeko, koadrotxo guztiak hautatu gabe utzi eta '''''Leheneratu'''''n klik egin. Aukeratutako leheneratze bat burutzeko, leheneratu nahi dituzun berrikuspenen koadrotxoak markatu eta '''''Leheneratu''''' klik egin. '''''Hasieratu'''''n klik eginez gero koadrotxo guztiak eta iruzkin koadroa hustu egingo dira.",
+'undeletearticle' => 'Ezabatutako orrialdea leheneratu',
+'undeleterevisions' => "$1 berrikuspen gordeta",
+'undeletehistory' => 'Orrialdea leheneratzen baduzu, berrikuspena guztiak leheneratuko dira historian. Ezabatu ondoren izen berdina duen orrialde berri bat sortzen bada leheneratutako berrikuspenak azalduko dira historian, eta oraingo berrikuspena ez da automatikoki ordezkatuko.',
+'undeletehistorynoadmin' => 'Artikulua ezabatu egin da. Ezabatzeko azalpena beheko laburpenean erakusten da, ezabatu aurretik parte hartu zuten erabiltzaileen xehetasunekin batera. Ezabatutako berrikuspenen oraingo testua administratzaileek bakarrik ikus dezakete.',
+'undeleterevision' => "$1 berrikuspen gordeta",
+'undeletebtn' => 'Leheneratu',
+'undeletereset' => 'Hasieratu',
+'undeletecomment' => 'Iruzkina:',
+'undeletedarticle' => "\"[[$1]]\" leheneratu da",
+'undeletedrevisions' => "$1 berrikuspen leheneratu dira",
+'undeletedrevisions-files' => "$1 berrikuspen eta $2 fitxategi leheneratu dira",
+'undeletedfiles' => "$1 fitxategi leheneratu dira",
+'cannotundelete' => 'Errorea birsortzerakoan; baliteke beste norbaitek lehenago birsortu izana.',
+'undeletedpage' => "<big>'''$1 leheneratu egin da'''</big>
+
+[[Special:Log/delete|Ezabaketa erregistrora]] jo azken ezabaketa eta leheneraketak ikusteko.",
+
+# Namespace form on various pages
+'namespace' => 'Izen-tartea:',
+'invert' => 'Hautapena alderanztu',
+
+# Contributions
+#
+'contributions' => 'Lankidearen ekarpenak',
+'mycontris' => 'Nire ekarpenak',
+'contribsub' => "$1",
+'nocontribs' => 'Ez da ezaugarri horiekin bat datorren aldaketarik aurkitu.',
+'ucnote' => "Behean agertzen dira erabiltzaile honen azken <b>$1</b> aldaketak azken <b>$2</b> egunetan.",
+'uclinks' => "Azken $1 aldaketak ikusi; azken $2 egunak ikusi.",
+'uctop' => ' (Azken aldaketa)' ,
+'newbies' => 'hasiberriak',
+
+'sp-newimages-showfrom' => 'Irudi berriak erakutsi $1(e)tik hasita',
+
+'sp-contributions-newest' => 'Berriena',
+'sp-contributions-oldest' => 'Zaharrena',
+'sp-contributions-newer' => '$1 berriago',
+'sp-contributions-older' => '$1 zaharrago',
+'sp-contributions-newbies-sub' => 'Hasiberrientzako',
+
+
+# What links here
+#
+'whatlinkshere' => 'Honekin lotzen diren orrialdeak',
+'whatlinkshere-barrow' => '&lt;',
+'notargettitle' => 'Helburu orrialderik ez',
+'notargettext' => 'Ez duzu eragiketa hau burutzeko helburu orrialde edo erabiltzaile bat zehaztu.',
+'linklistsub' => '(Loturen zerrenda)',
+'linkshere' => "Hurrengoek dute '''[[:$1]]''' orrialderako lotura:",
+'nolinkshere' => "Ez dago '''[[:$1]]''' lotura duen orrialderik.",
+'isredirect' => 'berbideraketa orrialdea',
+'istemplate' => 'erabilpena',
+
+# Block/unblock IP
+#
+'blockip' => 'Erabiltzailea blokeatu',
+'blockiptext' => "IP helbide edo erabiltzaile izen bati idazketa baimenak kentzeko beheko formularioa erabil dezakezu. Ekintza hau bandalismoa saihesteko baino ez da burutu behar, eta beti ere [[{{ns:project}}:Politikak|politikak]] errespetatuz. Blokeoaren arrazoi bat ere zehaztu ezazu (adibidez, orrialde batzuk zehaztuz).",
+'ipaddress' => 'IP Helbidea',
+'ipadressorusername' => 'IP Helbidea edo erabiltzaile izena',
+'ipbexpiry' => 'Iraungipena',
+'ipbreason' => 'Arrazoia',
+'ipbanononly' => 'Erabiltzaile anonimoak bakarrik blokeatu',
+'ipbcreateaccount' => 'Kontua sortzea debekatu',
+'ipbsubmit' => 'Erabiltzaile hau blokeatu',
+'ipbother' => 'Beste denbora-tarte bat',
+'ipboptions' => '15 minutu:15 minutes,30 minutu:30 minutes,ordu 1:1 hour,2 ordu:2 hours,egun bat:1 day,3 egun:3 days,aste 1:1 week,2 aste:2 weeks,hilabete 1:1 month,betirako:infinite',
+'ipbotheroption' => 'beste bat',
+'badipaddress' => 'Baliogabeko IP helbidea',
+'blockipsuccesssub' => 'Blokeoa burutu da',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|$1]] erabiltzaileari blokeoa ezarri zaio. Ikus [[{{ns:Special}}:Ipblocklist|IP blokeoen zerrenda]] blokeoak aztertzeko.',
+'unblockip' => 'Erabiltzailea desblokeatu',
+'unblockiptext' => 'Erabili beheko formularioa lehenago blokeatutako IP helbide edo erabiltzaile baten idazketa baimenak leheneratzeko.',
+'ipusubmit' => 'Helbide hau desblokeatu',
+'unblocked' => '[[User:$1|$1]] desblokeatu egin da',
+'ipblocklist' => 'Blokeatutako IP helbide eta erabiltzaileen zerrenda',
+'blocklistline' => "$1, $2(e)k $3 blokeatu du (iraungipena: $4)",
+'infiniteblock' => 'infinitu',
+'expiringblock' => 'iraungipen data: $1',
+'anononlyblock' => 'anon. soilik',
+'createaccountblock' => 'kontua sortzea blokeatuta',
+'ipblocklistempty' => 'Blokeo zerrenda hutsik dago.',
+'blocklink' => 'blokeatu',
+'unblocklink' => 'blokeoa kendu',
+'contribslink' => 'ekarpenak',
+'autoblocker' => '"[[Lankide:$1|$1]]"(e)k berriki erabili duen IP helbidea duzulako autoblokeatu zaizu. $1(e)k emandako arrazoia zera da: "\'\'\'$2\'\'\'"',
+'blocklogpage' => 'Blokeo erregistroa',
+'blocklogentry' => '"[[Lankide:$1|$1]]" $2(e)ko iraungipenarekin blokeatu da.',
+'blocklogtext' => 'Erabiltzaileen blokeoen ezarpen eta ezabaketen erregistroa da hau. Ez dira automatikoki blokeatutako IP helbideak zerrendatzen. Ikus [[Special:Ipblocklist|IP blokeoen zerrenda]] aktibo dauden blokeoak aztertzeko.',
+'unblocklogentry' => '$1 desblokeatu da',
+'range_block_disabled' => 'Administratzaileak IP eremuak blokeatzeko gaitasuna ezgaituta dago.',
+'ipb_expiry_invalid' => 'Baliogabeko iraungipen denbora',
+'ipb_already_blocked' => '"$1" badago blokeatuta',
+'ip_range_invalid' => 'Baliogabeko IP eremua.',
+'proxyblocker' => 'Proxy blokeatzailea',
+'ipb_cant_unblock' => 'Errorea: Ez da $1 IDa duen blokeoa aurkitu. Baliteke blokeoa jada kenduta egotea.',
+'proxyblockreason' => 'Zure IP helbidea blokeatu egin da proxy ireki baten zaudelako. Mesedez, zure Interneteko Zerbitzu Hornitzailearekin harremanetan jar zaitez segurtasun arazo honetaz ohartarazteko.',
+'proxyblocksuccess' => 'Egina.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Zure IP helbidea proxy ireki bezala zerrendatuta dago [http://www.sorbs.net SORBS]eko DNSBLan.',
+'sorbs_create_account_reason' => 'Zure IP helbidea proxy ireki bezala zerrendatuta dago [http://www.sorbs.net SORBS]eko DNSBLan. Ezin duzu kontua sortu.',
+
+# Developer tools
+#
+'lockdb' => 'Datu-basea blokeatu',
+'unlockdb' => 'Datu-basea desblokeatu',
+'lockdbtext' => 'Datu-basea blokeatzeak edozein erabiltzailek orrialdeak aldatzea, hobespenak aldatzea, jarraipen zerrendan aldaketak egitea, eta datu-basean edozein aldaketa behar duen edozein ekintza galaraziko du. Mesedez, baieztatu zure asmoa hori dela, eta blokeoa kenduko duzula mantenua burutu ondoren.',
+'unlockdbtext' => 'Datu-basea desblokeatzerakoan erabiltzaile guztiek orrialdeak aldatu, beraien hobespenak ezarri, jarraipen zerrendan aldaketak egin eta beste eragiketa batzuk burutzeko gaitasuna leheneratuko du. Mesedez, baieztatu egin nahi duzuna hori dela.',
+'lockconfirm' => 'Bai, datu-basea blokeatu nahi dut',
+'unlockconfirm' => 'Bai, datu-basea desblokeatu nahi dut',
+'lockbtn' => 'Datu-basea blokeatu',
+'unlockbtn' => 'Datu-basea desblokeatu',
+'locknoconfirm' => 'Ez duzu baieztapen kutxa hautatu.',
+'lockdbsuccesssub' => 'Datu-basea blokeatu egin da',
+'unlockdbsuccesssub' => 'Datu-basearen blokeoa kendu da',
+'lockdbsuccesstext' => 'Datu-basea blokeatu egin da. <br />Ez ahaztu mantenu lanak burutu ondoren [[Special:Unlockdb|blokeoa kentzeaz]].',
+'unlockdbsuccesstext' => 'Datu-basea desblokeatu egin da.',
+'lockfilenotwritable' => 'Ezin da datu-baseko blokeo fitxategian idatzi. Datu-basea blokeatu edo desblokeatzeko, zerbitzariak idazteko aukera izan beharra dauka.',
+'databasenotlocked' => 'Datu-basea ez dago blokeatuta.',
+
+# Make sysop
+'makesysoptitle' => 'Lankide bat administratzaile egin',
+'makesysoptext' => 'Lankide arruntei administratzaile baimenak emateko erabiltzen da orrialde hau. Lankidearen izena ipini laukian eta botoia sakatu.',
+'makesysopname' => 'Lankidearen izena:',
+'makesysopsubmit' => 'Lankide hau administratzaile egin',
+'makesysopok' => "<strong>\"$1\" lankidea administratzailea da orain</strong>",
+'makesysopfail' => "<strong>Ezin da \"$1\" lankidea administratzaile egin. (Ziur zaude izena zuzen idatzi duzula?)</strong>",
+'setbureaucratflag' => 'Burokrata egin',
+'rightslog' => 'Erabiltzaile eskubideen erregistroa',
+'rightslogtext' => 'Erabiltzaile eskubideetan izandako aldaketen erregistroa da hau.',
+'rightslogentry' => '$1(r)en partaidetza aldatu da $2(e)tik $3(e)ra',
+'rights' => 'Eskubideak:',
+'set_user_rights' => 'Erabiltzailearen eskubideak ezarri',
+'user_rights_set' => "<strong>\"$1\"(r)en eskubideak eguneratu egin dira</strong>",
+'set_rights_fail' => "<strong>Ezin izan dira \"$1\"(r)entzako eskubideak ezarri. (Izena ondo idatzi duzu?)</strong>",
+'makesysop' => 'Lankide bat administratzaile egin',
+'already_sysop' => 'Erabiltzaile hau bada administratzailea',
+'already_bureaucrat' => 'Erabiltzaile hau bada burokrata',
+'rightsnone' => '(bat ere ez)',
+
+# Move page
+#
+'movepage' => 'Orrialdea mugitu',
+'movepagetext' => 'Hurrengo pausoak jarraituz, artikulu edo orrialde baten izena aldatu daiteke. Izenburu zaharra, automatikoki izenburu berriari birzuzenduko zaio.
+Gogora ezazu, orrialdearen izena ez dela aldatuko, nahi duzun izena dagoeneko sortuta badago Wikipedian; birzuzenketa bat edo historiarik gabeko orrialde bat ez bada.
+
+<b>KONTUZ!</b>
+Artikulu oso erabilia edo asko aldatzen denaren izenburua aldatzera bazoaz, mesedez, lehenbizi artikuluaren eztabaidan adierazi ezazu beste lankideen iritziak jasotzeko.',
+'movepagetalktext' => 'Dagokion eztabaida orrialdea berarekin batera mugitu da, honako kasu hauetan \'\'\'ezik:\'\'\'
+* Hutsik ez dagoen eztabaida orrialde bat existitzen bada izen berrian.
+* Beheko koadroa hautatzen ez baduzu.
+
+Kasu horietan orrialdea eskuz mugitu edo bestearekin bateratu beharko duzu.',
+'movearticle' => 'Orrialdea mugitu',
+'movenologin' => 'Saioa hasi gabe',
+'movenologintext' => "Orrialde bat mugitzeko erregistratutako erabiltzailea izan behar duzu eta [[Special:Userlogin|saioa hasi]].",
+'newtitle' => 'Izenburu berria',
+'movepagebtn' => 'Orrialde mugitu',
+'pagemovedsub' => 'Mugimendua eginda',
+'pagemovedtext' => "\"$1\" izenburua \"$2\"(r)en truke aldatu da.",
+'articleexists' => 'Izen hori duen artikulu bat badago edo hautatutako izena ez da baliozkoa. Mesedez, beste izen bat aukeratu.',
+'talkexists' => "'''Orrialde hau arazorik gabe mugitu da, baina eztabaida orrialde ezin izan da mugitu izenburu berriarekin jada bat existitzen delako. Mesedez, eskuz batu itzazu biak.'''",
+'movedto' => 'hona mugitu da:',
+'movetalk' => 'Eztabaida orrialdea ere mugitu, ahal bada.',
+'talkpagemoved' => 'Artikulu honen eztabaida ere mugitu egin da.',
+'talkpagenotmoved' => 'Artikulu honen eztabaida <strong>ez</strong> da mugitu.',
+'1movedto2' => '$1 izenburua $2(r)engatik aldatu da',
+'1movedto2_redir' => '$1 izenburua $2(r)engatik aldatu da birzuzenketaren gainetik',
+'movelogpage' => 'Mugimendu erregistroa',
+'movelogpagetext' => 'Mugitutako orrialdeen zerrenda bat azaltzen da jarraian.',
+'movereason' => 'Arrazoia',
+'revertmove' => 'desegin',
+'delete_and_move' => 'Ezabatu eta mugitu',
+'delete_and_move_text' =>
+'== Ezabatzeko beharra ==
+
+"[[$1]]" helburua existitzen da. Lekua egiteko ezabatu nahi al duzu?',
+'delete_and_move_confirm' => 'Bai, orrialdea ezabatu',
+'delete_and_move_reason' => 'Lekua egiteko ezabatu da',
+'selfmove' => "Helburu izenburua berdina da; ezin da orrialde bat bere gainera mugitu.",
+'immobile_namespace' => "Hasierako edo amaierako izenburua Aparteko motakoa da; ezin da izen-tarte horretatik eta horretara ezer mugitu.",
+
+# Export
+
+'export' => 'Orrialdeak esportatu',
+'exporttext' => 'Orrialde bat edo batzuen testua eta historia esportatu dezakezu XML fitxategi batzuetan. Ondoren, MediaWiki erabiltzen duen beste wiki baten jarri dezakezu Special:Import orrialdea erabiliz.
+
+Orrialdeak esportatzeko zehaztu hauen izenburuak beheko koadroan, izenburu bat lerroko, eta aukeratu zein bertsio esportatu nahi dituzun.
+
+Horrez gain, lotura zuzena ere erabil dezakezu; adibidez, [[{{ns:Special}}:Export/{{int:mainpage}}]] {{int:mainpage}} orrialdearentzako.',
+'exportcuronly' => 'Oraingo berrikuspena bakarrik hartu, ez historia guztia',
+'exportnohistory' => "----
+'''Oharra:''' Formulario honen bitartez orrialdeen historia osoak esportatzeko aukera ezgaitu egin da, errendimendua dela-eta.",
+'export-submit' => 'Esportatu',
+
+# Namespace 8 related
+
+'allmessages' => 'Sistemako mezu guztiak',
+'allmessagesname' => 'Izena',
+'allmessagesdefault' => 'Testu lehenetsia',
+'allmessagescurrent' => 'Oraingo testua',
+'allmessagestext' => 'MediaWikin erabiltzen diren mezu guztien zerrenda:',
+'allmessagesnotsupportedUI' => 'Aukeratuta duzun hizkuntza (\'\'\'$1\'\'\') ez du Special:Allmessages orrialdeak onartzen gune honetan.',
+'allmessagesnotsupportedDB' => 'Ezin da \'\'\'Special:Allmessages\'\'\' erabili \'\'\'$wgUseDatabaseMessages\'\'\' ezgaituta dagoelako.',
+'allmessagesfilter' => 'Mezu izenaren iragazkia:',
+'allmessagesmodified' => 'Aldatutakoak bakarrik erakutsi',
+
+# Thumbnails
+
+'thumbnail-more' => 'Handitu',
+'missingimage' => '<b>Irudia falta da</b><br /><i>$1</i>',
+'filemissing' => 'Fitxategia falta da',
+'thumbnail_error' => 'Errorea irudi txikia sortzerakoan: $1',
+
+# Special:Import
+'import' => 'Orrialdeak inportatu',
+'importinterwiki' => 'Wikien arteko inportazioa',
+'import-interwiki-text' => 'Aukeratu inportatzeko wiki eta orrialde izenburu bat. Berrikuspenen datak eta egileak gorde egingo dira. Inportazio ekintza guzti hauek [[Special:Log/import|inportazio erregistroan]] gordetzen dira.',
+'import-interwiki-history' => 'Orrialde honen historiako bertsio guztiak kopiatu',
+'import-interwiki-submit' => 'Inportatu',
+'import-interwiki-namespace' => 'Izen-tarte honetako orrialdeak transferitu:',
+'importtext' => 'Mesedez, jatorrizko wikitik orrialdea esportatzeko Special:Export tresna erabil ezazu, zure diskoan gorde eta jarraian hona igo.',
+'importstart' => "Orrialdeak inportatzen...",
+'import-revision-count' => '{{PLURAL:$1|berrikuspen 1|$1 berrikuspen}}',
+'importnopages' => "Ez dago orrialderik inportatzeko.",
+'importfailed' => "Inportazioak huts egin du: $1",
+'importunknownsource' => "Inportazio iturri mota ezezaguna",
+'importcantopen' => "Ezin izan da inportazio fitxategia ireki",
+'importbadinterwiki' => "Interwiki lotura ezegokia",
+'importnotext' => 'Hutsik dago edo testurik gabe',
+'importsuccess' => 'Inportazioa burutu da!',
+'importhistoryconflict' => 'Gatazka sortzen ari den berrikuspen historia dago (baliteke orrialdea lehenago inportatu izana)',
+'importnosources' => 'Ez dago wikien arteko inportazio iturririk eta historialak zuzenean igotzea ezgaituta dago.',
+'importnofile' => 'Ez da inportazio fitxategirik igo.',
+'importuploaderror' => 'Inportazio fitxategiaren igoerak huts egin du; baliteke fitxategiaren tamaina baimendutakoa baino handiagoa izatea.',
+
+# import log
+'importlogpage' => 'Inportazio erregistroa',
+'importlogpagetext' => 'Beste wiki batzutatik historial eta guzti egindako orrialdeen inportazio administratiboak.',
+'import-logentry-upload' => '[[$1]] igoera bitartez inportatu da',
+'import-logentry-upload-detail' => '$1 berrikuspen',
+'import-logentry-interwiki' => '$1 wiki artean mugitu da',
+'import-logentry-interwiki-detail' => '$1 berrikuspen $2(e)tik',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => '{{SITENAME}}(e)n bilatu [alt-f]',
+'tooltip-minoredit' => 'Aldaketa txiki bezala markatu hau [alt-i]',
+'tooltip-save' => 'Zure aldaketak gorde [alt-s]',
+'tooltip-preview' => 'Zure aldaketak aurreikusi, mesedez gorde aurretik erabili! [alt-p]',
+'tooltip-diff' => 'Testuari egindako aldaketak erakutsi. [alt-v]',
+'tooltip-compareselectedversions' => 'Orrialde honen bi hautatutako bertsioen arteko ezberdintasunak ikusi. [alt-v]',
+'tooltip-watch' => 'Orrialde hau zure segimendu zerrendan gehitu [alt-w]',
+
+# stylesheets
+'common.css' => '/** Hemen idatzitako CSS kodeak itxura guztietan izango du eragina */',
+'monobook.css' => '/* Hemen idatzitako CSS kodeak Monobook itxuran bakarrik izango du eragina */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF metadatuak ezgaitu egin dira zerbitzari honetarako.',
+'nocreativecommons' => 'Creative Commons RDF metadatuak ezgaitu egin dira zerbitzari honetarako.',
+'notacceptable' => 'Wiki zerbitzariak ezin ditu datuak zure bezeroak irakur ditzakeen formatu batean eskaini.',
+
+# Attribution
+
+'anonymous' => '{{SITENAME}}(e)ko lankide anonimoak',
+'siteuser' => '{{SITENAME}}(e)ko $1 erabiltzailea',
+'lastmodifiedatby' => 'Orrialdearen azken aldaketa: $2, $1. Nork: $3.', // $1 date, $2 time. $3 user
+'and' => 'eta',
+'othercontribs' => '$1(r)en lanean oinarrituta.',
+'others' => 'besteak',
+'siteusers' => '{{SITENAME}}(e)ko $1 erabiltzailea(k)',
+'creditspage' => 'Orrialdearen kredituak',
+'nocredits' => 'Ez dago krediturik eskuragarri orrialde honentzako.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Spam-arengandik babesteko iragazkia',
+'spamprotectiontext' => 'Gorde nahi duzun orrialdea spam iragazkiak blokeatu du. Baliteke kanpo lotura batek sortzea arazo hori.',
+'spamprotectionmatch' => 'Gure spam iragazkiak testu hau antzeman du: $1',
+'subcategorycount' => "{{PLURAL:$1|Azpikategoria bat dago|$1 azpikategoria daude}} kategoria honetan.",
+'categoryarticlecount' => "Kategoria honetan {{PLURAL:$1|artikulu bakarra dago|$1 artikulu daude}}.",
+'listingcontinuesabbrev' => " jarr.",
+'spambot_username' => 'MediaWikiren spam garbiketa',
+'spam_reverting' => '$1(e)rako loturarik ez daukan azken bertsiora itzultzen',
+'spam_blanking' => 'Berrikuspen guztiek $1(e)rako lotura zeukaten, husten',
+
+# Info page
+'infosubtitle' => 'Orrialdearen informazioa',
+'numedits' => 'Aldaketa kopurua (artikulua): $1',
+'numtalkedits' => 'Aldaketa kopurua (eztabaida orrialdea): $1',
+'numwatchers' => 'Jarraitzaile kopurua: $1',
+'numauthors' => 'Egile ezberdinen kopurua (artikulua): $1',
+'numtalkauthors' => 'Egile ezberdinen kopurua (eztabaida orrialdea): $1',
+
+# Math options
+'mw_math_png' => 'Beti PNG irudiak sortu',
+'mw_math_simple' => 'Oso sinplea bada HTML, eta bestela PNG',
+'mw_math_html' => 'Posible bada HTML, eta bestela PNG',
+'mw_math_source' => 'TeX bezala utzi (testu bidezko nabigatzaileentzako)',
+'mw_math_modern' => 'Nabigatzaile berrientzako gomendatuta',
+'mw_math_mathml' => 'MathML posible bada (proba fasean)',
+
+# Patrolling
+'markaspatrolleddiff' => "Patruilatu bezala markatu",
+'markaspatrolledtext' => "Artikulu hau patruilatu bezala markatu",
+'markedaspatrolled' => "Patruilatu bezala markatu da",
+'markedaspatrolledtext' => "Hautatutako berrikuspena patruilatu bezala markatu da.",
+'rcpatroldisabled' => "Aldaketa berrien patruilaketa ezgaituta dago",
+'rcpatroldisabledtext' => "Aldaketa berrien patruilaketa ezaugarria ezgaituta dago orain.",
+'markedaspatrollederror' => "Ezin da patruilatu bezala markatu",
+'markedaspatrollederrortext' => "Patruilatu bezala markatzeko berrikuspen bat hautatu beharra daukazu.",
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Nire lankide orrialdea\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Zure IParen lankide orrialdea\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Nire eztabaida orrialdea\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Zure IParen eztabaida\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Nire hobespenak\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Jarraitzen dituzun orrialdeen zerrenda.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Nire ekarpenak\');
+ta[\'pt-login\'] = new Array(\'o\',\'Izen ematera gonbidatzen zaitugu.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Izen ematera gonbidatzen zaitugu.\');
+ta[\'pt-logout\'] = new Array(\'o\',\'Saioa itxi\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Artikuluari buruzko eztabaida\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Artikulu hau aldatu dezakezu. Mesedez, aurrebista botoia erabil ezazu gorde baino lehen.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Eztabaida honetan iruzkin bat erantsi ezazu.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Artikulu hau babesturik dago. Bere kodea soilik ikus dezakezu.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Artikulu honen aurreko bertsioak.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Artikulu hau babestu\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Artikulu hau ezabatu\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Ezabatu baino lehenago egindako aldaketak berrezarri.\');
+ta[\'ca-move\'] = new Array(\'m\',\'Orrialde hau mugitu\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Orrialde hau jarraipen zerrendan gehitu\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Orrialde hau jarraipen zerrendatik kendu\');
+ta[\'search\'] = new Array(\'f\',\'Wiki honetan bilatu\');
+ta[\'p-logo\'] = new Array(\'\',\'Azala\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Azala bisitatu\');
+ta[\'n-portal\'] = new Array(\'\',\'Proiektuaren inguruan, zer egin dezakezu, non aurkitu nahi duzuna\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Oraingo gertaeren inguruko informazio gehigarria\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Wikiko azken aldaketen zerrenda.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Ausazko orrialde bat kargatu\');
+ta[\'n-help\'] = new Array(\'\',\'Aurkitzeko lekua.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Lagun iezaguzu\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Hona lotzen duten wiki orrialde guztien zerrenda\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Orrialde honetatik lotutako orrialdeen azken aldaketak\');
+ta[\'feed-rss\'] = new Array(\'\',\'Orrialde honen RSS jarioa\');
+ta[\'feed-atom\'] = new Array(\'\',\'Orrialde honen atom jarioa\');
+ta[\'t-contributions\'] = new Array(\'\',\'Lankide honen ekarpen zerrenda ikusi\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Lankide honi e-posta mezua bidali\');
+ta[\'t-upload\'] = new Array(\'u\',\'Irudiak edo media fitxategiak igo\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Aparteko orrialde guztien zerrenda\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Eduki orrialdea ikusi\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Lankide orrialdea ikusi\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Media orrialdea ikusi\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Hau aparteko orrialde bat da, ezin duzu orrialdea aldatu.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Proiektuaren orrialdea ikusi\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Irudiaren orrialdea ikusi\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Sistemaren mezua ikusi\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Txantiloia ikusi\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Laguntza orrialdea ikusi\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Kategoria orrialdea ikusi\');',
+
+# image deletion
+'deletedrevision' => '$1 berrikuspen zaharra ezabatu da.',
+
+# browsing diffs
+'previousdiff' => '← Aurreko ezberdintasuna',
+'nextdiff' => 'Hurrengo ezberdintasuna →',
+
+'imagemaxsize' => 'Irudiak deskribapen-orrialdetan hurrengo tamainara txikitu:',
+'thumbsize' => 'Irudi txikiaren tamaina:',
+'showbigimage' => 'Bereizmen handiko bertsioa deskargatu ($1x$2, $3 KB)',
+
+'newimages' => 'Fitxategi berrien galeria',
+'showhidebots' => '($1 bot-ak)',
+'noimages' => 'Ez dago ezer ikusteko.',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+# variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+# variants for Kazakh language
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-cn' => 'kk-cn',
+'variantname-kk' => 'kk',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Lankidea:',
+'speciallogtitlelabel' => 'Izenburua:',
+
+'passwordtooshort' => 'Zure pasahitza laburregia da. $1 karaktere izan behar ditu gutxienez.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Oharra\'\'\': Fitxategi honek kode mingarria izan lezake; zure sisteman exekutatzea arriskutsua izan liteke.<hr />',
+
+'fileinfo' => '$1KB, MIME mota: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadatuak',
+'metadata-help' => 'Fitxategi honek informazio gehigarri dauka, ziurrenik kamera digital edo eskanerrak egiterako momentuan gehitutakoa. Hori dela-eta, jatorrizko fitxategi hori aldatu egin bada, baliteke xehetasun batzuek errealitatearekin bat ez egitea.',
+'metadata-expand' => 'Xehetasunak erakutsi',
+'metadata-collapse' => 'Xehetasunak ezkutatu',
+'metadata-fields' => 'Mezu honetan zerrendatutako EXIF metadatu eremuak irudiaren orrialdean erakutsiko dira. Gainontzekoak ezkutatu egindako dira lehenetsi bezala.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# Exif tags
+'exif-imagewidth' =>'Width',
+'exif-imagelength' =>'Height',
+'exif-bitspersample' =>'Bits per component',
+'exif-compression' =>'Compression scheme',
+'exif-photometricinterpretation' =>'Pixel composition',
+'exif-orientation' =>'Orientation',
+'exif-samplesperpixel' =>'Number of components',
+'exif-planarconfiguration' =>'Data arrangement',
+'exif-ycbcrsubsampling' =>'Subsampling ratio of Y to C',
+'exif-ycbcrpositioning' =>'Y and C positioning',
+'exif-xresolution' =>'Horizontal resolution',
+'exif-yresolution' =>'Vertical resolution',
+'exif-resolutionunit' =>'Unit of X and Y resolution',
+'exif-stripoffsets' =>'Image data location',
+'exif-rowsperstrip' =>'Number of rows per strip',
+'exif-stripbytecounts' =>'Bytes per compressed strip',
+'exif-jpeginterchangeformat' =>'Offset to JPEG SOI',
+'exif-jpeginterchangeformatlength' =>'Bytes of JPEG data',
+'exif-transferfunction' =>'Transfer function',
+'exif-whitepoint' =>'White point chromaticity',
+'exif-primarychromaticities' =>'Chromaticities of primarities',
+'exif-ycbcrcoefficients' =>'Color space transformation matrix coefficients',
+'exif-referenceblackwhite' =>'Pair of black and white reference values',
+'exif-datetime' =>'File change date and time',
+'exif-imagedescription' =>'Image title',
+'exif-make' =>'Camera manufacturer',
+'exif-model' =>'Camera model',
+'exif-software' =>'Software used',
+'exif-artist' =>'Author',
+'exif-copyright' =>'Copyright holder',
+'exif-exifversion' =>'Exif version',
+'exif-flashpixversion' =>'Supported Flashpix version',
+'exif-colorspace' =>'Color space',
+'exif-componentsconfiguration' =>'Meaning of each component',
+'exif-compressedbitsperpixel' =>'Image compression mode',
+'exif-pixelydimension' =>'Valid image width',
+'exif-pixelxdimension' =>'Valid image height',
+'exif-makernote' =>'Manufacturer notes',
+'exif-usercomment' =>'User comments',
+'exif-relatedsoundfile' =>'Related audio file',
+'exif-datetimeoriginal' =>'Date and time of data generation',
+'exif-datetimedigitized' =>'Date and time of digitizing',
+'exif-subsectime' =>'DateTime subseconds',
+'exif-subsectimeoriginal' =>'DateTimeOriginal subseconds',
+'exif-subsectimedigitized' =>'DateTimeDigitized subseconds',
+'exif-exposuretime' =>'Exposure time',
+'exif-exposuretime-format' => '$1 sec ($2)',
+'exif-fnumber' =>'F Number',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'Exposure Program',
+'exif-spectralsensitivity' =>'Spectral sensitivity',
+'exif-isospeedratings' =>'ISO speed rating',
+'exif-oecf' =>'Optoelectronic conversion factor',
+'exif-shutterspeedvalue' =>'Shutter speed',
+'exif-aperturevalue' =>'Aperture',
+'exif-brightnessvalue' =>'Brightness',
+'exif-exposurebiasvalue' =>'Exposure bias',
+'exif-maxaperturevalue' =>'Maximum land aperture',
+'exif-subjectdistance' =>'Subject distance',
+'exif-meteringmode' =>'Metering mode',
+'exif-lightsource' =>'Light source',
+'exif-flash' =>'Flash',
+'exif-focallength' =>'Lens focal length',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' =>'Subject area',
+'exif-flashenergy' =>'Flash energy',
+'exif-spatialfrequencyresponse' =>'Spatial frequency response',
+'exif-focalplanexresolution' =>'Focal plane X resolution',
+'exif-focalplaneyresolution' =>'Focal plane Y resolution',
+'exif-focalplaneresolutionunit' =>'Focal plane resolution unit',
+'exif-subjectlocation' =>'Subject location',
+'exif-exposureindex' =>'Exposure index',
+'exif-sensingmethod' =>'Sensing method',
+'exif-filesource' =>'File source',
+'exif-scenetype' =>'Scene type',
+'exif-cfapattern' =>'CFA pattern',
+'exif-customrendered' =>'Custom image processing',
+'exif-exposuremode' =>'Exposure mode',
+'exif-whitebalance' =>'White Balance',
+'exif-digitalzoomratio' =>'Digital zoom ratio',
+'exif-focallengthin35mmfilm' =>'Focal length in 35 mm film',
+'exif-scenecapturetype' =>'Scene capture type',
+'exif-gaincontrol' =>'Scene control',
+'exif-contrast' =>'Contrast',
+'exif-saturation' =>'Saturation',
+'exif-sharpness' =>'Sharpness',
+'exif-devicesettingdescription' =>'Device settings description',
+'exif-subjectdistancerange' =>'Subject distance range',
+'exif-imageuniqueid' =>'Unique image ID',
+'exif-gpsversionid' =>'GPS tag version',
+'exif-gpslatituderef' =>'North or South Latitude',
+'exif-gpslatitude' =>'Latitude',
+'exif-gpslongituderef' =>'East or West Longitude',
+'exif-gpslongitude' =>'Longitude',
+'exif-gpsaltituderef' =>'Altitude reference',
+'exif-gpsaltitude' =>'Altitude',
+'exif-gpstimestamp' =>'GPS time (atomic clock)',
+'exif-gpssatellites' =>'Satellites used for measurement',
+'exif-gpsstatus' =>'Receiver status',
+'exif-gpsmeasuremode' =>'Measurement mode',
+'exif-gpsdop' =>'Measurement precision',
+'exif-gpsspeedref' =>'Speed unit',
+'exif-gpsspeed' =>'Speed of GPS receiver',
+'exif-gpstrackref' =>'Reference for direction of movement',
+'exif-gpstrack' =>'Direction of movement',
+'exif-gpsimgdirectionref' =>'Reference for direction of image',
+'exif-gpsimgdirection' =>'Direction of image',
+'exif-gpsmapdatum' =>'Geodetic survey data used',
+'exif-gpsdestlatituderef' =>'Reference for latitude of destination',
+'exif-gpsdestlatitude' =>'Latitude destination',
+'exif-gpsdestlongituderef' =>'Reference for longitude of destination',
+'exif-gpsdestlongitude' =>'Longitude of destination',
+'exif-gpsdestbearingref' =>'Reference for bearing of destination',
+'exif-gpsdestbearing' =>'Bearing of destination',
+'exif-gpsdestdistanceref' =>'Reference for distance to destination',
+'exif-gpsdestdistance' =>'Distance to destination',
+'exif-gpsprocessingmethod' =>'Name of GPS processing method',
+'exif-gpsareainformation' =>'Name of GPS area',
+'exif-gpsdatestamp' =>'GPS date',
+'exif-gpsdifferential' =>'GPS differential correction',
+
+# Exif attributes
+
+'exif-compression-1' => 'Uncompressed',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normal', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Flipped horizontally', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Rotated 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Flipped vertically', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Rotated 90° CCW and flipped vertically', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Rotated 90° CW', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Rotated 90° CW and flipped vertically', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Rotated 90° CCW', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'chunky format',
+'exif-planarconfiguration-2' => 'planar format',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'does not exist',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Not defined',
+'exif-exposureprogram-1' => 'Manual',
+'exif-exposureprogram-2' => 'Normal program',
+'exif-exposureprogram-3' => 'Aperture priority',
+'exif-exposureprogram-4' => 'Shutter priority',
+'exif-exposureprogram-5' => 'Creative program (biased toward depth of field)',
+'exif-exposureprogram-6' => 'Action program (biased toward fast shutter speed)',
+'exif-exposureprogram-7' => 'Portrait mode (for closeup photos with the background out of focus)',
+'exif-exposureprogram-8' => 'Landscape mode (for landscape photos with the background in focus)',
+
+'exif-subjectdistance-value' => '$1 metres',
+
+'exif-meteringmode-0' => 'Unknown',
+'exif-meteringmode-1' => 'Average',
+'exif-meteringmode-2' => 'CenterWeightedAverage',
+'exif-meteringmode-3' => 'Spot',
+'exif-meteringmode-4' => 'MultiSpot',
+'exif-meteringmode-5' => 'Pattern',
+'exif-meteringmode-6' => 'Partial',
+'exif-meteringmode-255' => 'Other',
+
+'exif-lightsource-0' => 'Unknown',
+'exif-lightsource-1' => 'Daylight',
+'exif-lightsource-2' => 'Fluorescent',
+'exif-lightsource-3' => 'Tungsten (incandescent light)',
+'exif-lightsource-4' => 'Flash',
+'exif-lightsource-9' => 'Fine weather',
+'exif-lightsource-10' => 'Cloudy weather',
+'exif-lightsource-11' => 'Shade',
+'exif-lightsource-12' => 'Daylight fluorescent (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Day white fluorescent (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Cool white fluorescent (W 3900 – 4500K)',
+'exif-lightsource-15' => 'White fluorescent (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standard light A',
+'exif-lightsource-18' => 'Standard light B',
+'exif-lightsource-19' => 'Standard light C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO studio tungsten',
+'exif-lightsource-255' => 'Other light source',
+
+'exif-focalplaneresolutionunit-2' => 'inches',
+
+'exif-sensingmethod-1' => 'Undefined',
+'exif-sensingmethod-2' => 'One-chip color area sensor',
+'exif-sensingmethod-3' => 'Two-chip color area sensor',
+'exif-sensingmethod-4' => 'Three-chip color area sensor',
+'exif-sensingmethod-5' => 'Color sequential area sensor',
+'exif-sensingmethod-7' => 'Trilinear sensor',
+'exif-sensingmethod-8' => 'Color sequential linear sensor',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'A directly photographed image',
+
+'exif-customrendered-0' => 'Normal process',
+'exif-customrendered-1' => 'Custom process',
+
+'exif-exposuremode-0' => 'Auto exposure',
+'exif-exposuremode-1' => 'Manual exposure',
+'exif-exposuremode-2' => 'Auto bracket',
+
+'exif-whitebalance-0' => 'Auto white balance',
+'exif-whitebalance-1' => 'Manual white balance',
+
+'exif-scenecapturetype-0' => 'Standard',
+'exif-scenecapturetype-1' => 'Landscape',
+'exif-scenecapturetype-2' => 'Portrait',
+'exif-scenecapturetype-3' => 'Night scene',
+
+'exif-gaincontrol-0' => 'None',
+'exif-gaincontrol-1' => 'Low gain up',
+'exif-gaincontrol-2' => 'High gain up',
+'exif-gaincontrol-3' => 'Low gain down',
+'exif-gaincontrol-4' => 'High gain down',
+
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'Soft',
+'exif-contrast-2' => 'Hard',
+
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Low saturation',
+'exif-saturation-2' => 'High saturation',
+
+'exif-sharpness-0' => 'Normal',
+'exif-sharpness-1' => 'Soft',
+'exif-sharpness-2' => 'Hard',
+
+'exif-subjectdistancerange-0' => 'Unknown',
+'exif-subjectdistancerange-1' => 'Macro',
+'exif-subjectdistancerange-2' => 'Close view',
+'exif-subjectdistancerange-3' => 'Distant view',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'North latitude',
+'exif-gpslatitude-s' => 'South latitude',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'East longitude',
+'exif-gpslongitude-w' => 'West longitude',
+
+'exif-gpsstatus-a' => 'Measurement in progress',
+'exif-gpsstatus-v' => 'Measurement interoperability',
+
+'exif-gpsmeasuremode-2' => '2-dimensional measurement',
+'exif-gpsmeasuremode-3' => '3-dimensional measurement',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometres per hour',
+'exif-gpsspeed-m' => 'Miles per hour',
+'exif-gpsspeed-n' => 'Knots',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'True direction',
+'exif-gpsdirection-m' => 'Magnetic direction',
+
+# external editor support
+'edit-externally' => 'Fitxategi hau editatu kanpo-aplikazio bat erabiliz',
+'edit-externally-help' => 'Ikus [http://meta.wikimedia.org/wiki/Help:External_editors konfiguraziorako argibideak] informazio gehiagorako.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'guztiak',
+'imagelistall' => 'guztiak',
+'watchlistall1' => 'guztiak',
+'watchlistall2' => 'guztiak',
+'namespacesall' => 'guztiak',
+
+# E-mail address confirmation
+'confirmemail' => 'E-posta helbidea egiaztatu',
+'confirmemail_noemail' => 'Ez daukazu e-posta helbiderik zehaztuta zure [[Aparteko:Preferences|hobespenetan]].',
+'confirmemail_text' => "Wiki honetan zure e-posta helbidea egiaztatzea beharrezkoa da e-postarekin zerikusia duten ezaugarriak erabili aurretik. Beheko botoia jo zure helbidera egiaztapen mezu bat bidaltzeko. Mezuan kode bat duen lotura bat joango da atxikita; lotura hori zure nabigatzailean ireki ezazu e-posta helbidea egiaztatzeko.",
+'confirmemail_send' => 'Egiaztapen kodea e-postaz bidali',
+'confirmemail_sent' => 'Egiaztapen mezua bidali da.',
+'confirmemail_sendfailed' => 'Ezin izan da egiaztapen mezua bidali. Ziurtatu e-posta helbidean baliogabeko karaktererik ez dagoela. Zerbitzariaren mezua: $1',
+'confirmemail_invalid' => 'Baliogabeko egiaztapen kodea. Baliteke kodea iraungi izana.',
+'confirmemail_needlogin' => '$1 behar duzu zure e-posta helbidea egiaztatzeko.',
+'confirmemail_success' => 'Zure e-posta helbidea egiaztatu da. Saioa hasi eta ekarpenak egin ditzakezu orain.',
+'confirmemail_loggedin' => 'Zure e-posta helbidea egiaztatu da.',
+'confirmemail_error' => 'Akatsen bat gertatu da egiaztapena burutzerakoan.',
+
+'confirmemail_subject' => 'E-posta helbide egiaztapena {{SITENAME}}(e)n',
+'confirmemail_body' => "Norbaitek, ziurrenik zuk ($1 IP helbidetik), \"$2\" kontua erregistratu du {{SITENAME}}(e)n e-posta helbide honekin.
+
+Izen hori zuri dagokizula eta {{SITENAME}}(e)n zure e-posta egiaztatzeko, hurrengo lotura hau zure nabigatzailean ireki behar duzu:
+
+$3
+
+Zu *ez* bazara, ez jo lotura horretara. Egiaztapen kode hau $4 iraungiko da.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Izenburu zehatza bilatu',
+'searchfulltext' => 'Testu osoa bilatu',
+'createarticle' => 'Artikulua sortu',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Interwikien transklusioa ezgaituta dago]',
+'scarytranscludefailed' => '[Arazoa $1 txantiloia eskuratzerakoan; barkatu]',
+'scarytranscludetoolong' => '[URLa luzeegia da; barkatu]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks"> Artikulu honen aipuak:<br /> $1 </div>',
+'trackbackremove' => ' ([$1 Ezabatu])',
+'trackbacklink' => 'Aipua',
+'trackbackdeleteok' => 'Aipua ezabatu egin da.',
+
+
+# delete conflict
+
+'deletedwhileediting' => 'Oharra: Zu aldaketak egiten hasi ondoren ezabatu egin da orrialde hau!',
+'confirmrecreate' => '[[User:$1|$1]] erabiltzaileak ([[User talk:$1|eztabaida]]) orrialde hau ezabatu zu aldatzen hasi eta gero. Hona arrazoia: : \'\'$2\'\' Mesedez, baieztatu orrialde hau berriz sortu nahi duzula.',
+'recreate' => 'Birsortu',
+'tooltip-recreate' => 'Orrialdea birsortu ezabatu egin den arren',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => '[[$1]] orrialdera berbideratzen...',
+
+# action=purge
+'confirm_purge' => "Orrialde honen katxea ezabatu?
+
+$1",
+'confirm_purge_button' => 'Ados',
+
+'youhavenewmessagesmulti' => "Mezu berriak dituzu $1(e)n",
+'searchcontaining' => "''$1'' barne duten orrialdeen bilaketa.",
+'searchnamed' => "''$1'' izenburua duten artikuluen bilaketa.",
+'articletitles' => "''$1''(r)ekin hasten diren artikuluak",
+'hideresults' => 'Emaitzak ezkutatu',
+
+# DISPLAYTITLE
+'displaytitle' => '(Orrialde honetara lotzen da [[$1]] bezala)',
+
+'loginlanguagelabel' => 'Hizkuntza: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; aurreko orrialdea',
+'imgmultipagenext' => 'hurrengo orrialdea &rarr;',
+'imgmultigo' => 'Joan!',
+'imgmultigotopre' => 'Orrialdera jo',
+
+# Table pager
+'ascending_abbrev' => 'gor',
+'descending_abbrev' => 'behe',
+'table_pager_next' => 'Hurrengo orrialdea',
+'table_pager_prev' => 'Aurreko orrialdea',
+'table_pager_first' => 'Lehen orrialdea',
+'table_pager_last' => 'Azken orrialdea',
+'table_pager_limit' => 'Orrialdeko $1 elementu erakutsi',
+'table_pager_limit_submit' => 'Joan',
+'table_pager_empty' => 'Emaitzik ez',
+
+);
+
+?>
diff --git a/languages/messages/MessagesFa.php b/languages/messages/MessagesFa.php
new file mode 100644
index 000000000000..035c7264780e
--- /dev/null
+++ b/languages/messages/MessagesFa.php
@@ -0,0 +1,925 @@
+<?php
+/** Persian (فارسی)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$quickbarSettings = array(
+ 'نباشد', 'ثابت چپ', 'ثابت راست', 'شناور چپ'
+);
+
+$skinNames = array(
+ 'standard' => 'استاندارد',
+ 'nostalgia' => 'نوستالژی',
+ 'cologneblue' => 'آبی کلون',
+ 'smarty' => 'پدینگتون',
+ 'montparnasse' => 'مون‌پارناس',
+);
+$namespaceNames = array(
+ NS_MEDIA => 'مدیا',
+ NS_SPECIAL => 'ویژه',
+ NS_MAIN => '',
+ NS_TALK => 'بحث',
+ NS_USER => 'کاربر',
+ NS_USER_TALK => 'بحث_کاربر',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'بحث_$1',
+ NS_IMAGE => 'تصویر',
+ NS_IMAGE_TALK => 'بحث_تصویر',
+ NS_MEDIAWIKI => 'مدیاویکی',
+ NS_MEDIAWIKI_TALK => 'بحث_مدیاویکی',
+ NS_TEMPLATE => 'الگو',
+ NS_TEMPLATE_TALK => 'بحث_الگو',
+ NS_HELP => 'راهنما',
+ NS_HELP_TALK => 'بحث_راهنما',
+ NS_CATEGORY => 'رده',
+ NS_CATEGORY_TALK => 'بحث_رده'
+);
+
+$digitTransformTable = array(
+ "0" => "۰",
+ "1" => "۱",
+ "2" => "۲",
+ "3" => "۳",
+ "4" => "۴",
+ "5" => "۵",
+ "6" => "۶",
+ "7" => "۷",
+ "8" => "۸",
+ "9" => "۹",
+ "%" => "٪",
+ "." => "٫", // wrong table?
+ "," => "٬"
+);
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+ # Underlines seriously harm legibility. Force off:
+ 'underline' => 0,
+);
+$linkTrail = "/^([a-z]+)(.*)\$/sD"; /* This may need to be changed --RP */
+
+$messages = array(
+# User toggles
+
+'tog-underline' => "زیر پیوندها خط کشیده شود",
+'tog-highlightbroken' => "قالب‌بندی پیوندهای ناقص <a href=\"\" class=\"new\">به این شکل</a> (امکان دیگر: به این شکل<a href=\"\" class=\"internal\">؟</a>).",
+'tog-justify' => "تنظیم بندها",
+'tog-hideminor' => "نشان ندادن تغییرات جزئی در فهرست تغییرات اخیر",
+'tog-usenewrc' => "تغییرات اخیر گسترش‌یافته (برای هر مرورگری نیست)",
+'tog-numberheadings' => "شماره‌گذاری خودکار عناوین",
+'tog-showtoolbar'=>"نمایش نوار ابزار جعبه‌ی ویرایش",
+'tog-editondblclick' => "ویرایش صفحه‌ها با دوکلیک (جاوااسکریپت)",
+'tog-editsection'=>"به کار انداختن ویرایش قسمت‌ها از طریق پیوندهای [ویرایش]",
+'tog-editsectiononrightclick'=>"به کار انداختن ویرایش قسمت‌ها با کلیک راست<br />روی عناوین قسمت‌ها (جاوااسکریپت)",
+'tog-showtoc'=>"نمایش فهرست مندرجات<br />(برای مقالات با بیش از ۳ سرفصل)",
+'tog-rememberpassword' => "کلمه‌ی عبور برای نشست‌های بعدی بماند",
+'tog-editwidth' => "عرض جعبه‌ی ویرایش کامل باشد",
+'tog-watchdefault' => "افزودن صفحاتی که ویرایش می‌کند به فهرست تعقیبات",
+'tog-minordefault' => "پیش‌فرض همه‌ی ویرایش‌ها «جزئی» باشد",
+'tog-previewontop' => "نمایش پیش‌نمایش قبل از جعبه‌ی ویرایش و نه قبل از آن",
+'tog-nocache' => "از کار انداختن حافظه‌ی نهانی صفحات",
+# Dates
+
+'sunday' => "یک‌شنبه",
+'monday' => "دوشنبه",
+'tuesday' => "سه‌شنبه",
+'wednesday' => "چهارشنبه",
+'thursday' => "پنجشنبه",
+'friday' => "جمعه",
+'saturday' => "شنبه",
+'january' => "ژانویه",
+'february' => "فوریه",
+'march' => "مارس",
+'april' => "آوریل",
+'may_long' => "مه",
+'june' => "ژوئن",
+'july' => "ژوئیه",
+'august' => "اوت",
+'september' => "سپتامبر",
+'october' => "اکتبر",
+'november' => "نوامبر",
+'december' => "دسامبر",
+'jan' => "ژانویه",
+'feb' => "فوریه",
+'mar' => "مارس",
+'apr' => "آوریل",
+'may' => "مه",
+'jun' => "ژوئن",
+'jul' => "ژوئیه",
+'aug' => "اوت",
+'sep' => "سپتامبر",
+'oct' => "اکتبر",
+'nov' => "نوامبر",
+'dec' => "دسامبر",
+
+# Bits of text used by many pages:
+#
+'categories' => "رده‌های صفحات",
+'pagecategories' => "رده‌های صفحات",
+'category_header' => "مقاله‌های رده‌ی «$1»",
+'subcategories' => "زیررده‌ها",
+
+'mainpage' => "صفحه‌ی اصلی",
+'mainpagetext' => "نرم‌افزار ویکی با موفقیت نصب شد.",
+'about' => "درباره",
+'aboutsite' => "درباره‌ی {{SITENAME}}",
+'aboutpage' => "{{ns:project}}:درباره",
+'help' => "راهنما",
+'helppage' => "{{ns:project}}:راهنما",
+'bugreports' => "گزارش اشکالات",
+'bugreportspage' => "{{ns:project}}:گزارش اشکالات",
+'sitesupport' => "کمک مالی",
+'faq' => "سؤالات معمول",
+'faqpage' => "{{ns:project}}:سؤالات معمول",
+'edithelp' => "راهنمای ویرایش کردن",
+'edithelppage' => "{{ns:project}}:چگونه_صفحات_را_ویرایش_کنیم",
+'cancel' => "لغو",
+'qbfind' => "یافتن",
+'qbbrowse' => "مرور",
+'qbedit' => "ویرایش",
+'qbpageoptions' => "این صفحه",
+'qbpageinfo' => "بافت",
+'qbmyoptions' => "صفحات من",
+'qbspecialpages' => "صفحات ویژه",
+'moredotdotdot' => "بیشتر...",
+'mypage' => "صفحه‌ی من",
+'mytalk' => "بحث من",
+'currentevents' => "وقایع کنونی",
+'disclaimers' => "تکذیب‌نامه‌ها",
+'disclaimerpage' => "{{ns:project}}:تکذیب‌نامه‌ی عمومی",
+'errorpagetitle' => "خطا",
+'returnto' => "بازگشت به $1.",
+'whatlinkshere' => "صفحاتی که به اینجا پیوند دارند",
+'help' => "راهنما",
+'search' => "جستجو شود",
+'searchbutton' => "جستجو شود",
+'go' => "برود",
+'searcharticle' => "برود",
+'history' => "تاریخچه‌ی صفحه",
+'printableversion' => "نسخه‌ی قابل چاپ",
+'editthispage' => "ویرایش این صفحه",
+'deletethispage' => "حذف این صفحه",
+'protectthispage' => "محافظت از این صفحه",
+'unprotectthispage' => "از محافظت در آوردن این صفحه",
+'newpage' => "صفحه‌ی جدید",
+'talkpage' => "بحث درباره‌ی این صفحه",
+'postcomment' => "نوشتن نظر",
+'articlepage' => "نمایش مقاله",
+'userpage' => "نمایش صفحه‌ی کاربر",
+'projectpage' => "نمایش فوق صفحه",
+'imagepage' => "نمایش صفحه‌ی تصویر",
+'viewtalkpage' => "نمایش مباحثات",
+'otherlanguages' => "زبان‌های دیگر",
+'redirectedfrom' => "(تغییر مسیر از $1)",
+'lastmodifiedat' => "این صفحه آخرین بار در $2, $1 تغییر کرده است.",
+'viewcount' => "این صفحه $1 بار دیده شده است.",
+'protectedpage' => "صفحه‌ی محافظت‌شده",
+'nbytes' => "$1 بایت",
+'go' => "برو",
+'searcharticle' => "برو",
+'ok' => "باشد",
+'retrievedfrom' => "گرفته شده از «$1»",
+'editsection'=>"ویرایش",
+'editold'=>"ویرایش",
+'toc' => "فهرست مندرجات",
+'showtoc' => "نمایش داده شود",
+'hidetoc' => "مخفی شود",
+'thisisdeleted' => "نمایش یا احیای $1؟",
+'restorelink' => "$1 ویرایش حذف‌شده",
+
+# Main script and global functions
+#
+'nosuchaction' => "چنین عملی وجود ندارد",
+'nosuchactiontext' => "ویکی عمل مشخص شده در URL را نمی‌شناسد",
+'nosuchspecialpage' => "چنین صفحه‌ی ویژه‌ای وجود ندارد",
+'nospecialpagetext' => "شما صفحه‌ی ویژه‌ای را درخواست کرده‌اید که ویکی نمی‌شناسد.",
+
+# General errors
+#
+'error' => "خطا",
+'databaseerror' => "خطای پایگاه داده",
+'dberrortextcl' => "A database query syntax error has occurred.
+The last attempted database query was:
+\"$1\"
+from within function \"$2\".
+MySQL returned error \"$3: $4\".",
+'noconnect' => "شرمنده! ویکی مشکلات فنی دارد، و نمی‌تواند با خادم پایگاه داده تماس بگیرد.",
+'nodb' => "نمی‌توان پایگاه داده‌ی $1 را انتخاب کرد",
+'cachederror' => "در زیر یک نسخه‌ی بایگانی‌شده‌ی صفحه‌ی درخواستی می‌آید، و ممکن است به‌روز نباشد.",
+'readonly' => "پایگاه داده قفل شد",
+'enterlockreason' => "دلیلی برای قفل کردن ذکر کنید، شامل تقریبی برای زمانی که قفل برداشته خواهد شد",
+'readonlytext' => "The database is currently locked to new
+entries and other modifications, probably for routine database maintenance,
+after which it will be back to normal.
+The administrator who locked it offered this explanation:
+<p>$1",
+'missingarticle' => "پایگاه داده متن صفحه‌ای به نام «$1» را که باید می‌یافت، نیافت.
+
+<p>این مشکل معمولاٌ بر اثر ادامه دادن پیوندهای تاریخ‌گذشته‌ی تفاوت یا تاریخچه‌ی صفحاتی رخ می‌دهد که حذف شده‌اند.
+
+<p>اگر مورد شما این نیست، ممکن است اشکالی در نرم‌افزار پیدا کرده باشید.
+لطفاً این مسئله را، با ذکر URL، به یکی از مدیران گزارش کنید.",
+'internalerror' => "خطای داخلی",
+'filecopyerror' => "نتوانستم از پرونده‌ی «$1» روی «$2» نسخه‌برداری کنم.",
+'filerenameerror' => "نتوانستم پرونده‌ی «$1» را به «$2» تغییر نام دهم.",
+'filedeleteerror' => "نتوانستم پرونده‌ی «$1» را حذف کنم",
+'filenotfound' => "پرونده‌ی «$1» یافت نشد.",
+'unexpected' => "مقدار غیرمنتظره: «$1»=«$2».",
+'formerror' => "خطا: نمی‌توان فرم را فرستاد",
+'badarticleerror' => "نمی‌توان این عمل را بر این صفحه انجام داد.",
+'cannotdelete' => "نتوانستم صفحه را تصویر مشخص‌شده را حذف کنم. (ممکن است قبلاً کس دیگری آن را حذف کرده باشد.)",
+'badtitle' => "عنوان بد",
+'badtitletext' => "عنوان درخواستی نامعتبر، خالی، یا عنوانی بین زبانی یا بین‌ویکی‌ای با پیوند نادرست بود.",
+'perfdisabled' => "شرمنده! این امکان موفقتاً برداشته شده چون پایگاه داده را چنان کند می‌کند
+که هیچ کس نمی‌تواند از ویکی استفاده کند.",
+'perfdisabledsub' => "این نسخه‌ی ذخیره‌شده‌ای از $1 است:",
+'wrong_wfQuery_params' => "پارامترهای wfQuery() نادرست است<br />
+تابع: $1<br />
+پرس‌وجو: $2",
+'viewsource' => "نمایش مبدأ",
+'protectedtext' => "این صفحه برای جلوگیری از ویرایش قفل شده است؛ این کار ممکن است دلایل مختلفی داشته باشد. لطفاً به
+[[{{ns:project}}:صفحه‌ی محافظت‌شده]] مراجعه کنید.
+
+شما می‌توانید مبدأ این صفحه را مشاهده و تکثیر کنید:",
+
+# Login and logout pages
+#
+'logouttitle' => "خروج کاربر از سیستم",
+'logouttext' => "اکنون از سیستم خارج شدید.
+شما می‌توانید به استفاده‌ی گمنام از {{SITENAME}} ادامه دهید، یا می‌توانید با همین کاربر یا کاربر دیگری
+به سیستم وارد شوید. توجه کنید که تا زمانی که cache مرورگرتان را پاک کنید،
+بعضی صفحات ممکن است به شکلی نمایش یابند که انگار هنوز وارد سیستم هستید.",
+
+'welcomecreation' => "<h2>$1، خوش آمدید!</h2><p>حساب شما
+ایجاد شد.
+فراموش نکنید که ترجیحات {{SITENAME}} خود را
+تنظیم کنید.",
+
+'loginpagetitle' => "ورود کاربر به سیستم",
+'yourname' => "نام کاربری شما",
+'yourpassword' => "کلمه‌ی عبور شما",
+'yourpasswordagain' => "کلمه‌ی عبور را دوباره وارد کنید",
+'remembermypassword' => "کلمه‌ی عبور بین نشست‌ها به خاطر سپرده شود.",
+'loginproblem' => "<b>ورود شما به سیستم با مشکلی مواجه شد.</b><br />دوباره تلاش کنید!",
+'alreadyloggedin' => "<strong>کاربر $1, شما از قبل وارد سیستم شده‌اید!</strong><br />",
+
+'login' => "ورود به سیستم",
+'loginprompt' => "برای ورود به {{SITENAME}} باید cookieها را فعال کنید.",
+'userlogin' => "ورود به سیستم",
+'logout' => "خروج از سیستم",
+'userlogout' => "خروج از سیستم",
+'notloggedin' => "به سیستم وارد نشده‌اید",
+'createaccount' => "ایجاد حساب جدید",
+'createaccountmail' => "با پست الکترونیکی",
+'badretype' => "کلمه‌های عبوری که وارد کردید یکسان نیستند.",
+'userexists' => "نام کاربری‌ای که وارد کردید قبلاً استفاده شده است. لطفاً یک نام دیگر انتخاب کنید.",
+'youremail' => "پست الکترونیکی شما*",
+'yournick' => "لقب شما (برای امضاها)",
+'loginerror' => "خطا در ورود به سیستم",
+'nocookiesnew' => "حساب کاربری ایجاد شد، اما شما وارد سیستم نشدید. {{SITENAME}} برای ورود کاربران به سیستم از cookie استفاده می‌کند. شما
+cookieها را از کار انداخته‌اید. لطفاً cookieها را به کار بیندازید، و سپس با نام کاربری و کلمه‌ی عبور جدیدتان به سیستم وارد شوید.",
+'nocookieslogin' => "{{SITENAME}} برای ورود کاربران به سیستم از cookie استفاده می‌کند. شما cookieها را از کار
+انداخته‌اید. لطفاً cookieها را به کار بیندازید و دوباره تلاش کنید.",
+'noname' => "شما نام کاربری معتبری مشخص نکرده‌اید.",
+'loginsuccesstitle' => "ورود موفقیت‌آمیز به سیستم",
+'loginsuccess' => "شما اکنون با نام «$1» به {{SITENAME}} وارد شده‌اید.",
+'nosuchuser' => "کاربری با نام «$1» وجود ندارد.
+املای نام را بررسی کنید، یا از فرم زیر برای ایجاد یک حساب کاربری جدید استفاده کنید.",
+'wrongpassword' => "کلمه‌ی عبوری که وارد کردید نادرست است. لطفاٌ دوباره تلاش کنید.",
+'mailmypassword' => "یک کلمه‌ی عبور جدید به شما فرستاده شود",
+/* The following two passwordreminder messages should not be translated, in case
+ the user doesn't use email software able to read Persian. */
+//inherit en//'passwordremindertitle' => '',
+//inherit en//'passwordremindertext' => '',
+'noemail' => "هیچ نشانی پست الکترونیکی‌ای برای کاربر «$1» ثبت نشده است.",
+'passwordsent' => "یک کلمه‌ی عبور جدید به نشانی الکترونیکی ثبت شده برای کاربر «$1» فرستاده شد.
+لطفاٌ پس از دریافت آن دوباره به سیستم وارد شوید.",
+
+# Edit page toolbar
+'bold_sample'=>"متن سیاه",
+'bold_tip'=>"متن سیاه",
+'italic_sample'=>"متن ایتالیک",
+'italic_tip'=>"متن ایتالیک",
+'link_sample'=>"عنوان پیوند",
+'link_tip'=>"پیوند داخلی",
+'extlink_sample'=>"http://www.example.com عنوان پیوند",
+'extlink_tip'=>"پیوند خارجی (پیشوند http://‎ را فراموش نکنید)",
+'headline_sample'=>"متن عنوان",
+'headline_tip'=>"عنوان سطح ۲",
+'math_sample'=>"درج فرمول در اینجا",
+'math_tip'=>"فرمول ریاضی (LaTeX)",
+'nowiki_sample'=>"اینجا متن قالب‌بندی‌نشده وارد شود",
+'nowiki_tip'=>"نادیده گرفتن قالب‌بندی ویکی",
+'image_sample'=>"مثال.jpg",
+'image_tip'=>"تصویر داخل متن",
+'media_sample'=>"مثال.mp3",
+'media_tip'=>"پیوند پرونده‌ی رسانه",
+'sig_tip'=>"امضای شما و برچسب زمان",
+'hr_tip'=>"خط افقی (با صرفه‌جویی استفاده کنید)",
+
+# Edit pages
+#
+'summary' => "خلاصه",
+'subject' => "موضوع/عنوان",
+'minoredit' => "این ویرایش جزئی است",
+'watchthis' => "تعقیب این مقاله",
+'savearticle' => "صفحه ذخیره شود",
+'preview' => "پیش‌نمایش",
+'showpreview' => "پیش‌نمایش نمایش یابد",
+'blockedtitle' => "کاربر بسته شده است",
+'blockedtext' => "نام کاربری یا نشانی IP شما توسط $1 بسته شده است.
+دلیل داده‌شده این است:<br />''$2''<p>شما می‌توانید با $1 یا یکی از
+[[{{ns:project}}:مدیران|مدیران]] تماس بگیرید و در این باره صحبت کنید.
+
+توجه کنید که شما نمی‌توانید از امکان «فرستادن پست الکترونیکی به این کاربر» استفاده کنید مگر اینکه نشانی پست الکترونیکی
+معتبری در [[ویژه:ترجیحات|ترجیحات کاربری]]‌تان ثبت کرده باشید.
+
+نشانی IP شما $3 است. لطفاً این نشانی را در کلیه‌ی پرس‌وجوهایتان ذکر کنید.
+
+==نکته برای کاربران AOL==
+به خاطر اعمال تخریبی یک کاربر مشخص AOL، {{SITENAME}} معمولاً proxyهای AOL را می‌بندد.
+متأسفانه ممکن است تعداد زیادی از کاربران AOL از یک خادم proxy واحد استفاده کنند، و در نتیجه کاربران بی‌تقصیر AOL معمولاً ندانسته بسته می‌شوند.
+از دردسر ایجاد شده عذر می‌خواهیم.
+
+اگر این اتفاق برای شما افتاد، لطفاً به یکی از مدیران از یک نشانی پست الکترونیک AOL پیغام بفرستید. حتماً نشانی IPی را در فوق داده شده
+ذکر کنید.",
+'whitelistedittitle' => "برای ویرایش باید به سیستم وارد شوید",
+'whitelistedittext' => "برای ویرایش مقاله‌ها باید به سیستم [[ویژه:Userlogin|وارد]] شوید.",
+'whitelistreadtitle' => "برای خواندن باید به سیستم وارد شوید",
+'whitelistreadtext' => "
+برای خواندن مقالات باید [[ویژه:Userlogin|به سیستم وارد شوید]].",
+'whitelistacctitle' => "شما مجاز نیستید حساب درست کنید.",
+'whitelistacctext' => "برای ایجاد حساب در این ویکی باید [[ویژه:Userlogin|به سیستم وارد شوید]] و اجازه
+‌های مربوط به این کار را داشته باشید.",
+'accmailtitle' => "کلمه‌ی عبور فرستاده شد.",
+'accmailtext' => "کلمه‌ی عبور «$1» به «$2» فرستاده شد.",
+'newarticle' => "(جدید)",
+'newarticletext' =>
+"شما پیوندی را دنبال کرده‌اید و به صفحه‌ای رسیده‌اید که هنوز وجود ندارد.
+برای ایجاد صفحه، در مستطیل زیر شروع به تایپ کنید
+(برای اطلاعات بیشتر به [[{{ns:project}}:راهنما|صفحه‌ی راهنما]] مراجعه کنید).
+اگر اشتباهاً اینجا آمده‌اید، دکمه‌ی '''back''' مرورگرتان را بزنید.",
+'anontalkpagetext' => "---- ''این صفحه‌ی بحث برای کاربر گمنامی است که هنوز حسابی درست نکرده است یا از آن استفاده نمی‌کند.
+بنابراین برای شناسایی‌اش مجبوریم از [[نشانی IP]] عددی استفاده کنیم. چنین نشانی‌های IPای ممکن است توسط چندین کاربر به شکل
+مشترک استفاده شود.
+اگر شما کاربر گمنامی هستید و تصور می‌کنید اظهار نظرات نامربوط به شما صورت گرفته است،
+لطفاً برای پیشگیری از اشتباه گرفته شدن با کاربران گمنام دیگر در آیند [[ویژه:Userlogin|حسابی ایجاد کنید یا به سیستم وارد شوید]].''",
+'noarticletext' => "(این صفحه در حال حاضر متنی ندارد)",
+'updated' => "(به‌روز شد)",
+'note' => "<strong>نکته:</strong>",
+'previewnote' => "توجه کنید که این فقط پیش‌نمایش است، و ذخیره نشده است!",
+'previewconflict' => "این پیش‌نمایش منعکس‌کننده‌ی متن ناحیه‌ی ویرایش متن بالایی است،
+به شکلی که اگر بخواهید متن را ذخیره کنید نشان داده خواهد شد.",
+'editing' => "در حال ویرایش $1",
+'editinguser' => "در حال ویرایش $1",
+'editingsection' => "در حال ویرایش $1 (قسمت)",
+'editingcomment' => "در حال ویرایش $1 (یادداشت)",
+'editconflict' => "تعارض ویرایشی: $1",
+'explainconflict' => "از وقتی شما ویرایش این صفحه را آغاز کرده‌اید شخص دیگری آن را تغییر داده است.
+ناحیه‌ی متنی بالایی شامل متن صفحه به شکل فعلی آن است.
+تغییرات شما در ناحیه‌ی متنی پایینی نشان داده شده است.
+شما باید تغییراتتان را با متن فعلی ترکیب کنید.
+وقتی «ذخیره‌ی صفحه» را فشار دهید، <b>فقط</b> متن ناحیه‌ی متنی بالایی ذخیره خواهد شد.<br />",
+'yourtext' => "متن شما",
+'storedversion' => "نسخه‌ی ضبط‌شده",
+'editingold' => "<strong>هشدار:
+شما دارید نسخه‌ی قدیمی‌ای از این صفحه را ویرایش می‌کنید.
+اگر ذخیره‌اش کنید، هر تغییری که پس از این نسخه انجام شده از بین خواهد رفت.</strong>",
+'yourdiff' => "تفاوت‌ها",
+# FIXME: This is inappropriate for third-party use!
+/*'copyrightwarning' => "لطفاٌ توجه داشته باشید که فرض می‌شود کلیه‌ی مشارکت‌های شما با {{SITENAME}}
+تحت اجازه‌نامه‌ی مستندات آزاد گنو منتشر می‌شوند
+(برای جزئیات بیشتر به $1 مراجعه کنید).
+اگر نمی‌خواهد نوشته‌هایتان بیرحمانه ویرایش شده و به دلخواه توزیع شود،
+اینجا نفرستیدشان.<br />
+همینطور شما دارید به ما قول می‌دهید که خودتان این را نوشته‌اید، یا آن را از یک منبع آزاد با
+مالکیت عمومی یا مشابه آن برداشته‌اید.
+<strong>کارهای دارای حق انحصاری تکثیر (کپی‌رایت) را بی اجازه نفرستید!</strong>",*/
+'longpagewarning' => "<strong>هشدار: این صفحه $1 کیلوبایت طول دارد؛
+بعضی مرورگرها ممکن با ویرایش صفحات نزدیک به ۳۲ کیلوبایت یا طولانیتر از آن مشکلاتی داشته باشند.
+لطفاً درباره‌ی شکستن این صفحه به قسمت‌های کوچکتر فکر کنید.</strong>",
+'readonlywarning' => "<strong>هشدار: پایگاه داده برای نگهداری قفل شده است،
+بنابراین نمی‌توانید ویرایش‌هایتان را همین الآن ذخیره کنید.
+اگر می‌خواهید متن را در یک پرونده‌ی متنی ببرید و بچسبانید و برای آینده ذخیره‌اش کنید.</strong>",
+'protectedpagewarning' => "<strong>هشدار: این صفحه قفل شده است تا فقط کاربران با امتیاز اپراتور سیستم بتوانند ویرایشش کنند.
+مطمئن شوید که از
+[[{{ns:project}}:توصیه‌های صفحات محافظت‌شده|توصیه‌های صفحات محافظت‌شده]] پیروی می‌کنید.<strong>",
+
+# History pages
+#
+'revhistory' => "تاریخچه‌ی تغییرات",
+'nohistory' => "این صفحه تاریخچه‌ی ویرایش ندارد.",
+'revnotfound' => "نسخه یافت نشد",
+'revnotfoundtext' => "نسخه‌ی قدیمی‌از از صفحه که درخواست کرده بودید یافت نشد.
+لطفاً URLی را که برای دسترسی به این صفحه استفاده کرده‌اید بررسی کنید.n",
+'loadhist' => "در حال خواندن تاریخچه‌ی صفحه",
+'currentrev' => "نسخه‌ی فعلی",
+'revisionasof' => "نسخه‌ی $1",
+'cur' => "فعلی",
+'next' => "بعدی",
+'last' => "آخرین",
+'orig' => "اصلی",
+'histlegend' => "شرح: (فعلی) = تفاوت با نسخه‌ی فعلی،
+(آخرین) = تفاوت با نسخه‌ی قبلی، جز = ویرایش جزئی",
+
+# Diffs
+#
+'difference' => "(تفاوت بین نسخه‌ها)",
+'loadingrev' => "در حال خواندن نسخه برای تفاوت گرفتن",
+'lineno' => "سطر $1:",
+'editcurrent' => "ویرایش نسخه‌ی فعلی این صفحه",
+
+# Search results
+#
+'searchresults' => "نتایج جستجو",
+'searchresulttext' => "برای اطلاعات بیشتر درباره‌ی جستجوی {{SITENAME}}، به [[{{ns:project}}:جستجو کردن|جستجوی {{SITENAME}}]] مراجعه کنید.",
+'searchsubtitle' => "برای پرس‌وجوی «[[:$1]]»",
+'searchsubtitleinvalid' => "برای پرس‌وجوی «$1»",
+'badquery' => "پرس‌وجوی جستجویی بدشکل",
+'badquerytext' => "نتوانستیم پرس‌وجوی شما را پردازش کنیم.
+این مشکل احتمالاً به این دلیل است که سعی کرده‌اید به دنبال کلمه‌ای کوتاهتر از سه حرف
+بگردید، که هنوز پشتیبانی نمی‌شود.
+همین‌طور ممکن است عبارت را اشتباه وارد کرده باشید، مثلاً «ماهی و و پولک».
+لطفاً یک پرس‌وجوی دیگر را امتحان کنید.",
+'matchtotals' => "پرس‌وجوی «$1» متناظر $2 عنوان مقاله
+و $3 متن مقاله است.",
+'noexactmatch' => "صفحه‌ی با دقیقاً این عنوان وجود ندارد، تلاش برای جستجوی کل متن.",
+'titlematches' => 'Article title matches',
+'notitlematches' => "عنوان هیچ مقاله‌ای نمی‌خورد",
+'textmatches' => 'Article text matches',
+'notextmatches' => "متن هیچ مقاله‌ای نمی‌خورد",
+'prevn' => "$1تای قبلی",
+'nextn' => "$1تای بعدی",
+'viewprevnext' => "نمایش ($1) ($2) ($3).",
+'showingresults' => "Showing below <b>$1</b> results starting with #<b>$2</b>.",
+'showingresultsnum' => "Showing below <b>$3</b> results starting with #<b>$2</b>.",
+'nonefound' => "<strong>نکته</strong>: unsuccessful searches are
+often caused by searching for common words like \"have\" and \"from\",
+which are not indexed, or by specifying more than one search term (only pages
+containing all of the search terms will appear in the result).",
+'powersearch' => "جستجو",
+'powersearchtext' => "
+جستجو در فضاهای نام :<br />
+$1<br />
+$2 تغییرمسیرها فهرست شوند &nbsp; جستجو برای $3 $9",
+'searchdisabled' => "<p>شرمنده! جستجوی کل متن موقتاً از کار انداخته شده, for performance reasons. In the meantime, you can use the Google search below, which may be out of date.</p>",
+'blanknamespace' => "(اصلی)",
+
+# Preferences page
+#
+'preferences' => "ترجیحات",
+'prefsnologin' => "به سیستم وارد نشده‌اید",
+'prefsnologintext' => "برای تنظیم ترجیحات کاربر باید [[ویژه:Userlogin|به سیستم وارد شوید]].",
+'prefsreset' => "ترجیحات از حافظه میزان شد.",
+'qbsettings' => "تنظیمات نوار سریع",
+'changepassword' => "تغییر کلمه‌ی عبور",
+'skin' => "پوسته",
+'math' => "نمایش ریاضیات",
+'dateformat' => "قالب تاریخ",
+'math_failure' => "شکست در تجزیه",
+'math_unknown_error' => "خطای ناشناخته",
+'math_unknown_function' => "تابع ناشناخته‌ی",
+'math_lexing_error' => "خطای lexing",
+'math_syntax_error' => "خطای نحوی",
+'math_image_error' => "تبدیل به PNG شکست خورد",
+'saveprefs' => "ذخیره‌ی ترجیحات",
+'resetprefs' => "صفر کردن ترجیحات",
+'oldpassword' => "کلمه‌ی عبور قدیمی",
+'newpassword' => "کلمه‌ی عبور جدید",
+'retypenew' => "کلمه‌ی عبور جدید را دوباره وارد کنید",
+'textboxsize' => "ابعاد جعبه‌ی متن",
+'rows' => "تعداد سطرها",
+'columns' => "تعداد ستون‌ها",
+'searchresultshead' => "تنظیمات نتیجه‌ی جستجو",
+'resultsperpage' => "تعداد نتایج در هر صفحه",
+'contextlines' => "تعداد سطرها در هر نتیجه",
+'contextchars' => "تعداد نویسه‌های اطراف در سطر",
+'stubthreshold' => "آستانه‌ی نمایش ناقص‌ها",
+'recentchangescount' => "تعداد عناوین در تغییرات اخیر",
+'savedprefs' => "ترجیحات شما ذخیره شد.",
+'timezonetext' => "تفاوت تعداد ساعت زمان محلی‌تان با زمان خادم (وقت گرینیچ) را وارد کنید.",
+'localtime' => "نمایش زمان محلی",
+'timezoneoffset' => "تفاوت",
+'servertime' => "زمان فعلی خادم",
+'guesstimezone' => "از مرورگر گرفته شود",
+'defaultns' => "به طور پیشفرض در این فضاهای نام جستجو شود:",
+
+# Recent changes
+#
+'changes' => "تغییرات",
+'recentchanges' => "تغییرات اخیر",
+'recentchangestext' => "آخرین تغییرات ویکی را در این صفحه تعقیب کنید.",
+'rcnote' => "در زیر آخرین <strong>$1</strong> تغییر در <strong>$2</strong> روز اخیر آمده است.",
+'rcnotefrom' => "در زیر تغییرات از تاریخ <b>$2</b> آمده‌اند (تا <b>$1</b> مورد نشان داده می‌شود).",
+'rclistfrom' => "نمایش تغییرات جدید با شروع از $1",
+'rclinks' => "نمایش آخرین $1 تغییر در $2 روز اخیر؛ $3",
+'diff' => "تفاوت",
+'hist' => "تاریخچه",
+'hide' => "مخفی شود",
+'show' => "نمایش یابد",
+'minoreditletter' => "جز",
+'newpageletter' => "جد",
+
+# Upload
+#
+'upload' => "بار کردن پرونده",
+'uploadbtn' => "پرونده بار شود",
+'reupload' => "بار کردن مجدد",
+'reuploaddesc' => "بازگشت به فرم بار کردن",
+'uploadnologin' => "به سیستم وارد نشده‌اید",
+'uploadnologintext' => "برای بار کردن پرونده‌ها باید [[ویژه:Userlogin|وارد سیستم شوید]].",
+'uploaderror' => "خطا در بار کردن",
+'uploadtext' => "'''ایست!''' قبل از این که چیزی اینجا بار کنید،
+مطمئن شوید که
+[[{{ns:project}}:سیاست_استفاده_از_تصاویر|سیاست استفاده از تصاویر]]
+را خوانده‌اید و از آن پیروی می‌کنید.
+
+If a file with the name you are specifying already
+exists on the wiki, it'll be replaced without warning.
+So unless you mean to update a file, it's a good idea
+to first check if such a file exists.
+
+To view or search previously uploaded images,
+go to the [[Special:Imagelist|list of uploaded images]].
+Uploads and deletions are logged on the
+[[{{ns:project}}:Upload_log|upload log]].
+
+Use the form below to upload new image files for use in
+illustrating your articles.
+On most browsers, you will see a \"Browse...\" button, which will
+bring up your operating system's standard file open dialog.
+Choosing a file will fill the name of that file into the text
+field next to the button.
+You must also check the box affirming that you are not
+violating any copyrights by uploading the file.
+Press the \"Upload\" button to finish the upload.
+This may take some time if you have a slow internet connection.
+
+The preferred formats are JPEG for photographic images, PNG
+for drawings and other iconic images, and OGG for sounds.
+Please name your files descriptively to avoid confusion.
+To include the image in an article, use a link in the form
+'''<nowiki>[[image:file.jpg]]</nowiki>''' or
+'''<nowiki>[[image:file.png|alt text]]</nowiki>''' or
+'''<nowiki>[[media:file.ogg]]</nowiki>''' for sounds.
+
+Please note that as with wiki pages, others may edit or
+delete your uploads if they think it serves the encyclopedia, and
+you may be blocked from uploading if you abuse the system.",
+
+'uploadlog' => "سیاهه‌ی بارکردن‌ها",
+'uploadlogpage' => "سیاهه‌ی_بارکردن‌ها",
+'uploadlogpagetext' => "فهرست زیر فهرستی از آخرین بارکردن‌های پرونده‌های است.
+همه‌ی زمان‌های نشان‌داده‌شده زمان خادم هستند (وقت گرینیچ).
+<ul>
+</ul>",
+'filename' => "نام پرونده",
+'filedesc' => "خلاصه",
+'filestatus' => "وضعیت حق تکثیر",
+'filesource' => "منبع",
+'copyrightpage' => "{{ns:project}}:حق_تکثیر",
+'copyrightpagename' => "حق تکثیر {{SITENAME}}",
+'uploadedfiles' => "پرونده‌های بارشده",
+'minlength' => "نام پرونده باید حداقل سه‌حرفی باشد.",
+'badfilename' => "نام پرونده به «$1» تغییر کرد.",
+'badfiletype' => "قالب پرونده‌ای «‎.$1» برای پرونده‌های تصویری توصیه نمی‌شود.",
+'largefile' => "توصیه می‌شود که اندازه‌ی تصاویر از ۱۰۰ کیلوبایت بیشتر نباشد.",
+'successfulupload' => "بار کردن با موفقیت انجام شد",
+'fileuploaded' => "پرونده‌ی «$1» با موفقیت بار شد.
+لطفاً این پیوند را تعقیب کنید: ($2) تا صفحه‌ی توصیف و اطلاعات در مورد
+پرونده را، از قبیل این که از کجا آمده است، چه کسی و در چه زمانی آن را ایجاد کرده است،
+و هر چیز دیگری که ممکن است در مورد آن بدانید، پر کنید.",
+'uploadwarning' => "هشدار بار کردن",
+'savefile' => "ذخیره‌ی پرونده",
+'uploadedimage' => "«[[$1]]» بار شد",
+'uploaddisabled' => "شرمنده، بار کردن از کار افتاده است.",
+
+# Image list
+#
+'imagelist' => "فهرست تصاویر",
+'imagelisttext' => "در زیر فهرست $1 تصویری که $2 مرتب شده است آمده است.",
+'getimagelist' => "در حال اخذ فهرست تصاویر",
+'ilsubmit' => "جستجو",
+'showlast' => "نمایش آخرین $1 تصویر مرتب‌شده $2.",
+'byname' => "از روی نام",
+'bydate' => "از روی تاریخ",
+'bysize' => "از روی اندازه",
+'imgdelete' => "حذف",
+'imgdesc' => "توصیف",
+'imglegend' => "شرح: (توصیف) = نمایش/ویرایش توصیف تصویر.",
+'imghistory' => "تاریخچه‌ی تصویر",
+'revertimg' => "برگرد",
+'deleteimg' => "حذف",
+'deleteimgcompletely' => "حذف",
+'imghistlegend' => "شرح: (فعلی) = این تصویر فعلی است، (حذف) = این
+نسخه‌ی قدیمی حذف شود، (برگرد) = برگرداندن به این نسخه‌ی قدیمی.
+<br /><i>برای دیدن تصویر بار شده در تاریخ مشخص، روی تاریخ کلیک کنید</i>.",
+'imagelinks' => "پیوند‌های تصاویر",
+'linkstoimage' => "این صفحات به این تصویر پیوند دارند:",
+'nolinkstoimage' => "هیچ صفحه‌ای به این تصویر پیوند ندارد.",
+
+# Statistics
+#
+'statistics' => "آمار",
+'sitestats' => "آمار وبگاه",
+'userstats' => "آمار کاربران",
+'sitestatstext' => "کلاً <b>$1</b> صفحه در پایگاه داده هست.
+این شامل صفحات «بحث»، صفحات درباره‌ی {{SITENAME}}، صفحات «ناقص» کوچک،
+تغییرمسیرها، و صفحات دیگری می‌شود که احتمالاً مقاله به حساب نمی‌آیند.
+فارق از این‌ها، <b>$2</b> صفحه هست که احتمالاً مقاله‌ی معقول هستند.<p>
+از زمانی که نرم‌افزار ارتقا یافته (۲۰ ژوئیه‌ی ۲۰۰۲)، کلاً <b>$3</b> بازدید از صفحات،
+و <b>$4</b> ویرایش صفحات صورت گرفته است.
+این می‌شود به طور متوسط <b>$5</b> ویرایش برای هر صفحه، و <b>$6</b> بازدید به‌ازای هر ویرایش.",
+'userstatstext' => "تعداد <b>$1</b> کاربر ثبت‌شده وجود دارد.
+تعداد <b>$2</b> از این کاربران مدیرند (به $3 مراجعه شود).",
+
+# Maintenance Page
+#
+'disambiguations' => "صفحات رفع ابهام",
+'disambiguationspage' => "{{ns:project}}:پیوند به صفحات رفع ابهام",
+'disambiguationstext' => "مقاله‌های زیر به یک <i>صفحه‌ی رفع ابهام</i> پیوند دارند. به جای این، این صفحات باید به
+They should link to the appropriate topic instead.<br />A page is treated as dismbiguation if it is linked from $1.<br />Links from other namespaces are <i>not</i> listed here.",
+'doubleredirects' => "تغییرمسیرهای دوتایی",
+'brokenredirects' => "تغییرمسیرهای خراب",
+'brokenredirectstext' => "تغییرمسیرهای زیر به یک صفحه‌ی ناموجود پیوند دارند.",
+
+
+# Miscellaneous special pages
+#
+'lonelypages' => "صفحات یتیم",
+'unusedimages' => "تصاویر بلااستفاده",
+'popularpages' => "صفحات محبوب",
+'nviews' => "$1 نمایش",
+'wantedpages' => "صفحات مورد نیاز",
+'nlinks' => "$1 پیوند",
+'allpages' => "همه‌ی صفحات",
+'randompage' => "صفحه‌ی تصادفی",
+'shortpages' => "صفحات کوتاه",
+'longpages' => "صفحات بلند",
+'deadendpages' => "صفحات بن‌بست",
+'listusers' => "فهرست کاربران",
+'specialpages' => "صفحات ویژه",
+'spheading' => "صفحات ویژه‌ی همه‌ی کاربران",
+'recentchangeslinked' => "تغییرات مرتبط",
+'rclsub' => "(به صفحات پیونددار از «$1»)",
+'newpages' => "صفحات جدید",
+'ancientpages' => "قدیمی‌ترین مقاله‌ها",
+'intl' => "پیوندهای بین زبانی",
+'movethispage' => "انتقال این صفحه",
+'unusedimagestext' => "<p>لطفاٌ توجه کنید که وبگاه‌های دیگر از جمله {{SITENAME}}های بین‌المللی
+ممکن است با URL مستقیم به تصاویر پیوند داشته باشند، و نتیجتاً با وجود استفاده‌ی فعال
+اینجا فهرست شده باشند.",
+'booksources' => "منابع کتاب",
+# FIXME: Other sites, of course, may have affiliate relations with the booksellers list
+'booksourcetext' => "در زیر فهرستی از پیوندها به وبگاه‌های دیگری که کتاب‌های نو و دست دوم می‌فروشند آمده است،
+و ممکن است اطلاعات بیشتری نیز درباره‌ی کتاب‌هایی که دنبالشان می‌گردید داشته باشند.
+{{SITENAME}} وابستگی یا ارتباطی با هیچ یک از این کسب‌وکارها ندارد، و این فهرست
+نباید به معنی تأیید یا حمایت تعبیر شود.",
+'alphaindexline' => "$1 تا $2",
+
+# Email this user
+#
+'mailnologin' => "نشانی فرستنده‌ای نیست",
+'mailnologintext' => "برای فرستادن پست الکترونیکی به کاربران دیگر باید [[ویژه:Userlogin|به سیستم وارد شوید]]
+و نشانی پست الکترونیکی معتبری در [[ویژه:ترجیحات|ترجیحات]]
+خود داشته باشید.",
+'emailuser' => "پست الکترونیکی به این کاربر",
+'emailpage' => "پست الکترونیکی به کاربر",
+'emailpagetext' => "اگر این کاربر نشانی پست الکترونیکی معتبری در ترجیحات کاربریش وارد کرده
+باشد، فرم زیر یک پیغام می‌فرستد.
+نشانی پست الکترونیکی‌ای که در ترجیحات کاربریتان وارد کرده‌اید در نشانی فرستنده (From) نامه
+خواهد آمد، تا گیرنده بتواند پاسخ دهد.",
+'noemailtitle' => "نشانی پست‌الکترونیک موجود نیست",
+'noemailtext' => "این کاربر نشانی پست الکترونیکی معتبری مشخص نکرده است،
+یا تصمیم گرفته از کاربران دیگر پست الکترونیکی دریافت نکند.",
+'emailfrom' => "از",
+'emailto' => "به",
+'emailsubject' => "عنوان",
+'emailmessage' => "پیغام",
+'emailsend' => "فرستاده شود",
+'emailsent' => "پست الکترونیکی فرستاده شد",
+'emailsenttext' => "پیغام پست الکترونیکی شما فرستاده شد.",
+
+# Watchlist
+#
+'watchlist' => "فهرست تعقیبات من",
+'nowatchlist' => "در فهرست تعقیبات شما هیچ موردی نیست.",
+'watchnologin' => "به سیستم وارد نشده‌اید",
+'watchnologintext' => "برای تغییر فهرست تعقیباتتان باید [[ویژه:Userlogin|به سیستم وارد شوید]].",
+'addedwatch' => "به فهرست تعقیبات اضافه شود",
+'addedwatchtext' => "صفحه‌ی «$1» به <a href=\"" .
+ "{{localurle:ویژه:Watchlist}}\">فهرست تعقیبات</a> شما اضافه شد.
+تغییرات این صفحه و صفحه‌ی بحث متناظرش در آینده در اینجا فهرست خواهد شد. به‌علاوه، این صفحه، برای واضحتر دیده شدن در
+<a href=\"" .
+ "{{localurle:ویژه:Recentchanges}}\">فهرست تغییرات اخیر</a> to
+به شکل<b>سیاه</b> خواهد آمد.</p>
+
+<p>اگر بعداً می‌خواستید این صفحه از فهرست تعقیباتتان برداشته شود، روی «تعقیب متوقف شود» در نوار حاشیه کلیک کنید.",
+'removedwatch' => "از فهرست تعقیبات برداشته شد",
+'removedwatchtext' => "صفحه‌ی «$1» از فهرست تعقیبات شما برداشته شد",
+'watchthispage' => "تعقیب این صفحه",
+'unwatchthispage' => "توقف تعقیب",
+'notanarticle' => "مقاله نیست",
+'watchnochange' => "هیچ یک از موارد در حال تعقیب شما در دوره‌ی زمانی نمایش‌یافته ویرایش نشده است.",
+'watchdetails' => "($1 pages watched not counting talk pages;
+$2 total pages edited since cutoff;
+$3...
+[$4 نمایش و ویرایش فهرست کامل].)",
+'watchmethod-recent'=> "بررسی ویرایش‌های اخیر برای صفحات در حال تعقیب",
+'watchmethod-list' => "بررسی صفحات در حال تعقیب برای ویرایش‌های اخیر",
+'removechecked' => "برداشتن موارد تیک‌خورده از فهرست تعقیبات",
+'watchlistcontains' => "فهرست تعقیبات شما حاوی $1 صفحه است.",
+'watcheditlist' => "در اینجا فهرست الفبایی‌ای از صفحات در تعقیب شما می‌آید.
+در جعبه‌ی صفحاتی که می‌خواهید از فهرست تعقیباتتان حذف شود تیک بزنید و روی دکمه‌ی «برداشتن موارد» در پایین
+صفحه کلیک کنید.",
+'removingchecked' => "در حال برداشتن موارد درخواستی از فهرست تعقیبات...",
+'couldntremove' => "نمی‌توان مورد «$1» را حذف کرد...",
+'iteminvalidname' => "مشکل با مورد «$1»، نام نامعتبر است...",
+'wlnote' => "در زیر آخرین $1 تغییر در $2 ساعت آخر آمده است.",
+'wlshowlast' => "نمایش آخرین $1 ساعت $2 روز $3",
+'wlsaved' => "این نسخه‌ی ذخیره‌شده‌ای از فهرست تعقیبات شما است.",
+
+
+# Delete/protect/revert
+#
+'deletepage' => "حذف صفحه",
+'confirm' => "تأیید",
+'exblank' => "صفحه خالی بود",
+'confirmdelete' => "تأیید حذف",
+'deletesub' => "(در حال حذف «$1»)",
+'historywarning' => "هشدار: صفحه‌ای که دارید حذف می‌کند تاریخچه‌ای دارد:",
+'actioncomplete' => "عمل انجام شد",
+'deletedtext' => "«$1» حذف شده است.
+برای سابقه‌ی حذف‌های اخیر به $2 مراجعه کنید.",
+'deletedarticle' => "«$1» حذف شد",
+'dellogpage' => "سیاهه‌ی_حذف",
+'dellogpagetext' => "فهرست زیر فهرستی از اخیرترین حذف‌ها است.
+همه‌ی زمان‌های نشان‌داده‌شده زمان خادم (وقت گرینیچ) است.
+<ul>
+</ul>",
+'deletionlog' => "سیاهه‌ی حذف",
+'reverted' => "به نسخه‌ی قدیمی‌تر برگردانده شد",
+'deletecomment' => "دلیل حذف",
+'imagereverted' => "برگرداندن به نسخه‌ی قدیمی‌تر با موفقیت انجام شد.",
+'cantrollback' => "نمی‌توان ویرایش را برگرداند؛ آخرین مشارکت‌کننده تنها مؤلف این مقاله است.",
+'alreadyrolled' => "Cannot rollback last edit of [[:$1]]
+by [[User:$2|$2]] ([[User talk:$2|Talk]]); someone else has edited or rolled back the article already.
+
+آخرین ویرایش توسط [[کاربر:$3|$3]] ([[بحث کاربر:$3|بحث]]).",
+# only shown if there is an edit comment
+'editcomment' => "توضیح ویرایش این بود: \"<i>$1</i>\".",
+'revertpage' => "ویرایش $2 برگردانده شد، به آخرین تغییری که $1 انجام داده است",
+'protectlogpage' => "سیاهه‌ی_محافظت",
+'protectlogtext' => "در زیر فهرست قفل کردن‌ها/ازقفل‌درآوردن‌های صفحات آمده است.
+برای اطلاعات بیشتر به [[{{ns:project}}:صفحه‌ی محافظت‌شده]] مراجعه کنید.",
+'protectedarticle' => "[[$1]] محافظت شد",
+'unprotectedarticle' => "[[$1]] از محافظت در آمد",
+
+# Undelete
+'undelete' => "احیای صفحه‌ی حذف شده",
+'undeletepage' => "نمایش و احیای صفحات حذف شده",
+'undeletepagetext' => "صفحات زیر حذف شده‌اند ولی هنوز در بایگانی هستند و می‌توانند احیا شوند.
+این آرشیو ممکن است هر چند وقت تمیز شود.",
+'undeletearticle' => "احیای مقاله‌ی حذف‌شده",
+'undeleterevisions' => "$1 نسخه بایگانی شده است",
+'undeletehistory' => "اگر این صفحه را احیا کنید، همه‌ی نسخه‌های آن در تاریخچه احیا خواهند شد.
+اگر صفحه‌ی جدیدی با نام یکسان از زمان حذف ایجاد شده باشد، نسخه‌های احیاشده در تاریخچه‌ی قبلی خواهند آمد،
+و نسخه‌ی فعلی صفحه‌ی زنده به طور خودکار جایگزین نخواهد شد.",
+'undeleterevision' => "حذف نسخه‌ی به تاریخ $1",
+'undeletebtn' => "احیا شود!",
+'undeletedarticle' => "«$1» احیا شد",
+
+# Contributions
+#
+'contributions' => "مشارکت‌های کاربر",
+'mycontris' => "مشارکت‌های من",
+'contribsub' => "برای $1",
+'nocontribs' => "هیچ تغییری نظیر این مشخصات یافت نشد.",
+'ucnote' => "در زیر آخرین <b>$1</b> تغییر این کاربر در <b>$2</b> روز اخیر می‌آید.",
+'uclinks' => "نمایش آخرین $1 تغییر؛ نمایش $2 روز اخیر.",
+'uctop' => " (بالا)" ,
+
+# What links here
+#
+'whatlinkshere' => "آنچه به اینجا پیوند دارد",
+'notargettitle' => "مقصدی نیست",
+'notargettext' => "شما صفحه‌ی یا کاربر مقصدی برای انجام این عمل روی آن مشخص نکرده‌اید.",
+'linklistsub' => "(فهرست پیوندها)",
+'linkshere' => "صفحات زیر به اینجا پیوند دارند:",
+'nolinkshere' => "هیچ صفحه‌ای به اینجا پیوند ندارد.",
+'isredirect' => "صفحه‌ی تغییر مسیر",
+
+# Block/unblock IP
+#
+'blockip' => "بستن کاربر",
+'blockiptext' => "از فرم زیر برای بستن دسترسی نوشتن از یک نشانی IP یا
+نام کاربری مشخص استفاده کنید.
+این کار فقط فقط باید برای جلوگیری از خرابکاری انجام شود، و بر اساس
+[[{{ns:project}}:خط مشی|خط مشی].
+دلیل مشخص این کار را در زیر ذکر کنید (مثلاً با ذکر صفحات به‌خصوصی که تخریب شده‌اند).",
+'ipaddress' => "نشانی IP/نام کاربر",
+'ipbreason' => "دلیل",
+'ipbsubmit' => "این کاربر بسته شود",
+'badipaddress' => "کاربری با این نام وجود ندارد.",
+'blockipsuccesssub' => "بستن با موفقیت انجام شد",
+'blockipsuccesstext' => "«$1» بسته شده است.
+<br />برای بررسی بسته‌شدن‌ها، به [[ویژه:فهرستIPهای‌بسته|فهرست IPهای بسته]] مراجعه کنید.",
+'unblockip' => "باز کردن کاربر",
+'unblockiptext' => "برای باز گرداندن دسترسی نوشتن به یک نشانی IP یا نام کاربری بسته‌شده
+از فرم زیر استفاده کنید.",
+'ipusubmit' => "باز کردن این نشانی",
+'ipblocklist' => "فهرست نشانی‌های IP و نام‌های کاربری بسته‌شده",
+'blocklistline' => "$1، $2 بست $3 را ($4)",
+'blocklink' => "بسته شود",
+'unblocklink' => "باز شود",
+'contribslink' => "مشارکت‌ها",
+'autoblocker' => "به طور خودکار بسته شد چون IP شما و «$1» یکی است. دلیل «$2».",
+'blocklogpage' => "سیاهه‌ی_بسته‌شدن‌ها",
+'blocklogentry' => '«$1» بسته شد',
+'blocklogtext' => "این سیاهه‌ای از اعمال بستن و باز کردن کاربرها است. نشانی‌های IPی که به طور
+خودکار بسته شده‌اند فهرست نشده‌اند. برای فهرست محرومیت‌ها و بسته‌شدن‌های عملیاتی در لحظه‌ی حاضر،
+به [[Special:Ipblocklist|فهرست IPهای بسته]] مراجعه کنید.",
+'unblocklogentry' => '«$1» باز شد',
+
+# Developer tools
+#
+'lockdb' => "قفل کردن پایگاه داده",
+'unlockdb' => "از قفل در آوردن پایگاه داده",
+'lockconfirm' => "بله، من جداً می‌خواهم پایگاه داده را قفل کنم.",
+'unlockconfirm' => "بله، من جداً می‌خواهم پایگاه داده را از قفل در آورم.",
+'lockbtn' => "قفل کردن پایگاه داده",
+'unlockbtn' => "از قفل درآوردن پایگاه داده",
+'locknoconfirm' => "شما در جعبه‌ی تأیید تیک نزدید",
+'lockdbsuccesssub' => "قفل کردن پایگاه داده با موفقیت انجام شد",
+'unlockdbsuccesssub' => "قفل پایگاه داده برداشته شد",
+'lockdbsuccesstext' => "پایگاه داده قفل شد.
+<br />فراموش نکنید که پس از اتمام نگهداری قفل را بردارید.",
+'unlockdbsuccesstext' => "پایگاه داده از قفل در آمد.",
+
+# Move page
+#
+'movepage' => "انتقال صفحه",
+'movepagetext' => "با استفاده از فرم زیر نام صفحه تغییر خواهد کرد، و تمام تاریخچه‌اش به
+نام جدید منتقل خواهد شد.
+عنوان قدیمی تبدیل به یک صفحه‌ی تغییر مسیر به عنوان جدید خواهد شد.
+پیوندهای به عنوان صفحه‌ی قدیمی تغییر نخواهند کرد؛ حتماً تغییرمسیرهای دوتایی یا خراب را
+[[ویژه:نگهداری|بررسی کنید]].
+شما مسئول اطمینان از این هستید که پیوندها هنوز به همان‌جایی که قرار است بروند.
+
+توجه کنید که اگر از قبل صفحه‌ای در عنوان جدید وجود داشته باشد صفحه منتقل '''نخواهد شد'''، مگر
+این که صفحه خالی یا تغییر مسیر باشد و تاریخچه‌ی ویرایشی نداشته باشد.
+این یعنی اگر اشتباه کردید صفحه را به همان جایی که از آن منتقل شده بود برگردانید،
+و این که نمی‌توانید روی صفحات موجود بنویسید.
+
+<b>هشدار!</b>
+این کار ممکن است تغییر اساسی و غیرمنتظره‌ای برای صفحات محبوب باشد؛
+لطفاً مطمئن شوید که قبل از ادامه دادن عواقب این کار را درک می‌کنید.",
+'movearticle' => "انتقال صفحه",
+'movenologin' => "به سیستم وارد نشده‌اید",
+'movenologintext' => "برای انتقال صفحات باید کاربر ثبت‌شده بوده و
+[[ویژه:Userlogin|به سیستم وارد شوید]].",
+'newtitle' => "به عنوان جدید",
+'movepagebtn' => "صفحه منتقل شود",
+'pagemovedsub' => "انتقال با موفقیت انجام شد",
+'pagemovedtext' => "صفحه‌ی «[[$1]]» به «[[$2]]» منتقل شد.",
+'articleexists' => "صفحه‌ای با این نام از قبل وجود دارد، یا نامی که انتخاب کرده‌اید معتبر نیست.
+لطفاً نام دیگری انتخاب کنید.",
+'talkexists' => "صفحه با موفقیت منتقل شد، ولی صفحه‌ی بحث را، به این دلیل که صفحه‌ی بحثی در عنوان جدید
+وجود دارد، نمی‌توان منتقل کرد. لطفاً آنها را دستی ترکیب کنید.",
+'movedto' => "منتقل شد به",
+'movetalk' => "صفحه‌ی «بحث» هم، در صورت لزوم، منتقل شود.",
+'talkpagemoved' => "صفحه‌ی بحث متناظر نیز منتقل شد.",
+'talkpagenotmoved' => "صفحه‌ی بحث متناظر منتقل <strong>نشد</strong>.",
+"1movedto2" => "$1 به $2 منتقل شد",
+
+# Export
+
+'export' => "صدور صفحات",
+'exporttext' => "شما می‌توانید متن و تاریخچه‌ی ویرایش یک صفحه‌ی مشخص یا مجموعه‌ای از صفحات را به شکل پوشیده در XML صادر کنید؛
+این اطلاعات را می‌توان وارد ویکی دیگری که نرم‌افزار مدیاویکی اجرا می‌کند کرد، تبدیل کرد، یا برای سرگرمی شخصی نگه داشت.",
+'exportcuronly' => "فقط نسخه‌ی فعلی بیاید، نه کل تاریخچه",
+
+# Namespace 8 related
+
+'allmessages' => "همه‌ی پیغام‌ها",
+'allmessagestext' => "این فهرستی از همه‌ی پیغام‌های موجود در فضای نام مدیاویکی: است",
+
+# Thumbnails
+
+'thumbnail-more' => "بزرگ شود",
+
+# Math
+
+'mw_math_png' => "همیشه PNG کشیده شود",
+'mw_math_simple' => "اگر خیلی ساده بودHTML وگرنه PNG",
+'mw_math_html' => "اگر ممکن بود HTML وگرنه PNG",
+'mw_math_source' => "در قالب TeX باقی بماند (برای مرورگرهای متنی)",
+'mw_math_modern' => "توصیه برای مرورگرهای امروزی",
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesFi.php b/languages/messages/MessagesFi.php
new file mode 100644
index 000000000000..f1e787ed11d8
--- /dev/null
+++ b/languages/messages/MessagesFi.php
@@ -0,0 +1,2063 @@
+<?php
+/** Finnish (Suomi)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$skinNames = array(
+ 'standard' => 'Perus',
+ 'cologneblue' => 'Kölnin sininen',
+ 'myskin' => 'Oma tyylisivu'
+);
+
+$quickbarSettings = array(
+ 'Ei mitään', 'Tekstin mukana, vasen', 'Tekstin mukana, oikea', 'Pysyen vasemmalla', 'Pysyen oikealla'
+);
+
+$datePreferences = array(
+ 'default',
+ 'fi normal',
+ 'fi seconds',
+ 'fi numeric',
+ 'ISO 8601',
+);
+
+$defaultDateFormat = 'fi normal';
+
+$dateFormats = array(
+ 'fi normal time' => 'H.i',
+ 'fi normal date' => 'j. F"ta" Y',
+ 'fi normal both' => 'j. F"ta" Y "kello" H.i',
+
+ 'fi seconds time' => 'H:i:s',
+ 'fi seconds date' => 'j. F"ta" Y',
+ 'fi seconds both' => 'j. F"ta" Y "kello" H:i:s',
+
+ 'fi numeric time' => 'H.i',
+ 'fi numeric date' => 'j.n.Y',
+ 'fi numeric both' => 'j.n.Y "kello" H.i',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'fi normal',
+ 'fi seconds',
+ 'fi numeric',
+);
+
+$bookstoreList = array(
+ 'Bookplus' => 'http://www.bookplus.fi/product.php?isbn=$1',
+ 'Helsingin yliopiston kirjasto' => 'http://pandora.lib.hel.fi/cgi-bin/mhask/monihask.py?volname=&author=&keyword=&ident=$1&submit=Hae&engine_helka=ON',
+ 'Pääkaupunkiseudun kirjastot' => 'http://www.helmet.fi/search*fin/i?SEARCH=$1',
+ 'Tampereen seudun kirjastot' => 'http://kirjasto.tampere.fi/Piki?formid=fullt&typ0=6&dat0=$1'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Toiminnot',
+ NS_MAIN => '',
+ NS_TALK => 'Keskustelu',
+ NS_USER => 'Käyttäjä',
+ NS_USER_TALK => 'Keskustelu_käyttäjästä',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Keskustelu_{{grammar:elative|$1}}',
+ NS_IMAGE => 'Kuva',
+ NS_IMAGE_TALK => 'Keskustelu_kuvasta',
+ NS_MEDIAWIKI => 'Järjestelmäviesti',
+ NS_MEDIAWIKI_TALK => 'Keskustelu_järjestelmäviestistä',
+ NS_TEMPLATE => 'Malline',
+ NS_TEMPLATE_TALK => 'Keskustelu_mallineesta',
+ NS_HELP => 'Ohje',
+ NS_HELP_TALK => 'Keskustelu_ohjeesta',
+ NS_CATEGORY => 'Luokka',
+ NS_CATEGORY_TALK => 'Keskustelu_luokasta'
+);
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+$linkTrail = '/^([a-zäö]+)(.*)$/sDu';
+
+$specialPageAliases = array(
+ 'DoubleRedirects' => array( 'Kaksinkertaiset_uudelleenohjaukset' ),
+ 'BrokenRedirects' => array( 'Virheelliset_uudelleenohjaukset' ),
+ 'Disambiguations' => array( 'Täsmennyssivut' ),
+ 'Userlogin' => array( 'Kirjaudu_sisään' ),
+ 'Userlogout' => array( 'Kirjaudu_ulos' ),
+ 'Preferences' => array( 'Asetukset' ),
+ 'Watchlist' => array( 'Tarkkailulista' ),
+ 'Recentchanges' => array( 'Tuoreet_muutokset' ),
+ 'Upload' => array( 'Lisää_tiedosto' ),
+ 'Imagelist' => array( 'Tiedostoluettelo' ),
+ 'Newimages' => array( 'Uudet_kuvat' ),
+ 'Listusers' => array( 'Käyttäjät' ),
+ 'Statistics' => array( 'Tilastot' ),
+ 'Randompage' => array( 'Satunnainen_sivu' ),
+ 'Lonelypages' => array( 'Yksinäiset_sivut' ),
+ 'Uncategorizedpages' => array( 'Luokittelemattomat_sivut' ),
+ 'Uncategorizedcategories' => array( 'Luokittelemattomat_luokat' ),
+ 'Uncategorizedimages' => array( 'Luokittelemattomat_tiedostot' ),
+ 'Unusedcategories' => array( 'Käyttämättömät_luokat' ),
+ 'Unusedimages' => array( 'Käyttämättömät_tiedostot' ),
+ 'Wantedpages' => array( 'Halutuimmat_sivut' ),
+ 'Wantedcategories' => array( 'Halutuimmat_luokat' ),
+ 'Mostlinked' => array( 'Viitatuimmat_sivut' ),
+ 'Mostlinkedcategories' => array( 'Viitatuimmat_luokat' ),
+ 'Mostcategories' => array( 'Luokitelluimmat_sivut' ),
+ 'Mostimages' => array( 'Viitatuimmat_kuvat' ),
+ 'Mostrevisions' => array( 'Muokatuimmat_sivut' ),
+ 'Shortpages' => array( 'Lyhyet_sivut' ),
+ 'Longpages' => array( 'Pitkät_sivut' ),
+ 'Newpages' => array( 'Uudet_sivut' ),
+ 'Ancientpages' => array( 'Kuolleet_sivut' ),
+ 'Deadendpages' => array( 'Linkittömät_sivut' ),
+ 'Allpages' => array( 'Kaikki_sivut' ),
+ 'Prefixindex' => array( 'Etuliiteluettelo' ) ,
+ 'Ipblocklist' => array( 'Muokkausestot' ),
+ 'Specialpages' => array( 'Toimintosivut' ),
+ 'Contributions' => array( 'Muokkaukset' ),
+ 'Emailuser' => array( 'Lähetä_sähköpostia' ),
+ 'Whatlinkshere' => array( 'Tänne_viittaavat_sivut' ),
+ 'Recentchangeslinked' => array( 'Linkitetyt_muutokset' ),
+ 'Movepage' => array( 'Siirrä_sivu' ),
+ 'Blockme' => array( 'Estä_minut' ),
+ 'Booksources' => array( 'Kirjalähteet' ),
+ 'Categories' => array( 'Luokat' ),
+ 'Export' => array( 'Vie_sivuja' ),
+ 'Version' => array( 'Versio' ),
+ 'Allmessages' => array( 'Järjestelmäviestit' ),
+ 'Log' => array( 'Loki', 'Lokit' ),
+ 'Blockip' => array( 'Estä' ),
+ 'Undelete' => array( 'Palauta' ),
+ 'Import' => array( 'Tuo_sivuja' ),
+ 'Lockdb' => array( 'Lukitse_tietokanta' ),
+ 'Unlockdb' => array( 'Avaa_tietokanta' ),
+ 'Userrights' => array( 'Käyttöoikeudet' ),
+ 'MIMEsearch' => array( 'MIME-haku' ),
+ 'Unwatchedpages' => array( 'Tarkkailemattomat_sivut' ),
+ 'Listredirects' => array( 'Uudelleenohjaukset' ),
+ 'Listinterwikis' => array( 'Ulkowikilinkit' ),
+ 'Revisiondelete' => array( 'Poista_muokkaus' ),
+ 'Unusedtemplates' => array( 'Käyttämättömät_mallineet' ),
+ 'Randomredirect' => array( 'Satunnainen_uudelleenohjaus' ),
+ 'Mypage' => array( 'Oma_sivu' ),
+ 'Mytalk' => array( 'Oma_keskustelu' ),
+ 'Mycontributions' => array( 'Omat_muokkaukset' ),
+ 'Listadmins' => array( 'Ylläpitäjät' ),
+ 'Popularpages' => array( 'Suositut_sivut' ),
+ 'Search' => array( 'Haku' ),
+ 'Resetpass' => array( 'Alusta_salasana' ),
+);
+
+
+$messages = array(
+
+# User preference toggles
+'tog-underline' => 'Alleviivaa linkit:',
+'tog-highlightbroken' => 'Näytä linkit puuttuville sivuille <a href="#" class="new">näin</a> (vaihtoehtoisesti näin: <a href="#" class="internal">?</a>).',
+'tog-justify' => 'Tasaa kappaleet',
+'tog-hideminor' => 'Piilota pienet muutokset tuoreet muutokset -listasta',
+'tog-extendwatchlist' => 'Laajenna tarkkailulista näyttämään kaikki tehdyt muutokset',
+'tog-usenewrc' => 'Kehittynyt tuoreet muutokset -listaus (JavaScript)',
+'tog-numberheadings' => 'Numeroi otsikot',
+'tog-showtoolbar' => 'Näytä työkalupalkki',
+'tog-editondblclick' => 'Muokkaa sivuja kaksoisnapsautuksella (JavaScript)',
+'tog-editsection' => 'Näytä muokkauslinkit jokaisen osion yläpuolella',
+'tog-editsectiononrightclick' => 'Muokkaa osioita napsauttamalla otsikkoa hiiren oikealla painikkeella (JavaScript)',
+'tog-showtoc' =>'Näytä sisällysluettelo sivuille, joilla yli 3 otsikkoa',
+'tog-rememberpassword'=> 'Älä kysy salasanaa saman yhteyden eri istuntojen välillä',
+'tog-editwidth' => 'Muokkauskenttä on sivun levyinen',
+'tog-watchcreations' => 'Lisää luomani sivut tarkkailulistalle',
+'tog-watchdefault' => 'Lisää oletuksena uudet ja muokatut sivut tarkkailulistalle',
+'tog-watchmoves' => 'Lisää siirtämäni sivut tarkkailulistalle',
+'tog-watchdeletion' => 'Lisää poistamani sivut tarkkailulistalle',
+'tog-minordefault' => 'Muutokset ovat oletuksena pieniä',
+'tog-previewontop' => 'Näytä esikatselu muokkauskentän yläpuolella',
+'tog-previewonfirst' => 'Näytä esikatselu heti, kun muokkaus aloitetaan',
+'tog-nocache' => 'Älä tallenna sivuja välimuistiin',
+'tog-enotifwatchlistpages' => 'Lähetä sähköpostiviesti tarkkailtujen sivujen muutoksista',
+'tog-enotifusertalkpages' => 'Lähetä sähköpostiviesti, kun käyttäjäsivun keskustelusivu muuttuu',
+'tog-enotifminoredits' => 'Lähetä sähköpostiviesti myös pienistä muokkauksista',
+'tog-enotifrevealaddr' => 'Näytä sähköpostiosoitteeni muille lähetetyissä ilmoituksissa',
+'tog-shownumberswatching' => 'Näytä sivua tarkkailevien käyttäjien määrä',
+'tog-fancysig' => 'Muotoilematon allekirjoitus ilman automaattista linkkiä',
+'tog-externaleditor' => 'Käytä ulkoista tekstieditoria oletuksena',
+'tog-externaldiff' => 'Käytä ulkoista diff-ohjelmaa oletuksena',
+'tog-showjumplinks' => 'Lisää loikkaa-käytettävyyslinkit sivun alkuun',
+'tog-uselivepreview' => 'Käytä pikaesikatselua (JavaScript) (kokeellinen)',
+'tog-forceeditsummary'=> 'Huomauta, jos yhteenvetoa ei ole annettu',
+'tog-watchlisthideown' => 'Piilota omat muokkaukset',
+'tog-watchlisthidebots' => 'Piilota bottien muokkaukset',
+'tog-watchlisthideminor'=> 'Piilota pienet muokkaukset',
+'tog-nolangconversion' => 'Disable variants conversion',
+'tog-ccmeonemails' => 'Lähetä minulle kopio MediaWikin kautta lähetetyistä sähköposteista',
+
+'underline-always' => 'Aina',
+'underline-never' => 'Ei koskaan',
+'underline-default' => 'Selaimen oletustapa',
+
+'skinpreview' => '(Esikatsele...)',
+
+# dates
+'sunday' => 'sunnuntai',
+'monday' => 'maanantai',
+'tuesday' => 'tiistai',
+'wednesday' => 'keskiviikko',
+'thursday' => 'torstai',
+'friday' => 'perjantai',
+'saturday' => 'lauantai',
+'sun' => 'su',
+'mon' => 'ma',
+'tue' => 'ti',
+'wed' => 'ke',
+'thu' => 'to',
+'fri' => 'pe',
+'sat' => 'la',
+'january' => 'tammikuu',
+'february' => 'helmikuu',
+'march' => 'maaliskuu',
+'april' => 'huhtikuu',
+'may_long' => 'toukokuu',
+'june' => 'kesäkuu',
+'july' => 'heinäkuu',
+'august' => 'elokuu',
+'september' => 'syyskuu',
+'october' => 'lokakuu',
+'november' => 'marraskuu',
+'december' => 'joulukuu',
+'january-gen' => 'tammikuun',
+'february-gen'=> 'helmikuun',
+'march-gen' => 'maaliskuun',
+'april-gen' => 'huhtikuun',
+'may-gen' => 'toukokuun',
+'june-gen' => 'kesäkuun',
+'july-gen' => 'heinäkuun',
+'august-gen' => 'elokuun',
+'september-gen' => 'syyskuun',
+'october-gen' => 'lokakuun',
+'november-gen'=> 'marraskuun',
+'december-gen'=> 'joulukuun',
+'jan' => 'tammikuu',
+'feb' => 'helmikuu',
+'mar' => 'maaliskuu',
+'apr' => 'huhtikuu',
+'may' => 'toukokuu',
+'jun' => 'kesäkuu',
+'jul' => 'heinäkuu',
+'aug' => 'elokuu',
+'sep' => 'syyskuu',
+'oct' => 'lokakuu',
+'nov' => 'marraskuu',
+'dec' => 'joulukuu',
+
+# Bits of text used by many pages:
+#
+'categories' => 'Luokat',
+'pagecategories' => '{{PLURAL:$1|Luokka|Luokat}}',
+'category_header' => 'Sivut, jotka ovat luokassa $1',
+'subcategories' => 'Alaluokat',
+'category-media-header' => 'Luokan ”$1” sisältämät mediatiedostot',
+'mainpage' => 'Etusivu',
+'mainpagetext' => '\'\'\'Mediawiki on onnistuneesti asennettu.\'\'\'',
+'mainpagedocfooter' => 'Lisätietoja käytöstä on sivulla [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide User\'s Guide].
+=== Lisäohjeita===
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Asetusten teko-ohjeita]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWikin FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Sähköpostilista, jolla tiedotetaan MediaWikin uusista versioista]",
+=== Asetukset ===
+Tarkista, että alla olevat taivutusmuodot ovat oikein. Jos eivät, tee tarvittavat muutokset LocalSettings.php:hen seuraavasti:
+ $wgGrammarForms[\'fi\'][\'genitive\'][\'{{SITENAME}}\'] = \'...\';
+ $wgGrammarForms[\'fi\'][\'partitive\'][\'{{SITENAME}}\'] = \'...\';
+ $wgGrammarForms[\'fi\'][\'elative\'][\'{{SITENAME}}\'] = \'...\';
+ $wgGrammarForms[\'fi\'][\'inessive\'][\'{{SITENAME}}\'] = \'...\';
+ $wgGrammarForms[\'fi\'][\'illative\'][\'{{SITENAME}}\'] = \'...\';
+Taivutusmuodot: {{GRAMMAR:genitive|{{SITENAME}}}} (yön) — {{GRAMMAR:partitive|{{SITENAME}}}} (yötä) — {{GRAMMAR:elative|{{SITENAME}}}} (yöstä) — {{GRAMMAR:inessive|{{SITENAME}}}} (yössä) — {{GRAMMAR:illative|{{SITENAME}}}} (yöhön).',
+'portal' => 'Kahvihuone',
+'portal-url' => '{{ns:project}}:Kahvihuone',
+'about' => 'Tietoja',
+'aboutsite' => 'Tietoja {{GRAMMAR:elative|{{SITENAME}}}}',
+'aboutpage' => '{{ns:project}}:Tietoja',
+'article' => 'Sivu',
+'help' => 'Ohje',
+'helppage' => '{{ns:help}}:Ohje',
+'bugreports' => 'Ongelmat ja parannusehdotukset',
+'bugreportspage' => '{{ns:project}}:Ongelmat ja parannusehdotukset',
+'sitesupport' => 'Lahjoitukset',
+'sitesupport-url' => '{{ns:project}}:Lahjoitukset',
+
+'faq' => 'FAQ',
+'faqpage' => '{{ns:project}}:FAQ',
+'edithelp' => 'Muokkausohjeet',
+'newwindow' => '(avautuu uuteen ikkunaan)',
+'edithelppage' => '{{ns:help}}:Kuinka_sivuja_muokataan',
+'cancel' => 'Keskeytä',
+'qbfind' => 'Etsi',
+'qbbrowse' => 'Selaa',
+'qbedit' => 'Muokkaa',
+'qbpageoptions' => 'Sivuasetukset',
+'qbpageinfo' => 'Sivun tiedot',
+'qbmyoptions' => 'Asetukset',
+'qbspecialpages' => 'Toimintosivut',
+'moredotdotdot' => 'Lisää...',
+'mypage' => 'Käyttäjäsivu',
+'mytalk' => 'Keskustelusivu',
+'anontalk' => 'Keskustele tämän IP:n kanssa',
+'navigation' => 'Valikko',
+
+# Metadata in edit box
+'metadata_help' => 'Sisältökuvaukset (lisätietoja sivulla [[Project:Sisältökuvaukset]]):',
+
+'currentevents' => 'Ajankohtaista',
+'currentevents-url' => '{{ns:project}}:Ajankohtaista',
+
+'disclaimers' => 'Vastuuvapaus',
+'disclaimerpage' => '{{ns:project}}:Vastuuvapaus',
+'privacy' => 'Tietosuojakäytäntö',
+'privacypage' => '{{ns:project}}:Tietosuojakäytäntö',
+'errorpagetitle' => 'Virhe',
+'returnto' => 'Palaa sivulle $1.',
+'tagline' => '{{SITENAME}}',
+'whatlinkshere' => 'Tänne viittaavat sivut',
+'help' => 'Ohje',
+'search' => 'Haku',
+'searchbutton' => 'Etsi',
+'go' => 'Siirry',
+'searcharticle' => 'Siirry',
+'history' => 'Historia',
+'history_short' => 'Historia',
+'updatedmarker' => 'päivitetty viimeisimmän käyntisi jälkeen',
+'info_short' => 'Tiedostus',
+'printableversion' => 'Tulostettava versio',
+'permalink' => 'Ikilinkki',
+'print' => 'Tulosta',
+'edit' => 'Muokkaa',
+'editthispage' => 'Muokkaa tätä sivua',
+'delete' => 'Poista',
+'deletethispage' => 'Poista tämä sivu',
+'undelete_short' => 'Palauta $1 muokkausta',
+'protect' => 'Suojaa',
+'protectthispage' => 'Suojaa tämä sivu',
+'unprotect' => 'Poista suojaus',
+'unprotectthispage' => 'Poista tämän sivun suojaus',
+'newpage' => 'Uusi sivu',
+'talkpage' => 'Keskustele tästä sivusta',
+'specialpage' => 'Toimintosivu',
+'personaltools' => 'Henkilökohtaiset työkalut',
+'postcomment' => 'Kommentti sivun loppuun',
+'articlepage' => 'Näytä varsinainen sivu',
+'talk' => 'Keskustelu',
+'views' => 'Näkymät',
+'toolbox' => 'Työkalut',
+'userpage' => 'Näytä käyttäjäsivu',
+'projectpage' => 'Näytä projektisivu',
+'imagepage' => 'Näytä kuvasivu',
+'mediawikipage' => 'Näytä viestisivu',
+'templatepage' => 'Näytä mallinesivu',
+'viewhelppage' => 'Näytä ohjesivu',
+'categorypage' => 'Näytä luokkasivu',
+'viewtalkpage' => 'Näytä keskustelusivu',
+'otherlanguages' => 'Muut kielet',
+'redirectedfrom' => 'Uudelleenohjattu sivulta $1',
+'redirectpagesub' => 'Uudelleenohjaussivu',
+'lastmodifiedat' => 'Sivua on viimeksi muutettu $2 kello $1.',
+'viewcount' => 'Tämä sivu on näytetty {{PLURAL:$1|yhden kerran|$1 kertaa}}.',
+'copyright' => 'Sisältö on käytettävissä lisenssillä $1.',
+'protectedpage' => 'Suojattu sivu',
+'jumpto' => 'Loikkaa:',
+'jumptonavigation' => 'valikkoon',
+'jumptosearch' => 'hakuun',
+
+'badaccess' => 'Lupa evätty',
+'badaccess-group0' => 'Sinulla ei ole lupaa suorittaa pyydettyä toimintoa.',
+'badaccess-group1' => 'Pyytämäsi toiminto on rajoitettu henkilöille ryhmässä $1.',
+'badaccess-group2' => 'Pyytämäsi toiminto on rajoitettu henkilöille ryhmissä $1.',
+'badaccess-groups' => 'Pyytämäsi toiminto on rajoitettu ryhmien $1 henkilöille.',
+
+'versionrequired' => 'Mediawikistä tarvitaan vähintään versio $1',
+'versionrequiredtext' => 'Mediawikistä tarvitaan vähintään versio $1 tämän sivun käyttämiseen. Katso [[Special:Version|versio]]',
+
+'ok' => 'OK',
+'pagetitle' => '$1 — {{SITENAME}}',
+'retrievedfrom' => 'Haettu osoitteesta $1',
+'youhavenewmessages' => 'Sinulle on $1 ($2).',
+'newmessageslink' => 'uusia viestejä',
+'newmessagesdifflink' => 'viimeisin muutos',
+'editsection' => 'muokkaa',
+'editold' => 'muokkaa',
+'editsectionhint' => 'Muokkaa osiota $1',
+'toc' => 'Sisällysluettelo',
+'showtoc' => 'näytä',
+'hidetoc' => 'piilota',
+'thisisdeleted' => 'Näytä tai palauta $1.',
+'viewdeleted' => 'Näytä $1?',
+'restorelink' => '{{PLURAL:$1|yksi poistettu muokkaus|$1 poistettua muokkausta}}',
+'feedlinks' => 'Uutissyötteet:',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Sivu',
+'nstab-user' => 'Käyttäjäsivu',
+'nstab-media' => 'Media',
+'nstab-special' => 'Toiminto',
+'nstab-project' => 'Projektisivu',
+'nstab-image' => 'Tiedosto',
+'nstab-mediawiki' => 'Järjestelmäviesti',
+'nstab-template' => 'Malline',
+'nstab-help' => 'Ohje',
+'nstab-category' => 'Luokka',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Määrittelemätön pyyntö',
+'nosuchactiontext' => 'Wikiohjelmisto ei tunnista URL:ssä määriteltyä pyyntöä',
+'nosuchspecialpage' => 'Kyseistä toimintosivua ei ole',
+'nospecialpagetext' => 'Wikiohjelmisto ei tunnista pyytämääsi toimintosivua.',
+
+# General errors
+#
+'error' => 'Virhe',
+'databaseerror' => 'Tietokantavirhe',
+'dberrortext' => 'Tietokantakyselyssä oli syntaksivirhe. Syynä saattaa olla virheellinen kysely, tai se saattaa johtua ohjelmointivirheestä. Viimeinen tietokantakysely, jota yritettiin, oli: <blockquote><tt>$1</tt></blockquote>. Se tehtiin funktiosta ”<tt>$2</tt>”. MySQL palautti virheen ”<tt>$3: $4</tt>”.',
+'dberrortextcl' => 'Tietokantakyselyssä oli syntaksivirhe. Viimeinen tietokantakysely, jota yritettiin, oli: ”$1”. Se tehtiin funktiosta ”$2”. MySQL palautti virheen ”$3: $4”.',
+'noconnect' => 'Tietokantaongelma.<br />$1',
+'nodb' => 'Tietokantaa $1 ei voitu valita',
+'cachederror' => 'Pyydetystä sivusta näytettiin välimuistissa oleva kopio, ja se saattaa olla vanhentunut.',
+'laggedslavemode' => 'Varoitus: Sivu ei välttämättä sisällä viimeisimpiä muutoksia.',
+'readonly' => 'Tietokanta on lukittu',
+'enterlockreason' => 'Anna lukituksen syy sekä sen arvioitu poistamisaika',
+'readonlytext' => '{{GRAMMAR:genitive|{{SITENAME}}}} tietokanta on tällä hetkellä lukittu. Uusia sivuja ei voi luoda eikä muitakaan muutoksia tehdä. Syynä ovat todennäköisimmin rutiininomaiset tietokannan ylläpitotoimet. Tietokannan lukinneen ylläpitäjän selitys: $1',
+'missingarticle' => 'Tietokannasta ei löytynyt sivua \'\'\'$1\'\'\'. Sivu on saatettu poistaa, tai palvelin ei ole ehtinyt vielä käsitellä sitä. Jälkimmäisessä tapauksessa koita hetken päästä uudelleen. Jos ongelma ei katoa, ota yhteyttä ylläpitäjään ja anna mukaan tämän sivun URL-osoite.',
+'readonly_lag' => 'Tietokanta on automaattisesti lukittu, jotta kaikki tietokantapalvelimet saisivat kaikki tuoreet muutokset',
+'internalerror' => 'Sisäinen virhe',
+'filecopyerror' => 'Tiedostoa <b>$1</b> ei voitu kopioida tiedostoksi <b>$2</b>.',
+'filerenameerror' => 'Tiedostoa <b>$1</b> ei voitu nimetä uudelleen nimellä <b>$2</b>.',
+'filedeleteerror' => 'Tiedostoa <b>$1</b> ei voitu poistaa.',
+'filenotfound' => 'Tiedostoa <b>$1</b> ei löytynyt.',
+'unexpected' => 'Odottamaton arvo: ”$1” on ”$2”.',
+'formerror' => 'Lomakkeen tiedot eivät kelpaa',
+'badarticleerror' => 'Toimintoa ei voi suorittaa tälle sivulle.',
+'cannotdelete' => 'Sivun tai tiedoston poisto epäonnistui. Joku muu on saattanut poistaa sen.',
+'badtitle' => 'Virheellinen otsikko',
+'badtitletext' => 'Pyytämäsi sivuotsikko oli virheellinen, tyhjä tai väärin linkitetty kieltenvälinen tai wikienvälinen linkki.',
+'perfdisabled' => 'Pahoittelut! Tämä ominaisuus ei toistaiseksi ole käytetössä, sillä se hidastaa tietokantaa niin paljon, että kukaan ei voi käyttää wikiä. Toiminto ohjelmoidaan tehokkaammaksi lähiaikoina. (Sinäkin voit tehdä sen! Tämä on vapaa ohjelmisto.)',
+'perfdisabledsub' => 'Tässä on tallennettu kopio $1', # obsolete? ei ole
+'perfcached' => 'Seuraava data on tuotu välimuistista, eikä se ole välttämättä ajan tasalla.',
+'perfcachedts' => 'Seuraava data on tuotu välimuistista ja se päivitettiin viimeksi $1.',
+'querypage-no-updates'=> 'Tämän sivun tietoja ei toistaiseksi päivitetä.',
+'wrong_wfQuery_params'=> 'Virheelliset parametrit wfQuery()<br />Funktio: $1<br />Tiedustelu: $2',
+'viewsource' => 'Lähdekoodi',
+'viewsourcefor' => 'sivulle $1',
+'protectedpagetext' => 'Tämä sivu on suojattu muutoksilta.',
+'viewsourcetext' => 'Voit tarkastella ja kopioida tämän sivun lähdekoodia:',
+'protectedinterface' => 'Tämä sivu sisältää ohjelmiston käyttöliittymätekstiä ja on suojattu häiriköinnin estämiseksi.',
+'editinginterface' => '<center>Muokkaat sivua, joka sisältää ohjelmiston käyttöliittymätekstiä.</center>',
+'sqlhidden' => '(SQL-kysely piilotettu)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Uloskirjautuminen',
+'logouttext' => 'Olet nyt kirjautunut ulos {{GRAMMAR:elative|{{SITENAME}}}}. Voit jatkaa {{GRAMMAR:genitive|{{SITENAME}}}} käyttöä nimettömänä, tai kirjautua uudelleen sisään.',
+'welcomecreation' => '== Tervetuloa, $1! == Käyttäjätunnuksesi on luotu. Älä unohda virittää [[Special:Preferences|{{GRAMMAR:genitive|{{SITENAME}}}} asetuksiasi]].',
+'loginpagetitle' => 'Sisäänkirjautuminen',
+'yourname' => 'Käyttäjätunnus',
+'yourpassword' => 'Salasana',
+'yourpasswordagain' => 'Salasana uudelleen',
+'remembermypassword' => 'Muista minut',
+'yourdomainname' => 'Verkkonimi',
+'externaldberror' => 'Tapahtui virhe ulkoisen autentikointitietokannan käytössä tai sinulla ei ole lupaa päivittää tunnustasi.',
+'loginproblem' => '<b>Sisäänkirjautuminen ei onnistunut.</b><br />Yritä uudelleen!',
+'alreadyloggedin' => '<strong>Käyttäjä $1, olet jo kirjautunut sisään!</strong><br />\n',
+'login' => 'Kirjaudu sisään',
+'loginprompt' => 'Kirjautumiseen tarvitaan evästeitä.',
+'userlogin' => 'Kirjaudu sisään tai luo tunnus',
+'logout' => 'Kirjaudu ulos',
+'userlogout' => 'Kirjaudu ulos',
+'notloggedin' => 'Et ole kirjautunut',
+'nologin' => 'Jos sinulla ei ole vielä käyttäjätunnusta, voit $1 sellaisen.',
+'nologinlink' => 'luoda',
+'createaccount' => 'Luo uusi käyttäjätunnus',
+'gotaccount' => 'Jos sinulla on jo tunnus, voit $1.',
+'gotaccountlink' => 'kirjautua sisään',
+'createaccountmail' => 'sähköpostitse',
+'badretype' => 'Syöttämäsi salasanat ovat erilaiset.',
+'userexists' => 'Pyytämäsi käyttäjänimi on jo käytössä. Ole hyvä ja valitse toinen käyttäjänimi.',
+'youremail' => 'Sähköpostiosoite:',
+'username' => 'Tunnus:',
+'uid' => 'Numero:',
+'yourrealname' => 'Nimi:',
+'yourlanguage' => 'Käyttöliittymän kieli:',
+'yourvariant' => 'Kielivariantti',
+'yournick' => 'Nimimerkki allekirjoituksia varten:',
+'badsig' => 'Allekirjoitus on epävalidi.',
+'email' => 'Sähköpostitoiminnot',
+'prefs-help-email-enotif' => 'Tätä osoitetta käytetään myös artikkelien muuttumisilmoituksiin, jos ominaisuus on käytössä.',
+'prefs-help-realname' => 'Nimi (vapaaehtoinen): Nimeäsi käytetään antaamaan kunnia työllesi.',
+'loginerror' => 'Sisäänkirjautumisvirhe',
+'prefs-help-email' => 'Sähköpostiosoite (vapaaehtoinen): Muut käyttäjät voivat ottaa sinuun yhteyttä sähköpostilla ilman, että osoitteesi paljastuu.',
+
+'nocookiesnew' => 'Käyttäjä luotiin, mutta et ole kirjautunut sisään. {{SITENAME}} käyttää evästeitä sisäänkirjautumisen yhteydessä. Selaimesi ei salli evästeistä. Kytke ne päälle, ja sitten kirjaudu sisään juuri luomallasi käyttäjänimellä ja salasanalla.',
+'nocookieslogin' => '{{SITENAME}} käyttää evästeitä sisäänkirjautumisen yhteydessä. Selaimesi ei salli evästeitä. Ota ne käyttöön, ja yritä uudelleen.',
+'noname' => 'Et ole määritellyt kelvollista käyttäjänimeä.',
+'loginsuccesstitle' => 'Sisäänkirjautuminen onnistui',
+'loginsuccess' => 'Olet kirjautunut käyttäjänä $1.',
+'nosuchuser' => 'Käyttäjää ”$1” ei ole olemassa. Tarkista kirjoititko nimen oikein, tai käytä alla olevaa lomaketta uuden käyttäjätunnuksen luomiseksi.',
+'nosuchusershort' => 'Käyttäjää nimeltä ”$1” ei ole. Kirjoititko nimen oikein?',
+'nouserspecified' => 'Käyttäjätunnusta ei ole määritelty.',
+'wrongpassword' => 'Syöttämäsi salasana ei ole oikein. Ole hyvä ja yritä uudelleen.',
+'wrongpasswordempty' => 'Et voi antaa tyhjää salasanaa.',
+'mailmypassword' => 'Lähetä uusi salasana sähköpostitse',
+'passwordremindertitle' => 'Salasanamuistutus {{GRAMMAR:elative|{{SITENAME}}}}',
+
+'passwordremindertext'=> 'Joku IP-osoitteesta $1 pyysi {{GRAMMAR:partitive|{{SITENAME}}}} ($4) lähettämään uuden salasanan. Salasana käyttäjälle $2 on nyt $3. Kirjaudu sisään ja vaihda salasana.',
+'noemail' => 'Käyttäjälle \'\'\'$1\'\'\' ei ole määritelty sähköpostiosoitetta.',
+'passwordsent' => 'Uusi salasana on lähetetty käyttäjän <b>$1</b> sähköpostiosoitteeseen.',
+'blocked-mailpassword'=> 'Osoitteellesi on asetettu muokkausesto, joka estää käyttämästä salasanamuistutustoimintoa.',
+'eauthentsent' => 'Varmennussähköposti on lähetetty annettuun sähköpostiosoitteeseen. Muita viestejä ei lähetetä, ennen kuin olet toiminut viestin ohjeiden mukaan ja varmistanut, että sähköpostiosoite kuuluu sinulle.',
+'throttled-mailpassword' => 'Salasanamuistutus on lähetetty viimeisen $1 tunnin sisällä. Salasanamuistutuksia lähetään enintään $1 tunnin välein.',
+'mailerror' => 'Virhe lähetettäessä sähköpostia: $1',
+'acct_creation_throttle_hit' => 'Olet jo luonut $1 tunnusta. Et voi luoda uutta.',
+'emailauthenticated' => 'Sähköpostiosoitteesi varmennettiin $1.',
+'emailnotauthenticated' => 'Sähköpostiosoitettasi ei ole vielä varmennettu. Sähköpostia ei lähetetä liittyen alla oleviin toimintoihin.',
+'noemailprefs' => 'Sähköpostiosoitetta ei ole määritelty.',
+'emailconfirmlink' => 'Varmenna sähköpostiosoite',
+'invalidemailaddress' => 'Sähköpostiosoitetta ei voida hyväksyä, koska se ei ole oikeassa muodossa. Ole hyvä ja anna oikea sähköpostiosoite tai jätä kenttä tyhjäksi.',
+'accountcreated' => 'Käyttäjätunnus luotiin',
+'accountcreatedtext' => 'Käyttäjän $1 käyttäjätunnus luotiin.',
+
+# Password reset dialog
+'resetpass' => 'Salasanan alustus',
+'resetpass_announce' => 'Kirjauduit sisään sähköpostitse lähetetyllä väliaikaissalasanalla. Päätä sisäänkirjautuminen asettamalla uusi salasana.',
+'resetpass_text' => "<!-- Lisää tekstiä tähän -->",
+'resetpass_header' => 'Uuden salasanan asettaminen',
+'resetpass_submit' => 'Aseta salasana ja kirjaudu sisään',
+'resetpass_success' => 'Salasanan vaihto onnistui.',
+'resetpass_bad_temporary' => 'Kelvoton väliaikaissalasana. Olet saattanut jo asettaa uuden salasanan tai pyytänyt uutta väliaikaissalasanaa.',
+'resetpass_forbidden' => 'Salasanoja ei voi vaihtaa tässä wikissä',
+'resetpass_missing' => 'Ei syötettä.',
+
+# Edit page toolbar
+'bold_sample' => 'Lihavoitu teksti',
+'bold_tip' => 'Lihavointi',
+'italic_sample' => 'Kursivoitu teksti',
+'italic_tip' => 'Kursivointi',
+'link_sample' => 'linkki',
+'link_tip' => 'Sisäinen linkki',
+'extlink_sample' => 'http://www.example.com linkin otsikko',
+'extlink_tip' => 'Ulkoinen linkki (muista http:// edessä)',
+'headline_sample' => 'Otsikkoteksti',
+'headline_tip' => 'Otsikko',
+'math_sample' => 'Lisää kaava tähän',
+'math_tip' => 'Matemaattinen kaava (LaTeX)',
+'nowiki_sample' => 'Lisää muotoilematon teksti tähän',
+'nowiki_tip' => 'Tekstiä, jota wiki ei muotoile',
+'image_sample' => 'Esimerkki.jpg',
+'image_tip' => 'Tallennettu kuva',
+'media_sample' => 'Esimerkki.ogg',
+'media_tip' => 'Mediatiedostolinkki',
+'sig_tip' => 'Allekirjoitus aikamerkinnällä',
+'hr_tip' => 'Vaakasuora viiva',
+
+# Edit pages
+#
+'summary' => 'Yhteenveto',
+'subject' => 'Aihe',
+'minoredit' => 'Tämä on pieni muutos',
+'watchthis' => 'Tarkkaile tätä sivua',
+'savearticle' => 'Tallenna sivu',
+'preview' => 'Esikatselu',
+'showpreview' => 'Esikatsele',
+'showlivepreview' => 'Pikaesikatselu',
+'showdiff' => 'Näytä muutokset',
+'anoneditwarning' => 'Et ole kirjautunut sisään. IP-osoitteesi kirjataan tämän sivun muokkaushistoriaan.',
+'missingsummary' => 'Et ole antanut yhteenvetoa. Jos valitset Tallenna uudelleen, niin muokkauksesi tallennetaan ilman yhteenvetoa.',
+'missingcommenttext' => 'Anna yhteenveto alle.',
+'missingcommentheader'=> 'Et ole antanut otsikkoa kommentillesi. Valitse <em>Tallenna</em>, jos et halua antaa otsikkoa.',
+'summary-preview' => 'Yhteenvedon esikatelu',
+'subject-preview' => 'Otsikon esikatselu',
+'blockedtitle' => 'Pääsy estetty',
+'blockedtext' => 'Yritit muokata sivua tai luoda uuden sivun. $1 on estänyt pääsysi {{GRAMMAR:illative|{{SITENAME}}}} joko käyttäjänimesi tai IP-osoitteesi perusteella. Annettu syy estolle on: <br />\'\'$2\'\'<br />Jos olet sitä mieltä, että sinut on estetty syyttä, voit keskustella asiasta [[Project:Ylläpitäjät|ylläpitäjän]] kanssa. Huomaa, ettet voi lähettää sähköpostia {{GRAMMAR:genitive|{{SITENAME}}}} kautta, ellet ole asettanut olemassaolevaa sähköpostiosoitetta [[Special:Preferences|asetuksissa]]. Jos IP-osoitteesi on dynaaminen, eli se voi toisinaan vaihtua, olet saattanut saada estetyn osoitteen käyttöösi, ja esto vaikuttaa nyt sinuun. Jos tämä ongelma toistuu jatkuvasti, ota yhteyttä Internet-palveluntarjoajaasi tai {{GRAMMAR:genitive|{{SITENAME}}}} ylläpitäjään. IP-osoitteesi on $3 ja estotunnus on #$5.',
+'blockedoriginalsource' => 'Sivun ”$1” lähdekoodi:',
+'blockededitsource' => 'Muokkauksesi sivuun ”$1”:',
+'whitelistedittitle' => 'Sisäänkirjautuminen vaaditaan muokkaamiseen',
+'whitelistedittext' => 'Sinun täytyy $1, jotta voisit muokata sivuja.',
+'whitelistreadtitle' => 'Sisäänkirjautuminen vaaditaan lukemiseen',
+'whitelistreadtext' => 'Sinun täytyy kirjautua [[Special:Userlogin|sisään]] lukeaksesi sivuja.',
+'whitelistacctitle' => 'Sinun ei ole sallittu luoda tunnusta',
+'whitelistacctext' => 'Saadaksesi oikeudet luoda tunnus sinun täytyy kirjautua [[Special:Userlogin|sisään]] ja sinulla tulee olla asiaankuuluvat oikeudet.',
+'confirmedittitle' => 'Sähköpostin varmennus',
+'confirmedittext' => 'Et voi muokata sivuja, ennen kuin olet varmentanut sähköpostiosoitteesi. Voit tehdä varmennuksen [[Special:Preferences|asetussivulla]].',
+'loginreqtitle' => 'Sisäänkirjautuminen vaaditaan',
+'loginreqlink' => 'kirjautua sisään',
+'loginreqpagetext' => 'Sinun täytyy $1, jotta voisit nähdä muut sivut.',
+
+'accmailtitle' => 'Salasana lähetetty.',
+'accmailtext' => 'käyttäjän \'\'\'$1\'\'\' salasana on lähetetty osoitteeseen \'\'\'$2\'\'\'.',
+'newarticle' => '(uusi)',
+'newarticletext' => 'Linkki toi sivulle, jota ei vielä ole. Voit luoda sivun kirjoittamalla alla olevaan tilaan. Jos et halua luoda sivua, käytä selaimen paluutoimintoa.',
+'anontalkpagetext' => '----\'\'Tämä on nimettömän käyttäjän keskustelusivu. Hän ei ole joko luonut itselleen käyttäjätunnusta tai ei käytä sitä. Siksi hänet tunnistetaan nyt numeerisella IP-osoitteella. Kyseinen IP-osoite voi olla useamman henkilön käytössä. Jos olet nimetön käyttäjä, ja sinusta tuntuu, että aiheettomia kommentteja on ohjattu sinulle, [[Special:Userlogin|luo itsellesi käyttäjätunnus tai kirjaudu sisään]] välttääksesi jatkossa sekaannukset muiden nimettömien käyttäjien kanssa.\'\'',
+'noarticletext' => '<big>\'\'\'{{GRAMMAR:inessive|{{SITENAME}}}} ei ole tämän nimistä sivua.\'\'\'</big>
+* Voit kirjoittaa uuden sivun \'\'\'<span class="plainlinks">[{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} {{PAGENAME}}]</span>.\'\'\'
+* Jos olet luonut sivun tällä nimellä, se on saatettu poistaa — katso [[Special:Log/delete|poistoloki]].',
+'clearyourcache' => '\'\'\'Huomautus:\'\'\' Selaimen välimuisti pitää tyhjentää asetusten tallentamisen jälkeen, jotta muutokset tulisivat voimaan:
+*\'\'\'Mozilla, Konqueror ja Safari:\'\'\' napsauta \'\'Shift\'\'-näppäin pohjassa päivitä tai paina \'\'Ctrl-Shift-R\'\' (\'\'Cmd-Shift-R\'\' Applella)
+*\'\'\'IE:\'\'\' napsauta \'\'Ctrl\'\'-näppäin pohjassa päivitä tai paina \'\'Ctrl-F5\'\'
+*\'\'\'Konqueror\'\'\': napsauta päivitä tai paina \'\'F5\'\'
+*\'\'\'Opera:\'\'\' saatat joutua tyhjentään välimuistin kokonaan (\'\'Tools→Preferences\'\').',
+'usercssjsyoucanpreview' => 'Voit testata uutta CSS:ää tai JavaScriptiä ennen tallennusta esikatselulla.',
+'usercsspreview' => '\'\'\'Tämä on CSS:n esikatselu.\'\'\'',
+'userjspreview' => '\'\'\'Tämä on JavaScriptin esikatselu.\'\'\'',
+'userinvalidcssjstitle' => 'Tyyliä nimeltä ”$1” ei ole olemassa. Käyttäjän määrittelemät .css- ja .js-sivut alkavat pienellä alkukirjaimella.',
+'updated' => '(Päivitetty)',
+'note' => 'Huomautus:', // TODO: NO WIKI MARKUP
+'previewnote' => '<strong>Tämä on vasta sivun esikatselu. Sivua ei ole vielä tallennettu!</strong>',
+'session_fail_preview'=> '<strong>Muokkaustasi ei voitu tallentaa, koska istuntosi tiedot ovat kadonneet.</strong> Yritä uudelleen. Jos ongelma ei katoa, yritä kirjautua ulos ja takaisin sisään.',
+'previewconflict' => 'Tämä esikatselu näyttää miltä muokkausalueella oleva teksti näyttää tallennettuna.',
+'session_fail_preview_html' => '<strong>Muokkaustasi ei voitu tallentaa, koska istuntosi tiedot ovat kadonneet.</strong>
+
+Esikatselu on piilotettu varokeinona JavaScript-hyökkäyksiä vastaan – tässä wikissä on HTML-tila päällä.
+
+Yritä uudelleen. Jos ongelma ei katoa, yritä kirjautua ulos ja takaisin sisään.',
+'importing' => 'Tuodaan sivua $1',
+'editing' => 'Muokataan sivua $1',
+'editinguser' => 'Muokataan sivua $1',
+'editingsection' => 'Muokataan osiota sivusta $1',
+'editingcomment' => 'Muokataan kommenttia sivulla $1',
+'editconflict' => 'Päällekkäinen muokkaus: $1',
+'explainconflict' => 'Joku muu on muuttanut tätä sivua sen jälkeen, kun aloit muokata sitä. Ylempi tekstialue sisältää tämänhetkisen tekstin. Tekemäsi muutokset näkyvät alemmassa ikkunassa. Sinun täytyy yhdistää muutoksesi olemassa olevaan tekstiin. \'\'\'Vain\'\'\' ylemmässä alueessa oleva teksti tallentuu, kun tallennat sivun.',
+'yourtext' => 'Oma tekstisi',
+'storedversion' => 'Tallennettu versio',
+'nonunicodebrowser' => '\'\'\'Varoitus: Selaimesi ei ole Unicode-yhteensopiva. Ole hyvä ja vaihda selainta, ennen kuin muokkaat sivua.\'\'\'',
+'editingold' => '<center><strong>Varoitus</strong>: Olet muokkaamassa vanhaa versiota tämän sivun tekstistä. Jos tallennat sen, kaikki tämän version jälkeen tehdyt muutokset katoavat.</center>',
+'yourdiff' => 'Eroavaisuudet',
+'copyrightwarning' => '<strong>Muutoksesi astuvat voimaan välittömästi.</strong> Jos haluat harjoitella muokkaamista, ole hyvä ja käytä [[Project:Hiekkalaatikko|hiekkalaatikkoa]].<br /><br />Kaikki {{GRAMMAR:illative|{{SITENAME}}}} tehtävät tuotokset katsotaan julkaistuksi $2 -lisenssin mukaisesti ($1). Jos et halua, että kirjoitustasi muokataan armottomasti ja uudelleenkäytetään vapaasti, älä tallenna kirjoitustasi. Tallentamalla muutoksesi lupaat, että kirjoitit tekstisi itse, tai kopioit sen jostain vapaasta lähteestä. <strong>ÄLÄ KÄYTÄ TEKIJÄNOIKEUDEN ALAISTA MATERIAALIA ILMAN LUPAA!</strong>',
+'copyrightwarning2' => '>Huomaa, että kuka tahansa voi muokata, muuttaa ja poistaa kaikkia sivustolle tekemiäsi lisäyksiä ja muutoksia. Muokkaamalla sivustoa luovutat sivuston käyttäjille tämän oikeuden ja takaat, että lisäämäsi aineisto on joko itse kirjoittamaasi tai peräisin jostain vapaasta lähteestä. Lisätietoja sivulla $1. <strong>TEKIJÄNOIKEUDEN ALAISEN MATERIAALIN KÄYTTÄMINEN ILMAN LUPAA ON EHDOTTOMASTI KIELLETTYÄ!</strong>',
+'longpagewarning' => '<center>Tämän sivun tekstiosuus on $1 binäärikilotavua pitkä. Harkitse, voisiko sivun jakaa pienempiin osiin.</center>',
+'longpageerror' => '<strong>Sivun koko on $1 binäärikilotavua. Sivua ei voida tallentaa, koska enimmäiskoko on $2 binäärikilotavua.</strong>',
+'readonlywarning' => '<strong>Varoitus</strong>: Tietokanta on lukittu huoltoa varten, joten voi olla ettet pysty tallentamaan muokkauksiasi juuri nyt. Saattaa olla paras leikata ja liimata tekstisi omaan tekstitiedostoosi ja tallentaa se tänne myöhemmin.',
+'protectedpagewarning'=> '<center><small>Tämä sivu on lukittu. Vain ylläpitäjät voivat muokata sitä.</small></center>',
+'semiprotectedpagewarning' => 'Vain rekisteröityneet käyttäjät voivat muokata tätä sivua.',
+'templatesused' => 'Tällä sivulla käytetyt mallineet:',
+'templatesusedpreview'=> 'Esikatselussa mukana olevat mallineet:',
+'templatesusedsection'=> 'Tässä osiossa mukana olevat mallineet:',
+'template-protected' => '(suojattu)',
+'template-semiprotected' => '(suojattu anonyymeiltä ja uusilta käyttäjiltä)',
+'edittools' => '<!-- Tässä oleva teksi näytetään muokkauskentän alla. -->',
+'nocreatetitle' => 'Sivujen luominen on rajoitettu',
+'nocreatetext' => 'Et voi luoda uusia sivuja. Voit muokata olemassa olevia sivuja tai luoda [[Special:Userlogin|käyttäjätunnukssen]].',
+
+# "Undo" feature
+'undo-success' => 'Kumoaminen onnistui. Valitse <em>tallenna</em> toteuttaaksesi muutokset.',
+'undo-failure' => 'Muokkausta ei voitu kumota välissä olevien ristiriistaisten muutosten vuoksi. Kumoa muutokset käsin.',
+'undo-summary' => 'Kumottu muokkaus #$1, jonka teki [[Special:Contributions/$2|$2]] ([[User_talk:$2|keskustelu]])',
+
+'cantcreateaccounttitle' => 'Tunnuksen luominen epäonnistui',
+'cantcreateaccounttext' => 'Tunnuksien luominen tästä IP-osoitteesta ($1) on estetty. Syynä tähän on luultavasti jatkuva häiriköinti yhteiskäyttökoneelta.',
+
+# History pages
+#
+'revhistory' => 'Muutoshistoria',
+'viewpagelogs' => 'Näytä tämän sivun lokit',
+'nohistory' => 'Tällä sivulla ei ole muutoshistoriaa.',
+'revnotfound' => 'Versiota ei löydy',
+'revnotfoundtext' => 'Pyytämääsi versiota ei löydy. Tarkista URL-osoite, jolla hait tätä sivua.',
+'loadhist' => 'Ladataan sivuhistoriaa',
+'currentrev' => 'Nykyinen versio',
+'revisionasof' => 'Versio $1',
+'revision-info' => 'Versio hetkellä $1 – tehnyt $2',
+'previousrevision' => '← Vanhempi versio',
+'nextrevision' => 'Uudempi versio →',
+'currentrevisionlink' => 'Nykyinen versio',
+'cur' => 'nyk.',
+'next' => 'seur.',
+'last' => 'edell.',
+'orig' => 'alkup.',
+'histlegend' => 'Merkinnät: (nyk.) = eroavaisuudet nykyiseen versioon, (edell.) = eroavaisuudet edelliseen versioon, <span class="minor">p</span> = pieni muutos',
+'deletedrev' => '[poistettu]',
+'histfirst' => 'Ensimmäiset',
+'histlast' => 'Viimeisimmät',
+
+'rev-deleted-comment' => '(kommentti poistettu)',
+'rev-deleted-user' => '(käyttäjänimi poistettu)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">Tämä versio on poistettu julkisesta arkistosta. [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} Poistolokissa] saattaa olla lisätietoja.</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">Tämä versio on poistettu julkisesta arkistosta.</div>',
+'rev-delundel' => 'näytä tai piilota',
+
+# Revision deletion
+#
+'revisiondelete' => 'Poista tai palauta versioita',
+'revdelete-nooldid-title' => 'Ei kohdeversiota',
+'revdelete-nooldid-text' => 'Et ole valinnut kohdeversiota tai -versioita.',
+'revdelete-selected' => 'Valittu versio [[:$1]]:',
+'revdelete-text' => "Poistetut versiot näkyvät sivun historiassa, mutta niiden sisältö ei ole julkisesti saatavilla.\n\nMuut ylläpitäjät voivat lukea piilotetun sisällön ja palauttaa sen.",
+'revdelete-legend' => 'Version rajoitukset:',
+'revdelete-hide-text' => 'Piilota version sisältö',
+'revdelete-hide-comment' => 'Piilota yhteenveto',
+'revdelete-hide-user' => 'Piilota tekijän tunnus tai IP-osoite',
+'revdelete-hide-restricted' => 'Apply these restrictions to sysops as well as others',
+'revdelete-log' => 'Lokimerkintä:',
+'revdelete-submit' => 'Toteuta',
+'revdelete-logentry' => 'muutti sivun [[$1]] version näkyvyyttä',
+
+
+# Diffs
+#
+'difference' => 'Versioiden väliset erot',
+'loadingrev' => 'Ladataan versiota vertailua varten',
+'lineno' => 'Rivi $1:',
+'editcurrent' => 'Muokkaa tämän sivun uusinta versiota',
+'selectnewerversionfordiff' => 'Valitse uudempi versio vertailuun',
+'selectolderversionfordiff' => 'Valitse vanhempi versio vertailuun',
+'compareselectedversions' => 'Vertaile valittuja versioita',
+'editundo' => 'kumoa',
+'diff-multi' => '(Versioiden välissä {{PLURAL:$1|yksi muu muokkaus|$1 muuta muokkausta}}.)',
+
+# Search results
+#
+'searchresults' => 'Hakutulokset',
+'searchresulttext' => 'Saadaksesi lisätietoa hakutoiminnoista tällä sivustolla lue [[Project:Hakutoiminnot|sivuston hakuohje]].',
+'searchsubtitle' => 'Haku termeillä [[:$1]]',
+'searchsubtitleinvalid'=> 'Haku termeillä $1',
+'badquery' => 'Kelvoton hakumerkkijono',
+'badquerytext' => 'Tekemäsi kysely ei ole kelvollinen. Tämä johtuu todennäköisesti siitä, että et ole määritellyt hakumerkkijonoa.',
+'matchtotals' => 'Haulla \'\'\'$1\'\'\' löytyi $2 osumaa sivujen otsikoista ja $3 osumaa sivujen sisällöistä.',
+'noexactmatch' => '<big>Otsikolla $1 ei ole sivua.</big>
+
+:Voit [[$1|luoda aiheesta uuden sivun]].
+:<small>Etsi ensin vastaavaa sivua, joka voi olla kirjoitusasultaan hieman erilainen</small>',
+'titlematches' => 'Osumat sivujen otsikoissa',
+'notitlematches' => 'Hakusanaa ei löytynyt minkään sivun otsikosta',
+'textmatches' => 'Osumat sivujen teksteissä',
+'notextmatches' => 'Hakusanaa ei löytynyt sivujen teksteistä',
+'prevn' => '← $1 edellistä',
+'nextn' => '$1 seuraavaa →',
+'viewprevnext' => "Näytä [$3] kerralla.\n\n$1 | $2",
+'showingresults' => '<b>$1</b> tulosta tuloksesta <b>$2</b> alkaen.',
+'showingresultsnum' => 'Alla on <b>$3</b> hakutulosta alkaen <b>$2.</b> tuloksesta.',
+'nonefound' => '\'\'\'Huomautus\'\'\': Epäonnistuneet haut johtuvat usein hyvin yleisten sanojen, kuten \'\'on\'\' ja \'\'ei\'\', etsimisestä tai useamman kuin yhden hakutermin määrittelemisestä. Vain sivut, joilla on kaikki hakutermin sanat, näkyvät tuloksissa.',
+'powersearch' => 'Etsi',
+'powersearchtext' => 'Hae nimiavaruuksista:<br />$1<br />$2 Luettele uudelleenohjaukset<br />Etsi: $3 $9',
+'searchdisabled' => '<p style="margin: 1.5em 2em 1em">Tekstihaku on poistettu toistaiseksi käytöstä suuren kuorman vuoksi. Voit käyttää alla olevaa Googlen hakukenttää sivujen etsimiseen, kunnes haku tulee taas käyttöön.<small>Huomaa, että ulkopuoliset kopiot {{GRAMMAR:genitive|{{SITENAME}}}} sisällöstä eivät välttämättä ole ajan tasalla.</small></p>',
+
+'blanknamespace' => '(sivut)',
+
+# Preferences page
+#
+'preferences' => 'Asetukset',
+'mypreferences' => 'Asetukset',
+'prefsnologin' => 'Et ole kirjautunut sisään.',
+'prefsnologintext' => 'Sinun täytyy [[Special:Userlogin|kirjautua sisään]], jotta voisit muuttaa asetuksiasi.',
+'prefsreset' => 'Asetukset on palautettu tallennetuista asetuksistasi.',
+'qbsettings' => 'Pikavalikko',
+'changepassword' => 'Vaihda salasanaa',
+'skin' => 'Ulkonäkö',
+'math' => 'Matematiikka',
+'dateformat' => 'Päiväyksen muoto',
+'datedefault' => 'Ei valintaa',
+'datetime' => 'Aika ja päiväys',
+'math_failure' => 'Jäsentäminen epäonnistui',
+'math_unknown_error' => 'Tuntematon virhe',
+'math_unknown_function' => 'Tuntematon funktio',
+'math_lexing_error' => 'Tulkintavirhe',
+'math_syntax_error' => 'Jäsennysvirhe',
+'math_image_error' => 'PNG-muunnos epäonnistui; tarkista, että latex, dvips, gs ja convert on asennettu oikein.',
+'math_bad_tmpdir' => 'Matematiikan kirjoittaminen väliaikaishakemistoon tai tiedostonluonti ei onnistu',
+'math_bad_output' => 'Matematiikan tulostehakemistoon kirjoittaminen tai tuedostonluonti ei onnistu',
+'math_notexvc' => 'Texvc-sovellus puuttuu, lue math/READMEstä asennustietoja',
+'prefs-personal' => 'Käyttäjätiedot',
+'prefs-rc' => 'Tuoreet muutokset ja tyngät',
+'prefs-watchlist' => 'Tarkkailulista',
+'prefs-watchlist-days' => 'Tarkkailulistan ajanjakso:',
+'prefs-watchlist-edits' => 'Tarkkailulistalla näytettävien muutosten määrä:',
+'prefs-misc' => 'Muut asetukset',
+'saveprefs' => 'Tallenna asetukset',
+'resetprefs' => 'Palauta tallennetut asetukset',
+'oldpassword' => 'Vanha salasana:',
+'newpassword' => 'Uusi salasana:',
+'retypenew' => 'Uusi salasana uudelleen:',
+'textboxsize' => 'Muokkaaminen',
+'rows' => 'Rivit:',
+'columns' => 'Sarakkeet:',
+'searchresultshead' => 'Haku',
+'resultsperpage' => 'Tuloksia sivua kohti:',
+'contextlines' => 'Rivien määrä tulosta kohti:',
+'contextchars' => 'Sisällön merkkien määrä riviä kohden:',
+'stubthreshold' => 'Tynkäsivun osoituskynnys:',
+'recentchangescount' => 'Sivujen määrä tuoreissa muutoksissa:',
+'savedprefs' => 'Asetuksesi tallennettiin onnistuneesti.',
+'timezonelegend' => 'Aikavyöhyke',
+'timezonetext' => 'Paikallisen ajan ja palvelimen ajan (UTC) välinen aikaero tunteina.',
+'localtime' => 'Paikallinen aika',
+'timezoneoffset' => 'Aikaero¹:',
+'servertime' => 'Palvelimen aika',
+'guesstimezone' => 'Utele selaimelta',
+'allowemail' => 'Salli sähköpostin lähetys osoitteeseen',
+'defaultns' => 'Etsi oletusarvoisesti näistä nimiavaruuksista:',
+'default' => 'oletus',
+'files' => 'Tiedostot',
+
+# User rights
+'userrights-lookup-user' => 'Käyttöoikeuksien hallinta',
+'userrights-user-editname' => 'Käyttäjätunnus:',
+'editusergroup' => 'Muokkaa käyttäjän ryhmiä',
+
+'userrights-editusergroup' => 'Käyttäjän ryhmät',
+'saveusergroups' => 'Tallenna',
+'userrights-groupsmember' => 'Jäsenenä ryhmissä:',
+'userrights-groupsavailable' => 'Saatavilla olevat ryhmät:',
+'userrights-groupshelp' => 'Valitse ryhmät, jotka haluat poistaa tai lisätä. Valitsemattomia ryhmiä ei muuteta. Voit poistaa valinnan pitämällä Ctrl-näppäintä pohjassa napsautuksen aikana.',
+
+# Groups
+'group' => 'Ryhmä:',
+'group-bot' => 'botit',
+'group-sysop' => 'ylläpitäjät',
+'group-bureaucrat' => 'byrokraatit',
+'group-all' => '(kaikki)',
+'group-bot-member' => 'botti',
+'group-sysop-member' => 'ylläpitäjä',
+'group-bureaucrat-member' => 'byrokraatti',
+'grouppage-bot' => '{{ns:project}}:Botit',
+'grouppage-sysop' => '{{ns:project}}:Ylläpitäjät',
+'grouppage-bureaucrat' => '{{ns:project}}:Byrokraatit',
+
+
+# Recent changes
+#
+'changes' => 'muutosta',
+'recentchanges' => 'Tuoreet muutokset',
+'recentchangestext' => 'Tällä sivulla voi seurata tuoreita {{GRAMMAR:illative|{{SITENAME}}}} tehtyjä muutoksia.',
+'recentchanges-feed-description' => 'Tällä sivulla voi seurata tuoreita {{GRAMMAR:illative|{{SITENAME}}}} tehtyjä muutoksia.',
+'rcnote' => 'Alla on <b>$1</b> tuoreinta muutosta viimeisten <b>$2</b> päivän ajalta $3.',
+'rcnotefrom' => 'Alla on muutokset <b>$2</b> lähtien. Enintään <b>$1</b> merkintää näytetään.',
+'rclistfrom' => 'Näytä uudet muutokset $1 alkaen',
+'rcshowhideminor' => '$1 pienet muutokset',
+'rcshowhidebots' => '$1 botit',
+'rcshowhideliu' => '$1 kirjautuneet käyttäjät',
+'rcshowhideanons' => '$1 anonyymit käyttäjät',
+'rcshowhidepatr' => '$1 tarkastetut muutokset',
+'rcshowhidemine' => '$1 omat muutokset',
+'rclinks' => 'Näytä $1 tuoretta muutosta viimeisten $2 päivän ajalta.<br />$3',
+'diff' => 'ero',
+'hist' => 'historia',
+'hide' => 'piilota',
+'show' => 'näytä',
+'minoreditletter' => 'p',
+'newpageletter' => 'U',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 tarkkailevaa käyttäjää]', // TODO sigplu
+'rc_categories' => 'Vain luokista (erotin on ”|”)',
+'rc_categories_any' => 'Mikä tahansa',
+
+
+# Upload
+#
+'upload' => 'Lisää tiedosto',
+'uploadbtn' => 'Lähetä tiedosto',
+'reupload' => 'Lähetä uudelleen',
+'reuploaddesc' => 'Palaa lähetyslomakkeelle.',
+'uploadnologin' => 'Et ole kirjautunut sisään',
+'uploadnologintext' => 'Sinun pitää olla [[Special:Userlogin|kirjautuneena sisään]], jotta voisit lisätä tiedostoja.',
+'upload_directory_read_only' => 'Palvelimella ei ole kirjoitusoikeuksia tallennushakemistoon ”<tt>$1</tt>”.',
+'uploaderror' => 'Tallennusvirhe',
+'uploadtext' => 'Ennen kuin lähetät tiedostoja {{GRAMMAR:illative|{{SITENAME}}}}, lue seuraava:
+*\'\'Kirjoita tiedoston tietoihin tarkka tieto tiedoston lähteestä.\'\'
+*\'\'Kerro tiedoston tekijänoikeuksien tila.\'\'
+*\'\'Käytä järkevää tiedostonimeä.\'\' Nimeä tiedostosi mieluummin tyyliin ”Eiffel-torni Pariisissa, yökuva.jpg” kuin ”etpan1024c.jpg”. Näin vältät mahdollisesti jo olemassa olevan tiedoston korvaamisen omallasi.
+*Laita johonkin aiheeseen liittyvään sivuun linkki kyseiseen tiedostoon, tai kirjoita kuvaussivulle kuvaus tiedoston sisällöstä.
+*Jos haluat nähdä tai etsiä aiemmin lisättyjä tiedostoja, katso [[Special:Imagelist|tiedostoluettelo]]. Tallennukset ja poistot kirjataan [[Special:Log/upload|tiedostolokiin]].
+
+Suositellut kuvaformaatit ovat JPEG valokuville, PNG piirroksille ja kuvakkeille ja Ogg Vorbis äänille. Voit liittää kuvan sivulle käyttämällä seuraavan muotoista merkintää \'\'\'<nowiki>[[Kuva:tiedosto.jpg]]</nowiki>\'\'\' tai \'\'\'<nowiki>[[Kuva:tiedosto.png|kuvausteksti]]</nowiki>\'\'\' tai \'\'\'<nowiki>[[media:tiedosto.ogg]]</nowiki>\'\'\' äänille.
+
+Huomaa, että {{GRAMMAR:inessive|{{SITENAME}}}} muut voivat muokata tai poistaa lähettämäsi tiedoston, jos he katsovat, että se ei palvele projektin tarpeita. Tallentamismahdollisuutesi voidaan estää, jos käytät järjestelmää väärin.',
+'uploadlog' => 'Tiedostoloki',
+'uploadlogpage' => 'Tiedostoloki',
+'uploadlogpagetext' => 'Alla on luettelo uusimmista tiedostonlisäyksistä. Kaikki ajat näytetään palvelimen aikavyöhykkeessä (UTC).',
+'filename' => 'Tiedoston nimi',
+'filedesc' => 'Yhteenveto',
+'fileuploadsummary' => 'Yhteenveto:',
+'filestatus' => 'Tiedoston tekijänoikeudet',
+'filesource' => 'Lähde',
+'copyrightpage' => '{{ns:project}}:Tekijänoikeudet',
+'copyrightpagename' => '{{SITENAME}} ja tekijänoikeudet',
+'uploadedfiles' => 'Lisätyt tiedostot',
+'ignorewarning' => 'Tallenna tiedosto varoituksesta huolimatta.',
+'ignorewarnings' => 'Ohita kaikki varoitukset',
+'minlength' => 'Tiedoston nimessä pitää olla vähintään kolme merkkiä.',
+'illegalfilename' => 'Tiedoston nimessä \'\'\'$1\'\'\' on merkkejä, joita ei sallita sivujen nimissä. Vaihda tiedoston nimeä, ja yritä lähettämistä uudelleen.',
+'badfilename' => 'Tiedoston nimi vaihdettiin: $1.',
+'badfiletype' => '”<tt>.$1</tt>” ei ole suositeltava tiedostomuoto.',
+'large-file' => 'Tiedostojen enimmäiskoko on $1. Lähettämäsi tiedoston koko on $2.',
+'largefileserver' => 'Tämä tiedosto on suurempi kuin mitä palvelin sallii.',
+'emptyfile' => 'Tiedosto, jota yritit lähettää, näyttää olevan tyhjä. Tarkista, että kirjoitit polun ja nimen oikein ja että se ei ole liian suuri kohdepalvelimelle.',
+'fileexists' => 'Samanniminen tiedosto on jo olemassa. Katso tiedoston sivu $1, jos et ole varma, haluatko muuttaa sitä.',
+'fileexists-forbidden'=> 'Samanniminen tiedosto on jo olemassa. Tallenna tiedosto jollakin toisella nimellä. Nykyinen tiedosto: [[{ns:image}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Samanniminen tiedosto on jo olemassa jaetussa mediavarastossa. Tallenna tiedosto jollakin toisella nimellä. Nykyinen tiedosto: [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Tallennus onnistui',
+'fileuploaded' => 'Tiedosto \'\'\'$1\'\'\' on tallennettu onnistuneesti. Seuraa linkkiä ($2) kuvaussivulle, ja täytä tiedostoon liityvät tiedot, kuten mistä se on peräisin, milloin se on luotu, kuka sen loi ja mahdollisesti muita tietämiäsi tietoja. Jos tiedosto on kuva, voit lisätä sen sivulle näin: \'\'\'<nowiki>[[Kuva:$1|thumb|Kuvaus]]</nowiki>\'\'\'',
+'uploadwarning' => 'Tallennusvaroitus',
+'savefile' => 'Tallenna',
+'uploadedimage' => 'lisäsi tiedoston [[$1]]',
+'uploaddisabled' => '{{GRAMMAR:genitive|{{SITENAME}}}} ei voi lisätä tiedostoja.',
+'uploaddisabledtext' => 'Tiedostojen lisäys on poistettu käytöstä.',
+'uploadscripted' => 'Tämä tiedosto sisältää HTML-koodia tai skriptejä, jotka selain saattaa virheellisesti suorittaa.',
+'uploadcorrupt' => 'Tiedosto on vioittunut tai sillä on väärä tiedostopääte. Tarkista tiedosto ja lähetä se uudelleen.',
+'uploadvirus' => 'Tiedosto sisältää viruksen. Tarkemmat tiedot: $1',
+'sourcefilename' => 'Lähdenimi',
+'destfilename' => 'Kohdenimi',
+'watchthisupload' => 'Tarkkaile tätä sivua',
+'filewasdeleted' => 'Tämän niminen tiedosto on lisätty ja poistettu aikaisemmin. Tarkista $1 ennen jatkamista.',
+
+'upload-proto-error' => 'Virheellinen protokolla',
+'upload-proto-error-text' => 'Etälähetys on mahdollista vain osoitteista, jotka alkavat merkkijonolla <code>http://</code> tai <code>ftp://</code>.',
+'upload-file-error' => 'Vakava virhe',
+'upload-file-error-text' => 'Väliaikaistiedoston luominen epäonnistui. Ota yhteyttä sivuston ylläpitäjään.',
+'upload-misc-error' => 'Virhe',
+'upload-misc-error-text' => 'Tiedoston etälähetys ei onnistunut. Varmista, että antamasi osoite on oikein ja toimiva. Jos virhe ei katoa, ota yhteyttä sivuston ylläpitäjään.',
+'upload-curl-error6' => 'Toimimaton osoite',
+'upload-curl-error6-text' => 'Antamaasi osoitteeseen ei saatu yhteyttä. Varmista, että osoite on oikein ja että sivusto on saavutettavissa.',
+'upload-curl-error28' => 'Etälähetyksen aikakatkaisu',
+'upload-curl-error28-text'=> 'Antamastasi osoitteesta ei saatu vastausta määräajassa. Varmista, että sivusto on saavutettavissa ja yritä uudelleen.',
+
+'license' => 'Lisenssi',
+'nolicense' => 'Ei lisenssiä',
+'upload_source_url' => ' (julkinen verkko-osoite)',
+'upload_source_file' => ' (tiedosto tietokoneella)',
+
+
+# Image list
+#
+'imagelist' => 'Tiedostoluettelo',
+'imagelisttext' => 'Alla on <strong>$1</strong> tiedostoa lajiteltuna <strong>$2</strong>.',
+'imagelistforuser' => 'Käyttäjän ”$1” lisäämät kuvat.',
+'getimagelist' => 'noudetaan tiedostoluetteloa',
+'ilsubmit' => 'Hae',
+'showlast' => 'Näytä viimeiset $1 tiedostoa lajiteltuna $2.',
+'byname' => 'nimen mukaan',
+'bydate' => 'päiväyksen mukaan',
+'bysize' => 'koon mukaan',
+'imgdelete' => 'poista',
+'imgdesc' => 'kuvaus',
+'imgfile' => 'tiedosto',
+'imglegend' => 'Merkinnät: (kuvaus) = näytä tai muokkaa tiedoston kuvausta.',
+'imghistory' => 'Historia',
+'revertimg' => 'palauta',
+'deleteimg' => 'poista',
+'deleteimgcompletely' => 'poista',
+'imghistlegend' => 'Merkinnät: (nyk.) = nykyinen versio, (poista) = poista tämä vanha versio, (palauta) = palauta tiedosto tähän vanhaan versioon.<br />Napsauta päiväystä nähdäksesi silloin tallennettu tiedosto.',
+'imagelinks' => 'Viittaukset sivuilta',
+'linkstoimage' => 'Seuraavilta sivuilta on linkki tähän tiedostoon:',
+'nolinkstoimage' => 'Tähän tiedostoon ei ole linkkejä miltään sivulta.',
+'sharedupload' => 'Tämä tiedosto on jaettu ja muut projektit saattavat käyttää sitä.',
+'shareduploadwiki' => 'Katso $1 lisätietoja.',
+'shareduploadwiki-linktext' => 'kuvaussivulta',
+'noimage' => 'Tämän nimistä tiedostoa ei ole olemassa. Voit $1 {{GRAMMAR:illative|{{SITENAME}}}}',
+'noimage-linktext' => 'lisätä tiedoston',
+'uploadnewversion-linktext' => 'Lisää uusi versio tästä tiedostosta',
+'imagelist_date' => 'Päiväys',
+'imagelist_name' => 'Nimi',
+'imagelist_user' => 'Lähettäjä',
+'imagelist_size' => 'Koko (tavuja)',
+'imagelist_description' => 'Kuvaus',
+'imagelist_search_for'=> 'Nimihaku:',
+
+# Mime search
+#
+'mimesearch' => 'MIME-haku',
+'mimetype' => 'MIME-tyyppi:',
+'download' => 'lataa',
+
+# Unused templates
+'unusedtemplates' => 'Käyttämättömät mallineet',
+'unusedtemplatestext' => 'Tässä on lista kaikista mallineista, joita ei ole liitetty toiselle sivulle. Muista tarkistaa onko malline siitä huolimatta käytössä.',
+'unusedtemplateswlh' => 'muut linkit',
+
+
+# Statistics
+#
+'statistics' => 'Tilastoja',
+'sitestats' => 'Sivuston tilastoja',
+'userstats' => 'Käyttäjätilastoja',
+'sitestatstext' => 'Tietokannassa on yhteensä \'\'\'$1\'\'\' sivua. Tähän on laskettu mukaan keskustelusivut, {{GRAMMAR:genitive|{{SITENAME}}}} erikoissivut, hyvin lyhyet sivut, uudelleenohjaukset sekä muita sivuja, joita ei voi pitää kunnollisina sivuina. Nämä poislukien tietokannassa on \'\'\'$2\'\'\' sivua.
+
+{{GRAMMAR:illative|{{SITENAME}}}} on tallennettu \'\'\'$8\'\'\' tiedostoa.
+
+Sivuja on katsottu yhteensä \'\'\'$3\'\'\' kertaa ja muokattu \'\'\'$4\'\'\' kertaa. Keskimäärin yhtä sivua on muokattu \'\'\'$5\'\'\' kertaa, ja muokkausta kohden sivua on katsottu keskimäärin \'\'\'$6\'\'\' kertaa.
+
+Ohjelmiston ylläpitotöitä on jonossa \'\'\'$7\'\'\' kappaletta.',
+'userstatstext' => 'Rekisteröityneitä käyttäjiä on \'\'\'$1\'\'\'. Näistä \'\'\'$2\'\'\' ($4%) on ylläpitäjiä ($5).',
+'statistics-mostpopular' => 'Eniten katsellut sivut',
+
+'disambiguations' => 'Linkit täsmennyssivuihin',
+'disambiguationspage' => 'Project:Linkkejä_täsmennyssivuihin',
+'disambiguationstext' => 'Seuraavat artikkelit linkittävät <i>täsmennyssivuun</i>. Sen sijasta niiden pitäisi linkittää asianomaiseen aiheeseen.<br />Sivua kohdellaan täsmennyssivuna jos siihen on linkki sivulta $1.<br />Linkkejä muihin nimiavaruuksiin <i>ei</i> ole listattu tässä.',
+
+'doubleredirects' => 'Kaksinkertaiset uudelleenohjaukset',
+'doubleredirectstext' => '<b>Huomio:</b> Tässä listassa saattaa olla virheitä. Yleensä kyseessä on sivu, jossa ensimmäisen #REDIRECTin jälkeen on tekstiä.<br />\nJokaisella rivillä on linkit ensimmäiseen ja toiseen uudelleenohjaukseen sekä toisen uudelleenohjauksen kohteen ensimmäiseen riviin, eli yleensä ”oikeaan” kohteeseen, johon ensimmäisen uudelleenohjauksen pitäisi osoittaa.',
+
+'brokenredirects' => 'Virheelliset uudelleenohjaukset',
+'brokenredirectstext' => 'Seuraavat uudelleenohjaukset on linkitetty artikkeleihin, joita ei ole olemassa.',
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|tavu|tavua}}',
+'ncategories' => '$1 {{PLURAL:$1|luokka|luokkaa}}',
+'nlinks' => '$1 {{PLURAL:$1|linkki|linkkiä}}',
+'nmembers' => '$1 {{PLURAL:$1|jäsen|jäsentä}}',
+'nrevisions' => '$1 {{PLURAL:$1|muutos|muutosta}}',
+'nviews' => '$1 {{PLURAL:$1|lataus|latausta}}',
+'lonelypages' => 'Yksinäiset sivut',
+'lonelypagestext' => 'Seuraaviin sivuhin ei ole linkkejä muualta wikistä.',
+'uncategorizedpages' => 'Luokittelemattomat sivut',
+'uncategorizedcategories' => 'Luokittelemattomat luokat',
+'uncategorizedimages' => 'Luokittelemattomat tiedostot',
+'unusedcategories' => 'Käyttämättömät luokat',
+'unusedimages' => 'Käyttämättömät tiedostot',
+'popularpages' => 'Suositut sivut',
+'wantedcategories' => 'Halutut luokat',
+'wantedpages' => 'Halutut sivut',
+'mostlinked' => 'Sivut, joihin on eniten linkkejä',
+'mostlinkedcategories'=> 'Luokat, joihin on eniten linkkejä',
+'mostcategories' => 'Sivut, jotka ovat useissa luokissa',
+'mostimages' => 'Kuvat, joihin on eniten linkkejä',
+'mostrevisions' => 'Sivut, joilla on eniten muutoksia',
+'allpages' => 'Kaikki sivut',
+'prefixindex' => 'Sivut otsikon alun mukaan',
+'randompage' => 'Satunnainen sivu',
+'shortpages' => 'Lyhyet sivut',
+'longpages' => 'Pitkät sivut',
+'deadendpages' => 'Sivut, joilla ei ole linkkejä',
+'deadendpagestext' => 'Seuraavat sivut eivät linkitä muihin sivuihin wikissä.',
+'listusers' => 'Käyttäjälista',
+'specialpages' => 'Toimintosivut',
+'spheading' => 'Toimintosivut',
+'restrictedpheading' => 'Rajoitetut toimintosivut',
+'recentchangeslinked' => 'Linkitettyjen sivujen muutokset',
+'rclsub' => 'Sivut, joihin linkki sivulta $1',
+'newpages' => 'Uudet sivut',
+'newpages-username' => 'Käyttäjätunnus:',
+'ancientpages' => 'Kauan muokkaamattomat sivut',
+'intl' => 'Kieltenväliset linkit',
+'move' => 'Siirrä',
+'movethispage' => 'Siirrä tämä sivu',
+'unusedimagestext' => 'Huomaa, että muut verkkosivut saattavat viitata tiedostoon suoran URL:n avulla, jolloin tiedosto saattaa olla tässä listassa, vaikka sitä käytetäänkin.',
+'unusedcategoriestext'=> 'Nämä luokat ovat olemassa, mutta niitä ei käytetä.',
+
+# Book sources
+'booksources' => 'Kirjalähteet',
+'booksources-search-legend' => 'Etsi kirjalähteitä',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => 'Etsi',
+'booksources-text' => 'Alla linkkejä ulkopuolisiin sivustoihin, joilla myydään uusia ja käytettyjä kirjoja. Sivuilla voi myös olla lisätietoa kirjoista.',
+
+'categoriespagetext' => '{{GRAMMAR:inessive|{{SITENAME}}}} on seuraavat luokat:',
+'data' => 'Data', // TODO: CHECK ME
+'userrights' => 'Käyttöoikeuksien hallinta',
+'groups' => 'Ryhmät',
+
+'isbn' => 'ISBN',
+'unwatchedpages' => 'Tarkkailemattomat sivut',
+'listinterwikis' => 'Ulkowikilinkit',
+'listredirects' => 'Uudelleenohjaukset',
+'randomredirect' => 'Satunnainen uudelleenohjaus',
+
+
+# No reason to overwrite
+'alphaindexline' => '$1…$2',
+'version' => 'Versio',
+'log' => 'lokit',
+'alllogstext' => 'Yhdistetty lokien näyttö. Voit rajoittaa listaa valitsemalla lokityypin, käyttäjän tai sivun johon muutos on kohdistunut.',
+'logempty' => 'Ei tapahtumia lokissa.',
+
+# Special:Allpages
+'nextpage' => 'Seuraava sivu ($1)',
+'prevpage' => 'Edellinen sivu ($1)',
+'allpagesfrom' => 'Näytä sivuja lähtien sivusta:',
+'allarticles' => 'Kaikki sivut',
+'allinnamespace' => 'Kaikki sivut nimiavaruudessa $1',
+'allnotinnamespace' => 'Kaikki sivut, jotka eivät ole nimiavaruudessa $1',
+'allpagesprev' => 'Edellinen',
+'allpagesnext' => 'Seuraava',
+'allpagessubmit' => 'Vaihda',
+'allpagesprefix' => 'Näytä sivut, joiden otsikko alkaa',
+'allpagesbadtitle' => 'Annettu otsikko oli kelvoton tai siinä oli wikien välinen etuliite.',
+
+# Special:Listusers
+'listusersfrom' => 'Näytä käyttäjät alkaen:',
+
+# Email this user
+#
+'mailnologin' => 'Lähettäjän osoite puuttuu',
+'mailnologintext' => 'Sinun pitää olla [[Special:Userlogin|kirjautuneena sisään]] ja [[Special:Preferences|asetuksissasi]] pitää olla toimiva ja <strong>varmennettu</strong> sähköpostiosoite, jotta voit lähettää sähköpostia muille käyttäjille.',
+'emailuser' => 'Lähetä sähköpostia tälle käyttäjälle',
+'emailpage' => 'Lähetä sähköpostia käyttäjälle',
+'emailpagetext' => 'Jos tämä käyttäjä on antanut asetuksissaan kelvollisen sähköpostiosoitteen, alla olevalla lomakeella voi lähettää yhden viestin hänelle. Omissa asetuksissasi annettu sähköpostiosoite näkyy sähköpostin lähettäjän osoitteena, jotta vastaanottaja voi vastata viestiin.',
+'usermailererror' => 'Postitus palautti virheen:',
+'defemailsubject' => '{{SITENAME}}-sähköposti',
+'noemailtitle' => 'Ei sähköpostiosoitetta',
+'noemailtext' => 'Tämä käyttäjä ei ole määritellyt kelpoa sähköpostiosoitetta tai ei halua postia muilta käyttäjiltä.',
+'emailfrom' => 'Lähettäjä',
+'emailto' => 'Vastaanottaja',
+'emailsubject' => 'Aihe',
+'emailmessage' => 'Viesti',
+'emailsend' => 'Lähetä',
+'emailccme' => 'Lähetä kopio viestistä minulle.',
+'emailccsubject' => 'Kopio lähettämästäsi viestistä osoitteeseen $1: $2',
+'emailsent' => 'Sähköposti lähetetty',
+'emailsenttext' => 'Sähköpostiviestisi on lähetetty.',
+
+# Watchlist
+#
+'watchlist' => 'Tarkkailulista',
+'watchlistfor' => 'käyttäjälle <b>$1</b>',
+'nowatchlist' => 'Tarkkailulistallasi ei ole sivuja.',
+'watchlistanontext' => 'Sinun täytyy $1, jos haluat käyttää tarkkailulistaa.',
+'watchlistcount' => 'Tarkkailulistallasi on <b>$1</b> sivua, keskustelusivut mukaanlukien.',
+'clearwatchlist' => 'Tarkkailulistan tyhjentäminen',
+'watchlistcleartext' => 'Haluatko tyhjentää tarkkailulistan?',
+'watchlistclearbutton'=> 'Tyhjennä tarkkailusta',
+'watchlistcleardone' => 'Tarkkailulista on tyhjennetty. $1 sivua poistettiin listalta.',
+'watchnologin' => 'Et ole kirjautunut sisään',
+'watchnologintext' => 'Sinun pitää kirjautua sisään, jotta voisit käyttää tarkkailulistaa.',
+'addedwatch' => 'Lisätty tarkkailulistalle',
+'addedwatchtext' => 'Sivu \'\'\'$1\'\'\' on lisätty [[Special:Watchlist|tarkkailulistallesi]]. Tulevaisuudessa sivuun ja sen keskustelusivuun tehtävät muutokset listataan täällä. Sivu on \'\'\'lihavoitu\'\'\' [[Special:Recentchanges|tuoreiden muutosten listassa]], jotta huomaisit sen helpommin. Jos haluat myöhemmin poistaa sivun tarkkailulistaltasi, napsauta linkkiä \'\'lopeta tarkkailu\'\' sivun reunassa.',
+'removedwatch' => 'Poistettu tarkkailulistalta',
+'removedwatchtext' => 'Sivu \'\'\'$1\'\'\' on poistettu tarkkailulistaltasi.',
+'watch' => 'Tarkkaile',
+'watchthispage' => 'Tarkkaile tätä sivua',
+'unwatch' => 'Lopeta tarkkailu',
+'unwatchthispage' => 'Lopeta tarkkailu',
+'notanarticle' => 'Ei ole sivu',
+'watchnochange' => 'Valittuna ajanjaksona yhtäkään tarkkailemistasi sivuista ei muokattu.',
+'watchdetails' => 'Keskustelusivuja mukaan laskematta tarkkailun alla on $1 sivua, joista $2 on muokattu määritellyllä aikavälillä. <span class="plainlinks"> [$4 Muokkaa listaa]</span>.',
+'wlheader-enotif' => '* Sähköposti-ilmoitukset ovat käytössä.',
+'wlheader-showupdated'=> '* Sivut, joita on muokattu viimeisen käyntisi jälkeen on merkitty \'\'\'paksummalla\'\'\'',
+'watchmethod-recent' => 'tarkistetaan tuoreimpia muutoksia tarkkailluille sivuille',
+'watchmethod-list' => 'tarkistetaan tarkkailtujen sivujen tuoreimmat muutokset',
+'removechecked' => 'Poista valitut sivut tarkkailulistalta',
+'watchlistcontains' => 'Tarkkailulistallasi on $1 sivua.',
+'watcheditlist' => 'Tässä on aakkostettu lista tarkkailemistasi sivuista. Merkitse niiden sivujen ruudut, jotka haluat poistaa tarkkailulistaltasi.',
+'removingchecked' => 'Merkityt sivut poistettiin tarkkailulistalta.',
+'couldntremove' => 'Sivua $1 ei voitu poistaa tarkkailulistalta',
+'iteminvalidname' => 'Sivun $1 kanssa oli ongelmia! Sivun nimessä on vikaa.',
+'wlnote' => 'Alla on <b>$1</b> muutosta viimeisen <b>$2</b> tunnin ajalta.', // TODO NOWIKIMARKUP
+'wlshowlast' => 'Näytä viimeiset $1 tuntia tai $2 päivää$3',
+'wlsaved' => 'Tämä on tallennettu versio tarkkailulistastasi.',
+'watchlist-show-bots' => 'Näytä bottien muokkaukset',
+'watchlist-hide-bots' => 'Piilota bottien muokkaukset',
+'watchlist-show-own' => 'Näytä omat muokkaukset',
+'watchlist-hide-own' => 'Piilota omat muokkaukset',
+'watchlist-show-minor'=> 'Näytä pienet muokkaukset',
+'watchlist-hide-minor'=> 'Piilota pienet muokkaukset',
+'wldone' => 'Muutokset tehty.',
+'watching' => 'Lisätään tarkkailulistalle...',
+'unwatching' => 'Poistetaan tarkkailulistalta...',
+
+'enotif_mailer' => '{{GRAMMAR:genitive|{{SITENAME}}}} sivu on muuttunut -ilmoitus',
+'enotif_reset' => 'Merkitse kaikki sivut katsotuiksi',
+'enotif_newpagetext' => 'Tämä on uusi sivu.',
+'changed' => 'muuttanut sivua',
+'created' => 'luonut sivun',
+'enotif_subject' => '$PAGEEDITOR on $CHANGEDORCREATED $PAGETITLE',
+'enotif_lastvisited' => 'Osoitteessa $1 on kaikki muutokset viimeisen käyntisi jälkeen.',
+'enotif_body' => 'Käyttäjä $WATCHINGUSERNAME,
+
+{{GRAMMAR:genitive|{{SITENAME}}}} käyttäjä $PAGEEDITOR on $CHANGEDORCREATED $PAGETITLE $PAGEEDITDATE. Nykyinen versio on osoitteessa $PAGETITLE_URL .
+
+$NEWPAGE
+
+Muokkaajan yhteenveto: $PAGESUMMARY $PAGEMINOREDIT
+
+Ota yhteyttä muokkaajaan:
+sähköposti: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Uusia ilmoituksia tästä sivusta ei tule kunnes vierailet sivulla. Voit myös nollata ilmoitukset kaikille tarkkailemillesi sivuille tarkkailulistallasi.
+
+ {{GRAMMAR:genitive|{{SITENAME}}}} ilmoitusjärjestelmä
+
+--
+Tarkkailulistan asetuksia voit muuttaa osoitteessa:
+{{fullurl:Special:Watchlist/edit}}
+
+Palaute ja lisäapu osoitteessa:
+{{fullurl:Help:Sähköposti-ilmoitus}}',
+
+
+# Delete/protect/revert
+#
+'deletepage' => 'Poista sivu',
+'confirm' => 'Toteuta',
+'excontent' => 'sisälsi: ”$1”',
+'excontentauthor' => 'sisälsi: ”$1” (ainoa muokkaaja oli $2)',
+'exbeforeblank' => 'ennen tyhjentämistä sisälsi: ”$1”',
+'exblank' => 'oli tyhjä',
+'confirmdelete' => 'Vahvista poisto',
+'deletesub' => 'Sivun $1 poisto',
+'historywarning' => 'Varoitus: Sivulla, jonka aiot poistaa on muokkaushistoria:',
+'confirmdeletetext' => 'Olet poistamassa sivun tai tiedoston ja kaiken sen historian. Ymmärrä teon seuraukset ja tee poisto {{GRAMMAR:genitive|{{SITENAME}}}} käytäntöjen mukaisesti.',
+'actioncomplete' => 'Toiminto suoritettu',
+'deletedtext' => '\'\'\'[[Special:Undelete/$1|$1]]\'\'\' on poistettu. Katso $2 nähdäksesi listan viimeaikaisista poistoista.',
+'deletedarticle' => 'poisti sivun $1',
+'dellogpage' => 'Poistoloki',
+'dellogpagetext' => 'Alla on loki viimeisimmistä poistoista.',
+'deletionlog' => 'poistoloki',
+'reverted' => 'Palautettu aikaisempaan versioon',
+'deletecomment' => 'Poistamisen syy',
+'imagereverted' => 'Aikaisempaan versioon palauttaminen onnistui.',
+'rollback' => 'palauta aiempaan versioon',
+'rollback_short' => 'Palautus',
+'rollbacklink' => 'palauta',
+'rollbackfailed' => 'Palautus epäonnistui',
+'cantrollback' => 'Aiempaan versioon ei voi palauttaa, koska viimeisin kirjoittaja on sivun ainoa tekijä.',
+'alreadyrolled' => 'Käyttäjän [[User:$2|$2]] ([[User_talk:$2|keskustelu]]) tekemiä muutoksia sivuun $1 ei voi kumota, koska käyttäjä [[User:$3|$3]] ([[User_talk:$3|keskustelu]]) on tehnyt uudempia muutoksia.',
+'editcomment' => 'Muokkauksen yhteenveto oli: <i>$1</i>.', // TODO NOWIKIMARKUP
+'revertpage' => 'Käyttäjän [[Special:Contributions/$2|$2]] ([[User_talk:$2|keskustelu]]) muokkaukset kumottiin ja sivu palautettiin viimeisimpään käyttäjän [[User:$1|$1]] tekemään versioon.',
+
+'sessionfailure' => 'Istuntosi kanssa on ongelma. Muutosta ei toteutettu varotoimena sessionkaappauksien takia. Käytä selaimen paluutoimintoa ja päivitä sivu, jolta tulit, ja koita uudelleen.',
+'protectlogpage' => 'Suojausloki',
+'protectlogtext' => 'Alla loki sivujen suojauksista ja suojauksien poistoista.',
+'protectedarticle' => 'suojasi sivun $1',
+'unprotectedarticle' => 'poisti suojauksen sivulta $1',
+'protectsub' => 'Sivun $1 suojaus',
+'confirmprotecttext' => 'Haluatko varmasti suojata tämän sivun?',
+'confirmprotect' => 'Vahvista suojaus',
+'protectmoveonly' => 'Suojaa vain siirroilta',
+'protectcomment' => 'Suojauksen syy:',
+'unprotectsub' => 'Suojauksen poisto sivulta $1',
+'confirmunprotecttext'=> 'Haluatko varmasti poistaa tämän sivun suojauksen?',
+'confirmunprotect' => 'Vahvista suojauksen poisto',
+'unprotectcomment' => 'Syy suojauksen poistoon',
+'protect-unchain' => 'Käytä siirtosuojausta',
+'protect-text' => 'Voit katsoa ja muuttaa sivun ”<strong>$1</strong>” suojauksia:',
+'protect-viewtext' => 'Et voi muuttaa sivun ”<strong>$1</strong>” suojauksia. Alla on sivun nykyiset suojaukset:',
+'protect-default' => '(ei rajoituksia)',
+'protect-level-autoconfirmed' => 'Estä uudet ja anonyymit käyttäjät',
+'protect-level-sysop' => 'Vain ylläpitäjät',
+
+# restrictions (nouns)
+'restriction-edit' => 'muokkaus',
+'restriction-move' => 'siirto',
+
+
+# Undelete
+'undelete' => 'Palauta poistettuja sivuja',
+'undeletepage' => 'Poistettujen sivujen selaus',
+'viewdeletedpage' => 'Poistettujen sivujen selaus',
+'undeletepagetext' => 'Seuraavat sivut on poistettu, mutta ne löytyvät vielä arkistosta, joten ne ovat palautettavissa. Arkisto saatetaan tyhjentää aika ajoin.',
+'undeleteextrahelp' => 'Palauta sivu valitsemalla <b><i>Palauta</i></b>. Voit palauttaa versiota valikoivasti valitsemalla vain niiden versioiden valintalaatikot, jotka haluat palauttaa.',
+'undeletearticle' => 'Palauta poistettu sivu',
+'undeleterevisions' => '$1 versiota arkistoitu.',
+'undeletehistory' => 'Jos palautat sivun, kaikki versiot lisätään sivun historiaan. Jos uusi sivu samalla nimellä on luotu poistamisen jälkeen, palautetut versiot lisätään sen historiaan, ja olemassa olevaa versiota ei korvata automaattisesti.',
+'undeletehistorynoadmin' => 'Tämä sivu on poistettu. Syy sivun poistamiseen näkyy yhteenvedossa, jossa on myös tiedot, ketkä ovat muokanneet tätä sivua ennen poistamista. Sivujen varsinainen sisältö on vain ylläpitäjien luettavissa.',
+'undeleterevision' => 'Poistettu versio hetkellä $1',
+'undeleterevision-missing' => 'Virheellinen tai puuttuva versio. Se on saatettu palauttaa tai poistaa arkistosta.',
+'undeletebtn' => 'Palauta',
+'undeletereset' => 'Tyhjennä',
+'undeletecomment' => 'Kommentti:',
+'undeletedarticle' => 'palautti sivun [[$1]]',
+'undeletedrevisions' => '$1 versiota palautettiin',
+'undeletedrevisions-files' => '$1 versiota ja $2 tiedosto(a) palautettiin',
+'undeletedfiles' => "$1 tiedosto(a) palautettiin",
+'cannotundelete' => 'Palauttaminen epäonnistui.',
+'undeletedpage' => '<big>\'\'\'”$1” on palautettu.\'\'\'</big>
+
+[[Special:Log/delete|Poistolokista]] löydät listan viimeisimmistä poistoista ja palautuksista.',
+
+'namespace' => 'Nimiavaruus:',
+'invert' => 'Käännä nimiavaruusvalinta päinvastaiseksi',
+
+# Contributions
+#
+'contributions' => 'Käyttäjän muokkaukset',
+'mycontris' => 'Muokkaukset',
+'contribsub' => 'Käyttäjän $1 muokkaukset',
+'nocontribs' => 'Näihin ehtoihin sopivia muokkauksia ei löytynyt.',
+'ucnote' => 'Alla on \'\'\'$1\'\'\' viimeisintä tämän käyttäjän tekemää muokkausta viimeisten \'\'\'$2\'\'\' päivän aikana.',
+'uclinks' => 'Katso $1 viimeisintä muokkausta; katso $2 viimeisintä päivää.',
+'uctop' => ' (uusin)' ,
+'newbies' => 'tulokkaat',
+
+'sp-contributions-newest' => 'Uusimmat',
+'sp-contributions-oldest' => 'Vanhimmat',
+'sp-contributions-newer' => '← $1 uudempaa',
+'sp-contributions-older' => '$1 vanhempaa →',
+'sp-contributions-newbies-sub' => 'Uusien tulokkaiden muokkaukset',
+'sp-contributions-blocklog' => 'estot',
+
+# What links here
+#
+'whatlinkshere' => 'Tänne viittaavat sivut',
+'notargettitle' => 'Ei kohdetta',
+'notargettext' => 'Et ole määritellyt kohdesivua tai -käyttäjää johon toiminto kohdistuu.',
+'linklistsub' => 'Lista linkeistä',
+'linkshere' => 'Seuraavilta sivuilta on linkki sivulle <b>[[:$1]]</b>:',
+'nolinkshere' => 'Sivulle <b>[[:$1]]</b> ei ole linkkejä.',
+'isredirect' => 'uudelleenohjaussivu',
+'istemplate' => 'sisällytetty mallineeseen',
+
+# Block/unblock IP
+#
+'blockip' => 'Aseta muokkausesto',
+'blockiptext' => 'Tällä lomakkeella voit estää käyttäjän tai IP-osoitteen muokkausoikeudet. Muokkausoikeuksien poistamiseen pitää olla syy, esimerkiksi sivujen vandalisointi. Kirjoita syy siihen varattuun kenttään.<br />Vanhenemisajat noudattavat GNUn standardimuotoa, joka on kuvattu tar-manuaalissa ([http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html] [EN]), esimerkiksi ”1 hour”, ”2 days”, ”next Wednesday”, 2005-08-29”. Esto voi olla myös ”indefinite” tai ”infinite”, joka kestää kunnes se poistetaan.',
+'ipaddress' => 'IP-osoite', // TODO bug
+'ipadressorusername' => 'IP-osoite tai käyttäjätunnus',
+'ipbexpiry' => 'Umpeutuu',
+'ipbreason' => 'Syy',
+'ipbanononly' => 'Estä vain kirjautumattomat käyttäjät',
+'ipbcreateaccount' => 'Estä tunnusten luonti',
+'ipbenableautoblock' => 'Estä viimeisin IP-osoite, josta käyttäjä on muokannut, sekä ne osoitteet, joista hän jatkossa yrittää muokata.',
+'ipbsubmit' => 'Estä',
+'ipbother' => 'Vapaamuotoinen kesto',
+'ipboptions' => '2 tuntia:2 hours,1 päivä:1 day,3 päivää:3 days,1 viikko:1 week,2 viikkoa:2 weeks,1 kuukausi:1 month,3 kuukautta:3 months,6 kuukautta:6 months,1 vuosi:1 year,ikuisesti:infinite',
+'ipbotheroption' => 'Muu kesto',
+'badipaddress' => 'IP-osoite on väärin muotoiltu.',
+'blockipsuccesssub' => 'Esto onnistui',
+'blockipsuccesstext' => 'Käyttäjä tai IP-osoite \'\'\'$1\'\'\' on estetty.<br />Nykyiset estot löytyvät [[Special:Ipblocklist|estolistalta]].',
+'unblockip' => 'Muokkauseston poisto',
+'unblockiptext' => 'Tällä lomakkeella voit poistaa käyttäjän tai IP-osoitteen muokkauseston.',
+'ipusubmit' => 'Poista esto',
+'unblocked' => 'Käyttäjän [[User:$1|$1]] esto on poistettu',
+'ipblocklist' => 'Lista estetyistä IP-osoitteista',
+'ipblocklistempty' => 'Estolista on tyhjä.',
+'blocklistline' => '$1 — $2 on estänyt käyttäjän $3 ($4)',
+'infiniteblock' => 'ikuisesti',
+'expiringblock' => 'vanhenee $1',
+'anononlyblock' => 'vain kirjautumattomat',
+'noautoblockblock' => 'ei automaattista IP-osoitteiden estoa',
+'createaccountblock' => 'tunnusten luonti estetty',
+'blocklink' => 'estä',
+'unblocklink' => 'poista esto',
+'contribslink' => 'muokkaukset',
+'autoblocker' => 'Olet automaattisesti estetty, koska jaat IP-osoitteen käyttäjän $1 kanssa. Eston syy: $2.', // TODO: IS WIKIMARKUP?
+'blocklogpage' => 'Estoloki',
+'blocklogentry' => 'esti käyttäjän tai IP-osoitteen $1. Eston kesto: $2',
+'blocklogtext' => 'Tässä on loki muokkausestoista ja niiden purkamisista. Automaattisesti estettyjä IP-osoitteita ei kirjata. Tutustu [[Special:Ipblocklist|estolistaan]] nähdäksesi listan tällä hetkellä voimassa olevista estoista.',
+'unblocklogentry' => 'poisti käyttäjältä $1 muokkauseston',
+'range_block_disabled'=> 'Ylläpitäjän oikeus luoda alue-estoja ei ole käytössä.',
+'ipb_expiry_invalid' => 'Virheellinen umpeutumisaika.',
+'ip_range_invalid' => 'Virheellinen IP-alue.',
+'ipb_already_blocked' => '”$1” on jo estetty.',
+'ipb_cant_unblock' => 'Estoa ”$1” ei löytynyt. Se on saatettu poistaa.',
+'proxyblocker' => 'Välityspalvelinesto',
+'proxyblockreason' => 'IP-osoitteestasi on estetty muokkaukset, koska se on avoin välityspalvelin. Ota yhteyttä Internet-palveluntarjoajaasi tai tekniseen tukeen ja kerro heillä tästä tietoturvaongelmasta.',
+'proxyblocksuccess' => 'Valmis.',
+'sorbs' => 'SORBS-DNSBL',
+'sorbsreason' => 'IP-osoitteesti on listattu avoimena välityspalvelimena [http://www.sorbs.net SORBSin] mustalla listalla.',
+'sorbs_create_account_reason' => 'IP-osoitteesi on listattu avoimena välityspalvelimena [http://www.sorbs.net SORBSin] mustalla listalla. Et voi luoda käyttäjätunnusta.',
+
+
+# Developer tools
+#
+'lockdb' => 'Lukitse tietokanta',
+'unlockdb' => 'Vapauta tietokanta',
+'lockdbtext' => 'Tietokannan lukitseminen estää käyttäjiä muokkaamasta sivuja, vaihtamasta asetuksia, muokkaamasta tarkkailulistoja ja tekemästä muita tietokannan muuttamista vaativia toimia. Ole hyvä ja vahvista, että tämä on tarkoituksesi, ja että vapautat tietokannan kun olet suorittanut ylläpitotehtävät.',
+'unlockdbtext' => 'Tietokannan vapauttaminen antaa käyttäjille mahdollisuuden muokkata sivuja, vaihtamaa asetuksia, muokkata tarkkailulistoja ja tehdä muita tietokannan muuttamista vaativia toimia. Ole hyvä ja vahvista, että tämä on tarkoituksesi.',
+'lockconfirm' => 'Kyllä, haluan varmasti lukita tietokannan.',
+'unlockconfirm' => 'Kyllä, haluan varmasti vapauttaa tietokannan.',
+'lockbtn' => 'Lukitse tietokanta',
+'unlockbtn' => 'Vapauta tietokanta',
+'locknoconfirm' => 'Et merkinnyt vahvistuslaatikkoa.',
+'lockdbsuccesssub' => 'Tietokannan lukitseminen onnistui',
+'unlockdbsuccesssub' => 'Tietokannan vapauttaminen onnistui',
+'lockdbsuccesstext' => 'Tietokanta on lukittu.<br />Muista vapauttaa tietokanta ylläpitotoimenpiteiden jälkeen.',
+'unlockdbsuccesstext' => 'Tietokanta on vapautettu.',
+'lockfilenotwritable' => 'Tietokannan lukitustiedostoa ei voi kirjoittaa. Tarkista oikeudet.',
+'databasenotlocked' => 'Tietokanta ei ole lukittu.',
+
+
+# Make sysop
+'makesysoptitle' => 'Tee käyttäjästä ylläpitäjä',
+'makesysoptext' => 'Byrokraatit voivat tällä lomakkeella tehdä käyttäjistä ylläpitäjiä ja byrokraatteja. Kirjoita laatikkoon sen käyttäjän nimi, jolle haluat antaa oikeuksia.',
+'makesysopname' => 'Käyttäjän nimi:',
+'makesysopsubmit' => 'Tee käyttäjästä ylläpitäjä',
+'makesysopok' => 'Käyttäjä <b>$1</b> on nyt ylläpitäjä.',
+'makesysopfail' => 'Käyttäjästä <b>$1</b> ei voitu tehdä ylläpitäjää. Kirjoititko nimen oikein?', // TODO: NOWIKIMARKUP
+'setbureaucratflag' => 'Tee käyttäjästä myös byrokraatti',
+'rightslog' => 'Käyttöoikeusloki',
+'rightslogtext' => 'Alla on loki on käyttäjien käyttöoikeuksien muutoksista.',
+'rightslogentry' => 'Käyttäjän [[$1]] oikeudet muutettiin ryhmistä $2 ryhmiin $3',
+'rights' => 'Oikeudet:',
+'set_user_rights' => 'Aseta käyttäjän oikeudet',
+'user_rights_set' => 'Käyttäjän <b>$1</b> oikeudet päivitetty.',
+'set_rights_fail' => 'Käyttäjän <b>$1</b> oikeuksia ei voita asettaa. Kirjoititko nimen oikein?',
+'makesysop' => 'Tee käyttäjästä ylläpitäjä',
+'already_sysop' => 'Käyttäjä on jo ylläpitäjä',
+'already_bureaucrat' => 'Käyttäjä on jo byrokraatti',
+'rightsnone' => '(ei oikeuksia)',
+
+
+# Move page
+#
+'movepage' => 'Siirrä sivu',
+'movepagetext' => 'Alla olevalla lomakkeella voit nimetä uudelleen sivuja, jolloin niiden koko historia siirtyy uuden nimen alle. Vanhasta sivusta tulee uudelleenohjaussivu, joka osoittaa uuteen sivuun. Vanhaan sivuun suunnattuja linkkejä ei muuteta, joten muista tehdä tarkistukset kaksinkertaisten tai rikkinäisten uudellenohjausten varalta. \'\'\'Olet vastuussa siitä, että linkit osoittavat sinne, mihin niiden on tarkoituskin osoittaa.\'\'\'<br \>Huomaa, että sivua \'\'\'ei\'\'\' siirretä mikäli uusi otsikko on olemassaolevan sivun käytössä, paitsi milloin kyseessä on tyhjä sivu tai uudelleenohjaus, jolla ei ole muokkaushistoriaa. Tämä tarkoittaa sitä, että voit siirtää sivun takaisin vanhalle nimelleen mikäli teit virheen, mutta et voi kirjoittaa olemassa olevan sivun päälle. Jos sivu tarvitsee siirtää olemassa olevan sivun päälle, ota yhteyttä [[Special:Listusers/sysop|ylläpitäjään]].',
+'movepagetalktext' => 'Sivuun mahdollisesti kytketty keskustelusivu siirretään automaattisesti, \'\'\'paitsi jos\'\'\':
+*Siirrät sivua nimiavaruudesta toiseen
+*Kohdesivulla on olemassa keskustelusivu, joka ei ole tyhjä, tai
+*Kumoat alla olevan ruudun asetuksen.
+
+Näissä tapauksissa sivut täytyy siirtää tai yhdistää käsin.',
+'movearticle' => 'Siirrä sivu',
+'movenologin' => 'Et ole kirjautunut sisään',
+'movenologintext' => 'Sinun pitää olla rekisteröitynyt käyttäjä ja kirjautua sisään, jotta voisit siirtää sivun.',
+'newtitle' => 'Uusi nimi sivulle',
+'move-watch' => 'Tarkkaile tätä sivua',
+'movepagebtn' => 'Siirrä sivu',
+'pagemovedsub' => 'Siirto onnistui',
+'pagemovedtext' => 'Sivu \'\'\'[[$1]]\'\'\' siirrettiin nimelle \'\'\'[[$2]]\'\'\'.',
+'articleexists' => 'Kohdesivu on jo olemassa, tai valittu nimi ei ole sopiva. Ole hyvä ja valitse uusi nimi.',
+'talkexists' => 'Sivun siirto onnistui, mutta keskustelusivua ei voitu siirtää, koska uuden otsikon alla on jo keskustelusivu. Keskustelusivujen sisältö täytyy yhdistää käsin.',
+'movedto' => 'Siirretty uudelle otsikolle',
+'movetalk' => 'Siirrä myös keskustelusivu.',
+'talkpagemoved' => 'Myös sivun keskustelusivu siirrettiin.',
+'talkpagenotmoved' => 'Sivun keskustelusivua \'\'\'ei\'\'\' siirretty.',
+'1movedto2' => 'siirsi sivun ”$1” uudelle nimelle ”$2”',
+'1movedto2_redir' => 'siirsi sivun ”$1” uudelleenohjauksen ”$2” päälle',
+'movelogpage' => 'Siirtoloki',
+'movelogpagetext' => 'Anna on loki siirretyistä sivuista.',
+'movereason' => 'Syy',
+'revertmove' => 'kumoa',
+'delete_and_move' => 'Poista kohdesivu ja siirrä',
+'delete_and_move_text' => 'Kohdesivu [[$1]] on jo olemassa. Haluatko poistaa sen, jotta nykyinen sivu voitaisiin siirtää?',
+'delete_and_move_confirm'=> 'Poista sivu',
+'delete_and_move_reason' => 'Sivu on siirron tiellä.',
+'selfmove' => 'Lähde- ja kohdenimi ovat samat.',
+'immobile_namespace' => 'Sivuja ei voi siirtää tähän nimiavaruuteen.',
+
+# Export
+
+'export' => 'Sivujen vienti',
+'exporttext' => 'Voit viedä sivun tai sivujen tekstiä ja muokkaushistoriaa XML-muodossa. Tämä tieto voidaan tuoda johonkin toiseen wikiin, jossa käytetään MediaWiki-ohjelmistoa.<br \>Syötä sivujen otsikoita riveittäin alla olevaan laatikkoon. Valitse myös, haluatko kaikki versiot sivuista, vai ainoastaan nykyisen version.<br \>Jälkimmäisessä tapauksessa voit myös käyttää linkkiä. Esimerkiksi sivun {{Mediawiki:mainpage}} saa vietyä linkistä [[{{ns:Special}}:Export/{{Mediawiki:mainpage}}]].',
+'exportcuronly' => 'Liitä mukaan ainoastaan uusin versio, ei koko historiaa.',
+'exportnohistory' => "----\nSivujen koko historian vienti on estetty suorituskykysyistä.",
+'export-submit' => 'Vie',
+
+
+# Namespace 8 related
+
+'allmessages' => 'Järjestelmäviestit',
+'allmessagesname' => 'Nimi',
+'allmessagesdefault' => 'Oletusarvo',
+'allmessagescurrent' => 'Nykyinen arvo',
+'allmessagestext' => 'Tämä on luettelo kaikista MediaWiki-nimiavaruudessa olevista viesteistä.',
+'allmessagesnotsupportedUI' => 'Tämä sivu ei tue käyttöliittymäkieltäsi <b>$1</b> tässä MediaWikissä.',
+'allmessagesnotsupportedDB' => 'Tämä sivu ei ole käytössä, koska <tt>$wgUseDatabaseMessages</tt>-asetus on pois päältä.',
+'allmessagesfilter' => 'Viestiavainsuodatin:',
+'allmessagesmodified' => 'Näytä vain muutetut',
+
+
+# Thumbnails
+
+'thumbnail-more' => 'Suurenna',
+'missingimage' => '<b>Puuttuva kuva</b><br /><i>$1</i>',
+'filemissing' => 'Tiedosto puuttuu',
+'thumbnail_error' => 'Pienoiskuvan luominen epäonnistui: $1',
+
+# Special:Import
+'import' => 'Tuo sivuja',
+'importinterwiki' => 'Tuo sivuja lähiwikeistä',
+'import-interwiki-text' => 'Valitse wiki ja sivun nimi. Versioiden päivämäärät ja muokkaajat säilytetään. Kaikki wikienväliset tuonnit kirjataan [[Special:Log/import|tuontilokiin]].',
+'import-interwiki-history' => 'Kopioi sivun koko historia',
+'import-interwiki-submit' => 'Tuo',
+'import-interwiki-namespace' => 'Siirrä nimiavaruuteen:',
+'importtext' => 'Vie sivuja lähdewikistä käyttäen [[Special:Export|vienti]]-työkalua. Tallenna tiedot koneellesi ja tallenna ne täällä.',
+'importstart' => 'Tuodaan sivuja...',
+'import-revision-count' => '$1 {{PLURAL:$1|versio|versiota}}',
+'importnopages' => 'Ei tuotavia sivuja.',
+'importfailed' => 'Tuonti epäonnistui: $1',
+'importunknownsource' => 'Tuntematon lähdetyyppi',
+'importcantopen' => 'Tuontitiedoston avaus epäonnistui',
+'importbadinterwiki' => 'Kelpaamaton wikienvälinen linkki',
+'importnotext' => 'Tyhjä tai ei tekstiä',
+'importsuccess' => 'Tuonti onnistui!',
+'importhistoryconflict' => 'Sivusta on olemassa tuonnin kanssa ristiriitainen muokkausversio. Tämä sivu on saatettu tuoda jo aikaisemmin.',
+'importnosources' => 'Wikienvälisiä tuontilähteitä ei ole määritelty ja suorat historiatallennukset on poistettu käytöstä.',
+'importnofile' => 'Mitään tuotavaa tiedostoa ei lähetetty.',
+'importuploaderror' => 'Tiedoston lähettäminen epäonnistui. Tiedosto saattaa olla liian suuri.',
+
+# import log
+'importlogpage' => 'Tuontiloki',
+'importlogpagetext' => 'Loki toisista wikeistä tuoduista sivuista.',
+'import-logentry-upload' => 'toi sivun ”[[$1]]” lähettämällä tiedoston',
+'import-logentry-upload-detail' => '$1 versio(ta)',
+'import-logentry-interwiki' => 'toi toisesta wikistä sivun ”$1”',
+'import-logentry-interwiki-detail' => '$1 versio(ta) sivusta $2',
+
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Etsi {{GRAMMAR:elative|{{SITENAME}}}} [alt-f]',
+'tooltip-minoredit' => 'Merkitse tämä pieneksi muutokseksi [alt-i]',
+'tooltip-save' => 'Tallenna muokkaukset [alt-s]',
+'tooltip-preview' => 'Esikatsele muokkausta ennen tallennusta [alt-p]',
+'tooltip-diff' => 'Näytä tehdyt muutokset [alt-v]',
+'tooltip-compareselectedversions' => 'Vertaile valittuja versioita [alt-v]',
+'tooltip-watch' => 'Lisää tämä sivu tarkkailulistaan [alt-w]',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF-metatieto on poissa käytöstä tällä palvelimella.',
+'nocreativecommons' => 'Creative Commonsin RDF-metatieto on poissa käytöstä tällä palvelimella.',
+'notacceptable' => 'Wikipalvelin ei voi näyttää tietoja muodossa, jota ohjelmasi voisi lukea.',
+
+# Attribution
+
+'anonymous' => '{{GRAMMAR:genitive|{{SITENAME}}}} anonyymit käyttäjät',
+'siteuser' => '{{GRAMMAR:genitive|{{SITENAME}}}} käyttäjä $1',
+'lastmodifiedatby' => 'Tätä sivua muokkasi viimeksi ”$3” $2 kello $1.',
+'and' => 'ja',
+'othercontribs' => 'Perustuu työlle, jonka teki $1.',
+'others' => 'muut',
+'siteusers' => '{{GRAMMAR:genitive|{{SITENAME}}}} käyttäjä(t) $1',
+'creditspage' => 'Sivun tekijäluettelo',
+'nocredits' => 'Tämän sivun tekijäluettelotietoja ei löydy.',
+
+# Spam protection
+#
+'spamprotectiontitle' => 'Mainossuodatin',
+'spamprotectiontext' => 'Mainossuodatin on estänyt sivun tallentamisen. Syynä on todennäköisimmin {{GRAMMAR:genitive|{{SITENAME}}}} ulkopuolelle osoittava linkki.',
+'spamprotectionmatch' => 'Teksti, joka ei läpäissyt mainossuodatinta: $1',
+'subcategorycount' => 'Tällä luokalla on {{PLURAL:$1|yksi alaluokka|$1 alaluokkaa}}.',
+'categoryarticlecount'=> 'Tässä luokassa on {{PLURAL:$1|yksi sivu|$1 sivua}}.',
+'category-media-count'=> 'Tässä luokassa on {{PLURAL:$1|yksi tiedosto|$1 tiedostoa}}.',
+'listingcontinuesabbrev' => ' jatkuu',
+'spambot_username' => 'MediaWikin mainospoistaja',
+'spam_reverting' => 'Palautettu viimeisimpään versioon, joka ei sisällä linkkejä kohteeseen $1.',
+'spam_blanking' => 'Kaikki versiot sisälsivät linkkejä kohteeseen $1. Sivu tyhjennety.',
+
+
+# Info page
+'infosubtitle' => 'Tietoja sivusta',
+'numedits' => 'Sivun muokkausten määrä: $1',
+'numtalkedits' => 'Keskustelusivun muokkausten määrä: $1',
+'numwatchers' => 'Tarkkailijoiden määrä: $1',
+'numauthors' => 'Sivun erillisten kirjoittajien määrä: $1',
+'numtalkauthors' => 'Keskustelusivun erillisten kirjoittajien määrä: $1',
+
+# Math options
+'mw_math_png' => 'Näytä aina PNG:nä',
+'mw_math_simple' => 'Näytä HTML:nä, jos yksinkertainen, muuten PNG:nä',
+'mw_math_html' => 'Näytä HTML:nä, jos mahdollista, muuten PNG:nä',
+'mw_math_source' => 'Näytä TeX-muodossa (tekstiselaimille)',
+'mw_math_modern' => 'Suositus nykyselaimille',
+'mw_math_mathml' => 'Näytä MathML:nä jos mahdollista (kokeellinen)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Merkitse tarkastetuksi',
+'markaspatrolledtext' => 'Merkitse muokkaus tarkastetuksi',
+'markedaspatrolled' => 'Tarkastettu',
+'markedaspatrolledtext' => 'Valittu versio on tarkastettu.',
+'rcpatroldisabled' => 'Tuoreiden muutosten tarkastustoiminto ei ole käytössä',
+'rcpatroldisabledtext' => 'Tuoreiden muutosten tarkastustoiminto ei ole käytössä.',
+'markedaspatrollederror' => 'Muutoksen merkitseminen tarkastetuksi epäonnistui.',
+'markedaspatrollederrortext' => 'Tarkastetuksi merkittävää versiota ei ole määritelty.',
+'markedaspatrollederror-noautopatrol' => 'Et voi merkitä omia muutoksiasi tarkastetuiksi.',
+
+
+'common.css' => '/* Tämä sivu sisältää koko sivustoa muuttavia tyylejä. */',
+'monobook.css' => '/* Tämä sivu sisältää Monobook-ulkoasua muuttavia tyylejä. */',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* <pre> */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','Oma käyttäjäsivu');
+ta['pt-anonuserpage'] = new Array('.','IP-osoitteesi käyttäjäsivu');
+ta['pt-mytalk'] = new Array('n','Oma keskustelusivu');
+ta['pt-anontalk'] = new Array('n','Keskustelu tämän IP-osoitteen muokkauksista');
+ta['pt-preferences'] = new Array('','Omat asetukset');
+ta['pt-watchlist'] = new Array('l','Lista sivuista, joiden muokkauksia tarkkailet');
+ta['pt-mycontris'] = new Array('y','Lista omista muokkauksista');
+ta['pt-login'] = new Array('o','Kirjaudu sisään tai luo tunnus');
+ta['pt-anonlogin'] = new Array('o','Kirjaudu sisään tai luo tunnus');
+ta['pt-logout'] = new Array('','Kirjaudu uls');
+ta['ca-talk'] = new Array('t','Keskustele sisällöstä');
+ta['ca-edit'] = new Array('e','Muokkaa tätä sivua');
+ta['ca-addsection'] = new Array('+','Lisää kommentti tälle sivulle');
+ta['ca-viewsource'] = new Array('e','Näytä sivun lähdekoodi');
+ta['ca-history'] = new Array('h','Sivun aikaisemmat versiot');
+ta['ca-protect'] = new Array('','Suojaa tämä sivu');
+ta['ca-delete'] = new Array('d','Poista tämä sivu');
+ta['ca-undelete'] = new Array('d','Palauta tämä sivu');
+ta['ca-move'] = new Array('m','Siirrä tämä sivu');
+ta['ca-watch'] = new Array('w','Lisää tämä sivu tarkkailulistallesi');
+ta['ca-unwatch'] = new Array('w','Poista tämä sivu tarkkailulistaltasi');
+ta['search'] = new Array('f','Etsi sivu');
+ta['p-logo'] = new Array('','Etusivu');
+ta['n-mainpage'] = new Array('','Mene etusivulle');
+ta['n-portal'] = new Array('','Keskustelua projektista');
+ta['n-currentevents'] = new Array('','Taustatietoa tämänhetkisistä tapahtumista');
+ta['n-recentchanges'] = new Array('r','Lista tuoreista muutoksista');
+ta['n-randompage'] = new Array('x','Avaa satunnainen sivu');
+ta['n-help'] = new Array('','Ohjeita');
+ta['n-sitesupport'] = new Array('','Tue sivuston toimintaa');
+ta['t-whatlinkshere'] = new Array('j','Lista sivuista, jotka viittavat tänne');
+ta['t-recentchangeslinked'] = new Array('k','Viimeisimmät muokkaukset sivuissa, joille viitataan tältä sivulta');
+ta['feed-rss'] = new Array('','RSS-syöte tälle sivulle');
+ta['feed-atom'] = new Array('','Atom-syöte tälle sivulle');
+ta['t-contributions'] = new Array('','Näytä lista tämän käyttäjän muokkauksista');
+ta['t-emailuser'] = new Array('','Lähetä sähköpostia tälle käyttäjälle');
+ta['t-upload'] = new Array('u','Lisää kuvia tai muita mediatiedostoja');
+ta['t-specialpages'] = new Array('q','Näytä toimintosivut');
+ta['t-print']=new Array('', 'Lataa sivun tulostamiseen sopivalla tyylisivulla. Voit aina käyttää suoraan selaimen tulosta-toimintoa.');
+ta['t-permalink'] = new Array('', 'Ikuisesti toimiva linkki sivun tähän versioon, paitsi jos sivu poistetaan.');
+ta['ca-nstab-main'] = new Array('c','Näytä sisältösivu');
+ta['ca-nstab-user'] = new Array('c','Näytä käyttäjäsivu');
+ta['ca-nstab-media'] = new Array('c','Näytä mediasivu');
+ta['ca-nstab-special'] = new Array('','Tämä on toimintosivu');
+ta['ca-nstab-project'] = new Array('c','Näytä projektisivu');
+ta['ca-nstab-image'] = new Array('c','Näytä tiedostosivu');
+ta['ca-nstab-mediawiki'] = new Array('c','Näytä järjestelmäviesti');
+ta['ca-nstab-template'] = new Array('c','Näytä malline');
+ta['ca-nstab-help'] = new Array('c','Näytä ohjesivu');
+ta['ca-nstab-category'] = new Array('c','Näytä luokkasivu');
+/* </pre> */",
+
+'common.js' => '/* Tämän sivun koodi liitetään jokaiseen sivulataukseen */',
+
+# image deletion
+'deletedrevision' => 'Poistettiin vanha versio $1.',
+
+# browsing diffs
+'previousdiff' => '← Edellinen muutos',
+'nextdiff' => 'Seuraava muutos →',
+
+'imagemaxsize' => 'Rajoita kuvien koko kuvien kuvaussivuilla arvoon:',
+'thumbsize' => 'Pikkukuvien koko:',
+'showbigimage' => 'Lataa korkeatarkkuuksinen versio ($1×$2, $3 KiB)',
+
+'newimages' => 'Uudet kuvat',
+'showhidebots' => '($1 botit)',
+'noimages' => 'Ei uusia kuvia.',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Käyttäjä:',
+'speciallogtitlelabel'=> 'Kohde:',
+
+'passwordtooshort' => 'Salasanasi on liian lyhyt. Salasanan pitää olla vähintään $1 merkkiä pitkä.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Varoitus\'\'\': Tämä tiedosto saattaa sisältää vahingollista koodia, ja suorittamalla sen järjestelmäsi voi muuttua epäluotettavaksi.<hr />',
+
+'fileinfo' => '$1 KiB, MIME-tyyppi: <code>$2</code>',
+
+
+# Metadata
+'metadata' => 'Sisältökuvaukset',
+'metadata-help' => 'Tämä tiedosto sisältää esimerkiksi kuvanlukijan, digikameran tai kuvankäsittelyohjelman lisäämiä lisätietoja. Kaikki tiedot eivät enää välttämättä vastaa todellisuutta, jos kuvaa on muokattu sen alkuperäisen luonnin jälkeen.
+
+This file contains additional information, probably added from the digital camera or scanner used to create or digitize it. If the file has been modified from its original state, some details may not fully reflect the modified image.',
+'metadata-expand' => 'Näytä kaikki sisältökuvakset',
+'metadata-collapse' => 'Näytä vain tärkeimmät sisältökuvaukset',
+'metadata-fields' => 'Seuraavat kentät ovat esillä kuvasivulla, kun sisältötietotaulukko on pienennettynä.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+
+# Exif tags
+'exif-imagewidth' =>'Leveys',
+'exif-imagelength' =>'Korkeus',
+'exif-bitspersample' =>'Bittiä komponentissa',
+'exif-compression' =>'Pakkaustapa',
+'exif-photometricinterpretation' =>'Kuvapisteen koostumus',
+'exif-orientation' =>'Suunta',
+'exif-samplesperpixel' =>'Komponenttien lukumäärä',
+'exif-planarconfiguration' =>'Tiedon järjestely',
+'exif-ycbcrsubsampling' =>'Y:n ja C:n alinäytteistyssuhde',
+'exif-ycbcrpositioning' =>'Y:n ja C:n asemointi',
+'exif-xresolution' =>'Kuvan resoluutio leveyssuunnassa',
+'exif-yresolution' =>'Kuvan resoluutio korkeussuunnassa',
+'exif-resolutionunit' =>'Resoluution yksikkö X- ja Y-suunnassa',
+'exif-stripoffsets' =>'Kuvatiedon sijainti',
+'exif-rowsperstrip' =>'Kaistan rivien lukumäärä',
+'exif-stripbytecounts'=>'Tavua pakatussa kaistassa',
+'exif-jpeginterchangeformat' =>'Etäisyys JPEG SOI:hin',
+'exif-jpeginterchangeformatlength' =>'JPEG-tiedon tavujen lukumäärä',
+'exif-transferfunction' =>'Siirtofunktio',
+'exif-whitepoint' =>'Valkoisen pisteen väriarvot',
+'exif-primarychromaticities' =>'Päävärien väriarvot',
+'exif-ycbcrcoefficients' =>'Väriavaruuden muuntomatriisin kertoimet',
+'exif-referenceblackwhite' =>'Musta-valkoparin vertailuarvot',
+'exif-datetime' =>'Viimeksi muokattu',
+'exif-imagedescription' =>'Kuvan nimi',
+'exif-make' =>'Kameran valmistaja',
+'exif-model' =>'Kameran malli',
+'exif-software' =>'Käytetty ohjelmisto',
+'exif-artist' =>'Tekijä',
+'exif-copyright' =>'Tekijänoikeuden omistaja',
+'exif-exifversion' =>'Exif-versio',
+'exif-flashpixversion'=>'Tuettu Flashpix-versio',
+'exif-colorspace' =>'Väriavaruus',
+'exif-componentsconfiguration' =>'Kunkin komponentin määritelmä',
+'exif-compressedbitsperpixel' =>'Kuvan pakkaustapa',
+'exif-pixelydimension' =>'Käyttökelpoinen kuvan leveys',
+'exif-pixelxdimension' =>'Käyttökelpoinen kuvan korkeus',
+'exif-makernote' =>'Valmistajan merkinnät',
+'exif-usercomment' =>'Käyttäjän kommentit',
+'exif-relatedsoundfile' =>'Liitetty äänitiedosto',
+'exif-datetimeoriginal' =>'Luontipäivämäärä',
+'exif-datetimedigitized' =>'Digitointipäivämäärä',
+'exif-subsectime' =>'Aikaleiman sekunninosat',
+'exif-subsectimeoriginal' =>'Luontiaikaleiman sekunninosat',
+'exif-subsectimedigitized' =>'Digitointiaikaleiman sekunninosat',
+'exif-exposuretime' =>'Valotusaika',
+'exif-exposuretime-format' => '$1 s ($2)',
+'exif-fnumber' =>'Aukkosuhde',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'Valotusohjelma',
+'exif-spectralsensitivity' =>'Värikirjoherkkyys',
+'exif-isospeedratings' =>'Herkkyys (ISO)',
+'exif-oecf' =>'Optoelektroninen muuntokerroin',
+'exif-shutterspeedvalue' =>'Suljinaika',
+'exif-aperturevalue' =>'Aukko',
+'exif-brightnessvalue' =>'Kirkkaus',
+'exif-exposurebiasvalue' =>'Valotuksen korjaus',
+'exif-maxaperturevalue' =>'Suurin aukko',
+'exif-subjectdistance' =>'Kohteen etäisyys',
+'exif-meteringmode' =>'Mittaustapa',
+'exif-lightsource' =>'Valolähde',
+'exif-flash' =>'Salama',
+'exif-focallength' =>'Linssin polttoväli',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' =>'Kohteen ala',
+'exif-flashenergy' =>'Salaman teho',
+'exif-spatialfrequencyresponse'=>'Tilataajuusvaste',
+'exif-focalplanexresolution' =>'Tarkennustason X-resoluutio',
+'exif-focalplaneyresolution' =>'Tarkennustason Y-resoluutio',
+'exif-focalplaneresolutionunit'=>'Tarkennustason resoluution yksikkö',
+'exif-subjectlocation'=>'Kohteen sijainti',
+'exif-exposureindex' =>'Valotusindeksi',
+'exif-sensingmethod' =>'Mittausmenetelmä',
+'exif-filesource' =>'Tiedostolähde',
+'exif-scenetype' =>'Kuvatyyppi',
+'exif-cfapattern' =>'CFA-kuvio',
+'exif-customrendered' =>'Muokattu kuvankäsittely',
+'exif-exposuremode' =>'Valotustapa',
+'exif-whitebalance' =>'Valkotasapaino',
+'exif-digitalzoomratio' =>'Digitaalinen suurennoskerroin',
+'exif-focallengthin35mmfilm' =>'35 mm:n filmiä vastaava polttoväli',
+'exif-scenecapturetype' =>'Kuvan kaappaustapa',
+'exif-gaincontrol' =>'Kuvasäätö',
+'exif-contrast' =>'Kontrasti',
+'exif-saturation' =>'Värikylläisyys',
+'exif-sharpness' =>'Terävyys',
+'exif-devicesettingdescription' =>'Laitteen asetuskuvaus',
+'exif-subjectdistancerange' =>'Kohteen etäisyysväli',
+'exif-imageuniqueid' =>'Kuvan yksilöivä tunniste',
+'exif-gpsversionid' =>'GPS-muotoilukoodin versio',
+'exif-gpslatituderef' =>'Pohjoinen tai eteläinen leveysaste',
+'exif-gpslatitude' =>'Leveysaste',
+'exif-gpslongituderef'=>'Itäinen tai läntinen pituusaste',
+'exif-gpslongitude' =>'Pituusaste',
+'exif-gpsaltituderef' =>'Korkeuden vertailukohta',
+'exif-gpsaltitude' =>'Korkeus',
+'exif-gpstimestamp' =>'GPS-aika (atomikello)',
+'exif-gpssatellites' =>'Mittaukseen käytetyt satelliitit',
+'exif-gpsstatus' =>'Vastaanottimen tila',
+'exif-gpsmeasuremode' =>'Mittaustila',
+'exif-gpsdop' =>'Mittatarkkuus',
+'exif-gpsspeedref' =>'Nopeuden yksikkö',
+'exif-gpsspeed' =>'GPS-vastaanottimen nopeus',
+'exif-gpstrackref' =>'Liikesuunnan vertailukohta',
+'exif-gpstrack' =>'Liikesuunta',
+'exif-gpsimgdirectionref' =>'Kuvan suunnan vertailukohta',
+'exif-gpsimgdirection' =>'Kuvan suunta',
+'exif-gpsmapdatum' =>'Käytetty geodeettinen maanmittaustieto',
+'exif-gpsdestlatituderef' =>'Loppupisteen leveysasteen vertailukohta',
+'exif-gpsdestlatitude' =>'Loppupisteen leveysaste',
+'exif-gpsdestlongituderef'=>'Loppupisteen pituusasteen vertailukohta',
+'exif-gpsdestlongitude' =>'Loppupisteen pituusaste',
+'exif-gpsdestbearingref' =>'Loppupisteen suuntiman vertailukohta',
+'exif-gpsdestbearing' =>'Loppupisteen suuntima',
+'exif-gpsdestdistanceref' =>'Loppupisteen etäisyyden vertailukohta',
+'exif-gpsdestdistance' =>'Loppupisteen etäisyys',
+'exif-gpsprocessingmethod'=>'GPS-käsittelymenetelmän nimi',
+'exif-gpsareainformation' =>'GPS-alueen nimi',
+'exif-gpsdatestamp' =>'GPS-päivämäärä',
+'exif-gpsdifferential' =>'GPS-differentiaalikorjaus',
+
+# Exif attributes
+
+'exif-compression-1' => 'Pakkaamaton',
+'exif-compression-6' => 'JPEG',
+
+'exif-unknowndate' => 'Tuntematon päiväys',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normaali', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Käännetty vaakasuunnassa', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Käännetty 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Käännetty pystysuunnassa', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Käännetty 90° vastapäivään ja pystysuunnassa', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Käännetty 90° myötäpäivään', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Käännetty 90° myötäpäivään ja pystysuunnassa', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Käännetty 90° vastapäivään', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'chunky format',
+'exif-planarconfiguration-2' => 'planar format',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'ei ole',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Ei määritelty',
+'exif-exposureprogram-1' => 'Käsinsäädetty',
+'exif-exposureprogram-2' => 'Perusohjelma',
+'exif-exposureprogram-3' => 'Aukon etuoikeus',
+'exif-exposureprogram-4' => 'Suljinajan etuoikeus',
+'exif-exposureprogram-5' => 'Luova ohjelma (painotettu syvyysterävyyttä)',
+'exif-exposureprogram-6' => 'Toimintaohjelma (painotettu nopeaa suljinaikaa)',
+'exif-exposureprogram-7' => 'Muotokuvatila (lähikuviin, joissa tausta on epätarkka)',
+'exif-exposureprogram-8' => 'Maisematila (maisemakuviin, joissa tausta on tarkka)',
+
+'exif-subjectdistance-value' => '$1 metriä',
+
+'exif-meteringmode-0' => 'Tuntematon',
+'exif-meteringmode-1' => 'Keskiarvo',
+'exif-meteringmode-2' => 'Keskustapainotteinen keskiarvo',
+'exif-meteringmode-3' => 'Piste',
+'exif-meteringmode-4' => 'Monipiste',
+'exif-meteringmode-5' => 'Kuvio',
+'exif-meteringmode-6' => 'Osittainen',
+'exif-meteringmode-255' => 'Muu',
+
+'exif-lightsource-0' => 'Tuntematon',
+'exif-lightsource-1' => 'Päivänvalo',
+'exif-lightsource-2' => 'Loisteputki',
+'exif-lightsource-3' => 'Hehkulamppu (keinovalo)',
+'exif-lightsource-4' => 'Salama',
+'exif-lightsource-9' => 'Hyvä sää',
+'exif-lightsource-10' => 'Pilvinen sää',
+'exif-lightsource-11' => 'Varjoinen',
+'exif-lightsource-12' => 'Päivänvaloloisteputki (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Päivänvalkoinen loisteputki (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Kylmä valkoinen loisteputki (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Valkoinen loisteputki (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Oletusvalo A',
+'exif-lightsource-18' => 'Oletusvalo B',
+'exif-lightsource-19' => 'Oletusvalo C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO-studiohehkulamppu',
+'exif-lightsource-255'=> 'Muu valonlähde',
+
+'exif-focalplaneresolutionunit-2' => 'tuumaa',
+
+'exif-sensingmethod-1' => 'Määrittelemätön',
+'exif-sensingmethod-2' => 'Yksisiruinen värikenno',
+'exif-sensingmethod-3' => 'Kaksisiruinen värikenno',
+'exif-sensingmethod-4' => 'Kolmisiruinen värikenno',
+'exif-sensingmethod-5' => 'Sarjavärikenno',
+'exif-sensingmethod-7' => 'Trilineaarikenno',
+'exif-sensingmethod-8' => 'Sarjalineaarivärikenno',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'Suoraan valokuvattu kuva',
+
+'exif-customrendered-0' => 'Normaali käsittely',
+'exif-customrendered-1' => 'Muokattu käsittely',
+
+'exif-exposuremode-0' => 'Automaattinen valotus',
+'exif-exposuremode-1' => 'Käsinsäädetty valotus',
+'exif-exposuremode-2' => 'Automaattinen haarukointi',
+
+'exif-whitebalance-0' => 'Automaattinen valkotasapaino',
+'exif-whitebalance-1' => 'Käsinsäädetty valkotasapaino',
+
+'exif-scenecapturetype-0' => 'Perus',
+'exif-scenecapturetype-1' => 'Maisema',
+'exif-scenecapturetype-2' => 'Henkilökuva',
+'exif-scenecapturetype-3' => 'Yökuva',
+
+'exif-gaincontrol-0' => 'Ei ole',
+'exif-gaincontrol-1' => 'Matala ylävahvisus',
+'exif-gaincontrol-2' => 'Korkea ylävahvistus',
+'exif-gaincontrol-3' => 'Matala alavahvistus',
+'exif-gaincontrol-4' => 'Korkea alavahvistus',
+
+'exif-contrast-0' => 'Normaali',
+'exif-contrast-1' => 'Pehmeä',
+'exif-contrast-2' => 'Kova',
+
+'exif-saturation-0' => 'Normaali',
+'exif-saturation-1' => 'Alhainen värikylläisyys',
+'exif-saturation-2' => 'Korkea värikylläisyys',
+
+'exif-sharpness-0' => 'Normaali',
+'exif-sharpness-1' => 'Pehmeä',
+'exif-sharpness-2' => 'Kova',
+'exif-subjectdistancerange-0' => 'Tuntematon',
+'exif-subjectdistancerange-1' => 'Makro',
+'exif-subjectdistancerange-2' => 'Lähikuva',
+'exif-subjectdistancerange-3' => 'Kaukokuva',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Pohjoista leveyttä',
+'exif-gpslatitude-s' => 'Eteläistä leveyttä',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Itäistä pituutta',
+'exif-gpslongitude-w' => 'Läntistä pituutta',
+
+'exif-gpsstatus-a' => 'Mittaus käynnissä',
+'exif-gpsstatus-v' => 'Ristiinmittaus',
+
+'exif-gpsmeasuremode-2' => '2-ulotteinen mittaus',
+'exif-gpsmeasuremode-3' => '3-ulotteinen mittaus',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'km/h',
+'exif-gpsspeed-m' => 'mailia tunnissa',
+'exif-gpsspeed-n' => 'solmua',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Todellinen suunta',
+'exif-gpsdirection-m' => 'Magneettinen suunta',
+
+# external editor support
+'edit-externally' => 'Muokkaa tätä tiedostoa ulkoisessa sovelluksessa',
+'edit-externally-help'=> 'Katso [http://meta.wikimedia.org/wiki/Help:External_editors ohjeet], jos haluat lisätietoja.',
+
+'recentchangesall' => "kaikki", // unsure
+'imagelistall' => "kaikki", // unsure
+'watchlistall1' => 'kaikkia',
+'watchlistall2' => ', koko historia',
+'namespacesall' => 'kaikki',
+
+# E-mail address confirmation
+'confirmemail' => 'Varmenna sähköpostiosoite',
+'confirmemail_noemail'=> 'Sinulla ei ole kelvollista sähköpostiosoitetta [[Special:Preferences|asetuksissasi]].',
+'confirmemail_text' => 'Tämä wiki vaatii sähköpostiosoitteen varmentamisen, ennen kuin voit käyttää sähköpostitoimintoja. Lähetä alla olevasta painikkeesta varmennusviesti osoitteeseesi. Viesti sisältää linkin, jonka avaamalla varmennat sähköpostiosoitteesi.',
+'confirmemail_pending'=> '<div class="error">Varmennusviesti on jo lähetetty. Jos loit tunnuksen äskettäin, odota muutama minuutti viestin saapumista, ennen kuin yrität uudelleen.</div>',
+'confirmemail_send' => 'Lähetä varmennusviesti',
+'confirmemail_sent' => 'Varmennusviesti lähetetty.',
+'confirmemail_oncreate' => 'Varmennusviesti lähetettiin sähköpostiosoitteeseesi. Varmennuskoodia ei tarvita sisäänkirjautumiseen, mutta se täytyy antaa, ennen kuin voit käyttää sähköpostitoimintoja tässä wikissä.',
+'confirmemail_sendfailed' => 'Varmennusviestin lähettäminen epäonnistui. Tarkista, onko osoitteessa kiellettyjä merkkejä.
+
+Postitusohjelma palautti: $1',
+'confirmemail_invalid' => 'Varmennuskoodi ei kelpaa. Koodi on voinut vanhentua.',
+'confirmemail_needlogin' => 'Sinun täytyy $1, jotta voisit varmistaa sähköpostiosoitteesi.',
+'confirmemail_success' => 'Sähköpostiosoitteesi on nyt varmennettu. Voit kirjautua sisään.',
+'confirmemail_loggedin' => 'Sähköpostiosoitteesi on nyt varmennettu.',
+'confirmemail_error' => 'Jokin epäonnistui varmennnuksen tallentamisessa.',
+'confirmemail_subject'=> '{{GRAMMAR:genitive|{{SITENAME}}}} sähköpostiosoitteen varmennus',
+'confirmemail_body' => 'Joku IP-osoitteesta $1 on rekisteröinyt {{GRAMMAR:inessive|{{SITENAME}}}} tunnuksen $2 tällä sähköpostiosoitteella.
+
+Varmenna, että tämä tunnus kuuluu sinulle avamaalla seuraava linkki selaimellasi:
+
+$3
+
+Jos tämä tunnus ei ole sinun, ÄLÄ seuraa linkkiä. Varmennuskoodi vanhenee $4.',
+
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Koita tarkkaa osumaa',
+'searchfulltext' => 'Etsi koko tekstiä',
+'createarticle' => 'Luo sivu',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Wikienvälinen sisällytys ei ole käytössä]',
+'scarytranscludefailed' => '[Mallineen hakeminen epäonnistui: $1]', // kauhee?
+'scarytranscludetoolong' => '[Verkko-osoite on liian pitkä]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">Artikkelin trackbackit:<br />$1</div>',
+'trackbackremove' => ' ([$1 poista])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'Trackback poistettiin.',
+
+# delete conflict
+
+'deletedwhileediting' => '<center>\'\'\'Varoitus\'\'\': Tämä sivu on poistettu sen jälkeen, kun aloitit sen muokkaamisen!</center>',
+'confirmrecreate' => 'Käyttäjä \'\'\'[[User:$1|$1]]\'\'\' ([[User_talk:$1|keskustelu]]) poisti sivun sen jälkeen, kun aloit muokata sitä. Syy oli:
+: \'\'$2\'\'
+Ole hyvä ja varmista, että haluat luoda sivun uudelleen.',
+'recreate' => 'Luo uudelleen',
+'tooltip-recreate' => 'Luo sivu uudelleen',
+
+'unit-pixel' => ' px',
+
+# HTML dump
+'redirectingto' => 'Uudelleenohjataan sivulle [[$1]]...',
+
+# action=purge
+'confirm_purge' => "Poistetaanko tämän sivun välimuistikopiot?\n\n$1",
+'confirm_purge_button'=> 'Poista',
+
+'youhavenewmessagesmulti' => 'Sinulla on uusia viestejä sivuilla $1',
+
+'searchcontaining' => 'Etsi artikkeleita, jotka sisältävät ”$1”.',
+'searchnamed' => 'Etsi artikkeleita, joiden nimi on ”$1”.',
+'articletitles' => 'Artikkelit, jotka alkavat merkkijonolla ”$1”',
+'hideresults' => 'Piilota tulokset',
+
+# DISPLAYTITLE
+'displaytitle' => '(Linkitä tämä sivu merkinnällä [[$1]])',
+
+'loginlanguagelabel' => 'Kieli: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '← edellinen sivu',
+'imgmultipagenext' => 'seuraava sivu →',
+'imgmultigo' => 'Mene!',
+'imgmultigotopre' => 'Mene sivulle',
+
+# Table pager
+'ascending_abbrev' => 'nouseva',
+'descending_abbrev' => 'laskeva',
+'table_pager_next' => 'Seuraava sivu',
+'table_pager_prev' => 'Edellinen sivu',
+'table_pager_first' => 'Ensimmäinen sivu',
+'table_pager_last' => 'Viimeinen sivu',
+'table_pager_limit' => 'Näytä $1 nimikettä sivulla',
+'table_pager_limit_submit' => 'Mene',
+'table_pager_empty' => 'Ei tuloksia',
+
+# Auto-summaries
+'autosumm-blank' => 'Ak: Sivu tyhjennettin',
+'autosumm-replace' => 'Ak: Sivun sisältö korvattiin sisällöllä ”$1”',
+'autoredircomment' => 'Ak: Uudelleenohjaus sivulle [[$1]]',
+'autosumm-new' => 'Ak: Uusi sivu: $1',
+
+# Page history in an feed (RSS / Atom)
+'feed-invalid' => 'Virheellinen syötetyyppi.',
+'history-feed-title' => 'Muutoshistoria',
+'history-feed-description' => 'Tämän sivun muutoshistoria',
+'history-feed-item-nocomment' => '$1 ($2)',
+'history-feed-empty' => 'Pyydettyä sivua ei ole olemassa.
+Se on saatettu poistaa wikistä tai nimetä uudelleen.
+Kokeile [[Special:Search|hakua]] löytääksesi asiaan liittyviä sivuja.',
+
+'sp-newimages-showfrom' => 'Näytä uudet kuvat alkaen $1',
+
+# Size units
+'size-bytes' => '$1 B',
+'size-kilobytes' => '$1 KiB',
+'size-megabytes' => '$1 MiB',
+'size-gigabytes' => '$1 GiB',
+
+
+);
+?>
diff --git a/languages/messages/MessagesFo.php b/languages/messages/MessagesFo.php
new file mode 100644
index 000000000000..ad7946488dc4
--- /dev/null
+++ b/languages/messages/MessagesFo.php
@@ -0,0 +1,116 @@
+<?php
+/** Faroese (Føroyskt)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Eingin', 'Fast vinstru', 'Fast høgru', 'Flótandi vinstru'
+);
+
+$skinNames = array(
+ 'Standardur', 'Nostalgiskur', 'Cologne-bláur', 'Paddington', 'Montparnasse'
+);
+
+$bookstoreList = array(
+ 'Bokasolan.fo' => 'http://www.bokasolan.fo/vleitari.asp?haattur=bok.alfa&Heiti=&Hovindur=&Forlag=&innbinding=Oell&bolkur=Allir&prisur=Allir&Aarstal=Oell&mal=Oell&status=Oell&ISBN=$1',
+ 'inherit' => true,
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Miðil',
+ NS_SPECIAL => 'Serstakur',
+ NS_MAIN => '',
+ NS_TALK => 'Kjak',
+ NS_USER => 'Brúkari',
+ NS_USER_TALK => 'Brúkari_kjak',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_kjak',
+ NS_IMAGE => 'Mynd',
+ NS_IMAGE_TALK => 'Mynd_kjak',
+ NS_MEDIAWIKI => 'MidiaWiki',
+ NS_MEDIAWIKI_TALK => 'MidiaWiki_kjak',
+ NS_TEMPLATE => 'Fyrimynd',
+ NS_TEMPLATE_TALK => 'Fyrimynd_kjak',
+ NS_HELP => 'Hjálp',
+ NS_HELP_TALK => 'Hjálp_kjak',
+ NS_CATEGORY => 'Bólkur',
+ NS_CATEGORY_TALK => 'Bólkur_kjak'
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. M Y',
+ 'dmy both' => 'j. M Y "kl." H:i',
+);
+
+$linkTrail = '/^([áðíóúýæøa-z]+)(.*)$/sDu';
+
+$messages = array(
+
+# User toggles
+"tog-underline" => "Undurstrika ávísingar",
+"tog-highlightbroken" => "Brúka reyða ávísing til tómar síður",
+"tog-justify" => "Stilla greinpart",
+"tog-hideminor" => "Goym minni broytingar í seinast broytt listanum", # Skjul mindre ændringer i seneste ændringer listen
+"tog-usenewrc" => "víðka seinastu broytingar lista<br />(ikki til alla kagarar)",
+"tog-numberheadings" => "Sjálvtalmerking av yvirskrift",
+"tog-showtoolbar" => "Vís amboðslinju í rætting",
+"tog-editondblclick" => "Rætta síðu við at tvíklikkja (JavaScript)",
+"tog-editsection" =>"Rætta greinpart við hjálp av [rætta]-ávísing",
+"tog-editsectiononrightclick"=>"Rætta greinpart við at høgraklikkja<br /> á yvirskrift av greinparti (JavaScript)",
+"tog-showtoc"=>"Vís innihaldsyvurlit<br />(Til greinir við meira enn trimun greinpartum)",
+"tog-rememberpassword" => "Minst til loyniorð næstu ferð",
+"tog-editwidth" => "Rættingarkassin hevur fulla breid",
+"tog-watchdefault" => "Vaka yvur nýggjum og broyttum greinum",
+"tog-minordefault" => "Merk sum standard allar broytingar sum smærri",
+"tog-previewontop" => "Vís forhondsvísning áðren rættingarkassan",
+"tog-nocache" => "Minst ikki til síðurnar til næstu ferð",
+
+# Dates
+'sunday' => 'sunnudagur',
+'monday' => 'mánadagur',
+'tuesday' => 'týsdagur',
+'wednesday' => 'mikudagur',
+'thursday' => 'hósdagur',
+'friday' => 'fríggjadagur',
+'saturday' => 'leygardagur',
+'january' => 'januar',
+'february' => 'februar',
+'march' => 'mars',
+'april' => 'apríl',
+'may_long' => 'mai',
+'june' => 'juni',
+'july' => 'juli',
+'august' => 'august',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'desember',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'des',
+
+# Math options
+'mw_math_png' => "Vís altíð sum PNG",
+'mw_math_simple' => "HTML um sera einfalt annars PNG",
+'mw_math_html' => "HTML um møguligt annars PNG",
+'mw_math_source' => "Lat verða sum TeX (til tekstkagara)",
+'mw_math_modern' => "Tilmælt nýtíðarkagara",
+'mw_math_mathml' => 'MathML if possible (experimental)',
+
+);
+
+?>
diff --git a/languages/messages/MessagesFr.php b/languages/messages/MessagesFr.php
new file mode 100644
index 000000000000..c5754f06c0f6
--- /dev/null
+++ b/languages/messages/MessagesFr.php
@@ -0,0 +1,1540 @@
+<?php
+/** French (Français)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+$quickbarSettings = array(
+ 'Aucune', 'Gauche', 'Droite', 'Flottante à gauche'
+);
+
+$skinNames = array(
+ 'standard' => 'Standard',
+ 'nostalgia' => 'Nostalgie',
+);
+
+$bookstoreList = array(
+ 'Amazon.fr' => 'http://www.amazon.fr/exec/obidos/ISBN=$1',
+ 'alapage.fr' => 'http://www.alapage.com/mx/?tp=F&type=101&l_isbn=$1&donnee_appel=ALASQ&devise=&',
+ 'fnac.com' => 'http://www3.fnac.com/advanced/book.do?isbn=$1',
+ 'chapitre.com' => 'http://www.chapitre.com/frame_rec.asp?isbn=$1',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Discuter',
+ NS_USER => 'Utilisateur',
+ NS_USER_TALK => 'Discussion_Utilisateur',
+ NS_PROJECT => '$1',
+ NS_PROJECT_TALK => 'Discussion_$1',
+ NS_IMAGE => 'Image',
+ NS_IMAGE_TALK => 'Discussion_Image',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discussion_MediaWiki',
+ NS_TEMPLATE => 'Modèle',
+ NS_TEMPLATE_TALK => 'Discussion_Modèle',
+ NS_HELP => 'Aide',
+ NS_HELP_TALK => 'Discussion_Aide',
+ NS_CATEGORY => 'Catégorie',
+ NS_CATEGORY_TALK => 'Discussion_Catégorie'
+);
+$linkTrail = '/^([a-zàâçéèêîôûäëïöüùÇÉÂÊÎÔÛÄËÏÖÜÀÈÙ]+)(.*)$/sDu';
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'F j, Y',
+ 'mdy both' => 'F j, Y à H:i',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F Y',
+ 'dmy both' => 'j F Y à H:i',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y F j',
+ 'ymd both' => 'Y F j à H:i',
+);
+
+$separatorTransformTable = array( ',' => "\xc2\xa0", '.' => ',' );
+
+$messages = array(
+
+# User preference Toggles
+
+'tog-underline' => 'Liens soulignés',
+'tog-highlightbroken' => 'Liens vers les sujets non existants en rouge',
+'tog-justify' => 'Paragraphes justifiés',
+'tog-hideminor' => 'Cacher les <i>Modifications récentes</i> mineures',
+'tog-extendwatchlist' => 'Liste de suivi améliorée',
+'tog-usenewrc' => 'Modifications récentes améliorées<br /> (certains navigateurs seulement)',
+'tog-numberheadings' => 'Numérotation automatique des titres',
+'tog-showtoolbar' => 'Montrer la barre de menu de modification',
+'tog-editondblclick' => 'Double-cliquer pour modifier une page (nécessite JavaScript)',
+'tog-editsection' => 'Modifier une section via les liens [modifier]',
+'tog-editsectiononrightclick' => 'Modifier une section en cliquant à droite<br /> sur le titre de la section',
+'tog-showtoc' => 'Afficher la table des matières<br /> (pour les articles ayant plus de 3 sections)',
+'tog-rememberpassword' => 'Se souvenir de mon mot de passe (cookie)',
+'tog-editwidth' => 'La fenêtre de modification s’affiche en pleine largeur',
+'tog-watchcreations' => 'Ajouter les pages que vous créez à votre liste de suivi',
+'tog-watchdefault' => 'Ajouter les pages que vous modifiez à votre liste de suivi',
+'tog-minordefault' => 'Mes modifications sont considérées<br /> comme mineures par défaut',
+'tog-previewontop' => 'Montrer la prévisualisation au-dessus de la zone de modification',
+'tog-previewonfirst' => 'Montrer la prévisualisation lors de la première sauvegarde',
+'tog-nocache' => 'Désactiver le cache des pages',
+'tog-enotifwatchlistpages' => 'Avertissez-moi par courriel en cas de modification de la page',
+'tog-enotifusertalkpages' => 'Avertissez-moi par courriel en cas de modification de ma page de discussion',
+'tog-enotifminoredits' => 'Avertissez-moi par courriel même en cas de modification mineure',
+'tog-enotifrevealaddr' => 'Affichez mon adresse électronique dans les courriels d’avertissement',
+'tog-shownumberswatching' => 'Afficher le nombre d’utilisateurs qui suivent cette page',
+'tog-fancysig' => 'Signature brute (sans lien automatique)',
+'tog-externaleditor' => 'Utiliser un éditeur externe par défaut',
+'tog-externaldiff' => 'Utiliser un comparateur externe par défaut',
+'tog-showjumplinks' => 'Activer les liens d’accessibilité rapide.',
+'tog-uselivepreview' => 'Utiliser l’aperçu rapide (JavaScript) (Expérimental)',
+'tog-forceeditsummary' => 'M’avertir lorsque je n’ai pas completé le contenu de la boîte de commentaires',
+'tog-watchlisthideown' => 'Cacher mes propres modifications dans la liste de suivi',
+'tog-watchlisthidebots' => 'Cacher dans la liste de suivi les modifications faites par les bots',
+
+'underline-always' => 'Toujours',
+'underline-never' => 'Jamais',
+'underline-default' => 'Par défaut',
+
+'skinpreview' => '(Prévisualisation)',
+
+# Dates
+
+'sunday' => 'dimanche',
+'monday' => 'lundi',
+'tuesday' => 'mardi',
+'wednesday' => 'mercredi',
+'thursday' => 'jeudi',
+'friday' => 'vendredi',
+'saturday' => 'samedi',
+'january' => 'janvier',
+'february' => 'février',
+'march' => 'mars',
+'april' => 'avril',
+'may_long' => 'mai',
+'june' => 'juin',
+'july' => 'juillet',
+'august' => 'août',
+'september' => 'septembre',
+'october' => 'octobre',
+'november' => 'novembre',
+'december' => 'décembre',
+'jan' => 'jan',
+'feb' => 'fév',
+'mar' => 'mar',
+'apr' => 'avr',
+'may' => 'mai',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aoû',
+'sep' => 'sep',
+'oct' => 'oct',
+'nov' => 'nov',
+'dec' => 'déc',
+
+
+# Bits of text used by many pages:
+
+'categories' => 'Catégories',
+'pagecategories' => '{{PLURAL:$1|Catégorie|Catégories}}',
+'category_header' => 'Articles dans la catégorie « $1 ».',
+'subcategories' => 'Sous-catégories',
+
+'mainpage' => 'Accueil',
+'mainpagetext' => '<big>\'\'\'MediaWiki a été installé avec succès.\'\'\'</big>',
+'mainpagedocfooter' => 'Consultez le [http://meta.wikimedia.org/wiki/Aide:Contenu Guide de l’utilisateur] pour plus d’informations sur l’utilisation de ce logiciel.',
+'portal' => 'Communauté',
+'portal-url' => '{{ns:4}}:Accueil',
+'about' => 'À propos',
+'aboutsite' => 'À propos de {{SITENAME}}',
+'aboutpage' => '{{ns:4}}:À propos',
+'article' => 'Article',
+'help' => 'Aide',
+'helppage' => '{{ns:help}}:Aide',
+'bugreports' => 'Rapport d’erreurs',
+'bugreportspage' => '{{ns:4}}:Rapport d’erreurs',
+'sitesupport' => 'Faire un don',
+'sitesupport-url' => 'Project:D',
+'faqpage' => '{{ns:4}}:FAQ',
+'edithelp' => 'Aide',
+'newwindow' => '(s’ouvre dans une nouvelle fenêtre)',
+'edithelppage' => '{{ns:help}}:Comment modifier une page',
+'cancel' => 'Annuler',
+'qbfind' => 'Rechercher',
+'qbbrowse' => 'Défiler',
+'qbedit' => 'Modifier',
+'qbpageoptions' => 'Page d’option',
+'qbpageinfo' => 'Page d’information',
+'qbmyoptions' => 'Mes options',
+'qbspecialpages'=> 'Pages spéciales',
+'moredotdotdot' => 'Et plus...',
+'mypage' => 'Ma page',
+'mytalk' => 'Ma page de discussion',
+'anontalk' => 'Discussion avec cette adresse IP',
+
+# Metadata in edit box
+
+'metadata' => '<b>Metadata</b>',
+
+'currentevents' => 'Actualités',
+'currentevents-url' => 'Actualités',
+'disclaimers' => 'Avertissements',
+'disclaimerpage' => '{{ns:4}}:Avertissements généraux',
+'privacy' => 'Politique de confidentialité',
+'privacypage' => 'Project:Confidentialité',
+'errorpagetitle' => 'Erreur',
+'returnto' => 'Revenir à la page $1.',
+'tagline' => 'Un article de {{SITENAME}}.',
+'search' => 'Rechercher',
+'searchbutton' => 'Rechercher',
+'go' => 'Consulter',
+'searcharticle' => 'Consulter',
+'history' => 'Historique de la page',
+'history_short' => 'Historique',
+'updatedmarker' => 'modifié depuis ma dernière visite',
+'printableversion' => 'Version imprimable',
+'permalink' => 'Lien permanent',
+'print' => 'Imprimer',
+'edit' => 'Modifier',
+'editthispage' => 'Modifier cette page',
+'delete' => 'Supprimer',
+'deletethispage' => 'Supprimer cette page',
+'undelete_short' => 'Restaurer $1 modifications',
+'protect' => 'Protéger',
+'protectthispage' => 'Protéger cette page',
+'unprotect' => 'Déprotéger',
+'unprotectthispage' => 'Déprotéger cette page',
+'newpage' => 'Nouvelle page',
+'talkpage' => 'Page de discussion',
+'specialpage' => 'Page spéciale',
+'personaltools' => 'Outils personnels',
+'postcomment' => 'Ajouter un commentaire',
+'articlepage' => 'Voir l’article',
+'views' => 'Affichages',
+'toolbox' => 'Boîte à outils',
+'userpage' => 'Page utilisateur',
+'projectpage' => 'Page méta',
+'imagepage' => 'Page image',
+'viewtalkpage' => 'Page de discussion',
+'otherlanguages' => 'Autres langues',
+'redirectedfrom' => '(Redirigé depuis $1)',
+'redirectpagesub' => 'Page de redirection',
+'lastmodifiedat' => 'Dernière modification de cette page le $1 à $2',
+'viewcount' => 'Cette page a été consultée $1 fois.',
+'copyright' => 'Contenu disponible sous $1.',
+'protectedpage' => 'Page protégée',
+
+'badaccess' => 'Erreur de permission',
+
+'versionrequired' => 'Version $1 de MediaWiki nécessaire',
+'versionrequiredtext' => 'La version $1 de MediaWiki est nécessaire pour utiliser cette page. Consultez [[Special:Version]]',
+
+'nbytes' => '$1 octets',
+'ncategories' => '$1 catégories',
+'nrevisions' => '$1 révisions',
+'retrievedfrom' => 'Récupérée de « $1 »',
+'size-bytes' => '$1 O',
+'size-kilobytes' => '$1 KO',
+'size-megabytes' => '$1 MO',
+'size-gigabytes' => '$1 GO',
+'youhavenewmessages' => 'Vous avez $1 ($2).',
+'newmessageslink' => 'des nouveaux messages',
+'newmessagesdifflink' => 'diff vers l’avant-dernière révision',
+'editsection' => 'modifier',
+'editold' => 'modifier',
+'editsectionhint' => 'Modifier la section : $1',
+'toc' => 'Sommaire',
+'showtoc' => 'afficher',
+'hidetoc' => 'masquer',
+'thisisdeleted' => 'Désirez-vous afficher ou restaurer $1 ?',
+'viewdeleted' => 'Voir $1 ?',
+'restorelink' => '$1 modification(s) effacée(s)',
+'feedlinks' => 'Flux',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-user' => 'Page utilisateur',
+'nstab-media' => 'Média',
+'nstab-special' => 'Spécial',
+'nstab-project' => 'À propos',
+'nstab-image' => 'Image',
+'nstab-template' => 'Modèle',
+'nstab-help' => 'Aide',
+'nstab-category' => 'Catégorie',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Action inconnue',
+'nosuchactiontext' => 'L’action spécifiée dans l’URL n’est pas reconnue par le wiki.',
+'nosuchspecialpage' => 'Page spéciale inexistante',
+'nospecialpagetext' => 'Vous avez demandé une page spéciale qui n’est pas reconnue par le wiki.',
+
+# General errors
+#
+'error' => 'Erreur',
+'databaseerror' => 'Erreur base de données',
+'dberrortext' => 'Erreur de syntaxe dans la base de données. La dernière requête traitée par la base de données était :
+<blockquote><tt>$1</tt></blockquote>
+depuis la fonction « <tt>$2</tt> ».
+MySQL a renvoyé l’erreur « <tt>$3: $4</tt> ».',
+'dberrortextcl' => 'Une requête à la base de donnée comporte une erreur de syntaxe. La dernière requête envoyée était:
+« $1 »
+effectuée par la fonction « $2 »
+MySQL a retourné l’erreur « $3 : $4 ».',
+'noconnect' => 'Désolé ! Suite à des problèmes techniques, il est impossible de se connecter à la base de données pour le moment. <br /> $1',
+'nodb' => 'Sélection impossible de la base de données $1',
+'cachederror' => 'Ceci est une copie de la page demandée et peut ne pas être à jour',
+'laggedslavemode' => 'Attention : la page n’intègre peut être pas les dernières modifications',
+'readonly' => 'Mises à jour bloquées sur la base de données',
+'enterlockreason' => 'Indiquez la raison du blocage, ainsi qu’une estimation de sa durée',
+'readonlytext' => 'Les ajouts et mises à jour sur la base de donnée {{SITENAME}} sont actuellement bloqués, probablement pour permettre la maintenance de la base, après quoi, tout rentrera dans l’ordre. Voici la raison pour laquelle l’administrateur a bloqué la base :
+<p>$1',
+'missingarticle' => 'La base de données n’a pas pu trouver le texte d’une page existante, dont le titre est « $1 ».
+Ce n’est pas une erreur de la base de données, mais plus probablement un bogue du wiki.
+Veuillez rapporter cette erreur à un administrateur, en lui indiquant l’adresse de la page fautive.',
+'readonly_lag' => 'La base de donnée a été automatiquement bloquée pendant que les serveurs secondaires rattrapent leur retard avec le serveur principal',
+'internalerror' => 'Erreur interne',
+'filecopyerror' => 'Impossible de copier « $1 » vers « $2 ».',
+'filedeleteerror' => 'Impossible de supprimer « $1 ».',
+'filenotfound' => 'Le fichier « $1 » introuvable.',
+'unexpected' => 'Valeur inattendue : « $1 » = « $2 ».',
+'formerror' => 'Erreur : Impossible de soumettre le formulaire',
+'badarticleerror' => 'Cette action ne peut pas être effectuée sur cette page.',
+'cannotdelete' => 'Impossible de supprimer la page ou l’image indiquée.',
+'badtitle' => 'Mauvais titre',
+'badtitletext' => 'Le titre de la page demandée est invalide, vide ou le lien interlangue est invalide',
+'perfdisabled' => 'Désolé! Cette fonctionnalité est temporairement désactivée
+car elle ralentit la base de données à un point tel que plus personne
+ne peut utiliser le wiki.',
+'perfdisabledsub' => 'Ceci est une copie de sauvegarde de $1:',
+'perfcached' => 'Ceci est une version en cache et n’est peut-être pas à jour.',
+'perfcachedts' => 'Ceci est une version en cache, et fut mis à jour la dernière fois le $1.',
+'wrong_wfQuery_params' => 'Paramètres incorrects sur la commande wfQuery()<br />
+Fonction : $1<br />
+Requête : $2',
+'viewsource' => 'Voir le texte source',
+'viewsourcefor' => 'pour $1',
+'viewsourcetext' => 'Vous pouvez toutefois voir et copier son code source:',
+'protectedtext' => 'Cette page a été protégée pour empêcher sa modification. Vous pouvez consulter [[{{ns:4}}:Page protégée]] pour voir les différentes raisons possibles.',
+'protectedinterface' => 'Cette page fournit du texte d’interface pour le logiciel, et est protégée pour éviter les abus.',
+'editinginterface' => '\'\'\'Attention :\'\'\' Vous éditez une page utilisée pour fournir le texte de l’interface du logiciel. Les modifications affecteront l’apparence de l’interface pour les autres utilisateurs.',
+'sqlhidden' => '(requête SQL cachée)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Déconnexion',
+'logouttext' => 'Vous êtes à présent déconnecté(e).
+Vous pouvez continuer à utiliser {{SITENAME}} de façon anonyme, ou vous reconnecter, éventuellement sous un autre nom.',
+
+'welcomecreation' => '<h2>Bienvenue, $1!</h2><p>Votre compte d’utilisateur a été créé.
+N’oubliez pas de personnaliser votre {{SITENAME}} en consultant la page Préférences.',
+
+'loginpagetitle' => 'Votre identifiant',
+'yourname' => 'Votre nom d’utilisateur',
+'yourpassword' => 'Votre mot de passe',
+'yourpasswordagain' => 'Entrez à nouveau votre mot de passe',
+'remembermypassword' => 'Se souvenir de mon mot de passe (cookie)',
+'yourdomainname' => 'Votre domaine',
+'externaldberror' => 'Une erreur externe de la base de donnée d’authentification s’est produite et vous n’êtes pas autorisé à mettre à jour votre compte externe.',
+'loginproblem' => '<b>Problème d’identification.</b><br />Essayez à nouveau !',
+'alreadyloggedin' => '<strong>\'\'\'Utilisateur $1, vous êtes déjà identifié!\'\'\'</strong><br />',
+
+'login' => 'Identification',
+'loginprompt' => 'Vous devez activer les cookies pour vous connecter à {{SITENAME}}.',
+'userlogin' => 'Créer un compte ou se connecter',
+'logout' => 'Déconnexion',
+'userlogout' => 'Déconnexion',
+'notloggedin' => 'Non connecté',
+'nologin' => 'Vous n’avez pas de compte ? $1.',
+'nologinlink' => 'Créer un compte',
+'createaccount' => 'Créer un compte',
+'gotaccount' => 'Vous avez déjà un compte ? $1.',
+'gotaccountlink' => 'Identifiez-vous',
+'createaccountmail' => 'par courriel',
+'badretype' => 'Les deux mots de passe que vous avez saisis ne sont pas identiques.',
+'userexists' => 'Le nom d’utilisateur que vous avez saisi est déjà utilisé. Veuillez en choisir un autre.',
+'youremail' => 'Mon adresse électronique',
+'username' => 'Nom d’utilisateur :',
+'uid' => 'ID utilisateur :',
+'yourrealname' => 'Votre nom réel*',
+'yourlanguage' => 'Langue de l’interface',
+'yourvariant' => 'Variante',
+'yournick' => 'Pseudonyme :',
+'badsig' => 'Signature brute incorrecte, vérifiez vos balises HTML.',
+'email' => 'Courriel',
+'prefs-help-email-enotif' => 'Cette adresse est aussi utilisée pour vous envoyer des notifications par courriel si vous avez activé les options correspondantes.',
+'prefs-help-realname' => '* Nom réel (facultatif): si vous le spécifiez, il sera utilisé pour l’attribution de vos contributions.',
+'loginerror' => 'Problème d’identification',
+'prefs-help-email' => '* Adresse de courriel (facultatif): permet de vous contacter depuis le site sans dévoiler votre identité.',
+'nocookiesnew' => 'Le compte utilisateur a été créé, mais vous n’êtes pas connecté. {{SITENAME}} utilise des cookies pour la connexion mais vous avez les cookies désactives. Merci de les activer et de vous reconnecter.',
+'nocookieslogin' => '{{SITENAME}} utilise des cookies pour la connexion mais vous avez les cookies désactivés. Merci de les activer et de vous reconnecter.',
+'noname' => 'Vous n’avez pas saisi de nom d’utilisateur.',
+'loginsuccesstitle' => 'Identification réussie.',
+'loginsuccess' => 'Vous êtes actuellement connecté sur {{SITENAME}} en tant que « $1 ».',
+'nosuchuser' => 'L’utilisateur « $1 » n’existe pas.
+Vérifiez que vous avez bien orthographié le nom, ou utilisez le formulaire ci-dessous pour créer un nouveau compte utilisateur.',
+'nosuchusershort' => 'Il n’y a pas de contributeur avec le nom « $1 ». Vérifiez l’orthographe.',
+'wrongpassword' => 'Le mot de passe est incorrect. Essayez à nouveau.',
+'wrongpasswordempty'=> 'Vous n’avez pas entré de mot de passe. Essayez à nouveau.',
+'mailmypassword' => 'Envoyez-moi un nouveau mot de passe',
+'passwordremindertitle' => 'Votre nouveau mot de passe sur {{SITENAME}}',
+'passwordremindertext' => 'Quelqu’un (probablement vous) ayant l’adresse IP $1 a demandé à ce qu’un nouveau mot de passe vous soit envoyé pour {{SITENAME}} ($4)
+Le mot de passe de l’utilisateur « $2 » est à présent « $3 ».
+Nous vous conseillons de vous connecter et de modifier ce mot de passe dès que possible. Si vous n’êtes pas l’auteur de cette demande, ou si vous vous souvenez à présent de votre ancien mot de passe et que vous ne souhaitez plus en changer, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.',
+'noemail' => 'Aucune adresse électronique n’a été enregistrée pour l’utilisateur « $1 ».',
+'passwordsent' => 'Un nouveau mot de passe a été envoyé à l’adresse électronique de l’utilisateur « $1 ».',
+'mailerror' => 'Erreur en envoyant le courriel : $1',
+'acct_creation_throttle_hit' => 'Désolé, vous avez déjà créé $1 comptes. Vous ne pouvez pas en créer de nouveaux.',
+'emailauthenticated' => 'Votre adresse de courriel a été authentifiée le $1.',
+'emailnotauthenticated' => 'Votre adresse de courriel n’est pas encore authentifiée. Aucun courriel ne sera envoyé pour aucune des fonctions suivantes.',
+'noemailprefs' => '<strong>Veuillez fournir une adresse de courriel pour le bon fonctionnement de ces fonctionnalités.</strong>',
+'emailconfirmlink' => 'Confirmez votre adresse de courriel',
+'invalidemailaddress' => 'Cette adresse de courriel ne peut pas être acceptée parce qu’elle semble avoir un format invalide. Veuillez entrer une adresse valide ou vider ce champ.',
+'accountcreated' => 'Compte créé.',
+'accountcreatedtext' => 'Le compte utilisateur pour $1 a été créé.',
+
+# Edit page toolbar
+'bold_sample' => 'Texte gras',
+'bold_tip' => 'Texte gras',
+'italic_sample' => 'Texte italique',
+'italic_tip' => 'Texte italique',
+'link_sample' => 'Lien titre',
+'link_tip' => 'Lien interne',
+'extlink_sample' => 'http://www.example.com lien titre',
+'extlink_tip' => 'Lien externe (n’oubliez pas le préfixe http://)',
+'headline_sample' => 'Texte de sous-titre',
+'headline_tip' => 'Sous-titre niveau 2',
+'math_sample' => 'Entrez votre formule ici',
+'math_tip' => 'Formule mathématique (LaTeX)',
+'nowiki_sample' => 'Entrez le texte non formaté ici',
+'nowiki_tip' => 'Ignorer la syntaxe wiki',
+'image_sample' => 'Exemple.jpg',
+'image_tip' => 'Image insérée',
+'media_sample' => 'Exemple.ogg',
+'media_tip' => 'Lien fichier média',
+'sig_tip' => 'Votre signature avec la date',
+'hr_tip' => 'Lien horizontal (ne pas en abuser)',
+
+# Edit pages
+#
+'summary' => 'Résumé&nbsp;',
+'subject' => 'Sujet/titre',
+'minoredit' => 'Modification mineure',
+'watchthis' => 'Suivre cet article',
+'savearticle' => 'Sauvegarder',
+'preview' => 'Prévisualiser',
+'showpreview' => 'Prévisualisation',
+'showlivepreview'=> 'Prévisualisation rapide',
+'showdiff' => 'Changements en cours',
+'anoneditwarning' => '\'\'\'Attention :\'\'\' Vous n’êtes pas identifié. Votre adresse IP sera enregistrée dans l’historique de cette page.',
+'missingsummary' => '\'\'\'Rappel :\'\'\' Vous n’avez pas fourni de commentaire de modification. Si vous cliquez une nouvelle fois sur le bouton « Sauvegarder », votre modification sera enregistrée sans commentaire.',
+'missingcommenttext' => 'Merci d’insérer un commentaire ci-dessous.',
+'blockedtitle' => 'Utilisateur bloqué',
+'blockedtext' => 'Votre compte utilisateur ou votre adresse IP ont été bloqués par $1 pour la raison suivante : $2. Vous pouvez contacter $1 ou un des autres [[{{ns:4}}:Administrateur|administrateurs]] pour en discuter. Veuillez noter que vous ne pouvez utiliser la fonction de courriel si vous n’avez pas enregistré une adresse de courriel valide dans vos [[Special:Preferences|préférences]]. Votre adresse IP est $3. Merci d’inclure cette adresse dans toutes vos requêtes.',
+'whitelistedittitle' => 'Login requis pour rédiger',
+'whitelistedittext' => 'Vous devez être $1 pour avoir la permission de rédiger',
+'whitelistreadtitle' => 'Compte requis pour lire',
+'whitelistreadtext' => 'Vous devez être [[Special:Userlogin|connecté]] pour avoir la permission de lire les articles',
+'whitelistacctitle' => 'Vous n’êtes pas autorisé à créer un compte',
+'whitelistacctext' => 'Pour avoir la permission de créer un compte sur ce Wiki vous devez être [[Special:Userlogin|connecté]] et avoir les permissions appropriées',
+'confirmedittitle' => 'Validation par courriel requise pour modifier les pages',
+'confirmedittext' => 'Vous devez valider votre adresse de courriel avant de modifier une page. Veuillez entrer et valider votre adresse de courriel grâce à [[Special:Preferences|user preferences]].',
+'loginreqtitle' => 'Identification nécessaire',
+'loginreqlink' => 'connecter',
+'loginreqpagetext' => 'Vous devez vous $1 pour voir les autres pages.',
+'accmailtitle' => 'Mot de passe envoyé.',
+'accmailtext' => 'Le mot de passe de « $1 » a été envoyé à l’adresse $2.',
+'newarticle' => '(Nouveau)',
+'newarticletext' => 'Vous avez suivi un lien vers une page qui n’existe pas encore. Pour créer cette page, entrez votre texte dans la boîte ci-dessous (vous pouvez consulter [[Project:Aide|la page d’aide]] pour plus d’information). Si vous êtes arrivé ici par erreur, cliquez sur le bouton \'\'\'retour\'\'\' de votre navigateur.',
+'anontalkpagetext' => '---- \'\'Vous êtes sur la page de discussion d’un utilisateur anonyme qui n’a pas encore créé un compte ou qui ne l’utilise pas. Pour cette raison, nous devons utiliser l’adresse IP numérique pour l’identifier. Une adresse de ce type peut être partagée entre plusieurs utilisateurs. Si vous êtes un utilisateur anonyme et si vous constatez que des commentaires qui ne vous concernent pas vous ont été adressés, vous pouvez [[Special:Userlogin|créer un compte ou vous connecter]] afin d’éviter toute confusion future avec d’autres contributeurs anonymes.\'\'',
+'noarticletext' => 'Il n’y a pour l’instant aucun texte sur cette page, vous pouvez [[{{ns:special}}:Search/{{PAGENAME}}|faire une recherche pour le titre de cette page]] ou [{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} modifier cette page]',
+'clearyourcache' => '\'\'\'Note :\'\'\' Après avoir sauvegardé, vous devez forcer le rechargement de la page pour voir les changements : \'\'\'Mozilla / Konqueror / Firefox\'\'\' : \'\'ctrl-shift-r\'\', \'\'\'IE\'\'\' : \'\'ctrl-f5\'\', \'\'\'Safari\'\'\' : \'\'cmd-shift-r\'\'; \'\'\'Konqueror\'\'\' : \'\'f5\'\'.',
+'usercssjsyoucanpreview' => "'''Astuce :''' utilisez le bouton '''Prévisualisation''' pour tester votre nouvelle feuille css/js avant de l'enregistrer.",
+'usercsspreview' => "'''Rappelez-vous que vous êtes en train de prévisualiser votre propre feuille css et qu'elle n'a pas encore été enregistrée !'''",
+'userjspreview' => "'''Rappelez-vous que vous êtes en train de visualiser ou de tester votre code javascript et qu'il n'a pas encore été enregistré !'''",
+'updated' => '(Mis à jour)',
+'note' => '<strong>Note :</strong>',
+'previewnote' => 'Attention, ce texte n’est qu’une prévisualisation et n’a pas encore été sauvegardé !',
+'session_fail_preview' => '<strong>Désolé ! Nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session. Veuillez réessayer. Si cela échoue à nouveau, veuillez vous déconnecter, puis vous reconnecter.</strong>',
+'previewconflict' => 'La prévisualisation montre le texte de cette page tel qu’il apparaîtra une fois sauvegardé.',
+'importing' => 'Import de $1',
+'editing' => 'modification de $1',
+'editinguser' => 'modification de $1',
+'editingsection' => 'modification de $1 (section)',
+'editingcomment' => 'modification de $1 (commentaire)',
+'editconflict' => 'Conflit de modification : $1',
+'explainconflict' => '<b>Cette page a été sauvegardée après que vous avez commencé à la modifier.
+La zone de modification supérieure contient le texte tel qu’il est enregistré actuellement dans la base de données. Vos modifications apparaissent dans la zone de modification inférieure. Vous allez devoir apporter vos modifications au texte existant. Seul le texte de la zone supérieure sera sauvegardé.<br />',
+'yourtext' => 'Votre texte',
+'storedversion' => 'Version enregistrée',
+'nonunicodebrowser' => "<strong>Attention : Votre navigateur ne supporte pas l'unicode. Une solution temporaire a été trouvée pour vous permettre de modifier en tout sûreté un article : les caractères non-ASCII apparaîtront dans votre boîte de modification en tant que code hexadécimal.</strong>",
+'editingold' => '<strong>Attention : vous êtes en train de modifier une version obsolète de cette page. Si vous sauvegardez, toutes les modifications effectuées depuis cette version seront perdues.</strong>',
+'yourdiff' => 'Différences',
+'copyrightwarning' => 'Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la $2 (voir $1 pour plus de détails). Si vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici. Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre.<strong>N’UTILISEZ PAS DE TRAVAUX SOUS COPYRIGHT SANS AUTORISATION EXPRESSE !</strong>',
+'copyrightwarning2' => 'Toutes les contributions à {{SITENAME}} peuvent être modifiées ou supprimées par d’autres utilisateurs. Si vous ne désirez pas que vos écrits soient modifiés, merci de ne pas les soumettre ici. Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre. (voir $1 pour plus de détails).
+<strong>N’UTILISEZ PAS DE TRAVAUX SOUS COPYRIGHT SANS AUTORISATION EXPRESSE !</strong>',
+'longpagewarning' => "'''AVERTISSEMENT : cette page a une longueur de $1 ko;
+quelques navigateurs gèrent mal les pages approchant ou dépassant 32 ko lors de leur rédaction.
+Peut-être devriez-vous diviser la page en sections plus petites.'''",
+'longpageerror' => "<strong>ERREUR : Le texte que vous avez soumis fait $1 kilo-octets, ce qui dépasse la limite fixée à $2 kilo-octets. Le texte ne peut pas être sauvé.</strong>",
+'readonlywarning' => '\'\'\'AVERTISSEMENT : cette page est protégée pour maintenance,
+vous ne pourrez donc pas sauvegarder vos modifications maintenant. Vous pouvez copier le texte dans un fichier et le sauver pour plus tard.\'\'\'',
+'protectedpagewarning' => '\'\'\'AVERTISSEMENT : cette page est protégée.
+Seuls les utilisateurs ayant le statut d’administrateur peuvent la modifier. Soyez certain que
+vous suivez les [[Project:Page_protégée|directives concernant les pages protégées]].\'\'\'',
+'semiprotectedpagewarning' => "'''Note:''' Cette page a été protégée de telle façon que seuls les contributeurs enregistrés puissent la modifier.",
+'templatesused' => 'Modèles utilisés sur cette page :',
+'edittools' => '<!-- Tout texte entré ici sera affiché sous les boîtes de modification ou d’import. -->',
+'nocreatetitle' => 'Création de page limitée',
+'nocreatetext' => 'Ce site a restreint la possibilité de créer de nouvelles pages. Vous pouvez retourner en arrière et modifier une page existante ou [[Special:Userlogin|vous connecter ou créer un compte]].',
+'cantcreateaccounttitle' => 'Vous ne pouvez pas créer un compte.',
+'cantcreateaccounttext' => 'La création de compte depuis cette adresse IP (<b>$1</b>) a été bloquée. Ceci est probablement la conséquence d’un vandalisme répété depuis votre école ou votre fournisseur d’accès à internet.',
+
+# History pages #
+
+'revhistory' => 'Versions précédentes',
+'nohistory' => 'Il n’existe pas d’historique pour cette page.',
+'revnotfound' => 'Version introuvable',
+'revnotfoundtext' => 'La version précédente de cette page n’a pas pu être retrouvée. Vérifiez l’URL que vous avez utilisée pour accéder à cette page.',
+'loadhist' => 'Chargement de l’historique de la page',
+'currentrev' => 'Version actuelle',
+'revisionasof' => 'Version du $1',
+'previousrevision' => '← Version précédente',
+'nextrevision' => 'Version suivante →',
+'currentrevisionlink' => 'voir la version courante',
+'cur' => 'actu',
+'next' => 'suiv',
+'last' => 'dern',
+'histlegend' => 'Légende : (actu) = différence avec la version actuelle ,
+(dern) = différence avec la version précédente, M = modification mineure',
+'deletedrev' => '[supprimé]',
+'histfirst' => 'Premières contributions',
+'histlast' => 'Dernières contributions',
+'rev-deleted-comment' => '(commentaire supprimé)',
+'rev-deleted-user' => '(nom d’utilisateur supprimé)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks"> Cette version de la page a été retirée des archives publiques. Il peut y avoir des détails dans le [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} journal des effacements]. </div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks"> Cette version de la page a été retirée des archives publiques. En tant qu’administrateur de ce site, vous pouvez la visualiser ; il peut y avoir des détails dans le [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} journal des suppressions]. </div>',
+
+#'rev-delundel' => 'del/undel',
+'rev-delundel' => 'montrer/cacher',
+
+# Revision deletion
+#
+
+'revisiondelete' => 'Supprimer/Restaurer des versions',
+'revdelete-selected' => 'Version sélectionnée de [[:$1]] :',
+'revdelete-text' => 'Des versions supprimées apparaîtront encore dans l’historique de l’article, mais leur contenu textuel sera inaccessible au public.
+
+D’autres administrateurs sur ce wiki pourront toujours accèder au contenu caché et le restaurer à nouveau à travers cette même interface, à moins qu’une restriction supplémentaire ne soit mise en place par les opérateurs du site.',
+'revdelete-legend' => 'Mettre en place des restrictions de version :',
+'revdelete-hide-text' => 'Cacher le texte de la version',
+'revdelete-hide-comment' => 'Cacher le commentaire de modification',
+'revdelete-hide-user' => 'Cacher le nom du compte utilisateur/de l’IP.',
+'revdelete-hide-restricted' => 'Appliquer ces restrictions aux administrateurs ainsi qu’aux autres utilisateurs',
+'revdelete-log' => 'Commentaire pour le journal :',
+'revdelete-submit' => 'Appliquer à la version sélectionnée',
+'revdelete-logentry' => 'la visibilité des versions a été modifiée pour [[$1]]',
+
+# Diffs
+#
+'difference' => '(Différences entre les versions)',
+'loadingrev' => 'chargement de l’ancienne version pour comparaison',
+'lineno' => 'Ligne $1:',
+'editcurrent' => 'Modifier la version actuelle de cette page',
+'selectnewerversionfordiff' => 'Choisir une version plus récente pour comparaison',
+'selectolderversionfordiff' => 'Choisir une version plus ancienne pour comparaison',
+'compareselectedversions' => 'Comparer les versions sélectionnées',
+
+# Search results
+#
+'searchresults' => 'Résultat de la recherche',
+'searchresulttext' => 'Pour plus d’informations sur la recherche dans {{SITENAME}}, voir [[Aide:Recherche|Chercher dans {{SITENAME}}]].',
+'searchsubtitle' => 'Pour la requête « [[:$1]] »',
+'searchsubtitleinvalid' => 'Pour la requête « $1 »',
+'badquery' => 'Requête mal formulée',
+'badquerytext' => 'Nous n’avons pas pu traiter votre requête. Vous avez probablement recherché un mot d’une longueur inférieure à trois lettres, ce qui n’est pas encore possible. Vous avez aussi pu faire une erreur de syntaxe, telle que « poisson et et écailles ». Veuillez essayer une autre requête.',
+'matchtotals' => 'La requête « $1 » correspond à $2 titre(s) d’article et au texte de $3 article(s).',
+'noexactmatch' => 'Aucune page avec ce titre n’existe. Voulez-vous [[:$1|créer cet article]] ?',
+'titlematches' => 'Correspondances dans les titres',
+'notitlematches' => 'Aucun titre d’article ne contient le(s) mot(s) demandé(s)',
+'textmatches' => 'Correspondances dans les textes',
+'notextmatches' => 'Aucun texte d’article ne contient le(s) mot(s) demandé(s)',
+'prevn' => '$1 précédents',
+'nextn' => '$1 suivants',
+'viewprevnext' => 'Voir ($1) ($2) ($3).',
+'showingresults' => 'Affichage de <b>$1</b> résultats à partir du #<b>$2</b>.',
+'showingresultsnum' => 'Affichage de <b>$3</b> résultats à partir du #<b>$2</b>.',
+'nonefound' => '<strong>Note</strong>: l’absence de résultat est souvent due à l’emploi de termes de recherche trop courants, comme « à » ou « de »,
+qui ne sont pas indexés, ou à l’emploi de plusieurs termes de recherche (seules les pages
+contenant tous les termes apparaissent dans les résultats).',
+'powersearch' => 'Recherche',
+'powersearchtext' => 'Rechercher dans les espaces :<br />
+$1<br />
+$2 Inclure les page de redirections &nbsp; Rechercher $3 $9',
+'searchdisabled' => 'La recherche sur {{SITENAME}} a été désactivée. En attendant la réactivation, vous pouvez effectuer une recherche par le biais de Google. Attention, leur indexation du contenu {{SITENAME}} peut ne pas être à jour.',
+
+# Preferences page
+#
+'preferences' => 'Préférences',
+'prefsnologin' => 'Non connecté',
+'mypreferences' => 'Mes préférences',
+'prefsnologintext' => 'Vous devez être [[Special:Userlogin|connecté]] pour modifier vos préférences d’utilisateur.',
+'prefsreset' => 'Les préférences ont été rétablies à partir de la version enregistrée.',
+'qbsettings' => 'Personnalisation de la barre outils',
+'changepassword' => 'Modification du mot de passe',
+'skin' => 'Apparence',
+'math' => 'Rendu des maths',
+'dateformat' => 'Format de date',
+'datetime' => 'Date et heure',
+'math_failure' => 'Erreur math',
+'math_unknown_error' => 'erreur indéterminée',
+'math_unknown_function' => 'fonction inconnue',
+'math_lexing_error' => 'erreur lexicale',
+'math_syntax_error' => 'erreur de syntaxe',
+'math_image_error' => 'La conversion en PNG a échoué, vérifiez l’installation de Latex, dvips, gs et convert',
+'math_bad_tmpdir' => 'Impossible de crééer ou d’écrire dans le répertoire temporaire',
+'math_bad_output' => 'Impossible de crééer ou d’écrire dans le répertoire de sortie',
+'math_notexvc' => 'L’exécutable « texvc » est introuvable. Lisez math/README pour le configurer.',
+'prefs-personal' => 'Informations personnelles',
+'prefs-rc' => 'Modifications récentes',
+'prefs-watchlist-days' => 'Nombre de jours à montrer dans la liste de suivi:',
+'prefs-watchlist-edits' => 'Nombre de modifications à afficher dans la liste de suivi étendue:',
+'prefs-misc' => 'Préférences diverses',
+'saveprefs' => 'Enregistrer les préférences',
+'resetprefs' => 'Rétablir les préférences',
+'oldpassword' => 'Ancien mot de passe',
+'newpassword' => 'Nouveau mot de passe',
+'retypenew' => 'Confirmer le nouveau mot de passe',
+'textboxsize' => 'Fenêtre de modification',
+'rows' => 'Rangées',
+'columns' => 'Colonnes',
+'searchresultshead' => 'Affichage des résultats de recherche',
+'resultsperpage' => 'Nombre de réponses par page',
+'contextlines' => 'Nombre de lignes par réponse',
+'contextchars' => 'Nombre de caractères de contexte par ligne',
+'stubthreshold' => 'Taille minimale des articles courts',
+'recentchangescount' => 'Nombre de titres dans les modifications récentes',
+'savedprefs' => 'Les préférences ont été sauvegardées.',
+'timezonelegend' => 'Zone horaire',
+'timezonetext' => 'Si vous ne précisez pas de décalage horaire, c’est l’heure de l’Europe de l’ouest qui sera utilisée.',
+'localtime' => 'Heure locale',
+'timezoneoffset' => 'Décalage horaire',
+'servertime' => 'Heure du serveur',
+'guesstimezone' => 'Utiliser la valeur du navigateur',
+'allowemail' => 'Autoriser l’envoi de courriel d’autres utilisateurs',
+'defaultns' => 'Par défaut, rechercher dans ces espaces :',
+'default' => 'défaut',
+'files' => 'Fichiers',
+
+# User rights
+
+'userrights-lookup-user' => 'Gérer les groupes de l’utilisateur',
+'userrights-user-editname' => 'Entrer un nom d’utilisateur :',
+'editusergroup' => 'Modification des groupes de l’utilisateurs',
+
+'userrights-editusergroup' => 'Modifier les groupes de l’utilisateur',
+'saveusergroups' => 'Sauvegarder les groupes utilisateur',
+'userrights-groupsmember' => 'Membre de :',
+'userrights-groupsavailable' => 'Groupes disponibles :',
+'userrights-groupshelp' => 'Choisissez les groupes desquels vous voulez retirer ou rajouter l’utilisateur. Les groupes non sélectionnés ne seront pas modifiés. Vous pouvez désélectionner un groupe avec CTRL + clic gauche.',
+
+# Groups
+'group' => 'Groupe :',
+'group-sysop' => 'Administrateurs',
+'group-bureaucrat' => 'Bureaucrates',
+'group-all' => '(tous)',
+
+'group-sysop-member' => 'Administrateur',
+'group-bureaucrat-member' => 'Bureaucrate',
+
+'grouppage-sysop' => 'Projet:Administrateurs',
+'grouppage-bureaucrat' => 'Projet:Bureaucrates',
+
+# Recent changes
+#
+'changes' => 'modifications',
+'recentchanges' => 'Modifications récentes',
+'recentchangestext' => "Suivez sur cette page les dernières modifications de {{SITENAME}}.",
+'rcnote' => 'Voici les <strong>$1</strong> dernières modifications effectuées au cours des <strong>$2</strong> derniers jours, en date du $3',
+'rcnotefrom' => 'Voici les modifications effectuées depuis le <strong>$2</strong> (<b>$1</b> au maximum).',
+'rclistfrom' => 'Afficher les nouvelles modifications depuis le $1.',
+'rcshowhideminor' => '$1 modifications mineures',
+'rcshowhidebots' => '$1 robots',
+'rcshowhideliu' => '$1 utilisateurs enregistrés',
+'rcshowhideanons' => '$1 utilisateurs anonymes',
+'rcshowhidemine' => '$1 mes contributions',
+'rclinks' => 'Afficher les $1 dernières modifications effectuées au cours des $2 derniers jours; $3 modifications mineures.',
+'hide' => 'Masquer',
+'show' => 'Afficher',
+'number_of_watching_users_pageview' => '[$1 utilisateur/s suivant]',
+'rc_categories' => 'Limite des catégories (separation avec « | »)',
+'rc_categories_any' => 'Toutes',
+
+# Upload
+#
+'upload' => 'Copier sur le serveur',
+'uploadbtn' => 'Copier un fichier',
+'reupload' => 'Copier à nouveau',
+'reuploaddesc' => 'Retour au formulaire.',
+'uploadnologin' => 'Non connecté(e)',
+'uploadnologintext' => 'Vous devez être [[Special:Userlogin|connecté]] pour copier des fichiers sur le serveur.',
+'upload_directory_read_only' => 'Le serveur Web ne peut écrire dans le dossier cible ($1).',
+'uploaderror' => 'Erreur',
+'uploadtext' => 'Utilisez ce formulaire pour copier des fichiers, pour voir ou rechercher des images précédemment copiées consultez la [[Special:Imagelist|liste de fichiers copiés]], les copies et suppressions sont aussi enregistrées dans le [[Special:Log/upload|journal des copies]].
+
+Pour inclure une image dans une page, utilisez un lien de la forme
+\'\'\'<nowiki>[[{{ns:6}}:fichier.jpg]]</nowiki>\'\'\',
+\'\'\'<nowiki>[[{{ns:6}}:fichier.png|texte alternatif]]</nowiki>\'\'\' or
+\'\'\'<nowiki>[[{{ns:-2}}:fichier.ogg]]</nowiki>\'\'\' pour lier directement vers le fichier.',
+'uploadlog' => 'Journal d’upload',
+'uploadlogpage' => 'Journal d’upload',
+'uploadlogpagetext' => 'Voici la liste des derniers fichiers copiés sur le serveur.',
+'filename' => 'Nom du fichier',
+'filedesc' => 'Description',
+'fileuploadsummary' => 'Description :',
+'filestatus' => 'Statut du copyright',
+'copyrightpage' => '{{ns:4}}:Copyright',
+'copyrightpagename' => 'licence {{SITENAME}}',
+'uploadedfiles' => 'Fichiers copiés',
+'ignorewarning' => 'Ignorer l’avertissement et sauvegarder le fichier.',
+'ignorewarnings' => 'Ignorer tous les avertissements',
+'minlength' => 'Les noms des images doivent comporter au moins trois lettres.',
+'illegalfilename' => 'Le nom de fichier « $1 » contient des caractères interdits dans les titres de pages. Merci de le renommer et de le copier à nouveau.',
+'badfilename' => 'L’image a été renommée « $1 ».',
+'badfiletype' => '« .$1 » n’est pas un format accepté pour les fichiers images.',
+'largefile' => 'La taille maximale conseillée pour les images est de $1 ko ($2).',
+'largefileserver' => 'Ce fichier possède une taille supérieure à celle autorisée par la configuration du serveur.',
+'emptyfile' => 'Le fichier que vous voulez importer semble vide. Ceci peut-être dû à une erreur dans le nom du fichier. Veuillez vérifiez que vous désirez vraiment copier ce fichier.',
+'fileexists' => 'Un fichier avec ce nom existe déjà. Merci de vérifier $1. Êtes-vous certain de vouloir modifier ce fichier ?',
+'fileexists-forbidden' => 'Un fichier avec ce nom existe déjà ; merci de retourner en arrière et de copier le fichier sous un nouveau nom. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Un fichier portant ce nom existe déjà dans le répertoire de fichiers partagés ; merci de retourner en arrière et de copier le fichier sous un nouveau nom. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Copie réussie',
+'fileuploaded' => 'Le fichier « $1 » a été copié sur le serveur.
+Suivez ce lien ($2) pour accéder à la page de description, et donner des informations sur le fichier, par exemple son origine, sa date de création, son auteur, ou tout autre renseignement en votre possession.',
+'uploadwarning' => 'Attention !',
+'savefile' => 'Sauvegarder le fichier',
+'uploadedimage' => '« [[$1]] » copié sur le serveur',
+'uploaddisabled' => 'Désolé, l’envoi de fichier est désactivé.',
+'uploaddisabledtext' => 'La copie de fichiers est désactivée sur ce wiki.',
+'uploadscripted' => 'Ce fichier contient du code HTML ou un script qui pourrait être interprété de façon incorrecte par un navigateur Internet.',
+'uploadcorrupt' => 'Ce fichier est corrompu, a une taille nulle ou possède une extension invalide.
+Veuillez vérifer le fichier.',
+'uploadvirus' => 'Ce fichier contient un virus ! Pour plus de détails, consultez : $1',
+'sourcefilename' => 'Nom du fichier à envoyer',
+'destfilename' => 'Nom sous lequel le fichier sera enregistré',
+'filewasdeleted' => 'Un fichier avec ce nom a déjà été copié, puis supprimé. Vous devriez vérifier le $1 avant de procéder à une nouvelle copie.',
+
+'license' => 'Licence',
+'nolicense' => 'Aucune licence sélectionnée',
+
+
+# Image list
+#
+'imagelist' => 'Liste des images',
+'imagelisttext' => 'Voici une liste de $1 images classées $2.',
+'getimagelist' => 'Récupération de la liste des images',
+'ilsubmit' => 'Chercher',
+'showlast' => 'Afficher les $1 dernières images classées $2.',
+'byname' => 'par nom',
+'bydate' => 'par date',
+'bysize' => 'par taille',
+'imgdelete' => 'suppr',
+'imgdesc' => 'descr',
+'imglegend' => 'Légende : (descr) = afficher/modifier la description de l’image.',
+'imghistory' => 'Historique de l’image',
+'revertimg' => 'rétab',
+'deleteimg' => 'suppr',
+'deleteimgcompletely' => 'suppr',
+'imghistlegend' => 'Légende : (actu) = ceci est l’image actuelle, (suppr) = supprimer
+cette ancienne version, (rétab) = rétablir cette ancienne version.
+<br /><i>Cliquez sur la date pour voir l’image copiée à cette date</i>.',
+'imagelinks' => 'Liens vers l’image',
+'linkstoimage' => 'Les pages ci-dessous contiennent cette image :',
+'nolinkstoimage' => 'Aucune page ne contient cette image.',
+'sharedupload' => 'Ce fichier est partagé et peut-être utilisé par d’autres projets.',
+'shareduploadwiki' => 'Veuillez consulter le $1 pour plus d’informations.',
+'shareduploadwiki-linktext' => 'Page de description du fichier',
+'noimage' => 'Aucun fichier possèdant ce nom n’existe, vous pouvez $1.',
+'noimage-linktext' => 'le copier',
+'uploadnewversion-linktext' => 'Copier une nouvelle version de ce fichier',
+
+# Mime search
+#
+'mimesearch' => 'Recherche par type MIME',
+'mimetype' => 'Type MIME :',
+'download' => 'Téléchargement',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Pages non suivies',
+
+# List redirects
+'listredirects' => 'Liste des redirections',
+
+# Unused templates
+'unusedtemplates' => 'Modèles inutilisés',
+'unusedtemplatestext' => 'Cette page liste toutes les pages de l’espace de noms « Modèle » qui ne sont inclus dans aucune autre page. N’oubliez pas de vérifier s’il n’y a pas d’autre lien vers les modèles avant de les supprimer.',
+'unusedtemplateswlh' => 'autres liens',
+
+# Random redirect
+'randomredirect' => 'Redirect aléatoire',
+
+# Statistics
+
+'statistics' => 'Statistiques',
+'sitestats' => 'Statistiques de {{SITENAME}}',
+'userstats' => 'Statistiques utilisateur',
+'sitestatstext' => "La base de données contient actuellement <b>$1</b> pages.
+
+Ce chiffre inclut les pages « discussion », les pages relatives à {{SITENAME}}, les pages minimales (\"ébauches\"), les pages de redirection, ainsi que d'autres pages qui ne peuvent sans doute pas être considérées comme des articles.
+Si l'on exclut ces pages, il reste <b>$2</b> pages qui sont probablement de véritables articles.<p>
+
+'''$8''' fichiers ont été téléchargés.
+
+<b>$3</b> pages ont été consultées et <b>$4</b> pages modifiées.
+
+Cela représente une moyenne de <b>$5</b> modifications par page et de <b>$6</b> consultations pour une modification.</p>
+
+<p>Il y a '''$7''' articles dans [http://meta.wikimedia.org/wiki/Help:Job_queue la file de tâche].</p>",
+'userstatstext' => "Il y a <b>$1</b> utilisateurs enregistrés. Parmi ceux-ci, '''$2''' (ou '''$4%''') ont le statut d’administrateur (voir $3).",
+
+'disambiguations' => 'Pages d’homonymie',
+'disambiguationspage' => 'Modèle:Homonymie',
+'disambiguationstext' => 'Les pages suivantes lient vers une <i>page d’homonymie</i>. Elles devraient plutôt lier vers une page pertinente.<br /> Une page est traitée comme une page d’homonymie si elle est liée depuis $1.<br /> Les liens depuis d’autres espaces de noms <i>ne sont pas</i> listés ici.',
+
+'doubleredirects' => 'Doubles redirections.',
+'doubleredirectstext' => 'Chaque case contient des liens vers la première et la seconde redirection, ainsi que la première ligne de texte de la seconde page, ce qui fournit habituellement la « vraie » page cible, vers laquelle la première redirection devrait rediriger.',
+
+'brokenredirects' => 'Redirections cassées',
+'brokenredirectstext' => 'Ces redirections mènent vers des pages qui n’existent pas :',
+
+# Miscellaneous special pages
+#
+'lonelypages' => 'Pages orphelines',
+'uncategorizedpages' => 'Pages sans catégorie',
+'uncategorizedcategories' => 'Catégories sans catégories',
+'unusedcategories' => 'Catégories inutilisées',
+'unusedimages' => 'Images orphelines',
+'popularpages' => 'Pages les plus consultées',
+'nviews' => '$1 consultations',
+'wantedcategories' => 'Catégories les plus demandées',
+'wantedpages' => 'Pages les plus demandées',
+'mostlinked' => 'Pages les plus liées',
+'mostlinkedcategories' => 'Catégories les plus liées',
+'mostcategories' => 'Articles avec le plus de catégories',
+'mostimages' => 'Images les plus liées',
+'mostrevisions' => 'Articles avec le plus de révisions',
+'nlinks' => '$1 références',
+'allpages' => 'Toutes les pages',
+'prefixindex' => 'Index des préfixes',
+'randompage' => 'Une page au hasard',
+'shortpages' => 'Pages courtes',
+'longpages' => 'Pages longues',
+'deadendpages' => 'Pages en impasse',
+'listusers' => 'Liste des participants',
+'specialpages' => 'Pages spéciales',
+'spheading' => 'Pages spéciales',
+'restrictedpheading' => 'Pages spéciales d’accès restreint',
+'recentchangeslinked' => 'Suivi des liens',
+'rclsub' => '(des pages liées à « $1 »)',
+'newpages' => 'Nouvelles pages',
+'ancientpages' => 'Articles les moins récemment modifiés',
+'move' => 'Renommer',
+'movethispage' => 'Renommer la page',
+'unusedimagestext' => '<p>N’oubliez pas que d’autres sites, peuvent contenir un lien direct vers cette image, et que celle-ci peut être placée dans cette liste alors qu’elle est en réalité utilisée.</p>',
+'unusedcategoriestext' => 'Les pages des catégories suivantes existent bien qu’aucun article ou catégorie ne les utilise.',
+
+'booksources' => 'Ouvrages de référence',
+'categoriespagetext' => 'Les catégories suivantes existent dans le wiki.',
+'data' => 'Données',
+'userrights' => 'Gestion des droits utilisateurs',
+'groups' => 'Groupes utilisateurs',
+
+'booksourcetext' => 'Voici une liste de liens vers d’autres sites qui vendent des livres neufs et d’occasion et sur lesquels vous trouverez peut-être des informations sur les ouvrages que vous cherchez. {{SITENAME}} n’étant liée à aucune de ces sociétés, elle n’a aucunement l’intention d’en faire la promotion.',
+'alphaindexline' => '$1 à $2',
+'log' => 'Journaux',
+'alllogstext' => 'Affichage combiné des journaux de copie, suppression, protection, blocage, et administrateur. Vous pouvez restreindre la vue en sélectionnant un type de journal, un nom d’utilisateur ou la page concernée.',
+'logempty' => 'Aucun élement pertinent dans le journal.',
+
+# Special:Allpages
+
+'nextpage' => 'Page suivante ($1)',
+'allpagesfrom' => 'Afficher les pages à partir de :',
+'allarticles' => 'Tous les articles',
+'allinnamespace' => 'Toutes les pages (espace de noms $1)',
+'allnotinnamespace' => 'Toutes les pages (n’étant pas dans l’espace de noms $1)',
+'allpagesnext' => 'Suivant',
+'allpagesprev' => 'Précédent',
+'allpagessubmit' => 'Valider',
+'allpagesprefix' => 'Afficher les pages commençant par le préfixe :',
+
+# Email this user
+#
+'mailnologin' => 'Pas d’adresse',
+'mailnologintext' => 'Vous devez être [[Special:Userlogin|connecté]]
+et avoir indiqué une adresse électronique valide dans vos [[Special:Preferences|préférences]]
+pour avoir la permission d’envoyer un message à un autre utilisateur.',
+'emailuser' => 'Envoyer un message à cet utilisateur',
+'emailpage' => 'Envoyer un courriel à l’utilisateur',
+'emailpagetext' => 'Si cet utilisateur a indiqué une adresse électronique valide dans ses préférences, le formulaire ci-dessous lui enverra un message.
+L’adresse électronique que vous avez indiquée dans vos préférences apparaîtra dans le champ « Expéditeur » de votre message afin que le destinataire puisse vous répondre.',
+'usermailererror' => 'Erreur dans le sujet du courriel :',
+'defemailsubject' => 'courriel envoyé depuis {{SITENAME}}',
+'noemailtitle' => 'Pas d’adresse électronique',
+'noemailtext' => 'Cet utilisateur n’a pas spécifié d’adresse de courriel valide ou a choisi de ne pas recevoir de courriel des autres utilisateurs.',
+'emailfrom' => 'Expéditeur',
+'emailto' => 'Destinataire',
+'emailsubject' => 'Objet',
+'emailsend' => 'Envoyer',
+'emailsent' => 'Message envoyé',
+'emailsenttext' => 'Votre message a été envoyé.',
+
+# Watchlist
+#
+'watchlist' => 'Liste de suivi',
+'nowatchlist' => 'Votre liste de suivi ne contient aucun article.',
+'watchlistcount' => '\'\'\'Vous avez $1 pages dans votre liste de suivi, en incluant les pages de discussion\'\'\'',
+'clearwatchlist' => 'Nettoyer votre liste de suivi',
+'watchlistcleartext' => 'Êtes-vous sûr de vouloir les retirer ?',
+'watchlistclearbutton' => 'Nettoyer la liste de suivi',
+'watchlistcleardone' => 'Votre liste de suivi a été nettoyée. $1 pages en ont été retirées.',
+'watchnologin' => 'Non connecté',
+'watchnologintext' => 'Vous devez être [[Special:Userlogin|connecté]] pour modifier votre liste.',
+'addedwatch' => 'Ajouté à la liste de suivi',
+'addedwatchtext' => 'La page « $1 » a été ajoutée à votre [[Special:Watchlist|liste de suivi]].
+Les prochaines modifications de cette page et de la page de discussion associée seront répertoriées ici, et la page apparaîtra \'\'\'en gras\'\'\' dans la [[Special:Recentchanges|liste des modifications récentes]] pour être repérée plus facilement.
+
+Pour supprimer cette page de votre liste de suivi, cliquez sur « ne plus suivre » dans le cadre de navigation.',
+'removedwatch' => 'Retirée de la liste de suivi',
+'removedwatchtext' => 'La page « $1 » a été retirée de votre liste de suivi.',
+'watch' => 'Suivre',
+'watchthispage' => 'Suivre cette page',
+'unwatch' => 'Ne plus suivre',
+'unwatchthispage' => 'Ne plus suivre',
+'notanarticle' => 'Pas un article',
+'watchnochange' => "Aucune des pages que vous suivez n'a été modifiée pendant la période affichée",
+'watchdetails' => 'Vous suivez $1 pages, sans compter les pages de discussion.
+* [[Special:Watchlist/edit|Voir et modifier la liste de suivi]]
+* [[Special:Watchlist/clear|Retirer toutes les pages de ma liste de suivi]]',
+'wlheader-enotif' => '* La notification par courriel est activée.',
+'wlheader-showupdated' => '* Les pages qui ont été modifiées depuis votre dernière visite sont montrées en \'\'\'gras\'\'\'',
+'watchmethod-recent' => 'vérification des modifications récentes des pages suivies',
+'watchmethod-list' => 'vérification des pages suivies pour des modifications récentes',
+'removechecked' => 'Retirer de la liste de suivi les pages sélectionnées',
+'watchlistcontains' => 'Votre liste de suivi contient $1 pages',
+'watcheditlist' => 'Ceci est votre liste de suivi par ordre alphabétique. Sélectionnez les pages que vous souhaitez retirer de la liste et cliquez le bouton « retirer de la liste de suivi » en bas de l’écran. (retirer un article retire aussi la page de discussion associée, et vice-versa)',
+'removingchecked' => 'Les articles sélectionnés sont retirés de votre liste de suivi...',
+'couldntremove' => 'Impossible de retirer l’article « $1 »...',
+'iteminvalidname' => 'Problème avec l’article « $1 » : le nom est invalide...',
+'wlnote' => 'Ci-dessous se trouvent les $1 dernières modifications depuis les <b>$2</b> dernières heures.',
+'wlshowlast' => 'Montrer les dernières $1 heures $2 jours $3',
+'wlsaved' => 'La liste de suivi n’est remise à jour qu’une fois par heure pour alléger la charge sur le serveur.',
+'watchlist-show-bots' => 'Affichier les contributions de bots',
+'watchlist-hide-bots' => 'Masquer les contributions de bots',
+'watchlist-show-own' => 'Affichier mes modifications',
+'watchlist-hide-own' => 'Masquer mes modifications',
+
+'enotif_mailer' => '{{SITENAME}} Notificateur par courriel',
+'enotif_reset' => 'Marque toutes les pages comme visitées',
+'enotif_newpagetext'=> 'Ceci est une nouvelle page.',
+'changed' => 'modifiée',
+'created' => 'créée',
+'enotif_subject' => '{{SITENAME}} la page $PAGETITLE a été $CHANGEDORCREATED par $PAGEEDITOR',
+'enotif_lastvisited' => 'Consultez $1 pour tous les changements depuis votre dernière visite.',
+'enotif_body' => 'Cher $WATCHINGUSERNAME,
+
+la page de {{SITENAME}} $PAGETITLE a été $CHANGEDORCREATED le $PAGEEDITDATE par $PAGEEDITOR, voyez $PAGETITLE_URL pour la version actuelle.
+
+$NEWPAGE
+
+Résumé de l’éditeur : $PAGESUMMARY $PAGEMINOREDIT
+
+Contactez l’éditeur :
+courriel : $PAGEEDITOR_EMAIL
+wiki : $PAGEEDITOR_WIKI
+
+Il n’y aura pas de nouvelles notifications en cas d’autres modifications à moins que vous ne visitiez cette page. Vous pouvez aussi remettre à zéro le notificateur pour toutes les pages de votre liste de suivi.
+
+ Votre {{SITENAME}} système de notification
+
+--
+Pour modifier les paramètres de votre liste de suivi, visitez
+{{fullurl:Special:Watchlist/edit}}
+
+Retour et assistance :
+{{fullurl:Help:Contents}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Supprimer une page',
+'confirm' => 'Confirmer',
+'excontent' => 'contenant « $1 »',
+'excontentauthor' => 'le contenu était : « $1 » (et le seul contributeur était « $2 »)',
+'exbeforeblank' => 'Avant son blanchiment, cette page contenait : $1',
+'exblank' => 'page vide',
+'confirmdelete' => 'Confirmer la suppression',
+'deletesub' => '(Suppression de « $1 »)',
+'historywarning' => 'Attention : La page que vous êtes sur le point de supprimer a un historique :',
+'confirmdeletetext' => 'Vous êtes sur le point de supprimer définitivement de la base de données une page ou une image, ainsi que toutes ses versions antérieures. Veuillez confirmer que c’est bien là ce que vous voulez faire, que vous en comprenez les conséquences et que vous faites cela en accord avec les [[Project:Policy|règles internes]].',
+'actioncomplete' => 'Action effectuée',
+'deletedtext' => '« $1 » a été supprimé.
+Voir $2 pour une liste des suppressions récentes.',
+'deletedarticle' => 'a effacé « $1 »',
+'dellogpage' => 'Journal des effacements',
+'dellogpagetext' => 'Voici la liste des suppressions récentes.
+L’heure indiquée est celle du serveur (UTC).',
+'deletionlog' => 'journal des effacements',
+'reverted' => 'Rétablissement de la version précédente',
+'deletecomment' => 'Motif de la suppression',
+'imagereverted' => 'La version précédente a été rétablie.',
+'rollback' => 'révoquer modifications',
+'rollback_short' => 'Révoquer',
+'rollbacklink' => 'révoquer',
+'rollbackfailed' => 'La révocation a échoué',
+'cantrollback' => 'Impossible de révoquer : il n’y a qu’un seul auteur à avoir modifié cet article',
+'alreadyrolled' => "Impossible de révoquer la dernière modification de l’article « [[:$1]] » effectuée par [[User:$2|$2]] ([[User talk:$2|Discussion]]) ; quelqu’un d’autre a déjà modifié ou révoqué l’article. La dernière modification a été effectuée par [[User:$3|$3]] ([[User talk:$3|Discussion]]).",
+'editcomment' => "Le résumé de la modification était: <i>« $1 »</i>.",
+'revertpage' => "Modifications de [[Special:Contributions/$2|$2]] ([[User_talk:$2|Discussion]]) révertées; retour à l'ancienne version de [[User:$1|$1]]",
+'sessionfailure' => 'Il semble qu’il y ait eu un problème avec votre session d’identification; cette action a été annulée par précaution contre le piratage de session. Merci de cliquer sur « retour » et de recharger la page d’où vous venez, et de réessayer.',
+'protectlogpage' => 'Historique des protections',
+'protectlogtext' => 'Voir les [[Project:Page protégée|directives]] pour plus d’information.',
+'protectedarticle' => 'a protégé « $1 »',
+'unprotectedarticle' => 'a déprotégé « $1 »',
+'protectsub' => "(Protéger « $1 »)",
+'confirmprotect' => 'Confirmer la protection',
+'confirmprotecttext' => 'Voulez-vous réellement protéger cette page ?',
+'protectmoveonly' => 'Protéger uniquement les déplacements',
+'protectcomment' => 'Raison de la protection',
+'unprotectsub' => '(Déprotéger « $1 »)',
+'confirmunprotecttext' => 'Voulez-vous réellement déprotéger cette page ?',
+'confirmunprotect' => 'Raison de la déprotection',
+'unprotectcomment' => 'Raison du déblocage',
+'protect-unchain' => 'Débloquer les permissions de renommage',
+'protect-text' => 'Vous pouvez consulter et modifier le niveau de protection de la page <strong>$1</strong>.
+Veuillez vous assurez que vous suivez les [[Project:Protected page|règles internes]].',
+'protect-viewtext' => 'Votre compte ne possède pas les permissions nécessaires pour changer les niveaux de protection de page. La configuration actuelle pour la page <strong>$1</strong> est la suivante :',
+'protect-default' => '(défaut)',
+'protect-level-autoconfirmed' => 'Bloquer les utilisateurs non enregistrés',
+'protect-level-sysop' => 'Uniquement les administrateurs',
+
+# restrictions (nouns)
+'restriction-edit' => 'Modifier',
+'restriction-move' => 'Déplacer',
+
+# Special:Undelete
+#
+'undelete' => 'Voir la page supprimée',
+'undeletepage' => 'Voir et restaurer la page supprimée',
+'undeletepagetext' => 'Ces pages ont été supprimées et se trouvent dans l’archive, elles sont toujours dans la base de donnée et peuvent être restaurées.
+L’archive peut être effacée périodiquement.',
+'undeleteextrahelp' => 'Pour restaurer toutes les versions de cette page, laissez vierges toutes les cases à cocher, puis cliquez sur \'\'\'\'\'Procéder à la restauration\'\'\'\'\'.<br />Pour procéder à une restauration sélective, cochez les cases correspondant aux versions qui sont à restaurer, puis cliquez sur \'\'\'\'\'Procéder à la restauration\'\'\'\'\'.<br />En cliquant sur le bouton \'\'\'\'\'Réinitialiser\'\'\'\'\', la boîte de résumé et les cases cochées seront remises à zéro.',
+'undeletearticle' => 'Restaurer les articles supprimés',
+'undeleterevisions' => '$1 révisions archivées',
+'undeletehistory' => 'Si vous restaurez la page, toutes les révisions seront restaurées dans l’historique.
+
+Si une nouvelle page avec le même nom a été créée depuis la suppression, les révisions restaurées apparaîtront dans l’historique antérieur et la version courante ne sera pas automatiquement remplacée.',
+'undeletehistorynoadmin' => 'Cet article a été supprimé. Le motif de la suppression est indiqué dans le résumé ci-dessous, avec les détails des utilisateurs qui l’ont modifié avant sa suppression. Le contenu de ces versions n’est disponible qu’aux administrateurs.',
+'undeleterevision' => '$1 versions archivées',
+'undeletebtn' => 'Procéder à la restauration !',
+'undeletereset' => 'Réinitialiser',
+'undeletecomment' => 'Commentaire :',
+'undeletedarticle' => 'a restauré « [[$1]] »',
+'undeletedrevisions' => '$1 versions ont été restaurées',
+
+# Namespace form on various pages
+'namespace' => 'Espace de noms :',
+'invert' => 'Inverser la sélection',
+
+# Contributions
+#
+'contributions' => 'Contributions',
+'mycontris' => 'Mes contributions',
+'contribsub' => 'Pour $1',
+'nocontribs' => 'Aucune modification correspondant à ces critères n’a été trouvée.',
+'ucnote' => 'Voici les <b>$1</b> dernières modifications effectuées par cet utilisateur au cours des <b>$2</b> derniers jours.',
+'uclinks' => 'Afficher les $1 dernières modifications; afficher les $2 derniers jours.',
+'uctop' => ' (dernière)',
+'newbies' => 'Nouveaux contributeurs',
+
+'sp-contributions-newest' => 'Dernières contributions',
+'sp-contributions-oldest' => 'Premières contributions',
+'sp-contributions-newer' => '$1 précédents',
+'sp-contributions-older' => '$1 suivants',
+'sp-contributions-newbies-sub' => 'Contributions des nouveaux utilisateurs',
+
+
+# What links here
+
+'whatlinkshere' => 'Pages liées',
+'notargettitle' => 'Pas de cible',
+'notargettext' => 'Indiquez une page cible ou un utilisateur cible.',
+'linklistsub' => '(Liste de liens)',
+'linkshere' => 'Les pages ci-dessous contiennent un lien vers \'\'\'[[:$1]]\'\'\' :',
+'nolinkshere' => 'Aucune page ne contient de lien vers \'\'\'[[:$1]]\'\'\'.',
+'isredirect' => 'page de redirection',
+
+# Block/unblock IP
+#
+'blockip' => 'Bloquer une adresse IP ou un utilisateur',
+'blockiptext' => 'Utilisez le formulaire ci-dessous pour bloquer l’accès en écriture à partir d’une adresse IP donnée ou d’un nom d’utilisateur.
+
+Une telle mesure ne doit être prise que pour empêcher le vandalisme et en accord avec les [[{{ns:project}}:Policy|règles internes]].
+Donnez ci-dessous une raison précise (par exemple en indiquant les pages qui ont été vandalisées).',
+'ipaddress' => 'Adresse IP',
+'ipadressorusername' => 'Adresse IP ou nom d’utilisateur',
+'ipbexpiry' => 'Durée du blocage',
+'ipbreason' => 'Motif du blocage',
+'ipbanononly' => 'Bloquer uniquement les utilisateurs anonymes',
+'ipbcreateaccount' => 'Empêcher la création de compte',
+'ipbsubmit' => 'Bloquer cet utilisateur',
+'ipbother' => 'Autre durée',
+'ipboptions' => '2 heures:2 hours,1 jour:1 day,3 jours:3 days,1 semaine:1 week,2 semaines:2 weeks,1 mois:1 month,3 mois:3 months,6 mois:6 months,1 an:1 year,Permanent:infinite',
+'ipbotheroption' => 'autre',
+'badipaddress' => 'L’adresse IP n’est pas correcte.',
+'blockipsuccesssub' => 'Blocage réussi',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|$1]] a été bloqué.<br />Vous pouvez consulter sur cette [[Special:Ipblocklist|page]] la liste des adresses IP bloquées.',
+'unblockip' => "Débloquer un utilisateur",
+'unblockiptext' => 'Utilisez le formulaire ci-dessous pour rétablir l’accès en écriture
+d’une adresse IP précédemment bloquée.',
+'ipusubmit' => 'Débloquer cette adresse',
+'ipblocklist' => 'Liste des blocages',
+'blocklistline' => '$1, $2 a bloqué $3 ($4)',
+'infiniteblock' => 'permanent',
+'expiringblock' => 'expire le $1',
+'anononlyblock' => 'uniquement anonyme',
+'createaccountblock' => 'la création de compte est bloquée',
+'ipblocklistempty'=> 'La liste de blocage est vide.',
+'blocklink' => 'bloquer',
+'unblocklink' => 'débloquer',
+'contribslink' => 'contributions',
+'autoblocker' => 'Vous avez été bloqué automatiquement parce que votre adresse IP a été récemment utilisée par « $1 ». La raison fournie pour le blocage de $1 est : « $2 ».',
+'blocklogpage' => 'Journal des blocages',
+'blocklogentry' => 'blocage de [[$1]] avec un temps d’expiration de $2',
+'blocklogtext' => 'Ceci est la trace des blocages et déblocages des utilisateurs. Les adresses IP automatiquement bloquées ne sont pas listées. Consultez la [[Special:Ipblocklist|liste des utilisateurs bloqués]] pour voir qui est actuellement effectivement bloqué.',
+'unblocklogentry' => 'déblocage de « $1 »',
+'ipb_expiry_invalid' => 'temps d’expiration invalide.',
+'ipb_already_blocked' => '"$1" est déjà bloqué',
+'ip_range_invalid' => 'Bloc IP incorrect.',
+'proxyblocker' => 'Bloqueur de proxy',
+'proxyblockreason' => 'Votre ip a été bloquée car il s’agit d’un proxy ouvert. Merci de contacter votre fournisseur d’accès internet ou votre support technique et de l’informer de ce problème de sécurité.',
+'proxyblocksuccess' => 'Terminé.',
+'sorbsreason' => 'Votre adresse IP est listée en tant que proxy ouvert [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Votre adresse IP est listée en tant que proxy ouvert [http://www.sorbs.net SORBS] DNSBL. Vous ne pouvez créer un compte',
+
+# Developer tools
+#
+'lockdb' => 'Verrouiller la base',
+'unlockdb' => 'Déverrouiller la base',
+'lockdbtext' => 'Le verrouillage de la base de données empêchera tous les utilisateurs de modifier des pages, de sauvegarder leurs préférences, de modifier leur liste de suivi et d’effectuer toutes les autres opérations nécessitant des modifications dans la base de données.
+Veuillez confirmer que c’est bien là ce que vous voulez faire et que vous débloquerez la base dès que votre opération de maintenance sera terminée.',
+'unlockdbtext' => 'Le déverrouillage de la base de données permettra à nouveau à tous les utilisateurs de modifier des pages, de mettre à jour leurs préférences et leur liste de suivi, ainsi que d’effectuer les autres opérations nécessitant des modifications dans la base de données.
+
+Veuillez confirmer que c’est bien là ce que vous voulez faire.',
+'lockconfirm' => 'Oui, je confirme que je souhaite verrouiller la base de données.',
+'unlockconfirm' => 'Oui, je confirme que je souhaite déverrouiller la base de données.',
+
+'lockbtn' => 'Verrouiller la base',
+'unlockbtn' => 'Déverrouiller la base',
+'locknoconfirm' => 'Vous n’avez pas coché la case de confirmation.',
+'lockdbsuccesssub' => 'Verrouillage de la base réussi.',
+'unlockdbsuccesssub' => 'Base déverrouillée.',
+'lockdbsuccesstext' => 'La base de données de {{SITENAME}} est verrouillée.
+
+N’oubliez pas de la déverrouiller lorsque vous aurez terminé votre opération de maintenance.',
+'unlockdbsuccesstext' => 'La base de données de {{SITENAME}} est déverrouillée.',
+
+# Special:Makesysop
+'makesysoptitle' => 'Donne les droits d’administrateur.',
+'makesysoptext' => 'Ce formulaire est utilisé par les bureaucrates pour donner les droits d’administrateur.
+Tapez le nom de l’utilisateur dans la boite et pressez le bouton pour lui donner les droits.',
+'makesysopname' => 'Nom de l’utilisateur:',
+'makesysopsubmit' => 'Donner les droits d’administrateur à cet utilisateur',
+'makesysopok' => '<b>L’utilisateur « $1 » est désormais administrateur.</b>',
+'makesysopfail' => '<b>L’utilisateur « $1 » ne peut être converti en adminitrateur. (Avez vous entré le nom correctement?)</b>',
+'setbureaucratflag' => 'Ajouter le statut de Bureaucrate',
+'rightslog' => 'Journal des droits',
+'rightslogtext' => 'Ceci est un journal des modifications de statut d’utilisateur..',
+'rightslogentry' => 'Droits de l’utilisateur « $1 » de $2 à $3',
+'rights' => 'Droits:',
+'set_user_rights' => 'Appliquer les droits à l’utilisateur',
+'user_rights_set' => '<b>Les droits de l’utilisateur « $1 » ont été mis à jour</b>',
+'set_rights_fail' => '<b>Les droits de l’utilisateur « $1 » n’ont pas pu être mis à jour. (Avez-vous entré le nom correctement ?)</b>',
+'makesysop' => 'Donner les droits d’administrateur à un utilisateur',
+'already_sysop' => 'Cet utilisateur est déjà un administrateur.',
+'already_bureaucrat' => 'Cet utilisateur est déjà un bureaucrate.',
+'rightsnone' => '(aucun)',
+
+# Move page
+#
+'movepage' => 'Renommer une page',
+'movepagetext' => 'Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom.
+L’ancien titre deviendra une page de redirection vers le nouveau titre. Les liens vers le titre de l’ancienne page ne seront pas changés ; veuillez vérifier que ce déplacement n’a pas créé de double redirect. Vous devez vous assurez que les liens continuent de pointer vers leur destination supposée.
+
+Une page ne sera pas déplacée si il y a déjà une page au nouveau titre, à moins que la page soit vide, ou une redirection, et qu’elle n’ait pas d’historique. Ce qui veut dire que vous pouvez renommer une page vers sa position d’origine si vous avez commis une erreur, et que vous ne pouvez effacer une page déjà existante par ce procédé.',
+'movepagetalktext' => 'La page de discussion associée, si présente, sera automatiquement renommée avec \'\'\'sauf si :\'\'\'
+*Vous renommez une page vers un autre espace,
+*Une page de discussion existe déjà avec le nouveau nom, ou
+*Vous avez désélectionné le bouton ci-dessous.
+
+Dans ce cas, vous devrez renommer ou fusionner la page manuellement si vous le désirez.',
+
+'movearticle' => 'Renommer l’article',
+'movenologin' => 'Non connecté',
+'movenologintext' => 'Pour avoir la permission de renommer un article, vous devez être [[Special:Userlogin|connecté]] en tant qu’utilisateur enregistré.',
+'newtitle' => 'Nouveau titre',
+'movepagebtn' => 'Renommer l’article',
+'pagemovedsub' => 'Renommage réussi',
+'pagemovedtext' => 'L’article « [[$1]] » a été renommé en « [[$2]] ».',
+'articleexists' => 'Il existe déjà un article portant ce titre, ou le titre que vous avez choisi n’est pas valide. Veuillez en choisir un autre.',
+'talkexists' => 'La page elle-même a été déplacée avec succès, mais la page de discussion n’a pas pu être déplacée car il en existait déjà une sous le nouveau nom. Veuillez les fusionner manuellement.',
+'movedto' => 'renommé en',
+'movetalk' => 'Renommer aussi la page « discussion », s’il y a lieu.',
+'talkpagemoved' => 'La page discussion correspondante a également été déplacée.',
+'talkpagenotmoved' => 'La page discussion correspondante n’a <strong>pas</strong> été déplacée.',
+'1movedto2' => 'a renommé $1 en $2',
+'1movedto2_redir' => 'a renommé $1 en $2 (redirection)',
+'movelogpage' => 'Journal des renommages',
+'movelogpagetext' => 'Ci-dessous apparaît la liste des pages renommées.',
+'movereason' => 'Raison du renommage',
+'revertmove' => 'révocation',
+'delete_and_move' => 'Supprimer et renommer',
+'delete_and_move_text' =>
+'==Suppression requise==
+
+L’article de destination « [[$1]] » existe déjà. Voulez-vous le supprimer pour permettre le renommage ?',
+'delete_and_move_confirm' => 'Oui, supprimer la page',
+'delete_and_move_reason' => 'Page supprimée pour permettre un renommage',
+'selfmove' => 'La page source et de destination sont identiques ; il est impossible de renommer une page en elle-même',
+'immobile_namespace' => 'Le titre de destination est d’un type spécial ; il est impossible de renommer des pages vers cet espace de noms.',
+
+
+# Export page
+'export' => 'Exporter des pages',
+'exporttext' => 'Vous pouvez exporter en XML le texte et l’historique d’une page ou d’un ensemble de pages; le résultat peut alors être importé dans un autre wiki fonctionnant avec le logiciel MediaWiki.
+
+Pour exporter des pages, entrez leurs titres dans la boîte de texte ci-dessous, un titre par ligne, et sélectionnez si vous désirez ou non la version actuelle avec toutes les anciennes versions, avec la page d’historique, ou simplement la page actuelle avec des informations sur la dernière modification.
+
+Dans ce dernier cas, vous pouvez aussi utiliser un lien, comme [[{{ns:Special}}:Export/{{Mediawiki:mainpage}}]] pour la page {{Mediawiki:mainpage}}.',
+
+'exportcuronly' => 'Exporter uniquement la version courante sans l’historique complet',
+'exportnohistory' => "----
+'''Note :''' l'exportation de l'historique complet des pages à travers ce formulaire a été désactive pour des raisons de performance.",
+
+# Namespace 8 related
+
+'allmessages' => 'Liste des messages système',
+'allmessagesname' => 'Nom du champ',
+'allmessagesdefault' => 'Message par défaut',
+'allmessagescurrent' => 'Message actuel',
+'allmessagestext' => 'Ceci est la liste de tous les messages disponibles dans l’espace MediaWiki',
+'allmessagesnotsupportedUI' => 'Special:AllMessages n’accepte pas la langue de votre interface (<b>$1</b>) sur ce site.',
+'allmessagesnotsupportedDB' => '\'\'\'Special:Allmessages\'\'\' n’est pas disponible car \'\'\'$wgUseDatabaseMessages\'\'\' est désactivé.',
+'allmessagesfilter' => 'Filtre d’expression régulière :',
+'allmessagesmodified' => 'N’afficher que les modifications',
+
+# Thumbnails
+
+'thumbnail-more' => 'Agrandir',
+'missingimage' => '<b>Image manquante</b><br /><i>$1</i>',
+'filemissing' => 'Fichier manquant',
+'thumbnail_error' => 'Erreur lors de la création de la miniature : $1',
+
+# Special:Import
+
+'import' => 'Importer des pages',
+'importinterwiki' => 'Import inter-wiki',
+'importtext' => 'Veuillez exporter le fichier depuis le wiki d’origine en utilisant l’outil Special:Export, le sauvegarder sur votre disque dur et le copier ici.',
+'importfailed' => 'Échec de l’import : $1',
+'importhistoryconflict' => 'Il y a un conflit dans l’historique des versions (cette page à peut être déjà été importée avant)',
+'importnotext' => 'Vide ou sans texte',
+'importsuccess' => 'L’import a réussi !',
+'importhistoryconflict' => 'Il existe un conflit de versions d’historique (cette page a peut-être déjà été importée)',
+'importnosources' => 'Aucune source inter-wiki n’a été définie et la copie directe d’historique est désactivée.',
+'importnofile' => 'Aucun fichier d’import n’a été copié.',
+'importuploaderror' => 'La copie du fichier d’import a échouée ; la taille du fichier est peut-être supérieure à celle autorisée.',
+
+# Keyboard access keys for power users
+
+# tooltip help for some actions, most are in Monobook.js
+
+'tooltip-search' => 'Rechercher dans ce wiki',
+'tooltip-minoredit' => 'Marquer cette modification comme mineur [alt-i]',
+'tooltip-save' => 'Sauvegarder vos modifications [alt-s]',
+'tooltip-preview' => 'Prévisualiser vos changements, veuillez utiliser cette fonction avant de sauvegarder ! [alt-p]',
+'tooltip-diff' => 'Voir les modifications que vous avez apportées au texte. [alt-v]',
+'tooltip-compareselectedversions' => 'Voir les différences entre les deux versions séléctionnées de cette page. [alt-v]',
+'tooltip-watch' => 'Ajouter cette page à votre liste de suivi [alt-w]',
+
+# stylesheets
+
+'common.css' => '/** Le CSS placé ici sera appliqué à toutes les apparences. */',
+'monobook.css' => '/* Le CSS placé ici affectera les utilisateurs du skin Monobook */',
+
+# Metadata
+
+'nodublincore' => 'Les métadonnées « Dublin Core RDF » sont désactivées sur ce serveur.',
+'nocreativecommons' => 'Les données méta « Creative Commons RDF » sont désactivées sur ce serveur.',
+'notacceptable' => 'Ce serveur wiki ne peut pas fournir les données dans un format que votre client est capable de lire.',
+
+# Attribution
+
+'anonymous' => 'Utilisateur(s) anonyme(s) de {{SITENAME}}',
+'siteuser' => 'Utilisateur $1 de {{SITENAME}}',
+'lastmodifiedatby' => 'Cette page a été modifiée pour la dernière fois le $1 à $2 par $3.',
+'and' => 'et',
+'othercontribs' => 'Basé sur le travail de $1.',
+'others' => 'autres',
+'siteusers' => 'Utilisateur(s) $1',
+'creditspage' => 'Page de crédits',
+'nocredits' => 'Il n’y a pas d’informations de crédits disponible pour cette page.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Filtre de protection contre le spam',
+'spamprotectiontext' => 'La page que vous avez tenté de sauvegarder a été bloquée par notre filtre anti-spam. Ceci est probablement causé par un lien vers un site externe',
+'spamprotectionmatch' => 'Le texte suivant a déclenché le détecteur de spam: $1',
+'subcategorycount' => 'Il y a {{PLURAL:$1|une sous-catégorie|a $1 sous-catégories}} dans cette catégorie.',
+'categoryarticlecount' => 'Il y a {{PLURAL:$1|un article|$1 articles}} dans cette catégorie.',
+'spambot_username' => 'Nettoyage de spam MediaWiki',
+'spam_reverting' => 'Retour à la dernière version ne contenant pas de lien vers $1',
+'spam_blanking' => 'Blanchissement de toutes les versions contenant un lien vers $1',
+
+# Info page
+'infosubtitle' => 'Information pour la page',
+'numedits' => 'Nombre de modifications (article) : $1',
+'numtalkedits' => 'Nombre de modifications (page de discussion ) : $1',
+'numwatchers' => 'Nombre de contributeurs ayant la page dans leur liste de suivi : $1',
+'numauthors' => 'Nombre d’auteurs distincts (article) : $1',
+'numtalkauthors' => 'Nombre d’auteurs distincts (page de discussion ) : $1',
+
+# Math options
+
+'mw_math_png' => 'Toujours produire une image PNG',
+'mw_math_simple' => 'HTML si très simple, autrement PNG',
+'mw_math_html' => 'HTML si possible, autrement PNG',
+'mw_math_source' => 'Laisser le code TeX original',
+'mw_math_modern' => 'Pour les navigateurs modernes',
+'mw_math_mathml' => 'MathML',
+
+# Patrolling
+
+'markaspatrolleddiff' => 'Marquer comme vérifiée',
+'markaspatrolledtext' => 'Marquer cet article comme vérifié',
+'markedaspatrolled' => 'Marqué comme vérifié',
+'markedaspatrolledtext' => 'La version sélectionnée a été marquée comme vérifiée.',
+'rcpatroldisabled' => 'La fonction de patrouille des modifications récentes n’est pas activée.',
+'rcpatroldisabledtext' => 'La fonctionnalité de surveillance des modifications récentes n’est pas activée.',
+'markedaspatrollederror' => 'Impossibilté de marquer en tant que révision patrouillée',
+'markedaspatrollederrortext' => 'Vous devez spécifier une révision à marquer comme patrouillée.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* infobulles et touches d’accès */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Ma page utilisateur\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'La page utilisateur de l’IP avec laquelle vous contribuez\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Ma page de discussion\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussion à propos des modifications depuis cette adresse IP\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Mes préférences\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'liste des pages dont vous suivez les modifications.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Liste de mes contributions\');
+ta[\'pt-login\'] = new Array(\'o\',\'Vous êtes invité à vous identifier, mais ce n’est pas obligatoire.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Vous êtes invité à vous identifier, mais ce n’est pas obligatoire.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Se déconnecter\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Discussion à propos de l’article\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Vous pouvez modifier cette page. Merci d’utiliser le bouton de prévisualisation avant de sauvegarder.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Ajouter un commentaire à cette discussion.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Cette page est protégée. Vous pouvez voir sa source.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Anciennes versions de cette page.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Protéger cette page\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Supprimer cette page\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Restaurer les modifications effectuées sur cette page avant sa suppression\');
+ta[\'ca-move\'] = new Array(\'m\',\'Renommer cette page\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Ajouter cette page à votre liste de suivi\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Retirer cette page de votre liste de suivi\');
+ta[\'search\'] = new Array(\'f\',\'Chercher dans ce wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Page principale\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Visitez la page principale\');
+ta[\'n-portal\'] = new Array(\'\',\'À propos de ce projet, ce que vous pouvez faire, où trouver les choses\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Trouver des informations sur les évènements actuels\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Liste des changements récents sur le wiki\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Charger une page aléatoire\');
+ta[\'n-help\'] = new Array(\'\',\'Aide\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Aidez-nous\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Liste de tous les wikis qui lient vers cette page\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Changements récents dans les pages qui lient vers cette page\');
+ta[\'feed-rss\'] = new Array(\'\',\'Flux RSS pour cette page\');
+ta[\'feed-atom\'] = new Array(\'\',\'Flux Atom pour cette page\');
+ta[\'t-contributions\'] = new Array(\'\',\'Voir la liste de contributions de cet utilisateur\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Envoyer un courriel à cet utilisateur\');
+ta[\'t-upload\'] = new Array(\'u\',\'Télécharger une image ou des fichiers\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Liste de toutes les pages spéciales\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Voir l’article\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Voir la page utilisateur\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Voir la page du média\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Ceci est une page spéciale, vous ne pouvez la modifier.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Voir la page du projet\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Voir la page de l’image\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Voir le message système\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Voir le modèle\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Voir la page d’aide\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Voir la page de la catégorie\');',
+
+# image deletion
+'deletedrevision' => 'L’ancienne version $1 a été supprimée.',
+
+# browsing diffs
+'previousdiff' => '← Différence précédente',
+'nextdiff' => 'Différence suivante →',
+'imagemaxsize' => 'Limiter l’image sur la page de description de l’image à :',
+'thumbsize' => 'Taille de la miniature :',
+'showbigimage' => 'Télécharger une version haute résolution ($1x$2, $3 Ko)',
+
+'newimages' => 'Galerie des nouveaux fichiers',
+'noimages' => 'Rien à afficher.',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+
+# variants for Serbian language
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Utilisateur :',
+'speciallogtitlelabel' => 'Titre :',
+
+'passwordtooshort' => 'Votre mot de passe est trop court. Il doit contenir au moins $1 caractères.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Attention\'\'\': Ce fichier peut contenir du code malveillant, votre système pouvant être mis en danger par son exécution.
+<hr />',
+
+'fileinfo' => '$1KB, type MIME : <code>$2</code>',
+
+# Metadata
+
+# external editor support
+'edit-externally' => 'Modifier ce fichier en utilisant un application externe',
+'edit-externally-help' => 'Voir [http://meta.wikimedia.org/wiki/Help:External_editors les instructions] pour plus d’informations.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'toutes',
+'imagelistall' => 'toutes',
+'watchlistall1' => 'tout',
+'watchlistall2' => 'tout',
+'namespacesall' => 'tous',
+
+# E-mail address confirmation
+
+'confirmemail' => 'Confirmer adresse de courriel',
+'confirmemail_text' => 'Ce wiki nécessite la vérification de votre adresse de courriel avant de pouvoir utiliser toute fonction de messagerie. Utilisez le bouton ci-dessous pour envoyer un courriel de confirmation à votre adresse. Le courriel contiendra un lien contenant un code, chargez ce lien dans votre navigateur pour valider votre adresse.',
+'confirmemail_send' => 'Envoyer un code de confirmation',
+'confirmemail_sent' => 'Courriel de confirmation envoyé',
+'confirmemail_sendfailed' => 'Impossible d’envoyer le courriel de confirmation. Vérifiez votre adresse.',
+'confirmemail_invalid' => 'Code de confirmation incorrect. Le code a peut être expiré',
+'confirmemail_needlogin' => 'Vous devez vous $1 pour confirmer votre adresse de courriel.',
+'confirmemail_success' => 'Votre adresse de courriel est confirmée. Vous pouvez maintenant vous connecter et profiter du wiki.',
+'confirmemail_loggedin' => 'Votre adresse est maintenant confirmée',
+'confirmemail_error' => 'Un problème est survenu en voulant enregistrer votre confirmation',
+'confirmemail_subject' => 'Confirmation d’adresse de courriel pour {{SITENAME}}',
+'confirmemail_body' => 'Quelqu’un, probablement vous avec l’adresse IP $1, a enregistré un compte « $2 » avec cette adresse de courriel sur le site {{SITENAME}}.
+
+Pour confirmer que ce compte vous appartient vraiment et activer les fonctions de messagerie sur {{SITENAME}}, veuillez suivre le lien ci dessous dans votre navigateur :
+
+$3
+
+Si il ne s’agit pas de vous, n’ouvrez pas le lien. Ce code de confirmation expirera le $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Essayez la correspondance exacte',
+'searchfulltext' => 'Recherche en texte intégral',
+'createarticle' => 'Créer l’article',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[La transclusion interwiki est désactivée]',
+'scarytranscludefailed' => '[La récupération de modèle a échoué pour $1 ; désolé]',
+'scarytranscludetoolong' => '[L’URL est trop longue ; désolé]',
+
+# Trackbacks
+
+# delete conflict
+
+'deletedwhileediting' => 'Attention : cette page a été supprimée après que vous avez commencé à la modifier.',
+'confirmrecreate' => 'L’utilisateur [[User:$1|$1]] ([[User talk:$1|talk]]) a supprimé cette page après que vous ayez commencé à la modifier, avec la raison : \'\'$2\'\'
+Veuillez confirmer que vous désirez vraiment re-créer cette page.',
+'recreate' => 'Recréer',
+
+# HTML dump
+'redirectingto' => 'Redirection vers [[$1]]...',
+
+# action=purge
+'confirm_purge' => 'Voulez-vous rafraîchir cette page ?\n\n$1',
+'confirm_purge_button' => 'Confirmer',
+
+'youhavenewmessagesmulti' => 'Vous avez de nouveaux messages sur $1',
+'searchcontaining' => 'Chercher les articles contenant \'\'$1\'\'.',
+'searchnamed' => 'Chercher les articles nommés \'\'$1\'\'.',
+'articletitles' => 'Articles commençant par \'\'$1\'\'',
+'hideresults' => 'Cacher les résultats',
+
+# DISPLAYTITLE
+'displaytitle' => '(Lier vers cette page comme [[$1]])',
+
+# Separator for categories in page lists
+# Please don't localise this
+
+# Metadata
+'metadata' => 'Métadonnées',
+'metadata-help' => 'Ce fichier contient des informations additionnelles, certainement ajoutée par l’appareil photographique ou le numériseur utilisé pour le créer ou le digitaliser. Si l’état du fichier a été altéré, certains détails peuvent ne pas refléter totalement l’image modifiée.',
+'metadata-expand' => 'Montrer les détails',
+'metadata-collapse' => 'Cacher les détails',
+'metadata-fields' => 'Les champs de métadonnées d’EXIF listés dans ce message seront inclus dans la page de description de l’image quand la table de métadonnées sera réduite. Les autres champs seront cachés par défaut.
+* constructeur
+* modèle
+* Date et heure
+* temps d’exposition
+* Nombre F
+* longueur de la focale',
+
+# EXIF tags
+'exif-imagewidth' => 'Largeur',
+'exif-imagelength' => 'Hauteur',
+'exif-compression' => 'Type de compression',
+'exif-samplesperpixel' => 'Nombre d’échantillons',
+'exif-xresolution' => 'Résolution de l’image en largeur',
+'exif-yresolution' => 'Résolution de l’image en hauteur',
+'exif-jpeginterchangeformat' => 'Position du SOI JPEG',
+'exif-jpeginterchangeformatlength' => 'Taille en octet des données JPEG',
+'exif-transferfunction' => 'Fonction de transfert',
+'exif-datetime' => 'Date et heure de changement du fichier',
+'exif-imagedescription' => 'Titre de l’image',
+'exif-make' => 'Fabricant de l’appareil',
+'exif-model' => 'Modèle de l’appareil',
+'exif-software' => 'Logiciel utilisé',
+'exif-artist' => 'Auteur',
+'exif-copyright' => 'Détenteur du copyright',
+'exif-exifversion' => 'Version exif',
+'exif-makernote' => 'Notes du fabricant',
+'exif-relatedsoundfile' => 'Fichier audio lié',
+'exif-whitebalance' => 'Balance des blancs',
+'exif-contrast' => 'Contraste',
+'exif-compression-1' => 'Sans compression',
+'exif-orientation-2' => 'Inversée horizontalement',
+'exif-orientation-3' => 'Tournée de 180°',
+'exif-orientation-4' => 'Inversée verticalement',
+'exif-orientation-5' => 'Tournée de 90° à gauche et inversée verticalement',
+'exif-orientation-6' => 'Tournée de 90° à droite',
+'exif-orientation-7' => 'Tournée de 90° à droite et inversée verticalement',
+'exif-orientation-8' => 'Tournée de 90° à gauche',
+'exif-componentsconfiguration-0' => 'n’existe pas',
+
+
+// exifgps:
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesFur.php b/languages/messages/MessagesFur.php
new file mode 100644
index 000000000000..e9ca33641d67
--- /dev/null
+++ b/languages/messages/MessagesFur.php
@@ -0,0 +1,728 @@
+<?php
+/** Friulian (Furlan)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$quickbarSettings = array(
+ 'Nissune', 'Fis a Çampe', 'Fis a Drete', 'Flutuant a çampe'
+);
+
+$skinNames = array(
+ 'nostalgia' => 'Nostalgie',
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciâl',
+ NS_MAIN => '',
+ NS_TALK => 'Discussion',
+ NS_USER => 'Utent',
+ NS_USER_TALK => 'Discussion_utent',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discussion_$1',
+ NS_IMAGE => 'Figure',
+ NS_IMAGE_TALK => 'Discussion_figure',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discussion_MediaWiki',
+ NS_TEMPLATE => 'Model',
+ NS_TEMPLATE_TALK => 'Discussion_model',
+ NS_HELP => 'Jutori',
+ NS_HELP_TALK => 'Discussion_jutori',
+ NS_CATEGORY => 'Categorie',
+ NS_CATEGORY_TALK => 'Discussion_categorie'
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j "di" M Y',
+ 'dmy both' => 'j "di" M Y "a lis" H:i',
+);
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+
+$messages = array(
+'1movedto2' => "$1 movût in $2",
+'about' => "Informazions",
+'aboutsite' => "Informazions su {{SITENAME}}",
+'accmailtitle' => 'Password mandade.',
+'accmailtext' => 'La password par "$1" e je stade mandade a $2.',
+'addedwatch' => "Zontât aes pagjinis tignudis di voli",
+'addedwatchtext' => "La pagjine \"$1\" e je stade zontade ae [[Special:Watchlist|liste di chês tignudis di voli]].
+Tal futûr i cambiaments a cheste pagjine e ae pagjine di discussion relative a saran segnalâts ca,
+e la pagjine e sarà '''gruessute''' te [[Special:Recentchanges|liste dai ultins cambiaments]] cussì che tu puedis notâle daurman.
+
+<p>Se tu vuelis gjavâle de liste pi indevant, frache su \"No stâ tignî di voli\" te sbare in alt.",
+
+'allarticles' => "Dutis lis vôs",
+'allinnamespace' => "Dutis lis pagjinis (non dal spazi $1)",
+'alllogstext' => 'Viodude combinade dai regjistris des cjamadis, eliminazions, protezions, blocs e azions day sysop.
+Tu puedis strenzi la viodude sielzint un gjenar di regjistri, un non utent o la vôs che ti interesse.',
+'allmessages' => "Ducj i messaçs di sisteme",
+'allmessagescurrent' => "Test curint",
+'allmessagesdefault' => "Test predeterminât",
+'allmessagesmodified' => 'Mostre dome modificâts',
+'allmessagesname' => "Non",
+'allmessagestext' => "Cheste e je une liste dai messaçs di sisteme disponibii tal non dal spazi MediaWiki:",
+'allnotinnamespace' => "Dutis lis pagjinis (no tal non dal spazi $1)",
+'allpages' => "Dutis lis pagjinis",
+'allpagesfrom' => "Mostre pagjinis scomençant di:",
+'allpagesnext' => "Prossim",
+'allpagesprev' => "Precedent",
+'allpagessubmit' => "Va",
+'alreadyloggedin' => "<strong>Utent $1, tu sês za jentrât!</strong><br />",
+'ancientpages' => 'Pagjinis plui vecjis',
+'and' => 'e',
+'anoneditwarning' => 'No tu sês jentrât cuntun non utent. La to direzion IP e vignarà regjistrade tal storic di cheste pagjine.',
+'anontalk' => 'Discussion par chest IP',
+'anonymous' => 'Utent(s) anonim(s) di {{SITENAME}}',
+'apr' => "Avr",
+'april' => "Avrîl",
+'articleexists' => 'Une pagjine cun chest non e esist za, o il non sielt nol è valit.
+Sielç par plasê un altri non.',
+'aug' => "Avo",
+'august' => "Avost",
+'badfilename' => 'File non gambiât in "$1".',
+'badretype' => "Lis peraulis clâfs inseridis no son compagnis.",
+'badsig' => 'Firme crude invalide; controle i tags HTML.',
+'blanknamespace' => '(Principâl)',
+'blockedtitle' => 'Utent blocât',
+'blocklink' => "bloche",
+'bold_sample'=>'Test in gruessut',
+'bold_tip'=>'Test in gruessut',
+'brokenredirects' => 'Redirezions no funzionantis',
+'brokenredirectstext' => 'Lis redirezions ca sot inviin a pagjinis che no esistin:',
+'byname' => 'par non',
+'bydate' => 'par date',
+'bysize' => 'par dimension',
+'cancel' => "Scancele",
+'categories' => "Categoriis",
+'categoriespagetext' => 'Te wiki a esistin lis categoriis ca sot.',
+'category_header' => "Vôs inte categorie \"$1\"",
+'categoryarticlecount' => "In cheste categorie tu puedis cjatâ $1 vôs.",
+'changepassword' => 'Gambie peraule clâf',
+'changed' => 'cambiade',
+'changes' => 'cambiaments',
+'compareselectedversions' => 'Confronte versions selezionadis',
+'confirm' => "Conferme",
+'confirmdelete' => "Conferme eliminazion",
+'confirmemail' => 'Conferme direzione di pueste',
+'confirmemail_text' => "Cheste wiki ti domande di valid la to direzion di pueste eletroniche prime di doprâ lis funzions di email. Ative il boton ca sot par inviâ un codiç di conferme ae to direzion. Chest messaç al includarà un leam cuntun codiç; cjame il leam tal to sgarfadôr par confermâ la validitât de tô direzion.",
+'confirmemail_send' => 'Mande un codiç di conferme',
+'confirmemail_sent' => 'Messaç di conferme mandât.',
+'confirmemail_success' => 'La tô direzion di pueste e je stade confermade. Tu puedis cumò jentrâ e gjoldi la wiki.',
+'confirmemail_loggedin' => 'La tô direzion di pueste e je stade confermade.',
+'confirmprotect' => "Conferme protezion",
+'confirmprotecttext' => "Vuelistu pardabon protezi cheste pagjine?",
+'confirmunprotect' => "Conferme par gjavâ la protezion",
+'confirmunprotecttext' => "Vuelistu pardabon gjavâ la protezion a cheste pagjine?",
+'contextlines' => 'Riis par risultât',
+'contributions' => "Contribûts dal utent",
+'contribslink' => 'contribûts',
+'contribsub' => "Par $1",
+'copyright' => "Il contignût al è disponibil sot de $1",
+/*'copyrightwarning' => "<!-- Perché i link non abbiano l'aspetto di link esterni: -->
+<div class=\"plainlinks\">
+
+<div style=\"margin-top:2em\">
+<div style=\"font-weight: bold; font-size: 120%;\">I cambiaments che tu âs fat a saran visibii daurman.</div>
+* Par plasê, dopre la [[{{ns:project}}:Sandbox|sandbox]] se tu vuelis fâ cualchi prove.
+----
+<p style=\"background: red; color: white; font-weight: bold; text-align: center; padding: 2px;\">'''NO STÂ DOPRÂ MATERIÂL CUVIERT DAL DIRIT DI AUTÔR (COPYRIGHT - ©) SE NO TU ÂS UNE AUTORIZAZION ESPLICITE!!!'''</p></div>
+
+* Sta atent, par plasê, che ducj i contribûts ae {{SITENAME}} a son considerâts come dâts fûr sot di une licence GNU Free Documentation License (cjale $1 par altris detais).
+* Se no tu vuelis che il to test al puedi jessi gambiât e tornât a jessi distribuît da cualsisei persone cence limits, no stâ mandâlu ae {{SITENAME}}, al è miôr se tu ti fasis un to sît web personâl.
+* Inviant chest test, tu stâs garantint che chest al è stât scrit di te in origjin, o che al è stât copiât di une sorzint di public domini, o alc di simil, opûr che tu âs vût une autorizazion esplicite pe publicazion e tu puedis dimostrâ chest fat.
+</div>
+
+</div>",*/
+'createaccount' => "Cree une gnove identitât",
+'createaccountmail' => 'par pueste eletroniche',
+'createarticle' => "Cree vôs",
+'created' => 'creade',
+'creditspage' => 'Pagjine dai ricognossiments',
+'cur' => "cor",
+'currentevents' => "Lis gnovis",
+'currentevents-url' => 'Lis gnovis',
+'data' => 'Dâts',
+'dateformat' => 'Formât de date',
+'datedefault' => 'Nissune preference',
+'datetime' => 'Date e ore',
+'deadendpages' => 'Pagjinis cence usite',
+'dec' => "Dic",
+'december' => "Dicembar",
+'default' => "predeterminât",
+'delete' => "Elimine",
+'delete_and_move' => 'Elimine e môf',
+'deletecomment' => 'Reson pe eliminazion',
+'deletedarticle' => "eliminât \"$1\"",
+'deletedtext' => "\"$1\" al è stât eliminât.
+Cjale $2 par une liste des ultimis eliminazions.",
+'deleteimg' => "eli",
+'deletepage' => "Elimine pagjine",
+'deletesub' => "(Eliminant \"$1\")",
+'deletethispage' => "Elimine cheste pagjine",
+'deletionlog' => 'regjistri eliminazions',
+'dellogpage' => 'Regjistri des eliminazions',
+'destfilename' => 'Non dal file di destinazion',
+'diff' => "difarencis",
+'difference' => "(Difarence jenfri des revisions)",
+'disambiguations' => 'Pagjinis di disambiguazion',
+'disambiguationspage' => 'Template:disambig',
+'disambiguationstext' => "Lis pagjinis ca sot a son leadis a une <i>pagjine di disambiguazion</i>. A dovaressin invezit jessi leadis al argoment apropriât.<br />Une pagjine e je tratade come di disambiguazion se e je leade di $1.<br />Leams di altris nons di spazi <i>no</i> son metûts inte liste.",
+'disclaimers' => "Avîs legâi",
+'doubleredirects' => 'Reindirizaments doplis',
+'download' => 'discjame',
+'edit-externally' => 'Modifiche chest file cuntune aplicazion esterne',
+'edit-externally-help' => 'Cjale [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] par altris informazions.',
+'edit' => "Cambie",
+'editconflict' => 'Conflit inte modifiche: $1',
+'explainconflict' => 'Cualchidun altri al à cambiât cheste pagjine di cuant che tu âs començât a modificâle.
+La aree di test disore e conten il test de pagjine che esist cumò, i tiei cambiaments a son mostrâts inte aree disot.
+Tu varâs di inserî di gnûf i tiei cambiaments tal test esistint.
+<b>Dome</b> il test in alt al vignarà salvât cuant che tu frachis su "Salve pagjine".<br />',
+'editcurrent' => 'Cambie la version corinte di cheste pagjine',
+'editing' => "Cambiament di $1",
+'editinguser' => "Cambiament di $1",
+'edithelp' => "Jutori pai cambiaments",
+'edithelppage' => "Jutori:Cambiaments",
+'editingold' => "<strong>ATENZION: tu stâs cambiant une version vecje e no inzornade di cheste pagjine. Se tu la salvis, ducj i cambiaments fats di chê volte in ca a laran pierdûts.</strong>",
+'editingsection' => "Cambiament di $1 (sezion)",
+'editsection' => "cambie",
+'editold' => "cambie",
+'editthispage' => "Cambie cheste pagjine",
+'email' => 'Pueste eletroniche',
+'emailauthenticated' => 'La tô direzion email e je stade autenticade su $1.',
+'emailconfirmlink' => 'Conferme la tô direzion email',
+'emailmessage' => "Messaç",
+'emailnotauthenticated' => 'La tô direzion email no je ancjemò autenticade. No vignaran mandâts messaçs pes funzions ca sot.',
+'emailuser' => "Messaç di pueste a chest utent",
+'error' => "Erôr",
+'errorpagetitle' => "Erôr",
+'exbeforeblank' => "il contignût prime di disvuedâ al jere: '$1'",
+'exblank' => 'pagjine vueide',
+'excontent' => "il contignût al jere: '$1'",
+'excontentauthor' => "il contignût al jere: '$1' (e al veve contribuît dome '$2')",
+'exif-compression-1' => 'Cence compression',
+'exif-imagewidth' =>'Largjece',
+'exif-imagelength' =>'Altece',
+'exif-model' =>'Model di machine fotografiche',
+'exif-software' =>'Software doprÂt',
+'export' => "Espuarte pagjinis",
+'exportcuronly' => 'Inclût dome la revision corinte, no dut il storic',
+'extlink_sample'=>'http://www.example.com titul leam',
+'extlink_tip'=>'Leam esterni (visiti dal prefìs http://)',
+'feb' => "Fev",
+'february' => "Fevrâr",
+'filedesc' => "Descrizion",
+'fileuploadsummary' => 'Somari:',
+'fileinfo' => '$1KB, gjenar MIME: <code>$2</code>',
+'filemissing' => "File mancjant",
+'filename' => "Non dal file",
+'filenotfound' => "No si pues cjatâ il file \"$1\".",
+'filesource' => 'Surzint',
+'filestatus' => 'Stât dal copyright',
+'friday' => "Vinars",
+'go' => "Va",
+'searcharticle' => "Va",
+'gotaccount' => 'Âstu za une identitât? $1.',
+'gotaccountlink' => 'Jentre',
+'guesstimezone' => "Cjape impostazions dal sgarfadôr",
+'headline_sample'=>'Test dal titul',
+'headline_tip'=>'Titul di nivel 2',
+'help' => "Jutori",
+'helppage' => "Jutori:Contignûts",
+'hide' => "plate",
+'hideresults' => 'Plate risultâts',
+'hidetoc' => "plate",
+'hist' => "stor",
+'history' => "Storic de pagjine",
+'history_short' => "Storic",
+'historywarning' => 'Atenzion: la pagjine che tu stâs eliminant e à un storic.',
+'hr_tip' => "Rie orizontâl (no stâ doprâle masse spes)",
+'ignorewarning' => 'Ignore avîs e salve instès il file.',
+'ignorewarnings' => 'Ignore i avîs',
+'ilsubmit' => "Cîr",
+'image_sample' => "Esempli.jpg",
+'image_tip'=> 'Figure includude',
+'imagelinks' => "Leams de figure",
+'imagelist' => "Liste des figuris",
+'imagelistall' => 'ducj',
+'imagelisttext' => "Ca sot e je une liste di $1 files ordenâts $2.",
+'imagepage' => "Cjale pagjine de figure",
+'imgdelete' => "eli",
+'imgdesc' => "desc",
+'imghistlegend' => "Legenda: (cor) = cheste e je la figure corinte, (eli) = elimine
+cheste vecje version, (rip) = torne a ripristinâ cheste vecje version.
+<br /><i>Frache su une date par viodi la figure cjamade su chê volte</i>.",
+'imghistory' => "Storic de figure",
+'imglegend' => "Legenda: (desc) = mostre/cambie descrizion de figure.",
+'import' => 'Impuarte pagjinis',
+'importfailed' => "Impuartazion falide: $1",
+'importnotext' => "Vueit o cence test",
+'importsuccess' => 'Impuartât cun sucès!',
+'info_short' => "Informazions",
+'infosubtitle' => 'Informazions pe pagjine',
+'intl' => 'Leams interlengâi',
+'invalidemailaddress' => 'La direzion email no pues jessi acetade parcè che no samee intun formât valid. Inserìs par plasê une direzion ben formatade o disvuede chel cjamp.',
+'invert' => "Invertìs selezion",
+'ipbsubmit' => "Bloche chest utent",
+'isbn' => "ISBN",
+'isredirect' => "pagjine di reindirizament",
+'istemplate' => 'includude',
+'italic_sample'=>'Test in corsîf',
+'italic_tip'=>'Test in corsîf',
+'jan' => "Zen",
+'january' => "Zenâr",
+'jul' => "Lui",
+'july' => "Lui",
+'jumpto' => 'Va a:',
+'jumptonavigation' => 'navigazion',
+'jumptosearch' => 'ricercje',
+'jun' => "Jug",
+'june' => "Jugn",
+'largefile' => "Si racomande che lis figuris no sedin pi grandis di $1KB ($2).",
+'last' => "ultime",
+'lastmodifiedat' => "Cambiât par l'ultime volte ai $2, $1",
+'lastmodifiedatby' => "Cambiât par l'ultime volte ai $2, $1 di",
+'lineno' => "Rie $1:",
+'link_sample' => "Titul dal leam",
+'link_tip' => "Leams internis",
+'linklistsub' => "(Liste di leams)",
+'linkshere' => "Lis pagjinis ca sot a son leadis a cheste:",
+'linkstoimage' => "Lis pagjinis ca sot a son leadis a cheste figure:",
+'listingcontinuesabbrev' => " cont.",
+'listredirects' => 'Liste des redirezions',
+'listusers' => "Liste dai utents",
+'localtime' => 'Ore locâl',
+'lockbtn' => "Bloche base di dâts",
+'lockdb' => "Bloche base di dâts",
+'log' => 'Regjistris',
+'logempty' => 'Nissun element corispondint tal regjistri.',
+'login' => "Jentre",
+'loginerror' => "Erôr te jentrade",
+'loginpagetitle' => "Jentrade dal utent",
+'loginprompt' => 'Tu âs di vê abilitâts i cookies par jentrâ in {{SITENAME}}.',
+'loginreqtitle' => 'Si scugne jentrâ',
+'loginreqlink' => 'jentrâ',
+'loginreqpagetext' => 'Tu scugnis $1 par viodi lis altris pagjinis.',
+'loginsuccess' => "Cumò tu sês jentrât te {{SITENAME}} sicu \"$1\".",
+'loginsuccesstitle' => "Jentrât cun sucès",
+'logout' => "Jes",
+'logouttitle' => 'Jessude dal utent',
+'logouttext' => '<strong>Tu sâs cumò lât fûr.</strong><br />Tu puedis continuâ a doprâ {{SITENAME}} come anonim, o tu puedis jentrâ cul stes o cuntun altri non utent. Note che cualchi pagjine e pues mostrâti ancjemò come jentrât tal sît fin cuant che no tu netis la cache dal sgarfadôr.',
+'lonelypages' => 'Pagjinis solitaris',
+'longpagewarning' => "<strong>ATENZION: cheste pagjine e je grande $1 kilobytes; cualchi sgarfadôr al podarès vê problemis a modificâ pagjinis di 32kb o plui grandis. Considere par plasê la pussibilitât di dividi la pagjine in sezions plui piçulis.</strong>",
+'longpages' => 'Pagjinis lungjis',
+'mailmypassword' => "Mandimi une gnove peraule clâf",
+'mainpage' => "Pagjine principâl",
+'mainpagetext' => "'''MediaWiki e je stade instalade cun sucès.'''",
+'march' => 'Març',
+'matchtotals' => "La ricercje \"$1\" e à cjatât $2 titui di pagjinis e il test di $3 pagjinis.",
+'math' => 'Matematiche',
+'math_sample'=>'Inserìs la formule culì',
+'math_tip'=>'Formule matematiche (LaTeX)',
+'may' => "Mai",
+'may_long' => "Mai",
+'media_sample' => "Esempli.mp3",
+'media_tip' => "Leam a un file multimediâl",
+'minlength' => "Il non di une figure al à di jessi lunc al mancul trê letaris.",
+'minoredit' => "Cheste al è un piçul cambiament",
+'minoreditletter' => "p",
+'mimesearch' => 'Ricercje MIME',
+'mimetype' => 'Gjenar MIME:',
+'missingimage' => "<b>Figure mancjante</b><br /><i>$1</i>",
+'monday' => "Lunis",
+'monobook.css' => '/* modifiche chest file par personalizâ la skin monobook par dut il sît */',
+'moredotdotdot' => 'Plui...',
+'mostlinked' => 'Pagjinis a cui pontin il maiôr numar di leams',
+'mostlinkedcategories' => 'Categoriis a cui pontin il maiôr numar di leams',
+'mostcategories' => 'Vôs cul maiôr numar di categoriis',
+'mostimages' => 'Figuris a cui pontin il maiôr numar di leams',
+'mostrevisions' => 'Vôs cul maiôr numar di revisions',
+'move' => "Môf",
+'movearticle' => "Môf la vôs",
+'movedto' => "Movude in",
+'movelogpage' => 'Regjistri des pagjinis movudis',
+'movelogpagetext' => 'Ca sot e je une liste des pagjinis movudis.',
+'movenologin' => "No tu sês jentrât",
+'movenologintext' => "Tu âs di jessi un utent regjistrât e <a href=\"{{localurl:Special:Userlogin}}\">jentrât</a> par movi une pagjine.",
+'movepage' => "Môf pagjine",
+'movepagetext' => 'Cun il formulari ca sot tu puedis gambiâ il non a une pagjine, movint dut il sô storic al gnûf non.
+Il vieri titul al deventarà une pagjine di reindirizament al gnûf titul. I leams ae vecje pagjine no saran gambiâts; verifiche
+par plasê che no sedin reindirizaments doplis o no funzionants.
+Tu sês responsabil che i leams a continui a mandâ tal puest just.
+
+Note che la pagjine \'\'\'no\'\'\' sarà movude se e je za une pagjine cul gnûf titul, a mancul che no sedi vueide o un reindirizament e
+cence un storic. Chest al vûl dî che tu puedis tornâ a movi la pagjine tal titul precedent, se
+tu \'nd âs sbaliât e che no tu puedis sorescrivi une pagjine esistìnte.
+
+<b>ATENZION!</b>
+Chest al pues jessi un cambiament drastic e surprendint par une pagjine popolâr;
+tu âs di cognossi lis conseguencis prime di lâ indevant.',
+'movepagebtn' => "Môf pagjine",
+'movereason' => 'Reson',
+'movetalk' => 'Môf ancje la pagjine di discussion, se pussibil.',
+'movethispage' => "Môf cheste pagjine",
+'mw_math_png' => 'Torne simpri PNG',
+'mw_math_simple' => 'HTML se une vore sempliç, se no PNG',
+'mw_math_html' => 'HTML se pussibil se no PNG',
+'mw_math_source' => 'Lassile come TeX (par sgarfadôrs testuâi)',
+'mw_math_modern' => 'Racomandât pai sgarfadôrs testuâi',
+'mw_math_mathml' => 'MathML se pussibil (sperimentâl)',
+'mycontris' => "Miei contribûts",
+'mypage' => "Mê pagjine",
+'mytalk' => "Mês discussions",
+'navigation' => "somari",
+'nbytes' => "$1 bytes",
+'namespace' => 'Non dal spazi:',
+'namespacesall' => 'ducj',
+'newarticle' => "(Gnûf)",
+'newarticletext' => "Tu âs seguît un leam a une pagjine che no esist ancjemò. Par creâ une pagjine, scomence a scrivi tal spazi ca sot (cjale il [[Jutori:Contignûts|jutori]] par altris informazions). Se tu sês ca par erôr, frache semplicementri il boton '''Indaûr''' dal to sgarfadôr.",
+'newimages' => "Galarie dai gnûfs files",
+'newmessagesdifflink' => 'difarencis cu la penultime revision',
+'newmessageslink' => 'gnûfs messaçs',
+'newpage' => "Gnove pagjine",
+'newpageletter' => "G",
+'newpages' => "Gnovis pagjinis",
+'newpassword' => 'Gnove peraule clâf',
+'newtitle' => "Al gnûf titul",
+'newwindow' => "(al vierç un gnûf barcon)",
+'nextdiff' => "Prossime difarence &rarr;",
+'next' => 'prossim',
+'nextn' => "prossims $1",
+'nextpage' => 'Prossime pagjine ($1)',
+'nlinks' => "$1 leams",
+'noarticletext' => "(Par cumò nol è nuie in cheste pagjine)",
+'noconnect' => 'Nus displâs, ma il sît al à al moment cualchi dificoltât tecniche e nol pues conetisi al servidôr de base di dâts. <br />$1',
+'nocontribs' => 'Nissun cambiament che al rispiete chescj criteris cjatât.',
+'nocookiesnew' => 'L\'identitât utent e je stade creade, ma no tu sês jentrât. {{SITENAME}} al dopre i cookies par visâsi dai utents, e tu tu ju âs disabilitâts. Par plasê abilitiju, dopo jentre cul to gnûf non utent e password.',
+'nocookieslogin' => '{{SITENAME}} e dopre i cookies par visâsi dai utents, e tu tu ju âs disabilitâts. Par plasê abilitiju e torne a provâ.',
+'nocredits' => 'Nissune informazion sui ricognossiments disponibil par cheste pagjine.',
+'nodb' => 'No si pues selezionâ la base di dâts $1',
+'noemail' => 'Nissune direzion email regjistrade par l\'utent "$1".',
+'noemailtitle' => 'Nissune direzion email',
+'noemailprefs' => '<strong>Specifiche une direzion email par fâ lâ cheste funzion.</strong>',
+'noemailtext' => 'Chest utent nol à specificât une direzion di pueste valide o al à sielzût di no ricevi pueste di altris utents.',
+'noexactmatch' => "'''No esist une pagjine cul titul \"$1\".''' Tu podaressis [[:$1|creâle tu]].",
+'nohistory' => "Nol è presint un storic dai cambiaments par cheste pagjine.",
+'noimages' => "Nuie di viodi.",
+'nolinkshere' => "Nissune pagjine e à leams a cheste vôs",
+'nolinkstoimage' => 'No son pagjinis leadis a chest file.',
+'nologin' => 'No tu âs ancjemò une identitât par jentrâ? $1.',
+'nologinlink' => 'Creile cumò',
+'noname' => 'No tu âs inserît un non utent valit.',
+'notextmatches' => 'Nissune corispondence tal test des pagjinis',
+'notitlematches' => 'Nissune corispondence tai titui des pagjinis',
+'nowatchlist' => 'No tu stâs tignint di voli nissun element.',
+'nowiki_sample'=> 'Inserìs test no formatât culì',
+'nowiki_tip'=> 'Ignore la formatazion wiki',
+'nov' => "Nov",
+'november' => "Novembar",
+'nowatchlist' => "Nissun element al è tignût di voli.",
+'nstab-category' => "Categorie",
+'nstab-help' => "Jutori",
+'nstab-image' => "Figure",
+'nstab-main' => "Vôs",
+'nstab-media' => "Media",
+'nstab-mediawiki' => "Messaç",
+'nstab-special' => "Speciâl",
+'nstab-template' => "Model",
+'nstab-user' => "Pagjine dal utent",
+'nstab-project' => "Informazions",
+'numauthors' => 'Numar di autôrs diviers (vôs): $1',
+'numedits' => 'Numar di cambiaments (vôs): $1',
+'numtalkauthors' => 'Numar di autôrs diviers (pagjine di discussion): $1',
+'numtalkedits' => 'Numar di cambiaments (pagjine di discussion): $1',
+'numwatchers' => 'Numar di chei che e àn cjalât: $1',
+'oct' => "Otu",
+'october' => "Otubar",
+'ok' => "OK",
+'oldpassword' => 'Vecje peraule clâf',
+'orig' => "orig",
+'othercontribs' => 'Basât sul lavôr di $1.',
+'otherlanguages' => "Altris lenghis",
+'others' => 'altris',
+'pagecategories' => "Categoriis",
+'pagemovedsub' => 'Movude cun sucès',
+'pagemovedtext' => "Pagjine \"[[$1]]\" movude in \"[[$2]]\".",
+'passwordtooshort' => "La tô peraule clâf e je masse curte, e à di jessi lungje almancul $1 caratars.",
+'permalink' => 'Leam permanent',
+'personaltools' => 'Imprescj personâi',
+'popularpages' => 'Pagjinis popolârs',
+'postcomment' => 'Zonte un coment',
+'portal' => "Ostarie",
+'portal-url' => "{{ns:project}}:Ostarie",
+'powersearch' => "Cîr",
+'powersearchtext' => "
+Cîr tai nons dai spazis :<br />
+$1<br />
+$2 Liste redirezions &nbsp; Cîr $3 $9",
+'preferences' => "Preferencis",
+'prefs-personal' => 'Dâts utents',
+'prefs-rc' => 'Ultins cambiaments & stubs',
+'prefs-misc' => 'Variis',
+'prefs-help-realname' => "* Non vêr (opzionâl): se tu sielzis di inserîlu al vignarà doprât par dâti un ricognossiment dal tô lavôr.",
+'prefs-help-email-enotif' => 'Cheste direzion e ven ancje doprade par inviâti un messaç di notifiche se tu âs ativât chê opzion.',
+'prefs-help-email' => "* Email (opzionâl): Permet ai altris di contatâti vie la to pagjine utent o di discussion cence scugnî mostrâ a ducj la tô identitât.",
+'prefs-watchlist' => 'Tignudis di voli',
+'prefs-watchlist-days' => 'Numar di zornadis di mostrâ inte liste des pagjinis tignudis di voli:',
+'prefs-watchlist-edits' => 'Numar di modifichis di mostrâ inte liste slargjade:',
+'prevn' => "precedents $1",
+'preview' => "Anteprime",
+'previewnote' => "Visiti che cheste e je dome une anteprime, e no je stade ancjemò salvade!",
+'previousdiff' => "&larr; Difarence precedente",
+'printableversion' => "Version stampabil",
+'privacy' => 'Politiche pe privacy',
+'privacypage' => 'Project:Politiche_pe_privacy',
+'protect' => "Protêç",
+'protectcomment' => "Reson pe protezion",
+'protectedarticle' => "$1 protezût",
+'protectedpage' => "Pagjine protezude",
+'protectedtext' => "Cheste pagjine e je stade blocade par prevignî cambiaments; a son
+diviersis resons par chest fat, cjale par plasê
+[[Project:Pagjinis protezudis]].
+
+Tu puedis instès viodi e copiâ la risultive di cheste pagjine:",
+'protectmoveonly' => "Protêç dome dai spostaments",
+'protectsub' => "(Protezint \"$1\")",
+'protectthispage' => "Protêç cheste pagjine",
+'qbbrowse' => "Sgarfe",
+'qbedit' => "Cambie",
+'qbfind' => "Cjate",
+'qbmyoptions' => "Mês pagjinis",
+'qbpageinfo' => "Contest",
+'qbpageoptions' => "Cheste pagjine",
+'qbsettings' => "Sbare svelte",
+'qbspecialpages' => "Pagjinis speciâls",
+'randompage' => "Une pagjine a câs",
+'rclinks' => "Mostre i ultins $1 cambiaments tes ultimis $2 zornadis<br />$3",
+'rclistfrom' => "Mostre i ultins cambiaments dal $1",
+'rcnote' => "Ca sot tu cjatis i ultins <strong>$1</strong> cambiaments tes ultimis <strong>$2</strong> zornadis.",
+'rcshowhidebots' => '$1 bots',
+'rcshowhideliu' => '$1 utents jentrâts',
+'rcshowhideanons' => '$1 utents anonims',
+'rcshowhidepatr' => '$1 cambiaments verificâts',
+'rcshowhidemine' => '$1 miei cambiaments',
+'readonlytext' => 'La base di dâts pal moment e je blocade e no si puedin zontâ vôs e fâ modifichis, probabilmentri pe normâl manutenzion de base di dâts, daspò de cuâl dut al tornarà normâl.
+
+L\'aministradôr ch\'al à metût il bloc al à scrit cheste motivazion: $1',
+'recentchanges' => "Ultins cambiaments",
+'recentchangesall' => 'ducj',
+'recentchangescount' => "Numar di titui tai ultins cambiaments",
+'recentchangeslinked' => "Cambiaments leâts",
+'recentchangestext' => "Cheste pagjine e mostre i plui recents cambiaments inte {{SITENAME}}.",
+'rclsub' => "(aes pagjinis leadis di \"$1\")",
+'redirectedfrom' => "(Inviât ca di $1)",
+'redirectpagesub' => 'Pagjine di redirezion',
+'remembermypassword' => "Visiti di me",
+'removedwatch' => 'Gjavade de liste',
+'removedwatchtext' => "La pagjine \"$1\" e je stade gjavade de liste di chês tignudis di voli.",
+'resetprefs' => 'Predeterminât',
+'restorelink' => "$1 modifichis eliminadis",
+'restrictedpheading' => 'Pagjinis speciâls cun restrizions',
+'restriction-edit' => 'Cambie',
+'restriction-move' => 'Spostament',
+'resultsperpage' => 'Risultâts par pagjine',
+'retrievedfrom' => "Cjapât fûr di $1",
+'returnto' => "Torne a $1.",
+'retypenew' => 'Torne a scrivi chê gnove',
+'reupload' => "Torne a cjamâ sù",
+'revertimg' => "rip",
+'revertmove' => 'ripristine',
+'revhistory' => "Storic des revisions",
+'rows' => "Riis",
+'saturday' => "Sabide",
+'savearticle' => "Salve la pagjine",
+'savedprefs' => "Lis preferencis a son stadis salvadis",
+'savefile' => "Salve file",
+'saveprefs' => "Salve lis preferencis",
+'scarytranscludedisabled' => '[Inclusion dai interwikis no ative]',
+'scarytranscludefailed' => '[Recupar dal model falît par $1; o si scusin]',
+'scarytranscludetoolong' => '[URL masse lungje; o si scusin]',
+'search' => "Cîr",
+'searchbutton' => "Cîr",
+'searchdisabled' => 'La ricercje in {{SITENAME}} no je ative. Tu puedis doprâ Google intant. Sta atent che i lôr indis sul contignût di {{SITENAME}} a puedin jessi pôc inzornâts.',
+'searchresults' => "Risultâts de ricercje",
+'searchresulttext' => "Par plui informazions su lis ricercjis in {{SITENAME}}, cjale [[Project:Ricercje|Ricercje in {{SITENAME}}]].",
+'searchsubtitle' => "Pal test \"[[:$1]]\"",
+'searchsubtitleinvalid' => "Pal test \"$1\"",
+'sep' => "Set",
+'september' => "Setembar",
+'servertime' => 'Ore servidôr',
+'sharedupload' => 'Chest file al è condivîs e al pues jessi doprât di altris progjets.',
+'shareduploadwiki' => 'Cjale par plasê la [pagjine di descrizion dal file $1] par altris informazions.',
+'shortpages' => 'Pagjinis curtis',
+'show' => "mostre",
+'showbigimage' => "Discjame version a alte risoluzion ($1x$2, $3 KB)",
+'showdiff' => 'Mostre cambiaments',
+'showingresults' => "Ca sot a son fin a <b>$1</b> risultâts scomençant dal #<b>$2</b>.",
+'showingresultsnum' => "Ca sot a son <b>$3</b> risultâts scomençant dal #<b>$2</b>.",
+'showlast' => "Mostre i ultins $1 files ordenâts $2.",
+'showpreview' => "Mostre anteprime",
+'showtoc' => "mostre",
+'sig_tip' => "La tô firme cun ore e date",
+'sitestats' => "Statistichis dal sît",
+'sitestatstext' => "Tu puedis cjatâ in dut '''$1''' pagjine inte base di dâts.
+Chest numar al inclût pagjinis \"discussion\", pagjinis su la {{SITENAME}}, pagjinis cun pocjis peraulis, reindirizaments, e altris che probabilmentri no si puedin considerâ pardabon come pagjinis di contignût.
+Gjavant chestis, o vin '''$2''' pagjinis che a son probabilmentri pagjinis di contignût legjitimis.
+
+'''$8''' files a son stâts cjamâts sù.
+
+O vin vût in dut '''$3''' viodudis de pagjinis e '''$4''' cambiaments aes pagjinis di cuant che la wiki e je stade implantade.
+Chest al vûl dî une medie di '''$5''' cambiaments par pagjine, e '''$6''' viodudis par ogni cambiament.",
+'sitesupport' => 'Doninus',
+'sitesupport-url' => 'Project:Supuarte il sît',
+'siteuser' => 'Utent $1 di {{SITENAME}}',
+'siteusers' => 'Utents $1 di {{SITENAME}}',
+'skin' => 'Mascare',
+'skinpreview' => '(Anteprime)',
+'sourcefilename' => 'Non dal file origjinâl',
+'specialloguserlabel' => "Utent:",
+'speciallogtitlelabel' => "Titul:",
+'specialpage' => "Pagjine speciâl",
+'specialpages' => "Pagjinis speciâls",
+'spheading' => 'Pagjinis speciâls par ducj i utents',
+'statistics' => "Statistichis",
+'subcategories' => "Sot categoriis",
+'successfulupload' => "Cjamât sù cun sucès",
+'summary' => "Somari",
+'sunday' => "Domenie",
+'tagline' => "Di {{SITENAME}}",
+'talk' => "Discussion",
+'talkexists' => "'''La pagjine e je stade movude cun sucès, ma no si à podût movi la pagjine di discussion parcè che e esist za tal gnûf titul. Trasferìs il contignût a man par plasê.'''",
+'talkpage' => "Fevelin di cheste pagjine",
+'talkpagemoved' => "Ancje la pagjine di discussion corispondente e je stade movude.",
+'talkpagenotmoved' => "La pagjine di discussion corispondente <strong>no</strong> je stade movude.",
+'templatesused' => "Modei doprâts par cheste pagjine:",
+'textboxsize' => "Cambiament",
+'textmatches' => 'Corispondencis tal test des pagjinis',
+'thisisdeleted' => "Vuelistu cjalâ o ripristinâ $1?",
+'thumbnail-more' => "Slargje",
+'thumbnail_error' => 'Erôr inte creazion de miniature: $1',
+'thumbsize' => 'Dimension miniature:',
+'thursday' => "Joibe",
+'timezonelegend' => "Fûs orari",
+'timezonetext' => 'Il numar di oris di diference rispiet ae ore dal servidôr (UTC).',
+'titlematches' => 'Corispondencis tai titui des pagjinis',
+'toc' => "Indis",
+'tog-highlightbroken' => 'Mostre leams sbaliâts <a href="" class="new">cussì</a> (invezit di cussì<a href="" class="internal">?</a>).',
+'tog-justify' => 'Justifiche paragraf',
+'tog-hideminor' => 'Plate lis piçulis modifichis tai ultins cambiaments',
+'tog-usenewrc' => 'Ultins cambiaments avanzâts (JavaScript)',
+'tog-numberheadings' => 'Numerazion automatiche dai titui',
+'tog-editondblclick' => 'Cambie lis pagjinis fracant dôs voltis (JavaScript)',
+'tog-editsection' => 'Inserìs un leam [cambie] pe editazion veloç di une sezion',
+'tog-editsectiononrightclick' => 'Modifiche une sezion fracant cul tast diestri<br /> sui titui des sezions (JavaScript)',
+'tog-showtoc' => 'Mostre indis (par pagjinis cun plui di 3 sezions)',
+'tog-editwidth' => 'Il spazi pe modifiche al è larc il plui pussibil',
+'tog-minordefault' => 'Imposte come opzion predeterminade ducj i cambiaments come piçui',
+'tog-previewontop' => 'Mostre anteprime parsore dal spazi pe modifiche',
+'tog-previewonfirst' => 'Mostre anteprime te prime modifiche',
+'tog-nocache' => 'No stâ tignî in memorie (caching) lis pagjinis',
+'tog-enotifwatchlistpages' => 'Mandimi une email se la pagjine e gambie',
+'tog-enotifusertalkpages' => 'Mandimi une email cuant che la mê pagjine di discussion e gambie',
+'tog-enotifminoredits' => 'Mandimi une email ancje pai piçui cambiaments ae pagjine',
+'tog-enotifrevealaddr' => 'Distapone fûr il gno recapit email tai messaçs di notifiche',
+'tog-shownumberswatching' => 'Mostre il numar di utents che a stan tignint di voli',
+'tog-fancysig' => 'Firmis crudis (cence leam automatic)',
+'tog-externaleditor' => 'Dopre editôr esterni come opzion predeterminade',
+'tog-externaldiff' => 'Dopre editôr difarencis esterni come opzion predeterminade',
+'tog-rememberpassword' => 'Visiti tes prossimis sessions',
+'tog-showtoolbar' => 'Mostre sbare dai imprescj pe modifiche (JavaScript)',
+'tog-underline' => 'Sotlinee leams',
+'tog-watchdefault' => 'Zonte in automatic lis pagjinis che o cambii inte liste di chês tignudis di voli',
+'toolbox' => "imprescj",
+'tooltip-compareselectedversions' => 'Viôt lis difarencis framieç lis dôs versions di cheste pagjine selezionadis. [alt-v]',
+'tooltip-diff' => 'Mostre i cambiaments che tu âs fat al test. [alt-v]',
+'tooltip-minoredit' => "Segne cheste come une piçul cambiament [alt-i]",
+'tooltip-preview' => "Anteprime dai tiei cambiaments, doprile par plasê prime di salvâ! [alt-p]",
+'tooltip-save' => "Salve i tiei cambiaments [alt-s]",
+'tooltip-search' => "Cîr in cheste wiki [alt-f]",
+'tooltip-watch' => "Zonte cheste pagjine ae liste di chês tignudis di voli [alt-w]",
+'tuesday' => "Martars",
+'ucnote' => "Ca sot a son i ultins <b>$1</b> cambiaments dal utent tes ultimis <b>$2</b> zornadis.",
+'uclinks' => "Viôt i ultins $1 cambiaments; viôt lis ultimis $2 zornadis.",
+'uctop' => " (su)",
+'uid' => 'ID utent:',
+'uncategorizedpages' => 'Pagjinis cence categorie',
+'uncategorizedcategories' => 'Categoriis cence categorie',
+'undelete_short' => 'Recupere $1 modifichis eliminadis',
+'underline-always' => "Simpri",
+'underline-never' => "Mai",
+'underline-default' => "Predeterminât dal sgarfadôr",
+'unusedimages' => 'Files no doprâts',
+'unusedtemplates' => 'Modei no doprâts',
+'unwatch' => 'No stâ tignî di voli',
+'unwatchthispage' => 'No stâ tignî di voli plui',
+'updated' => "(Inzornât)",
+'updatedmarker' => 'inzornât de mê ultime visite',
+'upload' => "Cjame sù un file",
+'uploadbtn' => "Cjame sù un file",
+'uploaddisabled' => "Nus displâs, par cumò no si pues cjamâ sù robe.",
+'uploaddisabledtext' => 'Lis cjamadis a son disativâts su cheste wiki.',
+'uploadedfiles' => "Files cjamâts sù",
+'uploadedimage' => "cjamât sù \"$1\"",
+'uploaderror' => "Erôr cjamant sù",
+'uploadlog' => 'regjistri cjamâts sù',
+'uploadlogpagetext' => 'Ca sot e je une liste dai file cjamâts su di recent.',
+'uploadnologin' => 'No jentrât',
+'uploadtext' => "Dopre la form ca sot par cjamâ sù un file, par cjalâ o cirî i files cjamâts sù in precedence va te [[Special:Imagelist|liste dai files cjamâts sù]], lis cjamadis e lis eliminazions a son ancje regjistrâts tal [[Special:Log/upload|regjistri des cjamadis]].
+
+Par includi une figure intune pagjine, dopre un leam inte form
+'''<nowiki>[[{{ns:6}}:file.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:6}}:file.png|alt text]]</nowiki>''' or
+'''<nowiki>[[{{ns:-2}}:file.ogg]]</nowiki>''' par un leam diret al file.",
+'userexists' => "Il non utent inserît al è za doprât. Sielç par plasê un non diferent.",
+'userlogin' => "Regjistriti o jentre",
+'userlogout' => "Jes",
+'userpage' => "Cjale pagjine dal utent",
+'userstats' => "Statistichis dai utents",
+'userstatstext' => "A son '''$1''' utents regjistrâts, di chescj '''$2''' (il '''$4%''') a son aministradôrs (cjale $3).",
+'version' => "Version",
+'viewcount' => "Cheste pagjine e je stade viodude $1 voltis.",
+'viewdeleted' => 'Vuelistu viodi $1?',
+'viewprevnext' => "Cjale ($1) ($2) ($3).",
+'viewsource' => "Cjale risultive",
+'wantedpages' => 'Pagjinis desideradis',
+'watch' => "Ten di voli",
+'watchlist' => "Tignûts di voli",
+'watchlistall1' => "ducj",
+'watchlistall2' => "dutis",
+'watchlistcontains' => "Tu stâs tignint di voli $1 pagjinis.",
+'watchnochange' => 'Nissun element di chei tignûts di voli al è stât cambiât tal periodi mostrât.',
+'watchdetails' => "* $1 pagjinis tignudis di voli cence contâ lis pagjinis di discussion
+* [[Special:Watchlist/edit|Mostre e modfiche la liste complete]]",
+'watchnologin' => 'No tu sês jentrât',
+'watchnologintext' => "Tu 'nd âs di [[Speciâl:Userlogin|jentrâ]] par modificâ la liste des pagjinis tignudis di voli.",
+'watchthis' => "Ten di voli cheste pagjine",
+'watchthispage' => "Ten di voli cheste pagjine",
+'wednesday' => "Miercus",
+'welcomecreation' => "== Mandi e benvignût $1! ==
+
+La tô identitât e je stade creade. No stâ dismenteâti di gambiâ lis preferencis di {{SITENAME}}.",
+'whatlinkshere' => "Leams a cheste vôs",
+'projectpage' => "Cjale pagjine dal progjet",
+'wlheader-enotif' => "* Notifiche par pueste eletroniche ativade.",
+'wlheader-showupdated' => "* Lis pagjinis gambiadis de ultime volte che tu lis âs cjaladis a son mostradis in '''gruessut'''",
+'wlnote' => 'Ca sot a son i ultins $1 cambiaments tes ultimis <b>$2</b> oris.',
+'wlshowlast' => 'Mostre ultimis $1 oris $2 zornadis $3',
+'wlsaved' => 'Cheste e je une version salvade de liste da lis pagjinis tignudis di voli.',
+'wlhideshowown' => '$1 i miei cambiaments.',
+'wrongpassword' => "La peraule clâf zontade no je juste. Torne par plasê a provâ.",
+'youhavenewmessages' => 'Tu âs $1 ($2).',
+'youhavenewmessagesmulti' => "Tu âs gnûfs messaçs su $1",
+'yourdiff' => "Difarencis",
+'youremail' => "Email *",
+'yourlanguage' => "Lenghe di mostrâ",
+'yourdomainname' => 'Il to domini',
+'yourname' => 'Non utent',
+'yourpassword' => "Peraule clâf",
+'yourpasswordagain' => "Torne a scrivile",
+'yourrealname' => "Non vêr *",
+'yourvariant' => 'Varietât',
+);
+
+
+?>
diff --git a/languages/messages/MessagesFy.php b/languages/messages/MessagesFy.php
new file mode 100644
index 000000000000..39b1d065bf48
--- /dev/null
+++ b/languages/messages/MessagesFy.php
@@ -0,0 +1,868 @@
+<?php
+/** Frisian (Frysk)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+$quickbarSettings = array(
+ 'Ut', 'Lofts fêst', 'Rjochts fêst', 'Lofts sweevjend'
+);
+
+$skinNames = array(
+ 'standard' => 'Standert',
+ 'nostalgia' => 'Nostalgy',
+);
+
+$datePreferences = array(
+ 'default',
+ 'fy normal',
+ 'ISO 8601',
+);
+
+$defaultDateFormat = 'fy normal';
+
+$dateFormats = array(
+ 'fy normal time' => 'H.i',
+ 'fy normal date' => 'j M Y',
+ 'fy normal both' => 'j M Y, H.i',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'fy normal',
+ 'fy normal',
+ 'fy normal',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Wiki',
+ NS_MAIN => '',
+ NS_TALK => 'Oerlis',
+ NS_USER => 'Meidogger',
+ NS_USER_TALK => 'Meidogger_oerlis',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_oerlis',
+ NS_IMAGE => 'Ofbyld',
+ NS_IMAGE_TALK => 'Ofbyld_oerlis',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_oerlis',
+ NS_TEMPLATE => 'Berjocht',
+ NS_TEMPLATE_TALK => 'Berjocht_oerlis',
+ NS_HELP => 'Hulp',
+ NS_HELP_TALK => 'Hulp_oerlis',
+ NS_CATEGORY => 'Kategory',
+ NS_CATEGORY_TALK => 'Kategory_oerlis'
+);
+
+$namespaceAliases = array(
+ 'Brûker' => NS_USER,
+ 'Brûker_oerlis' => NS_USER_TALK,
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = '/^([a-zàáèéìíòóùúâêîôûäëïöü]+)(.*)$/sDu';
+
+
+$messages = array(
+# User Toggles
+
+"tog-underline" => "Keppelings ûnderstreekje",
+"tog-highlightbroken" => "Keppelings nei lege siden ta <a href=\"\" class=\"new\">read</a> (oars mei in fraachteken<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Paragrafen útfolje",
+"tog-hideminor" => "Tekstwizigings wei litte út 'Koarts feroare'",
+"tog-usenewrc" => "Utwreide ferzje fan 'Koarts feroare' brûke (net mei alle blêdzjers mooglik)",
+"tog-numberheadings" => "Koppen fansels nûmerje",
+"tog-showtoolbar" => "Show edit toolbar",
+"tog-editondblclick" => "Dûbelklik jout bewurkingsside (freget JavaScript)",
+"tog-editsection" => "Jou [bewurk]-keppelings foar seksjebewurking",
+"tog-editsectiononrightclick" => "Rjochtsklik op sekjsetitels jout seksjebewurking (freget JavaScript)",
+"tog-showtoc" => "Ynhâldsopjefte, foar siden mei mear as twa koppen",
+"tog-rememberpassword" => "Oare kear fansels oanmelde",
+"tog-editwidth" => "Bewurkingsfjild sa breed as de side",
+"tog-watchdefault" => "Sides dy't jo feroare hawwe folgje",
+"tog-minordefault" => "Feroarings yn it earst oanjaan as tekstwizigings.",
+"tog-previewontop" => "By it neisjen, bewurkingsfjild ûnderoan sette",
+"tog-nocache" => "Gjin oerslag brûke",
+# Dates
+'sunday' => 'snein',
+'monday' => 'moandei',
+'tuesday' => 'tiisdei',
+'wednesday' => 'woansdei',
+'thursday' => 'tongersdei',
+'friday' => 'freed',
+'saturday' => 'sneon',
+'january' => 'jannewaris',
+'february' => 'febrewaris',
+'march' => 'maart',
+'april' => 'april',
+'may_long' => 'maaie',
+'june' => 'juny',
+'july' => 'july',
+'august' => 'augustus',
+'september' => 'septimber',
+'october' => 'oktober',
+'november' => 'novimber',
+'december' => 'decimber',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dec',
+
+
+# Bits of text used by many pages:
+#
+"mainpage" => "Haadside",
+"mainpagetext" => "Wiki-programma goed installearre.",
+"about" => "Ynfo",
+"aboutsite" => "Oer de {{SITENAME}}",
+"aboutpage" => "{{ns:project}}:Ynfo",
+"help" => "Help",
+"helppage" => "{{ns:project}}:Help",
+"bugreports" => "Brekmelding",
+"bugreportspage" => "{{ns:project}}:Brekmelding",
+"faq" => "FAQ",
+"faqpage" => "{{ns:project}}:FAQ",
+"edithelp" => "Siden bewurkje",
+"edithelppage" => "{{ns:project}}:Bewurk-rie",
+"cancel" => "Ferlitte",
+"qbfind" => "Sykje",
+"qbbrowse" => "Blêdzje",
+"qbedit" => "Bewurkje",
+"qbpageoptions" => "Side-opsjes",
+"qbpageinfo" => "Side-ynfo",
+"qbmyoptions" => "Myn Opsjes",
+"mypage" => "Myn side",
+"mytalk" => "Myn oerlis",
+"currentevents" => "Hjoeddeis",
+"errorpagetitle" => "Fout",
+"returnto" => "Werom nei \"$1\".",
+"whatlinkshere" => "Siden mei in keppeling hjirhinne",
+"help" => "Help",
+"search" => "Sykje",
+"searchbutton" => "Sykje",
+"go" => "Side",
+'searcharticle' => "Side",
+"history" => "Sideskiednis",
+"printableversion" => "Ofdruk-ferzje",
+"editthispage" => "Side bewurkje",
+"deletethispage" => "Side wiskje",
+"protectthispage" => "Side beskermje",
+"newpage" => "Nije side",
+"talkpage" => "Sideoerlis",
+"postcomment" => "Skrieuw in opmerking",
+"articlepage" => "Side lêze",
+"userpage" => "Brûkerside",
+"projectpage" => "Metaside",
+"imagepage" => "Ofbyldside",
+"viewtalkpage" => "Oerlisside",
+"otherlanguages" => "Oare talen",
+"redirectedfrom" => "(Trochwiisd fan \"$1\")",
+"lastmodifiedat" => "Lêste kear bewurke op $2, $1.",
+"viewcount" => "Disse side is $1 kear iepenslein.",
+"protectedpage" => "Beskerme side",
+"nbytes" => "$1 byte",
+"ok" => "Goed",
+"retrievedfrom" => "Untfongen fan \"$1\"",
+"editsection" => "edit",
+"editold" => "edit",
+"toc" => "Ynhâld",
+"showtoc" => "sjen litte",
+"hidetoc" => "net sjen litte",
+"thisisdeleted" => "\"$1\" lêze of werombringje?",
+"restorelink" => "$1 wiske ferzjes",
+
+# Main script and global functions
+#
+"nosuchaction" => "Unbekende aksje.",
+"nosuchactiontext" => "De aksje dy't jo oanjoegen fia de URL is net bekind by it Wiki-programma",
+"nosuchspecialpage" => "Unbekende side",
+"nospecialpagetext" => "Jo hawwe in Wiki-side opfrege dy't net bekind is by it Wiki-programma.",
+
+
+# General errors
+#
+"error" => "Fout",
+"databaseerror" => "Databankfout",
+"dberrortext" => "Sinboufout in databankfraach.
+De lêst besochte databankfraach wie:
+<blockquote><tt>$1</tt></blockquote>
+fan funksje \"<tt>$2</tt>\" út.
+MySQL joech fout \"<tt>$3: $4</tt>\" werom.",
+
+"dberrortextcl" => "Sinboufout in databankfraach.
+De lêst besochte databankfraach wie:
+\"$1\"
+fan funksje \"$2\" út.
+MySQL joech fout \"<tt>$3: $4</tt>\" werom.",
+
+"noconnect" => "Sorry! Troch in fout yn de technyk, kin de Wiki gjin ferbining meitsje mei de databanktsjinner.",
+"nodb" => "Kin databank \"$1\" net berikke.",
+"cachederror" => "Dit is in ferzje út de oerslag, mar it kin wêze dat dy ferâldere is.",
+"readonly" => "Databank is Net-skriuwe",
+"enterlockreason" => "Skriuw wêrom de databank net-skriuwe makke is,
+en sawat hoenear't de men wêr skriuwe kin",
+"readonlytext" => "De {{SITENAME}} databank is ôfsletten foar nije siden en oare wizigings,
+nei alle gedachten is it foar ûnderhâld, en kinne jo der letter gewoan wer brûk fan meitsje.
+De behearder hat dizze útlis joen:
+<p>$1</p>",
+
+"missingarticle" => "De databank kin in side net fine, nammentlik: \"$1\".
+<p>Faak is dit om't in âlde ferskil-, of skiednisside opfreege wurdt fan in side dy't wiske is.
+<p>As dat it hjir net is, dan hawwe jo faaks in brek yn it programa fûn.
+Jou dat asjebleaft troch oan de [[{{ns:project}}:Brekmelding|behearder]], tegearre mei de URL.",
+
+"internalerror" => "Ynwindige fout",
+"filecopyerror" => "Koe bestân \"$1\" net kopiearje as \"$2\".",
+"filerenameerror" => "Koe bestân \"$1\" net werneame as \"$2\".",
+"filedeleteerror" => "Koe bestân \"$1\" net wiskje.",
+"filenotfound" => "Koe bestân \"$1\" net fine.",
+"unexpected" => "Hommelse wearde: \"$1\"=\"$2\".",
+"formerror" => "Fout: koe formulier net oerlizze",
+"badarticleerror" => "Dit kin op dizze side net dien wurden.",
+"cannotdelete" => "Koe de oantsjutte side of ôfbyld net wiskje. (Faaks hat in oar dat al dien.)",
+"badtitle" => "Misse titel",
+"badtitletext" => "De opfreeche side titel wie ûnjildich, leech, of in
+miskeppele ynter-taal of ynter-wiki titel.",
+"perfdisabled" => "Sorry! Dit ûnderdiel is tydlik út set om't it de databank sa starich makket
+dat gjinien de wiki brûke kin.",
+"perfdisabledsub" => "Dit is in opsleine ferzje fan \"$1\":",
+
+
+# Login and logout pages
+#
+"logouttitle" => "Ofmelde",
+"logouttext" => "Jo binne no ôfmeld.
+Jo kinne de {{SITENAME}} fierders anonym brûke,
+of jo op 'e nij [[{{ns:special}}:Userlogin|oanmelde]] ûnder in oare namme.",
+"welcomecreation" => "<h2>Wolkom, $1!</h2><p>Jo ynstellings bin oanmakke.
+Ferjit net se oan jo foarkar oan te passen.",
+
+"loginpagetitle" => "Oanmelde",
+"yourname" => "Jo brûkersnamme",
+"yourpassword" => "Jo wachtwurd",
+"yourpasswordagain" => "Jo wachtwurd (nochris)",
+"remembermypassword" => "Oare kear fansels oanmelde.",
+"loginproblem" => "<b>Der wie wat mis mei jo oanmelden.</b><br />Besykje it nochris, a.j.w.",
+"alreadyloggedin" => "<strong>Brûker $1, jo binne al oanmeld!</strong><br />",
+"login" => "Oanmelde",
+"userlogin" => "Oanmelde",
+"logout" => "Ofmelde",
+"userlogout" => "Ofmelde",
+"notloggedin" => "Net oanmelde",
+"createaccount" => "Nije ynstelingd oanmeitsje",
+"badretype" => "De infierde wuchtwurden binne net lyk.",
+"userexists" => "Dy brûkersname wurdt al brûkt. Besykje in oarenien.",
+"youremail" => "Jo e-postadres (*).",
+"yournick" => "Jo alias (foar sinjaturen)",
+
+"loginerror" => "Oanmeldflater",
+"noname" => "Jo moatte in brûkersnamme opjaan.",
+"loginsuccesstitle" => "Oanmelden slagge.",
+"loginsuccess" => "Jo binne no oanmelde op de {{SITENAME}} as: $1.",
+"nosuchuser" => "Brûkersnamme en wachtwurd hearre net by elkoar.
+Besykje op 'e nij, of fier it wachtwurd twa kear yn en meitsje neie brûkersynstellings.",
+
+"wrongpassword" => "Brûkersnamme en wachtwurd hearre net by elkoar.
+Besykje op 'e nij, of fier it wachtwurd twa kear yn en meitsje neie brûkersynstellings.",
+
+"mailmypassword" => "Stjoer my in nij wachtwurd.",
+"passwordremindertitle" => "Nij wachtwurd foar de {{SITENAME}}",
+"passwordremindertext" => "Immen (nei alle gedachten jo, fan Ynternet-adres $1)
+hat frege en stjoer jo in nij {{SITENAME}} wachtwurd.
+I wachtwurd foar brûker \"$2\" is no \"$3\".
+Meld jo no oan, en feroarje jo wachtwurd.",
+"noemail" => "Der is gjin e-postadres foar brûker \"$1\".",
+"passwordsent" => "In nij wachtwurd is tastjoert oan it e-postadres foar \"$1\".
+Please log in again after you receive it.",
+
+# Edit pages
+#
+"summary" => "Gearfetting",
+"subject" => "Mêd",
+"minoredit" => "Dit is in tekstwiziging",
+"watchthis" => "Folgje dizze side",
+"savearticle" => "Fêstlizze",
+"preview" => "Oerlêze",
+"showpreview" => "Oerlêze foar de side fêstlein is",
+"blockedtitle" => "Brûker is útsletten troch",
+"blockedtext" => "Jo brûkersname of Ynternet-adres is útsletten.
+As reden is opjûn:<br />''$2''<p>As jo wolle, kinne jo hjiroer kontakt op nimme meid de behearder.
+
+(Om't in Ynternet-adressen faak mar foar ien sessie tawiisd wurde, kin it wêze
+dat it eins gjit om in oar dy't deselde tagongferskaffer hat as jo hawwe. As it jo
+net betreft, besykje dan earst of it noch sa is as jo in skofke gjin
+Ynternet-ferbining hân hawwe. As it in probleem bliuwt, skriuw dan de behearder.
+Sorry, foar it ûngemak.)
+
+Jo Ynternet-adres is: $3. Nim dat op yn jo berjocht.
+
+Tink derom, dat \"skriuw nei dizze brûker\" allinich wol as jo in
+e-postadres opjûn hawwe in jo [[{{ns:special}}:Preferences|ynstellings]].",
+
+"newarticle" => "(Nij)",
+"newarticletext" =>
+"Jo hawwe in keppeling folge nei in side dêr't noch gjin tekst op stiet.
+Om sels tekst te meistjsen kinne jo dy gewoan yntype in dit bewurkingsfjild
+([[{{ns:project}}:Bewurk-rie|Mear ynformaasje oer bewurkjen]].)
+Oars kinne jo tebek mei de tebek-knop fan jo blêdzjer.",
+
+"anontalkpagetext" => "---- ''Dit is de oerlisside fan in unbekinde brûker; in brûker
+dy't sich net oanmeld hat. Om't der gjin namme is wurd it Ynternet-adres brûkt om
+oan te jaan wa. Mar faak is it sa dat sa'n adres net altid troch deselde brûkt wurdt.
+As jo it idee hawwe dat jo as ûnbekinde brûker opmerkings foar in oar krije, dan kinne
+jo jo [[{{ns:special}}:Userlogin|oanmelde]], dat jo allinnich opmerkings foar josels krije.''",
+"noarticletext" => "(Der stjit noch gjin tekst op dizze side.)",
+"updated" => "(Bewurke)",
+"note" => "<strong>Opmerking:</strong>",
+"previewnote" => "Tink der om dat dizze side noch net fêstlein is!",
+"previewconflict" => "Dizze side belanget allinich it earste bewurkingsfjild oan.",
+"editing" => "Bewurkje \"$1\"",
+'editinguser' => "Bewurkje \"$1\"",
+//"editing" => "Bewurkje \"$1\" (seksje)",
+//"editing" => "Bewurkje \"$1\" (nije opmerking)",
+"editconflict" => "Tagelyk bewurke: \"$1\"",
+"explainconflict" => "In oar hat de side feroare sûnt jo begûn binne mei it bewurkjen.
+It earste bewurkingsfjild is hoe't de tekst wilens wurde is.
+Jo feroarings stean yn it twadde fjild.
+Dy wurde allinnich tapasse safier as jo se yn it earste fjild ynpasse.
+<b>Allinnich</b> de tekst út it earste fjild kin fêstlein wurde.<br />",
+"yourtext" => "Jo tekst",
+"storedversion" => "Fêstleine ferzje",
+"editingold" => "<strong>Waarskôging: Jo binne dwaande mei in âldere ferzje fan dizze side.
+Soenen jo dizze fêstlizze, dan is al wat sûnt dy tiid feroare is kwyt.</strong>",
+"yourdiff" => "Feroarings",
+/*"copyrightwarning" => "Alle bydragen ta de {{SITENAME}} wurde sjoen
+as fallend ûnder de GNU Iepen Dokumentaasje Lisinsje
+(sjoch fierders: \"$1\").
+As jo net wolle dat jo skriuwen ûnferbidlik oanpast en frij ferspraat wurdt,
+dan is it baas, en set it net op de {{SITENAME}}.<br />
+Jo ferklare ek dat jo dit sels skreaun hawwe, of it oernaam hawwe út in
+publyk eigendom of in oare iepen boarne.
+<strong><big>Foeg gjin wurk ûnder auteursrjocht ta sûnder tastimming!</big></strong>",*/
+"longpagewarning" => "<strong>Waarskôging: Dizze side is $1 kilobyte lang;
+der binne blêdzjers dy problemen hawwe mei siden fan tsjin de 32kb. of langer.
+Besykje de side yn lytsere stikken te brekken.</strong>",
+"readonlywarning" => "<strong>Waarskôging: De databank is ôfsletten foar
+ûnderhâld, dus jo kinne jo bewurkings no net fêstlizze.
+It wie baas en nim de tekst foar letter oer yn in tekstbestân.</strong>",
+"protectedpagewarning" => "<strong>Waarskôging: Dizze side is beskerme, dat
+gewoane brûkers dy net bewurkje kinne. Tink om de
+[[Project:Beskerm-rie|rie oer beskerme siden]].</strong>",
+
+# History pages
+#
+"revhistory" => "Sideskiednis",
+"nohistory" => "Dit is de earste ferzje fan de side.",
+"revnotfound" => "Ferzje net fûn",
+"revnotfoundtext" => "De âlde ferzje fan dizze side dêr't jo om frege hawwe, is der net.
+Gean nei of de keppeling dy jo brûkt hawwe wol goed is.",
+"loadhist" => "Sideskiednis ...",
+"currentrev" => "Dizze ferzje",
+"revisionasof" => "Ferzje op $1",
+"cur" => "no",
+"next" => "dan",
+"last" => "doe",
+"orig" => "ea",
+"histlegend" => "Utlis: (no) = ferskil mei de side sa't dy no is,
+(doe) = ferskill mei de side sa't er doe wie, foar de feroaring, T = Tekstwiziging",
+
+
+# Diffs
+#
+"difference" => "(Ferskil tusken ferzjes)",
+"loadingrev" => "Ferskil tusken ferzjes ...",
+"lineno" => "Rigel $1:",
+"editcurrent" => "Bewurk de hjoeddeistiche ferzje fan dizze side",
+
+# Search results
+#
+"searchresults" => "Sykresultaat",
+"searchresulttext" => "\"[[Project:Syk-rie|Ynformaasje oer it sykjen|Sykje troch de {{SITENAME}}]]\" troch de {{SITENAME}}.",
+"searchsubtitle" => "Foar fraach \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Foar fraach \"$1\"",
+"badquery" => "Misfoarme sykfraach",
+"badquerytext" => "Jo fraach koe net ferwurke wurde.
+Dit is faaks om't jo besyke hawwe en sykje in word fan ien of twa letters, wat it programma noch net kin.
+Of it soe kinne dat jo de fraach misskreaun hawwe, lykas \"frysk en en frei\". Besykje it nochris.",
+"matchtotals" => "Foar \"$1\" binne $2 titles fûn en $3 siden.",
+"noexactmatch" => "Der is gjin side mei krekt dizze titel. Faaks is it better en Sykje nei dizze tekst.",
+"titlematches" => "Titels",
+"notitlematches" => "Gjin titels",
+"textmatches" => "Siden",
+"notextmatches" => "Gjin siden",
+"prevn" => "foarige $1",
+"nextn" => "folgende $1",
+"viewprevnext" => "($1) ($2) ($3) besjen.",
+"showingresults" => "<b>$1</b> resultaten fan <b>$2</b> ôf.",
+"showingresultsnum" => "<b>$3</b> resultaten fan <b>$2</b> ôf.",
+"nonefound" => "As der gjin resultaten binne, tink der dan om dat der <b>net</b> socht
+wurde kin om wurden as \"it\" en \"in\", om't dy net byhâlden wurde, en dat as der mear
+wurden syke wurde, allinnich siden fûn wurde wêr't <b>alle</b> worden op fûn wurde.",
+
+"powersearch" => "Sykje",
+"powersearchtext" => "
+Sykje in nammeromten :<br />
+$1<br />
+$2 List trochferwizings &nbsp; Sykje nei \"$3\" \"$9\"",
+
+"searchdisabled" => "<p>Op it stuit stjit it trochsykjen fan tekst net oan, om't de
+tsjinner it net oankin. Mei't we nije apparatuer krije wurdt it nei alle gedanken wer
+mooglik. Foar now kinne jo sykje fia Google:</p>",
+
+
+
+# Preferences page
+#
+"preferences" => "Ynstellings",
+"prefsnologin" => "Net oanmeld",
+"prefsnologintext" => "Jo moatte [[{{ns:special}}:Userlogin|oanmeld]] wêze om jo ynstellings te feroarjen.",
+
+"prefsreset" => "De ynstellings binne tebek set sa't se fêstlein wienen.",
+"qbsettings" => "Menu",
+"changepassword" => "Wachtword feroarje",
+"skin" => "Side-oansjen",
+"math" => "Formules",
+"dateformat" => "Datum",
+'datedefault' => 'Gjin foarkar',
+"math_failure" => "Untsjutbere formule",
+"math_unknown_error" => "Unbekinde fout",
+"math_unknown_function" => "Unbekinde funksje",
+"math_lexing_error" => "Unbekind wurd",
+"math_syntax_error" => "Sinboufout",
+"saveprefs" => "Ynstellings fêstlizze",
+"resetprefs" => "Ynstellings tebek sette",
+"oldpassword" => "Ald wachtwurd",
+"newpassword" => "Nij wachtwurd",
+"retypenew" => "Nij wachtwurd (nochris)",
+"textboxsize" => "Tekstfjid-omjittings",
+"rows" => "Rigen",
+"columns" => "Kolommen",
+"searchresultshead" => "Sykje",
+"resultsperpage" => "Treffers de side",
+"contextlines" => "Rigels inhâld de treffer",
+"contextchars" => "Tekens fan de inhâld de rigel",
+"stubthreshold" => "Grins foar stobben",
+"recentchangescount" => "Nûmer of titels op 'Koarts feroare'",
+"savedprefs" => "Jo ynstellings binne fêstlein.",
+"timezonetext" => "Jou it tal fan oeren dat jo tiidsône ferskilt fan UTC (Greenwich).",
+"localtime" => "Jo tiidsône",
+"timezoneoffset" => "Ferskil",
+"servertime" => "UTC",
+"guesstimezone" => "Freegje de blêdzjer",
+"defaultns" => "Nammeromten dy't normaal trochsykje wurde:",
+
+# Recent changes
+#
+"changes" => "feroarings",
+"recentchanges" => "Koarts feroare",
+"recentchangestext" => "De lêste feroarings fan de {{SITENAME}}.",
+"rcnote" => "Dit binne de lêste <strong>$1</strong> feroarings yn de lêste <strong>$2</strong> dagen.",
+"rcnotefrom" => "Dit binne de feroarings sûnt <b>$2</b> (maksimaal <b>$1</b>).",
+"rclistfrom" => "Jou nije feroarings, begjinnende mei $1",
+"rclinks" => "Jou $1 nije feroarings yn de lêste $2 dagen; $3 tekstwiziging",
+"diff" => "ferskil",
+"hist" => "skiednis",
+"hide" => "gjin",
+"show" => "al",
+"minoreditletter" => "T",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => "Bied bestân oan",
+"uploadbtn" => "Bied bestân oan",
+"reupload" => "Op 'e nij oanbiede",
+"reuploaddesc" => "Werom nei oanbied-side.",
+"uploadnologin" => "Net oanmelde",
+"uploadnologintext" => "Jo moatte [[{{ns:special}}:Userlogin|oanmeld]] wêze om in bestân oanbieden te kinnen.",
+
+"uploaderror" => "Oanbied-fout",
+"uploadtext" => "'''STOP!''' Lês ear't jo eat oanbiede
+de [[Project:Ofbyld-rie|regels foar ôfbyldbrûk]] foar de {{SITENAME}}.
+
+Earder oanbeane ôfbylden, kinne jo fine op de
+[[Project:Imagelist|list of oanbeane ôfbylden]].
+Wat oanbean en wat wiske wurdt, wurdt delskreaun yn it
+[[Project:Oanbied-loch|lochboek]].
+
+Om't nije ôfbylden oan te bieden, kieze jo in bestân út sa't dat
+normaal is foar jo blêdzjer en bestjoersysteem.
+Dan jouwe jo oan jo gjin auteursrjocht skeine troch it oanbieden.
+Mei \"Bied oan\" begjinne jo dan it oanbieden.
+Dit kin efkes duorje as jo Ynternet-ferbining net sa flug is.
+
+Foar de bestânsforam wurdt foto's JPEG oanret, foar tekenings ensfh. PNG, en foar
+lûden OGG. Brûk in dúdlike bestânsnamme, sa't in oar ek wit wat it is.
+
+Om it ôfbyld yn in side op te nimmen, meitsje jo dêr sa'n keppeling:<br />
+'''<nowiki>[[ôfbyld:jo_foto.jpg|omskriuwing]]</nowiki>''' of
+'''<nowiki>[[ôfbyld:jo_logo.png|omskriuwing]]</nowiki>''';
+en foar lûden '''<nowiki>[[media:jo_lûd.ogg]]</nowiki>'''.
+
+Tink derom dat oaren bewurkje kinne wat jo oanbiede, as dat better is foar de {{SITENAME}},
+krekt's sa't dat foar siden jildt, en dat jo útsletten wurde kinne as jo misbrûk
+meitsje fan it systeem..",
+
+"uploadlog" => "oanbied log",
+"uploadlogpage" => "Oanbied_log",
+"uploadlogpagetext" => "Liste fan de lêst oanbeane bestannen.
+(Tiid oanjûn as UTC).
+<ul>
+</ul>",
+
+"filename" => "Bestânsnamme",
+"filedesc" => "Omskriuwing",
+"copyrightpage" => "{{ns:project}}:Auteursrjocht",
+"copyrightpagename" => "{{SITENAME}} auteursrjocht",
+"uploadedfiles" => "Oanbeane bestannen",
+"minlength" => "Ofbyldnammen moatte trije letters of mear wêze.",
+"badfilename" => "De ôfbyldnamme is feroare nei \"$1\".",
+"badfiletype" => "\".$1\" is net yn in oanrette bestânsfoarm.",
+"largefile" => "It is baas as ôfbylden net grutter as 100k binne.",
+"successfulupload" => "Oanbieden slagge.",
+"fileuploaded" => "Bestân \"$1\" goed oanbean.
+Gean no fierder nei de beskriuwingsside: ($2). Dêr kinne jo oanjaan
+wêr't it bestân wei kaam, hoenear it oanmakke is en wa't it makke hat,
+en wat jo fierder mar oan ynformaasje hawwe.",
+
+"uploadwarning" => "Oanbied waarskôging",
+"savefile" => "Lis bestân fêst",
+"uploadedimage" => " \"[[$1]]\" oanbean",
+"uploaddisabled" => "Sorry, op dizze tsjinner kin net oanbean wurde.",
+
+# Image list
+#
+"imagelist" => "Ofbyld list",
+"imagelisttext" => "Dit is in list fan $1 ôfbylden, op $2.",
+"getimagelist" => "Ofbyld list ...",
+"ilsubmit" => "Sykje",
+"showlast" => "Jou lêste $1 ôfbylden, op $2.",
+"byname" => "namme",
+"bydate" => "datum",
+"bysize" => "grutte",
+"imgdelete" => "wisk",
+"imgdesc" => "tekst",
+"imglegend" => "Utlis: (tekst) = Jou/bewurk ôfbyld-omskriuwing.",
+"imghistory" => "Ofbyldskiednis",
+"revertimg" => "tebek",
+"deleteimg" => "wisk",
+"deleteimgcompletely" => "wisk",
+"imghistlegend" => "Utlis: (no) = dit is it hjoeddeiske ôfbyld,
+(wisk) = wiskje dizze âldere ferzje, (tebek) = set ôfbyld tebek nei dizze âldere ferzje.
+<br /><i>Fia de datum kinne jo it ôfbyld dat doe oanbean besjen</i>.",
+
+"imagelinks" => "Ofbyldkeppelings",
+"linkstoimage" => "Dizze siden binne keppele oan it ôfbyld:",
+"nolinkstoimage" => "Der binne gjin siden oan dit ôfbyld keppelje.",
+
+# Statistics
+#
+"statistics" => "Statistyk",
+"sitestats" => "Side statistyk",
+"userstats" => "Brûker statistyk",
+"sitestatstext" => "It tal fan siden in de {{SITENAME}} is: <b>$2</b>.<br />
+(Oerlissiden, siden oer de {{SITENAME}}, oare bysûndere siden, stobben en
+trochferwizings yn de databank binne dêrby net meiteld.)<br />
+It tal fan siden in de databank is: <b>$1</b>.
+<p>
+Der is <b>$3</b> kear in side opfrege, en <b>$4</b> kear in side bewurke,
+sûnt it programma bywurke is (15 oktober 2002).
+Dat komt yn trochslach del op <b>$5</b> kear bewurke de side,
+en <b>$6</b> kear opfrege de bewurking.",
+
+"userstatstext" => "It tal fan registreare brûkers is <b>$1</b>.
+It tal fan behearders dêrfan is: <b>$2</b>.",
+
+# Maintenance Page
+#
+"disambiguations" => "Trochverwizings",
+"disambiguationspage" => "{{ns:project}}:trochferwizing",
+"disambiguationstext" => "Dizze siden binne keppele fia in
+[[{{ns:project}}:trochferwizing]].
+Se soenen mei de side sels keppele wurde moatte.<br />
+(Allinnich siden út deselde nammeromte binne oanjûn.)",
+
+"doubleredirects" => "Dûbele trochverwizings",
+"doubleredirectstext" => "<b>Let op!</b> Der kinne missen yn dizze list stean!
+Dat komt dan ornaris troch oare keppelings ûnder de \"#REDIRECT\".<br />
+Eltse rigel jout keppelings nei de earste en twadde trochverwizing, en dan de earste regel fan
+de twadde trochferwizing, wat it \"echte\" doel wêze moat.",
+
+"brokenredirects" => "Misse trochferwizings",
+"brokenredirectstext" => "Dizze trochferwizings ferwize nei siden dy't der net binne.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Lossteande siden",
+"unusedimages" => "Lossteande ôbylden",
+"popularpages" => "Grage siden",
+"nviews" => "$1 kear sjoen",
+"wantedpages" => "Nedige siden",
+"nlinks" => "$1 keer keppele",
+"allpages" => "Alle titels",
+"randompage" => "Samar in side",
+"shortpages" => "Koarte siden",
+"longpages" => "Lange siden",
+"listusers" => "Brûkerlist",
+"specialpages" => "Bysûndere siden",
+"spheading" => "Bysûndere siden foar all brûkers",
+"recentchangeslinked" => "Folgje keppelings",
+"rclsub" => "(nei siden dêr't \"$1\" keppelings nei hat)",
+"newpages" => "Nije siden",
+"ancientpages" => "Alde siden",
+"movethispage" => "Move this side",
+"unusedimagestext" => "<p>Tink derom dat ore web sides lykas fan de oare
+parten fan it meartaliche projekt mei in keppeling nei in direkte URL nei
+an ôfbyld makke hawwe kinne. Dan wurde se noch brûke, mar stean al in dizze list.",
+
+"alphaindexline" => "$1 oan't $2",
+
+
+# Email this brûker
+#
+"mailnologin" => "Gjin adres beskikber",
+"mailnologintext" => "Jo moatte [[{{ns:special}}:Userlogin|oanmeld]]
+wêze, en in jildich e-postadres [[{{ns:special}}:Preferences|ynsteld]]
+hawwe, om oan oare brûkers e-post stjoere te kinnen.",
+
+"emailuser" => "Skriuw dizze brûker",
+"emailpage" => "E-post nei brûker",
+"emailpagetext" => "As dizze brûker in jildich e-postadres in ynsteld hat,
+dan kinne jo ien berjocht ferstjoere.
+It e-postadres dat jo ynsteld hawwe wurdt brûkt as de ôfstjoerder, sa't de ûntfanger
+antwurdzje kin.",
+"noemailtitle" => "Gjin e-postadres",
+"noemailtext" => "Dizze brûker had gjin jildich e-postadres ynsteld,
+of hat oanjaan gjin post fan oare brûkers krije te wollen.",
+"emailfrom" => "Fan",
+"emailto" => "Oan",
+"emailsubject" => "Oer",
+"emailmessage" => "Tekst",
+"emailsend" => "Stjoer",
+"emailsent" => "Berjocht stjoerd",
+"emailsenttext" => "Jo berjocht is stjoerd.",
+
+# Watchlist
+#
+"watchlist" => "Folchlist",
+"nowatchlist" => "Jo hawwe gjin siden op jo folchlist.",
+"watchnologin" => "Not oanmeld in",
+"watchnologintext"=> "Jo moatte [[{{ns:special}}:Userlogin|oanmeld]] wêze om jo folchlist te feroarjen.",
+
+"addedwatch" => "Oan folchlist tafoege",
+"addedwatchtext" => "De side \"$1\" is tafoege oan jo <a href=\""
+. "{{localurle:{{ns:special}}:Watchlist}}\">folchlist</a>.
+As dizze side sels, of de oerlisside, feroare wurd, dan komt dat dêr yn,
+en de side stiet dan ek <b>fet</b> yn de <a href=\"" .
+ "{{localurle:{{ns:special}}:Recentchanges}}\">Koarts feroare</a> list.
+
+<p>As jo letter in side net mear folgje wolle, dan brûke jo \"Ferjit dizze side\".",
+"removedwatch" => "Net mear folgje",
+"removedwatchtext" => "De side \"$1\" stiet net mear op jo folchlist.",
+"watchthispage" => "Folgje dizze side",
+"unwatchthispage" => "Ferjit dizze side",
+"notanarticle" => "Dit kin net folge wurde.",
+"watchnochange" => "Fan de siden dy't jo folgje is der yn dizze perioade net ien feroare.",
+"watchdetails" => "Jo folchlist hat $1 siden (oerlissiden net meiteld).
+In dizze perioade binne der $2 siden feroare.
+$3. ([$4 Gâns myn folchlist].)",
+
+"watchmethod-recent" => "Koarts feroare ...",
+"watchmethod-list" => "Folge ...",
+"removechecked" => "Ferjit dizze siden",
+"watchlistcontains" => "Jo folgje op it stuit $1 siden.",
+"watcheditlist" => "Dit binne de siden op jo folchlist, oardere op alfabet.
+Jou oan hokfoar siden jo net mear folgje wolle, en befêstigje dat ûnderoan de side.",
+
+"removingchecked" => "Wiskje siden fan jo folchlist ...",
+"couldntremove" => "Koe \"$1\" net ferjitte ...",
+"iteminvalidname" => "Misse namme: \"$1\" ...",
+"wlnote" => "Dit binne de lêste <strong>$1</strong> feroarings yn de lêste <strong>$2</strong> oeren.",
+
+
+# Delete/protect/revert
+#
+"deletepage" => "Wisk side",
+"confirm" => "Befêstigje",
+"excontent" => "inhâld wie: '$1'",
+"exbeforeblank" => "foar de tekst wiske wie, wie dat: '$1'",
+"exblank" => "side wie leech",
+"confirmdelete" => "Befestigje wiskjen",
+"deletesub" => "(Wiskje \"$1\")",
+"historywarning" => "Waarskôging: De side dy't jo wiskje wolle hat skiednis:",
+"confirmdeletetext" => "Jo binne dwaande mei it foar altyd wiskjen fan in side
+of ôfbyld, tegearre mei alle skiednis, út de databank.
+Befêstigje dat jo dat wier dwaan wolle. Befêstigje dat dat is wat jo witte wat it gefolch
+is en dat jo dit dogge neffens de [[{{ns:project}}:wisk-rie]].",
+
+"actioncomplete" => "Dien",
+"deletedtext" => "\"$1\" is wiske.
+Sjoch \"$2\" foar in list fan wat resint wiske is.",
+"deletedarticle" => "\"$1\" is wiske",
+"dellogpage" => "Wisk_loch",
+"dellogpagetext" => "Dit is wat der resint wiske is.
+(Tiden oanjûn as UTC).
+<ul>
+</ul>",
+
+"deletionlog" => "wisk loch",
+"reverted" => "Tebekset nei eardere ferzje",
+"deletecomment" => "Reden foar it wiskjen",
+"imagereverted" => "Tebeksette nei eardere ferzje is slagge.",
+"rollback" => "Feroarings tebeksette",
+"rollbacklink" => "feroaring tebeksette",
+"rollbackfailed" => "Feroaring tebeksette net slagge",
+"cantrollback" => "Disse feroaringt kin net tebek set, om't der mar ien skriuwer is.",
+"alreadyrolled" => "Kin de feroaring fan [[:$1]]
+troch [[Brûker:$2|$2]] ([[Brûker oerlis:$2|Oerlis]]) net tebeksette;
+inoar hat de feroaring tebekset, of oars wat oan de side feroare.
+
+De lêste feroaring wie fan [[Brûker:$3|$3]] ([[Brûker oerlis:$3|Oerlis]]).",
+# only shown if there is an edit comment
+"editcomment" => "De gearfetting wie: \"<i>$1</i>\".",
+"revertpage" => "Tebek set ta de ferzje fan \"$1\"",
+
+# Undelete
+"undelete" => "Side werom set",
+"undeletepage" => "Side besjen en werom sette",
+"undeletepagetext" => "Dizze siden binne wiske, mar sitte noch yn it argyf en kinne weromset wurde.
+(It argyf kin út en troch leechmeitsje wurde.)",
+"undeletearticle" => "Set side werom",
+"undeleterevisions" => "$1 ferzjes in it argyf",
+"undeletehistory" => "Soenen jo dizze side weromsette, dan wurde alle ferzjes weromset as part
+fan de skiednis. As der in nije side is mei dizze namme, dan wurd de hjoeddeise ferzje <b>net</b>
+troch de lêste ferzje út dy weromsette skiednis ferfangen.",
+"undeleterevision" => "Wiske side, sa't dy $1 wie.",
+"undeletebtn" => "Weromset!",
+"undeletedarticle" => "\"$1\" weromset",
+
+# Contributions
+#
+"contributions" => "Brûker bydragen",
+"mycontris" => "Myn bydragen",
+"contribsub" => "Foar \"$1\"",
+"nocontribs" => "Der binne gjin feroarings fûn dyt't hjirmei oerienkomme.",
+"ucnote" => "Dit binne dizze brûker's leste <b>$1</b> feroarings yn de lêste <b>$2</b> dagen.",
+"uclinks" => "Besjoch de lêste $1 feroarings; besjoch de lêste $2 dagen.",
+"uctop" => " (boppen)",
+
+# What links here
+#
+"whatlinkshere" => "Wat is hjirmei keppele",
+"notargettitle" => "Gjin side",
+"notargettext" => "Jo hawwe net sein oer hokfoar side jo dit witte wolle.",
+"linklistsub" => "(List fan keppelings)",
+"linkshere" => "Dizze siden binne hjirmei keppele:",
+"nolinkshere" => "Gjinien side is hjirmei keppele!",
+"isredirect" => "trochverwizing",
+
+# Block/unblock IP
+#
+"blockip" => "Slut brûker út",
+"blockiptext" => "Brûk dizze fjilden om in brûker fan skriuwtagong út te sluten.
+Dit soe allinnich omwillens fan fandalisme dwaan wurde moatte, sa't de
+[[{{ns:project}}:Utslut-rie|útslut-rie]] it oanjout.
+Meld de krekte reden! Begelyk, neam de siden dy't oantaaste waarden.",
+"ipaddress" => "Brûkernamme of Ynternet-adres",
+"ipbreason" => "Reden",
+"ipbsubmit" => "Slut dizze brûker út",
+"badipaddress" => "Dy brûker bestiet net",
+"blockipsuccesssub" => "Utsluting slagge",
+"blockipsuccesstext" => "Brûker \"$1\" is útsletten.<br />
+(List fan [[{{ns:special}}:Ipblocklist|útslette brûkers]].)",
+"unblockip" => "Lit brûker der wer yn",
+"unblockiptext" => "Brûk dizze fjilden om in brûker wer skriuwtagong te jaan.",
+"ipusubmit" => "Lit dizze brûker der wer yn",
+"ipblocklist" => "List fan útsletten Ynternet-adressen en brûkersnammen",
+"blocklistline" => '"$3", troch "$2" op $1 ($4)',
+"blocklink" => "slut út",
+"unblocklink" => "lit yn",
+"contribslink" => "bydragen",
+"autoblocker" => "Jo wienen útsletten om't jo Ynternet-adres oerienkomt mei dat fan \"$1\".
+Foar it útslute fan dy brûker waard dizze reden joen: \"$2\".",
+
+# Developer tools
+#
+"lockdb" => "Meitsje de database 'Net-skriuwe'",
+"unlockdb" => "Meitsje de databank skriuwber",
+"lockdbtext" => "Salang as de databank 'Net-skriuwe' is,
+is foar brûkers it feroarjen fan siden, ynstellings, folchlisten, ensfh. net mooglik.
+Befêstigje dat dit is wat jo wolle, en dat jo de databank wer skriuwber meitsje as
+jo ûnderhâld ree is.",
+"unlockdbtext" => "As de databank skriuwber makke wurdt,
+is foar brûkers it feroarjen fan siden, ynstelingen, folchlisten, ensfh, wer mooglik.
+Befêstigje dat dit is wat jo wolle.",
+"lockconfirm" => "Ja, ik wol wier de databank 'Net--skriuwe' meitsje.",
+"unlockconfirm" => "Ja, ik wol wier de databank skriuwber meitsje.",
+"lockbtn" => "Meitsje de database 'Net-skriuwe'",
+"unlockbtn" => "Meitsje de databank skriuwber",
+"locknoconfirm" => "Jo hawwe jo hanneling net befêstige.",
+"lockdbsuccesssub" => "Databank is 'Net-skriuwe'",
+"unlockdbsuccesssub" => "Database is skriuwber",
+"lockdbsuccesstext" => "De {{SITENAME}} databank is 'Net-skriuwe' makke.
+<br />Tink derom en meitsje de databank skriuwber as jo ûnderhâld ree is.",
+"unlockdbsuccesstext" => "De {{SITENAME}} databank is skriuwber makke.",
+
+# Move page
+#
+"movepage" => "Werneam side",
+"movepagetext" => "Dit werneamt in side, mei alle sideskiednis.
+De âlde titel wurdt in trochferwizing nei de nije.
+Keppelings mei de âlde side wurde net feroare;
+gean sels nei of't der dûbele of misse ferwizings binne.
+It hinget fan jo ôf of't de siden noch keppelen binne sa't it mient wie.
+
+De side wurdt '''net''' werneamt as der al in side mei dy namme is, útsein as it in side
+sûnder skiednis is en de side leech is of in trochferwizing is. Sa kinne jo in side
+daalks weromneame as jo in flater meitsje, mar jo kinne in oare side net oerskriuwe.",
+
+"movepagetalktext" => "As der in oerlisside by heart, dan bliuwt dy oan de side keppele, '''útsein''':
+*De nije sidenamme yn in oare nammeromte is,
+*Der keppele oan de nije namme al in net-lege oerlisside is, of
+*Jo dêr net foar kieze.
+
+In dizze gefallen is it oan jo hoe't jo de oerlisside werneame of ynfoegje wolle.",
+
+"movearticle" => "Werneam side",
+"movenologin" => "Net oameld",
+"movenologintext" => "Jo moatte [[{{ns:special}}:Userlogin|oanmeld]] wêze om in side wer te neamen.",
+
+"newtitle" => "As nij titel",
+"movepagebtn" => "Werneam side",
+"pagemovedsub" => "Werneamen slagge",
+"pagemovedtext" => "Side \"[[$1]]\" werneamd as \"[[$2]]\".",
+"articleexists" => "Der is al in side mei dy namme,
+of oars is de namme dy't jo oanjûn hawwe net tastean.
+Besykje it op 'e nij.",
+
+"talkexists" => "It werneamen op sich is slagge, mar de eardere oerlisside is
+net mear keppele om't der foar de nije namme el al in oerlisside wie.
+Gearfoegje de oerlissiden hânmjittig.",
+
+"movedto" => "werenamd as",
+"talkpagemoved" => "De oerlisside is al noch keppele.",
+"talkpagenotmoved" => "De oerlisside is <strong>net</strong> mear keppele.",
+# Math
+'mw_math_png' => "Altiten as PNG ôfbyldzje",
+'mw_math_simple' => "HTML foar ienfâldiche formules, oars PNG",
+'mw_math_html' => "HTML as mooglik, oars PNG",
+'mw_math_source' => "Lit de TeX ferzje stean (foar tekstblêdzjers)",
+'mw_math_modern' => "Oanbefelle foar resinte blêdzjers",
+'mw_math_mathml' => 'MathML',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesGa.php b/languages/messages/MessagesGa.php
new file mode 100644
index 000000000000..d314b525a160
--- /dev/null
+++ b/languages/messages/MessagesGa.php
@@ -0,0 +1,1786 @@
+<?php
+/** Irish (Gaeilge)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Faic', 'Greamaithe ar chlé', 'Greamaithe ar dheis', 'Ag faoileáil ar chlé', 'Ag faoileáil ar dheis'
+);
+
+$skinNames = array(
+ 'standard' => 'Gnáth',
+ 'nostalgia' => 'Sean-nós',
+ 'cologneblue' => 'Gorm na Colóna',
+ 'smarty' => 'Paddington',
+ 'montparnasse' => 'Montparnasse',
+ 'davinci' => 'DaVinci',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'MySkin',
+ 'chick' => 'Chick'
+);
+
+$magicWords = array(
+ # ID CASE SYNONYMS
+ 'redirect' => array( 0, '#redirect', '#athsheoladh' ),
+ 'notoc' => array( 0, '__NOTOC__', '__GANCÁ__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__CÁGACHUAIR__' ),
+ 'toc' => array( 0, '__TOC__', '__CÁ__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__GANMHÍRATHRÚ__' ),
+ 'start' => array( 0, '__START__', '__TÚS__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'MÍLÁITHREACH' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'AINMNAMÍOSALÁITHREAÍ' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'GINAINMNAMÍOSALÁITHREAÍ' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'GIORRÚNAMÍOSALÁITHREAÍ' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'LÁLÁITHREACH' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'AINMANLAELÁITHRIGH' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'BLIAINLÁITHREACH' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'AMLÁITHREACH' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'LÍONNANALT' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'LÍONNAGCOMHAD' ),
+ 'pagename' => array( 1, 'PAGENAME', 'AINMANLGH' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'AINMANLGHB' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'AINMSPÁS' ),
+ 'msg' => array( 0, 'MSG:', 'TCHT:' ),
+ 'subst' => array( 0, 'SUBST:', 'IONAD:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'TCHTFS:' ),
+ 'end' => array( 0, '__END__', '__DEIREADH__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'mionsamhail', 'mion' ),
+ 'img_right' => array( 1, 'right', 'deas' ),
+ 'img_left' => array( 1, 'left', 'clé' ),
+ 'img_none' => array( 1, 'none', 'faic' ),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre', 'lár' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'fráma', 'frámaithe' ),
+ 'int' => array( 0, 'INT:', 'INMH:' ),
+ 'sitename' => array( 1, 'SITENAME', 'AINMANTSUÍMH' ),
+ 'ns' => array( 0, 'NS:', 'AS:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'URLÁITIÚIL' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'URLÁITIÚILB' ),
+ 'server' => array( 0, 'SERVER', 'FREASTALAÍ' ),
+ 'servername' => array( 0, 'SERVERNAME', 'AINMANFHREASTALAÍ' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'SCRIPTCHOSÁN' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'GRAMADACH:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', '__GANTIONTÚNADTEIDEAL__', '__GANTT__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', '__GANTIONTÚNANÁBHAIR__', '__GANTA__' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'SEACHTAINLÁITHREACH' ),
+ 'currentdow' => array( 1, 'CURRENTDOW', 'LÁLÁITHREACHNAS' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'IDANLEASAITHE' ),
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Meán',
+ NS_SPECIAL => 'Speisialta',
+ NS_MAIN => '',
+ NS_TALK => 'Plé',
+ NS_USER => 'Úsáideoir',
+ NS_USER_TALK => 'Plé_úsáideora',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Plé_{{grammar:genitive|$1}}',
+ NS_IMAGE => 'Íomhá',
+ NS_IMAGE_TALK => 'Plé_íomhá',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Plé_MediaWiki',
+ NS_TEMPLATE => 'Teimpléad',
+ NS_TEMPLATE_TALK => 'Plé_teimpléid',
+ NS_HELP => 'Cabhair',
+ NS_HELP_TALK => 'Plé_cabhrach',
+ NS_CATEGORY => 'Catagóir',
+ NS_CATEGORY_TALK => 'Plé_catagóire'
+);
+
+$namespaceAliases = array(
+ 'Plé_í­omhá' => NS_IMAGE_TALK,
+ 'Múnla' => NS_TEMPLATE,
+ 'Plé_múnla' => NS_TEMPLATE_TALK,
+ 'Rang' => NS_CATEGORY
+);
+
+$linkTrail = '/^([a-z]+)(.*)\$/sD';
+
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+
+$messages = array(
+
+# User Toggles'tog-underline' => "Cuir línte faoi na naisc",
+'tog-highlightbroken' => "Cuir dath dearg ar naisc briste, <a href=\"\" class=\"new\">mar sin</a>
+(rogha eile: mar sin<a href=\"\" class=\"internal\">?</a>).",
+'tog-justify' => "Comhfhadaigh na paragraif",
+'tog-hideminor' => "Ná taispeáin fo-athruithe i measc na n-athruithe is déanaí",
+'tog-usenewrc' => "Stíl nua do na hathruithe is déanaí (le JavaScript)",
+'tog-numberheadings' => "Uimhrigh ceannteidil go huathoibríoch",
+'tog-showtoolbar' => 'Taispeáin an barra uirlisí eagair (JavaScript)',
+"tog-editondblclick" => "Cuir leathanaigh in eagar le déchliceáil (JavaScript)",
+"tog-editsection" =>"Cumasaigh mír-eagarthóireacht le naisc mar seo: [athrú]",
+"tog-editsectiononrightclick" =>"Cumasaigh mír-eagarthóireacht le deaschliceáil<br /> ar ceannteidil (JavaScript)",
+"tog-showtoc" =>"Taispeáin an clár ábhair (d'ailt le níos mó ná 3 ceannteidil)",
+"tog-rememberpassword" => "Cuimhnigh m'fhocal faire",
+"tog-editwidth" => "Cuir uasmhéid ar an mbosca eagair",
+"tog-watchdefault" => "Déan faire ar leathanaigh a athraíonn tú",
+"tog-minordefault" => "Déan mionathrú de gach aon athrú, mar réamhshocrú",
+"tog-previewontop" => "Cuir an réamhamharc os cionn an bhosca eagair, <br />agus ná cuir é taobh thíos de",
+'tog-previewonfirst' => 'Taispeáin réamhamharc don chéad athrú',
+"tog-nocache" => "Ciorraigh taisce na leathanach",
+
+'tog-enotifwatchlistpages' => 'Cuir ríomhphost chugam nuair a athraítear leathanaigh',
+'tog-enotifusertalkpages' => 'Cuir ríomhphost chugam nuair a athraítear mo leathanach phlé úsáideora',
+'tog-enotifminoredits' => 'Cuir ríomhphost chugam nuair a dhéantar mionathruithe chomh maith',
+'tog-enotifrevealaddr' => 'Taispeáin mo sheoladh ríomhphoist i dteachtaireachtaí fógra',
+'tog-shownumberswatching' => 'Taispeán an méid úsáideoirí atá ag faire',
+'tog-fancysig' => 'Síniuithe bunúsacha (gan nasc uathoibríoch)',
+'tog-externaleditor' => 'Bain úsáid as eagarthóir seachtrach, mar réamhshocrú',
+'tog-externaldiff' => 'Bain úsáid as difríocht sheachtrach, mar réamhshocrú',
+
+'underline-always' => 'Déan é gach uair é',
+'underline-never' => 'Ná déan é riamh',
+'underline-default' => 'Reamhshocrú ón brabhsálaí',
+
+'sunday' => 'an Domhnach',
+'monday' => 'an Luan',
+'tuesday' => 'an Mháirt',
+'wednesday' => 'an Chéadaoin',
+'thursday' => 'an Déardaoin',
+'friday' => 'an Aoine',
+'saturday' => 'an Satharn',
+'january' => 'Eanáir',
+'february' => 'Feabhra',
+'march' => 'Márta',
+'april' => 'Aibreán',
+'may_long' => 'Bealtaine',
+'june' => 'Meitheamh',
+'july' => 'Iúil',
+'august' => 'Lúnasa',
+'september' => 'Meán Fómhair',
+'october' => 'Deireadh Fómhair',
+'november' => 'Mí na Samhna',
+'december' => 'Mí na Nollag',
+'jan' => 'Ean',
+'feb' => 'Feabh',
+'mar' => 'Márta',
+'apr' => 'Aib',
+'may' => 'Beal',
+'jun' => 'Meith',
+'jul' => 'Iúil',
+'aug' => 'Lún',
+'sep' => 'MFómh',
+'oct' => 'DFómh',
+'nov' => 'Samh',
+'dec' => 'Noll',
+
+
+# Bits of text used by many pages:
+#
+# FIXME
+#
+'categories' => 'Catagóirí',
+'pagecategories' => 'Catagóirí',
+'category_header' => 'Ailt sa chatagóir "$1"',
+"subcategories" => "Fo-chatagóirí",
+
+"mainpage" => "Príomhleathanach",
+"mainpagetext" => "Suiteáladh an ríomhchlár vicí go rathúil.",
+"mainpagedocfooter" => "Féach ar [http://meta.wikimedia.org/wiki/MediaWiki_i18n doiciméid um conas an chomhéadán a athrú]
+agus an [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Lámhleabhar úsáideora] chun cabhair úsáide agus fíoraíochta a fháil.",
+
+'portal' => 'Ionad pobail',
+'portal-url' => '{{ns:4}}:Ionad pobail',
+"about" => "Maidir leis",
+"aboutsite" => "Maidir le {{SITENAME}}",
+'article' => "Leathanach ábhair",
+"aboutpage" => "{{ns:4}}:Maidir leis",
+"help" => "Cabhair",
+"helppage" => "Cabhair:Clár_ábhair",
+"bugreports" => "Fabht-thuairiscí",
+"bugreportspage" => "{{ns:4}}:Fabht-thuairiscí",
+'sitesupport' => 'Síntiúis',
+'sitesupport-url' => '{{ns:4}}:Tacaíocht an tsuímh',
+"faq" => "Ceisteanna Coiteanta",
+"faqpage" => "{{ns:4}}:Ceisteanna_Coiteanta",
+"edithelp" => "Cabhair eagarthóireachta",
+"newwindow" => "(osclaítear i bhfuinneog eile é)",
+"edithelppage" => "{{ns:help}}:Eagarthóireacht",
+"cancel" => "Cealaigh",
+"qbfind" => "Aimsigh",
+"qbbrowse" => "Brabhsáil",
+"qbedit" => "Cuir in eagar",
+"qbpageoptions" => "An leathanach seo",
+"qbpageinfo" => "Comhthéacs",
+"qbmyoptions" => "Mo chuid leathanaigh",
+"qbspecialpages" => "Leathanaigh speisialta",
+"moredotdotdot" => "Tuilleadh...",
+"mypage" => "Mo leathanach",
+"mytalk" => "Mo chuid phlé",
+"anontalk" => "Plé don IP seo",
+"navigation" => "Nascleanúint",
+
+# Metadata in edit box
+'metadata' => '<b>Meiteashonraí</b> (féach ar <a href="$1">here</a> le haghaidh a thuilleadh eolais)',
+
+"currentevents" => "Cursaí reatha",
+'currentevents-url' => 'Cursaí reatha',
+
+'disclaimers' => 'Séanadh',
+"disclaimerpage" => "{{ns:4}}:Séanadh_ginearálta",
+"errorpagetitle" => "Earráid",
+"returnto" => "Dul ar ais go $1.",
+"tagline" => "Ó {{SITENAME}}.",
+"whatlinkshere" => "Leathanaigh a nascaíonn chuig an leathanach seo",
+"help" => "Cabhair",
+"search" => "Cuardaigh",
+"searchbutton" => "Cuardaigh",
+"go" => "Téir",
+'searcharticle' => "Téir",
+"history" => "Stair an lgh seo",
+'history_short' => 'Stair',
+'info_short' => 'Eolas',
+"printableversion" => "Eagrán inphriontáilte",
+"print" => "Priontáil",
+"edit" => "Athraigh an lch seo",
+"editthispage" => "Athraigh an lch seo",
+"delete" => "Scrios",
+"deletethispage" => "Scrios an lch seo",
+"undelete_short" => "Díscrios $1 athruithe",
+"protect" => "Glasáil",
+"protectthispage" => "Glasáil an lch seo",
+"unprotect" => "Díghlasáil",
+"unprotectthispage" => "Díghlasáil an lch seo",
+"newpage" => "Leathanach nua",
+"talkpage" => "Pléigh an lch seo",
+'specialpage' => 'Leathanach Speisialta',
+'personaltools' => 'Uirlisí phearsánta',
+"postcomment" => "Caint ar an lch",
+"articlepage" => "Féach ar an alt",
+'talk' => 'Plé',
+'views' => 'Tuairimí',
+'toolbox' => 'Bosca uirlisí',
+"userpage" => "Féach ar lch úsáideora",
+"projectpage" => "Féach ar lch thionscadail",
+"imagepage" => "Féach ar lch íomhá",
+"viewtalkpage" => "Féach ar phlé",
+"otherlanguages" => "I dteangacha eile",
+"redirectedfrom" => "(Athsheolta ó $1)",
+"lastmodifiedat" => "Athraíodh an leathanach seo ag $2, $1.",
+"viewcount" => "Rochtainíodh an leathanach seo $1 uair.",
+'copyright' => "Tá an t-ábhar le fáil faoin $1.",
+"protectedpage" => "Leathanach glasáilte",
+
+'badaccess' => 'Earráid ceada',
+
+'versionrequired' => 'Tá leagan $1 de MediaWiki de dhíth',
+'versionrequiredtext' => 'Tá an leagan $1 de MediaWiki riachtanach chun an leathanach seo a úsáid. Féach ar [[Speisialta:Version]]',
+
+
+"nbytes" => "$1 beart",
+"ok" => "Déan",
+"editsection" => "athraigh",
+"editold" => "athraigh",
+"toc" => "Clár ábhair",
+"showtoc" => "taispeáin",
+"hidetoc" => "folaigh",
+"thisisdeleted" => "Breathnaigh nó cuir ar ais $1?",
+"restorelink" => "$1 athruithe scriosaithe",
+'feedlinks' => 'Fotha:',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Alt',
+'nstab-user' => 'Lch úsáideora',
+'nstab-media' => 'Lch meáin',
+'nstab-special' => 'Speisialta',
+'nstab-project' => 'Lch thionscadail',
+'nstab-image' => 'Comhad',
+'nstab-mediawiki' => 'Teachtaireacht',
+'nstab-template' => 'Teimpléad',
+'nstab-help' => 'Cabhair',
+'nstab-category' => 'Catagóir',
+
+# Main script and global functions
+#
+"nosuchaction" => "Níl a leithéid de ghníomh ann",
+"nosuchactiontext" => "Níl aithníonn an vicí an gníomh atá ann sa líonsheoladh.",
+"nosuchspecialpage" => "Níl a leithéid de leathanach speisialta ann",
+"nospecialpagetext" => "Níl aithníonn an vicí an leathanach speisialta a d'iarr tú ar.",
+
+# General errors
+#
+"error" => "Earráid",
+"databaseerror" => "Earráid sa bunachar sonraí",
+"dberrortext" => "Tharlaigh earráid chomhréire in iarratas chuig an bhunachar sonraí.
+<blockquote><tt>$1</tt></blockquote>, ón suim \"<tt>$2</tt>\",
+an iarratas deireanach chuig an bhunachar sonrai.
+Chuir MySQL an earráid seo ar ais: \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Tharlaigh earráid chomhréire in iarratas chuig an bhunachar
+
+sonraí.
+\"$1\", ón suim \"$2\",
+ab ea an iarratas fiosraithe deireanach chuig an bhunachar sonrai,
+Chuir MySQL an earráid seo ar ais: \"$3: $4\".",
+"noconnect" => "Tá brón orainn! Tá roinnt deacrachtaí teicniúla ag an vicí faoi
+
+láthair,
+agus ní féidir leis teagmháil a dhéanamh leis an mbunachar sonraí.",
+"nodb" => "Theip rogha an bhunachair sonraí $1",
+"cachederror" => "Seo í cóip taisce den leathanach atá á lorg agat (is dócha nach bhfuil sí bord ar bhord leis an leagan
+
+láithreach).",
+'laggedslavemode' => 'Fógra: B\'fhéidir nach bhfuil an leathanach suas chun dáta.',
+"readonly" => "Bunachar sonraí glasáilte",
+"enterlockreason" => "Iontráil cúis don glasáil, agus meastachán
+den uair a díghlasálfar an bunachar sonraí.",
+"readonlytext" => "Tá an bunachar sonraí {{GRAMMAR:genitive|{{SITENAME}}}} glasáilte anois do iontráilí agus athruithe nua
+(is dócha go bhfuil sé do gnáthchothabháil).
+Tar éis seo, díghlasálfar an bunachar sonraí arís.
+Tugadh an míniú seo ag an riarthóir a ghlasáil é:
+$1",
+"missingarticle" => "Chuardaigh an bunachar sonraí ar leathanach a mba chóir bheith
+faighte darb teideal \"$1\" ach níor bhfuarthas an leathanach.
+
+Is dócha gur lean tu nasc chuig sean-dhifríocht nó nasc staire a bhaineann le
+leathanach atá scriosta cheana féin.
+
+Muna bhfuil seo an scéal, b'fhéidir go bhfuair tú amach fabht sna bogearraí MediaWiki.
+Déan nóta den URL le do thoil, agus cuir an ábhar in iúl do riarthóir.",
+'readonly_lag' => "Glasáladh an bunachar sonraí go huathoibríoch, mar tá freastalaithe
+sclábhánta an bhunachair sonraí ag teacht suas chun dáta leis an máistirfhreastalaí
+fós.",
+"internalerror" => "Earráid inmhéanach",
+"filecopyerror" => "Ní féidir an comhad \"$1\" a chóipeáil go \"$2\".",
+"filerenameerror" => "Ní féidir an comhad \"$1\" a athainmnigh mar \"$2\".",
+"filedeleteerror" => "Ní féidir an comhad \"$1\" a scriosaigh amach.",
+"filenotfound" => "Ní bhfuarthas an comhad \"$1\".",
+"unexpected" => "Luach gan súil leis: \"$1\"=\"$2\".",
+"formerror" => "Earráid: ní féidir an foirm a tabhair isteach",
+"badarticleerror" => "Ní féidir an gníomh seo a dhéanamh ar an leathanach seo.",
+"cannotdelete" => "Ní féidir an leathanach nó íomhá sonraithe a scriosaigh. (B'fhéidir gur scrios duine eile é cheana féin.)",
+"badtitle" => "Teideal neamhbhailí",
+"badtitletext" => "Bhí teideal an leathanaigh a d'iarr tú ar neamhbhailí, folamh, nó
+teideal idirtheangach nó idirvicí nasctha go mícheart.",
+"perfdisabled" => "Tá brón orainn! Díchumasaíodh an gné seo ar feadh tamaill chun luas an bhunachair sonraí a chosaint.",
+"perfdisabledsub" => "Is cóip i dtaisce é seo, ó $1:",
+"wrong_wfQuery_params" => "Paraiméadair míchearta don wfQuery()<br />
+Feidhm: $1<br />
+Iarratas: $2",
+'perfcached' => 'Fuarthas na sonraí seo as dtaisce, agus is dócha nach bhfuil siad suas chun dáta:',
+"viewsource" => "Féach ar fhoinse",
+"protectedtext" => "Glasáladh an leathanach seo chun é a chosaint i gcoinne athruithe. Tá go leor
+cúiseanna féideartha don scéal seo. Féach ar
+[[{{ns:project}}:Leathanach glasáilte]] más é do thoil é.
+
+Is féidir leat foinse an leathanaigh seo a féachaint agus a chóipeáil:",
+'sqlhidden' => '(Iarratas SQL folaithe)',
+
+# Login and logout pages
+#
+"logouttitle" => "Logáil amach",
+"logouttext" => "Tá tú logáilte amach anois.
+Is féidir leat an {{SITENAME}} a úsáid fós gan ainm, nó is féidir leat logáil isteach
+arís mar an úsáideoir céanna, nó mar úsáideoir eile. Tabhair faoi deara go taispeáinfear roinnt
+leathanaigh mar atá tú logtha ann fós, go dtí go ghlanfá amach do thaisce brabhsálaí",
+
+"welcomecreation" => "== Tá fáilte romhat, $1! ==
+
+Cruthaíodh do chuntas. Ná déan dearmad ar do sainroghanna phearsanta {{GRAMMAR:genitive|{{SITENAME}}}} a hathrú.",
+
+"loginpagetitle" => "Logáil isteach",
+"yourname" => "D'ainm úsáideora",
+"yourpassword" => "D'fhocal faire",
+"yourpasswordagain" => "Athiontráil d'fhocal faire",
+"remembermypassword" => "Cuimhnigh orm",
+"yourdomainname" => "D'fhearann",
+'externaldberror' => 'Bhí earráid bhunachair sonraí ann maidir le fíordheimhniú seachtrach, nóThere was either an external authentication database error or you are not allowed to update your external account.',
+"loginproblem" => "<b>Bhí fadhb ann maidir leis an logáil isteach.</b><br />Déan iarracht eile!",
+"alreadyloggedin" => "<strong>A húsáideoir $1, tá tú logáilte isteach cheana féin!</strong><br />",
+
+"login" => "Logáil isteach",
+'loginprompt' => "Tá fianáin de dhíth chun logáil isteach a dhéanamh ag {{SITENAME}}.",
+"userlogin" => "Logáil isteach",
+"logout" => "Logáil amach",
+"userlogout" => "Logáil amach",
+"notloggedin" => "Níl tú logáilte isteach",
+"createaccount" => "Cruthaigh cuntas nua",
+"createaccountmail" => "le ríomhphost",
+"badretype" => "D'iontráil tú dhá fhocal faire difriúla.",
+"userexists" => "Tá an ainm úsáideora a d'iontráil tú á úsáid cheana féin. Déan rogha d'ainm eile, más é do thoil é.",
+"youremail" => "Do ríomhphost *",
+'yourrealname' => "D'fhíorainm **",
+'yourlanguage' => 'Teanga',
+'yourvariant' => 'Malairt',
+"yournick" => "Do leasainm (i síniuithe)",
+'prefs-help-email' => '** <strong>Ríomhphost</strong> (roghnach): Leis an tréith seo is féidir teagmháil a dhéanamh leat tríd do leathanach úsáideora nó phlé_úsáideora gan do sheoladh ríomhphost a thaispeáint.',
+'prefs-help-email-enotif' => 'Úsáidtear an seoladh seo chun fógraíocht ríomhphoist a sheoladh dhuit, má chumasaigh tú an rogha sin.',
+'prefs-help-realname' => '* <strong>Fíorainm</strong> (roghnach): má toghaíonn tú é sin a chur ar fáil, úsáidfear é chun
+do chuid dreachtaí a chur i leith tusa.',
+"loginerror" => "Earráid leis an logáil isteach",
+'nocookiesnew' => "Chruthaíodh an cuntas úsáideora, ach níl tú logáilte isteach.
+
+Úsáideann {{SITENAME}} fianáin chun úsáideoirí a logáil isteach. Tá fianáin díchumasaithe agat. Cumasaigh iad le do thoil, agus ansin logáil isteach le d'ainm úsáideora agus d'fhocal faire úrnua.",
+"nocookieslogin" => "Úsáideann {{SITENAME}} fianáin chun úsáideoirí a logáil
+isteach. Tá fianáin díchumasaithe agat. Cumasaigh iad agus déan athiarracht, le do thoil.",
+"noname" => "Níor shonraigh tú ainm úsáideora bailí.",
+"loginsuccesstitle" => "Logáil isteach rathúil",
+"loginsuccess" => "Tá tú logáilte isteach anois sa {{SITENAME}} mar \"$1\".",
+"nosuchuser" => "Níl aon úsáideoir ann leis an ainm \"$1\".
+Cinntigh do litriú, nó bain úsáid as an foirm thíos chun cuntas úsáideora nua a chruthú.",
+'nosuchusershort' => "Níl aon úsáideoir ann leis an ainm \"$1\". Cinntigh do litriú.",
+"wrongpassword" => "D'iontráil tú focal faire mícheart (nó ar iarraidh). Déan iarracht eile le do thoil.",
+"mailmypassword" => "Seol m'fhocal faire chugam.",
+'passwordremindertitle' => "Cuimneachán an fhocail faire ó {{SITENAME}}",
+'passwordremindertext' => "D'iarr duine éigin (tusa de réir cosúlachta, ón seoladh IP $1)
+go sheolfaimis focal faire {{GRAMMAR:genitive|{{SITENAME}}}} nua.
+\"$3\" an focal faire don úsáideoir \"$2\" anois.
+Ba chóir duit lógail isteach anois agus d'fhocal faire a athrú.",
+
+"noemail" => "Níl aon seoladh ríomhphoist i gcuntas don úsáideoir \"$1\".",
+"passwordsent" => "Cuireadh focal faire nua chuig an seoladh ríomhphoist atá cláraithe do \"$1\".
+Nuair atá sé agat, logáil isteach arís le do thoil chun fíordheimhniu a dhéanamh.",
+'eauthentsent' => "Cuireadh teachtaireacht ríomhphoist chuig an seoladh
+chun fíordheimhniú a dhéanamh. Chun fíordheimhniú a dhéanamh gur leatsa an cuntas, caithfidh tú glac leis an teachtaireacht sin nó ní sheolfar aon rud eile chuig do chuntas.",
+'mailerror' => "Tharlaigh earráid leis an seoladh: $1",
+'acct_creation_throttle_hit' => 'Tá brón orainn, ach tá tú i ndiadh $1 cuntas á chruthú. Ní féidir leat níos mó a dhéanamh.',
+
+'emailauthenticated' => 'D\'fhíordheimhníodh do sheoladh ríomhphoist ar $1.',
+'emailnotauthenticated' => 'Ní dhearna fíordheimhniú ar do sheoladh ríomhphoist fós, agu díchumasaítear na hardtréithe ríomhphoist go dtí go fíordheimhneofaí é (d.c.f.).
+Chun fíordheimhniú a dhéanamh, logáil isteach leis an focal faire neamhbhuan atá seolta chugat, nó iarr ar ceann nua ar an leathanach logála istigh.',
+'invalidemailaddress' => 'Ní féidir an seoladh ríomhphoist a ghlacadh leis mar is dócha go bhfuil formáid neamhbhailí aige.
+
+Iontráil seoladh dea-fhormáidte le do thoil, nó glan an réimse sin.',
+
+# Edit page toolbar
+'bold_sample'=>'Cló trom',
+'bold_tip'=>'Cló trom',
+'italic_sample'=>'Cló Iodáileach',
+'italic_tip'=>'Cló Iodáileach',
+'link_sample'=>'Ainm naisc',
+'link_tip'=>'Nasc inmhéanach',
+'extlink_sample'=>'http://www.sampla.com ainm naisc',
+'extlink_tip'=>'Nasc seachtrach (cuimhnigh an réimír http://)',
+'headline_sample'=>'Cló ceannlíne',
+'headline_tip'=>'Ceannlíne Leibhéil 2',
+'math_sample'=>'Cuir foirmle isteach anseo',
+'math_tip'=>'Foirmle matamataice (LaTeX)',
+'nowiki_sample'=>'Cuir téacs neamh-fhormáide anseo',
+'nowiki_tip'=>'Scaoil thar ar fhormáid mearshuímh',
+'image_sample'=>'Sámpla.jpg',
+'image_tip'=>'Íomhá leabaithe',
+'media_sample'=>'Sámpla.mp3',
+'media_tip'=>'Nasc chuig comhad meáin',
+'sig_tip'=>'Do shíniú le stampa ama',
+'hr_tip'=>'Líne cothrománach (inúsáidte go coigilteach)',
+
+# Edit pages
+#
+"summary" => "Achoimriú",
+"subject" => "Ábhar/ceannlíne",
+"minoredit" => "Is mionathrú é seo",
+"watchthis" => "Déan faire ar an lch seo",
+"savearticle" => "Sábháil an lch",
+"preview" => "Réamhamharc",
+"showpreview" => "Taispeáin réamhamharc",
+"blockedtitle" => "Tá an úsáideoir seo faoi chosc",
+"blockedtext" => "Chuir $1 cosc ar d'ainm úsáideora nó ar do sheoladh IP.
+Seo é an cúis a thugadh:<br />''$2''<p>Is féidir leat teagmháil a dhéanamh le $1 nó le ceann eile de na
+[[{{ns:4}}:Riarthóirí|riarthóirí]] chun an cosc a phléigh.
+
+Tabhair faoi deara nach bhfuil cead agat an gné \"cuir ríomhphost chuig an úsáideoir seo\" a úsáid
+mura bhfuil seoladh ríomhphoist bailí cláraithe i do [[Speisialta:Preferences|shainroghanna úsáideora]].
+
+Is é $3 do sheoladh IP. Más é do thoil é, déan tagairt den seoladh seo le gach ceist a chuirfeá.",
+"whitelistedittitle" => "Logáil isteach chun athrú a dhéanamh",
+"whitelistedittext" => "Ní mór duit [[Speisialta:Userlogin|logáil isteach]] chun ailt a athrú.",
+"whitelistreadtitle" => "Logáil isteach chun ailt a léamh",
+"whitelistreadtext" => "Ní mór duit [[Speisialta:Userlogin|logáil isteach]] chun ailt a léamh.",
+"whitelistacctitle" => "Níl cead agat cuntas a chruthú",
+"whitelistacctext" => "Chun cuntais nua a chruthú sa vicí seo, caithfidh tú [[Speisialta:Userlogin|logáil
+isteach]] agus caithfidh go bhfuil an cead riachtanach agat.",
+'loginreqtitle' => 'Tá logáil isteach de dhíth ort',
+"accmailtitle" => "Seoladh an focal faire.",
+"accmailtext" => "Seoladh chuig $2 focal faire an úsáideora '$1'.",
+"newarticle" => "(Nua)",
+"newarticletext" =>
+"Lean tú nasc chuig leathanach a nach bhfuil ann fós.
+Chun an leathanach a chruthú, tosaigh ag clóscríobh san bosca anseo thíos
+(féach ar an [[{{ns:project}}:Cabhair|leathanach cabhrach]] chun a thuilleadh eolais a fháil).
+Má tháinig tú anseo as dearmad, brúigh an cnaipe '''ar ais''' ar do líonléitheoir.",
+"anontalkpagetext" => "---- ''Is é seo an leathanach plé do úsáideoir gan ainm nach chruthaigh
+cuntas fós nó nach úsáideann a chuntas phéarsanta. Dá bhrí sin, caithfimid an [[seoladh IP]] uimhriúil a úsáid
+chun é/í a ionannaigh. Is féidir cuid mhaith úsáideoirí an seoladh IP céanna a úsáid. Má tá tú
+i do úsáideoir gan ainm agus má tá sé do thuairim go rinneadh léiriuithe neamhfheidhmeacha fút,
+[[Special:Userlogin|cruthaigh cuntas nó logáil isteach]] le do thoil chun mearbhall a héalú
+le húsáideoirí eile gan ainmneacha amach anseo.''",
+"noarticletext" => "(Níl aon téacs ar an leathanach seo faoi láthair)",
+'clearyourcache' => "'''Tabhair faoi deara:''' Tar éis duit ábhar a shábháil, ní mór duit
+taisce do líonléitheora chun na hathruithe a fheiceáil After saving, you have to clear your
+browser cache to see the changes: '''Mozilla / Netscape:''' roghnaigh ''Athlódáil''
+(nó ''Ctrl-R''), '''IE / Opera:''' ''Ctrl-F5'', '''Safari:''' ''Cmd-R'', '''Konqueror''' ''Ctrl-R''.",
+'usercssjsyoucanpreview' => "<strong>Leid:</strong> Sula sábhálaím tú, úsáid an cnaipe
+'Réamhamharc' chun do CSS/JS nua a tástáil.",
+'usercsspreview' => "'''Cuimhnigh nach bhfuil seo ach réamhamharc do CSS úsáideora -
+níor sábháladh é go fóill!'''",
+'userjspreview' => "'''Cuimhnigh nach bhfuil seo ach réamhamharc do JavaScript úsáideora
+- níor sábháladh é go fóill!'''",
+"updated" => "(Leasaithe)",
+"note" => "<strong>Tabhair faoi deara:</strong>",
+"previewnote" => "Cuimhnigh nach bhfuil seo ach réamhamharc, agus nach sábháladh é fós!",
+"previewconflict" => "San réamhamharc seo, feachann tú an téacs dé réir an eagarbhosca
+thuas mar a taispeáinfear é má sábháilfear é.",
+"editing" => "Ag athrú $1",
+'editinguser' => "Ag athrú $1",
+"editconflict" => "Coimhlint athraithe: $1",
+"explainconflict" => "D'athraigh duine eile an leathanach seo ó shin a thosaigh tú ag athrú é.
+Sa bhosca seo thuas feiceann tú téacs an leathanaigh mar atá sé faoi láthair.
+Tá do chuid athruithe sa bhosca thíos.
+Caithfidh tú do chuid athruithe a chumasadh leis an leagan láithreach.
+Nuair a brúann tú ar an cnaipe \"Sábháil an leathanach\", ní shábhálfar aon rud <b>ach
+amháin</b> an téacs sa bhosca thuas.<p>",
+"yourtext" => "Do chuid téacs",
+"storedversion" => "Eagrán sábháilte",
+"editingold" => "<strong>AIRE: Tá tú ag athrú eagrán an leathanaigh atá as dáta.
+Dá shábhálfá é, caillfear aon athrú a rinneadh ó shin an eagrán seo.</strong>",
+"yourdiff" => "Difríochtaí",
+/*"copyrightwarning" => "Tabhair faoi dearadh go scaoiltear gach ceart le {{SITENAME}} de réir tearmaí an <i>GNU Free Documentation License</i> (féach ar $1 le haghaidh tuilleadh eolais).
+Munar mian leat go gcuirfí do chuid scríbhinn in eagar go héadrócaireach agus go n-athdálfaí gan teorainn iad, ná
+tabhair isteach anseo iad.<br />
+Ina theannta sin, geallann tú gur scríobh tú féin an dréacht seo, nó gur chóipeáil tú é ó fhoinse gan chóipcheart
+é. <strong>NÁ TABHAIR ISTEACH OBAIR LE CÓIPCHEART GAN CHEAD!</strong>",*/
+"copyrightwarning2" => "Tabhair faoi dearadh gur féidir le cuiditheoirí eile gach dréacht do {{SITENAME}} a chur in eagar, a athrú agus a scriosadh. Munar mian leat go gcuirfí do chuid scríbhinn in eagar go héadrócaireach agus go n-athdálfaí gan teorainn iad, ná tabhair isteach anseo iad.<br /> Ina theannta sin, geallann tú gur scríobh tú féin an dréacht seo, nó gur chóipeáil tú é ó fhoinse gan chóipcheart é (féach ar $1 le haghaidh tuilleadh eolais). <strong>NÁ TABHAIR ISTEACH OBAIR LE CÓIPCHEART GAN CHEAD!</strong>",
+"longpagewarning" => "AIRE: Tá an leathanach seo $1 cilibheart i bhfad; ní féidir le roinnt brabhsálaithe
+leathanaigh a athrú má tá siad breis agus $1KiB, nó níos fada ná sin.
+Más féidir, giotaigh an leathanach i gcodanna níos bige.",
+"readonlywarning" => "AIRE: Glasáladh an bunachar sonraí, agus mar sin
+ní féidir leat do chuid athruithe a shábháil díreach anois. B'fhéidir gur mhaith leat an téacs a ghearr is
+ghreamú i gcomhad téacs agus é a úsáid níos déanaí.",
+"protectedpagewarning" => "AIRE: Glasáladh an leathanach seo, agus ní féidir le duine ar bith é a athrú
+ach amhaín na húsáideoirí le pribhléidí oibreora córais. Bí cinnte go leanann tú na
+[[Project:Treoirlínte_do_leathanaigh_glasáilte|treoirlínte do leathanaigh
+glasáilte]].",
+
+# History pages
+#
+"revhistory" => "Stáir athraithe",
+"nohistory" => "Níl aon stáir athraithe ag an leathanach seo.",
+"revnotfound" => "Ní bhfuarthas an athrú",
+"revnotfoundtext" => "Ní bhfuarthas seaneagrán an leathanaigh a d'iarr tú ar.
+Cinntigh an URL a d'úsáid tú chun an leathanach seo a rochtain.",
+"loadhist" => "Ag lódáil stáir an leathanaigh",
+"currentrev" => "Leagan láithreach",
+"revisionasof" => "Leagan ó $1",
+'previousrevision' => '?Leagan níos sine',
+'nextrevision' => 'Leagan níos nuaí?',
+'currentrevisionlink' => 'féach ar an leagan laithreach',
+"cur" => "rth",
+"next" => "lns",
+"last" => "rmh",
+"orig" => "bun",
+'histlegend' => "Difríochtaí a roghnú: marcáil na boscaí de na eagráin atá ag teastail uait á cuir i gcomparáid, agus brúigh Iontráil nó an cnaipe ag bun an leathanaigh.<br />
+Eochair: (rth) = difríocht leis an leagan láithreach,
+(rmh) = difríocht leis an eagrán roimhe, M = mionathrú",
+'deletedrev' => '[scriosta]',
+'histfirst' => 'An ceann is luaithe',
+'histlast' => 'An ceann is déanaí',
+
+# Diffs
+#
+"difference" => "(Difríochtaí idir leaganacha)",
+"loadingrev" => "ag lódáil leagan don difríocht",
+"lineno" => "Líne $1:",
+"editcurrent" => "Athraigh leagan láithreach an leathanaigh seo",
+'selectnewerversionfordiff' => 'Roghnaigh leagan níos nuaí mar chomparáid',
+'selectolderversionfordiff' => 'Roghnaigh leagan níos sine mar chomparáid',
+'compareselectedversions' => 'Cuir na leagain roghnaithe i gcomparáid',
+
+# Search results
+#
+"searchresults" => "Torthaí an chuardaigh",
+"searchresulttext" => "Féach ar [[{{ns:project}}:Cuardach|Cuardach sa {{SITENAME}}]] chun a thuilleadh eolais a fháil maidir le cuardaigh {{GRAMMAR:genitive|{{SITENAME}}}}.",
+"searchsubtitle" => "Don iarratas \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Don iarratas \"$1\"",
+"badquery" => "Iarratas fiosraithe neamhbhailí",
+"badquerytext" => "Nior éirigh linn d'iarratas a phróiseáil.
+Is dócha go rinne tú cuardach ar focal le níos lú ná trí litir,
+gné a nach bhfuil le tacaíocht aige fós.
+B'fhéidir freisin go mhíchlóshcríobh tú an leagan, mar shampla
+\"éisc agus agus lanna\". Déan athiarracht.",
+"matchtotals" => "Bhí an cheist \"$1\" ina mhacasamhail le $2 teidil alt
+agus leis an téacs i $3 ailt.",
+"noexactmatch" => "Níl aon leathanach ann leis an teideal áirithe seo air. Tá cuardach á dhéanamh sa téacs iomlán...",
+"titlematches" => "Tá macasamhla teidil alt ann",
+"notitlematches" => "Níl macasamhla teidil alt ann",
+"textmatches" => "Tá macasamhla téacs alt ann",
+"notextmatches" => "Níl macasamhla téacs alt ann",
+"prevn" => "na $1 roimhe",
+"nextn" => "an chéad $1 eile",
+"viewprevnext" => "Taispeáin ($1) ($2) ($3).",
+"showingresults" => "Ag taispeáint thíos <b>$1</b> toraidh, ag tosachh le #<b>$2</b>.",
+"showingresultsnum" => "Ag taispeáint thíos <b>$3</b> toraidh, ag tosach le #<b>$2</b>.",
+"nonefound" => "<strong>Tabhair faoi deara</strong>: go minic, ní éiríonn cuardaigh nuair a cuardaítear focail an-coiteanta, m.sh., \"ag\" is \"an\",
+a nach bhfuil innéacsaítear, nó nuair a ceisteann tú níos mó ná téarma amháin (ní
+taispeáintear sna toraidh ach na leathanaigh ina bhfuil go leoir na téarmaí cuardaigh).",
+"powersearch" => "Cuardaigh",
+"powersearchtext" => "
+Cuardaigh sna hainmspásanna :<br />
+$1<br />
+$2 Cuir athsheolaidh in áireamh Cuardaigh ar $3 $9",
+"searchdisabled" => "<p>Tá brón orainn! Mhíchumasaíodh an cuardach téacs iomlán go sealadach chun luas an tsuímh
+a chosaint. Idir an dá linn, is féidir leat an cuardach Google anseo thíos a úsáid - b'fhéidir go bhfuil sé as dáta.</p>",
+
+"blanknamespace" => "(Gnáth)",
+
+# Preferences page
+#
+"preferences" => "Sainroghanna",
+"prefsnologin" => "Níl tú logáilte isteach",
+"prefsnologintext" => "Ní mór duit [[Speisialta:Userlogin|logáil isteach]] chun do chuid sainroghanna phearsanta a shocrú.",
+"prefsreset" => "D'athraíodh do chuid sainroghanna ar ais chuig an leagan bunúsach ón stóras.",
+"qbsettings" => "Sainroghanna an bosca uirlisí",
+"changepassword" => "Athraigh d'fhocal faire",
+"skin" => "Craiceann",
+"math" => "Ag aistriú na matamaitice",
+"dateformat" => "Formáid dáta",
+'datedefault' => 'Is cuma liom',
+"math_failure" => "Theip anailís an fhoirmle",
+"math_unknown_error" => "earráid anaithnid",
+"math_unknown_function" => "foirmle anaithnid",
+"math_lexing_error" => "Theipeadh anailís an fhoclóra",
+"math_syntax_error" => "earráid comhréire",
+'math_image_error' => 'Theipeadh aistriú an PNG; tástáil má tá na ríomhchláir latex, dvips, gs, agus convert
+i suite go maith.',
+'math_bad_tmpdir' => 'Ní féidir scríobh chuig an fillteán mata sealadach, nó é a chruthú',
+'math_bad_output' => 'Ní féidir scríobh chuig an fillteán mata aschomhaid, nó é a chruthú',
+'math_notexvc' => 'Níl an ríomhchlár texvc ann; féach ar mata/EOLAIS chun é a sainathrú.',
+'prefs-personal' => 'Sonraí úsáideora',
+'prefs-rc' => 'Athruithe le déanaí agus taispeántas stumpaí',
+'prefs-misc' => 'Sainroghanna éagsúla',
+"saveprefs" => "Sábháil sainroghanna",
+"resetprefs" => "Athshuigh sainroghanna",
+"oldpassword" => "Seanfhocal faire",
+"newpassword" => "Nuafhocal faire",
+"retypenew" => "Athiontráil an nuafhocal faire",
+"textboxsize" => "Eagarthóireacht",
+"rows" => "Sraitheanna",
+"columns" => "Colúin",
+"searchresultshead" => "Sainroghanna do toraidh cuardaigh",
+"resultsperpage" => "Cuairt le taispeáint ar gach leathanach",
+"contextlines" => "Línte le taispeáint do gach cuairt",
+"contextchars" => "Litreacha chomhthéacs ar gach líne",
+"stubthreshold" => "Tairseach do taispeántas stumpaí",
+"recentchangescount" => "Méid teideal sna hathruithe le déanaí",
+"savedprefs" => "Sábháladh do chuid sainroghanna.",
+'timezonelegend' => 'Crios ama',
+"timezonetext" => "Iontráil an méid uaireanta a difríonn do am áitiúil
+den am an freastalaí (UTC).",
+"localtime" => "An t-am áitiúil",
+"timezoneoffset" => "Difear",
+"servertime" => "Am an freastalaí anois",
+"guesstimezone" => "Líon ón líonléitheoir",
+"defaultns" => "Cuardaigh sna ranna seo a los éagmaise:",
+'default' => 'réamhshocrú',
+'files' => 'Comhaid',
+
+# User levels special page
+#
+
+# switching pan
+'editusergroup' => 'Cuir Grúpái Úsáideoirí In Eagar',
+
+# user groups editing
+'saveusergroups' => 'Sábháil Grúpaí Úsáideoirí',
+
+# user groups editing
+#
+'userrights-editusergroup' => 'Cuir grúpaí na n-úsáideoirí in eagar',
+'saveusergroups' => 'Sábháil Grúpaí na n-Úsáideoirí',
+'userrights-groupsmember' => 'Ball de:',
+'userrights-groupsavailable' => 'Grúpaí atá le fáil:',
+'userrights-groupshelp' => 'Roghnaigh na grúpaí a bhfuil tú ag cur an úsáideoir leis nó ag baint an úsáideoir de.
+Ní bheidh aon athrú le grúpaí neamhroghnaithe. Is féidir leat grúpa a díroghnú le húsáid CTRL + cléchliceáil',
+
+# Recent changes
+#
+"changes" => "athruithe",
+"recentchanges" => "Athruithe is déanaí",
+"recentchangestext" => "Déan faire ar na hathruithe is déanaí sa vicí ar an leathanach seo.",
+"rcnote" => "Is iad seo a leanas na <strong>$1</strong> athruithe is déanaí sna <strong>$2</strong> lae seo caite.",
+"rcnotefrom" => "Is iad seo a leanas na hathruithe ó <b>$2</b> (go dti <b>$1</b> taispeánaithe).",
+"rclistfrom" => "Taispeáin nua-athruithe dom ó <b>$1</b> anuas)",
+# "rclinks" => "Taispeáin na $1 athruithe is déanaí sna $2 uaire seo caite / $3 laethanta seo caite.",
+# "rclinks" => "Taispeáin na $1 athruithe is déanaí sna $2 laethanta seo caite.",
+"rclinks" => "Taispeáin na $1 athruithe is déanaí sna $2 laethanta seo caite; $3 mionathruithe",
+"diff" => "difr",
+"hist" => "stáir",
+"hide" => "Folaigh",
+"show" => "taispeán",
+"minoreditletter" => "m",
+"newpageletter" => "N",
+'sectionlink' => '?',
+'number_of_watching_users_pageview' => '[$1 úsáideoirí ag breathnú]',
+
+# Upload
+#
+"upload" => "Uaslódáil comhad",
+"uploadbtn" => "Uaslódáil comhad",
+"reupload" => "Athuaslódáil",
+"reuploaddesc" => "Dul ar ais chuig an fhoirm uaslódála.",
+"uploadnologin" => "Nil tú logáilte isteach",
+"uploadnologintext" => "Ní mór duit <a href=\"" .
+ "{{localurle:Speisialta:Userlogin}}\">logáil isteach</a>
+chun comhaid a huaslódáil.",
+"uploaderror" => "Earráid uaslódála",
+"uploadtext" => "'''STOP!''' Sul má dhéanann tú uaslódáil anseo,
+bí cinnte an [[{{ns:project}}:Polasaí_úsáide_íomhá|polasaí úsáide íomhá]] atá ag {{SITENAME}} a léamh agus géilleadh dó.
+
+Má tá comhad ann cheana leis an ainm céanna atá tú ag tabhairt don chomhad nua, cuirfear an comhad nua
+in áit an sean-chomhaid gan fógra.
+Mar sin, muna roghnaíonn tú comhad, is fearr féachaint an bhfuil comhad leis an ainm chéanna ann cheana féin.
+
+Le breathnú nó cuardach a dhéanamh ar íomhánna a uaslódáladh cheana féin, téigh go dtí an
+[[Speisialta:Imagelist|liosta íomhánna]] uaslódáilte. Déantar liosta de uaslódála agus scriosaidh ar an [[{{ns:project}}:Liosta_uaslódála|liosta uaslódála]].
+
+Bain úsáid as an bhfoirm thíos chun íomhá-chomhaid nua a uaslódáil. Is féidir leat na h-íomhánna a úsáid i do chuid alt.
+Ar an gcuid is mó de na líonléitheoirí, feicfidh tú cnaipe \"Brabhsáil...\" nó rud éigin mar sin.
+Lé brú ar an gcnaipe seo, gheobhaigh tú an ghnáthbhosca dialóige comhad-oscailte dod'chóras oibriúcháin.
+Nuair a roghnaíonn tú comhad, líonfar ainm an chomhaid sa téacsbhosca in aice leis an gcnaipe.
+Caithfidh tú dearfú le brú sa bhosca beag nach bhfuil tú ag sárú aon chóipcheart leis an suaslódáil seo.
+Brúigh an cnaipe \"Uaslódáil\" chun an uaslódáil a chríochnú. Mura bhfuil nasc Idirlín tapaidh agat,
+beidh roinnt ama uait leis seo.
+
+Is iad na formáidí inmholta ná [[JPEG]] do íomhánna grianghrafa, [[PNG]] do pictiúir tarraingte agus léaráidí,
+agus [[OGG]] d'huaimeanna. Ainmnigh do chuid comhad i mbealach a mbeidh sé éasca ciall a bhaint astu, chun dul
+amú a sheachaint. Chun an íomhá a úsáid san alt, úsáid nasc mar seo:
+
+'''[[{{ns:6}}:comhad.jpg]]'''
+nó '''[[{{ns:6}}:íomhá.png|téacs eile]]''',
+nó '''[[{{ns:-2}}:comhad.ogg]]''' d'fhuaimeanna.
+
+Mar is fíor maidir le leathanaigh {{GRAMMAR:genitive|{{SITENAME}}}}, is féidir le daoine eile do chuid comhad
+
+uaslódáilte a athrú nó a
+scriosadh, má shíltear go bhfuil sé i gcabhair don ciclipéid. Má bhaineann tú mí-úsáid as an gcóras tá seans
+go gcoscfar ón gcóras tú.",
+
+"uploadlog" => "Stair uaslódála",
+"uploadlogpage" => "Stair_uaslódála",
+"uploadlogpagetext" => "Is liosta é seo a leanas de na uaslódáil comhad is deanaí.
+Is am an freastalaí (UTC) iad na hamanna atá anseo thíos.
+<ul>
+</ul>",
+"filename" => "Comhadainm",
+"filedesc" => "Achoimriú",
+"filestatus" => "Stádas cóipchirt",
+"filesource" => "Foinse",
+"copyrightpage" => "{{ns:4}}:Cóipchearta",
+"copyrightpagename" => "Cóipcheart {{GRAMMAR:genitive|{{SITENAME}}}}",
+"uploadedfiles" => "Comhaid uaslódáilte",
+"minlength" => "Caithfidh trí litreacha ar a laghad bheith ann sa comhadainm.",
+'illegalfilename' => 'Tá litreacha san comhadainm "$1" nach ceadaítear in ainm leathanaigh. Athainmnigh
+an comhad agus déan athiarracht, más é do thoil é.',
+"badfilename" => "D'athraíodh an comhadainm bheith \"$1\".",
+"badfiletype" => "Níl \".$1\" ina formáid comhaid íomhá inmholta.",
+"largefile" => "Moltar nach uaslódálaítear comhaid íomhá thar 100kb i méid.",
+'emptyfile' => "De réir a chuma, ní aon rud san chomhad a d'uaslódáil tú ach comhad folamh. Is dócha gur
+míchruinneas é seo san ainm chomhaid. Seiceáil más é an comhad seo atá le huaslódáil agat.",
+"successfulupload" => "Uaslódáil rathúil",
+"fileuploaded" => "Uaslódáladh an comhad \"$1\" go rathúil.
+Lean an nasc seo: ($2) chuig an leathanach cuir sios agus líon isteach
+eolas faoin comhad, mar shampla cá bhfuarthas é, cathain a
+chruthaíodh é agus rud eile ar bith tá 'fhios agat faoi. Más íomhá an comhad seo,
+is féidir leat é a hionsú mar sin: <tt>[[Íomhá:$1|mion|Cur síos]]</tt>",
+"uploadwarning" => "Rabhadh suaslódála",
+"savefile" => "Sábháil comhad",
+"uploadedimage" => "D'uaslódáladh \"$1\"",
+'uploaddisabled' => 'Tá brón orainn, díchumasaítear an córas uaslódála faoi láthair.',
+'uploadcorrupt' => 'Tá an comhad truaillithe nó tá iarmhír comhadainm neamhbhailí aige. Scrúdaigh an comhad agus
+uaslódáil é arís, le do thoil.',
+'uploadvirus' => 'Tá víreas ann sa comhad seo! Eolas: $1',
+'sourcefilename' => 'Comhadainm foinse',
+'destfilename' => 'Comhadainm sprice',
+
+# Image list
+#
+"imagelist" => "Liosta íomhánna",
+"imagelisttext" => "Is liosta é seo a leanas de $1 íomhánna, curtha in eagar le $2.",
+"getimagelist" => "ag fáil an liosta íomhánna",
+"ilsubmit" => "Cuardaigh",
+"showlast" => "Taispeáin na $1 íomhánna seo caite, curtha in eagar le $2.",
+"byname" => "de réir hainm",
+"bydate" => "de réir dáta",
+"bysize" => "de réir méid",
+"imgdelete" => "scrios",
+"imgdesc" => "curs",
+"imglegend" => "Eochair: (curs) = taispeáin/athraigh an cur síos comhaid.",
+"imghistory" => "Stair an chomhaid",
+"revertimg" => "ath",
+"deleteimg" => "scr",
+"deleteimgcompletely" => "Scrios gach leasú don comhad seo",
+"imghistlegend" => "Eochair: (rth) = an leagan láithreach is ea seo, (scr) = scrios an
+seanleagan seo, (ath) = athúsáid an seanleagan seo.
+<br /><i>Bruigh an dáta chun feach ar an íomhá mar a suaslódálaíodh é ar an dáta sin</i>.",
+"imagelinks" => "Naisc íomhá",
+"linkstoimage" => "Is iad na leathanaigh seo a leanas a nascaíonn chuig an íomhá seo:",
+"nolinkstoimage" => "Níl aon leathanach ann a nascaíonn chuig an íomhá seo.",
+'sharedupload' => 'Is uaslodáil roinnte atá ann sa comhad seo, agus is féidir le tionscadail eile é a úsáid.',
+'shareduploadwiki' => 'Féach ar an [leathanach cur síos don comhad $1] le tuilleadh eolais.',
+'noimage' => 'Níl aon chomhad ann leis an ainm seo, ba féidir leat [$1 é a uaslódáil]',
+'uploadnewversion-linktext' => 'Uaslódáil leagan nua den comhad seo',
+
+# Statistics
+#
+"statistics" => "Staidreamh",
+"sitestats" => "Staidreamh do {{SITENAME}}",
+"userstats" => "Staidreamh úsáideora",
+"sitestatstext" => "Is é '''$1''' líon na leathanach sa bunachar sonraí.
+Cuirtear leathanaigh \"phlé\", leathanaigh a bhaineann le {{SITENAME}} í fhéin, ailt \"stumpaí\"
+íosmhéadacha, athsheolaidh, agus leathanaigh eile nach cáileann mar ailt i ndáiríre, san áireamh.
+Ag fágáil na leathanaigh seo as, tá '''$2''' leathanaigh ann atá ina nailt dlisteanacha, is dócha.
+
+In iomlán tá '''$3''' radhairc leathanaigh, agus ''''$4''' athruithe leathanaigh sa {{SITENAME}}
+ó thus athchóiriú an vicí (25 Eanáir, 2004).
+Is é sin '''$5''' athruithe ar meán do gach leathanach, agus '''$6''' radhairc do gach athrú.",
+"userstatstext" => "Tá '''$1''' úsáideoirí cláraithe anseo.
+Tá '''$2''' de na úsáideoirí seo ina riarthóirí (féach ar $3).",
+
+# Maintenance Page
+#
+"disambiguations" => "Leathanaigh idirdhealaithe",
+"disambiguationspage" => "{{ns:project}}:Naisc_go_leathanaigh_idirdhealaithe",
+"disambiguationstext" => "Nascaíonn na ailt seo a leanas go <i>leathanach
+idirdhealaithe</i>. Ba chóir dóibh nasc a dhéanamh dón ábhar áirithe atá i gceist.<br />Tugtar
+an teideal \"idirdhealán\" ar leathanach má tá nasc ar $1 dó.<br /><i>Ní</i> cuirtear ar
+an liosta seo naisc as na hainmspásanna eile.",
+"doubleredirects" => "Athsheolaidh dúbailte",
+"doubleredirectstext" => "<b>Tabhair faoi deara:</b> B'fheidir go bhfuil toraidh bréagacha ar an liosta seo.
+De ghnáth cíallaíonn sé sin go bhfuil téacs breise le naisc thíos sa chéad #REDIRECT no #ATHSHEOLADH.<br />\n Sa
+gach sraith tá náisc chuig an chéad is an dara athsheoladh, chomh maith le chéad líne an dara téacs athsheolaidh. De
+ghnáth tugann sé sin an sprioc-alt \"fíor\".",
+"brokenredirects" => "Athsheolaidh Briste",
+"brokenredirectstext" => "Is iad na athsheolaidh seo a leanas a nascaíonn go ailt nach bhfuil ann fós.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Leathanaigh dhílleachtacha",
+'uncategorizedpages' => 'Leathanaigh gan catagóir',
+'unusedcategories' => 'Catagóirí nach úsáidtear',
+"unusedimages" => "Íomhánna nach úsáidtear",
+"popularpages" => "Leathanaigh coitianta",
+"nviews" => "$1 radhairc",
+"wantedpages" => "Leathanaigh de dhíth",
+"nlinks" => "$1 naisc",
+"allpages" => "Na leathanaigh go léir",
+'nextpage' => 'An lch a leanas ($1)',
+"randompage" => "Leathanach fánach",
+"shortpages" => "Leathanaigh gearra",
+"longpages" => "Leathanaigh fada",
+'deadendpages' => 'Leathanaigh caocha',
+"listusers" => "Liosta úsáideoirí",
+"specialpages" => "Leathanaigh speisialta",
+"spheading" => "Leathanaigh speisialta do gach úsáideoir",
+
+"recentchangeslinked" => "Athruithe gaolmhara",
+"rclsub" => "(go leathanaigh nasctha ó \"$1\")",
+"newpages" => "Leathanaigh nua",
+"ancientpages" => "Na leathanaigh is sine",
+"intl" => "Naisc idirtheangacha",
+'move' => 'Athainmnigh',
+"movethispage" => "Athainmnigh an leathanach seo",
+"unusedimagestext" => "<p>Tabhair faoi deara gur féidir le shuímh
+eile naisc a dhéanamh leis an íomha le URL díreach,
+agus mar sin bheadh siad ar an liosta seo fós cé go bhfuil siad
+in úsáid faoi láthair.",
+'unusedcategoriestext' => 'Tá na leathanaigh catagóire seo a leanas ann, cé nach úsáidtear
+iad in aon alt eile nó in aon chatagóir eile.',
+"booksources" => "Leabharfhoinsí",
+'categoriespagetext' => 'Tá na catagóir seo a leanas ann sa vicí.',
+'data' => 'Sonraí',
+"booksourcetext" => "Liosta is ea seo thíos de suímh eile a
+dhíolann leabhair nua agus athdhíolta, agus tá seans ann go bhfuil eolas
+breise acu maidir leis na leabhair a bhfuil tú ag iarradh ar.
+Níl aon baint ag {{SITENAME}} le gnó ar bith anseo, agus ní
+aontú leo é an liosta seo.",
+'isbn' => 'ISBN',
+"alphaindexline" => "$1 go $2",
+'version' => 'Leagan',
+'log' => 'Logaí',
+'alllogstext' => 'Taispeántas comhcheangaltha de logaí a bhaineann le huaslódáil, scriosadh, glasáil, coisc,
+agus oibreoirí córais. Is féidir leat an taispeántas a ghéarú - roghnaigh an saghas loga, an ainm úsáideora, nó an
+leathanach atá i gceist agat.',
+
+# Special:Allpages
+'nextpage' => 'An leathanach a leanas ($1)',
+'allarticles' => 'Gach alt',
+'allpagesprev' => 'Roimhe',
+'allpagesnext' => 'Ar aghaidh',
+'allpagessubmit' => 'Dul',
+
+# Email this user
+#
+"mailnologin" => "Níl aon seoladh maith ann",
+"mailnologintext" => "Ní mór duit bheith <a href=\"{{localurl:Special:Userlogin\">logáilte isteach</a>
+agus bheith le seoladh ríomhphoist bhailí i do chuid <a href=\"{{localurl:Special:Preferences}}\">sainroghanna</a>
+más mian leat ríomhphost a sheoladh chuig úsáideoirí eile.",
+"emailuser" => "Cuir ríomhphost chuig an úsáideoir seo",
+"emailpage" => "Seol ríomhphost",
+"emailpagetext" => "Má d'iontráil an úsáideoir seo seoladh ríomhphoist bhailí
+ina chuid sainroghanna úsáideora, cuirfidh an foirm anseo thíos teachtaireacht amháin do.
+Beidh do seoladh ríomhphoist a d'iontráil tú i do chuid sainroghanna úsáideora
+sa bhosca \"Seoltóir\" an riomhphoist, agus mar sin ba féidir léis an faighteoir ríomhphost eile a chur leatsa.",
+'usermailererror' => 'Earráid leis an píosa ríomhphoist:',
+'defemailsubject' => "Ríomhphost {{GRAMMAR:genitive|{{SITENAME}}}}",
+"noemailtitle" => "Níl aon seoladh ríomhphoist ann",
+"noemailtext" => "Níor thug an úsáideoir seo seoladh ríomhphoist bhailí, nó shocraigh sé nach
+mian leis ríomhphost a fháil ón úsáideoirí eile.",
+"emailfrom" => "Seoltóir",
+"emailto" => "Chuig",
+"emailsubject" => "Ábhar",
+"emailmessage" => "Teachtaireacht",
+"emailsend" => "Seol",
+"emailsent" => "Ríomhphost seolta",
+"emailsenttext" => "Seoladh do theachtaireacht ríomhphoist go ráthúil.",
+
+# Watchlist
+#
+"watchlist" => "Mo liosta faire",
+"nowatchlist" => "Níl aon rud i do liosta faire.",
+"watchnologin" => "Níl tú logáilte isteach",
+"watchnologintext" => "Ní mór duit <a href=\"" .
+ "{{localurle:Speisialta:Userlogin}}\">logáil isteach</a>
+chun do liosta faire a athrú.",
+"addedwatch" => "Curtha san liosta faire",
+"addedwatchtext" => "Cuireadh an leathanach \"$1\" le do <a href=\"" .
+ "{{localurle:Speisialta:Watchlist}}\">liosta faire</a>.
+Cuirfear athruithe amach anseo, don leathanach sin agus don leathanach phlé, ar an liosta ann,
+agus beidh <b>cló trom</b> ar a theideal san <a href=\"" .
+ "{{localurle:Speisialta:Recentchanges}}\">liosta de na hathruithe is déanaí</a> sa chaoi go bhfeicfeá iad go héasca.</p>
+<p>Más mian leat an leathanach a bain amach do liosta faire níos déanaí, brúigh ar \"Stop ag faire\" ar an taobhbharra.",
+"removedwatch" => "Bainthe amach ón liosta faire",
+"removedwatchtext" => "Baineadh an leathanach \"$1\" amach ó do liosta faire.",
+'watch' => 'Fair',
+"watchthispage" => "Fair ar an leathanach seo",
+'unwatch' => 'Stop ag faire',
+"unwatchthispage" => "Stop ag faire",
+"notanarticle" => "Níl alt ann",
+"watchnochange" => "Níor athraíodh ceann ar bith de na leathanaigh atá ar do liosta faire,
+taobh istigh den tréimhse atá roghnaithe agat.",
+"watchdetails" => "Tá tú ag faire ar $1 leathanaigh, gan leathanaigh phlé a chur san áireamh.",
+"watchmethod-recent" => "ag seiceáil na athruithe deireanacha ar do chuid leathanaigh faire",
+"watchmethod-list" => "ag seiceáil na leathanaigh faire ar do chuid athruithe deireanacha",
+"removechecked" => "Bain míreanna marcálaithe as do liosta faire",
+"watchlistcontains" => "Tá $1 leathanaigh i do liosta faire.",
+"watcheditlist" => "Is é seo liosta de na leathanaigh i do liosta faire, in ord aibitre.
+Marcáil boscaí de na leathanaigh atá le baint amach an liosta faire, agus bruigh
+an cnaipe 'bain amach le marcanna' ag bun an leathanaigh.",
+"removingchecked" => "Ag baint amach na míreanna ón liosta faire, mar a iarraidh...",
+"couldntremove" => "Níor baineadh amach an mír '$1'...",
+"iteminvalidname" => "Fadhb leis an mír '$1', ainm neamhbhailí...",
+"wlnote" => "Is iad seo na $1 athruithe deireanacha sna <b>$2</b> uaire deireanacha.",
+"wlshowlast" => "Taispeáin an $1 uair $2 lá seo caite$3", #FIXME
+'wlsaved' => 'Leagan sábháilte is ea seo de do liosta faire.',
+'wlhideshowown' => '$1 mo chuid athruithe.',
+
+'updatedmarker' => 'leasaithe (ó shin mo chuairt dheireanach)',
+
+'enotif_mailer' => 'Fógrasheoltóir as {{SITENAME}}',
+'enotif_reset' => 'Marcáil gach leathanach bheith tadhlaithe',
+'enotif_newpagetext'=> 'Is leathanach nua é seo.',
+'changed' => 'D\'athraigh',
+'created' => 'Cruthaigh',
+'enotif_subject' => ' $CHANGEDORCREATED $PAGEEDITOR an leathanach $PAGETITLE ag {{SITENAME}}.',
+'enotif_lastvisited' => 'Féach ar $1 le haghaidh gach athrú a rinneadh ó thús na cuairte seo caite a rinne tú.',
+'enotif_body' => 'A $WATCHINGUSERNAME, a chara,
+
+$CHANGEDORCREATED $PAGEEDITOR an leathanach $PAGETITLE ag {{SITENAME}} ar $PAGEEDITDATE, féach ar $PAGETITLE_URL chun an leagan reatha a fháil.
+
+$NEWPAGE
+
+Athchoimriú an úsáideora a rinne é: $PAGESUMMARY $PAGEMINOREDIT
+
+Déan teagmháil leis an úsáideoir:
+r-phost: $PAGEEDITOR_EMAIL
+vicí: $PAGEEDITOR_WIKI
+
+I gcás athruithe eile, ní bheidh aon fhógra eile muna dtéann tú go dtí an leathanach seo. Ba féidir leat na bratacha fógraithe a athrú do gach leathanach ar do liosta faire.
+
+ Is mise le meas,
+ An fógrachóras uathoibríoch ag {{SITENAME}}
+
+--
+Chun do chuid socruithe a athrú maidir leis an liosta faire, teir go dtí
+{{fullurl:Speisialta:Watchlist/edit}}
+
+Aiseolas agus a thuilleadh cabhrach:
+{{fullurl:Help:Contents}}',
+
+# Delete/protect/revert
+#
+"deletepage" => "Scrios an leathanach",
+"confirm" => "Cinntigh",
+"excontent" => "is é seo a raibh an ábhar:",
+"exbeforeblank" => "is é seo a raibh an ábhar roimh an folmhadh:",
+"exblank" => "bhí an leathanach folamh",
+"confirmdelete" => "Cinntigh an scriosadh",
+"deletesub" => "(Ag scriosadh \"$1\")",
+"historywarning" => "Aire: Ta stair ag an leathanach a bhfuil tú ar tí é a scriosadh:",
+"confirmdeletetext" => "Tá tú ar tí leathanach nó íomhá a scrios,
+chomh maith leis a chuid stair, ón bunachar sonraí.
+Cinntigh go mian leis an méid seo a dhéanamh, go dtuigeann tú na
+iarmhairtaí, agus go ndéanann tú é dar le [[{{ns:project}}:Polasaí]].",
+"actioncomplete" => "Gníomh críochnaithe",
+"deletedtext" => "scriosadh \"$1\".
+Féach ar $2 chun cuntas na scriosiadh deireanacha a fháil.",
+"deletedarticle" => "scriosadh \"$1\"",
+"dellogpage" => "Cuntas_scriosaidh",
+"dellogpagetext" => "Seo é liosta de na scriosaidh is deireanacha.
+Is in am an freastalaí (UTC) iad na hamanna anseo thíos.
+<ul>
+</ul>",
+"deletionlog" => "cuntas scriosaidh",
+"reverted" => "Tá eagrán níos luaithe in úsáid anois",
+"deletecomment" => "Cúis don scriosadh",
+"imagereverted" => "D'éirigh le athúsáid eagráin níos luaithe.",
+"rollback" => "Athúsáid seanathruithe",
+"rollbacklink" => "athúsáid",
+"rollbackfailed" => "Theip an athúsáid",
+"cantrollback" => "Ní féidir an athrú a athúsáid; ba é údar an ailt an t-aon duine a rinne athrú dó.",
+"alreadyrolled" => "Ní féidir eagrán níos luaí an leathanaigh [[:$1]]
+le [[Úsáideoir:$2|$2]] ([[Plé úsáideora:$2|Plé]]) a athúsáid; d'athraigh duine eile é cheana fein, nó
+d'athúsáid duine eile eagrán níos luaí cheana féin.
+
+[[Úsáideoir:$3|$3]] ([[Plé úsáideora:$3|Plé]]) an té a rinne an athrú is déanaí.",
+# only shown if there is an edit comment
+"editcomment" => "Seo a raibh an mínithe athraithe: \"<i>$1</i>\".",
+"revertpage" => "D'athúsáideadh an athrú seo caite le $1",
+"protectlogpage" => "Cuntas_cosanta",
+"protectlogtext" => "Seo é liosta de glais a cuireadh ar / baineadh de leathanaigh.
+Féach ar [[{{ns:4}}:Leathanach glasáilte]] chun a thuilleadh eolais a fháil.",
+'protectedarticle' => 'glasáladh "[[$1]]"',
+'unprotectedarticle' => 'díghlasáladh "[[$1]]"',
+'protectsub' =>'(Ag glasáil "$1")',
+'confirmprotecttext' => 'Ar mhaith leat go fírinneach an leathanach seo a ghlasáil?',
+'confirmprotect' => 'Cinntigh an glasáil',
+'protectcomment' => 'Cúis don glasáil',
+'unprotectsub' =>"(Ag díghlasáil \"$1\")",
+'confirmunprotecttext' => 'Ar mhaith leat go fírinneach an leathanach seo a díghlasáil?',
+'confirmunprotect' => 'Cinntigh baint an glais',
+'unprotectcomment' => 'Cúis do baint an glais',
+
+# Undelete
+"undelete" => "Díscrios leathanach scriosta",
+"undeletepage" => "Féach ar leathanaigh scriosta agus díscrios iad",
+"undeletepagetext" => "Scriosaíodh na leathanaigh seo a leanas cheana féin, ach
+tá síad sa cartlann fós agus is féidir iad a dhíscrios.
+Ó am go ham, is féidir an cartlann a fholmhú.",
+"undeletearticle" => "Díscrios alt scriosta",
+"undeleterevisions" => "Cuireadh $1 leagain sa chartlann",
+"undeletehistory" => "Dá díscriosfá an leathanach, díscriosfar gach leasú i stair an leathanaigh.
+Dá gcruthaíodh leathanach nua leis an teideal céanna ó shin an scriosadh, taispeáinfear
+na sean-athruithe san stair roimhe seo, agus ní athshuífear leagan láithreach an
+
+leathanaigh go huathoibríoch.",
+"undeleterevision" => "Leagan scriosta den dáta $1",
+"undeletebtn" => "Díscrios!",
+"undeletedarticle" => "Díscriosadh \"$1\" ar ais",
+
+
+# Namespace form on various pages
+'namespace' => 'Ainmspás:',
+'invert' => 'Cuir an roghnú bun os cionn',
+
+# Contributions
+#
+"contributions" => "Dréachtaí úsáideora",
+"mycontris" => "Mo chuid dréachtaí",
+"contribsub" => "Do $1",
+"nocontribs" => "Níor bhfuarthas aon athrú a raibh cosúil le na crítéir seo.",
+"ucnote" => "Is iad seo thíos na <b>$1</b> athruithe is déanaí a rinne an
+
+úsáideoir sna <b>$2</b> lae
+
+seo caite.",
+"uclinks" => "Féach ar na $1 athruithe is déanaí; féach ar na $2 lae seo caite.",
+"uctop" => " (barr)" ,
+'newbies' => 'núíosaigh',
+
+# What links here
+#
+"whatlinkshere" => "Naisc don leathanch seo",
+"notargettitle" => "Níl aon cuspóir ann",
+"notargettext" => "Níor thug tú leathanach nó úsáideoir sprice
+chun an gníomh seo a dhéanamh ar.",
+"linklistsub" => "(Liosta nasc)",
+"linkshere" => "Nascaíonn na leathanaigh seo a leanas chuig an leathanach seo:",
+"nolinkshere" => "Ní nascaíonn aon leathanach chuig an leathanach seo.",
+"isredirect" => "Leathanach athsheolaidh",
+
+# Block/unblock IP
+#
+"blockip" => "Coisc úsáideoir",
+"blockiptext" => "Úsáid an foirm anseo thíos chun bealach scríofa a chosc ó
+seoladh IP nó ainm úsáideora áirithe.
+Is féidir leat an rud seo a dhéanamh amháin chun an chreachadóireacht a chosc, de réir
+mar a deirtear sa [[{{ns:project}}:Polasaí|polasaí {{GRAMMAR:genitive|{{SITENAME}}}}]].
+Líonaigh cúis áirithe anseo thíos (mar shampla, is féidir leat a luaigh
+leathanaigh áirithe a rinne an duine damáiste ar).",
+"ipaddress" => "Seoladh IP / ainm úsáideora",
+'ipbexpiry' => 'Am éaga',
+"ipbreason" => "Cúis",
+"ipbsubmit" => "Coisc an úsáideoir seo",
+'ipbother' => 'Méid eile ama',
+'ipboptions' => '2 uair:2 hours,1 lá amháin:1 day,3 lá:3 days,1 sheachtain amháin:1 week,2 sheachtain:2 weeks,1 mhí amháin:1 month,3 mhí:3 months,6 mhí:6 months,1 bhliain amháin:1 year,gan teorainn:infinite',
+'ipbotheroption' => 'eile',
+"badipaddress" => "Níl aon úsáideoir ann leis an ainm seo.",
+"blockipsuccesssub" => "D'éirigh leis an cosc",
+"blockipsuccesstext" => "Choisceadh [[{{ns:Special}}:Contributions/$1|$1]].
+<br />Féach ar an g[[{{ns:Special}}:Ipblocklist|liosta coisc IP]] chun coisc a athbhreithniú.",
+"unblockip" => "Díchoisc úsáideoir",
+"unblockiptext" => "Úsáid an foirm anseo thíos chun bealach scríofa a thabhairt ar ais do seoladh
+IP nó ainm úsáideora a raibh faoi chosc roimhe seo.",
+"ipusubmit" => "Díchoisc an seoladh seo",
+"ipblocklist" => "Liosta seoltaí IP agus ainmneacha úsáideoirí coiscthe",
+"blocklistline" => "$1, $2 a choisc $3 (am éaga $4)",
+"blocklink" => "Cosc",
+"unblocklink" => "bain an cosc",
+"contribslink" => "dréachtaí",
+"autoblocker" => "Coisceadh go huathoibríoch thú dá bharr gur úsáideadh do sheoladh IP ag an úsáideoir \"[[Úsáideoir:$1|$1]]\". Is é seo an cúis don cosc ar $1: \"$2\".",
+"blocklogpage" => "Cuntas_coisc",
+"blocklogentry" => 'coisceadh "$1"; is é $2 an am éaga',
+"blocklogtext" => "Seo é cuntas de gníomhartha coisc úsáideoirí agus míchoisc úsáideoirí. Ní cuirtear
+seoltaí IP a raibh coiscthe go huathoibríoch ar an liosta seo. Féach ar an
+[[Speisialta:Ipblocklist|Liosta coisc IP]] chun
+liosta a fháil de coisc atá i bhfeidhm faoi láthair.",
+"unblocklogentry" => 'díchoisceadh $1',
+'range_block_disabled' => 'Faoi láthair, míchumasaítear an cumas riarthóra chun réimsechoisc a dhéanamh.',
+'ipb_expiry_invalid' => 'Am éaga neamhbhailí.',
+'ip_range_invalid' => "Réimse IP neamhbhailí.",
+'proxyblocker' => 'Cosc ar seachfhreastalaithe',
+'proxyblockreason' => "Coisceadh do sheoladh IP dá bharr gur seachfhreastalaí
+neamhshlándála is ea é. Déan teagmháil le do chomhlacht idirlín nó le do lucht cabhrach teicneolaíochta
+go mbeidh 'fhios acu faoin fadhb slándála tábhachtach seo.",
+'proxyblocksuccess' => "Rinneadh.",
+'sorbs' => 'DNSBL SORBS',
+'sorbsreason' => 'Liostalaítear do sheoladh IP mar sheachfhreastalaí oscailte sa DNSBL [http://www.sorbs.net SORBS].',
+
+# Developer tools
+#
+"lockdb" => "Glasáil an bunachar sonraí",
+"unlockdb" => "Díghlasáil bunachar sonraí",
+"lockdbtext" => "Dá nglasálfá an bunachar sonraí, ní beidh cead ar aon úsáideoir
+leathanaigh a chur in eagar, a socruithe a athrú, a liostaí faire a athrú, nó rudaí eile a thrachtann le
+athruithe san bunachar sonraí.
+Cinntigh go bhfuil an scéal seo d'intinn agat, is go díghlasálfaidh tú an bunachar sonraí nuair a bhfuil
+do chuid cothabháile críochnaithe.",
+"unlockdbtext" => "Dá díghlasálfá an bunachar sonraí, beidh ceat ag gach úsáideoirí aris
+na leathanaigh a chur in eagar, a sainroghanna a athrú, a liostaí faire a athrú, agus rudaí eile
+a dhéanamh a thrachtann le athruithe san bunachar sonraí.
+Cinntigh go bhfuil an scéal seo d'intinn agat.",
+"lockconfirm" => "Sea, is mian liom an bunachar sonraí a ghlasáil.",
+"unlockconfirm" => "Sea, is mian liom an bunachar sonraí a dhíghlasáil.",
+"lockbtn" => "Glasáil an bunachar sonraí",
+"unlockbtn" => "Díghlasáil an bunachar sonraí",
+"locknoconfirm" => "Níor mharcáil tú an bosca daingnithe.",
+"lockdbsuccesssub" => "D'éirigh le glasáil an bhunachair sonraí",
+"unlockdbsuccesssub" => "D'éirigh le díghlasáil an bhunachair sonraí",
+"lockdbsuccesstext" => "Glasáladh an bunachar sonraí {{GRAMMAR:genitive|{{SITENAME}}}}.
+<br />Cuimhnigh nach mór duit é a dhíghlasáil tar éis do chuid cothabháil.",
+"unlockdbsuccesstext" => "Díghlasáladh an bunachar sonraí {{GRAMMAR:genitive|{{SITENAME}}}}.",
+
+# SQL query
+
+# Make sysop
+'makesysoptitle' => 'Déan oibreoir córais de húsáideoir',
+'makesysoptext' => 'Úsáideann maorlathaigh an fhoirm seo chun riarthóirí a dhéanamh de ghnáthúsáideoirí.
+Iontráil ainm an úsáideora sa bosca seo agus brúigh an cnaipe chun riarthóir a dhéanamh den úsáideoir',
+'makesysopname' => 'Ainm an úsáideora:',
+'makesysopsubmit' => 'Déan oibreoir córais den úsáideoir seo',
+'makesysopok' => "Is oibreoir córais atá in <b>Úsáideoir \"$1\" anois.</b>",
+'makesysopfail' => "<b>Níor rinneadh oibreoir córais den Úsáideoir \"$1\". (Ar iontráil tú an ainm go ceart?)</b>",
+'setbureaucratflag' => 'Athraigh an brat maotharlach',
+'rights' => 'Cearta:',
+'set_user_rights' => 'Athraigh na cearta úsáideora',
+'user_rights_set' => "<b>Leasaíodh na cearta úsáideora do \"$1\"</b>",
+'set_rights_fail' => "<b>Níorbh fhéidir na cearta úsáideora do \"$1\" a athrú. (Ar iontráil tú an ainm go ceart?)</b>",
+'makesysop' => 'Déan oibreoir córais de húsáideoir',
+'already_sysop' => 'Is oibreoir córais é an usáideoir seo cheana féin',
+'already_bureaucrat' => 'Is maorlathach é an úsáideoir seo cheana féin',
+
+# Move page
+#
+"movepage" => "Athainmnigh an leathanach",
+"movepagetext" => "Úsáid an foirm seo thíos chun leathanach a hathainmniú. Aistreofar a chuid
+stair go léir chuig an teideal nua.
+Déanfar leathanach athsheolaidh den sean-theideal chuig an teideal nua.
+Ní athreofar naisc chuig sean-teidil an leathanaigh. Bí cinnte go ndéanfá
+[[Speisialta:Maintenance|cuardach]] ar athsheolaidh dubáilte nó briste.
+Tá tú freagrach i cinnteach go leanann naisc chuig an pointe a bhfuil siad ag aimsiú ar.
+
+Tabhair faoi deara '''nach''' n-athainmneofar an leathanach má tá leathanach
+ann cheana féin faoin teideal nua, mura bhfuil sé folamh nó athsheoladh nó mura bhfuil aon
+stair athraithe aige cheana. Ciallaíonn sé sin go féidir leat leathanach a athainmniú ar ais
+chuig an áit ina raibh sé roimhe má dhéanfá botún, agus ní féidir leat leathanach atá ann a fhorscriobh ar.
+
+<b>AIRE!</b>
+Is athrú tábhachtach é athainmniú má tá leathanach coitianta i gceist;
+cinntigh go dtuigeann tú na iarmhairtí go léir roimh a leanfá.",
+"movepagetalktext" => "Aistreofar an leathanach phlé leis, má tá sin ann:
+*'''muna''' bhfuil tú ag aistriú an leathanach trasna ainmspásanna,
+*'''muna''' bhfuil leathanach phlé neamhfholamh ann leis an teideal nua, nó
+*'''muna''' bhaineann tú an marc den bosca anseo thíos.
+
+Sna scéil sin, caithfidh tú an leathanach a aistrigh nó a báigh leis na lámha má tá sin an rud atá uait.",
+"movearticle" => "Athainmnigh an leathanach",
+"movenologin" => "Níl tú logáilte isteach",
+"movenologintext" => "Ní mór duit bheith i d'úsáideoir cláraithe agus <a href=\"" .
+ "{{localurle:Speisialta:Userlogin}}\">logáilte isteach</a>
+chun leathanach a hathainmniú.",
+"newtitle" => "Go teideal nua",
+"movepagebtn" => "Athainmnigh an leathanach",
+"pagemovedsub" => "D'éirigh leis an athainmniú",
+"pagemovedtext" => "D'athainmníodh an leathanach \"[[$1]]\" chuig \"[[$2]]\".",
+"articleexists" => "Tá leathanach leis an teideal seo ann fós, nó níl an
+teideal a rinne tú rogha air ina theideal bailí.
+Toghaigh teideal eile le do thoil.",
+"talkexists" => "D'athainmníodh an leathanach é féin go rathúil, ach ní raibh sé ar a chumas an
+leathanach phlé a hathainmniú dá bharr go bhfuil ceann ann cheana féin ag an teideal nua.
+Báigh tusa féin iad, le do thoil.",
+"movedto" => "athainmnithe go",
+"movetalk" => "Athainmnigh an leathanach \"phlé\" freisin, má bhfuil an leathanach sin ann.",
+"talkpagemoved" => "D'athainmníodh an leathanach phlé frithiontráil.",
+"talkpagenotmoved" => "<strong>Níor</strong> athainmníodh an leathanach phlé frithiontráil.",
+'1movedto2' => "D'athainmníodh $1 bheith $2",
+'1movedto2_redir' => "D'athainmníodh $1 bheith $2 thar athsheoladh",
+'movelogpage' => 'Athainmnigh loga',
+'movelogpagetext' => 'Liosta is ea seo thíos de leathanaigh athainmnithe.',
+'movereason' => 'Cúis',
+'revertmove' => 'athúsáid',
+'delete_and_move' => 'Scrios agus athainmnigh',
+'delete_and_move_text' =>
+'==Tá scrios riachtanach==
+
+Tá an t-alt "[[$1]]" ann cheana féin, a bhíodh ceaptha mar ainm nua don athainmniú. Ar
+mhaith leat é a scrios chun áit a dhéanamh don athainmniú?',
+'delete_and_move_reason' => 'Scriosta chun áit a dhéanamh d\'athainmniú',
+'selfmove' => "Tá an ainm céanna ag an bhfoinse mar atá ar an ainm sprice; ní féidir leathanach a athainmniú bheith é féin.",
+'immobile_namespace' => "Saghas speisialta leathanach atá ann san ainm sprice; ní féidir leathanaigh a athainmniú san ainmspás sin.",
+
+#Export
+
+"export" => "Easportáil leathanaigh",
+"exporttext" => "Is féidir leat an téacs agus stair athraithe de leathanach áirithe a heasportáil,
+fillte i bpíosa XML; is féidir leat ansin é a iompórtáil isteach vicí eile atá le na bogearraí MediaWiki
+air, nó is féidir leat é a coinniú do do chuid shiamsa féin.",
+"exportcuronly" => "Ná cuir san áireamh ach an leagan láithreach; ná cuir an stair iomlán ann",
+
+# Namespace 8 related
+
+"allmessages" => "Teachtaireachtaí córais",
+"allmessagestext" => "Liosta is ea seo de theachtaireachtaí córais atá le fáil san ainmspás MediaWiki: .",
+'allmessagesnotsupportedUI' => 'Níl tacaíocht ag Speisialta:AllMessages maidir le do theanga
+comhéadáin phearsanta don suíomh seo.',
+'allmessagesnotsupportedDB' => 'Níl aon tacaíocht anseo do Speisialta:AllMessages dá bharr
+go bhfuil wgUseDatabaseMessages druidte.',
+
+# Thumbnails
+
+'thumbnail-more' => 'Méadaigh',
+'missingimage' => "<b>Íomhá ar iarraidh</b><br /><i>$1</i>",
+'filemissing' => 'Comhad ar iarraidh',
+
+# Special:Import
+'import' => 'Iompórtáil leathanaigh',
+'importinterwiki' => 'Iompórtáil trasna vicíonna',
+'importtext' => 'Easportáil an comhad ón bhfoinse-vicí le do thoil (le húsáid na tréithe
+Speisialta:Export), sábháil ar do dhíosca é agus uaslódáil anseo é.',
+'importfailed' => "Theip ar an iompórtáil: $1",
+'importnotext' => 'Folamh nó gan téacs',
+'importsuccess' => "D'eirigh leis an iompórtáil!",
+'importhistoryconflict' => 'Tá stair athraithe contrártha ann cheana féin (is dócha go
+uaslódáladh an leathanach seo roimh ré)',
+'importnosources' => 'Níl aon fhoinse curtha i leith d\'iompórtáil trasna vicíonna, agus
+ní féidir uaslódála staire díreacha a dhéanamh faoi láthair.',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'c', # Cuardaigh
+'accesskey-minoredit' => 'm', # Mionathrú
+'accesskey-save' => 's', # Sábháil
+'accesskey-preview' => 'r', # Reamhamharc
+'accesskey-diff' => 'v', # Difríocht
+'accesskey-compareselectedversions' => 'l', # Leagain
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Cuardaigh ar {{SITENAME}} [alt-c]',
+'tooltip-minoredit' => 'Déan mionathrú den athrú seo [alt-m]',
+'tooltip-save' => 'Sábháil do chuid athruithe [alt-s]',
+'tooltip-preview' => 'Réamhamharc ar do chuid athruithe; úsáid an gné seo roimh a shábhálaíonn tú! [alt-r]',
+'tooltip-compareselectedversions' => 'Féach na difríochtaí idir an dhá leagain roghnaithe den leathanach seo. [alt-l]',
+'tooltip-watch' => 'Cuir an leathanach seo ar do liosta faire [alt-f]',
+'tooltip-diff' => 'Taispeáin na difríochtaí áirithe a rinne tú don téacs [alt-v]',
+
+
+# stylesheets
+
+'monobook.css' => '/* athraigh an comhad seo chun an craiceann MonoBook a athrú don suíomh ar fad */',
+#'monobook.js' => '/* athraigh an comhad seo chun rudaí js sa craiceann MonoBook a hathrú */',
+
+# Metadata
+'nodublincore' => 'Míchumasaítear meitea-shonraí Dublin Core RDF ar an freastalaí seo.',
+'nocreativecommons' => 'Míchumasaítear meitea-shonraí Creative Commons RDF ar an freastalaí seo.',
+'notacceptable' => 'Ní féidir leis an freastalaí vicí na sonraí a chur ar fáil i bhformáid atá inléite ag do chliant.',
+
+# Attribution
+
+'anonymous' => "Úsáideoir(í) gan ainm ar {{SITENAME}}",
+'siteuser' => "Úsáideoir $1 ag {{SITENAME}}", #FIXME - genitive needed here
+'lastmodifiedatby' => "Leasaigh $3 an leathanach seo go déanaí ag $2, $1.",
+'and' => 'agus',
+'othercontribs' => "Bunaithe ar saothair le $1.",
+'others' => 'daoine eile',
+'siteusers' => "Úsáideoir(í) ag {{SITENAME}}", #FIXME - genitive needed here
+'creditspage' => 'Creidiúintí leathanaigh',
+'nocredits' => 'Níl aon eolas creidiúna le fáil don leathanach seo.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Scagaire in aghaidh ríomhphost dramhála',
+'spamprotectiontext' => 'Chuir an scagaire dramhála bac ar an leathanach a raibh tú ar
+iarradh sábháil. Is dócha gur nasc chuig suíomh seachtrach ba chúis leis.',
+'spamprotectionmatch' => 'Truicear ár scagaire dramhála ag an téacs seo a leanas: $1',
+'subcategorycount' => "Tá $1 fo-chatagóirí sa chatagóir seo.",
+'categoryarticlecount' => "Tá $1 ailt sa chatagóir seo.",
+
+# Info page
+"infosubtitle" => "Eolas don leathanach",
+"numedits" => "Méid athruithe (alt): $1",
+"numtalkedits" => "Méid athruithe (leathanach phlé): $1",
+"numwatchers" => "Méid féachnóirí: $1",
+"numauthors" => "Méid údair ar leith (alt): $1",
+"numtalkauthors" => "Méid údair ar leith (leathanach phlé): $1",
+
+# Math options
+
+'mw_math_png' => "Déan PNG-íomhá gach uair",
+'mw_math_simple' => "Déan HTML má tá sin an-easca, nó PNG ar mhodh eile",
+'mw_math_html' => "Déan HTML más féidir, nó PNG ar mhodh eile",
+'mw_math_source' => "Fág mar cló TeX (do teacsleitheoirí)",
+'mw_math_modern' => "Inmholta do líonleitheoirí nua",
+'mw_math_mathml' => 'MathML más féidir (turgnamhach)',
+
+# Patrolling
+'markaspatrolleddiff' => "Marcáil bheith patrólaithe",
+'markedaspatrolled' => "Marcáil bheith patrólaithe",
+'markedaspatrolledtext' => "Marcáladh an athrú áirithe seo bheith patrólaithe.",
+'rcpatroldisabled' => "Mhíchumasaíodh Patról na n-Athruithe is Déanaí",
+'rcpatroldisabledtext' => "Tá an tréith Patról na n-Athruithe is Déanaí míchumasaithe faoi láthair.",
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* leideanna uirlisí agus cnaipí rochtana */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Mo leathanach úsáideora\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Leathanach úsáideora don IP ina dhéanann tú do chuid athruithe\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Mo leathanach phlé\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Plé maidir le na hathruithe a dhéantar ón seoladh IP seo\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Mo chuid sainroghanna\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Liosta de na leathanaigh a dhéanann tú faire ar maidir le athruithe\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Liosta de mo chuid dréachtaí\');
+ta[\'pt-login\'] = new Array(\'o\',\'Moltar duit logáil isteach, ach níl sé riachtanach.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Moltar duit logáil isteach, ach níl sé riachtanach.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Logáil amach\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Plé maidir leis an leathanach ábhair\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Is féidir leat an leathanach seo a athrú. Más é do thoil é, bain úsáid as an cnaipe réamhamhairc roimh sábháil a dhéanamh.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Cuir trácht leis an plé seo..\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Tá an leathanach seo glasáilte. Is féidir leat a fhoinse a fheiceáil.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Leagain stairiúla den leathanach seo.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Glasáil an leathanach seo\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Scrios an leathanach seo\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Díscrios na hathruithe a rinneadh don leathanach seo roimh a scriosadh é\');
+ta[\'ca-move\'] = new Array(\'m\',\'Athainmnigh an leathanach\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Níl an cead riachtanach agat chun an leathanach a athainmniú\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Cuir an leathanach seo ar do liosta faire\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Bain an leathanach seo as do liosta faire\');
+ta[\'search\'] = new Array(\'f\',\'Cuardaigh sa vicí seo\');
+ta[\'p-logo\'] = new Array(\'\',\'Príomhleathanach\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Tabhair cuairt ar an bPríomhleathanach\');
+ta[\'n-portal\'] = new Array(\'\',\'Maidir leis an tionscadal, cad is féidir leat a dhéanamh, conas achmhainní a fháil\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Faigh eolas cúlrach maidir le chursaí reatha\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Liosta de na hathruithe is déanaí sa vicí.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Lódáil leathanach fánach\');
+ta[\'n-help\'] = new Array(\'\',\'An áit chun cabhair a fháil.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Tabhair tacaíocht duinn\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Liosta de gach leathanach sa vicí a nascaíonn chuig an leathanach seo\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Na hathruithe is déanaí ar leathanaigh a nascaíonn chuig an leathanach seo\');
+ta[\'feed-rss\'] = new Array(\'\',\'Fotha RSS don leathanach seo\');
+ta[\'feed-atom\'] = new Array(\'\',\'Fotha Atom don leathanach seo\');
+ta[\'t-contributions\'] = new Array(\'\',\'Féach ar an liosta dréachtaí a rinne an t-úsáideoir seo\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Cuir teachtaireacht chuig an úsáideoir seo\');
+ta[\'t-upload\'] = new Array(\'u\',\'Comhaid íomhá nó meáin a uaslódáil\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Liosta de gach leathanach speisialta\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Féach ar an leathanach ábhair\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Féach ar an leathanach úsáideora\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Féach ar an leathanach meáin\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Is leathanach speisialta é seo, ní féidir leat an leathanach é fhéin a athrú.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Féach ar an leathanach thionscadail\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Féach ar an leathanach íomhá\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Féach ar an teachtaireacht córais\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Féach ar an teimpléad\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Féach ar an leathanach cabhrach\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Féach ar an leathanach catagóire\');',
+
+# image deletion
+'deletedrevision' => 'Scriosadh an sean-leagan $1.',
+
+# browsing diffs
+'previousdiff' => '&larr; An difríocht roimhe seo',
+'nextdiff' => 'An difríocht i ndiadh seo &rarr;',
+
+'imagemaxsize' => 'Cuir an teorann seo ar na íomhánna atá le fáil ar leathanaigh cuir síos íomhánna:',
+'thumbsize' => 'Méid mionshamhla :',
+'showbigimage' => 'Íoslódáil leagan ardtaifigh ($1x$2, $3 kb)',
+
+'newimages' => 'Gailearaí na n-íomhánna nua',
+'noimages' => 'Níl aon rud le feiscint.',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Úsáideoir:',
+'speciallogtitlelabel' => 'Teideal:',
+
+'passwordtooshort' => 'Tá d\'fhocal faire ró-ghearr. Caithfidh go bhfuil $1 carachtar ann ar a laghad.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Aire\'\'\': Tá seans ann go bhfuil cód mailíseach sa comhad seo - b\'fheidir go gcuirfear do chóras i gcontúirt dá rithfeá é.
+<hr />',
+
+'fileinfo' => '$1KB, saghas MIME: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Meiteasonraí',
+
+# Exif tags
+'exif-imagewidth' =>'Leithead',
+'exif-imagelength' =>'Airde',
+'exif-bitspersample' =>'Gíotáin sa chomhpháirt',
+'exif-compression' =>'Scéim comhbhrúite',
+'exif-photometricinterpretation' =>'Comhbhrú picteilíní',
+'exif-orientation' =>'Treoshuíomh',
+'exif-samplesperpixel' =>'Líon na gcomhpháirt',
+'exif-planarconfiguration' =>'Eagar na sonraí',
+'exif-ycbcrsubsampling' =>'Cóimheas foshamplála de Y i gcoinne C',
+'exif-ycbcrpositioning' =>'Suí Y agus C',
+'exif-xresolution' =>'Taifeach íomhá i dtreo an leithid',
+'exif-yresolution' =>'Taifeach íomhá i dtreo an airde',
+'exif-resolutionunit' =>'Aonad an taifigh X agus Y',
+'exif-stripoffsets' =>'Suíomh na sonraí íomhá',
+'exif-rowsperstrip' =>'Líon na rónna sa stráice',
+'exif-stripbytecounts' =>'Bearta sa stráice comhbhrúite',
+'exif-jpeginterchangeformat' =>'Aischló don SOI JPEG',
+'exif-jpeginterchangeformatlength' =>'Bearta sonraí JPEG',
+'exif-transferfunction' =>'Feidhm aistrithe',
+'exif-whitepoint' =>'Crómatacht na bpointí bán',
+'exif-primarychromaticities' =>'Crómatachta na bpríomhacht',
+'exif-ycbcrcoefficients' =>'Comhéifeachtaí mhaitrís trasfhoirmithe an dathspáis',
+'exif-referenceblackwhite' =>'Péire luachanna tagartha don dubh is don bán',
+'exif-datetime' =>'Dáta agus am athrú an chomhaid',
+'exif-imagedescription' =>'Íomhátheideal',
+'exif-make' =>'Déantóir an ceamara',
+'exif-model' =>'Déanamh an ceamara',
+'exif-software' =>'Na bogearraí a úsáideadh',
+'exif-artist' =>'Údar',
+'exif-copyright' =>'Úinéir an chóipchirt',
+'exif-exifversion' =>'Leagan EXIF',
+'exif-flashpixversion' =>'Leagan Flashpix atá á thacú',
+'exif-colorspace' =>'Dathspás',
+'exif-componentsconfiguration' =>'Ciall le gach giota',
+'exif-compressedbitsperpixel' =>'Modh chomhbhrú na n-íomhánna',
+'exif-pixelydimension' =>'Leithead bailí don íomhá',
+'exif-pixelxdimension' =>'Airde bailí don íomhá',
+'exif-makernote' =>'Nótaí an déantóra',
+'exif-usercomment' =>'Nótaí an úsáideora',
+'exif-relatedsoundfile' =>'comhad gaolmhara fuaime',
+'exif-datetimeoriginal' =>'Dáta agus am ghiniúint na sonraí',
+'exif-datetimedigitized' =>'Dáta agus am digitithe',
+'exif-subsectime' =>'Foshoicindí DateTime',
+'exif-subsectimeoriginal' =>'Foshoicindí DateTimeOriginal',
+'exif-subsectimedigitized' =>'Foshoicindí DateTimeDigitized',
+'exif-exposuretime' =>'Am nochta',
+'exif-fnumber' =>'Uimhir F',
+'exif-exposureprogram' =>'Clár nochta',
+'exif-spectralsensitivity' =>'Íogaireacht an speictrim',
+'exif-isospeedratings' =>'Grádú ISO luais',
+'exif-oecf' =>'Fachtóir optaileictreonach tiontaithe',
+'exif-shutterspeedvalue' =>'Luas nochta',
+'exif-aperturevalue' =>'Cró',
+'exif-brightnessvalue' =>'Gile',
+'exif-exposurebiasvalue' =>'Laobh nochta',
+'exif-maxaperturevalue' =>'Cró tíre uasmhéideach',
+'exif-subjectdistance' =>'Fad ón ábhar',
+'exif-meteringmode' =>'Modh meadarachta',
+'exif-lightsource' =>'Foinse solais',
+'exif-flash' =>'Splanc',
+'exif-focallength' =>'Fad fócasach an lionsa',
+'exif-subjectarea' =>'Achar an ábhair',
+'exif-flashenergy' =>'Splanfhuinneamh',
+'exif-spatialfrequencyresponse' =>'Freagairt minicíochta spáis',
+'exif-focalplanexresolution' =>'Taifeach an plána fócasaigh X',
+'exif-focalplaneyresolution' =>'Taifeach an plána fócasaigh Y',
+'exif-focalplaneresolutionunit' =>'Aonad taifigh an plána fócasaigh',
+'exif-subjectlocation' =>'Suíomh an ábhair',
+'exif-exposureindex' =>'Innéacs nochta',
+'exif-sensingmethod' =>'Modh braite',
+'exif-filesource' =>'Foinse comhaid',
+'exif-scenetype' =>'Cineál radhairc',
+'exif-cfapattern' =>'Patrún CFA',
+'exif-customrendered' =>'Íomháphróiseáil saincheaptha',
+'exif-exposuremode' =>'Modh nochta',
+'exif-whitebalance' =>'Bánchothromaíocht',
+'exif-digitalzoomratio' =>'Cóimheas zúmála digiteaí',
+'exif-focallengthin35mmfilm' =>'Fad fócasach i scannán 35 mm',
+'exif-scenecapturetype' =>'Cineál gabhála radhairc',
+'exif-gaincontrol' =>'Rialú radhairc',
+'exif-contrast' =>'Codarsnacht',
+'exif-saturation' =>'Sáithiú',
+'exif-sharpness' =>'Géire',
+'exif-devicesettingdescription' =>'Cur síos ar socruithe gléis',
+'exif-subjectdistancerange' =>'Raon fada ón ábhar',
+'exif-imageuniqueid' =>'Aitheantas uathúil an íomhá',
+'exif-gpsversionid' =>'Leagan clibe GPS',
+'exif-gpslatituderef' =>'Domhan-leithead Thuaidh no Theas',
+'exif-gpslatitude' =>'Domhan-leithead',
+'exif-gpslongituderef' =>'Domhanfhad Thoir nó Thiar',
+'exif-gpslongitude' =>'Domhanfhad',
+'exif-gpsaltituderef' =>'Tagairt airde',
+'exif-gpsaltitude' =>'Airde',
+'exif-gpstimestamp' =>'Am GPS (clog adamhach)',
+'exif-gpssatellites' =>'Satailítí úsáidte don tomhas',
+'exif-gpsstatus' =>'Stádas an ghlacadóra',
+'exif-gpsmeasuremode' =>'Modh tomhais',
+'exif-gpsdop' =>'Beachtas tomhais',
+'exif-gpsspeedref' =>'Aonad luais',
+'exif-gpsspeed' =>'Luas an ghlacadóra GPS',
+'exif-gpstrackref' =>'Tagairt don treo gluaiseachta',
+'exif-gpstrack' =>'Treo gluaiseachta',
+'exif-gpsimgdirectionref' =>'Tagairt do treo an íomhá',
+'exif-gpsimgdirection' =>'Treo an íomhá',
+'exif-gpsmapdatum' =>'Sonraí suirbhéireachta geodasaí a úsáideadh',
+'exif-gpsdestlatituderef' =>'Tagairt don domhan-leithead sprice',
+'exif-gpsdestlatitude' =>'Domhan-leithead sprice',
+'exif-gpsdestlongituderef' =>'Tagairt don domhanfhad sprice',
+'exif-gpsdestlongitude' =>'Domhanfhad sprice',
+'exif-gpsdestbearingref' =>'Tagairt don treo-uillinn sprice',
+'exif-gpsdestbearing' =>'Treo-uillinn sprice',
+'exif-gpsdestdistanceref' =>'Tagairt don fad ón áit sprice',
+'exif-gpsdestdistance' =>'Fad ón áit sprice',
+'exif-gpsprocessingmethod' =>'Ainm an modha próiseála GPS',
+'exif-gpsareainformation' =>'Ainm an cheantair GPS',
+'exif-gpsdatestamp' =>'Dáta GPS',
+'exif-gpsdifferential' =>'Ceartú difreálach GPS',
+
+# Exif attributes
+
+'exif-compression-1' => 'Neamh-chomhbhrúite',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Gnáth', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Iompaithe go cothrománach', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Rothlaithe trí 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Iompaithe go hingearach', // 0th row: bottom; 0th olumn: left
+'exif-orientation-5' => 'Rothlaithe trí 90° CCW agus iompaithe go hingearach', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Rothlaithe trí 90° CW', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Rothlaithe trí 90° CW agus iompaithe go hingearach', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Rothlaithe trí 90° CCW', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'Formáid shmutánach',
+'exif-planarconfiguration-2' => 'Formáid phlánach',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'níl a leithéid ann',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Gan sainiú',
+'exif-exposureprogram-1' => 'Leis na lámha',
+'exif-exposureprogram-2' => 'Gnáthchlár',
+'exif-exposureprogram-3' => 'Tosaíocht nochta',
+'exif-exposureprogram-4' => 'Tosaíocht cró',
+'exif-exposureprogram-5' => 'Clár cúise (laofa do doimhneacht réimse)',
+'exif-exposureprogram-6' => 'Clár gnímh (laofa do cróluas tapaidh)',
+'exif-exposureprogram-7' => 'Modh portráide (do grianghraif i ngar don ábhar,
+le cúlra as fócas)',
+'exif-exposureprogram-8' => 'Modh tírdhreacha (do grianghraif tírdhreacha le
+cúlra i bhfócas)',
+
+'exif-meteringmode-0' => 'Anaithnid',
+'exif-meteringmode-1' => 'Meán',
+'exif-meteringmode-2' => 'MeánUalaitheDonLár',
+'exif-meteringmode-3' => 'Spota',
+'exif-meteringmode-4' => 'Ilspotach',
+'exif-meteringmode-5' => 'Patrún',
+'exif-meteringmode-6' => 'Páirteach',
+'exif-meteringmode-255' => 'Eile',
+
+'exif-lightsource-0' => 'Anaithnid',
+'exif-lightsource-1' => 'Solas lae',
+'exif-lightsource-2' => 'Fluaraiseach',
+'exif-lightsource-3' => 'Tungstan (solas gealbhruthach)',
+'exif-lightsource-4' => 'Splanc',
+'exif-lightsource-9' => 'Aimsir breá',
+'exif-lightsource-10' => 'Aimsir scamallach',
+'exif-lightsource-11' => 'Scáth',
+'exif-lightsource-12' => 'Solas lae fluaraiseach (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Solas bán lae fluaraiseach (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Solas fuar bán fluaraiseach (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Solas bán fluaraiseach (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Gnáthsholas A',
+'exif-lightsource-18' => 'Gnáthsholas B',
+'exif-lightsource-19' => 'Gnáthsholas C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'Tungstan stiúideó ISO',
+'exif-lightsource-255' => 'Foinse eile solais',
+
+'exif-sensingmethod-1' => 'Gan sainiú',
+'exif-sensingmethod-2' => 'Braiteoir aonshliseach ceantair datha',
+'exif-sensingmethod-3' => 'Braiteoir dháshliseach ceantair datha',
+'exif-sensingmethod-4' => 'Braiteoir tríshliseach ceantair datha',
+'exif-sensingmethod-5' => 'Braiteoir dathsheicheamhach ceantair',
+'exif-sensingmethod-7' => 'Braiteoir trílíneach',
+'exif-sensingmethod-8' => 'Braiteoir dathsheicheamhach línte',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'Grianghraf a rinneadh go díreach',
+
+'exif-customrendered-0' => 'Gnáthphróiseas',
+'exif-customrendered-1' => 'Próiseas saincheaptha',
+
+'exif-exposuremode-0' => 'Nochtadh uathoibríoch',
+'exif-exposuremode-1' => 'Nochtadh láimhe',
+'exif-exposuremode-2' => 'Brac uathoibríoch',
+
+'exif-whitebalance-0' => 'Bánchothromaíocht uathoibríoch',
+'exif-whitebalance-1' => 'Bánchothromaíocht láimhe',
+
+'exif-scenecapturetype-0' => 'Gnáth',
+'exif-scenecapturetype-1' => 'Tírdhreach',
+'exif-scenecapturetype-2' => 'Portráid',
+'exif-scenecapturetype-3' => 'Radharc oíche',
+
+'exif-gaincontrol-0' => 'Dada',
+'exif-gaincontrol-1' => 'Íosneartúchán suas',
+'exif-gaincontrol-2' => 'Uasneartúchán suas',
+'exif-gaincontrol-3' => 'Íosneartúchán síos',
+'exif-gaincontrol-4' => 'Uasneartúchán síos',
+
+'exif-contrast-0' => 'Gnáth',
+'exif-contrast-1' => 'Bog',
+'exif-contrast-2' => 'Crua',
+
+'exif-saturation-0' => 'Gnáth',
+'exif-saturation-1' => 'Sáithiúchán íseal',
+'exif-saturation-2' => 'Ard-sáithiúchán',
+
+'exif-sharpness-0' => 'Gnáth',
+'exif-sharpness-1' => 'Bog',
+'exif-sharpness-2' => 'Crua',
+
+'exif-subjectdistancerange-0' => 'Anaithnid',
+'exif-subjectdistancerange-1' => 'Macra',
+'exif-subjectdistancerange-2' => 'Radharc teann',
+'exif-subjectdistancerange-3' => 'Cianradharc',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Domhan-leithead thuaidh',
+'exif-gpslatitude-s' => 'Domhan-leithead theas',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Domhanfhad Thoir',
+'exif-gpslongitude-w' => 'Domhanfhad Thiar',
+
+'exif-gpsstatus-a' => 'Tomhas ar siúl',
+'exif-gpsstatus-v' => 'Tomhas dodhéanta',
+
+'exif-gpsmeasuremode-2' => 'Tomhas déthoiseach',
+'exif-gpsmeasuremode-3' => 'Tomhas tríthoiseach',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Ciliméadair san uair',
+'exif-gpsspeed-m' => 'Mílte san uair',
+'exif-gpsspeed-n' => 'Muirmhílte',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Fíorthreo',
+'exif-gpsdirection-m' => 'Treo maighnéadach',
+
+# external editor support
+'edit-externally' => 'Athraigh an comhad seo le feidhmchlár seachtrach',
+'edit-externally-help' => 'Féach ar na
+
+[http://meta.wikimedia.org/wiki/Help:External_editors treoracha cumraíochta] (as Béarla)
+
+le tuilleadh eolais.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'gach',
+'imagelistall' => 'gach',
+'watchlistall1' => 'gach',
+'watchlistall2' => 'gach',
+
+# E-mail address confirmation
+'confirmemail' => 'Deimhnigh do sheoladh ríomhphoist',
+'confirmemail_text' => "Tá sé de dhíth an an vicí seo do sheoladh ríomhphoist a
+
+bhailíochtú sula úsáideann tú na gnéithe ríomhphoist. Gníomhachtaigh an cnaipe seo thíos
+
+chun teachtaireacht deimhnithe a sheoladh chuig do chuntas ríomhphoist. Beidh nasc ann sa
+
+comhad ina mbeidh cód áirithe; lódáil an nasc i do bhrabhsálaí chun deimhniú go bhfuil do
+
+sheoladh ríomhphoist bailí.",
+'confirmemail_send' => 'Seol cód deimhnithe',
+'confirmemail_sent' => 'Seoladh teachtaireacht deimhnithe.',
+'confirmemail_sendfailed' => 'Níorbh fhéidir an teachtaireacht deimhnithe a sheoladh. Seiceáil nach bhfuil caractair neamh-bhailí ann sa seoladh.',
+'confirmemail_invalid' => 'Cód deimhnithe neamh-bhailí. B\'fhéidir gur chuaidh an cód as feidhm.',
+'confirmemail_success' => 'Deimhníodh do sheoladh ríomhphoist. Is féidir leat logáil
+
+isteach anois agus sult a bhaint as an vicí.',
+'confirmemail_loggedin' => 'Deimhníodh do sheoladh ríomhphoist.',
+'confirmemail_error' => 'Tharlaigh botún éigin le sabháil do dheimhniú.',
+
+'confirmemail_subject' => 'Deimhniú seolaidh ríomhphoist as {{SITENAME}}',
+'confirmemail_body' => "Chláraigh duine éigin an cuntas \"$2\" le húsáid an seolaidh
+
+ríomhphoist seo ar {{SITENAME}} - is dócha gur rinne tú féin é seo, ón seoladh IP $1.
+
+Chun deimhniú a dhéanamh gur leatsa é an cuntas seo, agus chun gnéithe ríomhphoist a chur
+
+i ngníomh ag {{SITENAME}}, oscail an nasc seo i do bhrabhsalaí:
+
+$3
+
+*Muna* bhfuil tú an duine atá i gceist, ná roghnaigh an nasc. Rachfaidh an cód deimhnithe
+
+seo as feidhm ag $4.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Déan iarracht ar meaitseáil cruinn',
+'searchfulltext' => 'Cuardaigh sa téacs iomlán',
+'createarticle' => 'Cruthaigh alt',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Díchumasaíodh trasáireamh idir vicíonna]',
+'scarytranscludefailed' => '[Theip leis an iarradh teimpléid do $1; tá brón orainn]',
+'scarytranscludetoolong' => '[Tá an URL ró-fhada; tá brón orainn]',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesGn.php b/languages/messages/MessagesGn.php
new file mode 100644
index 000000000000..7ca6dc716c22
--- /dev/null
+++ b/languages/messages/MessagesGn.php
@@ -0,0 +1,9 @@
+<?php
+/** Guaraní (avañe'ẽ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'es';
+?>
diff --git a/languages/messages/MessagesGsw.php b/languages/messages/MessagesGsw.php
new file mode 100644
index 000000000000..56cc5501640f
--- /dev/null
+++ b/languages/messages/MessagesGsw.php
@@ -0,0 +1,794 @@
+<?php
+
+$fallback = 'de';
+$linkTrail = '/^([äöüßa-z]+)(.*)$/sDu';
+
+$messages = array(
+'tog-underline' => 'Links unterstryche',
+'tog-highlightbroken' => 'Links uf lääri Themene durestryche',
+'tog-justify' => 'Tekscht als Blocksatz',
+'tog-hideminor' => 'Cheini «chlyni Änderige» aazeige',
+'tog-extendwatchlist' => 'Erwiterti Beobachtungslischte',
+'tog-usenewrc' => 'Erwytereti «letschti Änderige» (geit nid uf allne Browser)',
+'tog-numberheadings' => 'Überschrifte outomatisch numeriere',
+'tog-showtoolbar' => 'Editier-Wärchzüüg aazeige',
+'tog-editondblclick' => 'Syte bearbeite mit Doppelklick i d Syte (JavaScript)',
+'tog-editsection' => 'Gleicher aazeige für ds Bearbeite vo einzelnen Absätz',
+'tog-editsectiononrightclick'=> 'Einzelni Absätz bearbeite mit Rächtsclick (Javascript)',
+'tog-showtoc' => 'Inhaltsverzeichnis aazeige bi Artikle mit meh als drei Überschrifte',
+'tog-rememberpassword' => 'Passwort spychere (Cookie)',
+'tog-editwidth' => 'Tekschtygabfäld mit voller Breiti',
+'tog-watchdefault' => 'Vo dir nöi gmachti oder verändereti Syte beobachte',
+'tog-minordefault' => 'Alli dyni Änderigen als «chlyni Änderige» markiere',
+'tog-previewontop' => 'Vorschou vor em Editierfänschter aazeige',
+'tog-previewonfirst' => 'Vorschou aazeige bim erschten Editiere',
+'tog-nocache' => 'Syte-Cache deaktiviere',
+'tog-enotifwatchlistpages'=> 'Benachrichtigungsmails by Änderigen a Wiki-Syte',
+'tog-enotifusertalkpages'=> 'Benachrichtigungsmails bi Änderigen a dyne Benutzersyte',
+'tog-enotifminoredits' => 'Benachrichtigungsmail ou bi chlyne Sytenänderige',
+'tog-enotifrevealaddr' => 'Dyni E-Mail-Adrässe wird i Benachrichtigungsmails zeigt',
+'tog-shownumberswatching'=> 'Aazahl Benutzer aazeige, wo ne Syten am Aaluege sy (i den Artikelsyte, i de «letschten Änderigen» und i der Beobachtigslischte)',
+'tog-fancysig' => 'Kei outomatischi Verlinkig vor Signatur uf d Benutzersyte',
+'tog-externaleditor' => 'Externen Editor als default',
+'tog-externaldiff' => 'Externi diff als default',
+'tog-showjumplinks' => '«Wächsle-zu»-Links ermügleche',
+'tog-uselivepreview' => 'Live preview benütze (JavaScript) (experimentell)',
+'tog-autopatrol' => 'Eigeni Bearbeitige als patrolliert markiere',
+'tog-forceeditsummary' => 'Sei miers, wänn I s Zommefassungsfeld leer los',
+'tog-watchlisthideown' => 'Eigeni Änderige uf d Beobachtungslischt usblende',
+'tog-watchlisthidebots' => 'Bot-Änderige in d Beobachtungslischt usblende',
+'underline-always' => 'immer',
+'underline-never' => 'nie',
+'underline-default' => 'Browser-Vorystellig',
+'skinpreview' => '(Vorschou)',
+'sunday' => 'Sundi',
+'monday' => 'Mändi',
+'tuesday' => 'Zischdi',
+'wednesday' => 'Mittwuch',
+'thursday' => 'Durschdi',
+'friday' => 'Fridi',
+'saturday' => 'Somschdi',
+'january' => 'Jänner',
+'august' => 'Ougschte',
+'september' => 'Septämber',
+'november' => 'Novämber',
+'december' => 'Dezämber',
+'may' => 'Mei',
+'categories' => 'Kategorie',
+'pagecategories' => '{{PLURAL:$1|Kategori|Kategorie}}',
+'category_header' => 'Artikel in de Kategori "$1"',
+'subcategories' => 'Unterkategorie',
+'mainpage' => 'Houptsyte',
+'mainpagetext' => 'MediaWiki isch erfolgrich inschtalliert worre.',
+'mainpagedocfooter' => 'Luege uf d [http://meta.wikimedia.org/wiki/MediaWiki_localisation Dokumentation fier d Onpassung vun de Bnutzeroberflächi] un s [http://meta.wikimedia.org/wiki/Help:Contents Bnutzerhondbuech] fier d Hilf yber d Bnutzung un s Ystelle.',
+'portal' => 'Gmeinschaftsportal',
+'portal-url' => 'Project:Gemeinschafts-Portal',
+'about' => 'Übr',
+'aboutsite' => 'Übr {{GRAMMAR:akkusativ|{{SITENAME}}}}',
+'aboutpage' => 'Project:Übr {{UCFIRST:{{GRAMMAR:akkusativ|{{SITENAME}}}}}}',
+'help' => 'Hilf',
+'helppage' => 'Help:Hilf',
+'bugreportspage' => 'Project:Kontakt',
+'sitesupport' => 'Finanzielli Hilf',
+'sitesupport-url' => 'Project:Spenden',
+'faqpage' => 'Project:FAQ',
+'edithelp' => 'Ratschläg fiers Bearbeite',
+'newwindow' => '(imene nöie Fänschter)',
+'edithelppage' => 'Project:Ändere',
+'cancel' => 'Abbräche',
+'qbfind' => 'Finde',
+'qbbrowse' => 'Blättre',
+'qbedit' => 'Ändere',
+'qbpageoptions' => 'Sytenoptione',
+'qbpageinfo' => 'Sytedate',
+'qbmyoptions' => 'Ystellige',
+'qbspecialpages' => 'Spezialsytene',
+'moredotdotdot' => 'Meh …',
+'mypage' => 'Minni Syte',
+'mytalk' => 'mini Diskussionsyte',
+'anontalk' => 'Diskussionssyste vo sellere IP',
+'currentevents' => 'Aktuelli Mäldige',
+'currentevents-url' => 'Aktuelli Termin',
+'disclaimers' => 'Impressum',
+'disclaimerpage' => '{{ns:project}}:Impressum',
+'privacy' => 'Daateschutz',
+'privacypage' => 'Project:Daateschutz',
+'errorpagetitle' => 'Fähler',
+'returnto' => 'Zrügg zur Syte $1.',
+'tagline' => 'Us {{SITENAME}}',
+'search' => 'Suech',
+'searchbutton' => 'Suech',
+'history' => 'Versione',
+'history_short' => 'Versione/Autore',
+'printableversion' => 'Druck-Aasicht',
+'permalink' => 'Bschtändigi URL',
+'print' => 'Drucke',
+'edit' => 'ändere',
+'editthispage' => 'Syte bearbeite',
+'delete' => 'lösche',
+'deletethispage' => 'Syte lösche',
+'undelete_short' => '$1 widerherstelle',
+'protect' => 'schütze',
+'protectthispage' => 'Artikel schütze',
+'unprotect' => 'nümm schütze',
+'unprotectthispage' => 'Schutz ufhebe',
+'newpage' => 'Nöji Syte',
+'specialpage' => 'Spezialsyte',
+'personaltools' => 'Persönlichi Wärkzüg',
+'postcomment' => 'Kommentar abgeh',
+'articlepage' => 'Syte',
+'toolbox' => 'Wärkzügkäschtli',
+'userpage' => 'Benutzersyte',
+'imagepage' => 'Bildsyte',
+'otherlanguages' => 'Andere Schprôche',
+'redirectedfrom' => '(Witergleitet vun $1)',
+'redirectpagesub' => 'Umgleiteti Syte',
+'lastmodifiedat' => 'Letschti Änderig vo dere Syte: $2, $1<br />',
+'viewcount' => 'Selli Syte isch {{PLURAL:$1|eimol|$1 Mol}} bsuecht worde.',
+'copyright' => 'Der Inhalt vo dere Syte steht unter der $1.',
+'protectedpage' => 'Gschützt Syte',
+'jumpto' => 'Hops zue:',
+'jumptosearch' => 'Suech',
+'badaccess' => 'Kei usreichendi Rechte.',
+'versionrequired' => 'Version $1 vun MediaWiki wird bnötigt',
+'versionrequiredtext' => 'Version $1 vun MediaWiki wird bnötigt um diä Syte zue nutze. Luege [[Special:Version]]',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Vun "$1"',
+'youhavenewmessages' => 'Du hesch $1 ($2).',
+'newmessageslink' => 'nöji Nachrichte',
+'newmessagesdifflink' => 'Unterschid',
+'editsection' => 'ändere',
+'editsectionhint' => 'Abschnitt ändere: $1',
+'showtoc' => 'ufklappe',
+'hidetoc' => 'zueklappe',
+'thisisdeleted' => 'Onluege oder widrherstelle vun $1?',
+'viewdeleted' => '$1 onluege?',
+'restorelink' => '{{PLURAL:$1|glöschti Änderig|$1 glöschti Ändrige}}',
+'nstab-user' => 'Benutzersyte',
+'nstab-project' => 'Projektsyte',
+'nstab-image' => 'Bildli',
+'nstab-mediawiki' => 'Nochricht',
+'nstab-template' => 'Vorlag',
+'nstab-help' => 'Hilf',
+'nosuchaction' => 'Di Aktion gibts nit',
+'nosuchactiontext' => 'Di Aktion wird vun de MediaWiki-Software nit unterschtützt',
+'nosuchspecialpage' => 'Di Spezialsyte gibts nit',
+'nospecialpagetext' => 'Diese Spezialseite wird von der MediaWiki-Software nicht unterstützt',
+'error' => 'Fähler',
+'databaseerror' => 'Fähler in dr Datebonk',
+'dberrortext' => 'S het ä Syntaxfähler in dr Datenbonkabfrôg gebä.
+
+D letzscht Datebonkabfrôg het ghiesse: "$1" us de Funktion "<tt>$2</tt>".
+
+MySQL het den Fähler gmeldet: "<tt>$3: $4</tt>".',
+'noconnect' => 'Hab kei Vobindung zuer Datebonk uf $1 herschtelle kinne',
+'nodb' => 'Hab d Datebonk $1 nit uswähle kinne',
+'cachederror' => 'D folgende isch ä Kopie usm Cache un möglicherwis nit aktuell.',
+'laggedslavemode' => 'Obacht: Kürzlich vorgnommene Änderunge wärdet u.U. no nit aazaigt!',
+'readonly' => 'Datebonk isch gsperrt',
+'enterlockreason' => 'Bitte gib ä Grund i, worum Datebonk gsperrt werre soll un ä Yschätzung yber d Dur vum Sperre',
+'readonlytext' => 'Diä {{SITENAME}}-Datebonk isch vorybergehend fier Neijyträg un Änderige gsperrt. Bitte vosuechs s später no mol.
+
+Grund vun de Sperrung: $1',
+'missingarticle' => 'De Tekscht vum Artikel "$1" isch in de Datebonk nit gfunde. Des isch wahrschinlich ä Fähler in de Software. Sin so guet, un melde des m Adminischtrator, un gib de Artikelnome on.',
+'readonly_lag' => 'Datebonk isch automatisch gschperrt worre, wil d Sklavedatebonkserver ihr Meischter yhole miesse',
+'internalerror' => 'Interner Fähler',
+'filecopyerror' => 'Datei "$1" het nit noch "$2" kopiert werre kinne.',
+'filerenameerror' => 'Datei "$1" het nit noch "$2" umbnennt werre kinne.',
+'filedeleteerror' => 'Datei "$1" het nit glöscht werre kinne.',
+'filenotfound' => 'Datei "$1" isch nit gfunde worre.',
+'formerror' => 'Fähler: Ds Formular het nid chönne verarbeitet wärde',
+'badarticleerror' => 'D Aktion konn uf denne Artikel nit ongwendet werre.',
+'cannotdelete' => 'Konn d spezifiziert Syte odr Artikel nit lösche. (Isch möglicherwis schu vun ebr ondrem glöscht worre.)',
+'badtitle' => 'Ugültiger Titel',
+'badtitletext' => 'Dr Titel vun de ongfordert Syte isch ugültig gsi, leer, odr ä ugültiger Sprochlink vun nm ondre Wiki.',
+'perfdisabled' => 'Leider isch die Funktion momentan usgschalte, wil\'s d Datebank eso starch würd belaschte, dass mer s Wiki nümm chönnti benütze.',
+'perfdisabledsub' => 'Dert isch ä gspeicherti Kopie vun $1:',
+'perfcached' => 'Selli Informatione chömme usem Zwüschespeicher un sin derwiil viilliecht nid aktuell.
+----',
+'perfcachedts' => 'D folgendi Date stomme usm Cache un sin om $1 s letzscht mol aktualisiert worre.',
+'wrong_wfQuery_params' => 'Falschi Parameter fier wfQuery()<br />
+Funktion: $1<br />
+Abfrog: $2',
+'viewsource' => 'Quelltext aaluege',
+'viewsourcefor' => 'fier $1',
+'protectedtext' => 'Die Syten isch für ds Bearbeite gsperrt; daderfür cha’s verschidnigi Gründ gä. Lueg ou unter [[Project:Geschützte Seiten|Project:Gschützti Syte]].
+
+Du chasch der Quelltekscht vo dere Syten aaluegen u kopiere.',
+'protectedinterface' => 'Die Syte enthält Text fiers Sproch-Interface vun de Software un isch gsperrt, um Missbrouch zue vohindre.',
+'editinginterface' => '\'\'\'Obacht:\'\'\' Du bisch e Syten am Verändere wo zum user interface ghört. We du die Syte veränderisch, de änderet sech ds user interface o für di andere Benutzer.',
+'sqlhidden' => '(SQL-Abfrog voschteckt)',
+'logouttitle' => 'Benutzer-Abmäldig',
+'logouttext' => '<div align="center" style="background-color:white;">
+<b>Du bisch jitz abgmäldet!</b>
+</div><br />
+We du jitz öppis uf der {{SITENAME}} änderisch, de wird dyni IP-Adrässen als Urhäber regischtriert u nid dy Benutzername. Du chasch di mit em glychen oder emnen andere Benutzername nöi aamälde.',
+'welcomecreation' => '<h2>Willkomme, $1!</h2>
+
+Dys Benutzerkonto isch aagleit worde
+
+Vergis nid, dyni [[Special:Preferences|Ystelligen]] aazpasse.',
+'loginpagetitle' => 'Benutzer-Aamelde',
+'yourname' => 'Dii Benutzername',
+'yourpassword' => 'Basswort',
+'yourpasswordagain' => 'Basswort nommol iitipe',
+'remembermypassword' => 'Passwort spychere',
+'yourdomainname' => 'Diini Domäne',
+'externaldberror' => 'Entwedr s ligt ä Fähler bi dr extern Authentifizierung vor, odr du derfsch din externs Benutzerkonto nit aktualisiere.',
+'loginproblem' => '\'\'\'S het ä Problem mit dinre Onmeldung gäbe.\'\'\'<br />Bitte vosuechs grad nomal!',
+'alreadyloggedin' => '<strong>Si sin scho als Benutzer $1 aagmolde!</strong><br />',
+'login' => 'Aamälde',
+'loginprompt' => '<small>Für di bir {{SITENAME}} aazmälde, muesch [[Cookie]]s erloube!</small>',
+'userlogin' => 'Aamälde',
+'logout' => 'Abmälde',
+'userlogout' => 'Abmälde',
+'notloggedin' => 'Nit aagmäldet',
+'nologin' => 'No chei Benutzerchonto? $1',
+'nologinlink' => '»Chonto aaleege«',
+'createaccount' => 'Nöis Benutzerkonto aalege',
+'gotaccount' => 'Du häsch scho a Chonto? $1',
+'gotaccountlink' => '»Login für beryts aagmeldete Benutzer«',
+'createaccountmail' => 'yber eMail',
+'badretype' => 'Di beidi Passwörter stimme nit yberi.',
+'userexists' => 'Dä Benutzername git’s scho. Bitte lis en anderen uus.',
+'youremail' => 'Ihri E-Bost-Adräss**',
+'username' => 'Benutzernome:',
+'yourrealname' => 'Ihre Name*',
+'yourlanguage' => 'Sproch:',
+'yourvariant' => 'Variante',
+'yournick' => 'Spitzname (zuem Untrschriibe):',
+'badsig' => 'Dr Syntax vun de Signatur isch ungültig; luege uffs HTML.',
+'email' => 'E-Bost',
+'prefs-help-email-enotif'=> 'A die Adrässe wärden o Mails mit Benachrichtigunge geschickt, falls du das ygschalte hesch.',
+'prefs-help-realname' => '* <strong>Dy ächt Name</strong> (optional): We du wosch, das dyni Änderigen uf di chöi zrüggfüert wärde.',
+'loginerror' => 'Fähler bir Aamäldig',
+'prefs-help-email' => '* <strong>E-Bost-Adräss</strong> (optional): Dodemit chönne anderi Lüt übr Ihri Benutzersyte mitene Kontakt uffneh, ohni dass Si muen Ihri E-Bost-Adräss z\'veröffentliche.
+Im Fall dass Si mol Ihr Basswort vergässe hen cha Ihne au e ziitwiiligs Eimol-Basswort gschickt wärde.',
+'nocookieslogin' => '{{SITENAME}} bruucht Cookies für nen Aamäldig. Du hesch Cookies deaktiviert. Aktivier se bitte u versuech’s nomal.',
+'noname' => 'Du muesch ä Benutzername aagebe.',
+'loginsuccesstitle' => 'Aamäldig erfolgrych',
+'loginsuccess' => '\'\'\'Du bisch jetz als "$1" bi {{SITENAME}} aagmäldet.\'\'\'',
+'nosuchuser' => 'Dr Benutzername "$1" exischtiert nit.
+
+Yberprüf d Schribwis, odr meld dich als neijer Benutzer ô.',
+'nosuchusershort' => 'S gibt kei Benutzername „$1“. Bitte yberprüf mol d Schribwis.',
+'nouserspecified' => 'Bitte gib ä Benutzername ii.',
+'wrongpassword' => 'Sell Basswort isch falsch (odr fählt). Bitte versuech\'s nomol.',
+'wrongpasswordempty' => 'Du hesch vagässe diin Basswort iizgeh. Bitte probiers nomol.',
+'mailmypassword' => 'Es nöis Passwort schicke',
+'passwordremindertitle' => 'Neijs Password fier {{SITENAME}}',
+'passwordremindertext' => 'Ebber mit dr IP-Adress $1 het ä neijs Passwort fier d Anmeldung bi {{SITENAME}} ongfordert.
+
+S automatisch generiert Passwort fier de Benutzer $2 lutet jetzert: $3
+
+Du sottsch dich jetzt onmelde un s Passwort ändere: {{fullurl:Special:Userlogin}}
+
+Bitte ignorier diä E-Mail, wenn du s nit selber ongfordert hesch. S alt Passwort blibt witerhin gültig.',
+'noemail' => 'Dr Benutzer "$1" het kei E-Mail-Adress ongebe.',
+'passwordsent' => 'Ä zytwilligs Passwort isch on d E-Mail-Adress vum Benutzer "$1" gschickt worre.
+Bitte meld dich domit ô, wenns bekumme hesch.',
+'eauthentsent' => 'Es Bestätigungs-Mail isch a die Adrässe gschickt worde, wo du hesch aaggä.
+
+Bevor das wyteri Mails yber d {{SITENAME}}-Mailfunktion a die Adrässe gschickt wärde, muesch du d Instruktionen i däm Mail befolge, für z bestätige, das es würklech dys isch.',
+'mailerror' => 'Fähler bim Sende vun de Mail: $1',
+'acct_creation_throttle_hit'=> 'Duet mr leid, so hän scho $1 Benutzer. Si chönne cheini meh aalege.',
+'emailauthenticated' => 'Di E-Bost-Adräss isch am $1 bschtätigt worde.',
+'emailnotauthenticated' => 'Dyni e-Mail-Adrässen isch no nid bestätiget. Drum göh di erwytereten e-Mail-Funktione no nid.
+Für d Bestätigung muesch du em Link folge, wo dir isch gmailet worde. Du chasch ou e nöie söttige Link aafordere:',
+'noemailprefs' => '<strong>Du hesch kei E-Mail-Adrässen aaggä</strong>, drum sy di folgende Funktione nid müglech.',
+'emailconfirmlink' => 'E-Bost-Adräss bschtätige',
+'invalidemailaddress' => 'Diä E-Mail-Adress isch nit akzeptiert worre, wil s ä ugültigs Format ghet het. Bitte gib ä neiji Adress in nem gültige Format ii, odr tue s Feld leere.',
+'accountcreated' => 'De Benutzer isch agleit worre.',
+'accountcreatedtext' => 'De Benutzer $1 isch aagleit worre.',
+'bold_sample' => 'fetti Schrift',
+'bold_tip' => 'Fetti Schrift',
+'italic_sample' => 'kursiv gschribe',
+'italic_tip' => 'Kursiv gschribe',
+'link_sample' => 'Stichwort',
+'extlink_sample' => 'http://www.zumbyschpil.ch Linktekscht',
+'extlink_tip' => 'Externer Link (http:// beachte)',
+'headline_sample' => 'Abschnitts-Überschrift',
+'math_sample' => 'Formel do yfüge',
+'math_tip' => 'Mathematisch Formel (LaTeX)',
+'nowiki_sample' => 'Was da inne staht wird nid formatiert',
+'image_sample' => 'Byschpil.jpg',
+'image_tip' => 'Bildvoweis',
+'media_sample' => 'Byschpil.mp3',
+'media_tip' => 'Mediedateivoweis',
+'hr_tip' => 'Horizontal Linie (sparsom vowende)',
+'summary' => 'Zämefassig',
+'minoredit' => 'Numen es birebitzeli gänderet',
+'watchthis' => 'Dä Artikel beobachte',
+'savearticle' => 'Syte spychere',
+'showpreview' => 'Vorschau aaluege',
+'showdiff' => 'Zeig Änderige',
+'anoneditwarning' => '\'\'\'Warnig:\'\'\' Si sin nit agmolde. Ihri IP-Adrässe wird in de Gschicht vo sellem Artikel gspeicheret.',
+'missingsummary' => '\'\'\'Obacht:\'\'\' Du hesch kei Zämefassig ongebe. Wenn du erneijt uf Spacher durcksch, wird d Änderung ohni gspychert.',
+'missingcommenttext' => 'Bitte gib dinr Kommentar unte ii.',
+'whitelistedittext' => 'Sie müssen sich $1, um Artikel bearbeiten zu können.',
+'whitelistreadtext' => 'Sie müssen sich [[Special:Userlogin|hier anmelden]], um Artikel lesen zu können.',
+'whitelistacctext' => 'Um in diesem Wiki Accounts anlegen zu dürfen, müssen Sie sich [[Special:Userlogin|hier anmelden]] und die nötigen Berechtigungen haben.',
+'confirmedittitle' => 'Zuem Ändere isch e bschtätigti E-Bost-Adräss nötig.',
+'confirmedittext' => 'Si muen Ihri E-Bost-Adräss erscht bstätige bevor Si Syte go ändere chönne. Bitte setze Si in [[Special:Preferences|Ihre Iistellige]] Ihri E-Bost Adräss ii un löhn Si si pruefe.',
+'accmailtitle' => 'S Bassword isch verschickt worre.',
+'accmailtext' => 'S Basswort für "$1" isch uf $2 gschickt worde.',
+'newarticletext' => '<div id="newarticletext">
+{{MediaWiki:Newarticletext/{{NAMESPACE}}}}
+</div>',
+'anontalkpagetext' => '----\'\'Sell isch e Diskussionssyte vome anonyme Benutzer wo chei Zuegang aaglegt het odr wo ihn nit bruucht. Sälleweg muen mir di numerischi IP-Adräss bruuche um ihn odr si z\'identifiziere. Sone IP-Adräss cha au vo mehrere Benutzer deilt werde. Wenn Si en anonyme Benutzer sin un \'s Gfuehl hen, dass do irrelevanti Kommentar an Si grichtet wärde, denn [[Special:Userlogin|lege Si sich bitte en Zuegang aa odr mälde sich aa]] go in Zuekunft Verwirrige mit andere anonyme Benutzer z\'vermeide.\'\'',
+'noarticletext' => '<div id="noarticletext">
+{{MediaWiki:Noarticletext/{{NAMESPACE}}}}
+</div>',
+'clearyourcache' => '\'\'\'Hywys:\'\'\' Nôch dyner Änderig muess no der Browser-Cache gleert wärde!<br />\'\'\'Mozilla/Safari/Konqueror:\'\'\' \'\'Strg-Umschalttaste-R\'\' (oder \'\'Umschalttaste\'\' drückt halte und uf’s \'\'Neu-Laden\'\'-Symbol klicke), \'\'\'IE:\'\'\' \'\'Strg-F5\'\', \'\'\'Opera/Firefox:\'\'\' \'\'F5\'\'',
+'usercsspreview' => '== Vorschau ihres Benutzer-CSS. ==
+\'\'\'Beachten Sie:\'\'\' Nach dem Speichern müssen Sie ihrem Browser sagen, die neue Version zu laden: \'\'\'Mozilla:\'\'\' \'\'Strg-Shift-R\'\', \'\'\'IE:\'\'\' \'\'Strg-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-Shift-R\'\', \'\'\'Konqueror:\'\'\' \'\'F5\'\'.',
+'userjspreview' => '== Vorschau Ihres Benutzer-Javascript. ==
+\'\'\'Beachten Sie:\'\'\' Nach dem Speichern müssen Sie ihrem Browser sagen, die neue Version zu laden: \'\'\'Mozilla:\'\'\' \'\'Strg-Shift-R\'\', \'\'\'IE:\'\'\' \'\'Strg-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-Shift-R\'\', \'\'\'Konqueror:\'\'\' \'\'F5\'\'.',
+'note' => '<strong>Achtung: </strong>',
+'previewnote' => 'Das isch numen e Vorschau und nonig gspycheret!',
+'editing' => 'Bearbeite vo «$1»',
+'editinguser' => 'Bearbeite vo «$1»',
+'editingsection' => 'Bearbeite vo «$1» (Absatz)',
+'editconflict' => 'Bearbeitigs-Konflikt: «$1»',
+'explainconflict' => 'Öpper anders het dä Artikel gänderet, wo du ne sälber am Ändere bisch gsy.
+Im obere Tekschtfäld steit der jitzig Artikel.
+Im untere Tekschtfält stöh dyni Änderige.
+Bitte überträg dyni Änderigen i ds obere Tekschtfäld.
+We du «Syte spychere» drücksch, de wird \'\'\'nume\'\'\' der Inhalt vom obere Tekschtfäld gspycheret.',
+'yourtext' => 'Ihre Tekscht',
+'storedversion' => 'Gspychereti Version',
+'editingold' => '<strong>Obacht: Du bisch en alti Version vo däm Artikel am Bearbeite.
+Alli nöiere Versione wärden überschribe, we du uf «Syte spychere» drücksch.</strong>',
+'yourdiff' => 'Untrschied',
+'copyrightwarning2' => 'Dängge Si dra, dass alli Änderige {{GRAMMAR:dativ {{SITENAME}}}} vo andere Benutzer wiedr gänderet odr glöscht wärde chönne. Wenn Si nit wänn, dass ander Lüt an Ihrem tekscht ummedoktere denn schicke Si ihn jetz nit ab.<br />
+Si verspräche uns usserdäm, dass Si des alles selber gschriebe oder vo nere Quälle kopiert hen, wo Public Domain odr sunscht frei isch (lueg $1 für Details).
+<strong>SETZE SI DO OHNI ERLAUBNIS CHEINI URHEBERRÄCHTLICH GSCHÜTZTI WÄRK INE!</strong>',
+'longpagewarning' => '<span style="color:#ff0000">WARNIG:</span> Die Syten isch $1KB groß; elteri Browser chönnte Problem ha, Sytene z bearbeite wo gröser sy als 32KB. Überleg bitte, öb du Abschnitte vo dere Syte zu eigete Sytene chönntsch usboue.',
+'protectedpagewarning' => '<span style="color:#ff0000">WARNIG:</span> Die Syten isch gsperrt worde, so das se nume Benutzer mit Sysop-Rechten chöi verändere. Bitte häb di a d [[Project:Geschützte Seiten|Regle für gschützti Syte]].',
+'semiprotectedpagewarning'=> '\'\'\'\'\'Halbsperrung\'\'\': Diese Seite kann von angemeldeten Benutzern bearbeitet werden. Für nicht angemeldete oder gerade eben erst angemeldete Benutzer ist der Schreibzugang gesperrt.\'\'',
+'templatesused' => 'Selli Vorlage wärde in sellem Artikel bruucht:',
+'edittools' => '<!-- Selle Text wird untr em "ändere"-Formular un bim "Uffelade"-Formular aagzeigt. -->',
+'revhistory' => 'Früecheri Versione',
+'currentrev' => 'Itzigi Version',
+'revisionasof' => 'Version vo $1',
+'previousrevision' => '← Vorderi Version',
+'nextrevision' => 'Nächschti Version →',
+'currentrevisionlink' => 'Itzigi Version',
+'cur' => 'Jetz',
+'next' => 'Nächschti',
+'last' => 'vorane',
+'histlegend' => 'Du chasch zwei Versionen uswähle und verglyche.<br />
+Erklärig: (aktuell) = Underschid zu jetz,
+(vorane) = Underschid zur alte Version, <strong>K</strong> = chlyni Änderig',
+'histfirst' => 'Eltischti',
+'histlast' => 'Nöischti',
+'difference' => '(Unterschide zwüsche Versione)',
+'compareselectedversions'=> 'Usgwählti Versione verglyche',
+'searchresults' => 'Suech-Ergäbnis',
+'searchresulttext' => 'Für wiiteri Informatione zuem Sueche uff {{SITENAME}} chönne Si mol uff [[Project:Searching|{{SITENAME}} duresueche]] luege.',
+'searchsubtitle' => 'Für d Suechaafrag «[[:$1]]»',
+'searchsubtitleinvalid' => 'Für d Suechaafrag «$1»',
+'prevn' => 'vorderi $1',
+'nextn' => 'nächschti $1',
+'viewprevnext' => '($1) ($2) aazeige; ($3) uf ds Mal',
+'powersearch' => 'Suechi',
+'powersearchtext' => '
+Suche in Namensräumen :<br />
+$1<br />
+$2 Zeige auch REDIRECTs Suche nach $3 $9',
+'searchdisabled' => '<p>Die Volltextsuche wurde wegen Überlastung temporär deaktiviert. Derweil können Sie entweder folgende Google- oder Yahoo-Suche verwenden, die allerdings nicht den aktuellen Stand widerspiegeln.</p>',
+'blanknamespace' => '(Haupt-)',
+'preferences' => 'Iistellige',
+'prefsnologin' => 'Nid aagmäldet',
+'prefsnologintext' => 'Du muesch [[Special:Userlogin|aagmäldet]] sy, für Benutzerystellige chönne z ändere',
+'prefsreset' => 'Du hesch itz wider Standardystellige',
+'changepassword' => 'Passwort ändere',
+'datedefault' => 'kei Aagab',
+'datetime' => 'Datum un Zit',
+'prefs-personal' => 'Benutzerdate',
+'prefs-rc' => 'Letschti Änderige',
+'prefs-watchlist' => 'Beobachtigslischte',
+'prefs-misc' => 'Verschidnigs',
+'saveprefs' => 'Änderige spychere',
+'resetprefs' => 'Änderige doch nid spychere',
+'oldpassword' => 'Alts Passwort',
+'newpassword' => 'Nöis Passwort',
+'retypenew' => 'Nöis Passwort (es zwöits Mal)',
+'textboxsize' => 'Tekscht-Ygab',
+'rows' => 'Zylene',
+'columns' => 'Spaltene',
+'searchresultshead' => 'Suech-Ergäbnis',
+'resultsperpage' => 'Träffer pro Syte',
+'contextlines' => 'Zyle pro Träffer',
+'contextchars' => 'Zeiche pro Zyle',
+'stubthreshold' => 'Artiklen als churz markiere bis (Bytes)',
+'recentchangescount' => 'Aazahl «letschti Änderige»',
+'savedprefs' => 'Dyni Ystellige sy gspycheret worde.',
+'timezonelegend' => 'Zytzone',
+'timezonetext' => 'Zytdifferänz i Stunden aagä zwüsche der Serverzyt u dyre Lokalzyt',
+'localtime' => 'Ortszyt',
+'timezoneoffset' => 'Unterschid¹',
+'servertime' => 'Aktuelli Serverzyt',
+'guesstimezone' => 'Vom Browser la ysetze',
+'allowemail' => 'andere Benutzer erlaube, dass si Ihne E-Bost schicke chönne',
+'defaultns' => 'Namensrüüm wo standardmäässig söll gsuecht wärde:',
+'files' => 'Bilder',
+'userrights-lookup-user'=> 'Verwalte Gruppenzugehörigkeit',
+'editusergroup' => 'Ändere vo Benutzerrächt',
+'userrights-editusergroup'=> 'Bearbeite Gruppenzugehörigkeit des Benutzers',
+'saveusergroups' => 'Speichere Gruppenzugehörigkeit',
+'userrights-groupshelp' => 'Wähle die Gruppen, aus denen der Benutzer entfernt oder zu denen er hinzugefügt werden soll.
+Nicht selektierte Gruppen werden nicht geändert. Eine Selektion kann mit Strg + Linksklick (bzw. Ctrl + Linksklick) entfernt werden.',
+'recentchanges' => 'Letschti Änderige',
+'recentchangestext' => 'Uff sellere Syte chönne Si die letschte Änderige in sellem Wiki aaluege.',
+'rcnote' => 'Anzeig: <b>$1</b> Änderige; <b>$2</b> Täg (<b>N</b> = nöji Artikel; <b>K</b> = chlyni Änderig; <b><span style="color:#ff0000">!</span></b> = unprüeft)',
+'rcnotefrom' => 'Dies sind die Änderungen seit <b>$2</b> (bis zu <b>$1</b> gezeigt).',
+'rclistfrom' => '<small>Nöji Änderige ab $1 aazeige (UTC)</small>',
+'rcshowhideminor' => 'Chlynigkeite $1',
+'rcshowhideliu' => 'Aagmoldene Benützer $1',
+'rcshowhideanons' => 'Uuaagmoldene Benützer $1',
+'rcshowhidepatr' => 'Patrulyrtes $1',
+'rcshowhidemine' => 'Eigeni Änderige $1',
+'rclinks' => 'Zeig di letschte $1 Änderige vo de vergangene $2 Täg.<br />$3',
+'diff' => 'Unterschid',
+'hist' => 'Versione',
+'hide' => 'usblände',
+'show' => 'yblände',
+'upload' => 'Datei uffelade',
+'uploadbtn' => 'Bild lokal ufelade',
+'uploadnologintext' => 'Sie müssen [[Special:Userlogin|angemeldet sein]], um Dateien hochladen zu können.',
+'uploadtext' => 'Bruuche Si sell Formular unte go Dateie uffelade. Zuem aaluege odr fruener uffegladeni Bilder go sueche lueg uff de [[Special:Imagelist|Lischte vo uffegladene Dateie]], Uffeladige un Löschige sin au protokolliert uff [[Special:Log/upload|Uffeladige Protokoll]].
+
+Go e Datei odr en Bild innere Syte iizbaue schriibe Si eifach ane:
+* \'\'\'<nowiki>[[File:file.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[File:file.png|alt text]]</nowiki>\'\'\'
+or
+* \'\'\'<nowiki>[[Media:file.ogg]]</nowiki>\'\'\'
+go direkt e Gleich uff d Datei z\'mache.',
+'copyrightpage' => 'Project:Copyright',
+'minlength' => 'Bilddateien müssen mindestens drei Buchstaben haben.',
+'largefile' => 'Bitte keine Bilder über 100 KByte hochladen.',
+'fileuploaded' => 'D Datei „$1“ isch erfolgriich uffeglade worde. Bitte folge Sie em Gleich $2 uff d Beschriibigssyte un dän Si wiiteri Informatione zue de Datei aa, wo Si si her hän, wer si gmacht het un so wiiter. Wenn sell e Bild isch denn chönne Si des eso iifuege: <tt><nowiki>[[Image:$1|thumb|Beschriibig]]</nowiki></tt>',
+'imagelist' => 'Lischte vo Bilder',
+'imagelisttext' => 'Hier ist eine Liste von $1 Bildern, sortiert $2.',
+'getimagelist' => 'Lade Bilderliste',
+'ilsubmit' => 'Suech',
+'showlast' => 'Zeige die letzten $1 Bilder, sortiert nach $2.',
+'imglegend' => 'Legende: (Beschreibung) = Zeige/Bearbeite Bildbeschreibung.',
+'imghistory' => 'Versione',
+'imghistlegend' => 'Legende: (cur) = Dies ist das aktuelle Bild, (Löschen) = lösche
+diese alte Version, (Zurücksetzen) = verwende wieder diese alte Version.',
+'imagelinks' => 'Bildverweise',
+'linkstoimage' => 'Di folgende Sytene händ en Link zu dem Bildli:',
+'nolinkstoimage' => 'Kein Artikel benutzt dieses Bild.',
+'sharedupload' => 'Selli Datei wird vo verschiedene Projekt bruucht.',
+'noimage-linktext' => 'Lads uffe!',
+'unwatchedpages' => 'Unbeobachteti Sytene',
+'listredirects' => 'Lischte vo Wyterleitige (Redirects)',
+'sitestats' => 'Statistik',
+'userstats' => 'Benützer-Statistik',
+'sitestatstext' => 'Zuer Ziit git\'s \'\'\'$2\'\'\' [[Special:Allpages|Artikel]] in {{SITENAME}}.
+
+Insgsamt sin \'\'\'$1\'\'\' Syte in de Datebank. Selli sin au alli Sytene wo usserhalb vom Hauptnamensruum exischtiere (z.B. Diskussionssyte) odr wo cheini interne Gleicher hen odr wo au numme [[Special:Listredirects|Weiterleitige]] sin.
+
+Insgesamt wurden \'\'\'$8\'\'\' Dateien hochgeladen.
+
+Es isch insgsamt \'\'\'$4\'\'\' mol öbbis gänderet worde un drmit jedi Syte im Durchschnitt \'\'\'$5\'\'\' mol und \'\'\'$6\'\'\' Seitenabrufe pro Bearbeitung.
+
+Es het \'\'\'$8\'\'\' uffegladeni Dateie.
+
+Zuer Ziit stöhn \'\'\'$7\'\'\' Arbete zuem mache aa.',
+'userstatstext' => 'S git \'\'\'$1\'\'\' [[Project:Benutzer|regischtriirte Benutzer]]. Dodrvo sin \'\'\'$2\'\'\' (also \'\'\'$4 %\'\'\') Administratore (lueg au uff $3).',
+'disambiguationspage' => 'Template:Begriffsklärig',
+'doubleredirects' => 'Doppelte Redirects',
+'brokenredirects' => 'Kaputti Wyterleitige',
+'brokenredirectstext' => 'Di folgende Wyterleitige füered zu Artikel wo\'s gar nid git.',
+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
+'ncategories' => '$1 {{PLURAL:$1|Kategori|Kategorie',
+'nlinks' => '$1 {{PLURAL:$1|Gleich|Gleicher}}',
+'nmembers' => '$1 {{PLURAL:$1|Syte|Sytene}}',
+'nrevisions' => '$1 {{PLURAL:$1|Revision|Revisione}}',
+'nviews' => '$1 {{PLURAL:$1|Betrachtig|Betrachtige}}',
+'lonelypages' => 'Verwaisti Sytene',
+'uncategorizedpages' => 'Nit kategorisierte Sytene',
+'uncategorizedcategories'=> 'Nit kategorisierte Kategorie',
+'unusedimages' => 'Verwaiste Bilder',
+'popularpages' => 'Beliebti Artikel',
+'wantedpages' => 'Artikel wo fähle',
+'mostlinked' => 'Meistverlinke Seiten',
+'allpages' => 'alli Sytene',
+'prefixindex' => 'Alli Artikle (mit Präfix)',
+'randompage' => 'Zuefalls-Artikel',
+'shortpages' => 'Churzi Artikel',
+'longpages' => 'Langi Artikel',
+'deadendpages' => 'Artikel ohni Links («Sackgasse»)',
+'listusers' => 'Lischte vo Benutzer',
+'specialpages' => 'Spezialsytene',
+'spheading' => 'Spezial-Sytene für alli Benützer',
+'recentchangeslinked' => 'Verlinktes prüefe',
+'newpages' => 'Nöji Artikel',
+'ancientpages' => 'alti Sytene',
+'move' => 'verschiebe',
+'movethispage' => 'Artikel verschiebe',
+'booksources' => 'ISBN-Suech',
+'categoriespagetext' => 'Selli Kategorie gits in dem Wiki:',
+'userrights' => 'Benutzerrechtsverwaltung',
+'alphaindexline' => 'vo $1 bis $2',
+'alllogstext' => 'Kombinierti Aasicht vo de Protokoll vom Ufelade, Lösche, Schütze, Spärre un de Adminischtratore.
+Si chönnet d Aazeig iischränke wenn Si e Protokoll, e Benutzername odr e Sytename iigän.',
+'logempty' => 'Kei passendi Yträg gfunde.',
+'nextpage' => 'Nächscht Syte ($1)',
+'allpagesfrom' => 'Syte aazeige vo:',
+'allarticles' => 'alli Artikel',
+'allinnamespace' => 'alli Sytene im Namensruum $1',
+'allnotinnamespace' => 'alli Sytene wo nit im $1 Namensruum sin',
+'allpagesprev' => 'Füehrigs',
+'allpagesnext' => 'nächschts',
+'allpagessubmit' => 'gang',
+'allpagesprefix' => 'Alli Sytene mit em Präfix:',
+'mailnologin' => 'Du bisch nid aagmäldet oder hesch keis Mail aaggä',
+'mailnologintext' => 'Du muesch [[Special:Userlogin|aagmäldet sy]] und e bestätigeti e-Mail-Adrässen i dynen [[Special:Preferences|Ystelligen]] aaggä ha, für das du öpper anderem es e-Mail chasch schicke.',
+'emailuser' => 'Es Mail schrybe',
+'emailpage' => 'e-Mail ane BenutzerIn',
+'emailpagetext' => 'Öpperem, wo sälber e bestätigeti e-Mail-Adrässe het aaggä, chasch du mit däm Formular es Mail schicke. Im Absänder steit dyni eigeti e-Mail-Adrässe, so das me dir cha antworte.',
+'usermailererror' => 'Das Mail-Objekt gab einen Fehler zurück:',
+'noemailtitle' => 'Kei e-Mail-Adrässe',
+'noemailtext' => 'Dä Benutzer het kei bestätigeti e-Mail-Adrässen aaggä oder wot kei e-Mails vo anderne Benutzer empfa.',
+'emailfrom' => 'Vo',
+'emailto' => 'Empfänger',
+'emailsubject' => 'Titel',
+'emailmessage' => 'E-Bost',
+'emailsend' => 'Abschicke',
+'emailsent' => 'E-Bost furtgschickt',
+'emailsenttext' => 'Dys e-Mail isch verschickt worde.',
+'watchlist' => 'Beobachtigslischte',
+'nowatchlist' => 'Du hesch ke Yträg uf dyre Beobachtigslischte.',
+'watchnologintext' => 'Du musst [[Special:Userlogin|angemeldet]] sein, um deine Beobachtungsliste zu bearbeiten.',
+'addedwatch' => 'zue de Beobachtigslischte drzue do',
+'addedwatchtext' => 'D Syte "[[:$1]]" stoht jetz uf Ihre [[Special:Watchlist|Beobachtigslischte]].
+Neui Änderige an de Syte odr de Diskussionssyte drvo chasch jetz dört seh. Usserdem sin selli Änderige uf de [[Special:Recentchanges|letschte Änderige]] fett gschriibe, dass Si s schneller finde.
+
+Wenn Si d Syte spöter wiedr vo de Lischte striiche wenn, denn drucke Si eifach uf "nümm beobachte".',
+'watch' => 'beobachte',
+'watchthispage' => 'Die Syte beobachte',
+'unwatch' => 'nümm beobachte',
+'watchnochange' => 'Vo den Artikle, wo du beobachtisch, isch im aazeigte Zytruum kene veränderet worde.',
+'watchdetails' => '{| class="messagebox" id="confirmemail" style="width:auto; background-color:#ffffff; border:1px #ccccff solid; margin: 0 1em 1em;"
+|-
+| \'\'\'Hywys #1:\'\'\' Dur a Schprôchcode-Umschtällung sind kurzzitig vyle Mäldunge uf Änglisch gsi; sot des bi dir allad no dr Fall sy, dann schtell in dyne [[Special:Preferences|Ystellige]] d „Schprôch vo dr Benuzeroberfläch“ uf [\'\'\'gsw - Alemannisch\'\'\'] und schpoicher\'s ab!
+|-
+| \'\'\'Hywys #2:\'\'\' Falls du bi dyner Ärschtaamäldung ou dyne E-Mail-Adress aagea hosch, und du wyterhin Nochrichta yber s’E-Mail-Formulaar empfange wit, isch a [[Special:Confirmemail|Bschtätigung vo dyner E-Mail-Adress]] nootwändig.
+|}
+
+* $1 Artikel wärde beobachtet (Diskussionssyte nid zelt, aber ou beobachtet)
+* [{{fullurl:Special:Watchlist|hideOwn=1}} Eigeni Änderige usblände] |   [[Special:Watchlist/edit|Kompletti Lischte zeigen u bearbeite]]',
+'wlshowlast' => 'Zeig di letschte $1 Stunde $2 Tage $3',
+'wlhideshowown' => '$1 vo dir sälber verändereti Artikle',
+'wlhideshowbots' => '$1 bot edits.',
+'enotif_subject' => 'Die {{SITENAME}} Seite $PAGETITLE wurde von $PAGEEDITOR $CHANGEDORCREATED',
+'enotif_lastvisited' => '$1 zeigt alle Änderungen auf einen Blick.',
+'enotif_body' => 'Liebe/r $WATCHINGUSERNAME,
+
+d {{SITENAME}} Syte $PAGETITLE isch vom $PAGEEDITOR am $PAGEEDITDATE $CHANGEDORCREATED,
+di aktuelli Version isch: $PAGETITLE_URL
+
+$NEWPAGE
+
+Zämmenfassig vom Autor: $PAGESUMMARY $PAGEMINOREDIT
+Kontakt zuem Autor:
+Mail $PAGEEDITOR_EMAIL
+Wiki $PAGEEDITOR_WIKI
+
+Es wird chei wiiteri Benochrichtigungsbost gschickt bis Si selli Syte wiedr bsueche. Uf de Beobachtigssyte chönne Si d Beobachtigsmarker zrucksetze.
+
+ Ihr fründlichs {{SITENAME}} Benochrichtigssyschtem
+
+---
+Ihri Beobachtigslischte {{fullurl:Special:Watchlist/edit}}
+Hilf zue de Benutzig gits uff {{fullurl:WikiHelpdesk}}',
+'deletepage' => 'Syte lösche',
+'confirm' => 'Bestätige',
+'excontentauthor' => 'einzigen Inhalt: \'$1\' (bearbeitet worde nume dür \'$2\')',
+'confirmdelete' => 'Löschig bestätige',
+'deletesub' => '(«$1» lösche)',
+'historywarning' => '<span style="color:#ff0000">WARNUNG:</span> Die Seite die Sie zu löschen gedenken hat eine Versionsgeschichte:',
+'confirmdeletetext' => 'Du bisch drann, en Artikel oder es Bild mitsamt Versionsgschicht permanänt us der Datebank z lösche.
+Bitte bis dir über d Konsequänze bewusst, u bis sicher, das du di a üsi [[Project:Leitlinien|Leitlinien]] haltisch.',
+'actioncomplete' => 'Uftrag usgfuehrt.',
+'deletedtext' => '«$1» isch glösche worde.
+Im $2 het’s e Lischte vo de letschte Löschige.',
+'deletionlog' => 'Lösch-Logbuech',
+'deletecomment' => 'Löschigsgrund',
+'alreadyrolled' => 'Cha d Änderig uf [[:$1]] wo [[User:$2|$2]] ([[User talk:$2|Talk]]) gmacht het nit zruckneh will des öbber anderscht scho gmacht het.
+
+Di letschti Änderig het [[User:$3|$3]] ([[User talk:$3|Talk]]) gmacht.',
+'revertpage' => 'Rückgängig gmacht zuer letschte Änderig vo $1',
+'protectlogtext' => 'Dies ist eine Liste der blockierten Seiten. Siehe [[Project:Geschützte Seiten]] für mehr Informationen.',
+'protectcomment' => 'Grund der Sperrung',
+'undeletehistorynoadmin'=> 'Dieser Artikel wurde gelöscht. Der Grund für die Löschung ist in der Zusammenfassung angegeben,
+genauso wie Details zum letzten Benutzer der diesen Artikel vor der Löschung bearbeitet hat.
+Der aktuelle Text des gelöschten Artikels ist nur Administratoren zugänglich.',
+'undeletebtn' => 'Wiederherstellen!',
+'undeletedrevisions' => '{{PLURAL:$1|ei Revision|$1 Revisione}} wiedr zruckgholt.',
+'namespace' => 'Namensruum:',
+'invert' => 'Uswahl umkehre',
+'contributions' => 'Benutzer-Byträg',
+'mycontris' => 'mini Biiträg',
+'whatlinkshere' => 'Was linkt da ane?',
+'linkshere' => 'Di folgende Sytene händ en Link wo da ane führt:',
+'nolinkshere' => 'Kein Artikel verweist hierhin.',
+'istemplate' => 'Vorlageybindig',
+'blockip' => 'Benutzer bzw. IP blockyre',
+'ipbsubmit' => 'Adresse blockieren',
+'ipboptions' => '1 Stunde:1 hour,2 Stunden:2 hours,6 Stunden:6 hours,1 Tag:1 day,3 Tage:3 days,1 Woche:1 week,2 Wochen:2 weeks,1 Monat:1 month,3 Monate:3 months,1 Jahr:1 year,Für immer:indefinite',
+'ipblocklist' => 'Lischte vo blockierte IP-Adresse',
+'blocklistline' => '$1, $2 het $3 ($4) gschperrt',
+'blocklink' => 'spärre',
+'contribslink' => 'Byträg',
+'blocklogpage' => 'Sperrigs-Protokoll',
+'blocklogentry' => 'sperrt [[User:$1]] - ([[Special:Contributions/$1|Biiträg]]) für d Ziit vo: $2',
+'blocklogtext' => 'Des ischs Logbuech yber Sperrunge un Entsperrunge vun Bnutzer. Automatisch blockti IP-Adresse werre nit erfasst. Lueg au [[Special:Ipblocklist|IP-Block Lischt]] fyr ä Lischt vun gsperrti Bnutzer.',
+'unblocklogentry' => 'Blockade von [[User:$1]] aufgehoben',
+'rightslogtext' => 'Des ischs Logbuech vun de Änderunge on Bnutzerrechte.',
+'already_sysop' => 'Selle Benutzer isch scho Adminischtrator.',
+'already_bureaucrat' => 'Selle Benutzer isch scho Bürokrat.',
+'movepage' => 'Artikel verschiebe',
+'movepagetext' => 'Mit däm Forumlar chasch du en Artikel verschiebe, u zwar mit syre komplette Versionsgschicht. Der alt Titel leitet zum nöie wyter, aber Links ufen alt Titel blyben unveränderet.',
+'movepagetalktext' => 'D Diskussionssyte wird mitverschobe, \'\'\'ussert:\'\'\'
+*Du verschiebsch d Syten i nen andere Namensruum, oder
+*es git scho ne Diskussionssyte mit däm Namen oder
+*du wählsch unte d Option, se nid z verschiebe.
+
+I söttigne Fäll müessti d Diskussionssyten allefalls vo Hand kopiert wärde.',
+'movearticle' => 'Artikel verschiebe',
+'movenologin' => 'Du bisch nid aagmäldet',
+'movenologintext' => 'Du muesch dich z’ersch [[Special:Userlogin|aamälde]] damit du die Syte chasch zügle.',
+'newtitle' => 'Zum nöie Titel',
+'movepagebtn' => 'Artikel verschiebe',
+'pagemovedsub' => 'Verschiebig erfolgrych',
+'pagemovedtext' => 'Artikel "[[$1]]" isch verschobe worden uf "[[$2]]".',
+'articleexists' => 'A Syte mit sellem Name gits scho odr de Name isch ungültigt. Bitte nimm en andere.',
+'movedto' => 'verschoben uf',
+'movetalk' => 'Diskussionssyte nach Müglechkeit mitverschiebe',
+'talkpagemoved' => 'D Diskussionssyten isch mitverschobe worde.',
+'1movedto2' => '[[$1]] isch uf [[$2]] verschobe worde.',
+'1movedto2_redir' => '[[$1]] isch uf [[$2]] verschobe worre un het drbii e Wiiterleitig übrschriebe.',
+'movereason' => 'Grund',
+'selfmove' => 'Der nöi Artikelname mues en andere sy als der alt!',
+'export' => 'Sytenen exportiere',
+'exporttext' => 'Sie können den Text und die Bearbeitungshistorie einer bestimmten oder einer Auswahl von Seiten nach XML exportieren. Das Ergebnis kann in ein anderes Wiki mit Mediawiki Software eingespielt werden, bearbeitet oder archiviert werden.',
+'allmessages' => 'Systemnochrichte',
+'allmessagesname' => 'Name',
+'allmessagesdefault' => 'Standard-Tekscht',
+'allmessagescurrent' => 'jetzige Tekscht',
+'allmessagestext' => 'Sell isch e Lischte vo alle mögliche Systemnochrichte ussem MediaWiki Namensruum.',
+'allmessagesnotsupportedUI'=> 'Diini Sprochiistellig \'\'\'$1\'\'\' wird vo Special:Allmessages uff sellere Syte nit unterschtützt.',
+'allmessagesnotsupportedDB'=> '\'\'\'Special:Allmessages\'\'\' cha nit bruucht wärde will \'\'\'$wgUseDatabaseMessages\'\'\' abgschalte isch.',
+'allmessagesfilter' => 'Nochrichte nochem Name filtere:',
+'allmessagesmodified' => 'numme gänderti aazeige',
+'importtext' => 'Bitte speichere Si selli Syte vom Quellwiki met em Special:Export Wärkzüg ab un lade Si denn di Datei denn do uffe.',
+'anonymous' => 'Anonyme Benutzer uff {{SITENAME}}',
+'lastmodifiedatby' => 'Diese Seite wurde zuletzt geändert um $2, $1 von $3.',
+'and' => 'un',
+'othercontribs' => 'Basiert auf der Arbeit von $1.',
+'spamprotectiontitle' => 'Spamschutz-Filter',
+'subcategorycount' => 'In sellere Kategori {{PLURAL:$1|isch no ei Unterkategori|sin no $1 Unterkategorie}}.',
+'categoryarticlecount' => 'In sellere Kategorie {{PLURAL:$1|isch ei Artikel|sin $1 Artikel}}.',
+'listingcontinuesabbrev'=> ' (Forts.)',
+'mw_math_png' => 'Immer als PNG aazeige',
+'mw_math_simple' => 'Eifachs TeX als HTML aazeige, süsch als PNG',
+'mw_math_html' => 'Falls müglech als HTML aazeige, süsch als PNG',
+'mw_math_source' => 'Als TeX la sy (für Tekschtbrowser)',
+'mw_math_modern' => 'Empfolnigi Ystellig für modärni Browser',
+'markaspatrolleddiff' => 'Als geprüft markiere',
+'markaspatrolledtext' => 'Den Artikel als geprüft markiere',
+'markedaspatrolledtext' => 'Die usgwählte Artikeländerung isch als geprüft markiert worre.',
+'monobook.js' => ' var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Myni Benutzersyte\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Myni Diskussionssyte\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Myni Ystellige\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Lischte vo de beobachtete Syte.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Lischte vo myne Byträg\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Ylogge\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Uslogge\');
+ ta[\'ca-article\'] = new Array(\'a\',\'Artikel aaluege\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskussion zum Artikelinhalt\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Syte bearbeite. Bitte vor em Spychere d Vorschou aaluege.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'E Kommentar zu dere Syte derzuetue.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Die Syte isch geschützt. Du chasch der Quelltext aaluege.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Früecheri Versione vo dere Syte.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Seite beschütze\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Syten entsorge\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Sodeli, da isch es wider.\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Dür ds Verschiebe gits e nöie Name.\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Du darfsch die Syte nid verschiebe.\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Tue die Syten uf dyni Beobachtigslischte.\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Nim die Syte us dyre Beobachtungslischte furt.\');
+ ta[\'search\'] = new Array(\'f\',\'Dürchsuech das Wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Houptsyte\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Gang uf d Houptsyte\');
+ ta[\'n-portal\'] = new Array(\'\',\'Über ds Projekt, was du chasch mache, wo du was findsch\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Lischte vo de letschten Änderige i däm Wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'E zuefälligi Syte\');
+ ta[\'n-help\'] = new Array(\'\',\'Ds Ort zum Usefinde.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Unterstütz üs\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lischte vo allne Sytene, wo do ane linke\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Letschti Änderige vo de Syte, wo vo do verlinkt sin\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS-Feed für selli Syte\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom-Feed für selli Syte\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Lischte vo de Byträg vo däm Benutzer\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Schick däm Benutzer e E-Bost\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lischte vo allne Spezialsyte\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Artikelinhalt aaluege\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Benutzersyte aaluege\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Mediasyte aaluege\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Sell isch e Spezialsyte, du chasch se nid bearbeite.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'D Projektsyte aaluege\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Die Bildsyten aaluege\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'D Systemmäldige aaluege\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'D Vorlag aaluege\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'D Hilfssyten aaluege\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'D Kategoryesyten aaluege\');',
+'previousdiff' => '← Vorderi Änderig',
+'nextdiff' => 'Nächschti Änderig →',
+'imagemaxsize' => 'Maximali Gröössi vo de Bilder uf de Bildbeschrybigs-Sytene:',
+'thumbsize' => 'Bildvorschou-Gröössi:',
+'newimages' => 'Gallery vo noie Bilder',
+'mediawarning' => '
+===Warnung!===
+Diese Art von Datei kann böswilligen Programmcode enthalten.
+Durch das Herunterladen oder Öffnen der Datei kann der Computer beschädigt werden.
+Bereits das Anklicken des Links kann dazu führen dass der Browser die Datei öffnet
+und unbekannter Programmcode zur Ausführung kommt.
+
+Die Betreiber dieses Wikis können keine Verantwortung für den Inhalte
+dieser Datei übernehmen. Sollte diese Datei tatsächlich böswilligen Programmcode enthalten,
+sollte umgehend ein Administrator informiert werden!',
+'fileinfo' => '$1KB, MIME Typ: <code>$2</code>',
+'exif-orientation' => 'Orientierung',
+'exif-copyright' => 'Copyright',
+'exif-pixelxdimension' => 'Valind image height',
+'exif-fnumber' => 'F-Wert',
+'exif-isospeedratings' => 'Filmempfindlichkeit (ISO)',
+'exif-shutterspeedvalue'=> 'Shutter Speed Value',
+'exif-brightnessvalue' => 'Brightness Value',
+'edit-externally-help' => 'Siehe [http://meta.wikimedia.org/wiki/Hilfe:Externe_Editoren Installations-Anweisungen] für weitere Informationen',
+'watchlistall1' => 'alli',
+'watchlistall2' => 'alli',
+'confirmemail' => 'Bschtätigung vo Ihre E-Bost-Adräss',
+'confirmemail_text' => 'Dermit du di erwyterete Mailfunktione chasch bruuche, muesch du die e-Mail-Adrässe, wo du hesch aaggä, la bestätige. Klick ufe Chnopf unte; das schickt dir es Mail. I däm Mail isch e Link; we du däm Link folgsch, de tuesch dadermit bestätige, das die e-Mail-Adrässe dyni isch.',
+'confirmemail_send' => 'Bestätigungs-Mail verschicke',
+'confirmemail_sent' => 'Es isch dir es Mail zur Adrässbestätigung gschickt worde.',
+'confirmemail_sendfailed'=> 'Could not send confirmation mail due to misconfigured server or invalid characters in e-mail address.',
+'confirmemail_success' => 'Dyni e-Mail-Adrässen isch bestätiget worde. Du chasch di jitz ylogge.',
+'confirmemail_loggedin' => 'Dyni e-Mail-Adrässen isch jitz bestätiget.',
+'confirmemail_subject' => '{{SITENAME}} e-Mail-Adrässbestätigung',
+'confirmemail_body' => 'Hallo
+
+{{SITENAME}}}}-BenutzerIn «$2» — das bisch allwäg du — het sech vor IP-Adrässen $1 uus mit deren e-Mail-Adrässe bi {{SITENAME}} aagmäldet.
+
+Für z bestätige, das die Adrässe würklech dir isch, u für dyni erwytereten e-Mail-Funktionen uf {{SITENAME}} yzschalte, tue bitte der folgend Link i dym Browser uuf:
+
+$3
+
+Falls du *nid* $2 sötsch sy, de tue dä Link bitte nid uuf.
+
+Die Bestätigung isch nume müglech bis $4.
+
+Fründtlechi Grüess',
+'confirm_purge' => 'Die Zwischeschpoicherung vo der Syte „{{FULLPAGENAME}}“ lösche?
+
+$1
+
+<div style="font-size: 95%; margin-top: 2em;">
+\'\'\'\'\'Erklärig:\'\'\'\'\'
+
+\'\'Zwüschespycherige (Cache) sy temporäri Kopye vore Websyten uf dym Computer. We ne Syte us em Zwüschespycher abgrüefft wird, de bruucht das weniger Rächeleischtig füre {{SITENAME}}-Server als en Abrueff vor Originalsyte.\'\'
+
+\'\'Falls du e Syte scho nes Wyli am Aaluege bisch, de het dy Computer sone Zwüschespycherig gmacht. Derby chönnt die Syten unter Umständ scho i dere Zyt liecht veraltere.\'\'
+
+\'\'Ds Lösche vor Zwüschespycherig zwingt der Server, dir di aktuellschti Version vor Syte z gä!\'\'
+</div>',
+'youhavenewmessagesmulti'=> 'Si hen neui Nochrichte: $1',
+);
+?>
diff --git a/languages/messages/MessagesGu.php b/languages/messages/MessagesGu.php
new file mode 100644
index 000000000000..842267c1d560
--- /dev/null
+++ b/languages/messages/MessagesGu.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$digitTransformTable = array(
+ '0' => '૦',
+ '1' => '૧',
+ '2' => '૨',
+ '3' => '૩',
+ '4' => '૪',
+ '5' => '૫',
+ '6' => '૬',
+ '7' => '૭',
+ '8' => '૮',
+ '9' => '૯'
+);
+?>
diff --git a/languages/messages/MessagesHe.php b/languages/messages/MessagesHe.php
new file mode 100644
index 000000000000..9b01307263e5
--- /dev/null
+++ b/languages/messages/MessagesHe.php
@@ -0,0 +1,2206 @@
+<?php
+/**
+ * Hebrew (עברית)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Rotem Dan (July 2003)
+ * @author Rotem Liss (March 2006 on)
+ */
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+);
+
+$linkTrail = '/^([a-zא-ת]+)(.*)$/sDu';
+$fallback8bitEncoding = 'windows-1255';
+
+$skinNames = array(
+ 'standard' => 'רגיל',
+ 'nostalgia' => 'נוסטלגי',
+ 'cologneblue' => 'מים כחולים',
+ 'davinci' => "דה־וינצ'י",
+ 'simple' => 'פשוט',
+ 'mono' => 'מונו',
+ 'monobook' => 'מונובוק',
+ 'myskin' => 'הרקע שלי',
+ 'chick' => "צ'יק"
+);
+
+$quickbarSettings = array(
+ 'ללא', 'קבוע משמאל', 'קבוע מימין', 'צף משמאל', 'צף מימין'
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'xg j, Y',
+ 'mdy both' => 'H:i, xg j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j xg Y',
+ 'dmy both' => 'H:i, j xg Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y xg j',
+ 'ymd both' => 'H:i, Y xg j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+$bookstoreList = array(
+ 'מיתוס' => 'http://www.mitos.co.il/',
+ 'iBooks' => 'http://www.ibooks.co.il/',
+ 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+$magicWords = array(
+ 'redirect' => array( 0, '#הפניה', '#REDIRECT' ),
+ 'notoc' => array( 0, '__ללא_תוכן_עניינים__', '__ללא_תוכן__', '__NOTOC__' ),
+ 'nogallery' => array( 0, '__ללא_גלריה__', '__NOGALLERY__' ),
+ 'forcetoc' => array( 0, '__חייב_תוכן_עניינים__', '__חייב_תוכן__', '__FORCETOC__' ),
+ 'toc' => array( 0, '__תוכן_עניינים__', '__תוכן__', '__TOC__' ),
+ 'noeditsection' => array( 0, '__ללא_עריכה__', '__NOEDITSECTION__' ),
+ 'start' => array( 0, '__התחלה__', '__START__' ),
+ 'currentmonth' => array( 1, 'חודש נוכחי', 'CURRENTMONTH' ),
+ 'currentmonthname' => array( 1, 'שם חודש נוכחי', 'CURRENTMONTHNAME' ),
+ 'currentmonthnamegen' => array( 1, 'שם חודש נוכחי קניין', 'CURRENTMONTHNAMEGEN' ),
+ 'currentmonthabbrev' => array( 1, 'קיצור חודש נוכחי', 'CURRENTMONTHABBREV' ),
+ 'currentday' => array( 1, 'יום נוכחי', 'CURRENTDAY' ),
+ 'currentday2' => array( 1, 'יום נוכחי 2', 'CURRENTDAY2' ),
+ 'currentdayname' => array( 1, 'שם יום נוכחי', 'CURRENTDAYNAME' ),
+ 'currentyear' => array( 1, 'שנה נוכחית', 'CURRENTYEAR' ),
+ 'currenttime' => array( 1, 'שעה נוכחית', 'CURRENTTIME' ),
+ 'currenthour' => array( 1, 'שעות נוכחיות', 'CURRENTHOUR' ),
+ 'localmonth' => array( 1, 'חודש מקומי', 'LOCALMONTH' ),
+ 'localmonthname' => array( 1, 'שם חודש מקומי', 'LOCALMONTHNAME' ),
+ 'localmonthnamegen' => array( 1, 'שם חודש מקומי קניין', 'LOCALMONTHNAMEGEN' ),
+ 'localmonthabbrev' => array( 1, 'קיצור חודש מקומי', 'LOCALMONTHABBREV' ),
+ 'localday' => array( 1, 'יום מקומי', 'LOCALDAY' ),
+ 'localday2' => array( 1, 'יום מקומי 2', 'LOCALDAY2' ),
+ 'localdayname' => array( 1, 'שם יום מקומי', 'LOCALDAYNAME' ),
+ 'localyear' => array( 1, 'שנה מקומית', 'LOCALYEAR' ),
+ 'localtime' => array( 1, 'שעה מקומית', 'LOCALTIME' ),
+ 'localhour' => array( 1, 'שעות מקומיות', 'LOCALHOUR' ),
+ 'numberofpages' => array( 1, 'מספר דפים כולל', 'מספר דפים', 'NUMBEROFPAGES' ),
+ 'numberofarticles' => array( 1, 'מספר ערכים', 'NUMBEROFARTICLES' ),
+ 'numberoffiles' => array( 1, 'מספר קבצים', 'NUMBEROFFILES' ),
+ 'numberofusers' => array( 1, 'מספר משתמשים', 'NUMBEROFUSERS' ),
+ 'pagename' => array( 1, 'שם הדף', 'PAGENAME' ),
+ 'pagenamee' => array( 1, 'שם הדף מקודד', 'PAGENAMEE' ),
+ 'namespace' => array( 1, 'מרחב השם', 'NAMESPACE' ),
+ 'namespacee' => array( 1, 'מרחב השם מקודד', 'NAMESPACEE' ),
+ 'talkspace' => array( 1, 'מרחב השיחה', 'TALKSPACE' ),
+ 'talkspacee' => array( 1, 'מרחב השיחה מקודד', 'TALKSPACEE' ),
+ 'subjectspace' => array( 1, 'מרחב הנושא', 'מרחב הערכים', 'SUBJECTSPACE', 'ARTICLESPACE' ),
+ 'subjectspacee' => array( 1, 'מרחב הנושא מקודד', 'מרחב הערכים מקודד', 'SUBJECTSPACEE', 'ARTICLESPACEE' ),
+ 'fullpagename' => array( 1, 'שם הדף המלא', 'FULLPAGENAME' ),
+ 'fullpagenamee' => array( 1, 'שם הדף המלא מקודד', 'FULLPAGENAMEE' ),
+ 'subpagename' => array( 1, 'שם דף המשנה', 'SUBPAGENAME' ),
+ 'subpagenamee' => array( 1, 'שם דף המשנה מקודד', 'SUBPAGENAMEE' ),
+ 'basepagename' => array( 1, 'שם דף הבסיס', 'BASEPAGENAME' ),
+ 'basepagenamee' => array( 1, 'שם דף הבסיס מקודד', 'BASEPAGENAMEE' ),
+ 'talkpagename' => array( 1, 'שם דף השיחה', 'TALKPAGENAME' ),
+ 'talkpagenamee' => array( 1, 'שם דף השיחה מקודד', 'TALKPAGENAMEE' ),
+ 'subjectpagename' => array( 1, 'שם דף הנושא', 'שם הערך', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ),
+ 'subjectpagenamee' => array( 1, 'שם דף הנושא מקודד', 'שם הערך מקודד', 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ),
+ 'msg' => array( 0, 'הכללה:', 'MSG:' ),
+ 'subst' => array( 0, 'ס:', 'SUBST:' ),
+ 'msgnw' => array( 0, 'הכללת מקור', 'MSGNW:' ),
+ 'end' => array( 0, '__סוף__', '__END__' ),
+ 'img_thumbnail' => array( 1, 'ממוזער', 'thumbnail', 'thumb' ),
+ 'img_manualthumb' => array( 1, 'ממוזער=$1', 'thumbnail=$1', 'thumb=$1'),
+ 'img_right' => array( 1, 'ימין', 'right' ),
+ 'img_left' => array( 1, 'שמאל', 'left' ),
+ 'img_none' => array( 1, 'ללא', 'none' ),
+ 'img_width' => array( 1, '$1px', '$1px' ),
+ 'img_center' => array( 1, 'מרכז', 'center', 'centre' ),
+ 'img_framed' => array( 1, 'ממוסגר', 'מסגרת', 'framed', 'enframed', 'frame' ),
+ 'img_page' => array( 1, 'דף=$1', 'דף $1', 'page=$1', 'page $1' ),
+ 'int' => array( 0, 'הודעה:', 'INT:' ),
+ 'sitename' => array( 1, 'שם האתר', 'SITENAME' ),
+ 'ns' => array( 0, 'מרחב שם:', 'NS:' ),
+ 'localurl' => array( 0, 'כתובת יחסית:', 'LOCALURL:' ),
+ 'localurle' => array( 0, 'כתובת יחסית מקודד:', 'LOCALURLE:' ),
+ 'server' => array( 0, 'כתובת השרת', 'שרת', 'SERVER' ),
+ 'servername' => array( 0, 'שם השרת', 'SERVERNAME' ),
+ 'scriptpath' => array( 0, 'נתיב הקבצים', 'SCRIPTPATH' ),
+ 'grammar' => array( 0, 'דקדוק:', 'GRAMMAR:' ),
+ 'notitleconvert' => array( 0, '__ללא_המרת_כותרת__', '__NOTITLECONVERT__', '__NOTC__'),
+ 'nocontentconvert' => array( 0, '__ללא_המרת_תוכן__', '__NOCONTENTCONVERT__', '__NOCC__'),
+ 'currentweek' => array( 1, 'שבוע נוכחי', 'CURRENTWEEK' ),
+ 'currentdow' => array( 1, 'מספר יום נוכחי', 'CURRENTDOW' ),
+ 'localweek' => array( 1, 'שבוע מקומי', 'LOCALWEEK' ),
+ 'localdow' => array( 1, 'מספר יום מקומי', 'LOCALDOW' ),
+ 'revisionid' => array( 1, 'מזהה גרסה', 'REVISIONID' ),
+ 'plural' => array( 0, 'רבים:', 'PLURAL:' ),
+ 'fullurl' => array( 0, 'כתובת מלאה:', 'FULLURL:' ),
+ 'fullurle' => array( 0, 'כתובת מלאה מקודד:', 'FULLURLE:' ),
+ 'lcfirst' => array( 0, 'אות ראשונה קטנה:', 'LCFIRST:' ),
+ 'ucfirst' => array( 0, 'אות ראשונה גדולה:', 'UCFIRST:' ),
+ 'lc' => array( 0, 'אותיות קטנות:', 'LC:' ),
+ 'uc' => array( 0, 'אותיות גדולות:', 'UC:' ),
+ 'raw' => array( 0, 'ללא עיבוד:', 'RAW:' ),
+ 'displaytitle' => array( 1, 'כותרת תצוגה', 'DISPLAYTITLE' ),
+ 'rawsuffix' => array( 1, 'ללא פסיק', 'R' ),
+ 'newsectionlink' => array( 1, '__יצירת_הערה__', '__NEWSECTIONLINK__' ),
+ 'currentversion' => array( 1, 'גרסה נוכחית', 'CURRENTVERSION' ),
+ 'urlencode' => array( 0, 'נתיב מקודד:', 'URLENCODE:' ),
+ 'anchorencode' => array( 0, 'עוגן מקודד:', 'ANCHORENCODE' ),
+ 'currenttimestamp' => array( 1, 'זמן נוכחי', 'CURRENTTIMESTAMP' ),
+ 'localtimestamp' => array( 1, 'זמן מקומי', 'LOCALTIMESTAMP' ),
+ 'directionmark' => array( 1, 'סימן כיווניות', 'DIRECTIONMARK', 'DIRMARK' ),
+ 'language' => array( 0, '#שפה:', '#LANGUAGE:' ),
+ 'contentlanguage' => array( 1, 'שפת תוכן', 'CONTENTLANGUAGE', 'CONTENTLANG' ),
+ 'pagesinnamespace' => array( 1, 'דפים במרחב השם:', 'PAGESINNAMESPACE:', 'PAGESINNS:' ),
+ 'numberofadmins' => array( 1, 'מספר מפעילים', 'NUMBEROFADMINS' ),
+ 'formatnum' => array( 0, 'עיצוב מספר', 'FORMATNUM' ),
+ 'padleft' => array( 0, 'ריפוד משמאל', 'PADLEFT' ),
+ 'padright' => array( 0, 'ריפוד מימין', 'PADRIGHT' ),
+ 'special' => array( 0, 'מיוחד', 'special' ),
+ 'defaultsort' => array( 1, 'מיון רגיל:', 'DEFAULTSORT:' ),
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'מדיה',
+ NS_SPECIAL => 'מיוחד',
+ NS_MAIN => '',
+ NS_TALK => 'שיחה',
+ NS_USER => 'משתמש',
+ NS_USER_TALK => 'שיחת_משתמש',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'שיחת_$1',
+ NS_IMAGE => 'תמונה',
+ NS_IMAGE_TALK => 'שיחת_תמונה',
+ NS_MEDIAWIKI => 'מדיה_ויקי',
+ NS_MEDIAWIKI_TALK => 'שיחת_מדיה_ויקי',
+ NS_TEMPLATE => 'תבנית',
+ NS_TEMPLATE_TALK => 'שיחת_תבנית',
+ NS_HELP => 'עזרה',
+ NS_HELP_TALK => 'שיחת_עזרה',
+ NS_CATEGORY => 'קטגוריה',
+ NS_CATEGORY_TALK => 'שיחת_קטגוריה',
+);
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'סמן קישורים בקו תחתי',
+'tog-highlightbroken' => 'סמן קישורים לדפים שלא נכתבו <a href="" class="new">כך</a> (או: כך<a href="" class="internal">?</a>))',
+'tog-justify' => 'ישר פסקאות',
+'tog-hideminor' => 'הסתר שינויים משניים ברשימת השינויים האחרונים',
+'tog-extendwatchlist' => 'הרחב את רשימת המעקב כך שתציג את כל השינויים המתאימים (אחרת: את השינוי האחרון בכל דף בלבד)',
+'tog-usenewrc' => 'רשימת שינויים אחרונים משופרת (JavaScript)',
+'tog-numberheadings' => 'מספר כותרות אוטומטית',
+'tog-showtoolbar' => 'הצג את סרגל העריכה',
+'tog-editondblclick' => 'ערוך דפים בלחיצה כפולה (JavaScript)',
+'tog-editsection' => 'הפעל עריכת פסקאות באמצעות קישורים מהצורה [עריכה]',
+'tog-editsectiononrightclick' => 'הפעל עריכת פסקאות על־ידי לחיצה ימנית<br />על כותרות הפסקאות (JavaScript)',
+'tog-showtoc' => 'הצג תוכן עניינים<br />(עבור דפים עם יותר מ־3 כותרות)',
+'tog-rememberpassword' => 'זכור את הכניסה שלי במחשב זה',
+'tog-editwidth' => 'תיבת העריכה ברוחב מלא',
+'tog-watchcreations' => 'עקוב אחרי דפים שיצרתי',
+'tog-watchdefault' => 'עקוב אחרי דפים שערכתי',
+'tog-watchmoves' => 'עקוב אחרי דפים שהעברתי',
+'tog-watchdeletion' => 'עקוב אחרי דפים שמחקתי',
+'tog-minordefault' => 'הגדר כל פעולת עריכה כמשנית אם לא צויין אחרת',
+'tog-previewontop' => 'הצג תצוגה מקדימה לפני תיבת העריכה (או: אחריה)',
+'tog-previewonfirst' => 'הצג תצוגה מקדימה בעריכה ראשונה',
+'tog-nocache' => 'נטרל משיכת דפים מזכרון המטמון שבשרת',
+'tog-enotifwatchlistpages' => 'שלח לי דוא"ל כאשר נעשה שינוי בדפים הנצפים על־ידי',
+'tog-enotifusertalkpages' => 'שלח לי דוא"ל כאשר נעשה שינוי בדף שיחת המשתמש שלי',
+'tog-enotifminoredits' => 'שלח לי דוא"ל גם על עריכות משניות של דפים',
+'tog-enotifrevealaddr' => 'חשוף את כתובת הדוא"ל שלי בהודעות דואר',
+'tog-shownumberswatching' => 'הצג את מספר המשתמשים הצופים בדף',
+'tog-fancysig' => 'הצג חתימה מסוגננת',
+'tog-externaleditor' => 'השתמש בעורך חיצוני כברירת מחדל',
+'tog-externaldiff' => 'השתמש בתוכנת השוואת הגרסאות החיצונית כברירת מחדל',
+'tog-showjumplinks' => 'אפשר קישורי נגישות מסוג "קפוץ אל"',
+'tog-uselivepreview' => 'השתמש בתצוגה מקדימה חיה (JavaScript) (ניסיוני)',
+'tog-forceeditsummary' => 'הזהר אותי כשאני מכניס תקציר עריכה ריק',
+'tog-watchlisthideown' => 'הסתר עריכות שלי ברשימת המעקב',
+'tog-watchlisthidebots' => 'הסתר בוטים ברשימת המעקב',
+'tog-watchlisthideminor' => 'הסתר עריכות משניות ברשימת המעקב',
+'tog-nolangconversion' => 'בטל המרת גרסאות שפה',
+'tog-ccmeonemails' => 'שלח אלי העתקים של הודעות דואר אלקטרוני שאני שולח למשתמשים אחרים',
+
+'underline-always' => 'תמיד',
+'underline-never' => 'אף פעם',
+'underline-default' => 'ברירת מחדל של הדפדפן',
+
+'skinpreview' => '(תצוגה מקדימה)',
+
+# Dates
+'sunday' => 'ראשון',
+'monday' => 'שני',
+'tuesday' => 'שלישי',
+'wednesday' => 'רביעי',
+'thursday' => 'חמישי',
+'friday' => 'שישי',
+'saturday' => 'שבת',
+'sun' => "ראש'",
+'mon' => 'שני',
+'tue' => "שלי'",
+'wed' => "רבי'",
+'thu' => "חמי'",
+'fri' => "שיש'",
+'sat' => 'שבת',
+'january' => 'ינואר',
+'february' => 'פברואר',
+'march' => 'מרץ',
+'april' => 'אפריל',
+'may_long' => 'מאי',
+'june' => 'יוני',
+'july' => 'יולי',
+'august' => 'אוגוסט',
+'september' => 'ספטמבר',
+'october' => 'אוקטובר',
+'november' => 'נובמבר',
+'december' => 'דצמבר',
+'january-gen' => 'בינואר',
+'february-gen' => 'בפברואר',
+'march-gen' => 'במרץ',
+'april-gen' => 'באפריל',
+'may-gen' => 'במאי',
+'june-gen' => 'ביוני',
+'july-gen' => 'ביולי',
+'august-gen' => 'באוגוסט',
+'september-gen' => 'בספטמבר',
+'october-gen' => 'באוקטובר',
+'november-gen' => 'בנובמבר',
+'december-gen' => 'בדצמבר',
+'jan' => "ינו'",
+'feb' => "פבר'",
+'mar' => 'מרץ',
+'apr' => "אפר'",
+'may' => 'מאי',
+'jun' => 'יוני',
+'jul' => 'יולי',
+'aug' => "אוג'",
+'sep' => "ספט'",
+'oct' => "אוק'",
+'nov' => "נוב'",
+'dec' => "דצמ'",
+
+# Bits of text used by many pages
+'categories' => 'קטגוריות',
+'pagecategories' => '{{plural:$1|קטגוריה|קטגוריות}}',
+'category_header' => 'דפים בקטגוריה "$1"',
+'subcategories' => 'קטגוריות משנה',
+'category-media-header' => 'קבצי מדיה בקטגוריה "$1"',
+
+'mainpage' => 'עמוד ראשי',
+'mainpagetext' => "'''תוכנת מדיה־ויקי הותקנה בהצלחה.'''",
+'mainpagedocfooter' => 'היעזרו ב[http://meta.wikimedia.org/wiki/Help:Contents מדריך למשתמש] למידע על שימוש בתוכנת הוויקי.
+
+== קישורים שימושיים ==
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings רשימת ההגדרות]
+* [http://www.mediawiki.org/wiki/Help:FAQ שאלות נפוצות]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]',
+
+'portal' => 'שער הקהילה',
+'portal-url' => '{{ns:project}}:שער הקהילה',
+'about' => 'אודות',
+'aboutsite' => 'אודות {{SITENAME}}',
+'aboutpage' => '{{ns:project}}:אודות',
+'article' => 'דף תוכן',
+'help' => 'עזרה',
+'helppage' => '{{ns:project}}:עזרה',
+'bugreports' => 'דיווח על באגים',
+'bugreportspage' => '{{ns:project}}:דיווח על באגים',
+'sitesupport' => 'תרומות',
+'sitesupport-url' => '{{ns:project}}:תרומות',
+'faq' => 'שאלות ותשובות',
+'faqpage' => '{{ns:project}}:שאלות ותשובות',
+'edithelp' => 'עזרה לעריכה',
+'newwindow' => '(נפתח בחלון חדש)',
+'edithelppage' => '{{ns:project}}:איך לערוך דף',
+'cancel' => 'בטל / צא',
+'qbfind' => 'חיפוש',
+'qbbrowse' => 'דפדוף',
+'qbedit' => 'עריכה',
+'qbpageoptions' => 'אפשרויות דף',
+'qbpageinfo' => 'מידע על הדף',
+'qbmyoptions' => 'האפשרויות שלי',
+'qbspecialpages' => 'דפים מיוחדים',
+'moredotdotdot' => 'עוד…',
+'mypage' => 'הדף שלי',
+'mytalk' => 'דף השיחה שלי',
+'anontalk' => 'השיחה עבור IP זה',
+'navigation' => 'ניווט',
+
+# Metadata in edit box
+'metadata_help' => 'Metadata (ראו [[{{ns:project}}:Metadata]] למידע נוסף):',
+
+'currentevents' => 'אקטואליה',
+'currentevents-url' => 'אקטואליה',
+
+'disclaimers' => 'הבהרה משפטית',
+'disclaimerpage' => '{{ns:project}}:הבהרה משפטית',
+'privacy' => 'מדיניות הפרטיות',
+'privacypage' => '{{ns:project}}:מדיניות הפרטיות',
+'errorpagetitle' => 'שגיאה',
+'returnto' => 'חזרה לדף $1.',
+'tagline' => 'מתוך {{SITENAME}}',
+'search' => 'חיפוש',
+'searchbutton' => 'חיפוש',
+'go' => 'עבור',
+'searcharticle' => 'עבור',
+'history' => 'היסטוריית הדף',
+'history_short' => 'היסטוריה',
+'updatedmarker' => 'עודכן מאז ביקורך האחרון',
+'info_short' => 'מידע',
+'printableversion' => 'גרסת הדפסה',
+'permalink' => 'קישור קבוע',
+'print' => 'גרסה להדפסה',
+'edit' => 'עריכה',
+'editthispage' => 'ערכו דף זה',
+'delete' => 'מחיקה',
+'deletethispage' => 'מחקו דף זה',
+'undelete_short' => 'שחזר {{plural:$1|עריכה אחת|$1 עריכות}}',
+'protect' => 'הגנה',
+'protectthispage' => 'הגנו על דף זה',
+'unprotect' => 'הסרת הגנה',
+'unprotectthispage' => 'הסירו הגנה מדף זה',
+'newpage' => 'דף חדש',
+'talkpage' => 'שוחחו על דף זה',
+'specialpage' => 'דף מיוחד',
+'personaltools' => 'כלים אישיים',
+'postcomment' => 'הוסף הערה לדף השיחה',
+'articlepage' => 'צפיה בדף התוכן',
+'talk' => 'שיחה',
+'views' => 'צפיות',
+'toolbox' => 'תיבת כלים',
+'userpage' => 'צפיה בדף המשתמש',
+'projectpage' => 'צפיה בדף המיזם',
+'imagepage' => 'צפיה בדף התמונה',
+'mediawikipage' => 'צפיה בדף ההודעה',
+'templatepage' => 'צפיה בדף התבנית',
+'viewhelppage' => 'צפיה בדף העזרה',
+'categorypage' => 'צפיה בדף הקטגוריה',
+'viewtalkpage' => 'צפיה בדף השיחה',
+'otherlanguages' => 'שפות אחרות',
+'redirectedfrom' => '(הופנה מהדף $1)',
+'redirectpagesub' => 'דף הפניה',
+'lastmodifiedat' => 'שונה לאחרונה ב־$2, $1.', # $1 date, $2 time
+'viewcount' => 'דף זה נצפה {{plural:$1|פעם אחת|$1 פעמים|פעמיים}}.',
+'copyright' => 'התוכן מוגש בכפוף ל־$1.<br /> בעלי זכויות היוצרים מפורטים בהיסטוריית השינויים של הדף.',
+'protectedpage' => 'דף מוגן',
+'jumpto' => 'קפיצה אל:',
+'jumptonavigation' => 'ניווט',
+'jumptosearch' => 'חיפוש',
+
+'badaccess' => 'שגיאה בהרשאות',
+'badaccess-group0' => 'אינכם מורשים לבצע את הפעולה שביקשתם.',
+'badaccess-group1' => 'הפעולה שביקשתם לבצע מוגבלת למשתמשים בקבוצה $1.',
+'badaccess-group2' => 'הפעולה שביקשתם לבצע מוגבלת למשתמשים באחת הקבוצות $1.',
+'badaccess-groups' => 'הפעולה שביקשתם לבצע מוגבלת למשתמשים באחת הקבוצות $1.',
+
+'versionrequired' => 'נדרשת גרסה $1 של מדיה־ויקי',
+'versionrequiredtext' => 'גרסה $1 של מדיה־ויקי נדרשת לשימוש בדף זה.
+
+למידע נוסף, ראו [[{{ns:special}}:Version]].',
+
+'ok' => 'אישור',
+'pagetitle' => '$1 – {{SITENAME}}',
+'retrievedfrom' => '<br /><span style="font-size: smaller;">מקור: $1</span>',
+'youhavenewmessages' => 'יש לכם $1 ($2).',
+'newmessageslink' => 'הודעות חדשות',
+'newmessagesdifflink' => 'שינוי אחרון',
+'editsection' => 'עריכה',
+'editold' => 'עריכה',
+'editsectionhint' => 'עריכת פסקה: $1',
+'toc' => 'תוכן עניינים',
+'showtoc' => 'הראה',
+'hidetoc' => 'הסתר',
+'thisisdeleted' => 'הציגו או שחזרו $1?',
+'viewdeleted' => 'הציגו $1?',
+'restorelink' => '{{plural:$1|גרסה מחוקה אחת|$1 גרסאות מחוקות}}',
+'feedlinks' => 'הזנה:',
+'feed-invalid' => 'סוג הזנת המנוי שגוי.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'דף תוכן',
+'nstab-user' => 'דף משתמש',
+'nstab-media' => 'מדיה',
+'nstab-special' => 'מיוחד',
+'nstab-project' => 'דף מיזם',
+'nstab-image' => 'תמונה',
+'nstab-mediawiki' => 'הודעה',
+'nstab-template' => 'תבנית',
+'nstab-help' => 'דף עזרה',
+'nstab-category' => 'קטגוריה',
+
+# Main script and global functions
+'nosuchaction' => 'אין פעולה כזו',
+'nosuchactiontext' => 'מערכת מדיה־ויקי אינה מכירה את הפעולה המצויינת בכתובת ה־URL של הדף.',
+'nosuchspecialpage' => 'אין דף מיוחד בשם זה',
+'nospecialpagetext' => 'ביקשת דף מיוחד שאינו מוכר למערכת מדיה־ויקי.',
+
+# General errors
+'error' => 'שגיאה',
+'databaseerror' => 'שגיאת בסיס־נתונים',
+'dberrortext' => '<p><b>ארעה שגיאת תחביר בשאילתה לבסיס הנתונים</b>.</p>
+<p>שגיאה זו יכולה להיות תוצאה של שאילתת חיפוש בלתי חוקית, או שהיא עלולה להעיד על באג במערכת מדיה־ויקי.</p>
+<table class="toccolours"
+<tr>
+<th colspan="2" style="background-color: #F8F8F8; text-align: center;">מידע על השגיאה</th>
+</tr>
+<tr>
+<td>השאילתה האחרונה שבוצעה לבסיס הנתונים היתה:</td>
+<td style="direction: ltr;">$1</td>
+</tr>
+<tr>
+<td>הפונקציה הקוראת היתה:</td>
+<td style="direction: ltr;">$2</td>
+</tr>
+<tr>
+<td>הודעת השגיאה שהוחזרה על־ידי בסיס הנתונים:</td>
+<td style="direction: ltr;">$3: $4</td>
+</tr>
+</table>',
+'dberrortextcl' => '<p><b>ארעה שגיאת תחביר בשאילתה לבסיס הנתונים</b>.</p>
+<table class="toccolours"
+<tr>
+<th colspan="2" style="background-color: #F8F8F8; text-align: center;">מידע על השגיאה</th>
+</tr>
+<tr>
+<td>השאילתה האחרונה שבוצעה לבסיס הנתונים היתה:</td>
+<td style="direction: ltr;">$1</td>
+</tr>
+<tr>
+<td>הפונקציה הקוראת היתה:</td>
+<td style="direction: ltr;">$2</td>
+</tr>
+<tr>
+<td>הודעת השגיאה שהוחזרה על־ידי בסיס הנתונים:</td>
+<td style="direction: ltr;">$3: $4</td>
+</tr>
+</table>',
+'noconnect' => 'ניסיון ההתחברות לבסיס הנתונים על $1 לא הצליח',
+'nodb' => 'לא ניתן לבחור את בסיס הנתונים $1',
+'cachederror' => 'להלן מוצג עותק גיבוי (Cache), שכנראה איננו עדכני, של הדף המבוקש.',
+'laggedslavemode' => 'אזהרה: הדף עשוי שלא להכיל עדכונים אחרונים.',
+'readonly' => 'בסיס הנתונים נעול',
+'enterlockreason' => 'הזינו סיבה לנעילת בסיס הנתונים, כולל הערכה לגבי מועד שחרור הנעילה.',
+'readonlytext' => 'בסיס נתונים זה של האתר נעול ברגע זה לצורך הזנת נתונים ושינויים. ככל הנראה מדובר בתחזוקה שוטפת, שלאחריה יחזור האתר לפעולתו הרגילה.
+
+המפתח שנעל את בסיס הנתונים סיפק את ההסבר הבא: $1',
+'missingarticle' => 'בסיס הנתונים לא מצא את הטקסט של הדף שהוא היה אמור למצוא, בשם "$1".
+
+הדבר נגרם בדרך כלל באמצעות קישור ישן להשוואת גרסאות או גרסה קודמת של דף שנמחק.
+
+אם זה אינו המקרה, כנראה שמצאת באג בתוכנה.
+
+אנא דווח על כך למפתח תוך שמירת פרטי כתובת ה־URL.',
+'readonly_lag' => 'בסיס הנתונים ננעל אוטומטית כדי לאפשר לבסיסי הנתונים המשניים להתעדכן מהבסיס הראשי.',
+'internalerror' => 'שגיאה פנימית',
+'filecopyerror' => 'העתקת "$1" ל־"$2" לא הצליחה.',
+'filerenameerror' => 'שינוי השם של "$1" ל-"$2" לא הצליח.',
+'filedeleteerror' => 'מחיקת "$1" לא הצליחה.',
+'filenotfound' => 'הקובץ "$1" לא נמצא.',
+'unexpected' => 'ערך לא צפוי: "$1"="$2"',
+'formerror' => 'שגיאה: לא יכול לשלוח טופס.',
+'badarticleerror' => 'לא ניתן לבצע פעולה זו בדף זה.',
+'cannotdelete' => 'מחיקת הדף או התמונה לא הצליחה. (יתכן שהוא נמחק כבר על־ידי מישהו אחר.)',
+'badtitle' => 'כותרת שגויה',
+'badtitletext' => 'כותרת הדף המבוקש הייתה לא־חוקית, ריקה, קישור ויקי פנימי, או פנים שפה שגוי.',
+'perfdisabled' => 'שירות זה הופסק זמנית בכדי לא לפגוע בביצועי המערכת. עמכם הסליחה!',
+'perfdisabledsub' => 'מוצג להלן עותק שמור של דף מ־$1:', # obsolete?
+'perfcached' => 'המידע הבא הוא עותק שמור של המידע, ועשוי שלא להיות מעודכן.',
+'perfcachedts' => 'המידע הבא הוא עותק שמור של המידע, שעודכן לאחרונה ב־$1.',
+'querypage-no-updates' => 'העדכונים לדף זה כרגע מופסקים, והמידע לא יעודכן באופן שוטף.',
+'wrong_wfQuery_params' => 'הפרמטרים שהוזנו ל־wfQuery() אינם נכונים:<br />
+פונקציה: $1<br />
+שאילתה: $2',
+'viewsource' => 'הצגת מקור',
+'viewsourcefor' => 'לדף $1',
+'protectedpagetext' => "דף זה הינו '''דף מוגן''' ולא ניתן לערוך אותו.",
+'viewsourcetext' => 'באפשרותכם לצפות בטקסט המקור של הדף, ואף להעתיקו:',
+'protectedinterface' => 'דף זה הוא אחד מסדרת דפים המספקים הודעות מערכת לתוכנה, ונעול לעריכה למפעילי מערכת בלבד כדי למנוע השחתות של ההודעות.',
+'editinginterface' => "'''אזהרה:''' דף זה הוא אחד מסדרת דפים המספקים הודעות מערכת לתוכנה. שינויים בדף זה ישנו את הודעת המערכת לכל המשתמשים האחרים.",
+'sqlhidden' => '(שאילתת ה־SQL מוסתרת)',
+
+# Login and logout pages
+'logouttitle' => 'יציאה מהחשבון',
+'logouttext' => 'יצאתם זה עתה מהחשבון. באפשרותכם להמשיך ולעשות שימוש ב{{grammar:תחילית|{{SITENAME}}}} באופן אנונימי, או לשוב ולהיכנס לאתר עם שם משתמש זהה או אחר.',
+'welcomecreation' => '== ברוך הבא, $1! ==
+חשבונך נפתח. אל תשכח להתאים את הגדרות המשתמש שלך.',
+'loginpagetitle' => 'כניסת משתמש',
+'yourname' => 'שם משתמש',
+'yourpassword' => 'סיסמה',
+'yourpasswordagain' => 'הקש סיסמה שנית',
+'remembermypassword' => 'זכור את הכניסה במחשב זה',
+'yourdomainname' => 'התחום שלך',
+'externaldberror' => 'הייתה שגיאת הזדהות חיצונית לבסיס הנתונים, או שאינך רשאי לעדכן את חשבונך החיצוני.',
+'loginproblem' => "'''אירעה שגיאה בכניסה לאתר.'''<br />נסה שנית!",
+'alreadyloggedin' => "'''$1, כבר ביצעת כניסה לאתר!'''<br />",
+'login' => 'כניסה לחשבון',
+'loginprompt' => 'לפני הכניסה לחשבון ב{{grammar:תחילית|{{SITENAME}}}}, עליכם לוודא כי ה"עוגיות" (Cookies) מופעלות.',
+'userlogin' => 'כניסה / הרשמה לחשבון',
+'logout' => 'יציאה מהחשבון',
+'userlogout' => 'יציאה מהחשבון',
+'notloggedin' => 'לא בחשבון',
+'nologin' => 'אין לכם חשבון? $1.',
+'nologinlink' => 'אתם מוזמנים להרשם',
+'createaccount' => 'צור משתמש חדש',
+'gotaccount' => 'כבר נרשמתם? $1.',
+'gotaccountlink' => 'הכנסו לחשבון',
+'createaccountmail' => 'באמצעות דוא"ל',
+'badretype' => 'הסיסמאות שהזנת אינן מתאימות.',
+'userexists' => 'שם המשתמש שבחרתם נמצא בשימוש. אנא בחרו שם אחר.',
+'youremail' => 'דואר אלקטרוני *:',
+'username' => 'שם משתמש:',
+'uid' => 'מספר סידורי:',
+'yourrealname' => 'שם אמיתי *:',
+'yourlanguage' => 'שפת הממשק:',
+'yourvariant' => 'שינוי',
+'yournick' => 'כינוי (לחתימות):',
+'badsig' => 'חתימה מסוגננת שגויה; אנא בדקו את תגיות ה־HTML.',
+'email' => 'דוא"ל',
+'prefs-help-email-enotif' => 'כתובת זו משמשת גם למשלוח עדכונים דרך הדוא"ל (אם אפשרתם זאת).',
+'prefs-help-realname' => '* שם אמיתי (אופציונאלי): אם תבחרו לספק שם זה, הוא ישמש לייחוס עבודתכם אליכם.',
+'loginerror' => 'שגיאה בכניסה לאתר',
+'prefs-help-email' => '* דואר אלקטרוני (אופציונאלי): אפשרו לאחרים לשלוח לכם מסר דרך דף המשתמש שלכם ללא צורך לחשוף את כתובתכם.',
+'nocookiesnew' => 'נוצר חשבון המשתמש שלכם, אך לא נכנסתם כמשתמשים רשומים למערכת כיוון שניטרלתם את העוגיות, ש{{grammar:תחילית|{{SITENAME}}}} משתמש בהן לצורך כניסה למערכת. אנא הפעילו אותן מחדש, ולאחר מכן תוכלו להיכנס למערכת עם שם המשתמש והסיסמה החדשים שלכם.',
+'nocookieslogin' => 'לא הצלחתם להיכנס למערכת כמשתמשים רשומים כיוון שניטרלתם את העוגיות, ש{{grammar:תחילית|{{SITENAME}}}} משתמש בהן לצורך כניסה למערכת. אנא הפעילו אותן מחדש, ולאחר מכן תוכלו להיכנס למערכת עם שם המשתמש והסיסמה שלכם.',
+'noname' => 'לא הזנתם שם משתמש חוקי',
+'loginsuccesstitle' => 'הכניסה הושלמה בהצלחה',
+'loginsuccess' => '\'\'\'נכנסתם ל{{grammar:תחילית|{{SITENAME}}}} בשם "$1".\'\'\'',
+'nosuchuser' => 'אין משתמש בשם "$1".
+
+אנא ודאו שהאיות נכון, או השתמשו בטופס שלהלן ליצירת חשבון משתמש חדש.',
+'nosuchusershort' => 'אין משתמש בשם "$1". אנא ודאו שהאיות נכון.',
+'nouserspecified' => 'עליכם לציין שם משתמש.',
+'wrongpassword' => 'הסיסמה שהקלדתם שגויה, אנא נסו שנית.',
+'wrongpasswordempty' => 'הסיסמה שהקלדתם ריקה. אנא נסו שנית.',
+'mailmypassword' => 'שלחו לי סיסמה חדשה',
+'passwordremindertitle' => 'תזכורת סיסמה מ{{grammar:תחילית|{{SITENAME}}}}',
+'passwordremindertext' => 'מישהו (ככל הנראה אתם, מכתובת ה־IP מספר $1) ביקש שנשלח לכם סיסמה חדשה לכניסה לחשבון ב{{grammar:תחילית|{{SITENAME}}}} ($4). הסיסמה עבור המשתמש "$2" היא עתה "$3". עליכם להיכנס לאתר ולשנות את סיסמתכם בהקדם האפשרי. אם מישהו אחר ביקש סיסמה חדשה זו או אם נזכרתם בסיסמתכם ואינכם רוצים עוד לשנות אותה, באפשרותכם להתעלם מהודעה זו ולהמשיך להשתמש בסיסמתכם הישנה.',
+'noemail' => 'לא רשומה כתובת דואר אלקטרוני עבור משתמש "$1".',
+'passwordsent' => 'סיסמה חדשה נשלחה לכתובת הדואר האלקטרוני הרשומה עבור "$1".
+אנא הכנסו חזרה לאתר אחרי שתקבלו אותה.',
+'blocked-mailpassword' => 'כתובת ה־IP שלכם חסומה מעריכה, ולפיכך אינכם מורשים להשתמש באפשרות שיחזור הסיסמה כדי למנוע ניצול לרעה של התכונה.',
+'eauthentsent' => 'דוא"ל אישור נשלח לכתובת הדוא"ל שקבעת. לפני שדברי דוא"ל אחרים נשלחים לחשבון הזה, תצטרך לפעול לפי ההוראות בדוא"ל כדי לוודא שהדוא"ל הוא אכן שלך.',
+'throttled-mailpassword' => 'כבר נעשה שימוש באפשרות שיחזור הסיסמה ב־$1 השעות האחרונות. כדי למנוע ניצול לרעה, רק דואר אחד כזה יכול להישלח כל $1 שעות.',
+'mailerror' => 'שגיאה בשליחת דואר: $1',
+'acct_creation_throttle_hit' => 'מצטערים, יצרת כבר $1 חשבונות. אינך יכול ליצור חשבונות נוספים.',
+'emailauthenticated' => 'כתובת הדוא"ל שלך אושרה על־ידי $1.',
+'emailnotauthenticated' => 'כתובת הדוא"ל שלך עדיין לא אושרה. אף דוא"ל לא יישלח מאף אחת מהתכונות הבאות.',
+'noemailprefs' => 'אנא ציינו כתובת דוא"ל כדי שתכונות אלה יעבדו.',
+'emailconfirmlink' => 'אשר את כתובת הדוא"ל שלך',
+'invalidemailaddress' => 'כתובת הדוא"ל אינה מתקבלת כיוון שנראה שהיא בפורמט לא נכון. אנא הכנס כתובת נכונה או ותר על השדה הזה.',
+'accountcreated' => 'החשבון נוצר',
+'accountcreatedtext' => 'חשבון המשתמש $1 נוצר.',
+
+# Password reset dialog
+'resetpass' => 'איפוס סיסמת החשבון',
+'resetpass_announce' => 'נכנסתם באמצעות סיסמה זמנית שנשלחה אליכם בדוא"ל. כדי לסיים את הכניסה, עליכם לקבוע כאן סיסמה חדשה:',
+'resetpass_text' => '<!-- הוסיפו טקסט כאן -->',
+'resetpass_header' => 'איפוס הסיסמה',
+'resetpass_submit' => 'הגדרת הסיסמה וכניסה',
+'resetpass_success' => 'סיסמתכם שונתה בהצלחה! מכניס אתכם למערכת…',
+'resetpass_bad_temporary' => 'סיסמה זמנית שגויה. ייתכן שכבר שיניתם בהצלחה את סיסמתכם; אם לא, אנא בקשו סיסמה זמנית חדשה.',
+'resetpass_forbidden' => 'לא ניתן לשנות סיסמאות באתר זה.',
+'resetpass_missing' => 'חסר מידע בטופס.',
+
+# Edit page toolbar
+'bold_sample' => 'טקסט מודגש',
+'bold_tip' => 'טקסט מודגש',
+'italic_sample' => 'טקסט נטוי',
+'italic_tip' => 'טקסט נטוי (לא מומלץ בעברית)',
+'link_sample' => 'קישור',
+'link_tip' => 'קישור פנימי',
+'extlink_sample' => 'http://www.example.com כותרת הקישור לתצוגה',
+'extlink_tip' => 'קישור חיצוני (כולל קידומת http מלאה)',
+'headline_sample' => 'כותרת',
+'headline_tip' => 'כותרת – דרגה 2',
+'math_sample' => 'formula',
+'math_tip' => 'נוסחה מתמטית (LaTeX)',
+'nowiki_sample' => 'טקסט לא מעוצב',
+'nowiki_tip' => 'טקסט לא מעוצב (התעלם מסימני ויקי)',
+'image_sample' => 'PictureFileName.jpg|left|thumb|250px|כיתוב תמונה',
+'image_tip' => 'תמונה (שכבר הועלתה לשרת)',
+'media_sample' => 'Example.ogg',
+'media_tip' => 'קישור לקובץ מדיה',
+'sig_tip' => 'חתימה + שעה',
+'hr_tip' => 'קו אופקי (השתדלו להמנע משימוש בקו)',
+
+# Edit pages
+'summary' => 'תקציר',
+'subject' => 'נושא/כותרת',
+'minoredit' => 'זהו שינוי משני',
+'watchthis' => 'מעקב אחרי דף זה',
+'savearticle' => 'שמור דף',
+'preview' => 'תצוגה מקדימה',
+'showpreview' => 'תצוגה מקדימה',
+'showlivepreview' => 'תצוגה מקדימה חיה',
+'showdiff' => 'הצג שינויים',
+'anoneditwarning' => "'''אזהרה:''' אינכם מחוברים לחשבון. כתובת ה־IP שלכם תירשם בהיסטוריית העריכות של הדף. אם לדעתכם זוהי פגיעה בפרטיותכם, עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]].",
+'missingsummary' => '\'\'\'תזכורת:\'\'\' לא הזנתם תקציר עריכה. אם תלחצו שוב על "שמור דף", עריכתכם תישמר בלעדיו.',
+'missingcommenttext' => 'אנא הקלידו את ההערה למטה.',
+'missingcommentheader' => '\'\'\'תזכורת:\'\'\' לא הזנתם נושא/כותרת להערה זו. אם תלחצו שוב על "שמור דף", עריכתכם תישמר בלעדיו.',
+'summary-preview' => 'תצוגה מקדימה של התקציר',
+'subject-preview' => 'תצוגה מקדימה של הנושא/הכותרת',
+'blockedtitle' => 'המשתמש חסום',
+'blockedtext' => '<big>\'\'\'שם המשתמש או כתובת ה־IP שלכם נחסמו.\'\'\'</big>
+
+החסימה בוצעה על־ידי $1. הסיבה שניתנה לכך היא \'\'\'$2\'\'\'.
+
+באפשרותכם ליצור קשר עם $1 או עם כל אחד מ[[{{ns:project}}:מפעיל מערכת|מפעילי המערכת]] האחרים כדי לדון על החסימה.
+אינכם יכולים להשתמש בתכונת "שלחו דואר אלקטרוני למשתמש זה" אם לא ציינתם כתובת דוא"ל תקפה ב[[{{ns:special}}:Preferences|העדפות המשתמש שלכם]].
+כתובת ה־IP שלכם היא $3, ומספר החסימה שלכם הוא #$5. אנא ציינו אחת מעובדות אלה (או את שתיהן) בכל פנייה למפעילי המערכת.',
+'blockedoriginalsource' => "טקסט המקור של '''$1''' מוצג למטה:",
+'blockededitsource' => "הטקסט של '''העריכות שלך''' לדף '''$1''' מוצג למטה:",
+'whitelistedittitle' => 'כניסה לחשבון נדרשת לעריכה',
+'whitelistedittext' => 'עליכם $1 כדי לערוך דפים.',
+'whitelistreadtitle' => 'כניסה לחשבון נדרשת לקריאה',
+'whitelistreadtext' => 'עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]] כדי לקרוא דפים.',
+'whitelistacctitle' => 'אינכם מורשים ליצור חשבון',
+'whitelistacctext' => 'עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]] שיש לו את ההרשאה ליצור חשבונות כדי ליצור חשבון.',
+'confirmedittitle' => 'הנכם חייבים לאמת את כתובת הדוא"ל שלכם כדי לערוך',
+'confirmedittext' => 'עליכם לאמת את כתובת הדוא"ל שלכם לפני שתוכלו לערוך דפים. אנא הגדירו ואמתו את כתובת הדוא"ל שלכם באמצעות [[{{ns:special}}:Preferences|העדפות המשתמש]] לשכם.',
+'loginreqtitle' => 'כניסה לחשבון נדרשת',
+'loginreqlink' => 'להיכנס לחשבון',
+'loginreqpagetext' => 'עליכם $1 כדי לצפות בדפים אחרים.',
+'accmailtitle' => 'הסיסמה נשלחה',
+'accmailtext' => 'הסיסמה עבור "$1" נשלחה אל $2.',
+'newarticle' => '(חדש)',
+'newarticletext' => "הגעתם לדף שעדיין איננו קיים. כדי ליצור דף חדש, כתבו את התוכן שלכם בתיבת הטקסט למטה.
+
+אם הגעתם לכאן בטעות, פשוט לחצו על מקש ה־'''Back''' בדפדפן שלכם.",
+'anontalkpagetext' => "----
+'''זהו דף שיחה של משתמש אנונימי שעדיין לא יצר חשבון במערכת, או שהוא לא משתמש בו. כיוון שכך, אנו צריכים להשתמש בכתובת ה־IP כדי לזהותו. ייתכן שכתובת IP זו תייצג מספר משתמשים. אם אתם משתמשים אנונימיים ומרגישים שקיבלתם הודעות בלתי רלוונטיות, אנא [[{{ns:special}}:Userlogin|צרו חשבון או הכנסו]] כדי להימנע מבלבול עתידי עם משתמשים אנונימיים נוספים.'''
+----",
+'noarticletext' => 'אין עדיין טקסט בדף זה. באפשרותכם [[{{ns:special}}:Search/{{PAGENAME}}|לחפש את {{PAGENAME}} באתר]], או [{{fullurl:{{FULLPAGENAME}}|action=edit}} ליצור דף זה].',
+'clearyourcache' => "'''הערה:''' לאחר השמירה, עליכם לנקות את זכרון המטמון (Cache) של הדפדפן על־מנת להבחין בשינויים.
+* ב'''מוזילה''', '''פיירפוקס''' או '''ספארי''', לחצו על מקש ה־Shift בעת לחיצתכם על '''העלה מחדש''' (Reload), או הקישו Ctrl+Shift+R (או Cmd+Shift+R במקינטוש של אפל).
+* ב'''אינטרנט אקספלורר''', לחצו על מקש ה־Ctrl בעת לחיצתכם על '''רענן''' (Refresh), או הקישו על Ctrl+F5.
+* ב־'''Konqueror''', פשוט לחצו על '''העלה מחדש''' (Reload), או הקישו על F5.
+* ב'''אופרה''', ייתכן שתצטרכו להשתמש ב'''כלים''' (Tools) > '''העדפות''' (Preferences) כדי לנקות לחלוטין את זכרון המטמון.",
+'usercssjsyoucanpreview' => '\'\'\'עצה:\'\'\' השתמשו בלחצן "תצוגה מקדימה" כדי לבחון את גליון ה־CSS או את סקריפט ה־JavaScript החדש שלכם לפני השמירה.',
+'usercsspreview' => "'''זכרו שזו רק תצוגה מקדימה של גליון ה־CSS שלכם, ושהוא טרם נשמר!'''",
+'userjspreview' => "'''זכרו שזו רק תצוגה מקדימה של סקריפט ה־JavaScript שלכם, ושהוא טרם נשמר!'''",
+'userinvalidcssjstitle' => '\'\'\'אזהרה\'\'\': הרקע "$1" אינו קיים. זכרו שדפי CSS ו־JavaScript מותאמים אישית משתמשים בכותרת עם אותיות קטנות – למשל, {{ns:user}}:דוגמה/monobook.css ולא {{ns:user}}:דוגמה/Monobook.css. כמו כן, יש להקפיד על שימוש ב־/ ולא ב־\.',
+'updated' => '(מעודכן)',
+'note' => "'''הערה:'''",
+'previewnote' => 'זכרו שזו רק תצוגה מקדימה, והדף עדיין לא נשמר!',
+'previewconflict' => 'תצוגה מקדימה זו מציגה כיצד ייראה הטקסט בחלון העריכה העליון, אם תבחרו לשמור אותו.',
+'session_fail_preview' => "'''מצטערים! לא ניתן לבצע את עריכתכם עקב אובדן קשר עם השרת. אנא נסו שנית. אם זה לא עוזר, אנא צאו מהחשבון ונסו שנית.",
+'session_fail_preview_html' => "'''מצטערים! לא ניתן לבצע את עריכתם עקב אובדן קשר עם השרת.'''
+
+כיוון שבאתר זה אפשרות השימוש ב־HTML מאופשרת, התצוגה המקדימה מוסתרת כדי למנוע התקפות JavaScript.
+
+'''אם זהו ניסיון עריכה לגיטימי, אנא נסו שנית. אם זה לא עוזר, נסו לצאת מהחשבון ולהיכנס אליו שנית.'''",
+'importing' => 'מייבא את $1',
+'editing' => 'עורך את $1',
+'editinguser' => 'עורך את המשתמש <b>$1</b>',
+'editingsection' => 'עורך את $1 (פסקה)',
+'editingcomment' => 'עורך את $1 (הערה)',
+'editconflict' => 'התנגשות עריכה: $1',
+'explainconflict' => "משתמש אחר שינה את הדף מאז שהתחלתם לערוך אותו.
+
+חלון העריכה העליון מכיל את הטקסט בדף כפי שהוא עתה.
+
+השינויים שלכם מוצגים בחלון העריכה התחתון.
+
+עליכם למזג את השינויים שלכם לתוך הטקסט הקיים.
+
+'''רק''' הטקסט בחלון העריכה העליון ישמר כשתשמרו את הדף.",
+'yourtext' => 'הטקסט שלך',
+'storedversion' => 'גרסה שמורה',
+'nonunicodebrowser' => "'''אזהרה: הדפדפן שלך אינו תואם לתקן יוניקוד. בשל כך הוכנס לפעולה מעקף של הבאג, כדי לאפשר לך לערוך דפים בבטחה: תווים שאינם ב־ASCII יוצגו בתיבת העריכה כקודים הקסדצימליים.",
+'editingold' => "'''זהירות: אתם עורכים גרסה לא עדכנית של דף זה.
+
+אם תשמרו את הדף, כל השינויים שנעשו מאז גרסה זו יאבדו.'''",
+'yourdiff' => 'הבדלים',
+'copyrightwarning' => '<div id="editing-warn">\'\'\'שימו לב:\'\'\' תרומתכם ל{{grammar:תחילית|{{SITENAME}}}} תפורסם תחת תנאי הרישיון $2 (ראו $1 לפרטים נוספים). אם אינכם רוצים שעבודתכם תהיה זמינה לעריכה על־ידי אחרים, שתופץ לעיני כל, ושאחרים יוכלו להעתיק ממנה בציון המקור – אל תפרסמו אותה פה. כמו־כן, אתם מבטיחים לנו כי כתבתם את הטקסט הזה בעצמכם, או העתקתם אותו ממקור שאינו מוגן על־ידי זכויות יוצרים. \'\'\'אל תעשו שימוש בחומר המוגן בזכויות יוצרים ללא רשות!\'\'\'</div>',
+'copyrightwarning2' => '<div id="editing-warn">\'\'\'שימו לב:\'\'\' תורמים אחרים עשויים לערוך או אף להסיר את תרומתכם ל{{grammar:תחילית|{{SITENAME}}}}. אם אינכם רוצים שעבודתכם תהיה זמינה לעריכה על־ידי אחרים – אל תפרסמו אותה פה. כמו־כן, אתם מבטיחים לנו כי כתבתם את הטקסט הזה בעצמכם, או העתקתם אותו ממקור שאינו מוגן על־ידי זכויות יוצרים (ראו $1 לפרטים נוספים). \'\'\'אל תעשו שימוש בחומר המוגן בזכויות יוצרים ללא רשות!\'\'\'</div>',
+'longpagewarning' => "'''אזהרה: גודל דף זה הוא $1 קילובייטים. בדפדפנים מסוימים יהיו בעיות בעריכת דף הגדול מ־32 קילובייטים. אנא שיקלו לחלק דף זה לדפים קטנים יותר. אם זהו דף שיחה, שיקלו לארכב אותו.'''",
+'longpageerror' => "'''שגיאה: הטקסט ששלחתם הוא באורך $1 קילובייטים, אך אסור לו להיות ארוך יותר מהמקסימום של $2 קילובייטים. לא ניתן לשומרו.'''",
+'readonlywarning' => "'''אזהרה: בסיס הנתונים ננעל לצורך תחזוקה. בזמן זה אי אפשר לשמור את הטקסט הערוך. בינתיים, עד סיום התחזוקה, אתם יכולים להשתמש בעורך חיצוני. אנו מתנצלים על התקלה.'''",
+'protectedpagewarning' => "'''אזהרה: דף זה הוא דף מוגן וניתן לעריכה על־ידי מפעילי מערכת בלבד. אנא ודאו שאתם פועלים על־פי העקרונות לעריכת דפים אלו.'''",
+'semiprotectedpagewarning' => "'''הערה:''' דף זה ננעל כך שרק משתמשים רשומים יכולים לערוך אותו.",
+'templatesused' => 'תבניות המופיעות בדף זה:',
+'templatesusedpreview' => 'תבניות המופיעות בתצוגה המקדימה הזו:',
+'templatesusedsection' => 'תבניות המופיעות בפיסקה זו:',
+'template-protected' => '(מוגנת)',
+'template-semiprotected' => '(מוגנת חלקית)',
+'edittools' => '<!-- הטקסט הנכתב כאן יוצג מתחת לטפסי עריכת דפים והעלאת קבצים, ולפיכך ניתן לכתוב להציג בו תווים קשים לכתיבה, קטעים מוכנים של טקסט ועוד. -->',
+'nocreatetitle' => 'יצירת הדפים הוגבלה',
+'nocreatetext' => 'אתר זה מגביל את האפשרות ליצור דפים חדשים. באפשרותכם לחזור אחורה ולערוך דף קיים, או [[{{ns:special}}:Userlogin|להיכנס לחשבון]].',
+
+# "Undo" feature
+'undo-success' => 'ניתן לבטל את העריכה. אנא בידקו את השוואת הגרסאות למטה כדי לוודא שזה מה שאתם רוצים לעשות, ואז שמרו את השינויים למטה כדי לבצע את ביטול העריכה.',
+'undo-failure' => 'לא ניתן היה לבטל את העריכה עקב התנגשות עם עריכות מאוחרות יותר.',
+'undo-summary' => 'ביטול גרסה $1 על־ידי [[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|שיחה]])',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'לא ניתן ליצור את החשבון',
+'cantcreateaccounttext' => 'אפשרות יצירת החשבונות מכתובת ה־IP הזו (<b>$1</b>) נחסמה, כנראה עקב השחתות מתמשכות מבית־הספר או ספק האינטרנט שלך.',
+
+# History pages
+'revhistory' => 'היסטוריית שינויים',
+'viewpagelogs' => 'הצג יומנים עבור דף זה',
+'nohistory' => 'אין היסטוריית שינויים עבור דף זה.',
+'revnotfound' => 'גרסה זו לא נמצאה',
+'revnotfoundtext' => 'הגרסה הישנה של דף זה לא נמצאה. אנא בדקו את כתובת הקישור שהוביל אתכם הנה.',
+'loadhist' => 'טוען את היסטוריית השינויים של הדף',
+'currentrev' => 'גרסה נוכחית',
+'revisionasof' => 'גרסה מתאריך $1',
+'revision-info' => 'גרסה מתאריך $1 מאת $2',
+'previousrevision' => '→ הגרסה הקודמת',
+'nextrevision' => 'הגרסה הבאה ←',
+'currentrevisionlink' => 'הגרסה הנוכחית',
+'cur' => 'נוכ',
+'next' => 'הבא',
+'last' => 'אחרון',
+'orig' => 'מקור',
+'histlegend' => 'השוואת גרסאות: סמנו את תיבות האפשרויות של הגרסאות המיועדות להשוואה, והקישו על Enter או על הכפתור שלמעלה או למטה.<br />
+מקרא: (נוכ) = הבדלים עם הגרסה הנוכחית, (אחרון) = הבדלים עם הגרסה הקודמת, מ = שינוי משני',
+'deletedrev' => '[נמחק]',
+'histfirst' => 'ראשונות',
+'histlast' => 'אחרונות',
+'rev-deleted-comment' => '(תקציר העריכה הוסתר)',
+'rev-deleted-user' => '(שם המשתמש הוסתר)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+גרסת הדף הזו הוסרה מהארכיונים הציבוריים. ייתכן שישנם פרטים נוספים על כך ב[{{fullurl:{{ns:special}}:Log/delete|page={{FULLPAGENAMEE}}}} יומן המחיקות].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+גרסת הדף הזו הוסרה מהארכיונים הציבוריים. כמפעיל מערכת, באפשרותך לצפות בגרסה; ייתכן שישנם פרטים נוספים על כך ב[{{fullurl:{{ns:special}}:Log/delete|page={{FULLPAGENAMEE}}}} יומן המחיקות].
+</div>',
+'rev-delundel' => 'הצג/הסתר',
+
+'history-feed-title' => 'היסטוריית גרסאות',
+'history-feed-description' => 'היסטוריית הגרסאות של הדף הזה בוויקי',
+'history-feed-item-nocomment' => '$1 ב־$2', # user at time
+'history-feed-empty' => 'הדף המבוקש לא נמצא.
+ייתכן שהוא נמחק מהוויקי, או ששמו שונה.
+נסו [[{{ns:special}}:Search|לחפש בוויקי]] אחר דפים רלוונטיים חדשים.',
+
+# Revision deletion
+'revisiondelete' => 'מחיקת ושחזור גרסאות',
+'revdelete-nooldid-title' => 'אין גרסת מטרה',
+'revdelete-nooldid-text' => 'לא ציינתם גרסת או גרסאות מטרה עליהן תבוצע פעולה זו.',
+'revdelete-selected' => 'הגרסאות שנבחרו של [[:$1]]:',
+'revdelete-text' => 'גרסאות מחוקות עדיין יופיעו בהיסטוריית הדף, אך התוכן שלהן לא יהיה זמין לציבור.
+
+מפעילי מערכת אחרים באתר עדיין יוכלו לגשת לתוכן הנסתר ויוכלו לשחזר אותו שוב דרך הממשק הזה, אלא אם כן הגבלה נוספת הוטלה על־ידי מנהלי האתר.',
+'revdelete-legend' => 'הגדרת הגבלות הגרסה:',
+'revdelete-hide-text' => 'הסתר את תוכן הגרסה',
+'revdelete-hide-comment' => 'הסתר את תקציר העריכה',
+'revdelete-hide-user' => 'הסתר את שם המשתמש או כתובת ה־IP של העורך',
+'revdelete-hide-restricted' => 'החל הגבלות אלו גם על מפעילי מערכת',
+'revdelete-log' => 'הערה ביומן:',
+'revdelete-submit' => 'החל לגרסה הנוכחית',
+'revdelete-logentry' => 'שינה הצגת גרסה לדף [[$1]]',
+
+# Diffs
+'difference' => '(הבדלים בין גרסאות)',
+'loadingrev' => 'טוען את הגרסה להשוואה',
+'lineno' => 'שורה $1:',
+'editcurrent' => 'ערוך גרסה נוכחית של הדף',
+'selectnewerversionfordiff' => 'בחר גרסה חדשה יותר להשוואה',
+'selectolderversionfordiff' => 'בחר גרסה ישנה יותר להשוואה',
+'compareselectedversions' => 'השווה את הגרסאות שנבחרו',
+'editundo' => 'ביטול',
+'diff-multi' => '({{plural:$1|גרסה אמצעית אחת לא מוצגת|$1 גרסאות אמצעיות לא מוצגות}}.)',
+
+# Search results
+'searchresults' => 'תוצאות החיפוש',
+'searchresulttext' => 'ראו גם [[{{ns:project}}:חיפוש|מידע נוסף על חיפוש ב{{grammar:תחילית|{{SITENAME}}}}]].',
+'searchsubtitle' => "לחיפוש המונח '''[[:$1]]'''",
+'searchsubtitleinvalid' => "לחיפוש המונח '''$1'''",
+'badquery' => 'שגיאה בניסוח השאילתה.',
+'badquerytext' => 'לא הצלחנו לבצע את השאילתה, ככל הנראה כיוון שניסיתם לחפש מילה בעלת פחות משלוש אותיות. חיפוש כזה עדיין אינו נתמך במערכת. ייתכן גם ששגיתם בהקלדת השאליתה – לדוגמה, כתבתם "דג וגם וגם משקל".
+
+ניתן לנסות שאילתה אחרת.',
+'matchtotals' => 'לחיפוש "$1" נמצאו $2 דפים עם כותרות תואמות ו־$3 דפים עם תוכן תואם',
+'noexactmatch' => 'אין דף שכותרתו "$1". באפשרותכם [[:$1|ליצור את הדף]].',
+'titlematches' => 'כותרות דפים תואמות',
+'notitlematches' => 'אין כותרות דפים תואמות',
+'textmatches' => 'דפים עם תוכן תואם',
+'notextmatches' => 'אין דפים עם תוכן תואם',
+'prevn' => '$1 הקודמים',
+'nextn' => '$1 הבאים',
+'viewprevnext' => 'צפו ב - ($1) ($2) ($3).',
+'showingresults' => 'מציג עד <b>$1</b> תוצאות החל ממספר #<b>$2</b>:',
+'showingresultsnum' => 'מציג <b>$3</b> תוצאות החל ממספר #<b>$2</b>:',
+'nonefound' => 'לא נמצאו דפים עם תוכן תואם. אנא ודאו שהקלדתם את שאילתת החיפוש נכון. אם אכן הקלדתם אותה נכון, נסו לחפש נושא כללי יותר.
+
+חיפושים כושלים מסוג זה נגרמים בדרך כלל בגלל ציון יותר ממילת חיפוש אחת, שכן במקרה זה מופיעים רק דפים הכוללים את כל המילים.',
+'powersearch' => 'חפש',
+'powersearchtext' => 'חפש במרחבי שם:<br />$1<br />$2 הצג גם דפי הפנייה<br />חפש $3 $9',
+'searchdisabled' => 'לצערנו, עקב עומס על המערכת, לא ניתן לחפש כעת בטקסט המלא של הדפים. באפשרותכם להשתמש בינתיים בגוגל, אך שימו לב שייתכן שהוא אינו מעודכן.',
+'blanknamespace' => '(ראשי)',
+
+# Preferences page
+'preferences' => 'העדפות',
+'mypreferences' => 'ההעדפות שלי',
+'prefsnologin' => 'לא נרשמת באתר',
+'prefsnologintext' => 'עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]] כדי לשנות העדפות משתמש.',
+'prefsreset' => 'העדפותיך שוחזרו לברירת המחדל.',
+'qbsettings' => 'הגדרות סרגל כלים',
+'changepassword' => 'שנה סיסמה',
+'skin' => 'רקע',
+'math' => 'נוסחאות מתמטיות',
+'dateformat' => 'מבנה תאריך',
+'datedefault' => 'ברירת המחדל',
+'datetime' => 'תאריך ושעה',
+'math_failure' => 'עיבוד הנוסחה נכשל',
+'math_unknown_error' => 'שגיאה לא ידועה',
+'math_unknown_function' => 'פונקציה לא מוכרת',
+'math_lexing_error' => 'שגיאת לקסינג',
+'math_syntax_error' => 'שגיאת תחביר',
+'math_image_error' => 'ההמרה ל־PNG נכשלה; אנא בדקו אם התקנתם נכון את latex, את dvips, את gs ואת convert.',
+'math_bad_tmpdir' => 'התוכנה לא הצליחה לכתוב או ליצור את הספרייה הזמנית של המתמטיקה',
+'math_bad_output' => 'התוכנה לא הצליחה לכתוב או ליצור את ספריית הפלט של המתמטיקה',
+'math_notexvc' => 'קובץ בר־ביצוע של texvc אינו זמין; אנא ראו את קובץ ה־README למידע על ההגדרות.',
+'prefs-personal' => 'פרטי המשתמש',
+'prefs-rc' => 'שינויים אחרונים',
+'prefs-watchlist' => 'רשימת המעקב',
+'prefs-watchlist-days' => 'מספר הימים לתצוגה ברשימת המעקב:',
+'prefs-watchlist-edits' => 'מספר העריכות לתצוגה ברשימת המעקב המורחבת:',
+'prefs-misc' => 'שונות',
+'saveprefs' => 'שמור העדפות',
+'resetprefs' => 'שחזר ברירת מחדל',
+'oldpassword' => 'סיסמה ישנה',
+'newpassword' => 'סיסמה חדשה',
+'retypenew' => 'הקלד סיסמה חדשה שנית',
+'textboxsize' => 'עריכה',
+'rows' => 'שורות',
+'columns' => 'עמודות',
+'searchresultshead' => 'חיפוש',
+'resultsperpage' => 'מספר תוצאות בעמוד',
+'contextlines' => 'שורות לכל תוצאה',
+'contextchars' => 'מספר תווי קונטקסט בשורה',
+'stubthreshold' => 'סף להצגת דפים קצרים (קצרמרים)',
+'recentchangescount' => 'מספר שינויים שיוצגו בדף שינויים אחרונים',
+'savedprefs' => 'העדפותיך נשמרו.',
+'timezonelegend' => 'אזור זמן',
+'timezonetext' => 'הפרש השעות בינך לבין השרת (UTC).',
+'localtime' => 'זמן מקומי',
+'timezoneoffset' => 'הפרש',
+'servertime' => 'השעה הנוכחית בשרת היא',
+'guesstimezone' => 'קבל מהדפדפן',
+'allowemail' => 'אפשר קבלת דוא"ל ממשתמשים אחרים',
+'defaultns' => 'כברירת מחדל, חפש במרחבי השם אלו:',
+'default' => 'ברירת מחדל',
+'files' => 'קבצים',
+
+# User rights
+'userrights-lookup-user' => 'נהלו קבוצות משתמש',
+'userrights-user-editname' => 'הכניסו שם משתמש:',
+'editusergroup' => 'ערכו קבוצות משתמשים',
+'userrights-editusergroup' => 'ערכו קבוצות משתמש',
+'saveusergroups' => 'שמור קבוצות משתמש',
+'userrights-groupsmember' => 'חבר בקבוצות:',
+'userrights-groupsavailable' => 'קבוצות זמינות:',
+'userrights-groupshelp' => 'אנא בחרו קבוצות שברצונכם שהמשתמש יתווסף אליהן או יוסר מהן.
+קבוצות שלא נבחרו לא ישתנו. באפשרותכם לבטל בחירה של קבוצה באמצעות לחיצה על הכפתור השמאלי של העכבר ועל Ctrl מעליה.',
+
+# Groups
+'group' => 'קבוצה:',
+'group-bot' => 'בוטים',
+'group-sysop' => 'מפעילי מערכת',
+'group-bureaucrat' => 'ביורוקרטים',
+'group-all' => '(הכול)',
+
+'group-bot-member' => 'בוט',
+'group-sysop-member' => 'מפעיל מערכת',
+'group-bureaucrat-member' => 'ביורוקרט',
+
+'grouppage-bot' => '{{ns:project}}:בוט',
+'grouppage-sysop' => '{{ns:project}}:מפעיל מערכת',
+'grouppage-bureaucrat' => '{{ns:project}}:ביורוקרט',
+
+# Recent changes
+'changes' => 'שינויים',
+'recentchanges' => 'שינויים אחרונים',
+'recentchangestext' => 'עקבו אחרי השינויים האחרונים באתר בדף זה.',
+'recentchanges-feed-description' => 'עקבו אחרי השינויים האחרונים באתר בדף זה.',
+'rcnote' => 'להלן <b>$1</b> השינויים האחרונים שבוצעו ב־$2 הימים האחרונים, עד התאריך <b>$3</b>:',
+'rcnotefrom' => 'להלן <b>$1</b> השינויים האחרונים שבוצעו החל מתאריך <b>$2</b>:',
+'rclistfrom' => 'הצג שינויים חדשים החל מ־$1',
+'rcshowhideminor' => '$1 שינויים משניים',
+'rcshowhidebots' => '$1 בוטים',
+'rcshowhideliu' => '$1 משתמשים רשומים',
+'rcshowhideanons' => '$1 משתמשים אנונימיים',
+'rcshowhidepatr' => '$1 עריכות בדוקות',
+'rcshowhidemine' => '$1 עריכות שלי',
+'rclinks' => 'הצג $1 שינויים אחרונים ב-$2 הימים האחרונים.<br /> $3',
+'diff' => 'הבדל',
+'hist' => 'היסטוריה',
+'hide' => 'הסתר',
+'show' => 'הצג',
+'minoreditletter' => 'מ',
+'newpageletter' => 'ח',
+'boteditletter' => 'ב',
+'sectionlink' => '←',
+'number_of_watching_users_pageview' => '[$1 משתמש/ים צופים]',
+'rc_categories' => 'הגבל לקטגוריות (הפרד עם "|")',
+'rc_categories_any' => 'הכול',
+
+# Upload
+'upload' => 'העלאת קובץ לשרת',
+'uploadbtn' => 'העלה קובץ',
+'reupload' => 'העלה שנית',
+'reuploaddesc' => 'חזרו לטופס העלאת קבצים לשרת.',
+'uploadnologin' => 'לא נכנסתם לאתר',
+'uploadnologintext' => 'עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]] כדי להעלות קבצים.',
+'upload_directory_read_only' => 'תיקיית ההעלאות ($1) אינה ניתנת לכתיבה על־ידי שרת האינטרנט, ולפיכך הוא אינו יכול להעלות את התמונה.',
+'uploaderror' => 'שגיאה בהעלאת הקובץ',
+'uploadtext' => "השתמשו בטופס להלן כדי להעלות תמונות. כדי לראות או לחפש תמונות שהועלו בעבר אנא פנו ל[[{{ns:special}}:Imagelist|רשימת הקבצים המועלים]], וכמו כן, העלאות מוצגות ב[[{{ns:special}}:Log/upload|יומן ההעלאות]], ומחיקות ב[[{{ns:special}}:Log/delete|יומן המחיקות]].
+
+כדי לכלול תמונה בדף, השתמשו בקישור בצורות '''<nowiki>[[{{ns:image}}:file.jpg]]</nowiki>''' לתמונות בפורמט JPG (המיועד לתצלומים), '''<nowiki>[[{{ns:image}}:file.png]]</nowiki>''' לתמונות בפורמט PNG (לאיורים, שרטוטים וסמלים). כדי לקשר ישירות לקובץ קול, השתמשו בקישור בצורה '''<nowiki>[[{{ns:media}}:file.jpg]]</nowiki>''' לקבצי קול בפורמט OGG.",
+'uploadlog' => 'יומן העלאות קבצים',
+'uploadlogpage' => 'יומן העלאות',
+'uploadlogpagetext' => 'להלן רשימה של העלאות הקבצים האחרונות שבוצעו.',
+'filename' => 'שם הקובץ',
+'filedesc' => 'תקציר',
+'fileuploadsummary' => 'תיאור:',
+'filestatus' => 'מעמד זכויות יוצרים',
+'filesource' => 'מקור',
+'copyrightpage' => '{{ns:project}}:זכויות יוצרים',
+'copyrightpagename' => 'זכויות היוצרים של {{SITENAME}}',
+'uploadedfiles' => 'קבצים שהועלו',
+'ignorewarning' => 'התעלם מהאזהרה ושמור את הקובץ בכל זאת.',
+'ignorewarnings' => 'התעלם מכל האזהרות',
+'minlength' => 'שמות של קבצי תמונה צריכים להיות בני שלושה תווים לפחות.',
+'illegalfilename' => 'הקובץ "$1" מכיל תוים בלתי חוקיים. אנא שנו את שמו ונסו להעלותו שנית.',
+'badfilename' => 'שם התמונה שונה ל־"$1".',
+'badfiletype' => '"$1" אינו פורמט מומלץ לשמירת תמונות.',
+'large-file' => 'מומלץ שהקבצים לא יהיו גדולים יותר מ־$1 (גודל הקובץ שהעליתם הוא $2).',
+'largefileserver' => 'גודל הקובץ שהעליתם חורג ממגבלת השרת.',
+'emptyfile' => 'הקובץ שהעליתם ריק. ייתכן שהסיבה לכך היא שגיאת הקלדה בשם הקובץ. אנא ודאו שזהו הקובץ שברצונך להעלות.',
+'fileexists' => 'קובץ בשם זה כבר קיים, אנא בדקו את $1 אם אינכם בטוחים שברצונכם להחליף אותו.',
+'fileexists-forbidden' => 'קובץ בשם זה כבר קיים; אנא חזרו לדף הקודם והעלו את הקובץ תחת שם חדש.
+[[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'קובץ בשם זה כבר קיים כקובץ משותף; אנא חזרו לדף הקודם והעלו את הקובץ תחת שם חדש.
+[[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'העלאת הקובץ הושלמה בהצלחה',
+'fileuploaded' => "הקובץ $1 הועלה לשרת בהצלחה.
+אנא השתמשו בקישור $2 כדי לעבור לדף תיאור הקובץ ולמלא את כל המידע אודות הקובץ, כגון מאין הגיע, מתי נוצר ועל־ידי מי, וכל פרט אחר שאתם יודעים עליו. אם זו תמונה, באפשרותכם להכלילה בדפים כך: '''<nowiki>[[{{ns:image}}:$1|thumb|Description]]</nowiki>'''",
+'uploadwarning' => 'אזהרת העלאת קבצים',
+'savefile' => 'שמור קובץ',
+'uploadedimage' => 'העלה את הקובץ "[[$1]]"',
+'uploaddisabled' => 'העלאת קבצים מנוטרלת',
+'uploaddisabledtext' => 'אפשרות העלאת הקבצים מנוטרלת באתר זה.',
+'uploadscripted' => 'הקובץ כולל קוד סקריפט או HTML שעשוי להתפרש או להתבצע בטעות על־ידי הדפדפן.',
+'uploadcorrupt' => 'קובץ זה אינו תקין או שהסיומת שלו איננה מתאימה. אנא בדקו את הקובץ והעלו אותו שוב.',
+'uploadvirus' => 'הקובץ מכיל וירוס! פרטים: <div style="direction: ltr;">$1</div>',
+'sourcefilename' => 'שם הקובץ',
+'destfilename' => 'שמור קובץ בשם',
+'watchthisupload' => 'מעקב אחרי דף זה',
+'filewasdeleted' => 'קובץ בשם זה כבר הועלה בעבר, ולאחר מכן נמחק. אנא בדקו את הדף $1 לפני שתמשיכו להעלותו שנית.',
+
+'upload-proto-error' => 'פרוטוקול שגוי',
+'upload-proto-error-text' => 'בהעלאה מרוחקת, יש להשתמש בכתובות URL המתחילות עם <code>http://</code> או <code>ftp://</code>.',
+'upload-file-error' => 'שגיאה פנימית',
+'upload-file-error-text' => 'שגיאה פנימית התרחשה בעת הניסיון ליצור קובץ זמני על השרת. אנא צרו קשר עם מנהל מערכת.',
+'upload-misc-error' => 'שגיאת העלאה בלתי ידועה',
+'upload-misc-error-text' => 'שגיאת העלאה בלתי ידועה התרחשה במהלך ההעלאה. אנא ודאו שכתובת ה־URL תקינה וזמינה ונסו שנית. אם הבעיה חוזרת על עצמה, אנא צרו קשר עם מנהל המערכת.',
+
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => 'לא ניתן להגיע ל־URL',
+'upload-curl-error6-text' => 'לא ניתן לכתובת ה־URL שנכתבה. אנא בדקו אם כתובת זו נכונה ואם האתר זמין.',
+'upload-curl-error28' => 'הסתיים זמן ההמתנה להעלאה',
+'upload-curl-error28-text' => 'לאתר לקח זמן רב מדי לענות. אנא בדקו שהאתר זמין, המתינו מעט ונסו שנית. ייתכן שתרצו לנסות בזמן פחות עמוס.',
+
+'license' => 'רישיון',
+'nolicense' => 'אין',
+'upload_source_url' => ' (כתובת URL תקפה ונגישה)',
+'upload_source_file' => ' (קובץ במחשב שלך)',
+
+# Image list
+'imagelist' => 'רשימת תמונות',
+'imagelisttext' => 'להלן רשימה של {{plural:$1|תמונה אחת|$1 תמונות}}, ממוינות $2:',
+'imagelistforuser' => 'מוצגות רק התמונות שהועלו על־ידי $1.',
+'getimagelist' => 'מושך את רשימת התמונות',
+'ilsubmit' => 'חיפוש',
+'showlast' => 'הצג $1 תמונות אחרונות ממוינות $2',
+'byname' => 'לפי שם',
+'bydate' => 'לפי תאריך',
+'bysize' => 'לפי גודל',
+'imgdelete' => 'מחק',
+'imgdesc' => 'תיאור',
+'imgfile' => 'קובץ',
+'imglegend' => 'מקרא: (תיאור) הצג/ערוך תיאור התמונה.',
+'imghistory' => 'היסטורית קובץ תמונה',
+'revertimg' => 'חזור',
+'deleteimg' => 'מחק',
+'deleteimgcompletely' => 'מחק את כל גרסאות התמונה',
+'imghistlegend' => "מקרא (נוכ) = זו התמונה הנוכחית, (מחק) = מחק גרסה ישנה זו, (חזור) חזור לגרסה ישנה זו.<br />
+'''לחצו על תאריך לראות את התמונה שהועלתה בתאריך זה'''.",
+'imagelinks' => 'קישורי תמונות',
+'linkstoimage' => 'הדפים הבאים משתמשים בתמונה זו:',
+'nolinkstoimage' => 'אין דפים המשתמשים בתמונה זו.',
+'sharedupload' => 'קובץ זה הוא קובץ משותף וניתן להשתמש בו גם באתרים אחרים.',
+'shareduploadwiki' => 'למידע נוסף, ראו את $1.',
+'shareduploadwiki-linktext' => 'דף תיאור הקובץ',
+'noimage' => 'לא נמצא קובץ בשם זה, אך יש באפשרותכם $1 חלופי.',
+'noimage-linktext' => 'להעלות קובץ',
+'uploadnewversion-linktext' => 'העלו גרסה חדשה של קובץ זה',
+'imagelist_date' => 'תאריך',
+'imagelist_name' => 'שם',
+'imagelist_user' => 'משתמש',
+'imagelist_size' => 'גודל (בתים)',
+'imagelist_description' => 'תיאור',
+'imagelist_search_for' => 'חיפוש תמונה בשם:',
+
+# MIME search
+'mimesearch' => 'חיפוש MIME',
+'mimetype' => 'סוג MIME:',
+'download' => 'הורדה',
+
+# Unwatched pages
+'unwatchedpages' => 'דפים שאינם במעקב',
+
+# List redirects
+'listredirects' => 'רשימת הפניות',
+
+# Unused templates
+'unusedtemplates' => 'תבניות שאינן בשימוש',
+'unusedtemplatestext' => 'דף זה מכיל רשימה של כל הדפים במרחב השם של התבניות שאינם נכללים בדף אחר. אנא זכרו לבדוק את הקישורים האחרים לתבניות לפני שתמחקו אותן.',
+'unusedtemplateswlh' => 'קישורים אחרים',
+
+# Random redirect
+'randomredirect' => 'הפניה אקראית',
+
+# Statistics
+'statistics' => 'סטטיסטיקות',
+'sitestats' => 'סטטיסטיקות {{SITENAME}}',
+'userstats' => 'סטטיסטיקות משתמשים',
+'sitestatstext' => "בבסיס הנתונים יש בסך הכול '''$1''' דפים. מספר זה כולל דפים שאינם דפי תוכן, כגון דפי שיחה, דפים אודות {{SITENAME}}, קצרמרים, דפי תוכן ללא קישורים פנימיים, הפניות, וכיוצא בזה. אם לא סופרים את הדפים שאינם דפי תוכן, נשארים '''$2''' דפים שהם ככל הנראה דפי תוכן לכל דבר.
+
+מאז תחילת פעולתו של האתר, היו באתר '''$3''' צפיות בדפים, ובוצעו '''$4''' פעולות עריכה.
+
+בסך הכול בוצעו בממוצע '''$5''' עריכות לדף, והיו '''$6''' צפיות לכל עריכה.
+
+אורך [http://meta.wikimedia.org/wiki/Help:Job_queue תור המשימות] הוא '''$7'''.
+
+'''$8''' קבצים הועלו לאתר עד כה.",
+'userstatstext' => "ישנם '''$1''' [[{{ns:special}}:Listusers|משתמשים רשומים]] באתר, '''$2''' (או $4%) מתוכם הם $5.",
+'statistics-mostpopular' => 'הדפים הנצפים ביותר',
+
+'disambiguations' => 'דפי פירושונים',
+'disambiguationspage' => '{{ns:template}}:פירושונים',
+'disambiguationstext' => '<p>הדפים שלהלן מקשרים אל <b>דפי פירושונים</b>. תפקיד דפים אלה הוא להפנות לדף הנושא הרלוונטי.</p>
+
+<p>אנו מתייחסים לדף כדף פירושונים אם הוא מקושר לדף $1.</p>
+
+<p>קישורים המגיעים לדף ממרחבי שם אחרים <b>אינם</b> מוצגים כאן.</p>',
+
+'doubleredirects' => 'הפניות כפולות',
+'doubleredirectstext' => '<p><b>שימו לב</b>: רשימה זו עלולה לכלול דפים שנמצאו בטעות – כלומר, דפים שיש בהם טקסט נוסף הכולל קישורים מתחת ל־#REDIRECT הראשון.</p>
+
+<p>כל שורה מכילה קישור להפניות הראשונה והשנייה, וכן את שורת הטקסט הראשונה של ההפניה השנייה, שלרוב נמצא בה היעד האמיתי של ההפניה, אליו אמורה ההפניה הראשונה להצביע.</p>',
+
+'brokenredirects' => 'הפניות לא תקינות',
+'brokenredirectstext' => 'ההפניות שלהלן מפנות לדפים שאינם קיימים:',
+
+# Miscellaneous special pages
+'nbytes' => '{{plural:$1|בית אחד|$1 בתים}}',
+'ncategories' => '{{plural:$1|קטגוריה אחת|$1 קטגוריות}}',
+'nlinks' => '{{plural:$1|קישור אחד|$1 קישורים}}',
+'nmembers' => '{{plural:$1|דף אחד|$1 דפים}}',
+'nrevisions' => '{{plural:$1|גרסה אחת|$1 גרסאות}}',
+'nviews' => '{{plural:$1|צפיה אחת|$1 צפיות}}',
+'lonelypages' => 'דפים יתומים',
+'lonelypagestext' => 'לדפים הבאים אין קישורים מדפים אחרים באתר זה.',
+'uncategorizedpages' => 'דפים חסרי קטגוריה',
+'uncategorizedcategories' => 'קטגוריות חסרות קטגוריה',
+'uncategorizedimages' => 'תמונות חסרות קטגוריה',
+'unusedcategories' => 'קטגוריות שאינן בשימוש',
+'unusedimages' => 'תמונות שאינן בשימוש',
+'popularpages' => 'דפים פופולריים',
+'wantedcategories' => 'קטגוריות מבוקשות',
+'wantedpages' => 'דפים מבוקשים',
+'mostlinked' => 'הדפים המקושרים ביותר',
+'mostlinkedcategories' => 'הקטגוריות המקושרות ביותר',
+'mostcategories' => 'הדפים מרובי־הקטגוריות ביותר',
+'mostimages' => 'התמונות המקושרות ביותר',
+'mostrevisions' => 'הדפים בעלי מספר העריכות הגבוה ביותר',
+'allpages' => 'כל הדפים',
+'prefixindex' => 'רשימת הדפים המתחילים ב…',
+'randompage' => 'דף אקראי',
+'shortpages' => 'דפים קצרים',
+'longpages' => 'דפים ארוכים',
+'deadendpages' => 'דפים ללא קישורים',
+'deadendpagestext' => 'הדפים הבאים אינם מקשרים לדפים אחרים באתר.',
+'listusers' => 'רשימת משתמשים',
+'specialpages' => 'דפים מיוחדים',
+'spheading' => 'דפים מיוחדים',
+'restrictedpheading' => 'דפים מיוחדים מוגבלים',
+'recentchangeslinked' => 'שינויים בדפים המקושרים',
+'rclsub' => '(לדפים המקושרים מהדף "$1")',
+'newpages' => 'דפים חדשים',
+'newpages-username' => 'שם משתמש:',
+'ancientpages' => 'דפים מוזנחים',
+'intl' => 'קישורים בינלשוניים',
+'move' => 'העברה',
+'movethispage' => 'העבר דף זה',
+'unusedimagestext' => 'רשימת הקבצים שאינם בשימוש באתר. יש למצוא מקום עבור הקבצים או לסמן אותם למחיקה.',
+'unusedcategoriestext' => 'למרות שהקטגוריות הבאות קיימות, אין שום דף בו נעשה בהן שימוש.',
+
+# Book sources
+'booksources' => 'משאבי ספרות חיצוניים',
+'booksources-search-legend' => 'חיפוש משאבי ספרות חיצוניים',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => 'עבור',
+'booksources-text' => 'להלן רשימת קישורים לאתרים אחרים המוכרים ספרים חדשים ויד־שנייה, ושבהם עשוי להיות מידע נוסף לגבי ספרים שאתם מחפשים:',
+
+'categoriespagetext' => 'אלו הקטגוריות הקיימות באתר.',
+'data' => 'נתונים',
+'userrights' => 'ניהול הרשאות משתמש',
+'groups' => 'קבוצות משתמשים',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 עד $2',
+'version' => 'גרסת התוכנה',
+'log' => 'יומנים',
+'alllogstext' => 'תצוגה משולבת של יומני העלאת קבצים, מחיקות והגנות על דפים, חסימת משתמשים ומינוי מפעילי מערכת.
+
+ניתן לצמצם את התצוגה על־ידי בחירת סוג היומן, שם המשתמש או הדפים המושפעים.',
+'logempty' => 'אין פריטים תואמים ביומן.',
+
+# Special:Allpages
+'nextpage' => 'הדף הבא ($1)',
+'prevpage' => 'הדף הקודם ($1)',
+'allpagesfrom' => 'הצג דפים החל מ:',
+'allarticles' => 'כל הדפים',
+'allinnamespace' => 'כל הדפים (מרחב שם $1)',
+'allnotinnamespace' => 'כל הדפים (שלא במרחב השם $1)',
+'allpagesprev' => 'הקודם',
+'allpagesnext' => 'הבא',
+'allpagessubmit' => 'עבור',
+'allpagesprefix' => 'הדפים ששמם מתחיל ב…:',
+'allpagesbadtitle' => 'כותרת הדף המבוקש הייתה לא־חוקית, ריקה, קישור ויקי פנימי, או פנים שפה שגוי. ייתכן שהיא כוללת תו אחד או יותר האסורים לשימוש בכותרות.',
+
+# Special:Listusers
+'listusersfrom' => 'הצג משתמשים החל מ:',
+
+# E-mail user
+'mailnologin' => 'אין כתובת לשליחה',
+'mailnologintext' => 'עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]] ולהגדיר לעצמכם כתובת דואר אלקטרוני תקינה ב[[{{ns:special}}:Preferences|העדפות המשתמש]] שלכם כדי לשלוח דואר למשתמש אחר.',
+'emailuser' => 'שלחו דואר אלקטרוני למשתמש זה',
+'emailpage' => 'שלחו דואר למשתמש',
+'emailpagetext' => 'אם המשתמש הזין כתובת דואר אלקטרוני חוקית בהעדפותיו האישיות, הטופס שלהלן ישלח אליו הודעת דואר אחת. כתובת הדואר האלקטרוני שהזנתם בהעדפותיכם האישיות תופיע ככתובת ממנה נשלחה ההודעה כדי שהמשתמש יוכל לענות.',
+'usermailererror' => 'אוביקט הדואר החזיר שגיאה:',
+'defemailsubject' => 'דוא"ל {{SITENAME}}',
+'noemailtitle' => 'אין כתובת דואר אלקטרוני',
+'noemailtext' => 'משתמש זה לא הזין כתובת דואר אלקטרוני חוקית או בחר שלא לקבל דואר אלקטרוני ממשתמשים אחרים.',
+'emailfrom' => 'מאת',
+'emailto' => 'אל',
+'emailsubject' => 'נושא',
+'emailmessage' => 'הודעה',
+'emailsend' => 'שלח',
+'emailccme' => 'שלח אלי בדואר האלקטרוני העתק של הודעתי.',
+'emailccsubject' => 'העתק של הודעתך למשתמש $1: $2',
+'emailsent' => 'הדואר נשלח',
+'emailsenttext' => 'הודעת הדואר האלקטרוני שלך נשלחה.',
+
+# Watchlist
+'watchlist' => 'רשימת המעקב שלי',
+'watchlistfor' => "(עבור '''$1''')",
+'nowatchlist' => 'אין דפים ברשימת המעקב.',
+'watchlistanontext' => 'עליכם $1 כדי לצפות או לערוך פריטים ברשימת המעקב.',
+'watchlistcount' => "'''יש לכם $1 פריטים ברשימת המעקב, כולל דפי שיחה.'''",
+'clearwatchlist' => 'ניקוי רשימת המעקב',
+'watchlistcleartext' => 'האם אתם בטוחים שברצונכם להסירם?',
+'watchlistclearbutton' => 'נקה את רשימת המעקב',
+'watchlistcleardone' => 'רשימת המעקב רוקנה. {{plural:$1|פריט אחד הוסר|$1 פריטים הוסרו}} ממנה.',
+'watchnologin' => 'לא נכנסתם לאתר',
+'watchnologintext' => 'עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]] כדי לערוך את רשימת המעקב.',
+'addedwatch' => 'הדף נוסף לרשימת המעקב',
+'addedwatchtext' => 'הדף "[[:$1]]" נוסף ל[[{{ns:special}}:Watchlist|רשימת המעקב]]. שינויים שייערכו בעתיד, בדף זה ובדף השיחה שלו, יוצגו ברשימת המעקב.
+
+בנוסף, הדף יופיע בכתב מודגש ב[[{{ns:special}}:Recentchanges|רשימת השינויים האחרונים]], כדי להקל עליכם את המעקב אחריו.
+
+אם תרצו להסיר את הדף מרשימת המעקב, לחצו על הלשונית "הפסקת מעקב" שלמעלה.',
+'removedwatch' => 'הדף הוסר מרשימת המעקב',
+'removedwatchtext' => 'הדף "[[:$1]]" הוסר מ[[{{ns:special}}:Watchlist|רשימת המעקב]].',
+'watch' => 'מעקב',
+'watchthispage' => 'עקוב אחר דף זה',
+'unwatch' => 'הפסקת מעקב',
+'unwatchthispage' => 'הפסק לעקוב אחר דף זה',
+'notanarticle' => 'זהו אינו דף תוכן',
+'watchnochange' => 'אף אחד מהדפים ברשימת המעקב לא עודכן בפרק הזמן המצוין למעלה.',
+'watchdetails' => '* ברשימת המעקב יש {{plural:$1|דף אחד|$1 דפים}} (לא כולל דפי שיחה).
+* [[{{ns:special}}:Watchlist/edit|הצגה ועריכה של רשימת המעקב במלואה]].
+* [[{{ns:special}}:Watchlist/clear|הסרת כל הדפים]].',
+'wlheader-enotif' => '* הודעות דוא"ל מאופשרות.',
+'wlheader-showupdated' => "* דפים שהשתנו מאז ביקורכם האחרון בהם מוצגים ב'''הדגשה'''.",
+'watchmethod-recent' => 'בודק את הדפים שברשימת המעקב לשינויים אחרונים.',
+'watchmethod-list' => 'בודק את העריכות האחרונות בדפים שברשימת המעקב',
+'removechecked' => 'הסר דפים מסומנים מרשימת המעקב',
+'watchlistcontains' => 'רשימת המעקב כוללת $1 דפים.',
+'watcheditlist' => 'להלן רשימה מסודרת של הדפים ברשימת המעקב. בחרו את הדפים שאתם רוצים להסיר מהרשימה ולחצו על "הסר דפים מסומנים" בתחתית הדף (הסרת דף גם מסירה את דף השיחה שלו, וכיוצא בזה).',
+'removingchecked' => 'מסיר את הדפים המסומנים מרשימת המעקב…',
+'couldntremove' => 'לא ניתן להסיר את $1…',
+'iteminvalidname' => 'בעיה עם $1, שם שגוי…',
+'wlnote' => "להלן $1 השינויים האחרונים ב־'''$2''' השעות האחרונות.",
+'wlshowlast' => '(הצג $1 שעות אחרונות | $2 ימים אחרונים | $3)',
+'wlsaved' => 'זוהי גרסה שמורה של רשימת המעקב.',
+'watchlist-show-bots' => 'הצג בוטים',
+'watchlist-hide-bots' => 'הסתר בוטים',
+'watchlist-show-own' => 'הצג עריכות שלי',
+'watchlist-hide-own' => 'הסתר עריכות שלי',
+'watchlist-show-minor' => 'הצג עריכות משניות',
+'watchlist-hide-minor' => 'הסתר עריכות משניות',
+'wldone' => 'בוצע.',
+
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => 'מוסיף לרשימת המעקב…',
+'unwatching' => 'מסיר מרשימת המעקב…',
+
+'enotif_mailer' => 'הודעות {{SITENAME}}',
+'enotif_reset' => 'סמן את כל הדפים כאילו נצפו',
+'enotif_newpagetext' => 'זהו דף חדש.',
+'changed' => 'שונה',
+'created' => 'נוצר',
+'enotif_subject' => 'הדף $PAGETITLE ב{{grammar:תחילית|{{SITENAME}}}} $CHANGEDORCREATED על־ידי $PAGEEDITOR',
+'enotif_lastvisited' => 'ראו $1 לכל השינויים מאז ביקורכם האחרון.',
+'enotif_body' => 'לכבוד $WATCHINGUSERNAME,
+
+הדף $PAGETITLE ב{{grammar:תחילית|{{SITENAME}}}} $CHANGEDORCREATED ב־$PAGEEDITDATE על־ידי $PAGEEDITOR, ראו $PAGETITLE_URL לגרסה הנוכחית.
+
+$NEWPAGE
+
+תקציר העריכה: $PAGESUMMARY $PAGEMINOREDIT
+
+באפשרותכם ליצור קשר עם העורך:
+בדואר האלקטרוני: $PAGEEDITOR_EMAIL
+באתר: $PAGEEDITOR_WIKI
+
+לא תהיינה הודעות על שינויים נוספים עד שתבקרו את הדף. באפשרותכם גם לאפס את דגלי ההודעות בכל הדפים שברשימת המעקב.
+
+ מערכת ההודעות של {{SITENAME}}
+
+--
+כדי לשנות את הגדרות רשימת המעקב, בקרו בדף
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+משוב ועזרה נוספת:
+{{fullurl:{{ns:project}}:עזרה}}',
+
+# Delete/protect/revert
+'deletepage' => 'מחיקת דף',
+'confirm' => 'אישור',
+'excontent' => 'תוכן היה: "$1"',
+'excontentauthor' => "תוכן היה: '$1' והתורם היחיד היה [[{{ns:special}}:Contributions/$2|$2]]",
+'exbeforeblank' => 'תוכן לפני שהורק היה: "$1"',
+'exblank' => 'הדף היה ריק',
+'confirmdelete' => 'אישור מחיקת הדף',
+'deletesub' => '(מוחק את "$1")',
+'historywarning' => 'אזהרה – לדף שאתם עומדים למחוק יש היסטוריית שינויים:',
+'confirmdeletetext' => 'אתם עומדים למחוק דף או תמונה, יחד עם כל ההיסטוריה שלהם, מבסיס הנתונים.
+
+אנא אשרו שזה אכן מה שאתם מתכוונים לעשות, שאתם מבינים את התוצאות של מעשה כזה, ושהמעשה מבוצע בהתאם לנהלי האתר.',
+'actioncomplete' => 'הפעולה בוצעה',
+'deletedtext' => '"[[:$1]]" נמחק. ראו $2 לרשימת המחיקות האחרונות.',
+'deletedarticle' => 'מחק את "[[$1]]"',
+'dellogpage' => 'יומן מחיקות',
+'dellogpagetext' => 'להלן רשימה של המחיקות האחרונות שבוצעו.',
+'deletionlog' => 'יומן מחיקות',
+'reverted' => 'שוחזר לגרסה קודמת',
+'deletecomment' => 'סיבת המחיקה',
+'imagereverted' => 'השיחזור לגרסה הקודמת הושלם בהצלחה.',
+'rollback' => 'שיחזור עריכות',
+'rollback_short' => 'שיחזור',
+'rollbacklink' => 'שיחזור',
+'rollbackfailed' => 'השיחזור נכשל',
+'cantrollback' => 'לא ניתן לשחזר את העריכה – התורם האחרון הוא היחיד שכתב דף זה; עם זאת, ניתן למחוק את הדף.',
+'alreadyrolled' => 'לא ניתן לשחזר את עריכת הדף [[:$1]] על־ידי [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|שיחה]]); מישהו אחר כבר ערך או שיחזר דף זה.
+
+העריכה האחרונה היתה של [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|שיחה]]).',
+'editcomment' => 'תקציר העריכה היה: "\'\'\'$1\'\'\'".', # only shown if there is an edit comment
+'revertpage' => 'שוחזר מעריכה של [[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|שיחה]]) לעריכה האחרונה של [[{{ns:user}}:$1|$1]]',
+'sessionfailure' => 'נראה שיש בעיה בחיבורכם לאתר. פעולתכם בוטלה כאמצעי זהירות כנגד התחזות לתקשורת ממחשבכם. אנא חיזרו לדף הקודם ונסו שנית.',
+'protectlogpage' => 'יומן הגנות',
+'protectlogtext' => 'להלן רשימה של הגנות וביטולי הגנות על דפים.',
+'protectedarticle' => 'הגן על [[$1]]',
+'unprotectedarticle' => 'ביטל את ההגנה על [[$1]]',
+'protectsub' => '(מגן על "$1")',
+'confirmprotecttext' => 'האם אתם בטוחים שברצונכם להגן על דף זה?',
+'confirmprotect' => 'מאשר את ההגנה',
+'protectmoveonly' => 'הגן מפני העברת הדף בלבד',
+'protectcomment' => 'הסיבה להגנה',
+'unprotectsub' => '(מבטל את ההגנה על "$1")',
+'confirmunprotecttext' => 'האם אתם בטוחים שברצונכם לבטל את ההגנה על דף זה?',
+'confirmunprotect' => 'מאשר את ביטול ההגנה',
+'unprotectcomment' => 'הסיבה להסרת ההגנה',
+'protect-unchain' => 'אפשר שינוי הרשאות העברה',
+'protect-text' => 'באפשרותכם לראות ולשנות כאן את רמת ההגנה של הדף [[:$1]]. אנא ודאו שאתם פועלים בהתאם בהתאם לנהלי האתר.',
+'protect-viewtext' => 'לחשבון שלך אין הרשאה לשנות את רמת ההגנה של הדף. להלן ההגדרות הנוכחיות עבור הדף [[:$1]]:',
+'protect-default' => '(ברירת מחדל)',
+'protect-level-autoconfirmed' => 'משתמשים רשומים בלבד',
+'protect-level-sysop' => 'מפעילי מערכת בלבד',
+
+# Restrictions (nouns)
+'restriction-edit' => 'עריכה',
+'restriction-move' => 'העברה',
+
+# Undelete
+'undelete' => 'צפיה בדפים מחוקים',
+'undeletepage' => 'צפיה ושיחזור דפים מחוקים',
+'viewdeletedpage' => 'צפיה בדפים מחוקים',
+'undeletepagetext' => 'הדפים שלהלן נמחקו, אך הם עדיין בארכיון וניתן לשחזר אותם. הארכיון מנוקה מעת לעת.',
+'undeleteextrahelp' => 'לשיחזור הדף כולו, אל תסמנו אף תיבת סימון ולחצו על "שיחזור". לשיחזור של גרסאות מסוימות בלבד, סמנו את תיבות הסימון של הגרסאות הללו, ולחצו על "שיחזור". לחיצה על "איפוס" תנקה את התקציר, ואת כל תיבות הסימון.',
+'undeletearticle' => 'שחזרו דף מחוק',
+'undeleterevisions' => '$1 גרסאות נשמרו בארכיון',
+'undeletehistory' => 'אם תשחזרו את הדף, כל הגרסאות תשוחזרנה להיסטוריית השינויים שלו.
+
+אם כבר יש דף חדש באותו השם, הגרסאות והשינויים יופיעו רק בדף ההיסטוריה שלו, והגרסה הנוכחית של הדף לא תוחלף אוטומטית.',
+'undeletehistorynoadmin' => 'דף זה נמחק. הסיבה למחיקה מוצגת בתקציר מטה, ביחד עם פרטים על המשתמשים שערכו את הדף לפני מחיקתו. הטקסט של גרסאות אלו זמין רק למפעילי מערכת.',
+'undeleterevision' => 'נמחקו גרסאות החל מ־$1.',
+'undeleterevision-missing' => 'הגרסה שגויה או חסרה. ייתכן שמדובר בקישור שבור, או שהגרסה שוחזרה או הוסרה מהארכיון.',
+'undeletebtn' => 'שיחזור',
+'undeletereset' => 'איפוס',
+'undeletecomment' => 'תקציר:',
+'undeletedarticle' => 'שיחזר את [[:$1]]',
+'undeletedrevisions' => 'שיחזר $1 גרסאות',
+'undeletedrevisions-files' => 'שיחזר $1 גרסאות ו־$2 קבצים',
+'undeletedfiles' => 'שיחזר $1 קבצים',
+'cannotundelete' => 'השיחזור נכשל; ייתכן שמישהו אחר כבר שיחזר את הדף.',
+'undeletedpage' => "'''הדף $1 שוחזר בהצלחה.'''
+
+ראו את [[{{ns:special}}:Log/delete|יומן המחיקות]] לרשימה של מחיקות ושיחזורים אחרונים.",
+
+# Namespace form on various pages
+'namespace' => 'מרחב שם:',
+'invert' => 'ללא מרחב זה',
+
+# Contributions
+'contributions' => 'תרומות המשתמש',
+'mycontris' => 'התרומות שלי',
+'contribsub' => 'עבור $1',
+'nocontribs' => 'לא נמצאו שינויים המתאימים לקריטריונים אלו.',
+'ucnote' => "להלן '''$1''' השינויים האחרונים שביצע משתמש זה ב־'''$2''' הימים האחרונים:",
+'uclinks' => 'צפה ב־$1 השינויים האחרונים; צפה ב־$2 הימים האחרונים',
+'uctop' => '(אחרון)',
+'newbies' => 'משתמשים חדשים',
+
+'sp-contributions-newest' => 'חדשות ביותר',
+'sp-contributions-oldest' => 'ישנות ביותר',
+'sp-contributions-newer' => '$1 החדשות',
+'sp-contributions-older' => '$1 הישנות',
+'sp-contributions-newbies-sub' => 'עבור משתמשים חדשים',
+'sp-contributions-blocklog' => 'יומן חסימות',
+
+'sp-newimages-showfrom' => 'הצג תמונות חדשות החל מ־$1',
+
+# What links here
+'whatlinkshere' => 'דפים המקושרים לכאן',
+'notargettitle' => 'אין דף מטרה',
+'notargettext' => 'לא ציינתם דף מטרה או משתמש לגביו תבוצע פעולה זו.',
+'linklistsub' => '(רשימת קישורים)',
+'linkshere' => "הדפים שלהלן מקושרים לדף '''[[:$1]]''':",
+'nolinkshere' => "אין דפים המקושרים לדף '''[[:$1]]'''.",
+'isredirect' => 'דף הפניה',
+'istemplate' => 'הכללה',
+
+# Block/unblock
+'blockip' => 'חסימת משתמש',
+'blockiptext' => 'השתמשו בטופס שלהלן כדי לחסום את הרשאות הכתיבה ממשתמש או כתובת IP ספציפיים.
+
+חסימות כאלה צריכות להתבצע אך ורק כדי למנוע ונדליזם, ובהתאם לנהלי האתר.
+
+אנא פרטו את הסיבה הספציפית לחסימה להלן (לדוגמה, ציון דפים ספציפיים אותם השחית המשתמש).',
+'ipaddress' => 'כתובת IP',
+'ipadressorusername' => 'כתובת IP או שם משתמש',
+'ipbexpiry' => 'פקיעה',
+'ipbreason' => 'סיבה',
+'ipbanononly' => 'חסום משתמשים אנונימיים בלבד',
+'ipbcreateaccount' => 'חסום יצירת חשבונות',
+'ipbenableautoblock' => 'עבור חסימת משתמש רשום: חסום גם את כתובת ה־IP שלו',
+'ipbsubmit' => 'חסום משתמש זה',
+'ipbother' => 'זמן אחר',
+'ipboptions' => 'שעתיים:2 hours,יום:1 day,שלושה ימים:3 days,שבוע:1 week,שבועיים:2 weeks,חודש:1 month,שלושה חודשים:3 months,חצי שנה:6 months,שנה:1 year,לצמיתות:infinite',
+'ipbotheroption' => 'אחר',
+'badipaddress' => 'משתמש או כתובת IP שגויים.',
+'blockipsuccesssub' => 'החסימה הושלמה בהצלחה',
+'blockipsuccesstext' => 'המשתמש [[{{ns:special}}:Contributions/$1|$1]] נחסם.
+
+ראו את [[{{ns:special}}:Ipblocklist|רשימת המשתמשים החסומים]] כדי לצפות בחסימות.',
+'unblockip' => 'שחרר משתמש',
+'unblockiptext' => 'השתמשו בטופס שלהלן כדי להחזיר את הרשאות הכתיבה למשתמש או כתובת IP חסומים.',
+'ipusubmit' => 'שחרר משתמש זה',
+'unblocked' => 'המשתמש "[[משתמש:$1|$1]]" שוחרר מחסימתו.',
+'ipblocklist' => 'רשימת משתמשים חסומים',
+'blocklistline' => '$1 $2 חסם את $3 ($4)',
+'infiniteblock' => 'לצמיתות',
+'expiringblock' => 'פוקע $1',
+'anononlyblock' => 'משתמשים אנונימיים בלבד',
+'noautoblockblock' => 'חסימה אוטומטית נוטרלה',
+'createaccountblock' => 'יצירת חשבונות נחסמה',
+'ipblocklistempty' => 'רשימת המשתמשים החסומים ריקה.',
+'blocklink' => 'חסום',
+'unblocklink' => 'שחרר חסימה',
+'contribslink' => 'תרומות',
+'autoblocker' => 'נחסמת באופן אוטומטי משום שאתה חולק את כתובת ה־IP שלך עם [[{{ns:user}}:$1|$1]]. הנימוק שניתן לחסימת [[{{ns:user}}:$1|$1]] הוא: "$2".',
+'blocklogpage' => 'יומן חסימות',
+'blocklogentry' => 'חסם את [[$1]] למשך $2',
+'blocklogtext' => 'זהו יומן פעולות החסימה והשחרור של משתמשים. כתובות IP הנחסמות באופן אוטומטי אינן מופיעות.
+
+ראו גם את [[{{ns:special}}:Ipblocklist|רשימת המשתמשים החסומים]] הנוכחית.',
+'unblocklogentry' => 'שיחרר את [[$1]]',
+'range_block_disabled' => 'היכולת לחסום טווח כתובות איננה פעילה.',
+'ipb_expiry_invalid' => 'זמן פקיעת חסימה בלתי חוקי',
+'ipb_already_blocked' => 'המשתמש "$1" כבר נחסם',
+'ip_range_invalid' => 'טווח IP שגוי.',
+'proxyblocker' => 'חוסם פרוקסי',
+'ipb_cant_unblock' => 'שגיאה: חסימה מספר $1 לא נמצאה. ייתכן שהיא כבר שוחררה.',
+'proxyblockreason' => 'כתובת ה־IP שלכם נחסמה משום שהיא כתובת פרוקסי פתוחה. אנא צרו קשר עם ספק האינטרנט שלכם והודיעו לו על בעיית האבטחה החמורה הזו.',
+'proxyblocksuccess' => 'בוצע.',
+'sorbs' => 'SORBS',
+'sorbsreason' => 'כתובת ה־IP שלכם רשומה ככתובת פרוקסי פתוחה ב־DNSBL שאתר זה משתמש בו.',
+'sorbs_create_account_reason' => 'כתובת ה־IP שלכם רשומה ככתובת פרוקסי פתוחה ב־DNSBL שאתר זה משתמש בו. אינכם יכולים ליצור חשבון.',
+
+# Developer tools
+'lockdb' => 'נעל בסיס־נתונים',
+'unlockdb' => 'שחרר בסיס־נתונים מנעילה',
+'lockdbtext' => 'נעילת בסיס הנתונים תמנע ממשתמשים את האפשרות לערוך דפים, לשנות את העדפותיהם, לערוך את רשימות המעקב שלהם, ופעולות אחרות הדורשות ביצוע שינויים בבסיס הנתונים.
+
+אנא אשרו שזה מה שאתם מתכוונים לעשות, ושתשחררו את בסיס הנתונים מנעילה כאשר פעולת התחזוקה תסתיים.',
+'unlockdbtext' => 'שחרור בסיס הנתונים מנעילה יחזיר למשתמשים את היכולת לערוך דפים, לשנות את העדפותיהם, לערוך את רשימות המעקב שלהם, ולבצע פעולות אחרות הדורשות ביצוע שינויים בבסיס הנתונים
+אנא אשרו שזה מה שבכוונתכם לעשות.',
+'lockconfirm' => 'כן, אני באמת רוצה לנעול את בסיס הנתונים.',
+'unlockconfirm' => 'כן, אני באמת רוצה לשחרר את בסיס הנתונים מנעילה.',
+'lockbtn' => 'נעל את בסיס הנתונים',
+'unlockbtn' => 'שחרר את בסיס הנתונים מנעילה',
+'locknoconfirm' => 'לא סימנתם את תיבת האישור.',
+'lockdbsuccesssub' => 'נעילת בסיס הנתונים הושלמה בהצלחה',
+'unlockdbsuccesssub' => 'שוחררה הנעילה מבסיס הנתונים',
+'lockdbsuccesstext' => 'בסיס הנתונים ננעל.
+
+זכרו [[{{ns:special}}:Unlockdb|לשחרר את הנעילה]] לאחר שפעולת התחזוקה הסתיימה.',
+'unlockdbsuccesstext' => 'שוחררה הנעילה של בסיס הנתונים',
+'lockfilenotwritable' => 'קובץ נעילת מסד הנתונים אינו ניתן לכתיבה. כדי שאפשר יהיה לנעול את מסד הנתונים או לבטל את נעילתו, שרת האינטרנט צריך לקבל הרשאות לכתוב אליו.',
+'databasenotlocked' => 'מסד הנתונים אינו נעול.',
+
+# Make sysop
+'makesysoptitle' => 'הפוך משתמש למפעיל מערכת',
+'makesysoptext' => 'דף זה משמש ביורוקרטים להפיכת משתמש רגיל למפעיל מערכת. אנא הקישו את שם המשתמש בתיבת הטקסט ולחצו על הכפתור על מנת להפוך את המשתמש למפעיל מערכת.',
+'makesysopname' => 'שם המשתמש:',
+'makesysopsubmit' => 'הפוך משתמש זה למפעיל מערכת',
+'makesysopok' => '\'\'\'המשתמש "$1" הוא עכשיו מפעיל מערכת.\'\'\'',
+'makesysopfail' => '\'\'\'לא ניתן היה למנות את המשתמש "$1" למפעיל מערכת.\'\'\' (האם הקלדתם נכונה את שם המשתמש?)',
+'setbureaucratflag' => 'הפוך משתמש זה לביורוקרט.',
+'rightslog' => 'יומן תפקידים',
+'rightslogtext' => 'זהו יומן השינויים בתפקידי המשתמשים.',
+'rightslogentry' => 'שינה את ההרשאות של "$1" מההרשאות $2 להרשאות $3',
+'rights' => 'הרשאות:',
+'set_user_rights' => 'קבע הרשאות משתמש',
+'user_rights_set' => '\'\'\'הרשאות המשתמש "$1" עודכנו.\'\'\'',
+'set_rights_fail' => '\'\'\'שינוי הרשאות המשתמש "$1" נכשל.\'\'\' (האם הקלדתם נכונה את שם המשתמש?)',
+'makesysop' => 'הפוך משתמש למפעיל מערכת',
+'already_sysop' => 'משתמש זה הוא כבר מפעיל מערכת',
+'already_bureaucrat' => 'משתמש זה הוא כבר ביורוקרט',
+'rightsnone' => '(ללא הרשאות)',
+
+# Move page
+'movepage' => 'העברת דף',
+'movepagetext' => "שימוש בטופס שלהלן ישנה את שמו של דף, ויעביר את כל ההיסטוריה שלו לשם חדש.
+
+השם הישן יהפוך לדף הפניה אל הדף עם השם החדש.
+
+קישורים לשם הישן לא ישתנו, ולכן אנא ודאו שאין [[{{ns:special}}:DoubleRedirects|הפניות כפולות]] או [[{{ns:special}}:BrokenRedirects|שבורות]].
+
+אתם אחראים לוודא שכל הקישורים ממשיכים להצביע למקום שאליו הם אמורים להצביע.
+
+שימו לב: הדף '''לא''' יועבר אם כבר יש דף תחת השם החדש, אלא אם הדף הזה ריק, או שהוא הפניה, ואין לו היסטוריה של שינויים. משמעות הדבר, שאפשר לשנות חזרה את שמו של דף לשם המקורי, אם נעשתה טעות, ולא יימחק דף קיים במערכת.
+
+'''אזהרה:''' שינוי זה עשוי להיות שינוי דרסטי ובלתי צפוי לדף פופולרי; אנא ודאו שאתם מבינים את השלכות המעשה לפני שאתם ממשיכים.",
+'movepagetalktext' => 'דף השיחה של דף זה יועבר אוטומטית, אלא אם:
+* קיים דף שיחה שאינו ריק תחת השם החדש אליו מועבר הדף.
+* הורדתם את הסימון בתיבה שלהלן.
+
+במקרים אלו, תצטרכו להעביר או לשלב את הדפים באופן ידני, אם תרצו.',
+'movearticle' => 'העבר דף',
+'movenologin' => 'לא נכנסתם לאתר',
+'movenologintext' => 'עליכם [[{{ns:special}}:Userlogin|להיכנס לחשבון]] כדי להעביר דפים.',
+'newtitle' => 'לשם החדש',
+'move-watch' => 'מעקב אחרי דף זה',
+'movepagebtn' => 'העבר דף',
+'pagemovedsub' => 'ההעברה הושלמה בהצלחה',
+'pagemovedtext' => 'הדף "[[$1]]" הועבר לשם "[[$2]]".',
+'articleexists' => 'קיים כבר דף עם אותו שם, או שהשם שבחרתם אינו חוקי.
+אנא בחרו שם אחר.',
+'talkexists' => 'הדף עצמו הועבר בהצלחה, אבל דף השיחה לא הועבר כיוון שקיים כבר דף שיחה במיקום החדש. אנא מזגו אותם ידנית.',
+'movedto' => 'הועבר ל',
+'movetalk' => 'העבר גם את דף השיחה.',
+'talkpagemoved' => 'דף השיחה המשוייך הועבר גם כן.',
+'talkpagenotmoved' => "דף השיחה המשוייך '''לא''' הועבר.",
+'1movedto2' => '[[$1]] הועבר לשם [[$2]]',
+'1movedto2_redir' => '[[$1]] הועבר לשם [[$2]] במקום הפניה',
+'movelogpage' => 'יומן העברות',
+'movelogpagetext' => 'להלן רשימה של העברות דפים.',
+'movereason' => 'סיבה',
+'revertmove' => 'החזר',
+'delete_and_move' => 'מחק והעבר',
+'delete_and_move_text' => '== בקשת מחיקה ==
+דף היעד "[[$1]]" כבר קיים. האם ברצונכם למחוק אותו כדי לאפשר את ההעברה?',
+'delete_and_move_confirm' => 'כן, מחק את הדף',
+'delete_and_move_reason' => 'מחיקה על מנת לאפשר העברה',
+'selfmove' => 'כותרות המקור והיעד זהות; לא ניתן להעביר דף לעצמו.',
+'immobile_namespace' => 'כותרת המקור או היעד היא סוג מיוחד של דף; לא ניתן להעביר דפים לתוך או מתוך מרחב שם זה.',
+
+# Export
+'export' => 'ייצוא דפים',
+'exporttext' => 'באפשרותכם לייצא את התוכן ואת היסטוריית העריכה של דף אחד או של מספר דפים, בתבנית של קובץ XML, שניתן לייבא אותו למיזם ויקי אחר המשתמש בתוכנת מדיה־ויקי באמצעות הדף [[{{ns:special}}:Import]].
+
+כדי לייצא דפים, הקישו את שמותיהם בתיבת הטקסט שלהלן, כל שם בשורה נפרדת, ובחרו האם לייצא גם את הגרסה הנוכחית וגם את היסטוריית השינויים של הדפים, או רק את הגרסה הנוכחית עם מידע על העריכה האחרונה.
+
+בנוסף, ניתן להשתמש בקישור, כגון [[{{ns:special}}:Export/{{int:mainpage}}]] לדף {{int:mainpage}} ללא היסטוריית השינויים שלו.',
+'exportcuronly' => 'כלול רק את הגרסה הנוכחית, ללא כל ההיסטוריה',
+'exportnohistory' => "----
+'''הערה:''' ייצוא ההיסטוריה המלאה של דפים דרך טופס זה הופסקה עקב בעיות ביצוע.",
+'export-submit' => 'ייצוא',
+
+# Namespace 8 related
+'allmessages' => 'הודעות המערכת',
+'allmessagesname' => 'שם',
+'allmessagesdefault' => 'טקסט ברירת מחדל',
+'allmessagescurrent' => 'טקסט נוכחי',
+'allmessagestext' => 'זוהי רשימת כל הודעות המערכת שבמרחב השם {{ns:mediawiki}}, המשמשים את ממשק האתר.
+
+מפעילי המערכת יכולים לערוך את ההודעות בלחיצה על שם ההודעה.',
+'allmessagesnotsupportedUI' => "שפת הממשק הנוכחית שלכם, '''$1''', אינה נתמכת על־ידי הדף באתר זה.",
+'allmessagesnotsupportedDB' => 'לא ניתן להשתמש בדף זה כיוון ש־wgUseDatabseMessages מבוטל.',
+'allmessagesfilter' => 'מסנן שמות ההודעות:',
+'allmessagesmodified' => 'רק הודעות ששונו',
+
+# Thumbnails
+'thumbnail-more' => 'הגדל',
+'missingimage' => "'''תמונה חסרה'''
+
+'''$1''",
+'filemissing' => 'קובץ חסר',
+'thumbnail_error' => 'שגיאה ביצירת תמונה ממוזערת: $1',
+
+# Special:Import
+'import' => 'ייבוא דפים',
+'importinterwiki' => 'ייבוא בין־אתרי',
+'import-interwiki-text' => 'אנא בחרו אתר ויקי ואת כותרת הדף לייבוא.
+תאריכי ועורכי הגרסאות יישמרו בעת הייבוא.
+כל פעולות הייבוא הבין־אתרי נשמרות ביומן הייבוא.',
+'import-interwiki-history' => 'העתק את כל היסטוריית העריכות של דף זה',
+'import-interwiki-submit' => 'ייבוא',
+'import-interwiki-namespace' => 'העבר את הדפים לתוך מרחב השם:',
+'importtext' => 'אנא ייצאו את הקובץ מאתר המקור תוך שימוש בעזר הייצוא, שמרו אותו לדיסק הקשיח שלכם והעלו אותו לכאן.',
+'importstart' => 'מייבא דפים…',
+'import-revision-count' => '{{plural:$1|גרסה אחת|$1 גרסאות}}',
+'importnopages' => 'אין דפים לייבוא.',
+'importfailed' => 'הייבוא נכשל: $1',
+'importunknownsource' => 'סוג ייבוא בלתי ידוע',
+'importcantopen' => 'פתיחת קובץ הייבוא נכשלה',
+'importbadinterwiki' => 'קישור אינטרוויקי שגוי',
+'importnotext' => 'ריק או חסר טקסט',
+'importsuccess' => 'הייבוא הושלם בהצלחה!',
+'importhistoryconflict' => 'ישנה התנגשות עם ההיסטוריה הקיימת של הדף (ייתכן שהדף יובא בעבר)',
+'importnosources' => 'אין מקורות לייבוא בין־אתרי, וייבוא ישיר של דף עם היסטוריה אינו מאופשר כעת.',
+'importnofile' => 'לא הועלה קובץ ייבוא.',
+'importuploaderror' => 'העלאת קובץ ייבוא נכשלה; ייתכן שהקובץ גדול מגודל ההעלאה המותר.',
+
+# Import log
+'importlogpage' => 'יומן ייבוא',
+'importlogpagetext' => 'ייבוא מנהלי של דפים כולל היסטוריית העריכות שלהם מאתרי ויקי אחרים.',
+'import-logentry-upload' => 'ייבא את [[$1]] על־ידי העלאת קובץ',
+'import-logentry-upload-detail' => '$1 גרסאות',
+'import-logentry-interwiki' => 'ייבא את $1 בייבוא בין־אתרי',
+'import-logentry-interwiki-detail' => '$1 גרסאות מהאתר $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'חיפוש ב{{grammar:תחילית|{{SITENAME}}}} [Alt+F]',
+'tooltip-minoredit' => 'סימון עריכה זו כמשנית [Alt+I]',
+'tooltip-save' => 'שמירת את השינויים שביצעתם [Alt+S]',
+'tooltip-preview' => 'תצוגה מקדימה, אנא השתמשו באפשרות זו לפני השמירה! [Alt+P]',
+'tooltip-diff' => 'צפו בשינויים שערכתם בטקסט [Alt+V]',
+'tooltip-compareselectedversions' => 'צפו בהשוואה של שתי גרסאות של דף זה [Alt+V]',
+'tooltip-watch' => 'הוסיפו דף זה לרשימת המעקב [Alt+W]',
+
+# Stylesheets
+'common.css' => '/* הסגנונות הנכתבים כאן ישפיעו על כל הרקעים */',
+'monobook.css' => '/* הסגנונות הנכתבים כאן ישפיעו על הרקע Monobook בלבד */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF metadata מנוטרל בשרת זה.',
+'nocreativecommons' => 'Creative Commons RDF metadata מנוטרל בשרת זה.',
+'notacceptable' => 'האתר לא יכול לספק מידע בפורמט שתוכנת הלקוח יכולה לקרוא.',
+
+# Attribution
+'anonymous' => 'משתמש(ים) אנונימי(ים) של {{SITENAME}}',
+'siteuser' => 'משתמש {{SITENAME}} $1',
+'lastmodifiedatby' => 'דף זה שונה לאחרונה בתאריך $2, $1 על־ידי $3.', # $1 date, $2 time, $3 user
+'and' => 'וגם',
+'othercontribs' => 'מבוסס על העבודה של $1.',
+'others' => 'אחרים',
+'siteusers' => 'משתמש(י) {{SITENAME}} $1',
+'creditspage' => 'קרדיטים בדף',
+'nocredits' => 'אין קרדיטים זמינים בדף זה.',
+
+# Spam protection
+'spamprotectiontitle' => 'מנגנון מסנן הספאם',
+'spamprotectiontext' => 'הדף אותו רצית לשמור נחסם על־ידי מסנן הספאם. הסיבה לכך היא לרוב קישור לאתר חיצוני.',
+'spamprotectionmatch' => 'הטקסט הבא הוא שגרם להפעלת סינון הספאם: $1',
+'subcategorycount' => '{{plural:$1|ישנה קטגוריית משנה אחת|ישנן $1 קטגוריות משנה}} בקטגוריה זו.',
+'categoryarticlecount' => '{{plural:$1|ישנו דף אחד|ישנם $1 דפים}} בקטגוריה זו.',
+'category-media-count' => '{{plural:$1|ישנו קובץ אחד|ישנם $1 קבצים}} בקטגוריה זו',
+'listingcontinuesabbrev' => ' (המשך)',
+'spambot_username' => 'MediaWiki spam cleanup',
+'spam_reverting' => 'שיחזור לגרסה אחרונה שלא כוללת קישורים ל־$1',
+'spam_blanking' => 'כל הגרסאות כוללות קישורים ל־$1, מרוקן את הדף',
+
+# Info page
+'infosubtitle' => 'מידע על הדף',
+'numedits' => 'מספר עריכות (דף תוכן): $1',
+'numtalkedits' => 'מספר עריכות (דף שיחה): $1',
+'numwatchers' => 'מספר צופים בדף: $1',
+'numauthors' => 'מספר כותבים נפרדים (דף תוכן): $1',
+'numtalkauthors' => 'מספר כותבים נפרדים (דף שיחה): $1',
+
+# Math options
+'mw_math_png' => 'תמיד הצג כ־PNG',
+'mw_math_simple' => 'HTML אם פשוט מאוד, אחרת PNG',
+'mw_math_html' => 'HTML אם אפשר, אחרת PNG',
+'mw_math_source' => 'השאר כקוד TeX (לדפדפני טקסט)',
+'mw_math_modern' => 'מומלץ לדפדפנים עדכניים',
+'mw_math_mathml' => 'MathML אם אפשר (ניסיוני)',
+
+# Patrolling
+'markaspatrolleddiff' => 'סמן שינוי כבדוק',
+'markaspatrolledtext' => 'סמן דף זה כבדוק',
+'markedaspatrolled' => 'השינוי נבדק',
+'markedaspatrolledtext' => 'השינוי שנבחר נבדק.',
+'rcpatroldisabled' => 'בדיקת השינויים האחרונים מבוטלת',
+'rcpatroldisabledtext' => 'תכונת סימון שינוי כבדוק בשינויים האחרונים היא כרגע מנוטרלת.',
+'markedaspatrollederror' => 'לא יכול לסמן כבדוק',
+'markedaspatrollederrortext' => 'עליכם לציין גרסה שתציינו כבדוקה.',
+'markedaspatrollederror-noautopatrol' => 'אינכם מורשים לסמן את השינויים של עצמכם כבדוקים.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* ערכו קובץ זה כדי להריץ סקריפטים ב־JavaScript ברקע Monobook באתר כולו */
+/* חלונות קופצים ומקשים חמים */
+var ta = new Object();
+ta["pt-userpage"] = [".", "דף המשתמש שלי"];
+ta["pt-anonuserpage"] = [".", "דף המשתמש של משתמש אנונימי זה"];
+ta["pt-mytalk"] = ["n", "דף השיחה שלי"];
+ta["pt-anontalk"] = ["n", "שיחה על תרומות המשתמש האנונימי"];
+ta["pt-preferences"] = ["", "ההעדפות שלי"];
+ta["pt-watchlist"] = ["l", "רשימת הדפים שאתה עוקב אחרי השינויים בהם"];
+ta["pt-mycontris"] = ["y", "רשימת התרומות שלי"];
+ta["pt-login"] = ["o", "מומלץ להירשם, אך אין חובה לעשות כן"];
+ta["pt-anonlogin"] = ["o", "מומלץ להירשם, אך אין חובה לעשות כן"];
+ta["pt-logout"] = ["", "יציאה מהחשבון"];
+ta["ca-talk"] = ["t", "שוחחו על דף זה"];
+ta["ca-edit"] = ["e", "באפשרותכם לערוך דף זה. אנא השתמשו בלחצן \"תצוגה מקדימה\" לפני השמירה."];
+ta["ca-addsection"] = ["+", "הוספת הערה לשיחה זו"];
+ta["ca-viewsource"] = ["e", "זהו דף מוגן, אך באפשרותך לצפות במקורו"];
+ta["ca-history"] = ["h", "גרסאות קודמות של דף זה."];
+ta["ca-protect"] = ["=", "הגנו על דף זה"];
+ta["ca-delete"] = ["d", "מחקו דף זה"];
+ta["ca-undelete"] = ["d", "שחזרו עריכות שנעשו בדף זה לפני שנמחק"];
+ta["ca-move"] = ["m", "העבירו דף זה"];
+ta["ca-watch"] = ["w", "הוסיפו דף זה לרשימת המעקב"];
+ta["ca-unwatch"] = ["w", "הסירו דף זה מרשימת המעקב"];
+ta["search"] = ["f", "חפשו באתר"];
+ta["p-logo"] = ["", "עמוד ראשי"];
+ta["n-mainpage"] = ["z", "בקרו בעמוד הראשי"];
+ta["n-portal"] = ["", "אודות המיזם, איך תוכלו לעזור, איפה למצוא דברים"];
+ta["n-currentevents"] = ["", "מצאו מידע רקע על האירועים האחרונים"];
+ta["n-recentchanges"] = ["r", "רשימת השינויים האחרונים באתר"];
+ta["n-randompage"] = ["x", "צפייה בדף תוכן אקראי"];
+ta["n-help"] = ["", "עזרה בשימוש באתר"];
+ta["n-sitesupport"] = ["", "תרומה"];
+ta["t-whatlinkshere"] = ["j", "רשימת כל הדפים המקושרים לכאן"];
+ta["t-recentchangeslinked"] = ["k", "השינויים האחרונים שבוצעו בדפים המקושרים לכאן"];
+ta["feed-rss"] = ["", "הוסיפו עדכון אוטומטי על־ידי RSS"];
+ta["feed-atom"] = ["", "הוסיפו עדכון אוטומטי על־ידי Atom"];
+ta["t-contributions"] = ["", "צפו בתרומותיו של משתמש זה"];
+ta["t-emailuser"] = ["", "שלחו דואר אלקטרוני למשתמש זה"];
+ta["t-upload"] = ["u", "העלו תמונות או קבצי מדיה"];
+ta["t-specialpages"] = ["q", "רשימת כל הדפים המיוחדים"];
+ta["ca-nstab-main"] = ["c", "צפו בדף התוכן"];
+ta["ca-nstab-user"] = ["c", "צפו בדף המשתמש"];
+ta["ca-nstab-media"] = ["c", "צפו בפריט המדיה"];
+ta["ca-nstab-special"] = ["", "זהו דף מיוחד, אי אפשר לערוך אותו"];
+ta["ca-nstab-project"] = ["a", "צפו בדף המיזם"];
+ta["ca-nstab-image"] = ["c", "צפו בדף תיאור התמונה"];
+ta["ca-nstab-mediawiki"] = ["c", "צפו בהודעת המערכת"];
+ta["ca-nstab-template"] = ["c", "צפו בתבנית"];
+ta["ca-nstab-help"] = ["c", "צפו בדף העזרה"];
+ta["ca-nstab-category"] = ["c", "צפו בדף הקטגוריה"];',
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* כל סקריפט JavaScript שנכתב כאן ירוץ עבור כל המשתמשים בכל טעינת עמוד */',
+
+# Image deletion
+'deletedrevision' => 'מחק גרסה ישנה $1.',
+
+# Browsing diffs
+'previousdiff' => '→ עבור להשוואת הגרסאות הקודמת',
+'nextdiff' => 'עבור להשוואת הגרסאות הבאה ←',
+
+'imagemaxsize' => 'הגבל תמונות בדפי תיאור תמונה ל:',
+'thumbsize' => 'הקטן לגודל של:',
+'showbigimage' => 'הורד גרסת רזולוציה גבוהה ($1x$2, גודל: $3 קילובייטים)',
+
+'newimages' => 'גלריית תמונות חדשות',
+'showhidebots' => '($1 בוטים)',
+'noimages' => 'אין תמונות.',
+
+/*
+Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language
+*/
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+
+# Variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+
+# Variants for Kazakh language
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-cn' => 'kk-cn',
+'variantname-kk' => 'kk',
+
+# Labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'משתמש:',
+'speciallogtitlelabel' => 'כותרת:',
+
+'passwordtooshort' => 'סיסמתכם קצרה מדי. עליה להיות מורכבת מ־$1 תווים לפחות.',
+
+# Media Warning
+'mediawarning' => "'''אזהרה:''' קובץ זה עלול להכיל קוד זדוני, שהרצתו עלולה לסכן את המערכת שלכם.<hr />",
+
+'fileinfo' => '$1 קילובייטים, סוג MIME: <code>$2</code>',
+
+# Metadata
+'metadata' => 'מידע נוסף על התמונה',
+'metadata-help' => 'קובץ זה מכיל מידע נוסף, שיש להניח שהגיע ממצלמה דיגיטלית או מסורק בו התמונה נוצרה או עברה דיגיטציה. אם הקובץ שונה ממצבו הראשוני, כמה מהנתונים להלן עלולים שלא לשקף באופן מלא את מצב התמונה החדש.',
+'metadata-expand' => 'הצג פרטים מורחבים',
+'metadata-collapse' => 'הסתר פרטים מורחבים',
+'metadata-fields' => 'שדות המידע הנוסף של EXIF האלה אינם פרטים מורחבים ויוצגו תמיד, לעומת השאר:
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# EXIF tags
+'exif-imagewidth' => 'רוחב',
+'exif-imagelength' => 'גובה',
+'exif-bitspersample' => 'ביטים לרכיב',
+'exif-compression' => 'תבנית דחיסה',
+'exif-photometricinterpretation' => 'הרכב פיקסלים',
+'exif-orientation' => 'כיווניות',
+'exif-samplesperpixel' => 'מספר רכיבים',
+'exif-planarconfiguration' => 'סידור מידע',
+'exif-ycbcrsubsampling' => 'הפחתת יחס Y ל־C',
+'exif-ycbcrpositioning' => 'מיקום Y ו־C',
+'exif-xresolution' => 'רזולוציה אופקית',
+'exif-yresolution' => 'רזולוציה אנכית',
+'exif-resolutionunit' => 'יחידות מידה של רזולוציות X ו־Y',
+'exif-stripoffsets' => 'מיקום מידע התמונה',
+'exif-rowsperstrip' => 'מספר השורות לרצועה',
+'exif-stripbytecounts' => 'בייטים לרצועה דחוסה',
+'exif-jpeginterchangeformat' => 'יחס ל־JPEG SOI',
+'exif-jpeginterchangeformatlength' => 'בייטים של מידע JPEG',
+'exif-transferfunction' => 'פונקציית העברה',
+'exif-whitepoint' => 'נקודה לבנה צבעונית',
+'exif-primarychromaticities' => 'צבעוניות ה־Primarity',
+'exif-ycbcrcoefficients' => 'מקדמי פעולת הטרנספורמציה של מרחב הצבע',
+'exif-referenceblackwhite' => 'זוג ערכי התייחסות לשחור ולבן',
+'exif-datetime' => 'תאריך ושעת שינוי הקובץ',
+'exif-imagedescription' => 'כותרת התמונה',
+'exif-make' => 'יצרן המצלמה',
+'exif-model' => 'דגם המצלמה',
+'exif-software' => 'תוכנה בשימוש',
+'exif-artist' => 'מחבר',
+'exif-copyright' => 'בעל זכויות היוצרים',
+'exif-exifversion' => 'גרסת Exif',
+'exif-flashpixversion' => 'גרסת Flashpix נתמכת',
+'exif-colorspace' => 'מרחב הצבע',
+'exif-componentsconfiguration' => 'משמעות כל רכיב',
+'exif-compressedbitsperpixel' => 'שיטת דחיסת התמונה',
+'exif-pixelydimension' => 'רוחב התמונה הנכון',
+'exif-pixelxdimension' => 'גובה התמונה הנכון',
+'exif-makernote' => 'הערות היצרן',
+'exif-usercomment' => 'הערות המשתמש',
+'exif-relatedsoundfile' => 'קובץ שמע מקושר',
+'exif-datetimeoriginal' => 'תאריך ושעת יצירת הקובץ',
+'exif-datetimedigitized' => 'תאריך ושעת הפיכת הקובץ לדיגיטלי',
+'exif-subsectime' => 'תת־השניות של שינוי הקובץ',
+'exif-subsectimeoriginal' => 'תת־השניות של יצירת הקובץ',
+'exif-subsectimedigitized' => 'תת־השניות של הפיכת הקובץ לדיגיטלי',
+'exif-exposuretime' => 'זמן חשיפה',
+'exif-exposuretime-format' => '$1 שניות ($2)',
+'exif-fnumber' => 'מספר F',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'תוכנת החשיפה',
+'exif-spectralsensitivity' => 'רגישות הספקטרום',
+'exif-isospeedratings' => 'דירוג מהירות ה־ISO',
+'exif-oecf' => 'מקדם המרה אופטו־אלקטרוני',
+'exif-shutterspeedvalue' => 'מהירות צמצם',
+'exif-aperturevalue' => 'פתח',
+'exif-brightnessvalue' => 'בהירות',
+'exif-exposurebiasvalue' => 'נטיית החשיפה',
+'exif-maxaperturevalue' => 'גודל הפתח המקסימאלי',
+'exif-subjectdistance' => 'נושא המרחק',
+'exif-meteringmode' => 'שיטת מדידה',
+'exif-lightsource' => 'מקור אור',
+'exif-flash' => 'פלש',
+'exif-focallength' => 'אורך מוקדי העדשות',
+'exif-focallength-format' => '$1 מ"מ',
+'exif-subjectarea' => 'נושא האזור',
+'exif-flashenergy' => 'אנרגיית הפלש',
+'exif-spatialfrequencyresponse' => 'תדירות התגובה המרחבית',
+'exif-focalplanexresolution' => 'משטח הפוקוס ברזולוציה האופקית',
+'exif-focalplaneyresolution' => 'משטח הפוקוס ברזולוציה האנכית',
+'exif-focalplaneresolutionunit' => 'יחידת המידה של משטח הפוקוס ברזולוציה',
+'exif-subjectlocation' => 'נושא המיקום',
+'exif-exposureindex' => 'מדד החשיפה',
+'exif-sensingmethod' => 'שיטת חישה',
+'exif-filesource' => 'מקור הקובץ',
+'exif-scenetype' => 'סוג הסצנה',
+'exif-cfapattern' => 'תבנית CFA',
+'exif-customrendered' => 'עיבוד תמונה מותאם',
+'exif-exposuremode' => 'מצב החשיפה',
+'exif-whitebalance' => 'איזון צבע לבן',
+'exif-digitalzoomratio' => 'יחס הזום הדיגיטלי',
+'exif-focallengthin35mmfilm' => 'אורך מוקדי העדשות בסרט צילום של 35 מ"מ',
+'exif-scenecapturetype' => 'אופן צילום הסצנה',
+'exif-gaincontrol' => 'בקרת הסצנה',
+'exif-contrast' => 'ניגוד',
+'exif-saturation' => 'רוויה',
+'exif-sharpness' => 'חדות',
+'exif-devicesettingdescription' => 'תיאור הגדרות ההתקן',
+'exif-subjectdistancerange' => 'טווח נושא המרחק',
+'exif-imageuniqueid' => 'מזהה תמונה ייחודי',
+'exif-gpsversionid' => 'גרסת תגי GPS',
+'exif-gpslatituderef' => 'קו־רוחב צפוני או דרומי',
+'exif-gpslatitude' => 'קו־רוחב',
+'exif-gpslongituderef' => 'קו־אורך מזרחי או מערבי',
+'exif-gpslongitude' => 'קו־אורך',
+'exif-gpsaltituderef' => 'התייחסות גובה',
+'exif-gpsaltitude' => 'גובה',
+'exif-gpstimestamp' => 'זמן GPS (שעון אטומי)',
+'exif-gpssatellites' => 'לוויינים ששמשו למדידה',
+'exif-gpsstatus' => 'מעמד המקלט',
+'exif-gpsmeasuremode' => 'מצב מדידה',
+'exif-gpsdop' => 'דיוק מדידה',
+'exif-gpsspeedref' => 'יחידת מהירות',
+'exif-gpsspeed' => 'יחידת מהירות של מקלט GPS',
+'exif-gpstrackref' => 'התייחסות מהירות התנועה',
+'exif-gpstrack' => 'מהירות התנועה',
+'exif-gpsimgdirectionref' => 'התייחסות כיוון התמונה',
+'exif-gpsimgdirection' => 'כיוון התמונה',
+'exif-gpsmapdatum' => 'מידע סקר מדידת הארץ שנעשה בו שימוש',
+'exif-gpsdestlatituderef' => 'התייחסות קו־הרוחב של היעד',
+'exif-gpsdestlatitude' => 'קו־הרוחב של היעד',
+'exif-gpsdestlongituderef' => 'התייחסות קו־האורך של היעד',
+'exif-gpsdestlongitude' => 'קו־האורך של היעד',
+'exif-gpsdestbearingref' => 'התייחסות כיוון היעד',
+'exif-gpsdestbearing' => 'כיוון היעד',
+'exif-gpsdestdistanceref' => 'התייחסות מרחק ליעד',
+'exif-gpsdestdistance' => 'מרחק ליעד',
+'exif-gpsprocessingmethod' => 'שם שיטת העיבוד של ה־GPS',
+'exif-gpsareainformation' => 'שם אזור ה־GPS',
+'exif-gpsdatestamp' => 'תאריך ה־GPS',
+'exif-gpsdifferential' => 'תיקון דיפרנציאלי של ה־GPS',
+
+# EXIF attributes
+'exif-compression-1' => 'לא דחוס',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-unknowndate' => 'תאריך בלתי ידוע',
+
+'exif-orientation-1' => 'רגילה', # 0th row: top; 0th column: left
+'exif-orientation-2' => 'הפוך אופקית', # 0th row: top; 0th column: right
+'exif-orientation-3' => 'מסובב 180°', # 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'הפוך אנכית', # 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'מסובב 90° נגד כיוון השעון והפוך אנכית', # 0th row: left; 0th column: top
+'exif-orientation-6' => 'מסובב 90° עם כיוון השעון', # 0th row: right; 0th column: top
+'exif-orientation-7' => 'מסובב 90° עם כיוון השעון והפוך אנכית', # 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'מסובב 90° נגד כיוון השעון', # 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'פורמט חסון',
+'exif-planarconfiguration-2' => 'פורמט שטוח',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'אינו קיים',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'לא הוגדרה',
+'exif-exposureprogram-1' => 'ידנית',
+'exif-exposureprogram-2' => 'תוכנה רגילה',
+'exif-exposureprogram-3' => 'עדיפות פתח',
+'exif-exposureprogram-4' => 'עדיפות צמצם',
+'exif-exposureprogram-5' => 'תוכנה יוצרת (מטה לכיוון עומק השדה)',
+'exif-exposureprogram-6' => 'תוכנה פועלת (מטה לכיוון מהירות צמצם גבוהה)',
+'exif-exposureprogram-7' => 'מצב דיוקן (לתמונות צילום מקרוב כשהרקע לא בפוקוס)',
+'exif-exposureprogram-8' => 'מצב נוף (לתמונות נוף כשהרקע בפוקוס)',
+
+'exif-subjectdistance-value' => '$1 מטרים',
+
+'exif-meteringmode-0' => 'לא ידוע',
+'exif-meteringmode-1' => 'ממוצע',
+'exif-meteringmode-2' => 'מרכז משקל ממוצע',
+'exif-meteringmode-3' => 'נקודה',
+'exif-meteringmode-4' => 'רב־נקודה',
+'exif-meteringmode-5' => 'תבנית',
+'exif-meteringmode-6' => 'חלקי',
+'exif-meteringmode-255' => 'אחר',
+
+'exif-lightsource-0' => 'לא ידוע',
+'exif-lightsource-1' => 'אור יום',
+'exif-lightsource-2' => 'פלואורסצנטי',
+'exif-lightsource-3' => 'טונגסטן (אור מתלהט)',
+'exif-lightsource-4' => 'פלש',
+'exif-lightsource-9' => 'מזג אוויר טוב',
+'exif-lightsource-10' => 'מזג אוויר מעונן',
+'exif-lightsource-11' => 'צל',
+'exif-lightsource-12' => 'אור יום פלואורסצנטי (D 5700 – 7100K)',
+'exif-lightsource-13' => 'אור יום לבן פלואורסצנטי (N 4600 – 5400K)',
+'exif-lightsource-14' => 'אור יום קריר לבן פלואורסצנטי (W 3900 – 4500K)',
+'exif-lightsource-15' => 'פלואורסצנטי לבן (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'אור רגיל A',
+'exif-lightsource-18' => 'אור רגיל B',
+'exif-lightsource-19' => 'אור רגיל C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'טונגסטן אולפן ISO',
+'exif-lightsource-255' => 'מקור אור אחר',
+
+'exif-focalplaneresolutionunit-2' => "אינצ'ים",
+
+'exif-sensingmethod-1' => 'לא מוגדרת',
+'exif-sensingmethod-2' => 'חיישן אזור בצבע עם שבב אחד',
+'exif-sensingmethod-3' => 'חיישן אזור בצבע עם שני שבבים',
+'exif-sensingmethod-4' => 'חיישן אזור בצבע עם שלושה שבבים',
+'exif-sensingmethod-5' => 'חיישן אזור עם צבע רציף',
+'exif-sensingmethod-7' => 'חיישן טריליניארי',
+'exif-sensingmethod-8' => 'חיישן עם צבע רציף ליניארי',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'תמונה שצולמה ישירות',
+
+'exif-customrendered-0' => 'תהליך רגיל',
+'exif-customrendered-1' => 'תהליך מותאם',
+
+'exif-exposuremode-0' => 'חשיפה אוטומטית',
+'exif-exposuremode-1' => 'חשיפה ידנית',
+'exif-exposuremode-2' => 'מסגרת אוטומטית',
+
+'exif-whitebalance-0' => 'איזון צבע לבן אוטומטי',
+'exif-whitebalance-1' => 'איזון צבע לבן ידני',
+
+'exif-scenecapturetype-0' => 'רגיל',
+'exif-scenecapturetype-1' => 'נוף',
+'exif-scenecapturetype-2' => 'דיוקן',
+'exif-scenecapturetype-3' => 'סצנה לילית',
+
+'exif-gaincontrol-0' => 'ללא',
+'exif-gaincontrol-1' => 'תוספת נמוכה למעלה',
+'exif-gaincontrol-2' => 'תוספת גבוהה למעלה',
+'exif-gaincontrol-3' => 'תוספת נמוכה למטה',
+'exif-gaincontrol-4' => 'תוספת גבוהה למטה',
+
+'exif-contrast-0' => 'רגיל',
+'exif-contrast-1' => 'רך',
+'exif-contrast-2' => 'קשה',
+
+'exif-saturation-0' => 'רגילה',
+'exif-saturation-1' => 'רוויה נמוכה',
+'exif-saturation-2' => 'רוויה גבוהה',
+
+'exif-sharpness-0' => 'רגילה',
+'exif-sharpness-1' => 'רכה',
+'exif-sharpness-2' => 'קשה',
+
+'exif-subjectdistancerange-0' => 'לא ידוע',
+'exif-subjectdistancerange-1' => 'מאקרו',
+'exif-subjectdistancerange-2' => 'תצוגה קרובה',
+'exif-subjectdistancerange-3' => 'תצוגה רחוקה',
+
+# Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'קו־רוחב צפוני',
+'exif-gpslatitude-s' => 'קו־רוחב דרומי',
+
+# Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'קו־אורך מזרחי',
+'exif-gpslongitude-w' => 'קו־אורך מערבי',
+
+'exif-gpsstatus-a' => 'מדידה בתהליך',
+'exif-gpsstatus-v' => 'מדידה בו־זמנית',
+
+'exif-gpsmeasuremode-2' => 'מדידה בשני ממדים',
+'exif-gpsmeasuremode-3' => 'מדידה בשלושה ממדים',
+
+# Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'קילומטרים בשעה',
+'exif-gpsspeed-m' => 'מיילים בשעה',
+'exif-gpsspeed-n' => 'מיילים ימיים בשעה',
+
+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'כיוון אמיתי',
+'exif-gpsdirection-m' => 'כיוון מגנטי',
+
+# External editor support
+'edit-externally' => 'ערכו קובץ זה באמצעות יישום חיצוני',
+'edit-externally-help' => 'ראו את [http://meta.wikimedia.org/wiki/Help:External_editors הוראות ההתקנה] למידע נוסף.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'הכול',
+'imagelistall' => 'הכול',
+'watchlistall1' => 'הכול',
+'watchlistall2' => 'הכול',
+'namespacesall' => 'הכול',
+
+# E-mail address confirmation
+'confirmemail' => 'אמתו כתובת דוא"ל',
+'confirmemail_noemail' => 'אין לכם כתובת דוא"ל תקפה המוגדרת ב[[{{ns:special}}:Preferences|העדפות המשתמש]] שלכם.',
+'confirmemail_text' => 'אתר זה דורש שתאמתו את כתובת הדוא"ל שלכם לפני שתשתמשו בשירותי הדוא"ל. לחצו על הכפתור למטה כדי לשלוח דוא"ל עם קוד אישור לכתובת הדוא"ל שהזנתם. טענו את הקישור בדפדפן שלכם כדי לאשר שכתובת הדוא"ל תקפה.',
+'confirmemail_pending' => '<div class="error">קוד אישור דוא"ל כבר נשלח אליכם; אם יצרתם את החשבון לאחרונה, ייתכן שתרצו לחכות מספר דקות עד שיגיע לפני שתנסו לבקש קוד חדש.</div>',
+'confirmemail_send' => 'שלח קוד אישור',
+'confirmemail_sent' => 'הדוא"ל עם קוד האישור נשלח.',
+'confirmemail_oncreate' => 'קוד אישור דוא"ל נשלח לכתובת הדוא"ל שלכם. הקוד הזה אינו נדרש לכניסה, אך תצטרכו לספקו כדי להשתמש בכל תכונה מבוססת דוא"ל באתר זה.',
+'confirmemail_sendfailed' => 'שליחת הדוא"ל עם קוד האישור לא הצליחה. אנא בדקו שאין תווים שגויים בכתובת.
+
+תוכנת הדואר החזירה את ההודעה הבאה: $1',
+'confirmemail_invalid' => 'קוד האישור שגוי. ייתכן שפג תוקפו.',
+'confirmemail_needlogin' => 'עליכם לבצע $1 כדי לאמת את כתובת הדוא"ל שלכם.',
+'confirmemail_success' => 'כתובת הדוא"ל שלכם אושרה. כעת באפשרותכם להיכנס לחשבון שלכם וליהנות מהאתר.',
+'confirmemail_loggedin' => 'כתובת הדוא"ל שלכם אושרה כעת.',
+'confirmemail_error' => 'שגיאה בשמירת קוד האישור.',
+'confirmemail_subject' => 'קוד אישור דוא"ל מ{{grammar:תחילית|{{SITENAME}}}}',
+'confirmemail_body' => 'מישהו, כנראה אתם (מכתובת ה־IP הזו: $1), רשם את החשבון "$2" עם כתובת הדוא"ל הזו ב{{grammar:תחילית|{{SITENAME}}}}.
+
+כדי לוודא שחשבון זה באמת שייך לכם ולהפעיל את שירותי הדוא"ל באתר, אנא פתחו את הכתובת הבאה בדפדפן שלכם:
+
+$3
+
+אם *לא* אתם ביקשתם קוד אישור זה, אל תפתחו את הקישור. קוד האישור יפקע ב־$4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'מצאו התאמה מדויקת',
+'searchfulltext' => 'חפשו בכל הדף',
+'createarticle' => 'צרו דף',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[הכללת תבניות בין אתרים מנוטרלת]',
+'scarytranscludefailed' => '[מצטערים, קבלת התבנית נכשלה בגלל $1]',
+'scarytranscludetoolong' => '[מצטערים, כתובת ה־URL ארוכה מדי]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+טרקבקים לדף זה:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 מחיקה])',
+'trackbacklink' => 'טרקבק',
+'trackbackdeleteok' => 'הטרקבק נמחק בהצלחה.',
+
+# Delete conflict
+'deletedwhileediting' => 'אזהרה: דף זה נמחק לאחר שהתחלתם לערוך!',
+'confirmrecreate' => "המשתמש [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|שיחה]]) מחק את הדף לאחר שהתחלת לערוך אותו, מסיבה זו:
+:'''$2'''
+אנא אשרו שאתם אכן רוצים ליצור מחדש את הדף.",
+'recreate' => 'צור מחדש',
+'tooltip-recreate' => 'צור מחדש את הדף למרות שהוא נמחק',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'מפנה ל־[[$1]]…',
+
+# action=purge
+'confirm_purge' => 'לנקות את המטמון של דף זה?
+
+$1',
+'confirm_purge_button' => 'אישור',
+
+'youhavenewmessagesmulti' => 'יש לך הודעות חדשות ב־$1',
+
+'searchcontaining' => "חפש דפים המכילים את הטקסט '''$1'''.",
+'searchnamed' => "חפש דפים בשם '''$1'''.",
+'articletitles' => "חפש דפים המתחילים עם '''$1'''",
+'hideresults' => 'הסתר תוצאות',
+
+# DISPLAYTITLE
+'displaytitle' => '(קשרו לדף זה בשם [[$1]])',
+
+'loginlanguagelabel' => 'שפה: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&rarr; לדף הקודם',
+'imgmultipagenext' => 'לדף הבא &larr;',
+'imgmultigo' => 'עבור!',
+'imgmultigotopre' => 'עבור לדף',
+
+# Table pager
+'ascending_abbrev' => 'עולה',
+'descending_abbrev' => 'יורד',
+'table_pager_next' => 'הדף הבא',
+'table_pager_prev' => 'הדף הקודם',
+'table_pager_first' => 'הדף הראשון',
+'table_pager_last' => 'הדף האחרון',
+'table_pager_limit' => 'הצג $1 פריטים בדף',
+'table_pager_limit_submit' => 'עבור',
+'table_pager_empty' => 'ללא תוצאות',
+
+# Auto-summaries
+'autosumm-blank' => 'מסיר את כל התוכן מדף זה',
+'autosumm-replace' => "מחליף את הדף עם '$1'",
+'autoredircomment' => 'הפניה לדף [[$1]]', # This should be changed to the new naming convention, but existed beforehand
+'autosumm-new' => 'דף חדש: $1',
+
+# Size units
+'size-bytes' => '$1 בייט',
+'size-kilobytes' => '$1 קילו־בייט',
+'size-megabytes' => '$1 מגה־בייט',
+'size-gigabytes' => "$1 ג'יגה־בייט",
+
+);
+
+?>
diff --git a/languages/messages/MessagesHi.php b/languages/messages/MessagesHi.php
new file mode 100644
index 000000000000..6e2630bebf3c
--- /dev/null
+++ b/languages/messages/MessagesHi.php
@@ -0,0 +1,127 @@
+<?php
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'विशेष',
+ NS_MAIN => '',
+ NS_TALK => 'वार्ता',
+ NS_USER => 'सदस्य',
+ NS_USER_TALK => 'सदस्य_वार्ता',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_वार्ता',
+ NS_IMAGE => 'चित्र',
+ NS_IMAGE_TALK => 'चित्र_वार्ता',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Template_talk',
+ NS_CATEGORY => 'श्रेणी',
+ NS_CATEGORY_TALK => 'श्रेणी_वार्ता',
+);
+
+$digitTransformTable = array(
+ "0" => "०",
+ "1" => "१",
+ "2" => "२",
+ "3" => "३",
+ "4" => "४",
+ "5" => "५",
+ "6" => "६",
+ "7" => "७",
+ "8" => "८",
+ "9" => "९"
+);
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+
+$messages = array(
+
+# Dates
+#
+'sunday' => "रविवार",
+'monday' => "सोमवार",
+'tuesday' => "मंगलवार",
+'wednesday' => "बुधवार",
+'thursday' => "गुरुवार",
+'friday' => "शुक्रवार",
+'saturday' => "शनिवार",
+'january' => "जनवरी",
+'february' => "फरवरी",
+'march' => "मार्च",
+'april' => "अप्रैल",
+'may_long' => "मई",
+'june' => "जून",
+'july' => "जुलाई",
+'august' => "अगस्त",
+'september' => "सितम्बर",
+'october' => "अक्टूबर",
+'november' => "नवम्बर",
+'december' => "दिसम्बर",
+'jan' => "जनवरी",
+'feb' => "फरवरी",
+'mar' => "मार्च",
+'apr' => "अप्रैल",
+'may' => "मई",
+'jun' => "जून",
+'jul' => "जुलाई",
+'aug' => "अगस्त",
+'sep' => "सितम्बर",
+'oct' => "अक्टूबर",
+'nov' => "नवम्बर",
+'dec' => "दिसम्बर",
+
+# Bits of text used by many pages:
+#
+"mainpage" => "मुख्य पृष्ठ",
+"about" => "अबाउट",
+"aboutsite" => "{{SITENAME}} के बारे में",
+"aboutpage" => "{{ns:project}}:अबाउट",
+"help" => "सहायता",
+"helppage" => "{{ns:project}}:सहायता",
+"mypage" => "मेरा पृष्ठ",
+"mytalk" => "मेरी बातें",
+"returnto" => "लौटें $1.",
+"search" => "खोज",
+"searchbutton" => "खोज",
+"go" => "जायें",
+'searcharticle' => "जायें",
+"editthispage" => "इस पृष्ठ को बदलें",
+"deletethispage" => "इस पृष्ठ को हटायें",
+"protectthispage" => "इस पृष्ठ को सुरक्षित करें",
+"unprotectthispage" => "इस पृष्ठ को असुरक्षित करें",
+"newpage" => "नया पृष्ठ",
+"talkpage" => "इस पृष्ठ के बारे में बात करें",
+"articlepage" => "लेख देखें",
+"userpage" => "सदस्य पृष्ठ देखें",
+"projectpage" => "मेटा पृष्ठ देखें",
+"imagepage" => "चित्र पृष्ठ देखें",
+"viewtalkpage" => "चर्चा देखें",
+"otherlanguages" => "अन्य भाषायें",
+"redirectedfrom" => "($1 से भेजा गया)",
+"lastmodifiedat" => "अन्तिम परिवर्तन $2, $1.",
+"viewcount" => "यह पृष्ठ $1 बार देखा गया है",
+"protectedpage" => "सुरक्षित पृष्ठ",
+"retrievedfrom" => "\"$1\" से लिया गया",
+
+# Main script and global functions
+#
+"nosuchaction" => "ऐसा कोई कार्य नहीं है",
+"nosuchactiontext" => "{{SITENAME}} सौफ़्टवेयर में इस URL द्वारा निर्धारित कोई क्रिया नही है",
+"nosuchspecialpage" => "ऐसा कोई विशेष पृष्ठ नहीं है",
+"nospecialpagetext" => "आपने ऐसा विशेष पृष्ठ मांगा है जो {{SITENAME}} सौफ़्टवेयर में नहीं है.",
+
+# General errors
+# ........
+
+"welcomecreation" => "<h2>स्वागतम्‌, $1!</h2><p>आपका अकाउन्ट बना दिया गया है.
+Don't forget to personalize your {{SITENAME}} preferences.",
+
+"yourname" => "आपका नाम",
+"yourpassword" => "आपका पासवर्ड",
+"yourpasswordagain" => "पासवर्ड दुबारा लिखें",
+
+## ....... more messages .....
+);
+
+
+?>
diff --git a/languages/messages/MessagesHr.php b/languages/messages/MessagesHr.php
new file mode 100644
index 000000000000..b43717817561
--- /dev/null
+++ b/languages/messages/MessagesHr.php
@@ -0,0 +1,1559 @@
+<?php
+/** Croatian (hrvatski)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+
+$quickbarSettings = array(
+ 'Bez', 'Lijevo nepomično', 'Desno nepomično', 'Lijevo leteće'
+);
+
+$skinNames = array(
+ 'standard' => 'Standardna',
+ 'nostalgia' => 'Nostalgija',
+ 'cologneblue' => 'Kölnska plava',
+ 'smarty' => 'Paddington',
+ 'montparnasse' => 'Montparnasse',
+ 'davinci' => 'DaVinci',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'MySkin',
+ 'chick' => 'Chick'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Mediji',
+ NS_SPECIAL => 'Posebno',
+ NS_MAIN => '',
+ NS_TALK => 'Razgovor',
+ NS_USER => 'Suradnik',
+ NS_USER_TALK => 'Razgovor_sa_suradnikom',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Razgovor_$1',
+ NS_IMAGE => 'Slika',
+ NS_IMAGE_TALK => 'Razgovor_o_slici',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_razgovor',
+ NS_TEMPLATE => 'Predložak',
+ NS_TEMPLATE_TALK => 'Razgovor_o_predlošku',
+ NS_HELP => 'Pomoć',
+ NS_HELP_TALK => 'Razgovor_o_pomoći',
+ NS_CATEGORY => 'Kategorija',
+ NS_CATEGORY_TALK => 'Razgovor_o_kategoriji'
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. F Y.',
+ 'dmy both' => 'H:i, j. F Y.',
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$fallback8bitEncoding = 'iso-8859-2';
+$linkTrail = '/^([čšžćđßa-z]+)(.*)$/sDu';
+
+
+$messages = array(
+'tog-underline' => 'Podcrtane poveznice',
+'tog-highlightbroken' => 'Istakni prazne poveznice drugom bojom (inače, upitnikom na kraju).',
+'tog-justify' => 'Poravnaj odlomke i zdesna',
+'tog-hideminor' => 'Sakrij manje izmjene na stranici "Nedavne promjene"',
+'tog-usenewrc' => 'Poboljšan izgled Nedavnih promjena (nije za sve preglednike)',
+'tog-numberheadings' => 'Automatski označi naslove brojevima',
+'tog-showtoolbar' => 'Prikaži traku s alatima za uređivanje',
+'tog-editondblclick' => 'Dvoklik otvara uređivanje stranice (JavaScript)',
+'tog-editsection' => 'Prikaži poveznice za uređivanje pojedinih odlomaka',
+'tog-editsectiononrightclick'=> 'Pritiskom na desnu tipku miša otvori uređivanje pojedinih odlomaka (JavaScript)',
+'tog-showtoc' => 'U člancima s više od tri odlomka prikaži tablicu sadržaja.',
+'tog-rememberpassword' => 'Zapamti lozinku između prijava',
+'tog-editwidth' => 'Okvir za uređivanje zauzima cijelu širinu',
+'tog-watchcreations' => 'Dodaj članke koje kreiram na moju listu praćenja',
+'tog-watchdefault' => 'Postavi sve nove i izmijenjene stranice u popis praćenja',
+'tog-minordefault' => 'Normalno označavaj sve moje izmjene kao manje',
+'tog-previewontop' => 'Prikaži kako će stranica izgledati iznad okvira za uređivanje',
+'tog-previewonfirst' => 'Prikaži kako će stranica izgledati čim otvorim uređivanje',
+'tog-nocache' => 'Isključi međuspremnik (cache) stranica.',
+'tog-enotifwatchlistpages'=> 'Pošalji mi e-mail kod izmjene stranice u popisu praćenja',
+'tog-enotifusertalkpages'=> 'Pošalji mi e-mail kod izmjene moje stranice za razgovor',
+'tog-enotifminoredits' => 'Pošalji mi e-mail i kod manjih izmjena',
+'tog-enotifrevealaddr' => 'Prikaži moju e-mail adresu u obavijestima o izmjeni',
+'tog-shownumberswatching'=> 'Prikaži broj suradnika koji prate stranicu (u nedavnim izmjenama, popisu praćenja i samim člancima)',
+'tog-fancysig' => 'Običan potpis (bez automatske poveznice)',
+'tog-externaleditor' => 'Uvijek koristi vanjski editor',
+'tog-externaldiff' => 'Uvijek koristi vanjski program za usporedbu',
+'tog-showjumplinks' => 'Uključi pomoćne poveznice "Skoči na"',
+'tog-uselivepreview' => 'Uključi trenutačni pretpregled (JavaScript) (eksperimentalno)',
+'tog-autopatrol' => 'Označi moje promjena več provjerenima',
+'tog-forceeditsummary' => 'Podsjeti me ako sažetak uređivanja ostavljam praznim',
+'underline-always' => 'Uvijek',
+'underline-never' => 'Nikad',
+'underline-default' => 'Prema postavkama preglednika',
+'skinpreview' => '(Pregled)',
+'sunday' => 'nedjelja',
+'monday' => 'ponedjeljak',
+'tuesday' => 'utorak',
+'wednesday' => 'srijeda',
+'thursday' => 'četvrtak',
+'friday' => 'petak',
+'saturday' => 'subota',
+'january' => 'siječnja',
+'february' => 'veljače',
+'march' => 'ožujka',
+'april' => 'travnja',
+'may_long' => 'svibnja',
+'june' => 'lipnja',
+'july' => 'srpnja',
+'august' => 'kolovoza',
+'september' => 'rujna',
+'october' => 'listopada',
+'november' => 'studenog',
+'december' => 'prosinca',
+'jan' => 'sij',
+'feb' => 'velj',
+'mar' => 'ožu',
+'apr' => 'tra',
+'may' => 'svi',
+'jun' => 'lip',
+'jul' => 'srp',
+'aug' => 'kol',
+'sep' => 'ruj',
+'oct' => 'lis',
+'nov' => 'stu',
+'dec' => 'pro',
+'categories' => 'Kategorije',
+'pagecategories' => '{{PLURAL:$1|Kategorija|Kategorije}}',
+'category_header' => 'Članci u kategoriji "$1"',
+'subcategories' => 'Potkategorije',
+'mainpage' => 'Glavna stranica',
+'mainpagetext' => 'Softver Wiki je uspješno instaliran.',
+'mainpagedocfooter' => 'Pogledajte [http://meta.wikimedia.org/wiki/MediaWiki_i18n dokumentaciju o prilagodbi sučelja]
+i [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Vodič za suradnike] za pomoć pri uporabi i podešavanju.',
+'portal' => 'Portal zajednice',
+'about' => 'O',
+'aboutsite' => 'O projektu {{SITENAME}}',
+'aboutpage' => 'Project:O_projektu_{{SITENAME}}',
+'article' => 'Članak',
+'help' => 'Pomoć',
+'helppage' => 'Project:Pomoć',
+'bugreports' => 'Poruke o programskim greškama',
+'bugreportspage' => 'Project:Poruke_o_programskim_greškama',
+'sitesupport' => 'Novčani prilozi',
+'faq' => 'Najčešća pitanja',
+'faqpage' => '{{ns:project}}:FAQ',
+'edithelp' => 'Kako uređivati stranicu',
+'newwindow' => '(otvara se u novom prozoru)',
+'edithelppage' => '{{ns:project}}:Kako_uređivati_stranicu',
+'cancel' => 'Odustani',
+'qbfind' => 'Nađi',
+'qbbrowse' => 'Pregledaj',
+'qbedit' => 'Uredi',
+'qbpageoptions' => 'Postavke stranice',
+'qbpageinfo' => 'O stranici',
+'qbmyoptions' => 'Moje stranice',
+'qbspecialpages' => 'Posebne stranice',
+'moredotdotdot' => 'Više...',
+'mypage' => 'Moja stranica',
+'mytalk' => 'Moj razgovor',
+'anontalk' => 'Razgovor za ovu IP adresu',
+'navigation' => 'Orijentacija',
+'currentevents' => 'Aktualno',
+'disclaimers' => 'Odricanje od odgovornosti',
+'disclaimerpage' => '{{ns:4}}:General_disclaimer',
+'privacy' => 'Zaštita privatnosti',
+'errorpagetitle' => 'Greška',
+'returnto' => 'Vrati se na $1.',
+'tagline' => 'Izvor: {{SITENAME}}',
+'search' => 'Traži',
+'searchbutton' => 'Traži',
+'go' => 'Kreni',
+'searcharticle' => 'Kreni',
+'history' => 'Stare izmjene',
+'history_short' => 'Stare izmjene',
+'updatedmarker' => 'obnovljeno od zadnjeg posjeta',
+'info_short' => 'Informacija',
+'printableversion' => 'Verzija za ispis',
+'permalink' => 'Trajna poveznica',
+'print' => 'Ispiši',
+'edit' => 'Uredi',
+'editthispage' => 'Uredi ovu stranicu',
+'delete' => 'Izbriši',
+'deletethispage' => 'Izbriši ovu stranicu',
+'undelete_short' => 'Vrati $1 uređivanja',
+'protect' => 'Zaštiti',
+'protectthispage' => 'Zaštiti ovu stranicu',
+'unprotect' => 'Ukloni zaštitu',
+'unprotectthispage' => 'Ukloni zaštitu s ove stranice',
+'newpage' => 'Nova stranica',
+'talkpage' => 'Razgovor o ovoj stranici',
+'specialpage' => 'Posebna stranica',
+'personaltools' => 'Osobni alati',
+'postcomment' => 'Napiši komentar',
+'articlepage' => 'Vidi članak',
+'talk' => 'Razgovor',
+'views' => 'Pogledi',
+'toolbox' => 'Traka s alatima',
+'userpage' => 'Vidi suradnikovu stranicu',
+'projectpage' => 'Vidi stranicu o projektu',
+'imagepage' => 'Vidi stranicu slike',
+'viewtalkpage' => 'Vidi razgovor',
+'otherlanguages' => 'Drugi jezici',
+'redirectedfrom' => '(Preusmjereno s $1)',
+'redirectpagesub' => 'Preusmjeravanje',
+'lastmodifiedat' => 'Datum zadnje promjene na ovoj stranici: $2, $1',
+'viewcount' => 'Ova stranica je pogledana $1 puta.',
+'copyright' => 'Sadržaji se koriste u skladu s $1.',
+'protectedpage' => 'Zaštićena stranica',
+'jumpto' => 'Skoči na:',
+'jumptonavigation' => 'orijentacija',
+'jumptosearch' => 'traži',
+'badaccess' => 'Greška u ovlaštenjima',
+'versionrequired' => 'Potrebna inačica $1 MediaWikija',
+'versionrequiredtext' => 'Za korištenje ove stranice potrebna je inačica $1 MediaWiki softvera. Pogledaj [[Special:Version]]',
+'ok' => 'U redu',
+'retrievedfrom' => 'Dobavljeno iz "$1"',
+'youhavenewmessages' => 'Imate $1 ($2).',
+'newmessageslink' => 'nove poruke',
+'newmessagesdifflink' => 'zadnja promjena na stranici za razgovor',
+'editsection' => 'uredi',
+'editold' => 'uredi',
+'editsectionhint' => 'Uređivanje odlomka: $1',
+'toc' => 'Sadržaj',
+'showtoc' => 'prikaži',
+'hidetoc' => 'sakrij',
+'thisisdeleted' => 'Vidi ili vrati $1?',
+'viewdeleted' => 'Vidi $1?',
+'restorelink' => '$1 pobrisanih izmjena',
+'nstab-main' => 'Članak',
+'nstab-user' => 'Stranica suradnika',
+'nstab-media' => 'Mediji',
+'nstab-special' => 'Posebno',
+'nstab-project' => 'Stranica o projektu',
+'nstab-image' => 'Slika',
+'nstab-mediawiki' => 'Poruka',
+'nstab-template' => 'Predložak',
+'nstab-help' => 'Pomoć',
+'nstab-category' => 'Kategorija',
+'nosuchaction' => 'Nema takve naredbe',
+'nosuchactiontext' => 'Navedeni URL označava
+nepostojeću naredbu',
+'nosuchspecialpage' => 'Posebna stranica ne postoji',
+'nospecialpagetext' => 'Takva posebna stranica ne postoji.',
+'error' => 'Greška',
+'databaseerror' => 'Greška baze podataka',
+'dberrortext' => 'Došlo je do sintaksne pogreške s upitom bazi.
+Možda se radi o bugu u softveru.
+Posljednji pokušaj upita je glasio:
+<blockquote><tt>$1</tt></blockquote>
+iz funkcije "<tt>$2</tt>".
+MySQL je vratio pogrešku "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Došlo je do sintaksne pogreške s upitom bazi.
+Možda se radi o bugu u softveru.
+Posljednji pokušaj upita je glasio:
+"$1"
+iz funkcije "<tt>$2</tt>".
+MySQL je vratio pogrešku "<tt>$3: $4</tt>".',
+'noconnect' => 'Oprostite! Wiki trenutno ima tehničkih problema i ne može se povezati s bazom podataka. $1',
+'nodb' => 'Nije bilo moguće odabrati bazu podataka $1',
+'cachederror' => 'Ova je verzija stranice iz međuspremnika i možda ne sadrži sve promjene.',
+'laggedslavemode' => 'Upozorenje: na stranici se možda ne nalaze najnovije promjene.',
+'readonly' => 'Baza podataka je zaključana',
+'enterlockreason' => 'Upiši razlog zaključavanja i procjenu vremena otključavanja',
+'readonlytext' => 'Baza podataka je trenutno zaključana, nije ju moguće uređivati ili mijenjati. Ovo je obično pokazatelj tekućeg redovitog održavanja. Nakon što se potonja privremena akcija završi, baza podataka će se vratiti u uobičajeno stanje.
+
+Administrator koji je izvršio zaključavanje naveo je ovaj razlog: $1',
+'missingarticle' => 'U bazi podataka nije pronađena stranica "$1" koja je trebala biti pronađena.
+
+Ovo se najčešće događa zbog poveznice na zastarjelu usporedbu ili staru promjenu stranice koja je u međuvremenu izbrisana.
+
+Ako to nije slučaj, možda se radi o softverskoj grešci. Molimo da u tom slučaju pošaljete poruku administratoru navodeći URL.',
+'readonly_lag' => 'Baza podataka je automatski zaključana dok se sekundarni bazni poslužitelji ne usklade s glavnim',
+'internalerror' => 'Greška sustava',
+'filecopyerror' => 'Ne mogu kopirati datoteku "$1" u "$2".',
+'filerenameerror' => 'Ne mogu preimenovati datoteku "$1" u "$2".',
+'filedeleteerror' => 'Ne mogu obrisati datoteku "$1".',
+'filenotfound' => 'Datoteka "$1" nije nađena.',
+'unexpected' => 'Neočekivana vrijednost: "$1"="$2".',
+'formerror' => 'Greška: Ne mogu poslati podatke',
+'badarticleerror' => 'Ovu radnju nije moguće izvesti s tom stranicom.',
+'cannotdelete' => 'Ne mogu obrisati navedenu stranicu ili sliku. (Moguće da je već obrisana.)',
+'badtitle' => 'Loš naslov',
+'badtitletext' => 'Navedeni naslov stranice nepravilan ili loše formirana interwiki poveznica.',
+'perfdisabled' => 'Privremeno onemogućeno. Koristite kopiju snimljenu $1:',
+'perfdisabledsub' => 'Ovo je snimljena kopija $1:',
+'perfcached' => 'Sljedeći podaci su iz međuspremnika i možda nisu najsvježiji:',
+'wrong_wfQuery_params' => 'Neispravni parametri poslani u wfQuery()<br />
+Funkcija: $1<br />
+Upit: $2',
+'viewsource' => 'Vidi izvornik',
+'viewsourcefor' => 'za $1',
+'protectedtext' => 'Ova je stranica zaključana čime je onemogućeno njeno uređivanje; za ovo postoji nekoliko mogućih razloga, molim pogledajte članak [[{{ns:4}}:Protected page|Zaštićena stranica]].
+
+Možete pogledati izvorni kod ove stranice i kopirati ga:',
+'sqlhidden' => '(SQL upit sakriven)',
+'logouttitle' => 'Odjava suradnika',
+'logouttext' => 'Odjavili ste se.<br />
+Možete nastaviti s korištenjem projekta {{SITENAME}} anonimno,
+ili se možete ponovo prijaviti pod istim ili drugim imenom. Neke se stranice mogu
+prikazivati kao da ste još uvijek prijavljeni, sve dok ne očistite međuspremnik svog preglednika.',
+'welcomecreation' => '== Dobrodošli, $1! ==
+
+Vaš je suradnički račun otvoren. Ne zaboravite podesiti korisničke postavke.',
+'loginpagetitle' => 'Prijava suradnika',
+'yourname' => 'Suradničko ime',
+'yourpassword' => 'Upišite lozinku',
+'yourpasswordagain' => 'Ponovno upišite lozinku',
+'remembermypassword' => 'Trajno zapamti moju lozinku.',
+'yourdomainname' => 'Vaša domena',
+'externaldberror' => 'Došlo je do greške s vanjskom autorizacijom ili vam nije dozvoljeno osvježavanje vanjskog suradničkog računa.',
+'loginproblem' => '<b>Došlo je do greške s vašom prijavom.</b><br />Pokušajte iznova!',
+'alreadyloggedin' => '<strong>Suradniče $1, već ste prijavljeni!</strong><br />',
+'login' => 'Prijavi se',
+'loginprompt' => 'Za prijavu na sustav {{SITENAME}} morate u pregledniku uključiti kolačiće (cookies).',
+'userlogin' => 'Prijavi se',
+'logout' => 'Odjavi se',
+'userlogout' => 'Odjavi se',
+'notloggedin' => 'Niste prijavljeni',
+'nologin' => 'Nemate suradničko ime? $1.',
+'nologinlink' => 'Otvorite račun',
+'createaccount' => 'Otvori novi suradnički račun',
+'gotaccount' => 'Već imate suradnički račun? $1.',
+'gotaccountlink' => 'Prijavite se',
+'createaccountmail' => 'poštom',
+'badretype' => 'Unesene lozinke nisu istovjetne.',
+'userexists' => 'Uneseno suradničko ime već je u upotrebi. Unesite neko drugo ime.',
+'youremail' => 'Vaša elektronska pošta *',
+'username' => 'Suradničko ime:',
+'uid' => 'Suradnički ID-broj:',
+'yourrealname' => 'Pravo ime (nije obvezno)*',
+'yournick' => 'Vaš nadimak (za potpisivanje)',
+'badsig' => 'Kôd vašeg potpisa nije valjan; provjerite HTML tagove.',
+'email' => 'Adresa elektronske pošte *',
+'prefs-help-email-enotif'=> 'Ova će se adresa koristiti i za slanje izvješća o promjenama u wikiju, ako ih uključite.',
+'prefs-help-realname' => '* Pravo ime (nije obvezno): za pravnu atribuciju vaših doprinosa.',
+'loginerror' => 'Greška u prijavi',
+'prefs-help-email' => '* E-mail (nije obvezno): Omogućuje drugima da vas kontaktiraju na suradničkoj stranici ili stranici za razgovor bez javnog otkrivanja vaše e-mail adrese.
+Također, ako zaboravite lozinku možemo vam na ovu adresu poslati novu, privremenu.',
+'nocookiesnew' => 'Suradnički račun je otvoren, ali niste uspješno prijavljeni. Naime, {{SITENAME}} koristi kolačiće (\'\'cookies\'\') u procesu prijave. Isključili ste kolačiće. Molim uključite ih i pokušajte ponovo s vašim novim imenom i lozinkom.',
+'nocookieslogin' => '{{SITELOGIN}} koristi kolačiće (\'\'cookies\'\') u procesu prijave. Isključili ste kolačiće. Molim uključite ih i pokušajte ponovo.',
+'noname' => 'Niste unijeli valjano suradničko ime.',
+'loginsuccesstitle' => 'Prijava uspješna',
+'loginsuccess' => 'Prijavili ste se na wiki kao "$1".',
+'nosuchuser' => 'Ne postoji suradnik s imenom "$1". Provjerite jeste li točno utipkali, ili otvorite novi suradnički račun koristeći donji obrazac.',
+'nosuchusershort' => 'Ne postoji suradnik s imenom "$1". Provjerite vaš unos.',
+'wrongpassword' => 'Lozinka koju ste unijeli nije ispravna. Pokušajte ponovno.',
+'wrongpasswordempty' => 'Niste unijeli lozinku. Pokušajte ponovno.',
+'mailmypassword' => 'Pošalji mi novu lozinku',
+'passwordremindertitle' => '{{SITENAME}}: nova lozinka.',
+'passwordremindertext' => 'Netko je (vjerojatno vi, s IP adrese $1)
+zatražio da vam pošaljemo novu lozinku za sustav {{SITENAME}} ($4).
+Lozinka za suradnika "$2" je postavljena na "$3".
+Molimo vas da se odmah prijavite i promijenite lozinku.
+
+Ukoliko niste zatražili novu lozinku, ili ste se sjetili stare lozinke i
+više ju ne želite promijeniti, slobodno zanemarite ovu poruku i nastavite
+koristiti staru lozinku.',
+'noemail' => 'Suradnik "$1" nema zapisanu e-mail adresu.',
+'passwordsent' => 'Nova je lozinka poslana na e-mail adresu suradnika "$1"',
+'eauthentsent' => 'Na navedenu adresu poslan je e-mail s potvrdom. Prije nego što pošaljemo daljnje poruke,
+molimo vas da otvorite e-mail i slijedite u njemu sadržana uputstva.',
+'mailerror' => 'Greška pri slanju e-maila: $1',
+'acct_creation_throttle_hit'=> 'Nažalost, ne možete otvoriti nove suradničke račune. Već ste otvorili $1.',
+'emailauthenticated' => 'Vaša e-mail adresa je ovjerena $1.',
+'emailnotauthenticated' => 'Vaša e-mail adresa još nije ovjerena.
+Ne možemo poslati e-mail ni u jednoj od sljedećih naredbi.',
+'noemailprefs' => '<strong>Nije navedena e-mail adresa</strong>, stoga sljedeće naredbe neće raditi.',
+'emailconfirmlink' => 'Potvrdite svoju e-mail adresu',
+'invalidemailaddress' => 'Ne mogu prihvatiti e-mail adresu jer nije valjano oblikovana.
+Molim unesite ispravno oblikovanu adresu ili ostavite polje praznim.',
+'bold_sample' => 'Podebljani tekst',
+'bold_tip' => 'Podebljani tekst',
+'italic_sample' => 'Kurzivni tekst',
+'italic_tip' => 'Kurzivni tekst',
+'link_sample' => 'Tekst poveznice',
+'link_tip' => 'Unutarnja poveznica',
+'extlink_sample' => 'http://www.primjer.hr Tekst poveznice',
+'extlink_tip' => 'Vanjska poveznica (pazi, nužan je prefiks http://)',
+'headline_sample' => 'Tekst naslova',
+'headline_tip' => 'Podnaslov',
+'math_sample' => 'Ovdje unesi formulu',
+'math_tip' => 'Matematička formula (LaTeX)',
+'nowiki_sample' => 'Ovdje unesite neoblikovani tekst',
+'nowiki_tip' => 'Neoblikovani tekst',
+'image_sample' => 'Primjer.jpg',
+'image_tip' => 'Uložena slika',
+'media_sample' => 'Primjer.ogg',
+'media_tip' => 'Uloženi medij',
+'sig_tip' => 'Vaš potpis s datumom',
+'hr_tip' => 'Vodoravna crta (koristiti rijetko)',
+'summary' => 'Sažetak',
+'subject' => 'Predmet',
+'minoredit' => 'Ovo je manja promjena',
+'watchthis' => 'Prati ovaj članak',
+'savearticle' => 'Sačuvaj stranicu',
+'preview' => 'Pregled kako će stranica izgledati',
+'showpreview' => 'Prikaži kako će izgledati',
+'showlivepreview' => 'Pregled kako će izgledati, uživo',
+'showdiff' => 'Prikaži promjene',
+'anoneditwarning' => '\'\'\'Upozorenje:\'\'\' Niste prijavljeni pod suradničkim imenom. Vaša IP adresa bit će zabilježena u popisu izmjena ove stranice.',
+'missingsummary' => '\'\'\'Napomena:\'\'\' Niste unijeli sažetak promjena. Ako ponovno kliknete na \'Sačuvaj\', vaše će promjene biti snimljene bez sažetka.',
+'missingcommenttext' => 'Molim unesite sažetak.',
+'blockedtitle' => 'Suradnik je blokiran',
+'blockedtext' => 'Vaše suradničko ime ili IP adresu blokirao je administrator $1.
+Razlog je:<br />\'\'$2\'\'
+
+Ako želite raspraviti blokiranje
+javite se administratoru $1 ili nekom drugom [[Project:Administrators|administratoru]].
+
+Ne možete se koristiti naredbom "piši suradniku" ako niste
+registrirali valjanu e-mail adresu u svojim [[Special:Preferences|postavkama]].
+
+Vaša IP adresa je $3. Molimo vas da je spomenete u porukama o ovom predmetu.',
+'whitelistedittitle' => 'Za uređivanje stranice morate se prijaviti',
+'whitelistedittext' => 'Za uređivanje stranice morate se $1.',
+'whitelistreadtitle' => 'Za čitanje stranice morate se prijaviti',
+'whitelistreadtext' => 'Za čitanje stranice morate se [[Special:Userlogin|prijaviti]].',
+'whitelistacctitle' => 'Ne možete otvoriti suradnički račun',
+'whitelistacctext' => 'Da biste otvarali suradničke račune na ovom wikiju morate se [[Special:Userlogin|prijaviti]] i posjedovati odgovarajuća ovlaštenja.',
+'confirmedittitle' => 'Ovjera e-mail adrese nužna za uređivanje',
+'confirmedittext' => 'Morate ovjeriti vašu e-mail adresu prije nego što vam bude omogućeno uređivanje. Molim unesite i ovjerite vašu e-mail adresu u [[Special:Preferences|suradničkim postavkama]].',
+'loginreqtitle' => 'Nužna prijava',
+'loginreqlink' => 'prijava',
+'loginreqpagetext' => 'Morate se $1 da biste vidjeli ostale stranice.',
+'accmailtitle' => 'Lozinka poslana.',
+'accmailtext' => 'Lozinka za suradnika \'$1\' poslana je na adresu $2.',
+'newarticle' => '(Novo)',
+'newarticletext' => 'Došli ste na stranicu koja još nema sadržaja.<br />
+*Ako želite unijeti sadržaj, počnite tipkati u prozor ispod ovog teksta.
+*Ako vam treba pomoć, idite na [[Project:Pomoć|stranicu za pomoć]].
+*Ako ste ovamo dospjeli slučajno, kliknite "Natrag" (Back) u svom programu.',
+'anontalkpagetext' => '----\'\'Ovo je stranica za razgovor s anonimnim suradnikom koji nije otvorio suradnički račun ili se njime ne koristi. Zbog toga se moramo služiti brojčanom [[IP adresa|IP adresom]] kako bismo ga identificirali. Takvu adresu često koristi više ljudi. Ako ste anonimni suradnik i smatrate da su vam upućeni irelevantni komentari, molimo vas da [[Special:Userlogin|otvorite suradnički račun ili se prijavite]] te tako u budućnosti izbjegnete zamjenu s drugim anonimnim suradnicima.\'\'',
+'noarticletext' => '(Trenutno na ovoj stranici nema teksta)',
+'clearyourcache' => '\'\'\'Napomena:\'\'\' Nakon snimanja trebate očistiti međuspremnik svog preglednika kako biste vidjeli promjene.
+\'\'\'Mozilla / Firefox / Safari:\'\'\' držite \'\'Shift\'\' i pritisnite \'\'Reload\'\', ili pritisnite \'\'Ctrl-Shift-R\'\' (\'\'Cmd-Shift-R\'\' na Apple Macu);
+\'\'\'IE:\'\'\' držite \'\'Ctrl\'\' i pritisnite \'\'Refresh\'\', ili pritisnite \'\'Ctrl-F5\'\'; \'\'\'Konqueror:\'\'\': samo pritisnite dugme \'\'Reload\'\' ili pritisnite \'\'F5\'\'; korsnici \'\'\'Opere\'\'\' možda će morati u potpunosti isprazniti međuspremnik u \'\'Tools&rarr;Preferences\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Savjet:</strong> Koristite dugme \'Pokaži kako će izgledati\' za testiranje svog CSS/JS prije snimanja.',
+'usercsspreview' => '\'\'\'Ne zaboravite: samo isprobavate/pregledavate svoj suradnički CSS, i da još nije snimljen!\'\'\'',
+'userjspreview' => '\'\'\'Ne zaboravite: samo isprobavate/pregledavate svoj suradnički JavaScript, i da još nije snimljen!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Upozorenje:\'\'\' Nema sučelja pod imenom "$1". Ne zaboravite da imena stranica s .css and .js kodom počinju malim slovom, npr. Suradnik:Mate/monobook.css, a ne Suradnik:Mate/Monobook.css.',
+'updated' => '(Ažurirano)',
+'note' => '<strong>Napomena:</strong>',
+'previewnote' => 'Ne zaboravite da je ovo samo pregled kako će stranica izgledati i da
+stranica još nije snimljena!',
+'session_fail_preview' => '<strong>Ispričavamo se! Nismo mogli obraditi vašu izmjenu zbog gubitka podataka o prijavi.
+Molimo pokušajte ponovno. Ako i dalje ne bude radilo, pokušajte se odjaviti i ponovno prijaviti.</strong>',
+'previewconflict' => 'Ovaj pregled odražava stanje u gornjem polju za unos koje će biti sačuvano
+ako pritisnete "Sačuvaj stranicu".',
+'importing' => 'Uvoz: $1',
+'editing' => 'Uređujete $1',
+'editinguser' => 'Uređujete $1',
+'editingsection' => 'Uređujete $1 (odlomak)',
+'editingcomment' => 'Uređujete $1 (komentar)',
+'editconflict' => 'Istovremeno uređivanje: $1',
+'explainconflict' => 'Netko je u međuvremenu promijenio stranicu. Gornje polje sadrži sadašnji tekst stranice.
+U donjem polju prikazane su vaše promjene. Morat ćete unijeti vaše promjene u sadašnji tekst. <b>Samo</b> će tekst
+u u gornjem polju biti sačuvan kad pritisnete "Snimi stranicu".',
+'yourtext' => 'Vaš tekst',
+'storedversion' => 'Pohranjena inačica',
+'nonunicodebrowser' => '<strong>UPOZORENJE: Vaš preglednik ne podržava Unicode zapis znakova, molim promijenite ga prije sljedećeg uređivanja članaka.</strong>',
+'editingold' => '<strong>UPOZORENJE: Uređujete stariju inačicu
+ove stranice. Ako je sačuvate, sve će promjene učinjene nakon ove inačice biti izgubljene.</strong>',
+'yourdiff' => 'Razlike',
+'longpagewarning' => 'PAŽNJA: Ova stranica je dugačka $1 kilobajta; neki preglednici bi mogli imati problema pri uređivanju stranica koje se približavaju ili su duže od 32 kb.
+Molimo razmislite o rastavljanju stranice na manje odjeljke.',
+'longpageerror' => '<strong>POGRJEŠKA: Tekst koji ste unijeli dug je $1 kilobajta, što je više od maksimalnih $2 kilobajta. Nije ga moguće snimiti.</strong>',
+'readonlywarning' => '<strong>UPOZORENJE: Baza podataka je zaključana zbog održavanja, pa trenutno ne možete sačuvati svoje
+promjene. Najbolje je da kopirate i zaljepite tekst u tekstualnu datoteku te je snimite za kasnije.</strong>',
+'protectedpagewarning' => '<strong>UPOZORENJE: ova stranica je zaključana i mogu je uređivati samo suradnici s administratorskim pravima. Molimo pogledajte [[Project:Protected_page_guidelines|smjernice o zaključavanju]].</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Napomena:\'\'\' Ovu stranicu mogu uređivati samo prijavljeni suradnici.',
+'templatesused' => 'Predlošci korišteni na ovoj stranici:',
+'nocreatetitle' => 'Otvaranje novih stranica ograničeno',
+'nocreatetext' => 'Na ovom je projektu ograničeno otvaranje novih stranica.
+Možete se vratiti i uređivati već postojeće stranice ili se [[Special:Userlogin|prijaviti ili otvoriti suradnički račun]].',
+'revhistory' => 'Stare izmjene',
+'nohistory' => 'Ova stranica nema starijih izmjena.',
+'revnotfound' => 'Stara izmjena nije nađena.',
+'revnotfoundtext' => 'Ne mogu pronaći staru izmjenu stranice koju ste zatražili.
+Molimo provjerite URL koji vas je doveo ovamo.',
+'loadhist' => 'Učitavam stare izmjene',
+'currentrev' => 'Trenutna inačica',
+'revisionasof' => 'Inačica od $1',
+'previousrevision' => '←Starija inačica',
+'nextrevision' => 'Novija inačica→',
+'currentrevisionlink' => 'vidi trenutnu inačicu',
+'cur' => 'sad',
+'next' => 'sljed',
+'last' => 'pret',
+'orig' => 'izvo',
+'histlegend' => 'Uputa: (sad) = razlika od trenutne inačice,
+(pret) = razlika od prethodne inačice, m = manja promjena',
+'deletedrev' => '[izbrisano]',
+'histfirst' => 'Najstarije',
+'histlast' => 'Najnovije',
+'rev-deleted-comment' => '(komentar uklonjen)',
+'rev-deleted-user' => '(suradničko ime uklonjeno)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Ova je izmjena uklonjena iz javnoga arhiva.
+Detalji se vjerojatno nalaze u [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} evidenciji brisanja].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Ova je izmjena uklonjena iz javnoga arhiva.
+Kao administrator na ovom projektu možete ju vidjeti;
+detalji se vjerojatno nalaze u [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} evidenciji brisanja].
+</div>',
+'rev-delundel' => 'pokaži/skrij',
+'revisiondelete' => 'Izbriši/vrati izmjene',
+'revdelete-selected' => 'Odabrane izmjene stranice [[:$1]]:',
+'revdelete-text' => 'Obrisane će se izmjene i dalje nalaziti u javnom popisu izmjena,
+ali njihov sadržaj neće biti dostupan javnosti.
+
+Drugi administratori ovoga projekta moći će i dalje pristupiti skrivenom sadržaju i
+vratiti ga u javni pristup putem ovog sučelja, osim ako operateri na projektu nisu
+postavili dodatna ograničenja.',
+'revdelete-legend' => 'Postavi ograničenja na izmjenu:',
+'revdelete-hide-text' => 'Sakrij tekst izmjene',
+'revdelete-hide-comment'=> 'Sakrij komentar (sažetak)',
+'revdelete-hide-user' => 'Sakrij suradnikovo ime/IP adresu',
+'revdelete-hide-restricted'=> 'Postavi ograničenja i za administratore kao i za ostale suradnike',
+'revdelete-log' => 'Komentar za evidenciju:',
+'revdelete-submit' => 'Izvrši brisanje/sakrivanje',
+'revdelete-logentry' => 'promijenjena su prava pristupa za stranicu [[$1]]',
+'difference' => '(Usporedba među inačicama)',
+'loadingrev' => 'učitavam inačicu za usporedbu',
+'lineno' => 'Redak $1:',
+'editcurrent' => 'Uredi trenutnu inačicu ove stranice',
+'selectnewerversionfordiff'=> 'Izaberi noviju inačicu za usporedbu',
+'selectolderversionfordiff'=> 'Izaberi stariju inačicu za usporedbu',
+'compareselectedversions'=> 'Usporedi odabrane inačice',
+'searchresults' => 'Rezultati pretrage',
+'searchresulttext' => 'Za više obavijesti o pretraživanju projekta {{SITENAME}} vidi [[Project:Tražilica]].',
+'searchsubtitle' => 'Za upit "[[:$1]]"',
+'searchsubtitleinvalid' => 'Za upit "$1"',
+'badquery' => 'Loše oblikovan upit',
+'badquerytext' => 'Nismo mogli provesti vašu pretragu.
+Razlog je vjerojatno u tome što ste pokušali tražiti riječ kraću od tri
+slova, što još nije moguće.
+Možda ste pogriješili pri upisu pretrage. Pokušajte ponovo.',
+'matchtotals' => 'Upitu "$1" odgovara $2 naslova stranica i $3 tekstova stranica.',
+'noexactmatch' => '\'\'\'Ne postoji stranica naziva "$1".\'\'\' Možete [[:$1|kreirati tu stranicu]].',
+'titlematches' => 'Pronađene stranice prema naslovu',
+'notitlematches' => 'Nema pronađenih stranica prema naslovu',
+'textmatches' => 'Pronađene stranice prema tekstu članka',
+'notextmatches' => 'Nema pronađenih stranica prema tekstu članka',
+'prevn' => 'prethodnih $1',
+'nextn' => 'sljedećih $1',
+'viewprevnext' => 'Vidi ($1) ($2) ($3).',
+'showingresults' => 'Ispod je prikazano <b>$1</b> rezultata, počevši od <b>$2.</b>.',
+'showingresultsnum' => 'Ispod je prikazano <b>$3</b> počevši s brojem #<b>$2</b>.',
+'nonefound' => '<b>Napomena</b>: pretrage su neuspješne ako tražite česte riječi koje ne indeksiramo, ili u upitu navedete previše pojmova (u rezultatu se pojavlju samo stranice koje sadrže sve tražene pojmove).',
+'powersearch' => 'Traženje',
+'powersearchtext' => '
+Traženje u prostoru :<br />
+$1<br />
+$2 Popis se preusmjerava Traženje za $3 $9',
+'searchdisabled' => '<p>Oprostite! Pretraga po cjelokupnoj bazi je zbog bržeg rada projekta {{SITENAME}} trenutno onomogućena. Možete se poslužiti tražilicom Google.</p>',
+'blanknamespace' => '(Glavni)',
+'preferences' => 'Postavke',
+'prefsnologin' => 'Niste prijavljeni',
+'prefsnologintext' => 'Morate biti [[Special:Userlogin|prijavljeni]]
+za podešavanje korisničkih postavki.',
+'prefsreset' => 'Postavke su vraćene na prvotne vrijednosti.',
+'qbsettings' => 'Traka',
+'changepassword' => 'Promjena lozinke',
+'skin' => 'Izgled',
+'math' => 'Prikaz matematičkih formula',
+'dateformat' => 'Format datuma',
+'datedefault' => 'Nemoj postaviti',
+'datetime' => 'Datum i vrijeme',
+'math_failure' => 'Obrada nije uspjela.',
+'math_unknown_error' => 'nepoznata greška',
+'math_unknown_function' => 'nepoznata funkcija',
+'math_lexing_error' => 'rječnička greška (lexing error)',
+'math_syntax_error' => 'sintaksna greška',
+'math_image_error' => 'Konverzija u PNG nije uspjela; provjerite jesu li dobro instalirani latex, dvips, gs, i convert',
+'math_bad_tmpdir' => 'Ne mogu otvoriti ili pisati u privremeni direktorij za matematiku',
+'math_bad_output' => 'Ne mogu otvoriti ili pisati u odredišni direktorij za matematiku',
+'math_notexvc' => 'Nedostaje izvršna datoteka texvc-a; pogledajte math/README za postavke.',
+'prefs-personal' => 'Podaci o suradniku',
+'prefs-rc' => 'Nedavne promjene i kratki članci',
+'prefs-misc' => 'Razno',
+'saveprefs' => 'Snimi postavke',
+'resetprefs' => 'Vrati na prvotne postavke',
+'oldpassword' => 'Stara lozinka',
+'newpassword' => 'Nova lozinka',
+'retypenew' => 'Ponovno unesite lozinku',
+'textboxsize' => 'Širina okvira za uređivanje',
+'rows' => 'Redova',
+'columns' => 'Stupaca',
+'searchresultshead' => 'Prikaz rezultata pretrage',
+'resultsperpage' => 'Koliko pogodaka na jednoj stranici',
+'contextlines' => 'Koliko redova teksta po pogotku',
+'contextchars' => 'Koliko znakova po retku',
+'stubthreshold' => 'Prag za prikaz članaka u nastajanju (stubova)',
+'recentchangescount' => 'Broj naslova u nedavnim izmjenama',
+'savedprefs' => 'Vaše postavke su sačuvane.',
+'timezonelegend' => 'Vremenska zona',
+'timezonetext' => 'Unesite razliku između vašeg lokalnog vremena i vremena na poslužitelju (UTC).',
+'localtime' => 'Lokalno vrijeme',
+'timezoneoffset' => 'Razlika',
+'servertime' => 'Vrijeme na poslužitelju',
+'guesstimezone' => 'Vrijeme dobiveno od preglednika',
+'allowemail' => 'Omogući primanje e-maila od drugih suradnika',
+'defaultns' => 'Ako ne navedem drugačije, traži u ovim prostorima:',
+'default' => 'prvotno',
+'files' => 'Datoteke',
+'userrights-lookup-user'=> 'Upravljaj skupinama suradnika',
+'userrights-user-editname'=> 'Unesite suradničko ime:',
+'editusergroup' => 'Uredi suradničke skupine',
+'userrights-editusergroup'=> 'Uredi skupine suradnika',
+'saveusergroups' => 'Snimi skupine suradnika',
+'userrights-groupsmember'=> 'Član:',
+'userrights-groupsavailable'=> 'Dostupne skupine:',
+'userrights-groupshelp' => 'Izaberite skupine u koje želite dodati ili iz njih ukloniti suradnika.
+Neoznačene skupine neće se promijeniti. Skupinu možete deselektirati istovremenim pritiskom CTRL + lijeva tipka miša',
+'changes' => 'promjene',
+'recentchanges' => 'Nedavne promjene',
+'recentchangestext' => 'Na ovoj stranici možete pratiti nedavne promjene u wikiju.',
+'rcnote' => 'Slijedi zadnjih <strong>$1</strong> promjena u zadnjih <strong>$2</strong> dana, od $3.',
+'rcnotefrom' => 'Slijede promjene od <b>$2</b> (prikazano ih je do <b>$1</b>).',
+'rclistfrom' => 'Prikaži nove promjene počevši od $1',
+'rcshowhideminor' => '$1 manje promjene',
+'rcshowhidebots' => '$1 botove',
+'rcshowhideliu' => '$1 prijavljene suradnike',
+'rcshowhideanons' => '$1 anonimne suradnike',
+'rcshowhidepatr' => '$1 provjerene promjene',
+'rcshowhidemine' => '$1 moje promjene',
+'rclinks' => 'Prikaži zadnjih $1 promjena u zadnjih $2 dana; $3',
+'diff' => 'razl',
+'hist' => 'pov',
+'hide' => 'sakrij',
+'show' => 'prikaži',
+'number_of_watching_users_pageview'=> '[$1 suradnika prati ovu stranicu]',
+'rc_categories' => 'Ograniči na kategorije (odvojene znakom "|")',
+'rc_categories_any' => 'Sve',
+'upload' => 'Postavi datoteku',
+'uploadbtn' => 'Postavi datoteku',
+'reupload' => 'Ponovno postavi',
+'reuploaddesc' => 'Vratite se u obrazac za postavljanje.',
+'uploadnologin' => 'Niste prijavljeni',
+'uploadnologintext' => 'Za postavljanje datoteka morate biti [[Special:Userlogin|prijavljeni].',
+'upload_directory_read_only'=> 'Server ne može pisati u direktorij za postavljanje ($1).',
+'uploaderror' => 'Greška kod postavljanja',
+'uploadtext' => '\'\'\'STANITE!\'\'\' Prije nego što postavite sliku pročitajte i slijedite upute
+o [[Project:Slike|upotrebi slika]].
+
+Ovaj obrazac služi za postavljanje novih slika. Za pregledavanje i pretraživanje već postavljenih slika
+vidi [[Special:Imagelist|popis postavljenih datoteka]]. Postavljanja i brisanja bilježe se i u [[Special:Log|evidenciji]].
+
+Stavljanjem oznake u odgovarajući kvadratić morate potvrditi da postavljanjem slike ne kršite ničija autorska prava.
+Na kraju pritisnite dugme "Postavi datoteku".
+
+Da biste na stranicu stavili sliku, koristite poveznice tipa
+\'\'\'<nowiki>[[{{ns:6}}:datoteka.jpg]]</nowiki>\'\'\',
+\'\'\'<nowiki>[[{{ns:6}}:datoteka.png|popratni tekst]]</nowiki>\'\'\' ili
+\'\'\'<nowiki>[[{{ns:-2}}:datoteka.ogg]]</nowiki>\'\'\' za izravnu poveznicu na datoteku.',
+'uploadlog' => 'evidencija postavljanja',
+'uploadlogpage' => 'Evidencija_postavljanja',
+'uploadlogpagetext' => 'Dolje je popis nedavno postavljenih slika.',
+'filename' => 'Ime datoteke',
+'filedesc' => 'Opis',
+'fileuploadsummary' => 'Opis:',
+'filestatus' => 'Status autorskih prava',
+'filesource' => 'Izvor',
+'copyrightpage' => 'Project:Autorska prava',
+'copyrightpagename' => 'Autorska prava na projektu {{SITENAME}}',
+'uploadedfiles' => 'Postavljene datoteke',
+'ignorewarning' => 'Zanemari upozorenja i snimi datoteku.',
+'ignorewarnings' => 'Zanemari sva upozorenja',
+'minlength' => 'Imena slika moraju imati najmanje tri slova.',
+'illegalfilename' => 'Ime datoteke "$1" sadrži znakove koji nisu dozvoljeni u imenima stranica. Preimenujte datoteku i ponovno je postavite.',
+'badfilename' => 'Ime slike automatski je promijenjeno u "$1".',
+'badfiletype' => '".$1" nije preporučljiv format za slike.',
+'largefile' => 'Preporučljivo je da veličina datoteka ne prelazi $1 bajtova; ova datoteka ima $2 bajtova',
+'largefileserver' => 'Veličina ove datoteke veća je od one dopuštene postavkama poslužitelja.',
+'emptyfile' => 'Datoteka koju ste postavili je prazna. Možda se radi o krivo utipkanom imenu datoteke. Provjerite želite li zaista postaviti ovu datoteku.',
+'fileexists' => 'Datoteka s ovim imenom već postoji, pogledajte $1 ako niste sigurni želite li je uistinu promijeniti.',
+'fileexists-forbidden' => 'Datoteka s ovim imenom već postoji; molim postavite ju pod drugim imenom. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Datoteka s ovim imenom već postoji u središnjem spremniku datoteka; molim postavite ju pod drugim imenom. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Postavljanje uspješno.',
+'fileuploaded' => 'Datoteka "$1" je uspješno postavljena.
+Slijedite ovu poveznicu: ($2) na stranicu s opisom i unesite
+podatke o datoteci: opis, izvor i licencu.
+
+Ako je ovo slika, možete je unijeti u stranicu ovako: <tt><nowiki>[[Image:$1|thumb|Opis]]</nowiki></tt>.',
+'uploadwarning' => 'Upozorenje kod postavljanja',
+'savefile' => 'Sačuvaj datoteku',
+'uploadedimage' => 'postavljeno "$1"',
+'uploaddisabled' => 'Postavljanje je onemogućeno',
+'uploaddisabledtext' => 'Postavljanje datoteka na ovom je wikiju onemogućeno.',
+'uploadscripted' => 'Ova datoteka sadrži HTML ili skriptu, što može dovesti do grešaka u web pregledniku.',
+'uploadcorrupt' => 'Ova je datoteka oštećena ili ima nepravilan nastavak. Provjerite i pokušajte ponovo.',
+'uploadvirus' => 'Datoteka sadrži virus! Podrobnije: $1',
+'sourcefilename' => 'Ime datoteke na vašem računalu',
+'destfilename' => 'Ime datoteke na wikiju',
+'license' => 'Dozvola',
+'nolicense' => 'Molim odaberite:',
+'imagelist' => 'Popis slika',
+'imagelisttext' => 'Ispod je popis $1 slika složen $2.',
+'imagelistforuser' => 'Prikazuje samo slike koje je postavio suradnik $1.',
+'getimagelist' => 'dobavljam popis slika',
+'ilsubmit' => 'Traži',
+'showlast' => 'Prikaži $1 slika složenih $2.',
+'byname' => 'po imenu',
+'bydate' => 'po datumu',
+'bysize' => 'po veličini',
+'imgdelete' => 'bris',
+'imgdesc' => 'opis',
+'imglegend' => 'Uputa: (opis) = prikaži/uredi opis slike.',
+'imghistory' => 'Povijest slike',
+'revertimg' => 'vra',
+'deleteimg' => 'bri',
+'deleteimgcompletely' => 'Izbriši sve inačice datoteke',
+'imghistlegend' => 'Uputa: (tre) = trenutna slika, (bri) = briši
+zadnju inačicu, (vra) = vrati sliku na prethodnu inačicu.
+<br /><i>Klikni na datum, da vidiš inačicu koja je tada postavljena</i>.',
+'imagelinks' => 'Poveznice slike',
+'linkstoimage' => 'Sljedeće stranice povezuju na ovu sliku:',
+'nolinkstoimage' => 'Nijedna stranica ne povezuje na ovu sliku.',
+'sharedupload' => 'Ova je datoteka postavljena na zajedničkom poslužitelju i mogu je koristiti i ostali wikiji',
+'shareduploadwiki' => 'Za podrobnije informacije vidi $1.',
+'shareduploadwiki-linktext'=> 'stranica s opisom datoteke',
+'noimage' => 'Ne postoji datoteka s ovim imenom. Možete ju $1.',
+'noimage-linktext' => 'postaviti',
+'uploadnewversion-linktext'=> 'Postavi novu inačicu datoteke',
+'mimesearch' => 'MIME tražilica',
+'mimetype' => 'MIME tip datoteke:',
+'download' => 'skidanje',
+'unwatchedpages' => 'Nenadgledane stranice',
+'listredirects' => 'Popis preusmjeravanja',
+'statistics' => 'Statistika',
+'sitestats' => 'Statistika ovog wikija',
+'userstats' => 'Statistika suradnika',
+'sitestatstext' => 'U bazi podataka ukupno je \'\'\'$1\'\'\' članaka.
+Ovaj broj uključuje stranice za raspravu, stranice o projektu u prostoru {{SITENAME}}, kratke članke,
+preusmjerene stranice, i sve ostale članke koje najvjerojatnije ne možemo računati kao sadržaj.
+
+Trenutno je \'\'\'$2\'\'\' članaka koji predstavljaju valjan sadržaj (nalaze se u glavnom prostoru i sadrže
+barem jednu unutarnju poveznicu).
+
+Snimljeno je \'\'\'$8\'\'\' datoteka.
+
+Ukupno je \'\'\'$3\'\'\' pregleda stranica, i \'\'\'$4\'\'\' uređivanja članaka od pokretanja projekta {{SITENAME}}.
+U prosjeku to iznosi \'\'\'$5\'\'\' uređivanja po stranici, i \'\'\'$6\'\'\' pregleda po uređivanju.
+
+Duljina [http://meta.wikimedia.org/wiki/Help:Job_queue zadataka za izvršavanje] je \'\'\'$7\'\'\'.',
+'userstatstext' => 'Broj registriranih suradnika je \'\'\'$1\'\'\'. Od toga je \'\'\'$2\'\'\' (ili \'\'\'$4%\'\'\') administratora (vidi $3).',
+'disambiguations' => 'Razdvojbene stranice',
+'disambiguationstext' => 'Sljedeći su članci povezani na <i>razdvojbenu stranicu</i>. Morali bi biti povezani
+na odgovarajući sadržaj.<br />Stranica je razdvojbena ako je povezana iz $1.<br />Poveznice
+iz sekundarnih prostora ovdje <i>nisu</i> prikazane.',
+'doubleredirects' => 'Dvostruko preusmjeravanje',
+'doubleredirectstext' => '<b>Pozor:</b>ovaj popis može sadržavati nepravilne članove. To obično znači
+da postoji dodatan tekst u poveznici prve naredbe \#REDIRECT.<br />
+Svaki red sadrži poveznice na prvo i drugo preusmjeravanje, te te prvu liniju teksta drugog preusmjeravanja
+koja obično ukazuje na "pravu" odredišnu stranicu, na koju bi trebalo pokazivati prvo preusmjeravanje.',
+'brokenredirects' => 'Kriva preusmjeravanja',
+'brokenredirectstext' => 'Sljedeća preusmjeravanja pokazuju na nepostojeće članke.',
+'nbytes' => '$1 bajtova',
+'ncategories' => '$1 kategorija',
+'nlinks' => '$1 poveznica',
+'nrevisions' => '$1 inačica',
+'nviews' => '$1 puta pogledano',
+'lonelypages' => 'Stranice siročad',
+'uncategorizedpages' => 'Nekategorizirane stranice',
+'uncategorizedcategories'=> 'Nekategorizirane kategorije',
+'unusedcategories' => 'Nekorištene kategorije',
+'unusedimages' => 'Nekorištene slike',
+'popularpages' => 'Popularne stranice',
+'wantedcategories' => 'Tražene kategorije',
+'wantedpages' => 'Tražene stranice',
+'mostlinked' => 'Stranice na koje vodi najviše poveznica',
+'mostlinkedcategories' => 'Kategorije na koje vodi najviše poveznica',
+'mostcategories' => 'Popis članaka po broju kategorija',
+'mostimages' => 'Slike na koje vodi najviše poveznica',
+'mostrevisions' => 'Popis članaka po broju uređivanja',
+'allpages' => 'Sve stranice',
+'prefixindex' => 'Indeks prema početku naslova',
+'randompage' => 'Slučajna stranica',
+'shortpages' => 'Kratke stranice',
+'longpages' => 'Duge stranice',
+'deadendpages' => 'Slijepe ulice',
+'listusers' => 'Popis suradnika',
+'specialpages' => 'Posebne stranice',
+'spheading' => 'Posebne stranice za sve suradnike',
+'restrictedpheading' => 'Posebne stranice s ograničenim pristupom',
+'recentchangeslinked' => 'Povezane stranice',
+'rclsub' => '(na stranice povezane iz "$1")',
+'newpages' => 'Nove stranice',
+'ancientpages' => 'Najstarije stranice',
+'intl' => 'Interwiki poveznice',
+'move' => 'Premjesti',
+'movethispage' => 'Premjesti ovu stranicu',
+'unusedimagestext' => '<p>Moguće je da su druge mrežne stranice izvan ovog
+wikija povezane na sliku neposrednim URLom, a nisu ovdje navedene unatoč aktivnoj uporabi.</p>',
+'unusedcategoriestext' => 'Na navedenim stranicama kategorija nema ni jednog članka ili potkategorije.',
+'booksources' => 'Pretraživanje po ISBN-u',
+'categoriespagetext' => 'Na ovom wikiju postoje sljedeće kategorije.',
+'data' => 'Podaci',
+'userrights' => 'Upravljanje suradničkim pravima',
+'groups' => 'Suradničke skupine',
+'booksourcetext' => 'Dolje je popis poveznica prema stranicama koje prodaju nove ili rabljene knjige i
+gdje su možda na raspolaganju dodatne informacije o knjigama koje tražite.
+{{SITENAME}} ne posluje ni s jednim od ovih siteova i ovaj popis nije pokazatelj njihovog uspjeha.',
+'alphaindexline' => '$1 do $2',
+'version' => 'Verzija softvera',
+'log' => 'Evidencije',
+'alllogstext' => 'Skupni prikaz evidencija postavljenih datoteka, brisanja, zaštite, blokiranja, i administratorskih prava.
+Možete suziti prikaz odabirući tip evidencije, suradničko ime ili stranicu u pitanju.',
+'logempty' => 'Nema pronađenih stavki.',
+'nextpage' => 'Sljedeća stranica ($1)',
+'allpagesfrom' => 'Pokaži stranice počevši od:',
+'allarticles' => 'Svi članci',
+'allinnamespace' => 'Svi članci (prostor $1)',
+'allnotinnamespace' => 'Sve stranice koje nisu u prostoru $1',
+'allpagesprev' => 'Prijašnje',
+'allpagesnext' => 'Sljedeće',
+'allpagessubmit' => 'Kreni',
+'allpagesprefix' => 'Stranice čiji naslov počinje s:',
+'mailnologin' => 'Nema adrese pošiljaoca',
+'mailnologintext' => 'Morate biti [[Special:Userlogin|prijavljeni]]
+i imati valjanu adresu e-pošte u svojim [[Special:Preferences|postavkama]]
+da bi mogli slati poštu drugim suradnicima.',
+'emailuser' => 'Pošalji e-poštu ovom suradniku',
+'emailpage' => 'Pošalji e-poštu suradniku',
+'emailpagetext' => 'Ako je suradnik unio valjanu e-mail adresu u svojim postavkama,
+bit će mu poslana poruka s tekstom iz donjeg obrasca.
+E-mail adresa iz vaših postavki nalazit će se u "From" polju poruke i primatelj će vam moći odgovoriti.',
+'usermailererror' => 'Sustav pošte se vratio s greškom:',
+'noemailtitle' => 'Nema adrese primaoca',
+'noemailtext' => 'Ovaj suradnik nije unio valjanu e-mail adresu ili se odlučio na neće primati poštu od drugih suradnika.',
+'emailfrom' => 'Od',
+'emailto' => 'Za',
+'emailsubject' => 'Tema',
+'emailmessage' => 'Poruka',
+'emailsend' => 'Pošalji',
+'emailsent' => 'E-mail poslan',
+'emailsenttext' => 'Vaša poruka je poslana.',
+'watchlist' => 'Moj popis praćenja',
+'nowatchlist' => 'Na vašem popisu praćenja nema nijednog članka.',
+'watchnologin' => 'Niste prijavljeni',
+'watchnologintext' => 'Morate biti [[Special:Userlogin|prijavljeni]]
+za promjene u popisu praćenja.',
+'addedwatch' => 'Dodano u popis praćenja',
+'addedwatchtext' => 'Stranica "$1" je dodana na vaš [[Special:Watchlist|popis praćenja]].
+Promjene na ovoj stranici i njenoj stranici za razgovor bit će tamo prikazani, a stranica će biti ispisana
+<b>podebljano</b> u [[Special:Recentchanges|popisu nedavnih promjena]], da biste je lakše primijetili.
+<p>Ako poželite ukloniti stranicu s popisa praćenja, pritisnite "Prekini praćenje" u traci s naredbama.</p>',
+'removedwatch' => 'Odstranjena s popisa praćenja',
+'removedwatchtext' => 'Stranica "$1" je odstranjena s vašeg popisa praćenja.',
+'watch' => 'Prati',
+'watchthispage' => 'Prati ovu stranicu',
+'unwatch' => 'Prekini praćenje',
+'unwatchthispage' => 'Prekini praćenje',
+'notanarticle' => 'Nije članak',
+'watchnochange' => 'Niti jedna od praćenih stranica nije promijenjena od vašeg zadnjeg posjeta.',
+'watchdetails' => '* broj stranica koje se prate (ne brojeći stranice za razgovor): $1
+* [[Special:Watchlist/edit|prikaži i uredi popis praćenja]]',
+'wlheader-enotif' => '* Uključeno je izvješćivanje e-mailom.',
+'wlheader-showupdated' => '* Stranice koje su promijenjene od vašeg zadnjeg posjeta prikazane su \'\'\'podebljano\'\'\'',
+'watchmethod-recent' => 'provjera nedavnih promjena praćenih stranica',
+'watchmethod-list' => 'provjera praćanih stranica za nedavne promjene',
+'removechecked' => 'Ukloni označene članke s popisa praćenja',
+'watchlistcontains' => 'Broj stranica na vašem popisu praćenja je $1.',
+'watcheditlist' => 'Ovdje je abecedni popis stranica koje pratite. Označite stranice koje želite ukloniti
+s popisa i pritisnite dugme \'ukloni označeno\' na dnu ekrana (uklanjanjem stranice sa sadržajem uklanja se
+i stranica za razgovor i obrnuto).',
+'removingchecked' => 'Uklanjam ove članke s popisa praćenja...',
+'couldntremove' => 'Nisam mogao ukloniti \'$1\'...',
+'iteminvalidname' => 'Problem s izborom \'$1\', ime nije valjano...',
+'wlnote' => 'Ovdje je posljednjih $1 promjena u posljednjih <b>$2</b> sati.',
+'wlshowlast' => 'Pokaži zadnjih $1 sati $2 dana $3',
+'wlsaved' => 'Ovo je snimljena inačica vašeg popisa praćenja.',
+'wlhideshowown' => '$1 moja uređivanja.',
+'wlhideshowbots' => '$1 botove.',
+'enotif_mailer' => '{{SITENAME}} - izvješća o promjenama',
+'enotif_reset' => 'Označi sve stranice kao već posjećene',
+'enotif_newpagetext' => 'Ovo je nova stranica.',
+'changed' => 'promijenio',
+'created' => 'stvorio',
+'enotif_subject' => '{{SITENAME}}: Stranicu $PAGETITLE je $CHANGEDORCREATED suradnik $PAGEEDITOR',
+'enotif_lastvisited' => 'Pogledaj $1 za promjene od zadnjeg posjeta.',
+'enotif_body' => '$WATCHINGUSERNAME,
+
+stranicu na projektu {{SITENAME}} s naslovom $PAGETITLE je dana $PAGEEDITDATE $CHANGEDORCREATED suradnik $PAGEEDITOR,
+pogledajte $PAGETITLE_URL za trenutnu inačicu.
+
+$NEWPAGE
+
+Sažetak urednika: $PAGESUMMARY $PAGEMINOREDIT
+
+Možete se javiti uredniku:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Do vašeg ponovnog posjeta stranici nećete dobivati daljnja izviješća.
+Postavke za izvješćivanje možete resetirati na svom popisu praćenja.
+
+ Vaš sustav izvješćivanja - hrvatska {{SITENAME}}.
+
+--
+Za promjene svog popisa praćenja posjetite
+{{fullurl:Special:Watchlist|edit=yes}}
+
+Za pomoć posjetite:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Izbriši stranicu',
+'confirm' => 'Potvrdi',
+'excontent' => 'sadržaj je bio: \'$1\'',
+'excontentauthor' => 'sadržaj je bio: \'$1\' (a jedini urednik \'$2\')',
+'exbeforeblank' => 'sadržaj prije brisanja je bio: \'$1\'',
+'exblank' => 'stranica je bila prazna',
+'confirmdelete' => 'Potvrdi brisanje',
+'deletesub' => '(Brišem "$1")',
+'historywarning' => 'UPOZORENJE: Stranica koju želite obrisati ima prijašnje inačice:',
+'confirmdeletetext' => 'Zauvijek ćete izbrisati stranicu ili sliku zajedno s prijašnjim inačicama.
+Molim potvrdite svoju namjeru, da razumijete posljedice i da ovo radite u skladu s [[Project:Pravila|pravilima]].',
+'actioncomplete' => 'Zahvat završen',
+'deletedtext' => '"$1" je izbrisana.
+Vidi $2 za evidenciju nedavnih brisanja.',
+'deletedarticle' => 'izbrisano "$1"',
+'dellogpage' => 'Evidencija_brisanja',
+'dellogpagetext' => 'Dolje je popis nedavnih brisanja.
+Sva vremena su prema poslužiteljevom vremenu (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'evidencija brisanja',
+'reverted' => 'Vraćeno na prijašnju inačicu',
+'deletecomment' => 'Razlog za brisanje',
+'imagereverted' => 'Uspješno vraćeno na prijašnju inačicu.',
+'rollback' => 'Ukloni posljednju promjenu',
+'rollback_short' => 'Ukloni',
+'rollbacklink' => 'ukloni',
+'rollbackfailed' => 'Uklanjanje neuspješno',
+'cantrollback' => 'Ne mogu ukloniti posljednju promjenu, postoji samo jedna promjena.',
+'alreadyrolled' => 'Ne mogu ukloniti posljednju promjenu članka [[:$1]] koju je napravio suradnik [[User:$2|$2]]
+([[User talk:$2|Talk]]); netko je već promijenio stranicu ili uklonio promjenu.
+
+Posljednju promjenu napravio je suradnik [[User:$3|$3]] ([[User talk:$3|Talk]]).',
+'editcomment' => 'Komentar promjene je: "<i>$1</i>".',
+'revertpage' => 'Uklonjena promjena suradnika $2, vraćeno na zadnju inačicu suradnika $1',
+'sessionfailure' => 'Uočili smo problem s vašom prijavom. Zadnja naredba nije izvršena
+kako bi izbjegla zloupotreba. Molimo vas da u pregledniku pritisnete "Natrag" (Back) i ponovno učitate stranicu
+s koje ste stigli.',
+'protectlogpage' => 'Evidencija zaštićivanja',
+'protectlogtext' => 'Ispod je popis zaštićivanja i uklanjanja zaštite pojedinih stranica.
+Pogledajte članak [[Project:Protected page|Zaštićena stranica]] za više obavijesti na ovu temu.',
+'protectedarticle' => 'članak "[[$1]]" je zaštićen',
+'unprotectedarticle' => 'uklonjena zaštita članka "[[$1]]"',
+'protectsub' => '(Zaštićujem "$1")',
+'confirmprotecttext' => 'Želite li doista zaštititi ovu stranicu?',
+'confirmprotect' => 'Potvrda zaštite',
+'protectmoveonly' => 'Zaštiti samo od premještanja',
+'protectcomment' => 'Razlog za zaštitu',
+'unprotectsub' => '(Uklanjam zaštitu stranice "$1")',
+'confirmunprotecttext' => 'Želite li doista ukloniti zaštitu?',
+'confirmunprotect' => 'Potvrda uklanjanja zaštite',
+'unprotectcomment' => 'Razlog za uklanjanje zaštite',
+'protect-unchain' => 'Otključaj ovlaštenja za premještanje',
+'protect-text' => 'Ovdje možete pregledati i promijeniti razinu zaštite za stranicu <strong>$1</strong>.
+Molim pripazite da ovo radite u skladu s [[Project:Pravila|pravilima]].',
+'protect-viewtext' => 'Vaš suradnički račun nema ovlasti
+za promjenu razine zaštite stranice. Ovo su trenutne postavke stranice <strong>$1</strong>:',
+'protect-default' => '(bez zaštite)',
+'protect-level-autoconfirmed'=> 'Blokiraj neregistrirane suradnike',
+'protect-level-sysop' => 'Samo administratori',
+'restriction-edit' => 'Uređivanje',
+'restriction-move' => 'Premještanje',
+'undelete' => 'Vrati izbrisanu stranicu',
+'undeletepage' => 'Vidi i/ili vrati izbrisane stranice',
+'viewdeletedpage' => 'Pogledaj izbrisanu stranicu',
+'undeletepagetext' => 'Sljedeće su stranice izbrisane, ali se još uvijek nalaze u bazi i mogu se obnoviti. Baza se povremeno čisti od ovakvih stranica.',
+'undeletearticle' => 'Vrati izbrisanu stranicu',
+'undeleterevisions' => '$1 inačica je arhivirano',
+'undeletehistory' => 'Ako vratite izbrisanu stranicu, bit će vraćene i sve prijašnje promjene. Ako je u međuvremenu stvorena nova stranica s istim imenom, vraćena stranica bit će upisana kao prijašnja promjena sadašnje. Sadašnja stranica neće biti zamijenjena.',
+'undeletehistorynoadmin'=> 'Ovaj je članak izbrisan. Razlog za brisanje prikazan je u donjem sažetku, zajedno s
+detaljima o suradnicima koji su uređivali ovu stranicu prije brisanja.
+Tekst izbrisanih inačica dostupan je samo administratorima.',
+'undeleterevision' => 'Izbrisana inačica od $1',
+'undeletebtn' => 'Vrati!',
+'undeletedarticle' => 'vraćen "$1"',
+'undeletedrevisions' => '$1 inačica vraćeno',
+'namespace' => 'Prostor:',
+'invert' => 'Sve osim odabranog',
+'contributions' => 'Doprinosi suradnika',
+'mycontris' => 'Moji doprinosi',
+'contribsub' => 'Za $1',
+'nocontribs' => 'Nema promjena koje udovoljavaju ovim kriterijima.',
+'ucnote' => 'Ovdje je zadnjih <b>$1</b> promjena ovog suradnika u zadnjih <b>$2</b> dana.',
+'uclinks' => 'Pogledaj zadnjih $1 promjena; pogledaj zadnjih $2 dana.',
+'uctop' => ' (vrh)',
+'newbies' => 'novaci',
+'sp-contributions-newest'=> 'Najnovije',
+'sp-contributions-oldest'=> 'Najstarije',
+'sp-contributions-newer'=> '$1 novijih',
+'sp-contributions-older'=> '$1 starijih',
+'sp-contributions-newbies-sub'=> 'Za nove suradnike',
+'whatlinkshere' => 'Što vodi ovamo',
+'notargettitle' => 'Nema odredišta',
+'notargettext' => 'Niste naveli ciljnu stranicu ili suradnika za izvršavanje ove funkcije.',
+'linklistsub' => '(Popis poveznica)',
+'linkshere' => 'Sljedeće stranice povezuju ovamo:',
+'nolinkshere' => 'Nijedna stranica ne povezuje ovamo.',
+'isredirect' => 'stranica za preusmjeravanje',
+'istemplate' => 'kao predložak',
+'blockip' => 'Blokiraj suradnika',
+'blockiptext' => 'Koristite donji obrazac za blokiranje pisanja pojedinih suradnika ili IP adresa .
+To biste trebali raditi samo zbog sprječavanja vandalizma i u skladu
+sa [[Project:Policy|smjernicama]].
+Upišite i razlog za ovo blokiranje (npr. stranice koje su
+vandalizirane).',
+'ipaddress' => 'IP adresa',
+'ipadressorusername' => 'IP adresa ili suradničko ime',
+'ipbexpiry' => 'Rok (na engleskom)',
+'ipbreason' => 'Razlog',
+'ipbsubmit' => 'Blokiraj ovog suradnika',
+'ipbother' => 'Neki drugi rok (na engleskom, npr. 6 days',
+'ipboptions' => '2 sata:2 hours,6 sati:6 hours,1 dan:1 day,3 dana:3 days,1 tjedan:1 week,2 tjedna:2 weeks,1 mjesec:1 month,3 mjeseca:3 months,6 mjeseci:6 months,1 godine:1 year,zauvijek:infinite',
+'ipbotheroption' => 'drugo',
+'badipaddress' => 'Nevaljana IP adresa.',
+'blockipsuccesssub' => 'Uspješno blokirano',
+'blockipsuccesstext' => 'Suradnik [[{{ns:Special}}:Contributions/$1|$1]] je blokiran.
+<br />Pogledaj [[{{ns:Special}}:Ipblocklist|IP block list]] za pregled blokiranja.',
+'unblockip' => 'Deblokiraj suradnika',
+'unblockiptext' => 'Ovaj se obrazac koristi za vraćanje prava na pisanje prethodno blokiranoj IP adresi.',
+'ipusubmit' => 'Deblokiraj ovu adresu',
+'ipblocklist' => 'Popis blokiranih IP adresa',
+'blocklistline' => '$1, $2 je blokirao $3 ($4)',
+'infiniteblock' => 'neograničeno',
+'expiringblock' => 'istječe $1',
+'ipblocklistempty' => 'Popis blokiranja je prazan.',
+'blocklink' => 'blokiraj',
+'unblocklink' => 'deblokiraj',
+'contribslink' => 'doprinosi',
+'autoblocker' => 'Automatski ste blokirani jer je vašu IP adresu nedavno koristio "[[User:$1|$1]]" koji je blokiran zbog: "$2".',
+'blocklogpage' => 'Evidencija_blokiranja',
+'blocklogentry' => 'Blokiran je "[[$1]]" na rok $2',
+'blocklogtext' => 'Ovo je evidencija blokiranja i deblokiranja. Na popisu
+nema automatski blokiranih IP adresa. Za popis trenutnih zabrana i
+blokiranja vidi [[Special:Ipblocklist|listu IP blokiranja]].',
+'unblocklogentry' => 'Deblokiran "$1"',
+'range_block_disabled' => 'Isključena je administratorska naredba za blokiranje raspona IP adresa.',
+'ipb_expiry_invalid' => 'Vremenski rok nije valjan.',
+'ip_range_invalid' => 'Raspon IP adresa nije valjan.',
+'proxyblocker' => 'Zaštita od otvorenih posrednika (proxyja)',
+'proxyblockreason' => 'Vaša je IP adresa blokirana jer se radi o otvorenom posredniku (proxyju). Molim stupite u vezu s vašim davateljem internetskih usluga (ISP-om) ili službom tehničke podrške i obavijestite ih o ovom ozbiljnom sigurnosnom problemu.',
+'proxyblocksuccess' => 'Napravljeno.',
+'sorbsreason' => 'Vaša IP adresa je na popisu otvorenih posrednika na poslužitelju [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason'=> 'Vaša IP adresa je na popisu otvorenih posrednika na poslužitelju [http://www.sorbs.net SORBS] DNSBL. Ne možete otvoriti račun.',
+'lockdb' => 'Zaključaj bazu podataka',
+'unlockdb' => 'Otključaj bazu podataka',
+'lockdbtext' => 'Zaključavanjem baze će se suradnicima onemogućiti uređivanje stranica, mijenjanje postavki i popisa praćenja, i sve drugo što zahtijeva promjene u bazi podataka.
+Molim potvrdite svoju namjeru zaključavanja, te da ćete otključati bazu čim završite s održavanjem.',
+'unlockdbtext' => 'Otključavanjem baze omogućit ćete suradnicima uređivanje stranica,
+mijenjanje postavki, uređivanje popisa praćenja i druge stvari koje zahtijevaju promjene u bazi. Molim potvrdite svoju namjeru.',
+'lockconfirm' => 'Da, sigurno želim zaključati bazu.',
+'unlockconfirm' => 'Da, sigurno želim otključati bazu.',
+'lockbtn' => 'Zaključaj bazu podataka',
+'unlockbtn' => 'Otključaj bazu podataka',
+'locknoconfirm' => 'Niste potvrdili svoje namjere.',
+'lockdbsuccesssub' => 'Zaključavanje baze podataka uspjelo',
+'unlockdbsuccesssub' => 'Otključavanje baze podataka uspjelo',
+'lockdbsuccesstext' => 'Baza podataka je zaključana.
+<br />Ne zaboravite otključati po završetku održavanja.',
+'unlockdbsuccesstext' => 'Baza podataka je otključana.',
+'makesysoptitle' => 'Načini suradnika administratorom',
+'makesysoptext' => 'Ovaj obrazac služi birokratima za dodjeljivanje administratorskih prava pojedinom suradniku. Utipkajte ime suradnika u kućicu i pritisnite dugme kako biste suradniku dali administratorska prava.',
+'makesysopname' => 'Ime suradnika:',
+'makesysopsubmit' => 'Učini ovog suradnika administratorom',
+'makesysopok' => '<b>Suradnik "$1" je postao administrator</b>',
+'makesysopfail' => '<b>Suradnika "$1" nije se moglo učiniti administratorom. (Jeste li pravilno upisali ime?)</b>',
+'setbureaucratflag' => 'Postavi oznaku birokrata',
+'rightslogtext' => 'Ovo je evidencija promjena suradničkih prava.',
+'rights' => 'Prava:',
+'set_user_rights' => 'Postavi suradnička prava',
+'user_rights_set' => '<b>Prava za suradnika "$1" postavljena</b>',
+'set_rights_fail' => '<b>Prava za suradnika "$1" nisu postavljena. (Jeste li pravilno upisali ime?)</b>',
+'makesysop' => 'Učini suradnika administratorom',
+'already_sysop' => 'Ovaj je suradnik već administrator',
+'already_bureaucrat' => 'Ovaj je suradnik već birokrat',
+'movepage' => 'Premjesti stranicu',
+'movepagetext' => 'Korištenjem ovog obrasca ćete preimenovati stranicu i premjestiti sve stare izmjene
+na novo ime.
+Stari će se naslov pretvoriti u stranicu koja automatski preusmjerava na novi naslov.
+Poveznice na stari naslov ostat će iste; bilo bi dobro da
+[[Special:Maintenance|provjerite]] je li preusmjeravanje ispravno.
+Na vama je da se pobrinete da poveznice i dalje vode tamo
+gdje bi trebale.
+
+Stranica se \'\'\'neće\'\'\' premjestiti ako već postoji stranica s novim naslovom,
+osim u slučaju prazne stranice ili stranice za preusmjeravanje koja nema
+nikakvih starih izmjena. To znači: 1. ako pogriješite, možete opet preimenovati
+stranicu na stari naslov, 2. ne može vam se dogoditi da izbrišete neku postojeću stranicu.
+
+<b>OPREZ!</b>
+Ovo može biti drastična i neočekivana promjena kad su u pitanju popularne stranice,
+i zato dobro razmislite prije nego što preimenujete stranicu.',
+'movepagetalktext' => 'Stranica za razgovor, ako postoji, automatski će se premjestiti zajedno sa stranicom koju premještate. \'\'\'Stranica za razgovor neće se premjestiti ako:\'\'\'
+*premještate stranicu iz jednog prostora u drugi,
+*pod novim imenom već postoji stranica za razgovor s nekim sadržajem, ili
+*maknete kvačicu u kućici na dnu ove stranice.
+
+U tim slučajevima ćete morati sami premjestiti ili iskopirati stranicu za razgovor,
+ako to želite.',
+'movearticle' => 'Premjesti stranicu',
+'movenologin' => 'Niste prijavljeni',
+'movenologintext' => 'Ako želite premjestiti stranicu morate biti [[Special:Userlogin|prijavljeni]].',
+'newtitle' => 'Na novi naslov',
+'movepagebtn' => 'Premjesti stranicu',
+'pagemovedsub' => 'Premještanje uspjelo',
+'pagemovedtext' => 'Stranica "[[$1]]" premještena je na "[[$2]]".',
+'articleexists' => 'Stranica pod tim imenom već postoji ili ime koje ste odabrali nije u skladu s pravilima.
+Molimo odaberite drugo ime.',
+'talkexists' => '\'\'\'Sama stranica je uspješno prenesena, ali stranicu za razgovor nije bilo moguće prenijeti jer na odredištu već postoji stranica za razgovor. Molimo da ih ručno spojite.\'\'\'',
+'movedto' => 'premješteno na',
+'movetalk' => 'Premjesti i njezinu stranicu za razgovor ako je moguće.',
+'talkpagemoved' => 'Pripadajuća stranica za razgovor također je premještena.',
+'talkpagenotmoved' => 'Pripadajuća stranica za razgovor <strong>nije</strong> premještena.',
+'1movedto2' => '$1 premješteno na $2',
+'1movedto2_redir' => '$1 premješteno na $2 preko postojećeg preusmjeravanja',
+'movelogpage' => 'Evidencija premještanja',
+'movelogpagetext' => 'Ispod je popis premještenih stranica.',
+'movereason' => 'Razlog',
+'revertmove' => 'vrati',
+'delete_and_move' => 'Izbriši i premjesti',
+'delete_and_move_text' => '==Nužno brisanje==
+
+Odredišni članak "[[$1]]" već postoji. Želite li ga obrisati da biste napravili mjesto za premještaj?',
+'delete_and_move_confirm'=> 'Da, izbriši stranicu',
+'delete_and_move_reason'=> 'Obrisano kako bi se napravilo mjesta za premještaj.',
+'selfmove' => 'Izvorni i odredišni naslov su isti; ne mogu premjestiti stranicu na nju samu.',
+'immobile_namespace' => 'Odredišni naslov pripada posebnom tipu; u taj prostor ne mogu pomicati stranice.',
+'export' => 'Izvezi stranice',
+'exporttext' => 'Možete izvesti tekst i prijašnje promjene jedne ili više stranica uklopljene u XML kod. U budućim verzijama MediaWiki softvera bit će moguće uvesti ovakvu stranicu u neki drugi wiki. Trenutna verzija to još ne podržava.
+
+Za izvoz stranica unesite njihove naslove u polje ispod, jedan naslov po retku, i označite želite li trenutnu inačicu zajedno sa svim prijašnjima, ili samo trenutnu inačicu s informacijom o zadnjoj promjeni.
+
+U potonjem slučaju možete koristiti i poveznicu, npr. [[{{ns:Special}}:Export/Hrvatska]] za članak [[Hrvatska]].',
+'exportcuronly' => 'Uključi samo trenutnu inačicu, ne i sve prijašnje',
+'exportnohistory' => '----
+\'\'\'Napomena:\'\'\' izvoz cjelokupne stranice sa svim prethodnim izmjenama onemogućen je zbog opterećenja poslužitelja.',
+'allmessages' => 'Sve sistemske poruke',
+'allmessagesname' => 'Ime',
+'allmessagesdefault' => 'Prvotni tekst',
+'allmessagescurrent' => 'Trenutni tekst',
+'allmessagestext' => 'Ovo je popis svih sistemskih poruka u prostoru MediaWiki: .',
+'allmessagesnotsupportedUI'=> 'Trenutno odabrani jezik, <b>$1</b>, nije podržan u popisu Special:AllMessages na ovom mjestu.',
+'allmessagesnotsupportedDB'=> 'Uređivanje Special:AllMessages trenutno nije podržano jer je isključen parametar wgUseDatabaseMessages.',
+'allmessagesfilter' => 'Filter imena poruka:',
+'allmessagesmodified' => 'Prikaži samo promijenjene',
+'thumbnail-more' => 'Povećaj',
+'missingimage' => '<b>Nedostaje slika</b><br /><i>$1</i>',
+'filemissing' => 'Nedostaje datoteka',
+'thumbnail_error' => 'Pogrješka pri izradbi sličice: $1',
+'import' => 'Uvezi stranice',
+'importinterwiki' => 'Transwiki uvoz',
+'importtext' => 'Molim da izvezete ovu datoteku iz izvorišnog wikija koristeći pomagalo Special:Export, snimite je na svoj disk i postavite je ovdje.',
+'importfailed' => 'Uvoz nije uspio: $1',
+'importnotext' => 'Prazno ili bez teksta',
+'importsuccess' => 'Uvoz je uspio!',
+'importhistoryconflict' => 'Došlo je do konflikta među prijašnjim inačicama (ova je stranica možda već uvezena)',
+'importnosources' => 'Nije unesen nijedan izvor za transwiki uvoz i neposredno postavljanje povijesti je onemogućeno.',
+'importnofile' => 'Nije postavljena uvozna datoteka.',
+'importuploaderror' => 'Postavljanje uvozne datoteke nije uspjelo; možda je datoteka veća od dozvoljene veličine.',
+'tooltip-search' => 'Pretraži projekt {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Označi kao manju promjenu [alt-i]',
+'tooltip-save' => 'Sačuvaj promjene [alt-s]',
+'tooltip-preview' => 'Prikaži kako će izgledati, molimo koristite prije snimanja! [alt-p]',
+'tooltip-diff' => 'Prikaži promjene učinjene u tekstu. [alt-v]',
+'tooltip-compareselectedversions'=> 'Prikaži usporedbu izabranih inačica ove stranice. [alt-v]',
+'tooltip-watch' => 'Dodaj na popis praćenja [alt-w]',
+'monobook.css' => '/** Ovdje idu izmjene monobook stylesheeta */',
+'nodublincore' => 'Dublin Core RDF metapodaci su isključeni na ovom serveru.',
+'nocreativecommons' => 'Creative Commons RDF metapodaci su isključeni na ovom serveru.',
+'notacceptable' => 'Wiki server ne može dobaviti podatke u obliku kojega vaš klijent može pročitati.',
+'anonymous' => 'Anonimni suradnik projekta {{SITENAME}}',
+'siteuser' => 'Suradnik $1 na projektu {{SITENAME}}',
+'lastmodifiedatby' => 'Ovu je stranicu zadnji put mijenjao dana $2, $1 suradnik $3.',
+'and' => 'i',
+'othercontribs' => 'Temelji se na doprinosu suradnika $1.',
+'others' => 'drugih',
+'siteusers' => '{{SITENAME}} suradnik(ci) $1',
+'creditspage' => 'Autori stranice',
+'nocredits' => 'Za ovu stranicu nema podataka o autorima.',
+'spamprotectiontitle' => 'Zaštita od spama',
+'spamprotectiontext' => 'Stranicu koju ste željeli snimiti blokirao je filter spama. Razlog je vjerojatno vanjska poveznica.',
+'spamprotectionmatch' => 'Naš filter spama reagirao je na sljedeći tekst: $1',
+'subcategorycount' => 'Broj potkategorija u ovoj kategoriji: $1.',
+'categoryarticlecount' => 'Broj članaka u ovoj kategoriji: $1.',
+'listingcontinuesabbrev'=> ' nast.',
+'spambot_username' => 'MediaWiki zaštita od spama',
+'spam_reverting' => 'Vraćam na zadnju inačicu koja ne sadrži poveznice na $1',
+'spam_blanking' => 'Sve inačice sadrže poveznice na $1, brišem cjelokupni sadržaj',
+'infosubtitle' => 'Podaci o stranici',
+'numedits' => 'Broj promjena (članak): $1',
+'numtalkedits' => 'Broj promjena (stranica za razgovor): $1',
+'numwatchers' => 'Broj pratitelja: $1',
+'numauthors' => 'Broj autora (članak): $1',
+'numtalkauthors' => 'Broj autora (stranica za razgovor): $1',
+'mw_math_png' => 'Uvijek kao PNG',
+'mw_math_simple' => 'Ako je vrlo jednostavno HTML, inače PNG',
+'mw_math_html' => 'Ako je moguće HTML, inače PNG',
+'mw_math_source' => 'Ostavi u formatu TeX (za tekstualne preglednike)',
+'mw_math_modern' => 'Preporučeno za današnje preglednike',
+'mw_math_mathml' => 'Ako je moguće MathML (u pokusnoj fazi)',
+'markaspatrolleddiff' => 'Označi za pregledano',
+'markaspatrolledtext' => 'Označi ovaj članak pregledanim',
+'markedaspatrolled' => 'Pregledano',
+'markedaspatrolledtext' => 'Odabrana promjena već je pregledana.',
+'rcpatroldisabled' => 'Nadzor nedavnih promjena isključen',
+'rcpatroldisabledtext' => 'Naredba "Nadziri nedavne promjene" trenutno je isključena.',
+'markedaspatrollederror'=> 'Ne mogu označiti za pregledano',
+'markedaspatrollederrortext'=> 'Morate odabrati inačicu koju treba označiti za pregledanu.',
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Moja suradnička stranica\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Suradnička stranica za IP adresu pod kojom uređujete\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Moja stranica za razgovor\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Razgovor o suradnicima s ove IP adrese\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Moje postavke\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Popis stranica koje pratite.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Popis mojih doprinosa\');
+ta[\'pt-login\'] = new Array(\'o\',\'Predlažemo vam da se prijavite, ali nije obvezno.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Predlažemo vam da se prijavite, ali nije obvezno.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Odjavi se\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Razgovor o stranici\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Možete uređivati ovu stranicu. Koristite Pregled kako će izgledati prije nego što snimite.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Dodaj komentar ovom razgovoru.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Ova stranica je zaštićena. Možete pogledati izvorni kod.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Ranije izmjene na ovoj stranici.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Zaštiti ovu stranicu\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Izbriši ovu stranicu\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Vrati uređivanja na ovoj stranici prije nego što je izbrisana\');
+ta[\'ca-move\'] = new Array(\'m\',\'Premjesti ovu stranicu\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Dodaj ovu stranicu na svoj popis praćenja\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Ukloni ovu stranicu s popisa praćenja\');
+ta[\'search\'] = new Array(\'f\',\'Pretraži ovaj wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Glavna stranica\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Posjeti glavnu stranicu\');
+ta[\'n-portal\'] = new Array(\'\',\'O projektu, što možete učiniti, gdje je što\');
+ta[\'n-currentevents\'] = new Array(\'\',\'O trenutnim događajima\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Popis nedavnih promjena u wikiju.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Učitaj slučajnu stranicu\');
+ta[\'n-help\'] = new Array(\'\',\'Mjesto za pomoć suradnicima.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Podržite nas materijalno\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Popis svih stranica koje sadrže poveznice ovamo\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Nedavne promjene na stranicama na koje vode ovdašnje poveznice\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS feed za ovu stranicu\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom feed za ovu stranicu\');
+ta[\'t-contributions\'] = new Array(\'\',\'Pogledaj popis suradnikovih doprinosa\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Pošalji suradniku e-mail\');
+ta[\'t-upload\'] = new Array(\'u\',\'Postavi slike i druge medije\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Popis posebnih stranica\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Pogledaj sadržaj\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Pogledaj suradničku stranicu\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Pogledaj stranicu s opisom medija\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Ovo je posebna stranica koju nije moguće izravno uređivati.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Pogledaj stranicu o projektu\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Pogledaj stranicu o slici\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Pogledaj sistemske poruke\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Pogledaj predložak\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Pogledaj stranicu za pomoć\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Pogledaj stranicu kategorije\');',
+'deletedrevision' => 'Izbrisana stara inačica $1.',
+'previousdiff' => '← Usporedba s prethodnom',
+'nextdiff' => 'Usporedba sa sljedećom →',
+'imagemaxsize' => 'Ograniči veličinu slike na stranici s opisom:',
+'thumbsize' => 'Veličina sličice (umanjene inačice slike):',
+'showbigimage' => 'Učitaj u punoj veličini ($1x$2, $3 KB)',
+'newimages' => 'Galerija novih datoteka',
+'showhidebots' => '($1 botova)',
+'noimages' => 'Nema slika.',
+'specialloguserlabel' => 'Suradnik:',
+'speciallogtitlelabel' => 'Naslov:',
+'passwordtooshort' => 'Vaša je lozinka prekratka. Lozinke moraju sadržavati najmanje $1 znakova.',
+'mediawarning' => '\'\'\'Upozorenje\'\'\': Ova datoteka možda sadrži zlonamjerni program čije bi izvršavanje moglo ugroziti vaš računalni sustav.
+<hr />',
+'fileinfo' => '$1KB, MIME tip: <code>$2</code>',
+'metadata' => 'Metapodaci',
+'metadata-help' => 'Ova datoteka sadržava dodatne podatke koje je vjerojatno dodala digitalna kamera ili skener u procesu snimanja odnosno digitalizacije. Ako je datoteka mijenjana, podatci možda nisu u skladu sa stvarnim stanjem.',
+'metadata-expand' => 'Pokaži sve podatke',
+'metadata-collapse' => 'Sakrij dodatne podatke',
+'exif-imagewidth' => 'Širina',
+'exif-imagelength' => 'Visina',
+'exif-bitspersample' => 'Dubina boje',
+'exif-compression' => 'Način sažimanja',
+'exif-photometricinterpretation'=> 'Kolor model',
+'exif-orientation' => 'Orijentacija kadra',
+'exif-samplesperpixel' => 'Broj kolor komponenata',
+'exif-planarconfiguration'=> 'Princip rasporeda podataka',
+'exif-ycbcrsubsampling' => 'Omjer kompnente Y prema C',
+'exif-ycbcrpositioning' => 'Razmještaj komponenata Y i C',
+'exif-xresolution' => 'Vodoravna razlučivost',
+'exif-yresolution' => 'Okomita razlučivost',
+'exif-resolutionunit' => 'Jedinica razlučivosti',
+'exif-stripoffsets' => 'Položaj bloka podataka',
+'exif-rowsperstrip' => 'Broj redova u bloku',
+'exif-stripbytecounts' => 'Veličina komprimiranog bloka',
+'exif-jpeginterchangeformat'=> 'Udaljenost JPEG previewa od početka datoteke',
+'exif-jpeginterchangeformatlength'=> 'Količina bajtova JPEG previewa',
+'exif-transferfunction' => 'Funkcija preoblikovanja kolor prostora',
+'exif-whitepoint' => 'Kromaticitet bijele točke',
+'exif-primarychromaticities'=> 'Kromaticitet primarnih boja',
+'exif-ycbcrcoefficients'=> 'Matrični koeficijenti preobrazbe kolor prostora',
+'exif-referenceblackwhite'=> 'Mjesto bijele i crne točke',
+'exif-datetime' => 'Datum zadnje promjene datoteke',
+'exif-imagedescription' => 'Ime slike',
+'exif-make' => 'Proizvođač kamere',
+'exif-model' => 'Model kamere',
+'exif-software' => 'Korišteni softver',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Nositelj prava',
+'exif-exifversion' => 'Exif verzija',
+'exif-flashpixversion' => 'Podržana verzija Flashpixa',
+'exif-colorspace' => 'Kolor prostor',
+'exif-componentsconfiguration'=> 'Značenje pojedinih komponenti',
+'exif-compressedbitsperpixel'=> 'Dubina boje poslije sažimanja',
+'exif-pixelydimension' => 'Puna visina slike',
+'exif-pixelxdimension' => 'Puna širina slike',
+'exif-makernote' => 'Napomene proizvođača',
+'exif-usercomment' => 'Suradnički komentar',
+'exif-relatedsoundfile' => 'Povezani zvučni zapis',
+'exif-datetimeoriginal' => 'Datum i vrijeme slikanja',
+'exif-datetimedigitized'=> 'Datum i vrijeme digitalizacije',
+'exif-subsectime' => 'Dio sekunde u kojem je slikano',
+'exif-subsectimeoriginal'=> 'Dio sekunde u kojem je fotografirano',
+'exif-subsectimedigitized'=> 'Dio sekunde u kojem je digitalizirano',
+'exif-exposuretime' => 'Ekspozicija',
+'exif-fnumber' => 'F broj dijafragme',
+'exif-exposureprogram' => 'Program ekspozicije',
+'exif-spectralsensitivity'=> 'Spektralna osjetljivost',
+'exif-isospeedratings' => 'ISO vrijednost',
+'exif-oecf' => 'Optoelektronski faktor konverzije',
+'exif-shutterspeedvalue'=> 'Brzina zatvarača',
+'exif-aperturevalue' => 'Dijafragma',
+'exif-brightnessvalue' => 'Osvijetljenost',
+'exif-exposurebiasvalue'=> 'Kompenzacija ekspozicije',
+'exif-maxaperturevalue' => 'Minimalni broj dijafragme',
+'exif-subjectdistance' => 'Udaljenost do objekta',
+'exif-meteringmode' => 'Režim mjerača vremena',
+'exif-lightsource' => 'Izvor svjetlosti',
+'exif-flash' => 'Bljeskalica',
+'exif-focallength' => 'Žarišna duljina leće',
+'exif-subjectarea' => 'Položaj i površina objekta snimke',
+'exif-flashenergy' => 'Energija bljeskalice',
+'exif-spatialfrequencyresponse'=> 'Prostorna frekvencijska karakteristika',
+'exif-focalplanexresolution'=> 'Vodoravna razlučivost žarišne ravnine',
+'exif-focalplaneyresolution'=> 'Okomita razlučivost žarišne ravnine',
+'exif-focalplaneresolutionunit'=> 'Jedinica razlučivosti žarišne ravnine',
+'exif-subjectlocation' => 'Položaj subjekta',
+'exif-exposureindex' => 'Indeks ekspozicije',
+'exif-sensingmethod' => 'Tip senzora',
+'exif-filesource' => 'Izvorna datoteka',
+'exif-scenetype' => 'Tip scene',
+'exif-cfapattern' => 'Tip kolor filtera',
+'exif-customrendered' => 'Dodatna obrada slike',
+'exif-exposuremode' => 'Režim izbora ekspozicije',
+'exif-whitebalance' => 'Balans bijele',
+'exif-digitalzoomratio' => 'Razmjer digitalnog zooma',
+'exif-focallengthin35mmfilm'=> 'Ekvivalent žarišne daljine za 35 mm film',
+'exif-scenecapturetype' => 'Tip scene na snimci',
+'exif-gaincontrol' => 'Kontrola osvijetljenosti',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Zasićenje',
+'exif-sharpness' => 'Oštrina',
+'exif-devicesettingdescription'=> 'Opis postavki uređaja',
+'exif-subjectdistancerange'=> 'Raspon udaljenosti subjekata',
+'exif-imageuniqueid' => 'Jedinstveni identifikator slike',
+'exif-gpsversionid' => 'Verzija bloka GPS-informacije',
+'exif-gpslatituderef' => 'Sjeverna ili južna širina',
+'exif-gpslatitude' => 'Širina',
+'exif-gpslongituderef' => 'Istočna ili zapadna dužina',
+'exif-gpslongitude' => 'Dužina',
+'exif-gpsaltituderef' => 'Visina ispod ili iznad mora',
+'exif-gpsaltitude' => 'Visina',
+'exif-gpstimestamp' => 'Vrijeme po GPS-u (atomski sat)',
+'exif-gpssatellites' => 'Korišteni sateliti',
+'exif-gpsstatus' => 'Status prijemnika',
+'exif-gpsmeasuremode' => 'Režim mjerenja',
+'exif-gpsdop' => 'Preciznost mjerenja',
+'exif-gpsspeedref' => 'Jedinica brzine',
+'exif-gpsspeed' => 'Brzina GPS prijemnika',
+'exif-gpstrackref' => 'Tip azimuta prijemnika (pravi ili magnetni)',
+'exif-gpstrack' => 'Azimut prijemnika',
+'exif-gpsimgdirectionref'=> 'Tip azimuta slike (pravi ili magnetni)',
+'exif-gpsimgdirection' => 'Azimut slike',
+'exif-gpsmapdatum' => 'Korišteni geodetski koordinatni sustav',
+'exif-gpsdestlatituderef'=> 'Indeks zemlj. širine objekta',
+'exif-gpsdestlatitude' => 'Zemlj. širina objekta',
+'exif-gpsdestlongituderef'=> 'Indeks zemlj. dužine objekta',
+'exif-gpsdestlongitude' => 'Zemljopisna dužina objekta',
+'exif-gpsdestbearingref'=> 'Indeks pelenga objekta',
+'exif-gpsdestbearing' => 'Peleng objekta',
+'exif-gpsdestdistanceref'=> 'Mjerne jedinice udaljenosti objekta',
+'exif-gpsdestdistance' => 'Udaljenost objekta',
+'exif-gpsprocessingmethod'=> 'Ime metode obrade GPS podataka',
+'exif-gpsareainformation'=> 'Ime GPS područja',
+'exif-gpsdatestamp' => 'GPS datum',
+'exif-gpsdifferential' => 'GPS diferencijalna korekcija',
+'exif-compression-1' => 'Nesažeto',
+'exif-orientation-1' => 'Normalno',
+'exif-orientation-2' => 'Zrcaljeno po horizontali',
+'exif-orientation-3' => 'Zaokrenuto 180°',
+'exif-orientation-4' => 'Zrcaljeno po vertikali',
+'exif-orientation-5' => 'Zaokrenuto 90° suprotno od sata i zrcaljeno po vertikali',
+'exif-orientation-6' => 'Zaokrenuto 90° u smjeru sata',
+'exif-orientation-7' => 'Zaokrenuto 90° u smjeru sata i zrcaljeno po vertikali',
+'exif-orientation-8' => 'Zaokrenuto 90° suprotno od sata',
+'exif-planarconfiguration-1'=> 'zrnasti format',
+'exif-planarconfiguration-2'=> 'planarni format',
+'exif-componentsconfiguration-0'=> 'ne postoji',
+'exif-exposureprogram-0'=> 'Nepoznato',
+'exif-exposureprogram-1'=> 'Ručno',
+'exif-exposureprogram-2'=> 'Normalni program',
+'exif-exposureprogram-3'=> 'Prioritet dijafragme',
+'exif-exposureprogram-4'=> 'Prioritet zatvarača',
+'exif-exposureprogram-5'=> 'Umjetnički program (na temelju nužne dubine polja)',
+'exif-exposureprogram-6'=> 'Sportski program (na temelju što bržeg zatvarača)',
+'exif-exposureprogram-7'=> 'Portretni režim (za krupne planove s neoštrom pozadinom)',
+'exif-exposureprogram-8'=> 'Režim krajolika (za slike krajolika s oštrom pozadinom)',
+'exif-subjectdistance-value'=> '$1 metara',
+'exif-meteringmode-0' => 'Nepoznato',
+'exif-meteringmode-1' => 'Prosjek',
+'exif-meteringmode-2' => 'Prosjek s težištem na sredini',
+'exif-meteringmode-3' => 'Točka',
+'exif-meteringmode-4' => 'Više točaka',
+'exif-meteringmode-5' => 'Matrični',
+'exif-meteringmode-6' => 'Djelomični',
+'exif-meteringmode-255' => 'Drugo',
+'exif-lightsource-0' => 'Nepoznato',
+'exif-lightsource-1' => 'Dnevna svjetlost',
+'exif-lightsource-2' => 'Fluorescentno',
+'exif-lightsource-3' => 'Volframska žarulja',
+'exif-lightsource-4' => 'Bljeskalica',
+'exif-lightsource-9' => 'Lijepo vrijeme',
+'exif-lightsource-10' => 'Oblačno vrijeme',
+'exif-lightsource-11' => 'Sjena',
+'exif-lightsource-12' => 'Fluorescentna svjetlost (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Fluorescentna svjetlost (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Fluorescentna svjetlost (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Bijela fluorescencija (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standardno svjetlo A',
+'exif-lightsource-18' => 'Standardno svjetlo B',
+'exif-lightsource-19' => 'Standardno svjetlo C',
+'exif-lightsource-24' => 'ISO studijska svjetiljka',
+'exif-lightsource-255' => 'Drugi izvor svjetla',
+'exif-focalplaneresolutionunit-2'=> 'inči',
+'exif-sensingmethod-1' => 'Nedefinirano',
+'exif-sensingmethod-2' => 'Jednokristalni matrični senzor',
+'exif-sensingmethod-3' => 'Dvokristalni matrični senzor',
+'exif-sensingmethod-4' => 'Trokristalni matrični senzor',
+'exif-sensingmethod-5' => 'Sekvencijalni matrični senzor',
+'exif-sensingmethod-7' => 'Trobojni linearni senzor',
+'exif-sensingmethod-8' => 'Sekvencijalni linearni senzor',
+'exif-filesource-3' => 'Digitalni fotoaparat',
+'exif-scenetype-1' => 'Izravno fotografirana slika',
+'exif-customrendered-0' => 'Normalni proces',
+'exif-customrendered-1' => 'Nestadardni proces',
+'exif-exposuremode-0' => 'Automatski',
+'exif-exposuremode-1' => 'Ručno',
+'exif-exposuremode-2' => 'Automatski sa zadanim rasponom',
+'exif-whitebalance-0' => 'Automatski',
+'exif-whitebalance-1' => 'Ručno',
+'exif-scenecapturetype-0'=> 'Standardno',
+'exif-scenecapturetype-1'=> 'Pejzaž',
+'exif-scenecapturetype-2'=> 'Portret',
+'exif-scenecapturetype-3'=> 'Noćno',
+'exif-gaincontrol-0' => 'Nema',
+'exif-gaincontrol-1' => 'Malo povećanje',
+'exif-gaincontrol-2' => 'Veliko povećanje',
+'exif-gaincontrol-3' => 'Malo smanjenje',
+'exif-gaincontrol-4' => 'Veliko smanjenje',
+'exif-contrast-0' => 'Normalno',
+'exif-contrast-1' => 'Meko',
+'exif-contrast-2' => 'Tvrdo',
+'exif-saturation-0' => 'Normalno',
+'exif-saturation-1' => 'Niska saturacija',
+'exif-saturation-2' => 'Visoka saturacija',
+'exif-sharpness-0' => 'Normalno',
+'exif-sharpness-1' => 'Meko',
+'exif-sharpness-2' => 'Tvrdo',
+'exif-subjectdistancerange-0'=> 'Nepoznato',
+'exif-subjectdistancerange-1'=> 'Krupni plan',
+'exif-subjectdistancerange-2'=> 'Bliski plan',
+'exif-subjectdistancerange-3'=> 'Udaljeno',
+'exif-gpslatitude-n' => 'Sjever',
+'exif-gpslatitude-s' => 'Jug',
+'exif-gpslongitude-e' => 'Istok',
+'exif-gpslongitude-w' => 'Zapad',
+'exif-gpsstatus-a' => 'Mjerenje u tijeku',
+'exif-gpsstatus-v' => 'Spreman za prijenos',
+'exif-gpsmeasuremode-2' => 'Dvodimenzionalno mjerenje',
+'exif-gpsmeasuremode-3' => 'Trodimenzionalno mjerenje',
+'exif-gpsspeed-k' => 'kmh',
+'exif-gpsspeed-m' => 'mph',
+'exif-gpsspeed-n' => 'čv',
+'exif-gpsdirection-t' => 'Pravi sjever',
+'exif-gpsdirection-m' => 'Magnetni sjever',
+'edit-externally' => 'Uredi koristeći se vanjskom aplikacijom',
+'edit-externally-help' => 'Vidi [http://meta.wikimedia.org/wiki/Help:External_editors setup upute] za više informacija.',
+'recentchangesall' => 'sve',
+'imagelistall' => 'sve',
+'watchlistall1' => 'sve',
+'watchlistall2' => 'sve',
+'namespacesall' => 'sve',
+'confirmemail' => 'Potvrda e-mail adrese',
+'confirmemail_text' => 'U ovom wikiju morate prije korištenja e-mail naredbi verificirati svoju e-mail adresu. Kliknite na dugme ispod kako biste
+poslali poruku s potvrdom na vašu adresu. U poruci će biti poveznica koju morate otvoriti u
+svom web pregledniku da biste verificirali adresu.',
+'confirmemail_send' => 'Pošalji kôd za potvrdu e-mail adrese',
+'confirmemail_sent' => 'Poruka s potvrdom je poslana.',
+'confirmemail_sendfailed'=> 'Poruka s potvrdom nije se mogla poslati. Provjerite pravilnost adrese.',
+'confirmemail_invalid' => 'Pogrešna potvrda. Kod je možda istekao.',
+'confirmemail_success' => 'Vaša je e-mail adresa potvrđena. Možete se prijaviti i uživati u wikiju.',
+'confirmemail_loggedin' => 'Vaša je e-mail adresa potvrđena.',
+'confirmemail_error' => 'Došlo je do greške kod snimanja vaše potvrde.',
+'confirmemail_subject' => '{{SITENAME}}: potvrda e-mail adrese',
+'confirmemail_body' => 'Vi ili netko drugi s IP adrese $1 ste otvorili
+suradnički račun pod imenom "$2" s ovom e-mail adresom na Wikipediji.
+
+Kako biste potvrdili da je ovaj suradnički račun uistinu vaš i
+uključili e-mail naredbe na Wikipediji, otvorite u vašem
+pregledniku sljedeću poveznicu:
+
+$3
+
+Ako ovo *niste* vi, nemojte otvarati poveznicu.
+
+Valjanost ovog potvrdnog koda istječe $4.',
+'tryexact' => 'Pokušaj naći točan pogodak',
+'searchfulltext' => 'Traži po cjelokupnom tekstu',
+'createarticle' => 'Stvori članak',
+'scarytranscludedisabled'=> '[Interwiki transkluzija isključena]',
+'scarytranscludefailed' => '[Dobava predloška nije uspjela; $1; ispričavam se]',
+'scarytranscludetoolong'=> '[URL je predug; ispričavam se]',
+'trackbackbox' => '<div id=\'mw_trackbacks\'>
+\'\'Trackbackovi\'\' za ovaj članak:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 izbrisati])',
+'trackbackdeleteok' => 'Trackback izbrisan.',
+'deletedwhileediting' => 'Upozorenje: dok ste uređivali stranicu netko ju je izbrisao!',
+'confirmrecreate' => 'Suradnik [[User:$1|$1]] ([[User talk:$1|talk]]) izbrisao je ovaj članak nakon što ste ga počeli uređivati. Razlog brisanja
+: \'\'$2\'\'
+Potvrdite namjeru vraćanja ovog članka.',
+'recreate' => 'Vrati',
+'redirectingto' => 'Preusmjeravam na [[$1]]...',
+'confirm_purge' => 'Isprazniti međuspremnik stranice?
+
+$1',
+'youhavenewmessagesmulti'=> 'Imate nove poruke na $1',
+'searchcontaining' => 'Traži članke koji sadržavaju \'\'$1\'\'.',
+'searchnamed' => 'Traži članke po imenu \'\'$1\'\'.',
+'articletitles' => 'Članci koji počinju s \'\'$1\'\'',
+'hideresults' => 'Sakrij rezultate',
+'displaytitle' => '(Poveznice na ovu stranicu trebaju biti pod naslovom [[$1]])',
+);
+?>
diff --git a/languages/messages/MessagesHsb.php b/languages/messages/MessagesHsb.php
new file mode 100644
index 000000000000..6aec6e8317c2
--- /dev/null
+++ b/languages/messages/MessagesHsb.php
@@ -0,0 +1,1575 @@
+<?php
+/**
+ * Upper Sorbian (Hornjoserbsce)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'de';
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Specialnje',
+ NS_MAIN => '',
+ NS_TALK => 'Diskusija',
+ NS_USER => 'Wužiwar',
+ NS_USER_TALK => 'Diskusija_z_wužiwarjom',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_diskusija',
+ NS_IMAGE => 'Wobraz',
+ NS_IMAGE_TALK => 'Diskusija_k_wobrazej',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_diskusija',
+ NS_TEMPLATE => 'Předłoha',
+ NS_TEMPLATE_TALK => 'Diskusija_k_předłoze',
+ NS_HELP => 'Pomoc',
+ NS_HELP_TALK => 'Pomoc_diskusija',
+ NS_CATEGORY => 'Kategorija',
+ NS_CATEGORY_TALK => 'Diskusija_ke_kategoriji'
+);
+
+
+$messages = array(
+
+'1movedto2' => 'je [[$1]] pod titul [[$2]] přesunył(a)',
+'1movedto2_redir' => 'je [[$1]] pod titul [[$2]] přesunył(a) a při tym daleposrědkowanje přepisał(a).',
+'common.css' => '/* CSS w tutej dataji budźe so na wšěch stronow wuskutkować. */',
+'monobook.css' => '/* CSS wobdźěłać, zo by so skin „monobook” za wšěčh wužiwarjow tutoho skina priměrił */',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Moja wužiwarska strona\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Wužiwarska strona za IP-adresu, z kotrejž tuchwilu dźěłaće\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Moja diskusijna strona\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskusija wo změnach z tuteje ip-adresy\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Moje nastajenja\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Lisćina stronow, kotrež wobkedźbujeće\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Lisćina mojich přinoškow\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Móžeće so woměrje přizjewić, ale to zawjazowace njeje.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Móžeće so woměrje přizjewić, ale to zawjazowace njeje.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'So wotzjewić\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskusija wo stronje\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Móžeće stronu wobdźěłać. Prošu wužijće tłóčku přehladka do składowanja.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Nowy wotrězk k diskusiji dodać.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Tuta strona je škitana. Móžeće jeje žórło wobhladać.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Stawizny tuteje strony\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Stronu škitać\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Stronu wušmórnyć\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Změny wobnowić, kotrež buchu do wušmórnjenja sčinjene\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Stronu přesunyć\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Stronu wobkedźbowankam přidać\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Stronu z wobkedźbowankow wotstronić\');
+ ta[\'search\'] = new Array(\'f\',\'W cyłym wiki pytać\');
+ ta[\'p-logo\'] = new Array(\'\',\'Hłowna strona\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Hłownu stronu pokazać\');
+ ta[\'n-portal\'] = new Array(\'\',\'Wo projekće, što móžeće činić, hdźe móžeće informacije namakać\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Pozadkowe informacije wo aktualnych podawkach pytać\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Lisćina aktualnych změnow w tutym wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Připadnu strony wopytać\');
+ ta[\'n-help\'] = new Array(\'\',\'Pomocna strona\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Projekt podpěrować\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lisćina wšěch stronow, kotrež sem pokazuja\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Aktualne změny w stronach, na kotrež tuta stronu pokaza\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS-feed za tutu stronu\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom-feed za tutu stronu\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Přinoški tutoho wužiwarja wobhladać\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Tutomu wužiwarjej email pósłać\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Wobrazy abo dataje nahrawać\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lisćina wšěch specialnych stronow\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Stronu wobhladać\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Wužiwarsku stronu wobhladać\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Datajowu stronu wobhladać\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'To je specialna strona, njemóžeće stronu samu wobdźěłać.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Projektowu stronu wobhladać\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Wobrazowu stronu wobhladać\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Systemowu zdźělenku wobhladać\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Předłohu wobhladać\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Pomocnu stronu wobhladać\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Kategorijnu stronu wobhladać\');',
+'about' => 'Wo',
+'aboutpage' => 'Wo {{GRAMMAR:lokatiw|{{SITENAME}}}}',
+'aboutsite' => 'Wo {{GRAMMAR:lokatiw|{{SITENAME}}}}',
+'accmailtext' => 'Hesło za „$1” bu na adresu $2 pósłane.',
+'accmailtitle' => 'Hesło bu pósłane.',
+'accountcreated' => 'Wužiwarske konto bu załožene',
+'accountcreatedtext' => 'Wužiwarske konto za $1 bu załožene.',
+'acct_creation_throttle_hit'=> 'Wodajće, maće hižo $1 wužiwarskich kontow załoženych. Njemóžeće dalše załožić.',
+'actioncomplete' => 'Dokónčene',
+'addedwatch' => 'Strona bu wobkedźbowankam přidata.',
+'addedwatchtext' => 'Strona „[[:$1]]” bu [[Special:Watchlist|wobkedźbowankam]] přidata. Přichodne změny k tutej stronje a z njej zwjazanej diskusijnej stronje budu tam naličene, a titul strony budźe so <b>tučne</b> w [[Special:Recentchanges|lisćinje aktualnych změnow]] jewić.
+
+Jelizo chceće stronu ze swojich wobkedźbowankow lisćiny pozdźišo wotstronić, klikńće na „Njewobkedźbować”.',
+'allarticles' => 'Wšě nastawki',
+'allinnamespace' => 'Wšě strony (mjenowy rum $1)',
+'alllogstext' => 'Kombinowany pohlad protokolow nahraća, wotstronjenja, škita, blokowanja a zrjadowanja wužiwarskich prawow. Móžeće pohlad wobmjezować, wuběrajo typ protokola, wužiwarske mjeno abo potrjechenu stronu.',
+'allmessages' => 'Systemowe powěsće',
+'allmessagescurrent' => 'Tuchwilny tekst',
+'allmessagesdefault' => 'Standardny tekst',
+'allmessagesfilter' => 'Filter za jednotliwe powěsće:',
+'allmessagesmodified' => 'Jenož změnjene pokazać',
+'allmessagesname' => 'Mjeno',
+'allmessagesnotsupportedDB'=> 'Strona <b>„Special:Allmessages”</b> njemóže so wužiwać, dokelž je datowa banka wotpinata.',
+'allmessagesnotsupportedUI'=> 'Waše rěčne nastajenje <b>„$1”</b> so w tutym wiki wot strony „Special:Allmessages” njepodpěruje.',
+'allmessagestext' => 'To je lisćina wšěch systemowych powěsćow, kotrež w mjenowym rumje MediaWiki k dispoziciji steja.',
+'allnotinnamespace' => 'Wšě strony (nic w mjenowym rumje $1)',
+'allowemail' => 'Přijeće emailow wot druhich wužiwarjow zmóžnić',
+'allpages' => 'Wšě nastawki',
+'allpagesbadtitle' => 'Mjeno strony, kotrež sće zapodał(a), njebě płaćiwe. Měješe pak rěčny, pak interwiki-prefiks abo wobsahowaše jedne abo wjace znamjow, kiž so w titulach wužiwać njesmědźa.',
+'allpagesfrom' => 'Strony pokazać, započinajo z:',
+'allpagesnext' => 'Přichodne',
+'allpagesprefix' => 'Strony pokazać z prefiksom:',
+'allpagesprev' => 'Předchadne',
+'allpagessubmit' => 'Pokazać',
+'alphaindexline' => '$1 do $2',
+'already_bureaucrat' => 'Tutón wužiwar je hižo běrokrat.',
+'already_sysop' => 'Tutón wužiwar je hižo administrator.',
+'alreadyloggedin' => '<strong>Wužiwar $1, sće hižo přizjewjeny!</strong><br />',
+'alreadyrolled' => 'Njemóžno poslednu změnu [[:$1]] wužiwarja [[User:$2|$2]] ([[User talk:$2|diskusija]]) cofnyć; něchtó druhi je tutu stronu hižo změnił abo změnu cofnył.
+
+Poslednja změna běše wot wužiwarja [[User:$3|$3]] ([[User talk:$3|diskusija]]).',
+'ancientpages' => 'Najstarše nastawki',
+'and' => 'a',
+'anoneditwarning' => '<b>Kedźbu:</b> Njejsće přizjewjeny(a). Změny budu z Wašej IP-adresu składowane.',
+'anontalk' => 'Z tutej IP diskutować',
+'anontalkpagetext' => '----
+<i>To je diskusijna strona za anonymneho wužiwarja, kiž hišće konto załožił njeje abo je njewužiwa. Dyrbimy tohodla numerisku IP-adresu wužiwać, zo bychmy jeho/ju identifikowali. Tajka adresa hodźi so wot wjacorych wužiwarjow zhromadnje wužiwać. Sće-li anonymny wužiwar a měniće, zo buchu irelewantne komentary k wam pósłane, [[Special:Userlogin|załožće konto abo přizjewće so]], zo byšće přichodnu šmjatańcu wobešoł/wobešła.</i>',
+'anonymous' => 'Anonymny wužiwar/anonymni wužiwarjo {{GRAMMAR:genitiw|{{SITENAME}}}}',
+'apr' => 'apr',
+'april' => 'apryl',
+'april-gen' => 'apryla',
+'article' => 'Nastawk',
+'articleexists' => 'Strona z tutym titulom hižo eksistuje abo mjeno, kotrež sće wubrał, płaćiwe njeje. Prošu wubjerće druhe mjeno.',
+'articlepage' => 'Nastawk',
+'articletitles' => 'Nastawki, kotrež z <i>$1</i> započnu',
+'aug' => 'awg',
+'august' => 'awgust',
+'august-gen' => 'awgusta',
+'autoblocker' => 'Awtomatiske blokowanje, dokelž Waša IP adresa bu tuchwilu wot wužiwarja „[[User:$1|$1]]” wužiwana. Přičina, podata přez blokowaceho administratora je: „<b>$2</b>”.',
+'autoredircomment' => 'Posrědkuju k stronje „[[$1]]”',
+'badaccess' => 'Nimaće wotpowědne dowolnosće',
+'badarticleerror' => 'Tuta akcija njeda so na tutej stronje wuwjesć.',
+'badfilename' => 'Mjeno dataje bu na „$1” změnjene.',
+'badfiletype' => '„.$1” poručowany format za dataje njeje.',
+'badipaddress' => 'Njepłaćiwa IP-adresa',
+'badquery' => 'Špatnje formulowane pytanske wotprašenje',
+'badquerytext' => 'Njemóžachmy waše wotprašenje předźěłować. Přičina za to je najskerje, zo sće spytał za słowom pytać, kotrež je krótše hač tři pismiki, štož so hišće njepodpěruje. Snadź sće tež wuraz wopak napisał, na přikład „ryba a a šupizny”. Prošu spytajće hišće raz.',
+'badretype' => 'Hesle, kotrejž sće zapisał(a), so njekryjetej.',
+'badsig' => 'Njepłaćiwa signatura, prošu HTML přepruwować.',
+'badtitle' => 'Wopačny titul',
+'badtitletext' => 'Požadany titul strony běše njepłaćiwe, prózdne abo njekorektny titul z inter-language abo inter-wiki. Snano jewi so w nim znamjo, kiž so w titulach wužiwać njehodźi.',
+'blanknamespace' => '(Nastawki)',
+'blockededitsource' => 'Tekst <b>Wašich změnow</b> strony <b>$1</b> so tu pokazuje:',
+'blockedoriginalsource' => 'To je žórłowy tekst strony <b>$1</b>:',
+'blockedtext' => 'Waše wužiwarske mjeno abo Waša IP-adresa bu přez $1 blokowane(-a).
+Podata přičina je:<br /><i>$2</i><br />Wy móhł(a) $1 kontaktować abo jednoho z druhich [[Project:Administratorojo|administratorow]], zo byštej blokowanje diskutowałoj.
+
+Wobkedźbujće zo njebyšće móhł funkciju „Tutomu wužiwarjej email pósłać” wužiwać chibazo maće emailowu adresu registrowanu w swojich [[Special:Preferences|wužiwarskich nastajenjach]].
+
+Waša IP-adresa je $3. Prošu zapodajće tutu adresu do swojich wotprašowanjow, kotrež přewjedźeće.',
+'blockedtitle' => 'Wužiwar je blokowany',
+'blockip' => 'Wužiwarja blokować',
+'blockipsuccesssub' => 'Blokowanje wuspěšne',
+'blockipsuccesstext' => 'Wužiwar „[[Special:Contributions/$1|$1]]” bu blokowany.
+
+Hlej [[Special:Ipblocklist|Lisćinu blokowanjow]], zo byšće blokowanja přepruwował.',
+'blockiptext' => 'Wužijće formular deleka, zo byšće pisanski přistup za podatu IP-adresu abo wužiwarske mjeno blokował(a). To měło so jenož činić, zo by so wandalizmej zadźěwało a woptpowědujo [[Project:Policy|prawidłam]]. Zapisajće deleka přičinu (na př. citujo wosebite strony, kotrež běchu wopor wandalizma).',
+'blocklink' => 'blokować',
+'blocklistline' => '$1, $2 blokowaše wužiwarja „$3” ($4)',
+'blocklogentry' => 'je wužiwarja „[[$1]]” blokował(a) z časom spadnjenja $2',
+'blocklogpage' => 'Protokol blokowanja',
+'blocklogtext' => 'Je to protokol blokowanjow a dopušćenjow wužiwarjow. Awtomatisce blokowane IP-adresy so njenaličuja. Hlej [[Special:Ipblocklist|lisćinu blokowanych IP-adresow]] za přehlad tuchwilnych blokowanjow.',
+'bold_sample' => 'Tučny tekst',
+'bold_tip' => 'Tučny tekst',
+'booksources' => 'Pytanje po ISBN',
+'booksourcetext' => 'Deleka je lisćina pokazow k druhim sydłam, kotrež nowe a wužite knihi předawaja a kotrež móža dalše informacije wo knihach, za kotrymiž pytaće, měć.',
+'brokenredirects' => 'Skóncowane daleposrědkowanja',
+'brokenredirectstext' => 'Naslědne daleposrědkowanja na njeeksistowace strony pokazuja:',
+'bugreports' => 'Bug reports',
+'bugreportspage' => 'Project:Bug reports',
+'bydate' => 'datumje',
+'byname' => 'mjenje',
+'bysize' => 'wulkosći',
+'cachederror' => 'Naslědne je kopija z pufrowaka a njemóhło hižo aktualne być.',
+'cancel' => 'Přetorhnyć',
+'cannotdelete' => 'Njeje móžno podatu stronu abo dataju wušmórnyć. (Po zdaću je to hižo něchtó druhi činił.)',
+'cannotundelete' => 'Wobnowjenje zwrěšćiło; něchtó druhi je stronu prjedy wobnowił.',
+'cantrollback' => 'Njemóžno změnu cofnyć; strona nima druhich awtorow.',
+'categories' => 'Kategorije',
+'categoriespagetext' => 'Slědowace kategorije w tutym wiki ekstistuja.',
+'category_header' => 'Nastawki w kategoriji „$1”',
+'categoryarticlecount' => 'W tutej kategoriji je {{PLURAL:$1|jedyn nastawk|$1 nastawkow}}.',
+'categorypage' => 'Kategoriju pokazać',
+'changed' => 'změnjena',
+'changepassword' => 'Hesło změnić',
+'changes' => 'změny',
+'clearwatchlist' => 'Wobkedźbowanki wuprózdnić',
+'clearyourcache' => '<b>Kedźbu:</b> Po składowanju dyrbiće snano pufrowak swojeho browsera wuprózdnić, <b>Mozilla/Firefox/Safari:</b> tłóčće na <i>Umsch</i> kliknjo na <i>Znowa</i> abo tłóčce <i>Strg-Umsch-R</i> (<i>Cmd-Shift-R</i> na Apple Mac); <b>IE:</b> tłóčće <i>Strg</i> kliknjo na symbol <i>Aktualisieren</i> abo tłóčće <i>Strg-F5</i>; <b>Konqueror:</b>: Klikńće jenož na tłóčatko <i>Erneut laden</i> abo tłočće <i>F5</i>; Wužiwarjo <b>Opery</b> móža swój pufrowak dospołnje w <i>Tools→Preferences</i> wuprózdnić.',
+'columns' => 'Stołpiki:',
+'compareselectedversions'=> 'Wubranej wersiji přirunać',
+'confirm' => 'Wobkrućić',
+'confirm_purge' => 'Pufrowak strony wuprózdnić? $1',
+'confirm_purge_button' => 'OK',
+'confirmdelete' => 'Wušmórnjenje wobkrućić',
+'confirmdeletetext' => 'Sće so rozsudźił(a) stronu abo dataju hromadźe ze jeje stawiznami z datoweje banki wotstronić. Prošu wobkručće, zo to zwotpohladom činiće, zo rozumiće sćěwki a zo činiće to po [[{{MSG:MediaWiki:Policy-url}}|prawidłami]] {{GRAMMAR:genitiw|{{SITENAME}}}}.',
+'confirmedittext' => 'Waša emailowa adresa dyrbi so wobkrućić, prjedy hač móžeće strony wobdźěłować. Prošu zapodajće a wobkrućće swoju emailowu adresu přez swoje [[Special:Preferences|nastajenja]].',
+'confirmedittitle' => 'Waša emailowa adresa dyrbi so wobkrućić, zo byšće strony wobdźěłować móhł(a).',
+'confirmemail' => 'Emailowu adresu potwjerdźić',
+'confirmemail_body' => 'Něchtó, najskerje Wy z IP-adresu $1, je wužiwarske konto "$2" z tutej emailowej adresu we {{GRAMMAR:lokatiw|{{SITENAME}}}} załožił.
+
+Zo by so wobkrućiło, zo tute konto woprawdźe Wam słuša a zo bychu emailowe funkcije na {{{GRAMMAR:lokatiw|{{SITENAME}}}} zaktiwizowali, wočińće tutón wotkaz w swojim browserje:
+$3
+
+Jeli to Wy *njejsće*, njeslědujće wotkaz. Tutón wobkrućenski kode spadnje dnja $4.',
+'confirmemail_error' => 'Zmylk při wobkrućenju Wašeje emailoweje adresy.',
+'confirmemail_invalid' => 'Njepłaćiwy wobkrućenski kode. Kode móhł spadnjeny być.',
+'confirmemail_loggedin' => 'Waša emailowa adresa bu nětko wobkrućena.',
+'confirmemail_needlogin'=> 'Dyrbiće so $1, zo byšće emailowu adresu wobkručić móhł(a).',
+'confirmemail_send' => 'Wobkrućenski kode pósłać',
+'confirmemail_sendfailed'=> 'Njebě móžno wobkrućenski email słać. Přepruwujće adresu za njepłaćiwymi znamješkami.',
+'confirmemail_sent' => 'Wobkrućenski email pósłany.',
+'confirmemail_subject' => '{{SITENAME}} – wobkrućenje emailoweje adresy',
+'confirmemail_success' => 'Waša emailowa adresa bu wobkrućena. Móžeće so nětko přizjewić.',
+'confirmemail_text' => 'Tutón wiki sej žada, zo swoju emailowu adresu wobručće, prjedy hač emailowe funkcije wužiwaće. Zaktiwizujće tłóčku deleka, zo by so wobkrućenski email k wašej adresy słał. Tutón email zapřijmje pokaz, kotryž kode wobsahuje; začitajće pokaz do swojeho browsera, zo byšće wobkrućił, zo emailowa adresa je płaćiwa.',
+'confirmprotect' => 'Škit wobkrućić',
+'confirmprotecttext' => 'Chceće tutu stronu woprawdźe škitać?',
+'confirmrecreate' => 'Wužiwar [[User:$1|$1]] ([[User talk:$1|talk]]) je stronu wušmórnył po tym zo sče započał(a) ju wobdźěłać z přičinu:
+: <i>$2</i>
+Prošu wobkručće, zo chceće ju woprawdźe zaso załožić.',
+'confirmunprotect' => 'Zběhnjenje škita wobkrućić',
+'confirmunprotecttext' => 'Chceće škit za tutu stronu woprawdźe zběhnyć?',
+'contextchars' => 'Kontekst na rjadku:',
+'contextlines' => 'Rjadki na wuslědk:',
+'contribslink' => 'přinoški',
+'contribsub' => 'Za wužiwarja $1',
+'contributions' => 'Wužiwarske přinoški',
+'copyright' => 'Wobsah steji pod {{GRAMMAR:lokatiw|$1}} k dispoziciji.',
+'copyrightpage' => 'Project:Awtorske prawa',
+'copyrightpagename' => '{{SITENAME}} awtorske prawa',
+'copyrightwarning' => 'Prošu wobkedźbujće, zo wšě přinoški za {{GRAMMAR:akuzatiw|{{SITENAME}}}} maja za pod $2 dopušćene (hlej $1 za dalše informacije). Jelizo nochceće, zo waš přinošk so po dobrozdaću wobdźěłuje a rozšěrja, njeskładujće jón.
+
+Lubiće nam tež, zo sće jón sam napisał(a) abo ze zjawneje domeny abo z podobneho swobodneho žórła kopěrował(a).
+
+<strong>NJEZAŁOŽĆE PŘINOŠKI Z COPYRIGHTOM BJEZ DOWOLENJA!</strong>',
+'copyrightwarning2' => 'Prošu wobkedźbujće, zo wšě přinoški za {{GRAMMAR:akuzatiw|{{SITENAME}}}} móhli so wot druhich wužiwarjow wobdźěłować, měnjeć abo wotstronjeć. Jelizo nochceće, zo waš přinošk so po dobrozdaću wobdźěłuje, njeskładujće jón.
+
+Lubiće nam tež, zo sće jón sam napisał(a) abo ze zjawneje domeny abo z podobneho swobodneho žórła kopěrował(a) (hlej $1 za detaile).
+
+<strong>NJEZAŁOŽĆE PŘINOŠKI Z COPYRIGHTOM BJEZ DOWOLENJA!</strong>',
+'couldntremove' => 'Njemóžu poziciju \'$1\' wotstronić...',
+'createaccount' => 'Wužiwarske konto załožić',
+'createaccountmail' => 'z emailom',
+'createarticle' => 'Nastawk załožić',
+'created' => 'załožena',
+'creditspage' => 'Dźakprajenje awtoram',
+'cur' => 'akt',
+'currentevents' => 'Aktualne podawki',
+'currentevents-url' => 'Aktualne podawki',
+'currentrev' => 'Aktualna wersija',
+'currentrevisionlink' => 'Aktualnu wersiju pokazać',
+'data' => 'Daty',
+'databaseerror' => 'Zmylk w datowej bance',
+'datedefault' => 'Standard',
+'dateformat' => 'Format datuma',
+'datetime' => 'Datum a čas',
+'dberrortext' => 'Syntaktiski zmylk při wotprašowanju datoweje banki.
+To móhło bug w programje być. Poslednje spytane wotprašenje w datowej bance běše:
+<blockquote><tt>$1</tt></blockquote>
+z funkcije „<tt>$2</tt>”.
+MySQL wróći zmylk „<tt>$3: $4</tt>”.',
+'dberrortextcl' => 'Syntaktiski zmylk je we wotprašowanju datoweje banki wustupił.
+Poslednje wotprašenje w datowej bance běše:
+„$1”
+z funkcije „$2”.
+MySQL wróći zmylk „$3: $4”.',
+'deadendpages' => 'Nastawki bjez wotkazow',
+'dec' => 'dec',
+'december' => 'december',
+'december-gen' => 'decembra',
+'default' => 'Standard',
+'defaultns' => 'W tutych mjenowych rumach awtomatisce pytać:',
+'defemailsubject' => '{{SITENAME}} email',
+'delete' => 'Wušmórnyć',
+'delete_and_move' => 'wotstronić a přesunyć',
+'delete_and_move_confirm'=> 'Haj, nastawk wušmórnyć.',
+'delete_and_move_reason'=> 'Strona bu wušmórnjena, zo by so přesunjenje zmóžniło',
+'delete_and_move_text' => '==Wotstronjenje trěbne==
+
+Cilowy nastawk „[[$1]]” hižo eksistuje. Chceće jón wušmórnyć, zo by so přesunjenje zmóžniło?',
+'deletecomment' => 'Přičina wušmórnjenja',
+'deletedarticle' => 'Strona „[[$1]]” bu wušmórnjena.',
+'deletedrev' => '[wušmórnjena]',
+'deletedrevision' => 'Stara wersija $1 wušmórnjena',
+'deletedtext' => '„$1” bu wotstronjene. Hlej $2 za zapis tuchwilnych wotstronjenjow.',
+'deletedwhileediting' => '<b>Kedźbu:</b> Strona bu wušmórnjena po tym zo sće započał(a) ju wobdźěłać!',
+'deleteimg' => 'wotstr',
+'deleteimgcompletely' => 'Wšě wersije tuteje dataje wotstronić',
+'deletepage' => 'Stronu wušmórnyć',
+'deletesub' => '(„$1” so wušmórnje)',
+'deletethispage' => 'Stronu wušmórnyć',
+'deletionlog' => 'Protokol wušmórnjenjow',
+'dellogpage' => 'Protokol wušmórnjenjow',
+'dellogpagetext' => 'Deleka je lisćina najaktualnišich wušmórnjenjow.',
+'destfilename' => 'Mjeno ciloweje dataje',
+'diff' => 'rozdźěl',
+'difference' => '(Rozdźěl mjez wersijomaj)',
+'disambiguations' => 'Rozjasnjenja wjacezmyslnosće',
+'disambiguationspage' => 'Template: ??? Rozjasnjenje wjacezmyslnosće ***',
+'disambiguationstext' => 'Naslědne strony pokazuja na <i> stronu disambiguacije</i>. Dyrbjeli město toho na přihódny nastawk pokazać.
+
+Strona so jako disambiguacija wobhlada, jelizo pokaz wot $1 ma.
+
+Pokazy z druhich mjenowych rumow tu naličene <i>njejsu</i>.',
+'disclaimerpage' => 'Project:Licencne postajenja',
+'disclaimers' => 'Licencne postajenja',
+'displaytitle' => '(Wotkaz na tutu stronu jako [[$1]])',
+'doubleredirects' => 'Dwójne daleposrědkowanja',
+'doubleredirectstext' => 'Kóžda rjadka wotkazy k prěnjemu a druhemu daleposrědkowanju wobsahuje, runje tak prěnja linka teksta druheho sposrědkowanja, kotraž z wašnjom „woprawdźitu” cilowu stronu podawa, na kotruž prěnje sposrědkowanje dyrbjało pokazać.',
+'download' => 'Sćahnyć',
+'eauthentsent' => 'Wobkrućenski email bu k mjenowanej adresy pósłany. Prjedy hač so druhi email ke kontu sćele, dyrbiće instrukcije w emailu sćěhować, zo byšće wobkrućił(a), zo je to woprawdźe Waše konto.',
+'edit' => 'Wobdźěłać',
+'edit-externally' => 'Tutu dataju z eksternym programom wobdźěłać',
+'edit-externally-help' => 'Hlej [http://meta.wikimedia.org/wiki/Help:External_editors pokiwy za instalaciju] za wjace informacijow.',
+'editcomment' => 'Komentar změny běše: „<i>$1</i>”.',
+'editconflict' => 'Wobdźěłowanski konflikt: $1',
+'editcurrent' => 'Tuchwilnu wersiju tuteje strony wobdźěłać',
+'edithelp' => 'Pomoc za wobdźěłanje',
+'edithelppage' => 'Pomoc:Wobdźěłanje',
+'editing' => 'Wobdźěłanje strony $1',
+'editingcomment' => 'Wobdźěłanje strony $1 (komentar)',
+'editinginterface' => '<b>Kedźbu:</b> Wobdźěłaće stronu, kotraž wobsahuje tekt za rěčny zwjerch. Změnjenja wuskutkuja so na wšěch druhich wužiwarjow tutoho rěčneho zwjercha.',
+'editingold' => '<strong>KEDŹBU: Wobdźěłujeće staršu wersiju tuteje strony. Jelizo ju składujeće, budźe jako najnowša wersija składowana.</strong>',
+'editingsection' => 'Wobdźěłanje strony $1 (wotrězk)',
+'editold' => 'wobdźěłać',
+'editsection' => 'wobdźěłać',
+'editsectionhint' => 'Wotrězk wobdźěłać: $1',
+'editthispage' => 'Stronu wobdźěłać',
+'edittools' => '<!-- Tutón tekst so pod wobdźělowanskimi a nahrawanskimi woknješkami pokazuje. -->',
+'editusergroup' => 'Wužiwarske skupiny wobdźěłać',
+'email' => 'Email',
+'emailauthenticated' => 'Waša emailowa adresa bu $1 wobkrućena.',
+'emailconfirmlink' => 'Wobkrućće swoju emailowu adresu',
+'emailfrom' => 'Wot',
+'emailmessage' => 'Powěsć',
+'emailnotauthenticated' => 'Waša emailowa adresa hišće <strong>wobkrućena njeje</strong>. Žadyn email za jednu z naslědnych funkcijow pósłany njebudźe.',
+'emailpage' => 'Wužiwarjej email pósłać',
+'emailpagetext' => 'Jelizo tutón wužiwar je płaćiwu emailowu adresu do swojich nastajenjow zapisał, móžeće z formularom deleka email słać. Emailowa adresa, kotruž sće do swojich wužiwarskich nastajenjow zapisał, budźe so jako adresa "Wot" emaila jewić, zo by přijimowar móhł wotmołwić.',
+'emailsend' => 'Wotesłać',
+'emailsent' => 'Email bu pósłany',
+'emailsenttext' => 'Emailowa powěsć bu pósłana.',
+'emailsubject' => 'Předmjet',
+'emailto' => 'Komu',
+'emailuser' => 'Tutomu wužiwarjej email pósłać',
+'emptyfile' => 'Dataja, kotruž sće nahrał, zda so prózdna być. Móhło to dla tipowanskeho zmylka w mjenje dataje być. Prošu pruwujće hač chceće tutu dataju woprawdźe nahrawać.',
+'enotif_body' => 'Luby(a) $WATCHINGUSERNAME,<br />
+
+strona {{SITENAME}} „$PAGETITLE” bu dnja $PAGEEDITDATE wot $PAGEEDITOR $CHANGEDORCREATED,
+hlej $PAGETITLE_URL za aktualnu wersiju.
+
+$NEWPAGE
+
+Zjeće wobdźěłaćerja běše: $PAGESUMMARY $PAGEMINOREDIT
+
+Wobdźěłarja kontaktować:
+mail $PAGEEDITOR_EMAIL
+wiki $PAGEEDITOR_WIKI
+
+Njebudu žane druhe zdźělenki w padźe dalšich změnow, chibazo wopytaće tutu stronu.
+Wy móhł(a) tež zdźělenske opcije za wšě ze swojich wobkedźbowanych stronow ze swojich wobkedźbowankow wróćo stajić.
+
+Waš přećelny zdźělenski system {{GRAMMAR:genitiw|{{SITENAME}}}}
+
+--
+Zo byšće nastajenja Wašich wobkedźbowankow změnił(a), wopytajće
+{{fullurl:Special:Watchlist/edit}}',
+'enotif_lastvisited' => 'Změny po Wašim poslednim wopyće: $1',
+'enotif_mailer' => '{{SITENAME}} Emailowe zdźělenje',
+'enotif_newpagetext' => 'To je nowa strona.',
+'enotif_reset' => 'Wšě strony jako widźane markěrować',
+'enotif_subject' => '{{SITENAME}} Strona „$PAGETITLE” bu přez $PAGEEDITOR $CHANGEDORCREATED.',
+'enterlockreason' => 'Podajće přičinu zawrjenja a přibližny čas, hdy so zawrjenje zběhnje',
+'error' => 'Zmylk',
+'errorpagetitle' => 'Zmylk',
+'exbeforeblank' => 'Wobsah do wuprózdnjenja běše: \'$1\'',
+'exblank' => 'Strona běše prózdna',
+'excontent' => 'Wobsah běše: \'$1\'',
+'excontentauthor' => 'Wobsah běše: \'$1\' (jenički wobdźěłowar běše \'$2\')',
+'exif-aperturevalue' => 'Zasłona',
+'exif-artist' => 'Awtor',
+'exif-bitspersample' => 'Bajtow na barbowu komponentu',
+'exif-brightnessvalue' => 'Swětłosć',
+'exif-cfapattern' => 'CFA-muster',
+'exif-colorspace' => 'Barbowy rum',
+'exif-componentsconfiguration'=> 'Woznam kóždeje komponenty',
+'exif-componentsconfiguration-0'=> 'Njeeksistuje',
+'exif-compressedbitsperpixel'=> 'Modus wobrazoweje kompresije',
+'exif-compression' => 'Metoda kompresije',
+'exif-compression-1' => 'Njekomprimowane',
+'exif-compression-6' => 'JPEG',
+'exif-contrast' => 'Kontrast',
+'exif-contrast-0' => 'Normalny',
+'exif-contrast-1' => 'Mjechki',
+'exif-contrast-2' => 'Twjerdy',
+'exif-copyright' => 'Mějićel awtorskich prawow',
+'exif-customrendered' => 'Wot wužiwarja definowane předźěłanje wobrazow',
+'exif-customrendered-0' => 'Normalne wobdźěłanje',
+'exif-customrendered-1' => 'Wužiwarske wobdźěłanje',
+'exif-datetime' => 'Datum a čas datajoweje změny',
+'exif-datetimedigitized'=> 'Datum a čas digitalizacije',
+'exif-datetimeoriginal' => 'Datum a čas załoženja datow',
+'exif-devicesettingdescription'=> 'Nastajenja nastroja',
+'exif-digitalzoomratio' => 'Digitalny zoom',
+'exif-exifversion' => 'Exif wersija',
+'exif-exposurebiasvalue'=> 'Naswětlenska směrnica',
+'exif-exposureindex' => 'Naswětlenski indeks',
+'exif-exposuremode' => 'Naswětlenski modus',
+'exif-exposuremode-0' => 'Awtomatiske naswětlenje',
+'exif-exposuremode-1' => 'Manuelne naswětlenje',
+'exif-exposuremode-2' => 'Rjad naswětlenjow (Bracketing)',
+'exif-exposureprogram' => 'Program naswětlenja',
+'exif-exposureprogram-0'=> 'Njeznaty',
+'exif-exposureprogram-1'=> 'Manualny',
+'exif-exposureprogram-2'=> 'Standardny program',
+'exif-exposureprogram-3'=> 'Priorita zasłony',
+'exif-exposureprogram-4'=> 'Priorita zawěrki',
+'exif-exposureprogram-5'=> 'Kreatiwny program (na hłubokostnu wótrosć wusměrjeny)',
+'exif-exposureprogram-6'=> 'Akcijny program (na krótši čas zawěrki wusměrjeny)',
+'exif-exposureprogram-7'=> 'Portretowy modus (za fotografije z bliskosće z njewótrym pozadkom)',
+'exif-exposureprogram-8'=> 'Krajinsky modus (za krajinske fotografije z wótrym pozadkom)',
+'exif-exposuretime' => 'Čas naswětlenja',
+'exif-exposuretime-format'=> '$1 sek. ($2)',
+'exif-filesource' => 'Žórło dataje',
+'exif-flash' => 'Błysk',
+'exif-flashenergy' => 'Sylnosć błyska',
+'exif-flashpixversion' => 'Podpěrowana wersija Flashpix',
+'exif-fnumber' => 'Zasłona',
+'exif-fnumber-format' => 'f/$1',
+'exif-focallength' => 'Wohnišćowa zdalenosć čóčka',
+'exif-focallength-format'=> '$1 mm',
+'exif-focallengthin35mmfilm'=> 'Wohnišćowa zdalenosć za film 35 mm přeličene',
+'exif-focalplaneresolutionunit'=> 'Jednotka rozpušćenja sensora',
+'exif-focalplaneresolutionunit-2'=> 'Cól',
+'exif-focalplanexresolution'=> 'Wodorune rozpušćenje sensora',
+'exif-focalplaneyresolution'=> 'Padorune rozpušćenje sensora',
+'exif-gaincontrol' => 'Wodźenje sceny',
+'exif-gaincontrol-0' => 'Žane powjetšenje',
+'exif-gaincontrol-1' => 'Snadne powjetšenje',
+'exif-gaincontrol-2' => 'Wysoke powjetšenje',
+'exif-gaincontrol-3' => 'Snadne pomjeńšenje',
+'exif-gaincontrol-4' => 'Wulke pomjeńšenje',
+'exif-gpsaltitude' => 'Wysokosć',
+'exif-gpsaltituderef' => 'Referenca wysokosće',
+'exif-gpsareainformation'=> 'Mjeno wobwoda GPS',
+'exif-gpsdatestamp' => 'Datum GPS',
+'exif-gpsdestbearing' => 'Wusměrjenje',
+'exif-gpsdestbearingref'=> 'Referenca za wusměrjenje',
+'exif-gpsdestdistance' => 'Zdalenosć k cilej',
+'exif-gpsdestdistanceref'=> 'Referenca za zdalenosć k cilej',
+'exif-gpsdestlatitude' => 'Šěrina',
+'exif-gpsdestlatituderef'=> 'Referenca za šěrinu',
+'exif-gpsdestlongitude' => 'Šěrina',
+'exif-gpsdestlongituderef'=> 'Referenca dołhosće',
+'exif-gpsdifferential' => 'Diferencialna korektura GPS',
+'exif-gpsdirection-m' => 'Magnetiski směr',
+'exif-gpsdirection-t' => 'Woprawdźity směr',
+'exif-gpsdop' => 'Měrjenska dokładnosć',
+'exif-gpsimgdirection' => 'Wobrazowy směr',
+'exif-gpsimgdirectionref'=> 'Referenca za wusměrjenje wobraza',
+'exif-gpslatitude' => 'Geografiska šěrina',
+'exif-gpslatitude-n' => 'Sewjerna šěrina',
+'exif-gpslatitude-s' => 'Južna šěrina',
+'exif-gpslatituderef' => 'Sewjerna abo južna šěrina',
+'exif-gpslongitude' => 'Geografiska dołhosć',
+'exif-gpslongitude-e' => 'Wuchodna dalokosć',
+'exif-gpslongitude-w' => 'Zapadna dalokosć',
+'exif-gpslongituderef' => 'Wuchodna abo zapadna dołhosć',
+'exif-gpsmapdatum' => 'Wužiwane geodetiske daty',
+'exif-gpsmeasuremode' => 'Měrjenska metoda',
+'exif-gpsmeasuremode-2' => 'dwudimensionalne měrjenje',
+'exif-gpsmeasuremode-3' => 'třidimensionalne měrjenje',
+'exif-gpsprocessingmethod'=> 'Metoda wobdźěłanja GPS',
+'exif-gpssatellites' => 'Satelity wužiwane za měrjenje',
+'exif-gpsspeed' => 'Spěšnosć přijimaka GPS',
+'exif-gpsspeed-n' => 'Suki',
+'exif-gpsspeedref' => 'Jednotka spěšnosće',
+'exif-gpsstatus' => 'Status přijimaka',
+'exif-gpsstatus-a' => 'Měrjenje hišće běži...',
+'exif-gpstimestamp' => 'GPS-čas (atomowy časnik)',
+'exif-gpstrack' => 'Pohibowy směr',
+'exif-gpstrackref' => 'Referenca za pohibowy směr',
+'exif-gpsversionid' => 'Wersija znamki GPS',
+'exif-imagedescription' => 'Titul wobraza',
+'exif-imagelength' => 'Wysokosć',
+'exif-imageuniqueid' => 'ID wobraza',
+'exif-imagewidth' => 'Šěrokosć',
+'exif-isospeedratings' => 'Cutliwosć film a abo sensora',
+'exif-jpeginterchangeformat'=> 'Offset k JPEG SOI',
+'exif-jpeginterchangeformatlength'=> 'Bajty JPEG datow',
+'exif-lightsource' => 'Žórło swěcy',
+'exif-lightsource-0' => 'Njeznate',
+'exif-lightsource-1' => 'Dnjowe swětło',
+'exif-lightsource-10' => 'Pomróčene',
+'exif-lightsource-11' => 'Sćin',
+'exif-lightsource-12' => 'Fluorescentne dnjowe swětło (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Dźeń, běłe, fluorescentne (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Chłódne, běłe, fluorescentne (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Běły, fluorescěrowacy (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Normalne swětło A',
+'exif-lightsource-18' => 'Normalne swětło B',
+'exif-lightsource-19' => 'Normalne swětło C',
+'exif-lightsource-2' => 'Fluorescentne',
+'exif-lightsource-24' => 'ISO studijowa wolframowa žehlawka',
+'exif-lightsource-255' => 'Hinaše swětłowe žórło',
+'exif-lightsource-3' => 'Žehlawka',
+'exif-lightsource-4' => 'Błysk',
+'exif-lightsource-9' => 'Rjane wjedro',
+'exif-make' => 'Zhotowjer kamery',
+'exif-makernote' => 'Přispomnjenja zhotowjerja',
+'exif-maxaperturevalue' => 'Najwjetša objektiwowa wotwěra',
+'exif-meteringmode' => 'Měrjenska metoda',
+'exif-meteringmode-0' => 'Njeznata',
+'exif-meteringmode-1' => 'Přerězk',
+'exif-meteringmode-2' => 'Dosrjedźny přerězk',
+'exif-meteringmode-255' => 'Druha',
+'exif-meteringmode-3' => 'Dypkowa',
+'exif-meteringmode-4' => 'wjeledypkowa',
+'exif-meteringmode-5' => 'Muster',
+'exif-meteringmode-6' => 'Na dźěl wobraza wusměrjena',
+'exif-model' => 'Model kamery',
+'exif-oecf' => 'Optoelektroniski přeličowanski faktor',
+'exif-orientation' => 'Wusměrjenje kamery',
+'exif-orientation-1' => 'Normalnje',
+'exif-orientation-2' => 'Horicontalnje kiwknjeny',
+'exif-orientation-3' => 'Wo 180° zwjertnjeny',
+'exif-orientation-4' => 'Wertikalnje kiwknjeny',
+'exif-orientation-5' => 'Wo 90° přećiwo směrej časnika zwjertnjeny a wertikalnje kiwknjeny',
+'exif-orientation-6' => 'Wo 90° po směrje časnika zwjertnjeny',
+'exif-orientation-7' => 'Wo 90° po směrje časnika zwjertnjeny a wertikalnje kiwknjeny',
+'exif-orientation-8' => 'Wo 90° přećiwo směrej časnika zwjertnjeny',
+'exif-photometricinterpretation'=> 'Zestajenje pikselow',
+'exif-photometricinterpretation-2'=> 'RGB',
+'exif-photometricinterpretation-6'=> 'YCbCr',
+'exif-pixelxdimension' => 'Płaćiwa wysokosć wobraza',
+'exif-pixelydimension' => 'Płaćiwa šěrokosć wobraza',
+'exif-planarconfiguration'=> 'Porjad datow',
+'exif-planarconfiguration-1'=> 'Škropawy format',
+'exif-planarconfiguration-2'=> 'Płony format',
+'exif-primarychromaticities'=> 'Barbowa kwalita primarnych barbow',
+'exif-referenceblackwhite'=> 'Por čorneje a běłeje referencneju hódnotow',
+'exif-relatedsoundfile' => 'Zwjazana zynkowa dataja',
+'exif-resolutionunit' => 'Jednotka rozeznaća X a Y',
+'exif-rowsperstrip' => 'Ličba rjadkow na pask',
+'exif-samplesperpixel' => 'Ličba komponentow',
+'exif-saturation' => 'Nasyćenosć',
+'exif-saturation-0' => 'Normalna nasyćenosć',
+'exif-saturation-1' => 'Niska nasyćenosć',
+'exif-saturation-2' => 'Wysoka nasyćenosć',
+'exif-scenecapturetype' => 'Typ zapopadnjenja sceny',
+'exif-scenecapturetype-0'=> 'Standard',
+'exif-scenecapturetype-1'=> 'Krajina',
+'exif-scenecapturetype-2'=> 'Portret',
+'exif-scenecapturetype-3'=> 'Nócne foto',
+'exif-scenetype' => 'Typ sceny',
+'exif-scenetype-1' => 'Direktnje zapopadnjeny wobraz',
+'exif-sensingmethod' => 'Měrjenska metoda',
+'exif-sensingmethod-1' => 'Njedefinowany',
+'exif-sensingmethod-2' => 'Jednočipowy barbowy přestrjenjowy sensor',
+'exif-sensingmethod-3' => 'Dwučipowy barbowy přestrjenjowy sensor',
+'exif-sensingmethod-4' => 'Třičipowy barbowy přestrjenjowy sensor',
+'exif-sensingmethod-5' => 'Sekwencielny barbowy přestrjenjowy sensor',
+'exif-sensingmethod-7' => 'Trilinearny sensor',
+'exif-sensingmethod-8' => 'Barbowy sekwencielny linearny sensor',
+'exif-sharpness' => 'Wótrosć',
+'exif-sharpness-0' => 'Normalny',
+'exif-sharpness-1' => 'Mjechki',
+'exif-sharpness-2' => 'Twjerdy',
+'exif-shutterspeedvalue'=> 'Čas naswětlenja',
+'exif-software' => 'Software',
+'exif-spatialfrequencyresponse'=> 'Rumnostna frekwencowa charakteristika',
+'exif-spectralsensitivity'=> 'Spektralna cutliwosć',
+'exif-stripbytecounts' => 'Bajtow na komprimowany pask',
+'exif-stripoffsets' => 'Městno wobrazowych datow',
+'exif-subjectarea' => 'Wobkruh',
+'exif-subjectdistance' => 'Zdalenosć k objektej',
+'exif-subjectdistance-value'=> '$1 m',
+'exif-subjectdistancerange'=> 'Zdalenosć objekta',
+'exif-subjectdistancerange-0'=> 'Njeznaty',
+'exif-subjectdistancerange-1'=> 'Makro',
+'exif-subjectdistancerange-2'=> 'Foto zbliska',
+'exif-subjectdistancerange-3'=> 'Foto znazdala',
+'exif-subjectlocation' => 'Městno objekta',
+'exif-subsectime' => 'Dźěl sekundow DateTime',
+'exif-subsectimedigitized'=> 'Dźěl sekundow DateTimeDigitized',
+'exif-subsectimeoriginal'=> 'Dźěl sekundow DateTimeOriginal',
+'exif-transferfunction' => 'Přenošowanska funkcija',
+'exif-usercomment' => 'Přispomjenja wužiwarja',
+'exif-whitebalance' => 'Balansa běłeje barby',
+'exif-whitebalance-0' => 'Automatiske wubalansowanje běłeho',
+'exif-whitebalance-1' => 'Manuelne wubalansowanje běłeho',
+'exif-whitepoint' => 'Barbowa kwalita běłeho dypka',
+'exif-xresolution' => 'Wodorune rozpušćenje',
+'exif-ycbcrcoefficients'=> 'Matriksowe koeficienty za transformaciju barboweho ruma',
+'exif-ycbcrpositioning' => 'Wusměrjenje Y a C',
+'exif-ycbcrsubsampling' => 'Poměr wottasanja Y k C',
+'exif-yresolution' => 'Padorune rozpušćenje',
+'expiringblock' => 'hač do $1',
+'explainconflict' => 'Něchtó druhi je tutu stronu změnił w samsnym času, hdyž sće spytał(a) ju wobdźěłać. Hornje tekstowe polo wobsahuje tekst strony kaž wón tuchwilu eksistuje. Waše změny so w delnim tekstowym polu jewja. Dyrbiće swoje změny do eksistowaceho teksta zasunyć. <b>Jenož</b> tekst w hornim tekstowym polu budźe so składować jelizo na „Składować” kliknjeće.<br />',
+'export' => 'Strony eksportować',
+'export-submit' => 'Eksportować',
+'exportcuronly' => 'Jenož aktualnu wersiju zapřijeć, nic dospołne stawizny',
+'exportnohistory' => '----
+<b>Kedźbu:</b> Eksport cyłych stawiznow přez tutón formular je wukonliwosće serwera dla znjemóžnjeny.',
+'exporttext' => 'Móžeće tekst a stawizny wěsteje strony abo skupiny stronow, kotrež su w XML zawite, eksportować. To da so potom do druheho wiki, kotryž ze software MediaWiki dźěła, z pomocu strony Special:Import importować.
+
+Zo bychu so strony z nastawkami eksportowali, zapisajće titule stron do tekstoweho pola deleka, jedyn titul na linku, a wubjerće hač chceće tuchwilnu wersiju kaž tež stare wersije z linkami stawiznow strony abo jenož aktualnu wersiju z informacijemi wo poslednjej změnje eksportować.
+
+W poslednim padźe móžeće tež wotkaz wužiwać, na př. „[[Special:Export/{{int:Mainpage}}]]” za stronu „{{int:Mainpage}}”.',
+'externaldberror' => 'Běše pak eksterny zmylk awtentifikacije datoweje banki, pak njesměće swoje eksterne konto aktualizować.',
+'extlink_sample' => 'http://www.beispiel.de Titul wotkaza',
+'extlink_tip' => 'Eksterny wotkaz (prošu dopomńće so na prefiks http://)',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'feb' => 'feb',
+'february' => 'februar',
+'february-gen' => 'februara',
+'feed-invalid' => 'Njepłaćiwy typ abonementa.',
+'feedlinks' => 'Newsfeed:',
+'filecopyerror' => 'Njebě móžno dataju „$1” k „$2” kopěrować.',
+'filedeleteerror' => 'Njebě móžno dataju „$1” wušmórnyć.',
+'filedesc' => 'Zjeće',
+'fileexists' => 'Dataja z tutym mjenom hižo eksistuje, prošu pruwujće $1 jelizo njejsće wěsty(a) hač chceće ju změnić.',
+'fileexists-forbidden' => 'Dataja z tutym mjenom hižo ekstituje, prošu dźiće wróćo a nahrawajće ju z druhim mjenom. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Dataja z tutym mjenom hižo ekstituje, prošu dźiće wróćo a nahrawajće ju z druhim mjenom. [[Image:$1|thumb|center|$1]]',
+'fileinfo' => '$1KB, družina MIME: <code>$2</code>',
+'filemissing' => 'Dataja pobrachuje',
+'filename' => 'Mjeno dataje',
+'filenotfound' => 'Njebě móžno dataju „$1” namakać.',
+'filerenameerror' => 'Njebě móžno dataju „$1” do „$2” přemjenować.',
+'files' => 'Dataje',
+'filesource' => 'Žórło',
+'filestatus' => 'Licenca',
+'fileuploaded' => 'Dataja „$1” bu z wuspěchom nahrata. Prošu slědujće tutón wotkaz: $2 k stronje wopisanja a zapisajće informacije wo dataji, na př. zwotkel pochadźa, hdy a wot koho bu załožena a štožkuli hišće wo njej wěsće. Jelizo je to wobraz, móžeće jón takle zasunyć: <tt><nowiki>[[Image:$1|thumb|wopisanje]]</nowiki></tt>',
+'fileuploadsummary' => 'Zjeće:',
+'filewasdeleted' => 'Dataja z tutym mjenom bu prjedy hižo nahrata a mjeztym wušmórnjena. Prošu přepruwujće $1 prjedy hač ju znowa składujće.',
+'formerror' => 'Zmylk: njeje móžno formular wotesłać',
+'fri' => 'Pja',
+'friday' => 'Pjatk',
+'getimagelist' => 'Lisćinu datajow nabyć',
+'go' => 'Nastawk',
+'gotaccount' => 'Maće hižo wužiwarske konto? $1.',
+'gotaccountlink' => 'Přizjewić',
+'group' => 'Skupina:',
+'group-all' => '(wšě)',
+'group-bot-member' => 'bot',
+'group-bureaucrat' => 'Běrokraća',
+'group-bureaucrat-member'=> 'běrokrat',
+'group-sysop' => 'Administratorojo',
+'group-sysop-member' => 'administrator',
+'grouppage-bot' => 'Project:Bots',
+'grouppage-bureaucrat' => 'Project:Běrokraća',
+'grouppage-sysop' => 'Project:Administratorojo',
+'groups' => 'Skupiny wužiwarjow',
+'guesstimezone' => 'Z browsera zasunyć',
+'headline_sample' => 'Nadpismo',
+'headline_tip' => 'Nadpismo runiny 2',
+'help' => 'Pomoc',
+'helppage' => 'Project:Pomoc',
+'hide' => 'schować',
+'hideresults' => 'Wuslědki schować',
+'hidetoc' => 'schować',
+'hist' => 'wersije',
+'histfirst' => 'Tuchwilnu',
+'histlast' => 'Najstaršu',
+'histlegend' => 'Diff wubrać: Wuběrće opciske pola za přirunanje a tłóčće na enter abo tłóčku deleka.
+
+Legenda: (akt) = rozdźěl k tuchwilnej wersiji, (posl) = rozdźěl k předchadnej wersiji, D = drobna změna.',
+'history' => 'Stawizny strony',
+'history-feed-description'=> 'Stawizny wersijow za tutu stronu we wiki',
+'history-feed-empty' => 'Strona, kotruž sće požadał(a), njeekstistuje. Je móžne, zo bě wušmórnjena abo so pod druhi titul zasunyła. Móžeće [[Special:Search|tu]] za stronam z podobnym titulom pytać.',
+'history-feed-item-nocomment'=> '$1 w $2 hodź.',
+'history-feed-title' => 'Stawizny wersijow',
+'history_short' => 'Stawizny',
+'historywarning' => 'KEDŹBU: Strona, kotruž chceće wušmórnyć, ma stawizny:',
+'hr_tip' => 'Wodoruna linija (zrědka wužiwać)',
+'ignorewarning' => 'Warnowanje ignorować a dataju najebać toho składować.',
+'ignorewarnings' => 'Warnowanja ignorować',
+'illegalfilename' => 'Mjeno dataje „$1” znamješka, kotrež njejsu w stronowych titulach dopušćene, wobsahuje. Prošu přemjenujće dataju a spytajće hišće raz ju nahrać.',
+'ilsubmit' => 'Pytam',
+'image_sample' => 'Přikład.jpg',
+'image_tip' => 'Zasadźeny wobraz',
+'imagelinks' => 'Wotkazy',
+'imagelist' => 'Lisćina datajow',
+'imagelistall' => 'wšě',
+'imagelistforuser' => 'Jenož dataje kiž buchu přez $1 nahrate.',
+'imagelisttext' => 'Deleka je lisćina <b>$1</b> datajow po <b>$2</b> sortěrowanych.',
+'imagemaxsize' => 'Wobrazy na stronach wobrazoweho wopisanja wobmjezować na:',
+'imagepage' => 'Wobrazowu stronu pokazać',
+'imagereverted' => 'K staršej wersiji nawróćene.',
+'imgdelete' => 'Wušmórnyć',
+'imgdesc' => 'wopisanje',
+'imghistlegend' => 'Legenda: (akt) = to je aktualna dataja, (wotstr) = tutu staru wersiju wotstronić, (nawróć) = nawróć so k tutej starej wersiji.
+
+<i>Klikńće na datum zo byšće werziju widźał(a) kiž bu na tutym dnju nahrata</i>.',
+'imghistory' => 'Stawizny dataje',
+'imglegend' => 'Legenda: (wop) = Wopisanje dataje pokazać/wobdźěłać.',
+'immobile_namespace' => 'Cilowy titul je wosebity typ; strony njedadźa so do druheho mjenoweho ruma přesunyć.',
+'import' => 'Strony importować',
+'import-interwiki-history'=> 'Wšě wersije ze stawiznow tuteje strony kopěrować',
+'import-interwiki-namespace'=> 'Strony importować do mjenoweho ruma:',
+'import-interwiki-submit'=> 'Importować',
+'import-interwiki-text' => 'Wuběrće wiki a stronu k importowanju. Daty wersijow a mjena awtorow so wobchowaju. Wšě transwiki-importy so w [[Special:Log/import|protokolu importow]] jewja.',
+'import-logentry-interwiki'=> 'z druheho wiki importowany $1',
+'import-logentry-interwiki-detail'=> '$1 wersijow z $2',
+'import-logentry-upload'=> 'strona „[[$1]]” bu přez nahrawanje importowana',
+'import-logentry-upload-detail'=> '$1 wersijow',
+'import-revision-count' => '$1 wersijow',
+'importbadinterwiki' => 'Wopačny interwiki-wotkaz',
+'importcantopen' => 'Njemóžno importowu dataju wočinić',
+'importfailed' => 'Importowanje njeporadźiło: $1',
+'importhistoryconflict' => 'Napřećiwne stawizny eksistuja (snano bu strona hižo prjedy importowana)',
+'importing' => 'Importuju $1',
+'importinterwiki' => 'Transwiki import',
+'importlogpage' => 'Protokol importow',
+'importlogpagetext' => 'To je lisćina stronow ze stawiznami z druhich wiki.',
+'importnofile' => 'Žana importowanska dataja wubrana.',
+'importnopages' => 'Žane strony k importowanju',
+'importnosources' => 'Žane importowanske žórła za transwiki wubrane a direktne nahraća stawiznow su znjemóžnjene.',
+'importnotext' => 'Prózdny abo žadyn tekst',
+'importstart' => 'Importuju…',
+'importsuccess' => 'Importowanje poradźiło!',
+'importtext' => 'Prošu eksportujće dataju ze žórłoweho wiki wužiwajo stronu Special:Export, składujće ju na swoju krutu tačel a nahrajće ju sem.',
+'importunknownsource' => 'Njeznate importowe žórło',
+'importuploaderror' => 'Nahraće importowanskeje dataje njeje so poradźiło; snano dataja je wjetša hač dowolena nahrawanska wulkosć.',
+'infiniteblock' => 'na přeco',
+'info_short' => 'Informacija',
+'infosubtitle' => 'Informacije za stronu',
+'internalerror' => 'Interny zmylk',
+'intl' => 'Interwiki-wotkazy',
+'invalidemailaddress' => 'Emailowa adresa njemóže so akceptować, dokelž zda so, zo ma njepłaćiwy format. Prošu zapisajće prawje formatowanu adresu abo wuprózdńće polo.',
+'invert' => 'Wuběr zwobroćić',
+'ip_range_invalid' => 'Njepłaciwy IP-wobkruh.',
+'ipaddress' => 'IP-adresa',
+'ipadressorusername' => 'IP-adresa abo wužiwarske mjeno',
+'ipb_expiry_invalid' => 'Čas spadnjenja je njepłaćiwy.',
+'ipbanononly' => 'Jenož anonymnych wužiwarjow blokować',
+'ipbcreateaccount' => 'Stworjenju nowych kontow zadźěwać',
+'ipbexpiry' => 'Spadnjenje',
+'ipblocklist' => 'Lisćina blokowanych IP-adresow a wužiwarskich mjenow',
+'ipblocklistempty' => 'Lisćina blokowanjow je prózdna.',
+'ipboptions' => '1 hodźinu:1 hodźinu,2 hodźinje:2 hodźinje,1 dźeń:1 dźeń,3 dny:3 dny,1 tydźeń:1 tydźeń,2 njedźeli:2 njedźeli,1 měsać:1 měsac,3 měsacy:3 měsacy,6 měsacow:6 měsacow,1 lěto:1 lěto,na přeco:na přeco',
+'ipbother' => 'Druha doba',
+'ipbotheroption' => 'druha doba (jendźelsce)',
+'ipbreason' => 'Přičina',
+'ipbsubmit' => 'Wužiwarja blokować',
+'ipusubmit' => 'Blokowanje adresy zběhnyć',
+'isbn' => 'ISBN',
+'isredirect' => 'Daleposrědkowanje',
+'istemplate' => 'Zapřijeće předłohi',
+'italic_sample' => 'Kursiwny tekst',
+'italic_tip' => 'Kursiwny tekst',
+'iteminvalidname' => 'Problem ze stronu „$1“, njepłaćiwe mjeno...',
+'jan' => 'jan',
+'january' => 'januar',
+'january-gen' => 'januara',
+'jul' => 'jul',
+'july' => 'julij',
+'july-gen' => 'julija',
+'jumpto' => 'Dźi do:',
+'jumptonavigation' => 'Nawigacija',
+'jumptosearch' => 'Pytaj',
+'jun' => 'jun',
+'june' => 'junij',
+'june-gen' => 'junija',
+'laggedslavemode' => 'Kedźbu: Je móžno, zo strona žane zaktualizowanja njewobsahuje.',
+'largefile' => 'Poruča so, zo wobrazy wulkosć $1 bajtow njepřekročuja, tuta dataja je $2 bajtow wulka.',
+'largefileserver' => 'Tuta dataja je wjetša hač serwer za nahrawanje dowoli.',
+'last' => 'posl',
+'lastmodifiedat' => 'Tuta strona bu posledni raz dnja $1 $2 změnjena.',
+'license' => 'Licenca',
+'lineno' => 'Linka $1:',
+'link_sample' => 'Titul wotkaza',
+'link_tip' => 'Interny wotkaz',
+'linklistsub' => '(Lisćina wotkazow)',
+'linkshere' => 'Naslědne strony sem pokazuja:',
+'linkstoimage' => 'Naslědne strony na tutu dataju pokazuja:',
+'listingcontinuesabbrev'=> 'pokr.',
+'listredirects' => 'Lisćina daleposrědkowanjow',
+'listusers' => 'Zapis wužiwarjow',
+'listusersfrom' => 'Započinajo z:',
+'loadhist' => 'Stawizny strony začitać',
+'loadingrev' => 'začitanje wersijow za diff',
+'localtime' => 'Lokalny čas',
+'lockbtn' => 'Datowu banku zawrěć',
+'lockconfirm' => 'Haj, chcu woprawdźe datowu banku zawrěć.',
+'lockdb' => 'Datowu banku zawrěć',
+'lockdbsuccesssub' => 'Zawrjenje datoweje banki poradźiło',
+'lockdbsuccesstext' => 'Datowa banka bu zawrjena.
+
+Pomyslće sej zawrjenje wotstronić, po tym zo su porjedźenske dźěła dokónčene.',
+'lockdbtext' => 'Zawrjenje datoweje banki znjezmóžni wšěm wužiwarjam strony wobdźěłać, jich nastajenja změnić, jich wobkedźbowanki wobdźěłać a hinaše dźěła činić, kotrež sej změny w datowej bance žadaja. Prošu wobkrućće, zo chceće datowu banku woprawdźe zawrěć a zo chceće zawrjenje zaso zběhnyć, hdyž budu porjedźenske dźěła skónčene.',
+'locknoconfirm' => 'Njejsće kašćik potwjerdźenja nakřižował(a).',
+'log' => 'Wšě protokole',
+'logempty' => 'Žane so hodźace zapiski.',
+'login' => 'Přizjewić',
+'loginerror' => 'Zmylk při přizjewjenju',
+'loginlanguagelabel' => 'Rěč: $1',
+'loginpagetitle' => 'Přizjewjenje',
+'loginproblem' => '<b>Běše problem z přizjewjenjom.</b>
+
+Prošu spytajće hišće raz!',
+'loginprompt' => 'Zo byšće so pola {{GRAMMAR:genitiw|{{SITENAME}}}} přizjewić móhł(a), dyrbja placki (cookies) zmóžnjene być.',
+'loginreqlink' => 'přizjewić',
+'loginreqpagetext' => 'Dyrbiće so $1, zo byšće strony čitać móhł(a).',
+'loginreqtitle' => 'Přizjewjene trěbne',
+'loginsuccess' => '<b>Sće nětko jako „$1” we {{GRAMMAR:lokatiw|{{SITENAME}}}} přizjewjeny(a).</b>',
+'loginsuccesstitle' => 'Přizjewjenje wuspěšne',
+'logout' => 'Wotzjewić',
+'logouttext' => '<strong>Sće nětko wotzjewjeny(a).</strong>
+
+Móžeće {{GRAMMAR:akuzatiw|{{SITENAME}}}} anonymnje dale wužiwać abo so ze samsnym abo druhim wužiwarskim mjenom zaso přizjewić. Wobkedźbujće zo so někotre strony dale jewja kaž bysće hišće přizjewjeny doniž pufrowak wašeho browsera njewuprózdnjeće.',
+'logouttitle' => 'Wotzjewjenje wužiwarja',
+'lonelypages' => 'Wosyroćene strony',
+'longpageerror' => '<strong>ZMYLK: Tekst, kotryž sće spytał(a) składować wobsaha $1 kB, maksimalna wulkosć pak je $2 kB. Njeje móžno jón składować.</strong>',
+'longpages' => 'Dołhe nastawki',
+'longpagewarning' => '<strong>KEDŹBU: Strona wobsahuje $1 kB; někotre browsery maja problemy, strony wobdźěłać, kotrež wobsahuja 32 kB abo wjace. Prošu rozwažće, stronu do mjeńšich wotrězkow rozdźělić.</strong>',
+'mailerror' => 'Zmylk při słanju emaila: $1',
+'mailmypassword' => 'Pósćelće mi nowe hesło',
+'mailnologin' => 'Njejsće přizjewjeny(a).',
+'mailnologintext' => 'Dyrbiće [[Special:Userlogin||přizjewjeny(a)]] być a płaćiwu emailowu adresu w swojich [[Special:Preferences|nastajenjach]] měć, zo byšće druhim wužiwarjam email pósłać móhł(a).',
+'mainpage' => 'Hłowna strona',
+'mainpagedocfooter' => 'Prošu hlej [http://meta.wikimedia.org/wiki/Help:Contents dokumentaciju] za informacije wo wobchadźenju z MediaWiki-software.
+
+== Za nowačkow ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Wo nastajenjach]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]',
+'mainpagetext' => '<big><b>MediaWiki bu wuspěšnje instalowany.</b></big>',
+'makesysop' => 'Wužiwarja k administratorej činić',
+'makesysopfail' => '<b>Wužiwar „$1” njeda so k sysopej činić. (Sće mjeno prawje zapisał(a)?)</b>',
+'makesysopname' => 'Mjeno wužiwarja:',
+'makesysopok' => '<b>Wužiwar „$1” je nětko administrator.</b>',
+'makesysopsubmit' => 'Wužiwarja k administratorej činić',
+'makesysoptext' => 'Tutón formular so wot běrokratow wužiwa, zo bychu so jednori wužiwarjo do administratorow přeměnili. Zadodajće wužiwarske mjeno do wotpowědneho pola a klikńće na tłočatko, zo byšće wužiwarja k administratorej činił(a).',
+'makesysoptitle' => 'Wužiwarja k administratorej činić',
+'mar' => 'měr',
+'march' => 'měrc',
+'march-gen' => 'měrca',
+'markaspatrolleddiff' => 'Nastawk jako dohladowany woznamjenić',
+'markaspatrolledtext' => 'Tutu změnu nastawka jako dohladowanu woznamjenić',
+'markedaspatrolled' => 'Jako dohladowany woznamjenjeny',
+'markedaspatrollederror'=> 'Njemóžno jako dohladowane woznamjenić',
+'markedaspatrollederrortext'=> 'Dyrbiće wersiju wubrać, kotruž cheće jako dohladowanu woznamjenić.',
+'markedaspatrolledtext' => 'Wubrana wersija bu jako dohladana woznamjenjena.',
+'matchtotals' => 'Wotprašenje „$1” namaka ((PLURAL:$2|jedyn titul|$2 titulow}} a tekst z {{PLURAL:$3|jedneje strony|$3 stron}}.',
+'math' => 'Math',
+'math_bad_output' => 'Njebě móžno do wudawanskeho zapisa pisać abo jón załožić',
+'math_bad_tmpdir' => 'Njebě móžno do zapisa math temp pisać abo jón załožić',
+'math_failure' => 'Analyzowanje njeporadźiło',
+'math_image_error' => 'PNG-konwertowanje njeporadźiło; přepruwujće, hač su latex, dvips, gs korektnje instalowane a konwertujće',
+'math_lexing_error' => 'lexing-zmylk',
+'math_notexvc' => 'Wuwjedźomny texvc pobrachuje; prošu hlej math/README za konfiguraciju.',
+'math_sample' => 'Zasuńće jow formulu',
+'math_syntax_error' => 'syntaktiski zmylk',
+'math_tip' => 'Matematiska formula (LaTeX)',
+'math_unknown_error' => 'njeznaty zmylk',
+'math_unknown_function' => 'njeznata funkcija',
+'may' => 'meje',
+'may-gen' => 'meje',
+'may_long' => 'meja',
+'media_sample' => 'Přikład.ogg',
+'media_tip' => 'Wotkaz k mediowej dataji',
+'mediawarning' => '<b>KEDŹBU:</b> Tuta dataja móhła zły kode wobsahować, kotrehož wuwjedźenje móhło Waš system wobškodźić.',
+'mediawikipage' => 'Powěsć pokazać',
+'metadata' => 'Metadaty',
+'metadata-collapse' => 'Rozšěrjene detaile schować',
+'metadata-expand' => 'Rozšěrjene detaile pokazać',
+'metadata-help' => 'W tutej dataji su dalše informacije zapřijate, kotrež pochadźa z digitalneje kamery abo z scannera kiž su so k załoženju dataje trebali. Bu-li dataja porno originalnemu stawej změnjena, je móžno, zo někotre detaile z nětčišeho stawa wotchila.',
+'metadata_help' => 'metadaty (hlej [[Project:Metadata]] za rozjasnjenje):',
+'mimesearch' => 'Pytaj po družinje MIME',
+'mimetype' => 'Družina MIME:',
+'minlength' => 'Mjena datajow dyrbja znajmjeńša tři pismiki měć.',
+'minoredit' => 'Drobna změna',
+'minoreditletter' => 'D',
+'missingarticle' => 'Datowa banka tekst stronu z mjenom „$1” namakała njeje, byrnjež ju poprawom namakać dyrbjała.
+
+To so zwjetša přez zestarjeny diff abo zestarjeny pokaz stawiznow k stronje, kotraž bu wušmórnjena, zawinuje.
+
+Jeli tomu tak njeje, sće snadź bug w softwarje namakał(a).
+Prošu zdźělće to administratorej podawajo URL.',
+'missingcommenttext' => 'Prošu zapodajće zjeće.',
+'missingimage' => '<b>Pobrachowacy wobraz</b>
+
+<i>$1</i>',
+'missingsummary' => '<b>Kedźbu:</b> Njejsće žane zjeće zapodał(a). Tłóčo druhi raz na „Składować” so Waše změny bjez komentara składuja.',
+'mon' => 'Pón',
+'monday' => 'Póndźela',
+'moredotdotdot' => 'Wjace...',
+'mostcategories' => 'Z najwjace kategorijemi zwjazane strony',
+'mostimages' => 'Z najwjace stronami zwjazane dataje',
+'mostlinked' => 'Z najwjace stronami zwjazane strony',
+'mostlinkedcategories' => 'Z najwjace stronami zwjazane kategorije',
+'mostrevisions' => 'Nastawki z najwjace wersijemi',
+'move' => 'Přesunyć',
+'movearticle' => 'Stronu přesunyć',
+'movedto' => 'přesunjena pod nadpis',
+'movelogpage' => 'Protokol přesunjenjow',
+'movelogpagetext' => 'Deleka je lisćina wšěch přesunjenych stronow.',
+'movenologin' => 'Njejsće přizjewjeny(a)',
+'movenologintext' => 'Dyrbiće zregistrowany wužiwar a [[Special:Userlogin|přizjewjeny(a)]] być, zo byšće stronu přesunyć móhł(a).',
+'movepage' => 'Stronu přesunyć',
+'movepagebtn' => 'Stronu přesunyć',
+'movepagetalktext' => 'Přizamknjena diskusijna strona, jelizo eksistuje, přesunje so awtomatisce hromadźe z njej, <b>chibazo:</b>
+*Njeprózdna diskusijna strona pod nowym mjenom hižo eksistuje abo
+*wotstronjeće hóčku z kašćika deleka.
+
+W tutych padach dyrbiće stronu, jeli požadane, manuelnje přesunyć abo zaměšeć.',
+'movepagetext' => 'Wužiwanje formulara deleka budźe stronu přemjenować, suwajo jeje cyłe stawizny pod nowe mjeno. Stary titul budźe daleposrědkowanje k nowemu titulej. Wotkazy k titulej stareje strony njebudu so měnjeć; njezabudźće, zo byšće za dwójnymi abo poškodźenymi daleposrědkowanjemi přepruwował(a). Sće zamołwity(a) zawěsćić, zo wotkazy na stronu pokazuja, na kotruž dyrbja dowjesć.
+
+Wobkedźbujće, zo strona so <b>nje</b> přesunje, jeli je hižo strona pod nowym titulom, chibazo wona je prózdna abo dalesposrědkowanje a nima zašłe stawizny. To woznamjenja, zo móžeće stronu tam wróćo přemjenować, hdźež bu runje přemjenowana, jelizo činiće zmylk a njemóžeće wobstejacu stronu wušmórnyć.
+
+<b>KEDŹBU!</b> Móže to drastiske a njewočakowana změna za woblubowanu stronu być; prošu sće sej wěsty(a), zo sćěwki z toho rozumiće, prjedy hač pokročujeće.',
+'movereason' => 'Přičina',
+'movetalk' => 'Diskusijnu stronu tohorunja přesunyć',
+'movethispage' => 'Stronu přesunyć',
+'mw_math_html' => 'HTML jeli móžno, hewak PNG',
+'mw_math_mathml' => 'MathML jeli móžno (eksperimentalnje)',
+'mw_math_modern' => 'Za moderne browsery doporučene',
+'mw_math_png' => 'Přeco jako PNG zwobraznić',
+'mw_math_simple' => 'HTML jeli jara jednory, hewak PNG',
+'mw_math_source' => 'Jako TeX wostajić (za tekstowe browsery)',
+'mycontris' => 'Moje přinoški',
+'mypage' => 'Moja strona',
+'mypreferences' => 'moje nastajenja',
+'mytalk' => 'Moja diskusija',
+'namespace' => 'Mjenowy rum:',
+'namespacesall' => 'wšě',
+'navigation' => 'Nawigacija',
+'nbytes' => '$1 {{PLURAL:$1|bajt|bajtow}}',
+'ncategories' => '$1 {{PLURAL:$1|1 kategorija|kategoriji|kategorije|kategorijow}}',
+'newarticle' => '(Nowy nastawk)',
+'newarticletext' => 'Sće wotkazej k stronje slědował, kotraž hišće njeeksistuje. Zo byšće stronu załožił(a), wupjelńće tekstowe polo deleka (hlej [[Project:Help|stronu pomocy]] za wjace informacijow). Sće-li zmylnje tu, klikńće na tłóčku <b>Wróćo</b> swojeho browsera.',
+'newbies' => 'Nowačcy',
+'newimages' => 'Nowe dataje',
+'newmessagesdifflink' => 'rozdźěl k předposlednjej wersiji',
+'newmessageslink' => 'nowe powěsće',
+'newpage' => 'Nowa strona',
+'newpageletter' => 'N',
+'newpages' => 'Nowe nastawki',
+'newpassword' => 'Nowe hesło:',
+'newtitle' => 'Pod nowy titul',
+'newwindow' => '(wočinja so w nowym woknješku)',
+'next' => 'přich',
+'nextdiff' => 'Přichodna wersija →',
+'nextn' => 'přichodne $1',
+'nextpage' => 'Přichodna strona ($1)',
+'nextrevision' => 'Nowša wersija→',
+'nlinks' => '$1 {{PLURAL:$1|wotkaz|wotkazej|wotkazy|wotkazow}}',
+'nmembers' => '{{PLURAL:$1|jedyn čłon|$1 čłonow}}',
+'noarticletext' => 'Tuchwilu tuta strona žadyn tekst njewobsahuje, móžeće jeje titul w druhich stronach [[Special:Search/{{PAGENAME}}|pytać]] abo [{{fullurl:{{FULLPAGENAME}}|action=edit}} stronu załožić].',
+'noconnect' => 'Wodajće! Wiki ma techniske problemy a njemóže ze serwerom datoweje banki zwjazać.
+
+$1',
+'nocontribs' => 'Žane změny, kotrež podatym kriterijam wotpowěduja.',
+'nocookieslogin' => '{{SITENAME}} wužiwa placki (cookies), zo bychu so wužiwarjo přizjewili. Sće placki znjemóžnił(a). Prošu zmóžńće je a spytajće hišće raz.',
+'nocookiesnew' => 'Wužiwarske konto bu załožene, ale njejsće přizjewjeny(a). {{SITENAME}} wužiwa placki (cookies), zo bychu so wužiwarjo přizjewili. Sće placki znjemóžnił(a). Prošu zmóžńće je, potom přizjewće so ze swojim nowym wužiwarskim mjenom a hesłom.',
+'nocreatetext' => 'Móžnosć załoženja nowych stron je w tutym wiki wobmjezowana. Móžeće wobstejace strony wobdźěłać abo [[Special:Userlogin|so přizjewić abo nowe konto załožić]].',
+'nocreatetitle' => 'Załoženje stron je wobmjezowane',
+'nocreativecommons' => 'Creative Commons RDF metadaty su za tutón serwer znjemóžnjene.',
+'nocredits' => 'Žane informacije wo dźakprajenju za tutu stronu njejsu.',
+'nodb' => 'Datowa banka $1 njeda so wubrać',
+'nodublincore' => 'Dublin Core RDF metadaty su za tutón serwer znjemóžnjene.',
+'noemail' => 'Za wužiwarja „$1” žana emailowa adresa podata njeje.',
+'noemailprefs' => '<strong>Njejsće emailowu adres podał(a). Naslědne funkcije fungować njebudu.</strong>',
+'noemailtext' => 'Tutón wužiwar njeje płaćiwu emailowu adresu podał abo je wubrał, zo nochce email wot druhich wužiwarjow dóstać.',
+'noemailtitle' => 'Žana emailowa adresa podata',
+'noexactmatch' => '<b>Nastawk „$1” njeeksistuje. Móžeće [[:$1|jón załožić]].</b>',
+'nohistory' => 'Njeje žanych staršich wersijow za tutu stronu.',
+'noimage' => 'Žana dataja z tutym mjenom njeeksistuje. Móžeće $1.',
+'noimage-linktext' => 'ju nahrać',
+'noimages' => 'Žane dataje.',
+'nolicense' => 'žadyn wuběr',
+'nolinkshere' => 'Žane strony sem njepokazuja.',
+'nolinkstoimage' => 'Žane strony, kotrež na tutu dataju pokazuja.',
+'nologin' => 'Nimaće žane konto? $1.',
+'nologinlink' => 'Wužiwarske konto załožić',
+'noname' => 'Njejsće płaćiwe wužiwarske mjeno podał(a).',
+'nonefound' => '<b>Kedźbu:</b> Pytanja bjez wuspěcha so často z pytanjom za wšědnymi słowami kaž „měć” a „z” zawinuja, kotrež so njeindicěruja abo přez podaće wjace hač jednoho pytanskeho wuraza (jenož strony, kotrež wšě pytanske wurazy wobsahuja, so w lisćinje wuslědkow zjewja).',
+'nonunicodebrowser' => '<strong>KEDŹBU: Waš browser z Unikodu kompatibelny njeje. Prošu wužiwajće druhi browser.</strong>',
+'nospecialpagetext' => 'Sće sej njepłaćiwu specialnu stronu požadał(a), lisćina płaćiwych stronow hodźi so pod [[Special:Specialpages]] namakać.',
+'nosuchaction' => 'Žana tajka akcija',
+'nosuchactiontext' => 'Akcija podata přez URL so přez wiki njepřipóznawa.',
+'nosuchspecialpage' => 'Tuta specialna strona njeeksistuje',
+'nosuchuser' => 'Wužiwarja z mjenom „$1” njeje. Přepruwujće pisanje abo załožiće nowe wužiwarske konto.',
+'nosuchusershort' => 'Wužiwarja z mjenom „$1” njeje. Přepruwujće swoje pisanje.',
+'notacceptable' => 'Wiki-serwer njemóže daty we formaće, kotryž waš klient móže čitać, dodać.',
+'notanarticle' => 'Njeje strona z wobsahom',
+'notargettext' => 'Njejsće cilowu stronu abo wužiwarja podał(a), zo byšće tutu funkciju zmóžnił.',
+'notargettitle' => 'Žadyn cil',
+'note' => '<strong>Kedźbu:</strong>',
+'notextmatches' => 'Žana přezjednota z tekstami stron',
+'notitlematches' => 'Žana přezjednota z titulemi stron',
+'notloggedin' => 'Njepřizjewjeny(a)',
+'nouserspecified' => 'Dyrbiće wužiwarske mjeno zapodać',
+'nov' => 'now',
+'november' => 'nowember',
+'november-gen' => 'nowembra',
+'nowatchlist' => 'Nimaće žane strony w swojich wobkedźbowankach.',
+'nowiki_sample' => 'Zasuńće tu njeformatowany tekst',
+'nowiki_tip' => 'Wiki-formatowanje ignorować',
+'nrevisions' => '$1 {{PLURAL:$1|wobdźěłanje|wobdźěłani|wobdźěłanja|wobdźěłanjow}}',
+'nstab-category' => 'Kategorija',
+'nstab-help' => 'Pomoc',
+'nstab-image' => 'Dataja',
+'nstab-main' => 'Nastawk',
+'nstab-media' => 'Medije',
+'nstab-mediawiki' => 'Powěsć',
+'nstab-project' => 'Projektowa strona',
+'nstab-special' => 'Specialnje',
+'nstab-template' => 'Předłoha',
+'nstab-user' => 'Wužiwarska strona',
+'numauthors' => 'Ličba rozdźělnych awtorow (nastawk): $1',
+'number_of_watching_users_pageview'=> '[$1 wobkedźbowacych wužiwarjow]',
+'numedits' => 'Ličba změnow (nastawk): $1',
+'numtalkauthors' => 'Ličba rozdźělnych awtorow (diskusijna strona): $1',
+'numtalkedits' => 'Ličba změnow (diskusijna strona): $1',
+'numwatchers' => 'Ličba wobkedźbowarjow: $1',
+'nviews' => '$1 {{PLURAL:$1|wotprašenje|$1 wotprašowanjow}}',
+'oct' => 'okt',
+'october' => 'oktober',
+'october-gen' => 'oktobra',
+'ok' => 'W porjadku',
+'revision-info' => 'Wersija wot $1; $2',
+'oldpassword' => 'Stare hesło:',
+'orig' => 'prěnja',
+'othercontribs' => 'Na zakładźe dźěła wužiwarja $1.',
+'otherlanguages' => 'W druhich rěčach',
+'others' => 'druhich',
+'pagecategories' => '{{PLURAL:$1|Kategorija|Kategorije}}',
+'pagemovedsub' => 'Přesunjenje poradźiło',
+'pagemovedtext' => 'Strona „[[$1]]” bu pod titul „[[$2]]” přesunjena.',
+'pagetitle' => '$1 - {{SITENAME}}',
+'passwordremindertext' => 'Něchtó (najskerje Wy, z IP-Adresu $1) je wo nowe hesło za přizjewjenje pola {{GRAMMAR:genitiw|{{SITENAME}}}} prosył. Hesło za wužiwarja "$2" je nětko "$3".
+Wy měł(a) so nětko přizjewić a swoje hesło změnić.
+
+Je-li něchto druhi hač Wy wo nowe hesło prosył, abo sće so zaso na njo dopomnił(a),
+móžeće tutu powěsć ignorować a ze starym hesłom pokročować.',
+'passwordremindertitle' => 'Skedźbnjenje na hesło z {{GRAMMAR:genitiw|{{SITENAME}}}}',
+'passwordsent' => 'Nowe hesło bu k emailowej adresy wužiwarja „$1” pósłane. Prošu přizjewće so, tak chětře kaž je dóstanjeće.',
+'passwordtooshort' => 'Waše hesło je překrótke. Dyrbi znajmjeńša $1 znamješkow měć.',
+'perfcached' => 'Naslědne daty pochadźeja z pufrowaka a njejsu snadź hižo aktualne.',
+'perfcachedts' => 'Naslědne daty pochadźeja z pufrowaka a buchu $1 posledni raz zaktualizowane.',
+'perfdisabled' => 'Wodajće! Tuta funkcija bu nachwilnje znjemóžnjena, dokelž datowu banku tak spomaluje, zo hižo nichtó wiki wužiwać njemóže.',
+'perfdisabledsub' => 'Tu je składowana kopija z $1:',
+'permalink' => 'Permanentny link',
+'personaltools' => 'Wosobinske graty',
+'popularpages' => 'Často wopytowane strony',
+'portal' => 'Portal {{GRAMMAR:genitiw|{{SITENAME}}}}',
+'portal-url' => 'Project:Portal',
+'postcomment' => 'Komentar dodawać',
+'powersearch' => 'Pytać',
+'powersearchtext' => 'W mjenowych rumach pytać:<br />$1<br />$2 Daleposrědkowanja naličeć<br />Za $3 $9 pytać',
+'preferences' => 'Nastajenja',
+'prefixindex' => 'Wšě nastawki (z prefiksom)',
+'prefs-help-email' => '* Email (opcionalnje): Zmóžnja druhim was přez wašu wužiwarsku abo diskusijnu stronu kontaktować, bjeztoho zo dyrbiće swoju identitu wotkryć. Sće-li swoje hesło zabył(a), budźe móžno, Wam nowe hesło připósłać.',
+'prefs-help-email-enotif'=> 'Tuta adresa so wužiwa, zo bychu so wam emailowe zdźělenki słali, jelizo sće tute opcije zmóžnił(a).',
+'prefs-help-realname' => '* Woprawdźite mjeno (opcionalnje): jelizo chceće je wotkryć, budźe so wužiwać, zo by so prawo za waše dźěło dało.',
+'prefs-misc' => 'Wšelake nastajenja',
+'prefs-personal' => 'Wužiwarske daty',
+'prefs-rc' => 'Aktualne změny',
+'prefs-watchlist' => 'Wobkedźbowanki',
+'prefs-watchlist-days' => 'Ličba dnjow, kotrež maja so we wobkedźbowankach pokazać:',
+'prefs-watchlist-edits' => 'Ličba změnow, kotrež maja so we wobkedźbowankach pokazać:',
+'prefsnologin' => 'Njepřizjewjeny(a)',
+'prefsnologintext' => 'Dyrbiće [[Special:Userlogin|přizjewjeny(a)]] być, zo bychu so wužiwarske nastajenja stajili.',
+'prefsreset' => 'Nastajenja su ze składa wróćo stajili.',
+'preview' => 'Přehlad',
+'previewconflict' => 'Tutón přehlad tekst w hornim tekstowym polu wotbłyšćuje kaž so zjewi, jelizo jón składujeće.',
+'previewnote' => '<strong>Kedźbu, to je jenož přehlad, změny hišće składowane njejsu!</strong>',
+'previousdiff' => '← Předchadna wersija',
+'previousrevision' => '←Starša wersija',
+'prevn' => 'předchadne $1',
+'print' => 'Ćišćeć',
+'printableversion' => 'Ćišćomna wersija',
+'privacy' => 'Škit datow',
+'privacypage' => 'Project:Škit datow',
+'projectpage' => 'Projektowu stronu pokazać',
+'protect' => 'Škitać',
+'protect-default' => '(standard)',
+'protect-level-autoconfirmed'=> 'jenož přizjewjeni wužiwarjo',
+'protect-level-sysop' => 'jenož administratorojo',
+'protect-text' => 'Tu móžeće status za škit strony <b>$1</b> widźeć a změnić. Prošu mějće so po prawidłami za škitane strony!',
+'protect-unchain' => 'Jenož škit před přesuwanjom změnić',
+'protect-viewtext' => 'Nimaće trěbne prawa za změnjenje škitoweho statusa. Tu je aktualny škitowy status za stronu <strong>$1</strong>:',
+'protectcomment' => 'Přičina za škitanje:',
+'protectedarticle' => 'Strona „[[$1]]” bu škitana',
+'protectedinterface' => 'Tuta strona wobsahuje tekst za rěčny zwjerch a je škitana zo by so znjewužiwanju zadźěwało.',
+'protectedpage' => 'Škitana strona',
+'protectedpagewarning' => '<strong>KEDŹBU: Strona bu škitana, zo bychu ju jenož wužiwarjo z prawami sysopa wobdźěłać móhli. Přeswědčće so, zo maće so po směrnicami za škitane strony.</strong>',
+'protectedtext' => 'Tuta strona je za wobdźěłowanje zawrjena.
+
+Móžeće pak žórłowy tekst strony wobhladać a kopěrować:',
+'protectlogpage' => 'Protokol škita',
+'protectlogtext' => 'To je lisćina škitanych stronow.',
+'protectmoveonly' => 'Jenož před přesuwanjom škitać',
+'protectsub' => '(Stronu „$1” škitać)',
+'protectthispage' => 'Stronu škitać',
+'proxyblocker' => 'Awtomatiske blokowanje wotewrjenych proxy-serwerow',
+'proxyblockreason' => 'Waša IP-adresa bu zablokowana, dokelž je wona wotewrjeny proksy. Prošu skontaktujće swojeho providera abo syćoweho administratora a informujće jeho wo tutym chutnym problemom wěstosće.',
+'proxyblocksuccess' => 'Hotowo.',
+'qbbrowse' => 'Přepytować',
+'qbedit' => 'Wobdźěłać',
+'qbfind' => 'Namakać',
+'qbmyoptions' => 'Moje strony',
+'qbpageinfo' => 'Kontekst',
+'qbpageoptions' => 'Tuta strona',
+'qbsettings' => 'Gratowa wobkroma',
+'qbspecialpages' => 'Specialne strony',
+'randompage' => 'Připadny nastawk',
+'randomredirect' => 'Připadne daleposrědkowanje',
+'range_block_disabled' => 'Dowolenje sysopa, cyłe wobkruhi IP-adresow blokować, je znjemóžnjene.',
+'rc_categories' => 'Jenož kategorije (dźělene z "|")',
+'rc_categories_any' => 'wšě',
+'rclinks' => 'Poslednje $1 změnow poslednych $2 dnjow pokazać<br />$3',
+'rclistfrom' => 'Nowe změny pokazać, započinajo z $1',
+'rclsub' => '(k stronam, na kotrež strona „$1” pokazuje)',
+'rcnote' => 'Deleka su poslednje <strong>$1</strong> změny poslednich <strong>$2</strong> dnjow, staw wot $3.',
+'rcnotefrom' => 'Deleka so změny wot <b>$2</b> pokazuja (hač k <b>$1</b>).',
+'rcpatroldisabled' => 'Dohladowanje najaktualnišich změnow znjemóžnjene',
+'rcpatroldisabledtext' => 'Funkcija dohladowanja najaktualnišich změnow je tuchwilu znjemóžnjena.',
+'rcshowhideanons' => 'Změny anonymnych wužiwarjow $1',
+'rcshowhidebots' => 'Změny awtomatiskich programow (bots) $1',
+'rcshowhideliu' => 'Změny přizjewjenych wužiwarjow $1',
+'rcshowhidemine' => 'Swójske přinoški $1',
+'rcshowhideminor' => 'Drobne změny $1',
+'rcshowhidepatr' => 'Dohladowane změny $1',
+'readonly' => 'Datowa banka je zawrjena',
+'readonly_lag' => 'Datowa banka bu awtomatisce zawrjena, mjeztym zo pospytuja wotwisne serwery datowych bankow hłowny serwer docpěć',
+'readonlytext' => 'Datowa banka je tuchwilu za nowe zapiski a změnjenja zawrjena, najskerje za hladanske dźěła. Po tym wšo budźe zaso normalne.
+
+Administrator, kiž je ju zawrjeł, je tute rozjasnjenje dał: $1',
+'readonlywarning' => '<strong>KEDŹBU: Datowa banka bu hižo za hladanje zawrjena, tohodla njemóžeće swoje wobdźěłowanja nětko składować. Móžeće tekst do tekstoweje dataje přesunyć a jón za pozdźišo składować.</strong>',
+'recentchanges' => 'Aktualne změny',
+'recentchangesall' => 'wšě',
+'recentchangescount' => 'Ličba titulow w aktualnych změnach:',
+'recentchangeslinked' => 'Změny zwjazanych stron',
+'recentchangestext' => 'Na tutej stronje móžeće najaktualniše změny w {{GRAMMAR:lokatiw|{{SITENAME}}}} wobkedźbować.',
+'recreate' => 'Wobnowić',
+'redirectedfrom' => '(Ze strony „$1” sposrědkowane)',
+'redirectingto' => 'Posrědkuju k stronje [[$1]]',
+'redirectpagesub' => 'Daleposrědkowanje',
+'remembermypassword' => 'Sej za dalše posedźenja spomjatkować',
+'removechecked' => 'Markěrowane strony z wobkedźbowankow wotstronić',
+'removedwatch' => 'Strona bu z wobkedźbowankow wotstronjena',
+'removedwatchtext' => 'Strona „[[:$1]]” bu z wobkedźbowankow wotstronjena.',
+'removingchecked' => 'Strony so z wobkedźbowankow wotstronjeja...',
+'resetprefs' => 'Wróćo stajić',
+'restorelink' => '{{PLURAL:$1|jednoho wušmórnjeneho wobdźěłanja|$1 wušmórnjenych wobdźěłanjow}}',
+'restrictedpheading' => 'Specialne strony za administratorow',
+'restriction-edit' => 'wobdźěłać',
+'restriction-move' => 'přesunyć',
+'resultsperpage' => 'Wuslědki po stronje:',
+'retrievedfrom' => 'Z {{GRAMMAR:genitiw|"$1"}}',
+'returnto' => 'Wróćo k stronje $1.',
+'retypenew' => 'Nowe hesło znowa zapodać:',
+'reupload' => 'Znowa nahrawać',
+'reuploaddesc' => 'Wróćo k nahrawanskemu formularej.',
+'rev-deleted-comment' => '(komentar wotstronjeny)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">Tuta wersija bu wušmórnjena a njeda so wjace čitać. Přićinu móžeće w [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} protokolu wušmórnjenjow] zhonić.</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">Tuta wersija bu wušmórnjena a njeda so wjace čitać. Jako administrator móžeće ju pak dale čitać. Přićinu móžeće w [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} protokolu wušmórnjenjow] zhonić.</div>',
+'rev-deleted-user' => '(wužiwarske mjeno wotstronjene)',
+'rev-delundel' => 'pokazać/schować',
+'revdelete-hide-comment'=> 'Zjeće schować',
+'revdelete-hide-restricted'=> 'Tute wobmjezowanja na administratorow kaž tež na druhich wužiwarjow nałožować',
+'revdelete-hide-text' => 'Tekst tuteje wersije schować',
+'revdelete-hide-user' => 'Wužiwarske mjeno/IP-adresu schować',
+'revdelete-legend' => 'Wobmjezowanja za wersije zrjadować:',
+'revdelete-log' => 'Komentar w protokolu:',
+'revdelete-logentry' => 'Widźomnosć wersije změnjena za [[$1]]',
+'revdelete-selected' => 'Wubrana wersija strony [[:$1]]:',
+'revdelete-submit' => 'Na wubranu wersiju nałožować',
+'revdelete-text' => 'Wušmórnjene wersije so w stawiznach dale jewja, jich wobsah pak za wužiwarjow čitajomne njeje.
+
+Druzy administratorojo w tutym wiki móža schowany tekst dale čitać a jón wobnowić, chibazo su tež jich prawa wobmjezowane.',
+'reverted' => 'Na staršu wersiju cofnjene',
+'revertimg' => 'Cofnyć',
+'revertmove' => 'wróćo přesunyć',
+'revertpage' => 'Změny wužiwarja [[User:$2|$2]] ([[Special:Contributions/$2|přinoški]]) cofnjene, nawróćene k poslednjej wersiji wužiwarja [[User:$1|$1]]',
+'revhistory' => 'Stawizny',
+'revisionasof' => 'Wersija z $1',
+'revisiondelete' => 'Wersije wušmórnyć/wobnowić',
+'revnotfound' => 'Njebě móžno, požadanu wersiju namakać',
+'revnotfoundtext' => 'Stara wersija strony, kotruž sće požadał(a), njeda so namakać. Prošu přepruwujće URL, kiž sće wužiwał(a).',
+'rights' => 'Prawa:',
+'rightslog' => 'Protokol zrjadowanja wužiwarskich prawow',
+'rightslogentry' => 'Skupinowe čłonstwo za $1 z $2 na $3 změnjene',
+'rightslogtext' => 'To je protokol změnow wužiwarskich prawow.',
+'rightsnone' => '(ničo)',
+'rollback' => 'Změny cofnyć',
+'rollback_short' => 'Cofnyć',
+'rollbackfailed' => 'Cofnjenje njeporadźiło',
+'rollbacklink' => 'Cofnyć',
+'rows' => 'Rjadki:',
+'sat' => 'Sob',
+'saturday' => 'Sobota',
+'savearticle' => 'Składować',
+'savedprefs' => 'Waše nastajenja buchu składowane.',
+'savefile' => 'Dataju składować',
+'saveprefs' => 'Składować',
+'saveusergroups' => 'Wužiwarske skupiny składować',
+'scarytranscludedisabled'=> '[Zapřijeće interwiki je znjemóžnjene]',
+'scarytranscludefailed' => '[Zapřijeće předłohi za stronu $1 njebě mózno]',
+'scarytranscludetoolong'=> '[Nažel běše URL předołhi]',
+'search' => 'Pytać',
+'searcharticle' => 'Nastawk',
+'searchbutton' => 'Pytać',
+'searchcontaining' => 'Za nastawkami pytać, w kotrychž so <i>$1</i> jewi.',
+'searchdisabled' => 'Pytanje w {{GRAMMAR:lokatiw|{{SITENAME}}}} je znjemóžnjene. Móžeće mjeztym z Google pytać. Wobkedźbujće, zo móža wuslědki z wobsaha {{GRAMMAR:genitiw|{{SITENAME}}}} zestarjene być.',
+'searchfulltext' => 'Dospołny tekst pytać',
+'searchnamed' => 'Za nastawkami pytać, w kotrychž titulach so <i>$1</i> jewi.',
+'searchresults' => 'Pytanske wuslědki',
+'searchresultshead' => 'Pytać',
+'searchresulttext' => 'Za wjace informacijow wo přepytowanju {{GRAMMAR:genitiw|{{SITENAME}}}}, hlej [[Project:Searching|Pytanje w {{GRAMMAR:lokatiw|{{SITENAME}}}}]].',
+'searchsubtitle' => 'Sće naprašowanje za „[[:$1]]“ stajił(a).',
+'searchsubtitleinvalid' => 'Sće naprašowanje za „$1“ stajił(a).',
+'selectnewerversionfordiff'=> 'Nowšu wersiju za přirunanje wubrać',
+'selectolderversionfordiff'=> 'Staršu wersiju za přirunanje wubrać',
+'selfmove' => 'Žórłowy a cilowy titul stej samsnej; strona njehodźi so na sebje samu přesunyć.',
+'semiprotectedpagewarning'=> '<b>Kedźbu:</b> Strona bu škitana, zo bychu ju jenož přizjewjeni wužiwarjo wobdžełać móhli.',
+'sep' => 'sep',
+'september' => 'september',
+'september-gen' => 'septembra',
+'servertime' => 'Čas serwera',
+'session_fail_preview' => '<strong>Zda so, zo je problem z Wašim přizjewjenjom; tuta akcija bu wěstosće dla přećiwo zadobywanju do posedźenja znjemóžnjena. Prošu spytajće hišće raz. Wostanje-li tutón problem, spytajće so wotzjewić a so zaso přizjewić.</strong>',
+'session_fail_preview_html'=> '<strong>Bohužel njemóžemy waše změny składować dokelž su Waše přizjewjenske daty zhubjene.</strong>
+
+<i>Dokelž w tutym wiki je raw HTML zmóžnjene, je přehlad schowany jako wěstotna naprawa přećiwo JavaScript-nadběham.</i>
+
+<strong>Je-li to legitimny pospyt změnjenja, spytajće hišće raz. Wostanje-li tutón problem, spytajće so wotzjewić a so zaso přizjewić.</strong>',
+'sessionfailure' => 'Zda so, zo je problem z Wašim přizjewjenjom; tuta akcija bu wěstosće dla přećiwo zadobywanju do posedźenja znjemóžniła. Prošu klikńće na "Wróćo" a začitajće stronu, z kotrejež přińdźeće, znowa; potom spytajće hišće raz.',
+'set_rights_fail' => '<b>Prawa za wužiwarja „$1” njedadźa so nastajić. (Sće mjeno prawje zapisał(a)?)</b>',
+'set_user_rights' => 'Wužiwarske prawa zrjadować',
+'setbureaucratflag' => 'Wužiwarja k běrokratej činić',
+'sharedupload' => 'Tuta dataja je zhromadne nahraće a móhła so přez druhe projekty wužiwać.',
+'shareduploadwiki' => 'Za dalše informacije hlej $1.',
+'shareduploadwiki-linktext'=> 'stronu datajoweho wopisanja',
+'shortpages' => 'Krótke nastawki',
+'show' => 'pokazać',
+'showbigimage' => 'Wersiju z wysokim rozpušćenjom sćahnyć ($1x$2, $3 KB)',
+'showdiff' => 'Změny pokazać',
+'showhidebots' => '($1 bots)',
+'showingresults' => 'Hač do <b>$1</b> wuslědkow so deleka pokazuje, započinajo z #<b>$2</b>.',
+'showingresultsnum' => '<b>$3</b> wuslědkow so deleka pokazuje, započinajo z #<b>$2</b>.',
+'showlast' => 'Poslednje $1 datajow sortěrowanych po $2 pokazać.',
+'showlivepreview' => 'Live-přehlad',
+'showpreview' => 'Přehlad pokazać',
+'showtoc' => 'pokazać',
+'sig_tip' => 'Waša signatura z časowym kołkom',
+'sitestats' => 'Statistika {{GRAMMAR:genitiw|{{SITENAME}}}}',
+'sitestatstext' => 'Je dohromady <b>$1</b> stron w datowej bance. To zapřija tež diskusijne strony, strony wo {{GRAMMAR:lokatiw|{{SITENAME}}}}, krótke nastawki, daleposrědkowanja a druhe, kotrež najskerje nastawki njejsu.
+
+Zwostanje <b>$2</b> stronow, kotrež najskerje su legitimne strony z wobsahom.
+
+Dohromady bu <b>$8</b> datajow nahratych.
+
+Běše tam dohromady <b>$3</b> wobhladanjow stron a <b>$4</b> změnow stron, wot toho, zo bu wiki připrawjeny. Běše přerěznje <b>$5</b> změnow na stronu a <b>$6</b> wobhladanjow na změnu.
+
+Dołhosć [http://meta.wikimedia.org/wiki/Help:Job_queue „Job queue”]je <b>$7</b>.',
+'sitesupport' => 'Projekt podpěrować',
+'sitesupport-url' => 'Project:Darić',
+'siteuser' => 'wužiwar {{GRAMMAR:genitiw|{{SITENAME}}}} $1',
+'siteusers' => 'wužiwar(jo) {{GRAMMAR:genitiw|{{SITENAME}}}} $1',
+'skin' => 'Skin',
+'skinpreview' => '(Přehlad)',
+'sorbs' => 'SORBS DNSbl',
+'sorbs_create_account_reason'=> 'Waša IP-adresa je zapisana jako wotewrjeny proksy na [http://www.sorbs.net SORBS] DNSBL. Njemóžeće konto załožić.',
+'sorbsreason' => 'Waša IP-adresa je zapisana jako wotewrjeny proksy na [http://www.sorbs.net SORBS] DNSBL.',
+'sourcefilename' => 'Mjeno žórłoweje dataje',
+'sp-contributions-newbies-sub'=> 'Za nowačkow',
+'sp-contributions-newer'=> 'Nowše $1',
+'sp-contributions-newest'=> 'Najnowše',
+'sp-contributions-older'=> 'Starše $1',
+'sp-contributions-oldest'=> 'Najstarše',
+'sp-newimages-showfrom' => 'Nowe dataja pokazać, započinajo z $1',
+'spam_blanking' => 'Wšě wersije wobsahowachu wotkazy na $1, wučisćene.',
+'spam_reverting' => 'Wobnowjejo poslednju wersiju bjez wotkazow na $1',
+'spambot_username' => 'MediaWiki čisćenje wot spama',
+'spamprotectionmatch' => 'Naslědny tekst je naš spamowy filter zahibał: $1',
+'spamprotectiontext' => 'Strona, kotruž sće spytał(a) składować, bu přez spamowy filter blokowana. Bu to najskerje přez wotkaz k eksternemu sydłu zawinowane.',
+'spamprotectiontitle' => 'Filter za škit přećiwo spamej',
+'speciallogtitlelabel' => 'Titul:',
+'specialloguserlabel' => 'Wužiwar:',
+'specialpage' => 'Specialna strona',
+'specialpages' => 'Specialne strony',
+'spheading' => 'Specialne strony za wšěch wužiwarjow',
+'sqlhidden' => '(SQL wotprašenje schowane)',
+'statistics' => 'Statistika',
+'storedversion' => 'Składowana wersija',
+'stubthreshold' => 'Próh za pjenk:',
+'subcategories' => 'Podkategorije',
+'subcategorycount' => 'W tutej kategoriji {{PLURAL:$1|je jedna podkategorija|stej $1 podkategoriji|su rest podkategorije}}',
+'subject' => 'Tema/Nadpismo',
+'successfulupload' => 'Dataja bu wuspěšnje nahrata',
+'summary' => 'Zjeće',
+'sun' => 'Njedź',
+'sunday' => 'Njedźela',
+'tagline' => 'Z {{GRAMMAR:genitiw|{{SITENAME}}}}',
+'talk' => 'Diskusija',
+'talkexists' => 'Strona sama bu z wuspěchom přesunjena, ale diskusijna strona njeda so přesunyć, dokelž pod nowym titulom hižo eksistuje. Prošu změšće jeju manuelnje.',
+'talkpage' => 'Diskusija',
+'talkpagemoved' => 'Wotpowědna diskusijna strona bu tohorunja přesunjena.',
+'talkpagenotmoved' => 'Wotpowědna diskusijna strona <strong>njebu</strong> přesunjena.',
+'templatepage' => 'Předłohu pokazać',
+'templatesused' => 'Na tutej stronje wužiwane předłohi:',
+'textboxsize' => 'Wobdźěłowanje',
+'textmatches' => 'Přezjednota z tekstami stron',
+'thisisdeleted' => '$1 pokazać abo wobnowić?',
+'thu' => 'Štw',
+'thumbnail-more' => 'powjetšić',
+'thumbnail_error' => 'Zmylk při wudźěłanju předhladoweho wobraza: $1',
+'thumbsize' => 'Wulkosć přehlada wobrazow:',
+'thursday' => 'Štwórtk',
+'timezonelegend' => 'Časowe pasmo',
+'timezoneoffset' => 'Wurunanje¹',
+'timezonetext' => 'Zapisajće ličbu hodźin, wo kotrež Waš lokalny čas so wot časa serwera (UTC) wotchila.',
+'titlematches' => 'Přezjednota z titulemi nastawkow',
+'toc' => 'Wobsah',
+'tog-autopatrol' => 'Moje wobdźěłanja jako dohladowane woznamjenjeć',
+'tog-editondblclick' => 'Strony z dwójnym kliknjenjom wobdźěłować (trjeba JavaScript)',
+'tog-editsection' => 'Wobdźěłowanje jednotliwych wotrězkow přez wosebite wotkazy zmóžnić',
+'tog-editsectiononrightclick'=> 'Wobdźěłowanje jednotliwych wotrězkow přez kliknjenje z prawej tastu<br />na nadpisma wotrězkow zmóžnić (JavaScript)',
+'tog-editwidth' => 'Wobdźěłanski kašćik ma połnu šěrokosć',
+'tog-enotifminoredits' => 'Email tež dla drobnych změnow pósłać',
+'tog-enotifrevealaddr' => 'Moju emailowu adresu w emailowych zdźělenkach wotkryć',
+'tog-enotifusertalkpages'=> 'Email pósłać, hdyž so moja diskusijna strona změni',
+'tog-enotifwatchlistpages'=> 'Email wo změnach wobkedźbowanych stron pósłać',
+'tog-extendwatchlist' => 'Rozšěrjena lisćina wobkedźbowankow',
+'tog-externaldiff' => 'Eksterny diff-program jako standard wužiwać',
+'tog-externaleditor' => 'Eksterny editor jako standard wužiwać',
+'tog-fancysig' => 'Hrube signatury (bjez awtomatiskeho wotkaza)',
+'tog-forceeditsummary' => 'Mje warnować, zabudu-li zjeće',
+'tog-hideminor' => 'Drobne změny w poslednich změnach schować',
+'tog-highlightbroken' => 'Wotkazy na prózdne nastawki <a href="" class="new">tak</a> (alternative: like this<a href="" class="internal">?</a>)zběhnyć',
+'tog-justify' => 'Wotstawki w blokowej sadźbje',
+'tog-minordefault' => 'Wšě změny jako drobne woznamjenić',
+'tog-nocache' => 'Pufrowanje strony znjemóžnić',
+'tog-numberheadings' => 'Nadpisma awtomatisce čisłować',
+'tog-previewonfirst' => 'Do składowanja přeco přehladku pokazać',
+'tog-previewontop' => 'Přehladku nad wobdźěłanskim kašćikom pokazać',
+'tog-rememberpassword' => 'Hesło za dalše posedźenja składować',
+'tog-showjumplinks' => 'Wotkazy typa „dźi do” zmóžnić',
+'tog-shownumberswatching'=> 'Ličbu wobkedźbowacych wužiwarjow pokazać',
+'tog-showtoc' => 'Zapis wobsaha pokazać (za strony z wjace hač 3 nadpismami)',
+'tog-showtoolbar' => 'Wobdźěłowansku wobkromu pokazać (trjeba JavaScript)',
+'tog-underline' => 'Wotkazy podšmórnyć:',
+'tog-uselivepreview' => 'Live-přehladku wužiwać (JavaScript) (eksperimentalnje)',
+'tog-usenewrc' => 'Rozšěrjena lisćina aktualnych změnow (trjeba JavaScript)',
+'tog-watchcreations' => 'Strony, kotrež załožu, wobkedźbowankam přidać',
+'tog-watchdefault' => 'Strony, kotrež wobdźěłam, wobkedźbowankam přidać',
+'tog-watchlisthidebots' => 'Změny awtomatiskich programow (botow) na wobkedźbowanskach schować',
+'tog-watchlisthideown' => 'Moje změny na wobkedźbowankach schować',
+'toolbox' => 'Graty',
+'tooltip-compareselectedversions'=> 'Rozdźěle mjez wubranymaj wersijomaj tuteje strony pokazać. [alt-v]',
+'tooltip-diff' => 'Waše změny tuteje strony pokazać. [alt-v]',
+'tooltip-minoredit' => 'To jako drobnu změnu woznamjenić [alt-i]',
+'tooltip-preview' => 'Wobhladajće swoje změny, prošu čińće to do składowanja! [alt-p]',
+'tooltip-recreate' => 'Stronu znowa załožić, byrnjež bu wumšmórnjena',
+'tooltip-save' => 'Změny składować [alt-s]',
+'tooltip-search' => '{{GRAMMAR:akuzatiw|{{SITENAME}}}} přepytać [alt-f]',
+'tooltip-watch' => 'Tutu stronu wobkedźbowankam přidać [alt-w]',
+'trackbackbox' => '<div id="mw_trackbacks">Trackbacks za tutón nastawk:<br />
+$1</div>',
+'trackbackdeleteok' => 'Trackback bu wuspěšnje wušmórnjeny.',
+'trackbacklink' => 'Trackback',
+'trackbackremove' => '([$1 wušmórnyć])',
+'tryexact' => 'Dokładne pytanje spytać',
+'tue' => 'Wut',
+'tuesday' => 'Wutora',
+'uclinks' => 'Poslednje $1 přinoškow pokazać; poslednje $2 dnjow pokazać.',
+'ucnote' => 'Deleka su poslednje <b>$1</b> změnow wužiwarja z poslednich <b>$2</b> dnjow.',
+'uctop' => '(aktualnje)',
+'uid' => 'ID wužiwarja:',
+'unblocked' => 'Wužiwar [[User:$1|$1]] bu dopušćeny',
+'unblockip' => 'Blokowanje zběhnyć',
+'unblockiptext' => 'Wužijće formular deleka, zo byšće blokowanje IP-adresy abo wužiwarskeho mjena zběhnył(a).',
+'unblocklink' => 'blokowanje zběhnyć',
+'unblocklogentry' => 'blokowanje wužiwarja $1 bu zběhnjene',
+'uncategorizedcategories'=> 'Njeklasifikowane kategorije',
+'uncategorizedimages' => 'Njeklasifikowane dataje',
+'uncategorizedpages' => 'Njeklasifikowane strony',
+'undelete' => 'Wušmórnjenu stronu wobnowić',
+'undelete_short' => '{{PLURAL:$1|jednu wersiju|$1 wersijow}} wobnowić',
+'undeletearticle' => 'Wušmórnjenu stronu wobnowić',
+'undeletebtn' => 'Wobnowić',
+'undeletecomment' => 'Přičina:',
+'undeletedarticle' => 'Strona „$1” bu wuspěšnje wobnowjena.',
+'undeletedfiles' => '$1 dataje/datajow wobnowjenych',
+'undeletedpage' => '<big><b>Strona $1 bu z wuspěchom wobnowjena.</b></big>
+
+Hlej [[Special:Log/delete|protokol]] za lisćinu aktualnych wušmórnjenjow a wobnowjenjow.',
+'undeletedrevisions' => '$1 wersijow wobnowjenych.',
+'undeletedrevisions-files'=> '$1 rewizijow a $2 dataje/datajow wobnowjenych',
+'undeleteextrahelp' => 'Zo byšće stronu z wšěmi wersijemi wobnowił(a) zapodajće prošu přičinu a klikńće na <b>Wobnowić</b>. Chceće-li jenož jednotliwe wersije wobnowić, wuběrće prošu jich markěrowanske pola, zapodajće přičinu a klikńće na <b>Wobnowić</b>. Kliknjenje na <b>Cofnyć</b> wuprózdni komentarowe polo a wšě markěrowanske pola.',
+'undeletehistory' => 'Jeli stronu wobnowjeće, zapřijmnu so wšě wersije zaso do stawiznow. Jelizo bu po wušmórnjenju nowa strona ze samsnym mjenom załožena, budu so wobnowjene wersije w prjedawšich stawiznach jewić a tuchwilna wersija aktualneje strony njebudźe so awtomatisce narunować.',
+'undeletehistorynoadmin'=> 'Tuta strona bu wušmórnjena. Přičina za wušmórnjenje je deleka zapodata kaž tež detaile k poslednjemu wužiwarjej, kotryž je stronu před wušmórnjenjom wobdźěłał. Tuchwilny wobsah strony je jenož administratoram přistupny.',
+'undeletepage' => 'Wušmórnjene strony wobnowić',
+'undeletepagetext' => 'Tute strony buchu wušmórnjene, su pak hišće w datowej bance składowane a móža so wobnowić.',
+'undeletereset' => 'Cofnyć',
+'undeleterevision' => 'Wušmórnjena wersija z dnja $1',
+'undeleterevisions' => '$1 wersijow archiwowanych',
+'underline-always' => 'Přeco',
+'underline-default' => 'Přednastajenje browsera',
+'underline-never' => 'Ženje',
+'unexpected' => 'Njewočakowana hódnota: "$1"="$2".',
+'unit-pixel' => 'px',
+'unlockbtn' => 'Zawrjenje datoweje banki zběhnyć',
+'unlockconfirm' => 'Haj, chcu woprawdźe zawrjenje datoweje banki zběhnyć.',
+'unlockdb' => 'Škit datoweje banki zběhnyć',
+'unlockdbsuccesssub' => 'Škit datoweje banki zběhnjeny',
+'unlockdbsuccesstext' => 'Zawrjenje datoweje banki bu zběhnjene.',
+'unlockdbtext' => 'Zběhnjenje škita datoweje banki zaso wšěm wužiwarjam zmóžni strony wobdźěłać, jich nastajenja změnić, jich wobkedźbowanki wobdźěłać a hinaše dźěła činić, kotrež sej změny w datowej bance žadaja. Prošu wobkrućće, zo chceće škit datoweje banki woprawdźe zběhnyć.',
+'unprotect' => 'Škit zběhnyć',
+'unprotectcomment' => 'Přičina za zběhnjenje škita',
+'unprotectedarticle' => 'Škit strony „[[$1]]” bu zběhnjeny',
+'unprotectsub' => '(Škit za stronu „$1” so zběhnje)',
+'unprotectthispage' => 'Škit za tutu stronu zběhnyć',
+'unusedcategories' => 'Njewužiwane kategorije',
+'unusedcategoriestext' => 'Slědowace strony kategorijow eksistuja hačrunjež žadyn druhi nastawk abo kategorija je wužiwa.',
+'unusedimages' => 'Njewužiwane dataje',
+'unusedimagestext' => '<p>Prošu wobkedźbujće, zo móža druhe web-sydła z wobrazom z direktnym URL zwjazane a móža tu naličene być, hačrunjež su w aktiwnym wužiwanjom.</p>',
+'unusedtemplates' => 'Njewužiwane předłohi',
+'unusedtemplatestext' => 'Na tutej stronje widźiće wšě předłohi, kiž so wot druhich stron njewužiwaju. Přepruwujće wotkazy k druhim předłoham, prjedy hač je wotstronjeće.',
+'unusedtemplateswlh' => 'Druhe wotkazy',
+'unwatch' => 'Njewobkedźbować',
+'unwatchedpages' => 'Njewobkedźbowane strony',
+'unwatchthispage' => 'Wobkedźbowanje skónčić',
+'updated' => '(Zaktualizowany)',
+'updatedmarker' => 'Změny z mojeho poslednjeho wopyta',
+'upload' => 'Dataju nahrawać',
+'upload_directory_read_only'=> 'Nahrawanski zapis ($1) njehodźi so přez webserwer popisować.',
+'uploadbtn' => 'Dataju nahrawać',
+'uploadcorrupt' => 'Dataja je wobškodźena abo ma njekorektny sufiks. Prošu přepruwujće dataju a wotsćelće ju hišće raz.',
+'uploaddisabled' => 'Wodajće, nahrawanje bu znjemóžnjene.',
+'uploaddisabledtext' => 'Nahrawanje datajow bu w tutym wiki znjemóžnjene.',
+'uploadedfiles' => 'Nahrate dataje',
+'uploadedimage' => 'je dataju „[[$1]]” nahrał(a)',
+'uploaderror' => 'Zmylk při nahrawanju',
+'uploadlog' => 'Protokol nahrawanjow',
+'uploadlogpage' => 'Protokol_nahrawanjow',
+'uploadlogpagetext' => 'Deleka je lisćina naposledk nahratych datajow.',
+'uploadnewversion-linktext'=> 'nowu wersiju tuteje dataje nahrać',
+'uploadnologin' => 'Njepřizjewjeny(a)',
+'uploadnologintext' => 'Dyrbiće [[Special:Userlogin|přizjwjeny(a)]] być, zo byšće dataje nahrawać móhł(a).',
+'uploadscripted' => 'Tuta dataja wobsahuje HTML- abo skriptowy kode, kotryž móhł so zmylnje přez web-browser wuwjesć.',
+'uploadtext' => 'Wužijće formular deleka, zo byšće nowe dataje nahrał(a); zo byšće prjedy nahrate wobrazy wobhladał(a) abo pytał(a) dźiće k [[Special:Imagelist|lisćinje nahratych datajow]]; detaile k nahrawanjam a wušmórnjenjam namakaće tež w [[Special:Log/upload|protokolu nahrawanjow]].
+
+Zo by so wobraz do strony zapřijał, wužijće jón we formje
+* <b><nowiki>[[Image:Dataja.jpg]]</nowiki></b>
+* <b><nowiki>[[Image:Dataja.png|alt tekst]]</nowiki></b>
+abo zo by so direktnje z dataju zwjazało
+* <b><nowiki>[[Media:Dataja.ogg]]</nowiki></b>',
+'uploadvirus' => 'Dataja wirus wobsahuje! Drobnosće: $1',
+'uploadwarning' => 'Warnowanje',
+'user_rights_set' => '<b>Prawa za wužiwarja „$1” zaktualizowane</b>',
+'usercssjsyoucanpreview'=> '<strong>Pokiw:</strong> Wužijće tłóčku \'Přehlad pokazać\', zo byšće swój nowy CSS/JS do składowanja testował(a).',
+'usercsspreview' => '<b>Pomylsće sej, zo swój wužiwarski CSS jenož wobhladujeće, je hišće njeskładowany!</b>',
+'userexists' => 'Wužiwarske mjeno, kotrež sće zapisał, so hižo wužiwa. Prošu wubjerće druhe mjeno.',
+'userinvalidcssjstitle' => '<b>Kedźbu:</b> Skin z mjenom "$1" njeeksistuje. Prošu mysliće na to, zo dyrbja wosobinske .css a .js strony z małym pismikom započeć, na př. User:Foo/monobook.css město User:Foo/Monobook.css.',
+'userjspreview' => '<b>Pomylsće sej, zo swój wužiwarski JavaScript jenož testujeće/wobhladujeće, je hišće njeskładowany!</b>',
+'userlogin' => 'Załožće konto abo přizjewće so',
+'userlogout' => 'Wotzjewić',
+'usermailererror' => 'Emailowy objekt wróći zmylk:',
+'username' => 'Wužiwarske mjeno:',
+'userpage' => 'Wužiwarsku stronu pokazać',
+'userrights' => 'Zrjadowanje wužiwarskich prawow',
+'userrights-editusergroup'=> 'Wužiwarske skupiny wobdźěłać',
+'userrights-groupsavailable'=> 'K dispoziciji stejace skupiny:',
+'userrights-groupshelp' => 'Wubjerće skupiny, z kotrychž chceće wužiwarja wotstronić abo do kotrychž chceće wužiwarja přidać. Njewubrane skupiny so njezměnja. Móžeće wubranje za skupinu zběhnyć wužiwajo STRG + Lěwe kliknjenje',
+'userrights-groupsmember'=> 'Sobustaw skupiny:',
+'userrights-lookup-user'=> 'Wužiwarske skupiny zrjadować',
+'userrights-user-editname'=> 'Wužiwarske mjeno:',
+'userstats' => 'Statistika wužiwarjow',
+'userstatstext' => 'Je <b>$1</b> [[Special:Listusers|wužiwarjow]] zregistrowanych, <b>$2</b> (abo <b>$4%</b>) z nich su $5.',
+'version' => 'Wersija',
+'versionrequired' => 'Wersija $1 softwary MediaWiki trěbna',
+'versionrequiredtext' => 'Wersija $1 softwary MediaWiki je trěbna, zo by so tuta strona wužiwać móhła. Hlej [[Special:Version]]',
+'viewcount' => 'Tuta strona bu $1 króć pokazana.',
+'viewdeleted' => '$1 pokazać?',
+'viewdeletedpage' => 'Wušmórnjene strony wobhladać',
+'viewhelppage' => 'Pomocnu stronu pokazać',
+'viewpagelogs' => 'Protokole zu tutu stronu pokazać',
+'viewprevnext' => '($1) ($2) ($3) wobhladać.',
+'views' => 'Pohlady',
+'viewsource' => 'Žórło wobhladać',
+'viewsourcefor' => 'za $1',
+'viewtalkpage' => 'Diskusiju pokazać',
+'wantedcategories' => 'Požadane kategorije',
+'wantedpages' => 'Požadane strony',
+'watch' => 'Wobkedźbować',
+'watchdetails' => '* $1 wobkedźbowanych stron nimo diskusijnych stron
+* [[Special:Watchlist/edit|Wobkedźbowanki pokazać a wobdźěłać]]
+* [[Special:Watchlist/clear|Wobkedźbowanki wuprózdnić]]',
+'watcheditlist' => 'Deleka je alfabetiska lisćina Wašich wobkedźbowanych stron.
+
+Markěrujće kašćiki stron, kotrež chceće ze swojich wobkedźbowankow wotstronić. Wotstronjenje wobsahoweje strony tež přisłušnu diskusijnu stronu wotstronja a nawopak.',
+'watchlist' => 'Wobkedźbowanki',
+'watchlistall1' => 'wšě',
+'watchlistall2' => 'wšě',
+'watchlistanontext' => 'Dyrbiće so $1, zo byšće swoje wobkedźbowanki wobhladać abo wobdźěłać móhł(a).',
+'watchlistclearbutton' => 'Wobkedźbowanki wuprózdnić',
+'watchlistcleardone' => 'Waše wobkedźbowanki z dohromady {{PLURAL:$1|jednej stronu|$1 stronami}} buchu wuprózdnjene.',
+'watchlistcleartext' => 'Sće sej wěsty(a), zo chceće swoje wobkedźbowanki wuprózdnić?',
+'watchlistcontains' => 'Maće $1 stron w swojich wobkedźbowankach.',
+'watchlistcount' => '<b>Maće {{PLURAL:$1|1 stronu|$1 stron}} we wobkedźbowankach hromadu z přisłušnymi diskusijnymi stronami.</b>',
+'watchlistfor' => '(za wužiwarja <b>$1</b>)',
+'watchmethod-list' => 'Wobkedźbowanki za aktualnymi změnami přepruwować',
+'watchmethod-recent' => 'Aktualne změny za wobkedźbowane strony přepruwować',
+'watchnochange' => 'Žana z Wašich wobkedźbowanych stron njebu w pokazowanej dobje wobdźěłowana.',
+'watchnologin' => 'Njejsće přizjewjeny(a).',
+'watchnologintext' => 'Dyrbiće [[Special:Userlogin|přizjewjeny(a)]] być, zo byšće swoje wobkedźbowanki změnić móhł(a).',
+'watchthis' => 'Tutu stronu wobkedźbować',
+'watchthispage' => 'Stronu wobkedźbować',
+'watchthisupload' => 'Stronu wobkedźbować',
+'wed' => 'Srj',
+'wednesday' => 'Srjeda',
+'welcomecreation' => '== Witajće, $1! ==
+
+Waše konto bu připrawjene. Njezabudźće, swoje nastajenja za {{GRAMMAR:akuzatiw|{{SITENAME}}}} změnić.',
+'whatlinkshere' => 'Što pokazuje sem',
+'whitelistacctext' => 'Zo byšće směł(a) konta w tutym wiki załožić, dyrbiće so [[Special:Userlogin|tu přizjewić]] a trěbne dowolenja měć.',
+'whitelistacctitle' => 'Njesměće konto załožować',
+'whitelistedittext' => 'Dyrbiće so $1, zo byšće strony wobdźěłować móhł(a).',
+'whitelistedittitle' => 'Přizjewjenje za wobdźěłanje trěbne',
+'whitelistreadtext' => 'Dyrbiće so [[Special:Userlogin|tu přizjewić]], zo byšće strony čitać móhł(a).',
+'whitelistreadtitle' => 'Přizjewjenje za čitanje trěbne',
+'wldone' => 'Akcija bu wuspěšnje wuwjedźena.',
+'wlheader-enotif' => '* Emailowe zdźělenje je zmóžnjene.',
+'wlheader-showupdated' => '* Strony, kotrež buchu po Wašim poslednim wopyće změnjene so <b>tučne</b> jewja.',
+'wlhideshowbots' => 'změny awtomatiskich programow (botow) $1',
+'wlhideshowown' => 'moje změny $1',
+'wlnote' => 'Deleka je poslednje $1 změnow za poslednje <b>$2</b> hodź.',
+'wlsaved' => 'To je składowana wersija Wašich wobkedźbowankow.',
+'wlshowlast' => 'Poslednje $1 hodź. - $2 dnjow - $3 pokazać',
+'wrong_wfQuery_params' => 'Njeprawe parametry za wfQuery()
+
+Funkcija: $1
+
+Wotprašenje: $2',
+'wrongpassword' => 'Hesło, kotrež sće zapisał(a), je wopak (abo pobrachuje). Prošu spytajće hišće raz.',
+'wrongpasswordempty' => 'Hesło, kotrež sće zapisał(a), běše prózdne. Prošu spytajće hišće raz.',
+'youhavenewmessages' => 'Maće $1 ($2).',
+'youhavenewmessagesmulti'=> 'Maće nowe powěsće: $1',
+'yourdiff' => 'Rozdźěle',
+'yourdomainname' => 'Waša domena',
+'youremail' => 'Email *',
+'yourlanguage' => 'Rěč:',
+'yourname' => 'Wužiwarske mjeno',
+'yournick' => 'Přimjeno:',
+'yourpassword' => 'Hesło',
+'yourpasswordagain' => 'Hesło znowa zapodać',
+'yourrealname' => 'Woprawdźite mjeno *',
+'yourtext' => 'Waš tekst',
+'yourvariant' => 'Warianta',
+
+);
+
+?>
diff --git a/languages/messages/MessagesHu.php b/languages/messages/MessagesHu.php
new file mode 100644
index 000000000000..628395b0d732
--- /dev/null
+++ b/languages/messages/MessagesHu.php
@@ -0,0 +1,1053 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+#
+# Hungarian localisation for MediaWiki
+#
+
+
+$namespaceNames = array(
+ NS_MEDIA => "Média",
+ NS_SPECIAL => "Speciális",
+ NS_MAIN => "",
+ NS_TALK => "Vita",
+ NS_USER => "User",
+ NS_USER_TALK => "User_vita",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => "$1_vita",
+ NS_IMAGE => "Kép",
+ NS_IMAGE_TALK => "Kép_vita",
+ NS_MEDIAWIKI => "MediaWiki",
+ NS_MEDIAWIKI_TALK => "MediaWiki_vita",
+ NS_TEMPLATE => "Sablon",
+ NS_TEMPLATE_TALK => "Sablon_vita",
+ NS_HELP => "Segítség",
+ NS_HELP_TALK => "Segítség_vita",
+ NS_CATEGORY => "Kategória",
+ NS_CATEGORY_TALK => "Kategória_vita"
+);
+
+
+$quickbarSettings = array(
+ "Nincs", "Fix baloldali", "Fix jobboldali", "Lebegő baloldali"
+);
+
+$skinNames = array(
+ 'standard' => "Alap",
+ 'nostalgia' => "Nosztalgia",
+ 'cologneblue' => "Kölni kék"
+);
+
+$fallback8bitEncoding = "iso8859-2";
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+
+$datePreferences = false;
+$defaultDateFormat = 'ymd';
+$dateFormats = array(
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y. F j.',
+ 'ymd both' => 'Y. F j., H:i',
+);
+
+$linkTrail = '/^([a-záéíóúöüőűÁÉÍÓÚÖÜŐŰ]+)(.*)$/sDu';
+
+$messages = array(
+'tog-underline' => 'Linkek aláhúzása:',
+'tog-highlightbroken' => 'Törött linkek <a href="" class="new">így</a> (alternatíva: így<a href="" class="internal">?</a>).',
+'tog-justify' => 'Bekezdések teljes szélességű tördelése („sorkizárás”)',
+'tog-hideminor' => 'Apró változtatások elrejtése a Friss változtatások lapon',
+'tog-extendwatchlist' => 'A figyelőlista kiterjesztése minden változtatásra (ne csak az utolsót mutassa)',
+'tog-usenewrc' => 'Modern változások listája (nem minden böngészőre)',
+'tog-numberheadings' => 'Címsorok automatikus számozása',
+'tog-showtoolbar' => 'Szerkesztőeszköz–sor látható',
+'tog-editondblclick' => 'Lapon duplakattintásra szerkesztés (JavaScript)',
+'tog-editsection' => 'Linkek az egyes szakaszok szerkesztéséhez',
+'tog-editsectiononrightclick'=> 'Egyes szakaszok szerkesztése a szakaszcímre klikkeléssel (Javascript)',
+'tog-showtoc' => 'Három fejezetnél többel rendelkező cikkeknél mutasson tartalomjegyzéket',
+'tog-rememberpassword' => 'Jelszó megjegyzése a használatok között',
+'tog-editwidth' => 'Teljes szélességű szerkesztőterület',
+'tog-watchcreations' => 'Általad létrehozott lapok felvétele a figyelőlistádra',
+'tog-watchdefault' => 'Szerkesztett cikkek felvétele a figyelőlistára',
+'tog-minordefault' => 'Alapból minden szerkesztést jelöljön aprónak',
+'tog-previewontop' => 'Előnézet a szerkesztőterület előtt és nem utána',
+'tog-previewonfirst' => 'Előnézet első szerkesztésnél',
+'tog-nocache' => 'Lapok gyorstárazásának letiltása',
+'tog-fancysig' => 'Aláírás automatikus hivatkozás nélkül',
+'tog-externaleditor' => 'Külső szerkesztőprogram alapértelmezett',
+'tog-externaldiff' => 'Külső különbségképző (diff) program használata',
+'tog-showjumplinks' => 'Helyezzen el linket („Ugrás”) a beépített eszköztárra',
+'tog-autopatrol' => 'Saját szerkesztések jelölése ellenőrzöttként',
+'tog-forceeditsummary' => 'Figyelmeztessen, ha nem adok meg szerkesztési összefoglalót',
+'tog-watchlisthideown' => 'Saját szerkesztések elrejtése',
+'tog-watchlisthidebots' => 'Robotok szerkesztéseinek elrejtése',
+'underline-always' => 'Mindig',
+'underline-never' => 'Soha',
+'underline-default' => 'A böngésző alapértelmezése szerint',
+'skinpreview' => '(előnézet)',
+'sunday' => 'vasárnap',
+'monday' => 'hétfő',
+'tuesday' => 'kedd',
+'wednesday' => 'szerda',
+'thursday' => 'csütörtök',
+'friday' => 'péntek',
+'saturday' => 'szombat',
+'january' => 'január',
+'february' => 'február',
+'march' => 'március',
+'april' => 'április',
+'may_long' => 'május',
+'june' => 'június',
+'july' => 'július',
+'august' => 'augusztus',
+'september' => 'szeptember',
+'october' => 'október',
+'november' => 'november',
+'december' => 'december',
+'mar' => 'Már',
+'apr' => 'ápr',
+'may' => 'Máj',
+'jun' => 'Jún',
+'jul' => 'Júl',
+'aug' => 'aug',
+'oct' => 'Okt',
+'categories' => 'Kategóriák',
+'pagecategories' => '{{PLURAL:$1|Kategória|Kategóriák}}',
+'category_header' => '„$1” kategóriába tartozó szócikkek',
+'subcategories' => 'Alkategóriák',
+'mainpage' => 'Kezdőlap',
+'mainpagetext' => 'Wiki szoftver sikeresen telepítve.',
+'portal' => 'Közösségi portál',
+'about' => 'Névjegy',
+'aboutsite' => 'A {{grammar:rol|{{SITENAME}}}}',
+'aboutpage' => 'Project:Névjegy',
+'article' => 'Szócikk',
+'help' => 'Segítség',
+'helppage' => 'Segítség:Tartalom',
+'bugreports' => 'Hibajelentés',
+'bugreportspage' => 'Project:Hibajelentések',
+'sitesupport' => 'Adományok',
+'faq' => 'GyIK',
+'faqpage' => 'Project:GyIK',
+'edithelp' => 'Segítség a szerkesztéshez',
+'newwindow' => '(új ablakban nyílik meg)',
+'edithelppage' => 'Help:Hogyan szerkessz egy lapot',
+'cancel' => 'Vissza',
+'qbfind' => 'Keresés',
+'qbbrowse' => 'Böngészés',
+'qbedit' => 'Szerkeszt',
+'qbpageoptions' => 'Lapbeállítások',
+'qbpageinfo' => 'Lapinformáció',
+'qbmyoptions' => 'Beállításaim',
+'qbspecialpages' => 'Speciális lapok',
+'moredotdotdot' => 'Tovább...',
+'mypage' => 'Lapom',
+'mytalk' => 'Vitám',
+'anontalk' => 'Vitalap ehhez az IP-hez',
+'navigation' => 'Navigáció',
+'currentevents' => 'Friss események',
+'disclaimers' => 'Jogi nyilatkozat',
+'privacy' => 'Adatvédelmi irányelvek',
+'privacypage' => 'Project:Adatvédelmi irányelvek',
+'errorpagetitle' => 'Hiba',
+'returnto' => 'Vissza a $1 cikkhez.',
+'tagline' => 'A {{SITENAME}}BÓL',
+'search' => 'Keresés',
+'searchbutton' => 'Keresés',
+'go' => 'Menj',
+'searcharticle' => 'Menj',
+'history' => 'laptörténet',
+'history_short' => 'Laptörténet',
+'printableversion' => 'Nyomtatható változat',
+'permalink' => 'Link erre a változatra',
+'edit' => 'Szerkeszt',
+'editthispage' => 'Szerkeszd ezt a lapot',
+'delete' => 'Törlés',
+'deletethispage' => 'Lap törlése',
+'undelete_short' => '{{PLURAL:$1|Egy|$1}} törölt szerkesztés helyreállítása',
+'protect' => 'Lapvédelem',
+'protectthispage' => 'Védelem a lapnak',
+'unprotect' => 'Védelem ki',
+'unprotectthispage' => 'Védelem megszüntetése',
+'newpage' => 'Új lap',
+'talkpage' => 'Lap megbeszélése',
+'specialpage' => 'Speciális Lap',
+'personaltools' => 'Személyes eszközök',
+'postcomment' => 'Üzenethagyás',
+'articlepage' => 'Szócikk megtekintése',
+'talk' => 'Vitalap',
+'toolbox' => 'Eszközök',
+'userpage' => 'Felhasználói lap',
+'projectpage' => 'Projekt lap megtekintése',
+'imagepage' => 'Képlap',
+'viewtalkpage' => 'Beszélgetés megtekintése',
+'otherlanguages' => 'Más nyelveken',
+'redirectedfrom' => '($1 szócikkből átirányítva)',
+'autoredircomment' => 'Átirányítás ide: [[$1]]',
+'lastmodifiedat' => 'A lap utolsó módosítása $2, $1.',
+'viewcount' => 'Ezt a lapot eddig {{PLURAL:$1|egy|$1}} alkalommal látogatták meg.',
+'copyright' => 'A tartalom a $1 feltételei mellett használható.',
+'protectedpage' => 'Védett lap',
+'jumpto' => 'Ugrás:',
+'jumptonavigation' => 'navigáció',
+'jumptosearch' => 'keresés',
+'retrievedfrom' => 'A lap eredeti címe "$1"',
+'youhavenewmessages' => '$1 van. ($2)',
+'newmessageslink' => 'Új üzeneted',
+'newmessagesdifflink' => 'eltérés az előző változattól',
+'editsection' => 'szerkesztés',
+'editold' => 'szerkesztés',
+'editsectionhint' => 'Szakasz szerkesztése: $1',
+'toc' => 'Tartalomjegyzék',
+'showtoc' => 'mutat',
+'hidetoc' => 'elrejt',
+'thisisdeleted' => '$1 megnézése vagy helyreállítása?',
+'restorelink' => '{{PLURAL:$1|egy|$1}} törölt szerkesztés',
+'nstab-main' => 'Szócikk',
+'nstab-user' => 'User lap',
+'nstab-media' => 'Média',
+'nstab-special' => 'Speciális',
+'nstab-project' => 'Projekt lap',
+'nstab-image' => 'Kép',
+'nstab-mediawiki' => 'Üzenet',
+'nstab-template' => 'Sablon',
+'nstab-help' => 'Segítség',
+'nstab-category' => 'Kategória',
+'nosuchaction' => 'Nincs ilyen tevékenység',
+'nosuchactiontext' => 'Az URL által megadott tevékenységet a {{SITENAME}}
+software nem ismeri fel',
+'nosuchspecialpage' => 'Nincs ilyen speciális lap',
+'nospecialpagetext' => 'Olyan speciális lapot kértél amit a {{SITENAME}}
+software nem ismer fel.',
+'error' => 'Hiba',
+'databaseerror' => 'Adatbázis hiba',
+'dberrortext' => 'Adatbázis formai hiba történt.
+Az utolsó lekérési próbálkozás az alábbi volt:
+<blockquote><tt>$1</tt></blockquote>
+a "<tt>$2</tt>" függvényből.
+A MySQL hiba "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Egy adatbázis lekérés formai hiba történt.
+Az utolsó lekérési próbálkozás:
+"$1"
+a "$2" függvényből történt.
+A MySQL hiba "$3: $4".',
+'noconnect' => 'Nem tudok az adatbázisszerverre csatlakozni.
+<br />
+$1',
+'nodb' => 'Nem tudom elérni a $1 adatbázist',
+'cachederror' => 'Ez a kért cikk egy régebben elmentett példánya, lehetséges, hogy nem tartalmazza a legújabb módosításokat.',
+'laggedslavemode' => 'Figyelem: Ez a lap nem feltétlenül tartalmazza a legfrissebb változtatásokat!',
+'readonly' => 'Adatbázis lezárva',
+'enterlockreason' => 'Add meg a lezárás indoklását valamint egy becslést,
+hogy mikor kerül a lezárás feloldásra',
+'readonlytext' => 'Az adatbázis jelenleg le van zárva az új szócikkek és módosítások elől, valószínűleg adatbázis karbantartás miatt, aminek a végén minden visszaáll a régi kerékvágásba.
+
+Az adminisztrátor aki a lezárást elvégezte az alábbi magyarázatot adta: $1',
+'missingarticle' => 'Az adatbázis nem találta meg egy létező lap szövegét,
+aminek a neve "$1".
+
+Ennek oka általában egy olyan régi link kiválasztása, ami egy
+már törölt lap történetére hivatkozik.
+
+Ha nem erről van szó akkor lehetséges, hogy programozási hibát
+találtál a software-ben. Kérlek értesíts erről egy adminisztrátort,
+és jegyezd fel neki az URL-t (pontos webcímet) is.',
+'internalerror' => 'Belső hiba',
+'filecopyerror' => 'Nem tudom a "$1" file-t a "$2" névre másolni.',
+'filerenameerror' => 'Nem tudom a "$1" file-t "$2" névre átnevezni.',
+'filedeleteerror' => 'Nem tudom a "$1" file-t letörölni.',
+'filenotfound' => 'Nem találom a "$1" file-t.',
+'unexpected' => 'Váratlan érték: "$1"="$2".',
+'formerror' => 'Hiba: nem tudom a formot elküldeni',
+'badarticleerror' => 'Ez a tevékenység nem végezhető ezen a lapon.',
+'cannotdelete' => 'Nem lehet a megadott lapot vagy képet törölni (talán már valaki más törölte).',
+'badtitle' => 'Hibás cím',
+'badtitletext' => 'A kért cím helytelen, üres vagy hibásan hivatkozik
+egy nyelvek közötti vagy wikik közötti címre.',
+'perfdisabled' => 'Elnézést, de ez a lehetőség átmenetileg nem elérhető, mert annyira lelassítja az adatbázist, hogy senki nem tudja a wikit használni.',
+'perfdisabledsub' => 'Íme $1 egy elmentett másolata:',
+'perfcached' => 'Az alábbi adatok gyorsítótárból (\'\'cache\'\'-ből) származnak, és ezért lehetséges, hogy nem a legfrissebb változatot mutatják:',
+'perfcachedts' => 'Az alábbi adatok gyorsítótárból (\'\'cache\'\'-ből) származnak, legutóbbi frissítésük ideje $1.',
+'viewsource' => 'Lapforrás',
+'logouttitle' => 'Kilépés',
+'logouttext' => 'Kiléptél.
+Folytathatod a {{SITENAME}} használatát név nélkül, vagy beléphetsz
+újra vagy másik felhasználóként.',
+'welcomecreation' => '== Üdvözöllek, $1! ==
+
+A felhasználói környezeted létrehoztuk.
+Ne felejtsd el átnézni a személyes {{SITENAME}} beállításaidat.',
+'loginpagetitle' => 'Belépés',
+'yourname' => 'A felhasználói neved',
+'yourpassword' => 'Jelszavad',
+'yourpasswordagain' => 'Jelszavad ismét',
+'remembermypassword' => 'Jelszó megjegyzése a használatok között.',
+'loginproblem' => '<b>Valami probléma van a belépéseddel.</b><br />Kérlek, próbáld ismét!',
+'alreadyloggedin' => '<strong>Kedves $1, már be vagy lépve!</strong><br />',
+'login' => 'Belépés',
+'loginprompt' => 'Engedélyezned kell a cookie-kat, hogy bejelentkezhess a {{grammar:ba|{{SITENAME}}}}.',
+'userlogin' => 'Belépés',
+'logout' => 'Kilépés',
+'userlogout' => 'Kilépés',
+'notloggedin' => 'Nincs belépve',
+'nologin' => 'Nincsen még felhasználói neved? $1.',
+'nologinlink' => 'Itt regisztrálhatsz',
+'createaccount' => 'Új felhasználó készítése',
+'gotaccount' => 'Ha már korábban regisztráltál, $1!',
+'gotaccountlink' => 'jelentkezz be',
+'createaccountmail' => 'eMail alapján',
+'badretype' => 'A két jelszó eltér egymástól.',
+'userexists' => 'A megadott felhasználói név már foglalt. Kérlek, válassz másikat!',
+'youremail' => 'Az emailed*:',
+'username' => 'Felhasználói név:',
+'uid' => 'Azonosító:',
+'yourrealname' => 'Valódi neved*',
+'yourlanguage' => 'A felület nyelve:',
+'yournick' => 'A beceneved (aláírásokhoz):',
+'loginerror' => 'Belépési hiba.',
+'prefs-help-email' => '² E-mail cím (nem kötelező megadni): Lehetővé teszi, hogy más szerkesztők kapcsolatba lépjenek veled a felhasználói vagy vitalapodon keresztül, anélkül, hogy névtelenséged feladnád.',
+'nocookiesnew' => 'A felhasználói azonosító létrejött, de nem léptél be. A(z) {{SITENAME}} cookie-kat ("sütiket") használ a felhasználók azonosítására, és te ezeket letiltottad. Kérünk, hogy engedélyezd a cookie-kat, majd lépj be azonosítóddal és jelszavaddal.',
+'nocookieslogin' => 'A(z) {{SITENAME}} cookie-kat ("sütiket") használ az azonosításhoz, de te ezeket letiltottad. Engedélyezd őket, majd próbálkozz ismét.',
+'noname' => 'Nem adtál meg érvényes felhasználói nevet.',
+'loginsuccesstitle' => 'Sikeres belépés',
+'loginsuccess' => 'Beléptél a {{grammar:ba|{{SITENAME}}}} "$1"-ként.',
+'nosuchuser' => 'Nincs olyan felhasználó hogy "$1".
+Ellenőrizd a gépelést, vagy készíts új nevet a fent látható űrlappal.',
+'wrongpassword' => 'A megadott jelszó helytelen.',
+'mailmypassword' => 'Küldd el nekem a jelszavamat emailben',
+'passwordremindertitle' => '{{SITENAME}} jelszó emlékeztető',
+'passwordremindertext' => 'Valaki (vélhetően te, a $1 IP-címről)
+azt kérte, hogy küldjünk neked új {{SITENAME}} ($4) jelszót.
+A "$2" felhasználó jelszava most "$3".
+Lépj be, és változtasd meg a jelszavad.
+
+Ha nem kértél új jelszót, vagy közben eszedbe jutott a régi,
+és már nem akarod megváltoztatni, nyugodtan figyelmen kívül
+hagyhatod ezt az értesítést, és használhatod tovább a régi jelszavadat.',
+'noemail' => 'Nincs a "$1" felhasználóhoz email felvéve.',
+'passwordsent' => 'Az új jelszót elküldtük "$1" email címére.
+Lépj be a levélben található adatokkal.',
+'acct_creation_throttle_hit'=> 'Már létrehoztál $1 azonosítót. Sajnáljuk, de többet nem hozhatsz létre.',
+'emailauthenticated' => 'Az e-mail címedet megerősítetted $1-kor.',
+'emailnotauthenticated' => 'Az e-mail címed még nincs megerősítve. E-mailek küldése és fogadása nem engedélyezett.',
+'emailconfirmlink' => 'Erősítsd meg az e-mail címedet',
+'accountcreated' => 'Azonosító létrehozva',
+'accountcreatedtext' => '$1 felhasználói azonosítója sikeresen létrejött.',
+'bold_tip' => 'Félkövér szöveg',
+'math_sample' => 'TeX-képlet ide',
+'hr_tip' => 'Vízszintes vonal (módjával használd)',
+'summary' => 'Összefoglaló',
+'subject' => 'Téma/főcím',
+'minoredit' => 'Ez egy apró változtatás',
+'watchthis' => 'Figyeld a szócikket',
+'savearticle' => 'Lap mentése',
+'preview' => 'Előnézet',
+'showpreview' => 'Előnézet megtekintése',
+'showdiff' => 'Változtatások megtekintése',
+'anoneditwarning' => 'Nem vagy bejelentkezve. Az IP címed látható 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.',
+'blockedtitle' => 'A felhasználó fel van függesztve',
+'blockedtext' => '$1 blokkolta a felhasználónevedet vagy az IP-címedet.
+Az általa adott indoklás:<br />\'\'$2\'\'<br />Felveheted a kapcsolatot vele vagy egy másik
+[[Project:Adminisztrátorok|adminisztrátorral]], hogy megvitasd a blokkolást.
+
+Ügyelj arra, hogy az „e-mail küldése ezen felhasználónak” funkció csak akkor működik, ha megadtál egy érvényes e-mail címet a [[Special:Preferences|beállításaidnál]].
+
+Az IP címed $3. Ha kapcsolatba lépsz az adminisztrátorokkal, ne felejtsd el megadni.',
+'whitelistedittitle' => 'A szerkesztéshez be kell lépned',
+'whitelistedittext' => 'A szócikkek szerkesztéséhez $1.',
+'whitelistreadtitle' => 'Az olvasáshoz be kell lépned',
+'whitelistreadtext' => '[[Special:Userlogin|Be kell lépned]] ahhoz, hogy cikkeket tudj olvasni.',
+'whitelistacctitle' => 'Nem készíthetsz új bejelentkezési kódot',
+'whitelistacctext' => 'Ahhoz, hogy ezen a Wikin új nevet regisztrálj [[Special:Userlogin|be kell lépned]] a szükséges engedélyszinttel.',
+'accmailtitle' => 'Jelszó elküldve.',
+'accmailtext' => '„$1” jelszavát elküldtük $2 címre.',
+'newarticle' => '(Új)',
+'newarticletext' => 'Egy olyan lapra jutottál ami még nem létezik.
+A lap létrehozásához kezdd el írni a szövegét lenti keretbe
+(a [[Help:Segítség|segítség]] lapon lelsz további
+információkat).
+Ha tévedésből jöttél ide, csak nyomd meg a böngésző \'\'\'Vissza/Back\'\'\'
+gombját.',
+'anontalkpagetext' => '---- \'\'Ez egy olyan anonim felhasználó vitalapja, aki még nem készített magának nevet vagy azt nem használta. Ezért az [[IP-cím]]ét használjuk az azonosítására. Az IP számokon számos felhasználó osztozhat az idők folyamán. Ha anonim felhasználó vagy és úgy érzed, hogy értelmetlen megjegyzéseket írnak neked akkor [[Special:Userlogin|készíts magadnak egy nevet vagy lépj be]] hogy megakadályozd más anonim felhasználókkal való keveredést.\'\'',
+'noarticletext' => '(Ez a lap jelenleg nem tartalmaz szöveget)',
+'clearyourcache' => '\'\'\'Megjegyzés:\'\'\' A beállítások elmentése után frissítened kell a böngésződ gyorsítótárát, hogy a változások érvénybe lépjenek. \'\'\'Mozilla\'\'\' / \'\'\'Firefox\'\'\' / \'\'\'Safari:\'\'\' tartsd lenyomva a Shift gombot és kattints a \'\'Reload\'\' / \'\'Frissítés\'\' gombra az eszköztáron, vagy használd a \'\'Ctrl–F5\'\' billentyűkombinációt (Apple Mac-en \'\'Cmd–Shift–R\'\'); \'\'\'Internet Explorer:\'\'\' tartsd nyomva a \'\'Ctrl\'\'-t, és kattints a \'\'Reload\'\' / \'\'Frissítés\'\' gombra, vagy nyomj \'\'Ctrl–F5\'\'-öt; \'\'\'Konqueror:\'\'\' egyszerűen csak kattints a \'\'Reload\'\' / \'\'Frissítés\'\' gombra (vagy \'\'Ctrl–R\'\' vagy \'\'F5\'\'); \'\'\'Opera\'\'\' felhasználóknak teljesen ki kell üríteniük a gyorsítótárat a \'\'Tools→Preferences\'\' menüben.',
+'usercssjsyoucanpreview'=> '<strong>Tipp:</strong> Használd az "Előnézet megtekintése" gombot az új css/js teszteléséhez mentés előtt.',
+'usercsspreview' => '\'\'\'Ne felejtsd el, hogy ez csak a css előnézete és még nincs elmentve!\'\'\'',
+'userjspreview' => '\'\'\'Ne felejtsd el hogy még csak teszteled a felhasználói javascriptedet és az még nincs elmentve!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Figyelem:\'\'\' Nincs „$1” nevű felület. Lehet, hogy nagy kezdőbetűt használtál olyan helyen, ahol nem kellene? A felületekhez tartozó .css/.js oldalak kisbetűvel kezdődnek. (Például \'\'User:Gipsz Jakab/monobook.css\'\' és nem \'\'User:Gipsz Jakab/Monobook.css\'\'.)',
+'updated' => '(Frissítve)',
+'note' => '<strong>Megjegyzés:</strong>',
+'previewnote' => 'Ne felejtsd el, hogy ez csak egy előnézet, és nincs elmentve!',
+'session_fail_preview' => '<strong>Sajnos nem tudtuk feldolgozni a szerkesztésedet, mert elveszett a session adat. Kérjük próbálkozz újra! Amennyiben továbbra sem sikerül próbálj meg kijelentkezni, majd ismét bejelentkezni!</strong>',
+'previewconflict' => 'Ez az előnézet a felső szerkesztőablakban levő
+szövegnek megfelelő képet mutatja, ahogy az elmentés után kinézne.',
+'editing' => '$1 szerkesztés alatt',
+'editinguser' => '$1 szerkesztés alatt',
+'editingsection' => '$1 szerkesztés alatt (szakasz)',
+'editingcomment' => '$1 szerkesztés alatt (üzenet)',
+'editconflict' => 'Szerkesztési ütközés: $1',
+'explainconflict' => 'Valaki megváltoztatta a lapot azóta,
+mióta szerkeszteni kezdted.
+A felső szövegablak tartalmazza a szöveget, ahogy az jelenleg létezik.
+A módosításaid az alsó ablakban láthatóak.
+Át kell vezetned a módosításaidat a felső szövegbe.
+<b>Csak</b> a felső ablakban levő szöveg kerül elmentésre akkor, mikor
+a "Lap mentését" választod.<br />',
+'yourtext' => 'A te szöveged',
+'storedversion' => 'A tárolt változat',
+'editingold' => '<strong>VIGYÁZAT! A lap egy elavult
+változatát szerkeszted.
+Ha elmented, akkor az ezen változat után végzett összes
+módosítás elvész.</strong>',
+'yourdiff' => 'Eltérések',
+'longpagewarning' => '<strong>FIGYELEM: Ez a lap $1 kilobyte hosszú;
+néhány böngészőnek problémái vannak a 32KB körüli vagy nagyobb lapok
+szerkesztésével.
+Fontold meg a lap kisebb szakaszokra bontását.</strong>',
+'readonlywarning' => '<strong>FIGYELEM: Az adatbázis karbantartás miatt le van zárva,
+ezért a módosításaidat most nem lehetséges elmenteni. Érdemes a szöveget
+kimásolni és elmenteni egy szövegszerkesztőben a későbbi mentéshez.</strong>',
+'protectedpagewarning' => '<strong>FIGYELEM: A lap lezárásra került és ilyenkor
+csak a Sysop jogú adminisztrátorok tudják szerkeszteni. Ellenőrizd, hogy
+betartod a [[Project:Zárt_lapok_irányelve|zárt lapok irányelvét]].</strong>',
+'templatesused' => 'Sablonok ezen a lapon:',
+'revhistory' => 'Változások története',
+'nohistory' => 'Nincs szerkesztési történet ehhez a laphoz.',
+'revnotfound' => 'A változat nem található',
+'revnotfoundtext' => 'A lap általad kért régi változatát nem találom. Kérlek, ellenőrizd az URL-t, amivel erre a lapra jutottál.',
+'loadhist' => 'Laptörténet beolvasása',
+'currentrev' => 'Aktuális változat',
+'revisionasof' => '$1 változat',
+'previousrevision' => '←Régebbi változat',
+'nextrevision' => 'Újabb változat→',
+'currentrevisionlink' => 'legfrissebb változat',
+'cur' => 'akt',
+'next' => 'köv',
+'last' => 'előző',
+'orig' => 'eredeti',
+'histlegend' => 'Jelmagyarázat: (akt) = eltérés az aktuális változattól,
+(előző) = eltérés az előző változattól,
+A = Apró változtatás',
+'histfirst' => 'legkorábbi',
+'histlast' => 'legutolsó',
+'difference' => '(Változatok közti eltérés)',
+'loadingrev' => 'különbségképzéshez olvasom a változatokat',
+'lineno' => '$1. sor:',
+'editcurrent' => 'A lap aktuális változatának szerkesztése',
+'compareselectedversions'=> 'Kiválasztott változatok összehasonlítása',
+'searchresults' => 'A keresés eredménye',
+'searchresulttext' => 'További információkkal a keresésről a [[Project:Keresés|Keresés]] szolgál.',
+'searchsubtitle' => 'Erre kerestél: „[[:$1]]”',
+'searchsubtitleinvalid' => 'A "$1" kereséshez',
+'badquery' => 'Hibás formájú keresés',
+'badquerytext' => 'Nem tudjuk a kérésedet végrehajtani. Ennek oka valószínűleg az, hogy három betűnél rövidebb karaktersorozatra próbáltál keresni, ami jelenleg nem lehetséges. Lehet az is, hogy elgépelted a kifejezést, például „hal and and mérleg”. Kérlek, próbálj másik kifejezést keresni.',
+'matchtotals' => 'A "$1" keresés $2 címszót talált és
+$3 szócikk szövegét.',
+'noexactmatch' => '\'\'\'Nincs „$1” című lap.\'\'\' [[:$1|Létrehozhatsz egy új lapot]] ezen a néven.',
+'titlematches' => 'Címszó egyezik',
+'notitlematches' => 'Nincs egyező címszó',
+'textmatches' => 'Szócikk szövege egyezik',
+'notextmatches' => 'Nincs szócikk szöveg egyezés',
+'prevn' => 'előző $1',
+'nextn' => 'következő $1',
+'viewprevnext' => '($1) ($2) ($3)',
+'showingresults' => 'Lent látható <b>$1</b> találat, az eleje <b>$2</b>.',
+'showingresultsnum' => 'Lent látható <b>$3</b> találat, az eleje #<b>$2</b>.',
+'nonefound' => '<strong>Megyjegyzés</strong>: a sikertelen keresések
+gyakori oka olyan szavak keresése (pl. "have" és "from") amiket a
+rendszer nem indexel fel, vagy több független keresési szó szerepeltetése
+(csak minden megadott szót tartalmazó találatok jelennek meg a
+végeredményben).',
+'powersearch' => 'Keresés',
+'powersearchtext' => '
+Keresés a névterekben:<br />
+$1<br />
+$2 Átirányítások listája &nbsp; Keresés:$3 $9',
+'searchdisabled' => '<p>Elnézésed kérjük, de a teljes szöveges keresés terhelési okok miatt átmenetileg nem használható. Ezidő alatt használhatod a lenti Google keresést, mely viszont lehetséges, hogy nem teljesen friss adatokkal dolgozik.</p>',
+'blanknamespace' => '(Alap)',
+'preferences' => 'Beállításaim',
+'prefsnologin' => 'Nem vagy belépve',
+'prefsnologintext' => 'Ahhoz, hogy a
+beállításaidat rögzíthesd, [[Special:Belépés|be kell lépned]].',
+'prefsreset' => 'A beállítások törlődtek a tárolóból vett értékekre.',
+'qbsettings' => 'Gyorsmenü beállítások',
+'changepassword' => 'Jelszó változtatása',
+'skin' => 'Felület',
+'math' => 'Képletek',
+'dateformat' => 'Dátum formátuma',
+'datetime' => 'Dátum és idő',
+'math_failure' => 'Értelmezés sikertelen',
+'math_unknown_error' => 'ismertlen hiba',
+'math_unknown_function' => 'ismeretlen függvény',
+'math_syntax_error' => 'formai hiba',
+'math_image_error' => 'Sikertelen PNG-vé alakítás (szerver oldali hiba)',
+'prefs-personal' => 'Felhasználói adatok',
+'prefs-rc' => 'Friss változtatások',
+'prefs-watchlist' => 'Figyelőlista',
+'prefs-watchlist-days' => 'A figyelőlistában mutatott napok száma:',
+'prefs-watchlist-edits' => 'A kiterjesztett figyelőlistán mutatott szerkesztések száma:',
+'prefs-misc' => 'Egyéb',
+'saveprefs' => 'Beállítások mentése',
+'resetprefs' => 'Beállítások törlése',
+'oldpassword' => 'Régi jelszó:',
+'newpassword' => 'Új jelszó:',
+'retypenew' => 'Új jelszó ismét:',
+'textboxsize' => 'Szerkesztés',
+'rows' => 'Sor',
+'columns' => 'Oszlop',
+'searchresultshead' => 'Keresés',
+'resultsperpage' => 'Laponként mutatott találatok száma:',
+'contextlines' => 'Találatonként mutatott sorok száma:',
+'contextchars' => 'Soronkénti szövegkörnyezet (karakterszám):',
+'stubthreshold' => 'Csonkok kijelzésének küszöbértéke:',
+'recentchangescount' => 'Címszavak száma a friss változtatásokban:',
+'savedprefs' => 'A beállításaidat letároltam.',
+'timezonelegend' => 'Időzóna',
+'timezonetext' => 'Add meg az órák számát, amennyivel a helyi
+idő a GMT-től eltér (Magyarországon nyáron 2, télen 1).',
+'localtime' => 'Helyi idő:',
+'timezoneoffset' => 'Eltérés¹:',
+'servertime' => 'A szerver ideje:',
+'guesstimezone' => 'Töltse ki a böngésző',
+'allowemail' => 'E-mail engedélyezése más felhasználóktól',
+'defaultns' => 'Alapértelmezésben az alábbi névterekben keressünk:',
+'files' => 'Képek',
+'changes' => 'változtatás',
+'recentchanges' => 'Friss változtatások',
+'recentchangestext' => 'Ezen a lapon követheted a wikiben történt legutóbbi változtatásokat.',
+'rcnote' => 'Lentebb az utolsó <strong>$2</strong> nap utolsó <strong>$1</strong> változtatása látható. A lap generálásának időpontja $3.',
+'rcnotefrom' => 'Lentebb láthatóak a <b>$2</b> óta történt változások (<b>$1</b>-ig).',
+'rclistfrom' => 'Az új változtatások kijelzése $1 után',
+'rcshowhideminor' => 'apró módosítások $1',
+'rcshowhidebots' => 'robotok szerkesztéseinek $1',
+'rcshowhideliu' => 'bejelentkezett felhasználók szerkesztéseinek $1',
+'rcshowhideanons' => 'névtelen szerkesztések $1',
+'rcshowhidepatr' => 'ellenőrzött szerkesztések $1',
+'rcshowhidemine' => 'saját szerkesztések $1',
+'rclinks' => 'Az elmúlt $2 nap utolsó $1 változtatása legyen látható<br />$3',
+'diff' => 'eltér',
+'hist' => 'történet',
+'hide' => 'elrejtése',
+'show' => 'megjelenítése',
+'minoreditletter' => 'A',
+'newpageletter' => 'Ú',
+'upload' => 'Fájl felküldése',
+'uploadbtn' => 'Fájl felküldése',
+'reupload' => 'Újraküldés',
+'reuploaddesc' => 'Visszatérés a felküldési űrlaphoz.',
+'uploadnologin' => 'Nem jelentkeztél be',
+'uploadnologintext' => 'Ahhoz, hogy fájlokat tudj feltölteni, [[Special:Userlogin|be kell jelentkezned]].',
+'uploaderror' => 'Felküldési hiba',
+'uploadtext' => 'Az alábbi űrlappal küldhetsz fel új fájlt. A régebben felküldött képek megnézéséhez vagy kereséséhez nézd meg a [[Special:Imagelist|felküldött képek listáját]]. A felküldések és törlések naplója a [[Special:Log/upload|felküldési naplóban]] található.
+
+A képet a cikkbe az
+* \'\'\'<nowiki>[[{{ns:Image}}:File.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[{{ns:Image}}:File.png|leírás]]</nowiki>\'\'\'
+formában illesztehted be. Közvetlenül is hivatkozhatsz a fájlra
+* \'\'\'<nowiki>[[{{ns:Media}}:File.ogg]]</nowiki>\'\'\'
+formában.',
+'uploadlog' => 'felküldési napló',
+'uploadlogpage' => 'Felküldési_napló',
+'uploadlogpagetext' => 'Lentebb látható a legutóbbi felküldések listája.
+Minden időpont a server idejében (UTC) van megadva.
+<ul>
+</ul>',
+'filename' => 'Filenév',
+'filedesc' => 'Összefoglaló',
+'fileuploadsummary' => 'Összefoglaló:',
+'filestatus' => 'Szerzői jogi állapot',
+'filesource' => 'Forrás',
+'copyrightpage' => 'Project:Copyright',
+'uploadedfiles' => 'Felküldött file-ok',
+'ignorewarning' => 'Biztosan így akarom feltölteni.',
+'ignorewarnings' => 'Hagyd figyelmen kívül a figyelmeztetéseket',
+'minlength' => 'A kép nevének legalább három betűből kell állnia.',
+'badfilename' => 'A kép új neve "$1".',
+'badfiletype' => '".$1" nem javasolt képformátumnak.',
+'largefile' => '$1 bájtnál nagyobb fájlok feltöltése nem javasolt; ez a fájl $2 bájtos.',
+'largefileserver' => 'A fájl mérete meghaladja a kiszolgálón beállított maximális értéket.',
+'fileexists' => 'Ezzel a névvel már létezik egy file: $1. Ellenőrizd hogy biztosan felül akarod-e írni azt!',
+'successfulupload' => 'Sikeresen felküldve',
+'fileuploaded' => 'A(z) „$1” fájl felküldése sikeres volt.
+Kérlek, a $2 linken adj meg minél több információt a
+fájlról, például hogy honnan való, mikor és ki készítette, vagy bármi
+mást, amit fontosnak tartasz. Ha egy képet töltöttél fel, így tudod beilleszteni: <tt><nowiki>[[Image:$1|thumb|Leírás]]</nowiki></tt>',
+'uploadwarning' => 'Felküldési figyelmeztetés',
+'savefile' => 'File mentése',
+'uploadedimage' => '"[[$1]]" felküldve',
+'uploadscripted' => 'Ez a file olyan HTML vagy script kódot tartalmaz melyet tévedésből egy webböngésző esetleg értelmezni próbálhatna.',
+'uploadcorrupt' => 'A fájl sérült vagy hibás a kiterjesztése. Légy szíves ellenőrizd a fájlt és próbálkozz újra!',
+'uploadvirus' => 'Ez a file vírust tartalmaz! A részletek: $1',
+'sourcefilename' => 'Forrásfájl neve',
+'destfilename' => 'Célmédiafájl neve',
+'license' => 'Licenc',
+'nolicense' => 'Nem választok, kézzel fogom beírni',
+'imagelist' => 'Képlista',
+'imagelisttext' => 'Lentebb látható $1 kép, $2 rendezve.',
+'getimagelist' => 'képlista lehívása',
+'ilsubmit' => 'Keresés',
+'showlast' => 'Az utolsó $1 kép $2.',
+'byname' => 'név szerint',
+'bydate' => 'dátum szerint',
+'bysize' => 'méret szerint',
+'imgdelete' => 'töröl',
+'imgdesc' => 'leírás',
+'imglegend' => 'Jelmagyarázat: (leírás) = kép leírás megtekintés/szerkesztés.',
+'imghistory' => 'Kép története',
+'revertimg' => 'régi',
+'deleteimg' => 'töröl',
+'deleteimgcompletely' => 'töröl',
+'imghistlegend' => 'Jelmagyarázat: (akt) = ez az aktuális kép,
+(töröl) = ezen régi változat törlése,
+(régi) = visszaállás erre a régi változatra.
+<br /><i>Klikkelj a dátumra hogy megnézhesd az akkor felküldött képet</i>.',
+'imagelinks' => 'Képhivatkozások',
+'linkstoimage' => 'Az alábbi lapok hivatkoznak erre a képre:',
+'nolinkstoimage' => 'Erre a képre nem hivatkozik lap.',
+'noimage' => 'Ezen a néven nem létezik médiafájl. Ha szeretnél, $1 egyet.',
+'noimage-linktext' => 'feltölthetsz',
+'uploadnewversion-linktext'=> 'A fájl újabb változatának felküldése',
+'mimesearch' => 'Keresés MIME-típus alapján',
+'mimetype' => 'MIME-típus:',
+'unwatchedpages' => 'Nem figyelt lapok',
+'listredirects' => 'Átirányítások listája',
+'unusedtemplates' => 'Nem használt sablonok',
+'unusedtemplatestext' => 'Ez a lap azon sablon névtérben lévő lapokat gyűjti össze, melyek nem találhatók meg más lapokon. Ellenőrizd a linkeket, mielőtt törölnéd őket.',
+'randomredirect' => 'Átirányítás találomra',
+'statistics' => 'Statisztikák',
+'sitestats' => 'Server statisztika',
+'userstats' => 'Felhasználói statisztikák',
+'sitestatstext' => 'Az adatbázisban összesen \'\'\'$1\'\'\' lap található.
+Ebben benne vannak a „vita”-lapok, a {{grammar:rol|{{SITENAME}}}} szóló lapok, a
+nagyon rövid („csonk”) lapok, átirányítások, és más olyan lapok, amik vélhetően nem
+számítanak igazi lapnak.
+Ezeket nem számítva \'\'$2\'\' lapunk van.
+
+\'\'\'$8\'\'\' fájlt töltöttek fel.
+
+A wiki elindítása óta \'\'\'$3\'\'\' alkalommal néztek meg
+lapot, és \'\'\'$4\'\'\' alkalommal szerkesztettek.
+Ez átlagosan \'\'\'$5\'\'\' szerkesztés laponként, és
+\'\'\'$6\'\'\' megnézés szerkesztésenként.
+
+$7 [http://meta.wikimedia.org/wiki/Help:Job_queue elvégzetlen feladat] van.',
+'userstatstext' => 'Jelenleg \'\'\'$1\'\'\' regisztrált felhasználó van, ebből \'\'\'$2\'\'\' darab (azaz \'\'\'$4%\'\'\') adminisztrátor (lásd: $3).',
+'disambiguations' => 'Egyértelműsítő lapok',
+'disambiguationspage' => 'Template:Egyért',
+'doubleredirects' => 'Dupla átirányítások',
+'doubleredirectstext' => 'Minden sor tartalmaz egy-egy hivatkozást az első és a második átirányításra, valamint a második átirányítás szövegének első sorát, ami általában a „valódi” célt tartalmazza, amire az első átirányításnak mutatnia kellene.',
+'brokenredirects' => 'Nem létező lapra mutató átirányítások',
+'brokenredirectstext' => 'Az alábbi átirányítások nem létező lapokra mutatnak.',
+'nbytes' => '$1 bájt',
+'ncategories' => '$1 kategória',
+'nlinks' => '{{FORMATNUM:$1}} link',
+'nmembers' => '$1 elem',
+'nrevisions' => '$1 revízió',
+'nviews' => '$1 megtekintés',
+'lonelypages' => 'Magányos lapok',
+'uncategorizedpages' => 'Kategorizálatlan lapok',
+'uncategorizedcategories'=> 'Kategorizálatlan kategóriák',
+'uncategorizedimages' => 'Kategorizálatlan képek',
+'unusedcategories' => 'Nem használt kategóriák',
+'unusedimages' => 'Nem használt képek',
+'popularpages' => 'Népszerű lapok',
+'wantedcategories' => 'Keresett kategóriák',
+'wantedpages' => 'Keresett lapok',
+'mostlinked' => 'Legtöbbet hivatkozott lapok',
+'mostlinkedcategories' => 'Legtöbbet hivatkozott kategóriák',
+'mostcategories' => 'Legtöbb kategóriába tartozó lapok',
+'mostimages' => 'Legtöbbet használt képek',
+'mostrevisions' => 'Legtöbbet szerkesztett lapok',
+'allpages' => 'Az összes lap listája',
+'prefixindex' => 'Keresés előtag szerint',
+'randompage' => 'Lap találomra',
+'shortpages' => 'Rövid lapok',
+'longpages' => 'Hosszú lapok',
+'deadendpages' => 'Zsákutca lapok',
+'listusers' => 'Felhasználók',
+'specialpages' => 'Speciális lapok',
+'spheading' => 'Speciális lapok',
+'restrictedpheading' => 'Korlátozott hozzáférésű speciális lapok',
+'recentchangeslinked' => 'Kapcsolódó változtatások',
+'rclsub' => '(a "$1" lapról hivatkozott lapok)',
+'newpages' => 'Új lapok',
+'ancientpages' => 'Leghosszabb ideje nem szerkesztett lapok',
+'intl' => 'Nyelvek közötti linkek',
+'move' => 'Átmozgat',
+'movethispage' => 'Mozgasd ezt a lapot',
+'unusedimagestext' => '<p>Vedd figyelembe azt hogy más
+lapok - mint például a nemzetközi {{grammar:k|{{SITENAME}}}} - közvetlenül
+hivatkozhatnak egy file URL-jére, ezért szerepelhet itt annak
+ellenére hogy aktívan használják.</p>',
+'unusedcategoriestext' => 'A következő kategóriákban egyetlen cikk, illetve alkategória sem szerepel.',
+'booksources' => 'Könyvforrások',
+'categoriespagetext' => 'A wikiben az alábbi kategóriák találhatóak.',
+'booksourcetext' => 'Alább néhány hivatkozás található olyan oldalakra, ahol új vagy használt könyveket árusítanak, vagy további információkkal szolgálhatnak az általad vizsgált könyvről.',
+'alphaindexline' => '$1 – $2',
+'version' => 'Névjegy',
+'log' => 'Rendszernaplók',
+'alllogstext' => 'A feltöltési, törlési, lapvédelmi, blokkolási és sysop naplók kombinált listája. Szűkítheted a nézetet a naplótípus, a műveletet végző felhasználó vagy az érintett oldal megadásával.',
+'logempty' => 'Nincs illeszkedő naplóbejegyzés.',
+'nextpage' => 'Következő lap ($1)',
+'allpagesfrom' => 'Lapok listázása ettől kezdve:',
+'allarticles' => 'Az összes szócikk',
+'allinnamespace' => 'Az összes lap ($1 névtér)',
+'allnotinnamespace' => 'Minden olyan lap, ami nem a(z) $1 névtérben van.',
+'allpagesprev' => 'Előző',
+'allpagesnext' => 'Következő',
+'allpagessubmit' => 'Menj',
+'allpagesprefix' => 'Lapok listázása, amik ezzel az előtaggal kezdődnek:',
+'allpagesbadtitle' => 'A megadott lapnév nyelvközi vagy wikiközi előtagot tartalmazott, vagy érvénytelen volt. Talán olyan karakter van benne, amit nem lehet lapnevekben használni.',
+'mailnologin' => 'Nincs feladó',
+'mailnologintext' => 'Ahhoz hogy másoknak emailt küldhess
+[[Special:Belépés|be kell jelentkezned]]
+és meg kell adnod egy érvényes email címet a [[Special:Beállítások|beállításaidban]].',
+'emailuser' => 'E-mail küldése ezen felhasználónak',
+'emailpage' => 'E-mail küldése',
+'emailpagetext' => 'Ha ez a felhasználó érvényes e-mail-címet adott meg, akkor ezen űrlap kitöltésével e-mailt tudsz neki küldeni. Feladóként a beállításaid között megadott e-mail-címed fog szerepelni, hogy a címzett válaszolni tudjon.',
+'noemailtitle' => 'Nincs email cím',
+'noemailtext' => 'Ez a felhasználó nem adott meg email címet, vagy
+nem kíván másoktól leveleket kapni.',
+'emailfrom' => 'Feladó',
+'emailto' => 'Címzett',
+'emailsubject' => 'Téma',
+'emailmessage' => 'Üzenet',
+'emailsend' => 'Küldés',
+'emailsent' => 'E-mail elküldve',
+'emailsenttext' => 'Az email üzenetedet elküldtem.',
+'watchlist' => 'Figyelőlistám',
+'nowatchlist' => 'Nincs lap a figyelőlistádon.',
+'watchlistcount' => '\'\'\'$1 lap van a figyelőlistádon, beleértve a vitalapokat is.\'\'\'',
+'clearwatchlist' => 'Figyelőlista törlése',
+'watchlistcleartext' => 'Biztosan el akarod őket távolítani?',
+'watchlistclearbutton' => 'Figyelőlista törlése',
+'watchnologin' => 'Nincs belépve',
+'watchnologintext' => 'Ahhoz, hogy figyelőlistád lehessen, [[Special:Login|be kell lépned]].',
+'addedwatch' => 'Figyelőlistához hozzáfűzve',
+'addedwatchtext' => 'A „[[:$1]]” lapot hozzáadtam a [[Special:Watchlist|figyelőlistádhoz]].
+Ezután minden, a lapon vagy annak vitalapján történő változást látni fogsz ott, és a lap \'\'\'vastagon\'\'\' fog szerepelni a [[Special:Recentchanges|friss változtatások]]
+között, hogy könnyen észrevehető legyen.
+
+Ha később el akarod távolítani a lapot a figyelőlistádról, az
+oldalmenü "lapfigyelés vége" pontjával teheted meg.',
+'removedwatch' => 'Figyelőlistáról eltávolítva',
+'removedwatchtext' => 'A „$1” lapot eltávolítottam a figyelőlistáról.',
+'watch' => 'Lap figyelése',
+'watchthispage' => 'Lap figyelése',
+'unwatch' => 'Lapfigyelés vége',
+'unwatchthispage' => 'Figyelés vége',
+'notanarticle' => 'Nem szócikk',
+'watchdetails' => '* $1 figyelt lap (a vitalapokat nem számítva)
+* [[Special:Watchlist/edit|A teljes lista áttekintése és szerkesztése]]
+* [[Special:Watchlist/clear|Az összes lap eltávolítása]]',
+'wlheader-enotif' => '* Email értesítés engedélyezve.',
+'wlheader-showupdated' => '* Azok a lapok, amelyek megváltoztak, mióta utoljára megnézted őket, \'\'\'vastagon\'\'\' láthatóak.',
+'watchmethod-recent' => 'a figyelt lapokon belüli legfrissebb szerkesztések',
+'watchmethod-list' => 'a legfrissebb szerkesztésekben található figyelt lapok',
+'removechecked' => 'A kijelölt lapok eltávolítása a figyelésből',
+'watchlistcontains' => 'A figyelőlistád $1 lapot tartalmaz.',
+'watcheditlist' => 'Íme a figyelőlistádban található lapok betűrendes listája. Ha egyes lapokat el szeretnél távolítani, jelöld ki őket, és válaszd a \'Kijelöltek eltávolítása\' gombot a lap alján.',
+'removingchecked' => 'A kért lapok eltávolítása a figyelőlistáról...',
+'couldntremove' => '\'$1\' nem távolítható el...',
+'iteminvalidname' => 'Probléma a \'$1\' elemmel: érvénytelen név...',
+'wlnote' => 'Lentebb az utolsó <b>$2</b> óra $1 változtatása látható.',
+'wlshowlast' => 'Az elmúlt $1 órában | $2 napon | $3 történt változtatások legyenek láthatóak',
+'wlsaved' => 'Ez a figyelőlistád egy elmentett példánya.',
+'wlhideshowown' => 'saját szerkesztések $1',
+'wlhideshowbots' => 'robotok szerkesztéseinek $1',
+'deletepage' => 'Lap törlése',
+'confirm' => 'Megerősítés',
+'excontent' => 'a lap tartalma: \'$1\'',
+'excontentauthor' => 'a lap tartalma: \'$1\' (és csak \'$2\' szerkesztette)',
+'exbeforeblank' => 'a kiürítés előtti tartalom: \'$1\'',
+'exblank' => 'a lap üres volt',
+'confirmdelete' => 'Törlés megerősítése',
+'historywarning' => 'Figyelem: a lapnak, amit törölni készülsz, története van:',
+'confirmdeletetext' => 'Egy lap vagy kép teljes laptörténetével együtti végleges törlésére készülsz. Kérlek, erősítsd meg, hogy valóban ezt szándékozod tenni, átlátod a következményeit, és az [[Project:Irányelvek|irányelvekkel]] összhangban cselekedsz.',
+'actioncomplete' => 'Művelet végrehajtva',
+'deletedtext' => 'A(z) „$1” lapot törölted. A legutóbbi törlések listájához lásd a $2 lapot.',
+'deletedarticle' => '"$1" törölve',
+'dellogpage' => 'Törlési_napló',
+'dellogpagetext' => 'Lentebb a mostanában törölt lapok láthatóak.
+Minden időpont a server órája ([[UTC]]) szerinti.
+<ul>
+</ul>',
+'deletionlog' => 'törlési napló',
+'deletecomment' => 'A törlés oka',
+'cantrollback' => 'Nem lehet visszaállítani: az utolsó szerkesztést végző felhasználó az egyetlen, aki a lapot szerkesztette.',
+'alreadyrolled' => '[[:$1]] utolsó, [[User:$2|$2]] ([[User talk:$2|vita]]) általi szerkesztését nem lehet visszavonni: időközben valakimár visszavonta, vagy szerkesztette a lapot.
+
+Az utolsó szerkesztést [[User:$3|$3]] ([[User talk:$3|vita]]) végezte.',
+'editcomment' => 'A változtatás összefoglalója "<i>$1</i>" volt.',
+'revertpage' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|vita]]) szerkesztései visszaállítva [[User:$1|$1]] utolsó változatára',
+'protectlogpage' => 'Lapvédelmi_napló',
+'protectedarticle' => 'levédte a(z) [[$1]] lapot',
+'unprotectedarticle' => 'eltávolította a védelmet a(z) "[[$1]]" lapról',
+'protectsub' => '(„$1” levédése)',
+'confirmprotecttext' => 'Tényleg le akarod védeni ezt a lapot?',
+'confirmprotect' => 'Levédés megerősítése',
+'protectmoveonly' => 'Csak átmozgatás elleni védelem',
+'protectcomment' => 'A védelem oka',
+'unprotectsub' => '(„$1” védelmének feloldása)',
+'confirmunprotecttext' => 'Tényleg fel akarod oldani ezen lap védelmét?',
+'confirmunprotect' => 'Védelemfeloldás megerősítése',
+'unprotectcomment' => 'Védelem feloldásának oka',
+'protect-unchain' => 'Mozgatási jogok állítása külön',
+'protect-default' => '(alapértelmezett)',
+'protect-level-autoconfirmed'=> 'Csak regisztrált felhasználók',
+'protect-level-sysop' => 'Csak adminisztrátorok',
+'restriction-edit' => 'Szerkesztés',
+'restriction-move' => 'Átmozgatás',
+'undelete' => 'Törölt lap helyreállítása',
+'undeletepage' => 'Törölt lapok megtekintése és helyreállítása',
+'undeletepagetext' => 'Az alábbi lapokat törölték, de még helyreállíthatók az archívumból. Az archívum időről időre ürítődik.',
+'undeleterevisions' => '$1 változat archiválva',
+'undeletehistory' => 'Ha helyreállítasz egy lapot, azzal visszahozod laptörténet összes változatát. Ha lap törlése óta azonos néven már létrehoztak egy újabb lapot, a helyreállított változatok a laptörténet elejére kerülnek be, az jelenlegi lapváltozat módosítása nélkül.',
+'undeleterevision' => '$1-i törölt változat',
+'undeletebtn' => 'Helyreállítás!',
+'undeletedarticle' => '"$1" helyreállítva',
+'undeletedrevisions' => '$1 változat helyreállítva',
+'namespace' => 'Névtér:',
+'invert' => 'Kijelölés megfordítása',
+'contributions' => 'User közreműködései',
+'mycontris' => 'Közreműködéseim',
+'contribsub' => '$1 cikkhez',
+'nocontribs' => 'Nem találtam a feltételnek megfelelő módosítást.',
+'ucnote' => 'Lentebb <b>$1</b> módosításai láthatóak az elmúlt <b>$2</b> napban.',
+'uctop' => ' (utolsó)',
+'sp-contributions-newest'=> 'Legfrissebb',
+'sp-contributions-oldest'=> 'Legkorábbi',
+'sp-contributions-newer'=> '$1 frissebb',
+'sp-contributions-older'=> '$1 korábbi',
+'sp-contributions-newbies-sub'=> 'Új szerkesztők lapjai',
+'whatlinkshere' => 'Mi hivatkozik erre',
+'notargettitle' => 'Nincs cél',
+'notargettext' => 'Nem adtál meg lapot vagy usert keresési célpontnak.',
+'linklistsub' => '(Linkek )',
+'linkshere' => 'Az alábbi lapok hivatkoznak erre:',
+'nolinkshere' => 'Erre a lapra semmi nem hivatkozik.',
+'isredirect' => 'átirányítás',
+'istemplate' => 'beillesztve',
+'blockip' => 'IP-cím blokkolása',
+'ipaddress' => 'IP cím',
+'ipadressorusername' => 'IP cím vagy felhasználói név',
+'ipbexpiry' => 'Lejárat',
+'ipbreason' => 'Blokkolás oka',
+'ipbsubmit' => 'Blokkolás',
+'ipbother' => 'Más időtartam',
+'ipboptions' => '2 óra:2 hours,1 nap:1 day,3 nap:3 days,1 hét:1 week,2 hét:2 weeks,1 hónap:1 month,3 hónap:3 months,6 hónap:6 months,1 év:1 year,végtelen:infinite',
+'ipbotheroption' => 'Más időtartam',
+'blockipsuccesssub' => 'Sikeres blokkolás',
+'ipusubmit' => 'Blokk feloldása',
+'ipblocklist' => 'Blokkolt IP címek listája',
+'blocklistline' => '$1, $2 blokkolta $3 felhasználót (lejárat: $4)',
+'blocklink' => 'blokkolás',
+'unblocklink' => 'blokk feloldása',
+'contribslink' => 'szerkesztései',
+'autoblocker' => 'Az általad használt IP-cím autoblokkolva van, mivel korábban a blokkolt „[[User:$1|$1]]” használta. $1 blokkolásának indoklása: „\'\'\'$2\'\'\'”',
+'blocklogpage' => 'Blokkolási_napló',
+'blocklogentry' => '"$1" blokkolva $2 lejárattal',
+'blocklogtext' => 'Ez a felhasználókra helyezett blokkoknak és azok feloldásának listája. Az IP autoblokkok nem szerepelnek a listában. Lásd még [[Special:Ipblocklist|a jelenleg életben lévő blokkok listáját]].',
+'unblocklogentry' => '"$1" blokkolása feloldva',
+'ipb_expiry_invalid' => 'Hibás lejárati dátum.',
+'proxyblockreason' => 'Az IP címed \'\'open proxy\'\' probléma miatt le van tiltva. Vedd fel a kapcsolatot egy informatikussal vagy az internet szolgáltatóddal ezen súlyos biztonsági probléma ügyében.',
+'proxyblocksuccess' => 'Kész.',
+'rights' => 'Rights:',
+'already_sysop' => 'Ez a felhasználó már adminisztrátor.',
+'already_bureaucrat' => 'Ez a felhasználó már bürokrata.',
+'movepage' => 'Lap mozgatása',
+'movepagetext' => 'A lentebb található űrlap segítségével lehetséges egy lapot átnevezni, és átmozgatni a teljes történetével együtt egy új névre. A régi név átirányítássá válik az új szócikkre. A régi szócikkre hivatkozások nem változnak meg; győződj meg arról, hogy nem hagysz magad után a régi szócikkre hivatkozó linkeket. A te feladatod biztosítani, hogy a linkek oda mutassanak, ahova kell nekik.
+
+Vedd figyelembe azt, hogy az átnevezés \'\'\'nem\'\'\' történik meg akkor, ha már létezik olyan nevű lap, kivéve ha az üres, átirányítás vagy nincs szerkesztési története. Ez azt jelenti, hogy vissza tudsz nevezni egy tévedésből átnevezett lapot, de nem tudsz egy már létező aktív lapot felülírni.
+
+\'\'\'FIGYELEM!\'\'\' Egy népszerű lap esetén ez egy drasztikus és váratlan változás; mielőtt átnevezel valamit, győződj meg arról, hogy tudatában vagy a következményeknek.',
+'movepagetalktext' => 'A laphoz tartozó vitalap automatikusan átneveződik, \'\'\'kivéve, ha:\'\'\'
+
+*a lapot névterek között mozgatod át,
+*már létezik egy nem üres vitalap az új helyen,
+*nem jelölöd be a lenti pipát.
+Ezen esetekben a vitalapot külön, kézzel kell átnevezned a kívánságaid szerint.',
+'movearticle' => 'Lap mozgatás',
+'movenologin' => 'Nincs belépve',
+'movenologintext' => 'Ahhoz hogy mozgass egy lapot [[Special:Belépés|be kell lépned]].',
+'newtitle' => 'Az új névre',
+'movepagebtn' => 'Lap mozgatása',
+'pagemovedsub' => 'Átmozgatás sikeres',
+'pagemovedtext' => 'A(z) „[[$1]]” lapot átmozgattam a(z) „[[$2]]” névre.
+
+\'\'\'Kérlek, [[Special:Whatlinkshere/$2|ellenőrizd]]\'\'\', hogy az átmozgatás nem hozott-e létre [[Special:DoubleRedirects|dupla átirányításokat]], és javítsd őket, ha szükséges.',
+'articleexists' => 'Ilyen névvel már létezik lap, vagy az általad
+választott név érvénytelen.
+Kérlek válassz egy másik nevet.',
+'talkexists' => 'A lap átmozgatása sikerült, de a hozzá tartozó
+vitalapot nem tudtam átmozgatni mert már létezik egy egyező nevű
+lap az új helyen. Kérlek gondoskodj a két lap összefűzéséről.',
+'movedto' => 'átmozgatva',
+'movetalk' => 'Mozgasd a "vita" lapokat is ha lehetséges.',
+'talkpagemoved' => 'Az oldal vitalapját is átmozgattam.',
+'talkpagenotmoved' => 'Az oldal vitalapja <strong>nem került</strong> átmozgatásra.',
+'1movedto2' => '[[$1]] átmozgatva [[$2]] névre',
+'1movedto2_redir' => '[[$1]] átmozgatva [[$2]] névre (az átirányítást felülírva)',
+'movelogpage' => 'Átmozgatási napló',
+'movelogpagetext' => 'Az alábbiakban az átmozgatott lapok listája látható.',
+'movereason' => 'Indoklás',
+'revertmove' => 'visszaállítás',
+'delete_and_move' => 'Törlés és átnevezés',
+'delete_and_move_text' => '== Törlés szükséges ==
+
+Az átnevezés céljaként megadott „[[$1]]” szócikk már létezik. Ha az átnevezést végre akarod hajtani, ezt a lapot törölni kell. Valóban ezt szeretnéd?',
+'delete_and_move_confirm'=> 'Igen, töröld a lapot',
+'delete_and_move_reason'=> 'átnevezendő lap célneve felszabadítva',
+'export' => 'Lapok exportálása',
+'exporttext' => 'Egy adott lap vagy lapcsoport szövegét és laptörténetét exportálhatod XML-be. A kapott fájlt importálhatod egy másik MediaWiki alapú rendszerbe a Special:Import lapon keresztül.
+
+Lapok exportálásához add meg a címüket a lenti szövegdobozban (minden címet külön sorba), és válaszd ki, hogy az összes korábbi változatra és a teljes laptörténetekre szükséged van-e, vagy csak az aktuális változatok és a legutolsó változtatásokra vonatkozó információk kellenek.
+
+Az utóbbi esetben közvetlen linket is használhatsz, például a [[Special:Export/{{msg:MediaWiki:Mainpage}}]] a [[{{msg:MediaWiki:Mainpage}}]] nevű lapot exportálja.',
+'exportcuronly' => 'Csak a legfrissebb állapot, teljes laptörténet nélkül',
+'allmessages' => 'Rendszerüzenetek',
+'allmessagesname' => 'Név',
+'allmessagesdefault' => 'Alapértelmezett szöveg',
+'allmessagescurrent' => 'Jelenlegi szöveg',
+'allmessagestext' => 'Ez a MediaWiki névtérben megtalálható összes rendszerüzenet listája.',
+'allmessagesnotsupportedUI'=> 'A felhasználói felületedhez jelenleg megadott nyelvet (<b>$1</b>) ezen a wikin a \'\'Special:Allmessages\'\' nem támogatja.',
+'allmessagesnotsupportedDB'=> 'A \'\'\'\'\'Special:Allmessages\'\'\'\'\' lap nem használható, mert a \'\'\'$wgUseDatabaseMessages\'\'\' ki van kapcsolva.',
+'allmessagesfilter' => 'Üzenetnevek szűrése:',
+'allmessagesmodified' => 'Csak a módosítottak mutatása',
+'thumbnail-more' => 'Nagyít',
+'missingimage' => '<b>Hiányzó kép</b><br /><i>$1</i>',
+'thumbnail_error' => 'Hiba az indexkép létrehozásakor: $1',
+'import' => 'Lapok importálása',
+'importnosources' => 'Nincsenek transzwikiimport-források definiálva, a közvetlen laptörténet-felküldés pedig nem megengedett.',
+'tooltip-minoredit' => 'Szerkesztés megjelölése apróként [alt-i]',
+'tooltip-save' => 'A változtatásaid elmentése [alt-s]',
+'tooltip-preview' => 'Mielőtt elmentenéd a lapot, ellenőrizd, biztosan úgy néz-e ki, ahogy szeretnéd! [alt-p]',
+'tooltip-diff' => 'Nézd meg, milyen változtatásokat végeztél eddig a szövegen [alt-v]',
+'tooltip-compareselectedversions'=> 'A két kiválasztott változat közötti eltérések megjelenítése [alt-v]',
+'anonymous' => 'Névtelen {{SITENAME}}-felhasználó(k)',
+'lastmodifiedatby' => 'Ezt a lapot utoljára $3 módosította $2, $1 időpontban.',
+'and' => 'és',
+'spamprotectiontext' => 'Az általad elmenteni kívánt lap fennakadt a \'\'spam\'\' szűrőn. Ezt valószínűleg egy külső weblapra hivatkozás okozta.',
+'spamprotectionmatch' => 'A \'\'spam\'\' szűrőn az alábbi szöveg akadt fenn: $1',
+'subcategorycount' => 'Ennek a kategóriának {{PLURAL:$1|egy|$1}} alkategóriája van.',
+'categoryarticlecount' => '{{PLURAL:$1|Egy|$1}} szócikk van ebben a kategóriában.',
+'listingcontinuesabbrev'=> ' folyt.',
+'mw_math_png' => 'Mindig készítsen PNG-t',
+'mw_math_simple' => 'HTML, ha nagyon egyszerű, egyébként PNG',
+'mw_math_html' => 'HTML, ha lehetséges, egyébként PNG',
+'mw_math_source' => 'Hagyja TeX formában (szöveges böngészőknek)',
+'mw_math_modern' => 'Modern böngészőknek ajánlott beállítás',
+'mw_math_mathml' => 'MathML',
+'markaspatrolleddiff' => 'Ellenőrzöttnek jelölöd',
+'markaspatrolledtext' => 'Ezt a cikket ellenőrzöttnek jelölöd',
+'markedaspatrolled' => 'Ellenőrzöttnek jelölve',
+'markedaspatrolledtext' => 'A kiválasztott változatot ellenőrzöttnek jelölted.',
+'rcpatroldisabled' => 'A Friss Változtatások Ellenőrzése kikapcsolva',
+'rcpatroldisabledtext' => 'A Friss Változtatások Ellenőrzése jelenleg nincs engedélyezve.',
+'monobook.js' => '/* Tooltipek és gyorsbillentyűk */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'A felhasználói lapod\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Az általad használt IP címhez tartozó felhasználói lap\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'A vitalapod\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Az általad használt IP címről végrehajtott szerkesztések megvitatása\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'A beállításaid\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Az általad figyelemmel kísért oldalak utolsó változtatásai\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'A közreműködéseid listája\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Bejelentkezni javasolt, de nem kötelező.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Bejelentkezni javasolt, de nem kötelező.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Kijelentkezés\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Az oldal tartalmának megvitatása\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Te is szerkesztheted ezt az oldalt. Mielőtt elmentenéd, használd az előnézetet.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Újabb fejezet nyitása a vitában.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Ez egy védett lap. Ide kattintva megnézheted a forrását.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'A lap korábbi változatai\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Lap levédése\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Lap törlése\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Törölt lapváltozatok visszaállítása\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Lap átmozgatása\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Lap hozzáadása a figyelőlistádhoz\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Lap eltávolítása a figyelőlistádról\');
+ ta[\'search\'] = new Array(\'f\',\'Keresés a wikiben\');
+ ta[\'p-logo\'] = new Array(\'\',\'Kezdőlap\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Kezdőlap megtekintése\');
+ ta[\'n-portal\'] = new Array(\'\',\'A közösségről, miben segíthetsz, mit hol találsz meg\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Háttérinformáció az aktuális eseményekről\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'A wikin történt legutóbbi változtatások listája\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Egy véletlenszerűen kiválasztott lap betöltése\');
+ ta[\'n-help\'] = new Array(\'\',\'Ha bármi problémád van...\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Támogass minket!\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Az erre a lapra hivatkozó más lapok listája\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Az erről a lapról hivatkozott lapok utolsó változtatásai\');
+ ta[\'feed-rss\'] = new Array(\'\',\'A lap tartalma RSS feed formájában\');
+ ta[\'feed-atom\'] = new Array(\'\',\'A lap tartalma Atom feed formájában\');
+ ta[\'t-contributions\'] = new Array(\'\',\'A felhasználó közreműködéseinek listája\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Írj levelet ennek a felhasználónak!\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Képek vagy egyéb fájlok feltöltése\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Az összes speciális lap listája\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Lap megtekintése\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Felhasználói lap megtekintése\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Fájlleíró lap megtekintése\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Ez egy speciális lap, nem lehet szerkeszteni.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Projekt lap megtekintése\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Képleíró lap megtekintése\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Rendszerüzenet megtekintése\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Sablon megtekintése\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Segítő lap megtekintése\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Kategória megtekintése\');',
+'previousdiff' => '← Előző változtatások',
+'nextdiff' => 'Következő változtatások →',
+'imagemaxsize' => 'A képlapokon mutatott maximális képméret:',
+'thumbsize' => 'Indexkép mérete:',
+'showbigimage' => 'Nagyfelbontású változat letöltése ($1x$2, $3 KB)',
+'newimages' => 'Új képek galériája',
+'specialloguserlabel' => 'Felhasználó:',
+'speciallogtitlelabel' => 'Cím:',
+'passwordtooshort' => 'Túl rövid a jelszavad. Legalább $1 karakterből kell állnia.',
+'metadata' => 'Metaadatok',
+'metadata-help' => 'Ez a kép járulékos adatokat tartalmaz, amelyek feltehetően a kép létrehozásához használt digitális fényképezőgép vagy lapolvasó beállításairól adnak tájékoztatást. Ha a képet az eredetihez képest módosították, ezen adatok eltérhetnek a kép tényleges jellemzőitől.',
+'metadata-expand' => 'További képadatok',
+'exif-imagewidth' => 'Szélesség',
+'exif-imagelength' => 'Magasság',
+'exif-compression' => 'Tömörítési séma',
+'exif-photometricinterpretation'=> 'Színösszetevők',
+'exif-samplesperpixel' => 'Színösszetevők száma',
+'exif-planarconfiguration'=> 'Adatok csoportosítása',
+'exif-stripoffsets' => 'Csík ofszet',
+'exif-rowsperstrip' => 'Egy csíkban levő sorok száma',
+'exif-stripbytecounts' => 'Bájt/csík',
+'exif-datetime' => 'Utolsó változtatás ideje',
+'exif-make' => 'Fényképezőgép gyártója',
+'exif-model' => 'Fényképezőgép típusa',
+'exif-software' => 'Használt szoftver',
+'exif-datetimeoriginal' => 'EXIF információ létrehozásának dátuma',
+'exif-exposuretime' => 'Expozíciós idő',
+'exif-focallength' => 'Fókusztávolság',
+'exif-planarconfiguration-1'=> 'Egyben',
+'edit-externally' => 'A file szerkesztése külső alkalmazással',
+'edit-externally-help' => 'Lásd a [http://meta.wikimedia.org/wiki/Help:External_editors „setup instructions”] leírást (angolul) ennek használatához.',
+'recentchangesall' => 'összes',
+'imagelistall' => 'összes',
+'watchlistall1' => 'összes',
+'watchlistall2' => 'bármikor',
+'namespacesall' => 'Összes',
+'confirmemail' => 'E-mail cím megerősítése',
+'confirmemail_text' => 'Ennek a wikinek a használatához meg kell erősítened az e-mail címed, mielőtt használni kezded a levelezési rendszerét. Nyomd meg az alsó gombot, hogy kaphass egy e-mailt, melyben megtalálod a megerősítéshez szükséges kódot. Töltsd be a kódot a böngésződbe, hogy aktiválhasd az e-mail címedet. Köszönjük!',
+'confirmemail_send' => 'Küldd el a kódot',
+'confirmemail_sent' => 'Kaptál egy e-mailt, melyben megtalálod a megerősítéshez szükséges kódot.',
+'confirmemail_sendfailed'=> 'Nem tudjuk elküldeni a megerősítéshez szükséges e-mailt. Kérünk, ellenőrizd a címet.',
+'confirmemail_invalid' => 'Nem megfelelő kód. A kódnak lehet, hogy lejárt a felhasználhatósági ideje.',
+'confirmemail_success' => 'Az e-mail címed megerősítve. Most már beléphetsz a wikibe.',
+'confirmemail_loggedin' => 'E-mail címed megerősítve.',
+'confirmemail_subject' => '{{SITENAME}} e-mail cím megerősítés',
+'confirmemail_body' => 'Valaki, valószínűleg te, a $1 IP címről regisztrált a(z) {{SITENAME}}RA a(z) "$2" azonosítóval, ezzel az e-mail címmel.
+
+Annak érdekében, hogy megerősítsd, ez az azonosító valóban hozzád tartozik, és hogy aktiváld az e-mail címedet a(z) {{SITENAME}}ON, nyisd meg az alábbi linket a böngésződben:
+
+$3
+
+Ha ez *nem* te vagy, ne kattints a linkre. Ennek a megerősítésre szánt kódnak a felhasználhatósági ideje lejár: $4.',
+'articletitles' => '\'\'$1\'\' kezdetű szócikkek',
+);
+?>
diff --git a/languages/messages/MessagesIa.php b/languages/messages/MessagesIa.php
new file mode 100644
index 000000000000..c3be51ff4820
--- /dev/null
+++ b/languages/messages/MessagesIa.php
@@ -0,0 +1,801 @@
+<?php
+/** Interlingua (Interlingua)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$quickbarSettings = array(
+ 'Nulle', 'Fixe a sinistra', 'Fixe a dextera', 'Flottante a sinistra'
+);
+
+$skinNames = array(
+ 'cologneblue' => 'Blau Colonia',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Discussion',
+ NS_USER => 'Usator',
+ NS_USER_TALK => 'Discussion_Usator',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discussion_$1',
+ NS_IMAGE => 'Imagine',
+ NS_IMAGE_TALK => 'Discussion_Imagine',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discussion_MediaWiki',
+ NS_TEMPLATE => 'Patrono',
+ NS_TEMPLATE_TALK => 'Discussion_Patrono',
+ NS_HELP => 'Adjuta',
+ NS_HELP_TALK => 'Discussion_Adjuta',
+ NS_CATEGORY => 'Categoria',
+ NS_CATEGORY_TALK => 'Discussion_Categoria'
+);
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+
+$messages = array(
+
+# User Toggles
+#
+
+"tog-underline" => "Sublinear ligamines",
+"tog-highlightbroken" => "Formatar ligamines rupte <a href=\"\" class=\"new\">assi</a> (alternativemente: assi<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Justificar paragraphos",
+"tog-hideminor" => "Occultar modificationes recente minor",
+"tog-usenewrc" => "Modificationes recente meliorate (non functiona in tote le navigatores)",
+"tog-numberheadings" => "Numerar titulos automaticamente",
+"tog-showtoolbar" => "Show edit toolbar",
+"tog-rememberpassword" => "Recordar contrasigno inter sessiones (usa cookies)",
+"tog-editwidth" => "Cassa de redaction occupa tote le largor del fenestra",
+"tog-editondblclick" => "Duple clic pro modificar un pagina (usa JavaScript)",
+"tog-watchdefault" => "Poner articulos nove e modificate sub observation",
+"tog-minordefault" => "Marcar modificationes initialmente como minor",
+"tog-previewontop" => "Monstrar previsualisation ante le cassa de edition e non post illo",
+
+# dates
+#
+
+'sunday' => 'dominica',
+'monday' => 'lunedi',
+'tuesday' => 'martedi',
+'wednesday' => 'mercuridi',
+'thursday' => 'jovedi',
+'friday' => 'venerdi',
+'saturday' => 'sabbato',
+'january' => 'januario',
+'february' => 'februario',
+'march' => 'martio',
+'april' => 'april',
+'may_long' => 'maio',
+'june' => 'junio',
+'july' => 'julio',
+'august' => 'augusto',
+'september' => 'septembre',
+'october' => 'octobre',
+'november' => 'novembre',
+'december' => 'decembre',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'oct',
+'nov' => 'nov',
+'dec' => 'dec',
+
+
+# Bits of text used by many pages:
+#
+"mainpage" => "Frontispicio",
+"about" => "A proposito",
+"aboutsite" => "A proposito de {{SITENAME}}",
+"aboutpage" => "{{ns:project}}:A_proposito",
+"help" => "Adjuta",
+"helppage" => "{{ns:project}}:Adjuta",
+"bugreports" => "Reportos de disfunctiones",
+"bugreportspage" => "{{ns:project}}:Reportos_de_disfunctiones",
+"faq" => "Questiones frequente",
+"faqpage" => "{{ns:project}}:Questiones_frequente",
+"edithelp" => "Adjuta al edition",
+"edithelppage" => "{{ns:project}}:Como_editar_un_pagina",
+"cancel" => "Cancellar",
+"qbfind" => "Trovar",
+"qbbrowse" => "Foliar",
+"qbedit" => "Modificar",
+"qbpageoptions" => "Optiones de pagina",
+"qbpageinfo" => "Info del pagina",
+"qbmyoptions" => "Mi optiones",
+"mypage" => "Mi pagina",
+"mytalk" => "Mi discussion",
+"currentevents" => "Actualitates",
+"errorpagetitle" => "Error",
+"returnto" => "Retornar a $1.",
+"whatlinkshere" => "Referentias a iste pagina",
+"help" => "Adjuta",
+"search" => "Recercar",
+"searchbutton" => "Recercar",
+"go" => "Ir",
+'searcharticle' => "Ir",
+"history" => "Chronologia",
+"printableversion" => "Version imprimibile",
+"editthispage" => "Modificar iste pagina",
+"deletethispage" => "Eliminar iste pagina",
+"protectthispage" => "Proteger iste pagina",
+"unprotectthispage" => "Disproteger iste pagina",
+"newpage" => "Nove pagina",
+"talkpage" => "Discuter iste pagina",
+"articlepage" => "Vider article",
+"userpage" => "Vider pagina del usator",
+"projectpage" => "Vider metapagina",
+"imagepage" => "Vider pagina de imagine",
+"viewtalkpage" => "Vider discussion",
+"otherlanguages" => "Altere linguas",
+"redirectedfrom" => "(Redirigite de $1)",
+"lastmodifiedat" => "Ultime modification: $2, $1.",
+"viewcount" => "Iste pagina esseva accessate $1 vices.",
+"protectedpage" => "Pagina protegite",
+"nbytes" => "$1 bytes",
+"ok" => "OK",
+"retrievedfrom" => "Recuperate de \"$1\"",
+"newmessageslink" => "messages nove",
+
+# Main script and global functions
+#
+"nosuchaction" => "Action inexistente",
+"nosuchactiontext" => "Le action specificate in le URL non es
+recognoscite per le systema de Mediawiki.",
+"nosuchspecialpage" => "Pagina special inexistente",
+"nospecialpagetext" => "
+Tu demandava un pagina special que non es
+recognoscite per le systema de Mediawiki.",
+
+# General errors
+#
+"error" => "Error",
+"databaseerror" => "Error de base de datos",
+"dberrortext" => "Occurreva un error de syntaxe in le consulta al base de datos.
+Le ultime demanda inviate al base de datos esseva:
+<blockquote><tt>$1</tt></blockquote>
+de intra le function \"<tt>$2</tt>\".
+MySQL retornava le error \"<tt>$3: $4</tt>\".",
+"noconnect" => "Impossibile connecter al base de datos a $1",
+"nodb" => "Impossibile selectionar base de datos $1",
+"readonly" => "Base de datos blocate",
+"enterlockreason" => "Describe le motivo del blocage, includente un estimation
+de quando illo essera terminate",
+"readonlytext" => "Actualmente le base de datos de {{SITENAME}} es blocate pro nove
+entratas e altere modificationes, probabilemente pro mantenentia
+routinari del base de datos, post le qual illo retornara al normal.
+Le administrator responsabile dava iste explication:
+<p>$1",
+"missingarticle" => "Le base de datos non trovava le texto de un pagina
+que illo deberea haber trovate, a saper \"$1\".
+Isto non es un error de base de datos, mais probabilemente
+un disfunction in le systema.
+Per favor reporta iste occurrentia a un administrator,
+indicante le URL.",
+"internalerror" => "Error interne",
+"filecopyerror" => "Impossibile copiar file \"$1\" a \"$2\".",
+"filerenameerror" => "Impossibile renominar file \"$1\" a \"$2\".",
+"filedeleteerror" => "Impossibile eliminar file \"$1\".",
+"filenotfound" => "Impossibile trovar file \"$1\".",
+"unexpected" => "Valor impreviste: \"$1\"=\"$2\".",
+"formerror" => "Error: impossibile submitter formulario",
+"badarticleerror" => "Iste action non pote esser effectuate super iste pagina.",
+"cannotdelete" => "Impossibile eliminar le pagina o imagine specificate. (Illo pote ja haber essite eliminate per un altere persona.)",
+"badtitle" => "Titulo incorrecte",
+"badtitletext" => "Le titulo de pagina demandate esseva invalide, vacue, o
+un titulo interlinguistic o interwiki incorrectemente ligate.",
+"perfdisabled" => "Pardono! Iste functionalitate es temporarimente inactivate durante
+horas de grande affluentia de accessos pro motivo de performance;
+retorna inter 02:00 e 14:00 UTC e tenta de nove.",
+
+# Login and logout pages
+#
+"logouttitle" => "Fin de session",
+"logouttext" => "Tu claudeva tu session.
+Tu pote continuar a usar {{SITENAME}} anonymemente, o initiar un
+nove session como le mesme o como un altere usator.",
+
+"welcomecreation" => "<h2>Benvenite, $1!</h2>
+<p>Tu conto de usator esseva create.
+Non oblida personalisar {{SITENAME}} secundo tu preferentias.",
+
+"loginpagetitle" => "Aperir session",
+"yourname" => "Tu nomine de usator",
+"yourpassword" => "Tu contrasigno",
+"yourpasswordagain" => "Confirmar contrasigno",
+"remembermypassword" => "Recordar contrasigno inter sessiones.",
+"loginproblem" => "<b>Occurreva problemas pro initiar tu session.</b><br />Tenta de nove!",
+"alreadyloggedin" => "<strong>Usator $1, tu session ja es aperte!</strong><br />",
+
+"login" => "Aperir session",
+"userlogin" => "Aperir session",
+"logout" => "Clauder session",
+"userlogout" => "Clauder session",
+"createaccount" => "Crear nove conto",
+"badretype" => "Le duo contrasignos que tu scribeva non coincide.",
+"userexists" => "Le nomine de usator que tu selectionava ja es in uso. Per favor selectiona un nomine differente.",
+"youremail" => "Tu e-mail",
+"yournick" => "Tu pseudonymo (pro signaturas)",
+"loginerror" => "Error in le apertura del session",
+"noname" => "Tu non specificava un nomine de usator valide.",
+"loginsuccesstitle" => "Session aperte con successo",
+"loginsuccess" => "Tu es identificate in {{SITENAME}} como \"$1\".",
+"nosuchuser" => "Non existe usator registrate con le nomine \"$1\".
+Verifica le orthographia, o usa le formulario infra pro crear un nove conto de usator.",
+"wrongpassword" => "Le contrasigno que tu scribeva es incorrecte. Per favor tenta de nove.",
+"mailmypassword" => "Demandar un nove contrasigno via e-mail",
+"passwordremindertitle" => "Nove contrasigno in {{SITENAME}}",
+"passwordremindertext" => "Alcuno (probabilemente tu, con adresse de IP $1)
+
+demandava inviar te un nove contrasigno pro {{SITENAME}}.
+Le contrasigno pro le usator \"$2\" ora es \"$3\".
+Nos consilia que tu initia un session e cambia le contrasigno le plus tosto possibile.",
+"noemail" => "Non existe adresse de e-mail registrate pro le usator \"$1\".",
+"passwordsent" => "Un nove contrasigno esseva inviate al adresse de e-mail
+registrate pro \"$1\".
+Per favor initia un session post reciper lo.",
+
+# Edit pages
+#
+"summary" => "Summario",
+"minoredit" => "Iste es un modification minor",
+"watchthis" => "Poner iste articulo sub observation",
+"savearticle" => "Salvar articulo",
+"preview" => "Previsualisar",
+"showpreview" => "Monstrar previsualisation",
+"blockedtitle" => "Le usator es blocate",
+"blockedtext" => "Tu nomine de usator o adresse de IP ha essite blocate per $1.
+Le motivo presentate es iste:<br />''$2''<p>Tu pote contactar $1 o un del altere
+[[{{ns:project}}:administratores|administratores]] pro discuter le bloco.",
+"newarticle" => "(Nove)",
+"newarticletext" =>
+"Tu ha sequite un ligamine a un pagina que ancora non existe.
+Pro crear un nove pagina, comencia a scriber in le cassa infra.
+(Vide le [[{{ns:project}}:Adjuta|pagina de adjuta]] pro plus information.)
+Si tu es hic per error, simplemente clicca le button '''Retornar''' de tu navigator.",
+"anontalkpagetext" => "---- ''Iste es le pagina de discussion pro un usator anonyme qui ancora non ha create un conto o qui non lo usa. Consequentemente nos debe usar le [[adresse de IP]] numeric pro identificar le/la. Un tal adresse de IP pote esser usate in commun per varie personas. Si tu es un usator anonyme e senti que commentarios irrelevante ha essite dirigite a te, per favor [[Special:Userlogin|crea un conto o aperi un session]] pro evitar futur confusiones con altere usatores anonyme.''",
+"noarticletext" => "(Actualmente il non ha texto in iste pagina)",
+"updated" => "(Actualisate)",
+"note" => "<strong>Nota:</strong>",
+"previewnote" => "Rememora te que isto es solmente un previsualisation, tu modificationes ancora non ha essite salvate!",
+"previewconflict" => "Iste previsualisation reflecte le apparentia final del texto in le area de redaction superior
+si tu opta pro salvar lo.",
+"editing" => "Modification de $1",
+'editinguser' => "Modification de $1",
+"editconflict" => "Conflicto de edition: $1",
+"explainconflict" => "Alcuno ha modificate iste pagina post que tu
+ha comenciate a modificar lo.
+Le area de texto superior contine le texto del pagina tal como illo existe actualmente.
+Tu modificationes es monstrate in le area de texto inferior.
+Tu debera incorporar tu modificationes al texto existente.
+<b>Solmente</b> le texto del area superior essera salvate
+quando tu premera \"Salvar pagina\".<br />",
+"yourtext" => "Tu texto",
+"storedversion" => "Version immagazinate",
+"editingold" => "<strong>ADVERTIMENTO: In iste momento tu modifica
+un version obsolete de iste pagina.
+Si tu lo salvara, tote le modificationes facite post iste revision essera perdite.</strong>",
+"yourdiff" => "Differentias",
+/*"copyrightwarning" => "Nota que tote le contributiones a {{SITENAME}} es
+considerate public secundo le terminos del Licentia de Documentation Libere GNU
+(vide plus detalios in $1).
+Si tu non vole que tu scripto sia modificate impietosemente e redistribuite
+a voluntate, alora non lo edita hic.<br />
+Additionalmente, tu nos garanti que tu es le autor de tu contributiones,
+o que tu los ha copiate de un ressource libere de derectos.
+<strong>NON USA MATERIAL COPERITE PER DERECTOS DE AUTOR (COPYRIGHT) SIN AUTORISATION EXPRESSE!</strong>",*/
+"longpagewarning" => "ADVERTIMENTO: Iste pagina ha $1 kilobytes de longitude;
+alcun navigatores pote presentar problemas in editar
+paginas de approximatemente o plus de 32kb.
+Considera fragmentar le pagina in sectiones minor.",
+
+# History pages
+#
+"revhistory" => "Chronologia de versiones",
+"nohistory" => "Iste pagina non ha versiones precedente.",
+"revnotfound" => "Revision non trovate",
+"revnotfoundtext" => "Impossibile trovar le version anterior del pagina que tu ha demandate.
+Verifica le URL que tu ha usate pro accessar iste pagina.",
+"loadhist" => "Carga del chronologia del pagina",
+"currentrev" => "Revision currente",
+"revisionasof" => "Revision de $1",
+"cur" => "actu",
+"next" => "sequ",
+"last" => "prec",
+"orig" => "orig",
+"histlegend" => "Legenda: (actu) = differentia del version actual,
+(prec) = differentia con le version precedente, M = modification minor",
+
+# Diffs
+#
+"difference" => "(Differentia inter revisiones)",
+"loadingrev" => "carga del revision pro diff",
+"lineno" => "Linea $1:",
+"editcurrent" => "Modificar le version actual de iste pagina",
+
+# Search results
+#
+"searchresults" => "Resultatos del recerca",
+"searchresulttext" => "Pro plus information super le recerca de {{SITENAME}}, vide [[Project:Recerca|Recerca in {{SITENAME}}]].",
+"searchsubtitle" => "Pro le consulta \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Pro le consulta \"$1\"",
+"badquery" => "Consulta de recerca mal formate",
+"badquerytext" => "Impossibile processar tu consulta.
+Probabilemente tu ha tentate recercar un parola con minus
+de tres litteras de longitude, situation que le systema non
+permitte. Es equalmente possibile que tu ha committite un
+error syntactic in le consulta, per exemplo,
+\"pisce and and squama\".
+Reformula tu consulta.",
+"matchtotals" => "Le consulta \"$1\" coincide con le titulos de $2 articulos
+e le texto de $3 articulos.",
+"noexactmatch" => "Non existe un pagina con iste titulo exacte, io recurre al recerca de texto integral.",
+"titlematches" => "Coincidentias con titulos de articulos",
+"notitlematches" => "Necun coincidentia",
+"textmatches" => "Coincidentias con textos de articulos",
+"notextmatches" => "Necun coincidentia",
+"prevn" => "$1 precedentes",
+"nextn" => "$1 sequentes",
+"viewprevnext" => "Vider ($1) ($2) ($3).",
+"showingresults" => "Monstra de <b>$1</b> resultatos a partir de nº <b>$2</b>.",
+"nonefound" => "<strong>Nota</strong>: recercas frustrate frequentemente
+es causate per le inclusion de vocabulos commun como \"que\" e \"illo\",
+que non es includite in le indice, o per le specification de plure
+terminos de recerca (solmente le paginas que contine tote le terminos
+de recerca apparera in le resultato).",
+"powersearch" => "Recercar",
+"powersearchtext" => "
+Recerca in contextos :<br />
+$1<br />
+$2 Listar redireciones &nbsp; Recercar pro $3 $9",
+
+
+# Preferences page
+#
+"preferences" => "Preferentias",
+"prefsnologin" => "Session non aperte",
+"prefsnologintext" => "Tu debe [[Special:Userlogin|aperir un session]]
+pro definir tu preferentias.",
+"prefsreset" => "Tu preferentias salvate previemente ha essite restaurate.",
+"qbsettings" => "Configuration del barra de utensiles",
+"changepassword" => "Cambiar contrasigno",
+"skin" => "Apparentia",
+"math" => "Exhibition de formulas",
+"math_failure" => "Impossibile analysar",
+"math_unknown_error" => "error incognite",
+"math_unknown_function" => "function incognite",
+"math_lexing_error" => "error lexic",
+"math_syntax_error" => "error syntactic",
+"saveprefs" => "Salvar preferentias",
+"resetprefs" => "Restaurar preferentias",
+"oldpassword" => "Contrasigno actual",
+"newpassword" => "Nove contrasigno",
+"retypenew" => "Confirmar nove contrasigno",
+"textboxsize" => "Dimensiones del cassa de texto",
+"rows" => "Lineas",
+"columns" => "Columnas",
+"searchresultshead" => "Configuration del resultatos de recerca",
+"resultsperpage" => "Coincidentias per pagina",
+"contextlines" => "Lineas per coincidentia",
+"contextchars" => "Characteres de contexto per linea",
+"stubthreshold" => "Limite pro exhibition residual",
+"recentchangescount" => "Quantitate de titulos in modificationes recente",
+"savedprefs" => "Tu preferentias ha essite salvate.",
+"timezonetext" => "Scribe le differentia de horas inter tu fuso horari
+e illo del servitor (UTC).",
+"localtime" => "Hora local",
+"timezoneoffset" => "Differentia de fuso horari",
+
+# Recent changes
+#
+"changes" => "modificationes",
+"recentchanges" => "Modificationes recente",
+"recentchangestext" => "Seque le plus recente modificationes a {{SITENAME}} in iste pagina.
+[[{{ns:project}}:Benvenite,_novicios|Benvenite, novicios]]!
+Per favor lege equalmente iste paginas: [[{{ns:project}}:Questiones_frequente|Questiones frequente super {{SITENAME}}]],
+[[{{ns:project}}:Politicas e directivas|Politica de {{SITENAME}}]]
+(specialmente [[{{ns:project}}:Conventiones de nomenclatura|conventiones de nomenclatura]],
+[[{{ns:project}}:Neutralitate e objectivitate|neutralitate e objectivitate]]),
+e [[{{ns:project}}:Le passos false plus commun|le passos false plus commun]].
+
+Si tu vole que {{SITENAME}} habe successo, es multo importante que tu non
+include material protegite per [[{{ns:project}}:Copyright|derectos de autor]].
+Le aspectos legal connexe poterea prejudicar gravemente le projecto,
+alora per favor non lo face.",
+"rcnote" => "Infra es le <strong>$1</strong> ultime modificationes in le <strong>$2</strong> ultime dies.",
+"rcnotefrom" => "infra es le modificationes a partir de <b>$2</b> (usque a <b>$1</b>).",
+"rclistfrom" => "Monstrar nove modificationes a partir de $1",
+# "rclinks" => "Monstrar le $1 ultime modificationes in le $2 ultime horas / $3 ultime dias",
+"rclinks" => "Monstrar le $1 ultime modificationes in le $2 ultime days.",
+"diff" => "diff",
+"hist" => "prec",
+"hide" => "occultar",
+"show" => "monstrar",
+"minoreditletter" => "M",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => "Cargar file",
+"uploadbtn" => "Cargar file",
+"reupload" => "Recargar",
+"reuploaddesc" => "Retornar al formulario de carga.",
+"uploadnologin" => "Session non aperte",
+"uploadnologintext" => "Tu debe [[Special:Userlogin|aperir un session]]
+pro poter cargar files.",
+"uploaderror" => "Error de carga",
+"uploadtext" => "'''STOP!''' Ante cargar files al servitor,
+prende cognoscentia del
+[[Project:Image_use_policy|politica de {{SITENAME}} super le uso de imagines]],
+e assecura te de respectar lo.
+
+Pro vider o recercar imagines cargate previemente,
+vade al [[Special:Imagelist|lista de imagines cargate]].
+Cargas e eliminationes es registrate in le
+[[Project:Upload_log|registro de cargas]].
+
+Usa le formulario infra pro cargar nove files de imagine pro
+illustrar tu articulos.
+In le major parte del navigatores, tu videra un button \"Browse...\",
+que facera apparer le cassa de dialogo de apertura de files
+standard de tu systema de operation. Selectiona un file pro
+inserer su nomine in le campo de texto adjacente al button.
+Tu debe additionalmente marcar le quadrato con le qual tu
+declara que tu non viola derectos de autor per medio del carga
+del file.
+Preme le button \"Cargar\" pro initiar le transmission.
+Le carga pote prender alcun tempore si tu connexion al Internet
+es lente.
+
+Le formatos preferite es JPEG pro imagines photographic,
+PNG pro designos e altere imagines iconic, e OGG pro sonos.
+Per favor, attribue nomines descriptive a tu files pro evitar
+confusion.
+Pro includer le imagine in un articulo, usa un ligamine in
+le forma '''<nowiki>[[image:file.jpg]]</nowiki>''' o
+'''<nowiki>[[image:file.png|texto alternative]]</nowiki>''' o
+'''<nowiki>[[media:file.ogg]]</nowiki>''' pro sonos.
+
+Nota que, justo como occurre con le paginas de {{SITENAME}}, alteros
+pote modificar o eliminar le files cargate si illes considera que
+isto beneficia le encyclopedia, e tu pote haber tu derecto
+de carga blocate si tu abusa del systema.",
+"uploadlog" => "registro de cargas",
+"uploadlogpage" => "Registro_de_cargas",
+"uploadlogpagetext" => "Infra es un lista del plus recente cargas de files.
+Tote le tempores monstrate es in le fuso horari del servitor (UCT).
+<ul>
+</ul>",
+"filename" => "Nomine del file",
+"filedesc" => "Description",
+"copyrightpage" => "{{ns:project}}:Copyright",
+"copyrightpagename" => "{{SITENAME}} e derectos de autor (copyright)",
+"uploadedfiles" => "Files cargate",
+"minlength" => "Le nomines de imagines debe haber al minus tres litteras.",
+"badfilename" => "Le nomine del imagine esseva cambiate a \"$1\".",
+"badfiletype" => "\".$1\" non es un formato de file de imagine recommendate.",
+"largefile" => "Es recommendabile que le imagines non excede 100kb.",
+"successfulupload" => "Carga complete",
+"fileuploaded" => "File \"$1\" cargate sin problemas.
+Per favor clicca hic: ($2) pro accessar le pagina de description
+e fornir information super le file, tal como su origine,
+quando illo esseva create e per qui, e toto plus que tu sape
+a su proposito.",
+"uploadwarning" => "Advertimento de carga",
+"savefile" => "Salvar file",
+"uploadedimage" => "\"[[$1]]\" cargate",
+
+# Image list
+#
+"imagelist" => "Lista de imagines",
+"imagelisttext" => "Infra es un lista de $1 imagines ordinate $2.",
+"getimagelist" => "recuperation del lista de imagines",
+"ilsubmit" => "Recercar",
+"showlast" => "Monstrar le ultime $1 imagines ordinate $2.",
+"byname" => "per nomine",
+"bydate" => "per data",
+"bysize" => "per dimension",
+"imgdelete" => "elim",
+"imgdesc" => "desc",
+"imglegend" => "Legenda: (desc) = monstrar/modificar description del imagine.",
+"imghistory" => "Chronologia del imagine",
+"revertimg" => "rev",
+"deleteimg" => "elim",
+"deleteimgcompletely" => "elim",
+"imghistlegend" => "Legend: (actu) = iste es le imagine actual, (elim) = elimina
+iste version antique, (rev) = reverte a iste version antique.
+<br /><i>Clica super le data pro vider le imagine cargate in ille die.</i>",
+"imagelinks" => "Ligamines al imagine",
+"linkstoimage" => "Le paginas sequente se liga a iste imagine:",
+"nolinkstoimage" => "Necun pagina se liga a iste imagine.",
+
+# Statistics
+#
+"statistics" => "Statisticas",
+"sitestats" => "Statisticas de accesso",
+"userstats" => "Statisticas de usator",
+"sitestatstext" => "Le base de datos contine un total de <b>$1</b> paginas.
+Iste numero include paginas de \"discussion\", paginas super {{SITENAME}}, paginas de \"residuo\"
+minime, paginas de redirection, e alteres que probabilemente non se qualifica como articulos.
+A parte de istes, il ha <b>$2</b> paginas que probabilemente es
+articulos legitime.<p>
+Il habeva un total de <b>$3</b> visitas a paginas, e <b>$4</b> modificationes de paginas
+desde le actualisation del systema (20 de julio 2002).
+Isto representa un media de <b>$5</b> modificationes per pagina, e <b>$6</b> visitas per modification.",
+"userstatstext" => "Il ha <b>$1</b> usatores registrate,
+del quales <b>$2</b> es administratores (vide $3).",
+
+# Maintenance Page
+#
+"disambiguations" => "Paginas de disambiguation",
+"disambiguationspage" => "{{ns:project}}:Ligamines_a_paginas_de_disambiguation",
+"disambiguationstext" => "Le articulos sequente se liga a un <i>pagina de disambiguation</i>.
+Illos deberea ligar se directemente al topico appropriate.<br />
+Un pagina es tractate como un pagina de disambiguation si existe un ligamine
+a illo in $1. Ligamines de altere contextos <i>non</i> es listate hic.",
+"doubleredirects" => "Redirectiones duple",
+"doubleredirectstext" => "<b>Attention:</b> Iste lista pote continer items false.
+Illo generalmente significa que il ha texto additional con ligamines sub le prime #REDIRECT.<br />
+Cata linea contine ligamines al prime e secunde redirection, assi como le prime linea del
+secunde texto de redirection, generalmente exhibiente le articulo scopo \"real\",
+al qual le prime redirection deberea referer se.",
+"brokenredirects" => "Redirectiones van",
+"brokenredirectstext" => "Le redirectiones sequente se liga a articulos inexistente.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Paginas orphanas",
+"unusedimages" => "Imagines non usate",
+"popularpages" => "Paginas popular",
+"nviews" => "$1 visitas",
+"wantedpages" => "Paginas plus demandate",
+"nlinks" => "$1 ligamines",
+"allpages" => "Tote le paginas",
+"randompage" => "Pagina aleatori",
+"shortpages" => "Paginas curte",
+"longpages" => "Paginas longe",
+"listusers" => "Lista de usatores",
+"specialpages" => "Paginas special",
+"spheading" => "Paginas special",
+"recentchangeslinked" => "Modificationes correlate",
+"rclsub" => "(a paginas ligate a partir de \"$1\")",
+"newpages" => "Nove paginas",
+"movethispage" => "Mover iste pagina",
+"unusedimagestext" => "<p>Nota que altere sitos del web
+tal como le {{SITENAME}}s international pote ligar se a un imagine
+con un URL directe, e consequentemente illos pote esser listate
+hic malgrado esser in uso active.",
+"booksources" => "Fornitores de libros",
+"booksourcetext" => "Infra es un lista de ligamines a altere sitos que
+vende libros nove e usate, e pote haber information ulterior super
+libros que tu cerca.
+{{SITENAME}} non es associate a iste interprisas, e iste lista
+non debe esser interpretate como alcun appoio special.",
+
+# Email this user
+#
+"mailnologin" => "Necun adresse de invio",
+"mailnologintext" => "Tu debe [[Special:Userlogin|aperir un session]]
+e haber un adresse de e-mail valide in tu [[Special:Preferences|preferentias]]
+pro inviar e-mail a altere usatores.",
+"emailuser" => "Inviar e-mail a iste usator",
+"emailpage" => "Inviar e-mail al usator",
+"emailpagetext" => "Si iste usator forniva un adresse de e-mail valide in
+su preferentias de usator, le formulario infra le/la inviara un message.
+Le adresse de e-mail que tu forniva in tu preferentias de usator apparera
+como le adresse del expeditor del e-mail, a fin que le destinatario
+pote responder te.",
+"noemailtitle" => "Necun adresse de e-mail",
+"noemailtext" => "Iste usator non ha specificate un adresse de e-mail valide,
+o ha optate pro non reciper e-mail de altere usatores.",
+"emailfrom" => "De",
+"emailto" => "A",
+"emailsubject" => "Subjecto",
+"emailmessage" => "Message",
+"emailsend" => "Inviar",
+"emailsent" => "E-mail inviate",
+"emailsenttext" => "Tu message de e-mail ha essite inviate.",
+
+# Watchlist
+#
+"watchlist" => "Paginas sub observation",
+"nowatchlist" => "Tu non ha paginas sub observation.",
+"watchnologin" => "Session non aperte",
+"watchnologintext" => "Tu debe [[Special:Userlogin|aperir un session]]
+pro modificar tu lista de paginas sub observation.",
+"addedwatch" => "Ponite sub observation",
+"addedwatchtext" => "Le pagina \"$1\" es ora in tu <a href=\"" .
+ "{{localurle:Special:Watchlist}}\">lista de paginas sub observation</a>.
+Modificationes futur a iste pagina e su pagina de discussion associate essera listate la,
+e le pagina apparera <b>in nigretto</b> in le <a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">lista de modificationes recente</a> pro
+facilitar su identification.</p>
+
+<p>Si tu vole cessar le obsevation de iste pagina posteriormente, clicca \"Cancellar observation\" in le barra de navigation.",
+"removedwatch" => "Observation cancellate",
+"removedwatchtext" => "Le pagina \"$1\" non es plus sub observation.",
+"watchthispage" => "Poner iste pagina sub observation",
+"unwatchthispage" => "Cancellar observation",
+"notanarticle" => "Non es un articulo",
+
+# Delete/protect/revert
+#
+"deletepage" => "Eliminar pagina",
+"confirm" => "Confirmar",
+"confirmdelete" => "Confirmar elimination",
+"deletesub" => "(Elimination de \"$1\")",
+"confirmdeletetext" => "Tu es a puncto de eliminar permanentemente un pagina
+o imagine del base de datos, conjunctemente con tote su chronologia de versiones.
+Per favor, confirma que, si tu intende facer lo, tu comprende le consequentias,
+e tu lo face de accordo con [[{{ns:project}}:Policy]].",
+"actioncomplete" => "Action complete",
+"deletedtext" => "\"$1\" ha essite eliminate.
+Vide $2 pro un registro de eliminationes recente.",
+"deletedarticle" => "\"$1\" eliminate",
+"dellogpage" => "Registro_de_eliminationes",
+"dellogpagetext" => "Infra es un lista del plus recente eliminationes.
+Tote le horas es in le fuso horari del servitor (UTC).
+<ul>
+</ul>",
+"deletionlog" => "registro de eliminationes",
+"reverted" => "Revertite a revision anterior",
+"deletecomment" => "Motivo del elimination",
+"imagereverted" => "Reversion con successo a version anterior.",
+"rollback" => "Revocar modificationes",
+"rollbacklink" => "revocar",
+"cantrollback" => "Impossibile revocar le modification; le ultime contribuente es le unic autor de iste articulo.",
+"revertpage" => "Revertite al ultime modification per $1",
+
+# Undelete
+"undelete" => "Restaurar pagina eliminate",
+"undeletepage" => "Vider e restaurar paginas eliminate",
+"undeletepagetext" => "Le paginas sequente ha essite eliminate mais ancora es in le archivo e
+pote esser restaurate. Le archivo pote esser evacuate periodicamente.",
+"undeletearticle" => "Restaurar articulo eliminate",
+"undeleterevisions" => "$1 revisiones archivate",
+"undeletehistory" => "Si tu restaura un pagina, tote le revisiones essera restaurate al chronologia.
+Si un nove pagina con le mesme nomine ha essite create post le elimination, le revisiones
+restaurate apparera in le chronologia anterior, e le revision currente del pagina in vigor
+non essera automaticamente substituite.",
+"undeleterevision" => "Revision eliminate in $1",
+"undeletebtn" => "Restautar!",
+"undeletedarticle" => "\"$1\" restaurate",
+
+# Contributions
+#
+"contributions" => "Contributiones de usator",
+"mycontris" => "Mi contributiones",
+"contribsub" => "Pro $1",
+"nocontribs" => "Necun modification ha essite trovate secundo iste criterios.",
+"ucnote" => "Infra es le <b>$1</b> ultime modificationes de iste usator in le <b>$2</b> ultime dies.",
+"uclinks" => "Vider le $1 ultime modificationes; vider le $2 ultime dies.",
+"uctop" => " (alto)" ,
+
+# What links here
+#
+"whatlinkshere" => "Referentias a iste pagina",
+"notargettitle" => "Sin scopo",
+"notargettext" => "Tu non ha specificate un pagina o usator super le qual
+executar iste function.",
+"linklistsub" => "(Lista de ligamines)",
+"linkshere" => "Le paginas sequente se liga a iste pagina:",
+"nolinkshere" => "Necun pagina se liga a iste.",
+"isredirect" => "pagina de redirection",
+
+# Block/unblock IP
+#
+"blockip" => "Blocar adresse IP",
+"blockiptext" => "Usa le formulario infra pro blocar le accesso de scriptura
+a partir de un adresse IP specific.
+Isto debe esser facite solmente pro impedir vandalismo, e de
+accordo con le [[{{ns:project}}:Policy|politica de {{SITENAME}}]].
+Scribe un motivo specific infra (per exemplo, citante paginas
+specific que ha essite vandalisate).",
+"ipaddress" => "Adresse IP",
+"ipbreason" => "Motivo",
+"ipbsubmit" => "Blocar iste adresse",
+"badipaddress" => "Adresse IP mal formate.",
+"blockipsuccesssub" => "Blocage con successo",
+"blockipsuccesstext" => "Le adresse IP \"$1\" ha essite blocate.
+<br />Vide [[Special:Ipblocklist|Lista de IPs blocate]] pro revider le blocages.",
+"unblockip" => "Disblocar adresse IP",
+"unblockiptext" => "Usa le formulario infra pro restaurar le accesso de scriptura
+a un adresse de IP blocate previemente.",
+"ipusubmit" => "Disbloca iste adresse",
+"ipblocklist" => "Lista de adresses IP blocate",
+"blocklistline" => "$1, $2 ha blockate $3 ($4)",
+"blocklink" => "blocar",
+"unblocklink" => "disblocar",
+"contribslink" => "contributiones",
+
+# Developer tools
+#
+"lockdb" => "Blocar base de datos",
+"unlockdb" => "Disblocar base de datos",
+"lockdbtext" => "Le blocage del base de datos suspendera le capacitate de tote
+le usatores de modificar paginas, modificar lor preferentias e listas de paginas sub observation,
+e altere actiones que require modificationes in le base de datos.
+Per favor confirma que iste es tu intention, e que tu disblocara le
+base de datos immediatemente post completar tu mantenentia.",
+"unlockdbtext" => "Le disblocage del base de datos restaurara le capacitate de tote
+le usatores de modificar paginas, modificar lor preferentias e listas de paginas sub observation,
+e altere actiones que require modificationes in le base de datos.
+Per favor confirma que iste es tu intention.",
+"lockconfirm" => "Si, io realmente vole blocar le base de datos.",
+"unlockconfirm" => "Si, io realmente vole disblocar le base de datos.",
+"lockbtn" => "Blocar base de datos",
+"unlockbtn" => "Disblocar base de datos",
+"locknoconfirm" => "Tu non ha marcate le quadrato de confirmation.",
+"lockdbsuccesssub" => "Base de datos blocate con successo",
+"unlockdbsuccesssub" => "Base de datos disblocate con successo",
+"lockdbsuccesstext" => "Le base de datos de {{SITENAME}} ha essite blocate.
+<br />Rememora te de disblocar lo post completar tu mantenentia.",
+"unlockdbsuccesstext" => "Le base de datos de {{SITENAME}} ha essite disblocate.",
+
+# Move page
+#
+"movepage" => "Mover pagina",
+"movepagetext" => "Per medio del formulario infra tu pote renominar un pagina,
+movente tote su chronologia al nove nomine.
+Le titulo anterior devenira un pagina de redirection al nove titulo.
+Le ligamines al pagina anterior non essera modificate;
+assecura te de verificar le apparition de redirectiones duple o van.
+Tu es responsabile pro assecurar que le ligamines continua a punctar a ubi illos deberea.
+
+Nota que le pagina '''non''' essera movite si ja existe un pagina
+sub le nove titulo, salvo si illo es vacue o un redirection e non
+ha un chronologia de modificationes passate. Isto significa que tu
+pote renominar un pagina a su titulo original si tu lo ha renominate
+erroneemente, e que tu non pote superscriber un pagina existente.
+
+<b>ADVERTIMENTO!</b>
+Isto pote esser un cambio drastic e inexpectate pro un pagina popular;
+per favor assecura te que tu comprende le consequentias de isto
+ante proceder.",
+"movepagetalktext" => "Le pagina de discussion associate, si existe, essera automaticamente movite conjunctemente con illo '''a minus que''':
+*Tu move le pagina trans contextos,
+*Un pagina de discussion non vacue ja existe sub le nove nomine, o
+*Tu dismarca le quadrato infra.
+
+Il tal casos, tu debera mover o fusionar le pagina manualmente si desirate.",
+"movearticle" => "Mover pagina",
+"movenologin" => "Session non aperte",
+"movenologintext" => "Tu debe esser un usator registrate e [[Special:Userlogin|aperir un session]]
+pro mover un pagina.",
+"newtitle" => "Al nove titulo",
+"movepagebtn" => "Mover pagina",
+"pagemovedsub" => "Pagina movite con successo",
+"pagemovedtext" => "Pagina \"[[$1]]\" movite a \"[[$2]]\".",
+"articleexists" => "Un pagina con iste nomine ja existe, o le
+nomine selectionate non es valide.
+Per favor selectiona un altere nomine.",
+"talkexists" => "Le pagina mesme ha essite movite con successo, mais le
+pagina de discussion associate non ha essite movite proque ja existe un sub le
+nove titulo. Per favor fusiona los manualmente.",
+"movedto" => "movite a",
+"movetalk" => "Mover le pagina de \"discussion\" tamben, si applicabile.",
+"talkpagemoved" => "Le pagina de discussion correspondente tamben ha essite movite.",
+"talkpagenotmoved" => "Le pagina de discussion correspondente <strong>non</strong> ha essite movite.",
+
+# Math
+
+'mw_math_png' => "Sempre produce PNG",
+'mw_math_simple' => "HTML si multo simple, alteremente PNG",
+'mw_math_html' => "HTML si possibile, alteremente PNG",
+'mw_math_source' => "Lassa lo como TeX (pro navigatores in modo texto)",
+'mw_math_modern' => "Recommendate pro navigatores moderne",
+'mw_math_mathml' => 'MathML',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesId.php b/languages/messages/MessagesId.php
new file mode 100644
index 000000000000..f283694ec37d
--- /dev/null
+++ b/languages/messages/MessagesId.php
@@ -0,0 +1,2011 @@
+<?php
+/** Indonesian (Bahasa Indonesia)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Tidak ada', 'Tetap sebelah kiri', 'Tetap sebelah kanan', 'Mengambang sebelah kiri'
+);
+
+$skinNames = array(
+ 'standard' => 'Standar',
+);
+
+$bookstoreList = array(
+ 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1',
+ 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
+ 'Bhinneka.com bookstore' => 'http://www.bhinneka.com/Buku/Engine/search.asp?fisbn=$1',
+ 'Gramedia Cyberstore (via Google)' => 'http://www.google.com/search?q=%22ISBN+:+$1%22+%22product_detail%22+site:www.gramediacyberstore.com+OR+site:www.gramediaonline.com+OR+site:www.kompas.com&hl=id',
+ 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Istimewa',
+ NS_MAIN => '',
+ NS_TALK => 'Pembicaraan',
+ NS_USER => 'Pengguna',
+ NS_USER_TALK => 'Pembicaraan_Pengguna',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Pembicaraan_$1',
+ NS_IMAGE => 'Berkas',
+ NS_IMAGE_TALK => 'Pembicaraan_Berkas',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Pembicaraan_MediaWiki',
+ NS_TEMPLATE => 'Templat',
+ NS_TEMPLATE_TALK => 'Pembicaraan_Templat',
+ NS_HELP => 'Bantuan',
+ NS_HELP_TALK => 'Pembicaraan_Bantuan',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Pembicaraan_Kategori'
+);
+
+$namespaceAliases = array(
+ 'Gambar_Pembicaraan' => NS_IMAGE_TALK,
+ 'MediaWiki_Pembicaraan' => NS_MEDIAWIKI_TALK,
+ 'Templat_Pembicaraan' => NS_TEMPLATE_TALK,
+ 'Bantuan_Pembicaraan' => NS_HELP_TALK,
+ 'Kategori_Pembicaraan' => NS_CATEGORY_TALK,
+ 'Gambar' => NS_IMAGE,
+ 'Pembicaraan_Gambar' => NS_IMAGE_TALK,
+ 'Bicara' => NS_TALK,
+ 'Bicara_Pengguna' => NS_USER_TALK,
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$datePreferences = false;
+
+$messages = array(
+
+# User preference toggles
+'tog-underline' => 'Garis bawahi pranala',
+'tog-highlightbroken' => 'Format pranala patah <a href="" class="new">seperti ini</a> (pilihan: seperti ini<a href="" class="internal">?</a>).',
+'tog-justify' => 'Ratakan paragraf',
+'tog-hideminor' => 'Sembunyikan suntingan kecil dalam perubahan terbaru',
+'tog-extendwatchlist' => 'Tampilkan daftar pantauan yang menunjukkan semua perubahan',
+'tog-usenewrc' => 'Tampilan perubahan terbaru alternatif (JavaScript)',
+'tog-numberheadings' => 'Beri nomor judul secara otomatis',
+'tog-showtoolbar' => "Perlihatkan <i>toolbar</i> (batang alat) penyuntingan",
+'tog-editondblclick' => 'Sunting halaman dengan klik ganda (JavaScript)',
+'tog-editsection'=> 'Fungsikan penyuntingan sub-bagian melalui pranala [sunting]',
+'tog-editsectiononrightclick' => 'Fungsikan penyuntingan sub-bagian dengan klik-kanan pada judul bagian (JavaScript)',
+'tog-showtoc' => 'Perlihatkan daftar isi (untuk halaman yang mempunyai lebih dari 3 sub-bagian)',
+'tog-rememberpassword' => 'Ingat kata sandi pada setiap sesi',
+'tog-editwidth' => 'Kotak sunting berukuran maksimum',
+'tog-watchcreations' => 'Tambahkan halaman yang saya buat ke daftar pantauan',
+'tog-watchdefault' => 'Tambahkan halaman yang saya sunting ke dalam daftar pantauan',
+'tog-watchmoves' => 'Tambahkan halaman yang saya pindahkan ke dalam daftar pantauan',
+'tog-watchdeletion' => 'Tambahkan halaman yang saya hapus ke daftar pantauan',
+'tog-minordefault' => 'Tandai semua suntingan sebagai suntingan kecil secara baku',
+'tog-previewontop' => 'Perlihatkan pratayang sebelum kotak sunting dan tidak sesudahnya',
+'tog-previewonfirst' => 'Perlihatkan pratayang pada suntingan pertama',
+'tog-nocache' => 'Matikan <em>cache</em> halaman',
+'tog-enotifwatchlistpages' => 'Surat-e saya jika suatu halaman yang saya pantau berubah',
+'tog-enotifusertalkpages' => 'Surat-e saya jika halaman bicara saya berubah',
+'tog-enotifminoredits' => 'Surat-e saya juga pada perubahan kecil',
+'tog-enotifrevealaddr' => 'Berikan surat-e saya pada surat notifikasi',
+'tog-shownumberswatching' => 'Tunjukkan jumlah pemantau',
+'tog-fancysig' => 'Paraf kasar (tanpa pranala otomatis)',
+'tog-externaleditor' => 'Gunakan perangkat lunak pengolah kata luar',
+'tog-externaldiff' => 'Gunakan perangkat lunak luar untuk melihat perbedaan suntingan',
+'tog-showjumplinks' => 'Aktifkan pranala pembantu "langsung ke"',
+'tog-uselivepreview' => 'Gunakan pratayang langsung (JavaScript) (eksperimental)',
+'tog-forceeditsummary' => 'Ingatkan saya bila kotak ringkasan suntingan masih kosong',
+'tog-watchlisthideown' => 'Sembunyikan suntingan saya dari daftar pantauan',
+'tog-watchlisthidebots' => 'Sembunyikan suntingan bot dari daftar pantauan',
+'tog-watchlisthideminor' => 'Sembunyikan suntingan kecil dari daftar pantauan',
+'tog-nolangconversion' => 'Matikan konversi varian',
+'tog-ccmeonemails' => 'Kirimkan saya salinan surat-e yang saya kirimkan ke orang lain',
+
+'underline-always' => 'Selalu',
+'underline-never' => 'Tidak',
+'underline-default' => 'Sesuai konfigurasi penjelajah web',
+
+'skinpreview' => '(Pratayang)',
+
+# dates
+'sunday' => 'Minggu',
+'monday' => 'Senin',
+'tuesday' => 'Selasa',
+'wednesday' => 'Rabu',
+'thursday' => 'Kamis',
+'friday' => "Jumat",
+'saturday' => 'Sabtu',
+'sun' => 'Min',
+'mon' => 'Sen',
+'tue' => 'Sel',
+'wed' => 'Rab',
+'thu' => 'Kam',
+'fri' => 'Jum',
+'sat' => 'Sab',
+'january' => 'Januari',
+'february' => 'Februari',
+'march' => 'Maret',
+'april' => 'April',
+'may_long' => 'Mei',
+'june' => 'Juni',
+'july' => 'Juli',
+'august' => 'Agustus',
+'september' => 'September',
+'october' => 'Oktober',
+'november' => 'November',
+'december' => 'Desember',
+'january-gen' => 'Januari',
+'february-gen' => 'Februari',
+'march-gen' => 'Maret',
+'april-gen' => 'April',
+'may-gen' => 'Mei',
+'june-gen' => 'Juni',
+'july-gen' => 'Juli',
+'august-gen' => 'Agustus',
+'september-gen' => 'September',
+'october-gen' => 'Oktober',
+'november-gen' => 'November',
+'december-gen' => 'Desember',
+'jan' => 'Jan',
+'feb' => 'Feb',
+'mar' => 'Mar',
+'apr' => 'Apr',
+'may' => 'Mei',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Agu',
+'sep' => 'Sep',
+'oct' => 'Okt',
+'nov' => 'Nov',
+'dec' => 'Des',
+
+# Bits of text used by many pages:
+#
+'categories' => 'Kategori',
+'pagecategories' => 'Kategori', # no need for plural
+"category_header" => "Artikel dalam kategori \"$1\"",
+"subcategories" => "Subkategori",
+'category-media-header' => 'Media dalam kategori "$1"',
+
+"mainpage" => "Halaman Utama",
+"mainpagetext" => "Perangkat lunak wiki berhasil dipasang.",
+'mainpagedocfooter' => "Silakan baca [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] untuk informasi penggunaan perangkat lunak wiki
+
+== Memulai penggunaan ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Daftar pengaturan preferensi]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Milis rilis MediaWiki]",
+
+'portal' => 'Portal komunitas',
+'portal-url' => 'Project:Portal komunitas',
+"about" => "Tentang",
+"aboutsite" => "Tentang {{SITENAME}}",
+"aboutpage" => "Project:Tentang",
+'article' => 'Artikel',
+"help" => "Bantuan",
+"helppage" => "{{ns:help}}:Isi",
+"bugreports" => "Laporan bug",
+"bugreportspage" => "Project:Laporan bug",
+'sitesupport' => 'Sumbangan dana',
+"sitesupport-url" => "Project:Sumbangan dana",
+"faq" => "FAQ",
+"faqpage" => "Project:FAQ",
+"edithelp" => "Bantuan penyuntingan",
+"newwindow" => "(buka di jendela baru)",
+"edithelppage" => "{{ns:help}}:Penyuntingan",
+"cancel" => "Batalkan",
+"qbfind" => "Cari",
+"qbbrowse" => "Panduan arah",
+"qbedit" => "Sunting",
+"qbpageoptions" => "Halaman ini",
+"qbpageinfo" => "Konteks halaman",
+"qbmyoptions" => "Halaman saya",
+"qbspecialpages" => "Halaman istimewa",
+"moredotdotdot" => "Lainnya...",
+"mypage" => "Halaman saya",
+"mytalk" => "Pembicaraan saya",
+"anontalk" => "Pembicaraan IP ini",
+'navigation' => 'Panduan arah',
+
+# Metadata in edit box
+'metadata_help' => 'Metadata (lihat [[{{ns:project}}:Metadata]] untuk penjelasan lanjut):',
+
+"currentevents" => "Peristiwa terkini",
+'currentevents-url' => 'Peristiwa terkini',
+
+"disclaimers" => "Penyangkalan",
+"disclaimerpage" => "Project:Penyangkalan umum",
+'privacy' => 'Kebijakan kerahasiaan',
+'privacypage' => 'Project:Kebijakan kerahasiaan',
+"errorpagetitle" => "Kesalahan",
+"returnto" => "Kembali ke $1.",
+"tagline" => "Dari {{SITENAME}}",
+"whatlinkshere" => "Pranala ke halaman ini",
+"help" => "Bantuan",
+"search" => "Cari",
+"searchbutton" => "Cari",
+"go" => "Tuju ke",
+'searcharticle' => "Tuju ke",
+"history" => "Versi terdahulu",
+'history_short' => 'Versi terdahulu',
+'updatedmarker' => 'diubah sejak kunjungan terakhir saya',
+'info_short' => 'Informasi',
+"printableversion" => "Versi cetak",
+'permalink' => 'Pranala permanen',
+'print' => 'Cetak',
+'edit' => 'Sunting',
+"editthispage" => "Sunting halaman ini",
+'delete' => 'Hapus',
+"deletethispage" => "Hapus halaman ini",
+'undelete_short' => 'Batal hapus $1 suntingan', # no need for plural
+'protect' => 'Lindungi',
+"protectthispage" => "Lindungi halaman ini",
+'unprotect' => 'Ubah perlindungan',
+"unprotectthispage" => "Ubah perlindungan halaman ini",
+"newpage" => "Halaman baru",
+"talkpage" => "Diskusikan halaman ini",
+'specialpage' => 'Halaman istimewa',
+'personaltools' => 'Peralatan pribadi',
+"postcomment" => "Kirim komentar",
+"articlepage" => "Lihat artikel",
+'talk' => 'Diskusi',
+'views' => 'Tampilan',
+'toolbox' => 'Kotak peralatan',
+"userpage" => "Lihat halaman pengguna",
+"projectpage" => "Lihat halaman proyek",
+"imagepage" => "Lihat halaman berkas",
+'mediawikipage' => 'Lihat halaman pesan sistem',
+'templatepage' => 'Lihat halaman templat',
+'viewhelppage' => 'Lihat halaman bantuan',
+'categorypage' => 'Lihat halaman kategori',
+"viewtalkpage" => "Lihat diskusi",
+"otherlanguages" => "Bahasa lain",
+"redirectedfrom" => "(Dialihkan dari $1)",
+'redirectpagesub' => 'Halaman peralihan',
+"lastmodifiedat" => "Halaman ini terakhir diubah pada $2, $1.",
+"viewcount" => "Halaman ini telah diakses sebanyak $1 kali.<br />",
+"copyright" => "Seluruh teks tersedia dalam naungan $1.",
+"protectedpage" => "Halaman yang dilindungi",
+'jumpto' => 'Langsung ke:',
+'jumptonavigation' => 'panduan arah',
+'jumptosearch' => 'cari',
+
+'badaccess' => 'Kesalahan hak akses',
+'badaccess-group0' => 'Anda tidak diizinkan untuk melakukan tindakan yang Anda minta.',
+'badaccess-group1' => 'Tindakan yang Anda minta dibatasi untuk pengguna kelompok $1.',
+'badaccess-group2' => 'Tindakan yang Anda minta dibatasi untuk pengguna dalam kelompok $1.',
+'badaccess-groups' => 'Tindakan yang Anda minta dibatasi untuk pengguna dalam kelompok $1.',
+
+'versionrequired' => 'Dibutuhkan MediaWiki versi $1',
+'versionrequiredtext' => 'MediaWiki versi $1 dibutuhkan untuk menggunakan halaman ini. Lihat [[{{ns:special}}:Version]]',
+
+"ok" => "OK",
+
+'pagetitle' => '$1 - {{SITENAME}}',
+
+"retrievedfrom" => "Diperoleh dari \"$1\"",
+'youhavenewmessages' => 'Anda mempunyai $1 ($2).',
+"newmessageslink" => "pesan baru",
+'newmessagesdifflink' => 'perubahan terakhir',
+"editsection" => "sunting",
+"editold" => "sunting",
+'editsectionhint' => 'Sunting bagian: $1',
+"toc" => "Daftar isi",
+"showtoc" => "tampilkan",
+"hidetoc" => "sembunyikan",
+"thisisdeleted" => "Lihat atau kembalikan $1?",
+'viewdeleted' => 'Lihat $1?',
+'restorelink' => '$1 suntingan yang telah dihapus', # no need for plural
+'feedlinks' => 'Asupan:',
+'feed-invalid' => 'Tipe permintaan asupan tidak tepat.',
+'feed-atom' => 'Atom',
+'feed-rss' => 'RSS',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Artikel',
+'nstab-user' => 'Halaman pengguna',
+'nstab-media' => 'Halaman media',
+'nstab-special' => 'Istimewa',
+'nstab-project' => 'Halaman proyek',
+'nstab-image' => 'Berkas',
+'nstab-mediawiki' => 'Pesan sistem',
+'nstab-template' => 'Templat',
+'nstab-help' => 'Bantuan',
+'nstab-category' => 'Kategori',
+
+# Main script and global functions
+#
+"nosuchaction" => "Tidak ada tindakan tersebut",
+"nosuchactiontext" => "Tindakan yang dispesifikasikan oleh URL tersebut tidak dikenal oleh wiki.",
+"nosuchspecialpage" => "Tidak ada halaman istimewa tersebut",
+"nospecialpagetext" => "Anda telah meminta halaman istimewa yang tidak dikenal oleh wiki.",
+
+# General errors
+#
+"error" => "Kesalahan",
+"databaseerror" => "Kesalahan basis data",
+"dberrortext" => "Ada kesalahan sintaks pada permintaan basis data. Kesalahan ini mungkin menandakan adanya ''bug'' dalam perangkat lunak. Permintaan basis data yang terakhir adalah: <blockquote><tt>$1</tt></blockquote> dari dalam fungsi \"<tt>$2</tt>\". Kesalahan MySQL \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Ada kesalahan sintaks pada permintaan basis data. Permintaan basis data yang terakhir adalah: \"$1\" dari dalam fungsi \"$2\". Kesalahan MySQL \"$3: $4\".",
+'noconnect' => 'Maaf! Wiki mengalami masalah teknis dan tidak dapat menghubungi basis data.<br />$1',
+"nodb" => "Tidak dapat memilih basis data $1",
+"cachederror" => "Berikut ini adalah salinan <em>cache</em> dari halaman yang diminta, yang mungkin tidak up-to-date.",
+'laggedslavemode' => 'Peringatan: Halaman mungkin tidak berisi perubahan terbaru.',
+"readonly" => "Basis data dikunci",
+"enterlockreason" => "Masukkan alasan penguncian, termasuk perkiraan kapan kunci akan dibuka",
+"readonlytext" => "Basis data sedang dikunci terhadap masukan baru. Pengurus yang melakukan penguncian memberikan penjelasan sebagai berikut: <p>$1",
+"missingarticle" => "Basis data tidak menemukan teks bagi halaman yang seharusnya mempunyai teks, yaitu halaman \"$1\".
+
+Ini biasanya disebabkan karena diff yang kadaluwarsa atau karena pranala lama kepada halaman telah dihapus.
+
+Jika ini bukan sebabnya, Anda mungkin menemukan bug dalam perangkat lunak. Silakan laporkan hal ini kepada pengurus, dengan mencantumkan URL halaman yang bermasalah tersebut",
+'readonly_lag' => 'Basis data telah dikunci otomatis selagi basis data sekunder melakukan sinkronisasi dengan basis data utama',
+"internalerror" => "Kesalahan internal",
+"filecopyerror" => "Tidak dapat menyalin berkas \"$1\" ke \"$2\".",
+"filerenameerror" => "Tidak dapat mengubah nama berkas \"$1\" menjadi \"$2\".",
+"filedeleteerror" => "Tidak dapat menghapus berkas \"$1\".",
+"filenotfound" => "Tidak dapat menemukan berkas \"$1\".",
+"unexpected" => "Nilai di luar jangkauan: \"$1\"=\"$2\".",
+"formerror" => "Kesalahan: Tidak dapat mengirimkan formulir",
+"badarticleerror" => "Tindakan ini tidak dapat dilaksanakan di halaman ini.",
+"cannotdelete" => "Tidak dapat menghapus halaman atau berkas yang diminta.",
+"badtitle" => "Judul tidak sah",
+"badtitletext" => "Judul halaman yang diminta tidak sah, kosong, atau judul antarbahasa atau antarwiki yang salah sambung.",
+"perfdisabled" => "Maaf! Fitur ini dimatikan sementara karena memperlambat basis data hingga tidak ada yang dapat menggunakan wiki ini.",
+"perfdisabledsub" => "Ini adalah salinan tersimpan dari $1:",
+"perfcached" => "Data berikut ini diambil dari <em>cache</em> dan mungkin bukan data mutakhir:",
+'perfcachedts' => 'Data berikut ini diambil dari <em>cache</em>, dan terakhir diperbarui pada $1.',
+'querypage-no-updates' => 'Pemutakhiran dari halaman ini sedang dimatikan. Data yang ada di sini saat ini tidak akan dimuat ulang.',
+"wrong_wfQuery_params" => "Parameter salah ke wfQuery()<br />Fungsi: $1<br />Permintaan: $2",
+"viewsource" => "Lihat sumber",
+'viewsourcefor' => 'dari $1',
+'protectedpagetext' => 'Halaman ini telah dikunci untuk menghindari penyuntingan.',
+'viewsourcetext' => 'Anda dapat melihat atau menyalin sumber halaman ini:',
+'protectedinterface' => 'Halaman ini berisi teks antarmuka untuk digunakan oleh perangkat lunak dan telah dikunci untuk menghindari kesalahan.',
+'editinginterface' => "'''Peringatan:''' Anda menyunting halaman yang digunakan untuk menyediakan teks antarmuka dengan perangkat lunak. Perubahan teks ini akan mempengaruhi tampilan pada pengguna lain.",
+'sqlhidden' => '(Permintaan SQL disembunyikan)',
+
+# Login and logout pages
+#
+"logouttitle" => "Keluar log pengguna",
+"logouttext" => "Anda telah keluar log dari sistem. Anda dapat terus menggunakan {{SITENAME}} secara anonim, atau Anda dapat masuk log lagi sebagai pengguna yang sama atau pengguna yang lain. Perhatikan bahwa beberapa halaman mungkin masih terus menunjukkan bahwa Anda masih masuk log sampai Anda membersihkan <em>cache</em> penjelajah web Anda",
+
+"welcomecreation" => "== Selamat datang, $1! ==
+
+Akun Anda telah dibuat. Jangan lupa mengatur konfigurasi {{SITENAME}} Anda.",
+
+"loginpagetitle" => "Masuk log pengguna",
+"yourname" => "Nama pengguna",
+"yourpassword" => "Kata sandi",
+"yourpasswordagain" => "Ulangi kata sandi",
+"remembermypassword" => "Ingat kata sandi",
+'yourdomainname' => 'Domain Anda',
+'externaldberror' => 'Telah terjadi kesalahan otentikasi basis data eksternal atau Anda tidak diizinkan melakukan kemaskini terhadap akun eksternal Anda.',
+"loginproblem" => "<strong>Ada masalah dengan proses masuk log Anda.</strong><br />Silakan coba lagi!",
+"alreadyloggedin" => "<strong>Pengguna $1, Anda sudah masuk log!</strong><br />",
+
+"login" => "Masuk log",
+"loginprompt" => "Anda harus mengaktifkan ''cookies'' untuk dapat masuk log ke {{SITENAME}}.",
+"userlogin" => "Masuk log / buat akun",
+"logout" => "Keluar log",
+"userlogout" => "Keluar log",
+"notloggedin" => "Belum masuk log",
+'nologin' => 'Belum mempunyai nama pengguna? $1.',
+'nologinlink' => 'Daftarkan akun baru',
+"createaccount" => "Buat akun baru",
+'gotaccount' => 'Sudah terdaftar sebagai pengguna? $1.',
+'gotaccountlink' => 'Masuk log',
+"createaccountmail" => "melalui surat-e",
+"badretype" => "Kata sandi yang Anda masukkan salah.",
+"userexists" => "Nama pengguna yang Anda masukkan telah dipakai. Silakan pilih nama yang lain.",
+"youremail" => "Surat elektronik *:",
+'username' => 'Nama pengguna:',
+'uid' => 'ID pengguna:',
+"yourrealname" => "Nama asli *:",
+'yourlanguage' => 'Bahasa antarmuka:',
+'yourvariant' => 'Varian bahasa',
+"yournick" => "Nama samaran (untuk tanda tangan):",
+'badsig' => 'Tanda tangan teks murni tak tepat; periksa tag HTML.',
+'email' => 'Surat elektronik',
+'prefs-help-email-enotif' => 'Alamat ini juga digunakan untuk mengirim surat-e notifikasi pada Anda jika Anda memilih pilihan tersebut.',
+'prefs-help-realname' => '* <strong>Nama asli</strong> (tidak wajib): jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan atas hasil kerja Anda.',
+'loginerror' => 'Kesalahan masuk log',
+'prefs-help-email' => '* <strong>Surat elektronik</strong> (tidak wajib): Memungkinkan orang lain untuk menghubungi Anda melalui situs tanpa perlu memberikan alamat email Anda kepada mereka, dan juga dapat digunakan untuk mengirimkan kata sandi baru jika Anda lupa kata sandi Anda.',
+"nocookiesnew" => "Akun pengguna telah dibuat, tetapi Anda belum masuk log. {{SITENAME}} menggunakan ''cookies'' untuk log pengguna. ''Cookies'' pada penjelajah web Anda dimatikan. Silakan aktifkan dan masuk log kembali dengan nama pengguna dan kata sandi Anda.",
+"nocookieslogin" => "{{SITENAME}} menggunakan ''cookies'' untuk log penggunanya. ''Cookies'' pada penjelajah web Anda dimatikan. Silakan aktifkan dan coba lagi.",
+"noname" => "Nama pengguna yang Anda masukkan tidak sah.",
+"loginsuccesstitle" => "Berhasil masuk log",
+"loginsuccess" => "'''Anda sekarang masuk log di {{SITENAME}} sebagai \"$1\".'''",
+"nosuchuser" => "Tidak ada pengguna dengan nama \"$1\". Periksalah ejaan Anda, atau gunakan formulir di bawah ini untuk membuka akun baru.",
+'nosuchusershort' => "Tidak ada pengguna dengan nama \"$1\". Periksalah ejaan Anda.",
+'nouserspecified' => 'Anda harus memasukkan nama pengguna.',
+"wrongpassword" => "Kata sandi yang Anda masukkan salah. Silakan coba lagi.",
+'wrongpasswordempty' => 'Anda tidak memasukkan kata sandi. Silakan coba lagi.',
+"mailmypassword" => "Kirimkan kata sandi baru",
+"passwordremindertitle" => "Peringatan kata sandi dari {{SITENAME}}",
+"passwordremindertext" => "Seseorang (mungkin Anda, dari alamat IP $1) meminta kami mengirimkan kata sandi yang baru untuk {{SITENAME}} ($4). Kata sandi untuk pengguna \"$2\" sekarang adalah \"$3\". Anda disarankan segera masuk log dan mengganti kata sandi.",
+
+"noemail" => "Tidak ada alamat surat-e yang tercatat untuk pengguna \"$1\".",
+"passwordsent" => "Kata sandi baru telah dikirimkan ke surat-e yang didaftarkan untuk \"$1\". Silakan masuk log kembali setelah menerima surat-e tersebut.",
+'blocked-mailpassword' => 'Alamat IP Anda diblokir dari penyuntingan dan karenanya tidak diizinkan menggunakan fungsi pengingat kata sandi untuk mencegah penyalahgunaan.',
+'eauthentsent' => 'Sebuah surat elektronik untuk konfirmasi telah dikirim ke alamat surat elektronik Anda. Anda harus mengikuti instruksi di dalam surat elektronik tersebut untuk melakukan konfirmasi bahwa alamat tersebut adalah benar kepunyaan Anda. {{SITENAME}} tidak akan mengaktifkan fitur surat elektronik jika langkah ini belum dilakukan.',
+'throttled-mailpassword' => 'Suatu pengingat kata sandi telah dikirimkan dalam $1 jam terakhir. Untuk menghindari penyalahgunaan, hanya satu kata sandi yang akan dikirimkan setiap $1 jam.',
+"mailerror" => "Kesalahan dalam mengirimkan surat-e: $1",
+'acct_creation_throttle_hit' => 'Maaf, Anda telah membuat $1 akun. Anda tidak dapat membuat akun lagi.',
+'emailauthenticated' => 'Alamat surat-e Anda telah dikonfirmasi pada $1.',
+'emailnotauthenticated' => 'Alamat surat-e Anda belum dikonfirmasi. Sebelum dikonfirmasi Anda tidak bisa menggunakan fitur surat elektronik.',
+'noemailprefs' => 'Anda harus memasukkan suatu alamat surat-e untuk dapat menggunakan fitur ini.',
+'emailconfirmlink' => 'Konfirmasikan alamat surat-e Anda',
+'invalidemailaddress' => 'Alamat surat-e ini tidak dapat diterima karena formatnya tidak sesuai. Harap masukkan alamat surat-e dalam format yang benar atau kosongkan isian tersebut.',
+'accountcreated' => 'Akun dibuat',
+'accountcreatedtext' => 'Akun pengguna untuk $1 telah dibuat.',
+
+# Password reset dialog
+'resetpass' => 'Atur ulang kata sandi akun',
+'resetpass_announce' => 'Anda telah masuk log dengan kode sementara yang dikirim melalui surat-e. Untuk melanjutkan, Anda harus memasukkan kata sandi baru di sini:',
+'resetpass_text' => "<!-- Tambahkan teks di sini -->",
+'resetpass_header' => 'Atur ulang kata sandi',
+'resetpass_submit' => 'Atur kata sandi dan masuk log',
+'resetpass_success' => 'Kata sandi Anda telah berhasil diubah! Sekarang memproses masuk log Anda...',
+'resetpass_bad_temporary' => 'Kata sandi sementara salah. Anda mungkin pernah berhasil mengganti kata sandi Anda atau telah meminta kata sandi baru.',
+'resetpass_forbidden' => 'Kata sandi tidak dapat diubah di wiki ini',
+'resetpass_missing' => 'Data formulir tak dikenali.',
+
+# Edit page toolbar
+"bold_sample" => "Teks ini akan dicetak tebal",
+"bold_tip" => "Cetak tebal",
+"italic_sample" => "Teks ini akan dicetak miring",
+"italic_tip" => "Cetak miring",
+"link_sample" => "Judul pranala",
+"link_tip" => "Pranala internal",
+"extlink_sample" => "http://www.contoh.com/ judul pranala",
+"extlink_tip" => "Pranala luar (jangan lupa awalan http:// )",
+"headline_sample" => "Teks judul",
+"headline_tip" => "Judul aras 2",
+"math_sample" => "Masukkan rumus di sini",
+"math_tip" => "Rumus matematika (LaTeX)",
+"nowiki_sample" => "Teks ini tidak akan diformat",
+"nowiki_tip" => "Abaikan pemformatan wiki",
+"image_sample" => "Contoh.jpg",
+"image_tip" => "Cantumkan berkas",
+"media_sample" => "Contoh.ogg",
+"media_tip" => "Pranala berkas media",
+"sig_tip" => "Tanda tangan Anda dengan tanda waktu",
+"hr_tip" => "Garis horisontal",
+
+# Edit pages
+#
+"summary" => "Ringkasan",
+"subject" => "Subjek/judul",
+"minoredit" => "Ini adalah suntingan kecil.",
+"watchthis" => "Pantau artikel ini",
+"savearticle" => "Simpan halaman",
+"preview" => "Pratayang",
+"showpreview" => "Lihat pratayang",
+'showlivepreview' => 'Pratayang langsung',
+'showdiff' => 'Perlihatkan perubahan',
+'anoneditwarning' => 'Anda tidak terdaftar masuk. Alamat IP Anda akan tercatat dalam sejarah (versi terdahulu) halaman ini.',
+'missingsummary' => "'''Peringatan:''' Anda tidak memasukkan ringkasan penyuntingan. Jika Anda kembali menekan tombol Simpan, suntingan Anda akan disimpan tanpa ringkasan penyuntingan.",
+'missingcommenttext' => 'Harap masukkan komentar di bawah ini.',
+'missingcommentheader' => "'''Peringatan:''' Anda belum memberikan subjek atau judul untuk komentar Anda. Jika Anda kembali menekan Simpan, suntingan Anda akan disimpan tanpa komentar tersebut.",
+'summary-preview' => 'Pratayang ringkasan',
+'subject-preview' => 'Pratayang subyek/tajuk',
+"blockedtitle" => "Pengguna diblokir",
+'blockedtext' => "<big>'''Nama pengguna atau alamat IP Anda telah diblokir.'''</big>
+
+Blokir dilakukan oleh $1. Alasan yang diberikan adalah ''$2''.
+
+Anda dapat menghubungi $1 atau [[{{ns:project}}:Pengurus|pengurus lainnya]] untuk membicarakan hal ini.
+
+Anda tidak dapat menggunakan fitur 'Kirim surat-e pengguna ini' kecuali Anda telah memasukkan alamat surat-e yang sah di [[{{ns:project}}:Preferences|preferensi]] Anda.
+
+Alamat IP Anda adalah $3, dan ID pemblokiran adalah $5. Tolong sertakan salah satu atau kedua informasi ini pada setiap pertanyaan yang Anda buat",
+'blockedoriginalsource' => "Isi sumber '''$1''' ditunjukkan berikut ini:",
+'blockededitsource' => "Teks '''suntingan Anda''' terhadap '''$1''' ditunjukkan berikut ini:",
+"whitelistedittitle" => "Perlu masuk log untuk menyunting",
+"whitelistedittext" => "Anda harus $1 untuk dapat menyunting artikel.",
+"whitelistreadtitle" => "Perlu masuk log untuk membaca",
+"whitelistreadtext" => "Anda harus [[{{ns:special}}:Userlogin|masuk log]] untuk dapat membaca artikel.",
+"whitelistacctitle" => "Anda tidak diperbolehkan untuk membuat akun",
+"whitelistacctext" => "Untuk dapat membuat akun dalam Wiki ini, Anda harus [[{{ns:special}}:Userlogin|login]] dan mempunyai izin yang tepat.",
+'confirmedittitle' => 'Konfirmasi surat-e diperlukan untuk melakukan penyuntingan',
+'confirmedittext' => 'Anda harus mengkonfirmasikan dulu alamat surat-e Anda sebelum menyunting halaman. Harap masukkan dan validasikan alamat surat-e Anda sebelum melakukan penyuntingan. Alamat surat-e dapat diubah melalui [[{{ns:special}}:Preferences|halaman preferensi]]',
+"loginreqtitle" => "Harus masuk log",
+'loginreqlink' => 'masuk log',
+"loginreqpagetext" => "Anda harus $1 untuk dapat melihat halaman lainnya.",
+"accmailtitle" => "Kata sandi telah terkirim.",
+"accmailtext" => "Kata sandi untuk '$1' telah dikirimkan ke $2.",
+"newarticle" => "(Baru)",
+"newarticletext" => "Anda mengikuti pranala ke halaman yang belum tersedia. Untuk membuat halaman tersebut, ketiklah isi halaman di kotak di bawah ini (lihat [[{{ns:help}}:Isi|halaman bantuan]] untuk informasi lebih lanjut). Jika Anda tanpa sengaja sampai ke halaman ini, klik tombol '''back''' di penjelajah web anda.",
+
+"anontalkpagetext" => "---- ''Ini adalah halaman diskusi seorang pengguna anonim yang belum membuat akun atau tidak menggunakannya. Karena ia tidak membuat akun, kami terpaksa harus memakai alamat IP-nya untuk mengenalinya. Alamat IP seperti ini dapat dipakai oleh beberapa pengguna yang berbeda. Jika Anda adalah seorang pengguna anonim dan merasa mendapatkan komentar-komentar miring, silakan [[{{ns:special}}:Userlogin|membuat akun atau masuk log]] untuk menghindari kerancuan dengan pengguna anonim lain di lain waktu.''",
+'noarticletext' => 'Saat ini tidak ada teks dalam halaman ini. Anda dapat [[{{ns:special}}:Search/{{PAGENAME}}|melakukan pencarian untuk judul halaman ini]] di halaman-halaman lain atau [{{fullurl:{{FULLPAGENAME}}|action=edit}} sunting halaman ini].',
+
+'clearyourcache' => "'''Catatan:''' Setelah menyimpan preferensi, Anda perlu membersihkan <em>cache</em> penjelajah web Anda untuk melihat perubahan. '''Mozilla / Firefox / Safari:''' tekan ''Ctrl-Shift-R'' (''Cmd-Shift-R'' pada Apple Mac); '''IE:''' tekan ''Ctrl-F5''; '''Konqueror:''': tekan ''F5''; '''Opera''' bersihkan <em>cache</em> melalui menu ''Tools→Preferences''.",
+'usercssjsyoucanpreview' => "<strong>Tips:</strong> Gunakan tombol 'Lihat pratayang' untuk menguji CSS/JS baru Anda sebelum menyimpannya.",
+'usercsspreview' => "'''Ingatlah bahwa yang Anda lihat hanyalah pratayang CSS Anda, dan bahwa pratayang tersebut belum disimpan!'''",
+'userjspreview' => "'''Ingatlah bahwa yang Anda lihat hanyalah pratayang JavaScript Anda, dan bahwa pratayang tersebut belum disimpan!'''",
+'userinvalidcssjstitle' => "'''Peringatan:''' Kulit \"$1\" tidak ditemukan. Harap diingat bahwa halaman .css dan .js menggunakan huruf kecil, contoh {{ns:user}}:Foo/monobook.css dan bukannya {{ns:user}}:Foo/Monobook.css.",
+"updated" => "(Diperbarui)",
+"note" => "<strong>Catatan:</strong>",
+"previewnote" => "Ingatlah bahwa ini hanyalah pratayang yang belum disimpan!",
+'session_fail_preview' => '<strong>Maaf, kami tidak dapat mengolah suntingan Anda akibat terhapusnya data sesi. Silakan coba sekali lagi. Jika masih tidak berhasil, cobalah keluar log dan masuk log kembali.</strong>',
+"previewconflict" => "Pratayang ini mencerminkan teks pada bagian atas kotak suntingan teks sebagaimana akan terlihat bila Anda menyimpannya.",
+'session_fail_preview_html' => '<strong>Maaf! Kami tidak dapat memproses suntingan Anda karena hilangnya data sesi.</strong>
+
+\'\'Karena wiki ini mengizinkan penggunaan HTML mentah, pratayang disembunyikan sebagai pencegahan terhadap serangan JavaScript.\'\'
+
+<strong>Jika ini merupakan upaya suntingan yang sahih, silakan coba lagi. Jika masih tetap tidak berhasil, cobalah keluar log dan masuk kembali.</strong>',
+'importing' => 'Sedang mengimpor $1',
+"editing" => "Menyunting $1",
+'editinguser' => "Menyunting $1",
+'editingsection' => 'Menyunting $1 (bagian)',
+'editingcomment' => 'Menyunting $1 (komentar)',
+"editconflict" => "Konflik penyuntingan: $1",
+"explainconflict" => "Orang lain telah menyunting halaman ini sejak Anda mulai menyuntingnya. Bagian atas teks ini mengandung teks halaman saat ini. Perubahan yang Anda lakukan ditunjukkan pada bagian bawah teks. Anda hanya perlu menggabungkan perubahan Anda dengan teks yang telah ada. <strong>Hanya</strong> teks pada bagian atas halamanlah yang akan disimpan apabila Anda menekan \"Simpan halaman\".<p>",
+"yourtext" => "Teks Anda",
+"storedversion" => "Versi tersimpan",
+'nonunicodebrowser' => "<strong>PERINGATAN: Penjelajah web Anda tidak mendukung Unicode, silakan ganti penjelajah web Anda sebelum menyunting artikel.</strong>",
+"editingold" => "'''Peringatan:''' Anda menyunting revisi lama suatu halaman. Jika Anda menyimpannya, perubahan-perubahan yang dibuat sejak revisi ini akan hilang.",
+"yourdiff" => "Perbedaan",
+"copyrightwarning" => "Perhatikan bahwa semua sumbangan terhadap {{SITENAME}} dianggap dilisensikan di bawah lisensi $2 (lihat $1 untuk informasi lebih lanjut). Jika Anda tidak ingin tulisan Anda disunting dan disebarkan ke halaman web yang lain, jangan kirimkan artikel Anda ke sini.<br />Anda juga berjanji bahwa ini adalah hasil karya Anda sendiri, atau disalin dari sumber milik umum atau sumber bebas yang lain. <strong>JANGAN KIRIMKAN KARYA YANG DILINDUNGI HAK CIPTA TANPA IZIN!</strong>",
+'copyrightwarning2' => "Perhatikan bahwa semua sumbangan terhadap {{SITENAME}} dapat disunting, diubah, atau dihapus oleh penyumbang lainnya. Jika Anda tidak ingin tulisan Anda disunting orang lain, jangan kirimkan artikel Anda ke sini.<br />Anda juga berjanji bahwa ini adalah hasil karya Anda sendiri, atau disalin dari sumber milik umum atau sumber bebas yang lain (lihat $1 untuk informasi lebih lanjut). <strong>JANGAN KIRIMKAN KARYA YANG DILINDUNGI HAK CIPTA TANPA IZIN!</strong>",
+"longpagewarning" => "'''PERINGATAN: Halaman ini panjangnya adalah $1 kilobita; beberapa penjelajah web mungkin mengalami masalah dalam menyunting halaman yang panjangnya 32 kb atau lebih. Harap pertimbangkan untuk memecah halaman menjadi beberapa bagian yang lebih kecil.'''",
+'longpageerror' => "<strong>KESALAHAN: Teks yang Anda kirimkan sebesar $1 kilobita, yang berarti lebih besar dari jumlah maksimum $2 kilobita. Teks tidak dapat disimpan.</strong>",
+"readonlywarning" => "<strong>PERINGATAN: Basis data sedang dikunci karena pemeliharaan, sehingga saat ini Anda tidak akan dapat menyimpan hasil penyuntingan Anda. Anda mungkin perlu memindahkan hasil penyuntingan Anda ini ke tempat lain untuk disimpan belakangan.</strong>",
+"protectedpagewarning" => "<strong>PERINGATAN: Halaman ini telah dikunci sehingga hanya pemakai dengan hak akses pengurus saja yang dapat menyuntingnya.</strong>",
+'semiprotectedpagewarning' => "'''Catatan:''' Halaman ini sedang dilindungi, sehingga hanya pengguna terdaftar yang bisa menyuntingnya.",
+'templatesused' => 'Templat yang digunakan di halaman ini:',
+'templatesusedpreview' => 'Templat yang digunakan di pratayang ini:',
+'templatesusedsection' => 'Templat yang digunakan di bagian ini:',
+'template-protected' => '(dilindungi)',
+'template-semiprotected' => '(semi-perlindungan)',
+'edittools' => '<!-- Teks di sini akan dimunculkan dibawah isian suntingan dan pemuatan.-->',
+'nocreatetitle' => 'Pembuatan halaman baru dibatasi',
+'nocreatetext' => 'Situs ini membatasi kemampuan membuat halaman baru. Anda dapat kembali dan menyunting halaman yang telah ada, atau silakan [[{{ns:special}}:Userlogin|masuk log atau mendaftar]]',
+
+# "Undo" feature
+'undo-success' => 'Suntingan ini telah dibatalkan. Tolong konfirmasi dan simpan perubahan di bawah.',
+'undo-failure' => 'Suntingan ini tidak dapat dibatalkan karena konflik penyuntingan antara.',
+'undo-summary' => 'Pembatalan revisi $1 by [[Special:Contributions/$2]] ([[User talk:$2]])',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'Akun tak dapat dibuat',
+'cantcreateaccounttext' => 'Pembuatan akun dari alamat IP ini (<b>$1</b>) diblokir.
+Hal ini mungkin disebabkan adanya vandalisme berulang yang berasal dari sekolah atau penyedia jasa Internet Anda.',
+
+# History pages
+#
+"revhistory" => "Sejarah revisi",
+'viewpagelogs' => 'Lihat log halaman ini',
+"nohistory" => "Tidak ada sejarah penyuntingan untuk halaman ini",
+"revnotfound" => "Revisi tidak ditemukan",
+"revnotfoundtext" => "Revisi lama halaman yang Anda minta tidak dapat ditemukan. Silakan periksa URL yang digunakan untuk mengakses halaman ini.",
+"loadhist" => "Memuat halaman sejarah",
+"currentrev" => "Revisi sekarang",
+"revisionasof" => "Revisi per $1",
+'revision-info' => 'Revisi per $1; $2',
+'previousrevision' => '← Revisi sebelumnya',
+'nextrevision' => 'Revisi selanjutnya →',
+'currentrevisionlink' => 'Revisi sekarang',
+"cur" => "skr",
+"next" => "selanjutnya",
+"last" => "akhir",
+"orig" => "asli",
+"histlegend" => "Cara membandingkan: tandai ''radio button'' versi-versi yang ingin dibandingkan, lalu tekan ENTER atau tombol di bawah.<br />Keterangan: (skr) = perbedaan dengan versi sekarang, (akhir) = perbedaan dengan versi sebelumnya, m = suntingan kecil",
+'deletedrev' => '[dihapus]',
+'histfirst' => 'Paling lama',
+'histlast' => 'Paling baru',
+'rev-deleted-comment' => '(komentar dihapus)',
+'rev-deleted-user' => '(nama pengguna dihapus)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">Riwayat revisi halaman ini telah dihapus dari arsip publik. Detil mungkin tersedia di [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} log penghapusan].</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">Riwayat revisi halaman ini telah dihapus dari arsip publik. Sebagai seorang pengurus situs, Anda dapat melihatnya; detil mungkin tersedia di [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} log penghapusan].</div>',
+'rev-delundel' => 'tampilkan/sembunyikan',
+
+'history-feed-title' => 'Riwayat revisi',
+'history-feed-description' => 'Riwayat revisi halaman ini di wiki',
+'history-feed-item-nocomment' => '$1 pada $2', # user at time
+'history-feed-empty' => 'Halaman yang diminta tak ditemukan. Kemungkinan telah dihapus dari wiki, atau diberi nama baru. Coba [[{{ns:special}}:Search|lakukan pencarian di wiki]] untuk halaman baru yang relevan.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Hapus/batal hapus revisi',
+'revdelete-nooldid-title' => 'Target revisi tak ditemukan',
+'revdelete-nooldid-text' => 'Anda belum memberikan target revisi untuk menjalankan fungsi ini.',
+'revdelete-selected' => 'Revisi terpilih dari [[:$1]]:',
+'revdelete-text' => "Revisi yang telah dihapus akan tetap muncul di halaman versi terdahulu, tapi teks isi tidak bisa diakses publik.
+
+Pengurus lain akan dapat mengakses isi tersebunyi dan dapat membatalkan penghapusan melalui antarmuka yang sama, kecuali jika ada pembatasan lain yang dibuat oleh operator situs",
+'revdelete-legend' => 'Atur batasan revisi:',
+'revdelete-hide-text' => 'Sembunyikan teks revisi',
+'revdelete-hide-comment' => 'Tampilkan/sembunyikan ringkasan suntingan',
+'revdelete-hide-user' => 'Sembunyikan nama pengguna/IP penyunting',
+'revdelete-hide-restricted' => 'Terapkan pembatasan bagi pengurus dan pengguna lainnya',
+'revdelete-log' => 'Log ringkasan:',
+'revdelete-submit' => 'Terapkan pada revisi terpilih',
+'revdelete-logentry' => 'ubah tampilan revisi untuk [[$1]]',
+
+# Diffs
+#
+"difference" => "(Perbedaan antarrevisi)",
+"loadingrev" => "memuat revisi untuk dibandingkan",
+"lineno" => "Baris $1:",
+"editcurrent" => "Sunting versi sekarang dari halaman ini",
+'selectnewerversionfordiff' => 'Pilih sebuah versi yang lebih baru untuk perbandingan',
+'selectolderversionfordiff' => 'Pilih sebuah versi yang lebih lama untuk perbandingan',
+'compareselectedversions' => 'Bandingkan versi terpilih',
+'editundo' => 'batalkan',
+'diff-multi' => "({{plural:$1|Satu|$1}} revisi antara tak ditampilkan.)",
+
+# Search results
+#
+"searchresults" => "Hasil pencarian",
+"searchresulttext" => "Untuk informasi lebih lanjut tentang pencarian di {{SITENAME}}, lihat [[{{ns:project}}:Pencarian|Melakukan pencarian di {{SITENAME}}]].",
+'searchsubtitle' => "Anda mencari '''[[:$1]]'''",
+'searchsubtitleinvalid' => "Anda mencari '''$1'''",
+"badquery" => "Format permintaan pencarian salah",
+"badquerytext" => "Kami tidak dapat memproses permintaan Anda. Hal ini mungkin disebabkan karena Anda mencoba mencari kata yang panjangnya kurang dari tiga huruf, yang masih belum didukung oleh sistem ini. Hal ini juga dapat disebabkan oleh kesalahan pengetikan ekspresi, misalnya \"fish and and scales\". Silakan coba permintaan yang lain.",
+"matchtotals" => "Permintaan \"$1\" cocok dengan $2 judul halaman dan teks dari $3 artikel.",
+'noexactmatch' => "'''Tidak ada halaman yang berjudul \"$1\".''' Anda dapat [[:$1|membuat halaman ini]].",
+"titlematches" => "Judul artikel yang sama",
+"notitlematches" => "Tidak ada judul halaman yang cocok",
+"textmatches" => "Teks artikel yang cocok",
+"notextmatches" => "Tidak ada teks halaman yang cocok",
+"prevn" => "$1 sebelumnya",
+"nextn" => "$1 selanjutnya",
+"viewprevnext" => "Lihat ($1) ($2) ($3).",
+"showingresults" => "Di bawah ini ditampilkan <strong>$1</strong> hasil, dimulai dari #<strong>$2</strong>.",
+"showingresultsnum" => "Di bawah ini ditampilkan <strong>$3</strong> hasil, dimulai dari #<strong>$2</strong>.",
+"nonefound" => "'''Catatan''': Kegagalan pencarian biasanya disebabkan oleh pencarian kata-kata umum, seperti \"have\" dan \"from\", yang biasanya tidak diindeks, atau dengan menentukan lebih dari satu aturan pencarian (hanya halaman yang mengandung semua aturan pencarianlah yang akan ditampilkan dalam hasil pencarian)",
+"powersearch" => "Cari",
+'powersearchtext' => "Cari dalam ruang nama:<br />$1<br />$2 Juga tampilkan peralihan<br />Cari $3 $9",
+"searchdisabled" => '<p style="margin: 1.5em 2em 1em">Mesin pencari {{SITENAME}} sementara dimatikan karena masalah kinerja. Anda dapat mencari melalui Google untuk sementara waktu. <span style="font-size: 89%; display: block; margin-left: .2em">Indeks Google untuk {{SITENAME}} mungkin belum diperbaharui. Jika istilah pencarian berisi garis bawah, gantikan dengan spasi.</span></p>',
+"blanknamespace" => "(Utama)",
+
+# Preferences page
+#
+"preferences" => "Preferensi",
+'mypreferences' => 'Preferensi saya',
+"prefsnologin" => "Belum masuk log",
+"prefsnologintext" => "Anda harus [[{{ns:special}}:Userlogin|masuk log]] untuk menetapkan preferensi Anda.",
+
+"prefsreset" => "Preferensi telah dikembalikan ke konfigurasi baku.",
+"qbsettings" => "Pengaturan quickbar",
+"changepassword" => "Ganti kata sandi",
+"skin" => "Kulit",
+"math" => "Penggambaran math",
+"dateformat" => "Format tanggal",
+'datedefault' => 'Tak ada preferensi',
+'datetime' => 'Tanggal dan waktu',
+"math_failure" => "Gagal memparse",
+"math_unknown_error" => "Kesalahan yang tidak diketahui",
+"math_unknown_function" => "fungsi yang tidak diketahui",
+"math_lexing_error" => "kesalahan lexing",
+"math_syntax_error" => "kesalahan sintaks",
+"math_image_error" => "Konversi PNG gagal; periksa apakah latex, dvips, gs, dan convert terinstal dengan benar",
+"math_bad_tmpdir" => "Tidak dapat menulisi atau membuat direktori sementara math",
+"math_bad_output" => "Tidak dapat menulisi atau membuat direktori keluaran math",
+"math_notexvc" => "Executable texvc hilang; silakan lihat math/README untuk cara konfigurasi.",
+'prefs-personal' => 'Profil',
+'prefs-rc' => 'Perubahan terbaru',
+'prefs-watchlist' => 'Daftar pantauan',
+'prefs-watchlist-days' => 'Jumlah hari untuk ditampilkan di daftar pantauan:',
+'prefs-watchlist-edits' => 'Jumlah hari untuk ditampilkan di daftar pantauan yang lebih lengkap:',
+'prefs-misc' => 'Lain-lain',
+"saveprefs" => "Simpan preferensi",
+"resetprefs" => "Pengaturan baku",
+"oldpassword" => "Kata sandi lama",
+"newpassword" => "Kata sandi baru",
+"retypenew" => "Ketik ulang kata sandi baru",
+"textboxsize" => "Penyuntingan",
+"rows" => "Baris",
+"columns" => "Kolom",
+"searchresultshead" => "Pencarian",
+"resultsperpage" => "Hasil per halaman",
+"contextlines" => "Baris ditampilkan per hasil",
+"contextchars" => "Karakter untuk konteks per baris",
+"stubthreshold" => "Ambang batas tampilan rintisan",
+"recentchangescount" => "Jumlah judul dalam perubahan terbaru",
+"savedprefs" => "Preferensi Anda telah disimpan",
+'timezonelegend' => 'Zona waktu',
+"timezonetext" => "Masukkan perbedaan waktu (dalam jam) antara waktu setempat dengan waktu server (UTC).",
+"localtime" => "Waktu setempat",
+"timezoneoffset" => "Perbedaan",
+"servertime" => "Waktu server sekarang adalah",
+"guesstimezone" => "Isikan dari penjelajah web",
+'allowemail' => 'Ijinkan pengguna lain mengirim surat-e',
+"defaultns" => "Cari dalam ruang nama berikut ini secara baku:",
+'default' => 'baku',
+'files' => 'Berkas',
+
+# User rights
+'userrights-lookup-user' => 'Mengatur grup pengguna',
+'userrights-user-editname' => 'Masukkan nama pengguna:',
+'editusergroup' => 'Sunting kelompok pengguna',
+
+# user groups editing
+'userrights-editusergroup' => 'Sunting grup pengguna',
+'saveusergroups' => 'Simpan kelompok pengguna',
+'userrights-groupsmember' => 'Anggota dari:',
+'userrights-groupsavailable' => 'Grup yang tersedia:',
+'userrights-groupshelp' => "Pilih grup yang Anda ingin hapus dari atau tambahkan pada pengguna. Grup yang tak dipilih tak akan diganti. Anda dapat membatalkan pilihan dengan menekan tombol CTRL + Klik kiri",
+
+# Groups
+'group' => 'Grup:',
+'group-bot' => 'Bot',
+'group-sysop' => 'Pengurus',
+'group-bureaucrat' => 'Birokrat',
+'group-all' => '(semua)',
+
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Pengurus',
+'group-bureaucrat-member' => 'Birokrat',
+
+'grouppage-bot' => '{{ns:project}}:Bot',
+'grouppage-sysop' => '{{ns:project}}:Pengurus',
+'grouppage-bureaucrat' => '{{ns:project}}:Birokrat',
+
+# Recent changes
+#
+"changes" => "perubahan",
+"recentchanges" => "Perubahan terbaru",
+
+'recentchangestext' => 'Temukan perubahan terbaru dalam wiki di halaman ini.,',
+'recentchanges-feed-description' => 'Temukan perubahan terbaru dalam wiki di asupan ini.',
+'rcnote' => "Di bawah ini adalah <strong>$1</strong> perubahan terbaru dalam <strong>$2</strong> hari terakhir sampai $3.",
+"rcnotefrom" => "Di bawah ini adalah perubahan sejak <strong>$2</strong> (ditampilkan sampai <strong>$1</strong> perubahan).",
+"rclistfrom" => "Perlihatkan perubahan terbaru sejak $1",
+'rcshowhideminor' => '$1 suntingan kecil',
+'rcshowhidebots' => '$1 bot',
+'rcshowhideliu' => '$1 pengguna masuk log',
+'rcshowhideanons' => '$1 pengguna anon',
+'rcshowhidepatr' => '$1 suntingan terpatroli',
+'rcshowhidemine' => '$1 suntingan saya',
+"rclinks" => "Perlihatkan $1 perubahan terbaru dalam $2 hari terakhir<br />$3",
+"diff" => "beda",
+"hist" => "versi terdahulu",
+"hide" => "Sembunyikan",
+"show" => "Tampilkan",
+"minoreditletter" => "m",
+"newpageletter" => "B",
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 pemantau]',
+'rc_categories' => 'Batasi sampai kategori (dipisah dengan "|")',
+'rc_categories_any' => 'Apapun',
+
+# Upload
+#
+"upload" => "Pemuatan",
+"uploadbtn" => "Muatkan berkas",
+"reupload" => "Muat ulang",
+"reuploaddesc" => "Kembali ke formulir pemuatan",
+"uploadnologin" => "Belum masuk log",
+"uploadnologintext" => "Anda harus [[{{ns:special}}:Userlogin|masuk log]] untuk dapat memuatkan berkas.",
+'upload_directory_read_only' => 'Direktori pemuatan ($1) tidak dapat ditulis oleh server web.',
+"uploaderror" => "Kesalahan pemuatan",
+'uploadtext' => "Gunakan isian di bawah untuk memuat berkas. Gunakan [[{{ns:special}}:Imagelist|daftar berkas]] atau [[{{ns:special}}:Log/upload|log pemuatan]] untuk menampilkan atau mencari berkas atau gambar yang telah dimuat sebelumnya.
+
+Untuk menampilkan atau menyertakan berkas atau gambar pada suatu halaman, gunakan pranala dengan format
+'''<nowiki>[[{{ns:image}}:Berkas.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:Berkas.png|teks alternatif]]</nowiki>''' atau
+'''<nowiki>[[{{ns:media}}:Berkas.ogg]]</nowiki>''' untuk langsung menuju berkas yang dimaksud.",
+"uploadlog" => "log pemuatan",
+"uploadlogpage" => "Log pemuatan",
+"uploadlogpagetext" => "Di bawah ini adalah log pemuatan berkas. Semua waktu yang ditunjukkan adalah waktu server (UTC).",
+"filename" => "Nama berkas",
+"filedesc" => "Ringkasan",
+'fileuploadsummary' => 'Ringkasan:',
+"filestatus" => "Status hak cipta",
+"filesource" => "Sumber",
+"copyrightpage" => "{{NS:PROJECT}}:Hak cipta",
+"copyrightpagename" => "Hak cipta {{SITENAME}}",
+"uploadedfiles" => "Berkas yang telah dimuat",
+'ignorewarning' => 'Abaikan peringatan dan langsung simpan berkas.',
+'ignorewarnings' => 'Abaikan peringatan apapun',
+"minlength" => "Nama berkas sekurang-kurangnya harus tiga huruf.",
+'illegalfilename' => 'Nama berkas "$1" mengandung aksara yang tidak diperbolehkan ada dalam judul halaman. Silakan ubah nama berkas tersebut dan cobalah memuatkannya kembali.',
+"badfilename" => "Nama berkas telah diubah menjadi \"$1\".",
+"badfiletype" => "\".$1\" adalah format berkas yang tidak diizinkan.",
+'large-file' => 'Ukuran berkas disarankan untuk tidak melebihi $1 bita; berkas ini berukuran $2 bita.',
+'largefileserver' => 'Berkas ini lebih besar dari pada yang diizinkan server.',
+'emptyfile' => 'Berkas yang Anda muatkan kelihatannya kosong. Hal ini mungkin disebabkan karena adanya kesalahan ketik pada nama berkas. Silakan pastikan apakah Anda benar-benar ingin memuatkan berkas ini.',
+'fileexists' => 'Berkas dengan nama tersebut telah ada, harap periksa $1 jika Anda tidak yakin untuk mengubahnya.',
+'fileexists-forbidden' => 'Ditemukan berkas dengan nama yang sama; harap kembali dan muatkan berkas dengan nama lain. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Ditemukan berkas lain dengan nama yang sama di repositori bersama; harap kembali dan muatkan berkas dengan nama lain. [[{{ns:image}}:$1|thumb|center|$1]]',
+"successfulupload" => "Berhasil dimuat",
+"fileuploaded" => "Berkas \"$1\" berhasil dimuatkan. Silakan ikuti pranala berikut: $2 ke halaman deskripsi dan isikan informasi tentang berkas tersebut, seperti dari mana berkas tersebut berasal, kapan berkas itu dibuat dan oleh siapa, dan informasi lain yang Anda ketahui.",
+"uploadwarning" => "Peringatan pemuatan",
+"savefile" => "Simpan berkas",
+"uploadedimage" => "memuat \"[[$1]]\"",
+"uploaddisabled" => "Maaf, pemuatan dimatikan.",
+'uploaddisabledtext' => 'Pemuatan berkas di tidak diizinkan di wiki ini.',
+'uploadscripted' => 'Berkas ini mengandung HTML atau kode yang mungkin mungkin diinterpretasikan dengan keliru oleh pelayar web.',
+'uploadcorrupt' => 'Berkas tersebut rusak atau ekstensinya salah. Silakan periksa berkas tersebut dan muatkan kembali.',
+'uploadvirus' => 'Berkas tersebut mengandung virus! Detil: $1',
+'sourcefilename' => 'Nama berkas sumber',
+'destfilename' => 'Nama berkas tujuan',
+'watchthisupload' => 'Pantau halaman ini',
+'filewasdeleted' => 'Suatu berkas dengan nama ini pernah dimuat dan selanjutnya dihapus. Harap cek $1 sebelum memuat lagi berkas tersebut.',
+
+'upload-proto-error' => 'Protokol tak tepat',
+'upload-proto-error-text' => 'Pemuatan jarak jauh membutuhkan URL yang diawali dengan <code>http://</code> atau <code>ftp://</code>.',
+'upload-file-error' => 'Kesalahan internal',
+'upload-file-error-text' => 'Suatu kesalahan internal terjadi sewaktu mencoba membuat berkas temporer di server. Silakan kontak administrator sistem.',
+'upload-misc-error' => 'Kesalahan pemuatan yang tak dikenal',
+'upload-misc-error-text' => 'Suatu kesalahan yang tak dikenal terjadi sewaktu pemuatan. Harap pastikan bahwa URL tersebut valid dan dapat diakses dan silakan coba lagi. Jika masalah ini tetap terjadi, kontak administrator sistem.',
+'upload-curl-error6' => "URL tidak dapat dihubungi",
+'upload-curl-error6-text' => 'URL yang diberikan tak dapat dihubungi. Harap periksa ulang bahwa URL tersebut tepat dan situs itu sedang aktif.',
+'upload-curl-error28' => 'Pemuatan lewat waktu',
+'upload-curl-error28-text' => 'Situs yang dituju terlalu lambat merespon. Tolong cek apakah situs tersebut aktif, tunggu sebentar, dan coba lagi. Mungkin Anda perlu mencobanya di saat yang lebih longgar.',
+
+'license' => 'Jenis lisensi',
+'nolicense' => 'Belum dipilih',
+'upload_source_url' => ' (suatu URL valid yang dapat diakses publik)',
+'upload_source_file' => ' (suatu berkas di komputer Anda)',
+
+# Image list
+#
+"imagelist" => "Daftar berkas",
+'imagelisttext' => "Di bawah ini adalah daftar '''$1''' berkas diurutkan $2.", # no need for plural
+'imagelistforuser' => "Hanya berkas yang dimuat oleh $1.",
+"getimagelist" => "mengambil daftar berkas",
+"ilsubmit" => "Cari",
+"showlast" => "Tampilkan $1 berkas terakhir diurutkan $2.",
+"byname" => "berdasarkan nama",
+"bydate" => "berdasarkan tanggal",
+"bysize" => "berdasarkan ukuran",
+"imgdelete" => "hps",
+"imgdesc" => "desk",
+'imgfile' => 'berkas',
+"imglegend" => "Keterangan: (desk) = lihat/sunting deskripsi berkas.",
+"imghistory" => "Riwayat berkas",
+"revertimg" => "kbl",
+"deleteimg" => "hps",
+'deleteimgcompletely' => 'Hapus semua revisi',
+"imghistlegend" => "Keterangan: (skr) = ini adalah berkas yang sekarang, (hps) = hapus versi lama ini, (kbl) = kembalikan ke versi lama ini. <br /><em>Klik pada tanggal untuk melihat berkas yang dimuat pada tanggal tersebut</em>.",
+"imagelinks" => "Pautan",
+"linkstoimage" => "Halaman-halaman berikut berpaut ke berkas ini:",
+"nolinkstoimage" => "Tidak ada halaman yang berpaut ke berkas ini.",
+"sharedupload" => "Berkas ini adalah pemuatan bersama yang mungkin juga dipakai oleh proyek lain.",
+'shareduploadwiki' => 'Lihat $1 untuk informasi detil.',
+'shareduploadwiki-linktext' => 'halaman deskripsi berkas',
+'noimage' => 'Tidak ada berkas dengan nama tersebut, Anda dapat $1.',
+'noimage-linktext' => 'memuat berkas',
+'uploadnewversion-linktext' => 'Muatkan versi yang lebih baru dari berkas ini',
+'imagelist_date' => 'Tanggal',
+'imagelist_name' => 'Nama',
+'imagelist_user' => 'Pengguna',
+'imagelist_size' => 'Ukuran (bita)',
+'imagelist_description' => 'Deskripsi',
+'imagelist_search_for' => 'Cari nama berkas:',
+
+# Mime search
+#
+'mimesearch' => 'Pencarian MIME',
+'mimetype' => 'Tipe MIME:',
+'download' => 'unduh',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Halaman yang tak dipantau',
+
+# List interwikis
+'listinterwikis' => 'Daftar interwiki',
+
+# List redirects
+'listredirects' => 'Daftar pengalihan',
+
+# Unused templates
+'unusedtemplates' => 'Templat yang tak digunakan',
+'unusedtemplatestext' => 'Daftar berikut adalah halaman pada ruang nama templat yang tidak dipakai di halaman manapun. Cek dahulu pranala lain ke templat tersebut sebelum menghapusnya.',
+'unusedtemplateswlh' => 'pranala lain',
+
+# Random redirect
+'randomredirect' => 'Pengalihan sembarang',
+
+# Statistics
+#
+"statistics" => "Statistik",
+"sitestats" => "Statistik situs",
+"userstats" => "Statistik pengguna",
+"sitestatstext" => "Terdapat total '''$1''' halaman dalam basis data. Ini termasuk halaman \"pembicaraan\", halaman tentang {{SITENAME}}, halaman \"rintisan\" minimum, halaman peralihan, dan halaman-halaman lain yang mungkin tidak masuk kriteria artikel. Selain itu, ada '''$2''' halaman yang mungkin termasuk artikel yang sah.
+
+'''$8''' berkas telah dimuat.
+
+Ada sejumlah '''$3''' penampilan halaman, dan sejumlah '''$4''' penyuntingan sejak wiki ini dimulai. Ini berarti rata-rata '''$5''' suntingan per halaman, dan '''$6''' penampilan per penyuntingan.
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue Antrian job] adalah sebanyak '''$7'''.",
+"userstatstext" => "Terdapat '''$1''' pengguna terdaftar. '''$2''' (atau '''$4%''') diantaranya adalah $5.",
+'statistics-mostpopular' => 'Halaman yang paling banyak ditampilkan',
+
+"disambiguations" => "Halaman disambiguasi",
+'disambiguationspage' => '{{ns:template}}:Disambig',
+"disambiguationstext" => "Halaman-halaman berikut ini berpaut ke sebuah halaman disambiguasi. Halaman-halaman tersebut seharusnya berpaut ke topik-topik yang tepat.<br />Satu halaman dianggap sebagai disambiguation apabila halaman tersebut disambung dari $1.<br />Pranala dari ruang nama lain <em>tidak</em> terdaftar di sini.",
+
+"doubleredirects" => "Pengalihan ganda",
+"doubleredirectstext" => "Setiap baris mengandung pranala ke peralihan pertama dan kedua, dan juga baris pertama dari teks peralihan kedua, yang biasanya memberikan artikel tujuan yang \"sesungguhnya\", yang seharusnya ditunjuk oleh peralihan yang pertama.",
+
+"brokenredirects" => "Pengalihan rusak",
+"brokenredirectstext" => "Peralihan halaman berikut berpaut ke halaman yang tidak ada.",
+
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 bita', # no need for plural
+'ncategories' => '$1 kategori', # no need for plural
+'nlinks' => '$1 pranala', # no need for plural
+'nmembers' => '$1 pengguna', # no need for plural
+'nrevisions' => '$1 revisi', # no need for plural
+'nviews' => '$1 penampilan', # no need for plural
+
+"lonelypages" => "Halaman tak bertuan",
+'lonelypagestext' => 'Halaman-halaman berikut tidak memiliki pranala dari halaman manapun di wiki ini.',
+'uncategorizedpages' => 'Halaman yang tak terkategori',
+'uncategorizedcategories' => 'Kategori yang tak terkategori',
+'uncategorizedimages' => 'Berkas yang tak terkategori',
+'unusedcategories' => 'Kategori yang tak digunakan',
+"unusedimages" => "Berkas yang tak digunakan",
+"popularpages" => "Halaman populer",
+'wantedcategories' => 'Kategori yang diinginkan',
+"wantedpages" => "Halaman yang diinginkan",
+'mostlinked' => 'Halaman yang tersering dituju',
+'mostlinkedcategories' => 'Kategori dengan halaman terbanyak',
+'mostcategories' => 'Artikel dengan kategori terbanyak',
+'mostimages' => 'Berkas yang tersering digunakan',
+'mostrevisions' => 'Artikel dengan perubahan terbanyak',
+"allpages" => "Semua halaman",
+'prefixindex' => 'Indeks awalan',
+"randompage" => "Halaman sembarang",
+"shortpages" => "Halaman pendek",
+"longpages" => "Halaman panjang",
+"deadendpages" => "Halaman buntu",
+'deadendpagestext' => 'Halaman-halaman berikut tidak memiliki pranala ke halaman manapun di wiki ini.',
+"listusers" => "Daftar pengguna",
+"specialpages" => "Halaman istimewa",
+"spheading" => "Halaman istimewa untuk semua pengguna",
+'restrictedpheading' => 'Halaman istimewa terbatas',
+"recentchangeslinked" => "Perubahan terkait",
+"rclsub" => "(untuk halaman yang berpaut dari \"$1\")",
+"newpages" => "Halaman baru",
+'newpages-username' => 'Nama pengguna:',
+"ancientpages" => "Artikel tertua",
+"intl" => "Pranala antarbahasa",
+'move' => 'Pindahkan',
+"movethispage" => "Pindahkan halaman ini",
+"unusedimagestext" => "<p>Perhatikan bahwa situs web lain mungkin dapat berpaut ke sebuah berkas secara langsung, dan berkas-berkas seperti itu mungkin terdapat dalam daftar ini meskipun masih digunakan oleh situs web lain.",
+'unusedcategoriestext' => 'Kategori berikut ada walaupun tidak ada artikel atau kategori lain yang menggunakannya.',
+
+
+# Book sources
+'booksources' => 'Sumber buku',
+'booksources-summary' => '',
+'booksources-search-legend' => 'Cari di sumber buku',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => 'Cari',
+'booksources-text' => 'Di bawah ini adalah daftar pranala ke situs lain yang menjual buku baru dan bekas, dan mungkin juga mempunyai informasi lebih lanjut mengenai buku yang sedang Anda cari:',
+
+'categoriespagetext' => 'Kategori-kategori berikut ada dalam wiki.',
+'data' => 'Data',
+'userrights' => 'Manajemen hak pengguna',
+'groups' => 'Grup pengguna',
+
+"isbn" => "ISBN",
+"alphaindexline" => "$1 ke $2",
+"version" => "Versi",
+'log' => 'Log',
+'alllogstext' => 'Di bawah ini adalah gabungan log pemblokiran, perlindungan, perubahan hak akses, penghapusan, pemuatan, pemindahan, impor, dll. Anda dapat melakukan pembatasan tampilan dengan memilih jenis log, nama pengguna, atau nama halaman yang terpengaruh.',
+'logempty' => 'Tidak ditemukan entri log yang sesuai.',
+
+
+# Special:Allpages
+'nextpage' => 'Halaman selanjutnya ($1)',
+'prevpage' => 'Halaman sebelumnya ($1)',
+'allpagesfrom' => 'Tampilkan halaman dimulai dengan:',
+'allarticles' => 'Semua artikel',
+'allinnamespace' => 'Semua halaman (ruang nama $1)',
+'allnotinnamespace' => 'Semua halaman (bukan ruang nama $1)',
+'allpagesprev' => 'Sebelumnya',
+'allpagesnext' => 'Selanjutnya',
+'allpagessubmit' => 'Cari',
+'allpagesprefix' => 'Tampilkan halaman dengan awalan:',
+'allpagesbadtitle' => 'Judul halaman yang diberikan tidak sah atau memiliki awalan antar-bahasa atau antar-wiki. Judul tersebut mungkin juga mengandung satu atau lebih aksara yang tidak dapat digunakan dalam judul.',
+
+# Special:Listusers
+'listusersfrom' => 'Tampilkan pengguna diawali dengan:',
+
+# Email this user
+#
+"mailnologin" => "Tidak ada alamat surat-e",
+"mailnologintext" => "Anda harus [[{{ns:special}}:Userlogin|masuk log]] dan mempunyai alamat surat-e yang sah di dalam [[{{ns:special}}:Preferences|preferensi]] untuk mengirimkan surat-e kepada pengguna lain.",
+
+"emailuser" => "Kirimi pengguna ini surat-e",
+"emailpage" => "Kirimi pengguna ini surat-e",
+"emailpagetext" => "Jika pengguna ini memasukkan alamat surat-e yang sah dalam preferensinya, formulir dibawah ini akan mengirimkan sebuah surat-e. Alamat surat-e yg terdapat pada preferensi Anda akan muncul sebagai alamat \"Dari\" dalam surat-e tersebut, sehingga penerima dapat membalas surat-e tersebut.",
+
+"usermailererror" => "Kesalahan objek surat:",
+"defemailsubject" => "Surat-e {{SITENAME}}",
+"noemailtitle" => "Tidak ada alamat surat-e",
+
+"noemailtext" => "Pengguna ini tidak memasukkan alamat surat-e yang sah, atau memilih untuk tidak menerima surat-e dari pengguna yang lain.",
+
+"emailfrom" => "Dari",
+"emailto" => "Untuk",
+"emailsubject" => "Perihal",
+"emailmessage" => "Pesan",
+"emailsend" => "Kirim",
+'emailccme' => 'Kirimi saya salinan pesan saya.',
+'emailccsubject'=> 'Salinan pesan Anda untuk $1: $2',
+"emailsent" => "Surat-e terkirim",
+"emailsenttext" => "Surat-e Anda telah dikirimkan.",
+
+# Watchlist
+"watchlist" => "Daftar pantauan",
+'watchlistfor' => "(untuk '''$1''')",
+"nowatchlist" => "Daftar pantauan Anda kosong.",
+'watchlistanontext' => 'Silakan $1 untuk melihat atau menyunting daftar pantauan Anda.',
+'watchlistcount' => "'''Anda memiliki $1 entri di daftar pantauan Anda, termasuk halaman diskusi/bicara.'''",
+'clearwatchlist' => 'Kosongkan daftar pantauan',
+'watchlistcleartext' => 'Apakah Anda yakin untuk menghapusnya?',
+'watchlistclearbutton' => 'Kosongkan daftar pantauan',
+'watchlistcleardone' => 'Daftar pantauan Anda telah dikosongkan. $1 entri telah dihapus.',
+"watchnologin" => "Belum masuk log",
+"watchnologintext" => "Anda harus [[{{ns:special}}:Userlogin|masuk log]] untuk mengubah daftar pantauan.",
+"addedwatch" => "Telah ditambahkan ke daftar pantauan",
+"addedwatchtext" => "Halaman \"[[:$1]]\" telah ditambahkan ke [[{{ns:special}}:Watchlist|daftar pantauan]]. Perubahan yang terjadi di masa yang akan datang pada halaman tersebut dan halaman bicara terkaitnya akan tercantum di sini, dan halaman itu akan ditampilkan ''tebal'' pada [[{{ns:special}}:Recentchanges|daftar perubahan terbaru]] agar lebih mudah terlihat.<br /><br />Jika Anda ingin menghapus halaman ini dari daftar pantauan, klik \"Berhenti memantau\" pada menu.",
+"removedwatch" => "Telah dihapus dari daftar pantauan",
+"removedwatchtext" => "Halaman \"$1\" telah dihapus dari daftar pantauan.",
+'watch' => 'Pantau',
+"watchthispage" => "Pantau halaman ini",
+'unwatch' => 'Batal pantau',
+"unwatchthispage" => "Batal pantau halaman ini",
+"notanarticle" => "Bukan sebuah artikel",
+"watchnochange" => "Tak ada halaman pantauan Anda yang telah berubah dalam jangka waktu yang dipilih.",
+'watchdetails' => '* $1 halaman dipantau, tidak termasuk halaman bicara
+* [[{{ns:special}}:Watchlist/edit|Lihat dan sunting daftar pantauan]]
+* [[{{ns:special}}:Watchlist/clear|Hapus semua halaman dari daftar]]',
+'wlheader-enotif' => "* Notifikasi surat-e diaktifkan.",
+'wlheader-showupdated' => "* Halaman-halaman yang telah berubah sejak kunjungan terakhir Anda ditampilkan dengan '''huruf tebal'''",
+"watchmethod-recent"=> "periksa daftar perubahan terbaru terhadap halaman yang dipantau",
+"watchmethod-list" => "periksa halaman yang dipantau terhadap perubahan terbaru",
+"removechecked" => "Keluarkan halaman yang ditandai dari daftar pantauan",
+"watchlistcontains" => "Daftar pantauan Anda berisi $1 halaman.",
+"watcheditlist" => "Berikut ini adalah daftar halaman-halaman yang Anda pantau. Untuk menghapus halaman dari daftar pantauan Anda, berikan tanda cek pada kotak cek di sebelah judul halaman yang ingin Anda hapus, lalu klik tombol 'Keluarkan halaman yang ditandai dari daftar pantauan' yang terletak di bagian bawah layar.",
+"removingchecked" => "Menghapus halaman yang diminta dari daftar pantauan Anda...",
+"couldntremove" => "Tidak dapat menghapus halaman '$1' dari daftar pantauan...",
+"iteminvalidname" => "Ada masalah dengan '$1', namanya tidak sah...",
+"wlnote" => "Di bawah ini adalah daftar $1 perubahan terakhir dalam <strong>$2</strong> jam terakhir.",
+"wlshowlast" => "Tampilkan $1 jam $2 hari $3 terakhir",
+"wlsaved" => "Ini adalah versi tersimpan dari daftar pantauan Anda.",
+'watchlist-show-bots' => 'Tampilkan suntingan bot',
+'watchlist-hide-bots' => 'Sembunyikan suntingan bot',
+'watchlist-show-own' => 'Tampilkan suntingan saya',
+'watchlist-hide-own' => 'Sembunyikan suntingan saya',
+'watchlist-show-minor' => 'Tampilkan suntingan kecil',
+'watchlist-hide-minor' => 'Sembunyikan suntingan kecil',
+'wldone' => 'Selesai.',
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => 'Memantau...',
+'unwatching' => 'Menghilangkan pemantauan...',
+
+'enotif_mailer' => 'Pengirim Notifikasi {{SITENAME}}',
+'enotif_reset' => 'Tandai semua halaman sebagai telah dikunjungi',
+'enotif_newpagetext'=> 'Ini adalah halaman baru.',
+'changed' => 'diubah',
+'created' => 'dibuat',
+'enotif_subject' => 'Halaman $PAGETITLE di {{SITENAME}} telah $CHANGEDORCREATED oleh $PAGEEDITOR',
+'enotif_lastvisited' => 'Lihat $1 untuk semua perubahan sejak kunjungan terakhir Anda.',
+'enotif_body' => 'Dear $WATCHINGUSERNAME,
+
+Halaman $PAGETITLE di {{SITENAME}} telah $CHANGEDORCREATED pada $PAGEEDITDATE oleh $PAGEEDITOR, lihat $PAGETITLE_URL untuk versi terakhir.
+
+$NEWPAGE
+
+Riwayat suntingan: $PAGESUMMARY $PAGEMINOREDIT
+
+Hubungi penyunting:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Kami tidak akan mengirimkan pemberitahuan lain jika terjadi perubahan lagi, kecuali Anda jika Anda telah mengunjungi halaman tersebut. Anda juga dapat menghapus tanda notifikasi untuk semua halaman pantauan Anda pada daftar pantauan Anda.
+
+ Sistem notifikasi {{SITENAME}}
+
+--
+Untuk mengubah preferensi daftar pantauan Anda, kunjungi
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Masukan dan bantuan lanjutan:
+{{fullurl:{{ns:help}}:Isi}}',
+
+
+# Delete/protect/revert
+#
+"deletepage" => "Hapus halaman",
+"confirm" => "Konfirmasikan",
+"excontent" => "isi sebelumnya: '$1'",
+'excontentauthor' => "isinya hanya berupa: '$1' (dan satu-satunya penyumbang adalah '[[Special:Contributions/$2|$2]]')",
+"exbeforeblank" => "isi sebelum dikosongkan: '$1'",
+"exblank" => "halaman kosong",
+"confirmdelete" => "Konfirmasi penghapusan",
+"deletesub" => "(Menghapus \"$1\")",
+"historywarning" => "Peringatan: Halaman yang ingin Anda hapus mempunyai sejarah:",
+"confirmdeletetext" => "Anda akan menghapus halaman atau berkas ini secara permanen berikut semua sejarahnya dari basis data. Pastikan bahwa Anda memang ingin berbuat demikian, mengetahui segala akibatnya, dan apa yang Anda lakukan ini adalah sejalan dengan [[{{ns:project}}:Kebijakan|kebijakan {{SITENAME}}]].",
+"actioncomplete" => "Proses selesai",
+"deletedtext" => "\"$1\" telah dihapus. Lihat $2 untuk log terkini halaman yang telah dihapus.",
+"deletedarticle" => "menghapus \"[[$1]]\"",
+"dellogpage" => "Log penghapusan",
+"dellogpagetext" => "Di bawah ini adalah log penghapusan halaman. Semua waktu yang ditunjukkan adalah waktu server (UTC).",
+"deletionlog" => "log penghapusan",
+"reverted" => "Dikembalikan ke revisi sebelumnya",
+"deletecomment" => "Alasan penghapusan",
+"imagereverted" => "Berhasil mengembalikan ke revisi sebelumnya",
+"rollback" => "Kembalikan suntingan",
+'rollback_short' => 'Kembalikan',
+"rollbacklink" => "kembalikan",
+"rollbackfailed" => "Pengembalian gagal dilakukan",
+"cantrollback" => "Tidak dapat mengembalikan suntingan; pengguna terakhir adalah satu-satunya penulis artikel ini.",
+"alreadyrolled" => "Tidak dapat melakukan pengembalian ke suntingan terakhir [[:$1]] oleh [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|Bicara]]); orang lain telah menyunting atau melakukan pengembalian terhadap artikel tersebut. Suntingan terakhir oleh [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|Bicara]]).",
+"editcomment" => "Komentar penyuntingan adalah: \"<em>$1</em>\".",
+'revertpage' => "Suntingan [[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|Bicara]]) dikembalikan ke versi terakhir oleh [[{{ns:user}}:$1|$1]]",
+'sessionfailure' => 'Sepertinya ada masalah dengan sesi log anda; log anda telah dibatalkan untuk mencegah pembajakan. Silahkan tekan tombol "back" dan muat kembali halaman sebelum anda masuk, lalu coba lagi.',
+"protectlogpage" => "Log perlindungan",
+"protectlogtext" => "Di bawah ini adalah log perlindungan dan penghilangan perlindungan halaman.",
+"protectedarticle" => "melindungi [[$1]]",
+"unprotectedarticle" => "menghilangkan perlindungan [[$1]]",
+"protectsub" =>"(Melindungi \"$1\")",
+"confirmprotecttext" => "Apakah Anda benar-benar ingin melindungi halaman ini?",
+"confirmprotect" => "Konfirmasi perlindungan",
+'protectmoveonly' => 'Lindungi dari pemindahan saja',
+"protectcomment" => "Alasan perlindungan",
+"unprotectsub" =>"(Menghilangkan perlindungan terhadap \"$1\")",
+"confirmunprotecttext" => "Apakah Anda benar-benar ingin menghilangkan perlindungan terhadap halaman ini?",
+"confirmunprotect" => "Konfirmasi penghilangan perlindungan",
+"unprotectcomment" => "Alasan penghilangan perlindungan",
+'protect-unchain' => 'Buka proteksi pemindahan',
+'protect-text' => 'Anda dapat melihat atau mengganti tingkatan perlindungan untuk halaman <strong>$1</strong> di sini.',
+'protect-viewtext' => 'Akun Anda tidak memiliki akses untuk mengganti tingkat perlindungan halaman. Berikut adalah konfigurasi saat ini untuk halaman <strong>$1</strong>:',
+'protect-default' => '(baku)',
+'protect-level-autoconfirmed' => 'Hanya pengguna terdaftar',
+'protect-level-sysop' => 'Hanya pengurus',
+
+# restrictions (nouns)
+'restriction-edit' => 'Penyuntingan',
+'restriction-move' => 'Pemindahan',
+
+# Undelete
+"undelete" => "Kembalikan halaman yang telah dihapus",
+"undeletepage" => "Lihat dan kembalikan halaman yang telah dihapus",
+'viewdeletedpage' => 'Lihat halaman yang telah dihapus',
+"undeletepagetext" => "Halaman-halaman berikut ini telah dihapus tapi masih ada di dalam arsip dan dapat dikembalikan. Arsip tersebut mungkin akan dibersihkan secara berkala.",
+'undeleteextrahelp' => "Untuk mengembalikan keseruhan halaman, biarkan seluruh ''check box'' tidak terpilih dan klik '''''Restore'''''. Untuk melakukan pengembalian seletif, cek kotak revisi yang diinginkan dan klik '''''Restore'''''. Menekan tombol '''''Reset''''' akan mengosongkan isian komentar dan semua ''cek box''",
+"undeletearticle" => "Kembalikan halaman yang telah dihapus",
+"undeletehistory" => "Jika Anda mengembalikan halaman tersebut, semua revisi akan dikembalikan ke dalam sejarah. Jika sebuah halaman baru dengan nama yang sama telah dibuat sejak penghapusan, revisi yang telah dikembalikan akan kelihatan dalam sejarah dahulu, dan revisi terkini halaman tersebut tidak akan ditimpa secara otomatis.",
+'undeletehistorynoadmin' => 'Artikel ini telah dihapus. Alasan penghapusan diberikan pada ringkasan di bawah ini, berikut detil pengguna yang telah melakukan penyuntingan pada halaman ini sebelum dihapus. Isi terakhir dari revisi yang telah dihapus ini hanya tersedia untuk pengurus.',
+"undeleterevisions" => "$1 revisi diarsipkan",
+'undeleterevision-missing' => "Revisi salah atau tak ditemukan. Anda mungkin mengikuti pranala yang salah, atau revisi tersebut telah dipulihkan atau dibuang dari arsip.",
+"undeleterevision" => "Revisi yang telah dihapus per $1",
+'undeletebtn' => "Kembalikan!",
+'undeletereset' => 'Reset',
+'undeletecomment' => 'Komentar:',
+"undeletedarticle" => "\"$1\" telah dikembalikan",
+'undeletedrevisions' => "$1 revisi telah dikembalikan",
+'undeletedrevisions-files' => "$1 revisi and $2 berkas dikembalikan",
+'undeletedfiles' => "$1 berkas dikembalikan",
+'cannotundelete' => 'Pembatalan penghapusan gagal; mungkin ada orang lain yang telah terlebih dahulu melakukan pembatalan.',
+'undeletedpage' => "<big>'''$1 berhasil dikembalikan'''</big>
+
+Lihat [[{{ns:special}}:Log/delete|log penghapusan]] untuk data penghapusan dan pengembalian.",
+
+# Namespace form on various pages
+'namespace' => 'Ruang nama:',
+'invert' => 'Balikkan pilihan',
+
+# Contributions
+#
+'contributions' => 'Sumbangan pengguna',
+'mycontris' => 'Sumbangan saya',
+'contribsub' => "Untuk $1",
+'nocontribs' => 'Tidak ada perubahan yang sesuai dengan kriteria tersebut.',
+'ucnote' => "Berikut adalah <b>$1</b> suntingan terakhir pengguna ini dalam <b>$2</b> hari terakhir.",
+'uclinks' => "Menampilkan $1 perubahan terakhir; menampilkan $2 hari terakhir.",
+'uctop' => ' (atas)' ,
+'newbies' => 'pengguna baru',
+
+'sp-contributions-newest' => 'Terbaru',
+'sp-contributions-oldest' => 'Terlama',
+'sp-contributions-newer' => '$1 terbaru',
+'sp-contributions-older' => '$1 terlama',
+'sp-contributions-newbies-sub' => 'Untuk pengguna baru',
+'sp-contributions-blocklog' => 'Log pemblokiran',
+
+'sp-newimages-showfrom' => 'Tampilkan berkas baru dimulai dari $1',
+
+# What links here
+#
+"whatlinkshere" => "Pranala ke halaman ini",
+'whatlinkshere-barrow' => '&lt;',
+"notargettitle" => "Tidak ada sasaran",
+"notargettext" => "Anda tidak menentukan halaman atau pengguna tujuan fungsi ini.",
+"linklistsub" => "(Daftar pranala)",
+"linkshere" => "Halaman-halaman berikut ini berpaut ke '''[[:$1]]''':",
+"nolinkshere" => "Tidak ada halaman yang berpaut ke '''[[:$1]]'''.",
+"isredirect" => "halaman peralihan",
+'istemplate' => 'dengan templat',
+
+# Block/unblock IP
+#
+"blockip" => "Blokir IP",
+"blockiptext" => "Gunakan formulir di bawah untuk memblokir kemampuan menulis sebuah alamat IP atau pengguna tertentu. Ini perlu dilakukan untuk mencegah vandalisme, dan sejalan dengan [[{{ns:project}}:Kebijakan|kebijakan {{SITENAME}}]]. Masukkan alasan Anda di bawah (contohnya mengambil halaman tertentu yang telah dirusak). Untuk daftar pengguna dan alamat yang diblokir, lihat [[{{ns:special}}:Ipblocklist|halaman ini]].",
+"ipaddress" => "Alamat IP",
+'ipadressorusername' => 'Alamat IP atau nama pengguna',
+"ipbexpiry" => "Kadaluwarsa",
+"ipbreason" => "Alasan",
+'ipbanononly' => 'Hanya blokir pengguna anonim',
+'ipbcreateaccount' => 'Cegah pembuatan akun',
+'ipbenableautoblock' => 'Blokir alamat IP terakhir yang digunakan pengguna ini secara otomatis, dan semua alamat berikutnya yang mereka coba gunakan untuk menyunting.',
+"ipbsubmit" => "Kirimkan",
+'ipbother' => 'Waktu lain',
+'ipboptions' => '2 jam:2 hours,1 hari:1 day,3 hari:3 days,1 minggu:1 week,2 minggu:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 tahun:1 year,selamanya:infinite',
+'ipbotheroption' => 'lainnya',
+"badipaddress" => "Format alamat IP atau nama pengguna salah.",
+"blockipsuccesssub" => "Pemblokiran sukses",
+"blockipsuccesstext" => "Alamat IP atau pengguna \"$1\" telah diblokir. <br />Lihat [[{{ns:special}}:Ipblocklist|Daftar IP dan pengguna diblokir]] untuk melihat kembali pemblokiran.",
+"unblockip" => "Hilangkan blokir terhadap alamat IP atau pengguna",
+"unblockiptext" => "Gunakan formulir di bawah untuk mengembalikan kemampuan menulis sebuah alamat IP atau pengguna yang sebelumnya telah diblokir.",
+"ipusubmit" => "Hilangkan blokir terhadap alamat ini",
+'unblocked' => 'Blokir terhadap [[User:$1|$1]] telah dihilangkan',
+"ipblocklist" => "Daftar alamat IP dan pengguna yang diblokir",
+"blocklistline" => "$1, $2 memblokir $3 ($4)",
+'infiniteblock' => 'tak terbatas',
+'expiringblock' => 'kadaluwarsa $1',
+'anononlyblock' => 'hanya anon',
+'noautoblockblock' => 'pemblokiran otomatis dimatikan',
+'createaccountblock' => 'pembuatan akun diblokir',
+'ipblocklistempty' => 'Daftar pemblokiran kosong.',
+"blocklink" => "blokir",
+"unblocklink" => "hilangkan blokir",
+"contribslink" => "sumbangan",
+"autoblocker" => "Diblokir secara otomatis karena Anda berbagi alamat IP dengan \"$1\". Alasan \"$2\".",
+"blocklogpage" => "Log pemblokiran",
+"blocklogentry" => 'memblokir "[[$1]]" dengan waktu kadaluwarsa $2',
+"blocklogtext" => "Di bawah ini adalah log pemblokiran dan penghilangan blokir terhadap pengguna. Alamat IP yang diblokir secara otomatis tidak terdapat di dalam daftar ini. Lihat [[{{ns:special}}:Ipblocklist|daftar alamat IP yang diblokir]] untuk daftar blokir terkini yang efektif.",
+"unblocklogentry" => 'menghilangkan blokir "$1"',
+"range_block_disabled" => "Kemampuan pengurus dalam membuat blokir blok IP dimatikan.",
+"ipb_expiry_invalid" => "Waktu kadaluwarsa tidak sah.",
+'ipb_already_blocked' => '"$1" telah diblokir',
+"ip_range_invalid" => "Blok IP tidak sah.",
+"proxyblocker" => "Pemblokir proxy",
+'ipb_cant_unblock' => 'Kesalahan: Blokir dengan ID $1 tidak ditemukan. Blokir tersebut kemungkinan telah dibuka.',
+"proxyblockreason" => "Alamat IP Anda telah diblokir karena alamat IP Anda adalah proxy terbuka. Silakan hubungi penyedia jasa internet Anda atau dukungan teknis dan beritahukan mereka masalah keamanan serius ini.",
+"proxyblocksuccess" => "Selesai.",
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Alamat IP anda terdaftar sebagai proxy terbuka di [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Alamat IP anda terdaftar sebagai proxy terbuka di [http://www.sorbs.net SORBS] DNSBL. Anda tidak dapat membuat akun.',
+
+# Make sysop
+"makesysoptitle" => "Buat seorang pengguna menjadi pengurus",
+"makesysoptext" => "Formulir ini digunakan oleh para birokrat untuk menjadikan pengguna biasa menjadi seorang pengurus. Ketikkan nama pengguna yang dimaksud dalam kotak dan tekan tombol untuk menjadikan pengguna tersebut seorang pengurus",
+"makesysopname" => "Nama pengguna:",
+"makesysopsubmit" => "Jadikan pengurus",
+"makesysopok" => "<strong>Pengguna \"$1\" sekarang adalah seorang pengurus</strong>",
+"makesysopfail" => "<strong>Pengguna \"$1\" tidak dapat dijadikan pengurus. (Apakah Anda mengetikkan namanya dengan benar?)</strong>",
+"setbureaucratflag" => "Beri tanda birokrat",
+'rightslog' => 'Log perubahan hak akses',
+'rightslogtext' => 'Di bawah ini adalah log perubahan terhadap hak-hak pengguna.',
+'rightslogentry' => 'mengganti keanggotaan group untuk $1 dari $2 menjadi $3',
+"rights" => "Hak-hak:",
+"set_user_rights" => "Atur hak-hak pengguna",
+"user_rights_set" => "<strong>Hak-hak pengguna \"$1\" diperbarui</strong>",
+"set_rights_fail" => "<strong>Hak-hak pengguna \"$1\" tidak dapat diatur. (Apakah Anda mengetikkan namanya dengan benar?)</strong>",
+"makesysop" => "Buat seorang pengguna menjadi pengurus",
+'already_sysop' => 'Pengguna ini sudah menjadi pengurus',
+'already_bureaucrat' => 'Pengguna ini sudah menjadi birokrat',
+'rightsnone' => '(tidak ada)',
+
+# Developer tools
+#
+"lockdb" => "Kunci basis data",
+"unlockdb" => "Buka kunci basis data",
+"lockdbtext" => "Mengunci basis data akan menghentikan kemampuan semua pengguna dalam menyunting halaman, mengubah preferensi pengguna, menyunting daftar pantauan mereka, dan hal-hal lain yang memerlukan perubahan terhadap basis data. Pastikan bahwa ini adalah yang ingin Anda lakukan, dan bahwa Anda akan membuka kunci basis data setelah pemeliharaan selesai.",
+"unlockdbtext" => "Membuka kunci basis data akan mengembalikan kemampuan semua pengguna dalam menyunting halaman, mengubah preferensi pengguna, menyunting daftar pantauan mereka, dan hal-hal lain yang memerlukan perubahan terhadap basis data. Pastikan bahwa ini adalah yang ingin Anda lakukan.",
+"lockconfirm" => "Ya, saya memang ingin mengunci basis data.",
+"unlockconfirm" => "Ya, saya memang ingin membuka kunci basis data.",
+"lockbtn" => "Kunci basis data",
+"unlockbtn" => "Buka kunci basis data",
+"locknoconfirm" => "Anda tidak memberikan tanda cek pada kotak konfirmasi.",
+"lockdbsuccesssub" => "Penguncian basis data berhasil",
+"unlockdbsuccesssub" => "Pembukaan kunci basis data berhasil",
+'lockdbsuccesstext' => 'Basis data telah dikunci.
+<br />Pastikan Anda [[Special:Unlockdb|membuka kuncinya]] setelah pemeliharaan selesai.',
+"unlockdbsuccesstext" => "Kunci basis data telah dibuka.",
+'lockfilenotwritable' => 'Berkas kunci basis data tidak dapat ditulis. Untuk mengunci atau membuka basis data, berkas ini harus dapat ditulis oleh server web.',
+'databasenotlocked' => 'Basis data tidak terkunci.',
+
+# Move page
+#
+"movepage" => "Pindahkan halaman",
+"movepagetext" => "Formulir di bawah ini digunakan untuk mengubah nama suatu halaman dan memindahkan semua data sejarah ke nama baru. Judul yang lama akan menjadi halaman peralihan menuju judul yang baru. Pranala kepada judul lama tidak akan berubah. Pastikan untuk memeriksa terhadap peralihan halaman yang rusak atau berganda setelah pemindahan. Anda bertanggung jawab untuk memastikan bahwa pranala terus menyambung ke halaman yang seharusnya.
+
+Perhatikan bahwa halaman '''tidak''' akan dipindah apabila telah ada halaman di pada judul yang baru, kecuali bila halaman tersebut kosong atau merupakan halaman peralihan dan tidak mempunyai sejarah penyuntingan. Ini berarti Anda dapat mengubah nama halaman kembali seperti semula apabila Anda membuat kesalahan, dan Anda tidak dapat menimpa halaman yang telah ada.
+
+<strong>PERINGATAN!</strong> Ini dapat mengakibatkan perubahan yang tak terduga dan drastis bagi halaman yang populer. Pastikan Anda mengerti konsekuensi dari perbuatan ini sebelum melanjutkan.",
+"movepagetalktext" => "Halaman pembicaraan yang berkaitan juga akan dipindahkan secara otomatis '''kecuali apabila:'''
+
+*Sebuah halaman pembicaraan yang tidak kosong telah ada di bawah judul baru, atau
+*Anda tidak memberi tanda cek pada kotak di bawah ini
+
+Dalam kasus tersebut, apabila diinginkan, Anda dapat memindahkan atau menggabungkan halaman secara manual.",
+"movearticle" => "Pindahkan halaman",
+"movenologin" => "Belum masuk log",
+"movenologintext" => "Anda harus menjadi pengguna terdaftar dan telah [[{{ns:special}}:Userlogin|masuk log]] untuk memindahkan halaman.",
+"newtitle" => "Ke judul baru",
+'move-watch' => 'Pantau halaman ini',
+"movepagebtn" => "Pindahkan halaman",
+"pagemovedsub" => "Pemindahan berhasil",
+"pagemovedtext" => "<div class=\"plainlinks\">Halaman \"[{{fullurl:<includeonly></includeonly>$1|redirect=no}} $1]\" dipindahkan ke \"[[$2]]\". Jangan lupa untuk memperbaiki [[{{ns:special}}:Whatlinkshere/$1|pengalihan ganda]] yang mungkin terjadi.</div>",
+"articleexists" => "Halaman dengan nama tersebut telah ada atau nama yang dipilih tidak sah. Silakan pilih nama lain.",
+"talkexists" => "Halaman tersebut berhasil dipindahkan, tetapi halaman pembicaraan dari halaman tersebut tidak dapat dipindahkan karena telah ada halaman pembicaraan pada judul yang baru. Silakan gabungkan halaman-halaman pembicaraan tersebut secara manual.",
+"movedto" => "dipindahkan ke",
+"movetalk" => "Pindahkan halaman \"pembicaraan\" juga, jika mungkin.",
+"talkpagemoved" => "Halaman pembicaraan yang berkaitan juga ikut dipindahkan.",
+"talkpagenotmoved" => "Halaman pembicaraan yang berkaitan <strong>tidak</strong> ikut dipindahkan.",
+'1movedto2' => '[[$1]] dipindahkan ke [[$2]]',
+'1movedto2_redir' => '[[$1]] dipindahkan ke [[$2]] melalui peralihan',
+'movelogpage' => 'Log pemindahan',
+'movelogpagetext' => 'Di bawah ini adalah log pemindahan halaman.',
+'movereason' => 'Alasan',
+'revertmove' => 'kembalikan',
+'delete_and_move' => 'Hapus dan pindahkan',
+'delete_and_move_text' =>
+'==Penghapusan diperlukan==
+
+Artikel yang dituju, "[[$1]]", telah mempunyai isi. Apakah Anda hendak menghapusnya untuk memberikan ruang bagi pemindahan?',
+'delete_and_move_confirm' => 'Ya, hapus halaman tersebut',
+'delete_and_move_reason' => 'Dihapus untuk mengantisipasikan pemindahan halaman',
+'selfmove' => "Pemindahan halaman tidak dapat dilakukan karena judul sumber dan judul tujuan sama.",
+'immobile_namespace' => "Judul sumber atau tujuan termasuk tipe khusus; tidak dapat memindahkan halaman ke ruang nama tersebut.",
+
+# Export
+
+"export" => "Ekspor halaman",
+'exporttext' => 'Anda dapat mengekspor teks dan sejarah penyuntingan suatu halaman tertentu atau suatu set halaman dalam bentuk XML tertentu. Hasil ekspor ini selanjutnya dapat diimpor ke wiki lainnya yang menggunakan perangkat lunak MediaWiki, dengan menggunakan fasilitas [[{{ns:special}}:Import]].
+
+Untuk mengekspor halaman-halaman artikel, masukkan judul-judul dalam kotak teks di bawah ini, satu judul per baris, dan pilih apakah anda ingin mengekspor lengkap dengan versi terdahulunya, atau hanya versi sekarang dengan catatan penyuntingan terakhir.
+
+Jika Anda hanya ingin mengimpor versi sekarang, Anda juga dapat melakukan hal ini dengan lebih cepat dengan cara menggunakan pranala khusus, sebagai contoh: [[{{ns:special}}:Export/{{int:mainpage}}]] untuk mengekspor artikel {{int:mainpage}}.',
+"exportcuronly" => "Hanya ekspor revisi sekarang, bukan seluruh versi terdahulu",
+'exportnohistory' => "----
+'''Catatan:''' Mengekspor keseluruhan riwayat suntingan halaman melalui isian ini telah dinon-aktifkan karena alasan kinerja.",
+'export-submit' => 'Ekspor',
+
+# Namespace 8 related
+
+"allmessages" => "Pesan sistem",
+'allmessagesname' => 'Nama',
+'allmessagesdefault' => 'Teks baku',
+'allmessagescurrent' => 'Teks sekarang',
+'allmessagestext' => 'Ini adalah daftar semua pesan sistem yang tersedia dalam ruang nama MediaWiki:',
+'allmessagesnotsupportedUI' => 'Bahasa antarmuka Anda saat ini, <strong>$1</strong> tidak didukung oleh {{ns:special}}:AllMessages di situs ini.',
+'allmessagesnotsupportedDB' => '\'\'\'{{ns:special}}:Allmessages\'\'\' tidak didukung karena wgUseDatabaseMessages dimatikan.',
+'allmessagesfilter' => 'Filter nama pesan:',
+'allmessagesmodified' => 'Hanya tampilkan yang diubah',
+
+# Thumbnails
+
+"thumbnail-more" => "Perbesar",
+"missingimage" => "<strong>Berkas tak ditemukan</strong><br /><em>$1</em>",
+'filemissing' => 'Berkas tak ditemukan',
+'thumbnail_error' => 'Kesalahan sewaktu pembuatan gambar kecil (thumbnail): $1',
+
+# Special:Import
+"import" => "Impor halaman",
+'importinterwiki' => 'Impor transwiki',
+'import-interwiki-text' => 'Pilih suatu wiki dan judul halaman yang akan di impor. Tanggal revisi dan nama penyunting akan dipertahankan. Semua aktivitas impor transwiki akan dilog di [[{{ns:special}}:Log/import|log impor]].',
+'import-interwiki-history' => 'Salin semua versi terdahulu dari halaman ini',
+'import-interwiki-submit' => 'Impor',
+'import-interwiki-namespace' => 'Transfer halaman ke dalam ruang nama:',
+"importtext" => "Silakan ekspor berkas dari wiki asal dengan menggunakan utilitas [[{{ns:special}}:Export]], simpan ke cakram digital, dan muatkan ke sini.",
+'importstart' => "Mengimpor halaman...",
+'import-revision-count' => '$1 versi terdahulu',
+'importnopages' => "Tidak ada halaman untuk diimpor.",
+"importfailed" => "Impor gagal: $1",
+'importunknownsource' => "Sumber impor tidak dikenali",
+'importcantopen' => "Berkas impor tidak dapat dibuka",
+'importbadinterwiki' => "Pranala interwiki rusak",
+"importnotext" => "Kosong atau tidak ada teks",
+"importsuccess" => "Impor sukses!",
+"importhistoryconflict" => "Terjadi konflik revisi sejarah (mungkin pernah mengimpor halaman ini sebelumnya)",
+'importnosources' => 'Tidak ada sumber impor transwiki yang telah dibuat dan pemuatan riwayat secara langsung telah di non-aktifkan.',
+'importnofile' => 'Tidak ada berkas sumber impor yang telah dimuat.',
+'importuploaderror' => 'Pemuatan berkas impor gagal; mungkin ukuran berkas lebih besar dari pada yang diizinkan.',
+
+# import log
+'importlogpage' => 'Log impor',
+'importlogpagetext' => 'Di bawah ini adalah log impor administratif dari halaman-halaman, berikut riwayat suntingannya dari wiki lain.',
+'import-logentry-upload' => 'mengimpor [[$1]] melalui pemuatan berkas',
+'import-logentry-upload-detail' => '$1 versi terdahulu',
+'import-logentry-interwiki' => 'men-transwiki $1',
+'import-logentry-interwiki-detail' => '$1 versi terdahulu dari $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for the main actions
+'tooltip-search' => 'Cari dalam wiki ini [alt-f]',
+'tooltip-minoredit' => 'Tandai ini sebagai suntingan kecil [alt-i]',
+'tooltip-save' => 'Simpan perubahan Anda [alt-s]',
+'tooltip-preview' => 'Pratayang perubahan Anda -- mohon gunakan ini sebelum menyimpan! [alt-p]',
+'tooltip-diff' => 'Lihat perubahan yang telah Anda lakukan. [alt-v]',
+'tooltip-compareselectedversions' => 'Lihat perbedaan antara dua versi halaman yang dipilih. [alt-v]',
+'tooltip-watch' => 'Tambahkan halaman ini ke daftar pantauan Anda [alt-w]',
+
+# stylesheets
+
+'common.css' => '/** CSS yang berada di sini akan diterapkan untuk semua kulit */',
+'monobook.css' => '/* CSS yang berada di sini akan mempengaruhi semua pengguna yang menggunakan kulit Monobook */',
+
+# Metadata
+"nodublincore" => "Metadata Dublin Core RDF dimatikan di server ini.",
+"nocreativecommons" => "Metadata Creative Commons RDF dimatikan di server ini.",
+"notacceptable" => "Server wiki tidak dapat menyediakan data dalam format yang dapat dibaca oleh client Anda.",
+
+# Attribution
+
+"anonymous" => "Pengguna(-pengguna) anonim {{SITENAME}}",
+"siteuser" => "Pengguna {{SITENAME}} $1",
+"lastmodifiedatby" => "Halaman ini terakhir kali diubah $2, $1 oleh $3.",
+"and" => "dan",
+"othercontribs" => "Didasarkan pada karya $1.",
+'others' => 'lainnya',
+"siteusers" => "Pengguna(-pengguna) {{SITENAME}} $1",
+'creditspage' => 'Penghargaan halaman',
+'nocredits' => 'Tidak ada informasi penghargaan yang tersedia untuk halaman ini.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Filter pencegah spam',
+'spamprotectiontext' => 'Halaman yang ingin Anda simpan diblokir oleh filter spam. Ini mungkin disebabkan oleh pranala ke situs luar.',
+'spamprotectionmatch' => 'Teks berikut ini memancing filter spam kami: $1',
+'subcategorycount' => "Ada $1 subkategori dalam kategori ini.",
+'categoryarticlecount' => "Ada $1 artikel dalam kategori ini.",
+'category-media-count' => "Ada $1 berkas dalam kategori ini.",
+'listingcontinuesabbrev' => " samb.",
+'spambot_username' => 'Pembersihan span MediaWiki',
+'spam_reverting' => 'Mengembalikan ke versi terakhir yang tak memiliki pranala ke $1',
+'spam_blanking' => 'Semua revisi yang memiliki pranala ke $1, pengosongan',
+
+# Info page
+"infosubtitle" => "Informasi halaman",
+"numedits" => "Jumlah penyuntingan (artikel): $1",
+"numtalkedits" => "Jumlah penyuntingan (halaman diskusi): $1",
+"numwatchers" => "Jumlah pengamat: $1",
+"numauthors" => "Jumlah pengarang yang berbeda (artikel): $1",
+"numtalkauthors" => "Jumlah pengarang yang berbeda (halaman diskusi): $1",
+
+# Math options
+'mw_math_png' => "Selalu buat PNG",
+'mw_math_simple' => "HTML jika sangat sederhana atau PNG",
+'mw_math_html' => "HTML jika mungkin atau PNG",
+'mw_math_source' => "Biarkan sebagai TeX (untuk penjelajah web teks)",
+'mw_math_modern' => "Disarankan untuk penjelajah web modern",
+'mw_math_mathml' => "MathML jika mungkin (percobaan)",
+
+# Patrolling
+'markaspatrolleddiff' => "Tandai telah dipatroli",
+'markaspatrolledtext' => "Tandai artikel ini telah dipatroli",
+'markedaspatrolled' => "Ditandai telah dipatroli",
+'markedaspatrolledtext' => "Revisi yang dipilih telah ditandai terpatroli",
+'rcpatroldisabled' => "Patroli perubahan terbaru dimatikan",
+'rcpatroldisabledtext' => "Fitur patroli perubahan terbaru sedang dimatikan.",
+'markedaspatrollederror' => "Tidak dapat menandai telah dipatroli",
+'markedaspatrollederrortext' => "Anda harus menentukan satu revisi untuk ditandai sebagai yang dipatroli.",
+'markedaspatrollederror-noautopatrol' => 'Anda tidak diizinkan menandai suntingan Anda sendiri dipatroli.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* bantuan peralatan dan kunci akses */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Halaman pengguna saya\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Halaman pengguna IP Anda\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Halaman pembicaraan saya\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskusi tentang suntingan dari alamat IP ini\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Preferensi saya\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Daftar halaman yang Anda pantau.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Daftar sumbangan saya\');
+ta[\'pt-login\'] = new Array(\'o\',\'Anda disarankan untuk masuk log, meskipun hal itu tidak diwajibkan.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Anda disarankan untuk masuk log, meskipun hal itu tidak diwajibkan.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Keluar log\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Diskusi tentang artikel\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Anda dapat menyunting halaman ini. Silakan gunakan tombol pratayang sebelum menyimpan.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Tambahkan komentar ke diskusi ini.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Halaman ini dilindungi. Anda hanya dapat melihat sumbernya.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Versi-versi sebelumnya dari halaman ini.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Lindungi halaman ini\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Hapus halaman ini\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Kembalikan suntingan ke halaman ini sebelum halaman ini dihapus\');
+ta[\'ca-move\'] = new Array(\'m\',\'Pindahkan halaman ini\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Tambahkan halaman ini ke daftar pantauan Anda\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Hapus halaman ini dari daftar pantauan Anda\');
+ta[\'search\'] = new Array(\'f\',\'Cari dalam wiki ini\');
+ta[\'p-logo\'] = new Array(\'\',\'Halaman Utama\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Kunjungi Halaman Utama\');
+ta[\'n-portal\'] = new Array(\'\',\'Tentang proyek, apa yang dapat anda lakukan, di mana mencari sesuatu\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Temukan informasi tentang kejadian terkini\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Daftar perubahan terbaru dalam wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Tampilkan sembarang halaman\');
+ta[\'n-help\'] = new Array(\'\',\'Tempat mencari bantuan.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Dukung kami\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Daftar semua halaman wiki yang berpaut ke sini\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Perubahan terbaru halaman-halaman yang berpaut dengan halaman ini\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS feed untuk halaman ini\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom feed untuk halaman ini\');
+ta[\'t-contributions\'] = new Array(\'\',\'Lihat daftar sumbangan pengguna ini\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Kirimkan surat-e kepada pengguna ini\');
+ta[\'t-upload\'] = new Array(\'u\',\'Muatkan gambar atau berkas media\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Daftar semua halaman istimewa\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Lihat halaman isi (artikel)\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Lihat halaman pengguna\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Lihat halaman media\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Ini adalah halaman istimewa yang tidak dapat disunting.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Lihat halaman proyek\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Lihat halaman berkas\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Lihat pesan sistem\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Lihat templat\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Lihat halaman bantuan\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Lihat halaman kategori\');',
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Semua JavaScript yang ada di sini akan dimuat untuk semua pengguna pada semua halaman. */',
+
+# image deletion
+'deletedrevision' => 'Revisi lama yang dihapus $1.',
+
+# browsing diffs
+'previousdiff' => '← Perbedaan sebelumnya',
+'nextdiff' => 'Perbedaan selanjutnya →',
+
+'imagemaxsize' => 'Batasi ukuran gambar dalam halaman deskripsi berkas sampai:',
+'thumbsize' => 'Ukuran gambar kecil (thumbnail):',
+'showbigimage' => 'Unduhkan versi resolusi tinggi ($1x$2, $3 KB)',
+
+'newimages' => 'Galeri berkas baru',
+'showhidebots' => '($1 bot)',
+'noimages' => 'Tidak ada yang dilihat.',
+'sp-newimages-showfrom' => 'Tampilkan berkas baru dimulai dari $1',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+# variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+# variants for Kazakh language
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-cn' => 'kk-cn',
+'variantname-kk' => 'kk',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Pengguna:',
+'speciallogtitlelabel' => 'Judul:',
+
+'passwordtooshort' => 'Kata sandi Anda terlalu pendek. Kata sandi minimum terdiri dari $1 karakter.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Peringatan\'\'\': Berkas ini mungkin mengandung kode berbahaya yang jika dijalankan dapat mempengaruhi sistem Anda.<hr />',
+
+'fileinfo' => '$1KB, tipe MIME: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadata',
+'metadata-help' => 'Berkas ini mengandung informasi tambahan yang mungkin ditambahkan oleh kamera digital atau pemindai yang digunakan untuk membuat atau mendigitalisasi berkas. Jika berkas ini telah mengalami modifikasi, detil yang ada mungkin tidak secara penuh merefleksikan informasi dari gambar yang sudah dimodifikasi ini.',
+'metadata-expand' => 'Tampilkan detil tambahan',
+'metadata-collapse' => 'Sembunyikan detil tambahan',
+'metadata-fields' => 'Entri metadata EXIF berikut akan ditampilkan pada halaman informasi gambar jika tabel metadata disembunyikan. Entri lain secara baku akan disembunyikan
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber',
+
+# Exif tags
+'exif-imagewidth' =>'Lebar',
+'exif-imagelength' =>'Tinggi',
+'exif-bitspersample' =>'Bit per komponen',
+'exif-compression' =>'Skema kompresi',
+'exif-photometricinterpretation' =>'Komposisi piksel',
+'exif-orientation' =>'Orientasi',
+'exif-samplesperpixel' =>'Jumlah komponen',
+'exif-planarconfiguration' =>'Pengaturan data',
+'exif-ycbcrsubsampling' =>'Rasio subsampling Y ke C',
+'exif-ycbcrpositioning' =>'Penempatan Y dan C',
+'exif-xresolution' =>'Resolusi horizontal',
+'exif-yresolution' =>'Resolusi vertikal',
+'exif-resolutionunit' =>'Satuan resolusi X dan Y',
+'exif-stripoffsets' =>'Lokasi data gambar',
+'exif-rowsperstrip' =>'Jumlah baris per strip',
+'exif-stripbytecounts' =>'Bita per strip kompresi',
+'exif-jpeginterchangeformat' =>'Ofset ke JPEG SOI',
+'exif-jpeginterchangeformatlength' =>'Bita data JPEG',
+'exif-transferfunction' =>'Fungsi transfer',
+'exif-whitepoint' =>'Kromatisitas titik putih',
+'exif-primarychromaticities' =>'Kromatisitas warna primer',
+'exif-ycbcrcoefficients' =>'Koefisien matriks transformasi ruang warna',
+'exif-referenceblackwhite' =>'Nilai referensi pasangan hitam putih',
+'exif-datetime' =>'Tanggal dan waktu perubahan berkas',
+'exif-imagedescription' =>'Judul gambar',
+'exif-make' =>'Produsen kamera',
+'exif-model' =>'Model kamera',
+'exif-software' =>'Perangkat lunak',
+'exif-artist' =>'Pembuat',
+'exif-copyright' =>'Pemilik hak cipta',
+'exif-exifversion' =>'Versi Exif',
+'exif-flashpixversion' =>'Dukungan versi Flashpix',
+'exif-colorspace' =>'Ruang warna',
+'exif-componentsconfiguration' =>'Arti tiap komponen',
+'exif-compressedbitsperpixel' =>'Mode kompresi gambar',
+'exif-pixelydimension' =>'Lebar gambar yang sah',
+'exif-pixelxdimension' =>'Tinggi gambar yang sah',
+'exif-makernote' =>'Catatan produsen',
+'exif-usercomment' =>'Komentar pengguna',
+'exif-relatedsoundfile' =>'Berkas audio yang berhubungan',
+'exif-datetimeoriginal' =>'Tanggal dan waktu pembuatan data',
+'exif-datetimedigitized' =>'Tanggal dan waktu digitalisasi',
+'exif-subsectime' =>'Subdetik DateTime',
+'exif-subsectimeoriginal' =>'Subdetik DateTimeOriginal',
+'exif-subsectimedigitized' =>'Subdetik DateTimeDigitized',
+'exif-exposuretime' =>'Waktu pajanan',
+'exif-exposuretime-format' => '$1 detik ($2)',
+'exif-fnumber' =>'Nilai F',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'Program pajanan',
+'exif-spectralsensitivity' =>'Sensitivitas spektral',
+'exif-isospeedratings' =>'ISO speed rating',
+'exif-oecf' =>'Faktor konversi optoelektronik',
+'exif-shutterspeedvalue' =>'Kecepatan shutter',
+'exif-aperturevalue' =>'Aperture',
+'exif-brightnessvalue' =>'Brightness',
+'exif-exposurebiasvalue' =>'Bias pajanan',
+'exif-maxaperturevalue' =>'Maximum land aperture',
+'exif-subjectdistance' =>'Jarak subjek',
+'exif-meteringmode' =>'Metering mode',
+'exif-lightsource' =>'Sumber cahaya',
+'exif-flash' =>'Flash',
+'exif-focallength' =>'Lens focal length',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' =>'Wilayah subjek',
+'exif-flashenergy' =>'Flash energy',
+'exif-spatialfrequencyresponse' =>'Respons frekuensi spasial',
+'exif-focalplanexresolution' =>'Resolusi focal plane X',
+'exif-focalplaneyresolution' =>'Resolusi focal plane Y',
+'exif-focalplaneresolutionunit' =>'Unit resolusi focal plane',
+'exif-subjectlocation' =>'Lokasi subjek',
+'exif-exposureindex' =>'Indeks pajanan',
+'exif-sensingmethod' =>'Metode sensing',
+'exif-filesource' =>'Sumber berkas',
+'exif-scenetype' =>'Tipe scene',
+'exif-cfapattern' =>'Pola CFA',
+'exif-customrendered' =>'Proses buatan gambar',
+'exif-exposuremode' =>'Mode pajanan',
+'exif-whitebalance' =>'White Balance',
+'exif-digitalzoomratio' =>'Rasio pembesaran digital',
+'exif-focallengthin35mmfilm' =>'Focal length in 35 mm film',
+'exif-scenecapturetype' =>'Tipe scene capture',
+'exif-gaincontrol' =>'Kontrol scene',
+'exif-contrast' =>'Kontras',
+'exif-saturation' =>'Saturasi',
+'exif-sharpness' =>'Ketajaman',
+'exif-devicesettingdescription' =>'Deskripsi pengaturan alat',
+'exif-subjectdistancerange' =>'Jarak subjek',
+'exif-imageuniqueid' =>'ID unik gambar',
+'exif-gpsversionid' =>'Versi tag GPS',
+'exif-gpslatituderef' =>'Lintang Utara atau Selatan',
+'exif-gpslatitude' =>'Lintang',
+'exif-gpslongituderef' =>'Bujur Timur atau Barat',
+'exif-gpslongitude' =>'Bujur',
+'exif-gpsaltituderef' =>'Referensi ketinggian',
+'exif-gpsaltitude' =>'Ketinggian',
+'exif-gpstimestamp' =>'Waktu GPS (jam atom)',
+'exif-gpssatellites' =>'Satelit untuk pengukuran',
+'exif-gpsstatus' =>'Status penerima',
+'exif-gpsmeasuremode' =>'Mode pengukuran',
+'exif-gpsdop' =>'Ketepatan pengukuran',
+'exif-gpsspeedref' =>'Unit kecepatan',
+'exif-gpsspeed' =>'Kecepatan penerima GPS',
+'exif-gpstrackref' =>'Referensi arah gerakan',
+'exif-gpstrack' =>'Arah gerakan',
+'exif-gpsimgdirectionref' =>'Referensi arah gambar',
+'exif-gpsimgdirection' =>'Arah gambar',
+'exif-gpsmapdatum' =>'Data survei geodesi',
+'exif-gpsdestlatituderef' =>'Referensi lintang dari tujuan',
+'exif-gpsdestlatitude' =>'Lintang tujuan',
+'exif-gpsdestlongituderef' =>'Referensi bujur dari tujuan',
+'exif-gpsdestlongitude' =>'Bujur tujuan',
+'exif-gpsdestbearingref' =>'Referensi bearing of destination',
+'exif-gpsdestbearing' =>'Bearing of destination',
+'exif-gpsdestdistanceref' =>'Referensi jarak dari tujuan',
+'exif-gpsdestdistance' =>'Jarak dari tujuan',
+'exif-gpsprocessingmethod' =>'Nama metode proses GPS',
+'exif-gpsareainformation' =>'Nama wilayah GPS',
+'exif-gpsdatestamp' =>'Tanggal GPS',
+'exif-gpsdifferential' =>'Koreksi diferensial GPS',
+
+# Exif attributes
+
+'exif-compression-1' => 'Tak terkompresi',
+'exif-compression-6' => 'JPEG',
+
+'exif-unknowndate' => 'Tanggal tak diketahui',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normal', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Dibalik horizontal', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Diputar 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Dibalik vertikal', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Diputar 90° CCW dan dibalik vertical', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Diputar 90° CW', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Diputar 90° CW dan dibalik vertical', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Diputar 90° CCW', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'format chunky',
+'exif-planarconfiguration-2' => 'format planar',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'tak tersedia',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Tak terdefinisi',
+'exif-exposureprogram-1' => 'Manual',
+'exif-exposureprogram-2' => 'Program normal',
+'exif-exposureprogram-3' => 'Prioritas aperture',
+'exif-exposureprogram-4' => 'Prioritas shutter',
+'exif-exposureprogram-5' => 'Program kreatif (condong ke depth of field)',
+'exif-exposureprogram-6' => 'Program aksi (condong ke fast shutter speed)',
+'exif-exposureprogram-7' => 'Mode potret (untuk foto closeup dengan latar belakang tak fokus)',
+'exif-exposureprogram-8' => 'Mode pemandangan (untuk foto pemandangan dengan latar belakang fokus)',
+
+'exif-subjectdistance-value' => '$1 meter',
+
+'exif-meteringmode-0' => 'Tak diketahui',
+'exif-meteringmode-1' => 'Average',
+'exif-meteringmode-2' => 'CenterWeightedAverage',
+'exif-meteringmode-3' => 'Spot',
+'exif-meteringmode-4' => 'MultiSpot',
+'exif-meteringmode-5' => 'Pattern',
+'exif-meteringmode-6' => 'Partial',
+'exif-meteringmode-255' => 'Lain-lain',
+
+'exif-lightsource-0' => 'Tak diketahui',
+'exif-lightsource-1' => 'Daylight',
+'exif-lightsource-2' => 'Fluorescent',
+'exif-lightsource-3' => 'Tungsten (incandescent light)',
+'exif-lightsource-4' => 'Flash',
+'exif-lightsource-9' => 'Fine weather',
+'exif-lightsource-10' => 'Cloudy weather',
+'exif-lightsource-11' => 'Shade',
+'exif-lightsource-12' => 'Daylight fluorescent (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Day white fluorescent (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Cool white fluorescent (W 3900 – 4500K)',
+'exif-lightsource-15' => 'White fluorescent (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standard light A',
+'exif-lightsource-18' => 'Standard light B',
+'exif-lightsource-19' => 'Standard light C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO studio tungsten',
+'exif-lightsource-255' => 'Sumber cahaya lain',
+
+'exif-focalplaneresolutionunit-2' => 'inci',
+
+'exif-sensingmethod-1' => 'Tak terdefinisi',
+'exif-sensingmethod-2' => 'One-chip color area sensor',
+'exif-sensingmethod-3' => 'Two-chip color area sensor',
+'exif-sensingmethod-4' => 'Three-chip color area sensor',
+'exif-sensingmethod-5' => 'Color sequential area sensor',
+'exif-sensingmethod-7' => 'Trilinear sensor',
+'exif-sensingmethod-8' => 'Color sequential linear sensor',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'Gambar foto langsung',
+
+'exif-customrendered-0' => 'Proses normal',
+'exif-customrendered-1' => 'Proses kustom',
+
+'exif-exposuremode-0' => 'Pajanan otomatis',
+'exif-exposuremode-1' => 'Pajanan manual',
+'exif-exposuremode-2' => 'Braket otomatis',
+
+'exif-whitebalance-0' => 'Auto white balance',
+'exif-whitebalance-1' => 'Manual white balance',
+
+'exif-scenecapturetype-0' => 'Standar',
+'exif-scenecapturetype-1' => 'Melebar',
+'exif-scenecapturetype-2' => 'Potret',
+'exif-scenecapturetype-3' => 'Scene malam',
+
+'exif-gaincontrol-0' => 'Tak ada',
+'exif-gaincontrol-1' => 'Low gain up',
+'exif-gaincontrol-2' => 'High gain up',
+'exif-gaincontrol-3' => 'Low gain down',
+'exif-gaincontrol-4' => 'High gain down',
+
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'Lembut',
+'exif-contrast-2' => 'Keras',
+
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Saturasi rendah',
+'exif-saturation-2' => 'Saturasi tinggi',
+
+'exif-sharpness-0' => 'Normal',
+'exif-sharpness-1' => 'Lembut',
+'exif-sharpness-2' => 'Keras',
+
+'exif-subjectdistancerange-0' => 'Tak diketahui',
+'exif-subjectdistancerange-1' => 'Makro',
+'exif-subjectdistancerange-2' => 'Close view',
+'exif-subjectdistancerange-3' => 'Distant view',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Lintang utara',
+'exif-gpslatitude-s' => 'Lintang selatan',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Bujur timur',
+'exif-gpslongitude-w' => 'Bujur barat',
+
+'exif-gpsstatus-a' => 'Pengukuran sedang berlangsung',
+'exif-gpsstatus-v' => 'Interoperabilitas pengukuran',
+
+'exif-gpsmeasuremode-2' => 'Pengukuran 2-dimensi',
+'exif-gpsmeasuremode-3' => 'Pengukuran 3-dimensi',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometer per jam',
+'exif-gpsspeed-m' => 'Mil per jam',
+'exif-gpsspeed-n' => 'Knot',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Arah sejati',
+'exif-gpsdirection-m' => 'Arah magnetis',
+
+# external editor support
+'edit-externally' => 'Sunting berkas ini dengan aplikasi luar',
+'edit-externally-help' => 'Lihat [http://meta.wikimedia.org/wiki/Help:External_editors instruksi pengaturan] untuk informasi lebih lanjut.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'semua',
+'imagelistall' => 'semua',
+'watchlistall1' => 'semua',
+'watchlistall2' => 'semua',
+'namespacesall' => 'semua',
+
+# E-mail address confirmation
+'confirmemail' => 'Konfirmasi alamat surat-e',
+'confirmemail_noemail' => 'Anda tidak memberikan alamat surat-e yang sah di [[Special:Preferences|preferensi pengguna]] Anda.',
+'confirmemail_text' => "{{ns:project}} mengharuskan Anda untuk melakukan konfirmasi atas alamat surat elektronik Anda sebelum fitur-fitur surat elektronik dapat digunakan. Tekan tombol di bawah ini untuk mengirimi Anda sebuah surat elektronik yang berisi kode konfirmasi yang berupa sebuah alamat internet. Salin alamat tersebut ke penjelajah web Anda dan buka alamat tersebut untuk melakukan konfirmasi sehingga menginformasikan {{ns:project}} bahwa alamat surat elektronik Anda valid.",
+'confirmemail_pending' => '<div class="error">Suatu kode konfirmasi telah dikirimkan kepada Anda; jika Anda baru saja membuat akun Anda, silakan tunggu beberapa menit untuk surat tersebut tiba sebelum mencoba untuk meminta satu kode baru.</div>',
+'confirmemail_send' => 'Kirim kode konfirmasi',
+'confirmemail_sent' => 'Surat elektronik berisi kode konfirmasi telah dikirim.',
+'confirmemail_oncreate' => 'Suatu kode konfirmasi telah dikirimkan ke alamat surat-e Anda. Kode ini tidak dibutuhkan untuk masuk log, tapi dibutuhkan sebelum menggunakan semua fitur yang menggunakan surat-e di wiki ini.',
+'confirmemail_sendfailed' => 'Surat-e konfirmasi tidak berhasil dikirim. Harap cek kemungkinan karakter ilegal pada alamat surat-e. Pengirim menginformasikan: $1',
+'confirmemail_invalid' => 'Kode konfirmasi salah. Kode tersebut mungkin sudah kadaluwarsa.',
+'confirmemail_needlogin' => 'Anda harus melakukan $1 untuk mengkonfirmasikan alamat surat-e Anda.',
+'confirmemail_success' => 'Alamat surat-e Anda telah dikonfirmasi. Sekarang Anda dapat masuk log dan mulai menggunakan wiki.',
+'confirmemail_loggedin' => 'Alamat surat elektronik Anda telah dikonfirmasi.',
+'confirmemail_error' => 'Terjadi kesalahan sewaktu menyimpan konfirmasi Anda.',
+
+'confirmemail_subject' => 'Konfirmasi alamat surat-e {{SITENAME}}',
+'confirmemail_body' => "Seseorang, mungkin Anda, dari alamat IP $1, telah mendaftarkan akun \"$2\" dengan alamat surat-e ini di {{SITENAME}}.
+
+Untuk mengkonfirmasikan bahwa akun ini benar dimiliki oleh Anda sekaligus mengaktifkan fitur surat-e di {{SITENAME}}, ikuti pranala berikut pada penjelajah web Anda:
+
+$3
+
+Jika Anda merasa *tidak pernah* mendaftar, jangan ikuti pranala di atas. Kode konfirmasi ini akan kadaluwarsa pada $4.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Coba pencocokan eksak',
+'searchfulltext' => 'Cari di teks lengkap',
+'createarticle' => 'Buat artikel',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Transklusi interwiki dimatikan]',
+'scarytranscludefailed' => '[Pengambilan templat $1 gagal; maaf]',
+'scarytranscludetoolong' => '[URL terlalu panjang; maaf]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Pelacakan balik untuk artikel ini:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Hapus])',
+'trackbacklink' => 'Lacak balik',
+'trackbackdeleteok' => 'Pelacakan balik berhasil dihapus.',
+
+
+# delete conflict
+
+'deletedwhileediting' => 'Perhatian: Halaman ini telah dihapus setelah Anda mulai melakukan penyuntingan!',
+'confirmrecreate' => 'Pengguna [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|talk]]) telah menghapus halaman selagi Anda mulai melakukan penyuntingan dengan alasan:
+: \'\'$2\'\'
+Silakan konfirmasi jika Anda ingin membuat ulang halaman ini.',
+'recreate' => 'Buat ulang',
+'tooltip-recreate' => 'Buat ulang halaman walaupun sebenarnya telah dihapus',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Sedang dialihkan ke [[$1]]...',
+
+# action=purge
+'confirm_purge' => "Hapus ''cache'' halaman ini?
+
+$1",
+'confirm_purge_button' => 'OK',
+
+'youhavenewmessagesmulti' => "Anda mendapat pesan-pesan baru $1",
+
+'searchcontaining' => "Mencari artikel yang mengandung ''$1''.",
+'searchnamed' => "Mencari artikel yang berjudul ''$1''.",
+'articletitles' => "Artikel yang diawali ''$1''",
+'hideresults' => 'Sembunyikan hasil',
+
+# DISPLAYTITLE
+'displaytitle' => '(Pranala ke halaman ini sebagai [[$1]])',
+
+'loginlanguagelabel' => 'Bahasa: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; halaman sebelumnya',
+'imgmultipagenext' => 'halaman selanjutnya &rarr;',
+'imgmultigo' => 'Cari!',
+'imgmultigotopre' => 'Ke halaman',
+
+# Table pager
+'ascending_abbrev' => 'naik',
+'descending_abbrev' => 'turun',
+'table_pager_next' => 'Halaman selanjutnya',
+'table_pager_prev' => 'Halaman sebelumnya',
+'table_pager_first' => 'Halaman pertama',
+'table_pager_last' => 'Halaman terakhir',
+'table_pager_limit' => 'Tampilkan $1 entri per halaman',
+'table_pager_limit_submit' => 'Cari',
+'table_pager_empty' => 'Tidak ditemukan',
+
+# Auto-summaries
+'autosumm-blank' => 'Menghapus semua isi dari halaman',
+'autosumm-replace' => 'Mengganti halaman dengan \'$1\'',
+'autoredircomment' => 'Alihkan ke [[$1]]',
+'autosumm-new' => 'Halaman baru: $1',
+
+);
+
+?>
diff --git a/languages/messages/MessagesIi.php b/languages/messages/MessagesIi.php
new file mode 100644
index 000000000000..314684f22ec2
--- /dev/null
+++ b/languages/messages/MessagesIi.php
@@ -0,0 +1,9 @@
+<?php
+/** Yi (ꆇꉙ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'zh-cn';
+?>
diff --git a/languages/messages/MessagesIs.php b/languages/messages/MessagesIs.php
new file mode 100644
index 000000000000..2aec09a831a0
--- /dev/null
+++ b/languages/messages/MessagesIs.php
@@ -0,0 +1,706 @@
+<?php
+/** Icelandic (Íslenska)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Sleppa', 'Fast vinstra megin', 'Fast hægra megin', 'Fljótandi til vinstri'
+);
+
+$skinNames = array(
+ 'standard' => 'Klassískt',
+ 'nostalgia' => 'Gamaldags',
+ 'cologneblue' => 'Kölnarblátt',
+ 'myskin' => 'Mitt þema',
+);
+
+$datePreferences = array(
+ 'default',
+ 'dmyt',
+ 'short dmyt',
+ 'tdmy',
+ 'short tdmy',
+ 'ISO 8601',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'dmyt',
+ 'short dmyt',
+ 'tdmy',
+ 'short tdmy',
+);
+
+$dateFormats = array(
+ 'dmyt time' => 'H:i',
+ 'dmyt date' => 'j. F Y',
+ 'dmyt both' => 'j. F Y "kl." H:i',
+
+ 'short dmyt time' => 'H:i',
+ 'short dmyt date' => 'j. M. Y',
+ 'short dmyt both' => 'j. M. Y "kl." H:i',
+
+ 'tdmy time' => 'H:i',
+ 'tdmy date' => 'j. F Y',
+ 'tdmy both' => 'H:i, j. F Y',
+
+ 'short tdmy time' => 'H:i',
+ 'short tdmy date' => 'j. M. Y',
+ 'short tdmy both' => 'H:i, j. M. Y',
+);
+
+$magicWords = array(
+ 'redirect' => array( 0, '#tilvísun', '#TILVÍSUN', '#redirect' ), // MagicWord::initRegex() sucks
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Miðill',
+ NS_SPECIAL => 'Kerfissíða',
+ NS_MAIN => '',
+ NS_TALK => 'Spjall',
+ NS_USER => 'Notandi',
+ NS_USER_TALK => 'Notandaspjall',
+ NS_PROJECT_TALK => '$1spjall',
+ NS_IMAGE => 'Mynd',
+ NS_IMAGE_TALK => 'Myndaspjall',
+ NS_MEDIAWIKI => 'Melding',
+ NS_MEDIAWIKI_TALK => 'Meldingarspjall',
+ NS_TEMPLATE => 'Snið',
+ NS_TEMPLATE_TALK => 'Sniðaspjall',
+ NS_HELP => 'Hjálp',
+ NS_HELP_TALK => 'Hjálparspjall',
+ NS_CATEGORY => 'Flokkur',
+ NS_CATEGORY_TALK => 'Flokkaspjall'
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkPrefixExtension = true;
+$linkTrail = '/^([áðéíóúýþæöa-z-–]+)(.*)$/sDu';
+
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+
+$messages = array(
+'linkprefix'=> '/^(.*?)([áÁðÐéÉíÍóÓúÚýÝþÞæÆöÖA-Za-z-–]+)$/sDu',
+
+'1movedto2' => "$1 færð á $2",
+'1movedto2_redir' => "$1 færð á $2 yfir tilvísun",
+'monobook.css' => "
+/* Stórir stafir í ýmsu */
+#p-personal ul { text-transform: inherit; } /* notandanfn, spjall, stillingar */
+.portlet h5 { text-transform: inherit;} /* flakk, leit, verkfæri... */
+#p-cactions li a {text-transform: inherit;} /* notandasíða, spjall... */",
+'monobook.js' => "/* tooltips and access keys */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','Notendasíðan mín');
+ta['pt-anonuserpage'] = new Array('.','Notendasíðan fyrir IP töluna þína');
+ta['pt-mytalk'] = new Array('n','Spallsíðan mín');
+ta['pt-anontalk'] = new Array('n','Spjallsíðan fyrir þessa IP tölu');
+ta['pt-preferences'] = new Array('','Almennar stillingar');
+ta['pt-watchlist'] = new Array('l','Vaktlistinn.');
+ta['pt-mycontris'] = new Array('y','Listi yfir framlög þín');
+ta['pt-login'] = new Array('o','Þú ert hvattur/hvött til að innskrá þig, það er hinsvegar ekki nauðsynlegt.');
+ta['pt-anonlogin'] = new Array('o','Þú ert hvattur/hvött til að innskrá þig, það er hinsvegar ekki nauðsynlegt.');
+ta['pt-logout'] = new Array('','Útskráning');
+ta['ca-talk'] = new Array('t','Spallsíða þessarar síðu');
+ta['ca-edit'] = new Array('e','Þú getur breytt síðu þessari, vinsamlegast notaðu „forskoða“ hnappinn áður en þú vistar');
+ta['ca-addsection'] = new Array('+','Viðbótarumræða.');
+ta['ca-viewsource'] = new Array('e','Síða þessi er vernduð, þú getur þó skoðað frumkóða hennar.');
+ta['ca-history'] = new Array('h','Eldri útgáfur af síðunni.');
+ta['ca-protect'] = new Array('=','Vernda þessa síðu');
+ta['ca-delete'] = new Array('d','Eyða þessari síðu');
+ta['ca-undelete'] = new Array('d','Endurvekja breytingar á síðu þessari fyrir en henni var tortímt');
+ta['ca-move'] = new Array('m','Færa þessa síðu');
+ta['ca-watch'] = new Array('w','Bæta þessari síðu við á vaktlistann');
+ta['ca-unwatch'] = new Array('w','Fjarlægja þessa síðu af vaktlistanum');
+ta['search'] = new Array('f','Leit');
+ta['p-logo'] = new Array('','Forsíða');
+ta['n-mainpage'] = new Array('z','Forsíða {{SITENAME}}');
+ta['n-portal'] = new Array('','Um verkefnið, hvernig er hægt að hjálpa og hvar á að byrja');
+ta['n-currentevents'] = new Array('','Líðandi stund');
+ta['n-recentchanges'] = new Array('r','Listi yfir nýlegar breytingar.');
+ta['n-randompage'] = new Array('x','Handahófsvalin síða');
+ta['n-help'] = new Array('','Efnisyfirlit yfir hjálparsíður.');
+ta['n-sitesupport'] = new Array('','Fjárframlagssíða');
+ta['t-whatlinkshere'] = new Array('j','Listi yfir síður sem tengjast í þessa');
+ta['t-recentchangeslinked'] = new Array('k','Nýlegar breitingar á ítengdum síðum');
+ta['feed-rss'] = new Array('','RSS fyrir þessa síðu');
+ta['feed-atom'] = new Array('','Atom fyrir þessa síðu');
+ta['t-contributions'] = new Array('','Sýna framlagslista þessa notanda');
+ta['t-emailuser'] = new Array('','Senda notanda þessum póst');
+ta['t-upload'] = new Array('u','Innhlaða myndum eða margmiðlunarskrám');
+ta['t-specialpages'] = new Array('q','Listi yfir kerfissíður');
+ta['ca-nstab-main'] = new Array('c','Sýna síðuna');
+ta['ca-nstab-user'] = new Array('c','Sýna notendasíðuna');
+ta['ca-nstab-media'] = new Array('c','Sýna margmiðlunarsíðuna');
+ta['ca-nstab-special'] = new Array('','Þetta er kerfissíða, þér er óhæft að breyta henni.');
+ta['ca-nstab-project'] = new Array('a','Sýna verkefnasíðuna');
+ta['ca-nstab-image'] = new Array('c','Sýna myndasíðuna');
+ta['ca-nstab-mediawiki'] = new Array('c','Sýna kerfisskilaboðin');
+ta['ca-nstab-template'] = new Array('c','View the template');
+ta['ca-nstab-help'] = new Array('c','Sýna hjálparsíðuna');
+ta['ca-nstab-category'] = new Array('c','Sýna efnisflokkasíðuna');",
+'about' => "Um",
+'aboutpage' => "Project:Um",
+'aboutsite' => "Um {{SITENAME}}",
+'accmailtext' => "Lykilorðið fyrir „$1“ hefur verið sent á $2.",
+'accmailtitle' => "Lykilorð sent.",
+'acct_creation_throttle_hit' => "Fyrirgefðu, þú hefur nú þegar búið til $1 aðgang(a). Þú getur ekki búið til fleiri.",
+'actioncomplete' => "Aðgerð lokið",
+'addedwatch' => "Bætt á vaktlistann",
+'addedwatchtext' => "Síðunni „$1“ hefur verið bætt á [[Special:Watchlist|Vaktlistann]] þinn.
+Frekari breytingar á henni eða spallsíðu hennar munu verða sýndar þar.
+Þar að auki verður síða þessi '''feitletruð''' á [[Special:Recentchanges|Nýlegum breytingum]]
+svo auðveldara sé að sjá hana þar meðal fjöldans.
+
+<p>Til að fjarlægja síðu þessa af vaktlistanum þarft þú að ýta á tengilinn er merktur er „afvakta“.",
+'allmessages' => "Kerfismeldingar",
+'allmessagescurrent' => "Núverandi texti",
+'allmessagesdefault' => "Sjálfgefinn texti",
+'allmessagesname' => "Titill",
+'allmessagestext' => "Listi yfir meldingar í „{{ns:8}}“ nafnarýminu.",
+'allpages' => "Allar síður",
+'alphaindexline' => "$1 til $2",
+'alreadyloggedin' => "<strong>Notandinn $1 er þegar innskráður!</strong><br />",
+'ancientpages' => "Elstu síður",
+'anontalkpagetext' => "----Þetta er spjallsíða fyrir óskráðan notanda sem hefur ekki búið til aðgang enn þá eða notar hann ekki, slíkir notendur þekkjast á [[IP tala|IP tölu]] sinni. Það getur gerst að margir notendur deili sömu IP tölu þannig að athugasemdum sem beint er til eins notanda geta birst á spjallsíðu annars. [[Special:Userlogin|Skráðu þig sem notanda]] til að koma í veg fyrir svona misskilning.''",
+'apr' => "apr",
+'april' => "apríl",
+'articleexists' => "Annaðhvort er þegar til síða undir þessum titli,
+eða sá titill sem þú hefur valið er ekki gildur.
+Vinsamlegast veldu annan titil.",
+'aug' => "ágú",
+'august' => "ágúst",
+'badfilename' => "Skáarnafninu hefur verið breytt í „$1“.",
+'badquery' => "Illa sniðin leitarfyrirspurn",
+'badtitle' => "Ógildur titill",
+'badtitletext' => "Umbeðin síðutitill er ógildur.",
+'blanknamespace' => "(Aðalnafnrýmið)",
+'blockip' => "Banna notanda",
+'blockipsuccesstext' => "„$1“ hefur verið bannaður.<br />
+Sjá [[Special:Ipblocklist|bannaðar notendur og IP tölur]] fyrir yfirlit yfir núverandi bönn.",
+'blockiptext' => "Hægt er að hindra einstaka notendur eða IP tölur í að gera breytingar á {{SITENAME}}
+
+Útrennslutímar eru í stöðluðu GNU sniði sem farið er yfir í [http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html tar handbókinni], Til dæmis „1 hour“, „2 days“, „next Wednesday“, „1 January 2017“ eða „indefinite“ og „infinite“ til að banna að eylífu, þetta ætti þó aðeins að vera notað á ódauðlegar verur þar sem um 150 ár ættu að duga jafnvel á þrjóskasta fólk.
+
+Sjá [[meta:Range blocks|Range blocks]] á meta fyrir yfirlit yfir [[CIDR]] tölur, [[{{ns:Special}}:Ipblocklist|bannaða notendur og IP tölur]] fyrir lista yfir þá sem nú eru bannaðir og [[{{ns:4}}:Bönnunarskrá|bönnunarskrá]] fyrir lista sem inniheldur einnig þá sem hafa verið bannaðir í fortíðinni.",
+'blocklink' => "banna",
+'blocklistline' => "$1, $2 bannaði $3 ($4)",
+'infiniteblock' => 'rennur út infinite', //fixme
+'expiringblock' => 'rennur út $1',
+'blocklogpage' => "Bönnunarskrá",
+'blocklogtext' => "This is a log of user blocking and unblocking actions. Automatically
+blocked IP addresses are not be listed. See the [[Special:Ipblocklist|IP block list]] for
+the list of currently operational bans and blocks.",
+'bold_sample' => "Feitletraður texti",
+'bold_tip' => "Feitletraður texti",
+'booksources' => "Bókabúðir",
+'bydate' => "eftir dagsetningu",
+'byname' => "eftir nafni",
+'bysize' => "eftir stærð",
+'cachederror' => "Eftirfarandi er afrit af umbeðinni síðu og gæti því ekki verið nýjasta útgáfa hennar:",
+'cancel' => "Hætta við",
+'cantrollback' => "Ekki hægt að taka aftur breytingu, síðasti höfundur er eini höfundur þessarar síðu.",
+'categories' => "Flokkar",
+'category_header' => "Greinar í flokknum „$1“",
+'categoryarticlecount' => "Það eru $1 síður í þessum flokki.",
+'changepassword' => "Breyta lykilorði",
+'changes' => "Breytingar",
+'clearyourcache' => "'''Ath:''' Eftir að þú hefur vistað breytingar þarf að hreynsa flýtiskrár vafrarans til að sjá þær, í '''Mozilla / Firefox''' ''CTRL-Shift-R'', '''IE:''' ''CTRL-F5'', '''Safari:''' ''CMD-Shift-R'', '''Konqueror:''' ''F5''.",
+'columns' => "Dálkar",
+'compareselectedversions' => "Bera saman valdar útgáfur",
+'confirm' => "Staðfesta",
+'confirmdelete' => "Staðfesting á eyðingu",
+'confirmprotect' => "Verndunarstaðfesting",
+'confirmprotecttext' => "Ertu viss um að þú viljir vernda þessa síðu?",
+'confirmunprotect' => "Afverndunarstaðfesting",
+'confirmunprotecttext' => "Ertu viss um að þú viljir afvernda þessa síðu?",
+'contextchars' => "Stafir í samhengi á hverja línu",
+'contextlines' => "Línur á hverja niðurstöðu",
+'contribslink' => "framlög",
+'contribsub' => "Eftir $1",
+'contributions' => "Framlög notanda",
+'copyright' => "Efni síðunnar má nota undir $1.",
+'copyrightpage' => "Project:Höfundarréttur",
+'copyrightpagename' => "Höfundarréttarreglum {{SITENAME}}",
+'createaccount' => "Nýskrá",
+'createaccountmail' => "með netfangi",
+'cur' => "nú",
+'currentevents' => "Líðandi stund",
+'currentevents-url' => "Líðandi stund",
+'currentrev' => "Núverandi útgáfa",
+'currentrevisionlink' => "núverandi útgáfa",
+'databaseerror' => "Gagnagrunnsvilla",
+'dateformat' => "Tímasnið",
+'datedefault' => 'Sjálfgefið',
+'deadendpages' => "Botnlangar",
+'dec' => "des",
+'december' => "desember",
+'defaultns' => "Leita í þessum nafnrýmum:",
+'defemailsubject' => "Varðandi {{SITENAME}}",
+'delete' => "Eyða",
+'deletecomment' => "Ástæða",
+'deletedarticle' => "tortímdi „$1“",
+'deletedtext' => "„$1“ hefur verið eytt. Sjá lista yfir nýlegar eyðingar í $2.",
+'deleteimg' => "eyða",
+'deleteimgcompletely' => "Eyða öllum útgáfum",
+'deletesub' => "(Eyði: „$1“)",
+'deletethispage' => "Eyða þessari síðu",
+'deletionlog' => "eyðingaskrá",
+'dellogpage' => "Eyðingaskrá",
+'diff' => "breyting",
+'difference' => "(Munur milli útgáfa)",
+'disambiguations' => "Aðgreiningarsíður",
+'disambiguationstext' => "The following pages link to a <i>disambiguation page</i>. They should link to the appropriate topic instead.<br />A page is treated as dismbiguation if it is linked from $1.<br />Links from other namespaces are <i>not</i> listed here.",
+'disclaimerpage' => "Project:Almennur fyrirvari",
+'disclaimers' => "Fyrirvarar",
+'edit' => "Breyta",
+'edithelp' => "Breytingarhjálp",
+'edithelppage' => "Hjálp:Breyta",
+'editing' => "Breyti $1",
+'editinguser' => "Breyti $1",
+'editingcomment' => "Breyti $1 (bæti við athugasemd)",
+'editingold' => "<strong>ATH: Þú ert að breyta gamalli útgáfu þessarar síðu og munu allar breytingar sem gerðar hafa verið á henni frá þeirri útgáfu vera fjarlægðar ef þú vistar.</strong>",
+'editingsection' => "Breyti $1 (hluta)",
+'editsection' => "breyta",
+'editold' => "breyta",
+'editthispage' => "Breyta þessari síðu",
+'emailfrom' => "Frá",
+'emailmessage' => "Skilaboð",
+'emailpage' => "Senda tölvupóst",
+'emailpagetext' => "Hafi notandi þessi fyllt út gild tölvupóstfang í stillingum sínum er hægt að senda skilaboð til hans eða hennar hér. Póstfangið sem þú fylltir út í stillingum þínum mun byrtast í „From:“ hlutanum svo viðtakandinn geti svarað.",
+'emailsend' => "Senda",
+'emailsent' => "Sending tókst",
+'emailsenttext' => "Skilaboðin þín hafa verið send.",
+'emailsubject' => "Fyrirsögn",
+'emailto' => "Til",
+'emailuser' => "Senda þessum notanda tölvupóst",
+/* 'enterlockreason' => "Enter a reason for the lock, including an estimate
+of when the lock will be released", */
+'error' => "Villa",
+'errorpagetitle' => "Villa",
+'excontent' => "innihaldið var: '$1'",
+'explainconflict' => "Síðunni hefur verið breytt síðan þú byrjaðir að gera breytingar á henni, textinn í efri reitnum inniheldur núverandi útgáfu úr gagnagrunni og sá neðri inniheldur þína útgáfu, þú þarft hér að færa breytingar sem þú vilt halda úr neðri reitnum í þann efri og vista síðuna. <strong>Aðeins</strong> texti úr efri reitnum mun vera vistaður þegar þú vistar.",
+'export' => "XML útgáfa síðu",
+'exportcuronly' => "Aðeins núverandi útgáfu án breytingarskrá",
+'extlink_sample' => "http://www.example.com titill tengils",
+'extlink_tip' => "Ytri tengill (muna að setja http:// á undan)",
+'feb' => "feb",
+'february' => "febrúar",
+'feedlinks' => "Nippan:",
+'filedesc' => "Lýsing",
+'fileexists' => "Skrá með þessu nafni er þegar til, skoðaðu $1 ef þú ert óviss um hvort þú viljir breyta henni, ekki verður skrifað yfir gömlu skránna hlaðiru inn nýrri með sama nafni heldur verður núverandi útgáfa geymd í útgáfusögu.",
+'filename' => "Skráarnafn",
+'fileuploaded' => "Skránni „$1“ hefur verið bætt við á {{SITENAME}}.
+Fylgdu þessum tengli: $2 á lýsingarsíðu skráarinnar og fylltu út
+upplýsingar um skránna, svosem um uppruna hennar, höfund og aðrar
+upplýsingar um hana.",
+'friday' => "föstudagur",
+'go' => "Áfram",
+'searcharticle' => "Áfram",
+'guesstimezone' => "Fylla inn",
+'headline_sample' => "Fyrirsagnartexti",
+'headline_tip' => "Annars stigs fyrirsögn",
+'help' => "Hjálp",
+'helppage' => "Hjálp:Efnisyfirlit",
+'hide' => "Fela",
+'hidetoc' => "fela",
+'hist' => "breytingaskrá",
+'histlegend' => "Skýringar: (nú) = bera saman við núverandi útgáfu,
+(breyting) = bera saman við útgáfun á undan, M = minniháttar breyting.",
+'history' => "breytingaskrá",
+'history_short' => "Breytingaskrá",
+'historywarning' => "Athugið: Síðan sem þú ert um það bil að eyða á sér&nbsp;",
+'hr_tip' => "Lárétt lína (notist sparlega)",
+'ilsubmit' => "Leita",
+'image_sample' => "Sýnishorn.jpeg",
+'image_tip' => "Setja inn mynd",
+'imagelinks' => "Myndatenglar",
+'imagelist' => "Skráalisti",
+'imagelisttext' => "Hér fyrir neðan er $1 skrám raðað $2.",
+'imgdelete' => "eyða",
+'imgdesc' => "lýsing",
+'imghistlegend' => "Skýringar: (nú) = bera saman við núverandi útgáfu,
+(breyting) = bera saman við útgáfun á undan, M = minniháttar breyting.
+
+Legend: (nú) = núverandi útgáfa,
+(eyða) = eyða þessari útgáfu, (nota) = nota þessa útgáfu í stað núverandi útgáfu.
+<br /><em>Fylgdu dagsetningartenglunum til að sjá mynd sem hlaðið var inn á þeim tíma</em>.",
+'imghistory' => "Breytingaskrá myndar",
+'imglegend' => "Skýringar: (lýsing) = sýna og/eða breyta lýsingu skráar.",
+'ipaddress' => "IP Tala/notendanafn",
+'ipbexpiry' => "Rennur út eftir",
+'ipblocklist' => "Bannaðar notendur og IP tölur",
+'ipbreason' => "Ástæða",
+'ipbsubmit' => "Banna notanda",
+'ipusubmit' => "Afbanna",
+'isredirect' => "tilvísun",
+'italic_sample' => "Skáletraður texti",
+'italic_tip' => "Skáletraður texti",
+'jan' => "jan",
+'january' => "janúar",
+'jul' => "júl",
+'july' => "júlí",
+'jun' => "jún",
+'june' => "júní",
+'last' => "breyting",
+'lastmodifiedat' => "Þessari síðu var síðast breytt $2, $1.",
+'lineno' => "Lína $1:",
+'link_sample' => "Titill tengils",
+'link_tip' => "Innri tengill",
+'linklistsub' => "(Listi yfir ítengdar síður)",
+'linkshere' => "Eftirfarandi síður tengjast hingað:",
+'linkstoimage' => "Eftirfarandi síður tengjast í mynd þessa:",
+'listingcontinuesabbrev' => " frh.",
+'listusers' => "Notendalisti",
+'localtime' => "Staðartími",
+'lockdb' => "Læsa gagnagrunninum",
+'login' => "Innskrá",
+'loginerror' => "Innskráningarvilla",
+'loginsuccess' => "Þú ert nú innskráð(ur) á {{SITENAME}} sem „$1“.",
+'loginsuccesstitle' => "Innskráning tókst",
+'logout' => "Útskráning",
+'logouttext' => "Þú hefur verið skráð(ur) út.
+Þú getur þó haldið áfram að nota {{SITENAME}} nafnlaust og þú getur skráð þig inn sem annar notandi. Athugaðu að sumar síður kunna að birtast líkt og þú sért ennþá innskráður, hægt er að koma í veg fyrir það með því að hreinsa biðminnið í vafranum.",
+'lonelypages' => "Munaðarlausar síður",
+'longpages' => "Langar síður",
+'mailmypassword' => "Senda nýtt lykilorð með tölvupósti",
+'mainpage' => "Forsíða",
+'makesysop' => "Veita stjórnandaréttindi",
+'makesysopname' => "Notandi:",
+'makesysopok' => "<strong>Notandanum „$1“ hefur verið veitt stjórnandastaða</strong>",
+'makesysopsubmit' => "Gera að stjórnanda",
+'makesysoptext' => "Kerfissíða þessi er notuð af möppudýrum til að veita venjulegum notendum stjórnendaréttindi.",
+'mar' => "mar",
+'march' => "mars",
+'math' => "Birting stærðfræðiformúlna",
+'math_sample' => "Formúlan setjist hér",
+'math_tip' => "LaTeX Stærðfræðiformúla",
+'may' => "maí",
+'may_long' => "maí",
+'media_sample' => "Sýnishorn.ogg",
+'media_tip' => "Tengill í margmiðlunarskrá",
+'minoredit' => "Minniháttar breyting",
+'missingimage' => "<b>Mynd vantar</b><br /><i>$1</i>",
+'monday' => "mánudagur",
+'move' => "Færa",
+'movearticle' => "Færa",
+'movenologin' => "Óinnskráð(ur)",
+'movenologintext' => "Þú verður að vera [[Kerfissíða:Userlogin|innskráð(ur)]] til að geta fært síður.",
+'movepage' => "Færa síðu",
+'movepagebtn' => "Færa síðuna",
+'movepagetalktext' => "Spallsíða síðunnar verður sjálfkrafa færð með ef hún er til nema:
+* Þú sért að færa síðuna á milli nafnrýma
+* Spallsíða sé þegar til undir nýja nafninu
+* Þú veljir að færa hana ekki
+Í þeim tilfellum verður að færa hana handvirkt.",
+'movepagetext' => "Hér er hægt að endurnefna síðu, hún mun ásamt breytingarskrá hennar
+verða færð á nýja nafnið og núverandi staðsetning mun
+breytast í tilvísun sem vísa mun á nýju staðsetninguna,
+tenglar í núverandi nafn munu hinsvegar ekki breytast,
+athugaðu að þetta búi ekki til margfaldar
+tilvísanir, það er á þína ábyrgð að tryggja það að tenglar haldi áfram
+að vísa á rétta síðu.
+
+Athugaðu að síðan mun '''ekki''' verða færð ef það er þegar síða á nafninu
+sem þú hyggst færa hana á, nema síða sú sé tóm eða tilvísun sem á sér enga
+breytingarsögu. Þú getur þar með fært síðuna aftur til baka án þess að
+missa breytingarsöguna, en ekki fært hana venjulega síðu.
+
+'''Varúð:'''
+Vertu viss um að skilja afleiðingarnar af þessari aðgerð vel. Þetta gæti þýtt
+mjög rótækar breytingar á vinsælum síðum og valdið titringi hjá öðrum notendum.",
+'movetalk' => "Færa „Spjall“ síðuna líka ef við á.",
+'movethispage' => "Færa þessa síðu",
+'mw_math_html' => "HTML ef hægt er, annars PNG",
+'mw_math_mathml' => "MathML",
+'mw_math_modern' => "Mælt með fyrir nýja vafra",
+'mw_math_png' => "Alltaf birta PNG mynd",
+'mw_math_simple' => "HTML fyrir einfaldar jöfnur annars PNG",
+'mw_math_source' => "Sýna TeX jöfnu (fyrir textavafra)",
+'mycontris' => "Framlög",
+'mypage' => "Mín síða",
+'mytalk' => "Spjall",
+'navigation' => "Flakk",
+'newarticle' => "(Ný)",
+'newimages' => "Gallerí nýlegra skráa",
+'newmessageslink' => "ný skilaboð",
+'newpages' => "Nýjar síður",
+'newpassword' => "Nýja lykilorðið",
+'newtitle' => "Yfir á",
+'newwindow' => "(í nýjum glugga)",
+'nextdiff' => "Næsta breyting →",
+'nextn' => "næstu $1",
+'nextrevision' => "Næsta útgáfa→",
+'noarticletext' => "'''Það er ekki enn grein undir þessu nafni á {{SITENAME}}.'''
+* '''[{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} Skrifa grein undir nafninu „{{PAGENAME}}“]'''
+* [[{{ns:special}}:Search/{{PAGENAME}}|Leita að „{{PAGENAME}}“]] í öðrum greinum og síðum.",
+'noemailtext' => "Notandi þessi hefur kosið að fá ekki tölvupóst frá öðrum notendum eða hefur ekki fyllt út netfang sitt í stillingum.",
+'noemailtitle' => "Ekkert póstfang",
+'nolinkshere' => "Engar síður tengjast hingað.",
+'nolinkstoimage' => "Engar síður tengja í hingað.",
+'noname' => "Ógilt notendanafn.",
+'nosuchuser' => "Enginn notandi er til undir nafninu „$1“.",
+'note' => "<strong>Athugið:</strong>",
+'notextmatches' => "Leitarorð fannst/fundust ekki í innihaldi greina",
+'notitlematches' => "Engir greinatitlar pössuðu við fyrirspurnina",
+'nov' => "nóv",
+'november' => "nóvember",
+'nowatchlist' => "Vaktlistinn er tómur.",
+'nowiki_sample' => "Innsetjið ósniðinn texta hér",
+'nowiki_tip' => "Hunsa wikisnið",
+'nstab-category' => "Efnisflokkur",
+'nstab-help' => "Hjálp",
+'nstab-image' => "Mynd",
+'nstab-main' => "Grein",
+'nstab-mediawiki' => "Skilaboð",
+'nstab-template' => "Forsnið",
+'nstab-user' => "Notandasíða",
+'nstab-project' => "Um",
+'oct' => "okt",
+'october' => "október",
+'oldpassword' => "Gamla lykilorðið",
+'otherlanguages' => "Á öðrum tungumálum",
+'pagecategories' => "Flokkar",
+'pagemovedsub' => "Færsla tókst",
+'pagemovedtext' => "Síðan „[[$1]]“ var færð yfir á „[[$2]]“.",
+'pagetitle' => "$1 - {{SITENAME}}",
+'perfcached' => "Eftirfarandi er afrit af umbeðinni síðu og gæti því ekki verið nýjasta útgáfa hennar:",
+'perfdisabled' => "Þessi síða hefur verið gerð óvirk þar sem notkun hennar veldur of miklu álagi á gagnagrunninum.",
+'personaltools' => "Tenglar",
+'portal' => "Samfélagsgátt",
+'portal-url' => "Project:Samfélagsgátt",
+'powersearch' => "Leita",
+'powersearchtext' => "Leita í eftirfarandi nafnrýmum :<br />
+$1<br />
+$2 Sýna tilvísarnir &nbsp; Leita að $3 $9",
+'preferences' => "Stillingar",
+'prefs-misc' => "Aðrar stillingar",
+'prefs-personal' => "Notendaupplýsingar",
+'prefs-rc' => "Nýlegar breytingar og stubbar",
+'prefsnologintext' => "You must be [[Special:Userlogin|logged in]]
+to set user preferences.",
+'preview' => "Forskoða",
+'previewnote' => " Það sem sést hér er aðeins forskoðun og hefur ekki enn verið vistað.",
+'previousdiff' => "← Fyrri breyting",
+'previousrevision' => "←Fyrri útgáfa",
+'prevn' => "síðustu $1",
+'printableversion' => "Prentvæn útgáfa",
+'protect' => "Vernda",
+'protectcomment' => "Ástæða",
+'protectedpagewarning' => "<!-- -->",
+'protectlogpage' => "Verndunarskrá",
+'protectsub' => "(Vernda „$1“)",
+'qbedit' => "Breyta",
+'qbsettings' => "Valblað",
+'randompage' => "Handahófsvalin síða",
+'rclinks' => "Sýna síðustu $1 breytingar síðustu $2 daga<br />$3",
+'rclistfrom' => "Sýna breytingar frá og með $1",
+'rclsub' => "(á síðum sem tengd er í frá „$1“)",
+'rcnote' => "Að neðan eru síðustu <strong>$1</strong> breytingar síðustu <strong>$2</strong> daga.",
+'recentchanges' => "Nýlegar breytingar",
+'recentchangescount' => "Fjöldi síðna á „nýlegum breytingum“",
+'recentchangeslinked' => "Skyldar breytingar",
+'redirectedfrom' => "(Tilvísun frá $1)",
+'remembermypassword' => "Muna.",
+'removechecked' => "Fjarlægja merktar síður af vaktlistanum",
+'removedwatch' => "Fjarlægt af vaktlistanum",
+'removedwatchtext' => "Síðan \"$1\" hefur verið fjarlægð af vaktlistanum.",
+'removingchecked' => "Fjarlægi umbeðnar síðu(r) af vaktlistanum...",
+'resetprefs' => "Endurstilla valmöguleika",
+'restorelink' => "$1 eydda(r) breyting(u/ar)",
+'resultsperpage' => "Niðurstöður á síðu",
+'retrievedfrom' => "Af „$1“",
+'returnto' => "Tilbaka: $1.",
+'retypenew' => "Endurtaktu nýja lykilorðið",
+'reupload' => "Endurinnhlaða",
+'reuploaddesc' => "Aftur á innhlaðningarformið.",
+'reverted' => "Breytt aftur til fyrri útgáfu",
+'revertimg' => "nota",
+'revertpage' => "Tók aftur breytingar $2, breytt til síðustu útgáfu $1",
+'revhistory' => "Útgáfusaga",
+'revisionasof' => "Útgáfa síðunnar kl. $1",
+'rollback' => "Taka aftur breytingar",
+'rollback_short' => "Afturtaka",
+'rollbackfailed' => "Afturtaka mistókst",
+'rollbacklink' => "afturtaka",
+'rows' => "Raðir",
+'saturday' => "laugardagur",
+'savearticle' => "Vista",
+'savedprefs' => "Stillingarnar þínar hafa verið vistaðar.",
+'savefile' => "Vista",
+'saveprefs' => "Vista stillingar",
+'search' => "Leit",
+'searchbutton' => "Leit",
+'searchsubtitle' => "Fyrir fyrirspurnina „[[:$1]]“",
+'searchsubtitleinvalid' => "Fyrir fyrirspurnina „$1“",
+'searchresults' => "Leitarniðurstöður",
+'searchresultshead' => "Leit",
+'searchresulttext' => "Fyrir frekari upplýsingar um leit á {{SITENAME}}, sjá $1.",
+'sep' => "sep",
+'september' => "september",
+'servertime' => "Tími netþjóns",
+'setbureaucratflag' => "Einnig möppudýr",
+'shortpages' => "Stuttar síður",
+'show' => "Sýna",
+'showingresults' => "Sýni <strong>$1</strong> niðurstöður frá og með #<strong>$2</strong>.",
+'showingresultsnum' => "Sýni <strong>$1</strong> niðurstöður frá og með #<strong>$2</strong>.",
+'showlast' => "Sýna síðustu $1 skrár raðaðar $2.",
+'showpreview' => "Forskoða",
+'showtoc' => "sýna",
+'sig_tip' => "Undirskrift þín auk tímasetningu",
+'sitestats' => "Almenn tölfræði",
+'sitestatstext' => "Nú eru alls '''$1''' síður í gagnagrunninum,
+þar á meðal „spjall“ síður, síður er snúa að {{SITENAME}} verkefninu,
+„stubbar“, tilvísanir og annað efni er ekki telst til greina.
+Þar fyrir utan eru '''$2''' síður sem líklega teljast fullgildar greinar.
+
+'''$3''' síður hafa verið skoðaðar og '''$4''' breytingar hafa verið gerðar
+síðan vefurinn var settur up. Það reiknast sem '''$5''' breytingar
+á hverja síðu að meðaltali, og '''$6''' fléttingar fyrir hverja breytingu.",
+'sitesupport' => "Framlög",
+'skin' => "Þema",
+'specialpage' => "Kerfissíða",
+'specialpages' => "Kerfissíður",
+'spheading' => "Almennar",
+'statistics' => "Tölfræði",
+'storedversion' => "Geymd útgáfa",
+'stubthreshold' => "Stubbamerkja allt undir",
+'subcategories' => "Undirflokkar",
+'subcategorycount' => "Það eru $1 undirflokkar í þessum flokki.",
+'subject' => "Fyrirsögn",
+'successfulupload' => "Innhlaðning tókst",
+'summary' => "Breytingar",
+'sunday' => "sunnudagur",
+'talk' => "Spjall",
+'talkpage' => "Ræða um þessa síðu",
+'talkpagenotmoved' => "Samsvarandi spjallsíða var <strong>ekki</strong> færð.",
+'templatesused' => "Snið notuð á síðunni:",
+'textboxsize' => "Breytingarflipinn",
+'textmatches' => "Leitarorð fannst/fundust í innihaldi eftirfarandi greina",
+'thisisdeleted' => "Endurvekja eða skoða $1?",
+'thursday' => "fimmtudagur",
+'timezonelegend' => "Tímabelti",
+'timezoneoffset' => "Hliðrun",
+'timezonetext' => "Hliðrun staðartíma frá UTC+0.",
+'titlematches' => "Titlar greina sem pössuðu við fyrirspurnina",
+'toc' => "Efnisyfirlit",
+'tog-editondblclick' => "Breyta síðu ef tvísmellt er á hlekkinn (JavaScript)",
+'tog-editsection' => "Leyfa breytingar á hluta síðna með [edit] hlekkjum",
+'tog-editsectiononrightclick' => "Leyfa breytingar á hluta síðna með því að hægrismella á titla (JavaScript)",
+'tog-editwidth' => "Innsláttarsvæði hefur fulla breidd",
+'tog-hideminor' => "Fela minniháttar breytingar",
+'tog-highlightbroken' => "Sýna brotna hlekki <a href=\"\" class=\"new\">svona</a> (annars: svona<a href=\"\" class=\"internal\">?</a>).",
+'tog-justify' => "Jafna málsgreinar",
+'tog-minordefault' => "Láta breytingar vera sjálfgefnar sem minniháttar",
+'tog-nocache' => "Slökkva á flýtivistun síðna",
+'tog-numberheadings' => "Númera fyrirsagnir sjálfkrafa",
+'tog-previewontop' => "Setja prufuhnapp fyrir framan breytingahnapp",
+'tog-rememberpassword' => "Muna lykilorð",
+'tog-showtoc' => "Sýna efnisyfirlit",
+'tog-underline' => "Undirstrika hlekki",
+'tog-usenewrc' => "Endurbætt nýjar tengingar (ekki fyrir alla vafra)",
+'tog-watchdefault' => "Bæta síðum sem þú breytir við eftirlitslista",
+'toolbox' => "Verkfæri",
+'tooltip-compareselectedversions' => "Sjá breytingarnar á þessari grein á milli útgáfanna sem þú valdir. [alt-v]",
+'tooltip-minoredit' => "Merktu þessa breytingu sem minniháttar [alt-i]",
+'tooltip-preview' => "Forskoða breytingarnar, vinsamlegast gerðu þetta áður en þú vistar! [alt-p]",
+'tooltip-save' => "Vista breytingarnar [alt-s]",
+'tooltip-search' => "Leit á þessari Wiki [alt-f]",
+'tuesday' => "þriðjudagur",
+'unblockip' => "Afbanna notanda",
+'unblockiptext' => "Endurvekja skrifréttindi bannaðra notenda eða IP talna.",
+'unblocklink' => "afbanna",
+'uncategorizedcategories' => "Óflokkaðir flokkar",
+'uncategorizedpages' => "Óflokkaðar síður",
+'undelete' => "Endurvekja eydda síðu",
+'undelete_short' => "Endurvekja $1 breyting(u/ar)",
+'undeletearticle' => "Endurvekja eydda síðu",
+'undeletebtn' => "Endurvekja!",
+'undeletepage' => "Skoða og endurvekja síður",
+'undeletepagetext' => "Eftirfarandi síðum hefur verið eitt en eru þó enn í gagnagrunninum og geta verið endurvaknar. Athugið að síður þessar eru reglulega fjarlægðar endanlega úr gagnagrunninum.",
+'undeleterevisions' => "$1 breyting(ar)",
+'unlockdb' => "Aflæsa gagnagrunninum",
+'unprotect' => "Afvernda",
+'unprotectcomment' => "Ástæða",
+'unprotectsub' => "(Afvernda „$1“)",
+'unusedimages' => "Munaðarlausar skrár",
+'unusedimagestext' => "<p>Please note that other web sites may link to an image with
+a direct URL, and so may still be listed here despite being
+in active use.",
+'unwatch' => "Afvakta",
+'upload' => "Innhlaða",
+'uploadbtn' => "Hlaða inn skrá",
+'uploadedimage' => "hlóð inn \"$1\"",
+'uploaderror' => "Villa í innhlaðningu",
+'uploadlog' => "innhlaðningarskrá",
+'uploadlogpage' => "Innhlaðningarskrá",
+'uploadnologin' => "Óinnskráð(ur)",
+'uploadnologintext' => "You must be [[Special:Userlogin|logged in]]
+to upload files.",
+/*'uploadtext' => "'''Áður en skrá er hlaðið inn''':
+* Notaðu [[JPEG]] skráarsniðið fyrir ljósmyndir, [[GIF]] fyrir hreyfimyndir, [[PNG]] fyrir aðrar myndir og [[Ogg Vorbis]] fyrir hljóðskrár.
+
+'''Eftir að skrá er hlaðið inn''':
+* Veittu nákvæmar upplýsingar um skránna á skráarsíðunni, t.d. um myndina (hvenær hún er tekin, hvar o.s.f.)
+* Gefðu upplýsingar um leyfið sem hún er undir, <code><nowiki>{{</nowiki>GFDL<nowiki>}}</nowiki></code> fyrir [[commons:Commons:Copyright tags#GNU Licenses|GNU FDL]] og <code><nowiki>{{</nowiki>Óhöfundaréttvarið<nowiki>}}</nowiki></code> ef hún er óvernduð af alþjóða höfundarlögum.",*/
+'uploadwarning' => "Aðvörun",
+'usercssjsyoucanpreview' => "<strong>Ath:</strong> Hægt er að nota „Forskoða“ hnappinn til að prófa CSS og JavaScript kóða áður en hann er vistaður.",
+'userlogin' => "Innskrá",
+'userlogout' => "Útskrá",
+'userstats' => "Notendatölfræði",
+'userstatstext' => "Það eru '''$1''' skráðir notendur, þar af eru '''$2''' eða '''$4%''' stjórnendur (sjá $3).",
+'version' => "Útgáfa",
+'viewprevnext' => "Skoða ($1) ($2) ($3).",
+'viewsource' => "Skoða wikikóða",
+'viewtalkpage' => "Skoða umræðu",
+'wantedpages' => "Eftirsóttar síður",
+'watch' => "Vakta",
+'watchdetails' => "Fyrir utan spjallsíður eru $1 síða/síður á vaktlistanum þínum. Hægt er að
+[$4 sýna heildarlistann og breyta honum].",
+'watcheditlist' => "Þetta er listi yfir þínar vöktuðu síður raðað í
+stafrófsröð. Merktu við þær síður sem þú vilt fjarlægja
+af vaktlistanum og ýttu á 'fjarlægja merktar' takkan
+neðst á skjánum.",
+'watchlist' => "Vaktlistinn",
+'watchlistcontains' => "Á vaktlistanum eru $1 síður.",
+'watchmethod-list' => "leita að breytingum í vöktuðum síðum",
+'watchmethod-recent' => "kanna hvort nýlegar breytingar innihalda vaktaðar síður",
+'watchnochange' => "Engri síðu á vaktlistanum þínum hefur verið breytt á tilgreindu tímabili.",
+'watchnologin' => "Óinnskráð(ur)",
+'watchnologintext' => "Þú verður að vera [[Special:Userlogin|innskáð(ur)]] til að geta breytt vaktlistanum.",
+'watchthis' => "Vakta",
+'watchthispage' => "Vakta þessa síðu",
+'wednesday' => "miðvikudagur",
+'welcomecreation' => "<h2>Velkomin(n), $1!</h2><p>Aðgangurinn þinn hefur verið búinn til.
+Ekki gleyma að breyta {{SITENAME}} stillingunum þínum.",
+'whatlinkshere' => "Hvað tengist hingað",
+'whitelistacctext' => "Til að geta búið til aðganga í þessu Wiki, verður þú að [[Special:Userlogin|innskrá]] og hafa viðkomandi réttindi.",
+'whitelistacctitle' => "Þér er óheimilt að skrá þig sem notanda.",
+'whitelistedittext' => "Þú verður að [[Special:Userlogin|skrá þig inn]] til að geta breytt síðum.",
+'whitelistedittitle' => "Þú verður að skrá þig inn til að geta breytt síðum.",
+'whitelistreadtext' => "Þú verður að [[Special:Userlogin|skrá þig inn]] til að lesa síður.",
+'whitelistreadtitle' => "Notandi verður að skrá sig inn til að geta lesið.",
+'projectpage' => "Sýna verkefnissíðu",
+'wlnote' => "Að neðan eru síðustu <b>$1</b> breytingar síðustu <b>$2</b> klukkutíma.",
+'wlsaved' => "Þetta er vistuð útgáfa af vaktlistanum þínum.",
+'wlshowlast' => "Sýna síðustu $1 klukkutíma, $2 daga, $3",
+'wrong_wfQuery_params' => "Incorrect parameters to wfQuery()<br />
+Function: $1<br />
+Query: $2",
+'wrongpassword' => "Uppgefið lykilorð er rangt. Vinsamlegast reyndu aftur.",
+'yourdiff' => "Mismunur",
+'youremail' => "Tölvupóstfangið þitt*",
+'yourlanguage' => "Viðmótstungumál",
+'yourname' => "Notendanafn",
+'yournick' => "Nafn (fyrir undirskriftir)",
+'yourpassword' => "Lykilorð",
+'yourpasswordagain' => "Lykilorð (aftur)",
+'yourrealname' => "Fullt nafn þitt*",
+'yourtext' => "Þinn texti",
+);
+
+?>
diff --git a/languages/messages/MessagesIt.php b/languages/messages/MessagesIt.php
new file mode 100644
index 000000000000..105f5516441f
--- /dev/null
+++ b/languages/messages/MessagesIt.php
@@ -0,0 +1,2035 @@
+<?php
+/** Italian (Italiano)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciale',
+ NS_MAIN => '',
+ NS_TALK => 'Discussione',
+ NS_USER => 'Utente',
+ NS_USER_TALK => 'Discussioni_utente',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discussioni_$1',
+ NS_IMAGE => 'Immagine',
+ NS_IMAGE_TALK => 'Discussioni_immagine',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discussioni_MediaWiki',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Discussioni_template',
+ NS_HELP => 'Aiuto',
+ NS_HELP_TALK => 'Discussioni_aiuto',
+ NS_CATEGORY => 'Categoria',
+ NS_CATEGORY_TALK => 'Discussioni_categoria'
+);
+
+$quickbarSettings = array(
+ 'Nessuno', 'Fisso a sinistra', 'Fisso a destra', 'Fluttuante a sinistra'
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'H:i, M j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'H:i, j M Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'H:i, Y M j',
+);
+
+$messages = array(
+
+# User preference toggles
+"tog-underline" => "Sottolinea i collegamenti",
+"tog-highlightbroken" => 'Formatta <a href="" class="new">così</a> i collegamenti a pagine inesistenti (se disattivato: così<a href="" class="internal">?</a>).',
+"tog-justify" => "Allineamento dei paragrafi giustificato",
+"tog-hideminor" => "Nascondi le modifiche minori nelle ultime modifiche",
+"tog-extendwatchlist" => "Espandi la funzione osservati speciali mostrando tutte le modifiche applicabili",
+"tog-usenewrc" => "Ultime modifiche avanzate (richiede JavaScript)",
+"tog-numberheadings" => "Numerazione automatica dei titoli di sezione",
+"tog-showtoolbar" => "Mostra barra degli strumenti di modifica (richiede JavaScript)",
+"tog-editondblclick" => "Modifica delle pagine tramite doppio clic (richiede JavaScript)",
+"tog-editsection" => "Modifica delle sezioni tramite il collegamento [modifica]",
+"tog-editsectiononrightclick" => "Modifica delle sezioni tramite clic destro sul titolo (richiede JavaScript)",
+"tog-showtoc" => "Mostra l'indice per le pagine con più di 3 sezioni",
+"tog-rememberpassword" => "Ricorda la password (richiede di accettare i cookie)",
+"tog-editwidth" => "Aumenta al massimo la larghezza della casella di modifica",
+"tog-watchcreations" => "Aggiungi le pagine create agli osservati speciali",
+"tog-watchdefault" => "Aggiungi le pagine modificate agli osservati speciali",
+"tog-watchmoves" => "Aggiungi le pagine spostate agli osservati speciali",
+"tog-watchdeletion" => "Aggiungi le pagine cancellate agli osservati speciali",
+"tog-minordefault" => "Indica per default tutte le modifiche come 'minori'",
+"tog-previewontop" => "Mostra l'anteprima sopra la casella di modifica",
+"tog-previewonfirst" => "Mostra l'anteprima per la prima modifica",
+"tog-nocache" => "Disattiva la ''cache'' per le pagine",
+"tog-enotifwatchlistpages" => "Segnalami via e-mail le modifiche alle pagine osservate",
+"tog-enotifusertalkpages" => "Segnalami via e-mail le modifiche alla mia pagina di discussione",
+"tog-enotifminoredits" => "Segnalami via e-mail anche le modifiche minori",
+"tog-enotifrevealaddr" => "Rivela il mio indirizzo e-mail nei messaggi di avviso",
+"tog-shownumberswatching" => "Mostra il numero di utenti che hanno la pagina in osservazione",
+"tog-fancysig" => "Non modificare il markup della firma (usare per firme non standard)",
+"tog-externaleditor" => "Usa per default un editor di testi esterno",
+"tog-externaldiff" => "Usa per default un programma di diff esterno",
+"tog-showjumplinks" => "Attiva i collegamenti accessibili 'vai a'",
+"tog-uselivepreview" => "Attiva la funzione ''Live preview'' (richiede JavaScript; sperimentale)",
+"tog-forceeditsummary" => "Chiedi conferma se l'oggetto della modifica è vuoto",
+"tog-watchlisthideown" => "Nascondi le mie modifiche negli osservati speciali",
+"tog-watchlisthidebots" => "Nascondi le modifiche dei bot negli osservati speciali",
+"tog-watchlisthideminor" => "Nascondi le modifiche minori negli osservati speciali",
+"tog-nolangconversion" => "Disattiva la conversione tra varianti linguistiche",
+"tog-ccmeonemails" => "Inviami una copia dei messaggi spediti agli altri utenti",
+
+"underline-always" => "Sempre",
+"underline-never" => "Mai",
+"underline-default" => "Mantieni le impostazioni del browser",
+
+"skinpreview" => "(anteprima)",
+
+# dates
+'sunday' => 'domenica',
+'monday' => 'lunedì',
+'tuesday' => 'martedì',
+'wednesday' => 'mercoledì',
+'thursday' => 'giovedì',
+'friday' => 'venerdì',
+'saturday' => 'sabato',
+'sun' => 'dom',
+'mon' => 'lun',
+'tue' => 'mar',
+'wed' => 'mer',
+'thu' => 'gio',
+'fri' => 'ven',
+'sat' => 'sab',
+'january' => 'gennaio',
+'february' => 'febbraio',
+'march' => 'marzo',
+'april' => 'aprile',
+'may_long' => 'maggio',
+'june' => 'giugno',
+'july' => 'luglio',
+'august' => 'agosto',
+'september' => 'settembre',
+'october' => 'ottobre',
+'november' => 'novembre',
+'december' => 'dicembre',
+'january-gen' => 'gennaio',
+'february-gen' => 'febbraio',
+'march-gen' => 'marzo',
+'april-gen' => 'aprile',
+'may-gen' => 'maggio',
+'june-gen' => 'giugno',
+'july-gen' => 'luglio',
+'august-gen' => 'agosto',
+'september-gen' => 'settembre',
+'october-gen' => 'ottobre',
+'november-gen' => 'novembre',
+'december-gen' => 'dicembre',
+'jan' => 'gen',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'mag',
+'jun' => 'giu',
+'jul' => 'lug',
+'aug' => 'ago',
+'sep' => 'set',
+'oct' => 'ott',
+'nov' => 'nov',
+'dec' => 'dic',
+
+# Bits of text used by many pages:
+#
+"categories" => "Categorie",
+"pagecategories" => "{{PLURAL:$1|Categoria|Categorie}}",
+"category_header" => 'Pagine nella categoria "$1"',
+"subcategories" => "Sottocategorie",
+"category-media-header" => "File nella categoria \"$1\"",
+
+"mainpage" => "Pagina principale",
+"mainpagetext" => "<big>'''Installazione di MediaWiki completata correttamente.'''</big>",
+"mainpagedocfooter" => "Consultare la [http://meta.wikimedia.org/wiki/Aiuto:Sommario Guida utente] per maggiori informazioni sull'uso di questo software wiki.
+
+== Per iniziare ==
+I seguenti collegamenti sono in lingua inglese:
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Impostazioni di configurazione]
+* [http://www.mediawiki.org/wiki/Help:FAQ Domande frequenti su MediaWiki]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Mailing list annunci MediaWiki]",
+
+"portal" => "Portale comunità",
+"portal-url" => "Project:Portale comunità",
+"about" => "Informazioni",
+"aboutsite" => "Informazioni su {{SITENAME}}",
+"aboutpage" => "Project:Informazioni",
+"article" => "Voce",
+"help" => "Aiuto",
+"helppage" => "Help:Indice",
+"bugreports" => "Malfunzionamenti",
+"bugreportspage" => "Project:Malfunzionamenti",
+"sitesupport" => "Donazioni",
+"sitesupport-url" => "Project:Donazioni",
+"faq" => "FAQ",
+"faqpage" => "Project:FAQ",
+"edithelp" => "Guida",
+"newwindow" => "(si apre in una nuova finestra)",
+"edithelppage" => "Project:Modifica",
+"cancel" => "Annulla",
+"qbfind" => "Trova",
+"qbbrowse" => "Sfoglia",
+"qbedit" => "Modifica",
+"qbpageoptions" => "Opzioni pagina",
+"qbpageinfo" => "Informazioni sulla pagina",
+"qbmyoptions" => "Le mie pagine",
+"qbspecialpages" => "Pagine speciali",
+"moredotdotdot" => "Altro...",
+"mypage" => "La mia pagina",
+"mytalk" => "Le mie discussioni",
+"anontalk" => "Discussioni per questo IP",
+"navigation" => "Navigazione",
+
+# Metadata in edit box
+"metadata_help" => "Metadati (consultare [[Project:Metadati]] per maggiori informazioni):",
+
+"currentevents" => "Attualità",
+"currentevents-url" => "Attualità",
+
+"disclaimers" => "Avvertenze",
+"disclaimerpage" => "Project:Avvertenze generali",
+"privacy" => "Informazioni sulla privacy",
+"privacypage" => "Project:Informazioni sulla privacy",
+"errorpagetitle" => "Errore",
+"returnto" => "Torna a $1.",
+"tagline" => "Da {{SITENAME}}.",
+"help" => "Aiuto",
+"search" => "Ricerca",
+"searchbutton" => "Ricerca",
+"go" => "Vai",
+'searcharticle' => "Vai",
+"history" => "Versioni precedenti",
+"history_short" => "Cronologia",
+"updatedmarker" => "modificata dalla mia ultima visita",
+"info_short" => "Informazioni",
+"printableversion" => "Versione stampabile",
+"permalink" => "Link permanente",
+"print" => "Stampa",
+"edit" => "Modifica",
+"editthispage" => "Modifica questa pagina",
+"delete" => "Cancella",
+"deletethispage" => "Cancella questa pagina",
+"undelete_short" => "Recupera {{PLURAL:$1|una revisione|$1 revisioni}}",
+"protect" => "Blocca",
+"protectthispage" => "Blocca questa pagina",
+"unprotect" => "Sblocca",
+"unprotectthispage" => "Sblocca questa pagina",
+"newpage" => "Nuova pagina",
+"talkpage" => "Pagina di discussione",
+"specialpage" => "Pagina speciale",
+"personaltools" => "Strumenti personali",
+"postcomment" => "Aggiungi un commento",
+"articlepage" => "Vedi la voce",
+"talk" => "Discussione",
+"views" => "Visite",
+"toolbox" => "Strumenti",
+"userpage" => "Visualizza la pagina utente",
+"projectpage" => "Visualizza la pagina di servizio",
+"imagepage" => "Visualizza la pagina di descrizione dell'immagine",
+"mediawikipage" => "Visualizza il messaggio",
+"templatepage" => "Visualizza il template",
+"viewhelppage" => "Visualizza la pagina di aiuto",
+"categorypage" => "Visualizza la categoria",
+"viewtalkpage" => "Visualizza la pagina di discussione",
+"otherlanguages" => "Altre lingue",
+"redirectedfrom" => "(Redirect da $1)",
+"autoredircomment" => "Redirect alla pagina [[$1]]",
+"redirectpagesub" => "Pagina di redirect",
+"lastmodifiedat" => "Ultima modifica per la pagina: $2, $1.",
+"viewcount" => "Questa pagina è stata letta {{PLURAL:$1|una volta|$1 volte}}.",
+"copyright" => "Contenuti soggetti a licenza d'uso $1.",
+"protectedpage" => "Pagina bloccata",
+"jumpto" => "Vai a:",
+"jumptonavigation" => "navigazione",
+"jumptosearch" => "ricerca",
+
+"badaccess" => "Permessi non sufficienti",
+"badaccess-group0" => "Non si dispone dei permessi necessari per eseguire l'azione richiesta.",
+"badaccess-group1" => "La funzione richiesta è riservata agli utenti che appartengono al gruppo $1.",
+"badaccess-group2" => "La funzione richiesta è riservata agli utenti che appartengono ai gruppi $1.",
+"badaccess-groups" => "La funzione richiesta è riservata agli utenti che appartengono a uno dei seguenti gruppi: $1.",
+
+"versionrequired" => "Versione $1 di MediaWiki richiesta",
+"versionrequiredtext" => "Per usare questa pagina è necessario disporre della versione $1 del software MediaWiki. Vedi [[Special:Version]]",
+
+"ok" => "OK",
+"pagetitle" => "$1 - {{SITENAME}}",
+"retrievedfrom" => "Estratto da \"$1\"",
+"youhavenewmessages" => "Hai $1 ($2).",
+"newmessageslink" => "nuovi messaggi",
+"newmessagesdifflink" => "differenza con la revisione precedente",
+"editsection" => "modifica",
+"editold" => "modifica",
+"editsectionhint" => "Modifica la sezione $1",
+"toc" => "Indice",
+"showtoc" => "mostra",
+"hidetoc" => "nascondi",
+"thisisdeleted" => "Vedi o ripristina $1?",
+"viewdeleted" => "Vedi $1?",
+"restorelink" => "{{PLURAL:$1|una modifica cancellata|$1 modifiche cancellate}}",
+"feedlinks" => "Feed:",
+"feed-invalid" => "Modalità di sottoscrizione del feed non valida.",
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Voce',
+'nstab-user' => 'Utente',
+'nstab-media' => 'File multimediale',
+'nstab-special' => 'Speciale',
+'nstab-project' => 'Pagina di servizio',
+'nstab-image' => 'Immagine',
+'nstab-mediawiki' => 'Messaggio',
+'nstab-template' => 'Template',
+'nstab-help' => 'Aiuto',
+'nstab-category' => 'Categoria',
+
+# Main script and global functions
+#
+"nosuchaction" => "Operazione non riconosciuta",
+"nosuchactiontext" => "La URL immessa non corrisponde a un comando riconosciuto dal software MediaWiki",
+"nosuchspecialpage" => "Pagina speciale non disponibile",
+"nospecialpagetext" => "La pagina speciale richiesta non è stata riconosciuta dal software MediaWiki; un elenco delle pagine speciali valide si trova alla pagina [[Special:Specialpages]].",
+
+# General errors
+#
+"error" => "Errore",
+"databaseerror" => "Errore del database",
+"dberrortext" => 'Errore di sintassi nella richiesta inoltrata al database.
+Ciò potrebbe indicare la presenza di un bug nel software.
+L\'ultima query inviata al database è stata:
+<blockquote><tt>$1</tt></blockquote>
+richiamata dalla funzione "<tt>$2</tt>".
+MySQL ha restituito il seguente errore "<tt>$3: $4</tt>".',
+"dberrortextcl" => 'Errore di sintassi nella richiesta inoltrata al database.
+L\'ultima query inviata al database è stata:
+"$1"
+richiamata dalla funzione "$2".
+MySQL ha restituito il seguente errore "$3: $4".',
+"noconnect" => "Connessione al database non riuscita a causa di un problema tecnico del sito.<br />$1",
+"nodb" => "Selezione del database $1 non riuscita",
+"cachederror" => "Quella presentata di seguito è una copia ''cache'' della pagina richiesta; potrebbe quindi non essere aggiornata.",
+"laggedslavemode" => "Attenzione: La pagina potrebbe non riportare gli aggiornamenti più recenti.",
+"readonly" => "Database bloccato",
+"enterlockreason" => "Indica il motivo del blocco, specificando il momento in cui è presumibile che venga rimosso.",
+"readonlytext" => "In questo momento il database è bloccato e non sono possibili aggiunte o modifiche alle pagine. Il blocco è di solito legato a operazioni di manutenzione ordinaria, al termine delle quali il database è di nuovo accessibile.
+
+L'amministratore di sistema che ha imposto il blocco ha fornito questa spiegazione: $1",
+"missingarticle" => "Il database non ha trovato il testo della pagina dal titolo \"$1\", che avrebbe dovuto essere presente.
+
+Di solito ciò si verifica quando viene seguito, a partire dalla cronologia o dal confronto tra versioni, un collegamento a una pagina cancellata.
+
+In caso contrario, si è probabilmente scoperto un errore del software MediaWiki.
+Si prega di segnalare l'accaduto a un amministratore specificando la URL in questione.",
+"readonly_lag" => "Il database è stato bloccato automaticamente per consentire ai server con i database slave di sincronizzarsi con il master",
+"internalerror" => "Errore interno",
+"filecopyerror" => 'Impossibile copiare il file "$1" in "$2".',
+"filerenameerror" => 'Impossibile rinominare il file "$1" in "$2".',
+"filedeleteerror" => 'Impossibile cancellare il file "$1".',
+"filenotfound" => 'File "$1" non trovato.',
+"unexpected" => 'Valore imprevisto: "$1"="$2".',
+"formerror" => "Errore: impossibile inviare il modulo",
+"badarticleerror" => "Operazione non consentita per questa pagina.",
+"cannotdelete" => "Impossibile cancellare la pagina o il file richiesto. (Potrebbe essere stato già cancellato.)",
+"badtitle" => "Titolo non corretto",
+"badtitletext" => "Il titolo della pagina richiesta è vuoto, errato o con caratteri non ammessi oppure deriva da un errore nei collegamenti tra siti wiki diversi o versioni in lingue diverse dello stesso sito.",
+"perfdisabled" => "Siamo spiacenti, questa funzionalità è temporaneamente disabilitata perché il suo uso rallenta il database fino a rendere il sito inutilizzabile per tutti gli utenti.",
+"perfdisabledsub" => "I dati presentati di seguito risalgono al $1:", # obsolete?
+"perfcached" => "I dati che seguono sono estratti da una copia ''cache'' del database, non aggiornati in tempo reale.",
+"perfcachedts" => "I dati che seguono sono estratti da una copia ''cache'' del database. Ultimo aggiornamento: $1.",
+"querypage-no-updates" => "Gli aggiornamenti della pagina sono temporaneamente sospesi. I dati in essa contenuti non verranno aggiornati.",
+"wrong_wfQuery_params" => "Errore nei parametri inviati alla funzione wfQuery()<br />
+Funzione: $1<br />
+Query: $2",
+"viewsource" => "Vedi sorgente",
+"viewsourcefor" => "di $1",
+"protectedpagetext" => "Questa pagina è stata protetta per impedirne la modifica.",
+"viewsourcetext" => "È possibile visualizzare e copiare il codice sorgente di questa pagina:",
+"protectedinterface" => "Questa pagina contiene un elemento che fa parte dell'interfaccia utente del software; è quindi protetta per evitare possibili abusi.",
+"editinginterface" => "'''Attenzione:''' Il testo di questa pagina fa parte dell'interfaccia utente del sito. Tutte le modifiche apportate a questa pagina si riflettono sui messaggi visualizzati per tutti gli utenti.",
+"sqlhidden" => "(la query SQL è stata nascosta)",
+
+# Login and logout pages
+#
+"logouttitle" => "Logout utente",
+"logouttext" => "<strong>Logout effettuato.</strong><br />
+Si può continuare ad usare {{SITENAME}} come utente anonimo oppure eseguire un nuovo accesso, con lo stesso nome utente o un nome diverso.
+
+Alcune pagine potrebbero continuare ad apparire come se il logout non fosse avvenuto finché non viene pulita la cache del proprio browser.",
+
+"welcomecreation" => "== Benvenuto, $1! ==
+
+L'account è stato creato correttamente. Non dimenticare di personalizzare le preferenze di {{SITENAME}}.",
+
+"loginpagetitle" => "Login utente",
+"yourname" => "Nome utente",
+"yourpassword" => "Password",
+"yourpasswordagain" => "Ripeti la password",
+"remembermypassword" => "Ricorda la password",
+"yourdomainname" => "Specificare il dominio",
+"externaldberror" => "Si è verificato un errore con il server di autenticazione esterno, oppure non si dispone delle autorizzazioni necessarie per aggiornare il proprio accesso esterno.",
+"loginproblem" => "<b>Si è verificato un errore durante l'accesso.</b><br />Riprovare.",
+"alreadyloggedin" => "<strong>L'utente $1 è già connesso a questo server.</strong><br />",
+
+"login" => "Entra",
+"loginprompt" => "Per accedere a {{SITENAME}} è necessario abilitare i cookie.",
+"userlogin" => "Entra o crea un nuovo accesso",
+"logout" => "Esci",
+"userlogout" => "Esci",
+"notloggedin" => "Accesso non effettuato",
+"nologin" => "Non hai ancora un accesso? $1.",
+"nologinlink" => "Crealo ora",
+"createaccount" => "Crea un nuovo accesso",
+"gotaccount" => "Hai già un accesso? $1.",
+"gotaccountlink" => "Entra",
+"createaccountmail" => "via e-mail",
+"badretype" => "Le password inserite non coincidono tra loro.",
+"userexists" => "Il nome utente inserito è già utilizzato. Si prega di scegliere un nome utente diverso.",
+"youremail" => "Indirizzo e-mail: *",
+"username" => "Nome utente",
+"uid" => "ID utente:",
+"yourrealname" => "Nome vero: *",
+"yourlanguage" => "Lingua:",
+"yourvariant" => "Variante:",
+"yournick" => "Soprannome (nickname):",
+"badsig" => "Errore nella firma non standard, verificare i tag HTML.",
+"email" => "Indirizzo e-mail",
+"prefs-help-email-enotif" => "L'indirizzo verrà inoltre usato per le segnalazioni via e-mail, se richieste con le apposite opzioni.",
+"prefs-help-realname" => "* Nome vero (opzionale): se si sceglie di inserirlo, verrà utilizzato per attribuire la paternità dei contenuti inviati.",
+"loginerror" => "Errore nell'accesso",
+"prefs-help-email" => "* Indirizzo e-mail (opzionale): Consente agli utenti di essere contattati attraverso la propria pagina utente o la relativa pagina di discussione, senza dover rivelare la propria identità.",
+"nocookiesnew" => "Il nome utente per l'accesso è stato creato, ma non è stato possibile accedere a {{SITENAME}} perché i cookie sono disattivati. Riprovare l'accesso con il nome utente e la password appena creati dopo aver attivato i cookie nel proprio browser.",
+"nocookieslogin" => "L'accesso a {{SITENAME}} richiede l'uso dei cookie, che risultano disattivati. Riprovare l'accesso dopo aver attivato i cookie nel proprio browser.",
+"noname" => "Il nome utente indicato non è valido.",
+"loginsuccesstitle" => "Accesso effettuato",
+"loginsuccess" => "'''Il collegamento al server di {{SITENAME}} con il nome utente \"$1\" è attivo.'''",
+"nosuchuser" => "Non è registrato alcun utente di nome \"$1\". Verificare il nome inserito o creare un nuovo accesso.",
+"nosuchusershort" => "Non è registrato alcun utente di nome \"$1\". Verificare il nome inserito.",
+"nouserspecified" => "È necessario specificare un nome utente.",
+"wrongpassword" => "La password inserita non è corretta. Riprovare.",
+"wrongpasswordempty" => "La password inserita è vuota. Riprovare.",
+"mailmypassword" => "Invia password via e-mail",
+"passwordremindertitle" => "Servizio Password Reminder di {{SITENAME}}",
+"passwordremindertext" => "Qualcuno (probabilmente tu, con indirizzo IP $1) ha richiesto l'invio di una nuova password di accesso a {{SITENAME}} ($4).
+La password per l'utente \"$2\" è stata impostata a \"$3\".
+È opportuno eseguire un accesso quanto prima e cambiare la password immediatamente.
+
+Se non sei stato tu a fare la richiesta, oppure hai ritrovato la password e non desideri più cambiarla, puoi ignorare questo messaggio e continuare a usare la vecchia password.",
+"noemail" => "Nessun indirizzo e-mail registrato per l'utente \"$1\".",
+"passwordsent" => "Una nuova password è stata inviata all'indirizzo e-mail registrato per l'utente \"$1\".
+Per favore, effettua un accesso non appena la ricevi.",
+"blocked-mailpassword" => "Per prevenire abusi, non è consentito usare la funzione \"Invia nuova password\" da un indirizzo IP bloccato.",
+"eauthentsent" => "Un messaggio e-mail di conferma è stato spedito all'indirizzo indicato.
+Per abilitare l'invio di messaggi e-mail per questo accesso è necessario seguire le istruzioni che vi sono indicate, in modo da confermare che si è i legittimi proprietari dell'indirizzo",
+"throttled-mailpassword" => "Una nuova password è già stata inviata da meno di $1 ore. Per prevenire abusi, la funzione \"Invia nuova password\" può essere usata solo una volta ogni $1 ore.",
+"mailerror" => "Errore nell'invio del messaggio: $1",
+"acct_creation_throttle_hit" => "Siamo spiacenti, ma hai già creato $1 account. Non puoi crearne altri.",
+"emailauthenticated" => "L'indirizzo e-mail è stato confermato il $1.",
+"emailnotauthenticated" => "L'indirizzo e-mail non è stato ancora confermato. Non verranno inviati messaggi e-mail attraverso le funzioni elencate di seguito.",
+"noemailprefs" => "Indicare un indirizzo e-mail per attivare queste funzioni.",
+"emailconfirmlink" => "Confermare il proprio indirizzo e-mail",
+"invalidemailaddress" => "L'indirizzo e-mail indicato ha un formato non valido. Inserire un indirizzo valido o svuotare la casella.",
+"accountcreated" => "Accesso creato",
+"accountcreatedtext" => "È stato creato un accesso per l'utente $1.",
+
+# Password reset dialog
+"resetpass" => "Reimposta la password",
+"resetpass_announce" => "L'accesso è stato effettuato con un codice temporaneo, inviato via e-mail. Per completare l'accesso è necessario impostare una nuova password:",
+"resetpass_text" => "<!-- Aggiungere il testo qui -->",
+"resetpass_header" => "Reimposta password",
+"resetpass_submit" => "Imposta la password e accedi al sito",
+"resetpass_success" => "La password è stata modificata. Accesso in corso...",
+"resetpass_bad_temporary" => "Password temporanea non valida. La password potrebbe essere stata già cambiata, oppure potrebbe essere stata richiesta una nuova password temporanea.",
+"resetpass_forbidden" => "Non è possibile modificare le password su questo sito",
+"resetpass_missing" => "Dati mancanti nel modulo.",
+
+
+# Edit page toolbar
+'bold_sample'=>'Grassetto',
+'bold_tip'=>'Grassetto',
+'italic_sample'=>'Corsivo',
+'italic_tip'=>'Corsivo',
+'link_sample'=>'Titolo del collegamento',
+'link_tip'=>'Collegamento interno',
+'extlink_sample'=>'http://www.example.com titolo del collegamento',
+'extlink_tip'=>'Collegamento esterno (notare il prefisso http:// )',
+'headline_sample'=>'Intestazione',
+'headline_tip'=>'Intestazione di 2° livello',
+'math_sample'=>'Inserire qui la formula',
+'math_tip'=>'Formula matematica (LaTeX)',
+'nowiki_sample'=>'Inserire qui il testo non formattato',
+'nowiki_tip'=>'Ignora la formattazione wiki',
+'image_sample'=>'Esempio.jpg',
+'image_tip'=>'Immagine incorporata',
+'media_sample'=>'Esempio.ogg',
+'media_tip'=>'Collegamento a file multimediale',
+'sig_tip'=>'Firma con data e ora',
+'hr_tip'=>'Linea orizzontale (usare con giudizio)',
+
+# Edit pages
+#
+"summary" => "Oggetto",
+"subject" => "Argomento (intestazione)",
+"minoredit" => "Questa è una modifica minore",
+"watchthis" => "Aggiungi agli osservati speciali",
+"savearticle" => "Salva la pagina",
+"preview" => "Anteprima",
+"showpreview" => "Visualizza anteprima",
+"showlivepreview" => "Funzione ''Live preview''",
+"showdiff" => "Mostra cambiamenti",
+"anoneditwarning" => "'''Attenzione:''' Accesso non effettuato. Nella cronologia della pagina verrà registrato l'indirizzo IP.",
+"missingsummary" => "'''Attenzione:''' Non è stato specificato l'oggetto della modifica. Premendo di nuovo 'Salva la pagina' la modifica verrà salvata con l'oggetto vuoto.",
+"missingcommenttext" => "Inserire un commento qui sotto.",
+"missingcommentheader" => "'''Attenzione:''' Non è stata specificata l'intestazione di questo commento. Premendo di nuovo '''Salva la pagina''' la modifica verrà salvata senza intestazione.",
+"summary-preview" => "Anteprima oggetto",
+"subject-preview" => "Anteprima oggetto/intestazione",
+"blockedtitle" => "Utente bloccato.",
+"blockedtext" => "Questo nome utente o indirizzo IP sono stati bloccati da $1.
+La motivazione del blocco è la seguente:<br />:''$2''<br />Se lo si desidera, è possibile contattare $1 o un altro [[{{ns:Project}}:Administrators|amministratore]] per discutere del blocco.
+
+Si noti che la funzione 'Scrivi all'utente' non è attiva se non è stato registrato un indirizzo e-mail valido nelle proprie [[{{ns:Special}}:Preferences|preferenze]].
+
+Si prega di specificare l'indirizzo IP coinvolto ($3) o il numero del blocco (ID #$5) in qualsiasi richiesta di chiarimenti.",
+"blockedoriginalsource" => "Di seguito viene mostrato il codice sorgente della pagina '''$1''':",
+"blockededitsource" => "Di seguito vengono mostrate le '''modifiche apportate''' alla pagina '''$1''':",
+"whitelistedittitle" => "Accesso necessario per la modifica delle pagine",
+"whitelistedittext" => "Per modificare le pagine è necessario $1.",
+"whitelistreadtitle" => "Accesso necessario per la lettura delle pagine",
+"whitelistreadtext" => "Per essere abilitato alla lettura delle pagine è necessario [[Special:Userlogin|eseguire l'accesso]].",
+"whitelistacctitle" => "Creazione di un nuovo accesso non consentita",
+"whitelistacctext" => "Per essere abilitati alla creazione di nuovi accessi su questo sito è necessario [[Special:Userlogin|effettuare l'accesso]] ed aver ricevuto le opportune autorizzazioni.",
+"confirmedittitle" => "Conferma della e-mail necessaria per la modifica delle pagine",
+"confirmedittext" => "Per essere abilitati alla modifica delle pagine è necessario confermare il proprio indirizzo e-mail. Per impostare e confermare l'indirizzo servirsi delle [[Special:Preferences|preferenze]].",
+"loginreqtitle" => "Per modificare questa pagina è necessario eseguire l'accesso al sito.",
+"loginreqlink" => "eseguire l'accesso",
+"loginreqpagetext" => "Per vedere altre pagine è necessario $1.",
+"accmailtitle" => "Password inviata.",
+"accmailtext" => "La password per l'utente \"$1\" è stata inviata all'indirizzo $2.",
+"newarticle" => "(Nuovo)",
+"newarticletext" => "Il collegamento appena seguito corrisponde a una pagina non ancora esistente.
+Se si desidera creare la pagina ora, basta cominciare a scrivere il testo nella casella qui sotto
+(fare riferimento alle [[Project:Aiuto|pagine di aiuto]] per maggiori informazioni).
+Se il collegamento è stato seguito per errore, è sufficiente fare clic sul pulsante '''Indietro''' del proprio browser.",
+"anontalkpagetext" => "----''Questa è la pagina di discussione di un utente anonimo, che non ha ancora creato un accesso o comunque non lo usa. Per identificarlo è quindi necessario usare il numero del suo indirizzo IP. Gli indirizzi IP possono però essere condivisi da più utenti. Se sei un utente anonimo e ritieni che i commenti presenti in questa pagina non si riferiscano a te, [[Special:Userlogin|crea un nuovo accesso o entra]] con quello che già hai per evitare di essere confuso con altri utenti anonimi in futuro''",
+
+"noarticletext" => "In questo momento la pagina richiesta è vuota. È possibile [[Special:Search/{{PAGENAME}}|cercare questo titolo]] nelle altre pagine del sito oppure [{{fullurl:{{FULLPAGENAME}}|action=edit}} modificare la pagina ora].",
+"clearyourcache" => "'''Nota:''' dopo aver salvato è necessario pulire la cache del proprio browser per vedere i cambiamenti. Per '''Mozilla / Firefox / Safari''': fare clic su ''Ricarica'' tenendo premuto il tasto delle maiuscole, oppure premere ''Ctrl-Maiusc-R'' (''Cmd-Maiusc-R'' su Mac); per '''Internet Explorer:''' mantenere premuto il tasto ''Ctrl'' mentre si preme il pulsante ''Aggiorna'' o premere ''Ctrl-F5''; per '''Konqueror''': premere il pulsante ''Ricarica'' o il tasto ''F5''; per '''Opera''' può essere necessario svuotare completamente la cache dal menu ''Strumenti → Preferenze''.",
+"usercssjsyoucanpreview" => "<strong>Suggerimento:</strong> si consiglia di usare il pulsante \'Visualizza anteprima\' per provare i nuovi CSS o JavaScript prima di salvarli.",
+"usercsspreview" => "'''Questa è solo un'anteprima del proprio CSS personale; le modifiche non sono ancora state salvate!'''",
+"userjspreview" => "'''Questa è solo un'anteprima per provare il proprio JavaScript personale; le modifiche non sono ancora state salvate!'''",
+"userinvalidcssjstitle" => "'''Attenzione:''' Non esiste alcuna skin con nome \"$1\". Si noti che le pagine per i .css e .js personalizzati hanno l'iniziale del titolo minuscola, ad esempio User:Esempio/monobook.js e non User:Esempio/Monobook.css.",
+"updated" => "(Aggiornato)",
+"note" => "<strong>NOTA:</strong>",
+"previewnote" => "Questa è solo una anteprima; le modifiche alla pagina NON sono ancora state salvate!",
+"session_fail_preview" => "<strong>Siamo spiacenti, non è stato possibile elaborare la modifica perché sono andati persi i dati relativi alla sessione. Se il problema persiste, si può provare a scollegarsi ed effettuare un nuovo accesso.</strong>",
+"previewconflict" => "L'anteprima corrisponde al testo presente nella casella di modifica superiore e rappresenta la pagina come apparirà se si sceglie di premere 'Salva la pagina' in questo momento.",
+"session_fail_preview_html" => "<strong>Siamo spiacenti, non è stato possibile elaborare la modifica perché sono andati persi i dati relativi alla sessione.</strong>
+
+''Poiché in questo sito è abilitato l'uso di HTML senza limitazioni, l'anteprima non viene visualizzata; si tratta di una misura di sicurezza contro gli attacchi JavaScript.''
+
+<strong>Se il problema persiste, si può provare a scollegarsi ed effettuare un nuovo accesso.</strong>",
+
+"importing" => "Importazione di $1",
+"editing" => "Modifica di $1",
+'editinguser' => "Modifica di $1",
+"editingsection" => "Modifica di $1 (sezione)",
+"editingcomment" => "Modifica di $1 (commento)",
+"editconflict" => "Conflitto di edizione su $1",
+"explainconflict" => "Un altro utente ha salvato una nuova versione della pagina mentre stavi effettuando le modifiche.<br />
+La casella di modifica superiore contiene il testo della pagina attualmente online, così come è stato aggiornato dall'altro utente. La versione con le tue modifiche è invece riportata nella casella di modifica inferiore. Se desideri confermarle, devi riportare le tue modifiche nel testo esistente (casella superiore).
+Premendo il pulsante 'Salva la pagina', verrà salvato <b>solo</b> il testo contenuto nella casella di modifica superiore.<br />",
+"yourtext" => "Il tuo testo",
+"storedversion" => "La versione memorizzata",
+"nonunicodebrowser" => "<strong>Attenzione: Si sta utilizzando un browser non compatibile con i caratteri Unicode. Per consentire la modifica delle pagine senza creare inconvenienti, i caratteri non ASCII vengono visualizzati nella casella di modifica sotto forma di codici esadecimali.</strong>",
+"editingold" => "<strong>Attenzione: si sta modificando una versione non aggiornata della pagina.<br />
+Se si sceglie di salvarla, tutti i cambiamenti apportati dopo questa revisione andranno perduti.</strong>",
+"yourdiff" => "Differenze",
+"copyrightwarning" => "Nota: tutti i contributi a {{SITENAME}} si considerano rilasciati nei termini della licenza d'uso $2 (vedi $1 per maggiori dettagli). Se non desideri che i tuoi testi possano essere modificati e ridistribuiti da chiunque senza alcuna limitazione, non inviarli a {{SITENAME}}.<br />
+Con l'invio del testo dichiari inoltre, sotto la tua responsabilità, che il testo è stato scritto da te personalmente oppure che è stato copiato da una fonte di pubblico dominio o analogamente libera.
+<strong>NON INVIARE MATERIALE COPERTO DA DIRITTO DI AUTORE SENZA AUTORIZZAZIONE!</strong>",
+"copyrightwarning2" => "Nota: tutti i contributi inviati a {{SITENAME}} possono essere modificati, stravolti o cancellati da parte degli altri partecipanti. Se non desideri che i tuoi testi possano essere modificati senza alcun riguardo, non inviarli a questo sito.<br />
+Con l'invio del testo dichiari inoltre, sotto la tua responsabilità, che il testo è stato scritto da te personalmente oppure che è stato copiato da una fonte di pubblico dominio o analogamente libera. (vedi $1 per maggiori dettagli)
+<strong>NON INVIARE MATERIALE COPERTO DA DIRITTO DI AUTORE SENZA AUTORIZZAZIONE!</strong>",
+"longpagewarning" => "<strong>ATTENZIONE: Questa pagina è lunga $1 kilobyte; alcuni browser potrebbero presentare dei problemi nella modifica di pagine che si avvicinano o superano i 32 KB. Valuta l'opportunità di suddividere la pagina in sezioni più piccole.</strong>",
+"longpageerror" => "<strong>ERRORE: Il testo inviato è lungo $1 kilobyte, più della dimensione massima consentita ($2 kilobyte). Il testo non può essere salvato.</strong>",
+"readonlywarning" => "<strong>ATTENZIONE: Il database è stato bloccato per manutenzione, è quindi impossibile salvare le modifiche in questo momento. Per non perderle, è possibile copiare quanto inserito finora nella casella di modifica, incollarlo in un programma di elaborazione testi e salvarlo in attesa dello sblocco del database.</strong>",
+"protectedpagewarning" => "<strong>ATTENZIONE: Questa pagina è stata bloccata in modo che solo gli utenti con privilegi di amministratore possano modificarla.</strong>",
+"semiprotectedpagewarning" => "'''Nota:''' Questa pagina è stata bloccata in modo che solo gli utenti registrati possano modificarla.",
+"templatesused" => "Template utilizzati in questa pagina:",
+"templatesusedpreview" => "Template utilizzati in questa anteprima:",
+"templatesusedsection" => "Template utilizzati in questa sezione:",
+"template-protected" => "(protetto)",
+"template-semiprotected" => "(semiprotetto)",
+"edittools" => "<!-- Testo che appare al di sotto del modulo di modifica e di upload. -->",
+"nocreatetitle" => "Creazione delle pagine limitata",
+"nocreatetext" => "Questo sito ha limitato la possibilità di creare nuove pagine ai soli utenti registrati. È possibile tornare indietro e modificare una pagina esistente, oppure [[Special:Userlogin|entrare o creare un nuovo accesso]].",
+
+# "Undo" feature
+"undo-success" => "Questa modifica può essere annullata. Verificare il confronto presentato di seguito per accertarsi che il contenuto corrisponda a quanto desiderato e quindi salvare le modifiche per completare la procedura di annullamento.",
+"undo-failure" => "Impossibile annullare la modifica a causa di un conflitto con modifiche intermedie.",
+"undo-summary" => "Annullata la modifica $1 di [[{{ns:Special}}:Contributions/$2]] ([[{{ns:User_talk}}:$2]])",
+
+#Account creation failure
+"cantcreateaccounttitle" => "Impossibile registrare un utente",
+"cantcreateaccounttext" => "La registrazione di nuovi utenti da questo indirizzo IP (<b>$1</b>) è stata bloccata. È possibile che questo indirizzo sia stato usato in passato per compiere vandalismi, causandone il blocco.",
+
+# History pages
+#
+"revhistory" => "Cronologia delle versioni di questa pagina.",
+"viewpagelogs" => "Visualizza i log relativi a questa pagina.",
+"nohistory" => "Cronologia delle versioni di questa pagina non reperibile.",
+"revnotfound" => "Versione non trovata",
+"revnotfoundtext" => "La versione richiesta della pagina non è stata trovata.
+Verificare la URL usata per accedere a questa pagina.",
+"loadhist" => "Caricamento cronologia di questa pagina",
+"currentrev" => "Versione corrente",
+"revisionasof" => "Versione del $1",
+"revision-info" => "Versione del $1, autore: $2",
+"previousrevision" => "← Versione meno recente",
+"nextrevision" => "Versione più recente →",
+"currentrevisionlink" => "Versione corrente",
+"cur" => "corr",
+"next" => "succ",
+"last" => "prec",
+"orig" => "orig",
+"histlegend" => "Confronto tra versioni: selezionare le caselle corrispondenti alle versioni desiderate e premere Invio o il pulsante in basso.
+
+Legenda: (corr) = differenze con la versione corrente, (prec) = differenze con la versione precedente, '''m''' = modifica minore",
+"deletedrev" => "[cancellata]",
+"histfirst" => "Prima",
+"histlast" => "Ultima",
+"rev-deleted-comment" => "(commento rimosso)",
+"rev-deleted-user" => "(nome utente rimosso)",
+"rev-deleted-text-permission" => '<div class="mw-warning plainlinks">
+Questa versione della pagina è stata rimossa dagli archivi visibili al pubblico.
+Consultare il [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} log di cancellazione] per ulteriori dettagli.
+</div>',
+"rev-deleted-text-view" => '<div class="mw-warning plainlinks">
+Questa versione della pagina è stata rimossa dagli archivi visibili al pubblico.
+Il testo può essere visualizzato soltanto dagli amministratori del sito.
+Consultare il [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} log di cancellazione] per ulteriori dettagli.
+</div>',
+"rev-delundel" => "mostra/nascondi",
+
+"history-feed-title" => "Cronologia",
+"history-feed-description" => "Cronologia della pagina su questo sito",
+"history-feed-item-nocomment" => "$1 il $2", # user at time
+"history-feed-empty" => "La pagina richiesta non esiste; potrebbe essere stata cancellata dal sito o rinominata. Verificare con la [[Special:Search|pagina di ricerca]] se vi sono nuove pagine.",
+
+# Revision deletion
+#
+"revisiondelete" => "Cancella o ripristina versioni",
+"revdelete-nooldid-title" => "Versione non specificata",
+"revdelete-nooldid-text" => "Non è stata specificata alcuna versione della pagina su cui eseguire questa funzione.",
+"revdelete-selected" => "Versioni selezionate di [[:$1]]:",
+"revdelete-text" => "Le versioni cancellate restano visibili nella cronologia della pagina, mentre il testo contenuto non è accessibile al pubblico.
+
+Gli altri amministratori del sito potranno accedere comunque ai contenuti nascosti e ripristinarli attraverso questa stessa interfaccia, se non sono state impostate altre limitazioni in fase di installazione del sito.",
+"revdelete-legend" => "Imposta le seguenti limitazioni sulle versioni cancellate:",
+"revdelete-hide-text" => "Nascondi il testo della versione",
+"revdelete-hide-comment" => "Nascondi l'oggetto della modifica",
+"revdelete-hide-user" => "Nascondi il nome o l'indirizzo IP dell'autore",
+"revdelete-hide-restricted" => "Applica le limitazioni indicate anche agli amministratori",
+"revdelete-log" => "Commento per il log:",
+"revdelete-submit" => "Applica alla revisione selezionata",
+"revdelete-logentry" => "ha modificato la visibilità per una revisione di [[$1]]",
+
+# Diffs
+#
+"difference" => "(Differenze fra le revisioni)",
+"loadingrev" => "caricamento revisione per differenze",
+"lineno" => "Riga $1:",
+"editcurrent" => "Modifica la versione corrente di questa pagina",
+"selectnewerversionfordiff" => "Seleziona una versione più recente per il confronto",
+"selectolderversionfordiff" => "Seleziona una versione meno recente per il confronto",
+"compareselectedversions" => "Confronta le versioni selezionate",
+"editundo" => "annulla",
+"diff-multi" => "({{plural:$1|Una revisione intermedia non mostrata|$1 revisioni intermedie non mostrate}}.)",
+
+
+# Search results
+#
+"searchresults" => "Risultati della ricerca",
+"searchresulttext" => "Per maggiori informazioni sulla ricerca interna di {{SITENAME}}, vedi [[Project:Ricerca|Ricerca in {{SITENAME}}]].",
+"searchsubtitle" => "Ricerca di '''[[:$1]]'''",
+"searchsubtitleinvalid" => "Ricerca di '''$1'''",
+"badquery" => "Richiesta mal posta",
+"badquerytext" => "Impossibile elaborare la richiesta. Questo potrebbe dipendere dall'aver cercato una parola più corta di 4 caratteri, il che al momento è impossibile, oppure da una errore nella forma della richiesta, ad esempio \"pesce and and azzurro\". Per favore, riprova.",
+"matchtotals" => "La ricerca di \"$1\" ha trovato $2 riscontri nel titolo e $3 riscontri nel testo.",
+"noexactmatch" => "'''La pagina \"$1\" non esiste.''' È possibile [[:$1|crearla ora]].",
+"titlematches" => "Corrispondenze nel titolo delle pagine",
+"notitlematches" => "Nessuna corrispondenza nei titoli delle pagine",
+"textmatches" => "Corrispondenze nel testo delle pagine",
+"notextmatches" => "Nessuna corrispondenza nel testo delle pagine",
+"prevn" => "precedenti $1",
+"nextn" => "successivi $1",
+"viewprevnext" => "Vedi ($1) ($2) ($3).",
+"showingresults" => "Di seguito vengono presentati fino a <b>$1</b> risultati a partire dal numero <b>$2</b>.",
+"showingresultsnum" => "Di seguito vengono presentati <b>$3</b> risultati a partire dal numero <b>$2</b>.",
+"nonefound" => "<strong>Nota</strong>: alcune parole comuni nella lingua inglese, come \"zero\" o \"more\", non sono indicizzate e possono quindi dare luogo a risultati nulli, così come l'indicazione di più termini da ricercare (solo le pagine che contengano tutti i termini richiesti vengono visualizzate fra i risultati).",
+"powersearch" => "Ricerca",
+"powersearchtext" => "Ricerca nei seguenti namespace:<br />$1<br />$2 Mostra i redirect<br />Criteri di ricerca: $3 $9",
+"searchdisabled" => "La ricerca interna di {{SITENAME}} non è attiva; nel frattempo si può provare ad usare un motore di ricerca esterno come Google. (Si noti però che i contenuti di {{SITENAME}} presenti in tali motori potrebbero non essere aggiornati.)",
+
+"blanknamespace" => "(Principale)",
+
+# Preferences page
+#
+"preferences" => "Preferenze",
+'mypreferences' => 'le mie preferenze',
+"prefsnologin" => "Accesso non effettuato",
+"prefsnologintext" => "Per poter personalizzare le preferenze è necessario effettuare l'[[Special:Userlogin|accesso]].",
+"prefsreset" => "Le preferenze sono state ripristinate ai valori predefiniti.",
+"qbsettings" => "Quickbar",
+"changepassword" => "Cambia password",
+"skin" => "Aspetto grafico (skin)",
+"math" => "Formule matematiche",
+"dateformat" => "Formato della data",
+"datedefault" => "Nessuna preferenza",
+"datetime" => "Data e ora",
+"math_failure" => "Errore del parser",
+"math_unknown_error" => "errore sconosciuto",
+"math_unknown_function" => "funzione sconosciuta",
+"math_lexing_error" => "errore lessicale",
+"math_syntax_error" => "errore di sintassi",
+"math_image_error" => "Conversione in PNG non riuscita; verificare che siano correttamente installati i seguenti programmi: latex, dvips, gs e convert.",
+"math_bad_tmpdir" => "Impossibile scrivere o creare la directory temporanea per math",
+"math_bad_output" => "Impossibile scrivere o creare la directory di output per math",
+"math_notexvc" => "Eseguibile texvc mancante; per favore consultare math/README per la configurazione.",
+"prefs-personal" => "Profilo utente",
+"prefs-rc" => "Ultime modifiche",
+"prefs-watchlist" => "Osservati speciali",
+"prefs-watchlist-days" => "Numero di giorni da mostrare negli osservati speciali:",
+"prefs-watchlist-edits" => "Numero di modifiche da mostrare con le funzioni avanzate:",
+"prefs-misc" => "Varie",
+"saveprefs" => "Salva le preferenze",
+"resetprefs" => "Reimposta le preferenze",
+"oldpassword" => "Vecchia password:",
+"newpassword" => "Nuova password:",
+"retypenew" => "Riscrivi la nuova password:",
+"textboxsize" => "Casella di modifica",
+"rows" => "Righe:",
+"columns" => "Colonne:",
+"searchresultshead" => "Ricerca",
+"resultsperpage" => "Numero di risultati per pagina:",
+"contextlines" => "Righe di testo per ciascun risultato:",
+"contextchars" => "Numero di caratteri di contesto:",
+"stubthreshold" => "Evidenzia gli stub più corti di:",
+"recentchangescount" => "Numero di righe nelle ultime modifiche:",
+"savedprefs" => "Le preferenze sono state salvate.",
+"timezonelegend" => "Fuso orario",
+"timezonetext" => "Numero di ore di differenza fra l'ora locale e l'ora del server (UTC).",
+"localtime" => "Ora locale",
+"timezoneoffset" => "Differenza¹",
+"servertime" => "Ora del server",
+"guesstimezone" => "Usa l'ora del tuo browser",
+"allowemail" => "Consenti la ricezione di e-mail da altri utenti (1)",
+"defaultns" => "Namespace predefiniti per la ricerca:",
+"default" => "predefinito",
+"files" => "File",
+
+# User rights
+"userrights-lookup-user" => "Gestione dei gruppi utente",
+"userrights-user-editname" => "Inserire il nome utente:",
+"editusergroup" => "Modifica gruppi utente",
+
+"userrights-editusergroup" => "Modifica gruppi utente",
+"saveusergroups" => "Salva gruppi utente",
+"userrights-groupsmember" => "Appartiene ai gruppi:",
+"userrights-groupsavailable" => "Gruppi disponibili:",
+"userrights-groupshelp" => "Selezionare i gruppi ai quali si vuole associare o rimuovere l'utente. L'appartenenza ai gruppi non selezionati non verrà modificata. Per deselezionare un gruppo, premere Ctrl + il tasto sinistro del mouse.",
+
+# Groups
+"group" => "Gruppo:",
+"group-bot" => "Bot",
+"group-sysop" => "Amministratori",
+"group-bureaucrat" => "Burocrati",
+"group-all" => "(utenti)",
+
+"group-bot-member" => "Bot",
+"group-sysop-member" => "Amministratore",
+"group-bureaucrat-member" => "Burocrate",
+
+"grouppage-bot" => "Project:Bot",
+"grouppage-sysop" => "Project:Amministratori",
+"grouppage-bureaucrat" => "Project:Burocrati",
+
+# Recent changes
+#
+"changes" => "modifiche",
+"recentchanges" => "Ultime modifiche",
+"recentchangestext" => "Questa pagina presenta le modifiche più recenti ai contenuti del sito.",
+"recentchanges-feed-description" => "Questo feed riporta le modifiche più recenti ai contenuti del sito.",
+"rcnote" => "Di seguito sono elencate le <strong>$1</strong> modifiche più recenti apportate negli ultimi <strong>$2</strong> giorni, aggiornate a $3.",
+"rcnotefrom" => "Di seguito sono elencate le modifiche apportate a partire da <b>$2</b> (fino a <b>$1</b>).",
+"rclistfrom" => "Mostra le modifiche apportate a partire da $1",
+"rcshowhideminor" => "$1 le modifiche minori",
+"rcshowhidebots" => "$1 i bot",
+"rcshowhideliu" => "$1 gli utenti registrati",
+"rcshowhideanons" => "$1 gli utenti anonimi",
+"rcshowhidepatr" => "$1 le modifiche controllate",
+"rcshowhidemine" => "$1 le mie modifiche",
+"rclinks" => "Mostra le $1 modifiche più recenti apportate negli ultimi $2 giorni<br />$3",
+"diff" => "diff",
+"hist" => "cron",
+"hide" => "nascondi",
+"show" => "mostra",
+"minoreditletter" => "m",
+"newpageletter" => "N",
+"boteditletter" => "b",
+"sectionlink" => "→",
+"number_of_watching_users_pageview" => "[osservata da $1 utenti]",
+"rc_categories" => "Limita alle categorie (separate da \"|\")",
+"rc_categories_any" => "Qualsiasi",
+
+# Upload
+#
+"upload" => "Carica un file",
+"uploadbtn" => "Carica",
+"reupload" => "Carica di nuovo",
+"reuploaddesc" => "Torna al modulo per il caricamento.",
+"uploadnologin" => "Accesso non effettuato",
+"uploadnologintext" => "Il caricamento dei file è consentito solo agli utenti registrati che hanno eseguito [[Special:Userlogin|l'accesso]] al sito.",
+"upload_directory_read_only" => "Il server web non è in grado di scrivere nella directory di upload ($1).",
+"uploaderror" => "Errore nel caricamento",
+"uploadtext" => "Usare il modulo sottostante per caricare nuovi file. Per visualizzare o ricercare i file già caricati, consultare il [[Special:Imagelist|log dei file caricati]]. Caricamenti e cancellazioni di file sono registrati nel [[Special:Log/upload|log degli upload]].
+
+Per inserire un'immagine in una pagina, fare un collegamento di questo tipo:
+* '''<nowiki>[[</nowiki>{{ns:Image}}:file.jpg<nowiki>]]</nowiki>'''
+* '''<nowiki>[[</nowiki>{{ns:Image}}:file.png|testo alternativo<nowiki>]]</nowiki>'''
+usare invece
+* '''<nowiki>[[</nowiki>{{ns:Media}}:file.ogg<nowiki>]]</nowiki>'''
+per collegare direttamente gli altri tipi di file.",
+"uploadlog" => "File caricati",
+"uploadlogpage" => "Log dei file caricati",
+"uploadlogpagetext" => "Elenco degli ultimi file caricati sul server di {{SITENAME}}.",
+"filename" => "Nome del file",
+"filedesc" => "Dettagli",
+"fileuploadsummary" => "Dettagli del file:",
+"filestatus" => "Informazioni sul copyright",
+"filesource" => "Fonte",
+"copyrightpage" => "Project:Copyright",
+"copyrightpagename" => "Il copyright su {{SITENAME}}",
+"uploadedfiles" => "Elenco dei file caricati",
+"ignorewarning" => "Ignora l'avvertimento e salva comunque il file.",
+"ignorewarnings" => "Ignora i messaggi di avvertimento del sistema",
+"minlength" => "I nomi dei file devono essere lunghi almeno tre caratteri.",
+"illegalfilename" => "Il nome \"$1\" contiene dei caratteri non ammessi nei titoli delle pagine. Dare al file un nome diverso e provare a caricarlo di nuovo.",
+"badfilename" => "Il nome del file è stato convertito in \"$1\".",
+"badfiletype" => "\".$1\" non è tra i tipi di file raccomandati per le immagini.",
+"large-file" => "Si raccomanda di non superare le dimensioni di $1 per ciascun file; questo file è grande $2.",
+"largefileserver" => "Il file supera le dimensioni consentite dalla configurazione del server.",
+"emptyfile" => "Il file appena caricato sembra essere vuoto. Ciò potrebbe essere dovuto ad un errore nel nome del file. Verificare che si intenda realmente caricare questo file.",
+"fileexists" => "Un file con questo nome esiste già. Verificare prima $1 se non si è sicuri di volerlo sovrascrivere.",
+"fileexists-forbidden" => "Un file con questo nome esiste già. Tornare indietro e modificare il nome con il quale caricare il file. [[Image:$1|thumb|center|$1]]",
+"fileexists-shared-forbidden" => "Un file con questo nome esiste già nell'archivio di risorse multimediali condivise. Tornare indietro e modificare il nome con il quale caricare il file. [[Image:$1|thumb|center|$1]]",
+"successfulupload" => "Caricamento completato",
+"fileuploaded" => "Il file \"$1\" è stato caricato correttamente sul server.
+Seguire il collegamento: $2 per modificare la pagina di descrizione del file appena caricato, indicandone la fonte, l'autore, la data di creazione e ogni altra informazione di cui si sia in possesso. Se si tratta di un'immagine, la si può inserire nelle pagine con il comando: <tt><nowiki>[[{{ns:Image}}:$1|thumb|Descrizione]]</nowiki></tt>.",
+"uploadwarning" => "Avviso di Upload",
+"savefile" => "Salva file",
+"uploadedimage" => "ha caricato \"[[$1]]\"",
+"uploaddisabled" => "Upload non attivo",
+"uploaddisabledtext" => "Il caricamento dei file non è attivo su questo sito.",
+"uploadscripted" => "Questo file contiene codice HTML o di script, che potrebbe essere interpretato erroneamente da un browser web.",
+"uploadcorrupt" => "Il file è corrotto o ha un'estensione non corretta. Controllare il file e provare di nuovo il caricamento.",
+"uploadvirus" => "Questo file contiene un virus! Dettagli: $1",
+"sourcefilename" => "Nome del file di origine",
+"destfilename" => "Nome del file di destinazione",
+"watchthisupload" => "Aggiungi agli osservati speciali",
+"filewasdeleted" => "Un file con questo nome è stato già caricato e cancellato in passato. Verificare $1 prima di caricarlo di nuovo.",
+
+"upload-proto-error" => "Protocollo errato",
+"upload-proto-error-text" => "Per l'upload remoto è necessario specificare URL che iniziano con <code>http://</code> oppure <code>ftp://</code>.",
+"upload-file-error" => "Errore interno",
+"upload-file-error-text" => "Si è verificato un errore interno durante la creazione di un file temporaneo sul server. Contattare un amministratore di sistema.",
+"upload-misc-error" => "Errore non identificato per l'upload",
+"upload-misc-error-text" => "Si è verificato un errore non identificato durante il caricamento del file. Verificare che la URL sia corretta e accessibile e provare di nuovo. Se il problema persiste, contattare un amministratore di sistema.",
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+"upload-curl-error6" => "URL non raggiungibile",
+"upload-curl-error6-text" => "Impossibile raggiungere la URL specificata. Verificare che la URL sia scritta correttamente e che il sito in questione sia attivo.",
+"upload-curl-error28" => "Tempo scaduto per l'upload",
+"upload-curl-error28-text" => "Il sito remoto ha impiegato troppo tempo a rispondere. Verificare che il sito sia attivo, attendere qualche minuto e provare di nuovo, eventualmente in un momento di minore traffico.",
+
+"license" => "Licenza d'uso",
+"nolicense" => "Nessuna licenza indicata",
+"upload_source_url" => " (una URL corretta e accessibile)",
+"upload_source_file" => " (un file sul proprio computer)",
+
+# Image list
+#
+"imagelist" => "Elenco dei file",
+"imagelisttext" => "Di seguito viene presentata una lista di '''$1''' file ordinati per $2.",
+"imagelistforuser" => "L'elenco mostra solo i file caricati da $1.",
+"getimagelist" => "caricamento elenco file",
+"ilsubmit" => "Ricerca",
+"showlast" => "Mostra gli ultimi $1 file ordinati per $2.",
+"byname" => "nome",
+"bydate" => "data",
+"bysize" => "dimensione",
+"imgdelete" => "canc",
+"imgdesc" => "desc",
+"imgfile" => "file",
+"imglegend" => "Legenda: (desc) = visualizza e modifica la descrizione del file.",
+"imghistory" => "Cronologia del file",
+"revertimg" => "ripr",
+"deleteimg" => "canc",
+"deleteimgcompletely" => "canc",
+"imghistlegend" => "Legenda: (cur) = immagine corrente, (canc) = cancella questa vecchia versione, (ripr) = ripristina questa vecchia versione come versione attuale.
+<br /><i>Fare clic su una data per vedere tutte le immagini che sono state caricate in quella data </i>.",
+"imagelinks" => "Collegamenti all'immagine",
+"linkstoimage" => "Pagine che contengono collegamenti all'immagine:",
+"nolinkstoimage" => "Nessuna pagina contiene collegamenti all'immagine.",
+"sharedupload" => "Questo file è un upload condiviso; può essere quindi utilizzato da più progetti wiki.",
+"shareduploadwiki" => "Si veda $1 per ulteriori informazioni.",
+"shareduploadwiki-linktext" => "la relativa pagina di descrizione",
+"noimage" => "Un file con questo nome non esiste; $1?",
+"noimage-linktext" => "caricarlo ora",
+"uploadnewversion-linktext" => "Carica una nuova versione di questo file",
+"imagelist_date" => "Data",
+"imagelist_name" => "Nome",
+"imagelist_user" => "Utente",
+"imagelist_size" => "Dimensione in byte",
+"imagelist_description" => "Description",
+"imagelist_search_for" => "Ricerca immagini per nome:",
+
+# Mime search
+#
+"mimesearch" => "Ricerca in base al tipo MIME",
+"mimetype" => "Tipo MIME:",
+"download" => "download",
+
+# Unwatchedpages
+#
+"unwatchedpages" => "Pagine non osservate",
+
+# List interwikis
+"listinterwikis" => "Elenco dei collegamenti inter-wiki",
+
+# List redirects
+"listredirects" => "Elenco dei redirect",
+
+# Unused templates
+"unusedtemplates" => "Template non utilizzati",
+"unusedtemplatestext" => "In questa pagina vengono elencati tutti i template (pagine del namespace Template) che non sono inclusi in nessuna pagina. Prima di cancellarli è opportuno verificare che i singoli template non abbiano altri collegamenti entranti.",
+'unusedtemplateswlh' => "altri collegamenti",
+
+# Random redirect
+"randomredirect" => "Un redirect a caso",
+
+# Statistics
+#
+"statistics" => "Statistiche",
+"sitestats" => "Statistiche relative a {{SITENAME}}",
+"userstats" => "Statistiche relative agli utenti",
+"sitestatstext" => "Il database contiene complessivamente '''$1''' pagine.
+Questa cifra comprende anche le pagine di discussione, quelle di servizio di {{SITENAME}}, le voci più esigue (\"stub\"), i redirect e altre pagine che probabilmente non vanno considerate tra i contenuti del sito. Escludendo le pagine sopra descritte, ve ne sono '''$2''' di contenuti veri e propri.
+
+Sono stati inoltre caricati '''$8''' file.
+
+Dall'installazione del sito sino a questo momento sono state visitate '''$3''' pagine ed eseguite '''$4''' modifiche, pari a una media di '''$5''' modifiche per pagina e '''$6''' richieste di lettura per ciascuna modifica.
+
+La [http://meta.wikimedia.org/wiki/Help:Job_queue coda] contiene '''$7''' processi.",
+"userstatstext" => "In questo momento vi sono '''$1''' utenti registrati, dei quali '''$2''' (pari al '''$4%''') sono $5.",
+"statistics-mostpopular" => "Pagine più visitate",
+
+"disambiguations" => "Pagine di disambigua",
+"disambiguationspage" => "Template:Disambigua",
+"disambiguationstext" => "Le pagine nella lista che segue contengono dei collegamenti a <i>pagine di disambigua</i> piuttosto che all'argomento corretto cui fanno riferimento.<br />Sono considerate pagine di disambigua tutte quelle che contengono collegamenti al $1.<br />I collegamenti da altri namespace <i>non</i> sono considerati nella lista che segue.",
+
+"doubleredirects" => "Redirect doppi",
+"doubleredirectstext" => "<b>Attenzione:</b> Questa lista può contenere risultati errati, ad esempio nel caso in cui il comando #REDIRECT sia seguito da altro testo o collegamenti.<br />\nCiascuna riga contiene i collegamenti al primo ed al secondo redirect, oltre alla prima riga di testo del secondo redirect che di solito contiene la pagina di destinazione \"corretta\" alla quale dovrebbe puntare anche il primo redirect.",
+"brokenredirects" => "Redirect errati",
+"brokenredirectstext" => "I seguenti redirect puntano a pagine inesistenti.",
+
+# Miscellaneous special pages
+#
+"nbytes" => "$1 byte",
+"ncategories" => "$1 {{PLURAL:$1|categoria|categorie}}",
+"nlinks" => "$1 {{PLURAL:$1|collegamento|collegamenti}}",
+"nmembers" => "$1 {{PLURAL:$1|elemento|elementi}}",
+"nrevisions" => "$1 {{PLURAL:$1|revisione|revisioni}}",
+"nviews" => "$1 {{PLURAL:$1|visita|visite}}",
+
+"lonelypages" => "Pagine orfane",
+"lonelypagestext" => "Le pagine indicate di seguito sono prive di collegamenti che provengono da altre pagine del sito.",
+"uncategorizedpages" => "Pagine prive di categorie",
+"uncategorizedcategories" => "Categorie prive di categorie",
+"uncategorizedimages" => "Immagini prive di categorie",
+"unusedcategories" => "Categorie non utilizzate",
+"unusedimages" => "File non utilizzati",
+"popularpages" => "Pagine più visitate",
+"wantedcategories" => "Categorie richieste",
+"wantedpages" => "Pagine più richieste",
+"mostlinked" => "Pagine più richiamate",
+"mostlinkedcategories" => "Categorie più richiamate",
+"mostcategories" => "Voci con più categorie",
+"mostimages" => "Immagini più richiamate",
+"allpages" => "Tutte le pagine",
+"mostrevisions" => "Voci con più revisioni",
+"prefixindex" => "Indice delle voci per lettere iniziali",
+"randompage" => "Una pagina a caso",
+"shortpages" => "Pagine più corte",
+"longpages" => "Pagine più lunghe",
+"deadendpages" => "Pagine senza uscita",
+"deadendpagestext" => "Le pagine indicate di seguito sono prive di collegamenti verso altre pagine del sito.",
+"listusers" => "Elenco degli utenti",
+"specialpages" => "Pagine speciali",
+"spheading" => "Pagine speciali non riservate",
+"restrictedpheading" => "Pagine speciali riservate",
+"recentchangeslinked" => "Modifiche correlate",
+"rclsub" => "(alle pagine collegate a \"$1\")",
+"newpages" => "Pagine più recenti",
+"newpages-username" => "Nome utente:",
+"ancientpages" => "Pagine meno recenti",
+"intl" => "Collegamenti tra lingue diverse",
+"move" => "Sposta",
+"movethispage" => "Sposta questa pagina",
+"unusedimagestext" => "<p>Si noti che è possibile realizzare collegamenti ai file da altri siti, usando direttamente la URL; questi potrebbero quindi essere utilizzati anche se compaiono nell'elenco.</p>",
+"unusedcategoriestext" => "Le pagine delle categorie indicate di seguito sono state create ma non contengono nessuna pagina né sottocategoria.",
+
+#Book sources
+"booksources" => "Fonti librarie",
+"booksources-search-legend" => "Ricerca di fonti librarie",
+"booksources-isbn" => "Codice ISBN:",
+"booksources-go" => "Vai",
+"booksources-text" => "Di seguito viene presentato un elenco di collegamenti verso siti esterni che vendono libri nuovi e usati, attraverso i quali è possibile ottenere maggiori informazioni sul testo cercato.",
+
+"categoriespagetext" => "Elenco completo delle categorie presenti sul sito.",
+"data" => "Dati",
+"userrights" => "Gestione dei permessi relativi agli utenti",
+"groups" => "Gruppi di utenti",
+
+"isbn" => 'ISBN',
+"alphaindexline" => "da $1 a $2",
+"version" => "Versione",
+"log" => "Log",
+"alllogstext" => "Presentazione unificata dei log relativi alle operazioni di caricamento, cancellazione, protezione, blocco e amministrazione del sito. Riempiendo gli appositi campi si può limitare la visualizzazione a uno specifico log, nome utente o pagina.",
+"logempty" => "Il log non contiene elementi corrispondenti alla ricerca.",
+
+# Special:Allpages
+"nextpage" => "Pagina successiva ($1)",
+"prevpage" => "Pagina precedente ($1)",
+"allpagesfrom" => "Mostra le pagine a partire da:",
+"allarticles" => "Tutte le voci",
+"allinnamespace" => "Tutte le pagine del namespace $1",
+"allnotinnamespace" => "Tutte le pagine, escluso il namespace $1",
+"allpagesprev" => "Precedenti",
+"allpagesnext" => "Successive",
+"allpagessubmit" => "Vai",
+"allpagesprefix" => "Mostra le pagine che iniziano con:",
+"allpagesbadtitle" => "Il titolo indicato per la pagina non è valido o contiene prefissi interlingua o interwiki. Potrebbe inoltre contenere uno o più caratteri il cui uso non è ammesso nei titoli.",
+
+# Special:Listusers
+"listusersfrom" => "Mostra gli utenti a partire da:",
+
+
+# Email this user
+#
+"mailnologin" => "Nessun indirizzo cui inviare il messaggio",
+"mailnologintext" => "Per inviare messaggi e-mail ad altri utenti è necessario [[Special:Userlogin|accedere al sito]] e aver registrato un indirizzo valido nelle proprie [[Special:Preferences|preferenze]].",
+"emailuser" => "Scrivi all'utente",
+"emailpage" => "Invia un messaggio e-mail all'utente",
+"emailpagetext" => "Se l'utente ha registrato un indirizzo e-mail valido nelle proprie preferenze, il modulo qui sotto consente di scrivere allo stesso un solo messaggio. L'indirizzo indicato nelle preferenze del mittente apparirà nel campo \"Da:\" del messaggio per consentire al destinatario l'eventuale risposta.",
+"usermailererror" => "L'oggetto mail ha restituito l'errore:",
+"defemailsubject" => "Messaggio da {{SITENAME}}",
+"noemailtitle" => "Nessun indirizzo e-mail",
+"noemailtext" => "Questo utente non ha indicato un indirizzo e-mail valido, oppure ha scelto di non ricevere messaggi di posta elettronica dagli altri utenti.",
+"emailfrom" => "Da",
+"emailto" => "A",
+"emailsubject" => "Oggetto",
+"emailmessage" => "Messaggio",
+"emailsend" => "Invia",
+"emailccme" => "Invia in copia al mio indirizzo.",
+"emailccsubject"=> "Copia del messaggio inviato a $1: $2",
+"emailsent" => "Messaggio inviato",
+"emailsenttext" => "Il messaggio e-mail è stato inviato.",
+
+# Watchlist
+
+"watchlist" => "Osservati speciali",
+"watchlistfor" => "(per '''$1''')",
+"nowatchlist" => "La lista degli osservati speciali è vuota.",
+"watchlistanontext" => "Per visualizzare e modificare l'elenco degli osservati speciali è necessario $1.",
+"watchlistcount" => "'''La lista degli osservati speciali contiene $1 elementi (comprese le pagine di discussione).'''",
+"clearwatchlist" => "Svuota la lista degli osservati speciali",
+"watchlistcleartext" => "Conferma la rimozione di tutti gli elementi.",
+"watchlistclearbutton" => "Svuota la lista",
+"watchlistcleardone" => "La lista degli osservati speciali è stata svuotata. Sono stati eliminati $1 elementi.",
+"watchnologin" => "Accesso non effettuato",
+"watchnologintext" => "Per modificare la lista degli osservati speciali è necessario prima eseguire l' [[Special:Userlogin|accesso al sito]].",
+"addedwatch" => "Pagina aggiunta alla lista degli osservati speciali",
+"addedwatchtext" => "La pagina \"[[:$1]]\" è stata aggiunta alla propria [[Special:Watchlist|lista degli osservati speciali]]. D'ora in poi, le modifiche apportate alla pagina e alla sua discussione verranno elencate in quella sede; il titolo della pagina apparirà in '''grassetto''' nella pagina delle [[Special:Recentchanges|ultime modifiche]] per renderlo più visibile.
+
+Se in un secondo tempo si desidera eliminare la pagina dalla lista degli osservati speciali, fare clic su \"non seguire\" nella barra in alto.",
+"removedwatch" => "Pagina eliminata dalla lista degli osservati speciali",
+"removedwatchtext" => "La pagina \"[[:$1]]\" è stata eliminata dalla lista degli osservati speciali.",
+"watch" => "Segui",
+"watchthispage" => "Segui questa pagina",
+"unwatch" => "Non seguire",
+"unwatchthispage" => "Smetti di seguire",
+"notanarticle" => "Questa pagina non è una voce",
+"watchnochange" => "Nessuna delle pagine osservate è stata modificata nel periodo considerato.",
+"watchdetails" => "* Nella lista degli osservati speciali ci sono $1 pagine (e le rispettive pagine di discussione).
+* [[Special:Watchlist/edit|Mostra e modifica la lista completa]] delle pagine osservate.
+* [[Special:Watchlist/clear|Svuota la lista]] delle pagine osservate.",
+"wlheader-enotif" => "* La notifica via e-mail è attiva.",
+"wlheader-showupdated" => "* Le pagine che sono state modificate dopo l'ultima visita sono evidenziate in '''grassetto'''",
+"watchmethod-recent" => "controllo delle modifiche recenti per gli osservati speciali",
+"watchmethod-list" => "controllo degli osservati speciali per modifiche recenti",
+"removechecked" => "Elimina elementi selezionati dalla lista",
+"watchlistcontains" => "La lista degli osservati speciali contiene $1 pagine.",
+"watcheditlist" => "Di seguito sono elencate tutte le pagine osservate, in ordine alfabetico. Selezionare le caselle relative alle pagine che si desidera eliminare dalla lista e fare clic sul pulsante 'Elimina elementi selezionati dalla lista' in fondo all'elenco per rimuoverle. Quando viene eliminata una pagina dalla lista, anche la corrispondente pagina di discussione cessa di essere osservata (e viceversa).",
+"removingchecked" => "Eliminazione degli elementi richiesti dalla lista degli osservati speciali...",
+"couldntremove" => "Non è possibile rimuovere la pagina '$1'...",
+"iteminvalidname" => "Problemi con la pagina '$1', nome non valido...",
+"wlnote" => "Di seguito sono elencate le ultime $1 modifiche, apportate nelle ultime <b>$2</b> ore.",
+"wlshowlast" => "Mostra le ultime $1 ore $2 giorni $3",
+"wlsaved" => "Questa è una versione salvata della lista personale delle pagine osservate.",
+"watchlist-show-bots" => "Mostra le modifiche dei bot",
+"watchlist-hide-bots" => "Nascondi le modifiche dei bot",
+"watchlist-show-own" => "Mostra le mie modifiche",
+"watchlist-hide-own" => "Nascondi le mie modifiche",
+"watchlist-show-minor" => "Mostra le modifiche minori",
+"watchlist-hide-minor" => "Nascondi le modifiche minori",
+"wldone" => "Fatto.",
+# Displayed when you click the "watch" button and it's in the process of watching
+"watching" => "Aggiunta agli osservati speciali...",
+"unwatching" => "Eliminazione dagli osservati speciali...",
+
+"enotif_mailer" => "Sistema di notifica via e-mail di {{SITENAME}}",
+"enotif_reset" => "Segna tutte le pagine come già visitate",
+"enotif_newpagetext" => "Questa è una nuova pagina.",
+"changed" => "modificata",
+"created" => "creata",
+"enotif_subject" => 'La pagina $PAGETITLE di {{SITENAME}} è stata $CHANGEDORCREATED da $PAGEEDITOR',
+"enotif_lastvisited" => "Consulta $1 per vedere tutte le modifiche dalla tua ultima visita.",
+"enotif_body" => 'Gentile $WATCHINGUSERNAME,
+
+la pagina $PAGETITLE di {{SITENAME}} è stata $CHANGEDORCREATED in data $PAGEEDITDATE da $PAGEEDITOR; la versione attuale si trova all\'indirizzo $PAGETITLE_URL.
+
+$NEWPAGE
+
+Riassunto della modifica, inserito dall\'autore: $PAGESUMMARY $PAGEMINOREDIT
+
+Contatta l\'autore della modifica:
+via e-mail: $PAGEEDITOR_EMAIL
+sul sito: $PAGEEDITOR_WIKI
+
+Non verranno inviate altre notifiche in caso di ulteriori cambiamenti, a meno che tu non visiti la pagina. Inoltre, è possibile reimpostare l\'avviso di notifica per tutte le pagine nella lista degli osservati speciali.
+
+ Il sistema di notifica di {{SITENAME}}, al tuo servizio
+
+--
+Per modificare le impostazioni della lista degli osservati speciali, visita
+{{fullurl:Special:Watchlist/edit}}
+
+Per dare il tuo feedback e ricevere ulteriore assistenza:
+{{fullurl:Help:Aiuto}}',
+
+# Delete/protect/revert
+#
+"deletepage" => "Cancella pagina",
+"confirm" => "Conferma",
+"excontent" => "il contenuto era: '$1'",
+"excontentauthor" => "il contenuto era: '$1' (e l'unico contributore era '$2')",
+"exbeforeblank" => "Il contenuto prima dello svuotamento era: '$1'",
+"exblank" => "la pagina era vuota",
+"confirmdelete" => "Conferma cancellazione",
+"deletesub" => "(Cancellazione di \"$1\")",
+"historywarning" => "Attenzione: La pagina che si sta per cancellare ha una cronologia:",
+"confirmdeletetext" => "Stai per cancellare permanentemente dal database una pagina o una immagine, insieme a tutta la sua cronologia. Per cortesia, conferma che è tua intenzione procedere a tale cancellazione, che hai piena consapevolezza delle conseguenze della tua azione e che essa è conforme alle linee guida stabilite in [[Project:Policy]].",
+"actioncomplete" => "Azione completata",
+"deletedtext" => "La pagina \"$1\" è stata cancellata. Consultare il $2 per un elenco delle pagine cancellate di recente.",
+"deletedarticle" => "ha cancellato \"[[$1]]\"",
+"dellogpage" => "Cancellazioni",
+"dellogpagetext" => "Di seguito sono elencate le pagine cancellate di recente.",
+"deletionlog" => "Log delle cancellazioni",
+"reverted" => "Ripristinata la versione precedente",
+"deletecomment" => "Motivo della cancellazione",
+"imagereverted" => "Versione precedente ripristinata correttamente.",
+"rollback" => "Annulla le modifiche",
+"rollback_short" => "Rollback",
+"rollbacklink" => "rollback",
+"rollbackfailed" => "Rollback non riuscito",
+"cantrollback" => "Impossibile annullare le modifiche; l'utente che le ha effettuate è l'unico ad aver contribuito alla pagina.",
+"alreadyrolled" => "Non è possibile annullare le modifiche apportate alla pagina [[:$1]] da parte di [[User:$2|$2]] ([[User talk:$2|discussione]]); un altro utente ha già modificato la pagina oppure ha effettuato il rollback.
+
+La modifica più recente alla pagina è stata apportata da [[User:$3|$3]] ([[User talk:$3|discussione]]).",
+"editcomment" => "Il commento alla modifica era: \"<i>$1</i>\".",
+"revertpage" => "Annullate le modifiche di [[Special:Contributions/$2|$2]] ([[User talk:$2|discussione]]), riportata alla versione precedente di [[User:$1|$1]]",
+"sessionfailure" => "Si è verificato un problema nella sessione che identifica l'accesso; il sistema non ha eseguito il comando impartito per precauzione. Tornare alla pagina precedente con il tasto 'Indietro' del proprio browser, ricaricare la pagina e riprovare.",
+"protectlogpage" => "Protezioni",
+"protectlogtext" => "Di seguito sono elencate le azioni di protezione e sblocco delle pagine.",
+"protectedarticle" => "ha protetto \"[[$1]]\"",
+"unprotectedarticle" => "ha sbloccato \"[[$1]]\"",
+"protectsub" => "(Protezione di \"$1\")",
+"confirmprotecttext" => "Proteggere questa pagina?",
+"confirmprotect" => "Conferma la protezione",
+"protectmoveonly" => "Proteggi solo dallo spostamento",
+"protectcomment" => "Motivo della protezione",
+"unprotectsub" => "(Sblocco di \"$1\")",
+"confirmunprotecttext" => "Sbloccare questa pagina?",
+"confirmunprotect" => "Conferma lo sblocco",
+"unprotectcomment" => "Motivo dello sblocco",
+"protect-unchain" => "Scollega i permessi di spostamento",
+"protect-text" => "Questo modulo consente di vedere e modificare il livello di protezione per la pagina <strong>$1</strong>.",
+"protect-viewtext" => "Questo account non ha le autorizzazioni necessarie per modificare il livello di protezione della pagina. Le impostazioni attuali per la pagina <strong>$1</strong> sono:",
+"protect-default" => "(predefinito)",
+"protect-level-autoconfirmed" => "Solo utenti registrati",
+"protect-level-sysop" => "Solo amministratori",
+
+# restrictions (nouns)
+"restriction-edit" => "Modifica",
+"restriction-move" => "Spostamento",
+
+# Undelete
+"undelete" => "Visualizza pagine cancellate",
+"undeletepage" => "Visualizza e recupera le pagine cancellate",
+"viewdeletedpage" => "Visualizza le pagine cancellate",
+"undeletepagetext" => "Le pagine indicate di seguito sono state cancellate, ma sono ancora in archivio e pertanto possono essere recuperate. L'archivio può essere svuotato periodicamente.",
+"undeleteextrahelp" => "Per recuperare l'intera pagina, lasciare tutte le caselle deselezionate e fare clic su '''''Ripristina'''''. Per effettuare un ripristino selettivo, selezionare le caselle corrispondenti alle revisioni da ripristinare e fare clic su '''''Ripristina'''''. Facendo clic su '''''Reset''''' verranno deselezionate tutte le caselle e svuotato lo spazio per il commento.",
+"undeletearticle" => "Recupera una pagina cancellata",
+"undeleterevisions" => "$1 revisioni in archivio",
+"undeleterevision-missing" => "Revisione errata o mancante. Il collegamento è errato oppure la revisione è stata già ripristinata o eliminata dall'archivio.",
+"undeletehistory" => "Recuperando questa pagina, tutte le sue revisioni verranno inserite di nuovo nella relativa cronologia. Se dopo la cancellazione è stata creata una nuova pagina con lo stesso titolo, le revisioni recuperate saranno inserite nella cronologia e la versione attualmente online della pagina non verrà modificata.",
+"undeletehistorynoadmin" => "La pagina è stata cancellata. Il motivo della cancellazione è indicato di seguito, assieme ai dati degli utenti che avevano modificato la pagina prima della cancellazione. Il testo contenuto nelle revisioni cancellate è disponibile solo agli amministratori.",
+"undeleterevision" => "Revisione cancellata, inserita il $1",
+"undeletebtn" => "Ripristina",
+"undeletereset" => "Reset",
+"undeletecomment" => "Commento:",
+"undeletedarticle" => "ha recuperato \"[[$1]]\"",
+"undeletedrevisions" => "$1 revisioni recuperate",
+"undeletedrevisions-files" => "$1 revisioni e $2 file recuperati",
+"undeletedfiles" => "$1 file recuperati",
+"cannotundelete" => "Ripristino non riuscito; è possibile che la pagina sia già stata recuperata da un altro utente.",
+"undeletedpage" => "<big>'''$1 è stata recuperata'''</big>
+
+Consultare il [[Special:Log/delete|log delle cancellazioni]] per vedere le cancellazioni e i recuperi più recenti.",
+
+# Namespace form on various pages
+"namespace" => "Namespace:",
+"invert" => "inverti la selezione",
+
+# Contributions
+#
+"contributions" => "Contributi utente",
+"mycontris" => "Miei contributi",
+"contribsub" => "Per $1",
+"nocontribs" => "Non sono state trovate modifiche che soddisfino i criteri di ricerca.",
+"ucnote" => "Di seguito sono elencate le <b>$1</b> modifiche più recenti effettuate dall'utente negli ultimi <b>$2</b> giorni.",
+"uclinks" => "Mostra le ultime $1 modifiche; mostra gli ultimi $2 giorni.",
+"uctop" => " (ultima per la pagina)" ,
+"newbies" => "nuovi utenti",
+
+"sp-newimages-showfrom" => "Mostra le immagini più recenti a partire da $1",
+
+"sp-contributions-newest" => "Ultimi",
+"sp-contributions-oldest" => "Primi",
+"sp-contributions-newer" => "$1 più recenti",
+"sp-contributions-older" => "$1 meno recenti",
+"sp-contributions-newbies-sub" => "Per i nuovi utenti",
+"sp-contributions-blocklog" => "Blocchi",
+
+# What links here
+#
+"whatlinkshere" => "Puntano qui",
+"notargettitle" => "Dati mancanti",
+"notargettext" => "Non è stata indicata una pagina o un utente in relazione al quale eseguire l'operazione richiesta.",
+"linklistsub" => "(Lista dei collegamenti)",
+"linkshere" => "Le seguenti pagine contengono dei collegamenti a '''[[:$1]]''':",
+"nolinkshere" => "Nessuna pagina contiene collegamenti che puntano a '''[[:$1]]'''.",
+"isredirect" => "redirect",
+"istemplate" => "inclusione",
+
+# Block/unblock IP
+#
+"blockip" => "Blocco utente",
+"blockiptext" => "Usare il modulo sottostante per bloccare l'accesso in scrittura ad uno specifico utente o indirizzo IP. Il blocco dev'essere operato per prevenire atti di vandalismo e in stretta osservanza della [[Project:Policy|policy di {{SITENAME}}]]. Specificare in dettaglio il motivo del blocco nel campo seguente (ad es. indicando i titoli delle pagine oggetto di vandalismo).",
+"ipaddress" => "Indirizzo IP",
+"ipadressorusername" => "Indirizzo IP o nome utente",
+"ipbexpiry" => "Scadenza del blocco",
+"ipbreason" => "Motivo del blocco",
+"ipbanononly" => "Blocca solo utenti anonimi",
+"ipbcreateaccount" => "Impedisci la creazione di altri account",
+"ipbenableautoblock" => "Blocca automaticamente l'ultimo indirizzo IP usato dall'utente e i successivi con cui vengono tentate modifiche",
+"ipbsubmit" => "Blocca l'utente",
+"ipbother" => "Durata non in elenco",
+"ipboptions" => "2 ore:2 hours,1 giorno:1 day,3 giorni:3 days,1 settimana:1 week,2 settimane:2 weeks,1 mese:1 month,3 mesi:3 months,6 mesi:6 months,1 anno:1 year,infinito:infinite",
+"ipbotheroption" => "altro",
+"badipaddress" => "Indirizzo IP non valido.",
+"blockipsuccesssub" => "Blocco eseguito",
+"blockipsuccesstext" => "[[Special:Contributions/$1|$1]] è stato bloccato.
+<br />Consultare la [[Special:Ipblocklist|lista degli IP bloccati]] per vedere i blocchi attivi.",
+"unblockip" => " Sblocca utente",
+"unblockiptext" => "Usare il modulo sottostante per restituire l'accesso in scrittura ad un utente o indirizzo IP bloccato.",
+"ipusubmit" => "Sblocca l'utente",
+"unblocked" => "L'utente [[User:$1|$1]] è stato sbloccato",
+"ipblocklist" => "Lista degli utenti e indirizzi IP bloccati",
+"blocklistline" => "$1, $2 ha bloccato $3 ($4)",
+"infiniteblock" => "senza scadenza",
+"expiringblock" => "fino al $1",
+"anononlyblock" => "solo utenti anonimi",
+"noautoblockblock" => "blocco automatico disattivato",
+"createaccountblock" => "creazione account bloccata",
+"ipblocklistempty" => "La lista dei blocchi è vuota.",
+"blocklink" => "blocca",
+"unblocklink" => "sblocca",
+"contribslink" => "contributi",
+"autoblocker" => "Bloccato automaticamente perché l'indirizzo IP è condiviso con l'utente \"[[User:$1|$1]]\". Il blocco dell'utente $1 è stato imposto per il seguente motivo: \"'''$2'''\".",
+"blocklogpage" => "Blocchi",
+"blocklogentry" => "ha bloccato \"[[$1]]\" per un periodo di $2",
+"blocklogtext" => "Questo è l'elenco delle azioni di blocco e sblocco utenti. Gli indirizzi IP bloccati automaticamente non sono elencati. Consultare l'[[Special:Ipblocklist|elenco IP bloccati]] per l'elenco degli indirizzi e nomi utente il cui blocco è operativo.",
+"unblocklogentry" => "ha sbloccato $1",
+"range_block_disabled" => "La possibilità di bloccare intervalli di indirizzi IP non è attiva al momento.",
+"ipb_expiry_invalid" => "Durata o scadenza del blocco non valida.",
+"ipb_already_blocked" => "L'utente \"$1\" è già bloccato",
+"ip_range_invalid" => "Intervallo di indirizzi IP non valido.",
+"proxyblocker" => "Blocco dei proxy aperti",
+"ipb_cant_unblock" => "Errore: Impossibile trovare il blocco con ID $1. Il blocco potrebbe essere già stato rimosso.",
+"proxyblockreason" => "Questo indirizzo IP è stato bloccato perché è risulta essere un proxy aperto. Si prega di contattare il proprio fornitore di accesso a Internet o il supporto tecnico e informarli di questo grave problema di sicurezza.",
+"proxyblocksuccess" => "Blocco eseguito.",
+"sorbs" => "SORBS DNSBL",
+"sorbsreason" => "Questo indirizzo IP è elencato come proxy aperto nella blacklist DNSBL di [http://www.sorbs.net SORBS].",
+"sorbs_create_account_reason" => "Non è possibile creare nuovi accessi da questo indirizzo IP perché è elencato come proxy aperto nella blacklist DNSBL di [http://www.sorbs.net SORBS].",
+
+# Developer tools
+#
+"lockdb" => "Blocca il database",
+"unlockdb" => "Sblocca il database",
+"lockdbtext" => "Il blocco del database comporta l'interruzione, per tutti gli utenti, della possibilità di modificare le pagine o di crearne di nuove, di cambiare le preferenze e modificare le liste degli osservati speciali, e in generale di tutte le operazioni che richiedono modifiche al database. Per cortesia, conferma che ciò corrisponde effettivamente all'azione da te richiesta e che al termine della manutenzione provvederai allo sblocco del database.",
+"unlockdbtext" => "Lo sblocco del database consente di nuovo a tutti gli utenti di modificare le pagine o di crearne di nuove, di cambiare le preferenze e modificare le liste degli osservati speciali, e in generale di compiere tutte le operazioni che richiedono modifiche al database. Per cortesia, conferma che ciò corrisponde effettivamente all'azione da te richiesta.",
+"lockconfirm" => "Sì, intendo effettivamente bloccare il database.",
+"unlockconfirm" => "Sì, intendo effettivamente sbloccare il database.",
+"lockbtn" => "Blocca il database",
+"unlockbtn" => "Sblocca il database",
+"locknoconfirm" => "Non è stata spuntata la casellina di conferma.",
+"lockdbsuccesssub" => "Blocco del database eseguito",
+"unlockdbsuccesssub" => "Sblocco del database eseguito",
+"lockdbsuccesstext" => "Il database è stato bloccato.
+<br />Ricorda di rimuovere il blocco dopo aver terminato le operazioni di manutenzione.",
+"unlockdbsuccesstext" => " Il database è stato sbloccato.",
+"lockfilenotwritable" => "Impossibile scrivere sul file di ''lock'' del database. L'accesso in scrittura a tale file da parte del server web è necessario per bloccare e sbloccare il database.",
+"databasenotlocked" => "Il database non è bloccato.",
+
+# Make sysop
+"makesysoptitle" => "Rendi amministratore un utente",
+"makesysoptext" => "Questo form può essere usato dai burocrati per far diventare amministratori gli utenti che non lo sono. Scrivere il nome dell'utente nella casella e premere il pulsante per farlo diventare amministratore.",
+"makesysopname" => "Nome dell'utente:",
+"makesysopsubmit" => "Rendi l'utente amministratore",
+"makesysopok" => "<b>L'utente \"$1\" è ora amministratore</b>",
+"makesysopfail" => "<b>Impossibile far diventare amministratore l'utente \"$1\". Verificare che il nome utente sia stato scritto correttamente.</b>",
+"setbureaucratflag" => "Assegna i diritti di burocrate",
+"rightslog" => "Diritti degli utenti",
+"rightslogtext" => "Questo è il log delle modifiche ai diritti assegnati agli utenti.",
+"rightslogentry" => "ha modificato l'appartenenza di $1 dal gruppo $2 al gruppo $3",
+"rights" => "Diritti:",
+"set_user_rights" => "Imposta diritti utente",
+"user_rights_set" => "<b>I diritti utente per \"$1\" sono stati aggiornati</b>",
+"set_rights_fail" => "<b>Impossibile aggiornare i diritti utente per \"$1\". Verificare che il nome utente sia stato scritto correttamente.</b>",
+"makesysop" => "Rendi l'utente amministratore",
+"already_sysop" => "Questo utente è già amministratore",
+"already_bureaucrat" => "Questo utente è già burocrate",
+"rightsnone" => "(nessuno)",
+
+# Move page
+#
+"movepage" => "Spostamento di pagina",
+"movepagetext" => "Questo modulo consente di rinominare una pagina, spostando tutta la sua cronologia al nuovo nome. La pagina attuale diverrà automaticamente un redirect al nuovo titolo. I collegamenti esistenti non saranno aggiornati; verificare che lo spostamento non abbia creato doppi redirect o redirect errati. L'onere di garantire che i collegamenti alla pagina restino corretti spetta a chi la sposta.
+
+Si noti che la pagina '''non''' sarà spostata se ne esiste già una con il nuovo nome, a meno che non sia vuota o costituita solo da un redirect alla vecchia e sia priva di versioni precedenti. In caso di spostamento errato si può quindi tornare subito al vecchio titolo, e non è possibile sovrascrivere per errore una pagina già esistente.
+
+<b>ATTENZIONE:</b>
+Un cambiamento così drastico può creare contrattempi e problemi, soprattutto per le pagine più visitate. Accertarsi di aver valutato le conseguenze dello spostamento prima di procedere.",
+"movepagetalktext" => "La corrispondente pagina di discussione sarà spostata automaticamente insieme alla pagina principale, '''tranne che nei seguenti casi:'''
+* Lo spostamento della pagina è tra namespace diversi
+* In corrispondenza del nuovo titolo esiste già una pagina di discussione (non vuota)
+* La casella qui sotto è stata deselezionata.
+
+In questi casi, se lo si ritiene opportuno, occorre spostare o aggiungere manualmente le informazioni contenute nella pagina di discussione.",
+"movearticle" => "Sposta la pagina",
+"movenologin" => "Accesso non effettuato",
+"movenologintext" => "Lo spostamento delle pagine è consentito solo agli utenti registrati che hanno eseguito l'[[Special:Userlogin|accesso]] al sito.",
+"newtitle" => "Nuovo titolo:",
+"move-watch" => "Aggiungi agli osservati speciali",
+"movepagebtn" => "Sposta la pagina",
+"pagemovedsub" => "Spostamento effettuato con successo",
+"pagemovedtext" => "La pagina \"[[$1]]\" è stata spostata al titolo \"[[$2]]\".",
+"articleexists" => "Una pagina con questo nome esiste già, oppure il nome scelto non è valido. Scegliere un altro titolo.",
+"talkexists" => "'''La pagina è stata spostata correttamente, ma non è stato possibile spostare la pagina di discussione perché ne esiste già un'altra con il nuovo titolo. Integrare manualmente i contenuti delle due pagine.'''",
+"movedto" => "spostata a",
+"movetalk" => "Sposta anche la pagina di discussione.",
+"talkpagemoved" => "Anche la rispettiva pagina di discussione è stata spostata.",
+"talkpagenotmoved" => "La rispettiva pagina di discussione <strong>non</strong> è stata spostata.",
+"1movedto2" => "ha spostato [[$1]] a [[$2]]",
+"1movedto2_redir" => "[[$1]] spostata a [[$2]] tramite redirect",
+"movelogpage" => "Spostamenti",
+"movelogpagetext" => "Questo è l'elenco delle pagine spostate.",
+"movereason" => "Motivo",
+"revertmove" => "ripristina",
+"delete_and_move" => "Cancella e sposta",
+"delete_and_move_text" => "==Richiesta di cancellazione==
+
+La pagina di destinazione [[$1]] esiste già. Si desidera cancellarla per rendere possibile lo spostamento?",
+"delete_and_move_confirm" => "Sì, sovrascrivi la pagina esistente",
+"delete_and_move_reason" => "Cancellata per rendere possibile lo spostamento",
+"selfmove" => "Il nuovo titolo è uguale al vecchio; impossibile spostare la pagina su se stessa.",
+"immobile_namespace" => "Il nuovo titolo corrisponde a una pagina speciale; impossibile spostare pagine in quel namespace.",
+
+# Export
+"export" => "Esporta pagine",
+"exporttext" => "È possibile esportare il testo e la cronologia delle modifiche di una pagina o di un gruppo di pagine in formato XML per importarle in altri siti che utilizzano il software MediaWiki, attraverso la pagina Special:Import.
+
+Per esportare le pagine indicare i titoli nella casella di testo sottostante, uno per riga, e specificare se si desidera ottenere la versione corrente e tutte le versioni precedenti, con i dati della cronologia della pagina, oppure soltanto l'ultima versione e i dati corrispondenti all'ultima modifica.
+
+In quest'ultimo caso si può anche utilizzare un collegamento, ad esempio [[Special:Export/{{Mediawiki:mainpage}}]] per esportare {{Mediawiki:mainpage}}.",
+"exportcuronly" => "Includi solo la revisione attuale, non l'intera cronologia",
+"exportnohistory" => "----
+'''Nota:''' l'esportazione dell'intera cronologia delle pagine attraverso questa interfaccia è stata disattivata per motivi legati alle prestazioni del sistema.",
+"export-submit" => "Esporta",
+
+# Namespace 8 related
+
+"allmessages" => "Messaggi di sistema",
+"allmessagesname" => "Nome",
+"allmessagesdefault" => "Testo predefinito",
+"allmessagescurrent" => "Testo attuale",
+"allmessagestext" => "Questa è la lista di tutti i messaggi di sistema disponibili nel namespace MediaWiki:",
+"allmessagesnotsupportedUI" => "La lingua selezionata per l'interfaccia, <b>$1</b>, non è supportata da Special:Allmessages su questo sito.",
+"allmessagesnotsupportedDB" => "'''Special:Allmessages''' non è supportato perché il flag '''\$wgUseDatabaseMessages''' non è attivo.",
+"allmessagesfilter" => "Filtro sui messaggi:",
+"allmessagesmodified" => "Mostra solo quelli modificati",
+
+
+# Thumbnails
+
+"thumbnail-more" => "Ingrandisci",
+"missingimage" => "<b>Immagine mancante</b><br /><i>$1</i>",
+"filemissing" => "File mancante",
+"thumbnail_error" => "Errore nella creazione della miniatura: $1",
+
+# Special:Import
+"import" => "Importa pagine",
+"importinterwiki" => "Importazione transwiki",
+"import-interwiki-text" => "Selezionare un progetto wiki e il titolo della pagina da importare.
+Le date di pubblicazione e i nomi degli autori delle varie versioni saranno conservati.
+Tutte le operazioni di importazione trans-wiki sono registrate nel [[Special:Log/import|log di importazione]].",
+"import-interwiki-history" => "Copia l'intera cronologia di questa pagina",
+"import-interwiki-submit" => "Importa",
+"import-interwiki-namespace" => "Trasferisci le pagine nel namespace:",
+"importtext" => "Si prega di esportare il file dal sito wiki di origine con la funzione Special:Export, salvarlo sul proprio disco e poi caricarlo qui.",
+"importstart" => "Importazione delle pagine in corso...",
+"import-revision-count" => "{{PLURAL:$1|una revisione importata|$1 revisioni importate}}",
+"importnopages" => "Nessuna pagina da importare.",
+"importfailed" => "Importazione non riuscita: $1",
+"importunknownsource" => "Tipo di origine sconosciuto per l'importazione",
+"importcantopen" => "Impossibile aprire il file di importazione",
+"importbadinterwiki" => "Collegamento inter-wiki errato",
+"importnotext" => "Testo vuoto o mancante",
+"importsuccess" => "Importazione riuscita.",
+"importhistoryconflict" => "La cronologia contiene delle versioni in conflitto (questa pagina potrebbe essere già stata importata)",
+"importnosources" => "Non è stata definita una fonte per l'importazione transwiki; l'importazione diretta della cronologia non è attiva.",
+"importnofile" => "Non è stato caricato nessun file per l'importazione,",
+"importuploaderror" => "Caricamento del file per l'importazione non riuscita; è possibile che il file sia di dimensioni superiori a quelle ammesse per gli upload.",
+
+# import log
+"importlogpage" => "Importazioni",
+"importlogpagetext" => "Registro delle importazioni d'ufficio di pagine provenienti da altre wiki, complete di cronologia.",
+"import-logentry-upload" => "ha importato [[$1]] tramite upload",
+"import-logentry-upload-detail" => "{{PLURAL:$1|una revisione importata|$1 revisioni importate}}",
+"import-logentry-interwiki" => "ha trasferito da altra wiki la pagina $1",
+"import-logentry-interwiki-detail" => "{{PLURAL:$1|una revisione importata|$1 revisioni importate}} da $2",
+
+# Keyboard access keys for power users
+"accesskey-search" => "f",
+"accesskey-minoredit" => "i",
+"accesskey-save" => "s",
+"accesskey-preview" => "p",
+"accesskey-diff" => "v",
+"accesskey-compareselectedversions" => "v",
+"accesskey-watch" => "w",
+
+# tooltip help for some actions, most are in Monobook.js
+"tooltip-search" => "Cerca in {{SITENAME}} [alt-f]",
+"tooltip-minoredit" => "Segnala come modifica minore [alt-i]",
+"tooltip-save" => "Salva le modifiche [alt-s]",
+"tooltip-preview" => "Anteprima delle modifiche (consigliata, prima di salvare!) [alt-p]",
+"tooltip-diff" => "Guarda le modifiche apportate al testo. [alt-v]",
+"tooltip-compareselectedversions" => "Guarda le differenze tra le due versioni selezionate di questa pagina. [alt-v]",
+"tooltip-watch" => "Aggiungi questa pagina alla lista degli osservati speciali [alt-w]",
+
+# stylesheets
+"Common.css" => "/* Gli stili CSS inseriti qui si applicano a tutte le skin */",
+"monobook.css" => "/* Gli stili CSS inseriti qui si applicano agli utenti che usano la skin Monobook */",
+
+# Metadata
+"nodublincore" => "Metadati Dublin Core RDF non attivi su questo server.",
+"nocreativecommons" => "Metadati Commons RDF non attivi su questo server.",
+"notacceptable" => "Il server wiki non è in grado di fornire i dati in un formato leggibile dal client utilizzato.",
+
+# Attribution
+"anonymous" => "uno o più utenti anonimi di {{SITENAME}}",
+"siteuser" => "$1, utente di {{SITENAME}}",
+"lastmodifiedatby" => "Questa pagina è stata modificata per l'ultima volta il $2, $1 da $3.",
+"and" => "e",
+"othercontribs" => "Il testo attuale è basato su contributi di $1.",
+"others" => "altri",
+"siteusers" => "$1, utenti di {{SITENAME}}",
+"creditspage" => "Autori della pagina",
+"nocredits" => "Nessuna informazione sugli autori disponibile per questa pagina.",
+
+# Spam protection
+"spamprotectiontitle" => "Filtro anti-spam",
+"spamprotectiontext" => "La pagina che si è tentato di salvare è stata bloccata dal filtro anti-spam. Ciò è probabilmente dovuto alla presenza di un collegamento a un sito esterno bloccato.",
+"spamprotectionmatch" => "Il filtro anti-spam è stato attivato dal seguente testo: $1",
+"subcategorycount" => "Questa categoria contiene {{PLURAL:$1|una sottocategoria|$1 sottocategorie}}.",
+"categoryarticlecount" => "Questa categoria contiene {{PLURAL:$1|una pagina|$1 pagine}}.",
+"category-media-count" => "Questa categoria contiene {{PLURAL:$1|un file|$1 file}}.",
+"listingcontinuesabbrev" => " cont.",
+"spambot_username" => "MediaWiki - sistema di rimozione spam",
+"spam_reverting" => "Ripristinata l'ultima versione priva di collegamenti a $1",
+"spam_blanking" => "Pagina svuotata, tutte le versioni contenevano collegamenti a $1",
+
+# Info page
+"infosubtitle" => "Informazioni per la pagina",
+"numedits" => "Numero di modifiche (pagina): $1",
+"numtalkedits" => "Numero di modifiche (pagina di discussione): $1",
+"numwatchers" => "Numero di osservatori: $1",
+"numauthors" => "Numero di autori distinti (pagina): $1",
+"numtalkauthors" => "Numero di autori distinti (pagina di discussione): $1",
+
+# Math options
+"mw_math_png" => "Mostra sempre in PNG",
+"mw_math_simple" => "HTML se molto semplice, altrimenti PNG",
+"mw_math_html" => "HTML se possibile, altrimenti PNG",
+"mw_math_source" => "Lascia in formato TeX (per browser testuali)",
+"mw_math_modern" => "Formato consigliato per i browser moderni",
+"mw_math_mathml" => "Usa MathML se possibile (sperimentale)",
+
+# Patrolling
+"markaspatrolleddiff" => "Segna la modifica come verificata",
+"markaspatrolledtext" => "Segna questa voce come verificata",
+"markedaspatrolled" => "Segnato come verificato",
+"markedaspatrolledtext" => "La revisione selezionata è stata segnata come verificata.",
+"rcpatroldisabled" => "La verifica delle ultime modifiche è disattivata",
+"rcpatroldisabledtext" => "La funzione di verifica delle ultime modifiche al momento non è attiva.",
+"markedaspatrollederror" => "Impossibile contrassegnare la voce come verificata",
+"markedaspatrollederrortext" => "Occorre specificare una revisione da contrassegnare come verificata.",
+"markedaspatrollederror-noautopatrol" => "Non si dispone dei permessi necessari per segnare le proprie modifiche come verificate.",
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'La tua pagina utente\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'La pagina utente di questo indirizzo IP\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'La tua pagina di discussione\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussioni sulle modifiche fatte da questo indirizzo IP\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Le tue preferenze\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'La lista delle pagine che stai tenendo sotto osservazione\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'L\\\'elenco dei tuoi contributi\');
+ ta[\'pt-login\'] = new Array(\'o\',\'La registrazione è consigliata, anche se non obbligatoria\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'La registrazione è consigliata, anche se non obbligatoria\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Uscita (logout)\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Vedi le discussioni relative a questa pagina\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Puoi modificare questa pagina. Per favore usa il pulsante di anteprima prima di salvare\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Aggiungi un commento a questa discussione\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Questa pagina è protetta, ma puoi vedere il suo codice sorgente\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Versioni precedenti di questa pagina\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Proteggi questa pagina\');
+ ta[\'ca-unprotect\'] = new Array(\'=\',\'Sblocca questa pagina\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Cancella questa pagina\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Ripristina la pagina com\\\'era prima della cancellazione\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Sposta questa pagina (cambia titolo)\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Aggiungi questa pagina alla tua lista di osservati speciali\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Elimina questa pagina dalla tua lista di osservati speciali\');
+ ta[\'search\'] = new Array(\'f\',\'Cerca all\\\'interno del sito\');
+ ta[\'p-logo\'] = new Array(\'\',\'Pagina principale\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Visita la pagina principale\');
+ ta[\'n-portal\'] = new Array(\'\',\'Descrizione del progetto, cosa puoi fare, dove trovare le cose\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Informazioni sugli eventi di attualità\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Elenco delle ultime modifiche del sito\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Mostra una pagina a caso\');
+ ta[\'n-help\'] = new Array(\'a\',\'Pagine di aiuto\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Aiutaci\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Elenco di tutte le pagine che sono collegate a questa\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Elenco delle ultime modifiche alle pagine collegate a questa\');
+ ta[\'feed-rss\'] = new Array(\'\',\'Feed RSS per questa pagina\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Feed Atom per questa pagina\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Lista dei contributi di questo utente\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Invia un messaggio e-mail a questo utente\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Carica immagini o file multimediali\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lista di tutte le pagine speciali\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vedi la voce\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vedi la pagina utente\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Vedi la pagina del file multimediale\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Questa è una pagina speciale, non può essere modificata\');
+ ta[\'ca-nstab-project\'] = new Array(\'c\',\'Vedi la pagina di servizio\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Vedi la pagina dell\\\'immagine\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vedi il messaggio di sistema\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vedi il template\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vedi la pagina di aiuto\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vedi la pagina della categoria\');',
+
+# Common.js: contains nothing but a placeholder comment
+"common.js" => "/* Questo codice JavaScript viene caricato da ciascuna pagina, per tutti gli utenti. */",
+
+# image deletion
+"deletedrevision" => "Revisione precedente, cancellata: $1.",
+
+# browsing diffs
+"previousdiff" => "← Differenza precedente",
+"nextdiff" => "Differenza successiva →",
+
+"imagemaxsize" => "Dimensione massima delle immagini sulle relative pagine di discussione:",
+"thumbsize" => "Grandezza delle miniature:",
+"showbigimage" => "Scarica la versione ad alta risoluzione ($1x$2, $3 KB)",
+
+"newimages" => "Galleria dei nuovi file",
+"showhidebots" => "($1 i bot)",
+"noimages" => "Non c'è nulla da vedere.",
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+
+# Not translated
+
+# variants for Serbian language
+
+# Not translated
+
+# labels for User: and Title: on Special:Log pages
+"specialloguserlabel" => "Utente:",
+"speciallogtitlelabel" => "Titolo:",
+
+"passwordtooshort" => "La password inserita è troppo breve. Deve contenere almeno $1 caratteri.",
+
+# Media Warning
+"mediawarning" => "'''Attenzione''': Questo file può contenere codice maligno; la sua esecuzione può danneggiare il proprio sistema informatico.
+
+<hr />",
+
+"fileinfo" => "Dimensioni: $1 KB, Tipo MIME: <code>$2</code>",
+
+# Metadata
+"metadata" => "Metadati",
+"metadata-help" => "Questo file contiene informazioni aggiuntive, probabilmente aggiunte dalla fotocamera o dallo scanner usati per crearla o digitalizzarla. Se il file è stato modificato, alcuni dettagli potrebbero non corrispondere alle modifiche apportate.",
+"metadata-expand" => "Mostra dettagli",
+"metadata-collapse" => "Nascondi dettagli",
+"metadata-fields" => "I campi relativi ai metadati EXIF elencati in questo messaggio verranno mostrati sulla pagina dell'immagine quando la tabella dei metadati è presentata nella forma breve. Per impostazione predefinita, gli altri campi verranno nascosti.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength",
+
+# Exif tags
+"exif-imagewidth" => "Larghezza",
+"exif-imagelength" => "Altezza",
+"exif-bitspersample" => "Bit per campione",
+"exif-compression" => "Meccanismo di compressione",
+"exif-photometricinterpretation" => "Struttura dei pixel",
+"exif-orientation" => "Orientamento",
+"exif-samplesperpixel" => "Numero delle componenti",
+"exif-planarconfiguration" => "Disposizione dei dati",
+"exif-ycbcrsubsampling" => "Rapporto di campionamento Y / C",
+"exif-ycbcrpositioning" => "Posizionamento componenti Y e C",
+"exif-xresolution" => "Risoluzione orizzontale",
+"exif-yresolution" => "Risoluzione verticale",
+"exif-resolutionunit" => "Unità di misura risoluzione X e Y",
+"exif-stripoffsets" => "Posizione dei dati immagine",
+"exif-rowsperstrip" => "Numero righe per striscia",
+"exif-stripbytecounts" => "Numero di byte per striscia compressa",
+"exif-jpeginterchangeformat" => "Posizione byte SOI JPEG",
+"exif-jpeginterchangeformatlength" => "Numero di byte di dati JPEG",
+"exif-transferfunction" => "Funzione di trasferimento",
+"exif-whitepoint" => "Coordinate cromatiche del punto di bianco",
+"exif-primarychromaticities" => "Coordinate cromatiche dei colori primari",
+"exif-ycbcrcoefficients" => "Coefficienti matrice di trasformazione spazi dei colori",
+"exif-referenceblackwhite" => "Coppia di valori di riferimento (nero e bianco)",
+"exif-datetime" => "Data e ora di modifica del file",
+"exif-imagedescription" => "Descrizione dell'immagine",
+"exif-make" => "Produttore fotocamera",
+"exif-model" => "Modello fotocamera",
+"exif-software" => "Software",
+"exif-artist" => "Autore",
+"exif-copyright" => "Informazioni sul copyright",
+"exif-exifversion" => "Versione del formato Exif",
+"exif-flashpixversion" => "Versione Flashpix supportata",
+"exif-colorspace" => "Spazio dei colori",
+"exif-componentsconfiguration" => "Significato di ciascuna componente",
+"exif-compressedbitsperpixel" => "Modalità di compressione immagine",
+"exif-pixelydimension" => "Larghezza effettiva immagine",
+"exif-pixelxdimension" => "Altezza effettiva immagine",
+"exif-makernote" => "Note del produttore",
+"exif-usercomment" => "Note dell'utente",
+"exif-relatedsoundfile" => "File audio collegato",
+"exif-datetimeoriginal" => "Data e ora di creazione dei dati",
+"exif-datetimedigitized" => "Data e ora di digitalizzazione",
+"exif-subsectime" => "Data e ora, frazioni di secondo",
+"exif-subsectimeoriginal" => "Data e ora di creazione, frazioni di secondo",
+"exif-subsectimedigitized" => "Data e ora di digitalizzazione, frazioni di secondo",
+"exif-exposuretime" => "Tempo di esposizione",
+"exif-exposuretime-format" => "$1 s ($2)",
+"exif-fnumber" => "Rapporto focale",
+"exif-fnumber-format" => "f/$1",
+"exif-exposureprogram" => "Programma di esposizione",
+"exif-spectralsensitivity" => "Sensibilità spettrale",
+"exif-isospeedratings" => "Sensibilità ISO",
+"exif-oecf" => "Fattore di conversione optoelettronica",
+"exif-shutterspeedvalue" => "Tempo di esposizione",
+"exif-aperturevalue" => "Apertura",
+"exif-brightnessvalue" => "Luminosità",
+"exif-exposurebiasvalue" => "Correzione esposizione",
+"exif-maxaperturevalue" => "Apertura massima",
+"exif-subjectdistance" => "Distanza del soggetto",
+"exif-meteringmode" => "Metodo di misurazione",
+"exif-lightsource" => "Sorgente luminosa",
+"exif-flash" => "Caratteristiche e stato del flash",
+"exif-focallength" => "Distanza focale obiettivo",
+"exif-focallength-format" => "$1 mm",
+"exif-subjectarea" => "Area inquadrante il soggetto",
+"exif-flashenergy" => "Potenza del flash",
+"exif-spatialfrequencyresponse" => "Risposta in frequenza spaziale",
+"exif-focalplanexresolution" => "Risoluzione X sul piano focale",
+"exif-focalplaneyresolution" => "Risoluzione Y sul piano focale",
+"exif-focalplaneresolutionunit" => "Unità di misura risoluzione sul piano focale",
+"exif-subjectlocation" => "Posizione del soggetto",
+"exif-exposureindex" => "Sensibilità impostata",
+"exif-sensingmethod" => "Metodo di rilevazione",
+"exif-filesource" => "Origine del file",
+"exif-scenetype" => "Tipo di inquadratura",
+"exif-cfapattern" => "Disposizione filtro colore",
+"exif-customrendered" => "Elaborazione personalizzata",
+"exif-exposuremode" => "Modalità di esposizione",
+"exif-whitebalance" => "Bilanciamento del bianco",
+"exif-digitalzoomratio" => "Rapporto zoom digitale",
+"exif-focallengthin35mmfilm" => "Focale equivalente su 35 mm",
+"exif-scenecapturetype" => "Tipo di acquisizione",
+"exif-gaincontrol" => "Controllo inquadratura",
+"exif-contrast" => "Controllo contrasto",
+"exif-saturation" => "Controllo saturazione",
+"exif-sharpness" => "Controllo nitidezza",
+"exif-devicesettingdescription" => "Descrizione impostazioni dispositivo",
+"exif-subjectdistancerange" => "Scala distanza soggetto",
+"exif-imageuniqueid" => "ID univoco immagine",
+"exif-gpsversionid" => "Versione dei tag GPS",
+"exif-gpslatituderef" => "Latitudine Nord/Sud",
+"exif-gpslatitude" => "Latitudine",
+"exif-gpslongituderef" => "Longitudine Est/Ovest",
+"exif-gpslongitude" => "Longitudine",
+"exif-gpsaltituderef" => "Riferimento per l'altitudine",
+"exif-gpsaltitude" => "Altitudine",
+"exif-gpstimestamp" => "Ora GPS (orologio atomico)",
+"exif-gpssatellites" => "Satelliti usati per la misurazione",
+"exif-gpsstatus" => "Stato del ricevitore",
+"exif-gpsmeasuremode" => "Modalità di misurazione",
+"exif-gpsdop" => "Precisione della misurazione",
+"exif-gpsspeedref" => "Unità di misura della velocità",
+"exif-gpsspeed" => "Velocità del ricevitore GPS",
+"exif-gpstrackref" => "Riferimento per la direzione movimento",
+"exif-gpstrack" => "Direzione del movimento",
+"exif-gpsimgdirectionref" => "Riferimento per la direzione dell'immagine",
+"exif-gpsimgdirection" => "Direzione dell'immagine",
+"exif-gpsmapdatum" => "Rilevamento geodetico usato",
+"exif-gpsdestlatituderef" => "Riferimento per la latitudine della destinazione",
+"exif-gpsdestlatitude" => "Latitudine della destinazione",
+"exif-gpsdestlongituderef" => "Riferimento per la longitudine della destinazione",
+"exif-gpsdestlongitude" => "Longitudine della destinazione",
+"exif-gpsdestbearingref" => "Riferimento per la direzione della destinazione",
+"exif-gpsdestbearing" => "Direzione della destinazione",
+"exif-gpsdestdistanceref" => "Riferimento per la distanza della destinazione",
+"exif-gpsdestdistance" => "Distanza della destinazione",
+"exif-gpsprocessingmethod" => "Nome del metodo di elaborazione GPS",
+"exif-gpsareainformation" => "Nome della zona GPS",
+"exif-gpsdatestamp" => "Data GPS",
+"exif-gpsdifferential" => "Correzione differenziale GPS",
+
+
+# Exif attributes
+
+"exif-compression-1" => "Nessuno",
+"exif-compression-6" => "JPEG",
+
+"exif-unknowndate" => "Data sconosciuta",
+
+"exif-photometricinterpretation-2" => "RGB",
+"exif-photometricinterpretation-6" => "YCbCr",
+
+"exif-orientation-1" => "Normale",
+"exif-orientation-2" => "Capovolto orizzontalmente",
+"exif-orientation-3" => "Ruotato di 180°",
+"exif-orientation-4" => "Capovolto verticalmente",
+"exif-orientation-5" => "Ruotato 90° in senso antiorario e capovolto verticalmente",
+"exif-orientation-6" => "Ruotato 90° in senso orario",
+"exif-orientation-7" => "Ruotato 90° in senso orario e capovolto verticalmente",
+"exif-orientation-8" => "Ruotato 90° in senso antiorario",
+
+"exif-planarconfiguration-1" => "a blocchi (chunky)",
+"exif-planarconfiguration-2" => "lineare (planar)",
+
+"exif-xyresolution-i" => "$1 punti per pollice (dpi)",
+"exif-xyresolution-c" => "$1 punti per centimetro (dpc)",
+
+"exif-colorspace-1" => "sRGB",
+"exif-colorspace-ffff.h" => "Non calibrato",
+
+"exif-componentsconfiguration-0" => "assente",
+"exif-componentsconfiguration-1" => "Y",
+"exif-componentsconfiguration-2" => "Cb",
+"exif-componentsconfiguration-3" => "Cr",
+"exif-componentsconfiguration-4" => "R",
+"exif-componentsconfiguration-5" => "G",
+"exif-componentsconfiguration-6" => "B",
+
+
+"exif-exposureprogram-0" => "Non definito",
+"exif-exposureprogram-1" => "Manuale",
+"exif-exposureprogram-2" => "Standard",
+"exif-exposureprogram-3" => "Priorità al diaframma",
+"exif-exposureprogram-4" => "Priorità all'esposizione",
+"exif-exposureprogram-5" => "Artistico (orientato alla profondità di campo)",
+"exif-exposureprogram-6" => "Sportivo (orientato alla velocità di ripresa)",
+"exif-exposureprogram-7" => "Ritratto (soggetti vicini con sfondo fuori fuoco)",
+"exif-exposureprogram-8" => "Panorama (soggetti lontani con sfondo a fuoco)",
+
+"exif-subjectdistance-value" => "$1 metri",
+
+"exif-meteringmode-0" => "Sconosciuto",
+"exif-meteringmode-1" => "Media",
+"exif-meteringmode-2" => "Media pesata centrata",
+"exif-meteringmode-3" => "Spot",
+"exif-meteringmode-4" => "MultiSpot",
+"exif-meteringmode-5" => "Pattern",
+"exif-meteringmode-6" => "Parziale",
+"exif-meteringmode-255" => "Altro",
+
+"exif-lightsource-0" => "Sconosciuta",
+"exif-lightsource-1" => "Luce diurna",
+"exif-lightsource-2" => "Lampada a fluorescenza",
+"exif-lightsource-3" => "Lampada al tungsteno (a incandescenza)",
+"exif-lightsource-4" => "Flash",
+"exif-lightsource-9" => "Bel tempo",
+"exif-lightsource-10" => "Nuvoloso",
+"exif-lightsource-11" => "In ombra",
+"exif-lightsource-12" => "Daylight fluorescent (D 5700 - 7100K)",
+"exif-lightsource-13" => "Day white fluorescent (N 4600 - 5400K)",
+"exif-lightsource-14" => "Cool white fluorescent (W 3900 - 4500K)",
+"exif-lightsource-15" => "White fluorescent (WW 3200 - 3700K)",
+"exif-lightsource-17" => "Luce standard A",
+"exif-lightsource-18" => "Luce standard B",
+"exif-lightsource-19" => "Luce standard C",
+"exif-lightsource-20" => "Illuminante D55",
+"exif-lightsource-21" => "Illuminante D65",
+"exif-lightsource-22" => "Illuminante D75",
+"exif-lightsource-23" => "Illuminante D50",
+"exif-lightsource-24" => "Lampada da studio ISO al tungsteno",
+"exif-lightsource-255" => "Altra sorgente luminosa",
+
+"exif-focalplaneresolutionunit-2" => "pollici",
+
+"exif-sensingmethod-1" => "Non definito",
+"exif-sensingmethod-2" => "Sensore area colore a 1 chip",
+"exif-sensingmethod-3" => "Sensore area colore a 2 chip",
+"exif-sensingmethod-4" => "Sensore area colore a 3 chip",
+"exif-sensingmethod-5" => "Sensore area colore sequenziale",
+"exif-sensingmethod-7" => "Sensore trilineare",
+"exif-sensingmethod-8" => "Sensore lineare colore sequenziale",
+
+"exif-filesource-3" => "DSC",
+
+"exif-scenetype-1" => "Fotografia diretta",
+
+"exif-customrendered-0" => "Processo normale",
+"exif-customrendered-1" => "Processo personalizzato",
+
+"exif-exposuremode-0" => "Esposizione automatica",
+"exif-exposuremode-1" => "Esposizione manuale",
+"exif-exposuremode-2" => "Bracketing automatico",
+
+"exif-whitebalance-0" => "Bilanciamento del bianco automatico",
+"exif-whitebalance-1" => "Bilanciamento del bianco manuale",
+
+"exif-scenecapturetype-0" => "Standard",
+"exif-scenecapturetype-1" => "Panorama",
+"exif-scenecapturetype-2" => "Ritratto",
+"exif-scenecapturetype-3" => "Notturna",
+
+"exif-gaincontrol-0" => "Nessuno",
+"exif-gaincontrol-1" => "Enfasi per basso guadagno",
+"exif-gaincontrol-2" => "Enfasi per alto guadagno",
+"exif-gaincontrol-3" => "Deenfasi per basso guadagno",
+"exif-gaincontrol-4" => "Deenfasi per alto guadagno",
+
+"exif-contrast-0" => "Normale",
+"exif-contrast-1" => "Alto contrasto",
+"exif-contrast-2" => "Basso contrasto",
+
+"exif-saturation-0" => "Normale",
+"exif-saturation-1" => "Bassa saturazione",
+"exif-saturation-2" => "Alta saturazione",
+
+"exif-sharpness-0" => "Normale",
+"exif-sharpness-1" => "Minore nitidezza",
+"exif-sharpness-2" => "Maggiore nitidezza",
+
+"exif-subjectdistancerange-0" => "Sconosciuta",
+"exif-subjectdistancerange-1" => "Macro",
+"exif-subjectdistancerange-2" => "Soggetto vicino",
+"exif-subjectdistancerange-3" => "Soggetto lontano",
+
+"exif-gpslatitude-n" => "Latitudine Nord",
+"exif-gpslatitude-s" => "Latitudine Sud",
+
+"exif-gpslongitude-e" => "Longitudine Est",
+"exif-gpslongitude-w" => "Longitudine Ovest",
+
+"exif-gpsstatus-a" => "Misurazione in corso", #rivedere
+"exif-gpsstatus-v" => "Misurazione interoperabile", #rivedere
+
+"exif-gpsmeasuremode-2" => "Misurazione bidimensionale",
+"exif-gpsmeasuremode-3" => "Misurazione tridimensionale",
+
+"exif-gpsspeed-k" => "Chilometri orari",
+"exif-gpsspeed-m" => "Miglia orarie",
+"exif-gpsspeed-n" => "Nodi",
+
+"exif-gpsdirection-t" => "Direzione reale",
+"exif-gpsdirection-m" => "Direzione magnetica",
+
+# external editor support
+"edit-externally" => "Modifica questo file usando un programma esterno",
+"edit-externally-help" => "Per maggiori informazioni consultare le [http://meta.wikimedia.org/wiki/Help:External_editors istruzioni] (in inglese)",
+
+# 'all' in various places, this might be different for inflected languages
+"recentchangesall" => "tutte",
+"imagelistall" => "tutte",
+"watchlistall1" => "tutte",
+"watchlistall2" => "tutte",
+"namespacesall" => "Tutti",
+
+# E-mail address confirmation
+"confirmemail" => "Conferma indirizzo e-mail",
+"confirmemail_noemail" => "Non è stato indicato un indirizzo e-mail valido nelle proprie [[Special:Preferences|preferenze]].",
+"confirmemail_text" => "Questo sito richiede la verifica dell'indirizzo e-mail prima di poter usare le funzioni connesse all'email. Premere il pulsante qui sotto per inviare una richiesta di conferma al proprio indirizzo; nel messaggio è presente un collegamento che contiene un codice. Visitare il collegamento con il proprio browser per confermare che l'indirizzo e-mail è valido.",
+"confirmemail_pending" => "<div class=\"error\">
+Il codice di conferma è già stato spedito via posta elettronica; se l'account è stato
+creato di recente, si prega di attendere l'arrivo del codice per qualche minuto prima
+di tentare di richiederne uno nuovo.
+</div>",
+"confirmemail_send" => "Invia un codice di conferma via e-mail.",
+"confirmemail_sent" => "Messaggio e-mail di conferma inviato.",
+"confirmemail_oncreate" => "Un codice di conferma è stato spedito all'indirizzo
+di posta elettronica indicato. Il codice non è necessario per accedere al sito,
+ma è necessario fornirlo per poter abilitare tutte le funzioni del sito che fanno
+uso della posta elettronica.",
+"confirmemail_sendfailed" => "Impossibile inviare il messaggio e-mail di conferma. Verificare che l'indirizzo non contenga caratteri non validi.
+
+Messaggio di errore del mailer: $1",
+"confirmemail_invalid" => "Codice di conferma non valido. Il codice potrebbe essere scaduto.",
+"confirmemail_needlogin" => "È necessario $1 per confermare il proprio indirizzo e-mail.",
+"confirmemail_success" => "L'indirizzo e-mail è confermato. Ora è possibile eseguire l'accesso e fare pieno uso del sito.",
+"confirmemail_loggedin" => "L'indirizzo e-mail è stato confermato.",
+"confirmemail_error" => "Errore nel salvataggio della conferma.",
+
+"confirmemail_subject" => "{{SITENAME}}: richiesta di conferma dell'indirizzo",
+"confirmemail_body" => "Qualcuno, probabilmente tu stesso dall'indirizzo IP $1, ha registrato l'account \"$2\" su {{SITENAME}} indicando questo indirizzo e-mail.
+
+Per confermare che l'account ti appartiene e attivare le funzioni relative all'invio di e-mail su {{SITENAME}}, apri il collegamento seguente con il tuo browser:
+
+$3
+
+Se l'account *non* ti appartiene, non seguire il collegamento. Questo codice di conferma scadrà automaticamente alle $4.",
+
+# Inputbox extension, may be useful in other contexts as well
+"tryexact" => "Cerca corrispondenza esatta",
+"searchfulltext" => "Ricerca nel testo",
+"createarticle" => "Crea voce",
+
+# Scary transclusion
+"scarytranscludedisabled" => "[L'inclusione di pagine tra siti wiki non è attiva]",
+"scarytranscludefailed" => "[Errore: Impossibile ottenere il template $1]",
+"scarytranscludetoolong" => "[Errore: URL troppo lunga]",
+
+# Trackbacks
+"trackbackbox" => "<div id=\"mw_trackbacks\">
+Informazioni di trackback per questa voce:<br />
+$1
+</div>",
+"trackbackremove" => " ([$1 Elimina])",
+"trackbacklink" => "Trackback",
+"trackbackdeleteok" => "Informazioni di trackback eliminate correttamente.",
+
+# delete conflict
+"deletedwhileediting" => "Attenzione: Questa pagina è stata cancellata dopo che hai iniziato a modificarla.",
+"confirmrecreate" => "L'utente [[User:$1|$1]] ([[User talk:$1|discussioni]]) ha cancellato questa pagina dopo che hai iniziato a modificarla, per il seguente motivo: ''$2''
+Per favore, conferma che desideri veramente ricreare questa pagina.",
+"recreate" => "Ricrea",
+"tooltip-recreate" => "Ricrea la pagina anche se è stata cancellata",
+
+"unit-pixel" => "px",
+
+# HTML dump
+"redirectingto" => "Reindirizzamento a [[$1]]...",
+
+# action=purge
+"confirm_purge" => "Si desidera pulire la cache di questa pagina?\n\n$1",
+"confirm_purge_button" => "Conferma",
+
+"youhavenewmessagesmulti" => "Hai nuovi messaggi su $1",
+
+"searchcontaining" => "Ricerca delle voci che contengono ''$1''.",
+"searchnamed" => "Ricerca delle voci con titolo ''$1''.",
+"articletitles" => "Ricerca delle voci che iniziano con ''$1''",
+"hideresults" => "Nascondi i risultati",
+
+# DISPLAYTITLE
+"displaytitle" => "(Per i collegamenti a questa pagina, usare [[$1]])",
+
+"loginlanguagelabel" => "Lingua: $1",
+
+# Multipage image navigation
+"imgmultipageprev" => "← pagina precedente",
+"imgmultipagenext" => "pagina seguente →",
+"imgmultigo" => "Vai",
+"imgmultigotopre" => "Vai alla pagina",
+
+# Table pager
+"ascending_abbrev" => "cresc",
+"descending_abbrev" => "decresc",
+"table_pager_next" => "Pagina successiva",
+"table_pager_prev" => "Pagina precedente",
+"table_pager_first" => "Prima pagina",
+"table_pager_last" => "Ultima pagina",
+"table_pager_limit" => "Mostra $1 file per pagina",
+"table_pager_limit_submit" => "Vai",
+"table_pager_empty" => "Nessun risultato",
+
+# Auto-summaries
+"autosumm-blank" => "Pagina svuotata completamente",
+"autosumm-replace" => "Pagina sostituita con '$1'",
+"autosumm-new" => "Nuova pagina: $1",
+
+# Size units
+"size-bytes" => "$1 byte",
+"size-kilobytes" => "$1 KB",
+"size-megabytes" => "$1 MB",
+"size-gigabytes" => "$1 GB",
+
+);
+
+?>
diff --git a/languages/messages/MessagesJa.php b/languages/messages/MessagesJa.php
new file mode 100644
index 000000000000..ddc47a309588
--- /dev/null
+++ b/languages/messages/MessagesJa.php
@@ -0,0 +1,1876 @@
+<?php
+/**
+ * Japanese (日本語)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ "なし", "左端", "右端", "ウィンドウの左上に固定"
+);
+
+$skinNames = array(
+ 'standard' => "標準",
+ 'nostalgia' => "ノスタルジア",
+ 'cologneblue' => "ケルンブルー",
+);
+
+$datePreferences = array(
+ 'default',
+ 'ISO 8601',
+);
+
+$defaultDateFormat = 'ja';
+
+$dateFormats = array(
+ 'ja time' => 'H:i',
+ 'ja date' => 'Y年n月j日 (D)',
+ 'ja both' => 'Y年n月j日 (D) H:i',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => "Media", /* Media */
+ NS_SPECIAL => "特別", /* Special */
+ NS_MAIN => "",
+ NS_TALK => "ノート", /* Talk */
+ NS_USER => "利用者", /* User */
+ NS_USER_TALK => "利用者‐会話", /* User_talk */
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1‐ノート', /* Wikipedia_talk */
+ NS_IMAGE => "画像", /* Image */
+ NS_IMAGE_TALK => "画像‐ノート", /* Image_talk */
+ NS_MEDIAWIKI => "MediaWiki", /* MediaWiki */
+ NS_MEDIAWIKI_TALK => "MediaWiki‐ノート", /* MediaWiki_talk */
+ NS_TEMPLATE => "Template", /* Template */
+ NS_TEMPLATE_TALK => "Template‐ノート", /* Template_talk */
+ NS_HELP => "Help", /* Help */
+ NS_HELP_TALK => "Help‐ノート", /* Help_talk */
+ NS_CATEGORY => "Category", /* Category */
+ NS_CATEGORY_TALK => "Category‐ノート" /* Category_talk */
+);
+
+$messages = array(
+'tog-underline' => 'リンクの下線:',
+'tog-highlightbroken' => '未作成のページへのリンクをハイライトする',
+'tog-justify' => '段落を均等割り付けする',
+'tog-hideminor' => '最近更新したページから細部の編集を隠す',
+'tog-extendwatchlist' => 'ウォッチリストを拡張する',
+'tog-usenewrc' => '最近更新したページを拡張する(ブラウザによっては使えないことがあります)',
+'tog-numberheadings' => '見出しに番号を振る',
+'tog-showtoolbar' => '編集ボタンを表示する',
+'tog-editondblclick' => 'ダブルクリックで編集する (JavaScript)',
+'tog-editsection' => 'セクション編集用リンクを有効にする',
+'tog-editsectiononrightclick'=> 'セクションタイトルの右クリックでセクション編集を行えるようにする (JavaScript)',
+'tog-showtoc' => '目次を表示する (4つ以上の見出しがあるページ)',
+'tog-rememberpassword' => 'セッションを越えてパスワードを記憶する',
+'tog-editwidth' => 'テキストボックスを横幅いっぱいに表示する',
+'tog-watchcreations' => '自分で作成したページをウォッチリストに追加する',
+'tog-watchdefault' => '編集したページをウォッチリストに追加する',
+'tog-watchmoves' => '自分が移動したページをウォッチリストに追加する',
+'tog-watchdeletion' => '自分が削除したページをウォッチリストに追加する',
+'tog-minordefault' => '細部の編集をデフォルトでチェックする',
+'tog-previewontop' => 'プレビューをテキストボックスの前に配置する',
+'tog-previewonfirst' => '編集開始時にもプレビューを表示する',
+'tog-nocache' => 'ページをキャッシュしない',
+'tog-enotifwatchlistpages'=> 'ウォッチリストにあるページが更新されたときにメールを受け取る',
+'tog-enotifusertalkpages'=> '自分の会話ページが更新されたときにメールを受け取る',
+'tog-enotifminoredits' => '細部の編集でもメールを受け取る',
+'tog-enotifrevealaddr' => 'あなた以外に送られる通知メールにあなたのメールアドレスを記載する',
+'tog-shownumberswatching'=> 'ページをウォッチしている利用者数を表示する',
+'tog-fancysig' => '署名を自動的に利用者ページへリンクさせない',
+'tog-externaleditor' => '編集に外部アプリケーションを使う',
+'tog-externaldiff' => '差分表示に外部アプリケーションを使う',
+'tog-showjumplinks' => 'アクセシビリティのための "{{int:jumpto}}" リンクを有効にする',
+'tog-uselivepreview' => 'ライブプレビューを使用する (JavaScript, 試験中の機能)',
+'tog-forceeditsummary' => '要約欄が空欄の場合に警告する',
+'tog-watchlisthideown' => '自分の編集を表示しない',
+'tog-watchlisthidebots' => 'ボットによる編集を表示しない',
+'tog-watchlisthideminor'=> '細部の編集を表示しない',
+'tog-nolangconversion' => '字形変換を無効にする',
+'tog-ccmeonemails' => '他ユーザーに送信したメールの控えを自分にも送る',
+
+'underline-always' => '常に付ける',
+'underline-never' => '常に付けない',
+'underline-default' => 'WWWブラウザに従う',
+'skinpreview' => '(プレビュー)',
+'sunday' => '日曜日',
+'monday' => '月曜日',
+'tuesday' => '火曜日',
+'wednesday' => '水曜日',
+'thursday' => '木曜日',
+'friday' => '金曜日',
+'saturday' => '土曜日',
+'sun' => '日',
+'mon' => '月',
+'tue' => '火',
+'wed' => '水',
+'thu' => '木',
+'fri' => '金',
+'sat' => '土',
+
+#long
+'january' => '1月',
+'february' => '2月',
+'march' => '3月',
+'april' => '4月',
+'may_long' => '5月',
+'june' => '6月',
+'july' => '7月',
+'august' => '8月',
+'september' => '9月',
+'october' => '10月',
+'november' => '11月',
+'december' => '12月',
+
+#genitive
+'january-gen' => '1月',
+'february-gen' => '2月',
+'march-gen' => '3月',
+'april-gen' => '4月',
+'may-gen' => '5月',
+'june-gen' => '6月',
+'july-gen' => '7月',
+'august-gen' => '8月',
+'september-gen' => '9月',
+'october-gen' => '10月',
+'november-gen' => '11月',
+'december-gen' => '12月',
+
+#short
+'jan' => '1月',
+'feb' => '2月',
+'mar' => '3月',
+'apr' => '4月',
+'may' => '5月',
+'jun' => '6月',
+'jul' => '7月',
+'aug' => '8月',
+'sep' => '9月',
+'oct' => '10月',
+'nov' => '11月',
+'dec' => '12月',
+
+'categories' => 'カテゴリ',
+'pagecategories' => 'カテゴリ',
+'category_header' => 'カテゴリ “$1” にあるページ',
+'subcategories' => 'サブカテゴリ',
+'category-media-header' => 'カテゴリ “$1” にあるメディア',
+
+'mainpage' => 'メインページ',
+'mainpagetext' => 'MediaWikiが正常にインストールされました。',
+'mainpagedocfooter' => '[http://meta.wikimedia.org/wiki/MediaWiki_localisation インターフェースの変更方法]や、そのほかの使い方・設定に関しては[http://meta.wikimedia.org/wiki/Help:Contents ユーザーズガイド]を参照してください。',
+'portal' => 'コミュニティ・ポータル',
+'portal-url' => 'Project:コミュニティ・ポータル',
+'about' => '解説',
+'aboutsite' => '{{SITENAME}}について',
+'aboutpage' => 'Project:{{SITENAME}}について',
+'article' => '本文',
+'help' => 'ヘルプ',
+'helppage' => 'Help:目次',
+'bugreports' => 'バグの報告',
+'bugreportspage' => 'Project:バグの報告',
+'sitesupport' => '寄付',
+'sitesupport-url' => 'Project:Site support',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => '編集の仕方',
+'newwindow' => '(新しいウィンドウが開きます)',
+'edithelppage' => 'Help:編集の仕方',
+'cancel' => '中止',
+'qbfind' => '検索',
+'qbbrowse' => '閲覧',
+'qbedit' => '編集',
+'qbpageoptions' => '個人用ツール',
+'qbpageinfo' => 'ページ情報',
+'qbmyoptions' => 'オプション',
+'qbspecialpages' => '特別ページ',
+'moredotdotdot' => 'すべて表示する',
+'mypage' => 'マイ・ページ',
+'mytalk' => 'マイ・トーク',
+'anontalk' => 'このIP利用者の会話',
+'navigation' => 'ナビゲーション',
+'metadata_help' => 'メタデータ([[Project:メタデータ]]を参照)',
+'currentevents' => '最近の出来事',
+'currentevents-url' => '最近の出来事',
+'disclaimers' => '免責事項',
+'disclaimerpage' => 'Project:免責事項',
+'privacy' => 'プライバシー・ポリシー',
+'privacypage' => 'Project:プライバシー・ポリシー',
+'errorpagetitle' => 'エラー',
+'returnto' => '$1 に戻る。',
+'tagline' => '出典: {{SITENAME}}',
+'search' => '検索',
+'searchbutton' => '検索',
+'go' => '表示',
+'searcharticle' => '表示',
+'history' => '履歴',
+'history_short' => '履歴',
+'updatedmarker' => '最後の訪問から更新されています',
+'info_short' => 'ページ情報',
+'printableversion' => '印刷用バージョン',
+'permalink' => 'この版への固定リンク',
+'print' => '印刷',
+'edit' => '編集',
+'editthispage' => 'このページを編集',
+'delete' => '削除',
+'deletethispage' => 'このページを削除',
+'undelete_short' => '削除済$1版',
+'protect' => '保護',
+'protectthispage' => 'このページを保護',
+'unprotect' => '保護解除',
+'unprotectthispage' => 'ページ保護解除',
+'newpage' => '新規ページ',
+'talkpage' => 'このページのノート',
+'specialpage' => '特別ページ',
+'personaltools' => '個人用ツール',
+'postcomment' => '新規にコメントを投稿',
+'articlepage' => '項目を表示',
+'talk' => 'ノート',
+'views' => '表示',
+'toolbox' => 'ツールボックス',
+'userpage' => '利用者ページを表示',
+'projectpage' => 'プロジェクトページを表示',
+'imagepage' => '画像のページを表示',
+'mediawikipage' => 'インターフェースページを表示',
+'templatepage' => 'テンプレートページを表示',
+'viewhelppage' => 'ヘルプページを表示',
+'categorypage' => 'カテゴリページを表示',
+'viewtalkpage' => 'ノートを表示',
+'otherlanguages' => '他の言語',
+'redirectedfrom' => '($1 から転送)',
+'redirectpagesub' => 'リダイレクトページ',
+'lastmodifiedat' => '最終更新 $2, $1。',
+'viewcount' => 'このページは $1 回アクセスされました。',
+'copyright' => 'コンテンツは$1のライセンスで利用することができます。',
+'protectedpage' => '保護されたページ',
+'jumpto' => '移動:',
+'jumptonavigation' => 'ナビゲーション',
+'jumptosearch' => '検索',
+
+'badaccess' => '権限がありません',
+'badaccess-group0' => 'あなたはこの処理を行う権限を持っていません。',
+'badaccess-group1' => 'この処理は $1 の権限を持った利用者のみが実行できます。',
+'badaccess-group2' => 'この処理は $1 のうちどちらかの権限を持った利用者のみが実行できます。',
+'badaccess-groups' => 'この処理は $1 のうちいずれかの権限を持った利用者のみが実行できます。',
+
+'versionrequired' => 'MediaWiki バージョン $1 が必要',
+'versionrequiredtext' => 'このページの利用には MediaWiki Version $1 が必要です。[[Special:Version|{{int:version}}]]を確認してください。',
+
+'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+
+'retrievedfrom' => ' "$1" より作成',
+'youhavenewmessages' => 'あなた宛の$1が届いています。($2)',
+'newmessageslink' => '新しいメッセージ',
+'newmessagesdifflink' => '差分',
+'editsection' => '編集',
+'editold' => '編集',
+'editsectionhint' => '節を編集: $1',
+'toc' => '目次',
+'showtoc' => '表示',
+'hidetoc' => '非表示',
+'thisisdeleted' => '$1 を参照または復帰する。',
+'viewdeleted' => '$1の削除記録と履歴を確認する',
+'restorelink' => '削除された $1 編集',
+'feedlinks' => 'フィード:',
+'feed-invalid' => 'フィード形式の指定が間違っています。',
+'nstab-main' => '本文',
+'nstab-user' => '利用者ページ',
+'nstab-media' => 'Media',
+'nstab-special' => '特別ページ',
+'nstab-project' => '解説',
+'nstab-image' => '画像',
+'nstab-mediawiki' => 'インターフェース',
+'nstab-template' => 'テンプレート',
+'nstab-help' => 'ヘルプ',
+'nstab-category' => 'カテゴリ',
+'nosuchaction' => 'そのような動作はありません',
+'nosuchactiontext' => 'このURIで指定された動作は{{SITENAME}}で認識できません。',
+'nosuchspecialpage' => 'そのような特別ページはありません',
+'nospecialpagetext' => '要求された特別ページは存在しません。有効な特別ページの一覧は[[Special:Specialpages]]にあります。',
+'error' => 'エラー',
+'databaseerror' => 'データベース・エラー',
+'dberrortext' => 'データベース検索の文法エラー。これは恐らくソフトウェアのバグを表しています。
+
+最後に実行を試みた問い合わせ:
+<blockquote><tt>$1</tt></blockquote>
+
+from within function "<tt>$2</tt>". MySQL returned error "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'データベースクエリの文法エラーが発生しました。
+----
+A database query syntax error has occurred.
+The last attempted database query was:
+"$1"
+from within function "$2".
+MySQL returned error "$3: $4"',
+'sqlhidden' => '(SQLクエリー非表示)',
+'noconnect' => '申し訳ありません。何らかの問題によりデータベースに接続できません。<br />$1',
+'nodb' => 'データベース $1 を選択できません。',
+'cachederror' => 'あなたがアクセスしたページのコピーを保存したものを表示しています。また、コピーは更新されません。',
+'laggedslavemode' => '警告: ページに最新の編集が反映されていない可能性があります。反映されるまでしばらくお待ちください。',
+'readonly' => 'データベースはロックされています',
+'enterlockreason' => 'ロックする理由を入力してください。ロックが解除されるのがいつになるかの見積もりについても述べてください。',
+'readonlytext' => 'データベースは現在、新しいページの追加や編集を受け付けない「ロック状態」になっています。これはおそらく定期的なメンテナンスのためで、メンテナンス終了後は正常な状態に復帰します。データベースをロックしたサーバー管理者は次のような説明をしています:
+
+$1
+
+----
+The database is currently locked to new entries and other modifications, probably for routine database maintenance, after which it will be back to normal. The administrator who locked it offered this explanation:
+
+$1',
+'missingarticle' => '<p>"$1" という題のページは見つかりませんでした。すでに削除された版を参照しようとしている可能性があります。これがソフトウェアのバグだと思われる場合は、URIと共にサーバー管理者に報告して下い。</p>',
+'readonly_lag' => 'データベースはスレーブ・サーバーがマスタ・サーバーに同期するまで自動的にロックされています。しばらくお待ちください。',
+'internalerror' => '内部処理エラー',
+'filecopyerror' => 'ファイル "$1" から "$2" へのコピーに失敗しました。',
+'filerenameerror' => 'ファイル名を "$1" から "$2" へ変更できませんでした。',
+'filedeleteerror' => 'ファイル "$1" の削除に失敗しました。',
+'filenotfound' => 'ファイル "$1" が見つかりません。',
+'unexpected' => '値が異常です: $1 = "$2"',
+'formerror' => 'エラー: フォームの送信に失敗しました。',
+'badarticleerror' => 'このページでは要求された処理を行えません。',
+'cannotdelete' => '指定されたページ、または画像の削除に失敗しました。',
+'badtitle' => 'ページタイトルの間違い',
+'badtitletext' => '要求されたページは無効か、何もないか、正しくない inter-language または inter-wiki のタイトルです。',
+'perfdisabled' => 'この機能はデータベースの負荷を軽くするために現在使えなくなっています。',
+'perfdisabledsub' => 'ここには $1 のコピーを表示しています。',
+'perfcached' => '以下のデータはキャッシュであり、しばらく更新されていません。',
+'perfcachedts' => '以下のデータは $1 に最終更新されたキャッシュです。',
+'querypage-no-updates' => 'ページの更新は無効になっています。以下のデータの更新は現在行われていません。',
+'wrong_wfQuery_params' => 'wfQuery()へ誤った引数が渡されました。<br />
+関数: $1<br />
+クエリ: $2',
+'viewsource' => 'ソースを表示',
+'viewsourcefor' => '$1 のソース',
+'protectedpagetext' => 'このページは編集できないように保護されています。',
+'viewsourcetext' => '以下にソースを表示しています:',
+'protectedinterface' => 'このページはソフトウェアのインターフェースに使用されるテキストが保存されおり、問題回避のために保護されています。',
+'editinginterface' => '\'\'\'警告:\'\'\' あなたはソフトウェアのインターフェースに使用されているテキストを編集しています。このページの変更はすべての利用者に影響します。',
+'logouttitle' => 'ログアウト',
+'logouttext' => '<p><strong>ログアウトしました。</strong>このまま{{SITENAME}}を匿名で使い続けることができます。もう一度ログインして元の、あるいは別の利用者として使うこともできます。</p>
+<p>※いくつかのページはブラウザのキャッシュをクリアするまでログインしているかのように表示されることがあります。</p>',
+'welcomecreation' => '== $1 さん、ようこそ! ==
+あなたのアカウントができました。お好みに合わせて[[Special:Preferences|オプション]]を変更することをお忘れなく。',
+'loginpagetitle' => 'ログイン',
+'yourname' => '利用者名',
+'yourpassword' => 'パスワード',
+'yourpasswordagain' => 'パスワード再入力',
+'remembermypassword' => 'セッションを越えてパスワードを記憶する',
+'yourdomainname' => 'あなたのドメイン',
+'externaldberror' => '外部の認証データベースでエラーが発生たか、または外部アカウント情報の更新が許可されていません。',
+'loginproblem' => '<b>ログインでエラーが発生しました。</b><br />再度実行してください。',
+'alreadyloggedin' => '<strong>利用者 $1 は、すでにログイン済みです。</strong><br />',
+'login' => 'ログイン',
+'loginprompt' => '{{SITENAME}}にログインするにはクッキーを有効にする必要があります。',
+'userlogin' => 'ログインまたはアカウント作成',
+'logout' => 'ログアウト',
+'userlogout' => 'ログアウト',
+'notloggedin' => 'ログインしていません',
+'nologin' => 'アカウントはお持ちですか? $1',
+'nologinlink' => 'アカウントを作成',
+'createaccount' => 'アカウント作成',
+'gotaccount' => 'すでにアカウントをお持ちの場合: $1',
+'gotaccountlink' => 'ログイン',
+'createaccountmail' => 'メールで送信',
+'badretype' => '両方のパスワードが一致しません。',
+'userexists' => 'その利用者名はすでに使われています。ほかの名前をお選びください。',
+'youremail' => 'メールアドレス*:',
+'username' => '利用者名:',
+'uid' => '利用者ID:',
+'yourrealname' => '本名*:',
+'yourlanguage' => 'インターフェース言語:',
+'yourvariant' => '字体変換',
+'yournick' => 'ニックネーム(署名用):',
+'badsig' => '署名が正しくありません。HTMLタグを見直してください。',
+'email' => 'メールアドレス',
+'prefs-help-email-enotif'=> 'このアドレスはあなたが有効にした各種メール通知の送信先としても利用されます。',
+'prefs-help-realname' => '* 本名 (任意): 本名を入力すると、ページ・クレジットに利用者名(アカウント名)の代わりに本名が表示されます。',
+'loginerror' => 'ログイン失敗',
+'prefs-help-email' => '* メールアドレス (任意): メールアドレスを入力すると、他の利用者があなたの利用者ページまたは会話ページから、あなたの身元を知ることなく、あなたに連絡が取れるようになります。',
+'nocookiesnew' => '利用者のアカウントは作成されましたが、ログインしていません。{{SITENAME}}ではログインにクッキーを使います。あなたはクッキーを無効な設定にしているようです。クッキーを有効にしてから作成した利用者名とパスワードでログインしてください。',
+'nocookieslogin' => '{{SITENAME}}ではログインにクッキーを使います。あなたはクッキーを無効な設定にしているようです。クッキーを有効にして、もう一度試してください。',
+'noname' => '利用者名を正しく指定していません。',
+'loginsuccesstitle' => 'ログイン成功',
+'loginsuccess' => '\'\'\'{{SITENAME}} に "$1" としてログインしました。\'\'\'',
+'nosuchuser' => '"$1" という利用者は見当たりません。綴りが正しいことを再度確認するか、下記のフォームを使ってアカウントを作成してください。',
+'nosuchusershort' => '"$1" という利用者は見当たりません。綴りが正しいことを再度確認してください。',
+'nouserspecified' => '利用者名を指定してください。',
+'wrongpassword' => 'パスワードが間違っています。再度入力してください。',
+'wrongpasswordempty' => 'パスワードを空にすることはできません。再度入力してください。',
+'mailmypassword' => '新しいパスワードをメールで送る',
+'passwordremindertitle' => '{{SITENAME}} パスワード再送通知',
+'passwordremindertext' => 'どなたか($1 のIPアドレスの使用者)が{{SITENAME}} ($4) のログイン用パスワードの再発行を依頼しました。
+
+利用者 "$2" のパスワードを "$3" に変更しました。
+ログインして別のパスワードに変更してください。',
+'noemail' => '利用者 "$1" のメールアドレスは登録されていません。',
+'passwordsent' => '新しいパスワードを "$1" さんの登録済みメールアドレスに送信しました。メールを受け取ったら、再度ログインしてください。',
+'blocked-mailpassword' => 'あなたの使用しているIPアドレスからの編集はブロックされています。悪用防止のため、パスワードの再発行は無効化されています。',
+'eauthentsent' => '指定されたメールアドレスにアドレス確認のためのメールを送信しました。このアカウントが本当にあなたのものであるか確認するため、あなたがメールの内容に従わない限り、その他のメールはこのアカウント宛には送信されません。',
+'throttled-mailpassword'=> '新しいパスワードは $1 時間以内に送信済みです。悪用防止のため、パスワードは $1 時間間隔で再発行可能となります。',
+'mailerror' => 'メールの送信中にエラーが発生しました: $1',
+'acct_creation_throttle_hit'=> 'あなたは既に $1 アカウントを作成しています。これ以上作成できません。',
+'emailauthenticated' => 'あなたのメールアドレスは $1 に確認されています。',
+'emailnotauthenticated' => 'あなたのメールアドレスは確認されていません。確認されるまで以下のいかなるメールも送られません。',
+'noemailprefs' => '<strong>これらの機能を有効にするにはメールアドレスを登録してください。</strong>',
+'emailconfirmlink' => 'メールアドレスを確認する',
+'invalidemailaddress' => '入力されたメールアドレスが正しい形式に従っていないため、受け付けられません。正しい形式で入力し直すか、メールアドレス欄を空にしてください。',
+'accountcreated' => 'アカウントを作成しました',
+'accountcreatedtext' => '利用者 $1 が作成されました。',
+'cantcreateaccounttitle'=> 'アカウントを作成できません',
+'cantcreateaccounttext' => 'このIPアドレス (<b>$1</b>) からのアカウント作成はブロックされています。',
+
+# Password reset dialog
+'resetpass' => 'パスワードの再設定',
+'resetpass_announce' => 'メールで送信した臨時パスワードでログインしています。ログインを完了するには、新しいパスワードを設定しなおす必要があります。',
+'resetpass_text' => "<!-- ここにテキストを挿入 -->",
+'resetpass_header' => 'パスワードを設定しなおす',
+'resetpass_submit' => '再設定してログイン',
+'resetpass_success' => 'あなたのパスワードは変更されました。ログインしています...',
+'resetpass_bad_temporary' => '無効な臨時パスワードです。パスワードは既に再設定されているか、再びパスワード通知メールが送信されています。',
+'resetpass_forbidden' => 'このウィキでは、パスワードの変更は許可されていません。',
+'resetpass_missing' => 'データがセットされていません。',
+
+# Edit page toolbar
+'bold_sample' => '強い強調(太字)',
+'bold_tip' => '強い強調(太字)',
+'italic_sample' => '弱い強調(斜体)',
+'italic_tip' => '弱い強調(斜体)',
+'link_sample' => '項目名',
+'link_tip' => '内部リンク',
+'extlink_sample' => 'http://www.example.com リンクのタイトル',
+'extlink_tip' => '外部リンク(http:// を忘れずにつけてください)',
+'headline_sample' => '見出し',
+'headline_tip' => '標準の見出し',
+'math_sample' => '\int f(x)dx',
+'math_tip' => '数式 (LaTeX)',
+'nowiki_sample' => 'そのまま表示させたい文字を入力',
+'nowiki_tip' => '入力文字をそのまま表示',
+'image_sample' => 'Example.jpg',
+'image_tip' => '埋め込み画像([[{{ns:image}}:~]]に直してください)',
+'media_sample' => 'Example.mp3',
+'media_tip' => 'メディアファイル(音声)へのリンク',
+'sig_tip' => '時刻つきの署名',
+'hr_tip' => '水平線(利用は控えめに)',
+'summary' => '編集内容の要約',
+'subject' => '題名・見出し',
+'minoredit' => 'これは細部の編集です',
+'watchthis' => 'ウォッチリストに追加',
+'savearticle' => '保存する',
+'preview' => 'プレビュー',
+'showpreview' => 'プレビューを実行',
+'showlivepreview' => 'ライブプレビュー',
+'showdiff' => '差分を表示',
+'anoneditwarning' => 'あなたはログインしていません。あなたのIPアドレスはこの項目の履歴に記録されます。',
+'missingsummary' => '\'\'\'注意:\'\'\' 要約欄が空欄です。投稿ボタンをもう一度押すと、要約なしのまま投稿されます。',
+'missingcommenttext' => '以下にコメントを入力してください。',
+'missingcommentheader' => '\'\'\'注意:\'\'\' 題名・見出しが空欄です。投稿ボタンをもう一度押すと、要約なしのまま投稿されます。',
+'summary-preview' => '要約のプレビュー',
+'subject-preview' => '題名・見出しのプレビュー',
+'blockedtitle' => '投稿ブロック',
+'blockedtext' => 'ご使用の利用者名またはIPアドレスは $1 によって投稿をブロックされています。その理由は次の通りです。
+:$2
+
+$1 または他の[[{{int:grouppage-sysop}}|{{int:group-sysop}}]]にこの件についてメールで問い合わせることができます。ただし、[[Special:Preferences|オプション]]に正しいメールアドレスが登録されていない場合、「{{int:emailuser}}」機能が使えないことに注意してください。
+
+あなたのIPアドレスは「$3」、ブロックIDは &#x23;$5 です。問い合わせを行う際には、この情報を必ず書いてください。',
+'blockedoriginalsource' => '以下に \'\'\'$1\'\'\' のソースを示します:',
+'blockededitsource' => '\'\'\'$1\'\'\' への \'\'\'あなたの編集\'\'\' を以下に示します:',
+'whitelistedittitle' => '編集にはログインが必要',
+'whitelistedittext' => 'このページを編集するには $1 する必要があります。',
+'whitelistreadtitle' => '閲覧にはログインが必要',
+'whitelistreadtext' => 'このページを閲覧するには[[Special:Userlogin|ログイン]]する必要があります。',
+'whitelistacctitle' => 'アカウントの作成は許可されていません',
+'whitelistacctext' => '{{SITENAME}}のアカウントを作成するには、適切な権限を持った利用者名で[[Special:Userlogin|ログイン]]する必要があります。',
+'confirmedittitle' => '編集にはメールアドレスの確認が必要です。',
+'confirmedittext' => 'ページの編集を始める前にメールアドレスの確認をする必要があります。[[Special:Preferences|オプション]]でメールアドレスを設定し、確認を行ってください。',
+'loginreqtitle' => 'ログインが必要',
+'loginreqlink' => 'ログイン',
+'loginreqpagetext' => '他のページを閲覧するには$1する必要があります。',
+'accmailtitle' => 'パスワードを送信しました',
+'accmailtext' => '"$1" のパスワードを $2 に送信しました。',
+'newarticle' => '(新規)',
+'newarticletext' => 'ページを新規に作成するには新しい内容を書き込んでください。',
+'anontalkpagetext' => '----
+\'\'これはアカウントをまだ作成していないか、あるいは使っていない匿名利用者のための会話ページです。{{SITENAME}}では匿名利用者の識別は利用者名のかわりにIPアドレスを用います。IPアドレスは何人かで共有されることがあります。もしも、あなたが匿名利用者で無関係なコメントがここに寄せられる場合は、[[Special:Userlogin|アカウントを作成するかログインして]]他の匿名利用者と間違えられないようにしてくださるようお願いします。',
+'noarticletext' => '現在このページには内容がありません。他のページから[[{{ns:special}}:Search/{{PAGENAME}}|このページタイトルを検索する]]か、[{{fullurl:{{FULLPAGENAME}}|action=edit}} このページを編集]できます。',
+'clearyourcache' => '\'\'\'お知らせ:\'\'\' 保存した後、ブラウザのキャッシュをクリアする必要があります。\'\'\'Mozilla / Firefox / Safari:\'\'\' [Shift] を押しながら [再読み込み] をクリック、または [Shift]-[Ctrl]-[R] (Macでは [Cmd]-[Shift]-[R]); \'\'\'IE:\'\'\' [Ctrl] を押しながら [更新] をクリック、または [Ctrl]-[F5]; \'\'\'Konqueror:\'\'\' [再読み込み] をクリック、または [F5]; \'\'\'Opera:\'\'\' 「ツール」→「設定」からキャッシュをクリア。',
+'usercssjsyoucanpreview'=> '<strong>ヒント:</strong> 「{{int:showpreview}}」ボタンを使うと保存前に新しいスタイルシート・スクリプトをテストできます。',
+'usercsspreview' => '\'\'\'あなたはユーザースタイルシートをプレビューしています。まだ保存されていないので注意してください。\'\'\'',
+'userjspreview' => '\'\'\'あなたはユーザースクリプトをテスト・プレビューしています。まだ保存されていないので注意してください。\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'警告:\'\'\' "$1" という外装はありません。.css と .js ページを編集する再にはタイトルを小文字にすることを忘れないでください。例えば {{ns:user}}:Hoge/Monobook.css ではなく {{ns:user}}:Hoge/monobook.css となります。',
+'updated' => '(更新)',
+'note' => '<strong>お知らせ:</strong>',
+'previewnote' => 'これはプレビューです。まだ保存されていません!',
+'session_fail_preview' => '<strong>セッションが切断されたため編集を保存できません。もう一度やりなおしてください。それでも失敗する場合、ログアウトしてからログインし直してください。</strong>',
+'previewconflict' => 'このプレビューは、上の文章編集エリアの文章を保存した場合にどう見えるようになるかを示すものです。',
+'session_fail_preview_html'=> '<strong>セッションデータが見つからないため、あなたの編集を保存することができませんでした。</strong>
+
+このウィキでは raw HTML の記述を許可しており、JavaScript でのアタックを予防するためにプレビューを隠しています。
+
+<strong>この編集が問題ないものであるならば再度保存してください。それでもうまくいかない際には一度ログアウトして、もう一度ログインしてみてください。</strong>',
+'importing' => '$1 をインポート中',
+'editing' => '$1 を編集中',
+'editinguser' => '$1 を編集中',
+'editingsection' => '$1 を編集中(節単位編集)',
+'editingcomment' => '$1 を編集中(新規コメント)',
+'editconflict' => '編集競合: $1',
+'explainconflict' => 'あなたがこのページを編集し始めた後に、他の誰かがこのページを変更しました。上側のテキストエリアは現在の最新の状態です。あなたの編集していた文章は下側のテキストエリアに示されています。編集していた文章を、上側のテキストエリアの文章に組み込んでください。<strong>上側のテキストエリアの内容だけ</strong>が、「{{int:Savearticle}}」をクリックした時に実際に保存されます。',
+'yourtext' => 'あなたの文章',
+'storedversion' => '保存された版',
+'nonunicodebrowser' => '<strong>警告: あなたの使用しているブラウザはUnicode互換ではありません。項目を編集する前にブラウザを変更してください。</strong>',
+'editingold' => '<strong>警告: あなたはこのページの古い版を編集しています。もしこの文章を保存すると、この版以降に追加された全ての変更が無効になってしまいます。</strong>',
+'yourdiff' => 'あなたの更新内容',
+'copyrightwarning' => '\'\'\'■投稿する前に以下を確認してください■\'\'\'
+* {{SITENAME}}に投稿された文書は、すべて$2(詳細は$1を参照)によって公開されることに同意してください。
+* あなたの文章が他人によって自由に編集、配布されることを望まない場合は、投稿を控えてください。
+* あなたの投稿する文章はあなた自身によって書かれたものであるか、パブリック・ドメインかそれに類する自由なリソースからの複製であることを約束してください。\'\'\'あなたが著作権を保持していない作品を許諾なしに投稿してはいけません!\'\'\'',
+'copyrightwarning2' => '\'\'\'■投稿する前に以下を確認してください■\'\'\'
+* あなたの文章が他人によって自由に編集、配布されることを望まない場合は、投稿を控えてください。
+* あなたの投稿する文章はあなた自身によって書かれたものであるか、パブリック・ドメインかそれに類する自由なリソースからの複製であることを約束してください(詳細は$1を参照)。\'\'\'あなたが著作権を保持していない作品を許諾なしに投稿してはいけません!\'\'\'',
+'longpagewarning' => '\'\'\'警告:\'\'\' このページのサイズは $1 キロバイトです。一部の古いブラウザでは 32 キロバイト以上のページを編集すると問題が起きるものがあります。ページを節に分けることを検討してください。',
+'longpageerror' => '<strong>エラー: あなたが投稿したテキストは $1 キロバイトの長さがあります。これは投稿できる最大の長さである $2 キロバイトを超えています。この編集を保存することはできません。</strong>',
+'readonlywarning' => '<strong>警告: データベースがメンテナンスのためにロックされています。現在は編集結果を保存できません。文章をカットアンドペーストしてローカルファイルとして保存し、後ほど保存をやり直してください。</strong>',
+'protectedpagewarning' => '\'\'\'警告:\'\'\' このページは保護されています。{{int:group-sysop}}しか編集できません。詳しくは[[Project:保護の方針|保護の方針]]を参照してください。',
+'semiprotectedpagewarning'=> '\'\'\'お知らせ:\'\'\' このページは登録利用者のみが編集できるよう保護されています。',
+'templatesused' => 'このページで使われているテンプレート:',
+'templatesusedpreview' => 'このプレビューで使われているテンプレート:',
+'templatesusedsection' => 'この節で使われているテンプレート:',
+'template-protected' => '(保護)',
+'template-semiprotected'=> '(半保護)',
+'edittools' => '<!-- ここに書いたテキストは編集及びアップロードのフォームの下に表示されます。 -->',
+'nocreatetitle' => 'ページを作成できません',
+'nocreatetext' => 'このサイトではページの新規作成を制限しています。元のページに戻って既存のページを編集するか、[[Special:Userlogin|ログイン]]してください。',
+
+# "Undo" feature
+'undo-success' => '編集の取り消しに成功しました。保存ボタンを押すと変更が確定されます。',
+'undo-failure' => '中間の版での編集と競合したため、自動取り消しできませんでした。',
+'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|会話]]) の編集 ( $1 版 ) を取り消し',
+
+# History pages
+'revhistory' => '変更履歴',
+'viewpagelogs' => 'このページに関するログを見る',
+'nohistory' => 'このページには変更履歴がありません。',
+'revnotfound' => '要求された版が見つかりません。',
+'revnotfoundtext' => '要求されたこのページの旧版は見つかりませんでした。このページにアクセスしたURLをもう一度確認してください。',
+'loadhist' => '変更履歴の読み込み中',
+'currentrev' => '最新版',
+'revisionasof' => '$1の版',
+'revision-info' => '$1; $2 による版',
+'previousrevision' => '←前の版',
+'nextrevision' => '次の版→',
+'currentrevisionlink' => '最新版を表示',
+'cur' => '最新版',
+'next' => '次の版',
+'last' => '前の版',
+'orig' => '最古版',
+'histlegend' => '凡例:(最新版)= 最新版との比較、(前の版)= 直前の版との比較、<strong>{{int:minoreditletter}}</strong> = 細部の編集',
+'deletedrev' => '[削除済み]',
+'histfirst' => '最古',
+'histlast' => '最新',
+'rev-deleted-comment' => '(要約は削除されています)',
+'rev-deleted-user' => '(投稿者名は削除されています)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+この版は公の履歴から削除されました。[{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} 削除記録]におそらくログがあります。</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+この版は公の履歴から削除されており、このサイトの{{int:group-sysop}}だけが内容を見ることができます。削除の詳細は[{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} 削除記録]を参照してください。
+</div>',
+'rev-delundel' => '復帰/削除',
+'history-feed-title' => '変更履歴',
+'history-feed-description'=> 'このウィキのこのページに関する変更履歴',
+'history-feed-item-nocomment'=> '$2 における $1 による編集',
+'history-feed-empty' => '要求したページは存在しません。既に削除されたか移動された可能性があります。 [[Special:Search|このウィキの検索]]で関連する新しいページを探してみてください。',
+
+# Revision deletion
+'revisiondelete' => '版の削除と復帰',
+'revdelete-nooldid-title' => '対象版がありません',
+'revdelete-nooldid-text'=> '操作の完了に必要な版が指定されていません。',
+'revdelete-selected' => '[[:$1]]の、以下の選択された版に対する操作:',
+'revdelete-text' => '版の削除ではページの履歴にその版は表示されます。しかしその版に含まれるテキストにはアクセスできなくなります。
+
+サーバー管理者にこれ以上の制限をかけられない限り、他の{{int:group-sysop}}は隠れた版を読んだり、元に戻したりできます。',
+'revdelete-legend' => '版の削除の適用',
+'revdelete-hide-text' => '版のテキストを隠す',
+'revdelete-hide-comment'=> '編集の要約を隠す',
+'revdelete-hide-user' => '版の投稿者を隠す',
+'revdelete-hide-restricted'=> 'これらの制限を{{int:group-sysop}}にも適用する',
+'revdelete-log' => '要約:',
+'revdelete-submit' => '隠蔽の設定を適用',
+'revdelete-logentry' => '[[$1]]の版の削除情報を操作しました',
+
+# Diffs
+'difference' => '版間での差分',
+'loadingrev' => '差分をとるために古い版を読み込んでいます',
+'lineno' => '$1 行',
+'editcurrent' => 'このページの最新版を編集',
+'selectnewerversionfordiff'=> '比較する新しい版を選択',
+'selectolderversionfordiff'=> '比較する古い版を選択',
+'compareselectedversions'=> '選択した版同士を比較',
+'editundo' => '取り消し',
+'diff-multi' => '(間の $1 版分が非表示です)',
+
+'searchresults' => '検索結果',
+'searchresulttext' => '{{SITENAME}}の検索に関する詳しい情報は、[[{{ns:project}}:検索]]をご覧ください。',
+'searchsubtitle' => '問い合わせ: "[[$1]]"',
+'searchsubtitleinvalid' => '問い合わせ: "$1"',
+'badquery' => 'おかしな形式の検索問い合わせ',
+'badquerytext' => '問い合わせを処理できませんでした。おそらく3文字未満の語を検索しようとしたためですが、まだ対応していません。例えば「魚 and and 大きさ」のように、表現を誤記しているのかもしれません。',
+'matchtotals' => '"$1" を検索し、 $2 の項目名及び $3 ページの本文と一致しました。',
+'noexactmatch' => '"$1" という名称のページは存在しませんでした。[[:$1|新規作成する]]。',
+'titlematches' => '項目名と一致',
+'notitlematches' => '項目名とは一致しませんでした',
+'textmatches' => 'ページ内本文と一致',
+'notextmatches' => 'ページ内本文とは一致しませんでした',
+'prevn' => '前 $1',
+'nextn' => '次 $1',
+'viewprevnext' => '($1)($2)($3)を見る',
+'showingresults' => '<b>$2</b> 件目から <b>$1</b> 件を表示しています。',
+'showingresultsnum' => '<b>$2</b> 件目から <b>$3</b> 件を表示しています。',
+'nonefound' => '\'\'\'※\'\'\'検索がうまくいかないのは、「ある」や「から」のような一般的な語で索引付けがされていないか、複数の検索語を指定している(全ての検索語を含むページだけが結果に示されます)などのためかもしれません。',
+'powersearch' => '検索',
+'powersearchtext' => '検索する名前空間 :<br />
+$1<br />
+$2リダイレクトを含める &nbsp; &nbsp; &nbsp; $3 $9',
+'searchdisabled' => '<p>全文検索はサーバー負荷の都合から、一時的に使用停止しています。元に戻るまでGoogleでの全文検索を利用してください。検索結果は少し古い内容となります。</p>',
+'blanknamespace' => '(標準)',
+
+# Preferences page
+'preferences' => 'オプション',
+'mypreferences' => 'オプション',
+'prefsnologin' => 'ログインしていません',
+'prefsnologintext' => 'オプションを変更するためには、[[Special:Userlogin|ログイン]]する必要があります。',
+'prefsreset' => 'オプションは初期化されました。',
+'qbsettings' => 'クイックバー設定',
+'changepassword' => 'パスワード変更',
+'skin' => '外装',
+'math' => '数式',
+'dateformat' => '日付の書式',
+'datedefault' => '選択なし',
+'datetime' => '日付と時刻',
+'math_failure' => '構文解析失敗',
+'math_unknown_error' => '不明なエラー',
+'math_unknown_function' => '不明な関数',
+'math_lexing_error' => '字句解析エラー',
+'math_syntax_error' => '構文エラー',
+'math_image_error' => 'PNGへの変換に失敗しました。latex, dvips, gs, convertが正しくインストールされているか確認してください。',
+'math_bad_tmpdir' => 'TeX一時ディレクトリを作成または書き込みできません',
+'math_bad_output' => 'TeX出力用ディレクトリを作成または書き込みできません',
+'math_notexvc' => 'texvcプログラムが見つかりません。math/READMEを読んで正しく設定してください。',
+'prefs-personal' => '利用者情報',
+'prefs-rc' => '最近更新したページ',
+'prefs-watchlist' => 'ウォッチリスト',
+'prefs-watchlist-days' => 'ウォッチリストに表示する日数:',
+'prefs-watchlist-edits' => '拡張したウォッチリストに表示する件数:',
+'prefs-misc' => 'その他',
+'saveprefs' => '設定の保存',
+'resetprefs' => '設定の初期化',
+'oldpassword' => '古いパスワード:',
+'newpassword' => '新しいパスワード:',
+'retypenew' => '新しいパスワードを再入力:',
+'textboxsize' => '編集画面',
+'rows' => '縦:',
+'columns' => '横:',
+'searchresultshead' => '検索',
+'resultsperpage' => '1ページあたりの表示件数:',
+'contextlines' => '1件あたりの行数:',
+'contextchars' => '1行あたりの文字数:',
+'stubthreshold' => 'スタブ表示にする閾値:',
+'recentchangescount' => '最近更新したページの表示件数:',
+'savedprefs' => 'オプションを保存しました',
+'timezonelegend' => 'タイムゾーン',
+'timezonetext' => 'UTCとあなたの地域の標準時間との差を入力してください(日本国内は9:00)。',
+'localtime' => 'あなたの現在時刻',
+'timezoneoffset' => '時差¹',
+'servertime' => 'サーバーの現在時刻',
+'guesstimezone' => '自動設定',
+'allowemail' => '他の利用者からのメールの受け取りを許可する',
+'defaultns' => '標準で検索する名前空間:',
+'default' => 'デフォルト',
+'files' => '画像等',
+'userrights-lookup-user'=> '利用者の所属グループの管理',
+'userrights-user-editname'=> '利用者名:',
+'editusergroup' => '編集',
+'userrights-editusergroup'=> '利用者の所属グループ',
+'saveusergroups' => '利用者の所属グループを保存',
+'userrights-groupsmember'=> '所属グループ:',
+'userrights-groupsavailable'=> '有効なグループ:',
+'userrights-groupshelp' => 'この利用者から削除したい、またはこの利用者に追加したいグループを選択してください。選択されていないグループは変更されません。選択を解除するには [CTRL]+[左クリック] です。',
+'group' => 'グループ:',
+'group-bot' => 'ボット',
+'group-sysop' => '管理者',
+'group-bureaucrat' => 'ビューロクラット',
+'group-all' => '(すべて)',
+'group-bot-member' => '{{int:group-bot}}',
+'group-sysop-member' => '{{int:group-sysop}}',
+'group-bureaucrat-member'=> '{{int:group-bureaucrat}}',
+'grouppage-bot' => 'Project:{{int:group-bot}}',
+'grouppage-sysop' => 'Project:{{int:group-sysop}}',
+'grouppage-bureaucrat' => 'Project:{{int:group-bureaucrat}}',
+'changes' => '更新',
+'recentchanges' => '最近更新したページ',
+'recentchangestext' => '最近付け加えられた変更はこのページで確認できます。',
+'recentchanges-feed-description' => '最近付け加えられた変更はこのフィードで確認できます。',
+'rcnote' => '以下は $3 までの <strong>$2</strong> 日間に編集された <strong>$1</strong> ページです(<strong>{{int:newpageletter}}</strong>=新規項目、<strong>{{int:minoreditletter}}</strong>=細部の編集、<strong>{{int:boteditletter}}</strong>=ボットの編集、日時はオプションで未設定ならUTC)',
+'rcnotefrom' => '以下は <b>$2</b> までの更新です。(最大 <b>$1</b> 件)',
+'rclistfrom' => '$1以後現在までの更新を表示',
+'rcshowhideminor' => '細部の編集を$1',
+'rcshowhidebots' => 'ボットの編集を$1',
+'rcshowhideliu' => '登録利用者の編集を$1',
+'rcshowhideanons' => '匿名利用者の編集を$1',
+'rcshowhidepatr' => 'パトロールされた編集を$1',
+'rcshowhidemine' => '自分の編集を$1',
+'rclinks' => '最近 $2 日間の $1 件分を表示する<br />$3',
+'diff' => '差分',
+'hist' => '履歴',
+'hide' => '隠す',
+'show' => '表示',
+'minoreditletter' => 'M',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[$1人がウォッチしています]',
+'rc_categories' => 'カテゴリを制限("|" で区切る)',
+'rc_categories_any' => 'すべて',
+'upload' => 'アップロード',
+'uploadbtn' => 'アップロード',
+'reupload' => '再アップロード',
+'reuploaddesc' => 'アップロードのフォームへ戻る',
+'uploadnologin' => 'ログインしていません',
+'uploadnologintext' => 'ファイルをアップロードするには[[Special:Userlogin|ログイン]]する必要があります。',
+'upload_directory_read_only'=> 'アップロード先のディレクトリ ($1) にウェブサーバーが書き込めません。',
+'uploaderror' => 'アップロード エラー',
+'uploadtext' => 'ファイルを新しくアップロードする場合には、以下のフォームを利用してください。
+* 過去にアップロードされた画像は[[Special:Imagelist|{{int:imagelist}}]]で閲覧したり探したりできます。
+* アップロードや削除は[[Special:Log|ログ]]に記録されます。
+* 「{{int:uploadbtn}}」ボタンを押すと、アップロードが完了します。
+ページに画像を挿入するには
+* \'\'\'&#91;&#91;{{ns:image}}:File.jpg]]\'\'\'
+* \'\'\'&#91;&#91;{{ns:image}}:File.png|thumb|代替テキスト]]\'\'\'
+といった書式を使います。<br />画像ページではなくファイルに直接リンクするには
+* \'\'\'&#91;&#91;{{ns:media}}:File.ogg]]\'\'\'
+とします。',
+'uploadlog' => 'アップロードログ',
+'uploadlogpage' => 'アップロード記録',
+'uploadlogpagetext' => '以下は最近のファイルのアップロードのログです。',
+'filename' => 'ファイル名',
+'filedesc' => 'ファイルの概要',
+'fileuploadsummary' => 'ファイルの概要:',
+'filestatus' => '著作権情報',
+'filesource' => 'ファイルの出典',
+'copyrightpage' => 'Project:著作権',
+'copyrightpagename' => '{{SITENAME}}の著作権',
+'uploadedfiles' => 'アップロードされたファイル',
+'ignorewarning' => '警告を無視し、保存してしまう',
+'ignorewarnings' => '警告を無視',
+'minlength' => 'ファイル名は3文字以上である必要があります。',
+'illegalfilename' => 'ファイル名 "$1" にページ・タイトルとして使えない文字が含まれています。ファイル名を変更してからもう一度アップロードしてください。',
+'badfilename' => 'ファイル名は "$1" へ変更されました。',
+'badfiletype' => '".$1" は推奨されているファイルフォーマットではありません。',
+'large-file' => 'ファイルサイズは $1 バイト以下に抑えることが推奨されています。このファイルは $2 バイトです。',
+'largefileserver' => 'ファイルが大きすぎます。サーバー設定で許されている最大値を超過しました。',
+'emptyfile' => 'あなたがアップロードしようとしているファイルは内容が空であるか、もしくはファイル名の指定が間違っています。もう一度、ファイル名が正しいか、あるいはアップロードしようとしたファイルであるかどうかを確認してください。',
+'fileexists' => 'この名前のファイルは既に存在しています。$1と置き換えるかどうかお確かめください。',
+'fileexists-forbidden' => 'この名前のファイルは既に存在しています。前のページに戻り、別のファイル名でアップロードし直してください。
+[[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'この名前のファイルは共有リポジトリに既に存在しています。前のページに戻り、別のファイル名でアップロードし直してください。
+[[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'アップロード成功',
+'fileuploaded' => 'ファイル "$1" は無事にアップロードされました。
+
+画像詳細ページ $2 に行き、ファイルについての情報―出典、製作者や時期、その他知っている情報を書き込んでください。
+
+この画像をページに貼り付ける際にはページ内に <tt>&#91;&#91;{{ns:image}}:$1|thumb|画像の説明]]</tt> を挿入してください。',
+'uploadwarning' => 'アップロード 警告',
+'savefile' => 'ファイルを保存',
+'uploadedimage' => '"$1" をアップロードしました。',
+'uploaddisabled' => '申し訳ありませんが、アップロードは現在使用できません。',
+'uploaddisabledtext' => 'このウィキではファイルのアップロードは禁止されています。',
+'uploadscripted' => 'このファイルはウェブブラウザが誤って解釈してしまうおそれのあるHTMLまたはスクリプトコードを含んでいます。',
+'uploadcorrupt' => '指定したファイルは壊れているか拡張子が正しくありません。ファイルを確認の上再度アップロードをしてください。',
+'uploadvirus' => 'このファイルにはウイルスが含まれています!! &nbsp;詳細: $1',
+'sourcefilename' => 'ファイル名',
+'destfilename' => '掲載するファイル名',
+'watchthisupload' => '画像をウォッチ',
+'filewasdeleted' => 'アップロードしようとしているファイル名のファイルが以前削除されています。再びアップロードする前に $1 を確認してください。',
+
+'upload-proto-error' => '不正なプロトコル',
+'upload-proto-error-text' => 'アップロード元のURLは <code>http://</code> か <code>ftp://</code> で始まっている必要があります。',
+'upload-file-error' => '内部エラー',
+'upload-file-error-text'=> 'サーバーの内部エラーのため、一時ファイルの作成に失敗しました。システムの管理者に連絡してください。',
+'upload-misc-error' => '不明なエラー',
+'upload-misc-error-text'=> 'アップロード時に不明なエラーが検出されました。指定したURLがアクセス可能で有効なものであるかを再度確認してください。それでもこのエラーが発生する場合は、システムの管理者に連絡してください。',
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => 'URLに到達不能',
+'upload-curl-error6-text' => '指定したURLに到達できませんでした。URLが正しいものであるか、指定したサイトが現在使用可能かを再度確認してください。',
+'upload-curl-error28' => 'タイムアウト',
+'upload-curl-error28-text' => '相手サイトからの応答がありませんでした。指定したサイトが現在使用可能かを確認した上で、しばらく待ってもう一度お試しください。また、インターネットが混雑していない時間帯に実行することを推奨します。',
+
+'license' => 'ライセンス',
+'nolicense' => 'ライセンス情報を選択してください:',
+'upload_source_url' => '(インターネット上のURL)',
+'upload_source_file' => '(あなたのコンピューター上のファイル)',
+
+# Image list
+'imagelist' => '画像リスト',
+'imagelisttext' => '$1 枚の画像を $2 に表示しています',
+'imagelistforuser' => '$1 によってアップロードされた画像のみ表示しています。',
+'getimagelist' => '画像リストを取得',
+'ilsubmit' => '検索',
+'showlast' => '$2に $1 枚の画像を表示',
+'byname' => '名前順',
+'bydate' => '日付順',
+'bysize' => 'サイズ順',
+'imgdelete' => '削除',
+'imgdesc' => '詳細',
+'imgfile' => 'ファイル',
+'imglegend' => '凡例: (詳細)= 画像の詳細を表示/編集',
+'imghistory' => '画像の履歴',
+'revertimg' => '差戻',
+'deleteimg' => '削除',
+'deleteimgcompletely' => '全版削除',
+'imghistlegend' => '凡例:(最新)= 最新版の画像、(削除)= この版の画像を削除、(差戻)= この版の画像に差し戻す<br />
+<b>アップロードされた画像を見るには日付をクリックします。</b>',
+'imagelinks' => 'リンク',
+'linkstoimage' => 'この画像にリンクしているページの一覧:',
+'nolinkstoimage' => 'この画像にリンクしているページはありません。',
+'sharedupload' => 'このファイルは共有されており、他のプロジェクトで使用されている可能性があります。',
+'shareduploadwiki' => '詳しい情報は$1を参照してください。',
+'shareduploadwiki-linktext'=> 'ファイルの詳細ページ',
+'noimage' => 'このファイル名の画像はありません。$1。',
+'noimage-linktext' => 'このファイル名でアップロードする',
+'uploadnewversion-linktext'=> 'このファイルの新しいバージョンをアップロードする',
+'imagelist_date' => '日時',
+'imagelist_name' => '名前',
+'imagelist_user' => '利用者',
+'imagelist_size' => 'サイズ(バイト)',
+'imagelist_description' => '概要',
+'imagelist_search_for' => '画像名で検索:',
+
+# Mime search
+'mimesearch' => 'MIMEタイプ検索',
+'mimetype' => 'MIMEタイプ:',
+'download' => 'ダウンロード',
+
+'unwatchedpages' => 'ウォッチされていないページ',
+'listredirects' => 'リダイレクトの一覧',
+'unusedtemplates' => '使われていないテンプレート',
+'unusedtemplatestext' => 'このページでは {{ns:template}} 名前空間にあって他のページから使用されていないものを一覧にしています。削除する前にリンク元を確認してください。',
+'unusedtemplateswlh' => 'リンク元',
+'randomredirect' => 'おまかせリダイレクト',
+'statistics' => 'アクセス統計',
+'sitestats' => 'サイト全体の統計',
+'userstats' => '利用者登録統計',
+'sitestatstext' => 'データベース内には\'\'\'$1\'\'\'ページのデータがあります。この数字には「ノートページ」や「{{SITENAME}}関連のページ」、「書きかけのページ」、「リダイレクト」など、記事とはみなせないページが含まれています。これらを除いた、記事とみなされるページ数は約\'\'\'$2\'\'\'ページになります。
+
+\'\'\'$8\'\'\'個のファイルがアップロードされました。
+
+ページの総閲覧回数は\'\'\'$3\'\'\'回です。また、\'\'\'$4\'\'\'回の編集が行われました。平均すると、1ページあたり\'\'\'$5\'\'\'回の編集が行われ、1編集あたり\'\'\'$6\'\'\'回閲覧されています。
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue job queue] の長さは \'\'\'$7\'\'\' です。',
+'statistics-mostpopular'=> '最も閲覧されているページ',
+'userstatstext' => '登録済みの利用者は\'\'\'$1\'\'\'人で、内\'\'\'$2\'\'\'人 (\'\'\'$4%\'\'\') が$5権限を持っています。($3を参照)',
+'disambiguations' => '曖昧さ回避ページ',
+'disambiguationspage' => 'Template:aimai',
+'disambiguationstext' => '以下のページは<b>曖昧さ回避ページ</b>へリンクしています。これらのページはより適した主題のページへリンクされるべきです。<br />
+$1 にリンクしているページは曖昧さ回避ページと見なされます。',
+'doubleredirects' => '二重リダイレクト',
+'doubleredirectstext' => '以下はリダイレクトにリンクしているリダイレクトの一覧です。最も左のリダイレクトは二番目のリダイレクトが指している、恐らく「真に」リダイレクトしたいページを指すよう、変更されるべきです。',
+'brokenredirects' => '迷子のリダイレクト',
+'brokenredirectstext' => '以下は存在しないページにリンクしているリダイレクトです。',
+'nbytes' => '$1 バイト',
+'ncategories' => '$1 のカテゴリ',
+'nlinks' => '$1 個のリンク',
+'nmembers' => '$1 項目',
+'nrevisions' => '$1 の版',
+'nviews' => '$1 回表示',
+'lonelypages' => '孤立しているページ',
+'lonelypagestext' => '以下のページは、どこからもリンクされていない孤立したページです。',
+'uncategorizedpages' => 'カテゴリ未導入のページ',
+'uncategorizedcategories'=> 'カテゴリ未導入のカテゴリ',
+'uncategorizedimages' => 'カテゴリ未導入の画像',
+'unusedcategories' => '使われていないカテゴリ',
+'unusedimages' => '使われていない画像',
+'popularpages' => '人気のページ',
+'wantedcategories' => '作成が望まれているカテゴリ',
+'wantedpages' => '投稿が望まれているページ',
+'mostlinked' => '被リンクの多いページ',
+'mostlinkedcategories' => '項目の多いカテゴリ',
+'mostcategories' => 'カテゴリの多い項目',
+'mostimages' => 'リンクの多い画像',
+'mostrevisions' => '版の多い項目',
+'allpages' => '全ページ',
+'prefixindex' => '全ページ (ページ指定)',
+'randompage' => 'おまかせ表示',
+'shortpages' => '短いページ',
+'longpages' => '長いページ',
+'deadendpages' => '有効なページへのリンクがないページ',
+'deadendpagestext' => '以下のページは、このウィキの他のページにリンクしていないページです。',
+'listusers' => '登録利用者の一覧',
+'specialpages' => '特別ページ',
+'spheading' => '特別ページ',
+'restrictedpheading' => '制限のある特別ページ',
+'recentchangeslinked' => 'リンク先の更新状況',
+'rclsub' => '"$1" からリンクされているページ',
+'newpages' => '新しいページ',
+'newpages-username' => '利用者名:',
+'ancientpages' => '更新されていないページ',
+'intl' => '言語間リンク',
+'move' => '移動',
+'movethispage' => 'このページを移動',
+'unusedimagestext' => '<p>他のウェブサイトがURLを直接用いて画像にリンクしている場合もあります。以下の画像一覧には、そのような形で利用されている画像が含まれている可能性があります。</p>',
+'unusedcategoriestext' => '以下のカテゴリページはどの項目・カテゴリからも使われていません。',
+
+'categoriespagetext' => '{{SITENAME}}には以下のカテゴリが存在します。',
+'data' => 'データ',
+'userrights' => '利用者権限の管理',
+'groups' => 'ユーザーグループ',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1―$2',
+'version' => 'バージョン情報',
+'log' => 'ログ',
+'alllogstext' => 'アップロード、削除、保護、投稿ブロック、権限変更のログがまとめて表示されています。ログの種類、実行した利用者、影響を受けたページ(利用者)による絞り込みができます。',
+'logempty' => '条件にマッチする記録はありません。',
+
+# Book sources
+'booksources' => '文献資料',
+'booksources-search-legend' => '文献資料を検索',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => '検索',
+'booksources-text' => '以下のリストは、新本、古本などを販売している外部サイトへのリンクです。あなたがお探しの本について、更に詳しい情報が提供されている場合もあります。',
+
+
+# Special:Allpages
+'nextpage' => '次のページ($1)',
+'prevpage' => '前のページ($1)',
+'allpagesfrom' => '表示開始ページ:',
+'allarticles' => '全ページ',
+'allinnamespace' => '全ページ ($1 名前空間)',
+'allnotinnamespace' => '全ページ ($1 名前空間を除く)',
+'allpagesprev' => '前へ',
+'allpagesnext' => '次へ',
+'allpagessubmit' => '表示',
+'allpagesprefix' => '次の文字列から始まるページを表示:',
+'allpagesbadtitle' => '指定したタイトルは無効か、正しくない inter-language または inter-wiki のタイトルです。ページタイトルに使用できない文字が含まれている可能性があります。',
+
+# Special:Listusers
+'listusersfrom' => 'この文字から表示:',
+
+# E this user
+'mailnologin' => '送信先のアドレスがありません。',
+'mailnologintext' => '他の利用者宛てにメールを送信するためには、[[Special:Userlogin|ログイン]]し、あなたのメールアドレスを[[Special:Preference|オプション]]に設定する必要があります。',
+'emailuser' => 'この利用者にメールを送信',
+'emailpage' => 'メール送信ページ',
+'emailpagetext' => 'メールを送る先の利用者が有効なメールアドレスを{{int:preferences}}で登録していれば、下のフォームを通じてメールを送ることができます。
+あなたが登録したご自分のメールアドレスはFrom:の欄に自動的に組み込まれ、受け取った相手が返事を出せるようになっています。',
+'usermailererror' => 'メール送信時に以下のエラーが発生しました:',
+'defemailsubject' => '{{SITENAME}} (ja) e-mail',
+'noemailtitle' => '送り先のメールアドレスがありません。',
+'noemailtext' => 'この利用者は有効なメールアドレスを登録していないか、メールを受け取りたくないというオプションを選択しています。',
+'emailfrom' => 'あなたのアドレス',
+'emailto' => 'あて先',
+'emailsubject' => '題名',
+'emailmessage' => '本文',
+'emailsend' => 'メール送信',
+'emailccme' => '自分宛に控えを送信する',
+'emailccsubject' => '$1宛てウィキメールの控え: $2',
+'emailsent' => 'メールを送りました',
+'emailsenttext' => 'メールは無事送信されました。',
+
+# Watchlist
+'watchlist' => 'ウォッチリスト',
+'watchlistfor' => '\'\'\'$1\'\'\'',
+'nowatchlist' => 'あなたのウォッチリストは空です。',
+'watchlistanontext' => 'ウォッチリストを確認あるいは編集するには $1 してください。',
+'watchlistcount' => '\'\'\'あなたのウォッチリストにはノートも含めて $1 ページ登録されています。\'\'\'',
+'clearwatchlist' => 'ウォッチリストを消去する',
+'watchlistcleartext' => 'これらを削除してもよろしいですか?',
+'watchlistclearbutton' => 'ウォッチリストを消去',
+'watchlistcleardone' => 'あなたのウォッチリストを消去しました。$1 項目を消去しました。',
+'watchnologin' => 'ログインしていません',
+'watchnologintext' => 'ウォッチリストを変更するためには、[[Special:Userlogin|ログイン]]している必要があります。',
+'addedwatch' => 'ウォッチリストに追加しました',
+'addedwatchtext' => 'ページ "$1" をあなたの[[Special:Watchlist|ウォッチリスト]]に追加しました。
+
+このページと、付属のノートのページに変更があった際にはそれをウォッチリストで知ることができます。また、[[Special:Recentchanges|最近更新したページ]]ではウォッチリストに含まれているページは\'\'\'ボールド体\'\'\'で表示され、見つけやすくなります。
+
+ウォッチリストから特定のページを削除したい場合には、サイドバーかタブにある "{{int:unwatch}}" のリンクをクリックしてください。',
+'removedwatch' => 'ウォッチリストから削除しました',
+'removedwatchtext' => 'ページ "$1" をウォッチリストから削除しました。',
+'watch' => 'ウォッチリストに追加',
+'watchthispage' => 'ウォッチリストに追加',
+'unwatch' => 'ウォッチリストから削除',
+'unwatchthispage' => 'ウォッチリストから削除',
+'notanarticle' => 'これは記事ではありません。',
+'watchnochange' => 'その期間内にウォッチリストにあるページはどれも編集されていません。',
+'watchdetails' => '* ウォッチリストに入っているページ数(ノート除く): $1
+* [[Special:Watchlist/edit|ウォッチリストの一覧・編集]]',
+'wlheader-enotif' => '* メール通知が有効になっています',
+'wlheader-showupdated' => '* あなたが最後に訪問したあとに変更されたページは\'\'\'ボールド体\'\'\'で表示されます',
+'watchmethod-recent' => 'ウォッチリストの中から最近編集されたものを抽出',
+'watchmethod-list' => '最近編集された中からウォッチしているページを抽出',
+'removechecked' => 'チェックした項目をウォッチリストから削除',
+'watchlistcontains' => 'あなたのウォッチリストには $1 ページ登録されています。',
+'watcheditlist' => 'ウォッチリストに登録しているページを文字コード順に表示しています。
+チェックボックスにチェックし、「{{int:removechecked}}」ボタンをクリックするとウォッチリストから削除されます。
+
+* ウォッチリストからページを削除すると、付随するノートページも削除されます。',
+'removingchecked' => '要求された項目をウォッチリストから削除しています:',
+'couldntremove' => '"$1" をウォッチリストから削除できません。',
+'iteminvalidname' => '"$1" をウォッチリストから削除できません。ページ名が不正です。',
+'wlnote' => '以下は最近 <strong>$2</strong> 時間に編集された <strong>$1</strong> ページです。',
+'wlshowlast' => '最近の [$1時間] [$2日間] [$3] のものを表示する',
+'wlsaved' => '現在、バックアップされたウォッチリストのみの表示となっています。',
+'watchlist-show-bots' => 'ボットの編集を表示',
+'watchlist-hide-bots' => 'ボットの編集を隠す',
+'watchlist-show-own' => '自分の編集を表示',
+'watchlist-hide-own' => '自分の編集を隠す',
+'watchlist-show-minor' => '細部の編集を表示',
+'watchlist-hide-minor' => '細部の編集を隠す',
+'wldone' => '終了しました。',
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => 'ウォッチリストに追加しています...',
+'unwatching' => 'ウォッチリストから削除しています...',
+
+'enotif_mailer' => '{{SITENAME}} 通知メール',
+'enotif_reset' => 'すべてのページを訪問済みにする',
+'enotif_newpagetext' => '(新規ページ)',
+'changed' => '変更',
+'created' => '作成',
+'enotif_subject' => '{{SITENAME}} のページ "$PAGETITLE" が $PAGEEDITOR によって$CHANGEDORCREATEDされました',
+'enotif_lastvisited' => '
+あなたが最後に閲覧してからの差分を見るには以下のURLにアクセスしてください:
+$1',
+'enotif_body' => 'Dear $WATCHINGUSERNAME,
+
+{{SITENAME}}のページ $PAGETITLE が $PAGEEDITDATE に
+$PAGEEDITOR によって$CHANGEDORCREATEDされました。
+現在の版を見るには次のURLにアクセスしてください:
+$PAGETITLE_URL
+$NEWPAGE
+
+編集内容の要約: $PAGESUMMARY ($PAGEMINOREDIT)
+
+投稿者:
+メール: $PAGEEDITOR_EMAIL
+ウィキ: $PAGEEDITOR_WIKI
+
+あなたがこのページを訪れない限り、これ以上の通知は送信されません。
+ウォッチリストからすべての通知フラグをリセットすることもできます。
+
+ {{SITENAME}} 通知システム
+
+--
+ウォッチリストの設定を変更する:
+{{fullurl:Special:Watchlist/edit}}
+
+助けが必要ですか:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'ページを削除',
+'confirm' => '確認',
+'excontent' => '内容: \'$1\'',
+'excontentauthor' => '内容: \'$1\' (投稿者 $2 のみ)',
+'exbeforeblank' => '白紙化前の内容: \'$1\'',
+'exblank' => '白紙ページ',
+'confirmdelete' => '削除の確認',
+'deletesub' => '"$1" を削除',
+'historywarning' => '警告: 削除しようとしているページには履歴があります:',
+'confirmdeletetext' => '指定されたページまたは画像は、その変更履歴と共にデータベースから永久に削除されようとしています。あなたが削除を望んでおり、それがもたらす帰結を理解しており、かつあなたのしようとしていることが[[Project:方針|方針]]に即したものであることを確認してください。',
+'actioncomplete' => '完了しました',
+'deletedtext' => '"$1" は削除されました。最近の削除に関しては $2 を参照してください。',
+'deletedarticle' => '"$1" を削除しました。',
+'dellogpage' => '削除記録',
+'dellogpagetext' => '以下は最近の削除と復帰の記録です。',
+'deletionlog' => '削除記録',
+'reverted' => '以前のバージョンへの差し戻し (Reverted to earlier revision)',
+'deletecomment' => '削除の理由',
+'imagereverted' => '以前のバージョンへの差し戻しに成功しました。',
+'rollback' => '編集の差し戻し',
+'rollback_short' => '差し戻し',
+'rollbacklink' => '差し戻し',
+'rollbackfailed' => '差し戻しに失敗しました',
+'cantrollback' => '投稿者がただ一人であるため、編集を差し戻せません。',
+'alreadyrolled' => 'ページ [[:$1]] の [[User:$2|$2]] ([[User_talk:$2|会話]] | [[Special:Contributions/$2|履歴]]) による編集の差し戻しに失敗しました。誰か他の利用者が編集を行ったか差し戻しされたのかもしれません。
+
+このページの最後の編集は [[User:$3|$3]] ([[User_talk:$3|会話]] | [[Special:Contributions/$3|履歴]]) によるものです。',
+'editcomment' => '編集内容の要約: <i>$1</i>',
+'revertpage' => '$2 による編集を $1 による版へと差し戻しました。',
+'sessionfailure' => 'あなたのログイン・セッションに問題が発生しました。この動作はセッションハイジャックを防ぐために取り消されました。ブラウザの「戻る」を押してからページを再読込し、もう一度送信してください。',
+'protectlogpage' => '保護記録',
+'protectlogtext' => '以下はページの保護・保護解除の一覧です。詳細は[[{{ns:project}}:保護されたページ]]を参照してください。',
+'protectedarticle' => '"$1" を保護しました。',
+'unprotectedarticle' => '"$1" の保護を解除しました。',
+'protectsub' => '"$1" の保護',
+'confirmprotecttext' => '本当にこのページを保護しますか?',
+'confirmprotect' => '保護の確認',
+'protectmoveonly' => 'ページの移動のみを差し止める',
+'protectcomment' => '保護・保護解除の理由',
+'unprotectsub' => '"$1" の保護解除',
+'confirmunprotecttext' => '本当にこのページの保護を解除しますか?',
+'confirmunprotect' => '保護解除の確認',
+'unprotectcomment' => '保護解除の理由',
+'protect-unchain' => '移動権限を操作',
+'protect-text' => 'ページ "\'\'\'$1\'\'\'" の保護レベルを表示・操作できます。[[{{ns:project}}:保護の方針|保護の方針]]に従っていることを確認してください。',
+'protect-viewtext' => 'ページの保護は{{int:group-sysop}}のみが実行できます。<strong>$1</strong>の現在の保護状況を表示しています:',
+'protect-default' => '(解除)',
+'protect-level-autoconfirmed'=> '新規利用者と匿名利用者を禁止',
+'protect-level-sysop' => '{{int:group-sysop}}のみ',
+'restriction-edit' => '編集',
+'restriction-move' => '移動',
+'undelete' => '削除されたページを参照する',
+'undeletepage' => '削除された編集の参照と復帰',
+'viewdeletedpage' => '削除されたページの削除記録と履歴',
+'undeletepagetext' => '以下のページは削除されていますが、アーカイブに残っているため、復帰できます。アーカイブは定期的に消去されます。',
+'undeleteextrahelp' => '全ての版を復帰する場合は、全ての版のチェックボックスを選択していない状態で「{{int:undeletebtn}}」ボタンをクリックしてください。
+特定の版を復帰する場合は、復帰する版のチェックボックスを選択した状態で「{{int:undeletebtn}}」ボタンをクリックしてください。
+「{{int:undeletereset}}」ボタンををクリックするとコメント欄と全てのチェックボックスがクリアされます。',
+'undeletearticle' => '削除済みページの復帰',
+'undeleterevisions' => '$1版保管',
+'undeletehistory' => 'ページの復帰を行うと、通常は履歴にある全ての編集が復帰します。特定版の復帰を行う場合は、{{int:undeletebtn}}ボタンを押す前に復帰対象版のチェックボックスを選択してください。',
+'undeletehistorynoadmin'=> '過去にこのページの全てもしくは一部が削除されています。以下に示すのは削除記録と削除された版の履歴です。削除された各版の内容は{{int:group-sysop}}のみが閲覧できます。',
+'undeleterevision' => '削除された $1 の版',
+'undeleterevision-missing' => '無効、あるいは誤った版です。当該版は既に復帰されたか、アーカイブから削除された可能性があります。',
+'undeletebtn' => '復帰',
+'undeletereset' => 'リセット',
+'undeletecomment' => 'コメント:',
+'undeletedarticle' => '"$1" を復帰しました。',
+'undeletedrevisions' => '$1 版を復帰しました。',
+'undeletedrevisions-files'=> '$1 版のページと $2 ファイルを復帰しました',
+'undeletedfiles' => '$1 ファイルを復帰しました',
+'cannotundelete' => '復帰に失敗しました。誰かがすでにこのページを復帰しています。',
+'undeletedpage' => '<big>\'\'\'$1 を復帰しました。\'\'\'</big>
+
+最近の削除と復帰については[[Special:Log/delete|削除記録]]を参照してください。',
+'namespace' => '名前空間:',
+'invert' => '選択した名前空間を隠す',
+'contributions' => '利用者の投稿記録',
+'mycontris' => '自分の投稿記録',
+'contribsub' => '利用者名: $1',
+'nocontribs' => '利用者の投稿記録は見つかりませんでした。',
+'ucnote' => '利用者 <b>$1</b> によるここ <b>$2</b> 日間の編集です。',
+'uclinks' => '過去 $2 日間の $1 編集',
+'uctop' => '(最新)',
+'newbies' => '新規利用者',
+'sp-newimages-showfrom' => '$1 以後現在までの新着画像を表示',
+'sp-contributions-newest'=> '最新',
+'sp-contributions-oldest'=> '最古',
+'sp-contributions-newer'=> '前 $1',
+'sp-contributions-older'=> '次 $1',
+'sp-contributions-newbies-sub'=> '新規利用者',
+'sp-contributions-blocklog' => '投稿ブロック記録',
+'whatlinkshere' => 'リンク元',
+'notargettitle' => '対象となるページが存在しません',
+'notargettext' => '対象となるページ又は利用者が指定されていません',
+'linklistsub' => 'リンクの一覧',
+'linkshere' => '[[:$1]] は以下のページからリンクされています',
+'nolinkshere' => '[[:$1]] にリンクしているページはありません。',
+'isredirect' => 'リダイレクトページ',
+'istemplate' => 'テンプレート呼出',
+
+# Block/unblock IP
+'blockip' => '投稿ブロック',
+'blockiptext' => '指定した利用者やIPアドレスからの投稿をブロックすることができます。投稿ブロックは荒らしを防ぐためであり、[[Project:方針|{{SITENAME}}の方針]]に従っているべきです。明確な理由を以下に記入してください(例えば、荒らされたページを引用する)。',
+'ipaddress' => 'IPアドレス',
+'ipadressorusername' => '利用者名 / IPアドレス',
+'ipbexpiry' => '期間',
+'ipbreason' => '理由',
+'ipbsubmit' => '投稿ブロックする',
+'ipbother' => '期間 (その他のとき)',
+'ipboptions' => '15分:15 minutes,30分:30 minutes,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',
+'ipbotheroption' => 'その他',
+'ipbanononly' => '匿名利用者のみブロック',
+'ipbcreateaccount' => 'アカウント作成をブロック',
+'ipbenableautoblock' => 'この利用者が最後に使用したIPアドレスを自動的にブロック(ブロック後に使用したIPアドレスも含む)',
+'badipaddress' => 'IPアドレスが異常です。',
+'blockipsuccesssub' => 'ブロックに成功しました。',
+'blockipsuccesstext' => '利用者またはIPアドレス "$1" の投稿をブロックしました。<br />
+[[Special:Ipblocklist|{{int:ipblocklist}}]]で確認できます。',
+'unblockip' => '投稿ブロックを解除する',
+'unblockiptext' => '以下のフォームで利用者またはIPアドレスの投稿ブロックを解除できます。',
+'ipusubmit' => '投稿ブロックを解除する',
+'unblocked' => '[[User:$1|$1]] の投稿ブロックを解除しました',
+'ipblocklist' => '投稿ブロック中の利用者やIPアドレス',
+'blocklistline' => '$1, $2 は $3 をブロック ($4)',
+'infiniteblock' => '無期限',
+'expiringblock' => '$1 に解除',
+'anononlyblock' => '匿名のみ',
+'noautoblockblock' => '自動ブロックなし',
+'createaccountblock' => 'アカウント作成のブロック',
+'ipblocklistempty' => '{{int:ipblocklist}}はありません。',
+'blocklink' => 'ブロック',
+'unblocklink' => 'ブロック解除',
+'contribslink' => '投稿記録',
+'autoblocker' => '投稿ブロックされている利用者 "$1" と同じIPアドレスのため、自動的にブロックされています。ブロックの理由は "$2" です。',
+'blocklogpage' => '投稿ブロック記録',
+'blocklogentry' => '"$1" を $2 ブロックしました',
+'blocklogtext' => 'このページは投稿ブロックと解除の記録です。自動的に投稿ブロックされたIPアドレスは記録されていません。現時点で有効な投稿ブロックは[[Special:Ipblocklist|{{int:ipblocklist}}]]をご覧ください。',
+'unblocklogentry' => '"$1" をブロック解除しました',
+'range_block_disabled' => '広域ブロックは無効に設定されています。',
+'ipb_expiry_invalid' => '不正な期間です。',
+'ip_range_invalid' => '不正なIPアドレス範囲です。',
+'proxyblocker' => 'プロクシブロッカー',
+'ipb_already_blocked' => '"$1" は既にブロックされています。',
+'ipb_cant_unblock' => 'エラー: ブロックされた ID $1 が見つかりません。おそらく既にブロック解除されています。',
+'proxyblockreason' => 'Your IP address has been blocked because it is an open proxy. Please contact your Internet service provider or tech support and inform them of this serious security problem.
+
+:あなたの使用しているIPアドレスはオープン・プロクシであるため投稿ブロックされています。あなたのインターネット・サービス・プロバイダ、もしくは技術担当者に連絡を取り、これが深刻なセキュリティ問題であることを伝えてください。',
+'proxyblocksuccess' => '終了しました。',
+'sorbs' => 'DNSBL',
+'sorbsreason' => 'あなたのIPアドレスはオープンプロクシであると、[http://www.sorbs.net/ SORBS] DNSBLに掲載されています。',
+'sorbs_create_account_reason' => 'あなたのIPアドレスがオープンプロクシであると、[http://www.sorbs.net/ SORBS] DNSBLに掲載されているため、アカウントを作成できません。',
+
+# Developer tools
+'lockdb' => 'データベースのロック',
+'unlockdb' => 'データベースのロック解除',
+'lockdbtext' => 'データベースをロックすると全ての利用者はページを編集できなくなり、オプションを変更できなくなり、ウォッチリストを編集できなくなるなど、データベースに書き込む全ての作業ができなくなります。本当にデータベースをロックして良いかどうか確認してください。メンテナンスが終了したらロックを解除してください。',
+'unlockdbtext' => 'データベースのロックを解除することで利用者はページを編集できるようになり、オプションを変更できるようになり、ウォッチリストを編集できるようになるなど、データベースに書き込む全ての作業ができるようになります。本当にデータベースのロックを解除していいかどうか確認してください。',
+'lockconfirm' => '本当にデータベースをロックする',
+'unlockconfirm' => 'ロックを解除する',
+'lockbtn' => 'ロック',
+'unlockbtn' => 'ロック解除',
+'locknoconfirm' => 'チェックボックスにチェックされていません。',
+'lockdbsuccesssub' => 'データベースはロックされました。',
+'unlockdbsuccesssub' => 'データベースのロックは解除されました',
+'lockdbsuccesstext' => 'データベースをロックしました。メンテナンスが終了したら忘れずにロックを解除してください。',
+'unlockdbsuccesstext' => 'データベースのロックは解除されました。',
+'lockfilenotwritable' => 'データベースのロックファイルに書き込めません。データベースのロック・解除をするには、サーバー上のロックファイルに書き込める必要があります。',
+'databasenotlocked' => 'データベースはロックされていません。',
+
+# Make sysop
+'makesysoptitle' => '{{int:Makesysop}}',
+'makesysoptext' => 'このフォームは通常の利用者を{{int:group-sysop}}にするために使用します。{{int:group-sysop}}にする利用者名を入力し、{{int:Makesysopsubmit}}ボタンを押してください。',
+'makesysopname' => '利用者名:',
+'makesysopsubmit' => 'この利用者を{{int:group-sysop}}にする',
+'makesysopok' => '<b>利用者 "$1" を{{int:group-sysop}}にしました。</b>',
+'makesysopfail' => '<b>利用者 "$1" を{{int:group-sysop}}にできませんでした。利用者名を正しく入力していたかどうか確認してください。</b>',
+'setbureaucratflag' => '“{{int:group-bureaucrat}}” フラグをセット',
+'rightslog' => '権限変更記録',
+'rightslogtext' => '以下は利用者権限変更の一覧です。',
+'rightslogentry' => '$1 の権限を $2 から $3 へ変更しました。',
+'rights' => '権限:',
+'set_user_rights' => '利用者権限の設定',
+'user_rights_set' => '<b>利用者 "$1" の権限が更新されました</b>',
+'set_rights_fail' => '<b>利用者 "$1" の権限を設定できませんでした。利用者名を正しく入力していたかどうか確認してください。</b>',
+'makesysop' => '利用者を{{int:group-sysop}}にする',
+'already_sysop' => '利用者は既に{{int:group-sysop}}です。',
+'already_bureaucrat' => '利用者は既に{{int:group-bureaucrat}}です。',
+'rightsnone' => '(権限なし)',
+
+# Move page
+#
+'movepage' => 'ページの移動',
+'movepagetext' => '下のフォームを利用すると、ページ名を変更し、その履歴も変更先へ移動することができます。古いページは変更先へのリダイレクトページとなります。ページの中身と変更前のページに張られたリンクは変わりません。ですから、二重になったり壊れてしまったリダイレクトをチェックする必要があります。
+
+変更先がすでに存在する場合には、履歴が移動元ページへのリダイレクトただ一つである場合を除いて、移動できません。つまり、間違えてページ名を変更した場合には元に戻せます。
+
+よく閲覧されるページや、他の多くのページからリンクされているページを移動すると予期せぬ結果が起こるかもしれません。ページの移動に伴う影響をよく考えてから踏み切るようにしてください。',
+'movepagetalktext' => '付随するノートのページがある場合には、基本的には、一緒に移動されることになります。
+
+但し、以下の場合については別です。
+*名前空間をまたがる移動の場合
+*移動先に既に履歴のあるノートページが存在する場合
+*下のチェックボックスのチェックマークを消した場合
+
+これらの場合、ノートページを移動する場合には、別に作業する必要があります。',
+'movearticle' => '移動するページ',
+'movenologin' => 'ログインしていません',
+'movenologintext' => 'ページを移動するためには、アカウント作成の上、[[Special:Userlogin|ログイン]]している必要があります。',
+'newtitle' => '新しいページ名',
+'move-watch' => '移動するページをウォッチ',
+'movepagebtn' => 'ページを移動',
+'pagemovedsub' => '無事移動しました。',
+'pagemovedtext' => 'ページ "[[$1]]" は "[[$2]]" に移動しました。',
+'articleexists' => '指定された移動先には既にページが存在するか、名前が不適切です。',
+'talkexists' => 'ページ自身は移動されましたが、付随のノートページは移動先のページが存在したため移動できませんでした。手動で内容を統合してください。',
+'movedto' => '移動先:',
+'movetalk' => 'ノートページが付随する場合には、それも一緒に移動する',
+'talkpagemoved' => '付随のノートのページも移動しました。',
+'talkpagenotmoved' => '付随のノートのページは<strong>移動されませんでした。</strong>',
+'1movedto2' => 'ページ [[$1]] を [[$2]] へ移動',
+'1movedto2_redir' => 'ページ [[$1]] をこのページあてのリダイレクト [[$2]] へ移動',
+'movelogpage' => '移動記録',
+'movelogpagetext' => '以下はページ移動の記録です。',
+'movereason' => '理由',
+'revertmove' => '差し戻し',
+'delete_and_move' => '削除して移動する',
+'delete_and_move_text' => '== 削除が必要です ==
+移動先 "[[$1]]" は既に存在しています。このページを移動のために削除しますか?',
+'delete_and_move_confirm'=> 'ページ削除の確認',
+'delete_and_move_reason'=> '移動のための削除',
+'selfmove' => '移動元と移動先のページ名が同じです。自分自身へは移動できません。',
+'immobile_namespace' => '移動先のページ名は特別なページです。その名前空間にページを移動することはできません。',
+'export' => 'ページデータの書き出し',
+'exporttext' => 'ここでは単独のまたは複数のページのテキストと編集履歴をXMLの形で書き出すことができます。書き出されたXML文書は他のMediaWikiで動いているウィキに取り込んだり、変換したり、個人的な楽しみに使ったりできます。
+
+ページデータを書き出すには下のテキストボックスに書き出したいページのタイトルを一行に一ページずつ記入してください。また編集履歴とともに全ての古い版を含んで書き出すのか、最新版のみを書き出すのか選択してください。
+
+後者のケースではリンクの形で使うこともできます。例: [[メインページ]]の最新版を取得するには[[Special:Export/メインページ]]を使用します。',
+'exportcuronly' => 'すべての履歴を含ませずに、最新版のみを書き出す',
+'exportnohistory' => '\'\'\'お知らせ:\'\'\' パフォーマンス上の理由により、このフォームによるページの完全な履歴の書き出しは行えません。',
+'export-submit' => '書き出し',
+'allmessages' => '表示メッセージの一覧',
+'allmessagesname' => 'メッセージ名',
+'allmessagesdefault' => '既定の文章',
+'allmessagescurrent' => '現在の文章',
+'allmessagestext' => 'これは{{ns:mediawiki}}名前空間にある全てのシステムメッセージの一覧です。',
+'allmessagesnotsupportedUI'=> 'このサイトでは、あなたの現在のインターフェース言語 <b>$1</b> における {{ns:special}}:Allmessages はサポートされていません。',
+'allmessagesnotsupportedDB'=> 'wgUseDatabaseMessages が無効のため、[[Special:Allmessages]] はサポートされません。',
+'allmessagesfilter' => 'メッセージ名フィルタ:',
+'allmessagesmodified' => '条件に当てはまるものを表示',
+'thumbnail-more' => '拡大',
+'missingimage' => '<b>以下の画像が見つかりません。</b><br /><i>$1</i>',
+'filemissing' => '<i>ファイルがありません</i>',
+'thumbnail_error' => 'サムネイルの作成中にエラーが発生しました: $1',
+
+# Special:Import
+'import' => 'ページデータの取り込み',
+'importinterwiki' => 'Transwikiインポート',
+'import-interwiki-text' => 'インポートするウィキとページ名を選択してください。変更履歴の日付と編集者が保存されます。すべてのtranswikiは[[Special:Log/import|インポート記録]]に記録されます。',
+'import-interwiki-history'=> 'このページの全ての版を複製する',
+'import-interwiki-submit'=> '取り込み',
+'import-interwiki-namespace' => 'Transfer pages into namespace:',
+'importtext' => '元となるウィキから {{ns:special}}:Export を使ってXMLファイルを書き出し、ここでアップロードしてください。',
+'importstart' => 'ページを取り込んでいます...',
+'import-revision-count' => '$1 版',
+'importnopages' => 'インポートするページがありません',
+'importfailed' => '取り込みに失敗しました: $1',
+'importunknownsource' => 'インポートするソースのファイルタイプが不明です',
+'importcantopen' => 'インポートするファイルを開けません',
+'importbadinterwiki' => 'interwiki リンクが正しくありません',
+'importnotext' => '内容が空か、テキストがありません。',
+'importsuccess' => '取り込みに成功しました。',
+'importhistoryconflict' => '取り込み時にいくつかの版が競合しました(以前に同じページを取り込んでいませんか)。',
+'importnosources' => 'Transwikiの読み込み元が定義されていないため、履歴の直接アップロードは無効になっています。',
+'importnofile' => 'ファイルがアップロードされませんでした',
+'importuploaderror' => 'ファイルの取り込みに失敗しました。恐らく、許可されている最大ファイルサイズより大きなファイルをアップロードしようとしています。',
+
+# import log
+'importlogpage' => 'インポート記録',
+'importlogpagetext' => '以下は管理者による他ウィキからのページデータの取り込み記録です。',
+'import-logentry-upload'=> 'ファイルのアップロードにより [[$1]] をインポートしました',
+'import-logentry-upload-detail'=> '$1 版',
+'import-logentry-interwiki'=> '$1 をtranswikiしました',
+'import-logentry-interwiki-detail'=> '$2 の $1 版',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'ウィキ内を検索 [alt-f]',
+'tooltip-minoredit' => 'この編集を細部の変更とマーク [alt-i]',
+'tooltip-save' => '編集を保存します。 [alt-s]',
+'tooltip-preview' => '編集結果を確認します。保存前に是非使用してください。 [alt-p]',
+'tooltip-diff' => 'あなたが編集した版の変更点を表示します。[alt-v]',
+'tooltip-compareselectedversions'=> '選択された二つの版の差分を表示します。 [alt-v]',
+'tooltip-watch' => 'このページをウォッチリストへ追加します。 [alt-w]',
+'common.css' => '/* ここに書いた CSS は全ての外装に反映されます */',
+'monobook.css' => '/* このページを編集するとサイト全体での外装 monobook のカスタマイズになります */
+#bodyContent { font-size:118% }',
+'nodublincore' => 'このサーバーでは Dublin Core RDF メタデータが許可されていません。',
+'nocreativecommons' => 'このサーバーではクリエイティブ・コモンズの RDF メタデータが許可されていません。',
+'notacceptable' => 'ウィキサーバーはあなたの使用しているクライアントが読める形式で情報を提供できません。',
+'anonymous' => '{{SITENAME}}の匿名利用者',
+'siteuser' => '{{SITENAME}}の利用者$1',
+'lastmodifiedatby' => '最終更新は $3 による $2, $1 の編集です。',
+'and' => 'および',
+'othercontribs' => '$1の版に基づきます。',
+'others' => 'その他の利用者',
+'siteusers' => '{{SITENAME}}の利用者$1',
+'creditspage' => 'ページ・クレジット',
+'nocredits' => 'このページには有効なクレジット情報がありません。',
+'spamprotectiontitle' => 'スパム防御フィルター',
+'spamprotectiontext' => 'あなたが保存しようとしたページはスパム・フィルターによって保存をブロックされました。これは主に外部サイトへのリンクが原因です。',
+'spamprotectionmatch' => '以下はスパム・フィルターによって検出されたテキストです: $1',
+'subcategorycount' => 'このカテゴリには $1 のサブカテゴリがあります。',
+'categoryarticlecount' => 'このカテゴリには $1 のページがあります。',
+'category-media-count' => 'このカテゴリには $1 のファイルがあります。',
+'listingcontinuesabbrev'=> ' の続き',
+'spambot_username' => 'MediaWiki スパム除去',
+'spam_reverting' => '$1 へのリンクを含まない以前の版に差し戻し',
+'spam_blanking' => 'すべての版から $1 へのリンクを削除',
+
+# Info page
+'infosubtitle' => 'ページ情報',
+'numedits' => '編集数(項目): $1',
+'numtalkedits' => '編集数(ノート): $1',
+'numwatchers' => 'ウォッチしている利用者数: $1',
+'numauthors' => '投稿者数(項目): $1',
+'numtalkauthors' => '投稿者数(ノート): $1',
+
+# Math options
+'mw_math_png' => '常にPNG',
+'mw_math_simple' => 'シンプルな数式はHTML、それ以外はPNG',
+'mw_math_html' => 'できる限りHTML、さもなければPNG',
+'mw_math_source' => 'TeXのままにする (テキストブラウザ向け)',
+'mw_math_modern' => '最近のブラウザで推奨',
+'mw_math_mathml' => '可能ならばMathMLを使う (実験中の機能)',
+
+# Patrolling
+'markaspatrolleddiff' => 'パトロール済みにする',
+'markaspatrolledtext' => 'この項目をパトロール済みにする',
+'markedaspatrolled' => 'パトロール済みにしました。',
+'markedaspatrolledtext' => '選択された編集をパトロール済みにしました。',
+'rcpatroldisabled' => 'RCパトロールが無効です',
+'rcpatroldisabledtext' => '最近更新されたページのパトロール機能は現在無効になっています。',
+'markedaspatrollederror'=> 'パトロール済みにできません。',
+'markedaspatrollederrortext' => 'パトロール済みにするためにはどの版かを指定する必要があります。',
+'markedaspatrollederror-noautopatrol' => '自分自身による編集をパトロール済みにする権限がありません。',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'自分の利用者ページ\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'あなたのIPアドレス用の利用者ページ\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'自分の会話ページ\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'あなたのIPアドレスからなされた編集の会話ページ\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'オプションの変更\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'変更を監視しているページの一覧\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'自分の投稿記録\');
+ ta[\'pt-login\'] = new Array(\'o\',\'ログインすることが推奨されますが、しなくても構いません。\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'ログインすることが推奨されますが、しなくても構いません。\');
+ ta[\'pt-logout\'] = new Array(\'\',\'ログアウト\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'項目のノート\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'このページを編集できます。投稿の前に「{{int:showpreview}}」ボタンを使ってください。\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'このページにコメントを加える\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'このページは保護されています。ページのソースを閲覧できます。\');
+ ta[\'ca-history\'] = new Array(\'h\',\'このページの過去の版\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'このページを保護\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'このページを削除\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'削除されたページを復帰する\');
+ ta[\'ca-move\'] = new Array(\'m\',\'このページを移動\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'このページをウォッチリストに追加\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'このページをウォッチリストから外す\');
+ ta[\'p-search\'] = new Array(\'f\',\'ウィキ内を検索\');
+ ta[\'p-logo\'] = new Array(\'\',\'メインページ\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'メインページに移動\');
+ ta[\'n-portal\'] = new Array(\'\',\'このプロジェクトについて、あなたのできることを探す場所です\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'最近の出来事\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'最近更新が行われたページの一覧\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'ランダムに記事を選んで表示\');
+ ta[\'n-help\'] = new Array(\'\',\'ヘルプ・使い方\');
+ ta[\'n-villagepump\'] = new Array(\'\',\'プロジェクトについての意見交換や告知\');
+ ta[\'n-contact\'] = new Array(\'\',\'ウィキペディアやウィキメディア財団に関する連絡先\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'私たちをサポートしてください\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'このページにリンクしているページの一覧\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'最近更新が行われたこのページのリンク先\');
+ ta[\'feed-rss\'] = new Array(\'\',\'このページのRSSフィード\');
+ ta[\'feed-atom\'] = new Array(\'\',\'このページのAtomフィード\');
+ ta[\'t-contributions\'] = new Array(\'\',\'利用者の投稿記録\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'{{int:emailuser}}\');
+ ta[\'t-upload\'] = new Array(\'u\',\'画像やメディアファイルをアップロード\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'特別ページの一覧\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'本文を表示\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'利用者ページを表示\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'メディアページを表示\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'これは特別ページです。編集することはできません。\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'プロジェクトページを表示\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'画像ページを表示\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'インターフェースを表示\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'テンプレートを表示\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'ヘルプページを表示\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'カテゴリページを表示\');',
+
+'common.js' => '/* ここに書いたスクリプトは全ての外装に反映されます */',
+
+'deletedrevision' => '古い版 $1 を削除しました。',
+'previousdiff' => '←前の差分',
+'nextdiff' => '次の差分→',
+'imagemaxsize' => '画像ページで表示する画像の最大サイズ:',
+'thumbsize' => 'サムネイルの大きさ:',
+'showbigimage' => '高解像度版をダウンロードする ($1x$2, $3 KB)',
+'newimages' => '新着画像ギャラリー',
+'showhidebots' => '(ボットを$1)',
+'noimages' => '画像がありません。',
+'variantname-zh-cn' => '簡体(中国)',
+'variantname-zh-tw' => '正字(台湾)',
+'variantname-zh-hk' => '正字(香港)',
+'variantname-zh-sg' => '簡体(シンガポール)',
+'variantname-zh' => '無変換',
+'specialloguserlabel' => '利用者名:',
+'speciallogtitlelabel' => 'タイトル:',
+'passwordtooshort' => 'パスワードが短すぎます。$1文字以上の文字列にしてください。',
+'mediawarning' => '\'\'\'警告:\'\'\' このファイルは悪意のあるコードを含んでいる可能性があり、実行するとコンピューターが危害を被る場合があります。
+----',
+'fileinfo' => '$1KB, MIMEタイプ: <code>$2</code>',
+'metadata' => 'メタデータ',
+'metadata-help' => 'このファイルはデジタルカメラ・スキャナなどが付加した追加情報を含んでいます。このファイルがオリジナルの状態から変更されている場合、いくつかの項目は変更を完全に反映していないかもしれません。',
+'metadata-expand' => '拡張項目を表示',
+'metadata-collapse' => '拡張項目を隠す',
+'metadata-fields' => 'ここに挙げたEXIF情報のフィールドのみが標準で表示されます。
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+'exif-imagewidth' => '画像の幅',
+'exif-imagelength' => '画像の高さ',
+'exif-bitspersample' => 'ビット深度',
+'exif-compression' => '圧縮形式',
+'exif-photometricinterpretation'=> '画素構成',
+'exif-orientation' => '画像方向',
+'exif-samplesperpixel' => 'コンポーネント数',
+'exif-planarconfiguration'=> 'データ格納形式',
+'exif-ycbcrsubsampling' => 'YCCの画素構成(Cの間引き率)',
+'exif-ycbcrpositioning' => 'YCCの画素構成(YとCの位置)',
+'exif-xresolution' => '水平解像度',
+'exif-yresolution' => '垂直解像度',
+'exif-resolutionunit' => '解像度の単位',
+'exif-stripoffsets' => '画像データの場所',
+'exif-rowsperstrip' => 'ストリップのライン数',
+'exif-stripbytecounts' => 'ストリップのデータ量',
+'exif-jpeginterchangeformat'=> 'JPEGのSOIへのオフセット',
+'exif-jpeginterchangeformatlength'=> 'JPEGデータのバイト数',
+'exif-transferfunction' => '再生階調カーブ特性',
+'exif-whitepoint' => '参照白色点の色度座標値',
+'exif-primarychromaticities'=> '原色の色度座標値',
+'exif-ycbcrcoefficients'=> '色変換マトリックス係数',
+'exif-referenceblackwhite'=> '参照黒色点値・参照白色点値',
+'exif-datetime' => 'ファイル変更日時',
+'exif-imagedescription' => '画像の説明',
+'exif-make' => '画像入力機器のメーカー',
+'exif-model' => '画像入力機器の機種',
+'exif-software' => 'ファームウェアのバージョン',
+'exif-artist' => '作成者',
+'exif-copyright' => '著作権者',
+'exif-exifversion' => 'Exifバージョン',
+'exif-flashpixversion' => '対応フラッシュピックスバージョン',
+'exif-colorspace' => '色空間',
+'exif-componentsconfiguration'=> '各コンポーネントの構成',
+'exif-compressedbitsperpixel'=> '画像圧縮モード',
+'exif-pixelydimension' => '実効画像幅',
+'exif-pixelxdimension' => '実効画像高さ',
+'exif-makernote' => 'メーカーノート',
+'exif-usercomment' => 'ユーザーコメント',
+'exif-relatedsoundfile' => '関連音声ファイル',
+'exif-datetimeoriginal' => '画像データ生成日時',
+'exif-datetimedigitized'=> 'デジタルデータ作成日時',
+'exif-subsectime' => 'ファイル変更日時 (秒未満)',
+'exif-subsectimeoriginal'=> '画像データ生成日時 (秒未満)',
+'exif-subsectimedigitized'=> 'デジタルデータ作成日時 (秒未満)',
+'exif-exposuretime' => '露出時間',
+'exif-exposuretime-format'=> '$1秒 ($2)',
+'exif-fnumber' => 'F値',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' => '露出プログラム',
+'exif-spectralsensitivity'=> 'スペクトル感度',
+'exif-isospeedratings' => 'ISOスピードレート',
+'exif-oecf' => '光電変換関数',
+'exif-shutterspeedvalue'=> 'シャッタースピード',
+'exif-aperturevalue' => '絞り値',
+'exif-brightnessvalue' => '明るさ',
+'exif-exposurebiasvalue'=> '露出補正値',
+'exif-maxaperturevalue' => 'レンズ最小F値',
+'exif-subjectdistance' => '被写体距離',
+'exif-meteringmode' => '測光方式',
+'exif-lightsource' => '光源',
+'exif-flash' => 'フラッシュ',
+'exif-focallength' => 'レンズの焦点距離',
+'exif-focallength-format' => '$1 mm',
+'exif-subjectarea' => '主要被写体の位置',
+'exif-flashenergy' => 'フラッシュ強度',
+'exif-spatialfrequencyresponse'=> '空間周波数応答',
+'exif-focalplanexresolution'=> '水平方向の焦点面解像度',
+'exif-focalplaneyresolution'=> '垂直方向の焦点面解像度',
+'exif-focalplaneresolutionunit'=> '焦点面解像度の単位',
+'exif-subjectlocation' => '被写体の場所',
+'exif-exposureindex' => '露出インデックス',
+'exif-sensingmethod' => 'センサー方式',
+'exif-filesource' => 'ファイルソース',
+'exif-scenetype' => 'シーンタイプ',
+'exif-cfapattern' => 'CFAパターン',
+'exif-customrendered' => '画像処理',
+'exif-exposuremode' => '露出モード',
+'exif-whitebalance' => 'ホワイトバランス',
+'exif-digitalzoomratio' => 'デジタルズーム倍率',
+'exif-focallengthin35mmfilm'=> 'レンズの焦点距離(35mmフィルム換算)',
+'exif-scenecapturetype' => '被写体の種別',
+'exif-gaincontrol' => 'ゲインコントロール',
+'exif-contrast' => 'コントラスト',
+'exif-saturation' => '彩度',
+'exif-sharpness' => 'シャープネス',
+'exif-devicesettingdescription'=> '機器設定',
+'exif-subjectdistancerange'=> '被写体距離の範囲',
+'exif-imageuniqueid' => 'ユニーク画像ID',
+'exif-gpsversionid' => 'GPSタグのバージョン',
+'exif-gpslatituderef' => '北緯/南緯',
+'exif-gpslatitude' => '緯度',
+'exif-gpslongituderef' => '東経/西経',
+'exif-gpslongitude' => '経度',
+'exif-gpsaltituderef' => '高度の基準',
+'exif-gpsaltitude' => '高度',
+'exif-gpstimestamp' => 'GPS時刻(原子時計)',
+'exif-gpssatellites' => '測位に用いた衛星信号',
+'exif-gpsstatus' => 'GPS受信機の状態',
+'exif-gpsmeasuremode' => 'GPS測位方法',
+'exif-gpsdop' => '測位精度',
+'exif-gpsspeedref' => '速度の単位',
+'exif-gpsspeed' => '速度',
+'exif-gpstrackref' => '進行方向の基準',
+'exif-gpstrack' => '進行方向',
+'exif-gpsimgdirectionref'=> '撮影方向の基準',
+'exif-gpsimgdirection' => '撮影方向',
+'exif-gpsmapdatum' => '測地系',
+'exif-gpsdestlatituderef'=> '目的地の北緯/南緯',
+'exif-gpsdestlatitude' => '目的地の緯度',
+'exif-gpsdestlongituderef'=> '目的地の東経/西経',
+'exif-gpsdestlongitude' => '目的地の経度',
+'exif-gpsdestbearingref'=> '目的地の方角の基準',
+'exif-gpsdestbearing' => '目的地の方角',
+'exif-gpsdestdistanceref'=> '目的地までの距離の単位',
+'exif-gpsdestdistance' => '目的地までの距離',
+'exif-gpsprocessingmethod'=> 'GPS処理方法',
+'exif-gpsareainformation'=> 'GPSエリア名',
+'exif-gpsdatestamp' => 'GPS測位日時',
+'exif-gpsdifferential' => 'ディファレンシャル補正',
+
+'exif-compression-1' => '非圧縮',
+'exif-compression-6' => 'JPEG圧縮',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => '通常',
+'exif-orientation-2' => '左右反転',
+'exif-orientation-3' => '180°回転',
+'exif-orientation-4' => '上下反転',
+'exif-orientation-5' => '反時計回りに90°回転 上下反転',
+'exif-orientation-6' => '時計回りに90°回転',
+'exif-orientation-7' => '時計回りに90°回転 上下反転',
+'exif-orientation-8' => '反時計回りに90°回転',
+
+'exif-planarconfiguration-1'=> '点順次フォーマット',
+'exif-planarconfiguration-2'=> '面順次フォーマット',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h'=> 'その他',
+
+'exif-componentsconfiguration-0' => 'なし',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0'=> '未定義',
+'exif-exposureprogram-1'=> 'マニュアル',
+'exif-exposureprogram-2'=> 'ノーマルプログラム',
+'exif-exposureprogram-3'=> '露出優先',
+'exif-exposureprogram-4'=> 'シャッター速度優先',
+'exif-exposureprogram-5'=> 'クリエイティブ・プログラム',
+'exif-exposureprogram-6'=> 'アクション・プログラム',
+'exif-exposureprogram-7'=> 'ポートレイトモード(近景)',
+'exif-exposureprogram-8'=> 'ランドスケープモード(遠景)',
+
+'exif-subjectdistance-value'=> '$1 メートル',
+
+'exif-meteringmode-0' => '不明',
+'exif-meteringmode-1' => '平均',
+'exif-meteringmode-2' => '中央重点',
+'exif-meteringmode-3' => 'スポット',
+'exif-meteringmode-4' => 'マルチスポット',
+'exif-meteringmode-5' => '分割測光',
+'exif-meteringmode-6' => '部分測光',
+'exif-meteringmode-255' => 'その他',
+'exif-lightsource-0' => '不明',
+'exif-lightsource-1' => '昼光',
+'exif-lightsource-2' => '蛍光灯',
+'exif-lightsource-3' => 'タングステン(白熱灯)',
+'exif-lightsource-4' => 'フラッシュ',
+'exif-lightsource-9' => '晴天',
+'exif-lightsource-10' => '曇天',
+'exif-lightsource-11' => '日陰',
+'exif-lightsource-12' => '昼光色蛍光灯 (D 5700 - 7100K)',
+'exif-lightsource-13' => '昼白色蛍光灯 (N 4600 - 5400K)',
+'exif-lightsource-14' => '白色蛍光灯 (W 3900 - 4500K)',
+'exif-lightsource-15' => '温白色蛍光灯 (WW 3200 - 3700K)',
+'exif-lightsource-17' => '標準光A',
+'exif-lightsource-18' => '標準光B',
+'exif-lightsource-19' => '標準光C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISOスタジオタングステン',
+'exif-lightsource-255' => 'その他',
+
+'exif-focalplaneresolutionunit-2'=> 'インチ',
+
+'exif-sensingmethod-1' => '未定義',
+'exif-sensingmethod-2' => '単板カラーセンサー',
+'exif-sensingmethod-3' => '2板カラーセンサー',
+'exif-sensingmethod-4' => '3板カラーセンサー',
+'exif-sensingmethod-5' => '色順次カラーセンサー',
+'exif-sensingmethod-7' => '3線リニアセンサー',
+'exif-sensingmethod-8' => '色順次リニアセンサー',
+'exif-filesource-3' => 'デジタルスチルカメラ',
+'exif-scenetype-1' => '直接撮影された画像',
+'exif-customrendered-0' => '通常',
+'exif-customrendered-1' => 'カスタム',
+'exif-exposuremode-0' => '自動',
+'exif-exposuremode-1' => 'マニュアル',
+'exif-exposuremode-2' => 'オートブラケット',
+'exif-whitebalance-0' => '自動',
+'exif-whitebalance-1' => 'マニュアル',
+'exif-scenecapturetype-0'=> '標準',
+'exif-scenecapturetype-1'=> '風景',
+'exif-scenecapturetype-2'=> '人物',
+'exif-scenecapturetype-3'=> '夜景',
+'exif-gaincontrol-0' => 'なし',
+'exif-gaincontrol-1' => '弱増感',
+'exif-gaincontrol-2' => '強増感',
+'exif-gaincontrol-3' => '弱減感',
+'exif-gaincontrol-4' => '強増感',
+'exif-contrast-0' => '標準',
+'exif-contrast-1' => '軟調',
+'exif-contrast-2' => '硬調',
+'exif-saturation-0' => '標準',
+'exif-saturation-1' => '低彩度',
+'exif-saturation-2' => '高彩度',
+'exif-sharpness-0' => '標準',
+'exif-sharpness-1' => '弱',
+'exif-sharpness-2' => '強',
+'exif-subjectdistancerange-0'=> '不明',
+'exif-subjectdistancerange-1'=> 'マクロ',
+'exif-subjectdistancerange-2'=> '近景',
+'exif-subjectdistancerange-3'=> '遠景',
+'exif-gpslatitude-n' => '北緯',
+'exif-gpslatitude-s' => '南緯',
+'exif-gpslongitude-e' => '東経',
+'exif-gpslongitude-w' => '西経',
+'exif-gpsstatus-a' => '測位中',
+'exif-gpsstatus-v' => '未測位',
+'exif-gpsmeasuremode-2' => '2次元測位',
+'exif-gpsmeasuremode-3' => '3次元測位',
+'exif-gpsspeed-k' => 'キロメートル毎時',
+'exif-gpsspeed-m' => 'マイル毎時',
+'exif-gpsspeed-n' => 'ノット',
+'exif-gpsdirection-t' => '真方位',
+'exif-gpsdirection-m' => '磁方位',
+'edit-externally' => '外部アプリケーションを使ってこのファイルを編集する',
+'edit-externally-help' => '詳しい情報は[http://meta.wikimedia.org/wiki/Help:External_editors 外部エディタに関する説明(英語)]をご覧ください。',
+'recentchangesall' => 'すべて',
+'imagelistall' => 'すべて',
+'watchlistall1' => 'すべて',
+'watchlistall2' => 'すべて',
+'namespacesall' => 'すべて',
+'confirmemail' => 'メールアドレスの確認',
+'confirmemail_noemail' => '[[{{ns:special}}:Preferences|オプション設定]]で有効なメールアドレスが指定されていません。',
+'confirmemail_text' => 'このウィキではメール通知を受け取る前にメールアドレスの確認が必要です。以下のボタンを押すと「{{int:Confirmemail_subject}}」という件名の確認メールがあなたのメールアドレスに送られます。メールには確認用コードを含むリンクが書かれています。そのリンクを開くことによってメールアドレスの正当性が確認されます。',
+'confirmemail_pending' => '<div class="error">
+確認メールは既に送信されています。あなたがこのアカウントを作成したばかりであれば、数分待って既にメールが送信されていないかを確かめてください。
+</div>',
+'confirmemail_send' => '確認用コードを送信する',
+'confirmemail_sent' => '確認メールを送信しました。',
+'confirmemail_sendfailed'=> '確認メールを送信できませんでした。メールアドレスに不正な文字が含まれていないかどうか確認してください。
+
+メールサーバーからの返答: $1',
+'confirmemail_invalid' => '確認用コードが正しくありません。このコードは期限切れです。',
+'confirmemail_needlogin'=> 'メールアドレスを確認するために$1が必要です。',
+'confirmemail_oncreate' => 'メールアドレスの正当性を確認するためのコードを含んだメールを送信しました。この確認を行わなくてもログインはできますが、確認するまでメール通知の機能は無効化されます。',
+'confirmemail_success' => 'あなたのメールアドレスは確認されました。ログインしてウィキを使用できます。',
+'confirmemail_loggedin' => 'あなたのメールアドレスは確認されました。',
+'confirmemail_error' => 'あなたの確認を保存する際に内部エラーが発生しました。',
+'confirmemail_subject' => '{{SITENAME}} メールアドレスの確認',
+'confirmemail_body' => 'This is a E-mail confirmation of *{{SITENAME}}*.
+If you can not read this message below,
+you can not read wikimail either.
+Then, please change a mailer
+or address which can read UTF-8 mail, and retry.
+Thank you.
+
+--
+
+どなたか(IPアドレス $1 の使用者)がこのメールアドレスを
+{{SITENAME}} のアカウント "$2" に登録しました。
+
+このアカウントがあなたのものであるか確認してください。
+あなたの登録したアカウントであるならば、{{SITENAME}}
+のメール通知機能を有効にするために、以下のURLにアクセスしてください:
+
+$3
+
+もし {{SITENAME}} について身に覚えがない場合は、リンクを開かないでください。
+確認用コードは $4 に期限切れになります。
+
+--
+{{SITENAME}}
+{{SERVER}}/',
+'tryexact' => '一致する項目を検索',
+'searchfulltext' => '全文検索',
+'createarticle' => '項目を作成',
+'scarytranscludedisabled'=> '[Interwiki transcluding は無効になっています]',
+'scarytranscludefailed' => '[テンプレート $1 の取得に失敗しました]',
+'scarytranscludetoolong'=> '[URLが長すぎます]',
+'trackbackbox' => '<div id="mw_trackbacks">
+この項目へのトラックバック:
+$1
+</div>',
+'trackbackremove' => ' ([$1 削除])',
+'trackbacklink' => 'トラックバック',
+'trackbackdeleteok' => 'トラックバックを削除しました。',
+'deletedwhileediting' => '\'\'\'警告:\'\'\' このページはあなたが編集し始めた後、削除されました!!',
+'confirmrecreate' => 'あなたがこのページを編集し始めた後に、このページは[[User:$1|$1]] ([[User_talk:$1|会話]]) によって削除されました。その理由は次の通りです:
+:$2
+このままこのページを新規作成して良いか確認してください。',
+'recreate' => '新規作成する',
+'tooltip-recreate' => 'このままこのページを新規作成する',
+
+'unit-pixel' => 'px',
+
+'redirectingto' => '[[$1]]へ転送しています...',
+'confirm_purge' => 'ページのキャッシュを破棄します。よろしいですか?
+
+$1',
+'confirm_purge_button' => 'はい',
+'youhavenewmessagesmulti'=> '$1 に新しいメッセージが届いています',
+'searchcontaining' => '\'\'\'$1\'\'\' を含むページの検索。',
+'searchnamed' => 'ページ名が \'\'\'$1\'\'\' の項目の検索。',
+'articletitles' => '\'\'$1\'\' からはじまる項目',
+'hideresults' => '結果を隠す',
+'loginlanguagelabel' => '言語: $1',
+
+'displaytitle' => '(このページへリンクするには [[$1]] を使用)',
+
+# Multipage image navigation
+# 使用ページ例: http://commons.wikimedia.org/wiki/Image:Drei_Register_Arithmetischer_ahnfeng_zur_Practic.djvu
+'imgmultipageprev' => '&larr; 前ページ',
+'imgmultipagenext' => '次ページ &rarr;',
+'imgmultigo' => '表示',
+'imgmultigotopre' => '',
+'imgmultigotopost' => 'ページ目を',
+
+# Table pager
+'ascending_abbrev' => '昇順',
+'descending_abbrev' => '降順',
+'table_pager_next' => '次のページ',
+'table_pager_prev' => '前のページ',
+'table_pager_first' => '最初のページ',
+'table_pager_last' => '最後のページ',
+'table_pager_limit' => '1ページに $1 個表示',
+'table_pager_limit_submit' => '実行',
+'table_pager_empty' => '結果なし',
+
+# Auto-summaries
+'autosumm-blank' => 'ページの白紙化',
+'autosumm-replace' => 'ページの置換: \'$1\'',
+'autoredircomment' => '[[$1]]へのリダイレクト',
+'autosumm-new' => '新しいページ: \'$1\'',
+
+# Size units
+'size-bytes' => '$1 バイト',
+'size-kilobytes' => '$1 キロバイト',
+'size-megabytes' => '$1 メガバイト',
+'size-gigabytes' => '$1 ギガバイト',
+
+);
+?>
diff --git a/languages/messages/MessagesJbo.php b/languages/messages/MessagesJbo.php
new file mode 100644
index 000000000000..a65b8f5d472e
--- /dev/null
+++ b/languages/messages/MessagesJbo.php
@@ -0,0 +1,24 @@
+<?php
+/** Lojban (Lojban)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$messages = array(
+
+'1movedto2' => 'le pu se cmene lu [[$1]] li\'u cu ca se cmene lu [[$2]] li\'u',
+'categories' => 'klesi',
+'pagecategories' => '{{PLURAL:$1|klesi|klesi}}',
+'currentevents' => 'nuzba ckupau',
+'currentevents-url' => 'nuzba ckupau',
+'help' => 'sidju ckupau',
+'mainpage' => 'ralju ckupau',
+'movedto' => 'te muvdu',
+'pagemovedtext' => '[[$1]] te muvdu [[$2]] le vreji',
+'portal' => 'bende ckupau',
+'randompage' => 'cunso ckupau'
+
+);
+
+?>
diff --git a/languages/messages/MessagesJv.php b/languages/messages/MessagesJv.php
new file mode 100644
index 000000000000..45899f69f2ee
--- /dev/null
+++ b/languages/messages/MessagesJv.php
@@ -0,0 +1,45 @@
+<?php
+/** Javanese (Basa Jawa)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Niklas Laxström
+ *
+ * @copyright Copyright © 2006, Niklas Laxström
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+$fallback = 'id';
+
+$quickbarSettings = array(
+ 'Ora ana', 'Tetep sisih kiwa', 'Tetep sisih tengen', 'Ngambang sisih kiwa'
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Astamiwa',
+ NS_MAIN => '',
+ NS_TALK => 'Dhiskusi',
+ NS_USER => 'Panganggo',
+ NS_USER_TALK => 'Dhiskusi_Panganggo',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Dhiskusi_$1',
+ NS_IMAGE => 'Gambar',
+ NS_IMAGE_TALK => 'Dhiskusi_Gambar',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Dhiskusi_MediaWiki',
+ NS_TEMPLATE => 'Cithakan',
+ NS_TEMPLATE_TALK => 'Dhiskusi_Cithakan',
+ NS_HELP => 'Pitulung',
+ NS_HELP_TALK => 'Dhiskusi_Pitulung',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Dhiskusi_Kategori'
+);
+
+$namespaceAliases = array(
+ 'Gambar_Dhiskusi' => NS_IMAGE_TALK,
+ 'MediaWiki_Dhiskusi' => NS_MEDIAWIKI_TALK,
+ 'Cithakan_Dhiskusi' => NS_TEMPLATE_TALK,
+ 'Pitulung_Dhiskusi' => NS_HELP_TALK,
+ 'Kategori_Dhiskusi' => NS_CATEGORY_TALK,
+);
+?>
diff --git a/languages/messages/MessagesKa.php b/languages/messages/MessagesKa.php
new file mode 100644
index 000000000000..2aa3cfe473c3
--- /dev/null
+++ b/languages/messages/MessagesKa.php
@@ -0,0 +1,575 @@
+<?php
+/** Georgian (ქართული)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$namespaceNames = array(
+ NS_MEDIA => 'მედია',
+ NS_SPECIAL => 'სპეციალური',
+ NS_MAIN => '',
+ NS_TALK => 'განხილვა',
+ NS_USER => 'მომხმარებელი',
+ NS_USER_TALK => 'მომხმარებელი_განხილვა',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_განხილვა',
+ NS_IMAGE => 'სურათი',
+ NS_IMAGE_TALK => 'სურათი_განხილვა',
+ NS_MEDIAWIKI => 'მედიავიკი',
+ NS_MEDIAWIKI_TALK => 'მედიავიკი_განხილვა',
+ NS_TEMPLATE => 'თარგი',
+ NS_TEMPLATE_TALK => 'თარგი_განხილვა',
+ NS_HELP => 'დახმარება',
+ NS_HELP_TALK => 'დახმარება_განხილვა',
+ NS_CATEGORY => 'კატეგორია',
+ NS_CATEGORY_TALK => 'კატეგორია_განხილვა'
+);
+
+$linkPrefixExtension = true;
+
+$linkTrail = '/^([a-zაბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰ“»]+)(.*)$/sDu';
+
+$messages = array(
+
+# User preference toggles
+
+# Dates
+'sunday' => 'კვირა',
+'monday' => 'ორშაბათი',
+'tuesday' => 'სამშაბათი',
+'wednesday' => 'ოთხშაბათი',
+'thursday' => 'ხუთშაბათი',
+'friday' => 'პარასკევი',
+'saturday' => 'შაბათი',
+'sun' => 'კვი',
+'mon' => 'ორშ',
+'tue' => 'სამ',
+'wed' => 'ოთხ',
+'thu' => 'ხუთ',
+'fri' => 'პარ',
+'sat' => 'შაბ',
+'january' => 'იანვარი',
+'february' => 'თებერვალი',
+'march' => 'მარტი',
+'april' => 'აპრილი',
+'may_long' => 'მაისი',
+'june' => 'ივნისი',
+'july' => 'ივლისი',
+'august' => 'აგვისტო',
+'september' => 'სექტემბერი',
+'october' => 'ოქტომბერი',
+'november' => 'ნოემბერი',
+'december' => 'დეკემბერი',
+'january-gen' => 'იანვრის',
+'february-gen' => 'თებერვლის',
+'march-gen' => 'მარტის',
+'april-gen' => 'აპრილის',
+'may-gen' => 'მაისის',
+'june-gen' => 'ივნისის',
+'july-gen' => 'ივლისის',
+'august-gen' => 'აგვისტოს',
+'september-gen' => 'სექტემბრის',
+'october-gen' => 'ოქტომბრის',
+'november-gen' => 'ნოემბრის',
+'december-gen' => 'დეკემბრის',
+'jan' => 'იან',
+'feb' => 'თებ',
+'mar' => 'მარ',
+'apr' => 'აპრ',
+'may' => 'მაი',
+'jun' => 'ივნ',
+'jul' => 'ივლ',
+'aug' => 'აგვ',
+'sep' => 'სექ',
+'oct' => 'ოქტ',
+'nov' => 'ნოე',
+'dec' => 'დეკ',
+
+# Bits of text used by many pages:
+'categories' => 'კატეგორიები',
+'pagecategories' => '{{PLURAL:$1|კატეგორია|კატეგორიები}}',
+'category_header' => 'სტატიები კატეგორიაში "$1"',
+'subcategories' => 'ქვეკატეგორიები',
+
+
+'linkprefix' => '/^(.*?)(„|«)$/sD',
+'mainpage' => 'მთავარი გვერდი',
+#TODO: 'mainpagetext' => "<big>'''MediaWiki has been successfully installed.'''</big>",
+/*TODO: 'mainpagedocfooter' => "Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
+
+== Getting started ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]",*/
+
+'portal' => 'საზოგადოების პორტალი',
+'portal-url' => 'პროექტი:საზოგადოების პორტალი',
+'about' => 'შესახებ',
+#TODO: 'aboutsite' => 'About {{SITENAME}}',
+'aboutpage' => 'პროექტი:შესახებ',
+'article' => 'სტატია',
+'help' => 'დახმარება',
+#TODO: 'helppage' => 'Help:Contents',
+#TODO: 'bugreports' => 'Bug reports',
+#TODO: 'bugreportspage' => 'Project:Bug_reports',
+#TODO: 'sitesupport' => 'Donations',
+#TODO: 'sitesupport-url' => 'Project:Site support',
+#TODO: 'faq' => 'FAQ',
+#TODO: 'faqpage' => 'Project:FAQ',
+#TODO: 'edithelp' => 'Editing help',
+'newwindow' => '(ახალ ფანჯარაში)',
+#TODO: 'edithelppage' => 'Help:Editing',
+'cancel' => 'გაუქმება',
+#TODO: 'qbfind' => 'Find',
+#TODO: 'qbbrowse' => 'Browse',
+'qbedit' => 'რედაქტირება',
+'qbpageoptions' => 'ეს გვერდი',
+'qbpageinfo' => 'კონტექსტი',
+'qbmyoptions' => 'ჩემი გვერდები',
+'qbspecialpages' => 'სპეციალური გვერდები',
+#TODO: 'moredotdotdot' => 'More...',
+'mypage' => 'ჩემი გვერდი',
+'mytalk' => 'ჩემი განხილვა',
+#TODO: 'anontalk' => 'Talk for this IP',
+#TODO: 'navigation' => 'Navigation',
+
+# Metadata in edit box
+#'metadata_help' => 'Metadata (see [[{{ns:project}}:Metadata]] for an explanation):',
+
+#'currentevents' => 'Current events',
+#'currentevents-url' => 'Current events',
+
+#'disclaimers' => 'Disclaimers',
+#'disclaimerpage' => 'Project:General_disclaimer',
+#'privacy' => 'Privacy policy',
+#'privacypage' => 'Project:Privacy_policy',
+#'errorpagetitle' => 'Error',
+#'returnto' => 'Return to $1.',
+#'tagline' => 'From {{SITENAME}}',
+'help' => 'დახმარება',
+#'search' => 'Search',
+#'searchbutton' => 'Search',
+#'go' => 'Go',
+'history' => 'გვერდის ისტორია',
+'history_short' => 'ისტორია',
+#'updatedmarker' => 'updated since my last visit',
+#'info_short' => 'Information',
+#'printableversion' => 'Printable version',
+#'permalink' => 'Permanent link',
+#'print' => 'Print',
+'edit' => 'რედაქტირება',
+'editthispage' => 'ამ გვერდის რედაქტირება',
+'delete' => 'წაშლა',
+'deletethispage' => 'ამ გვერდის წაშლა',
+#'undelete_short' => 'Undelete {{PLURAL:$1|one edit|$1 edits}}',
+#'protect' => 'Protect',
+#'protectthispage' => 'Protect this page',
+#'unprotect' => 'unprotect',
+#'unprotectthispage' => 'Unprotect this page',
+#'newpage' => 'New page',
+#'talkpage' => 'Discuss this page',
+#'specialpage' => 'Special Page',
+#'personaltools' => 'Personal tools',
+#'postcomment' => 'Post a comment',
+#'articlepage' => 'View content page',
+#'talk' => 'Discussion',
+#'views' => 'Views',
+#'toolbox' => 'Toolbox',
+#'userpage' => 'View user page',
+#'projectpage' => 'View project page',
+#'imagepage' => 'View image page',
+#'mediawikipage' => 'View message page',
+#'templatepage' => 'View template page',
+#'viewhelppage' => 'View help page',
+#'categorypage' => 'View category page',
+#'viewtalkpage' => 'View discussion',
+#'otherlanguages' => 'In other languages',
+#'redirectedfrom' => '(Redirected from $1)',
+#'autoredircomment' => 'Redirecting to [[$1]]',
+#'redirectpagesub' => 'Redirect page',
+#'lastmodifiedat' => 'This page was last modified $2, $1.', //$1 date, $2 time
+#'viewcount' => 'This page has been accessed {{plural:$1|one time|$1 times}}.',
+#'copyright' => 'Content is available under $1.',
+#'protectedpage' => 'Protected page',
+#'jumpto' => 'Jump to:',
+#'jumptonavigation' => 'navigation',
+#'jumptosearch' => 'search',
+
+#'badaccess' => 'Permission error',
+#'badaccess-group0' => 'You are not allowed to execute the action you have requested.',
+#'badaccess-group1' => 'The action you have requested is limited to users in the group $1.',
+#'badaccess-group2' => 'The action you have requested is limited to users in one of the groups $1.',
+#'badaccess-groups' => 'The action you have requested is limited to users in one of the groups $1.',
+
+#'versionrequired' => 'Version $1 of MediaWiki required',
+#'versionrequiredtext' => 'Version $1 of MediaWiki is required to use this page. See [[Special:Version]]',
+
+#'widthheight' => '$1×$2',
+#'ok' => 'OK',
+#'sitetitle' => '{{SITENAME}}',
+#'pagetitle' => '$1 - {{SITENAME}}',
+#'sitesubtitle' => '',
+#'retrievedfrom' => 'Retrieved from "$1"',
+'youhavenewmessages' => 'თქვენ გაქვთ $1 ($2).',
+#'newmessageslink' => 'new messages',
+#'newmessagesdifflink' => 'diff to penultimate revision',
+'editsection'=>'რედაქტირება',
+'editold'=>'რედაქტირება',
+'editsectionhint' => 'სექციის რედაქტირება: $1',
+#'toc' => 'Contents',
+#'showtoc' => 'show',
+#'hidetoc' => 'hide',
+#'thisisdeleted' => 'View or restore $1?',
+'viewdeleted' => 'იხილე $1?',
+#'restorelink' => '{{PLURAL:$1|one deleted edit|$1 deleted edits}}',
+#'feedlinks' => 'Feed:',
+#'feed-invalid' => 'Invalid subscription feed type.',
+#'sitenotice' => '-', # the equivalent to wgSiteNotice
+#'anonnotice' => '-',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'სტატია',
+'nstab-user' => 'მომხმარებლის გვერდი',
+'nstab-media' => 'მედია',
+'nstab-special' => 'სპეციალური',
+'nstab-project' => 'პროექტის გვერდი',
+'nstab-image' => 'ფაილი',
+'nstab-mediawiki' => 'შეტყობინება',
+'nstab-template' => 'თარგი',
+'nstab-help' => 'დახმარება',
+'nstab-category' => 'კატეგორია',
+
+# Main script and global functions
+
+# General errors
+
+# Login and logout pages
+
+# Edit page toolbar
+
+# Edit pages
+
+# History pages
+
+# Revision deletion
+
+# Diffs
+'difference' => '(სხვაობა ვერსიებს შორის)',
+#TODO: 'loadingrev' => 'loading revision for diff',
+'lineno' => "ხაზი $1:",
+'editcurrent' => 'ამ გვერდის ამჟამინდელი ვერსიის რედაქტირება',
+#TODO: 'selectnewerversionfordiff' => 'Select a newer version for comparison',
+#TODO: 'selectolderversionfordiff' => 'Select an older version for comparison',
+'compareselectedversions' => 'არჩეული ვერსიების შედარება',
+
+# Search results
+
+# Preferences page
+'preferences' => 'კონფიგურაცია',
+'mypreferences' => 'ჩემი კონფიგურაცია',
+#TODO: 'prefsnologin' => 'Not logged in',
+#TODO: 'prefsnologintext' => "You must be [[Special:Userlogin|logged in]] to set user preferences.",
+#TODO: 'prefsreset' => 'Preferences have been reset from storage.',
+#TODO: 'qbsettings' => 'Quickbar',
+'changepassword' => 'პაროლის შეცვლა',
+#TODO: 'skin' => 'Skin',
+#TODO: 'math' => 'Math',
+'dateformat' => 'თარიღის ფორმატი',
+#TODO: 'datedefault' => 'No preference',
+'datetime' => 'თარიღი და დრო',
+#TODO: 'math_failure' => 'Failed to parse',
+#TODO: 'math_unknown_error' => 'unknown error',
+#TODO: 'math_unknown_function' => 'unknown function',
+#TODO: 'math_lexing_error' => 'lexing error',
+#TODO: 'math_syntax_error' => 'syntax error',
+#TODO: 'math_image_error' => 'PNG conversion failed; check for correct installation of latex, dvips, gs, and convert',
+#TODO: 'math_bad_tmpdir' => 'Can\'t write to or create math temp directory',
+#TODO: 'math_bad_output' => 'Can\'t write to or create math output directory',
+#TODO: 'math_notexvc' => 'Missing texvc executable; please see math/README to configure.',
+'prefs-personal' => 'მომხმარებლის მონაცემები',
+#TODO: 'prefs-rc' => 'Recent changes',
+'prefs-watchlist' => 'კონტროლის სია',
+#TODO: 'prefs-watchlist-days' => 'Number of days to show in watchlist:',
+#TODO: 'prefs-watchlist-edits' => 'Number of edits to show in expanded watchlist:',
+#TODO: 'prefs-misc' => 'Misc',
+'saveprefs' => 'შენახვა',
+'resetprefs' => 'გადატვირთვა',
+'oldpassword' => 'ძველი პაროლი:',
+'newpassword' => 'ახალი პაროლი:',
+#TODO: 'retypenew' => 'Retype new password:',
+#TODO: 'textboxsize' => 'Editing',
+#TODO: 'rows' => 'Rows:',
+#TODO: 'columns' => 'Columns:',
+#TODO: 'searchresultshead' => 'Search',
+#TODO: 'resultsperpage' => 'Hits per page:',
+#TODO: 'contextlines' => 'Lines per hit:',
+#TODO: 'contextchars' => 'Context per line:',
+#TODO: 'stubthreshold' => 'Threshold for stub display:',
+#TODO: 'recentchangescount' => 'Titles in recent changes:',
+'savedprefs' => 'თქვენს მიერ შერჩეული პარამეტრები დამახსოვრებულია.',
+#TODO: 'timezonelegend' => 'Time zone',
+#TODO: 'timezonetext' => 'The number of hours your local time differs from server time (UTC).',
+#TODO: 'localtime' => 'Local time',
+#TODO: 'timezoneoffset' => 'Offset¹',
+#TODO: 'servertime' => 'Server time',
+#TODO: 'guesstimezone' => 'Fill in from browser',
+#TODO: 'allowemail' => 'Enable e-mail from other users',
+'defaultns' => 'სტანდარტული ძიება ამ სახელთა სივრცეებში:',
+'default' => 'სტანდარტული',
+'files' => 'ფაილები',
+
+# User rights
+
+# Groups
+'group' => 'ჯგუფი:',
+'group-bot' => 'რობოტები',
+'group-sysop' => 'ადმინისტრატორები',
+'group-bureaucrat' => 'ბიუროკრატები',
+'group-all' => '(ყველა)',
+
+'group-bot-member' => 'რობოტი',
+'group-sysop-member' => 'ადმინისტრატორი',
+'group-bureaucrat-member' => 'ბიუროკრატი',
+
+'grouppage-bot' => '{{ns:project}}:რობოტები',
+'grouppage-sysop' => '{{ns:project}}:ადმინისტრატორები',
+'grouppage-bureaucrat' => '{{ns:project}}:ბიუროკრატები',
+
+# Recent changes
+'changes' => 'ცვლილებები',
+'recentchanges' => 'ბოლო ცვლილებები',
+#TODO: 'recentchanges-url' => 'Special:Recentchanges',
+#TODO: 'recentchangestext' => 'Track the most recent changes to the wiki on this page.',
+#TODO: 'rcnote' => "Below are the last <strong>$1</strong> changes in the last <strong>$2</strong> days, as of $3.",
+#TODO: 'rcnotefrom' => "Below are the changes since <b>$2</b> (up to <b>$1</b> shown).",
+'rclistfrom' => "ახალი ცვლილებების ჩვენება დაწყებული $1-დან",
+'rcshowhideminor' => 'მცირე რედაქტირების $1',
+'rcshowhidebots' => 'რობოტების $1',
+'rcshowhideliu' => 'რეგისტრირებული მომხმარებლების $1',
+'rcshowhideanons' => 'ანონიმური მომხმარებლების $1',
+#TODO: 'rcshowhidepatr' => '$1 patrolled edits',
+'rcshowhidemine' => 'ჩემი რედაქტირების $1',
+'rclinks' => "ბოლო $1 ცვლილების ჩვენება უკანასკნელი $2 დღის მანძილზე<br />$3",
+'diff' => 'განსხ.',
+'hist' => 'ისტ.',
+'hide' => 'დამალვა',
+'show' => 'ჩვენება',
+'minoreditletter' => 'მ',
+'newpageletter' => 'ა',
+'boteditletter' => 'რ',
+'sectionlink' => '→',
+#TODO: 'number_of_watching_users_RCview' => '[$1]',
+#TODO: 'number_of_watching_users_pageview' => '[$1 watching user/s]',
+#TODO: 'rc_categories' => 'Limit to categories (separate with "|")',
+#TODO: 'rc_categories_any' => 'Any',
+
+# Upload
+
+# Image list
+'imagelist' => 'ფაილების სია',
+#TODO: 'imagelisttext' => "Below is a list of '''$1''' {{plural:$1|file|files}} sorted $2.",
+#TODO: 'imagelistforuser' => "This shows only images uploaded by $1.",
+#TODO: 'getimagelist' => 'fetching file list',
+#TODO: 'ilsubmit' => 'Search',
+#TODO: 'showlast' => 'Show last $1 files sorted $2.',
+#TODO: 'byname' => 'by name',
+#TODO: 'bydate' => 'by date',
+#TODO: 'bysize' => 'by size',
+'imgdelete' => 'წაშ.',
+'imgdesc' => 'აღწ.',
+'imgfile' => 'ფაილი',
+#TODO: 'imglegend' => 'Legend: (desc) = show/edit file description.',
+'imghistory' => 'ფაილის ისტორია',
+#TODO: 'revertimg' => 'rev',
+'deleteimg' => 'წაშ.',
+#TODO: 'deleteimgcompletely' => 'Delete all revisions of this file',
+/*TODO: 'imghistlegend' => 'Legend: (cur) = this is the current file, (del) = delete
+this old version, (rev) = revert to this old version.
+<br /><i>Click on date to see the file uploaded on that date</i>.',*/
+'imagelinks' => 'ბმულები',
+#TODO: 'linkstoimage' => 'The following pages link to this file:',
+#TODO: 'nolinkstoimage' => 'There are no pages that link to this file.',
+#TODO: 'sharedupload' => 'This file is a shared upload and may be used by other projects.',
+#TODO: 'shareduploadwiki' => 'Please see the $1 for further information.',
+#TODO: 'shareduploadwiki-linktext' => 'file description page',
+#TODO: 'shareddescriptionfollows' => '-',
+#TODO: 'noimage' => 'No file by this name exists, you can $1.',
+#TODO: 'noimage-linktext' => 'upload it',
+#TODO: 'uploadnewversion-linktext' => 'Upload a new version of this file',
+'imagelist_date' => 'თარიღი',
+'imagelist_name' => 'სახელი',
+'imagelist_user' => 'მომხმარებელი',
+#TODO: 'imagelist_size' => 'ზომა (ბაიტები)',
+'imagelist_description' => 'აღწერილობა',
+'imagelist_search_for' => 'ძიება სურათის სახელის მიხედვით:',
+
+# Mime search
+
+# Unwatchedpages
+
+# List redirects
+
+# Unused templates
+
+# Random redirect
+
+# Statistics
+
+# Miscellaneous special pages
+
+# Special:Allpages
+
+# Special:Listusers
+
+# E this user
+
+# Watchlist
+
+# Delete/protect/revert
+
+# restrictions (nouns)
+
+# Undelete
+
+# Namespace form on various pages
+
+# Contributions
+
+# What links here
+
+# Block/unblock IP
+
+# Developer tools
+
+# Make sysop
+
+# Move page
+
+# Export
+
+# Namespace 8 related
+'allmessages' => 'სისტემური შეტყობინება',
+'allmessagesname' => 'დასახელება',
+'allmessagesdefault' => 'სტანდარტული ტექსტი',
+'allmessagescurrent' => 'მიმდინარე ტექსტი',
+'allmessagestext' => 'ეს არის სახელთა სივრცე მედიავიკიში არსებული სისტემური შეტყობინებების ჩამონათვალი.',
+'allmessagesnotsupportedUI' => 'თქვენს ამჟამინდელ ინტერფეისის ენას <b>$1</b> არ აქვს სპეციალური:AllMessages-ის უზრუნველყოფა ამ საიტზე.',
+'allmessagesnotsupportedDB' => 'სპეციალური:AllMessages-ის უზრუნველყოფა არ ხდება, ვინაიდან wgUseDatabaseMessages გამორთულია.',
+'allmessagesfilter' => 'ფილტრი შეტყობინების სახელის მიხედვით:',
+'allmessagesmodified' => 'აჩვენე მხოლოდ შეცვლილი',
+
+# Thumbnails
+'thumbnail-more' => 'გაზარდეთ',
+#TODO: 'missingimage' => '<b>Missing image</b><br /><i>$1</i>',
+'filemissing' => 'ფაილი ვერ მოიძებნა',
+#TODO: 'thumbnail_error' => 'ესკიზის შექმნის შეცდომა: $1',
+
+# Special:Import
+
+# import log
+
+# tooltip help for some actions, most are in Monobook.js
+
+# stylesheets
+
+# Metadata
+
+# Attribution
+'anonymous' => '{{SITENAME}}-ის ანონიმური მომხმარებლები',
+'siteuser' => '{{SITENAME}} მომხმარებელი $1',
+#TODO: 'lastmodifiedatby' => 'This page was last modified $2, $1 by $3.', // $1 date, $2 time. $3 user
+'and' => 'და',
+#TODO: 'othercontribs' => 'Based on work by $1.',
+'others' => 'სხვები',
+'siteusers' => '{{SITENAME}} მომხმარებლები $1',
+#TODO: 'creditspage' => 'წვლილი',
+#TODO: 'nocredits' => 'There is no credits info available for this page.',
+
+# Spam protection
+
+# Info page
+
+# Math options
+
+# Patrolling
+
+# Monobook.js: tooltips and access keys for monobook
+
+# image deletion
+
+# browsing diffs
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'მომხმარებელი:',
+'speciallogtitlelabel' => 'სათაური:',
+
+'passwordtooshort' => 'თქვენი პაროლი ძალიან მოკლეა. მასში უნდა შედიოდეს არანაკლებ $1 ასო-ნიშანი.',
+
+# Media Warning
+#TODO: 'mediawarning' => '\'\'\'Warning\'\'\': This file may contain malicious code, by executing it your system may be compromised.<hr />',
+
+'fileinfo' => '$1KB, MIME ტიპი: <code>$2</code>',
+
+# Metadata
+
+# Exif tags
+
+# Make & model, can be wikified in order to link to the camera and model name
+
+# Exif attributes
+
+# external editor support
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'ყველა',
+'imagelistall' => 'ყველა',
+'watchlistall1' => 'ყველა',
+'watchlistall2' => 'ყველა',
+'namespacesall' => 'ყველა',
+
+# E-mail address confirmation
+
+# Inputbox extension, may be useful in other contexts as well
+
+# Scary transclusion
+
+# Trackbacks
+
+# delete conflict
+
+# HTML dump
+
+# action=purge
+#TODO: 'confirm_purge' => "Clear the cache of this page?\n\n$1",
+#TODO: 'confirm_purge_button' => 'OK',
+
+'youhavenewmessagesmulti' => "თქვენ გაქვთ ახალი შეტყობინება $1-ზე",
+
+#TODO: 'searchcontaining' => "Search for articles containing ''$1''.",
+#TODO: 'searchnamed' => "Search for articles named ''$1''.",
+#TODO: 'articletitles' => "Articles starting with ''$1''",
+'hideresults' => 'შედეგების დამალვა',
+
+# DISPLAYTITLE
+'displaytitle' => '(ამ გვერდის ბმული როგორც [[$1]])',
+
+'loginlanguagelabel' => 'ენა: $1',
+
+# Multipage image navigation
+
+# Table pager
+#TODO: 'ascending_abbrev' => 'asc',
+#TODO: 'descending_abbrev' => 'desc',
+#TODO: 'table_pager_next' => 'Next page',
+#TODO: 'table_pager_prev' => 'Previous page',
+'table_pager_first' => 'პირველი გვერდი',
+'table_pager_last' => 'ბოლო გვერდი',
+#TODO: 'table_pager_limit' => 'Show $1 items per page',
+#TODO: 'table_pager_limit_submit' => 'Go',
+#TODO: 'table_pager_empty' => 'No results',
+
+
+);
+
+?>
diff --git a/languages/messages/MessagesKaa.php b/languages/messages/MessagesKaa.php
new file mode 100644
index 000000000000..9c2f9d0c177a
--- /dev/null
+++ b/languages/messages/MessagesKaa.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Karakalpak (Qaraqalpaqsha)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$linkTrail = '/^([a-zʻ`]+)(.*)$/sDu';
+
+?>
diff --git a/languages/messages/MessagesKg.php b/languages/messages/MessagesKg.php
new file mode 100644
index 000000000000..ad5aceafd69a
--- /dev/null
+++ b/languages/messages/MessagesKg.php
@@ -0,0 +1,99 @@
+<?php
+/** Kongo (Kikongo)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$messages = array(
+
+# dates
+'sunday' => 'Lumingu',
+'monday' => 'Kimosi',
+'tuesday' => 'Kizole',
+'wednesday' => 'Kitatu',
+'thursday' => 'Kiya',
+'friday' => 'Kitanu',
+'saturday' => 'Sabala',
+
+# months
+'january' => 'ngonda ya ntete',
+'february' => 'ngonda ya zole',
+'march' => 'ngonda ya tatu',
+'april' => 'ngonda ya iya',
+'may_long' => 'ngonda ya tanu',
+'june' => 'ngonda ya sambanu',
+'july' => 'ngonda ya nsambwadi',
+'august' => 'ngonda ya nana',
+'september' => 'ngonda ya uvwa',
+'october' => 'ngonda ya kumi',
+'november' => 'ngonda ya kumi na mosi',
+'december' => 'ngonda ya kumi na zole',
+
+# Bits of text used by many pages:
+'categories' => 'Bakalasi',
+'pagecategories' => '{{PLURAL:$1|Kalasi|Bakalasi}}',
+'category_header' => 'Mikanda na kalasi "$1"',
+'mainpage' => 'Lukaya ya mfumu',
+
+'article' => 'Pagina contenta continens',
+'help' => 'Nsadisa',
+'mytalk' => 'Disolo ya munu',
+'currentevents' => 'Mambu ya mpa',
+'currentevents-url' => 'Mambu ya mpa',
+'search' => 'Sosa',
+'searchbutton' => 'Sosa',
+'searcharticle' => 'Kwenda',
+'history' => 'Bampaluka ya lukaya',
+'history_short' => 'Bampaluka',
+'edit' => 'Sonika',
+'talk' => 'Disolo',
+'toolbox' => 'Bisadilu',
+'otherlanguages' => 'Bandinga ya nkaka',
+'redirectedfrom' => '(Balulama tuka $1)',
+'retrievedfrom' => 'Receptum de "$1"',
+
+# nstab
+'nstab-main' => 'Mukanda',
+'nstab-category' => 'Kalasi',
+
+
+'yourlanguage' => 'Ndinga:',
+
+# Login and logout pages
+'loginlanguagelabel' => 'Ndinga: $1',
+'logout' => 'Basika',
+'userlogout' => 'Basika',
+
+'histfirst' => 'Ya ntete',
+'histlast' => 'Ya nsuka',
+
+'prevn' => 'biyita $1',
+'nextn' => 'bilandi $1',
+'viewprevnext' => 'Mona ($1) ($2) ($3).',
+
+'powersearch' => 'Sosa',
+
+'mypreferences' => 'Konte ya munu',
+
+# Recentchanges
+'recentchanges' => 'Bampaluka ya mpa',
+
+
+'ncategories' => '{{PLURAL:$1|kalasi|bakalasi}} $1',
+
+'randompage' => 'Lukaya na kintulumukini',
+'mycontris' => 'Makabu ya munu',
+'whatlinkshere' => 'Balukaya ke songa awa',
+
+'categoryarticlecount' => '{{PLURAL:$1|Mukanda mosi|Mikanda $1 }} ni na kalasi yayi.', //
+
+# Table pager
+'table_pager_first' => 'Lukaya ya ntete',
+'table_pager_last' => 'Lukaya ya nsuka',
+'table_pager_next' => 'Lukaya ya kulanda',
+'table_pager_prev' => 'Lukaya ya kuyita',
+
+);
+
+?>
diff --git a/languages/messages/MessagesKk.php b/languages/messages/MessagesKk.php
new file mode 100644
index 000000000000..eb8cf791937d
--- /dev/null
+++ b/languages/messages/MessagesKk.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Kazakh (Қазақша)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'kk-kz';
+
+$linkTrail = '/^([a-zäçéğıïñöşüýа-яёәғіқңөұүһʺʹ“»]+)(.*)$/sDu';
+
+?>
diff --git a/languages/messages/MessagesKk_cn.php b/languages/messages/MessagesKk_cn.php
new file mode 100644
index 000000000000..5cf82bd5ed5a
--- /dev/null
+++ b/languages/messages/MessagesKk_cn.php
@@ -0,0 +1,2175 @@
+<?php
+/**
+ * Kazakh (قازاقشا)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+$fallback = 'kk-kz';
+
+$rtl = true;
+
+$digitTransformTable = array(
+ "0" => "۰",
+ "1" => "۱",
+ "2" => "۲",
+ "3" => "۳",
+ "4" => "۴",
+ "5" => "۵",
+ "6" => "۶",
+ "7" => "۷",
+ "8" => "۸",
+ "9" => "۹",
+ "%" => "٪",
+);
+
+$separatorTransformTable = array(
+ "," => "٬",
+ "." => "٫", // wrong table?
+);
+
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+ # Underlines seriously harm legibility. Force off:
+ 'underline' => 0,
+);
+
+$extraUserToggles = array(
+ 'nolangconversion'
+);
+
+$fallback8bitEncoding = 'windows-1256';
+
+$linkPrefixExtension = true;
+
+$namespaceNames = array(
+ NS_MEDIA => 'تاسپا',
+ NS_SPECIAL => 'ارنايى',
+ # NS_MAIN => '',
+ NS_TALK => 'تالقىلاۋ',
+ NS_USER => 'قاتىسۋشى',
+ NS_USER_TALK => 'قاتىسۋشى_تالقىلاۋى',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_تالقىلاۋى',
+ NS_IMAGE => 'سۋرەت',
+ NS_IMAGE_TALK => 'سۋرەت_تالقىلاۋى',
+ NS_MEDIAWIKI => 'مەدياۋيكي',
+ NS_MEDIAWIKI_TALK => 'مەدياۋيكي_تالقىلاۋى',
+ NS_TEMPLATE => 'ٴۇلگٴى',
+ NS_TEMPLATE_TALK => 'ٴۇلگٴى_تالقىلاۋى',
+ NS_HELP => 'انىقتاما',
+ NS_HELP_TALK => 'انىقتاما_تالقىلاۋى',
+ NS_CATEGORY => 'سانات',
+ NS_CATEGORY_TALK => 'سانات_تالقىلاۋى'
+);
+
+$namespaceAliases = array(
+ # Aliases to kk-kz namespaces
+ 'Таспа' => NS_MEDIA,
+ 'Арнайы' => NS_SPECIAL,
+ 'Талқылау' => NS_TALK,
+ 'Қатысушы' => NS_USER,
+ 'Қатысушы_талқылауы' => NS_USER_TALK,
+ '$1_талқылауы' => NS_PROJECT_TALK,
+ 'Сурет' => NS_IMAGE,
+ 'Сурет_талқылауы' => NS_IMAGE_TALK,
+ 'МедиаУики' => NS_MEDIAWIKI,
+ 'МедиаУики_талқылауы' => NS_MEDIAWIKI_TALK,
+ 'Үлгі' => NS_TEMPLATE,
+ 'Үлгі_талқылауы' => NS_TEMPLATE_TALK,
+ 'Анықтама' => NS_HELP,
+ 'Анықтама_талқылауы' => NS_HELP_TALK,
+ 'Санат' => NS_CATEGORY,
+ 'Санат_талқылауы' => NS_CATEGORY_TALK,
+ # Aliases to kk-tr namespaces
+ 'Taspa' => NS_MEDIA,
+ 'Arnaýı' => NS_SPECIAL,
+ 'Talqılaw' => NS_TALK,
+ 'Qatıswşı' => NS_USER,
+ 'Qatıswşı_talqılawı' => NS_USER_TALK,
+ '$1_talqılawı' => NS_PROJECT_TALK,
+ 'Swret' => NS_IMAGE,
+ 'Swret_talqılawı' => NS_IMAGE_TALK,
+ 'MedïaWïkï' => NS_MEDIAWIKI,
+ 'MedïaWïkï_talqılawı' => NS_MEDIAWIKI_TALK,
+ 'Ülgi' => NS_TEMPLATE,
+ 'Ülgi_talqılawı' => NS_TEMPLATE_TALK,
+ 'Anıqtama' => NS_HELP,
+ 'Anıqtama_talqılawı' => NS_HELP_TALK,
+ 'Sanat' => NS_CATEGORY,
+ 'Sanat_talqılawı' => NS_CATEGORY_TALK,
+);
+
+$quickbarSettings = array(
+ 'ەشقانداي', 'سولعا بەكٴىتٴىلگەن', 'وڭعا بەكٴىتٴىلگەن', 'سولعا قالقىعان', 'وڭعا قالقىعان'
+);
+
+$skinNames = array(
+ 'standard' => 'داعدىلى',
+ 'nostalgia' => 'اڭساۋ',
+ 'cologneblue' => 'كٴولن زەڭگٴىرلٴىگٴى',
+ 'davinci' => 'دا ۆينچي',
+ 'mono' => 'دارا',
+ 'monobook' => 'دارا كٴىتاپ',
+ 'myskin' => 'ٴوز مٴانەرٴىم',
+ 'chick' => 'بالاپان',
+ 'simple' => 'كٴادٴىمگٴى'
+);
+
+$defaultDateFormat = 'ymd';
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'xg j, Y',
+ 'mdy both' => 'H:i, xg j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F, Y',
+ 'dmy both' => 'H:i, j F, Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y" ج" xg j',
+ 'ymd both' => 'H:i, Y" ج" xg j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'سٴىلتەمەنٴى استىنان سىز:',
+'tog-highlightbroken' => 'جوقتالعان سٴىلتەمەلەردٴى <a href="" class="new">بىلاي</a> پٴىشٴىمدە (باسقاشا: بىلاي <a href="" class="internal">?</a> سيياقتى).',
+'tog-justify' => 'ەجەلەردٴى ەنٴى بويىنشا تۋرالاۋ',
+'tog-hideminor' => 'جۋىقتاعى ٴوزگەرٴىستەردە شاعىن تٴۇزەتۋدٴى جاسىر',
+'tog-extendwatchlist' => 'باقىلاۋ تٴىزٴىمدٴى ۇلعايت (بارلىق جارامدى ٴوزگەرٴىستەردٴى كٴورسەت)',
+'tog-usenewrc' => 'كەڭەيتٴىلگەن جۋىقتاعى ٴوزگەرٴىستەر (JavaScript)',
+'tog-numberheadings' => 'بٴولٴىم تاقىرىپتارىن ٴوزدٴىك تٴۇردە نومٴىرلە',
+'tog-showtoolbar' => 'ٴوڭدەۋ قۋرالدار جولاعىن كٴورسەت (JavaScript)',
+'tog-editondblclick' => 'قوس نۇقىمداپ ٴوڭدەۋ (JavaScript)',
+'tog-editsection' => 'بٴولٴىمدەردٴى [ٴوڭدەۋ] سٴىلتەمەسٴىمەن ٴوڭدەۋٴىن ەندٴىر',
+'tog-editsectiononrightclick' => 'بٴولٴىم اتاۋىن وڭ جاق نۇقۋمەن<br />ٴوڭدەۋٴىن ەندٴىر (JavaScript)',
+'tog-showtoc' => 'مازمۇنىن كٴورسەت (3-تەن ارتىق بٴولٴىمٴى بارىلارعا)',
+'tog-rememberpassword' => 'كٴىرگەنٴىمدٴى بۇل كومپييۋتەردە ۇمىتپا',
+'tog-editwidth' => 'ٴوڭدەۋ اۋماعى تولىق ەنٴىمەن',
+'tog-watchcreations' => 'مەن باستاعان بەتتەردٴى باقىلاۋ تٴىزٴىمٴىمە قوس',
+'tog-watchdefault' => 'مەن ٴوڭدەگەن بەتتەردٴى باقىلاۋ تٴىزٴىمٴىمە قوس',
+'tog-minordefault' => 'بارلىق تٴۇزەتۋلەردٴى ٴادەپكٴىدەن شاعىن دەپ بەلگٴىلە',
+'tog-previewontop' => 'قاراپ شىعۋدى ٴوڭدەۋ اۋماعىنىڭ ٴۇستٴىنە سال',
+'tog-previewonfirst' => 'بٴىرٴىنشٴى ٴوڭدەگەندە قاراپ شىعۋ',
+'tog-nocache' => 'بەت قوسالقى قالتاسىن ٴوشٴىر',
+'tog-enotifwatchlistpages' => 'باقىلانعان بەت ٴوزگەرگەندە ماعان حات جٴىبەر',
+'tog-enotifusertalkpages' => 'تالقىلاۋىم ٴوزگەرگەندە ماعان حات جٴىبەر',
+'tog-enotifminoredits' => 'شاعىن تٴۇزەتۋ تۋرالى دا ماعان حات جٴىبەر',
+'tog-enotifrevealaddr' => 'ە-پوشتا جايىمدى ەسكەرتۋ حاتتا اشىق كٴورسەت',
+'tog-shownumberswatching' => 'باقىلاپ تۇرعان قاتىسۋشىلاردىڭ سانىن كٴورسەت',
+'tog-fancysig' => 'قام قولتاڭبا (ٴوزدٴىك سٴىلتەمەسٴىز;)',
+'tog-externaleditor' => 'سىرتقى ٴوڭدەۋٴىشتٴى ٴادەپكٴىدەن قولدان',
+'tog-externaldiff' => 'سىرتقى ايىرماعىشتى ٴادەپكٴىدەن قولدان',
+'tog-showjumplinks' => '«ٴوتٴىپ كەتۋ» قاتىناۋ سٴىلتەمەلەرٴىن ەندٴىر',
+'tog-uselivepreview' => 'تۋرا قاراپ شىعۋدى قولدانۋ (JavaScript) (سىناق تٴۇرٴىندە)',
+'tog-autopatrol' => 'تٴۇزەتۋٴىمدٴى كٴۇزەتكە بەلگٴىلە',
+'tog-forceeditsummary' => 'ٴوڭدەۋ سيپاتتاماسى بوس قالعاندا ماعان ەسكەرت',
+'tog-watchlisthideown' => 'تٴۇزەتۋٴىمدٴى باقىلاۋ تٴىزٴىمنەن جاسىر',
+'tog-watchlisthidebots' => 'بوت تٴۇزەتۋٴىن باقىلاۋ تٴىزٴىمنەن جاسىر',
+'tog-nolangconversion' => 'تٴىل تٴۇرٴىن اۋدارماۋ',
+
+'underline-always' => 'ٴارقاشان',
+'underline-never' => 'ەشقاشان',
+'underline-default' => 'شولعىش بويىنشا',
+
+'skinpreview' => '(قاراپ شىعۋ)',
+
+# Dates
+'sunday' => 'جەكسەنبٴى',
+'monday' => 'دٴۇيسەنبٴى',
+'tuesday' => 'سەيسەنبٴى',
+'wednesday' => 'سٴارسەنبٴى',
+'thursday' => 'بەيسەنبٴى',
+'friday' => 'جۇما',
+'saturday' => 'سەنبٴى',
+'sun' => 'جەك',
+'mon' => 'دٴۇي',
+'tue' => 'بەي',
+'wed' => 'سٴار',
+'thu' => 'بەي',
+'fri' => 'جۇم',
+'sat' => 'سەن',
+'january' => 'قاڭتار',
+'february' => 'اقپان',
+'march' => 'ناۋرىز',
+'april' => 'cٴاۋٴىر',
+'may_long' => 'مامىر',
+'june' => 'ماۋسىم',
+'july' => 'شٴىلدە',
+'august' => 'تامىز',
+'september' => 'قىركٴۇيەك',
+'october' => 'قازان',
+'november' => 'قاراشا',
+'december' => 'جەلتوقسان',
+'january-gen' => 'قانتاردىڭ',
+'february-gen' => 'اقپاننىڭ',
+'march-gen' => 'ناۋرىزدىڭ',
+'april-gen' => 'سٴاۋٴىردٴىڭ',
+'may-gen' => 'مامىردىڭ',
+'june-gen' => 'ماۋسىمنىڭ',
+'july-gen' => 'شٴىلدەنٴىڭ',
+'august-gen' => 'تامىزدىڭ',
+'september-gen' => 'قىركٴۇيەكتٴىڭ',
+'october-gen' => 'قازاننىڭ',
+'november-gen' => 'قاراشانىڭ',
+'december-gen' => 'جەلتوقساننىڭ',
+'jan' => 'قان',
+'feb' => 'اقپ',
+'mar' => 'ناۋ',
+'apr' => 'cٴاۋ',
+'may' => 'مام',
+'jun' => 'ماۋ',
+'jul' => 'شٴىل',
+'aug' => 'تام',
+'sep' => 'قىر',
+'oct' => 'قاز',
+'nov' => 'قار',
+'dec' => 'جەل',
+
+# Bits of text used by many pages
+'categories' => 'بارلىق سانات تٴىزٴىمٴى',
+'pagecategories' => '{{PLURAL:$1|سانات|ساناتتار}}',
+'category_header' => '«$1» ساناتىنداعى بەتتەر',
+'subcategories' => 'تٴومەنگٴى ساناتتار',
+'category-media-header' => '«$1» ساناتىنداعى تاسپالار',
+
+'linkprefix' => '/^(.*?)([a-zäçéğıïñöşüýа-яёәіңғүұқөһA-ZÄÇÉĞİÏÑÖŞÜÝА-ЯЁӘІҢҒҮҰҚӨҺʺʹ«„]+)$/sDu',
+'mainpage' => 'باستى بەت',
+'mainpagetext' => "<big>'''مەدياۋيكي باعدارلاماسى سٴاتتٴى ورناتىلدى.'''</big>",
+'mainpagedocfooter' => 'ۋيكي باعدارلاماسىن پايدالانۋ اقپاراتى ٴۇشٴىن [http://meta.wikimedia.org/wiki/Help:Contents پايدالانۋشى نۇسقاۋلارىمەن] تانىسىڭىز.
+
+== باستاۋ ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings باپتاۋ قالاۋلارى تٴىزٴىمٴى]
+* [http://www.mediawiki.org/wiki/Help:FAQ مەدياۋيكي جسج]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce مەدياۋيكي حات تاراتۋ تٴىزٴىمٴى]',
+
+'portal' => 'قاۋىم پورتالى',
+'portal-url' => '{{ns:project}}:قاۋىم_پورتالى',
+'about' => 'بٴىز تۋرالى',
+'aboutsite' => '{{SITENAME}} تۋرالى',
+'aboutpage' => '{{ns:project}}:بٴىز_تۋرالى',
+'article' => 'ماعلۇمات',
+'help' => 'انىقتاما',
+'helppage' => '{{ns:help}}:مازمۇنى',
+'bugreports' => 'قاتە ەسەپتەمەلەرٴى',
+'bugreportspage' => '{{ns:project}}:قاتە_ەسەپتەمەلەرٴى',
+'sitesupport' => 'دەمەۋشٴىلٴىك',
+'sitesupport-url' => '{{ns:project}}:جٴاردەم',
+'faq' => 'جسج',
+'faqpage' => '{{ns:project}}:جسج',
+'edithelp' => 'ٴوندەۋ انىقتاماسى',
+'newwindow' => '(جاڭا تەرەزەدە اشىلادى)',
+'edithelppage' => '{{ns:help}}:ٴوڭدەۋ',
+'cancel' => 'بولدىرماۋ',
+'qbfind' => 'تابۋ',
+'qbbrowse' => 'شولۋ',
+'qbedit' => 'ٴوڭدەۋ',
+'qbpageoptions' => 'وسى بەت',
+'qbpageinfo' => 'مٴاتٴىن ارالىعى',
+'qbmyoptions' => 'بەتتەرٴىم',
+'qbspecialpages' => 'ارنايى بەتتەر',
+'moredotdotdot' => 'كٴوبٴىرەك…',
+'mypage' => 'جەكە بەتٴىم',
+'mytalk' => 'تالقىلاۋىم',
+'anontalk' => 'IP تالقىلاۋى',
+'navigation' => 'باعىتتاۋ',
+
+# Metadata in edit box
+'metadata_help' => 'مەتا-دەرەكتەر (تٴۇسٴىندٴىرمەلەر ٴۇشٴىن [[{{ns:project}}:مەتا-دەرەكتەر]] بەتٴىن قاراڭىز):',
+
+'currentevents' => 'اعىمداعى وقيعالار',
+'currentevents-url' => 'اعىمداعى_وقيعالار',
+
+'disclaimers' => 'جاۋاپكەرشٴىلٴىكتەن باس تارتۋ',
+'disclaimerpage' => '{{ns:project}}:جاۋاپكەرشٴىلٴىكتەن_باس_تارتۋ',
+'privacy' => 'جەكە قۇپيياسىن ساقتاۋ',
+'privacypage' => '{{ns:project}}:جەكە_قۇپيياسىن_ساقتاۋ',
+'errorpagetitle' => 'قاتە',
+'returnto' => '$1 دەگەنگە ورالۋ.',
+'tagline' => '{{GRAMMAR:ablative|{{SITENAME}}}}',
+'search' => 'ٴىزدەۋ',
+'searchbutton' => 'ٴىزدەۋ',
+'go' => 'ٴوتۋ',
+'searcharticle' => 'ٴوتۋ',
+'history' => 'بەت تاريحى',
+'history_short' => 'تاريحى',
+'updatedmarker' => 'سوڭعى كٴىرگەننەن بەرٴى جاڭارتىلعان',
+'info_short' => 'اقپارات',
+'printableversion' => 'باسىپ شىعارۋعا',
+'permalink' => 'تۇراقتى سٴىلتەمە',
+'print' => 'باسىپ شىعارۋ',
+'edit' => 'ٴوڭدەۋ',
+'editthispage' => 'بەتتٴى ٴوڭدەۋ',
+'delete' => 'جويۋ',
+'deletethispage' => 'بەتتٴى جويۋ',
+'undelete_short' => '{{PLURAL:$1|بٴىر|$1}} تٴۇزەتۋدٴى قايتارۋ',
+'protect' => 'قورعاۋ',
+'protectthispage' => 'بەتتٴى قورعاۋ',
+'unprotect' => 'قورعاماۋ',
+'unprotectthispage' => 'بەتتٴى قورعاماۋ',
+'newpage' => 'جاڭا بەت',
+'talkpage' => 'بەتتٴى تالقىلاۋ',
+'specialpage' => 'ارنايى بەت',
+'personaltools' => 'جەكە قۇرالدار',
+'postcomment' => 'مٴاندەمە جٴىبەرۋ',
+'articlepage' => 'ماعلۇمات بەتٴىن قاراۋ',
+'talk' => 'تالقىلاۋ',
+'views' => 'كٴورٴىنٴىس',
+'toolbox' => 'قۇرالدار',
+'userpage' => 'قاتىسۋشىنىڭ بەتٴىن قاراۋ',
+'projectpage' => 'جوبا بەتٴىن قاراۋ',
+'imagepage' => 'سۋرەت بەتٴىن قاراۋ',
+'mediawikipage' => 'حابار بەتٴىن قاراۋ',
+'templatepage' => 'ٴۇلگٴى بەتٴىن قاراۋ',
+'viewhelppage' => 'انىقتاما بەتٴىن قاراۋ',
+'categorypage' => 'سانات بەتٴىن قاراۋ',
+'viewtalkpage' => 'تالقىلاۋ بەتٴىن قاراۋ',
+'otherlanguages' => 'باسقا تٴىلدەردە',
+'redirectedfrom' => '($1 بەتٴىنەن ايداتىلعان)',
+'redirectpagesub' => 'ايداتۋ بەتٴى',
+'lastmodifiedat' => 'بۇل بەتتٴىڭ ٴوزگەرتٴىلگەن سوڭعى كەزٴى: $2, $1.', # $1 date, $2 time
+'viewcount' => 'بۇل بەت {{plural:$1|بٴىر|$1}} رەت قارالعان.',
+'copyright' => 'ماعلۇمات $1 قۇجاتى بويىنشا قاتىناۋلى.',
+'protectedpage' => 'قورعاۋلى بەت',
+'jumpto' => 'مىناعان ٴوتٴىپ كەتۋ:',
+'jumptonavigation' => 'باعىتتاۋ',
+'jumptosearch' => 'ٴىزدەۋ',
+
+'badaccess' => 'رۇقسات قاتەسٴى',
+'badaccess-group0' => 'سۇرانىسقان ٴارەكەتٴىڭٴىزدٴى جەگۋٴىڭٴىزگە رۇقسات ەتٴىلمەيدٴى.',
+'badaccess-group1' => 'سۇرانىسقان ٴارەكەتٴىڭٴىز $1 توبىنىڭ قاتىسۋشىلارىنا شەكتەلەدٴى.',
+'badaccess-group2' => 'سۇرانىسقان ٴارەكەتٴىڭٴىز $1 توپتارى بٴىرٴىنٴىڭ قاتۋسىشىلارىنا شەكتەلەدٴى.',
+'badaccess-groups' => 'سۇرانىسقان ٴارەكەتٴىڭٴىز $1 توپتارى بٴىرٴىنٴىڭ قاتۋسىشىلارىنا شەكتەلەدٴى.',
+
+'versionrequired' => 'MediaWiki $1 نۇسقاسى قاجەت',
+'versionrequiredtext' => 'وسى بەتتٴى قولدانۋ ٴۇشٴىن MediaWiki $1 نۇسقاسى قاجەت. [[{{ns:special}}:Version]] بەتٴىن قاراڭىز.',
+
+'ok' => 'جارايدى',
+'pagetitle' => '$1 — {{SITENAME}}',
+'retrievedfrom' => '«$1» دەگەننەن الىنعان',
+'youhavenewmessages' => 'سٴىزدە $1 بار ($2).',
+'newmessageslink' => 'جاڭا حابارلار',
+'newmessagesdifflink' => 'سوڭعى ٴوزگەرٴىسٴىنە',
+'editsection' => 'ٴوڭدەۋ',
+'editold' => 'ٴوڭدەۋ',
+'editsectionhint' => 'بٴولٴىمدٴى ٴوڭدەۋ: $1',
+'toc' => 'مازمۇنى',
+'showtoc' => 'كٴورسەت',
+'hidetoc' => 'جاسىر',
+'thisisdeleted' => 'قارايمىز با, نە قايتارامىز با?: $1',
+'viewdeleted' => 'قارايمىز با?: $1',
+'restorelink' => 'جويىلعان {{PLURAL:$1|بٴىر|$1}} تٴۇزەتۋ',
+'feedlinks' => 'ارنا:',
+'feed-invalid' => 'جارامسىز جازىلىم ارنا تٴۇرٴى.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'ماعلۇمات',
+'nstab-user' => 'جەكە بەتٴى',
+'nstab-media' => 'تاسپا بەتٴى',
+'nstab-special' => 'ارنايى',
+'nstab-project' => 'جوبا بەتٴى',
+'nstab-image' => 'فايل',
+'nstab-mediawiki' => 'جٴۇيە حابارى',
+'nstab-template' => 'ٴۇلگٴى',
+'nstab-help' => 'انىقتاما',
+'nstab-category' => 'سانات',
+
+# Main script and global functions
+'nosuchaction' => 'مۇنداي ٴارەكەت جوق',
+'nosuchactiontext' => 'وسى URL جايىمەن ەنگٴىزٴىلگەن ٴارەكەتتٴى
+وسى ۋيكي جورامالداپ بٴىلمەدٴى.',
+'nosuchspecialpage' => 'بۇل ارنايى بەت ەمەس',
+'nospecialpagetext' => 'سٴىز سۇرانىسقان ارنايى بەت جارامسىز. بارلىق جارامدى ارنايى بەتتەر تٴىزٴىمٴىن [[{{ns:special}}:Specialpages]] بەتٴىندە تابا الاسىز.',
+
+# General errors
+'error' => 'قاتە',
+'databaseerror' => 'دەرەكقوردىڭ قاتەسٴى',
+'dberrortext' => 'دەرەكقورعا سۇرانىس جاسالعاندا سينتاكسيس قاتەسٴى كەزدەستٴى.
+بۇل باعدارلامانىڭ قاتەسٴىن كٴورسەتۋ مٴۇمكٴىن.
+دەرەكقورعا سوڭعى بولعان سۇرانىس:
+<blockquote><tt>$1</tt></blockquote>
+مىنا فۋنكتسيياسىنان «<tt>$2</tt>».
+MySQL قايتارعان قاتەسٴى «<tt>$3: $4</tt>».',
+'dberrortextcl' => 'دەرەكقورعا سۇرانىس جاسالعاندا سينتاكسيس قاتەسٴى كەزدەستٴى.
+دەرەكقورعا سوڭعى بولعان سۇرانىس:
+«$1»
+مىنا فۋنكتسيياسىنان: «$2».
+MySQL قايتارعان قاتەسٴى «$3: $4»',
+'noconnect' => 'عافۋ ەتٴىڭٴىز! بۇل ۋيكيدە كەيبٴىر تەحنيكالىق قيىنشىلىقتار كەزدەستٴى, سوندىقتان دەرەكقور سەرۆەرٴىنە قاتىناسۋ المايدى. <br />
+$1',
+'nodb' => '$1 دەرەكقورى تالعانبادى',
+'cachederror' => 'تٴومەندە سۇرانعان بەتتٴىڭ قوسالقى قالتاداعى كٴوشٴىرمەسٴى, وسى بەت جاڭارتىلماعان بولۋى مٴۇمكٴىن.',
+'laggedslavemode' => 'نازار سالىڭىز: بەتتە جۋىقتاعى جاڭالاۋلار بولماۋى مٴۇمكٴىن.',
+'readonly' => 'دەرەكقورى قۇلىپتالعان',
+'enterlockreason' => 'قۇلىپتاۋ سەبەبٴىن ەنگٴىزٴىڭٴىز, قاي ۋاقىتقا دەيٴىن
+قۇلىپتالعانىن قوسا',
+'readonlytext' => 'اعىمدا دەرەكقور جاڭا جازبا جٴانە تاعى باسقا ٴوزگەرٴىستەر جاساۋدان قۇلىپتالىنعان. بۇل دەرەكقوردى جٴوندەتۋ باعدارلامالارىن ورىنداۋ ٴۇشٴىن بولۋى مٴۇمكٴىن, بۇنى بٴىتٴىرگەننەن سوڭ قالٴىپتٴى ٴىسكە قايتارىلادى.
+
+قۇلىپتاعان ٴاكٴىمشٴى بۇنى بىلاي تٴۇسٴىندٴىرەدٴى: $1',
+'missingarticle' => 'ٴىزدەستٴىرٴىلگەن «$1» اتاۋلى بەت مٴاتٴىنٴى دەرەكقوردا تابىلمادى.
+
+بۇل داعدىدا ەسكٴىرگەن ايىرما سٴىلتەمەسٴىنە نەمەسە جويىلعان بەت تاريحىنىڭ سٴىلتەمەسٴىنە
+ەرگەننەن بولۋى مٴۇمكٴىن.
+
+ەگەر بۇل بولجام دۇرىس سەبەپ بولماسا, باعدارلامامىزداعى قاتەگە تاپ بولۋىڭىز مٴۇمكٴىن.
+بۇل تۋرالى ناقتى URL جايىن كٴورسەتٴىپ ٴاكٴىمشٴىگە ەسەپتەمە جٴىبەرٴىڭٴىز.',
+'readonly_lag' => 'جەتەك دەرەكقور سەرۆەرلەر باستاۋىشپەن قاداملانعاندا وسى دەرەكقور ٴوزدٴىك تٴۇرٴىندە قۇلىپتالىنعان',
+'internalerror' => 'ٴىشكٴى قاتە',
+'filecopyerror' => '«$1» فايلى «$2» فايلىنا كٴوشٴىرٴىلمەدٴى.',
+'filerenameerror' => '«$1» فايل اتى «$2» اتىنا ٴوزگەرتٴىلمەدٴى.',
+'filedeleteerror' => '«$1» فايلى جويىلمايدى.',
+'filenotfound' => '«$1» فايلى تابىلمادى.',
+'unexpected' => 'كٴۇتٴىلمەگەن ماعىنا: «$1» = «$2».',
+'formerror' => 'قاتە: جٴىبەرۋ ٴۇلگٴىتٴى ەمەس',
+'badarticleerror' => 'وسىنداي ٴارەكەت مىنا بەتتە اتقارىلمايدى.',
+'cannotdelete' => 'ايتىلمىش بەت نە سۋرەت جويىلمايدى. (بۇنى باسقا بٴىرەۋ جويعان شىعار.)',
+'badtitle' => 'جارامسىز اتاۋ',
+'badtitletext' => 'سۇرانىسقان بەت اتاۋى جارامسىز, بوس, تٴىلارا سٴىلتەمەسٴى نە ۋيكي-ارا اتاۋى مٴۇلتٴىك بولعان. اتاۋلاردا سٴۇەمەلدەمەگەن بٴىرقاتار ٴارٴىپتەر بولۋى مٴۇمكٴىن.',
+'perfdisabled' => 'عافۋ ەتٴىڭٴىز! وسى قاسيەت, دەرەكقوردىڭ جىلدامىلىعىنا ٴاسەر ەتٴىپ, ەشكٴىمگە ۋيكيدٴى پايدالانۋعا بەرمەگەسٴىن, ۋاقىتشا ٴوشٴىرٴىلگەن.',
+'perfdisabledsub' => 'مىندا $1 بەتٴىنٴىڭ ساقتالعان كٴوشٴىرمەسٴى:', # obsolete?
+'perfcached' => 'كەلەسٴى دەرەك قوسالقى قالتاسىنان الىنعان, سوندىقتان تولىقتاي جاڭالانماعان بولۋى مٴۇمكٴىن.',
+'perfcachedts' => 'كەلەسٴى دەرەك قوسالقى قالتاسىنان الىنعان, سوڭعى جاڭالانلعان كەزٴى: $1.',
+'wrong_wfQuery_params' => 'wfQuery() فۋنكتسيياسىندا جارامسىز باپتار<br />
+فۋنكتسييا: $1<br />
+سۇرانىس: $2',
+'viewsource' => 'قاينارىن قاراۋ',
+'viewsourcefor' => '$1 قاينارى',
+'protectedtext' => 'بۇل بەت ٴوڭدەۋ بولدىرماۋ ٴۇشٴىن قۇلىپتالىنعان.
+
+بۇل بەتتٴىڭ قاينارىن قاراۋىڭىزعا جٴانە كٴوشٴىرٴىپ الۋڭىزعا بولادى:',
+'protectedinterface' => 'بۇل بەت باعدارلامانىڭ تٴىلدەسۋ مٴاتٴىنٴىن جەتٴىستٴىرەدٴى, سوندىقتان قييانات كەلتٴىرمەۋ ٴۇشٴىن ٴوزگەرتۋٴى قۇلىپتالعان.',
+'editinginterface' => "'''نازار سالىڭىز:''' باعدارلاماعا تٴىلدەسۋ مٴاتٴىنٴىن جەتٴىستٴىرەتٴىن MediaWiki بەتٴىن ٴوڭدەپ جاتىرسىز. بۇل بەتتٴىڭ ٴوزگەرتۋٴى بارلىق پايدالانۋشىلار تٴىلدەسۋٴىنە ٴاسەر ەتەدٴى.",
+'sqlhidden' => '(SQL سۇرانىسى جاسىرىلدى)',
+
+# Login and logout pages
+'logouttitle' => 'قاتىسۋشى شىعۋى',
+'logouttext' => '<strong>ەندٴى جٴۇيەدەن شىقتىڭىز.</strong><br />
+بۇل كومپييۋتەردەن ٴالٴى دە جٴۇيەگە كٴىرمەستەن {{SITENAME}} جوباسىن
+شولۋىڭىز مٴۇمكٴىن, نەمەسە باسقا پايدالانۋشىنىڭ جٴۇيەگە كٴىرۋٴى مٴۇمكٴىن.
+كەيبٴىر بەتتەردە ٴالٴى دە جٴۇيەگە كٴىرگەنٴىڭٴىزدەي كٴورٴىنۋٴى مٴۇمكٴىندٴىگٴىن
+ەسكەرتەمٴىز; بۇل شولعىشتىڭ قوسالقى قالتاسىن بوساتۋ ارقىلى شەشٴىلەدٴى.',
+'welcomecreation' => '== قوش كەلدٴىڭٴىز, $1! ==
+
+تٴىركەلگٴىڭٴىز جاسالدى. {{SITENAME}} باپتاۋىڭىزدى قالاۋىڭىزبەن ٴوزگەرتۋدٴى ۇمىتپاڭىز.',
+'loginpagetitle' => 'قاتىسۋشى كٴىرۋٴى',
+'yourname' => 'قاتىسۋشى اتىڭىز',
+'yourpassword' => 'قۇپييا سٴوزٴىڭٴىز',
+'yourpasswordagain' => 'قۇپييا سٴوزدٴى قايتالاپ ەنگٴىزٴىڭٴىز',
+'remembermypassword' => 'مەنٴىڭ كٴىرگەنٴىمدٴى بۇل كومپييۋتەردە ۇمىتپا',
+'yourdomainname' => 'جەلٴى ٴۇيشٴىگٴىڭٴىز',
+'externaldberror' => 'وسىندا سىرتقى تەڭدەستٴىرۋ دەرەكقورىندا قاتە بولدى, نەمەسە سىرتقى تٴىركەلگٴىڭٴىزدٴى جاڭالاۋعا رۇقسات جوق.',
+'loginproblem' => '<b>كٴىرۋٴىڭٴىز كەزٴىندە وسىندا قيىندىققا تاپ بولدىق.</b><br />تاعى دا قايتالاپ قاراڭىز.',
+'alreadyloggedin' => '<strong>$1 دەگەن قاتىسۋشى, كٴىرٴىپسٴىز تٴۇگە!<strong><br />',
+'login' => 'كٴىرۋ',
+'loginprompt' => '{{SITENAME}} تورابىنا كٴىرۋ ٴۇشٴىن «cookies» قاسيەتٴىن ەندٴىرۋٴىڭٴىز قاجەت.',
+'userlogin' => 'كٴىرۋ / تٴىركەلگٴى جاساۋ',
+'logout' => 'شىعۋ',
+'userlogout' => 'شىعۋ',
+'notloggedin' => 'كٴىرمەگەنسٴىز',
+'nologin' => 'تٴىركەلگٴىڭٴىز جوق پا? $1.',
+'nologinlink' => 'جاساڭىز',
+'createaccount' => 'تٴىركەلگٴى جاسا',
+'gotaccount' => 'تٴىركەلگٴىڭٴىز بار ما? $1.',
+'gotaccountlink' => 'كٴىرٴىڭٴىز',
+'createaccountmail' => 'ە-پوشتامەن',
+'badretype' => 'ەنگٴىزگەن قۇپييا سٴوزدەرٴىڭٴىز بٴىر بٴىرٴىنە سٴايكەس ەمەس.',
+'userexists' => 'ەنگٴىزگەن قاتىسۋشى اتىڭىزدى بٴىرەۋ پايدالانىپ جاتىر. باسقا اتاۋ تانداڭىز.',
+'youremail' => 'ە-پوشتا جايىڭىز *:',
+'username' => 'قاتىسۋشى اتىڭىز:',
+'uid' => 'قاتىسۋشى تەڭدەستٴىرۋٴىڭٴىز:',
+'yourrealname' => 'شىن اتىڭىز *:',
+'yourlanguage' => 'تٴىلٴىڭٴىز:',
+'yourvariant' => 'تٴۇرٴى',
+'yournick' => 'لاقاپ اتىڭىز:',
+'badsig' => 'قام قولتاڭباڭىز جارامسىز; HTML بەلگٴىشەلەرٴىن تەكسەرٴىڭٴىز.',
+'email' => 'ە-پوشتاڭىز',
+'prefs-help-email-enotif' => 'ەگەر سونى باپتاساڭىز, وسى ە-پوشتا جايى سٴىزگە ەسكەرتۋ حات جٴىبەرۋگە قولدانىلادى.',
+'prefs-help-realname' => '* شىن اتىڭىز (مٴىندەتتٴى ەمەس): ەنگٴىزسەڭٴىز, شىعارماڭىزدىڭ اۋتورلىعىن بەلگٴىلەۋٴى ٴۇشٴىن قولدانىلادى.',
+'loginerror' => 'كٴىرۋ قاتەسٴى',
+'prefs-help-email' => '* ە-پوشتاڭىز (مٴىندەتتٴى ەمەس): «قاتىسۋشى» نەمەسە «قاتىسۋشى تالقىلاۋ» بەتٴىڭٴىزدەر ارقىلى باسقالارعا بايلانىسۋ مٴۇمكٴىندٴىك بەرەدٴى. ٴوزٴىڭٴىزدٴىڭ كٴىم ەكەنٴىڭٴىزدٴى بٴىلدٴىرتپەيدٴى.',
+'nocookiesnew' => 'قاتىسۋشى تٴىركەلگٴىسٴى جاسالدى, تەك ٴالٴى كٴىرمەگەنسٴىز. {{SITENAME}} جوباسىنا قاتىسۋشى كٴىرۋ ٴۇشٴىن «cookies» قاسيەتٴى قاجەت. شولعىشىڭىزدا «cookies» قاسيەتٴى ٴوشٴىرٴىلگەن. سونى ەندٴىرٴىڭٴىز دە جاڭا قاتىسۋشى اتىڭىزدى جٴانە قۇپييا سٴوزٴىڭٴىزدٴى ەنگٴىزٴىپ كٴىرٴىڭٴىز.',
+'nocookieslogin' => 'قاتىسۋشى كٴىرۋ ٴۇشٴىن {{SITENAME}} جوباسى «cookies» قاسيەتٴىن قولدانادى. شولعىشىڭىزدا «cookies» قاسيەتٴى ٴوشٴىرٴىلگەن. سونى ەندٴىرٴىڭٴىز دە قايتالاپ كٴىرٴىڭٴىز.',
+'noname' => 'قاتىسۋشى اتىن دۇرىس ەنگٴىزبەدٴىڭٴىز.',
+'loginsuccesstitle' => 'كٴىرۋٴىڭٴىز سٴاتتٴى ٴوتتٴى',
+'loginsuccess' => "'''سٴىز ەندٴى {{SITENAME}} جوباسىنا «$1» رەتٴىندە كٴىرٴىپ وتىرسىز.'''",
+'nosuchuser' => 'مىندا «$1» اتاۋلى قاتىسۋشى جوق. ەملەڭٴىزدٴى تەكسەرٴىڭٴىز, نەمەسە جاڭا تٴىركەلگٴى جاساڭىز.',
+'nosuchusershort' => 'مىندا «$1» دەگەن قاتىسۋشى اتاۋى جوق. ەملەڭٴىزدٴى تەكسەرٴىڭٴىز.',
+'nouserspecified' => 'قاتىسۋشى اتىن ەنگٴىزٴىۋٴىڭٴىز قاجەت.',
+'wrongpassword' => 'ەنگٴىزگەن قۇپييا سٴوز جارامسىز. قايتالاپ كٴورٴىڭٴىز.',
+'wrongpasswordempty' => 'قۇپييا سٴوز بوستى بوپتى. قايتالاپ كٴورٴىڭٴىز.',
+'mailmypassword' => 'قۇپييا سٴوزٴىمدٴى حاتپەن جٴىبەر',
+'passwordremindertitle' => 'قۇپييا سٴوز تۋرالى {{SITENAME}} جوباسىنىڭ ەسكەرتۋٴى',
+'passwordremindertext' => 'كەيبٴىرەۋ (IP جايى: $1, بٴالكٴىم, ٴوزٴىڭٴىز بولارسىز)
+{{SITENAME}} ٴۇشٴىن بٴىزدەن جاڭا قۇپييا سٴوزٴىن جٴىبەرۋٴىن سۇرانىسقان ($4).
+«$2» قاتىسۋشىنىڭ قۇپييا سٴوزٴى «$3» بولدى ەندٴى.
+قازٴىر كٴىرۋٴىڭٴىز جٴانە قۇپييا سٴوزٴىڭٴىزدٴى اۋىسترۋىڭىز قاجەت.
+
+ەگەر باسقا بٴىرەۋ بۇل سۇرانىستى جاساسا, نەمەسە قۇپييا سٴوزٴىڭٴىزدٴى ۇمىتساڭىز دا,
+جٴانە بۇنى ٴوزگەرتكٴىڭٴىز كەلمەسە دە, وسى حابارلاماعا اڭعارماۋىڭىزعا دا بولادى,
+ەسكٴى قۇپييا سٴوزٴىڭٴىزدٴى ٴارٴىعاراي قولدانىپ.',
+'noemail' => 'مىندا «$1» قاتىسۋشىنىڭ ە-پوشتاسى جوق.',
+'passwordsent' => 'جاڭا قۇپييا سٴوز «$1» ٴۇشٴىن
+تٴىركەلگەن ە-پوشتا جايىنا جٴىبەرٴىلدٴى.
+قابىلداعاننان كەيٴىن كٴىرگەندە سونى ەنگٴىزٴىڭٴىز.',
+'blocked-mailpassword' => 'IP جايىڭىزدان ٴوڭدەۋ بۇعاتتالعان, سوندىقتان
+قيياناتشىلىقتان ساقتانۋ ٴۇشٴىن قۇپييا سٴوز جٴىبەرۋ قىزمەتٴىنٴىڭ ٴارەكەتٴى رۇقسات ەتٴىلمەيدٴى.',
+'eauthentsent' => 'كۋٴالاندىرۋ حاتى اتالعان ە-پوشتا جايىنا جٴىبەرٴىلدٴى.
+باسقا ە-پوشتا حاتىن جٴىبەرۋدٴىڭ الدىنان, تٴىركەلگٴى شىنىنان سٴىزدٴىكٴى ەكەنٴىن
+كۋٴالاندىرۋ ٴۇشٴىن حاتتاعى نۇسقاۋلارعا ەرٴىڭٴىز.',
+'throttled-mailpassword' => 'سوڭعى $1 ساعاتتا قۇپييا سٴوز ەسكەرتۋ حاتى جٴىبەرٴىلدٴى تٴۇگە.
+قيياناتشىلىققا كەدەرگٴى بولۋ ٴۇشٴىن, $1 ساعات سايىن تەك بٴىر عانا قۇپييا سٴوز ەسكەرتۋ
+حاتى جٴىبەرٴىلەدٴى.',
+'mailerror' => 'حات جٴىبەرۋ قاتەسٴى: $1',
+'acct_creation_throttle_hit' => 'عافۋ ەتٴىڭٴىز, سٴىز $1 تٴىركەلگٴى جاساپسىز تٴۇگە. ونان ارتىق ٴىستەي المايسىز.',
+'emailauthenticated' => 'ە-پوشتا جايىڭىز كۋٴالاندىرىلعان كەزٴى: $1.',
+'emailnotauthenticated' => 'ە-پوشتا جايىڭىز ٴالٴى كۋٴالاندىرعان جوق.
+تٴومەندەگٴى قاسيەتتتەر ٴۇشٴىن ەشقانداي حات جٴىبەرٴىلمەيدٴى.',
+'noemailprefs' => 'وسى قاسيەتتەر ٴىستەۋٴى ٴۇشٴىن ە-پوشتا جايىڭىزدى ەنگٴىزٴىڭٴىز.',
+'emailconfirmlink' => 'ە-پوشتا جايىڭىزدى كۋٴالاندىرىڭىز',
+'invalidemailaddress' => 'وسى ە-پوشتا جايدا جارامسىز پٴىشٴىم بولعان, قابىل ەتٴىلمەيدٴى.
+دۇرىس پٴىشٴىمدەلگەن جايدى ەنگٴىزٴىڭٴىز, نە اۋماقتى بوس قالدىرىڭىز.',
+'accountcreated' => 'تٴىركەلگٴى جاسالدى',
+'accountcreatedtext' => '$1 ٴۇشٴىن قاتىسۋشى تٴىركەلگٴىسٴى جاسالدى.',
+
+# Edit page toolbar
+'bold_sample' => 'جۋان مٴاتٴىن',
+'bold_tip' => 'جۋان مٴاتٴىن',
+'italic_sample' => 'قيعاش مٴاتٴىن',
+'italic_tip' => 'قيعاش مٴاتٴىن',
+'link_sample' => 'سٴىلتەمە اتاۋى',
+'link_tip' => 'ٴىشكٴى سٴىلتەمە',
+'extlink_sample' => 'http://www.example.com سٴىلتەمە اتاۋى',
+'extlink_tip' => 'سىرتقى سٴىلتەمە (الدىنان http:// ەنگٴىزۋٴىن ۇمىتپاڭىز)',
+'headline_sample' => 'تاقىرىپ مٴاتٴىنٴى',
+'headline_tip' => '1-شٴى دەڭگەيلٴى تاقىرىپ',
+'math_sample' => 'فورمۋلانى مىندا ەنگٴىزٴىڭٴىز',
+'math_tip' => 'ماتەماتيكا فورمۋلاسى (LaTeX)',
+'nowiki_sample' => 'پٴىشٴىمدەلمەيتٴىن مٴاتٴىندٴى وسىندا ەنگٴىزٴىڭٴىز',
+'nowiki_tip' => 'ۋيكي پٴىشٴىمٴىن ەلەمەۋ',
+'image_sample' => 'Example.jpg',
+'image_tip' => 'كٴىرٴىكتٴىرٴىلگەن سۋرەت',
+'media_sample' => 'Example.ogg',
+'media_tip' => 'تاسپا فايلىنىڭ سٴىلتەمەسٴى',
+'sig_tip' => 'قولتاڭباڭىز جٴانە ۋاقىت بەلگٴىسٴى',
+'hr_tip' => 'دەرەلەي سىزىق (ٴۇنەمدٴى قولدانىڭىز)',
+
+# Edit pages
+'summary' => 'سيپاتتاماسى',
+'subject' => 'تاقىرىبى/باسى',
+'minoredit' => 'بۇل شاعىن تٴۇزەتۋ',
+'watchthis' => 'بەتتٴى باقىلاۋ',
+'savearticle' => 'بەتتٴى ساقتا!',
+'preview' => 'قاراپ شىعۋ',
+'showpreview' => 'قاراپ شىعۋ',
+'showlivepreview' => 'تۋرا قاراپ شىعۋ',
+'showdiff' => 'ٴوزگەرٴىستەردٴى كٴورسەت',
+'anoneditwarning' => "'''نازار سالىڭىز:''' سٴىز جٴۇيەگە كٴىرمەگەنسٴىز. IP جايىڭىز بۇل بەتتٴىڭ ٴوڭدەۋ تاريحىندا جازىلىپ الىنادى.",
+'missingsummary' => "'''ەسكەرتۋ:''' تٴۇزەتۋ سيپاتتاماسىن ەنگٴىزبەپسٴىز. «ساقتاۋ» تٴۇيمەسٴىن تاعى باسساڭىز, تٴۇزەتۋٴىڭٴىز مٴاندەمەسٴىز ساقتالادى.",
+'missingcommenttext' => 'تٴومەندە مٴاندەمەڭٴىزدٴى ەنگٴىزٴىڭٴىز.',
+'missingcommentheader' => "'''ەسكەرتۋ:''' بۇل مٴاندەمەگە تاقىرىپ/باسجول جەتٴىستٴىرمەپسٴىز. ەگەر تاعى دا ساقتاۋ تٴۇيمەسٴىن نۇقىساڭىز, تٴۇزەتۋٴىڭٴىز سولسىز ساقتالادى.",
+'summary-preview' => 'سيپاتتاماسىن قاراپ شىعۋ',
+'subject-preview' => 'تاقىرىبىن/باسىن قاراپ شىعۋ',
+'blockedtitle' => 'پايدالانۋشى بۇعاتتالعان',
+'blockedtext' => "<big>'''قاتىسۋشى اتىڭىز نە IP جايىڭىز بۇعاتتالعان.'''</big>
+
+بۇعاتتاۋدى $1 ٴىستەگەن. بەلگٴىلەنگەن سەبەبٴى: ''$2''.
+
+وسى بۇعاتتاۋدى تالقىلاۋ ٴۇشٴىن $1 دەگەنمەن نە باسقا [[{{ns:project}}:ٴاكٴىمشٴىلەر|ٴاكٴىمشٴىمەن]] قاتىناسۋىڭىزعا بولادى.
+[[{{ns:special:Preferences|تٴىركەلگٴى باپتاۋلارىن]] قولدانىپ جارامدى ە-پوشتا جايىن ەنگٴىزگەنشە دەيٴىن
+«قاتىسۋشىعا حات جازۋ» قاسيەتٴىن پايدالانىلمايسىز. اعىمدىق IP جايىڭىز $3 بولعان. بۇنى ٴاربٴىر سۇرانىسىڭىزعا قوسىڭىز.",
+'blockedoriginalsource' => "تٴومەندە '''$1''' دەگەننٴىڭ قاينارى كٴورسەتٴىلەدٴى:",
+'blockededitsource' => "تٴومەندە '''$1''' دەگەنگە جاسالعان '''تٴۇزەتۋڭٴىزدٴىڭ''' مٴاتٴىنٴى كٴورسەتٴىلەدٴى:",
+'whitelistedittitle' => 'ٴوڭدەۋ ٴۇشٴىن كٴىرۋٴىڭٴىز جٴون.',
+'whitelistedittext' => 'بەتتەردٴى ٴوڭدەۋ ٴۇشٴىن $1 جٴون.',
+'whitelistreadtitle' => 'وقۋ ٴۇشٴىن كٴىرۋٴىڭٴىز جٴون',
+'whitelistreadtext' => 'بەتتەردٴى وقۋ ٴۇشٴىن [[{{ns:special}}:Userlogin|كٴىرۋٴىڭٴىز]] جٴون.',
+'whitelistacctitle' => 'سٴىزگە تٴىركەلگٴى جاساۋعا رۇقسات بەرٴىلمەگەن',
+'whitelistacctext' => 'وسى ۋيكيدە باسقالارعا تٴىركەلگٴى جاساۋ ٴۇشٴىن [[{{ns:Special}}:Userlogin|كٴىرۋٴىڭٴىز]] قاجەت جٴانە جاناسىمدى رۇقساتتارىن بيلەۋ قاجەت.',
+'confirmedittitle' => 'ە-پوشتا جايىن كۋٴالاندىرۋ حاتىن قايتا ٴوڭدەۋ قاجەت',
+'confirmedittext' => 'بەتتەردٴى ٴوڭدەۋ ٴۇشٴىن الدىن الا ە-پوشتا جايىڭىزدى كۋٴالاندىرۋىڭىز قاجەت. جايىڭىزدى [[{{ns:Special}}:Preferences|قاتىسۋشى باپتاۋى]] ارقىلى ەنگٴىزٴىڭٴىز جٴانە تەكسەرتكٴىڭٴىز.',
+'loginreqtitle' => 'كٴىرۋٴىڭٴىز قاجەت',
+'loginreqlink' => 'كٴىرۋ',
+'loginreqpagetext' => 'باسقا بەتتەردٴى كٴورۋ ٴۇشٴىن سٴىز $1 بولۋىڭىز قاجەت.',
+'accmailtitle' => 'قۇپييا سٴوز جٴىبەرٴىلدٴى.',
+'accmailtext' => '$2 جايىنا «$1» قۇپييا سٴوزٴى جٴىبەرٴىلدٴى.',
+'newarticle' => '(جاڭا)',
+'newarticletext' => 'سٴىلتەمەگە ەرٴىپ ٴالٴى باستالماعان بەتكە
+كەلٴىپسٴىز. بەتتٴى باستاۋ ٴۇشٴىن, تٴومەندەگٴى اۋماقتا مٴاتٴىنٴىڭٴىزدٴى
+تەرٴىڭٴىز (كٴوبٴىرەك اقپارات ٴۇشٴىن [[{{ns:help}}:مازمۇنى|كٴومەك بەتٴىن]]
+قاراڭىز).ەگەر جاڭىلعاننان وسىندا كەلگەن بولساڭىز, شولعىشىڭىز
+«ارتقا» دەگەن تٴۇيمەسٴىن نۇقىڭىز.',
+'anontalkpagetext' => "----''بۇل تٴىركەلگٴىسٴىز (نەمەسە تٴىركەلگٴىسٴىن قولدانباعان) پايدالانۋشىنىڭ تالقىلاۋ بەتٴى. وسى پايدالانۋشىنى بٴىز تەك ساندىق IP جايىمەن تەڭدەستٴىرەمٴىز. وسىنداي IP جايلار بٴىرنەشە پايدالانۋشىعا ورتاق بولۋى مٴۇمكٴىن. ەگەر سٴىز تٴىركەلگٴىسٴىز پايدالانۋشى بولساڭىز جٴانە سٴىزگە قاتىسسىز مٴاندەمەلەر جٴىبەرٴىلگەنٴىن سەزسەڭٴىز, باسقا تٴىركەلگٴىسٴىز پايدالانۋشىلارمەن ارالاستىرماۋى ٴۇشٴىن [[{{ns:special}}:Userlogin|تٴىركەلگٴى جاساڭىز نە كٴىرٴىڭٴىز]].''",
+'noarticletext' => 'بۇل بەتتە اعىمدا ەش مٴاتٴىن جوق, باسقا بەتتەردەن وسى بەت اتاۋىن [[{{ns:special}}:Search/{{PAGENAME}}|ٴىزدەپ كٴورۋٴىڭٴىزگە]] نەمەسە وسى بەتتٴى [{{fullurl:{{FULLPAGENAME}}|action=edit}} تٴۇزەتۋٴىڭٴىزگە] بولادى.',
+'clearyourcache' => "'''اڭعارتپا:''' ساقتاعاننان كەيٴىن ٴوزگەرٴىستەردٴى كٴورۋ ٴۇشٴىن شولعىش قوسالقى قالتاسىن بوساتۋ كەرەگٴى مٴۇمكٴىن. '''Mozilla / Safari:''' ''Shift'' پەرنەسٴىن باسىپ تۇرىپ ''Reload'' (''قايتا جٴۇكتەۋ'') تٴۇيمەسٴىن نۇقىڭىز (نە ''Ctrl-Shift-R'' باسىڭىز); ''IE:'' ''Ctrl-F5'' باسىڭىز; '''Opera / Konqueror''' ''F5'' پەرنەسٴىن باسىڭىز.",
+'usercssjsyoucanpreview' => '<strong>باسالقى:</strong> ساقتاۋ الدىندا جاڭا CSS/JS فايلىن تەكسەرۋ ٴۇشٴىن «قاراپ شىعۋ» تٴۇيمەسٴىن قولدانىڭىز.',
+'usercsspreview' => "'''مىناۋ CSS مٴاتٴىنٴىن تەك قاراپ شىعۋ ەكەنٴىن ۇمىتپاڭىز, ول ٴالٴى ساقتالعان جوق!'''",
+'userjspreview' => "'''مىناۋ JavaScript قاتىسۋشى باعدارلاماسىن تەكسەرۋ/قاراپ شىعۋ ەكەنٴىن ۇمىتپاڭىز, ول ٴالٴى ساقتالعان جوق!'''",
+'userinvalidcssjstitle' => "'''نازار سالىڭىز:''' مىندا «$1» اتاۋلى بەزەندٴىرۋ مٴانەرٴى جوق. پايدالانۋشىنىڭ .css جٴانە .js فايل اتاۋى كٴىشٴى ٴارٴىپپپەن جازىلاتىنىن ۇمىتپاڭىز, مىسالعا {{ns:user}}:Foo/monobook.css دەگەندٴى {{ns:user}}:Foo/Monobook.css دەگەنمەن سالىستىرىڭىز.",
+'updated' => '(جاڭارتىلعان)',
+'note' => '<strong>اڭعارتپا:</strong>',
+'previewnote' => '<strong>مىناۋ تەك قاراپ شىعۋ ەكەنٴىن ۇمىتپاڭىز; تٴۇزەتۋلەر ٴالٴى ساقتالعان جوق!</strong>',
+'session_fail_preview' => '<strong>عافۋ ەتٴىڭٴىز! سەسسييا دەرەكتەرٴى ىسىراپ قالعاندىقتان ٴوڭدەۋٴىڭٴىزدٴى جٴوندەي المايمىز.
+مٴاتٴىنٴىڭٴىزدٴى ساقتاپ قايتالاپ كٴورٴىڭٴىز. ەگەر ٴالٴى ٴىس ٴوتپەيتٴىن بولسا, شىعىپ جٴانە كەرٴى كٴىرٴىپ كٴورٴىڭٴىز.</strong>',
+'previewconflict' => 'بۇل قاراپ شىعۋ جوعارىداعى ٴوڭدەۋ اۋماعىنداعى مٴاتٴىنگە ساقتاعان كەزٴىندەگٴى دەي ىقپال ەتەدٴى.',
+'session_fail_preview_html' => "<strong>عافۋ ەتٴىڭٴىز! سەسسييا دەرەكتەرٴى ىسىراپ قالعاندىقتان ٴوڭدەۋٴىڭٴىزدٴى جٴوندەي المايمىز.</strong>
+
+''وسى ۋيكيدە قام HTML ەندٴىرٴىلگەن, JavaScript شابۋىلداردان قورعانۋ ٴۇشٴىن الدىن الا قاراپ شىعۋ جاسىرىلعان.''
+
+<strong>ەگەر بۇل ٴوڭدەۋ ادال تالاپ بولسا, قايتارىپ كٴورٴىڭٴىز. ەگەر ٴالٴى دە ٴىستەمەسە, شىعىپ, سوسىن كەرٴى كٴىرٴىپ كٴورٴىڭٴىز.</strong>",
+'importing' => 'سىرتتان الۋدا: $1',
+'editing' => 'ٴوڭدەۋدە: $1',
+'editinguser' => 'قاتىسۋشىنى ٴوڭدەۋدە: <b>$1</b>',
+'editingsection' => 'ٴوڭدەۋدە: $1 (بٴولٴىمٴى)',
+'editingcomment' => 'ٴوڭدەۋدە: $1 (مٴاندەمەسٴى)',
+'editconflict' => 'ٴوڭدەۋ ەگەسٴى: $1',
+'explainconflict' => 'وسى بەتتٴى سٴىز ٴوڭدەي باستاعاندا باسقا كەيبٴىرەۋ بەتتٴى ٴوزگەرتكەن.
+جوعارعى اۋماقتا بەتتٴىڭ اعىمدىق مٴاتٴىنٴى بار.
+تٴومەنگٴى اۋماقتا سٴىز ٴوزگەرتكەن مٴاتٴىنٴى كٴورسەتٴىلەدٴى.
+ٴوزگەرتۋٴىڭٴىزدٴى اعىمدىق مٴاتٴىنگە ٴۇستەۋٴىڭٴىز جٴون.
+"بەتتٴى ساقتا!" تٴۇيمەسٴىنە باسقاندا
+<b>تەك</b> جوعارعى اۋماقتاعى مٴاتٴىن ساقتالادى.<br />',
+'yourtext' => 'مٴاتٴىنٴىڭٴىز',
+'storedversion' => 'ساقتالعان نۇسقاسى',
+'nonunicodebrowser' => '<strong>اڭعارتپا: شولعىشىڭىز Unicode بەلگٴىلەۋٴىنە ٴۇيلەسٴىمدٴى ەمەس, سوندىقتان لاتىن ەمەس ٴارٴىپتەرٴى بار بەتتەردٴى ٴوڭدەۋ زٴىل بولۋ مٴۇمكٴىن. جۇمىس ٴىستەۋگە ىقتيمالدىق بەرۋ ٴۇشٴىن, <strong>تٴومەنگٴى ٴوڭدەۋ اۋماعىندا ASCII ەمەس ٴارٴىپتەر ونالتىلىق سانىمەن كٴورسەتٴىلەدٴى</strong>.',
+'editingold' => '<strong>اڭعارتپا: وسى بەتتٴىڭ ەرتەرەك نۇسقاسىن
+ٴوڭدەپ جاتىرسىز.
+بۇنى ساقتاساڭىز, وسى نۋسقادان سوڭعى بارلىق تٴۇزەتۋلەر جويىلادى.</strong>',
+'yourdiff' => 'ايىرمالار',
+'copyrightwarning' => '{{SITENAME}} جوباسىنا قوسىلعان بٴۇكٴىل ٴۇلەس $2 (كٴوبٴىرەك اقپارات ٴۇشٴىن: $1) قۇجاتىنا ساي جٴىبەرٴىلگەن بولىپ سانالادى. ەگەر جازۋىڭىزدىڭ ەركٴىن كٴوشٴىرٴىلٴىپ تٴۇزەتٴىلۋٴىن قالاماساڭىز, مىندا ۇسىنباۋىڭىز جٴون.<br />
+تاعى, قوسقان ٴۇلەسٴىڭٴىز - ٴوزٴىڭٴىزدٴىڭ جازعانىعىز, نە اشىق اقپارات كٴوزدەرٴىنەن الىنعان ماعلۇمات بولعانىن ۋٴادە ەتەسٴىز.<br />
+<strong>اۆتورلىق قۇقىقپەن قورعاۋلى اقپاراتتى رۇقساتسىز قوسپاڭىز!</strong>',
+'copyrightwarning2' => 'ەستە تۇرسىن: بارلىق {{SITENAME}} جوباسىنا بەرٴىلگەن ٴۇلەستەر باسقا ۋلەس بەرۋشٴىلەرمەن تٴۇزەتۋگە, ٴوزگەرتۋگە, نە الاستانۋعا مٴۇمكٴىن. العىسسىز تٴۇزەتۋگە ەنجارلان بولساڭىز, وندا شىعارماڭىزدى مىندا جارييالاماڭىز.<br />
+تاعى, وسىنى ٴوزٴىڭٴىز جازعانىڭىزدى, نە بارشا قازىناسىنان, نەمەسە سونداي-اق اقىسىز اشىق قاينارىنان كٴوشٴىرگەنٴىڭٴىزدٴى
+دٴال وسىنداي بٴىزگە مٴىندەتتەمە بەرەسٴىز (كٴوبٴىرەك اقپارات ٴۇشٴىن $1 قۋجاتىن قاراڭىز).<br />
+<strong>اۋتورلىق قۇقىقپەن قورعاۋلى اقپاراتتى رۇقساتسىز قوسپاڭىز!</strong>',
+'longpagewarning' => '<strong>نازار سالىڭىز: بۇل بەتتٴىڭ مٴولشەرٴى — $1 كيلوبايت; كەيبٴىر
+شولعىشتاردا بەت مٴولشەرٴى 32 كب جەتسە نە ونى اسسا ٴوڭدەۋ كٴۇردەلٴى بولۋى مٴۇمكٴىن.
+بەتتٴى بٴىرنەشە كٴىشكٴىن بٴولٴىمدەرگە بٴولٴىپ كٴورٴىڭٴىز.</strong>',
+'longpageerror' => '<strong>قاتە: جٴىبەرەتٴىن مٴاتٴىنٴىڭٴىزدٴىن مٴولشەرٴى — $1 كب, ەڭ كٴوبٴى $2 كب
+رۇقسات ەتٴىلگەن مٴولشەرٴىنەن اسقان. بۇل ساقتاي الىنبايدى.</strong>',
+'readonlywarning' => '<strong>نازار سالىڭىز: دەرەكقور جٴوندەتۋ ٴۇشٴىن قۇلىپتالعان,
+سوندىقتان دٴال قازٴىر تٴۇزەتۋٴىڭٴىزدٴى ساقتاي المايسىز. سوسىن قولدانۋعا ٴۇشٴىن مٴاتٴانٴىڭٴىزدٴى كٴوشٴىرٴىپ,
+ٴوز كومپٴۇتەرٴىڭٴىزدە فايلعا ساقتاڭىز.</strong>',
+'protectedpagewarning' => '<strong>نازار سالىڭىز: بۇل بەت قورعالعان. تەك ٴاكٴىمشٴى رۇقساتى بار قاتىسۋشىلار ٴوڭدەۋ جاساي الادى.</strong>',
+'semiprotectedpagewarning' => "'''اڭعارتپا:''' بەت [[{{ns:project}}:جارتىلاي قورعاۋ ساياساتى|قورعالعان]], سوندىقتان وسىنى تەك رۇقساتى بار قاتىسۋشىلار ٴوڭدەي الادى.",
+'templatesused' => 'بۇل بەتتە قولدانىلعان ٴۇلگٴىلەر:',
+'templatesusedpreview' => 'بۇنى قاراپ شىعۋعا قولدانىلعان ٴۇلگٴىلەر:',
+'templatesusedsection' => 'بۇل بٴولٴىمدە قولدانىلعان ٴۇلگٴىلەر:',
+'edittools' => '<!-- مىنداعى ماعلۇمات ٴوڭدەۋ جٴانە قوتارۋ ٴۇلگٴىتترٴىڭٴىڭ استىندا كٴورسەتٴىلەدٴى. -->',
+'nocreatetitle' => 'بەتتٴى باستاۋ شەكتەلگەن',
+'nocreatetext' => 'بۇل توراپتا جاڭا بەت باستاۋى شەكتەلگەن.
+كەرٴى قايتىپ بار بەتتٴى ٴوڭدەۋٴىڭٴىزگە بولادى, نەمەسە [[{{ns:special}}:Userlogin|كٴىرۋٴىڭٴىزگە نە تٴىركەلگٴى جاساۋعا]] بولادى.',
+'cantcreateaccounttitle' => 'تٴىركەلگٴى جاسالمادى',
+'cantcreateaccounttext' => 'وسى IP جايدان (<b>$1</b>) تٴىركەلگٴى جاساۋى بۇعاتتالعان.
+بٴالكٴىم سەبەبٴى, وقۋ ورنىڭىزدان, نەمەسە ينتەرنەت جەتكٴىزۋشٴىدەن
+ٴۇزبەي بۇزاقىلىق بولعانى.',
+
+# History pages
+'revhistory' => 'نۇسقالار تاريحى',
+'viewpagelogs' => 'وسى بەتكە قاتىستى جۋرنالداردى قاراۋ',
+'nohistory' => 'وسى بەتتٴىنٴىڭ نۇسقالار تاريحى جوق.',
+'revnotfound' => 'نۇسقا تابىلمادى',
+'revnotfoundtext' => 'وسى سۇرانىسقان بەتتٴىڭ ەسكٴى نۇسقاسى تابىلعان جوق.
+وسى بەتتٴى اشۋعا پايدالانعان URL جايىن قايتا تەكسەرٴىپ شىعىڭىز.',
+'loadhist' => 'بەت تاريحىن جٴۇكتەۋٴى',
+'currentrev' => 'اعىمدىق نۇسقاسى',
+'revisionasof' => '$1 كەزٴىندەگٴى نۇسقاسى',
+'revision-info' => '$1 كەزٴىندەگٴى $2 جاساعان نۇسقاسى',
+'previousrevision' => '← ەسكٴىلەۋ نۇسقاسى',
+'nextrevision' => 'جاڭالاۋ نۇسقاسى →',
+'currentrevisionlink' => 'اعىمدىق نۇسقاسى',
+'cur' => 'اعىم.',
+'next' => 'كەل.',
+'last' => 'سوڭ.',
+'orig' => 'تٴۇپ.',
+'histlegend' => 'ايىرماسىن كٴورۋ: سالىستىرامىن دەگەن نۇسقالاردى تاڭداپ, نە <Enter> پەرنەسٴىن, نە تٴومەندەگٴى تٴۇيمەنٴى باسىڭىز.<br />
+شارتتى بەلگٴىلەر: (اعىم.) = اعىمدىق نۇسقامەن ايىرماسى,
+(سوڭ.) = الدىڭعى نۇسقامەن ايىرماسى, ش = شاعىن تٴۇزەتۋ',
+'deletedrev' => '[جويىلعان]',
+'histfirst' => 'ەڭ العاشقىسىنا',
+'histlast' => 'ەڭ سوڭعىسىنا',
+'rev-deleted-comment' => '(مٴاندەمە الاستاتىلدى)',
+'rev-deleted-user' => '(قاتىسۋشى اتى الاستاتىلدى)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+وسى بەتتٴىڭ نۇسقاسى جارييا مۇراعاتتارىنان الاستاتىلعان.
+بۇل جايتقا [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} جويۋ جۋرنالىندا] ەگجەي-تەگجەي مٴالٴىمەتتەر بولۋى مٴۇمكٴىن.
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+وسى بەتتٴىڭ نۇسقاسى جارييا مۇراعاتتارىنان الاستاتىلعان.
+سونى وسى توراپتىڭ ٴاكٴىمشٴىسٴى بوپ كٴورۋٴىڭٴىز مٴۇمكٴىن;
+بۇل جايتقا [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} جويۋ جۋرنالىندا] ەگجەي-تەگجەي مٴالمەتتەر بولۋى مٴۇمكٴىن.
+</div>',
+'rev-delundel' => 'كٴورسەت/جاسىر',
+
+'history-feed-title' => 'نۇسقالار تاريحى',
+'history-feed-description' => 'بۇل بەتتٴىڭ ۋيكيدەگٴى نۇسقالار تاريحى',
+'history-feed-item-nocomment' => '$1 دەگەن $2 كەزٴىندە', # user at time
+'history-feed-empty' => 'سۇرانعان بەت جوق.
+بۇل بەت ۋيكيدەن جويىلعان, نەمەسە قايتا اتالعان.
+سٴايكەسٴى بار جاڭا بەتتەردٴى [[{{ns:special}}:Search|ۋيكيدەن ٴىزدەپ]] قاراڭىز.',
+
+# Revision deletion
+'revisiondelete' => 'نۇسقالاردى جويۋ/قايتارۋ',
+'revdelete-nooldid-title' => 'نىسانا نۇسقاسى جوق',
+'revdelete-nooldid-text' => 'وسى ٴارەكەتتٴى ورىنداۋ ٴۇشٴىن اقىرعى نۇسقاسىن
+نە نۇسقالارىن ەنگٴىزبەپسٴىز.',
+'revdelete-selected' => '[[:$1]] دەگەننٴىڭ تالعانىلعان نۇسقاسى:',
+'revdelete-text' => 'جويىلعان نۇسقالاردى ٴالٴى دە بەت تاريحىندا كٴورۋگە بولادى,
+بٴىراق ونىڭ مٴاتٴىن ماعلۇماتى بارشاعا قاتىنالمايدى.
+
+وسى ۋيكيدٴىڭ باسقا ٴاكٴىمشٴىلەرٴى جاسىرىن ماعلۇماتقا قاتىناي الادى,
+جٴانە توراپ وپەراتورلارى قوسىمشا شەكتەۋ ەندٴىرگەنشە دەيٴىن,
+وسى تٴىلدەسۋ ارقىلى جويىلعاندى كەرٴى قايتارا الادى.',
+'revdelete-legend' => 'نۇسقانىنىڭ شەكتەۋلەرٴى:',
+'revdelete-hide-text' => 'نۇسقا مٴاتٴىنٴىن جاسىر',
+'revdelete-hide-comment' => 'تٴۇزەتۋ مٴاندەمەسٴىن جاسىر',
+'revdelete-hide-user' => 'ٴوڭدەۋشٴى اتىن (IP جايىن) جاسىر',
+'revdelete-hide-restricted' => 'وسى شەكتەۋلەردٴى بارشاعا سيياقتى ٴاكٴىمشٴىلەرگە دە قولدانۋ',
+'revdelete-log' => 'جۋرنال مٴاندەمەسٴى:',
+'revdelete-submit' => 'تالعانعان نۇسقاعا قولدانۋ',
+'revdelete-logentry' => '[[$1]] دەگەنگە نۇسقا كٴورٴىنٴىسٴىن ٴوزگەرتتٴى',
+
+# Diffs
+'difference' => '(نۇسقالار اراسىنداعى ايىرماشىلىق)',
+'loadingrev' => 'ايىرما ٴۇشٴىن نۇسقا جٴۇكتەۋ',
+'lineno' => 'جول $1:',
+'editcurrent' => 'وسى بەتتٴىڭ اعىمدىق نۇسقاسىن ٴوڭدەۋ',
+'selectnewerversionfordiff' => 'سالىستىرۋ ٴۇشٴىن جاڭالاۋ نۇسقاسىن تالعاڭىز',
+'selectolderversionfordiff' => 'سالىستىرۋ ٴۇشٴىن ەسكٴىلەۋ نۇسقاسىن تالعاڭىز',
+'compareselectedversions' => 'تاڭداعان نۇسقالاردى سالىستىرۋ',
+
+# Search results
+'searchresults' => 'ٴىزدەستٴىرۋ نٴاتيجەلەرٴى',
+'searchresulttext' => 'وسى {{SITENAME}} جوباسىندا ٴىزدەستٴىرۋ تۋرالى كٴوبٴىرەك اقپارات ٴۇشٴىن, [[{{ns:project}}:ٴىزدەۋ|{{SITENAME}} ٴىزدەۋ نۇسقاۋلارىن]] قاراڭىز.',
+'searchsubtitle' => "ٴىزدەستٴىرۋ سۇرانىسىڭىز: '''[[:$1]]'''",
+'searchsubtitleinvalid' => "ٴىزدەستٴىرۋ سۇرانىسىڭىز: '''$1'''",
+'badquery' => 'ٴىزدەستٴىرۋ سۇرانىس جارامسىز پٴىشٴىمدەلگەن',
+'badquerytext' => 'عافۋ ەتٴىڭٴىز, سۇرانىسىڭىزدى ورىنداي المادىق.
+بۇل ٴۇش ٴارٴىپتەن كەم سٴوزدٴى ٴىزدەستٴىرۋگە تالاپتانعانىڭىزدان
+بولۋعا مٴۇمكٴىن, ول ٴالٴى دە سٴۇيەمەلدەنبەگەن.
+تاعى دا بۇل سٴويلەمدٴى دۇرىس ەنگٴىزبەگەندٴىكتەن دە بولۋعا مٴۇمكٴىن,
+مىسالى, «بالىق جٴانە جٴانە قابىرشاق».
+باسقا سۇرانىس جاساپ كٴورٴىڭٴىز',
+'matchtotals' => '«$1» ٴىزدەستٴىرۋ سۇرانىسى $2 بەتتٴىڭ اتاۋىنا
+جٴانە $3 بەتتٴىڭ مٴاتٴىنٴىنە سٴايكەس.',
+'noexactmatch' => "'''وسىندا «$1» اتاۋلى بەت جوق.''' بۇل بەتتٴى ٴوزٴىڭٴىز '''[[:$1|باستاي الاسىز]].'''",
+'titlematches' => 'بەت اتاۋى سٴايكەسٴى',
+'notitlematches' => 'ەش بەت اتاۋى سٴايكەس ەمەس',
+'textmatches' => 'بەت مٴاتٴىنٴىڭ سٴايكەسٴى',
+'notextmatches' => 'ەش بەت مٴاتٴىنٴى سٴايكەس ەمەس',
+'prevn' => 'الدىڭعى $1',
+'nextn' => 'كەلەسٴى $1',
+'viewprevnext' => 'كٴورسەتٴىلۋٴى: ($1) ($2) ($3) جازبا.',
+'showingresults' => 'تٴومەندە نٴومٴىر <b>$2</b> دەگەننەن باستاپ <b>$1</b> نٴاتيجەگە دەيٴىن كٴورسەتٴىلگەن.',
+'showingresultsnum' => 'تٴومەندە نٴومٴىر <b>$2</b> دەگەننەن باستاپ <b>$3</b> نٴاتيجە كٴورسەتٴىلگەن.',
+'nonefound' => "'''اڭعارتپا''': تابۋ سٴاتسٴىز بٴىتۋٴى جيٴى «بولعان» جٴانە «دەگەن» سيياقتى
+تٴىزٴىمدەلمەيتٴىن جالپى سٴوزدەرمەن ٴىزدەستٴىرۋدەن بولۋى مٴۇمكٴىن,
+نەمەسە بٴىردەن ارتىق ٴىزدەستٴىرۋ شارت سٴوزدەرٴىن ەگٴىزگەننەن (نٴاتيجەلەردە تەك
+بارلىق شارت سٴوزدەر كەدەسسە كٴورسەتٴىلەدٴى) بولۋى مٴۇمكٴىن.",
+'powersearch' => 'ٴىزدەۋ',
+'powersearchtext' => 'مىنا ەسٴىم ايالاردا ٴىزدەۋ:<br />$1<br />$2 ايداتۋلاردى تٴىزٴىمدەۋ<br />ٴىزدەستٴىرۋ سۇرانىسى: $3 $9',
+'searchdisabled' => '{{SITENAME}} جوباسىندا ٴىشكٴى ٴىزدەۋٴى ٴوشٴىرٴىلگەن. ٴازٴىرشە Google نەمەسە Yahoo! ارقىلى ٴىزدەۋگە بولادى. اڭعارتپا: {{SITENAME}} ماعلۇمات تٴىزٴىمٴىدەۋلەرٴى ولاردا ەسكٴىرگەن بولۋعا مٴۇمكٴىن.',
+'blanknamespace' => '(نەگٴىزگٴى)',
+
+# Preferences page
+'preferences' => 'باپتاۋلار',
+'mypreferences' => 'باپتاۋىم',
+'prefsnologin' => 'كٴىرمەگەنسٴىز',
+'prefsnologintext' => 'باپتاۋلاردى قالاۋ ٴۇشٴىن الدىن الا [[{{ns:special}}:Userlogin|كٴىرۋٴىڭٴىز]] قاجەت.',
+'prefsreset' => 'باپتاۋلار ارقاۋدان قايتا ورناتىلدى.',
+'qbsettings' => 'مٴازٴىر ايماعى',
+'changepassword' => 'قۇپييا سٴوز ٴوزگەرتۋ',
+'skin' => 'بەزەندٴىرۋ',
+'math' => 'ماتەماتيكا',
+'dateformat' => 'كٴۇن-اي پٴىشٴىمٴى',
+'datedefault' => 'ەش قالاۋسىز',
+'datetime' => 'ۋاقىت',
+'math_failure' => 'ٴوڭدەتۋ سٴاتسٴىز بٴىتتٴى',
+'math_unknown_error' => 'بەلگٴىسٴىز قاتە',
+'math_unknown_function' => 'بەلگٴىسٴىز فۋنكتسييا',
+'math_lexing_error' => 'لەكسيكا قاتەسٴى',
+'math_syntax_error' => 'سينتاكسيس قاتەسٴى',
+'math_image_error' => 'PNG اۋدارىسى سٴاتسٴىز بٴىتتٴى; latex, dvips, gs جٴانە convert باعدارلامالارىنىڭ مٴۇلتٴىكسٴىز ورناتۋىن تەكسەرٴىڭٴىز',
+'math_bad_tmpdir' => 'ماتەماتيكانىڭ ۋاقىتشا قالتاسىنا جازىلمادى, نە قالتا جاسالمادى',
+'math_bad_output' => 'ماتەماتيكانىڭ بەرٴىس قالتاسىنا جازىلمادى, نە قالتا جاسالمادى',
+'math_notexvc' => 'texvc باعدارلاماسى جوعالتىلعان; باپتاۋ ٴۇشٴىن math/README قۇجاتىن قاراڭىز.',
+'prefs-personal' => 'جەكە دەرەكتەرٴى',
+'prefs-rc' => 'جۋىقتاعى ٴوزگەرٴىستەر',
+'prefs-watchlist' => 'باقىلاۋ',
+'prefs-watchlist-days' => 'باقىلاۋ تٴىزٴىمٴىندە كٴورسەتەرٴىن كٴۇن سانى:',
+'prefs-watchlist-edits' => 'كەڭەيتٴىلگەن باقىلاۋ تٴىزٴىمٴى تٴۇزەتۋ كٴورسەتەرٴىن سانى:',
+'prefs-misc' => 'قوسىمشا',
+'saveprefs' => 'ساقتا',
+'resetprefs' => 'تاستا',
+'oldpassword' => 'اعىمدىق قۇپييا سٴوز:',
+'newpassword' => 'جاڭا قۇپييا سٴوز:',
+'retypenew' => 'جاڭا قۇپييا سٴوزدٴى قايتالاڭىز:',
+'textboxsize' => 'ٴوڭدەۋ',
+'rows' => 'جولدار:',
+'columns' => 'باعاندار:',
+'searchresultshead' => 'ٴىزدەۋ',
+'resultsperpage' => 'بەت سايىن نٴاتيجە سانى:',
+'contextlines' => 'نٴاتيجە سايىن جول سانى:',
+'contextchars' => 'جول سايىن ٴارٴىپ سانى:',
+'stubthreshold' => 'بٴىتەمە كٴورستەتۋٴىن انىقتاۋ تابالدىرىعى:',
+'recentchangescount' => 'جۋىقتاعى ٴوزگەرٴىستەردەگٴى اتاۋلار:',
+'savedprefs' => 'باپتاۋلارىڭىز ساقتالدى.',
+'timezonelegend' => 'ۋاقىت بەلدەۋٴى',
+'timezonetext' => 'جەرگٴىلٴىكتٴى ۋاقىتىڭىزبەن سەرۆەر ۋاقىتىنىڭ (UTC) اراسىنداعى ساعات سانى.',
+'localtime' => 'جەرگٴىلٴىكتٴى ۋاقىت',
+'timezoneoffset' => 'ىعىستىرۋ¹',
+'servertime' => 'سەرۆەر ۋاقىتى',
+'guesstimezone' => 'شولعىشتان الىپ تولتىرۋ',
+'allowemail' => 'باسقادان حات قابىلداۋىن ەندٴىرۋ',
+'defaultns' => 'مىنا ەسٴىم ايالاردا ٴادەپكٴىدەن ٴىزدەۋ:',
+'default' => 'ٴادەپكٴى',
+'files' => 'فايلدار',
+
+# User rights
+'userrights-lookup-user' => 'قاتىسۋشى توپتارىن مەڭگەرۋ',
+'userrights-user-editname' => 'قاتىسۋشى اتىن ەنگٴىزٴىڭٴىز:',
+'editusergroup' => 'قاتىسۋشى توپتارىن ٴوڭدەۋ',
+'userrights-editusergroup' => 'قاتىسۋشى توپتارىن ٴوڭدەۋ',
+'saveusergroups' => 'قاتىسۋشى توپتارىن ساقتاۋ',
+'userrights-groupsmember' => 'مٴۇشەلٴىگٴى:',
+'userrights-groupsavailable' => 'قاتىناۋلى توپتار:',
+'userrights-groupshelp' => 'قاتىسۋشىنى ٴۇستەيتٴىن نە الاستاتىن توپتاردى تالعاڭىز.
+تالعاۋى ٴوشٴىرٴىلگەن توپتار ٴوزگەرتٴىلٴىمەيدٴى. توپتاردىڭ تالعاۋىن CTRL + سول جاق نۇقۋمەن ٴوشٴىرۋٴىڭٴىزگە بولادى.',
+
+# Groups
+'group' => 'توپ:',
+'group-bot' => 'بوتتار',
+'group-sysop' => 'ٴاكٴىمشٴىلەر',
+'group-bureaucrat' => 'تٴورەشٴىلەر',
+'group-all' => '(بارلىعى)',
+
+'group-bot-member' => 'بوت',
+'group-sysop-member' => 'ٴاكٴىمشٴى',
+'group-bureaucrat-member' => 'تٴورەشٴى',
+
+'grouppage-bot' => '{{ns:project}}:بوتتار',
+'grouppage-sysop' => '{{ns:project}}:ٴاكٴىمشٴىلەر',
+'grouppage-bureaucrat' => '{{ns:project}}:تٴورەشٴىلەر',
+
+# Recent changes
+'changes' => 'ٴوزگەرٴىس',
+'recentchanges' => 'جۋىقتاعى ٴوزگەرٴىستەر',
+'recentchangestext' => 'بۇل بەتتە وسى ۋيكيدەگٴى بولعان جۋىقتاعى ٴوزگەرٴىستەر بايقالادى.',
+'rcnote' => '$3 كەزٴىنە دەيٴىن — تٴومەندە سوڭعى <strong>$2</strong> كٴۇندەگٴى, سوڭعى <strong>$1</strong> ٴوزگەرٴىس كٴورسەتٴىلگەن.',
+'rcnotefrom' => '<b>$2</b> كەزٴىنەن بەرٴى — تٴومەندە ٴوزگەرٴىستەر <b>$1</b> دەيٴىن كٴورسەتٴىلگەن.',
+'rclistfrom' => '$1 كەزٴىنەن بەرٴى — جاڭا ٴوزگەرٴىستەردٴى كٴورسەت.',
+'rcshowhideminor' => 'شاعىن تٴۇزەتۋدٴى $1',
+'rcshowhidebots' => 'بوتتاردى $1',
+'rcshowhideliu' => 'تٴىركەلگەندٴى $1',
+'rcshowhideanons' => 'تٴىركەلگٴىسٴىزدٴى $1',
+'rcshowhidepatr' => 'كٴۇزەتتەگٴى تٴۇزەتۋلەردٴى $1',
+'rcshowhidemine' => 'تٴۇزەتۋٴىمدٴى $1',
+'rclinks' => 'سوڭعى $2 كٴۇندە بولعان, سوڭعى $1 ٴوزگەرٴىستٴى كٴورسەت<br />$3',
+'diff' => 'ايىرم.',
+'hist' => 'تار.',
+'hide' => 'جاسىر',
+'show' => 'كٴورسەت',
+'minoreditletter' => 'ش',
+'newpageletter' => 'ج',
+'boteditletter' => 'ب',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[باقىلاعان $1 قاتىسۋشى]',
+'rc_categories' => 'ساناتتارعا شەكتەۋ ("|" بەلگٴىسٴىمەن بٴولٴىكتەڭٴىز)',
+'rc_categories_any' => 'قايسىبٴىر',
+
+# Upload
+'upload' => 'فايل قوتارۋ',
+'uploadbtn' => 'قوتار!',
+'reupload' => 'قايتالاپ قوتارۋ',
+'reuploaddesc' => 'قوتارۋ ٴۇلگٴىتٴىنە ورالۋ.',
+'uploadnologin' => 'كٴىرمەگەنسٴىز',
+'uploadnologintext' => 'فايل قوتارۋ ٴۇشٴىن
+[[{{ns:special}}:Userlogin|كٴىرۋٴىڭٴىز]] قاجەت.',
+'upload_directory_read_only' => 'قوتارۋ قالتاسىنا ($1) جازۋعا ۆەب-سەرۆەرگە رۇقسات بەرٴىلمەگەن.',
+'uploaderror' => 'قوتارۋ قاتەسٴى',
+'uploadtext' => "تٴومەندەگٴى ٴۇلگٴىت فايل قوتارۋعا قولدانىلادى, الدىنداعى سۋرەتتەردٴى قاراۋ ٴۇشٴىن نە ٴىزدەۋ ٴۇشٴىن [[{{ns:special}}:Imagelist|قوتارىلعان فايلدار تٴىزٴىمٴىنە]] بارىڭىز, قوتارۋ مەن جويۋ تاعى دا [[{{ns:special}}:Log/upload|قوتارۋ جۋرنالىنا]] جازىلىپ الىنادى.
+
+سۋرەتتەردٴى بەتكە كٴىرگٴىزۋ ٴۇشٴىن, فايلعا تۋرا بايلانىستراتىن
+'''<nowiki>[[{{ns:image}}:File.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:File.png|بالاما مٴاتٴىن]]</nowiki>''' نەمەسە
+'''<nowiki>[[{{ns:media}}:File.ogg]]</nowiki>''' سٴىلتەمە پٴىشٴىمٴىن قولدانىڭىز.",
+'uploadlog' => 'قوتارۋ جۋرنالى',
+'uploadlogpage' => 'قوتارۋ جۋرنالى',
+'uploadlogpagetext' => 'تٴومەندە جۋىقتاعى قوتارىلعان فايل تٴىزٴىمٴى.',
+'filename' => 'فايل اتى',
+'filedesc' => 'سيپاتتاماسى',
+'fileuploadsummary' => 'سيپاتتاماسى:',
+'filestatus' => 'اۋتورلىق قۇقىقتارى كٴۇيٴى',
+'filesource' => 'فايل قاينارى',
+'copyrightpage' => '{{ns:project}}:اۋتورلىق قۇقىقتار',
+'copyrightpagename' => '{{SITENAME}} اۋتورلىق قۇقىقتارى',
+'uploadedfiles' => 'قوتارىلعان فايلدار',
+'ignorewarning' => 'نازار سالۋدى ەلەمەۋ جٴانە فايلدى ٴاردەقاشان ساقتاۋ.',
+'ignorewarnings' => 'ٴارقايسى نازار سالۋلاردى ەلەمەۋ',
+'minlength' => 'فايل اتىندا ەڭ كەمٴىندە ٴۇش ٴارٴىپ بولۋى كەرەك.',
+'illegalfilename' => '«$1» فايل اتاۋىندا بەت اتاۋلارىندا رۇقسات ەتٴىلمەگەن نىشاندار بار. فايلدى قايتا اتاڭىز, سوسىن قايتا جۋكتەپ كٴورٴىڭٴىز.',
+'badfilename' => 'فايلدىڭ اتى «$1» بوپ ٴوزگەرتٴىلدٴى.',
+'badfiletype' => '«.$1» ۇسىنىلماعان سۋرەت فايلىنىڭ كەڭەيتٴىمٴى.',
+'largefile' => 'فايل مٴولشەرٴىن $1 بايتتان اسىرماۋعا تىرىسىڭىز, بۇل فايل مٴولشەرٴى $2 بايت',
+'largefileserver' => 'وسى فايلدىڭ مٴولشەرٴى سەرۆەردٴىڭ قالاۋىنان اسىپ كەتكەن.',
+'emptyfile' => 'قوتارىلعان فايلىڭىز بوس سيياقتى. بۇل فايل اتاۋى جانساق ەنگٴىزٴىلگەنٴىنەن بولۋى مٴۇمكٴىن. قوتارعىڭىز كەلگەن فايل شىنىندا دا وسى فايل بولعانىن تەكسەرٴىپ الىڭىز.',
+'fileexists' => 'وسىنداي اتاۋلى فايل بار تٴۇگە. قايتا جازۋدىڭ الدىنان $1 تەكسەرٴىپ شىعىڭىز.',
+'fileexists-forbidden' => 'وسىنداي اتاۋلى فايل بار تٴۇگە. كەرٴى قايتىڭىز دا, جٴانە وسى فايلدى باسقا اتىمەن قوتارىڭىز. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'وسىنداي اتاۋلى فايل ورتاق فايل ارقاۋىندا بار تٴۇگە. كەرٴى قايتىڭىز دا, وسى فايلدى جاڭا اتىمەن قوتارىڭىز. [[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'قوتارۋ سٴاتتٴى ٴوتتٴى',
+'fileuploaded' => '«$1» فايلى سٴاتتٴى قوتارىلدى!
+وسى سٴىلتەمەگە ەرٴىپ — $2, سيپاتتاما بەتٴىنە بارىڭىز دا, جٴانە وسى فايل تۋرالى
+اقپارات تولتىرىڭىز: قايدان الىنعانىن, قاشان جاسالعانىن, كٴىم جاساعانىن,
+تاعى باسقا بٴىلەتٴىڭٴىزدٴى. بۇل سۋرەت بولسا, مىناداي پٴىشٴىمٴىمەن كٴىرٴىستٴىرۋگە بولادى: <tt><nowiki>[[سۋرەت:$1|thumb|سيپاتتاماسى]]</nowiki></tt>',
+'uploadwarning' => 'قوتارۋ تۋرالى نازار سالۋ',
+'savefile' => 'فايلدى ساقتاۋ',
+'uploadedimage' => '«[[$1]]» فايلىن قوتاردى',
+'uploaddisabled' => 'فايل قوتارۋى ٴوشٴىرٴىلگەن',
+'uploaddisabledtext' => 'وسى ۋيكيدە فايل قوتارۋى ٴوشٴىرٴىلگەن.',
+'uploadscripted' => 'وسى فايلدا, ۆەب شولعىشتى اعات تٴۇسٴىندٴىككە كەلتٴىرەتٴىڭ HTML بەلگٴىلەۋ, نە سكريپت كودى بار.',
+'uploadcorrupt' => 'وسى فايل بٴۇلدٴىرٴىلگەن, نە ٴادەپسٴىز كەڭەيتٴىمٴى بار. فايلدى تەكسەرٴىپ, قوتارۋىن قايتالاڭىز.',
+'uploadvirus' => 'وسى فايلدا ۆيرۋس بولۋى مٴۇمكٴىن! ەگجەي-تەگجەي اقپاراتى: $1',
+'sourcefilename' => 'قاينارداعى فايل اتى',
+'destfilename' => 'اقىرعى فايل اتى',
+'watchthisupload' => 'وسى بەتتٴى باقىلاۋ',
+'filewasdeleted' => 'وسى اتاۋى بار فايل بۇرىن قوتارىلعان, سوسىن جويىلدىرىلعان. قايتا قوتارۋ الدىنان $1 دەگەندٴى تەكسەرٴىڭٴىز.',
+
+'upload-proto-error' => 'جارامسىز حاتتامالىق',
+'upload-proto-error-text' => 'سىرتتان قوتارۋ ٴۇشٴىن URL جايلارى <code>http://</code> نەمەسە <code>ftp://</code> دەگەندەردەن باستالۋ قاجەت.',
+'upload-file-error' => 'ٴىشكٴى قاتە',
+'upload-file-error-text' => 'سەرۆەردە ۋاقىتشا فايل جاساۋى ٴىشكٴى قاتەگە ۇشىراستى. بۇل جٴۇيەنٴىڭ ٴاكٴىمشٴىمەن قاتىناسىڭىز.',
+'upload-misc-error' => 'بەلگٴىسٴىز قوتارۋ قاتەسٴى',
+'upload-misc-error-text' => 'قوتارۋ كەزٴىندە بەلگٴىسٴىز قاتە ۇشىراستى. قايسى URL جايى جارامدى جٴانە قاتىناۋلى ەكەنٴىن تەكسەرٴىپ شىعىڭىز دا قايتالاپ كٴورٴىڭٴىز. ەگەر بۇل مٴاسەلە ٴالدە دە قالسا, جٴۇيە ٴاكٴىمشٴىمەن قاتىناسىڭىز.',
+
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => 'URL جايى جەتٴىلمەدٴى',
+'upload-curl-error6-text' => 'بەرٴىلگەن URL جايى جەتٴىلمەدٴى. قايسى URL جايى دۇرىس ەكەنٴىن جٴانە توراپ ٴىستە ەكەنٴىن قايتالاپ قاتاڭ تەكسەرٴىڭٴىز.',
+'upload-curl-error28' => 'قوتارۋعا بەرٴىلگەن ۋاقىت بٴىتتٴى',
+'upload-curl-error28-text' => 'توراپتىڭ جاۋاپ بەرۋٴى تىم ۇزاق ۋاقىتقا سوزىلدى. بۇل توراپ ٴىستە ەكەنٴىن تەكسەرٴىپ شىعىڭىز, از ۋاقىت كٴىدٴىرە تۇرىڭىز دا تاعى قايتالاپ كٴورٴىڭٴىز. تالابىڭىزدى جٴۇكتەلۋٴى ازداۋ كەزٴىندە قايتالاۋعا بولمىس.',
+
+'license' => 'ليتسەنزيياسى',
+'nolicense' => 'ەشتەڭە تالعانباعان',
+'upload_source_url' => ' (جارامدى, بارشاعا قاتىناۋلى URL جاي)',
+'upload_source_file' => ' (كومپييۋتەرٴىڭٴىزدەگٴى فايل)',
+
+# Image list
+'imagelist' => 'فايل تٴىزٴىمٴى',
+'imagelisttext' => "تٴومەندە ''$2'' سۇرىپتالعان '''$1''' فايل تٴىزٴىمٴى.",
+'imagelistforuser' => 'مىندا تەك $1 جٴۇكتەگەن سۋرەتتەر كٴورسەتٴىلەدٴى.',
+'getimagelist' => 'فايل تٴىزٴىمدەۋٴى',
+'ilsubmit' => 'ٴىزدەۋ',
+'showlast' => 'سوڭعى $1 فايل $2 سۇرىپتاپ كٴورسەت.',
+'byname' => 'اتىمەن',
+'bydate' => 'كٴۇن-ايمەن',
+'bysize' => 'مٴولشەرٴىمەن',
+'imgdelete' => 'جويۋ',
+'imgdesc' => 'سيپپ.',
+'imgfile' => 'فايل',
+'imglegend' => 'شارتتى بەلگٴىلەر: (سيپپ.) — فايل سيپاتتاماسىن كٴورسەتۋ/ٴوڭدەۋ.',
+'imghistory' => 'فايل تاريحى',
+'revertimg' => 'قايت.',
+'deleteimg' => 'جويۋ',
+'deleteimgcompletely' => 'وسى فايلدىڭ بارلىق نۇسقالارىن جوي',
+'imghistlegend' => 'شارتتى بەلگٴىلەر: (اعىم.) = اعىمدىق فايل, (جويۋ) = ەسكٴى نۇسقاسىن
+جويۋ, (قاي.) = ەسكٴى نۇسقاسىنا قايتارۋ.
+<br /><i>قوتارىلعان فايلدى كٴورۋ ٴۇشٴىن كٴۇن-ايىنا نۇقىڭىز</i>.',
+'imagelinks' => 'سٴىلتەمەلەرٴى',
+'linkstoimage' => 'بۇل فايلعا كەلەسٴى بەتتەر سٴىلتەيدٴى:',
+'nolinkstoimage' => 'بۇل فايلعا ەش بەت سٴىلتەمەيدٴى.',
+'sharedupload' => 'بۇل فايل ورتاق ارقاۋىنا قوتارىلعان سوندىقتان باسقا جوبالاردا قولدانۋى مٴۇمكٴىن.',
+'shareduploadwiki' => 'بىلايعى اقپارات ٴۇشٴىن $1 دەگەندٴى قاراڭىز.',
+'shareduploadwiki-linktext' => 'فايل سيپاتتاماسى بەتٴى',
+'noimage' => 'مىناداي اتاۋلى فايل جوق, $1 مٴۇمكٴىندٴىگٴىڭٴىز بار.',
+'noimage-linktext' => 'وسىنى قوتارۋ',
+'uploadnewversion-linktext' => 'بۇل فايلدىڭ جاڭا نۇسقاسىن قوتارۋ',
+'imagelist_date' => 'كٴۇن-ايى',
+'imagelist_name' => 'اتاۋى',
+'imagelist_user' => 'قاتىسۋشى',
+'imagelist_size' => 'مٴولشەرٴى (بايت)',
+'imagelist_description' => 'سيپاتتاماسى',
+'imagelist_search_for' => 'سۋرەتتٴى اتىمەن ٴىزدەۋ:',
+
+# MIME search
+'mimesearch' => 'فايلدى MIME تٴۇرٴىمەن ٴىزدەۋ',
+'mimetype' => 'MIME تٴۇرٴى:',
+'download' => 'جٴۇكتەۋ',
+
+# Unwatched pages
+'unwatchedpages' => 'باقىلانباعان بەتتەر',
+
+# List redirects
+'listredirects' => 'ايداتۋ بەت تٴىزٴىمٴى',
+
+# Unused templates
+'unusedtemplates' => 'پايدالانىلماعان ٴۇلگٴىلەر',
+'unusedtemplatestext' => 'بۇل بەت باسقا بەتكە كٴىرٴىcتٴىرٴىلمەگەن ٴۇلگٴى ەسٴىم اياىسىنداعى بارلىق بەتتەردٴى تٴىزٴىمدەيدٴى. ٴۇلگٴىلەردٴى جويۋ الدىنان بۇنىڭ باسقا سٴىلتەمەلەرٴىن تەكسەرٴىپ شىعۋىن ۇمىتپاڭىز',
+'unusedtemplateswlh' => 'باسقا سٴىلتەمەلەر',
+
+# Random redirect
+'randomredirect' => 'كەزدەيسوق ايداتۋ',
+
+# Statistics
+'statistics' => 'جوبا ساناعى',
+'sitestats' => '{{SITENAME}} ساناعى',
+'userstats' => 'قاتىسۋشى ساناعى',
+'sitestatstext' => "مىنداعى دەرەكقوردا بۇلايشا '''$1''' بەت بار.
+بۇنىڭ ٴىشٴىندە «تالقىلاۋ» بەتتەرٴى, {{SITENAME}} جوباسى تۋرالى بەتتەر, كٴىشكەنە «بٴىتەمە»
+بەتتەر, ايداتۋلار, ماعلۇمات بەت دەپ سانالمايتىن, بٴالكٴىم, تاعى دا باسقالار.
+وسىنى ەسەپتەن شىعارعاندا, مىندا ماعلۇماتتى دەپ سانالاتىن
+'''$2''' بەت بار شىعار.
+
+توراپقا '''$8''' فايل قوتارىلعان.
+
+وسى ۋيكي جوباسى ورناتىلعاننان بەرٴى بۇلايشا بەتتەر '''$3''' رەت قارالعان,
+جٴانە بەتتەر '''$4''' رەت ٴوڭدەلگەن.
+بۇنىڭ نٴاتيجەسٴىندە ورتا ەسەپپەن بٴىر بەت سايىن '''$5''' ٴوڭدەۋ ٴىستەلٴىنگەن, جٴانە بٴىر ٴوڭدەۋ سايىن '''$6''' رەت قاراۋ كەلگەن.
+
+اعىمدىق [http://meta.wikimedia.org/wiki/Help:Job_queue تاپسىرىم كەزەگٴى] ۇزىندىلىعى: '''$7'''.",
+'userstatstext' => "مىندا '''$1''' تٴىركەلگەن قاتىسۋشى بار, سونىڭ ٴىشٴىندە
+'''$2''' (نەمەسە '''$4 %''') $5 بار.",
+'statistics-mostpopular' => 'ەڭ كٴوپ قارالعان بەتتەر',
+
+'disambiguations' => 'ايرىقتى بەتتەر',
+'disambiguationspage' => '{{ns:template}}:Disambig',
+'disambiguationstext' => 'كەلەسٴى بەتتەر <i>ايرىقتى بەتكە</i> سٴىلتەيدٴى. بۇنىڭ ورنىنا بەلگٴىلٴى تاقىرىپقا سٴىلتەۋٴى قاجەت.<br />بەتكە $1 سٴىلتەگەن جاعدايدا, بەت ايرىقتى دەپ سانالادى.<br />باسقا ەسٴىم اياسىنان نۇسقايتىن سٴىلتەمەلەر مىندا <i>تٴىزٴىمدەلمەيدٴى</i>.',
+
+'doubleredirects' => 'شىنجىرلى ايداتۋلار',
+'doubleredirectstext' => 'ٴاربٴىر جولداعى بٴىرٴىنشٴى مەن ەكٴىنشٴى ايداتۋ سٴىلتەمەلەرٴى بار, سونىمەن بٴىرگە ەكٴىنشٴى ايداتۋ مٴاتٴىننٴىڭ بٴىرٴىنشٴى جولى بار. ٴادەتتە بٴىرٴىنشٴى سٴىلتەمە ايدايتىن «شىن» اقىرعى بەتتٴىڭ اتاۋى بولۋى قاجەت.',
+
+'brokenredirects' => 'ەش بەتكە كەلتٴىرمەيتٴىن ايداتۋلار',
+'brokenredirectstext' => 'كەلەسٴى ايداتۋلار جوق بەتتەرگە سٴىلتەيدٴى:',
+
+# Miscellaneous special pages
+'nbytes' => '$1 بايت',
+'ncategories' => '$1 سانات',
+'nlinks' => '$1 سٴىلتەمە',
+'nmembers' => '$1 بۋىن',
+'nrevisions' => '$1 نۇسقا',
+'nviews' => '$1 رەت قارالعان',
+'lonelypages' => 'ەش بەت سٴىلتەمەگەن بەتتەر',
+'lonelypagestext' => 'كەلەسٴى بەتتەرگە وسى جوباداعى باسقا بەتتەر سٴىلتەمەيدٴى.',
+'uncategorizedpages' => 'ەش ساناتقا كٴىرمەگەن بەتتەر',
+'uncategorizedcategories' => 'ەش ساناتقا كٴىرمەگەن ساناتتار',
+'uncategorizedimages' => 'ەش ساناتقا كٴىرمەگەن سۋرەتتەر',
+'unusedcategories' => 'پايدالانىلماعان ساناتتار',
+'unusedimages' => 'پايدالانىلماعان فايلدار',
+'popularpages' => 'ٴايگٴىلٴى بەتتەر',
+'wantedcategories' => 'باستالماعان ساناتتار',
+'wantedpages' => 'باستالماعان بەتتەر',
+'mostlinked' => 'ەڭ كٴوپ سٴىلتەنگەن بەتتەر',
+'mostlinkedcategories' => 'ەڭ كٴوپ سٴىلتەنگەن ساناتتار',
+'mostcategories' => 'ەڭ كٴوپ ساناتتارعا كٴىرگەن بەتتەر',
+'mostimages' => 'ەڭ كٴوپ سٴىلتەنگەن سۋرەتتەر',
+'mostrevisions' => 'ەڭ كٴوپ تٴۇزەتٴىلگەن بەتتەر',
+'allpages' => 'بارلىق بەت تٴىزٴىمٴى',
+'prefixindex' => 'بەت باستاۋ تٴىزٴىمٴى',
+'randompage' => 'كەزدەيسوق بەت',
+'shortpages' => 'ەڭ قىسقا بەتتەر',
+'longpages' => 'ەڭ ٴۇلكەن بەتتەر',
+'deadendpages' => 'ەش بەتكە سٴىلتەمەيتٴىن بەتتەر',
+'deadendpagestext' => 'كەلەسٴى بەتتەر وسى جوباداعى باسقا بەتتەرگە سٴىلتەمەيدٴى.',
+'listusers' => 'بارلىق قاتىسۋشى تٴىزٴىمٴى',
+'specialpages' => 'ارنايى بەتتەر',
+'spheading' => 'بارشانىڭ ارنايى بەتتەرٴى',
+'restrictedpheading' => 'شەكتەۋلٴى ارنايى بەتتەر',
+'recentchangeslinked' => 'قاتىستى تٴۇزەتۋلەر',
+'rclsub' => '(«$1» بەتٴىنەن سٴىلتەنگەن بەتتەرگە)',
+'newpages' => 'ەڭ جاڭا بەتتەر',
+'newpages-username' => 'قاتىسۋشى اتى:',
+'ancientpages' => 'ەڭ ەسكٴى بەتتەر',
+'intl' => 'تٴىلارالىق سٴىلتەمەلەر',
+'move' => 'جىلجىتۋ',
+'movethispage' => 'بەتتٴى جىلجىتۋ',
+'unusedimagestext' => '<p>ەسكەرتۋ: باسقا ۆەب توراپتار فايلدىڭ
+URL جايىنا تٴىكەلەي سٴىلتەۋٴى مٴۇمكٴىن. سوندىقتان, بەلسەندٴى پايدالانۋىنا اڭعارماي,
+وسى تٴىزٴىمدە قالۋى مٴۇمكٴىن.</p>',
+'unusedcategoriestext' => 'كەلەسٴى سانات بەتتەر بار بولىپ تۇر, بٴىراق وعان ەشقانداي بەت, نە سانات كٴىرمەيدٴى.',
+'booksources' => 'كٴىتاپ قاينارلارى',
+'categoriespagetext' => 'وسىندا ۋيكيدەگٴى بارلىق ساناتتارىنىڭ تٴىزٴىمٴى بەرٴىلٴىپ تۇر.',
+'data' => 'دەرەكتەر',
+'userrights' => 'قاتىسۋشىلار قۇقىقتارىن مەڭگەرۋ',
+'groups' => 'قاتىسۋشى توپتارى',
+'booksourcetext' => 'تٴومەندە جاڭا جٴانە قولدانعان كٴىتاپتار ساتاتىن
+توراپتارىنىڭ سٴىلتەمەلەرٴى تٴىزٴىمدەلگەن. بۇل توراپتاردا ٴىزدەلگەن كٴىتاپتار
+تۋرالى بىلايعى اقپارات بولۋعا مٴۇمكٴىن.',
+'isbn' => 'ISBN بەلگٴىسٴى',
+'alphaindexline' => '$1 — $2',
+'version' => 'جٴۇيە نۇسقاسى',
+'log' => 'جۋرنالدار',
+'alllogstext' => 'بٴىرٴىككەن قوتارۋ, جويۋ, قورعاۋ, بۇعاتتاۋ جٴانە ٴاكٴىمشٴىلٴىك جۋرنالدارىن كٴورسەتۋ.
+جۋرنال تٴۇرٴىن, قاتىسۋشى اتىن, تيٴىستٴى بەتٴىن تالعاپ, تارىلتىپ قاراۋىڭىزعا بولادى.',
+'logempty' => 'جۋرنالدا سٴايكەس دانالار جوق.',
+
+# Special:Allpages
+'nextpage' => 'كەلەسٴى بەتكە ($1)',
+'allpagesfrom' => 'مىنا بەتتەن باستاپ كٴورسەتۋ:',
+'allarticles' => 'بارلىق بەت تٴىزٴىمٴى',
+'allinnamespace' => 'بارلىق بەت ($1 ەسٴىم اياسى)',
+'allnotinnamespace' => 'بارلىق بەت ($1 ەسٴىم اياسىنان تىس)',
+'allpagesprev' => 'الدىڭعىعا',
+'allpagesnext' => 'كەلەسٴىگە',
+'allpagessubmit' => 'ٴوتۋ',
+'allpagesprefix' => 'مىنادان باستالعان بەتتەردٴى كٴورسەتۋ:',
+'allpagesbadtitle' => 'الىنعان بەت اتاۋى جارامسىز بولعان, نەمەسە تٴىل-ارالىق نە ۋيكي-ارالىق باستاۋى بار بولدى. اتاۋدا قولدانۋعا بولمايتىن نىشاندار بولۋى مٴۇمكٴىن.',
+
+# Special:Listusers
+'listusersfrom' => 'مىنا قاتىسۋشىدان باستاپ كٴورسەتۋ:',
+
+# E-mail user
+'mailnologin' => 'ە-پوشتا جايى جٴىبەرٴىلگەن جوق',
+'mailnologintext' => 'باسقا قاتىسۋشىعا حات جٴىبەرۋ ٴۇشٴىن
+[[{{ns:special}}:Userlogin|كٴىرۋٴىڭٴىز]] قاجەت, جٴانە [[{{ns:special}}:Preferences|باپتاۋىڭىزدا]]
+كۋٴالاندىرىلعان ە-پوشتا جايى بولۋى جٴون.',
+'emailuser' => 'قاتىسۋشىعا حات جازۋ',
+'emailpage' => 'قاتىسۋشىعا حات جٴىبەرۋ',
+'emailpagetext' => 'ەگەر بۇل قاتىسۋشى باپتاۋلارىندا كۋٴالاندىرعان ە-پوشتا
+جايىن ەنگٴىزسە, تٴومەندەگٴى ٴۇلگٴىت ارقىلى بۇعان جالعىز ە-پوشتا حاتىن جٴىبەرۋگە بولادى.
+قاتىسۋشى باپتاۋىڭىزدا ەنگٴىزگەن ە-پوشتا جايىڭىز
+«كٴىمنەن» دەگەن باس جولاعىندا كٴورٴىنەدٴى, سوندىقتان
+حات الۋشىسى تۋرا جاۋاپ بەرە الادى.',
+'usermailererror' => 'Mail نىسانى قاتە قايتاردى:',
+'defemailsubject' => '{{SITENAME}} ە-پوشتاسىنىڭ حاتى',
+'noemailtitle' => 'بۇل ە-پوشتا جايى ەمەس',
+'noemailtext' => 'وسى قاتىسۋشى جارامدى ە-پوشتا جايىن ەنگٴىزبەگەن,
+نەمەسە باسقالاردان حات قابىلداۋىن ٴوشٴىرگەن.',
+'emailfrom' => 'كٴىمنەن',
+'emailto' => 'كٴىمگە',
+'emailsubject' => 'تاقىرىبى',
+'emailmessage' => 'حات',
+'emailsend' => 'جٴىبەرۋ',
+'emailccme' => 'حاتىمدىڭ كٴوشٴىرمەسٴىن ماعان دا جٴىبەر.',
+'emailccsubject' => '$1 دەگەنگە جٴىبەرٴىلگەن حاتىڭىزدىڭ كٴوشٴىرمەسٴى: $2',
+'emailsent' => 'حات جٴىبەرٴىلدٴى',
+'emailsenttext' => 'ە-پوشتا حاتىڭىز جٴىبەرٴىلدٴى.',
+
+# Watchlist
+'watchlist' => 'باقىلاۋىم',
+'watchlistfor' => "('''$1''' باقىلاۋلارى)",
+'nowatchlist' => 'باقىلاۋ تٴىزٴىمٴىڭٴىزدە ەشبٴىر دانا جوق',
+'watchlistanontext' => 'باقىلاۋ تٴىزٴىمٴىڭٴىزدەگٴى دانالاردى قاراۋ, نە ٴوڭدەۋ ٴۇشٴىن $1 قاجەت.',
+'watchlistcount' => "'''باقىلاۋ تٴىزٴىمٴىڭٴىزدە (تالقىلاۋ بەتتەردٴى قوسا) $1 دانا بار.'''",
+'clearwatchlist' => 'باقىلاۋ تٴىزٴىمٴىن تازالاۋ',
+'watchlistcleartext' => 'سولاردى تولىق الاستاتۋعا باتىلسىز با?',
+'watchlistclearbutton' => 'باقىلاۋ تٴىزٴىمٴىن تازالاۋ',
+'watchlistcleardone' => 'باقىلاۋ تٴىزٴىمٴىڭٴىز تازارتىلدى. $1 دانا الاستاتىلدى.',
+'watchnologin' => 'كٴىرمەگەنسٴىز',
+'watchnologintext' => 'باقىلاۋ تٴىزٴىمٴىڭٴىزدٴى ٴوزگەرتۋ ٴۇشٴىن [[{{ns:special}}:Userlogin|كٴىرۋٴىڭٴىز]] جٴون.',
+'addedwatch' => 'باقىلاۋ تٴىزٴىمٴىنە قوسىلدى',
+'addedwatchtext' => "«[[:$1]]» بەتٴى [[{{ns:special}}:Watchlist|باقىلاۋ تٴىزٴىمٴىڭٴىزگە]] قوسىلدى.
+وسى بەتتٴىڭ جٴانە سونىڭ تالقىلاۋ بەتٴىنٴىڭ كەلەشەكتەگٴى ٴوزگەرٴىستەرٴى مىندا تٴىزٴىمدەلەدٴى.
+سوندا بەتتٴىڭ اتاۋى تابۋعا جەڭٴىلدەتٴىپ [[{{ns:special}}:Recentchanges|جۋىقتاعى ٴوزگەرٴىستەر تٴىزٴىمٴىندە]]
+'''جۋان ٴارپٴىمەن''' كٴورسەتٴىلەدٴى.
+
+وسى بەتتٴى سوڭىنان باقىلاۋ تٴىزٴىمنەن الاستاتىڭىز كەلسە «باقىلاماۋ» پاراعىن نۇقىڭىز.",
+'removedwatch' => 'باقىلاۋ تٴىزٴىمٴىڭٴىزدەن الاستاتىلدى',
+'removedwatchtext' => '«[[:$1]]» بەتٴى باقىلاۋ تٴىزٴىمٴىڭٴىزدەن الاستاتىلدى.',
+'watch' => 'باقىلاۋ',
+'watchthispage' => 'بەتتٴى باقىلاۋ',
+'unwatch' => 'باقىلاماۋ',
+'unwatchthispage' => 'باقىلاۋدى توقتاتۋ',
+'notanarticle' => 'ماعلۇمات بەتٴى ەمەس',
+'watchnochange' => 'كٴورسەتٴىلگەن مەرزٴىمدە ەشبٴىر باقىلانعان دانا ٴوڭدەلگەن جوق.',
+'watchdetails' => "* باقىلاۋ تٴىزٴىمٴىندە (تالقىلاۋ بەتتەرٴىسٴىز) '''$1''' بەت بار.
+* [[{{ns:special}}:Watchlist/edit|بٴۇكٴىل تٴىزٴىمدٴى قاراۋ جٴانە ٴوزگەرتۋ]].
+* [[{{ns:special}}:Watchlist/clear|تٴىزٴىمدەگٴى بارلىق دانا الاستاتۋ]].",
+'wlheader-enotif' => '* ەسكەرتۋ حات جٴىبەرۋٴى ەندٴىرٴىلگەن.',
+'wlheader-showupdated' => "* سوڭعى كٴىرگەنٴىمنەن بەرٴى تٴۇزەتٴىلگەن بەتتەردٴى '''جۋان''' مٴاتٴىنمەن كٴورسەت",
+'watchmethod-recent' => 'باقىلاۋلى بەتتەردٴىڭ جۋىقتاعى ٴوزگەرٴىستەرٴىن تەكسەرۋ',
+'watchmethod-list' => 'جۋىقتاعى ٴوزگەرٴىستەردە باقىلاۋلى بەتتەردٴى تەكسەرۋ',
+'removechecked' => 'بەلگٴىلەنگەندٴى باقىلاۋ تٴىزٴىمٴىنەن الاستاتۋ',
+'watchlistcontains' => 'باقىلاۋ تٴىزٴىمٴىڭٴىزدە $1 بەت بار.',
+'watcheditlist' => "وسىندا ٴالٴىپپەم سۇرىپتالعان باقىلانعان ماعلۇمات بەتتەرٴىڭٴىز تٴىزٴىمدەلٴىنگەن.
+بەتتەردٴى الاستاتۋ ٴۇشٴىن ونىڭ قاسىنداعى قاباشاقتاردى بەلگٴىلەپ, تٴومەندەگٴى ''بەلگٴىلەنگەندٴى الاستات'' تٴۇيمەسٴىن نۇقىڭىز
+(ماعلۇمات بەتٴىن جويعاندا تالقىلاۋ بەتٴى دە بٴىرگە جويىلادى).",
+'removingchecked' => 'سۇرانعان دانالاردى باقىلاۋ تٴىزٴىمنەن الاستاۋى…',
+'couldntremove' => '«$1» دەگەن دانا الاستاتىلمادى…',
+'iteminvalidname' => '«$1» داناسىنىڭ جارامسىز اتاۋىنان شاتاق تۋدى…',
+'wlnote' => 'تٴومەندە سوڭعى <b>$2</b> ساعاتتاعى, سوڭعى $1 ٴوزگەرٴىس كٴورسەتٴىلگەن.',
+'wlshowlast' => 'سوڭعى $1 ساعاتتاعى, $2 كٴۇندەگٴى, $3 بولعان ٴوزگەرٴىستٴى كٴورسەتۋ',
+'wlsaved' => 'بۇل باقىلۋ تٴىزٴىمٴىڭٴىزدٴىڭ ساقتالعان نۇسقاسى.',
+'wlhideshowown' => 'تٴۇزەتۋٴىمدٴى $1',
+'wlhideshowbots' => 'بوتتاردى $1',
+'wldone' => 'ٴىس بٴىتتٴى.',
+
+'enotif_mailer' => '{{SITENAME}} ەسكەرتۋ حات جٴىبەرۋ قىزمەتٴى',
+'enotif_reset' => 'بارلىق بەت كارالدٴى دەپ بەلگٴىلە',
+'enotif_newpagetext' => 'مىناۋ جاڭا بەت.',
+'changed' => 'ٴوزگەرتتٴى',
+'created' => 'جاسادى',
+'enotif_subject' => '{{SITENAME}} جوباسىندا $PAGEEDITOR $PAGETITLE اتاۋلى بەتتٴى $CHANGEDORCREATED',
+'enotif_lastvisited' => 'سوڭعى كٴىرۋٴىڭٴىزدەن بەرٴى بولعان ٴوزگەرٴىستەر ٴۇشٴىن $1 دەگەندٴى قاراڭىز.',
+'enotif_body' => 'قۇرمەتتٴى $WATCHINGUSERNAME,
+
+{{SITENAME}} جوباسىدا $PAGEEDITDATE كەزٴىندە $PAGEEDITOR $PAGETITLE اتاۋلى بەتتٴى $CHANGEDORCREATED, اعىمدىق نۇسقاسىن $PAGETITLE_URL جايىنان قاراڭىز.
+
+$NEWPAGE
+
+ٴوڭدەۋشٴى سيپاتتاماسى: $PAGESUMMARY $PAGEMINOREDIT
+
+ٴوڭدەۋشٴىمەن قاتىناسۋ:
+ە-پوشتا: $PAGEEDITOR_EMAIL
+ۋيكي: $PAGEEDITOR_WIKI
+
+بىلايعى ٴوزگەرٴىستەر بولعاندا دا سٴىز وسى بەتكە بارعانشا دەيٴىن ەشقانداي باسقا ەسكەرتۋ حاتتار جٴىبەرٴىلمەيدٴى. سونىمەن قاتار باقىلاۋ تٴىزٴىمٴىڭٴىزدەگٴى بەت ەسكەرتپەلٴىك بەلگٴىسٴىن ٴادەپكە كٴۇيٴىنە كەلتٴىرٴىڭٴىز.
+
+ سٴىزدٴىڭ دوستى {{SITENAME}} ەسكەرتۋ قىزمەتٴى
+
+----
+باقىلاۋ تٴىزٴىمٴىڭٴىزدٴى باپتاۋ ٴۇشٴىن, مىندا بارىڭىز
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+سىن-پٴىكٴىر بەرۋ جٴانە بىلايعى جٴاردەم الۋ ٴۇشٴىن:
+{{fullurl:{{ns:help}}:مازمۇنى}}',
+
+# Delete/protect/revert
+'deletepage' => 'بەتتٴى جويۋ',
+'confirm' => 'راستاۋ',
+'excontent' => 'بولعان ماعلۇماتى: «$1»',
+'excontentauthor' => 'بولعان ماعلۇماتى: «$1» (تەك «[[Special:Contributions/$2|$2]]» ٴۇلەسٴى)',
+'exbeforeblank' => 'تازارتۋ الدىنداعى بولعان ماعلۇماتى: «$1»',
+'exblank' => 'بەت بوستى بولدى',
+'confirmdelete' => 'جويۋدى راستاۋ',
+'deletesub' => '(«$1» جويۋى)',
+'historywarning' => 'نازار سالىڭىز: جويۋعا ارنالعان بەتتە ٴوز تاريحى بار:',
+'confirmdeletetext' => 'بەتتٴى نەمەسە سۋرەتتٴى بارلىق تاريحىمەن
+بٴىرگە دەرەكقوردان ٴاردايىم جويىعىڭىز كەلەتٴىن سيياقتى.
+بۇنى جويۋدىڭ زاردابىن تٴۇسٴىنٴىپ شىن نيەتتەنگەنٴىڭٴىزدٴى, جٴانە
+[[{{ns:project}}:ساياسات]]قا لايىقتى دەپ
+سەنگەنٴىڭٴىزدٴى راستاڭىز.',
+'actioncomplete' => 'ٴارەكەت بٴىتتٴى',
+'deletedtext' => '«$1» جويىلدى.
+جۋىقتاعى جويۋلار تۋرالى جازبالارىن $2 دەگەننەن قاراڭىز.',
+'deletedarticle' => '«[[$1]]» بەتٴىن جويدى',
+'dellogpage' => 'جويۋ_جۋرنالى',
+'dellogpagetext' => 'تٴومەندە جۋىقتاعى جويۋلاردىڭ تٴىزٴىمٴى بەرٴىلگەن.',
+'deletionlog' => 'جويۋ جۋرنالى',
+'reverted' => 'ەرتەرەك نۇسقاسىنا قايتارىلعان',
+'deletecomment' => 'جويۋدىڭ سەبەبٴى',
+'imagereverted' => 'ەرتەرەك نۇسقاسىنا قايتارۋ سٴاتتٴى ٴوتتٴى.',
+'rollback' => 'تٴۇزەتۋلەردٴى قايتارۋ',
+'rollback_short' => 'قايتارۋ',
+'rollbacklink' => 'قايتارۋ',
+'rollbackfailed' => 'قايتارۋ سٴاتسٴىز اياقتالدى',
+'cantrollback' => 'تٴۇزەتۋ قايتارىلمايدى. بۇل بەتتٴىڭ سوڭعى ٴۇلەسكەرٴى تەك باستاۋىش اۋتورى.',
+'alreadyrolled' => '[[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|تالقىلاۋى]]) دەگەندٴى جاساعان [[:$1]]
+بەتٴىنٴىڭ سوڭعى ٴوڭدەۋٴىنەن قايتارۋ ٴوتپەدٴى; كەيبٴىرەۋ وسى قازٴىر بەتتٴى ٴوڭدەپ نە قايتارىپ جاتىر تٴۇگە.
+
+سوڭعى ٴوڭدەۋدٴى [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|تالقىلاۋى]]) دەگەندٴى جاساعان.',
+'editcomment' => 'تٴۇزەتۋدٴىڭ بولعان مٴاندەمەسٴى: "<i>$1</i>".', # only shown if there is an edit comment
+'revertpage' => '[[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|تالقىلاۋى]]) تٴۇزەتۋٴىنەن [[{{ns:user}}:$1|$1]] سوڭعى نۇسقاسىنا قايتاردى',
+'sessionfailure' => 'كٴىرۋ سەسسيياسىندا شاتاق بولعان سيياقتى;
+سەسسيياعا شابۋىلداۋداردان قورعانۋ ٴۇشٴىن, وسى ٴارەكەت توقتاتىلدى.
+«ارتقا» تٴۇيمەسٴىن باسىڭىز, جٴانە بەتتٴى كەرٴى جٴۇكتەڭٴىز, سوسىن قايتالاپ كٴورٴىڭٴىز.',
+'protectlogpage' => 'قورعاۋ_جۋرنالى',
+'protectlogtext' => 'تٴومەندە بەتتەردٴىڭ قورعاۋ/قورعاماۋ تٴىزٴىمٴى بەرٴىلگەن.',
+'protectedarticle' => '«$1» قورعالدى',
+'unprotectedarticle' => '«[[$1]]» قورعالمادى',
+'protectsub' => '(«$1» قورعاۋدا)',
+'confirmprotecttext' => 'وسى بەتتٴى راسىندا دا قورعاۋ قاجەت پە?',
+'confirmprotect' => 'قورعاۋدى راستاۋ',
+'protectmoveonly' => 'تەك جىلجىتۋدان قورعاۋ',
+'protectcomment' => 'قورعاۋ سەبەبٴى',
+'unprotectsub' => '(«$1» قورعاماۋدا)',
+'confirmunprotecttext' => 'وسى بەتتٴى راستان قورعاماۋ قاجەت پە?',
+'confirmunprotect' => 'قورعاماۋدى راستاۋ',
+'unprotectcomment' => 'قورعاماۋ سەبەبٴى',
+'protect-unchain' => 'جىلجىتۋعا رۇقسات بەرۋ',
+'protect-text' => '<strong>$1</strong> بەتٴىنٴىڭ قورعاۋ دەڭگەيٴىن قاراي جٴانە ٴوزگەرتە الاسىز.',
+'protect-viewtext' => 'تٴىركەلگٴىڭٴىز بەت قورعانىسى دەنگەيلەرٴىن ٴوزگەرتۋگە رۇقسات بەرمەيدٴى.
+مىنا <strong>$1</strong> بەتتٴىڭ اعىمدىق باپتاۋلارى:',
+'protect-default' => '(ٴادەپكٴى)',
+'protect-level-autoconfirmed' => 'تٴىركەلگٴىسٴىز پايدالانۋشىلارعا تيىم',
+'protect-level-sysop' => 'تەك ٴاكٴىمشٴىلەرگە رۇقسات',
+
+# Restrictions (nouns)
+'restriction-edit' => 'ٴوڭدەۋ',
+'restriction-move' => 'جىلجىتۋ',
+
+# Undelete
+'undelete' => 'جويىلعان بەتتەردٴى قاراۋ',
+'undeletepage' => 'جويىلعان بەتتەردٴى قاراۋ جٴانە قايتارۋ',
+'viewdeletedpage' => 'جويىلعان بەتتەردٴى قاراۋ',
+'undeletepagetext' => 'كەلەسٴى بەتتەر جويىلدى دەپ بەلگٴىلەنگەن, بٴىراق ماعلۇماتى مۇراعاتتا جاتقان,
+سوندىقتان كەرٴى قايتارۋعا ٴازٴىر. مۇراعات مەرزٴىم بويىنشا تازالانىپ تۇرۋى مٴۇمكٴىن.',
+'undeleteextrahelp' => "بٴۇكٴىل بەتتٴى قايتارۋ ٴۇشٴىن, بارلىق قاباشاقتاردى بوس قالدىرىپ
+'''''قايتار!''''' تٴۇيمەسٴىن نۇقىڭىز. بٴولەكشە قايتارۋ ورىنداۋ ٴۇشٴىن, قايتارايىن دەگەن نۇسقالارىنا سٴايكەس
+قاباشاقتارىن بەلگٴىلەڭٴىز دە, جٴانە '''''قايتار!''''' تٴۇيمەسٴىن نۇقىڭىز. '''''تاستا''''' تٴۇيمەسٴىن
+نۇقىعاندا مٴاندەمە اۋماعى مەن بارلىق قاباشاقتار تازالانادى.",
+'undeletearticle' => 'جويىلعان بەتتٴى قايتارۋ',
+'undeleterevisions' => '$1 نۇسقا مۇراعاتتالعان',
+'undeletehistory' => 'ەگەر بەت ماعلۇماتىن قايتارساڭىز,تاريحىندا بارلىق نۇسقالار دا
+قايتارىلادى. ەگەر جويۋدان سوڭ دٴال سولاي اتاۋىمەن جاڭا بەت جاسالسا, قايتارىلعان نۇسقالار
+تاريحتىڭ ەڭ ادىندا كٴورسەتٴىلەدٴى, جٴانە كٴورسەتٴىلٴىپ تۇرعان بەتتٴىڭ اعىمدىق نۇسقاسى
+ٴوزدٴىك تٴۇردە الماستىرىلمايدى.',
+'undeletehistorynoadmin' => 'بۇل بەت جويىلعان. جويۋ سەبەبٴى الدىنداعى ٴوڭدەگەن قاتىسۋشىلار
+ەگجەي-تەگجەيلەرٴىمەن بٴىرگە تٴومەندەگٴى سيپاتتاماسىندا كٴورسەتٴىلگەن.
+وسى جويىلعان نۇسقالاردىڭ مٴاتٴىنٴى تەك ٴاكٴىمشٴىلەرگە قاتىناۋلى.',
+'undeleterevision' => '$1 كەزٴىندەگٴى جويىلعان نۇسقاسىن',
+'undeleterevision-missing' => 'جارامسىز نە جوعالعان نۇسقا. سٴىلتەمەڭٴىز جارامسىز بولۋى مٴۇمكٴىن, نە
+نۇسقا قايتارىلعان تٴۇگە نەمەسە مۇراعاتتان الاستاتىلعان.',
+'undeletebtn' => 'قايتار!',
+'undeletereset' => 'تاستا',
+'undeletecomment' => 'مٴاندەمەسٴى:',
+'undeletedarticle' => '«[[$1]]» قايتاردى',
+'undeletedrevisions' => '$1 نۇسقاسى قايتارىلعان',
+'undeletedrevisions-files' => '$1 نۇسقا جٴانە $2 فايل قايتارىلدى',
+'undeletedfiles' => '$1 فايل قايتارىلدى',
+'cannotundelete' => 'قايتارۋ سٴاتسٴىز بٴىتتٴى; تاعى بٴىرەۋ سٴىزدەن بۇرىن سول بەتتٴى قايتارعان بولار.',
+'undeletedpage' => "<big>'''$1 قايتارىلدى'''</big>
+
+جۋىقتاعى جويۋ مەن قايتارۋ جٴونٴىندە [[{{ns:special}}:Log/delete|جويۋ جۋرنالىن]] قاراڭىز.",
+
+# Namespace form on various pages
+'namespace' => 'ەسٴىم اياسى:',
+'invert' => 'تالعاۋدى كەرٴىلەۋ',
+
+# Contributions
+'contributions' => 'قاتىسۋشى ٴۇلەسٴى',
+'mycontris' => 'ٴۇلەسٴىم',
+'contribsub' => '$1 ٴۇلەسٴى',
+'nocontribs' => 'وسى ٴىزدەۋ شارتىنا سٴايكەس ٴوزگەرٴىستەر تابىلعان جوق.',
+'ucnote' => 'تٴومەندە وسى قاتىسۋشىنىڭ سوڭعى <b>$2</b> كٴۇندەگٴى, سوڭعى <b>$1</b> ٴوزگەرٴىسٴى كٴورسەتلەدٴى.',
+'uclinks' => 'سوڭعى $2 كٴۇندەگٴى, سوڭعى $1 ٴوزگەرٴىسٴىن قاراۋ.',
+'uctop' => ' (ٴۇستٴى)',
+'newbies' => 'جاڭا قاتىسۋشىلار',
+
+'sp-newimages-showfrom' => '$1 كەزٴىنەن بەرٴى — جاڭا سۋرەتتەردٴى كٴورسەت',
+
+'sp-contributions-newest' => 'ەڭ جاڭاسىنا',
+'sp-contributions-oldest' => 'ەڭ ەسكٴىسٴىنە',
+'sp-contributions-newer' => 'جاڭالاۋ $1',
+'sp-contributions-older' => 'ەسكٴىلەۋ $1',
+'sp-contributions-newbies-sub' => 'جاڭا قاتىسۋشىلارعا',
+
+# What links here
+'whatlinkshere' => 'سٴىلتەگەن بەتتەر',
+'notargettitle' => 'اقىرعى اتاۋ جوق',
+'notargettext' => 'وسى ٴارەكەت ورىندالاتىن نىسانا بەت,
+نە قاتىسۋشى كٴورسەتٴىلمەگەن.',
+'linklistsub' => '(سٴىلتەمەلەر تٴىزٴىمٴى)',
+'linkshere' => "'''[[:$1]]''' دەگەنگە مىنا بەتتەر سٴىلتەيدٴى:",
+'nolinkshere' => "'''[[:$1]]''' دەگەنگە ەش بەت سٴىلتەمەيدٴى.",
+'isredirect' => 'ايداتۋ بەتٴى',
+'istemplate' => 'كٴىرٴىكتٴىرۋ',
+
+# Block/unblock
+'blockip' => 'پايدالانۋشىنى بۇعاتتاۋ',
+'blockiptext' => 'تٴومەندەگٴى ٴۇلگٴىت پايدالانۋشىنىڭ جازۋ رۇقساتىن
+بەلگٴىلٴى IP جايىمەن نە اتاۋىمەن بۇعاتتاۋ ٴۇشٴىن قولدانىلادى.
+بۇنى تەك بۇزاقىلىققا كەدەرگٴى ٴىستەۋ ٴۇشٴىن جٴانە دە
+[[{{ns:project}}:ساياسات|ساياسات]] بويىنشا اتقارۋىڭىز جٴون.
+تٴومەندە تيٴىستٴى سەبەبٴىن تولتىرىپ كٴورسەتٴىڭٴىز (مىسالى, دٴايەككە بۇزاقىلىقپەن
+ٴوزگەرتكەن بەتتەردٴى كەلتٴىرٴىپ).',
+'ipaddress' => 'IP جاي',
+'ipadressorusername' => 'IP جاي نە قاتىسۋشى اتى',
+'ipbexpiry' => 'بٴىتەتٴىن مەرزٴىمٴى',
+'ipbreason' => 'سەبەبٴى',
+'ipbanononly' => 'تەك تٴىركەلگٴىسٴىزدٴى بۇعاتتاۋ',
+'ipbcreateaccount' => 'تٴىركەلگٴى جاساۋىن كەدەرگٴىلەۋ',
+'ipbenableautoblock' => 'بۇل قاتىسۋشىنىڭ قولدانعان سوڭعى IP جايىن, جٴانە ٴارقايسى كەيٴىن تٴۇزەتۋ ٴىستەۋگە ٴۇمٴىتەلٴىگەن جايلارىن ٴوزدٴىك تٴۇردە بۇعاتتاۋ',
+'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',
+'ipbotheroption' => 'باسقا',
+'badipaddress' => 'جارامسىز IP جاي',
+'blockipsuccesssub' => 'بۇعاتتاۋ سٴاتتٴى ٴوتتٴى',
+'blockipsuccesstext' => '[[{{ns:special}}:Contributions/$1|$1]] دەگەن بۇعاتتالعان.
+<br />بۇعاتتاۋلاردى [[{{ns:special}}:Ipblocklist|IP بۇعاتتاۋ تٴىزٴىمٴىندە]] قاراپ شىعىڭىز.',
+'unblockip' => 'پايدالانۋشىنى بۇعاتتاماۋ',
+'unblockiptext' => 'تٴومەندەگٴى ٴۇلگٴىت بەلگٴىلٴى IP جايىمەن نە اتاۋىمەن
+بۇرىن بۇعاتتالعان پايدالانۋشىنىڭ جازۋ رۇقساتىن قايتارۋ ٴۇشٴىن قولدانىلادى.',
+'ipusubmit' => 'وسى جايدى بۇعاتتاماۋ',
+'unblocked' => '[[{{ns:user}}:$1|$1]] بۇعاتتاۋى ٴوشٴىرٴىلدٴى',
+'ipblocklist' => 'بۇعاتتالعان پايدالانۋشى / IP- جاي تٴىزٴىمٴى',
+'blocklistline' => '$1, $2 «$3» دەگەندٴى بۇعاتتادى ($4)',
+'infiniteblock' => 'مٴانگٴى',
+'expiringblock' => 'بٴىتۋٴى: $1',
+'anononlyblock' => 'تەك تٴىركەلگٴىسٴىزدٴى',
+'noautoblockblock' => 'ٴوزدٴىك بۇعاتتاۋ ٴوشٴىرٴىلەنگەن',
+'createaccountblock' => 'تٴىركەلگٴى جاساۋى بۇعاتتالعان',
+'ipblocklistempty' => 'بۇعاتتاۋ تٴىزٴىمٴى بوس.',
+'blocklink' => 'بۇعاتتاۋ',
+'unblocklink' => 'بۇعاتتاماۋ',
+'contribslink' => 'ٴۇلەسٴى',
+'autoblocker' => "IP جايىڭىزدى جۋىقتا «[[{{ns:user}}:1|$1]]» پايدالانعان, سوندىقتان ٴوزدٴىك تٴۇردە بۇعاتتالعان. $1 بۇعاتتاۋ سەبەبٴى: «'''$2'''».",
+'blocklogpage' => 'بۇعاتتاۋ_جۋرنالى',
+'blocklogentry' => '«[[$1]]» بۇعاتتادى, بٴىتەتٴىن مەرزٴىمٴى: $2',
+'blocklogtext' => 'بۇل پايدالانۋشىلاردى بۇعاتتاۋ/بۇعاتتاماۋ ٴارەكەتتەرٴىنٴىڭ جۋرنالى. ٴوزدٴىك تٴۇردە
+بۇعاتتالعان IP جايلار وسىندا تٴىزٴىمدەلگەمەگەن. اعىمداعى بەلسەندٴى بۇعاتتاۋلارىن
+[[{{ns:special}}:Ipblocklist|IP بۇعاتتاۋ تٴىزٴىمٴىنەن]] قاراۋعا بولادى.',
+'unblocklogentry' => '«$1» بۇعاتتاۋىن ٴوشٴىردٴى',
+'range_block_disabled' => 'اۋقىم بۇعاتتاۋىن جاساۋ ٴاكٴىمشٴىلٴىك مٴۇمكٴىندٴىگٴى ٴوشٴىرٴىلگەن.',
+'ipb_expiry_invalid' => 'بٴىتەتٴىن ۋاقىتى جارامسىز.',
+'ipb_already_blocked' => '«$1» بۇعاتتالعان تٴۇگە',
+'ip_range_invalid' => 'IP جاي اۋقىمى جارامسىز.',
+'proxyblocker' => 'پروكسي سەرۆەرلەردٴى بۇعاتتاۋىش',
+'ipb_cant_unblock' => 'قاتە: IP $1 بۇعاتتاۋى تابىلمادى. ونىڭ بۇعاتتاۋى ٴوشٴىرلگەن سيياقتى.',
+'proxyblockreason' => 'IP جايىڭىز اشىق پروكسي سەرۆەرگە جاتاتىندىقتان بۇعاتتالعان. ينتەرنەت قىزمەتٴىن جابدىقتاۋشىڭىزبەن, نە تەحنيكالىق مەدەۋ قىزمەتٴىمەن قاتىناسىڭىز, جٴانە ولارعا وسى وتە كٴۇردەلٴى قاۋىپسٴىزدٴىك شاتاق تۋرالى اقپارات بەرٴىڭٴىز.',
+'proxyblocksuccess' => 'بٴىتتٴى.',
+'sorbs' => 'DNSBL قارا تٴىزٴىمٴى',
+'sorbsreason' => 'سٴىزدٴىڭ IP جايىڭىز وسى توراپتا قولدانىلعان DNSBL قارا تٴىزٴىمٴىندەگٴى اشىق پروكسي-سەرۆەر دەپ تابىلادى.',
+'sorbs_create_account_reason' => 'سٴىزدٴىڭ IP جايىڭىز وسى توراپتا قولدانىلعان DNSBL قارا تٴىزٴىمٴىندەگٴى اشىق پروكسي-سەرۆەر دەپ تابىلادى. تٴىركەلگٴى جاساي المايسىز.',
+
+# Developer tools
+'lockdb' => 'دەرەكقوردى قۇلىپتاۋ',
+'unlockdb' => 'دەرەكقوردى قۇلىپتاماۋ',
+'lockdbtext' => 'دەرەكقوردىن قۇلىپتالۋى بارلىق پايدالانۋشىنىڭ
+بەت ٴوڭدەۋ, باپتاۋىن قالاۋ, باقىلاۋ تٴىزٴىمٴىن, تاعى باسقا
+دەرەكقوردى ٴوزگەرتەتٴىن مٴۇمكٴىندٴىكتەرٴىن توقتاتا تۇرادى.
+وسى ماقساتىڭىزدى, جٴانە جٴوندەۋٴىڭٴىز بٴىتكەندە
+دەرەكقوردى اشاتىڭىزدى راستاڭىز.',
+'unlockdbtext' => 'دەرەكقودىن اشىلۋى بارلىق پايدالانۋشىنىڭ بەت ٴوڭدەۋ,
+باپتاۋىن قالاۋ, باقىلاۋ تٴىزٴىمٴىن, تاعى باسقا دەرەكقوردى ٴوزگەرتەتٴىن
+مٴۇمكٴىندٴىكتەرٴىن قايتا اشادى.
+وسى ماقساتىڭىزدى راستاڭىز.',
+'lockconfirm' => 'يٴا, مەن دەرەكقوردى راستان قۇلىپتايمىن.',
+'unlockconfirm' => 'يٴا, مەن دەرەكقوردى راستان قۇلىپتامايمىن.',
+'lockbtn' => 'دەرەكقوردى قۇلىپتا',
+'unlockbtn' => 'دەرەكقوردى قۇلىپتاما',
+'locknoconfirm' => 'راستاۋ بەلگٴىسٴىن قويماپسىز.',
+'lockdbsuccesssub' => 'دەرەكقوردى قۇلىپتاۋ سٴاتتٴى ٴوتتٴى',
+'unlockdbsuccesssub' => 'قۇلىپتالعان دەرەكقور اشىلدى',
+'lockdbsuccesstext' => 'دەرەكقور قۇلىپتالدى.
+<br />جٴوندەۋٴىڭٴىز بٴىتكەننەن كەيٴىن [[{{ns:special}}:Unlockdb|قۇلىپتاۋىن ٴوشٴىرۋگە]] ۇمىتپاڭىز.',
+'unlockdbsuccesstext' => 'قۇلىپتالعان دەرەكقور سٴاتتٴى اشىلدى.',
+'lockfilenotwritable' => 'دەرەكقور قۇلىپتاۋ فايلى جازىلمايدى. دەرەكقوردى قۇلىپتاۋ نە اشۋ ٴۇشٴىن, ۆەب-سەرۆەر فايلعا جازۋ رۇقساتى بولۋ قاجەت.',
+'databasenotlocked' => 'دەرەكقور قۇلىپتالعان جوق.',
+
+# Make sysop
+'makesysoptitle' => 'قاتىسۋشىنى ٴاكٴىمشٴى قىلۋ',
+'makesysoptext' => 'بۇل ٴۇلگٴىتتٴى قاراپايىم قاتىسۋشىنى ٴاكٴىمشٴى قىلۋ ٴۇشٴىن تٴورەشٴىلەر قولدانادى.
+جولاققا قاتىسۋشى اتىن ەنگٴىزٴىڭٴىز دە, جٴانە بۇل قاتىسۋشىنى ٴاكٴىمشٴى قىلۋ ٴۇشٴىن, تٴۇيمەنٴى باسىڭىز.',
+'makesysopname' => 'قاتىسۋشى اتى:',
+'makesysopsubmit' => 'بۇل قاتىسۋشىنى ٴاكٴىمشٴى قىل',
+'makesysopok' => '<b>«$1» دەگەن قاتىسۋشى ەندٴى ٴاكٴىمشٴى بوپ تاعايىندالدى</b>',
+'makesysopfail' => '<b>«$1» دەگەن قاتىسۋشى ٴاكٴىمشٴى بوپ تاعايىندالمادى. (اتىن دۇرىس ەنگٴىزدٴىڭٴىز بە?)</b>',
+'setbureaucratflag' => 'قاتىسۋشىنى تٴورەشٴى قىلۋ',
+'rightslog' => 'قاتىسۋشى_قۇقىقتارى_جۋرنالى',
+'rightslogtext' => 'بۇل پايدالانۋشى قۇقىقتارىن ٴوزگەرتۋ جۋرنالى.',
+'rightslogentry' => ' $1 توپ مٴۇشەلگٴىن $2 دەگەننەن $3 دەگەنگە ٴوزگەرتتٴى',
+'rights' => 'قۇقىقتارى:',
+'set_user_rights' => 'قاتىسۋشى قۇقىقتارىن تاعايىنداۋ',
+'user_rights_set' => '<b>«$1» دەگەن قاتىسۋشىنىڭ قۇقىقتارى جاڭارتىلدى</b>',
+'set_rights_fail' => '<b>«$1» دەگەن قاتىسۋشىنىڭ قۇقىقتارى تاعايىندالمادى. (اتىن دۇرىس ەنگٴىزدٴىڭٴىز بە?)</b>',
+'makesysop' => 'قاتىسۋشىنى ٴاكٴىمشٴى قىلۋ',
+'already_sysop' => 'بۇل قاتىسۋشى ٴاكٴىمشٴى بوپتى تٴۇگە',
+'already_bureaucrat' => 'بۇل قاتىسۋشى تورەشٴى بوپتى تٴۇگە',
+'rightsnone' => '(ەشقانداي)',
+
+# Move page
+'movepage' => 'بەتتٴى جىلجىتۋ',
+'movepagetext' => "تٴومەندەگٴى ٴۇلگٴىتتٴى قولدانىپ بەتتەردٴى قايتا اتايدى,
+بارلىق تاريحىن جاڭا اتاۋعا جىلجىتادى.
+بۇرىنعى بەت اتاۋى جاڭا اتاۋعا ايداتاتىن بەت بولادى.
+ەسكٴى اتاۋىنا سٴىلتەيتٴىن سٴىلتەمەلەر ٴوزگەرتٴىلمەيدٴى; جىلجىتۋدان سوڭ
+شىنجىرلى ايداتۋلار بار-جوعىن تەكسەرٴىڭٴىز.
+سٴىلتەمەلەر بۇرىنعى جولداۋىمەن بىلايعى ٴوتۋٴىن تەكسەرۋٴىنە
+سٴىز مٴىندەتتٴى بولاسىز.
+
+ەسكەرٴىڭٴىز, ەگەر جىلجىتىلاتىن اتاۋدا بەت بولسا, سول ەسكٴى بەتكە ايداتۋ
+بولعانشا جٴانە تاريحى بولسا, بەت '''جىلجىتىلمايدى'''.
+وسىنىڭ ماعىناسى: ەگەر بەتتٴى قاتەلٴىك پەن قايتا اتالسا,
+بۇرىنعى اتاۋىنا قايتا اتاۋعا بولادى,
+بٴىراق بار بەتتٴىڭ ٴۇستٴىنە جازۋعا بولمايدى.
+
+<b>نازار سالىڭىز!</b>
+بۇل دٴارٴىپتٴى بەتكە قاتاڭ جٴانە كەنەت ٴوزگەرٴىس جاساۋعا مٴۇمكٴىن;
+ٴارەكەتتٴىڭ الدىنان وسىنىڭ زارداپتارىن تٴۇسٴىنگەنٴىڭٴىزگە باتىل
+بولىڭىز.",
+'movepagetalktext' => "كەلەسٴى سەبەپتەر '''بولعانشا''' دەيٴىن, تالقىلاۋ بەتٴى ٴوزدٴىك تٴۇردە بٴىرگە جىلجىتىلادى:
+* بوس ەمەس تالقىلاۋ بەتٴى جاڭا اتاۋدا بولعاندا, نەمەسە
+* تٴومەندەگٴى قابىشاقتا بەلگٴىنٴى الاستاتقاندا.
+
+وسى ورايدا, قالاۋىڭىز بولسا, بەتتٴى قولدان جىلجىتا نە قوسا الاسىز.",
+'movearticle' => 'بەتتٴى جىلجىتۋ',
+'movenologin' => 'جٴۇيەگە كٴىرمەگەنسٴىز',
+'movenologintext' => 'بەتتٴى جىلجىتۋ ٴۇشٴىن تٴىركەلگەن بولۋىڭىز جٴانە
+ [[{{ns:special}}:Userlogin|كٴىرۋٴىڭٴىز]] قاجەت.',
+'newtitle' => 'جاڭا اتاۋعا',
+'movepagebtn' => 'بەتتٴى جىلجىت',
+'pagemovedsub' => 'جىلجىتۋ سٴاتتٴى اياقتالدى',
+'pagemovedtext' => '«[[$1]]» بەتٴى «[[$2]]» بەتٴىنە جىلجىتىلدى.',
+'articleexists' => 'بىلاي اتاۋلى بەت بار بولدى, نە تاڭداعان
+اتاۋىڭىز جارامدى ەمەس.
+باسقا اتاۋ تانداڭىز',
+'talkexists' => "'''بەتتٴىڭ ٴوزٴى سٴاتتٴى جىلجىتىلدى, بٴىراق تالقىلاۋ بەتٴى بٴىرگە جىلجىتىلمادى, ونىڭ سەبەبٴى جاڭا اتاۋدىڭ تالقىلاۋ بەتٴى بار تٴۇگە. بۇنى قولمەن قوسىڭىز.'''",
+'movedto' => 'مىناعان جىلجىتىلدى:',
+'movetalk' => 'قاتىستى تالقىلاۋ بەتٴىمەن بٴىرگە جىلجىتۋ',
+'talkpagemoved' => 'قاتىستى تالقىلاۋ بەتٴى دە جىلجىتىلدى.',
+'talkpagenotmoved' => 'قاتىستى تالقىلاۋ بەتٴى <strong>جىلجىتىلمادى</strong>.',
+'1movedto2' => '«[[$1]]» بەتٴىندە ايداتۋ قالدىرىپ «[[$2]]» بەتٴىنە جىلجىتتى',
+'1movedto2_redir' => '«[[$1]]» بەتٴىن «[[$2]]» ايداتۋ بەتٴىنٴىڭ ٴۇستٴىنە جىلجىتتى',
+'movelogpage' => 'جىلجىتۋ جۋرنالى',
+'movelogpagetext' => 'تٴومەندە جىلجىتىلعان بەتتەردٴىڭ تٴىزٴىمٴى بەرٴىلٴىپ تۇر.',
+'movereason' => 'سەبەبٴى',
+'revertmove' => 'قايتارۋ',
+'delete_and_move' => 'جويۋ جٴانە جىلجىتۋ',
+'delete_and_move_text' => '==جويۋ قاجەت==
+
+اقىرعى «[[$1]]» بەت اتاۋى بار تٴۇگە.
+جىلجىتۋعا جول بەرۋ ٴۇشٴىن جويامىز با?',
+'delete_and_move_confirm' => 'يٴا, وسى بەتتٴى جوي',
+'delete_and_move_reason' => 'جىلجىتۋعا جول بەرۋ ٴۇشٴىن جويىلعان',
+'selfmove' => 'قاينار جٴانە اقىرعى اتاۋى بٴىردەي; بەت ٴوزٴىنە جىلجىتىلمايدى.',
+'immobile_namespace' => 'قاينار نەمەسە اقىرعى اتاۋى ارنايى تٴۇرٴىندە بولدى; وسىنداي ەسٴىم اياسى جاعىنا جٴانە جاعىنان بەتتەر جىلجىتىلمايدى.',
+
+# Export
+'export' => 'بەتتەردٴى سىرتقا بەرۋ',
+'exporttext' => 'XML پٴىشٴىمٴىنە قاپتالعان بٴولەك بەت نە بەتتەر بۋماسى
+مٴاتٴىنٴىڭ جٴانە ٴوڭدەۋ تاريحىن سىرتقا بەرە الاسىز. وسىنى, باسقا ۋيكي-گە
+{{ns:special}}:Import page MediaWiki قۇرالى ارقىلى, سىرتتان الۋعا بولادى.
+
+بەتتەردٴى سىرتقا بەرۋ ٴۇشٴىن, اتاۋلارىن تٴومەندەگٴى مٴاتٴىن اۋماعىنا ەنگٴىزٴىڭٴىز,
+بٴىر جولدا بٴىر اتاۋ, جٴانە تانداڭىز: نە اعىمدىق نۇسقاسىن, بارلىق ەسكٴى نۇسقالارى مەن
+جٴانە تاريحى جولدارى مەن بٴىرگە, نە دٴال اعىمدىق نۇسقاسىن, سوڭعى ٴوڭدەۋ تۋرالى اقپاراتى مەن بٴىرگە.
+
+سوڭعى جاعدايدا سٴىلتەمەنٴى دە قولدانۋعا بولادى, مىسالى {{int:mainpage}} بەتٴى ٴۇشٴىن [[{{ns:Special}}:Export/{{int:mainpage}}]].',
+'exportcuronly' => 'تولىق تاريحىن ەمەس, تەك اعىمدىق نۇسقاسىن كٴىرٴىستٴىرٴىڭٴىز',
+'exportnohistory' => "----
+'''اڭعارتپا:''' ٴونٴىمدٴىلٴىك ٴاسەرٴى سەبەپتەرٴىنەن, بەتتەر تولىق تاريحىن سىرتقا بەرۋٴى ٴوشٴىرٴىلگەن.",
+'export-submit' => 'سىرتقا بەر',
+
+# Namespace 8 related
+'allmessages' => 'جٴۇيە حابارلارى',
+'allmessagesname' => 'اتاۋى',
+'allmessagesdefault' => 'ٴادەپكٴى مٴاتٴىنٴى',
+'allmessagescurrent' => 'اعىمدىق مٴاتٴىنٴى',
+'allmessagestext' => 'مىندا «MediaWiki:» ەسٴىم اياسىنداعى بارلىق قاتىناۋلى جٴۇيە حابار تٴىزٴىمٴى بەرٴىلٴىپ تۇر.',
+'allmessagesnotsupportedUI' => 'Your current interface language <b>$1</b> is not supported by Special:Allmessages at this site.',
+'allmessagesnotsupportedDB' => "'''wgUseDatabaseMessages''' بابى ٴوشٴىرٴىلگەن سەبەبٴىنەن '''{{ns:special}}:AllMessages''' سيپاتى سٴۇەمەلدەنبەيدٴى.",
+'allmessagesfilter' => 'حاباردى اتاۋى بويىنشا سٴۇزگٴىلەۋ:',
+'allmessagesmodified' => 'تەك ٴوزگەرتٴىلگەندٴى كٴورسەت',
+
+# Thumbnails
+'thumbnail-more' => 'ٴۇلكەيتۋ',
+'missingimage' => '<b>جوعالعان سۋرەت </b><br /><i>$1</i>',
+'filemissing' => 'جوعالعان فايل',
+'thumbnail_error' => 'نوباي قۇرۋ قاتەسٴى: $1',
+
+# Special:Import
+'import' => 'بەتتەردٴى سىرتتان الۋ',
+'importinterwiki' => 'ۋيكي-تاسىمالداپ سىرتتان الۋ',
+'import-interwiki-text' => 'سىرتتان الاتىن ۋيكي جوباسىن جٴانە بەت اتاۋىن تانداڭىز.
+نۇسقا كٴۇن-ايى جٴانە ٴوڭدەۋشٴى اتتارى ساقتالادى.
+بارلىق ۋيكي-تاسىمالداپ سىرتتان الۋ ٴارەكەتتەر [[{{ns:special}}:Log/import|سىرتتان الۋ جۋرنالىنا]] جازىلىپ الىنادى.',
+'import-interwiki-history' => 'وسى بەتتٴىڭ بارلىق تاريحي نۇسقالارىن كٴوشٴىرۋ',
+'import-interwiki-submit' => 'سىرتتان الۋ',
+'import-interwiki-namespace' => 'مىنا ەسٴىم اياسىنا بەتتەردٴى تاسىمالداۋ:',
+'importtext' => 'قاينار ۋيكيدەن «Special:Export» قۋرالىن قولدانىپ, فايلدى سىرتقا بەرٴىڭٴىز, ديسكٴىڭٴىزگە ساقتاڭىز, سوسىن مىندا قوتارىڭىز.',
+'importstart' => 'بەتتەردٴى سىرتتان الۋى…',
+'import-revision-count' => '$1 نۇسقا',
+'importnopages' => 'سىرتتان الىناتىن بەتتەر جوق.',
+'importfailed' => 'سىرتتان الۋ سٴاتسٴىز بٴىتتٴى: $1',
+'importunknownsource' => 'Cىرتتان الۋ قاينار تٴۇرٴى تانىمالسىز',
+'importcantopen' => 'سىرتتان الۋ فايلى اشىلمايدى',
+'importbadinterwiki' => 'جارامسىز ۋيكي-ارالىق سٴىلتەمە',
+'importnotext' => 'بوستى, نە مٴاتٴىنٴى جوق',
+'importsuccess' => 'سىرتتان الۋ سٴاتتٴى اياقتالدى!',
+'importhistoryconflict' => 'تاريحىنىڭ ەگەس نۇسقالارى بار (بۇل بەتتٴى الدىندا سىرتتان الىنعان سيياقتى)',
+'importnosources' => 'ەشقانداي ۋيكي-تاسىمالداپ سىرتتان الۋ قاينارى بەلگٴىلەنمەگەن, جٴانە تاريحىن تٴىكەلەي قوتارۋى ٴوشٴىرٴىلگەن.',
+'importnofile' => 'سىرتتان الىناتىن فايل قوتارىلعان جوق.',
+'importuploaderror' => 'سىرتتان الۋ فايلدىڭ قوتارۋى سٴاتسٴىز بٴىتتٴى; وسى فايل مٴولشەرٴى رۇقسات ەتٴىلگەن مٴولشەردەن اسۋى مٴۇمكٴىن.',
+
+# Import log
+'importlogpage' => 'سىرتتان الۋ جۋرنالى',
+'importlogpagetext' => 'باسقا ۋيكيلەردەن ٴوڭدەۋ تاريحىمەن بٴىرگە بەتتەردٴى ٴاكٴىمشٴىلٴىك رەتٴىندە سىرتتان الۋ.',
+'import-logentry-upload' => 'فايل قوتارۋىمەن سىرتتان «[[$1]]» بەتٴى الىندى',
+'import-logentry-upload-detail' => '$1 نۇسقا',
+'import-logentry-interwiki' => 'ۋيكي-تاسىمالدانعان $1',
+'import-logentry-interwiki-detail' => '$2 دەگەننەن $1 نۇسقا',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => '{{SITENAME}} جوباسىنان ٴىزدەستٴىرۋ [alt-f]',
+'tooltip-minoredit' => 'وسىنى شاعىن تٴۇزەتۋ دەپ بەلگٴىلەۋ [alt-i]',
+'tooltip-save' => 'تٴۇزەتۋٴىڭٴىزدٴى ساقتاۋ [alt-s]',
+'tooltip-preview' => 'ساقتاۋدىڭ الدىنان تٴۇزەتۋٴىڭٴىزدٴى قاراپ شىعىڭىز! [alt-p]',
+'tooltip-diff' => 'مٴاتٴىنگە قانداي ٴوزگەرٴىستەردٴى جاساعانىڭىزدى قاراۋ. [alt-v]',
+'tooltip-compareselectedversions' => 'بەتتٴىڭ ەكٴى نۇسقاسىنىڭ ايىرماسىن قاراۋ. [alt-v]',
+'tooltip-watch' => 'بۇل بەتتٴى باقىلاۋ تٴىزٴىمٴىڭٴىزگە ٴۇستەۋ [alt-w]',
+
+# Stylesheets
+'common.css' => '/** مىنداعى CSS ٴامٴىرلەرٴى بارلىق بەزەندٴىرۋ مٴانەرٴىندەردە قولدانىلادى */',
+'monobook.css' => '/* مىنداعى CSS ٴامٴىرلەرٴى «دارا كٴىتاپ» بەزەندٴىرۋ مٴانەرٴىن پايدالانۋشىلارعا ٴاسەر ەتەدٴى */',
+
+# Metadata
+'nodublincore' => 'وسى سەرۆەرگە «Dublin Core RDF» مەتا-دەرەكتەرٴى ٴوشٴىرٴىلگەن.',
+'nocreativecommons' => 'وسى سەرۆەرگە «Creative Commons RDF» مەتا-دەرەكتەرٴى ٴوشٴىرٴىلگەن.',
+'notacceptable' => 'وسى ۋيكي سەرۆەرٴى سٴىزدٴىڭ «پايدالانۋشى ٴارەكەتكٴىشٴى» وقي الاتىن پٴىشٴىمٴى بار دەرەكتەردٴى جٴىبەرە المايدى.',
+
+# Attribution
+'anonymous' => '{{SITENAME}} تٴىركەلگٴىسٴىز پايدالانۋشى(لار)',
+'siteuser' => '{{SITENAME}} قاتىسۋشى $1',
+'lastmodifiedatby' => 'بۇل بەتتٴى $3 قاتىسۋشى سوڭعى ٴوزگەرتكەن كەزٴى: $2, $1.', # $1 date, $2 time, $3 user
+'and' => 'جٴانە',
+'othercontribs' => 'شىعارما نەگٴىزٴىن $1 جازعان.',
+'others' => 'باسقالار',
+'siteusers' => '{{SITENAME}} قاتىسۋشى(لار) $1',
+'creditspage' => 'بەتتٴى جازعاندار',
+'nocredits' => 'بۇل بەتتٴى جازعاندار تۋرالى اقپارات جوق.',
+
+# Spam protection
+'spamprotectiontitle' => '«سپام»-نان قورعايتىن سٴۇزگٴى',
+'spamprotectiontext' => 'بۇل بەتتٴىڭ ساقتاۋىن «سپام» سٴۇزگٴىسٴى بۇعاتتادى. بۇنىڭ سەبەبٴى سىرتقى توراپ سٴىلتەمەسٴىنەن بولۋى مٴۇمكٴىن.',
+'spamprotectionmatch' => 'كەلەسٴى «سپام» مٴاتٴىنٴى سٴۇزگٴىلەنگەن: $1',
+'subcategorycount' => 'بۇل ساناتتا {{PLURAL:$1|بٴىر|$1}} تٴومەنگٴى سانات بار.',
+'categoryarticlecount' => 'بۇل ساناتتا {{PLURAL:$1|بٴىر|$1}} بەت بار.',
+'category-media-count' => 'بۇل ساناتتا {{PLURAL:$1|بٴىر|$1}} فايل بار.',
+'listingcontinuesabbrev' => ' (جالع.)',
+'spambot_username' => 'MediaWiki spam cleanup',
+'spam_reverting' => '$1 دەگەنگە سٴىلتەمەسٴى جوق سوڭعى نۇسقاسىنا قايتارىلدى',
+'spam_blanking' => '$1 دەگەنگە سٴىلتەمەسٴى بار بارلىق نۇسقالار تازارتىلدى',
+
+# Info page
+'infosubtitle' => 'بەت تۋرالى اقپارات',
+'numedits' => 'تٴۇزەتۋ سانى (نەگٴىزگٴى بەتٴى): $1',
+'numtalkedits' => 'تٴۇزەتۋ سانى (تالقىلاۋ بەتٴى): $1',
+'numwatchers' => 'باقىلاۋشى سانى: $1',
+'numauthors' => 'ٴارتٴۇرلٴى اۋتورلار سانى (نەگٴىزگٴى بەتٴى): $1',
+'numtalkauthors' => 'ٴارتٴۇرلٴى اۋتور سانى (تالقىلاۋ بەتٴى): $1',
+
+# Math options
+'mw_math_png' => 'ٴارقاشان PNG تٴۇرٴىمەن كٴورسەت',
+'mw_math_simple' => 'كٴادٴىمگٴى بولسا HTML پٴىشٴىمٴىمەن, باسقاشا PNG تٴۇرٴىمەن',
+'mw_math_html' => 'ىقتيمال بولسا HTML پٴىشٴىمٴىمەن, باسقاشا PNG تٴۇرٴىمەن',
+'mw_math_source' => 'TeX پٴىشٴىمٴىندە قالدىرۋ (مٴاتٴىندٴىك شولعىشتارىنا)',
+'mw_math_modern' => 'وسى زاماننىڭ شولعىشتارىنا ۇسىنىلعان',
+'mw_math_mathml' => 'ىقتيمال بولسا MathML پشٴىمٴىمەن (سىناق تٴۇرٴىندە)',
+
+# Patrolling
+'markaspatrolleddiff' => 'كٴۇزەتتە دەپ بەلگٴىلەۋ',
+'markaspatrolledtext' => 'وسى بەتتٴى كٴۇزەتۋدە دەپ بەلگٴىلەۋ',
+'markedaspatrolled' => 'كٴۇزەتتە دەپ بەلگٴىلەندٴى',
+'markedaspatrolledtext' => 'تالعانعان نۇسقا كٴۇزەتتە دەپ بەلگٴىلەندٴى.',
+'rcpatroldisabled' => 'جۋىقتاعى ٴوزگەرٴىستەر كٴۇزەتٴى ٴوشٴىرٴىلگەن',
+'rcpatroldisabledtext' => 'جۋىقتاعى ٴوزگەرٴىستەر كٴۇزەتٴى قاسيەتٴى اعىمدا ٴوشٴىرٴىلگەن.',
+'markedaspatrollederror' => 'كٴۇزەتتە دەپ بەلگٴىلەنبەيدٴى',
+'markedaspatrollederrortext' => 'كٴۇزەتتە دەپ بەلگٴىلەۋ ٴۇشٴىن نۇسقاسىن ەنگٴىزٴىڭٴىز.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* tooltips and access keys */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','جەكە بەتٴىم');
+ta['pt-anonuserpage'] = new Array('.','وسى IP جايدىڭ جەكە بەتٴى');
+ta['pt-mytalk'] = new Array('n','تالقىلاۋ بەتٴىم');
+ta['pt-anontalk'] = new Array('n','وسى IP جاي تٴۇزەتۋلەرٴىن تالقىلاۋ');
+ta['pt-preferences'] = new Array('','باپتاۋىم');
+ta['pt-watchlist'] = new Array('l','ٴوزگەرٴىستەرٴىن باقىلاپ تۇرعان بەتتەر تٴىزٴىمٴىم.');
+ta['pt-mycontris'] = new Array('y','ٴۇلەستەرٴىمدٴىڭ تٴىزٴىمٴى');
+ta['pt-login'] = new Array('o','كٴىرۋٴىڭٴىزدٴى ۇسىنامىز, ول مٴىندەتتٴى ەمەس.');
+ta['pt-anonlogin'] = new Array('o','كٴىرۋٴىڭٴىزدٴى ۇسىنامىز, بٴىراق, ول مٴىندەتتٴى ەمەس.');
+ta['pt-logout'] = new Array('','شىعۋ');
+ta['ca-talk'] = new Array('t','ماعلۇمات بەتتٴى تالقىلاۋ');
+ta['ca-edit'] = new Array('e','بۇل بەتتٴى ٴوڭدەي الاسىز. ساقتاۋدىڭ الدىندا «قاراپ شىعۋ» تٴۇيمەسٴىن نۇقىڭىز.');
+ta['ca-addsection'] = new Array('+','بۇل تالقىلاۋ بەتٴىندە جاڭا تاراۋ باستاۋ.');
+ta['ca-viewsource'] = new Array('e','بۇل بەت قورعالعان, بٴىراق, قاينارىن قاراۋعا بولادى.');
+ta['ca-history'] = new Array('h','بۇل بەتتٴىن جۋىقتاعى نۇسقالارى.');
+ta['ca-protect'] = new Array('=','بۇل بەتتٴى قورعاۋ');
+ta['ca-unprotect'] = new Array('=','بۇل بەتتٴى قورعاماۋ');
+ta['ca-delete'] = new Array('d','بۇل بەتتٴى جويۋ');
+ta['ca-undelete'] = new Array('d','بۇل بەتتٴىڭ جويۋدىڭ الدىنداعى بولعان تٴۇزەتۋلەرٴىن قايتارۋ');
+ta['ca-move'] = new Array('m','بۇل بەتتٴى جىلجىتۋ');
+ta['ca-nomove'] = new Array('m','بۇل بەتتٴى جىلجىتۋعا رۇقساتىڭىز جوق');
+ta['ca-watch'] = new Array('w','بۇل بەتتٴى باقىلاۋ تٴىزٴىمٴىڭٴىزگە ٴۇستەۋ');
+ta['ca-unwatch'] = new Array('w','بۇل بەتتٴى باقىلاۋ تٴىزٴىمٴىڭٴىزدەن الاستاتۋ');
+ta['ca-varlang-0'] = new Array('','كيريلل جازۋى');
+ta['ca-varlang-1'] = new Array('','لاتىن جازۋى');
+ta['ca-varlang-2'] = new Array('','اراب جازۋى');
+ta['search'] = new Array('f','وسى ۋيكيدەن ٴىزدەۋ');
+ta['p-logo'] = new Array('','باستى بەتكە');
+ta['n-mainpage'] = new Array('z','باستى بەتكە بارىپ كەتٴىڭٴىز');
+ta['n-portal'] = new Array('','جوبا تۋرالى, نە ٴىستەۋٴىڭٴىزگە بولاتىن, قايدان تابۋعا بولاتىن تۋرالى');
+ta['n-currentevents'] = new Array('','اعىمداعى وقيعالارعا قاتىستى اقپارات');
+ta['n-recentchanges'] = new Array('r','وسى ۋيكيدەگٴى جۋىقتاعى ٴوزگەرٴىستەر تٴىزٴىمٴى.');
+ta['n-randompage'] = new Array('x','كەزدەيسوق بەتتٴى جٴۇكتەۋ');
+ta['n-help'] = new Array('','انىقتاما تابۋ ورنى.');
+ta['n-sitesupport'] = new Array('','بٴىزگە جٴاردەم ەتٴىڭٴىز');
+ta['t-whatlinkshere'] = new Array('j','مىندا سٴىلتەگەن بارلىق بەتتەردٴىڭ تٴىزٴىمٴى');
+ta['t-recentchangeslinked'] = new Array('k','مىننان سٴىلتەنگەن بەتتەردٴىڭ جۋىقتاعى ٴوزگەرٴىستەرٴى');
+ta['feed-rss'] = new Array('','بۇل بەتتٴىڭ RSS ارناسى');
+ta['feed-atom'] = new Array('','بۇل بەتتٴىڭ Atom ارناسى');
+ta['t-contributions'] = new Array('','وسى قاتىسۋشىنىڭ ٴۇلەس تٴىزٴىمٴىن قاراۋ');
+ta['t-emailuser'] = new Array('','وسى قاتىسۋشىعا email جٴىبەرۋ');
+ta['t-upload'] = new Array('u','سۋرەت نە مەديا فايلدارىن قوتارۋ');
+ta['t-specialpages'] = new Array('q','بارلىق ارنايى بەتتەر تٴىزٴىمٴى');
+ta['t-print'] = new Array('','وسى بەتتٴىڭ باسىپ شىعارۋ نۇسقاسى');
+ta['t-permalink'] = new Array('','بەتتٴىڭ وسى نۇسقاسىنىڭ تۇراقتى سٴىلتەمەسٴى');
+ta['ca-nstab-main'] = new Array('c','ماعلۇمات بەتٴىن قاراۋ');
+ta['ca-nstab-user'] = new Array('c','قاتىسۋشى بەتٴىن قاراۋ');
+ta['ca-nstab-media'] = new Array('c','تاسپا بەتٴىن قاراۋ');
+ta['ca-nstab-special'] = new Array('','بۇل ارنايى بەت, بەتتٴىڭ ٴوزٴى ٴوڭدەلٴىنبەيدٴى.');
+ta['ca-nstab-project'] = new Array('a','جوبا بەتٴىن قاراۋ');
+ta['ca-nstab-image'] = new Array('c','سۋرەت بەتٴىن قاراۋ');
+ta['ca-nstab-mediawiki'] = new Array('c','جٴۇيە حابارىن قاراۋ');
+ta['ca-nstab-template'] = new Array('c','ٴۇلگٴىنٴى قاراۋ');
+ta['ca-nstab-help'] = new Array('c','انىقتىما بەتٴىن قاراۋ');
+ta['ca-nstab-category'] = new Array('c','سانات بەتٴىن قاراۋ');",
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* مىنداعى كەز كەلگەن JavaScript ٴامٴىرلەرٴى ٴارقايسى بەت جٴۇكتەلگەندە بارلىق پايدالانۋشىلارعا جٴۇكتەلەدٴى. */
+
+// BEGIN workaround for RTL
+if (wgUserLanguage == "kk-cn"){
+ document.direction="rtl";
+ document.write(\'<style type="text/css">html {direction: rtl;}</style>\');
+ document.write(\'<link rel="stylesheet" type="text/css" href="\'+stylepath+\'/common/common_rtl.css">\');
+ document.write(\'<link rel="stylesheet" type="text/css" href="\'+stylepath+\'/\'+skin+\'/rtl.css">\');
+}
+// END workaround for RTL',
+
+# Image deletion
+'deletedrevision' => 'مىنا ەسكٴى نۇسقاسىن جويدى: $1.',
+
+# Browsing diffs
+'previousdiff' => '← الدىڭعىمەن ايىرماسى',
+'nextdiff' => 'كەلەسٴىمەن ايىرماسى →',
+
+'imagemaxsize' => 'سۋرەت تٴۇيٴىندەمە بەتٴىندەگٴى سۋرەتتٴىڭ مٴولشەرٴىن شەكتەۋٴى:',
+'thumbsize' => 'نوباي مٴولشەرٴى:',
+'showbigimage' => 'جوعارى اجىراتىلىمدى ($1×$2, $3 كب) نۇسقاسىن جٴۇكتەۋ',
+
+'newimages' => 'ەڭ جاڭا فايلدار قويماسى',
+'showhidebots' => '(بوتتاردى $1)',
+'noimages' => 'كٴورەتٴىن ەشتەڭە جوق.',
+
+# Variants for Kazakh language
+'variantname-kk-tr' => 'Latın',
+'variantname-kk-kz' => 'Кирил',
+'variantname-kk-cn' => 'توتە',
+'variantname-kk' => 'disable',
+
+# Labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'قاتىسۋشى:',
+'speciallogtitlelabel' => 'اتاۋ:',
+
+'passwordtooshort' => 'قۇپييا سٴوزٴىڭٴىز تىم قىسقا. ەڭ كەمٴىندە $1 ٴارٴىپ بولۋى قاجەت.',
+
+# Media Warning
+'mediawarning' => "'''نازار سالىڭىز''': بۇل فايل تٴۇرٴىندە قاسكٴۇنەمدٴى ٴامٴىردٴىڭ بار بولۋى ىقتيمال; فايلدى جەگٴىپ جٴۇيەڭٴىزگە زييان كەلتٴىرۋٴىڭٴىز مٴۇمكٴىن.<hr />",
+
+'fileinfo' => '$1 كب, MIME تٴۇرٴى: <code>$2</code>',
+
+# Metadata
+'metadata' => 'مەتا-دەرەكتەرٴى',
+'metadata-help' => 'وسى فايلدا قوسىمشا اقپارات بار. بٴالكٴىم, وسى اقپارات فايلدى جاساپ شىعارۋ, نە ساندىلاۋ ٴۇشٴىن پايدالانعان ساندىق كامەرا, نە مٴاتٴىنالعىردان الىنعان. ەگەر وسى فايل نەگٴىزگٴى كٴۇيٴىنەن ٴوزگەرتٴىلگەن بولسا, كەيبٴىر ەجەلەلەرٴى ٴوزگەرتٴىلگەن فوتوسۋرەتكە لايىق بولماس.',
+'metadata-expand' => 'ەگجەي-تەگجەيٴىن كٴورسەت',
+'metadata-collapse' => 'ەگجەي-تەگجەيٴىن جاسىر',
+'metadata-fields' => 'وسى حاباردا تٴىزٴىمدەلگەن EXIF مەتا-دەرەك اۋماقتارى,
+سۋرەت بەتٴى كٴورسەتۋ كەزٴىندە مەتا-دەرەك كەستە جاسىرىلىعاندا كٴىرٴىستٴىرلەدٴى.
+باسقاسى ٴادەپكٴىدەن جاسىرىلادى.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# EXIF tags
+'exif-imagewidth' => 'ەنٴى',
+'exif-imagelength' => 'بيٴىكتٴىگٴى',
+'exif-bitspersample' => 'قۇراش سايىن بيت سانى',
+'exif-compression' => 'قىسىم سۇلباسى',
+'exif-photometricinterpretation' => 'پيكسەل قيىسۋى',
+'exif-orientation' => 'مەگزەۋٴى',
+'exif-samplesperpixel' => 'قۇراش سانى',
+'exif-planarconfiguration' => 'دەرەك رەتتەۋٴى',
+'exif-ycbcrsubsampling' => 'Y قۇراشىنىڭ C قۇراشىنا جارناقتاۋى',
+'exif-ycbcrpositioning' => 'Y قۇراشى جٴانە C قۇراشى مەكەندەۋٴى',
+'exif-xresolution' => 'دەرەلەي اجىراتىلىمدىعى',
+'exif-yresolution' => 'تٴىرەلەي اجىراتىلىمدىعى',
+'exif-resolutionunit' => 'X جٴانە Y اجىراتىلىمدىقتارىعىنىڭ ٴولشەمٴى',
+'exif-stripoffsets' => 'سۋرەت دەرەرەكتەرٴىنٴىڭ جايعاسۋى',
+'exif-rowsperstrip' => 'بەلدٴىك سايىن جول سانى',
+'exif-stripbytecounts' => 'قىسىمدالعان بەلدٴىك سايىن بايت سانى',
+'exif-jpeginterchangeformat' => 'JPEG SOI دەگەننەن ىعىسۋى',
+'exif-jpeginterchangeformatlength' => 'JPEG دەرەكتەرٴىنٴىڭ بايت سانى',
+'exif-transferfunction' => 'تاسىمالداۋ فۋنكتسيياسى',
+'exif-whitepoint' => 'اق نٴۇكتە تٴۇستٴىلٴىگٴى',
+'exif-primarychromaticities' => 'العى شەپتەگٴى تٴۇستٴىلٴىكتەرٴى',
+'exif-ycbcrcoefficients' => 'تٴۇس اياسىن تاسىمالداۋ ماتريتسالىق ەسەلٴىكتەرٴى',
+'exif-referenceblackwhite' => 'قارا جٴانە اق انىقتاۋىش قوس كولەمدەرٴى',
+'exif-datetime' => 'فايلدىڭ ٴوزگەرتٴىلگەن كٴۇن-ايى',
+'exif-imagedescription' => 'سۋرەت اتاۋى',
+'exif-make' => 'كامەرا ٴوندٴىرۋشٴىسٴى',
+'exif-model' => 'كامەرا ٴۇلگٴىسٴى',
+'exif-software' => 'قولدانىلعان باعدارلاما',
+'exif-artist' => 'جىعارماشىسى',
+'exif-copyright' => 'جىعارماشىلىق قۇقىقتار يەسٴى',
+'exif-exifversion' => 'Exif نۇسقاسى',
+'exif-flashpixversion' => 'سٴۇيەمدەلٴىنگەن Flashpix نۇسقاسى',
+'exif-colorspace' => 'تٴۇس اياسى',
+'exif-componentsconfiguration' => 'ٴارقايسى قۇراش مٴانٴى',
+'exif-compressedbitsperpixel' => 'سۋرەت قىسىمداۋ تٴارتٴىبٴى',
+'exif-pixelydimension' => 'سۋرەتتٴىڭ جارامدى ەنٴى',
+'exif-pixelxdimension' => 'سۋرەتتٴىڭ جارامدى بيٴىكتٴىگٴى',
+'exif-makernote' => 'ٴوندٴىرۋشٴى ەسكەرتپەلەرٴى',
+'exif-usercomment' => 'پايدالانۋشى مٴاندەمەلەرٴى',
+'exif-relatedsoundfile' => 'قاتىستى دىبىس فايلى',
+'exif-datetimeoriginal' => 'جاسالعان كەزٴى',
+'exif-datetimedigitized' => 'ساندىقتاۋ كەزٴى',
+'exif-subsectime' => 'جاسالعان كەزٴىنٴىڭ سەكۋند بٴولشەكتەرٴى',
+'exif-subsectimeoriginal' => 'تٴۇپنۇسقا كەزٴىنٴىڭ سەكۋند بٴولشەكتەرٴى',
+'exif-subsectimedigitized' => 'ساندىقتاۋ كەزٴىنٴىڭ سەكۋند بٴولشەكتەرٴى',
+'exif-exposuretime' => 'ۇستالىم ۋاقىتى',
+'exif-exposuretime-format' => '$1 س ($2)',
+'exif-fnumber' => 'ساڭىلاۋ مٴولشەرٴى',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'ۇستالىم باعدارلاماسى',
+'exif-spectralsensitivity' => 'سپەكتر بويىنشا سەزگٴىشتٴىگٴى',
+'exif-isospeedratings' => 'ISO جىلدامدىق جارناقتاۋى (جارىق سەزگٴىشتٴىگٴى)',
+'exif-oecf' => 'وپتوەلەكتروندى تٴۇرلەتۋ ىقپالى',
+'exif-shutterspeedvalue' => 'جاپقىش جىلدامدىلىعى',
+'exif-aperturevalue' => 'ساڭىلاۋلىق',
+'exif-brightnessvalue' => 'اشىقتىق',
+'exif-exposurebiasvalue' => 'ۇستالىم ٴوتەمٴى',
+'exif-maxaperturevalue' => 'بارىنشا ساڭىلاۋ اشۋى',
+'exif-subjectdistance' => 'نىسانا قاشىقتىعى',
+'exif-meteringmode' => 'ٴولشەۋ تٴارتٴىبٴى',
+'exif-lightsource' => 'جارىق كٴوزٴى',
+'exif-flash' => 'جارقىلداعىش',
+'exif-focallength' => 'شوعىرلاۋ الشاقتىعى',
+'exif-focallength-format' => '$1 mm',
+'exif-subjectarea' => 'نىسانا اۋقىمى',
+'exif-flashenergy' => 'جارقىلداعىش قارقىنى',
+'exif-spatialfrequencyresponse' => 'كەڭٴىستٴىك-جيٴىلٴىك ٴاسەرشٴىلٴىگٴى',
+'exif-focalplanexresolution' => 'ح بويىنشا شوعىرلاۋ جايپاقتىقتىڭ اجىراتىلىمدىعى',
+'exif-focalplaneyresolution' => 'Y بويىنشا شوعىرلاۋ جايپاقتىقتىڭ اجىراتىلىمدىعى',
+'exif-focalplaneresolutionunit' => 'شوعىرلاۋ جايپاقتىقتىڭ اجىراتىلىمدىق ٴولشەمٴى',
+'exif-subjectlocation' => 'نىسانا مەكەندەۋٴى',
+'exif-exposureindex' => 'ۇستالىم ايقىنداۋى',
+'exif-sensingmethod' => 'سەنسوردٴىڭ ٴولشەۋ ٴادٴىسٴى',
+'exif-filesource' => 'فايل قاينارى',
+'exif-scenetype' => 'ساحنا تٴۇرٴى',
+'exif-cfapattern' => 'CFA سٴۇزگٴى كەيٴىپٴى',
+'exif-customrendered' => 'قوسىمشا سۋرەت ٴوڭدەتۋٴى',
+'exif-exposuremode' => 'ۇستالىم تٴارتٴىبٴى',
+'exif-whitebalance' => 'اق تٴۇسٴىنٴىڭ تەندەستٴىگٴى',
+'exif-digitalzoomratio' => 'ساندىق اۋقىمداۋ جارناقتاۋى',
+'exif-focallengthin35mmfilm' => '35 mm تاسپاسىنىڭ شوعىرلاۋ الشاقتىعى',
+'exif-scenecapturetype' => 'تٴۇسٴىرگەن ساحنا تٴۇرٴى',
+'exif-gaincontrol' => 'ساحنانى مەڭگەرۋ',
+'exif-contrast' => 'قاراما-قارسىلىق',
+'exif-saturation' => 'قانىقتىق',
+'exif-sharpness' => 'ايقىندىق',
+'exif-devicesettingdescription' => 'جابدىق باپتاۋ سيپاتتارى',
+'exif-subjectdistancerange' => 'ساحنا قاشىقتىعىنىڭ كٴولەمٴى',
+'exif-imageuniqueid' => 'سۋرەتتٴىڭ بٴىرەگەي نٴومٴىرٴى (ID)',
+'exif-gpsversionid' => 'GPS بەلگٴىشەسٴىنٴىڭ نۇسقاسى',
+'exif-gpslatituderef' => 'سولتٴۇستٴىك نەمەسە وڭتٴۇستٴىك بويلىعى',
+'exif-gpslatitude' => 'بويلىعى',
+'exif-gpslongituderef' => 'شىعىس نەمەسە باتىس ەندٴىگٴى',
+'exif-gpslongitude' => 'ەندٴىگٴى',
+'exif-gpsaltituderef' => 'بيٴىكتٴىك كٴورسەتۋٴى',
+'exif-gpsaltitude' => 'بيٴىكتٴىك',
+'exif-gpstimestamp' => 'GPS ۋاقىتى (اتوم ساعاتى)',
+'exif-gpssatellites' => 'ٴولشەۋگە پيدالانىلعان جەر سەرٴىكتەرٴى',
+'exif-gpsstatus' => 'قابىلداعىش كٴۇيٴى',
+'exif-gpsmeasuremode' => 'ٴولشەۋ تٴارتٴىبٴى',
+'exif-gpsdop' => 'ٴولشەۋ دٴالدٴىگٴى',
+'exif-gpsspeedref' => 'جىلدامدىلىق ٴولشەمٴى',
+'exif-gpsspeed' => 'GPS قابىلداعىشتىڭ جىلدامدىلىعى',
+'exif-gpstrackref' => 'قوزعالىس باعىتىن كٴورسەتۋٴى',
+'exif-gpstrack' => 'قوزعالىس باعىتى',
+'exif-gpsimgdirectionref' => 'سۋرەت باعىتىن كٴورسەتۋٴى',
+'exif-gpsimgdirection' => 'سۋرەت باعىتى',
+'exif-gpsmapdatum' => 'پايدالانىلعان گەودەزييالىق تٴۇسٴىرمە دەرەكتەرٴى',
+'exif-gpsdestlatituderef' => 'نىسانا بويلىعىن كٴورسەتۋٴى',
+'exif-gpsdestlatitude' => 'نىسانا بويلىعى',
+'exif-gpsdestlongituderef' => 'نىسانا ەندٴىگٴىن كٴورسەتۋٴى',
+'exif-gpsdestlongitude' => 'نىسانا ەندٴىگٴى',
+'exif-gpsdestbearingref' => 'نىسانا ازيمۋتىن كٴورسەتۋٴى',
+'exif-gpsdestbearing' => 'نىسانا ازيمۋتى',
+'exif-gpsdestdistanceref' => 'نىسانا قاشىقتىعىن كٴورسەتۋٴى',
+'exif-gpsdestdistance' => 'نىسانا قاشىقتىعى',
+'exif-gpsprocessingmethod' => 'GPS ٴوڭدەتۋ ٴادٴىسٴىنٴىڭ اتاۋى',
+'exif-gpsareainformation' => 'GPS اۋماعىنىڭ اتاۋى',
+'exif-gpsdatestamp' => 'GPS كٴۇن-ايى',
+'exif-gpsdifferential' => 'GPS سارالانعان تٴۇزەتۋ',
+
+# EXIF attributes
+'exif-compression-1' => 'ۇلعايتىلعان',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'قالىپتى', # 0th row: top; 0th column: left
+'exif-orientation-2' => 'دەرەلەي شاعىلىسقان', # 0th row: top; 0th column: right
+'exif-orientation-3' => '180° بۇرىشقا اينالعان', # 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'تٴىرەلەي شاعىلىسقان', # 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'ساعات تٴىلشەسٴىنە قارسى 90° بۇرىشقا اينالعان جٴانە تٴىرەلەي شاعىلىسقان', # 0th row: left; 0th column: top
+'exif-orientation-6' => 'ساعات تٴىلشە بويىنشا 90° بۇرىشقا اينالعان', # 0th row: right; 0th column: top
+'exif-orientation-7' => 'ساعات تٴىلشە بويىنشا 90° بۇرىشقا اينالعان جٴانە تٴىرەلەي شاعىلىسقان', # 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'ساعات تٴىلشەسٴىنە قارسى 90° بۇرىشقا اينالعان', # 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'تالپاق پٴىشٴىم',
+'exif-planarconfiguration-2' => 'تايپاق پٴىشٴىم',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'بار بولمادى',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'انىقتالماعان',
+'exif-exposureprogram-1' => 'قولمەن',
+'exif-exposureprogram-2' => 'باعدارلامالى ٴادٴىس (قالىپتى)',
+'exif-exposureprogram-3' => 'ساڭىلاۋ باسىڭقىلىعى',
+'exif-exposureprogram-4' => 'ىسىرما باسىڭقىلىعى',
+'exif-exposureprogram-5' => 'ٴونەر باعدارلاماسى (انىقتىق تەرەندٴىگٴىنە ساناسقان)',
+'exif-exposureprogram-6' => 'قيمىل باعدارلاماسى (جاپقىش شاپشاندىلىعىنا ساناسقان)',
+'exif-exposureprogram-7' => 'تٴىرەلەي ٴادٴىسٴى (ارتى شوعىرلاۋسىز تاياۋ تٴۇسٴىرمەلەر)',
+'exif-exposureprogram-8' => 'دەرەلەي ٴادٴىسٴى (ارتى شوعىرلانعان دەرەلەي تٴۇسٴىرمەلەر)',
+
+'exif-subjectdistance-value' => '$1 m',
+
+'exif-meteringmode-0' => 'بەلگٴىسٴىز',
+'exif-meteringmode-1' => 'بٴىركەلكٴى',
+'exif-meteringmode-2' => 'بۇلدىر داق',
+'exif-meteringmode-3' => 'بٴىرداقتى',
+'exif-meteringmode-4' => 'كٴوپداقتى',
+'exif-meteringmode-5' => 'ٴورنەكتٴى',
+'exif-meteringmode-6' => 'جىرتىندى',
+'exif-meteringmode-255' => 'باسقا',
+
+'exif-lightsource-0' => 'بەلگٴىسٴىز',
+'exif-lightsource-1' => 'كٴۇن جارىعى',
+'exif-lightsource-2' => 'كٴۇنجارىقتى شام',
+'exif-lightsource-3' => 'قىزدىرعىشتى شام',
+'exif-lightsource-4' => 'جارقىلداعىش',
+'exif-lightsource-9' => 'اشىق كٴۇن',
+'exif-lightsource-10' => 'بۇلىنعىر كٴۇن',
+'exif-lightsource-11' => 'كٴولەنكەلٴى',
+'exif-lightsource-12' => 'كٴۇنجارىقتى شام (D 5700–7100 K)',
+'exif-lightsource-13' => 'كٴۇنجارىقتى شام (N 4600–5400 K)',
+'exif-lightsource-14' => 'كٴۇنجارىقتى شام (W 3900–4500 K)',
+'exif-lightsource-15' => 'كٴۇنجارىقتى شام (WW 3200–3700 K)',
+'exif-lightsource-17' => 'قالىپتى جارىق قاينارى A',
+'exif-lightsource-18' => 'قالىپتى جارىق قاينارى B',
+'exif-lightsource-19' => 'قالىپتى جارىق قاينارى C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ستۋدييالىق ISO كٴۇنجارىقتى شام',
+'exif-lightsource-255' => 'باسقا جارىق قاينارى',
+
+'exif-focalplaneresolutionunit-2' => 'ديۋيم',
+
+'exif-sensingmethod-1' => 'انىقتالماعان',
+'exif-sensingmethod-2' => '1-چيپتٴى اۋماقتى تٴۇسسەزگٴىش',
+'exif-sensingmethod-3' => '2-چيپتٴى اۋماقتى تٴۇسسەزگٴىش',
+'exif-sensingmethod-4' => '3-چيپتٴى اۋماقتى تٴۇسسەزگٴىش',
+'exif-sensingmethod-5' => 'كەزەكتٴى اۋماقتى تٴۇسسەزگٴىش',
+'exif-sensingmethod-7' => '3-سىزىقتى تٴۇسسەزگٴىش',
+'exif-sensingmethod-8' => 'كەزەكتٴى سىزىقتى تٴۇسسەزگٴىش',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'تٴىكەلەي تٴۇسٴىرٴىلگەن فوتوسۋرەت',
+
+'exif-customrendered-0' => 'قالىپتى ٴوڭدەتۋ',
+'exif-customrendered-1' => 'قوسىمشا ٴوڭدەتۋ',
+
+'exif-exposuremode-0' => 'ٴوزدٴىك ۇستالىمداۋ',
+'exif-exposuremode-1' => 'قولمەن ۇستالىمداۋ',
+'exif-exposuremode-2' => 'ٴوزدٴىك جارقىلداۋ',
+
+'exif-whitebalance-0' => 'اق تٴۇسٴىنٴىڭ ٴوزدٴىك تەندەستٴىرۋ',
+'exif-whitebalance-1' => 'اق تٴۇسٴىنٴىڭ قولمەن تەندەستٴىرۋ',
+
+'exif-scenecapturetype-0' => 'قالىپتى',
+'exif-scenecapturetype-1' => 'دەرەلەي',
+'exif-scenecapturetype-2' => 'تٴىرەلەي',
+'exif-scenecapturetype-3' => 'تٴۇنگٴى ساحنا',
+
+'exif-gaincontrol-0' => 'جوق',
+'exif-gaincontrol-1' => 'تٴومەن زورايۋ',
+'exif-gaincontrol-2' => 'جوعارى زورايۋ',
+'exif-gaincontrol-3' => 'تٴومەن باياۋلاۋ',
+'exif-gaincontrol-4' => 'جوعارى باياۋلاۋ',
+
+'exif-contrast-0' => 'قالىپتى',
+'exif-contrast-1' => 'ۇيان',
+'exif-contrast-2' => 'تۇرپايى',
+
+'exif-saturation-0' => 'قالىپتى',
+'exif-saturation-1' => 'تٴومەن قانىقتى',
+'exif-saturation-2' => 'جوعارى قانىقتى',
+
+'exif-sharpness-0' => 'قالىپتى',
+'exif-sharpness-1' => 'ۇيان',
+'exif-sharpness-2' => 'تۇرپايى',
+
+'exif-subjectdistancerange-0' => 'بەلگٴىسٴىز',
+'exif-subjectdistancerange-1' => 'تاياۋ تٴۇسٴىرٴىلگەن',
+'exif-subjectdistancerange-2' => 'جاقىن تٴۇسٴىرٴىلگەن',
+'exif-subjectdistancerange-3' => 'الىس تٴۇسٴىرٴىلگەن',
+
+# Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'سولتٴۇستٴىك بويلىعى',
+'exif-gpslatitude-s' => 'وڭتٴۇستٴىك بويلىعى',
+
+# Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'شىعىس ەندٴىگٴى',
+'exif-gpslongitude-w' => 'باتىس ەندٴىگٴى',
+
+'exif-gpsstatus-a' => 'ٴولشەۋ ۇلاسۋدا',
+'exif-gpsstatus-v' => 'ٴولشەۋ ٴوزارا ٴارەكەتتە',
+
+'exif-gpsmeasuremode-2' => '2-باعىتتىق ٴولشەم',
+'exif-gpsmeasuremode-3' => '3-باعىتتىق ٴولشەم',
+
+# Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'km/h',
+'exif-gpsspeed-m' => 'mil/h',
+'exif-gpsspeed-n' => 'ج. تٴۇيٴىن',
+
+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'شىن باعىت',
+'exif-gpsdirection-m' => 'ماگنيتتى باعىت',
+
+# External editor support
+'edit-externally' => 'بۇل فايلدى سىرتقى قۇرال/باعدارلاما ارقىلى ٴوڭدەۋ',
+'edit-externally-help' => 'كٴوبٴىرەك اقپارات ٴۇشٴىن [http://meta.wikimedia.org/wiki/Help:External_editors ورناتۋ نۇسقاۋلارىن] قاراڭىز.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'بارلىعىن',
+'imagelistall' => 'بارلىعى',
+'watchlistall1' => 'بارلىعى',
+'watchlistall2' => 'بارلىق',
+'namespacesall' => 'بارلىعى',
+
+# E-mail address confirmation
+'confirmemail' => 'ە-پوشتا جايىن كۋٴالاندىرۋ',
+'confirmemail_noemail' => '[[{{ns:special}}:Preferences|قاتىسۋشى باپتاۋىڭىزدا]] جارامدى ە-پوشتا جايىن ەنگٴىزبەپسٴىز.',
+'confirmemail_text' => 'بۇل ۋيكيدە ە-پوشتا قاسيەتتەرٴىن پايدالانۋدىڭ الدىنان ە-پوشتا جايىڭىزدى
+كۋٴالاندىرۋ قاجەت. ٴوزٴىڭٴىزدٴىڭ جايىڭىزعا كۋٴالاندىرۋ حاتىن جٴىبەرۋ ٴۇشٴىن تٴومەندەگٴى تٴۇيمەنٴى نۇقىڭىز.
+حاتتىڭ ٴىشٴىندە ارنايى كودى بار سٴىلتەمە كٴىرٴىستٴىرلەدٴى; ە-پوشتا جايىڭىزدىڭ جارامدىعىن كۋٴالاندىرۋ ٴۇشٴىن
+سٴىلتەمەنٴى شولعىشتىڭ مەكەن-جاي جولاعىنا ەنگٴىزٴىپ اشىڭىز.',
+'confirmemail_send' => 'كۋٴالاندىرۋ كودىن جٴىبەرۋ',
+'confirmemail_sent' => 'كۋٴالاندىرۋ ە-پوشتا حاتى جٴىبەرٴىلدٴى.',
+'confirmemail_sendfailed' => 'كۋٴالاندىرۋ حاتى جٴىبەرٴىلمەدٴى. ەنگٴىزٴىلگەن جايدى جارامسىز ٴارٴىتەرٴىنە تەكسەرٴىپ شىعىڭىز.
+
+ە-پوشتا قىزمەتٴى قايتارعانى: $1',
+'confirmemail_invalid' => 'كۋٴالاندىرۋ كودى جارامسىز. كودتىڭ مەرزٴىمٴى بٴىتكەن شىعار.',
+'confirmemail_needlogin' => 'ە-پوشتا جايىڭىزدى كۋٴالاندىرۋ ٴۇشٴىن $1 قاجەت.',
+'confirmemail_success' => 'ە-پوشتا جايىڭىز كۋٴالاندىرىلدى. ەندٴى ۋيكيگە كٴىرٴىپ جۇمىسقا كٴىرٴىسۋگە بولادى',
+'confirmemail_loggedin' => 'ە-پوشتا جايىڭىز كۋٴالاندىرىلدى.',
+'confirmemail_error' => 'كۋٴالاندىرۋىڭىزدى ساقتاعاندا بەلگٴىسٴىز قاتە بولدى.',
+'confirmemail_subject' => '{{SITENAME}} تورابىنان ە-پوشتا جايىڭىزدى كۋٴالاندىرۋ حاتى',
+'confirmemail_body' => "كەيبٴىرەۋ, مىنا $1 IP جايىنان, ٴوزٴىڭٴىز بولۋى مٴۇمكٴىن,
+{{SITENAME}} جوباسىنداعى ە-پوشتا جايىن قولدانىپ «$2» تٴىركەلگٴى جاساپتى.
+
+وسى تٴىركەلگٴى راستان سٴىزدٴىكٴى ەكەنٴىن كۋٴالاندىرۋ ٴۇشٴىن, جٴانە {{SITENAME}} جوباسىنىڭ
+ە-پوشتا قاسيەتتەرٴىن بەلسەندٴىرۋ ٴۇشٴىن, مىنا سٴىلتەمەنٴى شولعىشپەن اشىڭىز:
+
+$3
+
+بۇل سٴىزدٴىكٴى '''ەمەس''' بولسا, سٴىلتەمەگە ەرمەڭٴىز. كۋٴالاندىرۋ كودىنىڭ
+مەرزٴىمٴى $4 كەزٴىندە بٴىتەدٴى.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'دٴال سٴايكەسٴىن سىناپ كٴورٴىڭٴىز',
+'searchfulltext' => 'تولىق مٴاتٴىنٴىمەن ٴىزدەۋ',
+'createarticle' => 'بەتتٴى باستاۋ',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[ۋيكي-ارا كٴىرەگۋ ٴوشٴىرٴىلگەن]',
+'scarytranscludefailed' => '[$1 بەتٴىنە ٴۇلگٴى ٴوڭدەتۋ سٴاتسٴىز بٴىتتٴى; كەشٴىرٴىڭٴىز]',
+'scarytranscludetoolong' => '[URL جايى تىم ۇزىن; كەشٴىرٴىڭٴىز]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+بۇل بەتتٴىڭ اڭىستاۋلارى:<br />
+$1
+</div>',
+'trackbackremove' => '([$1 جويىلدى])',
+'trackbacklink' => 'اڭىستاۋ',
+'trackbackdeleteok' => 'اڭىستاۋ جويۋى سٴاتتٴى ٴوتتٴى.',
+
+# Delete conflict
+'deletedwhileediting' => 'نازار سالىڭىز:سٴىز بۇل بەتتٴىڭ ٴوڭدەۋٴىن باستاعاندا, وسى بەت جويىلدى!',
+'confirmrecreate' => "سٴىز بۇل بەتتٴىڭ ٴوندەۋٴىن باستاعاندا [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|تالقىلاۋى]]) وسى بەتتٴى جويدى, كٴورسەتكەن سەبەبٴى:
+: ''$2''
+وسى بەتتٴى شىنىنان قايتا جاساۋىن راستاڭىز.",
+'recreate' => 'قايتا جاساۋ',
+'tooltip-recreate' => 'بۇل بەتتٴى جويىلۋىنا قاراماي قايتا جاساۋ',
+
+'unit-pixel' => ' px',
+
+# HTML dump
+'redirectingto' => '[[$1]] بەتٴىنە ايداتۋدا…',
+
+# action=purge
+'confirm_purge' => 'قوسالقى قالتاداعى وسى بەتٴىن تازالايمىز با?<br /><br />$1',
+'confirm_purge_button' => 'جارايدى',
+
+'youhavenewmessagesmulti' => '$1 دەگەنگە جاڭا حابارلار تٴۇستٴى',
+
+'searchcontaining' => "مىنا سٴوزٴى بار بەت اراسىنان ٴىزدەۋ: ''$1''.",
+'searchnamed' => "مىنا اتاۋلى بەت اراسىنان ٴىزدەۋ: ''$1''.",
+'articletitles' => "اتاۋلارى مىنادان باستالعان بەتتەر: ''$1''",
+'hideresults' => 'نٴاتيجەلەردٴى جاسىر',
+
+# DISPLAYTITLE
+'displaytitle' => '(بۇل بەتتٴىڭ سٴىلتەمەسٴى: [[$1]])',
+
+'loginlanguagelabel' => 'تٴىل: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; الدىڭعى بەتكە',
+'imgmultipagenext' => 'كەلەسٴى بەتكە &rarr;',
+'imgmultigo' => 'ٴوتۋ!',
+'imgmultigotopre' => 'مىنا بەتكە ٴوتۋ',
+
+# Table pager
+'ascending_abbrev' => 'ٴوسۋ',
+'descending_abbrev' => 'كەمۋ',
+'table_pager_next' => 'كەلەسٴى بەتكە',
+'table_pager_prev' => 'الدىڭعى بەتكە',
+'table_pager_first' => 'العاشقى بەتكە',
+'table_pager_last' => 'سوڭعى بەتكە',
+'table_pager_limit' => 'بەت سايىن $1 دانا كٴورسەت',
+'table_pager_limit_submit' => 'ٴوتۋ',
+'table_pager_empty' => 'ەش نٴاتيجە جوق',
+
+# Auto-summaries
+'autosumm-blank' => 'بەتتٴىڭ بارلىق ماعلۇماتىن الاستاتتى',
+'autosumm-replace' => "بەتتٴى '$1' دەگەنمەن الماستىردى",
+'autoredircomment' => '[[$1]] دەگەنگە ايدادى', # This should be changed to the new naming convention, but existed beforehand
+'autosumm-new' => 'جاڭا بەت ماعلۇماتى: $1',
+);
+
+?>
diff --git a/languages/messages/MessagesKk_kz.php b/languages/messages/MessagesKk_kz.php
new file mode 100644
index 000000000000..2d7f737749fd
--- /dev/null
+++ b/languages/messages/MessagesKk_kz.php
@@ -0,0 +1,2150 @@
+<?php
+/**
+ * Kazakh (Қазақша)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+
+$separatorTransformTable = array(
+ ',' => "\xc2\xa0",
+ '.' => ',',
+);
+
+$extraUserToggles = array(
+ 'nolangconversion'
+);
+
+$fallback8bitEncoding = 'windows-1251';
+
+$linkPrefixExtension = true;
+
+$namespaceNames = array(
+ NS_MEDIA => 'Таспа',
+ NS_SPECIAL => 'Арнайы',
+ # NS_MAIN => '',
+ NS_TALK => 'Талқылау',
+ NS_USER => 'Қатысушы',
+ NS_USER_TALK => 'Қатысушы_талқылауы',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_талқылауы',
+ NS_IMAGE => 'Сурет',
+ NS_IMAGE_TALK => 'Сурет_талқылауы',
+ NS_MEDIAWIKI => 'МедиаУики',
+ NS_MEDIAWIKI_TALK => 'МедиаУики_талқылауы',
+ NS_TEMPLATE => 'Үлгі',
+ NS_TEMPLATE_TALK => 'Үлгі_талқылауы',
+ NS_HELP => 'Анықтама',
+ NS_HELP_TALK => 'Анықтама_талқылауы',
+ NS_CATEGORY => 'Санат',
+ NS_CATEGORY_TALK => 'Санат_талқылауы'
+);
+
+$namespaceAliases = array(
+ # Aliases to kk-tr namespaces
+ 'Taspa' => NS_MEDIA,
+ 'Arnaýı' => NS_SPECIAL,
+ 'Talqılaw' => NS_TALK,
+ 'Qatıswşı' => NS_USER,
+ 'Qatıswşı_talqılawı' => NS_USER_TALK,
+ '$1_talqılawı' => NS_PROJECT_TALK,
+ 'Swret' => NS_IMAGE,
+ 'Swret_talqılawı' => NS_IMAGE_TALK,
+ 'MedïaWïkï' => NS_MEDIAWIKI,
+ 'MedïaWïkï_talqılawı' => NS_MEDIAWIKI_TALK,
+ 'Ülgi' => NS_TEMPLATE,
+ 'Ülgi_talqılawı' => NS_TEMPLATE_TALK,
+ 'Anıqtama' => NS_HELP,
+ 'Anıqtama_talqılawı' => NS_HELP_TALK,
+ 'Sanat' => NS_CATEGORY,
+ 'Sanat_talqılawı' => NS_CATEGORY_TALK,
+ # Aliases to kk-cn namespaces
+ 'تاسپا' => NS_MEDIA,
+ 'ارنايى' => NS_SPECIAL,
+ 'تالقىلاۋ' => NS_TALK,
+ 'قاتىسۋشى' => NS_USER,
+ 'قاتىسۋشى_تالقىلاۋى'=> NS_USER_TALK,
+ '$1_تالقىلاۋى' => NS_PROJECT_TALK,
+ 'سۋرەت' => NS_IMAGE,
+ 'سۋرەت_تالقىلاۋى' => NS_IMAGE_TALK,
+ 'مەدياۋيكي' => NS_MEDIAWIKI,
+ 'مەدياۋيكي_تالقىلاۋى' => NS_MEDIAWIKI_TALK,
+ 'ٴۇلگٴى' => NS_TEMPLATE,
+ 'ٴۇلگٴى_تالقىلاۋى' => NS_TEMPLATE_TALK,
+ 'انىقتاما' => NS_HELP,
+ 'انىقتاما_تالقىلاۋى' => NS_HELP_TALK,
+ 'سانات' => NS_CATEGORY,
+ 'سانات_تالقىلاۋى' => NS_CATEGORY_TALK,
+);
+
+$quickbarSettings = array(
+ 'Ешқандай', 'Солға бекітілген', 'Оңға бекітілген', 'Солға қалқыған', 'Оңға қалқыған'
+);
+
+$skinNames = array(
+ 'standard' => 'Дағдылы',
+ 'nostalgia' => 'Аңсау',
+ 'cologneblue' => 'Көлн зеңгірлігі',
+ 'davinci' => 'Да Винчи',
+ 'mono' => 'Дара',
+ 'monobook' => 'Дара кітап',
+ 'myskin' => 'Өз мәнерім',
+ 'chick' => 'Балапан',
+ 'simple' => 'Кәдімгі'
+);
+
+$defaultDateFormat = 'ymd';
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'xg j, Y',
+ 'mdy both' => 'H:i, xg j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F, Y',
+ 'dmy both' => 'H:i, j F, Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y" ж." xg j',
+ 'ymd both' => 'H:i, Y" ж." xg j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'Сілтемені астынан сыз:',
+'tog-highlightbroken' => 'Жоқталған сілтемелерді <a href="" class="new">былай</a> пішімде (басқаша: былай <a href="" class="internal">?</a> сияқты).',
+'tog-justify' => 'Ежелерді ені бойынша туралау',
+'tog-hideminor' => 'Жуықтағы өзгерістерде шағын түзетуді жасыр',
+'tog-extendwatchlist' => 'Бақылау тізімді ұлғайт (барлық жарамды өзгерістерді көрсет)',
+'tog-usenewrc' => 'Кеңейтілген Жуықтағы өзгерістер (JavaScript)',
+'tog-numberheadings' => 'Бөлім тақырыптарын өздік түрде номірле',
+'tog-showtoolbar' => 'Өңдеу қуралдар жолағын көрсет (JavaScript)',
+'tog-editondblclick' => 'Қос нұқымдап өңдеу (JavaScript)',
+'tog-editsection' => 'Бөлімдерді [өңдеу] сілтемесімен өңдеуін ендір',
+'tog-editsectiononrightclick' => 'Бөлім атауын оң жақ нұқумен<br />өңдеуін ендір (JavaScript)',
+'tog-showtoc' => 'Мазмұнын көрсет (3-тен артық бөлімі барыларға)',
+'tog-rememberpassword' => 'Кіргенімді бұл компьютерде ұмытпа',
+'tog-editwidth' => 'Өңдеу аумағы толық енімен',
+'tog-watchcreations' => 'Мен бастаған беттерді бақылау тізіміме қос',
+'tog-watchdefault' => 'Мен өңдеген беттерді бақылау тізіміме қос',
+'tog-minordefault' => 'Барлық түзетулерді әдепкіден шағын деп белгіле',
+'tog-previewontop' => 'Қарап шығуды өңдеу аумағының үстіне сал',
+'tog-previewonfirst' => 'Бірінші өңдегенде қарап шығу',
+'tog-nocache' => 'Бет қосалқы қалтасын өшір',
+'tog-enotifwatchlistpages' => 'Бақыланған бет өзгергенде маған хат жібер',
+'tog-enotifusertalkpages' => 'Талқылауым өзгергенде маған хат жібер',
+'tog-enotifminoredits' => 'Шағын түзету туралы да маған хат жібер',
+'tog-enotifrevealaddr' => 'Е-пошта жайымды ескерту хатта ашық көрсет',
+'tog-shownumberswatching' => 'Бақылап тұрған қатысушылардың санын көрсет',
+'tog-fancysig' => 'Қам қолтаңба (өздік сілтемесіз;)',
+'tog-externaleditor' => 'Сыртқы өңдеуішті әдепкіден қолдан',
+'tog-externaldiff' => 'Сыртқы айырмағышты әдепкіден қолдан',
+'tog-showjumplinks' => '«Өтіп кету» қатынау сілтемелерін ендір',
+'tog-uselivepreview' => 'Тура қарап шығуды қолдану (JavaScript) (Сынақ түрінде)',
+'tog-autopatrol' => 'Түзетуімді күзетке белгіле',
+'tog-forceeditsummary' => 'Өңдеу сипаттамасы бос қалғанда маған ескерт',
+'tog-watchlisthideown' => 'Түзетуімді бақылау тізімнен жасыр',
+'tog-watchlisthidebots' => 'Бот түзетуін бақылау тізімнен жасыр',
+'tog-nolangconversion' => 'Тіл түрін аудармау',
+
+'underline-always' => 'Әрқашан',
+'underline-never' => 'Ешқашан',
+'underline-default' => 'Шолғыш бойынша',
+
+'skinpreview' => '(Қарап шығу)',
+
+# Dates
+'sunday' => 'Жексенбі',
+'monday' => 'Дүйсенбі',
+'tuesday' => 'Сейсенбі',
+'wednesday' => 'Сәрсенбі',
+'thursday' => 'Бейсенбі',
+'friday' => 'Жұма',
+'saturday' => 'Сенбі',
+'sun' => 'Жек',
+'mon' => 'Дүй',
+'tue' => 'Бей',
+'wed' => 'Сәр',
+'thu' => 'Бей',
+'fri' => 'Жұм',
+'sat' => 'Сен',
+'january' => 'қаңтар',
+'february' => 'ақпан',
+'march' => 'наурыз',
+'april' => 'cәуір',
+'may_long' => 'мамыр',
+'june' => 'маусым',
+'july' => 'шілде',
+'august' => 'тамыз',
+'september' => 'қыркүйек',
+'october' => 'қазан',
+'november' => 'қараша',
+'december' => 'желтоқсан',
+'january-gen' => 'қантардың',
+'february-gen' => 'ақпанның',
+'march-gen' => 'наурыздың',
+'april-gen' => 'сәуірдің',
+'may-gen' => 'мамырдың',
+'june-gen' => 'маусымның',
+'july-gen' => 'шілденің',
+'august-gen' => 'тамыздың',
+'september-gen' => 'қыркүйектің',
+'october-gen' => 'қазанның',
+'november-gen' => 'қарашаның',
+'december-gen' => 'желтоқсанның',
+'jan' => 'қан',
+'feb' => 'ақп',
+'mar' => 'нау',
+'apr' => 'cәу',
+'may' => 'мам',
+'jun' => 'мау',
+'jul' => 'шіл',
+'aug' => 'там',
+'sep' => 'қыр',
+'oct' => 'қаз',
+'nov' => 'қар',
+'dec' => 'жел',
+
+# Bits of text used by many pages
+'categories' => 'Барлық санат тізімі',
+'pagecategories' => '{{PLURAL:$1|Санат|Санаттар}}',
+'category_header' => '«$1» санатындағы беттер',
+'subcategories' => 'Төменгі санаттар',
+'category-media-header' => '«$1» санатындағы таспалар',
+
+'linkprefix' => '/^(.*?)([a-zäçéğıïñöşüýа-яёәіңғүұқөһA-ZÄÇÉĞİÏÑÖŞÜÝА-ЯЁӘІҢҒҮҰҚӨҺʺʹ«„]+)$/sDu',
+'mainpage' => 'Басты бет',
+'mainpagetext' => "<big>'''МедиаУики бағдарламасы сәтті орнатылды.'''</big>",
+'mainpagedocfooter' => 'Уики бағдарламасын пайдалану ақпараты үшін [http://meta.wikimedia.org/wiki/Help:Contents Пайдаланушы нұсқауларымен] танысыңыз.
+
+== Бастау ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Баптау қалаулары тізімі]
+* [http://www.mediawiki.org/wiki/Help:FAQ МедиаУики ЖСЖ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce МедиаУики хат тарату тізімі]',
+
+'portal' => 'Қауым порталы',
+'portal-url' => '{{ns:project}}:Қауым_порталы',
+'about' => 'Біз туралы',
+'aboutsite' => '{{SITENAME}} туралы',
+'aboutpage' => '{{ns:project}}:Біз_туралы',
+'article' => 'Мағлұмат',
+'help' => 'Анықтама',
+'helppage' => '{{ns:help}}:Мазмұны',
+'bugreports' => 'Қате есептемелері',
+'bugreportspage' => '{{ns:project}}:Қате_есептемелері',
+'sitesupport' => 'Демеушілік',
+'sitesupport-url' => '{{ns:project}}:Жәрдем',
+'faq' => 'ЖСЖ',
+'faqpage' => '{{ns:project}}:ЖСЖ',
+'edithelp' => 'Өндеу анықтамасы',
+'newwindow' => '(жаңа терезеде ашылады)',
+'edithelppage' => '{{ns:help}}:Өңдеу',
+'cancel' => 'Болдырмау',
+'qbfind' => 'Табу',
+'qbbrowse' => 'Шолу',
+'qbedit' => 'Өңдеу',
+'qbpageoptions' => 'Осы бет',
+'qbpageinfo' => 'Мәтін аралығы',
+'qbmyoptions' => 'Беттерім',
+'qbspecialpages' => 'Арнайы беттер',
+'moredotdotdot' => 'Көбірек…',
+'mypage' => 'Жеке бетім',
+'mytalk' => 'Талқылауым',
+'anontalk' => 'IP талқылауы',
+'navigation' => 'Бағыттау',
+
+# Metadata in edit box
+'metadata_help' => 'Мета-деректер (түсіндірмелер үшін [[{{ns:project}}:Мета-деректер]] бетін қараңыз):',
+
+'currentevents' => 'Ағымдағы оқиғалар',
+'currentevents-url' => 'Ағымдағы_оқиғалар',
+
+'disclaimers' => 'Жауапкершіліктен бас тарту',
+'disclaimerpage' => '{{ns:project}}:Жауапкершіліктен_бас_тарту',
+'privacy' => 'Жеке құпиясын сақтау',
+'privacypage' => '{{ns:project}}:Жеке_құпиясын_сақтау',
+'errorpagetitle' => 'Қате',
+'returnto' => '$1 дегенге оралу.',
+'tagline' => '{{GRAMMAR:ablative|{{SITENAME}}}}',
+'search' => 'Іздеу',
+'searchbutton' => 'Іздеу',
+'go' => 'Өту',
+'searcharticle' => 'Өту',
+'history' => 'Бет тарихы',
+'history_short' => 'Тарихы',
+'updatedmarker' => 'соңғы кіргеннен бері жаңартылған',
+'info_short' => 'Ақпарат',
+'printableversion' => 'Басып шығаруға',
+'permalink' => 'Тұрақты сілтеме',
+'print' => 'Басып шығару',
+'edit' => 'Өңдеу',
+'editthispage' => 'Бетті өңдеу',
+'delete' => 'Жою',
+'deletethispage' => 'Бетті жою',
+'undelete_short' => '{{PLURAL:$1|Бір|$1}} түзетуді қайтару',
+'protect' => 'Қорғау',
+'protectthispage' => 'Бетті қорғау',
+'unprotect' => 'Қорғамау',
+'unprotectthispage' => 'Бетті қорғамау',
+'newpage' => 'Жаңа бет',
+'talkpage' => 'Бетті талқылау',
+'specialpage' => 'Арнайы бет',
+'personaltools' => 'Жеке құралдар',
+'postcomment' => 'Мәндеме жіберу',
+'articlepage' => 'Мағлұмат бетін қарау',
+'talk' => 'Талқылау',
+'views' => 'Көрініс',
+'toolbox' => 'Құралдар',
+'userpage' => 'Қатысушының бетін қарау',
+'projectpage' => 'Жоба бетін қарау',
+'imagepage' => 'Сурет бетін қарау',
+'mediawikipage' => 'Хабар бетін қарау',
+'templatepage' => 'Үлгі бетін қарау',
+'viewhelppage' => 'Анықтама бетін қарау',
+'categorypage' => 'Санат бетін қарау',
+'viewtalkpage' => 'Талқылау бетін қарау',
+'otherlanguages' => 'Басқа тілдерде',
+'redirectedfrom' => '($1 бетінен айдатылған)',
+'redirectpagesub' => 'Айдату беті',
+'lastmodifiedat' => 'Бұл беттің өзгертілген соңғы кезі: $2, $1.', # $1 date, $2 time
+'viewcount' => 'Бұл бет {{plural:$1|бір|$1}} рет қаралған.',
+'copyright' => 'Мағлұмат $1 құжаты бойынша қатынаулы.',
+'protectedpage' => 'Қорғаулы бет',
+'jumpto' => 'Мынаған өтіп кету:',
+'jumptonavigation' => 'бағыттау',
+'jumptosearch' => 'іздеу',
+
+'badaccess' => 'Рұқсат қатесі',
+'badaccess-group0' => 'Сұранысқан әрекетіңізді жегуіңізге рұқсат етілмейді.',
+'badaccess-group1' => 'Сұранысқан әрекетіңіз $1 тобының қатысушыларына шектеледі.',
+'badaccess-group2' => 'Сұранысқан әрекетіңіз $1 топтары бірінің қатусышыларына шектеледі.',
+'badaccess-groups' => 'Сұранысқан әрекетіңіз $1 топтары бірінің қатусышыларына шектеледі.',
+
+'versionrequired' => 'MediaWiki $1 нұсқасы қажет',
+'versionrequiredtext' => 'Осы бетті қолдану үшін MediaWiki $1 нұсқасы қажет. [[{{ns:special}}:Version]] бетін қараңыз.',
+
+'ok' => 'Жарайды',
+'pagetitle' => '$1 — {{SITENAME}}',
+'retrievedfrom' => '«$1» дегеннен алынған',
+'youhavenewmessages' => 'Сізде $1 бар ($2).',
+'newmessageslink' => 'жаңа хабарлар',
+'newmessagesdifflink' => 'соңғы өзгерісіне',
+'editsection' => 'өңдеу',
+'editold' => 'өңдеу',
+'editsectionhint' => 'Бөлімді өңдеу: $1',
+'toc' => 'Мазмұны',
+'showtoc' => 'көрсет',
+'hidetoc' => 'жасыр',
+'thisisdeleted' => 'Қараймыз ба, не қайтарамыз ба?: $1',
+'viewdeleted' => 'Қараймыз ба?: $1',
+'restorelink' => 'жойылған {{PLURAL:$1|бір|$1}} түзету',
+'feedlinks' => 'Арна:',
+'feed-invalid' => 'Жарамсыз жазылым арна түрі.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Мағлұмат',
+'nstab-user' => 'Жеке беті',
+'nstab-media' => 'Таспа беті',
+'nstab-special' => 'Арнайы',
+'nstab-project' => 'Жоба беті',
+'nstab-image' => 'Файл',
+'nstab-mediawiki' => 'Жүйе хабары',
+'nstab-template' => 'Үлгі',
+'nstab-help' => 'Анықтама',
+'nstab-category' => 'Санат',
+
+# Main script and global functions
+'nosuchaction' => 'Мұндай әрекет жоқ',
+'nosuchactiontext' => 'Осы URL жайымен енгізілген әрекетті
+осы уики жорамалдап білмеді.',
+'nosuchspecialpage' => 'Бұл арнайы бет емес',
+'nospecialpagetext' => 'Сіз сұранысқан арнайы бет жарамсыз. Барлық жарамды арнайы беттер тізімін [[{{ns:special}}:Specialpages]] бетінде таба аласыз.',
+
+# General errors
+'error' => 'Қате',
+'databaseerror' => 'Дерекқордың қатесі',
+'dberrortext' => 'Дерекқорға сұраныс жасалғанда синтаксис қатесі кездесті.
+Бұл бағдарламаның қатесін көрсету мүмкін.
+Дерекқорға соңғы болған сұраныс:
+<blockquote><tt>$1</tt></blockquote>
+мына функциясынан «<tt>$2</tt>».
+MySQL қайтарған қатесі «<tt>$3: $4</tt>».',
+'dberrortextcl' => 'Дерекқорға сұраныс жасалғанда синтаксис қатесі кездесті.
+Дерекқорға соңғы болған сұраныс:
+«$1»
+мына функциясынан: «$2».
+MySQL қайтарған қатесі «$3: $4»',
+'noconnect' => 'Ғафу етіңіз! Бұл уикиде кейбір техникалық қиыншылықтар кездесті, сондықтан дерекқор серверіне қатынасу алмайды. <br />
+$1',
+'nodb' => '$1 дерекқоры талғанбады',
+'cachederror' => 'Төменде сұранған беттің қосалқы қалтадағы көшірмесі, осы бет жаңартылмаған болуы мүмкін.',
+'laggedslavemode' => 'Назар салыңыз: Бетте жуықтағы жаңалаулар болмауы мүмкін.',
+'readonly' => 'Дерекқоры құлыпталған',
+'enterlockreason' => 'Құлыптау себебін енгізіңіз, қай уақытқа дейін
+құлыпталғанын қоса',
+'readonlytext' => 'Ағымда дерекқор жаңа жазба және тағы басқа өзгерістер жасаудан құлыпталынған. Бұл дерекқорды жөндету бағдарламаларын орындау үшін болуы мүмкін, бұны бітіргеннен соң қаліпті іске қайтарылады.
+
+Құлыптаған әкімші бұны былай түсіндіреді: $1',
+'missingarticle' => 'Іздестірілген «$1» атаулы бет мәтіні дерекқорда табылмады.
+
+Бұл дағдыда ескірген айырма сілтемесіне немесе жойылған бет тарихының сілтемесіне
+ергеннен болуы мүмкін.
+
+Егер бұл болжам дұрыс себеп болмаса, бағдарламамыздағы қатеге тап болуыңыз мүмкін.
+Бұл туралы нақты URL жайын көрсетіп әкімшіге есептеме жіберіңіз.',
+'readonly_lag' => 'Жетек дерекқор серверлер бастауышпен қадамланғанда осы дерекқор өздік түрінде құлыпталынған',
+'internalerror' => 'Ішкі қате',
+'filecopyerror' => '«$1» файлы «$2» файлына көшірілмеді.',
+'filerenameerror' => '«$1» файл аты «$2» атына өзгертілмеді.',
+'filedeleteerror' => '«$1» файлы жойылмайды.',
+'filenotfound' => '«$1» файлы табылмады.',
+'unexpected' => 'Күтілмеген мағына: «$1» = «$2».',
+'formerror' => 'Қате: жіберу үлгіті емес',
+'badarticleerror' => 'Осындай әрекет мына бетте атқарылмайды.',
+'cannotdelete' => 'Айтылмыш бет не сурет жойылмайды. (Бұны басқа біреу жойған шығар.)',
+'badtitle' => 'Жарамсыз атау',
+'badtitletext' => 'Сұранысқан бет атауы жарамсыз, бос, тілара сілтемесі не уики-ара атауы мүлтік болған. Атауларда сүемелдемеген бірқатар әріптер болуы мүмкін.',
+'perfdisabled' => 'Ғафу етіңіз! Осы қасиет, дерекқордың жылдамылығына әсер етіп, ешкімге уикиді пайдалануға бермегесін, уақытша өшірілген.',
+'perfdisabledsub' => 'Мында $1 бетінің сақталған көшірмесі:', # obsolete?
+'perfcached' => 'Келесі дерек қосалқы қалтасынан алынған, сондықтан толықтай жаңаланмаған болуы мүмкін.',
+'perfcachedts' => 'Келесі дерек қосалқы қалтасынан алынған, соңғы жаңаланлған кезі: $1.',
+'wrong_wfQuery_params' => 'wfQuery() функциясында жарамсыз баптар<br />
+Функция: $1<br />
+Сұраныс: $2',
+'viewsource' => 'Қайнарын қарау',
+'viewsourcefor' => '$1 қайнары',
+'protectedtext' => 'Бұл бет өңдеу болдырмау үшін құлыпталынған.
+
+Бұл беттің қайнарын қарауыңызға және көшіріп алуңызға болады:',
+'protectedinterface' => 'Бұл бет бағдарламаның тілдесу мәтінін жетістіреді, сондықтан қиянат келтірмеу үшін өзгертуі құлыпталған.',
+'editinginterface' => "'''Назар салыңыз:''' Бағдарламаға тілдесу мәтінін жетістіретін MediaWiki бетін өңдеп жатырсыз. Бұл беттің өзгертуі барлық пайдаланушылар тілдесуіне әсер етеді.",
+'sqlhidden' => '(SQL сұранысы жасырылды)',
+
+# Login and logout pages
+'logouttitle' => 'Қатысушы шығуы',
+'logouttext' => '<strong>Енді жүйеден шықтыңыз.</strong><br />
+Бұл компьютерден әлі де жүйеге кірместен {{SITENAME}} жобасын
+шолуыңыз мүмкін, немесе басқа пайдаланушының жүйеге кіруі мүмкін.
+Кейбір беттерде әлі де жүйеге кіргеніңіздей көрінуі мүмкіндігін
+ескертеміз; бұл шолғыштың қосалқы қалтасын босату арқылы шешіледі.',
+'welcomecreation' => '== Қош келдіңіз, $1! ==
+
+Тіркелгіңіз жасалды. {{SITENAME}} баптауыңызды қалауыңызбен өзгертуді ұмытпаңыз.',
+'loginpagetitle' => 'Қатысушы кіруі',
+'yourname' => 'Қатысушы атыңыз',
+'yourpassword' => 'Құпия сөзіңіз',
+'yourpasswordagain' => 'Құпия сөзді қайталап енгізіңіз',
+'remembermypassword' => 'Менің кіргенімді бұл компьютерде ұмытпа',
+'yourdomainname' => 'Желі үйшігіңіз',
+'externaldberror' => 'Осында сыртқы теңдестіру дерекқорында қате болды, немесе сыртқы тіркелгіңізді жаңалауға рұқсат жоқ.',
+'loginproblem' => '<b>Кіруіңіз кезінде осында қиындыққа тап болдық.</b><br />Тағы да қайталап қараңыз.',
+'alreadyloggedin' => '<strong>$1 деген қатысушы, кіріпсіз түге!<strong><br />',
+'login' => 'Кіру',
+'loginprompt' => '{{SITENAME}} торабына кіру үшін «cookies» қасиетін ендіруіңіз қажет.',
+'userlogin' => 'Кіру / Тіркелгі жасау',
+'logout' => 'Шығу',
+'userlogout' => 'Шығу',
+'notloggedin' => 'Кірмегенсіз',
+'nologin' => 'Тіркелгіңіз жоқ па? $1.',
+'nologinlink' => 'Жасаңыз',
+'createaccount' => 'Тіркелгі жаса',
+'gotaccount' => 'Тіркелгіңіз бар ма? $1.',
+'gotaccountlink' => 'Кіріңіз',
+'createaccountmail' => 'е-поштамен',
+'badretype' => 'Енгізген құпия сөздеріңіз бір біріне сәйкес емес.',
+'userexists' => 'Енгізген қатысушы атыңызды біреу пайдаланып жатыр. Басқа атау тандаңыз.',
+'youremail' => 'Е-пошта жайыңыз *:',
+'username' => 'Қатысушы атыңыз:',
+'uid' => 'Қатысушы теңдестіруіңіз:',
+'yourrealname' => 'Шын атыңыз *:',
+'yourlanguage' => 'Тіліңіз:',
+'yourvariant' => 'Түрі',
+'yournick' => 'Лақап атыңыз:',
+'badsig' => 'Қам қолтаңбаңыз жарамсыз; HTML белгішелерін тексеріңіз.',
+'email' => 'Е-поштаңыз',
+'prefs-help-email-enotif' => 'Егер соны баптасаңыз, осы е-пошта жайы сізге ескерту хат жіберуге қолданылады.',
+'prefs-help-realname' => '* Шын атыңыз (міндетті емес): енгізсеңіз, шығармаңыздың ауторлығын белгілеуі үшін қолданылады.',
+'loginerror' => 'Кіру қатесі',
+'prefs-help-email' => '* Е-поштаңыз (міндетті емес): «Қатысушы» немесе «қатысушы талқылау» бетіңіздер арқылы басқаларға байланысу мүмкіндік береді. Өзіңіздің кім екеніңізді білдіртпейді.',
+'nocookiesnew' => 'Қатысушы тіркелгісі жасалды, тек әлі кірмегенсіз. {{SITENAME}} жобасына қатысушы кіру үшін «cookies» қасиеті қажет. Шолғышыңызда «cookies» қасиеті өшірілген. Соны ендіріңіз де жаңа қатысушы атыңызды және құпия сөзіңізді енгізіп кіріңіз.',
+'nocookieslogin' => 'Қатысушы кіру үшін {{SITENAME}} жобасы «cookies» қасиетін қолданады. Шолғышыңызда «cookies» қасиеті өшірілген. Соны ендіріңіз де қайталап кіріңіз.',
+'noname' => 'Қатысушы атын дұрыс енгізбедіңіз.',
+'loginsuccesstitle' => 'Кіруіңіз сәтті өтті',
+'loginsuccess' => "'''Сіз енді {{SITENAME}} жобасына «$1» ретінде кіріп отырсыз.'''",
+'nosuchuser' => 'Мында «$1» атаулы қатысушы жоқ. Емлеңізді тексеріңіз, немесе жаңа тіркелгі жасаңыз.',
+'nosuchusershort' => 'Мында «$1» деген қатысушы атауы жоқ. Емлеңізді тексеріңіз.',
+'nouserspecified' => 'Қатысушы атын енгізіуіңіз қажет.',
+'wrongpassword' => 'Енгізген құпия сөз жарамсыз. Қайталап көріңіз.',
+'wrongpasswordempty' => 'Құпия сөз босты бопты. Қайталап көріңіз.',
+'mailmypassword' => 'Құпия сөзімді хатпен жібер',
+'passwordremindertitle' => 'Құпия сөз туралы {{SITENAME}} жобасының ескертуі',
+'passwordremindertext' => 'Кейбіреу (IP жайы: $1, бәлкім, өзіңіз боларсыз)
+{{SITENAME}} үшін бізден жаңа құпия сөзін жіберуін сұранысқан ($4).
+«$2» қатысушының құпия сөзі «$3» болды енді.
+Қазір кіруіңіз және құпия сөзіңізді ауыструыңыз қажет.
+
+Егер басқа біреу бұл сұранысты жасаса, немесе құпия сөзіңізді ұмытсаңыз да,
+және бұны өзгерткіңіз келмесе де, осы хабарламаға аңғармауыңызға да болады,
+ескі құпия сөзіңізді әріғарай қолданып.',
+'noemail' => 'Мында «$1» қатысушының е-поштасы жоқ.',
+'passwordsent' => 'Жаңа құпия сөз «$1» үшін
+тіркелген е-пошта жайына жіберілді.
+Қабылдағаннан кейін кіргенде соны енгізіңіз.',
+'blocked-mailpassword' => 'IP жайыңыздан өңдеу бұғатталған, сондықтан
+қиянатшылықтан сақтану үшін құпия сөз жіберу қызметінің әрекеті рұқсат етілмейді.',
+'eauthentsent' => 'Куәландыру хаты аталған е-пошта жайына жіберілді.
+Басқа е-пошта хатын жіберудің алдынан, тіркелгі шынынан сіздікі екенін
+куәландыру үшін хаттағы нұсқауларға еріңіз.',
+'throttled-mailpassword' => 'Соңғы $1 сағатта құпия сөз ескерту хаты жіберілді түге.
+Қиянатшылыққа кедергі болу үшін, $1 сағат сайын тек бір ғана құпия сөз ескерту
+хаты жіберіледі.',
+'mailerror' => 'Хат жіберу қатесі: $1',
+'acct_creation_throttle_hit' => 'Ғафу етіңіз, сіз $1 тіркелгі жасапсыз түге. Онан артық істей алмайсыз.',
+'emailauthenticated' => 'Е-пошта жайыңыз куәландырылған кезі: $1.',
+'emailnotauthenticated' => 'Е-пошта жайыңыз әлі куәландырған жоқ.
+Төмендегі қасиетттер үшін ешқандай хат жіберілмейді.',
+'noemailprefs' => 'Осы қасиеттер істеуі үшін е-пошта жайыңызды енгізіңіз.',
+'emailconfirmlink' => 'Е-пошта жайыңызды куәландырыңыз',
+'invalidemailaddress' => 'Осы е-пошта жайда жарамсыз пішім болған, қабыл етілмейді.
+Дұрыс пішімделген жайды енгізіңіз, не аумақты бос қалдырыңыз.',
+'accountcreated' => 'Тіркелгі жасалды',
+'accountcreatedtext' => '$1 үшін қатысушы тіркелгісі жасалды.',
+
+# Edit page toolbar
+'bold_sample' => 'Жуан мәтін',
+'bold_tip' => 'Жуан мәтін',
+'italic_sample' => 'Қиғаш мәтін',
+'italic_tip' => 'Қиғаш мәтін',
+'link_sample' => 'Сілтеме атауы',
+'link_tip' => 'Ішкі сілтеме',
+'extlink_sample' => 'http://www.example.com сілтеме атауы',
+'extlink_tip' => 'Сыртқы сілтеме (алдынан http:// енгізуін ұмытпаңыз)',
+'headline_sample' => 'Тақырып мәтіні',
+'headline_tip' => '1-ші деңгейлі тақырып',
+'math_sample' => 'Формуланы мында енгізіңіз',
+'math_tip' => 'Математика формуласы (LaTeX)',
+'nowiki_sample' => 'Пішімделмейтін мәтінді осында енгізіңіз',
+'nowiki_tip' => 'Уики пішімін елемеу',
+'image_sample' => 'Example.jpg',
+'image_tip' => 'Кіріктірілген сурет',
+'media_sample' => 'Example.ogg',
+'media_tip' => 'Таспа файлының сілтемесі',
+'sig_tip' => 'Қолтаңбаңыз және уақыт белгісі',
+'hr_tip' => 'Дерелей сызық (үнемді қолданыңыз)',
+
+# Edit pages
+'summary' => 'Сипаттамасы',
+'subject' => 'Тақырыбы/басы',
+'minoredit' => 'Бұл шағын түзету',
+'watchthis' => 'Бетті бақылау',
+'savearticle' => 'Бетті сақта!',
+'preview' => 'Қарап шығу',
+'showpreview' => 'Қарап шығу',
+'showlivepreview' => 'Тура қарап шығу',
+'showdiff' => 'Өзгерістерді көрсет',
+'anoneditwarning' => "'''Назар салыңыз:''' Сіз жүйеге кірмегенсіз. IP жайыңыз бұл беттің өңдеу тарихында жазылып алынады.",
+'missingsummary' => "'''Ескерту:''' Түзету сипаттамасын енгізбепсіз. «Сақтау» түймесін тағы бассаңыз, түзетуіңіз мәндемесіз сақталады.",
+'missingcommenttext' => 'Төменде мәндемеңізді енгізіңіз.',
+'missingcommentheader' => "'''Ескерту:''' Бұл мәндемеге тақырып/басжол жетістірмепсіз. Егер тағы да Сақтау түймесін нұқысаңыз, түзетуіңіз солсыз сақталады.",
+'summary-preview' => 'Сипаттамасын қарап шығу',
+'subject-preview' => 'Тақырыбын/басын қарап шығу',
+'blockedtitle' => 'Пайдаланушы бұғатталған',
+'blockedtext' => "<big>'''Қатысушы атыңыз не IP жайыңыз бұғатталған.'''</big>
+
+бұғаттауды $1 істеген. Белгіленген себебі: ''$2''.
+
+Осы бұғаттауды талқылау үшін $1 дегенмен не басқа [[{{ns:project}}:Әкімшілер|әкімшімен]] қатынасуыңызға болады.
+[[{{ns:special:Preferences|Тіркелгі баптауларын]] қолданып жарамды е-пошта жайын енгізгенше дейін
+«Қатысушыға хат жазу» қасиетін пайдаланылмайсыз. Ағымдық IP жайыңыз $3 болған. Бұны әрбір сұранысыңызға қосыңыз.",
+'blockedoriginalsource' => "Төменде '''$1''' дегеннің қайнары көрсетіледі:",
+'blockededitsource' => "Төменде '''$1''' дегенге жасалған '''түзетуңіздің''' мәтіні көрсетіледі:",
+'whitelistedittitle' => 'Өңдеу үшін кіруіңіз жөн.',
+'whitelistedittext' => 'Беттерді өңдеу үшін $1 жөн.',
+'whitelistreadtitle' => 'Оқу үшін кіруіңіз жөн',
+'whitelistreadtext' => 'Беттерді оқу үшін [[{{ns:special}}:Userlogin|кіруіңіз]] жөн.',
+'whitelistacctitle' => 'Сізге тіркелгі жасауға рұқсат берілмеген',
+'whitelistacctext' => 'Осы уикиде басқаларға тіркелгі жасау үшін [[{{ns:Special}}:Userlogin|кіруіңіз]] қажет және жанасымды рұқсаттарын билеу қажет.',
+'confirmedittitle' => 'Е-пошта жайын куәландыру хатын қайта өңдеу қажет',
+'confirmedittext' => 'Беттерді өңдеу үшін алдын ала Е-пошта жайыңызды куәландыруыңыз қажет. Жайыңызды [[{{ns:Special}}:Preferences|қатысушы баптауы]] арқылы енгізіңіз және тексерткіңіз.',
+'loginreqtitle' => 'Кіруіңіз қажет',
+'loginreqlink' => 'кіру',
+'loginreqpagetext' => 'Басқа беттерді көру үшін сіз $1 болуыңыз қажет.',
+'accmailtitle' => 'Құпия сөз жіберілді.',
+'accmailtext' => '$2 жайына «$1» құпия сөзі жіберілді.',
+'newarticle' => '(Жаңа)',
+'newarticletext' => 'Сілтемеге еріп әлі басталмаған бетке
+келіпсіз. Бетті бастау үшін, төмендегі аумақта мәтініңізді
+теріңіз (көбірек ақпарат үшін [[{{ns:help}}:Мазмұны|көмек бетін]]
+қараңыз).Егер жаңылғаннан осында келген болсаңыз, шолғышыңыз
+«Артқа» деген түймесін нұқыңыз.',
+'anontalkpagetext' => "----''Бұл тіркелгісіз (немесе тіркелгісін қолданбаған) пайдаланушының талқылау беті. Осы пайдаланушыны біз тек сандық IP жайымен теңдестіреміз. Осындай IP жайлар бірнеше пайдаланушыға ортақ болуы мүмкін. Егер сіз тіркелгісіз пайдаланушы болсаңыз және сізге қатыссыз мәндемелер жіберілгенін сезсеңіз, басқа тіркелгісіз пайдаланушылармен араластырмауы үшін [[{{ns:special}}:Userlogin|тіркелгі жасаңыз не кіріңіз]].''",
+'noarticletext' => 'Бұл бетте ағымда еш мәтін жоқ, басқа беттерден осы бет атауын [[{{ns:special}}:Search/{{PAGENAME}}|іздеп көруіңізге]] немесе осы бетті [{{fullurl:{{FULLPAGENAME}}|action=edit}} түзетуіңізге] болады.',
+'clearyourcache' => "'''Аңғартпа:''' Сақтағаннан кейін өзгерістерді көру үшін шолғыш қосалқы қалтасын босату керегі мүмкін. '''Mozilla / Safari:''' ''Shift'' пернесін басып тұрып ''Reload'' (''Қайта жүктеу'') түймесін нұқыңыз (не ''Ctrl-Shift-R'' басыңыз); ''IE:'' ''Ctrl-F5'' басыңыз; '''Opera / Konqueror''' ''F5'' пернесін басыңыз.",
+'usercssjsyoucanpreview' => '<strong>Басалқы:</strong> Сақтау алдында жаңа CSS/JS файлын тексеру үшін «Қарап шығу» түймесін қолданыңыз.',
+'usercsspreview' => "'''Мынау CSS мәтінін тек қарап шығу екенін ұмытпаңыз, ол әлі сақталған жоқ!'''",
+'userjspreview' => "'''Мынау JavaScript қатысушы бағдарламасын тексеру/қарап шығу екенін ұмытпаңыз, ол әлі сақталған жоқ!'''",
+'userinvalidcssjstitle' => "'''Назар салыңыз:''' Мында «$1» атаулы безендіру мәнері жоқ. Пайдаланушының .css және .js файл атауы кіші әріпппен жазылатынын ұмытпаңыз, мысалға {{ns:user}}:Foo/monobook.css дегенді {{ns:user}}:Foo/Monobook.css дегенмен салыстырыңыз.",
+'updated' => '(Жаңартылған)',
+'note' => '<strong>Аңғартпа:</strong>',
+'previewnote' => '<strong>Мынау тек қарап шығу екенін ұмытпаңыз; түзетулер әлі сақталған жоқ!</strong>',
+'session_fail_preview' => '<strong>Ғафу етіңіз! Сессия деректері ысырап қалғандықтан өңдеуіңізді жөндей алмаймыз.
+Мәтініңізді сақтап қайталап көріңіз. Егер әлі іс өтпейтін болса, шығып және кері кіріп көріңіз.</strong>',
+'previewconflict' => 'Бұл қарап шығу жоғарыдағы өңдеу аумағындағы мәтінге сақтаған кезіндегі дей ықпал етеді.',
+'session_fail_preview_html' => "<strong>Ғафу етіңіз! Сессия деректері ысырап қалғандықтан өңдеуіңізді жөндей алмаймыз.</strong>
+
+''Осы уикиде қам HTML ендірілген, JavaScript шабуылдардан қорғану үшін алдын ала қарап шығу жасырылған.''
+
+<strong>Егер бұл өңдеу адал талап болса, қайтарып көріңіз. Егер әлі де істемесе, шығып, сосын кері кіріп көріңіз.</strong>",
+'importing' => 'Сырттан алуда: $1',
+'editing' => 'Өңдеуде: $1',
+'editinguser' => 'Қатысушыны өңдеуде: <b>$1</b>',
+'editingsection' => 'Өңдеуде: $1 (бөлімі)',
+'editingcomment' => 'Өңдеуде: $1 (мәндемесі)',
+'editconflict' => 'Өңдеу егесі: $1',
+'explainconflict' => 'Осы бетті сіз өңдей бастағанда басқа кейбіреу бетті өзгерткен.
+Жоғарғы аумақта беттің ағымдық мәтіні бар.
+Төменгі аумақта сіз өзгерткен мәтіні көрсетіледі.
+Өзгертуіңізді ағымдық мәтінге үстеуіңіз жөн.
+"Бетті сақта!" түймесіне басқанда
+<b>тек</b> жоғарғы аумақтағы мәтін сақталады.<br />',
+'yourtext' => 'Мәтініңіз',
+'storedversion' => 'Сақталған нұсқасы',
+'nonunicodebrowser' => '<strong>АҢҒАРТПА: Шолғышыңыз Unicode белгілеуіне үйлесімді емес, сондықтан латын емес әріптері бар беттерді өңдеу зіл болу мүмкін. Жұмыс істеуге ықтималдық беру үшін, <strong>төменгі өңдеу аумағында ASCII емес әріптер оналтылық санымен көрсетіледі</strong>.',
+'editingold' => '<strong>АҢҒАРТПА: Осы беттің ертерек нұсқасын
+өңдеп жатырсыз.
+Бұны сақтасаңыз, осы нусқадан соңғы барлық түзетулер жойылады.</strong>',
+'yourdiff' => 'Айырмалар',
+'copyrightwarning' => '{{SITENAME}} жобасына қосылған бүкіл үлес $2 (көбірек ақпарат үшін: $1) құжатына сай жіберілген болып саналады. Егер жазуыңыздың еркін көшіріліп түзетілуін қаламасаңыз, мында ұсынбауыңыз жөн.<br />
+Тағы, қосқан үлесіңіз - өзіңіздің жазғанығыз, не ашық ақпарат көздерінен алынған мағлұмат болғанын уәде етесіз.<br />
+<strong>АВТОРЛЫҚ ҚҰҚЫҚПЕН ҚОРҒАУЛЫ АҚПАРАТТЫ РҰҚСАТСЫЗ ҚОСПАҢЫЗ!</strong>',
+'copyrightwarning2' => 'Есте тұрсын: барлық {{SITENAME}} жобасына берілген үлестер басқа улес берушілермен түзетуге, өзгертуге, не аластануға мүмкін. Алғыссыз түзетуге енжарлан болсаңыз, онда шығармаңызды мында жарияламаңыз.<br />
+Тағы, осыны өзіңіз жазғаныңызды, не барша қазынасынан, немесе сондай-ақ ақысыз ашық қайнарынан көшіргеніңізді
+дәл осындай бізге міндеттеме бересіз (көбірек ақпарат үшін $1 қужатын қараңыз).<br />
+<strong>АУТОРЛЫҚ ҚҰҚЫҚПЕН ҚОРҒАУЛЫ АҚПАРАТТЫ РҰҚСАТСЫЗ ҚОСПАҢЫЗ!</strong>',
+'longpagewarning' => '<strong>НАЗАР САЛЫҢЫЗ: Бұл беттің мөлшері — $1 килобайт; кейбір
+шолғыштарда бет мөлшері 32 кБ жетсе не оны асса өңдеу күрделі болуы мүмкін.
+Бетті бірнеше кішкін бөлімдерге бөліп көріңіз.</strong>',
+'longpageerror' => '<strong>ҚАТЕ: Жіберетін мәтініңіздін мөлшері — $1 кБ, ең көбі $2 кБ
+рұқсат етілген мөлшерінен асқан. Бұл сақтай алынбайды.</strong>',
+'readonlywarning' => '<strong>НАЗАР САЛЫҢЫЗ: Дерекқор жөндету үшін құлыпталған,
+сондықтан дәл қазір түзетуіңізді сақтай алмайсыз. Сосын қолдануға үшін мәтәніңізді көшіріп,
+өз компүтеріңізде файлға сақтаңыз.</strong>',
+'protectedpagewarning' => '<strong>НАЗАР САЛЫҢЫЗ: Бұл бет қорғалған. Тек әкімші рұқсаты бар қатысушылар өңдеу жасай алады.</strong>',
+'semiprotectedpagewarning' => "'''Аңғартпа:''' Бет [[{{ns:project}}:Жартылай қорғау саясаты|қорғалған]], сондықтан осыны тек рұқсаты бар қатысушылар өңдей алады.",
+'templatesused' => 'Бұл бетте қолданылған үлгілер:',
+'templatesusedpreview' => 'Бұны қарап шығуға қолданылған үлгілер:',
+'templatesusedsection' => 'Бұл бөлімде қолданылған үлгілер:',
+'edittools' => '<!-- Мындағы мағлұмат өңдеу және қотару үлгіттріңің астында көрсетіледі. -->',
+'nocreatetitle' => 'Бетті бастау шектелген',
+'nocreatetext' => 'Бұл торапта жаңа бет бастауы шектелген.
+Кері қайтып бар бетті өңдеуіңізге болады, немесе [[{{ns:special}}:Userlogin|кіруіңізге не тіркелгі жасауға]] болады.',
+'cantcreateaccounttitle' => 'Тіркелгі жасалмады',
+'cantcreateaccounttext' => 'Осы IP жайдан (<b>$1</b>) тіркелгі жасауы бұғатталған.
+Бәлкім себебі, оқу орныңыздан, немесе Интернет жеткізушіден
+үзбей бұзақылық болғаны.',
+
+# History pages
+'revhistory' => 'Нұсқалар тарихы',
+'viewpagelogs' => 'Осы бетке қатысты журналдарды қарау',
+'nohistory' => 'Осы беттінің нұсқалар тарихы жоқ.',
+'revnotfound' => 'Нұсқа табылмады',
+'revnotfoundtext' => 'Осы сұранысқан беттің ескі нұсқасы табылған жоқ.
+Осы бетті ашуға пайдаланған URL жайын қайта тексеріп шығыңыз.',
+'loadhist' => 'Бет тарихын жүктеуі',
+'currentrev' => 'Ағымдық нұсқасы',
+'revisionasof' => '$1 кезіндегі нұсқасы',
+'revision-info' => '$1 кезіндегі $2 жасаған нұсқасы',
+'previousrevision' => '← Ескілеу нұсқасы',
+'nextrevision' => 'Жаңалау нұсқасы →',
+'currentrevisionlink' => 'Ағымдық нұсқасы',
+'cur' => 'ағым.',
+'next' => 'кел.',
+'last' => 'соң.',
+'orig' => 'түп.',
+'histlegend' => 'Айырмасын көру: салыстырамын деген нұсқаларды таңдап, не <Enter> пернесін, не төмендегі түймені басыңыз.<br />
+Шартты белгілер: (ағым.) = ағымдық нұсқамен айырмасы,
+(соң.) = алдыңғы нұсқамен айырмасы, ш = шағын түзету',
+'deletedrev' => '[жойылған]',
+'histfirst' => 'Ең алғашқысына',
+'histlast' => 'Ең соңғысына',
+'rev-deleted-comment' => '(мәндеме аластатылды)',
+'rev-deleted-user' => '(қатысушы аты аластатылды)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Осы беттің нұсқасы жария мұрағаттарынан аластатылған.
+Бұл жайтқа [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} жою журналында] егжей-тегжей мәліметтер болуы мүмкін.
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Осы беттің нұсқасы жария мұрағаттарынан аластатылған.
+Соны осы тораптың әкімшісі боп көруіңіз мүмкін;
+бұл жайтқа [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} жою журналында] егжей-тегжей мәлметтер болуы мүмкін.
+</div>',
+'rev-delundel' => 'көрсет/жасыр',
+
+'history-feed-title' => 'Нұсқалар тарихы',
+'history-feed-description' => 'Бұл беттің уикидегі нұсқалар тарихы',
+'history-feed-item-nocomment' => '$1 деген $2 кезінде', # user at time
+'history-feed-empty' => 'Сұранған бет жоқ.
+Бұл бет уикиден жойылған, немесе қайта аталған.
+Сәйкесі бар жаңа беттерді [[{{ns:special}}:Search|уикиден іздеп]] қараңыз.',
+
+# Revision deletion
+'revisiondelete' => 'Нұсқаларды жою/қайтару',
+'revdelete-nooldid-title' => 'Нысана нұсқасы жоқ',
+'revdelete-nooldid-text' => 'Осы әрекетті орындау үшін ақырғы нұсқасын
+не нұсқаларын енгізбепсіз.',
+'revdelete-selected' => '[[:$1]] дегеннің талғанылған нұсқасы:',
+'revdelete-text' => 'Жойылған нұсқаларды әлі де бет тарихында көруге болады,
+бірақ оның мәтін мағлұматы баршаға қатыналмайды.
+
+Осы уикидің басқа әкімшілері жасырын мағлұматқа қатынай алады,
+және торап операторлары қосымша шектеу ендіргенше дейін,
+осы тілдесу арқылы жойылғанды кері қайтара алады.',
+'revdelete-legend' => 'Нұсқанының шектеулері:',
+'revdelete-hide-text' => 'Нұсқа мәтінін жасыр',
+'revdelete-hide-comment' => 'Түзету мәндемесін жасыр',
+'revdelete-hide-user' => 'Өңдеуші атын (IP жайын) жасыр',
+'revdelete-hide-restricted' => 'Осы шектеулерді баршаға сияқты әкімшілерге де қолдану',
+'revdelete-log' => 'Журнал мәндемесі:',
+'revdelete-submit' => 'Талғанған нұсқаға қолдану',
+'revdelete-logentry' => '[[$1]] дегенге нұсқа көрінісін өзгертті',
+
+# Diffs
+'difference' => '(Нұсқалар арасындағы айырмашылық)',
+'loadingrev' => 'айырма үшін нұсқа жүктеу',
+'lineno' => 'Жол $1:',
+'editcurrent' => 'Осы беттің ағымдық нұсқасын өңдеу',
+'selectnewerversionfordiff' => 'Салыстыру үшін жаңалау нұсқасын талғаңыз',
+'selectolderversionfordiff' => 'Салыстыру үшін ескілеу нұсқасын талғаңыз',
+'compareselectedversions' => 'Таңдаған нұсқаларды салыстыру',
+
+# Search results
+'searchresults' => 'Іздестіру нәтижелері',
+'searchresulttext' => 'Осы {{SITENAME}} жобасында іздестіру туралы көбірек ақпарат үшін, [[{{ns:project}}:Іздеу|{{SITENAME}} іздеу нұсқауларын]] қараңыз.',
+'searchsubtitle' => "Іздестіру сұранысыңыз: '''[[:$1]]'''",
+'searchsubtitleinvalid' => "Іздестіру сұранысыңыз: '''$1'''",
+'badquery' => 'Іздестіру сұраныс жарамсыз пішімделген',
+'badquerytext' => 'Ғафу етіңіз, сұранысыңызды орындай алмадық.
+Бұл үш әріптен кем сөзді іздестіруге талаптанғаныңыздан
+болуға мүмкін, ол әлі де сүйемелденбеген.
+Тағы да бұл сөйлемді дұрыс енгізбегендіктен де болуға мүмкін,
+мысалы, «балық және және қабыршақ».
+Басқа сұраныс жасап көріңіз',
+'matchtotals' => '«$1» іздестіру сұранысы $2 беттің атауына
+және $3 беттің мәтініне сәйкес.',
+'noexactmatch' => "'''Осында «$1» атаулы бет жоқ.''' Бұл бетті өзіңіз '''[[:$1|бастай аласыз]].'''",
+'titlematches' => 'Бет атауы сәйкесі',
+'notitlematches' => 'Еш бет атауы сәйкес емес',
+'textmatches' => 'Бет мәтінің сәйкесі',
+'notextmatches' => 'Еш бет мәтіні сәйкес емес',
+'prevn' => 'алдыңғы $1',
+'nextn' => 'келесі $1',
+'viewprevnext' => 'Көрсетілуі: ($1) ($2) ($3) жазба.',
+'showingresults' => 'Төменде нөмір <b>$2</b> дегеннен бастап <b>$1</b> нәтижеге дейін көрсетілген.',
+'showingresultsnum' => 'Төменде нөмір <b>$2</b> дегеннен бастап <b>$3</b> нәтиже көрсетілген.',
+'nonefound' => "'''Аңғартпа''': Табу сәтсіз бітуі жиі «болған» және «деген» сияқты
+тізімделмейтін жалпы сөздермен іздестіруден болуы мүмкін,
+немесе бірден артық іздестіру шарт сөздерін егізгеннен (нәтижелерде тек
+барлық шарт сөздер кедессе көрсетіледі) болуы мүмкін.",
+'powersearch' => 'Іздеу',
+'powersearchtext' => 'Мына есім аяларда іздеу:<br />$1<br />$2 Айдатуларды тізімдеу<br />Іздестіру сұранысы: $3 $9',
+'searchdisabled' => '{{SITENAME}} жобасында ішкі іздеуі өшірілген. Әзірше Google немесе Yahoo! арқылы іздеуге болады. Аңғартпа: {{SITENAME}} мағлұмат тізімідеулері оларда ескірген болуға мүмкін.',
+'blanknamespace' => '(Негізгі)',
+
+# Preferences page
+'preferences' => 'Баптаулар',
+'mypreferences' => 'Баптауым',
+'prefsnologin' => 'Кірмегенсіз',
+'prefsnologintext' => 'Баптауларды қалау үшін алдын ала [[{{ns:special}}:Userlogin|кіруіңіз]] қажет.',
+'prefsreset' => 'Баптаулар арқаудан қайта орнатылды.',
+'qbsettings' => 'Мәзір аймағы',
+'changepassword' => 'Құпия сөз өзгерту',
+'skin' => 'Безендіру',
+'math' => 'Математика',
+'dateformat' => 'Күн-ай пішімі',
+'datedefault' => 'Еш қалаусыз',
+'datetime' => 'Уақыт',
+'math_failure' => 'Өңдету сәтсіз бітті',
+'math_unknown_error' => 'белгісіз қате',
+'math_unknown_function' => 'белгісіз функция',
+'math_lexing_error' => 'лексика қатесі',
+'math_syntax_error' => 'синтаксис қатесі',
+'math_image_error' => 'PNG аударысы сәтсіз бітті; latex, dvips, gs және convert бағдарламаларының мүлтіксіз орнатуын тексеріңіз',
+'math_bad_tmpdir' => 'Математиканың уақытша қалтасына жазылмады, не қалта жасалмады',
+'math_bad_output' => 'Математиканың беріс қалтасына жазылмады, не қалта жасалмады',
+'math_notexvc' => 'texvc бағдарламасы жоғалтылған; баптау үшін math/README құжатын қараңыз.',
+'prefs-personal' => 'Жеке деректері',
+'prefs-rc' => 'Жуықтағы өзгерістер',
+'prefs-watchlist' => 'Бақылау',
+'prefs-watchlist-days' => 'Бақылау тізімінде көрсетерін күн саны:',
+'prefs-watchlist-edits' => 'Кеңейтілген бақылау тізімі түзету көрсетерін саны:',
+'prefs-misc' => 'Қосымша',
+'saveprefs' => 'Сақта',
+'resetprefs' => 'Таста',
+'oldpassword' => 'Ағымдық құпия сөз:',
+'newpassword' => 'Жаңа құпия сөз:',
+'retypenew' => 'Жаңа құпия сөзді қайталаңыз:',
+'textboxsize' => 'Өңдеу',
+'rows' => 'Жолдар:',
+'columns' => 'Бағандар:',
+'searchresultshead' => 'Іздеу',
+'resultsperpage' => 'Бет сайын нәтиже саны:',
+'contextlines' => 'Нәтиже сайын жол саны:',
+'contextchars' => 'Жол сайын әріп саны:',
+'stubthreshold' => 'Бітеме көрстетуін анықтау табалдырығы:',
+'recentchangescount' => 'Жуықтағы өзгерістердегі атаулар:',
+'savedprefs' => 'Баптауларыңыз сақталды.',
+'timezonelegend' => 'Уақыт белдеуі',
+'timezonetext' => 'Жергілікті уақытыңызбен сервер уақытының (UTC) арасындағы сағат саны.',
+'localtime' => 'Жергілікті уақыт',
+'timezoneoffset' => 'Ығыстыру¹',
+'servertime' => 'Сервер уақыты',
+'guesstimezone' => 'Шолғыштан алып толтыру',
+'allowemail' => 'Басқадан хат қабылдауын ендіру',
+'defaultns' => 'Мына есім аяларда әдепкіден іздеу:',
+'default' => 'әдепкі',
+'files' => 'Файлдар',
+
+# User rights
+'userrights-lookup-user' => 'Қатысушы топтарын меңгеру',
+'userrights-user-editname' => 'Қатысушы атын енгізіңіз:',
+'editusergroup' => 'Қатысушы топтарын өңдеу',
+'userrights-editusergroup' => 'Қатысушы топтарын өңдеу',
+'saveusergroups' => 'Қатысушы топтарын сақтау',
+'userrights-groupsmember' => 'Мүшелігі:',
+'userrights-groupsavailable' => 'Қатынаулы топтар:',
+'userrights-groupshelp' => 'Қатысушыны үстейтін не аластатын топтарды талғаңыз.
+Талғауы өшірілген топтар өзгертілімейді. Топтардың талғауын CTRL + Сол жақ нұқумен өшіруіңізге болады.',
+
+# Groups
+'group' => 'Топ:',
+'group-bot' => 'Боттар',
+'group-sysop' => 'Әкімшілер',
+'group-bureaucrat' => 'Төрешілер',
+'group-all' => '(барлығы)',
+
+'group-bot-member' => 'бот',
+'group-sysop-member' => 'әкімші',
+'group-bureaucrat-member' => 'төреші',
+
+'grouppage-bot' => '{{ns:project}}:Боттар',
+'grouppage-sysop' => '{{ns:project}}:Әкімшілер',
+'grouppage-bureaucrat' => '{{ns:project}}:Төрешілер',
+
+# Recent changes
+'changes' => 'өзгеріс',
+'recentchanges' => 'Жуықтағы өзгерістер',
+'recentchangestext' => 'Бұл бетте осы уикидегі болған жуықтағы өзгерістер байқалады.',
+'rcnote' => '$3 кезіне дейін — төменде соңғы <strong>$2</strong> күндегі, соңғы <strong>$1</strong> өзгеріс көрсетілген.',
+'rcnotefrom' => '<b>$2</b> кезінен бері — төменде өзгерістер <b>$1</b> дейін көрсетілген.',
+'rclistfrom' => '$1 кезінен бері — жаңа өзгерістерді көрсет.',
+'rcshowhideminor' => 'Шағын түзетуді $1',
+'rcshowhidebots' => 'Боттарды $1',
+'rcshowhideliu' => 'Тіркелгенді $1',
+'rcshowhideanons' => 'Тіркелгісізді $1',
+'rcshowhidepatr' => 'Күзеттегі түзетулерді $1',
+'rcshowhidemine' => 'Түзетуімді $1',
+'rclinks' => 'Соңғы $2 күнде болған, соңғы $1 өзгерісті көрсет<br />$3',
+'diff' => 'айырм.',
+'hist' => 'тар.',
+'hide' => 'жасыр',
+'show' => 'көрсет',
+'minoreditletter' => 'ш',
+'newpageletter' => 'Ж',
+'boteditletter' => 'б',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[бақылаған $1 қатысушы]',
+'rc_categories' => 'Санаттарға шектеу ("|" белгісімен бөліктеңіз)',
+'rc_categories_any' => 'Қайсыбір',
+
+# Upload
+'upload' => 'Файл қотару',
+'uploadbtn' => 'Қотар!',
+'reupload' => 'Қайталап қотару',
+'reuploaddesc' => 'Қотару үлгітіне оралу.',
+'uploadnologin' => 'Кірмегенсіз',
+'uploadnologintext' => 'Файл қотару үшін
+[[{{ns:special}}:Userlogin|кіруіңіз]] қажет.',
+'upload_directory_read_only' => 'Қотару қалтасына ($1) жазуға веб-серверге рұқсат берілмеген.',
+'uploaderror' => 'Қотару қатесі',
+'uploadtext' => "Төмендегі үлгіт файл қотаруға қолданылады, алдындағы суреттерді қарау үшін не іздеу үшін [[{{ns:special}}:Imagelist|қотарылған файлдар тізіміне]] барыңыз, қотару мен жою тағы да [[{{ns:special}}:Log/upload|қотару журналына]] жазылып алынады.
+
+Суреттерді бетке кіргізу үшін, файлға тура байланыстратын
+'''<nowiki>[[{{ns:image}}:File.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:File.png|балама мәтін]]</nowiki>''' немесе
+'''<nowiki>[[{{ns:media}}:File.ogg]]</nowiki>''' сілтеме пішімін қолданыңыз.",
+'uploadlog' => 'қотару журналы',
+'uploadlogpage' => 'Қотару журналы',
+'uploadlogpagetext' => 'Төменде жуықтағы қотарылған файл тізімі.',
+'filename' => 'Файл аты',
+'filedesc' => 'Сипаттамасы',
+'fileuploadsummary' => 'Сипаттамасы:',
+'filestatus' => 'Ауторлық құқықтары күйі',
+'filesource' => 'Файл қайнары',
+'copyrightpage' => '{{ns:project}}:Ауторлық құқықтар',
+'copyrightpagename' => '{{SITENAME}} ауторлық құқықтары',
+'uploadedfiles' => 'Қотарылған файлдар',
+'ignorewarning' => 'Назар салуды елемеу және файлды әрдеқашан сақтау.',
+'ignorewarnings' => 'Әрқайсы назар салуларды елемеу',
+'minlength' => 'Файл атында ең кемінде үш әріп болуы керек.',
+'illegalfilename' => '«$1» файл атауында бет атауларында рұқсат етілмеген нышандар бар. Файлды қайта атаңыз, сосын қайта жуктеп көріңіз.',
+'badfilename' => 'Файлдың аты «$1» боп өзгертілді.',
+'badfiletype' => '«.$1» ұсынылмаған сурет файлының кеңейтімі.',
+'largefile' => 'Файл мөлшерін $1 Байттан асырмауға тырысыңыз, бұл файл мөлшері $2 Байт',
+'largefileserver' => 'Осы файлдың мөлшері сервердің қалауынан асып кеткен.',
+'emptyfile' => 'Қотарылған файлыңыз бос сияқты. Бұл файл атауы жансақ енгізілгенінен болуы мүмкін. Қотарғыңыз келген файл шынында да осы файл болғанын тексеріп алыңыз.',
+'fileexists' => 'Осындай атаулы файл бар түге. Қайта жазудың алдынан $1 тексеріп шығыңыз.',
+'fileexists-forbidden' => 'Осындай атаулы файл бар түге. Кері қайтыңыз да, және осы файлды басқа атымен қотарыңыз. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Осындай атаулы файл ортақ файл арқауында бар түге. Кері қайтыңыз да, осы файлды жаңа атымен қотарыңыз. [[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'Қотару сәтті өтті',
+'fileuploaded' => '«$1» файлы сәтті қотарылды!
+Осы сілтемеге еріп — $2, сипаттама бетіне барыңыз да, және осы файл туралы
+ақпарат толтырыңыз: қайдан алынғанын, қашан жасалғанын, кім жасағанын,
+тағы басқа білетіңізді. Бұл сурет болса, мынадай пішімімен кірістіруге болады: <tt><nowiki>[[Сурет:$1|thumb|Сипаттамасы]]</nowiki></tt>',
+'uploadwarning' => 'Қотару туралы назар салу',
+'savefile' => 'Файлды сақтау',
+'uploadedimage' => '«[[$1]]» файлын қотарды',
+'uploaddisabled' => 'Файл қотаруы өшірілген',
+'uploaddisabledtext' => 'Осы уикиде файл қотаруы өшірілген.',
+'uploadscripted' => 'Осы файлда, веб шолғышты ағат түсіндікке келтіретің HTML белгілеу, не скрипт коды бар.',
+'uploadcorrupt' => 'Осы файл бүлдірілген, не әдепсіз кеңейтімі бар. Файлды тексеріп, қотаруын қайталаңыз.',
+'uploadvirus' => 'Осы файлда вирус болуы мүмкін! Егжей-тегжей ақпараты: $1',
+'sourcefilename' => 'Қайнардағы файл аты',
+'destfilename' => 'Ақырғы файл аты',
+'watchthisupload' => 'Осы бетті бақылау',
+'filewasdeleted' => 'Осы атауы бар файл бұрын қотарылған, сосын жойылдырылған. Қайта қотару алдынан $1 дегенді тексеріңіз.',
+
+'upload-proto-error' => 'Жарамсыз хаттамалық',
+'upload-proto-error-text' => 'Сырттан қотару үшін URL жайлары <code>http://</code> немесе <code>ftp://</code> дегендерден басталу қажет.',
+'upload-file-error' => 'Ішкі қате',
+'upload-file-error-text' => 'Серверде уақытша файл жасауы ішкі қатеге ұшырасты. Бұл жүйенің әкімшімен қатынасыңыз.',
+'upload-misc-error' => 'Белгісіз қотару қатесі',
+'upload-misc-error-text' => 'Қотару кезінде белгісіз қате ұшырасты. Қайсы URL жайы жарамды және қатынаулы екенін тексеріп шығыңыз да қайталап көріңіз. Егер бұл мәселе әлде де қалса, жүйе әкімшімен қатынасыңыз.',
+
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => 'URL жайы жетілмеді',
+'upload-curl-error6-text' => 'Берілген URL жайы жетілмеді. Қайсы URL жайы дұрыс екенін және торап істе екенін қайталап қатаң тексеріңіз.',
+'upload-curl-error28' => 'Қотаруға берілген уақыт бітті',
+'upload-curl-error28-text' => 'Тораптың жауап беруі тым ұзақ уақытқа созылды. Бұл торап істе екенін тексеріп шығыңыз, аз уақыт кідіре тұрыңыз да тағы қайталап көріңіз. Талабыңызды жүктелуі аздау кезінде қайталауға болмыс.',
+
+'license' => 'Лицензиясы',
+'nolicense' => 'Ештеңе талғанбаған',
+'upload_source_url' => ' (жарамды, баршаға қатынаулы URL жай)',
+'upload_source_file' => ' (компьютеріңіздегі файл)',
+
+# Image list
+'imagelist' => 'Файл тізімі',
+'imagelisttext' => "Төменде ''$2'' сұрыпталған '''$1''' файл тізімі.",
+'imagelistforuser' => 'Мында тек $1 жүктеген суреттер көрсетіледі.',
+'getimagelist' => 'файл тізімдеуі',
+'ilsubmit' => 'Іздеу',
+'showlast' => 'Соңғы $1 файл $2 сұрыптап көрсет.',
+'byname' => 'атымен',
+'bydate' => 'күн-аймен',
+'bysize' => 'мөлшерімен',
+'imgdelete' => 'жою',
+'imgdesc' => 'сипп.',
+'imgfile' => 'файл',
+'imglegend' => 'Шартты белгілер: (сипп.) — файл сипаттамасын көрсету/өңдеу.',
+'imghistory' => 'Файл тарихы',
+'revertimg' => 'қайт.',
+'deleteimg' => 'жою',
+'deleteimgcompletely' => 'Осы файлдың барлық нұсқаларын жой',
+'imghistlegend' => 'Шартты белгілер: (ағым.) = ағымдық файл, (жою) = ескі нұсқасын
+жою, (қай.) = ескі нұсқасына қайтару.
+<br /><i>Қотарылған файлды көру үшін күн-айына нұқыңыз</i>.',
+'imagelinks' => 'Сілтемелері',
+'linkstoimage' => 'Бұл файлға келесі беттер сілтейді:',
+'nolinkstoimage' => 'Бұл файлға еш бет сілтемейді.',
+'sharedupload' => 'Бұл файл ортақ арқауына қотарылған сондықтан басқа жобаларда қолдануы мүмкін.',
+'shareduploadwiki' => 'Былайғы ақпарат үшін $1 дегенді қараңыз.',
+'shareduploadwiki-linktext' => 'файл сипаттамасы беті',
+'noimage' => 'Мынадай атаулы файл жоқ, $1 мүмкіндігіңіз бар.',
+'noimage-linktext' => 'осыны қотару',
+'uploadnewversion-linktext' => 'Бұл файлдың жаңа нұсқасын қотару',
+'imagelist_date' => 'Күн-айы',
+'imagelist_name' => 'Атауы',
+'imagelist_user' => 'Қатысушы',
+'imagelist_size' => 'Мөлшері (байт)',
+'imagelist_description' => 'Сипаттамасы',
+'imagelist_search_for' => 'Суретті атымен іздеу:',
+
+# MIME search
+'mimesearch' => 'Файлды MIME түрімен іздеу',
+'mimetype' => 'MIME түрі:',
+'download' => 'жүктеу',
+
+# Unwatched pages
+'unwatchedpages' => 'Бақыланбаған беттер',
+
+# List redirects
+'listredirects' => 'Айдату бет тізімі',
+
+# Unused templates
+'unusedtemplates' => 'Пайдаланылмаған үлгілер',
+'unusedtemplatestext' => 'Бұл бет басқа бетке кіріcтірілмеген үлгі есім аяысындағы барлық беттерді тізімдейді. Үлгілерді жою алдынан бұның басқа сілтемелерін тексеріп шығуын ұмытпаңыз',
+'unusedtemplateswlh' => 'басқа сілтемелер',
+
+# Random redirect
+'randomredirect' => 'Кездейсоқ айдату',
+
+# Statistics
+'statistics' => 'Жоба санағы',
+'sitestats' => '{{SITENAME}} санағы',
+'userstats' => 'Қатысушы санағы',
+'sitestatstext' => "Мындағы дерекқорда бұлайша '''$1''' бет бар.
+Бұның ішінде «талқылау» беттері, {{SITENAME}} жобасы туралы беттер, кішкене «бітеме»
+беттер, айдатулар, мағлұмат бет деп саналмайтын, бәлкім, тағы да басқалар.
+Осыны есептен шығарғанда, мында мағлұматты деп саналатын
+'''$2''' бет бар шығар.
+
+Торапқа '''$8''' файл қотарылған.
+
+Осы уики жобасы орнатылғаннан бері бұлайша беттер '''$3''' рет қаралған,
+және беттер '''$4''' рет өңделген.
+Бұның нәтижесінде орта есеппен бір бет сайын '''$5''' өңдеу істелінген, және бір өңдеу сайын '''$6''' рет қарау келген.
+
+Ағымдық [http://meta.wikimedia.org/wiki/Help:Job_queue тапсырым кезегі] ұзындылығы: '''$7'''.",
+'userstatstext' => "Мында '''$1''' тіркелген қатысушы бар, соның ішінде
+'''$2''' (немесе '''$4 %''') $5 бар.",
+'statistics-mostpopular' => 'Ең көп қаралған беттер',
+
+'disambiguations' => 'Айрықты беттер',
+'disambiguationspage' => '{{ns:template}}:Disambig',
+'disambiguationstext' => 'Келесі беттер <i>айрықты бетке</i> сілтейді. Бұның орнына белгілі тақырыпқа сілтеуі қажет.<br />Бетке $1 сілтеген жағдайда, бет айрықты деп саналады.<br />Басқа есім аясынан нұсқайтын сілтемелер мында <i>тізімделмейді</i>.',
+
+'doubleredirects' => 'Шынжырлы айдатулар',
+'doubleredirectstext' => 'Әрбір жолдағы бірінші мен екінші айдату сілтемелері бар, сонымен бірге екінші айдату мәтіннің бірінші жолы бар. Әдетте бірінші сілтеме айдайтын «шын» ақырғы беттің атауы болуы қажет.',
+
+'brokenredirects' => 'Еш бетке келтірмейтін айдатулар',
+'brokenredirectstext' => 'Келесі айдатулар жоқ беттерге сілтейді:',
+
+# Miscellaneous special pages
+'nbytes' => '$1 Байт',
+'ncategories' => '$1 санат',
+'nlinks' => '$1 сілтеме',
+'nmembers' => '$1 буын',
+'nrevisions' => '$1 нұсқа',
+'nviews' => '$1 рет қаралған',
+'lonelypages' => 'Еш бет сілтемеген беттер',
+'lonelypagestext' => 'Келесі беттерге осы жобадағы басқа беттер сілтемейді.',
+'uncategorizedpages' => 'Еш санатқа кірмеген беттер',
+'uncategorizedcategories' => 'Еш санатқа кірмеген санаттар',
+'uncategorizedimages' => 'Еш санатқа кірмеген суреттер',
+'unusedcategories' => 'Пайдаланылмаған санаттар',
+'unusedimages' => 'Пайдаланылмаған файлдар',
+'popularpages' => 'Әйгілі беттер',
+'wantedcategories' => 'Басталмаған санаттар',
+'wantedpages' => 'Басталмаған беттер',
+'mostlinked' => 'Ең көп сілтенген беттер',
+'mostlinkedcategories' => 'Ең көп сілтенген санаттар',
+'mostcategories' => 'Ең көп санаттарға кірген беттер',
+'mostimages' => 'Ең көп сілтенген суреттер',
+'mostrevisions' => 'Ең көп түзетілген беттер',
+'allpages' => 'Барлық бет тізімі',
+'prefixindex' => 'Бет бастау тізімі',
+'randompage' => 'Кездейсоқ бет',
+'shortpages' => 'Ең қысқа беттер',
+'longpages' => 'Ең үлкен беттер',
+'deadendpages' => 'Еш бетке сілтемейтін беттер',
+'deadendpagestext' => 'Келесі беттер осы жобадағы басқа беттерге сілтемейді.',
+'listusers' => 'Барлық қатысушы тізімі',
+'specialpages' => 'Арнайы беттер',
+'spheading' => 'Баршаның арнайы беттері',
+'restrictedpheading' => 'Шектеулі арнайы беттер',
+'recentchangeslinked' => 'Қатысты түзетулер',
+'rclsub' => '(«$1» бетінен сілтенген беттерге)',
+'newpages' => 'Ең жаңа беттер',
+'newpages-username' => 'Қатысушы аты:',
+'ancientpages' => 'Ең ескі беттер',
+'intl' => 'Тіларалық сілтемелер',
+'move' => 'Жылжыту',
+'movethispage' => 'Бетті жылжыту',
+'unusedimagestext' => '<p>Ескерту: Басқа веб тораптар файлдың
+URL жайына тікелей сілтеуі мүмкін. Сондықтан, белсенді пайдалануына аңғармай,
+осы тізімде қалуы мүмкін.</p>',
+'unusedcategoriestext' => 'Келесі санат беттер бар болып тұр, бірақ оған ешқандай бет, не санат кірмейді.',
+'booksources' => 'Кітап қайнарлары',
+'categoriespagetext' => 'Осында уикидегі барлық санаттарының тізімі беріліп тұр.',
+'data' => 'Деректер',
+'userrights' => 'Қатысушылар құқықтарын меңгеру',
+'groups' => 'Қатысушы топтары',
+'booksourcetext' => 'Төменде жаңа және қолданған кітаптар сататын
+тораптарының сілтемелері тізімделген. Бұл тораптарда ізделген кітаптар
+туралы былайғы ақпарат болуға мүмкін.',
+'isbn' => 'ISBN белгісі',
+'alphaindexline' => '$1 — $2',
+'version' => 'Жүйе нұсқасы',
+'log' => 'Журналдар',
+'alllogstext' => 'Біріккен қотару, жою, қорғау, бұғаттау және әкімшілік журналдарын көрсету.
+Журнал түрін, қатысушы атын, тиісті бетін талғап, тарылтып қарауыңызға болады.',
+'logempty' => 'Журналда сәйкес даналар жоқ.',
+
+# Special:Allpages
+'nextpage' => 'Келесі бетке ($1)',
+'allpagesfrom' => 'Мына беттен бастап көрсету:',
+'allarticles' => 'Барлық бет тізімі',
+'allinnamespace' => 'Барлық бет ($1 есім аясы)',
+'allnotinnamespace' => 'Барлық бет ($1 есім аясынан тыс)',
+'allpagesprev' => 'Алдыңғыға',
+'allpagesnext' => 'Келесіге',
+'allpagessubmit' => 'Өту',
+'allpagesprefix' => 'Мынадан басталған беттерді көрсету:',
+'allpagesbadtitle' => 'Алынған бет атауы жарамсыз болған, немесе тіл-аралық не уики-аралық бастауы бар болды. Атауда қолдануға болмайтын нышандар болуы мүмкін.',
+
+# Special:Listusers
+'listusersfrom' => 'Мына қатысушыдан бастап көрсету:',
+
+# E-mail user
+'mailnologin' => 'Е-пошта жайы жіберілген жоқ',
+'mailnologintext' => 'Басқа қатысушыға хат жіберу үшін
+[[{{ns:special}}:Userlogin|кіруіңіз]] қажет, және [[{{ns:special}}:Preferences|баптауыңызда]]
+куәландырылған е-пошта жайы болуы жөн.',
+'emailuser' => 'Қатысушыға хат жазу',
+'emailpage' => 'Қатысушыға хат жіберу',
+'emailpagetext' => 'Егер бұл қатысушы баптауларында куәландырған е-пошта
+жайын енгізсе, төмендегі үлгіт арқылы бұған жалғыз е-пошта хатын жіберуге болады.
+Қатысушы баптауыңызда енгізген е-пошта жайыңыз
+«Кімнен» деген бас жолағында көрінеді, сондықтан
+хат алушысы тура жауап бере алады.',
+'usermailererror' => 'Mail нысаны қате қайтарды:',
+'defemailsubject' => '{{SITENAME}} е-поштасының хаты',
+'noemailtitle' => 'Бұл е-пошта жайы емес',
+'noemailtext' => 'Осы қатысушы жарамды Е-пошта жайын енгізбеген,
+немесе басқалардан хат қабылдауын өшірген.',
+'emailfrom' => 'Кімнен',
+'emailto' => 'Кімге',
+'emailsubject' => 'Тақырыбы',
+'emailmessage' => 'Хат',
+'emailsend' => 'Жіберу',
+'emailccme' => 'Хатымдың көшірмесін маған да жібер.',
+'emailccsubject' => '$1 дегенге жіберілген хатыңыздың көшірмесі: $2',
+'emailsent' => 'Хат жіберілді',
+'emailsenttext' => 'Е-пошта хатыңыз жіберілді.',
+
+# Watchlist
+'watchlist' => 'Бақылауым',
+'watchlistfor' => "('''$1''' бақылаулары)",
+'nowatchlist' => 'Бақылау тізіміңізде ешбір дана жоқ',
+'watchlistanontext' => 'Бақылау тізіміңіздегі даналарды қарау, не өңдеу үшін $1 қажет.',
+'watchlistcount' => "'''Бақылау тізіміңізде (талқылау беттерді қоса) $1 дана бар.'''",
+'clearwatchlist' => 'Бақылау тізімін тазалау',
+'watchlistcleartext' => 'Соларды толық аластатуға батылсыз ба?',
+'watchlistclearbutton' => 'Бақылау тізімін тазалау',
+'watchlistcleardone' => 'Бақылау тізіміңіз тазартылды. $1 дана аластатылды.',
+'watchnologin' => 'Кірмегенсіз',
+'watchnologintext' => 'Бақылау тізіміңізді өзгерту үшін [[{{ns:special}}:Userlogin|кіруіңіз]] жөн.',
+'addedwatch' => 'Бақылау тізіміне қосылды',
+'addedwatchtext' => "«[[:$1]]» беті [[{{ns:special}}:Watchlist|бақылау тізіміңізге]] қосылды.
+Осы беттің және соның талқылау бетінің келешектегі өзгерістері мында тізімделеді.
+Сонда беттің атауы табуға жеңілдетіп [[{{ns:special}}:Recentchanges|жуықтағы өзгерістер тізімінде]]
+'''жуан әрпімен''' көрсетіледі.
+
+Осы бетті соңынан бақылау тізімнен аластатыңыз келсе «Бақыламау» парағын нұқыңыз.",
+'removedwatch' => 'Бақылау тізіміңізден аластатылды',
+'removedwatchtext' => '«[[:$1]]» беті бақылау тізіміңізден аластатылды.',
+'watch' => 'Бақылау',
+'watchthispage' => 'Бетті бақылау',
+'unwatch' => 'Бақыламау',
+'unwatchthispage' => 'Бақылауды тоқтату',
+'notanarticle' => 'Мағлұмат беті емес',
+'watchnochange' => 'Көрсетілген мерзімде ешбір бақыланған дана өңделген жоқ.',
+'watchdetails' => "* Бақылау тізімінде (талқылау беттерісіз) '''$1''' бет бар.
+* [[{{ns:special}}:Watchlist/edit|Бүкіл тізімді қарау және өзгерту]].
+* [[{{ns:special}}:Watchlist/clear|Тізімдегі барлық дана аластату]].",
+'wlheader-enotif' => '* Ескерту хат жіберуі ендірілген.',
+'wlheader-showupdated' => "* Соңғы кіргенімнен бері түзетілген беттерді '''жуан''' мәтінмен көрсет",
+'watchmethod-recent' => 'бақылаулы беттердің жуықтағы өзгерістерін тексеру',
+'watchmethod-list' => 'жуықтағы өзгерістерде бақылаулы беттерді тексеру',
+'removechecked' => 'Белгіленгенді бақылау тізімінен аластату',
+'watchlistcontains' => 'Бақылау тізіміңізде $1 бет бар.',
+'watcheditlist' => "Осында әліппем сұрыпталған бақыланған мағлұмат беттеріңіз тізімделінген.
+Беттерді аластату үшін оның қасындағы қабашақтарды белгілеп, төмендегі ''Белгіленгенді аластат'' түймесін нұқыңыз
+(мағлұмат бетін жойғанда талқылау беті де бірге жойылады).",
+'removingchecked' => 'Сұранған даналарды бақылау тізімнен аластауы…',
+'couldntremove' => '«$1» деген дана аластатылмады…',
+'iteminvalidname' => '«$1» данасының жарамсыз атауынан шатақ туды…',
+'wlnote' => 'Төменде соңғы <b>$2</b> сағаттағы, соңғы $1 өзгеріс көрсетілген.',
+'wlshowlast' => 'Соңғы $1 сағаттағы, $2 күндегі, $3 болған өзгерісті көрсету',
+'wlsaved' => 'Бұл бақылу тізіміңіздің сақталған нұсқасы.',
+'wlhideshowown' => 'Түзетуімді $1',
+'wlhideshowbots' => 'Боттарды $1',
+'wldone' => 'Іс бітті.',
+
+'enotif_mailer' => '{{SITENAME}} ескерту хат жіберу қызметі',
+'enotif_reset' => 'Барлық бет каралді деп белгіле',
+'enotif_newpagetext' => 'Мынау жаңа бет.',
+'changed' => 'өзгертті',
+'created' => 'жасады',
+'enotif_subject' => '{{SITENAME}} жобасында $PAGEEDITOR $PAGETITLE атаулы бетті $CHANGEDORCREATED',
+'enotif_lastvisited' => 'Соңғы кіруіңізден бері болған өзгерістер үшін $1 дегенді қараңыз.',
+'enotif_body' => 'Құрметті $WATCHINGUSERNAME,
+
+{{SITENAME}} жобасыда $PAGEEDITDATE кезінде $PAGEEDITOR $PAGETITLE атаулы бетті $CHANGEDORCREATED, ағымдық нұсқасын $PAGETITLE_URL жайынан қараңыз.
+
+$NEWPAGE
+
+Өңдеуші сипаттамасы: $PAGESUMMARY $PAGEMINOREDIT
+
+Өңдеушімен қатынасу:
+е-пошта: $PAGEEDITOR_EMAIL
+уики: $PAGEEDITOR_WIKI
+
+Былайғы өзгерістер болғанда да сіз осы бетке барғанша дейін ешқандай басқа ескерту хаттар жіберілмейді. Сонымен қатар бақылау тізіміңіздегі бет ескертпелік белгісін әдепке күйіне келтіріңіз.
+
+ Сіздің досты {{SITENAME}} ескерту қызметі
+
+----
+Бақылау тізіміңізді баптау үшін, мында барыңыз
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Сын-пікір беру және былайғы жәрдем алу үшін:
+{{fullurl:{{ns:help}}:Мазмұны}}',
+
+# Delete/protect/revert
+'deletepage' => 'Бетті жою',
+'confirm' => 'Растау',
+'excontent' => 'болған мағлұматы: «$1»',
+'excontentauthor' => 'болған мағлұматы: «$1» (тек «[[Special:Contributions/$2|$2]]» үлесі)',
+'exbeforeblank' => 'тазарту алдындағы болған мағлұматы: «$1»',
+'exblank' => 'бет босты болды',
+'confirmdelete' => 'Жоюды растау',
+'deletesub' => '(«$1» жоюы)',
+'historywarning' => 'Назар салыңыз: Жоюға арналған бетте өз тарихы бар:',
+'confirmdeletetext' => 'Бетті немесе суретті барлық тарихымен
+бірге дерекқордан әрдайым жойығыңыз келетін сияқты.
+Бұны жоюдың зардабын түсініп шын ниеттенгеніңізді, және
+[[{{ns:project}}:Саясат]]қа лайықты деп
+сенгеніңізді растаңыз.',
+'actioncomplete' => 'Әрекет бітті',
+'deletedtext' => '«$1» жойылды.
+Жуықтағы жоюлар туралы жазбаларын $2 дегеннен қараңыз.',
+'deletedarticle' => '«[[$1]]» бетін жойды',
+'dellogpage' => 'Жою_журналы',
+'dellogpagetext' => 'Төменде жуықтағы жоюлардың тізімі берілген.',
+'deletionlog' => 'жою журналы',
+'reverted' => 'Ертерек нұсқасына қайтарылған',
+'deletecomment' => 'Жоюдың себебі',
+'imagereverted' => 'Ертерек нұсқасына қайтару сәтті өтті.',
+'rollback' => 'Түзетулерді қайтару',
+'rollback_short' => 'Қайтару',
+'rollbacklink' => 'қайтару',
+'rollbackfailed' => 'Қайтару сәтсіз аяқталды',
+'cantrollback' => 'Түзету қайтарылмайды. Бұл беттің соңғы үлескері тек бастауыш ауторы.',
+'alreadyrolled' => '[[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|талқылауы]]) дегенді жасаған [[:$1]]
+бетінің соңғы өңдеуінен қайтару өтпеді; кейбіреу осы қазір бетті өңдеп не қайтарып жатыр түге.
+
+Соңғы өңдеуді [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|талқылауы]]) дегенді жасаған.',
+'editcomment' => 'Түзетудің болған мәндемесі: "<i>$1</i>".', # only shown if there is an edit comment
+'revertpage' => '[[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|талқылауы]]) түзетуінен [[{{ns:user}}:$1|$1]] соңғы нұсқасына қайтарды',
+'sessionfailure' => 'Кіру сессиясында шатақ болған сияқты;
+сессияға шабуылдаудардан қорғану үшін, осы әрекет тоқтатылды.
+«Артқа» түймесін басыңыз, және бетті кері жүктеңіз, сосын қайталап көріңіз.',
+'protectlogpage' => 'Қорғау_журналы',
+'protectlogtext' => 'Төменде беттердің қорғау/қорғамау тізімі берілген.',
+'protectedarticle' => '«$1» қорғалды',
+'unprotectedarticle' => '«[[$1]]» қорғалмады',
+'protectsub' => '(«$1» қорғауда)',
+'confirmprotecttext' => 'Осы бетті расында да қорғау қажет пе?',
+'confirmprotect' => 'Қорғауды растау',
+'protectmoveonly' => 'Тек жылжытудан қорғау',
+'protectcomment' => 'Қорғау себебі',
+'unprotectsub' => '(«$1» қорғамауда)',
+'confirmunprotecttext' => 'Осы бетті растан қорғамау қажет пе?',
+'confirmunprotect' => 'Қорғамауды растау',
+'unprotectcomment' => 'Қорғамау себебі',
+'protect-unchain' => 'Жылжытуға рұқсат беру',
+'protect-text' => '<strong>$1</strong> бетінің қорғау деңгейін қарай және өзгерте аласыз.',
+'protect-viewtext' => 'Тіркелгіңіз бет қорғанысы денгейлерін өзгертуге рұқсат бермейді.
+Мына <strong>$1</strong> беттің ағымдық баптаулары:',
+'protect-default' => '(әдепкі)',
+'protect-level-autoconfirmed' => 'Тіркелгісіз пайдаланушыларға тиым',
+'protect-level-sysop' => 'Тек әкімшілерге рұқсат',
+
+# Restrictions (nouns)
+'restriction-edit' => 'Өңдеу',
+'restriction-move' => 'Жылжыту',
+
+# Undelete
+'undelete' => 'Жойылған беттерді қарау',
+'undeletepage' => 'Жойылған беттерді қарау және қайтару',
+'viewdeletedpage' => 'Жойылған беттерді қарау',
+'undeletepagetext' => 'Келесі беттер жойылды деп белгіленген, бірақ мағлұматы мұрағатта жатқан,
+сондықтан кері қайтаруға әзір. Мұрағат мерзім бойынша тазаланып тұруы мүмкін.',
+'undeleteextrahelp' => "Бүкіл бетті қайтару үшін, барлық қабашақтарды бос қалдырып
+'''''Қайтар!''''' түймесін нұқыңыз. Бөлекше қайтару орындау үшін, қайтарайын деген нұсқаларына сәйкес
+қабашақтарын белгілеңіз де, және '''''Қайтар!''''' түймесін нұқыңыз. '''''Таста''''' түймесін
+нұқығанда мәндеме аумағы мен барлық қабашақтар тазаланады.",
+'undeletearticle' => 'Жойылған бетті қайтару',
+'undeleterevisions' => '$1 нұсқа мұрағатталған',
+'undeletehistory' => 'Егер бет мағлұматын қайтарсаңыз,тарихында барлық нұсқалар да
+қайтарылады. Егер жоюдан соң дәл солай атауымен жаңа бет жасалса, қайтарылған нұсқалар
+тарихтың ең адында көрсетіледі, және көрсетіліп тұрған беттің ағымдық нұсқасы
+өздік түрде алмастырылмайды.',
+'undeletehistorynoadmin' => 'Бұл бет жойылған. Жою себебі алдындағы өңдеген қатысушылар
+егжей-тегжейлерімен бірге төмендегі сипаттамасында көрсетілген.
+Осы жойылған нұсқалардың мәтіні тек әкімшілерге қатынаулы.',
+'undeleterevision' => '$1 кезіндегі жойылған нұсқасын',
+'undeleterevision-missing' => 'Жарамсыз не жоғалған нұсқа. Сілтемеңіз жарамсыз болуы мүмкін, не
+нұсқа қайтарылған түге немесе мұрағаттан аластатылған.',
+'undeletebtn' => 'Қайтар!',
+'undeletereset' => 'Таста',
+'undeletecomment' => 'Мәндемесі:',
+'undeletedarticle' => '«[[$1]]» қайтарды',
+'undeletedrevisions' => '$1 нұсқасы қайтарылған',
+'undeletedrevisions-files' => '$1 нұсқа және $2 файл қайтарылды',
+'undeletedfiles' => '$1 файл қайтарылды',
+'cannotundelete' => 'Қайтару сәтсіз бітті; тағы біреу сізден бұрын сол бетті қайтарған болар.',
+'undeletedpage' => "<big>'''$1 қайтарылды'''</big>
+
+Жуықтағы жою мен қайтару жөнінде [[{{ns:special}}:Log/delete|жою журналын]] қараңыз.",
+
+# Namespace form on various pages
+'namespace' => 'Есім аясы:',
+'invert' => 'Талғауды керілеу',
+
+# Contributions
+'contributions' => 'Қатысушы үлесі',
+'mycontris' => 'Үлесім',
+'contribsub' => '$1 үлесі',
+'nocontribs' => 'Осы іздеу шартына сәйкес өзгерістер табылған жоқ.',
+'ucnote' => 'Төменде осы қатысушының соңғы <b>$2</b> күндегі, соңғы <b>$1</b> өзгерісі көрсетледі.',
+'uclinks' => 'Соңғы $2 күндегі, соңғы $1 өзгерісін қарау.',
+'uctop' => ' (үсті)',
+'newbies' => 'жаңа қатысушылар',
+
+'sp-newimages-showfrom' => '$1 кезінен бері — жаңа суреттерді көрсет',
+
+'sp-contributions-newest' => 'Ең жаңасына',
+'sp-contributions-oldest' => 'Ең ескісіне',
+'sp-contributions-newer' => 'Жаңалау $1',
+'sp-contributions-older' => 'Ескілеу $1',
+'sp-contributions-newbies-sub' => 'Жаңа қатысушыларға',
+
+# What links here
+'whatlinkshere' => 'Сілтеген беттер',
+'notargettitle' => 'Ақырғы атау жоқ',
+'notargettext' => 'Осы әрекет орындалатын нысана бет,
+не қатысушы көрсетілмеген.',
+'linklistsub' => '(Сілтемелер тізімі)',
+'linkshere' => "'''[[:$1]]''' дегенге мына беттер сілтейді:",
+'nolinkshere' => "'''[[:$1]]''' дегенге еш бет сілтемейді.",
+'isredirect' => 'айдату беті',
+'istemplate' => 'кіріктіру',
+
+# Block/unblock
+'blockip' => 'Пайдаланушыны бұғаттау',
+'blockiptext' => 'Төмендегі үлгіт пайдаланушының жазу рұқсатын
+белгілі IP жайымен не атауымен бұғаттау үшін қолданылады.
+Бұны тек бұзақылыққа кедергі істеу үшін және де
+[[{{ns:project}}:Саясат|саясат]] бойынша атқаруыңыз жөн.
+Төменде тиісті себебін толтырып көрсетіңіз (мысалы, дәйекке бұзақылықпен
+өзгерткен беттерді келтіріп).',
+'ipaddress' => 'IP жай',
+'ipadressorusername' => 'IP жай не қатысушы аты',
+'ipbexpiry' => 'Бітетін мерзімі',
+'ipbreason' => 'Себебі',
+'ipbanononly' => 'Тек тіркелгісізді бұғаттау',
+'ipbcreateaccount' => 'Тіркелгі жасауын кедергілеу',
+'ipbenableautoblock' => 'Бұл қатысушының қолданған соңғы IP жайын, және әрқайсы кейін түзету істеуге үмітеліген жайларын өздік түрде бұғаттау',
+'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',
+'ipbotheroption' => 'басқа',
+'badipaddress' => 'Жарамсыз IP жай',
+'blockipsuccesssub' => 'Бұғаттау сәтті өтті',
+'blockipsuccesstext' => '[[{{ns:special}}:Contributions/$1|$1]] деген бұғатталған.
+<br />Бұғаттауларды [[{{ns:special}}:Ipblocklist|IP бұғаттау тізімінде]] қарап шығыңыз.',
+'unblockip' => 'Пайдаланушыны бұғаттамау',
+'unblockiptext' => 'Төмендегі үлгіт белгілі IP жайымен не атауымен
+бұрын бұғатталған пайдаланушының жазу рұқсатын қайтару үшін қолданылады.',
+'ipusubmit' => 'Осы жайды бұғаттамау',
+'unblocked' => '[[{{ns:user}}:$1|$1]] бұғаттауы өшірілді',
+'ipblocklist' => 'Бұғатталған пайдаланушы / IP- жай тізімі',
+'blocklistline' => '$1, $2 «$3» дегенді бұғаттады ($4)',
+'infiniteblock' => 'мәнгі',
+'expiringblock' => 'бітуі: $1',
+'anononlyblock' => 'тек тіркелгісізді',
+'noautoblockblock' => 'өздік бұғаттау өшіріленген',
+'createaccountblock' => 'тіркелгі жасауы бұғатталған',
+'ipblocklistempty' => 'Бұғаттау тізімі бос.',
+'blocklink' => 'бұғаттау',
+'unblocklink' => 'бұғаттамау',
+'contribslink' => 'үлесі',
+'autoblocker' => "IP жайыңызды жуықта «[[{{ns:user}}:1|$1]]» пайдаланған, сондықтан өздік түрде бұғатталған. $1 бұғаттау себебі: «'''$2'''».",
+'blocklogpage' => 'Бұғаттау_журналы',
+'blocklogentry' => '«[[$1]]» бұғаттады, бітетін мерзімі: $2',
+'blocklogtext' => 'Бұл пайдаланушыларды бұғаттау/бұғаттамау әрекеттерінің журналы. Өздік түрде
+бұғатталған IP жайлар осында тізімделгемеген. Ағымдағы белсенді бұғаттауларын
+[[{{ns:special}}:Ipblocklist|IP бұғаттау тізімінен]] қарауға болады.',
+'unblocklogentry' => '«$1» бұғаттауын өшірді',
+'range_block_disabled' => 'Ауқым бұғаттауын жасау әкімшілік мүмкіндігі өшірілген.',
+'ipb_expiry_invalid' => 'Бітетін уақыты жарамсыз.',
+'ipb_already_blocked' => '«$1» бұғатталған түге',
+'ip_range_invalid' => 'IP жай ауқымы жарамсыз.',
+'proxyblocker' => 'Прокси серверлерді бұғаттауыш',
+'ipb_cant_unblock' => 'Қате: IP $1 бұғаттауы табылмады. Оның бұғаттауы өшірлген сияқты.',
+'proxyblockreason' => 'IP жайыңыз ашық прокси серверге жататындықтан бұғатталған. Интернет қызметін жабдықтаушыңызбен, не техникалық медеу қызметімен қатынасыңыз, және оларға осы оте күрделі қауыпсіздік шатақ туралы ақпарат беріңіз.',
+'proxyblocksuccess' => 'Бітті.',
+'sorbs' => 'DNSBL қара тізімі',
+'sorbsreason' => 'Сіздің IP жайыңыз осы торапта қолданылған DNSBL қара тізіміндегі ашық прокси-сервер деп табылады.',
+'sorbs_create_account_reason' => 'Сіздің IP жайыңыз осы торапта қолданылған DNSBL қара тізіміндегі ашық прокси-сервер деп табылады. Тіркелгі жасай алмайсыз.',
+
+# Developer tools
+'lockdb' => 'Дерекқорды құлыптау',
+'unlockdb' => 'Дерекқорды құлыптамау',
+'lockdbtext' => 'Дерекқордын құлыпталуы барлық пайдаланушының
+бет өңдеу, баптауын қалау, бақылау тізімін, тағы басқа
+дерекқорды өзгертетін мүмкіндіктерін тоқтата тұрады.
+Осы мақсатыңызды, және жөндеуіңіз біткенде
+дерекқорды ашатыңызды растаңыз.',
+'unlockdbtext' => 'Дерекқодын ашылуы барлық пайдаланушының бет өңдеу,
+баптауын қалау, бақылау тізімін, тағы басқа дерекқорды өзгертетін
+мүмкіндіктерін қайта ашады.
+Осы мақсатыңызды растаңыз.',
+'lockconfirm' => 'Иә, мен дерекқорды растан құлыптаймын.',
+'unlockconfirm' => 'Иә, мен дерекқорды растан құлыптамаймын.',
+'lockbtn' => 'Дерекқорды құлыпта',
+'unlockbtn' => 'Дерекқорды құлыптама',
+'locknoconfirm' => 'Растау белгісін қоймапсыз.',
+'lockdbsuccesssub' => 'Дерекқорды құлыптау сәтті өтті',
+'unlockdbsuccesssub' => 'Құлыпталған дерекқор ашылды',
+'lockdbsuccesstext' => 'Дерекқор құлыпталды.
+<br />Жөндеуіңіз біткеннен кейін [[{{ns:special}}:Unlockdb|құлыптауын өшіруге]] ұмытпаңыз.',
+'unlockdbsuccesstext' => 'Құлыпталған дерекқор сәтті ашылды.',
+'lockfilenotwritable' => 'Дерекқор құлыптау файлы жазылмайды. Дерекқорды құлыптау не ашу үшін, веб-сервер файлға жазу рұқсаты болу қажет.',
+'databasenotlocked' => 'Дерекқор құлыпталған жоқ.',
+
+# Make sysop
+'makesysoptitle' => 'Қатысушыны әкімші қылу',
+'makesysoptext' => 'Бұл үлгітті қарапайым қатысушыны әкімші қылу үшін төрешілер қолданады.
+Жолаққа қатысушы атын енгізіңіз де, және бұл қатысушыны әкімші қылу үшін, түймені басыңыз.',
+'makesysopname' => 'Қатысушы аты:',
+'makesysopsubmit' => 'Бұл қатысушыны әкімші қыл',
+'makesysopok' => '<b>«$1» деген қатысушы енді әкімші боп тағайындалды</b>',
+'makesysopfail' => '<b>«$1» деген қатысушы әкімші боп тағайындалмады. (Атын дұрыс енгіздіңіз бе?)</b>',
+'setbureaucratflag' => 'Қатысушыны төреші қылу',
+'rightslog' => 'Қатысушы_құқықтары_журналы',
+'rightslogtext' => 'Бұл пайдаланушы құқықтарын өзгерту журналы.',
+'rightslogentry' => ' $1 топ мүшелгін $2 дегеннен $3 дегенге өзгертті',
+'rights' => 'Құқықтары:',
+'set_user_rights' => 'Қатысушы құқықтарын тағайындау',
+'user_rights_set' => '<b>«$1» деген қатысушының құқықтары жаңартылды</b>',
+'set_rights_fail' => '<b>«$1» деген қатысушының құқықтары тағайындалмады. (Атын дұрыс енгіздіңіз бе?)</b>',
+'makesysop' => 'Қатысушыны әкімші қылу',
+'already_sysop' => 'Бұл қатысушы әкімші бопты түге',
+'already_bureaucrat' => 'Бұл қатысушы тореші бопты түге',
+'rightsnone' => '(ешқандай)',
+
+# Move page
+'movepage' => 'Бетті жылжыту',
+'movepagetext' => "Төмендегі үлгітті қолданып беттерді қайта атайды,
+барлық тарихын жаңа атауға жылжытады.
+Бұрынғы бет атауы жаңа атауға айдататын бет болады.
+Ескі атауына сілтейтін сілтемелер өзгертілмейді; жылжытудан соң
+шынжырлы айдатулар бар-жоғын тексеріңіз.
+Сілтемелер бұрынғы жолдауымен былайғы өтуін тексеруіне
+сіз міндетті боласыз.
+
+Ескеріңіз, егер жылжытылатын атауда бет болса, сол ескі бетке айдату
+болғанша және тарихы болса, бет '''жылжытылмайды'''.
+Осының мағынасы: егер бетті қателік пен қайта аталса,
+бұрынғы атауына қайта атауға болады,
+бірақ бар беттің үстіне жазуға болмайды.
+
+<b>НАЗАР САЛЫҢЫЗ!</b>
+Бұл дәріпті бетке қатаң және кенет өзгеріс жасауға мүмкін;
+әрекеттің алдынан осының зардаптарын түсінгеніңізге батыл
+болыңыз.",
+'movepagetalktext' => "Келесі себептер '''болғанша''' дейін, талқылау беті өздік түрде бірге жылжытылады:
+* Бос емес талқылау беті жаңа атауда болғанда, немесе
+* Төмендегі қабышақта белгіні аластатқанда.
+
+Осы орайда, қалауыңыз болса, бетті қолдан жылжыта не қоса аласыз.",
+'movearticle' => 'Бетті жылжыту',
+'movenologin' => 'Жүйеге кірмегенсіз',
+'movenologintext' => 'Бетті жылжыту үшін тіркелген болуыңыз және
+ [[{{ns:special}}:Userlogin|кіруіңіз]] қажет.',
+'newtitle' => 'Жаңа атауға',
+'movepagebtn' => 'Бетті жылжыт',
+'pagemovedsub' => 'Жылжыту сәтті аяқталды',
+'pagemovedtext' => '«[[$1]]» беті «[[$2]]» бетіне жылжытылды.',
+'articleexists' => 'Былай атаулы бет бар болды, не таңдаған
+атауыңыз жарамды емес.
+Басқа атау тандаңыз',
+'talkexists' => "'''Беттің өзі сәтті жылжытылды, бірақ талқылау беті бірге жылжытылмады, оның себебі жаңа атаудың талқылау беті бар түге. Бұны қолмен қосыңыз.'''",
+'movedto' => 'мынаған жылжытылды:',
+'movetalk' => 'Қатысты талқылау бетімен бірге жылжыту',
+'talkpagemoved' => 'Қатысты талқылау беті де жылжытылды.',
+'talkpagenotmoved' => 'Қатысты талқылау беті <strong>жылжытылмады</strong>.',
+'1movedto2' => '«[[$1]]» бетінде айдату қалдырып «[[$2]]» бетіне жылжытты',
+'1movedto2_redir' => '«[[$1]]» бетін «[[$2]]» айдату бетінің үстіне жылжытты',
+'movelogpage' => 'Жылжыту журналы',
+'movelogpagetext' => 'Төменде жылжытылған беттердің тізімі беріліп тұр.',
+'movereason' => 'Себебі',
+'revertmove' => 'қайтару',
+'delete_and_move' => 'Жою және жылжыту',
+'delete_and_move_text' => '==Жою қажет==
+
+Ақырғы «[[$1]]» бет атауы бар түге.
+Жылжытуға жол беру үшін жоямыз ба?',
+'delete_and_move_confirm' => 'Иә, осы бетті жой',
+'delete_and_move_reason' => 'Жылжытуға жол беру үшін жойылған',
+'selfmove' => 'Қайнар және ақырғы атауы бірдей; бет өзіне жылжытылмайды.',
+'immobile_namespace' => 'Қайнар немесе ақырғы атауы арнайы түрінде болды; осындай есім аясы жағына және жағынан беттер жылжытылмайды.',
+
+# Export
+'export' => 'Беттерді сыртқа беру',
+'exporttext' => 'XML пішіміне қапталған бөлек бет не беттер бумасы
+мәтінің және өңдеу тарихын сыртқа бере аласыз. Осыны, басқа уики-ге
+{{ns:special}}:Import page MediaWiki құралы арқылы, сырттан алуға болады.
+
+Беттерді сыртқа беру үшін, атауларын төмендегі мәтін аумағына енгізіңіз,
+бір жолда бір атау, және тандаңыз: не ағымдық нұсқасын, барлық ескі нұсқалары мен
+және тарихы жолдары мен бірге, не дәл ағымдық нұсқасын, соңғы өңдеу туралы ақпараты мен бірге.
+
+Соңғы жағдайда сілтемені де қолдануға болады, мысалы {{int:mainpage}} беті үшін [[{{ns:Special}}:Export/{{int:mainpage}}]].',
+'exportcuronly' => 'Толық тарихын емес, тек ағымдық нұсқасын кірістіріңіз',
+'exportnohistory' => "----
+'''Аңғартпа:''' Өнімділік әсері себептерінен, беттер толық тарихын сыртқа беруі өшірілген.",
+'export-submit' => 'Сыртқа бер',
+
+# Namespace 8 related
+'allmessages' => 'Жүйе хабарлары',
+'allmessagesname' => 'Атауы',
+'allmessagesdefault' => 'Әдепкі мәтіні',
+'allmessagescurrent' => 'Ағымдық мәтіні',
+'allmessagestext' => 'Мында «MediaWiki:» есім аясындағы барлық қатынаулы жүйе хабар тізімі беріліп тұр.',
+'allmessagesnotsupportedUI' => 'Your current interface language <b>$1</b> is not supported by Special:Allmessages at this site.',
+'allmessagesnotsupportedDB' => "'''wgUseDatabaseMessages''' бабы өшірілген себебінен '''{{ns:special}}:AllMessages''' сипаты сүемелденбейді.",
+'allmessagesfilter' => 'Хабарды атауы бойынша сүзгілеу:',
+'allmessagesmodified' => 'Тек өзгертілгенді көрсет',
+
+# Thumbnails
+'thumbnail-more' => 'Үлкейту',
+'missingimage' => '<b>Жоғалған сурет </b><br /><i>$1</i>',
+'filemissing' => 'Жоғалған файл',
+'thumbnail_error' => 'Нобай құру қатесі: $1',
+
+# Special:Import
+'import' => 'Беттерді сырттан алу',
+'importinterwiki' => 'Уики-тасымалдап сырттан алу',
+'import-interwiki-text' => 'Сырттан алатын уики жобасын және бет атауын тандаңыз.
+Нұсқа күн-айы және өңдеуші аттары сақталады.
+Барлық уики-тасымалдап сырттан алу әрекеттер [[{{ns:special}}:Log/import|сырттан алу журналына]] жазылып алынады.',
+'import-interwiki-history' => 'Осы беттің барлық тарихи нұсқаларын көшіру',
+'import-interwiki-submit' => 'Сырттан алу',
+'import-interwiki-namespace' => 'Мына есім аясына беттерді тасымалдау:',
+'importtext' => 'Қайнар уикиден «Special:Export» қуралын қолданып, файлды сыртқа беріңіз, дискіңізге сақтаңыз, сосын мында қотарыңыз.',
+'importstart' => 'Беттерді сырттан алуы…',
+'import-revision-count' => '$1 нұсқа',
+'importnopages' => 'Сырттан алынатын беттер жоқ.',
+'importfailed' => 'Сырттан алу сәтсіз бітті: $1',
+'importunknownsource' => 'Cырттан алу қайнар түрі танымалсыз',
+'importcantopen' => 'Сырттан алу файлы ашылмайды',
+'importbadinterwiki' => 'Жарамсыз уики-аралық сілтеме',
+'importnotext' => 'Босты, не мәтіні жоқ',
+'importsuccess' => 'Сырттан алу сәтті аяқталды!',
+'importhistoryconflict' => 'Тарихының егес нұсқалары бар (бұл бетті алдында сырттан алынған сияқты)',
+'importnosources' => 'Ешқандай уики-тасымалдап сырттан алу қайнары белгіленмеген, және тарихын тікелей қотаруы өшірілген.',
+'importnofile' => 'Сырттан алынатын файл қотарылған жоқ.',
+'importuploaderror' => 'Сырттан алу файлдың қотаруы сәтсіз бітті; осы файл мөлшері рұқсат етілген мөлшерден асуы мүмкін.',
+
+# Import log
+'importlogpage' => 'Сырттан алу журналы',
+'importlogpagetext' => 'Басқа уикилерден өңдеу тарихымен бірге беттерді әкімшілік ретінде сырттан алу.',
+'import-logentry-upload' => 'файл қотаруымен сырттан «[[$1]]» беті алынды',
+'import-logentry-upload-detail' => '$1 нұсқа',
+'import-logentry-interwiki' => 'уики-тасымалданған $1',
+'import-logentry-interwiki-detail' => '$2 дегеннен $1 нұсқа',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => '{{SITENAME}} жобасынан іздестіру [alt-f]',
+'tooltip-minoredit' => 'Осыны шағын түзету деп белгілеу [alt-i]',
+'tooltip-save' => 'Түзетуіңізді сақтау [alt-s]',
+'tooltip-preview' => 'Сақтаудың алдынан түзетуіңізді қарап шығыңыз! [alt-p]',
+'tooltip-diff' => 'Мәтінге қандай өзгерістерді жасағаныңызды қарау. [alt-v]',
+'tooltip-compareselectedversions' => 'Беттің екі нұсқасының айырмасын қарау. [alt-v]',
+'tooltip-watch' => 'Бұл бетті бақылау тізіміңізге үстеу [alt-w]',
+
+# Stylesheets
+'common.css' => '/** Мындағы CSS әмірлері барлық безендіру мәнеріндерде қолданылады */',
+'monobook.css' => '/* Мындағы CSS әмірлері «Дара кітап» безендіру мәнерін пайдаланушыларға әсер етеді */',
+
+# Metadata
+'nodublincore' => 'Осы серверге «Dublin Core RDF» мета-деректері өшірілген.',
+'nocreativecommons' => 'Осы серверге «Creative Commons RDF» мета-деректері өшірілген.',
+'notacceptable' => 'Осы уики сервері сіздің «пайдаланушы әрекеткіші» оқи алатын пішімі бар деректерді жібере алмайды.',
+
+# Attribution
+'anonymous' => '{{SITENAME}} тіркелгісіз пайдаланушы(лар)',
+'siteuser' => '{{SITENAME}} қатысушы $1',
+'lastmodifiedatby' => 'Бұл бетті $3 қатысушы соңғы өзгерткен кезі: $2, $1.', # $1 date, $2 time, $3 user
+'and' => 'және',
+'othercontribs' => 'Шығарма негізін $1 жазған.',
+'others' => 'басқалар',
+'siteusers' => '{{SITENAME}} қатысушы(лар) $1',
+'creditspage' => 'Бетті жазғандар',
+'nocredits' => 'Бұл бетті жазғандар туралы ақпарат жоқ.',
+
+# Spam protection
+'spamprotectiontitle' => '«Спам»-нан қорғайтын сүзгі',
+'spamprotectiontext' => 'Бұл беттің сақтауын «спам» сүзгісі бұғаттады. Бұның себебі сыртқы торап сілтемесінен болуы мүмкін.',
+'spamprotectionmatch' => 'Келесі «спам» мәтіні сүзгіленген: $1',
+'subcategorycount' => 'Бұл санатта {{PLURAL:$1|бір|$1}} төменгі санат бар.',
+'categoryarticlecount' => 'Бұл санатта {{PLURAL:$1|бір|$1}} бет бар.',
+'category-media-count' => 'Бұл санатта {{PLURAL:$1|бір|$1}} файл бар.',
+'listingcontinuesabbrev' => ' (жалғ.)',
+'spambot_username' => 'MediaWiki spam cleanup',
+'spam_reverting' => '$1 дегенге сілтемесі жоқ соңғы нұсқасына қайтарылды',
+'spam_blanking' => '$1 дегенге сілтемесі бар барлық нұсқалар тазартылды',
+
+# Info page
+'infosubtitle' => 'Бет туралы ақпарат',
+'numedits' => 'Түзету саны (негізгі беті): $1',
+'numtalkedits' => 'Түзету саны (талқылау беті): $1',
+'numwatchers' => 'Бақылаушы саны: $1',
+'numauthors' => 'Әртүрлі ауторлар саны (негізгі беті): $1',
+'numtalkauthors' => 'Әртүрлі аутор саны (талқылау беті): $1',
+
+# Math options
+'mw_math_png' => 'Әрқашан PNG түрімен көрсет',
+'mw_math_simple' => 'Кәдімгі болса HTML пішімімен, басқаша PNG түрімен',
+'mw_math_html' => 'Ықтимал болса HTML пішімімен, басқаша PNG түрімен',
+'mw_math_source' => 'TeX пішімінде қалдыру (мәтіндік шолғыштарына)',
+'mw_math_modern' => 'Осы заманның шолғыштарына ұсынылған',
+'mw_math_mathml' => 'Ықтимал болса MathML пшімімен (сынақ түрінде)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Күзетте деп белгілеу',
+'markaspatrolledtext' => 'Осы бетті күзетуде деп белгілеу',
+'markedaspatrolled' => 'Күзетте деп белгіленді',
+'markedaspatrolledtext' => 'Талғанған нұсқа күзетте деп белгіленді.',
+'rcpatroldisabled' => 'Жуықтағы өзгерістер Күзеті өшірілген',
+'rcpatroldisabledtext' => 'Жуықтағы өзгерістер Күзеті қасиеті ағымда өшірілген.',
+'markedaspatrollederror' => 'Күзетте деп белгіленбейді',
+'markedaspatrollederrortext' => 'Күзетте деп белгілеу үшін нұсқасын енгізіңіз.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* tooltips and access keys */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','Жеке бетім');
+ta['pt-anonuserpage'] = new Array('.','Осы IP жайдың жеке беті');
+ta['pt-mytalk'] = new Array('n','Талқылау бетім');
+ta['pt-anontalk'] = new Array('n','Осы IP жай түзетулерін талқылау');
+ta['pt-preferences'] = new Array('','Баптауым');
+ta['pt-watchlist'] = new Array('l','Өзгерістерін бақылап тұрған беттер тізімім.');
+ta['pt-mycontris'] = new Array('y','Үлестерімдің тізімі');
+ta['pt-login'] = new Array('o','Кіруіңізді ұсынамыз, ол міндетті емес.');
+ta['pt-anonlogin'] = new Array('o','Кіруіңізді ұсынамыз, бірақ, ол міндетті емес.');
+ta['pt-logout'] = new Array('','Шығу');
+ta['ca-talk'] = new Array('t','Мағлұмат бетті талқылау');
+ta['ca-edit'] = new Array('e','Бұл бетті өңдей аласыз. Сақтаудың алдында «Қарап шығу» түймесін нұқыңыз.');
+ta['ca-addsection'] = new Array('+','Бұл талқылау бетінде жаңа тарау бастау.');
+ta['ca-viewsource'] = new Array('e','Бұл бет қорғалған, бірақ, қайнарын қарауға болады.');
+ta['ca-history'] = new Array('h','Бұл беттін жуықтағы нұсқалары.');
+ta['ca-protect'] = new Array('=','Бұл бетті қорғау');
+ta['ca-unprotect'] = new Array('=','Бұл бетті қорғамау');
+ta['ca-delete'] = new Array('d','Бұл бетті жою');
+ta['ca-undelete'] = new Array('d','Бұл беттің жоюдың алдындағы болған түзетулерін қайтару');
+ta['ca-move'] = new Array('m','Бұл бетті жылжыту');
+ta['ca-nomove'] = new Array('m','Бұл бетті жылжытуға рұқсатыңыз жоқ');
+ta['ca-watch'] = new Array('w','Бұл бетті бақылау тізіміңізге үстеу');
+ta['ca-unwatch'] = new Array('w','Бұл бетті бақылау тізіміңізден аластату');
+ta['ca-varlang-0'] = new Array('','Кирилл жазуы');
+ta['ca-varlang-1'] = new Array('','Латын жазуы');
+ta['ca-varlang-2'] = new Array('','Араб жазуы');
+ta['search'] = new Array('f','Осы уикиден іздеу');
+ta['p-logo'] = new Array('','Басты бетке');
+ta['n-mainpage'] = new Array('z','Басты бетке барып кетіңіз');
+ta['n-portal'] = new Array('','Жоба туралы, не істеуіңізге болатын, қайдан табуға болатын туралы');
+ta['n-currentevents'] = new Array('','Ағымдағы оқиғаларға қатысты ақпарат');
+ta['n-recentchanges'] = new Array('r','Осы уикидегі жуықтағы өзгерістер тізімі.');
+ta['n-randompage'] = new Array('x','Кездейсоқ бетті жүктеу');
+ta['n-help'] = new Array('','Анықтама табу орны.');
+ta['n-sitesupport'] = new Array('','Бізге жәрдем етіңіз');
+ta['t-whatlinkshere'] = new Array('j','Мында сілтеген барлық беттердің тізімі');
+ta['t-recentchangeslinked'] = new Array('k','Мыннан сілтенген беттердің жуықтағы өзгерістері');
+ta['feed-rss'] = new Array('','Бұл беттің RSS арнасы');
+ta['feed-atom'] = new Array('','Бұл беттің Atom арнасы');
+ta['t-contributions'] = new Array('','Осы қатысушының үлес тізімін қарау');
+ta['t-emailuser'] = new Array('','Осы қатысушыға email жіберу');
+ta['t-upload'] = new Array('u','Сурет не медиа файлдарын қотару');
+ta['t-specialpages'] = new Array('q','Барлық арнайы беттер тізімі');
+ta['t-print'] = new Array('','Осы беттің басып шығару нұсқасы');
+ta['t-permalink'] = new Array('','Беттің осы нұсқасының тұрақты сілтемесі');
+ta['ca-nstab-main'] = new Array('c','Мағлұмат бетін қарау');
+ta['ca-nstab-user'] = new Array('c','Қатысушы бетін қарау');
+ta['ca-nstab-media'] = new Array('c','Таспа бетін қарау');
+ta['ca-nstab-special'] = new Array('','Бұл арнайы бет, беттің өзі өңделінбейді.');
+ta['ca-nstab-project'] = new Array('a','Жоба бетін қарау');
+ta['ca-nstab-image'] = new Array('c','Сурет бетін қарау');
+ta['ca-nstab-mediawiki'] = new Array('c','Жүйе хабарын қарау');
+ta['ca-nstab-template'] = new Array('c','Үлгіні қарау');
+ta['ca-nstab-help'] = new Array('c','Анықтыма бетін қарау');
+ta['ca-nstab-category'] = new Array('c','Санат бетін қарау');",
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Мындағы кез келген JavaScript әмірлері әрқайсы бет жүктелгенде барлық пайдаланушыларға жүктеледі. */
+
+// BEGIN workaround for RTL
+if (wgUserLanguage == "kk-cn"){
+ document.direction="rtl";
+ document.write(\'<style type="text/css">html {direction: rtl;}</style>\');
+ document.write(\'<link rel="stylesheet" type="text/css" href="\'+stylepath+\'/common/common_rtl.css">\');
+ document.write(\'<link rel="stylesheet" type="text/css" href="\'+stylepath+\'/\'+skin+\'/rtl.css">\');
+}
+// END workaround for RTL',
+
+# Image deletion
+'deletedrevision' => 'Мына ескі нұсқасын жойды: $1.',
+
+# Browsing diffs
+'previousdiff' => '← Алдыңғымен айырмасы',
+'nextdiff' => 'Келесімен айырмасы →',
+
+'imagemaxsize' => 'Сурет түйіндеме бетіндегі суреттің мөлшерін шектеуі:',
+'thumbsize' => 'Нобай мөлшері:',
+'showbigimage' => 'Жоғары ажыратылымды ($1×$2, $3 кБ) нұсқасын жүктеу',
+
+'newimages' => 'Ең жаңа файлдар қоймасы',
+'showhidebots' => '(боттарды $1)',
+'noimages' => 'Көретін ештеңе жоқ.',
+
+# Variants for Kazakh language
+'variantname-kk-tr' => 'Latın',
+'variantname-kk-kz' => 'Кирил',
+'variantname-kk-cn' => 'توتە',
+'variantname-kk' => 'disable',
+
+# Labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Қатысушы:',
+'speciallogtitlelabel' => 'Атау:',
+
+'passwordtooshort' => 'Құпия сөзіңіз тым қысқа. Ең кемінде $1 әріп болуы қажет.',
+
+# Media Warning
+'mediawarning' => "'''Назар салыңыз''': Бұл файл түрінде қаскүнемді әмірдің бар болуы ықтимал; файлды жегіп жүйеңізге зиян келтіруіңіз мүмкін.<hr />",
+
+'fileinfo' => '$1 кБ, MIME түрі: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Мета-деректері',
+'metadata-help' => 'Осы файлда қосымша ақпарат бар. Бәлкім, осы ақпарат файлды жасап шығару, не сандылау үшін пайдаланған сандық камера, не мәтіналғырдан алынған. Егер осы файл негізгі күйінен өзгертілген болса, кейбір ежелелері өзгертілген фотосуретке лайық болмас.',
+'metadata-expand' => 'Егжей-тегжейін көрсет',
+'metadata-collapse' => 'Егжей-тегжейін жасыр',
+'metadata-fields' => 'Осы хабарда тізімделген EXIF мета-дерек аумақтары,
+сурет беті көрсету кезінде мета-дерек кесте жасырылығанда кірістірледі.
+Басқасы әдепкіден жасырылады.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# EXIF tags
+'exif-imagewidth' => 'Ені',
+'exif-imagelength' => 'Биіктігі',
+'exif-bitspersample' => 'Құраш сайын бит саны',
+'exif-compression' => 'Қысым сұлбасы',
+'exif-photometricinterpretation' => 'Пиксел қиысуы',
+'exif-orientation' => 'Мегзеуі',
+'exif-samplesperpixel' => 'Құраш саны',
+'exif-planarconfiguration' => 'Дерек реттеуі',
+'exif-ycbcrsubsampling' => 'Y құрашының C құрашына жарнақтауы',
+'exif-ycbcrpositioning' => 'Y құрашы және C құрашы мекендеуі',
+'exif-xresolution' => 'Дерелей ажыратылымдығы',
+'exif-yresolution' => 'Тірелей ажыратылымдығы',
+'exif-resolutionunit' => 'X және Y ажыратылымдықтарығының өлшемі',
+'exif-stripoffsets' => 'Сурет дереректерінің жайғасуы',
+'exif-rowsperstrip' => 'Белдік сайын жол саны',
+'exif-stripbytecounts' => 'Қысымдалған белдік сайын байт саны',
+'exif-jpeginterchangeformat' => 'JPEG SOI дегеннен ығысуы',
+'exif-jpeginterchangeformatlength' => 'JPEG деректерінің байт саны',
+'exif-transferfunction' => 'Тасымалдау функциясы',
+'exif-whitepoint' => 'Ақ нүкте түстілігі',
+'exif-primarychromaticities' => 'Алғы шептегі түстіліктері',
+'exif-ycbcrcoefficients' => 'Түс аясын тасымалдау матрицалық еселіктері',
+'exif-referenceblackwhite' => 'Қара және ақ анықтауыш қос колемдері',
+'exif-datetime' => 'Файлдың өзгертілген күн-айы',
+'exif-imagedescription' => 'Сурет атауы',
+'exif-make' => 'Камера өндірушісі',
+'exif-model' => 'Камера үлгісі',
+'exif-software' => 'Қолданылған бағдарлама',
+'exif-artist' => 'Жығармашысы',
+'exif-copyright' => 'Жығармашылық құқықтар иесі',
+'exif-exifversion' => 'Exif нұсқасы',
+'exif-flashpixversion' => 'Сүйемделінген Flashpix нұсқасы',
+'exif-colorspace' => 'Түс аясы',
+'exif-componentsconfiguration' => 'Әрқайсы құраш мәні',
+'exif-compressedbitsperpixel' => 'Сурет қысымдау тәртібі',
+'exif-pixelydimension' => 'Суреттің жарамды ені',
+'exif-pixelxdimension' => 'Суреттің жарамды биіктігі',
+'exif-makernote' => 'Өндіруші ескертпелері',
+'exif-usercomment' => 'Пайдаланушы мәндемелері',
+'exif-relatedsoundfile' => 'Қатысты дыбыс файлы',
+'exif-datetimeoriginal' => 'Жасалған кезі',
+'exif-datetimedigitized' => 'Сандықтау кезі',
+'exif-subsectime' => 'Жасалған кезінің секунд бөлшектері',
+'exif-subsectimeoriginal' => 'Түпнұсқа кезінің секунд бөлшектері',
+'exif-subsectimedigitized' => 'Сандықтау кезінің секунд бөлшектері',
+'exif-exposuretime' => 'Ұсталым уақыты',
+'exif-exposuretime-format' => '$1 с ($2)',
+'exif-fnumber' => 'Саңылау мөлшері',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Ұсталым бағдарламасы',
+'exif-spectralsensitivity' => 'Спектр бойынша сезгіштігі',
+'exif-isospeedratings' => 'ISO жылдамдық жарнақтауы (жарық сезгіштігі)',
+'exif-oecf' => 'Оптоелектронды түрлету ықпалы',
+'exif-shutterspeedvalue' => 'Жапқыш жылдамдылығы',
+'exif-aperturevalue' => 'Саңылаулық',
+'exif-brightnessvalue' => 'Ашықтық',
+'exif-exposurebiasvalue' => 'Ұсталым өтемі',
+'exif-maxaperturevalue' => 'Барынша саңылау ашуы',
+'exif-subjectdistance' => 'Нысана қашықтығы',
+'exif-meteringmode' => 'Өлшеу тәртібі',
+'exif-lightsource' => 'Жарық көзі',
+'exif-flash' => 'Жарқылдағыш',
+'exif-focallength' => 'Шоғырлау алшақтығы',
+'exif-focallength-format' => '$1 mm',
+'exif-subjectarea' => 'Нысана ауқымы',
+'exif-flashenergy' => 'Жарқылдағыш қарқыны',
+'exif-spatialfrequencyresponse' => 'Кеңістік-жиілік әсершілігі',
+'exif-focalplanexresolution' => 'Х бойынша шоғырлау жайпақтықтың ажыратылымдығы',
+'exif-focalplaneyresolution' => 'Y бойынша шоғырлау жайпақтықтың ажыратылымдығы',
+'exif-focalplaneresolutionunit' => 'Шоғырлау жайпақтықтың ажыратылымдық өлшемі',
+'exif-subjectlocation' => 'Нысана мекендеуі',
+'exif-exposureindex' => 'Ұсталым айқындауы',
+'exif-sensingmethod' => 'Сенсордің өлшеу әдісі',
+'exif-filesource' => 'Файл қайнары',
+'exif-scenetype' => 'Сахна түрі',
+'exif-cfapattern' => 'CFA сүзгі кейіпі',
+'exif-customrendered' => 'Қосымша сурет өңдетуі',
+'exif-exposuremode' => 'Ұсталым тәртібі',
+'exif-whitebalance' => 'Ақ түсінің тендестігі',
+'exif-digitalzoomratio' => 'Сандық ауқымдау жарнақтауы',
+'exif-focallengthin35mmfilm' => '35 mm таспасының шоғырлау алшақтығы',
+'exif-scenecapturetype' => 'Түсірген сахна түрі',
+'exif-gaincontrol' => 'Сахнаны меңгеру',
+'exif-contrast' => 'Қарама-қарсылық',
+'exif-saturation' => 'Қанықтық',
+'exif-sharpness' => 'Айқындық',
+'exif-devicesettingdescription' => 'Жабдық баптау сипаттары',
+'exif-subjectdistancerange' => 'Сахна қашықтығының көлемі',
+'exif-imageuniqueid' => 'Суреттің бірегей нөмірі (ID)',
+'exif-gpsversionid' => 'GPS белгішесінің нұсқасы',
+'exif-gpslatituderef' => 'Солтүстік немесе Оңтүстік бойлығы',
+'exif-gpslatitude' => 'Бойлығы',
+'exif-gpslongituderef' => 'Шығыс немесе Батыс ендігі',
+'exif-gpslongitude' => 'Ендігі',
+'exif-gpsaltituderef' => 'Биіктік көрсетуі',
+'exif-gpsaltitude' => 'Биіктік',
+'exif-gpstimestamp' => 'GPS уақыты (атом сағаты)',
+'exif-gpssatellites' => 'Өлшеуге пйдаланылған Жер серіктері',
+'exif-gpsstatus' => 'Қабылдағыш күйі',
+'exif-gpsmeasuremode' => 'Өлшеу тәртібі',
+'exif-gpsdop' => 'Өлшеу дәлдігі',
+'exif-gpsspeedref' => 'Жылдамдылық өлшемі',
+'exif-gpsspeed' => 'GPS қабылдағыштың жылдамдылығы',
+'exif-gpstrackref' => 'Қозғалыс бағытын көрсетуі',
+'exif-gpstrack' => 'Қозғалыс бағыты',
+'exif-gpsimgdirectionref' => 'Сурет бағытын көрсетуі',
+'exif-gpsimgdirection' => 'Сурет бағыты',
+'exif-gpsmapdatum' => 'Пайдаланылған геодезиялық түсірме деректері',
+'exif-gpsdestlatituderef' => 'Нысана бойлығын көрсетуі',
+'exif-gpsdestlatitude' => 'Нысана бойлығы',
+'exif-gpsdestlongituderef' => 'Нысана ендігін көрсетуі',
+'exif-gpsdestlongitude' => 'Нысана ендігі',
+'exif-gpsdestbearingref' => 'Нысана азимутын көрсетуі',
+'exif-gpsdestbearing' => 'Нысана азимуты',
+'exif-gpsdestdistanceref' => 'Нысана қашықтығын көрсетуі',
+'exif-gpsdestdistance' => 'Нысана қашықтығы',
+'exif-gpsprocessingmethod' => 'GPS өңдету әдісінің атауы',
+'exif-gpsareainformation' => 'GPS аумағының атауы',
+'exif-gpsdatestamp' => 'GPS күн-айы',
+'exif-gpsdifferential' => 'GPS сараланған түзету',
+
+# EXIF attributes
+'exif-compression-1' => 'Ұлғайтылған',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Қалыпты', # 0th row: top; 0th column: left
+'exif-orientation-2' => 'Дерелей шағылысқан', # 0th row: top; 0th column: right
+'exif-orientation-3' => '180° бұрышқа айналған', # 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Тірелей шағылысқан', # 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Сағат тілшесіне қарсы 90° бұрышқа айналған және тірелей шағылысқан', # 0th row: left; 0th column: top
+'exif-orientation-6' => 'Сағат тілше бойынша 90° бұрышқа айналған', # 0th row: right; 0th column: top
+'exif-orientation-7' => 'Сағат тілше бойынша 90° бұрышқа айналған және тірелей шағылысқан', # 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Сағат тілшесіне қарсы 90° бұрышқа айналған', # 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'талпақ пішім',
+'exif-planarconfiguration-2' => 'тайпақ пішім',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'бар болмады',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Анықталмаған',
+'exif-exposureprogram-1' => 'Қолмен',
+'exif-exposureprogram-2' => 'Бағдарламалы әдіс (қалыпты)',
+'exif-exposureprogram-3' => 'Саңылау басыңқылығы',
+'exif-exposureprogram-4' => 'Ысырма басыңқылығы',
+'exif-exposureprogram-5' => 'Өнер бағдарламасы (анықтық терендігіне санасқан)',
+'exif-exposureprogram-6' => 'Қимыл бағдарламасы (жапқыш шапшандылығына санасқан)',
+'exif-exposureprogram-7' => 'Тірелей әдісі (арты шоғырлаусыз таяу түсірмелер)',
+'exif-exposureprogram-8' => 'Дерелей әдісі (арты шоғырланған дерелей түсірмелер)',
+
+'exif-subjectdistance-value' => '$1 m',
+
+'exif-meteringmode-0' => 'Белгісіз',
+'exif-meteringmode-1' => 'Біркелкі',
+'exif-meteringmode-2' => 'Бұлдыр дақ',
+'exif-meteringmode-3' => 'БірДақты',
+'exif-meteringmode-4' => 'КөпДақты',
+'exif-meteringmode-5' => 'Өрнекті',
+'exif-meteringmode-6' => 'Жыртынды',
+'exif-meteringmode-255' => 'Басқа',
+
+'exif-lightsource-0' => 'Белгісіз',
+'exif-lightsource-1' => 'Күн жарығы',
+'exif-lightsource-2' => 'Күнжарықты шам',
+'exif-lightsource-3' => 'Қыздырғышты шам',
+'exif-lightsource-4' => 'Жарқылдағыш',
+'exif-lightsource-9' => 'Ашық күн',
+'exif-lightsource-10' => 'Бұлынғыр күн',
+'exif-lightsource-11' => 'Көленкелі',
+'exif-lightsource-12' => 'Күнжарықты шам (D 5700–7100 K)',
+'exif-lightsource-13' => 'Күнжарықты шам (N 4600–5400 K)',
+'exif-lightsource-14' => 'Күнжарықты шам (W 3900–4500 K)',
+'exif-lightsource-15' => 'Күнжарықты шам (WW 3200–3700 K)',
+'exif-lightsource-17' => 'Қалыпты жарық қайнары A',
+'exif-lightsource-18' => 'Қалыпты жарық қайнары B',
+'exif-lightsource-19' => 'Қалыпты жарық қайнары C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'Студиялық ISO күнжарықты шам',
+'exif-lightsource-255' => 'Басқа жарық қайнары',
+
+'exif-focalplaneresolutionunit-2' => 'дюйм',
+
+'exif-sensingmethod-1' => 'Анықталмаған',
+'exif-sensingmethod-2' => '1-чипті аумақты түссезгіш',
+'exif-sensingmethod-3' => '2-чипті аумақты түссезгіш',
+'exif-sensingmethod-4' => '3-чипті аумақты түссезгіш',
+'exif-sensingmethod-5' => 'Кезекті аумақты түссезгіш',
+'exif-sensingmethod-7' => '3-сызықты түссезгіш',
+'exif-sensingmethod-8' => 'Кезекті сызықты түссезгіш',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'Тікелей түсірілген фотосурет',
+
+'exif-customrendered-0' => 'Қалыпты өңдету',
+'exif-customrendered-1' => 'Қосымша өңдету',
+
+'exif-exposuremode-0' => 'Өздік ұсталымдау',
+'exif-exposuremode-1' => 'Қолмен ұсталымдау',
+'exif-exposuremode-2' => 'Өздік жарқылдау',
+
+'exif-whitebalance-0' => 'Ақ түсінің өздік тендестіру',
+'exif-whitebalance-1' => 'Ақ түсінің қолмен тендестіру',
+
+'exif-scenecapturetype-0' => 'Қалыпты',
+'exif-scenecapturetype-1' => 'Дерелей',
+'exif-scenecapturetype-2' => 'Тірелей',
+'exif-scenecapturetype-3' => 'Түнгі сахна',
+
+'exif-gaincontrol-0' => 'Жоқ',
+'exif-gaincontrol-1' => 'Төмен зораю',
+'exif-gaincontrol-2' => 'Жоғары зораю',
+'exif-gaincontrol-3' => 'Төмен баяулау',
+'exif-gaincontrol-4' => 'Жоғары баяулау',
+
+'exif-contrast-0' => 'Қалыпты',
+'exif-contrast-1' => 'Ұян',
+'exif-contrast-2' => 'Тұрпайы',
+
+'exif-saturation-0' => 'Қалыпты',
+'exif-saturation-1' => 'Төмен қанықты',
+'exif-saturation-2' => 'Жоғары қанықты',
+
+'exif-sharpness-0' => 'Қалыпты',
+'exif-sharpness-1' => 'Ұян',
+'exif-sharpness-2' => 'Тұрпайы',
+
+'exif-subjectdistancerange-0' => 'Белгісіз',
+'exif-subjectdistancerange-1' => 'Таяу түсірілген',
+'exif-subjectdistancerange-2' => 'Жақын түсірілген',
+'exif-subjectdistancerange-3' => 'Алыс түсірілген',
+
+# Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Солтүстік бойлығы',
+'exif-gpslatitude-s' => 'Оңтүстік бойлығы',
+
+# Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Шығыс ендігі',
+'exif-gpslongitude-w' => 'Батыс ендігі',
+
+'exif-gpsstatus-a' => 'Өлшеу ұласуда',
+'exif-gpsstatus-v' => 'Өлшеу өзара әрекетте',
+
+'exif-gpsmeasuremode-2' => '2-бағыттық өлшем',
+'exif-gpsmeasuremode-3' => '3-бағыттық өлшем',
+
+# Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'km/h',
+'exif-gpsspeed-m' => 'mil/h',
+'exif-gpsspeed-n' => 'Ж. түйін',
+
+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Шын бағыт',
+'exif-gpsdirection-m' => 'Магнитты бағыт',
+
+# External editor support
+'edit-externally' => 'Бұл файлды сыртқы құрал/бағдарлама арқылы өңдеу',
+'edit-externally-help' => 'Көбірек ақпарат үшін [http://meta.wikimedia.org/wiki/Help:External_editors орнату нұсқауларын] қараңыз.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'барлығын',
+'imagelistall' => 'барлығы',
+'watchlistall1' => 'барлығы',
+'watchlistall2' => 'барлық',
+'namespacesall' => 'барлығы',
+
+# E-mail address confirmation
+'confirmemail' => 'Е-пошта жайын куәландыру',
+'confirmemail_noemail' => '[[{{ns:special}}:Preferences|Қатысушы баптауыңызда]] жарамды е-пошта жайын енгізбепсіз.',
+'confirmemail_text' => 'Бұл уикиде е-пошта қасиеттерін пайдаланудың алдынан е-пошта жайыңызды
+куәландыру қажет. Өзіңіздің жайыңызға куәландыру хатын жіберу үшін төмендегі түймені нұқыңыз.
+Хаттың ішінде арнайы коды бар сілтеме кірістірледі; е-пошта жайыңыздың жарамдығын куәландыру үшін
+сілтемені шолғыштың мекен-жай жолағына енгізіп ашыңыз.',
+'confirmemail_send' => 'Куәландыру кодын жіберу',
+'confirmemail_sent' => 'Куәландыру Е-пошта хаты жіберілді.',
+'confirmemail_sendfailed' => 'Куәландыру хаты жіберілмеді. Енгізілген жайды жарамсыз әрітеріне тексеріп шығыңыз.
+
+Е-пошта қызметі қайтарғаны: $1',
+'confirmemail_invalid' => 'Куәландыру коды жарамсыз. Кодтың мерзімі біткен шығар.',
+'confirmemail_needlogin' => 'Е-пошта жайыңызды куәландыру үшін $1 қажет.',
+'confirmemail_success' => 'Е-пошта жайыңыз куәландырылды. Енді Уикиге кіріп жұмысқа кірісуге болады',
+'confirmemail_loggedin' => 'Е-пошта жайыңыз куәландырылды.',
+'confirmemail_error' => 'Куәландыруыңызды сақтағанда белгісіз қате болды.',
+'confirmemail_subject' => '{{SITENAME}} торабынан е-пошта жайыңызды куәландыру хаты',
+'confirmemail_body' => "Кейбіреу, мына $1 IP жайынан, өзіңіз болуы мүмкін,
+{{SITENAME}} жобасындағы Е-пошта жайын қолданып «$2» тіркелгі жасапты.
+
+Осы тіркелгі растан сіздікі екенін куәландыру үшін, және {{SITENAME}} жобасының
+е-пошта қасиеттерін белсендіру үшін, мына сілтемені шолғышпен ашыңыз:
+
+$3
+
+Бұл сіздікі '''емес''' болса, сілтемеге ермеңіз. Куәландыру кодының
+мерзімі $4 кезінде бітеді.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Дәл сәйкесін сынап көріңіз',
+'searchfulltext' => 'Толық мәтінімен іздеу',
+'createarticle' => 'Бетті бастау',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Уики-ара кірегу өшірілген]',
+'scarytranscludefailed' => '[$1 бетіне үлгі өңдету сәтсіз бітті; кешіріңіз]',
+'scarytranscludetoolong' => '[URL жайы тым ұзын; кешіріңіз]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Бұл беттің аңыстаулары:<br />
+$1
+</div>',
+'trackbackremove' => '([$1 Жойылды])',
+'trackbacklink' => 'Аңыстау',
+'trackbackdeleteok' => 'Аңыстау жоюы сәтті өтті.',
+
+# Delete conflict
+'deletedwhileediting' => 'Назар салыңыз:Сіз бұл беттің өңдеуін бастағанда, осы бет жойылды!',
+'confirmrecreate' => "Сіз бұл беттің өндеуін бастағанда [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|талқылауы]]) осы бетті жойды, көрсеткен себебі:
+: ''$2''
+Осы бетті шынынан қайта жасауын растаңыз.",
+'recreate' => 'Қайта жасау',
+'tooltip-recreate' => 'Бұл бетті жойылуына қарамай қайта жасау',
+
+'unit-pixel' => ' px',
+
+# HTML dump
+'redirectingto' => '[[$1]] бетіне айдатуда…',
+
+# action=purge
+'confirm_purge' => 'Қосалқы қалтадағы осы бетін тазалаймыз ба?<br /><br />$1',
+'confirm_purge_button' => 'Жарайды',
+
+'youhavenewmessagesmulti' => '$1 дегенге жаңа хабарлар түсті',
+
+'searchcontaining' => "Мына сөзі бар бет арасынан іздеу: ''$1''.",
+'searchnamed' => "Мына атаулы бет арасынан іздеу: ''$1''.",
+'articletitles' => "Атаулары мынадан басталған беттер: ''$1''",
+'hideresults' => 'Нәтижелерді жасыр',
+
+# DISPLAYTITLE
+'displaytitle' => '(Бұл беттің сілтемесі: [[$1]])',
+
+'loginlanguagelabel' => 'Тіл: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; алдыңғы бетке',
+'imgmultipagenext' => 'келесі бетке &rarr;',
+'imgmultigo' => 'Өту!',
+'imgmultigotopre' => 'Мына бетке өту',
+
+# Table pager
+'ascending_abbrev' => 'өсу',
+'descending_abbrev' => 'кему',
+'table_pager_next' => 'Келесі бетке',
+'table_pager_prev' => 'Алдыңғы бетке',
+'table_pager_first' => 'Алғашқы бетке',
+'table_pager_last' => 'Соңғы бетке',
+'table_pager_limit' => 'Бет сайын $1 дана көрсет',
+'table_pager_limit_submit' => 'Өту',
+'table_pager_empty' => 'Еш нәтиже жоқ',
+
+# Auto-summaries
+'autosumm-blank' => 'Беттің барлық мағлұматын аластатты',
+'autosumm-replace' => "Бетті '$1' дегенмен алмастырды",
+'autoredircomment' => '[[$1]] дегенге айдады', # This should be changed to the new naming convention, but existed beforehand
+'autosumm-new' => 'Жаңа бет мағлұматы: $1',
+);
+
+?>
diff --git a/languages/messages/MessagesKk_tr.php b/languages/messages/MessagesKk_tr.php
new file mode 100644
index 000000000000..94c9907dc993
--- /dev/null
+++ b/languages/messages/MessagesKk_tr.php
@@ -0,0 +1,2151 @@
+<?php
+/**
+ * Kazakh (Qazaqşa)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+$fallback = 'kk-kz';
+
+$separatorTransformTable = array(
+ ',' => "\xc2\xa0",
+ '.' => ',',
+);
+
+$extraUserToggles = array(
+ 'nolangconversion'
+);
+
+$fallback8bitEncoding = 'windows-1254';
+
+$linkPrefixExtension = true;
+
+$namespaceNames = array(
+ NS_MEDIA => 'Taspa',
+ NS_SPECIAL => 'Arnaýı',
+ # NS_MAIN => '',
+ NS_TALK => 'Talqılaw',
+ NS_USER => 'Qatıswşı',
+ NS_USER_TALK => 'Qatıswşı_talqılawı',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_talqılawı',
+ NS_IMAGE => 'Swret',
+ NS_IMAGE_TALK => 'Swret_talqılawı',
+ NS_MEDIAWIKI => 'MedïaWïkï',
+ NS_MEDIAWIKI_TALK => 'MedïaWïkï_talqılawı',
+ NS_TEMPLATE => 'Ülgi',
+ NS_TEMPLATE_TALK => 'Ülgi_talqılawı',
+ NS_HELP => 'Anıqtama',
+ NS_HELP_TALK => 'Anıqtama_talqılawı',
+ NS_CATEGORY => 'Sanat',
+ NS_CATEGORY_TALK => 'Sanat_talqılawı'
+);
+
+$namespaceAliases = array(
+ # Aliases to kk-kz namespaces
+ 'Таспа' => NS_MEDIA,
+ 'Арнайы' => NS_SPECIAL,
+ 'Талқылау' => NS_TALK,
+ 'Қатысушы' => NS_USER,
+ 'Қатысушы_талқылауы' => NS_USER_TALK,
+ '$1_талқылауы' => NS_PROJECT_TALK,
+ 'Сурет' => NS_IMAGE,
+ 'Сурет_талқылауы' => NS_IMAGE_TALK,
+ 'МедиаУики' => NS_MEDIAWIKI,
+ 'МедиаУики_талқылауы' => NS_MEDIAWIKI_TALK,
+ 'Үлгі' => NS_TEMPLATE,
+ 'Үлгі_талқылауы' => NS_TEMPLATE_TALK,
+ 'Анықтама' => NS_HELP,
+ 'Анықтама_талқылауы' => NS_HELP_TALK,
+ 'Санат' => NS_CATEGORY,
+ 'Санат_талқылауы' => NS_CATEGORY_TALK,
+ # Aliases to kk-cn namespaces
+ 'تاسپا' => NS_MEDIA,
+ 'ارنايى' => NS_SPECIAL,
+ 'تالقىلاۋ' => NS_TALK,
+ 'قاتىسۋشى' => NS_USER,
+ 'قاتىسۋشى_تالقىلاۋى'=> NS_USER_TALK,
+ '$1_تالقىلاۋى' => NS_PROJECT_TALK,
+ 'سۋرەت' => NS_IMAGE,
+ 'سۋرەت_تالقىلاۋى' => NS_IMAGE_TALK,
+ 'مەدياۋيكي' => NS_MEDIAWIKI,
+ 'مەدياۋيكي_تالقىلاۋى' => NS_MEDIAWIKI_TALK,
+ 'ٴۇلگٴى' => NS_TEMPLATE,
+ 'ٴۇلگٴى_تالقىلاۋى' => NS_TEMPLATE_TALK,
+ 'انىقتاما' => NS_HELP,
+ 'انىقتاما_تالقىلاۋى' => NS_HELP_TALK,
+ 'سانات' => NS_CATEGORY,
+ 'سانات_تالقىلاۋى' => NS_CATEGORY_TALK,
+);
+
+$quickbarSettings = array(
+ 'Eşqandaý', 'Solğa bekitilgen', 'Oñğa bekitilgen', 'Solğa qalqığan', 'Oñğa qalqığan'
+);
+
+$skinNames = array(
+ 'standard' => 'Dağdılı',
+ 'nostalgia' => 'Añsaw',
+ 'cologneblue' => 'Köln zeñgirligi',
+ 'davinci' => 'Da Vïnçï',
+ 'mono' => 'Dara',
+ 'monobook' => 'Dara kitap',
+ 'myskin' => 'Öz mänerim',
+ 'chick' => 'Balapan',
+ 'simple' => 'Kädimgi'
+);
+
+$defaultDateFormat = 'ymd';
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'xg j, Y',
+ 'mdy both' => 'H:i, xg j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F, Y',
+ 'dmy both' => 'H:i, j F, Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y" j." xg j',
+ 'ymd both' => 'H:i, Y" j." xg j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'Siltemeni astınan sız:',
+'tog-highlightbroken' => 'Joqtalğan siltemelerdi <a href="" class="new">bılaý</a> pişimde (basqaşa: bılaý <a href="" class="internal">?</a> sïyaqtı).',
+'tog-justify' => 'Ejelerdi eni boýınşa twralaw',
+'tog-hideminor' => 'Jwıqtağı özgeristerde şağın tüzetwdi jasır',
+'tog-extendwatchlist' => 'Baqılaw tizimdi ulğaýt (barlıq jaramdı özgeristerdi körset)',
+'tog-usenewrc' => 'Keñeýtilgen Jwıqtağı özgerister (JavaScript)',
+'tog-numberheadings' => 'Bölim taqırıptarın özdik türde nomirle',
+'tog-showtoolbar' => 'Öñdew qwraldar jolağın körset (JavaScript)',
+'tog-editondblclick' => 'Qos nuqımdap öñdew (JavaScript)',
+'tog-editsection' => 'Bölimderdi [öñdew] siltemesimen öñdewin endir',
+'tog-editsectiononrightclick' => 'Bölim atawın oñ jaq nuqwmen<br />öñdewin endir (JavaScript)',
+'tog-showtoc' => 'Mazmunın körset (3-ten artıq bölimi barılarğa)',
+'tog-rememberpassword' => 'Kirgenimdi bul komp′ywterde umıtpa',
+'tog-editwidth' => 'Öñdew awmağı tolıq enimen',
+'tog-watchcreations' => 'Men bastağan betterdi baqılaw tizimime qos',
+'tog-watchdefault' => 'Men öñdegen betterdi baqılaw tizimime qos',
+'tog-minordefault' => 'Barlıq tüzetwlerdi ädepkiden şağın dep belgile',
+'tog-previewontop' => 'Qarap şığwdı öñdew awmağınıñ üstine sal',
+'tog-previewonfirst' => 'Birinşi öñdegende qarap şığw',
+'tog-nocache' => 'Bet qosalqı qaltasın öşir',
+'tog-enotifwatchlistpages' => 'Baqılanğan bet özgergende mağan xat jiber',
+'tog-enotifusertalkpages' => 'Talqılawım özgergende mağan xat jiber',
+'tog-enotifminoredits' => 'Şağın tüzetw twralı da mağan xat jiber',
+'tog-enotifrevealaddr' => 'E-poşta jaýımdı eskertw xatta aşıq körset',
+'tog-shownumberswatching' => 'Baqılap turğan qatıswşılardıñ sanın körset',
+'tog-fancysig' => 'Qam qoltañba (özdik siltemesiz;)',
+'tog-externaleditor' => 'Sırtqı öñdewişti ädepkiden qoldan',
+'tog-externaldiff' => 'Sırtqı aýırmağıştı ädepkiden qoldan',
+'tog-showjumplinks' => '«Ötip ketw» qatınaw siltemelerin endir',
+'tog-uselivepreview' => 'Twra qarap şığwdı qoldanw (JavaScript) (Sınaq türinde)',
+'tog-autopatrol' => 'Tüzetwimdi küzetke belgile',
+'tog-forceeditsummary' => 'Öñdew sïpattaması bos qalğanda mağan eskert',
+'tog-watchlisthideown' => 'Tüzetwimdi baqılaw tizimnen jasır',
+'tog-watchlisthidebots' => 'Bot tüzetwin baqılaw tizimnen jasır',
+'tog-nolangconversion' => 'Til türin awdarmaw',
+
+'underline-always' => 'Ärqaşan',
+'underline-never' => 'Eşqaşan',
+'underline-default' => 'Şolğış boýınşa',
+
+'skinpreview' => '(Qarap şığw)',
+
+# Dates
+'sunday' => 'Jeksenbi',
+'monday' => 'Düýsenbi',
+'tuesday' => 'Seýsenbi',
+'wednesday' => 'Särsenbi',
+'thursday' => 'Beýsenbi',
+'friday' => 'Juma',
+'saturday' => 'Senbi',
+'sun' => 'Jek',
+'mon' => 'Düý',
+'tue' => 'Beý',
+'wed' => 'Sär',
+'thu' => 'Beý',
+'fri' => 'Jum',
+'sat' => 'Sen',
+'january' => 'qañtar',
+'february' => 'aqpan',
+'march' => 'nawrız',
+'april' => 'cäwir',
+'may_long' => 'mamır',
+'june' => 'mawsım',
+'july' => 'şilde',
+'august' => 'tamız',
+'september' => 'qırküýek',
+'october' => 'qazan',
+'november' => 'qaraşa',
+'december' => 'jeltoqsan',
+'january-gen' => 'qantardıñ',
+'february-gen' => 'aqpannıñ',
+'march-gen' => 'nawrızdıñ',
+'april-gen' => 'säwirdiñ',
+'may-gen' => 'mamırdıñ',
+'june-gen' => 'mawsımnıñ',
+'july-gen' => 'şildeniñ',
+'august-gen' => 'tamızdıñ',
+'september-gen' => 'qırküýektiñ',
+'october-gen' => 'qazannıñ',
+'november-gen' => 'qaraşanıñ',
+'december-gen' => 'jeltoqsannıñ',
+'jan' => 'qan',
+'feb' => 'aqp',
+'mar' => 'naw',
+'apr' => 'cäw',
+'may' => 'mam',
+'jun' => 'maw',
+'jul' => 'şil',
+'aug' => 'tam',
+'sep' => 'qır',
+'oct' => 'qaz',
+'nov' => 'qar',
+'dec' => 'jel',
+
+# Bits of text used by many pages
+'categories' => 'Barlıq sanat tizimi',
+'pagecategories' => '{{PLURAL:$1|Sanat|Sanattar}}',
+'category_header' => '«$1» sanatındağı better',
+'subcategories' => 'Tömengi sanattar',
+'category-media-header' => '«$1» sanatındağı taspalar',
+
+'linkprefix' => '/^(.*?)([a-zäçéğıïñöşüýа-яёәіңғүұқөһA-ZÄÇÉĞİÏÑÖŞÜÝА-ЯЁӘІҢҒҮҰҚӨҺʺʹ«„]+)$/sDu',
+'mainpage' => 'Bastı bet',
+'mainpagetext' => "<big>'''MedïaWïkï bağdarlaması sätti ornatıldı.'''</big>",
+'mainpagedocfooter' => 'Wïkï bağdarlamasın paýdalanw aqparatı üşin [http://meta.wikimedia.org/wiki/Help:Contents Paýdalanwşı nusqawlarımen] tanısıñız.
+
+== Bastaw ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Baptaw qalawları tizimi]
+* [http://www.mediawiki.org/wiki/Help:FAQ MedïaWïkï JSJ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MedïaWïkï xat taratw tizimi]',
+
+'portal' => 'Qawım portalı',
+'portal-url' => '{{ns:project}}:Qawım_portalı',
+'about' => 'Biz twralı',
+'aboutsite' => '{{SITENAME}} twralı',
+'aboutpage' => '{{ns:project}}:Biz_twralı',
+'article' => 'Mağlumat',
+'help' => 'Anıqtama',
+'helppage' => '{{ns:help}}:Mazmunı',
+'bugreports' => 'Qate eseptemeleri',
+'bugreportspage' => '{{ns:project}}:Qate_eseptemeleri',
+'sitesupport' => 'Demewşilik',
+'sitesupport-url' => '{{ns:project}}:Järdem',
+'faq' => 'JSJ',
+'faqpage' => '{{ns:project}}:JSJ',
+'edithelp' => 'Öndew anıqtaması',
+'newwindow' => '(jaña terezede aşıladı)',
+'edithelppage' => '{{ns:help}}:Öñdew',
+'cancel' => 'Boldırmaw',
+'qbfind' => 'Tabw',
+'qbbrowse' => 'Şolw',
+'qbedit' => 'Öñdew',
+'qbpageoptions' => 'Osı bet',
+'qbpageinfo' => 'Mätin aralığı',
+'qbmyoptions' => 'Betterim',
+'qbspecialpages' => 'Arnaýı better',
+'moredotdotdot' => 'Köbirek…',
+'mypage' => 'Jeke betim',
+'mytalk' => 'Talqılawım',
+'anontalk' => 'IP talqılawı',
+'navigation' => 'Bağıttaw',
+
+# Metadata in edit box
+'metadata_help' => 'Meta-derekter (tüsindirmeler üşin [[{{ns:project}}:Meta-derekter]] betin qarañız):',
+
+'currentevents' => 'Ağımdağı oqïğalar',
+'currentevents-url' => 'Ağımdağı_oqïğalar',
+
+'disclaimers' => 'Jawapkerşilikten bas tartw',
+'disclaimerpage' => '{{ns:project}}:Jawapkerşilikten_bas_tartw',
+'privacy' => 'Jeke qupïyasın saqtaw',
+'privacypage' => '{{ns:project}}:Jeke_qupïyasın_saqtaw',
+'errorpagetitle' => 'Qate',
+'returnto' => '$1 degenge oralw.',
+'tagline' => '{{GRAMMAR:ablative|{{SITENAME}}}}',
+'search' => 'İzdew',
+'searchbutton' => 'İzdew',
+'go' => 'Ötw',
+'searcharticle' => 'Ötw',
+'history' => 'Bet tarïxı',
+'history_short' => 'Tarïxı',
+'updatedmarker' => 'soñğı kirgennen beri jañartılğan',
+'info_short' => 'Aqparat',
+'printableversion' => 'Basıp şığarwğa',
+'permalink' => 'Turaqtı silteme',
+'print' => 'Basıp şığarw',
+'edit' => 'Öñdew',
+'editthispage' => 'Betti öñdew',
+'delete' => 'Joyw',
+'deletethispage' => 'Betti joyw',
+'undelete_short' => '{{PLURAL:$1|Bir|$1}} tüzetwdi qaýtarw',
+'protect' => 'Qorğaw',
+'protectthispage' => 'Betti qorğaw',
+'unprotect' => 'Qorğamaw',
+'unprotectthispage' => 'Betti qorğamaw',
+'newpage' => 'Jaña bet',
+'talkpage' => 'Betti talqılaw',
+'specialpage' => 'Arnaýı bet',
+'personaltools' => 'Jeke quraldar',
+'postcomment' => 'Mändeme jiberw',
+'articlepage' => 'Mağlumat betin qaraw',
+'talk' => 'Talqılaw',
+'views' => 'Körinis',
+'toolbox' => 'Quraldar',
+'userpage' => 'Qatıswşınıñ betin qaraw',
+'projectpage' => 'Joba betin qaraw',
+'imagepage' => 'Swret betin qaraw',
+'mediawikipage' => 'Xabar betin qaraw',
+'templatepage' => 'Ülgi betin qaraw',
+'viewhelppage' => 'Anıqtama betin qaraw',
+'categorypage' => 'Sanat betin qaraw',
+'viewtalkpage' => 'Talqılaw betin qaraw',
+'otherlanguages' => 'Basqa tilderde',
+'redirectedfrom' => '($1 betinen aýdatılğan)',
+'redirectpagesub' => 'Aýdatw beti',
+'lastmodifiedat' => 'Bul bettiñ özgertilgen soñğı kezi: $2, $1.', # $1 date, $2 time
+'viewcount' => 'Bul bet {{plural:$1|bir|$1}} ret qaralğan.',
+'copyright' => 'Mağlumat $1 qujatı boýınşa qatınawlı.',
+'protectedpage' => 'Qorğawlı bet',
+'jumpto' => 'Mınağan ötip ketw:',
+'jumptonavigation' => 'bağıttaw',
+'jumptosearch' => 'izdew',
+
+'badaccess' => 'Ruqsat qatesi',
+'badaccess-group0' => 'Suranısqan äreketiñizdi jegwiñizge ruqsat etilmeýdi.',
+'badaccess-group1' => 'Suranısqan äreketiñiz $1 tobınıñ qatıswşılarına şekteledi.',
+'badaccess-group2' => 'Suranısqan äreketiñiz $1 toptarı biriniñ qatwsışılarına şekteledi.',
+'badaccess-groups' => 'Suranısqan äreketiñiz $1 toptarı biriniñ qatwsışılarına şekteledi.',
+
+'versionrequired' => 'MediaWiki $1 nusqası qajet',
+'versionrequiredtext' => 'Osı betti qoldanw üşin MediaWiki $1 nusqası qajet. [[{{ns:special}}:Version]] betin qarañız.',
+
+'ok' => 'Jaraýdı',
+'pagetitle' => '$1 — {{SITENAME}}',
+'retrievedfrom' => '«$1» degennen alınğan',
+'youhavenewmessages' => 'Sizde $1 bar ($2).',
+'newmessageslink' => 'jaña xabarlar',
+'newmessagesdifflink' => 'soñğı özgerisine',
+'editsection' => 'öñdew',
+'editold' => 'öñdew',
+'editsectionhint' => 'Bölimdi öñdew: $1',
+'toc' => 'Mazmunı',
+'showtoc' => 'körset',
+'hidetoc' => 'jasır',
+'thisisdeleted' => 'Qaraýmız ba, ne qaýtaramız ba?: $1',
+'viewdeleted' => 'Qaraýmız ba?: $1',
+'restorelink' => 'joýılğan {{PLURAL:$1|bir|$1}} tüzetw',
+'feedlinks' => 'Arna:',
+'feed-invalid' => 'Jaramsız jazılım arna türi.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Mağlumat',
+'nstab-user' => 'Jeke beti',
+'nstab-media' => 'Taspa beti',
+'nstab-special' => 'Arnaýı',
+'nstab-project' => 'Joba beti',
+'nstab-image' => 'Faýl',
+'nstab-mediawiki' => 'Jüýe xabarı',
+'nstab-template' => 'Ülgi',
+'nstab-help' => 'Anıqtama',
+'nstab-category' => 'Sanat',
+
+# Main script and global functions
+'nosuchaction' => 'Mundaý äreket joq',
+'nosuchactiontext' => 'Osı URL jaýımen engizilgen äreketti
+osı wïkï joramaldap bilmedi.',
+'nosuchspecialpage' => 'Bul arnaýı bet emes',
+'nospecialpagetext' => 'Siz suranısqan arnaýı bet jaramsız. Barlıq jaramdı arnaýı better tizimin [[{{ns:special}}:Specialpages]] betinde taba alasız.',
+
+# General errors
+'error' => 'Qate',
+'databaseerror' => 'Derekqordıñ qatesi',
+'dberrortext' => 'Derekqorğa suranıs jasalğanda sïntaksïs qatesi kezdesti.
+Bul bağdarlamanıñ qatesin körsetw mümkin.
+Derekqorğa soñğı bolğan suranıs:
+<blockquote><tt>$1</tt></blockquote>
+mına fwnkcïyasınan «<tt>$2</tt>».
+MySQL qaýtarğan qatesi «<tt>$3: $4</tt>».',
+'dberrortextcl' => 'Derekqorğa suranıs jasalğanda sïntaksïs qatesi kezdesti.
+Derekqorğa soñğı bolğan suranıs:
+«$1»
+mına fwnkcïyasınan: «$2».
+MySQL qaýtarğan qatesi «$3: $4»',
+'noconnect' => 'Ğafw etiñiz! Bul wïkïde keýbir texnïkalıq qïınşılıqtar kezdesti, sondıqtan derekqor serverine qatınasw almaýdı. <br />
+$1',
+'nodb' => '$1 derekqorı talğanbadı',
+'cachederror' => 'Tömende suranğan bettiñ qosalqı qaltadağı köşirmesi, osı bet jañartılmağan bolwı mümkin.',
+'laggedslavemode' => 'Nazar salıñız: Bette jwıqtağı jañalawlar bolmawı mümkin.',
+'readonly' => 'Derekqorı qulıptalğan',
+'enterlockreason' => 'Qulıptaw sebebin engiziñiz, qaý waqıtqa deýin
+qulıptalğanın qosa',
+'readonlytext' => 'Ağımda derekqor jaña jazba jäne tağı basqa özgerister jasawdan qulıptalınğan. Bul derekqordı jöndetw bağdarlamaların orındaw üşin bolwı mümkin, bunı bitirgennen soñ qalipti iske qaýtarıladı.
+
+Qulıptağan äkimşi bunı bılaý tüsindiredi: $1',
+'missingarticle' => 'İzdestirilgen «$1» atawlı bet mätini derekqorda tabılmadı.
+
+Bul dağdıda eskirgen aýırma siltemesine nemese joýılğan bet tarïxınıñ siltemesine
+ergennen bolwı mümkin.
+
+Eger bul boljam durıs sebep bolmasa, bağdarlamamızdağı qatege tap bolwıñız mümkin.
+Bul twralı naqtı URL jaýın körsetip äkimşige esepteme jiberiñiz.',
+'readonly_lag' => 'Jetek derekqor serverler bastawışpen qadamlanğanda osı derekqor özdik türinde qulıptalınğan',
+'internalerror' => 'İşki qate',
+'filecopyerror' => '«$1» faýlı «$2» faýlına köşirilmedi.',
+'filerenameerror' => '«$1» faýl atı «$2» atına özgertilmedi.',
+'filedeleteerror' => '«$1» faýlı joýılmaýdı.',
+'filenotfound' => '«$1» faýlı tabılmadı.',
+'unexpected' => 'Kütilmegen mağına: «$1» = «$2».',
+'formerror' => 'Qate: jiberw ülgiti emes',
+'badarticleerror' => 'Osındaý äreket mına bette atqarılmaýdı.',
+'cannotdelete' => 'Aýtılmış bet ne swret joýılmaýdı. (Bunı basqa birew joýğan şığar.)',
+'badtitle' => 'Jaramsız ataw',
+'badtitletext' => 'Suranısqan bet atawı jaramsız, bos, tilara siltemesi ne wïkï-ara atawı mültik bolğan. Atawlarda süemeldemegen birqatar äripter bolwı mümkin.',
+'perfdisabled' => 'Ğafw etiñiz! Osı qasïet, derekqordıñ jıldamılığına äser etip, eşkimge wïkïdi paýdalanwğa bermegesin, waqıtşa öşirilgen.',
+'perfdisabledsub' => 'Mında $1 betiniñ saqtalğan köşirmesi:', # obsolete?
+'perfcached' => 'Kelesi derek qosalqı qaltasınan alınğan, sondıqtan tolıqtaý jañalanmağan bolwı mümkin.',
+'perfcachedts' => 'Kelesi derek qosalqı qaltasınan alınğan, soñğı jañalanlğan kezi: $1.',
+'wrong_wfQuery_params' => 'wfQuery() fwnkcïyasında jaramsız baptar<br />
+Fwnkcïya: $1<br />
+Suranıs: $2',
+'viewsource' => 'Qaýnarın qaraw',
+'viewsourcefor' => '$1 qaýnarı',
+'protectedtext' => 'Bul bet öñdew boldırmaw üşin qulıptalınğan.
+
+Bul bettiñ qaýnarın qarawıñızğa jäne köşirip alwñızğa boladı:',
+'protectedinterface' => 'Bul bet bağdarlamanıñ tildesw mätinin jetistiredi, sondıqtan qïyanat keltirmew üşin özgertwi qulıptalğan.',
+'editinginterface' => "'''Nazar salıñız:''' Bağdarlamağa tildesw mätinin jetistiretin MediaWiki betin öñdep jatırsız. Bul bettiñ özgertwi barlıq paýdalanwşılar tildeswine äser etedi.",
+'sqlhidden' => '(SQL suranısı jasırıldı)',
+
+# Login and logout pages
+'logouttitle' => 'Qatıswşı şığwı',
+'logouttext' => '<strong>Endi jüýeden şıqtıñız.</strong><br />
+Bul komp′ywterden äli de jüýege kirmesten {{SITENAME}} jobasın
+şolwıñız mümkin, nemese basqa paýdalanwşınıñ jüýege kirwi mümkin.
+Keýbir betterde äli de jüýege kirgeniñizdeý körinwi mümkindigin
+eskertemiz; bul şolğıştıñ qosalqı qaltasın bosatw arqılı şeşiledi.',
+'welcomecreation' => '== Qoş keldiñiz, $1! ==
+
+Tirkelgiñiz jasaldı. {{SITENAME}} baptawıñızdı qalawıñızben özgertwdi umıtpañız.',
+'loginpagetitle' => 'Qatıswşı kirwi',
+'yourname' => 'Qatıswşı atıñız',
+'yourpassword' => 'Qupïya söziñiz',
+'yourpasswordagain' => 'Qupïya sözdi qaýtalap engiziñiz',
+'remembermypassword' => 'Meniñ kirgenimdi bul komp′ywterde umıtpa',
+'yourdomainname' => 'Jeli üýşigiñiz',
+'externaldberror' => 'Osında sırtqı teñdestirw derekqorında qate boldı, nemese sırtqı tirkelgiñizdi jañalawğa ruqsat joq.',
+'loginproblem' => '<b>Kirwiñiz kezinde osında qïındıqqa tap boldıq.</b><br />Tağı da qaýtalap qarañız.',
+'alreadyloggedin' => '<strong>$1 degen qatıswşı, kiripsiz tüge!<strong><br />',
+'login' => 'Kirw',
+'loginprompt' => '{{SITENAME}} torabına kirw üşin «cookies» qasïetin endirwiñiz qajet.',
+'userlogin' => 'Kirw / Tirkelgi jasaw',
+'logout' => 'Şığw',
+'userlogout' => 'Şığw',
+'notloggedin' => 'Kirmegensiz',
+'nologin' => 'Tirkelgiñiz joq pa? $1.',
+'nologinlink' => 'Jasañız',
+'createaccount' => 'Tirkelgi jasa',
+'gotaccount' => 'Tirkelgiñiz bar ma? $1.',
+'gotaccountlink' => 'Kiriñiz',
+'createaccountmail' => 'e-poştamen',
+'badretype' => 'Engizgen qupïya sözderiñiz bir birine säýkes emes.',
+'userexists' => 'Engizgen qatıswşı atıñızdı birew paýdalanıp jatır. Basqa ataw tandañız.',
+'youremail' => 'E-poşta jaýıñız *:',
+'username' => 'Qatıswşı atıñız:',
+'uid' => 'Qatıswşı teñdestirwiñiz:',
+'yourrealname' => 'Şın atıñız *:',
+'yourlanguage' => 'Tiliñiz:',
+'yourvariant' => 'Türi',
+'yournick' => 'Laqap atıñız:',
+'badsig' => 'Qam qoltañbañız jaramsız; HTML belgişelerin tekseriñiz.',
+'email' => 'E-poştañız',
+'prefs-help-email-enotif' => 'Eger sonı baptasañız, osı e-poşta jaýı sizge eskertw xat jiberwge qoldanıladı.',
+'prefs-help-realname' => '* Şın atıñız (mindetti emes): engizseñiz, şığarmañızdıñ awtorlığın belgilewi üşin qoldanıladı.',
+'loginerror' => 'Kirw qatesi',
+'prefs-help-email' => '* E-poştañız (mindetti emes): «Qatıswşı» nemese «qatıswşı talqılaw» betiñizder arqılı basqalarğa baýlanısw mümkindik beredi. Öziñizdiñ kim ekeniñizdi bildirtpeýdi.',
+'nocookiesnew' => 'Qatıswşı tirkelgisi jasaldı, tek äli kirmegensiz. {{SITENAME}} jobasına qatıswşı kirw üşin «cookies» qasïeti qajet. Şolğışıñızda «cookies» qasïeti öşirilgen. Sonı endiriñiz de jaña qatıswşı atıñızdı jäne qupïya söziñizdi engizip kiriñiz.',
+'nocookieslogin' => 'Qatıswşı kirw üşin {{SITENAME}} jobası «cookies» qasïetin qoldanadı. Şolğışıñızda «cookies» qasïeti öşirilgen. Sonı endiriñiz de qaýtalap kiriñiz.',
+'noname' => 'Qatıswşı atın durıs engizbediñiz.',
+'loginsuccesstitle' => 'Kirwiñiz sätti ötti',
+'loginsuccess' => "'''Siz endi {{SITENAME}} jobasına «$1» retinde kirip otırsız.'''",
+'nosuchuser' => 'Mında «$1» atawlı qatıswşı joq. Emleñizdi tekseriñiz, nemese jaña tirkelgi jasañız.',
+'nosuchusershort' => 'Mında «$1» degen qatıswşı atawı joq. Emleñizdi tekseriñiz.',
+'nouserspecified' => 'Qatıswşı atın engiziwiñiz qajet.',
+'wrongpassword' => 'Engizgen qupïya söz jaramsız. Qaýtalap köriñiz.',
+'wrongpasswordempty' => 'Qupïya söz bostı boptı. Qaýtalap köriñiz.',
+'mailmypassword' => 'Qupïya sözimdi xatpen jiber',
+'passwordremindertitle' => 'Qupïya söz twralı {{SITENAME}} jobasınıñ eskertwi',
+'passwordremindertext' => 'Keýbirew (IP jaýı: $1, bälkim, öziñiz bolarsız)
+{{SITENAME}} üşin bizden jaña qupïya sözin jiberwin suranısqan ($4).
+«$2» qatıswşınıñ qupïya sözi «$3» boldı endi.
+Qazir kirwiñiz jäne qupïya söziñizdi awıstrwıñız qajet.
+
+Eger basqa birew bul suranıstı jasasa, nemese qupïya söziñizdi umıtsañız da,
+jäne bunı özgertkiñiz kelmese de, osı xabarlamağa añğarmawıñızğa da boladı,
+eski qupïya söziñizdi äriğaraý qoldanıp.',
+'noemail' => 'Mında «$1» qatıswşınıñ e-poştası joq.',
+'passwordsent' => 'Jaña qupïya söz «$1» üşin
+tirkelgen e-poşta jaýına jiberildi.
+Qabıldağannan keýin kirgende sonı engiziñiz.',
+'blocked-mailpassword' => 'IP jaýıñızdan öñdew buğattalğan, sondıqtan
+qïyanatşılıqtan saqtanw üşin qupïya söz jiberw qızmetiniñ äreketi ruqsat etilmeýdi.',
+'eauthentsent' => 'Kwälandırw xatı atalğan e-poşta jaýına jiberildi.
+Basqa e-poşta xatın jiberwdiñ aldınan, tirkelgi şınınan sizdiki ekenin
+kwälandırw üşin xattağı nusqawlarğa eriñiz.',
+'throttled-mailpassword' => 'Soñğı $1 sağatta qupïya söz eskertw xatı jiberildi tüge.
+Qïyanatşılıqqa kedergi bolw üşin, $1 sağat saýın tek bir ğana qupïya söz eskertw
+xatı jiberiledi.',
+'mailerror' => 'Xat jiberw qatesi: $1',
+'acct_creation_throttle_hit' => 'Ğafw etiñiz, siz $1 tirkelgi jasapsız tüge. Onan artıq isteý almaýsız.',
+'emailauthenticated' => 'E-poşta jaýıñız kwälandırılğan kezi: $1.',
+'emailnotauthenticated' => 'E-poşta jaýıñız äli kwälandırğan joq.
+Tömendegi qasïettter üşin eşqandaý xat jiberilmeýdi.',
+'noemailprefs' => 'Osı qasïetter istewi üşin e-poşta jaýıñızdı engiziñiz.',
+'emailconfirmlink' => 'E-poşta jaýıñızdı kwälandırıñız',
+'invalidemailaddress' => 'Osı e-poşta jaýda jaramsız pişim bolğan, qabıl etilmeýdi.
+Durıs pişimdelgen jaýdı engiziñiz, ne awmaqtı bos qaldırıñız.',
+'accountcreated' => 'Tirkelgi jasaldı',
+'accountcreatedtext' => '$1 üşin qatıswşı tirkelgisi jasaldı.',
+
+# Edit page toolbar
+'bold_sample' => 'Jwan mätin',
+'bold_tip' => 'Jwan mätin',
+'italic_sample' => 'Qïğaş mätin',
+'italic_tip' => 'Qïğaş mätin',
+'link_sample' => 'Silteme atawı',
+'link_tip' => 'İşki silteme',
+'extlink_sample' => 'http://www.example.com silteme atawı',
+'extlink_tip' => 'Sırtqı silteme (aldınan http:// engizwin umıtpañız)',
+'headline_sample' => 'Taqırıp mätini',
+'headline_tip' => '1-şi deñgeýli taqırıp',
+'math_sample' => 'Formwlanı mında engiziñiz',
+'math_tip' => 'Matematïka formwlası (LaTeX)',
+'nowiki_sample' => 'Pişimdelmeýtin mätindi osında engiziñiz',
+'nowiki_tip' => 'Wïkï pişimin elemew',
+'image_sample' => 'Example.jpg',
+'image_tip' => 'Kiriktirilgen swret',
+'media_sample' => 'Example.ogg',
+'media_tip' => 'Taspa faýlınıñ siltemesi',
+'sig_tip' => 'Qoltañbañız jäne waqıt belgisi',
+'hr_tip' => 'Dereleý sızıq (ünemdi qoldanıñız)',
+
+# Edit pages
+'summary' => 'Sïpattaması',
+'subject' => 'Taqırıbı/bası',
+'minoredit' => 'Bul şağın tüzetw',
+'watchthis' => 'Betti baqılaw',
+'savearticle' => 'Betti saqta!',
+'preview' => 'Qarap şığw',
+'showpreview' => 'Qarap şığw',
+'showlivepreview' => 'Twra qarap şığw',
+'showdiff' => 'Özgeristerdi körset',
+'anoneditwarning' => "'''Nazar salıñız:''' Siz jüýege kirmegensiz. IP jaýıñız bul bettiñ öñdew tarïxında jazılıp alınadı.",
+'missingsummary' => "'''Eskertw:''' Tüzetw sïpattamasın engizbepsiz. «Saqtaw» tüýmesin tağı bassañız, tüzetwiñiz mändemesiz saqtaladı.",
+'missingcommenttext' => 'Tömende mändemeñizdi engiziñiz.',
+'missingcommentheader' => "'''Eskertw:''' Bul mändemege taqırıp/basjol jetistirmepsiz. Eger tağı da Saqtaw tüýmesin nuqısañız, tüzetwiñiz solsız saqtaladı.",
+'summary-preview' => 'Sïpattamasın qarap şığw',
+'subject-preview' => 'Taqırıbın/basın qarap şığw',
+'blockedtitle' => 'Paýdalanwşı buğattalğan',
+'blockedtext' => "<big>'''Qatıswşı atıñız ne IP jaýıñız buğattalğan.'''</big>
+
+buğattawdı $1 istegen. Belgilengen sebebi: ''$2''.
+
+Osı buğattawdı talqılaw üşin $1 degenmen ne basqa [[{{ns:project}}:Äkimşiler|äkimşimen]] qatınaswıñızğa boladı.
+[[{{ns:special:Preferences|Tirkelgi baptawların]] qoldanıp jaramdı e-poşta jaýın engizgenşe deýin
+«Qatıswşığa xat jazw» qasïetin paýdalanılmaýsız. Ağımdıq IP jaýıñız $3 bolğan. Bunı ärbir suranısıñızğa qosıñız.",
+'blockedoriginalsource' => "Tömende '''$1''' degenniñ qaýnarı körsetiledi:",
+'blockededitsource' => "Tömende '''$1''' degenge jasalğan '''tüzetwñizdiñ''' mätini körsetiledi:",
+'whitelistedittitle' => 'Öñdew üşin kirwiñiz jön.',
+'whitelistedittext' => 'Betterdi öñdew üşin $1 jön.',
+'whitelistreadtitle' => 'Oqw üşin kirwiñiz jön',
+'whitelistreadtext' => 'Betterdi oqw üşin [[{{ns:special}}:Userlogin|kirwiñiz]] jön.',
+'whitelistacctitle' => 'Sizge tirkelgi jasawğa ruqsat berilmegen',
+'whitelistacctext' => 'Osı wïkïde basqalarğa tirkelgi jasaw üşin [[{{ns:Special}}:Userlogin|kirwiñiz]] qajet jäne janasımdı ruqsattarın bïlew qajet.',
+'confirmedittitle' => 'E-poşta jaýın kwälandırw xatın qaýta öñdew qajet',
+'confirmedittext' => 'Betterdi öñdew üşin aldın ala E-poşta jaýıñızdı kwälandırwıñız qajet. Jaýıñızdı [[{{ns:Special}}:Preferences|qatıswşı baptawı]] arqılı engiziñiz jäne teksertkiñiz.',
+'loginreqtitle' => 'Kirwiñiz qajet',
+'loginreqlink' => 'kirw',
+'loginreqpagetext' => 'Basqa betterdi körw üşin siz $1 bolwıñız qajet.',
+'accmailtitle' => 'Qupïya söz jiberildi.',
+'accmailtext' => '$2 jaýına «$1» qupïya sözi jiberildi.',
+'newarticle' => '(Jaña)',
+'newarticletext' => 'Siltemege erip äli bastalmağan betke
+kelipsiz. Betti bastaw üşin, tömendegi awmaqta mätiniñizdi
+teriñiz (köbirek aqparat üşin [[{{ns:help}}:Mazmunı|kömek betin]]
+qarañız).Eger jañılğannan osında kelgen bolsañız, şolğışıñız
+«Artqa» degen tüýmesin nuqıñız.',
+'anontalkpagetext' => "----''Bul tirkelgisiz (nemese tirkelgisin qoldanbağan) paýdalanwşınıñ talqılaw beti. Osı paýdalanwşını biz tek sandıq IP jaýımen teñdestiremiz. Osındaý IP jaýlar birneşe paýdalanwşığa ortaq bolwı mümkin. Eger siz tirkelgisiz paýdalanwşı bolsañız jäne sizge qatıssız mändemeler jiberilgenin sezseñiz, basqa tirkelgisiz paýdalanwşılarmen aralastırmawı üşin [[{{ns:special}}:Userlogin|tirkelgi jasañız ne kiriñiz]].''",
+'noarticletext' => 'Bul bette ağımda eş mätin joq, basqa betterden osı bet atawın [[{{ns:special}}:Search/{{PAGENAME}}|izdep körwiñizge]] nemese osı betti [{{fullurl:{{FULLPAGENAME}}|action=edit}} tüzetwiñizge] boladı.',
+'clearyourcache' => "'''Añğartpa:''' Saqtağannan keýin özgeristerdi körw üşin şolğış qosalqı qaltasın bosatw keregi mümkin. '''Mozilla / Safari:''' ''Shift'' pernesin basıp turıp ''Reload'' (''Qaýta jüktew'') tüýmesin nuqıñız (ne ''Ctrl-Shift-R'' basıñız); ''IE:'' ''Ctrl-F5'' basıñız; '''Opera / Konqueror''' ''F5'' pernesin basıñız.",
+'usercssjsyoucanpreview' => '<strong>Basalqı:</strong> Saqtaw aldında jaña CSS/JS faýlın tekserw üşin «Qarap şığw» tüýmesin qoldanıñız.',
+'usercsspreview' => "'''Mınaw CSS mätinin tek qarap şığw ekenin umıtpañız, ol äli saqtalğan joq!'''",
+'userjspreview' => "'''Mınaw JavaScript qatıswşı bağdarlamasın tekserw/qarap şığw ekenin umıtpañız, ol äli saqtalğan joq!'''",
+'userinvalidcssjstitle' => "'''Nazar salıñız:''' Mında «$1» atawlı bezendirw mäneri joq. Paýdalanwşınıñ .css jäne .js faýl atawı kişi äripppen jazılatının umıtpañız, mısalğa {{ns:user}}:Foo/monobook.css degendi {{ns:user}}:Foo/Monobook.css degenmen salıstırıñız.",
+'updated' => '(Jañartılğan)',
+'note' => '<strong>Añğartpa:</strong>',
+'previewnote' => '<strong>Mınaw tek qarap şığw ekenin umıtpañız; tüzetwler äli saqtalğan joq!</strong>',
+'session_fail_preview' => '<strong>Ğafw etiñiz! Sessïya derekteri ısırap qalğandıqtan öñdewiñizdi jöndeý almaýmız.
+Mätiniñizdi saqtap qaýtalap köriñiz. Eger äli is ötpeýtin bolsa, şığıp jäne keri kirip köriñiz.</strong>',
+'previewconflict' => 'Bul qarap şığw joğarıdağı öñdew awmağındağı mätinge saqtağan kezindegi deý ıqpal etedi.',
+'session_fail_preview_html' => "<strong>Ğafw etiñiz! Sessïya derekteri ısırap qalğandıqtan öñdewiñizdi jöndeý almaýmız.</strong>
+
+''Osı wïkïde qam HTML endirilgen, JavaScript şabwıldardan qorğanw üşin aldın ala qarap şığw jasırılğan.''
+
+<strong>Eger bul öñdew adal talap bolsa, qaýtarıp köriñiz. Eger äli de istemese, şığıp, sosın keri kirip köriñiz.</strong>",
+'importing' => 'Sırttan alwda: $1',
+'editing' => 'Öñdewde: $1',
+'editinguser' => 'Qatıswşını öñdewde: <b>$1</b>',
+'editingsection' => 'Öñdewde: $1 (bölimi)',
+'editingcomment' => 'Öñdewde: $1 (mändemesi)',
+'editconflict' => 'Öñdew egesi: $1',
+'explainconflict' => 'Osı betti siz öñdeý bastağanda basqa keýbirew betti özgertken.
+Joğarğı awmaqta bettiñ ağımdıq mätini bar.
+Tömengi awmaqta siz özgertken mätini körsetiledi.
+Özgertwiñizdi ağımdıq mätinge üstewiñiz jön.
+"Betti saqta!" tüýmesine basqanda
+<b>tek</b> joğarğı awmaqtağı mätin saqtaladı.<br />',
+'yourtext' => 'Mätiniñiz',
+'storedversion' => 'Saqtalğan nusqası',
+'nonunicodebrowser' => '<strong>AÑĞARTPA: Şolğışıñız Unicode belgilewine üýlesimdi emes, sondıqtan latın emes äripteri bar betterdi öñdew zil bolw mümkin. Jumıs istewge ıqtïmaldıq berw üşin, <strong>tömengi öñdew awmağında ASCII emes äripter onaltılıq sanımen körsetiledi</strong>.',
+'editingold' => '<strong>AÑĞARTPA: Osı bettiñ erterek nusqasın
+öñdep jatırsız.
+Bunı saqtasañız, osı nwsqadan soñğı barlıq tüzetwler joýıladı.</strong>',
+'yourdiff' => 'Aýırmalar',
+'copyrightwarning' => '{{SITENAME}} jobasına qosılğan bükil üles $2 (köbirek aqparat üşin: $1) qujatına saý jiberilgen bolıp sanaladı. Eger jazwıñızdıñ erkin köşirilip tüzetilwin qalamasañız, mında usınbawıñız jön.<br />
+Tağı, qosqan ülesiñiz - öziñizdiñ jazğanığız, ne aşıq aqparat közderinen alınğan mağlumat bolğanın wäde etesiz.<br />
+<strong>AVTORLIQ QUQIQPEN QORĞAWLI AQPARATTI RUQSATSIZ QOSPAÑIZ!</strong>',
+'copyrightwarning2' => 'Este tursın: barlıq {{SITENAME}} jobasına berilgen ülester basqa wles berwşilermen tüzetwge, özgertwge, ne alastanwğa mümkin. Alğıssız tüzetwge enjarlan bolsañız, onda şığarmañızdı mında jarïyalamañız.<br />
+Tağı, osını öziñiz jazğanıñızdı, ne barşa qazınasınan, nemese sondaý-aq aqısız aşıq qaýnarınan köşirgeniñizdi
+däl osındaý bizge mindetteme beresiz (köbirek aqparat üşin $1 qwjatın qarañız).<br />
+<strong>AWTORLIQ QUQIQPEN QORĞAWLI AQPARATTI RUQSATSIZ QOSPAÑIZ!</strong>',
+'longpagewarning' => '<strong>NAZAR SALIÑIZ: Bul bettiñ mölşeri — $1 kïlobaýt; keýbir
+şolğıştarda bet mölşeri 32 kB jetse ne onı assa öñdew kürdeli bolwı mümkin.
+Betti birneşe kişkin bölimderge bölip köriñiz.</strong>',
+'longpageerror' => '<strong>QATE: Jiberetin mätiniñizdin mölşeri — $1 kB, eñ köbi $2 kB
+ruqsat etilgen mölşerinen asqan. Bul saqtaý alınbaýdı.</strong>',
+'readonlywarning' => '<strong>NAZAR SALIÑIZ: Derekqor jöndetw üşin qulıptalğan,
+sondıqtan däl qazir tüzetwiñizdi saqtaý almaýsız. Sosın qoldanwğa üşin mätäniñizdi köşirip,
+öz kompüteriñizde faýlğa saqtañız.</strong>',
+'protectedpagewarning' => '<strong>NAZAR SALIÑIZ: Bul bet qorğalğan. Tek äkimşi ruqsatı bar qatıswşılar öñdew jasaý aladı.</strong>',
+'semiprotectedpagewarning' => "'''Añğartpa:''' Bet [[{{ns:project}}:Jartılaý qorğaw sayasatı|qorğalğan]], sondıqtan osını tek ruqsatı bar qatıswşılar öñdeý aladı.",
+'templatesused' => 'Bul bette qoldanılğan ülgiler:',
+'templatesusedpreview' => 'Bunı qarap şığwğa qoldanılğan ülgiler:',
+'templatesusedsection' => 'Bul bölimde qoldanılğan ülgiler:',
+'edittools' => '<!-- Mındağı mağlumat öñdew jäne qotarw ülgittriñiñ astında körsetiledi. -->',
+'nocreatetitle' => 'Betti bastaw şektelgen',
+'nocreatetext' => 'Bul torapta jaña bet bastawı şektelgen.
+Keri qaýtıp bar betti öñdewiñizge boladı, nemese [[{{ns:special}}:Userlogin|kirwiñizge ne tirkelgi jasawğa]] boladı.',
+'cantcreateaccounttitle' => 'Tirkelgi jasalmadı',
+'cantcreateaccounttext' => 'Osı IP jaýdan (<b>$1</b>) tirkelgi jasawı buğattalğan.
+Bälkim sebebi, oqw ornıñızdan, nemese Ïnternet jetkizwşiden
+üzbeý buzaqılıq bolğanı.',
+
+# History pages
+'revhistory' => 'Nusqalar tarïxı',
+'viewpagelogs' => 'Osı betke qatıstı jwrnaldardı qaraw',
+'nohistory' => 'Osı bettiniñ nusqalar tarïxı joq.',
+'revnotfound' => 'Nusqa tabılmadı',
+'revnotfoundtext' => 'Osı suranısqan bettiñ eski nusqası tabılğan joq.
+Osı betti aşwğa paýdalanğan URL jaýın qaýta tekserip şığıñız.',
+'loadhist' => 'Bet tarïxın jüktewi',
+'currentrev' => 'Ağımdıq nusqası',
+'revisionasof' => '$1 kezindegi nusqası',
+'revision-info' => '$1 kezindegi $2 jasağan nusqası',
+'previousrevision' => '← Eskilew nusqası',
+'nextrevision' => 'Jañalaw nusqası →',
+'currentrevisionlink' => 'Ağımdıq nusqası',
+'cur' => 'ağım.',
+'next' => 'kel.',
+'last' => 'soñ.',
+'orig' => 'tüp.',
+'histlegend' => 'Aýırmasın körw: salıstıramın degen nusqalardı tañdap, ne <Enter> pernesin, ne tömendegi tüýmeni basıñız.<br />
+Şarttı belgiler: (ağım.) = ağımdıq nusqamen aýırması,
+(soñ.) = aldıñğı nusqamen aýırması, ş = şağın tüzetw',
+'deletedrev' => '[joýılğan]',
+'histfirst' => 'Eñ alğaşqısına',
+'histlast' => 'Eñ soñğısına',
+'rev-deleted-comment' => '(mändeme alastatıldı)',
+'rev-deleted-user' => '(qatıswşı atı alastatıldı)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Osı bettiñ nusqası jarïya murağattarınan alastatılğan.
+Bul jaýtqa [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} joyw jwrnalında] egjeý-tegjeý mälimetter bolwı mümkin.
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Osı bettiñ nusqası jarïya murağattarınan alastatılğan.
+Sonı osı toraptıñ äkimşisi bop körwiñiz mümkin;
+bul jaýtqa [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} joyw jwrnalında] egjeý-tegjeý mälmetter bolwı mümkin.
+</div>',
+'rev-delundel' => 'körset/jasır',
+
+'history-feed-title' => 'Nusqalar tarïxı',
+'history-feed-description' => 'Bul bettiñ wïkïdegi nusqalar tarïxı',
+'history-feed-item-nocomment' => '$1 degen $2 kezinde', # user at time
+'history-feed-empty' => 'Suranğan bet joq.
+Bul bet wïkïden joýılğan, nemese qaýta atalğan.
+Säýkesi bar jaña betterdi [[{{ns:special}}:Search|wïkïden izdep]] qarañız.',
+
+# Revision deletion
+'revisiondelete' => 'Nusqalardı joyw/qaýtarw',
+'revdelete-nooldid-title' => 'Nısana nusqası joq',
+'revdelete-nooldid-text' => 'Osı äreketti orındaw üşin aqırğı nusqasın
+ne nusqaların engizbepsiz.',
+'revdelete-selected' => '[[:$1]] degenniñ talğanılğan nusqası:',
+'revdelete-text' => 'Joýılğan nusqalardı äli de bet tarïxında körwge boladı,
+biraq onıñ mätin mağlumatı barşağa qatınalmaýdı.
+
+Osı wïkïdiñ basqa äkimşileri jasırın mağlumatqa qatınaý aladı,
+jäne torap operatorları qosımşa şektew endirgenşe deýin,
+osı tildesw arqılı joýılğandı keri qaýtara aladı.',
+'revdelete-legend' => 'Nusqanınıñ şektewleri:',
+'revdelete-hide-text' => 'Nusqa mätinin jasır',
+'revdelete-hide-comment' => 'Tüzetw mändemesin jasır',
+'revdelete-hide-user' => 'Öñdewşi atın (IP jaýın) jasır',
+'revdelete-hide-restricted' => 'Osı şektewlerdi barşağa sïyaqtı äkimşilerge de qoldanw',
+'revdelete-log' => 'Jwrnal mändemesi:',
+'revdelete-submit' => 'Talğanğan nusqağa qoldanw',
+'revdelete-logentry' => '[[$1]] degenge nusqa körinisin özgertti',
+
+# Diffs
+'difference' => '(Nusqalar arasındağı aýırmaşılıq)',
+'loadingrev' => 'aýırma üşin nusqa jüktew',
+'lineno' => 'Jol $1:',
+'editcurrent' => 'Osı bettiñ ağımdıq nusqasın öñdew',
+'selectnewerversionfordiff' => 'Salıstırw üşin jañalaw nusqasın talğañız',
+'selectolderversionfordiff' => 'Salıstırw üşin eskilew nusqasın talğañız',
+'compareselectedversions' => 'Tañdağan nusqalardı salıstırw',
+
+# Search results
+'searchresults' => 'İzdestirw nätïjeleri',
+'searchresulttext' => 'Osı {{SITENAME}} jobasında izdestirw twralı köbirek aqparat üşin, [[{{ns:project}}:İzdew|{{SITENAME}} izdew nusqawların]] qarañız.',
+'searchsubtitle' => "İzdestirw suranısıñız: '''[[:$1]]'''",
+'searchsubtitleinvalid' => "İzdestirw suranısıñız: '''$1'''",
+'badquery' => 'İzdestirw suranıs jaramsız pişimdelgen',
+'badquerytext' => 'Ğafw etiñiz, suranısıñızdı orındaý almadıq.
+Bul üş äripten kem sözdi izdestirwge talaptanğanıñızdan
+bolwğa mümkin, ol äli de süýemeldenbegen.
+Tağı da bul söýlemdi durıs engizbegendikten de bolwğa mümkin,
+mısalı, «balıq jäne jäne qabırşaq».
+Basqa suranıs jasap köriñiz',
+'matchtotals' => '«$1» izdestirw suranısı $2 bettiñ atawına
+jäne $3 bettiñ mätinine säýkes.',
+'noexactmatch' => "'''Osında «$1» atawlı bet joq.''' Bul betti öziñiz '''[[:$1|bastaý alasız]].'''",
+'titlematches' => 'Bet atawı säýkesi',
+'notitlematches' => 'Eş bet atawı säýkes emes',
+'textmatches' => 'Bet mätiniñ säýkesi',
+'notextmatches' => 'Eş bet mätini säýkes emes',
+'prevn' => 'aldıñğı $1',
+'nextn' => 'kelesi $1',
+'viewprevnext' => 'Körsetilwi: ($1) ($2) ($3) jazba.',
+'showingresults' => 'Tömende nömir <b>$2</b> degennen bastap <b>$1</b> nätïjege deýin körsetilgen.',
+'showingresultsnum' => 'Tömende nömir <b>$2</b> degennen bastap <b>$3</b> nätïje körsetilgen.',
+'nonefound' => "'''Añğartpa''': Tabw sätsiz bitwi jïi «bolğan» jäne «degen» sïyaqtı
+tizimdelmeýtin jalpı sözdermen izdestirwden bolwı mümkin,
+nemese birden artıq izdestirw şart sözderin egizgennen (nätïjelerde tek
+barlıq şart sözder kedesse körsetiledi) bolwı mümkin.",
+'powersearch' => 'İzdew',
+'powersearchtext' => 'Mına esim ayalarda izdew:<br />$1<br />$2 Aýdatwlardı tizimdew<br />İzdestirw suranısı: $3 $9',
+'searchdisabled' => '{{SITENAME}} jobasında işki izdewi öşirilgen. Äzirşe Google nemese Yahoo! arqılı izdewge boladı. Añğartpa: {{SITENAME}} mağlumat tizimidewleri olarda eskirgen bolwğa mümkin.',
+'blanknamespace' => '(Negizgi)',
+
+# Preferences page
+'preferences' => 'Baptawlar',
+'mypreferences' => 'Baptawım',
+'prefsnologin' => 'Kirmegensiz',
+'prefsnologintext' => 'Baptawlardı qalaw üşin aldın ala [[{{ns:special}}:Userlogin|kirwiñiz]] qajet.',
+'prefsreset' => 'Baptawlar arqawdan qaýta ornatıldı.',
+'qbsettings' => 'Mäzir aýmağı',
+'changepassword' => 'Qupïya söz özgertw',
+'skin' => 'Bezendirw',
+'math' => 'Matematïka',
+'dateformat' => 'Kün-aý pişimi',
+'datedefault' => 'Eş qalawsız',
+'datetime' => 'Waqıt',
+'math_failure' => 'Öñdetw sätsiz bitti',
+'math_unknown_error' => 'belgisiz qate',
+'math_unknown_function' => 'belgisiz fwnkcïya',
+'math_lexing_error' => 'leksïka qatesi',
+'math_syntax_error' => 'sïntaksïs qatesi',
+'math_image_error' => 'PNG awdarısı sätsiz bitti; latex, dvips, gs jäne convert bağdarlamalarınıñ mültiksiz ornatwın tekseriñiz',
+'math_bad_tmpdir' => 'Matematïkanıñ waqıtşa qaltasına jazılmadı, ne qalta jasalmadı',
+'math_bad_output' => 'Matematïkanıñ beris qaltasına jazılmadı, ne qalta jasalmadı',
+'math_notexvc' => 'texvc bağdarlaması joğaltılğan; baptaw üşin math/README qujatın qarañız.',
+'prefs-personal' => 'Jeke derekteri',
+'prefs-rc' => 'Jwıqtağı özgerister',
+'prefs-watchlist' => 'Baqılaw',
+'prefs-watchlist-days' => 'Baqılaw tiziminde körseterin kün sanı:',
+'prefs-watchlist-edits' => 'Keñeýtilgen baqılaw tizimi tüzetw körseterin sanı:',
+'prefs-misc' => 'Qosımşa',
+'saveprefs' => 'Saqta',
+'resetprefs' => 'Tasta',
+'oldpassword' => 'Ağımdıq qupïya söz:',
+'newpassword' => 'Jaña qupïya söz:',
+'retypenew' => 'Jaña qupïya sözdi qaýtalañız:',
+'textboxsize' => 'Öñdew',
+'rows' => 'Joldar:',
+'columns' => 'Bağandar:',
+'searchresultshead' => 'İzdew',
+'resultsperpage' => 'Bet saýın nätïje sanı:',
+'contextlines' => 'Nätïje saýın jol sanı:',
+'contextchars' => 'Jol saýın ärip sanı:',
+'stubthreshold' => 'Biteme körstetwin anıqtaw tabaldırığı:',
+'recentchangescount' => 'Jwıqtağı özgeristerdegi atawlar:',
+'savedprefs' => 'Baptawlarıñız saqtaldı.',
+'timezonelegend' => 'Waqıt beldewi',
+'timezonetext' => 'Jergilikti waqıtıñızben server waqıtınıñ (UTC) arasındağı sağat sanı.',
+'localtime' => 'Jergilikti waqıt',
+'timezoneoffset' => 'Iğıstırw¹',
+'servertime' => 'Server waqıtı',
+'guesstimezone' => 'Şolğıştan alıp toltırw',
+'allowemail' => 'Basqadan xat qabıldawın endirw',
+'defaultns' => 'Mına esim ayalarda ädepkiden izdew:',
+'default' => 'ädepki',
+'files' => 'Faýldar',
+
+# User rights
+'userrights-lookup-user' => 'Qatıswşı toptarın meñgerw',
+'userrights-user-editname' => 'Qatıswşı atın engiziñiz:',
+'editusergroup' => 'Qatıswşı toptarın öñdew',
+'userrights-editusergroup' => 'Qatıswşı toptarın öñdew',
+'saveusergroups' => 'Qatıswşı toptarın saqtaw',
+'userrights-groupsmember' => 'Müşeligi:',
+'userrights-groupsavailable' => 'Qatınawlı toptar:',
+'userrights-groupshelp' => 'Qatıswşını üsteýtin ne alastatın toptardı talğañız.
+Talğawı öşirilgen toptar özgertilimeýdi. Toptardıñ talğawın CTRL + Sol jaq nuqwmen öşirwiñizge boladı.',
+
+# Groups
+'group' => 'Top:',
+'group-bot' => 'Bottar',
+'group-sysop' => 'Äkimşiler',
+'group-bureaucrat' => 'Töreşiler',
+'group-all' => '(barlığı)',
+
+'group-bot-member' => 'bot',
+'group-sysop-member' => 'äkimşi',
+'group-bureaucrat-member' => 'töreşi',
+
+'grouppage-bot' => '{{ns:project}}:Bottar',
+'grouppage-sysop' => '{{ns:project}}:Äkimşiler',
+'grouppage-bureaucrat' => '{{ns:project}}:Töreşiler',
+
+# Recent changes
+'changes' => 'özgeris',
+'recentchanges' => 'Jwıqtağı özgerister',
+'recentchangestext' => 'Bul bette osı wïkïdegi bolğan jwıqtağı özgerister baýqaladı.',
+'rcnote' => '$3 kezine deýin — tömende soñğı <strong>$2</strong> kündegi, soñğı <strong>$1</strong> özgeris körsetilgen.',
+'rcnotefrom' => '<b>$2</b> kezinen beri — tömende özgerister <b>$1</b> deýin körsetilgen.',
+'rclistfrom' => '$1 kezinen beri — jaña özgeristerdi körset.',
+'rcshowhideminor' => 'Şağın tüzetwdi $1',
+'rcshowhidebots' => 'Bottardı $1',
+'rcshowhideliu' => 'Tirkelgendi $1',
+'rcshowhideanons' => 'Tirkelgisizdi $1',
+'rcshowhidepatr' => 'Küzettegi tüzetwlerdi $1',
+'rcshowhidemine' => 'Tüzetwimdi $1',
+'rclinks' => 'Soñğı $2 künde bolğan, soñğı $1 özgeristi körset<br />$3',
+'diff' => 'aýırm.',
+'hist' => 'tar.',
+'hide' => 'jasır',
+'show' => 'körset',
+'minoreditletter' => 'ş',
+'newpageletter' => 'J',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[baqılağan $1 qatıswşı]',
+'rc_categories' => 'Sanattarğa şektew ("|" belgisimen bölikteñiz)',
+'rc_categories_any' => 'Qaýsıbir',
+
+# Upload
+'upload' => 'Faýl qotarw',
+'uploadbtn' => 'Qotar!',
+'reupload' => 'Qaýtalap qotarw',
+'reuploaddesc' => 'Qotarw ülgitine oralw.',
+'uploadnologin' => 'Kirmegensiz',
+'uploadnologintext' => 'Faýl qotarw üşin
+[[{{ns:special}}:Userlogin|kirwiñiz]] qajet.',
+'upload_directory_read_only' => 'Qotarw qaltasına ($1) jazwğa veb-serverge ruqsat berilmegen.',
+'uploaderror' => 'Qotarw qatesi',
+'uploadtext' => "Tömendegi ülgit faýl qotarwğa qoldanıladı, aldındağı swretterdi qaraw üşin ne izdew üşin [[{{ns:special}}:Imagelist|qotarılğan faýldar tizimine]] barıñız, qotarw men joyw tağı da [[{{ns:special}}:Log/upload|qotarw jwrnalına]] jazılıp alınadı.
+
+Swretterdi betke kirgizw üşin, faýlğa twra baýlanıstratın
+'''<nowiki>[[{{ns:image}}:File.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:File.png|balama mätin]]</nowiki>''' nemese
+'''<nowiki>[[{{ns:media}}:File.ogg]]</nowiki>''' silteme pişimin qoldanıñız.",
+'uploadlog' => 'qotarw jwrnalı',
+'uploadlogpage' => 'Qotarw jwrnalı',
+'uploadlogpagetext' => 'Tömende jwıqtağı qotarılğan faýl tizimi.',
+'filename' => 'Faýl atı',
+'filedesc' => 'Sïpattaması',
+'fileuploadsummary' => 'Sïpattaması:',
+'filestatus' => 'Awtorlıq quqıqtarı küýi',
+'filesource' => 'Faýl qaýnarı',
+'copyrightpage' => '{{ns:project}}:Awtorlıq quqıqtar',
+'copyrightpagename' => '{{SITENAME}} awtorlıq quqıqtarı',
+'uploadedfiles' => 'Qotarılğan faýldar',
+'ignorewarning' => 'Nazar salwdı elemew jäne faýldı ärdeqaşan saqtaw.',
+'ignorewarnings' => 'Ärqaýsı nazar salwlardı elemew',
+'minlength' => 'Faýl atında eñ keminde üş ärip bolwı kerek.',
+'illegalfilename' => '«$1» faýl atawında bet atawlarında ruqsat etilmegen nışandar bar. Faýldı qaýta atañız, sosın qaýta jwktep köriñiz.',
+'badfilename' => 'Faýldıñ atı «$1» bop özgertildi.',
+'badfiletype' => '«.$1» usınılmağan swret faýlınıñ keñeýtimi.',
+'largefile' => 'Faýl mölşerin $1 Baýttan asırmawğa tırısıñız, bul faýl mölşeri $2 Baýt',
+'largefileserver' => 'Osı faýldıñ mölşeri serverdiñ qalawınan asıp ketken.',
+'emptyfile' => 'Qotarılğan faýlıñız bos sïyaqtı. Bul faýl atawı jansaq engizilgeninen bolwı mümkin. Qotarğıñız kelgen faýl şınında da osı faýl bolğanın tekserip alıñız.',
+'fileexists' => 'Osındaý atawlı faýl bar tüge. Qaýta jazwdıñ aldınan $1 tekserip şığıñız.',
+'fileexists-forbidden' => 'Osındaý atawlı faýl bar tüge. Keri qaýtıñız da, jäne osı faýldı basqa atımen qotarıñız. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Osındaý atawlı faýl ortaq faýl arqawında bar tüge. Keri qaýtıñız da, osı faýldı jaña atımen qotarıñız. [[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'Qotarw sätti ötti',
+'fileuploaded' => '«$1» faýlı sätti qotarıldı!
+Osı siltemege erip — $2, sïpattama betine barıñız da, jäne osı faýl twralı
+aqparat toltırıñız: qaýdan alınğanın, qaşan jasalğanın, kim jasağanın,
+tağı basqa biletiñizdi. Bul swret bolsa, mınadaý pişimimen kiristirwge boladı: <tt><nowiki>[[Swret:$1|thumb|Sïpattaması]]</nowiki></tt>',
+'uploadwarning' => 'Qotarw twralı nazar salw',
+'savefile' => 'Faýldı saqtaw',
+'uploadedimage' => '«[[$1]]» faýlın qotardı',
+'uploaddisabled' => 'Faýl qotarwı öşirilgen',
+'uploaddisabledtext' => 'Osı wïkïde faýl qotarwı öşirilgen.',
+'uploadscripted' => 'Osı faýlda, veb şolğıştı ağat tüsindikke keltiretiñ HTML belgilew, ne skrïpt kodı bar.',
+'uploadcorrupt' => 'Osı faýl büldirilgen, ne ädepsiz keñeýtimi bar. Faýldı tekserip, qotarwın qaýtalañız.',
+'uploadvirus' => 'Osı faýlda vïrws bolwı mümkin! Egjeý-tegjeý aqparatı: $1',
+'sourcefilename' => 'Qaýnardağı faýl atı',
+'destfilename' => 'Aqırğı faýl atı',
+'watchthisupload' => 'Osı betti baqılaw',
+'filewasdeleted' => 'Osı atawı bar faýl burın qotarılğan, sosın joýıldırılğan. Qaýta qotarw aldınan $1 degendi tekseriñiz.',
+
+'upload-proto-error' => 'Jaramsız xattamalıq',
+'upload-proto-error-text' => 'Sırttan qotarw üşin URL jaýları <code>http://</code> nemese <code>ftp://</code> degenderden bastalw qajet.',
+'upload-file-error' => 'İşki qate',
+'upload-file-error-text' => 'Serverde waqıtşa faýl jasawı işki qatege uşırastı. Bul jüýeniñ äkimşimen qatınasıñız.',
+'upload-misc-error' => 'Belgisiz qotarw qatesi',
+'upload-misc-error-text' => 'Qotarw kezinde belgisiz qate uşırastı. Qaýsı URL jaýı jaramdı jäne qatınawlı ekenin tekserip şığıñız da qaýtalap köriñiz. Eger bul mäsele älde de qalsa, jüýe äkimşimen qatınasıñız.',
+
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => 'URL jaýı jetilmedi',
+'upload-curl-error6-text' => 'Berilgen URL jaýı jetilmedi. Qaýsı URL jaýı durıs ekenin jäne torap iste ekenin qaýtalap qatañ tekseriñiz.',
+'upload-curl-error28' => 'Qotarwğa berilgen waqıt bitti',
+'upload-curl-error28-text' => 'Toraptıñ jawap berwi tım uzaq waqıtqa sozıldı. Bul torap iste ekenin tekserip şığıñız, az waqıt kidire turıñız da tağı qaýtalap köriñiz. Talabıñızdı jüktelwi azdaw kezinde qaýtalawğa bolmıs.',
+
+'license' => 'Lïcenzïyası',
+'nolicense' => 'Eşteñe talğanbağan',
+'upload_source_url' => ' (jaramdı, barşağa qatınawlı URL jaý)',
+'upload_source_file' => ' (komp′ywteriñizdegi faýl)',
+
+# Image list
+'imagelist' => 'Faýl tizimi',
+'imagelisttext' => "Tömende ''$2'' surıptalğan '''$1''' faýl tizimi.",
+'imagelistforuser' => 'Mında tek $1 jüktegen swretter körsetiledi.',
+'getimagelist' => 'faýl tizimdewi',
+'ilsubmit' => 'İzdew',
+'showlast' => 'Soñğı $1 faýl $2 surıptap körset.',
+'byname' => 'atımen',
+'bydate' => 'kün-aýmen',
+'bysize' => 'mölşerimen',
+'imgdelete' => 'joyw',
+'imgdesc' => 'sïpp.',
+'imgfile' => 'faýl',
+'imglegend' => 'Şarttı belgiler: (sïpp.) — faýl sïpattamasın körsetw/öñdew.',
+'imghistory' => 'Faýl tarïxı',
+'revertimg' => 'qaýt.',
+'deleteimg' => 'joyw',
+'deleteimgcompletely' => 'Osı faýldıñ barlıq nusqaların joý',
+'imghistlegend' => 'Şarttı belgiler: (ağım.) = ağımdıq faýl, (joyw) = eski nusqasın
+joyw, (qaý.) = eski nusqasına qaýtarw.
+<br /><i>Qotarılğan faýldı körw üşin kün-aýına nuqıñız</i>.',
+'imagelinks' => 'Siltemeleri',
+'linkstoimage' => 'Bul faýlğa kelesi better silteýdi:',
+'nolinkstoimage' => 'Bul faýlğa eş bet siltemeýdi.',
+'sharedupload' => 'Bul faýl ortaq arqawına qotarılğan sondıqtan basqa jobalarda qoldanwı mümkin.',
+'shareduploadwiki' => 'Bılaýğı aqparat üşin $1 degendi qarañız.',
+'shareduploadwiki-linktext' => 'faýl sïpattaması beti',
+'noimage' => 'Mınadaý atawlı faýl joq, $1 mümkindigiñiz bar.',
+'noimage-linktext' => 'osını qotarw',
+'uploadnewversion-linktext' => 'Bul faýldıñ jaña nusqasın qotarw',
+'imagelist_date' => 'Kün-aýı',
+'imagelist_name' => 'Atawı',
+'imagelist_user' => 'Qatıswşı',
+'imagelist_size' => 'Mölşeri (baýt)',
+'imagelist_description' => 'Sïpattaması',
+'imagelist_search_for' => 'Swretti atımen izdew:',
+
+# MIME search
+'mimesearch' => 'Faýldı MIME türimen izdew',
+'mimetype' => 'MIME türi:',
+'download' => 'jüktew',
+
+# Unwatched pages
+'unwatchedpages' => 'Baqılanbağan better',
+
+# List redirects
+'listredirects' => 'Aýdatw bet tizimi',
+
+# Unused templates
+'unusedtemplates' => 'Paýdalanılmağan ülgiler',
+'unusedtemplatestext' => 'Bul bet basqa betke kirictirilmegen ülgi esim ayaısındağı barlıq betterdi tizimdeýdi. Ülgilerdi joyw aldınan bunıñ basqa siltemelerin tekserip şığwın umıtpañız',
+'unusedtemplateswlh' => 'basqa siltemeler',
+
+# Random redirect
+'randomredirect' => 'Kezdeýsoq aýdatw',
+
+# Statistics
+'statistics' => 'Joba sanağı',
+'sitestats' => '{{SITENAME}} sanağı',
+'userstats' => 'Qatıswşı sanağı',
+'sitestatstext' => "Mındağı derekqorda bulaýşa '''$1''' bet bar.
+Bunıñ işinde «talqılaw» betteri, {{SITENAME}} jobası twralı better, kişkene «biteme»
+better, aýdatwlar, mağlumat bet dep sanalmaýtın, bälkim, tağı da basqalar.
+Osını esepten şığarğanda, mında mağlumattı dep sanalatın
+'''$2''' bet bar şığar.
+
+Torapqa '''$8''' faýl qotarılğan.
+
+Osı wïkï jobası ornatılğannan beri bulaýşa better '''$3''' ret qaralğan,
+jäne better '''$4''' ret öñdelgen.
+Bunıñ nätïjesinde orta eseppen bir bet saýın '''$5''' öñdew istelingen, jäne bir öñdew saýın '''$6''' ret qaraw kelgen.
+
+Ağımdıq [http://meta.wikimedia.org/wiki/Help:Job_queue tapsırım kezegi] uzındılığı: '''$7'''.",
+'userstatstext' => "Mında '''$1''' tirkelgen qatıswşı bar, sonıñ işinde
+'''$2''' (nemese '''$4 %''') $5 bar.",
+'statistics-mostpopular' => 'Eñ köp qaralğan better',
+
+'disambiguations' => 'Aýrıqtı better',
+'disambiguationspage' => '{{ns:template}}:Disambig',
+'disambiguationstext' => 'Kelesi better <i>aýrıqtı betke</i> silteýdi. Bunıñ ornına belgili taqırıpqa siltewi qajet.<br />Betke $1 siltegen jağdaýda, bet aýrıqtı dep sanaladı.<br />Basqa esim ayasınan nusqaýtın siltemeler mında <i>tizimdelmeýdi</i>.',
+
+'doubleredirects' => 'Şınjırlı aýdatwlar',
+'doubleredirectstext' => 'Ärbir joldağı birinşi men ekinşi aýdatw siltemeleri bar, sonımen birge ekinşi aýdatw mätinniñ birinşi jolı bar. Ädette birinşi silteme aýdaýtın «şın» aqırğı bettiñ atawı bolwı qajet.',
+
+'brokenredirects' => 'Eş betke keltirmeýtin aýdatwlar',
+'brokenredirectstext' => 'Kelesi aýdatwlar joq betterge silteýdi:',
+
+# Miscellaneous special pages
+'nbytes' => '$1 Baýt',
+'ncategories' => '$1 sanat',
+'nlinks' => '$1 silteme',
+'nmembers' => '$1 bwın',
+'nrevisions' => '$1 nusqa',
+'nviews' => '$1 ret qaralğan',
+'lonelypages' => 'Eş bet siltemegen better',
+'lonelypagestext' => 'Kelesi betterge osı jobadağı basqa better siltemeýdi.',
+'uncategorizedpages' => 'Eş sanatqa kirmegen better',
+'uncategorizedcategories' => 'Eş sanatqa kirmegen sanattar',
+'uncategorizedimages' => 'Eş sanatqa kirmegen swretter',
+'unusedcategories' => 'Paýdalanılmağan sanattar',
+'unusedimages' => 'Paýdalanılmağan faýldar',
+'popularpages' => 'Äýgili better',
+'wantedcategories' => 'Bastalmağan sanattar',
+'wantedpages' => 'Bastalmağan better',
+'mostlinked' => 'Eñ köp siltengen better',
+'mostlinkedcategories' => 'Eñ köp siltengen sanattar',
+'mostcategories' => 'Eñ köp sanattarğa kirgen better',
+'mostimages' => 'Eñ köp siltengen swretter',
+'mostrevisions' => 'Eñ köp tüzetilgen better',
+'allpages' => 'Barlıq bet tizimi',
+'prefixindex' => 'Bet bastaw tizimi',
+'randompage' => 'Kezdeýsoq bet',
+'shortpages' => 'Eñ qısqa better',
+'longpages' => 'Eñ ülken better',
+'deadendpages' => 'Eş betke siltemeýtin better',
+'deadendpagestext' => 'Kelesi better osı jobadağı basqa betterge siltemeýdi.',
+'listusers' => 'Barlıq qatıswşı tizimi',
+'specialpages' => 'Arnaýı better',
+'spheading' => 'Barşanıñ arnaýı betteri',
+'restrictedpheading' => 'Şektewli arnaýı better',
+'recentchangeslinked' => 'Qatıstı tüzetwler',
+'rclsub' => '(«$1» betinen siltengen betterge)',
+'newpages' => 'Eñ jaña better',
+'newpages-username' => 'Qatıswşı atı:',
+'ancientpages' => 'Eñ eski better',
+'intl' => 'Tilaralıq siltemeler',
+'move' => 'Jıljıtw',
+'movethispage' => 'Betti jıljıtw',
+'unusedimagestext' => '<p>Eskertw: Basqa veb toraptar faýldıñ
+URL jaýına tikeleý siltewi mümkin. Sondıqtan, belsendi paýdalanwına añğarmaý,
+osı tizimde qalwı mümkin.</p>',
+'unusedcategoriestext' => 'Kelesi sanat better bar bolıp tur, biraq oğan eşqandaý bet, ne sanat kirmeýdi.',
+'booksources' => 'Kitap qaýnarları',
+'categoriespagetext' => 'Osında wïkïdegi barlıq sanattarınıñ tizimi berilip tur.',
+'data' => 'Derekter',
+'userrights' => 'Qatıswşılar quqıqtarın meñgerw',
+'groups' => 'Qatıswşı toptarı',
+'booksourcetext' => 'Tömende jaña jäne qoldanğan kitaptar satatın
+toraptarınıñ siltemeleri tizimdelgen. Bul toraptarda izdelgen kitaptar
+twralı bılaýğı aqparat bolwğa mümkin.',
+'isbn' => 'ISBN belgisi',
+'alphaindexline' => '$1 — $2',
+'version' => 'Jüýe nusqası',
+'log' => 'Jwrnaldar',
+'alllogstext' => 'Birikken qotarw, joyw, qorğaw, buğattaw jäne äkimşilik jwrnaldarın körsetw.
+Jwrnal türin, qatıswşı atın, tïisti betin talğap, tarıltıp qarawıñızğa boladı.',
+'logempty' => 'Jwrnalda säýkes danalar joq.',
+
+# Special:Allpages
+'nextpage' => 'Kelesi betke ($1)',
+'allpagesfrom' => 'Mına betten bastap körsetw:',
+'allarticles' => 'Barlıq bet tizimi',
+'allinnamespace' => 'Barlıq bet ($1 esim ayası)',
+'allnotinnamespace' => 'Barlıq bet ($1 esim ayasınan tıs)',
+'allpagesprev' => 'Aldıñğığa',
+'allpagesnext' => 'Kelesige',
+'allpagessubmit' => 'Ötw',
+'allpagesprefix' => 'Mınadan bastalğan betterdi körsetw:',
+'allpagesbadtitle' => 'Alınğan bet atawı jaramsız bolğan, nemese til-aralıq ne wïkï-aralıq bastawı bar boldı. Atawda qoldanwğa bolmaýtın nışandar bolwı mümkin.',
+
+# Special:Listusers
+'listusersfrom' => 'Mına qatıswşıdan bastap körsetw:',
+
+# E-mail user
+'mailnologin' => 'E-poşta jaýı jiberilgen joq',
+'mailnologintext' => 'Basqa qatıswşığa xat jiberw üşin
+[[{{ns:special}}:Userlogin|kirwiñiz]] qajet, jäne [[{{ns:special}}:Preferences|baptawıñızda]]
+kwälandırılğan e-poşta jaýı bolwı jön.',
+'emailuser' => 'Qatıswşığa xat jazw',
+'emailpage' => 'Qatıswşığa xat jiberw',
+'emailpagetext' => 'Eger bul qatıswşı baptawlarında kwälandırğan e-poşta
+jaýın engizse, tömendegi ülgit arqılı buğan jalğız e-poşta xatın jiberwge boladı.
+Qatıswşı baptawıñızda engizgen e-poşta jaýıñız
+«Kimnen» degen bas jolağında körinedi, sondıqtan
+xat alwşısı twra jawap bere aladı.',
+'usermailererror' => 'Mail nısanı qate qaýtardı:',
+'defemailsubject' => '{{SITENAME}} e-poştasınıñ xatı',
+'noemailtitle' => 'Bul e-poşta jaýı emes',
+'noemailtext' => 'Osı qatıswşı jaramdı E-poşta jaýın engizbegen,
+nemese basqalardan xat qabıldawın öşirgen.',
+'emailfrom' => 'Kimnen',
+'emailto' => 'Kimge',
+'emailsubject' => 'Taqırıbı',
+'emailmessage' => 'Xat',
+'emailsend' => 'Jiberw',
+'emailccme' => 'Xatımdıñ köşirmesin mağan da jiber.',
+'emailccsubject' => '$1 degenge jiberilgen xatıñızdıñ köşirmesi: $2',
+'emailsent' => 'Xat jiberildi',
+'emailsenttext' => 'E-poşta xatıñız jiberildi.',
+
+# Watchlist
+'watchlist' => 'Baqılawım',
+'watchlistfor' => "('''$1''' baqılawları)",
+'nowatchlist' => 'Baqılaw tizimiñizde eşbir dana joq',
+'watchlistanontext' => 'Baqılaw tizimiñizdegi danalardı qaraw, ne öñdew üşin $1 qajet.',
+'watchlistcount' => "'''Baqılaw tizimiñizde (talqılaw betterdi qosa) $1 dana bar.'''",
+'clearwatchlist' => 'Baqılaw tizimin tazalaw',
+'watchlistcleartext' => 'Solardı tolıq alastatwğa batılsız ba?',
+'watchlistclearbutton' => 'Baqılaw tizimin tazalaw',
+'watchlistcleardone' => 'Baqılaw tizimiñiz tazartıldı. $1 dana alastatıldı.',
+'watchnologin' => 'Kirmegensiz',
+'watchnologintext' => 'Baqılaw tizimiñizdi özgertw üşin [[{{ns:special}}:Userlogin|kirwiñiz]] jön.',
+'addedwatch' => 'Baqılaw tizimine qosıldı',
+'addedwatchtext' => "«[[:$1]]» beti [[{{ns:special}}:Watchlist|baqılaw tizimiñizge]] qosıldı.
+Osı bettiñ jäne sonıñ talqılaw betiniñ keleşektegi özgeristeri mında tizimdeledi.
+Sonda bettiñ atawı tabwğa jeñildetip [[{{ns:special}}:Recentchanges|jwıqtağı özgerister tiziminde]]
+'''jwan ärpimen''' körsetiledi.
+
+Osı betti soñınan baqılaw tizimnen alastatıñız kelse «Baqılamaw» parağın nuqıñız.",
+'removedwatch' => 'Baqılaw tizimiñizden alastatıldı',
+'removedwatchtext' => '«[[:$1]]» beti baqılaw tizimiñizden alastatıldı.',
+'watch' => 'Baqılaw',
+'watchthispage' => 'Betti baqılaw',
+'unwatch' => 'Baqılamaw',
+'unwatchthispage' => 'Baqılawdı toqtatw',
+'notanarticle' => 'Mağlumat beti emes',
+'watchnochange' => 'Körsetilgen merzimde eşbir baqılanğan dana öñdelgen joq.',
+'watchdetails' => "* Baqılaw tiziminde (talqılaw betterisiz) '''$1''' bet bar.
+* [[{{ns:special}}:Watchlist/edit|Bükil tizimdi qaraw jäne özgertw]].
+* [[{{ns:special}}:Watchlist/clear|Tizimdegi barlıq dana alastatw]].",
+'wlheader-enotif' => '* Eskertw xat jiberwi endirilgen.',
+'wlheader-showupdated' => "* Soñğı kirgenimnen beri tüzetilgen betterdi '''jwan''' mätinmen körset",
+'watchmethod-recent' => 'baqılawlı betterdiñ jwıqtağı özgeristerin tekserw',
+'watchmethod-list' => 'jwıqtağı özgeristerde baqılawlı betterdi tekserw',
+'removechecked' => 'Belgilengendi baqılaw tiziminen alastatw',
+'watchlistcontains' => 'Baqılaw tizimiñizde $1 bet bar.',
+'watcheditlist' => "Osında älippem surıptalğan baqılanğan mağlumat betteriñiz tizimdelingen.
+Betterdi alastatw üşin onıñ qasındağı qabaşaqtardı belgilep, tömendegi ''Belgilengendi alastat'' tüýmesin nuqıñız
+(mağlumat betin joýğanda talqılaw beti de birge joýıladı).",
+'removingchecked' => 'Suranğan danalardı baqılaw tizimnen alastawı…',
+'couldntremove' => '«$1» degen dana alastatılmadı…',
+'iteminvalidname' => '«$1» danasınıñ jaramsız atawınan şataq twdı…',
+'wlnote' => 'Tömende soñğı <b>$2</b> sağattağı, soñğı $1 özgeris körsetilgen.',
+'wlshowlast' => 'Soñğı $1 sağattağı, $2 kündegi, $3 bolğan özgeristi körsetw',
+'wlsaved' => 'Bul baqılw tizimiñizdiñ saqtalğan nusqası.',
+'wlhideshowown' => 'Tüzetwimdi $1',
+'wlhideshowbots' => 'Bottardı $1',
+'wldone' => 'İs bitti.',
+
+'enotif_mailer' => '{{SITENAME}} eskertw xat jiberw qızmeti',
+'enotif_reset' => 'Barlıq bet karaldi dep belgile',
+'enotif_newpagetext' => 'Mınaw jaña bet.',
+'changed' => 'özgertti',
+'created' => 'jasadı',
+'enotif_subject' => '{{SITENAME}} jobasında $PAGEEDITOR $PAGETITLE atawlı betti $CHANGEDORCREATED',
+'enotif_lastvisited' => 'Soñğı kirwiñizden beri bolğan özgerister üşin $1 degendi qarañız.',
+'enotif_body' => 'Qurmetti $WATCHINGUSERNAME,
+
+{{SITENAME}} jobasıda $PAGEEDITDATE kezinde $PAGEEDITOR $PAGETITLE atawlı betti $CHANGEDORCREATED, ağımdıq nusqasın $PAGETITLE_URL jaýınan qarañız.
+
+$NEWPAGE
+
+Öñdewşi sïpattaması: $PAGESUMMARY $PAGEMINOREDIT
+
+Öñdewşimen qatınasw:
+e-poşta: $PAGEEDITOR_EMAIL
+wïkï: $PAGEEDITOR_WIKI
+
+Bılaýğı özgerister bolğanda da siz osı betke barğanşa deýin eşqandaý basqa eskertw xattar jiberilmeýdi. Sonımen qatar baqılaw tizimiñizdegi bet eskertpelik belgisin ädepke küýine keltiriñiz.
+
+ Sizdiñ dostı {{SITENAME}} eskertw qızmeti
+
+----
+Baqılaw tizimiñizdi baptaw üşin, mında barıñız
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Sın-pikir berw jäne bılaýğı järdem alw üşin:
+{{fullurl:{{ns:help}}:Mazmunı}}',
+
+# Delete/protect/revert
+'deletepage' => 'Betti joyw',
+'confirm' => 'Rastaw',
+'excontent' => 'bolğan mağlumatı: «$1»',
+'excontentauthor' => 'bolğan mağlumatı: «$1» (tek «[[Special:Contributions/$2|$2]]» ülesi)',
+'exbeforeblank' => 'tazartw aldındağı bolğan mağlumatı: «$1»',
+'exblank' => 'bet bostı boldı',
+'confirmdelete' => 'Joywdı rastaw',
+'deletesub' => '(«$1» joywı)',
+'historywarning' => 'Nazar salıñız: Joywğa arnalğan bette öz tarïxı bar:',
+'confirmdeletetext' => 'Betti nemese swretti barlıq tarïxımen
+birge derekqordan ärdaýım joýığıñız keletin sïyaqtı.
+Bunı joywdıñ zardabın tüsinip şın nïettengeniñizdi, jäne
+[[{{ns:project}}:Sayasat]]qa laýıqtı dep
+sengeniñizdi rastañız.',
+'actioncomplete' => 'Äreket bitti',
+'deletedtext' => '«$1» joýıldı.
+Jwıqtağı joywlar twralı jazbaların $2 degennen qarañız.',
+'deletedarticle' => '«[[$1]]» betin joýdı',
+'dellogpage' => 'Joyw_jwrnalı',
+'dellogpagetext' => 'Tömende jwıqtağı joywlardıñ tizimi berilgen.',
+'deletionlog' => 'joyw jwrnalı',
+'reverted' => 'Erterek nusqasına qaýtarılğan',
+'deletecomment' => 'Joywdıñ sebebi',
+'imagereverted' => 'Erterek nusqasına qaýtarw sätti ötti.',
+'rollback' => 'Tüzetwlerdi qaýtarw',
+'rollback_short' => 'Qaýtarw',
+'rollbacklink' => 'qaýtarw',
+'rollbackfailed' => 'Qaýtarw sätsiz ayaqtaldı',
+'cantrollback' => 'Tüzetw qaýtarılmaýdı. Bul bettiñ soñğı üleskeri tek bastawış awtorı.',
+'alreadyrolled' => '[[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|talqılawı]]) degendi jasağan [[:$1]]
+betiniñ soñğı öñdewinen qaýtarw ötpedi; keýbirew osı qazir betti öñdep ne qaýtarıp jatır tüge.
+
+Soñğı öñdewdi [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|talqılawı]]) degendi jasağan.',
+'editcomment' => 'Tüzetwdiñ bolğan mändemesi: "<i>$1</i>".', # only shown if there is an edit comment
+'revertpage' => '[[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|talqılawı]]) tüzetwinen [[{{ns:user}}:$1|$1]] soñğı nusqasına qaýtardı',
+'sessionfailure' => 'Kirw sessïyasında şataq bolğan sïyaqtı;
+sessïyağa şabwıldawdardan qorğanw üşin, osı äreket toqtatıldı.
+«Artqa» tüýmesin basıñız, jäne betti keri jükteñiz, sosın qaýtalap köriñiz.',
+'protectlogpage' => 'Qorğaw_jwrnalı',
+'protectlogtext' => 'Tömende betterdiñ qorğaw/qorğamaw tizimi berilgen.',
+'protectedarticle' => '«$1» qorğaldı',
+'unprotectedarticle' => '«[[$1]]» qorğalmadı',
+'protectsub' => '(«$1» qorğawda)',
+'confirmprotecttext' => 'Osı betti rasında da qorğaw qajet pe?',
+'confirmprotect' => 'Qorğawdı rastaw',
+'protectmoveonly' => 'Tek jıljıtwdan qorğaw',
+'protectcomment' => 'Qorğaw sebebi',
+'unprotectsub' => '(«$1» qorğamawda)',
+'confirmunprotecttext' => 'Osı betti rastan qorğamaw qajet pe?',
+'confirmunprotect' => 'Qorğamawdı rastaw',
+'unprotectcomment' => 'Qorğamaw sebebi',
+'protect-unchain' => 'Jıljıtwğa ruqsat berw',
+'protect-text' => '<strong>$1</strong> betiniñ qorğaw deñgeýin qaraý jäne özgerte alasız.',
+'protect-viewtext' => 'Tirkelgiñiz bet qorğanısı dengeýlerin özgertwge ruqsat bermeýdi.
+Mına <strong>$1</strong> bettiñ ağımdıq baptawları:',
+'protect-default' => '(ädepki)',
+'protect-level-autoconfirmed' => 'Tirkelgisiz paýdalanwşılarğa tïım',
+'protect-level-sysop' => 'Tek äkimşilerge ruqsat',
+
+# Restrictions (nouns)
+'restriction-edit' => 'Öñdew',
+'restriction-move' => 'Jıljıtw',
+
+# Undelete
+'undelete' => 'Joýılğan betterdi qaraw',
+'undeletepage' => 'Joýılğan betterdi qaraw jäne qaýtarw',
+'viewdeletedpage' => 'Joýılğan betterdi qaraw',
+'undeletepagetext' => 'Kelesi better joýıldı dep belgilengen, biraq mağlumatı murağatta jatqan,
+sondıqtan keri qaýtarwğa äzir. Murağat merzim boýınşa tazalanıp turwı mümkin.',
+'undeleteextrahelp' => "Bükil betti qaýtarw üşin, barlıq qabaşaqtardı bos qaldırıp
+'''''Qaýtar!''''' tüýmesin nuqıñız. Bölekşe qaýtarw orındaw üşin, qaýtaraýın degen nusqalarına säýkes
+qabaşaqtarın belgileñiz de, jäne '''''Qaýtar!''''' tüýmesin nuqıñız. '''''Tasta''''' tüýmesin
+nuqığanda mändeme awmağı men barlıq qabaşaqtar tazalanadı.",
+'undeletearticle' => 'Joýılğan betti qaýtarw',
+'undeleterevisions' => '$1 nusqa murağattalğan',
+'undeletehistory' => 'Eger bet mağlumatın qaýtarsañız,tarïxında barlıq nusqalar da
+qaýtarıladı. Eger joywdan soñ däl solaý atawımen jaña bet jasalsa, qaýtarılğan nusqalar
+tarïxtıñ eñ adında körsetiledi, jäne körsetilip turğan bettiñ ağımdıq nusqası
+özdik türde almastırılmaýdı.',
+'undeletehistorynoadmin' => 'Bul bet joýılğan. Joyw sebebi aldındağı öñdegen qatıswşılar
+egjeý-tegjeýlerimen birge tömendegi sïpattamasında körsetilgen.
+Osı joýılğan nusqalardıñ mätini tek äkimşilerge qatınawlı.',
+'undeleterevision' => '$1 kezindegi joýılğan nusqasın',
+'undeleterevision-missing' => 'Jaramsız ne joğalğan nusqa. Siltemeñiz jaramsız bolwı mümkin, ne
+nusqa qaýtarılğan tüge nemese murağattan alastatılğan.',
+'undeletebtn' => 'Qaýtar!',
+'undeletereset' => 'Tasta',
+'undeletecomment' => 'Mändemesi:',
+'undeletedarticle' => '«[[$1]]» qaýtardı',
+'undeletedrevisions' => '$1 nusqası qaýtarılğan',
+'undeletedrevisions-files' => '$1 nusqa jäne $2 faýl qaýtarıldı',
+'undeletedfiles' => '$1 faýl qaýtarıldı',
+'cannotundelete' => 'Qaýtarw sätsiz bitti; tağı birew sizden burın sol betti qaýtarğan bolar.',
+'undeletedpage' => "<big>'''$1 qaýtarıldı'''</big>
+
+Jwıqtağı joyw men qaýtarw jöninde [[{{ns:special}}:Log/delete|joyw jwrnalın]] qarañız.",
+
+# Namespace form on various pages
+'namespace' => 'Esim ayası:',
+'invert' => 'Talğawdı kerilew',
+
+# Contributions
+'contributions' => 'Qatıswşı ülesi',
+'mycontris' => 'Ülesim',
+'contribsub' => '$1 ülesi',
+'nocontribs' => 'Osı izdew şartına säýkes özgerister tabılğan joq.',
+'ucnote' => 'Tömende osı qatıswşınıñ soñğı <b>$2</b> kündegi, soñğı <b>$1</b> özgerisi körsetledi.',
+'uclinks' => 'Soñğı $2 kündegi, soñğı $1 özgerisin qaraw.',
+'uctop' => ' (üsti)',
+'newbies' => 'jaña qatıswşılar',
+
+'sp-newimages-showfrom' => '$1 kezinen beri — jaña swretterdi körset',
+
+'sp-contributions-newest' => 'Eñ jañasına',
+'sp-contributions-oldest' => 'Eñ eskisine',
+'sp-contributions-newer' => 'Jañalaw $1',
+'sp-contributions-older' => 'Eskilew $1',
+'sp-contributions-newbies-sub' => 'Jaña qatıswşılarğa',
+
+# What links here
+'whatlinkshere' => 'Siltegen better',
+'notargettitle' => 'Aqırğı ataw joq',
+'notargettext' => 'Osı äreket orındalatın nısana bet,
+ne qatıswşı körsetilmegen.',
+'linklistsub' => '(Siltemeler tizimi)',
+'linkshere' => "'''[[:$1]]''' degenge mına better silteýdi:",
+'nolinkshere' => "'''[[:$1]]''' degenge eş bet siltemeýdi.",
+'isredirect' => 'aýdatw beti',
+'istemplate' => 'kiriktirw',
+
+# Block/unblock
+'blockip' => 'Paýdalanwşını buğattaw',
+'blockiptext' => 'Tömendegi ülgit paýdalanwşınıñ jazw ruqsatın
+belgili IP jaýımen ne atawımen buğattaw üşin qoldanıladı.
+Bunı tek buzaqılıqqa kedergi istew üşin jäne de
+[[{{ns:project}}:Sayasat|sayasat]] boýınşa atqarwıñız jön.
+Tömende tïisti sebebin toltırıp körsetiñiz (mısalı, däýekke buzaqılıqpen
+özgertken betterdi keltirip).',
+'ipaddress' => 'IP jaý',
+'ipadressorusername' => 'IP jaý ne qatıswşı atı',
+'ipbexpiry' => 'Bitetin merzimi',
+'ipbreason' => 'Sebebi',
+'ipbanononly' => 'Tek tirkelgisizdi buğattaw',
+'ipbcreateaccount' => 'Tirkelgi jasawın kedergilew',
+'ipbenableautoblock' => 'Bul qatıswşınıñ qoldanğan soñğı IP jaýın, jäne ärqaýsı keýin tüzetw istewge ümiteligen jaýların özdik türde buğattaw',
+'ipbsubmit' => 'Paýdalanwşını buğattaw',
+'ipbother' => 'Basqa merzim',
+'ipboptions' => '2 sağat:2 hours,1 kün:1 day,3 kün:3 days,1 apta:1 week,2 apta:2 weeks,1 aý:1 month,3 aý:3 months,6 aý:6 months,1 jıl:1 year,mängi:infinite',
+'ipbotheroption' => 'basqa',
+'badipaddress' => 'Jaramsız IP jaý',
+'blockipsuccesssub' => 'Buğattaw sätti ötti',
+'blockipsuccesstext' => '[[{{ns:special}}:Contributions/$1|$1]] degen buğattalğan.
+<br />Buğattawlardı [[{{ns:special}}:Ipblocklist|IP buğattaw tiziminde]] qarap şığıñız.',
+'unblockip' => 'Paýdalanwşını buğattamaw',
+'unblockiptext' => 'Tömendegi ülgit belgili IP jaýımen ne atawımen
+burın buğattalğan paýdalanwşınıñ jazw ruqsatın qaýtarw üşin qoldanıladı.',
+'ipusubmit' => 'Osı jaýdı buğattamaw',
+'unblocked' => '[[{{ns:user}}:$1|$1]] buğattawı öşirildi',
+'ipblocklist' => 'Buğattalğan paýdalanwşı / IP- jaý tizimi',
+'blocklistline' => '$1, $2 «$3» degendi buğattadı ($4)',
+'infiniteblock' => 'mängi',
+'expiringblock' => 'bitwi: $1',
+'anononlyblock' => 'tek tirkelgisizdi',
+'noautoblockblock' => 'özdik buğattaw öşirilengen',
+'createaccountblock' => 'tirkelgi jasawı buğattalğan',
+'ipblocklistempty' => 'Buğattaw tizimi bos.',
+'blocklink' => 'buğattaw',
+'unblocklink' => 'buğattamaw',
+'contribslink' => 'ülesi',
+'autoblocker' => "IP jaýıñızdı jwıqta «[[{{ns:user}}:1|$1]]» paýdalanğan, sondıqtan özdik türde buğattalğan. $1 buğattaw sebebi: «'''$2'''».",
+'blocklogpage' => 'Buğattaw_jwrnalı',
+'blocklogentry' => '«[[$1]]» buğattadı, bitetin merzimi: $2',
+'blocklogtext' => 'Bul paýdalanwşılardı buğattaw/buğattamaw äreketteriniñ jwrnalı. Özdik türde
+buğattalğan IP jaýlar osında tizimdelgemegen. Ağımdağı belsendi buğattawların
+[[{{ns:special}}:Ipblocklist|IP buğattaw tiziminen]] qarawğa boladı.',
+'unblocklogentry' => '«$1» buğattawın öşirdi',
+'range_block_disabled' => 'Awqım buğattawın jasaw äkimşilik mümkindigi öşirilgen.',
+'ipb_expiry_invalid' => 'Bitetin waqıtı jaramsız.',
+'ipb_already_blocked' => '«$1» buğattalğan tüge',
+'ip_range_invalid' => 'IP jaý awqımı jaramsız.',
+'proxyblocker' => 'Proksï serverlerdi buğattawış',
+'ipb_cant_unblock' => 'Qate: IP $1 buğattawı tabılmadı. Onıñ buğattawı öşirlgen sïyaqtı.',
+'proxyblockreason' => 'IP jaýıñız aşıq proksï serverge jatatındıqtan buğattalğan. Ïnternet qızmetin jabdıqtawşıñızben, ne texnïkalıq medew qızmetimen qatınasıñız, jäne olarğa osı ote kürdeli qawıpsizdik şataq twralı aqparat beriñiz.',
+'proxyblocksuccess' => 'Bitti.',
+'sorbs' => 'DNSBL qara tizimi',
+'sorbsreason' => 'Sizdiñ IP jaýıñız osı torapta qoldanılğan DNSBL qara tizimindegi aşıq proksï-server dep tabıladı.',
+'sorbs_create_account_reason' => 'Sizdiñ IP jaýıñız osı torapta qoldanılğan DNSBL qara tizimindegi aşıq proksï-server dep tabıladı. Tirkelgi jasaý almaýsız.',
+
+# Developer tools
+'lockdb' => 'Derekqordı qulıptaw',
+'unlockdb' => 'Derekqordı qulıptamaw',
+'lockdbtext' => 'Derekqordın qulıptalwı barlıq paýdalanwşınıñ
+bet öñdew, baptawın qalaw, baqılaw tizimin, tağı basqa
+derekqordı özgertetin mümkindikterin toqtata turadı.
+Osı maqsatıñızdı, jäne jöndewiñiz bitkende
+derekqordı aşatıñızdı rastañız.',
+'unlockdbtext' => 'Derekqodın aşılwı barlıq paýdalanwşınıñ bet öñdew,
+baptawın qalaw, baqılaw tizimin, tağı basqa derekqordı özgertetin
+mümkindikterin qaýta aşadı.
+Osı maqsatıñızdı rastañız.',
+'lockconfirm' => 'Ïä, men derekqordı rastan qulıptaýmın.',
+'unlockconfirm' => 'Ïä, men derekqordı rastan qulıptamaýmın.',
+'lockbtn' => 'Derekqordı qulıpta',
+'unlockbtn' => 'Derekqordı qulıptama',
+'locknoconfirm' => 'Rastaw belgisin qoýmapsız.',
+'lockdbsuccesssub' => 'Derekqordı qulıptaw sätti ötti',
+'unlockdbsuccesssub' => 'Qulıptalğan derekqor aşıldı',
+'lockdbsuccesstext' => 'Derekqor qulıptaldı.
+<br />Jöndewiñiz bitkennen keýin [[{{ns:special}}:Unlockdb|qulıptawın öşirwge]] umıtpañız.',
+'unlockdbsuccesstext' => 'Qulıptalğan derekqor sätti aşıldı.',
+'lockfilenotwritable' => 'Derekqor qulıptaw faýlı jazılmaýdı. Derekqordı qulıptaw ne aşw üşin, veb-server faýlğa jazw ruqsatı bolw qajet.',
+'databasenotlocked' => 'Derekqor qulıptalğan joq.',
+
+# Make sysop
+'makesysoptitle' => 'Qatıswşını äkimşi qılw',
+'makesysoptext' => 'Bul ülgitti qarapaýım qatıswşını äkimşi qılw üşin töreşiler qoldanadı.
+Jolaqqa qatıswşı atın engiziñiz de, jäne bul qatıswşını äkimşi qılw üşin, tüýmeni basıñız.',
+'makesysopname' => 'Qatıswşı atı:',
+'makesysopsubmit' => 'Bul qatıswşını äkimşi qıl',
+'makesysopok' => '<b>«$1» degen qatıswşı endi äkimşi bop tağaýındaldı</b>',
+'makesysopfail' => '<b>«$1» degen qatıswşı äkimşi bop tağaýındalmadı. (Atın durıs engizdiñiz be?)</b>',
+'setbureaucratflag' => 'Qatıswşını töreşi qılw',
+'rightslog' => 'Qatıswşı_quqıqtarı_jwrnalı',
+'rightslogtext' => 'Bul paýdalanwşı quqıqtarın özgertw jwrnalı.',
+'rightslogentry' => ' $1 top müşelgin $2 degennen $3 degenge özgertti',
+'rights' => 'Quqıqtarı:',
+'set_user_rights' => 'Qatıswşı quqıqtarın tağaýındaw',
+'user_rights_set' => '<b>«$1» degen qatıswşınıñ quqıqtarı jañartıldı</b>',
+'set_rights_fail' => '<b>«$1» degen qatıswşınıñ quqıqtarı tağaýındalmadı. (Atın durıs engizdiñiz be?)</b>',
+'makesysop' => 'Qatıswşını äkimşi qılw',
+'already_sysop' => 'Bul qatıswşı äkimşi boptı tüge',
+'already_bureaucrat' => 'Bul qatıswşı toreşi boptı tüge',
+'rightsnone' => '(eşqandaý)',
+
+# Move page
+'movepage' => 'Betti jıljıtw',
+'movepagetext' => "Tömendegi ülgitti qoldanıp betterdi qaýta ataýdı,
+barlıq tarïxın jaña atawğa jıljıtadı.
+Burınğı bet atawı jaña atawğa aýdatatın bet boladı.
+Eski atawına silteýtin siltemeler özgertilmeýdi; jıljıtwdan soñ
+şınjırlı aýdatwlar bar-joğın tekseriñiz.
+Siltemeler burınğı joldawımen bılaýğı ötwin tekserwine
+siz mindetti bolasız.
+
+Eskeriñiz, eger jıljıtılatın atawda bet bolsa, sol eski betke aýdatw
+bolğanşa jäne tarïxı bolsa, bet '''jıljıtılmaýdı'''.
+Osınıñ mağınası: eger betti qatelik pen qaýta atalsa,
+burınğı atawına qaýta atawğa boladı,
+biraq bar bettiñ üstine jazwğa bolmaýdı.
+
+<b>NAZAR SALIÑIZ!</b>
+Bul däripti betke qatañ jäne kenet özgeris jasawğa mümkin;
+ärekettiñ aldınan osınıñ zardaptarın tüsingeniñizge batıl
+bolıñız.",
+'movepagetalktext' => "Kelesi sebepter '''bolğanşa''' deýin, talqılaw beti özdik türde birge jıljıtıladı:
+* Bos emes talqılaw beti jaña atawda bolğanda, nemese
+* Tömendegi qabışaqta belgini alastatqanda.
+
+Osı oraýda, qalawıñız bolsa, betti qoldan jıljıta ne qosa alasız.",
+'movearticle' => 'Betti jıljıtw',
+'movenologin' => 'Jüýege kirmegensiz',
+'movenologintext' => 'Betti jıljıtw üşin tirkelgen bolwıñız jäne
+ [[{{ns:special}}:Userlogin|kirwiñiz]] qajet.',
+'newtitle' => 'Jaña atawğa',
+'movepagebtn' => 'Betti jıljıt',
+'pagemovedsub' => 'Jıljıtw sätti ayaqtaldı',
+'pagemovedtext' => '«[[$1]]» beti «[[$2]]» betine jıljıtıldı.',
+'articleexists' => 'Bılaý atawlı bet bar boldı, ne tañdağan
+atawıñız jaramdı emes.
+Basqa ataw tandañız',
+'talkexists' => "'''Bettiñ özi sätti jıljıtıldı, biraq talqılaw beti birge jıljıtılmadı, onıñ sebebi jaña atawdıñ talqılaw beti bar tüge. Bunı qolmen qosıñız.'''",
+'movedto' => 'mınağan jıljıtıldı:',
+'movetalk' => 'Qatıstı talqılaw betimen birge jıljıtw',
+'talkpagemoved' => 'Qatıstı talqılaw beti de jıljıtıldı.',
+'talkpagenotmoved' => 'Qatıstı talqılaw beti <strong>jıljıtılmadı</strong>.',
+'1movedto2' => '«[[$1]]» betinde aýdatw qaldırıp «[[$2]]» betine jıljıttı',
+'1movedto2_redir' => '«[[$1]]» betin «[[$2]]» aýdatw betiniñ üstine jıljıttı',
+'movelogpage' => 'Jıljıtw jwrnalı',
+'movelogpagetext' => 'Tömende jıljıtılğan betterdiñ tizimi berilip tur.',
+'movereason' => 'Sebebi',
+'revertmove' => 'qaýtarw',
+'delete_and_move' => 'Joyw jäne jıljıtw',
+'delete_and_move_text' => '==Joyw qajet==
+
+Aqırğı «[[$1]]» bet atawı bar tüge.
+Jıljıtwğa jol berw üşin joyamız ba?',
+'delete_and_move_confirm' => 'Ïä, osı betti joý',
+'delete_and_move_reason' => 'Jıljıtwğa jol berw üşin joýılğan',
+'selfmove' => 'Qaýnar jäne aqırğı atawı birdeý; bet özine jıljıtılmaýdı.',
+'immobile_namespace' => 'Qaýnar nemese aqırğı atawı arnaýı türinde boldı; osındaý esim ayası jağına jäne jağınan better jıljıtılmaýdı.',
+
+# Export
+'export' => 'Betterdi sırtqa berw',
+'exporttext' => 'XML pişimine qaptalğan bölek bet ne better bwması
+mätiniñ jäne öñdew tarïxın sırtqa bere alasız. Osını, basqa wïkï-ge
+{{ns:special}}:Import page MediaWiki quralı arqılı, sırttan alwğa boladı.
+
+Betterdi sırtqa berw üşin, atawların tömendegi mätin awmağına engiziñiz,
+bir jolda bir ataw, jäne tandañız: ne ağımdıq nusqasın, barlıq eski nusqaları men
+jäne tarïxı joldarı men birge, ne däl ağımdıq nusqasın, soñğı öñdew twralı aqparatı men birge.
+
+Soñğı jağdaýda siltemeni de qoldanwğa boladı, mısalı {{int:mainpage}} beti üşin [[{{ns:Special}}:Export/{{int:mainpage}}]].',
+'exportcuronly' => 'Tolıq tarïxın emes, tek ağımdıq nusqasın kiristiriñiz',
+'exportnohistory' => "----
+'''Añğartpa:''' Önimdilik äseri sebepterinen, better tolıq tarïxın sırtqa berwi öşirilgen.",
+'export-submit' => 'Sırtqa ber',
+
+# Namespace 8 related
+'allmessages' => 'Jüýe xabarları',
+'allmessagesname' => 'Atawı',
+'allmessagesdefault' => 'Ädepki mätini',
+'allmessagescurrent' => 'Ağımdıq mätini',
+'allmessagestext' => 'Mında «MediaWiki:» esim ayasındağı barlıq qatınawlı jüýe xabar tizimi berilip tur.',
+'allmessagesnotsupportedUI' => 'Your current interface language <b>$1</b> is not supported by Special:Allmessages at this site.',
+'allmessagesnotsupportedDB' => "'''wgUseDatabaseMessages''' babı öşirilgen sebebinen '''{{ns:special}}:AllMessages''' sïpatı süemeldenbeýdi.",
+'allmessagesfilter' => 'Xabardı atawı boýınşa süzgilew:',
+'allmessagesmodified' => 'Tek özgertilgendi körset',
+
+# Thumbnails
+'thumbnail-more' => 'Ülkeýtw',
+'missingimage' => '<b>Joğalğan swret </b><br /><i>$1</i>',
+'filemissing' => 'Joğalğan faýl',
+'thumbnail_error' => 'Nobaý qurw qatesi: $1',
+
+# Special:Import
+'import' => 'Betterdi sırttan alw',
+'importinterwiki' => 'Wïkï-tasımaldap sırttan alw',
+'import-interwiki-text' => 'Sırttan alatın wïkï jobasın jäne bet atawın tandañız.
+Nusqa kün-aýı jäne öñdewşi attarı saqtaladı.
+Barlıq wïkï-tasımaldap sırttan alw äreketter [[{{ns:special}}:Log/import|sırttan alw jwrnalına]] jazılıp alınadı.',
+'import-interwiki-history' => 'Osı bettiñ barlıq tarïxï nusqaların köşirw',
+'import-interwiki-submit' => 'Sırttan alw',
+'import-interwiki-namespace' => 'Mına esim ayasına betterdi tasımaldaw:',
+'importtext' => 'Qaýnar wïkïden «Special:Export» qwralın qoldanıp, faýldı sırtqa beriñiz, dïskiñizge saqtañız, sosın mında qotarıñız.',
+'importstart' => 'Betterdi sırttan alwı…',
+'import-revision-count' => '$1 nusqa',
+'importnopages' => 'Sırttan alınatın better joq.',
+'importfailed' => 'Sırttan alw sätsiz bitti: $1',
+'importunknownsource' => 'Cırttan alw qaýnar türi tanımalsız',
+'importcantopen' => 'Sırttan alw faýlı aşılmaýdı',
+'importbadinterwiki' => 'Jaramsız wïkï-aralıq silteme',
+'importnotext' => 'Bostı, ne mätini joq',
+'importsuccess' => 'Sırttan alw sätti ayaqtaldı!',
+'importhistoryconflict' => 'Tarïxınıñ eges nusqaları bar (bul betti aldında sırttan alınğan sïyaqtı)',
+'importnosources' => 'Eşqandaý wïkï-tasımaldap sırttan alw qaýnarı belgilenmegen, jäne tarïxın tikeleý qotarwı öşirilgen.',
+'importnofile' => 'Sırttan alınatın faýl qotarılğan joq.',
+'importuploaderror' => 'Sırttan alw faýldıñ qotarwı sätsiz bitti; osı faýl mölşeri ruqsat etilgen mölşerden aswı mümkin.',
+
+# Import log
+'importlogpage' => 'Sırttan alw jwrnalı',
+'importlogpagetext' => 'Basqa wïkïlerden öñdew tarïxımen birge betterdi äkimşilik retinde sırttan alw.',
+'import-logentry-upload' => 'faýl qotarwımen sırttan «[[$1]]» beti alındı',
+'import-logentry-upload-detail' => '$1 nusqa',
+'import-logentry-interwiki' => 'wïkï-tasımaldanğan $1',
+'import-logentry-interwiki-detail' => '$2 degennen $1 nusqa',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => '{{SITENAME}} jobasınan izdestirw [alt-f]',
+'tooltip-minoredit' => 'Osını şağın tüzetw dep belgilew [alt-i]',
+'tooltip-save' => 'Tüzetwiñizdi saqtaw [alt-s]',
+'tooltip-preview' => 'Saqtawdıñ aldınan tüzetwiñizdi qarap şığıñız! [alt-p]',
+'tooltip-diff' => 'Mätinge qandaý özgeristerdi jasağanıñızdı qaraw. [alt-v]',
+'tooltip-compareselectedversions' => 'Bettiñ eki nusqasınıñ aýırmasın qaraw. [alt-v]',
+'tooltip-watch' => 'Bul betti baqılaw tizimiñizge üstew [alt-w]',
+
+# Stylesheets
+'common.css' => '/** Mındağı CSS ämirleri barlıq bezendirw mänerinderde qoldanıladı */',
+'monobook.css' => '/* Mındağı CSS ämirleri «Dara kitap» bezendirw mänerin paýdalanwşılarğa äser etedi */',
+
+# Metadata
+'nodublincore' => 'Osı serverge «Dublin Core RDF» meta-derekteri öşirilgen.',
+'nocreativecommons' => 'Osı serverge «Creative Commons RDF» meta-derekteri öşirilgen.',
+'notacceptable' => 'Osı wïkï serveri sizdiñ «paýdalanwşı äreketkişi» oqï alatın pişimi bar derekterdi jibere almaýdı.',
+
+# Attribution
+'anonymous' => '{{SITENAME}} tirkelgisiz paýdalanwşı(lar)',
+'siteuser' => '{{SITENAME}} qatıswşı $1',
+'lastmodifiedatby' => 'Bul betti $3 qatıswşı soñğı özgertken kezi: $2, $1.', # $1 date, $2 time, $3 user
+'and' => 'jäne',
+'othercontribs' => 'Şığarma negizin $1 jazğan.',
+'others' => 'basqalar',
+'siteusers' => '{{SITENAME}} qatıswşı(lar) $1',
+'creditspage' => 'Betti jazğandar',
+'nocredits' => 'Bul betti jazğandar twralı aqparat joq.',
+
+# Spam protection
+'spamprotectiontitle' => '«Spam»-nan qorğaýtın süzgi',
+'spamprotectiontext' => 'Bul bettiñ saqtawın «spam» süzgisi buğattadı. Bunıñ sebebi sırtqı torap siltemesinen bolwı mümkin.',
+'spamprotectionmatch' => 'Kelesi «spam» mätini süzgilengen: $1',
+'subcategorycount' => 'Bul sanatta {{PLURAL:$1|bir|$1}} tömengi sanat bar.',
+'categoryarticlecount' => 'Bul sanatta {{PLURAL:$1|bir|$1}} bet bar.',
+'category-media-count' => 'Bul sanatta {{PLURAL:$1|bir|$1}} faýl bar.',
+'listingcontinuesabbrev' => ' (jalğ.)',
+'spambot_username' => 'MediaWiki spam cleanup',
+'spam_reverting' => '$1 degenge siltemesi joq soñğı nusqasına qaýtarıldı',
+'spam_blanking' => '$1 degenge siltemesi bar barlıq nusqalar tazartıldı',
+
+# Info page
+'infosubtitle' => 'Bet twralı aqparat',
+'numedits' => 'Tüzetw sanı (negizgi beti): $1',
+'numtalkedits' => 'Tüzetw sanı (talqılaw beti): $1',
+'numwatchers' => 'Baqılawşı sanı: $1',
+'numauthors' => 'Ärtürli awtorlar sanı (negizgi beti): $1',
+'numtalkauthors' => 'Ärtürli awtor sanı (talqılaw beti): $1',
+
+# Math options
+'mw_math_png' => 'Ärqaşan PNG türimen körset',
+'mw_math_simple' => 'Kädimgi bolsa HTML pişimimen, basqaşa PNG türimen',
+'mw_math_html' => 'Iqtïmal bolsa HTML pişimimen, basqaşa PNG türimen',
+'mw_math_source' => 'TeX pişiminde qaldırw (mätindik şolğıştarına)',
+'mw_math_modern' => 'Osı zamannıñ şolğıştarına usınılğan',
+'mw_math_mathml' => 'Iqtïmal bolsa MathML pşimimen (sınaq türinde)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Küzette dep belgilew',
+'markaspatrolledtext' => 'Osı betti küzetwde dep belgilew',
+'markedaspatrolled' => 'Küzette dep belgilendi',
+'markedaspatrolledtext' => 'Talğanğan nusqa küzette dep belgilendi.',
+'rcpatroldisabled' => 'Jwıqtağı özgerister Küzeti öşirilgen',
+'rcpatroldisabledtext' => 'Jwıqtağı özgerister Küzeti qasïeti ağımda öşirilgen.',
+'markedaspatrollederror' => 'Küzette dep belgilenbeýdi',
+'markedaspatrollederrortext' => 'Küzette dep belgilew üşin nusqasın engiziñiz.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* tooltips and access keys */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','Jeke betim');
+ta['pt-anonuserpage'] = new Array('.','Osı IP jaýdıñ jeke beti');
+ta['pt-mytalk'] = new Array('n','Talqılaw betim');
+ta['pt-anontalk'] = new Array('n','Osı IP jaý tüzetwlerin talqılaw');
+ta['pt-preferences'] = new Array('','Baptawım');
+ta['pt-watchlist'] = new Array('l','Özgeristerin baqılap turğan better tizimim.');
+ta['pt-mycontris'] = new Array('y','Ülesterimdiñ tizimi');
+ta['pt-login'] = new Array('o','Kirwiñizdi usınamız, ol mindetti emes.');
+ta['pt-anonlogin'] = new Array('o','Kirwiñizdi usınamız, biraq, ol mindetti emes.');
+ta['pt-logout'] = new Array('','Şığw');
+ta['ca-talk'] = new Array('t','Mağlumat betti talqılaw');
+ta['ca-edit'] = new Array('e','Bul betti öñdeý alasız. Saqtawdıñ aldında «Qarap şığw» tüýmesin nuqıñız.');
+ta['ca-addsection'] = new Array('+','Bul talqılaw betinde jaña taraw bastaw.');
+ta['ca-viewsource'] = new Array('e','Bul bet qorğalğan, biraq, qaýnarın qarawğa boladı.');
+ta['ca-history'] = new Array('h','Bul bettin jwıqtağı nusqaları.');
+ta['ca-protect'] = new Array('=','Bul betti qorğaw');
+ta['ca-unprotect'] = new Array('=','Bul betti qorğamaw');
+ta['ca-delete'] = new Array('d','Bul betti joyw');
+ta['ca-undelete'] = new Array('d','Bul bettiñ joywdıñ aldındağı bolğan tüzetwlerin qaýtarw');
+ta['ca-move'] = new Array('m','Bul betti jıljıtw');
+ta['ca-nomove'] = new Array('m','Bul betti jıljıtwğa ruqsatıñız joq');
+ta['ca-watch'] = new Array('w','Bul betti baqılaw tizimiñizge üstew');
+ta['ca-unwatch'] = new Array('w','Bul betti baqılaw tizimiñizden alastatw');
+ta['ca-varlang-0'] = new Array('','Kïrïll jazwı');
+ta['ca-varlang-1'] = new Array('','Latın jazwı');
+ta['ca-varlang-2'] = new Array('','Arab jazwı');
+ta['search'] = new Array('f','Osı wïkïden izdew');
+ta['p-logo'] = new Array('','Bastı betke');
+ta['n-mainpage'] = new Array('z','Bastı betke barıp ketiñiz');
+ta['n-portal'] = new Array('','Joba twralı, ne istewiñizge bolatın, qaýdan tabwğa bolatın twralı');
+ta['n-currentevents'] = new Array('','Ağımdağı oqïğalarğa qatıstı aqparat');
+ta['n-recentchanges'] = new Array('r','Osı wïkïdegi jwıqtağı özgerister tizimi.');
+ta['n-randompage'] = new Array('x','Kezdeýsoq betti jüktew');
+ta['n-help'] = new Array('','Anıqtama tabw ornı.');
+ta['n-sitesupport'] = new Array('','Bizge järdem etiñiz');
+ta['t-whatlinkshere'] = new Array('j','Mında siltegen barlıq betterdiñ tizimi');
+ta['t-recentchangeslinked'] = new Array('k','Mınnan siltengen betterdiñ jwıqtağı özgeristeri');
+ta['feed-rss'] = new Array('','Bul bettiñ RSS arnası');
+ta['feed-atom'] = new Array('','Bul bettiñ Atom arnası');
+ta['t-contributions'] = new Array('','Osı qatıswşınıñ üles tizimin qaraw');
+ta['t-emailuser'] = new Array('','Osı qatıswşığa email jiberw');
+ta['t-upload'] = new Array('u','Swret ne medïa faýldarın qotarw');
+ta['t-specialpages'] = new Array('q','Barlıq arnaýı better tizimi');
+ta['t-print'] = new Array('','Osı bettiñ basıp şığarw nusqası');
+ta['t-permalink'] = new Array('','Bettiñ osı nusqasınıñ turaqtı siltemesi');
+ta['ca-nstab-main'] = new Array('c','Mağlumat betin qaraw');
+ta['ca-nstab-user'] = new Array('c','Qatıswşı betin qaraw');
+ta['ca-nstab-media'] = new Array('c','Taspa betin qaraw');
+ta['ca-nstab-special'] = new Array('','Bul arnaýı bet, bettiñ özi öñdelinbeýdi.');
+ta['ca-nstab-project'] = new Array('a','Joba betin qaraw');
+ta['ca-nstab-image'] = new Array('c','Swret betin qaraw');
+ta['ca-nstab-mediawiki'] = new Array('c','Jüýe xabarın qaraw');
+ta['ca-nstab-template'] = new Array('c','Ülgini qaraw');
+ta['ca-nstab-help'] = new Array('c','Anıqtıma betin qaraw');
+ta['ca-nstab-category'] = new Array('c','Sanat betin qaraw');",
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Mındağı kez kelgen JavaScript ämirleri ärqaýsı bet jüktelgende barlıq paýdalanwşılarğa jükteledi. */
+
+// BEGIN workaround for RTL
+if (wgUserLanguage == "kk-cn"){
+ document.direction="rtl";
+ document.write(\'<style type="text/css">html {direction: rtl;}</style>\');
+ document.write(\'<link rel="stylesheet" type="text/css" href="\'+stylepath+\'/common/common_rtl.css">\');
+ document.write(\'<link rel="stylesheet" type="text/css" href="\'+stylepath+\'/\'+skin+\'/rtl.css">\');
+}
+// END workaround for RTL',
+
+# Image deletion
+'deletedrevision' => 'Mına eski nusqasın joýdı: $1.',
+
+# Browsing diffs
+'previousdiff' => '← Aldıñğımen aýırması',
+'nextdiff' => 'Kelesimen aýırması →',
+
+'imagemaxsize' => 'Swret tüýindeme betindegi swrettiñ mölşerin şektewi:',
+'thumbsize' => 'Nobaý mölşeri:',
+'showbigimage' => 'Joğarı ajıratılımdı ($1×$2, $3 kB) nusqasın jüktew',
+
+'newimages' => 'Eñ jaña faýldar qoýması',
+'showhidebots' => '(bottardı $1)',
+'noimages' => 'Köretin eşteñe joq.',
+
+# Variants for Kazakh language
+'variantname-kk-tr' => 'Latın',
+'variantname-kk-kz' => 'Кирил',
+'variantname-kk-cn' => 'توتە',
+'variantname-kk' => 'disable',
+
+# Labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Qatıswşı:',
+'speciallogtitlelabel' => 'Ataw:',
+
+'passwordtooshort' => 'Qupïya söziñiz tım qısqa. Eñ keminde $1 ärip bolwı qajet.',
+
+# Media Warning
+'mediawarning' => "'''Nazar salıñız''': Bul faýl türinde qaskünemdi ämirdiñ bar bolwı ıqtïmal; faýldı jegip jüýeñizge zïyan keltirwiñiz mümkin.<hr />",
+
+'fileinfo' => '$1 kB, MIME türi: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Meta-derekteri',
+'metadata-help' => 'Osı faýlda qosımşa aqparat bar. Bälkim, osı aqparat faýldı jasap şığarw, ne sandılaw üşin paýdalanğan sandıq kamera, ne mätinalğırdan alınğan. Eger osı faýl negizgi küýinen özgertilgen bolsa, keýbir ejeleleri özgertilgen fotoswretke laýıq bolmas.',
+'metadata-expand' => 'Egjeý-tegjeýin körset',
+'metadata-collapse' => 'Egjeý-tegjeýin jasır',
+'metadata-fields' => 'Osı xabarda tizimdelgen EXIF meta-derek awmaqtarı,
+swret beti körsetw kezinde meta-derek keste jasırılığanda kiristirledi.
+Basqası ädepkiden jasırıladı.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# EXIF tags
+'exif-imagewidth' => 'Eni',
+'exif-imagelength' => 'Bïiktigi',
+'exif-bitspersample' => 'Quraş saýın bït sanı',
+'exif-compression' => 'Qısım sulbası',
+'exif-photometricinterpretation' => 'Pïksel qïıswı',
+'exif-orientation' => 'Megzewi',
+'exif-samplesperpixel' => 'Quraş sanı',
+'exif-planarconfiguration' => 'Derek rettewi',
+'exif-ycbcrsubsampling' => 'Y quraşınıñ C quraşına jarnaqtawı',
+'exif-ycbcrpositioning' => 'Y quraşı jäne C quraşı mekendewi',
+'exif-xresolution' => 'Dereleý ajıratılımdığı',
+'exif-yresolution' => 'Tireleý ajıratılımdığı',
+'exif-resolutionunit' => 'X jäne Y ajıratılımdıqtarığınıñ ölşemi',
+'exif-stripoffsets' => 'Swret dererekteriniñ jaýğaswı',
+'exif-rowsperstrip' => 'Beldik saýın jol sanı',
+'exif-stripbytecounts' => 'Qısımdalğan beldik saýın baýt sanı',
+'exif-jpeginterchangeformat' => 'JPEG SOI degennen ığıswı',
+'exif-jpeginterchangeformatlength' => 'JPEG derekteriniñ baýt sanı',
+'exif-transferfunction' => 'Tasımaldaw fwnkcïyası',
+'exif-whitepoint' => 'Aq nükte tüstiligi',
+'exif-primarychromaticities' => 'Alğı şeptegi tüstilikteri',
+'exif-ycbcrcoefficients' => 'Tüs ayasın tasımaldaw matrïcalıq eselikteri',
+'exif-referenceblackwhite' => 'Qara jäne aq anıqtawış qos kolemderi',
+'exif-datetime' => 'Faýldıñ özgertilgen kün-aýı',
+'exif-imagedescription' => 'Swret atawı',
+'exif-make' => 'Kamera öndirwşisi',
+'exif-model' => 'Kamera ülgisi',
+'exif-software' => 'Qoldanılğan bağdarlama',
+'exif-artist' => 'Jığarmaşısı',
+'exif-copyright' => 'Jığarmaşılıq quqıqtar ïesi',
+'exif-exifversion' => 'Exif nusqası',
+'exif-flashpixversion' => 'Süýemdelingen Flashpix nusqası',
+'exif-colorspace' => 'Tüs ayası',
+'exif-componentsconfiguration' => 'Ärqaýsı quraş mäni',
+'exif-compressedbitsperpixel' => 'Swret qısımdaw tärtibi',
+'exif-pixelydimension' => 'Swrettiñ jaramdı eni',
+'exif-pixelxdimension' => 'Swrettiñ jaramdı bïiktigi',
+'exif-makernote' => 'Öndirwşi eskertpeleri',
+'exif-usercomment' => 'Paýdalanwşı mändemeleri',
+'exif-relatedsoundfile' => 'Qatıstı dıbıs faýlı',
+'exif-datetimeoriginal' => 'Jasalğan kezi',
+'exif-datetimedigitized' => 'Sandıqtaw kezi',
+'exif-subsectime' => 'Jasalğan keziniñ sekwnd bölşekteri',
+'exif-subsectimeoriginal' => 'Tüpnusqa keziniñ sekwnd bölşekteri',
+'exif-subsectimedigitized' => 'Sandıqtaw keziniñ sekwnd bölşekteri',
+'exif-exposuretime' => 'Ustalım waqıtı',
+'exif-exposuretime-format' => '$1 s ($2)',
+'exif-fnumber' => 'Sañılaw mölşeri',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Ustalım bağdarlaması',
+'exif-spectralsensitivity' => 'Spektr boýınşa sezgiştigi',
+'exif-isospeedratings' => 'ISO jıldamdıq jarnaqtawı (jarıq sezgiştigi)',
+'exif-oecf' => 'Optoelektrondı türletw ıqpalı',
+'exif-shutterspeedvalue' => 'Japqış jıldamdılığı',
+'exif-aperturevalue' => 'Sañılawlıq',
+'exif-brightnessvalue' => 'Aşıqtıq',
+'exif-exposurebiasvalue' => 'Ustalım ötemi',
+'exif-maxaperturevalue' => 'Barınşa sañılaw aşwı',
+'exif-subjectdistance' => 'Nısana qaşıqtığı',
+'exif-meteringmode' => 'Ölşew tärtibi',
+'exif-lightsource' => 'Jarıq közi',
+'exif-flash' => 'Jarqıldağış',
+'exif-focallength' => 'Şoğırlaw alşaqtığı',
+'exif-focallength-format' => '$1 mm',
+'exif-subjectarea' => 'Nısana awqımı',
+'exif-flashenergy' => 'Jarqıldağış qarqını',
+'exif-spatialfrequencyresponse' => 'Keñistik-jïilik äserşiligi',
+'exif-focalplanexresolution' => 'X boýınşa şoğırlaw jaýpaqtıqtıñ ajıratılımdığı',
+'exif-focalplaneyresolution' => 'Y boýınşa şoğırlaw jaýpaqtıqtıñ ajıratılımdığı',
+'exif-focalplaneresolutionunit' => 'Şoğırlaw jaýpaqtıqtıñ ajıratılımdıq ölşemi',
+'exif-subjectlocation' => 'Nısana mekendewi',
+'exif-exposureindex' => 'Ustalım aýqındawı',
+'exif-sensingmethod' => 'Sensordiñ ölşew ädisi',
+'exif-filesource' => 'Faýl qaýnarı',
+'exif-scenetype' => 'Saxna türi',
+'exif-cfapattern' => 'CFA süzgi keýipi',
+'exif-customrendered' => 'Qosımşa swret öñdetwi',
+'exif-exposuremode' => 'Ustalım tärtibi',
+'exif-whitebalance' => 'Aq tüsiniñ tendestigi',
+'exif-digitalzoomratio' => 'Sandıq awqımdaw jarnaqtawı',
+'exif-focallengthin35mmfilm' => '35 mm taspasınıñ şoğırlaw alşaqtığı',
+'exif-scenecapturetype' => 'Tüsirgen saxna türi',
+'exif-gaincontrol' => 'Saxnanı meñgerw',
+'exif-contrast' => 'Qarama-qarsılıq',
+'exif-saturation' => 'Qanıqtıq',
+'exif-sharpness' => 'Aýqındıq',
+'exif-devicesettingdescription' => 'Jabdıq baptaw sïpattarı',
+'exif-subjectdistancerange' => 'Saxna qaşıqtığınıñ kölemi',
+'exif-imageuniqueid' => 'Swrettiñ biregeý nömiri (ID)',
+'exif-gpsversionid' => 'GPS belgişesiniñ nusqası',
+'exif-gpslatituderef' => 'Soltüstik nemese Oñtüstik boýlığı',
+'exif-gpslatitude' => 'Boýlığı',
+'exif-gpslongituderef' => 'Şığıs nemese Batıs endigi',
+'exif-gpslongitude' => 'Endigi',
+'exif-gpsaltituderef' => 'Bïiktik körsetwi',
+'exif-gpsaltitude' => 'Bïiktik',
+'exif-gpstimestamp' => 'GPS waqıtı (atom sağatı)',
+'exif-gpssatellites' => 'Ölşewge pýdalanılğan Jer serikteri',
+'exif-gpsstatus' => 'Qabıldağış küýi',
+'exif-gpsmeasuremode' => 'Ölşew tärtibi',
+'exif-gpsdop' => 'Ölşew däldigi',
+'exif-gpsspeedref' => 'Jıldamdılıq ölşemi',
+'exif-gpsspeed' => 'GPS qabıldağıştıñ jıldamdılığı',
+'exif-gpstrackref' => 'Qozğalıs bağıtın körsetwi',
+'exif-gpstrack' => 'Qozğalıs bağıtı',
+'exif-gpsimgdirectionref' => 'Swret bağıtın körsetwi',
+'exif-gpsimgdirection' => 'Swret bağıtı',
+'exif-gpsmapdatum' => 'Paýdalanılğan geodezïyalıq tüsirme derekteri',
+'exif-gpsdestlatituderef' => 'Nısana boýlığın körsetwi',
+'exif-gpsdestlatitude' => 'Nısana boýlığı',
+'exif-gpsdestlongituderef' => 'Nısana endigin körsetwi',
+'exif-gpsdestlongitude' => 'Nısana endigi',
+'exif-gpsdestbearingref' => 'Nısana azïmwtın körsetwi',
+'exif-gpsdestbearing' => 'Nısana azïmwtı',
+'exif-gpsdestdistanceref' => 'Nısana qaşıqtığın körsetwi',
+'exif-gpsdestdistance' => 'Nısana qaşıqtığı',
+'exif-gpsprocessingmethod' => 'GPS öñdetw ädisiniñ atawı',
+'exif-gpsareainformation' => 'GPS awmağınıñ atawı',
+'exif-gpsdatestamp' => 'GPS kün-aýı',
+'exif-gpsdifferential' => 'GPS saralanğan tüzetw',
+
+# EXIF attributes
+'exif-compression-1' => 'Ulğaýtılğan',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Qalıptı', # 0th row: top; 0th column: left
+'exif-orientation-2' => 'Dereleý şağılısqan', # 0th row: top; 0th column: right
+'exif-orientation-3' => '180° burışqa aýnalğan', # 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Tireleý şağılısqan', # 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Sağat tilşesine qarsı 90° burışqa aýnalğan jäne tireleý şağılısqan', # 0th row: left; 0th column: top
+'exif-orientation-6' => 'Sağat tilşe boýınşa 90° burışqa aýnalğan', # 0th row: right; 0th column: top
+'exif-orientation-7' => 'Sağat tilşe boýınşa 90° burışqa aýnalğan jäne tireleý şağılısqan', # 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Sağat tilşesine qarsı 90° burışqa aýnalğan', # 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'talpaq pişim',
+'exif-planarconfiguration-2' => 'taýpaq pişim',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'bar bolmadı',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Anıqtalmağan',
+'exif-exposureprogram-1' => 'Qolmen',
+'exif-exposureprogram-2' => 'Bağdarlamalı ädis (qalıptı)',
+'exif-exposureprogram-3' => 'Sañılaw basıñqılığı',
+'exif-exposureprogram-4' => 'Isırma basıñqılığı',
+'exif-exposureprogram-5' => 'Öner bağdarlaması (anıqtıq terendigine sanasqan)',
+'exif-exposureprogram-6' => 'Qïmıl bağdarlaması (japqış şapşandılığına sanasqan)',
+'exif-exposureprogram-7' => 'Tireleý ädisi (artı şoğırlawsız tayaw tüsirmeler)',
+'exif-exposureprogram-8' => 'Dereleý ädisi (artı şoğırlanğan dereleý tüsirmeler)',
+
+'exif-subjectdistance-value' => '$1 m',
+
+'exif-meteringmode-0' => 'Belgisiz',
+'exif-meteringmode-1' => 'Birkelki',
+'exif-meteringmode-2' => 'Buldır daq',
+'exif-meteringmode-3' => 'BirDaqtı',
+'exif-meteringmode-4' => 'KöpDaqtı',
+'exif-meteringmode-5' => 'Örnekti',
+'exif-meteringmode-6' => 'Jırtındı',
+'exif-meteringmode-255' => 'Basqa',
+
+'exif-lightsource-0' => 'Belgisiz',
+'exif-lightsource-1' => 'Kün jarığı',
+'exif-lightsource-2' => 'Künjarıqtı şam',
+'exif-lightsource-3' => 'Qızdırğıştı şam',
+'exif-lightsource-4' => 'Jarqıldağış',
+'exif-lightsource-9' => 'Aşıq kün',
+'exif-lightsource-10' => 'Bulınğır kün',
+'exif-lightsource-11' => 'Kölenkeli',
+'exif-lightsource-12' => 'Künjarıqtı şam (D 5700–7100 K)',
+'exif-lightsource-13' => 'Künjarıqtı şam (N 4600–5400 K)',
+'exif-lightsource-14' => 'Künjarıqtı şam (W 3900–4500 K)',
+'exif-lightsource-15' => 'Künjarıqtı şam (WW 3200–3700 K)',
+'exif-lightsource-17' => 'Qalıptı jarıq qaýnarı A',
+'exif-lightsource-18' => 'Qalıptı jarıq qaýnarı B',
+'exif-lightsource-19' => 'Qalıptı jarıq qaýnarı C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'Stwdïyalıq ISO künjarıqtı şam',
+'exif-lightsource-255' => 'Basqa jarıq qaýnarı',
+
+'exif-focalplaneresolutionunit-2' => 'dywým',
+
+'exif-sensingmethod-1' => 'Anıqtalmağan',
+'exif-sensingmethod-2' => '1-çïpti awmaqtı tüssezgiş',
+'exif-sensingmethod-3' => '2-çïpti awmaqtı tüssezgiş',
+'exif-sensingmethod-4' => '3-çïpti awmaqtı tüssezgiş',
+'exif-sensingmethod-5' => 'Kezekti awmaqtı tüssezgiş',
+'exif-sensingmethod-7' => '3-sızıqtı tüssezgiş',
+'exif-sensingmethod-8' => 'Kezekti sızıqtı tüssezgiş',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'Tikeleý tüsirilgen fotoswret',
+
+'exif-customrendered-0' => 'Qalıptı öñdetw',
+'exif-customrendered-1' => 'Qosımşa öñdetw',
+
+'exif-exposuremode-0' => 'Özdik ustalımdaw',
+'exif-exposuremode-1' => 'Qolmen ustalımdaw',
+'exif-exposuremode-2' => 'Özdik jarqıldaw',
+
+'exif-whitebalance-0' => 'Aq tüsiniñ özdik tendestirw',
+'exif-whitebalance-1' => 'Aq tüsiniñ qolmen tendestirw',
+
+'exif-scenecapturetype-0' => 'Qalıptı',
+'exif-scenecapturetype-1' => 'Dereleý',
+'exif-scenecapturetype-2' => 'Tireleý',
+'exif-scenecapturetype-3' => 'Tüngi saxna',
+
+'exif-gaincontrol-0' => 'Joq',
+'exif-gaincontrol-1' => 'Tömen zorayw',
+'exif-gaincontrol-2' => 'Joğarı zorayw',
+'exif-gaincontrol-3' => 'Tömen bayawlaw',
+'exif-gaincontrol-4' => 'Joğarı bayawlaw',
+
+'exif-contrast-0' => 'Qalıptı',
+'exif-contrast-1' => 'Uyan',
+'exif-contrast-2' => 'Turpaýı',
+
+'exif-saturation-0' => 'Qalıptı',
+'exif-saturation-1' => 'Tömen qanıqtı',
+'exif-saturation-2' => 'Joğarı qanıqtı',
+
+'exif-sharpness-0' => 'Qalıptı',
+'exif-sharpness-1' => 'Uyan',
+'exif-sharpness-2' => 'Turpaýı',
+
+'exif-subjectdistancerange-0' => 'Belgisiz',
+'exif-subjectdistancerange-1' => 'Tayaw tüsirilgen',
+'exif-subjectdistancerange-2' => 'Jaqın tüsirilgen',
+'exif-subjectdistancerange-3' => 'Alıs tüsirilgen',
+
+# Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Soltüstik boýlığı',
+'exif-gpslatitude-s' => 'Oñtüstik boýlığı',
+
+# Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Şığıs endigi',
+'exif-gpslongitude-w' => 'Batıs endigi',
+
+'exif-gpsstatus-a' => 'Ölşew ulaswda',
+'exif-gpsstatus-v' => 'Ölşew özara ärekette',
+
+'exif-gpsmeasuremode-2' => '2-bağıttıq ölşem',
+'exif-gpsmeasuremode-3' => '3-bağıttıq ölşem',
+
+# Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'km/h',
+'exif-gpsspeed-m' => 'mil/h',
+'exif-gpsspeed-n' => 'J. tüýin',
+
+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Şın bağıt',
+'exif-gpsdirection-m' => 'Magnïttı bağıt',
+
+# External editor support
+'edit-externally' => 'Bul faýldı sırtqı qural/bağdarlama arqılı öñdew',
+'edit-externally-help' => 'Köbirek aqparat üşin [http://meta.wikimedia.org/wiki/Help:External_editors ornatw nusqawların] qarañız.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'barlığın',
+'imagelistall' => 'barlığı',
+'watchlistall1' => 'barlığı',
+'watchlistall2' => 'barlıq',
+'namespacesall' => 'barlığı',
+
+# E-mail address confirmation
+'confirmemail' => 'E-poşta jaýın kwälandırw',
+'confirmemail_noemail' => '[[{{ns:special}}:Preferences|Qatıswşı baptawıñızda]] jaramdı e-poşta jaýın engizbepsiz.',
+'confirmemail_text' => 'Bul wïkïde e-poşta qasïetterin paýdalanwdıñ aldınan e-poşta jaýıñızdı
+kwälandırw qajet. Öziñizdiñ jaýıñızğa kwälandırw xatın jiberw üşin tömendegi tüýmeni nuqıñız.
+Xattıñ işinde arnaýı kodı bar silteme kiristirledi; e-poşta jaýıñızdıñ jaramdığın kwälandırw üşin
+siltemeni şolğıştıñ meken-jaý jolağına engizip aşıñız.',
+'confirmemail_send' => 'Kwälandırw kodın jiberw',
+'confirmemail_sent' => 'Kwälandırw E-poşta xatı jiberildi.',
+'confirmemail_sendfailed' => 'Kwälandırw xatı jiberilmedi. Engizilgen jaýdı jaramsız äriterine tekserip şığıñız.
+
+E-poşta qızmeti qaýtarğanı: $1',
+'confirmemail_invalid' => 'Kwälandırw kodı jaramsız. Kodtıñ merzimi bitken şığar.',
+'confirmemail_needlogin' => 'E-poşta jaýıñızdı kwälandırw üşin $1 qajet.',
+'confirmemail_success' => 'E-poşta jaýıñız kwälandırıldı. Endi Wïkïge kirip jumısqa kiriswge boladı',
+'confirmemail_loggedin' => 'E-poşta jaýıñız kwälandırıldı.',
+'confirmemail_error' => 'Kwälandırwıñızdı saqtağanda belgisiz qate boldı.',
+'confirmemail_subject' => '{{SITENAME}} torabınan e-poşta jaýıñızdı kwälandırw xatı',
+'confirmemail_body' => "Keýbirew, mına $1 IP jaýınan, öziñiz bolwı mümkin,
+{{SITENAME}} jobasındağı E-poşta jaýın qoldanıp «$2» tirkelgi jasaptı.
+
+Osı tirkelgi rastan sizdiki ekenin kwälandırw üşin, jäne {{SITENAME}} jobasınıñ
+e-poşta qasïetterin belsendirw üşin, mına siltemeni şolğışpen aşıñız:
+
+$3
+
+Bul sizdiki '''emes''' bolsa, siltemege ermeñiz. Kwälandırw kodınıñ
+merzimi $4 kezinde bitedi.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Däl säýkesin sınap köriñiz',
+'searchfulltext' => 'Tolıq mätinimen izdew',
+'createarticle' => 'Betti bastaw',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Wïkï-ara kiregw öşirilgen]',
+'scarytranscludefailed' => '[$1 betine ülgi öñdetw sätsiz bitti; keşiriñiz]',
+'scarytranscludetoolong' => '[URL jaýı tım uzın; keşiriñiz]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Bul bettiñ añıstawları:<br />
+$1
+</div>',
+'trackbackremove' => '([$1 Joýıldı])',
+'trackbacklink' => 'Añıstaw',
+'trackbackdeleteok' => 'Añıstaw joywı sätti ötti.',
+
+# Delete conflict
+'deletedwhileediting' => 'Nazar salıñız:Siz bul bettiñ öñdewin bastağanda, osı bet joýıldı!',
+'confirmrecreate' => "Siz bul bettiñ öndewin bastağanda [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|talqılawı]]) osı betti joýdı, körsetken sebebi:
+: ''$2''
+Osı betti şınınan qaýta jasawın rastañız.",
+'recreate' => 'Qaýta jasaw',
+'tooltip-recreate' => 'Bul betti joýılwına qaramaý qaýta jasaw',
+
+'unit-pixel' => ' px',
+
+# HTML dump
+'redirectingto' => '[[$1]] betine aýdatwda…',
+
+# action=purge
+'confirm_purge' => 'Qosalqı qaltadağı osı betin tazalaýmız ba?<br /><br />$1',
+'confirm_purge_button' => 'Jaraýdı',
+
+'youhavenewmessagesmulti' => '$1 degenge jaña xabarlar tüsti',
+
+'searchcontaining' => "Mına sözi bar bet arasınan izdew: ''$1''.",
+'searchnamed' => "Mına atawlı bet arasınan izdew: ''$1''.",
+'articletitles' => "Atawları mınadan bastalğan better: ''$1''",
+'hideresults' => 'Nätïjelerdi jasır',
+
+# DISPLAYTITLE
+'displaytitle' => '(Bul bettiñ siltemesi: [[$1]])',
+
+'loginlanguagelabel' => 'Til: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; aldıñğı betke',
+'imgmultipagenext' => 'kelesi betke &rarr;',
+'imgmultigo' => 'Ötw!',
+'imgmultigotopre' => 'Mına betke ötw',
+
+# Table pager
+'ascending_abbrev' => 'ösw',
+'descending_abbrev' => 'kemw',
+'table_pager_next' => 'Kelesi betke',
+'table_pager_prev' => 'Aldıñğı betke',
+'table_pager_first' => 'Alğaşqı betke',
+'table_pager_last' => 'Soñğı betke',
+'table_pager_limit' => 'Bet saýın $1 dana körset',
+'table_pager_limit_submit' => 'Ötw',
+'table_pager_empty' => 'Eş nätïje joq',
+
+# Auto-summaries
+'autosumm-blank' => 'Bettiñ barlıq mağlumatın alastattı',
+'autosumm-replace' => "Betti '$1' degenmen almastırdı",
+'autoredircomment' => '[[$1]] degenge aýdadı', # This should be changed to the new naming convention, but existed beforehand
+'autosumm-new' => 'Jaña bet: $1',
+);
+
+?>
diff --git a/languages/messages/MessagesKm.php b/languages/messages/MessagesKm.php
new file mode 100644
index 000000000000..bb2f807eb7f9
--- /dev/null
+++ b/languages/messages/MessagesKm.php
@@ -0,0 +1,22 @@
+<?php
+/** Khmer (ភាសាខ្មែរ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+$digitTransformTable = array(
+ '0' => '០',
+ '1' => '១',
+ '2' => '២',
+ '3' => '៣',
+ '4' => '៤',
+ '5' => '៥',
+ '6' => '៦',
+ '7' => '៧',
+ '8' => '៨',
+ '9' => '៩'
+);
+
+?>
diff --git a/languages/messages/MessagesKn.php b/languages/messages/MessagesKn.php
new file mode 100644
index 000000000000..066da5329872
--- /dev/null
+++ b/languages/messages/MessagesKn.php
@@ -0,0 +1,377 @@
+<?php
+/**
+ * Language file for Kannada.
+ * Mosty done by:
+ * Hari Prasad Nadig <hpnadig@gmail.com>
+ * http://en.wikipedia.org/wiki/User:Hpnadig
+ * Ashwath Mattur <ashwatham@gmail.com>
+ * http://en.wikipedia.org/wiki/User:Ashwatham
+ *
+ * Also see the Kannada Localisation Initiative at:
+ * http://kannada.sourceforge.net/
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'ಮೀಡಿಯ',
+ NS_SPECIAL => 'ವಿಶೇಷ',
+ NS_MAIN => '',
+ NS_TALK => 'ಚರ್ಚೆಪುಟ',
+ NS_USER => 'ಸದಸ್ಯ',
+ NS_USER_TALK => 'ಸದಸ್ಯರ_ಚರ್ಚೆಪುಟ',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_ಚರ್ಚೆ',
+ NS_IMAGE => 'ಚಿತ್ರ',
+ NS_IMAGE_TALK => 'ಚಿತ್ರ_ಚರ್ಚೆಪುಟ',
+ NS_MEDIAWIKI => 'ಮೀಡಿಯವಿಕಿ',
+ NS_MEDIAWIKI_TALK => 'ಮೀಡೀಯವಿಕಿ_ಚರ್ಚೆ',
+ NS_TEMPLATE => 'ಟೆಂಪ್ಲೇಟು',
+ NS_TEMPLATE_TALK => 'ಟೆಂಪ್ಲೇಟು_ಚರ್ಚೆ',
+ NS_HELP => 'ಸಹಾಯ',
+ NS_HELP_TALK => 'ಸಹಾಯ_ಚರ್ಚೆ',
+ NS_CATEGORY => 'ವರ್ಗ',
+ NS_CATEGORY_TALK => 'ವರ್ಗ_ಚರ್ಚೆ'
+);
+
+$digitTransformTable = array(
+ '0' => '೦',
+ '1' => '೧',
+ '2' => '೨',
+ '3' => '೩',
+ '4' => '೪',
+ '5' => '೫',
+ '6' => '೬',
+ '7' => '೭',
+ '8' => '೮',
+ '9' => '೯'
+);
+
+$messages = array(
+'jan' => 'ಜನವರಿ',
+'feb' => 'ಫೆಬ್ರುವರಿ',
+'mar' => 'ಮಾರ್ಚ್',
+'apr' => 'ಎಪ್ರಿಲ್',
+'may' => 'ಮೇ',
+'jun' => 'ಜೂನ್',
+'jul' => 'ಜುಲೈ',
+'aug' => 'ಆಗಸ್ಟ್',
+'sep' => 'ಸೆಪ್ಟೆಂಬರ್',
+'oct' => 'ಅಕ್ಟೋಬರ್',
+'nov' => 'ನವೆಂಬರ್',
+'dec' => 'ಡಿಸೆಂಬರ್',
+
+
+'1movedto2' => "$1 - $2 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸಲಾಗಿದೆ",
+'1movedto2_redir' => "$1 - $2 ಕ್ಕೆ ರಿಡೈರೆಕ್ಟ್ ಮೂಲಕ ಸ್ಥಳಾಂತರಿಸಲಾಗಿದೆ",
+'about' => "ನಮ್ಮ ಬಗ್ಗೆ",
+'aboutpage' => "ವಿಕಿಪೀಡಿಯಾ:ನಮ್ಮ ಬಗ್ಗೆ",
+'accmailtext' => "'$1'ನ ಪ್ರವೇಶ ಪದ $2 ಗೆ ಕಳುಹಿಸಲಾಗಿದೆ",
+'accmailtitle' => "ಪ್ರವೇಶ ಪದ ಕಳುಹಿಸಲಾಯಿತು.",
+'acct_creation_throttle_hit' => "ಕ್ಷಮಿಸಿ, ನೀವಾಗಲೇ $1 ಖಾತೆಗಳನ್ನು ತೆರೆದಿದ್ದೀರಿ. ಇನ್ನು ಖಾತೆಗಳನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ.",
+'actioncomplete' => "ಕಾರ್ಯ ಸಂಪೂರ್ಣ",
+'addedwatch' => "ವೀಕ್ಷಣಾ ಪಟ್ಟಿಗೆ ಸೇರಿಸಲಾಯಿತು",
+'addedwatchtext' => "\"$1\" ಪುಟವನ್ನು ನಿಮ್ಮ [[Special:Watchlist|ವೀಕ್ಷಣಾಪಟ್ಟಿಗೆ]] ಸೇರಿಸಲಾಗಿದೆ. ಈ ಪುಟದ ಮತ್ತು ಇದರ ಚರ್ಚಾ ಪುಟದ ಮು೦ದಿನ ಬದಲಾವಣೆಗಳು ವೀಕ್ಷಣಾ ಪಟ್ಟಿಯಲ್ಲಿ ಕಾಣಸಿಗುತ್ತವೆ, ಮತ್ತು [[Special:Recentchanges|ಇತ್ತೀಚೆಗಿನ ಬದಲಾವಣೆಗಳ]] ಪಟ್ಟಿಯಲ್ಲಿ ಈ ಪುಟಗಳನ್ನು ದಪ್ಪಕ್ಷರಗಳಲ್ಲಿ ಕಾಣಿಸಲಾಗುವುದು.
+
+<p>ಈ ಪುಟವನ್ನು ವೀಕ್ಷಣಾ ಪಟ್ಟಿಯಿ೦ದ ತೆಗೆಯಬಯಸಿದಲ್ಲಿ, ಮೇಲ್ಪಟ್ಟಿಯಲ್ಲಿ ಕಾಣಿಸಿರುವ \"ವೀಕ್ಷಣಾ ಪುಟದಿ೦ದ ತೆಗೆ\" ಅನ್ನು ಕ್ಲಿಕ್ಕಿಸಿ.",
+'alphaindexline' => "$1 ಇಂದ $2",
+'ancientpages' => "ಹಳೆಯ ಪುಟಗಳು",
+'and' => "ಮತ್ತು",
+'anontalk' => "ಈ ಐ.ಪಿ ಗೆ ಮಾತನಾಡಿ",
+'anonymous' => "ವಿಕಿಪೀಡಿಯಾದ ಅನಾಮಿಕ ಸದಸ್ಯರು",
+'apr' => "ಎಪ್ರಿಲ್",
+'article' => "ಲೇಖನ ಪುಟ",
+'articlepage' => "ಲೇಖನ ಪುಟವನ್ನು ವೀಕ್ಷಿಸಿ",
+
+
+'badarticleerror' => "ಈ ಪುಟದ ಮೇಲೆ ನೀವು ಪ್ರಯತ್ನಿಸಿದ ಕಾರ್ಯವನ್ನು ನಡೆಸಲಾಗದು.",
+'badfilename' => "ಚಿತ್ರದ ಹೆಸರನ್ನು $1 ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ.",
+'badfiletype' => "\".$1\" ಚಿತ್ರಗಳಿಗೆ ಸೂಚಿತ ಫಾರ್ಮ್ಯಾಟ್ ಅಲ್ಲ.",
+'badretype' => "ನೀವು ಕೊಟ್ಟ ಪ್ರವೇಶಪದಗಳು ಬೇರೆಬೇರೆಯಾಗಿವೆ.",
+'badtitle' => "ಸರಿಯಿಲ್ಲದ ಹೆಸರು",
+'blockedtitle' => "ಈ ಸದಸ್ಯರನ್ನು ತಡೆ ಹಿಡಿಯಲಾಗಿದೆ.",
+'blockip' => "ಈ ಸದಸ್ಯನನ್ನು ತಡೆ ಹಿಡಿಯಿರಿ",
+'blockipsuccesssub' => "ತಡೆಹಿಡಿಯುವಿಕೆ ಯಶಸ್ವಿಯಾಯಿತು.",
+'blocklink' => "ತಡೆ ಹಿಡಿಯಿರಿ",
+'blocklogentry' => "\"$1\" ಅನ್ನು $2 ರ ಸಮಯದವರೆಗೆ ತಡೆಹಿಡಿಯಲಾಗಿದೆ",
+'blocklogpage' => "ತಡೆಹಿಡಿದ ಸದಸ್ಯರ ದಿನಚರಿ",
+'bold_sample' => "ದಪ್ಪಗಿನ ಅಚ್ಚು",
+'bold_tip' => "ದಪ್ಪಗಿನ ಅಚ್ಚು",
+'booksources' => "ಪುಸ್ತಕಗಳ ಮೂಲ",
+'brokenredirects' => "ಮುರಿದ ರಿಡೈರೆಕ್ಟ್‌ಗಳು",
+'bydate' => "ದಿನಾಂಕಕ್ಕನುಗುಣವಾಗಿ",
+'byname' => "ಹೆಸರಿಗನುಗುಣವಾಗಿ",
+'bysize' => "ಗಾತ್ರಕ್ಕನುಗುಣವಾಗಿ",
+
+'cancel' => "ವಜಾ ಮಾಡಿ",
+'cannotdelete' => "ಈ ಪುಟ ಅಥವಾ ಚಿತ್ರವನ್ನು ಅಳಿಸಲಾಗಲಿಲ್ಲ. (ಬೇರೊಬ್ಬ ಸದಸ್ಯರಿ೦ದ ಆಗಲೇ ಅಳಿಸಲ್ಪಟ್ಟಿರಬಹುದು.)",
+'categories' => "ವರ್ಗಗಳು",
+'categoriespagetext' => "ವಿಕಿಯಲ್ಲಿ ಈ ಕೆಳಗಿನ ವರ್ಗಗಳಿವೆ",
+'category_header' => "\"$1\" ವರ್ಗದಲ್ಲಿರುವ ಲೇಖನಗಳು",
+'categoryarticlecount' => "ಈ ವರ್ಗದಲ್ಲಿ $1 ಲೇಖನಗಳಿವೆ.",
+'changepassword' => "ಪ್ರವೇಶ ಪದ ಬದಲಾಯಿಸಿ",
+'changes' => "ಬದಲಾವಣೆಗಳು",
+'compareselectedversions' => "ಆಯ್ಕೆ ಮಾಡಿದ ಆವೃತ್ತಿಗಳನ್ನು ಹೊಂದಾಣಿಕೆ ಮಾಡಿ ನೋಡಿ",
+'confirm' => "ಧೃಡಪಡಿಸು",
+'confirmdelete' => "ಅಳಿಸುವಿಕೆ ಧೃಡಪಡಿಸು",
+'confirmdeletetext' => "ಪುಟ ಅಥವಾ ಚಿತ್ರ ಮತ್ತು ಅದರ ಸ೦ಪೂರ್ಣ ಇತಿಹಾಸವನ್ನು ನೀವು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸಿಹಾಕುತ್ತಿದ್ದೀರಿ. ಇದನ್ನು ನೀವು ಮಾಡಬಯಸುವಿರಿ, ಇದರ ಪರಿಣಾಮಗಳನ್ನು ಬಲ್ಲಿರಿ, ಮತ್ತು [[{{ns:project}}:Policy]] ನ ಅನುಸಾರ ಇದನ್ನು ಮಾಡುತ್ತಿದ್ದೀರಿ ಎ೦ದು ದೃಢಪಡಿಸಿ.",
+'confirmprotect' => "ಸಂರಕ್ಷಣೆ ಧೃಡಪಡಿಸಿ",
+'confirmprotecttext' => "ಈ ಪುಟವನ್ನು ನಿಜಕ್ಕೂ ಸ೦ರಕ್ಷಿಸಬಯಸುತ್ತೀರಾ?",
+'confirmunprotect' => "ಸ೦ರಕ್ಷಣೆ ತೆಗೆಯಬೇಕೆ೦ದು ದೃಢಪಡಿಸಿ",
+'confirmunprotecttext' => "ಈ ಪುಟದ ಸ೦ರಕ್ಷಣೆಯನ್ನು ನಿಜಕ್ಕೂ ತೆಗೆಯಬಯಸುತ್ತೀರಾ?",
+'contribslink' => "ಕಾಣಿಕೆಗಳು",
+'contribsub' => "$1 ಗೆ",
+'contributions' => "ಸದಸ್ಯರ ಕಾಣಿಕೆಗಳು",
+'copyright' => "ಇದು ಈ ಕಾಪಿರೈಟ್‌ನಲ್ಲಿ ಲಭ್ಯವಿದೆ $1.",
+'copyrightpage' => "ವಿಕಿಪೀಡಿಯ: ಕೃತಿಸ್ವಾಮ್ಯತೆಗಳು",
+'copyrightpagename' => "{{SITENAME}} ಕಾಪಿರೈಟ್",
+'createaccount' => "ಹೊಸ ಖಾತೆ ತೆರೆಯಿರಿ",
+'createaccountmail' => "ಇ-ಅಂಚೆಯ ಮೂಲಕ",
+'creditspage' => "ಪುಟದ ಗೌರವಗಳು",
+'cur' => "ಸದ್ಯದ",
+'currentevents' => "ಪ್ರಚಲಿತ",
+'currentrev' => "ಈಗಿನ ತಿದ್ದುಪಡಿ",
+
+
+'databaseerror' => "ಡೇಟಬೇಸ್ ದೋಷ",
+'dateformat' => "ದಿನಾಂಕದ ಫಾರ್ಮ್ಯಾಟ್",
+'deadendpages' => "ಕೊನೆಯಂಚಿನ ಪುಟಗಳು",
+'dec' => "ಡಿಸೆಂಬರ್",
+'defemailsubject' => "ವಿಕಿಪೀಡಿಯ ವಿ-ಅ೦ಚೆ",
+'delete' => "ಅಳಿಸಿ",
+'deletecomment' => "ಅಳಿಸುವುದರ ಕಾರಣ",
+'deletedarticle' => "\"$1\" ಅಳಿಸಲಾಯಿತು",
+'deletedtext' => "\"$1\" ಅನ್ನು ಅಳಿಸಲಾಯಿತು.
+ಇತ್ತೀಚೆಗಿನ ಅಳಿಸುವಿಕೆಗಳ ಪಟ್ಟಿಗಾಗಿ $2 ಅನ್ನು ನೋಡಿ.",
+'deleteimg' => "ಅಳಿಸಿ",
+'deletepage' => "ಪುಟವನ್ನು ಅಳಿಸಿ",
+'deletesub' => "(\"$1\" ಅನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ)",
+'deletethispage' => "ಈ ಪುಟವನ್ನು ಅಳಿಸಿ",
+'deletionlog' => "ಅಳಿಸುವಿಕೆ ದಿನಚರಿ",
+'diff' => "ವ್ಯತ್ಯಾಸ",
+'difference' => "(ಆವೃತ್ತಿಗಳ ನಡುವಿನ ವ್ಯತ್ಯಾಸ)",
+
+
+'edit' => "ಸಂಪಾದಿಸಿ",
+'editcurrent' => "ಈ ಪುಟದ ಪ್ರಸಕ್ತ ಆವೃತ್ತಿಯನ್ನು ಸ೦ಪಾದಿಸಿ",
+'edithelp' => "ಸಂಪಾದನೆಗೆ ಸಹಾಯ",
+'edithelppage' => "ಸಹಾಯ:ಸ೦ಪಾದನೆ",
+'editing' => "'$1' ಲೇಖನ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ",
+'editinguser' => "'$1' ಲೇಖನ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ",
+'editingold' => "<strong>ಎಚ್ಚರಿಕೆ: ಈ ಪುಟದ ಹಳೆಯ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುತ್ತಿದ್ದೀರಿ. ಈ ಬದಲಾವಣೆಗಳನ್ನು ಉಳಿಸಿದಲ್ಲಿ, ನ೦ತರದ ಆವೃತ್ತಿಗಳೆಲ್ಲವೂ ಕಳೆದುಹೋಗುತ್ತವೆ.</strong>",
+'editsection' => "ಬದಲಾಯಿಸಿ",
+'editold' => "ಬದಲಾಯಿಸಿ",
+'editthispage' => "ಈ ಪುಟವನ್ನು ಬದಲಾಯಿಸಿ",
+'emailfrom' => "ಇಂದ",
+'emailmessage' => "ಸಂದೇಶ",
+'emailpage' => "ಸದಸ್ಯರಿಗೆ ವಿ-ಅ೦ಚೆ ಕಳಿಸಿ",
+'emailsend' => "ಕಳುಹಿಸಿ",
+'emailsent' => "ಇ-ಅಂಚೆ ಕಳುಹಿಸಲಾಯಿತು",
+'emailsenttext' => "ನಿಮ್ಮ ವಿ-ಅ೦ಚೆ ಸ೦ದೇಶವನ್ನು ಕಳುಹಿಸಲಾಯಿತು.",
+'emailsubject' => "ವಿಷಯ",
+'emailto' => "ಗೆ",
+'emailuser' => "ಈ ಸದಸ್ಯರಿಗೆ ವಿ-ಅ೦ಚೆ ಕಳಿಸಿ",
+'error' => "ದೋಷ",
+'errorpagetitle' => "ದೋಷ",
+'exblank' => "ಪುಟ ಖಾಲಿ ಇತ್ತು",
+'export' => "ಪುಟಗಳನ್ನು ರಫ್ತು ಮಾಡಿ",
+
+
+'feb' => "ಫೆಬ್ರುವರಿ",
+'feedlinks' => "ಫೀಡ್:",
+'filecopyerror' => "\"$1\" ಫೈಲ್ ಅನ್ನು \"$2\" ಗೆ ನಕಲಿಸಲಾಗಲಿಲ್ಲ.",
+'filedeleteerror' => "\"$1\" ಫೈಲ್ ಅನ್ನು ಅಳಿಸಲಾಗಲಿಲ್ಲ.",
+'filedesc' => "ಸಾರಾಂಶ",
+'fileexists' => "ಈ ಹೆಸರಿನ ಫೈಲ್ ಆಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ. ಈ ಹೆಸರನ್ನು ಬದಲಾಯಿಸಲು ಇಚ್ಛೆಯಿಲ್ಲದಿದ್ದರೆ, ದಯವಿಟ್ಟು $1 ಅನ್ನು ಪರೀಕ್ಷಿಸಿ.",
+'filename' => "ಕಡತದ ಹೆಸರು",
+'filenotfound' => "\"$1\" ಫೈಲನ್ನು ಹುಡುಕಲಾಗಲಿಲ್ಲ.",
+'filesource' => "ಆಕರ",
+'fileuploaded' => "ಫೈಲ್ \"$1\" ಯಶಸ್ವಿಯಾಗಿ ಅಪ್‍ಲೋಡ್ ಆಯಿತು. ದಯವಿಟ್ಟು ಕೆಳಗಿನ ಸ೦ಪರ್ಕವನ್ನು ಕ್ಲಿಕ್ಕಿಸಿ ಈ ಫೈಲ್ ನ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ತು೦ಬಿಸಿ. ಉದಾಹರಣೆಗೆ: ಈ ಫೈಲ್ ಎಲ್ಲಿ೦ದ ಬ೦ದಿತು, ಯಾವಾಗ ಯಾರಿ೦ದ ಸೃಷ್ಟಿಯಾದದ್ದು, ಮತ್ತು ನಿಮಗೆ ತಿಳಿದಿರುವ ಇತರ ಯಾವುದೇ ಮಾಹಿತಿ.
+
+$2",
+'formerror' => "ದೋಷ: ಅರ್ಜಿ ಕಳುಹಿಸಲಾಗಲಿಲ್ಲ",
+
+
+'getimagelist' => "ಚಿತ್ರಗಳ ಪಟ್ಟಿಯನ್ನು ಪಡೆಯಲಾಗುತ್ತಿದೆ",
+'go' => "ಹೋಗು",
+'searcharticle' => "ಹೋಗು",
+
+
+'headline_sample' => "ಶಿರೋಲೇಖ",
+'help' => "ಸಹಾಯ",
+'helppage' => "ಸಹಾಯ:ಪರಿವಿಡಿ",
+'hide' => "ಅಡಗಿಸು",
+'hidetoc' => "ಅಡಗಿಸು",
+'hist' => "ಇತಿಹಾಸ",
+'history' => "ಪುಟದ ಚರಿತ್ರೆ",
+'history_short' => "ಇತಿಹಾಸ",
+
+
+'ilsubmit' => "ಹುಡುಕು",
+'imagelist' => "ಚಿತ್ರಗಳ ಪಟ್ಟಿ",
+'imagepage' => "ಚಿತ್ರದ ಪುಟವನ್ನು ವೀಕ್ಷಿಸಿ",
+'import' => "ಪುಟಗಳನ್ನು ಅಮದು ಮಾಡಿ",
+'importfailed' => "ಆಮದು ಯಶಸ್ವಿಯಾಗಲಿಲ್ಲ: $1",
+'importnotext' => "ಖಾಲಿ ಅಥವಾ ಯಾವುದೇ ಶಬ್ಧಗಳಿಲ್ಲ",
+'importsuccess' => "ಆಮದು ಯಶಸ್ವಿಯಾಯಿತು!",
+'info_short' => "ಮಾಹಿತಿ",
+'internalerror' => "ಆ೦ತರಿಕ ದೋಷ",
+'ipblocklist' => "ಬ್ಲಾಕ್ ಮಾಡಲಾದ ಐಪಿ ವಿಳಾಸಗಳ ಹಾಗೂ ಬಳಕೆಯ ಹೆಸರುಗಳ ಪಟ್ಟಿ",
+'ipbreason' => "ಕಾರಣ",
+'ipbsubmit' => "ಈ ಸದಸ್ಯರನ್ನು ತಡೆಹಿಡಿಯಿರಿ",
+
+'last' => "ಕೊನೆಯ",
+'lastmodifiedat' => "ಈ ಪುಟವನ್ನು ಕೊನೆಯಾಗಿ $2, $1 ರಂದು ಬದಲಾಯಿಸಲಾಗಿತ್ತು.",
+'lineno' => "$1 ನೇ ಸಾಲು:",
+'link_sample' => "ಸಂಪರ್ಕದ ಹೆಸರು",
+'link_tip' => "ಆಂತರಿಕ ಸಂಪರ್ಕ",
+'linklistsub' => "(ಸ೦ಪರ್ಕಗಳ ಪಟ್ಟಿ)",
+'linkstoimage' => "ಈ ಕೆಳಗಿನ ಪುಟಗಳು ಈ ಚಿತ್ರಕ್ಕೆ ಸಂಪರ್ಕ ಹೊಂದಿವೆ:",
+'login' => "ಲಾಗ್ ಇನ್",
+'loginerror' => "ಲಾಗಿನ್ ದೋಷ",
+'loginproblem' => "<b>ನಿಮ್ಮ ಲಾಗಿನ್ ನಲ್ಲಿ ತೊ೦ದರೆಯಾಯಿತು.</b><br />ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ!",
+'loginreqtitle' => "ಲಾಗಿನ್ ಆಗಬೇಕು",
+'loginsuccess' => "ನೀವು ಈಗ \"$1\" ಆಗಿ ವಿಕಿಪೀಡಿಯಕ್ಕೆ ಲಾಗಿನ್ ಆಗಿದ್ದೀರಿ.",
+'loginsuccesstitle' => "ಲಾಗಿನ್ ಯಶಸ್ವಿ",
+'logout' => "ಲಾಗ್ ಔಟ್",
+'logouttitle' => "ಸದಸ್ಯ ಲಾಗೌಟ್",
+'lonelypages' => "ಒಬ್ಬಂಟಿ ಪುಟಗಳು",
+'longpages' => "ಉದ್ದನೆಯ ಪುಟಗಳು",
+
+
+'mailmypassword' => "ಹೊಸ ಪ್ರವೇಶ ಪದವನ್ನು ಇ-ಅಂಚೆ ಮೂಲಕ ಕಳುಹಿಸಿ",
+'mainpagetext' => "ವಿಕಿ ತ೦ತ್ರಾ೦ಶವನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಅನುಸ್ಥಾಪಿಸಲಾಯಿತು.",
+'makesysopname' => "ಸದಸ್ಯನ ಹೆಸರು:",
+'minlength' => "ಚಿತ್ರಗಳ ಹೆಸರಿನಲ್ಲಿ ಕನಿಷ್ಟ ಮೂರು ಅಕ್ಷರಗಳಿರಬೇಕು.",
+'minoredit' => "ಇದು ಚುಟುಕಾದ ಬದಲಾವಣೆ",
+'moredotdotdot' => "ಇನ್ನಷ್ಟು...",
+'move' => "ಸ್ಥಳಾಂತರಿಸಿ",
+'movearticle' => "ಪುಟವನ್ನು ಸ್ಥಳಾಂತರಿಸಿ",
+'movenologintext' => "ಪುಟವನ್ನು ಸ್ಥಳಾ೦ತರಿಸಲು ನೀವು ನೋ೦ದಾಯಿತ ಸದಸ್ಯರಾಗಿದ್ದು <a href=\"/wiki/Special:Userlogin\">ಲಾಗಿನ್</a> ಆಗಿರಬೇಕು.",
+'movepage' => "ಪುಟವನ್ನು ಸ್ಥಳಾಂತರಿಸಿ",
+'movepagebtn' => "ಪುಟವನ್ನು ಸ್ಥಳಾಂತರಿಸಿ",
+'movethispage' => "ಈ ಪುಟವನ್ನು ಸ್ಥಳಾಂತರಿಸಿ",
+'mycontris' => "ನನ್ನ ಕಾಣಿಕೆಗಳು",
+'mypage' => "ನನ್ನ ಪುಟ",
+'mytalk' => "ನನ್ನ ಚರ್ಚೆ",
+
+
+'navigation' => "ಸಂಚರಣೆ",
+'newarticle' => "(ಹೊಸತು)",
+'newmessageslink' => "ಹೊಸ ಸಂದೇಶಗಳು",
+'newpage' => "ಹೊಸ ಪುಟ",
+'newpageletter' => "ಹೊ",
+'newpages' => "ಹೊಸ ಪುಟಗಳು",
+'newpassword' => "ಹೊಸ ಪ್ರವೇಶ ಪದ",
+'newwindow' => "(ಹೊಸ ಕಿಟಕಿಯನ್ನು ತೆರೆಯುತ್ತದೆ)",
+'next' => "ಮುಂದಿನದು",
+'nextn' => "ಮು೦ದಿನ $1",
+'nextpage' => "ಮು೦ದಿನ ಪುಟ ($1)",
+'nlinks' => "$1 ಸ೦ಪರ್ಕಗಳು",
+'noarticletext' => "(ಈ ಪುಟದಲ್ಲಿ ಸದ್ಯಕ್ಕೆ ಏನೂ ಇಲ್ಲ)",
+'nosuchuser' => "\"$1\" ಹೆಸರಿನ ಯಾವ ಸದಸ್ಯರೂ ಇಲ್ಲ.
+ಕಾಗುಣಿತವನ್ನು ಪರೀಕ್ಷಿಸಿ, ಅಥವಾ ಕೆಳಗಿನ ಫಾರ್ಮ್ ಅನ್ನು ಉಪಯೋಗಿಸಿ ಹೊಸ ಸದಸ್ಯತ್ವವನ್ನು ಸೃಷ್ಟಿಸಿ.",
+'note' => "<strong>ಸೂಚನೆ:</strong>",
+'notloggedin' => "ಲಾಗಿನ್ ಆಗಿಲ್ಲ",
+'nstab-category' => "ವರ್ಗ",
+'nstab-help' => "ಸಹಾಯ",
+'nstab-image' => "ಚಿತ್ರ",
+'nstab-main' => "ಲೇಖನ",
+'nstab-mediawiki' => "ಸಂದೇಶ",
+'nstab-special' => "ವಿಶೇಷ",
+'nstab-user' => "ಸದಸ್ಯರ ಪುಟ",
+'nstab-project' => "ಬಗ್ಗೆ",
+
+
+'ok' => "ಸರಿ",
+'oldpassword' => "ಹಳೆಯ ಪ್ರವೇಶ ಪದ",
+'othercontribs' => "$1 ರ ಕೆಲಸವನ್ನು ಆಧರಿಸಿ.",
+'otherlanguages' => "ಇತರ ಭಾಷೆಗಳು",
+
+
+'pagecategories' => "ವರ್ಗಗಳು",
+'pagemovedsub' => "ಸ್ಥಳಾ೦ತರಿಸುವಿಕೆ ಯಶಸ್ವಿಯಾಯಿತು",
+'popularpages' => "ಜನಪ್ರಿಯ ಪುಟಗಳು",
+'portal' => "ಸಮುದಾಯ ಪುಟ",
+'postcomment' => "ನಿಮ್ಮ ಮಾತನ್ನು ಲಗತ್ತಿಸಿ",
+'powersearch' => "ಹುಡುಕಿ",
+'preview' => "ಮುನ್ನೋಟ",
+'previewnote' => "ಇದು ಕೇವಲ ಮುನ್ನೋಟ, ಪುಟವನ್ನು ಇನ್ನೂ ಉಳಿಸಲಾಗಿಲ್ಲ ಎ೦ಬುದನ್ನು ಮರೆಯದಿರಿ!",
+'protect' => "ಸಂರಕ್ಷಿಸು",
+'protectcomment' => "ಸ೦ರಕ್ಷಿಸಲು ಕಾರಣ",
+'protectedpage' => "ಸ೦ರಕ್ಷಿತ ಪುಟ",
+
+
+'randompage' => "ಯಾದೃಚ್ಛಿಕ ಪುಟ",
+'rclinks' => "ಕೊನೆಯ $2 ದಿನಗಳಲ್ಲಿ ಮಾಡಿದ $1 ಕೊನೆಯ ಬದಲಾವಣೆಗಳನ್ನು ನೋಡಿ <br />$3",
+'rclistfrom' => "$1 ಇಂದ ಪ್ರಾರಂಭಿಸಿ ಮಾಡಲಾದ ಬದಲಾವಣೆಗಳನ್ನು ನೋಡಿ",
+'rcnote' => "ಕೊನೆಯ <strong>$2</strong> ದಿನಗಳಲ್ಲಿ ಮಾಡಿದ <strong>$1</strong> ಬದಲಾವಣೆಗಳು ಕೆಳಗಿನಂತಿವೆ.",
+'recentchanges' => "ಇತ್ತೀಚೆಗಿನ ಬದಲಾವಣೆಗಳು",
+'recentchangescount' => "ಇತ್ತೀಚೆಗಿನ ಬದಲಾವಣೆಗಳಲ್ಲಿರುವ ವಿಷಯಗಳ ಸಂಖ್ಯೆ",
+'recentchangeslinked' => "ಸಂಬಂಧಪಟ್ಟ ಬದಲಾವಣೆಗಳು",
+'recentchangestext' => "ವಿಕಿಗೆ ಮಾಡಲ್ಪಟ್ಟ ಇತ್ತೀಚಿನ ಬದಲಾವಣೆಗಳನ್ನು ಈ ಪುಟದಲ್ಲಿ ನೀವು ಕಾಣಬಹುದು.",
+'returnto' => "$1 ಗೆ ಹಿಂತಿರುಗಿ.",
+'rights' => "ಹಕ್ಕುಗಳು:",
+
+
+'savearticle' => "ಪುಟವನ್ನು ಉಳಿಸಿ",
+'savefile' => "ಕಡತವನ್ನು ಉಳಿಸಿ",
+'search' => "ಹುಡುಕು",
+'searchbutton' => "ಹುಡುಕು",
+'searchresults' => "ಶೋಧನೆಯ ಫಲಿತಾಂಶಗಳು",
+'shortpages' => "ಪುಟ್ಟ ಪುಟಗಳು",
+'show' => "ತೋರಿಸು",
+'showpreview' => "ಮುನ್ನೋಟ",
+'showtoc' => "ತೋರಿಸು",
+'sitestats' => "ತಾಣದ ಅಂಕಿಅಂಶಗಳು",
+'sitestatstext' => "ಒಟ್ಟು '''$1''' ಪುಟಗಳು ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿವೆ.
+ಈ ಸಂಖ್ಯೆ \"ಚರ್ಚೆ\" ಪುಟಗಳನ್ನು, ವಿಕಿಪೀಡಿಯಾದ ಬಗೆಗಿನ ಪುಟಗಳನ್ನು, ಹಾಗೂ ಪುಟ್ಟ \"ಚುಟುಕು\" ಪುಟಗಳನ್ನೂ, ರೆಡೈರೆಕ್ಟ್ ಮಾಡಿದ ಪುಟಗಳನ್ನು ಹಾಗೂ ಬೇರೆಲ್ಲೂ ಸೇರಿಸಲಾಗದ ಕೆಲವು ಇತರೆ ಪುಟಗಳನ್ನು ಒಳಗೊಂಡಿದೆ.
+
+ಇವುಗಳನ್ನು ಬಿಟ್ಟು, ಒಟ್ಟು '''$2''' ಬಹುಶಃ ನಿಜವಾದ ಲೇಖನಗಳಿಂದ ಕೂಡಿದ ಪುಟಗಳಿವೆ.",
+'sitesupport' => "ದೇಣಿಗೆ",
+'specialpage' => "ವಿಶೇಷ ಪುಟ",
+'specialpages' => "ವಿಶೇಷ ಪುಟಗಳು",
+'spheading' => "ಎಲ್ಲಾ ಸದಸ್ಯರಿಗೂ ಇರುವ ವಿಶೇಷ ಪುಟಗಳು",
+'statistics' => "ಅಂಕಿ ಅಂಶಗಳು",
+'storedversion' => "ಈಗಾಗಲೇ ಉಳಿಸಲಾಗಿರುವ ಆವೃತ್ತಿ",
+'subcategories' => "ಉಪವಿಭಾಗಗಳು",
+'subcategorycount' => "ಒಟ್ಟು $1 ಉಪವಿಭಾಗಗಳು ಈ ವರ್ಗದಡಿ ಇವೆ.",
+'summary' => "ಸಾರಾಂಶ",
+
+
+'talkpage' => "ಈ ಪುಟದ ಬಗ್ಗೆ ಚರ್ಚೆ ಮಾಡಿ",
+'timezonelegend' => "ಟೈಮ್ ಝೋನ್",
+'toc' => "ಪರಿವಿಡಿ",
+'toolbox' => "ಉಪಕರಣ",
+
+
+'uctop' => " (ಮೇಲಕ್ಕೆ)",
+'uncategorizedpages' => "ವರ್ಗ ಗೊತ್ತು ಮಾಡದ ಪುಟಗಳು",
+'unprotect' => "ಸಂರಕ್ಷಣೆ ತೆಗೆ",
+'unusedimages' => "ಉಪಯೋಗಿಸದ ಚಿತ್ರಗಳು",
+'unwatch' => "ವೀಕ್ಷಣಾ ಪಟ್ಟಿಯಿಂದ ತೆಗೆ",
+'upload' => "ಫೈಲ್ ಅಪ್ಲೋಡ್",
+'userlogin' => "ಲಾಗ್ ಇನ್",
+'userlogout' => "ಲಾಗ್ ಔಟ್",
+'userstats' => "ಸದಸ್ಯರ ಅಂಕಿ ಅಂಶ",
+'userstatstext' => "ಒಟ್ಟು '''$1''' ನೊಂದಾಯಿಸಿದ ಸದಸ್ಯರಿದ್ದಾರೆ. ಇವರಲ್ಲಿ '''$2''' ಮಂದಿ ನಿರ್ವಾಹಕರಿದ್ದಾರೆ ($3 ನೋಡಿ).",
+
+
+'version' => "ಆವೃತ್ತಿ",
+'viewsource' => "ಆಕರ ವೀಕ್ಷಿಸು",
+
+
+'wantedpages' => "ಬೇಕಾಗಿರುವ ಪುಟಗಳು",
+'watch' => "ವೀಕ್ಷಿಸಿ",
+'watchthis' => "ಈ ಪುಟವನ್ನು ವೀಕ್ಷಿಸಿ",
+'watchthispage' => "ಈ ಪುಟವನ್ನು ವೀಕ್ಷಿಸಿ",
+'whatlinkshere' => "ಇಲ್ಲಿಗೆ ಯಾವ ಸಂಪರ್ಕ ಕೂಡುತ್ತದೆ",
+
+
+'yourname' => "ನಿಮ್ಮ ಬಳಕೆಯ ಹೆಸರು",
+'yourpassword' => "ನಿಮ್ಮ ಪ್ರವೇಶಪದ",
+);
+
+
+?>
diff --git a/languages/messages/MessagesKo.php b/languages/messages/MessagesKo.php
new file mode 100644
index 000000000000..76bddab69ea5
--- /dev/null
+++ b/languages/messages/MessagesKo.php
@@ -0,0 +1,1205 @@
+<?php
+/** Korean (한국어)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => '특수기능',
+ NS_MAIN => '',
+ NS_TALK => '토론',
+ NS_USER => '사용자',
+ NS_USER_TALK => '사용자토론',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1토론',
+ NS_IMAGE => '그림',
+ NS_IMAGE_TALK => '그림토론',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki토론',
+ NS_TEMPLATE => '틀',
+ NS_TEMPLATE_TALK => '틀토론',
+ NS_HELP => '도움말',
+ NS_HELP_TALK => '도움말토론',
+ NS_CATEGORY => '분류',
+ NS_CATEGORY_TALK => '분류토론',
+);
+
+$quickbarSettings = array(
+ '없음', '왼쪽', '오른쪽', '왼쪽 고정', '오른쪽 고정'
+);
+
+$skinNames = array(
+ 'standard' => '표준',
+ 'davinci' => '다빈치',
+ 'mono' => '모노',
+ 'monobook' => '모노북',
+ 'my skin' => '내 스킨',
+);
+
+$bookstoreList = array(
+ 'Aladdin.co.kr' => 'http://www.aladdin.co.kr/catalog/book.asp?ISBN=$1',
+ 'inherit' => true,
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'ko';
+$dateFormats = array(
+ 'ko time' => 'H:i',
+ 'ko date' => 'Y년 M월 j일 (D)',
+ 'ko both' => 'Y년 M월 j일 (D) H:i',
+);
+
+$messages = array(
+'tog-underline' => '고리에 밑줄치기:',
+'tog-highlightbroken' => '없는 문서로 가는 고리를 <a href="" class="new">이렇게</a> 보이기 (선택하지 않으면 이렇게<a href="" class="internal">?</a> 보임)',
+'tog-justify' => '문단 정렬',
+'tog-hideminor' => '사소한 편집을 최근 바뀜에서 숨기기',
+'tog-extendwatchlist' => '주시 문서를 모든 변경 목록에 적용하기',
+'tog-usenewrc' => '향상된 최근 바뀜 (자바스크립트)',
+'tog-numberheadings' => '머릿글 번호 매기기',
+'tog-showtoolbar' => '편집창에 툴바 보이기 (자바스크립트)',
+'tog-editondblclick' => '더블클릭으로 문서 편집하기 (자바스크립트)',
+'tog-editsection' => '"편집" 부분을 눌러 부분을 편집하기',
+'tog-editsectiononrightclick'=> '제목을 오른쪽 클릭해서 부분 편집하기 (자바스크립트)',
+'tog-showtoc' => '문서의 차례 보여주기 (머릿글이 4개 이상인 경우)',
+'tog-rememberpassword' => '자동 로그인',
+'tog-editwidth' => '편집상자의 너비를 최대로 맞추기',
+'tog-watchcreations' => '내가 처음 만드는 문서를 주시 목록에 추가함.',
+'tog-watchdefault' => '편집하는 글을 항상 주시문서에 추가하기',
+'tog-minordefault' => '‘사소한 편집’을 항상 선택하기',
+'tog-previewontop' => '편집상자 앞에 미리보기 창을 보여주기',
+'tog-previewonfirst' => '처음 편집할 때 미리보기 보여주기',
+'tog-nocache' => '문서 캐시 끄기',
+'tog-enotifwatchlistpages'=> '문서가 바뀌면 이메일을 보내기',
+'tog-enotifusertalkpages'=> '내 토론 문서가 바뀌면 이메일을 보내기',
+'tog-enotifminoredits' => '사소한 편집에도 이메일을 보내기',
+'tog-enotifrevealaddr' => '알림 메일에 내 이메일 주소를 밝히기',
+'tog-shownumberswatching'=> '주시 사용자 수를 보여주기',
+'tog-fancysig' => '서명에 고리를 걸지 않기',
+'tog-externaleditor' => '외부 입력기를 기본값으로 사용하기',
+'tog-externaldiff' => '외부 비교 툴을 기본값으로 사용하기',
+'tog-uselivepreview' => '실시간 미리보기 사용하기 (자바스크립트) (실험적 기능)',
+'tog-forceeditsummary' => '편집 요약을 쓰지 않았을 때 알려주기',
+'tog-watchlisthideown' => '주시문서 목록에 내 편집을 숨기기',
+'tog-watchlisthidebots' => '주시문서 목록에 봇 편집을 숨기기',
+'underline-always' => '항상',
+'underline-never' => '치지 않음',
+'underline-default' => '브라우저 설정을 따르기',
+'skinpreview' => '(미리 보기)',
+'sunday' => '일요일',
+'monday' => '월요일',
+'tuesday' => '화요일',
+'wednesday' => '수요일',
+'thursday' => '목요일',
+'friday' => '금요일',
+'saturday' => '토요일',
+'sun' => '일',
+'mon' => '월',
+'tue' => '화',
+'wed' => '수',
+'thu' => '목',
+'fri' => '금',
+'sat' => '토',
+'january' => '1월',
+'february' => '2월',
+'march' => '3월',
+'april' => '4월',
+'may_long' => '5월',
+'june' => '6월',
+'july' => '7월',
+'august' => '8월',
+'september' => '9월',
+'october' => '10월',
+'november' => '11월',
+'december' => '12월',
+'jan' => '1',
+'feb' => '2',
+'mar' => '3',
+'apr' => '4',
+'may' => '5',
+'jun' => '6',
+'jul' => '7',
+'aug' => '8',
+'sep' => '9',
+'oct' => '10',
+'nov' => '11',
+'dec' => '12',
+'categories' => '분류',
+'pagecategories' => '분류',
+'category_header' => '"$1" 분류에 속해 있는 문서',
+'subcategories' => '하위 분류',
+'mainpage' => '대문',
+'mainpagetext' => '<big>\'\'\'미디어위키가 성공적으로 설치되었습니다.\'\'\'</big>',
+'mainpagedocfooter' => '위키 프로그램에 대한 정보는[http://meta.wikimedia.org/wiki/Help:Contents 이곳]에서 얻을 수 있습니다.
+
+== 시작하기 ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings 설정하기]
+* [http://www.mediawiki.org/wiki/Help:FAQ 미디어위키 FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce 미디어위키 발표 메일링 리스트]',
+'portal' => '사용자 모임',
+'portal-url' => 'Project:사용자 모임',
+'about' => '소개',
+'aboutsite' => '{{SITENAME}} 소개',
+'aboutpage' => 'Project:소개',
+'article' => '문서 내용',
+'help' => '도움말',
+'helppage' => 'Help:목차',
+'bugreports' => '버그 신고',
+'bugreportspage' => 'Project:버그 신고',
+'sitesupport' => '기부 안내',
+'sitesupport-url' => 'Project:사이트 지원',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => '편집 도움말',
+'newwindow' => '(새 창으로 열림)',
+'edithelppage' => 'Project:문서 편집 도움말',
+'cancel' => '취소',
+'qbfind' => '찾기',
+'qbbrowse' => '탐색',
+'qbedit' => '편집',
+'qbpageoptions' => '문서 기능',
+'qbpageinfo' => '문서 정보',
+'qbmyoptions' => '나의 문서',
+'qbspecialpages' => '특수기능',
+'moredotdotdot' => '더 보기...',
+'mypage' => '내 사용자 문서',
+'mytalk' => '내 사용자 토론',
+'anontalk' => '익명 사용자 토론',
+'metadata_help' => '메타데이터([[Project:메타데이터]]에서 자세한 설명을 볼 수 있습니다):',
+'currentevents' => '요즘 화제',
+'currentevents-url' => '요즘 화제',
+'disclaimers' => '면책 조항',
+'disclaimerpage' => 'Project:면책 조항',
+'privacy' => '개인정보 정책',
+'privacypage' => 'Project:개인정보 정책',
+'errorpagetitle' => '오류',
+'returnto' => '$1(으)로 돌아가기',
+'tagline' => '{{SITENAME}}',
+'search' => '찾기',
+'searchbutton' => '찾기',
+'go' => '가기',
+'searcharticle' => '가기',
+'history' => '문서 역사',
+'history_short' => '역사',
+'updatedmarker' => '마지막으로 방문한 후 변경됨',
+'info_short' => '정보',
+'printableversion' => '인쇄용',
+'permalink' => '고유링크',
+'print' => '인쇄',
+'edit' => '편집',
+'editthispage' => '이 문서 편집하기',
+'delete' => '삭제',
+'deletethispage' => '이 문서 삭제하기',
+'undelete_short' => '$1개의 편집 되살리기',
+'protect' => '보호',
+'protectthispage' => '이 문서 보호하기',
+'unprotect' => '보호 해제',
+'unprotectthispage' => '이 문서 보호 해제하기',
+'newpage' => '새 문서',
+'talkpage' => '토론 문서',
+'specialpage' => '특수 문서',
+'personaltools' => '개인 도구',
+'articlepage' => '문서 보기',
+'talk' => '토론',
+'toolbox' => '도구모음',
+'userpage' => '사용자 문서 보기',
+'projectpage' => '프로젝트 문서 보기',
+'imagepage' => '그림 문서 보기',
+'viewtalkpage' => '토론 보기',
+'otherlanguages' => '다른 언어',
+'redirectedfrom' => '($1에서 넘어옴)',
+'autoredircomment' => '[[$1]]로 넘겨주기',
+'redirectpagesub' => '넘겨주기 문서',
+'lastmodifiedat' => '이 문서는 $2, $1에 마지막으로 바뀌었습니다.',
+'viewcount' => '이 문서는 총 $1번 읽혔습니다.',
+'copyright' => '문서는 $1 저작권 하에 있습니다.',
+'protectedpage' => '보호된 문서',
+'jumptosearch' => '찾기',
+'badaccess' => '권한 오류',
+'versionrequired' => '미디어위키 $1 버전 필요',
+'versionrequiredtext' => '이 문서를 보기 위해서는 미디어위키 $1 버전이 필요합니다. [[Special:Version]]을 참고하세요.',
+'ok' => '확인',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => '원본 주소 "$1"',
+'youhavenewmessages' => '$1 란에 누군가 글을 남겼습니다. ($2)',
+'newmessageslink' => '사용자 토론',
+'newmessagesdifflink' => '바뀐 내용 비교',
+'editsection' => '편집',
+'editold' => '편집',
+'editsectionhint' => '부분 편집: $1',
+'toc' => '목차',
+'showtoc' => '보이기',
+'hidetoc' => '숨기기',
+'thisisdeleted' => '$1을 보거나 되살리겠습니까?',
+'viewdeleted' => '$1을 보시겠습니까?',
+'restorelink' => '$1개의 삭제된 편집',
+'feedlinks' => '피드:',
+'feed-invalid' => '잘못된 구독 피드 방식입니다.',
+'nstab-main' => '문서',
+'nstab-user' => '사용자 문서',
+'nstab-media' => '미디어',
+'nstab-special' => '특수 문서',
+'nstab-project' => '프로젝트 문서',
+'nstab-image' => '그림',
+'nstab-mediawiki' => '메시지',
+'nstab-template' => '틀',
+'nstab-help' => '도움말',
+'nstab-category' => '분류',
+'nosuchaction' => '해당하는 동작이 없습니다.',
+'nosuchactiontext' => 'URL로 요청한 동작을 위키에서 판별할 수 없습니다.',
+'nosuchspecialpage' => '해당하는 특수기능이 없습니다.',
+'nospecialpagetext' => '요청한 특수 문서가 존재하지 않습니다. 특수 문서의 목록은 [[Special:Specialpages|여기]]에서 볼 수 있습니다.',
+'error' => '오류',
+'databaseerror' => '데이터베이스 오류',
+'dberrortext' => '데이터베이스 쿼리 구문 오류가 발생했습니다. 소프트웨어의 버그가 있을 수 있습니다. 마지막으로 요청한 데이터베이스 쿼리는 "<tt>$2</tt>" 함수에서 쓰인 <blockquote><tt>$1</tt></blockquote>입니다. MySQL은 "<tt>$3: $4</tt>" 오류를 냈습니다.',
+'dberrortextcl' => '데이터베이스 쿼리 구문 오류가 발생했습니다. 마지막으로 요청한 데이터베이스 쿼리는 "$2" 함수에서 쓰인 "$1"입니다. MySQL은 "$3: $4" 오류를 냈습니다.',
+'noconnect' => '죄송합니다. 위키의 기술적인 문제로 인해 데이터베이스 서버에 접근할 수 없습니다.<br />$1',
+'nodb' => '$1 데이터베이스를 선택할 수 없습니다.',
+'cachederror' => '아래는 요청한 문서의 캐시 복사본으로, 최신이 아닐 수 있습니다.',
+'laggedslavemode' => '주의: 문서가 최근 것이 아닐 수 있습니다.',
+'readonly' => '데이터베이스 잠김',
+'enterlockreason' => '데이터베이스를 잠그는 이유와 예상되는 기간을 적어 주세요.',
+'readonlytext' => '현재 데이터베이스는 편집을 하지 못하도록 잠겨 있습니다. 데이터베이스 관리가 끝난 후에는 다시 정상으로 돌아올 것입니다.
+
+관리자가 데이터베이스를 잠근 이유는 다음과 같습니다: $1',
+'missingarticle' => '데이터베이스에서 "$1" 문서를 찾지 못했습니다.
+
+이것은 삭제된 문서의 비교/역사를 가리키는 고리인 경우가 많습니다.
+
+만약 그런 경우가 아니라면, 프로그램 버그를 찾아냈을 수도 있습니다. 관리자에게 이 URL을 보내 주세요.',
+'readonly_lag' => '슬레이브 서버에서 마스터 서버를 따라잡을 때까지 데이터베이스가 자동적으로 잠깁니다.',
+'internalerror' => '내부 오류',
+'filecopyerror' => '"$1" 파일을 "$2"로 복사할 수 없습니다.',
+'filerenameerror' => '파일 "$1"의 이름을 "$2"로 바꿀 수 없습니다.',
+'filedeleteerror' => '파일 "$1"을 삭제할 수 없습니다.',
+'filenotfound' => '"$1" 파일을 찾을 수 없습니다.',
+'unexpected' => '예상되지 않은 값: "$1"="$2"',
+'formerror' => '오류: 양식을 제출할 수 없습니다.',
+'badarticleerror' => '지금의 명령은 이 문서에서는 실행할 수 없습니다.',
+'cannotdelete' => '문서나 파일을 삭제할 수 없습니다. 이미 삭제되었을 수도 있습니다.',
+'badtitle' => '잘못된 제목',
+'badtitletext' => '문서 제목이 잘못되었거나 비어있습니다.',
+'perfdisabled' => '이 기능을 쓰면 아무도 위키를 쓸 수 없을 정도로 데이터베이스가 느려지기 때문에 임시로 비활성화되었습니다.',
+'perfdisabledsub' => '이것은 $1에서의 복사본입니다.',
+'perfcached' => '다음 자료는 캐시된 것이므로 현재 상황을 반영하지 않을 수 있습니다.',
+'perfcachedts' => '다음 자료는 캐시된 것으로, $1에 마지막으로 갱신되었습니다.',
+'wrong_wfQuery_params' => 'wfQuery()에서 잘못된 매개변수 발생<br />함수: $1<br />쿼리: $2',
+'viewsource' => '내용 보기',
+'protectedtext' => '이 문서는 편집하지 못하도록 보호되어 있습니다. 문서 보호에 대해 알아보려면 [[Project:보호 문서]]를 참조하세요.
+
+문서의 내용을 보거나 복사할 수는 있습니다:',
+'protectedinterface' => '이 문서는 소프트웨어 인터페이스에 쓰이는 문서로, 잠겨 있습니다.',
+'editinginterface' => '\'\'\'경고\'\'\': 소프트웨어에서 사용하는 메시지 문서를 고치고 있습니다. 이것은 모든 사용자에게 영향을 끼칩니다.',
+'sqlhidden' => '(SQL 쿼리 숨겨짐)',
+'logouttitle' => '로그아웃',
+'logouttext' => '\'\'\'{{SITENAME}}에서 로그아웃했습니다.\'\'\' 이대로 이름없이 {{SITENAME}}을(를) 이용하거나, 방금 사용했던 계정이나 다른 계정으로 다시 로그인해서 이용할 수 있습니다. 웹 브라우저의 캐시를 지우지 않으면 몇몇 문서에서 로그인이 되어 있는 것처럼 보일 수 있다는 점을 유의해 주십시오.',
+'welcomecreation' => '== $1 님, 환영합니다! ==
+
+계정이 만들어졌습니다. [[Special:Preferences|사용자 환경 설정]]에서 당신의 {{SITENAME}} 사용자 환경 설정을 바꿀 수 있습니다.',
+'loginpagetitle' => '로그인',
+'yourname' => '이름',
+'yourpassword' => '암호',
+'yourpasswordagain' => '암호 확인',
+'remembermypassword' => '로그인 상태를 저장합니다.',
+'yourdomainname' => '도메인 이름',
+'externaldberror' => '외부 인증 데이터베이스에 오류가 있거나, 외부 계정을 갱신할 권한이 없습니다.',
+'loginproblem' => '\'\'\'로그인에 문제가 발생했습니다.\'\'\'<br />다시 시도해 보세요.',
+'alreadyloggedin' => '당신은 이미 $1 사용자로 로그인했습니다!',
+'login' => '로그인',
+'loginprompt' => '{{SITENAME}}에 로그인하려면 쿠키를 사용할 수 있어야 합니다.',
+'userlogin' => '로그인 / 계정 만들기',
+'logout' => '로그아웃',
+'userlogout' => '로그아웃',
+'notloggedin' => '로그인하고 있지 않음',
+'nologin' => '계정이 없나요? $1.',
+'nologinlink' => '계정을 만들 수 있습니다',
+'createaccount' => '계정 만들기',
+'gotaccount' => '계정이 이미 있나요? $1.',
+'gotaccountlink' => '로그인하세요',
+'createaccountmail' => '이메일로 하기',
+'badretype' => '암호가 서로 다릅니다.',
+'userexists' => '사용자 이름이 이미 등록되어 있습니다. 다른 이름으로 만들어주십시오.',
+'youremail' => '이메일 *',
+'username' => '사용자 이름:',
+'uid' => '사용자 ID:',
+'yourrealname' => '실명 *',
+'yourlanguage' => '언어:',
+'yournick' => '닉네임:',
+'badsig' => '서명이 잘못되었습니다. HTML 태그를 확인해주세요.',
+'email' => '이메일',
+'prefs-help-email-enotif'=> '이 주소는 이메일 알림을 설정했을 때 이메일을 받는 데에도 사용됩니다.',
+'loginerror' => '로그인 오류',
+'prefs-help-email' => '* 이메일(선택): 당신의 메일 주소를 공개하지 않고 다른 사용자들과 이야기를 할 수 있습니다.',
+'nocookiesnew' => '사용자 계정이 생성되었지만 로그인하고 있지는 않습니다. {{SITENAME}}은 로그인을 위해 쿠키를 사용하고, 현재 당신의 웹 브라우저에서는 쿠키 사용이 비활성되어 있습니다. 쿠키 사용을 활성화한 다음 로그인해 주세요.',
+'nocookieslogin' => '{{SITENAME}}에서는 로그인을 위해 쿠키를 사용합니다. 당신의 웹 브라우저에서 쿠키가 비활성되어 있습니다. 쿠키 사용을 활성화한 다음 로그인해 주세요.',
+'noname' => '사용자 이름이 올바르지 않습니다.',
+'loginsuccesstitle' => '로그인 성공',
+'loginsuccess' => '\'\'\'"$1" 계정으로 {{SITENAME}}에 로그인했습니다.\'\'\'',
+'nosuchuser' => '사용자 \'$1\'이 존재하지 않습니다. 철자가 맞는지 확인하고, 또는 새 계정을 만들 수 있습니다.',
+'nosuchusershort' => '사용자 \'$1\'이 존재하지 않습니다. 철자가 맞는지 확인해 주세요.',
+'nouserspecified' => '사용자 이름을 입력하지 않았습니다.',
+'wrongpassword' => '암호가 틀립니다. 다시 시도해 주세요.',
+'wrongpasswordempty' => '비밀번호가 비었습니다. 다시 시도해 주세요.',
+'mailmypassword' => '새 암호를 이메일로 보내기',
+'passwordremindertitle' => '{{SITENAME}}에서 보내는 새 암호',
+'passwordremindertext' => 'IP 주소 $1에게서 당신에게 {{SITENAME}}의 새 암호를 보내달라는 요청이 왔습니다. ($4)
+
+사용자 "$2"의 암호는 이제 "$3"입니다. 로그인한 후에 암호를 변경해 주세요.
+
+만약 다른 사람이 암호 요청을 했거나 예전 암호를 기억해냈다면 이 메시지를 무시하고 예전 암호를 계속 사용할 수 있습니다.',
+'noemail' => '사용자 "$1"에 등록된 이메일 주소가 없습니다.',
+'passwordsent' => '\'$1\' 계정의 새로운 암호를 이메일로 보냈습니다. 암호를 받고 다시 로그인해 주세요.',
+'eauthentsent' => '확인 이메일을 보냈습니다. 이메일 내용의 지시대로 계정 확인 절차를 실행해 주십시오.',
+'mailerror' => '메일 보내기 오류: $1',
+'acct_creation_throttle_hit'=> '당신은 이미 $1개의 계정이 있습니다. 더 이상 만들 수 없습니다.',
+'emailauthenticated' => '당신의 이메일 주소는 $1에 인증되었습니다.',
+'emailnotauthenticated' => '당신의 이메일 주소가 아직 확인되지 않았습니다. 이메일 확인 절차를 거치지 않으면 다음 이메일 기능을 사용할 수 없습니다.',
+'noemailprefs' => '이 기능을 사용하기 위해서는 이메일 주소를 기입해야 합니다.',
+'emailconfirmlink' => '이메일 주소 확인',
+'invalidemailaddress' => '이메일 주소 입력이 잘못되었습니다. 정상적인 이메일을 입력하거나, 칸을 비워 주세요.',
+'accountcreated' => '계정 만들어짐',
+'accountcreatedtext' => '$1 계정이 만들어졌습니다.',
+'bold_sample' => '굵은 글씨',
+'bold_tip' => '굵은 글씨',
+'italic_sample' => '기울인 글씨',
+'italic_tip' => '기울인 글씨',
+'link_sample' => '고리 제목',
+'link_tip' => '내부 고리',
+'extlink_sample' => 'http://www.example.com 사이트 이름',
+'extlink_tip' => '바깥 고리 (앞에 <nowiki>http://</nowiki>를 붙여야 합니다.)',
+'headline_sample' => '제목',
+'headline_tip' => '두번째로 큰 문단 제목',
+'math_sample' => '여기에 수식을 쓰세요',
+'math_tip' => '수식 (LaTeX)',
+'nowiki_sample' => '여기에 위키 문법을 사용하지 않을 글을 적어 주세요',
+'nowiki_tip' => '위키 문법 무시하기',
+'image_sample' => 'Example.jpg',
+'image_tip' => '그림 추가하기',
+'media_sample' => 'Example.ogg',
+'media_tip' => '미디어 파일 링크',
+'sig_tip' => '내 서명과 현재 시간',
+'hr_tip' => '가로줄 (되도록 사용하지 말아 주세요)',
+'summary' => '편집 요약',
+'subject' => '주제/제목',
+'minoredit' => '사소한 편집',
+'watchthis' => '이 문서 주시하기',
+'savearticle' => '저장',
+'preview' => '미리보기',
+'showpreview' => '미리보기',
+'showlivepreview' => '실시간 미리보기',
+'showdiff' => '차이 보기',
+'anoneditwarning' => '\'\'\'주의\'\'\': 로그인하고 있지 않습니다. 당신의 IP 주소가 문서 역사에 남게 됩니다.',
+'missingsummary' => '\'\'\'알림:\'\'\' 편집 요약을 적지 않았습니다. 그대로 저장하면 편집 요약 없이 저장됩니다.',
+'blockedtitle' => '사용자 차단됨',
+'blockedtext' => '당신의 계정 혹은 IP가 $1에 의해 차단되었습니다. 차단된 이유는 다음과 같습니다: "$2"
+
+[[User talk:$3]]을 참고하여 주시기 바랍니다.',
+'blockedoriginalsource' => '아래에 \'\'\'$1\'\'\'의 내용이 나와 있습니다:',
+'blockededitsource' => '아래에 \'\'\'$1\'\'\'에서의 \'\'\'당신의 편집\'\'\'이 나와 있습니다:',
+'whitelistedittitle' => '편집하려면 로그인 필요',
+'whitelistedittext' => '문서를 편집하려면 $1해야 합니다.',
+'whitelistreadtitle' => '문서를 보려면 로그인 필요',
+'whitelistreadtext' => '문서를 읽기 위해서는 [[Special:Userlogin|로그인]]해야 합니다.',
+'whitelistacctitle' => '계정을 생성하도록 허용되어 있지 않습니다.',
+'confirmedittitle' => '편집하려면 이메일 인증 필요',
+'confirmedittext' => '문서를 고치려면 이메일 인증 절차가 필요합니다. [[Special:Preferences|사용자 환경 설정]]에서 이메일 주소를 입력하고 이메일 주소 인증을 해 주시기 바랍니다.',
+'loginreqtitle' => '로그인 필요',
+'loginreqlink' => '로그인',
+'loginreqpagetext' => '다른 문서를 보기 위해서는 $1해야 합니다.',
+'accmailtitle' => '암호를 보냈습니다.',
+'accmailtext' => '"$1"의 암호를 $2로 보냈습니다.',
+'newarticle' => '(새 문서)',
+'newarticletext' => '이 문서는 아직 만들어지지 않았습니다. 문서를 만들기 위해서는 아래의 상자에 내용을 입력하면 됩니다. (자세한 내용은 [[{{MediaWiki:helppage}}|도움말 문서]]를 읽어 주시기 바랍니다.) 만약 잘못 찾아온 문서라면 브라우저의 \'\'\'뒤로\'\'\' 버튼을 눌러 주세요.',
+'anontalkpagetext' => '----
+여기는 계정에 로그인하지 않은 익명 사용자를 위한 토론 문서입니다. 익명 사용자의 사용자 이름은 IP 주소로 나오기 때문에, 한 IP 주소를 여러 명이 같이 쓰거나 유동 IP를 사용하는 경우 엉뚱한 사람에게 의견이 전달될 수 있습니다. 이러한 문제를 피하려면 [[Special:Userlogin|계정을 만들거나 로그인해 주시기 바랍니다]].',
+'noarticletext' => '현재 문서는 비어 있습니다. 이 제목으로 [[Special:Search/{{PAGENAME}}|검색]]하거나 문서를 [{{fullurl:{{FULLPAGENAME}}|action=edit}} 편집]할 수 있습니다.',
+'clearyourcache' => '\'\'\'참고:\'\'\' 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 무시해야 합니다. \'\'\'모질라 / 파이어폭스 / 사파리:\'\'\' \'시프트\' 키를 누르면서 \'새로고침\'을 클릭하거나, \'\'Ctrl-F5\'\'를 입력; \'\'\'컨커러:\'\'\' 단순히 \'새로고침\'을 클릭하거나 \'\'F5\'\'를 입력; \'\'\'오페라\'\'\' 사용자는 \'도구→설정\'에서 캐시를 완전히 비워야 합니다.',
+'usercssjsyoucanpreview'=> '\'\'\'안내\'\'\': CSS/JS 문서를 저장하기 전에 \'미리보기\' 기능을 통해 적용되는 점을 확인해주세요.',
+'usercsspreview' => '\'\'\'이것은 CSS 미리보기로, 아직 저장하지 않았다는 것을 주의해 주세요!\'\'\'',
+'userjspreview' => '\'\'\'이것은 자바스크립트 미리보기로, 아직 저장하지 않았다는 것을 주의해 주세요!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'경고\'\'\': ‘$1’ 스킨이 존재하지 않습니다. css와 js 문서의 제목은 {{ns:user}}:홍길동/monobook.css처럼 소문자로 씁니다.',
+'updated' => '(바뀜)',
+'note' => '\'\'\'주의:\'\'\'',
+'previewnote' => '\'\'\'지금 미리보기로 보고 있는 내용은 아직 저장되지 않았습니다!\'\'\'',
+'session_fail_preview' => '\'\'\'죄송합니다. 세션 데이터가 없어져 편집을 저장하지 못했습니다. 다시 시도해도 되지 않으면 로그아웃한 다음 다시 로그인해 보십시오.\'\'\'',
+'previewconflict' => '이 미리보기는 저장할 때의 모습, 즉 위쪽 편집창의 문서를 반영합니다.',
+'session_fail_preview_html'=> '\'\'\'죄송합니다. 세션 데이터가 없어져 편집을 저장하지 못했습니다.\'\'\'
+
+문서에 HTML 태그가 사용되었기 때문에, 자바스크립트 공격을 막기 위해 미리 보기는 숨겨져 있습니다.
+
+\'\'\'다시 시도해도 되지 않으면 로그아웃한 다음 다시 로그인해 보십시오.\'\'\'',
+'editing' => '$1 편집하기',
+'editinguser' => '$1 편집하기',
+'editingsection' => '$1 편집하기 (부분)',
+'editingcomment' => '$1 편집하기 (덧붙이기)',
+'editconflict' => '편집 충돌: $1',
+'explainconflict' => '문서를 편집하는 도중에 누군가가 이 문서를 바꾸었습니다. 위쪽에 있는 문서가 현재 바뀐 문서이고, 아래쪽의 문서가 당신이 편집한 문서입니다. 아래쪽의 내용을 위쪽에 적절히 합쳐 주시기 바랍니다. <b>위쪽의 편집 내역만이</b> 저장됩니다.',
+'yourtext' => '당신의 편집',
+'storedversion' => '바뀐 현재 문서',
+'nonunicodebrowser' => '\'\'\'주의: 당신의 웹 브라우저가 유니코드를 완벽하게 지원하지 않습니다. 몇몇 문자가 16진수 코드로 나타날 수 있습니다.\'\'\'',
+'editingold' => '\'\'\'경고\'\'\': 지금 옛날 버전의 문서를 고치고 있습니다. 이것을 저장하면 최근에 편집된 부분이 사라질 수 있습니다.',
+'yourdiff' => '차이',
+'copyrightwarning' => '{{SITENAME}}의 모든 기여는 $2 라이선스에 따라 배포된다는 점을 유의해 주시기 바랍니다. ($1에서 자세한 사항을 읽어 주세요.) 만약 당신이 이에 대해 찬성하지 않는다면, 여기에 편집 내역을 저장하지 말아 주세요. 또한 당신의 기여는 직접 작성했거나, 또는 퍼블릭 도메인과 같은 자유 문서에서 가져온 것을 보증해야 합니다. \'\'\'저작권이 있는 내용을 허가 없이 저장하지 마세요!\'\'\'',
+'copyrightwarning2' => '{{SITENAME}}의 모든 기여는 $2 라이선스에 따라 배포된다는 점을 유의해 주시기 바랍니다. 만약 당신이 이에 대해 찬성하지 않는다면, 여기에 편집 내역을 저장하지 말아 주세요.<br />또한 당신의 기여는 직접 작성했거나, 또는 퍼블릭 도메인과 같은 자유 문서에서 가져온 것을 보증해야 합니다. ($1에서 자세한 사항을 읽어 주세요.) \'\'\'저작권이 있는 내용을 허가 없이 저장하지 마세요!\'\'\'',
+'longpagewarning' => '\'\'\'주의: 이 문서의 용량이 $1킬로바이트입니다. 몇몇 웹 브라우저에서는 32킬로바이트 이상의 문서를 편집할 때 문제가 발생할 수 있습니다. 만약의 경우를 대비하여, 문서를 여러 문단으로 나누어서 편집할 수 있습니다.\'\'\'',
+'longpageerror' => '\'\'\'오류: 문서의 크기가 $1킬로바이트로, 최대 가능한 크기인 $2킬로바이트보다 큽니다. 저장할 수 없습니다.\'\'\'',
+'readonlywarning' => '\'\'\'주의: 데이터베이스가 관리를 위해 잠겨 있습니다. 따라서 문서를 편집한 내용을 지금 저장할 없습니다. 편집 내용을 다른 곳에 저장한 후, 나중에 다시 시도해 주세요.\'\'\'',
+'protectedpagewarning' => '\'\'\'주의: 이 문서는 관리자만 편집할 수 있도록 보호되어 있습니다. [[Project:문서 보호 정책|문서 보호 정책]]을 참고하십시오.\'\'\'',
+'semiprotectedpagewarning'=> '\'\'\'주의:\'\'\' 이 문서는 잠겨 있습니다. 등록된 사용자만이 편집할 수 있습니다.',
+'templatesused' => '이 문서에서 사용하고 있는 틀:',
+'edittools' => '<!-- 이 문서는 편집 창과 파일 올리기 창에 출력됩니다. -->',
+'nocreatetitle' => '문서 생성 제한',
+'nocreatetext' => '이 사이트에서는 새로운 문서를 생성하는 것에 제한을 두고 있습니다. 이미 존재하는 문서를 편집하거나, [[Special:Userlogin|로그인하거나 계정을 만들 수 있습니다]].',
+'revhistory' => '문서 역사',
+'viewpagelogs' => '이 문서의 기록 보기',
+'nohistory' => '이 문서는 편집 역사가 없습니다.',
+'revnotfound' => '버전 없음',
+'revnotfoundtext' => '문서의 해당 버전을 찾지 못했습니다. 접속할 때 사용한 URL을 확인해 주세요.',
+'loadhist' => '문서 역사 불러오는 중',
+'currentrev' => '현재 버전',
+'revisionasof' => '$1 버전',
+'revision-info' => '$1 버전; $2',
+'previousrevision' => '←이전 버전',
+'nextrevision' => '다음 버전→',
+'currentrevisionlink' => '현재 버전의 문서 보기',
+'cur' => '현재',
+'next' => '다음',
+'last' => '이전',
+'orig' => '처음',
+'histlegend' => '비교하려는 버전들을 선택한 다음 버튼을 누르세요.<br />설명: (현재) = 현재 버전과의 차이, (이전) = 바로 이전 버전과의 차이, 잔글 = 사소한 편집',
+'deletedrev' => '[삭제됨]',
+'histfirst' => '처음',
+'histlast' => '마지막',
+'difference' => '(버전 사이의 차이)',
+'loadingrev' => '버전 간의 차이를 받고 있습니다.',
+'lineno' => '$1번째 줄:',
+'editcurrent' => '현재 버전의 문서를 편집합니다',
+'selectnewerversionfordiff'=> '비교할 최근 버전을 선택해 주세요.',
+'selectolderversionfordiff'=> '비교할 과거 버전을 선택해 주세요.',
+'compareselectedversions'=> '선택된 버전들을 비교하기',
+'searchresults' => '검색 결과',
+'searchresulttext' => '{{SITENAME}} 검색에 대한 자세한 정보는 [[Project:Searching|{{SITENAME}} 검색]]을 보세요.',
+'searchsubtitle' => '열쇠말 \'\'\'[[:$1]]\'\'\'',
+'searchsubtitleinvalid' => '열쇠말 \'$1\'',
+'badquery' => '잘못된 질의 구문',
+'badquerytext' => '당신의 질의 구문을 실행하지 못했습니다. 3글자보다 짧은 문자열 검색은 지원하지 않습니다. 입력한 문장에 오타가 없는지도 확인해 주시기 바랍니다. 다른 문장을 입력해주세요.',
+'matchtotals' => '열쇠말 \'$1\'이 문서 제목 $2개, 문서 내용 $3개에 들어있습니다.',
+'noexactmatch' => '\'\'\'$1 문서가 없습니다.\'\'\' 문서를 [[:$1|만들 수]] 있습니다.',
+'titlematches' => '문서 제목 일치',
+'notitlematches' => '제목과 맞는 문서가 없습니다.',
+'textmatches' => '문서 내용 일치',
+'notextmatches' => '내용에 열쇠말을 담고 있은 문서가 없습니다.',
+'prevn' => '이전 $1개',
+'nextn' => '다음 $1개',
+'viewprevnext' => '보기: ($1) ($2) ($3).',
+'showingresults' => '\'\'\'$2\'\'\'번 부터 \'\'\'$1\'\'\'개의 결과입니다.',
+'showingresultsnum' => '\'\'\'$2\'\'\'번 부터 \'\'\'$3\'\'\'개의 결과입니다.',
+'nonefound' => '\'\'\'참고\'\'\': "have"와 "from"과 같은 일반적인 단어는 검색에 포함되지 않고, 이런 단어를 포함한 경우 검색이 효과적이지 못할 수 있습니다. 또는 여러 단어를 동시에 검색한 경우에도 효과적인 검색이 되지 않습니다(검색하려는 단어가 모두 들어 있는 문서만이 결과에 나타납니다).',
+'powersearch' => '찾기',
+'searchdisabled' => '{{SITENAME}} 검색 기능이 비활성되어 있습니다. 기능이 작동하지 않는 동안에는 Google을 이용해 검색할 수 있습니다. 검색 엔진의 내용은 최근 것이 아닐 수 있다는 점을 주의해주세요.',
+'blanknamespace' => '(일반)',
+'preferences' => '사용자 환경 설정',
+'prefsnologin' => '로그인해야 합니다',
+'prefsnologintext' => '사용자 환경 설정을 바꾸려면 먼저 [[Special:Userlogin|로그인]]해야 합니다.',
+'prefsreset' => '사용자 환경 설정을 기본값으로 되돌렸습니다.',
+'qbsettings' => '빨리가기 맞춤',
+'changepassword' => '암호 바꾸기',
+'skin' => '스킨',
+'math' => '수식',
+'dateformat' => '날짜 형식',
+'datedefault' => '기본값',
+'datetime' => '날짜와 시각',
+'math_failure' => '해석 실패',
+'math_unknown_error' => '알 수 없는 오류',
+'math_unknown_function' => '알 수 없는 함수',
+'math_syntax_error' => '구문 오류',
+'math_image_error' => 'PNG 변환 실패 - latex, dvips, gs가 올바르게 설치되어 있는지 확인해 주세요.',
+'math_bad_tmpdir' => '수식을 임시 폴더에 저장하거나 폴더를 만들 수 없습니다.',
+'math_bad_output' => '수식을 출력 폴더에 저장하거나 폴더를 만들 수 없습니다.',
+'math_notexvc' => '실행할 수 있는 texvc이 없습니다. 설정을 위해 math/README를 읽어 주세요.',
+'prefs-personal' => '사용자 정보',
+'prefs-rc' => '최근 바뀜',
+'prefs-watchlist' => '주시문서 목록',
+'prefs-watchlist-days' => '주시문서 목록에 보이는 날짜 수:',
+'prefs-watchlist-edits' => '주시문서 목록에 보이는 편집 갯수:',
+'prefs-misc' => '기타',
+'saveprefs' => '저장',
+'resetprefs' => '기본 설정으로',
+'oldpassword' => '현재 암호',
+'newpassword' => '새 암호',
+'retypenew' => '새 암호 확인',
+'textboxsize' => '편집상자 크기',
+'rows' => '줄 수:',
+'columns' => '열:',
+'searchresultshead' => '찾기 결과 설정',
+'resultsperpage' => '쪽마다 보이는 결과',
+'contextlines' => '결과마다 보이는 줄 수:',
+'contextchars' => '각 줄에 보이는 글 수:',
+'stubthreshold' => '토막글을 표시할 한계값:',
+'recentchangescount' => '최근 바뀜에 보이는 항목 수',
+'savedprefs' => '설정을 저장했습니다.',
+'timezonelegend' => '시간대',
+'timezonetext' => '현지 시간과 서버 시간(UTC) 사이의 시차를 써 주세요.',
+'localtime' => '현지 시각',
+'timezoneoffset' => '시간차',
+'servertime' => '서버 시각',
+'guesstimezone' => '웹 브라우저 설정에서 가져오기',
+'allowemail' => '다른 사용자로부터의 이메일 허용',
+'defaultns' => '기본으로 다음의 네임스페이스에서 찾기:',
+'default' => '기본값',
+'files' => '파일',
+'userrights-lookup-user'=> '사용자 권한 관리',
+'userrights-user-editname'=> '사용자 이름:',
+'editusergroup' => '사용자 그룹 편집',
+'userrights-editusergroup'=> '사용자 그룹 편집',
+'saveusergroups' => '사용자 권한 저장',
+'userrights-groupsmember'=> '현재 권한:',
+'userrights-groupsavailable'=> '가능한 권한:',
+'userrights-groupshelp' => '현재 권한에서 제거하려는 권한이나, 가능한 권한에서 추가하려는 권한을 선택해 주세요. 선택하지 않은 권한은 변경되지 않습니다. CTRL을 누른 채 클릭하면 선택을 해제할 수 있습니다.',
+'group' => '권한:',
+'group-bot' => '봇',
+'group-sysop' => '관리자',
+'group-bureaucrat' => '뷰로크랫',
+'group-all' => '(모두)',
+'group-bot-member' => '봇',
+'group-sysop-member' => '관리자',
+'group-bureaucrat-member'=> '뷰로크랫',
+'grouppage-bot' => 'Project:봇',
+'grouppage-sysop' => 'Project:관리자',
+'grouppage-bureaucrat' => 'Project:뷰로크랫',
+'changes' => '변경',
+'recentchanges' => '최근 바뀜',
+'recentchangestext' => '위키의 최근 바뀜 내역이 나와 있습니다.',
+'rcnote' => '다음은 $3까지 \'\'\'$2\'\'\'일간 바뀐 \'\'\'$1\'\'\'개의 문서입니다.',
+'rcnotefrom' => '다음은 \'\'\'$2\'\'\'에서부터 바뀐 \'\'\'$1\'\'\'개의 문서입니다.',
+'rclistfrom' => '$1 이래로 바뀐 문서',
+'rcshowhideminor' => '사소한 편집을 $1',
+'rcshowhidebots' => '봇을 $1',
+'rcshowhideliu' => '로그인한 사용자를 $1',
+'rcshowhideanons' => '익명 사용자를 $1',
+'rcshowhidepatr' => '검토된 편집을 $1',
+'rcshowhidemine' => '내 편집을 $1',
+'rclinks' => '최근 $2일 동안에 바뀐 $1개의 문서를 봅니다.<br />$3',
+'diff' => '차이',
+'hist' => '역사',
+'hide' => '숨기기',
+'show' => '보이기',
+'minoreditletter' => '잔글',
+'newpageletter' => '새글',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[$1 명이 주시하고 있음]',
+'rc_categories' => '다음 분류로 제한 (‘|’로 구분)',
+'rc_categories_any' => '모두',
+'upload' => '파일 올리기',
+'uploadbtn' => '파일 올리기',
+'reupload' => '다시 올리기',
+'reuploaddesc' => '올리기 양식으로 돌아가기',
+'uploadnologin' => '로그인하고 있지 않습니다.',
+'uploadnologintext' => '파일을 올리려면 [[Special:Userlogin|로그인]]해야 합니다.',
+'upload_directory_read_only'=> '파일 저장 디렉토리($1)에 쓰기 권한이 없습니다.',
+'uploaderror' => '올리기 오류',
+'uploadtext' => '파일을 올리기 위해서는 아래의 양식을 채워주세요. 또는 예전에 올라온 그림을 찾으려면 [[Special:Imagelist|파일 목록]]을 사용할 수 있습니다. [[Special:Log/upload|올리기 기록]]에서 파일이 올라온 기록과 삭제된 기록을 볼 수 있습니다.
+
+문서에 그림을 집어넣으려면 \'\'\'<nowiki>[[</nowiki>{{ns:image}}<nowiki>:File.jpg]]</nowiki>\'\'\', \'\'\'<nowiki>[[</nowiki>{{ns:image}}<nowiki>:File.png|대체 설명]]</nowiki>\'\'\'과 같이 사용합니다. 또는 파일에 직접 링크하려면 \'\'\'<nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki>\'\'\'와 같이 씁니다.',
+'uploadlog' => '올리기 기록',
+'uploadlogpage' => '올리기 기록',
+'uploadlogpagetext' => '최근 올라온 그림 목록입니다.',
+'filename' => '파일이름',
+'filedesc' => '파일의 설명',
+'fileuploadsummary' => '설명:',
+'filestatus' => '저작권 상태',
+'filesource' => '출처',
+'copyrightpage' => 'Project:저작권',
+'copyrightpagename' => '{{SITENAME}} 저작권',
+'uploadedfiles' => '파일 올리기',
+'ignorewarning' => '경고를 무시하고 저장합니다.',
+'ignorewarnings' => '모든 경고 무시하기',
+'minlength' => '파일 이름은 세 글자 이상이어야 합니다.',
+'illegalfilename' => '파일명 "$1"에는 문서 제목으로 허용되지 않는 글자가 포함되어 있습니다. 이름을 바꾸어 다시 시도해 주세요.',
+'badfilename' => '파일 이름이 "$1"로 바뀌었습니다.',
+'badfiletype' => '".$1" 형식은 권장하지 않습니다.',
+'largefile' => '그림 크기는 $1 KB 이하를 권장합니다. 이 파일은 $2 바이트입니다.',
+'largefileserver' => '이 파일의 크기가 서버에서 허용된 설정보다 큽니다.',
+'emptyfile' => '당신이 올린 파일이 빈 파일입니다. 파일명을 잘못 입력했을 수도 있습니다. 다시 한 번 확인해 주시기 바랍니다.',
+'fileexists' => '같은 이름의 파일이 이미 있습니다. 파일을 바꾸고 싶지 않다면 $1을 확인해 주시기 바랍니다.',
+'fileexists-forbidden' => '같은 이름의 파일이 이미 있습니다. 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> '같은 이름의 파일이 이미 공용 파일 저장소에 있습니다. 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => '올리기 성공',
+'fileuploaded' => '파일 $1을 올렸습니다. $2에서 파일의 정보, 출처, 파일이 만들어진 시기와 만든 사람의 정보 등을 추가해 주시기 바랍니다. 만약 그림이라면, 다음과 같은 내용을 추가할 수 있습니다: <tt><nowiki>[[</nowiki>{{ns:Image}}<nowiki>:$1|thumb|설명]]</nowiki></tt>',
+'uploadwarning' => '올리기 경고',
+'savefile' => '파일 저장',
+'uploadedimage' => '"[[$1]]"를 올렸습니다.',
+'uploaddisabled' => '올리기 비활성됨',
+'uploaddisabledtext' => '이 위키에서는 파일 올리기 기능이 비활성되어 있습니다.',
+'uploadscripted' => '이 파일에는 HTML이나 다른 스크립트 코드가 포함되어 있어, 웹 브라우저에서 오류를 일으킬 수 있습니다.',
+'uploadcorrupt' => '이 파일은 잘못된 형식을 가지고 있습니다. 파일을 확인하고 다시 시도해 주세요.',
+'uploadvirus' => '이 파일에 바이러스가 포함되어 있습니다! 상세 설명: $1',
+'sourcefilename' => '원본 파일명',
+'destfilename' => '파일의 새 이름',
+'filewasdeleted' => '같은 이름을 가진 파일이 올라온 적이 있었고, 그 후에 삭제되었습니다. 올리기 전에 $1을 확인해 주시기 바랍니다.',
+'license' => '저작권',
+'nolicense' => '선택하지 않음',
+'imagelist' => '그림 목록',
+'imagelisttext' => '$1개의 파일이 $2 순으로 정렬되어 있습니다.',
+'imagelistforuser' => '$1이 올린 그림만을 보여줍니다.',
+'getimagelist' => '그림 목록 가져오기',
+'ilsubmit' => '찾기',
+'showlast' => '최근의 $1개 파일이 $2 순으로 정렬되어 있습니다.',
+'byname' => '이름',
+'bydate' => '날짜',
+'bysize' => '크기',
+'imgdelete' => '삭제',
+'imgdesc' => '설명',
+'imglegend' => '상세 설명: (설명) = 그림 설명을 보거나 편집합니다.',
+'imghistory' => '파일 역사',
+'revertimg' => '되돌리기',
+'deleteimg' => '삭제',
+'deleteimgcompletely' => '이 파일의 과거 버전을 모두 삭제하기',
+'imghistlegend' => '상세 설명: (현재) = 현재의 그림입니다. (삭제) = 옛 버전을 삭제합니다. (돌림) = 옛 버전으로 되돌려 놓습니다.<br />특정 날짜에 올라온 그림을 보려면, 날짜를 선택해주세요.',
+'imagelinks' => '그림 고리',
+'linkstoimage' => '다음 문서들이 이 그림을 사용하고 있습니다:',
+'nolinkstoimage' => '이 그림을 사용하는 문서가 없습니다.',
+'sharedupload' => '이 파일은 공용 저장소에 있습니다. 다른 프로젝트에서 사용하고 있을 가능성이 있습니다.',
+'shareduploadwiki' => '$1에서 더 자세한 정보를 얻을 수 있습니다.',
+'shareduploadwiki-linktext'=> '파일 설명 문서',
+'noimage' => '파일이 없습니다. $1 할 수 있습니다.',
+'noimage-linktext' => '업로드',
+'uploadnewversion-linktext'=> '이 파일의 새로운 버전을 올리기',
+'mimesearch' => 'MIME 검색',
+'mimetype' => 'MIME 종류:',
+'download' => '다운로드',
+'unwatchedpages' => '주시되지 않는 문서 목록',
+'listredirects' => '넘겨주기 문서 목록',
+'unusedtemplates' => '사용하지 않는 틀 목록',
+'unusedtemplatestext' => '다른 문서에 사용되지 않는 틀을 모아 놓았습니다. 삭제하기 전에 쓰이지 않는지를 다시 한번 확인해 주세요.',
+'unusedtemplateswlh' => '다른 고리',
+'randomredirect' => '임의 넘겨주기 문서로',
+'statistics' => '통계',
+'sitestats' => '{{SITENAME}} 통계',
+'userstats' => '사용자 통계',
+'sitestatstext' => '현재 데이터베이스에는 \'\'\'$1\'\'\'개의 문서가 있습니다. 이것은 토론 문서, {{SITENAME}} 문서, "토막글" 문서, 넘겨주기 문서 등을 포함하고 있습니다. 이것들을 제외하면 \'\'\'$2\'\'\'개의 문서가 있습니다.
+
+\'\'\'$8\'\'\'개의 파일이 올라와 있습니다.
+
+위키가 설치된 후 문서는 전체 \'\'\'$3\'\'\'번 읽혔고, \'\'\'$4\'\'\'번 편집되었습니다. 문서당 평균 편집 횟수는 \'\'\'$5\'\'\'번이고, 한번 편집할 때마다 평균 \'\'\'$6\'\'\'번 문서를 보았습니다.
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue job queue]의 길이는 \'\'\'$7\'\'\'입니다.',
+'userstatstext' => '\'\'\'$1\'\'\'명의 사용자가 등록되어 있고, 이 중 관리자는 \'\'\'$2\'\'\'명으로, 전체의 \'\'\'$4%\'\'\'입니다. ($3 참조)',
+'disambiguations' => '동음이의 문서 목록',
+'disambiguationspage' => 'Template:Disambig',
+'disambiguationstext' => '아래의 문서들은 "동음이의 문서"를 가리키고 있습니다. 그 링크를 적절한 주제에 맞게 바꾸어야 합니다.<br />$1을 가리키는 문서를 동음이의 문서로 간주합니다.<br />다른 네임스페이스로 연결된 문서들은 목록에 없습니다.',
+'doubleredirects' => '이중 넘겨주기 목록',
+'doubleredirectstext' => '각 열의 첫번째 문서는 두번째 문서로, 두번째 문서는 세번째 문서로 연결됩니다. 첫번째 문서를 마지막 문서로 연결해 주어야 합니다.',
+'brokenredirects' => '끊긴 넘겨주기 목록',
+'brokenredirectstext' => '존재하지 않는 문서로 넘겨주기가 되어 있는 문서의 목록입니다:',
+'nbytes' => '$1 바이트',
+'ncategories' => '$1개의 분류',
+'nlinks' => '$1개의 고리',
+'nmembers' => '$1명의 사용자',
+'nrevisions' => '$1개의 판',
+'nviews' => '$1번 읽음',
+'lonelypages' => '외톨이 문서 목록',
+'uncategorizedpages' => '분류되지 않은 문서 목록',
+'uncategorizedcategories'=> '분류되지 않은 분류 목록',
+'uncategorizedimages' => '분류되지 않은 그림 목록',
+'unusedcategories' => '사용하지 않는 분류 목록',
+'unusedimages' => '사용하지 않는 그림 목록',
+'popularpages' => '인기있는 문서 목록',
+'wantedcategories' => '필요한 분류 목록',
+'wantedpages' => '필요한 문서 목록',
+'mostlinked' => '가장 많이 연결된 문서 목록',
+'mostlinkedcategories' => '가장 많이 연결된 분류 목록',
+'mostcategories' => '가장 많이 분류된 문서 목록',
+'mostimages' => '가장 많이 연결된 그림 목록',
+'mostrevisions' => '가장 많이 편집된 문서 목록',
+'allpages' => '모든 문서 목록',
+'prefixindex' => '접두어 목록',
+'randompage' => '임의 문서로',
+'shortpages' => '짧은 문서 목록',
+'longpages' => '긴 문서 목록',
+'deadendpages' => '막다른 문서 목록',
+'listusers' => '사용자 목록',
+'specialpages' => '특수 문서 목록',
+'spheading' => '일반 특수 문서',
+'restrictedpheading' => '제한된 특수 문서',
+'recentchangeslinked' => '여기서 가리키는 문서',
+'rclsub' => '(\'$1\'의 고리들이 가리키는)',
+'newpages' => '새 문서 목록',
+'ancientpages' => '오래된 문서 목록',
+'intl' => '인터위키',
+'move' => '이동',
+'movethispage' => '문서 이동하기',
+'unusedimagestext' => '<p>다른 사이트에서 그림의 URL을 사용하고 있을 가능성이 있고, 따라서 이 목록에 있는 그림도 사용하고 있을 수 있습니다.</p>',
+'unusedcategoriestext' => '사용하지 않는 분류 문서들의 목록입니다.',
+'booksources' => '책의 출처',
+'categoriespagetext' => '위키에 존재하는 분류들의 목록입니다.',
+'data' => '자료',
+'userrights' => '샤용자 권한 관리',
+'groups' => '사용자 권한 목록',
+'booksourcetext' => '아래의 목록은 새 책이나 헌 책을 파는 몇몇 사이트로, 찾고 있는 책의 정보를 가지고 있을 수 있습니다.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1에서 $2까지',
+'version' => '버전',
+'log' => '로그 목록',
+'alllogstext' => '파일 올리기, 문서 삭제, 보호, 사용자 차단, 관리자 기록이 모두 나와 있습니다. 원하는 기록을 선택해서 볼 수 있습니다.',
+'logempty' => '일치하는 항목이 없습니다.',
+'nextpage' => '다음 문서 ($1)',
+'allpagesfrom' => '다음으로 시작하는 문서들을 보여주기:',
+'allarticles' => '모든 문서',
+'allinnamespace' => '$1 네임스페이스의 모든 문서',
+'allnotinnamespace' => '$1 네임스페이스를 제외한 모든 문서 목록',
+'allpagesprev' => '이전',
+'allpagesnext' => '다음',
+'allpagessubmit' => '표시',
+'allpagesprefix' => '다음 접두어로 시작하는 문서 목록:',
+'allpagesbadtitle' => '문서 제목이 잘못되었거나 다른 사이트로 연결되는 인터위키를 가지고 있습니다. 문서 제목에 사용할 수 없는 문자를 사용했을 수 있습니다.',
+'mailnologin' => '보낼 이메일 주소가 없음',
+'mailnologintext' => '다른 사용자에게 이메일을 보내려면 {{SITENAME}}에 [[Special:Userlogin|로그인]]한 상태에서 [[Special:Preferences|사용자 환경 설정]]에 자신의 이메일 주소를 저장해야 합니다.',
+'emailuser' => '이 사용자에게 이메일 보내기',
+'emailpage' => '사용자에게 이메일 보내기',
+'emailpagetext' => '이 사용자가 환경설정에 올바른 주소를 적었다면 아래 틀을 이용하여 이메일을 보낼 수 있습니다. 받는이가 바로 답장할 수 있도록, 당신의 설정에 적힌 주소가 \'보낸이\' 주소에 들어갑니다.',
+'usermailererror' => '메일 객체에서 오류 발생:',
+'defemailsubject' => '{{SITENAME}} 이메일',
+'noemailtitle' => '이메일 주소 없음',
+'noemailtext' => '이 사용자는 올바른 이메일 주소를 입력하지 않았거나, 이메일을 받지 않도록 설정해 놓았습니다.',
+'emailfrom' => '이메일 발신자',
+'emailto' => '수신자',
+'emailsubject' => '제목',
+'emailmessage' => '내용',
+'emailsend' => '보내기',
+'emailsent' => '이메일 보냄',
+'emailsenttext' => '이메일을 보냈습니다.',
+'watchlist' => '주시문서 목록',
+'watchlistfor' => '(\'\'\'$1\'\'\'의 목록)',
+'nowatchlist' => '주시하는 문서가 아직 없습니다.',
+'watchlistanontext' => '주시문서 목록의 항목들을 보거나 편집하려면 $1을(를) 보세요.',
+'watchlistcount' => '\'\'\'주시문서 목록에는 토론 문서를 포함해 $1개의 문서가 있습니다.\'\'\'',
+'clearwatchlist' => '주시문서 목록 비우기',
+'watchlistcleartext' => '정말로 이 항목들을 제거할까요?',
+'watchlistclearbutton' => '목록 초기화',
+'watchlistcleardone' => '목록이 초기화되었습니다. $1개의 항목이 제거되었습니다.',
+'watchnologin' => '로그인하고 있지 않습니다.',
+'watchnologintext' => '[[Special:Userlogin|로그인]]을 해야만 주시문서 목록을 볼 수 있습니다.',
+'addedwatch' => '주시문서 목록에 추가',
+'addedwatchtext' => '[[:$1]] 문서가 주시문서 목록에 추가되었습니다. 앞으로 이 문서나 토론 문서가 변경되면 [[Special:Recentchanges|최근 바뀜]]에서 변경점들이 \'\'\'굵은 글씨\'\'\'로 나타날 것입니다. 더 이상 주시하지 않으려면 \'\'\'주시 해제\'\'\'를 누르면 됩니다.',
+'removedwatch' => '주시문서 목록에서 제거',
+'removedwatchtext' => '문서 \'[[:$1]]\'를 주시문서 목록에서 제거했습니다.',
+'watch' => '주시',
+'watchthispage' => '주시하기',
+'unwatch' => '주시 해제',
+'unwatchthispage' => '주시 해제하기',
+'notanarticle' => '문서가 아님',
+'watchnochange' => '주어진 기간 중에 바뀐 주시문서가 없습니다.',
+'watchdetails' => '* $1 개(토론 제외)의 문서를 주시하고 있습니다.
+* [[Special:Watchlist/edit|주시문서 목록 전체 보기·편집]]
+* [[Special:Watchlist/clear|모두 주시문서 목록에서 삭제]]',
+'wlheader-enotif' => '* 이메일 알림 기능이 활성화되었습니다.',
+'wlheader-showupdated' => '* 마지막으로 방문한 이후에 바뀐 문서들은 \'\'\'굵은 글씨\'\'\'로 표시됩니다.',
+'removechecked' => '선택한 문서를 주시문서 목록에서 삭제',
+'watchlistcontains' => '$1개의 문서를 주시하고 있습니다.',
+'watcheditlist' => '주시문서 목록이 순서대로 정렬되어 있습니다. 주시하지 않을 문서들을 선택하고 아래의 버튼을 누르면 주시문서 목록에서 제거됩니다. (일반 문서를 주시 해제하면 토론 문서도 자동으로 해제되고, 반대의 경우도 마찬가지입니다.)',
+'removingchecked' => '주시문서 목록에서 항목들을 삭제하는 중입니다...',
+'couldntremove' => '\'$1\'을 삭제할 수 없습니다.',
+'iteminvalidname' => '"$1" 항목에 문제가 발생했습니다. 이름이 잘못되었습니다...',
+'wlnote' => '다음은 최근 \'\'\'$2\'\'\'시간 동안에 바뀐 $1개의 문서입니다.',
+'wlshowlast' => '$3 최근 $1 시간 $2 일 동안에 바뀐 문서',
+'wlsaved' => '이것은 주시문서 목록에 저장되어 있는 판입니다.',
+'wlhideshowown' => '내 편집을 $1',
+'wlhideshowbots' => '봇을 $1',
+'wldone' => '완료.',
+'enotif_mailer' => '{{SITENAME}} 자동 알림 메일',
+'enotif_reset' => '모든 문서를 방문한 것으로 표시하기',
+'enotif_newpagetext' => '이것은 새 문서입니다.',
+'changed' => '바뀜',
+'created' => '만들어짐',
+'enotif_subject' => '{{SITENAME}}의 문서 $PAGETITLE이 $PAGEEDITOR에 의해 $CHANGEDORCREATED되었습니다',
+'enotif_lastvisited' => '당신의 마지막 방문 이후의 모든 변경사항을 보려면 $1을(를) 보십시오.',
+'deletepage' => '문서 삭제하기',
+'confirm' => '확인',
+'excontent' => '내용: \'$1\'',
+'excontentauthor' => '내용: \'$1\' (그리고 편집한 사람은 \'$2\'뿐)',
+'exbeforeblank' => '비우기 전의 내용: \'$1\'',
+'exblank' => '문서가 비어있음',
+'confirmdelete' => '삭제 확인',
+'deletesub' => '($1 삭제)',
+'historywarning' => '주의: 현재 삭제하려는 문서에는 문서 역사가 있습니다:',
+'confirmdeletetext' => '문서나 그림, 그리고 이 문서의 역사를 삭제하려고 합니다. 삭제하기 전에 다시 한번 문서 역사를 확인해 주시기 바랍니다.',
+'actioncomplete' => '명령완료',
+'deletedtext' => '$1이 삭제되었습니다. $2에서 최근의 삭제 기록을 볼 수 있습니다.',
+'deletedarticle' => '[[$1]]을 삭제함',
+'dellogpage' => '삭제 기록',
+'dellogpagetext' => '아래의 목록은 최근에 삭제된 문서들입니다.',
+'deletionlog' => '삭제 기록',
+'reverted' => '이전 버전으로 되돌렸습니다.',
+'deletecomment' => '삭제 이유',
+'imagereverted' => '이전 버전으로 되돌렸습니다.',
+'rollback' => '편집 되돌리기',
+'rollback_short' => '되돌리기',
+'rollbacklink' => '되돌리기',
+'rollbackfailed' => '되돌리기 실패',
+'cantrollback' => '편집을 되돌릴 수 없습니다. 문서를 편집한 사용자가 한명뿐입니다.',
+'alreadyrolled' => '[[:$1]]에서 [[User:$2|$2]]([[User talk:$2|토론]])의 편집을 되돌릴 수 없습니다. 누군가가 문서를 고치거나 되돌렸습니다.
+
+마지막으로 문서를 편집한 사람은[[User:$3|$3]]([[User talk:$3|토론]])입니다.',
+'revertpage' => '[[Special:Contributions/$2|$2]]([[User talk:$2|토론]])의 편집을 [[Special:Contributions/$1|$1]]의 버전으로 되돌림',
+'sessionfailure' => '로그인 세션에 문제가 발생한 것 같습니다. 세션 하이재킹을 막기 위해 동작이 취소되었습니다. 브라우저의 "뒤로" 버튼을 누르고 문서를 새로고침한 후에 다시 시도해 주세요.',
+'protectlogpage' => '문서 보호 기록',
+'protectlogtext' => '아래의 목록은 문서 보호와 보호 해제 기록입니다.',
+'protectedarticle' => '"[[$1]]" 문서가 보호되었음',
+'unprotectedarticle' => '"[[$1]]" 문서가 보호 해제되었음',
+'protectsub' => '("$1" 보호하기)',
+'confirmprotecttext' => '이 문서를 정말로 보호하겠습니까?',
+'confirmprotect' => '보호 확인',
+'protectmoveonly' => '문서 이동만 보호하기',
+'protectcomment' => '보호 이유',
+'unprotectsub' => '("$1" 보호 해제하기)',
+'confirmunprotecttext' => '이 문서를 정말로 보호 해제하겠습니까?',
+'confirmunprotect' => '보호 해제 확인',
+'unprotectcomment' => '보호 해제 이유',
+'protect-unchain' => '이동 권한을 수동으로 조정',
+'protect-text' => '\'\'\'$1\'\'\' 문서의 보호 수준을 보거나 변경할 수 있습니다.',
+'protect-viewtext' => '문서 보호 권한이 없습니다. 다음은 현재 \'\'\'$1\'\'\' 문서의 보호 설정입니다:',
+'protect-default' => '(기본값)',
+'protect-level-autoconfirmed'=> '등록된 사용자만 가능',
+'protect-level-sysop' => '관리자만 가능',
+'restriction-edit' => '편집',
+'restriction-move' => '이동',
+'undelete' => '삭제된 문서 보기',
+'undeletepage' => '삭제된 문서를 보거나 되살립니다.',
+'viewdeletedpage' => '삭제된 문서 보기',
+'undeletepagetext' => '다음의 문서는 삭제되었지만 보관되어있고, 되살릴 수 있습니다. 보관된 문서들은 주기적으로 삭제될 것입니다.',
+'undeletearticle' => '삭제된 문서 되살리기',
+'undeleterevisions' => '$1개의 버전 보관중',
+'undeletehistory' => '문서를 되살리면 모든 역사가 같이 복구됩니다. 문서가 삭제된 후에 같은 이름의 문서가 만들어졌다면, 복구되는 버전들은 역사의 과거 부분에 나타날 것입니다.',
+'undeletehistorynoadmin'=> '이 문서는 삭제되어 있습니다. 삭제된 이유와 삭제되기 전에 이 문서를 편집한 사용자들이 아래에 나와 있습니다. 삭제된 문서를 보려면 관리자 권한이 필요합니다.',
+'undeleterevision' => '$1 판을 삭제했습니다.',
+'undeletebtn' => '복구',
+'undeletereset' => '초기화',
+'undeletedarticle' => '"[[$1]]" 복구됨',
+'undeletedrevisions' => '$1개의 버전이 복구되었습니다.',
+'undeletedrevisions-files'=> '$1개의 버전과 $2개의 파일이 복구되었습니다.',
+'undeletedfiles' => '$1개의 파일이 복구되었습니다.',
+'cannotundelete' => '복구에 실패했습니다. 다른 누군가가 이미 복구했을 수도 있습니다.',
+'undeletedpage' => '<big>\'\'\'$1이 복구되었습니다.\'\'\'</big>
+
+[[Special:Log/delete|삭제 기록]]에서 최근의 삭제/복구 기록을 볼 수 있습니다.',
+'namespace' => '네임스페이스:',
+'invert' => '선택 반전',
+'contributions' => '사용자 기여',
+'mycontris' => '내 기여 목록',
+'contribsub' => '$1의',
+'nocontribs' => '이 사용자는 어디에도 기여하지 않았습니다.',
+'ucnote' => '이 사용자가 \'\'\'$2\'\'\'일 동안에 바꾼 \'\'\'$1\'\'\'개의 목록입니다.',
+'uclinks' => '최근 $1개 보기; 최근 $2일 보기',
+'uctop' => ' (최신)',
+'sp-newimages-showfrom' => '$1부터 올라온 그림 목록 보기',
+'whatlinkshere' => '여기를 가리키는 문서',
+'notargettitle' => '해당하는 문서 없음',
+'notargettext' => '기능을 수행할 목표 문서나 목표 사용자를 지정하지 않았습니다.',
+'linklistsub' => '(고리 목록)',
+'linkshere' => '다음의 문서들이 여기를 가리키고 있습니다:',
+'nolinkshere' => '이곳을 가리키는 문서가 없습니다.',
+'isredirect' => '넘겨주기 문서',
+'blockip' => '사용자 차단',
+'blockiptext' => '차단할 IP 주소나 사용자 이름을 아래에 적어 주세요. 차단은 반드시 반달행위를 막기 위해서, 혹은 {{SITENAME}} 정책에 의해서만 이루어져야 합니다. 차단 이유도 같이 적어 주시기 바랍니다.',
+'ipaddress' => 'IP 주소',
+'ipadressorusername' => 'IP 주소 또는 사용자 이름',
+'ipbexpiry' => '기간',
+'ipbreason' => '이유',
+'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',
+'ipbotheroption' => '수동으로 지정',
+'badipaddress' => '잘못된 IP 주소',
+'blockipsuccesssub' => '차단 완료',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] 사용자가 차단되었습니다. 차단된 사용자 목록은 [[Special:Ipblocklist|여기]]에서 볼 수 있습니다.',
+'unblockip' => '사용자 차단 해제',
+'unblockiptext' => '아래의 양식에 차단 해제하려는 IP 주소나 사용자 이름을 입력하세요.',
+'ipusubmit' => '차단 해제',
+'unblocked' => '[[User:$1|$1]] 사용자가 차단 해제되었습니다.',
+'ipblocklist' => '차단된 IP 주소와 사용자 목록',
+'blocklistline' => '$1, $2 사용자는 $3을 차단함 ($4)',
+'infiniteblock' => '무기한',
+'expiringblock' => '$1에 해제',
+'ipblocklistempty' => '차단 목록이 비어 있습니다.',
+'blocklink' => '차단',
+'unblocklink' => '차단 해제',
+'contribslink' => '기여',
+'autoblocker' => '당신의 IP 주소는 최근 [[User:$1|$1]]가 사용하였기 때문에 자동으로 차단되었습니다. $1의 차단 이유는 다음과 같습니다: \'\'\'$2\'\'\'',
+'blocklogpage' => '차단 기록',
+'blocklogentry' => '[[$1]]이 차단되었습니다. 차단 기간은 $2입니다.',
+'blocklogtext' => '이 목록은 사용자 차단/차단 해제 기록입니다. 자동으로 차단된 IP 주소는 여기에 나오지 않습니다. [[Special:Ipblocklist|여기]]에서 현재 차단된 사용자 목록을 볼 수 있습니다.',
+'unblocklogentry' => '$1을 차단 해제했습니다.',
+'range_block_disabled' => 'IP 범위 차단 기능이 비활성화되어 있습니다.',
+'ipb_expiry_invalid' => '차단 기간이 잘못되었습니다.',
+'ip_range_invalid' => 'IP 범위가 잘못되었습니다.',
+'proxyblocker' => '프록시 차단',
+'proxyblockreason' => '당신의 IP 주소는 공개 프록시로 밝혀져 자동으로 차단됩니다. 만약 인터넷 사용에 문제가 있다면 인터넷 서비스 공급자에게 문의해주세요.',
+'proxyblocksuccess' => '완료.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => '당신의 IP 주소는 [http://www.sorbs.net SORBS] DNSBL의 공개 프록시 목록에 들어있습니다.',
+'sorbs_create_account_reason'=> '당신의 IP 주소는 [http://www.sorbs.net SORBS] DNSBL의 공개 프록시 목록에 들어있습니다. 계정을 만들 수 없습니다.',
+'lockdb' => '데이터베이스 잠그기',
+'unlockdb' => '데이터베이스 잠금 해제',
+'lockdbtext' => '데이터베이스를 잠그면 모든 사용자의 편집 권한, 환경 설정 변경 권한, 주시문서 편집 권한 등의 모든 기능이 정지됩니다. 정말로 잠가야 하는지를 다시 한번 확인해주세요.',
+'unlockdbtext' => '데이터베이스를 잠금 해제하면 모든 사용자의 편집 권한, 환경 설정 변경 권한, 주시문서 편집 권한 등의 모든 기능이 복구됩니다. 정말로 잠금을 해제하려는지를 다시 한번 확인해주세요.',
+'lockconfirm' => '네, 데이터베이스를 잠급니다.',
+'unlockconfirm' => '네, 데이터베이스를 잠금 해제합니다.',
+'lockbtn' => '데이터베이스 잠그기',
+'unlockbtn' => '데이터베이스 잠금 해제',
+'locknoconfirm' => '확인 체크박스를 선택하지 않았습니다.',
+'lockdbsuccesssub' => '데이터베이스 잠김',
+'unlockdbsuccesssub' => '데이터베이스 잠금 해제됨',
+'lockdbsuccesstext' => '데이터베이스가 잠겼습니다.<br />관리가 끝나면 잠금을 해제하는 것을 잊지 말아 주세요.',
+'unlockdbsuccesstext' => '데이터베이스 잠금 상태가 해제되었습니다.',
+'makesysoptitle' => '사용자에게 관리자 권한 주기',
+'makesysoptext' => '이 양식은 뷰로크랫 권한이 있는 사용자가 다른 사용자에게 관리자 권한을 줄 때 사용됩니다. 사용자 이름을 입력하고 확인을 눌러 관리자 권한을 줄 수 있습니다.',
+'makesysopname' => '사용자 이름:',
+'makesysopsubmit' => '이 사용자에게 관리자 권한을 줍니다',
+'makesysopok' => '\'\'\'사용자 "$1"에게 관리자 권한을 주었습니다.\'\'\'',
+'makesysopfail' => '\'\'\'사용자 "$1"에게 관리자 권한을 줄 수 없습니다. (철자를 맞게 입력했는지 확인해주세요)\'\'\'',
+'setbureaucratflag' => '뷰로크랫 권한 주기',
+'rightslog' => '사용자 권한 기록',
+'rightslogtext' => '사용자 권한 조정 기록입니다.',
+'rightslogentry' => '$1의 권한을 $2에서 $3으로 변경',
+'rights' => '권한:',
+'set_user_rights' => '사용자 권한 설정',
+'user_rights_set' => '\'\'\'"$1"의 권한이 변경되었습니다.\'\'\'',
+'makesysop' => '사용자에게 관리자 권한을 주기',
+'already_sysop' => '이 사용자는 이미 관리자입니다.',
+'already_bureaucrat' => '이 사용자는 이미 뷰로크랫입니다.',
+'rightsnone' => '(없음)',
+'movepage' => '문서 이동하기',
+'movepagetext' => '아래 틀을 채워 문서의 이름을 바꿀 수 있습니다. 문서의 역사도 모두 새 문서로 옮겨집니다. 기존의 문서는 새 이름의 문서로 넘겨주는 문서가 됩니다. 기존 문서로의 고리는 바뀌지 않습니다. 이중 넘겨주기와 끊긴 넘겨주기에 주의해주세요.
+
+만약 문서의 새 이름으로 된 문서가 존재할 때, 이 문서가 비었거나 넘겨주기 문서이고 문서 역사가 없을 때에만 이동합니다. 그렇지 않을 경우에는 이동하지 \'\'\'않습니다\'\'\'. 이것은 실수로 이동한 문서를 되돌릴 수는 있지만, 이미 존재하는 문서 위에 덮어씌울 수는 없다는 것을 의미합니다.
+
+\'\'\'주의!\'\'\' 자주 사용하는 문서를 이동하면 위험한 결과를 가져올 수 있습니다. 이동하기 전에, 이동한 다음 문제가 없다는 것을 확인해주세요.',
+'movepagetalktext' => '딸린 토론 문서도 자동으로 이동합니다. 다음의 경우는 \'\'\'이동하지 않습니다\'\'\':
+* 이동할 이름으로 된 문서가 이미 있는 경우
+* 아래의 선택을 해제하는 경우
+이 경우에는 문서를 직접 이동하거나 두 문서를 합쳐야 합니다.',
+'movearticle' => '문서 이동하기',
+'movenologin' => '로그인하고 있지 않습니다.',
+'movenologintext' => '[[Special:Userlogin|로그인]]해야만 문서를 이동할 수 있습니다.',
+'newtitle' => '새 문서 이름',
+'movepagebtn' => '이동',
+'pagemovedsub' => '문서 옮겨짐',
+'pagemovedtext' => '\'[[$1]]\'를 \'[[$2]]\'로 이동했습니다.',
+'articleexists' => '문서가 이미 존재하거나, 문서 이름이 올바르지 않습니다. 다른 제목으로 시도해주세요.',
+'talkexists' => '\'\'\'문서는 이동되었습니다. 하지만 딸린 토론 문서의 새 이름으로 된 문서가 이미 존재해서, 토론 문서는 이동하지 않았습니다. 직접 문서를 합쳐 주세요.\'\'\'',
+'movedto' => '새 이름',
+'movetalk' => '딸린 토론도 함께 이동합니다.',
+'talkpagemoved' => '딸린 토론도 이동했습니다.',
+'talkpagenotmoved' => '딸린 토론은 이동하지 \'\'\'않았습니다\'\'\'.',
+'1movedto2' => '[[$1]]을(를) [[$2]](으)로 옮김',
+'1movedto2_redir' => '[[$1]]을(를) [[$2]](으)로 옮기면서 넘겨주기를 덮어 씀',
+'movelogpage' => '이동 기록',
+'movelogpagetext' => '아래는 옮겨진 문서의 목록입니다.',
+'movereason' => '이유',
+'revertmove' => '되돌리기',
+'delete_and_move' => '삭제하고 이동',
+'delete_and_move_text' => '== 삭제 필요 ==
+
+이동하려는 제목으로 된 문서 [[$1]]이(가) 이미 존재합니다. 삭제하고 이동할까요?',
+'delete_and_move_confirm'=> '네. 문서를 삭제합니다',
+'delete_and_move_reason'=> '문서를 이동하기 위해 삭제함',
+'selfmove' => '이동하려는 제목이 원래 제목과 같습니다. 이동할 수 없습니다.',
+'immobile_namespace' => '특수한 네임스페이스로는 이동할 수 없습니다.',
+'export' => '문서 내보내기',
+'exporttext' => '문서와 편집 역사들을 XML 형식으로 만들 수 있습니다. 이렇게 만들어지는 파일은 다른 미디어위키에서 Special:Import page를 통해 가져올 수 있습니다.
+
+문서를 내보내기 위해서는, 아래의 상자에 문서의 제목들을 한 줄에 한 제목씩 쓰면 됩니다. 그리고 현재의 버전만을 내보낼지, 또는 전체 역사, 최근의 내역 등을 내보낼지 선택해 주시기 바랍니다.
+
+특정 문서를 내보내려면, 예를 들어 {{Mediawiki:Mainpage}} 문서를 내보내려면 [[Special:Export/{{Mediawiki:Mainpage}}]] 문서를 사용할 수도 있습니다.',
+'exportcuronly' => '현재 버전만 포함하고, 전체 역사는 포함하지 않음',
+'exportnohistory' => '----
+\'\'\'주의:\'\'\' 전체 문서 역사를 내보내는 기능은 성능 문제로 인해 비활성되어 있습니다.',
+'export-submit' => '내보내기',
+'allmessages' => '시스템 메시지 목록',
+'allmessagesname' => '이름',
+'allmessagesdefault' => '기본 내용',
+'allmessagescurrent' => '현재 내용',
+'allmessagestext' => 'MediaWiki 네임스페이스에 있는 모든 시스템 메시지의 목록입니다.',
+'allmessagesnotsupportedUI'=> 'Special:Allmessages에서는 현재 인터페이스 언어 \'\'\'$1\'\'\'를 지원하지 않습니다.',
+'allmessagesnotsupportedDB'=> '\'\'\'$wgUseDatabaseMessages\'\'\'가 해제되어 있어서 \'\'\'Special:Allmessages\'\'\'를 사용할 수 없습니다.',
+'allmessagesfilter' => '다음 메시지만 보이기:',
+'allmessagesmodified' => '변경된 것만 보여주기',
+'thumbnail-more' => '실제 크기로',
+'missingimage' => '\'\'\'사라진 그림\'\'\'<br />\'\'$1\'\'',
+'filemissing' => '파일 사라짐',
+'thumbnail_error' => '섬네일을 만드는 중 오류 발생: $1',
+'import' => '문서 가져오기',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => '{{SITENAME}} 찾기 [alt-f]',
+'tooltip-minoredit' => '사소한 편집으로 표시하기 [alt-i]',
+'tooltip-save' => '편집 내용을 저장하기 [alt-s]',
+'tooltip-preview' => '편집 미리보기. 저장하기 전에 꼭 미리보기를 해주세요. [alt-p]',
+'tooltip-diff' => '원래의 문서와 현재 편집하는 문서를 비교하기 [alt-v]',
+'tooltip-compareselectedversions'=> '이 문서에서 선택한 두 버전간의 차이를 비교 [alt-v]',
+'tooltip-watch' => '이 문서를 주시문서 목록에 추가 [alt-w]',
+'common.css' => '/** 이 CSS 설정은 모든 스킨에 적용됩니다 */',
+'monobook.css' => '/* 이 CSS 설정은 모든 모노북 스킨에 적용됩니다 */',
+'nodublincore' => '더블린 코어 RDF 메타데이터 기능은 비활성되어 있습니다.',
+'nocreativecommons' => '크리에이티브 커먼즈 RDF 메타데이터 기능은 비활성되어 있습니다.',
+'anonymous' => '{{SITENAME}}의 익명 사용자',
+'siteuser' => '{{SITENAME}} 사용자 $1',
+'lastmodifiedatby' => '이 문서는 $3에 의해 $2, $1에 마지막으로 바뀌었습니다.',
+'and' => '그리고',
+'siteusers' => '{{SITENAME}} 사용자 $1',
+'creditspage' => '문서 기여자들',
+'subcategorycount' => '이 분류에 $1개의 하위 분류가 있습니다.',
+'categoryarticlecount' => '이 분류에 $1개의 문서가 있습니다.',
+'listingcontinuesabbrev'=> ' (계속)',
+'spam_reverting' => '$1을 포함하지 않는 최신 버전으로 되돌림',
+'spam_blanking' => '모든 버전에 $1을 포함하고 있어 문서를 비움',
+'infosubtitle' => '문서 정보',
+'numedits' => '편집 횟수(문서): $1',
+'numtalkedits' => '편집 횟수(토론 문서): $1',
+'numwatchers' => '주시하는 사용자 수: $1',
+'numauthors' => '기여한 사용자 수(문서): $1',
+'numtalkauthors' => '기여한 사용자 수(토론 문서): $1',
+'mw_math_png' => '항상 PNG로 표시',
+'mw_math_simple' => '아주 간단한 것은 HTML로, 나머지는 PNG로',
+'mw_math_html' => '가능한 한 HTML로, 나머지는 PNG로',
+'mw_math_source' => 'TeX로 남겨둠 (텍스트 브라우저용)',
+'mw_math_modern' => '최신 웹 브라우저인 경우 추천',
+'mw_math_mathml' => '가능하면 MathML로 (experimental)',
+'markaspatrolleddiff' => '검토된 것으로 표시',
+'markaspatrolledtext' => '이 문서를 검토된 것으로 표시',
+'markedaspatrolled' => '검토된 것으로 표시',
+'markedaspatrolledtext' => '선택한 버전이 검토된 것으로 표시되었습니다.',
+'rcpatroldisabled' => '최근 바뀜 검토 기능 비활성화됨',
+'rcpatroldisabledtext' => '최근 바뀜 검토 기능은 현재 비활성화되어 있습니다.',
+'markedaspatrollederror'=> '검토된 것으로 표시할 수 없습니다.',
+'markedaspatrollederrortext'=> '검토된 것으로 표시할 버전을 지정해야 합니다.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'내 사용자 문서\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'당신이 사용하는 IP를 위한 사용자 문서\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'내 토론 문서\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'당신이 사용하는 IP를 위한 사용자 토론 문서\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'사용자 환경 설정\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'주시문서 목록\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'내가 편집한 글\');
+ ta[\'pt-login\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'꼭 필요한 것은 아니지만, 로그인을 하면 편리한 점이 많습니다.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'로그아웃\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'문서의 내용에 대한 토론 문서\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'문서를 편집할 수 있습니다. 저장하기 전에 미리보기를 해 주세요.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'내용 추가하기\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'문서가 잠겨 있습니다. 문서의 소스만 볼 수 있습니다.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'문서의 과거 버전들\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'문서 보호하기\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'문서 삭제하기\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'삭제된 문서 복구하기\');
+ ta[\'ca-move\'] = new Array(\'m\',\'문서 이동하기\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'이 문서를 주시문서 목록에 추가합니다.\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'이 문서를 주시문서 목록에서 제거합니다.\');
+ ta[\'search\'] = new Array(\'f\',\'찾기\');
+ ta[\'p-logo\'] = new Array(\'\',\'대문\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'대문으로\');
+ ta[\'n-portal\'] = new Array(\'\',\'이 프로젝트에 대해\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'최근의 소식을 봅니다.\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'이 위키에서 최근 바뀐 점의 목록입니다.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'임의 문서로 갑니다.\');
+ ta[\'n-help\'] = new Array(\'\',\'도움말\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'지원을 기다립니다.\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'여기로 연결된 모든 문서의 목록\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'여기로 연결된 모든 문서의 변경 내역\');
+ ta[\'feed-rss\'] = new Array(\'\',\'이 문서의 RSS 피드입니다.\');
+ ta[\'feed-atom\'] = new Array(\'\',\'이 문서의 Atom 피드입니다.\');
+ ta[\'t-contributions\'] = new Array(\'\',\'이 사용자의 기여 목록을 봅니다.\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'이 사용자에게 이메일을 보냅니다.\');
+ ta[\'t-upload\'] = new Array(\'u\',\'파일을 올립니다.\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'모든 특수 문서의 목록입니다.\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'문서 내용을 봅니다.\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'사용자 문서 내용을 봅니다.\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'미디어 문서 내용을 봅니다.\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'이것은 특수 문서로, 편집할 수 없습니다.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'프로젝트 문서 내용을 봅니다.\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'그림 문서 내용을 봅니다.\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'시스템 메시지 내용을 봅니다.\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'틀 문서 내용을 봅니다.\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'도움말 문서 내용을 봅니다.\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'분류 문서 내용을 봅니다.\');',
+'deletedrevision' => '예전 버전 $1이 삭제되었습니다.',
+'previousdiff' => '← 이전 비교',
+'nextdiff' => '다음 비교 →',
+'imagemaxsize' => '그림 설명 문서에 그림 크기를 다음으로 제한:',
+'thumbsize' => '섬네일 크기:',
+'showbigimage' => '고해상도 버전 보기 ($1x$2, $3 KB)',
+'newimages' => '새 그림 파일 목록',
+'showhidebots' => '(봇을 $1)',
+'noimages' => '그림이 없습니다.',
+'specialloguserlabel' => '이름:',
+'speciallogtitlelabel' => '제목:',
+'passwordtooshort' => '암호가 너무 짧습니다. 암호 길이는 적어도 $1글자 이상이어야 합니다.',
+'mediawarning' => '\'\'\'경고\'\'\': 이 파일에는 시스템을 위험하게 만드는 악성 코드가 들어있을 수 있습니다.<br />',
+'fileinfo' => '$1KB, MIME 종류: <code>$2</code>',
+'metadata' => '메타데이터',
+'metadata-help' => '이 파일은 카메라/스캐너 정보와 같은 부가적인 정보를 담고 있습니다. 파일을 변경한다면 몇몇 세부 사항은 변경된 그림에 적용되지 않을 수 있습니다.',
+'metadata-expand' => '자세한 정보 보이기',
+'metadata-collapse' => '자세한 정보 숨기기',
+'edit-externally' => '이 파일을 외부 프로그램을 사용해서 편집하기',
+'edit-externally-help' => '[http://meta.wikimedia.org/wiki/Help:External_editors 설치 방법] 문서에서 더 자세한 정보를 얻을 수 있습니다.',
+'recentchangesall' => '모두',
+'imagelistall' => '모두',
+'watchlistall1' => '모두',
+'watchlistall2' => '모두',
+'namespacesall' => '모두',
+'confirmemail' => '이메일 주소 확인',
+'confirmemail_text' => '이 위키에서는 이메일과 관련된 기능을 사용하기 전에, 이메일 인증을 받아야 합니다. 아래의 버튼을 눌러 인증 메일을 보내세요. 메일에는 인증 코드를 포함한 링크가 들어 있을 것입니다. 링크를 브라우저에서 열면 인증이 됩니다.',
+'confirmemail_send' => '인증 코드를 메일로 보내기',
+'confirmemail_sent' => '인증 이메일을 보냈습니다.',
+'confirmemail_sendfailed'=> '인증 이메일을 보낼 수 없습니다. 잘못된 주소인지 확인해 주십시오.',
+'confirmemail_invalid' => '인증 코드가 올바르지 않습니다. 코드가 소멸되었을 수도 있습니다.',
+'confirmemail_needlogin'=> '이메일 주소를 인증하려면 $1이 필요합니다.',
+'confirmemail_success' => '당신의 이메일 주소가 인증되었습니다. 이제 로그인해서 위키를 사용하세요.',
+'confirmemail_loggedin' => '당신의 이메일 주소는 이제 인증되었습니다.',
+'confirmemail_error' => '당신의 인증을 저장하는 도중 오류가 발생했습니다.',
+'confirmemail_subject' => '{{SITENAME}} 이메일 주소 인증',
+'confirmemail_body' => '누군가가 $1 아이피 주소로 이미 "$2" 계정의 이메일 인증을 받았습니다.
+
+만약 이 계정이 당신의 계정이고 이메일 기능을 사용하려면, 다음을 열어 주시기 바랍니다:
+
+$3
+
+만약 당신의 계정이 \'\'\'아니라면\'\'\', 문서를 열지 않아도 됩니다. 승인 코드는 $4에 만료됩니다.',
+'searchfulltext' => '전체 글 검색',
+'createarticle' => '문서 만들기',
+'scarytranscludedisabled'=> '[인터위키가 비활성되어 있습니다]',
+'scarytranscludefailed' => '[$1 틀을 불러오는 데에 실패했습니다]',
+'scarytranscludetoolong'=> '[URL이 너무 깁니다]',
+'trackbackbox' => '<div id="mw_trackbacks">이 문서에 달린 트랙백:<br />$1</div>',
+'trackbackremove' => ' ([$1 삭제])',
+'trackbacklink' => '트랙백',
+'trackbackdeleteok' => '트랙백이 삭제되었습니다.',
+'deletedwhileediting' => '주의: 당신이 이 문서를 편집하던 중에 이 문서가 삭제되었습니다.',
+'confirmrecreate' => '[[User:$1|$1]]([[User talk:$1|토론]]) 사용자가 당신의 편집 도중 문서를 지웠습니다. 삭제 이유는 다음과 같습니다:
+: $2
+문서를 다시 되살릴 필요가 있는지를 확인해주세요.',
+'tooltip-recreate' => '문서를 편집하는 중 삭제되어도 새로 만들기',
+'unit-pixel' => 'px',
+'redirectingto' => '[[$1]]로 넘어가는 중...',
+'confirm_purge' => '문서의 캐시를 지울까요?
+
+$1',
+'confirm_purge_button' => '확인',
+'youhavenewmessagesmulti'=> '$1 란에 누군가 글을 남겼습니다.',
+'searchcontaining' => '"$1"이 포함된 글을 검색합니다.',
+'searchnamed' => '"$1" 이름을 가진 문서를 검색합니다.',
+'articletitles' => '\'\'$1\'\'로 시작하는 문서들',
+'hideresults' => '결과 숨기기',
+'loginlanguagelabel' => '언어: $1',
+);
+?>
diff --git a/languages/messages/MessagesKs.php b/languages/messages/MessagesKs.php
new file mode 100644
index 000000000000..07e90cb706a4
--- /dev/null
+++ b/languages/messages/MessagesKs.php
@@ -0,0 +1,11 @@
+<?php
+/** Kashmiri language file ( कश्मीरी - (ﻚﺸﻤﻳﺮﻳ) )
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#FIXME: inherit almost everything for now
+$rtl = true;
+
+?>
diff --git a/languages/messages/MessagesKsh.php b/languages/messages/MessagesKsh.php
new file mode 100644
index 000000000000..885396a8f958
--- /dev/null
+++ b/languages/messages/MessagesKsh.php
@@ -0,0 +1,2347 @@
+<?php
+/** Ripuarian (Ripoarėsh)
+ * The majority of users are bilingual in a Ripuarian language plus German, use German as fallback.
+ * (could also choose english, dutch, or limburgish)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Purodha Blissenbach
+ */
+
+$fallback = 'de';
+
+$namespaceNames = array(
+ NS_MEDIA => 'Meedije',
+ NS_SPECIAL => 'Shpezjal',
+ NS_MAIN => '',
+ NS_TALK => 'Klaaf',
+ NS_USER => 'Medmaacher',
+ NS_USER_TALK => 'Medmaacher_Klaaf',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_Klaaf',
+ NS_IMAGE => 'Beld',
+ NS_IMAGE_TALK => 'Belder_Klaaf',
+ NS_MEDIAWIKI => 'MedijaWikki',
+ NS_MEDIAWIKI_TALK => 'MedijaWikki_Klaaf',
+ NS_TEMPLATE => 'Schablon',
+ NS_TEMPLATE_TALK => 'Schablone_Klaaf',
+ NS_HELP => 'Hülp',
+ NS_HELP_TALK => 'Hülp_Klaaf',
+ NS_CATEGORY => 'Saachjropp',
+ NS_CATEGORY_TALK => 'Saachjroppe_Klaaf',
+);
+
+/**
+ * Array of namespace aliases, mapping from name to NS_xxx index
+ */
+$namespaceAliases = array(
+ 'Belld' => NS_IMAGE,
+ 'Bellder_Klaaf' => NS_IMAGE_TALK,
+ 'Sachjrop' => NS_CATEGORY,
+ 'Sachjrop_Klaaf' => NS_CATEGORY_TALK,
+ 'Kattejori' => NS_CATEGORY,
+ 'Kattejori_Klaaf' => NS_CATEGORY_TALK,
+ 'Kategorie' => NS_CATEGORY,
+ 'Kategorie_Klaaf' => NS_CATEGORY_TALK,
+ 'Katejori' => NS_CATEGORY,
+ 'Katejorije_Klaaf' => NS_CATEGORY_TALK,
+);
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+
+/**
+ * Labels of the quickbar settings in Special:Preferences
+ */
+$quickbarSettings = array(
+ "Fotlohse, dat well ish nitt sinn",
+ "Am lėnke Rand faßß aanjepapp",
+ "Am räächte Rand fßß aanjepapp",
+ "Am lėnke Rand am Shwääve"
+);
+
+
+/**
+ * Skin names. If any key is not specified, the English one will be used.
+ */
+$skinNames = array(
+ 'standard' => 'Shtandad',
+ 'nostalgia' => 'Noßtalljesh',
+ 'cologneblue' => 'Kölsch Blau',
+ 'smarty' => 'Päddingtonn',
+ 'montparnasse' => 'Mont_Panaßß',
+ 'davinci' => 'Da_Vintshi',
+ 'mono' => 'Monno',
+ 'monobook' => 'MonnoBooch',
+ 'myskin' => 'Ming_Skin',
+ 'chick' => 'Küüke'
+);
+
+$messages = array(
+'tog-underline' => 'Donn de Lėngkß ungershtriishe:',
+'tog-highlightbroken' => 'Zëijsh de Lėngkß op Sigge, di_jet_non_nit_jitt, esu met: „<a href=""
+
+class="new">Lämma</a>“ aan.<br />Wännß_De dat nit wellß, weed et esu: „Lämma<a href="" class="internal">?</a>“
+
+jezëijsh.',
+'tog-justify' => 'Donn de Affschnedde em Bloksaz aanzëije',
+'tog-hideminor' => 'Donn de klëijn minni_Ännderonge (\'\'\'M\'\'\') en_de Lėßß_met „Nöüßte_Ännderonge“
+
+shtanndad_määßish \'\'\'nit\'\'\' aanzëije',
+'tog-extendwatchlist' => 'Forjrüüßo de Oppaßß_Lėßß för jeede Aat fun mööshlėshe Ännderonge ze_zëije',
+'tog-usenewrc' => 'Donn_de Oppjemozzde Lėßß_met „Nöüßte_Ännderonge“ aanzëije (bruch Java_Skripp)',
+'tog-numberheadings' => 'Donn de Övverschreffte automatish nummerėere',
+'tog-showtoolbar' => 'Zëijsh de Wërrkzöüsh_Lëßß zom Änndere aan (bruch Java_Skripp)',
+'tog-editondblclick' => 'Sigge med Dubbel-Klikke Änndere (bruch Java_Skripp)',
+'tog-editsection' => 'Maach [Änndere]-Lėngkß aan de Affschnedde raan',
+'tog-editsectiononrightclick'=> 'Affschnedde med Räähß-Klikke op de Övverschrevv_Änndere (bruch Java_Skripp)',
+'tog-showtoc' => 'Zëijsj_en Ėnnhallds_Övverseesh bëij Sigge met_mieh_vi drëij Övverschreffte dren',
+'tog-rememberpassword' => 'Op_Dauer Aanmällde',
+'tog-editwidth' => 'Maach dat Felld zom Täxx_Ėnnjävve_su_brëijdt, vi_t jëijdt',
+'tog-watchcreations' => 'Donn di Sigge fö ming Oppaßß_Lėßß fürschlaare, di_ish nöü aanläje',
+'tog-watchdefault' => 'Donn di Sigge fö ming Oppaßß_Lėßß fürschlaare, di_isch aanpakke un änndere donn',
+'tog-minordefault' => 'Donn all ming Ännderonge shtandad_mäßėj_allß klëijn Minni_Ännderonge fürschlaare',
+'tog-previewontop' => 'Zëijsh de Füür_Aansėsh övver dämm Felld för_dä Täxx ėnn_ze_jävve aan.',
+'tog-previewonfirst' => 'Zëijsh de Füür_Aansėsh tirräg füür_em eetzte Mool bëijm Beärrbëijde aan',
+'tog-nocache' => 'Donn et Sigge_Zweshe_Shpëijshere — et Caching — affschallde',
+'tog-enotifwatchlistpages'=> 'Schegg_en e-mail, wänn_en Sigg_uß minge Oppaßß_Lėßß jeänndot wood',
+'tog-enotifusertalkpages'=> 'Scheck mer e-mail, wänn ming Klaaf_Sigk jeänndot weed',
+'tog-enotifminoredits' => 'Scheck mer och en e-mail för klëijn Minni_Ännderonge',
+'tog-enotifrevealaddr' => 'Zëijsh ming e-mail Addräßß aan, en de Benohreshtėjonge pä e-mail',
+'tog-shownumberswatching'=> 'Zëijsh de Aanzal Medmaacher di op di Sigk op_am_paßße sinn',
+'tog-fancysig' => 'Ungerschreff oohne outomatėshe Lėngk',
+'tog-externaleditor' => 'Nemm shtandad_mäßėsh en ëxtärrn „editor“-Projramm',
+'tog-externaldiff' => 'Nemm shtandad_mäßėsh en ëxtärrn „diff“-Projramm',
+'tog-showjumplinks' => 'Lėngkß ußjävve, di dem „bajjeerefrëije Zoojang“ hellfe důnn',
+'tog-uselivepreview' => 'Zëijsh_de „Lebänndijje Füür_Aansėsh Zëije“ (bruch Java_Skripp) (em Ußprobier_Shtadijum)',
+'tog-autopatrol' => 'Wänn esh jät ännder, dann jėlld di Sigk alß kontrollėet.',
+'tog-forceeditsummary' => 'Frooch nooh, wänn_en_dämm Felldt „Koot Zosammejefaßß, Kwälle“ bëijem Affshpëijshere nix
+
+dren shtëijdt',
+'tog-watchlisthideown' => 'Donn stanndad_määßisch ming ëijen
+Änderonge <strong>nit</strong> en minger Oppaßß_Lėßß aanzëije',
+'tog-watchlisthidebots' => 'Donn stanndad_määßisch dä Botß ier Änderonge
+
+<strong>nit</strong> en minger Oppaßß_Lėßß zëije',
+'underline-always' => 'jo, ėmmer',
+'underline-never' => 'nä',
+'underline-default' => 'nemm dem Brauser sing Ėnshtällung',
+'skinpreview' => '(Aanluere)',
+
+# dates
+'sunday' => 'Sunndaach',
+'monday' => 'Mohndaach',
+'tuesday' => 'Dinnßdaach',
+'wednesday' => 'Medtvoch',
+'thursday' => 'Dunnorßdaach',
+'friday' => 'Friidaach',
+'saturday' => 'Sammbsdaach',
+'sun' => 'Su.',
+'mon' => 'Mo.',
+'tue' => 'Di.',
+'wed' => 'Me.',
+'thu' => 'Du.',
+'fri' => 'Fr.',
+'sat' => 'Sa.',
+'january' => 'Jannowaa',
+'february' => 'Fäbrowaa',
+'march' => 'Määz',
+'april' => 'Apprell',
+'may_long' => 'Mëij',
+'june' => 'Juuni',
+'july' => 'Juuli',
+'august' => 'Ojjoßß',
+'september' => 'Säptämmbo',
+'october' => 'Oktoobo',
+'november' => 'Novämmbo',
+'december' => 'Dezämmbo',
+'january-gen' => 'Jannowaa',
+'february-gen' => 'Fäbrowaa',
+'march-gen' => 'Määz',
+'april-gen' => 'Apprell',
+'may-gen' => 'Mëij',
+'june-gen' => 'Juuni',
+'july-gen' => 'Juuli',
+'august-gen' => 'Ojjoßß',
+'september-gen' => 'Säptämmbo',
+'october-gen' => 'Oktoobo',
+'november-gen' => 'Novämmbo',
+'december-gen' => 'Dezämmbo',
+'jan' => 'Jan',
+'feb' => 'Feb',
+'mar' => 'Mäz',
+'apr' => 'Apr',
+'may' => 'Mej',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Auj',
+'sep' => 'Sep',
+'oct' => 'Okt',
+'nov' => 'Nov',
+'dec' => 'Dez',
+'categories' => 'Saachjroppe',
+'pagecategories' => '{{PLURAL:$1|Saachjropp|Saachjroppe }}',
+'category_header' => 'Attikkelle in_de Saachjropp „$1“',
+'subcategories' => 'Ungerjroppe',
+'mainpage' => 'Houpsigk',
+'mainpagetext' => '<big><strong>MediaWiki eß jäz enshtallėerdt.</strong></big>',
+'mainpagedocfooter' => 'Luer en dä [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide User\'s Guide] wänn
+
+De weßße wellß wi de Wikki_ßoffwäer jebruch un bedeendt weede moß.
+
+== För der Aanfang ==
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]',
+'portal' => 'Övver {{SITENAME}}',
+'portal-url' => '{{ns:project}}:Medmaacher Pooz',
+'about' => 'Övver {{SITENAME}}',
+'aboutsite' => 'Övver de {{SITENAME}}',
+'aboutpage' => '{{ns:project}}:Övver_de_{{SITENAME}}',
+'article' => 'Atikkel',
+'help' => 'Hülp',
+'helppage' => '{{ns:project}}:Hülp',
+'bugreports' => 'Fähler mällde',
+'bugreportspage' => '{{ns:project}}:Konntak',
+'sitesupport' => 'Shpännde',
+'sitesupport-url' => '{{ns:project}}:Shpännde',
+'faq' => 'FAQ',
+'faqpage' => '{{ns:project}}:FAQ',
+'edithelp' => 'Hülp fö_t Beärrbëijde',
+'newwindow' => '(Määd_e nöü Finßter op, wänn Dinge Brauser datt kann)',
+'edithelppage' => '{{ns:project}}:Hülp',
+'cancel' => 'Shtopp! Affbrëshe!',
+'qbfind' => 'Fingk',
+'qbbrowse' => 'Aanluere',
+'qbedit' => 'Änndere',
+'qbpageoptions' => 'Sigge_Ëijnshtällunge',
+'qbpageinfo' => 'Zosammehang',
+'qbmyoptions' => 'Ming Sigge',
+'qbspecialpages' => 'Shpezzjahl_Sigge',
+'moredotdotdot' => 'Mieh…',
+'mypage' => 'Ming Sigk',
+'mytalk' => 'ming Klaafsigk',
+'anontalk' => 'Klaaf fö_di IP_Addräßß',
+'navigation' => 'Jangk_noh',
+'metadata_help' => 'Däm Belld_sing Metta_Daate ([[{{ns:project}}:Metta_Daate fun Bellder|hee sin_se
+
+äkliert]])',
+'currentevents' => 'Nöüishkëijte',
+'currentevents-url' => '{{ns:project}}:Et Nöüßte',
+'disclaimers' => 'Henwieß',
+'disclaimerpage' => '{{ns:project}}:Impressum',
+'privacy' => 'Dateschotz un Jehëijmhalldung',
+'privacypage' => '{{ns:project}}:Dateschotz un Jehëijmhalldung',
+'errorpagetitle' => 'Fääler',
+'returnto' => 'Jangk widdo_noh: „$1“.',
+'tagline' => 'Uß de {{SITENAME}}',
+'search' => 'em Täxx',
+'searchbutton' => 'Sööke',
+'go' => 'alß Tittel',
+'searcharticle' => 'alß Tittel',
+'history' => 'Väsjohne',
+'history_short' => 'Väsjohne',
+'updatedmarker' => '(foänndot)',
+'info_short' => 'Ėnnfommazjohn',
+'printableversion' => 'För_ze Drokke',
+'permalink' => 'Allß Permalink',
+'print' => 'För_ze Drokke',
+'edit' => 'Änndere',
+'editthispage' => 'Di Sigk änndere',
+'delete' => 'Fottshmiiße',
+'deletethispage' => 'Di Sigk fott_schmiiße',
+'undelete_short' => '{{PLURAL:$1|ëijn Ännderong|$1 Ännderonge}} zerrökholle',
+'protect' => 'Shöze',
+'protectthispage' => 'Di Sigk schöze',
+'unprotect' => 'Schoz änndere',
+'unprotectthispage' => 'Dä Schoz fö_di Sigk ophävve',
+'newpage' => 'Nöü Sigk',
+'talkpage' => 'Övver di Sigk hee schwaade',
+'specialpage' => 'Söndersigk',
+'personaltools' => 'Medmaacher_Wërrkzöüsh',
+'postcomment' => 'Nöü Affschnett op_de Klaaf_Sigk',
+'articlepage' => 'Aanluere wat op_Dä Sigk drop_shtëijdt',
+'talk' => 'Klaaf',
+'views' => 'Aansėshte',
+'toolbox' => 'Wërrkzöüsh',
+'userpage' => 'Däm Medmaacher sing Sigk aanluere',
+'projectpage' => 'De Projäkk_Sigk aanluere',
+'imagepage' => 'Bėlld_Sigk aanluere',
+'mediawikipage' => 'De Meddëijongß_Sigk aanluere',
+'templatepage' => 'De Schablohn ier Sigk aanluere',
+'viewhelppage' => 'De Hülp_Sigk aanluere',
+'categorypage' => 'De Saachjroppe_Sigk aanluere',
+'viewtalkpage' => 'Klaaf aanluere',
+'otherlanguages' => 'En annder Shprooche',
+'redirectedfrom' => '(Ömjelëijdt fun $1)',
+'autoredircomment' => 'Lëijdt öm op „[[$1]]“',
+'redirectpagesub' => 'Ömlëijdungß_Sigk',
+'lastmodifiedat' => 'Shtand fum $2, $1',
+'viewcount' => 'Di Sigk eß beß jäz {{PLURAL:$1|ëijmol|$1 Mol}} affjeroofe woode.',
+'copyright' => 'Dä Ennhalldt_shtëijdt unger_de $1.',
+'protectedpage' => 'Jeshözde Sigk',
+'jumpto' => 'Jangk noh:',
+'jumptonavigation' => 'Noh_de Navvijazzjohn',
+'jumptosearch' => 'Jangk Sööke!',
+'badaccess' => 'Nit jenooch Rääshde',
+'badaccess-group0' => 'You are not allowed to execute the action you have requested.',
+'badaccess-group1' => 'Wat Do wellß, dat dörrve nuur Medmaacher, di $1 senn.',
+'badaccess-group2' => 'Wat Do wellß, dat dörrve nuur de Medmaacher uß dä Jroppe: $1.',
+'badaccess-groups' => 'Wat Do wellß, dat dörrve nuur de Medmaacher uß dä Jroppe: $1.',
+'versionrequired' => 'De Värsjon $1 fun MediaWiki ßoffwäer eß nüüdish',
+'versionrequiredtext' => 'De Värsjon $1 fun MediaWiki ßoffwäer eß nüüdish, öm di Sigk he bruche ze künne. Süsh op
+
+[[Special:Version|de Väsjohnß_Sigk]], wat mer hee förr_enne ßoffwäer_shtanndt hann.',
+'ok' => 'Okee',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Die Sigk hee shtammp uß „$1“.',
+'youhavenewmessages' => 'Do häßß $1 ($2).',
+'newmessageslink' => 'nöü Meddëijlonge op Dinger Klaaf_Sigk',
+'newmessagesdifflink' => 'Ungerscheed zor füürläzde Väsjoon',
+'editsection' => 'Änndere',
+'editold' => 'Hee di Väsjohn Änndere',
+'editsectionhint' => 'Affshnedt änndere: $1',
+'toc' => 'Enhalldtß_Övverseesh',
+'showtoc' => 'ennblännde',
+'hidetoc' => 'ußblännde',
+'thisisdeleted' => '$1 — aanluere odder widder zerrögk_holle?',
+'viewdeleted' => '$1 aanzëije?',
+'restorelink' => '{{PLURAL:$1|ëijn fottjeschmeßßen Ännderong|$1 fottjeschmeßßene Ännderonge}}',
+'feedlinks' => 'Fiidt:',
+'feed-invalid' => 'Esu enne Tüüp Abonnomang jid_det nit.',
+'nstab-main' => 'Atikkel',
+'nstab-user' => 'Medmaacher_Sigk',
+'nstab-media' => 'Medije_Sigk',
+'nstab-special' => 'Shpezzjahl',
+'nstab-project' => 'Projägk_Sigk',
+'nstab-image' => 'Belldt',
+'nstab-mediawiki' => 'Täxx',
+'nstab-template' => 'Schabbloon',
+'nstab-help' => 'Hülp',
+'nstab-category' => 'Saachjropp',
+'nosuchaction' => 'Di Oppjav (action=) känne mer nit',
+'nosuchactiontext' => '<strong>Na su_jëtt:</strong> Di Oppjaaf us dä URL,
+
+di_do hėnger „<code>action=</code>“ dren shtëijdt, jo_di kännt hee dat Wikki jaa_nit.',
+'nosuchspecialpage' => 'Esu en Söndersigk ham_mer nit',
+'nospecialpagetext' => 'Di aanjefroochte Söndersigk jidd_et nit, de [[Special:Specialpages|Lėßß met_te
+
+Söndersigge]] hėllef Do wigger.',
+'error' => 'Fääler',
+'databaseerror' => 'Fääler in_de Daate_Bangk',
+'dberrortext' => 'Enne Fääler es_opjefalle en dä Süntax fun_ennem Befääl fö_de_Date_Bank.
+Dat künnd_enne Fääler en de ßoffwäer fum Wikki sinn.
+De läzde Date_Bank_Befääl eß jewääse:
+<blockquote><code>$1</code></blockquote>
+uß däm Projramm singe Funkzjohn: „<code>$2</code>“.<br />
+MySQL mälldt dä Fääler: „<code>$3: $4</code>“.',
+'dberrortextcl' => 'Enne Fääler es_opjefalle en dä Süntax fun_ennem Befääl fö_de_Date_Bangk.
+Dä läzde Befääl fö_de Date_Bangg_eß jewääse:
+<blockquote><code>$1</code></blockquote>
+uß däm Projramm singe Funkzjohn: „<code>$2</code>“.<br />
+MySQL mälldt dä Fääler: „<code>$3: $4</code>“.',
+'noconnect' => 'Schadt!
+Mer kunnte këijn Fobinndung med_däm Daate_Bank_ßöövo op „$1“ krijje.',
+'nodb' => 'Kunnt de Daate_Bangk „$1“ nit ußßwääle',
+'cachederror' => 'Dät hee ėss_en Kopii fun_dä Sigk uss_em Cache.
+
+Mööshlish, se iß nit aktowäll.',
+'laggedslavemode' => '<strong>Opjepaßß:</strong> Künnt sinn, dat hee nit dä nöüßte Shtanndt fun dä Sigk
+
+annjezëijsh weedt.',
+'readonly' => 'De Daate_Bangg_eß jeshpächt',
+'enterlockreason' => 'Jiff aan, woröm un fö_wi_lang dat de Daate_Bangk jeshpächt wääde sull',
+'readonlytext' => 'De Daate_Bangk eß jeshpächt. Nöü Saache dren affshpëijshere jëijd_jrad nit, un Änndere
+och nit. Dä Jrunndt: „$1“',
+#Et weed wall_öm_de nommaale Waadung joonn. Důnn_et ëijnfarr_enn_e_paa Menutte widdo fosööke.
+#The administrator who locked it offered this explanation: $1',
+'missingarticle' => 'Dä Täxx fö de Sigk „$1“ kunndte mer nit en de Date_Bank finge.
+
+Di Sigk iß fellëijsh fottjeschmeßße oddo ömmjenanndt woode.
+
+Wann dat esu nit sinn sullt, dann hadd_Er fellëijsh_enne Fääler en de ßoffwäer fefonge.
+Vozälld_ed_ennem Wikki_Köbes,
+un doohd_em och de URL fun dä Sigk hee saare.',
+'readonly_lag' => 'De Daate_Bank eß fö_n koote Zigk jeshpächt, fö_de Daate aff_ze_jliishe.',
+'internalerror' => 'De Wikki-ßoffwäer hädd_enne Fääler jefonge',
+'filecopyerror' => 'Kunnt dė Dattëij „$1“ nit noh „$2“ kopėere.',
+'filerenameerror' => 'Kunnt dė Dattëij „$1“ nit op „$2“ ömdöüfe.',
+'filedeleteerror' => 'Kunnt dė Dattëij „$1“ nit fottschmiiße.',
+'filenotfound' => 'Kunnt dė Dattëij „$1“ nit finge.',
+'unexpected' => 'Domet hät këijne jo jeräshnet: „$1“=„$2“',
+'formerror' => 'Dat eß donävve jejange: Woh nix, met dämm Fomullaa.',
+'badarticleerror' => 'Dat jëijdt met hee dä Sigk nit ze maache.',
+'cannotdelete' => 'Di Sigk odder di Dattëij hee fott_ze_schmiiße eß nit mööshlėsh. Mööshlish, dat enne
+
+anndere Medmaacher flöcker wooh, hädd_et füjo_hejo alld jedonn, un jäz eß_di Sigg_ald fott.',
+'badtitle' => 'Fokiehrte Övverschreff',
+'badtitletext' => 'Di Övverschreff ėß esu nidd_ėn_Ochtnung.
+Et moßß jët dren shtonn.
+Et künnt sinn, dat ëijn fun_de Spėzjäll Zëijshe drėn shtëijdt,
+wat ėn Övverschreffte nit älaub_eß.
+Et künnd_ußsinn, wi_enne Inter_Wikki_Lėngk,
+dat_jëijd_ävver nit.
+Moßß_De reparėere.',
+'perfdisabled' => '<strong>\'\'\'Opjepaßß:\'\'\'</strong> Dat maache mer jäz nit — dä ßööver hät jraad
+
+zo_fill Laßß — do sim_mer jät fürseshtesh.',
+'perfdisabledsub' => 'Hee kütt en jeshpëijshote Koppii fun $1:',
+'perfcached' => 'De Daate he_noh kumme ussem Zwesheshpëijshor (cache) un künnte nit_mieh_janz de allonöüßte sinn.',
+'perfcachedts' => 'De Daate he_noh kumme ussem Zwesheshpëijshor (cache) un woodte $1 opjenumme. Se künnte nit_janz de allonöüßte sinn.',
+'wrong_wfQuery_params' => 'Fokiehrte Parrammeter för: <strong><code>wfQuery()</code></strong><br />
+De Funkßjohn eß: „<code>$1</code>“<br />
+De Aanfrooch eß: „<code>$2</code>“<br />',
+'viewsource' => 'Wikki_Täx Aanluere',
+'viewsourcefor' => 'för di Sigk: „$1“',
+'protectedtext' => 'Di Sigk hee eß jäje Veränderonge jeschöz.
+
+Do künnd_et an Aanzaal fun Ursaache fö_jëvve. Fellëijsh fingk mer jädd_em <span
+
+class="plainlinks">[{{FULLURL:Special:Log/protect|page={{FULLPAGENAMEE}}}} Logbooch]</span> do_drövver.
+
+Jeede kann sijj_ävver dä Wikkitäx fun dä Sigk aanluere un och koppėere. He kütt_e:',
+'protectedinterface' => 'Op dä Sigk hee shtëijdt Täggs_ussem Ingerfäjß fun de Wikki-ßoffwäer.
+Dröm eß dii jäje Änderonge jeschöz, domet Këijne ööhndsenne Meßß domet aanshtälle künne sull.',
+'editinginterface' => '<strong>Opjepaßß:</strong>
+Op dä Sigk hee shtëijdt Täggs_ussem Ingerfäijß fun de Wikki-ßoffwäer. Dröm eß dii jäje Änderonge jeschöz, domet
+
+Këijne ööhndsenne Meßß domet aanshtälle künne sull. Nuur de Wikki_Köbeßße künne
+
+se änndere. Dängk draan, hee Änndere dëijd_et Ußsinn un de Wööt änndere met dänne et Wikki op de Medmaacher un de
+
+Besööker drop aankütt!',
+'sqlhidden' => '(Dä SQL_Befääl dům_mer nit zëije)',
+'logouttitle' => 'Ußß_Logge',
+'logouttext' => 'Jäz beß_De ußßjelogg.
+
+* Do künnz op de {{SITENAME}} wigger maache, alls_enne name_lose Medmaacher.
+
+* Do kannß Dėjj_ävver_och widdo [[Special:Userlogin|ėnnlogge]], allß do_sälləve oddo och enne anndere Medmaacher.
+
+* Un Do kanns_enne <span class="plainlinks">[{{FULLURL:Special:Userlogin|type=signup}} enne nöüje Medmaacher
+
+aanmällde]</span>.
+
+<strong>Opjepaßß:</strong>
+
+Eß mööshlish, dat_Te de ëijn_oddo_anndere Sigk ėmmo wiggo aanjezëijsh krißß, wi wänn de noch ėnnjelogg_wööhß. Donn
+
+Dingem Brauser singe Cache
+
+fottschmiiße oddo leddish_maache, öm uß dä Nummo_erruß_ze_kumme!<br />',
+'welcomecreation' => '== Tach, $1! ==
+
+Dinge Zojang fö_hee eß doh. Do beß jäz aanjemälldt. Dengk draan, Do küünz Der Ding [[Special:Preferences|ming
+
+Ëijnshtellunge]] hee op de {{SITENAME}} zerrääshmaache.',
+'loginpagetitle' => 'Ėnnlogge',
+'yourname' => 'Medmaacher_Name',
+'yourpassword' => 'Paßßwoodt',
+'yourpasswordagain' => 'Norr_enß dat Paßßwoodt',
+'remembermypassword' => 'Op_Dauer Aanmällde',
+'yourdomainname' => 'Ding Domain',
+'externaldberror' => 'Do woo enne Fääler en de äxtärrne Daate_Bangk, oddo Do darrəfß Ding äxtärrn Daate nit
+
+änndere. Dat Aanmällde jingk donävve.',
+'loginproblem' => '<strong>Med däm Ėnnlogge eß jëtt schëijf jeloufe.</strong><br />Beß esu jood, un důnn_et
+
+norr_enß fosööhke!',
+'alreadyloggedin' => 'Do beß alld ennjelogg, als dä Medmaacher „<strong>$1</strong>“. Wänn_De nuur ann_ennem
+
+Kompjuto sez, wo sesj_enne Anndere enjelogg hätt, dann bess_esu jood, un důnn [[Special:Userlogout|ußßlogge]], iih
+
+dat_Te Sigge änndere dëijß! Dat moß_De och donn, wänn_De Desh don_noh medd_ennem anndere Naame wi
+
+„<strong>$1</strong>“ widde ennlogge wellß.<br />',
+'login' => 'Ėnnlogge',
+'loginprompt' => 'Öm op de {{SITENAME}} [[Special:Userlogin|ennlogge]] ze künne,
+moßß_De de Cookieß]en Dingem Brause]ennjeschalldt hann.',
+'userlogin' => 'Ėnnlogge / Medmaacher wääde',
+'logout' => 'Ußß_Logge',
+'userlogout' => 'Ußlogge',
+'notloggedin' => 'Nėd_Ėnnjelogg',
+'nologin' => 'Wänn_De Dėsh noh_nit aanjemälldt häßß,
+dann donn Dėsh $1.',
+'nologinlink' => 'Nöü Aanmällde',
+'createaccount' => 'Aanmällde als_enne nöüje Medmaacher',
+'gotaccount' => 'Do häßß alld_enn Aanmälldung op de {{SITENAME}}? Dann jangk noh_m $1.',
+'gotaccountlink' => 'Enlogge',
+'createaccountmail' => 'Paßßwoodt med e-mail Schekke',
+'badretype' => 'Ding zwëij ennjejovvene Paßßwööter sinn ungerscheedlish. Do moßß_De Desch fö_ëijn
+
+änntschëijde.',
+'userexists' => 'Enne Medmaacher med_däm name: „<strong>$1</strong>“ jidd_et alld. Schaadt. Doh moßß De
+
+Der_enne anndere Naame ußdängke.',
+'youremail' => 'E-mail *',
+'username' => 'Medmaacher_Name:',
+'uid' => 'Medmaacher ID:',
+'yourrealname' => 'Dinge rishtijje Name *',
+'yourlanguage' => 'Shprooch:',
+'yourvariant' => 'Ding Varijant',
+'yournick' => 'Name fö_en_Dinge Ungerschreff:',
+'badsig' => 'Di Ungeschreff jëijd_esu nit — luer noh dem HTML
+
+do_dren un maach et rėshtėsh.',
+'email' => 'E-Mail',
+'prefs-help-email-enotif'=> 'Di e-mail Addräßß weed och jebruch, öm Der övver Ännderonge beshëijdt_ze_saare, wänn_De
+
+dat ußßjevääldt häßß, en Dinge Ëijnshtellunge.',
+'prefs-help-realname' => '* Dinge rishtijje Name — kannz_E fott_loohße — wänn_De_n nänne wellß, do weedt_e jebruch,
+
+öm Ding Bëijdrääsh hee, domet ze schmökke.',
+'loginerror' => 'Fääler bem Ennlogge',
+'prefs-help-email' => '* E-mail — kannß_De fott_loohße, un es för Anndre nit_tse sinn — määd_et ävver mööshlish,
+
+dat mer met Dier en Kontak_kumme kann, oohne dat mer Dinge Name odder Ding e-mail Adräß känne däät.',
+'nocookiesnew' => 'Dinge nöüje Medmaacher_Name eß ėnnjerėshdt, ävver dat outomaatish Ėnnlogge woo dan_nix.
+
+Schaadt. De {{SITENAME}} bruch Cookieß, öm ze merrəke, wä
+
+ėnjelogg_eß. Wänn_De Cookieß affjeschaldt häß, en Dingem Brauser, dann kann
+
+dat nit loufe. Söök_Der_enne Brauser, dä et kann, donn_se ennschallde, un dann log Dėsh norr_enß nöü ėnn, met Dingem
+
+nöüje Medmaacher_Name un Paßßwoodt.',
+'nocookieslogin' => 'De {{SITENAME}} bruch Cookieß förr_et
+
+Ėnlogge. Et süüht esu uß, alß hättß_de Cookieß affjeschalldt. Důnn_se aanschallde un_dann fosöhg_et norr_enß.',
+'noname' => 'Dat jëijdt nidd_alls_enne Medmaacher_Naame. Jäz moßß_De_et norr_enß fosööke.',
+'loginsuccesstitle' => 'Dat Ėnlogge hät jeflupp.',
+'loginsuccess' => '<br />Do beß jäz enjelogg_bëij_de <strong>{{SITENAME}}</strong>, un Dinge
+
+Medmaacher_Naame eß „<strong>$1</strong>“.<br />',
+'nosuchuser' => 'Dat Passwoot odder dä Medmaacher_Naam woo fokiehrt. Jäz moßß_De_et norr_enß fosööke.
+Odder_<span class="plainlinks">[{{FULLURL:Special:Userlogin|type=signup}} enne nöüje Medmaacher aanmällde]</span>.',
+'nosuchusershort' => 'Dä Medmaacher_Naam woo fokiehrt. Jäz moßß_De_et norr_enß fosööke.',
+'nouserspecified' => 'Dat jëijdt nidd_alls_enne Medmaacher_Naame',
+'wrongpassword' => 'Dat Passwoot odder dä Medmaacher_Naame woo fokiehrt. Jäz moßß_De_et norr_enß fosööke.',
+'wrongpasswordempty' => 'Dat Paßßwoodt kam_mer nit fott_loohße.
+Jäz moßß_De_et norr_enß fosööke.',
+'mailmypassword' => 'Paßßwoodt fojäßße?',
+'passwordremindertitle' => 'Login op {{SITENAME}}',
+'passwordremindertext' => 'Joot mööshlish, Do wooß et sellver,
+fun de IP_Addräßß $1,
+jedenfallß hät Eijne aanjefrooch, dat
+mer Dier e neu Paßßwoodt zo_schekke sull,
+för et Ennlogge en de {{SITENAME}} op
+{{FULLURL:{{MediaWiki:Mainpage}}}}
+($4)
+
+Allso, e neu Paßßwoodt för "$2"
+es jäz füürjemerrek: "$3".
+Do sulltß De tiräg jlish enlogge,
+un dat Passwoot widde ännderre.
+Dä Tranßpocht övver et Näz met e-mail
+eß unsesher, do künne Främbde metlässe,
+un winnishßtenß de Jehäjmdeenßte dunn
+dat och. Ußßerdämm eß "$3"
+felleijsh ned_esu joot ze merreke?
+
+Wänn nit Do, söndern sönß wer noh däm
+neue Paßßwoodt forlangk hätt, wänn De
+Desh jäz doch widde aan Ding ahl Paßßwoodt
+äntsenne kannß, jo da bruchß de jaa nix
+ze donn, da kannß De Ding ahl Paßßwood_wigge
+bruche, un di e-mail hee, di kannß De
+jlatt forjäßße.
+
+Enne schööne Jrooß fun de {{SITENAME}}.
+
+--
+{{SITENAME}}: {{fullurl:{{Mediawiki:mainpage}}}}',
+'noemail' => 'Dä Medmaacher hät en de $1 këijn e-mail Addräßß aanjejovve.',
+'passwordsent' => 'E nöü Paßßwoodt eß aan de e-mail Addräßß fun däm Medmaacher ungerwähß. Mälldt desh do_met
+aan, wänn_De_t häßß. Dat aahle Paßßwoodt blief ähallde un kann och noch jebruch wääde, beß dat De Dejj_et eezt Mohl
+met däm Nöüe ėnnjelogk häßß.',
+'eauthentsent' => 'En e-mail eß jäz ungerwääß aan di Addräß, di en de Ëijnshtellunge vum Medmaacher $1
+
+shtëijdt.
+Ih dat_do_hen jäds_och e-mails övver de {{SITENAME}} iere e-mail-Knopp foshekk wääde künne, moß di e-mail Addräßß
+eetß_enß beshtähtish woode sinn. Wat mer do_fö_maache moß, shtëijd_en dä e-mail dren, di jrad affjeschek woode_eß.
+
+Allso luer do_erinn, un donn_et.',
+'mailerror' => 'Fääle bëij_em e-mail foshekke: $1.',
+'acct_creation_throttle_hit'=> '<b>Schaadt.</b> Do häß alld {{PLURAL:$1|ëijne|$1}} Medmaacher_Naame aanjelaat. Mieh
+
+senn nit mööshlėsh.',
+'emailauthenticated' => 'Ding e-mail Addrëßß wood beshtäätisj_om: $1.',
+'emailnotauthenticated' => 'Ding e-mail Addrëßß ėß nit beshtäätish.
+Dröm kann këijn e-mail aan Dėsh jeschekk wääde för:',
+'noemailprefs' => 'Důnn_en e-mail Adräßß enndraare, domet dadd_all fluppe kann.',
+'emailconfirmlink' => 'Donn Ding e-mail Addrëßß beshtäätije loohße',
+'invalidemailaddress' => 'Wat_De do alls_en e-mail Adräßß aanjejovve häß, süüt noh Drißß uß. En e-mail Addräss_en
+
+däm Fommat, dat jidd_et nit. Moß De reparėere — oddo Do määß dat Fëlld lëddish un schriifß nigs_errinn. Un_dann
+
+fosöög_et norr_enß.',
+'accountcreated' => 'Aanjemëlldt',
+'accountcreatedtext' => 'De Aanmëlldung fö_dä Medmaacher „<strong>$1</strong>“ eß dorsh, kann jätz enlogge.',
+'bold_sample' => 'Fätt_Schreff',
+'bold_tip' => 'Fätt_Schreff',
+'italic_sample' => 'Shëijve Schreff',
+'italic_tip' => 'Sheeve Schreff',
+'link_sample' => 'Angkor_Täxx',
+'link_tip' => 'Enne Lingk en de {{SITENAME}}',
+'extlink_sample' => 'http://www.example.com/ Dä Angkor_Täx',
+'extlink_tip' => 'Enne Lingk noh drußße (dängk draan, http:// aan der Aanfang!)',
+'headline_sample' => 'Övverschreff',
+'headline_tip' => 'Övverschreff op de bövverschte Ebenne',
+'math_sample' => 'Hee schrieef di Forrmel hen',
+'math_tip' => 'En mattemaatisch Forrmelle nemm „LaTeX“',
+'nowiki_sample' => 'Hee kütt dä Täx hen, dä fun de Wikki_ßoffwäer net beärbëijdt, un en Rou jeloohße wääde
+
+sull',
+'nowiki_tip' => 'De Wikki_Koode övverjonn',
+'image_sample' => 'Beijshpill.jpg',
+'image_tip' => 'E Belltsche ennboue',
+'media_sample' => 'Beijshpill.ogg',
+'media_tip' => 'Enne Lengk ob_enn Ton_Datteij, e Filləmshe, odder_esu_jät',
+'sig_tip' => 'Dinge Naame, med de Urzigk unn_em Dattum',
+'hr_tip' => 'En Qweerlinnish',
+'summary' => 'Koot Zosammejefaßß, Kwälle',
+'subject' => 'Övverschreff — wo_dröm jëijd_et?',
+'minoredit' => 'Dad_ess_en klëijn Ännderung (mini)',
+'watchthis' => 'Op di Sigk hee op_paßße',
+'savearticle' => 'Di Sigk Affspëijshere',
+'preview' => 'Füür_Aansėsh',
+'showpreview' => 'Füür_Aansėsh Zëije',
+'showlivepreview' => 'Lebänndijje Füür_Aansėsh Zëije',
+'showdiff' => 'De Ungerscheed zëije',
+'anoneditwarning' => 'Wëijl De net [[Special:Userlogin|ennjelogg]] beß, weedt Ding
+
+IP_Addräßß opjezëijshnet wääde, bëij_de Lėßß fun de <span
+
+class="plainlinks">[{{FULLURL:{{PAGENAME}}|action=history}} Donn DingVäsjohne]</span> fun_de Ännderonge fö_di_Sigk.
+
+Wänn_De dat nit hann wellß, důnn_nix affshpëijshere, oddo Dëijß äävenß [[Special:Userlogin|ennjelogge]], nê.',
+'missingsummary' => '<strong>Opjepaßß:</strong> Do häß nix bëij „Koot Zosammejefaßß, Kwälle“ ennjejovve. Donn
+
+norr_enß op „<b style="padding:2px; background-color:#ddd; color:black">Di Sigk Affspëijshere</b>“ klikke, öm Ding
+
+Ännderonge der_oohne_ze Shpëijshere, ävver bäßßo jißß_De do jätß_tirrägg_enß jätt enn!',
+'missingcommenttext' => 'Jivv_en „Koot Zosammejefaßß, Kwälle“ aan!',
+'blockedtitle' => 'Dä Medmaacher eß jeshpächt',
+'blockedtext' => '<big><b>Dinge Medmaacher_Name odder IP_Addräßß eß fun „$1“ jeshpächt woode.</b></big>
+
+Alß Jrund_eß ennjedraare: „<i>$2</i>“
+
+Do kannß met „$1“ oddo enne anndere Wikki_Köbes övver dat Shpärre schwade, wänn
+
+de wellß.
+
+Do kannß ävver nur dann dat „<i>E-mail aan dä Medmaacher</i>“ aanwände, wänn de ald en e-mail Adräßß en Dinge
+
+[[Special:Preferences|ming Ëijnshtellunge]] ennjedrare un frëijjejovve häßß.
+
+Ding IP_Addräßß eß de „$3“. Dunn se en Dinge Aanfroore nänne.',
+'blockedoriginalsource' => 'Dä Orrijinaal Wikki_Täxx fun dä Sigk „<strong>$1</strong>“ shtëijdt he drungo:',
+'blockededitsource' => 'Dä Wikki_Täxx fun <strong>Dinge Ännderonge</strong> aan dä Sigk „<strong>$1</strong>“
+
+shtëijdt he drungo:',
+'whitelistedittitle' => 'Enlogge nüüdish för Sigge ze Änndere',
+'whitelistedittext' => 'Do möötß alld_[[Special:Userlogin|ėnnjelogk_sinn]], öm hee em Wikki Sigge änndere ze
+dörrve.',
+'whitelistreadtitle' => 'Enlogge nüüdish för ze Lässe',
+'whitelistreadtext' => 'Do möötß alld_[[Special:Userlogin|ėnnjelogk_sinn]], öm hee Sigge Lësse ze dörrve.',
+'whitelistacctitle' => 'Këij Rääsh för Medmaacher aan_ze_lääje.',
+'whitelistacctext' => 'Do möötß alld_[[Special:Userlogin|ėnnjelogk_sinn]] un shpezzjäll_et Rääsh dofüer hann, öm
+
+hee en dämm Wikki Medmaacher ėnnrishte un aanlääje ze dörrəve.',
+'confirmedittitle' => 'För_et Sigge Änndere moß_De_Ding e-mail Adräßß ald beshtätėsh hann.',
+'confirmedittext' => 'De moß_Ding e-mail Adräßß ald beshtätėsh hann, ih_dat_De hee Sigge änndere darrəfß.
+
+Draach Ding e-mail Addräßß en Dinge [[{{ns:special}}:Preferences|ming Ëijnshtellunge]] enn, un důnn „<span
+
+style="padding:2px; background-color:#ddd; color:black">Donn Ding e-mail Addrëßß beshtäätije loohße</span>“ klikke.',
+'loginreqtitle' => 'Enlogge is nüüdish',
+'loginreqlink' => 'ėnnlogge',
+'loginreqpagetext' => 'Do moßß $1 ömm annder Sigge aanzeluere.',
+'accmailtitle' => 'Paßßwordt fosheck',
+'accmailtext' => 'Dat Paßßwoodt fö_dä Medmaacher „$1“ eß aan „$2“ jeschek woode.',
+'newarticle' => '(Nöü)',
+'newarticletext' => 'Enne Lėngk ob_en Sigk, wo non_nix drop shtëijdt, wëijl_et se noh jaa nit jitt, hät_Dish
+
+noh_hee jebraat.<br />
+
+<small>Öm di Sigk aanzelääje, schrief hee unge en dat Fëlld_errinn, un donn et dann affshpëijshere. (Luer op de
+
+Sigge met Hülp noh, wänn De mih do drövver weßße wellß)<br />Wänn De jaa nit hee hen
+
+kumme wůlltß, da_jangk zerög_op di Sigk, wo De heeo_jekumme beß, Dinge Brauser hädd_enne Knopp do_för.</small>',
+'anontalkpagetext' => '----
+<i>Dat hee eß de Klaaf_Sigk för_enne namenlose Medmaacher. Dä hät sesh noch këijne Medmaacher_Name jejovve un
+
+ėnnjereshdt, ov dëijt këijne bruche. Dröm bruche mier sing IP Addräßß ömm It oddo Inn en unsere Lėßßte faßzehallde.
+
+Su_w_en IP Adräßß kann fun janzz fille Medmaacher op ëijmool jebruch wääde, un ëijne Medmaacher kann janz flögk
+
+zwesche de ungescheedlishßte IP Adräßße wääßelle, wö_mööshlish oohn_datt_er_et märrək. Wänn Důů_jäds_enne namenlose
+
+Medmaacher beß, un fingkß, dat hee Saache an Dish jeschrevve wääde, wo Do jaa_nix medd_am_Hoot häßß, dann beß Doo
+
+vashëijnlijj_och nit jemëijndt. Dängk fellëijsj_enß drövver noh, dat_E Desh [[Special:Userlogin|aanmällde]] däijß,
+
+domet De dann don_noh nit mieh medd_esu_en Ömshtändt_ze donn häßß, vi di anndere namenlose Medmaacher hee.</i>',
+'noarticletext' => 'Hee eß jeds_em Momang këijne Täggs_ob_dä Sigk.<br />Jangk en de Täxte fun annder Sigge
+
+[[Special:Search/{{PAGENAME}}|noh däm Tittel sööhke]], oddor jangk, un <span
+
+class="plainlinks">[{{FULLURL:{{FULLPAGENAME}}|action=edit}} fang di Sigk aan]</span> ze schriive.<br
+
+/><small>Oddo_jangk zerök wo de heer koohmß. Dinge Brauser hädd_enne Knopp do_füer.</small>',
+'clearyourcache' => '<br clear="all" style="clear:both">
+\'\'\'Opjepaßß:\'\'\'
+Noh_rem Shpëijshere, künnd_et sinn, dat_Te Dingem Brauser singe Cache_Spëijsher
+
+övverlißßte moß, ih_dat_Te di Ännderonge och ze sinn krißß.
+Bëijm \'\'\'Mozilla\'\'\' un \'\'\'Firefox\'\'\' un \'\'\'Safari\'\'\', dröck de \'\'Jruß_Schreff_Knopp\'\' un
+
+Kligg_op \'\'Refresh\'\' / \'\'Aktualisieren\'\', oddo drögk \'\'Ctrl-Shift-R\'\' / \'\'Strg+Jruß_Schreff+R\'\', oddo
+
+drögk \'\'Ctrl-F5\'\' / \'\'Strg/F5\'\' / \'\'Cmd+Shift+R\'\' / \'\'Cmd+Jruß_Schreff+R\'\', je noh Dinge Taßtattuuer
+
+un Dingem Kompjutor.
+Bëijm \'\'\'Internet Explorer\'\'\' drögg_op \'\'Ctrl\'\' / \'\'Strg\'\' un Kligg_op \'\'Refresh\'\', oddo drögk
+
+\'\'Ctrl-F5\'\' / \'\'Strg+F5\'\'.
+Bëijm \'\'\'Konqueror:\'\'\' kligk dä \'\'Reload\'\'-Knopp oddo dröck dä \'\'F5\'\'-Knopp.
+Bëijm \'\'\'Opera\'\'\' kannß_De övver_et Mennüh jonn un
+
+däm jannze Cache singe Ėnnhalld_övver \'\'Tools→Preferences\'\' fott_schmiiße.',
+'usercssjsyoucanpreview'=> '<b>Tipp:</b> Donn met dämm <b style="padding:2px; background-color:#ddd;
+
+color:black">Füür_Aansėsh Zëije</b>-Knobb_ußßprobėere, wat Ding nöü
+
+Medmaacher_CSS/Java_Skripp määd,_iih_dat_et affshpëijshore dëijß!',
+'usercsspreview' => '<b>Opjepaßß: Do beß hee nur am Ußßprobėere, wat Ding
+
+Medmaacher_CSS määd,_ed_eß non_nit jeseshot!</b>',
+'userjspreview' => '<b>Opjepaßß: Do beß hee nur am Ußßprobėere, wat Ding
+
+Medmaacher_Java_Skripp määd_ed_eß non_nit jeseshot!</b>',
+'userinvalidcssjstitle' => '<strong>Opjepaßß:</strong> Et jitt këijn Uß_sinn med_däm Name: „<strong>$1</strong>“ —
+
+dängk draan, dat enne Medmaacher ëijenne Datëije förr_et Uß_sinn hann kann, un dat_di met klëijne Boochashtave
+
+aanfange donn, also ätva: {{ns:User}}:Name/monobook.css, un {{ns:User}}:Name/monobook.js uew. hëijshe.',
+'updated' => '(Aanjepakk)',
+'note' => '<strong>Opjepaßß:</strong>',
+'previewnote' => '<strong>He kütt nur de Füür_Aanseesh — Ding Ännderonge sin_non_nit jeseshort!</strong>',
+'session_fail_preview' => '<strong>Schaadt: Ding Ännderonge kunnte mer su nix mėd aanfange.
+
+De Daate fun Dinge Login-Sëschen sinn nit öhndlėsh erövver jekumme, odder ëijnfach ze alldt.
+
+Fosöög_et jraadt norr_enß. Wänn dat widder nit flupp, dann fosöög_et enß met [[Special:Userlogout|Ußlogge]]
+
+un_widder_Ėnnlogge. Ävver pass_op, dat_Te Ding Änderonge do_bëij behällß! Zo_Nuud důnn_se eetß enß bëij Dir om Räshno
+
+affshpëijshere.</strong>',
+'previewconflict' => 'He_di Füür_Aansėsh zëijsh dä Enhalldt fum bovvere Täxx_Fëlldt. Esu wöödt_dä Atikkel
+
+ußsinn, wänn_De_n jäz affshpëijshere dääts.',
+'session_fail_preview_html'=> '<strong>Schaadt: Ding Ännderonge kunnte mer su nix mėd aanfange.<br />De Daate fun
+
+Dinge Login-Sëschen sinn nit öhndlėsh erövver jekumme, odder ëijnfach ze alldt.</strong>
+
+Dat Wikki hee hät <i>rüüh HTML</i> zojeloohße, dröm weed de Füür_Aansėsh nit jezëijsh. Domet sollß_De jeschöz wääde —
+
+hoffe mer — un Aanjreffe med Java_Skripp jääje Dinge Kompjuto künne_Der nix aandonn.
+
+<strong>Fallß fö Dėsh sönß alles jood_ußsüüht, fosöög_et jraadt norr_enß. Wann dat widder nit flupp, dann fosöög_et
+
+enß met [[Special:Userlogout|Ußlogge]] un_widder_Ėnnlogge. Ävver pass_op, dat_Te Ding Änderonge do_bëij behällß!
+
+Zo_Nuud důnn_se eetß enß bëij Dir om Räshno affshpëijshere.</strong>',
+'importing' => '„$1“ am Impochtėere',
+'editing' => 'Di Sigk „$1“ änndere',
+'editinguser' => 'Di Sigk „$1“ änndere',
+'editingsection' => 'Ne Affshnedt fun dä Sigk: „$1“ änndere',
+'editingcomment' => '„$1“ Änndere (enne nöüje Affshnedd schriive)',
+'editconflict' => 'Problemshe: „$1“ dubbeld beärrbëijdt.',
+'explainconflict' => '<br />Enne anndere Medmaacher hät aan dä Sigk och jät jeänndodt, un zwa nohdämm Do en
+
+Änndere aanjefange häß. Jäz ham_mer dä salladt, un Do darrvs_et widdo ußzotteere.
+
+<strong>Opjepass:</strong>
+
+<ul><li>Dat bovverre Täxx_Fëlldt zëijsh di Sigg_esu, wi_se jäds_em Mommändt jeshpëijsherd_eß, allso med_de Ännderönge
+
+fun alle anndere Medmaacher, di flöcker wi Do jeshpëijshot hann.</li><li>Dat ungerre Täxx_Fëlldt zëijsh di Sigg_esu,
+
+wi_ß_De_se sellver zoläz zerääsh jebrasselt häß.</li></ul>
+
+Do moßß jäz Ding Ännderonge och in dat <strong>bovvere</strong> Täxx_Fëlldt erinn brenge. Nattöörlėsh oohne dä
+
+Anndere ier Saache kapott ze maache.
+
+<strong>Nuur wat em bovvere Täxx_Fëlldt shtëijt,</strong> dat weed övvernumme un affjeshpëijshot, wänn_De „<b
+
+style="padding:2px; background-color:#ddd; color:black">Di Sigk Affspëijshere</b>“ klix. Beß do_hen kannß_De_esu öff
+
+wi_De_wellß op „<b style="padding:2px; background-color:#ddd; color:black">Füür_Aansėsh Zëije</b>“ un „<b
+
+style="padding:2px; background-color:#ddd; color:black">De Ungerscheed zëije</b>“ klikke, öm ze prööfe, wat_Te alld
+
+joodß jemaat häß.
+
+Alleß Klooh?<br /><br />',
+'yourtext' => 'Dinge Täxx',
+'storedversion' => 'De jeshpëijshote Väsjohn',
+'nonunicodebrowser' => '<strong>Opjepaßß:</strong> Dinge Brauser kann nit
+
+ööndlėsh met däm Unicode un singe Boochstaave ömjonn. Bess_esu_joot un
+
+nėmmbs_enne anndere Brauser fö hee di Sigk!',
+'editingold' => '<strong>Opjepaßß!<br />
+Do beß en aahle, övverhollte, Väsjohn fun dä Sigk hee am Änndere.
+Wänn_De di affshpëijshere dëijß,
+wi se eß,
+dann sinn all_di Ännderonge foloohre,
+di zigk dämm aan dä Sigk jemaat woode sėnn.
+Allso:
+Beß De sesher,
+watt de määhß?
+</strong>',
+'yourdiff' => 'Ungerscheede',
+'copyrightwarning' => 'Ding Bëijdräsh shtonn unger de [[$2]], süch $1. Wänn De nit hann wellß, dat Dinge Täx
+
+ömjemoodeldt weed, un sönß wo_hen fodëijlt, donn_en hee nit shpëijshere. Me_m Affshpëijshere sääß De och zo, dadd_et
+
+fun Dier sellfß eß, un/oddo Do dat Rääsh häß, en hee zo forbrëijde. Wenn_t nit shtimmp, oddo Do kanns_et nit
+
+nohwiise, kann Dish dad_en_do Bou brenge!',
+'copyrightwarning2' => 'De Bëijdräsh en de {{SITENAME}} künne fun anndere Medmaacher ömjemoodeldt
+
+of_fottjeschmeßße wääde. Wänn Der dat nit rääsh eß, schriif nix. Et eß och nüüdish, dadd_et fun Dier sellfß eß, oddo
+
+dat Do dat Rääsh häß, et hee öffentlish wigger ze jävve. Süsh $1. Wenn_t nit shtimmp, oddo Do kanns_et nit nohwiise,
+
+künnt Dish dad_en_do Bou brenge!',
+'longpagewarning' => '<strong>Oppjepaßß:</strong> Dä Täxx, dä De hee jeschekk häß, dä eß <strong>$1</strong>
+
+Kilobyte jruuß. Mansh Brauser kütt nėt domet klooh, wänn_et mieh wi <strong>32</strong> Kilobyte sinn. Do künntß De drövver nohdängke, dat
+
+Dinge en klëijner Shtökshe ze_zerklope.',
+'longpageerror' => '<big><strong>Jannz Schlemme Fääler:</strong></big>
+
+Dä Täxx, dä De hee jeschekk häß, dä eß <strong>$1</strong> Kilobyte jruuß.
+
+Dat sinn mieh wi <strong>$2</strong> Kilobyte. Dat künne mer nit Shpëijshere!
+
+<strong>Maach klëijner Shtökke druß.</strong><br />',
+'readonlywarning' => '<strong>Opjepaßß:</strong> De Daate_Bangk eß jeshpächt woode, wo Do ald_am Änndere woohß.
+
+Däh. Jëz kannß_De Ding Änderonge nit mieh affshpëijshere. Donn se bëij Dir om Räshno faßßhallde un fosöög_et spääder
+
+norr_enß.',
+'protectedpagewarning' => '<strong>Opjepaßß:</strong> Di Sigk hee eß jäje Veränderonge jeschöz — wiso weed_em <span
+
+class="plainlinks">[{{FULLURL:Special:Log/protect|page={{FULLPAGENAMEE}}}} Logbooch]</span> shtonn. Nuur de
+
+Wikki_Köbeßße künne se änndere. Bess_esu jood un halldt Desh aan de Räjelle för
+
+dä Fall!',
+'semiprotectedpagewarning'=> '<strong>Opjepaßß:</strong> Di Sigk hee eß hallef jeshpächt, wi mer sare, dat hëijß, Do
+
+moß [[Special:Userlogin|aanjemälldt un ėnnjelogk]] sinn, wänn_De draan änndere wellß.',
+'templatesused' => 'De Shabloone, di fun dä Sigk hee jebruch wääde, sinn:',
+'edittools' => '<!-- Dä Täx hee zëijsj_et Wikki unger dä Täxx_Fälldt zem „Änndere/Beärbëijde“ un bëijm
+
+Täxx_Fälldt fum „Huhlade“. -->',
+'nocreatetitle' => 'Ėnnlogge eß nüüdėsh',
+'nocreatetext' => 'Sigge nöü aanläje eß nur möshlesh, wänn_de [[Special:Userlogin|enjelogk]] beß. Der oohne
+
+kannß_De ävver Sigge änndere, di ald_doo sinn.',
+'cantcreateaccounttitle'=> 'Kann këijne Zojang ėnnreshde',
+'cantcreateaccounttext' => 'Aanmälldunge fun Dinge IP_Addräßß [<strong>$1</strong>] senn jeshpächt. Dat hät fö_jewöönlijj_enne Jrundt. Zom Bëijshpill künnt sinn, dat
+
+fill_ze_fill SPAM fun däm Berëijsh fun dä Adräßße jekumme eß.',
+'revhistory' => 'De Väsjohne',
+'viewpagelogs' => 'De LogBöösher fö hee di Sigk',
+'nohistory' => 'Et jitt këijn Väsjohne fun dä Sigk.',
+'revnotfound' => 'Di Väsjohn ham_mer nit jefonge.',
+'revnotfoundtext' => '<b>Däh.</b> Di ählere Väsjohn fun dä Sigk, wo De noh froochß, eß nit do. Schadt. Luer_enß
+
+op di URL, di Dėsh hääjebraadt hät, di weed fokiehrt sinn, oder se iß fellëijsj_övverholldt, wëijl Ëijne di Sigk
+
+fottjeschmeßße hätt?',
+'loadhist' => 'Donn de Lėßß met ahle Väsohne laade',
+'currentrev' => 'Nöüßte Väsjohn',
+'revisionasof' => 'Väsjohn fum $1',
+'revision-info' => 'Väsjohn fum $1; $2',
+'previousrevision' => '← De Revisjohn dö_für zëije',
+'nextrevision' => 'De Väsjohn do_noh zëije →',
+'currentrevisionlink' => 'De nöüßte Väsjohn',
+'cur' => 'nöü',
+'next' => 'Wiggo',
+'last' => 'läz',
+'orig' => 'Orrjinahl',
+'histlegend' => 'Hee kanns_De Väsjohne för_et Forjlishe ußsööke: Donn met dä Knöpp di zwëij makkeere,
+
+zwesche dänne De de Ungescheed jezëijsh krijje wellß, dann dröck „<b style="padding:2px; background-color:#ddd;
+
+color:black">Důnn de makėete Väsjohne fojlishe</b>“ bëij Dinge Taßte, oddo klick op ëijn fun dä Knöpp övver odder
+
+unger de Lėßß.
+
+Äklierong: (nöü) = Fojlishe met de nöüßte Väsjohn, (läz) = Fojlishe met de Väsjohn ëijn_do_füer, <b>M</b> = en
+
+klëijne <b>M</b>ini_Ännderongk.',
+'deletedrev' => '[fott]',
+'histfirst' => 'Ählßte',
+'histlast' => 'Nöüßte',
+'rev-deleted-comment' => '(„Koot Zosammejefaßß, Kwälle“ ußßjeblenndt)',
+'rev-deleted-user' => '(Medmaacher_Name ußßjeblenndt)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">Di Väsjohn eß fottjeschmeßße woode. Jäz kam_mer
+
+se nit mieh beluere. Enne Wikki_Köbeß künnt se ävver zerrög_holle. Mieh drövver, vat met däm Fottschmiiße fun dä Sigk
+
+jewääse eß, künnd_Er em [{{FULLURL:Spezial:Log/delete|page={{PAGENAMEE}}}} Logbooch] nohlässe.</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">Di Väsjohn eß fottjeschmeßße woode. Jäz kam_mer se nit
+
+mieh beluere. Alls_enne Wikki_Köbes krėßß_De_se ävver doch ze_sinn, un küünz_e
+
+och zerrög_holle. Mieh drövver, vat met däm Fottschmiiße fun dä Sigk jewääse eß, künnd_Er em
+
+[{{FULLURL:Spezial:Log/delete|page={{PAGENAMEE}}}} Logbooch] nohlässe.</div>',
+'rev-delundel' => 'zëije/ußblännde',
+'history-feed-title' => 'Väsjohne',
+'history-feed-description'=> 'Äählere Väsjohne fun dä Sigk en de {{SITENAME}}',
+'history-feed-item-nocomment'=> '$1 öm $2',
+'history-feed-empty' => 'Di aanjefroocht Sigk jidd_et nit. Künnt sinn, dat se enzwesche fott_jeschmeßße oddo
+
+ömm_jenanndt voode eß. Kannß jo enß [[Special:Search|em Wikki sööke lohße]], öm paßßend nöüje Sigge ze finge.',
+'revisiondelete' => 'Väsjohne fottschmiiße un widdo zerrögk_holle',
+'revdelete-selected' => 'Ußßjewählte Värsjohn fun [[:$1]]:',
+'revdelete-text' => 'Dä fottjeschmeßßene Sigge ier Ennhaldt kannß_De nit mieh aanluere. Se bliive ävver en de
+
+Lėßß met_e Väsjohne dren.
+
+Enne Wikki_Köbes kann de fottjeschmeßßene Krohm emmo noch aanluere un kann_en och widdo_hää_holle, ußßer wänn bëij
+
+dem Wikki singe Inshtallzjohn dat angersch faßßjelaat woode eß.',
+'revdelete-legend' => 'Dä öffentlijje Zojang ennschrängke, fö_di Väsjohn:',
+'revdelete-hide-text' => 'Dä Täx fun dä Väsjohn ußblännde',
+'revdelete-hide-comment'=> 'Dä Ennhaldt fun „Koot Zosammejefaßß, Kwälle“ ußblännde',
+'revdelete-hide-user' => 'Däm Beärrbëijder sing IP_Addräßß oddo Medmaacher_Naame ußblännde',
+'revdelete-hide-restricted'=> 'Donn dat och för de Wikki_Köbeßße esu maache wi_fö_jeede Anndere',
+'revdelete-log' => 'Bemärrkung fö_t LogBooch:',
+'revdelete-submit' => 'Op di aanjekrüzde Väsjohn aanvënnde',
+'revdelete-logentry' => 'Zojang zo de Väsjohn foänndot för [[$1]]',
+'difference' => '(Ungerscheed zwesche de Väsjohne)',
+'loadingrev' => 'ben en Väsjohn för_t Fojliishe am laade',
+'lineno' => 'Rëij $1:',
+'editcurrent' => 'Donn_de_nöüßte Vasjohn fun dämm Atikkel änndere',
+'selectnewerversionfordiff'=> 'Důnn en nöüre Väsjohn för_t Fojliishe ußsööke',
+'selectolderversionfordiff'=> 'Důnn en äälere Väsjohn för_t Fojliishe ußsööke',
+'compareselectedversions'=> 'Důnn de makėete Väsjohne fojlishe',
+'searchresults' => 'Wat bëijm Sööke errußkohm',
+'searchresulttext' => 'Luer op de Sigk övver_et [[{{ns:project}}:Sööke en de {{SITENAME}}|Sööke en de
+
+{{SITENAME}}]] noh, wänn de mieh drövver weßße wellß, wi_mer en de {{SITENAME}} jät fingk.',
+'searchsubtitle' => 'För Ding Frooch noh „[[:$1]]“.',
+'searchsubtitleinvalid' => 'För Ding Frooch noh „$1“.',
+'badquery' => 'Fokierte Aanfroch fö_t Sööke',
+'badquerytext' => 'För Ding Frooch förr_et Sööke hät_dat nix jebraat.
+Zem Bëijshpill künnd_et sinn, dat_De noh ennem jannz koote Woot jefrooch häß — kööter wi fier Boochshtaven künne_mer
+
+ëijnfach nit. Odder Do häß_Desch fotipp, un noh „Kölle am am Rhing“ sööke lohße. Unn_et künnt sinn, dat mer Ding
+
+Schriifwiiß nit en de Daate_Bangk hann. Wannt jëijt, dann donn do_för jlish_en Ömlëijdung enjävve!',
+'matchtotals' => '„$1“ küdd_en <strong>$2</strong> Övverschreffte un em Täx fun <strong>$3</strong>
+
+Atikkelle für.',
+'noexactmatch' => 'Mer han këijn Sigk met jenou däm Name „<strong>$1</strong>“ jefonge. Do kannß_ße
+
+[[:$1|aanlääje]], wänn_De wellß.',
+'titlematches' => 'Paßßende Övverschreffte',
+'notitlematches' => 'Këij_paßßende Övverschreffte',
+'textmatches' => 'Sigge met_däm Täx',
+'notextmatches' => 'Këij Sigk met_däm Täx',
+'prevn' => 'de $1 do_für zëije',
+'nextn' => 'de nääkßte $1 zëije',
+'viewprevnext' => 'Bläddere: ($1) ($2) ($3).',
+'showingresults' => 'Unge weede beß <strong>$1</strong> fun de jefungene Enndrääsh jezëijsch,
+fun de Nommer <strong>$2</strong> aff.',
+'showingresultsnum' => 'Unge sinn <strong>$3</strong> fun de jefungene Enndrääsh opjelėßß,
+fun de Nommer <strong>$2</strong> aff.',
+'nonefound' => '<strong>Opjepaßß:</strong> Wänn bëijm Söhke nix eruß kütt, do kann dat draan lijje, dat
+
+mer esu jannz jewöönlijje Wööt, wi „hätt“, „allso“, „wääde“, un „senn“, uew. jaa__nid_esu en_de Daate_Bank dren_hann,
+
+dat_se jefonge wääde künnte.',
+'powersearch' => 'Söhke',
+'powersearchtext' => 'Söök in de Appachtemengß:<br />$1<br />$2 Zëijsh Ömëijdunge<br />Söhk noh $3 $9',
+'searchdisabled' => 'Dat Sööke he op de {{SITENAME}} eß em Mommänndt affjeschalldt.
+Dat weed fun de ßööver ald_enß jemaat, domet_te Laßß op inne nit_ze jrůůß_weedt,
+un winnishßtenß de Nommaalle Sigge_Oproofe flöck_jenooch jonn.
+
+Ühr künnd_esu lang övver en Söök_Maschiin fun ußßerhallf ėmmer noch
+Sigge op de {{SITENAME}} finge.
+Ed_eß nit_jesaat,
+dat denne ier Daate top_aktowäll sinn,
+ävve_ed_eß_bäßßo wi jaa_nix.',
+'blanknamespace' => '(Atikkelle)',
+'preferences' => 'ming Ëijnshtellunge',
+'prefsnologin' => 'Nėd_Ėnnjelogg',
+'prefsnologintext' => 'Do mööds_alld [[Special:Userlogin|ennjelogg]] sinn, öm Ding Ėnnshtellunge ze ännderre.',
+'prefsreset' => 'Dė Ëijnshtellunge woodte jäz op Shtanndadt zerrögk_jesaz.',
+'qbsettings' => '„Flöcke Lėngkß“',
+'changepassword' => 'Paßßwoodt Änndere',
+'skin' => 'Et Uß_Sinn',
+'math' => 'Mattematisch Forrmelle',
+'dateformat' => 'Em Dattum sing Fommaat',
+'datedefault' => 'Ejaal — këijn Füürliėbe',
+'datetime' => 'Dattum un Uur_Zigge',
+'math_failure' => 'Fääler fum Paaser',
+'math_unknown_error' => 'Fääler, dä_mmer nit känne',
+'math_unknown_function' => 'en Funkzjohn, di_mmer nit känne',
+'math_lexing_error' => 'Fääler bëijm Lëxing',
+'math_syntax_error' => 'Fääler en de Sünntax',
+'math_image_error' => 'De Ömwandlung noh PNG eß donëvve jejange. Donn enß noh de reshtijje Ėnnshtallazjoohn
+
+luere bëij <i>latex</i>, <i>dvips</i>, <i>gs</i>, un <i>convert</i>. Odder saar_et ennem ßööver_Admin, odder_ennem
+
+Wikki_Köbes.',
+'math_bad_tmpdir' => 'Dat Zwesche_Fozëijshniß fö de mattematėshe Forrmelle lööt sėsh nit aanlääje oddo nix
+
+erinn_schriive, Dat eß Dißß. Saar_et ennem Wikki_Köbes odder ennem
+
+ßööver_Minsch.',
+'math_bad_output' => 'Dat Fozëijshniß fö de mattematėshe Forrmelle lööt sėsh nit aanlääje oddo nix
+
+erinn_schriive, Dat eß Dißß. Saar_et ennem Wikki_Köbes odder ennem
+
+ßööver_Minsch.',
+'math_notexvc' => 'Dat Projamm <code>texvc</code> ham_mer nit jefonge. Saar_et ennem
+
+Wikki_Köbes, ennem ßööver_Minsch, odder luer_enß en de
+
+<code>math/README</code>.',
+'prefs-personal' => 'De Ëijnshtellonge',
+'prefs-rc' => 'Nöüßte Ännderunge',
+'prefs-watchlist' => 'De Oppaßß_Lėßß',
+'prefs-watchlist-days' => 'Aanzal Dare fö_en minger Oppaßß_Lėßß aan_ze_zëije:',
+'prefs-watchlist-edits' => 'Aanzal Änderonge fö_en minger forjrüüßorte Oppaßß_Lėßß aan_ze_zëije:',
+'prefs-misc' => 'Sönß',
+'saveprefs' => 'Faßßhallde',
+'resetprefs' => 'Zerrögk_Säzze',
+'oldpassword' => 'Et aahle Paßßwordt:',
+'newpassword' => 'Nöü Paßßwoodt:',
+'retypenew' => 'Norr_enß dat neue Paßßwoodt:',
+'textboxsize' => 'Bëijm Beärrbëijde',
+'rows' => 'Rëije:',
+'columns' => 'Shpallde:',
+'searchresultshead' => 'Bëijm Sööke',
+'resultsperpage' => 'Zëijsh Träfo pro Sigk:',
+'contextlines' => 'Rëije fö_jeede Träfor:',
+'contextchars' => 'Zëijshe uß de Ömjävung, pro Rëij:',
+'stubthreshold' => 'Aanzal Zëijshe fun_woh avv_en_Sigk alls_enne Atikkel zälldt:',
+'recentchangescount' => 'Enndrääsh en de Lėßß_met_de „Nöüßte_Ännderonge“:',
+'savedprefs' => 'Ding Ėnnshtellunge sinn jäz jeseshot.',
+'timezonelegend' => 'Zigk_Zoone Ungerscheed',
+'timezonetext' => 'Dat sin_de Shtunnde un Menutte zwesche de Zigk op de Uure bëij Dir am Oot un däm ßööver, dä med UTC leuf.',
+'localtime' => 'De Zigg_op Dingem Kompjutor:',
+'timezoneoffset' => 'Dä Ungerscheed ¹ eß:',
+'servertime' => 'De Ur_Zigg_öm ßööver eß jäz:',
+'guesstimezone' => 'Fingk ed_eruß övver dä Brauser',
+'allowemail' => 'e-mail fun anndere Medmaacher zo_loohße',
+'defaultns' => 'Donn shtandad_mäßėsh en hee dä Appachtemengß sööke:',
+'default' => 'Shtanndat',
+'files' => 'Dateije',
+'userrights-lookup-user'=> 'Medmaacher Jroppe fowallde',
+'userrights-user-editname'=> 'Medmaacher_Name: <!-- -->',
+'editusergroup' => 'Däm Medmaacher sing Jroppe Rääshte beärrbëijde',
+'userrights-editusergroup'=> 'Medmaacher_Jroppe aanpaßße',
+'saveusergroups' => 'Medmaacher_Jroppe affshpëijshere',
+'userrights-groupsmember'=> 'Eß en_de Medmaacher_Jroppe:<br />',
+'userrights-groupsavailable'=> 'Eß nit en de Medmaacher_Jroppe:<br />',
+'userrights-groupshelp' => 'Söök de Jroppe uß, wo dä Medmaacher bëij kumme sull oddo druss_eruß sull. Jroppe, di De
+
+hee nid_ußsöökß, bliive, wi_se_sėnn. Dat Ußsööke kannß_De bëij de miihßte Brausere met \'\'\'Ctrl + Lenkß_Klikke\'\'\' / \'\'\'Strg + Lenkß_Klikke\'\'\' maache.',
+'group' => 'Jropp:',
+'group-bot' => 'Botß',
+'group-sysop' => 'Wikki_Köbeßße',
+'group-bureaucrat' => 'BürroKraade',
+'group-all' => '(all)',
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Wikki_Köbes',
+'group-bureaucrat-member'=> 'Bürrokraat',
+'grouppage-bot' => '{{ns:project}}:Botß',
+'grouppage-sysop' => '{{ns:project}}:Wikki_Köbes',
+'grouppage-bureaucrat' => '{{ns:project}}:Bürrokraat',
+'changes' => 'Ännderonge',
+'recentchanges' => 'Nöüßte_Ännderonge',
+'recentchangestext' => 'Op dä Sigk hee sinn de nöüßte Änderonge aam Wikki opjelėßß.',
+'rcnote' => 'Hee sinn de läzde <strong>$1</strong> Änderonge uß de läzde <strong>$2</strong> Daare fum
+
+$3 aan.',
+'rcnotefrom' => 'Hee sinn beß_op <strong>$1</strong> Änderonge zigk <strong>$2</strong> opjelėßß.',
+'rclistfrom' => 'Zëijsh de nöüje Ännderonge fum $1 aff',
+'rcshowhideminor' => '$1 klëijn minni_Ännderonge',
+'rcshowhidebots' => '$1 de Botß ier Ännderonge',
+'rcshowhideliu' => '$1 de aanjemälldte Medmaacher ier Ännderonge',
+'rcshowhideanons' => '$1 de namenlose Medmaacher ier Ännderonge',
+'rcshowhidepatr' => '$1 de aanjeluerte Ännderonge',
+'rcshowhidemine' => '$1 ming ëijen Ännderonge',
+'rclinks' => 'Zëijsh de läzde | $1 | Ännderonge uß de läzde | $2 | Daare, un donn | $3 |',
+'diff' => 'Ungerscheed',
+'hist' => 'Väsjohne',
+'hide' => 'Ußblände:',
+'show' => 'Zëije:',
+'minoreditletter' => 'M',
+'newpageletter' => 'N',
+'boteditletter' => 'B',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[$1 Oppaßßer]',
+'rc_categories' => 'Nur di Saachjroppe (med „|“ dozwesche):',
+'rc_categories_any' => 'All, wat mer hann',
+'upload' => 'Daate huh_laade',
+'uploadbtn' => 'Huh_Laade!',
+'reupload' => 'Norr_enß huh_laade',
+'reuploaddesc' => 'Zerrögk noh de Sigk zem Huh_Laade.',
+'uploadnologin' => 'Nėd_Ėnnjelogg',
+'uploadnologintext' => 'Do möötds_alld [[Special:Userlogin|ennjelogg]] sinn, öm Daate huh_ze_lade.',
+'upload_directory_read_only'=> '<b>Doof:</b> En dat Fozëijshnißß <code>$1</code> fö_Dattëije drėn huh_ze_laade, do
+
+kann dat Web_ßööver_Projramm nix errinnschriive.',
+'uploaderror' => 'Fääler bem Huh_Laade',
+'uploadtext' => '<div dir="ltr">Met dämm Formular unge kannß_de Bellder oddo annder Daate huh_laade. Do
+
+kannß dann Ding Werrək diräg enbinge, en dä Aate:<ul style="list-style:none outside none;
+
+list-style-position:outside; list-style-image:none; list-style-type:none"><li style="list-style:none outside none;
+
+list-style-position:outside; list-style-image:none;
+
+list-style-type:none"><code>\'\'\'[[{{NS:Image}}:\'\'\'\'\'Belldshe\'\'\'\'\'.jpg]]\'\'\'</code></li><li
+
+style="list-style:none outside none; list-style-position:outside; list-style-image:none;
+
+list-style-type:none"><code>\'\'\'[[{{NS:Image}}:\'\'\'\'\'Esu_süühd_dat_uß\'\'\'\'\'.png | \'\'\'\'\'enne Täx, dä di
+
+Brausere zëije, di këij Bellder künne\'\'\'\'\']]\'\'\'</code></li><li style="list-style:none outside none;
+
+list-style-position:outside; list-style-image:none;
+
+list-style-type:none"><code>\'\'\'[[{{NS:Media}}:\'\'\'\'\'Su_hüert_sesh_dat_aan\'\'\'\'\'.ogg]]\'\'\'</code></li></u
+
+l>
+Ußßfüerlish met alle Möshlishkëijte finkß_de dat bëij de Hülp.
+
+Wänn De jäz entschloßße beß, dat De et hee huh_laade wellß:
+* Aanluere, wat mer he en de {{SITENAME}} ald hann, kannß De en unß [[Special:Imagelist|Bellder_Leßß]].
+* Wenn De jät söhke wellß, eetß enß noh_luere wellß, wat alld huhjelaade, oddo fellëijsh widdo fottjeschmeßße wood,
+
+dat shtëijd_em [[Special:Log/upload|Logbooch fum Huh_laade]].
+
+Esu, un jäz loß jonn:</div>
+== <span dir="ltr">Date en de {{SITENAME}} lade</span> ==',
+'uploadlog' => 'LogBooch fum Dattëije_Huh_Laade',
+'uploadlogpage' => 'Logbooch med_de huh_jelaadene Datëije',
+'uploadlogpagetext' => 'Hee sinn de nöüßte huh_jelaadenne Datëije opjelėßß un wä dat jedonn hät.',
+'filename' => 'Name fun dä Dattëij',
+'filedesc' => 'Beschriivungß_Täxx un Zosammefaßßung',
+'fileuploadsummary' => 'Beschriivungß_Täxx un Zosammefaßßung:',
+'filestatus' => 'Urhävver_Räächß_Shtattuß',
+'filesource' => 'Qwäll',
+'copyrightpage' => '{{ns:project}}:Lizänz',
+'copyrightpagename' => 'Lizänz',
+'uploadedfiles' => 'Huh_jeladenne Dattëije',
+'ignorewarning' => 'Warnung övverjonn, un Dattëij trozdämm affshpëijsherre.',
+'ignorewarnings' => 'Alle Warnunge övverjonn',
+'minlength' => 'De Name fun_de Dattëije künne_nit kööto_wi_drëij Boochshtawe sinn.',
+'illegalfilename' => 'Schaadt:
+<br />
+En däm Name fun dä Dattëij sin Zëijshe enthallde,
+di mer en Tittelle fun Sigge nit bruche kann.
+<br />
+Söök Der shtatt „$1“ jäd_andoß uß,
+un dann mußß_de dat Dinge norr_enß huh_laade.',
+'badfilename' => 'Dė Dattëij eß en „$1“ ömjedeuf.',
+'badfiletype' => '„.$1“ iß këijn fun de Fomatte fun Bėllder, wo mer jäz jät met aanfange künnte.',
+'largefile' => 'Di Datëij eß <strong>$2</strong> Byte jruß. Datëije Huh_ze_Laade, di jrüüßer wi
+
+<strong>$1</strong> Byte sind, do_för dům_mer affroode.',
+'largefileserver' => 'Di Datëij eß ze jruuß. Jrüüßo_wi_däm ßööver sing Ennshtëllung ällaup.',
+'emptyfile' => 'Wat De hee jäz huh_jelaade häßß, hatt kenn Daate drenn jehatt. Künnt sinn, dat_De Dėsh
+
+fordonn häßß, un dä Naame woh falləsch jeschrėvve. Luer_enß ov_De werreklesch <strong>di</strong> Dattëij hee
+
+huhlaade wellß.',
+'fileexists' => 'Et jidd_ald en Datëij med_dämm Name. Wänn_De op „<span style="padding:2px;
+
+background-color:#ddd; color:black">Dattëij affshpëijshere</span>“ klix, weed se äsäzz. Bess_esu joot, un_luer_Der $1
+
+aan, wänn_De nit 100% sescher beß.',
+'fileexists-forbidden' => 'Et jidd_ald en Datëij med_dämm Name. Jangk zerrögg_un laad_se unger_ennem anndere Naame
+
+huh. [[{{ns:Image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Et jidd_ald en Datëij med_dämm Name em jemëijnsame Shpëijsho. Jangk zerrögg_un
+
+laad_se unger_ennem anndere Naame huh. [[{{ns:Image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'Et Huh_laade hät jeflupp',
+'fileuploaded' => 'Di Dattëij „$1“ eß jäz huh_jelaade.
+Jangk op di Sigk met dä Dattëij ier Beshriivung un doh draach alles enn wat De övver se wëijß.
+Wo se her kohm, Wää se jemaat hädd_un wann, un_vat_De_Dėsch sönß noch draan entsėnne kannß.
+Do küßß_De hen övver dä Lėngk: $2
+
+Wänn dadd_e_Belldt wooh, do kannß_De met:
+:<code><nowiki>[[{{NS:Image}}:$1|thumb|Täxx för onger dat Belld ze donn]]</code>
+e Breefmarreke_Belldsche op dä Sigk moole lohße.',
+'uploadwarning' => 'Warrnung bëijm Huh_laade',
+'savefile' => 'Dattëij affshpëijshere',
+'uploadedimage' => 'hät huhjelade: „[[$1]]“',
+'uploaddisabled' => 'Huh_Lade jeshpächt',
+'uploaddisabledtext' => 'Et Huh_Lade eß jeshpächt he en dämm Wikki.',
+'uploadscripted' => 'En dä Datëij eß HTML dren oddo Kood fun_ennem
+Skripp, dä künnt Dinge Brauser en do fallsche Hallß krijje un ußföere.',
+'uploadcorrupt' => 'Schaad.
+<br />
+Di Dattëij iß kapott, hädd_en fokiehjəte File_Name Ëxtensjen, odder ööhnds_enne anndere Drißß eß paßßėet.
+<br />
+<br />
+Luer_enß noh_dä Dattëij, un dann moßß_de_t norr_enß fosöhke.',
+'uploadvirus' => 'Esu enne Drißß:
+<br />
+En dä Dattëij shtish e Kompjuto_Viruß!
+<br />
+De Ëijnzelhäijte: $1',
+'sourcefilename' => 'Dattëij zem huh_laade',
+'destfilename' => 'Unger dämm Dattëijname affshpëijshere',
+'filewasdeleted' => 'Unger dämm Name wood ald_enß en Datëij huh_jelaade. Di eß enzwesche ääver widdo
+fottjeschmeßße woode. Luer leever eeds_enß en_et $1 iih dat De se dann affshpëijsherre dëijß.',
+'license' => 'Lizzänz',
+'nolicense' => 'Nix üßßjesöök',
+'upload_source_url' => ' (reshtijje öffentlijje URL)',
+'imagelist' => 'Bellder, Tööhn, uew. (all)',
+'imagelisttext' => 'Hee küdd_en Lėßß fun <strong>$1</strong> Dattëij{{PLURAL:$1||e}}, zotteet $2.',
+'imagelistforuser' => 'Hee süühß De nuur de Bėllder, di dä Medmaacher „$1“ huh_jelaade hätt.',
+'getimagelist' => 'ben de Lėßß met de Datëij_Name am laade',
+'ilsubmit' => 'Söök',
+'showlast' => 'Zëijsh de läzde | $1 | Dattëije, zotteed $2.',
+'byname' => 'noh_m Name',
+'bydate' => 'noh_m Dattum',
+'bysize' => 'noh de Dattëij_Jrüüße',
+'imgdelete' => 'fott!',
+'imgdesc' => 'täxx',
+'imgfile' => 'Dattëij',
+'imglegend' => 'Legende: (täxx) = ännder odder zëijsh de Beschrivungß_Täxx för di Dattëij.',
+'imghistory' => 'Väsjohne',
+'revertimg' => 'retuur',
+'deleteimg' => 'Fottschmiiße',
+'deleteimgcompletely' => 'Alle Väsjohne fun dä Dattëij fottschmiiße',
+'imghistlegend' => 'Legende:
+(nöü) = dat iß de nöüßte Väsjohn —
+(fott!) = schmiiß di aale Väsjohn fott! —
+(retuur) = jangk zeröck op di aale Väsjohn —
+Op_et Dattum klikke = zëijsh di Väsjohn fun dohmols aan.',
+'imagelinks' => 'Lėngkß',
+'linkstoimage' => 'He kumme de Sigge, di op di Dattëij lingke donn:',
+'nolinkstoimage' => 'Nix lėngk op hee_di Dattëij.',
+'sharedupload' => 'Di Dattëij eß esu parat jelaat, dat se en divärse, ungesheedlijje Projäkkte jebruch wääde
+
+kann.',
+'shareduploadwiki' => 'Mieh Ėnnfommazjohne fingkß_De hee: $1.',
+'shareduploadwiki-linktext'=> 'Hee eß en Dattëij beschrėvve',
+'noimage' => 'Mer han këij_Dattëij med dämm Naame, kannz_E ävver $1.',
+'noimage-linktext' => 'Kannz_E huh_laade!',
+'uploadnewversion-linktext'=> 'Donn en nöüje Väsjohn fun dä Dattëij huh_laade',
+'imagelist_date' => 'Dattum',
+'imagelist_name' => 'Name',
+'imagelist_user' => 'Medmaacher',
+'imagelist_size' => 'Byte',
+'imagelist_description' => 'Description',
+'imagelist_search_for' => 'Search for image name:',
+'mimesearch' => 'Bellder, Tööhn, uew. övver ier MIME_Tüppe Sööhke',
+'mimetype' => 'MIME-Tüp:',
+'download' => 'Erunge_Laade',
+'unwatchedpages' => 'Sigge, wo Këijne dob_oppaßß',
+'listredirects' => 'Ömlëijdunge',
+'unusedtemplates' => 'Schabloone oddo Boushtëijn, di nit jebruch wääde',
+'unusedtemplatestext' => 'Hee sinn all di Schabloone opjelëßß, di em Appachtemeng „Schabbloon“ sinn, di nidd_en
+
+annder Sigge ennjeföösh wääde. Iih De jät dofun fottschmiiß, dängk draan, se künnte och obb_en annder Aat jebruch
+
+wääde, un luer Der di annder Lėngkß aan!',
+'unusedtemplateswlh' => 'annder Lėngkß',
+'randomredirect' => 'Zofällije Ömlëijdung',
+'statistics' => 'Shtatißtikke',
+'sitestats' => 'Shtatißtikke övver de {{SITENAME}}',
+'userstats' => 'Shtatißtikke övver de Medmaacher',
+'sitestatstext' => '* Et jidd_en_ättwa <strong>$2</strong> rėshtijje Atikkelle hee.
+
+* En de Daatebangk sinn_er ävvo <strong>$1</strong> Sigge, aan dänne beß jäz_zosamme <strong>$4</strong> mool jät
+
+jeänndort woode eß. Em_Shnett woote allso <strong>$5</strong> Ännderonge pro Sigk jemaat. <br /><small> (Do sinn
+
+ävvo de Klaaf_Sigge medjezalldt, de Sigge övver de {{SITENAME}}, un ußßodämm jeede klëijne Fuzz_un_Shtümpshenß_Sigk,
+
+Ömlëijdunge, Shabloone, Saachjroppe, un anndor Zeush, wat mer nit jood alls_enne Atikkel zälle kann)</small>
+
+* <strong>$8</strong> Bellder, Töön, un_esu_n äänlijje Daate woodte ald huhjelade.
+
+* Et {{PLURAL:$7|eß noch <strong>ëijn</strong> Oppjaf|sin_noch <strong>$7</strong> Oppjave|eß <strong>këijn</strong>
+
+Oppjaf mieh}} en_de_Lėßß.
+
+* <strong>$3</strong> mool wood_en Sigk hee affjeroofe, dat sinn <strong>$6</strong> Affroofe pro Sigk.',
+'userstatstext' => '* <strong>$1</strong> Medmaacher han sėsh beß jëz aanjemelldt.
+* <strong>$2</strong> do_fun sinn $5, dat sin_ner <strong>$4%</strong>.',
+'statistics-mostpopular'=> 'De miihz beluerte Sigge',
+'disambiguations' => '„(Watt ėßß datt?)“-Sigge',
+'disambiguationspage' => 'Template:Disambig',
+'disambiguationstext' => 'De Sigge,
+di hee_noh oppjelėßß wääde,hann Lėngkß op „(Watt ėßß datt?)“-Sigge.
+
+Allß „(Watt ėßß datt?)“-Sigge wääde all_di jezälldt, di_di_Schabloon <strong>„$1“</strong> bruche.
+
+Fill_fun_dänne sůllte_wůll bëßßer obb_en Sigk_lėngke,
+wo tiräg_de rishtijje Ėnhallde drop shtonn.
+Ävver nit unnbedėngk jeede, et küdd_op dä Lėngk drob_aan.
+
+Lėngkß uß annder Appachtemengß wääde he nit jezëijsh.',
+'doubleredirects' => 'Ömlëijdunge op Ömlëijdunge (Dubbel Ömlëijdunge sin fokiert)',
+'doubleredirectstext' => 'Dubbel Ömlëijdunge sin ėmmer fokiert, wëijl dem Wikki sing ßoffwäer de eezte Ömlëijdung
+
+follesh, dė zvëijte Ömlëijdung ävver dann aanzëije dëijt — un dat well mer jo nommall nit hann.
+
+Hee fingks De en jeede Rëij enne Lingg_op de iertßte un de zvëijte Ömlëijdung, don_noh enne Lėngg_op_di Sigk, wo de
+
+zvëijte Ömlëijdung hėn jëijdt. Fö_jewöönlish eß dat dann och de rishtijje Sigk, wo de iertßte Ömlëijdunge ald hėn
+
+jonn sůllt.
+
+Met däm „(Änndere)“-Lingk kannz_E Di eetßte Sigk tirëgg_aanpakke. Tipp: Merrek_Der_dat Lämma — de Övverschreff —
+
+fun_dä drette Sigk do_föer.',
+'brokenredirects' => 'Ömlëijdunge di inn_et Leere jonn (kappott oddo_op Fürat aanjelaat)',
+'brokenredirectstext' => 'Di Ömlëijdunge hee jonn op Sigge, di mer
+[[#ast|<small>noch\'\'\'<sup>*</sup>?\'\'\'</small>]]
+jaa nit hann.
+
+<small id="ast">\'\'\'<sup>*</sup>?\'\'\' Di künnte op Füeraat aanjelaat sinn.
+Di allso joot ußsinn,
+un woh_di Sigge woh_se drop zëije,
+spääder vall noch_kumme weede,
+di sullt mer behallde.</small>',
+'nbytes' => '$1 Byte',
+'ncategories' => '{{PLURAL:$1| eijn Saachjropp | $1 Saachjroppe }}',
+'nlinks' => '{{PLURAL:$1|ëijne Lėngk|$1 Lėngkß}}',
+'nmembers' => 'met {{PLURAL:$1|ëijn Sigk|$1 Sigge}} dren',
+'nrevisions' => '{{PLURAL:$1|ëijn Ännderong|$1 Ännderonge}}',
+'nviews' => '{{PLURAL:$1|1 Affroof|$1 Affroofe}}',
+'lonelypages' => 'Sigge wo nix drop lingk',
+'uncategorizedpages' => 'Sigge di in këij Saachjropp senn',
+'uncategorizedcategories'=> 'Saachjroppe di sellvs_in këijn Saachjroppe senn',
+'uncategorizedimages' => 'Bellder, Tööhn, uew. di en këijn Saachjroppe dren sinn',
+'unusedcategories' => 'Saachjroppe med nix dren',
+'unusedimages' => 'Bellder, Tööhn, uew. di nit en Sigge dren_shtäshe',
+'popularpages' => 'Sigge, di öff affjeroofe wääde',
+'wantedcategories' => 'Saachjroppe di_mer non_nit hann, di noch_jebruch wääde',
+'wantedpages' => 'Sigge di_mer non_nit hann, di noch_jebruch wääde',
+'mostlinked' => 'Sigge med_e miehßte Lingkß drop',
+'mostlinkedcategories' => 'Saachjroppe med_e miehßte Lingkß drop',
+'mostcategories' => 'Atikkelle met_e miehßte Saachjroppe',
+'mostimages' => 'Bellder, Tööhn, uew. met_e miehßte Lingkß drop',
+'mostrevisions' => 'Atikkelle met_e miehßte Änderonge',
+'allpages' => 'All Sigge',
+'prefixindex' => 'All Sigge, di dänne ier Name medd_ennem beshtemmpte Woot oddo Täx aanfange dëijdt',
+'randompage' => 'Zofällije Sigk',
+'shortpages' => 'Sigge zoteet fun koot noh lang',
+'longpages' => 'Sigge zotėet fun Lang noh Koot',
+'deadendpages' => 'Sigge oohne Lėngkß dren',
+'listusers' => 'Medmaacher',
+'specialpages' => 'Söndersigge',
+'spheading' => 'Södersigge för all Medmaacher',
+'restrictedpheading' => 'Söndersigge med beshrängkte Zojangsrääshte',
+'recentchangeslinked' => 'Folingg_Ännderonge',
+'rclsub' => '(aan Sigge, noh dänne de Sigk: „$1“ hen lėngk)',
+'newpages' => 'Nöü Sigge',
+'newpages-username' => 'Medmaacher_Naam:',
+'ancientpages' => 'Sigge zoteet fun Ahl noh Nöü',
+'intl' => 'Ingerwikki _Lėngkß',
+'move' => 'Ömnänne',
+'movethispage' => 'Di Sigk Ömnänne',
+'unusedimagestext' => '<p><strong>Opjepaßß:</strong> Annder Websigge künnte emmer noch di Dattëije hee tirrägk
+
+për URL aanshpräshe. Su künnd_et sinn, dadd_en
+
+Dattëij hee en de Lėßß shtëijdt, ävver doch jebruch weedt. Ußßerdämm, vinnishßtens bëij nöüe Dattëije, künnd sinn,
+
+dat_se non_nit enn_ennem Attikkel enjebout sinn, wëijl_noch Ëijne draan am brasselle eß.</p>',
+'unusedcategoriestext' => 'Di Saachjroppe hee senn ennjereshdt, ävver jäds_em Mommänndt, eß këijne Atikkel un
+
+këijnolëij Saachjropp dren ze fėnge.',
+'booksources' => 'Böösher',
+'categoriespagetext' => 'Dat sin_de Saachjroppe fun däm Wikki hee.',
+'data' => 'Daate',
+'userrights' => 'Medmaacher ier Rääshte fowallde',
+'groups' => 'Jroppe fun Medmaacher',
+'booksourcetext' => 'Hee noh küdd_en Lėßß met Websigge,
+wo mir fun de {{SITENAME}} nix wigger med ze donn hänn,
+wo mer jät övver Böösher erfaare
+un zom Dëijl och Böösher koufe kann.
+Doför moßß De Desh mannshmool allodengs eetß ennß aanmällde,
+wat Koßte und anddere Jefaare met sesh brenge künndt.
+Wo_t jëijdt, jonn di
+Lengkß hee tirrägg_op dat Booch,
+wadd_Er am Sööke sidt.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 … $2',
+'version' => 'Väsjohn fun de Wikki_ßoffwäer zëije',
+'log' => 'Logböösher ier Oppzëijshnonge (all)',
+'alllogstext' => 'Dat hee es en jesammdte Lėßß uß all_dä LogBöösher för_et [[Special:Log/block|Medmaacher
+
+oddo IP_Adräßß_Shpärre]], et [[Special:Log/protect|Sigge_Shpärre]], [[Special:Log/delete|et Sigge_Fottschmiiße]], et
+
+[[Special:Log/move|Sigge_Ömnänne]], et [[Special:Log/renameuser|Medmaacher_Ömnänne]], dor
+
+[[Special:Log/newusers|nöüje Medmaacher ier Aanmälldunge]], et [[Special:Log/upload|Daate Huhlaade]],
+
+[[Special:Log/rights|de Bürro_Kraade iere Kroohm]], unn_de [[Special:Log/makebot|Botß ier Shtattuß_Ännderonge]].
+
+Dä_LogBöösher iere Enhhalldt kam_mer all noh_de Aat, de Medmaacher, oddo de Sigge ier Naame, unn_esu, ëijnzel zottėet
+
+aanluere.',
+'logempty' => '<i>Mer han këijn paßßende Enndrääsh en däm Logbooch.</i>',
+# Special:Allpages
+'nextpage' => 'De näkßte Sigk: „$1“',
+'allpagesfrom' => 'Sigge aanzëije aff dämm Naame:',
+'allarticles' => 'All Atikkelle',
+'allinnamespace' => 'All Sigge (Em Appachtemeng „$1“)',
+'allnotinnamespace' => 'All Sigge (ußßer_em Appachtemeng "$1")',
+'allpagesprev' => 'Zerrögk',
+'allpagesnext' => 'Nääkß',
+'allpagessubmit' => 'Loß Jonn!',
+'allpagesprefix' => 'Sigge zëije, wo dä Naame aanfängk med:',
+'allpagesbadtitle' => 'Dä Sigge_Name eß nit ze bruche. Dä hädd_e Köözel fö_n Shprooch oddo_fö_ne
+
+Ingerwikki_Lėngk am Aanfang, odder_et küdd_e Zëijshe dren für, wat en Sigge_Name nit jëijt, fellëijsh och mieh wi
+
+ëijnß fun all_dämm op ëijmohl.',
+# Special:Listusers
+'listusersfrom' => 'Zëijsh de Medmaacher fun:',
+# e-mail this user
+'mailnologin' => 'Do beß nit ennjelogk.',
+'mailnologintext' => 'Do mööds_alld aanjemäldt un [[Special:Userlogin|ennjelogg]] sinn, un en joode e-mail
+
+Adräßß en Dinge [[Special:Preferences|ming Ëijnshtellunge]] shtonn hann, öm_men e-mail aan anndere Medmaacher ze
+
+schekke.',
+'emailuser' => 'E-mail aan dä Medmaacher',
+'emailpage' => 'E-mail aan enne Medmaacher',
+'emailpagetext' => 'Wänn dä Medmaacher en E-mail Adräßß aanjejovve hätt, en singe Ëijnshtellunge, un di
+
+dëijd_et och, dann kannß_De me_däm Fomulaa hee unge, en ëijnzellne E-mail aan dää Medmaacher schekke. Ding E-mail
+
+Adräßß, di De en Dinge ëijene Ëijnshtellunge aanjejovve häß, di weed allß de Affsändo Adräßß en di E-mail
+
+ennjedraare. Domet kann, wä di E-mail kritt, drop antwoote, un di Antwoot jëij_tirägg_aan Dish.
+
+Alleßß klooh?',
+'usermailererror' => 'Dat e-mail-Objägk
+
+joov_ennen_Fääler uß:',
+'defemailsubject' => 'E-mail övver de {{SITENAME}}.',
+'noemailtitle' => 'Këijn e-mail Addräßß',
+'noemailtext' => 'Dä Medmaacher hät këijn e-mail Addräßß ėnnjedraare, oddo hä well këijn e-mail krijje.',
+'emailfrom' => 'Fun',
+'emailto' => 'Aan',
+'emailsubject' => 'Övver',
+'emailmessage' => 'Dä Täxx',
+'emailsend' => 'Affschekke',
+'emailsent' => 'E-mail eß ungerwäähß',
+'emailsenttext' => 'Ding e-mail eß jäz loßßjeshekk woode.',
+'watchlist' => 'ming Op_paßß_Lėßß',
+'watchlistfor' => '(för <strong>$1</strong>)',
+'nowatchlist' => 'En Dinger Oppaßß_Lėßß eß nix dren.',
+'watchlistanontext' => 'Do moß $1, domet de en Ding Oppaßß_Lėßß errinnluere kannß, odder jät draan änndere.',
+'watchlistcount' => '<strong>En Dinger Oppaßß_Lėßß {{PLURAL:$1|eß ëijne Ėnndrach|sinn_er $1 Ėnndrääsh sinn|eß
+
+këijne Ėnndrach}} dren, de Klaaf_Sigge medjezalldt.</strong>',
+'clearwatchlist' => 'Dė Oppaßß_Lėßß fottschmiiße',
+'watchlistcleartext' => 'Beß_De sesher, dat De Ding jannze Oppaßß_Lėßß fottschmiiße wellß?',
+'watchlistclearbutton' => 'De jannze Oppaßß_Lėßß fott_schmiiße',
+'watchlistcleardone' => 'Ding Oppaßß_Lėßß wood fottjeschmeßße. {{PLURAL:$1|Dä Ėnndrach eß|De <strong>$1</strong>
+
+Ėnndrääsh sinn}} bëijm Döüvel.',
+'watchnologin' => 'Nėd_Ėnnjelogg',
+'watchnologintext' => 'Öm Ding Oppaßß_Lėßß ze änndere, möötß_de alld [[Special:Userlogin|ennjelogg]] sinn.',
+'addedwatch' => 'En dė Oppaßß_Lėßß jedonn',
+'addedwatchtext' => 'Di Sigk „[[$1]]“ eß jäz in Dinger [[Special:Watchlist|Oppaßß_Lėßß]]. Af_jäz, wänn di Sigk
+
+foänndot weed, odder ier Klaaf_Sigk, dann weed dat en de Oppaßß_Lėßß jezëijsh. Dä Enndraach fö_di_Sigk küdd_en
+
+Fättschreff en_de „[[Special:Recentchanges|Nöüßte Ännderonge]]“, domet_De_dä_do och flöck fingx.
+
+Wänn_de_Dä widdo loßß wääde wells uß Dinger Oppaßß_Lėßß, dann klick op „Nimmieh drob_oppaßße“ wann De_di Sigk om
+
+Schirrəm häßß.',
+'removedwatch' => 'Uß de Oppaßß_Lėßß jenůmme',
+'removedwatchtext' => 'Di Sigk „[[$1]]“ eß jäz uß de Oppaßß_Lėßß errußß_jenůmme.',
+'watch' => 'Drob_Oppaßße',
+'watchthispage' => 'Op_di Sigg op_paßße',
+'unwatch' => 'Nim_mieh drobb_Oppaßße',
+'unwatchthispage' => 'Nim_mieh op di Sigk op_paßße',
+'notanarticle' => 'Këijne Atikkel',
+'watchnochange' => 'Këijne Atikkel en Dinge Oppaßß_Lėßß eß en dä aanjezëijshte Zick foänndot woode.',
+'watchdetails' => '* <strong>$1</strong> Sigge sin in dä Oppaßß_Lėßß, oohne de Klaaf_Sigge
+* [[Special:Watchlist/edit|Zëijsh di_jannze Oppaßß_Lėßß aan, kann_ze och änndere]]
+* [[Special:Watchlist/clear|Schmiiß dä jannze Krohm fott, un pass_op nix mieh op]]',
+'wlheader-enotif' => '* Et E-mail Schekke eß ennjeschalldt.',
+'wlheader-showupdated' => '* Wënn_se Ëijne jeänndot hätt, zigk_dämm_De_se_t läzde moohl aanjeluert häß, sen di Sigge
+
+<strong>ëxtra makkeet</strong>.',
+'watchmethod-recent' => 'Ben de läzde Ännderonge jääje de Op_paßß_Lėßß am pröfe',
+'watchmethod-list' => 'Ben de Op_paßß_Lėßß am pröfe, noh de läzde Ännderong',
+'removechecked' => 'Schmiiß di Sigge medt Hökshe uß dä Oppaßß_Less_eruß',
+'watchlistcontains' => 'En dä Oppaßß_Lėßß sinn_er <strong>$1</strong> Sigge.',
+'watcheditlist' => 'Hee en dä Lėßß med_tä Sigge en Dinger Oppaßß_Lėßß, do důnn e Höökshe maache bëij dää
+
+Sigge, wo De nimmieh drobb_oppaßße wellß. Wänn De fäädish beß, donn unge op dä Knopp „<span style="padding:2px;
+
+background-color:#ddd; color:black">Schmiiß di Sigge medt Hökshe uß dä Oppaßß_Less_eruß</span>“ klikke, öm Ding Lėßß
+
+dann wörrəklijj_esu affzeshpëijsherre. Wänn De hee en Sigk fottlööhß, dann dëijhd_dä ier Klaaf_Sigk orr_erußfleeje,
+
+unn ömmjedriiht.<br /><br /><hr />',
+'removingchecked' => 'Ben di ußßjeväälte Sigge uß_dä Oppaßß_Lėßß eruss_am_schmiiße …',
+'couldntremove' => 'Kunnt „$1“ nit fott_schmiiße …',
+'iteminvalidname' => 'Dä Ėnndrach „$1“ hädd_enne kapodde Naame.',
+'wlnote' => 'Hee sinn de läzde <strong>$1</strong> Ännderonge uß de läzde <strong>$2</strong>
+
+Shtund.',
+'wlshowlast' => 'Zëijsh de läzde | $1 | Shtunnde | $2 | Daare | $3 | aan, donn',
+'wlsaved' => 'Dat ess_en jeseshorte Väsjohn fun Dinger Oppaßß_Lėßß.',
+'wlhideshowown' => '$1 ming ëijen Ännderonge',
+'wlhideshowbots' => '$1 de Botß ier Ännderonge',
+'wldone' => 'Fädish.',
+'enotif_mailer' => 'Dä {{SITENAME}} Nohreshte_Forsandt',
+'enotif_reset' => 'Säzz all Änderönge op „Aanjeluert“ un Äleedish.',
+'enotif_newpagetext' => 'Dad_ess_en neu aanjelaate Sigk.',
+'changed' => 'jeänndot',
+'created' => 'neu aanjelaat',
+'enotif_subject' => '{{SITENAME}}: Sigk "$PAGETITLE" fun "$PAGEEDITOR" $CHANGEDORCREATED.',
+'enotif_lastvisited' => 'Luer unger „$1“ — do fingkß de all di Änderonge zigk Dingem läzde Besooch hee.',
+'enotif_body' => 'Leeven $WATCHINGUSERNAME,
+
+en de {{SITENAME}} wood di Sigk „$PAGETITLE“ am $PAGEEDITDATE fun „$PAGEEDITOR“ $CHANGEDORCREATED, unger
+
+$PAGETITLE_URL fingkß de de nöüßte Värsjohn.
+
+$NEWPAGE
+
+Koot Zosammejefaßß, Kwälle: „$PAGESUMMARY“ $PAGEMINOREDIT
+
+Do kannß dä Medmaacher „$PAGEEDITOR“ aanshpräshe:
+* e-mail: $PAGEEDITOR_EMAIL
+* wiki: $PAGEEDITOR_WIKI
+
+Do krißß fun jäds aan keijn e-mail mieh, beß dat Do Der di Sigk aanjeluert häß. Do kannß ävver och all di e-mail
+
+Märreker för di Sigge en Dinger Oppaßß_Leßß op eijmool änndere.
+
+Enne schööne Jrooß fun de {{SITENAME}}.
+
+--
+Do kannß hee Ding Oppaßß_Leßß änndere:
+{{FULLURL:Special:Watchlist/edit}}
+
+Do kannß hee noh Hülp luere:
+{{FULLURL:int:MediaWiki:Helppage}}',
+'deletepage' => 'Schmiiß di Sigk jäz fott',
+'confirm' => 'Dä Schoz fö_di Sigk ännderre',
+'excontent' => 'drop shtunndt: „$1“',
+'excontentauthor' => 'drop shtunndt: „$1“ un dä ëijnzijje Shriiver woh: „$2“',
+'exbeforeblank' => 'drop shtunndt für_her: „$1“',
+'exblank' => 'drop shtunndt nix',
+'confirmdelete' => 'Dat Fottschmiiße moß beshtäätish wääde:',
+'deletesub' => '(Di_Sigk „$1“ sůll fott_jeschmeßße wääde)',
+'historywarning' => '<strong>Opjepaßß:</strong> Di Sigk hätt (mieh wi ëijn) für_her_jejangene',
+'confirmdeletetext' => 'Do beß koot do_füür, en Sigk för iewish fott_ze_schmiiße. Dobëij foschwindt och de jannze
+
+Fojangenhëijdt fun dä Sigk uß de Daate_Bangk, med all ier Ännderonge un Medmaacher_Name, un all dä Oppwandt, dä do
+
+dren shtish. Do moßß hee jäz beshtätijje, dat de foshtëijß, wat dat bedögk, un dat De wëijß, wat Do do määß.
+
+<strong>Donn et nuur, wänn_t met de [[{{ns:project}}:Övver et Sigge Fottschmiiße|Räjelle do_för]] wörrəklėsh zosamme
+
+jëijdt!</strong>',
+'actioncomplete' => 'Äledish',
+'deletedtext' => 'Di Sigk „$1“ eß jäz fottjeschmeßße woode.
+Luer_Der „$2“ aan, do häß_De en Lėßß med de nöüßte fotjeschmeßßenne Sigge.',
+'deletedarticle' => 'hät fottjeschmeßße: „[[$1]]“',
+'dellogpage' => 'Logbooch med_e fottjeschmeßßenne Sigge',
+'dellogpagetext' => 'He sinn de Sigeg oppjelėßß di et nöüß fottjeschmeßße woodte.',
+'deletionlog' => 'Dat Logbooch med_e fottjeschmeßßenne Sigge dren',
+'reverted' => 'Han de äählere Väsjohn fun dä Sigk zoröck_jeholldt.',
+'deletecomment' => 'Aanlaßß för_t Fottschmiiße',
+'imagereverted' => 'Dat Bėlld eß jäz op di Väsohn fun fröjer zerögk_jesaz.',
+'rollback' => 'Ännderonge Zerög_Nämme',
+'rollback_short' => 'Zerög_Nämme',
+'rollbacklink' => 'Zerröck_Nämme',
+'rollbackfailed' => 'Dat Zerög_Nämme jingk sheef',
+'cantrollback' => 'De läzte Änderong zerrögk_ze_nämme eß nit mööshlėsh. Dä läzte Schriiver eß dä ëijnzijje,
+
+dä aan dä Sigk hee jät jedonn hät!',
+'alreadyrolled' => '<strong>Dat wooh nix!</strong>
+
+Mer künne de läzde Ännderonge fun dä Sigk „[[$1]]“ fum Medmaacher „[[User:$2|$2]]“ (→[[User talk:$2|däm_singe
+
+Klaafs]]) nim_mieh zerögk_nämme, dat hädd_enne Anndere enzwesche alld jedonn.
+
+De nöüßte läzde Ännderong eß jäz funn dämm Medmaacher „[[User:$3|$3]]“ (→[[User talk:$3|däm_singe Klaafs]]).',
+'editcomment' => 'Bëij dä Ännderung shtundt: „<i>$1</i>“.',
+'revertpage' => 'Ännderonge fun däm Medmaacher „[[User:$2|$2]]“ (→[[User talk:$2|däm_singe Klaafs]])
+
+fottjeschmeßße, unn_do_föe de läzde Väsjohn fum „[[User:$1|$1]]“ widdo zerrökjeholldt',
+'sessionfailure' => 'Ed_joov_wall_e täshnesh Problehm med_Dingem Login. Dröm ham_mer dad_uß Füürsesh jäz nit
+
+jemaat, domet me_nid_fellëijsh Ding Ännderong dem fokierte Medmaacher ungerjuubelle. Jangk zerrögg_un
+
+fosöög_ed_norr_enß.',
+'protectlogpage' => 'Logbooch fum Sigge_Schöze',
+'protectlogtext' => 'He eß de Lėß fun Sigge, di jeschöz odder frëij jejovve woode sinn.',
+'protectedarticle' => 'hätt jeschöz: „[[$1]]“',
+'unprotectedarticle' => 'Schoz fö „[[$1]]“ opjehovve',
+'protectsub' => '(Sigge_Schoz för „$1“ änndere)',
+'confirmprotecttext' => 'Wellß De di Sigk schözze?',
+'confirmprotect' => 'Sigk schözze',
+'protectmoveonly' => 'Nuur jäje et Ömnänne schöze',
+'protectcomment' => 'Dä Jronnd oddo Aanlaß fö_t Schözze',
+'unprotectsub' => '(Schoz fö „$1“ ophävve)',
+'confirmunprotecttext' => 'Wellß De di Sigk frëij jëvve un dä iere Schoz opphävve?',
+'confirmunprotect' => 'Sigk frëij jëvve',
+'unprotectcomment' => 'Dä Aanlaßß för dä Schoz op_ze_häve',
+'protect-unchain' => 'Et Schözze jäje Ömnänne ëxtra ëijnshtëlle loohße',
+'protect-text' => 'Hee kannß_De dä Schoz jäje Veränderonge fö_de Sigk „$1“ aanlooere un änndere. Em <span
+
+class="plainlinks">[{{FULLURL:Special:Log/protect|page={{FULLPAGENAMEE}}}} Logbooch]</span> fingkß De ählere
+
+Ännderonge fun däm Schoz, wännt_se jitt. Bess_esu jood un halldt Desh aan de Räjelle för_esu Fäll!',
+'protect-viewtext' => 'Ding Beräshtijung als_enne Medmaacher eß nit jenooch, öm dä Sigge_Schoz ze änndere.
+
+Hee de aktowälle Ėnnshtällonge för di Sigk „<strong>$1</strong>“:',
+'protect-default' => '—(Shtanndadt)—',
+'protect-level-autoconfirmed'=> 'nur Medmaacher raanloohße, di sesh aanjemälldt hann',
+'protect-level-sysop' => 'Nuur de Wikki_Köbeßße raanloohße',
+'restriction-edit' => 'An et Änndere …',
+'restriction-move' => 'An et Ömnänne …',
+'undelete' => 'Fottjeschmeßßene Krohm aanluere/zerrökholle',
+'undeletepage' => 'Fottjeschmeßßen Sigge aanluere un widdo zerögk_holle',
+'viewdeletedpage' => 'Fottjeschmessen Sigge aanzëije',
+'undeletepagetext' => 'De Sigge hee_noh si fottjeschmeßße, mer künne se ävver ėmmer noch uss_em Möll_Ëmmer
+
+erruß_kroose.',
+'undeleteextrahelp' => 'Öm die jannze Sigk met alle iere Väsjoohne widder ze holle, loohß all de Väsjoohne oohne
+
+Höökshe, un kligg_op „<b style="padding:2px; background-color:#ddd; color:black">Zerröck_Holle!</b>“.
+
+Öm blooß ëijnzel Väsjoohne zerögk_ze_holle, maach Höökshe aan di_Väsjoohne, di_De widder hann wellß, un dann donn „<b
+
+style="padding:2px; background-color:#ddd; color:black">Zerröck_Holle!</b>“ klikke.
+
+Op „<b style="padding:2px; background-color:#ddd; color:black">De Fällder ußliihre</b>“
+klikk, wänn_De all Ding Höökshe un Ding „Äklierong (fö_enn_et LogBooch):“ widder fott hann wellß.',
+'undeletearticle' => 'Enne fottjeschmeßßene Atikkel widdo zerrögk_holle',
+'undeleterevisions' => '<strong>$1</strong> Väsjohne en_t Aschihf jedonn',
+'undeletehistory' => 'Wänn_De di Sigk widdo zerrögk_hollß,
+dann kriß_De alle fottjeshmeßßene Väsjohne widder.
+Wänn_enzwesche en nöüe Sigk unger dämm aahle Name ennjereshtdt woode eß,
+dann wääde de zerögkjeholldte Väsjohne ëijnfach alß zosätzlijje älldere Väsjohne fö_di nöüje Sigk ennjerëijdt wääde.
+Di nöüje Sigk weed nidd_äsäzz.',
+'undeletehistorynoadmin'=> 'Di Sigk es fottjeschmeßße woode. Dä Jrunnd_dö_füüer iß en de Leßß unge ze finge,
+
+jenau_esu wi de Medmaacher, wo de Sigk fo_änndot hann, iih dat se fotjeschmeßße wood. Wat op dä Sigk iere
+
+fotjeschmeßßene aahle Väsjohne shtundt, dat künne nuuer de Wikki_Köbeßße noch
+
+aansinn (un och widder zerögk holle)',
+'undeleterevision' => 'Fottjeschmeßßen Väsjohne noh_m Shtanndt fum $1',
+'undeletebtn' => 'Zerröck_Holle!',
+'undeletereset' => 'De Fällder ußliihre',
+'undeletecomment' => 'Äklierong (fö_enn_et LogBooch):',
+'undeletedarticle' => '„$1“ zerrögk_jeholldt',
+'undeletedrevisions' => '{{PLURAL:$1|ëijne Väsjohn|$1 Väsjohne}} zerrögk_jeholldt',
+'undeletedrevisions-files'=> 'Zesamme_jenůmme <strong>$1</strong> Väsjohne fun <strong>$2</strong> Dattëije
+
+zerrögk_jeholldt',
+'undeletedfiles' => '<strong>$1</strong> Dattëije zerrögk_jeholldt',
+'cannotundelete' => '<strong>Däh.</strong> Dat Zerrögk_Holle jing donevve. Mööshlish, dat enne Anndere
+
+Medmaacher flöcker wooh, un et alld et eetz jedonn hät, un jäz eß di Sigk ald widder do jewääse.',
+'undeletedpage' => '<big><strong>Di Sigk „$1“ eß jäz widdo_doo</strong></big>
+
+Luer Der_et [[Special:Log/delete|Logbooch med_e fottjeschmeßßenne Sigge]] aan, do häßß De de nöüßte fottjeschmeßßene
+un widdo herjeholldte Sigge.',
+# Namespace form on various pages
+'namespace' => 'Appachtemeng:',
+'invert' => 'donn di Ußßwaal ömmdriije',
+
+# Contributions
+'contributions' => 'Däm_Medmaacher sing Bëijdräsh',
+'mycontris' => 'ming Bëijdräsh',
+'contribsub' => 'För dä Medmaacher: $1',
+'nocontribs' => 'Mer han këijn Ännderonge jefonge, enn_de_Log_Böösher, di_do paßße dääte.',
+'ucnote' => 'Hee sinn däm Medmaacher sing läzde <strong>$1</strong> Änderonge fun de läzde
+
+<strong>$2</strong> Daare.',
+'uclinks' => 'Zëijsh de läzde <strong>$1</strong> Bëijdräsh, zëijsh de läzde <strong>$2</strong>
+
+Dare.',
+'uctop' => ' (Nöüßte)',
+'newbies' => 'Nöüje Medmaacher',
+
+# What links here
+'sp-newimages-showfrom' => 'Zëijsh de nöüje Bellder aff däm $1',
+'sp-contributions-newest'=> 'Nöüste',
+'sp-contributions-oldest'=> 'Ählßte',
+'sp-contributions-newer'=> 'Nöüste $1',
+'sp-contributions-older'=> 'Ähler $1',
+'sp-contributions-newbies-sub'=> 'Fö_Nöüje Medmaacher',
+'whatlinkshere' => 'Wat noh hee lingk',
+'notargettitle' => 'Këijne Bezoch obb_en Ziiel',
+'notargettext' => 'Et fäält enne Medmaacher odder en Sigk, wo mer jät zo erußfinge oddo oplißte sůlle.',
+'linklistsub' => '(Lėßß met de Lėngkß)',
+'linkshere' => 'Dat sinn di Sigge, di op <strong>„[[:$1]]“</strong> lingke důnn:',
+'nolinkshere' => 'Këijn_Sigk lėngk noh <strong>„[[:$1]]“</strong>.',
+'isredirect' => 'Ömlëijdungß_Sigk',
+'istemplate' => 'weed ėnnjeföösh',
+'blockip' => 'Medmaacher spärre',
+'blockiptext' => 'He kannz De beshtemmpte Medmaacher odder
+
+IP_Addräßße]shpärre, su dat_se he em Wikki nit mieh
+
+schriive und Sigge Änndere künne. Dat sullt nuur jedonn wääde om su jenannte
+
+Fandaale ze brämmse. Un mer mößße unß do_bëij natöörlish aan uns
+
+[[{{ns:project}}:Policy|Rääjelle]] fö_su_n Fäll hallde.
+
+Draach bëij „Aanlaßß“ enne mööshlishßt jenoue Jrunnd_en, wöröm dat Shpärre. Nänn un Link op de Sigge wo Ëijne kapott
+
+jemaat hätt, zem Bäijshpill.
+
+Luůr op [[Special:Ipblocklist|de Lėßß met jeshpächte IP_Aräßße]] wänn de ne Övverblegg_över de Shpärrunge hann wellß,
+
+un och wänn_De_se änndere wellß.',
+'ipaddress' => 'IP-Addräßß',
+'ipadressorusername' => 'IP Addräßß oddo Medmaacher_Name',
+'ipbexpiry' => 'Dauer fö_wi lang',
+'ipbreason' => 'Aanlaßß',
+'ipbanononly' => 'Nur de namelose Medmaacher shpärre',
+'ipbcreateaccount' => 'Nöüj_aanmällde fobeede',
+'ipbsubmit' => 'Důnn dä Medmaacher shpärre',
+'ipbother' => 'En annder Zigk',
+'ipboptions' => '1 Shrundt:1 hour,2 Shrundt:2 hours,3 Shrundt:3 hours,6 Shtund:6 hours,12 Shtund:12
+
+hours,1 Daach:1 day,3 Daare:3 days,1 Woch:1 week,2 Woche:2 weeks,3 Woche:3 weeks,1 Moohnd:1 month,3 Moohnde:3
+
+months,6 Moohnde:6 months,9 Moohnde:9 months,1 Joohr:1 year,2 Joohre:2 years,3 Joohre:3 years,Onbejrännz:infinite',
+'ipbotheroption' => 'Sönß_wi lang',
+'badipaddress' => 'Wat De do jeschrevve häß, dat eß këijn ööndlijje
+
+IP_Addräßß.',
+'blockipsuccesssub' => 'De IP-Addräß eß jeshpächt',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] eß jëz jeshpächt.
+
+Luůr op [[Special:Ipblocklist|de Lėßß met jeshpächte IP_Aräßße]] wänn de ne Övverblegg_över de Shpärrunge hann wellß,
+
+un och wänn_De_se änndere wellß.',
+'unblockip' => 'Dä Medmacher widdor maache loohße',
+'unblockiptext' => 'Hee kannz De für_her jeshpächte IP_Addräßße oddo Medmaacher widdo frëijäavve, un
+
+dänne_esu dat Rääsh fö_ze_Schriive he em Wikki widdo_jävve.
+
+Luůr op [[Special:Ipblocklist|de Lėßß met jeshpächte IP_Aräßße]] wänn de ne Övverblegg_över de Shpärrunge hann wellß,
+
+un och wänn_De_se änndere wellß.',
+'ipusubmit' => 'Důnn de Shpärr_fö_di Adräßß widdo ophävve',
+'unblocked' => '[[User:$1|$1]] wood widdo zohjelohße',
+'ipblocklist' => 'Lėßß med jeshpächte IP-Adräßße un Medmaacher_Naame',
+'blocklistline' => '$1, $2 hät „$3“ jeshpächt ($4)',
+'infiniteblock' => 'fö_iiwish',
+'expiringblock' => 'endt aam $1',
+'anononlyblock' => 'nur annonühme',
+'createaccountblock' => 'Aanmällde nit mööshlėsh',
+'ipblocklistempty' => 'Ed_eß nix en de Lėßß med jeshpächte IP-Adräßße un Medmaacher_Naame.',
+'blocklink' => 'Shpärre',
+'unblocklink' => 'widde_frëijjävve',
+'contribslink' => 'Bëijdrääsh',
+'autoblocker' => 'Automatesh jeshpächt. Ding IP_Addräßß wood köözlėsh fun däm Medmaacher „[[User:$1|$1]]“
+
+jebruch. Dä eß jeshpächt woode wääje: „<i>$2</i>“',
+'blocklogpage' => 'Logbooch med Medmaacher-Shpärre',
+'blocklogentry' => '„[[$1]]“ jeshpächt, för $2',
+'blocklogtext' => 'Hee ėß dat LogBooch för et Medmaacher Shpärre un Frëijävve. Automaatėsh jeshpächte
+
+IP-Addräßße sin nit hee, ävver em
+
+[[Special:Ipblocklist|Logbooch med jeshpächte IP-Adräße]] ze finge.',
+'unblocklogentry' => 'Medmaacher „[[User:$1|$1]]“ frëijejovve',
+'range_block_disabled' => 'Adräßße_Jebeede ze shpärre, eß nit älaup.',
+'ipb_expiry_invalid' => 'De Dauer eß Drißß. Jävv_se rishtish aan.',
+'ipb_already_blocked' => '„$1“ eß ald jeshpächt',
+'ip_range_invalid' => 'Dä Berëijsh fun IP_Addräßße eß nidd_en Ochdnung.',
+'proxyblocker' => 'Proxy_Blokker',
+'ipb_cant_unblock' => 'Enne Fääler: De Shpärr Nommer $1 eß nit ze finge. Se künndt ald widdo frëij_jejovve woode
+
+sinn.',
+'proxyblockreason' => 'Unger Dinge IP_Addräßß
+
+leuv_enne offene Proxy. Dröm kannß_De hee em Wikki nix maache. Schwadt med
+
+Dimgem Süßteem_Minsch oddo Näzwärrək_Täshnikko Internet Service Provider un
+
+fozäll dänne fun däm Rissikko för Ühr Sesherhëijdt!',
+'proxyblocksuccess' => 'Fähdėsh',
+'sorbs' => 'SORBS DNSbl',
+'sorbsreason' => 'Ding IP_Addräßß weed en de
+
+[http://www.sorbs.net SORBS] DNSbl als_enne offene
+
+Proxy jelėßß. Schwadt med Dimgem Süßteem_Minsch oddo Näzwärrək_Täshnikko
+
+Internet Service Provider drövver, un fozäll dänne fun däm Rissikko för Ühr
+
+Sesherhëijdt!',
+'sorbs_create_account_reason'=> 'Ding IP_Addräßß weed en
+
+[http://www.sorbs.net SORBS] DNSbl als_enne offene
+
+Proxy jelėßß. Dröm kannß_De Desch hee em Wikki nit allse_enne nöüje Medmaacher
+
+aanmällde. Schwadt med Dimgem Süßteem_Minsch oddo Näzwärrək_Täshnikko oddo Internet Service Provider drövver, un fozäll dänne fun däm Rissikko för Ühr Sesherhëijdt!',
+'lockdb' => 'Daate_Bangk Spärre',
+'unlockdb' => 'Daate_Bangk frëij_jäve',
+'lockdbtext' => 'Noh_m Shpärre kann Këijne mieh Ännderonge maache an singe Op_paßß_Lėßß, aan
+
+Ëijnshtellunge, Atikelle, uew. un nöüje Medmaacher jidd_et och nit. Beß sesher, dat_Te_dat wellß?',
+'unlockdbtext' => 'Noh_m Frëij_Jävve eß de Daate_Bangk nit mieh jeshpächt, un all_di nommaale Ännderonge
+
+weede widdo mööshlesh. Beß sesher, dat_Te_dat wellß?',
+'lockconfirm' => 'Jo, ėsh_well dė Daate_Bangk jeshpächt hann.',
+'unlockconfirm' => 'Jo, ėsh_well dė Daate_Bangk frëij jäve.',
+'lockbtn' => 'Daate_Bangk Spärre',
+'unlockbtn' => 'Daate_Bangk frëij jäve',
+'locknoconfirm' => 'Do häß këij Höhksche en_dämm Fëlldt zem Beshtätijje jemaat.',
+'lockdbsuccesssub' => 'De Daate_Bangk eß jäz jespächt',
+'unlockdbsuccesssub' => 'De Daate_Bangk eß jäz frëij_jejovve',
+'lockdbsuccesstext' => 'De Daate_Bank fun de {{SITENAME}} jäz jeshpächt.<br />
+Důnn_se widdo frëij_jëvve, wann_Ding Waadung dorresch eß.',
+'unlockdbsuccesstext' => 'De Daate_Bangk eß jäz frëij_jejovve.',
+'lockfilenotwritable' => 'Dė Dattëij, wo dė Date_Bangk met jeshpächt weede wööd, künne_mer nit aanlääje, odder nit
+
+dren shriive. Esu enne Drißß! Dat mööt dä Web_ßööver ävver künne! Fozäll dadd_ennem Foanntwochtlijje fö de
+
+Inshtallazjohn fu däm ßööver, odder reparėer_et selləve, wänn_De kannß.',
+'databasenotlocked' => '<strong>Opjepaßß:</strong> De Daate_Bangk eß <strong>nit</strong> jespächt.',
+'makesysoptitle' => 'Maach_enne Wikki_Köbes uß däm Medmaacher',
+'makesysoptext' => 'He künne Bürro_Kraade uss_ennem nommaale Medmaacher enne Wikki_Köbes oddo orr_enne
+
+Bürrokraat maache.
+Shriif däm Medmaacher singe Medmaacher_Name hee erinn, un Lohß Jonn!',
+'makesysopname' => 'Hee dä Medmaacher_Name:',
+'makesysopsubmit' => 'Maach enne Wikki_Köbes uß dämm Medmaacher',
+'makesysopok' => '<strong>Dä Medmaacher „[[User:$1|$1]]“ iß jäds_enne Wikki_Köbes jewoode.</strong>',
+'makesysopfail' => '<strong>Dä Medmaacher „$1“ kunnt nit zom Wikki_Köbes jemaat wääde. Et jing nit. Häß_De dä
+
+Naame fellëijsh fokiijet jeshrevve?</strong>',
+'setbureaucratflag' => 'Maach och enne Bürrokraat druß',
+'rightslog' => 'Logbooch fö_Ännderonge aan Medmaacher-Rääshde',
+'rightslogtext' => 'He sin de Änderonge an Medmaacher ier Rääshde opjelėßß. Op de Sigge övver
+
+Wikki_Köbeßße, Bürro_Kraade, … kannß_De
+
+noh_lässe, wat domet eß.',
+'rightslogentry' => 'hät däm Medmaacher „$1“ sing Rääshde fun „$2“ op „$3“ ömjestalldt',
+'rights' => 'Rääschde:',
+'set_user_rights' => 'Däm Medmaacher sing Rääshte nöü beshtemme',
+'user_rights_set' => '<strong>Dem Medmaacher „$1“ sing Rääshte woote nöü jessäz</strong>',
+'set_rights_fail' => '<strong>Dem Medmaacher „$1“ sing Rääshte woote nit aanjepakk. Et jing nit. Häß_De dä
+
+Naame fellëijsh fokiijet jeshrevve?</strong>',
+'makesysop' => 'Medmaacher zom Wikki_Köbes maache',
+'already_sysop' => 'Dä Medmaacher aß alld_enne Wikki_Köbes.',
+'already_bureaucrat' => 'Dä Medmaacher eß ald_ene Bürrokraat.',
+'rightsnone' => '(nix)',
+'movepage' => 'Sigk Ömnänne',
+'movepagetext' => 'Hee kannß De en Sigk en de {{SITENAME}} ömnänne. Domet kritt di Sigg_enne nöüje Name, un
+
+alle fürherijje Väsjohne fun dä Sigk och. Unger däm ahle Name weed_otomatijj_en
+
+Ömlëijdung op dä nöüe Name enjedraare. Lėngkß op dä
+
+aahle Name blieve ävver wi se woohre. Dat hëijß, Do moßß sellver nohluere, ov do jäz
+
+[[Special:Doubleredireects|dubbelde]] oddo [[Special:Doubleredireects|kapotte]] Ömlëijdunge bëij eruß_kumme.
+
+Wenn_De_n Sigg_ömnänne dëijß, häß Do och dör ze sorrəje, dat_de betroffene Lingkß do hen jonn, wo se hen jonn sulle.
+
+Allso holl Der de Leßß „Wat noh hee lingk“ un jangk se dorrsh!
+
+Di Sigk weed <strong>nit</strong> ömjenanndt, wann_et met däm nöüe Name alld_en Sigk jitt, <strong>ußßer</strong> do
+
+eß nix drop, odder et ess_en Ömlëijdung un se eß no nii jeänndot voode. Esu kam_mer en Sigk jlish widder zerögk
+
+ömnänne, wämmer sesh mem Ömnänne fodonn hätt, un mer kann_och këijn Sigge kapottmaache, wo alld jät drop shtëijdt.
+
+<strong>Oppjepaßß!</strong> Wat bëijm Ömnänne eruß_kütt, künnd_en opfällije un fellëijsh shtüürende Änderong am Wikki
+
+sinn, besöndoß bëij öff jebruchte Sigge. Also beß sėsher, dat_E foshtëijß, wat_De hee am maache beß, ih_dat_E_t
+
+määß!',
+'movepagetalktext' => 'Dä Sigk ier Klaaf_Sigk, wann_se_ëijn hätt, weed automattish medd_öm_jenanndt,
+
+\'\'\'ußßer\'\'\' wänn:
+* di Sigg_enn_en annder Appachtemeng kütt,
+* en Klaaf_Sigk met däm nöüe Name alld do eß, un et shtëijd_och_jät drop,
+* De unge en_däm Käßßje \'\'\'këij\'\'\' Höökshe aan häßß.
+
+En dänne Fäll, moßß_De Der dä Ėnnhalldt fun dä Klaaf_Sigge slləfß für_nämme, un eröm_kopėere,
+wat_De bruchß.',
+'movearticle' => 'Sigk Ömnänne',
+'movenologin' => 'Nėd_Ėnnjelogg',
+'movenologintext' => 'Do mööds_alld aanjemäldt un [[Special:Userlogin|ennjelogg]] sinn, öm en Sigk
+
+öm_ze_nänne.',
+'newtitle' => 'op dä nöüje Naame',
+'movepagebtn' => 'Ömnänne',
+'pagemovedsub' => 'Dat Ömnänne hätt_jeflupp',
+'pagemovedtext' => 'Di Sigk „[[$1]]“ eß jäz ömjenannd_en „[[$2]]“.',
+'articleexists' => 'Di Sigk met dämm Naame jidd_et alld, oddo dä Naame kam_mer odder darrəf
+
+mer_nit_bruche.<br />Do moß_De Der_enne anndere Name uß_sööhke.',
+'talkexists' => '<strong>Opjepaßß:</strong> Di Sigk sälləver woodt jäz ömjenanndt, ävver dä_ier Klaaf_Sigk
+
+kunnte mer net medt_öm_nänne. Et jidd_alld_ëijn met_däm nöüe Naame. Bess_esu_jood_un donn di zwëij fun hand zosamme
+
+lääje!',
+'movedto' => 'ömjenanndt en',
+'movetalk' => 'dä_ier Klaaf_Sigk met_öm_nänne',
+'talkpagemoved' => 'Di Klaaf_Sigk do_zo wood medt_ömm_jenanndt.',
+'talkpagenotmoved' => 'Di Klaaf_Sigk do_zo wood <strong>nit</strong> ömmjenanndt.',
+'1movedto2' => 'hät di Sigk fun „[[$1]]“ en „[[$2]]“ ömjenanndt.',
+'1movedto2_redir' => 'hät di Sigk fun „[[$1]]“ en „[[$2]]“ ömjenannd_un do_för de ahle Ömlëijdungß_Sigk
+
+fottjeschmeße.',
+'movelogpage' => 'Logbooch med de ömjenanndte Sigge',
+'movelogpagetext' => 'Hee sin_de_nöüßte ömjenanndte Sigge opjelėßß, unn_wä_t jedonn hätt.',
+'movereason' => 'Aanlaßß',
+'revertmove' => 'Et Ömnänne zerök_nämme',
+'delete_and_move' => 'Fottschmiiße un Ömnänne',
+'delete_and_move_text' => '== Däh! Dubbelte Name ==
+
+Dä Atikkel „[[$1]]“ jidd_et_ald. Wůlltß_De_en fottschmiiße, öm hee dä Atikkel ömnänne ze künne?',
+'delete_and_move_confirm'=> 'Jo, důnn dä Atikkel fottschmiiße.',
+'delete_and_move_reason'=> 'Fottjeschmeßße, öm Plaz för_t Ömnänne ze maache',
+'selfmove' => 'Dů_Doof! — dä aahle Namme un dä nöüje Naame eß dä_sellve — do hädd_et Ömnänne winnish
+
+Sėnn.',
+'immobile_namespace' => 'Do künne_mer Sigge nit hen ömnänne, dat Appachtemeng eß_shpezjäll, un_dä_nöüje_Name fö_di
+
+Sigk jëijd_däßwääje_nit.',
+'export' => 'Sigge Ëxpochtėere',
+'exporttext' => 'Hee äxpochtėeß_De dä Täxx un de Ëijenschaffte fun enner Sigk, oddo fun_ennem Knubbel
+
+Sigge,
+de aktowälle Väsjohn,
+met odder oohne ier äählere Väsjohne.
+Dat Jannze es enjepagg_en XML.
+Dat kam_mer enn_en annder Wikki
+— wänn_et och met dä MediaWiki-ßoffwäer leuf -
+övver di Sigk „[[Special:Import|Impocht]]“ doo, widder impochtėere.
+
+* Schriif de Tittelle fun dä Sigge en dat Fälldt fö_Täxx ennzejäve, unge, ëijne Tittel in jeede Rëij.
+* Dann dunn on_noch ußsööke, ov_De all de fürherijje Väsjohne fun dä Sigge hann wellß, oddo nuur de akktowälle met dä
+
+Infommazjoohne fun de läzde Ännderong. (En dämm Fall künnz_De, fö_n ëijnzellne Sigk, och enne tirägkte Lėngk bruche,
+
+zom Bëijshpill „[[{{ns:Special}}:Export/{{int:mainpage}}]]“ för de Sigk „[[{{int:mainpage}}]]“ ze äxpochtėere)
+
+Dängk draan, dat_Te dat Zeush em Unicode Fommaat afshpäijshere moßß,
+wänn_De jät domet aanfange künne wellß.',
+'exportcuronly' => 'Blooß de aktowälle Väsjohn ußßjävve (un_<strong>nit</strong> de jannze aaale Väsjohne
+
+on_noch met do_bëij donn)',
+'exportnohistory' => '----
+<strong>Opjepaßß:</strong> de jannze Väsjohne Äxpochtėere eß he em Wikki affjeschaldt. Schaadt, ävver_et wöör_en
+
+zo_jůůße Laßß fö_dä ßöövor.',
+'export-submit' => 'Lohß_Jonn!',
+'allmessages' => 'All Täxx, Boushtejn un Aanzeije fum Wikki_Süßteem',
+'allmessagesname' => 'Name',
+'allmessagesdefault' => 'Dä shtandat_määßijje Täxx',
+'allmessagescurrent' => 'Esu eß dä Täxx jäz',
+'allmessagestext' => 'Hee kütt en Lëß met Täxxte, Täx_Shtök, un Nohrishte em Appachtemeng „MediaWiki:“',
+'allmessagesnotsupportedUI'=> 'Mer künne „Special:Allmessages“ nit met dä Ingerfäijß_Shprooch <strong>$1</strong>
+
+zosamme, di De jraat ennjeshtälldt häß. Söök Der en anndere Shprooch uß, wo_t met jonn künnt!',
+'allmessagesnotsupportedDB'=> '<strong>Dat wooh nix!</strong> Mer künne „Special:Allmessages“ nit zëije,
+
+<code>wgUseDatabaseMessages</code> eß ußßjeshalldt!',
+'allmessagesfilter' => 'Fingk dat Shtöck hee em Name:',
+'allmessagesmodified' => 'Důnn nur de Foänndotte aanzëije',
+'thumbnail-more' => 'Jrüüßer aanzëije',
+'missingimage' => '<b>Dat Bėlld es nit doh:</b><br />„$1“',
+'filemissing' => 'Dattëij eß nit_do',
+'thumbnail_error' => 'Enne Fääler eß opjedouch bëijm Maache fun_em Breefmarrəke/Thumbnail-Belldshe: „$1“',
+'import' => 'Sigge Ėmpochtėere',
+'importinterwiki' => 'Tranß_Wikki Ėmpocht',
+'import-interwiki-text' => 'Wähl_en Wikki unn_en Sigk zem Ėmmpochtėere uß. Et Dattum fun de Väsjohne un de
+
+Medmaacher_Naame fun de Schriiver weede dobëij metjenůmme. All de Tranß_Wikki Ėmmpochte weede em
+
+[[{{ns:special}}:Log/import|Ėmmpocht_LogBooch]] faßßjehallde.',
+'import-interwiki-history'=> 'All de Väsjohne fun dä Sigk hee kopėere',
+'import-interwiki-submit'=> 'Huh_Laade!',
+'import-interwiki-namespace'=> 'Donn de Sigge ėmpochtėere em Appachtemeng:',
+'importtext' => 'Dunn de Daate med däm „[[Special:Export|Ëxpocht]]“ fun doo fun ennem Wikki Äxpochtėere,
+
+do_bëij don_net — ättwa bëij Dir om Räshnor — affshpëijsherre, un dann hee huh_laade.',
+'importstart' => 'Ben Sigge am ėmpochtėere …',
+'import-revision-count' => '({{PLURAL:$1|ëijn Väsjohn|$1 Väsjohne|këijn Väsjohn}})',
+'importnopages' => 'Këijn Sigk för ze_Ėmpochtėere jefonge.',
+'importfailed' => 'Dat Impochtėere eß donëvve_jejange: $1',
+'importunknownsource' => 'Di Zoot Qwäll fö_t Ėmpochtėere kënne_mer nit',
+'importcantopen' => 'Kunnt op de Dattëij fö_dä Ėmpocht nit zohjriife',
+'importbadinterwiki' => 'Fokiehjter Ingerwiki_Lėngk',
+'importnotext' => 'En dä Dattëij wooh nix dren ännthallde, oddo_winnishßdenß këijne Täxx',
+'importsuccess' => 'Dat Ėmpochtėere hätt jeflupp!',
+'importhistoryconflict' => 'Mer hann zwëij aahle Väsjohne jefonge, di donn sėsh biiße — di ëijn wooh alld_doo — de
+
+annder en dä Ėmpoot_Dattëij. Mööshlesh, Ühr hatt_i Daate alld_enß ėmpootėedt.',
+'importnosources' => 'Hee sin këijn Qwälle fö_do Tranß_Wikki Ėmpocht ennjereshdt.
+Dat aahle Väsjohne Huhlaade eß affjeschalldt, un_nit mööshlėsh.',
+'importnofile' => 'Et wood ja_këij Dattëij huh_jelaade fö_ze Ėmpochtėere.',
+'importuploaderror' => 'Dat Huh_Laade eß donevve jejange. Mööshlėsh, dat_te Dattëij ze_jruuß woh, jrüüßo wi_mmer
+
+huh_laade darrəf.',
+'importlogpage' => 'Logbooch med ėmpochtėerte Sigge',
+'importlogpagetext' => 'Sigge met iere Väsjohne fun annder Wikkiß ėmpochtėere.',
+'import-logentry-upload'=> '„[[$1]]“ ėmpochtėet',
+'import-logentry-upload-detail'=> '{{PLURAL:$1|ëijn Väsjohn|$1 Väsjohne|këijn Väsjohn}} ėmpochtėet',
+'import-logentry-interwiki'=> 'tranß_wikki_ėmmpochtėet: „$1“',
+'import-logentry-interwiki-detail'=> '{{PLURAL:$1|ëijn Väsjohn|$1 Väsjohne|këijn Väsjohn}} fun „$2“',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'm',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'En de {{SITENAME}} sööke [alt-f]',
+'tooltip-minoredit' => 'Dëijt Ding Ännderonge allß klëijn Minni_Ännderonge makėere. [alt-m]',
+'tooltip-save' => 'Dëijt Ding Ännderonge affsphëijshere. [alt-s]',
+'tooltip-preview' => 'Lißß de Füür_Aansėsh fun dä Sigk un_fun_Dinge Ännderonge ih_dat_De_n Affsphëijshere
+
+dëijß! [alt-p]',
+'tooltip-diff' => 'Zëijsh Ding Ännderone am Täxx aan. [alt-v]',
+'tooltip-compareselectedversions'=> 'Donn de Ungescheed zweshe dä bëijde ußjewäälte Väsjohne zëije. [alt-v]',
+'tooltip-watch' => 'Op di Sigk hee oppaßße. [alt-w]',
+'common.css' => '.allpagesredirect, .titleNamespace {font-style:italic}',
+'monobook.css' => ' /* edit this file to customize the monobook skin for the entire site */
+
+ /* distinguish redirections in Special:Allpages directory */
+ .allpagesredirect {font-style:italic}
+
+ /* Visualizza i bordi arrotondati sui browser basati su Geko */
+ .pBody {
+ padding: 0.1em 0.1em;
+ -moz-border-radius-topright: 1em;
+ -moz-border-radius-bottomright: 1em;
+ }
+ #p-cactions ul li, #p-cactions ul li a {
+ -moz-border-radius-topright: 0.8em;
+ -moz-border-radius-topleft: 0.8em;
+ }
+
+ /* Kleinschreibung nicht erzwingen */
+ .portlet h5, .portlet h6,
+ #p-personal ul, #p-cactions li a {
+ text-transform: none;
+ }',
+'nodublincore' => 'De RDF_Metta_Daate fun de „Dublin Core“ Aat senn affjeschalldt.',
+'nocreativecommons' => 'De RDF_Metta_Daate fun de „Creative Commons“ Aat senn affjeschalldt.',
+'notacceptable' => '<strong>Blööd:</strong> Dä Wikki_ßööver kann de Daate nit en_ennem Fomaat erövverjävve,
+
+wat Dinge Client odde Brauser foshtonn künnt.',
+'anonymous' => 'Namelose Medmaacher fun_de {{SITENAME}}',
+'siteuser' => '{{SITENAME}}-Medmaacher $1',
+'lastmodifiedatby' => 'Hee di Sigk wood_et läz jeänndort fun $3 om $2, $1',
+'and' => 'un',
+'othercontribs' => 'Bout op de Ärbeëijdt fun „<strong>$1</strong>“ op.',
+'others' => 'anndere',
+'siteusers' => '{{SITENAME}}-Medmaacher $1',
+'creditspage' => 'Övver de Medmaacher un ier Bëijdräsh fö_di Sigk',
+'nocredits' => 'Fö_di Sigk ham_mer nix en de Lėßß.',
+'spamprotectiontitle' => 'SPAM_Shoz',
+'spamprotectiontext' => 'Di Sigk, di de affshpëijshere wellß, di weed fun unsem SPAM_Shoz net dorschjelohße. Dat
+
+küt domiiz fun ennem Lėngg_obb_en främmbde Sigk.',
+'spamprotectionmatch' => 'Hee dä Täx hät dä SPAM_Shoz op_de Plan jeroofe: „<code>$1</code>“',
+'subcategorycount' => 'Hee {{PLURAL:$1|weed ëijn Ungerjropp|wääde $1 Ungerjroppe}} jezëijsh <small> (Et künnt
+
+mieh op de füürije un nähkßte Sigge jëvve)</small>',
+'categoryarticlecount' => 'Hee {{PLURAL:$1|weed ëijne Attikkel|wääde $1 Attikkelle}} jezëijsh <small> (Et künnt
+
+mieh op de füürije un nähkßte Sigge jëvve)</small>',
+'listingcontinuesabbrev'=> ' wigger',
+'spambot_username' => 'SPAM fottschmiiße',
+'spam_reverting' => 'De läzde Väsjohn eß oohne_de Lėnggs_obb „$1“ widdo zerrögk_jeholldt.',
+'spam_blanking' => 'All di Väsjohne hatte Lėnggs_obb „$1“, di_sen_jäds_erruß_jemaat.',
+'infosubtitle' => 'Övver de Sigk',
+'numedits' => 'Aanzal Ännderonge an_däm Atikkel: <strong>$1</strong>',
+'numtalkedits' => 'Aanzal Ännderonge aan de Klaaf_Sigk: <strong>$1</strong>',
+'numwatchers' => 'Aanzal Oppaßßer: <strong>$1</strong>',
+'numauthors' => 'Aanzal Medmaacher, di_an_dämm Atikkel jeshrevve hann: <strong>$1</strong>',
+'numtalkauthors' => 'Aanzal Medmaacher bëijem Klaaf: <strong>$1</strong>',
+'mw_math_png' => 'Ėmmer nuur PNG aanzëije',
+'mw_math_simple' => 'En ëijnfaache Fäll maach HTML, sönß PNG',
+'mw_math_html' => 'Maach HTML wann mööshlish, un sönß PNG',
+'mw_math_source' => 'Loohs_et als TeX (joot fö_de Täxx_Brausere)',
+'mw_math_modern' => 'De bëßß Ënnshtëllung_fö_de_Brauser fun hügk',
+'mw_math_mathml' => 'Nemm „MathML“ wän_mööshlish (em probier_Shtadijum)',
+'markaspatrolleddiff' => 'Nohjeluert. Důnn dat faßßhallde',
+'markaspatrolledtext' => 'Di Änderong eß nohjeluert, donn dat faßßhallde',
+'markedaspatrolled' => 'Et Kënnzëijshe „Nohjeluert“ shpëijshere',
+'markedaspatrolledtext' => 'Ed_eß_jäz faßßhallde, dat_dė ußßjewäälte Ännderonge nohjeluert woode sinn.',
+'rcpatroldisabled' => 'Et Nohluere fun de läzde Ännderonge eß affjeschalldt',
+'rcpatroldisabledtext' => 'Et Nohluere fun de läzde Ännderonge eß fö_do_Mommännt nit mööshlėsh.',
+'markedaspatrollederror'=> 'Kann dat Kënnzëijshe „Nohjeluert“ nit affshpëijshere.',
+'markedaspatrollederrortext'=> 'Do_moss_en beshtemmpte Väsjohn ußsööke.',
+'monobook.js' => ' /* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Ding ëijen Medmaacher_Sigk.\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'De Medmaacher_Sigk fun Dinge aktlowälle IP_Adräßß.\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Ding ëijen Klaaf_Sigk.\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Klaaf_Sigk övver de Bëijdräsh fun Dinge aktowälle IP_Addräß.\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Ding eijene Enshtëllunge hee op dä {{SITENAME}}.\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'De Leßß met dä Sigge wo De drop op_paßße lööhß.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'De Leßß met Dinge eijene Bëijdräsh.\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Do küünz Desh widdo ennlogge, ed_eß ävver nit nüüdish.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Do küünz Desh hee als_enne Medmaacher aanmëllde, moss_ävvor nit.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Ußlogge, domet De zem nameloose Medmaacher weeß.\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Klaaf övver de Sigk med Enhalld.\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Do kannß di Sigk fo_änndere. Luer Der de Füür_Aansesh aan, ih dat_De_se
+
+affshpëijsherre dëijß.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Donn norr_enne Affschnett bëij dä Klaaf hee.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Di Sigk eß jääve Foänderonge jeschöz. Do kannß ävver dä Wikki_täx
+
+beluere.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'De Väsjohne fun dä Sigk hee op_lißßte.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Di Sigk jäje et Fo_Änndere un/oddo Ömnänne schözze.\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Di Sigk fottschmiiße.\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Holl de Änderonge un Väsjohne fun dä Sigk zerög, di_t joof, ih_dat_se
+
+fott_jeschmeßße wood.\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Di Sigk ömnänne.\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Pack di Sigk en Ding Oppaß_Less_errinn.\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Schmiiß di Sigk uß Dinger Oppaß_Less_erruß.\');
+ ta[\'search\'] = new Array(\'f\',\'Söök jëdd_em Projägk hee.\');
+ ta[\'p-logo\'] = new Array(\'\',\'Zor Houpsigk fum Projägk.\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Jangk op de Houpsigk.\');
+ ta[\'n-portal\'] = new Array(\'\',\'Övver dat Projägk hee, wat Do donn kannß, woh De jät fingkß, un esu …\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Fingk jät do drövver jesaat, wadd_am Jang_eß.\');
+ ta[\'n-newpages\'] = new Array(\'p\',\'De Leßß met dä nöüe Attikkelle em Wikki.\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'De Leßß met dä nöüßte Ännderonge em Wikki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Jangg_obb_en zofällish üßßjewählte Sigk hee.\');
+ ta[\'n-help\'] = new Array(\'\',\'Jangk noh_m Enhalltß_Forzeijshneß fun de Hülp_Sigge.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Hellef dem Projägg Beshtonn.\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'De Leßß met all Sigge em Wikki, di no hee hen fowiise (lingke) donn.\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'De Leßß met dä nöüßte Ännderonge aan Sigge, di no hee hen fowiise
+
+(lingke) donn\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS Fied fö_di Sigk hee.\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom Fied fö_di Sigk hee.\');
+ ta[\'t-contributions\'] = new Array(\'\',\'De Leßß met alle Bëijdrääsh fun däm Medmaacher hee.\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Schegg_en e-mail aan dä Medmaacher hee.\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Bellder odde annder Medije_Enhallde Huhlaade.\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'De Leßß met all dä Sönder_Sigge.\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'De Sigk aanluere.\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'De Medmaacher_Sigk aanluere.\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'De Meedije_Sigk aanluere.\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Dat eß en Söndersigk, di kam_mer nit änndere.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'De Projägk_Sigk aanluere.\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'De Bellder_Sigk aanluere.\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'De Wikki_Meddäijlongs- oddo Täx_Boushtëijn_Sigk aanluere.\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'De Schabloone_Sigk aanluere.\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'De Hülp_Sigk aanluere.\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'De Saachjropp_Sigk aanluere.\');',
+'deletedrevision' => 'De ahle Väsjohn „$1“ eß fottjeschmeßße.',
+'previousdiff' => '← De Ungersheede dö_für zëije',
+'nextdiff' => 'De Ungersheede do_noh zëije →',
+'imagemaxsize' => 'Bėllder op_de Sigge, wo_se beschrivve vääde, nit jrüüßer maache wi:',
+'thumbsize' => 'Esu brëijdt sůlle de klëijn Belldsche (Thumbnails/Breefmarrke) sinn:',
+'showbigimage' => 'Důnn de Väsjohn med de hüütßte Opplösung eraf_laade, dad_eß <strong>$1</strong> x
+
+<strong>$2</strong> Pixelle, un_di eß <strong>$3</strong> Killo_Byte jruß.',
+'newimages' => 'Bellder, Tööhn, uew. allß Jallerih',
+'showhidebots' => '(Botß $1)',
+'noimages' => 'Këij_Dattëijje jefonge.',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+'specialloguserlabel' => 'Medmaacher:',
+'speciallogtitlelabel' => ' Sigge_Naame:',
+'passwordtooshort' => 'Dat Paßßwood_ėß jät koot — et mööte alld winnishßdenß <strong>$1</strong> Zëijshe,
+
+Zėffere, un Boochshtaave do_dren sinn.',
+'mediawarning' => '<strong>Opjepaßß</strong>: En dä Dattëij küünd_en <b>jefääerlish Projramm_Shtögk</b> dren
+
+shtäke. Wäm_mer_et joufe loohße däät, do künndt dä ßööver met fö de Kräkkor opjemaat wääde.
+<hr />',
+'fileinfo' => '<strong>$1</strong> Killo_Byte, MIME-Tüp: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metta_Daate',
+'metadata-help' => 'En dä Datttëij shish noh_mieh an Daate. Dat sin Metta_Daate, di nommaal fum Oppname_Jerät
+kumme. Wadd_en Kammera, ne Skänner, un_esu, do faßßjehallde hann, dat kann_ävver spääder medd_ennem Projramm
+beärrbtëijdt un ußjetuusch woode sinn.',
+'metadata-expand' => 'Mieh zëije',
+'metadata-collapse' => 'Daate Foshtäshe',
+'metadata-fields' => 'EXIF metadata fields listed in this message will
+be included on image page display when the metadata table
+is collapsed. Others will be hidden by default.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+# Exif tags
+
+
+# external editor support
+'edit-externally' => 'Donn di Dattëij med_ennem äxtärrne Projramm bëij Dr_om Räshnor beärrbëijde',
+'edit-externally-help' => 'Luer op [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] noh
+Henwiiß, wi mer_esu_en äxtärrn Projramm opsäzz un inshtallėere dëijt.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'all',
+'imagelistall' => 'all',
+'watchlistall1' => 'all',
+'watchlistall2' => 'Alles',
+'namespacesall' => 'all',
+
+# E-mail address confirmation
+'confirmemail' => 'e-mail Adräßß beshtätijje',
+'confirmemail_noemail' => 'En [[Special:Preferences||Dinge Ëijnshtellunge]] eß këijn ööndlijje e-mail Addräßß.',
+'confirmemail_text' => 'Ih dat De en dämm Wikki hee de e-mail bruche kannß, moß_De Ding e-mail Addräßß beshtätish
+hann, dat_se en Odenung_eß un dat_se och Ding ëijen eß. Kligk op dä Knopp un Do kriss_en e-mail jeschek. Do
+shtëijd_enne Lėngk medd_ennem Kood dren. Wänn_De met Dingem Brauser op dä Lėngk jëijß, dann dëijß_De domet
+beshtätijje, dadd_et wörrklėsh Ding e-mail Addräßß eß. Dat eß nit förshterlesh sesher, also wööh nix fö_Ding
+Bangk_Konto oddo bëij de Shpaakaßß, ävver et sorresh doför, dat nit jeede Paijjaßß met_Dinge e-mail oddo Dingem
+Medmaacher_Naame eröm_maache kann.',
+'confirmemail_send' => 'Schegg_en e-mail zem Beshtätijje',
+'confirmemail_sent' => 'En e-mail zem Beshtätijje eß ungerwääß.',
+'confirmemail_sendfailed'=> 'Bëijm e-mail Addräßß Beshtätijje eß jät donëvve jejange, dä ßööver hadd_e Problem_med
+
+singe Konfijurazjohn, oddo en Dinge e-mail Addräßß ess_e Zëijshe fokihjet, oddor_esu_jät.',
+'confirmemail_invalid' => 'Bëijm e-mail Addräßß Beshtätijje eß jät donëvve jejange, dä Kood eß fokihjet, künnt
+
+affjeloufe jewääse sinn.',
+'confirmemail_needlogin'=> 'Do moßß Desh $1, fö_de e-mail Addräßß ze beshtätijje.',
+'confirmemail_success' => 'Ding e-mail Adräßß eß jäz beshtäätisht. Jäz künnz_De och noch
+
+[[Special:Userlogin|enlogge]]. Fill_Shpaßß!',
+'confirmemail_loggedin' => 'Ding e-mail Addräßß eß jäz beshtäätish!',
+'confirmemail_error' => 'Bëijm e-mail Addräßß Beshtätijje eß jät donëvve jejange, dė Beshtätijung kunnt nit
+
+affjeshpëijshot weede.',
+'confirmemail_subject' => 'Donn Ding e-mail Addräßß beshtätijje fö_de {{SITENAME}}.',
+'confirmemail_body' => 'Joot mööshlish, Do woos_et sellver,
+fun de IP_Addräßß $1,
+hät sesh jedenfallß Äijne aanjemälldt,
+un well dä Medmaacher „$2“ op de {{SITENAME}}
+wääde, un hädd_en e-mail Addräßß aanjejovve.
+Öm jäz kloo_ze_krijje, dat_di e-mail
+Addräßß un dä nöüje Medmaacher och bëijenander
+jehüüre, moß dä Nöüje en singem Brauser
+dä Lengk:
+
+$3
+
+op_maache. Noch für em $4.
+Also donn dat, wänn de et sellver beß.
+
+Wänn nit Do, söndern sönß wer Ding e-mail
+Addräßß aanjejovve hätt, do bruchß de jaa nix
+ze donn. Di e-mail Addräß weed nimohlß jebruch
+wääde, ih dat se beshtätish eß.
+
+Wänn_de jäz nöüjieresh jewoode beß un wellß
+weßße, wat met_de {{SITENAME}} loßß eß,
+do jang met Dingem Brauser noh:
+{{FULLURL:{{MediaWiki:Mainpage}}}}
+un luer Derr_et aan.
+
+Enne schööne Jrooß fun de {{SITENAME}}.
+
+--
+{{SITENAME}}: {{fullurl:{{Mediawiki:mainpage}}}}',
+'tryexact' => 'Forsöök en akkoraate Överëijnstemmungk:',
+'searchfulltext' => 'Söök dorrsh dä jannze Täxx',
+'createarticle' => 'Atikkel ėnnreshte',
+'scarytranscludedisabled'=> '[Et Ennbinge për Ingerwikki eß affjeschalldt]',
+'scarytranscludefailed' => '[De Schabloon „$1“ en_ze_binge hät nit jeflupp]',
+'scarytranscludetoolong'=> '[Schadt, dė URL eß ze lang]',
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackbacks för dä Atikkel hee:<br />
+„<strong>$1</strong>“
+</div>',
+'trackbackremove' => ' ([$1 Fottschmiiße])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'Trackback eß fottjeschmeßße.',
+'deletedwhileediting' => '<strong>Opjepaßß:</strong> Di Sigk wood fottjeschmeßße, nohdämm Do alld aanjefange häß,
+draan ze Änndere.',
+'confirmrecreate' => 'Dä Medmaacher [[User:$1|$1]] (→[[User talk:$1|däm_singe Klaafs]]) hät di Sigk
+fottjeschmeßße, nohdämm Do do drahn et Änndere aanjefange häß. Dä Jrund:
+: „<i>$2</i>“
+Wellß Do jäz medd_en nöüe Väsjohn di Sigk nöü aanlääje?',
+'recreate' => 'Zerrögk_holle',
+'tooltip-recreate' => 'En fottjeschmeßßenne Sigk widderholle',
+'unit-pixel' => 'px',
+'redirectingto' => 'Lëijdt öm op „[[$1]]“...',
+'confirm_purge' => 'Donn dä Zwesche_Shpëijsher fö_di Sigk forschmiiße?
+
+$1',
+'confirm_purge_button' => 'Jo — loßß jonn!',
+'youhavenewmessagesmulti'=> 'Do häßß nöü Nohrishte op $1',
+'searchcontaining' => 'Söök noh Atikkelle, wo „$1“ em Täxx fürkütt.',
+'searchnamed' => 'Söök noh Atikkelle, wo „$1“ em Name fürkütt.',
+'articletitles' => 'Atikkelle di met „$1“ aanfange',
+'hideresults' => 'Äjepniß foshtäshe',
+'displaytitle' => '(Lėngkß op di Sigk allß [[$1]])',
+'loginlanguagelabel' => 'Shprooch: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '← de Sigk do_füür',
+'imgmultipagenext' => 'de Sigk do_noh →',
+'imgmultigo' => 'Loßß jonn!',
+'imgmultigotopre' => 'Jangk op_de Sigk',
+
+# Table pager
+'ascending_abbrev' => 'opwäätß zottėet',
+'descending_abbrev' => 'raffkaz zottėet',
+'table_pager_next' => 'De näkßte Sigk',
+'table_pager_prev' => 'De Sigk do_füür',
+'table_pager_first' => 'De eezde Sigk',
+'table_pager_last' => 'De läzde Sigk',
+'table_pager_limit' => 'Zëijsh $1 pro Sigk',
+'table_pager_limit_submit' => 'Loßß jonn!',
+'table_pager_empty' => 'Këij Äjepniß',
+
+);
+
+?>
diff --git a/languages/messages/MessagesKu.php b/languages/messages/MessagesKu.php
new file mode 100644
index 000000000000..af7905388a47
--- /dev/null
+++ b/languages/messages/MessagesKu.php
@@ -0,0 +1,775 @@
+<?php
+/** Kurdish (Kurdî / كوردي)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Medya',
+ NS_SPECIAL => 'Taybet',
+ NS_MAIN => '',
+ NS_TALK => 'Nîqaş',
+ NS_USER => 'Bikarhêner',
+ NS_USER_TALK => 'Bikarhêner_nîqaş',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_nîqaş',
+ NS_IMAGE => 'Wêne',
+ NS_IMAGE_TALK => 'Wêne_nîqaş',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_nîqaş',
+ NS_TEMPLATE => 'Şablon',
+ NS_TEMPLATE_TALK => 'Şablon_nîqaş',
+ NS_HELP => 'Alîkarî',
+ NS_HELP_TALK => 'Alîkarî_nîqaş',
+ NS_CATEGORY => 'Kategorî',
+ NS_CATEGORY_TALK => 'Kategorî_nîqaş'
+);
+
+$messages = array(
+'skinpreview' => '(Pêşdîtin)',
+'sunday' => 'yekşem',
+'monday' => 'duşem',
+'tuesday' => 'Sêşem',
+'wednesday' => 'Çarşem',
+'thursday' => 'Pêncşem',
+'friday' => 'În',
+'saturday' => 'şemî',
+'january' => 'Rêbendan',
+'february' => 'reşemî',
+'march' => 'adar',
+'april' => 'avrêl',
+'may_long' => 'gulan',
+'june' => 'pûşper',
+'july' => 'Tîrmeh',
+'august' => 'tebax',
+'september' => 'rezber',
+'october' => 'kewçêr',
+'november' => 'sermawez',
+'december' => 'Berfanbar',
+'jan' => 'rêb',
+'feb' => 'reş',
+'mar' => 'adr',
+'apr' => 'avr',
+'may' => 'gul',
+'jun' => 'pşr',
+'jul' => 'tîr',
+'aug' => 'teb',
+'sep' => 'rez',
+'oct' => 'kew',
+'nov' => 'ser',
+'dec' => 'ber',
+'categories' => 'Kategorî',
+'pagecategories' => '{{PLURAL:$1|Kategorî|Kategorî}}',
+'category_header' => 'Gotarên di kategoriya "$1" de',
+'subcategories' => 'Binkategorî',
+'mainpage' => 'Destpêk',
+'portal' => 'Portala komê',
+'portal-url' => 'Project:Portala komê',
+'about' => 'Der barê',
+'aboutsite' => 'Der barê {{SITENAME}}',
+'aboutpage' => '{{SITENAME}}:Der barê',
+'article' => 'Gotar',
+'help' => 'Alîkarî',
+'helppage' => 'Help:Alîkarî',
+'bugreports' => 'Raporên çewtiyan',
+'bugreportspage' => 'Project:Raporên çewtiyan',
+'sitesupport' => 'Ji bo Weqfa Wikimedia Beş',
+'faq' => 'Pirs û Bersîv (FAQ)',
+'faqpage' => 'Project:Pirs û Bersîv',
+'edithelp' => 'Alîkarî ji bo guherandin',
+'edithelppage' => 'Help:Rûpeleke çawa biguherînim',
+'cancel' => 'Betal',
+'qbfind' => 'Bibîne',
+'qbbrowse' => 'Bigere',
+'qbedit' => 'Biguherîne',
+'qbpageoptions' => 'Ev rûpel',
+'qbmyoptions' => 'Rûpelên min',
+'qbspecialpages' => 'Rûpelên taybet',
+'moredotdotdot' => 'Zêde...',
+'mypage' => 'Rûpela min',
+'mytalk' => 'Rûpela guftûgo ya min',
+'anontalk' => 'Guftûgo ji bo vê IPê',
+'navigation' => 'Navîgasyon',
+'currentevents' => 'Bûyerên rojane',
+'currentevents-url' => 'Bûyerên rojane',
+'disclaimers' => 'Ferexetname',
+'errorpagetitle' => 'Çewtî (Error)',
+'returnto' => 'Bizivire $1.',
+'tagline' => 'Ji {{SITENAME}}',
+'search' => 'Lêbigere',
+'searchbutton' => 'Lêbigere',
+'go' => 'Gotar',
+'searcharticle' => 'Gotar',
+'history' => 'Dîroka rûpelê',
+'history_short' => 'Dîrok',
+'info_short' => 'Zanyarî',
+'printableversion' => 'Versiyon ji bo çapkirinê',
+'print' => 'Çap',
+'edit' => 'Biguherîne',
+'editthispage' => 'Vê rûpelê biguherîne',
+'delete' => 'Jê bibe',
+'deletethispage' => 'Vê rûpelê jê bibe',
+'protect' => 'Biparêze',
+'protectthispage' => 'Vê rûpelê biparêze',
+'unprotect' => 'Parastinê rake',
+'unprotectthispage' => 'Parastina vê rûpelê rake',
+'newpage' => 'Rûpela nû',
+'talkpage' => 'Vê rûpelê guftûgo bike',
+'specialpage' => 'Rûpela taybet',
+'personaltools' => 'Amûrên şexsî',
+'postcomment' => 'Şîroveyekê bişîne',
+'articlepage' => 'Li naveroka rûpelê binêre',
+'talk' => 'Guftûgo',
+'views' => 'Dîtin',
+'toolbox' => 'Qutiya amûran',
+'userpage' => 'Rûpelê vê/vî bikarhênerê/î temaşe bike',
+'viewtalkpage' => 'Guftûgoyê temaşe bike',
+'otherlanguages' => 'Zimanên din',
+'redirectedfrom' => '(Hat ragihandin ji $1)',
+'lastmodifiedat' => 'Ev rûpel carî dawî di $2, $1 de hat guherandin.',
+'viewcount' => 'Ev rûpel $1 car hat xwestin.',
+'copyright' => 'Ji bo naverokê $1 derbas dibe.',
+'protectedpage' => 'Rûpela parastî',
+'badaccess' => 'Eror li bi dest Hînan',
+'ok' => 'Temam',
+'retrievedfrom' => 'Ji "$1" hatiye standin.',
+'youhavenewmessages' => '$1 yên te hene ($2).',
+'newmessageslink' => 'Nameyên nû',
+'newmessagesdifflink' => 'Ciyawazî ji revîzyona berê re',
+'editsection' => 'biguherîne',
+'editold' => 'biguherîne',
+'toc' => 'Tabloya Naverokê',
+'showtoc' => 'nîşan bide',
+'hidetoc' => 'veşêre',
+'nstab-main' => 'Gotar',
+'nstab-user' => 'Bikarhêner',
+'nstab-media' => 'Medya',
+'nstab-special' => 'Taybet',
+'nstab-image' => 'Wêne',
+'nstab-mediawiki' => 'Mesaj',
+'nstab-template' => 'Şablon',
+'nstab-help' => 'Alîkarî',
+'nstab-category' => 'Kategorî',
+'nosuchaction' => 'Çalakiyek bi vê rengê tune',
+'nosuchspecialpage' => 'Rûpeleke taybet bi vê rengê tune',
+'error' => 'Çewtî (Error)',
+'noconnect' => 'Bibexşîne! Çend pirsgrêkên teknîkî heye, girêdan ji pêşkêşvanê (suxrekirê, server) re niha ne gengaz e. <br />
+$1',
+'enterlockreason' => 'Hoyek ji bo bestin binav bike, herweha zemaneke mezende kirî ji bo helgirtina bestinê!',
+'filerenameerror' => 'Navê faylê "$1" nebû "$2".',
+'filenotfound' => 'Dosya bi navê "$1" nehat dîtin.',
+'badarticleerror' => 'Ev çalakî di vê rûpelê de nabe.',
+'badtitle' => 'Sernivîsa nebaş',
+'perfcached' => 'The following data is cached and may not be completely up to date:',
+'viewsource' => 'Çavkanî',
+'protectedtext' => 'Ew rûpel hat qefl kirin û nayê guherandin. Ew jî sedemên xwe heye.
+Binihêre:
+[[Project:Rûpela parastî]].
+
+Hûn dikarin çavkaniya wê rûpelê bibînin û kopî bikin. Heke hûn dixwazin tiştekî zêde bikin, ji kerema xwe di rûpela guftugoyê binivîsin.',
+'logouttitle' => 'Derketina bikarhêner',
+'logouttext' => '<strong>Tu niha derketî (logged out).</strong><br />
+Tu dikarî {{SITENAME}} niha weke bikarhênerekî nediyarkirî bikarbînî, yan jî tu dikarî dîsa bi vî navê xwe yan navekî din wek bikarhêner têkevî. Bila di bîra te de be ku gengaz e hin rûpel mîna ku tu hîn bi navê xwe qeyd kiriyî werin nîşandan, heta ku tu nîşanên çavlêgerandina (browser) xwe jênebî.',
+'welcomecreation' => '<h2>Bi xêr hatî, $1!</h2><p>Hesaba te hat afirandin. Tu dikarî niha tercîhên xwe eyar bikî.',
+'loginpagetitle' => 'Qeyda bikarhêner (User login)',
+'yourname' => 'Navê te wek bikarhêner (user name)',
+'yourpassword' => 'Şîfreya te (password)',
+'yourpasswordagain' => 'Şîfreya xwe careke din binîvîse',
+'remembermypassword' => 'Şifreya min di her rûniştdemê de bîne bîra xwe.',
+'loginproblem' => '<b>Di qeyda te (login) de pirsgirêkek derket.</b><br />Careke din biceribîne!',
+'alreadyloggedin' => '<strong>Bikarhêner $1, tu jixwe têketî!</strong><br />',
+'login' => 'Têkeve (login)',
+'loginprompt' => '<b>Eger tu xwe nû qeyd bikî, nav û şîfreya xwe hilbijêre.</b> Ji bo xwe qeyd kirinê di {{SITENAME}} de divê ku \'\'cookies\'\' gengaz be.',
+'userlogin' => 'Têkeve an hesabeke nû çêke',
+'logout' => 'Derkeve (log out)',
+'userlogout' => 'Derkeve',
+'notloggedin' => 'Xwe qeyd nekir (not logged in)',
+'nologin' => 'Tu hêj ne endamî? $1.',
+'nologinlink' => 'Bibe endam',
+'createaccount' => 'Hesabê nû çêke',
+'gotaccount' => 'Hesabê te heye? $1.',
+'gotaccountlink' => 'Têkeve (login)',
+'createaccountmail' => 'bi e-name',
+'badretype' => 'Herdu şîfreyên ku te nivîsîn hevûdin nagirin.',
+'youremail' => 'E-maila te*',
+'username' => 'Navê bikarhêner:',
+'yourrealname' => 'Navê te yê rastî*',
+'yourlanguage' => 'Ziman:',
+'yournick' => 'Leqeba te (ji bo îmza)',
+'loginerror' => 'Çewtî (Login error)',
+'prefs-help-email' => '* E-mail (optional): Enables others to contact you through your user or user_talk page without the need of revealing your identity.',
+'nocookieslogin' => 'Ji bo qeydkirina bikarhêneran {{SITENAME}} "cookies" bi kar tîne. Te fonksiyona "cookies" girt. Ji kerema xwe "cookies" gengaz bike û careke din biceribîne.',
+'noname' => 'Navê ku te nivîsand derbas nabe.',
+'loginsuccesstitle' => 'Têketin serkeftî!',
+'loginsuccess' => 'Tu niha di {{SITENAME}} de qeydkirî yî wek "$1".',
+'nosuchuser' => 'Bikarhênera/ê bi navê "$1" tune. Navê rast binivîse an bi vê formê <b>hesabeke nû çêke</b>. (Ji bo hevalên nû "Têkeve" çênabe!)',
+'wrongpassword' => 'Şifreya ku te nivîsand şaş e. Ji kerema xwe careke din biceribîne.',
+'mailmypassword' => 'Şîfreyeke nû bi e-mail ji min re bişîne',
+'noemail' => 'Navnîşana bikarhênerê/î "$1" nehat tomar kirine.',
+'passwordsent' => 'Ji navnîşana e-mail ku ji bo "$1" hat tomarkirin şîfreyekê nû hat şandin. Vê bistîne û dîsa têkeve.',
+'acct_creation_throttle_hit'=> 'Biborîne! Te hesab $1 vekirine. Tu êdî nikarî hesabên din vekî.',
+'bold_sample' => 'Nivîsa estûr',
+'bold_tip' => 'Nivîsa estûr',
+'italic_sample' => 'Nivîsa xwar (îtalîk)',
+'italic_tip' => 'Nivîsa xwar (îtalîk)',
+'link_sample' => 'Navê lînkê',
+'link_tip' => 'Lînka hundir',
+'extlink_sample' => 'http://www.minak.com navê lînkê',
+'extlink_tip' => 'Lînka derve (http:// di destpêkê de ji bîr neke)',
+'headline_sample' => 'Nivîsara sernameyê',
+'headline_tip' => 'Sername asta 2',
+'nowiki_sample' => 'Nivîs ku nebe formatkirin',
+'image_sample' => 'Mînak.jpg',
+'image_tip' => 'Wêne li hundirê gotarê',
+'media_sample' => 'Mînak.ogg',
+'sig_tip' => 'Îmze û demxeya wext ya te',
+'hr_tip' => 'Rastexêza berwarî (kêm bi kar bîne)',
+'summary' => 'Kurte û çavkanî (Te çi kir?)',
+'subject' => 'Mijar/sernivîs',
+'minoredit' => 'Ev guheraniyekê biçûk e',
+'watchthis' => 'Vê gotarê bişopîne',
+'savearticle' => 'Rûpelê tomar bike',
+'preview' => 'Pêşdîtin',
+'showpreview' => 'Pêşdîtin',
+'showdiff' => 'Guherandinê nîşan bide',
+'anoneditwarning' => 'Tu ne têketî. Navnîşana IP ya te wê di dîroka guherandina vê rûpelê de bê tomar kirin.',
+'blockedtitle' => 'Bikarhêner hat asteng kirin',
+'blockedtext' => 'Navê bikarhêner an jî navnîşana IP ya te ji aliyê $1 hat asteng kirin. Sedema vê ev e:<br />\'\'$2\'\'<br />Tu dikarî bi $1 an yek ji [[Project:Koordînator|koordînatorên din]] re ser vê blokê guftûgo bikî.
+
+Têbînî: Tu nikarî fonksiyona "Ji vê bikarhêner re E-mail bişîne" bi kar bîne eger te navnîşana email a xwe di "[[Special:Preferences|Tercîhên min]]" de nenivîsand.
+
+Navnîşana te ya IP $3 ye. Ji kerema xwe eger pirsên te hebe vê navnîşanê bibêje.',
+'whitelistedittext' => 'Ji bo guherandina rûpelan, $1 pêwîst e.',
+'loginreqtitle' => 'Têketin pêwîst e',
+'loginreqlink' => 'login',
+'accmailtitle' => 'Şîfre hat şandin.',
+'accmailtext' => 'Şîfreya \'$1\' hat şandin ji $2 re.',
+'newarticle' => '(Nû)',
+'newarticletext' => '<div style="font-size:small;color:#003333;border-width:1px;border-style:solid;border-color:#aaaaaa;padding:3px">
+Ev rûpel hîn tune. Eger tu bixwazî vê rûpelê çêkî, dest bi nivîsandinê bike û piştre qeyd bike. \'\'\'Wêrek be\'\'\', biceribîne!<br />
+Ji bo alîkarî binêre: [[Help:Alîkarî|Alîkarî]].<br />
+Eger tu bi şaştî hatî, bizivire rûpela berê.
+</div>',
+'anontalkpagetext' => '----
+\'\'Ev rûpela guftûgo ye ji bo bikarhênerên nediyarkirî ku hîn hesabekî xwe çênekirine an jî bikarnaînin. Ji ber vê yekê divê em wan bi [[IP address|navnîşana IP]] ya hejmarî nîşan bikin. Navnîşaneke IP dikare ji aliyê gelek kesan ve were bikaranîn. Heger tu bikarhênerekî nediyarkirî bî û bawerdikî ku nirxandinên bê peywend di der barê te de hatine kirin ji kerema xwe re [[Special:Userlogin|hesabekî xwe veke an jî têkeve]] da ku tu xwe ji tevlîheviyên bi bikarhênerên din re biparêzî.\'\'',
+'noarticletext' => 'Ev rûpel niha vala ye, tu dikarî
+[[Special:Search/{{PAGENAME}}|Di nav gotarên din de li "{{PAGENAME}}" bigere]] an
+[{{fullurl:{{FULLPAGENAME}}|action=edit}} vê rûpelê biguherînî].',
+'updated' => '(Hat taze kirin)',
+'note' => '<strong>Not:</strong>',
+'previewnote' => 'Ji bîr neke ku ev bi tenê çavdêriyek e, ev rûpel hîn nehat qeyd kirin!',
+'editing' => 'Biguherîne: "$1"',
+'editinguser' => 'Biguherîne: "$1"',
+'editingsection' => 'Tê guherandin: $1 (beş)',
+'editingcomment' => '$1 (şîrove) tê guherandin.',
+'editconflict' => 'Têkçûna guherandinan: $1',
+'explainconflict' => 'Ji dema te dest bi guherandinê kir heta niha kesekê/î din ev rûpel guherand.
+
+Jor guhartoya heyî tê dîtîn. Guherandinên te jêr tên nîşan dan. Divê tû wan bikî yek. Heke niha tomar bikî, <b>bi tene</b> nivîsara qutiya jor wê bê tomarkirin. <p>',
+'yourtext' => 'Nivîsara te',
+'storedversion' => 'Versiyona qeydkirî',
+'editingold' => '<strong>HÎŞYAR: Tu ser revîsyoneke kevn a vê rûpelê dixebitî.
+Eger tu qeyd bikî, hemû guhertinên ji vê revîzyonê piştre winda dibin.
+</strong>',
+'yourdiff' => 'Ciyawazî',
+'copyrightwarning' => 'Dîqat bike: Hemû tevkariyên {{SITENAME}} di bin $2 de tên belav kirin (ji bo hûragahiyan li $1 binêre). Eger tu nexwazî ku nivîsên te bê dilrehmî bên guherandin û li gora keyfa herkesî bên belavkirin, li vir neweşîne.<br />
+Tu soz didî ku te ev bi xwe nivîsand an jî ji çavkaniyekê azad an geliyane \'\'(public domain)\'\' girt.
+<strong>BERHEMÊN MAFÊN WAN PARASTÎ (©) BÊ DESTÛR NEWEŞÎNE!</strong>',
+'longpagewarning' => 'HIŞYAR: Drêjahiya vê rûpelê $1 kB (kilobayt) e, ev pir e. Dibe ku çend \'\'browser\'\'
+baş nikarin rûpelên ku ji 32 kB drêjtir in biguherînin. Eger tu vê rûpelê beş beş bikî gelo ne çêtir e?',
+'protectedpagewarning' => 'ŞIYARÎ: Ev rûpel hat qefl kirin. Bi tenê bikarhênerên ku xwediyên mafan "sysop" ne dikarin vê rûpelê biguherînin.<br />
+Be sure you are following the
+[[Project:Protected page guidelines|protected page guidelines]].',
+'revhistory' => 'Dîroka revîzyonan',
+'nohistory' => 'Ew rûpel dîroka guherandinê tune.',
+'revnotfound' => 'Revîzyon nehat dîtin',
+'currentrev' => 'Revîzyona niha',
+'revisionasof' => 'Revîzyon a $1',
+'previousrevision' => '←Rêvîzyona kevintir',
+'nextrevision' => 'Revîzyona nûtir→',
+'currentrevisionlink' => 'Revîzyona niha nîşan bide',
+'cur' => 'ferq',
+'next' => 'pêş',
+'last' => 'berê',
+'orig' => 'orîj',
+'histlegend' => 'Legend: (ferq) = cudayî nav vê û versiyon a niha,
+(berê) = cudayî nav vê û yê berê vê, B = guhêrka biçûk',
+'histfirst' => 'Kevintirîn',
+'histlast' => 'Nûtirîn',
+'rev-delundel' => 'nîşan bide/veşêre',
+'difference' => '(Ciyawaziya nav revîzyonan)',
+'lineno' => 'Dêrra $1:',
+'compareselectedversions'=> 'Guhartoyan Helsengêne',
+'searchresults' => 'Encamên lêgerînê',
+'searchresulttext' => 'Ji bo zêdetir agahî der barê lêgerînê di {{SITENAME}} de, binêre [[Project:Searching|Searching {{SITENAME}}]].',
+'searchsubtitle' => 'Ji bo query "[[:$1]]"',
+'searchsubtitleinvalid' => 'Ji bo query "$1"',
+'titlematches' => 'Dîtinên di sernivîsên gotaran de',
+'notitlematches' => 'Di nav sernivîsan de nehat dîtin.',
+'textmatches' => 'Dîtinên di nivîsara rûpelan de',
+'notextmatches' => 'Di nivîsarê de nehat dîtin.',
+'prevn' => '$1 paş',
+'nextn' => '$1 pêş',
+'viewprevnext' => '($1) ($2) ($3).',
+'showingresults' => '<b>$1</b> encam, bi #<b>$2</b> dest pê dike.',
+'showingresultsnum' => '<b>$3</b> encam, bi #<b>$2</b> dest pê dike.',
+'powersearch' => 'Lêbigere',
+'powersearchtext' => 'Lêgerîn di nav cihên navan de:<br />
+$1<br />
+$2 Ragihandinan nîşan bide Lêbigere: $3 $9',
+'searchdisabled' => '<p>Tu dikarî li {{SITENAME}} bi Google an Yahoo! bigere. Têbînî: Dibe ku encamen lêgerîne ne yên herî nû ne.
+</p>',
+'blanknamespace' => '(Serekî)',
+'preferences' => 'Tercîhên min',
+'prefsnologin' => 'Xwe qeyd nekir',
+'changepassword' => 'Şîfre biguherîne',
+'skin' => 'Pêste',
+'datetime' => 'Dem û rêkewt',
+'prefs-personal' => 'Agahiyên bikarhênerê/î',
+'prefs-rc' => 'Guherandinên dawî',
+'prefs-misc' => 'Eyaren cuda',
+'saveprefs' => 'Tercîhan qeyd bike',
+'oldpassword' => 'Şîfreya kevn',
+'newpassword' => 'Şîfreya nû',
+'retypenew' => 'Şîfreya nû careke din binîvîse',
+'rows' => 'Rêz',
+'columns' => 'stûn',
+'searchresultshead' => 'Eyarên encamên lêgerinê',
+'savedprefs' => 'Tercîhên te qeyd kirî ne.',
+'default' => 'asayî',
+'files' => 'Dosya',
+'changes' => 'guherandin',
+'recentchanges' => 'Guherandinên dawî',
+'recentchangestext' => '<!-- please translate: -->Track the most recent changes to the wiki on this page.',
+'rcnote' => 'Jêr <strong>$1</strong> guherandinên dawî di <strong>$2</strong> rojên dawî de, ji $3 şûnde tên nîşan dan.',
+'rclistfrom' => 'an jî guherandinên ji $1 şûnda nîşan bide.',
+'rclinks' => '$1 guherandinên di $2 rojên dawî de nîşan bide<br />$3',
+'diff' => 'ciyawazî',
+'hist' => 'dîrok',
+'hide' => 'veşêre',
+'show' => 'nîşan bide',
+'minoreditletter' => 'B',
+'newpageletter' => 'Nû',
+'upload' => 'Wêneyê barbike',
+'uploadbtn' => 'Dosyayê barbike',
+'uploadnologin' => 'Xwe qeyd nekir',
+'uploadnologintext' => 'Ji bo barkirina wêneyan divê ku tu [[Special:Userlogin|têkevî]].',
+'uploadtext' => 'Berê tu wêneyên nû bar bikî, ji bo dîtin an vedîtina wêneyên ku ji xwe hene binêre: [[Special:Imagelist|lîsteya wêneyên barkirî]]. Herwisa wêneyên ku hatine barkirin an jî jê birin li vir dikarî bibînî: [[Special:Log/upload|reşahiya barkiriyan]].
+
+Yek ji lînkên jêr ji bo bikarhînana wêne an faylê di gotarê de bikar bihîne:
+
+* \'\'\'<nowiki>[[{{ns:Image}}:File.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[{{ns:Image}}:File.png|alt text]]</nowiki>\'\'\'
+anjî ji bo faylên dengî
+* \'\'\'<nowiki>[[{{ns:Media}}:File.ogg]]</nowiki>\'\'\'',
+'filename' => 'Navê dosyayê',
+'filedesc' => 'Kurte',
+'fileuploadsummary' => 'Kurte:',
+'filesource' => 'Çavkanî',
+'copyrightpage' => 'Project:Mafên nivîsanê',
+'copyrightpagename' => 'Mafên nivîsanê',
+'uploadedfiles' => 'Dosyayên bar kirî',
+'ignorewarning' => 'Hişyarê qebûl neke û dosyayê qeyd bike.',
+'ignorewarnings' => 'goh nede hîşyaran!',
+'minlength' => 'Navê wêne bi lanî kêm dive ji 3 tîpan pêtir be.',
+'badfilename' => 'Navê wêneyê hat guherandin û bû "$1".',
+'badfiletype' => 'Formata ".$1" naye tawsiye kirin. (Ji bo wêne .png û .jpg tên tawsiye kirin.)',
+'largefile' => 'Pêşniyara me ewe ku wêneyan ji $1 bayt mezintir nebe, ew wêne $2 bayt e.',
+'successfulupload' => 'Barkirin serkeftî',
+'fileuploaded' => 'Barkirina dosyaya bi navê $1 serkeftî.
+Ji kerema xwe, biçe: $2 û agahî li der barê dosyayê binivîse (ji ku derê hat girtin, kîngê hat çêkirin, kê çêkir û hwd.)
+
+Heke ev dosya wêneyek be, bi vî rengî bi kar bîne:
+<br />
+<tt><nowiki>[[{{ns:Image}}:$1|thumb|Binnivîs]]</nowiki></tt>',
+'uploadwarning' => 'Hişyara barkirinê',
+'savefile' => 'Dosyayê tomar bike',
+'uploadedimage' => '"$1" barkirî',
+'destfilename' => 'Navê faylê xwastî',
+'imagelist' => 'Listeya wêneyan',
+'imagelisttext' => 'Below is a list of $1 files sorted $2.',
+'ilsubmit' => 'Lêbigere',
+'showlast' => '$1 wêneyên dawî bi rêz kirî $2 nîşan bide.',
+'byname' => 'li gor navê',
+'bydate' => 'li gor dîrokê',
+'bysize' => 'li gor mezinayiyê',
+'imghistory' => 'Dîroka wêneyê',
+'deleteimg' => 'jêbibe',
+'imagelinks' => 'Lînkên wêneyê',
+'linkstoimage' => 'Di van rûpelên de lînkek ji vê wêneyê re heye:',
+'nolinkstoimage' => 'Rûpeleke ku ji vê wêneyê re lînk dike tune.',
+'download' => 'dabezandin',
+'statistics' => 'Statîstîk',
+'sitestats' => 'Statîstîkên sîteyê',
+'userstats' => 'Statistîkên bikarhêneran',
+'sitestatstext' => 'Di \'\'database\'\' de \'\'\'$1\'\'\' rûpel hene.
+Tê de rûpelên guftûgoyê, rûpelên der barê {{SITENAME}}, rûpelên pir kurt (stub), rûpelên ragihandinê (redirect) û rûpelên din ku qey ne gotar in hene.
+Derve wan, \'\'\'$2\'\'\' rûpel hene ku qey \'\'\'gotarên rewa\'\'\' ne.
+
+\'\'\'$8\'\'\' dosya hatin barkirin.
+
+Ji afirandina Wîkiyê heta roja îro \'\'\'$3\'\'\' carî rûpel hatin mezekirin û \'\'\'$4\'\'\' carî rûpel hatin guherandin
+since the wiki was setup.
+Ji ber wê di nîvî de her rûpel \'\'\'$5\'\'\' carî hatiye guherandin, û nîspeta dîtun û guherandinan \'\'\'$6\'\'\' e.
+
+Dirêjahiya [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] \'\'\'$7\'\'\' e.',
+'userstatstext' => '\'\'\'$1\'\'\' bikarhênerên qeydkirî hene. Ji wan \'\'\'$2\'\'\' (an \'\'\'$4\'\'\') administrator/koordînator in. (Binêre $3).',
+'disambiguations' => 'Rûpelên cudakirinê',
+'brokenredirects' => 'Ragihandinên jê bûye',
+'nbytes' => '$1 bayt',
+'nlinks' => '$1 lînk',
+'nmembers' => '$1 {{PLURAL:$1|endam|endam}}',
+'nviews' => '$1 {{PLURAL:$1|dîtin|dîtin}}',
+'lonelypages' => 'Rûpelên sêwî',
+'uncategorizedpages' => 'Rûpelên bê kategorî',
+'uncategorizedcategories'=> 'Kategoriyên bê kategorî',
+'unusedcategories' => 'Kategoriyên ku nayên bi kar anîn',
+'unusedimages' => 'Wêneyên ku nayên bi kar anîn',
+'popularpages' => 'Rûpelên populer',
+'wantedcategories' => 'Kategoriyên tên xwestin',
+'wantedpages' => 'Rûpelên ku tên xwestin',
+'allpages' => 'Hemû rûpel',
+'randompage' => 'Rûpelek bi helkeft',
+'shortpages' => 'Rûpelên kurt',
+'longpages' => 'Rûpelên dirêj',
+'deadendpages' => 'Rûpelên bê dergeh',
+'listusers' => 'Lîsteya bikarhêneran',
+'specialpages' => 'Rûpelên taybet',
+'spheading' => 'Rûpelên taybet ji bo hemû bikarhêneran',
+'recentchangeslinked' => 'Guherandinên peywend',
+'newpages' => 'Rûpelên nû',
+'ancientpages' => 'Gotarên kevintirîn',
+'move' => 'Navê rûpelê biguherîne',
+'movethispage' => 'Vê rûpelê bigerîne',
+'booksources' => 'Çavkaniyên pirtûkan',
+'categoriespagetext' => 'Di vê wîkiyê de ev kategorî hene:',
+'booksourcetext' => 'Li jêr lîsteyek ji linkan bo sîteyên din ku pertûkên nû û destî dû difrotin hatiye û belkî zanyarî yên pêtir jî derbarî wan pertûkên ku tu dixwazî hebin.',
+'alphaindexline' => '$1 heta $2',
+'version' => 'Guherto',
+'log' => 'Reşahiyan',
+'nextpage' => 'Rûpela pêşî ($1)',
+'allpagesfrom' => 'Pêşdîtina rûpelan bi dest pê kirin ji',
+'allarticles' => 'Hemû gotar',
+'allinnamespace' => 'Hemû rûpelan ($1 boşahî a nav)',
+'allpagesprev' => 'Pêş',
+'allpagesnext' => 'Paş',
+'allpagessubmit' => 'Biçe',
+'allpagesprefix' => 'Nîşan bide rûpelên bi pêşgira:',
+'mailnologin' => 'Navnîşan neşîne',
+'emailuser' => 'Ji vê/î bikarhênerê/î re e-name bişîne',
+'emailpage' => 'E-name bikarhêner',
+'defemailsubject' => '{{SITENAME}} e-name',
+'noemailtitle' => 'Navnîşana e-name tune',
+'emailfrom' => 'Ji',
+'emailto' => 'Bo',
+'emailsubject' => 'Mijar',
+'emailmessage' => 'Name',
+'emailsend' => 'Bişîne',
+'emailsent' => 'E-name hat şandin',
+'emailsenttext' => 'E-nameya te hat şandin.',
+'watchlist' => 'Lîsteya min ya şopandinê',
+'watchlistfor' => '(ji bo \'\'\'$1\'\'\')',
+'watchnologin' => 'Xwe qeyd nekir',
+'addedwatch' => 'Hat îlawekirinî listeya şopandinê',
+'addedwatchtext' => 'Rûpela "$1" çû ser [[Special:Watchlist|lîsteya te ya şopandinê]].
+Li dahatû de her guhartoyek li wê rûpelê û rûpela guftûgo ya wê were kirin li vir dêt nîşan dan,
+
+Li rûpela [[Special:Recentchanges|Guherandinên dawî]] jî ji bo hasan dîtina wê, ew rûpel bi \'\'\'Nivîsa estûr\'\'\' dê nîşan dayîn.
+
+
+<p>Her dem tu bixwazî ew rûpel li nav lîsteya te ya şopandinê derbikî, li ser wê rûpelê, klîk bike "êdî neşopîne".</p>',
+'removedwatchtext' => 'The page "$1" has been removed from your watchlist.',
+'watch' => 'Bişopîne',
+'watchthispage' => 'Vê rûpelê bişopîne',
+'unwatch' => 'Êdî neşopîne',
+'notanarticle' => 'Ne gotar e',
+'watchdetails' => '* $1 rûpel tên şopandin, rûpelên guftûgoyê nayên jimartin
+* [[Special:Watchlist/edit|Lîsteya şopandinê bibîne û temam bike]]
+* [[Special:Watchlist/clear|Hemû rûpelan derxe]]',
+'watchlistcontains' => 'Di lîsteya şopandina te de $1 rûpel hene.',
+'couldntremove' => '\'$1\' naye jêbirin...',
+'wlhideshowown' => '$1 my edits.',
+'wlhideshowbots' => '$1 bot edits.',
+'wldone' => 'Çêbû.',
+'enotif_newpagetext' => 'Ev rûpeleke nû ye.',
+'changed' => 'guhart',
+'created' => 'afirandî',
+'deletepage' => 'Rûpelê jê bibe',
+'confirm' => 'Pesend bike',
+'excontent' => 'Naveroka berê: \'$1\'',
+'excontentauthor' => 'Nawerokê wê rûpelê ew bû: \'$1\' (û tenya bikarhêner \'$2\' bû)',
+'exbeforeblank' => 'Nawerok berî betal kirinê ew bû: \'$1\'',
+'exblank' => 'rûpel vala bû',
+'confirmdelete' => 'Teyîda jêbirinê',
+'deletesub' => '("$1" tê jêbirin)',
+'historywarning' => 'Hîşyar: Ew rûpel ku tu dixwazî jê bibî dîrokek heye:',
+'actioncomplete' => 'Çalakî temam',
+'deletedtext' => '"$1" hat jêbirin. Ji bo qeyda rûpelên ku di dema nêzîk de hatin jêbirin binêre $2.',
+'deletedarticle' => '"$1" hat jêbirin',
+'dellogpage' => 'Reşahiya_jêbirin',
+'dellogpagetext' => 'Li jêr lîsteyek ji jêbirinên dawî heye.',
+'deletionlog' => 'reşahiya jêbirin',
+'deletecomment' => 'Sedema jêbirinê',
+'rollback_short' => 'Bizivirîne pêş',
+'rollbacklink' => 'bizivirîne pêş',
+'cantrollback' => 'Guharto naye vegerandin; bikarhêrê dawî, \'\'\'tenya\'\'\' nivîskarê wê rûpelê ye.',
+'alreadyrolled' => 'Guherandina dawiya [[:$1]]
+bi [[User:$2|$2]] ([[User talk:$2|guftûgo]]) venizivre; keseke din wê rûpelê zivrandiye an guherandiye.
+
+Guhartoya dawî bi [[User:$3|$3]] ([[User talk:$3|guftûgo]]).',
+'revertpage' => 'Guherandina $2 hat betal kirin, vegerand guhartoya dawî ya $1',
+'protectlogpage' => 'Reşahiya _parastiyan',
+'protectedarticle' => 'parastî [[$1]]',
+'confirmprotecttext' => 'Tu bi rastî dixwazî wê rûpelê biparêzî?',
+'confirmprotect' => 'Parastinê teyîd bike',
+'protectcomment' => 'Sedema parastinê',
+'unprotectcomment' => 'Sedem ji bo rakirina parastinê',
+'restriction-edit' => 'Biguherîne',
+'restriction-move' => 'Nav biguherîne',
+'undeletebtn' => 'Restore!',
+'namespace' => 'Boşahiya nav:',
+'invert' => 'Hilbijardinê pêçewane bike',
+'contributions' => 'Beşdariyên vê bikarhêner',
+'mycontris' => 'Beşdariyên min',
+'contribsub' => 'Ji bo $1',
+'uclinks' => '$1 guherandinên dawî; $2 rojên dawî',
+'uctop' => ' (ser)',
+'newbies' => 'ecemî',
+'sp-contributions-newest'=> 'Nûtirîn',
+'sp-contributions-oldest'=> 'Kevintirîn',
+'sp-contributions-newer'=> '$1 yên nûtir',
+'sp-contributions-older'=> '$1 yên kevintir',
+'whatlinkshere' => 'Lînkên ji vê rûpelê re',
+'notargettitle' => 'Hedef tune',
+'linklistsub' => '(Listeya lînkan)',
+'linkshere' => 'Di van rûpelên de lînkek ji vê re heye:',
+'nolinkshere' => 'Ji hîç rûpel ji vê re lînk tune.',
+'isredirect' => 'rûpela ragihandinê',
+'blockip' => 'Bikarhêner asteng bike',
+'ipbreason' => 'Sedem',
+'ipbsubmit' => 'Vê bikarhêner asteng bike',
+'badipaddress' => 'Bikarhêner bi vî navî tune',
+'blockipsuccesssub' => 'Blok serkeftî',
+'blockipsuccesstext' => '"$1" hat asteng kirin.
+<br />Bibîne [[Special:Ipblocklist|Lîsteya IP\'yan hatî asteng kirin]] ji bo lîsteya blokan.',
+'blocklistline' => '$1, $2 $3 asteng kir ($4)',
+'blocklink' => 'asteng bike',
+'unblocklink' => 'betala astengê',
+'contribslink' => 'Beşdarî',
+'autoblocker' => 'Otomatîk hat bestin jiberku IP-ya we û ya "[[User:$1|$1]]" yek in. Sedem: "\'\'\'$2\'\'\'"',
+'blocklogpage' => 'Reşahiya_asteng kiriyan',
+'blocklogentry' => '"[[$1]]" ji bo dema $2 hatiye asteng kirin',
+'unblocklogentry' => 'astenga "$1" hat betal kirin',
+'proxyblocksuccess' => 'Çêbû.',
+'makesysopname' => 'Navê bikarhêner:',
+'rightsnone' => '(tune)',
+'movepage' => 'Vê rûpelê bigerîne',
+'movepagetalktext' => 'Rûpela \'\'\'guftûgoyê giredayî ji vê rûpelê re wê bê gerandin jî.
+\'\'\'Îstisna:\'\'\'
+*You are moving the page across namespaces,
+*A non-empty talk page already exists under the new name, or
+*You uncheck the box below.
+
+In those cases, you will have to move or merge the page manually if desired.',
+'movearticle' => 'Rûpelê bigerîne',
+'movenologin' => 'Xwe qeyd nekir',
+'movenologintext' => 'Tu dive bikarhênereke qeydkirî bî û [[Special:Userlogin|werî nav sîstemê]]
+da bikarî navê wê rûpelê biguherînî.',
+'newtitle' => 'Sernivîsa nû',
+'movepagebtn' => 'Vê rûpelê bigerîne',
+'pagemovedsub' => 'Gerandin serkeftî',
+'pagemovedtext' => 'Rûpela "[[$1]]" çû cihê "[[$2]]".',
+'articleexists' => 'Rûpela bi vî navî heye, an navê ku te hilbijart derbas nabe. Navekî din hilbijêre.',
+'movedto' => 'bû',
+'movetalk' => 'Rûpela \'\'\'guftûgo\'\'\' ya wê jî bigerîne, eger gengaz be.',
+'1movedto2' => '$1 çû cihê $2',
+'1movedto2_redir' => '$1 çû cihê $2 ser redirect',
+'movelogpage' => 'Reşahiya nav guherandin',
+'movelogpagetext' => 'Li jêr lîsteyek ji rûpelan ku navê wan hatiye guherandin heye.',
+'movereason' => 'Sedem',
+'allmessages' => 'Hemû mesajên sîstemê',
+'allmessagesname' => 'Nav',
+'allmessagescurrent' => 'Texta niha',
+'allmessagestext' => 'Ev lîsteya hemû mesajên di namespace a MediaWiki: de ye.',
+'allmessagesnotsupportedUI'=> 'Your current interface language <b>$1</b> is not supported by Special:Allmessages at this site.',
+'allmessagesnotsupportedDB'=> '\'\'\'Special:Allmessages\'\'\' cannot be used because \'\'\'$wgUseDatabaseMessages\'\'\' is switched off.',
+'thumbnail-more' => 'Mezin bike',
+'importnotext' => 'Vala an nivîs tune',
+'tooltip-diff' => 'Show which changes you made to the text. [alt-v]',
+'tooltip-compareselectedversions'=> 'Cudatiyên guhartoyên hilbijartî yên vê rûpelê bibîne. [alt-v]',
+'monobook.css' => '*.rtl
+ {
+ dir:rtl;
+ text-align:right;
+ font-family: "Tahoma", "Unikurd Web", "Arial Unicode MS", "DejaVu Sans", "Lateef", "Scheherazade", "ae_Rasheeq", sans-serif, sans;
+ }
+
+ /*Make the site more suitable for Soranî users */
+ h1 {font-family: "Tahoma", "Arial Unicode MS", sans-serif, sans, "Unikurd Web", "Scheherazade";}
+ h2 {font-family: "Tahoma", "Arial Unicode MS", sans-serif, sans, "Unikurd Web", "Scheherazade";}
+ h3 {font-family: "Tahoma", "Arial Unicode MS", sans-serif, sans, "Unikurd Web", "Scheherazade";}
+ body {font-family: "Tahoma", "Arial Unicode MS", sans-serif, sans, "Unikurd Web", "Scheherazade";}
+ textarea {font-family: Lucida Console, Tahoma;}
+ pre {font-family: Lucida Console, Tahoma;}
+
+ /* extra buttons for edit dialog (from bg:)*/
+ #my-buttons {
+ padding: 0.5em;
+ }
+ #my-buttons a {
+ color: black;
+ background-color: #ccddee;
+ font-weight: bold;
+ font-size: 0.9em;
+ text-decoration: none;
+ border: thin #006699 outset;
+ padding: 0 0.1em 0em 0.1em;
+ }
+ #my-buttons a:hover, #my-buttons a:active {
+ background-color: #bbccdd;
+ border-style: inset;
+ }
+ .messagebox {
+ border: 1px solid #aaaaaa;
+ background-color: #f9f9f9;
+ width: 80%;
+ margin: 0 auto 1em auto;
+ padding: 0.5em;
+ text-align: justify;
+ }
+ .messagebox.merge {
+ border: 1px solid #cf9fff;
+ background-color: #f5edf5;
+ text-align: center;
+ }
+ .messagebox.cleanup {
+ border: 1px solid #9f9fff;
+ background-color: #efefff;
+ text-align: center;
+ }
+ .messagebox.standard-talk {
+ border: 1px solid #c0c090;
+ background-color: #f8eaba;
+ }',
+'anonymous' => 'Bikarhênera/ê nediyarkirî ya/yê {{SITENAME}}',
+'siteuser' => 'Bikarhênera/ê $1 a/ê {{SITENAME}}',
+'and' => 'û',
+'others' => 'ên din',
+'siteusers' => 'Bikarhênerên $1 yên {{SITENAME}}',
+'subcategorycount' => 'Di vê kategoriyê de $1 binkategorî hene.',
+'categoryarticlecount' => 'Di vê kategoriyê de $1 gotar hene.',
+'listingcontinuesabbrev'=> ' dewam',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Rûpela min a şexsî\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'The user page for the ip you\'re editing as\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Rûpela guftûgo ya min\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussion about edits from this ip address\');
+ ta[\'pt-preferences\'] = new Array(\'\',\',Tercîhên min\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'The list of pages you\'re monitoring for changes.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Lîsteya tevkariyên min\');
+ ta[\'pt-login\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Derkeve (Log out)\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'guftûgo û şîrove ser vê rûpelê\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Vê rûpelê biguherîne! Berê qeydkirinê bişkoka "Pêşdîtin" bi kar bîne.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Beşekê zêde bike.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'This page is protected. You can view its source.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Versyonên berê yên vê rûpelê.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Vê rûplê biparêze\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Vê rûpelê jê bibe\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Restore the edits done to this page before it was deleted\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Navekî nû bide vê rûpelê\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'You don\'t have the permissions to move this page\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Add this page to your watchlist\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Remove this page from your watchlist\');
+ ta[\'search\'] = new Array(\'f\',\'Li vê wikiyê bigêre\');
+ ta[\'p-logo\'] = new Array(\'\',\'Destpêk\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Biçe Destpêkê\');
+ ta[\'n-portal\'] = new Array(\'\',\'About the project, what you can do, where to find things\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Find background information on current events\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'The list of recent changes in the wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Load a random page\');
+ ta[\'n-help\'] = new Array(\'\',\'Bersivên ji bo pirsên te.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Support us\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lîsteya hemû rûpelên ku ji vê re grêdidin.\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Recent changes in pages linking to this page\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed for this page\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed for this page\');
+ ta[\'t-contributions\'] = new Array(\'\',\'View the list of contributions of this user\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Jê re name bişîne\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Upload images or media files\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'List of all special pages\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'View the content page\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Rûpela bikarhênerê/î temaşe bike\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'View the media page\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'This is a special page, you can\'t edit the page itself.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'View the project page\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'View the image page\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'View the system message\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'View the template\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'View the help page\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'View the category page\');
+
+/*RTL and LTR*/
+ function bidiSwitchSetup() {
+ var editform = document.getElementById("wpTextbox1");
+ if (editform == null) {
+ return;
+ }
+
+ bidiAddButton(editform, "Default", function(style) {
+ style.direction = "inherit";
+ style.unicodeBidi = "inherit";
+ });
+ bidiAddButton(editform, "dir=ltr", function(style) {
+ style.direction = "ltr";
+ });
+ bidiAddButton(editform, "dir=rtl", function(style) {
+ style.direction = "rtl";
+ });
+ bidiAddButton(editform, "bidi=normal", function(style) {
+ style.unicodeBidi = "normal";
+ });
+ bidiAddButton(editform, "bidi=override", function(style) {
+ style.unicodeBidi = "bidi-override";
+ });
+ }
+
+ function bidiAddButton(before, label, action) {
+ var button = document.createElement("input");
+ button.type = "button";
+ button.value = label;
+ button.onclick = function(event) {
+ var box = document.getElementById("wpTextbox1");
+ if (box == null) {
+ alert("Broken! Edit box missing.");
+ } else {
+ //var style = document.getOverrideStyle(box, null);
+ var style = box.style;
+ action(style);
+ }
+ }
+ before.parentNode.insertBefore(button, before);
+ }
+
+ hookEvent(\'load\', bidiSwitchSetup);',
+'previousdiff' => '← Ciyawaziya pêştir',
+'nextdiff' => 'Ciyawaziya paştir →',
+'thumbsize' => 'Thumbnail size :',
+'showbigimage' => 'Versyona mezin bibîne an daxe ($1x$2, $3 KB).',
+'newimages' => 'Pêşangeha wêneyên nû',
+'specialloguserlabel' => 'Bikarhêner:',
+'recentchangesall' => 'hemû',
+'imagelistall' => 'hemû',
+'watchlistall1' => 'hemû',
+'watchlistall2' => 'hemû',
+'namespacesall' => 'Hemû',
+'createarticle' => 'Gotarê biafirîne',
+'scarytranscludefailed' => '[Anîna şablona $1 biserneket; biborîne]',
+'deletedwhileediting' => 'Hîşyar: Piştî te guherandinê dest pê kir ew rûpel hat jêbirin!',
+'confirm_purge_button' => 'Temam',
+'loginlanguagelabel' => 'Ziman: $1',
+);
+?>
diff --git a/languages/messages/MessagesKv.php b/languages/messages/MessagesKv.php
new file mode 100644
index 000000000000..847676d5dd2c
--- /dev/null
+++ b/languages/messages/MessagesKv.php
@@ -0,0 +1,9 @@
+<?php
+/** Komi (Коми)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'ru';
+?>
diff --git a/languages/messages/MessagesLa.php b/languages/messages/MessagesLa.php
new file mode 100644
index 000000000000..ee0c8b90dee2
--- /dev/null
+++ b/languages/messages/MessagesLa.php
@@ -0,0 +1,853 @@
+<?php
+/** Latin (lingua Latina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Nullus', 'Constituere a sinistra', 'Constituere a dextra', 'Innens a sinistra'
+);
+
+$skinNames = array(
+ 'standard' => 'Norma',
+ 'nostalgia' => 'Nostalgia',
+ 'cologneblue' => 'Caerulus Colonia'
+);
+
+$namespaceNames = array(
+ NS_SPECIAL => 'Specialis',
+ NS_MAIN => '',
+ NS_TALK => 'Disputatio',
+ NS_USER => 'Usor',
+ NS_USER_TALK => 'Disputatio_Usoris',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Disputatio_{{grammar:genitive|$1}}',
+ NS_IMAGE => 'Imago',
+ NS_IMAGE_TALK => 'Disputatio_Imaginis',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Disputatio_MediaWiki',
+ NS_TEMPLATE => 'Formula',
+ NS_TEMPLATE_TALK => 'Disputatio_Formulae',
+ NS_HELP => 'Auxilium',
+ NS_HELP_TALK => 'Disputatio_Auxilii',
+ NS_CATEGORY => 'Categoria',
+ NS_CATEGORY_TALK => 'Disputatio_Categoriae',
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'xg j, Y',
+ 'mdy both' => 'H:i, xg j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j xg Y',
+ 'dmy both' => 'H:i, j xg Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y xg j',
+ 'ymd both' => 'H:i, Y xg j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+$messages = array(
+'tog-underline' => 'Nexus cum linea subscribere',
+'tog-highlightbroken' => 'Formare nexos fractos <a href="" class="new">sici</a> (alioqui: sic<a href="" class="internal">?</a>).',
+'tog-justify' => 'Saepire capites',
+'tog-hideminor' => 'Celare mutationes recentes minores',
+'tog-usenewrc' => 'Mutationes recentes amplificatae (Javascript)',
+'tog-numberheadings' => 'Numerare indices necessario',
+'tog-editondblclick' => 'Premere bis ut paginam recensere (uti JavaScript)',
+'tog-rememberpassword' => 'Recordare tesseram inter conventa (utere cookies)',
+'tog-editwidth' => 'Capsa recensitorum totam latitudinem habet',
+'tog-minordefault' => 'Notare omnes mutationes sicut minores',
+'tog-editsection' => 'Licere paginarum partibus recensier via nexus [recensendos].',
+'tog-editsectiononrightclick' => 'Licere paginarum partibus recensier si dextram murem premam in titulis partum (JavaScript)',
+'tog-enotifminoredits' => 'Etiam mihi mittere nuntium per cursum electronicum pro emendationibus minoribus',
+'tog-enotifrevealaddr' => 'Non celare meum cursum electronicum in nuntiis notificantibus.',
+'tog-enotifusertalkpages' => 'Mittere mihi nuntium si mea disputatio mutatur',
+'tog-enotifwatchlistpages' => 'Mittere mihi nuntium per cursum electrionic si paginia mearum custoditarum mutatus',
+'tog-extendwatchlist' => 'Extendere indicem mutationum custoditarum ut omnes emendationes monstrentur',
+'tog-fancysig' => 'Signa cruda (sine nexu automatico)',
+'tog-forceeditsummary' => 'Si emendationem non summatim descripsero, me roga si continuare velim',
+'tog-justify' => 'Iustificare paragrapha',
+'tog-previewontop' => 'Monstrare praevisus ante capsam recensiti, non post ipsam',
+'tog-previewonfirst' => 'Praevisum monstrare ad emendationem primam',
+'tog-shownumberswatching' => 'Numerum usorum observantum monstrare',
+'tog-showtoc' => 'Indicem contenta monstrare (paginis in quibus sunt +3 partes)',
+'tog-showtoolbar' => 'Instrumenta pro recensendo monstrare (JavaScript)',
+'tog-watchcreations' => 'Paginas quas creavi in paginarum custoditarum indicem addere',
+'tog-watchdefault' => 'Res novas et mutata recentia custodire.',
+'tog-watchlisthidebots' => 'Emendationes a [[{{int:grouppage-bot}}|{{int:group-bot}}]] in paginarum custoditarum indice celare.',
+'tog-watchlisthideown' => 'Meas emendationes in paginarum custoditarum indice celare.',
+'prefs-personal' => 'Minutiae rationis',
+'prefs-rc' => 'Paginae custoditae',
+'prefs-watchlist' => 'Paginae custoditae',
+'prefs-help-realname' => '* Nomen verum (non necesse): si vis id dare, opera tua tibi ascribantur.',
+'prefs-help-email' => '* Cursum tuum electronicum (non necesse): Licet aliis tecum loqui per tuam paginam usoris, nisi te reveles.',
+'skinpreview' => '(Praevisum)',
+'username' => 'Nomen usoris:',
+'uid' => 'ID Usoris:',
+'underline-always' => 'Semper',
+'underline-never' => 'Numquam',
+
+'sunday' => 'dies Solis',
+'monday' => 'dies Lunae',
+'tuesday' => 'dies Martis',
+'wednesday' => 'dies Mercurii',
+'thursday' => 'dies Iovis',
+'friday' => 'dies Veneris',
+'saturday' => 'dies Saturni',
+'january' => 'Ianuarius',
+'february' => 'Februarius',
+'march' => 'Martius',
+'april' => 'Aprilis',
+'may_long' => 'Maius',
+'june' => 'Iunius',
+'july' => 'Iulius',
+'august' => 'Augustus',
+'september' => 'September',
+'october' => 'October',
+'november' => 'November',
+'december' => 'December',
+'january-gen' => 'Ianuarii',
+'february-gen' => 'Februarii',
+'march-gen' => 'Martii',
+'april-gen' => 'Aprilis',
+'may-gen' => 'Maii',
+'june-gen' => 'Iunii',
+'july-gen' => 'Iulii',
+'august-gen' => 'Augusti',
+'september-gen' => 'Septembris',
+'october-gen' => 'Octobris',
+'november-gen' => 'Novembris',
+'december-gen' => 'Decembris',
+'jan' => 'ian',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'iun',
+'jul' => 'iul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'oct',
+'nov' => 'nov',
+'dec' => 'dec',
+'categories' => 'Categoriae',
+'pagecategories' => '{{PLURAL:$1|Categoria|Categoriae}}',
+'category_header' => 'Paginae in categoria "$1"',
+'subcategories' => 'Categoriae inferiores',
+'mainpage' => 'Pagina prima',
+'portal' => 'Porta communis',
+'portal-url' => 'Project:Porta communis',
+'about' => 'De {{SITENAME}}',
+'aboutpage' => 'Project:De {{SITENAME}}',
+'article' => 'Pagina contenta continens',
+'help' => 'Adiutatum',
+'helppage' => 'Help:Auxilium pro editione',
+'bugreports' => 'Renuntiare errores',
+'bugreportspage' => 'Project:Renuntiare errores',
+'sitesupport' => 'Donationes',
+'faq' => 'Quaestiones frequentes',
+'faqpage' => 'Project:Quaestiones frequentes',
+'edithelp' => 'Adjutatum ad recensere',
+'edithelppage' => '{{ns:help}}:Quam paginam recensere',
+'newwindow' => '(in fenestra nova aperietur)',
+'cancel' => 'Abrogare',
+'qbfind' => 'Invenire',
+'qbbrowse' => 'Perspicere',
+'qbedit' => 'Recensere',
+'qbpageoptions' => 'Optiones paginae',
+'qbpageinfo' => 'Indicium paginae',
+'qbmyoptions' => 'Optiones meae',
+'qbspecialpages' => 'Paginae speciales',
+'moredotdotdot' => 'Plus...',
+'mypage' => 'Pagina mea',
+'mytalk' => 'Disputatum meum',
+'anontalk' => 'Disputatio huius IP',
+'navigation' => 'Navigatio',
+'currentevents' => 'Novissima',
+'currentevents-url' => 'Nuntii',
+'disclaimers' => 'Repudiationes',
+'tagline' => 'E {{SITENAME}}',
+'search' => 'Quaerere',
+'searchbutton' => 'Quaerere',
+'go' => 'Ire',
+'searcharticle' => 'Ire',
+'history' => 'Historia',
+'history_short' => 'Historia',
+'printableversion' => 'Forma impressibilis',
+'edit' => 'Recensere',
+'editthispage' => 'Recensere hanc paginam',
+'delete' => 'Delere',
+'deletethispage' => 'Delere hanc paginam',
+'protect' => 'Protegere',
+'protectthispage' => 'Protegere hanc paginam',
+'unprotect' => 'Deprotegere',
+'unprotectthispage' => 'Deprotegere hanc paginam',
+'newpage' => 'Nova pagina',
+'talkpage' => 'Disputare hanc paginam',
+'specialpage' => 'Pagina specialis',
+'postcomment' => 'Adnotare',
+'articlepage' => 'Videre rem',
+'talk' => 'Disputatio',
+'toolbox' => 'Arca ferramentorum',
+'userpage' => 'Videre paginam usoris',
+'imagepage' => 'Videre pagina imaginis',
+'viewtalkpage' => 'Videre disputatum',
+'otherlanguages' => 'Aliae linguae',
+'redirectedfrom' => '(Redirectum de $1)',
+'autoredircomment' => 'Redirigens ad [[$1]]',
+'viewcount' => 'This page has been accessed $1 times.',
+'copyright' => 'Res ad manum sub $1.',
+'protectedpage' => 'Pagina protecta',
+'jumpto' => 'Salire ad:',
+'jumptonavigation' => 'navigatio',
+'jumptosearch' => 'Petere',
+'retrievedfrom' => 'Receptum de "$1"',
+'youhavenewmessages' => 'Habes $1 ($2).',
+'newmessageslink' => 'nuntia nova',
+'newmessagesdifflink' => 'dissimilia postquam emendationem ultimam',
+'badaccess' => 'Error permissionis',
+'badtitle' => 'Titulus peius',
+'editsection' => 'recensere',
+'toc' => 'Index',
+'showtoc' => 'monstrare',
+'hidetoc' => 'celare',
+'thisisdeleted' => 'Videre aut restituere $1?',
+'restorelink' => '$1 recensita deleta',
+'nstab-main' => 'Res',
+'nstab-user' => 'Pagina usoris',
+'nstab-special' => 'Specialis',
+'nstab-project' => 'Consilium',
+'nstab-image' => 'Imago',
+'nstab-category' => 'Categoria',
+'nstab-help' => 'Help',
+'nstab-mediawiki' => 'Nuntium',
+'nstab-template' => 'Formula',
+
+'nosuchaction' => 'Actio non est',
+'nosuchactiontext' => 'Actio in URL designata non agnoscitur a {{SITENAME}}.',
+'nosuchspecialpage' => 'Pagina specialis non est',
+'nospecialpagetext' => 'Paginam specialem a {{SITENAME}} ignotam petivisti',
+'databaseerror' => 'Error basis dati',
+'noconnect' => 'Nos paenitet! Vicipaedia per aerumnas technicas agit, et server invenire non potest. <br /> $1',
+'cachederror' => 'Quae sequuntur sunt ex exemplo conditivo paginae quaesitae, fortasse non recente.',
+'cannotdelete' => 'Pagina vel imago deleri non potuit. (Fortasse usor alius iam deleverat.)',
+'perfcached' => 'The following data is cached and may not be completely up to date:',
+'viewsource' => 'Fontem videre',
+'logouttitle' => 'Finis conventi',
+'logouttext' => 'Conventum tuum finivisti.
+{{SITENAME}} sine nomine continuare usare potes, aut conventum
+novum aperire cum idem nomine aut ut alio usore.',
+'welcomecreation' => '<h2>Salve, $1!</h2>
+<p>Ratio tua iam creata est.
+Noli oblivisci praeferentias tuas mutare.',
+'loginpagetitle' => 'Aperire conventum',
+'youremail' => 'Cursum publicum tuum electronicum',
+'yourrealname' => 'Nomen tuum verum*',
+'yournick' => 'Agnomen tuum (in subscriptiones)',
+'yourname' => 'Nomen tuum usoris',
+'yourpassword' => 'Tessera tua',
+'yourpasswordagain' => 'Tesseram tuam adfirmare',
+'yourlanguage' => 'Lingua tua:',
+'remembermypassword' => 'Tessera mea inter conventa memento',
+'loginproblem' => '<b>Problema erat aperiens conventum tuum.</b><br />Conare denuo!',
+'alreadyloggedin' => '<span style="color:#ff0000"><b>Usor $1, conventum tuum iam apertum est!</b></span><br />',
+'login' => 'Aperire conventum',
+'loginprompt' => 'Cookies potestatem facere debes ut conventum aperire.',
+'userlogin' => 'Aperire conventum',
+'logout' => 'Finire conventum',
+'userlogout' => 'Finire conventum',
+'notloggedin' => 'Conventum non apertum est',
+'nologin' => 'Num rationem non habes? $1.',
+'nologinlink' => 'Eam crea',
+'createaccount' => 'Rationem novam creare',
+'createaccountmail' => 'ab curso publico electronico',
+'accountcreated' => 'Conventum creatum',
+'accountcreatedtext' => 'Conventum pro usore $1 creatum est.',
+'cantcreateaccounttitle'=> 'Ratio facier non potest',
+'acct_creation_throttle_hit' => 'Nos paenitet, etiam conventa $1 creavisti. Plurima non tibi licet creare.',
+'badretype' => 'Tesserae quas scripsisti non inter se congruunt.',
+'userexists' => 'Nomen usoris quod selegisti iam est.',
+'loginerror' => 'Error est in aperiens conventum',
+'nocookiesnew' => 'Ratio usoris creata est, sed conventum non apertum est. {{SITENAME}} Cookies utitur in usorum conventa aperiendo. Cookies tua debiles sunt. Eis potestatem fac, tum conventum aperi cum nomine usoris tesseraque tua nova.',
+'nocookieslogin' => '{{SITENAME}} Cookies utitur ut conventum aperire. Cookies tua debiles sunt. Ea potestatem fac, tum conare denuo.',
+'noname' => 'Nominem usoris ratum non designavisti.',
+'loginsuccesstitle' => 'Conventum prospere apertum est.',
+'loginsuccess' => 'In {{SITENAME}} agnosceris ut "$1".',
+'nosuchuser' => 'Nomen usoris "$1" non est.
+Orthographiam confirma, aut novam rationem usoris crea.',
+'wrongpassword' => 'Tessera quam scripsisti non constat. Conare denuo.',
+'mailmypassword' => 'Tesseram novam per cursum publicum electronicum petere',
+'passwordremindertitle' => 'Nova tessera in {{SITENAME}}',
+'passwordremindertext' => 'Aliquis (tu probabiliter, cum loco de IP $1) tesseram novam petivit pro {{SITENAME}} ($4).
+Tessera usoris "$2" nunc est "$3". Conventum aperias et statim tesseram tuam mutes.
+Si non ipse hanc petitionem fecisti, aut si tesseram tuam meministi et etiam nolis eam mutare, potes hunc nuntium ignorare, et tessera seni uti continuare.',
+
+# Editing page
+'summary' => 'Summarium',
+'subject' => 'Res/titulus',
+'minoredit' => 'Haec recensio minor est',
+'watchthis' => 'Custodire hanc paginam',
+'savearticle' => 'Servare hanc rem',
+'italic_sample' => 'Textus litteris italicis scriptus',
+'italic_tip' => 'Textus litteris italicis scriptus',
+'preview' => 'Praevidere',
+'showpreview' => 'Monstrare praevisum',
+'showdiff' => 'Mutata ostendere',
+'anoneditwarning' => 'Conventum tuum non apertum. Locus IP tuus in historia huius paginae non nomen usoris notabitur.',
+'blockedtitle' => 'Usor obstructus est.',
+'blockedtext' => 'Nomen usoris tuum aut locus de IP obstructum est ab usore $1. Causa:<br />
+\'\'$2\'\'
+<p>Vel usorem $1 appellare potes, vel alios [[{{int:grouppage-sysop}}|administratores]] si vis obstructionem disputare.</p>',
+'blockededitsource' => 'Textus tuarum \'\'\'emendationum\'\'\' in \'\'\'$1\'\'\' subter monstratur:',
+'whitelistacctitle' => 'Non licet tibi conventum creare.',
+'whitelistedittext' => 'Necesse est tibi $1, priusquam paginas recenseas.',
+'loginreqlink' => 'login',
+'accmailtext' => 'Tessera usoris "$1" ad $2 missa est.',
+'accmailtitle' => 'Tessera missa est.',
+'newarticle' => '(Nova)',
+'newarticletext' => 'Per nexum progressus es ad paginam quae nondum exsistit. Novam paginam si vis creare, in capsam infra praebitam scribe. (Vide [[Project:Adjutatum|paginam auxilii]] si plura cognoscere vis.) Si hic es propter errorem, solum \'\'\'Retrorsum\'\'\' in navigatro tuo preme.',
+'anontalkpagetext' => '---- \'\'Haec est pagina disputationis usoris anonymi qui rationem nondum creavit, vel ratione creata non utitur. Non igitur nisi ex inscriptione IP eum agnoscere possumus. Memento insctriptiones IP posse pluribus hominibus pertinere.\'\'',
+'noarticletext' => 'In hac pagina nondum litterae sunt.',
+'updated' => '(Novata)',
+'previewnote' => 'Memento hanc paginam solum praevisum esse, neque iam servatam!',
+'editing' => 'Recensio paginae "$1"',
+'editinguser' => 'Recensio paginae "$1"',
+'editingcomment' => 'Recensens $1 (adnotum)',
+'editingsection' => 'Recensens $1 (partem)',
+'editconflict' => 'Contentio recensionis: $1',
+'explainconflict' => 'Alius hanc paginam mutavit postquam eadem mutare incipebat.
+Capsa superior paginae verba recentissima continet.
+Mutationes tuae in capsa inferior monstrantur.
+Mutationes tuae in verbam superiorem adiungare debes.
+<b>Solum</b> verba capsae superioris servabuntur quando "Servare hanc rem" premes.
+</p>',
+'yourtext' => 'Verba tua',
+'storedversion' => 'Verba recentissima',
+'nonunicodebrowser' => '<strong>CAVETO: Navigatorium retiale tuum systemati UNICODE morem non gerit. Modum habemus quo commentationes sine damno recenseas: litterae non-ASCII in capsa sub veste hexadecimali ostendentur.</strong>',
+'editingold' => '<strong>MONITIO: Formam obsoletam huius paginae mutas.
+Si eam servabis, totae mutationes noviores amittentur.</strong>',
+'yourdiff' => 'Diversa',
+'copyrightwarning' => 'Nota omnia {{SITENAME}} contributa divulgata ac liberata esse habentur ex Potestatis tabulae liberae *** GNU (vide singula apud $1).
+Nisi vis verba tua crudelissime recenseri, mutari et ad libidinem redistribui, noli ea submittere.<br />
+Nobis etiam spondes te esse ipsum horum verborum scriptorem, nisi ex opere in "dominio publico" exscripsisti.
+<strong>NOLI OPERIBUS SUB IURE DIVULGANDI UTI NISI POTESTATE FACTA!</strong>',
+'longpagewarning' => 'MONITIO: Haec pagina $1 kilobytes longa est;
+aliqui navigatra paginas magniores quam 32 kilobytes longa.
+Considera paginam in partes minores frangere.',
+'templatesused' => 'Formulae hac in pagina adhibitae:',
+'revhistory' => 'Historia formarum',
+'viewpagelogs' => 'Vide historias huius paginae',
+'nohistory' => 'Huic paginae non est historia.',
+'revnotfound' => 'Emendatio non inventa.',
+'revnotfoundtext' => 'Emendatio qui rogavisti non inventa est.
+Confrima URL paginae.',
+'loadhist' => 'Onus historiae paginae',
+'currentrev' => 'Emendatio recentissima',
+'revisionasof' => 'Emendatio ex $1',
+'cur' => 'nov',
+'next' => 'seq',
+'last' => 'prox',
+'orig' => 'prim',
+'histlegend' => 'Titulus: (nov) = dissimilitudo de forma novissima,
+(prox) = dissimilitudo cum forma proxima, M = mutatio minor',
+'deletedrev' => '[deleta est]',
+'difference' => '(Dissimilitudo inter emendationes)',
+'loadingrev' => 'Onus emendationis pro diss',
+'editcurrent' => 'Recensere formam recentissimam huius paginae',
+'searchresults' => 'Eventum investigationis',
+'searchresulttext' => 'Pro plure nuntii de investigatione {{SITENAME}}, vide $1.',
+'searchsubtitle' => 'Pro investigatione "[[:$1]]"',
+'searchsubtitleinvalid' => 'Pro investigatione "$1"',
+'badquery' => 'Investigatio formata male',
+'badquerytext' => 'Investigatio tua procedere non poterat.
+Fortasse verba minora quam tres litteras longa quaerere conatus es, vel fortasse error in quaestione erat. Conare denuo.',
+'matchtotals' => 'Investigatio "$1" indicibus $2 rerum
+et verbis $3 rerum congruit.',
+'noexactmatch' => 'Nulla pagina cum titulo "$1" exacto existit. Potes [[:$1|eam]] creare.',
+'titlematches' => 'Exaequata indicibus rerum',
+'notitlematches' => 'Nulla exaequata',
+'prevn' => '$1 proxima',
+'nextn' => '$1 secuta',
+'viewprevnext' => 'Videre ($1) ($2) ($3).',
+'showingresults' => 'Subter monstrans <b>$1</b> eventibus tenus incipiens ab <b>#$2</b>.',
+'showingresultsnum' => 'Subter monstrans <b>$3</b> eventus incipiens ab #<b>$2</b>.',
+'nonefound' => '<strong>Nota</strong>: investigationes saepe infelices sunt propter verba frequentes huiusmodi "que" et "illo", aut quod plus unum verba quaerere designavisti (solae paginae qui tota verba investigationis continent in evento apparebit).',
+'powersearch' => 'Quaerere',
+'powersearchtext' => 'Quaerere in contexto :<br />
+$1<br />
+$2 Monstrare redirectiones Quaerere $3 $9',
+'searchdisabled' => '<p>Quaerere ad tempum debilitata est. Sis Google aut Yahoo! usere.</p>',
+'preferences' => 'Praeferentiae',
+'mypreferences' => 'Praeferentiae meae',
+'prefsnologin' => 'Conventum non apertum',
+'prefsnologintext' => '[[{{ns:special}}:Userlogin|Conventum aperire]] debes ut praeferentiae tuae perscribere.',
+'prefsreset' => 'Praeferentiae tuae reperscriptus est.',
+'qbsettings' => 'Figuratio claustri celeris',
+'changepassword' => 'Mutare tesseram',
+'skin' => 'Aspectum',
+'math' => 'Interpretatio artis mathematicae',
+'files' => 'Fascicula',
+'dateformat' => 'Forma diei',
+'math_failure' => 'Excutare non potest',
+'math_unknown_error' => 'error ignotus',
+'math_unknown_function' => 'functio ignota',
+'saveprefs' => 'Servare praeferentias',
+'resetprefs' => 'Reddere praeferentias',
+'oldpassword' => 'Tessera vetus',
+'newpassword' => 'Tessera nova',
+'emailauthenticated' => 'Tuum cursum electronicum recognitum est $1.',
+'retypenew' => 'Adfirmare tesseram novam',
+'textboxsize' => 'Mensura capsae verbi',
+'rows' => 'Lineae',
+'columns' => 'Columnae',
+'searchresultshead' => 'Figuratio eventorum investigationis',
+'articletitles' => 'Paginae ab \'\'$1\'\'',
+'resultsperpage' => 'Eventa per paginam',
+'contextlines' => 'Lineae per eventum',
+'contextchars' => 'Litterae contexti per lineam',
+'stubthreshold' => 'Limen ostentationis rei parvae',
+'recentchangescount' => 'Quantum rerum in mutationibus recentibus',
+'savedprefs' => 'Praeferentiae tuae servatae sunt.',
+'allowemail' => 'Nuntia per cursum tuum electronicum licere mittier.',
+'datetime' => 'Dies et tempus',
+'timezonetext' => 'Scribere numerum horae inter horam tuam et illam moderatri (UTC).',
+'localtime' => 'Hora indigena',
+'timezoneoffset' => 'Dissimilitudo cinguli horae',
+'servertime' => 'Hora moderatri nunc est',
+'guesstimezone' => 'Hora ex navigatro scribere',
+'confirmemail_success' => 'Tuum cursum electronicum confirmatum est. Libenter utens Vicipaedia esto.',
+'changes' => 'mutationes',
+
+# Recentchanges
+'recentchanges' => 'Mutationes recentes',
+'recentchangestext' => 'Mutationes recentiores.
+Adde quae scis, sed memento addita tua mutari ameliorarique posse ab aliis utentibus. Cave ne aliorum iura (©) violes!',
+'rcnote' => 'Subter <strong>$1</strong> mutationes recentissimae sunt in <strong>$2</strong> diebus proximis, ad $3 tempus.',
+'rcnotefrom' => 'Subter <b>$1</b> mutationes recentissimas sunt in proxima <b>$2</b> die.',
+'rclistfrom' => 'Monstrare mutationes novas incipiens ex $1',
+'rclinks' => 'Monstrare $1 mutationes recentissimas in $2 diebus proximis.<br />$3',
+'rcshowhideanons' => '$1 usores ignotos',
+'rcshowhideliu' => '$1 usores notos',
+'rcshowhidemine' => '$1 conlationes meas',
+'rcshowhideminor' => '$1 emendationes parvas',
+'recentchangesall' => 'omnes',
+
+'diff' => 'diss',
+'hide' => 'celare',
+'show' => 'monstrare',
+'upload' => 'Onerare fascicula',
+'uploadbtn' => 'Onerare fascicula',
+'reupload' => 'Reonerare',
+'reuploaddesc' => 'Redire ad formulam onerationis.',
+'uploadnologin' => 'Conventum non apertum est',
+'uploadnologintext' => '[[{{ns:special}}:Userlogin|Aperire conventum]] debes ut fasciculos oneres.',
+'uploaderror' => 'Error onerati',
+'uploadvirus' => 'Imagini huic est virus! Singula: $1',
+'uploadtext' => '<strong>SISTERE!</strong> Ante hic oneras, lege et pare [[Project:Consilias de uso imaginum|consilias de {{SITENAME}} de uso imaginum]].<br />
+Ut videre aut quaerere imagines oneratas antea,
+adi [[{{ns:special}}:Imagelist|indicem imaginum oneratae]].
+Onerata et deleta in [[{{ns:special}}:Log/upload|notationem oneratorum]] notata sunt.<br />
+Utere formam subter onerare fasciculos novos.
+Capsam desginare debes qui verba privata non uteris.
+Preme "Onerare" pro onerate incipere.<br />
+<br />
+Formae antipositae sunt: JPEG pro imaginibus, PNG pro simulacris, et OGG pro sonis.
+Nomina descriptiva utere, ut confusiones evitare.
+Pro imaginem in rebus includere, nexum
+* \'\'\'<nowiki>[[Image:File.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[Image:File.png|verba alterna]]</nowiki>\'\'\'
+aut pro sonis utere
+* \'\'\'<nowiki>[[Media:File.ogg]]</nowiki>\'\'\'',
+'uploadlog' => 'Notatio onerati',
+'uploadlogpage' => 'Notatio onerati',
+'uploadlogpagetext' => 'Subter index onerati recentissimi est.
+Totae horae in hora moderatri monstrantur (UTC).
+<ul>
+</ul>',
+'filename' => 'Nomen fasciculi',
+'filedesc' => 'Descriptio',
+'filestatus' => 'Locus verborum privatorum',
+'filesource' => 'Fons',
+'copyrightpage' => 'Project:Verba privata',
+'copyrightpagename' => '{{SITENAME}} verba privata',
+'uploadedfiles' => 'Fasciculi onerati',
+'ignorewarning' => 'Ignorare monita et servare fasciculum.',
+'minlength' => 'Nomines imaginum saltem tres litteras habere debent.',
+'badfilename' => 'Nomen imaginis ad "$1" mutatum est',
+'badfiletype' => '".$1" forma imaginis suasa non est.',
+'largefile' => 'Suasum est ut imagines $1 octopla magnitudine non excedeant; magnitudo huius imaginis $2 octopla est.',
+'successfulupload' => 'Oneratum perfectum',
+'fileuploaded' => 'Fasciculus "$1" sine problema oneratus est.
+Premere hic: ($2) ut paginam descriptionis adire
+et fasciculum describere.',
+'uploadwarning' => 'Monitus onerati',
+'savefile' => 'Servare fasciculum',
+'uploadedimage' => '"$1" oneratus est',
+'imagelist' => 'Imagines',
+'imagelisttext' => 'Subter est index {{plural:$1|\'\'\'unius\'\'\' imaginis|\'\'\'$1\'\'\' imaginum}} digestus $2.',
+'getimagelist' => 'Adducere indicem imaginum.',
+'ilsubmit' => 'Quaerere',
+'byname' => 'ex nomine',
+'bydate' => 'ex die',
+'bysize' => 'ex magnitudine',
+'imglegend' => 'Titulus: (desc) = monstrare/mutare descriptionem imaginis',
+'imghistory' => 'Historia imaginis',
+'imghistlegend' => 'Titulus: (nov) = haec est imago recentissima, (del) = delere hanc formam vetus, (rev) = reverte ad hanc formam vetus.
+<br /><i>Premere in diem ut imaginem in illum diem oneratum videre.</i>',
+'imagelinks' => 'Nexus ad imaginem',
+'linkstoimage' => 'Paginae insequentes huic imagini nectunt:',
+'nolinkstoimage' => 'Nullae paginae huic imagini nectunt.',
+'noimage' => 'Imago huius nominis non est, fortasse deleta est, vide [{{fullurl:{{ns:Special}}:Log|page={{FULLPAGENAMEE}}}} acta deletionum] et [{{fullurl:commons:Special:Log|page=Image:{{PAGENAMEE}}}} acta deletionum Vicimediae Communium]. $1 potes.',
+'noimage-linktext' => 'Imaginem huius nominis onerare',
+'noimages' => 'Nullum videndum.',
+'sharedupload' => 'This file is a shared upload and may be used by other projects.',
+'mimesearch' => 'Quaerere per MIME',
+'unwatchedpages' => 'Incustodita',
+'listredirects' => 'Index redirectionum',
+'unusedtemplates' => 'Formulae sine usu',
+'randomredirect' => 'Redirectio fortuita',
+'statistics' => 'Census',
+'sitestats' => 'Census accessi',
+'userstats' => 'Census usorum',
+'sitestatstext' => 'Basis dati <b>$1</b> habet.
+Hic numerus paginas disputationum, includitIste numero include paginas de "disputatio", paginas de {{SITENAME}}, res parvas, paginas redirectionum, et paginas alteras. Hae excludens, <b>$2</b> paginae sunt.
+
+<b>$8</b> imagines oneratae sunt.
+
+Paginae <b>$3</b> visae fuerunt, et <b>$4</b> mutationes paginae fuerunt
+postquam aperitum moderatri novi. Fere <b>$5</b> mutationes per pagina fuerunt, et <b>$6</b> visae per mutatione.
+
+$7 operationes etiam exspectant perfacier.',
+'userstatstext' => '<b>$1</b> usores relati sunt, quorum <b>$2</b> (vel <b>$4%</b>) administratores sunt (vide $3).',
+'disambiguations' => 'Paginae disambiguationis',
+'disambiguationspage' => 'Template:Discretiva',
+'disambiguationstext' => 'Paginae subsequentes ad <i>paginam discretivam</i> nectunt. Ad aptam paginam nectere debent.<br />Pagina discretivam esse putatur si $1 eam nectat. <br />Nexus sub aliis praefixis <i>non</i> hic indicantur.',
+'doubleredirects' => 'Redirectiones duplices',
+'brokenredirects' => 'Redirectiones fractae',
+'brokenredirectstext' => 'Redirectiones sequentes ad res inexistentes nectunt',
+'nbytes' => '$1 bytes',
+'ncategories' => '$1 categories',
+'nlinks' => '$1 nexus',
+'nmembers' => '$1 members',
+'nrevisions' => '$1 revisions',
+'nviews' => '$1 visae',
+'lonelypages' => 'Paginae orbatae',
+'uncategorizedpages' => 'Sine categoriis',
+'uncategorizedcategories'=> 'Categoriae sine categoriis',
+'unusedcategories' => 'Categoriae vacuae',
+'unusedimages' => 'Imagines non in usu',
+'popularpages' => 'Paginae populares',
+'wantedcategories' => 'Categoriae desideratae',
+'wantedpages' => 'Paginae desideratae',
+'mostlinked' => 'Maxime annexa',
+'mostlinkedcategories' => 'Maxime annexae categoriae',
+'mostcategories' => 'Paginae plurimis categoriis',
+'mostimages' => 'Maxime annexae imagines',
+'mostrevisions' => 'Plurimum mutata',
+'prefixindex' => 'Praefixa',
+'randompage' => 'Pagina fortuita',
+'shortpages' => 'Paginae breves',
+'longpages' => 'Paginae longae',
+'deadendpages' => 'Fundulae',
+'listusers' => 'Usores',
+'specialpages' => 'Paginae speciales',
+'spheading' => 'Paginae speciales',
+'restrictedpheading' => 'Paginae speciales propriae',
+'recentchangeslinked' => 'Mutationes conlatae',
+'rclsub' => '(Paginis nexis ex "$1")',
+'newpages' => 'Paginae novae',
+'newpages-username' => 'Nomen usoris',
+'ancientpages' => 'Res veterrimae',
+'move' => 'Movere',
+'movethispage' => 'Motare hanc paginam',
+'booksources' => 'Fontes librorum',
+'version' => 'Versio',
+'log' => 'Acta',
+'emailuser' => 'Mittere cursum publicum electronicum huic usori',
+'emailpage' => 'Mittere cursum publicum electronicum huic usori',
+'emailpagetext' => 'Si hic usor inscriptionem electronicam ratum in praeferentias usorum eius dedit, forma subter nuntium mittet.
+Inscriptio electronica qui in praeferentiis tuis dedis ut "De" inscriptione apparebit.',
+'noemailtitle' => 'Nulla inscriptio electronica',
+'noemailtext' => 'Hic usor inscriptionem electronicam ratam non dedit, aut nuntia ex aliis usoribus non vult.',
+'emailto' => 'Ad',
+'emailsubject' => 'Res',
+'emailmessage' => 'Nuntius',
+'emailsend' => 'Mittere',
+'emailsenttext' => 'Nuntius tuus missus est.',
+'watchlist' => 'Paginae custoditae',
+'nowatchlist' => 'Nullas paginas custodis.',
+'watchnologin' => 'Conventum non apertum est',
+'watchnologintext' => '[[{{ns:special}}:Userlogin|Aperire conventum]] debes ut indicem paginarum custoditarum mutes.',
+'addedwatch' => 'Pagina custodita',
+'addedwatchtext' => '<p>Pagina "$1" in [[{{ns:special}}:Watchlist|indice paginarum custoditarum]] tuo est. Mutationes posthac huic paginae et paginae disputationis ibi notabuntur, et pagina <b>in nigro</b> apparebit in [[{{ns:special}}:Recentchanges|indice modificationum recentum]].</p>
+<p>Si paginam de indice paginarum custoditarum removere vis, "Custodire non iam."</p>',
+'removedwatch' => 'Custoditum abrogatum est',
+'removedwatchtext' => 'Pagina "$1" custoditum non est iam.',
+'watch' => 'custodire',
+'watchthispage' => 'Custodire hanc paginam',
+'unwatch' => 'Decustodire',
+'unwatchthispage' => 'Abrogare custoditum',
+'notanarticle' => 'Res non est',
+'watchnochange' => 'Nullae paginarum custoditarum tuarum recensitae sunt in hoc tempo.',
+'watchdetails' => '($1 paginae custoditae, sine paginas disputationis;
+$2 paginae totae recensitae in hoc tempo;
+$3...
+[$4 monstrare et recensere indicem totum].)',
+'watchmethod-recent' => 'recensita recenta quaerens pro pagina custodita',
+'watchmethod-list' => 'paginas custoditas quaerens pro recensitis recentibus',
+'removechecked' => 'Removere paginas selectas ex indice paginarum custoditarum',
+'watchlistcontains' => 'Index paginarum custoditarum tuus $1 paginas habet.',
+'watcheditlist' => 'Hic est index alphabeticus paginarum custoditarum tui. Nota capsas paginarum qui removere vis ex index paginarum custoditarum et "removere" premere.',
+'watchlistcleartext' => 'Certus esne ut has paginas removere vis?',
+'removingchecked' => 'Removens res notatas ex indice paginarum custoditarum...',
+'couldntremove' => 'Paginam "$1" removere non posse...',
+'iteminvalidname' => 'Aerumna cum pagina "$1", nomen non est rectum.',
+'wlnote' => 'Subter proximae $1 mutationes sunt in proximis <b>$2</b> horis.',
+'wlshowlast' => 'Monstrare proximas $1 horas $2 dies $3',
+'wlhideshowown' => '$1 recensiones meas.',
+'wlhideshowbots' => '$1 recensiones automatarias.',
+'changed' => 'mutata',
+'created' => 'creata',
+'deletepage' => 'Delere paginam',
+'confirm' => 'Adfirmare',
+'excontent' => 'Contenta erant: "$1"',
+'excontentauthor' => 'contenta erant: \'$1\' (et contributor unicus \'$2\' erat)',
+'exbeforeblank' => 'Contenta priusquam pagina facta vacua erant: "$1"',
+'exblank' => 'pagina vacuata erat',
+'confirmdelete' => 'Adfirmare deletionem',
+'deletesub' => '(Deletio de "$1")',
+'historywarning' => 'Monitus: Paginam delebis historiam habet:',
+'confirmdeletetext' => 'Paginam imaginemve perpetuo delebis ex base datorum, cum tota historia eius. Adfirma quaeso te paginam delere velle, consequentias intellere, et deletionem [[Project:Consilium|Consilio {{SITENAME}}e]] congruere.',
+'actioncomplete' => 'Actio completa',
+'deletedtext' => '"$1" deletum est.
+Vide $2 pro indice deletionum recentum.',
+'deletedarticle' => 'deleta est "[[$1]]"',
+'undeletedarticle' => 'reconstituta "[[$1]]"',
+'dellogpage' => 'Index deletionum',
+'dellogpagetext' => 'Subter index deletionum recentissimum est.
+Totae horae in cingulo horis moderatri sunt (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'index deletionum',
+'reverted' => 'Reversum ad recensitum proximum',
+'deletecomment' => 'Ratio deletionis',
+'imagereverted' => 'Reversum ad formam proximam',
+'rollback' => 'Reverti mutationes',
+'rollbacklink' => 'reverti',
+'rollbackfailed' => 'Reversum defecit',
+'cantrollback' => 'Mutatio reverti non posse; conlator proximus solus auctor huius rei est.',
+'alreadyrolled' => 'Ad mutationem proxima paginae "[[:$1]]" ab usore "[[{{ns:user}}:$2|$2]]" ([[{{ns:user_talk}}:$2|disputatio]]) reverti non potest; alius paginam iam recensuit vel revertit. Mutatio proxima ab usore "[[{{ns:user}}:$3|$3]]" ([[{{ns:user_talk}}:$3|disputatio]]) effecta est.',
+'editcomment' => 'Dictum recensiti erat: "<i>$1</i>".',
+'revertpage' => 'Reverti ad mutationem proximam ab $1',
+'protectlogpage' => 'Index praesidii',
+'protectlogtext' => 'Subter index paginarum protectarum est. Vide [[{{ns:project}}:Pagina protecta]] si pluris nuntii eges.',
+'protectedarticle' => '[[$1]] protectum est',
+'confirmprotect' => 'Protectionem adfirmare',
+'confirmprotecttext' => 'Re vera hanc paginam visne protegere?',
+'unprotectedarticle' => '[[$1]] deprotectum est',
+'confirmunprotect' => 'Deprotectionem adfirmare',
+'confirmunprotecttext' => 'Re vera hanc paginam visne deprotegere?',
+'protect-text' => 'You may view and change the protection level here for the page <strong>$1</strong>. Please be sure you are following the [[Project:Protected page|project guidelines]].',
+'undelete' => 'Restituere paginam deletam',
+'undeletepage' => 'Videre et restituere paginas deletas',
+'undeletepagetext' => 'Paginae sequentes deletae sunt sed in tabulis sunt et eas restituere posse. Tabulae nonnumquam deleta est.',
+'undeletearticle' => 'Restituere rem deletam',
+'undeleterevisions' => '$1 recensita servata',
+'undeletehistory' => 'Si paginam restituis, tota recensita restituebuntur ad historiam.
+Si paginam novam cum ipse nomine post deletionem creata est, recensita restituta in historia prior apparebit, et recensitum recentissimum paginae necessario non renovabitur.',
+'undeleterevision' => 'Recensitum deletum usque ab $1',
+'undeletebtn' => 'Restituere!',
+'contributions' => 'Conlationes usoris',
+'mycontris' => 'Conlationes meae',
+'nocontribs' => 'Nullae mutationes inventae sunt ex his indiciis.',
+'contribsub' => 'Pro $1',
+'ucnote' => 'Subter <b>$1</b> mutationes proximae huius usoris sunt in <b>$2</b> die proximo.',
+'uclinks' => 'Videre $1 mutationes proximas; videre $2 dies proximos.',
+'uctop' => ' (vertex)',
+'whatlinkshere' => 'Nexus ad hanc paginam',
+'notargettitle' => 'Nullus scopus',
+'notargettext' => 'Paginam aut usorem non notavis.',
+'linklistsub' => '(Index nexuum)',
+'linkshere' => 'Paginae sequentes huic paginae nectunt:',
+'nolinkshere' => 'Nullae paginae hic nectunt.',
+'isredirect' => 'pagina redirectionis',
+'istemplate' => 'inclusio',
+'blockip' => 'Obstruere locum IP',
+'blockiptext' => 'Forma infera utere ut quendam locum IP obstruas. Hoc non nisi secundum [[Project:Consilium|consilium {{SITENAME}}e]] fieri potest. Rationem certam subsribe.',
+'ipaddress' => 'Locus IP',
+'ipbreason' => 'Ratio',
+'ipbsubmit' => 'Obstruere hunc locum',
+'anononlyblock' => 'Solum usores insciti.',
+'createaccountblock' => 'Creatio rationum obstructa',
+'badipaddress' => 'Locus IP formatus malus est.',
+'blockipsuccesssub' => 'Locus obstructus est.',
+'blockipsuccesstext' => 'Locus IP [[{{ns:special}}:Contributions/$1|$1]] obstructus est.
+<br />Vide [[{{ns:special}}:Ipblocklist|Indicem obstructorum IP]] ut obstructos revideas.',
+'unblockip' => 'Deobstruere locum IP',
+'unblockiptext' => 'Formam inferam usere ut locum IP deobstruere.',
+'ipusubmit' => 'Deobstruere hanc locum',
+'ipblocklist' => 'Index locorum IP obstructorum',
+'blocklistline' => '$1, $2 obstruxit $3 (exire $4)',
+'blocklink' => 'obstruere',
+'unblocklink' => 'deobstruere',
+'contribslink' => 'conlationes',
+'blocklogpage' => 'Index obstructorum',
+'blocklogentry' => 'obstructus "$1", exire $2',
+'blocklogtext' => 'Hic index obstructorum et deobstructorum est. Vide [[{{ns:special}}:Ipblocklist|Index locorum IP obstructorum]] pro index obstructorum.',
+'unblocklogentry' => 'deobstruxit "$1"',
+'lockdb' => 'Obstruere basem dati',
+'unlockdb' => 'Deobstruere basem dati',
+'lockdbtext' => 'Obstructio basis dati potestatem totorum usorum suspendebit paginas recensere et preferentiarum earum et paginarum custoditarum mutare.
+Adfirmare qui basem dati obstruere vis, et que basem dati deobstruebis ut primum alimentum tuum finiveris.',
+'lockconfirm' => 'Basem dati obstruere volo.',
+'unlockconfirm' => 'Basem dati deobstruere volo.',
+'lockbtn' => 'Obstruere basem dati',
+'unlockbtn' => 'Deobstruere basem dati',
+'locknoconfirm' => 'Capsam non notavis.',
+'lockdbsuccesssub' => 'Basis dati obstructa est',
+'unlockdbsuccesssub' => 'Basis dati deobstructa est',
+'lockdbsuccesstext' => 'Basis dati de {{SITENAME}} obstructa est.
+<br />Memento eam deobstruere ubi alimentum tuum finiveris.',
+'unlockdbsuccesstext' => 'Basis dati de {{SITENAME}} deobstructa est.',
+'movepage' => 'Motare paginam',
+'movepagetext' => 'Formam inferam utere ut paginam renominare et historia eius ad nominem novum motare. Index vetus paginam redirectionis ad indicem novum fiet. Nexus paginae veteris non mutabitur; redectiones duplices aut fractas [[{{ns:special}}:Maintenance|quaerere et figere]] debebis.
+
+Paginam \'\'\'non\'\'\' movebitur si pagina sub indice novo iam est, nisi vacuata est aut pagina redirectionis est et nulla historia habet.
+
+<b>MONITUM!</b> Haec mutatio vehemens et improvisa potest pro pagina populare; adfirmare qui consequentias intelleges ante procedere.',
+'movepagetalktext' => 'Pagina disputationis huius paginae, si est, etiam necessario motabitur \'\'\'nisi\'\'\':
+*Contexti transmoves,
+*Pagina disputationis non vacuata iam est, aut
+*Capsam subter non nota.
+
+Ergo paginam manu motare debebis, si vis.',
+'1movedto2' => '[[$1]] ad [[$2]] mota est.',
+'1movedto2_redir' => 'Praeter redirectionem [[$1]] ad [[$2]] mota est.',
+'movearticle' => 'Motare paginam',
+'movenologin' => 'Conventum non apertum',
+'movenologintext' => '[[{{ns:special}}:Userlogin|Rationem usoris]] habere debes ut paginam motare.',
+'newtitle' => 'Ad indicem novum',
+'movepagebtn' => 'Motare paginam',
+'pagemovedsub' => 'Pagina motata est.',
+'pagemovedtext' => 'Pagina "[[$1]]" motata est ad "[[$2]]".',
+'articleexists' => 'Pagina cum hoc nomine iam est, aut nomen selectum non ratum est.
+Selege nominem altera.',
+'talkexists' => 'Paginam motata est, sed paginam disputationis non motata est quod paginam ibi iam est. Eam manu motare debebis.',
+'movedto' => 'motata ad',
+'movetalk' => 'Motare etiam paginam disputationis, si est.',
+'talkpagemoved' => 'Pagina disputationis etiam motata est.',
+'talkpagenotmoved' => 'Pagina disputationis \'\'\'non\'\'\' motata est.',
+'movereason' => 'Ratio',
+'delete_and_move' => 'Delere et movere',
+'delete_and_move_confirm'=> 'Ita, paginam delere',
+'immobile_namespace' => 'Destination title is of a special type; cannot move pages into that namespace.',
+
+'import-interwiki-namespace' => 'Transferre paginas in spatium nominale:',
+'import-interwiki-submit' => 'Importare',
+'importbadinterwiki' => 'Nexus intervicus malus',
+'export' => 'Paginas exportare',
+
+# Special:Allmessages
+'allmessages' => 'Nuntia systematis',
+'allmessagestext' => 'Hic est index omnium nuntiorum in MediaWiki',
+'allmessagescurrent' => 'Textus recens',
+'allmessagesmodified' => 'Ea solum modificata monstrare',
+'allmessagesname' => 'Nomen',
+
+# Special:Allpages
+'allpages' => 'Omnes paginae',
+'allarticles' => 'Omnes paginae',
+'allinnamespace' => 'Omnes paginae ($1 in spatio nominum)',
+'allnotinnamespace' => 'Omnes paginae (quibus in spatio $1 nominum exclusis)',
+'allpagesfrom' => 'Monstrare paginas ab:',
+'allpagesnext' => 'Proximum',
+'allpagesprefix' => 'Paginae quibus est prefix:',
+'allpagesprev' => 'Superior',
+'allpagessubmit' => 'Ire',
+
+# makesysop
+'already_sysop' => 'Hic usor etiam est [[{{int:grouppage-sysop}}|administratores]].',
+
+'grouppage-sysop' => '{{ns:project}}:Administratores',
+
+'alphaindexline' => '$1 ad $2',
+'import' => 'Paginas importare',
+'tooltip-save' => 'Servare mutationes tuas [alt-s]',
+'tooltip-diff' => 'Show which changes you made to the text. [alt-v]',
+'anonymous' => 'Usor ignotus {{SITENAME}}e',
+'lastmodifiedat' => 'Ultima mutatio: $2, $1.',
+'lastmodifiedatby' => 'Ultima mutatio: $2, $1 ab $3.',
+'and' => 'et',
+'subcategorycount' => 'Huic categoriae {{PLURAL:$1|una categoria inferior est|$1 categoriae inferiores sunt}}.',
+'categoryarticlecount' => 'Huic categoriae {{PLURAL:$1|una pagina est|$1 paginae sunt}}.',
+'mw_math_png' => 'Semper vertere PNG',
+'mw_math_simple' => 'HTML si admodum simplex, alioqui PNG',
+'mw_math_html' => 'HTML si fieri potest, alioqui PNG',
+'mw_math_source' => 'Stet ut TeX (pro navigatri texti)',
+'mw_math_modern' => 'Commendatum pro navigatri recentes',
+'mw_math_mathml' => 'MathML',
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Pagina usoris mea\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'The user page for the ip you\'re editing as\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Disputatum meum\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussion about edits from this ip address\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Praeferentiae meae\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Paginae quae custodis\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Index conlationum mearum\');
+ta[\'pt-login\'] = new Array(\'o\',\'Te conventum aperire hortamur, non autem requisitum\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Te conventum aperire hortamur, non autem requisitum\');
+ta[\'pt-logout\'] = new Array(\'\',\'Finire conventum\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Disputatio de hac pagina\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Hanc paginam recensere potes\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Huic disputationi adnotare\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Haec pagina protecta est\');
+ta[\'ca-history\'] = new Array(\'h\',\'Historia huius paginae\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Protegere hanc paginam\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Delere hanc paginam\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Reficere hanc pagina deleta\');
+ta[\'ca-move\'] = new Array(\'m\',\'Movere hanc paginam\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Tibi movere hanc paginam non licet\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Custodire hanc paginam\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Decustodire hanc paginam\');
+ta[\'search\'] = new Array(\'f\',\'Quaerere hanc wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Pagina prima\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Invisere paginae primae\');
+ta[\'n-portal\'] = new Array(\'\',\'De {{SITENAME}}\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Eventa novissima\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Index mutationum recentum\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Invisere paginae fortuitae\');
+ta[\'n-help\'] = new Array(\'\',\'Adiutatum de hac wiki\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Adiuvare hanc wiki\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Index paginarum quae hic nectunt\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Mutationes recentes in paginis quae hic nectunt\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS feed\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom feed\');
+ta[\'t-contributions\'] = new Array(\'\',\'Index conlationum huius usoris\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Mittere cursum publicum electronicum huic usoro\');
+ta[\'t-upload\'] = new Array(\'u\',\'Onerare fascicula\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Index paginarum specialium\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Videre paginam\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Videre paginam usoris\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'View the media page\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Haec paginam specialis est, paginam ipsam tibi recensere not licet\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'View the project page\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Videre paginam imaginem\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'View the system message\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'View the template\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Videre paginam adiutatam\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Videre paginam categoriam\');',
+'thumbsize' => 'Magnitudo pollicisunguis:',
+'newimages' => 'Pinacotheca imaginum novarum',
+'exif-pixelxdimension' => 'Valind image height',
+'watchlistall1' => 'omnes',
+'watchlistall2' => 'omnes',
+);
+?>
diff --git a/languages/messages/MessagesLi.php b/languages/messages/MessagesLi.php
new file mode 100644
index 000000000000..b1e3e061b6fe
--- /dev/null
+++ b/languages/messages/MessagesLi.php
@@ -0,0 +1,947 @@
+<?php
+/** Limburgian (Limburgs)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Oetgesjakeld', 'Links vas', 'Rechts vas', 'Links zwevend'
+);
+
+$skinNames = array(
+ 'standard' => 'Standaard',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Keuls blauw',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciaal',
+ NS_MAIN => '',
+ NS_TALK => 'Euverlik',
+ NS_USER => 'Gebroeker',
+ NS_USER_TALK => 'Euverlik_gebroeker',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Euverlik_$1',
+ NS_IMAGE => 'Aafbeilding',
+ NS_IMAGE_TALK => 'Euverlik_afbeelding',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Euverlik_MediaWiki',
+ NS_TEMPLATE => 'Sjabloon',
+ NS_TEMPLATE_TALK => 'Euverlik_sjabloon',
+ NS_HELP => 'Help',
+ NS_HELP_TALK => 'Euverlik_help',
+ NS_CATEGORY => 'Categorie',
+ NS_CATEGORY_TALK => 'Euverlik_categorie'
+);
+
+$namespaceAliases = array(
+ 'Kategorie' => NS_CATEGORY,
+ 'Euverlik_kategorie' => NS_CATEGORY_TALK,
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'M j, Y H:i',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'j M Y H:i',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'Y M j H:i',
+);
+
+$messages = array(
+'tog-underline' => 'Links ongersjtreipe',
+'tog-highlightbroken' => 'Formatteer gebraoke links <a href="" class="new">op dees meneer</a> (angesj: zoe<a href="" class="internal">?</a>).',
+'tog-justify' => 'Paragrafe oetvulle',
+'tog-hideminor' => 'Verbèrg klein bewirking bie recènte verangeringe',
+'tog-usenewrc' => 'Oetgebreide recènte vervangeringe (neet vuur alle browsers)',
+'tog-numberheadings' => 'Köpkes automatisch nummere',
+'tog-showtoolbar' => 'Laot edit toolbar zeen',
+'tog-editondblclick' => 'Bewirk pazjena\'s bie \'ne dubbelklik (JavaScript)',
+'tog-editsection' => 'Bewirke van secties via [bewirke] links',
+'tog-editsectiononrightclick'=> 'Sècties bewirke mit inne rechtermoesklik op sèctietitels (JavaScript)',
+'tog-showtoc' => 'Inhawdsopgaaf vuur pazjena\'s mit mië as 3 köpkes',
+'tog-rememberpassword' => 'Wachwaord ónthauwe bie \'t aafmèlde',
+'tog-editwidth' => 'Edit boks haet de vol breidte',
+'tog-watchdefault' => 'Voog pazjena\'s die se bewirks toe aan dien volglies',
+'tog-minordefault' => 'Merkeer sjtandaard alle bewirke as klein',
+'tog-previewonfirst' => 'Preview laote zien bie de iesjte bewirking',
+'tog-nocache' => 'Pazjena cache oetzitte',
+'tog-fancysig' => 'Handjteikening zónger link nao dien gebroekerspazjena',
+'sunday' => 'zondig',
+'monday' => 'maondig',
+'tuesday' => 'dinsdig',
+'wednesday' => 'goonsdag',
+'thursday' => 'donderdig',
+'friday' => 'vriedig',
+'saturday' => 'zaoterdig',
+'january' => 'jannewarie',
+'february' => 'fibberwari',
+'march' => 'maart',
+'april' => 'april',
+'may_long' => 'mei',
+'june' => 'juni',
+'july' => 'juli',
+'august' => 'augustus',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'december',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mrt',
+'apr' => 'apr',
+'may' => 'mei',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dec',
+'categories' => 'Categorieë',
+'pagecategories' => '{{PLURAL:$1|Categorie|Categorieë}}',
+'category_header' => 'Artikele in categorie "$1"',
+'subcategories' => 'Subkattegorië',
+'mainpage' => 'Huidpazjena',
+'mainpagetext' => 'Wiki software succesvol geïnsjtalleerd.',
+'portal' => 'Gebroekersportaol',
+'portal-url' => 'Project:Gebroekersportaol',
+'about' => 'Info',
+'aboutsite' => 'Euver {{SITENAME}}',
+'aboutpage' => 'Project:Info',
+'article' => 'Contentpazjena',
+'help' => 'Hulp',
+'helppage' => 'Project:Help',
+'bugreports' => 'Fouterapportaasj',
+'bugreportspage' => 'Project:Fouterapportaasj',
+'sitesupport' => 'Donaties',
+'sitesupport-url' => 'Project:Gifte',
+'faqpage' => 'Project:Veulgestjilde vraoge',
+'edithelp' => 'Hulp bie bewirke',
+'newwindow' => '(in nuui venster)',
+'edithelppage' => 'Help:Instructies',
+'cancel' => 'Aafbraeke',
+'qbfind' => 'Zeuke',
+'qbbrowse' => 'Bladere',
+'qbedit' => 'Bewirke',
+'qbpageoptions' => 'Pazjena-opties',
+'qbpageinfo' => 'Pazjena-informatie',
+'qbmyoptions' => 'mien opties',
+'qbspecialpages' => 'Speciaal pazjena\'s',
+'moredotdotdot' => 'Miè...',
+'mypage' => 'Mien gebroekerspazjena',
+'mytalk' => 'Mien euverlikpazjena',
+'anontalk' => 'Euverlik veur dit IP adres',
+'navigation' => 'Navegatie',
+'currentevents' => 'In \'t nuujs',
+'currentevents-url' => 'In \'t nuujs',
+'disclaimers' => 'Aafwiezinge aansjprakelikheid',
+'disclaimerpage' => '{{SITENAME}}: Algemein aafwiezing aansjprakelikheid',
+'privacypage' => 'Project:Privacy_policy',
+'errorpagetitle' => 'Fout',
+'returnto' => 'Truuk nao $1.',
+'tagline' => 'Van {{SITENAME}}',
+'search' => 'Zeuke',
+'searchbutton' => 'Zeuke',
+'go' => 'OK',
+'searcharticle' => 'OK',
+'history' => 'Historie',
+'history_short' => 'Historie',
+'printableversion' => 'Printer-vruntelike versie',
+'edit' => 'Bewirk',
+'editthispage' => 'Pazjena bewirke',
+'delete' => 'Wisse',
+'deletethispage' => 'Wisse',
+'protect' => 'Besjerm',
+'protectthispage' => 'Beveilige',
+'unprotect' => 'vriegaeve',
+'unprotectthispage' => 'Besjerming opheffe',
+'newpage' => 'Nuuj pazjena',
+'talkpage' => 'euverlikpazjena',
+'specialpage' => 'Speciaal Pazjena',
+'personaltools' => 'Persoenlike hulpmiddele',
+'articlepage' => 'Artikel',
+'talk' => 'Euverlik',
+'toolbox' => 'Gereidsjapskis',
+'userpage' => 'gebroekerspazjena',
+'imagepage' => 'Besjrievingspazjena',
+'viewtalkpage' => 'Bekiek euverlik',
+'otherlanguages' => 'Anger tale',
+'redirectedfrom' => '(Doorverweze van $1)',
+'redirectpagesub' => 'Redirectpazjena',
+'lastmodifiedat' => 'Dees pazjena is \'t litst verangert op $2, $1.',
+'viewcount' => 'Dees pazjena is $1 kier bekeke.',
+'copyright' => 'De inhawd is besjikbaar ónger de $1.',
+'protectedpage' => 'Beveiligde pazjena',
+'badaccess' => 'Toeganksfout',
+'retrievedfrom' => 'Aafkómstig van "$1"',
+'youhavenewmessages' => 'Doe höbs $1 ($2).',
+'newmessageslink' => 'nuuj berichte',
+'newmessagesdifflink' => 'Lèste verangering',
+'editsection' => 'bewirk',
+'toc' => 'Inhawd',
+'hidetoc' => 'verberg',
+'thisisdeleted' => '$1 bekieke of trökzètte?',
+'restorelink' => '$1 verwiederde versies',
+'nstab-main' => 'Artikel',
+'nstab-user' => 'Gebroeker',
+'nstab-image' => 'Aafbeilding',
+'nstab-mediawiki' => 'Berich',
+'nstab-template' => 'Sjabloon',
+'nstab-category' => 'Kategorie',
+'nosuchaction' => 'Gevraagde handeling bestjit neet',
+'nosuchactiontext' => 'De door de URL gespecifieerde handeling wordt neet herkend door de MediaWiki software',
+'nosuchspecialpage' => 'D\'r besjteit gein speciaal pazjena mit deze naam',
+'nospecialpagetext' => 'U heeft een speciale pagina aangevraagd die neet wordt herkend door de MediaWiki software',
+'error' => 'Fout',
+'databaseerror' => 'Databasefout',
+'dberrortext' => 'Bie \'t zeuke is \'n syntaxfout in de database opgetreje.
+Dit kint zien veroorzaak door \'n óngeljige zeukactie (zuug $5),
+of \'t duujt op \'n fout in de software.
+De lètste zeukpoeging in de database waor:
+<blockquote><tt>$1</tt></blockquote>
+vanoet de functie "<tt>$2</tt>".
+MySQL gaof de foutmèlling "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Dao is \'n syntaxfout opgetreje bie \'t zeuke in de database.
+De lèste opgevraogde zeukactie waor:
+"$1"
+vanoet de functie "$2".
+MySQL brach fout "$3" nao veure: "$4"',
+'noconnect' => 'Verbinden met de database op $1 was neet mogelijk',
+'nodb' => 'Selectie van database $1 neet mogelijk',
+'cachederror' => 'Dit is \'n gearsjiveerde kopie van de gevraogde pazjena, en is mesjien neet gans actueel.',
+'readonly' => 'Database geblokkeerd',
+'enterlockreason' => 'Gaef \'n rae veur de blokkering en wie lank \'t dinkelik zal dore. De ingegaeve rae zal aan de gebroekers getuind waere.',
+'readonlytext' => 'De database van {{SITENAME}} is momenteel gesloten voor nieuwe bewerkingen en wijzigingen, waarschijnlijk voor bestandsonderhoud.
+De verantwoordelijke systeembeheerder gaf hiervoor volgende reden op:
+<p>$1',
+'missingarticle' => 'De database haet \'n pazjenatèks ("$1") die \'t zou motte vinge neet gevonge. Dit is gein fout in de database, mer waarscjienlik in de software. Meld dit estebleef aan inne adminstrator, mit vermèlding van de URL.',
+'internalerror' => 'Interne fout',
+'filecopyerror' => 'Besjtand "$1" nao "$2" kopiëre neet mugelik.',
+'filerenameerror' => 'Verangere van de titel van \'t besjtand "$1" in "$2" neet meugelik.',
+'filedeleteerror' => 'Kos bestjand "$1" neet weghaole.',
+'filenotfound' => 'Kos bestjand "$1" neet vinge.',
+'unexpected' => 'Onverwachte waarde: "$1"="$2".',
+'formerror' => 'Fout: kos formeleer neet verzende',
+'badarticleerror' => 'Dees hanjeling kint neet weure oetgeveurd op dees pazjena.',
+'cannotdelete' => 'Kós de pazjena of aafbeilding neet wisse.',
+'badtitle' => 'Óngeljige pazjenatitel',
+'badtitletext' => 'De opgevraogde pazjena is neet besjikbaar of laeg.',
+'perfdisabled' => 'Om te veurkomme dat de database weurd euverbelast is dees pazjena allein tusje 03:00 en 15:00 (Wes-Europiese zoemertied) besjikbaar.',
+'perfdisabledsub' => 'Hie is \'n opgesjlage kopie van $1:',
+'perfcached' => 'De volgende data is gecachet en is mesjien neet gans up to date:',
+'viewsource' => 'Bekiek brónteks',
+'protectedtext' => 'Dizze pazjena is besjermd om bewirkinge te veurkomme; d\'r zint \'n aantal meugelike redene hieveur.
+Zuug ouch [[Project:Protected page]].
+
+De kins de brontèks van dees pazjena bekieke en kopiëre:',
+'logouttitle' => 'Aafmèlde gebroeker',
+'logouttext' => 'De bis noe aafgemèld. De kins {{SITENAME}} noe anoniem (mit vermèlding van [[IP adres]]) gebroeke, of opnuui aanmèlde onger dezelfde of ein anger naam.',
+'welcomecreation' => '<h2>Wilkóm, $1!</h2><p>Dien gebroekersprofiel is vaerdig. De kins noe dien persuunlike veurkäöre insjtèlle.',
+'loginpagetitle' => 'gebroekersnaam',
+'yourname' => 'Diene gebroekersnaam',
+'yourpassword' => 'Die wachwaord',
+'yourpasswordagain' => 'Wachwaord opnuuj intype',
+'remembermypassword' => 'Mien wachwaord onthouwe veur later sessies.',
+'yourdomainname' => 'Die domein',
+'loginproblem' => '<b>D\'r is \'n prebleim mèt \'t aanmèlde.</b><br />Probeer estebleef nog es.',
+'alreadyloggedin' => '<span style="color:#ff0000"><b>Gebroeker $1, de bis al aangemèld.</b></span><br />',
+'login' => 'Aanmèlde',
+'loginprompt' => 'Diene [[Browser|browser]] mót \'\'[[Cookie|cookie]]s\'\' acceptere óm in te logge op {{SITENAME}}.',
+'userlogin' => 'Aanmèlde',
+'logout' => 'Aafmèlde',
+'userlogout' => 'Aafmèlde',
+'nologin' => 'Höbs te nog geine gebroekersnaam? $1.',
+'nologinlink' => 'Maak \'ne gebroekersnaam aan',
+'createaccount' => 'Nuuj gebroekersprofiel aanmake.',
+'gotaccount' => 'Höbs te al \'ne gebroekersnaam? $1.',
+'createaccountmail' => 'per e-mail',
+'badretype' => 'De ingeveurde wachwäörd versjille vanein.',
+'userexists' => 'De gebroekersnaam dae se höbs ingeveurd weurt al gebroek. Kees estebleef \'n anger naam.',
+'youremail' => 'Dien e-mailadres',
+'username' => 'Gebroekersnaam:',
+'uid' => 'Gebroekersnómmer:',
+'yourrealname' => 'Dienen echte naam*',
+'yourlanguage' => 'Taal van de gebroekersinterface',
+'yourvariant' => 'Taalvariant',
+'yournick' => 'Diene bienaam (veur \'\'handjteikeninge\'\')',
+'badsig' => 'Óngeljige roew handjteikening; zuug de HTML-tags nao.',
+'loginerror' => 'Inlogfout',
+'prefs-help-email' => '* E-mail (optioneel): Hiedoor kan me contak mit diech opnumme zónger dats te dien identiteit hoofs vrie te gaeve.',
+'noname' => 'De mos \'n gebroekersnaam opgaeve.',
+'loginsuccesstitle' => 'Aanmèlde geluk.',
+'loginsuccess' => 'De bis noe es "$1" aangemèld bie {{SITENAME}}.',
+'nosuchuser' => 'Er bestaat geen gebroeker met de naam "$1". Controleer uw spelling, of gebruik onderstaand formulier om een nieuw gebroekersprofiel aan te maken.',
+'wrongpassword' => '\'t Ingegaeve wachwaord is neet zjus. Perbeer \'t obbenuujts.',
+'wrongpasswordempty' => '\'t Ingegaeve wachwoord waor laeg. Perbeer \'t obbenuujts.',
+'mailmypassword' => 'Sjik mich \'n nuuj wachwaord',
+'passwordremindertitle' => 'Wachwaordherinnering van {{SITENAME}}',
+'passwordremindertext' => 'Emes (waarsjienliek dich zelf) vanaaf IP-adres $1 haet verzoch u een nieuw wachtwoord voor {{SITENAME}} toe te zenden ($4). Het nieuwe wachtwoord voor gebroeker "$2" is "$3". Advies: nu aanmelden en uw wachtwoord wijzigigen.',
+'noemail' => 'D\'r is gein geregistreerd e-mailadres veur "$1".',
+'passwordsent' => 'D\'r is \'n nuui wachwaord verzonde nao \'t e-mailadres dat geregistreerd sjtit veur "$1".
+Gelieve na ontvangst opnieuw aan te melden.',
+'eauthentsent' => 'Dao is \'ne bevèstigingse-mail nao \'t genomineerd e-mailadres gesjik.
+Iedat anger mail nao dat account versjik kan weure, mós te de insjtructies in daen e-mail volge,
+óm te bevèstige dat dit wirkelik dien account is.',
+'mailerror' => 'Fout bie \'t versjture van mail: $1',
+'acct_creation_throttle_hit'=> 'Sorry, de höbs al $1 accounts aangemak. De kins d\'r gein mië aanmake.',
+'emailauthenticated' => 'Dien e-mailadres is op $1 geauthentiserd.',
+'emailnotauthenticated' => 'Dien e-mailadres is nog neet geauthentiseerd. De zals gein
+e-mail óntvange veur alle volgende toepassinge.',
+'emailconfirmlink' => 'Bevèstig dien e-mailadres',
+'bold_sample' => 'Vetten teks',
+'bold_tip' => 'Vetten teks',
+'italic_sample' => 'Italic tèks',
+'italic_tip' => 'Italic tèks',
+'link_sample' => 'Link titel',
+'link_tip' => 'Interne link',
+'extlink_sample' => 'http://www.example.com link titel',
+'extlink_tip' => 'Externe link (mit de http:// prefix)',
+'math_tip' => 'Wiskundige formule (LaTeX)',
+'summary' => 'Samevatting',
+'minoredit' => 'Dit is \'n klein verangering',
+'watchthis' => 'Volg dees pazjena',
+'savearticle' => 'Pazjena opsjlaon',
+'preview' => 'Naokieke',
+'showpreview' => 'Bekiek dees bewirking',
+'showdiff' => 'Toen verangeringe',
+'anoneditwarning' => 'You are not logged in. Your IP address will be recorded in this page\'s edit history.',
+'blockedtitle' => 'Gebroeker is geblokkeerd',
+'blockedtext' => 'Diene gebroekersnaam of IP-adres is geblokkeerd door $1. De opgegaeve raeje:<br />$2<br />De kins veur euverlik kontak opnumme mit de [[Project:Systeemwèrkers|systeemwèrkers]].
+
+Your IP address is $3. Please include this address in any queries you make.',
+'whitelistedittitle' => 'Geer mót óch inlogke óm te bewirke',
+'whitelistedittext' => 'Geer mót uch $1 óm pajzená te bewirke.',
+'whitelistreadtitle' => 'Geer mót óch inlogke óm dit te kónne laeze',
+'whitelistreadtext' => 'Geer mót óch [[Special:Userlogin|inlogke]] óm pazjena\'s te laeze.',
+'whitelistacctitle' => 'Geer maag gein account aanmake',
+'whitelistacctext' => 'Óm accounts op dees wiki aan te make mót geer [[Special:Userlogin|ingelog]] zeen en de zjuste permissies höbbe.',
+'loginreqlink' => 'inglogge',
+'loginreqpagetext' => 'De mos $1 om anger pazjenas te bekieke.',
+'accmailtitle' => 'Wachwaord versjtuurd.',
+'accmailtext' => '\'t Wachwaord veur \'$1\' is nao $2 versjtuurd.',
+'newarticle' => '(Nuuj)',
+'newarticletext' => 'De höbs \'ne link gevolg nao \'n pazjena die nog neet besjteit.
+Type in de box hiejónger óm de pazjena te beginne (zuug de [[Help:Contents|helppazjena]] veur mier informatie). Es te hie per óngelök terech bis gekómme, klik dan op de \'\'\'trök\'\'\'-knóp van diene browser.',
+'anontalkpagetext' => '----\'\'Dit is de euverlikpazjena veur \'ne anonieme gebroeker dae nog gein account haet aangemak of dae \'t neet gebroek. Daorom gebroeke v\'r \'t [[IP adres]] om de gebroeker te identificere. Dat adres kint weure gedeild doer miedere gebroekers. As e \'ne anonieme gebroeker bis en de höbs \'t geveul dat \'r onrillevante commentare aan dich gericht zint, kins e \'t biste [[Special:Userlogin|\'n account crëere of inlogge]] om toekomstige verwarring mit angere anonieme gebroekers te veurkomme.\'\'',
+'noarticletext' => '(Dees pazjena bevat op \'t moment gein teks)',
+'clearyourcache' => '\'\'\'Lèt op:\'\'\' Nao \'t opsjlaon mós te diene browserbuffer wisse óm de verangeringe te zeen: \'\'\'Mozilla:\'\'\' klik \'\'Reload\'\' (of \'\'Ctrl-R\'\'), \'\'\'Firefox / IE / Opera:\'\'\' \'\'Ctrl-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-R\'\', \'\'\'Konqueror\'\'\' \'\'Ctrl-R\'\'.',
+'updated' => '(Biegewèrk)',
+'note' => '<strong>Opmirking:</strong>',
+'previewnote' => 'Lèt op: dit is \'n controlepazjena; dien tèks is nog neet opgesjlage!',
+'previewconflict' => 'Dees versie toent wie de tèks in \'t bôvesjte vèld oet git zeen es e zouws opsjlaon.',
+'editing' => 'Bewirkingspazjena: $1',
+'editinguser' => 'Bewirkingspazjena: $1',
+'editingsection' => 'Bewirke van sectie van $1',
+'editingcomment' => 'Bewirk $1 (commentair)',
+'editconflict' => 'Bewirkingsconflik: $1',
+'explainconflict' => 'Jemes angers haet dees pazjena verangerd naodats doe aan dees bewèrking bis begos. \'t Ierste teksveld tuint de hujige versie van de pazjena. De mós dien eige verangeringe dao-in inpasse. Allein d\'n tèks in \'t ierste teksveld weurt opgesjlaoge wens te noe op "Pazjena opsjlaon" duujs.<br />',
+'yourtext' => 'Euren teks',
+'storedversion' => 'Opgesjlage versie',
+'nonunicodebrowser' => '<strong>WAARSJUWING: Diene browser is voldit neet aan de unicode sjtandaarde, gebroek estebleef inne angere browser veurdas e artikele gis bewirke.</strong>',
+'editingold' => '<strong>WAARSJUWING: De bis \'n aw versie van dees pazjena aan \'t bewirke. Es e dees bewirking opjsleis, gaon alle verangeringe die na dees versie zien aangebrach verlore.</strong>',
+'yourdiff' => 'Verangeringe',
+'copyrightwarning' => 'Opgelèt: Alle biedrage aan {{SITENAME}} weure geach te zeen vriegegaeve ónger de $2 (zuug $1 veur details). Wens te neet wils dat dienen teks door angere bewirk en versjpreid weurt, kees dan neet veur \'Pazjena opsjlaon\'.<br /> Hiebie belaofs te ós ouch dats te dees teks zelf höbs gesjreve, of höbs euvergenómme oet \'n vriej, openbaar brón.<br /> <strong>GEBROEK GEI MATERIAAL DAT BESJIRMP WEURT DOOR AUTEURSRECH, BEHAUVE WENS TE DAO TOESJTÖMMING VEUR HÖBS!</strong>',
+'copyrightwarning2' => 'Mèrk op dat alle biedrages aan {{SITENAME}} kinne weure verangerd, aangepas of weggehaold door anger luuj. As te neet wils dat dienen tèks zoemer kint weure aangepas mós te \'t hie neet plaatsje.<br />
+De beluifs ós ouch dats te dezen tèks zelf höbs gesjreve, of gekopieerd van \'n brón in \'t [[Publiek|publiek]] domein of get vergliekbaars (zuug $1 veur details).
+<strong>HIE GEIN AUTEURSRECHTELIK BESJIRMP WERK ZÓNGER TOESJTUMMING!</strong>',
+'longpagewarning' => 'WAARSJOEWING: Dees pazjena is $1 kilobytes lank; \'n aantal browsers kint probleme höbbe mit \'t verangere van pazjena\'s in de buurt van of groeter es 32 kB. Kiek ofs te sjtökker van de pazjena mesjiens kins verplaatse nao \'n nuuj pazjena.',
+'readonlywarning' => 'WAARSJUWING: De database is vasgezèt veur ongerhoud, dus op \'t mement kins e dien verangeringe neet opsjlaon. De kins dien tèks \'t biste opsjlaon in \'n tèksbesjtand om \'t later hie nog es te prebere.',
+'protectedpagewarning' => 'WAARSJUWING: Dees pazjena is besjermd zoedat ze allein doer gebroekers mit administratorrechte kint weure verangerd.',
+'templatesused' => 'Sjablone gebroek in dees pazjena:',
+'edittools' => '[[literal]] translation',
+'revhistory' => 'Bewirkingshistorie',
+'nohistory' => 'Dees pazjena is nog neet bewirk.',
+'revnotfound' => 'Wieziging neet gevonge',
+'revnotfoundtext' => 'De opgevraogde aw versie van dees pazjena is verzjwónde. Kontroleer estebleef de URL dieste gebroek höbs óm nao dees pazjena te gaon.',
+'loadhist' => 'Bezig met \'t laje van de pazjenahistorie',
+'currentrev' => 'Hujige versie',
+'revisionasof' => 'Versie op $1',
+'previousrevision' => '← Awwer versie',
+'currentrevisionlink' => 'zuug hujige versie',
+'cur' => 'hujig',
+'next' => 'volgende',
+'last' => 'vörrige',
+'histlegend' => 'Verklaoring aafkortinge: (wijz) = versjil mit actueile versie, (vörrige) = versjil mit vörrige versie, K = kleine verangering',
+'deletedrev' => '[gewis]',
+'difference' => '(Versjil tösje bewirkinge)',
+'loadingrev' => 'bezig mit \'t laje van de pazjenaversie',
+'lineno' => 'Regel $1:',
+'editcurrent' => 'De hujige versie van dees pazjena bewirke.',
+'selectnewerversionfordiff'=> 'Kees \'n nuuiere versie om te vergelieke',
+'selectolderversionfordiff'=> 'Kees \'n auwere versie om te vergelieke',
+'compareselectedversions'=> 'Vergeliek geselecteerde versies',
+'searchresults' => 'Zeukresultate',
+'searchresulttext' => 'Veur mier informatie euver zeuke op {{SITENAME}}, zuug [[Project:Searching|Zeuke op {{SITENAME}}]].',
+'searchsubtitleinvalid' => 'Voor zoekopdracht "$1"',
+'badquery' => 'Ónzjus geformuleerde zeukopdrach',
+'badquerytext' => 'Diene zeukopdrach kós neet oetgeveurd weure. Waarsjienlik kump dit doordas te höbs geperbeerd e woord van minder as drie lètters te zeuke; dat weurt neet doer de software óngersjteundj. \'t Is ouch meugelik dats te de zeuktèrm verkierd höbs ingegaeve.',
+'matchtotals' => 'De zeukterm "$1" is gevonge in $2 pazjenatitels en in de tèks van $3 pazjena\'s.',
+'titlematches' => 'Overeinkoms mèt volgende titels',
+'notitlematches' => 'Geen enkele paginatitel gevonden met de opgegeven zoekterm',
+'textmatches' => 'Euvereinkoms mèt artikelinhoud',
+'notextmatches' => 'Geen artikel gevonden met opgegeven zoekterm',
+'prevn' => 'vörrige $1',
+'nextn' => 'volgende $1',
+'viewprevnext' => '($1) ($2) ($3) bekieke.',
+'showingresults' => 'Hieonger de <b>$1</b> resultate, vanaaf #<b>$2</b>.',
+'showingresultsnum' => 'Hieonger de <b>$3</b> resultate vanaaf #<b>$2</b>.',
+'nonefound' => '<strong>Lèt op:</strong> \'n zeukopdrach kan mislökke door \'t gebroek van (in \'t Ingelsj) väöl veurkómmende wäörd wie "of" en "be", die neet geïndexeerd zint, of door versjillende zeukterme tegeliek op te gaeve (de kries dan allein pazjena\'s te zeen woerin alle opgegaeve terme veurkómme).',
+'powersearch' => 'Zeuke',
+'powersearchtext' => '
+ Zeuk in naomroemdes :<br />
+$1<br />
+$2 Toen redirects Zeuk: $3 $9',
+'searchdisabled' => '<p style="margin: 1.5em 2em 1em">Zeuke op {{SITENAME}} is oetgesjakeld vanweige gebrek aan servercapaciteit. Zoelang as de servers nog neet sjterk genog zunt kins e zeuke bie Google.
+<span style="font-size: 89%; display: block; margin-left: .2em">Mèrk op dat hun indexe van {{SITENAME}} content e bietje gedatierd kint zien.</span></p>',
+'blanknamespace' => '(huidnaamruumde)',
+'preferences' => 'Veurkäöre',
+'prefsnologin' => 'Neet aangemèld',
+'prefsnologintext' => 'De mos zien [[Special:Userlogin|aangemèld]] om veurkäöre te kinne insjtèlle.',
+'prefsreset' => 'Sjtandaardveurkäöre hersjtèld.',
+'qbsettings' => 'Menubalkinsjtèllinge',
+'changepassword' => 'Wachwaord verangere',
+'skin' => '{{SITENAME}}-uterlik',
+'math' => 'Mattemetik rendere',
+'dateformat' => 'Datumformaat',
+'datedefault' => 'Gein veurkäör',
+'datetime' => 'Datum en tied',
+'math_unknown_error' => 'onbekènde fout',
+'math_unknown_function' => 'onbekènde functie',
+'math_bad_output' => 'Kin neet sjrieve nao de output directory veur mattematik',
+'prefs-personal' => 'Gebroekersinfo',
+'prefs-rc' => 'Recènte verangeringe en weergaaf van sjtumpkes',
+'prefs-misc' => 'Anger insjtèllinge',
+'saveprefs' => 'Veurkäöre opsjlaon',
+'resetprefs' => 'Sjtandaardveurkäöre hersjtèlle',
+'oldpassword' => 'Hujig wachwaord',
+'newpassword' => 'Nuuj wachwaord',
+'retypenew' => 'Veur \'t nuuj wachwaord nogins in',
+'textboxsize' => 'Aafmeitinge tèksveld',
+'rows' => 'Raegels',
+'columns' => 'Kolomme',
+'searchresultshead' => 'Insjtèllinge veur zeukresultate',
+'resultsperpage' => 'Aantal te toene zeukresultate per pazjena',
+'contextlines' => 'Aantal reigels per gevónje pazjena',
+'contextchars' => 'Aantal teikes van de conteks per reigel',
+'stubthreshold' => 'Een pazjena weurd als \'sjtumpke\' besjauwd mit \'n groette kleiner as',
+'recentchangescount' => 'Aantal titels in lies recènte verangeringe',
+'savedprefs' => 'Dien veurkäöre zint opgesjlage.',
+'timezonelegend' => 'Tiedzone',
+'timezonetext' => '\'t Aantal oere dat diene lokale tied versjilt van de servertied (UTC).',
+'localtime' => 'Plaotsjelike tied',
+'timezoneoffset' => 'tiedsverschil',
+'servertime' => 'Server tied is noe',
+'guesstimezone' => 'Invulle van browser',
+'allowemail' => 'E-mail van anger gebroekers toesjtaon',
+'defaultns' => 'Zeuk sjtandaard in dees naomruumdes:',
+'default' => 'sjtandaard',
+'changes' => 'verangeringe',
+'recentchanges' => 'Recènte verangeringe',
+'recentchangestext' => '[[literal] translation',
+'rcnote' => 'Hiejónger sjtaon de <strong>$1</strong> lètste verangeringe van de aafgeloupe <strong>$2</strong> daag, $3.',
+'rcnotefrom' => 'Verangeringe sins <b>$2</b> (mit \'n maximum van <b>$1</b> verangeringe).',
+'rclistfrom' => 'Toen de verangeringe vanaaf $1',
+'rclinks' => 'Bekiek de $1 litste verangeringe van de aafgelaupe $2 daag.<br />$3',
+'diff' => 'vera',
+'hide' => 'verberg',
+'show' => 'toen',
+'minoreditletter' => 'K',
+'upload' => 'Upload',
+'uploadbtn' => 'upload file',
+'reupload' => 'Opnuui uploade',
+'reuploaddesc' => 'Truuk nao \'t uploadformeleer.',
+'uploadnologin' => 'Neet aangemèld',
+'uploadnologintext' => 'De mos [[Special:Userlogin|zien aangemèld]] om besjtande te uploade.',
+'uploaderror' => 'upload fout',
+'uploadtext' => 'Gebroek \'t óngersjtaonde formuleer óm besjtande op te laje. Óm ierder opgelaje besjtande te bekieke of te zeuke, gank nao de [[Special:Imagelist|lies van opgelaje besjtande]]. Uploads en verwiederinge waere ouch biegehauwte in \'t [[Special:Log/upload|uploadlogbook]].
+
+Gebroek óm \'n plaetje of \'n besjtand in \'n pazjena op te numme \'ne link in de vörm:
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Besjtand.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Besjtand.png|alternatief teks]]</nowiki>\'\'\'
+of veur mediabesjtande:
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Besjtand.ogg]]</nowiki>\'\'\'',
+'uploadlog' => 'uploadlogbook',
+'uploadlogpage' => 'Uploadlogbook',
+'uploadlogpagetext' => 'Hieonger de lies mit de meist recent ge-uploade besjtande. Alle tiede zunt servertiede (UTC).
+<ul>
+</ul>',
+'filename' => 'Besjtandsnaom',
+'filedesc' => 'Besjrieving',
+'filesource' => 'Bron',
+'copyrightpage' => 'Project:Auteursrechte',
+'copyrightpagename' => '{{SITENAME}} auteursrechte',
+'uploadedfiles' => 'Ge-uploade bestanden',
+'minlength' => 'De naom van \'t besjtand mot oet minstes drie teikes besjtaon.',
+'badfilename' => 'De naom van \'t besjtand is verangerd in "$1".',
+'badfiletype' => '".$1" is gein aanbevole besjtandjsformaat veur aafbeildinge.',
+'largefile' => 'Maak aafbeildinge neet groter as $1 bytes; this file is $2 bytes',
+'emptyfile' => '\'t Besjtand wats re höbs geupload is laeg. Dit kump waorsjienliek door \'n typfout in de besjtandsnaom. Kiek estebleef ofs te dit besjtand wirkelik wils uploade.',
+'fileexists' => 'D\'r is al e besjtand mit dees naam, bekiek $1 of se dat besjtand mesjien wils vervange.',
+'successfulupload' => 'De upload is geluk',
+'fileuploaded' => '<b>Het uploaden van bestand "$1" is geslaagd.</b> Gelieve deze link naar de omschrijvingspagina te volgen: ($2). Vul daar informatie in over dit bestand, bijvoorbeeld de oorsprong, wanneer en door wie het gemaakt is en wat u verder er nog over te vertellen heeft.',
+'uploadwarning' => 'Upload waarsjuwing',
+'savefile' => 'Bestand opsjlaon',
+'uploadedimage' => 'haet ge-upload: [[$1]]',
+'destfilename' => 'Doeltitel',
+'imagelist' => 'Lies van aafbeildinge',
+'imagelisttext' => 'Hie volgt \'n lies mit $1 afbeildinge geordend $2.',
+'getimagelist' => 'Lies van aafbeildinge ophaole',
+'ilsubmit' => 'Zeuk',
+'showlast' => 'Toen de litste $1 aafbeildinge geordend $2.',
+'byname' => 'op naom',
+'bydate' => 'op datum',
+'bysize' => 'op gruutde',
+'imgdelete' => 'verw',
+'imgdesc' => 'besc',
+'imglegend' => 'Oetlik: (besc) = toen/veranger besjrieving van de aafbeilding, (verw) = wis de aafbeilding.',
+'imghistory' => 'Historie van de aafbeilding',
+'deleteimg' => 'wis',
+'deleteimgcompletely' => 'Wis al versies',
+'imghistlegend' => 'Oetlik: (cur)= huidige aafbeilding, (verw) = wis de aw versie, (rev) = zit aw versie truuk.<br />
+<i>Klik op de datum om de aafbeildinge die ge-upload zint op die datum te zeen</i>.',
+'imagelinks' => 'Aafbeildingsverwiezinge',
+'linkstoimage' => 'Dees aafbeilding weurt op de volgende pazjena\'s gebroek:',
+'nolinkstoimage' => 'Gein enkele pazjena gebroek dees aafbeilding.',
+'sharedupload' => '[[literal]] translation',
+'statistics' => 'Sjtattestieke',
+'sitestats' => 'Sjtatistieke euver {{SITENAME}}',
+'userstats' => 'Stattestieke euver gebroekers',
+'sitestatstext' => 'D\'r zunt in totaal \'\'\'$1\'\'\' pazjena\'s in de database.
+Dit is inclusief "euverlik"-pazjena\'s, pazjena\'s euver {{SITENAME}}, extreem korte "sjtumpkes", redirects, en anger pazjena\'s die waarsjienlik neet as inhoud mote waere getèld. \'t Aantal pazjena\'s mit content weurt gesjat op \'\'\'$2\'\'\'.
+
+D\'r zunt \'\'\'$8\'\'\' besjtande opgelaje.
+
+D\'r is in totaal \'\'\'$3\'\'\' kier \'n pazjena bekeke en \'\'\'$4\'\'\' kier \'n pazjena bewirk sins de wiki is opgezat. Dat geuf e gemiddelde van \'\'\'$5\'\'\' bewirkinge per pazjena en \'\'\'$6\'\'\' getuinde pazjena\'s per bewirking.
+
+De lengde van de [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] is \'\'\'$7\'\'\'.',
+'userstatstext' => 'D\'r zeen \'\'\'$1\'\'\' geregistreerde gebroekers; \'\'\'$2\'\'\' (of \'\'\'$4\'\'\') hievan zeen systeemwèrkers (zuug $3).',
+'disambiguations' => 'Verdudelikingspazjena\'s',
+'disambiguationspage' => 'Template:Verdudeliking',
+'disambiguationstext' => 'De ongersjtaonde artikele verwieze nao \'n <i>verdudelikingspazjena</i>. Dees zouwe waorsjienlik direk nao de pazjena euver \'t betriffend óngerwerp mótte verwieze.<br />Verdudelikingspazjena\'s zeen pazjena\'s woe vanaaf $1 nao verwieze weurt.<br />Opmèrking: Dees lies tuint allein pazjena\'s vanoet de hoofnaomruumde, en dus gein dinger wie euverlèkpazjena\'s of projekpazjena\'s.',
+'doubleredirects' => 'Dobbel redirects',
+'doubleredirectstext' => '<b>Kiek oet:</b> In dees lies kanne redirects sjtaon die neet dao-in toeshure. Dat kump meistal doordat nao de #REDIRECT nog anger links op de pazjena sjtaon.<br />
+Op eder raegel vings te de ierste redirectpazjena, de twiede redirectpazjena en de iesjte raegel van de twiede redirectpazjena. Normaal bevat dees litste de pazjena woe de iesjte redirect naotoe zouw mótte verwieze.',
+'brokenredirects' => 'Gebraoke redirects',
+'brokenredirectstext' => 'De óngersjtaonde redirectpazjena\'s bevatte \'n redirect nao \'n neet-besjtaonde pazjena.',
+'nbytes' => '$1 bytes',
+'ncategories' => '$1 categories',
+'nlinks' => '$1 verwiezinge',
+'nrevisions' => '$1 revisions',
+'nviews' => '$1 kier bekeke',
+'lonelypages' => 'Weispazjena\'s',
+'uncategorizedpages' => 'Ongekattegoriseerde pazjena\'s',
+'uncategorizedcategories'=> 'Ongekattegoriseerde kattegorië',
+'unusedcategories' => 'Óngebroekde kategorieë',
+'unusedimages' => 'Ongebroekde aafbeildinge',
+'popularpages' => 'Populaire artikels',
+'wantedcategories' => 'Gewunsjde categorieë',
+'wantedpages' => 'Gewunsjde pazjena\'s',
+'mostlinked' => 'Meis gelinkde pazjena\'s',
+'mostcategories' => 'Artikele mit de meiste kategorieë',
+'mostimages' => 'Meis gelinkde aafbeildinge',
+'mostrevisions' => 'Artikele mit de meiste bewirkinge',
+'allpages' => 'Alle pazjena\'s',
+'randompage' => 'Willekäörige pazjena',
+'shortpages' => 'Korte artikele',
+'longpages' => 'Lang artikele',
+'deadendpages' => 'Doedloupende pazjena\'s',
+'listusers' => 'Lies van gebroekers',
+'specialpages' => 'Speciaal pazjena\'s',
+'spheading' => 'Speciaal pazjena\'s',
+'recentchangeslinked' => 'Volg links',
+'rclsub' => '(van pazjena\'s woe "$1" heen verwiest)',
+'newpages' => 'Nuuj pazjena\'s',
+'ancientpages' => 'Artikele die lank neet bewèrk zeen',
+'move' => 'Verplaats',
+'movethispage' => 'Verplaats dees pazjena',
+'unusedimagestext' => '<p>Lèt op! \'t Zou kinne dat er via een directe link verweze weurt nao \'n aafbeilding, bevoorbild vanoet \'n angesjtalige {{SITENAME}}. Het is daorom meugelijk dat \'n aafbeilding hie vermeld sjtit terwiel e toch gebroek weurt.',
+'booksources' => 'Bookwinkele',
+'categoriespagetext' => 'De wiki haet de volgende categorieë:',
+'data' => 'Gegaeves',
+'booksourcetext' => 'Hiejónger \'n lies van extern websites die beuk verkoupe en ouch wiejer informatie hie-euver kinne gaeve. Via \'n ISBN-nómmer in \'n artikel kins te via dees pazjena e werk opzeuke. <p>Dees deens is inkel ter informatie. {{SITENAME}} haet <u>gein ènkel</u> relatie met dees websites.',
+'alphaindexline' => '$1 nao $2',
+'version' => 'Versie',
+'log' => 'Logbeuk',
+'alllogstext' => 'Dit is \'t gecombineerd logbook. De kins ouch \'n bepaald logbook keze, of filtere op gebroekersnaam of pazjena.',
+'nextpage' => 'Volgende pazjena ($1)',
+'allpagesfrom' => 'Tuin pazjena\'s vanaaf:',
+'allarticles' => 'Alle artikele',
+'allinnamespace' => 'Alle pazjena\'s (naamruumde $1)',
+'allnotinnamespace' => 'Alle pazjena\'s (neet in naamruumde $1)',
+'allpagesprev' => 'Veurige',
+'allpagesnext' => 'Volgende',
+'allpagessubmit' => 'OK',
+'allpagesprefix' => 'Tuin pazjena\'s mèt \'t veurvoogsel:',
+'mailnologin' => 'Gein e-mailadres bekènd veur deze gebroeker',
+'mailnologintext' => 'De mos zien [[Special:Userlogin|aangemèld]] en \'n gèldig e-mailadres in bie dien [[Special:Preferences|veurkäöre]] höbbe ingevuld om mail nao anger gebroekers te sjture.',
+'emailuser' => 'Sjik deze gebroeker \'nen e-mail',
+'emailpage' => 'Sjik gebroeker \'nen e-mail',
+'emailpagetext' => 'As deze gebroeker e geljig e-mailadres heet opgegaeve dan kant geer via dit formuleer e berich sjikke. \'t E-mailadres wat geer heet opgegeve bie eur veurkäöre zal as versjikker aangegaeve waere.',
+'noemailtitle' => 'Gein e-mailadres bekènd veur deze gebroeker',
+'noemailtext' => 'Deze gebroeker haet gein gèldig e-mailadres opgegaeve of haet dees functie oetgesjakeld.',
+'emailfrom' => 'Van',
+'emailto' => 'Aan',
+'emailsubject' => 'Óngerwerp',
+'emailmessage' => 'Berich',
+'emailsend' => 'Sjik berich',
+'emailsent' => 'E-mail sjikke',
+'emailsenttext' => 'Die berich is versjik.',
+'watchlist' => 'Volglies',
+'nowatchlist' => 'D\'r sjtit niks op dien volglies.',
+'watchnologin' => 'De bis neet aangemèld',
+'watchnologintext' => 'De mós [[Special:Userlogin|aangemèld]] zeen veur \'t verangere van dien volglies.',
+'addedwatch' => 'Aan volglies toegeveug',
+'addedwatchtext' => 'De pazjena "$1" is aan dien [[Special:Watchlist|volglies]] toegeveug.
+Toekomstige verangeringe aan deze pazjena en de biebehurende euverlikpazjena weure hie vermèld.
+Ouch versjiene gevolgde pazjena\'s in \'t <b>vet</b> in de [[Special:Recentchanges|liest van recènte verangeringe]]. <!-- zodat u ze eenvoudiger kan opmerken.-->
+
+<!-- huh? Wen se ein pazjena van dien volgliest wils haole mos e op "sjtop volge" -- pagina wenst te verwijderen van uw volgliest klik dan op "Van volgliest verwijderen" in de menubalk. -->',
+'removedwatch' => 'Van volglies aafhoale',
+'removedwatchtext' => 'De pazjena "$1" is van dien volglies aafgehaold.',
+'watch' => 'Volg',
+'watchthispage' => 'Volg dees pazjena',
+'unwatch' => 'Sjtop volge',
+'unwatchthispage' => 'Neet mië volge',
+'notanarticle' => 'Is gein artikel',
+'watchnochange' => 'Gein van dien gevolgde items is aangepas in dees periode.',
+'watchdetails' => 'Dao sjtaon $1 pazjena\'s op dien volglies mèt oetzunjering van de euverlikpazjena\'s. De kèns dien kómplete volglies [[Special:Watchlist/edit|bekieke en verangere]].',
+'wlheader-showupdated' => '* Pazjena\'s die verangerd zeen saers doe ze veur \'t lètste bezaogs sjtaon \'\'\'vet\'\'\'',
+'watchmethod-recent' => 'Controleer recènte verangere veur gevolgde pazjena\'s',
+'watchmethod-list' => 'controlere van gevolgde pazjena\'s veur recènte verangeringe',
+'removechecked' => 'Verwieder aangevinkde pazjena\'s van dien volglies',
+'watchlistcontains' => 'Dien volglies bevat $1 pazjena\'s.',
+'watcheditlist' => 'Hie is ein alfabetische lies van de door dich gevolgde pazjena\'s. Vink de veerkentjes van de pazjena\'s dies te van dien volglies wils haole aan en klik op de "wisse"-knop hieonger.',
+'removingchecked' => 'Pazjena\'s van volglies aafgehaold...',
+'couldntremove' => 'Kós item \'$1\' neet wisse...',
+'wlnote' => 'Hieonger de lètste $1 verangeringe van de lètste <b>$2</b> oor.',
+'wlshowlast' => 'Tuin lètste $1 ore $2 daag $3',
+'wlsaved' => 'Dit is \'n opgesjlage versie van dien volglies.',
+'wlhideshowown' => '$1 mien bewirkinge.',
+'wlhideshowbots' => '$1 robotbewirkinge.',
+'enotif_mailer' => '{{SITENAME}} notificatiemail',
+'enotif_reset' => 'Mèrk alle bezochde pazjena\'s aan.',
+'enotif_newpagetext' => 'DIt is \'n nuuj pazjena.',
+'changed' => 'verangerd',
+'created' => 'aangemaak',
+'enotif_subject' => 'De {{SITENAME}}pazjena $PAGETITLE is $CHANGEDORCREATED door $PAGEEDITOR',
+'enotif_lastvisited' => 'Zuug $1 veur al verangeringe saer dien lèste bezeuk.',
+'enotif_body' => 'Bèste $WATCHINGUSERNAME,
+
+De {{SITENAME}}-pazjena "$PAGETITLE" is $CHANGEDORCREATED op $PAGEEDITDATE door $PAGEEDITOR, zuug $PAGETITLE_URL veur de hujige versie.
+
+$NEWPAGE
+
+Bewirkingssamevatting: $PAGESUMMARY $PAGEMINOREDIT
+
+Contacteer de bewirker:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Dao zalle bie volgende verangeringe gein nuuj berichte kómme tenzies te dees pazjena obbenuujts bezeuks. De kans ouch de notificatievlegskes op dien volglies verzètte.
+
+ \'t {{SITENAME}}-notificatiesysteem
+
+--
+Óm de insjtèllinge van dien volglies te verangere, zuug
+{{fullurl:Special:Watchlist/edit}}
+
+Commentaar en wiejer assistentie:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Pazjena wisse',
+'confirm' => 'Bevèstig',
+'excontent' => 'inhawd waor: \'$1\'',
+'excontentauthor' => 'inhawd waor: \'$1\' (aangemaak door [[Special:Contributions/$2|$2]])',
+'exbeforeblank' => 'inhawd veur \'t wisse waor: \'$1\'',
+'exblank' => 'pazjena waor laeg',
+'confirmdelete' => 'Bevèstig wisse',
+'deletesub' => '(Wisse "$1")',
+'confirmdeletetext' => 'De sjteis op \'t punt \'n pazjena of e plaetje veur ummer te wisse. Dit haolt allen inhawd en historie oet de database eweg. Bevèstig hieónger dat dit welzeker dien bedoeling is, dats te de gevolge begrieps.',
+'actioncomplete' => 'Actie voltoeid',
+'deletedtext' => '"$1" is gewis. Zuug $2 vuur \'n euverzich van recèntelik gewisde pazjena\'s.',
+'deletedarticle' => '"$1" is gewis',
+'dellogpage' => 'Wislogbook',
+'dellogpagetext' => 'Hie volg \'n lies van de meis recèntelik gewisde pazjena\'s en plaetjes.',
+'deletionlog' => 'Wislogbook',
+'reverted' => 'Iedere versie hersjtèld',
+'deletecomment' => 'Rae veur wisactie',
+'imagereverted' => 'De omzetting naar de oudere versie is geslaagd.',
+'rollback' => 'Wijzigingen ongedaan maken',
+'rollbacklink' => 'Trukdrieje',
+'cantrollback' => 'Trökdrejje van verangeringe neet meugelik: Dit artikel haet mer einen auteur.',
+'alreadyrolled' => '\'t Is neet meugelik óm de lèste verangering van [[:$1]]
+door [[User:$2|$2]] ([[User talk:$2|euverlik]]) óngedaon te make. Emes angers haet de pazjena al hersjtèld of haet \'n anger bewèrking gedaon.
+
+De lèste bewèrking is gedaon door [[User:$3|$3]] ([[User talk:$3|euverlik]]).',
+'editcomment' => '\'t Bewirkingscommentair waor: "<i>$1</i>".',
+'revertpage' => 'Wieziginge door [[Special:Contributions/$2|$2]] ([[User_talk:$2|Euverlik]]) trukgedriejd tot de lètste versie door [[User:$1|$1]]',
+'protectlogpage' => 'Logbook besjermde pazjena\'s',
+'protectedarticle' => '$1 besjermd',
+'unprotectedarticle' => 'besjerming van $1 opgeheve',
+'protectsub' => '(Besjerme van "$1")',
+'confirmprotecttext' => 'Wits te zeker dats te dees pazjena wils besjèrme?',
+'confirmprotect' => 'Bevèstig besjerme',
+'protectmoveonly' => 'Besjerm allein taenge verplaatse',
+'protectcomment' => 'Rede veur besjerming',
+'unprotectsub' => '(Besjerming van "$1" opheve)',
+'confirmunprotecttext' => 'Wits e zeker das de besjèrming van dees pazjena wils opheffe?',
+'confirmunprotect' => 'Bevèstig vriegaeve van pazjena',
+'unprotectcomment' => 'Rede veur opheffe van besjerming',
+'undelete' => 'Verwiederde pazjena trukplaatse',
+'undeletepage' => 'Verwiederde pazjena\'s bekieke en trukplaatse',
+'undeletepagetext' => 'De ongersjtaande pazjena\'s zint verwiederd, meh bevinge zich nog sjteeds in \'t archief, en kinne weure truukgeplaatsj.',
+'undeletearticle' => 'Verwijderde pagina terugplaatsen',
+'undeleterevisions' => '$1 versies in \'t archief',
+'undeletehistory' => 'Als u een pagina terugplaatst, worden alle versies als oude versies teruggeplaatst. Als er al een nieuwe pagina met dezelfde naam is aangemaakt, zullen deze versies als oude versies worden teruggeplaatst, maar de huidige versie neet gewijzigd worden.',
+'undeleterevision' => 'Verwiederde versie van $1',
+'undeletebtn' => 'Trökzètte!',
+'undeletedarticle' => '"$1" is truukgeplaatsj.',
+'undeletedrevisions' => '$1 versies truukgeplaatsj',
+'namespace' => 'Naamruumde:',
+'invert' => 'Ómgedriejde selectie',
+'contributions' => 'Biedrages per gebroeker',
+'mycontris' => 'Mien biedraag',
+'contribsub' => 'Veur $1',
+'nocontribs' => 'Gein wijzigingen gevonden die aan de gestelde criteria voldoen.',
+'ucnote' => 'Hieonger sjtont de litste <b>$1</b> verangeringe van deze gebroeker in de litste <b>$2</b> daag.',
+'uclinks' => 'Bekiek de litste <b>$1</b> verangeringe; bekiek de litste <b>$2</b> daag.',
+'uctop' => ' (litste verangering)',
+'whatlinkshere' => 'Links nao dees pazjena',
+'notargettitle' => 'Gein doelpagina',
+'notargettext' => 'Ger hubt neet gezag veur welleke pagina ger deze functie wilt bekieke.',
+'linklistsub' => '(lies van verwiezinge)',
+'linkshere' => 'De volgende pazjena\'s verwieze hieheen:',
+'nolinkshere' => 'D\'r zint gein pazjena\'s mit links hiehaer.',
+'isredirect' => 'redirect pazjena',
+'blockip' => 'Blokkeer dit IP-adres',
+'blockiptext' => 'Gebroek \'t óngerstjaondj formeleer óm sjrieftoegank van e zeker IP-adres te verbeje. Dit maag allein gedaon weure om vandalisme te veurkómme.',
+'ipaddress' => 'IP-adres',
+'ipbreason' => 'Reden',
+'ipbsubmit' => 'Blokkeer dit IP-adres',
+'ipboptions' => '2 hours,1 day,3 days,1 week,2 weeks,1 month,3 months,6 months,1 year,infinite',
+'badipaddress' => '\'t IP-adres haet \'n ongeldige opmaak.',
+'blockipsuccesssub' => 'Blokkaad gelök',
+'blockipsuccesstext' => '\'t IP-adres "$1" is geblokkeerd.<br />
+Zuug de [[Special:Ipblocklist|lies van geblokkeerde IP-adresse]].',
+'unblockip' => 'Deblokkeer IP adres',
+'unblockiptext' => 'Gebroek het ongersjtaonde formeleer om weer sjrieftoegang te gaeve aan e geblokkierd IP adres.',
+'ipusubmit' => 'Deblokkeer dit IP-adres.',
+'ipblocklist' => 'Lies van geblokkeerde IP-adressen',
+'blocklistline' => 'Op $1 blokkeerde $2 $3 ($4)',
+'ipblocklistempty' => 'De blokkeerlies ies laeg.',
+'blocklink' => 'Blokkeer',
+'unblocklink' => 'deblokkeer',
+'contribslink' => 'biedrages',
+'autoblocker' => 'Ómdets te \'n IP-adres deils mit "$1" (geblokkeerd mit raeje "$2") bis te automatisch geblokkeerd.',
+'blocklogpage' => 'Blokkeerlogbook',
+'blocklogentry' => '"$1" is geblokkeerd veur d\'n tied van $2',
+'blocklogtext' => 'Dit is \'n log van blokkades van gebroekers. Automatisch geblokkeerde IP-adresse sjtoon hie neet bie. Zuug de [[Special:Ipblocklist|Lies van geblokkeerde IP-adresse]] veur de lies van op dit mement wèrkende blokkades.',
+'proxyblockreason' => 'Dien IP-adres is geblokkeerd ómdat \'t \'n aope proxy is. Contacteer estebleef diene internet service provider of technische óngersjteuning en informeer ze euver dit serjeus veiligheidsprebleem.',
+'proxyblocksuccess' => 'Klaor.',
+'lockdb' => 'Blokkeer de database',
+'unlockdb' => 'Deblokkeer de database',
+'lockdbtext' => 'Waarsjoewing: De database blokkere haet \'t gevolg dat nemes nog pazjena\'s kint bewirke, veurkäöre kint verangere of get angers kint doon woeveur d\'r verangeringe in de database nudig zint.',
+'unlockdbtext' => 'Het de-blokkeren van de database zal de gebroekers de mogelijkheid geven om wijzigingen aan pagina\'s op te slaan, hun voorkeuren te wijzigen en alle andere bewerkingen waarvoor er wijzigingen in de database nodig zijn. Is dit inderdaad wat u wilt doen?.',
+'lockconfirm' => 'Jao, ich wil de database blokkere.',
+'unlockconfirm' => 'Ja, ik wil de database de-blokkeren.',
+'lockbtn' => 'Blokkeer de database',
+'unlockbtn' => 'Deblokkeer de database',
+'locknoconfirm' => 'De höbs \'t vekske neet aangevink om dien keuze te bevèstige.',
+'lockdbsuccesssub' => 'Blokkering database succesvol',
+'unlockdbsuccesssub' => 'Blokkering van de database opgeheven',
+'lockdbsuccesstext' => 'De database van {{SITENAME}} is geblokkeerd. Vergaet neet de database opnuuj te deblokkere wens te klaor bis mit \'t óngerhaud.',
+'unlockdbsuccesstext' => 'Blokkering van de database van {{SITENAME}} is opgeheven.',
+'already_sysop' => 'Deze gebroeker is al systeemwèrker',
+'already_bureaucrat' => 'Deze gebroeker is al amtenaer',
+'movepage' => 'Verplaats pazjena',
+'movepagetext' => 'Mit \'t óngersjtaond formuleer kans te \'n pazjena verplaatse. De historie van de ouw pazjena zal nao de nuuj mitgaon. De ouwe titel zal automatisch \'ne redirect nao de nuuj pazjena waere. Doe kans \'n pazjena allein verplaatse, es gein pazjena besjteit mit de nuje naam, of es op die pazjena allein \'ne redirect zónger historie sjteit.',
+'movepagetalktext' => 'De biebehurende euverlikpazjena weurt ouch verplaats, mer \'\'\'neet\'\'\' in de volgende gevalle:
+* es de pazjena nao \'n anger [[Project:Naamruumde|naamruumde]] verplaats weurt
+* es al \'n euverlikpazjena besjteit ónger de angere naam
+* es doe \'t óngersjtaond vekske neet aanvinks',
+'movearticle' => 'Verplaats pazjena',
+'movenologin' => 'Neet aangemèld',
+'movenologintext' => 'Veur \'t verplaatsje van \'n pazjena mos e zien [[Special:Userlogin|aangemèld]].',
+'newtitle' => 'Nao de nuje titel',
+'movepagebtn' => 'Verplaats pazjena',
+'pagemovedsub' => 'De verplaatsing is gelök',
+'pagemovedtext' => 'Pazjena "[[$1]]" verplaats nao "[[$2]]".',
+'articleexists' => 'Dao is al \'n pazjena mit dees titel of de titel is óngeljig. <br />Kees estebleef \'n anger titel.',
+'talkexists' => 'De pazjena zelf is verplaats, meh de euverlikpazjena kós neet verplaats waere, ómdat d\'r al \'n euverlikpazjena mit de nuje titel besjtóng. Combineer de euverlikpazjena\'s estebleef mit de hand.',
+'movedto' => 'verplaats nao',
+'movetalk' => 'Verplaats de euverlikpazjena ouch.',
+'talkpagemoved' => 'De biebehurende euverlikpazjena is ouch verplaats.',
+'talkpagenotmoved' => 'De biebehurende euverlikpazjena is <strong>neet</strong> verplaats.',
+'1movedto2' => '[[$1]] verplaats nao [[$2]]',
+'1movedto2_redir' => '[[$1]] euver redirect verplaats nao [[$2]]',
+'movelogpage' => 'Logbook verplaatsde pazjena\'s',
+'movelogpagetext' => 'Dit is de lies van verplaatsde pazjena\'s.',
+'movereason' => 'Lèk oet woeróm',
+'revertmove' => 'trökdrieje',
+'delete_and_move' => 'Wis en verplaats',
+'delete_and_move_text' => '==Wisse vereis==
+
+De doeltitel "[[$1]]" besjteit al. Wils te dit artikel wisse óm ruumde te make veur de verplaatsing?',
+'delete_and_move_reason'=> 'Gewis óm artikel te kónne verplaatse',
+'export' => 'Exporteer pazjena\'s',
+'allmessages' => 'Alle systeemberichte',
+'allmessagesname' => 'Naam',
+'allmessagesdefault' => 'Obligaten teks',
+'allmessagescurrent' => 'Hujige teks',
+'allmessagestext' => 'Dit is \'n lies van alle systeemberichte besjikbaar in de MediaWiki:-naamruumde.',
+'allmessagesnotsupportedUI'=> 'Dien huidige interface taol <b>$1</b> weurt bie dees site neet ongerstjeund doer special:Allmessages.',
+'allmessagesnotsupportedDB'=> 'special:Allmessages neet óngersjteundj ómdat wgUseDatabaseMessages oet (off) sjteit.',
+'thumbnail-more' => 'Vergroete',
+'missingimage' => '<b>Plaetsje neet besjikbaar</b><br /><i>$1</i>',
+'filemissing' => 'Besjtand ontbrik',
+'tooltip-search' => 'Doerzeuk dizze wiki [alt-f]',
+'tooltip-minoredit' => 'Markeer dit as \'n kleine verangering [alt-i]',
+'tooltip-save' => 'Bewaar dien verangeringe [alt-s]',
+'tooltip-preview' => 'Bekiek dien verangeringe veurdets te ze definitief opsjleis! [alt-p]',
+'tooltip-diff' => 'Bekiek dien verangeringe in de teks. [alt-v]',
+'tooltip-compareselectedversions'=> 'Bekiek de versjille tusje de twie geselectierde versies van dees pazjena. [alt-v]',
+'tooltip-watch' => 'Voog dees pazjena toe aan dien volglies [alt-w]',
+'anonymous' => 'Anoniem(e) gebroeker(s) van {{SITENAME}}',
+'siteuser' => '{{SITENAME}} gebroeker $1',
+'lastmodifiedatby' => 'Dees pazjena is \'t litst verangert op $2, $1 doer $3.',
+'and' => 'en',
+'siteusers' => '{{SITENAME}} gebroekers(s) $1',
+'creditspage' => 'Sjrievers van dees pazjena',
+'subcategorycount' => 'Dees categorie haet {{PLURAL:$1|ein subcategorie|$1 subcategorieë}}.',
+'categoryarticlecount' => 'Dao zeen $1 artikele in dees categorie.',
+'mw_math_png' => 'Ummer PNG rendere',
+'mw_math_simple' => 'HTML in erg simpele gevalle en angesj PNG',
+'mw_math_html' => 'HTML woe meugelik en angesj PNG',
+'mw_math_source' => 'Laot de TeX code sjtaon (vuur tèksbrowsers)',
+'mw_math_modern' => 'Aangeroaje vuur nuui browsers',
+'mw_math_mathml' => 'MathML woe meugelik (experimenteil)',
+'monobook.js' => '/* tooltips en access keys, pas op mit \'t \'-teike */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Mien gebroekerspazjena\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'De gebroekerspazjena veur dit IP adres\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Mien euverlikpazjena\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Euverlik euver verangeringe doer dit IP addres\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Mien veurkäöre\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'De liest van gevolgde pazjenas.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Liest van mien biedraag\');
+ ta[\'pt-login\'] = new Array(\'o\',\'De weurs aangemodigd om in te logge, meh t is neet verplich.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'De weurs aangemodigd om in te logge, meh t is neet verplich.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Aafmèlde\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Euverlik euver dit artikel\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'De kins dees pazjena verangere.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Opmèrking toevoge aan dees discussie.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Dees pazjena is besjermd. De kins häör brontèks bekieke.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Auw versies van dees pazjena.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Besjerm dees pazjena\');
+ ta[\'ca-delete\'] = new Array(\'\',\'Verwieder dees pazjena\');
+ ta[\'ca-undelete\'] = new Array(\'\',\'Hersjtèl de verangeringe van dees pazjena van veurdat ze gewist woerd\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Verplaats dees pazjena\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'De höbs gein permissie veur \'t verplaatse van dees pazjena\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Dees pazjena toeveuge aan volgliest\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Dees pazjena van volgliest aafhaole\');
+ ta[\'search\'] = new Array(\'f\',\'Doerzeuk dizze wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Huidpazjena\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Bezeuk de huidpazjena\');
+ ta[\'n-portal\'] = new Array(\'\',\'Euver t projèk, was e kins doon, woe se dinger kins vinge\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Achtergrondinfo van t nuuis\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'De lies van recènte verangeringe in de wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Laadt n willekäörige pazjena\');
+ ta[\'n-help\'] = new Array(\'\',\'De plek om informatie euver dit projèk te vinge.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Sjteun os\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Liest van alle wiki pazjenas die hieheen linke\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Recènte verangeringe in pazjenas woeheen gelinkt weurd\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed veur dees pazjena\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed veur dees pazjena\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Bekiek de liest van contributies van dizze gebroeker\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Sjtuur inne mail noa dizze gebroeker\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Upload plaetsjes of media besjtande\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Liest van alle speciale pazjenas\');
+
+/* tot hie is \'t ok */
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Bekiek de pazjena\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Bekiek de gebroekerspazjena\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Bekiek de mediapazjena\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Dit is n speciaal pazjena, de kins dees pazjena neet zelf editte.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Bekiek de projèkpazjena\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Bekiek de plaetsjespazjena\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Bekiek t systeimberich\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Bekiek t sjabloon\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Bekiek de helppazjena\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Bekiek de kattegoriepazjena\');',
+'deletedrevision' => 'Aw versie $1 gewis.',
+'previousdiff' => '← Gank nao de vurrige diff',
+'nextdiff' => 'Gank nao de volgende diff →',
+'imagemaxsize' => 'Bepèrk plaetsjes op de besjrievingspazjena\'s van aafbeildinge tot:',
+'thumbsize' => 'Thumbnail size :',
+'showbigimage' => 'Download versie mit hoeg resolutie ($1x$2, $3 kB)',
+'newimages' => 'Nuuj plaetjes',
+'noimages' => 'Niks te zeen.',
+'specialloguserlabel' => 'Gebroeker:',
+'speciallogtitlelabel' => 'Titel:',
+'mediawarning' => '\'\'\'Warning\'\'\': This file may contain malicious code, by executing it your system may be compromised.<hr />',
+'exif-bitspersample' => 'Bits per componènt',
+'exif-compression' => 'Cómpressiesjema',
+'exif-datetime' => 'Datum en momènt besjtandjsverangering',
+'exif-artist' => 'Auteur',
+'exif-copyright' => 'Copyrighthawter',
+'exif-colorspace' => 'Kläörruumde',
+'exif-componentsconfiguration'=> 'Beteikenis van edere componènt',
+'exif-compressedbitsperpixel'=> 'Cómpressiemeneer bie dit plaetje',
+'exif-pixelxdimension' => 'Valind image height',
+'exif-datetimeoriginal' => 'Datum en momint van verwèkking',
+'exif-datetimedigitized'=> 'Datum en momènt van digitizing',
+'exif-aperturevalue' => 'Eupening',
+'exif-brightnessvalue' => 'Heljerheid',
+'exif-cfapattern' => 'CFA-patroen',
+'exif-contrast' => 'Contras',
+'exif-devicesettingdescription'=> 'Besjrieving methode-opties',
+'exif-compression-1' => 'Óngecómprimeerd',
+'exif-componentsconfiguration-0'=> 'besjteit neet',
+'exif-customrendered-0' => 'Normaal perces',
+'exif-contrast-0' => 'Normaal',
+'exif-contrast-1' => 'Weik',
+'exif-contrast-2' => 'Hel',
+'edit-externally' => 'Bewirk dit bestand mit \'n extern toepassing',
+'edit-externally-help' => 'Zuug de [http://meta.wikimedia.org/wiki/Help:External_editors setupinsjtructies] veur mier informatie.',
+'confirmemail' => 'Bevèstig e-mailadres',
+'confirmemail_text' => 'Deze wiki vereis dats te dien e-mailadres instèls iedats te e-mailfuncties
+gebroeks. Klik op de knop hieónger óm e bevèstegingsberich nao dien adres te
+sjikke. D\'n e-mail zal \'ne link mèt \'n code bevatte; eupen de link in diene
+browser óm te bevestege dat dien e-mailadres werk.',
+'confirmemail_send' => 'Sjik \'n bevèstegingcode',
+'confirmemail_sent' => 'Bevèstegingsberich versjik.',
+'confirmemail_sendfailed'=> 'Kós \'t bevèstegingsberich neet versjikke. Zuug dien e-mailadres nao op óngeljige karakters.',
+'confirmemail_invalid' => 'Óngeljige bevèstigingscode. De code is meugelik verloupe.',
+'confirmemail_success' => 'Dien e-mailadres is bevesteg. De kins noe inlogke en van de wiki genete.',
+'confirmemail_loggedin' => 'Dien e-mailadres is noe vasgelag.',
+'confirmemail_error' => 'Bie \'t opsjlaon van eur bevèstiging is get fout gegange.',
+'confirmemail_subject' => 'Bevèstiging e-mailadres veur {{SITENAME}}',
+'confirmemail_body' => 'Emes, waorsjienlik doe vanaaf \'t IP-adres $1, heet \'n account $2
+aangemaak mit dit e-mailadres op {{SITENAME}}.
+
+Eupen óm te bevèstige dat dit account wirkelik van dich is en de
+e-mailgegaeves op {{SITENAME}} te activere deze link in diene browser:
+
+$3
+
+Es geer dit *neet* zeet, dan volg de link neet. Dees bevèstigingscode
+blief geljig tot $4',
+'createarticle' => 'Maak artikel aan',
+'scarytranscludefailed' => '[Sjabloon $1 kós neet opgehaold waere; sorry]',
+'deletedwhileediting' => 'Waorsjoewing: dees pazjena is gewis naodats doe bis begós mit bewirke.',
+'confirmrecreate' => 'Gebroeker [[User:$1|$1]] ([[User talk:$1|euverlèk]]) heet dit artikel gewis naodats doe mèt bewirke begós mèt de rae:
+: \'\'$2\'\'
+Bevèsteg estebleef dats te dees pazjena ech obbenuujts wils make.',
+'recreate' => 'Pazjena obbenuujts make',
+'confirm_purge' => 'Wils te de buffer vaan dees paas wisse?
+
+$1',
+);
+?>
diff --git a/languages/messages/MessagesLn.php b/languages/messages/MessagesLn.php
new file mode 100644
index 000000000000..a6739387579e
--- /dev/null
+++ b/languages/messages/MessagesLn.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * Lingala language
+ *
+ * @package MediaWiki
+ * @subpackage language
+ */
+
+$linkPrefixExtension = true;
+
+# Same as the French (bug 8485)
+$separatorTransformTable = array( ',' => "\xc2\xa0", '.' => ',' );
+
+$messages = array( 'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD' );
+
+?> \ No newline at end of file
diff --git a/languages/messages/MessagesLo.php b/languages/messages/MessagesLo.php
new file mode 100644
index 000000000000..b2663f1742f0
--- /dev/null
+++ b/languages/messages/MessagesLo.php
@@ -0,0 +1,22 @@
+<?php
+/** Lao (ພາສາລາວ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+$digitTransformTable = array(
+ '0' => '໐',
+ '1' => '໑',
+ '2' => '໒',
+ '3' => '໓',
+ '4' => '໔',
+ '5' => '໕',
+ '6' => '໖',
+ '7' => '໗',
+ '8' => '໘',
+ '9' => '໙'
+);
+
+?>
diff --git a/languages/messages/MessagesLt.php b/languages/messages/MessagesLt.php
new file mode 100644
index 000000000000..e75c500f672d
--- /dev/null
+++ b/languages/messages/MessagesLt.php
@@ -0,0 +1,2077 @@
+<?php
+/** Lithuanian (Lietuvių)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Medija',
+ NS_SPECIAL => 'Specialus',
+ NS_MAIN => '',
+ NS_TALK => 'Aptarimas',
+ NS_USER => 'Naudotojas',
+ NS_USER_TALK => 'Naudotojo_aptarimas',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_aptarimas',
+ NS_IMAGE => 'Vaizdas',
+ NS_IMAGE_TALK => 'Vaizdo_aptarimas',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_aptarimas',
+ NS_TEMPLATE => 'Šablonas',
+ NS_TEMPLATE_TALK => 'Šablono_aptarimas',
+ NS_HELP => 'Pagalba',
+ NS_HELP_TALK => 'Pagalbos_aptarimas',
+ NS_CATEGORY => 'Kategorija',
+ NS_CATEGORY_TALK => 'Kategorijos_aptarimas',
+);
+
+$quickbarSettings = array(
+ 'Nerodyti', 'Fiksuoti kairėje', 'Fiksuoti dešinėje', 'Plaukiojantis kairėje'
+);
+
+$skinNames = array(
+ 'standard' => 'Standartinė',
+ 'nostalgia' => 'Nostalgija',
+ 'cologneblue' => 'Kiolno Mėlyna',
+ 'davinci' => 'Da Vinči',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'MySkin',
+ 'chick' => 'Chick'
+);
+$fallback8bitEncoding = 'windows-1257';
+$separatorTransformTable = array(',' => ' ', '.' => ',' );
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'F j, Y',
+ 'mdy both' => 'H:i, F j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'Y F j',
+ 'dmy both' => 'H:i, Y F j',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y F j',
+ 'ymd both' => 'Y F j, H:i',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'Pabraukti nuorodas:',
+'tog-highlightbroken' => 'Formuoti nesančių puslapių nuorodas <a href="#" class="new">šitaip</a> (priešingai - šitaip <a href="#" class="internal">?</a>).',
+'tog-justify' => 'Lygiuoti pastraipas pagal abi puses',
+'tog-hideminor' => 'Slėpti smulkius pakeitimus naujausių keitimų sąraše',
+'tog-extendwatchlist' => 'Išplėsti stebimų sąrašą, kad rodytų visus tinkamus keitimus',
+'tog-usenewrc' => 'Pažangiai rodomi naujausi keitimai (JavaScript)',
+'tog-numberheadings' => 'Automatiškai numeruoti skyrelius',
+'tog-showtoolbar' => 'Rodyti redagavimo įrankinę (JavaScript)',
+'tog-editondblclick' => 'Puslapių redagavimas dvigubu spustelėjimu (JavaScript)',
+'tog-editsection' => 'Įjungti skyrelių redagavimą naudojant nuorodas [taisyti]',
+'tog-editsectiononrightclick' => 'Įjungti skyrelių redagavimą paspaudus skyrelio pavadinimą<br />dešiniuoju pelės klavišu (JavaScript)',
+'tog-showtoc' => 'Rodyti turinį, jei puslapyje daugiau nei 3 skyreliai',
+'tog-rememberpassword' => 'Prisiminti prisijungimo informaciją šiame kompiuteryje',
+'tog-editwidth' => 'Pilno pločio redagavimo laukas',
+'tog-watchcreations' => 'Pridėti puslapius, kuriuos sukūriau, į stebimų sąrašą',
+'tog-watchdefault' => 'Pridėti puslapius, kuriuos redaguoju, į stebimų sąrašą',
+'tog-watchdeletion' => 'Pridėti puslapius, kuriuos ištrinu, į stebimų sąrašą',
+'tog-minordefault' => 'Pagal nutylėjimą pažymėti redagavimus kaip smulkius',
+'tog-previewontop' => 'Rodyti peržiūrą virš redagavimo lauko',
+'tog-previewonfirst' => 'Rodyti straipsnio peržiūrą pirmu redagavimu',
+'tog-nocache' => 'Nenaudoti puslapių kaupimo (caching)',
+'tog-enotifwatchlistpages' => 'Siųsti man laišką, kai pakeičiamas puslapis, kurį stebiu',
+'tog-enotifusertalkpages' => 'Siųsti man laišką, kai pakeičiamas mano naudotojo aptarimo puslapis',
+'tog-enotifminoredits' => 'Siųsti man laišką, kai puslapio keitimas yra smulkus',
+'tog-enotifrevealaddr' => 'Rodyti mano el. pašto adresą priminimo laiškuose',
+'tog-shownumberswatching' => 'Rodyti stebinčių naudotojų skaičių',
+'tog-fancysig' => 'Parašas be automatinių nuorodų',
+'tog-externaleditor' => 'Pagal nutylėjimą naudoti išorinį redaktorių',
+'tog-externaldiff' => 'Pagal nutylėjimą naudoti išorinę skirtumų rodymo programą',
+'tog-showjumplinks' => 'Įjungti "peršokti į" pasiekiamumo nuorodas',
+'tog-uselivepreview' => 'Naudoti tiesioginę peržiūrą (JavaScript) (Eksperimentinis)',
+'tog-forceeditsummary' => 'Klausti, kai palieku tuščią keitimo komentarą',
+'tog-watchlisthideown' => 'Slėpti mano keitimus stebimų sąraše',
+'tog-watchlisthidebots' => 'Slėpti robotų keitimus stebimų sąraše',
+'tog-watchlisthideminor' => 'Slėpti smulkius keitimus stebimų sąraše',
+'tog-nolangconversion' => 'Išjungti variantų keitimą',
+'tog-ccmeonemails' => 'Siųsti man laiškų kopijas, kuriuos siunčiu kitiems naudotojams',
+
+'underline-always' => 'Visada',
+'underline-never' => 'Niekada',
+'underline-default' => 'Pagal naršyklės nustatymus',
+
+'skinpreview' => '(Peržiūra)',
+
+# Dates
+'sunday' => 'sekmadienis',
+'monday' => 'pirmadienis',
+'tuesday' => 'antradienis',
+'wednesday' => 'trečiadienis',
+'thursday' => 'ketvirtadienis',
+'friday' => 'penktadienis',
+'saturday' => 'šeštadienis',
+'sun' => 'Sek',
+'mon' => 'Pir',
+'tue' => 'Ant',
+'wed' => 'Tre',
+'thu' => 'Ket',
+'fri' => 'Pen',
+'sat' => 'Šeš',
+'january' => 'sausio',
+'february' => 'vasario',
+'march' => 'kovo',
+'april' => 'balandžio',
+'may_long' => 'gegužės',
+'june' => 'birželio',
+'july' => 'liepos',
+'august' => 'rugpjūčio',
+'september' => 'rugsėjo',
+'october' => 'spalio',
+'november' => 'lapkričio',
+'december' => 'gruodžio',
+'january-gen' => 'Sausis',
+'february-gen' => 'Vasaris',
+'march-gen' => 'Kovas',
+'april-gen' => 'Balandis',
+'may-gen' => 'Gegužė',
+'june-gen' => 'Birželis',
+'july-gen' => 'Liepa',
+'august-gen' => 'Rugpjūtis',
+'september-gen' => 'Rugsėjis',
+'october-gen' => 'Spalis',
+'november-gen' => 'Lapkritis',
+'december-gen' => 'Gruodis',
+'jan' => 'sau',
+'feb' => 'vas',
+'mar' => 'kov',
+'apr' => 'bal',
+'may' => 'geg',
+'jun' => 'bir',
+'jul' => 'lie',
+'aug' => 'rgp',
+'sep' => 'rgs',
+'oct' => 'spa',
+'nov' => 'lap',
+'dec' => 'grd',
+
+# Bits of text used by many pages
+'categories' => 'Kategorijos',
+'pagecategories' => '{{PLURAL:$1|Kategorija|Kategorijos}}',
+'category_header' => 'Kategorijos "$1" straipsniai',
+'subcategories' => 'Subkategorijos',
+'category-media-header' => 'Media kategorijoje "$1"',
+
+'mainpage' => 'Pradžia',
+'mainpagetext' => "<big>'''MediaWiki sėkmingai įdiegta.'''</big>",
+'mainpagedocfooter' => 'Informacijos apie wiki programinės įrangos naudojimą, ieškokite [http://meta.wikimedia.org/wiki/Help:Contents žinyne].
+
+== Pradžiai ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Konfigūracijos nustatymų sąrašas]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki DUK]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki pranešimai paštu apie naujas versijas]',
+
+'portal' => 'Bendruomenė',
+'portal-url' => '{{ns:project}}:Bendruomenė',
+'about' => 'Apie',
+'aboutsite' => 'Apie {{SITENAME}}',
+'aboutpage' => '{{ns:project}}:Apie',
+'article' => 'Turinys',
+'help' => 'Pagalba',
+'helppage' => '{{ns:help}}:Turinys',
+'bugreports' => 'Pranešti apie klaidą',
+'bugreportspage' => '{{ns:project}}:Klaidų pranešimai',
+'sitesupport' => 'Parama',
+'sitesupport-url' => '{{ns:project}}:Svetainės palaikymas',
+'faq' => 'DUK',
+'faqpage' => '{{ns:project}}:DUK',
+'edithelp' => 'Kaip redaguoti',
+'newwindow' => '(atsidaro naujame lange)',
+'edithelppage' => '{{ns:help}}:Redagavimas',
+'cancel' => 'Atšaukti',
+'qbfind' => 'Paieška',
+'qbbrowse' => 'Naršymas',
+'qbedit' => 'Redagavimas',
+'qbpageoptions' => 'Šis puslapis',
+'qbpageinfo' => 'Kontekstas',
+'qbmyoptions' => 'Mano puslapiai',
+'qbspecialpages' => 'Specialieji puslapiai',
+'moredotdotdot' => 'Daugiau...',
+'mypage' => 'Mano puslapis',
+'mytalk' => 'Mano aptarimas',
+'anontalk' => 'Šio IP aptarimas',
+'navigation' => 'Navigacija',
+
+# Metadata in edit box
+'metadata_help' => 'Metaduomenys (žiūrėkite [[{{ns:project}}:Metaduomenys]] paaiškinimui):',
+
+'currentevents' => 'Naujienos',
+'currentevents-url' => 'Naujienos',
+
+'disclaimers' => 'Jokių Garantijų',
+'disclaimerpage' => '{{ns:project}}:Jokių garantijų',
+'privacy' => 'Privatumo politika',
+'privacypage' => '{{ns:project}}:Privatumo politika',
+'errorpagetitle' => 'Klaida',
+'returnto' => 'Grįžti į $1.',
+'tagline' => 'Straipsnis iš {{SITENAME}}.',
+'search' => 'Paieška',
+'searchbutton' => 'Paieška',
+'go' => 'Rodyti',
+'searcharticle' => 'Rodyti',
+'history' => 'Puslapio istorija',
+'history_short' => 'Istorija',
+'updatedmarker' => 'atnaujinta nuo paskutinio mano apsilankymo',
+'info_short' => 'Informacija',
+'printableversion' => 'Versija spausdinimui',
+'permalink' => 'Nuolatinė nuoroda',
+'print' => 'Spausdinti',
+'edit' => 'Redaguoti',
+'editthispage' => 'Redaguoti šį puslapį',
+'delete' => 'Trinti',
+'deletethispage' => 'Ištrinti šį puslapį',
+'undelete_short' => 'Atstatyti $1 {{plural:$1:redagavimą|redagavimus|redagavimų}}',
+'protect' => 'Užrakinti',
+'protectthispage' => 'Rakinti šį puslapį',
+'unprotect' => 'Atrakinti',
+'unprotectthispage' => 'Atrakinti šį puslapį',
+'newpage' => 'Naujas puslapis',
+'talkpage' => 'Aptarti šį puslapį',
+'specialpage' => 'Specialusis puslapis',
+'personaltools' => 'Asmeniniai įrankiai',
+'postcomment' => 'Rašyti komentarą',
+'articlepage' => 'Rodyti turinio puslapį',
+'talk' => 'Aptarimas',
+'views' => 'Žiūrėti',
+'toolbox' => 'Įrankiai',
+'userpage' => 'Rodyti naudotojo puslapį',
+'projectpage' => 'Rodyti projekto puslapį',
+'imagepage' => 'Žiūrėti paveikslėlio puslapį',
+'mediawikipage' => 'Rodyti pranešimo puslapį',
+'templatepage' => 'Rodyti šablono puslapį',
+'viewhelppage' => 'Rodyti pagalbos puslapį',
+'categorypage' => 'Rodyti kategorijos puslapį',
+'viewtalkpage' => 'Rodyti aptarimo puslapį',
+'otherlanguages' => 'Kitomis kalbomis',
+'redirectedfrom' => '(Nukreipta iš $1)',
+'redirectpagesub' => 'Nukreipimo puslapis',
+'lastmodifiedat' => 'Šis puslapis paskutinį kartą keistas $1 $2.', # $1 date, $2 time
+'viewcount' => 'Šis puslapis buvo atvertas $1 {{plural:$1|kartą|kartus|kartų}}.',
+'copyright' => 'Turinys pateikiamas su $1 licencija.',
+'protectedpage' => 'Užrakintas puslapis',
+'jumpto' => 'Peršokti į:',
+'jumptonavigation' => 'navigaciją',
+'jumptosearch' => 'paiešką',
+
+'badaccess' => 'Teisių klaida',
+'badaccess-group0' => 'Jums neleidžiama įvykdyti veiksmo, kurio prašėte.',
+'badaccess-group1' => 'Veiksmas, kurio prašėte, galimas tik $1 grupės naudotojams.',
+'badaccess-group2' => 'Veiksmas, kurio prašėte, galimas tik naudotojams, esantiems vienoje iš šių grupių $1.',
+'badaccess-groups' => 'Veiksmas, kurio prašėte, galimas tik naudotojams, esantiems vienoje iš šių grupių $1.',
+
+'versionrequired' => 'Reikalinga $1 MediaWiki versija',
+'versionrequiredtext' => 'Reikalinga $1 MediaWiki versija, kad pamatytumėte šį puslapį. Žiūrėkite [[{{ns:special}}:Version]]',
+
+'ok' => 'Gerai',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Gauta iš "$1"',
+'youhavenewmessages' => 'Jūs turite $1 ($2).',
+'newmessageslink' => 'naujų žinučių',
+'newmessagesdifflink' => 'paskutinis pakeitimas',
+'editsection' => 'taisyti',
+'editold' => 'taisyti',
+'editsectionhint' => 'Redaguoti skyrelį: $1',
+'toc' => 'Turinys',
+'showtoc' => 'rodyti',
+'hidetoc' => 'slėpti',
+'thisisdeleted' => 'Žiūrėti ar atkurti $1?',
+'viewdeleted' => 'Rodyti $1?',
+'restorelink' => '$1 {{plural:$1|ištrintą keitimą|ištrintus keitimus|ištrintų keitimų}}',
+'feedlinks' => 'Kanalas:',
+'feed-invalid' => 'Neleistinas kanalo tipas.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Straipsnis',
+'nstab-user' => 'Naudotojo puslapis',
+'nstab-media' => 'Media puslapis',
+'nstab-special' => 'Specialus',
+'nstab-project' => 'Projekto puslapis',
+'nstab-image' => 'Failas',
+'nstab-mediawiki' => 'Pranešimas',
+'nstab-template' => 'Šablonas',
+'nstab-help' => 'Pagalbos puslapis',
+'nstab-category' => 'Kategorija',
+
+# Main script and global functions
+'nosuchaction' => 'Nėra tokio veiksmo',
+'nosuchactiontext' => 'Veiksmas, nurodytas adrese, neatpažintas',
+'nosuchspecialpage' => 'Nėra tokio specialiojo puslapio',
+'nospecialpagetext' => 'Jūs prašėte neleistino specialiojo puslapio, leistinų specialiųjų puslapių sąrašas rasite [[{{ns:special}}:Specialpages]].',
+
+# General errors
+'error' => 'Klaida',
+'databaseerror' => 'Duomenų bazės klaida',
+'dberrortext' => 'Įvyko duomenų bazės užklausos sintaksės klaida.
+Tai gali reikšti klaidą programinėje įrangoje.
+Paskutinė mėginta duomenų bazės užklausa buvo:
+<blockquote><tt>$1</tt></blockquote>
+iš funkcijos: "<tt>$2</tt>".
+MySQL grąžino klaidą "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Įvyko duomenų bazės užklausos sintaksės klaida.
+Paskutinė mėginta duomenų bazės užklausa buvo:
+"$1"
+iš funkcijos: "$2".
+MySQL grąžino klaidą "$3: $4".',
+'noconnect' => 'Atsiprašome, bet projektas turi techninių nesklandumų, ir negali prisijungti prie duomenų bazės. <br />
+$1',
+'nodb' => 'Nepavyksta pasirinkti duomenų bazės $1',
+'cachederror' => 'Pateiktas išsaugota prašomo puslapio kopija, ji gali būti pasenusi.',
+'laggedslavemode' => 'Dėmesio: Puslapyje gali nesimatyti naujausių pakeitimų.',
+'readonly' => 'Duomenų bazė užrakinta',
+'enterlockreason' => 'Įveskite užrakinimo priežastį, taip pat maždaug kada bus atrakinta',
+'readonlytext' => 'Duomenų bazė šiuo metu yra užrakinta naujiems įrašams ar kitiems keitimams,
+turbūt duomenų bazės techninei profilaktikai,
+po to viskas vėl veiks kaip įprasta.
+
+Užrakinusiojo administratoriaus pateiktas rakinimo paaiškinimas: $1',
+'missingarticle' => 'Duomenų bazei nepavyksta rasti puslapio "$1" teksto.
+
+Paprastai tai sukelia pasenusi skirtumų ar istorijos nuoroda į puslapį, kuris buvo ištrintas.
+
+Jei tai ne toks atvejis, galbūt jūs aptikote klaidą programinėje įrangoje.
+Prašome pranešti apie tai administratoriui, taip pat nurodant ir URL.',
+'readonly_lag' => 'Duomenų bazė buvo automatiškai užrakinta, kol pagalbinės duomenų bazės prisivys pagrindinę',
+'internalerror' => 'Vidinė klaida',
+'filecopyerror' => 'Nepavyksta kopijuoti failo iš "$1" į "$2".',
+'filerenameerror' => 'Nepavyksta pervardinti failo iš "$1" į "$2".',
+'filedeleteerror' => 'Nepavyksta ištrinti failo "$1".',
+'filenotfound' => 'Nepavyksta rasti failo "$1".',
+'unexpected' => 'Netikėta reikšmė: "$1"="$2".',
+'formerror' => 'Klaida: nepavyko apdoroti formos duomenų',
+'badarticleerror' => 'Veiksmas negalimas šiam puslapiui.',
+'cannotdelete' => 'Nepavyko ištrinti nurodyto puslapio ar failo. (Galbūt jį jau kažkas ištrynė)',
+'badtitle' => 'Blogas pavadinimas',
+'badtitletext' => 'Nurodytas puslapio pavadinimas buvo neleistinas, tuščias arba neteisingai sujungtas tarpkalbinis arba tarpprojektinis pavadinimas. Jame gali būti vienas ar daugiau simbolių, neleistinų pavadinimuose',
+'perfdisabled' => 'Atsiprašome, bet ši funkcija yra laikinai išjungta, nes tai ypač sulėtina duomenų bazę taip, kad daugiau niekas negali naudotis projektu.',
+'perfdisabledsub' => 'Tai išsaugota puslapio kopija iš $1:', # obsolete?
+'perfcached' => 'Rodoma išsaugota duomenų kopija, todėl duomenys gali būti ne patys naujausi.',
+'perfcachedts' => 'Rodoma išsaugota duomenų kopija, kuri buvo atnaujinta $1.',
+'wrong_wfQuery_params' => 'Neteisingi parametrai į funkciją wfQuery()<br />
+Funkcija: $1<br />
+Užklausa: $2',
+'viewsource' => 'Žiūrėti kodą',
+'viewsourcefor' => 'puslapiui $1',
+'protectedpagetext' => 'Šis puslapis yra užrakintas, saugant jį nuo redagavimo.',
+'viewsourcetext' => 'Jūs galite žiūrėti ir kopijuoti puslapio kodą:',
+'protectedinterface' => 'Šiame puslapyje yra programinės įrangos sąsajos tekstas ir yra apsaugotas, kad būtų apsisaugota nuo piktnaudžiavimo.',
+'editinginterface' => "'''Dėmesio:''' Jūs redaguojate puslapį, kuris yra naudojamas programinės įrangos sąsajos tekste. Pakeitimai šiame puslapyje taip pat pakeis naudotojo sąsajos išvaizdą ir kitiems naudojams.",
+'sqlhidden' => '(SQL užklausa paslėpta)',
+
+# Login and logout pages
+'logouttitle' => 'Naudotojo atsijungimas',
+'logouttext' => '<strong>Dabar jūs esate atsijungęs.</strong><br />
+Galite toliau naudoti {{SITENAME}} anonimiškai arba prisijunkite iš naujo tuo pačiu ar kitu naudotoju.
+Pastaba: kai kuriuose puslapiuose ir toliau gali rodyti lyg būtumėte prisijungęs iki tol, kol išvalysite savo naršyklės podėlį',
+'welcomecreation' => '== Sveiki, $1! ==
+
+Jūsų paskyra buvo sukurta. Nepamirškite pakeisti savo {{SITENAME}} nustatymų.',
+'loginpagetitle' => 'Prisijungimas',
+'yourname' => 'Naudotojo vardas',
+'yourpassword' => 'Slaptažodis',
+'yourpasswordagain' => 'Pakartokite slaptažodį',
+'remembermypassword' => 'Prisiminti šią informaciją šiame kompiuteryje',
+'yourdomainname' => 'Jūsų domenas',
+'externaldberror' => 'Yra arba išorinė autorizacijos duomenų bazės klaida arba jums neleidžiama atnaujinti jūsų išorinės paskyros.',
+'loginproblem' => '<b>Problemos su jūsų prisijungimu.</b><br />Pabandykite iš naujo!',
+'alreadyloggedin' => '<strong>Jūs jau esate prisijungęs kaip naudotojas $1!</strong><br />',
+'login' => 'Prisijungti',
+'loginprompt' => 'Įjunkite slapukus, jei norite prisijungti prie {{SITENAME}}.',
+'userlogin' => 'Prisijungti / sukurti paskyrą',
+'logout' => 'Atsijungti',
+'userlogout' => 'Atsijungti',
+'notloggedin' => 'Neprisijungęs',
+'nologin' => 'Neturite prisijungimo vardo? $1.',
+'nologinlink' => 'Sukurkite paskyrą',
+'createaccount' => 'Sukurti paskyrą',
+'gotaccount' => 'Jau turite paskyrą? $1.',
+'gotaccountlink' => 'Prisijunkite',
+'createaccountmail' => 'el. paštu',
+'badretype' => 'Įvesti slaptažodžiai nesutampa.',
+'userexists' => 'Įvestasis naudotojo vardas jau naudojamas. Prašome pasirinkti kitą vardą.',
+'youremail' => 'El. pašto adresas *:',
+'username' => 'Naudotojo vardas:',
+'uid' => 'Naudotojo ID:',
+'yourrealname' => 'Jūsų tikras vardas *:',
+'yourlanguage' => 'Sąsajos kalba:',
+'yourvariant' => 'Variantas',
+'yournick' => 'Slapyvardis:',
+'badsig' => 'Neteisingas parašas; patikrinkite HTML žymes.',
+'email' => 'El. paštas',
+'prefs-help-email-enotif' => 'Šis adresas tai pat naudojamas siųsti pranešimus, jei pasirinkote tokius pranešimus gauti.',
+'prefs-help-realname' => '* Tikras vardas (neprivaloma): jei jūs jį įvesite, jis bus naudojamas jūsų darbo pažymėjimui.',
+'loginerror' => 'Prisijungimo klaida',
+'prefs-help-email' => '* El. paštas (neprivalomas): Leidžia kitiems pasiekti jus per naudotojo ar naudotojo aptarimą neatskleidžiant jūsų tapatybės.',
+'nocookiesnew' => 'Naudotojo paskyra buvo sukurta, bet jūs nesate prisijungęs. {{SITENAME}} naudoja slapukus, kad prijungtų naudotojus. Jūs esate išjungę slapukus. Prašome įjungti juos, tada prisijunkite su savo naujuoju naudotojo vardu ir slaptažodžiu.',
+'nocookieslogin' => '{{SITENAME}} naudoja slapukus, kad prijungtų naudotojus. Jūs esate išjungę slapukus. Prašome įjungti juos ir pamėginkite vėl.',
+'noname' => 'Jūs nesate nurodęs teisingo naudotojo vardo.',
+'loginsuccesstitle' => 'Sėkmingai prisijungėte',
+'loginsuccess' => '\'\'\'Dabar jūs prisijungęs prie {{SITENAME}} kaip "$1".\'\'\'',
+'nosuchuser' => 'Nėra jokio naudotojo pavadinto "$1". Patikrinkite rašybą, arba sukurkite naują paskyrą.',
+'nosuchusershort' => 'Nėra jokio naudotojo pavadinto "$1". Patikrinkite rašybą.',
+'nouserspecified' => 'Jums reikia nurodyti naudotojo vardą.',
+'wrongpassword' => 'Įvestas neteisingas slaptažodis. Pamėginkite dar kartą.',
+'wrongpasswordempty' => 'Įvestas slaptažodis yra tuščias. Pamėginkite vėl.',
+'mailmypassword' => 'Atsiųsti slaptažodį paštu',
+'passwordremindertitle' => 'Slaptažodžio priminimas iš {{SITENAME}}',
+'passwordremindertext' => 'Kažkas (tikriausiai jūs, IP adresu $1)
+paprašė, kad atsiųstumėte naują slaptažodį projektui {{SITENAME}} ($4).
+Naudotojo "$2" slaptažodis dabar yra "$3".
+Jūs turėtumėte prisijungti ir dabar pakeisti savo slaptažodį.
+
+Jei kažkas kitas atliko šį prašymą arba jūs prisiminėte savo slaptažodį ir
+nebenorite jo pakeisti, jūs galite tiesiog nekreipti dėmėsio į šį laišką ir toliau
+naudotis savo senuoju slaptažodžiu.',
+'noemail' => 'Nėra jokio el. pašto adreso įvesto naudotojui "$1".',
+'passwordsent' => 'Naujas slaptažodis buvo nusiųstas į el. pašto adresą,
+užregistruotą naudotojo "$1".
+Prašome prisijungti vėl, kai jūs jį gausite.',
+'blocked-mailpassword' => 'Jūsų IP adresas yra užblokuotas nuo redagavimo, taigi neleidžiama naudoti slaptažodžio priminimo funkcijos, kad apsisaugotume nuo piktnaudžiavimo.',
+'eauthentsent' => 'Patvirtinimo laiškas buvo nusiųstas į paskirtąjį el. pašto adresą.
+Prieš išsiunčiant kitą laišką į jūsų dėžutę, jūs turite vykdyti nurodymus laiške, kad patvirtintumėte, kad dėžutė tikrai yra jūsų.',
+'throttled-mailpassword' => 'Slaptažodžio priminimas jau buvo išsiųstas, per paskutinias $1 valandas. Norint apsisaugoti nuo piktnaudžiavimo, slaptažodžio priminimas gali būti išsiųstas tik kas $1 valandas.',
+'mailerror' => 'Klaida siunčiant paštą: $1',
+'acct_creation_throttle_hit' => 'Atleiskite, bet jūs jau sukūrėte $1 paskyras. Daugiau nebegalima.',
+'emailauthenticated' => 'Jūsų el. pašto adresas buvo patvirtintas $1.',
+'emailnotauthenticated' => 'Jūsų el. pašto adresas dar nėra patvirtintas. Jokie laiškai
+nebus siunčiami nei vienai žemiau išvardintai paslaugai.',
+'noemailprefs' => 'Nurodykite el. pašto adresą, kad šios funkcijos veiktų.',
+'emailconfirmlink' => 'Patvirtinkite savo el. pašto adresą',
+'invalidemailaddress' => 'El. pašto adresas negali būti priimtas, nes atrodo, kad jis nėra teisingo formato. Prašome įvesti gerai suformuotą adresą arba palikite tą laukelį tuščią.',
+'accountcreated' => 'Paskyra sukurta',
+'accountcreatedtext' => 'Naudotojo paskyra $1 buvo sukurta.',
+
+# Password reset dialog
+'resetpass' => 'Paskyros slaptažodžio atstatymas',
+'resetpass_announce' => 'Jūs prisijungėte su atsiųstu laikinuoju kodu. Norėdami užbaigti prisijungimą, čia jums reikia nustatyti naująjį slaptažodį:',
+'resetpass_text' => '<!-- Įterpkite čia tekstą -->',
+'resetpass_header' => 'Atstatyti slaptažodį',
+'resetpass_submit' => 'Nustatyti slaptažodį ir prisijungti',
+'resetpass_success' => 'Jūsų slaptažodis pakeistas sėkmingai! Dabar prisijungiama...',
+'resetpass_bad_temporary' => 'Neteisingas laikinasis slaptažodis. Galbūt jūs jau sėkmingai pakeitėte savo slaptažodį arba paprašėte naujo laikino slaptažodžio.',
+'resetpass_forbidden' => 'Šiame projekte slaptažodžiai negali būti pakeisti',
+'resetpass_missing' => 'Nėra formos duomenų.',
+
+# Edit page toolbar
+'bold_sample' => 'Paryškintas tekstas',
+'bold_tip' => 'Paryškinti tekstą',
+'italic_sample' => 'Tekstas kursyvu',
+'italic_tip' => 'Tekstas kursyvu',
+'link_sample' => 'Nuorodos pavadinimas',
+'link_tip' => 'Vidinė nuoroda',
+'extlink_sample' => 'http://www.pavyzdys.lt nuorodos pavadinimas',
+'extlink_tip' => 'Išorinė nuoroda (nepamirškite http:// priedėlio)',
+'headline_sample' => 'Skyriaus pavadinimas',
+'headline_tip' => 'Antro lygio skyriaus pavadinimas',
+'math_sample' => 'Įveskite formulę',
+'math_tip' => 'Matematinė formulė (LaTeX formatu)',
+'nowiki_sample' => 'Čia įterpkite neformuotą tekstą',
+'nowiki_tip' => 'Ignoruoti wiki formatą',
+'image_sample' => 'Pavyzdys.jpg',
+'image_tip' => 'Įdėti paveiksėlį',
+'media_sample' => 'Pavyzdys.ogg',
+'media_tip' => 'Nuoroda į media failą',
+'sig_tip' => 'Jūsų parašas bei laikas',
+'hr_tip' => 'Horizontali linija (naudokite taupiai)',
+
+# Edit pages
+'summary' => 'Komentaras',
+'subject' => 'Tema/antraštė',
+'minoredit' => 'Tai smulkus pataisymas',
+'watchthis' => 'Stebėti šį puslapį',
+'savearticle' => 'Išsaugoti puslapį',
+'preview' => 'Peržiūra',
+'showpreview' => 'Rodyti peržiūrą',
+'showlivepreview' => 'Tiesioginė peržiūra',
+'showdiff' => 'Rodyti skirtumus',
+'anoneditwarning' => "'''Dėmesio:''' Jūs nesate prisijungęs. Jūsų IP adresas bus įrašytas į šio puslapio istoriją.",
+'missingsummary' => "'''Priminimas:''' Jūs nenurodėte keitimo komentaro. Jei vėl paspausite Saugoti, jūsų keitimas bus išsaugotas be jo.",
+'missingcommenttext' => 'Prašome įvesti komentarą.',
+'missingcommentheader' => "'''Priminimas:''' Jūs nenurodėte skyrelio/antraštės šiam komentarui. Jei vėl paspausite Saugoti, jūsų keitimas bus išsaugotas be jo.",
+'summary-preview' => 'Komentaro peržiūra',
+'subject-preview' => 'Skyrelio/antraštės peržiūra',
+'blockedtitle' => 'Naudotojas yra užblokuotas',
+'blockedtext' => "<big>'''Jūsų naudotojo vardas arba IP adresas yra užblokuotas.'''</big>
+
+Užblokavo $1. Nurodyta priežastis yra ''$2''.
+
+Jūs galite susisiekti su $1 arba kitu
+[[{{ns:project}}:Administrators|administratoriumi]] aptarti užblokavimą.
+Jūs negalite naudoti funkcija 'Rašyti laišką šiam naudotojui', jei nesate pateikę tikro savo el. pašto adreso savo [[{{ns:special}}:Preferences|paskyros nustatymuose]]. Jūsų IP adresas yra $3, o bloko ID yra #$5. Prašome nurodyti vieną ar abu juos, kai kreipiatės dėl blokavimo.",
+'blockedoriginalsource' => "Žemiau yra rodomas '''$1''' turinys:",
+'blockededitsource' => "''Jūsų keitimų''' tekstas puslapiui '''$1''' yra rodomas žemiau:",
+'whitelistedittitle' => 'Norint redaguoti reikia prisijungti',
+'whitelistedittext' => 'Jūs turite $1, kad redaguotumėte puslapius.',
+'whitelistreadtitle' => 'Norint skaityti reikia prisijungti',
+'whitelistreadtext' => 'Jums reikia [[{{ns:special}}:Userlogin|prisijungti]], kad skaitytumėte puslapius.',
+'whitelistacctitle' => 'Jums neleidžiama kurti paskyros',
+'whitelistacctext' => 'Norėdami leisti kurti paskyras šiame projekte, jums reikia [[{{ns:special}}:Userlogin|prisijungti]] ir turėti atitinkamas teises.',
+'confirmedittitle' => 'Reikalingas el. pašto patvirtinimas, kad redaguotumėte',
+'confirmedittext' => 'Jums reikia patvirtinti el. pašto adresą, prieš redaguojant puslapius. Prašome nurodyti ir patvirtinti jūsų el. pašto adresą per jūsų [[{{ns:special}}:Preferences|naudotojo nustatymus]].',
+'loginreqtitle' => 'Reikalingas prisijungimas',
+'loginreqlink' => 'prisijungti',
+'loginreqpagetext' => 'Jums reikia $1, kad matytumėte kitus puslapius.',
+'accmailtitle' => 'Slaptažodis išsiųstas.',
+'accmailtext' => "Naudotojo '$1' slaptažodis nusiųstas į $2.",
+'newarticle' => '(Naujas)',
+'newarticletext' => "Jūs patekote į dar neegzistuojantį puslapį.
+Norėdami sukurti puslapį, pradėkite rašyti žemiau esančiame įvedimo lauke
+(plačiau [[{{ns:help}}:Kaip pradėti puslapį|apie puslapių kūrimą]]).
+Jei patekote čia per klaidą, paprasčiausiai spustelkite naršyklės mygtuką '''atgal'''.",
+'anontalkpagetext' => "----''Tai yra anoniminio naudotojo, nesusikūrusio arba nenaudojančio paskyros, aptarimų puslapis. Dėl to naudojamas IP adresas jo identifikavimui. Šis IP adresas gali būti dalinamas keliems naudotojams. Jeigu Jūs esate anoniminis naudotojas ir atrodo, kad komentarai nėra skirti Jums, [[{{ns:special}}:Userlogin|sukurkite paskyrą arba prisijunkite]], ir nebūsite tapatinamas su kitais anoniminiais naudotojais.''",
+'noarticletext' => 'Šiuo metu šiame puslapyje nėra jokio teksto, jūs galite [[{{ns:special}}:Search/{{PAGENAME}}|ieškoti šio puslapio pavadinimo]] kituose puslapiuose arba [{{fullurl:{{FULLPAGENAME}}|action=edit}} redaguoti šį puslapį].',
+'clearyourcache' => "'''Dėmesio:''' Išsaugoję jums gali prireikti išvalyti jūsų naršyklės podėlį, kad pamatytumėte pokyčius. '''Mozilla / Safari / Konqueror:''' laikydami ''Shift'' pasirinkite ''Atsiųsti iš naujo'', arba paspauskite ''Ctrl-Shift-R'' (sistemoje Apple Mac ''Cmd-Shift-R''); '''IE:''' laikydami ''Ctrl'' paspauskite ''Atnaujinti'', arba paspauskite ''Ctrl-F5''; '''Konqueror:''' tiesiog paspauskite ''Perkrauti'' mygtuką, arba paspauskite ''F5''; '''Opera''' naudotojams gali prireikti pilnai išvalyti jų podėlį ''Priemonės→Nuostatos''.",
+'usercssjsyoucanpreview' => "<strong>Patarimas:</strong> Naudokite 'Rodyti peržiūrą' mygtuką, kad išmėgintumėte savo naująjį CSS/JS prieš išsaugant.",
+'usercsspreview' => "'''Nepamirškite, kad jūs tik peržiūrit savo naudotojo CSS, jis dar nebuvo išsaugotas!'''",
+'userjspreview' => "'''Nepamirškite, kad jūs tik testuojat/peržiūrit savo naudotojo JavaScript, jis dar nebuvo išsaugotas!'''",
+'userinvalidcssjstitle' => '\'\'\'Dėmesio:\'\'\' Nėra jokios išvaizdos "$1". Nepamirškite, kad savo .css ir .js puslapiai naudoja pavadinimą mažosiomis raidėmis, pvz., {{ns:user}}:Foo/monobook.css, o ne {{ns:user}}:Foo/Monobook.css.',
+'updated' => '(Atnaujinta)',
+'note' => '<strong>Pastaba:</strong>',
+'previewnote' => '<strong>Nepamirškite, kad tai tik peržiūra, pakeitimai dar nėra išsaugoti!</strong>',
+'previewconflict' => 'Ši peržiūra parodo tekstą iš viršutiniojo teksto redagavimo lauko taip, kaip jis bus rodomas, jei pasirinksite išsaugoti.',
+'session_fail_preview' => '<strong>Atsiprašome! Mes negalime vykdyti jūsų keitimo dėl sesijos duomenų praradimo.
+Prašome pamėginti vėl. Jei tai nepadeda, pamėginkite atsijungti ir prisijungti atgal.</strong>',
+'session_fail_preview_html' => "<strong>Atsiprašome! Mes vykdyti apdoroti jūsų keitimo dėl sesijos duomenų praradimo.</strong>
+
+''Kadangi šiame projekte grynasis HTML yra įjungtas, peržiūra yra paslėpta kaip atsargumo priemonė prieš JavaScript atakas.''
+
+<strong>Jei tai teisėtas keitimo bandymas, prašome pamėginti vėl. Jei tai nepadeda, pamėginkite atsijungti ir prisijungti atgal.</strong>",
+'importing' => 'Importuojama $1',
+'editing' => 'Taisomas $1',
+'editinguser' => 'Taisomas naudotojas <b>$1</b>',
+'editingsection' => 'Taisomas $1 (skyrelis)',
+'editingcomment' => 'Taisomas $1 (komentaras)',
+'editconflict' => 'Išpręskite konfliktą: $1',
+'explainconflict' => 'Kažkas kitas jau pakeitė puslapį nuo tada, kai jūs pradėjote jį redaguoti.
+Viršutiniame tekstiniame lauke pateikta šiuo metu esanti puslapio versija.
+Jūsų keitimai pateikti žemiau esančiame lauke.
+Jums reikia sujungti jūsų pakeitimus su esančia versija.
+Paspaudus "Išsaugoti", užsaugotas bus
+<b>tik</b> tekstas viršutiniame tekstiniame lauke.<br />',
+'yourtext' => 'Jūsų tekstas',
+'storedversion' => 'Išsaugota versija',
+'nonunicodebrowser' => '<strong>ĮSPĖJIMAS: Jūsų naršyklė nepalaiko unikodo. Todėl, tam kad saugiai redaguotumėte straipsnį, redagavimo lauke vietoj ne ASCII simbolių bus rodomi šešioliktainiai kodai.</strong>',
+'editingold' => '<strong>ĮSPĖJIMAS: Jūs keičiate ne naujausią puslapio versiją.
+Jei išsaugosite savo keitimus, po to daryti pakeitimai pradings.</strong>',
+'yourdiff' => 'Skirtumai',
+'copyrightwarning' => 'Primename, kad viskas, kas patenka į {{SITENAME}}, yra laikoma paskelbtu pagal $2 (detaliau - $1). Jei nenorite, kad jūsų indėlis būtų be gailesčio redaguojamas ir platinamas, čia nerašykite.<br />
+Jūs taip pat pasižadate, kad tai jūsų pačių rašytas turinys arba kopijuotas iš viešų ar panašių nemokamų šaltinių.
+<strong>NEKOPIJUOKITE AUTORINĖMIS TEISĖMIS APSAUGOTŲ DARBŲ BE LEIDIMO!</strong>',
+'copyrightwarning2' => 'Prašome pastebėti, kad viskas, kas patenka į {{SITENAME}} gali būti redaguojami, perdaromi, ar pašalinami kitų naudotojų. Jei nenorite, kad jūsų indėlis būtų be gailesčio redaguojamas, čia nerašykite.<br />
+Taip pat jūs pasižadate, kad tai jūsų pačių rašytas tekstas arba kopijuotas
+iš viešų ar panašių nemokamų šaltinių (detaliau - $1).
+<strong>NEKOPIJUOKITE AUTORINĖMIS TEISĖMIS APSAUGOTŲ DARBŲ BE LEIDIMO!</strong>',
+'longpagewarning' => '<strong>DĖMESIO: Šis puslapis yra $1 kilobaitų ilgio; kai kurios
+naršyklės gali turėti problemų redaguojant puslapius beveik ar virš 32 KB.
+Prašome pamėginti puslapį padalinti į keletą smulkesnių dalių.</strong>',
+'longpageerror' => '<strong>KLAIDA: Tekstas, kurį pateikėte, yra $1 kilobaitų ilgio,
+kuris yra didesnis nei daugiausiai leistini $2 kilobaitai. Jis nebus išsaugotas.</strong>',
+'readonlywarning' => '<strong>DĖMESIO: Duomenų bazė buvo užrakinta techninei profilaktikai,
+taigi negalėsite išsaugoti savo pakeitimų dabar. Jūs gali nusikopijuoti tekstą į tekstinį failą
+ir vėliau įkelti jį čia.</strong>',
+'protectedpagewarning' => '<strong>DĖMESIO: Šis puslapis yra užrakintas ir jį redaguoti gali tik administratoriaus teises turintys naudotojai.</strong>',
+'semiprotectedpagewarning' => "'''Pastaba:''' Šis puslapis buvo užrakintas ir jį gali redaguoti tik registruoti naudotojai.",
+'templatesused' => 'Straipsnyje naudojami šablonai:',
+'templatesusedpreview' => 'Šablonai, naudoti šioje peržiūroje:',
+'templatesusedsection' => 'Šablonai, naudoti šiame skyrelyje:',
+'edittools' => '<!-- Šis tekstas bus rodomas po redagavimo ir įkėlimo formomis. -->',
+'nocreatetitle' => 'Puslapių kūrimas apribotas',
+'nocreatetext' => 'Šioje svetainėje yra apribota galimybė kurti naujus puslapius.
+Jūs galite grįžti ir redaguoti jau esantį puslapį, arba [[{{ns:special}}:Userlogin|prisijungti arba sukurti paskyrą]].',
+
+# "Undo" feature
+'undo-success' => 'Keitimas buvo atšauktas. Prašome patvirtinti, o tada išsaugoti pakeitimus žemiau.',
+'undo-failure' => 'Keitimas negali būti atšauktas dėl konfliktuojančių tarpinių keitimų.',
+'undo-summary' => 'Atšaukti [[{{ns:special}}:Contributions/$2]] ([[{{ns:user_talk}}:$2]]) versiją $1',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'Paskyrų kūrimas negalimas',
+'cantcreateaccounttext' => 'Paskyrų kūrimas iš šio IP adreso (<b>$1</b>) yra užbluokuotas.
+Tai gali būti dėl dažno vandalizmo iš jūsų mokyklos ar interneto tiekėjo.',
+
+# History pages
+'revhistory' => 'Versijų istorija',
+'viewpagelogs' => 'Rodyti šio puslapio specialiuosius veiksmus',
+'nohistory' => 'Šis puslapis neturi keitimų istorijos.',
+'revnotfound' => 'Versija nerasta',
+'revnotfoundtext' => 'Norima puslapio versija nerasta.
+Patikrinkite URL, kuriuo patekote į šį puslapį.',
+'loadhist' => 'Įkeliama puslapio istorija',
+'currentrev' => 'Dabartinė versija',
+'revisionasof' => '$1 versija',
+'revision-info' => '$1 versija naudotojo $2',
+'previousrevision' => '←Ankstesnė versija',
+'nextrevision' => 'Vėlesnė versija→',
+'currentrevisionlink' => 'Dabartinė versija',
+'cur' => 'dab',
+'next' => 'kitas',
+'last' => 'pask',
+'orig' => 'orig',
+'histlegend' => "Skirtumai tarp versijų: pažymėkite lyginamas versijas ir spustelkite ''Enter'' klavišą arba mygtuką apačioje.<br />
+Žymėjimai: (dab) = palyginimas su naujausia versija,
+(pask) = palyginimas su prieš tai buvusia versija, S = smulkus keitimas.",
+'deletedrev' => '[ištrinta]',
+'histfirst' => 'Seniausi',
+'histlast' => 'Paskutiniai',
+'rev-deleted-comment' => '(komentaras pašalintas)',
+'rev-deleted-user' => '(naudotojo vardas pašalintas)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">Ši puslapio versija buvo pašalinta iš viešųjų archyvų.
+[{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} Trynimo istorijoje] gali būti detalių.</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Ši puslapio versija buvo pašalinta iš viešųjų archyvų.
+Kaip šios svetainės administratorius, jūs galite jį pamatyti;
+[{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} trynimo istorijoje] gali būti detalių.
+</div>',
+'rev-delundel' => 'rodyti/slėpti',
+
+'history-feed-title' => 'Versijų istorija',
+'history-feed-description' => 'Šio puslapio versijų istorija projekte',
+'history-feed-item-nocomment' => '$1 $2', # user at time
+'history-feed-empty' => 'Prašomas puslapis neegzistuoja.
+Jis galėjo būti ištrintas iš projekto, arba pervardintas.
+Pamėginkite [[{{ns:special}}:Search|ieškoti projekte]] susijusių naujų puslapių.',
+
+# Revision deletion
+'revisiondelete' => 'Trinti/atkurti versijas',
+'revdelete-nooldid-title' => 'Nenurodyta versija',
+'revdelete-nooldid-text' => 'Nenurodėte versijos ar versijų, kurioms įvykdyti šią funkciją.',
+'revdelete-selected' => 'Pasirinktos [[:$1]] versijos:',
+'revdelete-text' => 'Ištrintos versjos vistiek dar bus rodomos puslapio istorijoje, bet jų turinys nebus viešai prieinamas.
+
+Kiti administratoriai šiame projekte vis dar galės pasiekti paslėptą turinį ir galės jį atkurti vėl naudojantis ta pačia sąsaja, nebent yra nustatyti papildomi apribojami svetainės tvarkytojams.',
+'revdelete-legend' => 'Nustatyti versijos apribojimus:',
+'revdelete-hide-text' => 'Slėpti versijos tekstą',
+'revdelete-hide-comment' => 'Slėpti redagavimo komentarą',
+'revdelete-hide-user' => 'Slėpti redagavusiojo naudotojo vardą ar IP adresą',
+'revdelete-hide-restricted' => 'Taikyti šiuos apribojimus ir administratoriams kaip ir kitiems',
+'revdelete-log' => 'Komentaras:',
+'revdelete-submit' => 'Taikyti pasirinktai versijai',
+'revdelete-logentry' => 'pakeistas versijos matomumas puslapiui [[$1]]',
+
+# Diffs
+'difference' => '(Skirtumai tarp versijų)',
+'loadingrev' => 'įkeliama versija palyginimui',
+'lineno' => 'Eilutė $1:',
+'editcurrent' => 'Redaguoti dabartinę puslapio versiją',
+'selectnewerversionfordiff' => 'Pasirinkite naujesnę versiją palyginimui',
+'selectolderversionfordiff' => 'Pasirinkite senesnę versiją palyginimui',
+'compareselectedversions' => 'Palyginti pasirinktas versijas',
+'editundo' => 'atšaukti',
+'diff-multi' => '($1 {{plural:$1|tarpinis keitimas nėra rodomas|tarpiniai keitimai nėra rodomi|tarpinių keitimų nėra rodoma}}.)',
+
+# Search results
+'searchresults' => 'Paieškos rezultatai',
+'searchresulttext' => 'Daugiau informacijos apie paiešką projekte {{SITENAME}} rasite - [[{{ns:project}}:Paieška|Paieška projekte {{SITENAME}}]].',
+'searchsubtitle' => 'Ieškoma "[[:$1]]"',
+'searchsubtitleinvalid' => 'Ieškoma "$1"',
+'badquery' => 'Blogai suformuota paieškos užklausa',
+'badquerytext' => 'Nepavyko apdoroti Jūsų užklausos.
+Tai galėjo būti dėl trumpesnio nei trijų simbolių paieškos rakto, arba neteisingai suformuotos užklausos (pavyzdžiui "tigras and and liūtas").
+Pamėginkite kitokią užklausą.',
+'matchtotals' => 'Užklausa "$1" atitiko $2 puslapių pavadinimus
+ir $3 puslapių turinius.',
+'noexactmatch' => '\'\'\'Nėra jokio puslapio pavadinto "$1".\'\'\' Jūs galite [[:$1|sukurti šį puslapį]].',
+'titlematches' => 'Straipsnių pavadinimų atitikmenys',
+'notitlematches' => 'Jokių pavadinimo atitikmenų',
+'textmatches' => 'Puslapio turinio atitikmenys',
+'notextmatches' => 'Jokių puslapių teksto atitikmenų',
+'prevn' => 'ankstesnius $1',
+'nextn' => 'tolimesnius $1',
+'viewprevnext' => 'Žiūrėti ($1) ($2) ($3).',
+'showingresults' => 'Rodomi iki <b>$1</b> rezultatų pradedant #<b>$2</b>.',
+'showingresultsnum' => 'Rodoma <b>$3</b> rezultatų pradedant #<b>$2</b>.',
+'nonefound' => '\'\'\'Pastaba\'\'\': Nesėkminga paieška dažnai būna dėl ieškomų
+dažnai naudojamų žodžių, tokių kaip "yra" ar "iš", kurie yra
+neindeksuojami, arba nurodžius daugiau nei vieną paieškos žodį (rezultatuose
+bus tik tie straipsniai, kuriuose bus visi paieškos žodžiai).',
+'powersearch' => 'Ieškoti',
+'powersearchtext' => 'Ieškoti šiose vardų srityse:<br />$1<br /><label>$2 Rodyti peradresavimus</label><br />Ieškoti $3 $9',
+'searchdisabled' => 'Projekto {{SITENAME}} paieška yra uždrausta. Galite pamėginti ieškoti Google paieškos sistemoje. Paieškos sistemoje projekto {{SITENAME}} duomenys gali būti pasenę.',
+'blanknamespace' => '(Pagrindinė)',
+
+# Preferences page
+'preferences' => 'Nustatymai',
+'mypreferences' => 'Mano nustatymai',
+'prefsnologin' => 'Neprisijungęs',
+'prefsnologintext' => 'Jums reikia būti [[{{ns:special}}:Userlogin|prisijungti]], kad galėtumėte keisti savo nustatymus.',
+'prefsreset' => 'Nustatymai buvo atstatyti iš saugyklos.',
+'qbsettings' => 'Greitasis pasirinkimas',
+'changepassword' => 'Pakeisti slaptažodį',
+'skin' => 'Išvaizda',
+'math' => 'Matematika',
+'dateformat' => 'Datos formatas',
+'datedefault' => 'Jokio pasirinkimo',
+'datetime' => 'Data ir laikas',
+'math_failure' => 'Nepavyko apdoroti',
+'math_unknown_error' => 'nežinoma klaida',
+'math_unknown_function' => 'nežinoma funkcija',
+'math_lexing_error' => 'leksikos klaida',
+'math_syntax_error' => 'sintaksės klaida',
+'math_image_error' => 'PNG konvertavimas nepavyko; patikrinkite, ar teisingai įdiegta latex, dvips, gs, ir convert',
+'math_bad_tmpdir' => 'Nepavyksta sukurti arba rašyti į matematikos laikinąjį aplanką',
+'math_bad_output' => 'Nepavyksta sukurti arba rašyti į matematikos išvesties aplanką',
+'math_notexvc' => 'Trūksta texvc vykdomojo failo; pažiūrėkite math/README kaip konfigūruoti.',
+'prefs-personal' => 'Naudotojo profilis',
+'prefs-rc' => 'Paskutiniai keitimai',
+'prefs-watchlist' => 'Stebimų sąrašas',
+'prefs-watchlist-days' => 'Kiek dienų rodyti stebimų sąraše:',
+'prefs-watchlist-edits' => 'Kiek keitimų rodyti išplėstiniame stebimų sąraše:',
+'prefs-misc' => 'Įvairūs nustatymai',
+'saveprefs' => 'Išsaugoti',
+'resetprefs' => 'Atstatyti nustatymus',
+'oldpassword' => 'Senas slaptažodis:',
+'newpassword' => 'Naujas slaptažodis:',
+'retypenew' => 'Pakartokite naują slaptažodį:',
+'textboxsize' => 'Redagavimo dėžė',
+'rows' => 'Eilutės:',
+'columns' => 'Stulpeliai:',
+'searchresultshead' => 'Paieškos nustatymai',
+'resultsperpage' => 'Rezultatų puslapyje:',
+'contextlines' => 'Eilučių rezultate:',
+'contextchars' => 'Konteksto simbolių eilutėje:',
+'stubthreshold' => 'Žymėti puslapį kaip nepilną, jei mažesnis nei:',
+'recentchangescount' => 'Kiek pakeitimų rodoma naujausių keitimų sąraše',
+'savedprefs' => 'Nustatymai sėkmingai išsaugoti.',
+'timezonelegend' => 'Laiko juosta',
+'timezonetext' => 'Įveskite kiek valandų jūsų vietinis laikas skiriasi nuo serverio laiko (UTC).',
+'localtime' => 'Vietinis laikas',
+'timezoneoffset' => 'Skirtumas¹',
+'servertime' => 'Serverio laikas',
+'guesstimezone' => 'Paimti iš naršyklės',
+'allowemail' => 'Leisti siųsti el. laiškus iš kitų naudotojų',
+'defaultns' => 'Pagal nutylėjimą ieškoti šiose vardų srityse:',
+'default' => 'pagal nutylėjimą',
+'files' => 'Failai',
+
+# User rights
+'userrights-lookup-user' => 'Tvarkyti naudotojo grupes',
+'userrights-user-editname' => 'Įveskite naudotojo vardą:',
+'editusergroup' => 'Redaguoti naudotojo grupes',
+'userrights-editusergroup' => 'Redaguoti naudotojų grupes',
+'saveusergroups' => 'Saugoti naudotojų grupes',
+'userrights-groupsmember' => 'Narys:',
+'userrights-groupsavailable' => 'Galimos grupės:',
+'userrights-groupshelp' => 'Pasirinkite grupes, į kurias pridėti ar iš kurių pašalinti naudotoją.
+Nepasirinktos grupės nebus pakeistos. Galite atžymėti grupę laikydami Ctrl ir paspausdami kairiuoju pelės klavišu',
+
+# Groups
+'group' => 'Grupė:',
+'group-bot' => 'Robotai',
+'group-sysop' => 'Administratoriai',
+'group-bureaucrat' => 'Biurokratai',
+'group-all' => '(visi)',
+
+'group-bot-member' => 'Robotas',
+'group-sysop-member' => 'Administratorius',
+'group-bureaucrat-member' => 'Biurokratas',
+
+'grouppage-bot' => '{{ns:project}}:Robotai',
+'grouppage-sysop' => '{{ns:project}}:Administratoriai',
+'grouppage-bureaucrat' => '{{ns:project}}:Biurokratai',
+
+# Recent changes
+'changes' => 'pasikeitimai',
+'recentchanges' => 'Paskutiniai keitimai',
+'recentchangestext' => 'Šiame puslapyje yra patys naujausi pakeitimai šiame projekte.',
+'rcnote' => 'Pateikiamas <strong>$1</strong> paskutinių pakeitimų sąrašas per {{PLURAL:$2|$2 paskutiniąją dieną|paskutiniąsias $2 dienas|paskutiniąsias $2 dienų}} skaičiuojant nuo $3.',
+'rcnotefrom' => 'Žemiau yra pakeitimai pradedant <b>$2</b> (rodoma iki <b>$1</b> pakeitimų).',
+'rclistfrom' => 'Rodyti naujus pakeitimus pradedant $1',
+'rcshowhideminor' => '$1 smulkius keitimus',
+'rcshowhidebots' => '$1 robotus',
+'rcshowhideliu' => '$1 prisijungusius naudotojus',
+'rcshowhideanons' => '$1 anoniminius naudotojos',
+'rcshowhidepatr' => '$1 patikrintus keitimus',
+'rcshowhidemine' => '$1 mano keitimus',
+'rclinks' => 'Rodyti paskutinius $1 pakeitimų per paskutiniąsias $2 dienas(ų)<br />$3',
+'diff' => 'skirt',
+'hist' => 'ist',
+'hide' => 'Slėpti',
+'show' => 'Rodyti',
+'minoreditletter' => 'S',
+'newpageletter' => 'N',
+'boteditletter' => 'R',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 stebintys naudotojai]',
+'rc_categories' => 'Rodyti tik šias kategorijas (atskirkite su "|")',
+'rc_categories_any' => 'Bet kokia',
+
+# Upload
+'upload' => 'Įkelti failą',
+'uploadbtn' => 'Įkelti failą',
+'reupload' => 'Pakartoti įkėlimą',
+'reuploaddesc' => 'Grįžti į įkėlimo formą.',
+'uploadnologin' => 'Neprisijungęs',
+'uploadnologintext' => 'Norėdami įkelti failą, turite būti [[{{ns:special}}:Userlogin|prisijungęs]].',
+'upload_directory_read_only' => 'Tinklapio serveris negali rašyti į įkėlimo aplanką ($1).',
+'uploaderror' => 'Įkėlimo klaida',
+'uploadtext' => "Naudokitės žemiau pateikta forma failų įkėlimui, norėdami peržiūrėti ar ieškoti anksčiau įkeltų paveikslėlių,
+eikite į [[{{ns:special}}:Imagelist|įkeltų failų sąrašą]], įkėlimai ir trynimai yra registruojami [[{{ns:special}}:Log/upload|įkėlimų istorijoje]].
+
+Norėdami panaudoti įkeltą paveikslėlį puslapyje, naudokite tokias nuorodas
+'''<nowiki>[[{{ns:image}}:Failas.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:Failas.png|alternatyvusis tekstas]]</nowiki>''' arba
+'''<nowiki>[[{{ns:media}}:Failas.ogg]]</nowiki>''' tiesioginei nuorodai į failą.",
+'uploadlog' => 'įkėlimų sąrašas',
+'uploadlogpage' => 'Įkėlimų sąrašas',
+'uploadlogpagetext' => 'Žemiau pateikiamas paskutinių failų įkėlimų sąrašas.',
+'filename' => 'Failo vardas',
+'filedesc' => 'Komentaras',
+'fileuploadsummary' => 'Komentaras:',
+'filestatus' => 'Autorystės teisės',
+'filesource' => 'Šaltinis',
+'copyrightpage' => '{{ns:project}}:Autorystės teisės',
+'copyrightpagename' => '{{SITENAME}} autorystės teisės',
+'uploadedfiles' => 'Įkelti failai',
+'ignorewarning' => 'Ignoruoti įspėjimą ir išsaugoti failą vistiek.',
+'ignorewarnings' => 'Ignuoruoti bet kokius įspėjimus',
+'minlength' => 'Failo pavadinimas turi būti bent trijų raidžių ilgio.',
+'illegalfilename' => 'Failo varde "$1" yra simbolių, neleidžiamų puslapio pavadinimuose. Prašome pervadint failą ir mėginkite įkelti jį iš naujo.',
+'badfilename' => 'Failo pavadinimas pakeistas į "$1".',
+'badfiletype' => '".$1" yra nerekomenduojamas paveikslėlio bylos formatas.',
+'large-file' => 'Rekomenduojama, kad failų dydis būtų nedidesnis nei $1; šio failo dydis yra $2.',
+'largefileserver' => 'Šis failas yra didesnis nei serveris yra sukonfigūruotas leisti.',
+'emptyfile' => 'Panašu, kad failas, kurį įkėlėte yra tuščias. Tai gali būti dėl klaidos failo pavadinime. Pasitikrinkite ar tikrai norite įkelti šitą failą.',
+'fileexists' => 'Failas tuo pačiu vardu jau egzistuoja, prašome pažiūrėti $1, jei nesate tikras, ar norite perrašyti šį failą.',
+'fileexists-forbidden' => 'Failas tokiu pačiu vardu jau egzistuoja; prašome eiti atgal ir įkelti šį failą kitu vardu. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Failas tokiu vardu jau egzistuoja bendrojoje failų saugykloje; prašome eiti atgal ir įkelti šį failą kitu vardu. [[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'Įkelta sėkmingai',
+'fileuploaded' => 'Failas $1 sėkmingai įkeltas.
+Prašome nueiti šia nuoroda: $2 į aprašymo puslapį ir įrašyti
+informaciją apie failą, iš kokio šaltinio paimtas, kada buvo sukurtas,
+kas jo autorius, bei kitą susijusią informaciją. Jei tai
+paveikslėlis, jūs galite jį įterpti šitaip: <tt><nowiki>[[{{ns:image}}:$1|thumb|Aprašymas]]</nowiki></tt>',
+'uploadwarning' => 'Dėmesio',
+'savefile' => 'Išsaugoti failą',
+'uploadedimage' => 'įkėlė "[[$1]]"',
+'uploaddisabled' => 'Įkėlimai uždrausti',
+'uploaddisabledtext' => 'Šiame projekte failų įkėlimai yra uždrausti.',
+'uploadscripted' => 'Šis failas turi HTML arba programinį kodą, kuris gali būti klaidingai suprastas interneto naršyklės.',
+'uploadcorrupt' => 'Failas yra pažeistas arba turi neteisingą galūnę. Prašome patikrinti failą ir įkeltį jį vėl.',
+'uploadvirus' => 'Šiame faile yra virusas! Smulkiau: $1',
+'sourcefilename' => 'Įkeliamas failas',
+'destfilename' => 'Norimas failo vardas',
+'watchthisupload' => 'Stebėti šį puslapį',
+'filewasdeleted' => 'Failas šiuo vardu anksčiau buvo įkeltas, o paskui ištrintas. Jums reikėtų patikrinti $1 prieš bandant įkelti jį vėl.',
+
+'upload-proto-error' => 'Neteisingas protokolas',
+'upload-proto-error-text' => 'Nuotoliniai įkėlimas reikalauja, kad URL prasidėtų <code>http://</code> arba <code>ftp://</code>.',
+'upload-file-error' => 'Vidinė klaida',
+'upload-file-error-text' => 'Įvyko vidinė klaida bandant sukurti laikinąjį failą serveryje. Prašome susisiekti su sistemos administratoriumi.',
+'upload-misc-error' => 'Nežinoma įkėlimo klaida',
+'upload-misc-error-text' => 'Įvyko nežinoma klaida vykstant įkėlimui. Prašome patikrinti, kad URL teisingas bei pasiekiamas ir pamėginkite vėl. Jei problema lieka, susisiekite su sistemos administratoriumi.',
+
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => 'Nepavyksta pasiekti URL',
+'upload-curl-error6-text' => 'Pateiktas URL negali būti pasiektas. Prašome patikrinti, kad URL yra teisingas ir svetainė veikia.',
+'upload-curl-error28' => 'Per ilgai įkeliama',
+'upload-curl-error28-text' => 'Atsakant svetainė užtrunka per ilgai. Patikrinkite, ar svetainė veikia, palaukite truputį ir vėl pamėginkite. Galbūt jums reikėtų pamėginti ne tokiu apkrautu metu.',
+
+'license' => 'Licensija',
+'nolicense' => 'Nepasirinkta',
+'upload_source_url' => ' (tikras, viešai prieinamas URL)',
+'upload_source_file' => ' (failas jūsų kompiuteryje)',
+
+# Image list
+'imagelist' => 'Failų sąrašas',
+'imagelisttext' => "Žemiau yra '''$1''' {{plural:$1|failo|failų}} sąrašas, surūšiuotas $2.",
+'imagelistforuser' => 'Čia rodomi tik paveikslėliai, kuriuos įkelė $1.',
+'getimagelist' => 'gauti failų sąrašą',
+'ilsubmit' => 'Ieškoti',
+'showlast' => 'Rodyti paskutinius $1 paveikslėlių, rūšiuojant $2.',
+'byname' => 'pagal vardą',
+'bydate' => 'pagal datą',
+'bysize' => 'pagal dydį',
+'imgdelete' => 'trint',
+'imgdesc' => 'apr',
+'imgfile' => 'failas',
+'imglegend' => 'Žymėjimai: (apr) = žiūrėti/redaguoti failo aprašymą.',
+'imghistory' => 'Paveikslėlio istorija',
+'revertimg' => 'atst',
+'deleteimg' => 'trinti',
+'deleteimgcompletely' => 'Ištrinti visas šio failo versijas',
+'imghistlegend' => 'Žymėjimai: (dab) = dabartinė failo versija, (trinti) = ištrinti
+seną versiją, (atst) = atstatyti seną versiją.
+<br /><i>Spustelkite ant datos norėdami pažiūrėti tuo metu buvusią versiją</i>.',
+'imagelinks' => 'Nuorodos',
+'linkstoimage' => 'Šie puslapiai nurodo į šį failą:',
+'nolinkstoimage' => 'Į failą nenurodo joks puslapis.',
+'sharedupload' => 'Šis failas yra įkeltas bendram naudojimui ir gali būti naudojamas kituose projektuose.',
+'shareduploadwiki' => 'Žiūrėkite $1 tolimesnei informacijai.',
+'shareduploadwiki-linktext' => 'failo aprašymo puslapį',
+'noimage' => 'Failas tokiu pavadinimu neegzistuoja. Jūs galite $1',
+'noimage-linktext' => 'įkelti jį',
+'uploadnewversion-linktext' => 'Įkelti naują failo versiją',
+'imagelist_date' => 'Data',
+'imagelist_name' => 'Pavadinimas',
+'imagelist_user' => 'Naudotojas',
+'imagelist_size' => 'Dydis (baitais)',
+'imagelist_description' => 'Aprašymas',
+'imagelist_search_for' => 'Ieškoti paveikslėlio pavadinimo:',
+
+# MIME search
+'mimesearch' => 'MIME paieška',
+'mimetype' => 'MIME tipas:',
+'download' => 'parsisiųsti',
+
+# Unwatched pages
+'unwatchedpages' => 'Nestebimi puslapiai',
+
+# List redirects
+'listredirects' => 'Peradresavimų sąrašas',
+
+# Unused templates
+'unusedtemplates' => 'Nenaudojami šablonai',
+'unusedtemplatestext' => 'Šis puslapis rodo sąrašą puslapių, esančių šablonų vardų srityje, kurie nėra įterpti į jokį kitą puslapį. Nepamirškite patikrinti kitų nuorodų prieš juos ištrinant.',
+'unusedtemplateswlh' => 'kitos nuorodos',
+
+# Random redirect
+'randomredirect' => 'Atsitiktinis peradresavimas',
+
+# Statistics
+'statistics' => 'Statistika',
+'sitestats' => '{{SITENAME}} statistika',
+'userstats' => 'Naudotojų statistika',
+'sitestatstext' => "Šiuo metu duomenų bazėje yra '''$1''' straipsnių.
+Į šį skaičių įeina aptarimų puslapiai, puslapiai apie {{SITENAME}}, peradresavimo puslapiai ir kiti, nelaikomi straipsniais.
+Be šių puslapių, yra '''$2''' {{PLURAL:$2|tikras straipsnis|tikri straipsniai|tikrų straipsnių}}.
+
+Buvo įkelti '''$8''' failai.
+
+Nuo projekto pradžios buvo parodyti '''$3''' puslapiai, ir buvo atlikta '''$4''' puslapių keitimų.
+Vidutiniškai kiekvienas puslapis keistas '''$5''' kartų, ir '''$6''' parodymai per redagavimą.
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue Užduočių eilės] ilgis yra '''$7'''.",
+'userstatstext' => "Šiuo metu yra '''$1''' {{plural:$1|registruotas naudotojas|registruoti naudotojai|registruotų naudotojų}}, iš jų
+'''$2''' (arba '''$4%''') yra $5.",
+'statistics-mostpopular' => 'Daugiausiai rodyti puslapiai',
+
+'disambiguations' => 'Daugiaprasmių žodžių puslapiai',
+'disambiguationspage' => '{{ns:template}}:Daugiareikšmis',
+'disambiguationstext' => 'Žemiau išvardinti puslapiai, rodantys į <i>daugiaprasmių žodžių puslapius</i>. Nuorodos turėtų būti patikslintos, kad rodytų į konkretų straipsnį.<br />Puslapis laikomas daugiaprasmiu, jei nuoroda į jį yra iš $1.<br />Nuorodos iš kitų vardų sričių čia <i>nėra</i> įtrauktos.',
+
+'doubleredirects' => 'Dvigubi peradresavimai',
+'doubleredirectstext' => 'Kiekvienoje eilutėje išvardintas pirmasis ir antrasis peradresavimai, taip pat pirma antrojo peradresavimo eilutė, paprastai rodanti į "teisingą" puslapį, į kurį turi būti rodoma.',
+
+'brokenredirects' => 'Peradresavimai į niekur',
+'brokenredirectstext' => 'Žemiau išvardinti peradresavimo puslapiai rodo į neegzistuojančius puslapius:',
+
+# Miscellaneous special pages
+'nbytes' => '$1 {{PLURAL:$1|baitas|baitai|baitų}}',
+'ncategories' => '$1 {{PLURAL:$1|kategorija|kategorijos|kategorijų}}',
+'nlinks' => '$1 {{PLURAL:$1|nuoroda|nuorodos|nuorodų}}',
+'nmembers' => '$1 {{PLURAL:$1|narys|nariai|narių}}',
+'nrevisions' => '$1 {{PLURAL:$1|keitimas|keitimai|keitimų}}',
+'nviews' => '$1 {{PLURAL:$1|parodymas|parodymai|parodymų}}',
+'lonelypages' => 'Vieniši straipsniai',
+'lonelypagestext' => 'Į šiuos puslapius nėra nuorodų iš kitų šio projekto puslapių.',
+'uncategorizedpages' => 'Puslapiai, nepriskirti jokiai kategorijai',
+'uncategorizedcategories' => 'Kategorijos, nepriskirtos jokiai kategorijai',
+'uncategorizedimages' => 'Paveikslėliai, nepriskirti jokiai kategorijai',
+'unusedcategories' => 'Nenaudojamos kategorijos',
+'unusedimages' => 'Nenaudojami failai',
+'popularpages' => 'Populiarūs puslapiai',
+'wantedcategories' => 'Geidžiamiausios kategorijos',
+'wantedpages' => 'Geidžiamiausi puslapiai',
+'mostlinked' => 'Daugiausiai nurodomi straipsniai',
+'mostlinkedcategories' => 'Daugiausiai nurodomos kategorijos',
+'mostcategories' => 'Straipsniai su daugiausia kategorijų',
+'mostimages' => 'Daugiausiai nurodomi paveikslėliai',
+'mostrevisions' => 'Straipsniai su daugiausia keitimų',
+'allpages' => 'Visi puslapiai',
+'prefixindex' => 'Rodyklė pagal pavadinimo pradžią',
+'randompage' => 'Atsitiktinis puslapis',
+'shortpages' => 'Trumpiausi puslapiai',
+'longpages' => 'Ilgiausi puslapiai',
+'deadendpages' => 'Straipsniai-aklavietės',
+'deadendpagestext' => 'Šie puslapiai neturi nuorodų į kitus puslapius šiame projekte.',
+'listusers' => 'Naudotojų sąrašas',
+'specialpages' => 'Specialieji puslapiai',
+'spheading' => 'Specialieji puslapiai visiems naudotojams',
+'restrictedpheading' => 'Apribotieji specialieji puslapiai',
+'recentchangeslinked' => 'Susiję keitimai',
+'rclsub' => '(puslapių, pasiekiamų iš "$1")',
+'newpages' => 'Naujausi puslapiai',
+'newpages-username' => 'Naudotojo vardas:',
+'ancientpages' => 'Seniausi puslapiai',
+'intl' => 'Tarpkalbinės nuorodos',
+'move' => 'Pervadinti',
+'movethispage' => 'Pervadinti šį puslapį',
+'unusedimagestext' => '<p>Primename, kad kitos svetainės gali būti nurodžiusios į paveikslėlį tiesioginiu URL, bet vistiek gali būti šiame sąraše, nors ir yra aktyviai naudojamas.</p>',
+'unusedcategoriestext' => 'Šie kategorijų puslapiai sukurti, nors joks kitas straipsnis ar kategorija jo nenaudoja.',
+
+# Book sources
+'booksources' => 'Knygų šaltiniai',
+'booksources-search-legend' => 'Knygų šaltinių paieška',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => 'Rodyti',
+'booksources-text' => 'Žemiau yra nuorodų sąrašas į kitas svetaines, kurios parduoda naujas ar naudotas knygas, bei galbūt turinčias daugiau informacijos apie knygas, kurių ieškote:',
+
+'categoriespagetext' => 'Projekte yra šios kategorijos.',
+'data' => 'Duomenys',
+'userrights' => 'Naudotojų teisių valdymas',
+'groups' => 'Naudotojų grupės',
+'isbn' => 'ISBN',
+'alphaindexline' => 'Nuo $1 iki $2',
+'version' => 'Versija',
+'log' => 'Specialiųjų veiksmų istorija',
+'alllogstext' => 'Bendra įdėtų failų, ištrynimų, užrakinimų, blokavimų ir teisių suteikimų istorija.
+Galima sumažinti rezultatų skaičių patikslinant veiksmo rūšį, naudotoją ar susijusį puslapį.',
+'logempty' => 'Istorijoje nėra jokių atitinkančių įvykių.',
+
+# Special:Allpages
+'nextpage' => 'Kitas puslapis ($1)',
+'prevpage' => 'Ankstesnis puslapis ($1)',
+'allpagesfrom' => 'Rodyti puslapius pradedant nuo:',
+'allarticles' => 'Visi straipsniai',
+'allinnamespace' => 'Visi puslapiai ($1 vardų sritis)',
+'allnotinnamespace' => 'Visi puslapiai (nesantys $1 vardų srityje)',
+'allpagesprev' => 'Atgal',
+'allpagesnext' => 'Pirmyn',
+'allpagessubmit' => 'Rodyti',
+'allpagesprefix' => 'Rodyti puslapiu su priedėliu:',
+'allpagesbadtitle' => 'Duotas puslapio pavadinimas yra neteisingas arba turi tarpkalbininį arba tarpprojektinį priedėlį. Jame yra vienas ar keli simboliai, kurių negalima naudoti pavadinimuose.',
+
+# Special:Listusers
+'listusersfrom' => 'Rodyti naudotojus pradedant nuo:',
+
+# E-mail user
+'mailnologin' => 'Nėra adreso',
+'mailnologintext' => 'Jums reikia būti [[{{ns:special}}:Userlogin|prisijungusiam]]
+ir turi būti įvestas teisingas el. pašto adresas jūsų [[{{ns:special}}:Preferences|nustatymuose]],
+kad siųstumėte el. laiškus kitiems nautotojams.',
+'emailuser' => 'Rašyti laišką šiam naudotojui',
+'emailpage' => 'Siųsti el. laišką naudotojui',
+'emailpagetext' => 'Jei šis naudotojas yra įvedęs teisingą el. pašto adresą
+savo nustatymuose, ši forma nusiųs vieną laišką.
+El. pašto adresas, nurodytas jūsų nustatymuose, bus rodomas
+kaip laiško adresas "Nuo", kad gavėjas galėtų jums atsakyti.',
+'usermailererror' => 'Pašto objektas grąžino klaidą::',
+'defemailsubject' => '{{SITENAME}} el. paštas',
+'noemailtitle' => 'Nėra el. pašto adreso',
+'noemailtext' => 'Šis naudotojas yra nenurodęs teisingo el. pašto adreso, arba yra pasirinkęs negauti el. pašto iš kitų naudotojų.',
+'emailfrom' => 'Nuo',
+'emailto' => 'Kam',
+'emailsubject' => 'Tema',
+'emailmessage' => 'Tekstas',
+'emailsend' => 'Siųsti',
+'emailccme' => 'Siųsti man mano laiško kopiją.',
+'emailccsubject' => 'Laiško kopija naudotojui $1: $2',
+'emailsent' => 'El. laiškas išsiųstas',
+'emailsenttext' => 'Jūsų el. pašto žinutė išsiųsta.',
+
+# Watchlist
+'watchlist' => 'Stebimi straipsniai',
+'watchlistfor' => "(naudotojo '''$1''')",
+'nowatchlist' => 'Neturite nei vieno stebimo puslapio.',
+'watchlistanontext' => 'Prašome $1, kad peržiūrėtumėte ar pakeistumėte elementus savo stebimųjų sąraše.',
+'watchlistcount' => "'''Jūs turite $1 {{PLURAL:$1|elementą|elementus|elementų}} stebimųjų sąraše įskaitant aptarimo puslapius.'''",
+'clearwatchlist' => 'Išvalyti stebimų sąrašą',
+'watchlistcleartext' => 'Ar tikrai norite juos pašalinti?',
+'watchlistclearbutton' => 'Išvalyti stebimų sąrašą',
+'watchlistcleardone' => 'Jūsų stebimųjų sąrašas išvalytas. Pašalinta $1 {{PLURAL:$1|elementas|elementai|elementų}}.',
+'watchnologin' => 'Neprisijungęs',
+'watchnologintext' => 'Jums reikia būti [[{{ns:special}}:Userlogin|prisijungusiam]], kad pakeistumėte savo stebimųjų sąrašą.',
+'addedwatch' => 'Pridėta prie Stebimų',
+'addedwatchtext' => 'Puslapis "[[:$1]]" pridėtas į [[{{ns:special}}:Watchlist|stebimųjų sąrašą]].
+Būsimi puslapio bei atitinkamo aptarimo puslapio pakeitimai bus rodomi stebimųjų puslapių sąraše,
+taip pat bus \'\'\'paryškinti\'\'\' [[{{ns:special}}:Recentchanges|naujausių keitimų sąraše]], kad išsiskirtų iš kitų straipsnių.
+
+Jei vėliau užsinorėtumėte nustoti stebėti straipsnį, spustelkite "Nebestebėti" viršutiniame meniu.',
+'removedwatch' => 'Pašalinta iš stebimų',
+'removedwatchtext' => 'Puslapis "[[:$1]]" pašalintas iš jūsų stebimų sąrašo.',
+'watch' => 'Stebėti',
+'watchthispage' => 'Stebėti šį puslapį',
+'unwatch' => 'Nebestebėti',
+'unwatchthispage' => 'Nustoti stebėti',
+'notanarticle' => 'Ne turinio puslapis',
+'watchnochange' => 'Pasirinktu laikotarpiu nebuvo redaguotas nei vienas stebimas straipsnis.',
+'watchdetails' => '* Stebima $1 {{plural:$1|puslapis|puslapiai|puslapių}} neskaičiuojant aptarimų puslapių
+* [[{{ns:special}}:Watchlist/edit|Parodyti ir redaguoti pilną sąrašą]]
+* [[{{ns:special}}:Watchlist/clear|Pašalinti visus puslapius]]',
+'wlheader-enotif' => '* El. pašto priminimai yra įjungti.',
+'wlheader-showupdated' => "* Puslapiai pakeisti nuo tada, kai paskutinį kartą apsilankėte juose, yra pažymėti '''pastorintai'''",
+'watchmethod-recent' => 'tikrinami paskutiniai keitimai stebimiems puslapiams',
+'watchmethod-list' => 'ieškoma naujausių keitimų stebimuose puslapiuose',
+'removechecked' => 'Išmesti pažymėtus elementus iš stebimų sąrašo',
+'watchlistcontains' => 'Puslapių jūsų stebimųjų sąraše - $1.',
+'watcheditlist' => 'Tai abėcėlės tvarka surikiuotas stebimų puslapių sąraše. Pažymėkite puslapius, kuriuos norite pašalinti iš jūsų stebimųjų sąrašo ir paspauskite žemiau
+esantį mygtuką "Išmesti pažymėtus" (pašalinus turinio puslapį bus pašalintas ir susijęs aptarimo puslapis ir atvirkščiai).',
+'removingchecked' => 'Pasirinkti elementai išmetami iš stebimų sąrašo...',
+'couldntremove' => "Nepavyko pašalinti '$1'...",
+'iteminvalidname' => "Problema su elementu '$1', neteisingas vardas...",
+'wlnote' => 'Rodomi paskutiniai $1 pakeitimai, padaryti per paskutines <b>$2</b> valandas.',
+'wlshowlast' => 'Rodyti paskutinių $1 valandų, $2 dienų ar $3 pakeitimus',
+'wlsaved' => 'Tai išsaugota jūsų stebimųjų sąrašo versija.',
+'watchlist-show-bots' => 'Rodyti robotų keitimus',
+'watchlist-hide-bots' => 'Slėpti robotų keitimus',
+'watchlist-show-own' => 'Rodyti mano keitimus',
+'watchlist-hide-own' => 'Slėpti mano keitimus',
+'watchlist-show-minor' => 'Rodyti smulkius keitimus',
+'watchlist-hide-minor' => 'Slėpti smulkius keitimus',
+'wldone' => 'Atlikta.',
+
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => 'Įtraukiama į stebimųjų sąrašą...',
+'unwatching' => 'Šalinama iš stebimųjų sąrašo...',
+
+'enotif_mailer' => '{{SITENAME}} Pranešimų sistema',
+'enotif_reset' => 'Pažymėti visus puslapius kaip aplankytus',
+'enotif_newpagetext' => 'Tai naujas puslapis.',
+'changed' => 'pakeitė',
+'created' => 'sukurė',
+'enotif_subject' => 'Projekte {{SITENAME}} naudotojas $PAGEEDITOR $CHANGEDORCREATED $PAGETITLE',
+'enotif_lastvisited' => 'Užeikite į $1, jei norite matyti pakeitimus nuo paskutiniojo apsilankymo.',
+'enotif_body' => '$WATCHINGUSERNAME,
+
+$PAGEEDITDATE projekte {{SITENAME}} naudotojas $PAGEEDITOR $CHANGEDORCREATED puslapį $PAGETITLE, dabartinę versiją rasite adresu $PAGETITLE_URL.
+
+$NEWPAGE
+
+Redaguotojo komentaras: $PAGESUMMARY $PAGEMINOREDIT
+
+Susisiekti su redaguotoju:
+el. paštu: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Daugiau pranešimų apie vėlesnius pakeitimus nebus siunčiama, jei neapsilankysite puslapyje. Jūs taip pat galite išjungti pranešimo žymę visiems jūsų stebimiems puslapiams savo stebimųjų sąraše.
+
+ Jūsų draugiškoji projekto {{SITENAME}} pranešimų sistema
+
+--
+Norėdami pakeisti stebimų puslapių nustatymus, užeikite į
+{{fullurl:{{ns:special}}:Watchlist}}
+
+Atsiliepimai ir pagalba:
+{{fullurl:{{ns:help}}:Turinys}}',
+
+# Delete/protect/revert
+'deletepage' => 'Trinti puslapį',
+'confirm' => 'Tvirtinu',
+'excontent' => 'buvęs turinys: "$1"',
+'excontentauthor' => "buvęs turinys: '$1' (redagavo tik '[[{{ns:special}}:Contributions/$2|$2]]')",
+'exbeforeblank' => 'prieš ištrinant turinys buvo: "$1"',
+'exblank' => 'puslapis buvo tuščias',
+'confirmdelete' => 'Trynimo patvirtinimas',
+'deletesub' => '(Trinama "$1")',
+'historywarning' => 'Dėmesio: Trinamas puslapis turi istoriją:',
+'confirmdeletetext' => 'Jūs pasirinkote ištrinti puslapį ar paveikslėlį
+kartu su visa jo istorija iš duomenų bazės.
+Prašome patvirtinti, kad jūs norite tai padaryti,
+žinote apie galimas pasėkmes, ir kad jūs tai darote nenusižengdamas
+[[{{ns:project}}:Politika|projekto {{SITENAME}} politikai]].',
+'actioncomplete' => 'Veiksmas atliktas',
+'deletedtext' => '"$1" ištrintas.
+Paskutinių šalinimų sąrašas - $2.',
+'deletedarticle' => 'ištrynė "$1"',
+'dellogpage' => 'Šalinimų sąrašas',
+'dellogpagetext' => 'Žemiau pateikiamas sąrašas paskutinių trynimų sąrašas.',
+'deletionlog' => 'šalinimų sąrašas',
+'reverted' => 'Atkurta į ankstesnę versiją',
+'deletecomment' => 'Trynimo priežastis',
+'imagereverted' => 'Atstatymas į ankstesnę versiją pavyko.',
+'rollback' => 'Atmesti keitimus',
+'rollback_short' => 'Atmesti',
+'rollbacklink' => 'atmesti',
+'rollbackfailed' => 'Atmetimas nepavyko',
+'cantrollback' => 'Negalima atmesti redagavimo; paskutinis keitęs naudotojas yra šio puslapio autorius.',
+'alreadyrolled' => 'Nepavyko atmesti paskutinio [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|Aptarimas]]) daryto straipsnio [[:$1]] keitimo; kažkas jau pakeitė straipsnį arba suspėjo pirmas atmesti keitimą.
+
+Paskutimas keitimas darytas naudotojo [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|Aptarimas]]).',
+'editcomment' => 'Redagavimo komentaras: "<i>$1</i>".', # only shown if there is an edit comment
+'revertpage' => 'Atmestas [[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|Aptarimas]]) pakeitimas; sugrąžinta naudotojo [[{{ns:user}}:$1|$1]] versija',
+'sessionfailure' => 'Atrodo yra problemų su jūsų prisijungimo sesija; šis veiksmas buvo atšauktas kaip atsargumo priemonė prieš sesijos vogimą.
+Prašome paspausti "atgal" ir perkraukite puslapį iš kurio atėjote, ir pamėginkite vėl.',
+'protectlogpage' => 'Rakinimų sąrašas',
+'protectlogtext' => 'Žemiau yra puslapių užrakinimų bei atrakinimų sąrašas.',
+'protectedarticle' => 'užrakino "[[$1]]"',
+'unprotectedarticle' => 'atrakino "[[$1]]"',
+'protectsub' => '(Rakinamas "$1")',
+'confirmprotecttext' => 'Ar jūs tikrai norite užrakinti šį straipsnį?',
+'confirmprotect' => 'Užrakinimo patvirtinimas',
+'protectmoveonly' => 'Uždrausti tik perkėlimus',
+'protectcomment' => 'Rakinimo priežastis',
+'unprotectsub' => '(Atrakinamas "$1")',
+'confirmunprotecttext' => 'Ar tikrai norite atrakinti šį straipsnį?',
+'confirmunprotect' => 'Atrakinimo patvirtinimas',
+'unprotectcomment' => 'Atrakinimo priežastis',
+'protect-unchain' => 'Atrakinti pervardinimo teises',
+'protect-text' => 'Čia jūs gali matyti ir keisti apsaugos lygį puslapiui <strong>$1</strong>.',
+'protect-viewtext' => 'Jūsų paskyra neturi teisių keisti puslapių apsaugos lygius. Čia yra dabartiniai nustatymai puslapiui <strong>$1</strong>:',
+'protect-default' => '(pagal nutylėjimą)',
+'protect-level-autoconfirmed' => 'Blokuoti neregistruotus naudotojus',
+'protect-level-sysop' => 'Tik administratoriai',
+
+# Restrictions (nouns)
+'restriction-edit' => 'Redagavimas',
+'restriction-move' => 'Pervardinimas',
+
+# Undelete
+'undelete' => 'Atstatyti ištrintą puslapį',
+'undeletepage' => 'Rodyti ir atkurti ištrintus puslapius',
+'viewdeletedpage' => 'Rodyti ištrintus puslapius',
+'undeletepagetext' => 'Žemiau išvardinti puslapiai yra ištrinti, bet dar laikomi
+archyve, todėl jie gali būti atstatyti. Archyvas gali būti periodiškai valomas.',
+'undeleteextrahelp' => "Norėdami atkurti visą puslapį, palikite visas varneles nepažymėtas ir
+spauskite '''''Atstatyti'''''. Norėdami atlikti pasirinktinį atstatymą, pažymėkite varneles tų versijų, kurias norėtumėte atstatyti, ir spauskite '''''Atstatyti'''''. Paspaudus
+'''''Iš naujo''''' bus išvalytos visos varnelės bei komentaro laukas.",
+'undeletearticle' => 'Atstatyti ištrintą puslapį',
+'undeleterevisions' => '$1 versijos suarchyvuotos',
+'undeletehistory' => 'Jei atstatysite straipsnį, istorijoje bus atstatytos visos versijos.
+Jei po ištrynimo buvo sukurtas straipsnis tokiu pačiu pavadinimu,
+atstatytos versijos atsiras ankstesnėje istorijoje, o dabartinė
+versija liks nepakeista.',
+'undeletehistorynoadmin' => 'Šis straipsnis buvo ištrintas. Trynimo priežastis yra
+rodoma žemiau, taip pat kas redagavo puslapį
+iki trynimo. Ištrintų puslapių tekstas yra galimas tik administratoriams.',
+'undeleterevision' => 'Ištrinta $1 dienos versija',
+'undeleterevision-missing' => 'Neteisinga arba dingusi versija. Jūs turbūt turite blogą nuorodą, arba versija buvo atkurta arba pašalinta iš archyvo.',
+'undeletebtn' => 'Atstatyti',
+'undeletereset' => 'Iš naujo',
+'undeletecomment' => 'Komentaras:',
+'undeletedarticle' => 'atstatyta "[[$1]]"',
+'undeletedrevisions' => 'atstatyta $1 revizijų',
+'undeletedrevisions-files' => 'atkurtos $1 versijos ir $2 failai',
+'undeletedfiles' => '$1 failai atkurti',
+'cannotundelete' => 'Atkūrimas nepavyko; kažkas kitas pirmas galėjo atkurti puslapį.',
+'undeletedpage' => "<big>'''$1 buvo atkurtas'''</big>
+
+Peržiūrėkite [[{{ns:special}}:Log/delete|trynimų sąrašą]], norėdami rasti paskutinių trynimų ir atkūrimų sąrašą.",
+
+# Namespace form on various pages
+'namespace' => 'Vardų sritis:',
+'invert' => 'Žymėti priešingai',
+
+# Contributions
+'contributions' => 'Naudotojo įnašas',
+'mycontris' => 'Mano įnašas',
+'contribsub' => 'Naudotojo $1',
+'nocontribs' => 'Jokie keitimai neatitiko šių kriterijų.',
+'ucnote' => 'Žemiau yra šio naudotojo paskutiniai <b>$1</b> keitimai per pastarąsias <b>$2</b> dienas.',
+'uclinks' => 'Rodyti paskutinius $1 pakeitimus; rodyti paskutines $2 dienas.',
+'uctop' => ' (paskutinis)',
+'newbies' => 'naujokai',
+
+'sp-newimages-showfrom' => 'Rodyti naujus paveiklėlius pradedant nuo $1',
+
+'sp-contributions-newest' => 'Naujausi',
+'sp-contributions-oldest' => 'Seniausi',
+'sp-contributions-newer' => '$1 naujesnių',
+'sp-contributions-older' => '$1 senesnių',
+'sp-contributions-newbies-sub' => 'Naujokams',
+
+# What links here
+'whatlinkshere' => 'Susiję puslapiai',
+'notargettitle' => 'Nenurodytas objektas',
+'notargettext' => 'Jūs nenurodėte norimo puslapio ar naudotojo,
+kuriam įvykdyti šią funkciją.',
+'linklistsub' => '(Nuorodų sąrašas)',
+'linkshere' => "Šie puslapiai rodo į '''[[:$1]]''':",
+'nolinkshere' => "Į '''[[:$1]]''' nuorodų nėra.",
+'isredirect' => 'nukreipiamasis puslapis',
+'istemplate' => 'įterpimas',
+
+# Block/unblock
+'blockip' => 'Blokuoti naudotoją',
+'blockiptext' => 'Naudokite šią formą norėdami uždrausti rašymo teises nurodytui IP adresi ar naudotojui. Tai turėtų būti atliekama tiktai tam, kad sustabdytumėte vandalizmą, ir pagal [[{{ns:project}}:Politika|politiką]].
+Žemiau nurodykite tikslią priežastį (pavyzdžiui, nurodydami sugadintus puslapius).',
+'ipaddress' => 'IP adresas',
+'ipadressorusername' => 'IP adresas arba naudotojo vardas',
+'ipbexpiry' => 'Galiojimo laikas',
+'ipbreason' => 'Priežastis',
+'ipbanononly' => 'Blokuoti tik anoniminius naudotojus',
+'ipbcreateaccount' => 'Neleisti kurti paskyrų',
+'ipbenableautoblock' => 'Automatiškai blokuoti šio naudotojo paskiausiai naudotą IP adresą, bei bet kokius vėlesnius adresus, iš kurių jie mėgina redaguoti',
+'ipbsubmit' => 'Blokuoti šį naudotoją',
+'ipbother' => 'Kitoks laikas',
+'ipboptions' => '2 valandos:2 hours,1 diena:1 day,3 dienos:3 days,1 savaite:1 week,2 savaitės:2 weeks,1 mėnesis:1 month,3 mėnesiai:3 months,6 mėnesiai:6 months,1 metai:1 year,neribotai:infinite',
+'ipbotheroption' => 'kita',
+'badipaddress' => 'Neleistinas IP adresas',
+'blockipsuccesssub' => 'Užblokavimas pavyko',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|$1]] buvo užblokuotas.
+<br />Aplankykite [[{{ns:special}}:Ipblocklist|IP blokavimų sąrašą]] norėdami jį peržiūrėti.',
+'unblockip' => 'Atblokuoti naudotoją',
+'unblockiptext' => 'Naudokite šią formą, kad atkurtumėte rašymo teises
+ankščiau užblokuotam IP adresui ar naudotojui.',
+'ipusubmit' => 'Atblokuoti šį adresą',
+'unblocked' => '[[{{ns:user}}:$1|$1]] buvo atblokuotas',
+'ipblocklist' => 'Blokuotų IP adresų bei naudotojų sąrašas',
+'blocklistline' => '$1, $2 blokavo $3 ($4)',
+'infiniteblock' => 'neribotai',
+'expiringblock' => 'baigia galioti $1',
+'anononlyblock' => 'tik anonimai',
+'noautoblockblock' => 'automatinis blokavimas išjungtas',
+'createaccountblock' => 'paskyrų kūrimas uždraustas',
+'ipblocklistempty' => 'Užblokuotųjų sąrašas tuščias.',
+'blocklink' => 'blokuoti',
+'unblocklink' => 'atblokuoti',
+'contribslink' => 'įnašas',
+'autoblocker' => 'Jūs buvote automatiškai užblokuotas, nes jūsų IP neseniai naudojo "[[{{ns:user}}:$1|$1]]". Duota priežastis naudotojo $1 užblokavimui: "\'\'\'$2\'\'\'".',
+'blocklogpage' => 'Blokavimų sąrašas',
+'blocklogentry' => 'blokavo "[[$1]]", blokavimo laikas - $2',
+'blocklogtext' => 'Čia yra naudotojų blokavimo ir atblokavimo sąrašas. Automatiškai blokuoti IP adresai nėra išvardinti. Jei norite pamatyti dabar blokuojamus adresus, žiūrėkite [[{{ns:special}}:Ipblocklist|IP blokavimų sąrašą]].',
+'unblocklogentry' => 'atblokavo $1',
+'range_block_disabled' => 'Administratoriaus galimybė kurti intevalinius blokus yra išjungta.',
+'ipb_expiry_invalid' => 'Galiojimo laikas neleistinas.',
+'ipb_already_blocked' => '"$1" jau užblokuotas',
+'ip_range_invalid' => 'Neleistina IP sritis.',
+'proxyblocker' => 'Tarpinių serverių blokuotojas',
+'ipb_cant_unblock' => 'Klaida: Blokavimo ID $1 nerastas. Galbūt jis jau atblokuotas.',
+'proxyblockreason' => 'Jūsų IP adresas yra užblokuotas, nes jis yra atvirasis tarpinis serveris. Prašome susisiekti su savo interneto paslaugų tiekėju ar technine pagalba ir praneškite jiems apie šią svarbią saugumo problemą.',
+'proxyblocksuccess' => 'Atlikta.',
+'sorbs' => 'DNSBL',
+'sorbsreason' => 'Jūsų IP adresas yra įtrauktas į atvirųjų tarpinių serverių DNSBL sąrašą, naudojamą šios svetainės.',
+'sorbs_create_account_reason' => 'Jūsų IP adresas yra įtrauktas į atvirųjų tarpinių serverių DNSBL sąrašą, naudojamą šios svetainės. Jūs negalite sukurti paskyros',
+
+# Developer tools
+'lockdb' => 'Užrakinti duomenų bazę',
+'unlockdb' => 'Atrakinti duomenų bazę',
+'lockdbtext' => 'Užrakinus duomenų bazę sustabdys galimybę visiems
+naudotojams redaguoti puslapius, keisti jų nustatymus, keisti jų stebimųjų sąrašą bei
+kitus dalykus, reikalaujančius pakeitimų duomenų bazėje.
+Prašome patvirtinti, kad tai, ką ketinate padaryti, ir kad jūs
+atrakinsite duomenų bazę, kai techninė profilaktika bus baigta.',
+'unlockdbtext' => 'Atrakinus duomenų bazę grąžins galimybę visiems
+naudotojams redaguoti puslapius, keisti jų nustatymus, keisti jų stebimųjų sąrašą bei
+kitus dalykus, reikalaujančius pakeitimų duomenų bazėje.
+Prašome patvirtinti tai, ką ketinate padaryti.',
+'lockconfirm' => 'Taip, aš tikrai noriu užrakinti duomenų bazę.',
+'unlockconfirm' => 'Taip, aš tikrai noriu atrakinti duomenų bazę.',
+'lockbtn' => 'Užrakinti duomenų bazę',
+'unlockbtn' => 'Atrakinti duomenų bazę',
+'locknoconfirm' => 'Jūs neuždėjote patvirtinimo varnelės.',
+'lockdbsuccesssub' => 'Duomenų bazės užrakinimas pavyko',
+'unlockdbsuccesssub' => 'Duomenų bazės užrakinimas pašalintas',
+'lockdbsuccesstext' => 'Duomenų bazė buvo užrakinta.
+<br />Nepamirškite [[Special:Unlockdb|pašalinti užraktą]], kai techninė profilaktika bus baigta.',
+'unlockdbsuccesstext' => 'Duomenų bazė buvo atrakinta.',
+'lockfilenotwritable' => 'Duomenų bazės užrakto failas nėra įrašomas. Norint užrakinti ar atrakinti duomenų bazę, tinklapio serveris privalo turėti įrašymo teises šiam failui.',
+'databasenotlocked' => 'Duomenų bazė neužrakinta.',
+
+# Make sysop
+'makesysoptitle' => 'Padaryti naudotoją administratoriumi',
+'makesysoptext' => 'Ši forma yra naudojama biurokratų, kad paprastus naudotojus pavestų į administratorius.
+Įveskite naudotojo vardą ir paspauskite mygtuką, kad padarytumėte naudotoją administratoriumi',
+'makesysopname' => 'Naudotojo vardas:',
+'makesysopsubmit' => 'Padaryti šį naudotoją administratoriumi',
+'makesysopok' => '<b>Naudotojas "$1" dabar yra administratorius</b>',
+'makesysopfail' => '<b>Naudotojo "$1" nepavyko padaryti administratoriumi. (Ar teisingai įvedėte vardą?)</b>',
+'setbureaucratflag' => 'Nustatatyti biurokrato žymę',
+'rightslog' => 'Naudotojų teisių istorija',
+'rightslogtext' => 'Pateikiamas naudotojų teisių pasikeitimų sąrašas.',
+'rightslogentry' => 'pakeista $1 grupės narystė iš $2 į $3',
+'rights' => 'Teisės:',
+'set_user_rights' => 'Nustatyti naudotojo teises',
+'user_rights_set' => '<b>"$1" naudotojo teisės atnaujintos</b>',
+'set_rights_fail' => '<b>"$1" naudotojo teisės negali būti nustatytos. (Ar teisingai įvedėte vardą?)</b>',
+'makesysop' => 'Padaryti naudotoją administratoriumi',
+'already_sysop' => 'Naudotojas jau yra administratorius',
+'already_bureaucrat' => 'Naudotojas jau yra biurokratas',
+'rightsnone' => '(jokių)',
+
+# Move page
+'movepage' => 'Puslapio pervadinimas',
+'movepagetext' => "Naudodamiesi žemiau pateikta forma, pervadinsite puslapį
+neprarasdami jo istorijos.
+Senasis pavadinimas taps nukreipiamuoju - rodys į naująjį.
+Nuorodos į senąjį puslapį nebus automatiškai pakeistos, todėl būtinai
+patikrinkite ar nesukūrėte dvigubų ar
+neveikiančių nukreipimų.
+Jūs esate atsakingas už tai, kad nuorodos rodytų į ten, kur ir norėta.
+
+Primename, kad puslapis '''nebus''' pervadintas, jei jau yra puslapis
+nauju pavadinimu, nebent tas puslapis tuščias arba nukreipiamasis ir
+neturi redagavimo istorijos. Taigi, jūs galite pervadinti puslapį
+seniau naudotu vardu, jei prieš tai jis buvo per klaidą pervadintas,
+o egzistuojančių puslapių sugadinti negalite.
+
+<b>DĖMESIO!</b>
+Jei pervadinate populiarų puslapį, tai gali sukelti nepageidaujamų
+šalutinių efektų, dėl to šį veiksmą vykdykite tik įsitikinę,
+kad suprantate visas pasekmes.",
+'movepagetalktext' => "Susietas aptarimo puslapis bus automatiškai perkeltas kartu su juo, '''išskyrus:''':
+*Puslapis nauju pavadinimu jau turi netuščią aptarimo puslapį, arba
+*Paliksite žemiau esančia varnelę nepažymėtą.
+
+Šiais atvejais jūs savo nuožiūra turite perkelti arba apjungti aptarimo puslapį.",
+'movearticle' => 'Puslapio pervadinimas',
+'movenologin' => 'Neprisijungęs',
+'movenologintext' => 'Norėdami pervadinti puslapį, turite būti užsiregistravęs naudotojas ir būti [[{{ns:special}}:Userlogin|prisijungęs]].',
+'newtitle' => 'Naujas pavadinimas',
+'movepagebtn' => 'Pervadinti puslapį',
+'pagemovedsub' => 'Pervadinta sėkmingai',
+'pagemovedtext' => 'Puslapis "[[$1]]" pervadintas į "[[$2]]".',
+'articleexists' => 'Puslapis tokiu pavadinimu jau egzistuoja
+arba pasirinktas vardas yra neteisingas.
+Pasirinkite kitą pavadinimą.',
+'talkexists' => "'''Pats puslapis buvo sėkmingai pervadintas, bet aptarimų puslapis nebuvo perkeltas, kadangi naujo
+pavadinimo straipsnis jau turėjo aptarimų puslapį.
+Prašome sujungti šiuos puslapius.'''",
+'movedto' => 'pervardintas į',
+'movetalk' => 'Perkelti susijusį aptarimo puslapį.',
+'talkpagemoved' => 'Susietas aptarimo puslapis buvo taip pat perkeltas.',
+'talkpagenotmoved' => 'Susietas aptarimo puslapis <strong>nebuvo</strong> perkeltas.',
+'1movedto2' => '[[$1]] pervadintas į [[$2]]',
+'1movedto2_redir' => '[[$1]] pervadintas į [[$2]] (anksčiau buvo nukreipiamasis)',
+'movelogpage' => 'Perkėlimų sąrašas',
+'movelogpagetext' => 'Perkeltų puslapių sąrašas.',
+'movereason' => 'Priežastis',
+'revertmove' => 'atkurti',
+'delete_and_move' => 'Ištrinti ir perkelti',
+'delete_and_move_text' => '==Reikalingas ištrynimas==
+
+Paskirties straipsnis "[[$1]]" jau yra. Ar norite jį ištrinti, kad galėtumėte pervardinti?',
+'delete_and_move_confirm' => 'Taip, trinti puslapį',
+'delete_and_move_reason' => 'Ištrinta dėl perkėlimo',
+'selfmove' => 'Šaltinio ir paskirties pavadinimai yra tokie patys; negalima pervardinti puslapio į save.',
+'immobile_namespace' => 'Šaltinio arba paskirties pavadinimas yra specialiojo tipo; negalima pervadinti iš ir į tą vardų sritį.',
+
+# Export
+'export' => 'Eksportuoti puslapius',
+'exporttext' => 'Galite eksportuoti vieno puslapio tekstą ir istoriją ar kelių puslapių vienu metu
+tame pačiame XML atsakyme. Šie puslapiai galės būti importuojami į kitą
+projektą, veikiantį MediaWiki pagrindu, per {{ns:special}}:Import puslapį.
+
+Norėdami eksportuoti puslapius, įveskite pavadinimus žemiau esančiame tekstiniame lauke
+po vieną pavadinimą eilutėje, taip pat pasirinkite ar norite eksportuoti ir istoriją
+ar tik dabartinę versiją su paskutinio redagavimo informacija.
+
+Pastaruoju atveju, jūs taip pat galite naudoti nuorodą, pvz. [[{{ns:Special}}:Export/{{int:mainpage}}]] straipsniui [[{{int:mainpage}}]].',
+'exportcuronly' => 'Eksportuoti tik dabartinę versiją, neįtraukiant istorijos',
+'exportnohistory' => "----
+'''Pastaba:''' Pilnos puslapių istorijos eksportavimas naudojantis šia forma yra išjungtas dėl spartos.",
+'export-submit' => 'Ekportuoti',
+
+# Namespace 8 related
+'allmessages' => 'Sistemos pranešimų sąrašas',
+'allmessagesname' => 'Pavadinimas',
+'allmessagesdefault' => 'Pradinis tekstas',
+'allmessagescurrent' => 'Dabartinis tekstas',
+'allmessagestext' => 'Čia pateikiamas sisteminių pranešimų sąrašas, esančių MediaWiki vardų srityje.',
+'allmessagesnotsupportedUI' => 'Jūsų pasirinkta kalba <b>$1</b> nėra palaikoma puslapyje {{ns:special}}:Allmessages šioje svetainėje.',
+'allmessagesnotsupportedDB' => '\'\'\'{{ns:special}}:Allmessages\'\'\' nepalaikoma, nes nustatymas \'\'\'$wgUseDatabaseMessages\'\'\' yra išjungtas.',
+'allmessagesfilter' => 'Tekstų pavadinimo filtras:',
+'allmessagesmodified' => 'Rodyti tik pakeistus',
+
+# Thumbnails
+'thumbnail-more' => 'Padidinti',
+'missingimage' => '<b>Trūkstamas paveikslėlis</b><br /><i>$1</i>',
+'filemissing' => 'Dingęs failas',
+'thumbnail_error' => 'Klaida kuriant sumažintą paveiklėlį: $1',
+
+# Special:Import
+'import' => 'Importuoti puslapius',
+'importinterwiki' => 'Tarpprojektinis importas',
+'import-interwiki-text' => 'Pasirinkite projektą ir puslapio pavadinimą importavimui.
+Versijų datos ir redaktorių vardai bus išlaikyti.
+Visi tarpprojektiniai importo veiksmai yra registruojami [[Special:Log/import|importo istorijoje]].',
+'import-interwiki-history' => 'Kopijuoti visas istorijos versijas šiam puslapiui',
+'import-interwiki-submit' => 'Importuoti',
+'import-interwiki-namespace' => 'Perkelti puslapius į vardų sritį:',
+'importtext' => 'Prašome eksportuoti failą iš projekto-šaltinio naudojantis {{ns:special}}:Export priemone, išsaugokite jį savo diske ir įkelkite jį čia.',
+'importstart' => 'Imporuojami puslapiai...',
+'import-revision-count' => '$1 {{PLURAL:$1|versija|versijos|versijų}}',
+'importnopages' => 'Nėra puslapių importavimui.',
+'importfailed' => 'Importavimas nepavyko: $1',
+'importunknownsource' => 'Nežinomas importo šaltinio tipas',
+'importcantopen' => 'Nepavyksta atverti importo failo',
+'importbadinterwiki' => 'Bloga tarpprojektinė nuoroda',
+'importnotext' => 'Tuščia arba jokio teksto',
+'importsuccess' => 'Importas pavyko!',
+'importhistoryconflict' => 'Yra konfliktuojanti istorijos versija (galbūt šis puslapis buvo importuotas anksčiau)',
+'importnosources' => 'Nenustatyti transwiki importo šaltiniai, o tiesioginis praeities įkėlimas uždraustas.',
+'importnofile' => 'Nebuvo įkeltas joks importo failas.',
+'importuploaderror' => 'Importo failo įkelimas nepavyko; galbūt failas yra didesnis nei leidžiamas įkėlimo dydis.',
+
+# Import log
+'importlogpage' => 'Importo istorija',
+'importlogpagetext' => 'Administraciniai puslapių importai su keitimų istorija iš kitų wiki projektų.',
+'import-logentry-upload' => 'importuota $1 įkėliant failą',
+'import-logentry-upload-detail' => '$1 {{plural:$1|keitimas|keitimai|keitimų}}',
+'import-logentry-interwiki' => 'tarpprojektinis $1',
+'import-logentry-interwiki-detail' => '$1 {{plural:$1|keitimas|keitimai|keitimų}} iš $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Ieškoti projekte {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Pažymėti keitimą kaip smulkų [alt-i]',
+'tooltip-save' => 'Išsaugoti pakeitimus [alt-s]',
+'tooltip-preview' => 'Pakeitimų peržiūra, prašome pažiūrėti prieš išsaugant! [alt-p]',
+'tooltip-diff' => 'Rodo, kokius pakeitimus padarėte tekste. [alt-v]',
+'tooltip-compareselectedversions' => 'Žiūrėti dviejų pasirinktų puslapio versijų skirtumus. [alt-v]',
+'tooltip-watch' => 'Pridėti šį straipsnį prie stebimų [alt-w]',
+
+# Stylesheets
+'common.css' => '/** Čia įdėtas CSS bus taikomas visoms išvaizdoms */',
+'monobook.css' => '/* Čia įdėtas CSS bus rodomas Monobook išvaizdos naudotojams */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF metaduomenys yra išjungti šiame serveryje.',
+'nocreativecommons' => 'Creative Commons RDF metaduomenys yra išjungti šiame serveryje.',
+'notacceptable' => 'Projekto serveris negali pateikti duomenų formatu, kurį jūsų klientas galėtų skaityti.',
+
+# Attribution
+'anonymous' => 'neregistruotų {{SITENAME}} naudotojų',
+'siteuser' => '{{SITENAME}} naudotojas $1',
+'lastmodifiedatby' => 'Šį puslapį paskutinį kartą redagavo $3 $2, $1.', # $1 date, $2 time, $3 user
+'and' => 'ir',
+'othercontribs' => 'Paremta $1 darbu.',
+'others' => 'kiti',
+'siteusers' => '{{SITENAME}} naudotojas(-ai) $1',
+'creditspage' => 'Puslapio kūrėjai',
+'nocredits' => 'Kūrėjų informacija negalima šiam puslapiui.',
+
+# Spam protection
+'spamprotectiontitle' => 'Priešreklaminis filtras',
+'spamprotectiontext' => 'Puslapis, kurį norėjote išsaugoti buvo užblokuotas priešreklaminio filtro. Tai turbūt sukėlė nuoroda į kitą svetainę.',
+'spamprotectionmatch' => 'Šis tekstas buvo atpažintas priešreklaminio filtro: $1',
+'subcategorycount' => 'Kategorijoje yra $1 {{PLURAL:$1|subkategorija|subkategorijos|subkategorijų}}',
+'categoryarticlecount' => 'Kategorijoje yra $1 {{plural:$1|straipsnis|straipsniai|straipsnių}}',
+'category-media-count' => 'Kategorijoje yra $1 {{PLURAL:$1|failas|failai|failų}}.',
+'listingcontinuesabbrev' => ' tęs.',
+'spambot_username' => 'MediaWiki reklamų šalinimas',
+'spam_reverting' => 'Atkuriama į ankstesnę versiją, neturinčios nuorodų į $1',
+'spam_blanking' => 'Visos versijos turėjo nuorodų į $1, išvaloma',
+
+# Info page
+'infosubtitle' => 'Puslapio informacija',
+'numedits' => 'Keitimų skaičius (straipsnis): $1',
+'numtalkedits' => 'Keitimų skaičius (aptarimo puslapis): $1',
+'numwatchers' => 'Stebinčiųjų skaičius: $1',
+'numauthors' => 'Skirtingų autorių skaičius (straipsnis): $1',
+'numtalkauthors' => 'Skirtingų autorių skaičius (aptarimo puslapis): $1',
+
+# Math options
+'mw_math_png' => 'Visada formuoti PNG',
+'mw_math_simple' => 'HTML paprastais atvejais, kitaip - PNG',
+'mw_math_html' => 'HTML kai įmanoma, kitaip - PNG',
+'mw_math_source' => 'Palikti TeX formatą (tekstinėms naršyklėms)',
+'mw_math_modern' => 'Rekomenduojama modernioms naršyklėms',
+'mw_math_mathml' => 'MathML jei įmanoma (eksperimentinis)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Žymėti, kad patikrinta',
+'markaspatrolledtext' => 'Pažymėti, kad straipsnis patikrintas',
+'markedaspatrolled' => 'Pažymėtas kaip patikrintas',
+'markedaspatrolledtext' => 'Pasirinkta versija sėkmingai pažymėta kaip patikrinta',
+'rcpatroldisabled' => 'Paskutinių keitimų tikrinimas išjungtas',
+'rcpatroldisabledtext' => 'Paskutinių keitimų tikrinimo funkcija šiuo metu išjungta.',
+'markedaspatrollederror' => 'Negalima pažymėti, kad patikrinta',
+'markedaspatrollederrortext' => 'Jums reikia nurodyti versiją, kurią pažymėti kaip patikrintą.',
+'markedaspatrollederror-noautopatrol' => 'Jums neleidžiama pažymėti savo paties keitimų kaip patikrintų.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* patarimai ir spartieji klavišai */
+var ta = new Object();
+ta['pt-userpage'] = new Array('.','Mano naudotojo puslapis');
+ta['pt-anonuserpage'] = new Array('.','Naudotojo puslapis jūsų IP adresui');
+ta['pt-mytalk'] = new Array('n','Mano aptarimo puslapis');
+ta['pt-anontalk'] = new Array('n','Pakeitimų aptarimas, darytus naudojant šį IP adresą');
+ta['pt-preferences'] = new Array('','Mano nustatymai');
+ta['pt-watchlist'] = new Array('l','Puslapių sąrašas, kuriuos jūs pasirinkote stebėti.');
+ta['pt-mycontris'] = new Array('y','Mano darytų keitimų sąrašas');
+ta['pt-login'] = new Array('o','Rekomenduojame prisijungti, nors tai nėra privaloma.');
+ta['pt-anonlogin'] = new Array('o','Rekomenduojame prisijungti, nors tai nėra privaloma.');
+ta['pt-logout'] = new Array('','Atsijungti');
+ta['ca-talk'] = new Array('t','Puslapio turinio aptarimas');
+ta['ca-edit'] = new Array('e','Jūs galite redaguoti šį puslapį. Nepamirškite paspausti peržiūros mygtuka prieš išsaugodami.');
+ta['ca-addsection'] = new Array('+','Pridėti komentarą į aptarimą.');
+ta['ca-viewsource'] = new Array('e','Puslapis yra užrakintas. Galite pažiūrėti turinį.');
+ta['ca-history'] = new Array('h','Ankstesnės puslapio versijos.');
+ta['ca-protect'] = new Array('=','Užrakinti šį puslapį');
+ta['ca-delete'] = new Array('d','Ištrinti šį puslapį');
+ta['ca-undelete'] = new Array('d','Atkurti puslapį su visais darytais keitimais');
+ta['ca-move'] = new Array('m','Pervadinti puslapį');
+ta['ca-watch'] = new Array('w','Pridėti puslapį į stebimųjų sąrašą');
+ta['ca-unwatch'] = new Array('w','Pašalinti puslapį iš stebimųjų sąrašo');
+ta['search'] = new Array('f','Ieškoti šiame projekte');
+ta['p-logo'] = new Array('','Pradinis puslapis');
+ta['n-mainpage'] = new Array('z','Eiti į pradinį puslapį');
+ta['n-portal'] = new Array('','Apie projektą, ką galima daryti, kur ką rasti');
+ta['n-currentevents'] = new Array('','Raskite naujausią informaciją');
+ta['n-recentchanges'] = new Array('r','Paskutinių keitimų sąrašas šiame projekte.');
+ta['n-randompage'] = new Array('x','Atidaryti atsitiktinį puslapį');
+ta['n-help'] = new Array('','Vieta, kur rasite rūpimus atsakymus.');
+ta['n-sitesupport'] = new Array('','Padėkite mums');
+ta['t-whatlinkshere'] = new Array('j','Puslapių sąrašas, rodančių į čia');
+ta['t-recentchangeslinked'] = new Array('k','Paskutiniai keitimai straipsniuose, pasiekiamuose iš šio straipsnio');
+ta['feed-rss'] = new Array('','Šio puslapio RSS kanalas');
+ta['feed-atom'] = new Array('','Šio puslapio Atom kanalas');
+ta['t-contributions'] = new Array('','Rodyti šio naudotojo keitimų sąrašą');
+ta['t-emailuser'] = new Array('','Siųsti laišką šiam naudotojui');
+ta['t-upload'] = new Array('u','Įdėti paveikslėlius ar media failus');
+ta['t-specialpages'] = new Array('q','Specialiųjų puslapių sąrašas');
+ta['ca-nstab-main'] = new Array('c','Rodyti puslapio turinį');
+ta['ca-nstab-user'] = new Array('c','Rodyti naudotojo puslapį');
+ta['ca-nstab-media'] = new Array('c','Rodyti media puslapį');
+ta['ca-nstab-special'] = new Array('','Šis puslapis yra specialusis - jo negalima redaguoti.');
+ta['ca-nstab-project'] = new Array('a','Rodyti projekto puslapį');
+ta['ca-nstab-image'] = new Array('c','Rodyti paveikslėlio puslapį');
+ta['ca-nstab-mediawiki'] = new Array('c','Rodyti sisteminį pranešimą');
+ta['ca-nstab-template'] = new Array('c','Rodyti šabloną');
+ta['ca-nstab-help'] = new Array('c','Rodyti pagalbos puslapį');
+ta['ca-nstab-category'] = new Array('c','Rodyti kategorijos puslapį');",
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Bet koks čia parašytas JavaScript bus paleistas kieviename puslapyje kievienam naudotojui. */',
+
+# Image deletion
+'deletedrevision' => 'Ištrinta sena versija $1.',
+
+# Browsing diffs
+'previousdiff' => '← Ankstesnis keitimas',
+'nextdiff' => 'Vėlesnis pakeitimas →',
+
+'imagemaxsize' => 'Riboti paveikslėlių dydį jų aprašymo puslapyje iki:',
+'thumbsize' => 'Sumažintų paveikslėlių dydis:',
+'showbigimage' => 'Rodyti geresnės raiškos versiją ($1x$2, $3 KB)',
+
+'newimages' => 'Naujausių failų galerija',
+'showhidebots' => '($1 robotus)',
+'noimages' => 'Nėra ką parodyti.',
+
+# Labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Naudotojas:',
+'speciallogtitlelabel' => 'Pavadinimas:',
+
+'passwordtooshort' => 'Jūsų slaptažodis per trumpas. Jis turi būti bent $1 simbolių ilgio.',
+
+# Media Warning
+'mediawarning' => "'''Dėmesio''': Šis failas gali turėti kenksmingą kodą, jį paleidus jūsų sistema gali būti pažeista.<hr />",
+
+'fileinfo' => '$1 KB, MIME tipas: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metaduomenys',
+'metadata-help' => 'Šiame faile yra papildomos informacijos, tikriausiai pridėtos skaitmeninės kameros ar skaitytuvo, naudoto jam sukurti ar perkelti į skaitmeninį formatą. Jei failas buvo pakeistas iš pradinės versijos, kai kurios detalės gali nepilnai atspindėti naują failą.',
+'metadata-expand' => 'Rodyti išplėstinę informaciją',
+'metadata-collapse' => 'Slėpti išplėstinę informaciją',
+'metadata-fields' => 'EXIF metaduomenų laukai, nurodyti šiame pranešime, bus įtraukti į paveikslėlio puslapį, kai metaduomenų lentelė bus suskleista. Pagal nutylėjimą kiti laukai bus paslėpti.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# EXIF tags
+'exif-imagewidth' => 'Plotis',
+'exif-imagelength' => 'Aukštis',
+'exif-bitspersample' => 'Bitai komponente',
+'exif-compression' => 'Suspaudimo tipas',
+'exif-photometricinterpretation' => 'Taškų struktūra',
+'exif-orientation' => 'Pasukimas',
+'exif-samplesperpixel' => 'Komponentų skaičius',
+'exif-planarconfiguration' => 'Duomenų išdėstymas',
+'exif-ycbcrsubsampling' => 'Y iki C atrankos santykis',
+'exif-ycbcrpositioning' => 'Y ir C pozicija',
+'exif-xresolution' => 'Horizontali raiška',
+'exif-yresolution' => 'Vertikali raiška',
+'exif-resolutionunit' => 'X ir Y raiškos matavimo vienetai',
+'exif-stripoffsets' => 'Paveikslėlio duomenų vieta',
+'exif-rowsperstrip' => 'Eilių skaičius juostoje',
+'exif-stripbytecounts' => 'Baitai suspaustje juostoje',
+'exif-jpeginterchangeformat' => 'JPEG SOI pozicija',
+'exif-jpeginterchangeformatlength' => 'JPEG duomenų baitai',
+'exif-transferfunction' => 'Perkėlimo funkcija',
+'exif-whitepoint' => 'Balto taško chromatiškumas',
+'exif-primarychromaticities' => 'Pagrindinių spalvų chromiškumas',
+'exif-ycbcrcoefficients' => 'Spalvų pristatym matricos matricos koeficientai',
+'exif-referenceblackwhite' => 'Juodos ir baltos poros nuorodos reikšmės',
+'exif-datetime' => 'Failo keitimo data ir laikas',
+'exif-imagedescription' => 'Paveikslėlio pavadinimas',
+'exif-make' => 'Kameros gamintojas',
+'exif-model' => 'Kameros modelis',
+'exif-software' => 'Naudota programinė įranga',
+'exif-artist' => 'Autorius',
+'exif-copyright' => 'Autorystės teisių savininkas',
+'exif-exifversion' => 'Exif versija',
+'exif-flashpixversion' => 'Palaikoma Flashpix versija',
+'exif-colorspace' => 'Spalvų pristatymas',
+'exif-componentsconfiguration' => 'kiekvieno komponento reikšmė',
+'exif-compressedbitsperpixel' => 'Paveikslėlio suspaudimo režimas',
+'exif-pixelydimension' => 'Leistinas paveikslėlio plotis',
+'exif-pixelxdimension' => 'Leistinas paveikslėlio aukštis',
+'exif-makernote' => 'Gamintojo pastabos',
+'exif-usercomment' => 'Naudotojo komentarai',
+'exif-relatedsoundfile' => 'Susijusi garso byla',
+'exif-datetimeoriginal' => 'Duomenų generavimo data ir laikas',
+'exif-datetimedigitized' => 'Pervedimo į skaitmeninį formatą data ir laikas',
+'exif-subsectime' => 'Datos ir laiko sekundės dalys',
+'exif-subsectimeoriginal' => 'Duomenų generavimo datos ir laiko sekundės dalys',
+'exif-subsectimedigitized' => 'Pervedimo į skaitmeninį formatą datos ir laiko sekundės dalys',
+'exif-exposuretime' => 'Išlaikymo laikas',
+'exif-exposuretime-format' => '$1 sek. ($2)',
+'exif-fnumber' => 'F numeris',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Išlaikymo programa',
+'exif-spectralsensitivity' => 'Spektrinis jautrumas',
+'exif-isospeedratings' => 'ISO greitis',
+'exif-oecf' => 'Optoelektronikos konversijos daugiklis',
+'exif-shutterspeedvalue' => 'Užrakto greitis',
+'exif-aperturevalue' => 'Diafragma',
+'exif-brightnessvalue' => 'Šviesumas',
+'exif-exposurebiasvalue' => 'Išlaikymo paklaida',
+'exif-maxaperturevalue' => 'Mažiausias lešio F numeris',
+'exif-subjectdistance' => 'Objekto atstumas',
+'exif-meteringmode' => 'Matavimo režimas',
+'exif-lightsource' => 'Šviesos šaltinis',
+'exif-flash' => 'Blykstė',
+'exif-focallength' => 'Židinio nuotolis',
+'exif-focallength-format' => '$1 mm',
+'exif-subjectarea' => 'Objekto zona',
+'exif-flashenergy' => 'Blykstės energija',
+'exif-spatialfrequencyresponse' => 'Erdvės dažnio atsakas',
+'exif-focalplanexresolution' => 'Židinio projekcijos X raiška',
+'exif-focalplaneyresolution' => 'Židinio projekcijos Y raiška',
+'exif-focalplaneresolutionunit' => 'Židinio projekcijos raiškos matavimo vienetai',
+'exif-subjectlocation' => 'Objekto vieta',
+'exif-exposureindex' => 'Išlaikymo indeksas',
+'exif-sensingmethod' => 'Jutimo režimas',
+'exif-filesource' => 'Failo šaltinis',
+'exif-scenetype' => 'Scenos tipas',
+'exif-cfapattern' => 'CFA raštas',
+'exif-customrendered' => 'Pasirinktinis vaizdo apdorojimas',
+'exif-exposuremode' => 'Išlaikymo režimas',
+'exif-whitebalance' => 'Baltumo balansas',
+'exif-digitalzoomratio' => 'Skaitmeninio priartinimo koeficientas',
+'exif-focallengthin35mmfilm' => 'Židinio nuotolis 35 mm juostoje',
+'exif-scenecapturetype' => 'Scenos fiksavimo tipas',
+'exif-gaincontrol' => 'Scenos kontrolė',
+'exif-contrast' => 'Kontrastas',
+'exif-saturation' => 'Sodrumas',
+'exif-sharpness' => 'Aštrumas',
+'exif-devicesettingdescription' => 'Įrenginio nustatymų aprašas',
+'exif-subjectdistancerange' => 'Objekto nuotolis',
+'exif-imageuniqueid' => 'Unikalusis paveikslėlio ID',
+'exif-gpsversionid' => 'GPS versija',
+'exif-gpslatituderef' => 'Šiaurės ar pietų platuma',
+'exif-gpslatitude' => 'Platuma',
+'exif-gpslongituderef' => 'Rytų ar vakarų ilguma',
+'exif-gpslongitude' => 'Ilguma',
+'exif-gpsaltituderef' => 'Aukščio nuoroda',
+'exif-gpsaltitude' => 'Aukštis',
+'exif-gpstimestamp' => 'GPS laikas (atominis laikrodis)',
+'exif-gpssatellites' => 'Palydovai, naudoti matavimui',
+'exif-gpsstatus' => 'Gaviklio būsena',
+'exif-gpsmeasuremode' => 'Matavimo režimas',
+'exif-gpsdop' => 'Matavimo tikslumas',
+'exif-gpsspeedref' => 'Greičio vienetai',
+'exif-gpsspeed' => 'GPS gaviklio greitis',
+'exif-gpstrackref' => 'Nuoroda judėjimo krypčiai',
+'exif-gpstrack' => 'Judėjimo kryptis',
+'exif-gpsimgdirectionref' => 'Nuoroda vaizdo krypčiai',
+'exif-gpsimgdirection' => 'Nuotraukos kryptis',
+'exif-gpsmapdatum' => 'Panaudoti geodeziniai apžvalgos duomenys',
+'exif-gpsdestlatituderef' => 'Nuoroda paskirties platumai',
+'exif-gpsdestlatitude' => 'Paskirties platuma',
+'exif-gpsdestlongituderef' => 'Nuoroda paskirties ilgumai',
+'exif-gpsdestlongitude' => 'Paskirties ilguma',
+'exif-gpsdestbearingref' => 'Nuoroda į paskirties pelengą',
+'exif-gpsdestbearing' => 'Paskirties pelengas',
+'exif-gpsdestdistanceref' => 'Nuoroda atstumui iki paskirties',
+'exif-gpsdestdistance' => 'Atstumas iki paskirties',
+'exif-gpsprocessingmethod' => 'GPS apdorojimo metodo pavadinimas',
+'exif-gpsareainformation' => 'GPS zonos pavadinimas',
+'exif-gpsdatestamp' => 'GPS data',
+'exif-gpsdifferential' => 'GPS diferiancialo pataisymas',
+
+# EXIF attributes
+'exif-compression-1' => 'Nesuspausta',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Standartinis', # 0th row: top; 0th column: left
+'exif-orientation-2' => 'Apversta horizontaliai', # 0th row: top; 0th column: right
+'exif-orientation-3' => 'Pasukta 180°', # 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Apversta vertikaliai', # 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Pasukta 90° prieš laikrodžio rodyklę ir apversta vertikaliai', # 0th row: left; 0th column: top
+'exif-orientation-6' => 'Pasukta 90° laikrodžio rodyklės kryptimi', # 0th row: right; 0th column: top
+'exif-orientation-7' => 'Pasukta 90° laikrodžio rodyklės kryptimi ir apversta vertikaliai', # 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Pasukta 90° prieš laikrodžio rodyklę', # 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'stambusis formatas',
+'exif-planarconfiguration-2' => 'plokštuminis formatas',
+
+'exif-xyresolution-i' => '$1 taškai colyje',
+'exif-xyresolution-c' => '$1 taškai centimetre',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'neegzistuoja',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Nenurodyta',
+'exif-exposureprogram-1' => 'Rankinė',
+'exif-exposureprogram-2' => 'Paprasta programa',
+'exif-exposureprogram-3' => 'Diafragmos pirmenybė',
+'exif-exposureprogram-4' => 'Užrakto pirmenybė',
+'exif-exposureprogram-5' => 'Kūrybos programa (linkusi į lauko gylį)',
+'exif-exposureprogram-6' => 'Veiksmo programa (linkusi link greito užrakto greičio)',
+'exif-exposureprogram-7' => 'Portreto režimas (nuotraukoms iš arti nepabrėžiant fono)',
+'exif-exposureprogram-8' => 'Peizažo režimas (peizažo nuotraukoms pabrėžiant foną)',
+
+'exif-subjectdistance-value' => '$1 metrų',
+
+'exif-meteringmode-0' => 'Nežinoma',
+'exif-meteringmode-1' => 'Vidurkis',
+'exif-meteringmode-2' => 'Centruotas vidurkis',
+'exif-meteringmode-3' => 'Taškas',
+'exif-meteringmode-4' => 'Daugiataškis',
+'exif-meteringmode-5' => 'Raštas',
+'exif-meteringmode-6' => 'Dalinis',
+'exif-meteringmode-255' => 'Kita',
+
+'exif-lightsource-0' => 'Nežinomas',
+'exif-lightsource-1' => 'Dienos šviesa',
+'exif-lightsource-2' => 'Fluorescentinis',
+'exif-lightsource-3' => 'Volframas (kaitinamoji lempa)',
+'exif-lightsource-4' => 'Blykstė',
+'exif-lightsource-9' => 'Giedras oras',
+'exif-lightsource-10' => 'Debesuotas oras',
+'exif-lightsource-11' => 'Šešėlis',
+'exif-lightsource-12' => 'Dienos šviesos fluorescentinis (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Dienos baltumo fluorescentinis (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Šalto baltumo fluorescentinis (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Baltas fluorescentinis (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standartinis apšvietimas A',
+'exif-lightsource-18' => 'Standartinis apšvietimas B',
+'exif-lightsource-19' => 'Standartinis apšvietimas C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO studijos volframas',
+'exif-lightsource-255' => 'Kitas šviesos šaltinis',
+
+'exif-focalplaneresolutionunit-2' => 'coliai',
+
+'exif-sensingmethod-1' => 'Nenurodytas',
+'exif-sensingmethod-2' => 'Vienalustis spalvų zonos jutiklis',
+'exif-sensingmethod-3' => 'Dvilustis spalvų zonos jutiklis',
+'exif-sensingmethod-4' => 'Trilustis spalvų zonos jutiklis',
+'exif-sensingmethod-5' => 'Nuoseklusis spalvų zonos jutiklis',
+'exif-sensingmethod-7' => 'Trilinijinis jutiklis',
+'exif-sensingmethod-8' => 'Spalvų nuoseklusis linijinis jutiklis',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'Tiesiogiai fotografuotas vaizdas',
+
+'exif-customrendered-0' => 'Standartinis procesas',
+'exif-customrendered-1' => 'Pasirinktinis procesas',
+
+'exif-exposuremode-0' => 'Automatinis išlaikymas',
+'exif-exposuremode-1' => 'Rankinis išlaikymas',
+'exif-exposuremode-2' => 'Automatinis skliaustas',
+
+'exif-whitebalance-0' => 'Automatinis baltumo balansas',
+'exif-whitebalance-1' => 'Rankinis baltumo balansas',
+
+'exif-scenecapturetype-0' => 'Paprastas',
+'exif-scenecapturetype-1' => 'Peizažas',
+'exif-scenecapturetype-2' => 'Portretas',
+'exif-scenecapturetype-3' => 'Nakties vaizdas',
+
+'exif-gaincontrol-0' => 'Jokia',
+'exif-gaincontrol-1' => 'Nedidelis pakėlimas',
+'exif-gaincontrol-2' => 'Didelis pakėlimas',
+'exif-gaincontrol-3' => 'Mažas nuleidimas',
+'exif-gaincontrol-4' => 'Didelis nuleidimas',
+
+'exif-contrast-0' => 'Paprastas',
+'exif-contrast-1' => 'Mažas',
+'exif-contrast-2' => 'Didelis',
+
+'exif-saturation-0' => 'Paprastas',
+'exif-saturation-1' => 'Mažas sodrumas',
+'exif-saturation-2' => 'Didelis sodrumas',
+
+'exif-sharpness-0' => 'Paprastas',
+'exif-sharpness-1' => 'Mažas',
+'exif-sharpness-2' => 'Didelis',
+
+'exif-subjectdistancerange-0' => 'Nežinomas',
+'exif-subjectdistancerange-1' => 'Macro',
+'exif-subjectdistancerange-2' => 'Artimas vaizdas',
+'exif-subjectdistancerange-3' => 'Tolimas vaizdas',
+
+# Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Šiaurės platuma',
+'exif-gpslatitude-s' => 'Pietų platuma',
+
+# Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Rytų ilguma',
+'exif-gpslongitude-w' => 'Vakarų ilguma',
+
+'exif-gpsstatus-a' => 'Matavimas vykdyme',
+'exif-gpsstatus-v' => 'Matuojamas programinis sąveikumas',
+
+'exif-gpsmeasuremode-2' => 'Dvimatis matavimas',
+'exif-gpsmeasuremode-3' => 'Trimatis matavimas',
+
+# Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometrai per valandą',
+'exif-gpsspeed-m' => 'Mylios per valandą',
+'exif-gpsspeed-n' => 'Mazgai',
+
+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Tikroji kryptis',
+'exif-gpsdirection-m' => 'Magnetinė kryptis',
+
+# External editor support
+'edit-externally' => 'Atidaryti išoriniame redaktoriuje',
+'edit-externally-help' => 'Norėdami gauti daugiau informacijos, žiūrėkite [http://meta.wikimedia.org/wiki/Help:External_editors diegimo instrukcijas].',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'visos',
+'imagelistall' => 'visi',
+'watchlistall1' => 'visi',
+'watchlistall2' => 'visus',
+'namespacesall' => 'visos',
+
+# E-mail address confirmation
+'confirmemail' => 'Patvirtinkite el. pašto adresą',
+'confirmemail_noemail' => 'Jūs neturite nurodę teisingo el. pašto adreso [[{{ns:special}}:Preferences|savo nustatymuose]].',
+'confirmemail_text' => 'Šiame projekte būtina patvirtinti el. pašto adresą prieš naudojant el. pašto funkcijas. Spustelkite žemiau esantį mygtuką,
+kad jūsų el. pašto adresu būtų išsiųstas patvirtinimo kodas.
+Laiške bus atsiųsta nuoroda su kodu, kuria nuėjus, el. pašto adresas bus patvirtintas.',
+'confirmemail_pending' => '<div class="error">
+Patvirtinimo kodas jau nusiųstas jums; jei neseniai sukūrėte savo paskyrą, jūs turėtumėte palaukti jo dar kelias minutes prieš prašant naujo kodo.
+</div>',
+'confirmemail_send' => 'Išsiųsti patvirtinimo kodą',
+'confirmemail_sent' => 'Patvirtinimo laiškas išsiųstas.',
+'confirmemail_oncreate' => 'Patvirtinimo kodas buvo išsiųstas jūsų el. pašto adresu.
+Šis kodas nėra būtinas, kad prisijungtumėte, bet jums reikės jį duoti prieš įjungiant el. pašto paslaugas projekte.',
+'confirmemail_sendfailed' => 'Nepavyko išsiųsti patvirtinamojo laiško. Patikrinkite, ar adrese nėra klaidingų simbolių.
+
+Pašto tarnyba atsakė: $1',
+'confirmemail_invalid' => 'Neteisingas patvirtinimo kodas. Kodo galiojimas gali būti jau pasibaigęs.',
+'confirmemail_needlogin' => 'Jums reikia $1, kad patvirtintumėte savo el. pašto adresą.',
+'confirmemail_success' => 'Jūsų el. pašto adresas patvirtintas. Dabar galite prisijungti ir mėgautis projektu.',
+'confirmemail_loggedin' => 'Jūsų el. pašto adresas patvirtintas.',
+'confirmemail_error' => 'Patvirtinimo metu įvyko neatpažinta klaida.',
+'confirmemail_subject' => '{{SITENAME}} el. pašto adreso patvirtinimas',
+'confirmemail_body' => 'Kažkas, tikriausiai jūs IP adresu $1, užregistravo
+paskyrą "$2" susietą su šiuo el. pašto adresu projekte {{SITENAME}}.
+
+Kad patvirtintumėte, kad ši dėžutė tikrai priklauso jums, ir aktyvuotumėte
+el. pašto paslaugas projekte {{SITENAME}}, atverkite šią nuorodą savo naršyklėje:
+
+$3
+
+Jei naudotoją registravote *ne* jūs, neatidarykite šio adreso. Patvirtinimo kodas
+baigs galioti $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Mėginti tikslų atitikimą',
+'searchfulltext' => 'Ieškoti pilno teksto',
+'createarticle' => 'Kurti straipsnį',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Tarpprojektinis įterpimas yra išjungtas]',
+'scarytranscludefailed' => '[Šablono gavimas iš $1 nepavyko; atsiprašome]',
+'scarytranscludetoolong' => '[URL per ilgas; atsiprašome]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackback šiam straipsniui:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Trinti])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'Trackback buvo sėkmingai ištrintas.',
+
+# Delete conflict
+'deletedwhileediting' => 'Dėmesio: Šis puslapis ištrintas po to, kai pradėjote redaguoti!',
+'confirmrecreate' => "Naudotojas [[{{ns:user}}:$1|$1]] ([[{{user_talk}}:$1|aptarimas]]) ištrynė šį puslapį po to, kai pradėjote jį redaguoti. Trynimo priežastis:
+: ''$2''
+Prašome patvirtinti, kad tikrai norite iš naujo sukurti straipsnį.",
+'recreate' => 'Atkurti',
+'tooltip-recreate' => 'Atkurti puslapį nepaisant to, kad jis buvo ištrintas',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Peradresuojama į [[$1]]...',
+
+# action=purge
+'confirm_purge' => 'Išvalyti šio puslapio podėlį?
+
+$1',
+'confirm_purge_button' => 'Gerai',
+
+'youhavenewmessagesmulti' => 'Turite naujų žinučių $1',
+
+'searchcontaining' => "Ieškoti straipsnių, prasidedančių ''$1''.",
+'searchnamed' => "Ieškoti straipsnių, pavadintų ''$1''.",
+'articletitles' => "Straipsniai, pradedant nuo ''$1''",
+'hideresults' => 'Slėpti rezultatus',
+
+# DISPLAYTITLE
+'displaytitle' => '(Nurodyti šį puslapį kaip [[$1]])',
+
+'loginlanguagelabel' => 'Kalba: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; ankstesnis puslapis',
+'imgmultipagenext' => 'kitas puslapis &rarr;',
+'imgmultigo' => 'Eiti!',
+'imgmultigotopre' => 'Pereiti į puslapį',
+
+# Table pager
+'ascending_abbrev' => 'didėjanti tvarka',
+'descending_abbrev' => 'mažėjanti tvarka',
+'table_pager_next' => 'Kitas puslapis',
+'table_pager_prev' => 'Ankstesnis puslapis',
+'table_pager_first' => 'Pirmas puslapis',
+'table_pager_last' => 'Paskutinis puslapis',
+'table_pager_limit' => 'Rodyti $1 elementų per puslapį',
+'table_pager_limit_submit' => 'Rodyti',
+'table_pager_empty' => 'Jokių rezultatų',
+
+# Auto-summaries
+'autosumm-blank' => 'Šalinamas visas turinys iš puslapio',
+'autosumm-replace' => "Puslapis keičiamas su '$1'",
+'autoredircomment' => 'Nukreipiama į [[$1]]', # This should be changed to the new naming convention, but existed beforehand
+'autosumm-new' => 'Naujas puslapis: $1',
+
+# Size units
+'size-bytes' => '$1 B',
+'size-kilobytes' => '$1 KiB',
+'size-megabytes' => '$1 MiB',
+'size-gigabytes' => '$1 GiB',
+
+);
+
+?>
diff --git a/languages/messages/MessagesLv.php b/languages/messages/MessagesLv.php
new file mode 100644
index 000000000000..3a6ac3a5c3b3
--- /dev/null
+++ b/languages/messages/MessagesLv.php
@@ -0,0 +1,979 @@
+<?php
+/** Latvian (Latviešu)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Niklas Laxström
+ *
+ * @copyright Copyright © 2006, Niklas Laxström
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Diskusija',
+ NS_USER => 'Lietotājs',
+ NS_USER_TALK => 'Lietotāja_diskusija',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '{{grammar:ģenitīvs|$1}}_diskusija',
+ NS_IMAGE => 'Attēls',
+ NS_IMAGE_TALK => 'Attēla_diskusija',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_diskusija',
+ NS_TEMPLATE => 'Veidne',
+ NS_TEMPLATE_TALK => 'Veidnes_diskusija',
+ NS_HELP => 'Palīdzība',
+ NS_HELP_TALK => 'Palīdzības_diskusija',
+ NS_CATEGORY => 'Kategorija',
+ NS_CATEGORY_TALK => 'Kategorijas_diskusija',
+);
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+
+
+$messages= array(
+'tog-underline' => 'Pasvītrot saites:',
+'tog-highlightbroken' => 'Saites uz neesošām lapām rādīt <a href="" class="new">šādi</a> (alternatīva: šādi<a href="" class="internal">?</a>).',
+'tog-justify' => 'Taisnot rindkopas',
+'tog-hideminor' => 'Paslēpt maznozīmīgus labojumus pēdējo izmaiņu lapā',
+'tog-extendwatchlist' => 'Izvērst uzraugāmo sarakstu, lai parādītu visas veiktās izmaiņas',
+'tog-usenewrc' => 'Uzlabotas pēdējās izmaiņas (izmanto \'\'JavaScript\'\')',
+'tog-numberheadings' => 'Automātiski numurēt virsrakstus.',
+'tog-showtoolbar' => 'Rādīt rediģēšanas rīkjoslu',
+'tog-editondblclick' => 'Atvērt rediģēšanas lapu ar dubultklikšķi (izmanto \'\'JavaScript\'\')',
+'tog-editsection' => 'Rādīt sadaļu izmainīšanas saites "izmainīt šo sadaļu"',
+'tog-editsectiononrightclick'=> 'Atvērt sadaļas izmainīšanas lapu, uzklikšķinot ar labo pogu uz sadaļas virsraksta (JavaScript)',
+'tog-showtoc' => 'Parādīt satura rādītāju (lapām, kurās ir vairāk par 3 virsrakstiem)',
+'tog-rememberpassword' => 'Atcerēties paroli pēc pārlūka aizvēršanas',
+'tog-editwidth' => 'Parādīt izmainīšanas logu pilnā platumā',
+'tog-watchcreations' => 'Pievienot tevis radītās lapas uzraugāmo lapu sarakstam',
+'tog-watchdefault' => 'Pievienot tevis izmainītās lapas uzraugāmo lapu sarakstam',
+'tog-minordefault' => 'Atzīmēt visus labojumus jau sākotnēji par maznozīmīgiem',
+'tog-previewontop' => 'Parādīt priekšskatījumu virs rediģēšanas loga, nevis zem.',
+'tog-previewonfirst' => 'Parādīt priekšskatījumu jau sākotnējā labošanā.',
+'tog-nocache' => 'Neļaut pārlūkam saglabāt lapas kešatmiņā',
+'tog-enotifwatchlistpages'=> 'Paziņot pa e-pastu par rakstu izmaiņām',
+'tog-enotifusertalkpages'=> 'Paziņot pa e-pastu par izmaiņām manā diskusiju lapā',
+'tog-enotifminoredits' => 'Paziņot pa e-pastu arī par maznozīmīgiem rakstu labojumiem',
+'tog-enotifrevealaddr' => 'Atklāt manu e-pasta adresi paziņojumu vēstulēs',
+'tog-shownumberswatching'=> 'Rādīt uzraudzītāju skaitu',
+'tog-fancysig' => 'Vienkāršs paraksts (bez automātiskās saites)',
+'tog-externaleditor' => 'Pēc noklusējuma izmantot ārēju programmu lapu izmainīšanai',
+'tog-externaldiff' => 'Pēc noklusējuma izmantot ārēju programmu izmaiņu parādīšanai',
+'tog-showjumplinks' => 'Rādīt pārlēkšanas saites',
+'tog-uselivepreview' => 'Lietot tūlītējo priekšskatījumu (izmanto "JavaScript"; eksperimentāla iespēja).',
+'tog-forceeditsummary' => 'Atgādināt man, ja kopsavilkuma ailīte ir tukša',
+'tog-watchlisthideown' => 'Paslēpt manus labojumus manā uzraugāmo sarakstā.',
+'tog-watchlisthidebots' => 'Paslēpt botu labojumus manā uzraugāmo sarakstā.',
+'underline-always' => 'vienmēr',
+'underline-never' => 'nekad',
+'underline-default' => 'Kā pārlūkā',
+'skinpreview' => '(Priekšskats)',
+'sunday' => 'svētdiena',
+'monday' => 'Pirmdiena',
+'tuesday' => 'otrdiena',
+'wednesday' => 'trešdiena',
+'thursday' => 'ceturtdiena',
+'friday' => 'piektdiena',
+'saturday' => 'sestdiena',
+'january' => 'janvārī',
+'february' => 'februārī',
+'march' => 'martā',
+'april' => 'aprīlī',
+'may_long' => 'maijā',
+'june' => 'jūnijā',
+'july' => 'jūlijā',
+'august' => 'augustā',
+'september' => 'septembrī',
+'october' => 'oktobrī',
+'november' => 'novembrī',
+'december' => 'decembrī',
+'jan' => 'janvārī,',
+'feb' => 'februārī,',
+'mar' => 'martā,',
+'apr' => 'aprīlī,',
+'may' => 'maijā,',
+'jun' => 'jūnijā,',
+'jul' => 'jūlijā,',
+'aug' => 'augustā,',
+'sep' => 'septembrī,',
+'oct' => 'oktobrī,',
+'nov' => 'novembrī,',
+'dec' => 'decembrī,',
+'categories' => 'Kategorijas',
+'pagecategories' => '{{PLURAL:$1|Kategorija|Kategorijas}}',
+'category_header' => 'Raksti, kas ietverti kategorijā "$1".',
+'subcategories' => 'Apakškategorijas',
+'mainpage' => 'Sākumlapa',
+'mainpagetext' => '<big>\'\'\'MediaWiki veiksmīgi ieinstalēts\'\'\'</big>',
+'portal' => 'Kopienas portāls',
+'portal-url' => 'Project:Kopienas portāls',
+'about' => 'Par',
+'aboutsite' => 'Par {{grammar:akuzatīvs|{{SITENAME}}}}',
+'article' => 'Raksts',
+'help' => 'Palīdzība',
+'bugreports' => 'Kļūdu paziņojumi',
+'sitesupport' => 'Ziedojumi',
+'sitesupport-url' => 'Project:Ziedojumi',
+'faq' => 'FAQ',
+'edithelp' => 'Palīdzība izmaiņām',
+'newwindow' => '(atveras jaunā logā)',
+'cancel' => 'Atcelt',
+'qbfind' => 'Meklēšana',
+'qbbrowse' => 'Navigācija',
+'qbedit' => 'Izmainīšana',
+'qbpageoptions' => 'Šī lapa',
+'qbpageinfo' => 'Konteksts',
+'qbmyoptions' => 'Manas lapas',
+'qbspecialpages' => 'Īpašās lapas',
+'moredotdotdot' => 'Vairāk...',
+'mypage' => 'Mana lapa',
+'mytalk' => 'Mana diskusija',
+'anontalk' => 'Šīs IP adreses diskusija',
+'navigation' => 'Navigācija',
+'currentevents' => 'Aktualitātes',
+'currentevents-url' => 'Aktualitātes',
+'disclaimers' => 'Saistību atrunas',
+'privacy' => 'Privātuma politika',
+'privacypage' => 'Project:Privātuma politika',
+'errorpagetitle' => 'Kļūda',
+'returnto' => 'Atgriezties: $1.',
+'tagline' => 'No \'\'{{grammar:ģenitīvs|{{SITENAME}}}}\'\'',
+'search' => 'Meklēt',
+'searchbutton' => 'Meklēt',
+'go' => 'Aiziet!',
+'searcharticle' => 'Aiziet!',
+'history' => 'hronoloģija',
+'history_short' => 'Hronoloģija',
+'updatedmarker' => 'atjaunināti kopš pēdējā apmeklējuma',
+'info_short' => 'Informācija',
+'printableversion' => 'Drukājama versija',
+'permalink' => 'Pastāvīgā saite',
+'print' => 'Drukāt',
+'edit' => 'Izmainīt šo lapu',
+'editthispage' => 'Izmainīt šo lapu',
+'delete' => 'Dzēst',
+'deletethispage' => 'Dzēst šo lapu',
+'undelete_short' => 'Atjaunot $1 versijas',
+'protect' => 'Aizsargāt',
+'protectthispage' => 'Aizsargāt šo lapu',
+'unprotect' => 'Neaizsargāt',
+'unprotectthispage' => 'Neaizsargāt šo lapu',
+'newpage' => 'Jauna lapa',
+'talkpage' => 'Diskusija par šo lapu',
+'specialpage' => 'Īpašā Lapa',
+'personaltools' => 'Lietotāja rīki',
+'postcomment' => 'Pievienot komentāru',
+'articlepage' => 'Apskatīt rakstu',
+'talk' => 'Diskusija',
+'views' => 'Apskates',
+'toolbox' => 'Rīki',
+'userpage' => 'Skatīt lietotāja lapu',
+'projectpage' => 'Skatīt projekta lapu',
+'imagepage' => 'Aplūkot attēla lapu',
+'viewtalkpage' => 'Skatīt diskusiju',
+'otherlanguages' => 'Citās valodās',
+'redirectedfrom' => '(Pāradresēts no $1)',
+'autoredircomment' => 'Pāradresē uz [[$1]]',
+'redirectpagesub' => 'Pāradresācijas lapa',
+'lastmodifiedat' => 'Šajā lapā pēdējās izmaiņas izdarītas $2, $1.',
+'viewcount' => 'Šī lapa ir tikusi apskatīta $1 reizes.',
+'copyright' => 'Saturs ir pieejams saskaņā ar $1.',
+'protectedpage' => 'Aizsargāta lapa',
+'jumpto' => 'Pārlēkt uz:',
+'jumptonavigation' => 'navigācija',
+'jumptosearch' => 'meklēt',
+'badaccess' => 'Atļaujas kļūda',
+'versionrequired' => 'Nepieciešamā \'\'MediaWiki\'\' versija: $1.',
+'versionrequiredtext' => 'Lai lietotu šo lapu, nepieciešama \'\'MediaWiki\'\' versija $1. Sk. [[Special:versija]].',
+'ok' => 'Labi',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Saturs iegūts no "$1"',
+'youhavenewmessages' => 'Tev ir $1 (skat. $2).',
+'newmessageslink' => 'jauns vēstījums',
+'newmessagesdifflink' => 'izmaiņu lapu, lai redzētu, kas jauns',
+'editsection' => 'izmainīt šo sadaļu',
+'editold' => 'rediģēt',
+'editsectionhint' => 'Rediģēt sadaļu: $1',
+'toc' => 'Satura rādītājs',
+'showtoc' => 'parādīt',
+'hidetoc' => 'paslēpt',
+'thisisdeleted' => 'Apskatīt vai atjaunot $1?',
+'viewdeleted' => 'Skatīt $1?',
+'restorelink' => '$1 dzēstās versijas',
+'feedlinks' => 'Barotne:',
+'nstab-main' => 'Raksts',
+'nstab-user' => 'Lietotāja lapa',
+'nstab-media' => 'Multivides lapa',
+'nstab-project' => 'Projekta lapa',
+'nstab-image' => 'Attēls',
+'nstab-mediawiki' => 'paziņojums',
+'nstab-template' => 'Veidne',
+'nstab-help' => 'palīdzība',
+'nstab-category' => 'Kategorija',
+'nosuchaction' => 'Šādas darbības nav.',
+'nosuchactiontext' => 'Wiki neatpazīst URL norādīto darbību',
+'nosuchspecialpage' => 'Nav tādas īpašās lapas',
+'nospecialpagetext' => 'Tu esi pieprasījis īpašo lapu, ko wiki neatpazīst.',
+'error' => 'Kļūda',
+'databaseerror' => 'Datu bāzes kļūda',
+'noconnect' => 'Atvainojiet, šajā wiki ir radušās tehniskas grūtības un nav iespējams savienoties ar datubāžu serveri. <br />
+$1',
+'cachederror' => 'Šī ir lapas saglabātā versija, iespējams, ka tā nav atjaunināta.',
+'laggedslavemode' => 'Uzmanību: Iespējams, šajā lapā nav redzami nesen izdarītie papildinājumi.',
+'readonly' => 'Datubāze bloķēta',
+'readonlytext' => 'Datubāze šobrīd ir bloķēta pret jauniem ierakstiem un citām izmaiņām. Visdrīzāk iemesls ir parasts datubāzes uzturēšanas pasākums, pēc kura tā tiks atjaunota normālā stāvoklī. Administrators, kurš nobloķēja datubāzi, norādīja šādu iemeslu:
+<p>$1',
+'internalerror' => 'Iekšēja kļūda',
+'filecopyerror' => 'Nav iespējams nokopēt failu "$1" uz "$2"',
+'filerenameerror' => 'Neizdevās pārdēvēt failu "$1" par "$2".',
+'filedeleteerror' => 'Nevar izdzēst failu "$1".',
+'filenotfound' => 'Neizdevās atrast failu "$1".',
+'formerror' => 'Kļūda: neizdevās nosūtīt saturu',
+'badarticleerror' => 'Šo darbību nevar veikt šajā lapā.',
+'cannotdelete' => 'Nevar izdzēst norādīto lapu vai failu. (Iespējams, to jau ir izdzēsis kāds cits)',
+'badtitle' => 'Nepiemērots nosaukums',
+'perfcached' => 'Šie dati ir no servera kešatmiņas un var būt novecojuši:',
+'viewsource' => 'Aplūkot kodu',
+'viewsourcefor' => 'Lapa: $1',
+'protectedtext' => 'Šī lapa ir bloķēta pret izmaiņām. Iemeslus, lūdzu, skaties [[Project:Aizsargāta lapa]].',
+'protectedinterface' => 'Šī lapa satur programmatūras interfeisā lietotu tekstu un ir bloķēta pret izmaiņām, lai pasargātu no bojājumiem.',
+'editinginterface' => '\'\'\'Brīdinājums:\'\'\' Tu izmaini lapu, kuras saturu izmanto wiki programmatūras lietotāja saskarnē (\'\'interfeisā\'\'). Šīs lapas izmaiņas ietekmēs lietotāja saskarni citiem lietotājiem.',
+'logouttitle' => 'Lietotāja iziešana',
+'logouttext' => 'Tu esi izgājis no {{grammar:ģenitīvs|{{SITENAME}}}}.
+Vari turpināt to izmantot anonīmi, vari atgriezties kā cits lietotājs vai varbūt tas pats.
+Ņem vērā, ka arī pēc iziešanas no {{grammar:ģenitīvs|{{SITENAME}}}} dažas lapas var tikt parādītas tā, it kā tu vēl būtu iekšā, līdz tiks iztīrīta pārlūka kešatmiņa.',
+'welcomecreation' => '== Laipni lūdzam, $1! ==
+
+Tavs lietotāja konts ir izveidots. Neaizmirsti, ka ir iespējams mainīt \'\'{{grammar:ģenitīvs|{{SITENAME}}}}\'\' izmantošanas izvēles.',
+'loginpagetitle' => 'Lietotāja ieiešana',
+'yourname' => 'Tavs lietotājvārds',
+'yourpassword' => 'Tava parole',
+'yourpasswordagain' => 'Atkārto paroli',
+'remembermypassword' => 'Atcerēties manu paroli pēc pārlūka aizvēršanas.',
+'yourdomainname' => 'Tavs domēns',
+'externaldberror' => 'Notikusi vai nu ārējās autentifikācijas datubāzes kļūda, vai arī tev nav atļauts izmainīt savu ārējo kontu.',
+'loginproblem' => '<b>Radās problēma ar ieiešanu.</b><br />Mēģini vēlreiz!',
+'alreadyloggedin' => '<span style="color:#ff0000"><b>Lietotāj $1, tu jau esi iegājis!</b></span><br />',
+'login' => 'Ieiet',
+'loginprompt' => 'Lai ieietu {{grammar:lokatīvs|{{SITENAME}}}}, tavam datoram ir jāpieņem sīkdatnes (<i>cookies</i>).',
+'userlogin' => 'Izveidot jaunu lietotāju vai doties iekšā',
+'logout' => 'Iziet',
+'userlogout' => 'Iziet',
+'notloggedin' => 'Neesi iegājis',
+'nologin' => 'Nav lietotājvārda? $1.',
+'nologinlink' => 'Reģistrējies',
+'createaccount' => 'Izveidot jaunu lietotāju',
+'gotaccount' => 'Tev jau ir lietotājvārds? $1!',
+'gotaccountlink' => 'Dodies iekšā',
+'createaccountmail' => 'pa e-pastu',
+'badretype' => 'Tevis ievadītās paroles nesakrīt.',
+'userexists' => 'Šāds lietotāja vārds jau eksistē. Lūdzu izvēlies citu vārdu.',
+'youremail' => 'Tava e-pasta adrese*',
+'username' => 'Lietotājvārds:',
+'uid' => 'Lietotāja ID:',
+'yourrealname' => 'Tavs īstais vārds*',
+'yourlanguage' => 'Lietotāja saskarnes valoda:',
+'yournick' => 'Tavs paraksts (iesauka):',
+'badsig' => 'Kļūdains \'\'paraksta\'\' kods; pārbaudi HTML (ja tāds ir lietots).',
+'email' => 'E-pasts',
+'prefs-help-email-enotif'=> 'Šo adresi lieto arī lai sūtītu paziņojumus pa e-pastu, ja tādi ir nodefinēti.',
+'loginerror' => 'Neveiksmīga ieiešana',
+'prefs-help-email' => '* E-pasts (nav obligāti jānorāda): Ļauj citiem sazināties ar tevi, izmantojot tavu lietotāja lapu vai lietotāja diskusiju lapu, tev nekur neatklājot savu identitāti.',
+'nocookiesnew' => 'Lietotājvārds tika izveidots, bet tu neesi iegājis iekšā. {{SITENAME}} izmanto sīkdatnes (<i>cookies</i>), lai lietotāji varētu tajā ieiet. Tavs pārlūks nepieņem tās. Lūdzu, atļauj to pieņemšanu un tad nāc iekšā ar savu lietotājvārdu un paroli.',
+'nocookieslogin' => '{{SITENAME}} izmanto sīkdatnes (<i>cookies</i>), lai lietotāji varētu ieiet tajā. Diemžēl tavs pārlūks tos nepieņem. Lūdzu, atļauj to pieņemšanu un mēģini vēlreiz.',
+'noname' => 'Tu neesi norādījis derīgu lietotāja vārdu.',
+'loginsuccesstitle' => 'Ieiešana veiksmīga',
+'loginsuccess' => 'Tu esi ienācis {{grammar:lokatīvs|{{SITENAME}}}} kā "$1".',
+'nosuchuser' => 'Šeit nav lietotāja ar vārdu "$1". Pārbaudi, vai pareizi uzrakstīts, vai arī izveido jaunu kontu.',
+'nosuchusershort' => 'Šeit nav lietotāja ar vārdu "$1". Pārbaudi vai pareizi uzrakstīts.',
+'nouserspecified' => 'Tev jānorāda lietotājvārds.',
+'wrongpassword' => 'Tu ievadīji nepareizu paroli. Lūdzu, mēģini vēlreiz.',
+'wrongpasswordempty' => 'Parole bija tukša. Lūdzu mēģini vēlreiz.',
+'mailmypassword' => 'Atsūtīt man jaunu paroli',
+'passwordremindertitle' => 'Paroles atgadinajums no {{SITENAME}}s',
+'passwordremindertext' => 'Kads (iespejams, Tu pats, no IP adreses $1)
+ludza, lai nosutam Tev jaunu {{SITENAME}} ({{SERVER}}) ($4) paroli.
+Lietotajam $2 parole tagad ir $3.
+Ludzu, nomaini paroli, kad esi veiksmigi iekluvis ieksa.',
+'noemail' => 'Lietotājs "$1" nav reģistrējis e-pasta adresi.',
+'passwordsent' => 'Esam nosūtījuši jaunu paroli uz e-pasta adresi, kuru ir norādījis lietotājs $1. Lūdzu, nāc iekšā ar jauno paroli, kad būsi to saņēmis.',
+'eauthentsent' => 'Apstiprinājuma e-pasts tika nosūtīts uz norādīto e-pasta adresi. Lai varētu saņemt citus \'\'meilus\'\', izpildi vēstulē norādītās instrukcijas, lai apstiprinātu, ka šī tiešām ir tava e-pasta adrese.',
+'mailerror' => 'E-pasta sūtīšanas kļūda: $1',
+'acct_creation_throttle_hit'=> 'Tu jau esi izveidojis $1 kontus. Vairāk nevar.',
+'emailauthenticated' => 'Tava e-pasta adrese tika apstiprināta $1.',
+'emailnotauthenticated' => 'Tava e-pasta adrese vēl nav apstiprināta un zemāk norādītās iespējas nav pieejamas.',
+'noemailprefs' => '<strong>Norādi e-pasta adresi, lai lietotu šīs iespējas.</strong>',
+'emailconfirmlink' => 'Apstiprināt tavu e-pasta adresi',
+'invalidemailaddress' => 'E-pasta adrese nevar tikt apstiprināta, jo izskatās nederīga. Lūdzu ievadi korekti noformētu e-pasta adresi, vai arī atstāj to lauku tukšu.',
+'accountcreated' => 'Konts izveidots',
+'accountcreatedtext' => 'Lietotāja konts priekš $1 tika izveidots.',
+'bold_sample' => 'Teksts boldā',
+'bold_tip' => 'Teksts boldā',
+'italic_sample' => 'Teksts kursīvā',
+'italic_tip' => 'Teksts kursīvā',
+'link_sample' => 'Lapas nosaukums',
+'link_tip' => 'Iekšējā saite',
+'extlink_sample' => 'http://www.piemers.lv saites apraksts',
+'extlink_tip' => 'Ārējā saite (neaizmirsti sākumā pierakstīt "http://")',
+'headline_sample' => 'Virsraksta teksts',
+'headline_tip' => '2. līmeņa virsraksts',
+'math_sample' => 'Šeit ievieto formulu',
+'math_tip' => 'Matemātikas formula (LaTeX)',
+'nowiki_sample' => 'Šeit raksti neformatētu tekstu',
+'nowiki_tip' => 'Ignorēt wiki formatējumu',
+'image_sample' => 'Piemers.jpg',
+'image_tip' => 'Ievietots attēls',
+'media_sample' => 'Piemers.ogg',
+'media_tip' => 'Saite uz multimēdiju failu',
+'sig_tip' => 'Tavs paraksts ar laika atzīmi',
+'hr_tip' => 'Horizontāla līnija (neizmanto lieki)',
+'summary' => 'Kopsavilkums',
+'subject' => 'Tēma/virsraksts',
+'minoredit' => 'maznozīmīgs labojums',
+'watchthis' => 'uzraudzīt',
+'savearticle' => 'Saglabāt lapu',
+'preview' => 'Pirmskats',
+'showpreview' => 'Rādīt pirmskatu',
+'showlivepreview' => 'Tūlītējs pirmskats',
+'showdiff' => 'Rādīt izmaiņas',
+'anoneditwarning' => '\'\'\'Uzmanību:\'\'\' tu neesi iegājis. Lapas hronoloģijā tiks ierakstīta tava IP adrese.',
+'missingsummary' => '\'\'\'Atgādinājums\'\'\': Tu neesi norādījis izmaiņu kopsavilkumu. Vēlreiz klikšķinot uz "Saglabāt lapu", Tavas izmaiņas tiks saglabātas bez kopsavilkuma.',
+'missingcommenttext' => 'Lūdzu, ievadi tekstu zemāk redzamajā logā!',
+'blockedtitle' => 'Lietotājs ir bloķēts.',
+'blockedtext' => '$1 ir nobloķējis tavu lietotāja vārdu vai IP adresi. Iemesls tam ir:<br />\'\'$2\'\'<br />. Tu vari sazināties ar $1 vai kādu citu [[Project:Administrators|administratoru]] lai apspriestu šo bloku.
+
+Pievērs uzmanību, tam, ka ja tu neesi norādījis derīgu e-pasta adresi [Special:Preferences|user preferences]], tev nedarbosies "sūtīt e-pastu" iespēja.
+
+Tava IP adrese ir $3. Lūdzu iekļauj to visos turpmākajos pieprasījumos.',
+'whitelistedittitle' => 'Lai varētu rediģēt, šeit jāielogojas.',
+'whitelistedittext' => 'Tev $1 lai varētu rediģēt lapas.',
+'whitelistreadtitle' => 'Jāielogojas, lai varētu lasīt',
+'whitelistreadtext' => 'Tev [[Special:Userlogin|jāielogojas]] lai varētu lasīt lapas.',
+'whitelistacctitle' => 'Tev nav atļauts izveidot kontu',
+'loginreqtitle' => 'Nepieciešama ieiešana',
+'loginreqlink' => 'login',
+'accmailtitle' => 'Parole izsūtīta.',
+'accmailtext' => '$1 parole tika nosūtīta uz $2.',
+'newarticle' => '(Jauns raksts)',
+'newarticletext' => '<div style="border: 1px solid #ccc; padding: 7px;">\'\'\'{{grammar:lokatīvs|{{SITENAME}}}} vēl nav tāda {{NAMESPACE}} raksta ar virsrakstu "{{PAGENAME}}".\'\'\'
+* Lai izveidotu šo lapu, raksti tekstu zemāk redzamajā logā. Kad esi pabeidzis, spied pogu "Saglabāt lapu". Ja viss būs kārtībā, izmaiņām vajadzētu būt tūlīt redzamām.
+* \'\'\'Ja esi izveidojis šo lapu dažu pēdējo minūšu laikā un nekas nav parādījies, iespējams, ir aizkavējusies informācijas saglabāšana datubāzē.\'\'\' Lūdzam mazliet pagaidīt un tad vēlreiz pārbaudīt - visdrīzāk, pēc kāda brīža lapa būs redzama un nebūs jāraksta viss vēlreiz.
+* Ja šis ir raksts (nevis, piemēram, diskusiju lapa), tad
+** lūdzam neveidot rakstu, kurā būtu reklamēts vai slavināts tu pats, kāda weblapa, produkts vai uzņēmums (skat. "[[Project:Kas {{SITENAME}} nav|Kas {{SITENAME}} nav]]").
+** ja tie ir tavi pirmie soļi {{grammar:lokatīvs|{{SITENAME}}}}, lūdzam vispirms izlasīt [[Project:Pamācība|pamācību]] un eksperimentiem izmantot tikai [[Project:Smilšu kaste|smilšu kasti]]. Paldies!
+** [[Special:Search/{{PAGENAME}}|spied šeit]], lai meklētu {{grammar:lokatīvs|{{SITENAME}}}} informāciju par jēdzienu "{{PAGENAME}}".
+</div>',
+'anontalkpagetext' => '----\'\'Šī ir diskusiju lapa anonīmam lietotājam, kurš vēl nav kļuvis par reģistrētu lietotāju vai arī neizmanto savu lietotājvārdu. Tādēļ mums ir jāizmanto skaitliskā [[IP adrese]], lai viņu identificētu. Šāda IP adrese var būt vairākiem lietotājiem. Ja tu esi anonīms lietotājs un uzskati, ka tev ir adresēti neatbilstoši komentāri, lūdzu, [[Special:Userlogin|kļūsti par lietotāju vai arī izmanto jau izveidotu lietotājvārdu]], lai izvairītos no turpmākām neskaidrībām un tu netiktu sajaukts ar citiem anonīmiem lietotājiem.\'\'',
+'noarticletext' => '(Šajā lapā šobrīd nav nekāda teksta)',
+'clearyourcache' => '\'\'\'Piezīme:\'\'\' Pēc saglabāšanas iztīri pārlūka kešatmiņu, lai pārmaiņas būtu redzamas: Mozilla/Safari/Konqueror: turi nospiestu \'\'\'Shift\'\'\' un klikšķini \'\'\'Reload\'\'\' (vai spied \'\'\'Ctrl-Shift-r\'\'\'), IE: spied \'\'\'Ctrl-F5\'\'\', Opera: spied \'\'\'F5\'\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Ieteikums:</strong> Lieto pirmsskata pogu, lai pārbaudītu savu jauno CSS/JS pirms saglabāšanas.',
+'usercsspreview' => '\'\'\'Atceries, ka šis ir tikai tava lietotāja CSS pirmskats, lapa vēl nav saglabāta!\'\'\'',
+'userjspreview' => '\'\'\'Atceries, ka šis ir tikai tava lietotāja JavaScript pirmskats/tests, lapa vēl nav saglabāta!\'\'\'',
+'note' => '<strong>Piezīme: </strong>',
+'previewnote' => '\'\'\'Atceries, ka šis ir tikai pirmskats un vēl nav saglabāts!\'\'\'',
+'editing' => 'Izmainīt $1',
+'editinguser' => 'Izmainīt $1',
+'editingsection' => 'Izmainīt $1 (sadaļa)',
+'editingcomment' => 'Izmainīt $1 (komentārs)',
+'editconflict' => 'Izmaiņu konflikts: $1',
+'explainconflict' => 'Kāds cits ir izmainījis šo lapu pēc tam, kad tu sāki to mainīt. Augšējā teksta logā ir lapas teksts tā pašreizējā versijā. Tevis veiktās izmaiņas ir redzamas apakšējā teksta logā. Lai saglabātu savas izmaiņas, tev ir jāapvieno savs teksts ar saglabāto pašreizējo variantu. Kad spiedīsi pogu "Saglabāt lapu", tiks saglabāts <b>tikai</b> teksts, kas ir augšējā teksta logā.',
+'yourtext' => 'Tavs teksts',
+'storedversion' => 'Saglabātā versija',
+'editingold' => '<strong>BRĪDINĀJUMS: Saglabājot šo lapu, tu izmainīsi šīs lapas novecojušu versiju, un ar to tiks dzēstas visas izmaiņas, kas izdarītas pēc šīs versijas.</strong>',
+'yourdiff' => 'Atšķirības',
+'copyrightwarning' => 'Lūdzu, ņem vērā, ka viss ieguldījums, kas veikts {{grammar:lokatīvs|{{SITENAME}}}}, ir uzskatāms par publiskotu saskaņā ar $2 (vairāk info skat. $1).
+Ja nevēlies, lai Tevis rakstīto kāds rediģē un izplata tālāk, tad, lūdzu, nepievieno to šeit!<br />
+
+Izvēloties "Saglabāt lapu", Tu apliecini, ka šo rakstu esi rakstījis vai papildinājis pats vai izmantojis informāciju no darba, ko neaizsargā autortiesības, vai tamlīdzīga brīvi pieejama resursa.<br />
+
+<strong>BEZ ATĻAUJAS NEPIEVIENO DARBU, KO AIZSARGĀ AUTORTIESĪBAS!</strong>',
+'copyrightwarning2' => 'Lūdz ņem vērā, ka visu ieguldījumu {{grammar:lokatīvs|{{SITENAME}}}} var rediģēt, mainīt vai izdzēst citi lietotāji. Ja negribi lai ar tavu rakstīto tā izrīkojas, nepievieno to šeit.
+
+Tu apliecini, ka šo rakstu esi rakstījis vai papildinājis pats vai izmantojis informāciju no darba, ko neaizsargā autortiesības, vai tamlīdzīga brīvi pieejama resursa (sīkāk skatīt $1).
+
+\'\'\'BEZ ATĻAUJAS NEPIEVIENO DARBU, KO AIZSARGĀ AUTORTIESĪBAS!\'\'\'',
+'longpagewarning' => '<div style="border-width:1px;border-style:solid;border-color:#aaaaaa;padding:3px">
+Šī lapa ir $1 kilobaitus liela. Tas var būt vairāk par lapas optimālo izmēru. Lūdzu apsver iespēju sašķelt to mazākās sekcijās.
+</div>',
+'protectedpagewarning' => '\'\'\'BRĪDINĀJUMS: Šī lapa ir bloķēta pret izmaiņām, tikai lietotāji ar admina privilēģijām var to izmainīt. To darot, noteikti ievēro [[Project:Norādījumi par aizsargātajām lapām|norādījumus par aizsargātajām lapām]].\'\'\'',
+'templatesused' => '<br />Šajā lapā izmantotās veidnes:',
+'revhistory' => 'Versiju hronoloģija',
+'nohistory' => 'Šai lapai nav pieejama versiju hronoloģija.',
+'revnotfound' => 'Versija nav atrasta',
+'loadhist' => 'Ielādē lapas hronoloģiju',
+'currentrev' => 'Pašreizējā versija',
+'revisionasof' => 'Versija, kas saglabāta $1',
+'previousrevision' => '←Senāka versija',
+'nextrevision' => 'Jaunāka versija→',
+'currentrevisionlink' => 'skatīt pašreizējo versiju',
+'cur' => 'ar pašreizējo',
+'next' => 'nākamais',
+'last' => 'ar iepriekšējo',
+'histlegend' => 'Atšķirību izvēle: atzīmē vajadzīgo versiju apaļās pogas un spied "Salīdzināt izvēlētās versijas".<br />
+Apzīmējumi:
+"ar pašreizējo" = salīdzināt ar pašreizējo versiju,
+"ar iepriekšējo" = salīdzināt ar iepriekšējo versiju,
+m = maznozīmīgs labojums.',
+'histfirst' => 'Senākās',
+'histlast' => 'Jaunākās',
+'rev-deleted-comment' => '(komentārs nodzēsts)',
+'rev-deleted-user' => '(lietotāja vārds nodzēsts)',
+'rev-delundel' => 'rādīt/slēpt',
+'history-feed-title' => 'Versiju hronoloģija',
+'history-feed-description'=> 'Šīs wiki lapas versiju hronoloģija',
+'difference' => '(Atšķirības starp versijām)',
+'loadingrev' => 'ielādē atšķirību versiju',
+'lineno' => '$1. rindiņa:',
+'editcurrent' => 'Izmainīt šīs lapas pašreizējo versiju',
+'selectolderversionfordiff'=> 'Izvēlies vecāku versiju, ar kuru salīdzināt',
+'compareselectedversions'=> 'Salīdzināt izvēlētās versijas',
+'searchresults' => 'Meklēšanas rezultāti',
+'searchresulttext' => 'Lai iegūtu vairāk informācijas par meklēšanu {{grammar:akuzatīvs|{{SITENAME}}}}, skat. [[Project:Searching|{{grammar:ģenitīvs|{{SITENAME}}}} meklēšana]].',
+'searchsubtitle' => 'Pieprasījums: [[:$1]] [[Special:Allpages/$1|&#x5B;Indekss&#x5D;]]',
+'searchsubtitleinvalid' => 'Pieprasījums: $1',
+'badquery' => 'Nepareizi noformulēts meklēšanas pieprasījums',
+'badquerytext' => 'Mēs nevarējām apstrādāt tavu pieprasījumu. Iespējams, tāpēc, ka tu mēģināji meklēt vārdu, kas ir īsāks par trim burtiem, kas vēl nav iespējams. Varbūt tu nepareizi ierakstīji kādu frāzi, piemēram "fish and and scales". Lūdzu, mēģini citus atslēgvārdus.',
+'titlematches' => 'Rezultāti virsrakstos',
+'notitlematches' => 'Neviena rezultāta, meklējot lapas virsrakstā',
+'textmatches' => 'Rezultāti lapu tekstos',
+'notextmatches' => 'Neviena rezultāta, meklējot lapas tekstā',
+'prevn' => 'iepriekšējās $1',
+'nextn' => 'nākamās $1',
+'viewprevnext' => 'Skatīt ($1) ($2) ($3 vienā lapā).',
+'showingresults' => 'Šobrīd ir redzamas <b>$1</b> lapas, sākot ar #<b>$2</b>.',
+'showingresultsnum' => 'Šobrīd ir redzamas <b>$3</b> lapas, sākot ar #<b>$2</b>.',
+'nonefound' => '<strong>Piezīme:</strong> bieži vien meklēšana ir neveiksmīga, meklējot plaši izplatītus vārdus, piemēram, "un" vai "ir", jo tie netiek iekļauti meklēšanas datubāzē, vai arī meklējot vairāk par vienu vārdu (jo rezultātos parādīsies tikai lapas, kurās ir visi meklētie vārdi).',
+'powersearch' => 'Meklēt',
+'powersearchtext' => 'Meklēt šādās palīglapās :<br />
+$1<br />
+$2 Parādīt pāradresācijas lapas Meklēt $3 $9',
+'searchdisabled' => '<p style="margin: 1.5em 2em 1em">Meklēšana {{grammar:lokatīvs|{{SITENAME}}}} šobrīd ir atslēgta darbības traucējumu dēļ. Pagaidām vari meklēt, izmantojot Google vai Yahoo.
+<span style="font-size: 89%; display: block; margin-left: .2em">Ņem vērā, ka meklētāju indeksētais {{grammar:ģenitīvs|{{SITENAME}}}} saturs var būt novecojis.</span></p>',
+'blanknamespace' => '(Pamatlapa)',
+'preferences' => 'Izvēles',
+'prefsnologin' => 'Neesi iegājis',
+'prefsnologintext' => 'Tev jābūt [[Special:Userlogin|iegājušam]], lai mainītu lietotāja izvēles.',
+'prefsreset' => 'Sākotnējās izvēles ir atjaunotas.',
+'qbsettings' => 'Rīku joslas stāvoklis',
+'changepassword' => 'Mainīt paroli',
+'skin' => 'Apdare',
+'math' => 'Matemātikas formulu attēlošana',
+'dateformat' => 'Datuma formāts',
+'datedefault' => 'Vienalga',
+'datetime' => 'Datums un laiks',
+'math_unknown_error' => 'nezināma kļūda',
+'math_unknown_function' => 'nezināma funkcija',
+'math_syntax_error' => 'sintakses kļūda',
+'prefs-personal' => 'Lietotāja dati',
+'prefs-rc' => 'Pēdējās izmaiņas',
+'prefs-watchlist' => 'Uzraugāmie raksti',
+'prefs-misc' => 'Dažādas izvēles',
+'saveprefs' => 'Saglabāt izvēles',
+'resetprefs' => 'Atjaunot sākotnējās izvēles',
+'oldpassword' => 'Vecā parole',
+'newpassword' => 'Jaunā parole',
+'retypenew' => 'Atkārto jauno paroli',
+'textboxsize' => 'Izmaiņu loga izmēri',
+'rows' => 'Rindiņas',
+'columns' => 'Simbolu skaits rindiņā',
+'searchresultshead' => 'Meklēšanas rezultātu attēlojums',
+'resultsperpage' => 'Lappusē parādāmo rezultātu skaits',
+'contextlines' => 'Cik rindiņas parādīt katram atrastajam rezultātam',
+'contextchars' => 'Konteksta simbolu skaits vienā rindiņā',
+'stubthreshold' => 'Aizmetņu izmēra slieksnis',
+'recentchangescount' => 'Virsrakstu skaits pēdējo izmaiņu lapā',
+'savedprefs' => 'Tavas izvēles ir saglabātas.',
+'timezonelegend' => 'Laika josla',
+'timezonetext' => 'Ieraksti, par cik stundām tavs vietējais laiks atšķiras no servera laika (UTC).',
+'localtime' => 'Attēlotais vietējais laiks',
+'timezoneoffset' => 'Starpība¹',
+'servertime' => 'Servera laiks šobrīd',
+'guesstimezone' => 'Izmantot datora sistēmas laiku',
+'allowemail' => 'Atļaut saņemt e-pastus no citiem lietotājiem.',
+'defaultns' => 'Meklēt šajās palīglapās pēc noklusējuma:',
+'default' => 'pēc noklusējuma',
+'files' => 'Attēli',
+'changes' => 'izmaiņas',
+'recentchanges' => 'Pēdējās izmaiņas',
+'recentchangestext' => '{{Pēdējās izmaiņas}}',
+'rcnote' => 'Šobrīd ir redzamas pēdējās <strong>$1</strong> izmaiņas, kas izdarītas {{PLURAL:$2|pēdējā|pēdējās}} <strong>$2</strong> {{PLURAL:$2|dienā|dienās}} (līdz $3).',
+'rcnotefrom' => 'Šobrīd redzamas izmaiņas kopš <b>$2</b> (parādītas ne vairāk par <b>$1</b>).',
+'rclistfrom' => 'Parādīt jaunas izmaiņas kopš $1',
+'rcshowhideminor' => '$1 maznozīmīgus',
+'rcshowhidebots' => '$1 botus',
+'rcshowhideliu' => '$1 reģistrētos',
+'rcshowhideanons' => '$1 anonīmos',
+'rcshowhidemine' => '$1 manus',
+'rclinks' => 'Parādīt pēdējās $1 izmaiņas {{PLURAL:$2|pēdējā|pēdējās}} $2 {{PLURAL:$2|dienā|dienās}}.<br />$3',
+'diff' => 'izmaiņas',
+'hist' => 'hronoloģija',
+'hide' => 'paslēpt',
+'show' => 'parādīt',
+'minoreditletter' => 'm',
+'newpageletter' => 'J',
+'sectionlink' => '→',
+'upload' => 'Augšuplādēt failu',
+'uploadbtn' => 'Augšuplādēt',
+'reupload' => 'Vēlreiz augšuplādēt',
+'reuploaddesc' => 'Atgriezties pie augšupielādes veidnes.',
+'uploadnologin' => 'Neesi iegājis',
+'uploadnologintext' => 'Tev jābūt [[Special:Userlogin|iegājušam]], lai augšuplādētu failus.',
+'uploaderror' => 'Augšupielādes kļūda',
+'uploadtext' => '\'\'\'STOP!\'\'\' Pirms tu kaut ko augšupielādē, noteikti izlasi un ievēro [[Project:Attēlu izmantošanas noteikumi|attēlu izmantošanas noteikumus]].
+
+Lai aplūkotu vai meklētu agrāk augšuplādētus attēlus,
+dodies uz [[Special:Imagelist|augšupielādēto attēlu sarakstu]].
+Augšupielādes un dzēšanas tiek reģistrētas [[Special:Log/upload|augšupielādes reģistrā]].
+
+Izmanto šo veidni, lai augšupielādētu jaunus attēlu failus, ar kuriem ilustrēt tevis izmainītās lapas.
+Gandrīz visos pārlūkos tev vajadzētu redzēt pogu \'\'\'"Choose...",\'\'\' kuru spiežot parādīsies faila atvēršanas dialogs.
+Izvēloties kādu failu, tā adrese parādīsies ailītē blakus šai pogai.
+Tev ir arī jāatzīmē ailīte, kas apstiprina, ka tu nepārkāp nekādas autortiesības, augšupielādējot šo failu.
+Spied pogu \'\'\'Augšuplādēt\'\'\', lai pabeigtu augšupielādi.
+Tas var ieilgt, ja tavs interneta pieslēgums ir lēns.
+
+Ieteicamie formāti ir:
+* JPEG - ja tā ir fotogrāfija,
+* PNG - ja tas ir zīmējums vai kāda ikona, un
+* OGG - ja tas ir skaņas fails.
+
+Lūdzu, pārliecinies, ka faila nosaukums ir pietiekami aprakstošs, lai izvairītos no neskaidrībām. Lai attēlu pēc tam ievietotu kādā lapā, izmanto šādi noformētu linkus:
+* \'\'\'<nowiki>[[{Image:Fails.jpg|paskaidrojošs teksts]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[Image:Fails.png|paskaidrojošs teksts]]</nowiki>\'\'\'
+vai skaņām
+* \'\'\'<nowiki>[[Media:Fails.ogg]]</nowiki>\'\'\'
+
+Lūdzu, ņem vērā, ka tāpat kā citas wiki lapas arī tevis augšuplādētos failus citi var mainīt vai dzēst, ja uzskata, ka tas nāktu par labu šim projektam, kā arī atceries, ka tev var tikt liegta augšupielādes iespēja, ja tu šo sistēmu.',
+'uploadlog' => 'augšupielādes reģistrs',
+'uploadlogpage' => 'Augšupielādes reģistrs',
+'uploadlogpagetext' => 'Failu augšupielādes reģistrs.',
+'filename' => 'Faila nosaukums',
+'filedesc' => 'Kopsavilkums',
+'fileuploadsummary' => 'Informācija par failu:',
+'filestatus' => 'Autortiesību statuss',
+'filesource' => 'Izejas kods',
+'copyrightpage' => 'Project:Autortiesības',
+'copyrightpagename' => '{{grammar:ģenitīvs|{{SITENAME}}}} autortiesības',
+'uploadedfiles' => 'Augšupielādēja failus',
+'ignorewarning' => 'Ignorēt brīdinājumu un saglabāt failu.',
+'ignorewarnings' => 'Ignorēt visus brīdinājumus',
+'minlength' => 'Failu vārdiem ir jābūt vismaz trīs simbolus gariem.',
+'illegalfilename' => 'Faila nosaukumā "$1" ir simboli, kas nav atļauti virsrakstos. Lūdzu, pārdēvē failu un mēģini to vēlreiz augšuplādēt.',
+'badfilename' => 'Attēla nosaukums ir nomainīts, tagad tas ir "$1".',
+'badfiletype' => 'Neiesakām izmantot ".$1" formāta attēlu failus.',
+'largefile' => 'Ieteicamais attēlu izmērs ir ne lielāks par $1 baitiem; šī attēla izmērs ir $2 baiti.',
+'largefileserver' => 'Šis fails ir lielāks nekā serveris ņem pretī.',
+'emptyfile' => 'Šķiet, ka tu esi augšuplādējis tukšu failu. Iespējams, faila nosaukumā esi pieļāvis kļūdu. Lūdzu, pārbaudi, vai tiešām tu vēlies augšuplādēt tieši šo failu.',
+'fileexists' => 'Fails ar šādu nosaukumu jau pastāv, lūdzu, pārbaudi $1, ja neesi drošs, ka vēlies to mainīt.',
+'fileexists-forbidden' => 'Fails ar šādu nosaukumu jau eksistē, mēģini kādu citu nosaukumu. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Augšupielāde veiksmīga',
+'fileuploaded' => 'Fails "$1" augšuplādēts veiksmīgi.
+Lūdzu, dodies uz šo lapu - $2 - un aizpildi faila aprakstu, piemēram, no kurienes tas fails ir, kad tas ir izveidots un kurš to izveidojis, kā arī citu informāciju par to.',
+'uploadwarning' => 'Augšupielādes brīdinājums',
+'savefile' => 'Saglabāt failu',
+'uploadedimage' => 'augšupielādēju "$1"',
+'uploaddisabled' => 'Augšupielāde atslēgta',
+'uploaddisabledtext' => 'Falu augšupielāde šajā wiki ir atslēgta.',
+'uploadcorrupt' => 'Šis fails ir bojāts, vai arī tam ir nekorekts paplašinājums. Lūdzu pārbaudi failu un augšupielādē vēlreiz.',
+'uploadvirus' => 'Šis fails satur vīrusu! Sīkāk: $1',
+'sourcefilename' => 'Augšuplādējamais fails',
+'destfilename' => 'Vajadzīgais faila nosaukums',
+'license' => 'Licence',
+'imagelist' => 'Attēlu uzskaitījums',
+'imagelisttext' => 'Šobrīd redzams $1 attēlu uzskaitījums, kas sakārtots $2.',
+'ilsubmit' => 'Meklēt',
+'showlast' => 'Parādīt pēdējos $1 attēlus, kas sakārtoti $2.',
+'byname' => '<b>pēc nosaukuma</b>',
+'bydate' => '<b>pēc datuma</b>',
+'bysize' => '<b>pēc izmēra</b>',
+'imgdelete' => 'dzēst',
+'imgdesc' => 'apraksts',
+'imglegend' => 'Apzīmējumi: (apraksts) = parādīt vai mainīt attēla aprakstu.',
+'imghistory' => 'Attēla hronoloģija',
+'revertimg' => 'atjaunot',
+'deleteimg' => 'dzēst',
+'deleteimgcompletely' => 'Dzēst visas versijas',
+'imghistlegend' => 'Apzīmējumi: (pašreizējais) = šā attēla pašreizējā versija, (dzēst) = dzēst šo veco versiju,
+(atjaunot) = nomainīt pret šo veco versiju.
+<br /><i>Klikšķini uz datuma, lai aplūkotu tajā datumā augšuplādēto failu.</i>.',
+'imagelinks' => 'Attēlu saites',
+'linkstoimage' => 'Attēls ir izmantots šajās lapās:',
+'nolinkstoimage' => 'Nevienā lapā nav norāžu uz šo attēlu.',
+'sharedupload' => 'Šis fails ir no *** [[literal]] translation',
+'noimage' => 'Ar šādu nosaukumu nav neviena faila, tu vari [$1].',
+'noimage-linktext' => 'augšuplādēt to',
+'uploadnewversion-linktext'=> 'Augšupielādēt jaunu šī faila versiju',
+'listredirects' => 'Pāradresāciju uzskaitījums',
+'statistics' => 'Statistika',
+'sitestats' => '{{grammar:ģenitīvs|{{SITENAME}}}} statistika',
+'userstats' => 'Statistika par lietotājiem',
+'sitestatstext' => 'Datubāzē kopā ir \'\'\'$1\'\'\' {{plural:$1|lapa|lapas}}, ieskaitot diskusiju lapas, lapas par {{GRAMMAR:akuzatīvs|{{SITENAME}}}}, nelielas "aizmetņu" lapas (\'\'stubs\'\'), pāradresācijas lapas, kā arī citas lapas, kuras, iespējams, nevar nosaukt par pilnvērtīgām satura lapām. Neskaitot iepriekš minētās, {{grammar:lokatīvs|{{SITENAME}}}} ir \'\'\'$2\'\'\' {{plural:$2|lapa|lapas}}, {{plural:$2|kuru|kuras}} var uzskatīt par pamatsatura {{plural:$2|lapu|lapām}}.
+
+Augšupielādēti \'\'\'$8\'\'\' faili.
+
+Kopš {{grammar:ģenitīvs|{{SITENAME}}}} izveidošanas lapas ir tikušas apskatītas \'\'\'$3\'\'\' reizes un lietotāji ir izdarījuši \'\'\'$4\'\'\' {{plural:$4|labojumu|labojumus}} (katra lapa ir labota vidēji \'\'\'$5\'\'\' reizes).
+Vidēji tas ir \'\'\'$5\'\'\' labojumi uz lapu un apskatīšanas/labojumu attiecība ir \'\'\'$6\'\'\'.
+
+The [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] length is \'\'\'$7\'\'\'.',
+'userstatstext' => 'Reģistrēto lietotāju skaits ir \'\'\'$1\'\'\'. No tiem \'\'\'$2\'\'\' (jeb \'\'\'$4%\'\'\') ir administratori (skat. $3).',
+'disambiguations' => 'Nozīmju atdalīšanas lapas',
+'disambiguationspage' => 'Template:Disambig',
+'disambiguationstext' => 'Šajās lapās ir saites uz nozīmju atdalīšanas lapām. Tās būtu jāizlabo par saitēm uz piemērotāku tēmu.<br />
+Lapu uzskata par nozīmju atdalīšanas lapu, ja uz to ir saite lapā $1.<br />
+Saites no citiem lapu veidiem (<i>namespaces</i>) <b>nav</b> šeit uzskaitītas.',
+'doubleredirects' => 'Divkāršas pāradresācijas lapas',
+'doubleredirectstext' => 'Katrā rindiņā ir saites uz pirmo un otro pāradresācijas lapu, kā arī pirmā rindiņa no otrās pāradresācijas lapas teksta, kas parasti ir faktiskā "gala" lapa, uz kuru vajadzētu būt saitei pirmajā lapā.',
+'brokenredirects' => 'Kļūdainas pāradresācijas',
+'brokenredirectstext' => 'Šīs ir pāradresācijas lapas uz neesošām lapām.',
+'nbytes' => '$1 baitu',
+'ncategories' => '$1 categories',
+'nlinks' => '$1 {{PLURAL:$1|saite|saites}}',
+'nrevisions' => '$1 {{PLURAL:$1|versija|versijas}}',
+'nviews' => '$1 views',
+'lonelypages' => 'Lapas bez saitēm uz tām',
+'uncategorizedpages' => 'Nekategorizētās lapas',
+'uncategorizedcategories'=> 'Nekategorizētās kategorijas',
+'unusedcategories' => 'Neizmantotas kategorijas',
+'unusedimages' => 'Neizmantoti attēli',
+'wantedcategories' => 'Sarkanas kategorijas',
+'wantedpages' => 'Pieprasītās lapas',
+'mostlinked' => 'Lapas, uz kurām ir visvairāk norāžu',
+'mostlinkedcategories' => 'Kategorijas, uz kurām ir visvairāk saišu',
+'mostcategories' => 'Raksti ar visvairāk kategorijām',
+'mostimages' => 'Attēli, uz kuriem ir visvairāk saišu',
+'mostrevisions' => 'Raksti, kuriem ir visvairāk iepriekšēju versiju',
+'allpages' => 'Visas lapas',
+'prefixindex' => 'Meklēt pēc virsraksta pirmajiem burtiem',
+'randompage' => 'Nejauša lapa',
+'shortpages' => 'Īsākās lapas',
+'longpages' => 'Garākās lapas',
+'deadendpages' => 'Lapas bez izejošām saitēm',
+'listusers' => 'Lietotāju uzskaitījums',
+'specialpages' => 'Īpašās lapas',
+'spheading' => 'Visiem lietotājiem pieejamās īpašās lapas',
+'recentchangeslinked' => 'Saistītās izmaiņas',
+'rclsub' => '(lapās, kurās ir norādes uz "$1")',
+'newpages' => 'Jaunas lapas',
+'ancientpages' => 'Senākās lapas',
+'move' => 'Pārvietot',
+'movethispage' => 'Pārvietot šo lapu',
+'unusedcategoriestext' => 'Šīs kategorijas eksistē, tomēr nevienā rakstā vai kategorijās tās nav izmantotas.',
+'booksources' => 'Grāmatu avoti',
+'categoriespagetext' => 'Wiki ir atrodamas šādas kategorijas.',
+'version' => 'Versija',
+'log' => 'Reģistri',
+'alllogstext' => 'Augšupielādes, dzēšanas, aizsargāšanas, bloķēšanas un adminu reģistru apvienotais reģistrs.
+Tu vari sašaurināt aplūkojamo reģistru, izvēloties reģistra veidu, lietotāja vārdu vai reģistrēto lapu.',
+'allarticles' => 'Visi raksti',
+'allpagessubmit' => 'Aiziet!',
+'allpagesprefix' => 'Parādīt lapas ar šādu virsraksta sākumu:',
+'mailnologin' => 'Nav adreses, uz kuru sūtīt',
+'mailnologintext' => 'Tev jābūt [[Special:Userlogin|iegājušam]], kā arī tev jābūt [[Special:Preferences|norādītai]] derīgai e-pasta adresei, lai sūtītu e-pastu citiem lietotājiem.',
+'emailuser' => 'Sūtīt e-pastu šim lietotājam',
+'emailpage' => 'Sūtīt e-pastu lietotājam',
+'emailpagetext' => 'Ja šis lietotājs ir norādījis reālu e-pasta adresi savu izvēļu lapā, tad ar šo veidni ir iespējams tam nosūtīt e-pastu. Tā e-pasta adrese, kuru tu esi norādījis savā izvēļu lapā, parādīsies e-pasta "From" lauciņā, tādēļ saņēmējs varēs tev atbildēt.',
+'defemailsubject' => 'E-pasts par {{grammar:akuzatīvs|{{SITENAME}}}}',
+'noemailtitle' => 'Nav e-pasta adreses',
+'noemailtext' => 'Šis lietotājs nav norādījis derīgu e-pasta adresi vai arī ir izvēlējies nesaņemt e-pastu no citiem lietotājiem.',
+'emailfrom' => 'No',
+'emailto' => 'Kam',
+'emailsubject' => 'Temats',
+'emailmessage' => 'Vēstījums',
+'emailsend' => 'Nosūtīt',
+'emailsent' => 'E-pasts nosūtīts',
+'emailsenttext' => 'Tavs e-pasts ir nosūtīts.',
+'watchlist' => 'Mani uzraugāmie raksti',
+'nowatchlist' => 'Tavā uzraugāmo rakstu sarakstā nav neviena raksta.',
+'watchlistcount' => '\'\'\'Tavā uzraugāmo sarakstā ir $1 vienumi, ieskaitot diskusiju lapas.\'\'\'',
+'clearwatchlist' => 'Tīrīt uzraugāmo sarakstu',
+'watchlistcleartext' => 'Vai esi pārliecināts, ka vēlies noņemt visus saraksta vienumus?',
+'watchlistclearbutton' => 'Tīrīt uzraugāmo sarakstu',
+'watchlistcleardone' => 'Tavs uzraugāmo rakstu saraksts tika iztīrīts. Tika izmesti $1 raksti.',
+'watchnologin' => 'Neesi iegājis',
+'watchnologintext' => 'Tev ir [[Special:Userlogin|jāieiet]], lai mainītu uzraugāmo lapu sarakstu.',
+'addedwatch' => 'Pievienots uzraugāmo sarakstam.',
+'removedwatch' => 'Lapa vairs netiek uzraudzīta',
+'removedwatchtext' => 'Lapa "$1" ir izņemta no tava uzraugāmo lapu saraksta.',
+'watch' => 'Uzraudzīt',
+'watchthispage' => 'Uzraudzīt šo lapu',
+'unwatch' => 'Neuzraudzīt',
+'unwatchthispage' => 'Pārtraukt uzraudzīšanu',
+'watchnochange' => 'Neviena no tevis uzraudzītajām lapām nav mainīta parādītajā laika posmā.',
+'watchdetails' => '* (Tu uzraugi $1 lapas, neieskaitot diskusiju lapas;
+* [[Special:Watchlist/edit|parādīt un mainīt visu sarakstu]];
+* [[Special:Watchlist/clear|Novākt visas lapas]]',
+'removechecked' => 'Izņemt no uzraugāmajām lapām',
+'watchlistcontains' => 'Tavā uzraugāmo lapu sarakstā ir $1 {{PLURAL:$1|lapa|lapas}}.',
+'watcheditlist' => 'Šajā lapā ir tevis uzraudzītās lapas, sakārtotas pēc alfabēta.<br />
+Atzīmē tās lapas, kuras tu vairs nevēlies uzraudzīt,<br />
+un klikšķini uz pogas "\'\'\'Izņemt no uzraugāmajām lapām\'\'\'".',
+'removingchecked' => 'No uzraugāmo lapu saraksta izņemam atzīmētās lapas...',
+'wlshowlast' => 'Parādīt izmaiņas pēdējo $1 stundu laikā vai $2 dienu laikā, vai arī $3.',
+'wlhideshowown' => '$1 manus labojumus.',
+'wlhideshowbots' => '$1 bot edits.',
+'deletepage' => 'Dzēst lapu',
+'confirm' => 'Apstiprināt',
+'excontent' => 'lapas saturs bija: \'$1\'',
+'excontentauthor' => 'saturs bija: "$1" (vienīgais autors: [[Special:Contributions/$2|$2]])',
+'exbeforeblank' => 'lapas saturs pirms satura dzēšanas bija šāds: \'$1\'',
+'exblank' => 'lapa bija tukša',
+'confirmdelete' => 'Apstiprināt dzēšanu',
+'deletesub' => '(Dzēst "$1")',
+'historywarning' => 'Brīdinājums: Tu dzēsīsi lapu, kurai ir saglabātas iepriekšējas versijas.',
+'confirmdeletetext' => 'Tu tūlīt no datubāzes dzēsīsi lapu vai attēlu, kā arī to iepriekšējās versijas. Lūdzu, apstiprini, ka tu tiešām to vēlies darīt, ka tu apzinies sekas un ka tu to dari saskaņā ar [[Project:Vadlīnijas|vadlīnijām]].',
+'deletedtext' => 'Lapa "$1" ir izdzēsta.
+Šeit var apskatīties pēdējos izdzēstos: "$2".',
+'deletedarticle' => 'izdzēsu "$1"',
+'dellogpage' => 'Dzēšanas reģistrs',
+'dellogpagetext' => 'Šajā lapā ir pēdējo dzēsto lapu saraksts.',
+'deletionlog' => 'dzēšanas reģistrs',
+'reverted' => 'Atjaunots uz iepriekšējo versiju',
+'deletecomment' => 'Dzēšanas iemesls',
+'rollback' => 'Novērst labojumus',
+'rollback_short' => 'Novērst',
+'rollbacklink' => 'novērst',
+'rollbackfailed' => 'Novēršana neizdevās',
+'cantrollback' => 'Nav iespējams novērst labojumu; iepriekšējais labotājs ir vienīgais lapas autors.',
+'alreadyrolled' => 'Nav iespējams novērst pēdējās izmaiņas, ko lapā [[:$1]] saglabāja [[User:$2|$2]] ([[User talk:$2|Diskusija]]). Kāds cits jau ir rediģējis šo lapu vai novērsis izmaiņas.
+
+Pēdējās izmaiņas saglabāja [[User:$3|$3]] ([[User talk:$3|diskusija]])',
+'revertpage' => 'Novērsu izmaiņas, ko izdarīja [[Special:Contributions/$2|$2]], atjaunoju versiju, ko saglabāja $1',
+'sessionfailure' => 'Ir radusies problēma ar sesijas autentifikāciju;
+šī darbība ir atcelta, lai novērstu lietotājvārda iespējami ļaunprātīgu izmantošanu.
+Lūdzu, spied "\'\'back\'\'" un atjaunini iepriekšējo lapu. Tad mēģini vēlreiz.',
+'protectlogpage' => 'Aizsargāšanas reģistrs',
+'protectedarticle' => 'aizsargāja $1',
+'unprotectedarticle' => 'atcēla aizsardzību: $1',
+'protectsub' => '(Aizsargāt "$1"?)',
+'confirmprotecttext' => 'Vai tu tiešām vēlies aizsargāt šo lapu?',
+'confirmprotect' => 'Apstiprināt aizsargāšanu',
+'protectmoveonly' => 'Aizsargāt tikai pret pārdēvēšanu',
+'protectcomment' => 'Aizsargāšanas iemesls',
+'unprotectsub' => '(Neaizsargāt "$1"?)',
+'confirmunprotecttext' => 'Vai tu tiešām vēlies atcelt šīs lapas aizsardzību?',
+'confirmunprotect' => 'Apstiprināt aizsardzības atcelšanu',
+'unprotectcomment' => 'Aizsardzības atcelšanas iemesls',
+'undelete' => 'Atjaunot dzēstu lapu',
+'undeletepage' => 'Skatīt un atjaunot dzēstās lapas',
+'undeletepagetext' => 'Šīs lapas ir dzēstas, bet ir saglabātas arhīvā. Tās ir iespējams atjaunot, bet ņemiet vērā, ka arhīvs reizēm tiek tīrīts.',
+'undeleterevisions' => '$1 {{PLURAL:$1|versija|versijas}} {{PLURAL:$1|arhivēta|arhivētas}}',
+'undeletehistory' => 'Ja tu atjauno lapu, visas versijas tiks atjaunotas tās hronoloģijā.
+Ja pēc dzēšanas ir izveidota jauna lapa ar tādu pašu nosaukumu, atjaunotās versijas tiks ievietotas lapas hronoloģijā attiecīgā secībā un konkrētās lapas pašreizējā versija netiks automātiski nomainīta.',
+'undeleterevision' => 'Versija, kas izdzēsta $1',
+'undeletebtn' => 'Atjaunot!',
+'undeletedarticle' => 'atjaunoju "$1"',
+'undeletedrevisions' => '$1 {{PLURAL:$1|versija|versijas}} {{PLURAL:$1|atjaunota|atjaunotas}}',
+'namespace' => 'Lapas veids:',
+'invert' => 'Izvēlēties pretēji',
+'contributions' => 'Lietotāja devums',
+'mycontris' => 'Mans devums',
+'contribsub' => 'Lietotājs: $1',
+'nocontribs' => 'Netika atrastas izmaiņas, kas atbilstu šiem kritērijiem.',
+'uctop' => '(pēdējā izmaiņa)',
+'sp-contributions-newest'=> 'jaunākās',
+'sp-contributions-oldest'=> 'senākās',
+'sp-contributions-newer'=> 'jaunākas $1',
+'sp-contributions-older'=> 'senākas $1',
+'whatlinkshere' => 'Norādes uz šo rakstu',
+'linklistsub' => '(Saišu uzskaitījums)',
+'linkshere' => 'Šajās lapās ir norādes uz šo lapu:',
+'nolinkshere' => 'Nevienā lapā nav norāžu uz šo lapu.',
+'isredirect' => 'pāradresācijas lapa',
+'istemplate' => 'izsaukts',
+'blockip' => 'Bloķēt lietotāju',
+'blockiptext' => 'Šo veidni izmanto, lai bloķētu kādas IP adreses vai lietotājvārda piekļuvi wiki lapu saglabāšanai. Dari to tikai, lai novērstu vandālismu atbilstoši [[Project:Vadlīnijas|noteikumiem]].
+Norādi konkrētu iemeslu (piemēram, linkus uz vandalizētajām lapām).',
+'ipaddress' => 'IP adrese/lietotājvārds',
+'ipadressorusername' => 'IP adrese vai lietotājvārds',
+'ipbexpiry' => 'Termiņš',
+'ipbreason' => 'Iemesls',
+'ipbsubmit' => 'Bloķēt šo lietotāju',
+'ipbother' => 'Cits laiks',
+'ipboptions' => '2 stundas:2 hours,1 diena:1 day,3 dienas:3 days,1 nedēļa:1 week,2 nedēļas:2 weeks,1 mēnesis:1 month,3 mēneši:3 months,6 mēneši:6 months,1 gads:1 year,uz nenoteiktu laiku:infinite',
+'ipbotheroption' => 'cits',
+'badipaddress' => 'Nederīga IP adrese',
+'blockipsuccesssub' => 'Nobloķēts veiksmīgi',
+'ipblocklist' => 'Bloķēto IP adrešu un lietotājvārdu uzskaitījums',
+'blocklistline' => '$1 $2 bloķēja $3 (termiņš $4)',
+'blocklink' => 'bloķēt',
+'unblocklink' => 'atbloķēt',
+'contribslink' => 'devums',
+'blocklogpage' => 'Bloķēšanas reģistrs',
+'ipb_expiry_invalid' => 'Nederīgs beigu termiņš',
+'ip_range_invalid' => 'Nederīgs IP diapazons',
+'proxyblocker' => 'Starpniekservera bloķētājs',
+'proxyblocksuccess' => 'Darīts.',
+'movepage' => 'Pārvietot lapu',
+'movepagetext' => 'Šajā lapā tu vari pārdēvēt vai pārvietot lapu, kopā tās izmaiņu hronoloģiju pārvietojot to uz citu nosaukumu.
+Iepriekšējā lapa kļūs par lapu, kas pāradresēs uz jauno lapu.
+Saites uz iepriekšējo lapu netiks mainītas, bet noteikti pārbaudi un izlabo, izskaužot dubultu pāradresāciju vai pāradresāciju uz neesošu lapu.
+Tev ir jāpārliecinās, vai saites vēl aizvien ved tur, kur tās ir paredzētas.
+
+Ņem vērā, ka lapa \'\'\'netiks\'\'\' pārvietota, ja jau eksistē kāda cita lapa ar vēlamo nosaukumu (izņemot gadījumus, kad tā ir tukša vai kad tā ir pāradresācijas lapa, kā arī tad, ja tai nav izmaiņu hronoloģijas). Tas nozīmē, ka tu vari pārvietot lapu atpakaļ, no kurienes tu jau reiz to esi pārvietojis, ja būsi kļūdījies, bet tu nevari pārrakstīt jau esošu lapu.
+
+<b>BRĪDINĀJUMS!</b>
+Populārām lapām tā var būt krasa un negaidīta pārmaiņa; pirms turpināšanas vēlreiz pārdomā, vai tu izproti visas iespējamās sekas.',
+'movepagetalktext' => 'Saistītā diskusiju lapa, ja tāda eksistē, tiks automātiski pārvietota, \'\'\'izņemot gadījumus, kad\'\'\':
+*tu pārvieto lapu uz citu palīglapu (piemēram, [[Project talk:{{SITENAME}}]] uz [[Project:{{SITENAME}}]]),
+*ar jauno nosaukumu jau eksistē diskusiju lapa, vai arī
+*atzīmēsi zemāk atrodamo lauciņu.
+
+Ja tomēr vēlēsies, tad tev šī diskusiju lapa būs jāpārvieto vai jāapvieno pašam.',
+'movearticle' => 'Pārvietot lapu',
+'movenologin' => 'Neesi iegājis kā reģistrēts lietotājs',
+'movenologintext' => 'Tev ir jābūt reģistrētam lietotājam un jābūt [[Special:Userlogin|iegājušam]] {{grammar:lokatīvs|{{SITENAME}}}}, lai pārvietotu lapu.',
+'newtitle' => 'Uz šādu lapu',
+'movepagebtn' => 'Pārvietot lapu',
+'pagemovedsub' => 'Pārvietošana notikusi veiksmīgi',
+'pagemovedtext' => 'Lapa "[[$1]]" ir pārvietota uz "[[$2]]".
+
+
+\'\'\'Lūdzu [[Special:Whatlinkshere/$2|pārbaudi]]\'\'\', vai šī pārvietošana nav radījusi [[Project:Dubulta pāradresācija|dubultu pāradresāciju]] un pēc vajadzības izlabo to.',
+'articleexists' => 'Lapa ar tādu nosaukumu jau pastāv vai arī tevis izvēlētais nosaukums ir nederīgs. Lūdzu, izvēlies citu nosaukumu.',
+'movedto' => 'pārvietota uz',
+'movetalk' => 'Pārvietot arī diskusiju lapu, ja tāda ir.',
+'talkpagemoved' => 'Tika pārvietota arī atbilstošā diskusiju lapa.',
+'talkpagenotmoved' => 'Atbilstošā diskusiju lapa <strong>netika</strong> pārvietota.',
+'1movedto2' => '"[[$1]]" pārdēvēju par "[[$2]]"',
+'1movedto2_redir' => '$1 pārdēvēju par $2, izmantojot pāradresāciju',
+'movelogpage' => 'Pārvietošanas reģistrs',
+'movelogpagetext' => 'Lapu pārvietošanas (pārdēvēšanas) reģistrs.',
+'movereason' => 'Iemesls',
+'revertmove' => 'atcelt',
+'export' => 'Eksportēt lapas',
+'allmessages' => 'Visi sistēmas paziņojumi',
+'allmessagesname' => 'Nosaukums',
+'allmessagesdefault' => 'Sākotnējais teksts',
+'allmessagescurrent' => 'Pašreizējais teksts',
+'allmessagestext' => 'Šajā lapā ir visu "\'\'\'Mediawiki:\'\'\'" lapās atrodamo sistēmas paziņojumu uzskaitījums.',
+'allmessagesnotsupportedUI'=> 'Your current interface language <b>$1</b> is not supported by special:Allmessages at this site.',
+'allmessagesnotsupportedDB'=> 'special:Allmessages not supported because wgUseDatabaseMessages is off.',
+'thumbnail-more' => 'Palielināt',
+'missingimage' => '<b>Trūkst attēla</b><br /><i>$1</i>',
+'filemissing' => 'Trūkst faila',
+'tooltip-search' => 'Meklēt šajā wiki [alt-f]',
+'tooltip-minoredit' => 'Atzīmēt šo par maznozīmīgu labojumu [alt-i]',
+'tooltip-save' => 'Saglabāt veiktās izmaiņas [alt-s]',
+'tooltip-preview' => 'Parādīt izmaiņu priekšskatījumu. Lūdzam izmantot šo iespēju pirms saglabāšanas. [alt-p]',
+'tooltip-diff' => 'Parādīt, kā esi izmainījis tekstu. [alt-v]',
+'tooltip-compareselectedversions'=> 'Aplūkot atšķirības starp divām izvēlētajām lapas versijām. [alt-v]',
+'tooltip-watch' => 'Pievienot šo lapu uzraugāmo lapu sarakstam [alt-w]',
+'siteuser' => '{{grammar:ģenitīvs|{{SITENAME}}}} lietotājs $1',
+'and' => 'un',
+'subcategorycount' => 'Šajā kategorijā ir $1 {{PLURAL:$1|apakškategorija|apakškategorijas}}.',
+'categoryarticlecount' => 'Šajā kategorijā ir $1 {{PLURAL:$1|raksts|raksti}}.',
+'listingcontinuesabbrev'=> ' (turpinājums)',
+'mw_math_png' => 'Vienmēr attēlot PNG',
+'mw_math_simple' => 'HTML, ja ļoti vienkārši, vai arī PNG',
+'mw_math_html' => 'HTML, ja iespējams, vai arī PNG',
+'mw_math_source' => 'Saglabāt kā TeX (teksta pārlūkiem)',
+'mw_math_modern' => 'Moderniem pārlūkiem ieteiktais variants',
+'mw_math_mathml' => 'MathML, ja iespējams (eksperimentāla iespēja)',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Mana lietotāja lapa\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Manas IP adreses lietotāja lapa\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Mana diskusiju lapa\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskusija par labojumiem, kas izdarīti no šīs IP adreses\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Manas izvēles\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Manis uzraudzītās lapas.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Mani ieguldījumi\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Aicinām tevi ieiet {{grammar:lokatīvs|{{SITENAME}}}}, tomēr tas nav obligāti.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Aicinām tevi ieiet {{grammar:lokatīvs|{{SITENAME}}}}, tomēr tas nav obligāti.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Iziet\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskusija par šī raksta lapu\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Izmainīt šo lapu. Lūdzam izmantot pirmskatu pirms lapas saglabāšanas.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Pievienot komentāru šai diskusijai.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Šī lapa ir aizsargāta. Tu vari apskatīties tās izejas kodu.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Šīs lapas iepriekšējās versijas.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Aizsargāt šo lapu\');
+ ta[\'ca-delete\'] = new Array(\'v\',\'Dzēst šo lapu\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Atjaunot labojumus, kas izdarīti šajā lapā pirms lapas dzēšanas.\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Pārvietot šo lapu\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Tev nav pietiekamu privilēģiju, lai pārvietotu šo lapu.\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Pievienot šo lapu manis uzraudzītajām lapām\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Izņemt šo lapu no uzraudzītajām lapām\');
+ ta[\'search\'] = new Array(\'f\',\'Meklēt šajā wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Sākumlapa\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Iet uz sākumlapu\');
+ ta[\'n-portal\'] = new Array(\'\',\'Par šo projektu, par to, ko tu vari šeit darīt un kur ko atrast\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Uzzini papildinformāciju par šobrīd aktuālajiem notikumiem\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Izmaiņas, kas nesen izdarītas šajā wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Iet uz nejauši izvēlētu lapu\');
+ ta[\'n-help\'] = new Array(\'\',\'Vieta, kur uzzināt.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Atbalsti mūs\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Visas wiki lapas, kurās ir saites uz šejieni\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Izmaiņas, kas nesen izdarītas lapās, kurās ir saites uz šo lapu\');
+ ta[\'feed-rss\'] = new Array(\'\',\'Šīs lapas RSS barotne\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Šīs lapas Atom barotne\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Apskatīt šā lietotāja ieguldījumu uzskaitījumu.\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Sūtīt e-pastu šim lietotājam\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Augšuplādēt attēlus vai multimēdiju failus\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Visu īpašo lapu uzskaitījums\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Apskatīt rakstu\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Apskatīt lietotāja lapu\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Apskatīt multimēdiju lapu\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Šī ir īpašā lapa, tu nevari izmainīt pašu lapu.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Apskatīt projekta lapu\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Apskatīt attēla lapu\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Apskatīt sistēmas paziņojumu\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Apskatīt veidni\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Apskatīt palīdzības lapu\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Apskatīt kategorijas lapu\');',
+'previousdiff' => '← Salīdzināt ar iepriekšējo versiju',
+'nextdiff' => 'Salīdzināt ar nākamo versiju →',
+'imagemaxsize' => 'Attēlu apraksta lappusēs parādāmo attēlu maksimālais izmērs:',
+'thumbsize' => 'Sīkbildes (thumbnail) izmērs:',
+'showbigimage' => 'Lejuplādē augstas izšķirtspējas attēlu ($1x$2, $3 KB)',
+'newimages' => 'Jauno attēlu galerija',
+'showhidebots' => '($1 botus)',
+'noimages' => 'Nav nekā ko redzēt.',
+'specialloguserlabel' => 'Lietotājs:',
+'speciallogtitlelabel' => 'Virsraksts:',
+'passwordtooshort' => 'Tava parole ir pārāk īsa. Tajā jābūt vismaz $1 zīmēm.',
+'metadata-expand' => 'Parādīt papildu detaļas',
+'metadata-collapse' => 'Paslēpt papildu detaļas',
+'exif-imagewidth' => 'platums',
+'exif-imagelength' => 'augstums',
+'exif-bitspersample' => 'biti komponentē',
+'exif-compression' => 'Saspiešanas veids',
+'exif-xresolution' => 'Horizontālā izšķirtspēja',
+'exif-yresolution' => 'Vertikālā izšķirtspēja',
+'exif-pixelxdimension' => 'Valind image height',
+'edit-externally' => 'Izmainīt šo failu ar ārēju programmu',
+'edit-externally-help' => 'Skat. [http://meta.wikimedia.org/wiki/Help:External_editors instrukcijas] Meta-Wiki, lai iegūtu vairāk informācijas.',
+'recentchangesall' => 'visi',
+'imagelistall' => 'visas',
+'watchlistall1' => 'visas',
+'watchlistall2' => 'visas',
+'namespacesall' => 'visas',
+'confirmemail' => 'Apstiprini e-pasta adresi',
+'confirmemail_text' => 'Šajā wiki ir nepieciešams apstiprināt savu e-pasta adresi, lai izmantotu e-pasta funkcijas. Spied uz zemāk esošās pogas, lai uz tavu e-pasta adresi nosūtītu apstiprināšanas e-pastu. Tajā būs saite ar kodu; spied uz tās saites vai atver to savā interneta pārlūkā, lai apstiprinātu tavas e-pasta adreses derīgumu.',
+'confirmemail_send' => 'Nosūtīt apstiprināšanas kodu',
+'confirmemail_sent' => 'Apstiprināšanas e-pasts nosūtīts.',
+'confirmemail_sendfailed'=> 'Nevarējām nosūtīt apstiprināšanas e-pastu. Pārbaudi, vai adresē nav kāds nepareizs simbols.',
+'confirmemail_invalid' => 'Nederīgs apstiprināšanas kods. Iespējams, beidzies tā termiņš.',
+'confirmemail_success' => 'Tava e-pasta adrese ir apstiprināta. Tagad vari doties iekšā ar savu lietotājvārdu un pilnvērtīgi izmantot wiki iespējas.',
+'confirmemail_loggedin' => 'Tava e-pasta adrese tagad ir apstiprināta.',
+'confirmemail_error' => 'Notikusi kāda kļūme ar tava apstiprinājuma saglabāšanu.',
+'confirmemail_subject' => 'E-pasta adreses apstiprinajums no {{grammar:ģenitīvs|{{SITENAME}}}}',
+'confirmemail_body' => 'Kads, iespejams, tu pats, no IP adreses $1 ir registrejis {{grammar:ģenitīvs|{{SITENAME}}}} lietotaja vardu "$2" ar so e-pasta adresi.
+
+Lai apstiprinatu, ka so lietotaja vardu esi izveidojis tu pats, un aktivizetu e-pasta izmantosanu {{SITENAME}}, atver so saiti sava interneta parluka:
+
+$3
+
+Ja tu *neesi* registrejis sadu lietotaja vardu, nespied uz saites. Si apstiprinajuma kods deriguma termins ir $4.',
+'createarticle' => 'Izveidot rakstu',
+'scarytranscludedisabled'=> '[Starpviki saišu iekļaušana ir atspējota.]',
+'scarytranscludefailed' => '[Atvaino, neizdevās ienest veidni $1.]',
+'scarytranscludetoolong'=> '[Atvaino, URL adrese ir pārāk gara.]',
+'searchcontaining' => 'Meklēt rakstus, kas satur \'\'$1\'\'.',
+'searchnamed' => 'Meklēt rakstus ar nosaukumu \'\'$1\'\'.',
+'articletitles' => 'Raksti, kas sākas ar \'\'$1\'\'',
+'hideresults' => 'Paslēpt rezultātus',
+);
+?>
diff --git a/languages/messages/MessagesMi.php b/languages/messages/MessagesMi.php
new file mode 100644
index 000000000000..d8d12d9979b3
--- /dev/null
+++ b/languages/messages/MessagesMi.php
@@ -0,0 +1,111 @@
+<?php
+/** Maori (Māori)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$messages = array(
+# Dates
+'sunday' => 'Rātapu',
+'monday' => 'Rāhina',
+'tuesday' => 'Rātū',
+'wednesday' => 'Rāapa',
+'thursday' => 'Rāpare',
+'friday' => 'Rāmere',
+'saturday' => 'Rāhoroi',
+'january' => 'Kohi-tātea',
+'february' => 'Hui-tanguru',
+'march' => 'Poutū-te-rangi',
+'april' => 'Paenga-whāwhā',
+'may_long' => 'Haratua',
+'june' => 'Pipiri',
+'july' => 'Hōngongoi',
+'august' => 'Here-turi-kōkā',
+'september' => 'Mahuru',
+'october' => 'Whiringa-ā-nuku',
+'november' => 'Whiringa-ā-rangi',
+'december' => 'Hakihea',
+
+'mainpage' => 'Hau Kāinga',
+
+'portal' => 'Tomokanga hapori',
+'portal-url' => 'Project:Tomokanga hapori',
+'help' => 'Whakamārama',
+'sitesupport' => 'Koha',
+'cancel' => 'Whakakore',
+'qbspecialpages' => 'Whārangi motuhake',
+'mytalk' => 'Karere mōku',
+'navigation' => 'Huarahi',
+
+'currentevents' => 'Kōrero',
+'currentevents-url' => 'Project:Kōrero',
+
+'search' => 'Rapua',
+'go' => 'Haere',
+'history' => 'Kōrero Nehe',
+'history_short' => 'Tuhinga/kaituhi',
+'printableversion' => 'Tāia',
+'permalink' => 'Hononga toitū',
+'edit' => 'Whakatika',
+'delete' => 'tangohia',
+'protect' => 'Whakangungua',
+'talk' => 'Kōrerorero',
+'toolbox' => 'Pouaka utauta',
+
+'toc' => 'Rārangi kōrero',
+'showtoc' => 'whakakite',
+'hidetoc' => 'hunaia',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'tuhi pānui',
+'nstab-template' => 'papa tauira',
+'nstab-help' => 'Āwhina',
+'nstab-category' => 'Wāhanga',
+
+# Login and logout pages
+'userlogout' => 'Whakarere',
+
+# Edit pages
+'savearticle' => 'Tiaki',
+'showdiff' => 'Tiro rerekētanga',
+
+# Preferences page
+'preferences' => 'Kōwhiringa',
+
+# Recent changes
+'recentchanges' => 'Rerekētanga hōu',
+'hide' => 'Hunaia',
+'show' => 'Whakaaturia',
+
+# Upload
+'upload' => 'Tuku atu',
+
+# Miscellaneous special pages
+'allpages' => 'Ngā whārangi katoa',
+'randompage' => 'Tipihaere',
+'specialpages' => 'Whārangi motuhake',
+'recentchangeslinked' => 'Rerekētanga pū tahi',
+'move' => 'Nekehia',
+
+# Special:Allpages
+'allpagessubmit' => 'Haere',
+
+# Watchlist
+'watchlist' => 'Rārangi mātaki',
+'watch' => 'Mātaki',
+'unwatch' => 'kāti te mātaki',
+
+# Contributions
+'contributions' => 'Ngā mahi a tēnei mema',
+'mycontris' => 'āku mahi',
+
+# What links here
+'whatlinkshere' => 'Ngā hononga mai',
+
+# Namespace 8 related
+'allmessages' => 'Pānui pūnaha',
+
+);
+
+?>
diff --git a/languages/messages/MessagesMk.php b/languages/messages/MessagesMk.php
new file mode 100644
index 000000000000..29a7dfe7db09
--- /dev/null
+++ b/languages/messages/MessagesMk.php
@@ -0,0 +1,1709 @@
+<?php
+/** Macedonian (Македонски)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Без мени', 'Фиксирано лево', 'Фиксирано десно', 'Пловечко лево'
+);
+
+$skinNames = array(
+ 'standard' => 'Класика',
+ 'nostalgia' => 'Носталгија',
+ 'cologneblue' => 'Келнско сино',
+ 'davinci' => 'ДаВинчи',
+ 'mono' => 'Моно',
+ 'monobook' => 'Monobook',
+ 'myskin' => 'Моја маска',
+ 'chick' => 'Шик'
+);
+
+$magicWords = array(
+ 'redirect' => array( 0, '#redirect', '#пренасочување', '#види' ),
+ 'notoc' => array( 0, '__NOTOC__', '__БЕЗСОДРЖИНА__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__СОСОДРЖИНА__' ),
+ 'toc' => array( 0, '__TOC__', '__СОДРЖИНА__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__' , '__БЕЗ_УРЕДУВАЊЕ_НА_СЕКЦИИ__'),
+ 'start' => array( 0, '__START__' , '__ПОЧЕТОК__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'СЕГАШЕНМЕСЕЦ' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'СЕГАШЕНМЕСЕЦИМЕ' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'СЕГАШЕНМЕСЕЦИМЕРОД' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'СЕГАШЕНМЕСЕЦСКР' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'СЕГАШЕНДЕН' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'СЕГАШЕНДЕНИМЕ' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'СЕГАШНАГОДИНА' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'СЕГАШНОВРЕМЕ' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'БРОЈСТАТИИ' ),
+ 'pagename' => array( 1, 'PAGENAME', 'СТРАНИЦА' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'СТРАНИЦАИ' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'ИМЕПРОСТОР' ),
+ 'subst' => array( 0, 'SUBST:', 'ЗАМЕСТ:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'ИЗВЕШТNW:' ),
+ 'end' => array( 0, '', '__КРАЈ__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'мини' ),
+ 'img_right' => array( 1, 'right', 'десно', 'д' ),
+ 'img_left' => array( 1, 'left', 'лево', 'л' ),
+ 'img_none' => array( 1, 'none', 'н' ),
+ 'img_width' => array( 1, '$1px', '$1пкс' , '$1п' ),
+ 'img_center' => array( 1, 'center', 'centre', 'центар', 'ц' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'рамка', 'ворамка' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'ИМЕНАСАЈТ' ),
+ 'ns' => array( 0, 'NS:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'ЛОКАЛНААДРЕСА:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'ЛОКАЛНААДРЕСАИ:' ),
+ 'server' => array( 0, 'SERVER', 'СЕРВЕР' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'ГРАМАТИКА:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'СЕГАШНАСЕДМИЦА'),
+ 'currentdow' => array( 1, 'CURRENTDOW' ),
+ 'revisionid' => array( 1, 'REVISIONID' ),
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Медија',
+ NS_SPECIAL => 'Специјални',
+ NS_MAIN => '',
+ NS_TALK => 'Разговор',
+ NS_USER => 'Корисник',
+ NS_USER_TALK => 'Разговор_со_корисник',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Разговор_за_$1',
+ NS_IMAGE => 'Слика',
+ NS_IMAGE_TALK => 'Разговор_за_слика',
+ NS_MEDIAWIKI => 'МедијаВики',
+ NS_MEDIAWIKI_TALK => 'Разговор_за_МедијаВики',
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Разговор_за_шаблон',
+ NS_HELP => 'Помош',
+ NS_HELP_TALK => 'Разговор_за_помош',
+ NS_CATEGORY => 'Категорија',
+ NS_CATEGORY_TALK => 'Разговор_за_категорија',
+);
+
+$linkTrail = '/^([a-zабвгдѓежзѕијклљмнњопрстќуфхцчџш]+)(.*)$/sDu';
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+$messages = array(
+'tog-underline' => 'Потцртај ги врските',
+'tog-highlightbroken' => 'Покажи ги неправилните врски <a href="" class="new">вака</a> (алтернативно: вака<a href="" class="internal">?</a>).',
+'tog-justify' => 'Двостранично порамнување на параграфите',
+'tog-hideminor' => 'Сокриј ги ситните уредувања во скорешните промени',
+'tog-extendwatchlist' => 'Прошири ја листа на набљудувања за да ги прикаже сите можни промени',
+'tog-usenewrc' => 'Подобри ги скорешните промени (JavaScript)',
+'tog-numberheadings' => 'Нумерирај ги заглавијата',
+'tog-showtoolbar' => 'Алатник за уредување (JavaScript)',
+'tog-editondblclick' => 'Уредување при двојно кликнување (JavaScript)',
+'tog-editsection' => 'Овозможи уредување на секција преку (уредување) врски',
+'tog-editsectiononrightclick'=> 'Овозможи уредување при десен клик<br /> на насловите на секциите (JavaScript)',
+'tog-showtoc' => 'Покажи содржина<br />(за страници со повеќе од 3 заглавија)',
+'tog-rememberpassword' => 'Запомни ја лозинката меѓу сесии',
+'tog-editwidth' => 'Максимална ширина на кутијата за уредување',
+'tog-watchcreations' => 'Додади ги страниците што ги креирам јас во мојата набљудувана листа',
+'tog-watchdefault' => 'Додади ги страниците што ги уредуваш во набљудувани страници',
+'tog-minordefault' => 'Обележи ги сите уредувања како ситни по основно',
+'tog-previewontop' => 'Прикажи го прегледот пред кутијата за уредување, а не после неа',
+'tog-previewonfirst' => 'Прикажи преглед на првото уредување',
+'tog-nocache' => 'Без складирање на страниците',
+'tog-enotifwatchlistpages'=> 'Испрати ми е-пошта при промена на страницата',
+'tog-enotifusertalkpages'=> 'Испрати ми е-пошта при промена на мојата страница за разговор',
+'tog-enotifminoredits' => 'Испрати ми, исто така, е-пошта за ситни промени на страници',
+'tog-enotifrevealaddr' => 'Откриј ја мојата е-поштенска адреса во пораките за известување',
+'tog-shownumberswatching'=> 'Прикажи го бројот на корисници кои набљудуваат',
+'tog-fancysig' => 'Чист потпис (без автоматска врска)',
+'tog-externaleditor' => 'Користи надворешен уредувач по основно',
+'tog-externaldiff' => 'Користи надворешна програма за разлики по основно',
+'tog-showjumplinks' => 'Овозможи „скокни до“ врски на пристапност',
+'tog-uselivepreview' => 'Користи преглед во живо (JavaScript) (Експериментално)',
+'tog-autopatrol' => 'Моите промени означи ги како проверени',
+'tog-forceeditsummary' => 'Извести ме кога нема опис на промените',
+'tog-watchlisthideown' => 'Сокриј ги моите уредувања од набљудуваната листа',
+'tog-watchlisthidebots' => 'Сокриј промени од ботови во набљудуваната листа',
+'underline-always' => 'Секогаш',
+'underline-never' => 'Никогаш',
+'underline-default' => 'Според прилагодувањата на прелистувачот',
+'skinpreview' => '(Прегледај)',
+'sunday' => 'недела',
+'monday' => 'понеделник',
+'tuesday' => 'вторник',
+'wednesday' => 'среда',
+'thursday' => 'четврток',
+'friday' => 'петок',
+'saturday' => 'сабота',
+'sun' => 'нед',
+'mon' => 'пон',
+'tue' => 'вто',
+'wed' => 'сре',
+'thu' => 'чет',
+'fri' => 'пет',
+'sat' => 'саб',
+'january' => 'јануари',
+'february' => 'февруари',
+'march' => 'март',
+'april' => 'април',
+'may_long' => 'мај',
+'june' => 'јуни',
+'july' => 'јули',
+'august' => 'август',
+'september' => 'септември',
+'october' => 'октомври',
+'november' => 'ноември',
+'december' => 'декември',
+'january-gen' => 'јануари',
+'february-gen' => 'февруари',
+'march-gen' => 'март',
+'april-gen' => 'април',
+'may-gen' => 'мај',
+'june-gen' => 'јуни',
+'july-gen' => 'јули',
+'august-gen' => 'август',
+'september-gen' => 'септември',
+'october-gen' => 'октомври',
+'november-gen' => 'ноември',
+'december-gen' => 'декември',
+'jan' => 'јан',
+'feb' => 'фев',
+'mar' => 'мар',
+'apr' => 'апр',
+'may' => 'мај',
+'jun' => 'јун',
+'jul' => 'јул',
+'aug' => 'авг',
+'sep' => 'сеп',
+'oct' => 'окт',
+'nov' => 'ное',
+'dec' => 'дек',
+'categories' => 'Категории',
+'pagecategories' => '{{PLURAL:$1|Категорија|Категории}}',
+'category_header' => 'Статии во категоријата "$1"',
+'subcategories' => 'Подкатегории',
+'mainpage' => 'Главна страница',
+'mainpagetext' => 'Вики софтверот е успешно инсталиран.',
+'mainpagedocfooter' => 'Ве молиме, видете ја [http://meta.wikimedia.org/wiki/MediaWiki_i18n документацијата] и [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide водичот] за подетална информација односно МедијаВики. Актуелната верзија на македонската јазична датотека можете да најдете на [http://meta.wikimedia.org/wiki/LanguageMk.php Мета].',
+'portal' => 'Портал',
+'portal-url' => 'Project:Портал',
+'about' => 'За',
+'aboutsite' => 'За {{SITENAME}}',
+'aboutpage' => 'Project:За {{SITENAME}}',
+'article' => 'Статија',
+'help' => 'Помош',
+'helppage' => 'Help:Содржина',
+'bugreports' => 'Извештаи за грешки',
+'bugreportspage' => 'Project:Извештаи за грешки',
+'sitesupport' => 'Донации',
+'sitesupport-url' => 'Project:Поддршка',
+'faq' => 'ЧПП',
+'faqpage' => 'Project:ЧПП',
+'edithelp' => 'Помош за уредување',
+'newwindow' => '(се отвара во нов прозорец)',
+'edithelppage' => 'Help:Како се уредуваат страници',
+'cancel' => 'Откажи',
+'qbfind' => 'Најди',
+'qbbrowse' => 'Прелистај',
+'qbedit' => 'Уреди',
+'qbpageoptions' => 'Оваа страница',
+'qbpageinfo' => 'Информации за страницата',
+'qbmyoptions' => 'Моите страници',
+'qbspecialpages' => 'Специјални страници',
+'moredotdotdot' => 'Повеќе...',
+'mypage' => 'Мојата страница',
+'mytalk' => 'Мојот разговор',
+'anontalk' => 'Разговор за таа IP адреса',
+'navigation' => 'Навигација',
+'metadata_help' => 'Метаподатоци (видете [[Project:Метаподатоци]] за објаснување):',
+'currentevents' => 'Тековни настани',
+'currentevents-url' => 'Project:Тековни настани',
+'disclaimers' => 'Услови на употреба',
+'disclaimerpage' => 'Project:Услови на употреба',
+'privacy' => 'Заштита на личните податоци',
+'privacypage' => 'Project:Заштита на личните податоци',
+'errorpagetitle' => 'Грешка',
+'returnto' => 'Врати се на $1.',
+'tagline' => 'Од {{SITENAME}}',
+'search' => 'Пребарај',
+'searchbutton' => 'Пребарај',
+'go' => 'Оди',
+'searcharticle' => 'Оди',
+'history' => 'Историја на страницата',
+'history_short' => 'Историја',
+'updatedmarker' => 'ажурирано од мојата последна посета',
+'info_short' => 'Информација',
+'printableversion' => 'Верзија за печатење',
+'permalink' => 'Перманентна врска',
+'print' => 'Печати',
+'edit' => 'Уреди',
+'editthispage' => 'Уреди ја оваа страница',
+'delete' => 'Избриши',
+'deletethispage' => 'Избриши ја оваа страница',
+'undelete_short' => 'Враќање на {{PLURAL:$1|едно избришано уредување|$1 избришани уредувања}}',
+'protect' => 'Заштити',
+'protectthispage' => 'Заштити ја оваа страница',
+'unprotect' => 'Отстрани ја заштитата',
+'unprotectthispage' => 'Отстрани ја заштитата на оваа страница',
+'newpage' => 'Нова страница',
+'talkpage' => 'Дискутирај за оваа страница',
+'specialpage' => 'Специјална страница',
+'personaltools' => 'Лични алатки',
+'postcomment' => 'Испрати коментар',
+'articlepage' => 'Види статија',
+'talk' => 'Разговор',
+'views' => 'Прегледи',
+'toolbox' => 'Алатник',
+'userpage' => 'Види ја страницата на корисникот',
+'projectpage' => 'Види ја страницата на проектот',
+'imagepage' => 'Види ја страницата на сликата',
+'mediawikipage' => 'Види ја страницата за порака',
+'templatepage' => 'Види ја страницата на шаблонот',
+'viewhelppage' => 'Види ја страницата за помош',
+'categorypage' => 'Види ја страницата за категорија',
+'viewtalkpage' => 'Видете го разговорот',
+'otherlanguages' => 'Други јазици',
+'redirectedfrom' => '(Пренасочено од $1)',
+'autoredircomment' => 'Пренасочување кон [[$1]]',
+'redirectpagesub' => 'Страница за пренасочување',
+'lastmodifiedat' => 'Оваа страница последен пат е изменета на $2, $1.',
+'viewcount' => 'Оваа страница била посетена {{plural:$1|еднаш|$1 пати}}.',
+'copyright' => 'Сите текстови се достапни под условите на $1.',
+'protectedpage' => 'Заштитена страница',
+'jumpto' => 'Скокни на:',
+'jumptonavigation' => 'навигација',
+'jumptosearch' => 'барај',
+'badaccess' => 'Грешка во пермисии',
+'badaccess-group0' => 'Немате дозвола да ја извршите бараната акција.',
+'badaccess-group1' => 'Акцијата што ја баравте е ограничена само на корисниците во групата $1.',
+'badaccess-group2' => 'Акцијата што ја баравте е ограничена само на корисниците во една од групите $1.',
+'badaccess-groups' => 'Акцијата што ја баравте е ограничена само на корисниците во една од групите $1.',
+'versionrequired' => 'Верзијата $1 од МедијаВики е задолжителна',
+'versionrequiredtext' => 'Мора да имате верзија $1 од МедијаВики за да ја користите оваа страница. Видете [[Special:Version]]',
+'ok' => 'Во ред',
+'retrievedfrom' => 'Преземено од "$1"',
+'youhavenewmessages' => 'Имате $1 ($2).',
+'newmessageslink' => 'нови пораки',
+'newmessagesdifflink' => 'разлики со последната видена верзија',
+'editsection' => 'уреди',
+'editold' => 'уреди',
+'editsectionhint' => 'Уредување на секција: $1',
+'toc' => 'Содржина',
+'showtoc' => 'прикажи',
+'hidetoc' => 'сокриј',
+'thisisdeleted' => 'Погледни или врати $1?',
+'viewdeleted' => 'Прегледај $1?',
+'restorelink' => '$1 избришани промени',
+'feedlinks' => 'Фид:',
+'feed-invalid' => 'Лош тип на фид пријава',
+'nstab-main' => 'Статија',
+'nstab-user' => 'Корисник',
+'nstab-media' => 'Медија',
+'nstab-special' => 'Специјална страница',
+'nstab-project' => 'проект',
+'nstab-image' => 'Слика',
+'nstab-mediawiki' => 'МедијаВики',
+'nstab-template' => 'Шаблон',
+'nstab-help' => 'Помош',
+'nstab-category' => 'Категорија',
+'nosuchaction' => 'Не постои таква функција',
+'nosuchactiontext' => 'Функцијата од УРЛ-то не е подржана од Вики',
+'nosuchspecialpage' => 'Не постои таква специјална страница',
+'nospecialpagetext' => 'Баравте невалидна [[Special:Specialpages|специјална страница]].',
+'error' => 'Грешка',
+'databaseerror' => 'Грешка во базата',
+'dberrortext' => 'Грешка во прашалникот кон базата. Ова може да значи грешка во софтверот.
+Последниот прашалник кон базата беше:
+<blockquote><tt>"$1"</tt></blockquote>
+од функцијата "<tt>$2</tt>".
+MySQL ја врати следната грешка "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Грешка во прашалникот кон базата. Последниот прашалник кон базата беше: "$1" од функцијата "$2". MySQL ја врати следната грешка "$3: $4".',
+'noconnect' => 'Извинете! Викито има некои технички проблеми и не може да пристапи кон серверот.
+<br />
+$1',
+'nodb' => 'Не можам да изберам база $1',
+'cachederror' => 'Следува зачувана копија на бараната страница, која можеби е застарена.',
+'laggedslavemode' => 'Предупредување: Страницата може да не ги содржи скорешните ажурирања.',
+'readonly' => 'Базата е заклучена',
+'enterlockreason' => 'Внесете причина за заклучувањето, вклулувајќи и време на отклучување (приближно)',
+'readonlytext' => 'Базата е моментално затворена за нови статии и други модификации, најверојатно за рутинска проверка, по која ќе се врати во нормалната состојба. Администраторот кој ја заклучи го понуди следното објаснување: <p>$1',
+'missingarticle' => 'Базата на податоци не го најде текстот што требаше да го најде, наречен "$1".
+
+Најчеста причина е застарена разлика во верзиите или врска кон
+страница која била избришана.
+
+Доколку причина е нешто друго, можеби најдовте грешка во софтверот. Ве молиме пријавете го ова на администратор, наведувајќи ја URL адресата.',
+'readonly_lag' => 'Базата е автоматски заклучена додека помошните сервери не се синхронизираат',
+'internalerror' => 'Внатрешна грешка',
+'filecopyerror' => 'Не можам да ја копирам датотеката "$1" во "$2".',
+'filerenameerror' => 'Не можам да ја преименувам датотеката "$1" во "$2".',
+'filedeleteerror' => 'Не можам да ја избришам датотеката "$1".',
+'filenotfound' => 'Не можам да ја најдам датотеката "$1".',
+'unexpected' => 'Неочекувана вредност: "$1"="$2".',
+'formerror' => 'Грешка: не можам да го испратам формуларот',
+'badarticleerror' => 'Ова дејство не може да се спроведе на наведената страница.',
+'cannotdelete' => 'Не можам да ја избришам страницата или сликата. (Можеби е веќе избришана од некој друг.)',
+'badtitle' => 'Лош наслов',
+'badtitletext' => 'Бараниот наслов е грешен, празен или погрешно поврзан меѓујазичен или интер-вики наслов. Може да содржи еден или повеќе знаци што не можат да се користат во наслови.',
+'perfdisabled' => 'Извинете! Оваа можност е привремено исклучена бидејќи ја успорува базата до ниво на кое никој не може да го користи викито.',
+'perfdisabledsub' => 'Овде е зачувана копија од $1:',
+'perfcached' => 'Следните податоци се кеширани и може да не бидат целосно ажурирани:',
+'perfcachedts' => 'Следните податоци се кеширани, и последен пат ажурирани на $1.',
+'wrong_wfQuery_params' => 'Грешни параметри до wfQuery()<br /> Функција: $1<br /> Прашалник: $2',
+'viewsource' => 'Видете го кодот',
+'viewsourcefor' => 'за $1',
+'protectedtext' => 'Оваа страница е заклучена; има повеќе причини за тоа,
+ве молиме погледнете [[Project:Заштитена страница]].
+
+Можете да го гледате и да го ископирате кодот на оваа страница:',
+'protectedinterface' => 'Оваа страница содржи текст од интерфејсот на софтверот и е заклучена заради можна злоупотреба.',
+'editinginterface' => '\'\'\'Предупредување:\'\'\' Уредувате страница која се користи за приказ на текст од интерфејсот на софтверот. Промените на оваа страница ќе се одразат на изгледот на сајтот кај сите корисници.',
+'sqlhidden' => '(Скриен SQL прашалник)',
+'logouttitle' => 'Одјави се',
+'logouttext' => 'Сега си одјавен.<br /> Можеш да продолжиш да го користиш {{SITENAME}} анонимно, или можеш да се најавиш под истото или различно корисничко име. Некои страници може да продолжат да се прикажуваат како да сте најавени, се додека не го исчистите кеш-от на вашиот пребарувач',
+'welcomecreation' => '== Добредојдовте, $1! ==
+
+Сега сте регистрирани. Не заборавајте да ги промените прилагодувањата за {{SITENAME}}.',
+'loginpagetitle' => 'Најавување',
+'yourname' => 'Корисничко име',
+'yourpassword' => 'Лозинка',
+'yourpasswordagain' => 'Повторете ја лозинката',
+'remembermypassword' => 'Запамти ја лозинката за повеќе сесии.',
+'yourdomainname' => 'Вашиот домен',
+'externaldberror' => 'Настана грешка при надворешното најавување на базата или немате дозвола да ја ажурирате вашата надворешна сметка.',
+'loginproblem' => '<b>Има проблем со вашето најавување.</b><br />Обидете се повторно!',
+'alreadyloggedin' => '<strong>Корисник $1, веќе сте најавени!</strong><br />',
+'login' => 'Најавување',
+'loginprompt' => 'Морате да користите колачиња за да се најавите на {{SITENAME}}.',
+'userlogin' => 'Најавете се',
+'logout' => 'Одјави се',
+'userlogout' => 'Одјавете се',
+'notloggedin' => 'Не сте најавени',
+'nologin' => 'Немате сметка? $1.',
+'nologinlink' => 'Креирајте нова сметка',
+'createaccount' => 'Регистрирај се',
+'gotaccount' => 'Веќе имате сметка? $1.',
+'gotaccountlink' => 'Најавете се',
+'createaccountmail' => 'по е-пошта',
+'badretype' => 'Внесените лозинки не се исти.',
+'userexists' => 'Корисничкото име што го внесовте веќе се користи. Изберете друго име.',
+'youremail' => 'Вашата е-пошта*',
+'username' => 'Корисничко име:',
+'uid' => 'Кориснички ID:',
+'yourrealname' => 'Вистинско име *',
+'yourlanguage' => 'Јазик:',
+'yourvariant' => 'Варијанта',
+'yournick' => 'Прекар:',
+'badsig' => 'Грешка во потписот, проверете ги HTML таговите.',
+'email' => 'Е-пошта',
+'prefs-help-email-enotif'=> 'Оваа адреса истотака се користи за испраќање на известувања по е-пошта доколку ја имате дозволено таа можност.',
+'prefs-help-realname' => '* Вистинско име (опција). Доколку изберете да го дадете вашето име, тоа може да се искористи за давање на заслуги за вашата работа.',
+'loginerror' => 'Грешка при најавување',
+'prefs-help-email' => '* Е-пошта (опционално): Им овозможува на другите да контактираат со вас преку вашата корисничка страница или вашата страница за разговор, без да биде потребно да го откриете вашиот идентитет.',
+'nocookiesnew' => 'Регистрирани сте, но не сте најавени. {{SITENAME}} користи колачиња за најавување на корисници. Вие имате оневозможено користењето на колачиња. Ве молиме активирајте ги, па потоа најавете се со вашето корисничко име и лозинка.',
+'nocookieslogin' => '{{SITENAME}} користи колачиња за најавување на корисници. Вие го имате оневозможено користењето на колачиња. Ве молиме активирајте ги и обидете се повторно.',
+'noname' => 'Внесовте грешно корисничко име.',
+'loginsuccesstitle' => 'Успешно најавување',
+'loginsuccess' => 'Сега сте најавени на {{SITENAME}} како "$1".',
+'nosuchuser' => 'Нема корисник со името "$1". Проверете ја синтаксата, или искористете го долниот формулар да се регистрирате.',
+'nosuchusershort' => 'Нема корисник со името "$1". Проверете ја синтаксата.',
+'nouserspecified' => 'Мора да назначите корисничко име.',
+'wrongpassword' => 'Внесовте погрешна лозинка. Обидете се повторно.',
+'wrongpasswordempty' => 'Внесената лозинка е празна. Обидете се повторно.',
+'mailmypassword' => 'Испрати ми нова лозинка по е-пошта',
+'passwordremindertitle' => 'Потсетник за лозинка од {{SITENAME}}',
+'passwordremindertext' => 'Некој (најверојатно вие, од IP адреса $1) побара да ви испратиме нова {{SITENAME}} лозинка. Лозинката за корисникот "$2" сега е "$4". Треба да се најавите и да ја промените лозинката сега. Сега можете да се логирате со оваа привремена позинка, која е валидна само за едно логирање. Можете да продолжите да ја користите старата лозинка ако ја памтите или да поставите нова. {{fullurl:Special:Userlogin|wpName=$3&wpPassword=$4&returnto=Special:Preferences}}',
+'noemail' => 'Не е внесена е-поштенската адреса за корисникот "$1".',
+'passwordsent' => 'Нова лозинка е испратена на корисникот "$1". Најавете се повторно откако ќе ја примите пораката.',
+'eauthentsent' => 'Е-пошта е испратена на назначената е-поштенска адреса. Пред било која пошта да се прати на сметката, ќе мората да ги следите инструкциите во е-поштата, за да потврдите дека таа е навистина ваша.',
+'mailerror' => 'Грешка при испраќање на е-поштата: $1',
+'acct_creation_throttle_hit'=> 'Извинете, веќе имате создадено $1 сметки. Не можете да создавате повеќе.',
+'emailauthenticated' => 'Автентичноста на вашата е-поштенска адреса е проверена на $1.',
+'emailnotauthenticated' => 'Автентичноста на вашата е-поштенска адреса сеуште не е проверена. Нема да биде испратена е-пошта за никоја од следните содржини.',
+'noemailprefs' => '<strong>Не беше наведена е-поштенска адреса</strong>, следните содржини нема да работат.',
+'emailconfirmlink' => 'Потврдете ја вашата е-поштенска адреса',
+'invalidemailaddress' => 'Е-поштенската адреса не може да биде прифатена бидејќи има неважечки формат. Ве молиме, внесете важечки формат или испразнете го тоа поле.',
+'accountcreated' => 'Сметката е направена',
+'accountcreatedtext' => 'Сметката за $1 е направена.',
+'bold_sample' => 'Задебелен текст',
+'bold_tip' => 'Закосен текст',
+'italic_sample' => 'Закосен текст',
+'italic_tip' => 'Закосен текст',
+'link_sample' => 'Наслов на врска',
+'link_tip' => 'Внатрешна врска',
+'extlink_sample' => 'http://www.example.com наслов на врска',
+'extlink_tip' => 'Надворешна врска (користи http:// префикс)',
+'headline_sample' => 'Наслов',
+'headline_tip' => 'Ниво 2 наслов',
+'math_sample' => 'Овде вметни формула',
+'math_tip' => 'Математичка формула (LaTeX)',
+'nowiki_sample' => 'Овде внесете неформатиран текст',
+'nowiki_tip' => 'Игнорирај вики форматирање',
+'image_sample' => 'пример.jpg',
+'image_tip' => 'Вметната слика',
+'media_sample' => 'Пример.mp3',
+'media_tip' => 'Врска кон мултимедијална датотека',
+'sig_tip' => 'Вашиот потпис со време',
+'hr_tip' => 'Хоризонтална линија',
+'summary' => 'Опис',
+'subject' => 'Наслов',
+'minoredit' => 'Ова е ситна промена',
+'watchthis' => 'Набљудувајте ја оваа страница',
+'savearticle' => 'Зачувај ја страницата',
+'preview' => 'Преглед',
+'showpreview' => 'Прегледај',
+'showlivepreview' => 'Преглед во живо',
+'showdiff' => 'Прикажи ги промените',
+'anoneditwarning' => '\'\'\'Предупредување:\'\'\' Не сте најавени. Вашата IP адреса ќе биде забележана во историјата на страницата.',
+'missingsummary' => '\'\'\'Потсетник:\'\'\' Не внесовте опис на измените. Ако притиснете Зачувај повторно, вашите измени ќе се зачуваат без опис.',
+'missingcommenttext' => 'Ве молиме внесете коментар подолу.',
+'blockedtitle' => 'Корисникот е блокиран',
+'blockedtext' => 'Вашето корисничко име или IP адреса беше блокирано од $1.
+
+Дадена беше следнава причина:<br />\'\'$2\'\'<br />Можете да контактирате со $1 или еден од другите [[Project:Администратори|администратори]] за блокадата.
+
+Забелешка: Не можете да ја користите опцијата "е-пошта до корисникот" ако немате внесено валидна адреса во вашите [[Special:Прилагодувања|прилагодувања]]. Вашата IP адреса е $3. Ве молиме вклучете ја оваа адреса во сите барања што ќе ги приложите.',
+'blockedoriginalsource' => 'Кодот на \'\'\'$1\'\'\' е прикажан подолу:',
+'blockededitsource' => 'Текстот на \'\'\'вашите уредувања\'\'\' на \'\'\'$1\'\'\' е прикажан подолу:',
+'whitelistedittitle' => 'Мора да сте најавени за менување на статии',
+'whitelistedittext' => 'Мора да сте $1 за да уредувате страници.',
+'whitelistreadtitle' => 'Мора да сте најавени за да читате статии',
+'whitelistreadtext' => 'Мора да сте [[Special:Userlogin|најавени]] за да читате статии.',
+'whitelistacctitle' => 'Немате дозвола да додавате корисници',
+'whitelistacctext' => 'За да можете да додавате корисници во ова Вики мора да се [[Special:Userlogin|најавите]] и да имате соодветна дозвола.',
+'confirmedittitle' => 'Потребна е потврда за е-поштенската адреса за уредување',
+'confirmedittext' => 'Морате да ја потврдите вашата е-поштенска адреса пред да уредувате страници. Поставете ја и валидирајте ја вашата е-поштенска адреса преку вашите [[Special:Preferences|прилагодувања]].',
+'loginreqtitle' => 'Потребно најавување',
+'loginreqlink' => 'најавување',
+'loginreqpagetext' => 'Морате да се $1 за да ги видите другите страници.',
+'accmailtitle' => 'Лозинката е испратена.',
+'accmailtext' => 'Лозинката за \'$1\' е испратена на $2.',
+'newarticle' => '(нова)',
+'newarticletext' => 'Следевте врска која води до страница која сеуште не постои. За да ја креирате страницата, почнете со типкање во долното прозорче (видете ја страницата за [[Project:Помош|помош]] за повеќе информации). Ако сте овде по грешка, само притиснете го копчето \'\'\'назад\'\'\' во вашиот прелистувач.',
+'anontalkpagetext' => '---- \'\'Ова е страница за разговор за анонимен корисник кој сеуште не е регистриран или не ја користи. Затоа мораме да ја користиме неговата нумеричка [[IP адреса]] за идентификација. Една IP адреса може да биде делена од повеќе корисници. Ако сте анонимен корисник и сметате дека кон вас се упатени ирелевантни коментари, ве молиме [[Special:Userlogin|Регистрирајте или најавете се]] за да избегнете забуна со други корисници.\'\'',
+'noarticletext' => '(Моментално нема текст на оваа страница)',
+'clearyourcache' => '\'\'\'Забелешка:\'\'\' По зачувување морате да го исчистите кешот на вашиот прелистувач за да ги видите промените: \'\'\'Mozilla / Firefox:\'\'\' \'\'Ctrl-Shift-R\'\', \'\'\'IE:\'\'\' \'\'Ctrl-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-Shift-R\'\', \'\'\'Konqueror\'\'\' \'\'F5\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Совет:</strong> Користете го копчето Прегледај за да го испробате новиот CSS/JS код пред зачувувањето.',
+'usercsspreview' => '\'\'\'Запомнете дека ова е само преглед на вашиот CSS код, и дека страницата сеуште не е зачувана!\'\'\'',
+'userjspreview' => '\'\'\'Запомнете дека ова е само преглед на вашиот JavaScript код, и страницата сеуште не е зачувана!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Предупредување:\'\'\' Нема маска "$1". Запамтете дека сопствените .css и .js страници имаат имиња со мали букви, пр. Корисник:Некој/monobook.css наместо Корисник:Некој/Monobook.css.',
+'updated' => '(Освежено)',
+'note' => '<strong>Забелешка:</strong>',
+'previewnote' => 'Запомнете дека ова е само преглед, и страницата сеуште не е зачувана!',
+'session_fail_preview' => '<strong>Извинете! Не можевме да го процесираме вашето уредување заради губење на сесиски податоци.
+Обидете се повторно. Ако сеуште не функционира, пробајте да се одјавите и повторно да се најавите.</strong>',
+'previewconflict' => 'Овој преглед прикажува како ќе изгледа текстот
+внесен во горниот дел кога ќе се зачува страницата.',
+'session_fail_preview_html'=> '<strong>Извинете! Не можевме да го процесираме вашето уредување заради губење на сесиски податоци. </strong>
+
+\'\'Поради тоа што викито има овозможено raw HTML, прегледот е скриен како обезбедување JavaScript напади.\'\'
+
+<strong>Ако е ова е дозволен обид за уредување, ве молиме обидете се повторно. Ако сеуште не функционира, пробајте да се одјавите и повторно да се најавите.</strong>',
+'importing' => 'Увоз во тек $1',
+'editing' => 'Уредување на $1',
+'editinguser' => 'Уредување на $1',
+'editingsection' => 'Уредување на $1 (секција)',
+'editingcomment' => 'Уредување на $1 (коментар)',
+'editconflict' => 'Конфликтни уредувања: $1',
+'explainconflict' => 'Некој друг ја променил страницата откако почнавте да ја уредувате.
+Горниот дел за текст ја содржи страницата како што сега постои.
+Вашите промени се прикажани во долниот дел.
+Ќе морате да ги внесете вашите промени со постоечкиот текст.
+<b>Само</b> текстот во горниот дел ќе биде зачуван кога
+ќе притиснете на "Зачувај". <br />',
+'yourtext' => 'Вашиот текст',
+'storedversion' => 'Зачувана верзија',
+'nonunicodebrowser' => '<strong>ПРЕДУПРЕДУВАЊЕ: Вашиот прелистувач не е Уникод компатибилен, ве молиме променете го пред да уредувате статија.</strong>',
+'editingold' => '<strong>ПРЕДУПРЕДУВАЊЕ: Менувате застарена
+верзија на оваа страница.
+Ако ја зачувате, сите промени по оваа верзија ќе бидат изгубени.</strong>',
+'yourdiff' => 'Разлики',
+'copyrightwarning' => '<div style="display:block;vertical-align: top;width:100%; background:blue; color:#fff; text-align:center; font-weight:bold; font-size:100%;margin-bottom:5px;margin-top:0;margin-left:-5px;margin-right:-4px;">НЕ ПРАЌАЈТЕ ТЕКСТОВИ ЗАШТИТЕНИ СО АВТОРСКИ ПРАВА БЕЗ ДОЗВОЛА!</div><br />
+Имајте во предвив дека сите придонеси кон {{SITENAME}} се смета дека се издадени под $2 (видете $1 за детали). Ако не сакате вашите текстови да бидат слободно уредувани и разменувани, не ги праќајте овде.<br />
+Исто така потврдувате дека вие сте автори на текстот, или сте го копирале од некој слободен извор.',
+'copyrightwarning2' => 'Ве молиме, имајте во предвид дека сите придонеси кон {{SITENAME}} можат да бидат уредувани, менувани или отстранети од други корисници. Ако не сакате вашиот текст да биде менуван и редистрибуиран слободно, не го испраќајте овде.<br />
+Исто така потврдувате дека текстот сте го напишале сами, или сте го копирале од јавен домен или сличен слободен извор (видетe $1 за детали).<br />
+<strong>НЕ ПРАЌАЈТЕ ТЕКСТОВИ ЗАШТИТЕНИ СО АВТОРСКИ ПРАВА БЕЗ ДОЗВОЛА!</strong>',
+'longpagewarning' => '<strong>ПРЕДУПРЕДУВАЊЕ: Оваа страница има $1 килобајти; некои
+прелистувачи може да имаат проблеми со уредување на страниците поголеми од 32kb.
+Размислете за разделување на страницата во помали делови.</strong>',
+'longpageerror' => '<strong>ГРЕШКА: Текстот што го внесовте е голем $1 килобајти,
+што е повеќе од максималните $2 килобајти. Не може да се зачува.</strong>',
+'readonlywarning' => '<strong>ПРЕДУПРЕДУВАЊЕ: Базата е заклучена заради одржување,
+па нема да можете да ги зачувате вашите промени сега. Пробајте да го зачувате
+текстот локално и да го пратите подоцна.</strong>',
+'protectedpagewarning' => 'ПРЕДУПРЕДУВАЊЕ: Оваа страница е заклучена па само корисници со администраторски привилегии може да ја менуваат. Прочитајте го *** [[Project:Protected page guidelines|упатството за заштитени страници]].',
+'semiprotectedpagewarning'=> '\'\'\'Забелешка:\'\'\' Оваа страница е заклучена и само регистрирани корисници може да ја уредуваат.',
+'templatesused' => 'Шаблони користени на оваа страница:',
+'edittools' => '<!-- Овој текст ќе се прикаже под формите за уредување и подигнување датотеки. -->',
+'nocreatetitle' => 'Креирањето на нови страници е ограничено',
+'nocreatetext' => 'Овој сајт ја ограничил можноста за креирање нови страници.
+Можете да се вратите назад и да уредите постоечка страница, или [[Special:Userlogin|најавете се или креирајте нова сметка]].',
+'cantcreateaccounttitle'=> 'Неможам да направам сметка',
+'cantcreateaccounttext' => 'Креирањето сметки од оваа IP адреса (<b>$1</b>) е блокирано.
+Ова е најверојатно заради константен вандализам од вашето училиште или Интернет провајдер.',
+'revhistory' => 'Историја на верзиите',
+'viewpagelogs' => 'Види ја историјата за оваа страница',
+'nohistory' => 'Не постои историја на верзии за оваа страница.',
+'revnotfound' => 'Верзијата не е пронајдена',
+'revnotfoundtext' => 'Старата верзија на оваа страница не може да се пронајде.
+Проверете ја URL адресата што ја користевте за пристап до оваа страница.',
+'loadhist' => 'Се вчитува историјата за страницата',
+'currentrev' => 'Тековна верзија',
+'revisionasof' => 'Верзија од $1',
+'revision-info' => 'Ревизии од $1; $2',
+'previousrevision' => '<Претходна ревизија',
+'nextrevision' => 'Следна верзија>',
+'currentrevisionlink' => 'видете ја тековната верзија',
+'cur' => 'мом',
+'next' => 'след',
+'last' => 'посл',
+'orig' => 'ориг',
+'histlegend' => 'Легенда: (мом) = разлика со моменталната верзија,
+(последна) = разлика со претходната верзија, С = ситна промена.',
+'deletedrev' => '[избришана]',
+'histfirst' => 'Први',
+'histlast' => 'Последни',
+'rev-deleted-comment' => '(коментарот е избришан)',
+'rev-deleted-user' => '(корисничкото име е избришано)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Верзијата на оваа страница е избришана од јавните архиви.
+Можеби има повеќе информации во [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} историјата на избришани статии].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Верзијата на оваа страница беше избришана од јавните архиви.
+Како администратор вие можете да ја погледнете;
+можеби има повеќе информации во [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} историјата на избришани статии].
+</div>',
+'rev-delundel' => 'прикажи/сокриј',
+'history-feed-title' => 'Историја на верзиите',
+'history-feed-description'=> 'Историја на верзиите на оваа страница на викито',
+'history-feed-item-nocomment'=> '$1, $2',
+'history-feed-empty' => 'Бараната страница не постои.
+Може била избришана од викито, или преименувана.
+Обидете се да го [[Special:Search|пребарате викито]] за релевантните нови страници.',
+'revisiondelete' => 'Избриши/врати верзии',
+'revdelete-nooldid-title'=> 'Нема барана ревизија',
+'revdelete-nooldid-text'=> 'Не избравте ревизија/и за да ја извршите функцијата.',
+'revdelete-selected' => 'Избрани верзии од [[:$1]]:',
+'revdelete-text' => 'Избришаните верзии сеуште ќе се прикажуваат во историјата на страницата,
+но нивната содржина нема да биде пристапна за јавноста.
+
+Другите администратори на ова вики сеуште ќе можат да го пристапат скриениот текст
+и можат да го вратат преку истиот интерфејс, освен ако не постојат дополнителни
+ограничувања.',
+'revdelete-legend' => 'Постави ограничувања на верзијата:',
+'revdelete-hide-text' => 'Сокриј го текстот на верзијата',
+'revdelete-hide-comment'=> 'Сокриј го описот на измената',
+'revdelete-hide-user' => 'Сокриј име/адреса на уредувачот',
+'revdelete-hide-restricted'=> 'Примени ги овие ограничувања на администраторите исто како и на другите корисници',
+'revdelete-log' => 'Коментар за лог:',
+'revdelete-submit' => 'Примени на следните верзии:',
+'revdelete-logentry' => 'променет приказ на верзија за [[$1]]',
+'difference' => '(Разлика меѓу верзии)',
+'loadingrev' => 'се вчитуваат верзиите за функцијата <em>разл</em>',
+'lineno' => 'Линија $1:',
+'editcurrent' => 'Промени ја моментална верзија на оваа страница',
+'selectnewerversionfordiff'=> 'Изберете понова верзија за споредба',
+'selectolderversionfordiff'=> 'Изберете постара верзија за споредба',
+'compareselectedversions'=> 'Споредете ги избраните верзии',
+'searchresults' => 'Резултати од пребарувањето',
+'searchresulttext' => 'За повеќе информации за пребарување на {{SITENAME}}, видете [[Project:Пребарување|Пребарување на {{SITENAME}}]].',
+'searchsubtitle' => 'За прашалникот "[[:$1]]"',
+'searchsubtitleinvalid' => 'За прашалникот "$1"',
+'badquery' => 'Лошо формиран прашалник за пребарување',
+'badquerytext' => 'Не можевме да го процесираме вашето барање. Најверојатно баравте збор со помалку од три букви, што не е уште подржано. Исто така можеби лошо сте го внесе изразот, како "риба ии коски". Обидете се повторно.',
+'matchtotals' => 'Прашалникот "$1" најде $2 наслови на страници
+и текст од $3 страници.',
+'noexactmatch' => '\'\'\'Нема статија со наслов „$1“.\'\'\' Можете да ја [[:$1|креирате оваа статија]].',
+'titlematches' => 'Насловот на статијата одговара',
+'notitlematches' => 'Ниеден текст на насловите не одговара',
+'textmatches' => 'Текстот на статијата одговара',
+'notextmatches' => 'Ниеден текст во статиите не одговара',
+'prevn' => 'претходни $1',
+'nextn' => 'следни $1',
+'viewprevnext' => 'Видете ($1) ($2) ($3).',
+'showingresults' => 'Прикажувам под <b>$1</b> резултати почнувајќи од #<b>$2</b>.',
+'showingresultsnum' => 'Прикажувам под <b>$3</b> резултати во #<b>$2</b>.',
+'nonefound' => '<strong>Забелешка</strong>: неуспешни барања
+најчесто се предизвикани од барање на чести зборови како "има" и "од",
+кои не се индексираат, или пак, со внесување на повеќе од еден критериуми (се прикажуваат
+само страници кои ги содржат сите барани зборови).',
+'powersearch' => 'Барај',
+'powersearchtext' => 'Барајте во именските простори :<br />$1<br />$2 Листа на пренасочувања<br />Барај $3 $9',
+'searchdisabled' => '{{SITENAME}}пребарувањето е привремено исклучено. Во меѓувреме, можете да барате преку Google (подолу), што може да даде застарени резултати.',
+'blanknamespace' => '(Главна)',
+'preferences' => 'Прилагодувања',
+'mypreferences' => 'мои прилагодувања',
+'prefsnologin' => 'Не сте најавени',
+'prefsnologintext' => 'Мора да бидете [[Special:Userlogin|најавени]] за промена на прилагодувањата.',
+'prefsreset' => 'Воспоставени се стандардните прилагодувања.',
+'qbsettings' => 'Лента за брз избор',
+'changepassword' => 'Промени лозинка',
+'skin' => 'Маска',
+'math' => 'Математички операции',
+'dateformat' => 'Приказ на време',
+'datedefault' => 'Небитно',
+'datetime' => 'Дата и време',
+'math_failure' => 'Неможам да парсирам',
+'math_unknown_error' => 'непозната грешка',
+'math_unknown_function' => 'непозната функција',
+'math_lexing_error' => 'лексичка грешка',
+'math_syntax_error' => 'синтаксна грешка',
+'math_image_error' => 'неуспешна PNG конверзија',
+'math_bad_tmpdir' => 'Невозможно е создавањето на привремен директориум за математичките операции',
+'math_bad_output' => 'Невозможно е создавањето на аутпут директориум за математичките операции',
+'math_notexvc' => 'Недостасува извршната датотека texvc; ве молиме видете math/README за подесувања.',
+'prefs-personal' => 'Кориснички податоци',
+'prefs-rc' => 'Скорешни промени и никулци',
+'prefs-watchlist' => 'Список на набљудувања',
+'prefs-watchlist-days' => 'Број на денови за прикажување во листата на набљудување:',
+'prefs-watchlist-edits' => 'Број на уредувања за прикажување во проширената листа на набљудување:',
+'prefs-misc' => 'Разно',
+'saveprefs' => 'Запамти ги прилагодувањата',
+'resetprefs' => 'Ресетирај ги прилагодувањата',
+'oldpassword' => 'Стара лозинка',
+'newpassword' => 'Нова лозинка:',
+'retypenew' => 'Повторно внесување на нова лозинка',
+'textboxsize' => 'Димензии на кутијата за текст',
+'rows' => 'Редови:',
+'columns' => 'Колони',
+'searchresultshead' => 'Опции за пребарување',
+'resultsperpage' => 'Резултати по страница',
+'contextlines' => 'Линии по резултати',
+'contextchars' => 'Карактери од содржината по линија',
+'stubthreshold' => 'Граница за прикажување на никулци:',
+'recentchangescount' => 'Број на наслови во скорешни промени',
+'savedprefs' => 'Вашите прилагодувања се зачувани.',
+'timezonelegend' => 'Временска зона',
+'timezonetext' => 'Внесете колку часови вашето локално време се разликува од серверското време (UTC).',
+'localtime' => 'Локално време',
+'timezoneoffset' => 'Отстапка',
+'servertime' => 'Серверското време е',
+'guesstimezone' => 'Пополни од прелистувачот',
+'allowemail' => 'Дозволи е-пошта од други корисници',
+'defaultns' => 'Барај во овие именски простори по основно:',
+'default' => 'по основно',
+'files' => 'Датотеки',
+'userrights-lookup-user'=> 'Управувај со корисничките групи',
+'userrights-user-editname'=> 'Внеси корисничко име:',
+'editusergroup' => 'Уреди кориснички групи',
+'userrights-editusergroup'=> 'Уреди ги корисничките групи',
+'saveusergroups' => 'Зачувај ги корисничките групи',
+'userrights-groupsmember'=> 'Член на:',
+'userrights-groupsavailable'=> 'Достапни групи:',
+'userrights-groupshelp' => 'Изберете групи од кои сакате да го отстраните корисникот или да го додадете. Групите што не се избрани нема да бидат променети. Можете да деселектирате група со CTRL + лев клик',
+'group' => 'Група:',
+'group-bot' => 'Ботови',
+'group-sysop' => 'Администратори',
+'group-bureaucrat' => 'Бирократи',
+'group-all' => '(сите)',
+'group-bot-member' => 'Бот',
+'group-sysop-member' => 'Администратор',
+'group-bureaucrat-member'=> 'Бирократ',
+'grouppage-bot' => 'Project:Ботови',
+'grouppage-sysop' => 'Project:Администратори',
+'grouppage-bureaucrat' => 'Project:Бирократи',
+'changes' => 'промени',
+'recentchanges' => 'Скорешни промени',
+'recentchangestext' => 'Забележете ги најновите промени на викито на оваа страница.',
+'rcnote' => 'Подолу е листа на последните <strong>$1</strong> промени во последните <strong>$2</strong> дена, почнувајќи од $3.',
+'rcnotefrom' => 'Подолу се промените од <b>$2</b> (се прикажуваат до <b>$1</b>).',
+'rclistfrom' => 'Прикажи ги новите промени почнувајќи од $1',
+'rcshowhideminor' => '$1 ситни промени',
+'rcshowhidebots' => '$1 ботови',
+'rcshowhideliu' => '$1 најавени корисници',
+'rcshowhideanons' => '$1 анонимни корисници',
+'rcshowhidepatr' => '$1 проверени уредувања',
+'rcshowhidemine' => '$1 мои уредувања',
+'rclinks' => 'Прикажи ги последните $1 промени во последните $2 дена<br />$3',
+'diff' => 'разл',
+'hist' => 'ист',
+'hide' => 'Сокриј',
+'show' => 'Прикажи',
+'minoreditletter' => 'с',
+'newpageletter' => 'Н',
+'number_of_watching_users_pageview'=> '[$1 корисници кои набљудуваат]',
+'rc_categories' => 'Ограничи на категории (раздели со "|")',
+'rc_categories_any' => 'Било кои',
+'upload' => 'Подигни датотека',
+'uploadbtn' => 'Подигни датотека',
+'reupload' => 'Повторно подигни',
+'reuploaddesc' => 'Врати се во формуларот за подигнување.',
+'uploadnologin' => 'Не сте најавени',
+'uploadnologintext' => 'Морате да бидете [[Special:Userlogin|најавени]] за да подигнувате датотеки.',
+'upload_directory_read_only'=> 'Веб серверот не може да запишува во папката за подигнување ($1).',
+'uploaderror' => 'Грешка во подигнувањето',
+'uploadtext' => 'Користете го долниот формулар за да подигнете нови датотеки, а за да гледате или пребарувате претходно подигнати слики одете на [[Special:Imagelist|листата на подигнати датотеки]], подигнувањата и бришењата се истотака запишани во [[Special:Log|дневникот на проектот]]. Исто така мора да го штиклирате полето дека не прекршувате некои авторски права со подигнувањето на датотеката. Притиснете го копчето "Подигни датотека" за да го завршите подигнувањето. За да внесете слика во страница, користете врска во обликот
+
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:File.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:File.png|alt text]]</nowiki>\'\'\'
+или за директно поврзување со датотеката
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:File.ogg]]</nowiki>\'\'\'',
+'uploadlog' => 'дневник на подигнувањата',
+'uploadlogpage' => 'Дневник на подигнувањата',
+'uploadlogpagetext' => 'Подолу е листа на најновите подигнувања на датотеки.',
+'filename' => 'Име на датотеката',
+'filedesc' => 'Опис',
+'fileuploadsummary' => 'Опис (автор, извор, итн):',
+'filestatus' => 'Авторски права',
+'filesource' => 'Извор',
+'copyrightpage' => 'Project:Авторски права',
+'copyrightpagename' => '{{SITENAME}} авторски права',
+'uploadedfiles' => 'Подигнати датотеки',
+'ignorewarning' => 'Игнорирај ги предупредувањата и зачувај ја датотеката.',
+'ignorewarnings' => 'Игнорирај ги сите предупредувања',
+'minlength' => 'Имињата на сликите мораат да имаат барем три букви.',
+'illegalfilename' => 'Името на датотеката "$1" содржи знаци што не се дозволени во наслов на страници. Ве молиме преименувајте ја датотеката и подигнете ја пак.',
+'badfilename' => 'Името на сликата е променето во "$1".',
+'badfiletype' => '".$1" не е препорачано име за слика.',
+'largefile' => 'Се препорачува датотеките да не бидат поголеми од $1 бајти; оваа датотека тежи $2 бајти',
+'largefileserver' => 'Датотеката е поголема од максималната дозволена големина.',
+'emptyfile' => 'Датотеката што ја подигнавте е празна. Ова може да е поради грешка во името на датотеката. Ве молиме проверете дали навистина сакате да ја подигнете оваа датотека.',
+'fileexists' => 'Датотека со ова име веќе постои, проверете $1 ако не сте сигурни дали сакате да го промените.',
+'fileexists-forbidden' => 'Датотека со тоа име веќе постои; ве молиме вратете се и подигнете ја оваа датотека под друго име.
+[[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Датотека со ова име веќе постои во заедничкиот склад; ве молиме вратете се и повторно подигнете ја датотеката под ново име. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Успешно подигнување',
+'fileuploaded' => 'Датотеката "$1" е успешно подигната.
+Ве молиме следете ја оваа врска: ($2) до страницата за опис и пополнете
+ги информациите за датотеката - од каде доаѓа, кога е
+направена, и од кого, и било што друго што знаете за неа. Ако ова е слика, може да ја вметнете на
+следниов начин: <tt><nowiki>[[{{ns:Image}}:$1|мини|Опис]]</nowiki></tt>',
+'uploadwarning' => 'Предупредување при подигнување',
+'savefile' => 'Зачувај',
+'uploadedimage' => 'подигнато "[[$1]]"',
+'uploaddisabled' => 'Извинете, подигнувањето е забрането.',
+'uploaddisabledtext' => 'Подигнувања на датотеки не се дозволени на ова вики.',
+'uploadscripted' => 'Датотеката содржи HTML код или скрипта што може да биде погрешно интерпретира од прелистувачот.',
+'uploadcorrupt' => 'Датотеката е неисправна или има неточна наставка. Ве молиме проверете ја датотеката и подигнете ја повторно.',
+'uploadvirus' => 'Оваа датотека содржи вирус! Детално: $1',
+'sourcefilename' => 'Изворно име',
+'destfilename' => 'Целно име',
+'watchthisupload' => 'Набљудувај ја оваа страница',
+'filewasdeleted' => 'Датотека со ова име претходно била подигната и потоа избришана. Погледнете го $1 пред да продолжите со подигнувањето.',
+'license' => 'Лиценца',
+'nolicense' => 'Нема',
+'upload_source_url' => ' (валидна, јавно достапна адреса (URL))',
+'upload_source_file' => ' (датотека на вашиот компјутер)',
+'imagelist' => 'Листа на слики',
+'imagelisttext' => 'Подолу е листа на $1 подредени слики $2.',
+'imagelistforuser' => 'Ова ги прикажува само сликите подигнати од $1.',
+'getimagelist' => 'вчитување на листата',
+'ilsubmit' => 'Барај',
+'showlast' => 'Прикажи ги последните $1 подредени слики по $2.',
+'byname' => 'по име',
+'bydate' => 'по време',
+'bysize' => 'по големина',
+'imgdelete' => 'избр',
+'imgdesc' => 'опис',
+'imgfile' => 'датотека',
+'imglegend' => 'Легенда: (опис) = прикажи/промени го описот на сликата.',
+'imghistory' => 'Историја на сликата',
+'revertimg' => 'врт',
+'deleteimg' => 'избр',
+'deleteimgcompletely' => 'Избриши ги сите верзии',
+'imghistlegend' => 'Легенда: (мом) = ова е моменталната слика, (избр) = ја брише оваа стара верзија, (врт) = врати кон оваа стара верзија. <br /><i>Притиснете на датум за да ги видите сите слики пратени на тој датум</i>.',
+'imagelinks' => 'Врски кон сликата',
+'linkstoimage' => 'Следните страници ја користат оваа слика:',
+'nolinkstoimage' => 'Нема страници кои ја користат оваа слика',
+'sharedupload' => 'Оваа датотека е заедничка и може да се користи од други проекти.',
+'shareduploadwiki' => 'Ве молиме видете $1 за понатамошна информација.',
+'shareduploadwiki-linktext'=> 'страница за опис на датотеката',
+'noimage' => 'Не постои датотека со тоа име, можете $1',
+'noimage-linktext' => 'да го подигнете',
+'uploadnewversion-linktext'=> 'Подигни нова верзија на оваа датотека',
+'imagelist_date' => 'Датум',
+'imagelist_name' => 'Име',
+'imagelist_user' => 'Корисник',
+'imagelist_size' => 'Големина (бајти)',
+'imagelist_description' => 'Опис',
+'imagelist_search_for' => 'Барај име на слика:',
+'mimesearch' => 'MIME пребарување',
+'mimetype' => 'MIME тип:',
+'download' => 'преземи',
+'unwatchedpages' => 'Ненабљудувани страници',
+'listredirects' => 'Листа на пренасочувања',
+'unusedtemplates' => 'Неискористени шаблони',
+'unusedtemplatestext' => 'Оваа страница ги прикажува сите страници во шаблонскиот именски простор кои не се вклучени во некоја друга страница. Не заборавајте да ги проверите другите врски во шаблоните пред да ги избришете.',
+'unusedtemplateswlh' => 'други врски',
+'randomredirect' => 'Случајно пренасочување',
+'statistics' => 'Статистики',
+'sitestats' => 'Статистики за {{SITENAME}}',
+'userstats' => 'Статистики за корисници',
+'sitestatstext' => 'Има вкупно \'\'\'$1\'\'\' страници во базата.
+Оваа бројка вклучува "разговор" страници, страници за {{SITENAME}}, минимални
+"никулци", пренасочувања, и други страници кои најверојатно не се сметаат за статии.
+Без нив, има \'\'\'$2\'\'\' стрници кои се вистински статии.
+
+\'\'\'$8\'\'\' датотеки се подигнати.
+
+Има вкупно \'\'\'$3\'\'\' прегледи на страници, и \'\'\'$4\'\'\' промени на страници откако овој
+софтвер беше поставен.
+Тоа се сведува на \'\'\'$5\'\'\' просечни менувања по страница, и \'\'\'$6\'\'\' прегледувања по страница.
+
+Должината на [http://meta.wikimedia.org/wiki/Help:Job_queue редицата за работи] изнесува \'\'\'$7\'\'\'.',
+'userstatstext' => 'Има вкупно \'\'\'$1\'\'\' регистрирани корисници.
+\'\'\'$2\'\'\' (или \'\'\'$4%\'\'\') од нив се $5.',
+'statistics-mostpopular'=> 'Најгледани страници',
+'disambiguations' => 'Страници за појаснување',
+'disambiguationspage' => 'Project:Врски до страници за појаснување',
+'disambiguationstext' => 'Следните статии посочуваат кон <i>појаснителна страница</i>. Тие треба да посочуваат кон соодветниот наслов.<br />Страница се третира како појаснителна ако е поврзана од $1.<br />Овде <i>НЕ</i> се прикажуваат врски од други именски простори.',
+'doubleredirects' => 'Двојни пренасочувања',
+'doubleredirectstext' => 'Секој ред содржи врски кон првото и второто пренасочување, којшто обично ја посочува <i>вистинската</i> целна страница кон кое првото пренасочување би требало да насочува.',
+'brokenredirects' => 'Прекинати пренасочувања',
+'brokenredirectstext' => 'Следните пренасочувања покажуваат кон непостоечка статија.',
+'nbytes' => '$1 бајти',
+'ncategories' => '$1 категории',
+'nlinks' => '$1 врски',
+'nmembers' => '$1 {{PLURAL:$1|член|членови}}',
+'nrevisions' => '$1 верзија',
+'nviews' => '$1 прегледувања',
+'lonelypages' => 'Осамени страници',
+'uncategorizedpages' => 'Некатегоризирани страници',
+'uncategorizedcategories'=> 'Некатегоризирани категории',
+'uncategorizedimages' => 'Некатегоризирани слики',
+'unusedcategories' => 'Неискористени категории',
+'unusedimages' => 'Неискористени слики',
+'popularpages' => 'Популарни страници',
+'wantedcategories' => 'Барани категории',
+'wantedpages' => 'Барани страници',
+'mostlinked' => 'Најмногу врски до страници',
+'mostlinkedcategories' => 'Најмногу врски до категории',
+'mostcategories' => 'Статии со најмногу категории',
+'mostimages' => 'Најмногу врски до слики',
+'mostrevisions' => 'Статии со најмногу верзии',
+'allpages' => 'Сите страници',
+'prefixindex' => 'Список на префикси',
+'randompage' => 'Случајна страница',
+'shortpages' => 'Кратки страници',
+'longpages' => 'Долги страници',
+'deadendpages' => 'Ќорсокак страници',
+'listusers' => 'Листа на корисници',
+'specialpages' => 'Специјални страници',
+'spheading' => 'Специјални страници за сите корисници',
+'restrictedpheading' => 'Специјални страници со ограничен пристап',
+'recentchangeslinked' => 'Поврзани промени',
+'rclsub' => '(до страници поврзани од "$1")',
+'newpages' => 'Нови страници',
+'newpages-username' => 'Корисничко име:',
+'ancientpages' => 'Најстари статии',
+'intl' => 'Меѓујазични врски',
+'move' => 'Премести',
+'movethispage' => 'Премести ја оваа страница',
+'unusedimagestext' => '<p>Имајте во предвид дека други веб сајтови може да имаат врска кон слика
+со директна URL, па може сеуште да се прикажуваат иако
+активно се користат.</p>',
+'unusedcategoriestext' => 'Следните категории постојат и покрај тоа што ниедна статија и категорија не ги користи.',
+'booksources' => 'Печатени извори',
+'categoriespagetext' => 'Во викито постојат следниве категории.',
+'data' => 'Податоци',
+'userrights' => 'Управување со кориснички права',
+'groups' => 'Кориснички групи',
+'booksourcetext' => 'Подолу имате листа на сите врски до други веб сајтови кои
+продаваат нови или користени книги, и може да имаат повеќе информации
+за книгите што ги барате.',
+'alphaindexline' => '$1 во $2',
+'version' => 'Верзија',
+'log' => 'Дневници',
+'alllogstext' => 'Комбиниран приказ на дневници на подигнувања, бришења, заштита, блокирање и администраторски. Можете да го стесните прегледот преку избор на вид на дневник, име на корисник, или односната страница.',
+'logempty' => 'Нема одговарачки записи во дневникот.',
+'nextpage' => 'Следна страница ($1)',
+'allpagesfrom' => 'Прикажи страници кои започнуваат од:',
+'allarticles' => 'Сите статии',
+'allinnamespace' => 'Сите страници (именски простор $1)',
+'allnotinnamespace' => 'Сите страници (кои не се во именскиот простор $1)',
+'allpagesprev' => 'Претходна',
+'allpagesnext' => 'Следна',
+'allpagessubmit' => 'Оди',
+'allpagesprefix' => 'Прикажи страници со префикс:',
+'allpagesbadtitle' => 'Дадениот наслов е невалиден или има интер-јазичен или интер-вики префикс. Може да содржи повеќе карактери кои несмеат да се користат во наслови.',
+'listusersfrom' => 'Прикажни корисници почнувајќи од:',
+'mailnologin' => 'Нема адреса за праќање',
+'mailnologintext' => 'Мора да бидете [[Special:Userlogin|најавени]] и да имате валидна е-поштенска адреса во вашите [[Special:Preferences|прилагодувања]] за да испратите е-пошта до други корисници.',
+'emailuser' => 'Е-пошта до овој корисник',
+'emailpage' => 'Е-пошта до корисникот',
+'emailpagetext' => 'Ако овој корисник внесол валидна е-адреса во неговите или нејзините прилагодувања, долниот формулар ќе прати една порака. Е-поштенската адреса што ја внесовте во вашите прилагодувања ќе се прикаже во "Од" полето на пораката, со што примачот ќе може да ви одговори.',
+'usermailererror' => 'Настана следната грешка:',
+'defemailsubject' => '{{SITENAME}} е-пошта',
+'noemailtitle' => 'Нема е-поштенска адреса',
+'noemailtext' => 'Овој корисник нема наведено валидна е-поштенска адреса, или избрал да не прима е-пошта од други корисници.',
+'emailfrom' => 'Од',
+'emailto' => 'До',
+'emailsubject' => 'Тема',
+'emailmessage' => 'Порака',
+'emailsend' => 'Прати',
+'emailsent' => 'Е-поштата е пратена',
+'emailsenttext' => 'Вашата е-пошта е пратена.',
+'watchlist' => 'Моите набљудувани страници',
+'watchlistfor' => '(за \'\'\'$1\'\'\')',
+'nowatchlist' => 'Немате елементи во вашите набљудувани страници.',
+'watchlistanontext' => 'Ве молиме $1 за да гледате или менувате елементи во вашата листа на набљудувани страници.',
+'watchlistcount' => '\'\'\'Имате $1 записи во вашата набљудувана листа, заедно со страници за разговор.\'\'\'',
+'clearwatchlist' => 'Избриши ја листата за набљудување',
+'watchlistcleartext' => 'Сигурно сакате да ги избришете?',
+'watchlistclearbutton' => 'Избриши ја листата на набљудувани страници',
+'watchlistcleardone' => 'Вашата листа на набљудувани страници е избришана. $1 записи беа избришани.',
+'watchnologin' => 'Не сте најавени',
+'watchnologintext' => 'Мора да бидете [[Special:Userlogin|најавени]] за да се модифицира вашата листа на набљудувани страници.',
+'addedwatch' => 'Додадено во набљудувани страници',
+'addedwatchtext' => 'Страницата"$1" е додадена во вашите [[Special:Watchlist|набљудувани страници]]. Идните промени на оваа страница и поврзаните со неа Страници за разговор ќе бидат прикажани овде и страницата ќе се прикаже \'\'\'задебелена\'\'\' во [[Special:Recentchanges|листата на скорешни промени]] за да можете полесно да ја изберете. <p>Ако подоцна сакате да ја отстраните страницата од набљудувани страници, притиснете на "Престани набљудување" .',
+'removedwatch' => 'Отстрани ја страницата од набљудуваните страници',
+'removedwatchtext' => 'Страницата "$1" е отстранета од набљудуваните страници.',
+'watch' => 'Набљудувај',
+'watchthispage' => 'Набљудувајте ја оваа страница',
+'unwatch' => 'Престани набљудување',
+'unwatchthispage' => 'Престани набљудување',
+'notanarticle' => 'Не е статија',
+'watchnochange' => 'Ниедна од вашите набљудувани страници не беше уредувана во прикажаниот период.',
+'watchdetails' => '* $1 набљудувани страници неброејќи ги страниците за разговор;
+* [[Special:Watchlist/edit|Прикажи и промени ја целосната листа на набљудувани страници]]
+* [[Special:Watchlist/clear|Ибриши ги сите страници]]',
+'wlheader-enotif' => '* Известувањето по е-пошта е вклучено.',
+'wlheader-showupdated' => '* Страниците кои се променети од вашата последна посета се прикажани со \'\'\'задебелени\'\'\' букви',
+'watchmethod-recent' => 'Проверување на скорешните уредувања на набљудуваните страници',
+'watchmethod-list' => 'Проверување на скорешните уредувања на набљудуваните страници',
+'removechecked' => 'Отстрани ги означените елементи од набљудуваните страници',
+'watchlistcontains' => 'Вие набљудувате $1 страници.',
+'watcheditlist' => 'Ова е азбучна листа на вашите
+набљудувани страници. Означете ги полињата на страниците кои сакате да ги остраните од вашата листа и притиснете го копчето \'Отстрани го избраното\'
+на дното на екранот (бришењето на страница исто така ги брише и поврзаните статии за разговор, и обратно).',
+'removingchecked' => 'Отстранување на избраните елементи од списокот...',
+'couldntremove' => 'Не може да се отстрани елементот \'$1\'...',
+'iteminvalidname' => 'Проблем со елементот \'$1\', неважечко име...',
+'wlnote' => 'Подолу се последните $1 промени во последните <b>$2</b> часа.',
+'wlshowlast' => 'Прикажи ги последните $1 часа $2 денови $3',
+'wlsaved' => 'Ова е зачувана верзија од листата на набљудувани страници.',
+'wlhideshowown' => '$1 мои уредувања',
+'wlhideshowbots' => '$1 уредувања на ботови',
+'wldone' => 'Готово.',
+'enotif_mailer' => '{{SITENAME}} Систем за известување',
+'enotif_reset' => 'Означи ги сите страници како посетени',
+'enotif_newpagetext' => 'Ова е нова страница.',
+'changed' => 'променет',
+'created' => 'создадена',
+'enotif_subject' => '{{SITENAME}} страницата $PAGETITLE беше $CHANGEDORCREATED од $PAGEEDITOR',
+'enotif_lastvisited' => 'Видете $1 за сите промени од вашата последна посета.',
+'enotif_body' => 'Драги $WATCHINGUSERNAME,
+
+страницата $PAGETITLE на {{SITENAME}} беше $CHANGEDORCREATED на $PAGEEDITDATE од $PAGEEDITOR, видете $PAGETITLE_URL за сегашната верзија.
+
+$NEWPAGE
+
+Резиме: $PAGESUMMARY $PAGEMINOREDIT
+
+Контактирајте го уредувачот:
+е-пошта: $PAGEEDITOR_EMAIL
+вики: $PAGEEDITOR_WIKI
+
+Веќе нема да има известувања за следните промени освен ако не ја посетите оваа страница. Исто така треба да ги ресетирате знаменцата за известување за сите ваши набљудувани страни во соодветната листа.
+
+ Вашиот пријателски {{SITENAME}} систем за известување
+
+--
+За да ги промените прилагодувањата за набљудување, посетете
+{{fullurl:Special:Watchlist/edit}}
+
+Фидбек и помош:
+{{fullurl:Help:Содржина}}',
+'deletepage' => 'Избриши ја страницата',
+'confirm' => 'Потврди',
+'excontent' => 'содржината беше: \'$1\'',
+'excontentauthor' => 'содржината беше: \'$1\' (и единствениот автор беше \'$2\')',
+'exbeforeblank' => 'содржината пред бришењето беше: \'$1\'',
+'exblank' => 'страницата беше празна',
+'confirmdelete' => 'Потврди го бришењето',
+'deletesub' => '(Бришам "$1")',
+'historywarning' => 'Предупредување: Страницата која сакате да ја избришете има историја:',
+'confirmdeletetext' => 'На пат сте трајно да избришете страница или слика заедно со нејзината историја од базата на податоци. Ве молиме потврдете дека имате намера да го направите ова, и дека ги разбирате последиците, и дека го правите ова во согласност со [[Project:Википедија политика|нашата политика на однесување]].',
+'actioncomplete' => 'Дејството беше извршено',
+'deletedtext' => '"$1" беше избришана. Видете $2 за досие на скорешните бришења.',
+'deletedarticle' => 'избришано "[[$1]]"',
+'dellogpage' => 'Дневник на бришењата',
+'dellogpagetext' => 'Подолу имате листа на последните бришења.',
+'deletionlog' => 'дневник на бришењата',
+'reverted' => 'Вратено на претходната верзија',
+'deletecomment' => 'Причина за бришење',
+'imagereverted' => 'Враќањето на претходната верзија е успешно.',
+'rollback' => 'Врати промени',
+'rollback_short' => 'Врати',
+'rollbacklink' => 'Врати',
+'rollbackfailed' => 'Враќањето беше неуспешно',
+'cantrollback' => 'Не може да се врати последната промена, последниот автор е истовремено и единствен.',
+'alreadyrolled' => 'Не може да се врати последната верзија [[:$1]] на [[User:$2|$2]] ([[User talk:$2|Разговор]]); некој веќе ја уредил или ги вратил промените на страницата.
+
+Последното уредување беше на [[User:$3|$3]] ([[User talk:$3|Разговор]]).',
+'editcomment' => 'Коментарот на уредувањето беше: "<i>$1</i>".',
+'revertpage' => 'Отстрането уредување на [[Special:Contributions/$2|$2]], вратено на последната верзија на [[User:$1|$1]]',
+'sessionfailure' => 'Има проблем со вашата сесија;
+оваа акција е откажана како превентива против преземање сесии.
+Притиснете го копчето „назад“ и повторно вчитајте ја страницата
+од која дојдовте и обидете се повторно.',
+'protectlogpage' => 'Дневник на заштитата',
+'protectlogtext' => 'Подолу е листа на отклучувања/заклучувања на страницата. Видете [[Project:Заштитена страница]] за повеќе информации.',
+'protectedarticle' => 'заштитена "[[$1]]"',
+'unprotectedarticle' => 'отстранета заштита на "[[$1]]"',
+'protectsub' => '(Заштитување "$1")',
+'confirmprotecttext' => 'Дали навистина сакате да ја заштитите оваа страница?',
+'confirmprotect' => 'Потврдете ја заштитата',
+'protectmoveonly' => 'Заштити само од преместувања',
+'protectcomment' => 'Причина за заштитување',
+'unprotectsub' => '(Отстранување на заштитата на "$1")',
+'confirmunprotecttext' => 'Дали навистина сакате да ја отстраните заштитата на оваа страница?',
+'confirmunprotect' => 'Потврдете го отстранувањето на заштитата',
+'unprotectcomment' => 'Причина за отстранување на заштитата',
+'protect-unchain' => 'Отклучи ја можноста за преместување',
+'protect-text' => 'Овде можете да го погледнете или смените нивото на заштита за страницата <strong>$1</strong>.
+Ве молиме прво прочитајте ги *** [[Project:Protected page|упатствата]].',
+'protect-viewtext' => 'Вашата сметка нема дозвола за промена на нивоа
+на заштита за страници. Еве ги моменталните подесувања за страницата <strong>$1</strong>:',
+'protect-default' => '(по основно)',
+'protect-level-autoconfirmed'=> 'Блокирај ги нерегистрираните корисници',
+'protect-level-sysop' => 'Само администратори',
+'restriction-edit' => 'Уреди',
+'restriction-move' => 'Премести',
+'undelete' => 'Врати ја избришаната страница',
+'undeletepage' => 'Погледај и врати ги избришаните страници',
+'viewdeletedpage' => 'Прегледај ги избришаните страници',
+'undeletepagetext' => 'Следните страници се избришани, но сеуште се во архивата и можат да бидат обновени. Архивата може периодично да се чисти.',
+'undeleteextrahelp' => 'За да ја вратите целата страница, одселектирајте ги сите полиња
+и притиснете на \'\'\'\'\'Врати\'\'\'\'\'. За да извршите селективно враќање,
+селектирајте ги полињата до соодветните верзии за враќање и притиснете
+на \'\'\'\'\'Врати\'\'\'\'\'. Со притиснување на \'\'\'\'\'Ресетирај\'\'\'\'\' ги бришете
+коментарот и сите полиња за штиклирање.',
+'undeletearticle' => 'Обновување на избришана страница',
+'undeleterevisions' => '$1 архивирани верзии',
+'undeletehistory' => 'Ако ја обновите страницата, сите верзии ќе бидат вратени во историјата.
+Ако нова страница со исто име е создадена по бришењето, обновените
+верзии ќе се појават во претходната историја, и тековната верзија на постоечката страница
+нема да биде автоматски заменета.',
+'undeletehistorynoadmin'=> 'Оваа статија беше избришана. Причината за бришењето е наведена подолу,
+заедно со информации за корисникот кој ја уредувал страницата пред бришењето. Целиот текст
+од избришаните верзии е достапен само за администраторите.',
+'undeleterevision' => 'Избришана ревизија на $1',
+'undeletebtn' => 'Обнови!',
+'undeletereset' => 'Ресетирај',
+'undeletecomment' => 'Коментар:',
+'undeletedarticle' => 'обновена "[[$1]]"',
+'undeletedrevisions' => '$1 обновени верзии',
+'undeletedrevisions-files'=> 'вратени $1 ревизии и $2 датотеки',
+'undeletedfiles' => 'Вратени $1 датотеки',
+'cannotundelete' => 'Враќањето не успеа, некој друг можеби ја вратил страницата претходно.',
+'undeletedpage' => '<big>\'\'\'$1 е обновена\'\'\'</big>
+
+Видете ја [[Special:Log/delete|историјата на бришења]] за листа на скоро избришани и обновени страници.',
+'namespace' => 'Именски простор:',
+'invert' => 'Обратен избор',
+'contributions' => 'Придонеси',
+'mycontris' => 'Моите придонеси',
+'contribsub' => 'За $1',
+'nocontribs' => 'Не се пронајдени промени што одговараат на овој критериум.',
+'ucnote' => 'Подолу се последните <b>$1</b> промени на корисникот, во последните <b>$2</b> дена.',
+'uclinks' => 'Гледај ги последните $1 промени; гледај ги последните $2 дена.',
+'uctop' => ' (врв)',
+'newbies' => 'новајлија',
+'sp-newimages-showfrom' => 'Прикажи ги новите слики почнувајќи од $1',
+'sp-contributions-newest'=> 'Најнови',
+'sp-contributions-oldest'=> 'Најстари',
+'sp-contributions-newer'=> 'Нови $1',
+'sp-contributions-older'=> 'Стари $1',
+'sp-contributions-newbies-sub'=> 'За новајлии',
+'whatlinkshere' => 'Што е поврзано со ова',
+'notargettitle' => 'Нема цел',
+'notargettext' => 'Не одредивте целна страница или корисник
+на кој би се применила функцијата.',
+'linklistsub' => '(Листа на врски)',
+'linkshere' => 'Следните страници покажуваат кон \'\'\'[[:$1]]\'\'\':',
+'nolinkshere' => 'Ниедна страница не е поврзана со \'\'\'[[:$1]]\'\'\'.',
+'isredirect' => 'пренасочувачка страница',
+'istemplate' => 'вклучување',
+'blockip' => 'Блокирај го корисникот',
+'blockiptext' => 'Користете го долниот формулар да го забраните пристапот за пишување
+од одредена IP адреса или корисничко име.
+Ова единствено треба да се прави за да се спречи вандализам, и во
+согласност со [[Project:Википедија политика|политиката]].
+Пополнете конкретна причина подолу (на пример, цитирање на конкретни
+страници што биле вандализирани).',
+'ipaddress' => 'IP адреса',
+'ipadressorusername' => 'IP адреса или корисничко име',
+'ipbexpiry' => 'Истек на рокот',
+'ipbreason' => 'Причина',
+'ipbanononly' => 'Блокирај само анонимни корисници',
+'ipbcreateaccount' => 'Оневозможи креирање сметки',
+'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',
+'ipbotheroption' => 'друго',
+'badipaddress' => 'Невалидна IP адреса',
+'blockipsuccesssub' => 'Успешно блокирање',
+'blockipsuccesstext' => '"$1" беше блокиран.
+<br />Видете ја [[Special:Ipblocklist|листата на блокирани IP адреси]] за преглед на блокирањата.',
+'unblockip' => 'Деблокирај го корисникот',
+'unblockiptext' => 'Користете го долниот формулар да го обновите правото на пишување на претходно блокирана IP адреса или корисничко име.',
+'ipusubmit' => 'Деблокирај ја оваа адреса',
+'unblocked' => '[[User:$1|$1]] беше одблокиран',
+'ipblocklist' => 'Листа на блокирани IP адреси и кориснички имиња',
+'blocklistline' => '$1, $2 го блокираше $3 ($4)',
+'infiniteblock' => 'бесконечно',
+'expiringblock' => 'истекува на $1',
+'anononlyblock' => 'само анон.',
+'createaccountblock' => 'забрането креирање сметки',
+'ipblocklistempty' => 'Листата на блокирања е празна.',
+'blocklink' => 'блокирај',
+'unblocklink' => 'деблокирај',
+'contribslink' => 'придонеси',
+'autoblocker' => 'Автоматски сте блокирани бидејќи делите IP адреса со "$1". Причина "$2".',
+'blocklogpage' => 'Дневник на блокирања',
+'blocklogentry' => 'блокиран "[[$1]]" со истек на рокот $2',
+'blocklogtext' => 'Ова е дневник на блокирањата и деблокирањата, извршени од овој корисник. Автоматски
+блокираните IP адреси не се наведени. Видете ја [[Special:Ipblocklist|листата на блокирани IP адреси]] за листа на тековни забрани и блокирања.',
+'unblocklogentry' => 'деблокиран "$1"',
+'range_block_disabled' => 'Администраторската можност да блокираат IP групи е исклучена.',
+'ipb_expiry_invalid' => 'Неважечки истек на рок.',
+'ipb_already_blocked' => '"$1" е веќе блокиран',
+'ip_range_invalid' => 'Неважечки интервал за IP адреси.',
+'proxyblocker' => 'Прокси блокирач',
+'ipb_cant_unblock' => 'Грешка: $1 не постои. Можеби веќе е одблокиран.',
+'proxyblockreason' => 'Вашата IP адреса е блокирана бидејќи е отворено прокси. Ве молиме контактирајте со вашиот доставувач на Интернет услуги или техничката поддршка и информирајте ги за овој сериозен безбедносен проблем.',
+'proxyblocksuccess' => 'Готово.',
+'sorbsreason' => 'Вашата IP адреса е запишана како отворено прокси во [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason'=> 'Вашата IP адреса е наведена како отворено прокси во [http://www.sorbs.net SORBS] DNSBL. Не можете да креирате сметка',
+'lockdb' => 'Заклучи ја базата',
+'unlockdb' => 'Отклучи ја базата',
+'lockdbtext' => 'Заклучувањето на базата ќе им ја укине можноста на сите корисници да уредуваат страници, да ги менуваат нивните прилагодувања, да ги уредуваат нивните листи на набљудувани страници, и се останато што бара промени во базата. Ве молиме потврдете дека ова е вашата намера, и дека ќе ја отклучите базата кога ќе ја завршите работата околу нејзиното одржување.',
+'unlockdbtext' => 'Отклучувањето на базата ќе им ја врати можноста на сите
+корисници да уредуваат страници, да ги менуваат нивните прилагодувања, да ги уредуваат нивните листи на набљудувани страници, и се останато што бара промени во базата.
+Ве молиме потврдете дека ова е вашата намера.',
+'lockconfirm' => 'Да, навистина сакам да ја заклучам базата.',
+'unlockconfirm' => 'Да, навистина сакам да ја отклучам базата.',
+'lockbtn' => 'Заклучи ја базата',
+'unlockbtn' => 'Отклучи ја базата',
+'locknoconfirm' => 'Не ја потврдивте вашата намера.',
+'lockdbsuccesssub' => 'Базата е заклучена',
+'unlockdbsuccesssub' => 'Базата е отклучена',
+'lockdbsuccesstext' => 'Базата е заклучена. <br />Сетете се да ја отклучите кога ќе завршите со нејзиното одржување.',
+'unlockdbsuccesstext' => 'Базата е отклучена.',
+'lockfilenotwritable' => 'Датотеката за заклучување на базата не е отворен за пишување. За да ја заклучите/отклучите базата, датотеката мора да биде достапна за пишување од веб серверот.',
+'databasenotlocked' => 'Базата не е заклучена.',
+'makesysoptitle' => 'Претвори го корисникот во администратор',
+'makesysoptext' => 'Овој формулар се користи од бирократи за претворање на обични корисници во администратори. Напишете го името на корисникот во полето и притиснете го копчето да го претворите корисникот во администратор',
+'makesysopname' => 'Име на корисникот:',
+'makesysopsubmit' => 'Претвори го овој корисник во администратор',
+'makesysopok' => '<b>Корисникот "$1" сега е администратор</b>',
+'makesysopfail' => '<b>Корисникот "$1" не може да биде претворен во администратор. (Дали го внесовте правилно името?)</b>',
+'setbureaucratflag' => 'Постави „бирократ“ знаменце',
+'rightslog' => 'Историја на корисничките права',
+'rightslogtext' => 'Ова е дневник на промени на кориснички права.',
+'rightslogentry' => 'променето групно членство за $1 од $2 во $3',
+'rights' => 'Права:',
+'set_user_rights' => 'Давање на кориснички права',
+'user_rights_set' => '<b>Корисничките права на "$1" се променети</b>',
+'set_rights_fail' => '<b> Корисничките права на "$1" не се променети. (Дали го внесовте правилно името?)</b>',
+'makesysop' => 'Претвори го корисникот во администратор',
+'already_sysop' => 'Овој корисник веќе е администратор',
+'already_bureaucrat' => 'Овој корисник веќе е бирократ',
+'rightsnone' => '(нема)',
+'movepage' => 'Премести ја страницата',
+'movepagetext' => 'Со користењето на долниот формулар можете да преименувате страница, преместувајќи ја целата нејзина историја на новото име. Стариот наслов ќе стане страница за пренасочување кон новиот наслов.<br />
+\'\'\'Врските кон стариот наслов на страницата нема да бидат сменети;\'\'\' проверете дали постојат двојни или прекинати пренасочувања.<br />
+На вас е одговорноста да се осигурате дека врските ќе продолжат да насочуваат таму за каде се предвидени.
+Имајте во предвид дека страницата НЕМА да биде преместена ако постои страница со новиот наслов, освен ако е празна или ако е пренасочување и нема историја на минати уредувања.<br />
+<b>ПРЕДУПРЕДУВАЊЕ!</b><br />
+Ова може да биде драстична и неочекувана промена за популарна страница; осигурајте се дека сте ги разбрале последиците од ова пред да продолжите.',
+'movepagetalktext' => 'Соодветната страница за разговор, доколку постои, ќе биде автоматски преместена заедно со неа, освен ако:
+*Ја преместувате страницата низ именски простори,
+*Непразна страница за разговор веќе постои за новиот наслов, или
+*Не сте го одштиклирале долното поле. Во тие случаи, вие ќе треба да ја преместите или споите страницата рачно, доколку сакате.',
+'movearticle' => 'Премести ја страницата',
+'movenologin' => 'Не сте најавени',
+'movenologintext' => 'Мора да бидете регистриран корисник и [[Special:Userlogin|најавен]] да преместите страница.',
+'newtitle' => 'Кон новиот наслов',
+'movepagebtn' => 'Премести ја страницата',
+'pagemovedsub' => 'Преместувањето успеа',
+'pagemovedtext' => 'Страницата "[[$1]]" е преместена на "[[$2]]".',
+'articleexists' => 'Страница со тоа име веќе постои, или името што го избравте не е валидно. Ве молиме изберете друго име.',
+'talkexists' => 'Самата страница беше преместена успешно, но страницата за разговор не можеше да биде преместена бидејќи веќе постои таква на новиот наслов. Ве молиме спојте ги рачно.',
+'movedto' => 'преместена како',
+'movetalk' => 'Премести ја и страницата за разговор, ако е возможно.',
+'talkpagemoved' => 'Соодветната страница за разговор исто така беше преместена.',
+'talkpagenotmoved' => 'Соодветната страница за разговор <strong>не беше</strong> преместена.',
+'1movedto2' => '[[$1]] преместена како [[$2]]',
+'1movedto2_redir' => '[[$1]] преместена како [[$2]] преку пренасочување',
+'movelogpage' => 'Дневник на преместувања',
+'movelogpagetext' => 'Подолу е листа на преместени страници.',
+'movereason' => 'Причина',
+'revertmove' => 'врати',
+'delete_and_move' => 'Избриши и премести',
+'delete_and_move_text' => '==Потребно бришење== Целната статија "[[$1]]" веќе постои. Дали сакате да ја избришете за да ослободите место за преместувањето?',
+'delete_and_move_confirm'=> 'Да, избриши ја страницата',
+'delete_and_move_reason'=> 'Избришано за да се ослободи место за преместувањето',
+'selfmove' => 'Страницата не може да биде преместена бидејќи целниот наслов се совпаѓа со првобитниот наслов.',
+'immobile_namespace' => 'Целниот наслов е од специјален тип; не може да се преместуваат страници во тој именски простор.',
+'export' => 'Извезување на страници',
+'exporttext' => 'Можете да извезете како XML текст, така и историја на една или група страници. Добиените податоци може да:
+*ги искористите во друг сајт, кој го користи МедијаВики софтверот ,
+*ги обработите или
+*едноставно да ги искористите за лични потреби.
+
+За да извезете неколку страници, секоја нова секција ставајте ја во \'\'\'нов ред\'\'\'. Потоа изберете дали ја сакате само тековната верзија (заедно со информацијата за последното уредување) или сите верзии (заедно со тековната) на страницата.
+
+Ако ја сакате само тековната верзија, би можеле да искористите врска од видот [[Special:Export/Шах]] за страницата [[Шах]].',
+'exportcuronly' => 'Вклучи ја само тековната верзија, не целосната историја',
+'exportnohistory' => '----
+\'\'\'Забелешка:\'\'\' извезувањето на целата историја на страниците преку овој формулар е оневозможено заради подобри перформанси.',
+'export-submit' => 'Извези',
+'allmessages' => 'Системски пораки',
+'allmessagesname' => 'Име',
+'allmessagesdefault' => 'Текст по основно',
+'allmessagescurrent' => 'Сегашен текст',
+'allmessagestext' => 'Ова е листа на сите системски пораки досапни во МедијаВики: именскиот простор.',
+'allmessagesnotsupportedUI'=> 'Моменталниот интерфејс јазик <b>$1</b> не е поддржан од Special:AllMessages на овој сајт.',
+'allmessagesnotsupportedDB'=> 'Special:AllMessages не е поддржан бидејќи wgUseDatabaseMessages е исклучен.',
+'allmessagesfilter' => 'Филтер за регуларни изрази:',
+'allmessagesmodified' => 'Прикажи само изменети',
+'thumbnail-more' => 'Зголеми',
+'missingimage' => '<b>Недостасува слика</b><br /><i>$1</i>',
+'filemissing' => 'Датотеката недостасува',
+'thumbnail_error' => 'Грешка во креирањето на мини-слика: $1',
+'import' => 'Увезување на страници',
+'importinterwiki' => 'Трансвики увезување',
+'import-interwiki-text' => 'Изберете вики и наслов на страница за внесување.
+Времињата и авторите на ревизиите ќе се зачуваат.
+Сите трансвики акции за внесување се бележат во [[Special:Log/import|историјата за внесување]].',
+'import-interwiki-history'=> 'Копирај ги сите постари верзии за оваа страница',
+'import-interwiki-submit'=> 'Внеси',
+'import-interwiki-namespace'=> 'Премести страница во именски простор:',
+'importtext' => 'Ве молиме извезете ја датотеката од изворното вики со користење на алатката Special:Export, зачувајте ја на вашиот диск и подигнете ја овде.',
+'importstart' => 'Внесувам страници...',
+'import-revision-count' => '$1 {{PLURAL:$1|ревизија|ревизии}}',
+'importnopages' => 'Нема страници за внесување.',
+'importfailed' => 'Увозот не успеа: $1',
+'importunknownsource' => 'Непознат тип за внесување',
+'importcantopen' => 'Неможам да ја отворам датотеката за внесување',
+'importbadinterwiki' => 'Лоша интервики врска',
+'importnotext' => 'Празно или без текст',
+'importsuccess' => 'Увозот успеа!',
+'importhistoryconflict' => 'Постои конфликтна историја на верзиите (можно е страницата веќе да била внесена)',
+'importnosources' => 'Нема дефинирано трансвики извори за увезување и директните подигнувања на историја се оневозможени.',
+'importnofile' => 'Нема подигнато увозна датотека.',
+'importuploaderror' => 'Подигнувањето на увозната датотека не успеа; можеби датотеката е поголема од максималната дозволена големина.',
+'importlogpage' => 'Дневник на внесувања',
+'importlogpagetext' => 'Административно внесување на страници со историја од други викија.',
+'import-logentry-upload'=> 'внесена [[$1]] со подигнување',
+'import-logentry-upload-detail'=> '$1 ревизија(и)',
+'import-logentry-interwiki'=> 'трансвикифиран $1',
+'import-logentry-interwiki-detail'=> '$1 ревизија(и) од $2',
+'accesskey-diff' => 'v',
+'tooltip-search' => 'Пребарајте на {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Обележете ја промената како ситна [alt-i]',
+'tooltip-save' => 'Зачувајте ги вашите промени [alt-s]',
+'tooltip-preview' => 'Прегледајте ги вашите промени, ве молиме користете го ова пред зачувување! [alt-p]',
+'tooltip-diff' => 'Покажи кои промени ги направи во текстот. [alt-v]',
+'tooltip-compareselectedversions'=> 'Видете ги разликите меѓу двете избрани верзии на страницата. [alt-v]',
+'tooltip-watch' => 'Додај ја оваа страница во набљудуваните страници [alt-w]',
+'common.css' => '/** CSS кодот на оваа страница ќе се примени на сите маски */',
+'monobook.css' => '/* преку уредување на оваа датотека можете да ја прилагодите Monobook маската за целиот сајт */',
+'nodublincore' => 'Dublin Core RDF метаподатоци се оневозможени за овој сервер.',
+'nocreativecommons' => 'Creative Commons RDF метаподатоци се оневозможени за овој сервер.',
+'notacceptable' => 'Вики серверот не може да генерира податоци во формат погоден за вашиот клиент.',
+'anonymous' => 'Анонимен корисник од {{SITENAME}}',
+'siteuser' => 'корисник на {{SITENAME}} $1',
+'lastmodifiedatby' => 'Последната промена на страницата е извршена од $3, на $2, $1.',
+'and' => 'и',
+'othercontribs' => 'Засновано на делото на $1.',
+'others' => 'други',
+'siteusers' => 'корисници на {{SITENAME}} $1',
+'creditspage' => 'Библиографија и извори',
+'nocredits' => 'Не постојат библиографија и извори за оваа страница.',
+'spamprotectiontitle' => 'Филтер за заштита од спам',
+'spamprotectiontext' => 'Страницата која сакавте да ја зачувате беше блокирана од филтерот за спам. Ова најверојатно е предизвикано од врска кон надворешен сајт.',
+'spamprotectionmatch' => 'Следниот текст е она што го предизвика нашиот филтер за спам: $1',
+'subcategorycount' => '{{PLURAL:$1|Постои една подкатегорија|Постојат $1 подкатегории}} во оваа категорија.',
+'categoryarticlecount' => '{{PLURAL:$1|Постои една статија|Постојат $1 статии}} во оваа категорија.',
+'listingcontinuesabbrev'=> 'продолжува',
+'spambot_username' => 'МедијаВики чистач на спам',
+'spam_reverting' => 'Враќам на последната верзија што не содржи врска до $1',
+'spam_blanking' => 'Сите верзии содржеа врски до $1, бришам',
+'infosubtitle' => 'Информација за страницата',
+'numedits' => 'Број на уредувања (статија): $1',
+'numtalkedits' => 'Број на уредувања (страница за разговор): $1',
+'numwatchers' => 'Број на набљудувачи: $1',
+'numauthors' => 'Број на различни автори (статија): $1',
+'numtalkauthors' => 'Број на различни автори (страница за разговор): $1',
+'mw_math_png' => 'Секогаш исцртувај во PNG',
+'mw_math_simple' => 'HTML ако е многу едноставно ако не во PNG',
+'mw_math_html' => 'HTML ако е можно ако не PNG',
+'mw_math_source' => 'Остави го како TeX (за теx прелистувачите)',
+'mw_math_modern' => 'Препорачливо за современи прелистувачи',
+'mw_math_mathml' => 'MathML ако е можно (експериментално)',
+'markaspatrolleddiff' => 'Означи како проверена верзија',
+'markaspatrolledtext' => 'Означи ја верзијата како проверена',
+'markedaspatrolled' => 'Проверена верзија',
+'markedaspatrolledtext' => 'Избраната верзија е означена како проверена.',
+'rcpatroldisabled' => 'Патролирањето е деактивирано',
+'rcpatroldisabledtext' => 'Патролирањето на Скорешните промени е деактивирано.',
+'markedaspatrollederror'=> 'Не можам да означам како проверена',
+'markedaspatrollederrortext'=> 'Морате да внесете верзија за да ја означите како проверена.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Мојата корисничка страница\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Корисничка страница за IP адресата од која уредувате\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Мојата страница за разговор \');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Разговор за уредувањата од оваа IP адреса\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Мои прилагодувања\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Листа на страници кои сте избрале да ги набљудувате.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Листа на моите придонеси\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Ве охрабруваме да се најавите, иако тоа не е задолжително.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Ве охрабруваме да се најавите, иако тоа не е задолжително.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Одјавете се\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Разговор за страницата\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Можете да ја уредите оваа страница. Ве молиме користете го копчето за преглед пред зачувување.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Додадете коментар во овој разговор.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Оваа страница е заштитена. Можете да го видите изворниот код.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Претходни верзии на оваа страница.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Заштитете ја оваа страница\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Избришете ја оваа страница\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Обновете ги уредувањата направени на оваа страница што постоеле пред да биде избришана\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Преместете ја оваа страница\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Додајте ја оваа страница во набљудувани страници\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Отстранете ја оваа страница од набљудувани страници\');
+ ta[\'search\'] = new Array(\'f\',\'Пребарајте го викито\');
+ ta[\'p-logo\'] = new Array(\'\',\'Главна страница\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Посетете ја главната страница\');
+ ta[\'n-portal\'] = new Array(\'\',\'За проектот, што можете да направите, каде да најдете некои работи\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Најдете информации за тековните настани\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Листа на скорешни промени на викито.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Случајна страница\');
+ ta[\'n-help\'] = new Array(\'\',\'Место каде што може да се информирате.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Поддржете ја Википедија\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Листа на сите вики страници поврзани овде\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Скорешни промени поврзани од оваа страница\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed за страницата\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed за страницата\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Видете ја листата на придонеси на овој корисник\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Пратете е-пошта на овој корисник\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Подигнете слики или медија датотеки\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Листа на сите специјални страници\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Видете ја основната страница\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Видете ја корисничката страница\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Видете ја медија страницата\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Ова е специјална страница, не можете да ја уредувате.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Видете ја проектната страница\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Видете ја страницата на сликата\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Видете ја системската порака\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Видете го шаблонот\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Видете ја помошната страница\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Видете ја страницата со категории\');',
+'deletedrevision' => 'Избришана стара верзија $1.',
+'previousdiff' => '< Претходна разлика',
+'nextdiff' => 'Следна разлика >',
+'imagemaxsize' => 'Ограничи ги сликите на нивните описни страници до:',
+'thumbsize' => 'Големина на мини-слика:',
+'showbigimage' => 'Преземете ја верзијата со висока резолуција ($1x$2, $3 KB)',
+'newimages' => 'Галерија на нови слики',
+'showhidebots' => '($1 ботови)',
+'noimages' => 'Нема ништо.',
+'specialloguserlabel' => 'Корисник:',
+'speciallogtitlelabel' => 'Наслов:',
+'passwordtooshort' => 'Вашата лозинка е прекратка. Мора да има најмалку $1 знаци.',
+'mediawarning' => '\'\'\'Предупредување\'\'\': Оваа датотека може да содржи штетен код, нејзиното извршување може да му наштети на вашиот систем<hr />',
+'fileinfo' => '$1KB, MIME тип: <code>$2</code>',
+'metadata' => 'Метаподатоци',
+'metadata-help' => 'Оваа датотека содржи дополнителни информации, најверојатно додадени од дигитален апарат или скенер користен за нивното креирање или дигитализација. Ако датотеката се промени, некои детали може да не одговараат на модифицираната слика.',
+'metadata-expand' => 'Прикажи ги проширените информации',
+'metadata-collapse' => 'Сокриј ги проширените информации',
+'exif-imagewidth' => 'Ширина',
+'exif-imagelength' => 'Висина',
+'exif-bitspersample' => 'Битови по компонента',
+'exif-compression' => 'Шема на компресијата',
+'exif-photometricinterpretation'=> 'Колор модел',
+'exif-orientation' => 'Ориентација на кадарот',
+'exif-samplesperpixel' => 'Број на колор компоненти',
+'exif-planarconfiguration'=> 'Принцип на распоредот на податоците',
+'exif-ycbcrsubsampling' => 'Однос на компонентата Y спрема C',
+'exif-ycbcrpositioning' => 'Распоред на компонентите Y и C',
+'exif-xresolution' => 'Хоризонтална резолуција',
+'exif-yresolution' => 'Вертикална резолуција',
+'exif-resolutionunit' => 'Единица за резолуција',
+'exif-stripoffsets' => 'Положба на блокот на податоци',
+'exif-rowsperstrip' => 'Број на редови во блокот',
+'exif-stripbytecounts' => 'Големина на компресираниот блок',
+'exif-jpeginterchangeformat'=> 'Оддалеченост на JPEG прегледот од почетокот на фајлот',
+'exif-jpeginterchangeformatlength'=> 'Количина на бајтови во JPEG прегледот',
+'exif-transferfunction' => 'Функција на преобликување на колор просторот',
+'exif-whitepoint' => 'Хромацитет на белата точка',
+'exif-primarychromaticities'=> 'Хроматичност на примарните бои',
+'exif-ycbcrcoefficients'=> 'Матрични коефициенти на трансформација на колор просторот',
+'exif-referenceblackwhite'=> 'Место на белата и црната точка',
+'exif-datetime' => 'Датум на последната промена на датотеката',
+'exif-imagedescription' => 'Име на сликата',
+'exif-make' => 'Производител на камерата',
+'exif-model' => 'Модел на камерата',
+'exif-software' => 'Користен софтвер',
+'exif-artist' => 'Автор',
+'exif-copyright' => 'Носител на авторските права',
+'exif-exifversion' => 'Exif верзија',
+'exif-flashpixversion' => 'Поддржана верзија на Flashpix',
+'exif-colorspace' => 'Простор на бојата',
+'exif-componentsconfiguration'=> 'Значење на секоја од компонентите.',
+'exif-compressedbitsperpixel'=> 'Мод на компресирање на сликата',
+'exif-pixelydimension' => 'Полна висина на сликата',
+'exif-pixelxdimension' => 'Полна ширина на сликата',
+'exif-makernote' => 'Забелешки на производителот',
+'exif-usercomment' => 'Коментар на корисникот',
+'exif-relatedsoundfile' => 'Поврзана звучна датотека',
+'exif-datetimeoriginal' => 'Датум и време на сликање',
+'exif-datetimedigitized'=> 'Датум и време на дигитализација',
+'exif-subsectime' => 'Дел од секундата во кој е сликано',
+'exif-subsectimeoriginal'=> 'Дел од секундата во кој е фотографирано',
+'exif-subsectimedigitized'=> 'Дел од секундата во кој е дигитализирано',
+'exif-exposuretime' => 'Експозиција',
+'exif-fnumber' => 'F број на отворот на блендата',
+'exif-exposureprogram' => 'Програм за експозиција',
+'exif-spectralsensitivity'=> 'Спектрална осетливост',
+'exif-isospeedratings' => 'ИСО вредност',
+'exif-oecf' => 'Оптоелектронски фактор на конверзија',
+'exif-shutterspeedvalue'=> 'Брзина на затворачот',
+'exif-aperturevalue' => 'Отвор на блендата',
+'exif-brightnessvalue' => 'Светлост',
+'exif-exposurebiasvalue'=> 'Компензација на експозицијата',
+'exif-maxaperturevalue' => 'Минимален број на отворот на блендата',
+'exif-subjectdistance' => 'Оддалеченост до објектот',
+'exif-meteringmode' => 'Режим на мерачот на времето',
+'exif-lightsource' => 'Светлосен извор',
+'exif-flash' => 'Блиц',
+'exif-focallength' => 'Фокусна далечина на леќата',
+'exif-subjectarea' => 'Положба и површина на објектот',
+'exif-flashenergy' => 'Енергија на блицот',
+'exif-spatialfrequencyresponse'=> 'Просторна фреквенциска карактеристика',
+'exif-focalplanexresolution'=> 'Хоризонтална резолуција на фокусната рамнина',
+'exif-focalplaneyresolution'=> 'Вертикална резолуција на фокусната рамнина',
+'exif-focalplaneresolutionunit'=> 'Единица за резолуција на фокусната рамнина',
+'exif-subjectlocation' => 'Положба на субјектот',
+'exif-exposureindex' => 'Индекс на експозицијата',
+'exif-sensingmethod' => 'Тип на сензори',
+'exif-filesource' => 'Извор на датотеката',
+'exif-scenetype' => 'Тип на сцена',
+'exif-cfapattern' => 'CFA шаблон',
+'exif-customrendered' => 'Додатна обработка на сликата',
+'exif-exposuremode' => 'Режим за избор на експозицијата',
+'exif-whitebalance' => 'Баланс на белата боја',
+'exif-digitalzoomratio' => 'Однос на дигиталниот зум',
+'exif-focallengthin35mmfilm'=> 'Еквивалент на фокусната далечина за 35 mm филм',
+'exif-scenecapturetype' => 'Тип на сцена на снимката',
+'exif-gaincontrol' => 'Контрола на осветленоста',
+'exif-contrast' => 'Контраст',
+'exif-saturation' => 'Сатурација',
+'exif-sharpness' => 'Острина',
+'exif-devicesettingdescription'=> 'Опис на подесувањата на апаратот',
+'exif-subjectdistancerange'=> 'Распон на оддалеченоста на субјектот',
+'exif-imageuniqueid' => 'Единствен идентификатор на сликата',
+'exif-gpsversionid' => 'Верзија на блокот на GPS информации',
+'exif-gpslatituderef' => 'Северна или Јужна ширина',
+'exif-gpslatitude' => 'Ширина',
+'exif-gpslongituderef' => 'Источна или западна должина',
+'exif-gpslongitude' => 'Должина',
+'exif-gpsaltituderef' => 'Висина под или над морето',
+'exif-gpsaltitude' => 'Висина',
+'exif-gpstimestamp' => 'GPS време (атомски часовник)',
+'exif-gpssatellites' => 'Употребени сателити',
+'exif-gpsstatus' => 'Статус на приемникот',
+'exif-gpsmeasuremode' => 'Режим на мерењето',
+'exif-gpsdop' => 'Прецизност на мерењето',
+'exif-gpsspeedref' => 'Единица за брзината',
+'exif-gpsspeed' => 'Брзина на GPS приемникот',
+'exif-gpstrackref' => 'Тип на азимутот на приемникот (вистински или магнетен)',
+'exif-gpstrack' => 'Азимут на приемникот',
+'exif-gpsimgdirectionref'=> 'Тип на азимутот на сликата (вистински или магнетен)',
+'exif-gpsimgdirection' => 'Азимут на сликата',
+'exif-gpsmapdatum' => 'Користен геодетски координатен систем',
+'exif-gpsdestlatituderef'=> 'Индекс за географската ширина на објектот',
+'exif-gpsdestlatitude' => 'Географска ширина на објектот',
+'exif-gpsdestlongituderef'=> 'Индекс за географската должина на објектот',
+'exif-gpsdestlongitude' => 'Географска должина на објектот',
+'exif-gpsdestbearingref'=> 'Индекс на азимутот на објектот',
+'exif-gpsdestbearing' => 'Азимут на објектот',
+'exif-gpsdestdistanceref'=> 'Мерна единица за оддалеченоста на објектот',
+'exif-gpsdestdistance' => 'Оддалеченост на објектот',
+'exif-gpsprocessingmethod'=> 'Име на методот за обработка на GPS податоците',
+'exif-gpsareainformation'=> 'Има на GPS зоната',
+'exif-gpsdatestamp' => 'GPS датум',
+'exif-gpsdifferential' => 'GPS диференцијална корекција',
+'exif-compression-1' => 'Некомпресиран',
+'exif-orientation-1' => 'Нормално',
+'exif-orientation-2' => 'Обратно по хоризонтала',
+'exif-orientation-3' => 'Ротирано 180°',
+'exif-orientation-4' => 'Обратно по вертикала',
+'exif-orientation-5' => 'Ротирано 90° спротивно од правецот на стрелките на часовникот и обратно по вертикала',
+'exif-orientation-6' => 'Ротирано 90° во правец на стрелките на часовникот',
+'exif-orientation-7' => 'Ротирано 90° во правец на стрелките на часовникот и обратно по вертикала',
+'exif-orientation-8' => 'Ротирано 90° спротивно од правецот на стрелките на часовникот',
+'exif-planarconfiguration-1'=> 'делумен формат',
+'exif-planarconfiguration-2'=> 'планарен формат',
+'exif-componentsconfiguration-0'=> 'не постои',
+'exif-exposureprogram-0'=> 'Недефинирано',
+'exif-exposureprogram-1'=> 'Рачно',
+'exif-exposureprogram-2'=> 'Нормална програма',
+'exif-exposureprogram-3'=> 'Приоритет на отворот на блендата',
+'exif-exposureprogram-4'=> 'Приоритет на затворачот',
+'exif-exposureprogram-5'=> 'Уметничка програма (на база на нужната длабочина на полето)',
+'exif-exposureprogram-6'=> 'Спортска програма (на база на што побрз затворач)',
+'exif-exposureprogram-7'=> 'Портретен режим (за крупни кадри со неоцтра позадина)',
+'exif-exposureprogram-8'=> 'Пејсажен режим (за слики на пејсажи со остра позадина)',
+'exif-subjectdistance-value'=> '$1 метри',
+'exif-meteringmode-0' => 'Непознато',
+'exif-meteringmode-1' => 'Просек',
+'exif-meteringmode-2' => 'Просек со тежиште на средина',
+'exif-meteringmode-3' => 'Точка',
+'exif-meteringmode-4' => 'Повеќе точки',
+'exif-meteringmode-5' => 'Матричен',
+'exif-meteringmode-6' => 'Делумен',
+'exif-meteringmode-255' => 'Друго',
+'exif-lightsource-0' => 'Непознато',
+'exif-lightsource-1' => 'Дневна светлина',
+'exif-lightsource-2' => 'Флуоресцентно',
+'exif-lightsource-3' => 'Волфрам (светло)',
+'exif-lightsource-4' => 'Блиц',
+'exif-lightsource-9' => 'Убаво време',
+'exif-lightsource-10' => 'Облачно време',
+'exif-lightsource-11' => 'Сенка',
+'exif-lightsource-12' => 'Флуоресцентна светлина (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Флуоресцентна светлина (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Флуоресцентна светлина (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Бела флуоресцентност (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Стандардна светлина A',
+'exif-lightsource-18' => 'Стандардна светлина B',
+'exif-lightsource-19' => 'Стандардна светлина C',
+'exif-lightsource-24' => 'ISO студиски волфрам',
+'exif-lightsource-255' => 'Друг светлосен извор',
+'exif-focalplaneresolutionunit-2'=> 'инчи',
+'exif-sensingmethod-1' => 'Недефинирано',
+'exif-sensingmethod-2' => 'Еднокристален матричен сензор',
+'exif-sensingmethod-3' => 'Двокристален матричен сензор',
+'exif-sensingmethod-4' => 'Трокристален матричен сензор',
+'exif-sensingmethod-5' => 'Секвенцијален матричен сензор',
+'exif-sensingmethod-7' => 'Тробоен линеарен сензор',
+'exif-sensingmethod-8' => 'Секвенцијален линеарен сензор',
+'exif-filesource-3' => 'Дигитален фотоапарат',
+'exif-scenetype-1' => 'Директно фотографирана слика',
+'exif-customrendered-0' => 'Нормален процес',
+'exif-customrendered-1' => 'Нестандарден процес',
+'exif-exposuremode-0' => 'Автоматска експозиција',
+'exif-exposuremode-1' => 'Рачна експозиција',
+'exif-exposuremode-2' => 'Автоматски со зададен распон',
+'exif-whitebalance-0' => 'Автоматски',
+'exif-whitebalance-1' => 'Рачно',
+'exif-scenecapturetype-0'=> 'Стандардно',
+'exif-scenecapturetype-1'=> 'Пејсаж',
+'exif-scenecapturetype-2'=> 'Портрет',
+'exif-scenecapturetype-3'=> 'Ноќна сцена',
+'exif-gaincontrol-0' => 'Нема',
+'exif-gaincontrol-1' => 'Мало зголемување',
+'exif-gaincontrol-2' => 'Големо зголемување',
+'exif-gaincontrol-3' => 'Мало смалување',
+'exif-gaincontrol-4' => 'Големо смалување',
+'exif-contrast-0' => 'Нормално',
+'exif-contrast-1' => 'Меко',
+'exif-contrast-2' => 'Грубо',
+'exif-saturation-0' => 'Нормално',
+'exif-saturation-1' => 'Ниска сатурација',
+'exif-saturation-2' => 'Висока сатурација',
+'exif-sharpness-0' => 'Нормално',
+'exif-sharpness-1' => 'Меко',
+'exif-sharpness-2' => 'Тврдо',
+'exif-subjectdistancerange-0'=> 'Непознато',
+'exif-subjectdistancerange-1'=> 'Крупен кадар (макро)',
+'exif-subjectdistancerange-2'=> 'Близок кадар',
+'exif-subjectdistancerange-3'=> 'Далечен кадар',
+'exif-gpslatitude-n' => 'Север',
+'exif-gpslatitude-s' => 'Југ',
+'exif-gpslongitude-e' => 'Исток',
+'exif-gpslongitude-w' => 'Запад',
+'exif-gpsstatus-a' => 'Мерење во тек',
+'exif-gpsstatus-v' => 'Подготвен за пренос',
+'exif-gpsmeasuremode-2' => 'Дводимензионално мерење',
+'exif-gpsmeasuremode-3' => 'Тродимензионално мерење',
+'exif-gpsspeed-k' => 'Километри на час',
+'exif-gpsspeed-m' => 'Милји на час',
+'exif-gpsspeed-n' => 'Јазли',
+'exif-gpsdirection-t' => 'Вистински правец',
+'exif-gpsdirection-m' => 'Магнетен правец',
+'edit-externally' => 'Уредете ја оваа датотека со надворешна апликација',
+'edit-externally-help' => 'Видете [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] за повеќе информации.',
+'recentchangesall' => 'сите',
+'imagelistall' => 'сите',
+'watchlistall1' => 'сите',
+'watchlistall2' => 'сите',
+'namespacesall' => 'сите',
+'confirmemail' => 'Потврди е-поштенска адреса',
+'confirmemail_noemail' => 'Немате поставено валидна е-поштенска адреса во вашите [[Special:Preferences|прилагодувања]].',
+'confirmemail_text' => 'Ова вики бара да ја валидирате вашата е-поштенска адреса
+пред да ги користите можностите за е-пошта. Активирајте го копчето подолу за да
+пратите потврдна порака до вашата адреса. Оваа порака ќе содржи врска со код;
+отворете ја врската во вашиот прелистувач за да потврдите дека вашата е-поштенска
+адреса е валидна.',
+'confirmemail_send' => 'Прати код за потврда',
+'confirmemail_sent' => 'Пораката за потврда е пратена.',
+'confirmemail_sendfailed'=> 'Не можам да пратам порака со код за потврда. Проверете дали адресата содржи неважечки знаци.',
+'confirmemail_invalid' => 'Неточен код за потврда. Кодот можеби е истечен.',
+'confirmemail_needlogin'=> 'Морате да $1 за да ја потврдите вашата е-поштенска адреса.',
+'confirmemail_success' => 'Вашата е-поштенска адреса сега е потврдена. Можете да се најавите и да уживате во викито.',
+'confirmemail_loggedin' => 'Вашата е-поштенска адреса сега е потврдена.',
+'confirmemail_error' => 'Нешто тргна наопаку при снимањето на вашата потврда.',
+'confirmemail_subject' => '{{SITENAME}} потврда за е-поштенска адреса',
+'confirmemail_body' => 'Некој, најверојатно вие, од IP адресата $1, ја регистрираше
+сметката "$2" со оваа е-поштенска адреса на {{SITENAME}}.
+
+За да потврдите дека оваа сметка навистина ви припаѓа вам и да ги
+активирате е-поштенските можности на {{SITENAME}}, отворете ја оваа
+врска во вашиот прелистувач:
+
+$3
+
+Ако ова *не* сте вие, не одете на врската. Овој код за потврда ќе
+истече на $4.',
+'tryexact' => 'Обиди се точно',
+'searchfulltext' => 'Барај низ целиот текст',
+'createarticle' => 'Создади статија',
+'scarytranscludedisabled'=> '[Интервики вклучувањето е оневозможено]',
+'scarytranscludefailed' => '[Преземањето на шаблонот за $1 не успеа]',
+'scarytranscludetoolong'=> '[Адресата е предолга; жалиме]',
+'trackbackbox' => '<div id="mw_trackbacks">
+Враќања за оваа статија:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Бришење])',
+'trackbacklink' => 'Враќање',
+'trackbackdeleteok' => 'Враќањето беше успешно избришано.',
+'deletedwhileediting' => 'Предупредување: Оваа страница беше избришана откако почнавте со уредување!',
+'confirmrecreate' => 'Корисникот [[User:$1|$1]] ([[User talk:$1|talk]]) ја избриша оваа статија откако почнавте да ја уредувате заради:
+: \'\'$2\'\'
+Потврдете дека навистина сакате повторно да ја креирате оваа статија.',
+'recreate' => 'Повторно направи',
+'tooltip-recreate' => 'Повторно креирај ја страницата иако беше избришана',
+'unit-pixel' => 'п',
+'redirectingto' => 'Пренасочувам на [[$1]]...',
+'confirm_purge' => 'Да се исчисти кешот на оваа страница?
+
+$1',
+'confirm_purge_button' => 'Да',
+'youhavenewmessagesmulti'=> 'Имате нови пораки на $1',
+'searchcontaining' => 'Барам статии што содржат \'\'$1\'\'.',
+'searchnamed' => 'Статии со име: \'\'$1\'\'.',
+'articletitles' => 'Статии кои почнуваат со \'\'$1\'\'',
+'hideresults' => 'Сокриј резултати',
+'displaytitle' => '(Врски до оваа страница како [[$1]])',
+'loginlanguagelabel' => 'Јазик: $1',
+'imgmultipageprev' => '&larr; претходна страница',
+'imgmultipagenext' => 'следна страница &rarr;',
+'imgmultigo' => 'Оди!',
+'imgmultigotopre' => 'Оди на страница',
+'ascending_abbrev' => 'раст',
+'descending_abbrev' => 'опаѓ',
+'table_pager_next' => 'Следна страница',
+'table_pager_prev' => 'Претходна страница',
+'table_pager_first' => 'Прва страница',
+'table_pager_last' => 'Последна страница',
+'table_pager_limit' => 'Прикажи $1 записи по страница',
+'table_pager_limit_submit'=> 'Оди',
+'table_pager_empty' => 'Нема резултати',
+);
+?>
diff --git a/languages/messages/MessagesMl.php b/languages/messages/MessagesMl.php
new file mode 100644
index 000000000000..d004f4359bb0
--- /dev/null
+++ b/languages/messages/MessagesMl.php
@@ -0,0 +1,23 @@
+<?php
+/** Malayalam (മലയാളം)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+
+$digitTransformTable = array(
+ '0' => '൦',
+ '1' => '൧',
+ '2' => '൨',
+ '3' => '൩',
+ '4' => '൪',
+ '5' => '൫',
+ '6' => '൬',
+ '7' => '൭',
+ '8' => '൮',
+ '9' => '൯'
+);
+
+?>
diff --git a/languages/messages/MessagesMs.php b/languages/messages/MessagesMs.php
new file mode 100644
index 000000000000..285cc0e91305
--- /dev/null
+++ b/languages/messages/MessagesMs.php
@@ -0,0 +1,817 @@
+<?php
+/** Malay (Bahasa Melayu)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# This localisation is based on a file kindly donated by the folks at MIMOS
+# http://www.asiaosc.org/enwiki/page/Knowledgebase_Home.html
+
+$quickbarSettings = array(
+ 'Tiada', 'Tetap sebelah kiri', 'Tetap sebelah kanan', 'Berubah-ubah sebelah kiri'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Istimewa', #Special
+ NS_MAIN => '',
+ NS_TALK => 'Perbualan',#Talk
+ NS_USER => 'Pengguna',#User
+ NS_USER_TALK => 'Perbualan_Pengguna',#User_talk
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Perbualan_$1',#Wikipedia_talk
+ NS_IMAGE => 'Imej',#Image
+ NS_IMAGE_TALK => 'Imej_Perbualan',#Image_talk
+ NS_MEDIAWIKI => 'MediaWiki',#MediaWiki
+ NS_MEDIAWIKI_TALK => 'MediaWiki_Perbualan',#MediaWiki_talk
+ NS_TEMPLATE => 'Templat',#Template
+ NS_TEMPLATE_TALK => 'Perbualan_Templat',#Template_talk
+ NS_CATEGORY => 'Kategori',#Category
+ NS_CATEGORY_TALK => 'Perbualan_Kategori',#Category_talk
+ NS_HELP => 'Bantuan',#Help
+ NS_HELP_TALK => 'Perbualan_Bantuan' #Help_talk
+);
+
+$datePreferences = false;
+
+
+$messages = array(
+
+# User Toggles
+
+"tog-underline" => "Gariskan pautan", #"Underline links",
+"tog-highlightbroken" => 'Formatkan pautan rosak <a href="" class="new">seperti ini</a> (ataupun seperti ini<a href="" class="internal">?</a>)', #'Format broken links <a href="" class="new">like this</a> (alternative: like this<a href="" class="internal">?</a>).',
+"tog-justify" => "Selaraskan perenggan", #"Justify paragraphs",
+"tog-hideminor" => "Sembunyikan suntingan kecil untuk perubahan terkini", #"Hide minor edits in recent changes",
+"tog-usenewrc" => "Pertingkatkan perubahan terkini (Javaskrip)",
+"tog-numberheadings" => "Nomborkan tajuk secara automatik", #"Auto-number headings",
+"tog-showtoolbar" => "Paparkan alat penyuntingan", #"Show edit toolbar",
+"tog-editsection"=> "Benarkan penyuntingan bahagian melalui pautan [sunting]",
+"tog-editsectiononrightclick" => "Benarkan penyuntingan melalui klik kanan<br /> pada tajuk bahagian (JavaSkrip)", #'Enable section editing by right clicking<br /> on section titles (JavaScript)',
+"tog-showtoc"=> "Paparkan jadual kandungan bagi rencana melebihi 3 tajuk", # "Show table of contents for articles with more than 3 headings",
+"tog-rememberpassword" => "Ingatkan kata laluan bagi setiap sesi", #"Remember password across sessions",
+"tog-editwidth" => "Kotak penyuntingan mencapai lebar penuh", #"Edit box has full width",
+"tog-editondblclick" => "Suntingkan halaman melalui dwiklik (JavaSkrip)", #"Edit pages on double click (JavaScript)"
+"tog-watchdefault" => "Masukkan halaman yang anda sunting ke senarai pantau", #"Add pages you edit to your watchlist",
+"tog-minordefault" => "Tandakan semua suntingan kecil secara lalai",#"Mark all edits minor by default"
+"tog-previewontop" => "Paparkan pratonton sebelum kotak penyuntingan dan bukan selepasnya", #"Show preview before edit box and not after it",
+"tog-previewonfirst" => "Paparkan penyuntingan pertama", #'Show preview on first edit'
+"tog-nocache" => "Matikan ingatan cache",
+'tog-enotifwatchlistpages' => "Emelkan saya jika terdapat perubahan halaman", #'Send me an email on page changes',
+'tog-enotifusertalkpages' => "Emelkan saya jika terdapat perubahan halaman perbualan saya", #'Send me an email when my user talk page is changed',
+'tog-enotifminoredits' => "Emelkan saya juga jika terdapat suntingan kecil pada halaman-halaman", #'Send me an email also for minor edits of pages',
+'tog-enotifrevealaddr' => "Tunjukkan alamat emel saya dalam emel pemberitahuan", #"Reveal my email address in notification mails",
+'tog-shownumberswatching' => "Paparkan bilangan pengguna yang memantau", #'Show the number of watching users',
+'tog-fancysig' => "Tandatangan mentah (tanpa pautan automatik)", #'Raw signatures (without automatic link)',
+'tog-externaleditor' => "Gunakan penyunting luar secara lalai", #'Use external editor by default',
+'tog-externaldiff' => "Gunakan perbezaan luar secara lalai", #'Use external diff by default',
+'underline-always' => "Sentiasa", #'Always',
+'underline-never' => "Jangan", #'Never',
+'underline-default' => "Lalai pelayar", #'Browser default',
+'skinpreview' => "Paparkan", #'(Preview)',
+
+
+# Dates
+
+'sunday' => 'Ahad', #'Sunday',
+'monday' => 'Isnin', #'Monday',
+'tuesday' => 'Selasa', #'Tuesday',
+'wednesday' => 'Rabu', #'Wednesday',
+'thursday' => 'Khamis', #'Thursday',
+'friday' => 'Jumaat', #'Friday',
+'saturday' => 'Sabtu', #'Saturday',
+'january' => 'Januari', #'January',
+'february' => 'Februari', #'February',
+'march' => 'Mac', #'March',
+'april' => 'April',
+'may_long' => 'Mei', #'May',
+'june' => 'Jun', #'June',
+'july' => 'Julai', #'July',
+'august' => 'Ogos', #'August',
+'september' => 'September',
+'october' => 'Oktober', #'October',
+'november' => 'November',
+'december' => 'Disember', #'December',
+'jan' => 'Jan',
+'feb' => 'Feb',
+'mar' => 'Mac', #'Mar',
+'apr' => 'Apr',
+'may' => 'Mei', #'May',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Ogo', #'Ogo',
+'sep' => 'Sep',
+'oct' => 'Okt', #'Oct',
+'nov' => 'Nov',
+'dec' => 'Dis', #'Dec',
+
+
+
+# Bits of text used by many pages:
+#
+"mainpage" => "Halaman Utama", #"Main Page",
+"mainpagetext" => "Atur cara Wiki berjaya dipasang.",
+"portal" => "Portal Masyarakat",
+"portal-url" => "{{ns:project}}:Portal Masyarakat",
+"about" => "Perihal",
+"aboutsite" => "Tentang {{SITENAME}}",
+"aboutpage" => "{{ns:project}}:Perihal", #"{{ns:project}}:About",
+"help" => "Bantuan",
+"helppage" => "{{ns:project}}:Bantuan",
+"bugreports" => "Laporan Pepijat",
+"bugreportspage" => "{{ns:project}}:Laporan Pepijat",
+"faq" => "FAQ",
+"faqpage" => "{{ns:project}}:FAQ",
+"edithelp" => "Bantuan menyunting",
+"edithelppage" => "{{ns:project}}:Menyunting",
+"newwindow" => "(terbuka dalam tetingkap baru)",
+"cancel" => "Batal",
+"qbfind" => "Cari",
+"qbbrowse" => "Tinjau", #"Browse",
+"qbedit" => "Sunting",
+"qbpageoptions" => "Halaman Ini", #"This page",
+"qbpageinfo" => "Konteks", #"Context",
+"qbmyoptions" => "Pilihan saya",
+"qbspecialpages" => "Halaman Istimewa",
+"moredotdotdot" => "Lebih lanjut...",
+"mypage" => "Halaman saya",
+"mytalk" => "Perbualan saya",
+"anontalk" => "Perbualan untuk IP ini",
+"navigation" => "Pelayaran",
+"currentevents" => "Peristiwa Semasa",
+"currentevents-url" => "{{ns:project}}:Hal Semasa",
+"disclaimers" => "Penafian",
+"disclaimerpage" => "Project:Penafian_umum",
+"errorpagetitle" => "Ralat Tajuk Halaman",
+"returnto" => "Kembali ke $1.", #"Return to $1.",
+//"tagline" => "Dari Wikipedia, ensiklopedia bebas", # "From {{ns:project}}, the free encyclopedia",
+"whatlinkshere" => "Halaman yang dipautkan ke sini", #"Pages that link here",
+"help" => "Bantuan",
+"search" => "Cari",
+"searchbutton" => "Cari",
+"go" => "Paparkan",
+'searcharticle' => "Paparkan",
+"history" => "Sejarah Halaman",
+"history_short" => "Sejarah",
+"info_short" => "Maklumat",
+"printableversion" => "Versi untuk dicetak",
+"editthispage" => "Sunting halaman ini",
+"delete" => "Hapus",
+"deletethispage" => "Hapuskan halaman ini", #"Delete this page",
+"protect" => "Lindung",
+"protectthispage" => "Lindungi halaman ini", #"Protect this page",
+"unprotectthispage" => "Nyahlindung halaman ini", #"Unprotect this page",
+"newpage" => "(cipta) Halaman baru", #'(create) "New page"',
+"talkpage" => "Halaman Perbualan",
+"specialpage" => "Halaman Istimewa",
+"personaltools" => "Alatan Peribadi",
+"postcomment" => "Kirimkan komen",
+"toolbox" => "Kotak Peralatan",
+"articlepage" => "Lihat rencana", #"View article",
+"userpage" => "Lihat halaman pengguna", #"View user page",
+"projectpage" => "Lihat halaman meta", #"View meta page",
+"imagepage" => "Paparkan halaman imej",
+"viewtalkpage" => "Lihat perbualan", #"View discussion",
+"otherlanguages" => "Bahasa Lain",
+"redirectedfrom" => "(Dialihkan dari $1)", #"(Redirected from $1)",
+"lastmodifiedat" => "Halaman ini diubah kali terakhir pada $2, $1.", #"The page was last modified $2, $1.",
+"copyright" => "Kandungan tersedia di bawah $1.",
+"viewcount" => "Halaman ini telah dicapai sebanyak $1 kali.", #"This page has been accessed $1 times.",
+"protectedpage" => "Halaman Dilindungi", #"Protected page",
+"nbytes" => "$1 bait",
+"ok" => "OK",
+"retrievedfrom" => "Diperolehi daripada \"$1\"", #"Retrieved from \"$1\"",
+"editsection" => "Sunting",
+"editold" => "Sunting",
+"toc" => "Jadual Kandungan",
+"showtoc" => "Paparkan",
+"hidetoc" => "sorok",
+"thisisdeleted" => "Lihat atau kembalikan $1?",
+"restorelink" => "$1 suntingan dipadam",
+"feedlinks" => "Menyuap:",
+"categories" => "Kategori",
+"pagecategories" => "Kategori",
+"category_header" => "Rencana dalam kategori \"$1\"",
+"subcategories" => "Subkategori",
+
+
+# Main script and global functions
+#
+"nosuchaction" => "Tiada tindakan tersebut", #"No such action",
+"nosuchactiontext" => "Tindakan yang ditetapkan oleh URL tidak dikenalpasti oleh perisian {{SITENAME}}.",
+"nosuchspecialpage" => "Tiada halaman istimewa tersebut", #"No such special page",
+"nospecialpagetext" => "Anda memintai halaman istimewa yang tidak dikenalpasti oleh perisian {{SITENAME}}.",
+
+
+# General errors =>Ralat umum
+#
+"error" => "Ralat",
+"databaseerror" => "Ralat Pangkalan Data", #"Database error",
+"dberrortext" => "Kesalahan sintaks anda ini mungkin disebabkan oleh pepijat pangkalan data. Pertanyaan anda yang terakhir adalah: <blockquote><tt>$1</tt></blockquote> dari fungsi \"<tt>$2</tt>\". MySQL mengembalikan ralat \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Kesalahan sintaks anda ini mungkin disebabkan oleh pepijat pangkalan data. Pertanyaan anda yang terakhir adalah \"$1\ dari fungsi \"$2\". MySQL mengembalikan ralat \"$3: $4\".<br />",
+"noconnect" => "Maaf! Wiki ini mengalami masalah teknikal dan tidak dapat menghubungi pelayan pangkalan data. <br />", #"Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server. <br />",
+"nodb" => "Tidak dapat mencapai pangkalan data $1", #"Could not select database $1",
+"cachederror" => "Berikut ini adalah salinan ingatan cache dari halaman yang dimintai. Salinan ini mungkin bukan versi yang terbaru.",
+"laggedslavemode" => "<strong>AMARAN:</strong>: Halaman ini mungkin tidak mengandungi perubahan yang terbaru.",
+"readonly" => "Pangkalan data terkunci", #"Database locked",
+"enterlockreason" => "Masukkan alasan penguncian serta anggaran bila kunci akan dibuka",
+"readonlytext" => "Pangkalan data {{SITENAME}} terkunci, mungkin untuk penyelenggaraan rutin, dan akan dibuka semula. Penyelia yang berkenaan memberi penjelasan berikut: <p>$1", #"The database is currently locked to new entries and other modifications, probably for routine database maintenance, after which it will be back to normal. The administrator who locked it offered this explanation: $1",
+"missingarticle" => "Pangkalan data tidak dapat mencari teks \"$1\" yang sepatutnya wujud. Ini biasa berlaku kerana anda telah mengikuti pautan 'Perbezaan' yang lapuk ataupun pautan 'Sejarah' ke halaman terpadam.", #"The database did not find the text of a page that it should have found, named \"$1\". This is usually caused by following an outdated diff or history link to a page that has been deleted."
+"internalerror" => "Ralat dalaman", #"Internal error",
+"filecopyerror" => "Tidak dapat menyalinkan fail \"$1\" ke \"$2\".", #"Could not copy file \"$1\" to \"$2\".",
+"filerenameerror" => "Tidak dapat menukarkan nama fail \"$1\" menjadi \"$2\".", #"Could not rename file \"$1\" to \"$2\".",
+"filedeleteerror" => "Tidak dapat memadamkan fail \"$1\".", #"Could not delete file \"$1\".",
+"filenotfound" => "Tidak dapat mencari fail \"$1\".", #"Could not find file \"$1\".",
+"unexpected" => "Nilai di luar jangkaan: \"$1\"=\"$2\".", #"Unexpected value: \"$1\"=\"$2\".",
+"formerror" => "Ralat: Tidak dapat mengirimkan borang", #"Error: could not submit form",
+"badarticleerror" => "Tindakan ini tidak boleh dilaksanakan di halaman ini.", #"This action cannot be performed on this page.",
+"cannotdelete" => "Tidak dapat memadamkan halaman atau imej yang dipilih.",
+"badtitle" => "Tajuk tidak sah", #"Bad title",
+"badtitletext" => "Tajuk halaman yang dimintai tidak sah, kosong, ataupun tajuk antara bahasa atau tajuk antara wiki salah dipaut.", #The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title.",
+"perfdisabled" => "Maaf! Ciri ini telah dimatikan buat sementara kerana ia melambatkan pangkalan data sehingga tidak dapat digunakan.", #"Sorry! This feature has been temporarily disabled because it slows the database down to the point that no one can use the wiki.",
+"perfdisabledsub" => "Ini adalah salinan yang tersimpan di $1:", #"Here's a saved copy from $1:",
+"perfcached" => "Data ini daripada ingatan cache dan mungkin bukan terkini:",
+"wrong_wfQuery_params" => "Terdapat parameter yang salah ke wfQuery()<br />Fungsi: $1<br />Kueri: $2",
+"viewsource" => "Lihat sumber",
+"protectedtext" => "Halaman ini telah dikunci untuk menghalang penyuntingan. Sila lihat [[{{ns:project}}:Halaman Dilindungi]] untuk alasannya.\n\n Bagaimanapun, anda boleh melihat dan menyalin sumber halaman ini:", #"This page has been locked to prevent editing; there are a number of reasons why this may be so, please see [[Project:Protected page]].\n\n You can view and copy the source of this page:",
+'sqlhidden' => '(Pertanyaan SQL disembunyikan)',
+
+
+# Login and logout pages
+#
+"logouttitle" => "Pengguna keluar", #"User logout",
+"logouttext" => "Anda telah keluar dari sistem. Anda masih boleh menggunakan {{SITENAME}} sebagai pengguna tanpa nama jika anda tidak ingin masuk semula. Perhatikan bahawa beberapa halaman mungkin masih dipaparkan sehingga anda membersihkan ingatan cache pelayar anda.<br />",
+"welcomecreation" => "<h2>Selamat datang, $1!</h2><p>Akaun anda telah dibuka. Sila memperibadikan \"Tatarajah\" {{SITENAME}} anda.</p>",
+"loginpagetitle" => "Pengguna masuk", #"User login",
+"yourname" => "Nama Pengguna", #"Your user name",
+"yourpassword" => "Kata Laluan", #"Your password",
+"yourpasswordagain" => "Ulangi kata laluan", #"Retype password",
+"remembermypassword" => "Sentiasa ingati kata laluan saya.", #"Remember my password across sessions.",
+"yourdomainname" => "Domain anda.", #"Your domain",
+"externaldberror" => "Kesalahan ini disebabkan oleh ralat pengesahan pangkalan data yang luar ataupun anda tidak mempunyai kebenaran untuk mengemaskinikan akaun luaran.", #'There was either an external authentication database error or you are not allowed to update your external account.',
+"loginproblem" => "<b>Terdapat masalah dalam pendaftaran masuk anda.</b><br />Cuba semula!", #"There has been a problem with your login.</b><br />Try again!",
+"alreadyloggedin" => "<strong>$1, anda telah berjaya masuk!</strong><br />",
+"login" => "Masuk", #"Log in",
+"userlogin" => "Buka akaun atau log masuk", #"Create an account or log in",
+"loginprompt" => "Anda harus menghidupkan cookie untuk masuk ke {{SITENAME}}.", #"You must have cookies enabled to log in to {{SITENAME}}.",
+"logout" => "Keluar",
+"userlogout" => "Log keluar", #"Log out",
+"notloggedin" => "Belum log masuk",
+"createaccount" => "Buka akaun baru", #Create new account",
+"badretype" => "Anda memasukkan kata laluan yang salah.", #"The passwords you entered do not match.",
+"userexists" => "Nama pengguna yang anda masukkan telah digunakan. Sila pilih nama yang lain.",
+"youremail" => "Emel anda", #"Your e-mail",
+"yourrealname" => "Nama sebenar", #"Real name",
+"yourlanguage" => "Bahasa", #"Language",
+'yourvariant' => "Kelainan", #"Variant",
+'email' => "Emel", #"Email",
+"yournick" => "Nama Samaran (untuk tandatangan)", #"Your nickname (for signatures)",
+"prefs-help-realname" => "* Nama benar (tidak wajib): Jika anda memberikan nama yang benar, pengakuan akan diberikan kepada karya anda.", #"* Real name (optional): if you choose to provide it this will be used for giving you attribution for your work.",
+"prefs-help-email" => "Emel (tidak wajib): Alamat emel anda memungkinkan pengguna lain untuk menghubungi anda melalui laman web tanpa mengetahui alamat emel anda. Alamat emel ini juga digunakan untuk mengirimkan kata laluan kepada anda jika anda terlupa.",
+"prefs-help-email-enotif" => 'Alamat emel ini juga boleh digunakan untuk mengirimkan pemberitahuan emel jika anda menghidupkan pilihan tersebut.', #'This address is also used to send you email notifications if you enabled the options.',
+"loginerror" => "Gagal log masuk", #"Login error",
+"nocookiesnew" => "Akaun pengguna anda telah dibuka tetapi anda masih belum didaftar masuk. Anda telah mematikan cookie anda. {{SITENAME}} menggunakan cookie untuk mendaftar masuk pengguna. Sila hidupkannya dan log masuk semula dengan nama pengguna serta laluan kata anda.", #"The user account was created, but you are not logged in. {{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them, then log in with your new username and password.",
+"nocookieslogin" => "Anda telah mematikan cookie anda. {{SITENAME}} menggunakan cookie untuk mendaftar masuk pengguna. Sila hidupkannya dan cuba semula.", #"{{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them and try again."
+"noname" => "Nama pengguna tidak sah.", #"You have not specified a valid user name.",
+"loginsuccesstitle" => "Berjaya masuk", #"Login successful",
+"loginsuccess" => "Anda berjaya log masuk ke {{SITENAME}} sebagai \"$1\".",
+"nosuchuser" => "Tiada pengguna dengan nama \"$1\".", #"There is no user by the name \"$1\".",
+'nosuchusershort' => "Tiada pengguna dengan nama \"$1\". Semak ejaan anda.", #"There is no user by the name \"$1\". Check your spelling.",
+"wrongpassword" => "Anda memasukkan kata laluan yang salah. Sila masukkan semula.",
+"mailmypassword" => "Sila emelkan kata laluan baru kepada saya", #"Mail me a new password",
+"passwordremindertitle" => "Peringatan kata laluan daripada {{SITENAME}}",
+"passwordremindertext" => "Anda dari alamat IP $1 mungkin telah memohon kata laluan {{SITENAME}} yang baru. Kata laluan terkini untuk pengguna \"$2\" ialah \"$3\". Anda disarankan log masuk dengan segera untuk menukarkan kata laluan anda.",
+"noemail" => "Tiada alamat emel dalam rekod untuk pengguna \"$1\".",
+"passwordsent" => "Kata laluan baru telah diemelkan kepada \"$1\". Sila log masuk semula setelah penerimaannya.", #"A new password has been sent to the e-mail address registered for \"$1\". Please log in again after you receive it.",
+"eauthentsent" => "Emel pengesahan telah dikirimkan ke alamat emel anda. Sebelum kami mengirimkan emel yang lain kepada anda, anda dikehendaki mematuhi arahan-arahan dalam emel ini untuk membuktikan pemilikan.", #"A confirmation email has been sent to the nominated email address. Before any other mail is sent to the account, you will have to follow the instructions in the email, to confirm that the account is actually yours.",
+'mailerror' => "Ralat dalam pengiriman emel: $1", #"Error sending mail: $1",
+'acct_creation_throttle_hit' => "Maaf, anda telah membuka akaun $1. Oleh sebab itu, anda tidak dibenarkan membuka akaun lagi.", #"Sorry, you have already created $1 accounts. You can\'t make any more.",
+'emailauthenticated' => "Alamat emel anda telah disahkan pada $1.", #"Your email address was authenticated on $1.",
+'emailnotauthenticated' => "Alamat emel anda masih belum disahkan. Oleh sebab itu, emel untuk ciri-ciri berikut tidak akan dikirimkan:", #"Your email address is not yet authenticated. No email will be sent for any of the following features.",
+'noemailprefs' => "<strong>Tiada alamat emel ditetapkan</strong. Oleh sebab itu, anda tidak boleh menggunakan ciri-ciri yang berikut:", #"<strong>No email address has been specified</strong>, the following features will not work.",
+'emailconfirmlink' => "Sahkan alamat emel anda.", #"Confirm your e-mail address.",
+'invalidemailaddress' => "Format alamat emel tidak sah. Sila masukkan semula ataupun kosongkan sahaja medan tersebut.", #"The email address cannot be accepted as it appears to have an invalid format. Please enter a well-formatted address or empty that field.",
+
+
+# Edit pages
+#
+"summary" => "Ringkasan", #"Summary",
+"subject" => "Tajuk/tajuk bahagian", #"Subject/headline",
+"minoredit" => "Suntingan kecil.", #"This is a minor edit.",
+"watchthis" => "Pantau rencana ini.", #"Watch this article",
+"savearticle" => "Simpan", #"Save page",
+"preview" => "Paparan", #"Preview",
+"showpreview" => "Tunjuk paparan", #"Show preview",
+"blockedtitle" => "Pengguna ini telah disekat", #"User is blocked",
+"blockedtext" => "Nama pengguna atau alamat IP anda telah disekat oleh $1. Alasannya: <br />$2. <p>Sila hubungi $1 atau [[[[Project:Penyelia|penyelia]] yang lain untuk membincangkan sekatan ini. <p>Sila ambil perhatian bahawa anda tidak dapat menggunakan ciri \"Emelkan pengguna ini\" kecuali anda mempunyai alamat emel yang sah di dalam [[{{ns:-1}}:Preferences|Tatarajah]] anda.", #'Your user name or IP address has been blocked by $1. The reason given is this:<br />''$2''<p>You may contact $1 or one of the other [[Project:Administrators|administrators]] to discuss the block. <p>Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]].',
+"whitelistedittitle" => "Pendaftaran masuk diperlukan untuk menyunting",
+"whitelistedittext" => "Anda harus [[{{ns:special}}:Userlogin|log masuk]] untuk dapat menyunting rencana.",
+"whitelistreadtitle" => "Pendaftaran masuk diperlukan untuk membaca",
+"whitelistreadtext" => "Anda harus [[{{ns:special}}:Userlogin|log masuk]] untuk dapat membaca rencana.",
+"whitelistacctitle" => "Anda tidak dibenarkan membuka akaun",
+"whitelistacctext" => "Untuk dibenarkan membuka akaun dalam Wiki ini, anda harus [[{{ns:special}}:Userlogin|log masuk]] dan mempunyai kebenaran yang wajar.",
+"loginreqtitle" => "Pendaftaran masuk diperlukan",
+'loginreqlink' => 'log masuk',
+"loginreqpagetext" => "Anda harus $1 untuk dapat melihat halaman yang lain.",
+"accmailtitle" => "Kata laluan dikirimkan",
+"accmailtext" => "Kata laluan untuk '$1' telah dikirimkan ke $2.",
+"newarticle" => "(Baru)", #"(New)",
+"newarticletext" => "Anda telah mengikuti pautan ke halaman yang masih belum wujud. Untuk memulakannya, masukkan teks anda ke dalam kotak di bawah (sila lihat [[Project:Bantuan|Bantuan]] untuk maklumat lanjut).\n Jika anda mengunjungi halaman ini tanpa sengaja, klik butang '''balik''' di pelayar anda.", #"You've followed a link to a page that doesn't exist yet. To create the page, start typing in the box below (see the [[Project:Help|help page]] for more info). If you are here by mistake, just click your browser's '''back''' button.",
+"anontalkpagetext" => "---- Ini adalah halaman perbualan untuk pengguna tanpa nama, iaitu pengguna yang tidak log masuk ataupun masih belum membuka akaun. Kami terpaksa menggunakan alamat IP untuk mengesan pengguna tersebut. Alamat IP ini mungkin digunakan oleh ramai pengguna. Sekiranya anda adalah pengguna tanpa nama dan berasa bahawa komen yang tidak kena mengena telah ditujui kepada anda, sila [[{{ns:special}}:Userlogin|menggunakan nama pengguna anda atau membuka akaun]] bagi mengelakkan sebarang kekeliruan dengan pengguna tanpa nama yang lain.", #"---- ''This is the discussion page for an anonymous user who has not created an account yet or who does not use it. We therefore have to use the numerical [[IP address]] to identify him/her. Such an IP address can be shared by several users. If you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:Userlogin|create an account or log in]] to avoid future confusion with other anonymous users.''",
+'clearyourcache' => "'''Nota:''' Selepas menyimpan, anda mungkin perlu memirau ingatan cache pelayar anda untuk melihat perubahan. '''Mozilla /Firefox/Safari:''' ''Ctrl-Shift-R''; '''IE:''' ''Ctrl-F5''; '''Konqueror:''' ''F5''. Pengguna '''Opera''' mungkin perlu membersihkan kesemua ingatan cachenya di dalam ''Alatan: Tatarajah'' (''Tools?Preferences'').", #"'''Note:''' After saving, you may have to bypass your browser's cache to see the changes. '''Mozilla / Firefox / Safari:''' hold down ''Shift'' while clicking ''Reload'', or press ''Ctrl-Shift-R'' (''Cmd-Shift-R'' on Apple Mac); '''IE:''' hold ''Ctrl'' while clicking ''Refresh'', or press ''Ctrl-F5''; '''Konqueror:''': simply click the ''Reload'' button, or press ''F5''; '''Opera''' users may need to completely clear their cache in ''Tools?Preferences''.",
+"usercssjsyoucanpreview" => "'''Petua:''' Gunakan butang \"Tunjuk paparan\" untuk menguji CSS/JS anda yang baru sebelum menyimpan.", #"<strong>Tip:</strong> Use the 'Show preview' button to test your new CSS/JS before saving.",
+"usercsspreview" => "'''Ingatan bahawa ini hanyalah paparan CSS pengguna anda dan masih belum disimpan lagi!'''", #"'''Remember that you are only previewing your user CSS, it has not yet been saved!'''",
+"noarticletext" => "(Tiada teks di dalam halaman ini buat sekarang)",
+"updated" => "(Dikemaskini)", #"(Updated)",
+"note" => "<strong>Catatan:</strong>",
+"previewnote" => "Ingatan bahawa ini hanyalah paparan dan masih belum disimpan lagi!", #"Remember that this is only a preview, and has not yet been saved!",
+"previewconflict" => "Paparan ini merupakan teks di bahagian atas dalam kotak penyuntingan teks. Teks ini akan disimpan sekiranya anda memilih berbuat demikian.",
+"editing" => "Menyunting $1", #"Editing $1",
+'editinguser' => "Menyunting $1", #"Editing $1",
+"editingsection" => "Menyunting $1 (bahagian)",
+"editingcomment" => "Menyunting $1 (komen)",
+"editconflict" => "Konflik penyuntingan: $1", #"Edit conflict: $1",
+"explainconflict" => "Pengguna lain telah menyunting halaman ini sejak anda bermula. Bahagian atas di kawasan teks mengandungi teks yang terkini. Perubahan anda dipaparkan di bahagian bawah dalam kawasan teks. Anda perlu menggabungkan perubahan anda dengan teks terkini. <b>Hanya</b> teks pada bahagian atas di kawasan teks akan disimpan jika anda menekan \"Simpan\".<br />", #"Someone else has changed this page since you started editing it. The upper text area contains the page text as it currently exists. Your changes are shown in the lower text area. You will have to merge your changes into the existing text. <b>Only</b> the text in the upper text area will be saved when you press \"Save page\".<br />",
+"yourtext" => "Teks Anda", #"Your text",
+"storedversion" => "Versi Tersimpan", #"Stored version",
+'nonunicodebrowser' => "<strong>AMARAN: Pelayar anda tidak mendukung Unikod. Bagaimanapun, terdapatnya kaedah untuk membenarkan anda menyunting rencana dengan selamat: huruf-huruf yang bukan huruf ASCII akan dipaparkan dalam kotak penyuntingan sebagai kod perenambelasan.</strong>", #"<strong>WARNING: Your browser is not unicode compliant. A workaround is in place to allow you to safely edit articles: non-ASCII characters will appear in the edit box as hexadecimal codes.</strong>",
+"editingold" => "<strong>PERINGATAN: Anda menyunting semakan lama. Jika anda menyimpannya, perubahan yang dibuat sejak semakan ini akan hilang.</strong>",
+"yourdiff" => "Perbezaan", #"Differences",
+"copyrightwarning" => "Semua sumbangan kepada {{SITENAME}} adalah tertakluk kepada $2 (sila lihat $1 untuk maklumat lanjut). Oleh sebab itu, jika anda tidak ingin rencana anda disunting atau disebarkan secara bebas, jangan hantar rencana anda ke sini. Anda juga perlu mengakui bahawa ini adalah karya anda sendiri, ataupun anda telah menyalinkannya daripada domain umum atau sumber bebas yang serupa. <p><strong>JANGAN HANTAR SEBARANG KARYA HAK CIPTA ORANG LAIN TANPA KEBENARAN.</strong></p>",
+"longpagewarning" => "<strong>AMARAN: Panjangnya halaman ini $1 kilobait. Terdapat beberapa pelayar yang mengalami masalah terhadap penyuntingan halaman yang mendekati ataupun melebihi 32kB. Sila bahagikan rencana ini, jika boleh.</strong>", #"<strong>WARNING: This page is $1 kilobytes long; some browsers may have problems editing pages approaching or longer than 32kb. Please consider breaking the page into smaller sections.</strong>",
+"readonlywarning" => "<strong>AMARAN: Pangkalan data ini telah dikunci untuk penyelenggaraan. Oleh sebab itu, anda tidak dapat menyimpan suntingan anda buat sekarang. Anda mungkin ingin 'gunting-dan-tampal' teks anda dan menyimpannya dalam fail teks untuk kegunaan kemudian.</strong>", #"<strong>WARNING: The database has been locked for maintenance, so you will not be able to save your edits right now. You may wish to cut-n-paste the text into a text file and save it for later.</strong>",
+"protectedpagewarning" => "<strong>AMARAN: Halaman ini telah dikunci supaya penyelia sahaja yang boleh mengemaskinikannya. Sila mematuhi [[Project:Polisi perlindungan|panduan untuk halaman dilindungi]]</strong>", #"<strong>WARNING: This page has been locked so that only users with sysop privileges can edit it. Be sure you are following the [[Project:Protected_page_guidelines|protected page guidelines]].</strong>",
+"templatesused" => "Templat yang digunakan di halaman ini.", #'Templates used on this page:',
+
+
+# History pages
+#
+"revhistory" => "Sejarah Penyemakan", #"Revision history",
+"nohistory" => "Tiada sejarah penyuntingan untuk halaman ini", #"There is no edit history for this page.",
+"revnotfound" => "Semakan tidak dapat dijumpai", #"Revision not found",
+"revnotfoundtext" => "Semakan lama untuk halaman yang anda pinta tidak dapat dijumpai. Sila semak URL yang anda gunakan untuk mencapai halaman ini.", #"The old revision of the page you asked for could not be found. Please check the URL you used to access this page.",
+"loadhist" => "Muat turun halaman sejarah", #"Loading page history",
+"currentrev" => "Semakan terkini", #"Current revision",
+"revisionasof" => "Semakan sejak $1", #"Revision as of $1",
+"previousrevision" => "Semakan terdahulu",
+"cur" => "kini", #"cur",
+"next" => "berikut",
+"last" => "akhir",
+"orig" => "asal",
+"histlegend" => "Cara untuk pembandingan: Tandakan butang radio versi-versi untuk dibanding, lalu tekan butang ''enter'' atau butang di bawah. <br />Legenda: (kini) = perbezaan dengan versi terkini, (akhir) = perbezaan dengan versi terakhir, K = suntingan kecil", #'Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.<br />Legend: (cur) = difference with current version, (last) = difference with preceding version, K = minor edit.',
+"deletedrev" => "[dipadam]", #'[deleted]',
+"histfirst" => "Terawal", #'Earliest'
+"histlast" => "Terkini", #'Latest'
+
+
+# Search results
+#
+"searchresults" => "Hasil Carian",
+"searchresulttext" => "Untuk maklumat lanjut mengenai pencarian di {{SITENAME}}, sila lihat [[Project:Mencari|pencarian di {{SITENAME}}]].",
+"searchsubtitle" => "Untuk pertanyaan \"$1\"", #"For query \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Untuk pertanyaan \"$1\"", #"For query \"$1\"",
+"badquery" => "Format pertanyaan untuk pencarian adalah salah", #"Badly formed search query",
+"badquerytext" => "Kami tidak dapat melaksanakan pertanyaan anda. Hal ini mungkin disebabkan kerana anda cuba mencari perkataan yang mengandungi kurang daripada tiga huruf (perisian sistem masih belum dapat mendukungnya buat sekarang), ataupun anda tersalah taip ungkapan untuk pertanyaan; contohnya \"ikan dan dan udang\". Sila cuba pertanyaan yang lain.",
+"matchtotals" => "Pertanyaan \"$1\" sepadan dengan tajuk halaman $2 dan teks halaman $3.", #"The query \"$1\" matched $2 page titles and the text of $3 pages.",
+"noexactmatch" => "Tiada halaman yang mempunyai tajuk tepat ini. Sila cuba mencari melalui teks yang penuh.", #"No page with this exact title exists, trying full text search.",
+"titlematches" => "Tajuk rencana yang sepadan", #"Article title matches",
+"notitlematches" => "Tiada tajuk halaman yang sepadan", #"No page title matches",
+"textmatches" => "Teks rencana yang sepadan", #"Article text matches",
+"notextmatches" => "Tiada teks halaman yang sepadan", #No page text matches",
+"prevn" => "sebelum $1", #"previous $1",
+"nextn" => "selepas $1", #"next $1",
+"viewprevnext" => "Lihat ($1) ($2) ($3).", #"View ($1) ($2) ($3).",
+"showingresults" => "Terpapar di bawah adalah hasil pencarian dari <b>$1</b> hingga <b>$2</b>.",
+"showingresultsnum"=> "Terpapar di bawah <b>$3</b> adalah hasil pencarian yang bermula dengan #<b>$2</b>.",
+"nonefound" => "<strong>Catatan</strong>: Kegagalan enjin carian biasanya disebabkan oleh pencarian perkataan-perkataan yang umum, seperti \"ada\" dan \"dari\", yang tidak wujud dalam senarai indeks ataupun kerana anda menetapkan lebih daripada satu perkataan pencarian (hanya halaman yang mengandungi kesemua perkataan pencarian akan dipaparkan).",
+"powersearch" => "Cari", #"Search",
+"powersearchtext" => "Cari dalam ruang nama:<br />$1<br />$2 Paparkan peralihan Cari $3 $9",
+"searchdisabled" => "Pencarian {{SITENAME}} telah dimatikan. Anda boleh mencari melalui Google buat sekarang. Sila ambil perhatian bahawa hasil daripada pencarian Google mungkin bukan merupakan halaman yang terkini.",
+"blanknamespace" => "(Utama)",
+
+
+
+# Preferences page
+#
+"preferences" => "Tatarajah", #"Preferences",
+"prefsnologin" => "Belum log masuk", #"Not logged in",
+"prefsnologintext" => "Anda mesti [[{{ns:special}}:Userlogin|log masuk]] untuk menetapkan butir-butir kecenderungan anda dalam [[{{ns:special}}:Preferences|Tatarajah]].",
+"prefsreset" => "Tatarajah anda telah dikembalikan dari storan", #"Preferences have been reset from storage.",
+"qbsettings" => "Konfigurasi palang pantas", #"Quickbar settings",
+"changepassword" => "Tukar kata laluan", #"Change password",
+"skin" => "Kulit", #"Skin",
+"math" => "Matematik",
+"dateformat" => "Format tarikh", #"Date format",
+"math_failure" => "Huraian tergagal", #"Failed to parse",
+"math_unknown_error" => "Ralat yang tidak dapat dikesan", #"unknown error",
+"math_unknown_function" => "Fungsi yang tidak dapat diketahui", #"unknown function",
+"math_lexing_error" => "Ralat leksing", #"lexing error",
+"math_syntax_error" => "Ralat sintaks", #"syntax error",
+"math_image_error" => "Penukaran kepada PNG gagal; semak pemasangan latex, dvips, gs, dan tukarkan semula.",
+"math_bad_tmpdir" => "Tidak dapat menulis atau membuat direktori matematik sementara",
+"math_bad_output" => "Tidak dapat menulis atau membuat direktori keluaran matematik",
+"math_notexvc" => "Texvc boleh laku terhilang; sila lihat matematik/fail README untuk cara membuat tatarajah.",
+"prefs-personal" => "Data Pengguna",
+"prefs-rc" => "Perubahan terkini dan rencana stub",
+'prefs-misc' => 'Pelbagai',
+"saveprefs" => "Simpan", #"Save preferences",
+"resetprefs" => "Kembalikan", #"Reset preferences",
+"oldpassword" => "Kata laluan lama", #"Old password",
+"newpassword" => "Kata laluan baru", #"New password",
+"retypenew" => "Ulangi kata laluan baru", #"Retype new password",
+"textboxsize" => "Menyunting", #"Editing",
+"rows" => "Baris", #"Rows",
+"columns" => "Lajur", #"Columns",
+"searchresultshead" => "Cari", #"Search result settings",
+"resultsperpage" => "Bilangan capaian untuk dipaparkan bagi setiap halaman", #"Hits to show per page",
+"contextlines" => "Bilangan baris untuk dipaparkan bagi setiap capaian", #"Lines to show per hit",
+"contextchars" => "Bilangan huruf konteks bagi setiap baris", #"Characters of context per line",
+"stubthreshold" => "Ambang untuk paparan rencana stub", #"Threshold for stub display",
+"recentchangescount" => "Bilangan tajuk dalam perubahan terkini", #"Number of titles in recent changes",
+"savedprefs" => "Tatarajah anda telah disimpan", #"Your preferences have been saved.",
+"timezonelegend" => "Zon waktu", #'Time zone',
+"timezonetext" => "Masukkan perbezaan waktu (dalam jam) antara waktu tempatan anda dengan waktu pelayan (GMT+8 untuk Kuala Lumpur).", #"Enter number of hours your local time differs from server time (Kuala Lumpur, which is GMT+8).",
+"localtime" => "Waktu tempatan", #"Local time",
+"timezoneoffset" => "Ofset", #"Offset",
+"servertime" => "Waktu pelayan sekarang adalah", #"Server time is now",
+"guesstimezone" => "Isikan dari pelayar", #"Fill in from browser",
+"defaultns" => "Cari dalam ruang nama secara lalai:", #"Search in these namespaces by default:",
+"default" => 'lalai',
+"files" => "Fail",
+
+
+# Recent changes
+#
+"changes" => "perubahan",
+"recentchanges" => "Perubahan Terkini",
+"recentchangestext" => "Kenalpasti perubahan wiki yang terkini dalam halaman ini.",
+"rcnote" => "Di bawah adalah <strong>$1</strong> perubahan terbaru pada <strong>$2</strong> hari yang lalu.", #"Below are the last <strong>$1</strong> changes in last <strong>$2</strong> days.",
+"rcnotefrom" => "Di bawah adalah perubahan sejak <b>$2</b> (sehingga <b>$1</b>).",
+"rclistfrom" => "Paparkan perubahan baru mulai dari $1",
+"rclinks" => "Paparkan $1 perubahan pada $2 hari yang lalu.", #"Show last $1 changes in last $2 days.",
+"diff" => "perbezaan", #"diff",
+"hist" => "sejarah", #"hist",
+"hide" => "sorok", #"hide",
+"show" => "papar", #"show",
+"minoreditletter" => "k", #"m",
+"newpageletter" => "B",
+
+
+# Upload
+#
+"upload" => "Muat naik",
+"uploadbtn" => "Muat naik fail", #"Upload file",
+"reupload" => "Muat naik semula", #"Re-upload",
+"reuploaddesc" => "Kembali ke borang muat naik", #"Return to the upload form.",
+"uploadnologin" => "Belum log masuk", #"Not logged in",
+"uploadnologintext" => "Anda mesti [[{{ns:special}}:Userlogin|log masuk]] untuk memuat naik fail.",
+"uploaderror" => "Ralat muat naik", #"Upload error",
+"uploadtext" => "Borang di bawah adalah untuk memuat naik fail yang baru. Ia juga boleh digunakan untuk mecapai [[{{ns:special}}:Imagelist|senarai imej]]. Setiap pemuatan naik dan pemadaman di halaman ini juga dicatat dalam [[{{ns:special}}:Log|log]]. <p>Anda juga dikehendaki menandakan kotak untuk mengesahkan bahawa anda tidak melanggarkan sebarang hak cipta dengan pemuatan naik fail ini. Tekan butang \"Muat naik\" untuk menyelesaikan pemuatan naik.</p><p>Untuk memasukkan imej yang anda baru muat naik ke dalam halaman rencana, gunakan pautan dalam bentuk '''[[{{ns:image}}:fail.jpg]]''', '''[[{{ns:image}}:fail.png|teks alt]]''' atau '''[[{{ns:media}}:fail.ogg]]''' untuk mengaitkan fail imej secara langsung.</p>",
+"uploadlog" => "Log muat naik", #"upload log",
+"uploadlogpage" => "Log muat naik", #"Upload_log",
+"uploadlogpagetext" => "Di bawah ini adalah senarai terkini bagi fail yang dimuat naik. Segala waktu yang dipaparkan adalah waktu pelayan (UTC).",
+"filename" => "Nama Fail", #"Filename",
+"filedesc" => "Ringkasan", #"Summary",
+"filestatus" => "Taraf hak cipta",
+"filesource" => "Sumber",
+"copyrightpage" => "{{ns:project}}:Hak cipta",
+"copyrightpagename" => "Hak cipta {{SITENAME}}",
+"uploadedfiles" => "Fail yang telah dimuat naik", #"Uploaded files",
+"ignorewarning" => "Abaikan amaran dan simpankan fail sahaja", #"Ignore warning and save file anyway.",
+"minlength" => "Nama imej harus mempunyai sekurang-kurangnya tiga huruf.", #"Image names must be at least three letters.",
+"illegalfilename" => "Nama fail \"$1\" mengandungi huruf-huruf yang tidak dibenarkan dalam tajuk halaman. Sila tukarkan nama fail dan cuba memuat naik semula.",
+"badfilename" => "Nama imej telah ditukarkan menjadi \"$1\".", #"Image name has been changed to \"$1\".",
+"badfiletype" => "\".$1\" adalah format fail imej yang tidak dibenarkan.",
+"emptyfile" => "Fail yang anda cuba memuat naik kelihatannya kosong. Ini mungkin disebabkan oleh kesilapan menaip nama fail. Sila pastikan adakah anda betul-betul ingin memuat naik fail ini.",
+"fileexists" => "Terdapat satu fail dengan nama ini. Sila semakkan $1 jika anda tidak pasti bahawa anda hendak menukarkannya.",
+"largefile" => "Saiz fail ini $2 bait. Saiz imej yang tidak melebihi $1 disarankan.",
+"successfulupload" => "Pemuatan naik berjaya", #"Successful upload",
+"fileuploaded" => "Fail \"$1\" berjaya dimuat naik. Sila ikuti pautan ini: ($2) ke halaman huraian dan isikan maklumat fail ini (contoh: keasalan fail, bila dibuat serta oleh siapa, dan butir-butir lain yang anda ketahui). Jika fail ini merupakan fail imej, anda boleh memasukkannya melalui:<br /><tt><nowiki>[[</nowiki>Imej:$1|thumb|right|300px|Huraian]]</tt>.",
+"uploadwarning" => "Amaran pemuatan naik", #"Upload warning",
+"savefile" => "Simpan", #"Save file",
+"uploadedimage" => "Telah dimuat naik \"[[$1]]\"",
+"uploaddisabled" => "Maaf, kemudahan muat naik dimatikan.",
+"uploadscripted" => "Fail ini mengandungi kod HTML atau kod skrip yang mungkin boleh disalah tafsir oleh pelayar web.",
+"uploadcorrupt" => "Fail ini rosak ataupun mempunyai ekstensi yang salah. Sila semakkan fail dan muat naik semula.",
+"uploadvirus" => "Fail in mengandungi virus! Butir-butir: $1",
+"sourcefilename" => "Sumber nama fail",
+"destfilename" => "Destinasi nama fail",
+
+
+# Image list
+#
+"imagelist" => "Senarai imej", #"Image list",
+"imagelisttext" => "Di bawah adalah senarai $1 imej yang terisih $2.", #"Below is a list of $1 images sorted $2.",
+"getimagelist" => "Memperolehi senarai imej", #"fetching image list",
+"ilsubmit" => "Cari", #"Search",
+"showlast" => "Paparkan $1 imej terbaru yang telah diisih $2.", #"Show last $1 images sorted $2.",
+"byname" => "berdasarkan nama", #"by name",
+"bydate" => "berdasarkan tarikh", #by date",
+"bysize" => "berdasarkan saiz", #"by size",
+"imgdelete" => "padam", #"del",
+"imgdesc" => "huraian", #"desc",
+"imglegend" => "Legenda: (huraian) = paparkan/suntingkan huraian imej.", #"Legend: (desc) = show/edit image description.",
+"imghistory" => "Sejarah imej", #"Image history",
+"revertimg" => "kembali",
+"deleteimg" => "padam", #"del",
+"deleteimgcompletely" => "Hapuskan semua semakan fail ini",
+"imghistlegend" => "Legenda: (terkini) = ini merupakan imej terkini, (padam) = padamkan versi yang lama, (kembali) = kembalikan versi lama.<br /><i>Klikkan pada tarikh untuk melihat imej yang telah dimuat naik pada tarikh itu</i>.", #"Legend: (cur) = this is the current image, (del) = delete this old version, (rev) = revert to this old version. <br /><i>Click on date to see image uploaded on that date</i>.",
+"imagelinks" => "Pautan imej", #"Image links",
+"linkstoimage" => "Halaman-halaman berikut berpaut ke imej ini:", #"The following pages link to this image:",
+"nolinkstoimage" => "Tiada halaman yang berpaut ke imej ini.", #"There are no pages that link to this image.",
+"sharedupload" => "Fail ini merupakan pemuatan naik berkongsi dan boleh dipergunakan untuk projek lain.",
+"shareduploadwiki" => "Sila lihat [halaman huraian fail $1] untuk maklumat lanjut.",
+"noimage" => "Tiada fail yang mengandungi nama ini. Anda boleh muat naik $1.",
+"uploadnewversion-linktext" => "Muat naik versi baru untuk fail ini",
+
+
+# Statistics
+#
+"statistics" => "Statistik", #"Statistics",
+"sitestats" => "Statistik laman", #"Site statistics",
+"userstats" => "Statistik pengguna", #"User statistics",
+"sitestatstext" => "<p>Ketika ini, {{SITENAME}} mempunyai <b>$2</b> buah rencana.</p><p>Selain itu, terdapat juga laman perbualan, laman penerangan imej, laman pengguna, laman {{SITENAME}}, laman ringkas/buntu, laman pengalihan dan templat. Kesemua laman ini menjadikan jumlah keseluruhan halaman di {{SITENAME}} sebanyak <b>$1</b> halaman.</p><p>Sebanyak <b>$4</b> suntingan telah dilakukan sejak permulaannya wiki ini; iaitu purata <b>$5</b> suntingan bagi setiap halaman.</p>",
+"userstatstext" => "Terdapat <b>$1</b> pengguna berdaftar. <b>$2</b> daripadanya adalah penyelia (lihat {{ns:project}}:Penyelia).",
+
+
+"disambiguations" => "Halaman Nyahkekaburan", #"Disambiguation pages",
+"disambiguationspage" => "{{ns:project}}:Pautan_ke_halaman_nyahkekaburan", #"{{ns:project}}:Links_to_disambiguating_pages",
+"disambiguationstext" => "Halaman-halaman yang berikut berpaut ke <i>halaman nyahkekaburan</i>. Halaman-halaman ini sepatutnya kena dipaut ke halaman yang wajar. <br />Satu halaman dianggap sebagai 'halaman nyahkekaburan' jika halaman itu dikaitkan dari $1. <br />Pautan dari ruang nama yang lain <i>tidak</i> tersenarai di sini.",
+
+"doubleredirects" => "Peralihan Berganda", #"Double Redirects",
+"doubleredirectstext" => "Setiap baris mengandungi pautan ke halaman peralihan pertama dan peralihan kedua, serta ayat pertama dalam halaman peralihan kedua. Biasanya, baris tersebut akan memberikan halaman \"benar\" yang sepatutnya ditujui oleh peralihan pertama.",
+
+"brokenredirects" => "Peralihan Rosak", #"Broken Redirects",
+"brokenredirectstext" => "Peralihan berikut berpaut ke halaman yang tidak wujud", #"The following redirects link to a non-existing page.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Halaman Yatim", #"Orphaned pages",
+'uncategorizedpages' => 'Halaman Tak Berkategori',
+'uncategorizedcategories' => 'Kategori Tak Berkategori',
+"unusedcategories" => "Kategori Tidak Digunakan",
+"unusedimages" => "Imej Tidak Digunakan",
+"popularpages" => "Halaman Popular",
+"nviews" => "$1 capaian", #"$1 views",
+"wantedpages" => "Halaman Dikehendaki",
+"mostlinked" => "Halaman Paling Banyak Dipaut",
+"nlinks" => "$1 pautan", #"$1 links",
+"allpages" => "Semua Halaman",
+"nextpage" => 'Halaman yang berikut ($1)',
+"randompage" => "Halaman Rawak",
+"shortpages" => "Halaman Pendek",
+"longpages" => "Halaman Panjang",
+"deadendpages" => "Halaman Buntu",
+"listusers" => "Senarai Pengguna",
+"specialpages" => "Halaman Istimewa",
+"spheading" => "Halaman Istimewa Umum",
+"restrictedpheading" => "Halaman Istimewa Terhad",
+"recentchangeslinked" => "Perubahan berkaitan",
+"recentchangeslinked" => "Perubahan terkini yang dipaut",
+"rclsub" => "(Untuk halaman yang berpaut dari \"$1\")", #"(to pages linked from \"$1\")",
+"newpages" => "Halaman Baru",
+"ancientpages" => "Rencana Lama",
+"intl" => "Pautan Antarabahasa",
+"movethispage" => "Pindahkan halaman ini",
+"unusedimagestext" => "<p>Walaupun imej ini disenaraikan di sini, imej ini mungkin masih sentiasa digunakan. Keadaan ini tertimbul kerana laman web yang lain mungkin berpaut kepada imej yang mengandungi URL langsung.</p>",
+"categoriespagetext" => "Kategori-kategori berikut wujud di wiki ini.",
+"unusedcategoriestext" => "Kategori di bawah ini wujud walaupun tiada rencana atau kategori lain di dalamnya.",
+"data" => "Data",
+"booksources" => "Sumber Buku",
+"booksourcetext" => "Di bawah ini adalah senarai pautan ke laman lain yang menjual buku,baik buku baru ataupun buku terpakai, dan mungkin mempunyai maklumat lanjut tentang buku yang anda sedang mencari. {{SITENAME}} tidak bergabung dengan mana-mana perniagaan di atas, dan senarai ini bukan merupakan penyokongan.",
+"isbn" => "ISBN",
+"alphaindexline" => "$1 ke $2",
+"version" => "Versi",
+"log" => "Log",
+"alllogstext" => "Paparan gabungan untuk log pemuatan naik, pemadaman, perlindungan, penyekatan, dan penyelia. Anda boleh menyempitkan paparan dengan memilihkan jenis log, nama pengguna ataupun nama halaman yang berkaitan.",
+
+
+# Email this user
+#
+"mailnologin" => "Tiada alamat emel.", #"No send address",
+"mailnologintext" => "Anda harus [[{{ns:special}}:Userlogin|log masuk]] dan mempunyai alamat emel yang sah di dalam [[{{ns:special}}:Preferences|Tatarajah]] anda untuk mengirimkan emel kepada pengguna lain.",
+"emailuser" => "Emelkan pengguna ini", #"E-mail this user",
+"emailpage" => "Emelkan pengguna", #"E-mail user",
+"emailpagetext" => "Jika pengguna ini memasukkan alamat emel yang sah dalam Tatarajahnya, borang di bawah akan mengirimkan satu pesanan. Alamat emel di dalam Tatarajah anda akan dipaparkan sebagai alamat emel \"Daripada\", jadi penerima boleh membalas emel tersebut.", #"If this user has entered a valid e-mail address in is user preferences, the form below will send a single message. The e-mail address you entered in your user preferences will appear as the \"From\" address of the mail, so the recipient wi#ll be able to reply.",
+'usermailererror' => "Objek emel mengembalikan ralat:",
+'defemailsubject' => "Emel {{SITENAME}",
+"noemailtitle" => "Tiada alamat emel", #"No e-mail address",
+"noemailtext" => "Pengguna ini tidak menetapkan alamat emel yang sah, atau telah memilih untuk tidak mendapat emel daripada pengguna yang lain.", #"This user has not specified a valid e-mail address, or has chosen not to receive e-mail from other users.",
+"emailfrom" => "Daripada", #"From",
+"emailto" => "Kepada", #"To",
+"emailsubject" => "Perkara", #"Subject",
+"emailmessage" => "Pesanan", #"Message",
+"emailsend" => "Kirim", #"Send",
+"emailsent" => "Emel telah dikirim", #"E-mail sent",
+"emailsenttext" => "Emel anda telah dikirim.", #"Your e-mail message has been sent.",
+
+
+# Watchlist
+#
+"watchlist" => "Senarai Pantau",
+"nowatchlist" => "Tiada sebarang rencana dalam senarai pantau anda.", #"You have no items on your watchlist.",
+"watchnologin" => "Belum log masuk", #"Not logged in",
+"watchnologintext" => "Anda mesti [[{{ns:special}}:Userlogin|log masuk]] untuk mengubahkan senarai pantau.",
+"addedwatch" => "Telah ditambah ke senarai pantau",
+"addedwatchtext" => "Halaman \"[[:$1]]\" telah ditambah ke [[Special:Watchlist|Senarai pantau]]. Semua perubahan pada masa hadapan di halaman tersebut dan halaman perbualannya akan disenaraikan di sini. Tajuk halaman tersebut juga akan <b>dicetak tebal</b> dalam [[Special:Recentchanges|senarai perubahan terkini]] supaya lebih mudah dilihat. <p>Jika anda ingin memadamkan halaman dari senarai pantau, klik \"Nyahpantau\" pada palang di atas.",
+"removedwatch" => "Telah dipadam dari senarai pantau", #"Removed from watchlist",
+"removedwatchtext" => "Halaman \"$1\"telah dipadam dari senarai pantau.",
+"watch" => "Pantau",
+"watchthispage" => "Pantau rencana ini",
+"unwatchthispage" => "Nyahpantau", #"Stop watching",
+"notanarticle" => "Bukan rencana.", #"Not a page",
+"watchnochange" => "Tiada sebarang perubahan pada halaman-halaman dalam tempoh yang dipaparkan.",
+"watchdetails" => "* $1 halaman dipantau (tidak termasuk halaman perbualan). [[{{ns:-1}}:Watchlist/edit|Paparkan senarai pantauan yang lengkap]].",
+"wlheader-enotif" => "* Pemberitahuan emel telah dihidupkan.",
+"wlheader-showupdated" => "* Halaman yang telah diubah sejak capaian terakhir anda dipaparkan dalam cetak '''tebal'''",
+"watchmethod-recent" => "Semakkan suntingan terkini untuk mengesan halaman pantau",
+"watchmethod-list" => "Semakkan halaman pantau untuk mengesan penyuntingan terkini",
+"removechecked" => "Hapuskan halaman yang ditandakan dari senarai pantau",
+"watchlistcontains" => "Senarai pantau anda mengandungi $1 halaman.",
+"watcheditlist" => "Berikut ini merupakan senarai halaman pantauan anda mengikut susunan abjad. Tandakan kotak halaman-halaman yang anda ingin padamkan dari senarai pantauan dan tekan butang \"Hapuskan halaman yang ditanda\" yang terletak di bahagian bawah skrin (pemadaman halaman rencana akan menyebabkan pemadaman halaman perbualan yang berkaitan dan sebaliknya).",
+"removingchecked" => "Memadamkan halaman-halaman yang dipilih dari senarai pantau anda...",
+"couldntremove" => "Tidak dapat memadamkan halaman '$1'...",
+"iteminvalidname" => "Terdapat masalah dengan halaman '$1' (namanya tidak sah)...",
+"wlnote" => "Di bawah ini adalah $1 perubahan terbaru dalam <b>$2</b> jam yang lalu.",
+"wlshowlast" => "Paparkan $1 jam $2 hari $3 yang lalu",
+"wlsaved" => "Ini adalah versi tersimpan bagi senarai pantau anda.",
+'wlhideshowown' => "$1 suntingan saya.",
+
+# Delete/protect/revert
+#
+"deletepage" => "Hapus", #"Delete page",
+"confirm" => "Sahkan", #"Confirm",
+"excontent" => "Kandungan dahulu: '$1'",
+"exbeforeblank" => "Kandungan sebelum dikosongkan adalah: '$1'",
+"exblank" => "Halaman Kosong",
+"confirmdelete" => "Sahkan pemadaman", #"Confirm delete",
+"deletesub" => "(Memadam \"$1\")", #"(Deleting \"$1\")",
+"historywarning" => "<b>AMARAN</b>: Halaman yang anda ingin padamkan mempunyai sejarah:",
+"confirmdeletetext" => "Anda akan memadamkan secara kekal halaman atau imej ini bersama-sama sejarahnya dari pangkalan data. Sila pastikan bahawa anda memang hendak berbuat demikian, dan anda faham akan segala akibatnya. Pastikan juga bahawa apa yang anda hendak melakukan adalah selaras dengan [[{{ns:project}}:Polisi dan garis panduan|dasar {{SITENAME}}]].",
+"actioncomplete" => "Tindakan berjaya", #"Action complete",
+"deletedtext" => "\"$1\" telah dipadam. Sila lihat $2 untuk rekod terkini bagi halaman yang telah dipadam.",
+"deletedarticle" => "\"$1\" telah dipadam", #"deleted \"$1\"",
+"dellogpage" => "Log Pemadaman", #"Deletion log",
+"dellogpagetext" => "Di bawah ini adalah senarai terkini untuk halaman yang telah dipadam. Semua waktu yang ditunjukkan adalah waktu pelayan (UTC).",
+"deletionlog" => "Log Pemadaman", #"deletion log",
+"reverted" => "Telah dikembalikan ke semakan sebelumnya", #"Reverted to earlier revision",
+"deletecomment" => "Alasan pemadaman", #"Reason for deletion",
+"imagereverted" => "Pengembalian ke versi sebelumnya berjaya", #"Revert to earlier version was successful.",
+"rollback" => "Kembalikan ke asal",
+'rollback_short' => "Kembali asal",
+"rollbacklink" => "Kembalikan ke asal",
+"rollbackfailed" => "Pengembalian ke asal tergagal.",
+"cantrollback" => "Tidak dapat mengembalikan suntingan terakhir; penyumbang akhir adalah pengarang tunggal untuk rencana ini.", #"Cannot revert edit; last contributor is only author of this article.",
+"alreadyrolled" => "Tidak dapat mengembalikan suntingan terakhir dari [[$1]] oleh [[Pengguna:$2|$2]] ([[Perbualan Pengguna:$2|Perbualan]]); terdapat pengguna yang telah berbuat demikian ataupun telah menyuntingnya. Suntingan terakhir telah dibuat oleh [[Pengguna:$3|$3]] ([[Perbualan Pengguna:$3|Perbualan]]).", #"Cannot rollback last edit of [[:$1]] by [[User:$2|$2]] ([[User talk:$2|Talk]]); someone else has edited or rolled back the article already. Last edit was by [[User:$3|$3]] ([[User talk:$3|Talk]]).",
+# only shown if there is an edit comment
+"editcomment" => "Komen penyuntingan: \"<i>$1</i>\".", #"The edit comment was: \"<i>$1</i>\".",
+"revertpage" => "Suntingan $1 dikembalikan ke versi terakhir oleh $1",
+'sessionfailure' => "Terdapat masalah terhadap pendaftaran masuk anda; tindakan ini telah dibatalkan sebagai langkah untuk mencegah perampasan sesi. Sila tekan butang \"balik\", lalu muatkan semula halaman yang anda telah mengunjungi sebelum ini dan cuba semula.",
+"protectlogpage" => "Log perlindungan",
+"protectlogtext" => "Di bawah ini adalah senarai untuk halaman yang telah dikunci/dibuka semula. Sila lihat [[{{ns:project}}:Halaman Dilindungi]] untuk maklumat lanjut.",
+"protectedarticle" => "Melindungi [[$1]]",
+"unprotectedarticle" => "Nyahkan perlindungan [[$1]]",
+"protectsub" => "(Melindungi \"$1\")",
+"confirmprotecttext" => "Adakah anda benar-benar ingin melindungi halaman ini?",
+"confirmprotect" => "Pengesahan Perlindungan",
+'protectmoveonly' => "Lindungi dari perpindahan sahaja",
+"protectcomment" => "Alasan perlindungan",
+"unprotectsub" => "(Nyahkan perlindungan bagi \"$1\")",
+"confirmunprotecttext" => "Adakah anda benar-benar hendak mengenyahkan perlindungan bagi halaman ini?",
+"confirmunprotect" => "Pengesahan nyahlindung",
+"unprotectcomment" => "Alasan nyahlindung",
+
+
+# Undelete
+"undelete" => "Pulihkan halaman terpadam", #"Restore deleted page",
+"undeletepage" => "Lihat dan pulihkan halaman terpadam", #"View and restore deleted pages",
+"undeletepagetext" => "Halaman-halaman terpadam yang berikut masih berada di dalam arkib dan boleh lagi dipulihkan, jika perlu. Arkib ini boleh dibersihkan dari semasa ke semasa.", #"The following pages have been deleted but are still in the archive and can be restored. The archive may be periodically cleaned out.",
+"undeletearticle" => "Pulihkan rencana terpadam", #"Restore deleted article",
+"undeleterevisions" => "$1 semakan telah diarkib.", #"$1 revisions archived",
+"undeletehistory" => "Jika anda memulihkan halaman tersebut, semua semakan akan dipulihkan ke sejarahnya. Jika terdapat halaman baru yang mempunyai nama yang sama telah dibuat sejak pemadaman, semakan yang dipulihkan akan wujud dalam sejarah dahulu, dan halaman semakan terkini tidak akan digantikan secara automatik.", #"If you restore the page, all revisions will be restored to the history. If a new page with the same name has been created since the deletion, the restored revisions will appear in the prior history, and the current revision of the live page will not be automatically replaced.",
+"undeleterevision" => "Semakan terpadam sejak $1", #"Deleted revision as of $1",
+"undeletebtn" => "Terpulih!",
+"undeletedarticle" => "\"$1\" telah dipulih",
+'undeletedrevisions' => "$1 semakan telah dipulih",
+"undeletebtn" => "Pemulihan berjaya!", #"Restore!",
+"undeletedarticle" => "telah dipulih", #"restored \"$1\"",
+
+
+# Contributions
+#
+"contributions" => "Sumbangan pengguna", #"User contributions",
+"mycontris" => "Sumbangan saya", #"My contributions",
+"contribsub" => "Untuk $1", #"For $1",
+"nocontribs" => "Tiada sebarang perubahan yang sepadan dengan kriteria-kriteria ini.", #"No changes were found matching these criteria.",
+"ucnote" => "Di bawah ini adalah <b>$1</b> perubahan terbaru yang dibuat oleh pengguna ini sejak <b>$2</b> hari yang lalu.", #"Below are this user's last <b>$1</b> changes in the last <b>$2</b> days.",
+"uclinks" => "Paparkan $1 perubahan terkini; paparkan $2 hari yang lalu", #"View the last $1 changes; view the last $2 days.",
+"uctop" => "(atas)", #"(top)",
+'newbies' => "Pengguna baru",
+
+
+# What links here
+#
+"whatlinkshere" => "Pautan ke halaman ini", #"Pages that link here,
+"notargettitle" => "Tiada sasaran", #"No target",
+"notargettext" => "Anda tidak menetapkan halaman atau pengguna sasaran untuk melaksanakan fungsi ini.",
+"linklistsub" => "(Senarai Pautan)", #"(List of links)",
+"linkshere" => "Halaman-halaman berikut berpaut ke sini:", #"The following pages link to here:",
+"nolinkshere" => "Tiada halaman yang berpaut ke sini.", #"No pages link to here.",
+"isredirect" => "Halaman peralihan", #"redirect page",
+
+
+# Block/unblock IP
+#
+"blockip" => "Sekatkan IP", #"Block IP",
+"blockiptext" => "Gunakan borang di bawah untuk menyekatkan capaian tulis dari alamat IP atau pengguna tertentu. Ini hanya dilakukan untuk mencegah laku musnah selaras dengan [[{{ns:project}}:Polisi dan garis panduan|Dasar {{SITENAME}}]]. Masukkan alasan tertentu di bawah (umpamannya, sebutkan halaman yang telah dilaku musnahkan).",
+"ipaddress" => "Alamat IP atau Nama Pengguna", #"IP Address or Username",
+"ipbreason" => "Alasan", #"Reason",
+"ipbsubmit" => "Kirim", #"Submit",
+'ipbother' => "Waktu lain",
+'ipboptions' => "1 jam:1 hour, 2 jam:2 hours, 1 hari:1 day, 3 hari:3 days, 1 minggu:1 week, 2 minggu:2 week, 1 bulan:1 month, 3 bulan:3 months, 6 bulan:6 months,1 tahun:1 year,tak terbatas:infinite",
+'ipbotheroption' => "lain-lain",
+"badipaddress" => "Format alamat IP atau nama pengguna tidak betul.", #"The IP address or username is badly formed.",
+"blockipsuccesssub" => "Penyekatan berjaya", #"Block succeeded",
+"blockipsuccesstext" => "Alamat IP atau nama pengguna \"$1\" telah disekat. <br />Sila lihat [[{{ns:special}}:Ipblocklist|Senarai Sekatan]] untuk meninjau penyekatan semula.",
+"unblockip" => "Nyahkan sekatan alamat IP atau pengguna", #"Unblock IP address or user",
+"unblockiptext" => "Gunakan borang di bawah untuk memulihkan capaian tulis kepada alamat IP atau nama pengguna yang telah disekat.",
+"ipusubmit" => "Nyahkan sekatan bagi alamat ini.", #"Unblock this address",
+"ipblocklist" => "Senarai alamat IP dan nama pengguna yang tersekat", #"List of blocked IP addresses and users",
+'infiniteblock' => "tak terbatas",
+'expiringblock' => "$1 tamat tempohnya",
+'ipblocklistempty' => "Senarai sekatan adalah kosong.",
+"blocklistline" => "$1, $2 menyekati $3 ($4)",
+"blocklink" => "sekat", #"block",
+"unblocklink" => "nyahsekat", #"unblock",
+"contribslink" => "sumbangan",
+"autoblocker" => "Disekat secara automatik kerana alamat IP baru-baru ini digunakan oleh '[[Pengguna:$1|$1]]'. Alasan untuk menyekatkan $1\ adalah: \"$2\".",
+"blocklogpage" => "Log sekatan",
+"blocklogentry" => "Sekatkan '$1' sehingga $2",
+"blocklogtext" => "Ini adalah log tindakan sekat dan nyahsekat. Penyekatan secara automatik tidak tersenarai. Sila lihat [[{{ns:special}}:Ipblocklist|Senarai Sekatan IP]] untuk penyekatan terkini.",
+"unblocklogentry" => "nyahsekat '$1'",
+"range_block_disabled" => "Kebolehan penyelia untuk membuat penyekatan julat dimatikan.",
+"ipb_expiry_invalid"=> "Waktu habis tempoh tidak sah.",
+"ip_range_invalid" => "Julat IP tidak sah.",
+"proxyblocker" => "Penyekat proksi",
+"proxyblockreason" => "Alamat IP anda telah disekat kerana ia merupakan proksi terbuka. Sila hubungi Penyedia Perkhidmatan Internet atau bantuan teknikal anda untuk memberitahu masalah keselamatan yang teruk ini.",
+"proxyblocksuccess" => "Berjaya.",
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => "Alamat IP anda telah disenaraikan sebagai proksi terbuka di [http://www.sorbs.net SORBS] DNSBL.",
+'sorbs_create_account_reason' => "Alamat IP anda telah disenaraikan sebagai proksi terbuka di [http://www.sorbs.net SORBS] DNSBL. Oleh sebab itu, anda tidak dapat membuka akaun.",
+
+
+# Developer tools
+#
+"lockdb" => "Kuncikan pangkalan data", #"Lock database",
+"unlockdb" => "Nyahkan kunci pangkalan data", #"Unlock database",
+"lockdbtext" => "Mengunci pangkalan data akan menyekati pengguna daripada penyuntingan halaman, penukaran tatarajah mereka serta lain-lain perkara yang melibatkan pengemaskinan pangkalan data. Sila pastikan anda memang hendak berbuat demikian, dan anda akan membuka semula pangkalan data apabila penyelenggaraan telah selesai.",
+"unlockdbtext" => "Nyahkan kunci pangkalan data akan membolehkan pengguna daripada penyuntingan halaman, penukaran tatarajah mereka serta lain-lain perkara yang melibatkan pengemaskinian pangkalan data. Sila pastikan anda memang hendak berbuat demikian.",
+"lockconfirm" => "Ya, saya memang hendak menguncikan pangkalan data ini.", #"Yes, I really want to lock the database.",
+"unlockconfirm" => "Ya, saya memang hendak mengenyahkan kunci pangkalan data ini.", #"Yes, I really want to unlock the database.",
+"lockbtn" => "Kuncikan pangkalan data", #"Lock database",
+"unlockbtn" => "Nyahkan kunci pangkalan data", #"Unlock database",
+"locknoconfirm" => "Anda tidak menandakan kotak pengesahan.", #"You did not check the confirmation box.",
+"lockdbsuccesssub" => "Penguncian pangkalan data berjaya", #"Database lock succeeded",
+"unlockdbsuccesssub" => "Pangkalan data telah dibuka semula", #"Database lock removed",
+"lockdbsuccesstext" => "Pangkalan data {{SITENAME}} telah dikunci.<br />Pastikan anda membukanya semula selepas penyelenggaraan telah selesai.",
+"unlockdbsuccesstext" => "Pangkalan data {{SITENAME}} telah dibuka semula.",
+
+
+
+# Move page
+#
+"movepage" => "Alih halaman", #"Move page",
+"movepagetext" => "Borang di bawah ini adalah untuk mengubahkan nama halaman dan memindahkan semua data sejarahnya ke nama baru. Tajuk yang lama akan menjadi halaman peralihan yang menuju ke tajuk yang baru. Pautan-pautan ke tajuk yang lama tidak akan berubah. Sila semak bagi mengelakkan peralihan berganda atau peralihan rosak. Anda adalah bertanggung jawab untuk memastikan bahawa pautan-pautan masih berkait ke halaman yang seharusnya. <p>Sila perhatikan bahawa halaman <b>tidak</b> akan dipindah jika terdapatnya halaman yang mempunyai tajuk yang sama (kecuali halaman itu kosong atau merupakan halaman peralihan dan tidak mempunyai sejarah penyuntingan). Ini bererti bahawa anda dapat mengubahkan kembali nama halaman ke nama asalnya. Anda tidak boleh menindih atas halaman yang telah wujud.</p> <p><b>AMARAN!</b> Ini boleh merupakan perubahan yang drastik dan menyebabkan akibat yang tidak dijangka, khususnya bagi halaman yang popular. Sila pastikan bahawa anda faham akan selok belok borang ini sebelum anda meneruskan.</p>",
+'movepagetalktext'=> "Halaman perbualan yang berkaitan, jika ada, akan dipindahkan bersama-sama secara automatik kecuali:\n * Anda memindahkan halaman melampaui ruangnama;\n * Halaman perbualan yang berisi sedia ada di bawah nama baru; atau\n * Anda mengenyahkan tanda di bawah.\n Dalam kes tersebut, anda terpaksa memindahkan atau menggabungkan halaman secara manual sekiranya diperlukan.",
+
+"movearticle" => "Alih halaman", #"Move page",
+"movenologin" => "Belum log masuk", #"Not logged in",
+"movenologintext" => "Anda harus [[{{ns:special}}:Userlogin|log masuk]] untuk mengalihkan halaman.",
+"newtitle" => "Ke tajuk baru", #"To new title",
+"movepagebtn" => "Alih halaman", #"Move page",
+"pagemovedsub" => "Pengalihan berjaya", #"Move succeeded",
+"pagemovedtext" => "Halaman \"[[$1]]\" dialihkan ke \"[[$2]]\".", #"Page \"[[$1]]\" moved to \"[[$2]]\".",
+"articleexists" => "Halaman dengan nama tersebut telah wujud, atau nama yang dipilih tidak sah.
+Sila pilihkan nama lain.",
+"talkexists" => "Halaman ini sahaja berjaya dialihkan. Halaman perbualan tidak dapat dialih kerana halaman itu telah wujud. Sila gabungkan secara manual.", #"The page itself was moved successfully, but the talk page could not be moved because one already exists at the new title. Please merge them manually.",
+"movedto" => "Alihkan ke", #"moved to",
+"movetalk" => "Alihkan halaman \"perbualan\" juga, jika sesuai.", #"Move \"talk\" page as well, if applicable.",
+"talkpagemoved" => "Halaman perbualan yang berkaitan juga turut dialihkan.", #"The corresponding talk page was also moved.",
+"talkpagenotmoved" => "Halaman perbualan yang berkaitan <b>tidak</b> turut dialihkan.",
+'1movedto2' => "$1 dialihkan ke $2",
+'movelogpage' => "Log pengalihan",
+'movelogpagetext' => "Di bawah adalah senarai halaman yang telah dialih.",
+'movereason' => "Alasan",
+'revertmove' => "Kembali",
+'delete_and_move' => "Hapus dan alih",
+'delete_and_move_text' =>
+"==Pemadaman diperlu==
+Rencana destinasi \"[[$1]]\" sudah wujud. Adakah anda ingin memadamkannya supaya dapat membolehkan peralihan?",
+'delete_and_move_reason' => "Terpadam untuk membolehkan peralihan",
+'selfmove' => "Tajuk sumber dan tajuk destinasi adalah sama; tidak dapat mengalihkan halaman ke halaman kendiri.", #"Source and destination titles are the same; can't move a page over itself.",
+'immobile_namespace' => "Tajuk destinasi merupakan jenis yang istimewa; tidak dapat mengalihkan halaman-halaman ke ruang nama itu.", #"Destination title is of a special type; cannot move pages into that namespace."
+);
+
+?>
diff --git a/languages/messages/MessagesMt.php b/languages/messages/MessagesMt.php
new file mode 100644
index 000000000000..8f2332a26e54
--- /dev/null
+++ b/languages/messages/MessagesMt.php
@@ -0,0 +1,99 @@
+<?php
+/** Maltese (Malti)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$messages = array(
+'mainpage' => 'Paġna prinċipali',
+
+'portal' => 'Portal tal-komunità',
+'portal-url' => 'Project:Portal tal-komunità',
+'aboutsite' => 'Dwar {{SITENAME}}',
+'help' => 'Għajnuna',
+'sitesupport' => 'Donazzjonijiet',
+'sitesupport-url' => 'Project:Donazzjonijiet',
+'mytalk' => 'Diskussjonijiet tiegħi',
+'navigation' => 'Navigazzjoni',
+
+'currentevents' => 'Ġrajjiet kurrenti',
+'currentevents-url' => 'Project:Ġrajjiet kurrenti',
+
+'disclaimers' => 'Ċaħdiet',
+'search' => 'Fittex',
+'go' => 'Mur',
+'history_short' => 'Kronoloġija',
+'printableversion' => 'Verżjoni għall-ipprintjar',
+'permalink' => 'Link permanenti',
+'edit' => 'Editja',
+'delete' => 'Ħassar',
+'protect' => 'Ipproteġi',
+'unprotect' => 'Tibqax tipproteġi',
+'personaltools' => 'Strumenti personali',
+'talk' => 'Diskussjoni',
+'toolbox' => 'Għodda',
+
+'youhavenewmessages' => 'Għandek $1 ($2).',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Artiklu',
+'nstab-mediawiki' => 'Messaġġ',
+
+# General errors
+'viewsource' => 'Ara l-fonti',
+
+# Login and logout pages
+'userlogin' => 'Idħol jew oħloq kont ġdid',
+'userlogout' => 'Oħroġ',
+
+# Edit pages
+'savearticle' => 'Salva l-paġna',
+'editing' => 'Qed jiġi editjat l-artiklu $1',
+'editingcomment' => 'Edit $1 (kumment)',
+
+# Preferences page
+'preferences' => 'Preferenzi',
+
+# Recent changes
+'recentchanges' => 'Tibdil riċenti',
+
+# Upload
+'upload' => "Tella' file",
+
+# Miscellaneous special pages
+'allpages' => 'Il-paġni kollha',
+'randompage' => 'Paġna kwalunkwe',
+'specialpages' => 'Paġni speċjali',
+'recentchangeslinked' => 'Tibdil relatat',
+'move' => 'Mexxi',
+
+'version' => 'Verżjoni',
+
+# E-mail user
+'emailuser' => 'Ibgħat e-mail lil dan l-utent',
+
+# Watchlist
+'watchlist' => "Lista t'osservazzjoni tiegħi",
+'watch' => 'Segwi',
+'unwatch' => 'Tibqax issegwi',
+
+# Undelete
+'undelete' => 'Irkupra l-paġna mħassra',
+
+# Contributions
+'contributions' => 'Kontribuzzjonijiet tal-user',
+'mycontris' => 'Kontribuzzjonijiet tiegħi',
+
+# What links here
+'whatlinkshere' => 'Links li jwasslu hawn',
+
+# Block/unblock
+'blockip' => 'Ibblokkja l-utent',
+
+# Namespace 8 related
+'allmessages' => 'Il-messaġġi kollha tas-sistema',
+
+);
+
+?>
diff --git a/languages/messages/MessagesMzn.php b/languages/messages/MessagesMzn.php
new file mode 100644
index 000000000000..081432bcdb76
--- /dev/null
+++ b/languages/messages/MessagesMzn.php
@@ -0,0 +1,23 @@
+<?php
+/** Mazandarani
+ *
+ * Minimalistic setup, needed to switch to right-to-left writing.
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$linkPrefixExtension = true;
+$fallback8bitEncoding = 'windows-1256';
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+ # Underlines seriously harm legibility. Force off:
+ 'underline' => 0,
+);
+
+$fallback = 'fa';
+
+?>
diff --git a/languages/messages/MessagesNah.php b/languages/messages/MessagesNah.php
new file mode 100644
index 000000000000..b3f4b31fa551
--- /dev/null
+++ b/languages/messages/MessagesNah.php
@@ -0,0 +1,51 @@
+<?php
+/** Nahuatl
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Rob Church <robchur@gmail.com>
+ *
+ * @copyright Copyright © 2006, Rob Church
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+# Per conversation with a user in IRC, we inherit from Spanish and work from there
+# Nahuatl was the language of the Aztecs, and a modern speaker is most likely to
+# understand Spanish if a Nah translation is not available
+$fallback = 'es';
+
+$messages = array(
+
+ # Month names
+ 'january' => 'Tlacenti',
+ 'february' => 'Tlaonti',
+ 'march' => 'Tlayeti',
+ 'april' => 'Tlanauhtl',
+ 'may' => 'Tlamacuilti',
+ 'june' => 'Tlachicuazti',
+ 'august' => 'Tlachiconti',
+ 'september' => 'Tlachicnauhti',
+ 'october' => 'Tlamatlacti',
+ 'november' => 'Tlamactlihuanceti',
+ 'december' => 'Tlamactlihuanonti',
+
+ # Days of the week
+ 'monday' => 'Metztlitonal',
+ 'tuesday' => 'Huitzilopochtonal',
+ 'wednesday' => 'Yacatlipotonal',
+ 'thursday' => 'Tezcatlipotonal',
+ 'friday' => 'Quetzalcoatonal',
+ 'saturday' => 'Tlaloctitonal',
+ 'sunday' => 'Tonatiutonal',
+
+ # Preferences etc.
+ 'userlogin' => 'Calaqui / Registrarse',
+ 'yourlanguage' => 'Tlahtolli:',
+ 'yourpassword' => 'Tlahtolichtacayo',
+ 'yourpasswordagain' => 'Tlahtolichtacayo zapa'
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesNap.php b/languages/messages/MessagesNap.php
new file mode 100644
index 000000000000..64924cf395cf
--- /dev/null
+++ b/languages/messages/MessagesNap.php
@@ -0,0 +1,10 @@
+<?php
+/** Neapolitan (Nnapulitano)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'it';
+
+?>
diff --git a/languages/messages/MessagesNds.php b/languages/messages/MessagesNds.php
new file mode 100644
index 000000000000..4f0853c67d4d
--- /dev/null
+++ b/languages/messages/MessagesNds.php
@@ -0,0 +1,1171 @@
+<?php
+
+/** Low Saxon (Plattdüütsch)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$quickbarSettings = array(
+ 'Keen', 'Links, fast', 'Rechts, fast', 'Links, sweven'
+);
+
+$magicWords = array(
+ # ID CASE SYNONYMS
+ 'redirect' => array( 0, '#redirect', '#wiederleiden' ),
+ 'notoc' => array( 0, '__NOTOC__', '__KEENINHOLTVERTEKEN__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__WIESINHOLTVERTEKEN__' ),
+ 'toc' => array( 0, '__TOC__', '__INHOLTVERTEKEN__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__KEENÄNNERNLINK__' ),
+ 'start' => array( 0, '__START__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'AKTMAAND' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'AKTMAANDNAAM' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'AKTDAG' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'AKTDAGNAAM' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'AKTJOHR' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'AKTTIED' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'ARTIKELTALL' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'AKTMAANDNAAMGEN' ),
+ 'pagename' => array( 1, 'PAGENAME', 'SIETNAAM' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'SIETNAAME' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'NAAMRUUM' ),
+ 'subst' => array( 0, 'SUBST:' ),
+ 'msgnw' => array( 0, 'MSGNW:' ),
+ 'end' => array( 0, '__END__', '__ENN__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'duum' ),
+ 'img_right' => array( 1, 'right', 'rechts' ),
+ 'img_left' => array( 1, 'left', 'links' ),
+ 'img_none' => array( 1, 'none', 'keen' ),
+ 'img_width' => array( 1, '$1px', '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre', 'merrn' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'rahmt' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'STEEDNAAM' ),
+ 'ns' => array( 0, 'NS:', 'NR:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'STEEDURL:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'STEEDURLE:' ),
+ 'server' => array( 0, 'SERVER', 'SERVER' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'GRAMMATIK:' )
+);
+
+$skinNames = array(
+ 'standard' => 'Klassik',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Kölsch Blau',
+ 'smarty' => 'Paddington',
+ 'chick' => 'Küken'
+);
+
+
+$bookstoreList = array(
+ 'Verteken vun leverbore Böker' => 'http://www.buchhandel.de/sixcms/list.php?page=buchhandel_profisuche_frameset&suchfeld=isbn&suchwert=$1=0&y=0',
+ 'abebooks.de' => 'http://www.abebooks.de/servlet/BookSearchPL?ph=2&isbn=$1',
+ 'Amazon.de' => 'http://www.amazon.de/exec/obidos/ISBN=$1',
+ 'Lehmanns Fachbuchhandlung' => 'http://www.lob.de/cgi-bin/work/suche?flag=new&stich1=$1',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Spezial',
+ NS_MAIN => '',
+ NS_TALK => 'Diskuschoon',
+ NS_USER => 'Bruker',
+ NS_USER_TALK => 'Bruker_Diskuschoon',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_Diskuschoon',
+ NS_IMAGE => 'Bild',
+ NS_IMAGE_TALK => 'Bild_Diskuschoon',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_Diskuschoon',
+ NS_TEMPLATE => 'Vörlaag',
+ NS_TEMPLATE_TALK => 'Vörlaag_Diskuschoon',
+ NS_HELP => 'Hülp',
+ NS_HELP_TALK => 'Hülp_Diskuschoon',
+ NS_CATEGORY => 'Kategorie',
+ NS_CATEGORY_TALK => 'Kategorie_Diskuschoon'
+);
+$linkTrail = '/^([äöüßa-z]+)(.*)$/sDu';
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j., Y',
+ 'mdy both' => 'H:i, M j., Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. M Y',
+ 'dmy both' => 'H:i, j. M Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j.',
+ 'ymd both' => 'H:i, Y M j.',
+);
+
+$messages = array(
+# Schalter för de Brukers
+'tog-underline' => 'Verwies ünnerstrieken',
+'tog-highlightbroken' => 'Verwies op leddige Sieten hervörheven',
+'tog-justify' => 'Text as Blocksatz',
+'tog-hideminor' => 'Kene lütten Ännern in letzte Ännern wiesen',
+'tog-usenewrc' => 'Erwiederte letzte Ännern (nich för alle Browser bruukbor)',
+'tog-numberheadings' => 'Överschrieven automatsch nummereern',
+'tog-showtoolbar' => 'Editeer-Warktüüchlist wiesen',
+'tog-editondblclick' => 'Sieten mit Dubbelklick bearbeiden (JavaScript)',
+'tog-editsection' => 'Links för dat Bearbeiden vun en Afsatz wiesen',
+'tog-editsectiononrightclick' => 'En Afsatz mit en Rechtsklick bearbeiden (Javascript)',
+'tog-showtoc' => 'Wiesen vun\'n Inholtsverteken bi Sieten mit mehr as dree Överschriften',
+'tog-rememberpassword' => 'Duersam Inloggen',
+'tog-editwidth' => 'Text-Ingaavfeld mit vulle Breed',
+'tog-watchdefault' => 'Op niege un ännerte Sieten oppassen',
+'tog-minordefault' => 'Alle Ännern as lütt markeern',
+'tog-previewontop' => 'Vörschau vör dat Editeerfinster wiesen',
+'tog-previewonfirst' => 'Vörschau bi\'n eersten Ännern wiesen',
+'tog-nocache' => 'Sietencache deaktiveern',
+# Dates
+'sunday' => 'Sünndag',
+'monday' => 'Maandag',
+'tuesday' => 'Dingsdag',
+'wednesday' => 'Merrweek',
+'thursday' => 'Dunnersdag',
+'friday' => 'Freedag',
+'saturday' => 'Sünnavend',
+'january' => 'Januar',
+'february' => 'Februar',
+'march' => 'März',
+'april' => 'April',
+'may_long' => 'Mai',
+'june' => 'Juni',
+'july' => 'Juli',
+'august' => 'August',
+'september' => 'September',
+'october' => 'Oktober',
+'november' => 'November',
+'december' => 'Dezember',
+'jan' => 'Jan',
+'feb' => 'Feb',
+'mar' => 'Mär',
+'apr' => 'Apr',
+'may' => 'Mai',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Aug',
+'sep' => 'Sep',
+'oct' => 'Okt',
+'nov' => 'Nov',
+'dec' => 'Dez',
+
+
+# Textdelen, de vun vele Sieten bruukt warrn:
+#
+'categories' => 'Sietenkategorien',
+'pagecategories' => 'Sietenkategorien',
+'category_header' => 'Sieten in de Kategorie $1',
+'subcategories' => 'Ünnerkategorien',
+'mainpage' => 'Hööftsiet',
+'mainpagetext' => 'De Wiki-Software is mit Spood installeert worrn.',
+'mainpagedocfooter' => 'Kiek de [http://meta.wikimedia.org/wiki/MediaWiki_i18n Dokumentatschoon för dat Anpassen vun de Brukerböversiet]
+un dat [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Brukerhandbook] för Hülp to de Bruuk un Konfiguratschoon.',
+'portal' => '{{SITENAME}}-Portal',
+'portal-url' => '{{ns:4}}:Portal',
+'about' => 'Över',
+'aboutsite' => 'Över {{SITENAME}}',
+'aboutpage' => '{{ns:4}}:Över_{{SITENAME}}',
+'article' => 'Artikel',
+'help' => 'Hülp',
+'helppage' => '{{ns:4}}:Hülp',
+'bugreports' => 'Kontakt',
+'bugreportspage' => '{{ns:4}}:Kontakt',
+'sitesupport' => 'Gaven',
+'faq' => 'Faken stellte Fragen',
+'faqpage' => '{{ns:project}}:Faken stellte Fragen',
+'newwindow' => '(apent sik in en nieg Finster)',
+'edithelp' => 'Bearbeidenshülp',
+'edithelppage' => '{{ns:project}}:Editeerhülp',
+'cancel' => 'Afbreken',
+'qbfind' => 'Finnen',
+'qbbrowse' => 'Blädern',
+'qbedit' => 'Ännern',
+'qbpageoptions' => 'Sietenoptschonen',
+'qbpageinfo' => 'Sietendaten',
+'qbmyoptions' => 'Instellen',
+'qbspecialpages' => 'Spezialsieten',
+'moredotdotdot' => 'Mehr...',
+'mypage' => 'Mien Siet',
+'mytalk' => 'Mien Diskuschoon',
+'anontalk' => 'Diskuschoonssiet vun disse IP',
+'navigation' => 'Navigatschoon',
+'currentevents' => 'Aktuell Schehn',
+'currentevents-url' => '{{ns:4}}:Aktuell Schehn',
+'disclaimers' => 'Lizenzbestimmen',
+'disclaimerpage' => '{{ns:4}}:Lizenzbestimmen',
+'errorpagetitle' => 'Fehler',
+'returnto' => 'Trüch to $1.',
+'whatlinkshere' => 'Wat wiest hierher',
+'help' => 'Hülp',
+'search' => 'Söök',
+'searchbutton' => 'Söök',
+'history' => 'Historie',
+'history_short' => 'Historie',
+'info_short' => 'Informatschoon',
+'printableversion' => 'Druckversion',
+'editthispage' => 'Siet bearbeiden',
+'delete' => 'wegsmieten',
+'deletethispage' => 'Disse Siet wegsmieten',
+'undelete_short' => 'Weerholen',
+'protect' => 'Schulen',
+'protectthispage' => 'Siet schulen',
+'unprotect' => 'Freegeven',
+'unprotectthispage' => 'Schuul opheben',
+'newpage' => 'Niege Siet',
+'talkpage' => 'Diskuschoon',
+'specialpage' => 'Spezialsiet',
+'personaltools' => 'Persönliche Warktüüch',
+'postcomment' => 'Kommentar hentofögen',
+'articlepage' => 'Artikel',
+'toolbox' => 'Warktüüch',
+'projectpage' => 'Meta-Text',
+'userpage' => 'Brukersiet',
+'imagepage' => 'Bildsiet',
+'viewtalkpage' => 'Diskuschoon',
+'otherlanguages' => 'Annere Spraken',
+'redirectedfrom' => '(Wiederleiden vun $1)',
+'lastmodifiedat' => 'Disse Siet is toletzt üm $2, $1 ännert worrn.',
+'viewcount' => 'Disse Siet is $1 Maal opropen worrn.',
+'copyright' => 'De Inholt is verfögbor ünner de $1.',
+'protectedpage' => 'Schulte Sieten',
+'nbytes' => '$1 Bytes',
+'go' => 'Los',
+'searcharticle' => 'Los',
+'ok' => 'OK',
+'retrievedfrom' => 'Vun „$1“',
+'newmessageslink' => 'niege Norichten',
+'editsection' => 'bearbeiden',
+'editold' => 'bearbeiden',
+'toc' => 'Inholtsverteken',
+'showtoc' => 'wiesen',
+'hidetoc' => 'Nich wiesen',
+'thisisdeleted' => 'Ankieken oder weerholen vun $1?',
+'restorelink' => '$1 löscht Bearbeidensvörgäng',
+'feedlinks' => 'Feed:',
+
+# Kortwöör för elkeen Namespace, ünner annern vun MonoBook bruukt
+'nstab-main' => 'Artikel',
+'nstab-user' => 'Brukersiet',
+'nstab-media' => 'Media',
+'nstab-special' => 'Spezial',
+'nstab-project' => 'Över',
+'nstab-image' => 'Bild',
+'nstab-mediawiki' => 'Noricht',
+'nstab-template' => 'Vörlaag',
+'nstab-help' => 'Hülp',
+'nstab-category' => 'Kategorie',
+
+# Editeer-Warktüüchleist
+'bold_sample' => 'Fetten Text',
+'bold_tip' => 'Fetten Text',
+'italic_sample' => 'Kursiven Text',
+'italic_tip' => 'Kursiven Text',
+'link_sample' => 'Link-Text',
+'link_tip' => 'Internen Link',
+'extlink_sample' => 'http://www.bispeel.com Link-Text',
+'extlink_tip' => 'Externen Link (http:// is wichtig)',
+'headline_sample' => 'Evene 2 Överschrift',
+'headline_tip' => 'Evene 2 Överschrift',
+'math_sample' => 'Formel hier infögen',
+'math_tip' => 'Mathematsche Formel (LaTeX)',
+'nowiki_sample' => 'Unformateerten Text hier infögen',
+'nowiki_tip' => 'Unformateerten Text',
+'image_sample' => 'Bispeel.jpg',
+'image_tip' => 'Bild-Verwies',
+'media_sample' => 'Bispeel.mp3',
+'media_tip' => 'Mediendatei-Verwies',
+'sig_tip' => 'Dien Signatur mit Tiedstempel',
+'hr_tip' => 'Waagrechte Lien (sporsam bruken)',
+
+# Hööft-Script un globale Funktschonen
+#
+'nosuchaction' => 'Disse Aktschoon gifft dat nich',
+'nosuchactiontext' => 'Disse Aktschoon warrt vun de MediaWiki-Software nich ünnerstütt',
+'nosuchspecialpage' => 'Disse Spezialsiet gifft dat nich',
+'nospecialpagetext' => 'Disse Spezialsiet warrt vun de MediaWiki-Software nich ünnerstütt',
+
+# Generelle Fehlers
+#
+'error' => 'Fehler',
+'databaseerror' => 'Fehler in de Datenbank',
+'dberrortext' => 'Dor weer en Syntaxfehler in de Datenbankaffraag.
+De letzte Datenbankaffraag weer:
+
+<blockquote><tt>$1</tt></blockquote>
+
+ut de Funktschoon <tt>$2</tt>.
+MySQL mell den Fehler <tt>$3: $4</tt>.',
+'dberrortextcl' => 'Dor weer en Syntaxfehler in de Datenbankaffraag.
+De letzte Datenbankaffraag weer: $1 ut de Funktschoon <tt>$2</tt>.
+MySQL mell den Fehler: <tt>$3: $4</tt>.',
+'noconnect' => 'De Software kunn keen Verbinnen to de Datenbank op $1 opnehmen',
+'nodb' => 'De Software kunn de Datenbank $1 nich utwählen',
+'cachederror' => 'Disse Siet is en Kopie ut\'n Cache un is mööglicherwies nich aktuell.',
+'readonly' => 'Datenbank is sparrt',
+'enterlockreason' => 'Giff den Grund an, worüm de Datenbank sparrt warrn schall un taxeer, wo lang de Sparr duert',
+'readonlytext' => 'De {{SITENAME}}-Datenbank is för enige Tied sparrt, to\'n Bispeel wegen Pleegarbeiden. Versöök dat later noch eenmal.',
+'missingarticle' => 'De Text för de Siet \'$1\' kunn nich in de Datenbank funnen warrn. Dat is wohrschienlich en Fehler in de Software. Bitte mell dat an enen Administrater un giff ok den Sietennaam an.',
+'internalerror' => 'Internen Fehler',
+'filecopyerror' => 'De Software kunn Datei \'$1\' nich no \'$2\' kopeern.',
+'filerenameerror' => 'De Software kunn Datei \'$1\' nich no \'$2\' ümnömen.',
+'filedeleteerror' => 'De Software kunn Datei \'$1\' nich löschen.',
+'filenotfound' => 'De Software kunn Datei \'$1\' nich finnen.',
+'unexpected' => 'Unvermodten Weert: \'$1\'=\'$2\'.',
+'formerror' => 'Fehler: De Software kunn dat Formular nich verarbeiden',
+'badarticleerror' => 'Disse Aktschoon kann op disse Siet nich anwennt warrn.',
+'cannotdelete' => 'De Software kunn de spezifizeerte Siet nich löschen. (Mööglicherwies is de al vun en annern löscht worrn.)',
+'badtitle' => 'Ungülligen Titel',
+'badtitletext' => 'De Titel vun de födderte Siet weer ungüllig, leddig, oder en ungülligen Spraaklink vun en annern Wiki.',
+'perfdisabled' => 'Disse Funktschoon is wegen Överlast vun de Servers för enige Tied deaktiveert. Versöök dat doch twüschen 02:00 un 14:00 UTC noch eenmal<br />(Aktuelle Servertied: '.date('H:i:s').' UTC).',
+'perfdisabledsub' => 'Hier is en spiekerte Kopie vun $1:',
+'perfcached' => 'Disse Daten kamen ut den Cache un sünd mööglicherwies nich aktuell:',
+'wrong_wfQuery_params' => 'Falschen Parameter för wfQuery()<br />
+Funktschoon: $1<br />
+Query: $2',
+'viewsource' => 'Borntext ankieken',
+'protectedtext' => 'Disse Siet is för dat Bearbeiden sparrt. Dorför kann dat verschedene Grünn geven; kiek [[{{ns:4}}:Schulte Sieten]].
+
+Du kannst den Borntext vun disse Siet ankieken un kopeern:',
+
+
+# Login- un Logoutsieten
+#
+'logouttitle' => 'Bruker-Afmellen',
+'logouttext' => 'Du büst nu afmellt. Du kannst {{SITENAME}} nu anonym wiederbruken oder di ünner en annern Brukernaam weer anmellen.',
+
+'welcomecreation' => '<h2>Willkomen, $1!</h2><p>Dien Brukerkonto is nu inricht.
+Vergeet nich, dien [[Special:Preferences|Instellen]] antopassen.',
+
+'loginpagetitle' => 'Bruker-Anmellen',
+'yourname' => 'Dien Brukernaam',
+'yourpassword' => 'Dien Password',
+'yourpasswordagain' => 'Password nochmal ingeven',
+'remembermypassword' => 'Duersam inloggen',
+'loginproblem' => '<b>Dor weer en Problem mit dien Anmellen.</b><br />Versöök dat noch eenmal!',
+'alreadyloggedin' => '<strong>Bruker $1, du büst al anmellt!</strong><br />',
+
+'login' => 'Anmellen',
+'loginprompt' => 'Üm sik bi {{SITENAME}} antomellen, musst du Cookies aktiveert hebben.',
+'userlogin' => 'Anmellen',
+'logout' => 'Afmellen',
+'userlogout' => 'Afmellen',
+'notloggedin' => 'Nich anmellt',
+'createaccount' => 'Nieg Brukerkonto anleggen',
+'createaccountmail' => 'över E-Mail',
+'badretype' => 'De beiden Passwöör stimmt nich övereen.',
+'userexists' => 'Dissen Brukernaam is al vergeven. Bitte wähl en annern.',
+'youremail' => 'Dien E-Mail (kene Plicht) *',
+'yournick' => 'Dien Ökelnaam (för dat Ünnerschrieven)',
+'yourrealname' => 'Dien echten Naam (kene Plicht)',
+'yourlanguage' => 'Snittstellenspraak',
+'yourvariant' => 'Dien Spraak',
+// FIXME: following should be split to 'prefs-help-realname' & 'prefs-help-email'
+#'prefs-help-userdata' => '* <strong>E-Mail</strong> (kene Plicht): Wenn du en E-Mailadress angiffst, könen annere di E-Mails sennen,
+#ahn dat diene Adress no buten künnig warrt. Wenn du dien ol Password vergeten hest,
+#kannst du ok blots denn en nieg Passwort kriegen, wenn du en E-Mailadress angeven hest.',
+'loginerror' => 'Fehler bi dat Anmellen',
+'noname' => 'Du muttst en Brukernaam angeven.',
+'loginsuccesstitle' => 'Anmellen hett Spood',
+'loginsuccess' => 'Du büst nu as „$1“ bi {{SITENAME}} anmellt.',
+'nosuchuser' => 'De Brukernaam „$1“ existeert nich.
+Prööv de Schrievwies oder mell di as niegen Bruker an.',
+'nosuchusershort' => 'De Brukernaam „$1“ existeert nich. Prööv de Schrievwies.',
+'wrongpassword' => 'Dat Password is falsch. Bitte versöök dat nochmal.',
+'mailmypassword' => 'En nieg Password sennen',
+'passwordremindertitle' => '{{SITENAME}} Password',
+'passwordremindertext' => 'Een (IP-Adress $1) hett üm en nieg Password för dat Anmellen bi {{SITENAME}} beed.
+Dat Password för Bruker „$2“ is nu „$3“. Bitte mell di nu an un änner dien Password.',
+'noemail' => 'Bruker „$1“ hett kene E-Mail-Adress angeven.',
+'passwordsent' => 'En nieg Password is an de E-Mail-Adress vun Bruker „$1“ send worrn. Mell di an, wenn du dat Password kriegt hest.',
+'mailerror' => 'Fehler bi dat Sennen vun de E-Mail: $1',
+'acct_creation_throttle_hit' => 'Du hest al $1 Brukerkontos anleggt. Du kannst nich noch mehr anleggen.',
+
+
+# Sieten ännern
+#
+'summary' => 'Tosamenfaten',
+'subject' => 'Bedrap',
+'minoredit' => 'Blots lütte Ännern.',
+'watchthis' => 'Op disse Siet oppassen',
+'savearticle' => 'Siet spiekern',
+'preview' => 'Vörschau',
+'showpreview' => 'Vörschau wiesen',
+'blockedtitle' => 'Bruker is blockt',
+'blockedtext' => 'Dien Brukernaam oder dien IP-Adress is vun $1 blockt worrn.
+As Grund is angeven:<br />$2<p>Wenn du över den Block spreken willst, kontakteer den Administrater.',
+'whitelistedittitle' => 'üm de Siet to Bearbeiden is dat neudig anmellt to ween',
+'whitelistedittext' => 'Du muttst di [[Special:Userlogin|hier anmellen]] üm Sieten bearbeiden to könen.',
+'whitelistreadtitle' => 'üm to Lesen is dat neudig anmellt to ween',
+'whitelistreadtext' => 'Du muttst di [[Special:Userlogin|hier anmellen]] üm Sieten lesen to könen.',
+'whitelistacctitle' => 'Du hest nich de Rechten en Konto antoleggen',
+'whitelistacctext' => 'Üm in dissen Wiki Kontos anleggen to könen muttst du di [[Special:Userlogin|hier anmellen]] un de neudigen Rechten hebben.',
+'loginreqtitle' => 'Anmellen neudig',
+'loginreqlink' => 'anmellen',
+'loginreqpagetext' => 'Du muttst di $1, üm annere Sieten ankieken to könen.',
+'accmailtitle' => 'Passwort is send worrn.',
+'accmailtext' => 'Dat Passwort vun $1 is an $2 send worrn.',
+'newarticle' => '(Nieg)',
+'newarticletext' => 'Hier den Text vun de niegen Siet indregen. Jümmer in ganze Sätz schrieven un kene Texten vun annern, de enen Oorheverrecht ünnerliggt, hierher kopeern.',
+'anontalkpagetext' => "---- ''Dit is de Diskuschoonssiet vun en nich anmellt Bruker. Wi mööt hier de numerische [[IP-Adress]]
+verwennen, üm den Bruker to identifizeern. So en Adress kann vun verscheden Brukern bruukt warrn. Wenn du en anonymen Bruker büst un meenst,
+dat disse Kommentaren nich an di richt sünd, denn [[Special:Userlogin|mell di doch an]], dormit dat Problem nich mehr besteiht.''",
+'noarticletext' => '(Disse Siet hett in\'n Momang kenen Text)',
+'usercsspreview' => "'''Denk doran, dat du blots en Vörschau vun dien CSS ankiekst, dat is noch nich spiekert!'''",
+'userjspreview' => "'''Denk doran, dat du blots en Vörschau vun dien JS ankiekst, dat is noch nich spiekert!'''",
+'clearyourcache' => "'''Denk doran:''' No den Spiekern muttst du dien Browser noch seggen, de niege Version to laden: '''Mozilla/Firefox:''' ''Strg-Shift-R'', '''IE:''' ''Strg-F5'', '''Safari:''' ''Cmd-Shift-R'', '''Konqueror:''' ''F5''.",
+'usercssjsyoucanpreview' => '<strong>Tipp:</strong> Bruuk den Vörschau-Knoop, üm dien nieg CSS/JS vör dat Spiekern to testen.',
+'updated' => '(Ännert)',
+'note' => '<strong>Henwies:</strong>',
+'previewnote' => 'Dit is blots en Vörschau, de Siet is noch nich spiekert!',
+'previewconflict' => 'Disse Vörschau wiest den Inholt vun dat Textfeld baven; so warrt de Siet utseihn, wenn du nu spiekerst.',
+'editing' => 'Ännern vun $1',
+'editinguser' => 'Ännern vun $1',
+'editingsection' => 'Ännern vun $1 (Afsatz)',
+'editingcomment' => 'Ännern vun $1 (Kommentar)',
+'editconflict' => 'Konflikt bi dat Bearbeiden: $1',
+'explainconflict' => 'En anner Bruker hett disse Siet ännert, no de Tied dat du anfungen hest, de Siet to bearbeiden.
+Dat Textfeld baven wiest de aktuelle Siet.
+Dat Textfeld nerrn wiest diene Ännern.
+Föög diene Ännern in dat Textfeld baven in.
+
+<b>Blots</b> de Text in dat Textfeld baven warrt spiekert, wenn du op Spiekern klickst!<br />',
+'yourtext' => 'Dien Text',
+'storedversion' => 'Spiekerte Version',
+'nonunicodebrowser' => '<strong>Wohrscho: Dien Browser ünnerstütt keen Unicode, wähl en annern Browser, wenn du en Siet ännern wullst.</strong>',
+'editingold' => '<strong>Wohrscho: Du bearbeidst en ole Version vun disse Siet.
+Wenn du spiekerst, warrn alle niegeren Versionen överschrieven.</strong>',
+'yourdiff' => 'Ünnerscheed',
+/*'copyrightwarning' => "<b><big>Kopeer kene Websieten</big>, de nich dien egen sünd un bruuk <big>kene Warken, de enen Oorheverrecht ünnerliggt,</big> ahn Verlööv vun de Copyright-Inhebbers!</b>
+<p>Du giffst hiermit dien Tosaag, dat du dien Text <strong>sülvst verfaat</strong> hest, dat de Text Gemeengood
+(<strong>„Public Domain“</strong>) is, oder dat de <strong>Copyright-Inhebber</strong> sien <strong>Tostimmen</strong> geven hett.
+Wenn dissen Text al an annere Steed apentlich maakt is, schriev dat ok op de Diskuschoonssiet, sünst kann dat passeern, dat en annern dat weer löscht,
+vun wegen dat he denkt, dat weer en Brook vun dat Oorheverrecht.
+
+<p><i>Denk doran, dat alle {{SITENAME}}-Bidreeg automatsch ünner de „GNU Fre'e Dokumentatschoonslizenz“ steiht.
+Wenn du nich wullst, dat dien Arbeid hier vun annern ännert un verbreed warrt, denn klick nich op Spiekern.</i></p>",*/
+'longpagewarning' => '<strong>Wohrscho: Disse Siet is $1 KB groot; en poor Browser köönt Probleme hebben, Sieten to bearbeiden, de grötter as 32 KB sünd.
+Bedenk of disse Siet vilicht in lüttere Afsnitten opdeelt warrn kann.</strong>',
+'readonlywarning' => '<strong>Wohrscho: De Datenbank is wiel dat Ännern vun de
+Siet för Pleegarbeiden sparrt worrn, so dat du de Siet en Stoot nich
+spiekern kannst. Seker di den Text un versöök later weer de Ännern to spiekern.</strong>',
+'protectedpagewarning' => '<strong>Wohrscho: Disse Siet is sparrt worrn, so dat blots
+Bruker mit Sysop-Rechten doran arbeiden könnt. Kiek ok bi de [[Project:Schulte Sieten|Regeln för schulte Sieten]].</strong>',
+'copyrightwarning2' => 'Dien Text, de du op {{SITENAME}} stellen wullst, könnt vun elkeen ännert oder wegmaakt warrn.
+Wenn du dat nich wullst, dröffst du dien Text hier nich apentlich maken.<br />
+
+Du bestätigst ok, dat du den Text sülvst schreven hest oder ut en „Public Domain“-Born oder en annere fre\'e Born kopeert hest (Kiek ok $1 för Details).
+<strong>Kopeer kene Warken, de enen Oorheverrecht ünnerliggt, ahn Verlööv vun de Copyright-Inhebbers!</strong>',
+
+# Sietenhistorie
+#
+'revhistory' => 'Fröhere Versionen',
+'nohistory' => 'Dor sünd kene fröheren Versionen vun disse Siet.',
+'revnotfound' => 'Kene fröheren Versionen funnen',
+'revnotfoundtext' => 'De Version vun disse Siet, no de du söökst, kunn nich funnen warrn. Prööv de URL vun disse Siet.',
+'loadhist' => 'Lade List mit freuhere Versionen',
+'currentrev' => 'Aktuelle Version',
+'revisionasof' => 'Version vun\'n $1',
+'nextrevision' => '←Nächstjüngere Version',
+'previousrevision' => 'Nächstöllere Version→',
+'cur' => 'Aktuell',
+'next' => 'Tokamen',
+'last' => 'Letzte',
+'orig' => 'Original',
+'histlegend' => 'Ünnerscheed-Utwahl: De Boxen vun de wünschten
+Versionen markeern un \'Enter\' drücken oder den Knoop nerrn klicken/alt-v.<br />
+Legende:
+(Aktuell) = Ünnerscheed to de aktuelle Version,
+(Letzte) = Ünnerscheed to de vörige Version,
+L = Lütte Ännern',
+
+# Ünnerscheed
+#
+'difference' => '(Ünnerscheed twüschen Versionen)',
+'loadingrev' => 'laad Versionen üm Ünnerscheden to wiesen',
+'lineno' => 'Lien $1:',
+'editcurrent' => 'De aktuelle Version vun disse Siet bearbeiden',
+'selectnewerversionfordiff' => 'En niegere Version för en Vergliek utwählen',
+'selectolderversionfordiff' => 'En öllere Version för en Vergliek utwählen',
+'compareselectedversions' => 'Wählte Versionen verglieken',
+
+# Söök
+#
+'searchresults' => 'Söökresultaten',
+'searchresulttext' => 'För mehr Informatschonen över {{SITENAME}}, kiek [[{{ns:4}}:Söök|{{SITENAME}} dörsöken]].',
+'searchsubtitle' => 'För de Söökanfraag „[[:$1]]“',
+'searchsubtitleinvalid' => 'För de Söökanfraag „$1“',
+'badquery' => 'Falsche Söökanfraag',
+'badquerytext' => 'De Söökanfraag kunn nich verarbeid warrn.
+Sachts hest du versöökt, en Word to söken, dat kötter as twee Bookstaven is.
+Dit funktschoneert in\'n Momang noch nich.
+Mööglicherwies hest du ok de Anfraag falsch formuleert, to\'n Bispeel \'Lohn un un Stüern\'. Versöök en anners formuleerte Anfraag.',
+'matchtotals' => 'De Anfraag „$1“ stimmt mit $2 Sietenöverschriften un den Text vun $3 Sieten överein.',
+'noexactmatch' => 'Dor existeert kene Siet mit dissen Naam. Versöök de Vulltextsöök oder legg de Siet [[:$1|nieg]] an.',
+'titlematches' => 'Övereenstimmen mit Överschriften',
+'notitlematches' => 'Kene Övereenstimmen',
+'textmatches' => 'Övereenstimmen mit Texten',
+'notextmatches' => 'Kene Övereenstimmen',
+'prevn' => 'vörige $1',
+'nextn' => 'tokamen $1',
+'viewprevnext' => 'Wies ($1) ($2) ($3).',
+'showingresults' => 'Hier sünd <b>$1</b> Resultaten, anfungen mit #<b>$2</b>.',
+'showingresultsnum' => 'Hier sünd <b>$3</b> Resultaten, anfungen mit #<b>$2</b>.',
+'nonefound' => '<strong>Henwies</strong>:
+Söökanfragen ahn Spood hebbt faken de Oorsaak, dat no kotte oder gemeene Wöör söökt warrt, de nich indizeert sünd.',
+'powersearch' => 'Söök',
+'powersearchtext' => '
+Söök in Naamrüüm:<br />
+
+
+$1<br />
+$2 Wies ok Wiederleiden Söök no $3 $9',
+'searchdisabled' => '<p>De Vulltextsöök is wegen Överlast en Stoot deaktiveert. In disse Tied kannst du disse Google-Söök verwennen,
+de aver nich jümmer den aktuellsten Stand weerspegelt.<p>',
+'blanknamespace' => '(Hööft-)',
+
+# Instellen
+#
+'preferences' => 'Instellen',
+'prefsnologin' => 'Nich anmellt',
+'prefsnologintext' => 'Du muttst [[Special:Userlogin|anmellt]] ween, üm dien Instellen to ännern.',
+'prefsreset' => 'Instellen sünd op Standard trüchsett.',
+'qbsettings' => 'Sietenliest',
+'changepassword' => 'Password ännern',
+'skin' => 'Utsehn vun de Steed',
+'math' => 'TeX',
+'dateformat' => 'Datumsformat',
+'math_failure' => 'Parser-Fehler',
+'math_unknown_error' => 'Unbekannten Fehler',
+'math_unknown_function' => 'Unbekannte Funktschoon',
+'math_lexing_error' => '\'Lexing\'-Fehler',
+'math_syntax_error' => 'Syntaxfehler',
+'saveprefs' => 'Instellen spiekern',
+'resetprefs' => 'Instellen trüchsetten',
+'oldpassword' => 'Ool Password',
+'newpassword' => 'Nieg Password',
+'retypenew' => 'Nieg Password (nochmal)',
+'textboxsize' => 'Textfeld-Grött',
+'rows' => 'Regen',
+'columns' => 'Spalten',
+'searchresultshead' => 'Söökresultaten',
+'resultsperpage' => 'Treffer pro Siet',
+'contextlines' => 'Lienen pro Treffer',
+'contextchars' => 'Teken pro Lien',
+'stubthreshold' => 'Kotte Sieten markeeren bet',
+'recentchangescount' => 'Antall „Letzte Ännern“',
+'savedprefs' => 'Dien Instellen sünd spiekert.',
+'timezonelegend' => 'Tiedrebeet',
+'timezonetext' => 'Giff de Antall vun de Stünnen an, de twüschen dien Tiedrebeet un UTC liggen.',
+'localtime' => 'Oortstied',
+'timezoneoffset' => 'Ünnerscheed',
+'servertime' => 'Aktuelle Tied op den Server',
+'guesstimezone' => 'Ut den Browser övernehmen',
+'defaultns' => 'In disse Naamrüüm schall standardmatig söökt warrn:',
+
+# letzte Ännern
+#
+'changes' => 'Ännern',
+'recentchanges' => 'Letzte Ännern',
+'recentchangestext' => '
+Disse Siet warrt wiel dat Laden automatsch aktualiseert. Wiest warrn Sieten, de toletzt bearbeid worrn sünd, dorto de Tied un de Naam vun de Autor.',
+'rcnote' => 'Hier sünd de letzten <b>$1</b> Ännern vun de letzten <b>$2</b> Daag. (<b>N</b> - Niege Sieten; <b>L</b> - Lütte Ännern)',
+'rcnotefrom' => 'Dit sünd de Ännern siet <b>$2</b> (bet to <b>$1</b> wiest).',
+'rclistfrom' => 'Wies niege Ännern siet $1',
+'rclinks' => 'Wies de letzten $1 Ännern; wies de letzten $2 Daag.',
+'diff' => 'Ünnerscheed',
+'hist' => 'Versionen',
+'hide' => 'Nich wiesen',
+'show' => 'Wiesen',
+'minoreditletter' => 'L',
+'newpageletter' => 'N',
+
+
+# Upload
+#
+'upload' => 'Hoochladen',
+'uploadbtn' => 'Datei hoochladen',
+'reupload' => 'Nieg hoochladen',
+'reuploaddesc' => 'Trüch to de Hoochladen-Siet.',
+'uploadnologin' => 'Nich anmellt',
+'uploadnologintext' => 'Du muttst [[Spezial:Userlogin|anmellt ween]] üm Datein hoochladen to könen.',
+'uploaderror' => 'Fehler bi dat Hoochladen',
+'uploadtext' => "
+Üm hoochladene Biller to söken un antokieken,
+geih to de [[Special:Imagelist|List vun hoochladene Biller]].
+
+Bruuk dat Formular, üm niege Biller hoochtoladen un disse in Sieten to bruken.
+In de mehrsten Browser warrt en „Durchsuchen“-Feld wiest, dat en Standard-Dateidialog apent.
+Wähl de Datei ut, de du hoochladen wullst. De Dateinaam warrt denn in dat Textfeld wiest.
+Bestätig dann den Copyright-Henwies.
+Toletzt muttst du den „Hoochladen“-Knopp klicken.
+Dat kann en Stoot duern, sünnerlich bi en langsamen Internet-Verbinnen.
+
+För Fotos is dat JPEG-Format, för Grafiken un Symbolen dat PNG-Format best.
+Üm en Bild in en Siet to bruken, schriev an Stell vun dat Bild
+'''[[Bild:datei.jpg]]''' oder
+'''[[Bild:datei.jpg|Beschrieven]]'''.
+
+Denk doran, dat, lieks as bi de annern Sieten, annere Bruker dien Datein löschen oder ännern könen.',
+'uploadlog' => 'Datei-Logbook',
+'uploadlogpage' => 'Datei-Logbook',
+'uploadlogpagetext' => 'Hier is de List vun de letzten hoochladenen Datein.
+Alle Tieden sünd UTC.
+
+<ul>
+
+</ul>",
+'filename' => 'Dateinaam',
+'filedesc' => 'Beschrieven',
+'filestatus' => 'Copyright-Status',
+'filesource' => 'Born',
+'copyrightpage' => '{{ns:4}}:Copyright',
+'copyrightpagename' => '{{SITENAME}} Copyright',
+'uploadedfiles' => 'Hoochladene Datein',
+'minlength' => 'Bilddatein möten tominnst dree Bookstaven hebben.',
+'badfilename' => 'De Bildnaam is in „$1“ ännert worrn.',
+'badfiletype' => '„.$1“ is keen anratenswert Dateiformat.',
+'largefile' => 'Kene Biller över 100 KByte hoochladen.',
+'emptyfile' => 'De hoochladene Datei is leddig. De Grund kann en Tippfehler in de Dateinaam ween. Kontrolleer, of du de Datei redig hoochladen wullst.',
+'fileexists' => 'En Datei mit dissen Naam existeert al, prööv $1, wenn du di nich seker büst of du dat ännern wullst.',
+'successfulupload' => 'Datei hoochladen hett Spood',
+'fileuploaded' => 'Dat Hoochladen vun de Datei „$1“ hett Spood.
+Disse ($2) Link föhrt to de Bildsiet. Dor kann indregen warrn, woneem dat Bild kummt, welkeen dat wann mookt hett un wenn neudig, welkeen Copyright-Status dat Bild hett.',
+'uploadwarning' => 'Wohrscho',
+'savefile' => 'Datei spiekern',
+'uploadedimage' => '„$1“ hoochladen',
+'uploadcorrupt' => 'De Datei is korrupt oder hett en falsch Ennen. Datei pröven un nieg hoochladen.',
+'filemissing' => 'Datei fehlt',
+
+# Billerlist
+#
+'imagelist' => 'Billerlist',
+'imagelisttext' => 'Hier is en List vun $1 Biller, sorteert $2.',
+'getimagelist' => 'Billerlist laden',
+'ilsubmit' => 'Söök',
+'showlast' => 'Wies de letzten $1 Biller, sorteert $2.',
+'byname' => 'no Naam',
+'bydate' => 'no Datum',
+'bysize' => 'no Grött',
+'imgdelete' => 'Löschen',
+'imgdesc' => 'Beschrieven',
+'imglegend' => 'Legende: (Beschrieven) = Wies/Änner Bildbeschrieven.',
+'imghistory' => 'Bild-Versionen',
+'revertimg' => 'trüchsetten',
+'deleteimg' => 'Löschen',
+'deleteimgcompletely' => 'Löschen',
+'imghistlegend' => 'Legende: (cur) = Dit is dat aktuelle Bild, (Löschen) = lösch
+disse ole Version, (Trüchsetten) = bruuk weer disse ole Version.',
+'imagelinks' => 'Bildverwiesen',
+'linkstoimage' => 'Disse Sieten bruukt dat Bild:',
+'nolinkstoimage' => 'Kene Siet bruukt dat Bild.',
+'sharedupload' => 'Disse Datei is en Datei, de mööglicherwies ok vun annere Wikis bruukt warrt.',
+
+
+# Statistik
+#
+'statistics' => 'Statistik',
+'sitestats' => 'Sietenstatistik',
+'userstats' => 'Brukerstatistik',
+'sitestatstext' => 'Dat gifft allens tosamen <b>$1</b> Sieten in de Datenbank.
+Dat slött Diskuschoonsieten, Sieten över {{SITENAME}}, extrem kotte Artikels, Wiederleiden un annere Sieten in, de nich as Artikel gelten köönt.
+Disse utnommen, gifft dat <b>$2</b> Sieten, de as Artikel gelten könen.<p>
+
+
+De Lüüd hebbt <b>$3</b>× Sieten oprufen, un <b>$4</b>× Sieten ännert.
+Dorut ergeven sik <b>$5</b> Ännern pro Siet, un <b>$6</b> Ankieken pro Ännern.',
+'userstatstext' => 'Dat gifft <b>$1</b> registreert Bruker.
+Dorvun hebbt <b>$2</b> Administrater-Rechten (kiek $3).',
+
+# Maintenance Page
+#
+'disambiguations' => 'Begreepklorensieten',
+'disambiguationspage' => '{{ns:4}}:Begreepkloren',
+'disambiguationstext' => 'Disse Sieten wiest no en <i>Begreepklorensiet</i>. Se schallen staats dat no de Siet wiesen, de egentlich meent is.<br />En Siet warrt as Begreepklorensiet ansehn, wenn $1 op se verwiest.<br />Verwiesen ut Naamrüüm sünd hier <i>nich</i> oplist.',
+'doubleredirects' => 'Dubbelte Wiederleiden',
+'doubleredirectstext' => '<b>Wohrscho:</b> Disse List kann „falsche Positive“ bargen.
+Dat passeert denn, wenn en Wiederleiden blangen de Wiederleiden-Verwies noch mehr Text mit annere Verwiesen hett.
+De schallen denn löscht warrn. Elk Reeg wiest de eerste un tweete Wiederleiden un de eerste Reeg Text ut de Siet,
+to den vun den tweeten Wiederleiden wiest warrt, un to den de eerste Wiederleiden mehrst wiesen schall.',
+'brokenredirects' => 'Kaputte Wiederleiden',
+'brokenredirectstext' => 'Disse Wiederleiden wiesen to en Siet, de nich existeert',
+
+
+# Verscheden Spezialsieten
+#
+'lonelypages' => 'Weetsieten',
+'uncategorizedpages' => 'Unkategoriseerte Sieten',
+'uncategorizedcategories' => 'Unkategoriseerte Kategorien',
+'unusedimages' => 'Weetbiller',
+'popularpages' => 'Faken opropene Sieten',
+'nviews' => '$1 Affragen',
+'wantedpages' => 'Wünschte Sieten',
+'nlinks' => '$1 Verwies',
+'allpages' => 'Alle Sieten',
+'randompage' => 'Tofällige Siet',
+'shortpages' => 'Kotte Sieten',
+'longpages' => 'Lange Sieten',
+'listusers' => 'Brukerlist',
+'specialpages' => 'Spezialsieten',
+'spheading' => 'Spezialsieten för alle Bruker',
+'recentchangeslinked' => 'Verlinkte Sieten',
+'rclsub' => '(op Artikel vun „$1“)',
+'newpages' => 'Niege Sieten',
+'ancientpages' => 'Öllste Sieten',
+'move' => 'Schuven',
+'movethispage' => 'Siet schuven',
+'unusedimagestext' => 'Denk doran, dat annere Wikis mööglicherwies en poor vun disse Biller bruken.',
+'booksources' => 'Bookhannel',
+'categoriespagetext' => 'Disse Kategorien existeern in dissen Wiki',
+'data' => 'Daten',
+'booksourcetext' => 'Dit is en List mit Links to Internetsieten, de niege un bruukte Böker verkööpt.
+Dor kann dat ok mehr Informatschonen över de Böker geven, de di interesseert.
+{{SITENAME}} is mit kenen vun disse Höker warflich verbunnen.',
+'alphaindexline' => '$1 bet $2',
+'log' => 'Logböker',
+'alllogstext' => 'Kombineerte Ansicht vun Hoochlaad-, Lösch-, Schuul-, Block- un Sysop-Logböker.
+Du kannst de List kötter maken, wenn du den Logtyp, den Brukernaam oder de de Siet angiffst.',
+
+
+# E-Mail an'n Bruker
+#
+'mailnologin' => 'Du büst nich anmellt.',
+'mailnologintext' => 'Du muttst [[Spezial:Userlogin|anmellt ween]] un en güllige E-Mail-Adress hebben, dormit du en annern Bruker en E-Mail sennen kannst.',
+'emailuser' => 'E-Mail an dissen Bruker',
+'emailpage' => 'E-Mail an Bruker',
+'emailpagetext' => 'Wenn disse Bruker en güllige E-Mail-Adress angeven hett, kannst du em mit den nerrn stahn Formular en E-Mail sennen. As Afsenner warrt de E-Mail-Adress ut dien Instellen indregen, dormit de Bruker di antern kann.',
+'usermailererror' => 'Dat Mail-Objekt hett en Fehler trüchgeven:',
+'defemailsubject' => '{{SITENAME}} E-Mail',
+'noemailtitle' => 'Kene E-Mail-Adress',
+'noemailtext' => 'Disse Bruker hett kene güllige E-Mail-Adress angeven, oder will kene E-Mail vun annere Bruker sennt kriegen.',
+'emailfrom' => 'Vun',
+'emailto' => 'An',
+'emailsubject' => 'Bedrap',
+'emailmessage' => 'Noricht',
+'emailsend' => 'Sennen',
+'emailsent' => 'E-Mail afsennt',
+'emailsenttext' => 'Dien E-Mail is afsennt worrn.',
+
+# Special:Allpages
+'nextpage' => 'tokamen Siet ($1)',
+'allarticles' => 'Alle Artikels',
+'allpagesprev' => 'vörig',
+'allpagesnext' => 'tokamen',
+'allinnamespace' => 'Alle Sieten ($1 Naamruum)',
+'allpagessubmit' => 'Los',
+
+# Oppasslist
+#
+'watchlist' => 'Oppasslist',
+'nowatchlist' => 'Du hest kene Indreeg op dien Oppasslist.',
+'watchnologin' => 'Du büst nich anmellt',
+'watchnologintext' => 'Du muttst [[Spezial:Userlogin|anmellt]] ween, wenn du dien Oppasslist ännern willst.',
+'addedwatch' => 'To de Oppasslist hentofögt',
+'addedwatchtext' => 'De Siet „$1“ is to dien <a href=\'{{localurle:Spezial:Watchlist}}\'>Oppasslist</a> hentofögt worrn.
+Ännern, de in Tokumst an disse Siet un an de toheurige Diskuschoonssiet mookt warrn, sünd dorop list un de Siet is op de
+<a href=\'{{localurle:Spezial:Recentchanges}}\'>List vun de letzten Ännern</a> fett markeert. Wenn du de Siet nich mehr op dien Oppasslist
+hebben wullst, klick op „Nich mehr oppassen“ in de Linklist.',
+'removedwatch' => 'De Siet is nich mehr op de Oppasslist',
+'removedwatchtext' => 'De Siet „$1“ is nich mehr op de Oppasslist.',
+'watchthispage' => 'Op Siet oppassen',
+'unwatchthispage' => 'Nich mehr oppassen',
+'notanarticle' => 'Keen Artikel',
+'watchnochange' => 'Kene Siet, op de du oppasst, is in den wiesten Tiedruum bearbeid worrn.',
+'watchdetails' => '($1 Sieten sünd op de Oppasslist (ahn Diskuschoonssieten);
+$2 Sieten werrn in de instellte Tied bearbeid;
+$3... [$4 komplette List wiesen un bearbeiden].)',
+'watchmethod-recent' => 'letzte Ännern no Oppasslist pröven',
+'watchmethod-list' => 'Oppasslist no letzte Ännern pröven',
+'removechecked' => 'Markeerte Indreeg löschen',
+'watchlistcontains' => 'Dien Oppasslist bargt $1 Sieten.',
+'watcheditlist' => 'Hier is ene alphabetsche List vun de Sieten op de du oppasst. Markeer de Sieten, de vun de Oppasslist löscht warrn schallt un klick den \'markeerte Indreeg löschen\'-Knoop.',
+'removingchecked' => 'Indreeg warrt vun de Oppasslist löscht...',
+'couldntremove' => 'De Indrag \'$1\' kann nich löscht warrn...',
+'iteminvalidname' => 'Problem mit den Indrag \'$1\', ungülligen Naam...',
+'wlnote' => 'Nerrn steiht de letzten Ännern vun de letzten <b>$2</b> Stünnen.',
+'wlshowlast' => 'Wies de letzten $1 Stünnen $2 Daag $3',
+'wlsaved' => 'Dit is en spiekerte Version vun dien Oppasslist.',
+
+# löschen/schulen/trüchsetten
+#
+'deletepage' => 'Siet löschen',
+'confirm' => 'Bestätigen',
+'excontent' => "Olen Inholt: '$1'",
+'exbeforeblank' => "Inholt vör dat Leddigmaken vun de Siet: '$1'",
+'exblank' => 'Siet weer leddig',
+'confirmdelete' => 'Löschen bestätigen',
+'deletesub' => '(Lösche „$1“)',
+'historywarning' => 'Wohrscho: De Siet, de du versöökst to löschen, hett en Versionshistorie:',
+'confirmdeletetext' => 'Du büst dorbi, en Siet oder en Bild un alle ölleren Versionen duersam ut de Datenbank to löschen.
+Segg to, dat du över de Folgen Bescheed weetst un dat du in Övereenstimmen mit uns [[{{ns:4}}:Leidlienen|Leidlienen]] hannelst.',
+'actioncomplete' => 'Aktschoon beennt',
+'deletedtext' => '„$1“ is löscht.
+In $2 kannst du en List vun de letzten Löschen finnen.',
+'deletedarticle' => '„$1“ löscht',
+'dellogpage' => 'Lösch-Logbook',
+'dellogpagetext' => 'Hier is en List vun de letzten Löschen (UTC).
+
+<ul>
+
+</ul>',
+'deletionlog' => 'Lösch-Logbook',
+'reverted' => 'Op en ole Version trüchsett',
+'deletecomment' => 'Grund vun de Löschen',
+'imagereverted' => 'Op en ole Version trüchsett.',
+'rollback' => 'Trüchnahm vun de Ännern',
+'rollback_short' => 'Trüchnehmen',
+'rollbacklink' => 'Trüchnehmen',
+'rollbackfailed' => 'Trüchnahm hett kenen Spood',
+'cantrollback' => 'De Ännern kann nich trüchnahmen warrn; de letzte Autor is de eenzige.',
+'alreadyrolled' => 'Dat Trüchnehmen vun de Ännern an de Siet [[:$1]] vun [[User:$2|$2]]
+([[User_talk:$2|Diskuschoonssiet]]) is nich mööglich, vun wegen dat dor en annere Ännern oder Trüchnahm ween is.
+
+De letzte Ännern is vun [[User:$3|$3]]
+([[User talk:$3|Diskuschoon]])',
+# blots wiesen wenn dor en Ännerkommentar is
+'editcomment' => 'De Ännerkommentar weer: <i>$1</i>.',
+'revertpage' => 'Weerholt to de letzte Ännern vun $1',
+
+# Weerholen
+'undelete' => 'Löschte Siet weerholen',
+'undeletepage' => 'Löschte Sieten weerholen',
+'undeletepagetext' => 'Disse Sieten sünd löscht worrn, aver jümmer noch
+spiekert un könnt weerholt warrn.',
+'undeletearticle' => 'Löschte Siet weerholen',
+'undeleterevisions' => '$1 Versionen archiveert',
+'undeletehistory' => 'Wenn du disse Siet weerholst, warrt ok alle olen Versionen weerholt. Wenn siet dat Löschen en nieg Siet mit lieken
+Naam schreven worrn is, warrt de weerholten Versionen as ole Versionen vun disse Siet wiest.',
+'undeleterevision' => 'Löschte Version vun de $1',
+'undeletebtn' => 'Weerholen!',
+'undeletedarticle' => '„$1“ weerholt',
+
+# Bidreeg
+#
+'contributions' => 'Brukerbidreeg',
+'mycontris' => 'Mien Bidreeg',
+'contribsub' => 'För $1',
+'nocontribs' => 'Kene Ännern för disse Kriterien funnen.',
+'ucnote' => 'Dit sünd de letzten <b>$1</b> Bidreeg vun de Bruker in de letzten <b>$2</b> Doog.',
+'uclinks' => 'Wies de letzten $1 Bidreeg; wies de letzten $2 Daag.',
+'uctop' => ' (aktuell)',
+'newbies' => 'Niegling',
+
+# Wat wiest hier hen
+#
+'whatlinkshere' => 'Wat wiest hierher',
+'notargettitle' => 'Kene Siet angeven',
+'notargettext' => 'Du hest nich angeven, op welke Siet du disse Funktschoon anwennen willst.',
+'linklistsub' => '(List vun de Verwiesen)',
+'linkshere' => 'Disse Sieten wiesen hierher:',
+'nolinkshere' => 'Kene Siet wiest hierher.',
+'isredirect' => 'Wiederleiden',
+
+# Blocken/nich mehr blocken vun IPs
+#
+'blockip' => 'IP-Adress blocken',
+'blockiptext' => 'Bruuk dat Formular, üm en IP-Adress to blocken.
+Dit schall blots maakt warrn, üm Vandalismus to vermasseln, aver jümmer in Övereenstimmen mit uns [[{{ns:4}}:Leidlienen|Leidlienen]].
+Ok den Grund för dat Blocken indregen.',
+'ipaddress' => 'IP-Adress',
+'ipbreason' => 'Grund',
+'ipbsubmit' => 'Adress blocken',
+'badipaddress' => 'De IP-Adress hett en falsch Format.',
+'blockipsuccesssub' => 'Blocken hett Spood',
+'blockipsuccesstext' => 'De IP-Adress „$1“ is nu blockt.
+
+<br />Op de [[Special:Ipblocklist|IP-Blocklist]] is en List vun alle Blocks to finnen.',
+'unblockip' => 'IP-Adress freegeven',
+'unblockiptext' => 'Bruuk dat Formular, üm en blockte IP-Adress freetogeven.',
+'ipusubmit' => 'Disse Adress freegeven',
+'ipblocklist' => 'List vun blockte IP-Adressen',
+'blocklistline' => '$1, $2 hett $3 blockt ($4)',
+'blocklink' => 'blocken',
+'unblocklink' => 'freegeven',
+'contribslink' => 'Bidreeg',
+'autoblocker' => 'Automatisch Block, vun wegen dat du en IP-Adress bruukst mit „$1“. Grund: „$2“.',
+
+# Entwickler-Warktüüch
+#
+'lockdb' => 'Datenbank sparren',
+'unlockdb' => 'Datenbank freegeven',
+'lockdbtext' => 'Mit de Sparr vun de Datenbank warrt alle Ännern an de Brukerinstellen, Oppasslisten, Sieten un so wieder verhinnert.
+Schall de Datenbank redig sparrt warrn?',
+'unlockdbtext' => 'Dat Beennen vun de Datenbank-Sparr maakt alle Ännern weer mööglich.
+Schall de Datenbank-Sparr redig beennt warrn?',
+'lockconfirm' => 'Ja, ik will de Datenbank sparren.',
+'unlockconfirm' => 'Ja, ik will de Datenbank freegeven.',
+'lockbtn' => 'Datenbank sparren',
+'unlockbtn' => 'Datenbank freegeven',
+'locknoconfirm' => 'Du hest dat Bestätigungsfeld nich markeert.',
+'lockdbsuccesssub' => 'Datenbanksparr hett Spood',
+'unlockdbsuccesssub' => 'Datenbankfreegaav hett Spood',
+'lockdbsuccesstext' => 'De {{SITENAME}}-Datenbank is sparrt.
+<br />Du muttst de Datenbank weer freegeven, wenn de Pleegarbeiden beennt sünd.',
+'unlockdbsuccesstext' => 'De {{SITENAME}}-Datenbank is weer freegeven.',
+
+# Siet schuven
+#
+'movepage' => 'Siet schuven',
+'movepagetext' => 'Mit dissen Formular kannst du en Siet ümnömen, tosamen mit allen Versionen. De ole Titel warrt to den niegen wiederleid. Verwies op den olen Titel warrn nich ännert un de Diskuschoonssiet warrt ok nich mitschuven.',
+'movepagetalktext' => "De tohören Diskuschoonssiet warrt, wenn een dor is, mitschuuvt, '''mit disse Utnahmen:''
+* Du schuuvst de Siet in en annern Naamruum oder
+* dat existeert al en Diskuschoonssiet mit dissen Naam, oder
+* du wählst de nerrn stahn Optschoon af
+
+In disse Fäll muttst du de Siet, wenn du dat wullst, vun Hand schuven.",
+'movearticle' => 'Siet schuven',
+'movenologin' => 'Du büst nich anmellt',
+'movenologintext' => 'Du muttst en registreert Bruker un
+[[Special:Userlogin|anmellt]] ween,
+üm en Siet to schuven.',
+'newtitle' => 'To niegen Titel',
+'movepagebtn' => 'Siet schuven',
+'pagemovedsub' => 'Schuven hett Spood',
+'pagemovedtext' => 'Siet „[[$1]]“ no „[[$2]]“ schuuvt.',
+'articleexists' => 'Ünner dissen Naam existeert al en Siet.
+Bitte wähl en annern Naam.',
+'talkexists' => 'Dat Schuven vun de Siet sülvst hett Spood, aver dat Schuven vun de
+Diskuschoonssiet nich, vun wegen dat dor al en Siet mit dissen Titel existeert. De Inholt muss vun Hand anpasst warrn.',
+'movedto' => 'schuven no',
+'1movedto2_redir' => '$1 schuven no $2 över Wiederleiden',
+'movetalk' => 'De Diskuschoonssiet ok schuven, wenn mööglich.',
+'talkpagemoved' => 'De Diskuschoonssiet is ok schuven worrn.',
+'talkpagenotmoved' => 'De Diskuschoonssiet is <strong>nich</strong> schuven worrn.',
+
+'export' => 'Sieten exporteern',
+'exporttext' => 'Du kannst de Text un de Bearbeidenshistorie vun een oder mehr Sieten no XML exporteern. Dat Resultat kann in en annern Wiki mit Mediawiki-Software inspeelt warrn, bearbeid oder archiveert warrn.',
+'exportcuronly' => 'Blots de aktuelle Version vun de Siet exporteern',
+'missingimage' => '<b>Bild fehlt</b><br /><i>$1</i>',
+
+#Tooltips:
+'tooltip-watch' => 'Op disse Siet oppassen. [alt-w]',
+'tooltip-search' => 'Söken [alt-f]',
+'tooltip-minoredit' => 'Disse Ännern as lütt markeern. [alt-i]',
+'tooltip-save' => 'Ännern spiekern [alt-s]',
+'tooltip-preview' => 'Vörschau vun de Ännern an disse Siet. Bruuk dat vör dat Spiekern. [alt-p]',
+'tooltip-compareselectedversions' => 'Ünnerscheed twüschen twee utwählte Versionen vun disse Siet verglieken. [alt-v]',
+
+#Tastatur-Shortcuts
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-compareselectedversions' => 'v',
+
+'makesysoptitle' => 'Maak en Bruker to en Administrater',
+'makesysoptext' => 'Disse Mask warrt vun Bürokraten bruukt, üm normale Bruker to Administratern to maken.',
+'makesysopname' => 'Naam vun de Bruker:',
+'makesysopsubmit' => 'Maak dissen Bruker to en Administrater',
+'makesysopok' => '<b>Bruker „$1“ is nu en Administrater.</b>',
+'makesysopfail' => '<b>Bruker „$1“ kunn nich to en Administrater maakt warrn. (Is de Naam richtig schreven?)</b>',
+'makesysop' => 'Maak en Bruker to en Administrater',
+'setbureaucratflag' => 'Bürokraten-Flagg setten',
+'rights' => 'Rechten:',
+'set_user_rights' => 'Brukerrechten setten',
+'user_rights_set' => '<b>Brukerrechten för „$1“ aktualiseert</b>',
+'set_rights_fail' => '<b>Brukerrechten för „$1“ kunnen nich sett warrn. (Is de Naam richtig schreven?)</b>',
+'1movedto2' => '$1 is no $2 schuven worrn',
+'allmessages' => 'Alle MediaWiki-Norichten',
+'allmessagestext' => 'Dit is en List vun alle mööglichen Norichten in den MediaWiki-Naamruum.',
+'thumbnail-more' => 'vergröttern',
+'and' => 'un',
+'uploaddisabled' => 'Dat Hoochladen is deaktiveert.',
+'deadendpages' => 'Sackstraatsieten',
+'intl' => 'Interwiki-Links',
+'version' => 'Version',
+'protectlogpage' => 'Sietenschuul-Logbook',
+'protectlogtext' => 'Dit is en List vun de blockten Sieten. Kiek [[{{ns:4}}:Schulte Sieten]] för mehr Informatschonen.',
+'protectedarticle' => 'Siet $1 schuult',
+'unprotectedarticle' => 'Siet $1 freegeven',
+'protectsub' =>'(Sparren vun „$1“)',
+'confirmprotecttext' => 'Schall disse Siet redig schuult warrn?',
+'ipbexpiry' => 'Aflöptied',
+'blocklogpage' => 'Brukerblock-Logbook',
+'blocklogentry' => 'block [[User:$1]] - ([[Special:Contributions/$1|Bidreeg]]) för en Tiedruum vun: $2',
+'blocklogtext' => 'Dit is en Logbook över Blocks un Freegaven vun Brukern. Automatisch blockte IP-Adressen sünd nich opföhrt.
+Kiek [[Special:Ipblocklist|IP-Blocklist]] för en List vun den blockten Brukern.',
+'unblocklogentry' => 'Block vun [[User:$1]] ophoven',
+'range_block_disabled' => 'De Mööglichkeit, ganze Adressrüüm to sparren, is nich aktiveert.',
+'ipb_expiry_invalid' => 'De angeven Aflöptied is ungüllig.',
+'ip_range_invalid' => 'Ungüllig IP-Addressrebeet.',
+'confirmprotect' => 'Sparr bestätigen',
+'protectcomment' => 'Grund för de Sparr',
+'unprotectsub' => '(Beennen vun de Sparr vun „$1“)',
+'confirmunprotecttext' => 'Schall de Sparr vun disse Siet redig beennt warrn?',
+'confirmunprotect' => 'De Sparr beennen',
+'unprotectcomment' => 'Grund för dat Beennen vun de Sparr',
+'proxyblocker' => 'Proxyblocker',
+'proxyblockreason' => 'Dien IP-Adress is blockt, vun wegen dat se en apenen Proxy is.
+Kontakteer dien Provider oder diene Systemtechnik un informeer se över dat möögliche Sekerheitsproblem.',
+'proxyblocksuccess' => 'Fardig.',
+'math_image_error' => 'dat Konverteern no PNG hett kenen Spood.',
+'math_bad_tmpdir' => 'Kann dat Temporärverteken för mathematsche Formeln nich anleggen oder beschrieven.',
+'math_bad_output' => 'Kann dat Teelverteken för mathematsche Formeln nich anleggen oder beschrieven.',
+'math_notexvc' => 'Dat texvc-Programm kann nich funnen warrn. Kiek ok math/README.',
+'prefs-personal' => 'Brukerdaten',
+'prefs-rc' => 'Letzte Ännern un Wiesen vun kotte Sieten',
+'prefs-misc' => 'Verscheden Instellen',
+'import' => 'Sieten importeern',
+'importtext' => 'Exporteer de Siet vun dat Utgangswiki mit Special:Export un laad de Datei denn över disse Siet weer hooch.',
+'importfailed' => 'Import hett kenen Spood: $1',
+'importnotext' => 'Leddig oder keen Text',
+'importsuccess' => 'Import hett Spood!',
+'importhistoryconflict' => 'Dor sünd al öllere Versionen, de mit dissen kollideert. (Mööglicherwies is de Siet al vörher importeert worrn)',
+'isbn' => 'ISBN',
+'siteuser' => '{{SITENAME}}-Bruker $1',
+'siteusers' => '{{SITENAME}}-Bruker $1',
+'watch' => 'Oppassen',
+'unwatch' => 'nich mehr oppassen',
+'edit' => 'ännern',
+'talk' => 'Diskuschoon',
+'nocookiesnew' => 'De Brukertogang is anleggt, aver du büst nich inloggt. {{SITENAME}} bruukt för disse Funktschoon Cookies, aktiveer de Cookies un logg di denn mit dien nieg Brukernaam un den Password in.',
+'nocookieslogin' => '{{SITENAME}} bruukt Cookies för dat Inloggen vun de Bruker. Du hest Cookies deaktiveert, aktiveer de Cookies un versöök dat noch eenmal.',
+'subcategorycount' => 'Disse Kategorie hett $1 Ünnerkategorien.',
+'categoryarticlecount' => 'To disse Kategorie höört $1 Sieten.',
+
+# Math
+'mw_math_png' => 'Jümmer as PNG dorstellen',
+'mw_math_simple' => 'Eenfach TeX as HTML dorstellen, sünst PNG',
+'mw_math_html' => 'Wenn mööglich as HTML dorstellen, sünst PNG',
+'mw_math_source' =>'As TeX laten (för Textbrowser)',
+'mw_math_modern' => 'Anratenswert för moderne Browser',
+'mw_math_mathml' => 'MathML (experimentell)',
+
+# Infosiet
+'infosubtitle' => 'Informatschonen för de Siet',
+'numedits' => 'Antall vun Ännern (Siet): $1',
+'numtalkedits' => 'Antall vun Ännern (Diskuschoonssiet): $1',
+'numwatchers' => 'Antall vun Oppassers: $1',
+'numauthors' => 'Antall vun verschedene Autoren (Siet): $1',
+'numtalkauthors' => 'Antall vun verschedene Autoren (Diskuschoonssiet): $1',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'In dissen Wiki söken [alt-f]',
+'tooltip-minoredit' => 'Dit as en lütt Ännern markeern [alt-i]',
+'tooltip-save' => 'Dien Ännern spiekern [alt-s]',
+'tooltip-preview' => 'Vörschau för dien Ännern, bruuk dat vör dat Spiekern. [alt-p]',
+'tooltip-compareselectedversions' => 'De Ünnerscheed twüschen de twee wählten Versionen vun disse Siet ankieken. [alt-v]',
+
+# Stilvörlagen
+
+'monobook.css' => '/* disse Datei editeern üm den Monobook-Skin för de ganze Siet antopassen */',
+#'monobook.js' => '/* disse Datei editeern üm js-Saken in den Monobook-Skin to ännern */',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* Tooltips un Togriepslötel */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Mien Brukersiet\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'De Brukersiet för de IP-Adress ünner de du schriffst\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Mien Diskuschoonssiet\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskuschoon över Ännern vun disse IP-Adress\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Mien Instellen\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Mien Oppasslist\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'List vun mien Bidreeg\');
+ta[\'pt-login\'] = new Array(\'o\',\'Du kannst di geern anmellen, dat is aver nich neudig, üm Sieten to bearbeiden.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Du kannst di geern anmellen, dat is aver nich neudig, üm Sieten to bearbeiden.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Afmellen\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Diskuschoon över disse Siet\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Du kannst disse Siet ännern. Bruuk dat vör dat Spiekern.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'En Kommentar to disse Diskuschoonssiet hentofögen.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Disse Siet is schuult. Du kannst den Borntext ankieken.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Historie vun disse Siet.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Disse Siet schulen\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Disse Siet löschen\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Weerholen vun de Siet, so as se vör dat löschen ween is\');
+ta[\'ca-move\'] = new Array(\'m\',\'Disse Siet schuven\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Disse Siet to de Oppasslist hentofögen\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Disse Siet vun de Oppasslist löschen\');
+ta[\'search\'] = new Array(\'f\',\'In dissen Wiki söken\');
+ta[\'p-logo\'] = new Array(\'\',\'Hööftsiet\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Besöök de Hööftsiet\');
+ta[\'n-portal\'] = new Array(\'\',\'över dat Projekt, wat du doon kannst, woans du de Saken finnen kannst\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Achtergrünn to aktuellen Schehn finnen\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'List vun de letzten Ännern in dissen Wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Tofällige Siet\');
+ta[\'n-help\'] = new Array(\'\',\'Hier kriegst du Hülp.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Gaven\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Wat wiest hierher\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Verlinkte Sieten\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS-Feed för disse Siet\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom-Feed för disse Siet\');
+ta[\'t-contributions\'] = new Array(\'\',\'List vun de Bidreeg vun dissen Bruker\');
+ta[\'t-emailuser\'] = new Array(\'\',\'En E-Mail an dissen Bruker sennen\');
+ta[\'t-upload\'] = new Array(\'u\',\'Biller oder Mediendatein hoochladen\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'List vun alle Spezialsieten\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Siet ankieken\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Brukersiet ankieken\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Mediensiet ankieken\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Dit is en Spezialsiet, du kannst disse Siet nich ännern.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Portalsiet ankieken\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Bildsiet ankieken\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Systemnorichten ankieken\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vörlaag ankieken\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Hülpsiet ankieken\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Kategoriesiet ankieken\');',
+
+# Billerlöschen
+'deletedrevision' => 'Löschte ole Version $1.',
+
+# Ünnerscheed ankieken
+'previousdiff' => '← Geih to den vörigen Ünnerscheed',
+'nextdiff' => 'Geih to den tokamen Ünnerscheed →',
+
+'imagemaxsize' => 'Biller op de Bildbeschrievensiet begrenzen op:',
+'showbigimage' => 'Version mit högere Oplösen dolladen ($1x$2, $3 KB)',
+
+'newimages' => 'Galeree vun niege Biller',
+
+
+# Schalttafel
+
+'editusergroup' => 'Brukergruppen bearbeiden',
+
+
+# Brukergruppen bearbeiden
+'saveusergroups' => 'Brukergruppen spiekern',
+
+# Metadata
+'nodublincore' => 'Dublin-Core-RDF-Metadaten sünd för dissen Server nich aktiveert.',
+'nocreativecommons' => 'Creative-Commons-RDF-Metadaten sünd för dissen Server nich aktiveert.',
+'notacceptable' => 'Dat Wiki-Server kann kene Daten in enen Format levern, dat dien Klient lesen kann.',
+
+# Attributschoon
+
+'anonymous' => 'Anonyme Bruker vun {{SITENAME}}',
+'siteuser' => '{{SITENAME}}-Bruker $1',
+'lastmodifiedatby' => 'Disse Siet weer dat letzte Maal $2, $1 vun $3 ännert.',
+'othercontribs' => 'Grünnt op Arbeid vun $1.',
+'others' => 'annere',
+'siteusers' => '{{SITENAME}}-Bruker $1',
+'creditspage' => 'Sieten-Autoren',
+'nocredits' => 'Dor is keen Autorenlist för disse Siet verfögbor.',
+
+# Spamschild
+
+'spamprotectiontitle' => 'Spamschild',
+'spamprotectiontext' => 'De Siet, de du spiekern wullst, weer vun de Spamschild blockt. Dat kann vun en Link to en externe Siet kamen.',
+'spamprotectionmatch' => 'Dit Text hett den Spamschild utlöst: $1',
+'listingcontinuesabbrev' => ' wieder',
+
+# Patrolleern
+'markaspatrolleddiff' => 'As patrolleert markeern',
+'markaspatrolledtext' => 'Disse Siet as patrolleert markeern',
+'markedaspatrolled' => 'As patrolleert markeert',
+'markedaspatrolledtext' => 'Disse Revision is as patrolleert markeert.',
+'rcpatroldisabled' => 'Letzte-Ännern-Patrol nich aktiveert',
+'rcpatroldisabledtext' => 'De Letzte-Ännern-Patrol-Funktschoon is in\'n Momang nich aktiveert.',
+
+# Naamruum 8
+
+'allmessages' => 'Alle Systemnorichten',
+'allmessagestext' => 'Dit is en List vun alle Systemnorichten, de in de MediaWiki:-Naamruum verfögbor sünd.',
+'allmessagesnotsupportedUI' => 'Dien aktuelle Snittstellenspraak <b>$1</b> warrt vun Special:AllMessages op disse Steed nich ünnerstütt.',
+'allmessagesnotsupportedDB' => 'Special:AllMessages is nich ünnerstütt, vun wegen dat wgUseDatabaseMessages utstellt is.',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesNds_nl.php b/languages/messages/MessagesNds_nl.php
new file mode 100644
index 000000000000..499169c391ee
--- /dev/null
+++ b/languages/messages/MessagesNds_nl.php
@@ -0,0 +1,63 @@
+<?php
+/** Dutch Lower Saxon (Nedersaksisch)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>, Jens Frank
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, Jens Frank
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+$fallback = 'nds';
+
+$skinNames = array(
+ 'standard' => 'Klassiek',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Keuls blauw',
+ 'smarty' => 'Paddington',
+ 'chick' => 'Sjiek'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciaal',
+ NS_MAIN => '',
+ NS_TALK => 'Overleg',
+ NS_USER => 'Gebruker',
+ NS_USER_TALK => 'Overleg_gebruker',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Overleg_$1',
+ NS_IMAGE => 'Ofbeelding',
+ NS_IMAGE_TALK => 'Overleg_ofbeelding',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Overleg_MediaWiki',
+ NS_TEMPLATE => 'Sjabloon',
+ NS_TEMPLATE_TALK => 'Overleg_sjabloon',
+ NS_HELP => 'Help',
+ NS_HELP_TALK => 'Overleg_help',
+ NS_CATEGORY => 'Kattegerie',
+ NS_CATEGORY_TALK => 'Overleg_kattegerie'
+);
+
+$namespaceAliases = array(
+ 'Speciaol' => NS_SPECIAL,
+ 'Categorie' => NS_CATEGORY,
+ 'Overleg_categorie' => NS_CATEGORY_TALK,
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'H:i, M j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'H:i, j M Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'H:i, Y M j',
+);
+
+?>
diff --git a/languages/messages/MessagesNl.php b/languages/messages/MessagesNl.php
new file mode 100644
index 000000000000..1177543c6bc1
--- /dev/null
+++ b/languages/messages/MessagesNl.php
@@ -0,0 +1,1901 @@
+<?php
+/** Dutch (Nederlands)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Uitgeschakeld', 'Links vast', 'Rechts vast', 'Links zwevend'
+);
+
+$skinNames = array(
+ 'standard' => 'Standaard',
+ 'nostalgia' => 'Nostalgie',
+ 'cologneblue' => 'Keuls blauw',
+);
+
+$bookstoreList = array(
+ 'Koninklijke Bibliotheek' => 'http://opc4.kb.nl/DB=1/SET=5/TTL=1/CMD?ACT=SRCH&IKT=1007&SRT=RLV&TRM=$1'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciaal',
+ NS_MAIN => '',
+ NS_TALK => 'Overleg',
+ NS_USER => 'Gebruiker',
+ NS_USER_TALK => 'Overleg_gebruiker',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Overleg_$1',
+ NS_IMAGE => 'Afbeelding',
+ NS_IMAGE_TALK => 'Overleg_afbeelding',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Overleg_MediaWiki',
+ NS_TEMPLATE => 'Sjabloon',
+ NS_TEMPLATE_TALK => 'Overleg_sjabloon',
+ NS_HELP => 'Help',
+ NS_HELP_TALK => 'Overleg_help',
+ NS_CATEGORY => 'Categorie',
+ NS_CATEGORY_TALK => 'Overleg_categorie'
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'M j, Y H:i',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'j M Y H:i',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'Y M j H:i',
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = '/^([a-zäöüïëéèà]+)(.*)$/sDu';
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+# Allowed characters in keys are: A-Z, a-z, 0-9, underscore (_) and
+# hyphen (-). If you need more characters, you may be able to change
+# the regex in MagicWord::initRegex
+
+$messages = array(
+/*
+The sidebar for MonoBook is generated from this message, lines that do not
+begin with * or ** are discarded, furthermore lines that do begin with ** and
+do not contain | are also discarded, but don't depend on this behaviour for
+future releases. Also note that since each list value is wrapped in a unique
+XHTML id it should only appear once and include characters that are legal
+XHTML id names.
+
+Note to translators: Do not include this message in the language files you
+submit for inclusion in MediaWiki, it should always be inherited from the
+parent class in order maintain consistency across languages.
+*/
+# User preference toggles
+'tog-underline' => 'Links onderstrepen:',
+'tog-highlightbroken' => 'Links naar lege pagina\'s <a href="" class="new">zo weergeven</a> (alternatief: zo weergeven<a href="" class="internal">?</a>).',
+'tog-justify' => 'Paragrafen uitvullen',
+'tog-hideminor' => 'Kleine wijzigingen verbergen in recente wijzigingen',
+'tog-extendwatchlist' => 'Toon alle wijzigingen in mijn volglijst',
+'tog-usenewrc' => 'Gebruik de uitgebreide Recente Wijzigingen-pagina (vereist JavaScript)',
+'tog-numberheadings' => 'Koppen automatisch nummeren',
+'tog-showtoolbar' => 'Toon werkbalk boven bewerkingsveld (vereist JavaScript)',
+'tog-editondblclick' => 'Dubbelklikken voor bewerken (vereist JavaScript)',
+'tog-editsection' => 'Maak het bewerken van deelpagina\'s mogelijk',
+'tog-editsectiononrightclick'=> 'Maak bewerken van deelpagina\'s mogelijk met een rechtermuisklik op een tussenkop (vereist JavaScript)',
+'tog-showtoc' => 'Toon inhoudsopgave (voor pagina\'s met minstens 3 tussenkoppen)',
+'tog-rememberpassword' => 'Wachtwoord onthouden',
+'tog-editwidth' => 'Bewerkingsveld over volle breedte',
+'tog-watchcreations' => 'Pagina\'s die ik aanmaak automatisch volgen',
+'tog-watchdefault' => 'Pagina\'s die ik bewerk automatisch volgen',
+'tog-minordefault' => 'Al mijn bewerkingen als \'klein\' markeren',
+'tog-previewontop' => 'Toon voorvertoning boven bewerkingsveld',
+'tog-previewonfirst' => 'Toon voorvertoning bij eerste bewerking',
+'tog-nocache' => 'Gebruik geen caching',
+'tog-enotifwatchlistpages'=> 'Verzend een e-mail bij bewerkingen van pagina\'s op mijn volglijst',
+'tog-enotifusertalkpages'=> 'Verzend een e-mail als mijn overlegpagina wijzigt',
+'tog-enotifminoredits' => 'Verzend ook een e-mail bij kleine bewerkingen op pagina\'s op mijn volglijst',
+'tog-enotifrevealaddr' => 'Toon mijn e-mailadres in e-mailberichten',
+'tog-shownumberswatching'=> 'Toon aantal gebruikers dat deze pagina volgt',
+'tog-fancysig' => 'Ondertekenen zonder link naar gebruikerspagina',
+'tog-externaleditor' => 'Gebruik standaard een externe tekstbewerker',
+'tog-externaldiff' => 'Gebruik standaard een extern vergelijkingsprogramma',
+'tog-showjumplinks' => 'Maak "ga naar"-toegankelijkheidslinks mogelijk',
+'tog-uselivepreview' => 'Gebruik "live voorvertoning" (vereist JavaScript - experimenteel)',
+'tog-autopatrol' => 'Markeer eigen bewerkingen als gecontroleerd',
+'tog-forceeditsummary' => 'Geef een melding bij een lege samenvatting',
+'tog-watchlisthideown' => 'Verberg eigen bewerkingen op mijn volglijst',
+'tog-watchlisthidebots' => 'Verberg botbewerkingen op mijn volglijst',
+
+'underline-always' => 'Altijd',
+'underline-never' => 'Nooit',
+'underline-default' => 'Webbrowser-standaard',
+
+'skinpreview' => '(Voorvertoning)',
+
+# dates
+'sunday' => 'zondag',
+'monday' => 'maandag',
+'tuesday' => 'dinsdag',
+'wednesday' => 'woensdag',
+'thursday' => 'donderdag',
+'friday' => 'vrijdag',
+'saturday' => 'zaterdag',
+'sun' => 'zon',
+'mon' => 'maa',
+'tue' => 'din',
+'wed' => 'woe',
+'thu' => 'don',
+'fri' => 'vri',
+'sat' => 'zat',
+'january' => 'januari',
+'february' => 'februari',
+'march' => 'maart',
+'april' => 'april',
+'may_long' => 'mei',
+'june' => 'juni',
+'july' => 'juli',
+'august' => 'augustus',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'december',
+'january-gen' => 'januari',
+'february-gen' => 'februari',
+'march-gen' => 'maart',
+'april-gen' => 'april',
+'may-gen' => 'mei',
+'june-gen' => 'juni',
+'july-gen' => 'juli',
+'august-gen' => 'augustus',
+'september-gen' => 'september',
+'october-gen' => 'oktober',
+'november-gen' => 'november',
+'december-gen' => 'december',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mrt',
+'apr' => 'apr',
+'may' => 'mei',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dec',
+# Bits of text used by many pages:
+#
+'categories' => 'Categorieën',
+'pagecategories' => '{{PLURAL:$1|Categorie|Categorieën}}',
+'category_header' => 'Pagina\'s in categorie "$1"',
+'subcategories' => 'Ondercategorieën',
+
+'mainpage' => 'Hoofdpagina',
+'mainpagetext' => '<big>\'\'\'De installatie van MediaWiki is geslaagd.\'\'\'</big>',
+'mainpagedocfooter' => 'Raadpleeg de [http://meta.wikimedia.org/wiki/Help:Contents handleiding] voor informatie over het gebruik van de wikisoftware.
+
+== Meer hulp ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Lijst met instellingen]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki mailinglijst voor nieuwe versies]',
+
+'portal' => 'Gebruikersportaal',
+'portal-url' => 'Project:Gebruikersportaal',
+'about' => 'Info',
+'aboutsite' => 'Over {{SITENAME}}',
+'aboutpage' => 'Project:Info',
+'article' => 'Pagina',
+'help' => 'Hulp en contact',
+'helppage' => 'Help:Inhoud',
+'bugreports' => 'Foutrapporten',
+'bugreportspage' => 'Project:Foutrapportage',
+'sitesupport' => 'Financieel bijdragen',
+'sitesupport-url' => 'Project:Financieel bijdragen',
+'faq' => 'FAQ (veelgestelde vragen)',
+'faqpage' => 'Project:Veelgestelde vragen',
+'edithelp' => 'Hulp bij bewerken',
+'newwindow' => '(nieuw venster)',
+'edithelppage' => 'Help:Bewerken',
+'cancel' => 'Annuleren',
+'qbfind' => 'Zoeken',
+'qbbrowse' => 'Bladeren',
+'qbedit' => 'Bewerken',
+'qbpageoptions' => 'Pagina-opties',
+'qbpageinfo' => 'Pagina-informatie',
+'qbmyoptions' => 'Mijn opties',
+'qbspecialpages' => 'Speciale pagina\'s',
+'moredotdotdot' => 'Meer...',
+'mypage' => 'Mijn gebruikerspagina',
+'mytalk' => 'Mijn overleg',
+'anontalk' => 'Overlegpagina voor dit IP-adres',
+'navigation' => 'Navigatie',
+
+# Metadata in edit box
+'metadata_help' => 'Metadata (zie [[Project:Metadata]] voor toelichting):',
+
+'currentevents' => 'In het nieuws',
+'currentevents-url' => 'In het nieuws',
+
+'disclaimers' => 'Voorbehoud',
+'disclaimerpage' => 'Project:Algemeen voorbehoud',
+'privacy' => 'Privacybeleid',
+'privacypage' => 'Project:Privacybeleid',
+'errorpagetitle' => 'Fout',
+'returnto' => 'Terug naar $1.',
+'tagline' => 'Van {{SITENAME}}',
+'search' => 'Zoeken',
+'searchbutton' => 'Zoeken',
+'go' => 'OK',
+'searcharticle' => 'OK',
+'history' => 'Geschiedenis',
+'history_short' => 'Geschiedenis',
+'updatedmarker' => 'bewerkt sinds mijn laatste bezoek',
+'info_short' => 'Informatie',
+'printableversion' => 'Printervriendelijke versie',
+'permalink' => 'Permalink',
+'print' => 'Afdrukken',
+'edit' => 'Bewerk',
+'editthispage' => 'Bewerk deze pagina',
+'delete' => 'Verwijder',
+'deletethispage' => 'Verwijder deze pagina',
+'undelete_short' => '$1 {{PLURAL:$1|bewerking|bewerkingen}} terugplaatsen',
+'protect' => 'Beveilig',
+'protectthispage' => 'Beveiligen',
+'unprotect' => 'Beveiliging opheffen',
+'unprotectthispage' => 'Beveiliging opheffen',
+'newpage' => 'Nieuwe pagina',
+'talkpage' => 'Overlegpagina',
+'specialpage' => 'Speciale pagina',
+'personaltools' => 'Persoonlijke instellingen',
+'postcomment' => 'Voeg opmerking toe',
+'articlepage' => 'Toon pagina',
+'talk' => 'Overleg',
+'views' => 'Aspecten/acties',
+'toolbox' => 'Hulpmiddelen',
+'userpage' => 'Toon gebruikerspagina',
+'projectpage' => 'Toon projectpagina',
+'imagepage' => 'Toon afbeeldingspagina',
+'mediawikipage' => 'Toon berichtpagina',
+'templatepage' => 'Toon sjabloonpagina',
+'viewhelppage' => 'Toon helppagina',
+'categorypage' => 'Toon categoriepagina',
+'viewtalkpage' => 'Toon overlegpagina',
+'otherlanguages' => 'Andere talen',
+'redirectedfrom' => '(Doorverwezen vanaf $1)',
+'autoredircomment' => 'Verwijst door naar [[$1]]',
+'redirectpagesub' => 'Doorverwijspagina',
+'lastmodifiedat' => 'Deze pagina is het laatst bewerkt op $2, $1.',
+'viewcount' => 'Deze pagina is $1 maal bekeken.',
+'copyright' => 'Inhoud is beschikbaar onder de $1.',
+'protectedpage' => 'Beveiligde pagina',
+'jumpto' => 'Ga naar:',
+'jumptonavigation' => 'navigatie',
+'jumptosearch' => 'zoek',
+
+'badaccess' => 'Geen toestemming',
+'badaccess-group0' => 'U heeft geen rechten om de gevraagde handeling uit te voeren.',
+'badaccess-group1' => 'De gevraagde handeling is voorbehouden aan gebruikers in de groep $1.',
+'badaccess-group2' => 'De gevraagde handeling is voorbehouden aan gebruikers in een van de groepen $1.',
+'badaccess-groups' => 'De gevraagde handeling is voorbehouden aan gebruikers in een van de groepen $1.',
+
+'versionrequired' => 'Versie $1 van MediaWiki is vereist',
+'versionrequiredtext' => 'Versie $1 van MediaWiki is vereist om deze pagina te gebruiken. Zie [[Special:Version]]',
+
+'retrievedfrom' => 'Teruggeplaatst van "$1"',
+'youhavenewmessages' => 'U heeft $1 ($2).',
+'newmessageslink' => 'nieuwe berichten',
+'newmessagesdifflink' => 'toon de bewerking',
+'editsection' => 'bewerk',
+'editold' => 'bewerk',
+'editsectionhint' => 'Bewerk deelpagina: $1',
+'toc' => 'Inhoud',
+'showtoc' => 'tonen',
+'hidetoc' => 'verbergen',
+'thisisdeleted' => '$1 tonen of terugplaatsen?',
+'viewdeleted' => '$1 tonen?',
+'restorelink' => '$1 verwijderde {{PLURAL:$1|versie|versies}}',
+'feedlinks' => 'Feed:',
+'feed-invalid' => 'Feedtype wordt niet ondersteund.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Pagina',
+'nstab-user' => 'Gebruiker',
+'nstab-media' => 'Mediapagina',
+'nstab-special' => 'Speciaal',
+'nstab-project' => 'Projectpagina',
+'nstab-image' => 'Bestand',
+'nstab-mediawiki' => 'Bericht',
+'nstab-template' => 'Sjabloon',
+'nstab-help' => 'Help',
+'nstab-category' => 'Categorie',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Opgegeven handeling bestaat niet',
+'nosuchactiontext' => 'De opdracht in de URL is niet herkend door de wiki',
+'nosuchspecialpage' => 'Deze speciale pagina bestaat niet',
+'nospecialpagetext' => 'U heeft een niet bestaande speciale pagina opgevraagd. Een lijst met speciale pagina\'s staat op [[Special:Specialpages]].',
+
+# General errors
+#
+'error' => 'Fout',
+'databaseerror' => 'Databasefout',
+'dberrortext' => 'Er is een syntaxisfout in de databasequery opgetreden.
+Mogelijk zit er een fout in de software.
+De laatste query naar de database was:
+<blockquote><tt>$1</tt></blockquote>
+vanuit de functie "<tt>$2</tt>".
+MySQL gaf the foutmelding "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Er is een syntaxisfout in de databasequery opgetreden.
+De laatste query naar de database was:
+"$1"
+vanuit de functie "$2".
+MySQL gaf de volgende foutmelding: "$3: $4"',
+'noconnect' => 'Sorry! De wiki ondervindt technische moeilijkheden en kan de database niet bereiken. <br />
+$1',
+'nodb' => 'Kon database $1 niet selecteren',
+'cachederror' => 'De getoonde pagina is een kopie uit de cache en deze kan verouderd zijn.',
+'laggedslavemode' => 'Waarschuwing: De pagina kan verouderd zijn.',
+'readonly' => 'Database geblokkeerd',
+'enterlockreason' => 'Geef een reden op voor de blokkade en geef op wanneer die waarschijnlijk wordt opgeheven.',
+'readonlytext' => 'De database is op het moment geblokkeerd voor bewerkingen, waarschijnlijk vanwege regulier databaseonderhoud. Na afronding wordt de functionaliteit hersteld.
+
+De beheerder heeft de volgende reden opgegeven: $1',
+'missingarticle' => 'In de database is geen tekst aangetroffen voor een pagina met de naam "$1".
+
+Dit wordt meestal veroorzaakt door het volgen van een verouderde link of een link uit de geschiedenis naar een pagina die is verwijderd.
+
+Als dit niet het geval is, dan heeft u een fout in de software gevonden.
+Rapporteer dit alstublieft aan een beheerder met vermelding van de URL.',
+'readonly_lag' => 'De database is automatisch vergrendeld terwijl de slave databaseservers synchroniseren met de master.',
+'internalerror' => 'Interne fout',
+'filecopyerror' => 'Bestand "$1" kon niet gekopieerd worden naar "$2".',
+'filerenameerror' => '"$1" kon niet hernoemd worden naar "$2".',
+'filedeleteerror' => 'Bestand "$1" kon niet verwijderd worden.',
+'filenotfound' => 'Bestand "$1" is niet gevonden.',
+'unexpected' => 'Onverwachte waarde: "$1"="$2".',
+'formerror' => 'Fout: formulier kon niet verzonden worden',
+'badarticleerror' => 'Deze handeling kan niet op deze pagina worden uitgevoerd.',
+'cannotdelete' => 'De pagina of het bestand kon niet verwijderd worden. Mogelijk is deze al door iemand anders verwijderd.',
+'badtitle' => 'Ongeldige paginanaam',
+'badtitletext' => 'De opgevraagde pagina was ongeldig, leeg, of een verkeerd gelinkte intertaal- of interwikinaam. Wellicht bevat de paginanaam niet toegestane karakters.',
+'perfdisabled' => 'Sorry! Deze functionaliteit is tijdelijk uitgeschakeld omdat deze de database zo langzaam maakt dat niemand de wiki kan gebruiken.',
+'perfdisabledsub' => 'Hieronder staat een opgeslagen kopie van $1:',
+'perfcached' => 'De getoonde gegevens komen uit een cache en zijn mogelijk niet actueel.',
+'perfcachedts' => 'De getoonde gegevens komen uit een cache en zijn voor het laatst bijgewerkt op $1.',
+'wrong_wfQuery_params' => 'Incorrecte parameters voor wfQuery()<br />
+Functie: $1<br />
+Query: $2',
+'viewsource' => 'Toon brontekst',
+'viewsourcefor' => 'voor $1',
+'protectedtext' => 'Deze pagina is beveiligd en niet te bewerken.
+
+U kunt de broncode bekijken en kopiëren:',
+'protectedinterface' => 'Deze pagina bevat tekst voor berichten van de software en is beveiligd om misbruik te voorkomen.',
+'editinginterface' => '\'\'\'Waarschuwing:\'\'\' U bewerkt een pagina die gebruikt wordt door de software. Bewerkingen op deze pagina beïnvloeden de gebruikers interface van iedereen.',
+'sqlhidden' => '(SQL query verborgen)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Gebruiker afmelden',
+'logouttext' => '<strong>U bent nu afgemeld.</strong><br />
+U kunt {{SITENAME}} nu anoniem gebruiken of weer aanmelden als dezelfde of een andere gebruiker. Mogelijk blijven een aantal pagina\'s getoond worden alsof u nog bent aangemeld totdat u de cache van uw browser leegt.',
+'welcomecreation' => '== Welkom, $1! ==
+
+Uw account is aangemaakt. Vergeet niet uw voorkeuren voor {{SITENAME}} aan te passen.',
+'loginpagetitle' => 'Gebruikersnaam',
+'yourname' => 'Gebruikersnaam',
+'yourpassword' => 'Wachtwoord',
+'yourpasswordagain' => 'Wachtwoord opnieuw ingeven',
+'remembermypassword' => 'Aanmeldgegevens onthouden',
+'yourdomainname' => 'Uw domein',
+'externaldberror' => 'Er is een fout opgetreden bij het aanmelden bij de database of u heeft geen toestemming uw externe account bij te werken.',
+'loginproblem' => '<b>Er was een probleem bij het aanmelden.</b><br />Probeer het a.u.b. opnieuw.',
+'alreadyloggedin' => '<strong>Gebruiker $1, u bent al aangemeld.</strong><br />',
+
+'login' => 'Aanmelden',
+'loginprompt' => 'U moet cookies accepteren om aan te kunnen melden bij {{SITENAME}}.',
+'userlogin' => 'Aanmelden / Inschrijven',
+'logout' => 'Afmelden',
+'userlogout' => 'Afmelden',
+'notloggedin' => 'Niet aangemeld',
+'nologin' => 'Nog geen gebruikersnaam? $1.',
+'nologinlink' => 'Maak een gebruiker aan',
+'createaccount' => 'Gebruiker aanmaken',
+'gotaccount' => 'Heeft u al een gebruikersnaam? $1.',
+'gotaccountlink' => 'Aanmelden',
+'createaccountmail' => 'per e-mail',
+'badretype' => 'De ingevoerde wachtwoorden verschillen van elkaar.',
+'userexists' => 'De gekozen gebruikersnaam is al in gebruik. Kies a.u.b. een andere naam.',
+'youremail' => 'Uw e-mailadres (optioneel)*:',
+'username' => 'Gebruikersnaam:',
+'uid' => 'Gebruikersnummer:',
+'yourrealname' => 'Uw echte naam *:',
+'yourlanguage' => 'Taal:',
+'yourvariant' => 'Taalvariant',
+'yournick' => 'Tekst voor ondertekening:',
+'badsig' => 'Ongeldige ondertekening; controleer de HTML-tags.',
+'email' => 'E-mail',
+'prefs-help-email-enotif'=> 'Dit e-mailadres wordt ook gebruikt om mededelingen naar u toe te sturen, als u die functies heeft ingesteld.',
+'prefs-help-realname' => '* Echte naam (optioneel): als u deze opgeeft kan deze naam gebruikt worden om u erkenning te geven voor uw werk.',
+'loginerror' => 'Aanmeldfout',
+'prefs-help-email' => '* E-mail (optioneel): Stelt anderen in staat contact met u op te nemen via uw gebruikers- of overlegpagina zonder dat u uw identiteit prijsgeeft.',
+'nocookiesnew' => 'De gebruiker is aangemaakt maar nog niet aangemeld. {{SITENAME}} gebruikt cookies voor het aanmelden van gebruikers. Schakel die a.u.b. in en meld daarna aan met uw nieuwe gebruikersnaam en wachtwoord.',
+'nocookieslogin' => '{{SITENAME}} gebruikt cookies voor het aanmelden van gebruikers. U accepteert geen cookies. Schakel deze optie a.u.b. aan en probeer het opnieuw.',
+'noname' => 'U heeft geen geldige gebruikersnaam opgegeven.',
+'loginsuccesstitle' => 'Aanmelden geslaagd',
+'loginsuccess' => '\'\'\'U bent nu aangemeld bij {{SITENAME}} als "$1".\'\'\'',
+'nosuchuser' => 'De gebruiker "$1" bestaat niet. Controleer de schrijfwijze of maak een nieuwe gebruiker aan.',
+'nosuchusershort' => 'De gebruiker "$1" bestaat niet. Controleer de schrijfwijze.',
+'nouserspecified' => 'U dient een gebruikersnaam op te geven.',
+'wrongpassword' => 'Wachtwoord onjuist. Probeer het opnieuw.',
+'wrongpasswordempty' => 'Het opgegeven wachtwoord was leeg. Probeer het opnieuw.',
+'mailmypassword' => 'E-mail wachtwoord',
+'passwordremindertitle' => 'Wachtwoordherinnering van {{SITENAME}}',
+'passwordremindertext' => 'Iemand, waarschijnlijk u, heeft vanaf IP-adres $1 een verzoek gedaan tot het
+toezenden van het wachtwoord voor {{SITENAME}} ($4).
+Het wachtwoord voor gebruiker "$2" is "$3".
+Meld u nu aan en wijzig dan uw wachtwoord.
+
+Als iemand anders dan u dit verzoek heeft gedaan of als u zich inmiddels het wachtwoord herinnert en het niet langer wilt wijzigen, negeer dit bericht dan en blijf uw bestaande wachtwoord gebruiken.',
+'noemail' => 'Er is geen e-mailadres bekend voor gebruiker "$1".',
+'passwordsent' => 'Het wachtwoord is verzonden naar het e-mailadres voor "$1".
+Meld u a.u.b. aan nadat u het heeft ontvangen.',
+'eauthentsent' => 'Er is een bevestigingsmail naar het opgegeven e-mailadres gezonden. Volg de instructies in de e-mail om aan te geven dat het uw e-mailadres is. Tot die tijd wordt er geen e-mail aan het adres gezonden.',
+'mailerror' => 'Fout bij het verzenden van e-mail: $1',
+'acct_creation_throttle_hit'=> 'Sorry, er zijn al $1 accounts aangemaakt vanaf dit IP-adres. U kunt geen nieuwe gebruikers meer aanmaken.',
+'emailauthenticated' => 'Uw e-mailadres is bevestigd op $1.',
+'emailnotauthenticated' => 'Uw e-mailadres is nog niet bevestigd. U ontvangt geen e-mail voor de onderstaande functies.',
+'noemailprefs' => 'Geef een e-mailadres op om deze functies te gebruiken.',
+'emailconfirmlink' => 'Bevestig uw e-mailadres',
+'invalidemailaddress' => 'Het e-mailadres is niet geaccepteerd omdat het een ongeldige opmaak heeft. Geef a.u.b. een geldig e-mailadres op of laat het veld leeg.',
+'accountcreated' => 'Gebruiker aangemaakt',
+'accountcreatedtext' => 'De gebruiker $1 is aangemaakt.',
+
+# Edit page toolbar
+'bold_sample' => 'Vetgedrukte tekst',
+'bold_tip' => 'Vet',
+'italic_sample' => 'Cursieve tekst',
+'italic_tip' => 'Cursief',
+'link_sample' => 'Onderwerp',
+'link_tip' => 'Interne link',
+'extlink_sample' => 'http://www.example.com linktekst',
+'extlink_tip' => 'Externe link (vergeet http:// niet)',
+'headline_sample' => 'Deelonderwerp',
+'headline_tip' => 'Tussenkopje (hoogste niveau)',
+'math_sample' => 'Voer de formule in',
+'math_tip' => 'Wiskundige formule (LaTeX)',
+'nowiki_sample' => 'Voer hier de niet op te maken tekst in',
+'nowiki_tip' => 'Negeer wiki-opmaak',
+'image_sample' => 'Voorbeeld.png',
+'image_tip' => 'Afbeelding',
+'media_sample' => 'Voorbeeld.ogg',
+'media_tip' => 'Link naar bestand',
+'sig_tip' => 'Uw handtekening met datum en tijd',
+'hr_tip' => 'Horizontale lijn (gebruik spaarzaam)',
+
+# Edit pages
+#
+'summary' => 'Samenvatting',
+'subject' => 'Onderwerp/kop',
+'minoredit' => 'Dit is een kleine bewerking',
+'watchthis' => 'Volg deze pagina',
+'savearticle' => 'Pagina opslaan',
+'preview' => 'Nakijken',
+'showpreview' => 'Toon bewerking ter controle',
+'showlivepreview' => 'Toon bewerking ter controle',
+'showdiff' => 'Toon wijzigingen',
+'anoneditwarning' => '\'\'\'Waarschuwing:\'\'\' U bent niet aangemeld. Uw IP-adres wordt opgeslagen als u wijzigingen op deze pagina maakt.',
+'missingsummary' => '\'\'\'Herinnering:\'\'\' U heeft geen samenvatting opgegeven voor uw bewerking. Als u nogmaals op \'\'Pagina opslaan\'\' klikt wordt de bewerking zonder samenvatting opgeslagen.',
+'missingcommenttext' => 'Plaats uw opmerking hieronder, a.u.b.',
+'blockedtitle' => 'Gebruiker is geblokkeerd',
+'blockedtext' => "<big>'''Uw gebruikersnaam of IP-adres is geblokkeerd.'''</big>
+De blokkade is ingesteld door $1. De opgegeven reden is ''$2''.
+U kunt contact opnemen met $1 of een andere [[Project:Administrators|beheerder]] om de blokkade te bespreken.
+U kunt geen gebruik maken van de functie 'E-mail gebruiker' tenzij u een een geldig e-mailadres heeft opgegeven in uw [[Special:Preferences|voorkeuren]].
+Uw huidige IP-adres is $3. Vermeld dit adres in eventuele correspondentie.",
+'blockedoriginalsource' => 'Hieronder staat de brontekst van \'\'\'$1\'\'\':',
+'blockededitsource' => 'Hieronder staat de tekst van \'\'\'uw bewerkingen\'\'\' aan \'\'\'$1\'\'\':',
+'whitelistedittitle' => 'Voor bewerken is aanmelden verplicht',
+'whitelistedittext' => 'U moet $1 om pagina\'s te bewerken.',
+'whitelistreadtitle' => 'Voor leestoegang is aanmelden verplicht',
+'whitelistreadtext' => '[[Special:Userlogin|Meld u aan]] voor leestoegang tot pagina\'s.',
+'whitelistacctitle' => 'Het aanmaken van nieuwe gebruikers is niet toegestaan',
+'whitelistacctext' => 'U dient [[Special:Userlogin|aangemeld]] te zijn en de juiste rechten te hebben om gebruikers aan te maken in deze Wiki.',
+'confirmedittitle' => 'E-mailbevestiging is verplicht voordat u kunt bewerken',
+'confirmedittext' => 'U moet uw e-mailadres bevestigen voor u kunt bewerken. Voer uw emailadres in en bevestig het via [[Special:Preferences|uw voorkeuren]].',
+'loginreqtitle' => 'Aanmelden verplicht',
+'loginreqlink' => 'aanmelden',
+'loginreqpagetext' => '$1 is verplicht om andere pagina\'s te kunnen zien.',
+'accmailtitle' => 'Wachtwoord verzonden.',
+'accmailtext' => 'Het wachtwoord voor "$1" is verzonden naar $2.',
+'newarticle' => '(Nieuw)',
+'newarticletext' => 'Deze pagina bestaat nog niet. Typ in het onderstaande veld om de pagina aan te maken (meer informatie staat op de [[Help:Inhoud|hulppagina]]).
+Gebruik te knop \'\'\'vorige\'\'\' in uw browser als u hier per ongeluk terecht bent gekomen.',
+'anontalkpagetext' => '----\'\'Deze overlegpagina hoort bij een anonieme gebruiker die hetzij geen loginnaam heeft, hetzij deze niet gebruikt. We gebruiken daarom het IP-adres ter identificatie. Het is mogelijk dat meerdere personen hetzelfde IP-adres gebruiken. Mogelijk ontvangt u hier berichten die niet voor u bedoeld zijn. Als u dat wilt voorkomen, [[Special:Userlogin|maak dan een gebruikersnaam aan of meld u aan]].\'\'',
+'noarticletext' => 'Deze pagina bevat geen tekst. U kunt [[Special:Search/{{PAGENAME}}|naar deze term zoeken]] in andere pagina\'s of [{{fullurl:{{FULLPAGENAME}}|action=edit}} deze pagina bewerken].',
+'clearyourcache' => '\'\'\'Let op!\'\'\' Leeg uw cache nadat u de wijzigingen heeft opgeslagen.
+
+{| border="1" cellpadding="3" class=toccolours style="border: 1px #AAAAAA solid; border-collapse: collapse;"
+| Mozilla/Safari/Konqueror || CTRL-SHIFT-R
+|-
+| IE || CTRL-F5
+|-
+| Opera || F5
+|-
+| Safari || CMD-R
+|-
+| Konqueror || F5
+|}',
+'usercssjsyoucanpreview'=> "<strong>Tip:</strong> Gebruik de knop 'Toon bewerking ter controle' om uw nieuwe css/js te testen alvorens op te slaan.",
+'usercsspreview' => "'''Dit is alleen een voorvertoning van uw persoonlijke css, deze is nog niet opgeslagen!'''",
+'userjspreview' => "'''Let op: u test nu uw persoonlijke JavaScript. Het is nog niet opgeslagen!'''",
+'userinvalidcssjstitle' => "'''Waarschuwing:''' er is geen skin \"$1\". Let op: uw eigen .css- en .js-pagina's beginnen met een kleine letter, bijvoorbeeld User:Naam/monobook.css in plaats van User:Naam/Monobook.css.",
+'updated' => '(Bijgewerkt)',
+'note' => '<strong>Opmerking:</strong>',
+'previewnote' => '<strong>Let op: dit is een controlepagina; uw tekst is nog niet opgeslagen!</strong>',
+'session_fail_preview' => '<strong>Sorry! Uw bewerking is niet verwerkt omdat sessiegegevens verloren zijn gegaan.
+Probeer het opnieuw. Als het dan nog niet lukt, meldt u dan af en weer aan.</strong>',
+'previewconflict' => 'Deze voorvertoning geeft aan hoe de tekst in het bovenste veld eruit ziet als u deze opslaat.',
+'session_fail_preview_html'=> '<strong>Sorry! Uw bewerking is niet verwerkt omdat sessiegegevens verloren zijn gegaan.</strong>
+
+\'\'Omdat in deze wiki ruwe HTML is ingeschakeld, is een voorvertoning niet mogelijk als bescherming tegen aanvallen met JavaScript.\'\'
+
+<strong>Als dit een legitieme bewerking is, probeer het dan opnieuw. Als het dan nog niet lukt, meldt u dan af en weer aan.</strong>',
+'importing' => 'Bezig met importeren van $1',
+'editing' => 'Bezig met bewerken van $1',
+'editinguser' => 'Bezig met bewerken van $1',
+'editingsection' => 'Bezig met bewerken van $1 (deelpagina)',
+'editingcomment' => 'Bezig met bewerken van $1 (opmerking)',
+'editconflict' => 'Bewerkingsconflict: $1',
+'explainconflict' => 'Een andere gebruiker heeft deze pagina bewerkt sinds u met uw bewerking bent begonnen.
+In het bovenste deel van het venster staat de tekst van de huidige pagina.
+Uw bewerking staat nog in het onderste gedeelte.
+U dient uw bewerkingen in te voegen in de bestaande tekst.
+<b>Alleen</b> de tekst in het bovenste gedeelte wordt opgeslagen als u op "Pagina opslaan" klikt.<br />',
+'yourtext' => 'Uw tekst',
+'storedversion' => 'Opgeslagen versie',
+'nonunicodebrowser' => '<strong>WAARSCHUWING: Uw browser kan niet goed overweg met unicode. Hiermee wordt door de Mediawiki rekening gehouden zodat u toch zonder problemen pagina\'s kan bewerken: niet-ASCII karakters worden in het bewerkingsveld weergegeven als hexadecimale codes.</strong>',
+'editingold' => '<strong><span style="color:#ff0000">Waarschuwing!</span> U bewerkt een oude versie van deze pagina. Als u uw bewerking opslaat, gaan alle wijzigingen die na deze versie gemaakt zijn verloren.</strong>',
+'yourdiff' => 'Wijzigingen',
+'copyrightwarning' => 'Opgelet: Alle bijdragen aan {{SITENAME}} worden geacht te zijn vrijgegeven onder de $2 (zie $1 voor details). Als u niet wilt dat uw tekst door anderen naar believen bewerkt en verspreid kan worden, kies dan niet voor \'Pagina Opslaan\'.<br />
+Hierbij belooft u ons tevens dat u deze tekst zelf heeft geschreven, of overgenomen uit een vrije, openbare bron.<br />
+<strong>GEBRUIK GEEN MATERIAAL DAT BESCHERMD WORDT DOOR AUTEURSRECHT, TENZIJ U DAARTOE TOESTEMMING HEEFT!</strong>',
+'copyrightwarning2' => 'Al uw bijdragen aan {{SITENAME}} kunnen bewerkt, gewijzigd of verwijderd worden door andere gebruikers. Als u niet wilt dat uw teksten rigoureus aangepast worden door anderen, plaats ze hier dan niet.<br />
+U belooft ook u dat u de oorspronkelijke auteur bent van dit materiaal, of dat u het heeft gekopieerd uit een bron in het publieke domein, of een soortgelijke vrije bron (zie $1 voor details).
+<strong>GEBRUIK GEEN MATERIAAL DAT BESCHERMD WORDT DOOR AUTEURSRECHT, TENZIJ U DAARTOE TOESTEMMING HEEFT!</strong>',
+'longpagewarning' => '<strong>Deze pagina is $1 kilobyte groot; sommige browsers hebben problemen met het bewerken van pagina\'s die groter zijn dan 32kb. Wellicht kan deze pagina gesplitst worden in kleinere delen.</strong>',
+'longpageerror' => '<strong>ERROR: De tekst die u heeft toegevoegd heeft is $1 kilobyte
+groot, wat groter is dan het maximum van $2 kilobyte. Opslaan is niet mogelijk.</strong>',
+'readonlywarning' => '<strong>WAARSCHUWING: De database accepteert geen bewerkingen, dus u kunt deze nu niet opslaan. Het is misschien verstandig uw tekst lokaal op te slaan in een bestand met kopiëren en plakken zodat u die hier later weer kunt invoegen.</strong>',
+'protectedpagewarning' => '<strong>WAARSCHUWING! Deze beveiligde pagina kan alleen door gebruikers met beheerdersrechten bewerkt worden.</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Let op:\'\'\' Deze pagina is beveiligd en kan alleen door geregistreerde gebruikers bewerkt worden.',
+'templatesused' => 'Op deze pagina gebruikte sjablonen:',
+'edittools' => '<!-- Deze tekst wordt weergegeven onder bewerkings- en uploadformulieren. -->',
+'nocreatetitle' => 'Het aanmaken van pagina\'s is beperkt',
+'nocreatetext' => 'Deze website heeft de mogelijkheid om nieuwe pagina\'s te maken beperkt.
+U kunt reeds bestaande pagina\'s wijzigen, of u kunt [[Special:Userlogin|zich aanmelden of een gebruiker aanmaken]].',
+'cantcreateaccounttitle' => 'Kan gebruiker niet aanmaken',
+'cantcreateaccounttext' => 'Het aanmaken van gebruikers vanaf dit IP-adres (<b>$1</b>) is geblokkeerd. Dit komt mogelijk door aanhoudend vandalisme vanuit uw onderwijsinstelling of Internet service provider.',
+
+# History pages
+#
+'revhistory' => 'Bewerkingsgeschiedenis',
+'viewpagelogs' => 'Toon logboek voor deze pagina',
+'nohistory' => 'Deze pagina is nog niet bewerkt.',
+'revnotfound' => 'Bewerking niet gevonden',
+'revnotfoundtext' => 'De opgevraagde oude versie van deze pagina is onvindbaar. Controleer a.u.b. de URL die u gebruikte om naar deze pagina te gaan.',
+'loadhist' => 'Bezig met het laden van de paginageschiedenis',
+'currentrev' => 'Huidige versie',
+'revisionasof' => 'Versie op $1',
+'revision-info' => 'Versie per $1; $2',
+'previousrevision' => '←Oudere versie',
+'nextrevision' => 'Nieuwere versie→',
+'currentrevisionlink' => 'Huidige versie',
+'cur' => 'huidig',
+'next' => 'volgende',
+'last' => 'vorige',
+'histlegend' => 'Selectie voor diff: selecteer de te vergelijken versies en toets ENTER of de knop onderaan.<br />
+Verklaring afkortingen: (huidig) = verschil met huidige versie, (vorige) = verschil met voorgaande versie, k = kleine wijziging',
+'deletedrev' => '[verwijderd]',
+'histfirst' => 'Oudste',
+'histlast' => 'Nieuwste',
+'rev-deleted-comment' => '(opmerking verwijderd)',
+'rev-deleted-user' => '(gebruiker verwijderd)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+De geschiedenis van deze pagina is verwijderd uit de publieke archieven.
+Er kunnen details aanwezig zijn in het [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} verwijderlogboek].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+De geschiedenis van deze pagina is verwijderd uit de publieke archieven.
+Als beheerder van deze site kunt u deze zien;
+er kunnen details aanwezig zijn in het [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} verwijderlogboek].
+</div>',
+'rev-delundel' => 'toon/verberg',
+
+'history-feed-title' => 'Bewerkingsoverzicht',
+'history-feed-description'=> 'Bewerkingsoverzicht voor deze pagina op de wiki',
+'history-feed-item-nocomment'=> '$1 op $2',
+'history-feed-empty' => 'De gevraagde pagina bestaat niet.
+Wellicht is die verwijderd of hernoemd.
+[[Special:Search|Doorzoek de wiki]] voor relevante pagina\'s.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Verwijder/Herstel bewerkingen',
+'revdelete-nooldid-title'=> 'Geen doelversie',
+'revdelete-nooldid-text'=> 'U heeft geen doelversie(s) voor deze handeling opgegeven.',
+'revdelete-selected' => 'Geselecteerde bewerking van [[:$1]]:',
+'revdelete-text' => 'Verwijderde bewerkingen zijn nog steeds zichtbaar in de geschiedenis, maar de inhoud is niet langer publiek toegankelijk.
+
+Andere beheerders van deze wiki kunnen nog steeds de verborgen inhoud benaderen en de verwijdering ongedaan maken met behulp van dit scherm, tenzij er additionele restricties gelden die zijn ingesteld door de systeembeheerder.',
+'revdelete-legend' => 'Stel versiebeperkingen in:',
+'revdelete-hide-text' => 'Verberg de bewerkte tekst',
+'revdelete-hide-comment'=> 'Verberg de bewerkingssamenvatting',
+'revdelete-hide-user' => 'Verberg gebruikersnaam/IP van de gebruiker',
+'revdelete-hide-restricted'=> 'Pas deze beperkingen toe op zowel beheerders als anderen',
+'revdelete-log' => 'Opmerking in logboek:',
+'revdelete-submit' => 'Pas toe op de geselecteerde bewerking',
+'revdelete-logentry' => 'zichtbaarheid van bewerkingen is gewijzigd voor [[$1]]',
+
+# Diffs
+#
+'difference' => '(Verschil tussen bewerkingen)',
+'loadingrev' => 'bezig versie voor diff te laden',
+'lineno' => 'Regel $1:',
+'editcurrent' => 'Bewerk de huidige versie van deze pagina',
+'selectnewerversionfordiff'=> 'Selecteer een nieuwere versie voor de vergelijking',
+'selectolderversionfordiff'=> 'Selecteer een oudere versie voor de vergelijking',
+'compareselectedversions'=> 'Vergelijk geselecteerde versies',
+
+# Search results
+#
+'searchresults' => 'Zoekresultaten',
+'searchresulttext' => 'Voor meer informatie over zoeken op {{SITENAME}}, zie [[Project:Zoeken|Zoeken op {{SITENAME}}]].',
+'searchsubtitle' => "U zocht naar '''[[:$1]]'''",
+'searchsubtitleinvalid' => 'Voor zoekopdracht "$1"',
+'badquery' => 'Verkeerd geformuleerde zoekopdracht',
+'badquerytext' => 'Uw vraag kan niet verwerkt worden.
+Dit komt waarschijnlijk doordat u heeft gezocht op woorden met minder dan drie letters, wat niet mogelijk is.
+Mogelijk heeft u een verkeerde zoekopdracht gebruikt, zoals bijvoorbeeld "fish and and scales".
+Probeer het nog een keer.',
+'matchtotals' => 'De zoekterm "$1" is gevonden in $2 onderwerpen en in de tekst van $3 pagina\'s.',
+'noexactmatch' => '\'\'\'Er bestaat geen pagina met onderwerp $1.\'\'\' U kunt deze [[:$1|aanmaken]].',
+'titlematches' => 'Overeenkomst met onderwerp',
+'notitlematches' => 'Geen resultaten gevonden',
+'textmatches' => 'Overeenkomst met inhoud',
+'notextmatches' => 'Geen pagina\'s gevonden',
+'prevn' => 'vorige $1',
+'nextn' => 'volgende $1',
+'viewprevnext' => '($1) ($2) ($3) tonen.',
+'showingresults' => 'Hieronder staan <b>$1</b> resultaten vanaf resultaat <b>$2</b>.',
+'showingresultsnum' => 'Hieronder staan <b>$3</b> resultaten vanaf resultaat <b>$2</b>.',
+'nonefound' => '\'\'\'Opmerking\'\'\': mislukte zoekopdrachten worden vaak veroorzaakt door zoeken naar veelvoorkomende woorden als "van" en "het", die niet in de indexen worden opgenomen, of door meer dan één zoekterm op te geven. Alleen pagina\'s die alle zoektermen bevatten worden opgenomen in de resultaten.',
+'powersearch' => 'Zoeken',
+'powersearchtext' => 'Zoek in naamruimten:<br />$1<br />$2 Toon redirects<br />Zoek naar $3 $9',
+'searchdisabled' => 'Zoeken in {{SITENAME}} is niet mogelijk. U kunt gebruik maken van Google. De gegevens over {{SITENAME}} zijn mogelijk niet bijgewerkt.',
+
+'blanknamespace' => '(Hoofdnaamruimte)',
+
+# Preferences page
+#
+'preferences' => 'Voorkeuren',
+'mypreferences' => 'Mijn voorkeuren',
+'prefsnologin' => 'Niet aangemeld',
+'prefsnologintext' => 'U dient [[Special:Userlogin|aangemeld]] te zijn om uw voorkeuren te kunnen instellen.',
+'prefsreset' => 'Standaardvoorkeuren hersteld.',
+'qbsettings' => 'Menubalk',
+'changepassword' => 'Wachtwoord wijzigen',
+'skin' => 'Vormgeving',
+'math' => 'Formules',
+'dateformat' => 'Datumopmaak',
+'datedefault' => 'Geen voorkeur',
+'datetime' => 'Datum en tijd',
+'math_failure' => 'Parsen mislukt',
+'math_unknown_error' => 'onbekende fout',
+'math_unknown_function' => 'onbekende functie',
+'math_lexing_error' => 'lexicografische fout',
+'math_syntax_error' => 'syntactische fout',
+'math_image_error' => 'PNG-conversie is mislukt. Ga na of latex, dvips en gs correct geïnstalleerd zijn en converteer nogmaals',
+'math_bad_tmpdir' => 'De map voor tijdelijke bestanden voor wiskundige formules bestaat niet of kan niet gemaakt worden',
+'math_bad_output' => 'De map voor bestanden met wiskundige formules bestaat niet of kan niet gemaakt worden.',
+'math_notexvc' => 'Kan het programma texvc niet vinden; stel alles in volgens de beschrijving in math/README.',
+'prefs-personal' => 'Gebruikersprofiel',
+'prefs-rc' => 'Recente wijzigingen',
+'prefs-watchlist' => 'Volglijst',
+'prefs-watchlist-days' => 'Aantal dagen in de volglijst:',
+'prefs-watchlist-edits' => 'Aantal bewerkingen in de uitgebreide volglijst:',
+'prefs-misc' => 'Diversen',
+'saveprefs' => 'Opslaan',
+'resetprefs' => 'Standaardvoorkeuren herstellen',
+'oldpassword' => 'Huidige wachtwoord:',
+'newpassword' => 'Nieuwe wachtwoord:',
+'retypenew' => 'Herhaling nieuwe wachtwoord:',
+'textboxsize' => 'Bewerken',
+'rows' => 'Regels:',
+'columns' => 'Kolommen:',
+'searchresultshead' => 'Zoeken',
+'resultsperpage' => 'Resultaten per pagina:',
+'contextlines' => 'Regels per resultaat:',
+'contextchars' => 'Context per regel:',
+'stubthreshold' => 'Drempelwaarde voor markering als \'beginnetje\':',
+'recentchangescount' => 'Aantal pagina\'s in Recente wijzigingen:',
+'savedprefs' => 'Uw voorkeuren zijn opgeslagen.',
+'timezonelegend' => 'Tijdzone',
+'timezonetext' => 'Het aantal uren dat uw lokale tijd afwijkt van de servertijd (UTC).',
+'localtime' => 'Plaatselijke tijd',
+'timezoneoffset' => 'Tijdsverschil¹',
+'servertime' => 'Servertijd',
+'guesstimezone' => 'Vanuit de browser toevoegen',
+'allowemail' => 'E-mail van andere gebruikers toestaan',
+'defaultns' => 'Zoek standaard in deze naamruimten:',
+'default' => 'standaard',
+'files' => 'Bestanden',
+
+# User rights
+'userrights-lookup-user'=> 'Beheer gebruikersgroepen',
+'userrights-user-editname'=> 'Voer een gebruikersnaam in:',
+'editusergroup' => 'Bewerk gebruikersgroepen',
+
+'userrights-editusergroup'=> 'Bewerk gebruikersgroepen',
+'saveusergroups' => 'Gebruikersgroepen opslaan',
+'userrights-groupsmember'=> 'Lid van:',
+'userrights-groupsavailable'=> 'Beschikbare groepen:',
+'userrights-groupshelp' => 'Selecteer de groepen waaruit u de gebruiker wilt verwijderen of aan toe wilt voegen.
+Niet geselecteerde groepen worden niet gewijzigd. Deselecteer een groep met "Ctrl + linkermuisknop".',
+
+# Groups
+'group' => 'Groep:',
+'group-sysop' => 'Beheerders',
+'group-bureaucrat' => 'Bureaucraten',
+'group-all' => '(alles)',
+
+'group-sysop-member' => 'Beheerder',
+'group-bureaucrat-member'=> 'Bureaucraat',
+
+'grouppage-bot' => 'Project:Bots',
+'grouppage-sysop' => 'Project:Beheerders',
+'grouppage-bureaucrat' => 'Project:Bureaucraten',
+
+# Recent changes
+#
+'changes' => 'wijzigingen',
+'recentchanges' => 'Recente wijzigingen',
+'recentchangestext' => 'Toon de meest recente wijzigingen op de wiki op deze pagina.',
+'rcnote' => 'Hieronder staan de <strong>$1</strong> laatste bewerkingen in de laatste <strong>$2</strong> dagen, per $3.',
+'rcnotefrom' => 'Wijzigingen sinds <b>$2</b> (met een maximum van <b>$1</b> wijzigingen).',
+'rclistfrom' => 'Toon de wijzigingen vanaf $1',
+'rcshowhideminor' => '$1 kleine wijzigingen',
+'rcshowhideliu' => '$1 aangemelde gebruikers',
+'rcshowhideanons' => '$1 anonieme gebruikers',
+'rcshowhidepatr' => '$1 gecontroleerde bewerkingen',
+'rcshowhidemine' => '$1 mijn bewerkingen',
+'rclinks' => 'Toon de $1 laatste wijzigingen in de laatste $2 dagen<br />$3',
+'diff' => 'wijz',
+'hist' => 'gesch',
+'hide' => 'Verberg',
+'show' => 'Toon',
+'minoreditletter' => 'k',
+'number_of_watching_users_pageview'=> '[$1 keer op een volglijst]',
+'rc_categories' => 'Toon alleen categorieën (scheid met een "|")',
+'rc_categories_any' => 'Elke',
+
+# Upload
+#
+'upload' => 'Upload bestand',
+'uploadbtn' => 'Upload bestand',
+'reupload' => 'Opnieuw uploaden',
+'reuploaddesc' => 'Terug naar het uploadformulier.',
+'uploadnologin' => 'Niet aangemeld',
+'uploadnologintext' => 'U dient [[Special:Userlogin|aangemeld]] te zijn
+om bestanden te uploaden.',
+'upload_directory_read_only'=> 'De webserver kan niet schrijven in de uploadmap ($1).',
+'uploaderror' => 'Uploadfout',
+'uploadtext' => 'Gebruik het onderstaande formulier om bestanden te uploaden. Om eerder geüploade bestanden te bekijken of te zoeken kunt u naar de [[Special:Imagelist|lijst van geüploade bestanden]] gaan. Uploads en verwijderingen worden bijgehouden in het [[Special:Log/upload|uploadlogboek]].
+
+Om de afbeelding of het bestand in te voegen in een pagina kunt u een van de volgende codes gebruiken, al naar gelang het bestandsformaat dat van toepassing is:
+
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Bestand.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Bestand.png|alternatieve tekst]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Bestand.ogg]]</nowiki>\'\'\'
+
+De laatste link is bedoeld voor mediabestanden.',
+'uploadlog' => 'uploadlogboek',
+'uploadlogpage' => 'Uploadlogboek',
+'uploadlogpagetext' => 'Hieronder staan de nieuwste bestanden.',
+'filename' => 'Bestandsnaam',
+'filedesc' => 'Samenvatting',
+'fileuploadsummary' => 'Samenvatting:',
+'filestatus' => 'Auteursrechtensituatie',
+'filesource' => 'Bron',
+'copyrightpage' => 'Project:Auteursrechten',
+'copyrightpagename' => '{{SITENAME}} auteursrechten',
+'uploadedfiles' => 'Geüploade bestanden',
+'ignorewarning' => 'Negeer deze waarschuwing en sla het bestand toch op.',
+'ignorewarnings' => 'Negeer alle waarschuwingen',
+'minlength' => 'Bestandsnamen hebben een minimale lengte van drie letters.',
+'illegalfilename' => 'De bestandsnaam "$1" bevat ongeldige karakters. Geef het bestand een andere naam, en probeer het dan opnieuw te uploaden.',
+'badfilename' => 'De naam van het bestand is gewijzigd in "$1".',
+'badfiletype' => '".$1" is geen aanbevolen bestandsformaat.',
+'largefile' => 'Aanbeveling: maak bestanden niet groter dan $1 bytes, dit bestand is $2 bytes',
+'largefileserver' => 'Het bestand is groter dan de instelling van de server toestaat.',
+'emptyfile' => 'Het bestand dat u heeft geüpload lijkt leeg te zijn. Dit zou kunnen komen door een typefout in de bestandsnaam. Ga a.u.b. na of u dit bestand werkelijk bedoelde te uploaden.',
+'fileexists' => 'Er bestaat al een bestand met deze naam. Controleer $1 als u niet zeker weet of u het huidige bestand wilt overschrijven.',
+'fileexists-forbidden' => 'Er bestaat al een bestand met deze naam. Upload uw bestand onder een andere naam.
+[[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Er bestaat al een bestand met deze naam bij de gedeelte bestanden. Upload het bestand onder een andere naam. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'De upload is geslaagd',
+'fileuploaded' => 'De upload van bestand $1 is geslaagd.
+Volg alstublieft deze link: $2 naar de beschrijvingspagina en voeg informatie toe over het bestand, zoals waar het vandaan komt, wanneer en door wie het is gemaakt en wat u er nog meer over weet.
+
+Een afbeelding kunt u als volgt toevoegen: <tt><nowiki>[[Image:$1|thumb|Beschrijving]]</nowiki></tt>',
+'uploadwarning' => 'Uploadwaarschuwing',
+'savefile' => 'Bestand opslaan',
+'uploadedimage' => 'heeft "[[$1]]" geüpload',
+'uploaddisabled' => 'Uploaden is uitgeschakeld',
+'uploaddisabledtext' => 'Het uploaden van bestanden is uitgeschakeld op deze wiki.',
+'uploadscripted' => 'Dit bestand bevat HTML- of scriptcode die foutief door uw browser kan worden weergegeven.',
+'uploadcorrupt' => 'Het bestand is corrupt of heeft een onjuiste extensie. Controleer het bestand en upload het opnieuw.',
+'uploadvirus' => 'Het bestand bevat een virus! Details: $1',
+'sourcefilename' => 'Oorspronkelijke bestandsnaam',
+'destfilename' => 'Opslaan als',
+'watchthisupload' => 'Volg deze pagina',
+'filewasdeleted' => 'Er is eerder een bestand met deze naam verwijderd. Raadpleeg het $1 voordat u het opnieuw toevoegt.',
+
+'license' => 'Licentie',
+'nolicense' => 'Maak een keuze',
+'upload_source_url' => ' (een geldige, publiek toegankelijke URL)',
+'upload_source_file' => ' (een bestand op uw computer)',
+
+# Image list
+#
+'imagelist' => 'Bestandslijst',
+'imagelisttext' => 'Hier volgt een lijst met \'\'\'$1\'\'\' {{plural:$1|bestand|bestanden}} gesorteerd $2.',
+'imagelistforuser' => 'Hieronder staan alleen bestanden die door $1 zijn toegevoegd.',
+'getimagelist' => 'bezig met ophalen bestandslijst',
+'ilsubmit' => 'Zoek',
+'showlast' => 'Toon de laatste $1 afbeeldingen gesorteerd $2.',
+'byname' => 'op naam',
+'bydate' => 'op datum',
+'bysize' => 'op grootte',
+'imgdelete' => 'verw',
+'imgdesc' => 'beschrijving',
+'imgfile' => 'bestand',
+'imglegend' => 'Verklaring: (desc) = toon/bewerk bestandsbeschrijving.',
+'imghistory' => 'Bestandsgeschiedenis',
+'revertimg' => 'herstel',
+'deleteimg' => 'verw',
+'deleteimgcompletely' => 'Verwijder alle versies van dit bestand',
+'imghistlegend' => 'Verklaring: (huidig) = huidige afbeelding, (verw) = verwijder de oude versie, (herstel) = gebruik eerdere versie.<br />
+<i>Klik op het tijdstip om de versie van het bestand te zien die op dat tijdstip is geüpload.</i>.',
+'imagelinks' => 'Bestandsverwijzingen',
+'linkstoimage' => 'Dit bestand wordt op de volgende pagina\'s gebruikt:',
+'nolinkstoimage' => 'Geen enkele pagina gebruikt dit bestand.',
+'sharedupload' => 'Dit bestand is een gedeelde upload en kan ook door andere projecten gebruikt worden.',
+'shareduploadwiki' => 'Zie $1 voor verdere informatie.',
+'shareduploadwiki-linktext'=> 'bestandsbeschrijving',
+'noimage' => 'Er bestaat nog geen bestand met deze naam. U kunt het $1.',
+'noimage-linktext' => 'uploaden',
+'uploadnewversion-linktext'=> 'Upload een nieuwe versie van dit bestand',
+'imagelist_date' => 'Datum',
+'imagelist_name' => 'Naam',
+'imagelist_user' => 'Gebruiker',
+'imagelist_size' => 'Grootte (bytes)',
+'imagelist_description' => 'Beschrijving',
+'imagelist_search_for' => 'Zoek naar bestand:',
+
+# Mime search
+#
+'mimesearch' => 'Zoeken op MIME-type',
+'mimetype' => 'MIME-type:',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Pagina\'s die niet op een volglijst staan',
+
+# List redirects
+'listredirects' => 'Lijst van doorverwijzingen',
+
+# Unused templates
+'unusedtemplates' => 'Ongebruikte sjablonen',
+'unusedtemplatestext' => 'Deze pagina geeft alle pagina\'s weer in de naamruimte sjabloon die op geen enkele pagina gebruikt worden. Vergeet niet de "Links naar deze pagina" te controleren alvorens dit sjabloon te verwijderen.',
+'unusedtemplateswlh' => 'andere links',
+
+# Random redirect
+'randomredirect' => 'Willekeurige doorverwijzing',
+
+# Statistics
+#
+'statistics' => 'Statistieken',
+'sitestats' => 'Statistieken betreffende {{SITENAME}} NL',
+'userstats' => 'Gebruikerstatistieken',
+'sitestatstext' => 'In de database staan \'\'\'$1\'\'\' pagina\'s, inclusief overlegpagina\'s, pagina\'s over {{SITENAME}}, beginnetjes, doorverwijzingen en andere pagina\'s die waarschijnlijk geen content zijn.
+Er zijn waarschijnlijk \'\'\'$2\'\'\' pagina\'s met echte content.
+
+Er zijn \'\'\'$8\'\'\' bestanden toegevoegd.
+
+Er zijn \'\'\'$3\'\'\' pagina\'s getoond en \'\'\'$4\'\'\' bewerkingen gemaakt sinds de wiki is opgezet.
+Dat komt uit op gemiddeld \'\'\'$5\'\'\' bewerkingen per pagina en \'\'\'$6\'\'\' getoonde pagina\'s per bewerking.
+
+De lengte van de [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] is \'\'\'$7\'\'\'.',
+'userstatstext' => "Er zijn $1 geregistreerde gebruikers; hiervan zijn er '''$2''' (of '''$4%''') $5.",
+'statistics-mostpopular'=> 'Meest bekeken pagina\'s',
+
+'disambiguations' => 'Doorverwijspagina\'s',
+'disambiguationspage' => 'Template:Disambig',
+'disambiguationstext' => 'Hieronder staan pagina\'s die verwijzen naar een <i>disambiguation page</i>. Deze horen waarschijnlijk direct naar het juiste onderwerp te verwijzen. <br />Als doorverwijspagina\'s worden de pagina\'s beschouwd waar $1 in voorkomt.<br />Verwijzingen vanuit andere naamruimtes worden hier niet getoond.',
+
+'doubleredirects' => 'Dubbele doorverwijzingen',
+'doubleredirectstext' => 'Op elke regel staat de eerste doorverwijspagina, de tweede doorverwijspagina en de eerste regel van de tweede doorverwijzing. Meestal is laatste pagina het eigenlijke doel.',
+
+'brokenredirects' => 'Onjuiste doorverwijzingen',
+'brokenredirectstext' => 'Hieronder staan doorverwijspagina\'s die een doorverwijzing bevatten naar een niet-bestaande pagina.',
+
+# Miscellaneous special pages
+#
+'ncategories' => '$1 {{PLURAL:$1|categorie|categorieën}}',
+'nlinks' => '{{FORMATNUM|$1}} {{PLURAL:$1|verwijzing|verwijzingen}}',
+'nmembers' => '$1 {{PLURAL:$1|item|items}}',
+'nrevisions' => '$1 {{PLURAL:$1|versie|versies}}',
+'nviews' => '$1 keer bekeken',
+
+'lonelypages' => 'Weespagina\'s',
+'lonelypagestext' => 'Naar de onderstaande pagina\'s wordt vanuit deze wiki niet verwezen.',
+'uncategorizedpages' => 'Niet-gecategoriseerde pagina\'s',
+'uncategorizedcategories'=> 'Niet-gecategoriseerde categorieën',
+'uncategorizedimages' => 'Niet-gecatoriseerde afbeeldingen',
+'unusedcategories' => 'Ongebruikte categorieën',
+'unusedimages' => 'Ongebruikte bestanden',
+'popularpages' => 'Populaire pagina\'s',
+'wantedcategories' => 'Niet-bestaande categorieën met de meeste verwijzingen',
+'wantedpages' => 'Niet-bestaande pagina\'s met de meeste verwijzingen',
+'mostlinked' => 'Pagina\'s waar het meest naar verwezen wordt',
+'mostlinkedcategories' => 'Categorieën waar het meest naar verwezen wordt',
+'mostcategories' => 'Pagina\'s met de meeste categorieën',
+'mostimages' => 'Meest gebruikte bestanden',
+'mostrevisions' => 'Pagina\'s met de meeste bewerkingen',
+'allpages' => 'Alle pagina\'s',
+'prefixindex' => 'Prefix-index',
+'randompage' => 'Willekeurige pagina',
+'shortpages' => 'Korte pagina\'s',
+'longpages' => 'Lange pagina\'s',
+'deadendpages' => 'Pagina\'s zonder links',
+'deadendpagestext' => 'De onderstaande pagina\'s verwijzen niet naar andere pagina\'s in deze wiki.',
+'listusers' => 'Gebruikerslijst',
+'specialpages' => 'Speciale pagina\'s',
+'spheading' => 'Speciale pagina\'s voor alle gebruikers',
+'restrictedpheading' => 'Speciale pagina\'s met beperkte toegang',
+'recentchangeslinked' => 'Volg links',
+'rclsub' => '(van pagina\'s waarnaar "$1" verwijst)',
+'newpages' => 'Nieuwe pagina\'s',
+'newpages-username' => 'Gebruikersnaam:',
+'ancientpages' => 'Oudste pagina\'s',
+'intl' => 'Taallinks',
+'move' => 'Hernoem',
+'movethispage' => 'Hernoem pagina',
+'unusedimagestext' => '<p>Let op! Het is mogelijk dat er via een directe link verwezen wordt naar een bestand. Een bestand kan hier dus ten onrechte opgenomen zijn.',
+'unusedcategoriestext' => 'Hieronder staan categorieën die zijn aangemaakt, maar door geen enkele pagina of andere categorie gebruikt worden.',
+
+'booksources' => 'Boekinformatie',
+'categoriespagetext' => 'Deze wiki kent de volgende categorieën.',
+'data' => 'Gegevens',
+'userrights' => 'Gebruikersrechtenbeheer',
+'groups' => 'Gebruikersgroepen',
+
+'booksourcetext' => 'Hieronder staan verwijzingen naar andere sites waar nieuwe en gebruikte boeken verkocht worden. Mogelijk is er ook verdere informatie te vinden over boeken waar u naar op zoek bent.',
+'alphaindexline' => '$1 tot $2',
+'version' => 'Softwareversie',
+'log' => 'Logboeken',
+'alllogstext' => 'Dit is het gecombineerde logboek. U kunt ook kiezen voor specifieke logboeken en filteren op gebruiker en paginanaam.',
+'logempty' => 'Er zijn geen regels in het logboek die voldoen aan deze criteria.',
+
+# Special:Allpages
+'nextpage' => 'Volgende pagina ($1)',
+'allpagesfrom' => 'Toon pagina\'s vanaf:',
+'allarticles' => 'Alle pagina\'s',
+'allinnamespace' => 'Alle pagina\'s (naamruimte $1)',
+'allnotinnamespace' => 'Alle pagina\'s (niet in naamruimte $1)',
+'allpagesprev' => 'Vorige',
+'allpagesnext' => 'Volgende',
+'allpagessubmit' => 'OK',
+'allpagesprefix' => 'Toon pagina\'s die beginnen met:',
+'allpagesbadtitle' => 'De opgegeven paginanaam is ongeldig of had een intertaal of interwiki voorvoegsel. Mogelijk bevatte de naam karakters die niet gebruikt mogen worden in paginanamen.',
+
+# Special:Listusers
+'listusersfrom' => 'Toon gebruikers vanaf:',
+
+# E this user
+#
+'mailnologin' => 'Geen verzendadres beschikbaar',
+'mailnologintext' => 'U dient [[Special:Userlogin|aangemeld]] te zijn en een geldig e-mailadres in uw [[Special:Preferences|voorkeuren]] te vermelden om andere gebruikers te mailen.',
+'emailuser' => 'E-mail deze gebruiker',
+'emailpage' => 'E-mail gebruiker',
+'emailpagetext' => 'Als deze gebruiker een geldig e-mailadres heeft opgegeven dan kunt u via dit formulier een bericht verzenden. Het e-mailadres dat u heeft opgegeven bij uw voorkeuren wordt als afzender gebruikt.',
+'usermailererror' => 'Foutmelding bij het verzenden:',
+'defemailsubject' => '{{SITENAME}} e-mail',
+'noemailtitle' => 'Van deze gebruiker is geen e-mailadres bekend',
+'noemailtext' => 'Deze gebruiker heeft geen e-mailadres opgegeven of wil geen e-mail ontvangen van andere gebruikers.',
+'emailfrom' => 'Van',
+'emailto' => 'Aan',
+'emailsubject' => 'Onderwerp',
+'emailmessage' => 'Bericht',
+'emailsend' => 'Verstuur',
+'emailsent' => 'E-mail verzonden',
+'emailsenttext' => 'Uw e-mail is verzonden.',
+
+# Watchlist
+'watchlist' => 'Volglijst',
+'watchlistfor' => "(voor '''$1''')",
+'nowatchlist' => 'Uw volglijst is leeg.',
+'watchlistanontext' => '$1 is verplicht om uw volglijst in te zien of te wijzigen.',
+'watchlistcount' => "'''Uw volglijst bevat {{PLURAL:$1|één pagina|$1 pagina's}}, inclusief overlegpagina's.'''",
+'clearwatchlist' => 'Wis volglijst',
+'watchlistcleartext' => 'Weet u zeker dat u ze wilt verwijderen?',
+'watchlistclearbutton' => 'Wis volglijst',
+'watchlistcleardone' => "Uw volglijst is gewist. Er {{PLURAL:$1|is één pagina|zijn $1 pagina's}} verwijderd).",
+'watchnologin' => 'U bent niet aangemeld',
+'watchnologintext' => 'U dient [[Special:Userlogin|aangemeld]] te zijn om uw volglijst te bewerken.',
+'addedwatch' => 'Toegevoegd aan volglijst',
+'addedwatchtext' => 'De pagina "[[:$1]]" is toegevoegd aan uw [[Special:Watchlist|volglijst]].
+Toekomstige bewerkingen van deze pagina en de bijbehorende overlegpagina worden op [[Special:Watchlist|uw volglijst]] vermeld en worden \'\'\'vet\'\'\' weergegeven in de [[Special:Recentchanges|lijst van recente wijzigingen]].
+
+Indien u een pagina niet langer wilt volgen, ga dan naar de pagina en klik op "Niet volgen" in de menubalk.',
+'removedwatch' => 'Verwijderd van volglijst',
+'removedwatchtext' => 'De pagina "[[:$1]]" is van uw volglijst verwijderd.',
+'watch' => 'Volg',
+'watchthispage' => 'Volg deze pagina',
+'unwatch' => 'Niet volgen',
+'unwatchthispage' => 'Niet meer volgen',
+'notanarticle' => 'Is geen pagina',
+'watchnochange' => 'Geen van de pagina\'s op uw volglijst is in deze periode bewerkt.',
+'watchdetails' => '* Er {{PLURAL:$1|staat één pagina|staan $1 pagina\'s}} op uw volglijst, exclusief overlegpagina\'s
+* [[Special:Watchlist/edit|Toon en bewerk de volledige volglijst]]
+* [[Special:Watchlist/clear|Verwijder alle pagina\'s van de volglijst]]',
+'wlheader-enotif' => '* U wordt per e-mail gewaarschuwd',
+'wlheader-showupdated' => '* Pagina\'s die zijn bewerkt sinds uw laatste bezoek worden \'\'\'vet\'\'\' weergegeven',
+'watchmethod-recent' => 'controleer recente wijzigingen op pagina\'s op volglijst',
+'watchmethod-list' => 'controleer pagina\'s op volglijst op wijzigingen',
+'removechecked' => 'Verwijderen',
+'watchlistcontains' => 'Er staan $1 pagina\'s op uw volglijst.',
+'watcheditlist' => 'Hieronder staan alle pagina\'s op uw volglijst, alfabetisch gesorteerd. Vink de vakjes aan voor de pagina\'s die u wilt verwijderen en druk dan op \'Verwijderen\' onderaan deze pagina. Door een pagina te verwijderen, verwijdert u ook het volgen van de bijbehorende overlegpagina en vice versa.',
+'removingchecked' => 'De aangegeven pagina\'s worden van uw volglijst verwijderd...',
+'couldntremove' => 'Het was niet mogelijk object \'$1\' te verwijderen...',
+'iteminvalidname' => 'Probleem met object \'$1\', ongeldige naam...',
+'wlnote' => 'Hieronder staan de laatste $1 wijzigingen in de laatste $2 uur.',
+'wlshowlast' => 'Toon de laatste $1 uur $2 dagen $3',
+'wlsaved' => 'Dit is een opgeslagen versie van uw volglijst.',
+'wlhideshowown' => '$1 mijn bewerkingen.',
+'wlhideshowbots' => '$1 botbewerkingen.',
+'wldone' => 'Uitgevoerd.',
+
+'enotif_mailer' => '{{SITENAME}} waarschuwingssysteem',
+'enotif_reset' => 'Markeer alle pagina\'s als bezocht',
+'enotif_newpagetext' => 'Dit is een nieuwe pagina.',
+'changed' => 'gewijzigd',
+'created' => 'aangemaakt',
+'enotif_subject' => 'Pagina $PAGETITLE op {{SITENAME}} is $CHANGEDORCREATED door $PAGEEDITOR',
+'enotif_lastvisited' => 'Zie $1 voor alle wijzigingen sinds uw laatste bezoek.',
+'enotif_body' => 'Beste $WATCHINGUSERNAME,
+
+De pagina $PAGETITLE op {{SITENAME}} is $CHANGEDORCREATED op $PAGEEDITDATE door $PAGEEDITOR, zie $PAGETITLE_URL voor de huidige versie.
+
+$NEWPAGE
+
+Samenvatting van de wijziging: $PAGESUMMARY $PAGEMINOREDIT
+
+Contactgevevens van de auteur:
+E-mail: $PAGEEDITOR_EMAIL
+Wiki: $PAGEEDITOR_WIKI
+
+Tenzij u deze pagina bezoekt komen er geen verdere berichten. Op uw volglijst kunt u voor alle gevolgde pagina\'s de waarschuwingsinstellingen opschonen.
+
+ Groet van uw {{SITENAME}} waarschuwingssysteem.
+
+--
+U kunt uw volglijstinstellingen wijzigen op:
+{{fullurl:Special:Watchlist/edit}}
+
+Feedback en andere assistentie:
+{{fullurl:Help:Contents}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Verwijder pagina',
+'confirm' => 'Bevestig',
+'excontent' => 'De inhoud was: \'$1\'',
+'excontentauthor' => 'inhoud was: \'$1\' (\'$2\' was de enige auteur)',
+'exbeforeblank' => 'De inhoud was: \'$1\'',
+'exblank' => 'pagina was leeg',
+'confirmdelete' => 'Bevestig verwijdering',
+'deletesub' => '("$1" aan het verwijderen)',
+'historywarning' => 'Waarschuwing: de pagina die u wilt verwijderen heeft meerdere versies:',
+'confirmdeletetext' => 'U staat op het punt een pagina of bestand voorgoed te verwijderen, inclusief de geschiedenis. Bevestig hieronder dat dit inderdaad uw bedoeling is, dat u de gevolgen begrijpt en dat uw verwijdering overeenkomt met het beleid op deze wiki.',
+'actioncomplete' => 'Handeling voltooid.',
+'deletedtext' => '"$1" is verwijderd. Zie $2 voor een overzicht van recente verwijderingen.',
+'deletedarticle' => 'verwijderde "[[$1]]"',
+'dellogpage' => 'Logboek verwijderde pagina\'s',
+'dellogpagetext' => 'Hieronder staan recent verwijderde pagina\'s en bestanden.',
+'deletionlog' => 'logboek verwijderde pagina\'s',
+'reverted' => 'Eerdere versie hersteld',
+'deletecomment' => 'Reden voor verwijderen',
+'imagereverted' => 'Herstel naar de eerdere versie is geslaagd.',
+'rollback' => 'Wijzigingen ongedaan maken',
+'rollback_short' => 'Terugdraaien',
+'rollbacklink' => 'terugdraaien',
+'rollbackfailed' => 'Ongedaan maken van wijzigingen mislukt.',
+'cantrollback' => 'Ongedaan maken van wijzigingen onmogelijk: deze pagina heeft slechts 1 auteur.',
+'alreadyrolled' => 'Het is niet mogelijk om de bewerking van de pagina [[:$1]] door [[User:$2|$2]] ([[User talk:$2|overleg]]) ongedaan te maken. Iemand anders heeft deze pagina al bewerkt of hersteld naar een eerdere versie.
+
+De meest recente bewerking is gemaakt door [[User:$3|$3]] ([[User talk:$3|overleg]]).',
+'editcomment' => 'Bewerkingssamenvatting: "<i>$1</i>".',
+'revertpage' => 'Wijzigingen door [[Special:Contributions/$2|$2]] hersteld tot de laatste versie door [[User:$1|$1]].',
+'sessionfailure' => 'Er lijkt een probleem te zijn met uw aanmeldsessie. Uw handeling is gestopt uit voorzorg tegen een beveiligingsrisico (dat bestaat uit mogelijke "hijacking" van deze sessie). Ga een pagina terug, laad die pagina opnieuw en probeer het nog eens.',
+'protectlogpage' => 'Logboek beveiligde pagina\'s',
+'protectlogtext' => 'Hieronder staan pagina\'s die recentelijk beveiligd zijn, of waarvan de beveiliging is opgeheven.',
+'protectedarticle' => '"[[$1]]" beveiligd',
+'unprotectedarticle' => 'beveiliging "[[$1]]" opgeheven',
+'protectsub' => '(Beveilig "$1")',
+'confirmprotecttext' => 'Wilt u deze pagina inderdaad beveiligen?',
+'confirmprotect' => 'Bevestig beveiliging',
+'protectmoveonly' => 'Alleen beveiligen tegen hernoemen',
+'protectcomment' => 'Reden voor beveiligen',
+'unprotectsub' => '(Beveiliging "$1" opgeheven)',
+'confirmunprotecttext' => 'Wilt u inderdaad de beveiliging van deze pagina opheffen?',
+'confirmunprotect' => 'Bevestig opheffen beveiliging',
+'unprotectcomment' => 'Reden voor opheffen beveiliging',
+'protect-unchain' => 'Maak hernoemen mogelijk',
+'protect-text' => 'Hier kunt u het beveiligingsniveau voor de pagina <strong>$1</strong> bekijken en wijzigen.',
+'protect-viewtext' => 'U heeft geen rechten om de beveiliging te wijzigen. Dit zijn de huidige beveiligingsinstellingen voor <strong>$1</strong>:',
+'protect-default' => '(standaard)',
+'protect-level-autoconfirmed'=> 'Blokkeer niet-geregistreerde gebruikers',
+'protect-level-sysop' => 'Alleen beheerders',
+
+# restrictions (nouns)
+'restriction-edit' => 'Bewerk',
+'restriction-move' => 'Hernoem',
+
+# Undelete
+'undelete' => 'Toon verwijderde pagina\'s',
+'undeletepage' => 'Verwijderde pagina\'s tonen en terugplaatsen',
+'viewdeletedpage' => 'Toon verwijderde pagina\'s',
+'undeletepagetext' => 'Hieronder staan pagina\'s die zijn verwijderd en vanuit het archief teruggeplaatst kunnen worden.',
+'undeleteextrahelp' => 'Om de hele pagina inclusief alle eerdere versies terug te plaatsen: laat alle hokjes onafgevinkt en klik op \'\'\'\'\'Terugplaatsen\'\'\'\'\'. Om slechts bepaalde versies terug te zetten: vink de terug te plaatsen versies aan en klik op \'\'\'\'\'Terugplaatsen\'\'\'\'\'. Als u op \'\'\'\'\'Reset\'\'\'\'\' klikt wordt het toelichtingsveld leeggemaakt en worden alle versies gedeselecteerd.',
+'undeletearticle' => 'Verwijderde pagina terugplaatsen',
+'undeleterevisions' => '$1 versies gearchiveerd',
+'undeletehistory' => 'Als u een pagina terugplaatst, worden alle versies hersteld. Als er al een nieuwe pagina met dezelfde naam is aangemaakt, worden deze versies teruggeplaatst en blijft de huidige versie in tact.',
+'undeletehistorynoadmin'=> 'Deze pagina is verwijderd. De reden hiervoor staat hieronder, samen met de details van de gebruikers die deze pagina hebben bewerkt vóór de verwijdering. De verwijderde inhoud van de pagina is alleen zichtbaar voor beheerders.',
+'undeleterevision' => 'Verwijderde versie van $1',
+'undeletebtn' => 'Terugplaatsen',
+'undeletecomment' => 'Toelichting:',
+'undeletedarticle' => '"[[$1]]" is teruggeplaatst',
+'undeletedrevisions' => '$1 versies teruggeplaatst',
+'undeletedrevisions-files'=> '$1 versies en $2 bestand(en) teruggeplaatst',
+'undeletedfiles' => '$1 bestand(en) teruggeplaatst',
+'cannotundelete' => 'Verwijderen mislukt. Misschien heeft een andere gebruiker de pagina al verwijderd.',
+'undeletedpage' => '<big>\'\'\'$1 is teruggeplaatst\'\'\'</big>
+
+In het [[Special:Log/delete|verwijderlogboek]] staan recente verwijderingen en herstelhandelingen.',
+
+# Namespace form on various pages
+'namespace' => 'Naamruimte:',
+'invert' => 'Omgekeerde selectie',
+
+# Contributions
+#
+'contributions' => 'Bijdragen gebruiker',
+'mycontris' => 'Mijn bijdragen',
+'contribsub' => 'Voor $1',
+'nocontribs' => 'Geen wijzigingen gevonden die aan de gestelde criteria voldoen.',
+'ucnote' => 'Hieronder staan de laatste <b>$1</b> wijzigingen van deze gebruiker in de laatste <b>$2</b> dagen.',
+'uclinks' => 'Toon de laatste $1 wijzigingen; toon de laatste $2 dagen.',
+'uctop' => ' (laatste wijziging)',
+'newbies' => 'nieuwelingen',
+'sp-newimages-showfrom' => 'Toon nieuwe afbeeldingen vanaf $1',
+'sp-contributions-newest'=> 'Nieuwste',
+'sp-contributions-oldest'=> 'Oudste',
+'sp-contributions-newer'=> '$1 nieuwere',
+'sp-contributions-older'=> '$1 oudere',
+'sp-contributions-newbies-sub'=> 'Voor nieuwelingen',
+
+# What links here
+#
+'whatlinkshere' => 'Verwijzingen naar deze pagina',
+'notargettitle' => 'Geen doelpagina',
+'notargettext' => 'U heeft niet opgegeven voor welke pagina of gebruiker u deze handeling wilt uitvoeren.',
+'linklistsub' => '(Lijst van verwijzingen)',
+'linkshere' => "De volgende pagina's verwijzen naar '''[[:$1]]''':",
+'nolinkshere' => "Geen enkele pagina verwijst naar '''[[:$1]]'''.",
+'isredirect' => 'redirectpagina',
+'istemplate' => 'ingevoegd als sjabloon',
+
+# Block/unblock IP
+#
+'blockip' => 'Gebruiker blokkeren',
+'blockiptext' => 'Gebruik het onderstaande formulier om schrijftoegang voor een gebruiker of IP-adres in te trekken. Doe dit alleen als bescherming tegen vandalisme en in overeenstemming met het [[Project:Policy|beleid]].
+Geef hieronder een reden op (bijvoorbeeld welke pagina\'s gevandaliseerd zijn).',
+'ipaddress' => 'IP-adres',
+'ipadressorusername' => 'IP-adres of gebruikersnaam',
+'ipbexpiry' => 'Duur (maak een keuze)',
+'ipbreason' => 'Reden',
+'ipbanononly' => 'Blokkeer alleen anonieme gebruikers',
+'ipbcreateaccount' => 'Voorkomen aanmaken gebruikers',
+'ipbsubmit' => 'Blokkeer deze gebruiker',
+'ipbother' => 'Andere duur',
+'ipboptions' => '15 minuten:15 min,1 uur:1 hour,2 uur:2 hours,6 uur:6 hours,12 uur:12 hours,1 dag:1 day,3 dagen:3 days,1 week:1 week,2 weken:2 weeks,1 maand:1 month,3 maanden:3 months,6 maanden:6 months,1 jaar:1 year,onbeperkt:infinite',
+'ipbotheroption' => 'ander verloop',
+'badipaddress' => 'Geen geldig IP-adres',
+'blockipsuccesssub' => 'Blokkering geslaagd',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] is geblokkeerd.<br />
+Zie de [[Special:Ipblocklist|Lijst van geblokkeerde IP-adressen]].',
+'unblockip' => 'Deblokkeer gebruiker',
+'unblockiptext' => 'Gebruik het onderstaande formulier om opnieuw schrijftoegang te geven aan een geblokkeerde gebruiker of IP-adres.',
+'ipusubmit' => 'Blokkade van dit adres opheffen.',
+'unblocked' => 'Blokkade van [[User:$1|$1]] is opgeheven',
+'ipblocklist' => 'Lijst van geblokkeerde gebruikers en IP-adressen.',
+'blocklistline' => 'Op $1 blokkeerde $2: $3 ($4)',
+'infiniteblock' => 'onbeperkt',
+'expiringblock' => 'verloopt op $1',
+'anononlyblock' => 'alleen anoniemen',
+'createaccountblock' => 'gebruikers aanmaken geblokkeerd',
+'ipblocklistempty' => 'Het blokkeerlogboek is leeg.',
+'blocklink' => 'blokkeer',
+'unblocklink' => 'deblokkeer',
+'contribslink' => 'bijdragen',
+'autoblocker' => 'Automatisch geblokkeerd omdat het IP-adres overeenkomt met dat van [[User:$1|$1]], die geblokkeerd is om de volgende reden: "\'\'\'$2\'\'\'"',
+'blocklogpage' => 'Blokkeerlogboek',
+'blocklogentry' => '"[[$1]]" is geblokkeerd voor de duur van $2.',
+'blocklogtext' => 'Hier ziet u een lijst van de recente blokkeringen en deblokkeringen. Automatische blokkeringen en deblokkeringen komen niet in het logboek. Zie de [[Special:Ipblocklist|Ipblocklist]] voor op dit moment geblokkeerde adressen.',
+'unblocklogentry' => 'blokkade van $1 opgeheven',
+'range_block_disabled' => 'De mogelijkheid voor beheerders om een groep IP-addressen te blokkeren is uitgeschakeld.',
+'ipb_expiry_invalid' => 'Ongeldige duur.',
+'ipb_already_blocked' => '"$1" is al geblokkeerd',
+'ip_range_invalid' => 'Ongeldige IP-reeks.',
+'proxyblocker' => 'Proxyblocker',
+'ipb_cant_unblock' => 'Fout: BlokkadeID $1 niet aangetroffen. Wellicht is de blokkade al opgeheven.',
+'proxyblockreason' => 'Dit is een automatische preventieve blokkade omdat u gebruik maakt van een open proxyserver. Neem a.u.b. contact op met uw Internet provider of uw helpdesk en stel die op de hoogte van dit ernstige beveiligingsprobleem.',
+'proxyblocksuccess' => 'Geslaagd.',
+'sorbs' => 'SORBS DNS-blacklist',
+'sorbsreason' => 'Uw IP-adres is opgenomen in de [http://www.sorbs.net SORBS DNS-blacklist] als open proxyserver.',
+'sorbs_create_account_reason'=> 'Uw IP-adres is opgenomen in de [http://www.sorbs.net SORBS DNS-blacklist] als open proxyserver. U kunt geen account aanmaken.',
+
+# Developer tools
+#
+'lockdb' => 'Blokkeer de database',
+'unlockdb' => 'Blokkering van de database opheffen',
+'lockdbtext' => 'Waarschuwing: De database blokkeren heeft tot gevolg dat geen enkele gebruiker meer in staat is pagina\'s te bewerken, voorkeuren te wijzigen of iets anders te doen waarvoor wijzigingen in de database nodig zijn.
+
+Bevestig dat u deze handeling wilt uitvoeren en dat u de database vrijgeeft nadat het onderhoud is uitgevoerd.',
+'unlockdbtext' => 'Na het vrijgeven van de database kunnen gebruikers weer pagina\'s bewerken, hun voorkeuren wijzigen of iets anders te doen waarvoor er wijzigingen in de database nodig zijn.
+
+Bevestig dat u deze handeling wilt uitvoeren.',
+'lockconfirm' => 'Ja, ik wil de database blokkeren.',
+'unlockconfirm' => 'Ja, ik wil de database vrijgeven.',
+'lockbtn' => 'Blokkeer de database',
+'unlockbtn' => 'Geef de database vrij',
+'locknoconfirm' => 'U heeft uw keuze niet bevestigd via het vinkvakje.',
+'lockdbsuccesssub' => 'Blokkeren database geslaagd',
+'unlockdbsuccesssub' => 'Database vrijgegeven.',
+'lockdbsuccesstext' => 'De database is geblokkeerd.
+<br />Vergeet niet de database vrij te geven zodra u klaar bent met uw onderhoud.',
+'unlockdbsuccesstext' => 'De database is vrijgegeven.',
+'lockfilenotwritable' => 'Geen schrijfrechten op het databaselockbestand. Om de database te blokkeren of de blokkade op te heffen, dient er geschreven te kunnen worden door de webserver.',
+'databasenotlocked' => 'De database is niet geblokkeerd.',
+
+# Make sysop
+'makesysoptitle' => 'Maak een gebruiker beheerder',
+'makesysoptext' => 'Dit formulier wordt door bureaucraten gebruikt om een gebruiker beheerder te maken. Geef de naam van een gebruiker in het veld in en klik op de knop om de gebruiker beheerder te maken.',
+'makesysopname' => 'Gebruikersnaam:',
+'makesysopsubmit' => 'Wijzig de gebruikersrechten',
+'makesysopok' => '<b>Gebruiker "$1" is nu beheerder</b>',
+'makesysopfail' => '<b>Gebruiker "$1" kon geen beheerder gemaakt worden. Heeft u de juiste naam opgegeven?</b>',
+'setbureaucratflag' => 'Maak deze gebruiker ook bureaucraat',
+'rightslog' => 'Gebruikersrechtenlogboek',
+'rightslogtext' => 'Hieronder staan de wijzigingen in gebruikersrechten.',
+'rightslogentry' => 'wijzigde de gebruikersrechten voor $1 van $2 naar $3',
+'rights' => 'Rechten:',
+'set_user_rights' => 'Gebruikersrechten aanpassen',
+'user_rights_set' => '<b>Rechten van gebruiker "$1" bijgewerkt</b>',
+'set_rights_fail' => '<b>Gebruikersrechten voor "$1" konden niet worden aangepast. Heeft u de naam juist ingevoerd?</b>',
+'makesysop' => 'Maak een gebruiker beheerder',
+'already_sysop' => 'Deze gebruiker is al beheerder',
+'already_bureaucrat' => 'Deze gebruiker is al bureaucraat',
+'rightsnone' => '(geen)',
+
+# Move page
+#
+'movepage' => 'Hernoem pagina',
+'movepagetext' => 'Door middel van het onderstaande formulier kunt u een pagina hernoemen. De geschiedenis gaat mee naar de nieuwe pagina. De oude naam wordt automatisch een doorverwijzing naar de nieuwe pagina. Verwijzingen naar de oude pagina worden niet aangepast. Controleer na het hernoemen of er geen dubbele of onjuiste doorverwijzingen zijn onstaan. U bent verantwoordelijk voor de continuiteït van de verwijzingen.
+
+Een wijziging van de paginanaam kan \'\'\'alleen\'\'\' worden uitgevoerd als de nieuwe paginanaam:
+*nog niet bestaat, of
+*slechts een doorverwijspagina zonder verdere geschiedenis is.
+
+<b>WAARSCHUWING!</b>
+Voor populaire pagina\'s kan het hernoemen drastische en onvoorziene gevolgen hebben. Zorg ervoor dat u de consequenties overziet voordat u deze handeling uitvoert.',
+'movepagetalktext' => 'De bijbehorende overlegpagina krijgt automatisch een andere naam, \'\'\'tenzij\'\'\':
+* De overlegpagina onder de nieuwe naam al bestaat;
+* U het onderstaande vinkje deselecteert.',
+'movearticle' => 'Hernoem pagina',
+'movenologin' => 'Niet aangemeld',
+'movenologintext' => 'U dient [[Special:Userlogin|aangemeld]] te zijn om een pagina te hernoemen.',
+'newtitle' => 'Naar de nieuwe paginanaam',
+'movepagebtn' => 'Hernoem pagina',
+'pagemovedsub' => 'Hernoemen pagina geslaagd',
+'pagemovedtext' => 'Pagina "[[$1]]" is hernoemd naar "[[$2]]".',
+'articleexists' => 'De pagina bestaat al of de paginanaam is ongeldig.
+Kies a.u.b. een andere paginanaam.',
+'talkexists' => '\'\'\'De pagina is hernoemd, maar de overlegpagina kon niet hernoemd worden omdat er al een pagina met de nieuwe naam bestaat. Combineer de overlegpagina\'s a.u.b. handmatig.\'\'\'',
+'movedto' => 'hernoemd naar',
+'movetalk' => 'Hernoem de bijbehorende overlegpagina',
+'talkpagemoved' => 'De bijbehorende overlegpagina is ook hernoemd.',
+'talkpagenotmoved' => 'De bijhorende overlegpagina is <strong>niet</strong> hernoemd.',
+'1movedto2' => '[[$1]] hernoemd naar [[$2]]',
+'1movedto2_redir' => '[[$1]] hernoemd over de doorverwijzing [[$2]]',
+'movelogpage' => 'Logboek hernoemde pagina\'s',
+'movelogpagetext' => 'Hieronder staan hernoemde pagina\'s.',
+'movereason' => 'Reden',
+'revertmove' => 'terugdraaien',
+'delete_and_move' => 'Verwijderen en hernoemen',
+'delete_and_move_text' => '==Verwijdering nodig==
+Onder de naam "[[$1]]" bestaat al een pagina. Wilt u het verwijderen om plaats te maken voor de te hernoemen pagina?',
+'delete_and_move_confirm'=> 'Ja, verwijder de pagina',
+'delete_and_move_reason'=> 'Verwijderd in verband met hernoeming',
+'selfmove' => 'U kunt een pagina niet hernoemen naar dezelfde paginanaam.',
+'immobile_namespace' => 'De bron- of doelpaginanaam is van een speciaal type. Een pagina kan niet hernoemd worden naar of van die naamruimte.',
+
+# Export
+'export' => 'Exporteren',
+'exporttext' => 'U kunt de tekst en geschiedenis van een pagina of pagina\'s exporteren naar XML. Dit exportbestand is daarna te importeren in een andere MediaWiki via de pagina Special:Import.
+
+Geef in het onderstaande veld de namen van de te exporteren pagina\'s op, één pagina per regel, en geef aan of u alle versies met de bewerkingssamenvatting of alleen de huidige versies met de bewerkingssamenvatting wilt exporteren.
+
+In het laatste geval kunt u ook een link gebruiken, bijvoorbeeld [[Special:Export/{{Mediawiki:Mainpage}}]] voor de pagina {{Mediawiki:Mainpage}}.',
+'exportcuronly' => 'Alleen de laatste versie, niet de volledige geschiedenis',
+'exportnohistory' => '----
+\'\'\'Let op:\'\'\' het exporteren van de gehele geschiedenis is uitgeschakeld wegens prestatieredenen.',
+'export-submit' => 'Exporteer',
+
+# Namespace 8 related
+'allmessages' => 'Systeemteksten',
+'allmessagesname' => 'Naam',
+'allmessagesdefault' => 'Standaardinhoud',
+'allmessagescurrent' => 'Huidige inhoud',
+'allmessagestext' => 'Hieronder staan de systeemberichten uit de MediaWiki-naamruimte:',
+'allmessagesnotsupportedUI'=> 'De taal die u heeft geselecteerd voor berichten (<b>$1</b>) wordt niet ondersteund door Special:Allmessages op deze wiki.',
+'allmessagesnotsupportedDB'=> 'Er is geen ondersteuning voor Special:AllMessages omdat \'\'\'$wgUseDatabaseMessages\'\'\' is uitgeschakeld.',
+'allmessagesfilter' => 'Bericht naamfilter:',
+'allmessagesmodified' => 'Toon alleen gewijzigde systeemteksten',
+
+# Thumbnails
+'thumbnail-more' => 'Groter',
+'missingimage' => '<b>Afbeelding ontbreekt</b><br /><i>$1</i>',
+'filemissing' => 'Bestand is zoek',
+'thumbnail_error' => 'Fout bij het aanmaken van thumbnail: $1',
+
+# Special:Import
+'import' => 'Pagina\'s importeren',
+'importinterwiki' => 'Transwiki-import',
+'import-interwiki-text' => 'Selecteer een wiki en paginanaam om te importeren.
+Versie- en auteursgegevens blijven hierbij in tact.
+Alle transwiki-importhandelingen worden opgeslagen in het [[Special:Log/import|importlogboek]].',
+'import-interwiki-history'=> 'Kopieer de volledige geschiedenis van deze pagina',
+'import-interwiki-submit'=> 'Importeer',
+'import-interwiki-namespace'=> 'Plaats pagina\'s in de volgende naamruimte:',
+'importtext' => 'Gebruik de functie Special:Export in de wiki waar de informatie vandaan komt, sla de uitvoer op uw eigen systeem op, en voeg die daarna hier toe.',
+'importstart' => 'Pagina\'s aan het importeren...',
+'import-revision-count' => '$1 {{PLURAL:$1|versie|versies}}',
+'importnopages' => 'Geen pagina\'s te importeren.',
+'importfailed' => 'Import is mislukt: $1',
+'importunknownsource' => 'Onbekend importbrontype',
+'importcantopen' => 'Kon het importbestand niet openen',
+'importbadinterwiki' => 'Verkeerde interwikilink',
+'importnotext' => 'Leeg of geen tekst',
+'importsuccess' => 'Import geslaagd.',
+'importhistoryconflict' => 'Er zijn conflicten in de geschiedenis van de pagina (is misschien eerder geïmporteerd)',
+'importnosources' => 'Er zijn geen transwiki-importbronnen gedefinieerd en directe geschiedenis-uploads zijn uitgeschakeld.',
+'importnofile' => 'Er is geen importbestand geüpload.',
+'importuploaderror' => 'Upload van het importbestand in mislukt; mogelijk is het bestand groter is dan de limiet.',
+
+# import log
+'importlogpage' => 'Importlogboek',
+'importlogpagetext' => 'Administratieve import van pagina\'s met geschiedenis van andere wiki\'s.',
+'import-logentry-upload'=> '[[$1]] geïmporteerd via een bestandsupload',
+'import-logentry-upload-detail'=> '$1 versie(s)',
+'import-logentry-interwiki'=> 'transwiki voor $1 geslaagd',
+'import-logentry-interwiki-detail'=> '$1 versie(s) van $2',
+
+# Keyboard access keys for power users
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Doorzoek {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Markeer dit als een kleine wijziging [alt-i]',
+'tooltip-save' => 'Sla uw wijzigingen op [alt-s]',
+'tooltip-preview' => 'Maak een voorvertoning. Gebruik dit! [alt-p]',
+'tooltip-diff' => 'Toon de gemaakte wijzigingen. [alt-v]',
+'tooltip-compareselectedversions'=> 'Toon de verschillen tussen de geselecteerde versies. [alt-v]',
+'tooltip-watch' => 'Voeg deze pagina toe aan uw volglijst [alt-w]',
+
+# stylesheets
+'monobook.css' => '/* Een CSS die hier wordt geplaatst heeft invloed op alle gebruikers van de skin Monobook */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF metadata is uitgeschakeld op deze server.',
+'nocreativecommons' => 'Creative Commons RDF metadata is uitgeschakeld op deze server.',
+'notacceptable' => 'De wikiserver kan de gegevens niet leveren in een vorm die uw client kan lezen.',
+
+# Attribution
+'anonymous' => 'Anonieme gebruiker(s) van {{SITENAME}}',
+'siteuser' => '{{SITENAME}} gebruiker $1',
+'lastmodifiedatby' => 'Deze pagina is het laatst bewerkt op $2, $1 door $3.',
+'and' => 'en',
+'othercontribs' => 'Gebaseerd op werk van $1.',
+'others' => 'anderen',
+'siteusers' => '{{SITENAME}} gebruiker(s) $1',
+'creditspage' => 'Auteurspagina',
+'nocredits' => 'Er is geen auteursinformatie beschikbaar voor deze pagina.',
+
+# Spam protection
+'spamprotectiontitle' => 'Spamfilter',
+'spamprotectiontext' => 'De pagina die u wilde opslaan is geblokkeerd door het spamfilter. Meestal wordt dit door een externe link veroorzaakt.',
+'spamprotectionmatch' => 'De volgende tekst veroorzaakte het alarm van de spamfilter: $1',
+'subcategorycount' => 'Er {{PLURAL:$1|is één ondercategorie|zijn $1 ondercategorieën}} binnen deze categorie.',
+'categoryarticlecount' => 'Er {{PLURAL:$1|staat één onderwerp|staan $1 onderwerpen}} in deze categorie.',
+'listingcontinuesabbrev'=> ' meer',
+'spambot_username' => 'MediaWiki opschoning spam',
+'spam_reverting' => 'Bezig met terugdraaien naar de laatste versie die geen verwijzing heeft naar $1',
+'spam_blanking' => 'Alle wijzigingen met een link naar $1 worden verwijderd',
+
+# Info page
+'infosubtitle' => 'Informatie voor pagina',
+'numedits' => 'Aantal bewerkingen (pagina): $1',
+'numtalkedits' => 'Aantal bewerkingen (overlegpagina): $1',
+'numwatchers' => 'Aantal volgers: $1',
+'numauthors' => 'Aantal auteurs (pagina): $1',
+'numtalkauthors' => 'Aantal verschilende auteurs (overlegpagina): $1',
+
+# Math options
+'mw_math_png' => 'Altijd als PNG weergeven',
+'mw_math_simple' => 'HTML voor eenvoudige formules, anders PNG',
+'mw_math_html' => 'HTML indien mogelijk, anders PNG',
+'mw_math_source' => 'Toon de TeX broncode (voor tekstbrowsers)',
+'mw_math_modern' => 'Aanbevolen methode voor recente browsers',
+'mw_math_mathml' => 'MathML als mogelijk (experimenteel)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Markeer als gecontroleerd',
+'markaspatrolledtext' => 'Markeer deze pagina als gecontroleerd',
+'markedaspatrolled' => 'Gemarkeerd als gecontroleerd',
+'markedaspatrolledtext' => 'De gekozen versie is gemarkeerd als gecontroleerd.',
+'rcpatroldisabled' => 'De controlemogelijkheid op recente wijzigingen is uitgeschakeld.',
+'rcpatroldisabledtext' => 'De mogelijkheid om recente wijzigingen als gecontroleerd aan te merken is op dit ogenblik uitgeschakeld.',
+'markedaspatrollederror'=> 'Kan niet als gecontroleerd worden aangemerkt',
+'markedaspatrollederrortext'=> 'Selecteer een versie om als gecontroleerd aan te merken.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips en sneltoetsen */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Mijn gebruikerspagina\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Gebruikerspagina voor uw IP-adres\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Mijn overlegpagina\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Overlegpagina van de anonieme gebruiker van dit IP-adres\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Mijn voorkeuren\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Pagina\'s die op mijn volglijst staan\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Mijn bijdragen\');
+ ta[\'pt-login\'] = new Array(\'o\',\'U wordt van harte uitgenodigd om u aan te melden als gebruiker, maar dit is niet verplicht\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'U wordt van harte uitgenodigd om u aan te melden als gebruiker, maar dit is niet verplicht\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Afmelden\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Toon de overlegtekst bij deze pagina\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'U kunt deze pagina bewerken. Gebruik a.u.b. de voorbeeldweergaveknop alvorens te bewaren\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Voeg uw opmerking toe aan de overlegpagina\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Deze pagina is beveiligd tegen wijzigen. U kunt de pagina wel inzien\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Eerdere versies van deze pagina\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Beveilig deze pagina tegen wijzigen\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Verwijder deze pagina\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Plaats verwijderde versies van deze pagina terug\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Hernoem deze pagina\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Voeg deze pagina toe aan mijn volglijst\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Verwijder deze pagina van mijn volglijst\');
+ ta[\'search\'] = new Array(\'f\',\'Doorzoek deze wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Hoofdpaginalogo\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Ga naar de Hoofdpagina\');
+ ta[\'n-portal\'] = new Array(\'\',\'Informatie over het project: wie, wat, hoe en waarom\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Achtergrondinformatie over actuele zaken\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Toon recente wijzigingen\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Toon een willekeurige pagina\');
+ ta[\'n-help\'] = new Array(\'\',\'Hulpinformatie over deze wiki\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Ondersteun ons financieel\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Toon verwijzingen naar deze pagina\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Toon wijzigingen van pagina\'s waar deze pagina naar verwijst\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS-feed voor deze pagina\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom-feed voor deze pagina\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Bijdragen van deze gebruiker\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Verzend een e-mail naar deze gebruiker\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Upload bestanden\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Toon alle speciale pagina\'s\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Toon de paginatekst\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Toon de gebruikerspagina\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Toon de mediatekst\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Deze speciale pagina kunt u niet wijzigen\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Toon de projectpagina\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Toon de afbeeldingspagina\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Toon de systeemtekstpagina\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Toon de sjabloonpagina\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Toon de helppagina\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Toon de rubriekpagina\');',
+
+# image deletion
+'deletedrevision' => 'Oude versie $1 verwijderd.',
+
+# browsing diffs
+'previousdiff' => '← Vorige wijziging',
+'nextdiff' => 'Volgende wijziging →',
+
+'imagemaxsize' => 'Maximale grootte beelden op beschrijvingspagina:',
+'thumbsize' => 'Grootte thumbnail:',
+'showbigimage' => 'Download afbeelding in origineel formaat ($1x$2 pixels, $3 kB)',
+
+'newimages' => 'Nieuwe afbeeldingen',
+'noimages' => 'Niets te zien.',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+# variants for Serbian language
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Gebruiker:',
+'speciallogtitlelabel' => 'Paginanaam:',
+
+'passwordtooshort' => 'Uw wachtwoord is te kort. Het moet uit minstens $1 tekens bestaan.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Waarschuwing\'\'\': dit bestand bevat mogelijk programmacode die uw systeem schade kan berokkenen.<hr />',
+'fileinfo' => '$1KB, MIME-type: <code>$2</code>',
+
+# Metadata
+'metadata-help' => 'Dit bestand bevat aanvullende informatie, die door een fotocamera, scanner of fotobewerkingsprogramma toegevoegd kan zijn. Als het bestand is aangepast, dan komen details mogelijk niet overeen met de gewijzigde afbeelding.',
+'metadata-expand' => 'Toon uitgebreide gegevens',
+'metadata-collapse' => 'Verberg uitgebreide gegevens',
+
+# Exif tags
+'exif-imagewidth' => 'Breedte',
+'exif-imagelength' => 'Hoogte',
+'exif-bitspersample' => 'Bits per component',
+'exif-compression' => 'Compressieschema',
+'exif-photometricinterpretation'=> 'Pixelcompositie',
+'exif-orientation' => 'Oriëntatie',
+'exif-samplesperpixel' => 'Aantal componenten',
+'exif-planarconfiguration'=> 'Gegevensstructuur',
+'exif-ycbcrsubsampling' => 'Subsampleverhouding van Y tot C',
+'exif-ycbcrpositioning' => 'Y- en C-positionering',
+'exif-xresolution' => 'Horizontale resolutie',
+'exif-yresolution' => 'Verticale resolutie',
+'exif-resolutionunit' => 'Eenheid X en Y resolutie',
+'exif-stripoffsets' => 'Locatie afbeeldingsgegevens',
+'exif-rowsperstrip' => 'Rijen per strip',
+'exif-stripbytecounts' => 'Bytes per gecomprimeerde strip',
+'exif-jpeginterchangeformat'=> 'Afstand tot JPEG SOI',
+'exif-jpeginterchangeformatlength'=> 'Bytes JPEG-gegevens',
+'exif-transferfunction' => 'Transferfunctie',
+'exif-whitepoint' => 'Witpuntchromaticiteit',
+'exif-primarychromaticities'=> 'Chromaticities of primaries',
+'exif-ycbcrcoefficients'=> 'Transformatiematrixcoëfficiënten voor de kleurruimte',
+'exif-referenceblackwhite'=> 'Paar zwart en wit referentiewaarden',
+'exif-datetime' => 'Tijdstip laatste bestandswijziging',
+'exif-imagedescription' => 'Omschrijving afbeelding',
+'exif-make' => 'Merk camera',
+'exif-model' => 'Cameramodel',
+'exif-software' => 'Gebruikte software',
+'exif-artist' => 'Auteur',
+'exif-copyright' => 'Copyrighthouder',
+'exif-exifversion' => 'Exif-versie',
+'exif-flashpixversion' => 'Ondersteunde Flashpix-versie',
+'exif-colorspace' => 'Kleurruimte',
+'exif-componentsconfiguration'=> 'Betekenis van elke component',
+'exif-compressedbitsperpixel'=> 'Beeldcompressiemethode',
+'exif-pixelydimension' => 'Bruikbare afbeeldingsbreedte',
+'exif-pixelxdimension' => 'Bruikbare afbeeldingshoogte',
+'exif-makernote' => 'Opmerkingen maker',
+'exif-usercomment' => 'Opmerkingen',
+'exif-relatedsoundfile' => 'Bijbehorend audiobestand',
+'exif-datetimeoriginal' => 'Tijdstip gegevensaanmaak',
+'exif-datetimedigitized'=> 'Tijdstip digitalisering',
+'exif-subsectime' => 'Datum tijd subseconden',
+'exif-exposuretime' => 'Belichtingstijd',
+'exif-fnumber' => 'F-getal',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Belichtingsprogramma',
+'exif-spectralsensitivity'=> 'Spectrale gevoeligheid',
+'exif-isospeedratings' => 'ISO/ASA-waarde',
+'exif-oecf' => 'Opto-elektronische conversiefactor',
+'exif-shutterspeedvalue'=> 'Sluitersnelheid',
+'exif-aperturevalue' => 'Diafragma',
+'exif-brightnessvalue' => 'Helderheid',
+'exif-exposurebiasvalue'=> 'Belichtingscompensatie',
+'exif-maxaperturevalue' => 'Maximale diafragma-opening',
+'exif-subjectdistance' => 'Objectafstand',
+'exif-meteringmode' => 'Methode lichtmeting',
+'exif-lightsource' => 'Lichtbron',
+'exif-flash' => 'Flitser',
+'exif-focallength' => 'Brandpuntsafstand',
+'exif-subjectarea' => 'Objectruimte',
+'exif-flashenergy' => 'Flitssterkte',
+'exif-focalplanexresolution'=> 'Brandpuntsvlak-X-resolutie',
+'exif-focalplaneyresolution'=> 'Brandpuntsvlak-Y-resolutie',
+'exif-focalplaneresolutionunit'=> 'Eenheid CCD-resolutie',
+'exif-subjectlocation' => 'Objectlocatie',
+'exif-exposureindex' => 'Belichtingsindex',
+'exif-sensingmethod' => 'Opvangmethode',
+'exif-filesource' => 'Bestandsbron',
+'exif-scenetype' => 'Soort scene',
+'exif-cfapattern' => 'CFA-patroon',
+'exif-customrendered' => 'Aangepaste beeldverwerking',
+'exif-exposuremode' => 'Belichtingsinstelling',
+'exif-whitebalance' => 'Witbalans',
+'exif-digitalzoomratio' => 'Digitale zoomfactor',
+'exif-focallengthin35mmfilm'=> 'Brandpuntsafstand (35mm-equivalent)',
+'exif-scenecapturetype' => 'Soort opname',
+'exif-gaincontrol' => 'Piekbeheersing',
+'exif-saturation' => 'Verzadiging',
+'exif-sharpness' => 'Scherpte',
+'exif-devicesettingdescription'=> 'Omschrijving apparaatinstellingen',
+'exif-subjectdistancerange'=> 'Bereik objectafstand',
+'exif-imageuniqueid' => 'Uniek ID afbeelding',
+'exif-gpsversionid' => 'GPS versienummer',
+'exif-gpslatituderef' => 'Noorder- of zuiderbreedte',
+'exif-gpslatitude' => 'Breedtegraad',
+'exif-gpslongituderef' => 'Ooster- of westerlengte',
+'exif-gpslongitude' => 'Lengtegraad',
+'exif-gpsaltituderef' => 'Hoogtereferentie',
+'exif-gpsaltitude' => 'Hoogte',
+'exif-gpstimestamp' => 'GPS-tijd (atoomklok)',
+'exif-gpssatellites' => 'Gebruikte satellieten voor meting',
+'exif-gpsstatus' => 'Ontvangerstatus',
+'exif-gpsmeasuremode' => 'Meetmodus',
+'exif-gpsdop' => 'Meetprecisie',
+'exif-gpsspeedref' => 'Snelheid eenheid',
+'exif-gpsspeed' => 'Snelheid van GPS-ontvanger',
+'exif-gpstrackref' => 'Referentie voor bewegingsrichting',
+'exif-gpstrack' => 'Bewegingsrichting',
+'exif-gpsimgdirectionref'=> 'Referentie voor afbeeldingsrichting',
+'exif-gpsimgdirection' => 'Afbeeldingsrichting',
+'exif-gpsmapdatum' => 'Gebruikte geodetische onderzoeksgegevens',
+'exif-gpsdestlatituderef'=> 'Referentie voor breedtegraad bestemming',
+'exif-gpsdestlatitude' => 'Breedtegraad bestemming',
+'exif-gpsdestlongituderef'=> 'Referentie voor lengtegraad bestemming',
+'exif-gpsdestlongitude' => 'Lengtegraad bestemming',
+'exif-gpsdestbearingref'=> 'Referentie voor richting naar bestemming',
+'exif-gpsdestbearing' => 'Richting naar bestemming',
+'exif-gpsdestdistanceref'=> 'Referentie voor afstand tot bestemming',
+'exif-gpsdestdistance' => 'Afstand tot bestemming',
+'exif-gpsprocessingmethod'=> 'GPS-verwerkingsmethode',
+'exif-gpsareainformation'=> 'Naam GPS-gebied',
+'exif-gpsdatestamp' => 'GPS-datum',
+'exif-gpsdifferential' => 'Differentiele GPS-correctie',
+
+# Make & model, can be wikified in order to link to the camera and model name
+
+# Exif attributes
+
+'exif-compression-1' => 'Ongecomprimeerd',
+
+'exif-orientation-1' => 'Normaal',
+'exif-orientation-2' => 'Horizontaal gespiegeld',
+'exif-orientation-3' => '180° gedraaid',
+'exif-orientation-4' => 'Verticaal gespiegeld',
+'exif-orientation-5' => 'Gespiegeld om as linksboven-rechtsonder',
+'exif-orientation-6' => '90° rechtsom gedraaid',
+'exif-orientation-7' => 'Gespiegeld om as linksonder-rechtsboven',
+'exif-orientation-8' => '90° linksom gedraaid',
+
+'exif-colorspace-ffff.h'=> 'Niet gecalibreerd',
+'exif-componentsconfiguration-0'=> 'bestaat niet',
+
+'exif-exposureprogram-0'=> 'Niet gedefiniëerd',
+'exif-exposureprogram-1'=> 'Handmatig',
+'exif-exposureprogram-2'=> 'Normaal programma',
+'exif-exposureprogram-3'=> 'Diafragmaprioriteit',
+'exif-exposureprogram-4'=> 'Sluiterprioriteit',
+'exif-exposureprogram-5'=> 'Creatief (voorkeur voor hoge scherpte/diepte)',
+'exif-exposureprogram-6'=> 'Actie (voorkeur voor hoge sluitersnelheid)',
+'exif-exposureprogram-7'=> 'Portret (detailopname met onscherpe achtergrond)',
+'exif-exposureprogram-8'=> 'Landschap (scherpe achtergrond)',
+
+'exif-subjectdistance-value'=> '$1 meter',
+
+'exif-meteringmode-0' => 'Onbekend',
+'exif-meteringmode-1' => 'Gemiddeld',
+'exif-meteringmode-2' => 'Centrumgewogen',
+'exif-meteringmode-4' => 'Multi-spot',
+'exif-meteringmode-5' => 'Multi-segment (patroon)',
+'exif-meteringmode-6' => 'Deelmeting',
+'exif-meteringmode-255' => 'Anders',
+
+'exif-lightsource-0' => 'Onbekend',
+'exif-lightsource-1' => 'Daglicht',
+'exif-lightsource-2' => 'TL-licht',
+'exif-lightsource-3' => 'Tungsten (lamplicht)',
+'exif-lightsource-4' => 'Flits',
+'exif-lightsource-9' => 'Mooi weer',
+'exif-lightsource-10' => 'Bewolkt',
+'exif-lightsource-11' => 'Schaduw',
+'exif-lightsource-12' => 'Daglicht fluorescerend (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Dagwit fluorescerend (N 4600 - 5400K)',
+'exif-lightsource-14' => 'Koel wit fluorescerend (W 3900 - 4500K)',
+'exif-lightsource-15' => 'Wit fluorescerend (WW 3200 - 3700K)',
+'exif-lightsource-17' => 'Standaard licht A',
+'exif-lightsource-18' => 'Standaard licht B',
+'exif-lightsource-19' => 'Standaard licht C',
+'exif-lightsource-255' => 'Andere lichtbron',
+
+'exif-focalplaneresolutionunit-2'=> 'inch',
+
+'exif-sensingmethod-1' => 'Niet gedefiniëerd',
+'exif-sensingmethod-2' => 'Eén-chip-kleursensor',
+'exif-sensingmethod-3' => 'Twee-chip-kleursensor',
+'exif-sensingmethod-4' => 'Drie-chip-kleursensor',
+
+'exif-scenetype-1' => 'Een direct gefotografeerde afbeelding',
+
+'exif-customrendered-0' => 'Normale verwerking',
+'exif-customrendered-1' => 'Aangepaste verwerking',
+
+'exif-exposuremode-0' => 'Automatische belichting',
+'exif-exposuremode-1' => 'Handmatige belichting',
+'exif-exposuremode-2' => 'Auto-Bracket',
+
+'exif-whitebalance-0' => 'Automatische witbalans',
+'exif-whitebalance-1' => 'Handmatige witbalans',
+
+'exif-scenecapturetype-0'=> 'Standaard',
+'exif-scenecapturetype-1'=> 'Landschap',
+'exif-scenecapturetype-2'=> 'Portret',
+'exif-scenecapturetype-3'=> 'Nachtscène',
+
+'exif-gaincontrol-0' => 'Geen',
+'exif-gaincontrol-1' => 'Lage pieken omhoog',
+'exif-gaincontrol-2' => 'Hoge pieken omhoog',
+'exif-gaincontrol-3' => 'Lage pieken omlaag',
+'exif-gaincontrol-4' => 'Hoge pieken omlaag',
+
+'exif-contrast-0' => 'Normaal',
+'exif-contrast-1' => 'Zacht',
+
+'exif-saturation-0' => 'Normaal',
+'exif-saturation-1' => 'Laag',
+'exif-saturation-2' => 'Hoog',
+
+'exif-sharpness-0' => 'Normaal',
+'exif-sharpness-1' => 'Zacht',
+
+'exif-subjectdistancerange-0'=> 'Onbekend',
+'exif-subjectdistancerange-2'=> 'Dichtbij',
+'exif-subjectdistancerange-3'=> 'Ver weg',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Noorderbreedte',
+'exif-gpslatitude-s' => 'Zuiderbreedte',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Oosterlengte',
+'exif-gpslongitude-w' => 'Westerlengte',
+
+'exif-gpsstatus-a' => 'Bezig met meten',
+'exif-gpsstatus-v' => 'Meetinteroperabiliteit',
+
+'exif-gpsmeasuremode-2' => '2-dimensionale meting',
+'exif-gpsmeasuremode-3' => '3-dimensionale meting',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometer per uur',
+'exif-gpsspeed-m' => 'Mijl per uur',
+'exif-gpsspeed-n' => 'Knopen',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Eigenlijke richting',
+'exif-gpsdirection-m' => 'Magnetische richting',
+
+# external editor support
+'edit-externally' => 'Bewerk dit bestand in een extern programma',
+'edit-externally-help' => 'In de [http://meta.wikimedia.org/wiki/Help:External_editors handleiding voor instellingen] staat meer informatie.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'alles',
+'imagelistall' => 'alle',
+'watchlistall1' => 'allemaal',
+'watchlistall2' => 'alles',
+'namespacesall' => 'alle',
+
+# E-mail address confirmation
+'confirmemail' => 'Bevestig e-mailadres',
+'confirmemail_noemail' => 'U heeft geen geldig e-mailadres ingegeven in uw [[Special:Preferences|gebruikersvoorkeuren]].',
+'confirmemail_text' => 'Deze wiki vereist de bevestiging van uw e-mailadres voordat u de e-mailmogelijkheden kunt gebruiken. Klik op de onderstaande knop om een bevestigingsbericht te ontvangen. Dit bericht bevat een link met een code. Open die link om uw e-mailadres te bevestigen.',
+'confirmemail_send' => 'Verzend een bevestigingscode',
+'confirmemail_sent' => 'Bevestigingscode verzonden.',
+'confirmemail_sendfailed'=> 'Het was niet mogelijk een bevestigingscode te verzenden. Controleer het adres op ongeldige tekens.',
+'confirmemail_invalid' => 'Ongeldige bevestigingscode. Mogelijk is de code verlopen.',
+'confirmemail_needlogin'=> 'U dient $1 om uw e-mailadres te bevestigen.',
+'confirmemail_success' => 'Uw e-mailadres is bevestigd. U kunt zich nu aanmelden en {{SITENAME}} gebruiken.',
+'confirmemail_loggedin' => 'Uw e-mailadres is nu bevestigd.',
+'confirmemail_error' => 'Er is iets verkeerd gegaan tijdens het opslaan van uw bevestiging.',
+'confirmemail_subject' => 'Bevestiging e-mailadres voor {{SITENAME}}',
+'confirmemail_body' => 'Iemand, waarschijnlijk u, met het IP-adres $1, heeft zich met dit e-mailadres geregistreerd als gebruiker "$2" op {{SITENAME}}.
+
+Open de volgende link om te bevestigen dat u deze gebruiker bent en om de e-mailmogelijkheden op {{SITENAME}} te activeren:
+
+$3
+
+Als u zichzelf *niet* heeft aangemeld, open deze link dan niet. De bevestigingscode verloopt op $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Zoek op exacte overeenkomst',
+'searchfulltext' => 'Volledige tekst doorzoeken',
+'createarticle' => 'Maak nieuwe pagina',
+
+# Scary transclusion
+'scarytranscludedisabled'=> '[Interwikitransclusie is uitgeschakeld]',
+'scarytranscludefailed' => '[Sjabloon $1 kon niet opgehaald worden; sorry]',
+'scarytranscludetoolong'=> '[URL is te lang; sorry]',
+
+# Trackbacks
+'trackbackbox' => '<div id=\'mw_trackbacks\'>
+Trackbacks voor deze pagina:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Verwijderen])',
+'trackbackdeleteok' => 'De trackback is verwijderd.',
+
+# delete conflict
+'deletedwhileediting' => 'Let op: deze pagina is verwijderd terwijl u bezig was met uw bewerking!',
+'confirmrecreate' => 'Gebruiker [[User:$1|$1]] ([[User talk:$1|overleg]]) heeft deze pagina verwijderd nadat u begonnen bent met uw wijziging met opgaaf van de volgende reden:
+: \'\'$2\'\'
+Bevestig alstublieft dat u de pagina opnieuw wilt aanmaken.',
+'recreate' => 'Opnieuw aanmaken',
+'tooltip-recreate' => 'Maak deze pagina opnieuw aan ondanks eerdere verwijdering',
+
+
+# HTML dump
+'redirectingto' => 'Aan het doorverwijzen naar [[$1]]...',
+
+# action=purge
+'confirm_purge' => 'Wis de cache van deze pagina?
+
+$1',
+'youhavenewmessagesmulti'=> 'U heeft nieuwe berichten op $1',
+'searchcontaining' => "Zoek naar pagina's die ''$1'' bevatten.",
+'searchnamed' => "Zoek naar pagina's met de naam ''$1''.",
+'articletitles' => "Pagina's die met ''$1'' beginnen",
+'hideresults' => 'Verberg resultaten',
+
+# DISPLAYTITLE
+'displaytitle' => '(Link naar deze pagina als [[$1]])',
+# Separator for categories in page lists
+# Please don't localise this
+'loginlanguagelabel' => 'Taal: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; vorige pagina',
+'imgmultipagenext' => 'volgende pagina &rarr;',
+'imgmultigo' => 'OK',
+'imgmultigotopre' => 'Ga naar pagina',
+
+# Table pager
+'ascending_abbrev' => 'opl.',
+'descending_abbrev' => 'afl.',
+'table_pager_next' => 'Volgende pagina',
+'table_pager_prev' => 'Vorige pagina',
+'table_pager_first' => 'Eerste pagina',
+'table_pager_last' => 'Laatste pagina',
+'table_pager_limit' => 'Toon $1 resultaten per pagina',
+'table_pager_limit_submit'=> 'OK',
+'table_pager_empty' => 'Geen resultaten',
+);
+?>
diff --git a/languages/messages/MessagesNn.php b/languages/messages/MessagesNn.php
new file mode 100644
index 000000000000..3ffc0c1cbdf0
--- /dev/null
+++ b/languages/messages/MessagesNn.php
@@ -0,0 +1,1602 @@
+<?php
+/** Norwegian (Nynorsk)
+ *
+ * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ *
+ * @author Olve Utne
+ * @author Guttorm Flatabø
+ * @link http://meta.wikimedia.org/w/index.php?title=LanguageNn.php&action=history
+ * @link http://nn.wikipedia.org/w/index.php?title=Brukar:Dittaeva/LanguageNn.php&action=history
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+
+$quickbarSettings = array(
+ 'Ingen', 'Venstre', 'Høgre', 'Flytande venstre', 'Flytande høgre'
+);
+
+$skinNames = array(
+ 'standard' => 'Klassisk',
+ 'nostalgia' => 'Nostalgi',
+ 'cologneblue' => 'Kölnerblå',
+ 'myskin' => 'MiDrakt'
+);
+
+$datePreferences = array(
+ 'default',
+ 'dmyt',
+ 'short dmyt',
+ 'tdmy',
+ 'short dmyt',
+ 'ISO 8601',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'dmyt',
+ 'short dmyt',
+ 'tdmy',
+ 'short tdmy',
+);
+
+$dateFormats = array(
+ /*
+ 'Standard',
+ '15. januar 2001 kl. 16:12',
+ '15. jan. 2001 kl. 16:12',
+ '16:12, 15. januar 2001',
+ '16:12, 15. jan. 2001',
+ 'ISO 8601' => '2001-01-15 16:12:34'
+ */
+ 'dmyt time' => 'H:i',
+ 'dmyt date' => 'j. F Y',
+ 'dmyt both' => 'j. F Y "kl." H:i',
+
+ 'short dmyt time' => 'H:i',
+ 'short dmyt date' => 'j. M. Y',
+ 'short dmyt both' => 'j. M. Y "kl." H:i',
+
+ 'tdmy time' => 'H:i',
+ 'tdmy date' => 'j. F Y',
+ 'tdmy both' => 'H:i, j. F Y',
+
+ 'short tdmy time' => 'H:i',
+ 'short tdmy date' => 'j. M. Y',
+ 'short tdmy both' => 'H:i, j. M. Y',
+);
+
+$bookstoreList = array(
+ 'Bibsys' => 'http://ask.bibsys.no/ask/action/result?kilde=biblio&fid=isbn&lang=nn&term=$1',
+ 'BokBerit' => 'http://www.bokberit.no/annet_sted/bocker/$1.html',
+ 'Bokkilden' => 'http://www.bokkilden.no/ProductDetails.aspx?ProductId=$1',
+ 'Haugenbok' => 'http://www.haugenbok.no/resultat.cfm?st=hurtig&isbn=$1',
+ 'Akademika' => 'http://www.akademika.no/sok.php?isbn=$1',
+ 'Gnist' => 'http://www.gnist.no/sok.php?isbn=$1',
+ 'Amazon.co.uk' => 'http://www.amazon.co.uk/exec/obidos/ISBN=$1',
+ 'Amazon.de' => 'http://www.amazon.de/exec/obidos/ISBN=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+# Note to translators:
+# Please include the English words as synonyms. This allows people
+# from other wikis to contribute more easily.
+#
+$magicWords = array(
+ # ID CASE SYNONYMS
+ 'redirect' => array( 0, '#redirect', '#omdiriger' ),
+ 'notoc' => array( 0, '__NOTOC__', '__INGAINNHALDSLISTE__', '__INGENINNHOLDSLISTE__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__ALLTIDINNHALDSLISTE__', '__ALLTIDINNHOLDSLISTE__' ),
+ 'toc' => array( 0, '__TOC__', '__INNHALDSLISTE__', '__INNHOLDSLISTE__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__INGABOLKENDRING__', '__INGABOLKREDIGERING__', '__INGENDELENDRING__'),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'MÅNADNO', 'MÅNEDNÅ' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'MÅNADNONAMN', 'MÅNEDNÅNAVN' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'MÅNADNOKORT', 'MÅNEDNÅKORT' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'DAGNO', 'DAGNÅ' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'DAGNONAMN', 'DAGNÅNAVN' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'ÅRNO', 'ÅRNÅ' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'TIDNO', 'TIDNÅ' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'INNHALDSSIDETAL', 'INNHOLDSSIDETALL' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'FILTAL' ),
+ 'pagename' => array( 1, 'PAGENAME', 'SIDENAMN', 'SIDENAVN' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'SIDENAMNE', 'SIDENAVNE' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'NAMNEROM', 'NAVNEROM' ),
+ 'subst' => array( 0, 'SUBST:', 'LIMINN:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'IKWIKMELD:' ),
+ 'end' => array( 0, '__END__', '__SLUTT__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'mini', 'miniatyr' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'mini=$1', 'miniatyr=$1' ),
+ 'img_right' => array( 1, 'right', 'høgre', 'høyre' ),
+ 'img_left' => array( 1, 'left', 'venstre' ),
+ 'img_none' => array( 1, 'none', 'ingen' ),
+ 'img_width' => array( 1, '$1px', '$1pk' ),
+ 'img_center' => array( 1, 'center', 'centre', 'sentrum' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'ramme' ),
+ 'sitename' => array( 1, 'SITENAME', 'NETTSTADNAMN' ),
+ 'ns' => array( 0, 'NS:', 'NR:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'LOKALLENKJE:', 'LOKALLENKE:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'LOKALLENKJEE:', 'LOKALLENKEE:' ),
+ 'server' => array( 0, 'SERVER', 'TENAR', 'TJENER' ),
+ 'servername' => array( 0, 'SERVERNAME', 'TENARNAMN', 'TJENERNAVN' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'SKRIPTSTI' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'GRAMMATIKK:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__' ),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'VEKENRNO', 'UKENRNÅ' ),
+ 'currentdow' => array( 1, 'CURRENTDOW', 'VEKEDAGNRNO', 'UKEDAGNRNÅ' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'VERSJONSID' )
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Filpeikar',
+ NS_SPECIAL => 'Spesial',
+ NS_MAIN => '',
+ NS_TALK => 'Diskusjon',
+ NS_USER => 'Brukar',
+ NS_USER_TALK => 'Brukardiskusjon',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1-diskusjon',
+ NS_IMAGE => 'Fil',
+ NS_IMAGE_TALK => 'Fildiskusjon',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki-diskusjon',
+ NS_TEMPLATE => 'Mal',
+ NS_TEMPLATE_TALK => 'Maldiskusjon',
+ NS_HELP => 'Hjelp',
+ NS_HELP_TALK => 'Hjelpdiskusjon',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Kategoridiskusjon'
+);
+
+$separatorTransformTable = array(
+ ',' => "\xc2\xa0",
+ '.' => ','
+);
+$linkTrail = '/^([æøåa-z]+)(.*)$/sDu';
+
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'Strek under lenkjer:',
+'tog-highlightbroken' => 'Vis lenkjer til tomme sider <a href="" class="new">slik</a> (alternativt slik<a href="" class="internal">?</a>)',
+'tog-justify' => 'Blokkjusterte avsnitt',
+'tog-hideminor' => 'Skjul uviktige endringar på «siste endringar»',
+'tog-usenewrc' => 'Utvida funksjonalitet på «siste endringar» (JavaScript)',
+'tog-numberheadings' => 'Vis nummererte overskrifter',
+'tog-showtoolbar' => 'Vis endringsknappar (JavaScript)',
+'tog-editondblclick' => 'Endre sider med dobbelklikk (JavaScript)',
+'tog-editsection' => 'Endre avsnitt med hjelp av [endre]-lenkje',
+'tog-editsectiononrightclick' => 'Endre avsnitt med å høgreklikke på avsnittsoverskrift (JavaScript)',
+'tog-showtoc' => 'Vis innhaldsliste (for sider med meir enn tre bolkar)',
+'tog-rememberpassword' => 'Hugs passordet til neste gong',
+'tog-editwidth' => 'Gjev endringsboksen full breidd',
+'tog-watchdefault' => 'Legg sider eg endrar i overvakingslista mi',
+'tog-minordefault' => 'Merk endringar som «uviktige» som standard',
+'tog-previewontop' => 'Vis førehandsvisinga føre endringsboksen',
+'tog-previewonfirst' => 'Førehandsvis første endring',
+'tog-nocache' => 'Ikkje bruk nettlesaren sitt mellomlager (cache)',
+'tog-enotifwatchlistpages' => 'Send e-post når dei overvaka sidene mine blir endra',
+'tog-enotifusertalkpages' => 'Send e-post når brukarsida mi blir endra',
+'tog-enotifminoredits' => 'Send e-post òg for uviktige endringar',
+'tog-enotifrevealaddr' => 'Vis e-postadressa mi i endrings-e-post',
+'tog-shownumberswatching' => 'Vis kor mange som overvakar sida',
+'tog-fancysig' => 'Signatur utan automatisk lenkje',
+'tog-externaleditor' => 'Eksternt handsamingsprogram som standard',
+'tog-externaldiff' => 'Eksternt skilnadprogram som standard',
+
+'underline-always' => 'Alltid',
+'underline-never' => 'Aldri',
+'underline-default' => 'Nettlesarstandard',
+
+'skinpreview' => '(førehandsvis)',
+
+# Dates
+'sunday' => 'søndag',
+'monday' => 'måndag',
+'tuesday' => 'tysdag',
+'wednesday' => 'onsdag',
+'thursday' => 'torsdag',
+'friday' => 'fredag',
+'saturday' => 'laurdag',
+'january' => 'januar',
+'february' => 'februar',
+'march' => 'mars',
+'april' => 'april',
+'may_long' => 'mai',
+'june' => 'juni',
+'july' => 'juli',
+'august' => 'august',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'desember',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'des',
+
+# Bits of text used by many pages:
+'categories' => 'Kategoriar',
+'pagecategories' => 'Kategoriar',
+'category_header' => 'Artiklar i kategorien «$1»',
+'subcategories' => 'Underkategoriar',
+
+'mainpage' => 'Hovudside',
+'mainpagetext' => 'MediaWiki er no installert.',
+'mainpagedocfooter' => 'Sjå [http://meta.wikimedia.org/wiki/MediaWiki_localization dokumentasjon for å tilpasse brukargrensesnittet] og [http://meta.wikimedia.org/wiki/Help:Contents brukarmanualen] for bruk og konfigurasjonshjelp.',
+
+'portal' => 'Brukarportal',
+'portal-url' => 'Project:Brukarportal',
+'about' => 'Om',
+'aboutsite' => 'Om {{SITENAME}}',
+'aboutpage' => 'Project:Om',
+'article' => 'Innhaldsside',
+'help' => 'Hjelp',
+'helppage' => 'Help:Innhald',
+'bugreports' => 'Feilmeldingar',
+'bugreportspage' => 'Project:Feilmeldingar',
+'sitesupport' => 'Gåver',
+'sitesupport-url' => 'Project:Gåver',
+'faq' => 'OSS',
+'faqpage' => 'Project:OSS',
+'edithelp' => 'Hjelp til endring',
+'newwindow' => '(blir opna i eit nytt vindauge)',
+'edithelppage' => 'Help:Endring',
+'cancel' => 'Avbryt',
+'qbfind' => 'Finn',
+'qbbrowse' => 'Bla gjennom',
+'qbedit' => 'Endre',
+'qbpageoptions' => 'Denne sida',
+'qbpageinfo' => 'Samanheng',
+'qbmyoptions' => 'Sidene mine',
+'qbspecialpages' => 'Spesialsider',
+'moredotdotdot' => 'Meir...',
+'mypage' => 'Sida mi',
+'mytalk' => 'Diskusjonssida mi',
+'anontalk' => 'Diskusjonside for denne IP-adressa',
+'navigation' => 'Navigering',
+
+# Metadata in edit box
+'metadata' => '<b>Metadata</b> (for forklaring, sjå <a href="$1">her</a>)',
+
+'currentevents' => 'Aktuelt',
+'currentevents-url' => 'Aktuelt',
+
+'disclaimers' => 'Vilkår',
+'disclaimerpage' => 'Project:Vilkår',
+'errorpagetitle' => 'Feil',
+'returnto' => 'Attende til $1.',
+'tagline' => 'Frå {{SITENAME}}',
+'whatlinkshere' => 'Sider med lenkjer hit',
+'help' => 'Hjelp',
+'search' => 'Søk',
+'searchbutton' => 'Søk',
+'go' => 'Vis',
+'searcharticle' => 'Vis',
+'history' => 'Sidehistorikk',
+'history_short' => 'Historikk',
+'updatedmarker' => 'oppdatert etter mitt siste besøk',
+'info_short' => 'Informasjon',
+'printableversion' => 'Utskriftsversjon',
+'print' => 'Skriv ut',
+'edit' => 'Endre',
+'editthispage' => 'Endre sida',
+'delete' => 'Slett',
+'deletethispage' => 'Slett side',
+'undelete_short' => 'Attopprett $1 endringar',
+'protect' => 'Vern',
+'protectthispage' => 'Vern denne sida',
+'unprotect' => 'fjern vern',
+'unprotectthispage' => 'Fjern vern av denne sida',
+'newpage' => 'Ny side',
+'talkpage' => 'Drøft sida',
+'specialpage' => 'Spesialside',
+'personaltools' => 'Personlege verktøy',
+'postcomment' => 'Legg til kommentar',
+'articlepage' => 'Vis innhaldsside',
+'talk' => 'Diskusjon',
+'views' => 'Visningar',
+'toolbox' => 'Verktøy',
+'userpage' => 'Vis brukarside',
+'projectpage' => 'Vis prosjektside',
+'imagepage' => 'Vis filside',
+'viewtalkpage' => 'Vis diskusjon',
+'otherlanguages' => 'På andre språk',
+'redirectedfrom' => '(Omdirigert frå $1)',
+'lastmodifiedat' => 'Sist endra $2, $1.',
+'viewcount' => 'Vist $1 gonger.',
+'copyright' => 'Innhaldet er utgjeve under $1.',
+'protectedpage' => 'Verna side',
+'badaccess' => 'Tilgangsfeil',
+'versionrequired' => 'MediaWiki versjon $1 trengst',
+'versionrequiredtext' => 'For å bruke denne sida trengst MediaWiki versjon $1. Sjå [[{{ns:special}}:Version]]',
+'nbytes' => '$1 byte',
+'ok' => 'OK',
+'retrievedfrom' => 'Henta frå «$1»',
+'newmessageslink' => 'nye meldingar',
+'editsection' => 'endre',
+'editold' => 'endre',
+'toc' => 'Innhaldsliste',
+'showtoc' => 'vis',
+'hidetoc' => 'gøym',
+'thisisdeleted' => 'Sjå eller attopprett $1?',
+'viewdeleted' => 'Sjå historikk for $1?',
+'restorelink' => '$1 sletta versjonar',
+'feedlinks' => 'Mating:',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Innhaldsside',
+'nstab-user' => 'Brukarside',
+'nstab-media' => 'Filside',
+'nstab-special' => 'Spesial',
+'nstab-project' => 'Prosjektside',
+'nstab-image' => 'Fil',
+'nstab-mediawiki' => 'Systemmelding',
+'nstab-template' => 'Mal',
+'nstab-help' => 'Hjelp',
+'nstab-category' => 'Kategori',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Funksjonen finst ikkje',
+'nosuchactiontext' => 'Wikiprogramvaren kjenner ikkje att funksjonen som er spesifisert i nettadressa',
+'nosuchspecialpage' => 'Ei slik spesialside finst ikkje',
+'nospecialpagetext' => 'Du har bede om ei spesialside som ikkje finst, liste over spesialsider er [[Special:Specialpages|her]].',
+
+# General errors
+#
+'error' => 'Feil',
+'databaseerror' => 'Databasefeil',
+'dberrortext' => 'Det oppstod ein syntaksfeil i databaseførespurnaden. Dette kan tyde på ein feil i programvaren. Den sist prøvde førespurnaden var: <blockquote><tt>$1</tt></blockquote> frå funksjonen «<tt>$2</tt>». MySQL returnerte feilen «<tt>$3: $4</tt>».',
+'dberrortextcl' => 'Det oppstod ein syntaksfeil i databaseførespurnaden. Den sist prøvde førespurnaden var: «$1» frå funksjonen "$2".
+MySQL returnerte feilen «$3: $4».',
+'noconnect' => 'Wikien har tekniske problem og kunne ikkje kople til databasen.<br />$1',
+'nodb' => 'Kunne ikkje velja databasen $1',
+'cachederror' => 'Det følgjande er ein lagra kopi av den ønska sida, og er ikkje nødvendigvis oppdatert.',
+'laggedslavemode' => 'Åtvaring: Det er mogleg at sida ikkje er heilt oppdatert.',
+'readonly' => 'Databasen er skriveverna',
+'enterlockreason' => 'Skriv ein grunn for vernet, inkludert eit overslag for kva tid det vil bli oppheva',
+'readonlytext' => 'Databasen er akkurat no skriveverna, truleg for rutinemessig vedlikehald. Administratoren som verna han har gjeve denne forklaringa:<p>$1',
+'missingarticle' => 'Databasen fann ikkje teksten til ei side med namnet «$1» som han skulle ha funne.
+
+Dette skjer oftast fordi du følgde ei lenkje til ei oppføring som har vorte sletta.
+Sletta oppføringar kan vanlegvis attopprettast.
+
+Dersom dette ikkje er tilfellet kan du ha funne ein feil i programvaren. Gje melding om dette til ein administrator, med adressa åt sida.',
+'readonly_lag' => 'Databasen er mellombels skriveverna for at databasetenarane skal kunna synkronisere seg mot kvarandre',
+'internalerror' => 'Intern feil',
+'filecopyerror' => 'Kunne ikkje kopiere fila frå «$1» til «$2».',
+'filerenameerror' => 'Kunne ikkje døype om fila frå «$1» til «$2».',
+'filedeleteerror' => 'Kunne ikkje slette fila «$1».',
+'filenotfound' => 'Kunne ikkje finne fila «$1».',
+'unexpected' => 'Uventa verdi: «$1»=«$2».',
+'formerror' => 'Feil: Kunne ikkje sende skjema',
+'badarticleerror' => 'Handlinga kan ikkje utførast på denne sida.',
+'cannotdelete' => 'Kunne ikkje slette fila. (Ho kan vera sletta av andre.)',
+'badtitle' => 'Feil i tittelen',
+'badtitletext' => 'Den ønska tittelen var ulovleg, tom eller feil lenka frå ei anna wiki.',
+'perfdisabled' => 'Beklagar! Denne funksjonen er mellombels deaktivert for å spara tenarkapasitet.',
+'perfdisabledsub' => 'Her er ein lagra kopi frå $1:',
+'perfcached' => 'Det følgjande er frå mellomlageret åt tenaren og er ikkje nødvendigvis oppdatert.',
+'wrong_wfQuery_params' => 'Feil parameter gjevne til wfQuery()<br />Funksjon: $1<br />Førespurnad: $2',
+'viewsource' => 'Vis kjeldetekst',
+'protectedtext' => 'Denne sida er verna for endring. Det kan vera fleire grunnar til dette, sjå [[{{ns:4}}:Verna side]].
+
+Du kan sjå og kopiere kjeldeteksten til denne sida:',
+'sqlhidden' => '(SQL-førespurnaden er gøymd)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Logg ut',
+'logouttext' => 'Du er no utlogga. Avhengig av innstillingane på tenaren kan nettlesaren no brukast anonymt på {{SITENAME}};
+du kan logge inn att med same kontoen eller ein annan brukar kan logge inn. Ver merksam på at nokre sider kan fortsetje å bli viste som om du er innlogga inntil du tømmer mellomlageret til nettlesaren din.',
+'welcomecreation' => '== Hjarteleg velkommen til {{SITENAME}}, [[user:$1|$1]]! ==
+
+Brukarkontoen din har vorte oppretta. Det er tilrådd at du skriv litt om deg sjølv på [[user:$1|brukarsida di]] og ser gjennom [[special:preferences|brukarinnstillingane dine]].',
+'loginpagetitle' => 'Logg inn',
+'yourname' => 'Brukarnamn',
+'yourpassword' => 'Passord',
+'yourpasswordagain' => 'Skriv opp att passordet',
+'remembermypassword' => 'Hugs passordet.',
+'yourdomainname' => 'Domenet ditt',
+'externaldberror' => 'Det var anten ein ekstern databasefeil i tilgjengekontrollen, eller du har ikkje løyve til å oppdatere den eksterne kontoen din.',
+'loginproblem' => '<b>Du vart ikkje innlogga.</b><br />Prøv om att!',
+'alreadyloggedin' => '<strong>Brukar $1, du er allereie innlogga!</strong><br />',
+'login' => 'Logg inn',
+'loginprompt' => 'Nettlesaren din må godta informasjonskapslar for at du skal kunna logge inn.',
+'userlogin' => 'Lag brukarkonto / logg inn',
+'logout' => 'Logg ut',
+'userlogout' => 'Logg ut',
+'notloggedin' => 'Ikkje innlogga',
+'createaccount' => 'Opprett ny konto',
+'createaccountmail' => 'over e-post',
+'badretype' => 'Passorda du skreiv inn er ikkje like.',
+'userexists' => 'Brukarnamnet er allereie i bruk. Vel eit nytt.',
+'youremail' => 'E-postadresse*',
+'yourrealname' => 'Namn*',
+'yourlanguage' => 'Språk for brukargrensesnittet',
+'yourvariant' => 'Språkvariant',
+'yournick' => 'Kallenamn (for signaturar)',
+'email' => 'E-post',
+'prefs-help-email-enotif' => 'Denne adressa blir også brukt til å sende deg endringsmeldingar dersom du har valt å ta den funksjonen i bruk.',
+'prefs-help-realname' => '* Namn (valfritt): Om du vel å fylle ut dette feltet, vil informasjonen bli brukt til å godskrive arbeid du har gjort.',
+'loginerror' => 'Innloggingsfeil',
+'prefs-help-email' => '* E-post (valfritt): Gjer det mogleg for andre brukarar å ta kontakt med deg utan at du offentleggjer adressa.',
+'nocookiesnew' => 'Brukarkontoen vart oppretta, men du er ikkje innlogga. {{SITENAME}} bruker informasjonskapslar for å logge inn brukarar,
+nettlesaren din er innstilt for ikkje å godta desse. Etter at du har endra innstillingane slik at nettlesaren godtek informasjonskapslar, kan du logge inn med det nye brukarnamnet og passordet ditt.',
+'nocookieslogin' => '{{SITENAME}} bruker informasjonskapslar for å logge inn brukarar, nettlesaren din er innstilt for ikkje å godta desse.
+Etter at du har endra innstillingane slik at nettlesaren godtek informasjonskapslar kan du prøve å logge inn på nytt.',
+'noname' => 'Du har ikkje oppgjeve gyldig brukarnamn.',
+'loginsuccesstitle' => 'Du er no innlogga',
+'loginsuccess' => 'Du er no innlogga som «$1».',
+'nosuchuser' => 'Det finst ikkje nokon brukar med brukarnamnet «$1». Sjekk at du har skrive rett eller bruk skjemaet under til å opprette ein ny konto.',
+'nosuchusershort' => 'Det finst ikkje nokon brukar med brukarnamnet «$1». Sjekk at du har skrive rett.',
+'wrongpassword' => 'Du har oppgjeve eit ugyldig passord. Prøv om att.',
+'mailmypassword' => 'Send meg nytt passord',
+'passwordremindertitle' => 'Nytt passord til {{SITENAME}}',
+'passwordremindertext' => 'Nokon (truleg du, frå IP-adressa $1) bad oss sende deg eit nytt passord til {{SITENAME}}. Passordet for brukaren «$2» er no «$3». Du bør logge inn og endre passordet så snart som råd.',
+'noemail' => 'Det er ikkje registrert noka e-postadresse åt brukaren «$1».',
+'passwordsent' => 'Eit nytt passord er sendt åt e-postadressa registrert på brukaren «$1».',
+'eauthentsent' => 'Ein stadfestings-e-post er sendt til den oppgjevne e-postadressa. For at adressa skal kunna brukast, må du følgje instruksjonane i e-posten for å stadfeste at ho faktisk tilhøyrer deg.',
+'mailerror' => 'Ein feil oppstod ved sending av e-post: $1',
+'acct_creation_throttle_hit' => 'Beklagar, du har allereie laga $1 brukarkontoar. Du har ikkje høve til å laga fleire.',
+'emailauthenticated' => 'E-postadressa di vart stadfest $1.',
+'emailnotauthenticated' => 'E-postadressa di er enno ikkje stadfest. Dei følgjande funksjonane kan ikkje bruke ho.',
+'noemailprefs' => '<strong>Du har ikkje oppgjeve noko e-postadresse</strong>, dei følgjande funksjonane vil ikkje verke.',
+'emailconfirmlink' => 'Stadfest e-post-adressa di',
+'invalidemailaddress' => 'E-postadressa kan ikkje brukast sidan ho er feil oppbygd. Skriv ei rett oppbygd adresse eller tøm feltet.',
+
+# Edit page toolbar
+'bold_sample' => 'Halvfeit skrift',
+'bold_tip' => 'Halvfeit skrift',
+'italic_sample' => 'Kursivskrift',
+'italic_tip' => 'Kursivskrift',
+'link_sample' => 'Lenkjetittel',
+'link_tip' => 'Intern lenkje',
+'extlink_sample' => 'http://www.eksempel.no lenkjetittel',
+'extlink_tip' => 'Ekstern lenkje (hugs http:// prefiks)',
+'headline_sample' => 'Overskriftstekst',
+'headline_tip' => '2. nivå-overskrift',
+'math_sample' => 'Skriv formel her',
+'math_tip' => 'Matematisk formel (LaTeX)',
+'nowiki_sample' => 'Skriv uformatert tekst her',
+'nowiki_tip' => 'Sjå bort frå wikiformatering',
+'image_sample' => 'Eksempel.jpg',
+'image_tip' => 'Bilete eller lenkje til filomtale',
+'media_sample' => 'Eksempel.ogg',
+'media_tip' => 'Filpeikar',
+'sig_tip' => 'Signaturen din med tidsstempel',
+'hr_tip' => 'Vassrett line',
+
+# Edit pages
+#
+'summary' => 'Samandrag',
+'subject' => 'Emne/overskrift',
+'minoredit' => 'Uviktig endring',
+'watchthis' => 'Overvak side',
+'savearticle' => 'Lagre',
+'preview' => 'Førehandsvising',
+'showpreview' => 'Førehandsvis',
+'showdiff' => 'Vis skilnad',
+'blockedtitle' => 'Brukaren er blokkert',
+'blockedtext' => 'Brukarnamnet ditt eller IP-adressa di er blokkert frå endring, av $1. Denne grunnen vart gjeven:<br />\'\'$2\'\'<p>Du kan kontakte $1 eller ein annan [[Project:Administratorar|administrator]] for å diskutere blokkeringa.
+
+Ver merksam på at du ikkje kan bruke «send e-post åt brukar»-funksjonen så lenge du ikkje har ei gyldig e-postadresse registrert i [[Special:Preferences|innstillingane dine]].
+
+IP-adressa di er $3. Legg henne ved eventuelle førespurnader.',
+'whitelistedittitle' => 'Du lyt logge inn for å gjera endringar',
+'whitelistedittext' => 'Du lyt [[{{ns:-1}}:Userlogin|logge inn]] for å endre sider.',
+'whitelistreadtitle' => 'Du lyt logge inn for å lesa',
+'whitelistreadtext' => 'Du lyt [[{{ns:-1}}:Userlogin|logge inn]] for å lesa sider.',
+'whitelistacctitle' => 'Du har ikkje løyve til å laga brukarkonto',
+'whitelistacctext' => 'For å laga brukarkontoar på denne wikien lyt du [[{{ns:-1}}:Userlogin|logge inn]] og ha rett type tilgang',
+'loginreqtitle' => 'Innlogging trengst',
+'loginreqlink' => 'logge inn',
+'loginreqpagetext' => 'Du lyt $1 for å lesa andre sider.',
+'accmailtitle' => 'Passord er sendt.',
+'accmailtext' => 'Passordet for «$1» er vorte sendt til $2.',
+'newarticle' => '(Ny)',
+'newarticletext' => '\'\'\'{{SITENAME}} har ikkje noka side med namnet {{PAGENAME}} enno.\'\'\'
+* For å laga ei slik side kan du skrive i boksen under og klikke på «Lagre». Endringane vil vera synlege med det same.
+* Om du er ny her er det tilrådd å sjå på [[Project:Retningsliner|retningsliner]] og [[Help:Innhald|hjelp]] først.
+* Om du lagrar ei testside, vil du ikkje kunne slette ho sjølv. Ver difor venleg og bruk [[Project:Sandkasse|sandkassa]] til å eksperimentere.
+* Dersom du ikkje ønskjer å endre sida, kan du utan risiko klikke på \'\'\'attende\'\'\'-knappen i nettlesaren din.',
+'anontalkpagetext' => '---- \'\'Dette er ei diskusjonsside for ein anonym brukar som ikkje har logga inn på eigen brukarkonto. Vi er difor nøydde til å bruke den numeriske IP-adressa knytt til internettoppkoplinga åt brukaren. Same IP-adressa kan vera knytt til fleire brukarar. Om du er ein anonym brukar og meiner at du har fått irrelevante kommentarar på ei slik side, [[{{ns:-1}}:Userlogin|logg inn]] slik at vi unngår framtidige forvekslingar med andre anonyme brukarar.\'\'',
+'noarticletext' => '\'\'\'Sida «{{PAGENAME}}» finst ikkje på {{SITENAME}} enno.\'\'\'
+* Klikk på \'\'\'[{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} endre]\'\'\' for å opprette sida.',
+'clearyourcache' => '\'\'\'Merk:\'\'\' Etter lagring vil det kanskje vera naudsynt at nettlesaren omgår mellomlageret sitt for at endringane skal tre i kraft. \'\'\'Mozilla og Firefox:\'\'\' trykk \'\'Ctrl-Shift-R\'\', \'\'\'Internet Explorer:\'\'\' \'\'Ctrl-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-Shift-R\'\', \'\'\'Konqueror:\'\'\' \'\'F5\'\'.',
+'usercssjsyoucanpreview' => '<strong>Tip:</strong> Bruk «Førehandsvis»-knappen for å teste den nye CSS- eller JS-koden din føre du lagrar.',
+'usercsspreview' => '\'\'\'Hugs at du berre testar ditt eige CSS, det har ikkje vorte lagra enno!\'\'\'',
+'userjspreview' => '\'\'\'Hugs at du berre testar ditt eige JavaScript, det har ikkje vorte lagra enno!!\'\'\'',
+'updated' => '(Oppdatert)',
+'note' => '<strong>Merk:</strong>',
+'previewnote' => 'Hugs at dette berre er ei førehandsvising og at teksten ikkje er lagra!',
+'previewconflict' => 'Dette er ei førehandsvising av teksten i endringsboksen over, slik han vil sjå ut om du lagrar han',
+'editing' => 'Endrar $1',
+'editinguser' => 'Endrar $1',
+'editingsection' => 'Endrar $1 (bolk)',
+'editingcomment' => 'Endrar $1 (kommentar)',
+'editconflict' => 'Endringskonflikt: $1',
+'explainconflict' => 'Nokon annan har endra teksten sidan du byrja å skrive. Den øvste boksen inneheld den noverande teksten. Skilnaden mellom den lagra versjonen og din endra versjon er viste under. Versjonen som du har endra er i den nedste boksen. Du lyt flette endringane dine saman med den noverande teksten. <strong>Berre</strong> teksten i den øvste tekstboksen vil bli lagra når du klikkar på «Lagre».<br />',
+'yourtext' => 'Teksten din',
+'storedversion' => 'Den lagra versjonen',
+'nonunicodebrowser' => '<strong>ÅTVARING: Nettlesaren din støttar ikkje «Unicode». For å omgå problemet blir teikn utanfor ASCII-standarden viste som heksadesimale kodar. Det vil vera ein fordel om du byter nettlesar. Sjå [[hjelp:unicode]] for meir informasjon.</strong><br />',
+'editingold' => '<strong>ÅTVARING: Du endrar ein gammal versjon av denne sida. Om du lagrar ho, vil alle endringar gjorde etter denne versjonen bli overskrivne.</strong> (Men dei kan hentast fram att frå historikken.)<br />',
+'yourdiff' => 'Skilnad',
+'copyrightwarning' => 'Merk deg at alle bidrag til {{SITENAME}} er å rekne som utgjevne under $2 (sjå $1 for detaljar). Om du ikkje vil ha teksten endra og kopiert under desse vilkåra, kan du ikkje leggje han her.<br />
+Teksten må du ha skrive sjølv, eller kopiert frå ein ressurs som er kompatibel med vilkåra eller ikkje verna av opphavsrett.
+
+<strong>LEGG ALDRI INN MATERIALE SOM ANDRE HAR OPPHAVSRETT TIL UTAN LØYVE FRÅ DEI!</strong>',
+'copyrightwarning2' => 'Merk deg at alle bidrag til {{SITENAME}} kan bli endra, omskrive og fjerna av andre bidragsytarar. Om du ikkje vil ha teksten endra under desse vilkåra, kan du ikkje leggje han her.<br />
+Teksten må du ha skrive sjølv eller ha kopiert frå ein ressurs som er kompatibel med vilkåra eller ikkje verna av opphavsrett (sjå $1 for detaljar).
+
+<strong>LEGG ALDRI INN MATERIALE SOM ANDRE HAR OPPHAVSRETT TIL UTAN LØYVE FRÅ DEI!</strong>',
+'longpagewarning' => '<strong>ÅTVARING: Denne sida er $1 KB lang; nokre nettlesarar kan ha problem med å handsama endringar av sider som nærmar seg eller er lengre enn 32 KB. Du bør vurdere å dele opp sida i mindre bolkar.</strong><br />',
+'readonlywarning' => '<strong>ÅTVARING: Databasen er skriveverna på grunn av vedlikehald, difor kan du ikkje lagre endringane dine akkurat no. Det kan vera lurt å kopiere teksten din åt ei tekstfil, så du kan lagre han her seinare.</strong><br />',
+'protectedpagewarning' => '<strong>ÅTVARING: Denne sida er verna, slik at berre administratorar kan endre ho.</strong><br />',
+'templatesused' => 'Malar brukte på denne sida:',
+
+# History pages
+#
+'revhistory' => 'Historikk',
+'nohistory' => 'Det finst ikkje nokon historikk for denne sida.',
+'revnotfound' => 'Fann ikkje versjonen',
+'revnotfoundtext' => 'Den gamle versjonen av sida du spurde etter finst ikkje. Sjekk nettadressa du brukte for å komma deg åt denne sida.',
+'loadhist' => 'Lastar historikk',
+'currentrev' => 'Noverande versjon',
+'revisionasof' => 'Versjonen frå $1',
+'previousrevision' => '←Eldre versjon',
+'nextrevision' => 'Nyare versjon→',
+'currentrevisionlink' => 'Vis noverande versjon',
+'cur' => 'no',
+'next' => 'neste',
+'last' => 'førre',
+'orig' => 'orig',
+'histlegend' => 'Merk av for dei versjonane du vil samanlikne og trykk [Enter] eller klikk på knappen nedst på sida.<br />Forklaring: (no) = skilnad frå den noverande versjonen, (førre) = skilnad frå den førre versjonen, <b>u</b> = uviktig endring',
+'deletedrev' => '[sletta]',
+'histfirst' => 'Første',
+'histlast' => 'Siste',
+
+# Diffs
+#
+'difference' => '(Skilnad mellom versjonar)',
+'loadingrev' => 'lastar versjon for å sjå skilnad',
+'lineno' => 'Line $1:',
+'editcurrent' => 'Endre den noverande versjonen av denne sida',
+'selectnewerversionfordiff' => 'Vel ein nyare versjon for samanlikning',
+'selectolderversionfordiff' => 'Vel ein eldre versjon for samanlikning',
+'compareselectedversions' => 'Samanlikn valde versjonar',
+
+# Search results
+#
+'searchresults' => 'Søkjeresultat',
+'searchresulttext' => 'For meir info om søkjefunksjonen i {{SITENAME}}, sjå [[Help:Søk|Hjelp]].',
+'searchsubtitle' => 'Du søkte etter «[[:$1]]»', // plain text
+'searchsubtitleinvalid' => 'Du søkte etter «$1»', // plain text
+'badquery' => 'Feil utforma førespurnad',
+'badquerytext' => 'Vi kunne ikkje svara på denne førespurnaden &mdash; Truleg fordi du prøvde å søkje etter eit ord med færre enn tre bokstavar, noko som ikkje er mogleg enno. Det kan òg vera du skreiv feil... Prøv om att.',
+'matchtotals' => 'Førespurnaden «$1» gav treff på $2 sidetitlar og på teksten på $3 sider.',
+'noexactmatch' => '* \'\'\'{{SITENAME}} har ikkje noka side med [[:$1|dette namnet]].\'\'\'
+* <big>\'\'\'Du kan [[:$1|opprette ho no]]\'\'\'</big>.<br />
+(Men du bør søkje etter andre namnevariasjonar først, slik at du ikkje lagar ei side som allereie finst under eit anna namn!)',
+'titlematches' => 'Sidetitlar med treff på førespurnaden',
+'notitlematches' => 'Ingen sidetitlar hadde treff på førespurnaden',
+'textmatches' => 'Sider med treff på førespurnaden',
+'notextmatches' => 'Ingen sider hadde treff på førespurnaden',
+'prevn' => 'førre $1',
+'nextn' => 'neste $1',
+'viewprevnext' => 'Vis ($1) ($2) ($3).',
+'showingresults' => 'Nedanfor er opp til <strong>$1</strong> resultat som byrjar med nummer <strong>$2</strong> viste.',
+'showingresultsnum' => 'Nedanfor er <strong>$3</strong> resultat som byrjar med nummer <strong>$2</strong> viste.',
+'nonefound' => '\'\'\'Merk\'\'\': søk utan resultat kan komma av at du leitar etter alminnelege engelske ord som ikkje blir indekserte, eller det kan komma av at du har gjeve meir enn eitt søkjeord (berre sider som inneheld alle søkjeorda vil bli funne).',
+'powersearch' => 'Søk',
+'powersearchtext' => 'Søk i namnerom:<br />$1<br />$2<br />List omdirigeringar &nbsp; Søk etter: $3 $9',
+'searchdisabled' => 'Søkjefunksjonen på {{SITENAME}} er deaktivert på grunn av for stort press på tenarane akkurat no. I mellomtida kan du søkje gjennom Google eller Yahoo! Ver merksam på at registra deira kan vera utdaterte.',
+'blanknamespace' => '(Hovud)',
+
+# Preferences page
+#
+'preferences' => 'Innstillingar',
+'prefsnologin' => 'Ikkje innlogga',
+'prefsnologintext' => 'Du lyt vera [[Special:Userlogin|innlogga]] for å endre brukarinnstillingane dine.',
+'prefsreset' => 'Innstillingane er tilbakestilte til siste lagra versjon.',
+'qbsettings' => 'Snøggmeny',
+'changepassword' => 'Skift passord',
+'skin' => 'Drakt',
+'math' => 'Matematiske formlar',
+'dateformat' => 'Datoformat',
+'datedefault' => 'Standard',
+'math_failure' => 'Klarte ikkje å tolke formelen',
+'math_unknown_error' => 'ukjend feil',
+'math_unknown_function' => 'ukjend funksjon',
+'math_lexing_error' => 'lexerfeil',
+'math_syntax_error' => 'syntaksfeil',
+'math_image_error' => 'PNG-konverteringa var mislukka; sjekk at latex, dvips, gs, og convert er rett installerte',
+'math_bad_tmpdir' => 'Kan ikkje skrive til eller laga mellombels mattemappe',
+'math_bad_output' => 'Kan ikkje skrive til eller laga mattemappe',
+'math_notexvc' => 'Manglar texvc-program; sjå math/README for konfigurasjon.',
+'prefs-personal' => 'Brukaropplysningar',
+'prefs-rc' => 'Siste endringar og spirer',
+'prefs-misc' => 'Andre',
+'saveprefs' => 'Lagre',
+'resetprefs' => 'Rull attende',
+'oldpassword' => 'Gammalt passord',
+'newpassword' => 'Nytt passord',
+'retypenew' => 'Nytt passord om att',
+'textboxsize' => 'Endring',
+'rows' => 'Rekkjer',
+'columns' => 'Kolonnar',
+'searchresultshead' => 'Søk',
+'resultsperpage' => 'Resultat per side',
+'contextlines' => 'Liner per resultat',
+'contextchars' => 'Teikn per line i resultatet',
+'stubthreshold' => 'Grense (byte) for vising av spirer',
+'recentchangescount' => 'Tal titlar på «siste endringar»',
+'savedprefs' => 'Brukarinnstillingane er lagra.',
+'timezonelegend' => 'Tidssone',
+'timezonetext' => 'Tal timar lokal tid skil seg frå tenaren si tid.',
+'localtime' => 'Lokaltid',
+'timezoneoffset' => 'Skilnad',
+'servertime' => 'Tenartid',
+'guesstimezone' => 'Hent tidssone frå nettlesaren',
+'defaultns' => 'Søk som standard i desse namneromma:',
+'default' => 'standard',
+'files' => 'Filer',
+
+# User levels special page
+#
+
+# switching pan
+
+'userrights-lookup-user' => 'Administrer brukargrupper',
+'userrights-user-editname' => 'Skriv inn brukarnamn:',
+'editusergroup' => 'Endre brukargrupper',
+
+# user groups editing
+#
+'userrights-editusergroup' => 'Endre brukargrupper',
+'saveusergroups' => 'Lagre brukargrupper',
+'userrights-groupsmember' => 'Medlem av:',
+'userrights-groupsavailable' => 'Tilgjengelege grupper:',
+'userrights-groupshelp' => 'Vel grupper du vil at brukaren skal fjernast frå eller leggjast til. Grupper som ikkje er valde vil ikkje bli endra. Du kan velja vekk ei gruppe med [CTRL + venstreklikk]',
+
+# Recent changes
+#
+'changes' => 'endringar',
+'recentchanges' => 'Siste endringar',
+'recentchangestext' => 'På denne sida ser du dei sist endra sidene i {{SITENAME}}.',
+'rcnote' => 'Nedanfor er dei siste <strong>$1</strong> endringane gjort dei siste <strong>$2</strong> dagane.',
+'rcnotefrom' => 'Nedanfor er endringane frå <b>$2</b> inntil <b>$1</b> viste.',
+'rclistfrom' => 'Vis nye endringar frå $1',
+'rclinks' => 'Vis siste $1 endringar dei siste $2 dagane<br />$3',
+'diff' => 'skil',
+'hist' => 'hist',
+'hide' => 'gøym',
+'show' => 'vis',
+'minoreditletter' => 'u',
+'newpageletter' => 'n',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 brukar(ar) overvakar]',
+
+# Upload
+#
+'upload' => 'Last opp fil',
+'uploadbtn' => 'Last opp fil',
+'reupload' => 'Nytt forsøk',
+'reuploaddesc' => 'Attende til opplastingsskjemaet.',
+'uploadnologin' => 'Ikkje innlogga',
+'uploadnologintext' => 'Du lyt vera [[Special:Userlogin|innlogga]] for å kunna laste opp filer.',
+'upload_directory_read_only' => 'Opplastingsmappa ($1) er skriveverna.',
+'uploaderror' => 'Feil under opplasting av fil',
+'uploadtext' => 'Dette er sida til å laste opp filer. Nyleg opplasta filer finn du på [[Special:Imagelist|filsida]]. Opplastingar og slettingar [[Special:Log|blir loggført]].
+
+* For å bruke eit bilete på ei side, skriv inn ei lenkje av dette slaget: <tt><nowiki>[[{{ns:6}}:Eksempelbilete.jpg]]</nowiki></tt> eller <tt><nowiki>[[{{ns:6}}:Eksempelbilete.png|bilettekst]]</nowiki></tt>, eller <tt><nowiki>[[{{ns:-2}}:Eksempelfil.ogg]]</nowiki></tt> for lydar og andre filer. For å leggje inn eit bilete som miniatyr, skriv <tt><nowiki>[[{{ns:6}}:Eksempelbilete.jpg|mini|Bilettekst]]</nowiki></tt>. Sjå [[Help:Biletsyntaks|biletesyntaks-hjelp]] for meir informasjon.
+* Om du lastar opp ei fil med same namn som ei eksisterande fil vil du bli beden om å stadfeste, og den eksisterande fila vil ikkje bli sletta.
+
+Sjå [[Help:Laste opp fil|hjelp for filopplasting]] for meir informasjon om korleis dette skjemaet verkar og korleis ein bruker filer på wikisider.
+
+For å laste opp ei fil bruker du «Bla gjennom...» eller «Browse...»-knappen som opnar ein standarddialog for val av fil. Når du vel ei fil, vil namnet på denne fila dukke opp i tekstfeltet ved sida av knappen. Skriv inn \'\'\'all\'\'\' nødvendig informasjon i \'\'Samandrag\'\'-feltet, kryss av at du ikkje bryt nokon sin opphavsrett, og klikk til slutt på \'\'Last opp fil\'\'.',
+'uploadlog' => 'opplastingslogg',
+'uploadlogpage' => 'Opplastingslogg',
+'uploadlogpagetext' => 'Dette er ei liste over filer som nyleg er lasta opp.',
+'filename' => 'Filnamn',
+'filedesc' => 'Skildring',
+'fileuploadsummary' => 'Skildring:',
+'filestatus' => 'Opphavsrettsstatus',
+'filesource' => 'Kjelde',
+'copyrightpage' => '{{ns:4}}:Opphavsrett',
+'copyrightpagename' => '{{SITENAME}} opphavsrett',
+'uploadedfiles' => 'Filer som er opplasta',
+'minlength' => 'Namnet på fila må ha minst tre teikn.',
+'illegalfilename' => 'Filnamnet «$1» inneheld teikn som ikkje er tillatne i sidetitlar. Skift namn på fila og prøv på nytt.',
+'badfilename' => 'Namnet på fila har vorte endra til «$1».',
+'badfiletype' => 'Filformatet «.$1» er ikkje tillete.',
+'largefile' => 'Det er frårådd å bruke filer som er større enn $1 byte, denne fila er $2 byte.',
+'emptyfile' => 'Det ser ut til at fila du lasta opp er tom. Dette kan komma av ein skrivefeil i filnamnet. Sjekk og tenk etter om du verkeleg vil laste opp fila.',
+'fileexists' => 'Ei fil med dette namnet finst allereie, sjekk $1 om du ikkje er sikker på om du vil endre namnet.',
+'successfulupload' => 'Opplastinga er ferdig',
+'fileuploaded' => 'Fila «$1» er opplasta. Følg lenkja «$2» åt sida med skildring og fyll ut informasjon om fila &mdash; slik som kvar ho kom frå, kva tid ho vart laga og av kven, og andre ting du veit om fila.',
+'uploadwarning' => 'Opplastingsåtvaring',
+'savefile' => 'Lagre fil',
+'uploadedimage' => 'Lasta opp «[[$1]]»',
+'uploaddisabled' => 'Beklagar, funksjonen for opplasting er deaktivert på denne nettenaren.',
+'uploadscripted' => 'Fila inneheld HTML- eller skriptkode som feilaktig kan bli tolka og køyrd av nettlesarar.',
+'uploadcorrupt' => 'Fila er øydelagd eller har feil etternamn. Sjekk fila og prøv på nytt.',
+'uploadvirus' => 'Fila innheld virus! Detaljar: $1',
+'sourcefilename' => 'Filsti',
+'destfilename' => 'Målfilnamn',
+
+# Image list
+#
+'imagelist' => 'Filliste',
+'imagelisttext' => 'Her er ei liste med $1 filer sorterte $2.',
+'getimagelist' => 'hentar filliste',
+'ilsubmit' => 'Søk',
+'showlast' => 'Vis dei siste $1 filene sorterte $2.',
+'byname' => 'etter namn',
+'bydate' => 'etter dato',
+'bysize' => 'etter storleik',
+'imgdelete' => 'slett',
+'imgdesc' => 'skildring',
+'imglegend' => 'Forklaring: (skildring) = vis/endre filskildring.',
+'imghistory' => 'Filhistorikk',
+'revertimg' => 'rulltb',
+'deleteimg' => 'slett',
+'deleteimgcompletely' => 'Slett alle versjonar av fila',
+'imghistlegend' => 'Forklaring: (no) = dette er den noverande versjonen av fila, (slett) = slett denne versjonen, (rulltb) = tilbake til denne versjonen.<br /><i>Klikk på ein dato for å sjå fila som vart opplasta då</i>.',
+'imagelinks' => 'Fillenkjer',
+'linkstoimage' => 'Dei følgjande sidene har lenkjer til denne fila:',
+'nolinkstoimage' => 'Det finst ikkje noka side med lenkje til denne fila.',
+'sharedupload' => 'Denne fila er ei delt opplasting og kan brukast av andre prosjekt.',
+'shareduploadwiki' => 'Sjå $1 for meir informasjon.',
+'shareduploadwiki-linktext' => 'filskildringssida',
+'noimage' => 'Det finst ikkje noka fil med dette namnet, men du kan $1',
+'noimage-linktext' => 'laste ho opp',
+'uploadnewversion-linktext' => 'Last opp ny versjon av denne fila',
+
+# Statistics
+#
+'statistics' => 'Statistikk',
+'sitestats' => '{{SITENAME}}-statistikk',
+'userstats' => 'Brukarstatistikk',
+'sitestatstext' => 'Det er i alt \'\'\'$1\'\'\' sider i databasen. Dette inkluderer diskusjonssider, sider om {{SITENAME}}, småsider,
+omdirigeringssider, og andre som truleg ikkje kan kallast innhaldssider. Om ein ser bort frå desse sidene, er det \'\'\'$2\'\'\' sider som truleg er innhaldssider.
+
+Alle sidene er vortne viste \'\'\'$3\'\'\' gonger og endra \'\'\'$4\'\'\' gonger sidan programvaren vart installert. Det vil seie at kvar side gjennomsnittleg har vorte endra \'\'\'$5\'\'\' gonger, og vist \'\'\'$6\'\'\' gonger per endring.',
+'userstatstext' => '{{SITENAME}} har \'\'\'$1\'\'\' registrerte brukarar. \'\'\'$2\'\'\' (eller \'\'\'$4%\'\'\') av desse er administratorar (sjå $3).',
+
+# Maintenance Page
+#
+'disambiguations' => 'Fleirtydingssider',
+'disambiguationspage' => 'Template:Fleirtyding',
+'disambiguationstext' => 'Dei følgjande artiklane har lenkjer til <i>artiklar med fleirtydige titlar</i>. Dei burde heller lenkje til ein ikkje-fleirtydig tittel i staden.<br />Ein artikkeltittel blir handsama som fleirtydig om han har lenkjer frå $1.<br />Lenkjer frå andre namnerom er <i>ikkje</i> opprekna her.',
+'doubleredirects' => 'Doble omdirigeringar',
+'doubleredirectstext' => 'Kvar line inneheld lenkjer til den første og den andre omdirigeringa, og den første lina frå den andre omdirigeringsteksten. Det gjev som regel den «rette» målartikkelen, som den første omdirigeringa skulle ha peikt på.',
+'brokenredirects' => 'Blindvegsomdirigeringar',
+'brokenredirectstext' => 'Dei følgjande omdirigeringane viser til ei side som ikkje finst.',
+
+# Miscellaneous special pages
+#
+'lonelypages' => 'Foreldrelause sider',
+'uncategorizedpages' => 'Ikkje kategoriserte sider',
+'uncategorizedcategories' => 'Ikkje kategoriserte kategoriar',
+'unusedcategories' => 'Ubrukte kategoriar',
+'unusedimages' => 'Ubrukte filer',
+'popularpages' => 'Populære sider',
+'nviews' => '$1 visingar',
+'wantedpages' => 'Etterspurde sider',
+'mostlinked' => 'Sider mest lenkja til',
+'nlinks' => '$1 lenkjer',
+'allpages' => 'Alle sider',
+'prefixindex' => 'Prefiksindeks',
+'randompage' => 'Tilfeldig side',
+'shortpages' => 'Korte sider',
+'longpages' => 'Lange sider',
+'deadendpages' => 'Blindvegsider',
+'listusers' => 'Brukarliste',
+'specialpages' => 'Spesialsider',
+'spheading' => 'Spesialsider for alle brukarar',
+'restrictedpheading' => 'Spesialsider med avgrensa tilgang',
+
+'recentchangeslinked' => 'Relaterte endringar',
+'rclsub' => '(til sider med lenkje frå «$1»)',
+'newpages' => 'Nye sider',
+'ancientpages' => 'Eldste sider',
+'intl' => 'Språklenkjer',
+'move' => 'Flytt',
+'movethispage' => 'Flytt side',
+'unusedimagestext' => '<p>Merk deg at andre internettsider kan ha lenkjer til filer som er lista her. Dei kan difor vera i aktiv bruk.</p>',
+'unusedcategoriestext' => 'Dei følgjande kategorisidene er oppretta, sjølv om ingen artikkel eller kategori brukar dei.',
+
+'booksources' => 'Bokkjelder',
+'categoriespagetext' => 'Wikien har følgjande kategoriar.',
+'data' => 'Data',
+'userrights' => 'Administrering av brukartilgang',
+'groups' => 'Brukargrupper',
+'booksourcetext' => 'Her er ei liste over lenkjer til internettsider som låner ut og/eller sel nye og/eller brukte bøker, og som kanskje har meir informasjon om bøker du leitar etter. {{SITENAME}} er ikkje nødvendigvis assosiert med nokon av desse sidene, og lista er <b>ikkje</b> å rekne som ei spesifikk tilråding om å bruke dei.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 til $2',
+'version' => 'Versjon',
+'log' => 'Loggar',
+'alllogstext' => 'Kombinert vising av opplastings-, slette-, verne-, blokkerings- og administrator-loggar. Du kan avgrense visinga ved å velja loggtype, brukarnamn, og/eller sidnamn.',
+
+# Special:Allpages
+'nextpage' => 'Neste side ($1)',
+'allpagesfrom' => 'Vis sider frå:',
+'allarticles' => 'Alle sider',
+'allinnamespace' => 'Alle sider ($1 namnerom)',
+'allnotinnamespace' => 'Alle sider (ikkje i $1-namnerommet)',
+'allpagesprev' => 'Førre',
+'allpagesnext' => 'Neste',
+'allpagessubmit' => 'Vis',
+
+# Email this user
+#
+'mailnologin' => 'Inga avsendaradresse',
+'mailnologintext' => 'Du lyt vera [[Special:Userlogin|innlogga]] og ha ei gyldig e-postadresse sett i [[Special:Preferences|brukarinnstillingane]] for å sende e-post åt andre brukarar.',
+'emailuser' => 'Send e-post åt denne brukaren',
+'emailpage' => 'Send e-post åt brukar',
+'emailpagetext' => 'Om denne brukaren har gjeve ei gyldig e-postadresse i brukarinnstillingane sine, vil dette skjemaet sende ei enkel melding. E-postadressa di frå brukarinnstillingane dine vil vera synleg i «Frå»-feltet i denne e-posten, slik at mottakaren kan svara deg.',
+'usermailererror' => 'E-post systemet gav feilmelding:',
+'defemailsubject' => '{{SITENAME}} e-post',
+'noemailtitle' => 'Inga e-postadresse',
+'noemailtext' => 'Denne brukaren har ikkje oppgjeve ei gyldig e-postadresse, eller har valt å ikkje opne for e-post frå andre brukarar.',
+'emailfrom' => 'Frå',
+'emailto' => 'Åt',
+'emailsubject' => 'Emne',
+'emailmessage' => 'Melding',
+'emailsend' => 'Send',
+'emailsent' => 'E-posten er sendt',
+'emailsenttext' => 'E-posten er sendt.',
+
+# Watchlist
+#
+'watchlist' => 'Overvakingsliste',
+'nowatchlist' => 'Du har ikkje noko i overvakingslista di.',
+'watchnologin' => 'Ikkje innlogga',
+'watchnologintext' => 'Du lyt vera [[Special:Userlogin|innlogga]] for å kunna endre overvakingslista.',
+'addedwatch' => 'Lagt til overvakingslista',
+'addedwatchtext' => 'Sida «$1» er lagt til [[Special:Watchlist|overvakingslista]] di. Framtidige endringar av denne sida og den tilhøyrande diskusjonssida vil bli oppførde her, og sida vil vera \'\'\'utheva\'\'\' på «[[Special:Recentchanges|siste endringar]]» for å gjera deg merksam på henne.
+
+Om du seinere vil fjerne sida frå overvakingslista, klikk på «Fjern overvaking» på den aktuelle sida.',
+'removedwatch' => 'Fjerna frå overvakingslista',
+'removedwatchtext' => 'Sida «$1» er fjerna frå overvakingslista.',
+'watch' => 'Overvak',
+'watchthispage' => 'Overvak denne sida',
+'unwatch' => 'Fjern overvaking',
+'unwatchthispage' => 'Fjern overvaking',
+'notanarticle' => 'Ikkje innhaldsside',
+'watchnochange' => 'Ingen av sidene i overvakingslista er endra i den valde perioden.',
+'watchdetails' => 'Du har $1 sider i overvakingslista di (diskusjonssider ikkje medrekna); du kan [[Special:Watchlist/edit|vise og endre den fullstendige lista]].',
+'wlheader-enotif' => '* Funksjonen for endringsmeldingar per e-post er på.',
+'wlheader-showupdated' => '* Sider som har vorte endra sidan du sist såg på dei er \'\'\'utheva\'\'\'',
+'watchmethod-recent' => 'sjekkar siste endringar for dei overvaka sidene',
+'watchmethod-list' => 'sjekkar om dei overvaka sidene er vortne endra i det siste',
+'removechecked' => 'Fjern dei valde sidene frå overvakingslista',
+'watchlistcontains' => 'Overvakingslista inneheld $1 sider.',
+'watcheditlist' => 'Dette er ei alfabetisk liste over sider du overvakar. For å fjerne sider frå lista må du velja dei sidene du vil fjerne og klikke på «Fjern overvaking»-knappen nedst på sida.',
+'removingchecked' => 'Fjernar dei valde sidene frå overvakingslista ...',
+'couldntremove' => 'Kunne ikkje fjerne «$1»...',
+'iteminvalidname' => 'Problem med «$1», ugyldig namn...',
+'wlnote' => 'Nedanfor er dei siste $1 endringane dei siste <b>$2</b> timane.',
+'wlshowlast' => 'Vis siste $1 timar $2 dagar $3',
+'wlsaved' => 'Dette er ein mellomlagra versjon av overvakingslista di.',
+'wlhideshowown' => '$1 eigne endringar.',
+
+'enotif_mailer' => '{{SITENAME}}-endringsmeldingssendar',
+'enotif_reset' => 'Merk alle sider som vitja',
+'enotif_newpagetext' => 'Dette er ei ny side.',
+'changed' => 'endra',
+'created' => 'oppretta',
+'enotif_subject' => '{{SITENAME}}-sida $PAGETITLE har vorte $CHANGEDORCREATED av $PAGEEDITOR',
+'enotif_lastvisited' => 'Sjå $1 for alle endringane sidan siste vitjing.',
+'enotif_body' => 'Hei $WATCHINGUSERNAME,
+
+{{SITENAME}}-sida $PAGETITLE har vorte $CHANGEDORCREATED $PAGEEDITDATE av $PAGEEDITOR, sjå $PAGETITLE_URL for den gjeldande versjonen.
+
+$NEWPAGE
+
+Bidragytaren sitt endringssamandrag: $PAGESUMMARY $PAGEMINOREDIT
+
+Du kan kontakte bidragsytaren gjennom:
+e-post: $PAGEEDITOR_EMAIL , eller
+wiki: $PAGEEDITOR_WIKI
+
+Du får ikkje fleire endringsmeldingar om denne sida før du har vitja henne på nytt. Du kan også tilbakestille endringsmeldingsstatus for alle sidene på overvakingslista di.
+
+ Helsing din overvakande {{SITENAME}}-endringsmeldingssystemven
+
+--
+For å endre innstillingane for overvakingslista di, gå til
+{{fullurl:Special:Watchlist/edit}}
+
+For hjelp og meir informasjon:
+{{fullurl:Hjelp:Overvaking}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Slett side',
+'confirm' => 'Stadfest',
+'excontent' => 'innhaldet var: «$1»',
+'excontentauthor' => 'innhaldet var: «$1» (og den einaste bidragsytaren var «[[{{ns:2}}:$2|$2]]»)',
+'exbeforeblank' => 'innhaldet før sida vart tømd var: «$1»',
+'exblank' => 'sida var tom',
+'confirmdelete' => 'Stadfest sletting',
+'deletesub' => '(Slettar «$1»)',
+'historywarning' => 'Åtvaring: Sida du held på å slette har ein historikk:',
+'confirmdeletetext' => 'Du held på å varig slette ei side eller eit bilete saman med heile den tilhøyrande historikken frå databasen. Stadfest at du verkeleg vil gjera dette, at du skjønner konsekvensane, og at du gjer dette i tråd med [[Project:Retningsliner|retningslinene]].',
+'actioncomplete' => 'Ferdig',
+'deletedtext' => '«$1» er sletta. Sjå $2 for eit oversyn over dei siste slettingane.',
+'deletedarticle' => 'sletta «[[$1]]»',
+'dellogpage' => 'Slettelogg',
+'dellogpagetext' => 'Her er ei liste over dei siste slettingane.',
+'deletionlog' => 'slettelogg',
+'reverted' => 'Attenderulla til ein tidlegare versjon',
+'deletecomment' => 'Grunn for sletting',
+'imagereverted' => 'Attenderulling av tidlegare versjon ferdig.',
+'rollback' => 'Rull attende endringar',
+'rollback_short' => 'Rull attende',
+'rollbacklink' => 'rull attende',
+'rollbackfailed' => 'Kunne ikkje rulle attende',
+'cantrollback' => 'Kan ikkje rulle attende fordi den siste brukaren er den einaste forfattaren.',
+'alreadyrolled' => 'Kan ikkje rulle attende den siste endringa av [[:$1]] gjort av [[{{ns:2}}:$2|$2]] ([[{{ns:3}}:$2|brukardiskusjon]]) fordi nokon andre allereie har endra sida att eller fjerna endringa.
+
+Den siste endringa vart gjort av [[{{ns:2}}:$3|$3]] ([[{{ns:3}}:$3|brukardiskusjon]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Samandraget for endringa var: "<i>$1</i>".',
+'revertpage' => 'Attenderulla endring gjort av [[{{ns:2}}:$2|$2]] til tidlegare versjon endra av [[{{ns:2}}:$1|$1]]',
+'sessionfailure' => 'Det ser ut til å vera eit problem med innloggingsøkta di. Handlinga er vorten avbroten for å vera føre var mot kidnapping av økta. Bruk attendeknappen i nettlesaren din og prøv om att.',
+'protectlogpage' => 'Vernelogg',
+'protectlogtext' => 'Dette er ei liste over sider som er vortne verna eller har fått fjerna vern. Sjå [[{{ns:4}}:Verna side]] for meir info.',
+'protectedarticle' => 'verna «[[$1]]»',
+'unprotectedarticle' => 'fjerna vern av «[[$1]]»',
+'protectsub' => '(Vernar «$1»)',
+'confirmprotecttext' => 'Er du sikker på at du vil verne denne sida?',
+'confirmprotect' => 'Stadfest vern',
+'protectmoveonly' => 'Berre vern mot flytting',
+'protectcomment' => 'Grunn til verning',
+'unprotectsub' => '(Fjernar vern av «$1»)',
+'confirmunprotecttext' => 'Er du sikker på at du vil fjerne vernet av denne sida?',
+'confirmunprotect' => 'Stadfest fjerning av vern',
+'unprotectcomment' => 'Grunn til fjerning av vern',
+
+# Undelete
+'undelete' => 'Sletta sider',
+'undeletepage' => 'Sletta sider',
+'viewdeletedpage' => 'Sjå sletta sider',
+'undeletepagetext' => 'Dei følgjande sidene er sletta, men dei finst enno i arkivet og kan attopprettast. Arkivet blir periodevis sletta.',
+'undeletearticle' => 'Attopprett sletta side',
+'undeleterevisions' => '$1 versjonar arkiverte',
+'undeletehistory' => 'Om du attopprettar sida, vil alle versjonane i historikken også bli attoppretta. Dersom ei ny side med same namnet er oppretta sidan den gamle sida vart sletta, vil dei attoppretta versjonane dukke opp i historikken, og den nyaste versjonen vil bli verande som han er.',
+'undeletehistorynoadmin' => 'Ein eller fleire versjonar av denne sida har blitt sletta. Grunnlaget for sletting er oppgjeve under, saman med informasjon om kven som sletta og når versjonane vart sletta. Innhaldet i dei sletta versjonane er berre tilgjengeleg for [[special:listusers/sysop|administratorar]].',
+'undeleterevision' => 'Sletta versjon frå $1',
+'undeletebtn' => 'Attopprett!',
+'undeletedarticle' => 'attoppretta «[[$1]]»',
+'undeletedrevisions' => '$1 versjonar attoppretta',
+
+ # Namespace form on various pages
+'namespace' => 'Namnerom:',
+'invert' => 'Vreng val',
+
+# Contributions
+#
+'contributions' => 'Brukarbidrag',
+'mycontris' => 'Eigne bidrag',
+'contribsub' => 'For $1',
+'nocontribs' => 'Det vart ikkje funne nokon endringar gjorde av denne brukaren.',
+'ucnote' => 'Her er dei siste <b>$1</b> endringane frå denne brukaren dei siste <b>$2</b> dagane.',
+'uclinks' => 'Vis dei siste $1 endringane; vis dei siste $2 dagane.',
+'uctop' => ' (øvst)' ,
+'newbies' => 'ferskingar',
+
+# What links here
+#
+'whatlinkshere' => 'Lenkjer hit',
+'notargettitle' => 'Inkje mål',
+'notargettext' => 'Du har ikkje spesifisert noka målside eller nokon brukar å bruke denne funksjonen på.',
+'linklistsub' => '(Liste over lenkjer)',
+'linkshere' => 'Desse sidene har lenkjer hit:',
+'nolinkshere' => 'Inga side har lenkje hit.',
+'isredirect' => 'omdirigeringsside',
+
+# Block/unblock IP
+#
+'blockip' => 'Blokker brukar',
+'blockiptext' => 'Bruk skjemaet nedanfor for å blokkere skrivetilgangen frå ei spesifikk IP-adresse eller brukarnamn. Dette bør berre gjerast for å hindre hærverk, og i samsvar med [[Project:Retningsliner|retningslinene]]. Skriv grunngjeving nedanfor (t.d. med sitat frå sider som er vortne utsette for hærverk). Opphørstid for blokkeringa skriv ein med GNU standardformat, som er skildra i [http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html tar manualen] (engelsk), t.d. «1 hour», «2 days», «next Wednesday», «1 January 2017». Alternativt kan ei blokkering vera «indefinite» (ikkje fastsett) eller «infinite» (uendeleg).
+
+For informasjon om korleis ein kan blokkere seriar av IP-adresser, sjå [http://meta.wikimedia.org/wiki/Range_blocks] (engelsk). For å oppheve blokkering, sjå [[Special:Ipblocklist|blokkeringslista]].',
+'ipaddress' => 'IP-adresse',
+'ipadressorusername' => 'IP-adresse eller brukarnamn',
+'ipbreason' => 'Grunngjeving',
+'ipbsubmit' => 'Blokker denne brukaren',
+'ipbother' => 'Anna tid',
+'ipboptions' => '2 timar:2 hours,1 dag:1 day,3 dagar:3 days,1 veke:1 week,2 veker:2 weeks,1 månad:1 month,3 månader:3 months,6 månader:6 months,1 år:1 year,endelaus:infinite',
+'ipbotheroption' => 'anna tid',
+'badipaddress' => 'IP-adressa var ugyldig eller brukarblokkering er deaktivert på tenaren.',
+'blockipsuccesssub' => 'Blokkering utført',
+'blockipsuccesstext' => '«[[User:$1|$1]]» er blokkert.<br />Sjå [[Special:Ipblocklist|blokkeringslista]] for alle blokkeringar.',
+'unblockip' => 'Opphev blokkering',
+'unblockiptext' => 'Bruk skjemaet nedanfor for å oppheve blokkeringa av ein tidlegare blokkert brukar.',
+'ipusubmit' => 'Opphev blokkering',
+'ipblocklist' => 'Blokkerte IP-adresser og brukarnamn',
+'blocklistline' => '$1, $2 blokkerte $3 ($4)',
+'infiniteblock' => 'uendeleg opphørstid',
+'expiringblock' => '$1 opphørstid',
+'ipblocklistempty' => 'Blokkeringslista er tom.',
+'blocklink' => 'blokker',
+'unblocklink' => 'opphev blokkering',
+'contribslink' => 'bidrag',
+'autoblocker' => 'Automatisk blokkert fordi du deler IP-adresse med [[{{ns:2}}:$1|$1]]. Grunngjeving gjeve for blokkeringa av $1 var: «$2».',
+'blocklogpage' => 'Blokkeringslogg',
+'blocklogentry' => 'Blokkerte «[[$1]]» med opphørstid $2',
+'blocklogtext' => 'Dette er ein logg over blokkeringar og oppheving av blokkeringar gjorde av [[{{ns:4}}:Administratorar|administratorar]].
+IP-adresser som blir automatisk blokkerte er ikkje lista her. Sjå [[{{ns:-1}}:Ipblocklist|blokkeringslista]] for alle aktive blokkeringar.',
+'unblocklogentry' => 'oppheva blokkering av «$1»',
+'range_block_disabled' => 'Funksjonen for blokkering av IP-adresse-seriar er deaktivert på tenaren.',
+'ipb_expiry_invalid' => 'Ugyldig opphørstid.',
+'ip_range_invalid' => 'Ugyldig IP-adresseserie.',
+'proxyblocker' => 'Proxy-blokkerar',
+'proxyblockreason' => 'Du er blokkert frå å endre fordi IP-adressa di tilhøyrer ein open mellomtenar (proxy). Du bør kontakte internettleverandøren din eller kundesørvis og gje dei beskjed, ettersom dette er eit alvorleg sikkerheitsproblem.',
+'proxyblocksuccess' => 'Utført.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'IP-adressa di er lista som ein open mellomtenar i [http://www.sorbs.net SORBS DNSBL].
+
+Dersom du er feilaktig blokkert kan http://www.sorbs.net/faq/retest.shtml vera til hjelp for å få IP-adressa di fjerna frå svartelista.',
+'sorbs_create_account_reason' => 'IP-adressa di er lista som ein open mellomtenar i [http://www.sorbs.net SORBS] DNSBL, og difor får du ikkje registrert deg.',
+
+# Developer tools
+#
+'lockdb' => 'Skrivevern (lock) database',
+'unlockdb' => 'Opphev skrivevern (unlock) av databasen',
+'lockdbtext' => 'Å skriveverne databasen vil gjere det umogleg for alle brukarar å endre sider, brukarinnstillingar, overvakingslister og andre ting som krev endringar i databasen. Stadfest at du ønskjer å gjera dette, og at du vil låse opp databasen att når vedlikehaldet er ferdig.',
+'unlockdbtext' => 'Å oppheva skrivevernet på databasen fører til at alle brukarar kan endre sider, brukarinnstillingar, overvakingslister og andre ting som krev endringar i databasen att. Stadfest at du ønskjer å gjera dette.',
+'lockconfirm' => 'Ja, eg vil verkeleg skriveverne databasen.',
+'unlockconfirm' => 'Ja, eg vil verkeleg oppheva skrivevernet på databasen.',
+'lockbtn' => 'Skrivevern databasen',
+'unlockbtn' => 'Opphev skrivevern på databasen',
+'locknoconfirm' => 'Du har ikkje stadfest handlinga.',
+'lockdbsuccesssub' => 'Databasen er no skriveverna',
+'unlockdbsuccesssub' => 'Srivevernet på databasen er no oppheva',
+'lockdbsuccesstext' => 'Databasen er no skriveverna. <br />Hugs å oppheve skrivevernet når du er ferdig med vedlikehaldet.',
+'unlockdbsuccesstext' => 'Skrivevernet er oppheva.',
+
+# Make sysop
+'makesysoptitle' => 'Gjer brukar om til administrator',
+'makesysoptext' => 'Dette skjemaet kan brukast av byråkratar til å gjera vanlege brukarar om til administratorar. Skriv inn namnet på brukaren i tekstboksen og trykk på knappen for å gjere brukaren om til administrator',
+'makesysopname' => 'Brukarnamn:',
+'makesysopsubmit' => 'Gjer brukaren om til administrator',
+'makesysopok' => '<b>Brukaren «$1» er no administrator</b>',
+'makesysopfail' => '<b>Brukaren «$1» kunne ikkje gjerast om til administrator. (Skreiv du brukarnamnet rett?)</b>',
+'setbureaucratflag' => 'Gje byråkrat-tilgang',
+'rightslogtext' => 'Dette er ein logg over endringar av brukartilgang.',
+'rights' => 'Tilgang:',
+'set_user_rights' => 'Set brukartilgang',
+'user_rights_set' => '<b>Brukartilgang for «$1» er oppdatert</b>',
+'set_rights_fail' => '<b>Brukartilgang for «$1» kunne ikkje setjast. (Skreiv du brukarnamnet rett?)</b>',
+'makesysop' => 'Gje brukar administratortilgang',
+'already_sysop' => 'Denne brukaren har allereie administratortilgang',
+'already_bureaucrat' => 'Denne brukaren har allereie byråkrat-tilgang',
+
+# Move page
+#
+'movepage' => 'Flytt side',
+'movepagetext' => 'Ved å bruke skjemaet nedanfor kan du få omdøypt ei side og flytt heile historikken til det nye namnet. Den gamle tittelen vil bli ei omdirigeringsside til den nye tittelen. Lenkjer til den gamle tittelen vil ikkje bli endra. Pass på å sjekke for doble eller dårlege omdirigeringar. Du er ansvarleg for at alle lenkjene stadig peiker dit det er meininga at dei skal peike.
+
+Merk at sida \'\'\'ikkje\'\'\' kan flyttast dersom det allereie finst ei side med den nye tittelen. Du kan likevel flytte ei side attende dit ho vart flytt frå dersom du gjer ein feil, så lenge den sida du flytter attende til ikkje er vorten endra sidan flyttinga.
+
+<b>ÅTVARING!</b> Dette kan vera ei drastisk og uventa endring for ei populær side; ver sikker på at du skjønner konsekvensane av dette før du fortset.',
+'movepagetalktext' => 'Den tilhøyrande diskusjonssida, om ho finst, vil automatisk bli flytt med sida \'\'\'med mindre:\'\'\'
+*Du flytter sida til eit anna namnerom,
+*Ei diskusjonsside som ikkje er tom allereie finst under det nye namnet, eller
+*Du fjernar merkinga i boksen nedanfor.
+
+I desse falla lyt du flytte eller flette saman sida manuelt. Om det ikkje er mogleg for deg å gjera dette kan du kontakte ein [[{{ns:4}}:Administratorar|administrator]], men <b>ikkje</b> bruk klipp-og-lim metoden sidan dette ikkje tek vare på endringshistorikken.',
+'movearticle' => 'Flytt side',
+'movenologin' => 'Ikkje innlogga',
+'movenologintext' => 'Du lyt vera registrert brukar og vera [[Special:Userlogin|innlogga]] for å flytte ei side.',
+'newtitle' => 'Til ny tittel',
+'movepagebtn' => 'Flytt side',
+'pagemovedsub' => 'Flyttinga er gjennomført',
+'pagemovedtext' => 'Sida «[[$1]]» er flytt til «[[$2]]».',
+'articleexists' => 'Ei side med det namnet finst allereie, eller det namnet du har valt er ikkje gyldig. Vel eit anna namn.',
+'talkexists' => '\'\'\'Innhaldssida vart flytt, men diskusjonssida som høyrer til kunne ikkje flyttast fordi det allereie finst ei side med den nye tittelen. Du lyt flette dei saman manuelt. Dersom det ikkje er mogleg for deg å gjera dette kan du kontakte ein <a href="{{localurl:Project:Administratorar}}">administrator</a> &#8212; men <b>ikkje</b> bruk klipp-og-lim metoden sidan dette ikkje tek vare på endringshistorikken.\'\'\'',
+'movedto' => 'er flytt til',
+'movetalk' => 'Flytt diskusjonssida òg om ho finst.',
+'talkpagemoved' => 'Diskusjonssida som høyrer til vart òg flytt.',
+'talkpagenotmoved' => 'Diskusjonssida som høyrer til vart <strong>ikkje</strong> flytt.',
+'1movedto2' => '«[[$1]]» flytt til «[[$2]]»',
+'1movedto2_redir' => '«[[$1]]» flytt over omdirigering til «[[$2]]»',
+'movelogpage' => 'Flyttelogg',
+'movelogpagetext' => 'Under er ei liste over sider som er flytte.',
+'movereason' => 'Grunngjeving',
+'revertmove' => 'attende',
+'delete_and_move' => 'Slett og flytt',
+'delete_and_move_text' => '== Sletting påkrevd ==
+
+Målsida «[[$1]]» finst allereie. Vil du slette ho for å gje rom for flytting?',
+'delete_and_move_reason' => 'Sletta for å gje rom for flytting',
+'selfmove' => 'Kjelde- og måltitlane er like; kan ikkje flytte sida over seg sjølv.',
+'immobile_namespace' => 'Måltittelen høyrer til eit namnerom som gjer at sida ikkje kan flyttast dit.',
+
+# Export
+'export' => 'Eksporter sider',
+'exporttext' => 'Du kan eksportere teksten og endringshistorikken til ei side eller ein serie sider, pakka inn i litt XML. I framtida kan det hende at dette att kan bli importert til ei anna wiki som brukar MediaWiki-programvaren, men det er det ikkje støtte for dette i denne versjonen av MediaWiki.
+
+For å eksportere sider, skriv tittelen i tekstboksen nedanfor, ein tittel per line, og vel om du vil ha med alle versjonane eller berre siste versjon.
+
+Dersom du berre vil ha den siste versjonen kan du òg bruke ei lenkje, t.d. [[{{ns:Special}}:Export/MediaWiki]] for [[MediaWiki]] sida.',
+'exportcuronly' => 'Berre eksporter siste versjonen, ikkje med heile historikken.',
+
+# Namespace 8 related
+'allmessages' => 'Systemmeldingar',
+'allmessagesname' => 'Namn',
+'allmessagesdefault' => 'Standardtekst',
+'allmessagescurrent' => 'Noverande tekst',
+'allmessagestext' => 'Dette er ei liste over systemmeldingar i MediaWiki-namnerommet.',
+'allmessagesnotsupportedUI' => 'Det gjeldande språket for grensesnittet <b>$1</b>, støttar ikkje {{ns:-1}}:Allmessages.',
+'allmessagesnotsupportedDB' => '{{ns:-1}}:Allmessages er ikkje støtta fordi "wgUseDatabaseMessages" ikkje er aktivert på tenaren.',
+
+# Thumbnails
+'thumbnail-more' => 'Forstørr',
+'missingimage' => '<b>Bilete manglar</b><br /><i>$1</i>',
+'filemissing' => 'Fil manglar',
+
+# Special:Import
+'import' => 'Importer sider',
+'importinterwiki' => 'Transwikiimport',
+'importtext' => 'Du må først eksportere sida du vil importere til ei fil som du lagrar på maskina di, deretter kan du laste ho inn her.
+For å eksportere bruker du [[{{ns:-1}}:Export|eksportsida]] på kjeldewikien; hugs at kjelda òg må bruke MediaWiki-programvaren.',
+'importfailed' => 'Importeringa var mislukka: $1',
+'importnotext' => 'Tom eller ingen tekst',
+'importsuccess' => 'Importeringa er ferdig!',
+'importhistoryconflict' => 'Det kan vera at det er konflikt i historikken (kanskje sida vart importert før)',
+'importnosources' => 'Ingen kjelder for transwikiimport er oppgjevne og funksjonen for opplasting av historikk er deaktivert.',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Søk i {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Merk dette som ei uviktig endring [alt-i]',
+'tooltip-save' => 'Lagre endringane dine [alt-s]',
+'tooltip-preview' => 'Førehandsvis endringane dine, bruk denne funksjonen før du lagrar! [alt-p]',
+'tooltip-diff' => 'Vis skilnaden mellom din versjon og lagra versjon, utan å lagre. [alt-v]',
+'tooltip-compareselectedversions' => 'Sjå endringane mellom dei valde versjonane av denne sida. [alt-v]',
+'tooltip-watch' => 'Legg denne sida til i overvakingslista di [alt-w]',
+
+# Metadata
+'nodublincore' => 'Funksjonen for Dublin Core RDF metadata er deaktivert på denne tenaren.',
+'nocreativecommons' => 'Funksjonen for Creative Commons RDF er deaktivert på denne tenaren.',
+'notacceptable' => 'Wikitenaren kan ikkje gje data i noko format som programmet ditt kan lesa.',
+
+# Attribution
+'anonymous' => 'Anonym(e) brukar(ar) av {{SITENAME}}',
+'siteuser' => '{{SITENAME}} brukar $1',
+'lastmodifiedatby' => 'Denne sida vart sist endra $2, $1 av $3.',
+'and' => 'og',
+'othercontribs' => 'Basert på arbeid av $1.',
+'others' => 'andre',
+'siteusers' => '{{SITENAME}} brukar(ar) $1',
+'creditspage' => 'Sidegodskriving',
+'nocredits' => 'Det finst ikkje ikkje nokon godskrivingsinformasjon for denne sida.',
+
+# Spam protection
+'spamprotectiontitle' => 'Filter for vern mot reklame',
+'spamprotectiontext' => 'Sida du prøvde å lagre vart blokkert av filteret for vern mot reklame (spam). Dette skjedde truleg på grunn av ei ekstern lenkje.',
+'spamprotectionmatch' => 'Den følgjande teksten utløyste reklamefilteret: $1',
+'subcategorycount' => 'Det er $1 underkategoriar av denne kategorien.',
+'categoryarticlecount' => 'Det er $1 innhaldssider i denne kategorien.',
+'listingcontinuesabbrev' => ' vidare',
+
+# Info page
+'infosubtitle' => 'Informasjon om side',
+'numedits' => 'Tal endringar (innhaldsside): $1',
+'numtalkedits' => 'Tal endringar (diskusjonsside): $1',
+'numwatchers' => 'Tal brukarar som overvakar: $1',
+'numauthors' => 'Tal ulike bidragsytarar (innhaldsside): $1',
+'numtalkauthors' => 'Tal ulike bidragsytarar (diskusjonsside): $1',
+
+# Math options
+'mw_math_png' => 'Vis alltid som PNG',
+'mw_math_simple' => 'HTML om svært enkel, elles PNG',
+'mw_math_html' => 'HTML om mogleg, elles PNG',
+'mw_math_source' => 'Behald som TeX (for tekst-nettlesarar)',
+'mw_math_modern' => 'Tilrådd for moderne nettlesarar',
+'mw_math_mathml' => 'MathML dersom mogleg (eksperimentell)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Merk som patruljert',
+'markaspatrolledtext' => 'Merk denne innhaldssida som patruljert',
+'markedaspatrolled' => 'Merk som patruljert',
+'markedaspatrolledtext' => 'Den valde versjonen er vorten merkt som patruljert.',
+'rcpatroldisabled' => 'Siste-endringar-patruljering er deaktivert',
+'rcpatroldisabledtext' => 'Patruljeringsfunksjonen er deaktivert.',
+
+# stylesheets
+'monobook.js' => '/*
+<pre>
+*/
+/* verktøytips og snøggtastar */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Brukarsida mi\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Brukarsida for ip-adressa du endrar under\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Diskusjonssida mi\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskusjon om endringar gjorde av denne ip-adressa\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Innstillingane mine\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Liste over sidene du overvakar.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Liste over bidraga mine\');
+ta[\'pt-login\'] = new Array(\'o\',\'Det er ikkje obligatorisk å logga inn, men medfører mange fordelar.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Det er ikkje obligatorisk å logga inn, men medfører mange fordelar.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Logg ut\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Diskusjon om innhaldssida\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Du kan endre denne sida. Bruk førehandsvisings-knappen før du lagrar.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Legg til ein bolk på denne diskusjonssida.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Denne sida er verna, men du kan sjå kjeldeteksten.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Eldre versjonar av denne sida.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Vern denne sida\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Slett denne sida\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Attopprett denne sida\');
+ta[\'ca-move\'] = new Array(\'m\',\'Flytt denne sida\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Legg denne sida til i overvakingslista di\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Fjern denne sida frå overvakingslista di\');
+ta[\'search\'] = new Array(\'f\',\'Søk gjennom denne wikien\');
+ta[\'p-logo\'] = new Array(\'\',\'Hovudside\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Gå til hovudsida\');
+ta[\'n-portal\'] = new Array(\'\',\'Om prosjektet, kva du kan gjera, kvar du finn saker og ting\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Aktuelt\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Liste over dei siste endringane som er gjort på wikien.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Vis ei tilfeldig side\');
+ta[\'n-help\'] = new Array(\'\',\'Hjelp til å bruke alle funksjonane.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Støtt oss!\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Liste over alle wikisidene som har lenkjer hit\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Siste endringar på sider denne sida lenkjer til\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS-mating for denne sida\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom-mating for denne sida\');
+ta[\'t-contributions\'] = new Array(\'\',\'Sjå liste over bidrag frå denne brukaren\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Send ein e-post til denne brukaren\');
+ta[\'t-upload\'] = new Array(\'u\',\'Last opp filer\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Liste over spesialsider\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vis innhaldssida\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vis brukarsida\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Direktelenkje (filpeikar) til fil\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Dette er ei spesialside, du kan ikkje endre ho.\');
+ta[\'ca-nstab-project\'] = new Array(\'c\',\'Vis prosjektside\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Vis filside\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vis systemmelding\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vis mal\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vis hjelpeside\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vis kategoriside\');
+/*
+</pre>
+*/',
+
+# image deletion
+'deletedrevision' => 'Slett gammal versjon $1.',
+
+# browsing diffs
+'previousdiff' => '← Gå til førre skilnaden',
+'nextdiff' => 'Gå til neste skilnaden →',
+'imagemaxsize' => 'Avgrens bilete på filsider til (pikslar):',
+'thumbsize' => 'Miniatyrstørrelse:',
+'showbigimage' => 'Last ned høgoppløysingsversjon ($1x$2, $3 KB)',
+'newimages' => 'Filgalleri',
+'showhidebots' => '($1 bottar)',
+'noimages' => 'Her er ingen filer som kan visast.',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Brukar:',
+'speciallogtitlelabel' => 'Tittel:',
+
+'passwordtooshort' => 'Passordet er for kort. Det må vera minst $1 teikn langt.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Åtvaring\'\'\': Denne fila kan innehalda skadelege program, ved å opna ho kan systemet ditt ta skade.
+<hr />',
+
+'fileinfo' => '$1KB, MIME-type: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadata',
+
+# Exif tags
+'exif-imagewidth' => 'Breidd',
+'exif-imagelength' => 'Høgd',
+'exif-bitspersample' => 'Bitar per komponent',
+'exif-compression' => 'Komprimeringsteknikk',
+'exif-photometricinterpretation' => 'Pikselsamansetjing',
+'exif-orientation' => 'Retning',
+'exif-samplesperpixel' => 'Tal komponentar',
+'exif-planarconfiguration' => 'Dataarrangement',
+'exif-ycbcrpositioning' => 'Y- og C-posisjon',
+'exif-xresolution' => 'Oppløysing i breidda',
+'exif-yresolution' => 'Oppløysing i høgda',
+'exif-resolutionunit' => 'Eining for X- og Y-oppløysing',
+'exif-jpeginterchangeformatlength' => 'Byte JPEG-data',
+'exif-referenceblackwhite' => 'Svart og kvitt referanseverdipar',
+'exif-datetime' => 'Dato og tid endra',
+'exif-imagedescription' => 'Tittel',
+'exif-make' => 'Kameraprodusent',
+'exif-model' => 'Kameramodell',
+'exif-software' => 'Programvare brukt',
+'exif-artist' => 'Skapar',
+'exif-copyright' => 'Opphavsrettsleg eigar',
+'exif-exifversion' => 'Exif-versjon',
+'exif-flashpixversion' => 'Støtta Flashpix versjon',
+'exif-colorspace' => 'Fargerom',
+'exif-pixelydimension' => 'Gyldig biletbreidd',
+'exif-pixelxdimension' => 'Gyldig bilethøgd',
+'exif-makernote' => 'Produsentnotat',
+'exif-usercomment' => 'Brukarkommentarar',
+'exif-relatedsoundfile' => 'Tilknytt lydfil',
+'exif-datetimeoriginal' => 'Dato og tid laga',
+'exif-datetimedigitized' => 'Dato og tid digitalisert',
+'exif-subsectime' => 'Dato og tid subsekund',
+'exif-subsectimeoriginal' => 'Dato og tid laga subsekund',
+'exif-subsectimedigitized' => 'Dato og tid digitalisert subsekund',
+'exif-exposuretime' => 'Eksponeringstid',
+'exif-fnumber' => 'F-nummer',
+'exif-exposureprogram' => 'Eksponeringsprogram',
+'exif-isospeedratings' => 'Lysfølsemd (ISO)',
+'exif-shutterspeedvalue' => 'Lukkarfart',
+'exif-aperturevalue' => 'Blendartal',
+'exif-brightnessvalue' => 'Lysstyrke',
+'exif-exposurebiasvalue' => 'Exposure bias',
+'exif-subjectdistance' => 'Motivavstand',
+'exif-meteringmode' => 'Lysmålarmodus',
+'exif-lightsource' => 'Lyskjelde',
+'exif-flash' => 'Blits',
+'exif-focallength' => 'Linsefokallengd',
+'exif-subjectarea' => 'Motivområde',
+'exif-flashenergy' => 'Blitsstyrke',
+'exif-focalplaneresolutionunit' => 'Oppløysingseining for fokalplanet',
+'exif-subjectlocation' => 'Motivplassering',
+'exif-exposureindex' => 'Eksponeringsindeks',
+'exif-sensingmethod' => 'Sensor',
+'exif-filesource' => 'Filkjelde',
+'exif-scenetype' => 'Scenetype',
+'exif-cfapattern' => 'CFA-mønster',
+'exif-exposuremode' => 'Eksponeringsmodus',
+'exif-whitebalance' => 'Kvitbalanse',
+'exif-digitalzoomratio' => 'Digital zoom-rate',
+'exif-focallengthin35mmfilm' => '(Tilsvarande) brennvidd ved 35 mm film',
+'exif-scenecapturetype' => 'Motivtype',
+'exif-gaincontrol' => 'Scene control',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Metting',
+'exif-sharpness' => 'Skarpleik',
+'exif-subjectdistancerange' => 'Motivavstandsområde',
+'exif-imageuniqueid' => 'Unik bilete-ID',
+'exif-gpsversionid' => 'GPS-merke-versjon',
+'exif-gpslatituderef' => 'Nordleg eller sørleg breiddegrad',
+'exif-gpslatitude' => 'Breiddegrad',
+'exif-gpslongituderef' => 'Austleg eller vestleg lengdegrad',
+'exif-gpslongitude' => 'Lengdegrad',
+'exif-gpsaltituderef' => 'Høgdereferanse',
+'exif-gpsaltitude' => 'Høgd over havet',
+'exif-gpstimestamp' => 'GPS-tid (atomklokke)',
+'exif-gpssatellites' => 'Satellittar brukt for å måle',
+'exif-gpsstatus' => 'GPS-Mottakarstatus',
+'exif-gpsmeasuremode' => 'Målemodus',
+'exif-gpsdop' => 'Målepresisjon',
+'exif-gpsspeedref' => 'Fartsmåleining',
+'exif-gpsspeed' => 'Fart på GPS-mottakar',
+'exif-gpstrackref' => 'Referanse for rørsleretning',
+'exif-gpstrack' => 'Rørsleretning',
+'exif-gpsimgdirectionref' => 'Referanse for retning åt biletet',
+'exif-gpsimgdirection' => 'Retninga åt biletet',
+'exif-gpsmapdatum' => 'Geodetisk kartleggingsdata brukt',
+'exif-gpsdestlatituderef' => 'Referanse for målbreiddegrad',
+'exif-gpsdestlatitude' => 'Målbreiddegrad',
+'exif-gpsdestlongituderef' => 'Referanse for mållengdegrad',
+'exif-gpsdestlongitude' => 'Mållengdegrad',
+'exif-gpsdestdistanceref' => 'Referanse for avstand til mål',
+'exif-gpsdestdistance' => 'Avstand til mål',
+'exif-gpsprocessingmethod' => 'Namn på GPS-handsamingsmetode',
+'exif-gpsareainformation' => 'Namn på GPS-område',
+'exif-gpsdatestamp' => 'GPS-dato',
+'exif-gpsdifferential' => 'GPS differential correction',
+
+# Exif attributes
+'exif-compression-1' => 'Ukomprimert',
+
+'exif-orientation-1' => 'Normal', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Spegla vassrett', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Rotert 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Spegla loddrett', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Rotert 90° motsols og spegla vassrett', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Rotert 90° medsols', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Rotert 90° medsols og spegla loddrett', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Rotert 90° motsols', // 0th row: left; 0th column: bottom
+
+'exif-componentsconfiguration-0' => 'finst ikkje',
+
+'exif-exposureprogram-0' => 'Ikkje bestemt',
+'exif-exposureprogram-1' => 'Manuelt',
+'exif-exposureprogram-2' => 'Normalt program',
+'exif-exposureprogram-3' => 'Blendarprioritet',
+'exif-exposureprogram-4' => 'Lukkarprioritet',
+'exif-exposureprogram-5' => 'Kreativt program (mest mogleg skarpt)',
+'exif-exposureprogram-6' => 'Handlingsprogram (med vekt på snøgg lukkar)',
+'exif-exposureprogram-7' => 'Portrettmodus (for nærbilete med uskarp bakgrunn)',
+'exif-exposureprogram-8' => 'Landskapsmodus (for landskapsbilete med skarp bakgrunn)',
+
+'exif-subjectdistance-value' => '$1 meter',
+
+'exif-meteringmode-0' => 'Ukjent',
+'exif-meteringmode-1' => 'Snittmåling',
+'exif-meteringmode-2' => 'Snittmåling med vekt på midten',
+'exif-meteringmode-3' => 'Punktmåling',
+'exif-meteringmode-4' => 'Fleirpunktsmåling',
+'exif-meteringmode-5' => 'Mønster',
+'exif-meteringmode-6' => 'Delvis',
+'exif-meteringmode-255' => 'Annan',
+
+'exif-lightsource-0' => 'Ukjent',
+'exif-lightsource-1' => 'Dagslys',
+'exif-lightsource-2' => 'Fluorescerande',
+'exif-lightsource-4' => 'Blits',
+'exif-lightsource-9' => 'Fint vêr',
+'exif-lightsource-10' => 'Overskya vêr',
+'exif-lightsource-11' => 'Skugge',
+'exif-lightsource-12' => 'Fluorescerande dagslys (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Dag, kvitt, fluorescerande (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Kjølig, kvitt, fluorescerande (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Kvitt fluorescerande (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standardlys A',
+'exif-lightsource-18' => 'Standardlys B',
+'exif-lightsource-19' => 'Standardlys C',
+'exif-lightsource-255' => 'Anna lyskjelde',
+
+'exif-focalplaneresolutionunit-2' => 'tommar',
+
+'exif-sensingmethod-1' => 'Ikkje bestemt',
+'exif-sensingmethod-2' => 'Einbrikka fargeområdesensor',
+'exif-sensingmethod-3' => 'Tobrikka fargeområdesensor',
+'exif-sensingmethod-4' => 'Trebrikka fargeområdesensor',
+'exif-sensingmethod-7' => 'Trilinær sensor',
+
+'exif-scenetype-1' => 'Direkte fotografert bilete',
+
+'exif-customrendered-0' => 'Normal prosess',
+'exif-customrendered-1' => 'Tilpassa prosess',
+
+'exif-exposuremode-0' => 'Autoeksponert',
+'exif-exposuremode-1' => 'Manuelt eksponert',
+
+'exif-whitebalance-0' => 'Automatisk kvitbalanse',
+'exif-whitebalance-1' => 'Manuell kvitbalanse',
+
+'exif-scenecapturetype-0' => 'Standard',
+'exif-scenecapturetype-1' => 'Landskap',
+'exif-scenecapturetype-2' => 'Portrett',
+'exif-scenecapturetype-3' => 'Nattscene',
+
+'exif-gaincontrol-0' => 'Ingen',
+
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'Mjuk',
+'exif-contrast-2' => 'Hard',
+
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Låg metting',
+'exif-saturation-2' => 'Høg metting',
+
+'exif-sharpness-0' => 'Normal',
+'exif-sharpness-1' => 'Mjuk',
+'exif-sharpness-2' => 'Hard',
+
+'exif-subjectdistancerange-0' => 'Ukjent',
+'exif-subjectdistancerange-1' => 'Makro',
+'exif-subjectdistancerange-2' => 'Nært',
+'exif-subjectdistancerange-3' => 'Fjernt',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Nordleg breiddegrad',
+'exif-gpslatitude-s' => 'Sørleg breiddegrad',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Austleg lengdegrad',
+'exif-gpslongitude-w' => 'Vestleg lengdegrad',
+
+'exif-gpsstatus-a' => 'Måling pågår',
+
+'exif-gpsmeasuremode-2' => 'todimensjonalt målt',
+'exif-gpsmeasuremode-3' => 'tredimensjonalt målt',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometer per time',
+'exif-gpsspeed-m' => 'Engelsk mil per time',
+'exif-gpsspeed-n' => 'Knop',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Verkeleg retning',
+'exif-gpsdirection-m' => 'Magnetisk retning',
+
+# external editor support
+'edit-externally' => 'Endre denne fila med eit eksternt program',
+'edit-externally-help' => 'Sjå [[Help:Eksterne program|instruksjonane]] for meir informasjon.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'alle',
+'imagelistall' => 'alle',
+'watchlistall1' => 'alle',
+'watchlistall2' => 'alle',
+'namespacesall' => 'alle',
+
+# E-mail address confirmation
+'confirmemail' => 'Stadfest e-postadresse',
+'confirmemail_text' => '{{SITENAME}} krev at du stadfester e-postadressa di
+før du får brukt funksjonar knytt til e-post. Klikk på knappen under for å sende ei stadfestingsmelding
+til adressa di. E-posten kjem med ei lenkje som har ein kode; opne
+lenkja i nettlesaren din for å stadfeste at e-postadressa di er gyldig.',
+'confirmemail_send' => 'Send stadfestingsmelding',
+'confirmemail_sent' => 'Stadfestingsmelding er sendt.',
+'confirmemail_sendfailed' => 'Kunne ikkje sende stadfestingsmelding. Sjå til at adressa ikkje har ugyldige bokstavar.',
+'confirmemail_invalid' => 'Feil stadfestingskode. Koden er kanskje for forelda.',
+'confirmemail_success' => 'E-postadressa di er stadfest. Du kan no logge inn og kose deg med {{SITENAME}}.',
+'confirmemail_loggedin' => 'E-postadressa di er stadfest.',
+'confirmemail_error' => 'Noko gjekk gale når stadfestinga di skulle lagrast.',
+
+'confirmemail_subject' => 'Stadfesting av e-postadresse frå {{SITENAME}}',
+'confirmemail_body' => 'Nokon, truleg du, frå IP-adressa $1, har registrert kontoen «$2» med di e-postadresse på {{SITENAME}}.
+
+For å stadfeste at denne kontoen faktisk høyrer til deg og for å slå på
+funksjonar tilknytt e-post på {{SITENAME}} må du opne denne lenkja i nettlesaren din:
+
+$3
+
+Dersom dette *ikkje* er deg, må du ikkje opne lenkja. Denne stadfestingskoden
+blir forelda $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Prøv nøyaktig treff',
+'searchfulltext' => 'Søk i all tekst',
+'createarticle' => 'Lag side',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Interwiki transcluding is disabled]',
+'scarytranscludefailed' => '[Henting av mal for $1 gjekk ikkje, beklagar]',
+'scarytranscludetoolong' => '[Nettadressa er for lang, beklagar]',
+
+# Trackbacks
+'trackbackbox' => "<div id='mw_trackbacks'>
+Attendelenkjer for denne sida:<br />
+$1
+</div>",
+'trackbackremove' => ' ([$1 Slett])',
+'trackbacklink' => 'Attendelenkje',
+'trackbackdeleteok' => 'Attendelenkja vart sletta.',
+
+# delete conflict
+'deletedwhileediting' => 'Åtvaring: Denne sida har blitt sletta medan du endra den!',
+'confirmrecreate' => 'Brukaren «[[User:$1|$1]]» ([[User talk:$1|brukardiskusjon]]) sletta denne sida medan du endra den med denne grunngjevinga:
+: \'\'$2\'\'
+Du må stadfesta om du verkjeleg vil nyopprette denne sida.',
+'recreate' => 'Nyopprett',
+'tooltip-recreate' => 'Ved å trykkje på «Nyopprett» vert sida oppretta på nytt.',
+
+'unit-pixel' => 'px',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesNo.php b/languages/messages/MessagesNo.php
new file mode 100644
index 000000000000..93aab1534522
--- /dev/null
+++ b/languages/messages/MessagesNo.php
@@ -0,0 +1,1368 @@
+<?php
+/** Norwegian (Norsk (bokmål))
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Ingen', 'Fast venstre', 'Fast høyre', 'Flytende venstre'
+);
+
+$skinNames = array(
+ 'standard' => 'Standard',
+ 'nostalgia' => 'Nostalgi',
+ 'cologneblue' => 'Kölnerblå'
+);
+
+$bookstoreList = array(
+ 'Antikvariat.net' => 'http://www.antikvariat.net/',
+ 'Frida' => 'http://wo.uio.no/as/WebObjects/frida.woa/wa/fres?action=sok&isbn=$1&visParametre=1&sort=alfabetisk&bs=50',
+ 'Bibsys' => 'http://ask.bibsys.no/ask/action/result?cmd=&kilde=biblio&fid=isbn&term=$1&op=and&fid=bd&term=&arstall=&sortering=sortdate-&treffPrSide=50',
+ 'Akademika' => 'http://www.akademika.no/sok.php?ts=4&sok=$1',
+ 'Haugenbok' => 'http://www.haugenbok.no/resultat.cfm?st=extended&isbn=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Medium',
+ NS_SPECIAL => 'Spesial',
+ NS_MAIN => '',
+ NS_TALK => 'Diskusjon',
+ NS_USER => 'Bruker',
+ NS_USER_TALK => 'Brukerdiskusjon',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1-diskusjon',
+ NS_IMAGE => 'Bilde',
+ NS_IMAGE_TALK => 'Bildediskusjon',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki-diskusjon',
+ NS_TEMPLATE => 'Mal',
+ NS_TEMPLATE_TALK => 'Maldiskusjon',
+ NS_HELP => 'Hjelp',
+ NS_HELP_TALK => 'Hjelpdiskusjon',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Kategoridiskusjon',
+);
+
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+$linkTrail = '/^([æøåa-z]+)(.*)$/sDu';
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j., Y',
+ 'mdy both' => 'M j., Y "kl." H:i',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. M Y',
+ 'dmy both' => 'j. M Y "kl." H:i',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j.',
+ 'ymd both' => 'Y M j. "kl." H:i',
+);
+
+
+$messages = array(
+'tog-underline' => 'Strek under lenker:',
+'tog-highlightbroken' => 'Formater ødelagte lenker <a href="" class="new">slik</a> (alternativt: slik<a href="" class="internal">?</a>).',
+'tog-justify' => 'Blokkjusterte avsnitt',
+'tog-hideminor' => 'Skjul mindre endringer i siste endringer',
+'tog-extendwatchlist' => 'Utvid overvåkningslista til å vise alle endringer i valgt tidsrom',
+'tog-usenewrc' => 'Forbedret siste endringer (ikke for alle nettlesere)',
+'tog-numberheadings' => 'Nummerer overskrifter',
+'tog-showtoolbar' => 'Vis verktøylinje (JavaScript)',
+'tog-editondblclick' => 'Rediger sider ved å dobbeltklikke (JavaScript)',
+'tog-editsection' => 'Rediger avsnitt ved hjelp av [rediger]-lenke',
+'tog-editsectiononrightclick'=> 'Rediger avsnitt ved å høyreklikke på avsnittsoverskrift (JavaScript)',
+'tog-showtoc' => 'Vis innholdsfortegnelse (for sider med mer enn tre seksjoner)',
+'tog-rememberpassword' => 'Husk passordet',
+'tog-editwidth' => 'Full bredde på redigeringsboksen',
+'tog-watchcreations' => 'Overvåk sider du oppretter',
+'tog-watchdefault' => 'Overvåk alle redigerte sider',
+'tog-minordefault' => 'Merk i utgangspunktet alle redigeringer som mindre',
+'tog-previewontop' => 'Flytt forhåndsvisningen foran redigeringsboksen',
+'tog-previewonfirst' => 'Vis forhåndsvisning ved første redigering av en side',
+'tog-nocache' => 'Skru av mellomlagring av sider («caching»)',
+'tog-enotifwatchlistpages'=> 'E-post med ved sideenringer',
+'tog-enotifusertalkpages'=> 'E-post meg ved endringer på brukerdiskusjonssiden min',
+'tog-enotifminoredits' => 'E-post meg også ved mindre sideendringer',
+'tog-enotifrevealaddr' => 'Vis e-postadressen min i e-poster',
+'tog-shownumberswatching'=> 'Vis antall overvåkende brukere',
+'tog-fancysig' => 'Råsignatur (uten automatisk lenke)',
+'tog-externaleditor' => 'Bruk ekstern behandler som standard',
+'tog-externaldiff' => 'Bruk ekstern differanse som standard',
+'tog-showjumplinks' => 'Slå på «gå til»-lenker',
+'tog-uselivepreview' => 'Bruk levende forhåndsvisning (eksperimentell JavaScript)',
+'tog-autopatrol' => 'Merk mine redigeringer som godkjente automatisk',
+'tog-forceeditsummary' => 'Advar meg når jeg ikke har noen redigeringsforklaring',
+'tog-watchlisthideown' => 'Skjul mine endringer fra overvåkningslista',
+'tog-watchlisthidebots' => 'Skjul robotendringer fra overvåkningslista',
+'underline-always' => 'Alltid',
+'underline-never' => 'Aldri',
+'underline-default' => 'Bruk nettleserstandard',
+'skinpreview' => '(forhåndsvisning)',
+'sunday' => 'søndag',
+'monday' => 'mandag',
+'tuesday' => 'tirsdag',
+'wednesday' => 'onsdag',
+'thursday' => 'torsdag',
+'friday' => 'fredag',
+'saturday' => 'lørdag',
+'january' => 'januar',
+'february' => 'februar',
+'march' => 'mars',
+'april' => 'april',
+'may_long' => 'mai',
+'june' => 'juni',
+'july' => 'juli',
+'august' => 'august',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'desember',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'des',
+'categories' => 'Kategorier',
+'pagecategories' => '{{PLURAL:$1|Kategori|Kategorier}}',
+'category_header' => 'Artikler i kategorien «$1»',
+'subcategories' => 'Underkategorier',
+'mainpage' => 'Hovedside',
+'mainpagetext' => '<big>\'\'\'MediaWiki-programvaren er nå installert.\'\'\'</big>',
+'mainpagedocfooter' => 'Se [http://meta.wikimedia.org/wiki/Help:Contents brukerveiledningen] for informasjon om hvordan du bruker wiki-programvaren.
+
+==Å starte==
+*[http://www.mediawiki.org/wiki/Help:Configuration_settings Konfigurasjonsliste]
+*[http://www.mediawiki.org/wiki/Help:FAQ Ofte spurte spørsmål]
+*[http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki e-postliste]',
+'portal' => 'Prosjektportal',
+'portal-url' => 'Project:Prosjektportal',
+'about' => 'Om',
+'aboutsite' => 'Om {{SITENAME}}',
+'aboutpage' => 'Project:Om',
+'article' => 'Artikkel',
+'help' => 'Hjelp',
+'helppage' => 'Help:Hjelp',
+'bugreports' => 'Feilmeldinger',
+'bugreportspage' => 'Project:Feilmeldinger',
+'sitesupport' => 'Donasjoner',
+'sitesupport-url' => 'Project:Donasjoner',
+'faq' => 'Ofte spurte spørsmål',
+'faqpage' => 'Project:Ofte spurte spørsmål',
+'edithelp' => 'Redigeringshjelp',
+'newwindow' => '(åpner i nytt vindu)',
+'edithelppage' => 'Help:Hvordan redigere',
+'cancel' => 'Avbryt',
+'qbfind' => 'Finn',
+'qbbrowse' => 'Søk',
+'qbedit' => 'Rediger',
+'qbpageoptions' => 'Sideinnstillinger',
+'qbpageinfo' => 'Sideinformasjon',
+'qbmyoptions' => 'Egne innstillinger',
+'qbspecialpages' => 'Spesialsider',
+'moredotdotdot' => 'Mer…',
+'mypage' => 'Min side',
+'mytalk' => 'Min diskusjonsside',
+'anontalk' => 'Brukerdiskusjon for denne IP-adressen',
+'navigation' => 'Navigasjon',
+'metadata_help' => 'Metadata (se [[Project:Metadata]] for en forklaring):',
+'currentevents' => 'Aktuelt',
+'currentevents-url' => 'Project:Aktuelt',
+'disclaimers' => 'Opphavsrett',
+'disclaimerpage' => 'Project:Opphavsrett',
+'privacy' => 'Personvern',
+'privacypage' => 'Project:Personvern',
+'errorpagetitle' => 'Feil',
+'returnto' => 'Tilbake til $1.',
+'tagline' => 'Fra {{SITENAME}}',
+'search' => 'Søk',
+'searchbutton' => 'Søk',
+'go' => 'Gå',
+'searcharticle' => 'Gå',
+'history' => 'Historikk',
+'history_short' => 'Historikk',
+'updatedmarker' => 'oppdatert siden mitt forrige besøk',
+'info_short' => 'Informasjon',
+'printableversion' => 'Utskriftsvennlig versjon',
+'permalink' => 'Permanent lenke',
+'print' => 'Skriv ut',
+'edit' => 'Rediger',
+'editthispage' => 'Rediger siden',
+'delete' => 'Slett',
+'deletethispage' => 'Slett side',
+'undelete_short' => 'Gjenopprett $1 revisjoner',
+'protect' => 'Lås',
+'protectthispage' => 'Lås siden',
+'unprotect' => 'Åpne',
+'unprotectthispage' => 'Åpne siden',
+'newpage' => 'Ny side',
+'talkpage' => 'Diskuter siden',
+'specialpage' => 'Spesialside',
+'personaltools' => 'Personlige verktøy',
+'postcomment' => 'Legg til en kommentar',
+'articlepage' => 'Vis artikkel',
+'talk' => 'Diskusjon',
+'views' => 'Visninger',
+'toolbox' => 'Verktøy',
+'userpage' => 'Vis brukerside',
+'projectpage' => 'Vis prosjektside',
+'imagepage' => 'Bildeside',
+'viewtalkpage' => 'Vis diskusjon',
+'otherlanguages' => 'Andre språk',
+'redirectedfrom' => '(Omdirigert fra $1)',
+'autoredircomment' => 'Omdirigerer til [[$1]]',
+'redirectpagesub' => 'Omdirigeringsside',
+'lastmodifiedat' => 'Denne siden ble sist endret $2, $1.',
+'viewcount' => 'Denne siden er vist $1 {{plural:$1|gang|ganger}}.',
+'copyright' => 'Innholdet er tilgjengelig under $1.',
+'protectedpage' => 'Låst side',
+'jumpto' => 'Gå til:',
+'jumptonavigation' => 'navigasjon',
+'jumptosearch' => 'søk',
+'badaccess' => 'Rettighetsfeil',
+'versionrequired' => 'Versjon $1 av MediaWiki påtrengt',
+'versionrequiredtext' => 'Versjon $1 av MediaWiki er nødvendig for å bruke denne siden. Se [[Special:Version]]',
+'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Hentet fra «$1»',
+'youhavenewmessages' => 'Du har $1 ($2).',
+'newmessageslink' => 'nye meldinger',
+'newmessagesdifflink' => 'forskjell fra forrige beskjed',
+'editsection' => 'rediger',
+'editold' => 'rediger',
+'editsectionhint' => 'Rediger seksjon: $1',
+'toc' => 'Innhold',
+'showtoc' => 'vis',
+'hidetoc' => 'skjul',
+'thisisdeleted' => 'Se eller gjenopprett $1?',
+'viewdeleted' => 'Vis $1?',
+'restorelink' => '{{plural:$1|én slettet revisjon|$1 slettede revisjoner}}',
+'feedlinks' => 'Mating:',
+'feed-invalid' => 'Ugyldig matingstype.',
+'nstab-main' => 'Artikkel',
+'nstab-user' => 'Brukerside',
+'nstab-media' => 'Mediaside',
+'nstab-special' => 'Spesial',
+'nstab-project' => 'Prosjektside',
+'nstab-image' => 'Fil',
+'nstab-mediawiki' => 'Melding',
+'nstab-template' => 'Mal',
+'nstab-help' => 'Hjelp',
+'nstab-category' => 'Kategori',
+'nosuchaction' => 'Funksjonen finnes ikke',
+'nosuchactiontext' => 'MediaWiki-programvaren kjenner ikke igjen funksjonen som er spesifisert i URL-en.',
+'nosuchspecialpage' => 'En slik spesialside finnes ikke',
+'nospecialpagetext' => 'Du har bedt om en ugyldig spesialside; en liste over gyldige spesialsider finnes på [[Special:Specialpages]].',
+'error' => 'Feil',
+'databaseerror' => 'databasefeil',
+'dberrortext' => 'Det har skjedd en syntaksfeil i databasen. Den sist forsøkte forespørsel var: <blockquote><tt>$1</tt></blockquote> fra funksjonen «<tt>$2</tt>». MySQL returnerte feilen «<tt>$3: $4</tt>».',
+'dberrortextcl' => 'Det har skjedd en syntaksfeil i databasen. Den sist forsøkte forespørselen var: «$1» fra funksjonen «$2». MySQL returnerte feilen «$3: $4».',
+'noconnect' => 'Beklager! Wikien har tekniske problemer, og kan ikke kontakte databasetjeneren.<br />$1',
+'nodb' => 'Kunne ikke velge databasen $1',
+'cachederror' => 'Det følgende er en lagret kopi av den ønskede siden, og er ikke nødvendigvis oppdatert.',
+'laggedslavemode' => 'Advarsel: Dette kan være en eldre versjon av siden.',
+'readonly' => 'Databasen er skrivebeskyttet',
+'enterlockreason' => 'Skriv en begrunnelse for skrivebeskyttelsen, inkludert et estimat angående når den vil bli opphevet',
+'readonlytext' => 'Databasen er for øyeblikket skrivebeskyttet, sannsynligvis på grunn av rutinemessig vedlikehold.
+
+Administratoren som låste databasen ga forklaringen: $1',
+'missingarticle' => 'Databasen fant ikke teksten til en side den skulle ha funnet, «$1».
+
+Hvis dette er en nylig endret side vil det vanligvis hjelpe å prøve igjen
+om et minutt eller to. Ellers er det mulig du har fulgt en lenke til en side
+som er blitt slettet.
+
+Hvis dette ikke er tilfelle er det mulig du har støtt på en programfeil.
+Send en rapport om dette til en administrator, og inkluder adressen (URL-en)
+til siden.',
+'readonly_lag' => 'Databasen er automatisk skrivebeskyttet så slavetjenerne kan ta igjen mestertjeneren',
+'internalerror' => 'Intern feil',
+'filecopyerror' => 'Kunne ikke kopiere filen «$1» til «$2».',
+'filerenameerror' => 'Kunne ikke omdøpe filen «$1» til «$2».',
+'filedeleteerror' => 'Kunne ikke slette filen «$1».',
+'filenotfound' => 'Kunne ikke finne filen «$1».',
+'unexpected' => 'Uventet verdi: «$1»=«$2».',
+'formerror' => 'Feil: kunne ikke sende skjema',
+'badarticleerror' => 'Handlingen kan ikke utføres på denne siden.',
+'cannotdelete' => 'Kunne ikke slette filen (den kan allerede være slettet av noen andre).',
+'badtitle' => 'Ugyldig tittel',
+'badtitletext' => 'Den ønskede tittelen var ugyldig, tom eller galt lenket fra et annet språk.',
+'perfdisabled' => 'Denne funksjonen er midlertidig utilgjengelig av vedlikeholdsgrunner.',
+'perfdisabledsub' => 'Her er en lagret kopi fra $1:',
+'perfcached' => 'Følgende data er en lagret kopi, og ikke nødvendigvis den siste versjonen i databasen.',
+'perfcachedts' => 'Følgende data er en lagret kopi, og ble sist oppdatert $1.',
+'viewsource' => 'Vis kildekode',
+'viewsourcefor' => 'for $1',
+'protectedtext' => 'Denne siden er sperret for redigeringer; det kan være flere grunner til dette, se [[Project:Beskyttet side]].
+
+Du kan se og kopiere kildekoden til denne siden:',
+'protectedinterface' => 'Denne siden viser brukergrensesnittet for programvaren, og er låst for å hindre misbruk.',
+'editinginterface' => '\'\'\'Advarsel:\'\'\' Du redigerer en side som brukes i grensesnittet for programvaren. Endringer på denne siden vil påvirke hvordan grensesnittet vil se ut.',
+'sqlhidden' => '(SQL-spørring skjult)',
+'logouttitle' => 'Logg ut',
+'logouttext' => '<strong>Du er nå logget ut.</strong><br />
+Du kan fortsette å bruke {{SITENAME}} anonymt, eller logge inn igjen som samme eller annen bruker.',
+'welcomecreation' => '==Velkommen, $1!==
+
+Brukerkontoen din har blitt opprettet. Ikke glem å endre [[Special:Preferences|innstillingene dine]].',
+'loginpagetitle' => 'Logg inn',
+'yourname' => 'Brukernavn',
+'yourpassword' => 'Passord',
+'yourpasswordagain' => 'Gjenta passord',
+'remembermypassword' => 'Husk passordet',
+'yourdomainname' => 'Ditt domene',
+'loginproblem' => '<strong>Du ble ikke logget inn.</strong><br />Prøv igjen!',
+'alreadyloggedin' => '\'\'\'$1 er allerede logget inn!\'\'\'<br />',
+'login' => 'Logg inn',
+'loginprompt' => 'Du må ha slått på cookies for å logge in på {{SITENAME}}.',
+'userlogin' => 'Logg inn eller registrer deg',
+'logout' => 'Logg ut',
+'userlogout' => 'Logg ut',
+'notloggedin' => 'Ikke innlogget',
+'nologin' => 'Er du ikke registrert? $1.',
+'nologinlink' => 'Registrer deg',
+'createaccount' => 'Opprett ny konto',
+'gotaccount' => 'Har du allerede et brukernavn? $1.',
+'gotaccountlink' => 'Logg inn',
+'createaccountmail' => 'per e-post',
+'badretype' => 'Passordene samsvarte ikke.',
+'userexists' => 'Brukernavnet er allerede i bruk. Velg et nytt.',
+'youremail' => 'E-postadresse',
+'username' => 'Brukernavn:',
+'uid' => 'Bruker-ID:',
+'yourrealname' => 'Virkelig navn *',
+'yourlanguage' => 'Språk:',
+'yourvariant' => 'Variant',
+'yournick' => 'Signatur',
+'badsig' => 'Ugyldig råsignatur; sjekk HTML-tagger.',
+'email' => 'E-post',
+'prefs-help-email-enotif'=> 'Denne adressen brukes også til å sende e-postmeldinger dersom du har slått på dette.',
+'prefs-help-realname' => '* Virkelig navn (valgfritt): dersom du velger å oppgi navnet, vil det bli brukt til å kreditere deg for ditt arbeid.',
+'loginerror' => 'Innloggingsfeil',
+'prefs-help-email' => '* E-post (valgfritt): Muliggjør at andre kan kontakte deg uten at identiteten din blir avslørt.',
+'nocookiesnew' => 'Din brukerkonto er nå opprettet, men du har ikke logget på. {{SITENAME}} bruker informasjonskapsler («cookies») for å logge brukere på. Du har slått dem av. Slå dem p åfor å kunne logge på med ditt nye brukernavn og passord.',
+'nocookieslogin' => '{{SITENAME}} bruker informasjonskapsler («cookies») for å logge brukere på. Du har slått dem av. Slå dem på og prøv igjen.',
+'noname' => 'Du har ikke oppgitt et gyldig brukernavn.',
+'loginsuccesstitle' => 'Du er nå logget inn',
+'loginsuccess' => 'Du er nå logget inn på {{SITENAME}} som «$1».',
+'nosuchuser' => 'Det eksisterer ingen bruker ved navn «$1». Sjekk stavemåten eller opprett en ny konto.',
+'nosuchusershort' => 'Det finnes ingen bruker ved navn «$1». Kontroller stavemåten.',
+'nouserspecified' => 'Du må oppgi et brukernavn.',
+'wrongpassword' => 'Du har oppgitt et ugyldig passord. Prøv igjen.',
+'wrongpasswordempty' => 'Du oppga ikke noe passord. Prøv igjen.',
+'mailmypassword' => 'Send nytt passord.',
+'passwordremindertitle' => 'Nytt passord fra {{SITENAME}}',
+'passwordremindertext' => 'Noen (antagelig deg, fra IP-adressen $1) ba oss sende deg et nytt passord til {{SITENAME}} ($4). Passordet for kontoen «$2» er nå «$3». Du bør logge inn og endre pasordet nå.
+
+Dersom noen andre gjorde denne forespørselen eller om du kom på passordet og ikke lenger ønsker å endre det, kan du ignorere denne beskjeden og fortsette å bruke det gamle passordet.',
+'noemail' => 'Det er ikke registrert noen e-postadresse for brukeren «$1».',
+'passwordsent' => 'Et nytt passord har blitt send til e-postadressen registrert på bruker «$1». Logg inn når du har mottatt det nye passordet.',
+'eauthentsent' => 'En bekreftelses e-post har blitt sendt til den angitte e-postadressen. Før andre e-poster kan sendes til kontoen, må du følge instruksjonene i e-posten for å bekrefte at kontoen faktisk er din.',
+'mailerror' => 'Feil under sending av e-post: $1',
+'acct_creation_throttle_hit'=> 'Beklager, du har allerede opprettet $1 kontoer. Du kan ikke opprette flere.',
+'emailauthenticated' => 'E-postadressen ble bekreftet $1.',
+'emailnotauthenticated' => 'E-postadressen er ikke bekreftet. Ingen e-poster vil bli sendt for følgende tjenester.',
+'noemailprefs' => '<strong>Ingen e-postadresse er oppgitt</strong>, så følgende funksjoner vil ikke fungere.',
+'emailconfirmlink' => 'Bekreft e-postadressen din.',
+'invalidemailaddress' => 'E-postadressen kan ikke aksepteres fordi den er ugyldig formatert. Skriv inn en fungerende e-postadresse eller tøm feltet.',
+'accountcreated' => 'Brukerkonto opprettet',
+'accountcreatedtext' => 'Brukerkonto for $1 har blitt opprettet.',
+'bold_sample' => 'Fet tekst',
+'bold_tip' => 'Fet tekst',
+'italic_sample' => 'Kursiv tekst',
+'italic_tip' => 'Kursiv tekst',
+'link_sample' => 'Lenketittel',
+'link_tip' => 'Intern lenke',
+'extlink_sample' => '{{SERVER}} lenketittel',
+'extlink_tip' => 'Ekstern lenke (husk prefikset http://)',
+'headline_sample' => 'Overskrift',
+'headline_tip' => 'Overskrift',
+'math_sample' => 'Sett inn formel her',
+'math_tip' => 'Matematisk formel (LaTeX)',
+'nowiki_sample' => 'Sett inn uformatert tekst her',
+'nowiki_tip' => 'Ignorer wikiformatering',
+'image_sample' => 'Eksempel.jpg',
+'image_tip' => 'Bilde',
+'media_sample' => 'Eksempel.ogg',
+'media_tip' => 'Mediafillenke',
+'sig_tip' => 'Din signatur med dato',
+'hr_tip' => 'Horisontal linje',
+'summary' => 'Redigeringsforklaring',
+'subject' => 'Overskrift',
+'minoredit' => 'Mindre endring',
+'watchthis' => 'Overvåk side',
+'savearticle' => 'Lagre siden',
+'preview' => 'Forhåndsvisning',
+'showpreview' => 'Forhåndsvisning',
+'showlivepreview' => 'Levende forhåndsvisning',
+'showdiff' => 'Vis endringer',
+'anoneditwarning' => '\'\'\'Advarsel:\'\'\' Du er ikke logget inn. Din IP-adresse vil bli bevart i sidens redigeringshistorikk.',
+'missingsummary' => '\'\'\'Påminnelse:\'\'\' Du har ikke lagt inn en [[Help:Redigeringsforklaring|redigeringsforklaring]]. velger du \'\'Lagre siden\'\' en gang til blir endringene lagret uten forklaring.',
+'missingcommenttext' => 'Vennligst legg inn en kommentar under.',
+'blockedtitle' => 'Brukeren er blokkert',
+'blockedtext' => 'Brukernavnet eller IP-adressen er blokkert av $1 med følgende begrunnelse:<br />\'\'$2\'\'
+
+Du kan kontakte $1 eller en annen [[Project:Administratorer|administrator]] for å diskutere utestengelsen.
+
+Din ip-adresse er $3. Vennligst inkluder denne i alle forespørsler du gjør.',
+'whitelistedittitle' => 'Innlogging kreves for å redigere',
+'whitelistedittext' => 'Du må [[Special:userlogin|logge inn}} for å redigere artikler.',
+'whitelistreadtitle' => 'Innlogging kreves for å lese',
+'whitelistreadtext' => 'Du må [[Special:Userlogin|logge inn]] for å lese artikler.',
+'whitelistacctitle' => 'Du har ikke adgang til å opprette en konto',
+'whitelistacctext' => 'For å få adgang til å opprette kontoer må du [[Special:Userlogin|logge inn]] og ha tilstrekkelige rettigheter.',
+'confirmedittitle' => 'E-postbekreftelse nødvendig før du kan redigere',
+'confirmedittext' => 'Du må bekrefte e-postadressen din før du kan redigere sider. Vennligst oppgi og valider e-postadressen din via [[Special:Preferences|innstillingene dine]].',
+'loginreqtitle' => 'Innlogging kreves',
+'loginreqlink' => 'logge inn',
+'loginreqpagetext' => 'Du må [[Special:Userlogin|logge inn]] for å se andre sider.',
+'accmailtitle' => 'Passord sendt',
+'accmailtext' => 'Passordet for «$1» har blitt sendt til $2.',
+'newarticle' => '(ny)',
+'newarticletext' => 'Du har fulgt en lenke til en side som ikke finnes ennå. For å opprette siden, start å skrive i boksen under (se [[Project:Hjelp|hjelpesiden]] for mer informasjon). Om du kom hit ved en feil, trykk på nettleserens \'\'\'tilbake\'\'\'-knapp.',
+'anontalkpagetext' => '----
+\'\'Dette er en diskusjonsside for en anonym bruker som ikke har opprettet konto eller ikke er logget inn. Vi er derfor nødt til å bruke den numeriske IP-adressen til å identifisere ham eller henne. En IP-adresse kan være delt mellom flere brukere. Hvis du er en anonym bruker og synes at du har fått irrelevante kommentarer på en slik side, [[Special:Userlogin|logg på]] så vi unngår framtidige forvekslinger med andre anonyme brukere.\'\'',
+'noarticletext' => 'Det er ikke noe tekst på denne siden. Du kan [[Special:Search/{{PAGENAME}}|søke etter siden]] i andre sider, eller [{{fullurl:{{FULLPAGENAME}}|action=edit}} redigere siden].',
+'clearyourcache' => '\'\'\'NB:\'\'\' Etter å ha lagret må du tømme nettleserens mellomlager («cache») for å kunne se endringene: \'\'\'Mozilla/Safari/Konqueror:\'\'\' hold nede \'\'Shift\'\' mens du klikker på \'\'Reload\'\' (eller trykk \'\'Ctrl-Shift-R\'\'), \'\'\'IE:\'\'\' trykk \'\'Ctrl-F5\'\', \'\'\'Opera:\'\'\' trykk \'\'F5\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Tips:</strong> Bruk «Forhåndsvisning»-knappen for å teste din nye CSS/JS før du lagrer.',
+'usercsspreview' => '\'\'\'Husk at dette bare er en forhåndsvisning av din bruker-CSS og at den ikke er lagret!\'\'\'',
+'userjspreview' => '\'\'\'Husk at dette bare er en test eller forhåndsvisning av ditt bruker-JavaScript, og det ikke er lagret!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Advarsel:\'\'\' Det finnes ikke noe utseende ved navn «$1». Husk at .css- og .js-sider bruker titler i små bokstaver, for eksempel User:Eksempel/monobook.css, ikke User:Eksempel/Monobook.css',
+'updated' => '(Oppdatert)',
+'note' => '<strong>Merk:</strong>',
+'previewnote' => '<strong>Dette er bare en forhåndsvisning; endringer har ikke blitt lagret!</strong>',
+'session_fail_preview' => '<strong>Beklager! Redigeringen din kunne ikke lagres. Vennligst prøv igjen. Om det fortsetter å gå galt, prøv å logge ut og så inn igjen.</strong>',
+'previewconflict' => 'Slik vil teksten i redigeringsvinduet se ut dersom du lagrer den.',
+'session_fail_preview_html'=> '<strong>Beklager! Redigeringen din kunne ikke lagres på grunn av tap av sesjonsdata.</strong>
+
+\'\'Fordi denne wikien har rå HTML slått på, er forhåndsvisningen skjult for å forhindre JavaScript-angrep.\'\'',
+'importing' => 'Importerer $1',
+'editing' => 'Redigerer $1',
+'editinguser' => 'Redigerer $1',
+'editingsection' => 'Redigerer $1 (seksjon)',
+'editingcomment' => 'Redigerer $1 (kommentar)',
+'editconflict' => 'Redigeringskonflikt: $1',
+'explainconflict' => 'Noen andre har endret teksten siden du begynte å redigere.
+Den øverste boksen inneholder den nåværende tekst.
+Dine endringer vises i den nederste boksen.
+Du er nødt til å flette dine endringer sammen med den nåværende teksten.
+<b>Kun</b> teksten i den øverste tekstboksen vil bli lagret når du
+trykker «Lagre siden».<br />',
+'yourtext' => 'Din tekst',
+'storedversion' => 'Den lagrede versjonen',
+'nonunicodebrowser' => '<strong>ADVARSEL: Nettleseren din har ikke støtte for nicode. Skru det på før du begynner å redigere artikler.</strong>',
+'editingold' => '\'\'\'ADVARSEL: Du redigerer en gammel versjon av denne siden. Hvis du lagrer den, vil alle endringer foretatt siden denne versjonen bli overskrevet.\'\'\'',
+'yourdiff' => 'Forskjeller',
+'copyrightwarning' => 'Vennligst merk at alle bidrag til {{SITENAME}} anses som utgitt under $2 (se $1 for detaljer). Om du ikke vil at dine bidrag skal kunne redigeres og distribuert fritt, ikke legg det til her.<br />
+Du lover også at du har skrevet dette selv, eller kopiert det fra en ressurs som er i public domain eller lignende. <strong>IKKE LEGG TIL OPPHAVSBESKYTTET MATERIALE UTEN TILLATELSE!</strong>',
+'copyrightwarning2' => 'Vennligst merk at alle bidrag til {{SITENAME}} kan bli redigert, endret eller fjernet av andre bidragsytere. Om du ikke vil at dine bidrag skal kunne redigeres fritt, ikke legg det til her.<br />
+Du lover også at du har skrevet dette selv, eller kopiert det fra en ressurs som er i public domain eller lignende (se $1 for detaljer). <strong>IKKE LEGG TIL OPPHAVSBESKYTTET MATERIALE UTEN TILLATELSE!</strong>',
+'longpagewarning' => '<strong>ADVARSEL: Denne siden er $1&nbsp;kB lang; noen eldre nettlesere kan ha problemer med å redigere sider som nærmer seg eller er lengre enn 32&nbsp;kB. Overvei om ikke siden kan deles opp i mindre deler.</strong>',
+'longpageerror' => '<strong>FEIL: Teksten du har forsøkt å lagre er $1&nbsp;kB lang, dvs. lenger enn det maksimale $2&nbsp;kB. Den kan ikke lagres.</strong>',
+'readonlywarning' => '<strong>ADVARSEL: Databasen er låst på grunn av vedlikehold,
+så du kan ikke lagre dine endringer akkurat nå. Det kan være en god idé å
+kopiere teksten din til en tekstfil, så du kan lagre den til senere.</strong>',
+'protectedpagewarning' => '<strong>ADVARSEL: Denne siden er låst slik at bare administratorer kan redigere den. Sørg for at du følger [[Project:Retningslinjer for låsing av sider|retningslinjer for låsing av sider]].</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Merk:\'\'\' Denne siden har blitt låst slik at kun registrerte brukere kan endre den. Nyopprettede og anonyme brukere kan ikke redigere.',
+'templatesused' => 'Maler i bruk på denne siden:',
+'edittools' => '<!-- Teksten her vil vises under redigerings- og opplastingsboksene. -->',
+'nocreatetitle' => 'Sideoppretting er begrenset',
+'nocreatetext' => 'Denne siden har begrensede muligheter for oppretting av nye sider. Du kan gå tilbake og redigere en eksisterende side, eller [[Special:Userlogin|logge inn eller opprette en ny konto]].',
+'revhistory' => 'Historikk',
+'nohistory' => 'Denne siden har ingen historikk.',
+'revnotfound' => 'Versjonen er ikke funnet',
+'revnotfoundtext' => 'Den gamle versjonen av siden du etterspurte finnes ikke. Vennligst kontroller adressen du brukte for å få adgang til denne siden.',
+'loadhist' => 'Laster historikk',
+'currentrev' => 'Nåværende versjon',
+'revisionasof' => 'Versjonen fra $1',
+'previousrevision' => '← Eldre versjon',
+'nextrevision' => 'Nyere versjon →',
+'currentrevisionlink' => 'vis nåværende versjon',
+'cur' => 'nå',
+'next' => 'neste',
+'last' => 'forrige',
+'orig' => 'original',
+'histlegend' => 'Forklaring: (nå) = forskjell fra nåværende versjon, (forrige) = forskjell fra forrige versjon, M = mindre endring.',
+'deletedrev' => '[slettet]',
+'histfirst' => 'Første',
+'histlast' => 'Siste',
+'rev-deleted-comment' => '(kommentar fjernet)',
+'rev-deleted-user' => '(brukernavn fjernet)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Denne sidehistorikken har blitt fjernet fra de offentlige arkivene. Det kan være detaljer i [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} slettingsloggen].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Denne revisjonen har blitt fjernet fra det offentlige arkivet. Som administrator har du mulighet til å se den; det kan være detaljer i [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} slettingsloggen].
+</div>',
+'rev-delundel' => 'vis/skjul',
+'history-feed-title' => 'Revisjonshistorikk',
+'history-feed-description'=> 'Revisjonshistorikk for denne siden',
+'history-feed-item-nocomment'=> '$1 på $2',
+'history-feed-empty' => 'Den etterspurte siden finnes ikke. Den kan ha blitt slettet fra wikien, eller fått et nytt navn. Prøv å [[Special:Search|søke]] etter beslektede sider.',
+'revisiondelete' => 'Slett/gjenopprett revisjoner',
+'revdelete-selected' => 'Valgte revisjon av [[:$1]]:',
+'revdelete-text' => 'Slettede revisjoner vil fortsatt vises i sidehistorikken, men innholdet vil ikke være tilgjengelig for offentligheten.
+
+Andre administratorer på denne wikien vil fortsatt kunne se det skjulte innholdet, og kan gjenopprette det, med mindre videre begrensninger blir gitt av sideoperatørene.',
+'revdelete-legend' => 'Sett revisjonsbegrensninger:',
+'revdelete-hide-text' => 'Skjul revisjonstekst',
+'revdelete-hide-comment'=> 'Skjul redigeringsforklaring',
+'revdelete-hide-user' => 'Skjul bidragsyters brukernavn eller IP',
+'revdelete-hide-restricted'=> 'Disse restriksjonene gjelder også for administratorer',
+'revdelete-log' => 'Loggkommentar:',
+'revdelete-submit' => 'Utfør for valgte revisjoner',
+'revdelete-logentry' => 'endre revisjonssynlighet for [[$1]]',
+'difference' => '(Forskjeller mellom versjoner)',
+'loadingrev' => 'laster revisjon for å se forskjeller',
+'lineno' => 'Linje $1:',
+'editcurrent' => 'Rediger nåværende versjon av denne siden',
+'selectnewerversionfordiff'=> 'Velg en nyere versjon for sammenligning',
+'selectolderversionfordiff'=> 'Velg en eldre versjon for sammenligning',
+'compareselectedversions'=> 'Sammenlign valgte versjoner',
+'searchresults' => 'Søkeresultater',
+'searchresulttext' => 'For mer informasjon om søking i {{SITENAME}}, se [[Project:Søking]].',
+'badquery' => 'Ugyldig forespørsel',
+'badquerytext' => 'Forespørselen kunne ikke bli utført. Det er sannsynligvis fordi du har prøvd å søke etter et ord med færre en tre bokstaver, noe som ikke fungerer ennå. Det kan også hende at du har skrevet feil. Prøv igjen.',
+'matchtotals' => 'Forespørselen «$1» ga treff på {{plural:$2|én artikkel|$2 artikler}} og på teksten i {{plural:$3|én artikkel|$3 artikler}}.',
+'titlematches' => 'Artikkeltitler med treff på forespørselen',
+'notitlematches' => 'Ingen artikkeltitler hadde treff på forespørselen',
+'textmatches' => 'Artikkeltekster med treff på forespørselen',
+'notextmatches' => 'Ingen artikkeltekster hadde treff på forespørselen',
+'prevn' => 'forrige $1',
+'nextn' => 'neste $1',
+'viewprevnext' => 'Vis ($1) ($2) ($3).',
+'showingresults' => 'Nedenfor vises opptil \'\'\'$1\'\'\' resultater som starter med nummer \'\'\'$2\'\'\'.',
+'showingresultsnum' => 'Nedenfor vises \'\'\'$3\'\'\' resultater som starter med nummer \'\'\'$2\'\'\'.',
+'nonefound' => '\'\'\'Merk:\'\'\' Søk uten resultat skyldes ofte at man søker etter alminnelige ord som «i» eller «på», som ikke er indeksert, eller ved å spesifisere mer enn et søkeord (da kun sider som inneholder alle søkeordene blir funnet).',
+'powersearch' => 'Søk',
+'powersearchtext' => 'Søk i navnerom:<br />$1<br />$2 List opp omdirigeringer<br />Søk etter $3 $9',
+'searchdisabled' => 'Søkefunksjonen er slått av. Du kan søke via Google i mellomtiden. Merk at Googles indeksering av {{SITENAME}} muligens er utdatert.',
+'blanknamespace' => '(Hoved)',
+'preferences' => 'Innstillinger',
+'prefsnologin' => 'Ikke logget inn',
+'prefsnologintext' => 'Du må være [[Special:Userlogin|logget inn]] for å endre brukerinnstillingene.',
+'prefsreset' => 'Brukerinnstillingene er tilbakestilt.',
+'qbsettings' => 'Brukerinnstillinger for hurtigmeny.',
+'changepassword' => 'Endre passord',
+'skin' => 'Utseende',
+'math' => 'Matteformler',
+'dateformat' => 'Datoformat',
+'datedefault' => 'Ingen foretrukket',
+'datetime' => 'Dato og tid',
+'math_failure' => 'Feil i matematikken',
+'math_unknown_error' => 'ukjent feil',
+'math_unknown_function' => 'ukjent funksjon',
+'math_lexing_error' => 'lexerfeil',
+'math_syntax_error' => 'syntaksfeil',
+'math_image_error' => 'PNG-konversjon mislyktes',
+'math_bad_tmpdir' => 'Kan ikke skrive til eller opprette midlertidig mappe',
+'math_bad_output' => 'Kan ikke skrive til eller opprette resultatmappe',
+'prefs-personal' => 'Brukerdata',
+'prefs-rc' => 'Siste endringer',
+'prefs-watchlist' => 'Overvåkningsliste',
+'prefs-watchlist-days' => 'Antall dager vist i overvåkningslista:',
+'prefs-watchlist-edits' => 'Antall redigeringer som skal vises i utvidet overvåkningsliste:',
+'prefs-misc' => 'Diverse',
+'saveprefs' => 'Lagre innstillinger',
+'resetprefs' => 'Tilbakestill instillinger',
+'oldpassword' => 'Gammelt passord:',
+'newpassword' => 'Nytt passord:',
+'retypenew' => 'Gjenta nytt passord:',
+'textboxsize' => 'Redigering',
+'rows' => 'Rader:',
+'columns' => 'Kolonner',
+'searchresultshead' => 'Søking',
+'resultsperpage' => 'Resultater per side:',
+'contextlines' => 'Linjer per resultat',
+'contextchars' => 'Tegn per linje i resultatet',
+'stubthreshold' => 'Grense for markering av småartikler:',
+'recentchangescount' => 'Antall titler i «siste endringer»:',
+'savedprefs' => 'Innstillingene har blitt lagret.',
+'timezonelegend' => 'Tidssone',
+'timezonetext' => 'Tast inn antall timer lokaltid differerer fra tjenertiden (UTC).',
+'localtime' => 'Lokaltid',
+'timezoneoffset' => 'Forskjell',
+'servertime' => 'Tjenerens tid er nå',
+'guesstimezone' => 'Hent tidssone fra nettleseren',
+'allowemail' => 'Tillat andre å sende e-post til meg',
+'defaultns' => 'Søk i disse navnerommene som standard:',
+'default' => 'standard',
+'files' => 'Filer',
+'userrights-lookup-user'=> 'Ordne brukergrupper',
+'userrights-user-editname'=> 'Skriv inn et brukernavn:',
+'editusergroup' => 'Endre brukergrupper',
+'userrights-editusergroup'=> 'Rediger brukergrupper',
+'saveusergroups' => 'Lagre brukergrupper',
+'userrights-groupsmember'=> 'Medlem av:',
+'userrights-groupsavailable'=> 'Tilgjengelige grupper:',
+'userrights-groupshelp' => 'Velg grupper du vil at brukeren skal fjernes fra eller lagt til. Ikke valgte grupper vil ikke bli forandret. Du kan fjerne merkingen av en gruppe med Ctrl + Venstreklikk.',
+'group' => 'Gruppe:',
+'group-bot' => 'Roboter',
+'group-sysop' => 'Administratorer',
+'group-bureaucrat' => 'Byråkrater',
+'group-all' => '(alle)',
+'group-bot-member' => 'Robot',
+'group-sysop-member' => 'Administrator',
+'group-bureaucrat-member'=> 'Byråkrat',
+'grouppage-bot' => 'Project:Roboter',
+'grouppage-sysop' => 'Project:Administratorer',
+'grouppage-bureaucrat' => 'Project:Byråkrater',
+'changes' => 'endringer',
+'recentchanges' => 'Siste endringer',
+'recentchangestext' => 'Vis de siste endringene til denne siden',
+'rcnote' => 'Nedenfor vises de siste <strong>$1</strong> endringene de siste <strong>$2</strong> dagene, fra $3.',
+'rcnotefrom' => 'Nedenfor er endringene fra <strong>$2</strong> til <strong>$1</strong> vist.',
+'rclistfrom' => 'Vis nye endringer med start fra $1',
+'rcshowhideminor' => '$1 mindre endringer',
+'rcshowhidebots' => '$1 roboter',
+'rcshowhideliu' => '$1 innloggede brukere',
+'rcshowhideanons' => '$1 anonyme brukere',
+'rcshowhidepatr' => '$1 godkjente endringer',
+'rcshowhidemine' => '$1 mine endringer',
+'rclinks' => 'Vis siste $1 endringer i de siste $2 dagene<br />$3',
+'diff' => 'diff',
+'hist' => 'hist',
+'hide' => 'skjul',
+'show' => 'vis',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[$1 overvåkende {{plural:$1|bruker|brukere}}]',
+'rc_categories' => 'Begrens til kategorier (skilletegn: «|»)',
+'rc_categories_any' => 'Alle',
+'upload' => 'Last opp fil',
+'uploadbtn' => 'Last opp fil',
+'reupload' => 'Last opp fil igjen',
+'reuploaddesc' => 'Tilbake til skjemaet for å laste opp filer.',
+'uploadnologin' => 'Ikke logget inn',
+'uploadnologintext' => 'Du må være [[Special:Userlogin|logget inn]] for å kunne laste opp filer.',
+'upload_directory_read_only'=> 'Opplastingsmappa ($1) er ikke skrivbar for tjeneren.',
+'uploaderror' => 'Feil under opplasting av fil',
+'uploadtext' => 'Bruk skjemaet under for å laste opp filer. For å se eller søke i tidligere opplastede filer, gå til [[Special:Imagelist|fillista]]. Opplastinger lagres også i [[Special:Log/upload|opplastingsloggen]].
+
+For å inkludere et bilde på en side, bruk ei slik lenke:
+*\'\'\'<nowiki>[[</nowiki>{{ns:Image}}:Filnavn.jpg<nowiki>]]</nowiki>\'\'\'
+*\'\'\'<nowiki>[[</nowiki>{{ns:Image}}:Filnavn.png|Alternativ tekst<nowiki>]]</nowiki>\'\'\'
+For å lenke direkte til bildet, skriv:
+*\'\'\'<nowiki>[[</nowiki>{{ns:Media}}:Filnavn.ogg<nowiki>]]</nowiki>\'\'\'',
+'uploadlog' => 'opplastingslogg',
+'uploadlogpage' => 'Opplastingslogg',
+'uploadlogpagetext' => 'Her er en liste over de siste opplastede filene.',
+'filename' => 'Filnavn',
+'filedesc' => 'Beskrivelse',
+'fileuploadsummary' => 'Filbeskrivelse:',
+'filestatus' => 'Opphavsrettsstatus',
+'filesource' => 'Kilde',
+'copyrightpage' => 'Project:Opphavsrett',
+'copyrightpagename' => 'Opphavsrett',
+'uploadedfiles' => 'Filer som er lastet opp',
+'ignorewarning' => 'Lagre filen likevel.',
+'ignorewarnings' => 'Ignorer eventuelle advarsler',
+'minlength' => 'Navnet på filen må bestå av minst tre bokstaver.',
+'illegalfilename' => 'Filnavnet «$1» inneholder ugyldige tegn; gi filem et nytt navn og prøv igjen.',
+'badfilename' => 'Navnet på filen er blitt endret til «$1».',
+'badfiletype' => '«.$1» er ikke et tillatt filformat.',
+'largefile' => 'Det anbefales at filer ikke er større enn $1&nbsp;bytes; denne filen er $2&nbsp;bytes',
+'largefileserver' => 'Denne filen er større enn det tjeneren er konfigurert til å tillate.',
+'emptyfile' => 'Filen du lastet opp ser ut til å være tom. Dette kan komme av en skrivefeil i filnavnet. Sjekk om du virkelig vil laste opp denne filen.',
+'fileexists' => 'En fil med dette navnet finnes allerede. Sjekk $1 hvis du ikke er sikker på at du vil forandre den.',
+'fileexists-forbidden' => 'En fil med dette navnet finnes fra før; gå tilbake og last opp filen under et nytt navn. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'En fil med dette navnet finnes fra før i det delte fillageret; gå tilbake og last opp filen under et nytt navn. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Opplastingen er gjennomført',
+'fileuploaded' => 'Opplastingen av $1 var vellykket. Vennligst følg denne lenken $2 til beskrivelsessiden og fyll inn informasjon om filen, som hvor den kom fra, når og av hvem den ble laget, og annen informasjon. Om filen er et bilde, kan du sette det inn slik: <tt><nowiki>[[Image:$1|thumb|Beskrivelse]]</nowiki></tt>',
+'uploadwarning' => 'Opplastingsadvarsel',
+'savefile' => 'Lagre fil',
+'uploadedimage' => 'Lastet opp «[[$1]]»',
+'uploaddisabled' => 'Opplastingsfunksjonen er deaktivert',
+'uploaddisabledtext' => 'Opplasting er slått av på denne wikien.',
+'uploadscripted' => 'Denne filen inneholder HTML eller skripting som kan feiltolkes av en nettleser.',
+'uploadcorrupt' => 'Denne filen er ødelagt eller er en ugyldig filtype. Sjekk filen og last den opp på nytt.',
+'uploadvirus' => 'Denne filen inneholder virus! Detaljer: $1',
+'sourcefilename' => 'Velg en fil',
+'destfilename' => 'Ønsket filnavn',
+'filewasdeleted' => 'En fil ved dette navnet har blitt lastet opp tidligere og så slettet. Sjekk $1 før du forsøker å laste det opp igjen.',
+'license' => 'Lisensiering',
+'nolicense' => 'Ingen spesifisert',
+'imagelist' => 'Bildeliste',
+'imagelisttext' => 'Her er en liste med <strong>$1</strong> filer sortert <strong>$2</strong>.',
+'imagelistforuser' => 'Denne listen viser filer lastet opp av $1.',
+'getimagelist' => 'henter filliste',
+'ilsubmit' => 'Søk',
+'showlast' => 'Vis de siste $1 filene sortert $2.',
+'byname' => 'etter navn',
+'bydate' => 'etter dato',
+'bysize' => 'etter størrelse',
+'imgdelete' => 'slett',
+'imgdesc' => 'beskrivelse',
+'imglegend' => 'Forklaring: (beskrivelse) = vis/rediger filbeskrivelse.',
+'imghistory' => 'Filhistorikk',
+'revertimg' => 'gjenopprett',
+'deleteimg' => 'slett',
+'deleteimgcompletely' => 'Slett alle revisjoner av denne filen',
+'imghistlegend' => 'Forklaring: (nå) = dette er den nåværende filen, (slett) = slett denne gamle versjonen, (gjenopprett) = gjenopprett en gammel versjon.
+<br /><i>Klikk på en dato for å se filen som ble lastet opp</i>.',
+'imagelinks' => 'Lenker',
+'linkstoimage' => 'Følgende sider har lenker til denne filen:',
+'nolinkstoimage' => 'Det er ingen sider som bruker denne filen.',
+'sharedupload' => 'Denne filen deles av andre prosjekter.',
+'shareduploadwiki' => 'Se $1 for mer informasjon.',
+'shareduploadwiki-linktext'=> 'filbeskrivelsesside',
+'noimage' => 'Ingen fil ved dette navnet finnes, du kan $1.',
+'noimage-linktext' => 'laste det opp',
+'uploadnewversion-linktext'=> 'Last opp en ny versjon av denne filen',
+'mimesearch' => 'MIME-søk',
+'mimetype' => 'MIME-type:',
+'download' => 'last ned',
+'unwatchedpages' => 'Sider som ikke er overvåket',
+'listredirects' => 'Liste over omdirigeringer',
+'unusedtemplates' => 'Ubrukte maler',
+'unusedtemplatestext' => 'Denne siden lister opp alle sider i malnavnerommet som ikke er inkludert på en annen side. Husk å sjekke for andre slags lenker til malen før du sletter den.',
+'unusedtemplateswlh' => 'andre lenker',
+'randomredirect' => 'Tilfeldig omdirigering',
+'statistics' => 'Statistikk',
+'sitestats' => '{{SITENAME}}-statistikk',
+'userstats' => 'Brukerstatistikk',
+'sitestatstext' => 'Det er til sammen \'\'\'$1\'\'\' sider i databasen. Dette inkluderer diskusjonssider, sider om {{SITENAME}}, små stubbsider, omdirigeringer, og annet som antageligvis ikke gjelder som ordentlig innhold. Om man ikke regner med disse er det \'\'\'$2\'\'\' sider som sannsynligvis er ordentlige innholdssider.
+
+\'\'\'$8\'\'\' filer har blitt lastet opp.
+
+Det har vært totalt \'\'\'$3\'\'\' sidevisninger, og \'\'\'$4\'\'\' redigeringer siden wikien ble satt opp. Det blir i snitt \'\'\'$5\'\'\' redigeringer per side, og \'\'\'$6\'\'\' visninger per redigering.
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue Arbeidskøen] er på \'\'\'$7\'\'\'.',
+'userstatstext' => 'Det er \'\'\'$1\'\'\' registrerte brukere. \'\'\'$2\'\'\' av disse (eller $4 %) er administratorer (se $3).',
+'disambiguations' => 'Artikler med flertydige titler',
+'disambiguationspage' => 'Template:Peker',
+'disambiguationstext' => 'Følgende artikler har lenker til \'\'artikler med flertydige titler\'\'. De bør ha en lenke til en entydig tittel i stedet. En artikkel blir behandlet som flertydig dersom den lenker til $1. Lenker fra andre navnerom listes \'\'ikke\'\' her.',
+'doubleredirects' => 'Doble omdirigeringer',
+'doubleredirectstext' => '\'\'\'NB:\'\'\' Denne listen kan inneholde gale resultater. Det er som regel fordi siden inneholder ekstra tekst under den første <tt>#redirect</tt>.<br />Hver linje inneholder lenker til den første og den andre omdirigeringen, og den første linjen fra den andre omdirigeringsteksten. Det gir som regel den «riktige» artikkelen, som den første omdirigeringen skulle ha pekt på.',
+'brokenredirects' => 'Ødelagte omdirigeringer',
+'brokenredirectstext' => 'Følgende omdirigeringer peker til ikke-eksisterende sider.',
+'nbytes' => '$1 {{plural:$1|byte|bytes}}',
+'ncategories' => '$1 {{plural:$1|kategori|kategorier}}',
+'nlinks' => '$1 {{plural:$1|lenke|lenker}}',
+'nmembers' => '$1 {{plural:$1|medlem|medlemmer}}',
+'nrevisions' => '$1 {{plural:$1|revisjon|revisjoner}}',
+'nviews' => '$1 {{plural:$1|visning|visninger}}',
+'lonelypages' => 'Foreldreløse sider',
+'uncategorizedpages' => 'Ukategoriserte sider',
+'uncategorizedcategories'=> 'Ukategoriserte kategorier',
+'unusedcategories' => 'Ubrukte kategorier',
+'unusedimages' => 'Ubrukte filer',
+'popularpages' => 'Populære sider',
+'wantedcategories' => 'Ønskede kategorier',
+'wantedpages' => 'Etterspurte sider',
+'mostlinked' => 'Sider med flest lenker til seg',
+'mostlinkedcategories' => 'Kategorier med flest sider',
+'mostcategories' => 'Sider med flest kategorier',
+'mostimages' => 'Mest brukte bilder',
+'mostrevisions' => 'Artikler med flest revisjoner',
+'allpages' => 'Alle sider',
+'prefixindex' => 'Prefiksindeks',
+'randompage' => 'Tilfeldig side',
+'shortpages' => 'Korte sider',
+'longpages' => 'Lange sider',
+'deadendpages' => 'Blindveisider',
+'listusers' => 'Brukerliste',
+'specialpages' => 'Spesialsider',
+'spheading' => 'Spesialsider for alle brukere',
+'restrictedpheading' => 'Spesialsider for administratorer',
+'recentchangeslinked' => 'Relaterte endringer',
+'rclsub' => '(til sider med lenke fra «$1»)',
+'newpages' => 'Nye sider',
+'ancientpages' => 'Eldste sider',
+'intl' => 'Språklenker',
+'move' => 'Flytt',
+'movethispage' => 'Flytt siden',
+'unusedimagestext' => '<p>Merk at andre sider kanskje lenker til et bilde med en direkte lenke, så bildet listes her selv om det faktisk er i bruk.</p>',
+'unusedcategoriestext' => 'Følgende kategorier eksisterer, men det er ingen sider i dem.',
+'booksources' => 'Bokkilder',
+'categoriespagetext' => 'Følgende kategorier finnes i wikien.',
+'data' => 'data',
+'userrights' => 'Brukerrettighetskontroll',
+'groups' => 'Brukergrupper',
+'booksourcetext' => 'Her er en liste over lenker til steder som låner ut og/eller selger nye og brukte bøker, og som kanskje også har ytterligere informasjon om bøker du leter etter.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 til $2',
+'version' => 'Versjon',
+'log' => 'Logger',
+'alllogstext' => 'Kombinert visning av alle loggene. Du kan begrense visningen ved å velge loggtype, bruker og/eller påvirket side.',
+'logempty' => 'Ingen elementer i loggen.',
+'nextpage' => 'Neste side ($1)',
+'allpagesfrom' => 'Vis sider som starter med:',
+'allarticles' => 'Alle artikler',
+'allinnamespace' => 'Alle sider i $1-navnerommet',
+'allnotinnamespace' => 'Alle sider (ikke i $1-navnerommet)',
+'allpagesprev' => 'Forrige',
+'allpagesnext' => 'Neste',
+'allpagessubmit' => 'Gå',
+'allpagesprefix' => 'Vis sider med prefikset:',
+'mailnologin' => 'Ingen avsenderadresse',
+'mailnologintext' => 'Du må være [[Special:Userlogin|logget inn]] og ha en gyldig e-postadresse satt i [[Special:Preferences|brukerinnstillingene]] for å sende e-post til andre brukere.',
+'emailuser' => 'E-post til denne brukeren',
+'emailpage' => 'E-post til bruker.',
+'emailpagetext' => 'Hvis denne brukeren har oppgitt en gyldig e-postadresse i sine innstillinger, vil dette skjemaet sende en enkelt beskjed. Den e-postadressen du har satt i innstillingene dine vil dukke opp i «Fra»-feltet på denne e-posten, så mottakeren er i stand til å svare.',
+'defemailsubject' => 'E-post fra {{SITENAME}}',
+'noemailtitle' => 'Ingen e-postadresse',
+'noemailtext' => 'Denne brukeren har ikke oppgitt en gyldig e-postadresse eller har valgt å ikke motta e-post fra andre brukere.',
+'emailfrom' => 'Fra',
+'emailto' => 'Til',
+'emailsubject' => 'Emne',
+'emailmessage' => 'Beskjed',
+'emailsend' => 'Send',
+'emailsent' => 'E-post sendt',
+'emailsenttext' => 'E-postbeskjeden er sendt',
+'watchlist' => 'Overvåkningsliste',
+'nowatchlist' => 'Du har ingenting i overvåkningslista.',
+'watchlistcount' => '\'\'\'Du har $1 {{plural:$1|objekt|objekter}} i overvåkningslista di, inkludert diskusjonssider.\'\'\'',
+'clearwatchlist' => 'Nullstill overvåkningsliste',
+'watchlistcleartext' => 'Er du sikker på at du vil fjerne dem?',
+'watchlistclearbutton' => 'Nullstill overvåkningsliste',
+'watchlistcleardone' => 'Overvåkningslisten din er nullstilt. $1 {{plural:$1|objekt|objekter}} ble fjernet.',
+'watchnologin' => 'Ikke logget inn',
+'watchnologintext' => 'Du må være [[Special:Userlogin|logget inn]] for å kunne endre overvåkningslisten.',
+'addedwatch' => 'Lagt til overvåkningslista',
+'addedwatchtext' => 'Siden «$1» er føyd til [[Special:Watchlist|overvåkningslistea]]. Fremtidige endringer til denne siden og den tilhørende diskusjonssiden vil bli listet opp her, og siden vil fremstå \'\'\'fremhevet\'\'\' i [[Special:Recentchanges|lista over de siste endringene]] for å gjøre det lettere å finne den.
+
+Hvis du senere vil fjerne siden fra overvåkningslista, klikk «Avslutt overvåkning» ute i siden.',
+'removedwatch' => 'Fjernet fra overvåkningslista',
+'removedwatchtext' => 'Siden «[[:$1]]» er fjernet fra overvåkningslista di.',
+'watch' => 'Overvåk',
+'watchthispage' => 'Overvåk siden',
+'unwatch' => 'Avslutt overvåkning',
+'unwatchthispage' => 'Fjerner overvåkning',
+'notanarticle' => 'Ikke en artikkel',
+'watchnochange' => 'Ingen av sidene i overvåkningslista er endret i den valgte perioden.',
+'watchdetails' => '* $1 sider overvåket, utenom diskusjonssider.
+* [[Special:Watchlist/edit|Vis og rediger hele lista]]
+* [[Special:Watchlist/clear|Fjern alle sider]]',
+'wlheader-enotif' => '* E-postnotifikasjon er slått på.',
+'wlheader-showupdated' => '* Sider som har blitt forandret siden du sist besøkte dem vises i \'\'\'fet tekst\'\'\'',
+'watchmethod-recent' => 'sjekker siste endringer for sider overvåkningslista',
+'watchmethod-list' => 'sjekker siste endringer for sider i overvåkningstlista',
+'removechecked' => 'Fjern valgte sider fra overvåkningslista',
+'watchlistcontains' => 'Overvåkningslista inneholder $1 {{plural:$1|side|sider}}.',
+'watcheditlist' => 'Her er en alfabetisk liste over sidene i overvåkningslista. Velg sidene du vil fjerne fra overvåkningslista og klikk på knappen «fjern valgte sider fra overvåkningslista» nederst på denne siden.',
+'removingchecked' => 'Fjerner de valgte sidene fra overvåkningslista…',
+'couldntremove' => 'Kunne ikke fjerne «$1»…',
+'iteminvalidname' => 'Problem med «$1», ugyldig navn…',
+'wlnote' => 'Nedenfor er de siste $1 endringene de siste <b>$2</b> timene.',
+'wlshowlast' => 'Vis siste $1 timer $2 dager $3',
+'wlsaved' => 'Dette er en lagret versjon av overvåkningslista di. Den er ikke nødvendigvis oppdatert.',
+'wlhideshowown' => '$1 mine endringer.',
+'wlhideshowbots' => '$1 robotendringer',
+'wldone' => 'Utført.',
+'enotif_mailer' => '{{SITENAME}} påminnelsessystem',
+'enotif_reset' => 'Merk alle sider som besøkt',
+'enotif_newpagetext' => 'Dette er en ny side.',
+'changed' => 'endret',
+'created' => 'opprettet',
+'enotif_subject' => '{{SITENAME}}-siden $PAGETITLE har blitt $CHANGEDORCREATED av $PAGEEDITOR',
+'enotif_lastvisited' => 'Se $1 for alle endringer siden ditt forrige besøk.',
+'enotif_body' => '$WATCHINGUSERNAME,
+
+{{SITENAME}}-siden $PAGETITLE har blitt $CHANGEDORCREATED $PAGEEDITDATE av $PAGEEDITOR, se $PAGETITLE_URL for den nåværende versjonen.
+
+$NEWPAGE
+
+Redigeringssammendrag: $PAGESUMMARY $PAGEMINOREDIT
+
+Kontakt brukeren:
+e-post: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Det vil ikke komme flere påminnelser om endringer på denne siden med mindre du besøker den. Du kan også fjerne påminnelsesflagg for alle sider i overvåkningslista di.
+
+Med vennlig hilsen,
+{{SITENAME}}s påminnelsessystem
+
+--
+For å endre innstillingene i overvåkningslista di, besøk {{fullurl:Special:Watchlist/edit}}
+
+Tilbakemeldinger og videre assistanse:
+{{fullurl:Project:Hjelp}}',
+'deletepage' => 'Slett side',
+'confirm' => 'Bekreft',
+'excontent' => 'Innholdet var: «$1»',
+'excontentauthor' => 'innholdet var «$1» (og eneste bidragsyter var [[{{ns:special}}:Contributions/$2|$2]])',
+'exbeforeblank' => 'innholdet før siden ble tømt var: «$1»',
+'exblank' => 'siden var tom',
+'confirmdelete' => 'Bekreft sletting',
+'deletesub' => '(Sletter «[[$1]]»)',
+'historywarning' => 'Advarsel: Siden du er i ferd med å slette har en historikk:',
+'confirmdeletetext' => 'Du holder på å slette en side eller et bilde sammen med historikken. Bilder som slettes kan ikke gjenopprettes, men alle andre sider som slettes på denne måten kan gjenopprettes. Bekreft at du virkelig vil slette denne siden, og at du gjør det i samsvar med [[Project:Retningslinjer for sletting|retningslinjene]].',
+'actioncomplete' => 'Gjennomført',
+'deletedtext' => '«[[$1]]» er slettet. Se $2 for en oversikt over de siste slettingene.',
+'deletedarticle' => 'slettet «[[$1]]»',
+'dellogpage' => 'Slettingslogg',
+'dellogpagetext' => 'Under er ei liste over nylige slettinger.',
+'deletionlog' => 'slettingslogg',
+'reverted' => 'Gjenopprettet en tidligere versjon',
+'deletecomment' => 'Begrunnelse for sletting',
+'imagereverted' => 'Tilbakestilling til tidligere versjon gjennomført.',
+'rollback' => 'Fjern redigeringer',
+'rollback_short' => 'Tilbakestill',
+'rollbacklink' => 'tilbakestill',
+'rollbackfailed' => 'Kunne ikke tilbakestille',
+'cantrollback' => 'Kan ikke fjerne redigering; den siste brukeren er den eneste forfatteren.',
+'alreadyrolled' => 'Kan ikke fjerne den siste redigeringen på [[:$1]] av [[User:$2|$2]] ([[User talk:$2|diskusjon]]); en annen har allerede redigert siden eller fjernet redigeringen. Den siste redigeringen er foretatt av [[User:$3|$3]] ([[User talk:$3|diskusjon]]).',
+'editcomment' => 'Redigeringskommentaren var: «\'\'$1\'\'»',
+'revertpage' => 'Tilbakestilte endring av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusjon]] · [[Special:Blockip/$2|blokker]]) til siste versjon av $1',
+'sessionfailure' => 'Det ser ut til å være et problem med innloggingen din, og den har blitt avbrutt av sikkerhetshensyn. Trykk \'\'Tilbake\'\' i nettleseren din, oppdater siden og prøv igjen.',
+'protectlogpage' => 'Låsingslogg',
+'protectlogtext' => 'Her er en liste over sider som er blitt beskyttet eller har fått fjernet beskyttelsen. Se [[Project:Beskyttet side]] for mer informasjon.',
+'protectedarticle' => 'låste [[$1]]',
+'unprotectedarticle' => 'åpnet [[$1]]',
+'protectsub' => '(Låser «$1»)',
+'confirmprotecttext' => 'Vil du virkelig låse siden?',
+'confirmprotect' => 'Bekreft låsing',
+'protectmoveonly' => 'Bare lås for flytting',
+'protectcomment' => 'Låsingsbegrunnelse',
+'unprotectsub' => '(Åpner «$1»)',
+'confirmunprotecttext' => 'Vil du virkelig åpne denne siden?',
+'confirmunprotect' => 'Bekreft åpning',
+'unprotectcomment' => 'Åpningsbegrunnelse',
+'protect-unchain' => 'Spesielle flyttingstillatelser',
+'protect-text' => 'Du kan se og forandre beskyttelsesnivået for siden [[$1]] her. Vennligst følg [[Project:Beskyttelsesretningslinjer|beskyttelsesretningslinjene]].',
+'protect-viewtext' => 'Kontoen din har ikke tillatelse til å forandre sidens beskyttelsesnivå. Dette er de nåværende innstillingene for siden <strong>$1</strong>:',
+'protect-default' => '(standard)',
+'protect-level-autoconfirmed'=> 'Blokker uregistrerte brukere',
+'protect-level-sysop' => 'Kun administratorer',
+'restriction-edit' => 'Redigering',
+'restriction-move' => 'Flytting',
+'undelete' => 'Vis slettede sider',
+'undeletepage' => 'Se og gjenopprett slettede sider',
+'viewdeletedpage' => 'Vis slettede sider',
+'undeletepagetext' => 'Følgende sider er slettet, men finnes fortsatt i arkivet og kan gjenopprettes. Arkivet blir periodevis slettet.',
+'undeleteextrahelp' => 'For å gjenopprette hele siden, la alle boksene være som de er, og klikk \'\'\'Gjenopprett\'\'\'. For å gjenopprette kun deler, kryss av revisjonenes bokser, og klikk \'\'\'Gjenopprett\'\'\'.',
+'undeletearticle' => 'Gjenopprett slettet side',
+'undeleterevisions' => '$1 revisjoner arkivert',
+'undeletehistory' => 'Hvis du gjenoppretter siden, vil alle de historiske
+revisjoner også bli gjenopprettet. Hvis en ny side med det samme navnet
+er opprettet siden denne ble slettet, vil de gjenopprettede revisjonene
+dukke opp i den tidligere historikken, og den nyeste revisjonen vil forbli
+på siden.',
+'undeletehistorynoadmin'=> 'Denne artikkelen har blitt slettet. Grunnen for slettingen vises i oppsummeringen nedenfor, sammen med detaljer om brukerne som redigerte siden før den ble slettet. Teksten i disse slettede revisjonene er kun tilgjengelig for [[Project:Administratorer|administratorer]].',
+'undeleterevision' => 'Slettet revisjon fra $1',
+'undeletebtn' => 'Gjenopprett',
+'undeletereset' => 'Resett skjema',
+'undeletecomment' => 'Forklaring:',
+'undeletedarticle' => 'gjenopprettet «[[$1]]»',
+'undeletedrevisions' => '$1 revisjoner gjenopprettet',
+'undeletedrevisions-files'=> '{{PLURAL:$1|Én revisjon|$1 revisjoner}} og {{PLURAL:$2|én fil|$2 filer}} gjenopprettet',
+'undeletedfiles' => '{{PLURAL:$1|Én fil|$1 filer}} gjenopprettet',
+'cannotundelete' => 'Gjenoppretting feilet; noen andre kan ha gjenopprettet siden først.',
+'undeletedpage' => '<big>\'\'\'$1 har blitt gjenopprettet\'\'\'</big>
+
+Sjekk [[Special:Log/delete|slettingsloggen]] for en liste over nylige slettinger og gjenopprettelser.',
+'namespace' => 'Navnerom:',
+'invert' => 'Inverter',
+'contributions' => 'Bidrag',
+'mycontris' => 'Mine bidrag',
+'contribsub' => 'For $1',
+'nocontribs' => 'Ingen endringer er funnet som passer disse kriteriene.',
+'ucnote' => 'Her er denne brukerens siste <b>$1</b> endringer i de siste <b>$2</b> dagene.',
+'uclinks' => 'Vis de siste $1 endringene; vis de siste $2 dagene.',
+'uctop' => ' (topp)',
+'newbies' => 'nybegynnere',
+'sp-newimages-showfrom' => 'Vis nye bilder fra og med $1',
+'sp-contributions-newest'=> 'Nyeste',
+'sp-contributions-oldest'=> 'Eldste',
+'sp-contributions-newer'=> '$1 nyere',
+'sp-contributions-older'=> '$1 eldre',
+'sp-contributions-newbies-sub'=> 'For nybegynnere',
+'whatlinkshere' => 'Lenker hit',
+'notargettitle' => 'Intet mål',
+'notargettext' => 'Du har ikke spesifisert en målside eller bruker å utføre denne funksjonen på.',
+'linklistsub' => '(Liste over lenker)',
+'linkshere' => 'Følgende sider lenker hit:',
+'nolinkshere' => 'Ingen sider lenker hit.',
+'isredirect' => 'omdirigeringsside',
+'istemplate' => 'inklusjon',
+'blockip' => 'Blokker IP-adresse',
+'blockiptext' => 'Bruk skjemaet under for å blokkere en IP-adresses tilgang til å redigere artikler. Dette må kun gjøres for å forhindre hærverk, og i overensstemmelse med [[Project:Retningslinjer for blokkering|retningslinjene]]. Fyll ut en spesiell begrunnelse under.',
+'ipaddress' => 'IP-adresse',
+'ipadressorusername' => 'IP-adresse eller brukernavn',
+'ipbexpiry' => 'Utløper',
+'ipbreason' => 'Begrunnelse',
+'ipbsubmit' => 'Blokker denne adressen',
+'ipbother' => 'Annen tid',
+'ipboptions' => '2 timer:2 hours,1 dag:1 day,3 dager:3 days,1 uke:1 week,2 uker:2 weeks,1 måned:1 month,3 måneder:3 months,6 måneder:6 months,1 år:1 year,uendelig:infinite',
+'ipbotheroption' => 'annet',
+'badipaddress' => 'Ugyldig IP-adresse.',
+'blockipsuccesssub' => 'Blokkering utført',
+'blockipsuccesstext' => 'IP-adressen «$1» er blokkert. Se [[Special:Ipblocklist|blokkeringslista]] for alle blokkeringer.',
+'unblockip' => 'Opphev blokkering',
+'unblockiptext' => 'Bruk skjemaet under for å gjenopprette skriveadgangen for en tidligere blokkert adresse eller bruker.',
+'ipusubmit' => 'Opphav blokkeringen av denne adressen',
+'unblocked' => '[[User:$1|$1]] har blitt avblokkert',
+'ipblocklist' => 'Liste over blokkerte IP-adresser og brukere',
+'blocklistline' => '$1, $2 blokkerte $3 ($4)',
+'infiniteblock' => 'uendelig',
+'expiringblock' => 'utgår $1',
+'ipblocklistempty' => 'Blokkeringslista er tom.',
+'blocklink' => 'blokker',
+'unblocklink' => 'opphev blokkering',
+'contribslink' => 'bidrag',
+'autoblocker' => 'Du har blitt automatisk blokkert fordi du deler IP-adresse med «[[User:$1|$1]]». Grunnen som ble gitt til at «$1» ble blokkert var: «$2».',
+'blocklogpage' => 'Blokkeringslogg',
+'blocklogentry' => 'Blokkerte «[[$1]]» med en utløpstid på $2',
+'blocklogtext' => 'Dette er en logg som viser hvilke brukere som har blitt blokkert og avblokkert. Automatisk blokkerte IP-adresser vises ikke. Se [[Special:Ipblocklist|blokkeringslista]] for en liste over IP-adresser som er blokkert i nåværende tidspunkt.',
+'unblocklogentry' => 'opphevet blokkeringen av $1',
+'range_block_disabled' => 'Muligheten til å blokkere flere IP-adresser om gangen er slått av.',
+'ipb_expiry_invalid' => 'Ugyldig utløpstid.',
+'ip_range_invalid' => 'Ugyldig IP-rad.',
+'proxyblocker' => 'Proxyblokker',
+'proxyblockreason' => 'IP-adressen din har blitt blokkert fordi den er en åpen proxy. Kontakt internettleverandør eller teknisk støtte og informer dem om dette alvorlige sikkerhetsproblemet.',
+'proxyblocksuccess' => 'Utført.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'IP-adressen din er oppgitt som åpen proxy i [http://sorbs.net/ SORBS]\' DNSBL.',
+'sorbs_create_account_reason'=> 'IP-adressen din oppgis som en åpen proxy i [http://sorbs.net/ SORBS]\' DNSBL. Du kan ikke opprette en konto.',
+'lockdb' => 'Lås database',
+'unlockdb' => 'Åpne database',
+'lockdbtext' => 'Å låse databasen vil avbryte alle brukere fra å kunne
+redigere sider, endre deres innstillinger, redigere deres
+overvåkningsliste, og andre ting som krever endringer i databasen.
+Bekreft at du har til hensikt å gjøre dette, og at du vil
+låse opp databasen når vedlikeholdet er utført.',
+'unlockdbtext' => 'Å låse opp databasen vil si at alle brukere igjen
+kan redigere sider, endre sine innstillinger, redigere sin
+overvåkningsliste, og andre ting som krever endringer i databasen.
+Bekreft at du har til hensikt å gjøre dette.',
+'lockconfirm' => 'Ja, jeg vil virkelig låse databasen.',
+'unlockconfirm' => 'Ja, jeg vil virkelig låse opp databasen.',
+'lockbtn' => 'Lås databasen',
+'unlockbtn' => 'Åpne databasen',
+'locknoconfirm' => 'Du har ikke bekreftet handlingen.',
+'lockdbsuccesssub' => 'Databasen er nå låst',
+'unlockdbsuccesssub' => 'Databasen er nå lås opp',
+'lockdbsuccesstext' => 'Databasen er låst.<br />Husk å fjerne låsen når du er ferdig med vedlikeholdet.',
+'unlockdbsuccesstext' => 'Databasen er låst opp.',
+'makesysoptitle' => 'Gjør en bruker til administrator',
+'makesysoptext' => 'Dette skjemaet blir brukt av byråkrater for å gjøre vanlige brukere til administratorer. Skriv brukernavnet i boksen og trykk på knappen for å gjøre en bruker til administrator.',
+'makesysopname' => 'Brukernavn:',
+'makesysopsubmit' => 'Gjør denne brukeren til administrator',
+'makesysopok' => '<b>«$1» er nå administrator</b>',
+'makesysopfail' => '<b>«$1» kunne ikke bli administrator. (Er brukernavnet skrevet riktig?)</b>',
+'setbureaucratflag' => 'Gjør til byråkrat',
+'rightslog' => 'Rettighetslogg',
+'rightslogtext' => 'Dette er en logg over forandringer i brukerrettigheter.',
+'rightslogentry' => 'endret gruppe for $1 fra $2 til $3',
+'rights' => 'Rettigheter:',
+'set_user_rights' => 'Sett brukerrettigheter',
+'user_rights_set' => '<b>Brukerrettigheter for «$1» er oppdatert</b>',
+'set_rights_fail' => '<b>Brukerrettigheter for «$1» kunne ikke settes. (Skrev du navnet riktig?)</b>',
+'makesysop' => 'Gjør en bruker til administrator',
+'already_sysop' => 'Den brukeren er allerede administrator',
+'already_bureaucrat' => 'Denne brukeren er allerede byråkrat',
+'rightsnone' => '(ingen)',
+'movepage' => 'Flytt side',
+'movepagetext' => 'Når du bruker skjemaet under, vil du få omdøpt en
+side og flyttet hele historikken til det nye navnet.
+Den gamle tittelen vil bli en omdirigeringsside til den nye tittelen.
+Lenker til den gamle tittelen vil ikke bli endret. Eventuelle omdirigeringer vil bli brutt.
+
+<span style="color:#ff0000"><b>Det er <u>ditt ansvar</u> å rette alle omdirigeringer (bruk «Lenker hit» for å finne dem) hvis du flytter en side!</b></span>
+
+Legg merke til at siden \'\'\'ikke\'\'\' kan flyttes hvis det allerede finnes en side
+med den nye tittelen, med mindre den siden er tom eller er en omdirigering
+uten noen historikk. Det betyr at du kan flytte en side tilbake dit
+den kom fra hvis du gjør en feil.
+
+<b>ADVARSEL!</b>
+Dette kan være en drastisk og uventet endring for en populær side;
+vær sikker på at du forstår konsekvensene av dette før du
+fortsetter.',
+'movepagetalktext' => 'Den tilhørende diskusjonssiden, hvis det finnes en,
+vil automatisk bli flyttet med siden \'\'\'med mindre:\'\'\'
+*En ikke-tom diskusjonsside allerede eksisterer under det nye navnet, eller
+*Du fjerner markeringen i boksen nedenunder.
+
+I disse tilfellene er du nødt til å flytte eller flette sammen siden manuelt.',
+'movearticle' => 'Flytt side',
+'movenologin' => 'Ikke logget inn',
+'movenologintext' => 'Du må være registrert bruker og være [[Special:Userlogin|logget på]] for å flytte en side.',
+'newtitle' => 'Til ny tittel',
+'movepagebtn' => 'Flytt side',
+'pagemovedsub' => 'Flytting gjennomført',
+'pagemovedtext' => 'Siden «<span class="plainlinks">[{{fullurl:$1|redirect=no}} $1]</span>» er nå flyttet til «[[$2]]». \'\'\'Vennligst [[Special:Whatlinkshere/$2|sjekk]]\'\'\' om denne flyttingen har skapt noen [[Special:DoubleRedirects|doble omdirigeringssider]], og fiks dem om nødvendig.',
+'articleexists' => 'En side med det navnet eksisterer allerede, eller valgte navn er ugyldig. Velg et annet navn.',
+'talkexists' => '\'\'\'Siden ble flyttet korrekt, men den tilhørende diskusjonssiden kunne ikke flyttes, fordi det allerede eksisterer en med den nye tittelen. Du er nødt til å flette dem sammen manuelt.\'\'\'',
+'movedto' => 'flyttet til',
+'movetalk' => 'Flytt også diskusjonssiden, hvis den eksisterer.',
+'talkpagemoved' => 'Den tilhørende diskusjonssiden ble også flyttet.',
+'talkpagenotmoved' => 'Den tilhørende diskusjonssiden ble <strong>ikke</strong> flyttet.',
+'1movedto2' => '[[$1]] flyttet til [[$2]]',
+'1movedto2_redir' => '[[$1]] flyttet til [[$2]] over omdirigeringsside',
+'movelogpage' => 'Flyttelogg',
+'movelogpagetext' => 'Her er ei liste over sider som har blitt flyttet.',
+'movereason' => 'Årsak',
+'revertmove' => 'tilbakestill',
+'delete_and_move' => 'Slett og flytt',
+'delete_and_move_text' => '==Sletting nødvendig==
+Målsiden «[[$1]]» finnes allerede. Vil du slette den så denne siden kan flyttes dit?',
+'delete_and_move_confirm'=> 'Ja, slett siden',
+'delete_and_move_reason'=> 'Slettet grunnet flytting',
+'selfmove' => 'Kilde- og destinasjonstittel er den samme; kan ikke flytte siden.',
+'immobile_namespace' => 'Sider kan ikke flyttes til dette navnerommet.',
+'export' => 'Eksportsider',
+'exporttext' => 'Du kan eksportere teksten og redigeringshistorikken for en bestemt side eller en gruppe sider i XML. Dette kan senere importeres til en annen wiki som bruker MediaWiki ved hjelp av [[Special:Import]].
+
+For å eksportere sider, skriv inn titler i tekstboksen under, én tittel per linje, og velg om du vil ha kun nåværende versjon, eller alle versjoner i historikken. Dersom du bare vil ha nåværende versjon, kan du også bruke en lenke, for eksempel [[Special:Export/{{Mediawiki:Mainpage}}]] for siden «{{Mediawiki:Mainpage}}».',
+'exportcuronly' => 'Inkluder kun den nåværende versjonen, ikke hele historikken.',
+'exportnohistory' => '----
+\'\'\'Merk:\'\'\' Eksportering av hele historikken gjennom dette skjemaet har blitt slått av av ytelsesgrunner.',
+'export-submit' => 'Eksporter',
+'allmessages' => 'Systemmeldinger',
+'allmessagesname' => 'Navn',
+'allmessagesdefault' => 'Standardtekst',
+'allmessagescurrent' => 'Nåværende tekst',
+'allmessagestext' => 'Dette er en liste over tilgjengelige systemmeldinger i MediaWiki-navnerommet.',
+'allmessagesnotsupportedUI'=> 'Språket du bruker, \'\'\'$1\'\'\', støttes ikke av Special:Allmessages på denne siden.',
+'allmessagesnotsupportedDB'=> '\'\'\'Special:Allmessages\'\'\' kan ikke brukes fordi \'\'\'$wgUseDatabaseMessages\'\'\' er slått av.',
+'allmessagesfilter' => 'Filter:',
+'allmessagesmodified' => 'Vis kun endrede',
+'thumbnail-more' => 'Forstørr',
+'missingimage' => '<b>Bilde mangler</b><br /><i>$1</i>',
+'filemissing' => 'Filen mangler',
+'thumbnail_error' => 'Feil under oppretting av miniatyrbilde: $1',
+'import' => 'Importer sider',
+'importinterwiki' => 'Transwiki-importering',
+'import-interwiki-text' => 'Velg en wiki og en side å importere. Revisjonsdatoer og bidragsyteres navn vil bli bevart. Alle transwiki-importeringer spares i [[Special:Log/import|importloggen]].',
+'import-interwiki-history'=> 'Kopier all historikk for denne siden',
+'import-interwiki-submit'=> 'Importer',
+'importtext' => 'Importer filen fra kildewikien med Special:Export-verktøyet, lagre den på den egen datamaskin, og last den opp hit.',
+'importstart' => 'Importerer sider…',
+'import-revision-count' => '{{PLURAL:$1|Én revisjon|$1 revisjoner}}',
+'importnopages' => 'Ingen sider å importere.',
+'importfailed' => 'Importering mislyktes: $1',
+'importunknownsource' => 'Ukjent importkildetype',
+'importcantopen' => 'Kunne ikke åpne importfil',
+'importbadinterwiki' => 'Ugyldig interwikilenke',
+'importnotext' => 'Tom eller ingen tekst',
+'importsuccess' => 'Import lyktes!',
+'importhistoryconflict' => 'Motstridende revisjoner finnes (siden kan ha blitt importert tidligere)',
+'importnosources' => 'Ingen transwikiimportkilder er definert, og direkte historikkimporteringer er slått av.',
+'importnofile' => 'Ingen importfil opplastet.',
+'importuploaderror' => 'Opplasting av importfil feilet; kanskje filen er større en den tillatte opplastingsstørrelsen.',
+'importlogpage' => 'Importlogg',
+'importlogpagetext' => 'Administrativ import av sider med redigeringshistorikk fra andre wikier.',
+'import-logentry-upload'=> 'importerte [[$1]] ved opplasting',
+'import-logentry-upload-detail'=> '{{PLURAL:$1|Én revisjon|$1 revisjoner}}',
+'import-logentry-interwiki'=> 'transwikiimporterte $1',
+'import-logentry-interwiki-detail'=> '{{PLURAL:$1|Én revisjon|$1 revisjoner}} fra $2',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'Søk i {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Merk dette som en mindre endring [alt-i]',
+'tooltip-save' => 'Lagre endringer [alt-s]',
+'tooltip-preview' => 'Forhåndsvis endringene, vennligst bruk denne funksjonen før du lagrer! [alt-p]',
+'tooltip-diff' => 'Vis hvilke endringer du har gjort på teksten. [alt-v]',
+'tooltip-compareselectedversions'=> 'Se forskjellene mellom de to valgte versjonene av denne siden. [alt-v]',
+'tooltip-watch' => 'Legg denne siden til din overvåkningsliste [alt-w]',
+'common.css' => '/* CSS plassert i denne filen vil gjelde for alle utseender. */',
+'monobook.css' => '/* rediger denne filen for å tilpasse Monobook-skinnet for hele siden */',
+'nodublincore' => 'Dublin Core RDF-metadata er slått av på denne tjeneren.',
+'nocreativecommons' => 'Create Commons RDF-metadata er slått av på denne tjeneren.',
+'notacceptable' => 'Tjeneren har ingen mulige måter å vise data i din nettleser.',
+'anonymous' => 'Anonym(e) bruker(e) av {{SITENAME}}',
+'siteuser' => '{{SITENAME}}-bruker $1',
+'lastmodifiedatby' => 'Denne siden var sist redigert $2, $1 av $3.',
+'and' => 'og',
+'othercontribs' => 'Basert på arbeid av $1.',
+'others' => 'andre',
+'siteusers' => '{{SITENAME}}-bruker(e) $1',
+'creditspage' => 'Sidekreditteringer',
+'nocredits' => 'Ingen krediteringer er tilgjengelig for denne siden.',
+'spamprotectiontitle' => 'Søppelpostfilter',
+'spamprotectiontext' => 'Siden du ønsket å lagre ble blokkert av spamfilteret. Dette er sannsynligvis forårsaket av en lenke til et eksternt nettsted.',
+'spamprotectionmatch' => 'Følgende tekst er det som aktiverte spamfilteret: $1',
+'subcategorycount' => 'Det er {{PLURAL:$1|én underkategori|$1 underkategorier}} i denne kategorien.',
+'categoryarticlecount' => 'Det er {{PLURAL:$1|en artikkel|$1 artikler}} i denne kategorien.',
+'listingcontinuesabbrev'=> ' forts.',
+'spambot_username' => 'MediaWikis spamopprydning',
+'spam_reverting' => 'Tilbakestiller til siste versjon uten lenke til $1',
+'spam_blanking' => 'Alle revisjoner inneholdt lenke til $1, tømmer siden',
+'infosubtitle' => 'Sideinformasjon',
+'numedits' => 'Antall redigeringer (artikkel): $1',
+'numtalkedits' => 'Antall redigeringer (diskusjonsside): $1',
+'numwatchers' => 'Antall overvåkere: $1',
+'numauthors' => 'Antall forskjellige bidragsytere (artikkel): $1',
+'numtalkauthors' => 'Antall forskjellige bidragsytere (diskusjonsside): $1',
+'mw_math_png' => 'Vis alltid som PNG',
+'mw_math_simple' => 'HTML hvis veldig enkel, ellers PNG',
+'mw_math_html' => 'HTML vis mulig, ellers PNG',
+'mw_math_source' => 'Behold som TeX (for tekst-nettlesere)',
+'mw_math_modern' => 'Anbefalt for moderne nettlesere',
+'mw_math_mathml' => 'MathML hvis mulig',
+'markaspatrolleddiff' => 'Godkjenn endringen',
+'markaspatrolledtext' => 'Godkjenn denne siden',
+'markedaspatrolled' => 'Merket som godkjent',
+'markedaspatrolledtext' => 'Endringen er merket som godkjent.',
+'rcpatroldisabled' => 'Siste endringer-patruljering er slått av',
+'rcpatroldisabledtext' => 'Siste endringer-patruljeringsfunksjonen er slått av.',
+'markedaspatrollederror'=> 'Kan ikke merke som godkjent',
+'markedaspatrollederrortext'=> 'Du må spesifisere en versjon å merke som godkjent.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Min brukerside\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Brukersiden for IP-adressen du redigerer fra\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Min diskusjonsside\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskusjon om redigeringer fra denne IP-adressen\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Mine innstillinger\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Liste over sider du overvåker for endringer.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Liste over mine bidrag\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Du oppfordres til å logge inn, men det er ikke obligatorisk.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Du oppfordres til å logge inn, men det er ikke obligatorisk.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Logg ut\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskusjon om innholdssiden\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Du kan redigere denne siden. Vennligst bruk Forhåndsvis-knappen før du lagrer.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Legg til et diskusjonsinnlegg.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Denne siden er beskyttet. Du kan se kildeteksten.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Tidligere revisjoner av denne siden.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Beskytt denne siden\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Slette denne siden\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Gjenopprett redigerenge som ble gjort på denne siden før den ble slettet.\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Flytt denne siden\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Du har ikke tillatelse til å flytte denne siden\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Legg til denne siden til din overvåkningsliste.\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Fjern denne siden fra din overvåkningsliste.\');
+ ta[\'search\'] = new Array(\'f\',\'Søk i denne wikien\');
+ ta[\'p-logo\'] = new Array(\'\',\'Hovedside\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Gå til hovedsiden\');
+ ta[\'n-portal\'] = new Array(\'\',\'Om prosjektet; hva du kan gjøre og hvor du kan finne ting\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Finn bakgrunnsinformasjon om aktuelle hendelser\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Liste over siste endringer på wikien.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Gå inn på en tilfeldig side\');
+ ta[\'n-help\'] = new Array(\'\',\'Stedet for å få hjelp.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Støtt oss\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Liste over alle sider som lenker hit\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Siste endringer i sider som blir lenket fra denne siden\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS-føde for denne siden\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom-føde for denne siden\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Vis liste over bidrag fra denne brukeren\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Send en e-post til denne brukeren\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Last opp bilder eller mediafiler\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Liste over alle spesialsider\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vis innholdssiden\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vis brukersiden\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Vis mediasiden\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Dette er en spesialside, og kan ikke redigeres.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Vis prosjektsiden\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Vis bildesiden\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vis systembeskjeden\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vis malen\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vis hjelpesiden\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vis kategorisiden\');
+ ta[\'history-prevlink\'] = new Array(\'-\',\'Forrige\');
+ ta[\'history-nextlink\'] = new Array(\'+\',\'Neste\');',
+'deletedrevision' => 'Slettet gammel revisjon $1.',
+'previousdiff' => '← Gå til forrige revisjon',
+'nextdiff' => 'Gå til neste diff →',
+'imagemaxsize' => 'Begrens bilder på bildebeskrivelsessider til:',
+'thumbsize' => 'Miniatyrbildestørrelse:',
+'showbigimage' => 'Last ned versjon med høy opløsning ($1×$2, $3&nbsp;KB)',
+'newimages' => 'Galleri over nye filer',
+'showhidebots' => '($1 roboter)',
+'noimages' => 'Ingenting å se.',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+'specialloguserlabel' => 'Bruker:',
+'speciallogtitlelabel' => 'Tittel:',
+'passwordtooshort' => 'Passordet ditt er for kort. Det må ha minst $1 tegn.',
+'mediawarning' => '\'\'\'Advarsel\'\'\': Denne filen kan inneholde farlig kode; ved å åpne den kan systemet ditt kompromitteres.<hr />',
+'fileinfo' => '$1&nbsp;KB, MIME-type: <code>$2</code>',
+'metadata' => 'Metadata',
+'metadata-help' => 'Denne filen inneholder tilleggsinformasjon, antagligvis fra digitalkameraet eller skanneren brukt til å lage eller digitalisere det. Hvis filen har blitt forandret fra utgangspunktet kan enkelte detaljer være unøyaktige.',
+'metadata-expand' => 'Vis detaljer',
+'metadata-collapse' => 'Skjul detaljer',
+'exif-imagewidth' => 'Bredde',
+'exif-imagelength' => 'Høyde',
+'exif-bitspersample' => 'Bits per komponent',
+'exif-photometricinterpretation'=> 'Pixelsammensetning',
+'exif-samplesperpixel' => 'Antall komponenter',
+'exif-xresolution' => 'Horisontal oppløsning',
+'exif-yresolution' => 'Vertikal oppløsning',
+'exif-imagedescription' => 'Bildetittel',
+'exif-make' => 'Kameraprodusent',
+'exif-model' => 'Kameramodell',
+'exif-software' => 'Programvare brukt',
+'exif-artist' => 'Opphavsperson',
+'exif-copyright' => 'Opphavsbeskyttelse tilhører',
+'exif-pixelydimension' => 'Gyldig bildebredde',
+'exif-pixelxdimension' => 'Gyldig bildehøyde',
+'exif-usercomment' => 'Brukerkommentarer',
+'exif-relatedsoundfile' => 'Relatert lydfil',
+'edit-externally' => 'Rediger denne filen med en ekstern applikasjon',
+'edit-externally-help' => 'Se [http://meta.wikimedia.org/wiki/Help:External_editors oppsettsinstruksjonene] for mer informasjon.',
+'recentchangesall' => 'alle',
+'imagelistall' => 'alle',
+'watchlistall1' => 'alle',
+'watchlistall2' => 'alle',
+'namespacesall' => 'alle',
+'confirmemail' => 'Bekreft e-postadresse',
+'confirmemail_text' => 'Denne wikien krever at du bekrefter e-postadressen din før e-posttjenester kan bli brukt. Trykk på knappen under for å sende en bekreftelsese-post til din adresse. E-posten vil inneholde en lenke med en kode; last lenken i nettleseren din for å bekrefte at e-postadressen er gyldig.',
+'confirmemail_send' => 'Send en bekreftelseskode.',
+'confirmemail_sent' => 'Bekreftelsese-post sendt.',
+'confirmemail_sendfailed'=> 'Kunne ikke sende bekreftelseskode. Sjekk e-postadressen for ugyldige tegn.',
+'confirmemail_invalid' => 'Ugyldig bekreftelseskode. Koden kan ha utløpt.',
+'confirmemail_needlogin'=> 'Du må $1 for å bekrefte e-postadressen di.',
+'confirmemail_success' => 'E-postadressen din har blitt bekreftet. Du kan nå logge inn og nyte wikien.',
+'confirmemail_loggedin' => 'E-postadressen din har blitt bekreftet.',
+'confirmemail_error' => 'Noe gitt galt under registrering av din bekreftelse.',
+'confirmemail_subject' => 'Bekreftelsese-post fra {{SITENAME}}',
+'confirmemail_body' => 'Noen, antageligvis deg, fra IP-adressen $1, har registrert kontoen «$2» på {{SITENAME}}, og oppgitt denne e-post-adressen. For å bekrefte at kontoen virkelig tilhører deg og for å aktivere e-posttjenester på {{SITENAME}}, åpne denne lenken i din nettleser: $3
+
+Om dette ikke er deg, ikke følg lenken. Denne bekreftelseskoden vil utløpe $4.',
+'tryexact' => 'Prøv nøyaktig treff',
+'searchfulltext' => 'Søk full tekst',
+'createarticle' => 'Opprett artikkel',
+'scarytranscludedisabled'=> '[Interwiki-transkludering er slått av]',
+'scarytranscludefailed' => '[Malen kunne ikke hentes for $1; beklager]',
+'scarytranscludetoolong'=> '[URL-en er for lang; beklager]',
+'trackbackbox' => '<div id="mw_trackbacks">
+Tilbakesporinger for denne artikkelen:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Slett])',
+'trackbacklink' => 'Tilbakesporing',
+'trackbackdeleteok' => 'Tilbakesporingen ble slettet.',
+'deletedwhileediting' => 'Advarsel: Denne siden har blitt slettet etter at du begynte å redigere den!',
+'confirmrecreate' => '«[[User:$1|$1]]» ([[User talk:$1|diskusjon]]) slettet siden etter at du begynte å redigere den, med begrunnelsen «$2». Vennligst bekreft at du vil gjenopprette siden.',
+'recreate' => 'Gjenopprett',
+'tooltip-recreate' => 'Gjenopprett siden til tross for at den har blitt slettet',
+'unit-pixel' => 'px',
+'redirectingto' => 'Omdirigerer til [[$1]]…',
+'confirm_purge' => 'Vil du slette tjenerens mellomlagrede versjon (\'\'cache\'\') av denne siden? $1',
+'confirm_purge_button' => 'OK',
+'youhavenewmessagesmulti'=> 'Du har nye beskjeder på $1',
+'searchcontaining' => 'Søk etter artikler som inneholder \'\'$1\'\'.',
+'searchnamed' => 'Søk for artikler ved navn \'\'$1\'\'.',
+'articletitles' => 'Artikler som begynner med \'\'$1\'\'',
+'hideresults' => 'Skjul resultater',
+'displaytitle' => '(Lenke til denne siden som [[$1]])',
+'loginlanguagelabel' => 'Språk: $1',
+);
+?>
diff --git a/languages/messages/MessagesNon.php b/languages/messages/MessagesNon.php
new file mode 100644
index 000000000000..17b7e2a49aee
--- /dev/null
+++ b/languages/messages/MessagesNon.php
@@ -0,0 +1,11 @@
+<?php
+/** Old Norse (Norrǿna)
+ *
+ * Defaults to Icelandic instead of English.
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$fallback = 'is';
+
+?>
diff --git a/languages/messages/MessagesNv.php b/languages/messages/MessagesNv.php
new file mode 100644
index 000000000000..d0646cc70a1f
--- /dev/null
+++ b/languages/messages/MessagesNv.php
@@ -0,0 +1,72 @@
+<?php
+/** Navajo (Diné bizaad)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$skinNames = array(
+ 'mono' => 'Łáa\'ígíí',
+ 'monobook' => 'NaaltsoosŁáa\'ígíí'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Naaltsoos_baa_yinísht\'į́',
+ NS_USER => 'Choinish\'įįhí',
+ NS_USER_TALK => 'Choinish\'įįhí_baa_yinísht\'į́',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_baa_yinísht\'į́',
+ NS_IMAGE => 'E\'elyaaígíí',
+ NS_IMAGE_TALK => 'E\'elyaaígíí_baa_yinísht\'į́',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_baa_yinísht\'į́',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Template_talk',
+ NS_HELP => 'Aná\'álwo\'',
+ NS_HELP_TALK => 'Aná\'álwo\'_baa_yinísht\'į́',
+ NS_CATEGORY => 'T\'ááłáhági_át\'éego',
+ NS_CATEGORY_TALK => 'T\'ááłáhági_át\'éego_baa_yinísht\'į́'
+);
+
+$datePreferences = false;
+
+$messages = array(
+'sunday' => 'Damóogo',
+'monday' => 'Damóo biiskání',
+'tuesday' => 'Damóodóó naakiską́o',
+'wednesday' => 'Damóodóó tágí jį́',
+'thursday' => 'Damóodóó dį́į́\' yiską́o',
+'friday' => 'Nda\'iiníísh',
+'saturday' => 'Yiską́ damóo',
+
+'january' => 'Yas Niłt\'ees',
+'february' => 'Atsá Biyáázh',
+'march' => 'Wóózhch\'į́į́d',
+'april' => 'T\'ą́ą́chil',
+'may_long' => 'T\'ą́ą́tsoh',
+'june' => 'Ya\'iishjááshchilí',
+'july' => 'Ya\'iishjáástsoh',
+'august' => 'Bini\'ant\'ą́ą́ts\'ózí',
+'september' => 'Bini\'ant\'ą́ą́tsoh',
+'october' => 'Ghąąjį',
+'november' => 'Níłch\'its\'ósí',
+'december' => 'Níłch\'itsoh',
+
+'jan' => 'Ynts',
+'feb' => 'Atsb',
+'mar' => 'Wozh',
+'apr' => 'Tchi',
+'may' => 'Ttso',
+'jun' => 'Yjsh',
+'jul' => 'Yjts',
+'aug' => 'Btsz',
+'sep' => 'Btsx',
+'oct' => 'Ghąj',
+'nov' => 'Ntss',
+'dec' => 'Ntsx',
+);
+
+?>
diff --git a/languages/messages/MessagesOc.php b/languages/messages/MessagesOc.php
new file mode 100644
index 000000000000..6f20ba5a1489
--- /dev/null
+++ b/languages/messages/MessagesOc.php
@@ -0,0 +1,821 @@
+<?php
+/** Occitan (Occitan)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$quickbarSettings = array(
+ 'Cap', 'Esquèr', 'Drech', 'Flotejant a esquèr'
+);
+
+$skinNames = array(
+ 'standard' => 'Normal',
+ 'nostalgia' => 'Nostalgia',
+ 'cologneblue' => 'Còlonha Blau',
+);
+
+$bookstoreList = array(
+ 'Amazon.fr' => 'http://www.amazon.fr/exec/obidos/ISBN=$1'
+);
+
+$namespaceNames = array(
+ NS_SPECIAL => 'Especial',
+ NS_MAIN => '',
+ NS_TALK => 'Discutir',
+ NS_USER => 'Utilizaire',
+ NS_USER_TALK => 'Discussion_Utilizaire',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discussion_$1',
+ NS_IMAGE => 'Imatge',
+ NS_IMAGE_TALK => 'Discussion_Imatge',
+ NS_MEDIAWIKI => 'Mediaòiqui',
+ NS_MEDIAWIKI_TALK => 'Discussion_Mediaòiqui',
+ NS_TEMPLATE => 'Modèl',
+ NS_TEMPLATE_TALK => 'Discussion_Modèl',
+ NS_HELP => 'Ajuda',
+ NS_HELP_TALK => 'Discussion_Ajuda',
+ NS_CATEGORY => 'Categoria',
+ NS_CATEGORY_TALK => 'Discussion_Categoria',
+);
+$namespaceAliases = array(
+ 'Utilisator' => NS_USER,
+ 'Discussion_Utilisator' => NS_USER_TALK,
+ 'Discutida_Utilisator' => NS_USER_TALK,
+ //'Discutida_$1' => NS_PROJECT_TALK, /// @fixme
+ 'Discutida_Imatge' => NS_IMAGE_TALK,
+ 'Discutida_Mediaòiqui' => NS_MEDIAWIKI_TALK,
+ 'Discutida_Modèl' => NS_TEMPLATE_TALK,
+ 'Discutida_Ajuda' => NS_HELP_TALK,
+ 'Discutida_Categoria' => NS_CATEGORY_TALK,
+);
+$linkTrail = "/^([a-zàâçéèêîôû]+)(.*)\$/sDu";
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'M j, Y "a" H:i',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'j M Y "a" H:i',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'Y M j "a" H:i',
+);
+
+
+$messages = array(
+
+# User Toggles
+
+"tog-underline" => "Ligams solinhats",
+"tog-highlightbroken" => "Ligams sus los subjèctes non creats aparéisson en rog",
+"tog-justify" => "Paragrafes justificats",
+"tog-hideminor" => "Amagar las <i>Cambiadas recentas</i> minoras",
+"tog-usenewrc" => "Cambiadas recentas melhorats<br /> (non per tots los navigaires)",
+"tog-numberheadings" => "Numerotacion automatica de los títols",
+"tog-showtoolbar" => "Show edit toolbar",
+"tog-editondblclick" => "Editar paginas amb un doble clic (JavaScript)",
+"tog-editsection" => "Éditer une section via les liens [éditer]", //Looxix (Enable section editing via [edit] links)
+"tog-editsectiononrightclick" => "Éditer une section en cliquant à droite<br /> sur le titre de la section", // Looxix
+"tog-showtoc" => "Afficher la table des matières<br /> (pour les articles ayant plus de 3 sections)",
+"tog-rememberpassword" => "Se souvenir de mon mot de passe (cookie)",
+"tog-editwidth" => "La fenêtre d'édition s'affiche en pleine largeur",
+"tog-watchdefault" => "Suivre les articles que je crée ou modifie",
+"tog-minordefault" => "Mes modifications sont considérées<br /> comme mineures par défaut",
+"tog-previewontop" => "La prévisualisation s'affiche au<br /> dessus de la boite de rédaction",
+"tog-nocache" => "Désactiver le cache des pages", // Looxix "Disable page caching"
+
+# Dates
+#
+
+'sunday' => 'dimenge',
+'monday' => 'diluns',
+'tuesday' => 'dimarts',
+'wednesday' => 'dimècres',
+'thursday' => 'dijòus',
+'friday' => 'divendres',
+'saturday' => 'dissabte',
+
+'wed' => 'Dimè',
+
+'january' => 'janvièir',
+'february' => 'febrièr',
+'march' => 'març',
+'april' => 'abril',
+'may_long' => 'mai',
+'june' => 'junh',
+'july' => 'julhet',
+'august' => 'agost',
+'september' => 'setembre',
+'october' => 'octòbre',
+'november' => 'novembre',
+'december' => 'decembre',
+
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'abr',
+'may' => 'mai',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'ago',
+'sep' => 'set',
+'oct' => 'oct',
+'nov' => 'nov',
+'dec' => 'dec',
+
+
+# Bits of text used by many pages:
+#
+"categories" => "Catégories de la page", // Looxix "Categories",
+"pagecategories" => "Catégories de la page", // Looxix "{{PLURAL:$1|Category|Categories}}",
+"category_header" => "Articles dans la catégorie \"$1\"", // Looxix "Articles in category \"$1\"",
+"subcategories" => "Sous-catégories", // Looxix "Subcategories",
+
+
+"mainpage" => "Accueil",
+"mainpagetext" => "Logiciel {{SITENAME}} installé.",
+"about" => "À propos",
+"aboutsite" => "À propos de {{SITENAME}}",
+"aboutpage" => "{{ns:project}}:À propos",
+"help" => "Aide",
+"helppage" => "{{ns:project}}:Aide",
+"bugreports" => "Rapport d'erreurs",
+"bugreportspage" => "{{ns:project}}:Rapport d'erreurs",
+"sitesupport" => "Participer en faisant un don",
+
+"faq" => "FAQ",
+"faqpage" => "{{ns:project}}:FAQ",
+"edithelp" => "Aide",
+"edithelppage" => "{{ns:project}}:Comment éditer une page",
+"cancel" => "Annuler",
+"qbfind" => "Rechercher",
+"qbbrowse" => "Défiler",
+"qbedit" => "Éditer",
+"qbpageoptions" => "Page d'option",
+"qbpageinfo" => "Page d'information",
+"qbmyoptions" => "Mes options",
+"mypage" => "Ma page",
+"mytalk" => "Ma page de discussion",
+"currentevents" => "Actualités",
+"errorpagetitle" => "Erreur",
+"returnto" => "Revenir à la page $1.",
+"whatlinkshere" => "Références à cette page",
+"help" => "Aide",
+"search" => "Rechercher",
+"searchbutton" => "Rechercher",
+"history" => "Historique",
+"printableversion" => "Version imprimable",
+"editthispage" => "Modifier cette page",
+"deletethispage" => "Supprimer cette page",
+"protectthispage" => "Protéger cette page",
+"unprotectthispage" => "Déprotéger cette page",
+"newpage" => "Nouvelle page",
+"talkpage" => "Page de discussion",
+"postcomment" => "Ajouter un commentaire", // Looxix "Post a comment",
+"articlepage" => "Voir l'article",
+"userpage" => "Page utilisateur",
+"projectpage" => "Page méta",
+"imagepage" => "Page image",
+"viewtalkpage" => "Page de discussion",
+"otherlanguages" => "Autres langues",
+"redirectedfrom" => "(Redirigé depuis $1)",
+"lastmodifiedat" => "Dernière modification de cette page : $2, $1.",
+"viewcount" => "Cette page a été consultée $1 fois.",
+"protectedpage" => "Page protégée",
+"nbytes" => "$1 octets",
+"go" => "Consulter", // Looxix "OK",
+'searcharticle' => "Consulter", // Looxix "OK",
+"ok" => "OK",
+"retrievedfrom" => "Récupérée de \"$1\"",
+"newmessageslink" => "nouveaux messages",
+"editsection" => "modifier",
+"editold" => "modifier",
+"toc" => "Sommaire", // Looxix "Table"
+"showtoc" => "montrer", // Looxix
+"hidetoc" => "cacher", // Looxix
+"thisisdeleted" => "Afficher ou restaurer $1?", // Looxix "View or restore $1?"
+"restorelink" => "$1 modifications effacées", // Looxix "$1 deleted edits"
+
+# Main script and global functions
+#
+"nosuchaction" => "Action inconnue",
+"nosuchactiontext" => "L'action spécifiée dans l'Url n'est pas reconnue par le logiciel {{SITENAME}}.",
+"nosuchspecialpage" => "Page spéciale inexistante",
+"nospecialpagetext" => "Vous avez demandé une page spéciale qui n'est pas reconnue par le logiciel {{SITENAME}}.",
+
+# General errors
+#
+"error" => "Erreur",
+"databaseerror" => "Erreur base de données",
+"dberrortext" => "Erreur de syntaxe dans la base de données. La dernière requête traitée par la base de données était :
+<blockquote><tt>$1</tt></blockquote>
+depuis la fonction \"<tt>$2</tt>\".
+MySQL a renvoyé l'erreur \"<tt>$3: $4</tt>\".",
+"noconnect" => "Désolé ! Suite à des problèmes techniques, il est impossible de se connecter à la base de données pour le moment.", //"Connexion impossible à la base de données sur $1",
+"nodb" => "Sélection impossible de la base de données $1",
+"cachederror" => "Ceci est une copie de la page demandée et peut ne pas être à jour", // Looxix
+"readonly" => "Mises à jour bloquées sur la base de données",
+"enterlockreason" => "Indiquez la raison du blocage, ainsi qu'une estimation de la durée de blocage",
+"readonlytext" => "Les ajouts et mises à jour sur la base de données {{SITENAME}} sont actuellement bloqués, probablement pour permettre la maintenance de la base, après quoi, tout rentrera dans l'ordre. Voici la raison pour laquelle l'administrateur a bloqué la base :
+<p>$1",
+"missingarticle" => "La base de données n'a pas pu trouver le texte d'une page existante, dont le titre est \"$1\".
+Ce n'est pas une erreur de la base de données, mais plus probablement un bogue du logiciel {{SITENAME}}.
+Veuillez rapporter cette erreur à un administrateur, en lui indiquant l'adresse de la page fautive.",
+"internalerror" => "Erreur interne",
+"filecopyerror" => "Impossible de copier \"$1\" vers \"$2\".",
+"filerenameerror" => "Impossible de renommer \"$1\" en \"$2\".",
+"filedeleteerror" => "Impossible de supprimer \"$1\".",
+"filenotfound" => "Fichier \"$1\" introuvable.",
+"unexpected" => "Valeur inattendue : \"$1\"=\"$2\".",
+"formerror" => "Erreur: Impossible de soumettre le formulaire",
+"badarticleerror" => "Cette action ne peut pas être effectuée sur cette page.",
+"cannotdelete" => "Impossible de supprimer la page ou l'image indiquée.",
+
+"badtitle" => "Mauvais titre", // Looxix "Bad title",
+"badtitletext" => "Le titre de la page demandée est invalide, vide ou le lien interlangue est invalide", // Looxix
+"perfdisabled" => "Désolé ! Cette fonctionnalité est temporairement désactivée
+car elle ralentit la base de données à un point tel que plus personne
+ne peut utiliser le wiki.", // Looxix
+"perfdisabledsub" => "Ceci est une copie de sauvegarde de $1:", // Looxix
+"viewsource" => "Voir le texte source",
+"protectedtext" => "Cette page a été bloquée pour empêcher sa modification. Consultez [[{{ns:project}}:Page protégée]] pour voir les différentes raisons possibles.", // Looxix
+
+# Login and logout pages
+#
+"logouttitle" => "Déconnexion",
+"logouttext" => "Vous êtes à présent déconnecté(e).
+Vous pouvez continuer à utiliser {{SITENAME}} de façon anonyme, ou vous reconnecter, éventuellement sous un autre nom.",
+
+"welcomecreation" => "<h2>Bienvenue, $1!</h2><p>Votre compte d'utilisateur a été créé.
+N'oubliez pas de personnaliser votre {{SITENAME}} en consultant la page Préférences.",
+
+"loginpagetitle" => "Votre identifiant",
+"yourname" => "Vòstre nom d'utilizaire",
+"yourpassword" => "Vòstre senhal",
+"yourpasswordagain" => "Entrez à nouveau votre mot de passe",
+"remembermypassword" => "Se souvenir de mon mot de passe (cookie)",
+"loginproblem" => "<b>Problème d'identification.</b><br />Essayez à nouveau !",
+"alreadyloggedin" => "<strong>Utilisateur $1, vous êtes déjà identifié !</strong><br />",
+'yourvariant' => 'Varianta lingüistica',
+
+"login" => "Identification",
+"userlogin" => "Identification",
+"logout" => "Déconnexion",
+"userlogout" => "Déconnexion",
+"createaccount" => "Créer un nouveau compte",
+"createaccountmail" => "par courriel", // Looxix "by eMail",
+"badretype" => "Les deux mots de passe que vous avez saisis ne sont pas identiques.",
+"userexists" => "Le nom d'utilisateur que vous avez saisi est déjà utilisé. Veuillez en choisir un autre.",
+"yourdomainname" => "Vòstre domeni",
+"youremail" => "Vòstra adreça electronica",
+"yournick" => "Mon surnom (pour les signatures)",
+"loginerror" => "Problème d'identification",
+"noname" => "Vous n'avez pas saisi de nom d'utilisateur.",
+"loginsuccesstitle" => "Identification réussie.",
+"loginsuccess" => "Vous êtes actuellement connecté(e) sur {{SITENAME}} en tant que \"$1\".",
+"nosuchuser" => "L'utilisateur \"$1\" n'existe pas.
+Vérifiez que vous avez bien orthographié le nom, ou utilisez le formulaire ci-dessous pour créer un nouveau compte utilisateur.",
+"wrongpassword" => "Le mot de passe est incorrect. Essayez à nouveau.",
+"mailmypassword" => "Envoyez-moi un nouveau mot de passe",
+"passwordremindertitle" => "Votre nouveau mot de passe sur {{SITENAME}}",
+"passwordremindertext" => "Quelqu'un (probablement vous) ayant l'adresse IP $1 a demandé à ce qu'un nouveau mot de passe vous soit envoyé pour votre accès à {{SITENAME}}.
+Le mot de passe de l'utilisateur \"$2\" est à présent \"$3\".
+Nous vous conseillons de vous connecter et de modifier ce mot de passe dès que possible.",
+"noemail" => "Aucune adresse électronique n'a été enregistrée pour l'utilisateur \"$1\".",
+"passwordsent" => "Un nouveau mot de passe a été envoyé à l'adresse électronique de l'utilisateur \"$1\".
+Veuillez vous identifier dès que vous l'aurez reçu.",
+
+# Edit pages
+#
+"summary" => "Résumé",
+"subject" => "Sujet/titre", // Looxix "Subject/headline",
+"minoredit" => "Modification mineure.",
+"watchthis" => "Suivre cet article",
+"savearticle" => "Sauvegarder",
+"preview" => "Prévisualiser",
+"showpreview" => "Prévisualisation",
+"blockedtitle" => "Utilisateur bloqué",
+"blockedtext" => "Votre compte utilisateur ou votre adresse IP ont été bloqués par $1 pour la raison suivante :<br />$2<p> Vous pouvez contacter l'administrateur pour en discuter.",
+'whitelistedittitle' => 'Devètz vos enregistrar per redigir',
+"whitelistedittext" => "Vous devez être [[Special:Userlogin|connecté]] pour pouvoir rédiger", // Looxix
+"whitelistreadtitle" => "Login requis pour lire", // Looxix "Login required to read",
+"whitelistreadtext" => "Vous devez être [[Special:Userlogin|connecté]] pour pouvoir lire les articles", // Looxix
+'whitelistacctitle' => 'Vos es pas permés de crear un compte',
+"whitelistacctext" => "Pour pouvoir créer un compte sur ce Wiki vous devez être [[Special:Userlogin|connecté]] et avoir les permissions appropriées", // Looxix
+"accmailtitle" => "Mot de passe envoyé.", // Looxix "Password sent.",
+"accmailtext" => "Le mot de passe de '$1' a été envoyé à $2.", // Looxix
+
+"newarticle" => "(Nouveau)",
+"newarticletext" => "Saisissez ici le texte de votre article.",
+"anontalkpagetext" => "---- ''Ceci est la page de discussion pour un utilisateur anonyme qui n'a pas encore créé un compte ou qui ne l'utilise pas. Pour cette raison, nous devons utiliser l'[[adresse IP]] numérique pour l'identifier. Une adresse de ce type peut être partagée entre plusieurs utilisateurs. Si vous êtes un utilisateur anonyme et si vous constatez que des commentaires qui ne vous concernent pas vous ont été adressés, vous pouvez [[Special:Userlogin|créer un compte ou vous connecter]] afin d'éviter toute future confusion à l'avenir.",
+"noarticletext" => "(Il n'y a pour l'instant aucun texte sur cette page)",
+"updated" => "(Mes a jorn)",
+"note" => "<strong>Note :</strong>",
+"previewnote" => "Attention, ce texte n'est qu'une prévisualisation et n'a pas encore été sauvegardé !",
+"previewconflict" => "La prévisualisation montre le texte de cette page tel qu'il apparaîtra une fois sauvegardé.",
+"editing" => "modification de $1",
+'editinguser' => "modification de $1",
+"editconflict" => "Conflit de modification : $1",
+"explainconflict" => "<b>Cette page a été sauvegardée après que vous avez commencé à la modifier.
+La zone d'édition supérieure contient le texte tel qu'il est enregistré actuellement dans la base de données. Vos modifications apparaissent dans la zone d'édition inférieure. Vous allez devoir apporter vos modifications au texte existant. Seul le texte de la zone supérieure sera sauvegardé.<br />",
+'yourtext' => 'Vòstre tèxt',
+"storedversion" => "Version enregistrée",
+"editingold" => "<strong>Attention : vous êtes en train de modifier une version obsolète de cette page. Si vous sauvegardez, toutes les modifications effectuées depuis cette version seront perdues.</strong>",
+"yourdiff" => "Diferéncias",
+/*"copyrightwarning" => "Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la GNU Free Documentation Licence, une licence de documentation libre (Voir $1 pour plus de détails). Si vous ne désirez pas que vos écrits soient édités et distribués à volonté, ne les envoyez pas. De même, merci de ne contribuer qu'en apportant vos propres écrits ou des écrits issus d'une source libre de droits. <b>N'UTILISEZ PAS DE TRAVAUX SOUS COPYRIGHT SANS AUTORISATION EXPRESSE !</b>",*/
+"longpagewarning" => "<strong>AVERTISSEMENT : cette page a une longueur de $1 ko;
+quelques navigateurs gèrent mal les pages approchant ou dépassant 32 ko lors de leur rédaction.
+Peut-être serait-il mieux que vous divisiez la page en sections plus petites.</strong>", // Panoramix
+"readonlywarning" => "<strong>AVERTISSEMENT : cette page a été bloquée pour maintenance,
+vous ne pourrez donc pas sauvegarder vos modifications maintenant. Vous pouvez copier le texte dans un fichier et le sauver pour plus tard.</strong>", // Looxix
+"protectedpagewarning" => "<strong>AVERTISSEMENT : cette page a été bloquée.
+Seuls les utilisateurs ayant le statut d'administrateur peuvent la modifier. Soyez certain que
+vous suivez les [[Project:Page protégée|directives concernant les pages protégées]].</strong>", // Looxix
+
+# History pages
+#
+"revhistory" => "Versions précédentes",
+"nohistory" => "Il n'existe pas d'historique pour cette page.",
+"revnotfound" => "Version introuvable",
+"revnotfoundtext" => "La version précédente de cette page n'a pas pu être retrouvée. Vérifiez l'URL que vous avez utilisée pour accéder à cette page.",
+
+"loadhist" => "Chargement de l'historique de la page",
+"currentrev" => "Version actuelle",
+"revisionasof" => "Version du $1",
+"cur" => "actu",
+"next" => "suiv",
+"last" => "dern",
+"orig" => "orig",
+"histlegend" => "Légende : (actu) = différence avec la version actuelle ,
+(dern) = différence avec la version précédente, M = modification mineure",
+
+# Diffs
+#
+"difference" => "(Différences entre les versions)",
+"loadingrev" => "chargement de l'ancienne version pour comparaison",
+"lineno" => "Ligne $1:",
+"editcurrent" => "Modifier la version actuelle de cette page",
+
+
+# Search results
+#
+"searchresults" => "Résultat de la recherche",
+"searchresulttext" => "Pour plus d'informations sur la recherche dans {{SITENAME}}, voir [[Project:Recherche|Chercher dans {{SITENAME}}]].",
+"searchsubtitle" => "Pour la requête \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Pour la requête \"$1\"",
+"badquery" => "Requête mal formulée",
+"badquerytext" => "Nous n'avons pas pu traiter votre requête.
+Vous avez probablement recherché un mot d'une longueur inférieure
+à trois lettres, ce qui n'est pas encore possible. Vous avez
+aussi pu faire une erreur de syntaxe, telle que \"poisson et
+et écailles\".
+Veuillez essayer une autre requête.",
+"matchtotals" => "La requête \"$1\" correspond à $2 titre(s)
+d'article et au texte de $3 article(s).",
+"noexactmatch" => "Aucune page avec ce titre n'existe, essai avec la recherche complète.", // Looxix
+"titlematches" => "Correspondances dans les titres",
+"notitlematches" => "Aucun titre d'article ne contient le(s) mot(s) demandé(s)",
+"textmatches" => "Correspondances dans les textes",
+"notextmatches" => "Aucun texte d'article ne contient le(s) mot(s) demandé(s)",
+"prevn" => "$1 précédents",
+"nextn" => "$1 suivants",
+"viewprevnext" => "Voir ($1) ($2) ($3).",
+"showingresults" => "Affichage de <b>$1</b> résultats à partir du #<b>$2</b>.",
+"showingresultsnum" => "Affichage de <b>$3</b> résultats à partir du #<b>$2</b>.", // Looxix
+"nonefound" => "<strong>Note</strong>: l'absence de résultat est souvent due à l'emploi de termes de recherche trop courants, comme \"à\" ou \"de\",
+qui ne sont pas indexés, ou à l'emploi de plusieurs termes de recherche (seules les pages
+contenant tous les termes apparaissent dans les résultats).",
+"powersearch" => "Recherche",
+"powersearchtext" => "
+Rechercher dans les espaces :<br />
+$1<br />
+$2 Inclure les page de redirections Rechercher $3 $9",
+"blanknamespace" => "(Principal)", // FIXME FvdP: trad de "(Main)"
+
+# Preferences page
+#
+"preferences" => "Préférences",
+"prefsnologin" => "Non connecté",
+"prefsnologintext" => "Vous devez être [[Special:Userlogin|connecté]]
+pour modifier vos préférences d'utilisateur.",
+"prefsreset" => "Les préférences ont été rétablies à partir de la version enregistrée.",
+"qbsettings" => "Personnalisation de la barre outils",
+"changepassword" => "Modification du mot de passe",
+"skin" => "Apparence",
+"math" => "Rendu des maths", // Looxix "Rendering math",
+"dateformat" => "Format de date", // Looxix "Date format",
+"math_failure" => "Erreur math", // Looxix "Failure toparse",
+"math_unknown_error" => "erreur indéterminée", // FvdP+Looxix "unknown error",
+"math_unknown_function" => "fonction inconnue", // Looxix "unknown function ",
+"math_lexing_error" => "erreur lexicale", // Looxxi "lexing error",
+"math_syntax_error" => "erreur de syntaxe", // Looxix "syntax error",
+"saveprefs" => "Enregistrer les préférences",
+"resetprefs" => "Rétablir les préférences",
+"oldpassword" => "Ancien mot de passe",
+"newpassword" => "Nouveau mot de passe",
+"retypenew" => "Confirmer le nouveau mot de passe",
+"textboxsize" => "Taille de la fenêtre d'édition",
+"rows" => "Rangées",
+"columns" => "Colonnes",
+"searchresultshead" => "Affichage des résultats de recherche",
+"resultsperpage" => "Nombre de réponses par page",
+"contextlines" => "Nombre de lignes par réponse",
+"contextchars" => "Nombre de caractères de contexte par ligne",
+"stubthreshold" => "Taille minimale des articles courts",
+"recentchangescount" => "Nombre de titres dans les modifications récentes",
+"savedprefs" => "Les préférences ont été sauvegardées.",
+"timezonetext" => "Si vous ne précisez pas de décalage horaire, c'est l'heure de l'Europe de l'ouest qui sera utilisée.",
+"localtime" => "Heure locale",
+"timezoneoffset" => "Décalage horaire",
+"servertime" => "Heure du serveur", //Looxix (Server time is now)
+"guesstimezone" => "Utiliser la valeur du navigateur", //Looxix (Fill in from browser)
+"defaultns" => "Par défaut, rechercher dans ces espaces :", //Looxix (Search in these namespaces by default)
+
+# Recent changes
+#
+"changes" => "modifications",
+"recentchanges" => "Modifications récentes",
+"recentchangestext" => "Suivez sur cette page les dernières modifications de {{SITENAME}}.
+[[{{ns:project}}:Bienvenue|Bienvenue]] aux nouveaux participants !
+Jetez un coup d'\x{0153}il sur ces pages : [[{{ns:project}}:FAQ|foire aux questions]],
+[[{{ns:project}}:Recommandations et règles à suivre|recommandations et règles à suivre]]
+(notamment [[{{ns:project}}:Règles de nommage|conventions de nommage]],
+[[{{ns:project}}:La neutralité de point de vue|la neutralité de point de vue]]),
+et [[{{ns:project}}:Les faux-pas les plus courants|les faux-pas les plus courants]].
+
+Si vous voulez que {{SITENAME}} connaisse le succès, merci de ne pas y inclure pas de matériaux protégés par des [[{{ns:project}}:Copyright|copyrights]]. La responsabilité juridique pourrait en effet compromettre le projet.",
+"rcnote" => "Voici les <strong>$1</strong> dernières modifications effectuées au cours des <strong>$2</strong> derniers jours.",
+"rcnotefrom" => "Voici les modifications effectuées depuis le <strong>$2</strong> (<b>$1</b> au maximum).",
+"rclistfrom" => "Afficher les nouvelles modifications depuis le $1.",
+# "rclinks" => "Afficher les $1 dernières modifications effectuées au cours des $2 dernières heures / $3 derniers jours",
+# "rclinks" => "Afficher les $1 dernières modifications effectuées au cours des $2 derniers jours.",
+"rclinks" => "Afficher les $1 dernières modifications effectuées au cours des $2 derniers jours; $3 modifications mineures.", // Looxix
+"diff" => "diff",
+"hist" => "hist",
+"hide" => "cacher",
+"show" => "montrer",
+"minoreditletter" => "M",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => 'Copiar sul serveire',
+"uploadbtn" => 'Copiar un fichièr',
+"reupload" => "Copier à nouveau",
+"reuploaddesc" => "Retour au formulaire.",
+
+'uploadnologin' => 'Non connectat(ada)',
+"uploadnologintext" => "Vous devez être [[Special:Userlogin|connecté]]
+pour copier des fichiers sur le serveur.",
+'uploaderror' => 'Error',
+"uploadtext" => "'''STOP !''' Avant de copier votre fichier sur le serveur,
+prenez connaissance des [[Project:règles d'utilisation des images|règles d'utilisation des images]] de {{SITENAME}} et assurez-vous que vous les respectez.<br />N'oubliez pas de remplir la [[Project:Page de description d'une image|page de description de l'image]] quand celle-ci sera sur le serveur.
+
+Pour voir les images déjà placées sur le serveur ou pour effectuer une recherche parmi celles-ci,
+allez à la [[Special:Imagelist|liste des images]].
+Les uploads et les suppressions sont listés dans le [[Project:Journal_des_uploads|journal des uploads]].
+
+Utilisez le formulaire ci-dessous pour copier sur le serveur de nouvelles images destinées à illustrer vos articles.
+Sur la plupart des navigateurs, vous verrez un bouton \"Browse...\" qui ouvre la fenêtre de dialogue standard de votre système d'exploitation pour l'ouverture des fichiers.
+Sélectionnez un fichier, son nom apparaîtra dans le champ situé à côté du bouton.
+Vous devez également confirmer, en cochant la case prévue à cet effet, que la copie de ce fichier ne viole aucun copyright.
+Cliquez sur le bouton \"Envoyer\" pour terminer.
+Si votre connexion est lente, l'opération peut prendre un certain temps.
+
+Les formats recommandés sont JPEG pour les photos, PNG
+pour les dessins et les autres images, et OGG pour les fichiers sonores.
+Donnez à vos fichiers des noms descriptifs clairs, afin d'éviter toute confusion.
+Pour incorporer l'image dans un article, placez dans celui-ci un lien rédigé comme suit:
+'''<nowiki>[[image:nom_du_fichier.jpg]]</nowiki>''' ou
+'''<nowiki>[[image:nom_du_fichier.png|autre texte]]</nowiki>''' ou
+'''<nowiki>[[media:nom_du_fichier.ogg]]</nowiki>''' pour les sons.
+
+N'oubliez pas que, comme toutes les pages de {{SITENAME}}, les fichiers que vous copiez peuvent être modifiés ou supprimés par les autres utilisateurs s'ils estiment que cela est dans l'intérêt de l'encyclopédie. Sachez aussi que votre accès au serveur peut être bloqué si vous faites un mauvais usage du système.",
+"uploadlog" => "log d'upload", // FIXME
+"uploadlogpage" => "Log_d'upload", // FIXME
+"uploadlogpagetext" => "Voici la liste des derniers fichiers copiés sur le serveur.
+L'heure indiquée est celle du serveur (UTC).
+<ul>
+</ul>",
+"filename" => "Nom",
+"filedesc" => "Description",
+"copyrightpage" => "{{ns:project}}:Copyright",
+"copyrightpagename" => "licence {{SITENAME}}",
+"uploadedfiles" => 'Fichièrs copiats',
+"minlength" => "Les noms des images doivent comporter au moins trois lettres.",
+"badfilename" => "L'image a été renommée \"$1\".",
+"badfiletype" => "\".$1\" n'est pas un format recommandé pour les fichiers images.",
+"largefile" => "La taille maximale conseillée pour les images est de 100Ko.",
+"successfulupload" => "Copie réussie",
+"fileuploaded" => "Le fichier \"$1\" a été copié sur le serveur.
+Suivez ce lien: ($2) pour accéder à la page de description, et donner des informations sur le fichier, par exemple son origine, sa date de création, son auteur, ou tout autre renseignement en votre possession.",
+"uploadwarning" => "Attention !",
+"savefile" => "Sauvegarder le fichier",
+"uploadedimage" => " \"[[$1]]\" copié sur le serveur",
+
+# Image list
+#
+"imagelist" => "Liste des images",
+"imagelisttext" => "Voici une liste de $1 images classées $2.",
+"getimagelist" => "Récupération de la liste des images",
+"ilsubmit" => "Chercher",
+"showlast" => "Afficher les $1 dernières images classées $2.",
+"byname" => "par nom",
+"bydate" => "par date",
+"bysize" => "par taille",
+"imgdelete" => "suppr",
+"imgdesc" => "descr",
+"imglegend" => "Légende: (descr) = afficher/modifier la description de l'image.",
+"imghistory" => "Historique de l'image",
+"revertimg" => "rétab",
+"deleteimg" => "suppr",
+"deleteimgcompletely" => "suppr",
+"imghistlegend" => "Légende: (actu) = ceci est l'image actuelle, (suppr) = supprimer
+cette ancienne version, (rétab) = rétablir cette ancienne version.
+<br /><i>Cliquez sur la date pour voir l'image copiée à cette date</i>.",
+"imagelinks" => "Liens vers l'image",
+"linkstoimage" => "Les pages ci-dessous comportent un lien vers cette image:",
+"nolinkstoimage" => "Aucune page ne comporte de lien vers cette image.",
+
+# Statistics
+
+"statistics" => "Statistiques",
+"sitestats" => "Statistiques du site",
+"userstats" => "Statistiques utilisateur",
+"sitestatstext" => "La base de données contient actuellement <b>$1</b> pages.
+
+Ce chiffre inclut les pages \"discussion\", les pages relatives à {{SITENAME}}, les pages minimales (\"bouchons\"), les pages de redirection, ainsi que d'autres pages qui ne peuvent sans doute pas être considérées comme des articles.
+Si l'on exclut ces pages, il reste <b>$2</b> pages qui sont probablement de véritables articles.<p>
+<b>$3</b> pages ont été consultées et <b>$4</b> pages modifiées
+
+depuis la mise à jour du logiciel (31 octobre 2002).
+Cela représente une moyenne de <b>$5</b> modifications par page et de <b>$6</b> consultations pour une modification.",
+"userstatstext" => "Il y a <b>$1</b> utilisateurs enregistrés.
+Parmi ceux-ci, <b>$2</b> ont le statut d'administrateur (voir $3).",
+
+
+# Maintenance Page
+#
+"disambiguations" => "Pages d'homonymie",
+"disambiguationspage" => "{{ns:project}}:Liens_aux_pages_d'homonymie",
+"disambiguationstext" => "Les articles suivants sont liés à une <i>page d'homonymie</i>. Or, ils devraient être liés au sujet.<br />Une page est considérée comme page d'homonymie si elle est liée à partir de $1.<br />Les liens à partir d'autres <i>espaces</i> ne sont pas pris en compte.",
+"doubleredirects" => "Double redirection",
+"doubleredirectstext" => "<b>Attention:</b> cette liste peut contenir des \"faux positifs\". Dans ce cas, c'est probablement la page du premier #REDIRECT contient aussi du texte.<br />Chaque ligne contient les liens à la 1re et 2e page de redirection, ainsi que la première ligne de cette dernière, qui donne normalement la \"vraie\" destination. Le premier #REDIRECT devrait lier vers cette destination.",
+"brokenredirects" => "Redirections cassées",
+"brokenredirectstext" => "Ces redirections mènent a une page qui n'existe pas.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Pages orphelines",
+"unusedimages" => "Imatges orfanèls",
+"popularpages" => "Pages les plus consultées",
+"nviews" => "$1 consultations",
+"wantedpages" => "Paginas mai demandadas",
+"nlinks" => "$1 références",
+"allpages" => "Toutes les pages",
+"randompage" => "Une page au hasard",
+"shortpages" => "Articles courts",
+"longpages" => "Articles longs",
+"listusers" => "Liste des participants",
+"specialpages" => "Pages spéciales",
+"spheading" => "Pages spéciales",
+"recentchangeslinked" => "Suivi des liens",
+"rclsub" => "(des pages liées à \"$1\")",
+"newpages" => "Nouvelles pages",
+"ancientpages" => "Articles les plus anciens", // Looxix
+// "intl" => "Liens inter-langues",
+"movethispage" => "Déplacer la page",
+"unusedimagestext" => "<p>N'oubliez pas que d'autres sites, comme certains {{SITENAME}}s non francophones, peuvent contenir un lien direct vers cette image, et que celle-ci peut être placée dans cette liste alors qu'elle est en réalité utilisée.",
+"booksources" => "Ouvrages de référence",
+"booksourcetext" => "Voici une liste de liens vers d'autres sites qui vendent des livres neufs et d'occasion et sur lesquels vous trouverez peut-être des informations sur les ouvrages que vous cherchez. {{SITENAME}} n'étant liée à aucune de ces sociétés, elle n'a aucunement l'intention d'en faire les objets d'une préférence particulière.",
+"alphaindexline" => "$1 à $2",
+
+# Email this user
+#
+"mailnologin" => "Pas d'adresse",
+"mailnologintext" => "Vous devez être [[Special:Userlogin|connecté]]
+et avoir indiqué une adresse électronique valide dans vos [[Special:Preferences|préférences]]
+pour pouvoir envoyer un message à un autre utilisateur.",
+"emailuser" => "Envoyer un message à cet utilisateur",
+"emailpage" => "Email user",
+"emailpagetext" => "Si cet utilisateur a indiqué une adresse électronique valide dans ses préférences, le formulaire ci-dessous lui enverra un message.
+L'adresse électronique que vous avez indiquée dans vos préférences apparaîtra dans le champ \"Expéditeur\" de votre message, afin que le destinataire puisse vous répondre.",
+"noemailtitle" => "Pas d'adresse électronique",
+"noemailtext" => "Cet utilisateur n'a pas spécifié d'adresse électronique valide ou a choisi de ne pas recevoir de courrier électronique des autres utilisateurs.",
+
+"emailfrom" => "Expéditeur",
+"emailto" => "Destinataire",
+"emailsubject" => "Objet",
+"emailmessage" => "Message",
+"emailsend" => "Envoyer",
+"emailsent" => "Message envoyé",
+"emailsenttext" => "Votre message a été envoyé.",
+
+# Watchlist
+#
+'watchlist' => 'Lista de seguit',
+"nowatchlist" => "Votre liste de suivi ne contient aucun article.",
+"watchnologin" => "Non connecté",
+"watchnologintext" => "Vous devez être [[Special:Userlogin|connecté]]
+pour modifier votre liste.",
+"addedwatch" => "Ajouté à la liste",
+"addedwatchtext" => "La page \"$1\" a été ajoutée à votre <a href=\"" .
+ "{{localurle:Special:Watchlist}}\">liste de suivi</a>.
+Les prochaines modifications de cette page et de la page discussion associée seront répertoriées ici, et la page apparaîtra <b>en gras</b> dans la <a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">liste des modifications récentes</a> pour être repérée plus facilement.</p>
+
+<p>Pour supprimer cette page de votre liste de suivi, cliquez sur \"Ne plus suivre\" dans le cadre de navigation.",
+"removedwatch" => "Supprimée de la liste de suivi",
+"removedwatchtext" => "La page \"$1\" a été supprimée de votre liste de suivi.",
+"watchthispage" => "Suivre cette page",
+"unwatchthispage" => "Ne plus suivre",
+"notanarticle" => "Aucun article",
+"watchnochange" => "Aucune des pages que vous suivez n'a été modifiée pendant la période affichée.", // Looxix
+"watchdetails" => "Vous suivez $1 pages, sans compter les pages de discussion. [$4 Afficher et modifier la liste complète].", // Looxix
+"watchmethod-recent" => "vérification des modifications récentes des pages suivies", // Looxix
+"watchmethod-list" => "vérification des pages suivies pour des modifications récentes", // Looxix
+
+"removechecked" => "Retirer de la liste de suivi les articles sélectionnés", // Looxix
+"watchlistcontains" => "Votre liste de suivi contient $1 pages", // Looxix
+"watcheditlist" => "Ceci est votre liste de suivi par ordre alphabétique. Sélectionnez les pages que vous souhaitez retirer de la liste et cliquez le bouton \"retirer de la liste de suivi\" en bas de l'écran.", // Looxix
+"removingchecked" => "Les articles sélectionnés sont retirés de votre liste de suivi...", // Looxix
+"couldntremove" => "Impossible de retirer l'article '$1'...", // Looxix "Couldn't remove item '$1'...",
+"iteminvalidname" => "Problème avec l'article '$1': les nom est invalide...", // Looxix
+"wlnote" => "Ci-dessous se trouve les $1 dernières modifications depuis les <b>$2</b> dernières heures.", // Looxix
+'wldone' => 'Acabat.',
+
+# Delete/protect/revert
+#
+"deletepage" => "Supprimer une page",
+"confirm" => "Confirmer",
+"excontent" => "contenant '$1'",
+"exbeforeblank" => "le contenu avant effacement était :'$1'",
+"exblank" => "page vide",
+"confirmdelete" => "Confirmer la suppression",
+"deletesub" => "(Suppression de \"$1\")",
+"historywarning" => "Attention: La page que vous êtes sur le point de supprimer à un historique:",
+"confirmdeletetext" => "Vous êtes sur le point de supprimer définitivement de la base de données une page
+ou une image, ainsi que toutes ses versions antérieures.
+Veuillez confirmer que c'est bien là ce que vous voulez faire, que vous en comprenez les conséquences et que vous faites cela en accord avec les [[{{ns:project}}:Recommandations Et Règles à Suivre|recommandations et règles à suivre]].",
+"actioncomplete" => "Suppression effectuée",
+"deletedtext" => "\"$1\" a été supprimé.
+Voir $2 pour une liste des suppressions récentes.",
+"deletedarticle" => "effacement de \"$1\"",
+"dellogpage" => "Trace des effacements",
+"dellogpagetext" => "Voici la liste des suppressions récentes.
+L'heure indiquée est celle du serveur (UTC).
+<ul>
+</ul>",
+"deletionlog" => "trace des effacements",
+"reverted" => "Rétablissement de la version précédente",
+"deletecomment" => "Motif de la suppression",
+"imagereverted" => "La version précédente a été rétablie.",
+"rollback" => "révoquer modifications",
+"rollbacklink" => "révoquer",
+"rollbackfailed" => "La révocation a échoué",
+"cantrollback" => "Impossible de révoquer: dernier auteur est le seul à avoir modifié cet article",
+"alreadyrolled" => "Impossible de révoquer la dernière modification de [[:$1]]
+par [[User:$2|$2]] ([[User talk:$2|Talk]]); quelqu'un d'autre à déjà modifer ou révoquer l'article.
+
+La dernière modificaion était de [[User:$3|$3]] ([[User talk:$3|Talk]]).", //Looxix
+
+# only shown if there is an edit comment
+"editcomment" => "Le résumé de la modification était: \"<i>$1</i>\".", //Looxix
+"revertpage" => "restitution de la dernière modification de $1",
+
+# Undelete
+#
+"undelete" => "Restaurer la page effacée",
+"undeletepage" => "Voir et restaurer la page effacée",
+"undeletepagetext" => "Ces pages ont été effacées et se trouvent dans la corbeille, elles sont toujours dans la base de donnée et peuvent être restaurées.
+La corbeille peut être effacée périodiquement.",
+
+"undeletearticle" => "Restaurer les articles effacés",
+"undeleterevisions" => "$1 révisions archivées", // Looxix "$1 revisions archived",
+"undeletehistory" => "Si vous restaurez la page, toutes les révisions seront restaurées dans l'historique.
+Si une nouvelle page avec le même nom a été crée depuis la suppression,
+les révisions restaurées apparaîtront dans l'historique antérieur et la version courante ne sera pas automatiquement remplacée.", // Looxix
+"undeleterevision" => "Version effacée ($1)", // Looxix "Deleted revision as of $1",
+"undeletebtn" => "Restaurer !", // Looxix "Restore!",
+"undeletedarticle" => "restauré \"$1\"", // FvdP "restored \"$1\""
+# Contributions
+#
+"contributions" => "Contributions",
+"mycontris" => "Mes contributions",
+"contribsub" => "Pour $1",
+"nocontribs" => "Aucune modification correspondant à ces critères n'a été trouvée.",
+"ucnote" => "Voici les <b>$1</b> dernières modifications effectuées par cet utilisateur au cours des <b>$2</b> derniers jours.",
+"uclinks" => "Afficher les $1 dernières modifications; afficher les $2 derniers jours.",
+"uctop" => " (dernière)", // FvdP " (top)"
+
+# What links here
+#
+"whatlinkshere" => 'Paginas ligadas',
+"notargettitle" => "Pas de cible",
+"notargettext" => "Indiquez une page cible ou un utilisateur cible.",
+"linklistsub" => "(Liste de liens)",
+"linkshere" => "Les pages ci-dessous contiennent un lien vers celle-ci:",
+"nolinkshere" => "Aucune page ne contient de lien vers celle-ci.",
+"isredirect" => "page de redirection",
+
+# Block/unblock IP
+#
+"blockip" => "Bloquer une adresse IP",
+"blockiptext" => "Utilisez le formulaire ci-dessous pour bloquer l'accès en écriture à partir d'une adresse IP donnée.
+Une telle mesure ne doit être prise que pour empêcher le vandalisme et en accord avec [[{{ns:project}}:Recommandations et règles à suivre|recommandations et règles à suivre]].
+Donnez ci-dessous une raison précise (par exemple en indiquant les pages qui ont été vandalisées).",
+"ipaddress" => "Adresse IP",
+"ipbreason" => "Motif",
+"ipbsubmit" => "Bloquer cette adresse",
+"badipaddress" => "L'adresse IP n'est pas correcte.",
+"blockipsuccesssub" => "Blocage réussi",
+"blockipsuccesstext" => "L'adresse IP \"$1\" a été bloquée.
+<br />Vous pouvez consulter sur cette [[Special:Ipblocklist|page]] la liste des adresses IP bloquées.",
+"unblockip" => "Débloquer une adresse IP",
+"unblockiptext" => "Utilisez le formulaire ci-dessous pour rétablir l'accès en écriture
+à partir d'une adresse IP précédemment bloquée.",
+"ipusubmit" => "Débloquer cette adresse",
+"ipblocklist" => "Liste des adresses IP bloquées",
+"blocklistline" => "$1, $2 a bloqué $3 ($4)",
+"blocklink" => "bloquer",
+"unblocklink" => "débloquer",
+"contribslink" => "contribs",
+"autoblocker" => "Autobloqué parce que vous partagez un adresse IP avec \"$1\". Raison : \"$2\".", // Looxix
+
+
+# Developer tools
+#
+"lockdb" => "Verrouiller la base",
+"unlockdb" => "Déverrouiller la base",
+"lockdbtext" => "Le verrouillage de la base de données empêchera tous les utilisateurs de modifier des pages, de sauvegarder leurs préférences, de modifier leur liste de suivi et d'effectuer toutes les autres opérations nécessitant des modifications dans la base de données.
+Veuillez confirmer que c'est bien là ce que vous voulez faire et que vous débloquerez la base dès que votre opération de maintenance sera terminée.",
+"unlockdbtext" => "Le déverrouillage de la base de données permettra à nouveau à tous les utilisateurs de modifier des pages, de mettre à jour leurs préférences et leur liste de suivi, ainsi que d'effectuer les autres opérations nécessitant des modifications dans la base de données.
+Veuillez confirmer que c'est bien là ce que vous voulez faire.",
+"lockconfirm" => "Oui, je confirme que je souhaite verrouiller la base de données.",
+"unlockconfirm" => "Oui, je confirme que je souhaite déverrouiller la base de données.",
+
+"lockbtn" => "Verrouiller la base",
+"unlockbtn" => "Déverrouiller la base",
+"locknoconfirm" => "Vous n'avez pas coché la case de confirmation.",
+"lockdbsuccesssub" => "Verrouillage de la base réussi.",
+"unlockdbsuccesssub" => "Base déverrouillée.",
+"lockdbsuccesstext" => "La base de données de {{SITENAME}} est verrouillée.
+
+<br />N'oubliez pas de la déverrouiller lorsque vous aurez terminé votre opération de maintenance.",
+"unlockdbsuccesstext" => "La base de données de {{SITENAME}} est déverrouillée.",
+
+# Move page
+#
+"movepage" => "Déplacer un article",
+"movepagetext" => "Utilisez le formulaire ci-dessous pour renommer un article, en déplaçant toutes ses versions antérieures vers le nouveau nom.
+Le titre précédent deviendra une page de redirection vers le nouveau titre.
+Les liens vers l'ancien titre ne seront pas modifiés et la page discussion, si elle existe, ne sera pas déplacée.<br />
+<b>ATTENTION !</b>
+Il peut s'agir d'un changement radical et inattendu pour un article souvent consulté;
+assurez-vous que vous en comprenez bien les conséquences avant de procéder.",
+"movepagetalktext" => "La page de discussion associé, si présente, sera automatiquement déplacée avec '''sauf si:'''
+*Vous déplacez une page vers un autre espace,
+*Une page de discussion existe déjà avec le nouveau nom, ou
+*Vous avez désélectionné le bouton ci-dessous.
+
+Dans ce cas, vous devrez déplacer ou fusionner la page manuellement si vous le désirez.", // Looxix
+
+"movearticle" => "Déplacer l'article",
+"movenologin" => "Non connecté",
+"movenologintext" => "Pour pouvoir déplacer un article, vous devez être [[Special:Userlogin|connecté]]
+en tant qu'utilisateur enregistré.",
+"newtitle" => "Nouveau titre",
+"movepagebtn" => "Déplacer l'article",
+"pagemovedsub" => "Déplacement réussi",
+"pagemovedtext" => "L'article \"[[$1]]\" a été déplacé vers \"[[$2]]\".",
+"articleexists" => "Il existe déjà un article portant ce titre, ou le titre que vous avez choisi n'est pas valide.
+Veuillez en choisir un autre.",
+"talkexists" => "La page elle-même a été déplacée avec succès, mais
+la page de discussion n'a pas pu être déplacée car il en existait déjà une
+sous le nouveau nom. S'il vous plait, fusionnez les manuellement.", // Looxix
+
+"movedto" => "déplacé vers",
+"movetalk" => "Déplacer aussi la page \"discussion\", s'il y a lieu.",
+"talkpagemoved" => "La page discussion correspondante a également été déplacée.",
+"talkpagenotmoved" => "La page discussion correspondante n'a <strong>pas</strong> été déplacée.",
+
+# Math
+
+'mw_math_png' => "Totjorn produsir una image PNG",
+'mw_math_simple' => "HTML si plan simpla, senon PNG",
+'mw_math_html' => "HTML si possibla, senon PNG",
+'mw_math_source' => "Laissar lo còdi TeX del origina",
+'mw_math_modern' => "Per los navigaire modèrn",
+'mw_math_mathml' => 'MathML',
+
+# Other stuff
+
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesOr.php b/languages/messages/MessagesOr.php
new file mode 100644
index 000000000000..c5136493ff01
--- /dev/null
+++ b/languages/messages/MessagesOr.php
@@ -0,0 +1,22 @@
+<?php
+/** Oriya (ଓଡ଼ିଆ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+$digitTransformTable = array(
+ '0' => '୦',
+ '1' => '୧',
+ '2' => '୨',
+ '3' => '୩',
+ '4' => '୪',
+ '5' => '୫',
+ '6' => '୬',
+ '7' => '୭',
+ '8' => '୮',
+ '9' => '୯',
+);
+
+?>
diff --git a/languages/messages/MessagesOs.php b/languages/messages/MessagesOs.php
new file mode 100644
index 000000000000..a1b24d5c4562
--- /dev/null
+++ b/languages/messages/MessagesOs.php
@@ -0,0 +1,218 @@
+<?php
+/** Ossetic (Иронау)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$fallback = 'ru';
+
+$quickbarSettings = array(
+ 'Ма равдис', 'Галиуырдыгæй', 'Рахизырдыгæй', 'Рахизырдыгæй ленккæнгæ'
+);
+
+$skinNames = array(
+ 'standard' => 'Стандартон',
+ 'nostalgia' => 'Æнкъард',
+ 'cologneblue' => 'Кёльны æрхæндæг',
+ 'davinci' => 'Да Винчи',
+ 'mono' => 'Моно',
+ 'monobook' => 'Моно-чиныг',
+ 'myskin' => 'Мæхи',
+ 'chick' => 'Карк'
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media', //чтоб не писать "Мультимедия"
+ NS_SPECIAL => 'Сæрмагонд',
+ NS_MAIN => '',
+ NS_TALK => 'Дискусси',
+ NS_USER => 'Архайæг',
+ NS_USER_TALK => 'Архайæджы_дискусси',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Дискусси_$1',
+ NS_IMAGE => 'Ныв',
+ NS_IMAGE_TALK => 'Нывы_тыххæй_дискусси',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Дискусси_MediaWiki',
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Шаблоны_тыххæй_дискусси',
+ NS_HELP => 'Æххуыс',
+ NS_HELP_TALK => 'Æххуысы_тыххæй_дискусси',
+ NS_CATEGORY => 'Категори',
+ NS_CATEGORY_TALK => 'Категорийы_тыххæй_дискусси',
+);
+
+$linkTrail = '/^((?:[a-z]|а|æ|б|в|г|д|е|ё|ж|з|и|й|к|л|м|н|о|п|р|с|т|у|ф|х|ц|ч|ш|щ|ъ|ы|ь|э|ю|я|“|»)+)(.*)$/sDu';
+$fallback8bitEncoding = 'windows-1251';
+
+
+$messages = array(
+'titlematches' => 'Статьяты сæргæндты æмцаутæ',
+'toc' => 'Сæргæндтæ',
+'addedwatch' => "Дæ цæст кæмæ дарыс, уыцы статьятæм бафтыд.",
+'allarticles' => "Æппæт статьятæ",
+'allmessages' => "Æппæт техникон фыстытæ",
+'allpages' => "Æппæт фæрстæ",
+'allpagesnext' => "дарддæр",
+'allpagesprev' => "фæстæмæ",
+'alphaindexline' => "$1 (уыдоны ’хсæн цы статьятæ ис, фен) $2",
+'ancientpages' => "Зæронддæр фæрстæ",
+'and' => "æмæ",
+'articlepage' => "Фен статья",
+'blanknamespace' => "(Сæйраг)",
+'bold_sample' => "Ацы текст бæзджын суыдзæн",
+'bold_tip' => "Бæзджын текст",
+'bydate' => "рæстæгмæ гæсгæ",
+'byname' => "номмæ гæсгæ",
+'bysize' => "асмæ гæсгæ",
+'categories' => "Категоритæ",
+'categoriespagetext' => "Мæнæ ахæм категоритæ ирон Википедийы ис.",
+'category_header' => "Категори \"$1\"",
+'categoryarticlecount' => "Ацы категорийы мидæг $1 статьяйы ис.",
+'contributions' => "Йæ бавæрд",
+'createaccountmail' => "адрисмæ гæсгæ",
+'currentevents' => "Ног хабæрттæ",
+'currentevents-url' => "Xabar",
+'diff' => "хицæн.",
+'edit' => "Баив æй",
+'editsection' => "баив æй",
+'editold' => "баив æй",
+'emailpage' => "Электронон фыстæг йæм барвит",
+'error' => "Рæдыд",
+'errorpagetitle' => "Рæдыд",
+'exblank' => "фарс афтид уыдис",
+'filename' => "Файлы ном",
+'go' => "Статьямæ",
+'searcharticle' => "Статьямæ",
+'headline_sample' => "Ам сæргонды текст уæд",
+'help' => "Æххуыс",
+'hide' => "бамбæхс",
+'hidetoc' => "бамбæхс",
+'hist' => "лог",
+'histlegend' => "Куыд æй æмбарын: (нырыккон) = нырыккон версийæ хъауджыдæрдзинад, (раздæры) = раздæры версийæ хъауджыдæрдзинад, Ч = чысыл ивддзинад.",
+'history_short' => "Истори",
+'ilsubmit' => "Агур",
+'imagelist' => "Нывты номхыгъд",
+'imghistory' => "Нывы ивддзинæдты лог",
+'importnotext' => "Афтид у кæнæ текст дзы нæй",
+'internalerror' => "Мидæг рæдыд",
+'intl' => "Æндæр æвзæгтæм æрвитæнтæ",
+'ipbreason' => "Аххос",
+'largefile' => "Сæдæ килобайтæй стырдæр файлтæ æгæр дынджыр сты.",
+'last' => "раздæры",
+'lastmodifiedat' => "<span style=\"white-space: normal;\">Кæд æмæ ацы статьяйы ссардтай рæдыд, уæд сраст æй кæн: ацы фарсы уæлæ ис æрвитæн «баив æй».
+<br /> Ацы фарс фæстаг хатт ивд æрцыд: $1.</span>",
+'lineno' => "Рæнхъ $1:",
+'linklistsub' => "(Æрвитæнты номхыгъд)",
+'linkstoimage' => "Ацы нывæй чи пайда кæны, ахæм статьятæ:",
+'listusers' => "Архайджыты номхыгъд",
+'localtime' => "Бынатон рæстæг",
+'login' => "Дæхи бавдис системæйæн",
+'loginpagetitle' => "Дæхи бацамон системæйæн",
+'loginsuccess' => "Ныр та Википедийы архайыс $1, зæгъгæ, ахæм номæй.",
+'logout' => "Номсусæг суын",
+'logouttitle' => "Номсусæг суын",
+'lonelypages' => "Сидзæр фæрстæ",
+'longpages' => "Даргъ фæрстæ",
+'mailnologintext' => "Фыстæгтæ æрвитынмæ хъуамæ [[Special:Userlogin|системæйæн дæхи бавдисай]] æмæ дæ бæлвырд электронон посты адрис [[Special:Preferences|ныффыссай]].",
+'mainpage' => "Сæйраг фарс",
+'makesysopname' => "Архайæджы ном:",
+'minoredit' => "Ай чысыл ивддзинад у.",
+'monday' => "Къуырисæр",
+'move' => "Ном баив",
+'movearticle' => "Статьяйы ном баив",
+'movenologin' => "Системæйæн дæхи нæ бавдыстай",
+'mycontris' => "Дæ бавæрд",
+'mypage' => "Дæхи фарс",
+'mytalk' => "Дæумæ цы дзурынц",
+'navigation' => "хъæугæ æрвитæнтæ",
+'nbytes' => "$1 байт(ы)",
+'newarticle' => "(Ног)",
+'newimages' => "Ног нывты галерей",
+'newmessageslink' => "ног фыстæгтæ",
+'newpage' => "Ног фарс",
+'newpageletter' => "Н",
+'newpages' => "Ног фæрстæ",
+'newpassword' => "Новый пароль",
+'newtitle' => "Ног ном",
+'nextn' => "$1 размæ",
+'nlinks' => "$1 æрвитæн(ы)",
+'nowatchlist' => "Иу статьямæ дæр дæ цæст нæ дарыс.",
+'nstab-image' => "Ныв",
+'nstab-mediawiki' => "Фыстаг",
+'nstab-special' => "Сæрмагонд фарс",
+'nstab-template' => "Шаблон",
+'nstab-user' => "Архайæджы фарс",
+'otherlanguages' => "Æндæр æвзæгтыл",
+'others' => "æндæртæ",
+'pagecategories' => "Категоритæ",
+'portal' => "Архайджыты æхсæнад",
+'prevn' => "$1 фæстæмæ",
+'printableversion' => "Мыхурмæ верси",
+'qbfind' => "Агур",
+'qbspecialpages' => "Сæрмагонд фæрстæ",
+'randompage' => "Æнæбары æвзæрст фарс",
+'rclinks' => "Фæстаг $1 ивддзинæдтæ (афæстаг $2 боны дæргъы чи ’рцыдысты) равдис;
+$3",
+'rcnote' => "Дæлдæр нымад сты афæстаг <strong>$2</strong> боны дæргъы конд <strong>$1</strong> ивддзинад(ы).",
+'recentchanges' => "Фæстаг ивддзинæдтæ",
+'recentchangeslinked' => "Баст ивддзинæдтæ",
+'recentchangestext' => "Ацы фарсыл ирон Википедийы фæстаг ивддзинæдтæ фенæн ис.",
+'revhistory' => "Ивддзинæдты истори",
+'rights' => "Бартæ",
+'saturday' => "Сабат",
+'savearticle' => "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Афтæ!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
+'savefile' => "Бавæр æй",
+'search' => "агур",
+'searchbutton' => "агур",
+'searchresults' => "Цы ссардæуы",
+'shortpages' => "Цыбыр фæрстæ",
+'showpreview' => "&nbsp;&nbsp;Фен уал æй&nbsp;&nbsp;",
+'showtoc' => "равдис",
+'show' => "равдис",
+'showpreview' => "&nbsp;&nbsp;Фен уал æй&nbsp;&nbsp;",
+'specialpage' => "Сæрмагонд фарс",
+'specialpages' => "Сæрмагонд фæрстæ",
+'spheading' => "Сæрмагонд фæрстæ",
+'subcategories' => "Дæлкатегоритæ",
+'subcategorycount' => "Ацы категорийы мидæг $1 дæлкатегорийы ис.",
+'sunday' => "Хуыцаубон",
+'tagline' => "Сæрибар энциклопеди Википедийы æрмæг.",
+'talk' => "Дискусси",
+'talkpage' => "Ацы фарсы тыххæй ныхас",
+'textmatches' => "Статьяты æмцаутæ",
+'thursday' => "Цыппарæм",
+'timezonelegend' => "Сахаты таг",
+'timezoneoffset' => "Хъауджыдæрдзинад",
+'titlematches' => "Статьяты сæргæндты æмцаутæ",
+'toc' => "Сæргæндтæ",
+'tog-underline' => "Æрвитæнты бын хахх",
+'toolbox' => "мигæнæнтæ",
+'tuesday' => "Дыццæг",
+'uctop' => "(уæле баззад)",
+'userlogin' => "Системæйæн дæхи бавдис",
+'userlogout' => "Номсусæг суын",
+'userpage' => "Ацы архайæджы фарс фен",
+'userstatstext' => "Регистрацигонд æрцыдысты <b>$1</b> архайджыты, уыдонæй <b>$2</b> — админтæ (кæс $3).",
+'wantedpages' => "Хъæугæ фæрстæ",
+'watch' => "Дæ цæст æрдар",
+'watchdetails' => "($1 фæрстæм дæ цæст дарыс, дискусситы фæстæмæ; $3... [$4 Æххæст номхыгъд фен].)",
+'watchlist' => "Дæ цæст кæмæ дарыс, уыцы фæрстæ",
+'watchlistcontains' => "Дæ цæст $1 фæрстæм дарыс.",
+'watchnologin' => "Системæйæн дæхи нæ бавдыстай",
+'watchnologintext' => "Ацы номхыгъд ивынмæ <a href=\"{{localurle:Специальные:Userlogin}}\">хъуамæ дæхи бавдисай системæйæн</a>.",
+'watchthis' => "Ацы фарсмæ дæ цæст æрдар",
+'watchthispage' => "Ацы фарсмæ дæ цæст æрдар",
+'wednesday' => "Æртыццæг",
+'welcomecreation' => "<h2>Æгас цу, $1!</h2><p>Регистрацигонд æрцыдтæ.",
+'whatlinkshere' => "Цавæр æрвитæнтæ цæуынц ардæм",
+'wlnote' => "Дæлæ афæстаг <b>$2</b> сахаты дæргъы цы $1 ивддзинад(ы) æрцыди, уыдон.",
+'wlshowlast' => "Фæстæг $1 сахаты, $2 боны дæргъы; $3.",
+'youremail' => "Дæ электронон посты адрис",
+'yourlanguage' => "Техникон фыстыты æвзаг",
+'yourname' => "Дæ ном кæнæ фæсномыг",
+'yourrealname' => "Дæ æцæг ном*",
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesPa.php b/languages/messages/MessagesPa.php
new file mode 100644
index 000000000000..d1b6a4348b9a
--- /dev/null
+++ b/languages/messages/MessagesPa.php
@@ -0,0 +1,410 @@
+<?php
+/** Punjabi (Gurmukhi)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+# This file is dual-licensed under GFDL and GPL.
+#
+# See: http://bugzilla.wikimedia.org/show_bug.cgi?id=1478
+
+$quickbarSettings = array(
+ 'ਕੋਈ ਨਹੀਂ', 'ਸਥਿਰ ਖੱਬੇ', 'ਸਥਿਰ ਸੱਜਾ', 'ਤੈਰਦਾ ਖੱਬੇ'
+);
+
+$skinNames = array(
+ 'standard' => 'ਮਿਆਰੀ',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'ਮੀਡੀਆ',
+ NS_SPECIAL => 'ਖਾਸ',
+ NS_MAIN => '',
+ NS_TALK => 'ਚਰਚਾ',
+ NS_USER => 'ਮੈਂਬਰ',
+ NS_USER_TALK => 'ਮੈਂਬਰ_ਚਰਚਾ',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_ਚਰਚਾ',
+ NS_IMAGE => 'ਤਸਵੀਰ',
+ NS_IMAGE_TALK => 'ਤਸਵੀਰ_ਚਰਚਾ',
+ NS_MEDIAWIKI => 'ਮੀਡੀਆਵਿਕਿ',
+ NS_MEDIAWIKI_TALK => 'ਮੀਡੀਆਵਿਕਿ_ਚਰਚਾ',
+ NS_TEMPLATE => 'ਨਮੂਨਾ',
+ NS_TEMPLATE_TALK => 'ਨਮੂਨਾ_ਚਰਚਾ',
+ NS_HELP => 'ਮਦਦ',
+ NS_HELP_TALK => 'ਮਦਦ_ਚਰਚਾ',
+ NS_CATEGORY => 'ਸ਼੍ਰੇਣੀ',
+ NS_CATEGORY_TALK => 'ਸ਼੍ਰੇਣੀ_ਚਰਚਾ'
+);
+
+$digitTransformTable = array(
+ '0' => '੦',
+ '1' => '੧',
+ '2' => '੨',
+ '3' => '੩',
+ '4' => '੪',
+ '5' => '੫',
+ '6' => '੬',
+ '7' => '੭',
+ '8' => '੮',
+ '9' => '੯'
+);
+$linkTrail = '/^([ਁਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹ਼ਾਿੀੁੂੇੈੋੌ੍ਖ਼ਗ਼ਜ਼ੜਫ਼ੰੱੲੳa-z]+)(.*)$/sDu';
+
+
+$messages = array(
+# Bits of text used by many pages:
+#
+
+# Dates
+'sunday' => 'ਐਤਵਾਰ',
+'monday' => 'ਸੋਮਵਾਰ',
+'tuesday' => 'ਮੰਗਲਵਾਰ',
+'wednesday' => 'ਬੁਧਵਾਰ',
+'thursday' => 'ਵੀਰਵਾਰ',
+'friday' => 'ਸ਼ੁੱਕਰਵਾਰ',
+'saturday' => 'ਸ਼ਨੀਚਰਵਾਰ',
+'january' => 'ਜਨਵਰੀ',
+'february' => 'ਫ਼ਰਵਰੀ',
+'march' => 'ਮਾਰਚ',
+'april' => 'ਅਪ੍ਰੈਲ',
+'may_long' => 'ਮਈ',
+'june' => 'ਜੂਨ',
+'july' => 'ਜੁਲਾਈ',
+'august' => 'ਅਗਸਤ',
+'september' => 'ਸਤੰਬਰ',
+'october' => 'ਅਕਤੂਬਰ',
+'november' => 'ਨਵੰਬਰ',
+'december' => 'ਦਸੰਬਰ',
+'jan' => 'ਜਨਵਰੀ',
+'feb' => 'ਫ਼ਰਵਰੀ',
+'mar' => 'ਮਾਰਚ',
+'apr' => 'ਅਪ੍ਰੈਲ',
+'may' => 'ਮਈ',
+'jun' => 'ਜੂਨ',
+'jul' => 'ਜੁਲਾਈ',
+'aug' => 'ਅਗਸਤ',
+'sep' => 'ਸਤੰਬਰ',
+'oct' => 'ਅਕਤੂਬਰ',
+'nov' => 'ਨਵੰਬਰ',
+'dec' => 'ਦਸੰਬਰ',
+
+'categories' => 'ਸ਼੍ਰੇਣੀਆਂ',
+'pagecategories' => 'ਸ਼੍ਰੇਣੀਆਂ',
+'category_header' => 'ਸ਼੍ਰੇਣੀ \'$1\' ਵਾਲੇ ਲੇਖ',
+'subcategories' => 'ਉਪਸ਼੍ਰੇਣੀਆਂ',
+
+'mainpage' => 'ਮੁੱਖ ਪੰਨਾ',
+'mainpagetext' => 'ਵਿਕਿ ਸਾਫ਼ਟਵੇਅਰ ਚੰਗੀ ਤਰ੍ਹਾਂ ਇੰਸਟਾਲ ਹੋ ਗਿਆ ਹੈ',
+
+'portal' => 'ਸਮੂਹ ਦ੍ਵਾਰ',
+'portal-url' => 'Project:ਸਮੂਹ ਦ੍ਵਾਰ',
+'about' => 'ਜਾਣਕਾਰੀ',
+'aboutsite' => '{{SITENAME}} ਬਾਰੇ',
+'aboutpage' => 'Project:ਜਾਣਕਾਰੀ',
+'article' => 'ਵਿਸ਼ਾ-ਵਸਤੂ ਵਾਲਾ ਪੰਨਾ',
+'help' => 'ਮਦਦ',
+'helppage' => 'ਮਦਦ:ਵਿਸ਼ਾ-ਵਸਤੂ',
+'bugreports' => 'ਖਾਮੀ ਸੂਚਨਾ',
+'bugreportspage' => 'Project:ਖਾਮੀ_ਸੂਚਨਾ',
+'sitesupport' => 'ਦਾਨ',
+'sitesupport-url' => 'Project:ਦਾਨ',
+'faq' => 'ਪ੍ਰਸ਼ਨਾਵਲੀ - FAQ',
+'faqpage' => 'Project:ਪ੍ਰਸ਼ਨਾਵਲੀ',
+'edithelp' => 'ਬਦਲਾਵ ਮਦਦ',
+'newwindow' => '(ਨਵੀਂ window ਵਿੱਚ ਖੁੱਲੇਗਾ)',
+'edithelppage' => 'ਮਦਦ:ਬਦਲਾਵ',
+'cancel' => 'ਰੱਦ ਕਰੋ',
+'qbfind' => 'ਲੱਭੋ',
+'qbbrowse' => 'ਵੇਖੋ - Browse',
+'qbedit' => 'ਬਦਲੋ',
+'qbpageoptions' => 'ਪੰਨਾ ਵਿਕਲਪ - Options',
+'qbpageinfo' => 'ਪੰਨਾ ਜਾਣਕਾਰੀ',
+'qbmyoptions' => 'ਮੇਰੇ ਵਿਕਲਪ',
+'qbspecialpages' => 'ਖਾਸ ਪੰਨੇ',
+'moredotdotdot' => 'ਹੋਰ...',
+'mypage' => 'ਮੇਰਾ ਪੰਨਾ',
+'mytalk' => 'ਮੇਰੀ ਚਰਚਾ',
+'anontalk' => 'ਇੱਸ ਆਈ-ਪੀ (IP) ਦੀ ਚਰਚਾ',
+'navigation' => 'ਨੈਵੀਗੇਸ਼ੱਨ',
+
+
+
+'disclaimers' => 'ਡਿਸਕਲੇਮਰ',
+'disclaimerpage' => 'Project:General_disclaimer',
+'errorpagetitle' => 'ਗਲਤੀ',
+'returnto' => 'ਵਾਪਿਸ ਪਰਤੋ: $1.',
+'tagline' => '{{SITENAME}} ਤੋਂ',
+'whatlinkshere' => 'ਪੰਨੇ ਜੋ ਇੱਥੇ ਜੁੜਦੇ ਹਨ',
+'help' => 'ਮਦਦ',
+'search' => 'ਖੋਜ',
+'searchbutton' => 'ਖੋਜ',
+'go' => 'ਜਾਓ',
+'searcharticle' => 'ਜਾਓ',
+'history' => 'ਪੁਰਾਣੇ ਆਵਰਤਣ',
+'history_short' => 'ਇਤਿਹਾਸ',
+'info_short' => 'ਸੂਚਨਾ',
+'printableversion' => 'ਛਾਪਣ-ਯੋਗ ਆਵਰਤਣ',
+'edit' => 'ਬਦਲੋ',
+'editthispage' => 'ਇਸ ਪੰਨੇ ਨੂੰ ਬਦਲੋ',
+'delete' => 'ਹਟਾਓ',
+'deletethispage' => 'ਇਸ ਪੰਨੇ ਨੂੰ ਹਟਾਓ',
+'undelete_short' => '$1 ਬਦਲਾਵ ਮੁੜ ਵਾਪਿਸ ਲਿਆਓ',
+'protect' => 'ਰੱਖਿਆ ਕਰੋ',
+'protectthispage' => 'ਇਸ ਪੰਨੇ ਦੀ ਰੱਖਿਆ ਕਰੋ',
+'unprotect' => 'ਅਸੁਰੱਖਿਅਤ ਕਰੋ',
+'unprotectthispage' => 'ਇਸ ਪੰਨੇ ਨੂੰ ਅਸੁਰੱਖਿਅਤ ਕਰੋ',
+'newpage' => 'ਨਵਾਂ ਪੰਨਾ',
+'talkpage' => 'ਇਸ ਪੰਨੇ ਤੇ ਚਰਚਾ ਕਰੋ',
+'specialpage' => 'ਖ਼ਾਸ ਪੰਨਾ',
+'personaltools' => 'ਨਿਜੀ ਔਜ਼ਾਰ',
+'postcomment' => 'ਆਪਨੇ ਵਿਚਾਰ ਪੇਸ਼ ਕਰੋ',
+'articlepage' => 'ਵਿਸ਼ਾ-ਵਸਤੂ ਵਾਲਾ ਪੰਨਾ ਵੇਖੋ',
+'talk' => 'ਚਰਚਾ',
+'toolbox' => 'ਔਜ਼ਾਰ-ਡੱਬਾ',
+'userpage' => 'ਮੈਂਬਰ ਦਾ ਪੰਨਾ ਵੇਖੋ',
+'projectpage' => 'ਪਰਿਯੋਜਨਾ (project) ਵਾਲਾ ਪੰਨਾ ਵੇਖੋ',
+'imagepage' => 'ਤਸਵੀਰ ਵਾਲਾ ਪੰਨਾ ਵੇਖੋ',
+'viewtalkpage' => 'ਚਰਚਾ ਵਾਲਾ ਪੰਨਾ ਵੇਖੋ',
+'otherlanguages' => 'ਬਾਕੀ ਭਾਸ਼ਾਵਾਂ',
+'redirectedfrom' => '($1 ਤੋਂ ਭੇਜਿਆ ਗਿਆ ਹੈ)',
+'lastmodifiedat' => 'ਅਖੀਰਲਾ ਬਦਲਾਵ $2, $1',
+'viewcount' => 'ਇਹ ਪੰਨਾ $1 ਵਾਰ ਵੇਖਿਆ ਗਿਆ ਹੈ',
+'copyright' => 'ਵਿਸ਼ਾ-ਵਸਤੂ $1 ਤਹਿਤ ਉਪਲੱਬਧ ਹੈ',
+'protectedpage' => 'ਸੁਰੱਖਿਅਤ ਪੰਨਾ',
+'nbytes' => '$1 ਬਾਈਟ',
+'ok' => 'ਠੀਕ ਹੈ',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => '\'$1\' ਤੋਂ ਪ੍ਰਾਪਤ ਕੀਤਾ ਗਿਆ ਹੈ',
+'newmessageslink' => 'ਨਵੇਂ ਸੰਦੇਸ਼',
+'editsection' => 'ਬਦਲੋ',
+'editold' => 'ਬਦਲੋ',
+'toc' => 'ਵਿਸ਼ਾ-ਸੂਚੀ',
+'showtoc' => 'ਦਿਖਾਓ',
+'hidetoc' => 'ਛੁਪਾਓ',
+'thisisdeleted' => 'ਵੇਖੋ ਜਾਂ ਮੁੜ ਵਾਪਿਸ ਲਿਆਓ $1?',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'ਲੇਖ',
+'nstab-user' => 'ਮੈਂਬਰ ਦਾ ਪੰਨਾ',
+'nstab-media' => 'ਮੀਡੀਆ',
+'nstab-special' => 'ਖਾਸ',
+'nstab-project' => 'ਜਾਣਕਾਰੀ',
+'nstab-image' => 'ਤਸਵੀਰ',
+'nstab-mediawiki' => 'ਸੰਦੇਸ਼',
+'nstab-template' => 'ਨਮੂਨਾ',
+'nstab-help' => 'ਮਦਦ',
+'nstab-category' => 'ਸ਼੍ਰੇਣੀ',
+
+# Main script and global functions
+#
+'nosuchaction' => 'ਅਜੇਹੀ ਕੋਈ ਕਿਰਿਆ ਨਹੀਂ ਹੈ',
+'nosuchactiontext' => 'URL ਦੁਵਾਰਾ ਕੀਤੀ ਗਈ ਕਿਰਿਆ (action) ਤੋਂ ਵਿਕਿ ਸੋਫ਼ਟਵੇਅਰ ਜਾਣੂ ਨਹੀਂ ਹੈ',
+'nosuchspecialpage' => 'ਅਜੇਹਾ ਕੋਈ ਖਾਸ ਪੰਨਾ ਨਹੀਂ ਹੈ',
+'nospecialpagetext' => 'ਤੁਸੀਂ ਇੱਕ ਖਾਸ ਪੰਨੇ ਦੀ ਮੰਗ ਕੀਤੀ ਹੈ ਜਿਸ ਤੋਂ ਵਿਕਿ ਸੋਫ਼ਟਵੇਅਰ ਜਾਣੂ ਨਹੀਂ ਹੈ',
+
+# General errors
+#
+'error' => 'ਗਲਤੀ',
+'databaseerror' => 'ਡਾਟਾਬੇਸ ਨਾਲ ਸੰਬੰਧਤ ਗਲਤੀ',
+'dberrortext' => 'ਡਾਟਾਬੇਸ ਪੁੱਛਗਿੱਛ ਦੀ ਵਾਕ-ਰਚਨਾ ਵਿਚ ਕੋਈ ਗਲਤੀ ਹੋ ਗਈ ਹੈ।
+ਇਹ ਕਿਸੇ ਖੋਜ ਬਾਰੇ ਗਲਤ ਪੁੱਛਗਿੱਛ ਦੇ ਕਾਰਨ ਹੋ ਸਕਦਾ ਹੈ($5 ਦੇਖੋ),
+ਜਾਂ ਸ਼ਾਇਦ ਸੌਫ਼ਟਵੇਅਰ ਵਿਚ ਕੋਈ ਖ਼ਰਾਬੀ ਹੋ ਸਕਦੀ ਹੈ।
+ਪਿਛਲੀ ਵਾਰ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਗਈ ਡਾਟਾਬੇਸ ਪੁੱਛਗਿੱਛ ਇਹ ਸੀ:
+<blockquote><tt>$1</tt></blockquote>
+\'<tt>$2</tt>\'ਇਸ ਫ਼ੰਕਸ਼ਨ ਦੇ ਵਿਚੋਂ।
+MySQL ਨੇ \'<tt>$3: $4</tt>\'ਗਲਤੀ ਦਿਖਾਈ।',
+'dberrortextcl' => 'ਡਾਟਾਬੇਸ ਪੁੱਛਗਿੱਛ ਦੀ ਵਾਕ-ਰਚਨਾ ਵਿਚ ਕੋਈ ਗਲਤੀ ਹੋ ਗਈ ਹੈ।
+ਪਿਛਲੀ ਵਾਰ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਗਈ ਡਾਟਾਬੇਸ ਪੁੱਛਗਿੱਛ ਇਹ ਸੀ:
+<blockquote><tt>$1</tt></blockquote>
+\'$2\'ਇਸ ਫ਼ੰਕਸ਼ਨ ਦੇ ਵਿਚੋਂ।
+MySQL ਨੇ \'$3: $4\'ਗਲਤੀ ਦਿਖਾਈ।\n',
+'noconnect' => 'ਮਾਫ਼ ਕਰਨਾ! ਵਿਕਿ ਨੂੰ ਕੁਝ ਤਕਨੀਕੀ ਮੁਸ਼ਕਲਾਂ ਦਾ ਸਾਹਮਣਾ ਕਰਨਾ ਪੈ ਰਿਹਾ ਹੈ, ਅਤੇ ਇਹ ਡਾਟਾਬੇਸ ਸਰਵਰ ਨਾਲ ਸੰਪਰਕ ਨਹੀਂ ਬਣਾ ਸਕਦਾ ਹੈ। <br />$1',
+'nodb' => 'ਡਾਟਾਬੇਸ $1 ਨੂੰ ਚੁਣ ਨਹੀਂ ਸਕਿਆ',
+'internalerror' => 'ਅੰਦਰੂਨੀ ਗਲਤੀ',
+'filecopyerror' => 'ਫ਼ਾਈਲ \'$1\' ਨੂੰ ਫ਼ਾਈਲ \'$2\' ਤੇ ਨਕਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ',
+'filerenameerror' => 'ਫ਼ਾਈਲ \'$1\' ਦਾ ਨਾਮ \'$2\' ਨਹੀਂ ਕੀਤਾ ਜਾ ਸੱਕਿਆ',
+'filedeleteerror' => 'ਫ਼ਾਈਲ \'$1\' ਨੂੰ ਨਹੀਂ ਹਟਾਇਆ ਜਾ ਸੱਕਿਆ',
+'filenotfound' => 'ਫ਼ਾਈਲ \'$1\' ਨਹੀਂ ਲੱਭੀ ਜਾ ਸਕੀ',
+'unexpected' => 'Unexpected value: \'$1\'=\'$2\'.',
+'formerror' => 'Error: could not submit form',
+'badarticleerror' => 'ਇਹ ਕਿਰਿਆ ਇਸ ਪੰਨੇ ਤੇ ਸੰਪੰਨ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ',
+'cannotdelete' => 'ਪੰਨੇ ਜਾਂ ਤਸਵੀਰ ਨੂੰ ਨਹੀਂ ਹਟਾ ਸੱਕਿਆ ਗਿਆ (ਇਹ ਸ਼ਾਇਦ ਪਿਹਲਾਂ ਹੀ ਕਿਸੇ ਦੁਆਰਾ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ)',
+'badtitle' => 'ਗਲਤ ਸਿਰਲੇਖ',
+'viewsource' => 'ਸ੍ਰੋਤ ਦੇਖੋ',
+'protectedtext' => 'This page has been locked to prevent editing; there are
+a number of reasons why this may be so, please see
+[[{{ns:4}}:Protected page]].
+
+You can view and copy the source of this page:',
+
+# Login and logout pages
+#
+'logouttitle' => 'ਮੈਂਬਰ ਲਾਗ ਆਊਟ',
+'logouttext' => 'ਹੁਣ ਤੁਸੀਂ ਲਾਗ ਆਊਟ ਹੋ ਚੁੱਕੇ ਹੋ। ਹੁਣ ਤੁਸੀਂ ਅਗਿਆਤ ਰੂਪ ਵਿੱਚ
+ {{SITENAME}} ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਹੋ ਜਾਂ ਓਹੀ ਮੈਂਬਰ
+ਜਾਂ ਕਿਸੇ ਹੋਰ ਮੈਂਬਰ ਦੇ ਰੂਪ ਵਿੱਚ ਲਾਗ ਇਨ ਕਰ ਸਕਦੇ ਹੋ।
+Note that some pages may continue to be displayed as if you were
+still logged in, until you clear your browser cache\n',
+
+'welcomecreation' => '== ਜੀ ਆਇਆਂ ਨੂੰ, $1! ==
+
+ਤੁਹਾਡਾ ਖਾਤਾ ਬਣਾ ਦਿੱਤਾ ਗਿਆ ਹੈ, ਆਪਣੀਆਂ {{SITENAME}} ਪਸੰਦਾਂ (preferences) ਨੂੰ ਬਦਲਣਾ ਨਾ ਭੁਲਣਾ।',
+
+'loginpagetitle' => 'ਮੈਂਬਰ ਲਾਗ ਇਨ',
+'yourname' => 'ਤੁਹਾਡਾ ਨਾਮ',
+'yourpassword' => 'ਤੁਹਾਡਾ ਪਾਸਵਰਡ',
+'yourpasswordagain' => 'ਪਾਸਵਰਡ ਦੌਬਾਰਾ ਲਿੱਖੋ',
+'remembermypassword' => 'ਅੱਗੋਂ ਲਈ ਮੇਰਾ ਪਾਸਵਰਡ ਯਾਦ ਰੱਖੋ',
+'loginproblem' => '<b>ਤੁਹਾਡੇ ਲਾਗ ਇਨ ਵਿੱਚ ਕੁਝ ਸਮੱਸਿਆ ਹੈ,</b><br />ਦੌਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ!',
+'alreadyloggedin' => '<strong>$1, ਤੁਸੀਂ ਪਿਹਲਾਂ ਹੀ ਲਾਗ ਇਨ ਹੋ ਚੁੱਕੇ ਹੋ!</strong><br />\n',
+
+'login' => 'ਲਾਗ ਇਨ',
+'loginprompt' => '{{SITENAME}} ਵਿਚ ਲਾੱਗ-ਇਨ ਕਰਨ ਲਈ ਤੁਹਾਡੀਆਂ cookies enabled ਹੋਣੀਆਂ ਚਾਹੀਦੀਆਂ ਹਨ।',
+'userlogin' => 'ਨਵਾਂ ਖਾਤਾ ਬਨਾਓ ਜਾਂ ਲਾਗ ਇਨ ਕਰੋ',
+'logout' => 'ਲਾਗ ਆਊਟ',
+'userlogout' => 'ਲਾਗ ਆਊਟ',
+'notloggedin' => 'ਲਾਗ ਇਨ ਨਹੀਂ ਹੈ',
+'createaccount' => 'ਨਵਾਂ ਖਾਤਾ ਬਣਾਓ',
+'createaccountmail' => 'ਈ-ਮੇਲ (email) ਰਾਹੀਂ',
+'badretype' => 'ਪਾਸਵਰਡ ਇਕ ਦੂਜੇ ਨਾਲ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ',
+'userexists' => 'ਇਹ ਨਾਮ ਪਿਹਲਾਂ ਹੀ ਵਰਤੋਂ ਵਿੱਚ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਕਿਸੇ ਹੋਰ ਨਾਮ ਦੀ ਵਰਤੋਂ ਕਰੋ',
+'youremail' => '* ਤੁਹਾਡਾ ਈ-ਮੇਲ (email)',
+'yourrealname' => '* ਤੁਹਾਡਾ ਨਾਮ',
+'yourlanguage' => 'Interface language',
+'yourvariant' => 'Language variant',
+'yournick' => 'ਤੁਹਾਡਾ ਉਪਨਾਮ (ਦਸਤਖ਼ਤ ਲਈ)',
+'prefs-help-realname' => '* <strong>ਅਸਲੀ ਨਾਮ</strong> (ਗੈਰ-ਜ਼ਰੂਰੀ): ਜੇ ਤੁਸੀਂ ਭਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡੇ ਕੰਮ ਨੂੰ attribution ਦੇਣ ਲਈ ਵਰਤਿਆ ਜਾਵੇਗਾ<br />',
+'prefs-help-email' => '* <strong>ਈ-ਮੇਲ</strong> (ਗੈਰ-ਜ਼ਰੂਰੀ): ਜੇ ਭਰਦੇ ਹੋ ਤਾਂ ਬਿਨਾਂ ਤੁਹਾਡੇ ਅਸਲੀ ਈ-ਮੇਲ ਨੂੰ ਜਾਣੇ, ਇਸ website ਦੁਆਰਾ ਲੋਗ ਤੁਹਾਨੂੰ ਸੰਪੰਰਕ ਕਰ ਸਕਦੇ ਹਨ
+ਅਤੇ ਜੇ ਕਦੀ ਤੁਸੀਂ ਆਪਣਾ ਪਾਸਵਰਡ ਭੁੱਲ ਜਾਓ, ਤਾਂ ਇਸ ਈ-ਮੇਲ ਤੇ ਤੁਹਾਨੂੰ ਨਵਾਂ ਪਾਸਵਰਡ ਭੇਜਿਆ ਜਾ ਸਕਦਾ ਹੈ.',
+'loginerror' => 'ਲਾਗ ਇਨ ਵਿੱਚ ਗਲਤੀ',
+'noname' => 'ਤੁਸੀਂ ਮੈਂਬਰ ਦਾ ਨਾਮ ਸਹੀ ਨਹੀਂ ਦੱਸਿਆ.',
+'loginsuccesstitle' => 'ਲਾਗ ਇਨ ਕਾਮਯਾਬ ਰਿਹਾ',
+'loginsuccess' => 'ਹੁਣ ਤੁਸੀਂ {{SITENAME}} ਵਿੱਚ \'$1\' ਨਾਮ ਨਾਲ ਲਾਗ ਇਨ ਹੋ',
+'nosuchuser' => '\'$1\' ਨਾਮ ਦਾ ਕੋਈ ਮੈਂਬਰ ਨਹੀਂ ਹੈ.
+ਕਿਰਪਾ ਕਰਕੇ ਨਾਮ ਸਹੀ ਲਿੱਖੋ ਜਾਂ ਨੀਚੇ ਦਿੱਤੇ ਗਏ ਫ਼ਾਰਮ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਇੱਕ ਨਵਾਂ ਖਾਤਾ ਬਣਾ ਲਓ.',
+'wrongpassword' => 'ਦਿੱਤਾ ਗਿਆ ਪਾਸਵਰਡ ਗਲਤ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਦੋਬਾਰਾ ਯਤਨ ਕਰੋ',
+'mailmypassword' => 'ਮੈਨੂੰ ਇੱਕ ਨਵਾਂ ਪਾਸਵਰਡ ਈ-ਮੇਲ ਰਾਹੀਂ ਭੇਜ ਦਿਓ',
+'passwordremindertitle' => '{{SITENAME}} ਵਲੋਂ ਪਾਸਵਰਡ ਯਾਦਦਹਾਣੀ-ਪੱਤ੍ਰ (Password Reminder from {{SITENAME}})',
+'passwordremindertext' => 'ਕਿਸੇ ਨੇ (ਸ਼ਾਯਿਦ ਤੁਸੀਂ ਹੀ, $1 IP address ਤੋਂ)
+ {{SITENAME}} ਲਾਗ ਇਨ ਦਾ ਨਵਾਂ ਪਾਸਵਰਡ ਭੇਜਣ ਦੀ ਮੰਗ ਕੀਤੀ ਸੀ.
+ਮੈਂਬਰ \'$1\' ਦਾ ਹੁਣ ਨਵਾਂ ਪਾਸਵਰਡ \'$3\' ਹੈ.
+ਕਿਰਪਾ ਕਰਕੇ {{SITENAME}} ਵਿੱਚ ਲਾਗ ਇਨ ਕਰਕੇ ਹੁਣੇ ਆਪਣਾ ਪਾਸਵਰਡ ਬਦਲ ਲਓ.\n<br /><br />
+Someone (probably you, from IP address $1)
+requested that we send you a new {{SITENAME}} login password.
+The password for user \'$2\' is now \'$3\'.
+You should log in and change your password now.',
+'noemail' => 'ਮੈਂਬਰ \'$1\' ਲਈ ਕੋਈ ਈ-ਮੇਲ ਅਡ੍ਰੈੱਸ ਨਹੀਂ ਹੈ',
+'passwordsent' => '\'$1\' ਮੈਂਬਰ ਦੇ ਈ-ਮੇਲ ਅਡ੍ਰੈੱਸ ਤੇ ਇੱਕ ਨਵਾਂ ਪਾਸਵਰਡ ਭੇਜ ਦਿੱਤਾ ਗਿਆ ਹੈ.
+ਪਾਸਵਰਡ ਮਿਲੱਣ ਤੋਂ ਬਾਅਦ ਕਿਰਪਾ ਲਾਗ ਇਨ ਜ਼ਰੂਰ ਕਰੋ.',
+'mailerror' => 'ਮੇਲ (mail) $1 ਭੇਜਣ ਵਿੱਚ ਸਮੱਸਿਆ ਆ ਗਈ ਹੈ',
+'acct_creation_throttle_hit' => 'ਮਾਫ਼ੀ ਚਾਹੁੰਦੇ ਹਾਂ, ਤੁਸੀਂ ਪਿਹਲਾਂ ਹੀ $1 ਖਾਤੇ ਬਣਾ ਚੁੱਕੇ ਹੋ. ਤੁਸੀਂ ਇਸਤੋਂ ਜ਼ਿਆਦਾ ਨਹੀਂ ਬਣਾ ਸੱਕਦੇ ਹੋ',
+
+# Edit page toolbar
+'bold_sample' =>'ਬੋਲਡ ਅੱਖਰ',
+'bold_tip' =>'ਬੋਲਡ ਅੱਖਰ',
+'italic_sample' =>'ਇਟੈਲਿਕ ਅੱਖਰ',
+'italic_tip' =>'ਇਟੈਲਿਕ ਅੱਖਰ',
+'link_sample' =>'Link title',
+'link_tip' =>'ਅੰਦਰੂਨੀ ਕੜੀ',
+'extlink_tip' =>'ਬਾਹਰੀ ਕੜੀ (ਪਹਿਲਾਂ http:// ਲਗਾਉਣਾ ਯਾਦ ਰੱਖੋ)',
+'math_tip' =>'ਗਣਿਤ ਦਾ ਫਾਰਮੂਲਾ (LaTeX)',
+
+# Edit pages
+#
+'summary' => 'ਸਾਰ',
+'subject' => 'ਵਿਸ਼ਾ',
+'minoredit' => 'ਇਹ ਇਕ ਮਾਮੂਲੀ ਬਦਲਾਵ ਹੈ',
+'watchthis' => 'ਇਸ ਪੰਨੇ ਤੇ ਨਜ਼ਰ ਰਖੋ',
+'savearticle' => 'ਪੱਕਾ ਕਰ ਦਿਓ',
+'preview' => 'ਝਲਕ',
+'showpreview' => 'ਝਲਕ ਦਿਖਾਓ',
+'blockedtitle' => 'ਮੈਂਬਰ ਤੇ ਰੋਕ ਲਗਾ ਦਿੱਤੀ ਗਈ ਹੈ',
+'blockedtext' => 'ਤੁਹਾਡੇ ਮੈਂਬਰ ਨਾਮ ਜਾਂ IP address ਉੱਤੇ $1 ਦੁਆਰਾ ਰੋਕ ਲਗਾ ਦਿੱਤੀ ਗਈ ਹੈ.
+ਕਾਰਣ ਹੈ:<br />\'\'$2\'\'<p>ਇਸ ਰੋਕ ਦੇ ਬਾਰੇ ਵਿੱਚ ਚਰਚਾ ਕਰਨ ਲਈ
+$1 ਜਾਂ ਕਿਸੇ ਵੀ ਹੋਰ [[{{ns:4}}:ਪ੍ਰਸ਼ਾਸਕ]]
+ਨੂੰ ਸੰਪੰਰਕ ਕਰੋ. ਧਿਆਨ ਦਿਓ ਕਿ ਤੁਸੀਂ ਓਹਨਾਂ ਚਿਰ \'ਇਸ ਮੈਂਬਰ ਨੂੰ ਈ-ਮੇਲ ਕਰੋ\' ਸੁਵੀਧਾ ਦੀ ਵਰਤੋਂ
+ਨਹੀਂ ਕਰ ਸਕਦੇ, ਜਦੋਂ ਤੱਕ ਕਿ ਤੁਸੀਂ [[Special:Preferences|preferences]]
+ਵਿੱਚ ਆਪਣਾ ਈ-ਮੇਲ ਨਹੀਂ ਦਿੰਦੇ. ਤੁਹਾਡਾ IP address ਹੈ $3.
+ਕਿਰਪਾ ਕਰਕੇ ਪੁਛ-ਗਿੱਛ ਕਰਦੇ ਵਕਤ ਇਸ IP address ਦੀ ਵਰਤੋਂ ਜ਼ਰੂਰ ਕਰੋ.',
+'whitelistedittitle' => 'ਬਦਲਾਵ ਕਰਨ ਲਈ ਲਾੱਗ-ਇਨ ਹੋਣਾ ਜ਼ਰੂਰੀ ਹੈ',
+'whitelistedittext' => 'ਤੁਹਾਨੂੰ ਲੇਖਾਂ ਵਿੱਚ ਬਦਲਾਵ ਕਰਨ ਲਈ [[Special:Userlogin|login]] ਕਰਨਾ ਜ਼ਰੂਰੀ ਹੈ',
+'whitelistreadtitle' => 'ਪੜ੍ਹਨ ਲਈ ਲਾੱਗ-ਇਨ ਕਰਨਾ ਜ਼ਰੂਰੀ ਹੈ',
+'whitelistreadtext' => 'ਤੁਹਾਨੂੰ ਲੇਖ ਪੜਨ ਲਈ [[Special:Userlogin|login]] ਕਰਨਾ ਜ਼ਰੂਰੀ ਹੈ',
+'whitelistacctitle' => 'ਤੁਹਾਨੂੰ ਖਾਤਾ ਬਨਾਓਣ ਦੀ ਅਨੁਮਤੀ ਨਹੀਂ ਹੈ',
+'whitelistacctext' => 'ਇਸ ਵਿਕਿ ਵਿੱਚ ਖਾਤਾ ਬਨਾਓਣ ਲਈ ਤੁਹਾਨੂੰ [[Special:Userlogin|login]] ਕਰਨਾ ਜ਼ਰੂਰੀ ਹੈ ਅਤੇ ਨਾਲ ਹੀ ਉਪ੍ਯੁਕਤ ਅਨੁਮਤੀ ਵੀ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ',
+'loginreqtitle' => 'ਲਾਗ ਇਨ ਜ਼ਰੂਰੀ ਹੈ',
+'loginreqpagetext' => 'ਬਾਕੀ ਦੇ ਲੇਖ ਵੇਖਣ ਲਈ $1 ਕਰਨਾ ਜ਼ਰੂਰੀ ਹੈ',
+'accmailtitle' => 'ਪਾਸਵਰਡ ਭੇਜ ਦਿੱਤਾ ਗਿਆ ਹੈ',
+'accmailtext' => '\'$1\' ਦਾ ਪਾਸਵਰਡ $2 ਨੂੰ ਭੇਜ ਦਿੱਤਾ ਗਿਆ ਹੈ',
+'newarticle' => '(ਨਵਾਂ ਲੇਖ)',
+'newarticletext' => '
+ਤੁਸੀਂ ਅਜੇਹੇ ਪੰਨੇ ਤੇ ਪੁੱਜ ਗਏ ਹੋ ਜੋ ਅਜੇ ਲਿੱਖਿਆ ਨਹੀਂ ਗਿਆ ਹੈ.
+ਜੇ ਤੁਸੀਂ ਇਸ ਪੰਨੇ ਨੂੰ ਬਨਾਣਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਹੇਠਾਂ ਦਿੱਤੀ
+ਥਾਂ ਵਿੱਚ ਲਿੱਖਣਾ ਸ਼ੁਰੂ ਕਰ ਦਿਓ(ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਵੇਖੋ [[Project:Help|help page]]).
+ਜੇ ਤੁਸੀਂ ਗਲਤੀ ਨਾਲ ਇੱਥੇ ਆ ਗਏ ਹੋ, ਤਾਂ ਆਪਣੇ browser ਦਾ \'\'\'back\'\'\' button ਦਬਾਓ',
+'noarticletext' => '(ਅਜੇ ਇਹ ਪੰਨਾ ਖਾਲੀ ਹੈ)',
+'usercssjsyoucanpreview' => '<strong>ਨਸੀਹਤ:</strong>CSS/JS ਵਿੱਚ ਕੀਤੇ ਗਏ ਬਦਲਾਵ ਨੂੰ ਪੱਕਾ ਕਰਨ ਤੋਂ ਪਿਹਲਾਂ, \'ਝਲਕ ਦਿਖਾਓ\' button ਦਾ ਇਸਤੇਮਾਲ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ',
+'usercsspreview' => '\'\'\'ਯਾਦ ਰੱਖੋ ਕਿ ਤੁਸੀਂ ਆਪਣੀ CSS ਦੀ ਸਿਰਫ਼ ਝਲਕ ਵੇਖ ਰਹੇ ਹੋ, ਅਜੇ ਇਸਨੂੰ ਪੱਕਾ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ!\'\'\'',
+'userjspreview' => '\'\'\'ਯਾਦ ਰੱਖੋ ਕਿ ਤੁਸੀਂ ਆਪਣੀ javascript ਦੀ ਸਿਰਫ਼ ਝਲਕ ਵੇਖ ਰਹੇ ਹੋ, ਅਜੇ ਇਸਨੂੰ ਪੱਕਾ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ!\'\'\'',
+'updated' => '(ਅੱਪਡੇਟ (update) ਹੋ ਗਿਆ ਹੈ)',
+'note' => '<strong>ਧਿਆਨ ਦਿਓ:</strong>',
+'previewnote' => 'ਯਾਦ ਰੱਖੋ ਕਿ ਇਹ ਸਿਰਫ਼ ਇਕ ਝਲਕ ਹੈ, ਅਜੇ ਇਸਨੂੰ ਪੱਕਾ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ!',
+'editing' => 'ਬਦਲ ਰਹੇ ਹਾਂ: $1',
+'editinguser' => 'ਬਦਲ ਰਹੇ ਹਾਂ: $1',
+'editconflict' => 'ਬਦਲਾਵ ਮੱਤਭੇਦ: $1',
+'yourdiff' => 'ਅੰਤਰ (Differences)',
+
+# History pages
+#
+'revhistory' => 'ਸੋਧ ਦਾ ਇਤਿਹਾਸ',
+'nohistory' => 'ਇਸ ਪੰਨੇ ਲਈ ਤਬਦੀਲ਼ੀ ਦਾ ਕੋਈ ੲਤਿਹਾਸ ਨਹੀਂ ਹੈ.',
+'revnotfound' => 'ਸੋਧ ਨਹੀਂ ਮਿਲੀ',
+'loadhist' => 'ਪੰਨੇ ਦਾ ਇਤਿਹਾਸ ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ',
+'currentrev' => 'ਮੌਜੂਦਾ ਸੰਸ਼ੋਧਨ',
+'cur' => 'ਮੌਜੂਦਾ',
+'next' => 'ਅਗਲਾ',
+'last' => 'ਪਿਛਲਾ',
+'orig' => 'ਅਸਲ',
+
+# Diffs
+#
+'editcurrent' => 'ਇਸ ਪੰਨੇ ਦੇ ਮੌਜੂਦਾ ਰੁਪਾਂਤਰ ਵਿਚ ਤਬਦੀਲੀ ਕਰੋ',
+'selectnewerversionfordiff' => 'ਆਪਸ ਵਿਚ ਮਿਲਾਉਣ ਲਈ ਨਵਾਂ ਰੁਪਾਂਤਰ ਚੁਣੋ',
+'selectolderversionfordiff' => 'ਆਪਸ ਵਿਚ ਮਿਲਾਉਣ ਲਈ ਪੁਰਾਣਾ ਰੁਪਾਂਤਰ ਚੁਣੋ',
+'compareselectedversions' => 'ਚੁਣੇ ਹੋਏ ਰਪਾਂਤਰਾਂ ਨੂੰ ਆਪਸ ਵਿਚ ਮਿਲਾਓ',
+
+# Search results
+#
+'searchdisabled' => '<p>ਮੁਆਫ਼ੀ ਚਾਹੁੰਦੇ ਹਾਂ! Full text search, performance reasons ਕਰਕੇ ਕੁੱਝ ਦੇਰ ਲਈ ਬੰਦ ਕਰ ਦਿੱਤੀ ਗਈ ਹੈ. ਇਸ ਦਰਮਿਆਨ, ਚਾਹੋ ਤਾਂ ਤੁਸੀਂ Google search ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਹੋ, ਜੋ ਕਿ ਹੋ ਸਕਦਾ ਹੈ ਪੂਰਾਣੀ ਹੋ ਚੁੱਕੀ ਹੋਵੇ</p>',
+
+# Recent changes
+#
+'changes' => 'ਬਦਲਾਵ',
+'recentchanges' => 'ਹਾਲ ਵਿੱਚ ਹੋਏ ਬਦਲਾਵ',
+'rcnote' => 'ਪਿੱਛਲੇ <strong>$2</strong> ਦਿਨਾਂ ਵਿੱਚ ਹੋਏ <strong>$1</strong> ਬਦਲਾਵ:',
+'rclistfrom' => '$1 ਤੋਂ ਸ਼ੁਰੂ ਹੋਣ ਵਾਲੇ ਨਵੇਂ ਬਦਲਾਵ ਦਿਖਾਓ',
+'rclinks' => 'ਪਿੱਛਲੇ $2 ਦਿਨਾਂ ਵਿੱਚ ਹੋਏ $1 ਬਦਲਾਵ ਦਿਖਾਓ<br />$3',
+'hide' => 'ਛੁਪਾਓ',
+'show' => 'ਦਿਖਾਓ',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-watch' => 'ਇਸ ਪੰਨੇ ਨੂੰ ਆਪਣੀ watchlist ਵਿੱਚ ਜਮਾਂ ਕਰੋ[alt-w]',
+'tooltip-search' => 'ਇਸ ਵਿਕਿ ਵਿੱਚ ਲੱਭੋ [alt-f]',
+'tooltip-minoredit' => 'ਮਾਮੂਲੀ ਬਦਲਾਵ ਦੀ ਨਿਸ਼ਾਨੀ ਲਗਾਓ (Mark this as a minor edit) [alt-i]',
+'tooltip-save' => 'ਕੀਤੇ ਗਏ ਬਦਲਾਵ ਪੱਕੇ ਕਰੋ [alt-s]',
+'tooltip-preview' => 'ਕੀਤੇ ਗਏ ਬਦਲਾਵਾਂ ਦੀ ਝਲਕ ਵੇਖੋ, ਕਿਰਪਾ ਕਰਕੇ ਪੱਕਾ ਕਰਨ ਤੋਂ ਪਿਹਲਾਂ ਇਸਦੀ ਵਰਤੋਂ ਜ਼ਰੂਰ ਕਰੋ! [alt-p]',
+
+# Attribution
+
+'lastmodifiedatby' => 'ਇਹ ਪੰਨਾ ਅਖੀਰਲੀ ਵਾਰ $2, $1 ਨੂੰ $3 ਦੁਆਰਾ ਬਦਲਿਆ ਗਿਆ ਸੀ',
+'and' => 'ਅਤੇ',
+'othercontribs' => '$1 ਦੁਆਰਾ ਕੰਮ ਤੇ ਅਧਾਰਤ।',
+
+# Info page
+'infosubtitle' => 'ਪੰਨੇ ਸੰਬੰਧੀ ਸੂਚਨਾ',
+'numedits' => 'ਤਬਦੀਲੀਆਂ ਦੀ ਗਿਣਤੀ (ਲੇਖ ਵਿਚਾਲੇ):',
+'numtalkedits' => 'ਤਬਦੀਲੀਆਂ ਦੀ ਗਿਣਤੀ (ਚਰਚਾ-ਪੰਨੇ ਵਿਚਾਲੇ):',
+);
+
+
+?>
diff --git a/languages/messages/MessagesPl.php b/languages/messages/MessagesPl.php
new file mode 100644
index 000000000000..657d6a2d32e5
--- /dev/null
+++ b/languages/messages/MessagesPl.php
@@ -0,0 +1,1798 @@
+<?php
+/** Polish (Polski)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Specjalna',
+ NS_MAIN => '',
+ NS_TALK => 'Dyskusja',
+ NS_USER => 'Użytkownik',
+ NS_USER_TALK => 'Dyskusja_użytkownika',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Dyskusja_$1',
+ NS_IMAGE => 'Grafika',
+ NS_IMAGE_TALK => 'Dyskusja_grafiki',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Dyskusja_MediaWiki',
+ NS_TEMPLATE => 'Szablon',
+ NS_TEMPLATE_TALK => 'Dyskusja_szablonu',
+ NS_HELP => 'Pomoc',
+ NS_HELP_TALK => 'Dyskusja_pomocy',
+ NS_CATEGORY => 'Kategoria',
+ NS_CATEGORY_TALK => 'Dyskusja_kategorii'
+);
+
+$quickbarSettings = array(
+ 'Brak', 'Stały, z lewej', 'Stały, z prawej', 'Unoszący się, z lewej'
+);
+
+$skinNames = array(
+ 'standard' => 'Standardowa',
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'H:i, M j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'H:i, j M Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'H:i, Y M j',
+);
+
+$fallback8bitEncoding = 'iso-8859-2';
+$separatorTransformTable = array(
+ ',' => "\xc2\xa0", // @bug 2749
+ '.' => ','
+);
+$linkTrail = '/^([a-zęóąśłżźćńĘÓĄŚŁŻŹĆŃ]+)(.*)$/sDu';
+
+
+$messages = array(
+
+# User preference toggles
+'tog-underline' => 'Podkreślenie linków:',
+'tog-highlightbroken' => '<a href="" class="new">Podświetl</a> linki pustych stron (alternatywa: znak zapytania<a href="" class="internal">?</a>).',
+'tog-justify' => 'Wyrównuj tekst w akapitach do obu stron',
+'tog-hideminor' => 'Ukryj drobne zmiany w "Ostatnich zmianach"',
+'tog-extendwatchlist' => 'Rozszerzona lista obserwowanych',
+'tog-usenewrc' => 'Rozszerzenie ostatnich zmian (JavaScript)',
+'tog-numberheadings' => 'Automatyczna numeracja nagłówków',
+'tog-showtoolbar' => 'Pokaż pasek narzędzi (JavaScript)',
+'tog-editondblclick' => 'Podwójne kliknięcie rozpoczyna edycję (JavaScript)',
+'tog-editsection' => 'Możliwość edycji poszczególnych sekcji strony',
+'tog-editsectiononrightclick' => 'Kliknięcie prawym klawiszem na tytule sekcji<br />rozpoczyna jej edycję (JavaScript)',
+'tog-showtoc' => 'Pokaż spis treści (na stronach zawierających więcej niż 3 nagłówki)',
+'tog-rememberpassword' => 'Pamiętaj hasło między sesjami',
+'tog-editwidth' => 'Obszar edycji o pełnej szerokości',
+'tog-watchcreations' => 'Dodaj tworzone przeze mnie strony do obserwowanych',
+'tog-watchdefault' => 'Obserwuj strony, które będę edytować',
+'tog-minordefault' => 'Wszystkie zmiany zaznaczaj domyślnie jako drobne',
+'tog-previewontop' => 'Pokazuj podgląd przed obszarem edycji',
+'tog-previewonfirst' => 'Pokaż podgląd strony podczas pierwszej edycji',
+'tog-nocache' => 'Wyłącz pamięć podręczną',
+'tog-enotifwatchlistpages' => 'Wyślij e-mail kiedy obserwowana przeze mnie strona ulegnie zmianie',
+'tog-enotifusertalkpages' => 'Wyślij e-mail kiedy moja strona dyskusji ulegnie zmianie',
+'tog-enotifminoredits' => 'Wyślij e-mail także w przypadku drobnych zmian na stronach',
+'tog-enotifrevealaddr' => 'Ujawnij mój adres e-mail w zawiadomieniach',
+'tog-shownumberswatching' => 'Pokaż liczbę obserwujących użytkowników',
+'tog-fancysig' => 'Podpis bez automatycznego linku',
+'tog-externaleditor' => 'Domyślnie używaj zewnętrznego edytora',
+'tog-externaldiff' => 'Domyślnie używaj zewnętrznego programu pokazującego zmiany',
+'tog-showjumplinks' => 'Włącz odnośniki "skocz do"',
+'tog-uselivepreview' => 'Używaj dynamicznego podglądu (JavaScript) (eksperymentalna)',
+'tog-autopatrol' => 'Zaznacz moje edycje jako patrolowane',
+'tog-forceeditsummary' => 'Informuj o niewypełnieniu pola opisu zmian',
+'tog-watchlisthideown' => 'Ukryj moje edycje w obserwowanych',
+'tog-watchlisthidebots' => 'Ukryj edycje botów w obserwowanych',
+
+'underline-always' => 'Zawsze',
+'underline-never' => 'Nigdy',
+'underline-default' => 'Ustawienia przeglądarki',
+
+'skinpreview' => '(podgląd)',
+
+# dates
+'sunday' => 'niedziela',
+'monday' => 'poniedziałek',
+'tuesday' => 'wtorek',
+'wednesday' => 'środa',
+'thursday' => 'czwartek',
+'friday' => 'piątek',
+'saturday' => 'sobota',
+'sun' => 'Nie',
+'mon' => 'Pon',
+'tue' => 'Wto',
+'wed' => 'Śro',
+'thu' => 'Czw',
+'fri' => 'Pią',
+'sat' => 'Sob',
+'january' => 'styczeń',
+'february' => 'luty',
+'march' => 'marzec',
+'april' => 'kwiecień',
+'may_long' => 'maj',
+'june' => 'czerwiec',
+'july' => 'lipiec',
+'august' => 'sierpień',
+'september' => 'wrzesień',
+'october' => 'październik',
+'november' => 'listopad',
+'december' => 'grudzień',
+'january-gen' => 'stycznia',
+'february-gen' => 'lutego',
+'march-gen' => 'marca',
+'april-gen' => 'kwietnia',
+'may-gen' => 'maja',
+'june-gen' => 'czerwca',
+'july-gen' => 'lipca',
+'august-gen' => 'sierpnia',
+'september-gen' => 'września',
+'october-gen' => 'października',
+'november-gen' => 'listopada',
+'december-gen' => 'grudnia',
+'jan' => 'sty',
+'feb' => 'lut',
+'mar' => 'mar',
+'apr' => 'kwi',
+'may' => 'maj',
+'jun' => 'cze',
+'jul' => 'lip',
+'aug' => 'sie',
+'sep' => 'wrz',
+'oct' => 'paź',
+'nov' => 'lis',
+'dec' => 'gru',
+
+# Bits of text used by many pages:
+#
+'categories' => 'Kategorie',
+'pagecategories' => '{{PLURAL:$1|Kategoria|Kategorie}}',
+'category_header' => 'Artykuły w kategorii "$1"',
+'subcategories' => 'Podkategorie',
+
+'mainpage' => 'Strona główna',
+'mainpagetext' => "<big>'''Instalacja oprogramowania powiodła się.'''</big>",
+'mainpagedocfooter' => 'Zobacz [http://meta.wikimedia.org/wiki/Help:Contents przewodnik użytkownika] w celu uzyskania informacji o działaniu oprogramowania wiki.
+
+== Na początek ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Lista ustawień konfiguracyjnych]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Ogłoszenia o wydaniach MediaWiki]',
+
+'portal' => 'Portal użytkowników',
+'portal-url' => 'Project:Portal użytkowników',
+'about' => 'O serwisie',
+'aboutsite' => 'O serwisie {{SITENAME}}',
+'aboutpage' => 'Project:O serwisie',
+'article' => 'Artykuł',
+'help' => 'Pomoc',
+'helppage' => 'Project:Pomoc',
+'bugreports' => 'Raport o błędach',
+'bugreportspage' => 'Project:Błędy',
+'sitesupport' => 'Dary pieniężne',
+'sitesupport-url' => 'Project:Dary pieniężne',
+'faq' => 'FAQ',
+'edithelp' => 'Pomoc w edycji',
+'newwindow' => '(otwiera się w nowym oknie)',
+'edithelppage' => 'Project:Jak_edytować_stronę',
+'cancel' => 'Anuluj',
+'qbfind' => 'Znajdź',
+'qbbrowse' => 'Przeglądanie',
+'qbedit' => 'Edycja',
+'qbpageoptions' => 'Opcje strony',
+'qbpageinfo' => 'O stronie',
+'qbmyoptions' => 'Moje opcje',
+'qbspecialpages' => 'Strony specjalne',
+'moredotdotdot' => 'Więcej...',
+'mypage' => 'Moja strona',
+'mytalk' => 'Moja dyskusja',
+'anontalk' => 'Dyskusja tego IP',
+'navigation' => 'Nawigacja',
+
+# Metadata in edit box
+'metadata_help' => 'Metadane (zobacz [[{{ns:project}}:Metadane]]):',
+
+'currentevents' => 'Bieżące wydarzenia',
+'currentevents-url' => 'Bieżące wydarzenia',
+
+'disclaimers' => 'Informacje Prawne',
+'privacy' => 'Zasady ochrony prywatności',
+'privacypage' => '{{ns:Project}}:Zasady ochrony prywatności',
+'errorpagetitle' => 'Błąd',
+'returnto' => 'Wróć do strony $1.',
+'help' => 'Pomoc',
+'search' => 'Szukaj',
+'searchbutton' => 'Szukaj',
+'go' => 'Przejdź',
+'searcharticle' => 'Przejdź',
+'history' => 'Historia strony',
+'history_short' => 'Historia',
+'info_short' => 'Informacja',
+'printableversion' => 'Wersja do druku',
+'permalink' => 'Bezpośredni link',
+'print' => 'Drukuj',
+'edit' => 'Edytuj',
+'editthispage' => 'Edytuj tę stronę',
+'delete' => 'Usuń',
+'deletethispage' => 'Usuń tę stronę',
+'undelete_short' => 'Odtwórz {{PLURAL:$1|jedną wersję|$1 wersji}}',
+'protect' => 'Zabezpiecz',
+'protectthispage' => 'Zabezpiecz tę stronę',
+'unprotect' => 'Odbezpiecz',
+'unprotectthispage' => 'Odbezpiecz tę stronę',
+'newpage' => 'Nowa strona',
+'talkpage' => 'Dyskusja',
+'specialpage' => 'strona specjalna',
+'personaltools' => 'Osobiste',
+'postcomment' => 'Skomentuj',
+'articlepage' => 'Strona artykułu',
+'talk' => 'dyskusja',
+'views' => 'widok',
+'toolbox' => 'Narzędzia',
+'userpage' => 'Strona użytkownika',
+'projectpage' => 'Strona projektu',
+'imagepage' => 'Strona grafiki',
+'mediawikipage' => 'Strona komunikatu',
+'templatepage' => 'Strona szablonu',
+'viewhelppage' => 'Strona pomocy',
+'categorypage' => 'Strona kategorii',
+'viewtalkpage' => 'Strona dyskusji',
+'otherlanguages' => 'W innych językach',
+'redirectedfrom' => '(Przekierowano z $1)',
+'autoredircomment' => 'Przekierowanie do [[$1]]',
+'redirectpagesub' => 'Strona przekierowująca',
+'lastmodifiedat' => 'Tę stronę ostatnio zmodyfikowano $2, $1.',
+'viewcount' => 'Tę stronę obejrzano {{plural:$1|jeden raz|$1 razy}}.',
+'copyright' => 'Tekst udostępniany na licencji $1.',
+'protectedpage' => 'Strona zabezpieczona',
+'jumpto' => 'Skocz do:',
+'jumptonavigation' => 'nawigacji',
+'jumptosearch' => 'wyszukiwania',
+
+'badaccess' => 'Nieprawidłowe uprawnienia',
+'badaccess-group0' => 'Nie masz uprawnień wymaganych do wykonania tej operacji.',
+'badaccess-group1' => 'Wykonywanie tej operacji zostało ograniczone do użytkowników w grupie $1.',
+'badaccess-group2' => 'Wykonywanie tej operacji zostało ograniczone do użytkowników w jednej z grup $1.',
+'badaccess-groups' => 'Wykonywanie tej operacji zostało ograniczone do użytkowników w jednej z grup $1.',
+
+'versionrequired' => 'Wymagana MediaWiki w wersji $1',
+'versionrequiredtext' => 'Wymagana jest MediaWiki w wersji $1 aby skorzystać z tej strony . Zobacz [[Special:Version]]',
+
+'retrievedfrom' => 'Źródło: "$1"',
+'youhavenewmessages' => 'Masz $1 ($2).',
+'newmessageslink' => 'nowe wiadomości',
+'newmessagesdifflink' => 'różnica z poprzednią wersją',
+'editsection' => 'edytuj',
+'editold' => 'edytuj',
+'editsectionhint' => 'Edytuj sekcję: $1',
+'toc' => 'Spis treści',
+'showtoc' => 'pokaż',
+'hidetoc' => 'ukryj',
+'thisisdeleted' => 'Pokaż/odtwórz $1',
+'viewdeleted' => 'Zobacz $1',
+'restorelink' => '{{PLURAL:$1|jedną skasowaną wersję|skasowane wersje (w sumie $1)}}',
+'feedlinks' => 'Kanały:',
+'feed-invalid' => 'Niewłaściwy typ kanału informacyjnego.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Artykuł',
+'nstab-user' => 'Strona użytkownika',
+'nstab-media' => 'Media',
+'nstab-special' => 'Strona specjalna',
+'nstab-project' => 'Strona projektu',
+'nstab-image' => 'Plik',
+'nstab-mediawiki' => 'Komunikat',
+'nstab-template' => 'Szablon',
+'nstab-help' => 'Strona pomocy',
+'nstab-category' => 'Kategoria',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Nie ma takiej operacji',
+'nosuchactiontext' => 'Oprogramowanie nie rozpoznaje
+operacji takiej jak podana w URL',
+'nosuchspecialpage' => 'Nie ma takiej strony specjalnej',
+'nospecialpagetext' => 'Oprogramowanie nie rozpoznaje takiej specjalnej strony. Listę stron specjalnych znajdziesz na [[{{ns:Special}}:Specialpages]]',
+
+# General errors
+#
+'error' => 'Błąd',
+'databaseerror' => 'Błąd bazy danych',
+'dberrortext' => 'Wystąpił błąd składni w zapytaniu do bazy danych.
+Ostatnie, nieudane zapytanie to:
+<blockquote><tt>$1</tt></blockquote>
+wysłane przez funkcję "<tt>$2</tt>".
+MySQL zgłosił błąd "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Wystąpił błąd składni w zapytaniu do bazy danych.
+Ostatnie, nieudane zapytanie to:
+"$1"
+wywołane zostało przez funkcję "$2".
+MySQL zgłosił błąd "$3: $4"',
+'noconnect' => 'Przepraszamy! {{SITENAME}} ma chwilowo problemy techniczne. Nie można połączyć się z serwerem bazy danych.<br />$1',
+'nodb' => 'Nie można odnaleźć bazy danych $1',
+'cachederror' => 'Poniższy tekst strony jest kopią znajdującą się w pamięci podręcznej i może być już nieaktualny.',
+'laggedslavemode' => 'Uwaga: Ta strona może nie zawierać najnowszych aktualizacji.',
+'readonly' => 'Baza danych jest zablokowana',
+'enterlockreason' => 'Podaj powód zablokowania bazy oraz szacunkowy czas jej odblokowania',
+'readonlytext' => 'Baza danych jest w tej chwili zablokowana
+- nie można wprowadzać nowych artykułów ani modyfikować istniejących. Powodem
+są prawdopodobnie czynności administracyjne. Po ich zakończeniu przywrócona
+zostanie pełna funkcjonalność bazy.
+Administrator, który zablokował bazę, podał następujące wyjaśnienie:<br /> $1',
+'missingarticle' => 'Oprogramowanie nie odnalazło tekstu strony, która powinna się znajdować w bazie, tzn. strony "$1".
+
+Zazwyczaj zdarza się to, gdy wybrane zostanie łącze do skasowanej strony, np. w starszej wersji innej ze stron.
+
+Inne okoliczności świadczyłyby o tym, że w oprogramowaniu jest błąd. W takim przypadku zgłoś, proszę, ten fakt
+administratorowi podając także powyższy adres.',
+'readonly_lag' => 'Baza danych została automatycznie zablokowana na czas potrzebny na synchronizację zmian między serwerem głównym i serwerami pośredniczącymi.',
+'internalerror' => 'Błąd wewnętrzny',
+'filecopyerror' => 'Nie można skopiować pliku "$1" do "$2".',
+'filerenameerror' => 'Nie można zmienić nazwy pliku "$1" na "$2".',
+'filedeleteerror' => 'Nie można skasować pliku "$1".',
+'filenotfound' => 'Nie można znaleźć pliku "$1".',
+'unexpected' => 'Niespodziewana wartość: "$1"="$2".',
+'formerror' => 'Błąd: nie można wysłać formularza',
+'badarticleerror' => 'Dla tej strony ta operacja nie może być wykonana.',
+'cannotdelete' => 'Nie można skasować podanej strony lub obrazka.',
+'badtitle' => 'Niepoprawny tytuł',
+'badtitletext' => 'Podano niepoprawny tytuł strony. Prawdopodobnie zawiera znaki, których użycie jest zabronione lub jest pusty.',
+'perfdisabled' => 'Przepraszamy! By odciążyć serwer w godzinach szczytu czasowo zablokowaliśmy wykonanie tej czynności.',
+'perfcached' => 'Poniższe dane są kopią z pamięci podręcznej i mogą nie być do końca aktualne.',
+'perfcachedts' => 'Poniższe dane są kopią z pamięci podręcznej i zostały uaktualnione $1.',
+'wrong_wfQuery_params' => 'Nieprawidłowe parametry przekazane do wfQuery()<br />
+Funkcja: $1<br />
+Zapytanie: $2',
+'viewsource' => 'Tekst źródłowy',
+'viewsourcefor' => 'dla $1',
+'protectedtext' => 'Wyłączono możliwość edycji tej strony. Istnieje kilka powodów
+dla których jest to robione - zobacz [[{{ns:Project}}:Strona_zabezpieczona]].
+
+Tekst źródłowy strony można w dalszym ciągu podejrzeć i skopiować.',
+'protectedinterface' => 'Ta strona dostarcza tekst interfejsu do oprogramowania i została zablokowana możliwość jej edycji.',
+'editinginterface' => "'''Ostrzeżenie:''' Edytujesz stronę, która jest użyta w celu dostarczenia tekstu interfejsu do oprogramowania. Zmiany na tej stronie zmienią wygląd interfejsu użytkownika dla innych użytkowników.",
+'sqlhidden' => '(ukryto zapytanie SQL)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Wylogowanie użytkownika',
+'logouttext' => '<strong>Wylogowano Cię</strong>.<br />Możesz kontynuować pracę jako niezarejestrowany użytkownik albo zalogować się ponownie jako ten sam lub inny użytkownik.',
+
+'welcomecreation' => '== Witaj, $1! ==
+
+Właśnie utworzyliśmy dla Ciebie konto. Nie zapomnij dostosować [[{{ns:Special}}:Preferences|preferencji]].',
+
+'loginpagetitle' => 'Logowanie',
+'yourname' => 'Login',
+'yourpassword' => 'Hasło',
+'yourpasswordagain' => 'Powtórz hasło',
+'remembermypassword' => 'Zapamiętaj moje hasło na tym komputerze',
+'yourdomainname' => 'Twoja domena',
+'externaldberror' => 'Wystąpił błąd zewnętrznej bazy autentyfikacyjnej lub nie posiadasz uprawnień koniecznych do aktualizacji zewnętrznego konta.',
+'loginproblem' => '<b>Wystąpił problem przy próbie zalogowania się.</b><br />Spróbuj ponownie!',
+'alreadyloggedin' => '<strong>$1, jesteś już zalogowany!</strong><br />',
+
+'login' => 'Zaloguj mnie',
+'loginprompt' => 'Musisz mieć włączone cookies by móc się zalogować.',
+'userlogin' => 'Logowanie / rejestracja',
+'logout' => 'Wyloguj mnie',
+'userlogout' => 'Wylogowanie',
+'notloggedin' => 'Brak logowania',
+'nologin' => 'Nie masz konta? $1.',
+'nologinlink' => 'Zarejestruj się',
+'createaccount' => 'Załóż nowe konto',
+'gotaccount' => 'Masz już konto? $1.',
+'gotaccountlink' => 'Zaloguj się',
+'createaccountmail' => 'przez e-mail',
+'badretype' => 'Wprowadzone hasła różnią się między sobą.',
+'userexists' => 'Wybrana przez Ciebie nazwa użytkownika jest już zajęta. Wybierz, proszę, inną.',
+'youremail' => 'Twój E-mail *',
+'username' => 'Nazwa użytkownika:',
+'uid' => 'ID użytkownika:',
+'yourrealname' => 'Imię i nazwisko *',
+'yourlanguage' => 'Język interfejsu',
+'yourvariant' => 'Wariant',
+'yournick' => 'Twój podpis',
+'badsig' => 'Błędny podpis, sprawdź tagi HTML.',
+'prefs-help-email-enotif' => 'Ten adres jest także używany do wysyłania powiadomień, jeśli włączysz tę opcję.',
+'prefs-help-realname' => '* Imię i nazwisko (opcjonalnie): jeśli zdecydujesz się je podać, zostaną użyte, aby zapewnić Twojej pracy atrybucję.',
+'loginerror' => 'Błąd logowania',
+'prefs-help-email' => '* E-mail (opcjonalnie): Podanie e-maila pozwala innym skontaktować się z tobą za pośrednictwem twojej strony użytkownika
+lub twojej strony dyskusji bez potrzeby ujawniania twoich danych identyfikacyjnych.',
+'nocookiesnew' => 'Konto użytkownika zostało utworzone, ale nie jesteś zalogowany. {{SITENAME}} używa ciasteczek do logowania. Masz wyłączone ciasteczka. Żeby się zalogować odblokuj ciasteczka i podaj nazwę i hasło swojego konta.',
+'nocookieslogin' => '{{SITENAME}} używa ciasteczek żeby zalogować użytkownika. Masz zablokowaną obsługę ciasteczek. Spróbuj ponownie po ich odblokowaniu.',
+'noname' => 'To nie jest poprawna nazwa użytkownika.',
+'loginsuccesstitle' => 'Udane logowanie',
+'loginsuccess' => 'Zalogowano Cię do serwisu {{SITENAME}} jako "$1".',
+'nosuchuser' => 'Nie ma użytkownika nazywającego się "$1". Sprawdź pisownię lub użyj poniższego formularza by utworzyć nowe konto.',
+'nosuchusershort' => 'Nie ma użytkownika nazywającego się "$1".',
+'nouserspecified' => 'Musisz podać nazwę użytkownika.',
+'wrongpassword' => 'Podane przez Ciebie hasło jest nieprawidłowe. Spróbuj jeszcze raz.',
+'wrongpasswordempty' => 'Wprowadzone hasło jest puste. Spróbuj ponownie.',
+'mailmypassword' => 'Wyślij mi nowe hasło',
+'passwordremindertitle' => 'Przypomnienie hasła w serwisie {{SITENAME}}',
+'passwordremindertext' => 'Ktoś (prawdopodobnie Ty, spod adresu $1)
+poprosił od nas o wysłanie nowego hasła dostępu do serwisu
+{{SITENAME}} ($4).
+Aktualne hasło dla użytkownika "$2" to "$3".
+Najlepiej będzie jak zalogujesz się teraz i od razu zmienisz hasło.',
+'noemail' => 'W bazie nie ma adresu e-mailowego dla użytkownika "$1".',
+'passwordsent' => 'Nowe hasło zostało wysłane na adres e-mailowy użytkownika "$1". Po otrzymaniu go zaloguj się ponownie.',
+'eauthentsent' => 'Potwierdzenie zostało wysłane na adres e-mail.
+Nim jakiekolwiek wiadomości zostaną wysłane na ten adres, należy wypełnić zawarte w nim instrukcje, by potwierdzić Twoją własność e-maila.',
+'mailerror' => 'Przy wysyłaniu e-maila nastąpił błąd: $1',
+'acct_creation_throttle_hit' => 'Przykro nam, założyłeś/aś już $1 kont(a). Nie możesz założyć kolejnego.',
+'emailauthenticated' => 'Twój adres email został uwierzytelniony $1.',
+'emailnotauthenticated' => 'Twój adres e-mail nie jest potwierdzony. Poniższe funkcje poczty nie będą działały.',
+'noemailprefs' => 'Musisz podać adres e-mail, aby te funkcje działały.',
+'emailconfirmlink' => 'Potwierdź swój adres e-mail',
+'invalidemailaddress' => 'E-mail nie zostanie zaakceptowany: jego format nie spełnia formalnych wymagań. Proszę wpisać poprawny adres email lub wyczyścić pole.',
+'accountcreated' => 'Utworzono konto',
+'accountcreatedtext' => 'Konto dla $1 zostało utworzone.',
+
+# Edit page toolbar
+'bold_sample' => 'Tekst wytłuszczony',
+'bold_tip' => 'Tekst wytłuszczony',
+'italic_sample' => 'Tekst pochylony',
+'italic_tip' => 'Tekst pochylony',
+'link_sample' => 'Tytuł linku',
+'link_tip' => 'Link wewnętrzny',
+'extlink_sample' => 'http://www.przyklad.pl tytuł strony',
+'extlink_tip' => 'Link zewnętrzny (pamiętaj o prefiksie http:// )',
+'headline_sample' => 'Tekst nagłówka',
+'headline_tip' => 'Nagłówek 2. poziomu',
+'math_sample' => 'W tym miejscu wprowadź wzór',
+'math_tip' => 'Wzór matematyczny (LaTeX)',
+'nowiki_sample' => 'Wstaw tu tekst niesformatowany',
+'nowiki_tip' => 'Zignoruj formatowanie wiki',
+'image_sample' => 'Przyklad.jpg',
+'image_tip' => 'Obrazek osadzony',
+'media_sample' => 'Przyklad.ogg',
+'media_tip' => 'Link do pliku',
+'sig_tip' => 'Twój podpis wraz z datą i czasem',
+'hr_tip' => 'Pozioma linia (używaj oszczędnie)',
+
+# Edit pages
+#
+'summary' => 'Opis zmian',
+'subject' => 'Temat/nagłówek',
+'minoredit' => 'To jest drobna zmiana',
+'watchthis' => 'Obserwuj tę stronę',
+'savearticle' => 'Zapisz',
+'preview' => 'Podgląd',
+'showpreview' => 'Podgląd',
+'showlivepreview' => 'Dynamiczny podgląd',
+'showdiff' => 'Podgląd zmian',
+'anoneditwarning' => 'Nie jesteś zalogowany. Twój adres IP będzie zapisany w historii edycji strony.',
+'missingsummary' => "'''Przypomnienie:''' Nie wprowadziłeś opisu zmian. Jeżeli nie chcesz go wprowadzać naciśnij przycisk \"Zapisz\" jeszcze raz.",
+'missingcommenttext' => 'Wprowadź komentarz poniżej.',
+'blockedtitle' => 'Użytkownik jest zablokowany',
+'blockedtext' => "'''Twoje konto lub adres IP zostały zablokowane.'''
+
+Blokada została nałożona przez $1. Podany powód to: ''$2''.
+
+W celu wyjaśnienia sprawy zablokowania możesz się skontaktować z $1 lub innym [[{{ns:Project}}:Administratorzy|administratorem]].
+
+Twój adres IP to $3.",
+'whitelistedittitle' => 'Przed edycją musisz się zalogować',
+'whitelistedittext' => 'Musisz $1 żeby móc edytować artykuły.',
+'whitelistreadtitle' => 'Przed przeczytaniem musisz się zalogować',
+'whitelistreadtext' => 'Musisz się [[{{ns:Special}}:Userlogin|zalogować]] żeby czytać strony.',
+'whitelistacctitle' => 'Nie jesteś dopuszczony do utworzenia konta',
+'whitelistacctext' => 'Aby móc zakładać konta na tej Wiki musisz [[{{ns:Special}}:Userlogin|zalogować się]] i mieć przyznane specjalne prawa.',
+'confirmedittitle' => 'Wymagane potwierdzenie e-maila by móc edytować',
+'confirmedittext' => 'Musisz podać i potwierdzić swój e-mail by móc edytować. Możesz to zrobić w [[{{ns:Special}}:Preferences|swoich ustawieniach]].',
+'loginreqtitle' => 'Musisz się zalogować',
+'loginreqlink' => 'zaloguj się',
+'loginreqpagetext' => 'Musisz $1 żeby móc przeglądać inne strony.',
+'accmailtitle' => 'Hasło wysłane.',
+'accmailtext' => 'Hasło dla użytkownika "$1" zostało wysłane pod adres $2.',
+'newarticle' => '(Nowy)',
+'newarticletext' => "Nie ma jeszcze artykułu o tym tytule. W poniższym polu można wpisać pierwszy jego fragment. Jeśli nie to było Twoim zamiarem, wciśnij po prostu ''Wstecz''.",
+'anontalkpagetext' => "---- ''To jest strona dyskusyjna dla użytkowników anonimowych - takich, którzy nie mają jeszcze swojego konta lub nie chcą go w tej chwili używać. By ich identyfikować używamy numerów IP. Jeśli jesteś anonimowym użytkownikiem i wydaje Ci się, że zamieszczone tu komentarze nie są skierowane do Ciebie, [[{{ns:Special}}:Userlogin|utwórz proszę konto albo zaloguj się]] - dzięki temu unikniesz w przyszłości podobnych nieporozumień.''",
+'noarticletext' => 'Nie ma jeszcze artykułu o tym tytule. Możesz [{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} utworzyć artykuł {{FULLPAGENAME}}] lub [[{{ns:Special}}:Search/{{FULLPAGENAME}}|poszukać {{FULLPAGENAME}} w innych artykułach]].',
+'clearyourcache' => "'''Uwaga:''' po zapisaniu zmian musisz zaktualizować pamięć podręczną (cache) przeglądarki: '''Mozilla / Firefox:''' kliknij ''Reload'' (lub ''Ctrl-R''), '''IE / Opera:''' ''Ctrl-F5'', '''Safari:''' ''Cmd-R'', '''Konqueror''' ''Ctrl-R''.",
+'usercssjsyoucanpreview' => '<strong>Wskazówka:</strong> Użyj przycisku "Podgląd", aby przetestować Twój nowy arkusz stylów CSS lub kod JavaScript przed jego zapisaniem.',
+'usercsspreview' => "'''Pamiętaj, że to na razie tylko podgląd Twojego arkusza stylów - nic jeszcze nie zostało zapisane!'''",
+'userjspreview' => "'''Pamiętaj, że to na razie tylko podgląd Twojego JavaScriptu - nic jeszcze nie zostało zapisane!'''",
+'userinvalidcssjstitle' => "'''Uwaga:''' Nie ma skórki o nazwie \"$1\". Pamiętaj, że strony użytkownika zawierające CSS i JavaScript powinny zaczynać się małą literą, np. User:Foo/monobook.css.",
+'updated' => '(Zmodyfikowano)',
+'note' => '<strong>Uwaga:</strong>',
+'previewnote' => '<strong>To jest tylko podgląd - artykuł nie został jeszcze zapisany!</strong>',
+'session_fail_preview' => '<strong>Przepraszamy! Serwer nie może przetworzyć tej edycji z powodu utraty danych sesji. Spróbuj jeszcze raz. Jeśli to nie pomoże - wyloguj się i zaloguj ponownie.</strong>',
+'previewconflict' => 'Wersja podglądana odnosi się do tekstu z górnego pola edycji. Tak będzie wyglądać strona jeśli zdecydujesz się ją zapisać.',
+'importing' => 'Importowanie $1',
+'editing' => 'Edytujesz "$1"',
+'editinguser' => 'Edytujesz "$1"',
+'editingsection' => 'Edytujesz "$1" (fragment)',
+'editingcomment' => 'Edytujesz "$1" (komentarz)',
+'editconflict' => 'Konflikt edycji: $1',
+'explainconflict' => 'Ktoś zdążył wprowadzić swoją wersję artykułu w trakcie Twojej edycji.
+Górne pole edycji zawiera tekst strony aktualnie zapisany w bazie danych.
+Twoje zmiany znajdują się w dolnym polu edycji.
+By wprowadzić swoje zmiany musisz zmodyfikować tekst z górnego pola.
+<b>Tylko</b> tekst z górnego pola będzie zapisany w bazie gdy wciśniesz "Zapisz".<br />',
+'yourtext' => 'Twój tekst',
+'storedversion' => 'Zapisana wersja',
+'nonunicodebrowser' => "<strong>Uwaga! Twoja przeglądarka nie umie poprawnie rozpoznawać kodowania UTF-8 (Unicode). Z tego powodu wszystkie znaki, których Twoja przeglądarka nie jest w stanie rozpoznać, zostały zastąpione ich kodami heksadecymalnymi.</strong>",
+'editingold' => "<strong>Ostrzeżenie: Edytujesz inną niż bieżąca wersję tej strony. Jeśli zapiszesz ją wszystkie późniejsze zmiany zostaną skasowane.</strong>",
+'yourdiff' => 'Różnice',
+'copyrightwarning' => "Proszę pamiętać o tym, że wszelki wkład do serwisu {{SITENAME}} jest udostępniany na zasadach $2 (szczegóły w $1). Jeśli nie chcesz, żeby Twój tekst był dowolnie zmieniany przez każdego i rozpowszechniany bez ograniczeń, nie umieszczaj go tutaj.<br />
+Niniejszym jednocześnie oświadczasz, że ten tekst jest Twoim dziełem lub pochodzi z materiałów dostępnych na zasadach ''public domain'' albo kompatybilnych.
+<br /><strong>PROSZĘ NIE UŻYWAĆ BEZ POZWOLENIA MATERIAŁÓW OBJĘTYCH PRAWEM AUTORSKIM!</strong>",
+'longpagewarning' => '<strong>Uwaga: Ta strona ma $1 kilobajt-y/-ów; w przypadku niektórych przeglądarek mogą wystąpić problemy w edycji stron mających więcej niż 32 kilobajty. Jeśli to możliwe, spróbuj podzielić tekst na mniejsze części.</strong>',
+'longpageerror' => '<strong>Błąd: Przesłany przez Ciebie tekst ma $1 kilobajtów. Maksymalna długość tekstu nie może przekraczać $2 kilobajtów. Twój tekst nie zostanie zapisany.</strong>',
+'readonlywarning' => '<strong>Uwaga: Baza danych została chwilowo zablokowana do celów administracyjnych. Nie można więc na razie zapisać nowej wersji artykułu. Proponujemy przenieść jej tekst do prywatnego pliku (wytnij/wklej) i zachować na później.</strong>',
+'protectedpagewarning' => '<strong>Uwaga: Modyfikacja tej strony została zablokowana. Mogą ją edytować jedynie użytkownicy z prawami administracyjnymi. Upewnij się, że postępujesz zgodnie z [[{{ns:Project}}:Blokowanie_stron|zasadami dotyczącymi zablokowanych stron]].</strong>',
+'semiprotectedpagewarning' => '<strong>Uwaga:</strong> Tę stronę mogą edytować tylko zarejestrowani użytkownicy.',
+'templatesused' => 'Szablony użyte na tej stronie:',
+'edittools' => '<!-- Znajdujący się tutaj tekst zostanie pokazany pod polem edycji i formularzem przesyłania plików. -->',
+'nocreatetitle' => 'Ograniczono tworzenie stron',
+'nocreatetext' => 'Ograniczono możliwość tworzenia nowych stron. Możesz edytować istniejące strony lub [[{{ns:Special}}:Userlogin|zalogować się albo utworzyć nowe konto]].',
+'cantcreateaccounttitle' => 'Nie można utworzyć konta',
+'cantcreateaccounttext' => 'Możliwość utworzenia konta z tego adresu IP (<b>$1</b>) została zablokowana. Stało się to prawdopodobnie wskutek ciągłych aktów wandalizmu z Twojej szkoły/uczelni lub wandalizmów innych użytkowników Twojego providera internetowego.',
+
+# History pages
+#
+'revhistory' => 'Historia modyfikacji',
+'viewpagelogs' => 'Zobacz rejestry operacji dla tej strony',
+'nohistory' => 'Ta strona nie ma swojej historii edycji.',
+'revnotfound' => 'Wersja nie została odnaleziona',
+'revnotfoundtext' => 'Starsza wersja strony nie może zostać odnaleziona. Sprawdź, proszę, URL użyty przez Ciebie by uzyskać dostęp do tej strony.',
+'loadhist' => 'Pobieranie historii tej strony',
+'currentrev' => 'Aktualna wersja',
+'revisionasof' => 'Wersja z dnia $1',
+'revision-info' => 'Wersja z dnia $1; $2',
+'previousrevision' => '← Poprzednia wersja',
+'nextrevision' => 'Następna wersja →',
+'currentrevisionlink' => 'Aktualna wersja',
+'cur' => 'bież',
+'next' => 'następna',
+'last' => 'poprz',
+'orig' => 'oryginał',
+'histlegend' => 'Legenda: (bież) - różnice z wersją bieżącą, (poprz) - różnice z wersją poprzedzającą, d - drobne zmiany',
+'deletedrev' => '[usunięto]',
+'histfirst' => 'od początku',
+'histlast' => 'od końca',
+'rev-deleted-comment' => '(komentarz usunięty)',
+'rev-deleted-user' => '(użytkownik usunięty)',
+'rev-delundel' => 'pokaż/ukryj',
+
+'history-feed-title' => 'Historia wersji',
+'history-feed-description' => 'Historia wersji tej strony wiki',
+'history-feed-item-nocomment' => '$1 o $2',
+'history-feed-empty' => 'Wybrana strona nie istnieje. Mogła ona zostać usunięta lub przeniesiona pod inną nazwę. Możesz także [[{{ns:special}}:Search|poszukać]] tej strony.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Skasuj/przywróć wersje',
+'revdelete-selected' => 'Wybrano wersje strony [[:$1]]:',
+
+# Diffs
+#
+'difference' => '(Różnice między wersjami)',
+'loadingrev' => 'pobieranie wersji w celu porównania',
+'lineno' => "Linia $1:",
+'editcurrent' => 'Edytuj bieżącą wersję tej strony',
+'selectnewerversionfordiff' => 'Wybierz nowszą wersję do porównania',
+'selectolderversionfordiff' => 'Wybierz starszą wersję do porównania',
+'compareselectedversions' => 'porównaj wybrane wersje',
+
+# Search results
+#
+'searchresults' => 'Wyniki wyszukiwania',
+'searchresulttext' => 'Aby dowiedzieć się więcej o przeszukiwaniu serwisu {{SITENAME}}, zobacz stronę [[{{ns:Project}}:Przeszukiwanie|Przeszukiwanie]].',
+'searchsubtitle' => 'Dla zapytania "[[:$1]]"',
+'searchsubtitleinvalid' => 'Dla zapytania "$1"',
+'badquery' => 'Źle sformułowane zapytanie',
+'badquerytext' => 'Nie można zrealizować Twojego zapytania. Prawdopodobna przyczyna to obecność słowa krótszego niż trzyliterowe. Spróbuj, proszę, innego zapytania.',
+'matchtotals' => 'Zapytanie "$1", liczba znalezionych tytułów: $2,
+liczba znalezionych artykułów: $3.',
+'noexactmatch' => 'Nie ma stron zatytułowanych "$1". Możesz [[:$1|utworzyć tę stronę]] lub spróbować pełnego przeszukiwania.',
+'titlematches' => 'Znaleziono w tytułach:',
+'notitlematches' => 'Nie znaleziono w tytułach',
+'textmatches' => 'Znaleziono na stronach:',
+'notextmatches' => 'Nie znaleziono w tekście stron',
+'prevn' => 'poprzednie $1',
+'nextn' => 'następne $1',
+'viewprevnext' => 'Zobacz ($1) ($2) ($3).',
+'showingresults' => 'Oto lista <b>$1</b> pozycji, poczynając od numeru <b>$2</b>.',
+'showingresultsnum' => 'Oto lista <b>$3</b> pozycji, poczynając od numeru <b>$2</b>.',
+'nonefound' => "'''Uwaga''': brak rezultatów wyszukiwania spowodowany jest bardzo często szukaniem najpopularniejszych słów, takich jak \"jest\" czy \"nie\", które nie są indeksowane, albo z powodu podania w zapytaniu więcej niż jednego słowa (na liście odnalezionych stron znajdą się tylko te, które zawierają wszystkie podane słowa).",
+'powersearch' => 'Szukaj',
+'powersearchtext' => "Szukaj w przestrzeniach nazw:<br />$1<br />$2 Pokaż przekierowania<br />Szukany tekst $3 $9",
+'searchdisabled' => 'Wyszukiwanie w serwisie {{SITENAME}} zostało wyłączone. W międzyczasie możesz skorzystać z wyszukiwania Google.',
+'blanknamespace' => '(główna)',
+
+# Preferences page
+#
+'preferences' => 'Preferencje',
+'mypreferences' => 'Moje preferencje',
+'prefsnologin' => 'Nie jesteś zalogowany',
+'prefsnologintext' => 'Musisz się [[{{ns:Special}}:Userlogin|zalogować]] przed zmianą swoich preferencji.',
+'prefsreset' => 'Preferencje domyślne zostały odtworzone.',
+'qbsettings' => 'Pasek szybkiego dostępu',
+'changepassword' => 'Zmiana hasła',
+'skin' => 'Skórka',
+'math' => 'Wzory matematyczne',
+'dateformat' => 'Format daty',
+'datedefault' => 'Domyślny',
+'datetime' => 'Data i czas',
+'math_failure' => 'Parser nie mógł rozpoznać',
+'math_unknown_error' => 'nieznany błąd',
+'math_unknown_function' => 'nieznana funkcja',
+'math_lexing_error' => 'błąd leksera',
+'math_syntax_error' => 'błąd składni',
+'math_image_error' => 'konwersja do formatu PNG niepowiodła się ; check for correct installation of latex, dvips, gs, and convert',
+'math_bad_tmpdir' => 'Nie można utworzyć lub zapisywać w tymczasowym katalogu dla wzorów matematycznych',
+'math_bad_output' => 'Nie można utworzyć lub zapisywać w wyjściowym katalogu dla wzorów matematycznych',
+'prefs-personal' => 'Dane użytkownika',
+'prefs-rc' => 'Ostatnie zmiany',
+'prefs-watchlist' => 'Obserwowane',
+'prefs-watchlist-days' => 'Liczba dni ukazywania się pozycji na liście:',
+'prefs-watchlist-edits' => 'Liczba edycji pokazywanych w rozszerzonej liście obserwowanych:',
+'prefs-misc' => 'Różne',
+'saveprefs' => 'Zapisz preferencje',
+'resetprefs' => 'Preferencje domyślne',
+'oldpassword' => 'Stare hasło',
+'newpassword' => 'Nowe hasło',
+'retypenew' => 'Powtórz nowe hasło',
+'textboxsize' => 'Edytowanie',
+'rows' => 'Wiersze:',
+'columns' => 'Kolumny:',
+'searchresultshead' => 'Wyszukiwarka',
+'resultsperpage' => 'Liczba wyników na stronie',
+'contextlines' => 'Pierwsze wiersze artykułu',
+'contextchars' => 'Litery kontekstu w linijce',
+'stubthreshold' => 'Maksymalny rozmiar artykułu prowizorycznego:',
+'recentchangescount' => 'Liczba pozycji na liście ostatnich zmian:',
+'savedprefs' => 'Twoje preferencje zostały zapisane.',
+'timezonelegend' => 'Strefa czasowa',
+'timezonetext' => 'Podaj liczbę godzin różnicy między Twoim czasem, a czasem uniwersalnym (UTC). Np. dla Polski jest to liczba "2" (czas letni) lub "1" (czas zimowy).',
+'localtime' => 'Twój czas:',
+'timezoneoffset' => 'Różnica ¹',
+'servertime' => 'Aktualny czas serwera',
+'guesstimezone' => 'Pobierz z przeglądarki',
+'allowemail' => 'Inni użytkownicy mogą przesyłać mi e-maile',
+'defaultns' => 'Przeszukuj następujące przestrzenie nazw domyślnie:',
+'default' => 'domyślnie',
+'files' => 'Pliki',
+
+# User rights
+'userrights-lookup-user' => 'Zarządzaj grupami użytkownika',
+'userrights-user-editname' => 'Wprowadź nazwę użytkownika:',
+'editusergroup' => 'Edytuj grupy użytkownika',
+
+'userrights-editusergroup' => 'Edytuj grupy użytkownika',
+'saveusergroups' => 'Zapisz',
+'userrights-groupsmember' => 'Członek grup:',
+'userrights-groupsavailable' => 'Dostępne grupy:',
+'userrights-groupshelp' => 'Zaznacz grupy do których użytkownik ma zostać dodany lub z których ma zostać usunięty. Niezaznaczone grupy nie zostaną zmienione. Możesz odznaczyć grupę za pomocą CTRL + lewy przycisk myszy.',
+
+# Groups
+'group' => 'Grupa:',
+'group-bot' => 'Boty',
+'group-sysop' => 'Administratorzy',
+'group-bureaucrat' => 'Biurokraci',
+'group-all' => '(wszyscy)',
+
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Administrator',
+'group-bureaucrat-member' => 'Biurokrata',
+
+'grouppage-bot' => '{{ns:Project}}:Boty',
+'grouppage-sysop' => '{{ns:Project}}:Administratorzy',
+'grouppage-bureaucrat' => '{{ns:Project}}:Biurokraci',
+
+# Recent changes
+#
+'changes' => 'zmiany',
+'recentchanges' => 'Ostatnie zmiany',
+'recentchangestext' => 'Ta strona przedstawia historię ostatnich zmian w serwisie.',
+'rcnote' => 'To ostatnie <strong>$1</strong> zmian dokonanych w ciągu ostatnich <strong>$2</strong> dni, poczynając od $3.',
+'rcnotefrom' => 'Poniżej pokazano zmiany dokonane po <b>$2</b> (nie więcej niż <b>$1</b> pozycji).',
+'rclistfrom' => 'Pokaż zmiany od $1',
+'rcshowhideminor' => '$1 drobne zmiany',
+'rcshowhidebots' => '$1 boty',
+'rcshowhideliu' => '$1 zalogowanych',
+'rcshowhideanons' => '$1 anonimowych',
+'rcshowhidepatr' => '$1 patrolowane',
+'rcshowhidemine' => '$1 moje edycje',
+'rclinks' => 'Wyświetl ostatnie $1 zmian w ciągu ostatnich $2 dni.<br />$3',
+'diff' => 'różn',
+'hist' => 'hist',
+'hide' => 'ukryj',
+'show' => 'pokaż',
+'minoreditletter' => 'd',
+'newpageletter' => 'N',
+'sectionlink' => '→',
+'rc_categories' => 'Ogranicz do kategorii (oddzielaj za pomocą "|")',
+'rc_categories_any' => 'Wszystkie',
+
+# Upload
+#
+'upload' => 'Prześlij plik',
+'uploadbtn' => 'Prześlij plik',
+'reupload' => 'Prześlij ponownie',
+'reuploaddesc' => 'Wróć do formularza wysyłki.',
+'uploadnologin' => 'Brak logowania',
+'uploadnologintext' => 'Musisz się [[{{ns:Special}}:Userlogin|zalogować]] przed przesłaniem pików.',
+'upload_directory_read_only' => 'Serwer nie może zapisywać do katalogu ($1) przeznaczonego na przesyłane pliki.',
+'uploaderror' => 'Błąd przesyłki',
+'uploadtext' => 'Użyj poniższego formularza do przesłania plików. Jeśli chcesz przejrzeć lub przeszukać dotychczas przesłane pliki, przejdź do [[{{ns:Special}}:Imagelist|listy dołączonych plików]]. Wszystkie przesyłki są odnotowane w [[{{ns:Special}}:Log/upload|rejestrze przesyłanych plików]].',
+'uploadlog' => 'Wykaz przesyłek',
+'uploadlogpage' => 'Dołączone',
+'uploadlogpagetext' => 'Oto lista ostatnio przesłanych plików.',
+'filename' => 'Plik',
+'filedesc' => 'Opis',
+'fileuploadsummary' => 'Opis:',
+'filestatus' => 'Status prawny',
+'filesource' => 'Kod źródłowy',
+'copyrightpage' => "{{ns:Project}}:Prawa_autorskie",
+'copyrightpagename' => "prawami autorskimi serwisu {{SITENAME}}",
+'uploadedfiles' => 'Przesłane pliki',
+'ignorewarning' => 'Zignoruj ostrzeżenia i wymuś zapisanie pliku.',
+'ignorewarnings' => 'Ignoruj ostrzeżenia',
+'minlength' => 'Nazwa obrazku musi mieć co najmniej trzy litery.',
+'illegalfilename' => 'Nazwa pliku ("$1") zawiera znaki niedozwolone w tytułach stron. Proszę zmienić nazwę pliku i przesłać go ponownie.',
+'badfilename' => 'Nazwę obrazku zmieniona na "$1".',
+'badfiletype' => '".$1" nie jest zalecanym formatem pliku.',
+'largefile' => 'Zalecane jest aby rozmiar pliku z obrazkiem nie był większy niż $1 bajtów. Ten plik ma rozmiar $2 bajtów.',
+'largefileserver' => 'Plik jest większy niż maksymalny dozwolony rozmiar.',
+'emptyfile' => 'Plik, który przesłałeś wydaje się być pusty. Może być to spowodowane literówką w nazwie pliku. Sprawdź, czy nazwa jest prawidłowa.',
+'fileexists' => 'Plik o takiej nazwie już istnieje! Załadowanie nowej grafiki nieodwacalnie usunie już istniejącą ($1)! Upewnij się, że wiesz, co robisz.',
+'fileexists-forbidden' => 'Plik o tej nazwie już istnieje! Wróć i załaduj ten plik pod inną nazwą. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Plik o tej nazwie już istnieje! Wróć i załaduj ten plik pod inną nazwą. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Przesłanie pliku powiodło się',
+'fileuploaded' => 'Plik "$1" został pomyślnie przesłany. Przejdź, proszę, do strony opisu pliku ($2) i podaj dotyczące go informacje takie jak: pochodzenie pliku, kiedy i przez kogo został utworzony i cokolwiek co wiesz o pliku, a wydaje Ci się ważne.',
+'uploadwarning' => 'Ostrzeżenie o przesyłce',
+'savefile' => 'Zapisz plik',
+'uploadedimage' => 'przesłano "[[$1]]"',
+'uploaddisabled' => 'Przesyłanie plików wyłączone',
+'uploaddisabledtext' => 'Możliwość przesyłania plików została wyłączona.',
+'uploadscripted' => 'Ten plik zawiera kod HTML lub skrypt który może zostać błędnie zinterpretowany przez przeglądarkę internetową.',
+'uploadcorrupt' => 'Ten plik jest uszkodzony lub ma nieprawidłowe rozszerzenie. Proszę sprawdzić plik i załadować poprawną wersję.',
+'uploadvirus' => 'W tym pliku jest wirus! Szczegóły: $1',
+'sourcefilename' => 'Nazwa oryginalna',
+'destfilename' => 'Nazwa docelowa',
+'watchthisupload' => 'Obserwuj tę stronę',
+'filewasdeleted' => 'Plik o tej nazwie istniał, ale został skasowany. Zanim załadujesz go ponownie, sprawdź $1.',
+
+'license' => 'Licencja',
+'nolicense' => 'Nie wybrano (wpisz ręcznie!)',
+'upload_source_url' => ' (poprawny, publicznie dostępny URL)',
+'upload_source_file' => ' (plik na twoim komputerze)',
+
+# Image list
+#
+'imagelist' => 'Lista plików',
+'imagelisttext' => "To jest lista '''$1''' plików posortowanych $2.",
+'imagelistforuser' => 'Lista grafik załadowanych przez $1.',
+'getimagelist' => 'pobieranie listy plików',
+'ilsubmit' => 'Szukaj',
+'showlast' => 'Pokaż ostatnie $1 plików posortowanych $2.',
+'byname' => 'według nazwy',
+'bydate' => 'według daty',
+'bysize' => 'według rozmiaru',
+'imgdelete' => 'usuń',
+'imgdesc' => 'opis',
+'imgfile' => 'plik',
+'imglegend' => 'Legenda: (opis) - pokaż/edytuj opis pliku.',
+'imghistory' => 'Historia pliku',
+'revertimg' => 'przywróć',
+'deleteimg' => 'usuń',
+'deleteimgcompletely' => 'Usuń wszystkie wersje tego pliku',
+'imghistlegend' => 'Legend: (bież) - to jest bieżący plik, (usuń) - usuń starszą wersję, (przywróć) - przywróc starszą wersję.<br /><i>Kliknij na datę aby zobaczyć przesłany plik</i>.',
+'imagelinks' => 'Odnośniki do pliku',
+'linkstoimage' => 'Oto strony odwołujące się do tego pliku:',
+'nolinkstoimage' => 'Żadna strona nie odwołuje się do tego pliku.',
+'sharedupload' => 'Plik [[Commons:Image:{{PAGENAME}}|{{PAGENAME}}]] umieszczony jest we wspólnym repozytorium i może być używany w innych projektach.',
+'shareduploadwiki' => 'Zobacz $1 aby dowiedzieć się więcej.',
+'shareduploadwiki-linktext' => 'stronę opisu grafiki',
+'noimage' => 'Nie istnieje plik o tej nazwie. Możesz go $1.',
+'noimage-linktext' => 'przesłać',
+'uploadnewversion-linktext' => 'Załaduj nowszą wersję tego pliku',
+'imagelist_date' => 'Data',
+'imagelist_name' => 'Nazwa',
+'imagelist_user' => 'Użytkownik',
+'imagelist_size' => 'Rozmiar (bajty)',
+'imagelist_description' => 'Opis',
+'imagelist_search_for' => 'Szukaj grafiki o nazwie:',
+
+# Mime search
+#
+'mimesearch' => 'Wyszukiwanie MIME',
+'mimetype' => 'Typ MIME:',
+'download' => 'pobierz',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Nieobserwowane strony',
+
+# List redirects
+'listredirects' => 'Lista przekierowań',
+
+# Unused templates
+'unusedtemplates' => 'Nieużywane szablony',
+'unusedtemplatestext' => 'Poniżej znajduje się lista szablonów nieużywanych na innych stronach.',
+'unusedtemplateswlh' => 'linkujące',
+
+# Random redirect
+'randomredirect' => 'Losowe przekierowanie',
+
+# Statistics
+#
+'statistics' => 'Statystyka',
+'sitestats' => 'Statystyka artykułów',
+'userstats' => 'Statystyka użytkowników',
+'sitestatstext' => "W bazie danych jest w sumie '''$1''' stron.
+
+Ta liczba uwzględnia strony dyskusji, strony na temat serwisu {{SITENAME}}, strony prowizorycznych (\"stub\"), strony przekierowujące oraz inne, które trudno uznać za artykuły. Wyłączając powyższe, jest prawdopodobnie '''$2''' stron, które można uznać za artykuły.
+
+Ilość przesłanych plików: '''$8'''.
+
+Użytkownicy od startu serwisu wykonali '''$4''' edycji, średnio '''$5''' edycji na stronę. W sumie było '''$3''' odwiedzin, średnio '''$6''' odwiedzin na edycję.
+
+Długość [http://meta.wikimedia.org/wiki/Help:Job_queue kolejki zadań] wynosi '''$7'''.",
+'userstatstext' => "Jest '''$1''' zarejestrowanych użytkowników. Spośród nich '''$2''' (czyli '''$4%''') ma status $5.",
+'statistics-mostpopular' => 'Najczęściej odwiedzane strony',
+
+'disambiguations' => 'Strony ujednoznaczniające',
+'disambiguationspage' => '{{ns:Template}}:disambig',
+'disambiguationstext' => 'Poniższe artykuły odwołują się do <i>stron ujednoznaczniających</i>, a powinny odwoływać się bezpośrednio do hasła związanego z treścią artykułu.<br />Strona uznawana jest za ujednoznaczniającą jeśli odwołuje się do niej $1.<br />Linki z innych przestrzeni nazw <i>nie</i> zostały tu uwzględnione.',
+
+'doubleredirects' => 'Podwójne przekierowania',
+'doubleredirectstext' => 'Na tej liście mogą znajdować się przekierowania pozorne. Oznacza to, że poniżej pierwszej linii artykułu, zawierającej "#REDIRECT ...", może znajdować się dodatkowy tekst.<br />Każdy wiersz listy zawiera odwołania do pierwszego i drugiego przekierowania oraz pierwszą linię tekstu drugiego przekierowania. Umożliwia to w większości przypadków odnalezienie właściwego artykułu, do którego powinno się przekierowywać.',
+
+'brokenredirects' => 'Zerwane przekierowania',
+'brokenredirectstext' => 'Poniższe przekierowania wskazują na nieistniejące artykuły.',
+
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|bajt|bajtów}}',
+'ncategories' => '$1 {{PLURAL:$1|kategoria|kategorii}}',
+'nlinks' => '$1 {{PLURAL:$1|link|linków}}',
+'nmembers' => '$1 {{PLURAL:$1|element|elementów}}',
+'nrevisions' => '$1 {{PLURAL:$1|wersja|wersji}}',
+'nviews' => 'odwiedzono $1 {{PLURAL:$1|raz|razy}}',
+
+'lonelypages' => 'Porzucone strony',
+'uncategorizedpages' => 'Nieskategoryzowane strony',
+'uncategorizedcategories' => 'Nieskategoryzowane kategorie',
+'uncategorizedimages' => 'Nieskategoryzowane grafiki',
+'unusedcategories' => 'Nieużywane kategorie',
+'unusedimages' => 'Nie używane pliki',
+'popularpages' => 'Najpopularniejsze strony',
+'wantedcategories' => 'Potrzebne kategorie',
+'wantedpages' => 'Najpotrzebniejsze strony',
+'mostlinked' => 'Najczęściej linkowane',
+'mostlinkedcategories' => 'Kategorie o największej liczbie artykułów',
+'mostcategories' => 'Artykuły z największą liczbą kategorii',
+'mostimages' => 'Najczęściej linkowane pliki',
+'mostrevisions' => 'Najczęściej edytowane artykuły',
+'allpages' => 'Wszystkie strony',
+'prefixindex' => 'Wszystkie strony według prefiksu',
+'randompage' => 'Losuj stronę',
+'shortpages' => 'Najkrótsze strony',
+'longpages' => 'Najdłuższe strony',
+'deadendpages' => 'Strony bez linków',
+'deadendpagestext' => 'Poniższe strony nie posiadają odnośników do innych stron znajdujących się w tej wiki.',
+'listusers' => 'Lista użytkowników',
+'specialpages' => 'Strony specjalne',
+'spheading' => 'Strony specjalne dla wszystkich użytkowników',
+'restrictedpheading' => 'Strony specjalne z ograniczonym dostępem',
+'recentchangeslinked' => 'Zmiany w dolinkowanych',
+'rclsub' => '(dla stron dolinkowanych do "$1")',
+'newpages' => 'Nowe strony',
+'newpages-username' => 'Nazwa użytkownika:',
+'ancientpages' => 'Najstarsze strony',
+'intl' => 'Linki interwiki',
+'move' => 'Przenieś',
+'movethispage' => 'Przenieś tę stronę',
+'unusedimagestext' => 'Pamiętaj, proszę, że inne witryny, np. projekty Wikimedia w innych językach, mogą odwoływać się do tych plików używając bezpośrednio URL. Dlatego też niektóre z plików mogą się znajdować na tej liście mimo, że żadna strona nie odwołuje się do nich.',
+'unusedcategoriestext' => 'Poniższe kategorie istnieją, choć nie korzysta z nich żaden artykuł ani kategoria.',
+
+'booksources' => 'Książki',
+'categoriespagetext' => 'Poniższe kategorie istnieją na wiki.',
+'userrights' => 'Zarządzanie prawami użytkowników',
+'groups' => 'Grupy użytkowników',
+
+'booksourcetext' => 'Oto lista linków do innych witryn, które pośredniczą w sprzedaży nowych i używanych książek i mogą podać informacje o książkach, których szukasz. {{SITENAME}} nie jest stowarzyszona z żadnym ze sprzedawców, a ta lista nie powinna być interpretowana jako świadectwo udziału w zyskach.',
+'alphaindexline' => "$1 --> $2",
+'version' => 'Wersja oprogramowania',
+'log' => 'Rejestry operacji',
+'alllogstext' => 'Połączone rejestry przesłanych plików, skasowanych stron, zabezpieczania, blokowania i nadawania uprawnień. Możesz zawęzić wynik przez wybranie typu rejestru, nazwy użytkownika albo nazwy interesującej Cię strony.',
+'logempty' => 'Brak pozycji w rejestrze.',
+
+
+# Special:Allpages
+'nextpage' => 'Następna strona ($1)',
+'allpagesfrom' => 'Strony zaczynające się na:',
+'allarticles' => 'Wszystkie artykuły',
+'allinnamespace' => 'Wszystkie strony (w przestrzeni $1)',
+'allnotinnamespace' => 'Wszystkie strony (oprócz przestrzeni nazw $1)',
+'allpagesprev' => 'Poprzednia',
+'allpagesnext' => 'Następna',
+'allpagessubmit' => 'Pokaż',
+'allpagesprefix' => 'Pokaż zaczynające się od:',
+'allpagesbadtitle' => 'Podana nazwa jest nieprawidłowa, zawiera prefiks międzyprojektowy lub międzyjęzykowy. Może ona także zawierać w sobie jeden lub więcej znaków których użycie w nazwach jest niedozwolone.',
+
+# Special:Listusers
+'listusersfrom' => 'Wyświetl użytkowników zaczynając od:',
+
+# E this user
+#
+'mailnologin' => 'Brak adresu',
+'mailnologintext' => 'Musisz się [[{{ns:Special}}:Userlogin|zalogować]] i mieć wpisany aktualny adres e-mailowy w swoich [[{{ns:Special}}:Preferences|preferencjach]], aby móc wysłać e-mail do innych użytkowników.',
+'emailuser' => 'Wyślij e-mail do tego użytkownika',
+'emailpage' => 'Wyślij e-mail do użytkownika',
+'emailpagetext' => 'Jeśli ten użytkownik wpisał poprawny adres e-mailowy w swoich preferencjach, to poniższy formularz umożliwi Ci wysłanie jednej wiadomości. Adres e-mailowy, który został przez Ciebie wprowadzony w Twoich preferencjach pojawi się w polu "Od", dzięki temu odbiorca będzie mógł Ci odpowiedzieć.',
+'usermailererror' => 'Obiekt Mail zwrócił błąd:',
+'defemailsubject' => '{{SITENAME}} e-mail',
+'noemailtitle' => 'Brak adresu e-mailowego',
+'noemailtext' => 'Ten użytkownik nie podał poprawnego adresu e-mailowego, albo zadecydował, że nie chce otrzymywać e-maili od innych użytkowników.',
+'emailfrom' => 'Od',
+'emailto' => 'Do',
+'emailsubject' => 'Temat',
+'emailmessage' => 'Wiadomość',
+'emailsend' => 'Wyślij',
+'emailsent' => 'Wiadomość została wysłana',
+'emailsenttext' => 'Twoja wiadomość została wysłana.',
+
+# Watchlist
+#
+'watchlist' => 'Obserwowane',
+'watchlistfor' => "(dla użytkownika '''$1''')",
+'nowatchlist' => 'Nie ma żadnych pozycji na liście obserwowanych przez Ciebie stron.',
+'watchlistanontext' => '$1 aby obejrzeć lub edytować elementy listy obserwowanych.',
+'watchlistcount' => "'''Masz $1 {{PLURAL:$1|$1 pozycję|$1 pozycji}} na liście obserwowanych stron, włączając strony dyskusji.'''",
+'clearwatchlist' => 'Wyczyść listę obserwowanych',
+'watchlistcleartext' => 'Czy jesteś pewien, że chcesz je usunąć?',
+'watchlistclearbutton' => 'Wyczyść obserwowane',
+'watchlistcleardone' => 'Twoja lista stron obserwowanych została wyczyszczona. Liczba usuniętych obiektów: $1.',
+'watchnologin' => 'Brak logowania',
+'watchnologintext' => 'Musisz się [[{{ns:Special}}:Userlogin|zalogować]] przed modyfikacją listy obserwowanych artykułów.',
+'addedwatch' => 'Dodana do listy obserwowanych',
+'addedwatchtext' => "Strona \"[[:$1|$1]]\" została dodana do Twojej [[{{ns:Special}}:Watchlist|listy obserwowanych]]. Na tej liście znajdzie się rejestr przyszłych zmian tej strony i związanej z nią strony dyskusji, a nazwa samej strony zostanie '''wytłuszczona''' na [[{{ns:Special}}:Recentchanges|liście ostatnich zmian]], aby łatwiej było Ci sam fakt zmiany zauważyć.
+
+Jeśli chcesz usunąć stronę ze swojej listy obserwowanych, kliknij na \"Przestań obserwować\".",
+'removedwatch' => 'Usunięto z listy obserwowanych',
+'removedwatchtext' => 'Strona "[[:$1]]" została usunięta z Twojej listy obserwowanych.',
+'watch' => 'Obserwuj',
+'watchthispage' => 'Obserwuj tę stronę',
+'unwatch' => 'Przestań obserwować',
+'unwatchthispage' => 'Przestań obserwować',
+'notanarticle' => 'To nie artykuł',
+'watchnochange' => 'Żadna z obserwowanych stron nie była edytowana w podanym okresie.',
+'watchdetails' => '* Liczba obserwowanych przez Ciebie stron: $1, nie licząc stron dyskusji.
+* [[{{ns:Special}}:Watchlist/edit|Pokaż i edytuj pełną listę]]
+* [[{{ns:Special}}:Watchlist/clear|Wyczyść listę obserwowanych]]',
+'wlheader-enotif' => '* Wysyłanie powiadomień na adres e-mail jest włączone.',
+'wlheader-showupdated' => "* Strony które zostały zmienione od twojej ostatniej wizyty na nich zostały '''pogrubione'''",
+'watchmethod-recent'=> 'poszukiwanie ostatnich zmian wśród obserwowanych stron',
+'watchmethod-list' => 'poszukiwanie obserwowanych stron wśród ostatnich zmian',
+'removechecked' => 'Usuń zaznaczone pozycje z listy obserwowanych',
+'watchlistcontains' => 'Lista obserwowanych przez Ciebie stron zawiera $1 pozycji.',
+'watcheditlist' => "Oto alfabetyczna lista obserwowanych stron. Zaznacz, które z nich chcesz usunąć z listy i kliknij przycisk ''Usuń zaznaczone pozycje z listy obserwowanych'' znajdujący się na dole strony.",
+'removingchecked' => 'Usuwamy zaznaczone pozycje z listy obserwowanych...',
+'couldntremove' => 'Nie można było usunąć pozycji "$1"...',
+'iteminvalidname' => 'Problem z pozycją "$1", niepoprawna nazwa...',
+'wlnote' => 'Poniżej pokazano ostatnie $1 zmian dokonanych w ciągu ostatnich <b>$2</b> godzin.',
+'wlshowlast' => 'Pokaż ostatnie $1 godzin $2 dni ($3)',
+'wlsaved' => 'To jest ostatnia zapisana kopia Twojej listy obserwowanych.',
+'wlhideshowown' => '$1 moje edycje',
+'wlhideshowbots' => '$1 edycje botów',
+'wldone' => 'Wykonano.',
+
+'enotif_mailer' => 'Powiadomienie z serwisu {{SITENAME}}',
+'enotif_reset' => 'Zaznacz wszystkie strony jako odwiedzone',
+'enotif_newpagetext'=> 'To jest nowa strona.',
+'changed' => 'zmieniona',
+'created' => 'utworzona',
+'enotif_subject' => 'Strona $PAGETITLE w serwisie {{SITENAME}} została $CHANGEDORCREATED przez użytkownika $PAGEEDITOR',
+'enotif_lastvisited' => 'Zobacz $1 w celu obejrzenia wszystkich zmian od twojej ostatniej wizyty.',
+'enotif_body' => 'Drogi $WATCHINGUSERNAME,
+
+strona $PAGETITLE w serwisie {{SITENAME}} została $CHANGEDORCREATED o $PAGEEDITDATE przez użytkownika $PAGEEDITOR, zobacz $PAGETITLE_URL w celu obejrzenia aktualnej wersji.
+
+$NEWPAGE
+
+Opis zmiany: $PAGESUMMARY $PAGEMINOREDIT
+
+Skontaktuj się z autorem:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+W przypadku kolejnych zmian nowe powiadomienia nie zostaną wysłane dopóki nie odwiedzisz tej strony. Możesz także zresetować flagi powiadomień dla wszystkich obserwowanych przez ciebie stron.
+
+ Wiadomość systemu powiadomień serwisu {{SITENAME}}
+
+--
+W celu zmiany ustawień swojej listy obserwowanych odwiedź
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Pomoc:
+{{fullurl:{{ns:help}}:Contents}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Usuń stronę',
+'confirm' => 'Potwierdź',
+'excontent' => 'Zawartość strony "$1"',
+'excontentauthor' => 'treść: "$1" (jedyny autor: [[{{ns:Special}}:Contributions/$2|$2]])',
+'exbeforeblank' => 'Poprzednia zawartość pustej strony "$1"',
+'exblank' => 'Strona była pusta',
+'confirmdelete' => 'Potwierdź usunięcie',
+'deletesub' => '(Usuwanie "$1")',
+'historywarning' => 'Uwaga! Strona, którą chcesz skasować ma starsze wersje:',
+'confirmdeletetext' => 'Zamierzasz trwale usunąć stronę lub plik z bazy danych razem z dotyczącą ich historią. Potwierdź, proszę, swoje zamiary, tzn., że rozumiesz konsekwencje, i że robisz to w zgodzie z [[{{ns:Project}}:Zasady i wskazówki|zasadami]].',
+'actioncomplete' => 'Operacja wykonana',
+'deletedtext' => 'Usunięto "$1". Rejestr ostatnio dokonanych kasowań możesz obejrzeć tutaj: $2.',
+'deletedarticle' => 'usunięto "[[$1]]"',
+'dellogpage' => 'Usunięte',
+'dellogpagetext' => 'To jest lista ostatnio wykonanych kasowań.',
+'deletionlog' => 'rejestr usunięć',
+'reverted' => 'Przywrócono starszą wersję',
+'deletecomment' => 'Powód usunięcia',
+'imagereverted' => 'Przywrócenie wcześniejszej wersji powiodło się.',
+'rollback' => 'Cofnij edycję',
+'rollback_short' => 'Cofnij',
+'rollbacklink' => 'cofnij',
+'rollbackfailed' => 'Nie udało się cofnąć zmiany',
+'cantrollback' => 'Nie można cofnąć edycji; jest tylko jedna wersja tej strony.',
+'alreadyrolled' => 'Nie można cofnąć ostatniej zmiany strony [[:$1|$1]], której autorem jest [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|dyskusja]]). Ktoś inny zdążył już to zrobić lub wprowadził własne poprawki do treści strony. Autorem ostatniej zmiany jest teraz [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|dyskusja]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Opisano ją następująco: "<i>$1</i>".',
+'revertpage' => 'Wycofano edycję użytkownika [[{{ns:Special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|dyskusja]]). Autor przywróconej wersji to [[{{ns:user}}:$1|$1]].',
+'sessionfailure' => 'Błąd weryfikacji sesji. Twoje polecenie zostało anulowane, aby uniknąć przechwycenia sesji.
+
+Naciśnij "wstecz", przeładuj stronę, po czym ponownie wydaj polecenie.',
+'protectlogpage' => 'Zabezpieczone',
+'protectlogtext' => 'Poniżej znajduje się lista blokad założonych i zdjętych z pojedynczych stron. By dowiedzieć się czegoś więcej o blokowaniu stron, przeczytaj [[{{ns:Project}}:Zabezpieczanie stron]].',
+'protectedarticle' => 'zabezpieczono "[[$1]]"',
+'unprotectedarticle' => 'odbezpieczono "[[$1]]"',
+'protectsub' => '(Zabezpieczanie "$1")',
+'confirmprotecttext' => 'Czy na pewno chcesz zabezpieczyć tę stronę?',
+'confirmprotect' => 'potwierdź zabezpieczenie',
+'protectmoveonly' => 'Zabezpiecz tylko przed przenoszeniem',
+'protectcomment' => 'Powód zabezpieczenia',
+'unprotectsub' => '(Odbezpieczanie "$1")',
+'confirmunprotecttext' => 'Czy na pewno chcesz odbezpieczyć tę stronę?',
+'confirmunprotect' => 'potwierdź odbezpieczenie',
+'unprotectcomment' => 'Powód odbezpieczenia',
+'protect-unchain' => 'Odblokowanie możliwości przenoszenia strony',
+'protect-text' => 'Możesz tu zobaczyć i zmienić poziom zabezpieczenia strony <strong>$1</strong>. Upewnij się, że przestrzegasz [[{{ns:Project}}:Blokowanie stron|zasad zabezpieczania stron]].',
+'protect-viewtext' => 'Nie masz uprawnień do zmiany poziomu zabezpieczenia strony. Obecne ustawienia dla strony <strong>$1</strong> to:',
+'protect-default' => '(wszyscy)',
+'protect-level-autoconfirmed' => 'tylko zarejestrowani',
+'protect-level-sysop' => 'tylko administratorzy',
+
+# restrictions (nouns)
+'restriction-edit' => 'Edytuj',
+'restriction-move' => 'Przenieś',
+
+# Undelete
+'undelete' => 'Odtwórz skasowaną stronę',
+'undeletepage' => 'Odtwarzanie skasowanych stron',
+'viewdeletedpage' => 'Zobacz skasowane wersje',
+'undeletepagetext' => 'Poniższe strony zostały skasowane, ale ich kopia wciąż znajduje się w archiwum. Archiwum co jakiś czas także jest kasowane.',
+'undeleteextrahelp' => "Aby odtworzyć całą stronę, pozostaw wszystkie pola niezaznaczone i kliknij '''Odtwórz'''. Aby wybrać częściowe odtworzenie należy zaznaczyć odpowiednie pole. Naciśnięcie '''Wyczyść''' wyczyści wszystkie pola, łącznie z opisem komentarza.",
+'undeletearticle' => 'Odtwórz skasowaną stronę',
+'undeleterevisions' => 'Liczba zarchiwizowanych wersji: $1',
+'undeletehistory' => 'Odtworzenie strony spowoduje przywrócenie także jej wszystkich poprzednich wersji. Jeśli od czasu skasowania ktoś utworzył nową stronę o tej nazwie, odtwarzane wersje znajdą się w jej historii, a obecna wersja pozostanie bez zmian.',
+'undeletehistorynoadmin' => 'Ten artykuł został skasowany. Przyczyna usunięcia podana jest w podsumowaniu poniżej, razem z danymi użytkownika, który edytował artykuł przed skasowaniem. Sama treść usuniętych wersji jest dostępna jedynie dla administratorów.',
+'undeleterevision' => 'Skasowano wersję z $1',
+'undeletebtn' => 'Odtwórz',
+'undeletereset' => 'Wyczyść',
+'undeletecomment' => 'Powód odtworzenia:',
+'undeletedarticle' => 'odtworzono "$1"',
+'undeletedrevisions' => 'Liczba odtworzonych wersji: $1',
+'undeletedrevisions-files' => "Odtworzono $1 wersji i $2 plik(i)",
+'undeletedfiles' => "Odtworzono $1 plik(i)",
+'cannotundelete' => 'Odtworzenie nie powiodło się. Ktoś inny mógł odtworzyć stronę pierwszy.',
+'undeletedpage' => '<big>Odtworzono stronę $1.</big>
+
+Zobacz [[{{ns:Special}}:Log/delete]], jeśli chcesz przejrzeć rejestr ostatnio skasowanych i odtworzonych stron.',
+
+# Namespace form on various pages
+'namespace' => 'Przestrzeń nazw:',
+'invert' => 'Odwróć wybór',
+
+# Contributions
+#
+'contributions' => 'Wkład użytkownika',
+'mycontris' => 'Moje edycje',
+'contribsub' => 'Dla użytkownika $1',
+'nocontribs' => 'Brak zmian odpowiadających tym kryteriom.',
+'ucnote' => 'Oto lista ostatnich <b>$1</b> zmian dokonanych przez użytkownika w ciągu ostatnich <b>$2</b> dni.',
+'uclinks' => 'Zobacz ostatnie $1 zmian; zobacz ostatnie $2 dni.',
+'uctop' => ' (jako ostatnia)' ,
+'newbies' => 'początkujący',
+
+'sp-newimages-showfrom' => 'Pokaż nowe grafiki od $1',
+
+'sp-contributions-newest' => 'Najnowsze',
+'sp-contributions-oldest' => 'Najstarsze',
+'sp-contributions-newer' => 'nowsze $1',
+'sp-contributions-older' => 'starsze $1',
+'sp-contributions-newbies-sub' => 'Dla nowych użytkowników',
+
+# What links here
+#
+'whatlinkshere' => 'Linkujące',
+'notargettitle' => 'Wskazywana strona nie istnieje',
+'notargettext' => 'Nie podano strony albo użytkownika, dla których ta operacja ma być wykonana.',
+'linklistsub' => '(Lista linków)',
+'linkshere' => "Następujące strony odwołują się do '''[[:$1]]''':",
+'nolinkshere' => "Żadna strona nie odwołuje się do '''[[:$1]]'''.",
+'isredirect' => 'strona przekierowująca',
+'istemplate' => 'dołączony szablon',
+
+# Block/unblock IP
+#
+'blockip' => 'Zablokuj użytkownika',
+'blockiptext' => 'Użyj poniższego formularza aby zablokować prawo zapisu spod określonego adresu IP. Powinno się to robić jedynie by zapobiec wandalizmowi, a zarazem w zgodzie z [[{{ns:Project}}:Zasady i wskazówki|zasadami]]. Podaj powód (np. umieszczając nazwy stron, na których dopuszczono się wandalizmu).',
+'ipaddress' => 'Adres IP',
+'ipadressorusername' => 'Adres IP lub nazwa użytkownika',
+'ipbexpiry' => 'Czas blokady',
+'ipbreason' => 'Powód',
+'ipbanononly' => 'Zablokuj tylko anonimowych użytkowników',
+'ipbcreateaccount' => 'Zapobiegnij utworzeniu konta',
+'ipbsubmit' => 'Zablokuj użytkownika',
+'ipbother' => 'Inny czas',
+'ipboptions' => '2 godziny:2 hours,1 dzień:1 day,3 dni:3 days,1 tydzień:1 week,2 tygodnie:2 weeks,1 miesiąc:1 month,3 miesiące:3 months,6 miesięcy:6 months,1 rok:1 year,nieskończony:infinite',
+'ipbotheroption' => 'inny',
+'badipaddress' => 'Adres IP jest źle utworzony',
+'blockipsuccesssub' => 'Zablokowanie powiodło się',
+'blockipsuccesstext' => 'Użytkownik [[{{ns:Special}}:Contributions/$1|$1]] został zablokowany. <br />Przejdź do [[{{ns:Special}}:Ipblocklist|listy zablokowanych adresów IP]] by przejrzeć blokady.',
+'unblockip' => 'Odblokuj użytkownika',
+'unblockiptext' => 'Użyj poniższego formularza by przywrócić prawa zapisu dla poprzednio zablokowanego użytkownika lub adresu IP.',
+'ipusubmit' => 'Odblokuj użytkownika',
+'unblocked' => '[[{{ns:User}}:$1|$1]] został odblokowany.',
+'ipblocklist' => 'Lista zablokowanych użytkowników i adresów IP',
+'blocklistline' => '$1, $2 zablokował $3 ($4)',
+'infiniteblock' => 'na zawsze',
+'expiringblock' => 'wygasa $1',
+'anononlyblock' => 'tylko anonimowi',
+'createaccountblock' => 'Zablokowano możliwość utworzenia konta',
+'ipblocklistempty' => 'Lista zablokowanych użytkowników i adresów IP jest pusta',
+'blocklink' => 'zablokuj',
+'unblocklink' => 'odblokuj',
+'contribslink' => 'wkład',
+'autoblocker' => 'Zablokowano Cię automatycznie ponieważ używasz tego samego adresu IP co użytkownik "[[{{ns:user}}:$1|$1]]". Powód: "\'\'\'$2\'\'\'".',
+'blocklogpage' => 'Zablokowani',
+'blocklogentry' => 'zablokowano "[[$1]]", czas blokady: $2',
+'blocklogtext' => 'Poniżej znajduje się lista blokad założonych i zdjętych z poszczególnych adresów IP. Na liście nie znajdą się adresy IP, które zablokowano w sposób automatyczny. By przejrzeć listę obecnie aktywnych blokad, przejdź na stronę [[{{ns:Special}}:Ipblocklist|Zablokowane adresy IP]].',
+'unblocklogentry' => 'odblokowano "$1"',
+'range_block_disabled' => 'Możliwość blokowania zakresu numerów IP została wyłączona.',
+'ipb_expiry_invalid' => 'Błędny czas wygaśnięcia.',
+'ipb_already_blocked' => '"$1" jest już zablokowany.',
+'ip_range_invalid' => 'Niewłaściwy zakres adresów IP.',
+'ipb_cant_unblock' => 'Błąd: Blokada o ID $1 nie została znaleziona. Mogła ona zostać odblokowana wcześniej.',
+'proxyblockreason' => 'Twój adres IP został zablokowany - jest to otwarte proxy. Sprawę należy rozwiązać u dostawcy Internetu.',
+'proxyblocksuccess' => 'Wykonane.',
+'sorbsreason' => 'Twój adres IP znajduje się na liście serwerów open proxy w [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Twój adres IP znajduje się na liście serwerów open proxy w [http://www.sorbs.net SORBS] DNSBL. Nie możesz utworzyć konta.',
+
+# Developer tools
+#
+'lockdb' => 'Zablokuj bazę danych',
+'unlockdb' => 'Odblokuj bazę danych',
+'lockdbtext' => 'Zablokowanie bazy danych uniemożliwi wszystkim użytkownikom edycję stron, zmianę preferencji, edycję list obserwowanych artykułów oraz inne czynności wymagające dostępu do bazy danych. Potwierdź, proszę, że to jest zgodne z Twoimi zamiarami, i że odblokujesz bazę danych, gdy tylko zakończysz zadania administracyjne.',
+'unlockdbtext' => 'Odblokowanie bazy danych umożliwi wszystkim użytkownikom edycję stron, zmianę preferencji, edycję list obserwowanych artykułów oraz inne czynności związane ze zmianami w bazie danych. Potwierdź, proszę, że to jest zgodne z Twoimi zamiarami.',
+'lockconfirm' => 'Tak, naprawdę chcę zablokować bazę danych.',
+'unlockconfirm' => 'Tak, naprawdę chcę odblokować bazę danych.',
+'lockbtn' => 'Zablokuj bazę danych',
+'unlockbtn' => 'Odblokuj bazę danych',
+'locknoconfirm' => 'Nie zaznaczyłeś pola potwierdzenia.',
+'lockdbsuccesssub' => 'Baza danych została pomyślnie zablokowana',
+'unlockdbsuccesssub' => 'Blokada bazy danych usunięta',
+'lockdbsuccesstext' => 'Baza danych została zablokowana.<br />Pamiętaj by [[{{ns:Special}}:Unlockdb|usunąć blokadę]] po zakończeniu działań administracyjnych.',
+'unlockdbsuccesstext' => 'Baza danych została odblokowana.',
+'databasenotlocked' => 'Baza danych nie jest zablokowana.',
+
+# Make sysop
+'makesysoptitle' => 'Nadaj użytkownikowi uprawnienia administratora',
+'makesysoptext' => 'Ten formularz jest wykorzystywany przez użytkowników o statusie biurokraty do przyznawania innym użytkownikom praw administratora. Aby to uczynić, wpisz nazwę użytkownika i kliknij na przycisk.',
+'makesysopname' => 'Nazwa użytkownika:',
+'makesysopsubmit' => 'Przyznaj temu użytkownikowi uprawnienia administratora',
+'makesysopok' => '<b>Użytkownik "$1" otrzymał uprawnienia administratora</b>',
+'makesysopfail' => '<b>Użytkownik "$1" nie otrzymał uprawnienień administratora. (Czy wprowadziłeś poprawną nazwę użytkownika?)</b>',
+'setbureaucratflag' => 'Ustaw status biurokraty',
+'rightslog' => 'Uprawnienia',
+'rightslogtext' => 'Rejestr zmian uprawnień użytkowników.',
+'rightslogentry' => 'zmienił uprawnienia użytkownika $1 z "$2" na "$3"',
+'rights' => 'Uprawnienia:',
+'set_user_rights' => 'Zmień uprawnienia użytkownika',
+'user_rights_set' => '<b>Uprawnienia użytkownika "$1" zostały zmienione</b>',
+'set_rights_fail' => '<b>Uprawnienia użytkownika "$1" nie zostały zmienione. (Czy wprowadziłeś poprawną nazwę użytkownika?)</b>',
+'makesysop' => 'Przyznaj użytkownikowi uprawnienia administratora',
+'already_sysop' => 'Ten użytkownik jest już administratorem',
+'already_bureaucrat' => 'Ten użytkownik jest już biurokratą',
+'rightsnone' => '(podstawowe)',
+
+# Move page
+#
+'movepage' => 'Przenieś stronę',
+'movepagetext' => "Za pomocą poniższego formularza zmienisz nazwę strony, przenosząc jednocześnie jej historię.
+Pod starym tytułem zostanie umieszczona strona przekierowująca. Linki do starego tytułu pozostaną niezmienione.
+Upewnij się, że uwzględniasz podwójne lub zerwane przekierowania. Odpowiadasz za to, żeby linki odnosiły się do właściwych artykułów!
+
+Strona '''nie''' będzie przeniesiona jeśli:
+*jest pusta i nigdy nie była edytowana
+*jest stroną przekierowującą
+*strona o nowej nazwie już istnieje
+
+'''UWAGA!'''
+Może to być drastyczna lub nieprzewidywalna zmiana w przypadku popularnych stron; upewnij się co do konsekwencji tej operacji zanim się na nią zdecydujesz.",
+'movepagetalktext' => "Odpowiednia strona dyskusji, jeśli istnieje, będzie przeniesiona automatycznie, pod warunkiem, że:
+*nie przenosisz strony do innej przestrzeni nazw
+*nie istnieje strona dyskusji o nowej nazwie
+W takich przypadkach tekst dyskusji trzeba przenieść, i ewentualnie połączyć z istniejącym, ręcznie. Możesz też zrezygnować z przeniesienia dyskusji (poniższy ''checkbox'').",
+'movearticle' => 'Przenieś stronę',
+'movenologin' => 'Brak logowania',
+'movenologintext' => 'Musisz być zarejestrowanym i [[{{ns:Special}}:Userlogin|zalogowanym]] użytkownikiem aby móc przenieść stronę.',
+'newtitle' => 'Nowy tytuł',
+'movepagebtn' => 'Przenieś stronę',
+'pagemovedsub' => 'Przeniesienie powiodło się',
+'pagemovedtext' => 'Strona "[[:$1|$1]]" została przeniesiona do "[[:$2|$2]]".',
+'articleexists' => 'Strona o podanej nazwie już istnieje albo wybrana przez Ciebie nazwa nie jest poprawna. Wybierz, proszę, nową nazwę.',
+'talkexists' => 'Strona artykułu została przeniesiona, natomiast strona dyskusji nie - strona dyskusji o nowym tytule już istnieje. Połącz, proszę, teksty obu dyskusji ręcznie.',
+'movedto' => 'przeniesiono do',
+'movetalk' => 'Przenieś także stronę dyskusji, jeśli to możliwe.',
+'talkpagemoved' => 'Odpowiednia strona dyskusji także została przeniesiona.',
+'talkpagenotmoved' => 'Odpowiednia strona dyskusji <strong>nie</strong> została przeniesiona.',
+'1movedto2' => '[[$1]] przeniesiono do [[$2]]',
+'1movedto2_redir' => '[[$1]] przeniesiono do [[$2]] nad przekierowaniem',
+'movelogpage' => 'Przeniesione',
+'movelogpagetext' => 'Oto lista stron, które ostatnio zostały przeniesione.',
+'movereason' => 'Powód',
+'revertmove' => 'cofnij',
+'delete_and_move' => 'Usuń i przenieś',
+'delete_and_move_text' => '== Wymagane usunięcie ==
+
+Artykuł docelowy "[[:$1|$1]]" już istnieje. Czy chcesz go usunąć, by zrobić miejsce dla przenoszonego artykułu?',
+'delete_and_move_confirm' => 'Tak, usuń stronę',
+'delete_and_move_reason' => 'Usunięto by zrobić miejsce dla przenoszonego artykułu',
+'selfmove' => 'Nazwy stron źródłowej i docelowej są takie same. Strony nie można przenieść na nią samą!',
+'immobile_namespace' => 'Docelowy tytuł jest specjalnego typu. Nie można przenieść do tej przestrzeni nazw.',
+
+# Export
+
+'export' => 'Eksport stron',
+'exporttext' => 'Możesz wyeksportować tekst i historię edycji danej strony lub zestawu stron w postaci XML. Taki zrzut można potem (jak import już będzie działać) zaimportować do innej wiki działającej na oprogramowaniu MediaWiki, obrabiać lub po prostu trzymać dla zabawy.
+
+Żeby uzyskać kilka stron wpisz ich nazwy jedna pod drugą.
+
+Można również użyć łącza, np. [[{{ns:Special}}:Export/{{Mediawiki:mainpage}}]] dla strony {{Mediawiki:mainpage}}.',
+'exportcuronly' => 'Tylko bieżąca wersja, bez historii',
+'exportnohistory' => "----
+'''Uwaga:''' możliwość eksportowania pełnej historii stron została wyłączona.",
+'export-submit' => 'Eksportuj',
+
+# Namespace 8 related
+
+'allmessages' => 'Komunikaty systemowe',
+'allmessagesname' => 'Nazwa',
+'allmessagesdefault' => 'Tekst domyślny',
+'allmessagescurrent' => 'Tekst obecny',
+'allmessagestext' => 'Oto lista wszystkich komunikatów dostępnych w przestrzeni nazw MediaWiki:',
+'allmessagesnotsupportedUI' => 'Wybrany przez Ciebie język interfejsu <b>$1</b> nie jest wspierany przez stronę Special:Allmessages.',
+'allmessagesnotsupportedDB' => 'Strona \'\'\'Special:Allmessages\'\'\' nie może być użyta, ponieważ \'\'\'$wgUseDatabaseMessages\'\'\' jest wyłączone.',
+'allmessagesfilter' => 'Filtr nazw komunikatów:',
+'allmessagesmodified' => 'Pokaż tylko zmodyfikowane',
+
+# Thumbnails
+
+'thumbnail-more' => 'Powiększ',
+'missingimage' => '<b>Brak obrazka</b><br /><i>$1</i>',
+'filemissing' => 'Brak pliku',
+'thumbnail_error' => 'Błąd przy generowaniu miniatury: $1',
+
+# Special:Import
+'import' => 'Importuj strony',
+'importinterwiki' => 'Import transwiki',
+'import-interwiki-text' => 'Wybierz wiki i nazwę strony do importowania. Daty oraz nazwy autorów zostaną zachowane. Wszystkie operacje importu transwiki są odnotowywane w [[{{ns:Special}}:Log/import|rejestrze importu]].',
+'import-interwiki-history' => 'Kopiuj całą historię edycji tej strony',
+'import-interwiki-submit' => 'Importuj',
+'import-interwiki-namespace' => 'Przenieś strony do przestrzeni nazw:',
+'importtext' => 'Używając narzędzia Special:Export wyeksportuj plik ze źródłowej wiki, zapisz go na swoim dysku, a następnie prześlij go tutaj.',
+'importstart' => 'Trwa importowanie stron...',
+'import-revision-count' => '$1 {{PLURAL:$1|wersja|wersji}}',
+'importnopages' => 'Brak stron do importu.',
+'importfailed' => 'Import nie powiódł się: $1',
+'importunknownsource' => 'Nieznany format importu źródłowego',
+'importcantopen' => 'Nie można otworzyć importowanego pliku',
+'importbadinterwiki' => 'Błędny link interwiki',
+'importnotext' => 'Brak tekstu lub zawartości',
+'importsuccess' => 'Import zakończony powodzeniem!',
+'importhistoryconflict' => 'Wystąpił konflikt wersji (ta strona mogła zostać importowana już wcześniej)',
+'importnosources' => 'Możliwość bezpośredniego importu historii została wyłączona: nie zdefiniowano źródła.',
+'importnofile' => 'Importowany plik nie został załadowany.',
+'importuploaderror' => 'Przesłanie pliku nie powiodło się. Możliwe, że plik jest większy od dozwolonego limitu.',
+
+# import log
+'importlogpage' => 'Rejestr importu',
+'importlogpagetext' => 'Rejestr przeprowadzonych importów stron z innych serwisów wiki.',
+
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Przeszukaj serwis {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Oznacz zmiany jako drobne [alt-i]',
+'tooltip-save' => 'Zapisz zmiany [alt-s]',
+'tooltip-preview' => 'Obejrzyj efekt swojej edycji przed zapisaniem zmian! [alt-p]',
+'tooltip-diff' => 'Pokaż zmiany dokonane w tekście. [alt-v]',
+'tooltip-compareselectedversions' => 'Zobacz różnice między dwoma wybranymi wersjami strony. [alt-v]',
+'tooltip-watch' => 'Dodaj tę stronę do listy obserwowanych [alt-w]',
+
+# stylesheets
+'common.css' => '/* Kod CSS umieszczony tutaj zostanie zastosowany we wszystkich skórkach */',
+'monobook.css' => '/* Kod CSS umieszczony tutaj wpłynie na wygląd skórki Monobook */',
+
+'notacceptable' => 'Serwer wiki nie jest w stanie dostarczyć danych, które Twoja przeglądarka będzie w stanie odczytać.',
+
+# Attribution
+
+'anonymous' => 'Anonimowy użytkownicy serwisu {{SITENAME}}',
+'siteuser' => 'Użytkownik serwisu {{SITENAME}} - $1',
+'lastmodifiedatby' => 'Ostatnia edycja tej strony: $2, $1 (autor zmian: $3)',
+'and' => 'oraz',
+'othercontribs' => 'Inni autorzy: $1.',
+'others' => 'inni',
+'creditspage' => 'Autorzy',
+'nocredits' => 'Nie ma informacji o autorach tej strony.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Filtr antyspamowy',
+'spamprotectiontext' => 'Strona, którą chciałeś zapisać została zablokowana przez filtr antyspamowy. Najprawdopodobniej zostało to spowodowane przez link do zewnętrznej strony internetowej.',
+'spamprotectionmatch' => 'Tekst, który uruchomił nasz filtr antyspamowy to: $1',
+'subcategorycount' => '{{PLURAL:$1|Jest jedna podkategoria|Liczba podkategorii: $1}}',
+'categoryarticlecount' => '{{PLURAL:$1|Jest jeden artykuł w tej kategorii|Liczba artykułów w tej kategorii: $1}}',
+'listingcontinuesabbrev' => " c.d.",
+'spam_reverting' => 'Przywracanie ostatniej wersji nie zawierającej odnośników do $1',
+'spam_blanking' => 'Wszystkie wersje zawierały odnośniki do $1; czyszczenie strony',
+
+# Info page
+'infosubtitle' => 'Informacja o stronie',
+'numedits' => 'Liczba edycji (artykuł): $1',
+'numtalkedits' => 'Liczba edycji (strona dyskusji): $1',
+'numwatchers' => 'Liczba obserwujących: $1',
+'numauthors' => 'Liczba autorów (artykuł): $1',
+'numtalkauthors' => 'Liczba autorów (strona dyskusji): $1',
+
+# Math options
+'mw_math_png' => 'Zawsze jako PNG',
+'mw_math_simple' => 'HTML dla prostych, dla reszty PNG',
+'mw_math_html' => 'Spróbuj HTML; jeśli zawiedzie, to PNG',
+'mw_math_source' => 'Pozostaw w TeXu (dla przeglądarek tekstowych)',
+'mw_math_modern' => 'HTML, dla nowszych przeglądarek',
+'mw_math_mathml' => 'MathML (eksperymentalne)',
+
+# Patrolling
+'markaspatrolleddiff' => 'oznacz edycję jako "sprawdzoną"',
+'markaspatrolledtext' => 'Oznacz ten artykuł jako "sprawdzony"',
+'markedaspatrolled' => 'Sprawdzone',
+'markedaspatrolledtext' => 'Ta wersja została oznaczona jako "sprawdzona".',
+'rcpatroldisabled' => 'Wyłączono patrolowanie w "Ostatnich zmianach"',
+'rcpatroldisabledtext' => 'Patrolowanie w "Ostatnich zmianach" jest obecnie wyłączone',
+'markedaspatrollederror' => 'Nie można oznaczyć jako "sprawdzone"',
+'markedaspatrollederrortext' => 'Musisz wybrać wersję żeby oznaczyć ją jako "sprawdzoną".',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Moja osobista strona\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Strona użytkownika numeru IP spod którego edytujesz\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Moja strona dyskusji\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Dyskusja o edycjach z tego numeru IP\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Moje preferencje\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Lista stron obserwowanych\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Lista moich edycji\');
+ta[\'pt-login\'] = new Array(\'o\',\'Zachęcamy do zalogowania się, choć nie jest to obowiązkowe.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Zachęcamy do zalogowania się, choć nie jest to obowiązkowe\');
+ta[\'pt-logout\'] = new Array(\'\',\'Wylogowanie\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Dyskusja o zawartości tej strony.\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Możesz edytować tę stronę. Przed zapisaniem zmian użyj przycisku podgląd.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Dodaj swój komentarz do dyskusji\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Ta strona jest zabezpieczona. Możesz zobaczyć tekst źródłowy.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Starsze wersje tej strony.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Zabezpiecz tę stronę.\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Usuń tę stronę\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Przywróć wersję tej strony sprzed usunięcia\');
+ta[\'ca-move\'] = new Array(\'m\',\'Przenieś tę stronę.\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Nie masz wystarczających uprawnień do przeniesienia tej strony\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Dodaj tę stronę do listy obserwowanych\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Usuń tę stronę z listy obserwowanych\');
+ta[\'search\'] = new Array(\'f\',\'Szukaj w wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Strona główna\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Zobacz stronę główną\');
+ta[\'n-portal\'] = new Array(\'\',\'O projekcie, co możesz zrobić, gdzie możesz znaleźć informacje\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Informacje o aktualnych wydarzeniach\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Lista ostatnich zmian w artykułach\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Pokaż losowo wybraną stronę\');
+ta[\'n-help\'] = new Array(\'\',\'Zapoznaj się z obsługą wiki\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Wesprzyj nas\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Pokaż listę stron linkujących do tego artykułu\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Ostatnie zmiany w stronach linkujących do tej strony\');
+ta[\'feed-rss\'] = new Array(\'\',\'Kanał RSS dla tej strony\');
+ta[\'feed-atom\'] = new Array(\'\',\'Kanał Atom dla tej strony\');
+ta[\'t-contributions\'] = new Array(\'\',\'Pokaż listę edycji tego użytkownika\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Wyślij e-mail do tego użytkownika\');
+ta[\'t-upload\'] = new Array(\'u\',\'Wyślij plik na serwer\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Lista wszystkich specjalnych stron\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Zobacz stronę artykułu\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Zobacz stronę osobistą użytkownika\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Pokaż stronę pliku\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'To jest specjalna strona. Nie możesz jej edytować.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Zobacz stronę projektu\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Zobacz stronę grafiki\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Zobacz komunikat systemowy\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Zobacz szablon\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Zobacz stronę pomocy\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Zobacz stronę kategorii\');',
+
+# image deletion
+'deletedrevision' => 'Skasowano poprzednie wersje $1.',
+
+# browsing diffs
+'previousdiff' => '← Poprzednia edycja',
+'nextdiff' => 'Następna edycja →',
+
+'imagemaxsize' => 'Na stronach opisu pokaż grafiki przeskalowane do rozdzielczości:',
+'thumbsize' => 'Rozmiar miniaturki:',
+'showbigimage' => 'Pobierz grafikę w wyższej rozdzielczości ($1x$2, $3 KB)',
+
+'newimages' => 'Najnowsze grafiki',
+'showhidebots' => '($1 boty)',
+'noimages' => 'Nic.',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Użytkownik:',
+'speciallogtitlelabel' => 'Tytuł:',
+
+'passwordtooshort' => 'Twoje hasło jest za krótkie. Musi mieć co najmniej $1 znaków.',
+
+# Media Warning
+'mediawarning' => "'''Uwaga:''' Ten plik może zawierać złośliwy kod, otwierając go możesz zarazić swój system.<hr />",
+
+'fileinfo' => '$1KB, typ MIME: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadane',
+'metadata-help' => 'Niniejszy plik zawiera dodatkowe informacje, prawdopodobnie dodane przez aparat cyfrowy lub skaner. Jeśli plik był modyfikowany, dane mogą być częściowo błędne.',
+'metadata-expand' => 'Pokaż szczegóły',
+'metadata-collapse' => 'Ukryj szczegóły',
+
+# Exif tags
+'exif-imagewidth' => 'Szerokość',
+'exif-imagelength' => 'Wysokość',
+'exif-compression' => 'Schemat kompresji',
+'exif-orientation' => 'Orientacja',
+'exif-planarconfiguration' => 'Rozkład danych',
+'exif-xresolution' => 'rozdzielczosć w poziomie',
+'exif-yresolution' => 'rozdzielczość w pionie',
+'exif-resolutionunit' => 'Jednostki rozdzielczośći X i Y',
+'exif-jpeginterchangeformatlength' => 'Wielkość pliku JPEG',
+'exif-whitepoint' => 'Punkty bieli',
+'exif-ycbcrcoefficients' => 'Współczynniki macierzy transformacji przestrzeni barw',
+'exif-datetime' => 'Data i czas zmiany pliku',
+'exif-imagedescription' => 'Tytuł',
+'exif-make' => 'Producent aparatu',
+'exif-model' => 'Model aparatu',
+'exif-software' => 'Oprogramowanie',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Właściciel praw autorskich',
+'exif-exifversion' => 'Wersja EXIF',
+'exif-flashpixversion' => 'Obsługiwana wersja Flashpix',
+'exif-colorspace' => 'Przestrzeń kolorów',
+'exif-componentsconfiguration' => 'Znaczenie elementów',
+'exif-compressedbitsperpixel' => 'Tryb kompresji grafiki',
+'exif-makernote' => 'Informacje producenta',
+'exif-usercomment' => 'Komentarz',
+'exif-relatedsoundfile' => 'Zawiera plik audio',
+'exif-datetimeoriginal' => 'Data i czas utworzenia',
+'exif-datetimedigitized' => 'Data i czas utworzenia kopii cyfrowej',
+'exif-exposuretime' => 'Czas ekspozycji',
+'exif-exposuretime-format' => '$1 s. ($2)',
+'exif-fnumber' => 'Wartość przesłony',
+'exif-exposureprogram' => 'Program ekspozycji',
+'exif-oecf' => 'Optyczno-elektroniczna zamiana wektora',
+'exif-shutterspeedvalue' => 'Czas naświetlania',
+'exif-aperturevalue' => 'Wartość przesłony',
+'exif-brightnessvalue' => 'Jasność',
+'exif-exposurebiasvalue' => 'Nastawienie ekspozycji',
+'exif-maxaperturevalue' => 'Maksymalna wartość przysłony',
+'exif-subjectdistance' => 'Odległość od obiektu',
+'exif-meteringmode' => 'Tryb pomiaru',
+'exif-lightsource' => 'Źródło światła',
+'exif-flash' => 'Lampa błyskowa',
+'exif-focallength' => 'Długość ogniskowej soczewki',
+'exif-subjectarea' => 'Otoczenie obiektu',
+'exif-flashenergy' => 'Moc lampy błyskowej',
+'exif-focalplanexresolution' => 'Rozdzielczość w poziomie płaszczyzny odwzorowania obiektywu',
+'exif-focalplaneyresolution' => 'Rozdzielczość w pionie płaszczyzny odwzorowania obiektywu',
+'exif-focalplaneresolutionunit' => 'Jednostka rozdzielczości płaszczyzny odwzorowania obiektywu',
+'exif-subjectlocation' => 'Umiejscowienie obiektu',
+'exif-exposureindex' => 'Tabela ekspozycji',
+'exif-sensingmethod' => 'Metoda pomiaru',
+'exif-filesource' => 'Plik źródłowy',
+'exif-scenetype' => 'Typ sceny',
+'exif-cfapattern' => 'Wzór CFA',
+'exif-customrendered' => 'Rodzaj obróbki',
+'exif-exposuremode' => 'Ekspozycja',
+'exif-whitebalance' => 'Balans bieli',
+'exif-digitalzoomratio' => 'Przybliżenie cyfrowe',
+'exif-focallengthin35mmfilm' => 'Długość ogniskowej na filmie 35 mm',
+'exif-scenecapturetype' => 'Rodzaj sceny',
+'exif-gaincontrol' => 'Kontrola sceny',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Nasycenie barw',
+'exif-sharpness' => 'Ostrość',
+'exif-devicesettingdescription' => 'Opis ustawień urządzenia',
+'exif-subjectdistancerange' => 'Zakres odległości od obiektu',
+'exif-imageuniqueid' => 'ID grafiki',
+'exif-gpsversionid' => 'Wersja GPS',
+'exif-gpslatituderef' => 'Północna lub południowa szerokość geograficzna',
+'exif-gpslatitude' => 'Szerokość geograficzna',
+'exif-gpslongituderef' => 'Wschodnia lub zachodnia długość geograficzna',
+'exif-gpslongitude' => 'Długość geograficzna',
+'exif-gpsaltituderef' => 'Wielkość odwoławcza',
+'exif-gpsaltitude' => 'Wysokość',
+'exif-gpstimestamp' => 'Czas GPS (zegar atomowy)',
+'exif-gpssatellites' => 'Satelity użyte do pomiaru',
+'exif-gpsstatus' => 'Otrzymany status',
+'exif-gpsmeasuremode' => 'Tryb pomiaru',
+'exif-gpsdop' => 'Precyzja pomiaru',
+'exif-gpsspeedref' => 'Jednostka prędkości',
+'exif-gpsspeed' => 'Prędkość odbiornika GPS',
+'exif-gpstrackref' => 'Poprawka pomiędzy kierunkiem i celem',
+'exif-gpstrack' => 'Kierunek ruchu',
+'exif-gpsdestlatitude' => 'Szerokość geograficzna celu',
+'exif-gpsdestlongitude' => 'Długość geograficzna celu',
+'exif-gpsdestdistance' => 'Odległość od celu',
+'exif-gpsprocessingmethod' => 'Nazwa metody GPS',
+'exif-gpsareainformation' => 'Nazwa przestrzeni GPS',
+'exif-gpsdatestamp' => 'Data GPS',
+
+# Exif attributes
+
+'exif-compression-1' => 'Nieskompresowany',
+
+'exif-orientation-1' => 'Normalna',
+'exif-orientation-2' => 'Odwrócona w poziomie',
+'exif-orientation-3' => 'Obrócona o 180°',
+'exif-orientation-4' => 'Odwrócona w pionie',
+'exif-orientation-5' => 'Obrót o 90° przeciwnie do wskazówek zegara i odwrócenie w pionie',
+'exif-orientation-6' => 'Obrót o 90° zgodnie ze wskazówkami zegara',
+'exif-orientation-7' => 'Obrót o 90° zgodnie do wskazówek zegara i odwrót w pionie',
+'exif-orientation-8' => 'Obrót o 90° przeciwnie do wskazówek zegara',
+
+'exif-planarconfiguration-1' => 'format masywny',
+'exif-planarconfiguration-2' => 'format powierzchniowy',
+
+'exif-componentsconfiguration-0' => 'nie istnieje',
+
+'exif-exposureprogram-0' => 'Nie zdefiniowany',
+'exif-exposureprogram-1' => 'Manualny',
+'exif-exposureprogram-2' => 'Normalny',
+'exif-exposureprogram-3' => 'Preselekcja przesłony',
+'exif-exposureprogram-4' => 'Preselekcja migawki',
+'exif-exposureprogram-5' => 'Kreatywny (duża głębia ostrości)',
+'exif-exposureprogram-6' => 'Aktywny (duża szybkość migawki)',
+'exif-exposureprogram-7' => 'Tryb portretowy (dla zdjęć z bliska, z rozmazanym tłem)',
+'exif-exposureprogram-8' => 'Tryb krajobrazowy (dla dalekich zdjęć z ostrym tłem)',
+
+'exif-subjectdistance-value' => '$1 metrów',
+
+'exif-meteringmode-0' => 'Nieznany',
+'exif-meteringmode-1' => 'Średni',
+'exif-meteringmode-2' => 'Średnia ważona',
+'exif-meteringmode-3' => 'Punktowy',
+'exif-meteringmode-4' => 'Wielopunktowy',
+'exif-meteringmode-5' => 'Próbkowy',
+'exif-meteringmode-6' => 'Częściowy',
+'exif-meteringmode-255' => 'Inny',
+
+'exif-lightsource-0' => 'Nieznane',
+'exif-lightsource-1' => 'Światło dzienne',
+'exif-lightsource-2' => 'Światło jarzeniowe',
+'exif-lightsource-3' => 'Światło sztuczne (żarowe)',
+'exif-lightsource-4' => 'Lampa błyskowa',
+'exif-lightsource-9' => 'Dobra pogoda',
+'exif-lightsource-10' => 'Zachmurzona pogoda',
+'exif-lightsource-11' => 'Cienie',
+'exif-lightsource-12' => 'Jarzeniowe światło dnia (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Jarzeniowe białe (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Jarzeniowe miękkie (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Jarzeniowe białe (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Światło standardowe A',
+'exif-lightsource-18' => 'Światło standardowe B',
+'exif-lightsource-19' => 'Światło standardowe C',
+'exif-lightsource-24' => 'Żarowe studyjne',
+'exif-lightsource-255' => 'Inne źródło światła',
+
+'exif-focalplaneresolutionunit-2' => 'cale',
+
+'exif-sensingmethod-1' => 'Niezdefiniowana',
+'exif-sensingmethod-7' => 'Trilinearna',
+
+'exif-scenetype-1' => 'Obiekt fotografowany bezpośrednio',
+
+'exif-customrendered-0' => 'Tryb normalny',
+'exif-customrendered-1' => 'Tryb zmienny',
+
+'exif-exposuremode-0' => 'Automatyczna',
+'exif-exposuremode-1' => 'Manualna',
+'exif-exposuremode-2' => 'Wieloprzysłonowa',
+
+'exif-whitebalance-0' => 'Automatyczny balans bieli',
+'exif-whitebalance-1' => 'Ręczny balans bieli',
+
+'exif-scenecapturetype-0' => 'Standardowy',
+'exif-scenecapturetype-1' => 'Krajobraz',
+'exif-scenecapturetype-2' => 'Portret',
+'exif-scenecapturetype-3' => 'Scena nocna',
+
+'exif-gaincontrol-0' => 'Brak',
+'exif-gaincontrol-1' => 'Niskie wzmocnienie',
+'exif-gaincontrol-2' => 'Wysokie wzmocnienie',
+'exif-gaincontrol-3' => 'Niskie osłabienie',
+'exif-gaincontrol-4' => 'Wysokie osłabienie',
+
+'exif-contrast-0' => 'Normalny',
+'exif-contrast-1' => 'Miękki',
+'exif-contrast-2' => 'Twardy',
+
+'exif-saturation-0' => 'Normalne',
+'exif-saturation-1' => 'Niskie',
+'exif-saturation-2' => 'Wysokie',
+
+'exif-sharpness-0' => 'Normalna',
+'exif-sharpness-1' => 'Miękka',
+'exif-sharpness-2' => 'Twarda',
+
+'exif-subjectdistancerange-0' => 'Nieznana',
+'exif-subjectdistancerange-1' => 'Makro',
+'exif-subjectdistancerange-2' => 'Widok z bliska',
+'exif-subjectdistancerange-3' => 'Widok z daleka',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Szerokość geograficzna północna',
+'exif-gpslatitude-s' => 'Szerokość geograficzna południowa',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Długość geograficzna wschodnia',
+'exif-gpslongitude-w' => 'Długość geograficzna zachodnia',
+
+'exif-gpsstatus-a' => 'Pomiar w trakcie',
+'exif-gpsstatus-v' => 'Pomiar interoperacyjny',
+
+'exif-gpsmeasuremode-2' => '2-wymiarowy',
+'exif-gpsmeasuremode-3' => '3-wymiarowy',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometry na godzinę',
+'exif-gpsspeed-m' => 'Mile na godzinę',
+'exif-gpsspeed-n' => 'Węzły',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Prawdziwy kierunek',
+'exif-gpsdirection-m' => 'Kierunek magnetyczny',
+
+# external editor support
+'edit-externally' => 'Edytuj ten plik używając zewnętrznej aplikacji',
+'edit-externally-help' => 'Zobacz więcej informacji o używaniu [http://meta.wikimedia.org/wiki/Help:External_editors zewnętrznych edytorów].',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'wszystkie',
+'imagelistall' => 'wszystkich',
+'watchlistall1' => 'wszystkie',
+'watchlistall2' => 'wszystkie',
+'namespacesall' => 'wszystkie',
+
+# E-mail address confirmation
+'confirmemail' => 'Potwierdź adres e-mail',
+'confirmemail_noemail' => 'Nie podałeś prawidłowego adresu e-mail w [[Special:Preferences|preferencjach]].',
+'confirmemail_text' => 'Wymagane jest potwierdzenie adresu e-mail przed użyciem funkcji pocztowych. Wciśnij przycisk poniżej aby wysłać na swój adres list uwierzytelniający. W liście znajdziesz link zawierający kod: załaduj go do przeglądarki aby potwierdzić swój adres.',
+'confirmemail_send' => 'Wyślij kod potwierdzenia',
+'confirmemail_sent' => 'E-mail uwierzytelniający został wysłany.',
+'confirmemail_sendfailed' => 'Nie udało się wsłać maila potwierdzającego. Proszę sprawdzić adres.
+
+Program zwrócił komunikat: $1',
+'confirmemail_invalid' => 'Błędny kod potwierdzenia. Kod może być przedawniony.',
+'confirmemail_needlogin' => 'Musisz $1 aby potwierdzić adres email.',
+'confirmemail_success' => 'Adres e-mail został zatwierdzony. Możesz się zalogować i cieszyć możliwościami wiki.',
+'confirmemail_loggedin' => 'Twój adres email został potwierdzony.',
+'confirmemail_error' => 'Pojawiły się błędy przy zapisywaniu potwierdzenia.',
+
+'confirmemail_subject' => '{{SITENAME}} - potwierdzenie adresu e-mail',
+'confirmemail_body' => 'Ktoś łącząc się z komputera o adresie IP $1 zarejestrował w serwisie
+{{SITENAME}} konto "$2" podając niniejszy adres email.
+
+Aby potwierdzić, że to Ty zarejestrowałeś/aś to konto oraz aby włączyć
+wszystkie funkcje wymagające działającego adresu email, otwórz w swojej
+przeglądarce ten link:
+
+$3
+
+Jeśli to NIE TY zarejestrowałeś/aś to konto, NIE KLIKAJ W POWYŻSZY LINK.
+Kod zawarty w linku straci ważność $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Użyj dokładnego wyrażenia',
+'searchfulltext' => 'Szukaj w całych tekstach',
+'createarticle' => 'Utwórz artykuł',
+
+# Scary transclusion
+'scarytranscludefailed' => '[Nie powiodło się pobranie szablonu dla $1]',
+'scarytranscludetoolong' => '[URL za długi]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Sygnały Trackback dla tego artykułu:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Usuń])',
+'trackbackdeleteok' => 'Trackback został usunięty.',
+
+# delete conflict
+
+'deletedwhileediting' => 'Uwaga: Ta strona została usunięta po tym, jak rozpoczęłeś jej edycję!',
+'confirmrecreate' => "Użytkownik [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|dyskusja]]) usunął tę stronę po tym jak rozpocząłeś jego edycję, podając jako powód usunięcia:
+: '''$2'''
+Potwierdź chęć odtworzenia tej strony.",
+'recreate' => 'Odtwórz',
+'tooltip-recreate' => 'Odtworzono stronę pomimo jej wcześniejszego usunięcia.',
+
+# HTML dump
+'redirectingto' => 'Przechodzenie do [[:$1|$1]]...',
+
+# action=purge
+'confirm_purge' => 'Wyczyścić bufor dla tej strony?
+
+$1',
+'confirm_purge_button' => 'Wyczyść',
+
+'youhavenewmessagesmulti' => 'Masz nowe wiadomości: $1',
+'searchcontaining' => "Szukaj artykułów zawierających ''$1''.",
+'searchnamed' => "Szukaj artykułów nazywających się ''$1''.",
+'articletitles' => "Artykuły zaczynające się od ''$1''.",
+'hideresults' => 'Ukryj wyniki',
+
+# DISPLAYTITLE
+'displaytitle' => '(Link do tej strony to [[:$1|$1]])',
+
+'loginlanguagelabel' => 'Język: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; poprzednia strona',
+'imgmultipagenext' => 'następna strona &rarr;',
+'imgmultigo' => 'Przejdź',
+'imgmultigotopre' => 'Przejdź na stronę',
+
+# Table pager
+'ascending_abbrev' => 'rosn.',
+'descending_abbrev' => 'mal.',
+'table_pager_next' => 'Następna strona',
+'table_pager_prev' => 'Poprzednia strona',
+'table_pager_first' => 'Pierwsza strona',
+'table_pager_last' => 'Ostatnia strona',
+'table_pager_limit' => 'Pokaż $1 obiektów na stronę',
+'table_pager_limit_submit' => 'Pokaż',
+'table_pager_empty' => 'Brak wyników',
+
+);
+
+?>
diff --git a/languages/messages/MessagesPms.php b/languages/messages/MessagesPms.php
new file mode 100644
index 000000000000..dfd516d48a8d
--- /dev/null
+++ b/languages/messages/MessagesPms.php
@@ -0,0 +1,1698 @@
+<?php
+/** Piedmontese (Piemontèis)
+ * Users are bilingual in Piedmontese and Italian, using Italian as template.
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @bug 5362
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>, Jens Frank
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, Jens Frank
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+$fallback = 'it';
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Discussion',
+ NS_USER => 'Utent',
+ NS_USER_TALK => 'Ciaciarade',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discussion_ant_sla_$1',
+ NS_IMAGE => 'Figura',
+ NS_IMAGE_TALK => 'Discussion_dla_figura',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discussion_dla_MediaWiki',
+ NS_TEMPLATE => 'Stamp',
+ NS_TEMPLATE_TALK => 'Discussion_dlë_stamp',
+ NS_HELP => 'Agiut',
+ NS_HELP_TALK => 'Discussion_ant_sl\'agiut',
+ NS_CATEGORY => 'Categorìa',
+ NS_CATEGORY_TALK => 'Discussion_ant_sla_categorìa'
+);
+
+
+$messages = array(
+'tog-underline' => 'Anliure con la sotliniadura',
+'tog-highlightbroken' => 'Buta an evidensa j\'anliure che a men-o a<br />
+dj\'artìcol ancó pa scrit',
+'tog-justify' => 'Paràgraf: giustificà',
+'tog-hideminor' => 'Stërma le modifiche cite<br />ant sla pàgina "Ùltime Modìfiche"',
+'tog-extendwatchlist' => 'Slarga la funsion "ten sot euj" an manera che a la smon-a tute le modìfiche che as peulo fesse',
+'tog-usenewrc' => 'Ùltime modìfiche an bela forma (a-i va Javascript)',
+'tog-numberheadings' => 'Tìtoj ëd paràgraf<br />che as nùmero daspërlor',
+'tog-showtoolbar' => 'Mostra la bara dj\'utiss (a-i va Javascript)',
+'tog-editondblclick' => 'Dobia sgnacà për modifiché l\'artìcol<br />(a-i va JavaScript)',
+'tog-editsection' => 'Abìlita la modìfica dle session con j\'anliure [modìfica]',
+'tog-editsectiononrightclick'=> 'Abilité la modìfica dle session ën sgnacand-je ansima<br /> al tìtol col tast drit dël rat (a-i va Javascript)',
+'tog-showtoc' => 'Buta le tàole dij contnù<br />(për j\'artìcoj che l\'han pì che 3 session)',
+'tog-rememberpassword' => 'Vis-te la ciav<br />(nen mach për na session<br />- a l\'ha da manca dij cookies)',
+'tog-editwidth' => 'Quàder ëd modìfica slargà<br />al màssim',
+'tog-watchcreations' => 'Gionta le pàgine che i creo mi a la lista ëd lòn che im ten-o sot euj',
+'tog-watchdefault' => 'Notìfica dj\'articoli neuv e ëd coj modificà',
+'tog-minordefault' => 'Marca tute le modìfica coma cite<br />(mach coma predefinission dla casela)',
+'tog-previewontop' => 'Smon-e la preuva dzora al quàder ëd modìfica dël test e nen sota',
+'tog-previewonfirst' => 'Smon na preuva la prima vira che as fa na modìfica',
+'tog-nocache' => 'Dòvra pa la memorisassion \'\'cache\'\' për le pàgine',
+'tog-enotifwatchlistpages'=> 'Mand-me un messagi an pòsta eletrònica quand a-i son dle modìfiche a le pàgine',
+'tog-enotifusertalkpages'=> 'Mand-me un messagi ëd pòsta eletrònica quand a-i son dle modìfiche a mia pàgina dle ciaciarade',
+'tog-enotifminoredits' => 'Mand-me un messagi an pòsta bele che për le modìfiche cite',
+'tog-enotifrevealaddr' => 'Lassa che a së s-ciàira mia adrëssa ëd pòsta eletrònica ant ij messagi ëd notìfica',
+'tog-shownumberswatching'=> 'Smon ël nùmer d\'utent che as ten-o la pàgina sot euj',
+'tog-fancysig' => 'Modìfica mai la firma da coma a l\'é ambelessì (as dòvra për fesse na firma fòra stàndard)',
+'tog-externaleditor' => 'Dòvra coma stàndard n\'editor ëd test estern',
+'tog-externaldiff' => 'Dòvra për stàndard un programa "diff" estern',
+'tog-showjumplinks' => 'Dòvra j\'anliure d\'acessibilità dla sòrt "Va a"',
+'tog-uselivepreview' => 'Dòvra la funsion \'\'Preuva dal viv\'\' (a-i va JavaScript e a l\'é mach sperimental)',
+'tog-autopatrol' => 'Marca mie modìfiche coma \'\'già verificà\'\'',
+'tog-forceeditsummary' => 'Ciama conferma se ël somari dla modìfica a l\'é veujd',
+'tog-watchlisthideown' => 'Stërma mie modìfiche ant la ròba che im ten-o sot euj',
+'tog-watchlisthidebots' => 'Stërma le modìfiche faite daj trigomiro ant la lista dle ròbe che im ten-o sot euj',
+'underline-always' => 'Sempe',
+'underline-never' => 'Mai',
+'underline-default' => 'Dòvra lë stàndard dël programma ëd navigassion (browser)',
+'skinpreview' => '(Preuva)',
+'sunday' => 'Dumìnica',
+'monday' => 'Lun-es',
+'tuesday' => 'Martes',
+'wednesday' => 'Merco',
+'thursday' => 'Giòbia',
+'friday' => 'Vënner',
+'saturday' => 'Saba',
+'january' => 'Gené',
+'february' => 'Fërvé',
+'march' => 'Mars',
+'april' => 'Avril',
+'may_long' => 'Magg',
+'june' => 'Giugn',
+'july' => 'Luj',
+'august' => 'Aost',
+'september' => 'Stémber',
+'october' => 'Otóber',
+'november' => 'Novémber',
+'december' => 'Dzémber',
+'jan' => 'Gen',
+'feb' => 'Fër',
+'mar' => 'Mar',
+'apr' => 'Avr',
+'may' => 'Mag',
+'jun' => 'Giu',
+'jul' => 'Luj',
+'aug' => 'Aos',
+'sep' => 'Ste',
+'oct' => 'Oto',
+'nov' => 'Nov',
+'dec' => 'Dze',
+'categories' => 'Categorìe',
+'pagecategories' => '{{PLURAL:$1|Categorìa|Categorìe}}',
+'category_header' => 'Artìcoj ant la categorìa "$1"',
+'subcategories' => 'Sotacategorìe',
+'mainpage' => 'Intrada',
+'mainpagetext' => '<big>\'\'\'MediaWiki a l\'é staita anstalà a la perfession.\'\'\'</big>',
+'mainpagedocfooter' => 'Che a varda la [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide User\'s Guide] ([[belavans]] për adess a-i é mach n\'anglèis) për avej dj\'anformassion suplementar ant sël coma dovré ël programa dla wiki.
+
+== Për anandiesse a travajé ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikipedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]',
+'portal' => 'Piòla',
+'portal-url' => 'Project:Piòla',
+'about' => 'A propòsit ëd',
+'aboutsite' => 'A propòsit ëd {{SITENAME}}',
+'aboutpage' => 'Project:A propòsit',
+'article' => 'Pàgina ëd contnù',
+'help' => 'Agiut',
+'helppage' => 'Project:Agiut',
+'bugreports' => 'Malfunsionament',
+'bugreportspage' => 'Project:Malfunsionament',
+'sitesupport' => 'Oferte',
+'sitesupport-url' => 'Project:Oferte',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => 'Manual dë spiegassion',
+'newwindow' => '(as deurb ant na fnestra neuva)',
+'edithelppage' => 'Project:Coma scrive n\'artìcol',
+'cancel' => 'Scancela',
+'qbfind' => 'Treuva',
+'qbbrowse' => 'Sfeuja',
+'qbedit' => 'Modìfica',
+'qbpageoptions' => 'Opsion dla pàgina',
+'qbpageinfo' => 'Informassioni rësguard a la pagina',
+'qbmyoptions' => 'Mie opsion',
+'qbspecialpages' => 'Pàgine speciaj',
+'moredotdotdot' => 'Dë pì...',
+'mypage' => 'Mia pàgina',
+'mytalk' => 'Mie ciaciarade',
+'anontalk' => 'Ciaciarade për st\'adrëssa IP-sì',
+'navigation' => 'Navigassion',
+'metadata_help' => 'Metadat (consulté [[{{ns:project}}:Metadat]] për avej pì d\'anformassion):',
+'currentevents' => 'Neuve',
+'currentevents-url' => 'Project:Neuve',
+'disclaimers' => 'Difide',
+'disclaimerpage' => 'Project:Avertense generaj',
+'privacy' => 'Polìtica ëd confindensialità',
+'privacypage' => 'Project:Polìtica ëd confidensialità',
+'errorpagetitle' => 'Eror',
+'returnto' => 'Torna andré a $1.',
+'tagline' => 'Da {{SITENAME}}.',
+'search' => 'Sërca',
+'searchbutton' => 'Sërca',
+'go' => 'Va',
+'searcharticle' => 'Va',
+'history' => 'Version pì veje',
+'history_short' => 'Stòria',
+'updatedmarker' => 'Agiornà da \'nt l\'ùltima vira che i son passà',
+'info_short' => 'Anformassion',
+'printableversion' => 'Version bon-a për stampé',
+'permalink' => 'Anliura fissa',
+'print' => 'Stampa',
+'edit' => 'Modìfica',
+'editthispage' => 'Modìfica st\'artìcol-sì',
+'delete' => 'Scancela',
+'deletethispage' => 'Scancela pàgina',
+'undelete_short' => 'Disdëscancela {{PLURAL:$1|na modìfica|$1 modìfiche}}',
+'protect' => 'Protegg',
+'protectthispage' => 'Protegg sta pàgina-sì',
+'unprotect' => 'gava la protession',
+'unprotectthispage' => 'Gava via la protession',
+'newpage' => 'Pàgina neuva',
+'talkpage' => 'Discussion',
+'specialpage' => 'Pàgina Special',
+'personaltools' => 'Utiss personaj',
+'postcomment' => 'Gionta un coment',
+'articlepage' => 'Che a varda l\'articol',
+'talk' => 'Discussion',
+'views' => 'vìsite',
+'toolbox' => 'utiss',
+'userpage' => 'Che a varda la pàgina Utent',
+'projectpage' => 'Che a varda la pàgina ëd servissi',
+'imagepage' => 'Pàgina dla figura',
+'viewtalkpage' => 'Vardé la discussion',
+'otherlanguages' => 'Àutre lenghe',
+'redirectedfrom' => '(Ridiression da $1)',
+'autoredircomment' => 'Ridiression anvers a [[$1]]',
+'redirectpagesub' => 'Pàgina ëd ridiression',
+'lastmodifiedat' => 'Modificà l\'ùltima vira al $2, $1.',
+'viewcount' => 'St\'artìcol-sì a l\'é stait lesù {{plural:$1|na vira|$1 vire}}.',
+'copyright' => 'Ël contnù a resta disponibil sota a na licensa $1.',
+'protectedpage' => 'Pàgina proteta',
+'jumpto' => 'Va a:',
+'jumptonavigation' => 'navigassion',
+'jumptosearch' => 'arsërca',
+'badaccess' => 'Përmess nen giust',
+'versionrequired' => 'A-i va për fòrsa la version $1 ëd MediaWiki',
+'versionrequiredtext' => 'Për dovrè sta pàgina-sì a-i va la version $1 dël programa MediaWiki. Che a varda [[Special:Version]]',
+'ok' => 'Va bin',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Pijait da "$1"',
+'youhavenewmessages' => 'A l\'ha $1 ($2).',
+'newmessageslink' => 'ëd messagi neuv',
+'newmessagesdifflink' => 'A-i é chèich-còs ëd diferent da \'nt l\'ùltima revision',
+'editsection' => 'modìfica',
+'editold' => 'modìfica',
+'editsectionhint' => 'I soma dapress a modifiché la session: $1',
+'toc' => 'Contnù',
+'showtoc' => 'smon',
+'hidetoc' => 'stërma',
+'thisisdeleted' => 'Veul-lo vardé ò ripristiné $1?',
+'viewdeleted' => 'Veul-lo vardé $1?',
+'restorelink' => '{{PLURAL:$1|na modìfica scancelà|$1 modìfiche scancelà}}',
+'feedlinks' => 'Fluss:',
+'feed-invalid' => 'Modalità ëd sotoscrission dël fluss nen vàlida.',
+'nstab-main' => 'Artìcol',
+'nstab-user' => 'Pàgina dl\'utent',
+'nstab-media' => 'Pàgina multimedial',
+'nstab-special' => 'Special',
+'nstab-project' => 'Pàgina ëd servissi',
+'nstab-image' => 'Figura',
+'nstab-mediawiki' => 'Messagi',
+'nstab-template' => 'Stamp',
+'nstab-help' => 'Agiut',
+'nstab-category' => 'Categorìa',
+'nosuchaction' => 'Operassione nen arconossùa',
+'nosuchactiontext' => 'L\'operassion che a l\'ha ciamà a l\'é nen arconossùa dal programa MediaWiki',
+'nosuchspecialpage' => 'A-i é pa gnun-a pàgina special tan-me cola che chiel a l\'ha ciamà.',
+'nospecialpagetext' => 'A l\'ha ciamà na pàgina special che a l\'é pa staita arconossùa dal programa MediaWiki, ò pura a l\'é nen disponibila.',
+'error' => 'Eror',
+'databaseerror' => 'Eror ant la base dat',
+'dberrortext' => 'Eror ëd sintassi ant la domanda mandà a la base dat.
+L\'ùltima domanda mandà a la base dat a l\'é staita:
+<blockquote><tt>$1</tt></blockquote>
+da \'nt la funsion "<tt>$2</tt>".
+MySQL a l\'ha dane andré n\'eror "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'A-i é staje n\'eror ant la sintassi d\'anterogassion dla base dat.
+L\'ùltima anterogassion a l\'é staita:
+"$1"
+da andrinta a la funsion "$2".
+MySQL a l\'ha dane n\'eror "$3: $4"',
+'noconnect' => 'Conession a la base dat falà ansima a $1',
+'nodb' => 'Selession da la base dat $1 falìa',
+'cachederror' => 'Costa a l\'é mach na còpia memorisà dla pàgina che a l\'ha ciamà, donca a podrìa ëdcò nen esse agiornà.',
+'laggedslavemode' => 'Avis: la pàgina a podrìa ëdcò nen mostré tute soe modìfiche.',
+'readonly' => 'Acess a la base dat sërà për chèich temp.',
+'enterlockreason' => 'Che a buta na rason për ël blocagi, con andrinta data e ora ëd quand che a stima che a sarà gavà.',
+'readonlytext' => 'La base dat ëd {{SITENAME}} për adess a l\'é blocà, e as peulo pa fesse nì dle neuve imission, nì dle modìfiche, con tute le probabilità për n\'operassion ëd manutension dël server. Se a l\'é parej motobin ampressa la base a sarà torna doèrta.<br />
+L\'aministrator che a l\'ha blocala a l\'ha lassà sto messagi-sì:
+<p>:$1',
+'missingarticle' => 'La base dat a l\'ha pa trovà ël test ëd la pàgina "$1", che però a l\'avrìa pro dovù trové.<br />
+Sòn a l\'é pa n\'eror dla base dat, ma a l\'ha l\'ària dë esse na gran-a dël programa.<br />
+Për piasì, che a-j segnala sossì a n\'[[{{ns:project}}:Aministrator|aministrator]] dël sistema, specificand tìtol dla pàgina e ora dl\'assident.',
+'readonly_lag' => 'La base dat a l\'é staita blocà n\'automàtich antramentr che che le màchine dël circuito secondari (slave) as buto an pari con cole dël prinsipal (master)',
+'internalerror' => 'Eror intern',
+'filecopyerror' => 'A l\'é pa stait possibil copié l\'archivi "$1" coma "$2".',
+'filerenameerror' => 'A l\'é pa podusse cangeje nòm a l\'archivi "$1" an "$2".',
+'filedeleteerror' => 'A l\'é pa podusse scancelé l\'archivi "$1".',
+'filenotfound' => ' A l\'é pa trovasse l\'archivi "$1".',
+'unexpected' => 'Valor che i së spitavo pa: "$1"="$2".',
+'formerror' => 'Eror: la domanda a l\'é staita mandà mal',
+'badarticleerror' => 'N\'operassion parej as peul pa fesse ansima a sta pàgina-sì.',
+'cannotdelete' => 'As peul pa scancelesse la pàgina, l\'archivi ò la figura che a veul scancelé.',
+'badtitle' => 'Tìtol nen giust',
+'badtitletext' => 'La pàgina che a l\'ha ciamà a peul pa esse mostrà. A podrìa tratesse ëd na pàgina nen bon-a, veujda, ò pura a podrìa ëdcò esse n\'eror ant n\'anliura antra lenghe diferente ò tra diferente version ëd {{SITENAME}}.',
+'perfdisabled' => 'An dëspias, ma costa funsion a l\'é nen disponibila ant j\'ore ëd pì gran acess a la base dat, për nen ralenté l\'acess dj\'Utent!<br />Che a preuva torna antra 2 bot e 4 ore dòp mesdì (UTC).<br /><br />Mersì.',
+'perfdisabledsub' => 'Ambelessì a-i é na còpia salvà da $1:',
+'perfcached' => 'Sòn a l\'é stait memorisà an local e podrìa ëdcò nen esse agiornà:',
+'perfcachedts' => 'Lòn che a-j ven dapress a sossì a l\'é pijait da \'nt na còpia local "cache" dla base dat. L\'ùltim agiornament a l\'é dël: $1.',
+'wrong_wfQuery_params' => 'Paràmetro nen giust për wfQuery()<br />
+Funsion: $1<br />
+Query: $2',
+'viewsource' => 'Vardé la sorgiss',
+'viewsourcefor' => 'ëd $1',
+'protectedtext' => 'Costa pàgina-sì a l\'é staita blocà për nen che as podèissa modifichela;
+a-i son vàire motiv përchè a peula esse stait faita na ròba parej,
+për piasì che a varda [[Project:Pàgina proteta|polìtiche ëd protession]] për savejne dë pì.
+
+Ant tute le manere a peul s-ciairé e volend copié la sorgiss dla pàgina:',
+'protectedinterface' => 'Costa pàgina-sì a l\'ha andrinta un chèich-còs che a fa part d\'antërfacia dël programa che a dòvro tùit; donca a l\'é proteta për evité che a-i rivo dle ròbe brute.',
+'editinginterface' => '\'\'\'A l\'euj!:\'\'\' A sta modificand na pàgina che as dòvra për generé ël test dl\'antërfassa dël programa. Le modìfiche faite ambelessì a l\'avran efet dë cangé l\'antërfassa për j\'àutri Utent.',
+'sqlhidden' => '(l\'anterogassion SQL a l\'é stërmà)',
+'logouttitle' => 'Seurte da \'nt ël sistema',
+'logouttext' => 'A l\'é sortù da \'nt ël sistema.
+A peul tiré anans a dovré {{SITENAME}} coma Utent anonim, ò pura a peul rintré torna ant ël sistema con l\'istess stranòm che a dovrava prima, ò con un diferent.',
+'welcomecreation' => '<h2>Bin avnù, $1!</h2><p>Sò cont a l\'è stait creà.<br />Mersì për avej sërnù dë giutene a fé chërse {{SITENAME}}.<br />Për fé {{SITENAME}} pì soa, e përchè a sia pì belfé dovrela, che as dësmentia nen dë compilé la pàgina dij "sò gust".',
+'loginpagetitle' => 'rintré ant ël sistema',
+'yourname' => 'Sò stranòm',
+'yourpassword' => 'Soa ciav',
+'yourpasswordagain' => 'Che a bata torna soa ciav',
+'remembermypassword' => 'Vis-te mia ciav për vàire session (për podej felo a fa da manca che un a l\'abia ij \'\'cookies\'\' abilità).',
+'yourdomainname' => 'Sò domini',
+'externaldberror' => 'Ò che a l\'é rivaje n\'eror d\'autenticassion esterna, ò pura a l\'é chiel (chila) che a l\'é nen autorisà a agiornesse sò cont estern.',
+'loginproblem' => '<b>A l\'é staje n\'eror dëmentré che as provava a rintré ant ël sistema.</b><br />
+Che a preuva n\'àutra vira, miraco che sta vira a andèissa mai bin!',
+'alreadyloggedin' => '<strong>Utent $1, che a varda che a l\'é già andrinta al sistema, a l\'ha pa dë manca dë felo torna!</strong><br />',
+'login' => 'Rintré ant ël sistema',
+'loginprompt' => 'Che a varda mach che a venta avej ij [[cookies]] abilità për podej rintré an {{SITENAME}}.',
+'userlogin' => 'rintré ant ël sistema',
+'logout' => 'Seurte da \'nt ël sistema',
+'userlogout' => 'seurte dal sistema',
+'notloggedin' => 'a l\'é pa ant ël sistema',
+'nologin' => 'Ha-lo ancó nen sò cont? $1.',
+'nologinlink' => 'creésse un cont.',
+'createaccount' => 'Crea un cont neuv',
+'gotaccount' => 'Ha-lo già un sò cont? $1.',
+'gotaccountlink' => 'Rintré ant ël sistema',
+'createaccountmail' => 'për pòsta eletrònica',
+'badretype' => 'Le doe ciav che a l\'ha scrivù a resto diferente antra lor, e a venta che a sio mideme.',
+'userexists' => 'An dëspias.<br />Lë stranòm che a l\'ha sërnusse a l\'é già dovrà da n\'àutr Utent.<br />
+Për son i-j ciamoma dë sërn-se në stranòm diferent.',
+'youremail' => 'Soa adrëssa ëd pòsta eletrònica',
+'username' => 'Stranòm:',
+'uid' => 'ID dl\'utent:',
+'yourrealname' => 'Nòm vèir *',
+'yourlanguage' => 'Lenga:',
+'yourvariant' => 'Variant',
+'yournick' => 'Sò stranòm (për firmé)',
+'badsig' => 'Soa forma a l\'é nen giusta, che a controla le istrussion HTML.',
+'email' => 'pòsta eletrònica',
+'prefs-help-email-enotif'=> 'Costa adrëssa-sì as dòvra ëdcò për mandeve dle notìfiche, se i l\'eve abilità n\'opsion che a në génera.',
+'prefs-help-realname' => '* Nòm vèir (opsional): se i sërne da butelo ambelessì a sarà dovrà për deve mérit ëd vòstr travaj.',
+'loginerror' => 'Eror ën rintrand ant ël sistema',
+'prefs-help-email' => '* Adrëssa ëd pòsta eletrònica (opsional): ën butandlo i feve an manera che la gent a peula contateve passand për vòstra pàgina dle ciaciarade sensa dë manca che a sapia chi i seve e che adrëssa che i l\'eve.',
+'nocookiesnew' => 'Sò cont a l\'é doèrt, ma chiel (ò chila) a l\'ha nen podù rintré ant ël sistema.
+{{SITENAME}} a dòvra ij [[cookies]] për fé rintré la gent ant sò sistema. [[Belavans]] chiel a l\'ha pa ij cookies abilità.
+Për piasì, che as j\'abìlita e peuj che a preuva torna a rintré con sò stranòm e soa ciav.',
+'nocookieslogin' => '{{SITENAME}} a dòvra ij [[cookies]] për fé rintré la gent ant sò sistema. [[Belavans]] chiel a l\'ha pa ij cookies abilità. Pëër piasì, che a j\'abìlita e peuj che a preuva torna.',
+'noname' => 'Lë stranòm che a l\'ha batù as peul pa dovresse, as peul nen creésse un cont Utent con ës nòm-sì.',
+'loginsuccesstitle' => 'Compliment! A l\'é pen-a rintrà ant ël sistema. A-i é pa staje gnun eror.',
+'loginsuccess' => 'A l\'ha avù ël përmess ëd conession al server ëd {{SITENAME}} con lë stranòm utent ëd "$1".',
+'nosuchuser' => 'Atension<br /><br /> dapress a na verìfica, a n\'arsulta pa gnin Utent che a l\'abia stranòm "$1".<br /><br />
+Për piasì, che a contròla ël nòm che a l\'ha batù, ò pura che a dòvra la domanda ambelessì sota për fé un cont Utent neuv.',
+'nosuchusershort' => 'A-i é pa gnun utent che as ciama "$1". Për piasì, che a contròla se a l\'ha scrit tut giust.',
+'nouserspecified' => 'A venta che a specìfica në stranòm utent',
+'wrongpassword' => 'La ciav batùa a l\'é pa giusta.<br /><br />Che a preuva torna, për piasì.',
+'wrongpasswordempty' => 'A l\'ha butà na ciav veujda. Për piasì, che a preuva torna.',
+'mailmypassword' => 'Mandme na neuva ciav con un messagi ëd pòsta eletrònica',
+'passwordremindertitle' => 'Servissi për visé la paròla ciav ëd {{SITENAME}}',
+'passwordremindertext' => 'Cheidun (a l\'é belfé che a sia stait pròpe chiel, da \'nt l\'adrëssa IP $1)
+a l\'ha ciamà che i-j mandèisso na neuva paròla ciav për rintré ant ël sistema ëd {{SITENAME}} ($4).
+La ciav për l\'Utent "$2" adess a resta "$3".
+Për rason ëd sicurëssa, a sarìa mej che chiel a la dovrèissa për rintré ant ël sistema pì ampressa che a peul, e che tut sùbit as la cambièissa con un-a che a sern daspërchiel.',
+'noemail' => 'An arsulta pa gnun-a casela ëd pòsta eletrònica për l\'Utent "$1".',
+'passwordsent' => 'Na neuva paròla ciav a l\'é staita mandà a l\'adrëssa eletrònica registrà për l\'Utent "$1".
+Për piasì, che a la dòvra sùbit për rintré ant ël sistema pen-a che a l\'arsèiv.',
+'eauthentsent' => 'A l\'adrëssa che a l\'ha dane i l\'oma mandaje un messagi ëd pòsta eletrònica për conferma.
+Anans che qualsëssìa àutr messagi ëd pòsta a ven-a mandà a \'s cont-sì, a venta che a a fasa coma che a-j diso dë fé ant ël messagi, për confermé che ës cont a l\'é da bon sò.',
+'mailerror' => 'Eror ën mandand via un messagi ëd pòsta eletrònica: $1',
+'acct_creation_throttle_hit'=> 'Darmagi, ma chiel (chila) a l\'ha già creasse $1 cont. A peul pa pì deurb-ne dj\'àutri.',
+'emailauthenticated' => 'Soa adrëssa ëd pòsta eletrònica a l\'é staita autenticà ël $1.',
+'emailnotauthenticated' => 'Soa adrëssa ëd pòsta eletrònica a l\'é ancó pa staita autenticà.
+Da qualsëssìa ëd coste funsion a sarà mandà gnun messagi fin che chiel (chila) a s\'auténtica nen.',
+'noemailprefs' => '<strong>Che a specìfica n\'adrëssa ëd pòsta eletrònica se a veul dovré coste funsion-sì.</strong>',
+'emailconfirmlink' => 'Che an conferma sa adrëssa ëd pòsta eletrònica',
+'invalidemailaddress' => 'Costa adrëssa ëd pòsta eletrònica-sì as peul nen pijesse përchè a l\'ha na forma nen bon-a.
+Për piasì che a buta n\'adrëssa scrita giusta ò che a lassa ël camp veujd.',
+'accountcreated' => 'Cont creà',
+'accountcreatedtext' => 'Ël cont Utent për $1 a l\'é stait creà.',
+'bold_sample' => 'Test an grassèt',
+'bold_tip' => 'Test an grassèt',
+'italic_sample' => 'Test an corsiv',
+'italic_tip' => 'Test an corsiv',
+'link_sample' => 'Tìtol dl\'anliura',
+'link_tip' => 'Anliura interna',
+'extlink_sample' => 'http://www.esempi.com tìtol dl\'anliura',
+'extlink_tip' => 'Anliura esterna (che as visa dë buté ël prefiss http://)',
+'headline_sample' => 'Antestassion dl\'artìcol',
+'headline_tip' => 'Antestassion dë scond livel',
+'math_sample' => 'Che a buta la fòrmula ambelessì',
+'math_tip' => 'Fòrmula matemàtica (LaTeX)',
+'nowiki_sample' => 'Che a buta ël test nen formatà ambelessì',
+'nowiki_tip' => 'Lassé un tòch ëd test fòra dla formatassion dla wiki',
+'image_sample' => 'Esempi.jpg',
+'image_tip' => 'Figura anglobà ant ël test',
+'media_sample' => 'Esempi.ogg',
+'media_tip' => 'Anliura a n\'archivi multimedial',
+'sig_tip' => 'Firma butand data e ora',
+'hr_tip' => 'Riga orisontal (da dovresse nen tròp soèns)',
+'summary' => 'Somari',
+'subject' => 'Sogèt',
+'minoredit' => 'Costa-sì a l\'è na modìfica cita',
+'watchthis' => 'Ten sot euj st\'artìcol-sì',
+'savearticle' => 'Salva sta pàgina',
+'preview' => 'Preuva',
+'showpreview' => 'Mostra na preuva',
+'showlivepreview' => 'Funsion \'\'Preuva dal viv\'\'',
+'showdiff' => 'Smon-me le modìfiche',
+'anoneditwarning' => 'A l\'é ancó nen rintrà ant ël sistema. Soa adrëssa IP a sarà registrà ant la stòria dle modìfiche dë sta pàgina-sì.',
+'missingsummary' => '\'\'\'Nòta:\'\'\' a l\'ha pa butà gnun somari dla modìfica. Se a sgnaca Salva n\'àutra vira, soa modìfica a resterà salvà sensa pa ëd somari.',
+'missingcommenttext' => 'Për piasì che a buta un coment ambelessì sota.',
+'blockedtitle' => 'Belavans cost ëstranòm-sì a resta col ëd n\'utent che a l\'é stait disabilità a fé \'d modìfiche a j\'articoj.',
+'blockedtext' => 'Sò stranòm ò pura soa adrëssa IP a son stait blocà da $1.<br />
+La rason dël blocagi a l\'é:<br />
+:\'\'$2\'\'<p>
+Se a veul, a peul contaté $1 ò pura un dj\'àutri [[Project:administrators|aministrator]] për discute d\'ës blocagi.
+
+Che a nòta mach che a peul nen dovré la funsion "Mand-je un messagi eletrònich a st\'utent-sì" se a l\'ha nen buta na soa adrëssa ëd pòsta ant ij [[Special:Preferences|sò gust]].
+
+Soa adrëssa IP a la resta $3. Për piasì che a lo fasa present ant soe comunicassion an materia.',
+'blockedoriginalsource' => 'La sorgiss ëd \'\'\'$1\'\'\' a së s-ciàira ambelessì sota:',
+'blockededitsource' => 'Ël test ëd le \'\'\'soe modìfiche\'\'\' a \'\'\'$1\'\'\' a së s-ciàira ambelessì sota:',
+'whitelistedittitle' => 'Sòn as peul pa fesse nen rintrand ant ël sistema',
+'whitelistedittext' => 'A venta $1 për podej fé dle modìfiche.',
+'whitelistreadtitle' => 'Sòn as peul pa fesse nen rintrand ant ël sistema',
+'whitelistreadtext' => 'A l\'ha da [[Special:Userlogin|rintré ant ël sistema]] për podej lese dle pàgine.',
+'whitelistacctitle' => 'Che a në scusa, ma a peul nen creésse un cont.',
+'whitelistacctext' => 'Për podej creé dij cont ant sta wiki-sì a l\'ha da [[Special:Userlogin|rintré ant ël sistema]] e avej ël drit da creéje.',
+'confirmedittitle' => 'Confermé l\'adrëssa postal për podej fé dle modìfiche',
+'confirmedittext' => 'A dev confermé soa adrëssa ëd pòsta eletrònica, anans che modifiché dle pàgine. Për piasì, che a convalida soa adrëssa ën dovrand la pàgina [[Special:Preferences|mè gust]].',
+'loginreqtitle' => 'a venta rintré ant ël sistema',
+'loginreqlink' => 'rintré ant ël sistema',
+'loginreqpagetext' => 'Che a pòrta passiensa, ma a dev $1 për podej vëdde dj\'àutre pàgine.',
+'accmailtitle' => 'Ciav spedìa.',
+'accmailtext' => 'La paròla ciav për "$1" a l\'é staita mandà a $2.',
+'newarticle' => '(Neuv)',
+'newarticletext' => 'Che a scriva sò test ambelessì.',
+'anontalkpagetext' => '----\'\'Costa a l\'é la pàgina ëd ciaciarade che a s-ciàira n\'utent anònim che a l\'é ancó pa dorbusse un cont, ò pura che a lo dòvra nen. Nen savend chi che a sia chiel (chila) i l\'oma da dovré ël nùmer [[IP address]] për deje n\'identificassion. Belavans, ës nùmer-sì a peul esse dovrà da vàire Utent. J\'Utent anònim che a l\'han l\'impression d\'arsèive dij coment sensa sust a dovrìo [[Special:Userlogin|creésse sò cont ò pura rintré ant ël sistema]] për evité dë fé confusion con dj\'àutri Utent che a peulo avej l\'istess nùmer IP.\'\'',
+'noarticletext' => '(St\'artìcol-sì a l\'é veujd, a podrìa për gentilëssa anandielo chiel, ò pura ciamé la scancelassion dë sta pàgina)',
+'clearyourcache' => '\'\'\'Nòta:\'\'\' na vira che i l\'ha salvà, a peul esse che a-j fasa da manca da passé via la memorisassion (cache) dël sò programa ëd navigassion (browser) për podej ës-ciairé le modìfiche.
+*\'\'\'Mozilla / Firefox / Safari:\'\'\' Che a ten-a sgnacà \'\'Shift\'\' antramentr che a sgnaca col rat ansima a \'\'Reload\'\', ò pura che a sgnaca tut ansema \'\'Ctrl-Shift-R\'\' (\'\'Cmd-Shift-R\'\' ansima a j\'Apple Mac);
+*\'\'\'IE:\'\'\' che a ten-a sgnacà \'\'Ctrl\'\' antramentr che a sgnaca col rat ansima a \'\'Refresh\'\', ò pura che a sgnaca tut ansema \'\'Ctrl-F5\'\';
+*\'\'\'Konqueror:\'\'\': a basta mach sgnaché ël boton \'\'Reload\'\', ò pura sgnaché \'\'F5\'\';
+*\'\'\'Opera\'\'\' j\'utent a peulo avej da manca dë veujdé \'d continùo soa memorisassion (cache) andrinta a \'\'Tools&rarr;Preferences\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Drita:</strong> che a dòvra ël boton \'Mostra na preuva\' për controlé l\'efet ëd sò còdes CSS/JS anans che salvelo.',
+'usercsspreview' => '\'\'\'Che a varda che a lòn che a s-ciàira a l\'é nomach na preuva ëd sò CSS, che salvà a resta ancó nen!\'\'\'',
+'userjspreview' => '\'\'\'Che as visa che a l\'é mach antramentr che as fa na preuva ëd sò Javascript, che a l\'é ancó pa stait salvà!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Avis:\'\'\' A-i é pa gnun-a facia "$1". Che as visa che le pàgine .css e .js che un as fa daspërchiel a dòvro tute minùscole për tìtol, pr\'esempi Utent:Scaramacaj/monobook.css [[nopà]] che Utent:Scaramacaj/Monobook.css.',
+'updated' => '(Agiornà)',
+'note' => '<strong>NÒTA:</strong>',
+'previewnote' => 'Che a ten-a mach present che costa-sì a l\'é nomach na PREUVA, e che soa version a l\'é ancó pa staita salvà!',
+'session_fail_preview' => '<strong>Darmagi! I l\'oma pa podù processé soa modìfica per via che a son përdusse për la stra ij dat ëd session.
+Për piasì che a preuva n\'àutra vira. Se a dovèissa mai torna riveje sossì, che a preuva a seurte dal sistema e peuj torna a rintré.</strong>',
+'previewconflict' => 'Costa preuva a-j mostra ël test dl\'articol ambelessì dzora. Se a sërn dë salvelo, a l\'é parej che a lo s-ciaireran ëdcò tuti j\'àutri Utent.',
+'session_fail_preview_html'=> '<strong>Darmagi! I l\'oma nen podù processé soa modìfica ën essend che a son përdusse për la stra ij dat ëd session.</strong>
+
+\'\'Contand che sta wiki-sì a mostra dël còdes HTMP nen filtrà, la preuva a ven ëstarmà coma precaussion contra a dij possibij atach fait an Javascript.\'\'
+
+<strong>Se sòn a l\'èra na modìfica normal, për piasì che a preuva a fela n\'àutra vira. Se a dovèissa mai torna deje dle gran-e, che a preuva a seurte da \'nt ël sistema e peuj torna a rintré.</strong>',
+'importing' => 'I soma dapress a amporté $1',
+'editing' => 'Modìfica ëd $1',
+'editinguser' => 'Modìfica ëd $1',
+'editingsection' => 'I soma dapress a modifiché $1 (session)',
+'editingcomment' => 'I soma dapress a modifiché $1 (coment)',
+'editconflict' => 'Conflit d\'edission: $1',
+'explainconflict' => 'Cheidun d\'àutr a l\'ha salvà soa version dl\'artìcol antramentré che chiel (chila) as prontava la soa.<br />
+Ël quàder ëd modìfica dë dzora a mostra ël test ëd l\'articol coma a resta adess (visadì, lòn che a-i é ant sla Ragnà). Soe modìfiche a stan ant ël quàder dë sota.
+Ën volend a peul gionté soe modìfiche ant ël quàder dë dzora.
+<b>Mach</b> ël test ant ël quàder dë dzora a sarà salvà, ën sgnacand ël boton "Salva".<br />',
+'yourtext' => 'Sò test',
+'storedversion' => 'Version memorisà',
+'nonunicodebrowser' => '<strong>A L\'EUJ! Sò programa ëd navigassion (browser) a travaja pa giust con lë stàndard unicode. I soma obligà a dovré dij truschin përchè a peula salvesse sò artìcoj sensa problema: ij caràter che a son nen ASCII a jë s-ciairerà ant ël quàder ëd modìfica test coma còdes esadecimaj.</strong>',
+'editingold' => '<strong>CHE A FASA MACH ATENSION: che a sta fasend-je dle modìfiche a na version nen agiornà dl\'artìcol.<br />
+Se a la salva parej, lòn che a l\'era stait fait dapress a sta revision-sì as përderà d\'autut.</strong>',
+'yourdiff' => 'Diferense',
+'copyrightwarning' => 'Che a ten-a për piasì present che tute le contribussion a {{SITENAME}} as considero daite sota a na licensa ëd la sòrt $2 (che a varda $1 për avej pì \'d detaj).
+Se a veul nen che sò test a peula esse modificà e distribuì da qualsëssìa person-a sensa gnun-a limitassion ëd gnun-a sòrt, che a lo buta pa ansima a {{SITENAME}}, ma pitòst che as lo pùblica ansima a un sò sit personal.<br />
+Ën mandand ës test-sì chiel (chila) as fa garant sota soa responsabilità che ël test a l\'ha scrivusslo despërchiel (daspërchila) coma original, ò pura che a l\'ha tracopialo da na sorgiss ëd pùblich domini, ò da n\'àutra sorgiss dla midema sòrt, ò pura che chiel (chila) a l\'ha arseivù autorisassion scrita a dovré sto test e che sòn a peul dimostrelo.<br />
+<strong>DOVRÉ PA MAI DËL MATERIAL COERTÀ DA DRIT D\'AUTOR (c) SENSA AVEJ N\'AUTORISASSION SCRITA PËR FELO!!!</strong>',
+'copyrightwarning2' => 'Për piasì, che a ten-a present che tute le contribussion a {{SITENAME}} a peulo esse modificà ò scancelà da dj\'àutri contributor. Se a veul nen che lòn che a scriv a ven-a modificà sensa limitassion ëd gnun-a sòrt, che a lo manda nen ambelessì.<br />
+Ant l\'istess temp, ën mandand dël material un as pija la responsabilità dë dì che a l\'ha scrivusslo daspërchiel (ò daspërchila), ò pura che a l\'ha copialo da na sorgiss ëd domini pùblich, ò pura da \'nt n\'àutra sorgiss dla midema sòrt (che a varda $1 për avej pì d\'anformassion).
+<strong>CHE A MANDA PA DËL MATERIAL COERTÀ DA DRIT D\'AUTOR SENSA AVEJ AVÙ ËL PËRMESS SCRIT DË FELO!</strong>',
+'longpagewarning' => '<strong>CHE A TEN-A PRESENT!: Sta pàgina-sì a l\'é longa $1 kb; chèich
+programa ëd navigassion a podrìa avej dle gran-e a modifiché dle pàgine che a-j rivo a brus
+ò pura a passo ij 32 kb.
+Për piasì che a varda se a-i fussa mai la possibilità dë divide sto paginon an vàire tòch pì cit.</strong>',
+'longpageerror' => '<strong>EROR: Ël test che a l\'ha mandà a l\'é longh $1 kb, che a resta pì che ël
+lìmit màssim ëd $2 kb. Parej as peul nen salvesse. A venta che a në fasa vàire
+pàgine diferente për rintré ant ij lìmit tècnich.</strong>',
+'readonlywarning' => '<strong>AVIS: La base dat a l\'é staita blocà për manutension,
+e donca a peudrà pa salvesse soe modìfiche tut sùbit. A peul esse che
+a-j ven-a còmod copiesse via sò test e butesslo da na part për salvelo peuj.</strong>',
+'protectedpagewarning' => '<strong>AVIS: costa pàgina-sì a l\'é staita blocà an manera che mach dj\'utent con la qualìfica da aministrator a peulo modifichelo. Che a varda le [[Project:Pàgina proteta|polìtiche për la protession dle pàgine]] për savejne dë pì.</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Nòta:\'\'\'costa pàgina-sì a l\'é staita protegiùa an manera che mach j\'utent registrà a peulo modifichela.',
+'templatesused' => 'Stamp dovrà dzora a sta pàgina-sì:',
+'nocreatetitle' => 'Creassion ëd pàgine limità',
+'nocreatetext' => 'Cost sit-sì a l\'ha limità la possibilità ëd creé dle pàgine neuve.
+A peul torné andaré e modifiché na pàgine che a-i é già, ò pura [[Special:Userlogin|rintré ant ël sistema ò deurb-se un cont]].',
+'revhistory' => 'Stòria dle version dë sta pàgina-sì.',
+'nohistory' => 'La stòria dle version dë sta pàgina-sì a l\'é pa trovasse.',
+'revnotfound' => 'Version nen trovà',
+'revnotfoundtext' => 'La version prima dl\'artìcol che a l\'ha ciamà a l\'é pa staita trovà.
+Che as controla për piasì l\'adrëssa (URL) che a l\'ha dovrà për rivé a sta pàgina-sì.',
+'loadhist' => 'I soma antramentr che i carioma la stòria dë sta pàgina-sì',
+'currentrev' => 'Versione dël dì d\'ancheuj',
+'revisionasof' => 'Revision $1',
+'revision-info' => 'Revision al $1; $2',
+'previousrevision' => '←Version pì veja',
+'nextrevision' => 'Revision pì neuve→',
+'currentrevisionlink' => 'vardé la version corenta',
+'cur' => 'cor',
+'next' => 'anans',
+'last' => 'andaré',
+'orig' => 'orig',
+'histlegend' => 'Confront antra version diferente: che as selession-a le casele dle version che a veul e peui che a sgnaca ël boton për anandié ël process.<br />
+Legenda: (cor) = diferense con la version corenta,
+(prim) = diferense con la version prima, M = modìfica cita',
+'deletedrev' => '[scancelà]',
+'histfirst' => 'Prima',
+'histlast' => 'Ùltima',
+'rev-deleted-comment' => '(coment gavà)',
+'rev-deleted-user' => '(stranòm gavà)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Costa revision dla pàgina-sì a l\'é staita gavà via da \'nt j\'archivi pùblich.
+A peul esse che a sio restajne chèich marca ant ël [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} Registr ëd jë scancelament].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Costa revision dla pàgina-sì a l\'é staita gavà via da \'nt j\'archivi pùblich.
+Coma aministrator d\'ës sit-sì chiel a peul ës-ciairela;
+a peul esse che a sio restajne chèich marca ant ël [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} Registr ëd jë scancelament].
+</div>',
+'rev-delundel' => 'mostra/stërma',
+'history-feed-title' => 'Stòria',
+'history-feed-description'=> 'Stòria dla pàgina ansima a sto sit-sì',
+'history-feed-item-nocomment'=> '$1 al $2',
+'history-feed-empty' => 'La pàgina che a l\'ha ciamà a-i é pa; a podrìa esse staita scancelà da \'nt ël sit, ò pura tramudà a n\'àutr nòm.
+
+Che a verìfica con la [[Special:Arserca|pàgina d\'arserca]] se a-i fusso mai dj\'àutre pàgine che a podèisso andeje bin.',
+'revisiondelete' => 'Scancela/disdëscancela revision',
+'revdelete-selected' => 'Revision selessionà për [[:$1]]:',
+'revdelete-text' => 'Le version scancelà a së s-ciaireran sempe ant la stòria dla pàgina,
+ma sò test al pùblich a-j andran pì nen.
+
+J\'àutri aministrator ëd sta wiki-sì a saran ancó sempe bon a s-ciairé ël contnù stërmà
+e a podran disdëscancelelo andré con la midema antërfacia, sempe che a sia nen staita butà
+na restrission adissional da j\'operator dël sit.',
+'revdelete-legend' => 'But-je coste limitassion-sì a le version scancelà:',
+'revdelete-hide-text' => 'Stërma ël test dla revision',
+'revdelete-hide-comment'=> 'Stërma ël coment a la modìfica',
+'revdelete-hide-user' => 'Stërma lë stranòm ò l\'adrëssa IP dël contributor',
+'revdelete-hide-restricted'=> 'But-je ste restrission-sì a j\'aministrator tan-me a j\'àutri',
+'revdelete-log' => 'Coment për ël registr:',
+'revdelete-submit' => 'But-jlo a la version selessionà',
+'revdelete-logentry' => 'visibilità dla revision cangià për [[$1]]',
+'difference' => '(Diferense antra revision)',
+'loadingrev' => 'i soma antramentr che i carioma la revision për diferensa',
+'lineno' => 'Riga $1:',
+'editcurrent' => 'Modìfica la version corenta dë sta pàgina-sì',
+'selectnewerversionfordiff'=> 'Selession-a na version pì neuva për fé paragon',
+'selectolderversionfordiff'=> 'Selession-a na version pì veja për fé paragon',
+'compareselectedversions'=> 'Paragon-a le version selessionà',
+'searchresults' => 'Arsultà dl\'arserca',
+'searchresulttext' => 'Per avej pì d\'anformassion ant sl\'arserca interna ëd {{SITENAME}}, che a varda [[Project:Ricerca|Arserca ant la {{SITENAME}}]].',
+'searchsubtitle' => 'Domanda "[[:$1]]"',
+'searchsubtitleinvalid' => 'Domanda "$1"',
+'badquery' => 'Domanda mal faita',
+'badquerytext' => 'Soa domanda a l\'é pa podusse processé.
+Sòn a podrìa dipende da lòn che chiel (chila) a l\'ha arsercà na paròla con manch che tre caràter.
+Ò pura a podrìa esse che a l\'abia scrivù mal la domanda, pr\'esempi "bleu and and pom"
+Për piasì, che a preuva torna.',
+'matchtotals' => 'L\'arserca për la vos "$1" a l\'ha trovà<br />$2 rëscontr ant ij tìtoj ëd j\'artìcoj e<br />$3 rëscontr ant ij test ëd j\'artìcoj.',
+'noexactmatch' => '\'\'\'La pàgina "$1" a-i é pa.\'\'\' As peul [[:$1|creéla d\'amblé]].',
+'titlematches' => 'Ant ij tìtoj dj\'artìcoj',
+'notitlematches' => 'La vos che a l\'ha ciamà a l\'é pa trovasse antrames aj tìtoj dj\'articol',
+'textmatches' => 'Ant ël test ëd j\'artìcoj',
+'notextmatches' => 'La vos che a l\'ha ciamà a l\'é pa trovasse antrames aj test dj\'articol',
+'prevn' => 'ij $1 prima',
+'nextn' => 'ij $1 peuj',
+'viewprevnext' => 'Che a varda ($1) ($2) ($3).',
+'showingresults' => 'Ambelessì sota <b>$1</b> arsultà, a parte dal nùmer #<b>$2</b>.',
+'showingresultsnum' => 'Për sòlit a së smon-o <b>$3</b> arzultà a parte da #<b>$2</b>.',
+'nonefound' => '<strong>Nòta</strong>: l\'arserchè dle paròle soèns dovrà, coma "avej" ò "esse", che a son pa indicisà, a peul dé n\'arsultà negativ, tan-me buté pì che na paròla da arserché (che a ven-o fòra mach cole pàgine andoa le paròle arsercà a-i son tute ansema).',
+'powersearch' => 'Arserca',
+'powersearchtext' => 'Sërca antra jë spassi nominaj:<br />
+$1<br />
+$2 Elenca le ridiression &nbsp; sërca për $3 $9',
+'searchdisabled' => 'L\'arserca anterna ëd {{SITENAME}} a l\'é nen abilità; për adess a peul prové a dovré un motor d\'arserca estern coma Google. (Però che a ten-a present che ij contnù ëd {{SITENAME}} listà ant ij motor pùblich a podrìo ëdcò esse nen d\'autut agiornà)',
+'blanknamespace' => '(Prinsipal)',
+'preferences' => 'Mè gust',
+'prefsnologin' => 'A l\'é ancó pa rintrà ant ël sistema',
+'prefsnologintext' => 'A dev [[Special:Userlogin|rintré ant ël sistema]]
+për podej specifiché ij sò gust.',
+'prefsreset' => 'Ij "sò gust" a son stait pijait andré da \'nt la memòria dël server ëd {{SITENAME}}.',
+'qbsettings' => 'Regolassion dla bara dij menù',
+'changepassword' => 'Cambia ciav',
+'skin' => 'Facia',
+'math' => 'Fòrmule ëd matemàtica',
+'dateformat' => 'Forma dla data',
+'datedefault' => 'franch l\'istess',
+'datetime' => 'Data e ora',
+'math_failure' => 'Parsificassion falà',
+'math_unknown_error' => 'Eror nen conossù',
+'math_unknown_function' => 'funsion che as sa pa lòn che a la sia',
+'math_lexing_error' => 'eror ëd léssich',
+'math_syntax_error' => 'eror ëd sintassi',
+'math_image_error' => 'Conversion a PNG falà; che a contròla che latex, dvips, gs, e convert a sio instalà giust',
+'math_bad_tmpdir' => 'Ël sistema a-i la fa pa a creé la diretriss \'\'\'math temp\'\'\', ò pura a-i la fa nen a scriv-je andrinta',
+'math_bad_output' => 'Ël sistema a-i la fa pa a creé la diretriss \'\'\'math output\'\'\', ò pura a-i la fa nen a scriv-je andrinta',
+'math_notexvc' => 'Pa gnun texvc executable; për piasì, che a contròla math/README për la configurassion.',
+'prefs-personal' => 'Profil dl\'utent',
+'prefs-rc' => 'Ùltime modìfiche',
+'prefs-watchlist' => 'Ròba che as ten sot euj',
+'prefs-watchlist-days' => 'Vàire dì che a veul ës-ciairé an soa lista ëd lòn che as ten sot euj:',
+'prefs-watchlist-edits' => 'Vàire modìfiche che a veul ës-ciairé con le funsion avansà:',
+'prefs-misc' => 'Sòn e lòn',
+'saveprefs' => 'Salvé ij sò gust',
+'resetprefs' => 'Buta torna ij "mè gust" coma a-i ero al prinsipi',
+'oldpassword' => 'Veja ciav',
+'newpassword' => 'Neuva ciav',
+'retypenew' => 'Che a scriva torna soa neuva ciav',
+'textboxsize' => 'Amzure dël quàder ëd modìfica dël test',
+'rows' => 'Righe',
+'columns' => 'Colòne',
+'searchresultshead' => 'Specifiché soe preferense d\'arserca',
+'resultsperpage' => 'Arsultà da mostré për vira pàgina',
+'contextlines' => 'Righe ëd test për vira arsultà',
+'contextchars' => 'Caràter për riga',
+'stubthreshold' => 'Smon jë sbòss pì curt che:',
+'recentchangescount' => 'Nùmer ëd tìtoj ant j\'ùltime modìfiche',
+'savedprefs' => 'Ij sò gust a son stait salvà.',
+'timezonelegend' => 'Fus orari',
+'timezonetext' => 'Che a buta ël nùmer d\'ore ëd diferensa antra soa ora local e l\'ora dël server (UTC).',
+'localtime' => 'Ora Local',
+'timezoneoffset' => 'Diferensa oraria (1)',
+'servertime' => 'Ora dël server',
+'guesstimezone' => 'Ciapa sù l\'ora da \'nt ël mè programa ëd navigassion (browser)',
+'allowemail' => 'Lassa che j\'àutri Utent am mando ëd pòsta eletrònica',
+'defaultns' => 'Se as dis nen divers, as sërca ant costi spassi nominaj-sì:',
+'default' => 'stàndard',
+'files' => 'Archivi',
+'userrights-lookup-user'=> 'Gestion dle partìe d\'utent',
+'userrights-user-editname'=> 'Che a buta në stranòm:',
+'editusergroup' => 'Modifiché le partìe d\'Utent',
+'userrights-editusergroup'=> 'Modìfiché le partìe dj\'utent',
+'saveusergroups' => 'Salva le partìe d\'utent',
+'userrights-groupsmember'=> 'A l\'é andrinta a:',
+'userrights-groupsavailable'=> 'Partìe disponibij:',
+'userrights-groupshelp' => 'Che as selession-a le partìe d\'andoa che a veul gavé ò andoa che a veul buteje andrinta l\'utent.
+Le partìe nen selessionà a saran nen tocà. Për deselessioné na partìa a venta che a jë sgnaca ansima ën tnisend ësgnacà ëdcò ël tast CTRL ëd soa tastera.',
+'group' => 'Partìa:',
+'group-bot' => 'Trigomiro',
+'group-sysop' => 'Aministrator',
+'group-bureaucrat' => 'Mangiapapé',
+'group-all' => '(utent)',
+'group-bot-member' => 'Trigomiro',
+'group-sysop-member' => 'Aministrator',
+'group-bureaucrat-member'=> 'Mangiapapé',
+'grouppage-bot' => '{{ns:project}}:Trigomiro',
+'grouppage-sysop' => '{{ns:project}}:Aministrator',
+'grouppage-bureaucrat' => '{{ns:project}}:Mangiapapé',
+'changes' => 'modìfiche',
+'recentchanges' => 'Ùltime Modìfiche',
+'recentchangestext' => 'Costa a l\'é la pàgina che a ten ël registr dij cambiament a la wiki pì davsin ant ël temp.',
+'rcnote' => 'Ambelessì sota a-i é la lista dj\'ùltime <strong>$1</strong> pàgine modificà ant j\'ùltim <strong>$2</strong> dì, a fé data al $3.',
+'rcnotefrom' => ' Ambelessì sota a-i é la lista dle modìfiche da <b>$2</b> (fin-a a <b>$1</b>).',
+'rclistfrom' => 'Most-me le modìfiche a parte da $1',
+'rcshowhideminor' => '$1 le modìfiche cite',
+'rcshowhidebots' => '$1 ij trigomiro',
+'rcshowhideliu' => '$1 j\'utent registrà',
+'rcshowhideanons' => '$1 j\'utent anònim',
+'rcshowhidepatr' => '$1 le modìfiche verificà',
+'rcshowhidemine' => '$1 mie modìfiche',
+'rclinks' => 'Most-me j\'ùltime $1 modìfiche ëd j\'ùltim $2 dì<br />$3',
+'diff' => 'dif.',
+'hist' => 'stòria',
+'hide' => 'stërma',
+'show' => 'smon',
+'minoreditletter' => 'c',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[$1 utent che as ten-o sossì sot euj]',
+'rc_categories' => 'Limité a le categorìe (che a jë scriva separand-je antra lor con un "|")',
+'rc_categories_any' => 'Qualsëssìa',
+'upload' => 'Carié',
+'uploadbtn' => 'Carié',
+'reupload' => 'Caria torna',
+'reuploaddesc' => 'Torné al mòdulo ëd domanda për carié archivi',
+'uploadnologin' => 'A dev [[Special:Userlogin|rintré ant ël sistema]] për podej fé st\'operassion-sì',
+'uploadnologintext' => 'A dev [[Special:Userlogin|rintré ant ël sistema]]
+për podej carié dj\'archivi.',
+'upload_directory_read_only'=> 'Ël programa webserver a-i la fa nen a scrive ansima a la diretriss ëd càrich ($1).',
+'uploaderror' => 'Eror dëmentré che as cariava',
+'uploadtext' => '\'\'\'DOSMAN!\'\'\' Anans che carié dla ròba ansima a {{SITENAME}}, che a sia motobin sigur d\'avej bin lesù e capì
+[[Project:Image_use_policy|ël regolament ëd {{SITENAME}} ansima al dovré dle figure]].
+
+Për vardé ò pura sërché figure già carià ant sla {{SITENAME}}, che a vada ant sla [[Special:Imagelist | lista dle figure]].
+Lòn che as caria e së scancela a resta marcà ant ël [[Project:upload log|registr dij càrich]].
+
+Che a dòvra ël mòdulo ambelessì sota për carié neuv archivi con figure da dovré për fé pì bej e bin spiegà ij sò artìcoj.
+Ant sla pì part dij programa ëd navigassion dla Ragnà (browsers) a dovr ia s-ciairesse un boton con scrit "Browse..." (ò pura "Sfeuja...", se i l\'eve un sistema n\'italian) che av deurb la sòlita fnestra che as dòvra për carié dj\'archivi.<br />
+
+Ën sërnend un dj\'archivi che i l\'eve ant sij vòstri disco, ël nòm a vnirà scrit n\'automàtich ant la casela ëd test da fianch dël boton.<p>
+
+\'\'\'A dev ëdcò selessioné la casela ëd conferma che a dis che l\'archivi a-j va nen contra a gnun-a nòrma ant sël drit d\'autor.\'\'\'<p>
+
+Fait lolì, che a sgnaca ël boton "Carié" për completé l\'operassion.
+Ël càrich a podrìa duré ëdcò chèich minuta, se chiel (chila) a l\'avèissa na conession che a va pian, ò pura se la figura a la fussa tròp gròssa (figure parej as conseja dë nen carieje).<p>
+
+Le sòrt d\'archivi che as preferisso a son ël JPEG për le fotografìe, ël PNG për ij dissègn, j\'icòne e ij simboj, l\'OGG për j\'archivi sonòr.<p>
+
+Për piasì, anans che carieje, che a rinòmina ij sò archivi con dij nòm che diso lòn che a son, për evité dë fé confusion.
+Për buté na neuva figura ant n\'articol, dovré n\'anliura ant la forma
+\'\'\'<nowiki>[[image:archivi.jpg]]</nowiki>\'\'\' ò pura
+\'\'\'<nowiki>[[image:archivi.png|alt text, test alternativ]]</nowiki>\'\'\' ò pura
+\'\'\'<nowiki>[[media:archivi.ogg]]</nowiki>\'\'\' per ij son.<p>
+
+Che a ten-a present che tan-me për tuti ij contnù ëd la {{SITENAME}}, qualsëssìa person-a a peul modifiché, cangé ò pura scancelé ij sò archivi, se a jë smija che sòn a sia ant j\'anteressi ëd l\'enciclopedìa. Che a ten-a ëdcò da ment che, se a-i fusso dij comportament nen conformà a le nòrme, ò pura se a-i fussa na caria tròp gròssa për ël sistema, a podrìa esse blocà (ant sël pat d\'esse perseguì se a-i fusso dle responsabilita legaj).',
+'uploadlog' => 'Registr dij càrich',
+'uploadlogpage' => 'Registr dij càrich',
+'uploadlogpagetext' => 'Ambelessì sota a-i é la lista dj\'ùltim archivi carià ant sël server ëd {{SITENAME}}.',
+'filename' => 'Nòm dl\'archivi',
+'filedesc' => 'Oget',
+'fileuploadsummary' => 'Detaj dl\'archivi:',
+'filestatus' => 'Situassion dij drit d\'autor',
+'filesource' => 'Sorgiss',
+'copyrightpage' => 'Project:Drit d\'autor',
+'copyrightpagename' => 'Drit d\'autor ëd {{SITENAME}}',
+'uploadedfiles' => 'Archivi carià ant la {{SITENAME}}',
+'ignorewarning' => 'Piantla-lì con j\'avis e salva an tute le manere',
+'ignorewarnings' => 'Lassa sté j\'avis',
+'minlength' => 'Ij nòm dj\'archivi dle figure a l\'han dë esse longh almanch 3 caràter, ma a l\'é pì bon deuit dovré dij nòm longh, basta che a faso na bon-a descrission dël soget dla figura.',
+'illegalfilename' => 'Ël nòm d\'archivi "$1" a l\'ha andrinta dij caràter che as peulo pa dovresse ant ij tìtoj dle pàgine. Për piasì che a-j cangia nòm e peui che a torna a carielo.',
+'badfilename' => 'Ël nòm dl\'archivi a l\'é stait cambià an "$1".',
+'badfiletype' => '".$1" a l\'é nen ëd la sòrt d\'archivi che as racomando për le figure, almanch nen për lòn che an fa da manca.',
+'largefile' => 'Ël pèis ëd n\'archivi che as caria a dovrìa resté sota a ij $1 bytes; cost-sì a l\'amzura $2 bytes.',
+'largefileserver' => 'St\'archivi-sì a resta pì gròss che lòn che la màchina sentral a përmet.',
+'emptyfile' => 'L\'archivi che a l\'ha pen-a carià a smija veujd.
+Sòn a podrìa esse rivà përchè che chiel a l\'ha scrivù mal ël nòm dl\'archivi midem.
+Për piasì che a contròla se a l\'é pro cost l\'archivi che a veul carié.',
+'fileexists' => 'N\'archivi con ës nòm-sì a-i é già, për piasì che as contròla $1 se a l\'é pa sigur dë volej cangelo.',
+'fileexists-forbidden' => '[[Belavans]] n\'archivi con ës nòm-sì a-i é già, donca ël nòm as peul pa pì dovresse; për piasì che a torna andré e che as caria sò archivi con un nòm diferent. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> '[[Belavans]] n\'archivi con ës nòm-sì ant la diretriss dj\'archivi condivis a-i é già, donca ël nòm as peul pa pì dovresse; për piasì che a torna andré e che as caria sò archivi con un nòm diferent.
+[[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Carià complet',
+'fileuploaded' => 'L\'archivi "$1" a l\'é stait carià ant sël server coma che as dev.
+Che a dòvra st\'anliura-sì: ($2) për modifiché la pàgina ëd descrission dl\'archivi che a l\'ha pen-a carià, e che a buta bele sùbit cole anformassion che a jë smija dë buté (lòn che a l\'é, andoa a l\'ha trovalo, chi che a l\'ha falo e quand, e via fòrt) e na nòta ansma a la situassion dij drit d\'autor dl\'archivi midem.<br /> Che as dësmentia pa dla nota ant sij drit, che dësnò l\'archivi a sarà scancelà motobin ampressa.',
+'uploadwarning' => 'Avis che i soma dapress a carié',
+'savefile' => 'Salva l\'archivi',
+'uploadedimage' => 'a l\'ha carià "[[$1]]"',
+'uploaddisabled' => 'Càrich blocà',
+'uploaddisabledtext' => 'La possibilità ëd carié dj\'archivi ansima a sta wiki-sì a l\'é staita disabilità.',
+'uploadscripted' => 'St\'archivi-sì a l\'ha andrinta chèich-còs (dël còdes HTML ò pura dlë script) che a podrìe esse travajà mal da chèich programa ëd navigassion (browser).',
+'uploadcorrupt' => 'St\'archivi-sì ò che a l\'é falà ò che a l\'ha n\'estension cioca. Për piasì, che as contròla l\'archivi e peuj che a preuva torna a carielo.',
+'uploadvirus' => 'St\'archivi-sì a l\'han andrinta un \'\'\'vìrus!\'\'\' Detaj: $1',
+'sourcefilename' => 'Nòm dl\'archivi sorgiss',
+'destfilename' => 'Nòm dl\'archivi ëd destinassion',
+'filewasdeleted' => 'N\'archivi con ës nòm-sì a l\'é gia stait caria e peui scancelà. Për piasì, che a verìfica $1 anans che carielo n\'àutra vira.',
+'license' => 'Licensa',
+'nolicense' => 'Pa gnun-a selession faita',
+'imagelist' => 'Lista dle figure',
+'imagelisttext' => 'Ambelessì sota a-i é {{PLURAL:$1|l\'ùnica figura che a-i sia|na lista ëd \'\'\'$1\'\'\' figure, ordinà për $2}}.',
+'imagelistforuser' => 'Sòn a mostra mach le figure carià da $1.',
+'getimagelist' => 'arserca ant la lista dle figure',
+'ilsubmit' => 'Sërca',
+'showlast' => 'Lista ëd $1, antra j\'ùltime figure, ordinà për $2.',
+'byname' => 'nòm',
+'bydate' => 'për data',
+'bysize' => 'pèis',
+'imgdelete' => 'scanc',
+'imgdesc' => 'descr',
+'imglegend' => 'Legenda: (desc) = mostra/modìfica la descrission dla figura.',
+'imghistory' => 'Stòria dë sta figura',
+'revertimg' => 'buta torna',
+'deleteimg' => 'scanc',
+'deleteimgcompletely' => 'scanc',
+'imghistlegend' => 'Legenda: (cor) = figura corenta, (scanc) = scancela sta version veja, (arb) = arbuta sù sta veja version coma version corenta.
+<br /><i>Che a jë sgnaca ansima a na data për ës-ciairé tute le figure che sono staite carià an cola data-lì </i>.',
+'imagelinks' => 'Anliure a le figure',
+'linkstoimage' => 'Le pàgine sì sota a l\'han andrinta dj\'anliure a sta figura-sì:',
+'nolinkstoimage' => 'Pa gnun-a pàgina che a l\'abia n\'anliura a sta figura-sì.',
+'sharedupload' => 'St\'archivi-sì a l\'é stait carià an comun; donca a peul esse dovrà antra vàire proget wiki diferent.',
+'shareduploadwiki' => 'Che as varda $1 për savejne dë pì.',
+'shareduploadwiki-linktext'=> 'pàgina dë spiegon dl\'archivi',
+'noimage' => 'A-i é pa gnun archivi che as ciama parej, a peul $1.',
+'noimage-linktext' => 'carijlo',
+'uploadnewversion-linktext'=> 'Carié na version neuva dë st\'archivi-sì',
+'mimesearch' => 'Arsërca për sòrt MIME',
+'mimetype' => 'Sòrt MIME:',
+'download' => 'dëscarié',
+'unwatchedpages' => 'Pàgine che as ten-o pì nen sot euj',
+'listredirects' => 'Lista dle ridiression',
+'unusedtemplates' => 'Stamp nen dovrà',
+'unusedtemplatestext' => 'Sta pàgina-sì a la smon tuti jë stamp (pàgine dlë spassi nominal Stamp) che a son pa dovrà andrinta a gnun-a pàgina. Mej verifiché che në stamp a-j serva nen a dj\'àutri stamp (che dle vire në stamp gròss a l\'é fait ëd vàire cit sotastamp), anans che fé che ranchelo via.',
+'unusedtemplateswlh' => 'àutre anliure',
+'randomredirect' => 'Na ridiression qualsëssìa',
+'statistics' => 'Statìstiche',
+'sitestats' => 'Statìstiche dël sit',
+'userstats' => 'Statìstiche ëd {{SITENAME}}',
+'sitestatstext' => 'A-i é la blëssa ëd <b>$1</b> pàgine ant la base dat.
+Ës nùmer-sì a comprend le pàgine ëd ciaciarada, cole ansima a {{SITENAME}}, artìcoj curt (che ant ël parlé técnich dla wiki as ciamo "sbòss"), ridiression, e àutre pàgine che a l\'é belfé che a sio pa dj\'artìcoj.
+Gavà coste, a resto <b>$2</b> pàgine che a l\'han tuta l\'ària d\'esse dj\'artìcoj da bon.
+
+\'\'\'$8\'\'\' archivi a son stait carià.
+
+A-i é staje un total ëd \'\'\'$3\'\'\' pàgine consultà, e \'\'\'$4\'\'\' modìfiche a j\'artìcoj, da quand sta wiki a l\'é doèrta.
+Costa media an dis che a-i son ëstaje <b>$5</b> modìfiche për artìcol, e che vira artìcol a l\'é stait lesù <b>$6</b> vire për modìfica.
+
+Ant la [http://meta.wikimedia.org/wiki/Help:Job_queue coa] a-i {{plural|é|son}} \'\'\'$7\'\'\' process.',
+'userstatstext' => 'A-i son <b>$1</b> utent registrà, dont
+<b>$2</b> (ël \'\'\'$4%\'\'\') a l\'han la qualìfica d\'aministrator (che a varda $3).',
+'disambiguations' => 'Pàgine për la gestion dij sinònim',
+'disambiguationspage' => 'Template:Gestion dij sinònim',
+'disambiguationstext' => 'Sti artìcoj-sì a l\'han dj\'anliure a dle \'\'pàgine për la gestion dij sinònim\'\'. [[Nopà]] che ëmné la gent ambelelì a dovrìo deurbe l\'artìcol giust.<br />
+Na pàgina as consìdera për la gestion dij sinònim se a l\'ha n\'anliura che a-i men-a dzora da $1.<br />
+Anliure che a rivèisso da dj\'àutri spassi nominaj a resterìo nen listà ambelessì.',
+'doubleredirects' => 'Ridiression dobie',
+'doubleredirectstext' => '<b>Pieve varda:</b> costa lista-sì dle vire a peul avej andrinta dj\'arsultà nen giust. Sòn a peul rivé miraco përchè a-i sio dj\'anliure ò pura dël test giontà dapress a l\'istrussion #REDIRECT.<br />
+Vira riga a l\'ha andrinta j\'anliure a la prima e a la sconda rediression, ant sël pat ëd la prima riga ëd test dla seconda rediression, che për sòlit a l\'ha andrinta l\'artìcol ëd destinassion vèir, col andoa che a dovrìa ëmné ëdcò la prima reiression.',
+'brokenredirects' => 'Ridiression nen giuste',
+'brokenredirectstext' => 'Coste ridiression-sì a men-o a dj\'articoj ancó pa creà.',
+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
+'ncategories' => '$1 {{PLURAL:$1|categorìa|categorìe}}',
+'nlinks' => '$1 {{PLURAL:$1|anliura|anliure}}',
+'nmembers' => '$1 {{PLURAL:$1|element|element}}',
+'nrevisions' => '{{PLURAL:$1|na revision|$1 revision}}',
+'nviews' => '{{PLURAL:$1|na consultassion|$1 consultassion}}',
+'lonelypages' => 'Pàgine daspërlor',
+'uncategorizedpages' => 'Pàgine che a son nen assignà a na categorìa',
+'uncategorizedcategories'=> 'Categorìe che a son pa assignà a na categorìa',
+'uncategorizedimages' => 'Figure nen dovrà',
+'unusedcategories' => 'Categorìe nen dovrà',
+'unusedimages' => 'Figure nen dovrà',
+'popularpages' => 'Pàgine pì s-ciairà',
+'wantedcategories' => 'Categorìe dont a fa da manca',
+'wantedpages' => 'Artìcoj pì ciamà',
+'mostlinked' => 'Pàgine che a l\'han pì d\'anliure che a-i men-o la gent ansima',
+'mostlinkedcategories' => 'Categorìe che a l\'han pì d\'anliure che a-i men-o la gent ansima',
+'mostcategories' => 'Artìcoj che a son marcà an pì categorìe',
+'mostimages' => 'Figure pì dovrà',
+'mostrevisions' => 'Artìcoj pì modificà',
+'allpages' => 'Tute le pàgine',
+'prefixindex' => 'Ìndess për inissiaj',
+'randompage' => 'Na pàgina qualsëssìa',
+'shortpages' => 'Pàgine curte',
+'longpages' => 'Pàgine longhe',
+'deadendpages' => 'Pàgine che a men-o da gnun-a part',
+'listusers' => 'Lista dj\'utent',
+'specialpages' => 'Pàgine Speciaj',
+'spheading' => 'Pàgine Speciaj',
+'restrictedpheading' => 'Pàgine speciaj riservà',
+'recentchangeslinked' => 'Modìfiche colegà',
+'rclsub' => '(pàgine che a l\'han n\'anliura che a riva da "$1")',
+'newpages' => 'Pàgine neuve',
+'ancientpages' => 'Le pàgine pì veje',
+'intl' => 'Anliure antra lenghe diferente',
+'move' => 'Tramuda',
+'movethispage' => 'Tramuda costa pàgina-sì',
+'unusedimagestext' => '<p>Che ten-a present che dj\'àutri sit ant sla Ragnà, coma la {{SITENAME}} antërnassional, a podrìo avej butà n\'anliura a na figura con n\'adrëssa direta, e donca a peul esse che le figure ant costa lista-sì, contut che son nen dovrà ant costa version-sì dla {{SITENAME}}, a sio però dovrà ant chèich àutr pòst.',
+'unusedcategoriestext' => 'Le pàgine ëd coste categorìe-sì a son fasse ma peuj a l\'han andrinta nì d\'artìcoj, nì ëd sotacategorìe.',
+'booksources' => 'Andoa trové dij lìber',
+'categoriespagetext' => 'An costa wiki a-i son ste categorìe-sì.',
+'data' => 'Dat',
+'userrights' => 'Gestion dij drit dj\'utent',
+'groups' => 'Partìe d\'utent',
+'booksourcetext' => 'Ambelessì sota a-i é na lista d\'àutri sit
+che a vendo lìber neuv e dë sconda man, che peulo
+ëdcò avej pì d\'anformassion ansima a ij lìber che
+i seve dapress a sërché.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 a $2',
+'version' => 'Version',
+'log' => 'Registr',
+'alllogstext' => 'Son a mostra na combinassion dij registr ëd lòn che a l\'é cariasse, scancelasse, blocasse e ëd lòn che a l\'han fait j\'aministrator.
+A peul sern-se n\'arsultà pì strèit ën selessionand na sòrt ëd registr sola, un nòm Utent ò pura la pàgina che a-j anteressa.',
+'logempty' => 'Pa gnun element parej che a sia trovasse ant ij registr.',
+'nextpage' => 'Pàgina che a-i ven ($1)',
+'allpagesfrom' => 'Most-me la pàgine ën partend da:',
+'allarticles' => 'Tùit j\'artìcoj',
+'allinnamespace' => 'Tute le pàgine (spassi nominal $1)',
+'allnotinnamespace' => 'Tute le pàgine (che a son nen ant lë spassi nominal $1)',
+'allpagesprev' => 'Cole prima',
+'allpagesnext' => 'Cole che a ven-o',
+'allpagessubmit' => 'Va',
+'allpagesprefix' => 'Most-me la pàgine che a l\'ha prefiss:',
+'mailnologin' => 'A-i é pa gnun-a adrëssa për mandé ël messagi',
+'mailnologintext' => 'A dev [[Special:Userlogin|rintré ant ël sistema]]
+e avej registrà n\'adrëssa ëd pòsta eletrònica vàlida ant ij [[Special:Preferences|sò gust]] për podej mandé dij messagi ëd pòsta eletrònica a j\'àutri Utent.',
+'emailuser' => 'Mand-je un messagi eletrònich a st\'Utent-sì',
+'emailpage' => 'Mand-je un messagi ëd pòsta eletrònica a st\'utent-sì',
+'emailpagetext' => 'Se st\'Utent-sì a l\'ha registrà na soa casela ëd pòsta eletrònica, i peule scriv-je un messagi con ël mòdulo ambelessì sota.
+L\'adrëssa eletrònica che a l\'ha specificà ant ij sò "gust" a sarà butà coma mitent, an manera che ël destinatari, ën volend, a peula arspond-je.',
+'usermailererror' => 'L\'oget che a goèrna la pòsta eletrònica a l\'ha dait eror:',
+'defemailsubject' => 'Messagi da {{SITENAME}}',
+'noemailtitle' => 'Pa gnun-a adrëssa ëd pòsta eletrònica',
+'noemailtext' => 'Cost Utent-sì a l\'ha nen registrà gnun-a casela ëd pòsta eletrònica, ò pura a l\'ha sërnù ëd nen fesse mandé pòsta da j\'àutri Utent.',
+'emailfrom' => 'Da',
+'emailto' => 'A',
+'emailsubject' => 'Oget',
+'emailmessage' => 'Messagi',
+'emailsend' => 'Manda',
+'emailsent' => 'Messagi eletrònich mandà',
+'emailsenttext' => 'Sò messagi eletrònich a l\'é stait mandà',
+'watchlist' => 'Ròba che im ten-o sot euj',
+'watchlistfor' => '(për \'\'\'$1\'\'\')',
+'nowatchlist' => 'A l\'ha ancó pa marcà dj\'artìcoj coma "ròba da tnì sot euj".',
+'watchlistanontext' => 'Për piasì, $1 për ës-ciairé ò pura modifiché j\'element ëd soa lista dla ròba che as ten sot euj.',
+'watchlistcount' => '\'\'\'La lista dla ròba che as ten sot euj a l\'ha andrinta $1 element (contand ëdcò le pàgine ëd discussion).\'\'\'',
+'clearwatchlist' => 'Veujda la lista dle ròbe da tnì sot euj',
+'watchlistcleartext' => 'Che a conferma che a veul gavé via tùit j\'element',
+'watchlistclearbutton' => 'Dësveujda la lista',
+'watchlistcleardone' => 'La lista dla ròba che as ten sot euj a l\'è staita dësveujdà. Ën fasendlo a son gavasse via $1 element.',
+'watchnologin' => 'A l\'é ancó nen rintrà ant ël sistema',
+'watchnologintext' => 'A l\'ha da manca prima ëd tut dë [[Special:Userlogin|rintré ant ël sistema]]
+për podej modifiché soa lista dla ròba dë tnì sot euj.',
+'addedwatch' => 'Sòn a l\'é stait giontà a le pàgine che it ten-e sot euj',
+'addedwatchtext' => ' La pàgina "$1" a l\'é staita giontà a tua <a href="{{localurle:Special:Watchlist}}">lista dla ròba da tnì sot euj</a>.
+Le modìfiche che a-i vniran ant costa pàgina-sì e ant soa pàgina ëd discussion a saran listà ambelessì, e la pàgina a së s-ciairerà ën <b>grassèt</b> ant la pàgina ëd j\'<a href="{{localurle:Special:Recentchanges}}">ùltime modìfiche</a> përchè che a resta belfé a ten-la d\'euj.</p>
+
+<p>Se a vorèissa mai gavé st\'articol-sì da \'nt la lista dij \'\'Sot Euj\'\', che a sgnaca " Chita da tnì sot euj " ant sla bara dij menù.',
+'removedwatch' => 'Gavà via da \'nt la lista dla ròba da tnì sot euj',
+'removedwatchtext' => 'La pàgina "$1" a l\'è staita gavà via da soa lista dla ròba da tnì sot euj.',
+'watch' => 'ten sot euj',
+'watchthispage' => 'Ten sot euj st\'artìcol-sì',
+'unwatch' => 'Chita-lì da ten-e sossì sot euj',
+'unwatchthispage' => 'Chita-lì da ten-e sossì sot euj',
+'notanarticle' => 'Sòn a l\'é pa n\'artìcol',
+'watchnochange' => 'Pa gnun-a dle ròbe che as ten sot euj che a sia staita modificà ant ël temp indicà.',
+'watchdetails' => '* $1 pàgine che im ten-o sot euj nen contand cole ëd discussion
+* [[Special:Watchlist/edit|most-me e lass-me modifiché la lista antrega ëd lòn che im ten-o sot euj]]',
+'wlheader-enotif' => '* Le notìfiche për pòsta eletrònica a son abilità.',
+'wlheader-showupdated' => '* Cole pàgine che a son staite modificà da quand che a l\'é passa l\'ùltima vira a resto marcà an \'\'\'grassèt\'\'\'',
+'watchmethod-recent' => 'controland j\'ùltime modìfiche faite a le pàgine che as ten sot euj',
+'watchmethod-list' => 'controland le pàgine che as ten sot euj për vëdde se a-i sio mai staje dle modìfiche',
+'removechecked' => 'Gava via j\'element marcà da \'nt la lista dle ròbe da ten-e sot euj',
+'watchlistcontains' => 'Soa lista dla ròba che as ten sot euj a l\'ha andrinta $1 pàgine.',
+'watcheditlist' => 'Sossì a l\'é un elench alfabétich ëd tute le pàgine ëd contnù che as ten sot euj.
+Che a-j buta la cros ant sle casele dle pàgine che a veul gavé via da \'nt la lista e peuj che a jë sgnaca ansima al boton "gava cole selessionà" che a treuva sota (pàgina ëd contnù e ëd discussion a fa mach basta gavene un-a, che as bogio sempe an cobia).',
+'removingchecked' => 'I soma antramentr che ij gavoma j\'element da \'nt la lista dle ròbe da ten-se sot euj...',
+'couldntremove' => 'A l\'é pa podusse gavé via l\'element \'$1\'...',
+'iteminvalidname' => 'Problema con l\'element \'$1\', nòm nen vàlid...',
+'wlnote' => 'Ambelessì sota a-i son j\'ùltime $1 modìfiche ant j\'ùltime <b>$2</b> ore.',
+'wlshowlast' => 'Most-me j\'ùltime $1 ore $2 dì $3',
+'wlsaved' => 'Costa-sì a l\'é na version memorisà ëd soa lista dle ròbe da tnì sot euj.',
+'wlhideshowown' => '$1 soe modìfiche.',
+'wlhideshowbots' => '$1 modìfiche dij trigomiro.',
+'wldone' => 'Fait.',
+'enotif_mailer' => '{{SITENAME}} - Servissi ëd Notìfica Postal',
+'enotif_reset' => 'March-me tute le pàgine visità',
+'enotif_newpagetext' => 'Costa-sì a l\'é na pàgina neuva',
+'changed' => 'cangià',
+'created' => 'creà',
+'enotif_subject' => 'La pàgina $PAGETITLE ëd {{SITENAME}} a l\'é staita $CHANGEDORCREATED da $PAGEEDITOR',
+'enotif_lastvisited' => 'Che as varda $1 për ës-ciaré tute le modìfiche da \'nt l\'ùltima vira che a l\'é passà.',
+'enotif_body' => 'A l\'atension ëd $WATCHINGUSERNAME,
+
+La pàgina $PAGETITLE dël sit {{SITENAME}} a l\'é staita $CHANGEDORCREATED al $PAGEEDITDATE da $PAGEEDITOR, che a varda $PAGETITLE_URL për la version corenta.
+
+$NEWPAGE
+
+Somari dl\'editor: $PAGESUMMARY $PAGEMINOREDIT
+
+Për contaté l\'editor:
+Pòsta eletrònica: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Se chiel (chila) a visitèissa nen la pàgina modificà për contròl a-i sarìa pì gnun-a notìfica ëd modìfiche che a podèisso riveje dapress a costa.
+Che as visa che a peul cangeje ij setagi dle notìfiche a le pàgine che as ten sot-euj ansima a soa lista dla ròba da ten-e sot euj.
+
+ Comunicassion dël sistema ëd notìfica da {{SITENAME}}
+
+--
+Për cangé ij setagi ëd lòn che as ten sot euj che a vada ansima a
+{{fullurl:Special:Watchlist/edit}}
+
+Për fé dle comunicassion ëd servissi e avej pì d\'agiut:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Scancela pàgina',
+'confirm' => 'Conferma',
+'excontent' => 'Ël contnù a l\'era: \'$1\'',
+'excontentauthor' => 'ël contnù a l\'era: \'$1\' (e l\'ùnich contributor a l\'era stait \'$2\')',
+'exbeforeblank' => 'Anans d\'esse dësvojdà ël contnù a l\'era: \'$1\'',
+'exblank' => 'La pàgina a l\'era veujda',
+'confirmdelete' => 'Conferma dlë scancelament',
+'deletesub' => '(Scancelament ëd "$1")',
+'historywarning' => 'Avis: la pàgina che a l\'é antramentr che a scancela a l\'ha na stòria:',
+'confirmdeletetext' => 'A sta për scancelé d\'autut da \'nt la base dat na pàgina ò pura na figura, ansema a tuta soa cronologìa.<p>
+Për piasì, che an conferma che sòn a l\'é da bon sò but, che a as rend cont ëd le conseguense ëd lòn che a fa, e che sòn a resta an pien an régola con lòn che a l\'é stabilì ant la [[Project:Polìtica]].',
+'actioncomplete' => 'Travaj fait e finì',
+'deletedtext' => 'La pàgina "$1" a l\'é staita scancelà.
+Che a varda $2 për na lista dle pàgine scancelà ant j\'ùltim temp.',
+'deletedarticle' => 'Scancelà "$1"',
+'dellogpage' => 'Registr djë scancelament',
+'dellogpagetext' => 'Ambelessì sota na lista dle pàgine scancelà ant j\'ùltim temp.
+Ij temp a son conforma a l\'ora dël server (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'Registr djë scancelament',
+'reverted' => 'Version prima butà torna sù',
+'deletecomment' => 'Motiv dlë scancelament',
+'imagereverted' => 'La version pì veja a l\'é staita torna buta sù. Gnun eror.',
+'rollback' => 'Dòvra na revision pì veja',
+'rollback_short' => 'Ripristinè',
+'rollbacklink' => 'ripristiné j\'archivi',
+'rollbackfailed' => 'A l\'é pa podusse ripristiné',
+'cantrollback' => 'As peul pa tornesse a na version pì veja: l\'ùltima modìfica a l\'ha fala l\'ùnich utent che a l\'abia travajà a cost artìcol-sì.',
+'alreadyrolled' => 'As peulo pa anulé j\'Ultime modìfiche ëd [[:$1]]
+faite da [[User:$2|$2]] ([[User talk:$2|Talk]]); Cheidun d\'àutr a l\'ha già modificà ò pura anulà le modìfiche a sta pàgina-sì.
+
+L\'ùltima modìfica a l\'é staita faita da [[User:$3|$3]] ([[User talk:$3|Talk]]).',
+'editcomment' => 'Ël coment dla modìfica a l\'era: "<i>$1</i>".',
+'revertpage' => 'Gavà via le modìfiche dl\'utent [[Special:Contributions/$2|$2]] ([[User_talk:$2|Talk]]); ël contnù a l\'é stait tirà andarè a l\'ùltima version dl\'utent [[User:$1|$1]]',
+'sessionfailure' => 'A-i son ëstaje dle gran-e con la session che a identìfica sò acess; ël sistema a l\'ha nen eseguì l\'ordin che a l\'ha daje për precaussion. Che a torna andaré a la pàgina prima con ël boton "andaré" ëd sò programa ëd navigassion (browser), peuj che as carìa n\'àutra vira costa pàgina-sì e che a preuva torna a fé lòn che vorìa fé.',
+'protectlogpage' => 'Registr dle protession',
+'protectlogtext' => 'Ambelessì sota a-i é na lista d\'event ëd protession e dësprotession ëd pàgine.
+Che a varda la [[Project:Pàgina proteta|guida a le pàgine protete]] për savejne dë pì.',
+'protectedarticle' => '"[[$1]]" a l\'é protet',
+'unprotectedarticle' => 'Dësprotegiù "[[$1]]"',
+'protectsub' => '(I soma antramentr che i protegioma "$1")',
+'confirmprotecttext' => 'Veul-lo da bon protege sta pàgina-sì?',
+'confirmprotect' => 'Che an conferma la protession',
+'protectmoveonly' => 'Lòn che as peul nen fesse ambelessì a l\'é mach tramudé.',
+'protectcomment' => 'Motiv dla protession',
+'unprotectsub' => '(dësprotession ëd "$1")',
+'confirmunprotecttext' => 'Veul-lo da bon dësprotege sta pàgina-sì?',
+'confirmunprotect' => 'Che an conferma la dësprotession',
+'unprotectcomment' => 'Motiv dla dësprotession',
+'protect-unchain' => 'Dësbloché ij permess ëd tramudé dla ròba',
+'protect-text' => 'Ambelessì a peul vardé e cangé ël livel ëd protession dla pàgina <strong>$1</strong>.
+Për piasì, che a resta mach motobin sigur da esse ant ij lìmit ëd le [[Project:Pàgina proteta|polìtiche ëd proget]].',
+'protect-viewtext' => '[[Belavans]] sò cont a l\'ha pa na qualìfica che a-j permëtta da cangé ij livej ëd protession dë sta pàgina-sì. Ambelessì a peul ës-ciairé ij livej ëd protession ëd la pàgina <strong>$1</strong>:',
+'protect-default' => '(stàndard)',
+'protect-level-autoconfirmed'=> 'Bloché j\'utent nen registrà',
+'protect-level-sysop' => 'mach për j\'aministrator',
+'restriction-edit' => 'Modìfica',
+'restriction-move' => 'Tramuda',
+'undelete' => 'Pija andré na pàgina scancelà',
+'undeletepage' => 'S-ciàira e pija andaré le pàgine scancelà',
+'viewdeletedpage' => 'Smon le pàgine scancelà',
+'undeletepagetext' => 'Le pàgine ambelessì sota a son staite scancelà, ma a resto ancó memorisà e donca as peulo pijesse andaré. La memòria a ven polidà passaje un pòch ëd temp.',
+'undeleteextrahelp' => 'Për ripristiné la pàgina antrega, che a lassa tute le casele nen selessionà e che a jë sgnaca ansima a \'\'\'\'\'Buta coma a l\'era \'\'\'\'\'.
+Për ripristiné mach chèich-còs, che a selession-a lòn che a veul ripristiné anans che sgnaché. Ën sgacand-je ansima a \'\'\'\'\'Veujda casele\'\'\'\'\' peul polidesse d\'amblé tute le casele selessionà e dësvojdé ël coment.',
+'undeletearticle' => 'Pija andré n\'artìcol scancelà',
+'undeleterevisions' => '$1 revision memorisà',
+'undeletehistory' => 'Se a pija andré st\'articol-sì, ëdcò tute soe revision a saran pijaite andaré ansema a chiel ant soa cronologìa.<br />
+Se a fussa mai staita creà na pàgina neuva con l\'istess nòm dòp che la veja a l\'era staita scancelà, le revision a saran buta ant la cronologìa e la version pùblica dla pàgina a sarà nen modificà.',
+'undeletehistorynoadmin'=> 'Sta pàgina-sì a l\'é staita scancelà. Ël motiv che a l\'é scancelasse
+as peul savejsse ën vardand ël somari ambelessì sota, andoa che a së s-ciàira ëdcò chi che a
+l\'avìa travaje ansima anans che a la scancelèisso.
+Ël test che a-i era ant le vàire version a peulo s-ciairelo mach j\'aministrator.',
+'undeleterevision' => 'Revision $1 scancelà',
+'undeletebtn' => 'Ripristiné',
+'undeletereset' => 'Gava tute le selession',
+'undeletecomment' => 'Coment:',
+'undeletedarticle' => 'Pijaita andré "$1"',
+'undeletedrevisions' => '$1 revision pijaite andaré',
+'undeletedrevisions-files'=> '$1 revision e $2 archivi pijait andaré',
+'undeletedfiles' => '$1 archivi pijait andaré',
+'cannotundelete' => 'Disdëscancelament falì; a peul esse che i fusse antra doi a felo ant l\'istess temp e l\'àutr a sia riva prima.',
+'undeletedpage' => '<big>\'\'\'$1 a l\'é stait pijait andaré\'\'\'</big>
+
+Che as varda ël [[Special:Log/delete|Registr djë scancelament]] për ës-ciairé j\'ùltim scancelament e disdëscancelament.',
+'namespace' => 'Spassi nominal:',
+'invert' => 'Anvert la selession',
+'contributions' => 'Contribussion dë st\'Utent-sì',
+'mycontris' => 'Mie contribussion',
+'contribsub' => 'Për $1',
+'nocontribs' => 'A l\'é pa trovasse gnun-a modìfica che a fussa conforma a costi criteri-sì',
+'ucnote' => 'Ambelessì sota a-i son j\'ùltime <b>$1</b> modìfiche faite da st\'Utent-sì ant j\'ùltim <b>$2</b> dì.',
+'uclinks' => 'Vardé j\'ùltimi $1 modifiche; vardé j\'ùltim $2 dì.',
+'uctop' => ' (ùltima dla pàgina)',
+'newbies' => 'Utent neuv',
+'sp-newimages-showfrom' => 'Smon j\'ùltime figure anandiandse da $1',
+'sp-contributions-newest'=> 'J\'ùltim',
+'sp-contributions-oldest'=> 'Ij prim',
+'sp-contributions-newer'=> '$1 andaré',
+'sp-contributions-older'=> '$1 anans',
+'sp-contributions-newbies-sub'=> 'Për j\'utent neuv',
+'whatlinkshere' => 'Pàgine con dj\'anliure che a men-o a costa-sì',
+'notargettitle' => 'A manco ij dat',
+'notargettext' => 'A l\'ha pa dit a che pàgina ò Utent apliché l\'operassion ciamà.',
+'linklistsub' => '(Lista d\'anliure)',
+'linkshere' => 'Le pàgine sì sota a l\'han andrinta dj\'anliure che a men-o ambelessì:',
+'nolinkshere' => 'Pa gnun-a pàgina che a l\'abia dj\'anliure che a men-o a costa-sì.',
+'isredirect' => 'ridiression',
+'istemplate' => 'inclusion',
+'blockip' => 'Blochè n\'adrëssa IP',
+'blockiptext' => 'Che a dòvra ël mòdulo ëd domanda \'d blocagi ambelessì sota për bloché l\'acess con drit dë scritura da na chèich adrëssa IP.<br />
+Ës blocagi-sì as dev dovresse MACH për evité dij comportament vandàlich, ën strèita osservansa ëd tùit ij prinsipi dla [[{{ns:project}}:Policy|polìtica ëd {{SITENAME}}]].<br />
+Ël blocagi a peul nen ën gnun-a manera esse dovrà për dle question d\'ideologìa.<p>
+Che a scriva codì che st\'adrëssa IP-sì a dev second chiel (chila) esse blocà (pr\'esempi, che a buta ij tìtoj ëd pàgine che a l\'abio già patì dj\'at vandàlich da cost\'adrëssa IP-sì).',
+'ipaddress' => 'Adrëssa IP',
+'ipadressorusername' => 'Adrëssa IP ò stranòm',
+'ipbexpiry' => 'Fin-a al',
+'ipbreason' => 'Motiv dël blocagi',
+'ipbsubmit' => 'Bloca st\'adrëssa IP-sì',
+'ipbother' => 'N\'àutra durà',
+'ipboptions' => '2 ore:2 ore,1 dì:1 dì,3 dì:3 dì,na sman-a:na sman-a,2 sman-e:2 sman-e,1 mèis:1 mèis,3 mèis:3 mèis,6 mèis:6 mèis,n\'ann:n\'ann,për sempe:për sempe',
+'ipbotheroption' => 'd\'àutr',
+'badipaddress' => 'L\'adrëssa IP che a l\'ha dane a l\'é nen giusta.',
+'blockipsuccesssub' => 'Blocagi fait',
+'blockipsuccesstext' => ' L\'adrëssa IP "$1" a l\'é staita blocà.<br />
+Che a varda la [[Special:Ipblocklist|lista dj\'IP blocà]].',
+'unblockip' => 'Dësblòca st\'adrëssa IP-sì',
+'unblockiptext' => 'Che a dòvra ël mòdulo ëd domanda ambelessì sota për deje andé al drit dë scritura a n\'adrëssa IP che a l\'era staita blocà.',
+'ipusubmit' => 'Dësblòca st\'adrëssa IP-sì',
+'unblocked' => '[[User:$1|$1]] a l\'é stait dësblocà',
+'ipblocklist' => 'Lista dj\'adrësse IP blocà',
+'blocklistline' => '$1, $2 a l\'ha blocà $3 ($4)',
+'infiniteblock' => 'për sempe',
+'expiringblock' => 'fin-a al $1',
+'ipblocklistempty' => 'La lista dij blocagi a l\'é veujda',
+'blocklink' => 'blòca',
+'unblocklink' => 'dësblòca',
+'contribslink' => 'contribussion',
+'autoblocker' => 'A l\'é scataje un blocagi përchè soa adrëssa IP a l\'é staita dovrà ant j\'ùltim temp da l\'Utent "[[User:$1|$1]]". Ël motiv për bloché $1 a l\'é stait: "\'\'\'$2\'\'\'"',
+'blocklogpage' => 'Registr dij blocagi',
+'blocklogentry' => '"[[$1]]" a l\'é stait blocà fin-a a $2',
+'blocklogtext' => 'Sossì a l\'é ël registr dij blocagi e dësblocagi dj\'Utent. J\'adrësse che
+a son staite blocà n\'automàtich ambelessì a së s-ciàiro nen.
+Che a varda la [[Special:Ipblocklist|lista dj\'adrësse IP blocà]] për vëdde
+coj che sio ij blocagi ativ al dì d\'ancheuj.',
+'unblocklogentry' => 'a l\'ha dësblocà $1',
+'range_block_disabled' => 'La possibilità che n\'aministrator a fasa dij blocagi a ragg a l\'é disabilità.',
+'ipb_expiry_invalid' => 'Temp dë scadensa nen bon.',
+'ip_range_invalid' => 'Nùmer IP nen bon.',
+'proxyblocker' => 'Bloché j\'arpetitor (Proxy) doèrt',
+'proxyblockreason' => 'Soa adrëssa IP a l\'é staita bloca përchè a l\'é cola ëd n\'arpetitor (proxy) doèrt. Për piasì che a contata al sò fornitor ëd conession e che a lo anforma. As trata d\'un problema ëd siguressa motobin serio.',
+'proxyblocksuccess' => 'Bele fait.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Soa adrëssa IP a l\'é listà coma arpetitor doèrt (open proxy) ansima a [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason'=> 'Soa adrëssa IP a l\'é listà coma arpetitor doèrt (open proxy) ansima a [http://www.sorbs.net SORBS] DNSBL. A peul nen creésse un cont.',
+'lockdb' => 'Blòca la base dat',
+'unlockdb' => 'Dësblòca la base dat',
+'lockdbtext' => 'Ën blocand la base dat as fërma la possibilità che tuti j\'Utent a peulo modifiché le pàgine ò pura fene \'d neuve, che a peulo cambiesse ij "sò gust", che a peulo modifichesse soe liste dla ròba da tnì sot euj, e an general gnun a podrà pì fé dj\'operassion che a ciamo dë modifiché la base dat.<br /><br />
+Për piasì, che an conferma che sossì a l\'é pròpe lòn che a veul fé, e dzortut che a sblocherà la base dat pì ampressa che a peul, an manera che tut a funsion-a torna coma che as dev, pen-a che a l\'avrà finisse soa manutension.',
+'unlockdbtext' => 'Ën dësblocand la base dat as darà andaré a tuti j\'Utent la possibilità dë fé \'d modìfiche a le pàgine ò dë fene ëd neuve, ëd cangé ij "sò gust", ëd modifiché soe liste \'d ròba da tnì sot euj, e pì an general dë fé tute cole operassion che a l\'han da manca dë fé \'d modìfiche a la base dat.
+Për piasì, che an conferma che sòn a l\'é da bon lòn che chiel (chila) a veul fé.',
+'lockconfirm' => 'É, i veuj da bon, e sota mia responsabilità, bloché la base dat.',
+'unlockconfirm' => ' É, da bon i veuj dësbloché la base dat, sota mia responsabilità personal.',
+'lockbtn' => 'Blòca la base dat',
+'unlockbtn' => 'Dësblòca la base dat',
+'locknoconfirm' => 'Che a varda che a l\'é dësmentiasse dë spunté ël quadrèt ëd conferma.',
+'lockdbsuccesssub' => 'Blocagi dla base dat fait',
+'unlockdbsuccesssub' => 'Dësblocagi dla base dat fait, ël blòch a l\'é stait gavà',
+'lockdbsuccesstext' => 'La base dat ëd {{SITENAME}} a l\'è staita blocà.
+<br />Che as visa mach dë gavé ël blocagi pen-a che a l\'ha finì soa manutension.',
+'unlockdbsuccesstext' => ' La base dat ëd {{SITENAME}} a l\'è staita dësblocà.',
+'makesysoptitle' => 'Deje a n\'utent la qualìfica da aministrator',
+'makesysoptext' => 'Sta domanda-sì a la dòvro ij mangiapapé për deje a n\'utent normal la qualìfica da aministrator.
+Che a scriva lë stranòm dl\'utent che a veul fé aministrator e peuj che a sgnaca ël boton për deje la qualìfica.',
+'makesysopname' => 'Stranòm:',
+'makesysopsubmit' => 'Daje a st\'utent-sì la qualìfica da aministrator',
+'makesysopok' => '<b>L\'utent "$1" adess a l\'é n\'aministrator</b>',
+'makesysopfail' => '<b>L\'utent "$1" as peul pa felo aminìstrator. (Fuss-lo pa mai che a l\'avèissa butà un nòm nen giust?)</b>',
+'setbureaucratflag' => 'Deje a st-utent-sì la qualìfica ëd Mangiapapé',
+'rightslog' => 'Drit dj\'utent',
+'rightslogtext' => 'Sòn a l\'é na lista dij cambiament aj drit dj\'utent.',
+'rightslogentry' => 'a l\'ha tramudà $1 da \'nt la partìa $2 a la partìa $3',
+'rights' => 'Drit:',
+'set_user_rights' => 'Deje sò drit a j\'utent',
+'user_rights_set' => '<b>Ij drit dl\'utent për "$1" a son stait modificà</b>',
+'set_rights_fail' => '<b>As peul pa buteje sò drit a "$1". (Ha-lo pa mai scrivù mal lë stranòm?)</b>',
+'makesysop' => 'Deje a n\'utent la qualìfica da aministrator',
+'already_sysop' => 'St\'Utent-sì a l\'é già n\'aministrator (administrator)',
+'already_bureaucrat' => 'St\'Utent-sì a l\'é già un Mangiapapé (bureaucrat)',
+'rightsnone' => '(gnun)',
+'movepage' => 'Tramudé na pàgina',
+'movepagetext' => 'Con ël mòdulo ëd domanda ambelessì sota a peul cangeje nòm a na pàgina, tramudand-je dapress ëdcò tuta soa cronologìa anvers al nòm neuv.
+Ël vej tìtol a resterà trasformà ant na ridiression che a men-a al tìtol neuv.
+J\'anliure a la veja pàgina a saran NEN agiornà (e donca a men-eran la gent a la ridiression); che a fasa atension dë
+[[Special:Manutenzioni|controlé con cura]] che as creo pa dle ridiression dobie ò dle ridiression che men-o da gnun-a part.
+A resta soa responsabilità cola dë esse sigur che j\'anliure a men-o la gent andoa che a devo mnela.
+
+Noté bin: la pàgina a sarà \'\'\'nen\'\'\' tramudà se a-i fussa già mai n\'articol che a l\'ha ël nòm neuv, gavà col cas che a sia na pàgina veujda ò pura na ridiression, sempre che bele che essend mach parej a l\'abia già nen na soa cronologìa.
+Sòn a veul dì che, se a l\'avèissa mai da fé n\'operassion nen giusta, a podrìa sempe torné a rinominé la pàgina col nòm vej, ma ant gnun cas a podrìa coerté na pàgina che a-i é già.
+
+<b>ATENSION!</b>
+Un cambiament dràstich parej a podrìa dé dle gran-e che un a së speta pa gnanca. Sòn dzortut se a fussa fait dzora a na pàgina motobin visità. Che a varda mach dë esse pì che sigur d\'avej presente le conseguense, prima che fé che fé. Se a l\'ha dij dùbit, che a contata pura n\'aministrator për ciameje \'d consej.',
+'movepagetalktext' => 'La pàgina ëd discussion tacà a costa pàgina d\'articol, se a-i é, a sarà tramudà n\'automatich ansema a l\'artìcol, \'\'\'gavà costi cas-sì\'\'\':
+*quand as tramuda la pàgina tra diferent spassi nominal,
+*quand na pàgina ëd discussion nen veujda a-i é già për ël nòm neuv, ò pura
+*a l\'ha deselessionà ël quadrèt ëd conferma ambelessì sota.
+Ant 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' => 'Cang-je nòm a l\'artìcol',
+'movenologin' => 'Che a varda che chiel (chila) a l\'è pa rintrà ant ël sistema',
+'movenologintext' => 'A venta esse n\'Utent registrà e esse [[Special:Userlogin|rintrà ant ël sistema]]
+për podej tramudé na pàgina.',
+'newtitle' => 'Neuv tìtol ëd',
+'movepagebtn' => 'Tramuda sta pàgina-sì',
+'pagemovedsub' => 'San Martin bele finì!',
+'pagemovedtext' => 'La pàgina "[[$1]]" a l\'ha cangià nòm an "[[$2]]".',
+'articleexists' => 'Na pàgina che as ciama parej a-i é già, ò pura ël nòm che a l\'ha sërnù a va nen bin.<br />
+Che as sërna, për piasì, un nòm diferent për st\'articol.',
+'talkexists' => 'La pàgina a l\'é staita bin tramudà, ma a l\'é pa podusse tramudé soa pàgina ëd discussion, përchè a-i në j\'é già n\'àutra ant la pàgina con ël tìtol neuv. Për piasì, che a modìfica a man ij contnù dle doe pàgine ëd discussion, an manera che as perdo nen dij pensé anteressant.',
+'movedto' => 'tramudà a',
+'movetalk' => 'Podend, tramuda ëdcò la pàgina ëd discussion che a l\'ha tacà.',
+'talkpagemoved' => 'Ëdcò la pàgina ëd discussion colegà a l\'é staita tramudà',
+'talkpagenotmoved' => 'La pàgina ëd discussion colegà <strong>a l\'é nen ëstaita tramudà</strong>.',
+'1movedto2' => '[[$1]] Tramudà a [[$2]]',
+'1movedto2_redir' => '[[$1]] tramudà a [[$2]] ën passand për na ridiression',
+'movelogpage' => 'Registr dij San Martin',
+'movelogpagetext' => 'Ambelessì sota a-i é na lista ëd pàgine che a son staite tramudà.',
+'movereason' => 'Motiv',
+'revertmove' => 'buta torna coma a l\'era',
+'delete_and_move' => 'Scancela e tramuda',
+'delete_and_move_text' => '==A fa da manca dë scancelé==
+
+L\'artìcol ëd destinassion "[[$1]]" a-i é già. Veul-lo scancelelo për avej ëd pòst për tramudé l\'àutr?',
+'delete_and_move_confirm'=> 'É, scancela la pàgina',
+'delete_and_move_reason'=> 'Scancelà për liberé ël pòst për tramudene n\'àutra',
+'selfmove' => 'Tìtol neuv e tìtol vej a resto midem antra lor; as peul pa tramudesse na pàgina butand-la andoa che a l\'é già.',
+'immobile_namespace' => '[[Belavans]] ël tìtol ëd destinassion a l\'é ëd na sòrt riservà; as peulo pa tramudé dle pàgine anvers a col ëspassi nominal-lì.',
+'export' => 'Esporté dle pàgine',
+'exporttext' => 'A peul esporté ël test e modifiché la stòria ëd na pàgina ò pura
+ëd n\'ansema ëd pàgine gropa ant n\'archivi XML. Sòn a peul peuj amportesse
+ant n\'àutra wiki ën dovrand la funsion Special:Ampòrta pàgina.
+
+Për esporté le pàgine, che a së scriva ij tìtoj ant ël quàder ambelessì sota, butand-ji un tìtol për riga,
+e che as serna se a veul la version corenta ansema a cole veje, con le righe che conto la stòria dla pàgina,
+ò pura mach l\'anformassion ant sël quand che a sia staje l\'ùltima modìfica.
+
+Se costa ùltima possibilità a fussa lòn che a-j serv, a podrìa ëdcò dovré n\'anliura, pr\'esempi [[Special:Export/{{Mediawiki:Mainpage}}]] për la pàgina {{Mediawiki:Mainpage}}.',
+'exportcuronly' => 'Ciapa sù mach la version corenta, pa tuta la stòria',
+'exportnohistory' => '----
+\'\'\'Nòta:\'\'\' la possibilità d\'esporté la stòria completa dle pàgine a l\'é staita gavà për dle question corelà a le prestassion dël sistema.',
+'export-submit' => 'Esporté',
+'allmessages' => 'Messagi ëd sistema',
+'allmessagesname' => 'Nòm',
+'allmessagesdefault' => 'Test che a-i sarìa se a-i fusso pa \'d modìfiche',
+'allmessagescurrent' => 'Test corent',
+'allmessagestext' => 'Costa-sì a l\'é na lista ëd tùit ij messagi ëd sistema ant lë spassi nominal MediaWiki:',
+'allmessagesnotsupportedUI'=> 'Soa antërfacia an lenga <b>$1</b> a l\'é nen ativa ansima a Special:Tùit_ij_messagi dzora ës sit-sì.',
+'allmessagesnotsupportedDB'=> 'Special:Tùit_ij_messagi a travaja nen përchè a-i é ël component wgUseDatabaseMessages frëmm.',
+'allmessagesfilter' => 'Seletor dël nòm dël messagi:',
+'allmessagesmodified' => 'Most-me mach lòn che a l\'é modificasse',
+'thumbnail-more' => 'Slarga',
+'missingimage' => '<b>Figura che a manca</b><br /><i>$1</i>',
+'filemissing' => 'Archivi che a manca',
+'thumbnail_error' => 'Eror antramentr che as fasìa la figurin-a: $1',
+'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é.
+Date dle revision e stranòm dj\'editor a resteran piajit sù \'cò lor.
+Tute le amportassion antra wiki diferente a resto marcà ant ël [[Special:Log/import|Registr dj\'amportassion]].',
+'import-interwiki-history'=> 'Còpia tute le version stòriche dë sta pàgina-sì',
+'import-interwiki-submit'=> 'Amporté',
+'importtext' => 'Për piasì, che as espòrta l\'archivi da \'nt la sorgiss wiki esterna ën dovrand l\'utiss Special:Esportassion, che as lo salva ansima a sò disch e peui che a lo caria ambelessì.',
+'importstart' => 'I soma antramentr che amportoma le pàgine...',
+'import-revision-count' => '$1 revision',
+'importnopages' => 'Pa gnun-a pàgina da amporté',
+'importfailed' => 'Amportassion falìa: $1',
+'importunknownsource' => 'Sorgiss d\'amportassion ëd na sòrt nen conossùa',
+'importcantopen' => 'L\'archivi da amporté a l\'é pa podusse deurbe',
+'importbadinterwiki' => 'Anliura antra wiki diferente malfaita',
+'importnotext' => 'Veujd ò sensa pa gnun test',
+'importsuccess' => 'Amportassion andaita a bon fin!',
+'importhistoryconflict' => 'A-i son dle stòrie dë sta pàgina-sì che as contradisso un-a con l\'àutra (a peul esse che sta pàgina-sì a l\'avèissa già amportala)',
+'importnosources' => 'A l\'é pa staita definìa gnun-a sorgiss d\'amportassion da na wiki diferenta, e carié mach le stòrie as peul nen.',
+'importnofile' => 'Pa gnun archivi d\'amportassion carià.',
+'importuploaderror' => 'L\'archivi da amporté a l\'é pa podusse carié; miraco a fussa mai pì gròss che ël màssim consentì?',
+'importlogpage' => 'Registr dj\'amportassion',
+'importlogpagetext' => 'Amportassion aministrative ëd pàgine e ëd soa stòria da dj\'àutre wiki.',
+'import-logentry-upload'=> 'amportà [[$1]] con un càrich d\'archivi',
+'import-logentry-upload-detail'=> '$1 revision',
+'import-logentry-interwiki'=> 'Amportà da n\'àutra wiki $1',
+'import-logentry-interwiki-detail'=> '$1 revision da $2',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'c',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'Sërca an {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Marca sossì coma modìfica cita [alt-i]',
+'tooltip-save' => 'Salva le modìfiche [alt-s]',
+'tooltip-preview' => 'Preuva dle modìfiche (mej sempe fela, prima che fé che salvé!) [alt-p]',
+'tooltip-diff' => 'Fame vëdde che modìfiche che i l\'hai faje al test. [alt-v]',
+'tooltip-compareselectedversions'=> 'Fame ël paragon dle diferense antra le version selessionà. [alt-v]',
+'tooltip-watch' => 'Gionta sta pàgina-sì a la lista dle ròbe che im ten-o sot euj [alt-w]',
+'common.css' => '/** Ël còdes CSS che as buta ambelessì a resta dovrà ant tute le "facie" */',
+'monobook.css' => '/* cangé st\'archivi-sì për modifiché la formatassion dël sit antregh */',
+'nodublincore' => 'Ij metadat dla sòrt \'\'\'Dublin Core RDF\'\'\' a son disabilità ansima a sta màchina-sì.',
+'nocreativecommons' => 'Ij metadat dla sòrt \'\'\'Creative Commons RDF\'\'\' a son disabilità ansima a sta màchina-sì.',
+'notacceptable' => 'Ël server dla wiki a-i la fa pa a provëdde dij dat ant na forma che sò programa local a peula lese.',
+'anonymous' => 'Utent anònim ëd la {{SITENAME}}',
+'siteuser' => '$1, utent ëd {{SITENAME}}',
+'lastmodifiedatby' => 'Sta pàgina-sì a l\'é staita modificà l\'ùltima vira al $2, $1 da $3.',
+'and' => 'e',
+'othercontribs' => 'Basà ant sëj travaj ëd $1.',
+'others' => 'àutri',
+'siteusers' => '$1, utent ëd {{SITENAME}}',
+'creditspage' => 'Credit dla pàgina',
+'nocredits' => 'A-i é pa gnun crédit për sta pagina-sì.',
+'spamprotectiontitle' => 'Filtror dla rumenta',
+'spamprotectiontext' => 'La pàgina che a vorìa salvé a l\'é staita blocà dal filtror dla rumenta. Sòn a l\'é motobin belfé che a sia rivà përchè a-i era n\'anliura a un sit estern ëd coj blocà.',
+'spamprotectionmatch' => 'Cost-sì a l\'é ël test che a l\'é restà ciapà andrinta al filtror dla rumenta: $1',
+'subcategorycount' => 'An sta categorìa-sì a-i {{PLURAL:$1|é mach na sotacategorìa|son $1 sotacategorìe}}.',
+'categoryarticlecount' => 'A-i {{PLURAL:$1|é|son}} $1 {{PLURAL:$1|artìcol|artìcoj}} andrinta a la categorìa.',
+'listingcontinuesabbrev'=> ' anans',
+'spambot_username' => 'MediaWiki - trigomiro che a-j dà deuit a la rumenta',
+'spam_reverting' => 'Buta andaré a l\'ùltima version che a l\'avèissa pa andrinta dj\'anliure a $1',
+'spam_blanking' => 'Pàgina dësveujdà, che tute le version a l\'avìo andrinta dj\'anliure a $1',
+'infosubtitle' => 'Anformassion për la pàgina',
+'numedits' => 'Nùmer ëd modìfiche (artìcol): $1',
+'numtalkedits' => 'Nùmer ëd modìfiche (pàgina ëd discussion): $1',
+'numwatchers' => 'Nùmer d\'utent che as ten-o sossì sot euj: $1',
+'numauthors' => 'Nùmer d\'autor diferent (artìcol): $1',
+'numtalkauthors' => 'Nùmer d\'autor distint (pàgina ëd discussion): $1',
+'mw_math_png' => 'Most-lo sempe coma PNG',
+'mw_math_simple' => 'But-lo an HTML se a l\'é motobin belfé a fesse, dësnò but-lo an PNG',
+'mw_math_html' => 'But-lo an HTML se as peul, dësnò an PNG',
+'mw_math_source' => 'Lass-lo coma TeX (për ij programa ëd navigassion testual)',
+'mw_math_modern' => 'As racomanda për ij programa ëd navigassion pì modern',
+'mw_math_mathml' => 'But-lo an MathML se as peul (sperimental)',
+'markaspatrolleddiff' => 'Marca coma verificà',
+'markaspatrolledtext' => 'Marca st\'artìcol-sì coma verificà',
+'markedaspatrolled' => 'Marca dla verìfica butà',
+'markedaspatrolledtext' => 'La version selessionà a l\'é staita marcà coma verificà.',
+'rcpatroldisabled' => 'Verìfica dj\'ùltime modìfiche disabilità',
+'rcpatroldisabledtext' => 'La possibilità ëd verifichè j\'ùltime modìfiche a l\'é disabilità.',
+'markedaspatrollederror'=> 'As peul pa marchè verificà',
+'markedaspatrollederrortext'=> 'A venta che a specìfica che version che a veul marchè verificà.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Mia pàgina Utent.\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Pàgina Utent për l\'IP dont a scriv coma anònim.\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Mia pàgina ëd discussion e ciaciarade.\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Pàgina ëd ciaciarade për l\'IP dont chiel a scriv coma anònim.\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Coma che i veuj mia wikipedia.\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Lista dle pàgine che chiel as ten sot euj.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Sòn i l\'hai falo mi! \');
+ ta[\'pt-login\'] = new Array(\'o\',\'Un a l\'é nen obligà a rintré ant al sistema, ma se a lo fa a l\'é mej.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Un a l\'é nen obligà a rintré ant al sistema, ma se a lo fa a l\'é mej.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Seurte da \'nt ël sistema.\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Discussion ansima a sta pàgina ëd contnù.\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Modifiché sta pàgina-sì. Për piasì, che as fasa na preuva anans che salvé .\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Gionteje un coment a sta discussion-sì.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Sta pàgina-sì a l\'é proteta, ma as peul ës-ciairene la sorgiss.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Veje version dla pàgina.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Për protege sta pàgina-sì.\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Scancelé sta pàgina-sì\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Pijé andré le modìfiche faite a sta pàgina-sì, anans che a fussa scancelà.\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Tramudé sta pàgina, visadì cangeje tìtol.\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Gionté sta pàgina-sì a la lista dle ròbe che as ten-o sot euj.\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Gavé via sta pàgina da \'nt la lista dle ròbe che as ten sot euj.\');
+ ta[\'search\'] = new Array(\'f\',\'Sërché \'d ròba për la wiki.\');
+ ta[\'p-logo\'] = new Array(\'\',\'Pàgina prinsipal.\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Visité la pàgina prinsipal.\');
+ ta[\'n-portal\'] = new Array(\'\',\'Rësguard al proget, lòn che a peul fé, andoa trové còsa.\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Informassion ansima a lòn che a-i riva.\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Lista dj\'ùltime modìfiche ant la wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Carié na pàgina basta che a sia.\');
+ ta[\'n-help\'] = new Array(\'\',\'Ël pòst për capì.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Dene na man.\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lista ëd tute le pàgine dla wiki che a men-o ambelessì.\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Ùltime modìfiche dle pàgine andoa as peul andesse da costa.\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed për sta pàgina-sì.\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed për sta pàgina-sì.\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Vardé la lista dle contribussion dë st\'Utent-sì.\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Mandeje un messagi ëd pòsta a st\'Utent-sì\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Carié archivi ëd figure ò son.\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lista ëd tute le pàgine speciaj.\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vardé la pàgina ëd contnù.\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vardé la pàgina Utent.\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Vardé la pàgina dl\'archivi.\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Costa a l\'é na pàgina special, as peul pa modifichesse.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Vardé la pàgina proteta.\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Vardé la pàgina dl\'archivi.\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vardé ël messagi ëd sistema.\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vardé lë stamp.\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vardé la pàgina d\'agiut.\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vardé la pàgina dla categorìa.\');',
+'deletedrevision' => 'Veja version scancelà $1.',
+'previousdiff' => '← Diferensa prima',
+'nextdiff' => 'Diferensa che a-i ven →',
+'imagemaxsize' => 'Ten le figure andrinta a le pàgine ëd descrission dle figure ant ël lìmit ëd:',
+'thumbsize' => 'Amzura dle figurin-e:',
+'showbigimage' => 'Dëscarijmne na version a àuta risolussion ($1x$2, $3 KB)',
+'newimages' => 'Galerìa ëd figure e son neuv',
+'showhidebots' => '($1 trigomiro)',
+'noimages' => 'Pa gnente da vëdde.',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+'specialloguserlabel' => 'Utent:',
+'speciallogtitlelabel' => 'Tìtol:',
+'passwordtooshort' => 'Soa ciav a l\'é pa assé longa. A la dev avej almanch $1 caràter.',
+'mediawarning' => '\'\'\'Atension!\'\'\': st\'archivi-sì a podrìa avej andrinta dël còdes butà-lì da cheidun për fé ëd darmagi, e se parej a fussa, ën fasend-lo travajé ansima a sò calcolador chiel a podrìa porteje ëd dann a sò sistema.
+<hr />',
+'fileinfo' => 'amzura $1[[Kilobyte|KB]], sòrt [[MIME]]: <code>[[$2]]</code>',
+'metadata' => 'Dat adissionaj',
+'metadata-help' => 'Costi-sì a son dij dat adissionaj, che a l\'é belfé che a sio stait giontà da la màchina fotogràfica digital ò pura da lë scanner che a l\'é stiat dovrà për creé la figura digital. Se la figura a fussa mai staita modificà da \'nt soa forma original, a podrìa ëdcò riveje che chèich detaj a fussa ancò butà coma ant l\'original, donca sensa pa ten-e cont ëd le modìfiche.',
+'metadata-expand' => 'Most-me tùit ij dat',
+'metadata-collapse' => 'Stërma ij dat adissionaj',
+'exif-imagewidth' => 'Larghëssa',
+'exif-imagelength' => 'Autëssa',
+'exif-bitspersample' => 'Bit për campion',
+'exif-compression' => 'Schema ëd compression',
+'exif-photometricinterpretation'=> 'Composission dij pixel',
+'exif-orientation' => 'Orientament',
+'exif-samplesperpixel' => 'Nùmer ëd component',
+'exif-planarconfiguration'=> 'Sistemassion dij dat',
+'exif-ycbcrsubsampling' => 'Rapòrt ëd campionament antra Y e C',
+'exif-ycbcrpositioning' => 'Posissionament Y e C',
+'exif-xresolution' => 'Risolussion orizontal',
+'exif-yresolution' => 'Risolussion vertical',
+'exif-resolutionunit' => 'Unità d\'amzura për le coordinà X e Y',
+'exif-stripoffsets' => 'Posission dij dat dla figura',
+'exif-rowsperstrip' => 'Nùmer ëd righe për banda',
+'exif-stripbytecounts' => 'Bytes për banda compressa',
+'exif-jpeginterchangeformat'=> 'Diferensa posissional anvers al SOI dël JPEG',
+'exif-jpeginterchangeformatlength'=> 'Byte ëd dat an formà JPEG',
+'exif-transferfunction' => 'Funsion ëd trasferiment',
+'exif-whitepoint' => 'Pont cromàtich dël bianch',
+'exif-primarychromaticities'=> 'Coordinà cromàtiche dij color primari',
+'exif-ycbcrcoefficients'=> 'Coeficent dla matriss ëd trasformassion dlë spassi color',
+'exif-referenceblackwhite'=> 'Pàira ëd valor d\'arferiment për bianch e nèir',
+'exif-datetime' => 'Data e ora dle modìfiche',
+'exif-imagedescription' => 'Tìtol dla figura',
+'exif-make' => 'Fabricant dla màchina fotogràfica ò videocàmera',
+'exif-model' => 'Model dla màchina',
+'exif-software' => 'Programa dovrà',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Titolar dël drit d\'autor',
+'exif-exifversion' => 'Version dël formà Exif',
+'exif-flashpixversion' => 'A riva a la version Flashpix',
+'exif-colorspace' => 'Spassi color',
+'exif-componentsconfiguration'=> 'Sust ëd vira component',
+'exif-compressedbitsperpixel'=> 'Sistema ëd compression dle figure',
+'exif-pixelydimension' => 'Larghëssa vàlida dla figura',
+'exif-pixelxdimension' => 'Autëssa vàlida dla figura',
+'exif-makernote' => 'Nòte dël fabricant',
+'exif-usercomment' => 'Nòte lìbere',
+'exif-relatedsoundfile' => 'Archivi audio colegà',
+'exif-datetimeoriginal' => 'Data e ora dla generassion dij dat',
+'exif-datetimedigitized'=> 'Data e ora dla digitalisassion',
+'exif-subsectime' => 'Data, ora e frassion ëd second',
+'exif-subsectimeoriginal'=> 'Data e ora ëd creassion, con frassion ëd second',
+'exif-subsectimedigitized'=> 'Data e ora ëd digitalisassion, con frassion ëd second',
+'exif-exposuretime' => 'Temp d\'esposission',
+'exif-exposuretime-format'=> '$1 sec ($2)',
+'exif-fnumber' => 'Nùmer d\'F',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Programa d\'esposission',
+'exif-spectralsensitivity'=> 'Sensibilità dë spetro',
+'exif-isospeedratings' => 'Sensibilità ISO',
+'exif-oecf' => 'Fator ëd conversion optoeletrònica',
+'exif-shutterspeedvalue'=> 'Temp dë scat',
+'exif-aperturevalue' => 'Diaframa',
+'exif-brightnessvalue' => 'Luminosità',
+'exif-exposurebiasvalue'=> 'Coression dl\'esposission',
+'exif-maxaperturevalue' => 'Apertura màssima',
+'exif-subjectdistance' => 'Distansa dël soget',
+'exif-meteringmode' => 'Càlcol dl\'espossision',
+'exif-lightsource' => 'Sorgiss d\'anluminassion',
+'exif-flash' => 'Flash',
+'exif-focallength' => 'Lunghëssa focal dle lent',
+'exif-focallength-format'=> '$1 mm',
+'exif-subjectarea' => 'Spassi d\'anquadratura dël soget',
+'exif-flashenergy' => 'Potensa dël flash',
+'exif-spatialfrequencyresponse'=> 'Arspòsta an frequensa spassial',
+'exif-focalplanexresolution'=> 'Resolussion dla coordinà X ant sël pian dla focal',
+'exif-focalplaneyresolution'=> 'Resolussion dla coordinà Y ant sël pian dla focal',
+'exif-focalplaneresolutionunit'=> 'Unità d\'amzura për ël pian dla focal',
+'exif-subjectlocation' => 'Posission dël soget',
+'exif-exposureindex' => 'Ìndes dl\'esposission',
+'exif-sensingmethod' => 'Metod ëd campionament',
+'exif-filesource' => 'Sorgiss dl\'archivi',
+'exif-scenetype' => 'Sòrt d\'anquadratura',
+'exif-cfapattern' => 'Schema CFA',
+'exif-customrendered' => 'Process dla figura particolar',
+'exif-exposuremode' => 'Modalità dl\'esposission',
+'exif-whitebalance' => 'Balansa dël bianch',
+'exif-digitalzoomratio' => 'Rapòrt ëd lë zoom digital',
+'exif-focallengthin35mmfilm'=> 'Lunghëssa focal an film da 35 mm',
+'exif-scenecapturetype' => 'Sistema ëd campionament',
+'exif-gaincontrol' => 'Contròl ëd sienari',
+'exif-contrast' => 'Contrast',
+'exif-saturation' => 'Saturassion',
+'exif-sharpness' => 'Definission dij bòrd',
+'exif-devicesettingdescription'=> 'Nòm dla configurassion dl\'aparechiatura',
+'exif-subjectdistancerange'=> 'Ragg ëd distansa dël soget',
+'exif-imageuniqueid' => 'Identificator ùnich dla figura',
+'exif-gpsversionid' => 'Version dël GPS',
+'exif-gpslatituderef' => 'Latitùdin setentrional ò meridional',
+'exif-gpslatitude' => 'Latitùdin',
+'exif-gpslongituderef' => 'Longitùdin oriental ò ossidental',
+'exif-gpslongitude' => 'Longitùdin',
+'exif-gpsaltituderef' => 'Arferiment d\'autëssa',
+'exif-gpsaltitude' => 'Autëssa',
+'exif-gpstimestamp' => 'Ora dël GPS (mostra atòmica)',
+'exif-gpssatellites' => 'Satélit dovrà për l\'amzura',
+'exif-gpsstatus' => 'Condission dël ricevitor',
+'exif-gpsmeasuremode' => 'Sistema d\'amzura',
+'exif-gpsdop' => 'Precision dl\'amzura',
+'exif-gpsspeedref' => 'Unità d\'amzura për la velocità',
+'exif-gpsspeed' => 'Velocità dël ricevitor GPS',
+'exif-gpstrackref' => 'Arferiment për la diression dël moviment',
+'exif-gpstrack' => 'Diression dël moviment',
+'exif-gpsimgdirectionref'=> 'Arferiment për la diression dla figura',
+'exif-gpsimgdirection' => 'Diression dla figura',
+'exif-gpsmapdatum' => 'Dat dl\'amzura geodética che a son dovrà',
+'exif-gpsdestlatituderef'=> 'Arferiment për la latitùdin dla destinassion',
+'exif-gpsdestlatitude' => 'Latitùdin dla destinassion',
+'exif-gpsdestlongituderef'=> 'Arferiment për la longitùdin dla destinassion',
+'exif-gpsdestlongitude' => 'Longitùdin dla destinassion',
+'exif-gpsdestbearingref'=> 'Arferiment për l\'orientament a destinassion',
+'exif-gpsdestbearing' => 'Orientament anvers a la destinassion',
+'exif-gpsdestdistanceref'=> 'Arferiment për la lontanansa da \'nt la destinassion',
+'exif-gpsdestdistance' => 'Lontanansa da \'nt la destinassion',
+'exif-gpsprocessingmethod'=> 'Nòm dël sistema ëd process an GPS',
+'exif-gpsareainformation'=> 'Nòm dlë spassi GPS',
+'exif-gpsdatestamp' => 'Data dël GPS',
+'exif-gpsdifferential' => 'Coression diferensial dël GPS',
+'exif-compression-1' => 'Pa compress',
+'exif-compression-6' => 'JPEG',
+'exif-photometricinterpretation-2'=> 'RGB',
+'exif-photometricinterpretation-6'=> 'YCbCr',
+'exif-orientation-1' => 'Normal',
+'exif-orientation-2' => 'Specolar',
+'exif-orientation-3' => 'Arvirà ëd 180°',
+'exif-orientation-4' => 'Arvirà dzorsuta',
+'exif-orientation-5' => 'Arvirà dzorsota e ëd 90° contramostra',
+'exif-orientation-6' => 'Arvirà ëd 90° ant ël sens dla mostra',
+'exif-orientation-7' => 'Arvirà dzorsota e ëd 90° ant ël sens dla mostra',
+'exif-orientation-8' => 'Arvirà ëd 90° contramostra',
+'exif-planarconfiguration-1'=> 'për blòch (chunky)',
+'exif-planarconfiguration-2'=> 'an planar',
+'exif-xyresolution-i' => '$1 pont për pòles (dpi)',
+'exif-xyresolution-c' => '$1 pont për centim (dpc)',
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h'=> 'Nen calibrà',
+'exif-componentsconfiguration-0'=> 'a esist pa',
+'exif-componentsconfiguration-1'=> 'Y',
+'exif-componentsconfiguration-2'=> 'Cb',
+'exif-componentsconfiguration-3'=> 'Cr',
+'exif-componentsconfiguration-4'=> 'R',
+'exif-componentsconfiguration-5'=> 'G',
+'exif-componentsconfiguration-6'=> 'B',
+'exif-exposureprogram-0'=> 'Nen definì',
+'exif-exposureprogram-1'=> 'Manual',
+'exif-exposureprogram-2'=> 'Programa normal',
+'exif-exposureprogram-3'=> 'Priorità ëd temp',
+'exif-exposureprogram-4'=> 'Priorità ëd diaframa',
+'exif-exposureprogram-5'=> 'Programa creativ (coregiù për avej pì ëd profondità \'d camp)',
+'exif-exposureprogram-6'=> 'Programa d\'assion (coregiù për avej ël temp pì curt che as peul)',
+'exif-exposureprogram-7'=> 'Programa ritrat (për fotografìe pijaite da davsin, con lë sfond fòra feu)',
+'exif-exposureprogram-8'=> 'Panorama (sogèt lontan e con lë sfond a feu)',
+'exif-subjectdistance-value'=> '$1 méter',
+'exif-meteringmode-0' => 'as sa nen coma',
+'exif-meteringmode-1' => 'Media',
+'exif-meteringmode-2' => 'Media centrà',
+'exif-meteringmode-3' => 'Quadrèt (Spot)',
+'exif-meteringmode-4' => 'Vàire quadrèt (MultiSpot)',
+'exif-meteringmode-5' => 'Schema (Pattern)',
+'exif-meteringmode-6' => 'Parsial',
+'exif-meteringmode-255' => 'n\'àutr',
+'exif-lightsource-0' => 'Nen marcà',
+'exif-lightsource-1' => 'Lus dël dì',
+'exif-lightsource-2' => 'Fluoressenta',
+'exif-lightsource-3' => 'Lus al tungsten (a incandessensa)',
+'exif-lightsource-4' => 'Flash',
+'exif-lightsource-9' => 'Temp bel',
+'exif-lightsource-10' => 'Temp an-nivolà',
+'exif-lightsource-11' => 'Ombra',
+'exif-lightsource-12' => 'Fluoressensa tipo lus dël dì (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Fluoressensa bianca për ël dì (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Fluoressensa bianca frèida (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Fluoressensa bianca (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Lus stàndard sòrt A',
+'exif-lightsource-18' => 'Lus stàndard sòrt B',
+'exif-lightsource-19' => 'Lus stàndard sòrt C',
+'exif-lightsource-20' => 'Anluminant D55',
+'exif-lightsource-21' => 'Anluminant D65',
+'exif-lightsource-22' => 'Anluminant D75',
+'exif-lightsource-23' => 'Anluminant D50',
+'exif-lightsource-24' => 'Làmpada da studio ISO al tungsten',
+'exif-lightsource-255' => 'Aùtra sorgiss d\'anluminassion',
+'exif-focalplaneresolutionunit-2'=> 'pòles anglèis (inches)',
+'exif-sensingmethod-1' => 'Nen definì',
+'exif-sensingmethod-2' => 'Sensor dlë spassi color a 1 processor',
+'exif-sensingmethod-3' => 'Sensor dlë spassi color a 2 processor',
+'exif-sensingmethod-4' => 'Sensor dlë spassi color a 3 processor',
+'exif-sensingmethod-5' => 'Sensor sequensial dlë spassi color',
+'exif-sensingmethod-7' => 'Sensor trilinear',
+'exif-sensingmethod-8' => 'Sensor linear ëd color sequensiaj',
+'exif-filesource-3' => 'DSC',
+'exif-scenetype-1' => 'Fotografìa an diret',
+'exif-customrendered-0' => 'Process normal',
+'exif-customrendered-1' => 'Process particular',
+'exif-exposuremode-0' => 'Esposission automàtica',
+'exif-exposuremode-1' => 'Esposission manual',
+'exif-exposuremode-2' => 'Esposission automàtica (auto bracket)',
+'exif-whitebalance-0' => 'Balansa dël bianch n\'automàtich',
+'exif-whitebalance-1' => 'Balansa dël bianch an manual',
+'exif-scenecapturetype-0'=> 'Stàndard',
+'exif-scenecapturetype-1'=> 'Paisagi',
+'exif-scenecapturetype-2'=> 'Ritrat',
+'exif-scenecapturetype-3'=> 'La neuit',
+'exif-gaincontrol-0' => 'Gnun',
+'exif-gaincontrol-1' => 'Sparé ij contrast bass',
+'exif-gaincontrol-2' => 'Sparé ij contrast fòrt',
+'exif-gaincontrol-3' => 'Bassé ij contrast bass',
+'exif-gaincontrol-4' => 'Bassé ij contrast fòrt',
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'dosman',
+'exif-contrast-2' => 'contrastà fòrt',
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Saturassion bassa',
+'exif-saturation-2' => 'Saturassion àuta',
+'exif-sharpness-0' => 'Normal',
+'exif-sharpness-1' => 'dossa',
+'exif-sharpness-2' => 'contrastà',
+'exif-subjectdistancerange-0'=> 'Nen specificà',
+'exif-subjectdistancerange-1'=> 'Macro',
+'exif-subjectdistancerange-2'=> 'Prim pian',
+'exif-subjectdistancerange-3'=> 'Anquadratura a soget lontan',
+'exif-gpslatitude-n' => 'Latitùdin setentrional',
+'exif-gpslatitude-s' => 'Latitùdin meridional',
+'exif-gpslongitude-e' => 'Longitùdin oriental',
+'exif-gpslongitude-w' => 'Longitùdin ossidental',
+'exif-gpsstatus-a' => 'Amzura antramentr che as fa',
+'exif-gpsstatus-v' => 'Interoperabilità dl\'amzura',
+'exif-gpsmeasuremode-2' => 'amzura bidimensional',
+'exif-gpsmeasuremode-3' => 'amzura tridimensional',
+'exif-gpsspeed-k' => 'Km/h',
+'exif-gpsspeed-m' => 'mija/h',
+'exif-gpsspeed-n' => 'Grop (marin)',
+'exif-gpsdirection-t' => 'Diression vèira',
+'exif-gpsdirection-m' => 'Diression magnética',
+'edit-externally' => 'Modifiché st\'archivi con un programa estern',
+'edit-externally-help' => 'Che a varda [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] për avej pì d\'anformassion.',
+'recentchangesall' => 'tute',
+'imagelistall' => 'tùit/tute',
+'watchlistall1' => 'tute',
+'watchlistall2' => 'tute',
+'namespacesall' => 'tùit',
+'confirmemail' => 'Confermé l\'adrëssa postal',
+'confirmemail_text' => 'Costa wiki a ciama che chiel a convalida n\'adrëssa postal anans che
+dovré lòn che toca la pòsta. Che a sgnaca ël boton ambelessì sota
+për fesse mandé un messa ëd conferma a soa adrëssa eletrònica.
+Andrinta al messagi a-i sara n\'anliura (URL) con andrinta un còdes.
+Che a deurba st\'anliura andrinta a sò programa ëd navigassion (browser)
+për confermé che soa adrëssa a l\'é pròpe cola.',
+'confirmemail_send' => 'Manda un còdes ëd conferma për pòsta eletrònica',
+'confirmemail_sent' => 'Ël messagi ëd conferma a l\'é stait mandà.',
+'confirmemail_sendfailed'=> 'A l\'é pa podusse mandé ël còdes ëd conferma. Che a controla l\'adrëssa che a l\'ha dane, mai che a-i fusso dij caràter nen vàlid.',
+'confirmemail_invalid' => 'Còdes ëd conferma nen vàlid. A podrìa ëdcò mach esse scadù.',
+'confirmemail_needlogin'=> 'A venta che a fasa $1 për confermé soa addrëssa postal eletrònica.',
+'confirmemail_success' => 'Soa adrëssa postal a l\'é staita confermà, adess a peul rintré ant ël sistema e i-j auguroma da fessla bin ant la wiki!',
+'confirmemail_loggedin' => 'Motobin mersì. Soa adrëssa ëd pòsta eletrònica adess a l\'é confermà.',
+'confirmemail_error' => 'Cheich-còs a l\'é andà mal ën salvand soa conferma.',
+'confirmemail_subject' => 'Conferma dl\'adrëssa postal da \'nt la {{SITENAME}}',
+'confirmemail_body' => 'Cheidun, a l\'é belfé che a sia stait pròpe chiel (ò chila)
+da \'nt l\'adrëssa IP $1, a l\'ha doertà un cont utent "$2"
+ansima a {{SITENAME}}, lassand-ne st\'adrëssa ëd pòsta eletrònica-sì.
+
+Për confermé che ës cont a l\'é da bon sò e për ativé le possibilità
+corelà a la pòsta eletrònica ansima a {{SITENAME}}, che a deurba
+st\'adrëssa-sì andrinta a sò programa ëd navigassion (browser)
+
+$3
+
+Se a fussa *nen* stait chiel a deurbe ël cont, anlora che a fasa gnente.
+Cost còdes ëd conferma a l\'é bon fin-a al $4.',
+'tryexact' => 'Sërca che a sia pròpe parej',
+'searchfulltext' => 'Sërca an tut ël test',
+'createarticle' => 'Crea n\'artìcol',
+'scarytranscludedisabled'=> '[L\'inclusion ëd pàgine antra wiki diferente a l\'é nen abilità]',
+'scarytranscludefailed' => '[Darmagi, ma lë stamp $1 a l\'é pa podusse carié]',
+'scarytranscludetoolong'=> '[Eror: anliura tròp longa]',
+'trackbackbox' => '<div id="mw_trackbacks">
+Anformassion për feje ël traciament a sta vos-sì:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Gava via])',
+'trackbacklink' => 'Traciament',
+'trackbackdeleteok' => 'J\'anformassion për fé traciament a son staite gavà via.',
+'deletedwhileediting' => 'Avertensa: sta pàgina-sì a l\'é staita scancelà quand che chiel (chila) a l\'avìa già anandiasse a modifichela!',
+'confirmrecreate' => 'L\'utent [[User:$1|$1]] ([[User talk:$1|talk]]) a l\'ha scancelà st\'articol-sì quand che chiel (chila) a l\'avia già anandiasse a modifichelo, dand coma motiv ëd la scancelament:
+\'\'$2\'\'
+Për piasì, che an conferma che da bon a veul torna creélo.',
+'recreate' => 'Créa n\'àutra vira',
+'tooltip-recreate' => 'Creé torna la pàgina contut che a la sia staita scancelà',
+'unit-pixel' => 'px',
+'redirectingto' => 'I soma antramentr che i foma na ridiression a [[$1]]...',
+'confirm_purge' => 'Veujdé la memorisassion dë sta pàgina-sì?
+
+$1',
+'confirm_purge_button' => 'Va bin',
+'youhavenewmessagesmulti'=> 'A l\'ha dij neuv messagi an $1',
+'searchcontaining' => 'Sërca le vos che a l\'han andrinta \'\'$1\'\'.',
+'searchnamed' => 'Sërca le vos che a l\'han për tìtol \'\'$1\'\'.',
+'articletitles' => 'Artìcoj che as anandio për \'\'$1\'\'',
+'hideresults' => 'Stërma j\'arsultà',
+'displaytitle' => '(J\'anliure a sta pàgina-sì a van faite coma [[$1]])',
+'loginlanguagelabel' => 'Lenga: $1',
+);
+?>
diff --git a/languages/messages/MessagesPs.php b/languages/messages/MessagesPs.php
new file mode 100644
index 000000000000..439e7cdba153
--- /dev/null
+++ b/languages/messages/MessagesPs.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# Stub for Pashto
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+ # Underlines seriously harm legibility. Force off:
+ 'underline' => 0,
+);
+
+?>
diff --git a/languages/messages/MessagesPt.php b/languages/messages/MessagesPt.php
new file mode 100644
index 000000000000..49672df85332
--- /dev/null
+++ b/languages/messages/MessagesPt.php
@@ -0,0 +1,2001 @@
+<?php
+/** Portuguese (Português)
+ * This translation was made by:
+ * - Yves Marques Junqueira
+ * - Rodrigo Calanca Nishino
+ * - Nuno Tavares
+ * - Paulo Juntas
+ * - Manuel Menezes de Sequeira
+ * - Sérgio Ribeiro
+ * from the Portuguese Wikipedia
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media', # -2
+ NS_SPECIAL => 'Especial', # -1
+ NS_MAIN => '', # 0
+ NS_TALK => 'Discussão', # 1
+ NS_USER => 'Usuário',
+ NS_USER_TALK => 'Usuário_Discussão',
+/*
+ Above entries are for PT_br. The following entries should
+ be used instead. But:
+
+ DO NOT USE THOSE ENTRIES WITHOUT MIGRATING STUFF ON
+ WIKIMEDIA WEB SERVERS FIRST !! You will just break a lot
+ of links 8-)
+
+ NS_USER => 'Utilizador', # 2
+ NS_USER_TALK => 'Utilizador_Discussão', # 3
+*/
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_Discussão', # 5
+ NS_IMAGE => 'Imagem', # 6
+ NS_IMAGE_TALK => 'Imagem_Discussão', # 7
+ NS_MEDIAWIKI => 'MediaWiki', # 8
+ NS_MEDIAWIKI_TALK => 'MediaWiki_Discussão', # 9
+ NS_TEMPLATE => 'Predefinição', # 10
+ NS_TEMPLATE_TALK => 'Predefinição_Discussão', # 11
+ NS_HELP => 'Ajuda', # 12
+ NS_HELP_TALK => 'Ajuda_Discussão', # 13
+ NS_CATEGORY => 'Categoria', # 14
+ NS_CATEGORY_TALK => 'Categoria_Discussão' # 15
+);
+
+$quickbarSettings = array(
+ 'Nenhuma', 'Fixo à esquerda', 'Fixo à direita', 'Flutuando à esquerda', 'Flutuando à direita'
+);
+
+$skinNames = array(
+ 'standard' => 'Clássico',
+ 'nostalgia' => 'Nostalgia',
+ 'cologneblue' => 'Azul colonial',
+ 'davinci' => 'DaVinci',
+ 'mono' => 'Mono',
+ 'monobook' => 'MonoBook',
+ 'myskin' => 'MySkin',
+ 'chick' => 'Chick'
+);
+
+# Note to translators:
+# Please include the English words as synonyms. This allows people
+# from other wikis to contribute more easily.
+#
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#REDIRECT', '#redir' ),
+ 'notoc' => array( 0, '__NOTOC__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__' ),
+ 'toc' => array( 0, '__TOC__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__' ),
+ 'start' => array( 0, '__START__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV' ),
+ 'currentday' => array( 1, 'CURRENTDAY' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR' ),
+ 'currenttime' => array( 1, 'CURRENTTIME' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES' ),
+ 'pagename' => array( 1, 'PAGENAME' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE' ),
+ 'namespace' => array( 1, 'NAMESPACE' ),
+ 'msg' => array( 0, 'MSG:' ),
+ 'subst' => array( 0, 'SUBST:' ),
+ 'msgnw' => array( 0, 'MSGNW:' ),
+ 'end' => array( 0, '__END__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1'),
+ 'img_right' => array( 1, 'right', 'direita' ),
+ 'img_left' => array( 1, 'left', 'esquerda' ),
+ 'img_none' => array( 1, 'none', 'nenhum' ),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame' ),
+ 'img_page' => array( 1, 'page=$1', 'page $1' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME' ),
+ 'ns' => array( 0, 'NS:' ),
+ 'localurl' => array( 0, 'LOCALURL:' ),
+ 'localurle' => array( 0, 'LOCALURLE:' ),
+ 'server' => array( 0, 'SERVER' ),
+ 'servername' => array( 0, 'SERVERNAME' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH' ),
+ 'grammar' => array( 0, 'GRAMMAR:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK' ),
+ 'currentdow' => array( 1, 'CURRENTDOW' ),
+ 'revisionid' => array( 1, 'REVISIONID' ),
+);
+
+$separatorTransformTable = array(',' => ' ', '.' => ',' );
+#$linkTrail = '/^([a-z]+)(.*)$/sD';# ignore list
+
+
+
+$messages = array(
+
+# User preference toggles
+'tog-underline' => 'Sublinhar hiperligações',
+'tog-highlightbroken' => 'Formatar links quebrados <a href="" class="new">como isto</a> (alternativa: como isto<a href="" class="internal">?</a>).',
+'tog-justify' => 'Justificar parágrafos',
+'tog-hideminor' => 'Esconder edições secundárias nas mudanças recentes',
+'tog-extendwatchlist' => 'Expandir a lista de artigos vigiados para mostrar todas as alterações aplicáveis',
+'tog-usenewrc' => 'Mudanças recentes melhoradas (JavaScript)',
+'tog-numberheadings' => 'Auto-numerar cabeçalhos',
+'tog-showtoolbar' => 'Mostrar barra de edição (JavaScript)',
+'tog-editondblclick' => 'Editar páginas quando houver clique duplo (JavaScript)',
+'tog-editsection' => 'Habilitar edição de secção via links [editar]',
+'tog-editsectiononrightclick' => 'Habilitar edição de secção por clique <br /> com o botão direito no título da secção (JavaScript)',
+'tog-showtoc' => 'Mostrar Tabela de Conteúdos (para artigos com mais de 3 cabeçalhos)',
+'tog-rememberpassword' => 'Lembrar palavra-chave entre sessões',
+'tog-editwidth' => 'Caixa de edição com largura completa',
+'tog-watchcreations' => 'Adicionar páginas criadas por mim à minha lista de artigos vigiados',
+'tog-watchdefault' => 'Adicionar páginas editadas por mim à minha lista de artigos vigiados',
+'tog-minordefault' => 'Marcar todas as edições como secundárias, por padrão',
+'tog-previewontop' => 'Mostrar previsão antes da caixa de edição ao invés de ser após',
+'tog-previewonfirst' => 'Mostrar previsão na primeira edição',
+'tog-nocache' => 'Desactivar caching de páginas',
+'tog-enotifwatchlistpages' => 'Enviar-me um email quando houver mudanças nas páginas',
+'tog-enotifusertalkpages' => 'Enviar-me um email quando a minha página de discussão for editada',
+'tog-enotifminoredits' => 'Enviar-me um email também quando forem edições menores',
+'tog-enotifrevealaddr' => 'Revelar o meu endereço de email nas notificações',
+'tog-shownumberswatching' => 'mostrar o número de utilizadores a vigiar',
+'tog-fancysig' => 'Assinaturas sem atalhos automáticos.',
+'tog-externaleditor' => 'Utilizar editor externo por padrão',
+'tog-externaldiff' => 'Utilizar diferenças externas por padrão',
+'tog-showjumplinks' => 'Activar hiperligações de acessibilidade "ir para"',
+'tog-uselivepreview' => 'Utilizar pré-visualização em tempo real (JavaScript) (Experimental)',
+'tog-autopatrol' => 'Marcar as minhas edições como verificadas',
+'tog-forceeditsummary' => 'Avisar-me ao introduzir um sumário vazio',
+'tog-watchlisthideown' => 'Esconder as minhas edições da lista de artigos vigiados',
+'tog-watchlisthidebots' => 'Esconder edições efectuadas por robôs da lista de artigos vigiados',
+
+'underline-always' => 'Sempre',
+'underline-never' => 'Nunca',
+'underline-default' => 'Padrão',
+
+'skinpreview' => '(Pré-visualizar)',
+
+# dates
+'sunday' => 'Domingo',
+'monday' => 'Segunda-feira',
+'tuesday' => 'Terça-feira',
+'wednesday' => 'Quarta-feira',
+'thursday' => 'Quinta-feira',
+'friday' => 'Sexta-feira',
+'saturday' => 'Sábado',
+'sun' => 'Dom',
+'mon' => 'Seg',
+'tue' => 'Ter',
+'wed' => 'Qua',
+'thu' => 'Qui',
+'fri' => 'Sex',
+'sat' => 'Sáb',
+'january' => 'Janeiro',
+'february' => 'Fevereiro',
+'march' => 'Março',
+'april' => 'Abril',
+'may_long' => 'Maio',
+'june' => 'Junho',
+'july' => 'Julho',
+'august' => 'Agosto',
+'september' => 'Setembro',
+'october' => 'Outubro',
+'november' => 'Novembro',
+'december' => 'Dezembro',
+'january-gen' => 'Janeiro',
+'february-gen' => 'Fevereiro',
+'march-gen' => 'Março',
+'april-gen' => 'Abril',
+'may-gen' => 'Maio',
+'june-gen' => 'Junho',
+'july-gen' => 'Julho',
+'august-gen' => 'Agosto',
+'september-gen' => 'Setembro',
+'october-gen' => 'Outubro',
+'november-gen' => 'Novembro',
+'december-gen' => 'Dezembro',
+'jan' => 'Jan',
+'feb' => 'Fev',
+'mar' => 'Mar',
+'apr' => 'Abr',
+'may' => 'Mai',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Ago',
+'sep' => 'Set',
+'oct' => 'Out',
+'nov' => 'Nov',
+'dec' => 'Dez',
+
+# Bits of text used by many pages:
+#
+'categories' => 'Categorias',
+'pagecategories' => '{{PLURAL:$1|Categoria|Categorias}}',
+'category_header' => 'Artigos na categoria "$1"',
+'subcategories' => 'Subcategorias',
+
+
+#'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD', # ignore list
+'mainpage' => 'Página principal',
+'mainpagetext' => "<big>'''MediaWiki instalado com sucesso.'''</big>",
+'mainpagedocfooter' => "Consultar o [http://meta.wikimedia.org/wiki/Help:Contents Guia de Utilizadores] para informação acerca de como utilizador o software wiki.
+
+== Começando ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Lista de configuração de ajustes]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki Perguntas e respostas frequentes]
+* [http://mail.wikipedia.org/mailman/listinfo/mediawiki-announce Lista de correio do anúncio de publicações do MediaWiki]",
+
+'portal' => 'Portal comunitário',
+'portal-url' => '{{ns:project}}:Portal comunitário',
+'about' => 'Sobre',
+'aboutsite' => 'Sobre',
+'aboutpage' => '{{ns:project}}:Sobre',
+'article' => 'Artigo',
+'help' => 'Ajuda',
+'helppage' => 'Ajuda:Conteúdos',
+'bugreports' => 'Bug reports',
+'bugreportspage' => '{{ns:project}}:Bug_reports',
+'sitesupport' => 'Doações',
+'sitesupport-url' => '{{ns:project}}:Apoio',
+'faq' => 'FAQ',
+'faqpage' => '{{ns:project}}:FAQ',
+'edithelp' => 'Ajuda de edição',
+'newwindow' => '(abre numa nova janela)',
+'edithelppage' => 'Ajuda:Editar',
+'cancel' => 'Cancelar',
+'qbfind' => 'Procurar',
+'qbbrowse' => 'Navegar',
+'qbedit' => 'Editar',
+'qbpageoptions' => 'Esta página',
+'qbpageinfo' => 'Informação da página',
+'qbmyoptions' => 'Minhas opções',
+'qbspecialpages' => 'Páginas especiais',
+'moredotdotdot' => 'Mais...',
+'mypage' => 'Minha página',
+'mytalk' => 'Minha discussão',
+'anontalk' => 'Discussão para este IP',
+'navigation' => 'Navegação',
+
+# Metadata in edit box
+'metadata_help' => 'Metadata (para uma explicação ver [[{{ns:project}}:Metadata]]):',
+
+'currentevents' => 'Eventos actuais',
+'currentevents-url' => 'Eventos actuais',
+
+'disclaimers' => 'Disclaimers',
+'disclaimerpage' => "{{ns:project}}:General_disclaimer",
+'privacy' => 'Política de privacidade',
+'privacypage' => '{{ns:project}}:Política_de_privacidade',
+'errorpagetitle' => "Erro",
+'returnto' => "Retornar para $1.",
+'tagline' => 'De {{SITENAME}}',
+'help' => 'Ajuda',
+'search' => 'Pesquisa',
+'searchbutton' => 'Pesquisa',
+'go' => 'Ir',
+'searcharticle' => 'Ir',
+"history" => 'Histórico',
+'history_short' => 'História',
+'updatedmarker' => 'actualizado desde a minha última visita',
+'info_short' => 'Informação',
+'printableversion' => 'Versão para impressão',
+'permalink' => 'Ligação permanente',
+'print' => 'Imprimir',
+'edit' => 'Editar',
+'editthispage' => 'Editar esta página',
+'delete' => 'Eliminar',
+'deletethispage' => 'Eliminar esta página',
+'undelete_short' => 'Restaurar $1 edições',
+'protect' => 'Proteger',
+'protectthispage' => 'Proteger esta página',
+'unprotect' => 'Desproteger',
+'unprotectthispage' => 'Desproteger esta página',
+'newpage' => 'Nova página',
+'talkpage' => 'Discutir esta página',
+'specialpage' => 'Página Especial',
+'personaltools' => 'Ferramentas pessoais',
+'postcomment' => 'Envie um comentário',
+'articlepage' => 'Ver artigo',
+'talk' => 'Discussão',
+'views' => 'Vistas',
+'toolbox' => 'Ferramentas',
+'userpage' => 'Ver página de utilizador',
+'projectpage' => 'Ver página do projecto',
+'imagepage' => 'Ver página de imagens',
+'mediawikipage' => 'Ver página de mensagens',
+'templatepage' => 'Ver página de predefinições',
+'viewhelppage' => 'Ver página de ajuda',
+'categorypage' => 'Ver página de categorias',
+'viewtalkpage' => 'Ver discussão',
+'otherlanguages' => 'Outras línguas',
+'redirectedfrom' => '(Redireccionado de <b>$1</b> para <b>{{PAGENAME}}</b>.)',
+'autoredircomment' => 'Redireccionando para [[$1]]',
+'redirectpagesub' => 'Página de redireccionamento',
+'lastmodifiedat' => 'Esta página foi modificada pela última vez a $2, $1.',
+'viewcount' => 'Esta página foi acedida {{plural:$1|uma vez|$1 vezes}}.',
+'copyright' => 'Conteúdo disponível sob $1.',
+'protectedpage' => 'Página protegida',
+'jumpto' => 'Ir para:',
+'jumptonavigation' => 'navegação',
+'jumptosearch' => 'pesquisa',
+
+'badaccess' => 'Erro de permissão',
+'badaccess-group0' => 'Não está autorizado a executar a acção requisitada.',
+'badaccess-group1' => 'A acção que requisitou está limitada a utilizadores do grupo $1.',
+'badaccess-group2' => 'A acção que requisitou está limitada a utilizadores de um dos grupos $1.',
+'badaccess-groups' => 'A acção que requisitou está limitada a utilizadores de um dos grupos $1.',
+
+'versionrequired' => 'Necessária versão $1 do MediaWiki',
+'versionrequiredtext' => 'Esta página requer a versão $1 do MediaWiki para ser utilizada. Consulte [[Special:Version]]',
+
+'ok' => 'OK',
+'pagetitle' => "$1 - {{SITENAME}}",
+'retrievedfrom' => 'Retirado de "$1"',
+'youhavenewmessages' => "Você tem $1 ($2).",
+'newmessageslink' => 'novas mensagens',
+'newmessagesdifflink' => 'comparar com a penúltima revisão',
+'editsection'=>'editar',
+'editold'=>'editar',
+'editsectionhint' => 'Editar secção: $1',
+'toc' => 'Tabela de conteúdo',
+'showtoc' => 'mostrar',
+'hidetoc' => 'esconder',
+'thisisdeleted' => "Ver ou restaurar $1?",
+'viewdeleted' => 'Ver $1?',
+'restorelink' => '{{PLURAL:$1|uma edição eliminada|$1 edições eliminadas}}',
+'feedlinks' => 'Feed:',
+'feed-invalid' => 'Tipo de subscrição feed inválido.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Artigo',
+'nstab-user' => 'Página de utilizador',
+'nstab-media' => 'Media',
+'nstab-special' => 'Especial',
+'nstab-project' => 'Página de projecto',
+'nstab-image' => 'Ficheiro',
+'nstab-mediawiki' => 'Mensagem',
+'nstab-template' => 'Predefinição',
+'nstab-help' => 'Ajuda',
+'nstab-category' => 'Categoria',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Acção não existente',
+'nosuchactiontext' => 'A acção especificada pelo URL não é reconhecida pelo programa da Wikipédia',
+'nosuchspecialpage' => 'Não existe a página especial requesitada',
+'nospecialpagetext' => 'Requesitou uma página especial inválida; uma lista de páginas especiais válidas poderá ser encontrada em [[{{ns:special}}:Specialpages]].',
+
+# General errors
+#
+'error' => 'Erro',
+'databaseerror' => 'Erro na base de dados',
+'dberrortext' => "Ocorreu um erro de sintaxe na pesquisa à base de dados.
+A última tentativa de busca na base de dados foi:
+<blockquote><tt>$1</tt></blockquote>
+na função \"<tt>$2</tt>\".
+MySQL retornou o erro \"<tt>$3: $4</tt>\".",
+'dberrortextcl' => "Ocorre um erro de sintaxe na pesquisa à base de dados.
+A última tentativa de busca na base de dados foi:
+<blockquote><tt>$1</tt></blockquote>
+na função \"<tt>$2</tt>\".
+MySQL retornou o erro \"<tt>$3: $4</tt>\".",
+'noconnect' => 'Pedimos desculpas, mas esta wiki está passando por algumas
+dificuldades técnicas e não pode contactar o servidor da base de dados.',
+'noconnect' => 'Desculpe! A wiki está a experienciar algumas dificuldades técnicas, e não pode contactar o servidor da base de dados. <br />
+$1',
+'nodb' => "Não foi possível seleccionar a base de dados $1",
+'cachederror' => 'A página apresentada é uma cópia em cache da página requisitada, e pode não estar actualizada.',
+'laggedslavemode' => 'Aviso: A página poderá não conter actualizações recentes.',
+'readonly' => 'Base de dados somente para leitura',
+'enterlockreason' => 'Introduza com um motivo para trancar, incluindo uma estimativa de quando poderá novamente ser editada',
+'readonlytext' => "A base de dados da {{SITENAME}} está actualmente trancada para novos
+artigos e outras modificações, provavelmente por uma manutenção de rotina à base de dados, mais tarde voltará ao normal.
+
+O administrador que fez o bloqueio oferece a seguinte explicação: $1",
+'missingarticle' => "A base de dados não encontrou o texto de uma página que deveria ter encontrado: \"$1\".
+
+Isto é geralmente causado pela procura de uma diferença num antigo ou num histórico que leva a uma página que foi eliminada.
+
+Se este não for o caso, você pode ter encontrado um ''bug'' no software.
+Por favor, tome nota do URL e comunique o erro a um [[{{ns:project}}:Administradores|administrador]].",
+'readonly_lag' => "A base de dados foi automaticamente bloqueada para sincronização",
+'internalerror' => 'Erro interno',
+'filecopyerror' => "Não foi possível copiar o ficheiro \"$1\" para \"$2\".",
+'filerenameerror' => "Não foi possível renomear o ficheiro \"$1\" para \"$2\".",
+'filedeleteerror' => "Não foi possível eliminar o ficheiro \"$1\".",
+'filenotfound' => "Não foi possível encontrar o ficheiro \"$1\".",
+'unexpected' => "Valor não esperado: \"$1\"=\"$2\".",
+'formerror' => 'Erro: Não foi possível enviar o formulário',
+'badarticleerror' => 'Esta acção não pode ser realizada nesta página.',
+'cannotdelete' => 'Não foi possível eliminar a página ou imagem especificada (Pode ter sido já eliminada por outro administrador.)',
+'badtitle' => 'Título inválido',
+'badtitletext' => "O título de página requisitada era inválido, vazio, ou uma ligação incorrecta de inter-linguagem ou título inter-wiki.
+No qual pode conter um ou mais caracteres que não podem ser utilizados em títulos.",
+'perfdisabled' => 'Esta opção foi temporariamente desabilitada,
+devido a tornar a base de dados lenta demais a ponto de impossibilitar a wiki.',
+'perfdisabledsub' => "Aqui pode ver uma cópia de $1 salvaguardada:", # obsolete?
+'perfcached' => 'Os dados seguintes encontram-se na cache e podem não estar actualizados.',
+'perfcachedts' => 'Os seguintes dados encontram-se armazenados na cache e foram actualizados pela última vez a $1.',
+
+'wrong_wfQuery_params' => "Parâmetros incorrectos para wfQuery()<br />
+Function: $1<br />
+Query: $2",
+'viewsource' => 'Ver fonte',
+'viewsourcefor' => 'para $1',
+'protectedtext' => "Esta página foi protegida para não permitir edições; existem inúmeros motivos para
+ocorrer esta situação, por favor consulte [[{{ns:project}}:Página protegida]].
+
+Pode ver e copiar o código fonte desta página:",
+'protectedinterface' => 'Esta página fornece texto de interface ao software, e encontra-se trancada para prevenir abusos.',
+'editinginterface' => "'''Aviso:''' Encontra-se a editar uma página que é utilizada para fornecer texto de interface ao software. Alterações nesta página irão afectar a aparência da interface de utilizador para outros utilizadores.",
+'sqlhidden' => '(Consulta SQL escondida)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Saída de utilizador',
+'logouttext' => '<strong>Saiu agora da sua conta.</strong><br />
+Pode continuar a utilizar a {{SITENAME}} anonimamente, ou pode autenticar-se
+novamente como o mesmo nome de utilizador ou com um nome de utilizador diferente. Tenha em atenção que algumas páginas poderão
+continuar a ser apresentadas como se tivesse ainda autenticado, até limpar
+a cache do seu navegador.',
+
+'welcomecreation' => "== Bem-vindo, $1! ==
+
+A sua conta foi criada. Não se esqueça de personalizar as suas [[Special:Preferences|preferências]] na {{SITENAME}}.",
+
+'loginpagetitle' => 'Autenticação de utilizador',
+'yourname' => 'Seu nome de utilizador',
+'yourpassword' => 'Palavra-chave',
+'yourpasswordagain' => 'Reintroduza a sua palavra-chave',
+'remembermypassword' => 'Lembrar a minha palavra-chave entre sessões.',
+'yourdomainname' => 'Seu domínio',
+'externaldberror' => 'Ocorreu um erro externo à base de dados durante a autenticação, ou não lhe é permitido actualizar a sua conta externa.',
+'loginproblem' => '<b>Houve um problema com a sua autenticação.</b><br />Tente novamente!',
+'alreadyloggedin' => "<strong>Utilizador $1, você já está autenticado!</strong><br />",
+'login' => 'Entrar',
+'loginprompt' => "Você necessita de ter os <i>cookies</i> ligados para poder autenticar-se na {{SITENAME}}.",
+'userlogin' => 'Criar uma conta ou entrar',
+'logout' => 'Sair',
+'userlogout' => 'Sair',
+'notloggedin' => 'Não autenticado',
+'nologin' => 'Não possui uma conta? $1.',
+'nologinlink' => 'Criar uma conta',
+'createaccount' => 'Criar conta de utilizador',
+'gotaccount' => 'Já possui uma conta? $1.',
+'gotaccountlink' => 'Entrar',
+'createaccount' => 'Criar nova conta',
+'createaccountmail' => 'por email',
+'badretype' => 'As palavras-chaves que introduziu não são iguais.',
+'userexists' => 'O nome de utilizador que introduziu já existe. Por favor, escolha um nome diferente.',
+'youremail' => 'Endereço de email *:',
+'username' => 'Nome de utilizador:',
+'uid' => 'Número de identificação:',
+'yourrealname' => 'Nome verdadeiro *:',
+'yourlanguage' => 'Idioma:',
+'yourvariant' => 'Variante',
+'yournick' => 'Alcunha:',
+'badsig' => 'Assinatura inválida; verifique o código HTML utilizado.',
+'email' => 'Correio electrónico',
+'prefs-help-email-enotif' => 'Este endereço é também utilizado para enviar-lhe notificações caso as active nas preferências.',
+'prefs-help-realname' => '* Nome verdadeiro (opcional): caso decida indicar, este será utilizado para lhe dar crédito pelo seu trabalho.',
+'loginerror' => 'Erro de autenticação',
+'prefs-help-email' => '* Email (opcional): Permite os utilizadores entrem em contacto consigo sem que tenha de lhes revelar o seu endereço de e-mail.',
+'nocookiesnew' => "A conta de utilizador foi criada, mas você não foi ligado à conta. Tem os <i>cookies</i> desactivados no seu navegador, e a {{SITENAME}} utiliza <i>cookies</i> para ligar os utilizadores às suas contas. Por favor os active, depois autentique-se com o seu nome de utilizador e a sua palavra-chave.",
+'nocookieslogin' => "Você tem os <i>cookies</i> desactivados no seu navegador, e a {{SITENAME}} utiliza <i>cookies</i> para ligar os utilizadores às suas contas. Por favor os active e tente novamente.",
+'noname' => 'Não colocou um nome de utilizador válido.',
+'loginsuccesstitle' => 'Login bem sucedido',
+'loginsuccess' => "'''Encontra-se agora ligado à {{SITENAME}} como \"$1\"'''.",
+'nosuchuser' => "Não existe nenhum utilizador com o nome \"$1\".
+Verifique o nome que introduziu, ou crie uma nova conta de utilizador.",
+'nosuchusershort' => "Não existe um utilizador com o nome \"$1\". Verifique o nome que introduziu.",
+'nouserspecified' => 'Precisa de especificar um nome de utilizador.',
+'wrongpassword' => 'A palavra-chave que introduziu é inválida. Por favor tente novamente.',
+'wrongpasswordempty' => 'Palavra-chave introduzida está em branco. Por favor tente novamente.',
+'mailmypassword' => 'Enviar uma nova palavra-chave por correio electrónico',
+'passwordremindertitle' => "Lembrador de palavras-chave da {{SITENAME}}",
+'passwordremindertext' => "Alguém (provavelmente você, do endereço de IP $1) solicitou que fosse lhe envido uma nova palavra-chave para {{SITENAME}} ($4).
+A palavra para o utilizador \"$2\" é a partir de agora \"$3\". Pode agora entrar na sua conta e alterar a palavra-chave.
+
+Caso tenha sido outra pessoa a fazer este pedido ou caso você já se tenha lembrado da sua palavra-chave e se não a desejar alterar, pode ignorar esta mensagem e continuar a utilizar a palavra-chave antiga.",
+'noemail' => "Não existe um endereço de correio electrónico associado ao utilizador \"$1\".",
+'passwordsent' => "Uma nova palavra-chave encontra-se a ser enviada para o endereço de correio electrónico associado ao utilizador \"$1\".
+Por favor, volte a efectuar a autenticação ao recebê-la.",
+'eauthentsent' => "Um email de confirmação foi enviado para o endereço de correio electrónico nomeado.
+Antes de qualquer outro email seja enviado para a conta, terá seguir as instruções no email,
+de modo a confirmar que a conta é mesmo sua.",
+#'signupend' => '{{int:loginend}}', # ignore list
+'mailerror' => "Erro a enviar o mail: $1",
+'acct_creation_throttle_hit' => 'Pedimos desculpa, mas já foram criadas $1 contas por si. Não lhe é possível criar mais nenhuma.',
+'emailauthenticated' => 'O seu endereço de correio electrónico foi autenticado em $1.',
+'emailnotauthenticated' => 'O seu endereço de correio electrónico ainda não foi autenticado. Não lhe será enviado nenhum correio sobre nenhuma das seguintes funcionalidades.',
+'noemailprefs' => '<strong>Nenhum endereço de correio electrónico foi especificado</strong>, as seguintes funcionalidades não irão funcionar.',
+'emailconfirmlink' => 'Confirme o seu endereço de correio electrónico',
+'invalidemailaddress' => 'O endereço de correio electrónico não pode ser aceite devido a possuír um formato inválido. Por favor introduza um endereço bem formatado ou esvazie o campo.',
+'accountcreated' => 'Conta criada',
+'accountcreatedtext' => 'A conta de utilizador para $1 foi criada.',
+
+# Edit page toolbar
+#
+'bold_sample' => 'Texto a negrito',
+'bold_tip' => 'Texto a negrito',
+'italic_sample' => 'Texto em itálico',
+'italic_tip' => 'Texto em itálico',
+'link_sample' => 'Título da ligação',
+'link_tip' => 'Ligação interna',
+'extlink_sample' => 'http://www.wikimedia.org ligação externa',
+'extlink_tip' => 'Ligação externa (lembre-se dos prefixos http://, ftp://, ...)',
+'headline_sample' => 'Texto de cabeçalho',
+'headline_tip' => 'Secção de nível 2',
+'math_sample' => 'Inserir fórmula aqui',
+'math_tip' => 'Fórmula matemática (LaTeX)',
+'nowiki_sample' => 'Inserir texto não-formatado aqui',
+'nowiki_tip' => 'Ignorar formato wiki',
+'image_sample' => 'Exemplo.jpg',
+'image_tip' => 'Imagem anexa',
+'media_sample' => 'Exemplo.ogg',
+'media_tip' => 'Ligação a ficheiro interno de multimédia',
+'sig_tip' => 'Sua assinatura com hora e data',
+'hr_tip' => 'Linha horizontal (utilize moderadamente)',
+
+# Edit pages
+#
+'summary' => 'Sumário',
+'subject' => 'Assunto/cabeçalho',
+'minoredit' => 'Marcar como edição menor',
+'watchthis' => 'Observar este artigo',
+'savearticle' => 'Salvar página',
+'preview' => 'Prever',
+'showpreview' => 'Mostrar previsão',
+'showlivepreview' => 'Pré-visualização em tempo real',
+'showdiff' => 'Mostrar alterações',
+'anoneditwarning' => 'Não encontra-se autenticado. O seu endereço de IP será registado no histórico de edições desta página.',
+'missingsummary' => "'''Atenção:''' Não introduziu um sumário de edição. Se carregar em Salvar novamente, a sua edição será salva sem um sumário.",
+'missingcommenttext' => 'Por favor introduzida um comentário abaixo.',
+'blockedtitle' => 'Utilizador está bloqueado',
+'blockedtext' => "O seu nome de utilizador ou endereço de IP foi bloqueado por $1.<br />
+O motivo é: ''$2''
+
+Pode contactar [[{{ns:special}}:emailuser/$4|$4]] ou outro
+[[{{ns:project}}:Administradores|administrador]] para discutir sobre o bloqueio.
+
+Note que não poderá utilizar a funcionalidade \"Contactar utilizador\" se não possuir uma conta na Wikipédia e um endereço de email válido indicado nas suas preferências de utilizador. E lembre-se que só se encontra impossibilitado de editar páginas.<br /><br />
+
+'''O seu endereço de IP é $3.''' Por favor inclua o seu endereço de IP ao contactar um administrador sobre o bloqueio.",
+'blockedoriginalsource' => "A fonte de '''$1''' é mostrada abaixo:",
+'blockededitsource' => "O texto das '''suas edições''' para '''$1''' é mostrado abaixo:",
+'whitelistedittitle' => 'Autentificação necessária para visualizar',
+'whitelistedittext' => 'Precisa de se $1 para poder visualizar páginas.',
+'whitelistreadtitle' => 'Autentificação necessária para visualizar',
+'whitelistreadtext' => 'Precisa de se [[Special:Userlogin|autenticar]] para puder visualizar páginas.',
+'whitelistacctitle' => 'Não lhe é permitido criar uma conta',
+'whitelistacctext' => 'De modo a poder criar contas de utilizador nesta Wiki terá que se [[Special:Userlogin|autenticar]] e possuir as devidas permissões.',
+'confirmedittitle' => 'Confirmação por correio electrónico necessária para editar',
+'confirmedittext' => 'Precisa de confirmar o seu endereço de correio electrónico antes de começar a editar páginas. Por favor introduza e valide o seu endereço de correio electrónico através das suas [[Especial:Preferences|preferências de utilizador]].',
+'loginreqtitle' => 'Autenticação Requesitada',
+'loginreqlink' => 'autenticar-se',
+'loginreqpagetext' => 'Precisa de $1 para visualizar outras páginas.',
+'accmailtitle' => 'Palavra-chave enviada.',
+'accmailtext' => "A palavra-chave para '$1' foi enviada para $2.",
+'newarticle' => '(Novo)',
+'newarticletext' =>
+"Seguiu um link para um artigo que ainda não existe. Para criá-lo, escreva o seu conteúdo na caixa abaixo, mas se chegou aqui por engano clique no botão '''volta''' (ou ''back'') do seu navegador. Por favor, '''NÃO''' crie páginas apenas para fazer [[Project:Artigos pedidos|pedidos]] ou [[Project:Página de testes|testes]].
+
+(Consulte [[{{ns:project}}:Ajuda|a página de ajuda]] para mais informações)",
+'anontalkpagetext' => "----
+''Esta é a página de discussão para um utilizador anónimo que ainda não criou uma conta ou que não a utiliza. De modo a que temos que utilizar o endereço de IP para identificá-lo(a). Um endereço de IP pode ser partilhado por vários utilizadores. Se é um utilizador anónimo e acha relevante que os comentários sejam direccionados a si, por favor [[{{ns:special}}:Userlogin|crie uma conta ou autentique-se]] para evitar futuras confusões com outros utilizadores anónimos.''",
+'noarticletext' => 'Não existe actualmente texto nesta página, pode [[{{ns:special}}:Search/{{PAGENAME}}|pesquisar pelo título desta página noutras páginas]] ou [{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} editar esta página].',
+'clearyourcache' => "'''Nota:''' Após salvar, terá de limpar a cache do seu navegador para ver as alterações.
+'''Mozilla / Firefox / Safari:''' pressione ''Shift'' enquanto clica em ''Recarregar'', ou pressione ''Ctrl-Shift-R'' (''Cmd-Shift-R'' no Apple Mac); '''IE:''' pressione ''Ctrl'' enquanto clica em ''Recarregar'', ou pressione ''Ctrl-F5''; '''Konqueror:''': simplesmente clique no botão ''Recarregar'', ou pressione ''F5''; utilizadores do navegador '''Opera''' podem limpar completamente a sua cache em ''Ferramentas→Preferências''.",
+'usercssjsyoucanpreview' => "<strong>Dica:</strong> Utilize o botão \"Mostrar previsão\" para testar seu novo CSS/JS antes de salvar.",
+'usercsspreview' => "'''Lembre-se que está apenas a prever o seu CSS particular, e que ainda não foi salvo!'''",
+'userjspreview' => "'''Lembre-se que está apenas a testar/prever o seu JavaScript particular, e que ainda não foi salvo!'''",
+'userinvalidcssjstitle' => "'''Aviso:''' Não existe um tema \"$1\". Lembre-se que as páginas .css e .js utilizam um título em minúsculas, exemplo: Utilizador:Silva/monobook.css aposto a Utilizador:Silva/Monobook.css.",
+'updated' => '(Actualizado)',
+'note' => '<strong>Nota:</strong>',
+'previewnote' => '<strong>Isto é apenas uma previsão, as modificações ainda não foram salvas!</strong>',
+'session_fail_preview' => '<strong>Pedimos desculpas, mas não foi possível processar a sua edição devido à perda de dados da sua sessão.
+Por favor tente novamente. Caso continue a não funcionar, tente sair e voltar a entrar na sua conta.</strong>',
+'previewconflict' => 'Esta previsão reflete o texto que está na área de edição acima e como ele aparecerá se você escolher salvar.',
+'session_fail_preview_html' => '<strong>Pedimos desculpas! Não foi possível processar a sua edição devido a uma perda de dados de sessão.</strong>
+
+\'\'Devido a esta wiki possuir HTML raw activo, a previsão está escondida como forma de precaução contra ataques JavaScript.\'\'
+
+<strong>Por favor tente novamente caso esta seja uma tentativa de edição legítima. Caso continue a não funcionar, por favor tente sair e voltar a entrar na sua conta.</strong>',
+'importing' => "Importando $1",
+'editing' => "Editando $1",
+'editinguser' => "Editando $1",
+'editingsection' => "Editando $1 (secção)",
+'editingcomment' => "Editando $1 (comentário)",
+'editconflict' => 'Conflito de edição: $1',
+'explainconflict' => "Alguém mudou a página enquanto você a estava editando.<br />
+A área de texto acima mostra o texto original.
+Suas mudanças são mostradas na área abaixo
+Você terá que mesclar suas modificações no texto existente.
+<b>SOMENTE</b> o texto na área acima será salvo quando você pressionar \"Salvar página\".\n<br />",
+'yourtext' => 'Seu texto',
+'storedversion' => 'Versão guardada',
+'nonunicodebrowser' => "<strong>AVISO: O seu navegador não segue as especificações Unicode. Existe uma maneira para que possa editar com segurança os artigos: os caracteres não-ASCII aparecerão na caixa de edição no formato de códigos hexadecimais.</strong>",
+'editingold' => "<strong>CUIDADO: Encontra-se a editar uma revisão desactualizada deste artigo.
+Se salvá-lo, todas as mudanças feitas a partir desta revisão serão perdidas.</strong>",
+'yourdiff' => 'Diferenças',
+/*'copyrightwarning' => "Por favor note que todas as contribuições para a {{SITENAME}} são imediatamente colocadas sob a <b>GNU Free Documentation License</b> (consulte $1 para detalhes). Se você não quer que seu texto esteja sujeito a estes termos, então não o envie.<br />
+Você também garante que está nos enviando um artigo escrito por você mesmo, ou extraído de uma fonte em domínio público.
+<strong>Não ENVIE </strong>",*/
+'copyrightwarning2' => "Tenha em consideração que todas as contribuições para o projecto {{SITENAME}}
+podem ser editadas, alteradas, ou removidas por outros contribuidores.
+Se não deseja ver as suas contribuições alteradas sem consentimento, não as envie para esta Wiki.<br />
+Adicionalmente, estar-nos-á a dar a sua palavra em como os teus são da sua autoria, ou copiados por fontes de domínio público ou similares (veja mais detalhes em $1).
+<strong>NÃO ENVIE MATERIAL COM DIREITOS DE AUTOR SEM PERMISSÃO!</strong>",
+'longpagewarning' => "<strong>AVISO: Esta página ocupa $1; alguns browsers verificam
+problemas em editar páginas maiores que 32kb.
+Por favor, considere seccionar a página em secções de menor dimensão.</strong>",
+'longpageerror' => "<strong>ERRO: A página que submeteu tem mais de $1 kilobytes
+em tamanho, que é maior que o máximo de $2 kilobytes. A página não pode salva.</strong>",
+'readonlywarning' => '<strong>AVISO: A base de dados foi bloqueada para manutenção, pelo que não poderá salvar a sua edição neste momento. Pode, no entanto, copiar o seu texto num editor externo e guardá-lo para posterior submissão.</strong>',
+'protectedpagewarning' => "<strong>AVISO: Esta página foi protegida e apenas poderá ser editada por utilizadores com privilégios sysop (administradores). Certifique-se que está a respeitar as [[{{ns:project}}:Protected_page_guidelines|linhas de orientação para páginas protegidas]].</strong>",
+'semiprotectedpagewarning' => "'''Nota:''' Esta página foi protegida de modo a que apenas utilizadores registados a possam editar.",
+'templatesused' => 'Predefinições utilizadas nesta página:',
+'edittools' => '<!-- Text here will be shown below edit and upload forms. -->',
+'nocreatetitle' => 'Limitada a criação de páginas',
+'nocreatetext' => 'Este website tem restringida a habilidade de criar novas páginas.
+Pode voltar atrás e editar uma página já existente, ou [[Special:Userlogin|autenticar-se ou criar uma conta]].',
+'cantcreateaccounttitle' => 'Não é possível criar uma conta',
+'cantcreateaccounttext' => 'A criação de contas a partir deste endereço IP (<b>$1</b>) foi bloqueada.
+Isto é provavelmente devido a vandalismo persistente efectuada a partir da sua escola ou ISP.',
+
+# History pages
+#
+'revhistory' => 'Histórico de revisões',
+'viewpagelogs' => 'Ver registos para esta página',
+'nohistory' => 'Não há histórico de edições para esta página.',
+'revnotfound' => 'Revisão não encontrada',
+'revnotfoundtext' => "A antiga revisão desta página que requesitou não pode ser encontrada. Por favor verifique o URL que utilizou para aceder esta página.",
+'loadhist' => 'Carregando histórico',
+'currentrev' => 'Revisão actual',
+'revisionasof' => 'Revisão de $1',
+'revision-info' => 'Revisão de $1; $2',
+'previousrevision' => '← Versão anterior',
+'nextrevision' => 'Versão posterior →',
+'currentrevisionlink' => 'ver versão actual',
+'cur' => 'act',
+'next' => 'prox',
+'last' => 'ult',
+'orig' => 'orig',
+'histlegend' => 'Selecção de diferença: marque as caixas para das versões que deseja comparar e carregue no botão.<br />
+Legenda: (actu) = diferenças da versão actual,
+(ult) = diferença da versão precedente, m = edição menor',
+'deletedrev' => '[eliminada]',
+'histfirst' => 'Mais antigas',
+'histlast' => 'Mais recentes',
+'rev-deleted-comment' => '(comentário removido)',
+'rev-deleted-user' => '(nome de utilizador removido)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Esta revisão desta página foi removida dos arquivos públicos.
+Poderão existir detalhes no [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} registo de eliminação].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+A revisão desta página foi removida dos arquivos públicos.
+Como um administrador desta wiki pode a ver;
+mais detalhes no [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} registo de eliminação].
+</div>',
+'rev-delundel' => 'mostrar/esconder',
+
+'history-feed-title' => 'História de revisão',
+'history-feed-description' => 'História de revisão para esta página nesta wiki',
+'history-feed-item-nocomment' => '$1 a $2', # user at time
+'history-feed-empty' => 'A página requisitada não existe.
+Poderá ter sido eliminada da wiki, ou renomeada.
+Tente [[Especial:Search|pesquisar na wiki]] por novas páginas relevantes.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Eliminar/restaurar revisões',
+'revdelete-nooldid-title' => 'Nenhuma revisão seleccionada',
+'revdelete-nooldid-text' => 'Não especificou nenhuma revisão, ou revisões,
+no qual aplicar esta função.',
+'revdelete-selected' => 'Revisão seleccionada para [[:$1]]:',
+'revdelete-text' => "Revisões eliminadas continuarão a aparecer na história da página,
+mas o seu conteúdo textual estará inacessível ao público.
+
+Outros administradores nesta wiki continuarão a poder aceder ao conteúdo escondido e restaurá-lo novamente através deste mesmo ''interface'', a menos que uma restrição adicional seja colocada pelos operadores do ''site''.",
+'revdelete-legend' => 'Atribuir restrições de revisões:',
+'revdelete-hide-text' => 'Esconder texto de revisão',
+'revdelete-hide-comment' => 'Esconder comentário de edição',
+'revdelete-hide-user' => 'Esconder nome de utilizador/IP do editor',
+'revdelete-hide-restricted' => 'Aplicar estas restrições a administrador tal como a outros',
+'revdelete-log' => 'Comentário de registo:',
+'revdelete-submit' => 'Aplicar a revisões seleccionadas',
+'revdelete-logentry' => 'modificada visibilidade de revisão para [[$1]]',
+
+# Diffs
+#
+'difference' => '(Diferença entre revisões)',
+'loadingrev' => 'carregando a pesquisa por diferenças',
+'lineno' => "Linha $1:",
+'editcurrent' => 'Editar a versão actual desta página',
+'selectnewerversionfordiff' => 'Seleccione uma versão mais recente para comparação',
+'selectolderversionfordiff' => 'Seleccione uma versão mais antiga para comparação',
+'compareselectedversions' => 'Compare as versões seleccionadas',
+
+# Search results
+#
+'searchresults' => 'Resultados de pesquisa',
+'searchresulttext' => "Para mais informações de como pesquisar na {{SITENAME}}, consulte [[{{ns:project}}:Pesquisa|Pesquisando {{SITENAME}}]].",
+'searchsubtitle' => "Para consulta \"[[:$1]]\"",
+'searchsubtitleinvalid' => "Para consulta \"$1\"",
+'badquery' => 'Linha de pesquisa inválida',
+'badquerytext' => 'Não foi possível processar seu pedido de pesquisa.
+Aconteceu provavelmente porque tentou procurar uma palavra com menos de três letras. Isto também pode ter ocorrido porque digitou incorrectamente a expressão, por
+exemplo "peixes <strong>e e</strong> escalas".
+Por favor realize outro pedido de pesquisa.',
+'matchtotals' => "A pesquisa \"$1\" resultou $2 títulos de artigos
+e $3 artigos com o texto procurado.",
+'noexactmatch' => 'Não existe uma página com o título \"$1\". Pode criar [[:$1|esta página]].',
+'titlematches' => 'Resultados nos títulos dos artigos',
+'notitlematches' => 'Nenhum título de página coincide',
+'textmatches' => 'Resultados dos textos dos artigos',
+'notextmatches' => 'Nenhum texto nas páginas coincide',
+'prevn' => "anteriores $1",
+'nextn' => "próximos $1",
+'viewprevnext' => "Ver ($1) ($2) ($3).",
+'showingresults' => "Mostrando <b>$1</b> resultados, começando no <b>$2</b>º.",
+'showingresultsnum' => "Mostrando <b>$3</b> resultados começando com #<b>$2</b>.",
+'nonefound' => "<strong>Nota</strong>: pesquisas mal sucedidas são geralmente causadas devido ao uso de palavras muito comuns como \"tem\" e \"de\",
+que não são indexadas, ou pela especificação de mais de um termo (somente as páginas contendo todos os termos aparecerão nos resultados).",
+'powersearch' => 'Pesquisa',
+'powersearchtext' => "
+Pesquisar nos domínios:<br />
+$1<br />
+$2 Lista redirecciona &nbsp; Pesquisar por $3 $9",
+"searchdisabled" => 'O motor de pesquisa na {{SITENAME}} foi desactivado por motivos de desempenho. Enquanto isso pode fazer a sua pesquisa através do Google ou do Yahoo!.<br />
+Note que os índices do conteúdo da {{SITENAME}} destes sites podem estar desactualizados.',
+
+'blanknamespace' => '(Principal)',
+
+# Preferences page
+#
+'preferences' => 'Preferências',
+'mypreferences' => 'Minhas preferências',
+'prefsnologin' => 'Não autenticado',
+'prefsnologintext' => "Precisa estar [[Special:Userlogin|autenticado]] para definir suas preferências.",
+'prefsreset' => 'Preferências restauradas da base de dados.',
+'qbsettings' => 'Barra Rápida',
+'changepassword' => 'Alterar palavra-chave',
+'skin' => 'Tema',
+'math' => 'Matemática',
+'dateformat' => 'Formato da data',
+'datedefault' => 'Sem preferência',
+'datetime' => 'Data e hora',
+'math_failure' => 'Falhou ao verificar gramática',
+'math_unknown_error' => 'Erro desconhecido',
+'math_unknown_function' => 'Função desconhecida',
+'math_lexing_error' => 'Erro léxico',
+'math_syntax_error' => 'Erro de sintaxe',
+'math_image_error' => 'Erro na conversão para PNG; Verifique a instalação do latex, dvips, gs e convert',
+'math_bad_tmpdir' => 'Ocorreram problemas na criação ou escrita na directoria temporária math',
+'math_bad_output' => 'Ocorreram problemas na criação ou escrita na directoria de resultados math',
+'math_notexvc' => 'Executável texvc não encontrado; Consulte math/README para instruções da configuração.',
+'prefs-personal' => 'Perfil de utilizador',
+'prefs-rc' => 'Mudanças recentes',
+'prefs-watchlist' => 'Lista de artigos vigiados',
+'prefs-watchlist-days' => 'Número de dias a mostrar na lista de artigos vigiados:',
+'prefs-watchlist-edits' => 'Numéro de edições a mostrar na lista de artigos vigados expandida:',
+'prefs-misc' => 'Diversos',
+'saveprefs' => 'Salvar',
+'resetprefs' => 'Restaurar',
+'oldpassword' => 'Palavra-chave antiga',
+'newpassword' => 'Nova palavra-chave',
+'retypenew' => 'Reintroduza a nova palavra-chave',
+'textboxsize' => 'Opções de edição',
+'rows' => 'Linhas:',
+'columns' => 'Colunas:',
+'searchresultshead' => 'Pesquisa',
+'resultsperpage' => 'Resultados por página:',
+'contextlines' => 'Linhas por resultado:',
+'contextchars' => 'Contexto por linha:',
+'stubthreshold' => 'Variação para a visualização de esboços:',
+'recentchangescount' => 'Número de artigos nas mudanças recentes:',
+'savedprefs' => 'As suas preferências foram salvas.',
+'timezonelegend' => 'Fuso horário',
+'timezonetext' => 'Número de horas que o seu horário local difere do horário do servidor (UTC).',
+'localtime' => 'Hora local',
+'timezoneoffset' => 'Diferença horária¹',
+'servertime' => 'Horário do servidor',
+'guesstimezone' => 'Preencher a partir do navegador (browser)',
+'allowemail' => 'Permitir email de outros utilizadores',
+'defaultns' => 'Pesquisar nestes domínios por padrão:',
+'default' => 'padrão',
+'files' => 'Ficheiros',
+
+# User rights
+
+'userrights-lookup-user' => 'Gerir grupos de utilizadores',
+'userrights-user-editname' => 'Intruduza um nome de utilizador:',
+'editusergroup' => 'Editar Grupos de Utilizadores',
+
+'userrights-editusergroup' => 'Editar grupos do utilizador',
+'saveusergroups' => 'Salvar Grupos do Utilizador',
+'userrights-groupsmember' => 'Membro de:',
+'userrights-groupsavailable' => 'Grupos disponíveis:',
+'userrights-groupshelp' => 'Seleccione os grupos no qual deseja que o utilizador seja removido ou adicionado.
+Grupos não seleccionados, não serão alterados. Pode seleccionar ou remover a selecção a um grupo com CTRL + Click esquerdo',
+
+# Groups
+'group' => 'Grupo:',
+'group-bot' => 'Robôs',
+'group-sysop' => 'Administradores',
+'group-bureaucrat' => 'Burocratas',
+'group-all' => '(todos)',
+
+'group-bot-member' => 'Robô',
+'group-sysop-member' => 'Administrador',
+'group-bureaucrat-member' => 'Burocrata',
+
+'grouppage-bot' => '{{ns:project}}:Robôs',
+'grouppage-sysop' => '{{ns:project}}:Administradores',
+'grouppage-bureaucrat' => '{{ns:project}}:Burocratas',
+
+# Recent changes
+#
+'changes' => 'mudanças',
+'recentchanges' => 'Mudanças recentes',
+'recentchangestext' => 'Veja as mais novas mudanças na {{SITENAME}} nesta página.',
+'rcnote' => "Abaixo estão as últimas <strong>$1</strong> alterações nos últimos <strong>$2</strong> dias, desde $3.",
+'rcnotefrom' => "Abaixo estão as mudanças desde <b>$2</b> (mostradas até <b>$1</b>).",
+'rclistfrom' => "Mostrar as novas alterações a partir de $1",
+'rcshowhideminor' => '$1 edições menores',
+'rcshowhidebots' => '$1 robôs',
+'rcshowhideliu' => '$1 utilizadores registados',
+'rcshowhideanons' => '$1 utilizadores anónimos',
+'rcshowhidepatr' => '$1 edições verificadas',
+'rcshowhidemine' => '$1 as minhas edições',
+'rclinks' => "Mostrar as últimas $1 mudanças nos últimos $2 dias<br />$3",
+'diff' => 'dif',
+'hist' => 'hist',
+'hide' => 'Esconder',
+'show' => 'Mostrar',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'boteditletter' => 'r',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 utilizador/es a vigiar]',
+'rc_categories' => 'Limite para categorias (separar com "|")',
+'rc_categories_any' => 'Qualquer',
+
+# Upload
+#
+'upload' => 'Carregar ficheiro',
+'uploadbtn' => 'Carregar ficheiro',
+'reupload' => 'Recarregar',
+'reuploaddesc' => 'Voltar ao formulário de carregamento.',
+'uploadnologin' => 'Não autenticado',
+'uploadnologintext' => "Deve estar <a href=\"{{localurle:Special:Userlogin}}\">autenticado</a>
+para carregar ficheiros.",
+'upload_directory_read_only' => 'A directoria de envio ($1) não tem permissões de escrita pelo servidor Web.',
+'uploaderror' => 'Erro ao carregar',
+'uploadtext' =>
+"
+Utilize o formulário abaixo para carregar novos ficheiros,
+para ver ou pesquisar imagens anteriormente carregadas
+consulte a [[Special:Imagelist|lista de ficheiros carregados]],
+carregamentos e eliminações são também registados no [[Special:Log|registo do projecto]].
+
+Para incluír a imagem numa página, utilize o link na forma de
+'''[[{{ns:6}}:ficheiro.jpg]]''',
+'''[[{{ns:6}}:ficheiro.png|texto]]''' ou
+'''[[{{ns:-2}}:ficheiro.ogg]]''' para uma ligação directa ao ficheiro.",
+'uploadlog' => 'registo de carregamento',
+'uploadlogpage' => 'Registo de carregamento',
+'uploadlogpagetext' => 'Segue-se uma lista dos carregamentos mais recentes.',
+'filename' => 'Nome do ficheiro',
+'filedesc' => 'Descrição do ficheiro',
+'fileuploadsummary' => 'Sumário:',
+'filestatus' => 'Estatuto de copyright',
+'filesource' => 'Fonte',
+'copyrightpage' => "{{ns:project}}:Direitos_de_autor",
+'copyrightpagename' => "Direitos autorais da {{SITENAME}}",
+'uploadedfiles' => 'Ficheiros carregados',
+'ignorewarning' => 'Ignorar aviso e salvar de qualquer forma.',
+'ignorewarnings' => 'Ignorar todos os avisos',
+'minlength' => 'O nome de um ficheiro tem de ter no mínimo três letras.',
+'illegalfilename' => 'O ficheiro "$1" possui caracteres que não são permitidos no título de uma página. Por favor altere o nome do ficheiro e tente carregar novamente.',
+'badfilename' => 'Nome do ficheiro foi alterado para "$1".',
+'badfiletype' => "\".$1\" é um formato de ficheiro não recomendado.",
+'largefile' => 'É recomendado que imagens não excedam $1 bytes em tamanho, o tamanho deste ficheiro é $2 bytes',
+'largefileserver' => 'O tamanho deste ficheiro é superior ao qual o servidor encontra-se configurado para permitir.',
+'emptyfile' => 'O ficheiro que está a tentar carregar parece encontrar-se vazio. Isto poderá ser devido a um erro na escrita do nome do ficheiro. Por favor verifique se realmente deseja carregar este ficheiro.',
+'fileexists' => 'Já existe um ficheiro com este nome, por favor verifique $1 caso não tenha a certeza se deseja alterar o ficheiro actual.',
+'fileexists-forbidden' => 'Já existe um ficheiro com este nome; por favor volte atrás e carregue este ficheiro sob um novo nome. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Já existe um ficheiro com este nome no repositório de ficheiros partilhados; por favor volte atrás e carregue este ficheiro sob um novo nome. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Envio efectuado com sucesso',
+'fileuploaded' => "Ficheiro $1 enviado com sucesso.
+Por favor siga este endereço: $2 para a página de descrição e preencha a informação acerca deste ficheiro, tais como a sua origem, quando foi criado e por quem, e quaisquer outros dados que tenha conhecimento sobre o mesmo. Caso este ficheiro seja uma imagem, pode inseri-lo desta forma: <tt>[[Imagem:$1|thumb|Descrição]]</tt>",
+'uploadwarning' => 'Aviso de envio',
+'savefile' => 'Salvar ficheiro',
+'uploadedimage' => "carregado \"[[$1]]\"",
+'uploaddisabled' => 'Carregamentos desactivados',
+'uploaddisabledtext' => 'O carregamento de ficheiros encontra-se desactivado nesta wiki.',
+'uploadscripted' => 'Este ficheiro contém HTML ou código que pode ser erradamente interpretado por um navegador web.',
+'uploadcorrupt' => 'O ficheiro encontra-se corrompido ou tem uma extensão não permitida. Corrija o ficheiro e tente novamento.',
+'uploadvirus' => 'O ficheiro contém vírus! Detalhes: $1',
+'sourcefilename' => 'Nome do ficheiro de origem',
+'destfilename' => 'Nome do ficheiro de destino',
+'watchthisupload' => 'Vigiar esta página',
+'filewasdeleted' => 'Um ficheiro com este nome foi anteriormente carregado e subsequentemente eliminado. Deveria verificar o $1 antes de proceder ao carregamento novamente.',
+
+'license' => 'Licença',
+'nolicense' => 'Nenhuma seleccionada',
+'upload_source_url' => ' (válido, URL publicamente acessível)',
+'upload_source_file' => ' (um ficheiro no seu computador)',
+
+# Image list
+#
+'imagelist' => 'Lista de ficheiros',
+'imagelisttext' => 'Segue-se uma lista de <strong>$1</strong> ficheiros organizados <strong>$2</strong>.',
+'imagelistforuser' => "Esta lista apenas mostra imagens carregadas por $1.",
+'getimagelist' => 'carregando lista de ficheiros',
+'ilsubmit' => 'Procurar',
+'showlast' => 'Mostrar últimos $1 ficheiros organizados $2.',
+'byname' => 'por nome',
+'bydate' => 'por data',
+'bysize' => 'por tamanho',
+'imgdelete' => 'eli',
+'imgdesc' => 'desc',
+'imgfile' => 'ficheiro',
+'imglegend' => 'Legenda: (desc) = mostrar/editar descrição de imagem.',
+'imghistory' => 'História',
+'revertimg' => 'rev',
+'deleteimg' => 'eli',
+'deleteimgcompletely' => 'Eliminar todas revisões deste ficheiro',
+'imghistlegend' => 'Legenda: (actu) = imagem actual, (eli) = eliminar versão antiga, (rev) = reverter para versão antiga.
+<br /><i>Clique na data para ver as imagens carregadas nessa data</i>.',
+'imagelinks' => 'Ligações',
+'linkstoimage' => 'As seguintes páginas apontam para este ficheiro:',
+'nolinkstoimage' => 'Nenhuma página aponta para este ficheiro.',
+'sharedupload' => 'Este ficheiro encontra-se partilhado e pode ser utilizado por outros projectos.',
+'shareduploadwiki' => 'Por favor consulte a $1 para mais informação.',
+'shareduploadwiki-linktext' => 'página de descrição',
+'noimage' => 'Nenhum ficheiro com este nome existe, se desejar pode $1',
+'noimage-linktext' => 'carrega-lo',
+'uploadnewversion-linktext' => 'Carregar uma nova versão deste ficheiro',
+'imagelist_date' => 'Data',
+'imagelist_name' => 'Nome',
+'imagelist_user' => 'Utilizador',
+'imagelist_size' => 'Tamanho (bytes)',
+'imagelist_description' => 'Descrição',
+'imagelist_search_for' => 'Pesquisar por nome de imagem:',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Páginas não vigiadas',
+
+# List redirects
+'listredirects' => 'Listar redireccionamentos',
+
+# Unused templates
+'unusedtemplates' => 'Predefinições não utilizadas',
+'unusedtemplatestext' => 'Esta página lista todas as páginas no domínio predefinição que não estão incluídas numa outra página. Lembre-se de verificar por outras ligações nas predefinições antes de as apagar.',
+'unusedtemplateswlh' => 'outras ligações',
+
+# Random redirect
+'randomredirect' => 'Redireccionamento aleatório',
+
+# Statistics
+#
+'statistics' => 'Estatísticas',
+'sitestats' => 'Estatísticas do site',
+'userstats' => 'Estatística dos utilizadores',
+'sitestatstext' => "Há actualmente um total de '''$1''' páginas na base de dados.
+Isto inclui páginas de \"discussão\", páginas sobre o projecto, páginas de rascunho, redireccionamentos, e outras que provavelmente não são qualificadas como artigos.
+Excluindo estas, há '''$2''' páginas que provavelmente são artigos legítimos.
+
+'''$8''' ficheiros foram carregados.
+
+Há um total de '''$3''' páginas vistas, e '''$4''' edições em páginas
+desde a instalação do software.
+O que nos leva a aproximadamente '''$5''' edições por página, e '''$6''' vistas por edição.
+
+O tamanho da [http://meta.wikimedia.org/wiki/Help:Job_queue fila de tarefas] é de actualmente '''$7'''.",
+'userstatstext' => "Há actualmente '''$1''' utilizadores registados.
+Destes, '''$2''' (ou '''$4%''') são $5.",
+'statistics-mostpopular' => 'Páginas mais vistas',
+
+# Maintenance Page
+#
+'disambiguations' => 'Página de desambiguações',
+'disambiguationspage' => 'Template:disambig',
+'disambiguationstext' => "As seguintes páginas ligam com uma <i>página de desambiguação</i>. Estas páginas deviam ligar com o tópico apropriado.<br />Qualquer página ligada com $1 é considerada página de desambiguação.<br />As ligações de outros domínios não são listadas aqui.",
+'doubleredirects' => 'Redireccionamentos duplos',
+'doubleredirectstext' => "Cada linha contém ligações para o primeiro e segundo redireccionamento, bem como a primeira linha de conteúdo do segundo redireccionamento, geralmente contendo a página destino \"real\", que devia ser o destino do primeiro redireccionamento.",
+'brokenredirects' => 'Redireccionamentos quebrados',
+'brokenredirectstext' => 'Os seguintes redireccionamentos ligam para páginas inexistentes:',
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
+'ncategories' => '$1 {{PLURAL:$1|categoria|categorias}}',
+'nlinks' => '$1 {{PLURAL:$1|link|links}}',
+'nmembers' => '$1 {{PLURAL:$1|membro|membros}}',
+'nrevisions' => '$1 {{PLURAL:$1|revisão|revisões}}',
+'nviews' => '$1 {{PLURAL:$1|visita|visitas}}',
+
+'lonelypages' => 'Páginas órfãs',
+'lonelypagestext' => 'As seguintes páginas não têm hiperligações a apontar para elas a partir de outras páginas nesta wiki.',
+'uncategorizedpages' => 'Páginas não categorizadas',
+'uncategorizedcategories' => 'Categorias não categorizadas',
+'uncategorizedimages' => 'Imagens não categorizadas',
+'unusedcategories' => 'Categorias não utilizadas',
+'unusedimages' => 'Ficheiros não utilizados',
+'popularpages' => 'Páginas populares',
+'wantedcategories' => 'Categorias pedidas',
+'wantedpages' => 'Páginas pedidas',
+'mostlinked' => 'Páginas com mais afluentes',
+'mostlinkedcategories' => 'Categorias com mais afluentes',
+'mostcategories' => 'Artigos com mais categorias',
+'mostimages' => 'Imagens com mais afluentes',
+'mostrevisions' => 'Artigos com mais revisões',
+'allpages' => 'Todas as páginas',
+'prefixindex' => 'Índice de prefixo',
+'randompage' => 'Página aleatória',
+'shortpages' => 'Páginas curtas',
+'longpages' => 'Páginas longas',
+'deadendpages' => 'Páginas sem saída',
+'deadendpagestext' => 'As seguintes páginas não contêm hiperligações para outras páginas nesta wiki.',
+'listusers' => 'Lista de utilizadores',
+'specialpages' => 'Páginas especiais',
+'spheading' => 'Páginas especiais para todos os utilizadores',
+'restrictedpheading' => 'Páginas especiais restritas',
+'recentchangeslinked' => 'Alterações relacionadas',
+'rclsub' => "(para páginas linkadas de \"$1\")",
+'newpages' => 'Páginas novas',
+'newpages-username' => 'Nome de utilizador:',
+'ancientpages' => 'Páginas mais antigas',
+'intl' => 'Ligações interlínguas',
+'move' => 'Mover',
+'movethispage' => 'Mover esta página',
+'unusedimagestext' => '<p>Por favor note que outros websites como as Wikipédias internacionais podem apontar para uma imagem através de um URL directamente, e por isso pode estar aparecer aqui mesmo estando em uso.</p>',
+'unusedcategoriestext' => 'As seguintes categorias existem embora nenhum artigo ou categoria faça uso delas.',
+'booksources' => 'Fontes de livros',
+'categoriespagetext' => 'As seguintes categorias existem na wiki.',
+'data' => 'Dados',
+'userrights' => 'Gestão de privilégios do utilizador',
+'groups' => 'Grupos de utilizadores',
+
+'booksourcetext' => "Abaixo encontra-se uma lista de ligações para outros websites que vendem livros novos ou usados, e poderão ter mais informações sobre os livros que procura.",
+'isbn' => 'ISBN',
+'alphaindexline' => "$1 até $2",
+'version' => 'Versão',
+'log' => 'Registos',
+'alllogstext' => 'Exposição combinada de carregamento de ficheiros, eliminação, protecção, bloqueio, e de direitos.
+Pode diminuir a lista escolhendo um tipo de registo, um nome de utilizar, ou uma página afectada.',
+'logempty' => 'Nenhum item idêntico no registo.',
+
+# Special:Allpages
+'nextpage' => 'Próxima página ($1)',
+'allpagesfrom' => 'Mostrar páginas começando em:',
+'allarticles' => 'Todos artigos',
+'allinnamespace' => 'Todas páginas (domínio $1)',
+'allnotinnamespace' => 'Todas páginas (não no domínio $1)',
+'allpagesprev' => 'Anterior',
+'allpagesnext' => 'Próximo',
+'allpagessubmit' => 'Ir',
+'allpagesprefix' => 'Exibir páginas com o prefixo:',
+'allpagesbadtitle' => 'O título de página dado encontrava-se inválido ou tinha um prefixo interlíngua ou inter-wiki. Poderá conter um ou mais caracteres que não podem ser utilizados em títulos.',
+
+# Special:Listusers
+'listusersfrom' => 'Mostrar utilizadores começando em:',
+
+# E this user
+#
+'mailnologin' => 'Nenhum endereço de envio',
+'mailnologintext' => "Necessita de estar [[Special:Userlogin|autenticado]]
+e de possuir um endereço de e-mail válido nas suas [[Special:Preferences|preferências]]
+para enviar um e-mail a outros utilizadores.",
+'emailuser' => 'Contactar este utilizador',
+'emailpage' => 'Contactar utilizador',
+'emailpagetext' => 'Se o utilizador introduziu um endereço válido de e-mail
+nas suas preferências, poderá usar o formulário abaixo para lhe enviar uma mensagem.
+O endereço que introduziu nas suas preferências irá aparecer no campo "From" do e-mail
+para que o destinatário lhe possa responder.',
+'usermailererror' => 'Objecto de correio retornou um erro:',
+'defemailsubject' => "E-mail: {{SITENAME}}",
+'noemailtitle' => 'Sem endereço de e-mail',
+'noemailtext' => 'Este utilizador não especificou um endereço de e-mail válido, ou optou por não receber e-mail de outros utilizadores.',
+'emailfrom' => 'De',
+'emailto' => 'Para',
+'emailsubject' => 'Assunto',
+'emailmessage' => 'Mensagem',
+'emailsend' => 'Enviar',
+'emailsent' => 'E-mail enviado',
+'emailsenttext' => 'A sua mensagem foi enviada.',
+
+# Watchlist
+#
+'watchlist' => 'Artigos vigiados',
+'watchlistfor' => "(para '''$1''')",
+'nowatchlist' => 'Não existem itens na sua lista de artigos vigiados.',
+'watchlistanontext' => 'Por favor $1 para ver ou editar os itens na sua lista de artigos vigiados.',
+'watchlistcount' => "'''Tem {{PLURAL:$1|$1 item|$1 items}} na sua lista de artigos vigiados, incluindo páginas de discussão.'''",
+'clearwatchlist' => 'Limpar lista de artigos vigiados',
+'watchlistcleartext' => 'Tem a certeza que deseja removê-los?',
+'watchlistclearbutton' => 'Limpar',
+'watchlistcleardone' => 'A sua lista de artigos vigiados foi limpa. {{PLURAL:$1|$1 item foi removido|$1 items foram removidos}}.',
+'watchnologin' => 'Não está autenticado',
+'watchnologintext' => 'Deve estar [[Special:Userlogin|autenticado]] para modificar a sua lista de artigos vigiados.',
+'addedwatch' => 'Adicionado à lista',
+'addedwatchtext' => "A página \"$1\" foi adicionada à sua [[Special:Watchlist|lista de artigos vigiados]].
+Modificações futuras neste artigo e páginas de discussão associadas serão listadas lá e a página aparecerá a '''negrito''' na [[Especial:Recentchanges|lista de mudanças recentes]], para que possa encontrá-la com maior facilidade.
+
+Se desejar remover o artigo da sua lista de artigos vigiados, clique em \"Desinteressar-se\" na barra lateral ou de topo.",
+'removedwatch' => 'Removida da lista de artigos vigiados',
+'removedwatchtext' => "A página \"$1\" não é mais de seu interesse e portanto foi removida de sua lista de artigos vigiados",
+'watch' => 'Vigiar',
+'watchthispage' => 'Vigiar esta página',
+'unwatch' => 'Desinteressar-se',
+'unwatchthispage' => 'Parar de vigiar esta página',
+'notanarticle' => 'Não é um artigo',
+'watchnochange' => 'Nenhum dos itens vigiados foram editados no período exibido.',
+'watchdetails' => '* {{PLURAL:$1|$1 página vigiada|$1 páginas vigiadas}}, excluindo páginas de discussão
+* [[Especial:Watchlist/edit|Mostrar e editar a lista completa]]
+* [[Especial:Watchlist/clear|Remover todas as páginas]]',
+'wlheader-enotif' => "* Notificação por email encontra-se activada.",
+'wlheader-showupdated' => "* Páginas modificadas desde a sua última visita são mostradas a '''negrito'''",
+'watchmethod-recent'=> 'verificando edições recentes para os artigos vigiados',
+'watchmethod-list' => 'verificando páginas vigiadas para edições recentes',
+'removechecked' => 'Remover itens seleccionados',
+'watchlistcontains' => "Sua lista contém $1 páginas.",
+'watcheditlist' => 'Aqui está uma lista alfabética de sua lista de artigos vigiados. Marque as caixas dos artigos que você deseja remover da lista e clique no botão \'Remover itens seleccionados\' na parte de baixo do ecrã (removendo uma página de discussão remove também a página associada e vice versa).',
+'removingchecked' => 'Removendo os itens solicitados de sua lista de artigos vigiados...',
+'couldntremove' => "Não foi possível remover o item '$1'...",
+'iteminvalidname' => "Problema com item '$1', nome inválido...",
+'wlnote' => 'Abaixo as últimas $1 mudanças nas últimas <b>$2</b> horas.',
+'wlshowlast' => 'Ver últimas $1 horas $2 dias $3',
+'wlsaved' => 'Esta é uma versão salva de sua lista de artigos vigiados.',
+'wlhideshowown' => '$1 minhas edições',
+'wlhideshowbots' => '$1 edições por robôs',
+'wldone' => 'Concluído.',
+
+'enotif_mailer' => '{{SITENAME}} Correio de Notificação',
+'enotif_reset' => 'Marcar todas páginas como visitadas',
+'enotif_newpagetext'=> 'Isto é uma nova página.',
+'changed' => 'alterada',
+'created' => 'criada',
+'enotif_subject' => '{{SITENAME}}: A página $PAGETITLE foi $CHANGEDORCREATED por $PAGEEDITOR',
+'enotif_lastvisited' => 'Consulte $1 para todas as alterações efectuadas desde a sua última visita.',
+'enotif_body' => 'Caro $WATCHINGUSERNAME,
+
+A página $PAGETITLE na {{SITENAME}} foi $CHANGEDORCREATED a $PAGEEDITDATE por $PAGEEDITOR, consulte $PAGETITLE_URL para a versão actual.
+
+$NEWPAGE
+
+Sumário de editor: $PAGESUMMARY $PAGEMINOREDIT
+
+Contacte o editor:
+email: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Não haverá mais notificações no caso de futuras alterações a não ser que visite esta página. Poderá também restaurar as bandeiras de notificação para todas as suas páginas vigiadas na sua lista de artigos vigiados.
+
+ O seu sistema de notificação amigável da {{SITENAME}}
+
+--
+Para alterar as suas preferências da lista de artigos vigiados, visite
+{{fullurl:Special:Watchlist/edit}}
+
+Contacto e assistência
+{{fullurl:Ajuda:Conteúdos}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Eliminar página',
+'confirm' => 'Confirmar',
+'excontent' => "conteúdo era: '$1'",
+'excontentauthor' => "conteúdo era: '$1' (e o único editor era '[[Especial:Contributions/$2|$2]]')",
+'exbeforeblank' => "conteúdo antes de esvaziar era: '$1'",
+'exblank' => 'página esvaziada',
+'confirmdelete' => 'Confirmar eliminação',
+'deletesub' => "(Eliminando \"$1\")",
+'historywarning' => 'Aviso: A página que está prestes a eliminar possui um histórico:',
+'confirmdeletetext' => "Encontra-se prestes a eliminar permanentemente uma página ou uma imagem e todo o seu histórico da base de dados.
+Por favor confirme que entende fazer isto, e que compreende as consequências, e que encontra-se a fazer isto de acordo com a [[{{ns:project}}:Política de eliminação|Política de eliminação]] do projecto.",
+'actioncomplete' => 'Acção completada',
+'deletedtext' => "\"$1\" foi eliminada.
+Consulte $2 para um registo de eliminações recentes.",
+'deletedarticle' => "eliminada \"[[$1]]\"",
+'dellogpage' => 'Registo de eliminação',
+'dellogpagetext' => 'Abaixo uma lista das eliminações mais recentes.',
+'deletionlog' => 'registo de eliminação',
+'reverted' => 'Revertido para versão mais nova',
+'deletecomment' => 'Motivo de eliminação',
+'imagereverted' => 'Reversão para versão mais nova foi bem sucedida.',
+'rollback' => 'Voltar edições',
+'rollback_short' => 'Voltar',
+'rollbacklink' => 'voltar',
+'rollbackfailed' => 'Reversão falhou',
+'cantrollback' => 'Não foi possível reverter a edição; o último contribuidor é o único autor deste artigo',
+'alreadyrolled' => "Não foi possível reverter as edições de [[:$1]]
+por [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|Discussão]]); alguém editou ou já reverteu o artigo.
+
+A última edição foi de [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|Discussão]]).",
+
+# only shown if there is an edit comment
+'editcomment' => "O sumário de edição era: \"<i>$1</i>\".",
+'revertpage' => "Revertidas edições por $2, para a última versão por $1",
+'sessionfailure' => 'Foram detectados problemas com a sua sessão;
+Esta acção foi cancelada como medida de protecção contra a intercepção de sessões.
+Experimente usar o botão "Voltar atrás" e refrescar a página de onde veio, e repita o processo.',
+'protectlogpage' => 'Registo de protecção',
+'protectlogtext' => "Abaixo encontra-se o registo de protecção e desprotecção de páginas.
+Veja [[{{ns:project}}:Página protegida]] para mais informações.",
+'protectedarticle' => 'protegeu "[[$1]]"',
+'unprotectedarticle' => 'desprotegeu "[[$1]]"',
+'protectsub' => '(Protegendo "$1")',
+'confirmprotecttext' => 'Deseja realmente proteger esta página?',
+'confirmprotect' => 'Confirmar protecção',
+'protectmoveonly' => 'Impedir apenas que a página seja movida.',
+'protectcomment' => 'Motivo de protecção',
+'unprotectsub' =>"(Desprotegendo \"$1\")",
+'confirmunprotecttext' => 'Deseja realmente desproteger esta página?',
+'confirmunprotect' => 'Confirmar desprotecção',
+'unprotectcomment' => 'Motivo de desprotecção',
+'protect-unchain' => 'Desbloquear permissões de moção',
+'protect-text' => 'Pode ver e alterar aqui, o nível de protecção para a página <strong>$1</strong>.
+Por favor tenha a certeza que segue as [[{{ns:project}}:Página protegida|normas do projecto]].',
+'protect-viewtext' => 'A sua conta de utilizador não tem permissões para alterar
+os níveis de protecção desta página. Estas são as configurações actuais para a página <strong>$1</strong>:',
+'protect-default' => '(padrão)',
+'protect-level-autoconfirmed' => 'Bloquear utilizadores não-registados',
+'protect-level-sysop' => 'Administradores apenas',
+
+# restrictions (nouns)
+'restriction-edit' => 'Editar',
+'restriction-move' => 'Mover',
+
+# Undelete
+'undelete' => 'Ver páginas eliminadas',
+'undeletepage' => 'Ver e restaurar páginas eliminadas',
+'viewdeletedpage' => 'Ver páginas eliminadas',
+'undeletepagetext' => 'As páginas seguintes foram eliminadas mas ainda permanecem na base de dados e podem ser restauradas. O arquivo pode ser limpo periodicamente.',
+'undeleteextrahelp' => "Para restaurar a página inteira, deixe todas as caixas de selecção desseleccionadas e
+clique em '''''Restaurar'''''. Para efectuar uma restauração selectiva, seleccione as caixas correspondentes às
+revisões a serem restauradas, e clique em '''''Restaurar'''''. Clicar em '''''Limpar''''' irá limpar o
+campo de comentário e todas as caixas de selecção.",
+'undeletearticle' => 'Restaurar artigo eliminado',
+'undeleterevisions' => "$1 revisões arquivadas",
+'undeletehistory' => 'Se restaurar uma página, todas as revisões serão restauradas para o histórico.
+Se uma nova página foi criada com o mesmo nome desde a eliminação, as revisões restauradas aparecerão primeiro no histórico e a página actual não será automaticamente trocada.',
+'undeletehistorynoadmin' => 'Este artigo foi eliminado. O motivo para a eliminação é apresentado no súmario abaixo, junto dos detalhes do utilizador que editou esta página antes de eliminar. O texto actual destas revisões eliminadas encontra-se agora apenas disponível para administradores.',
+'undeleterevision' => "Revisões eliminadas de $1",
+'undeletebtn' => 'Restaurar',
+'undeletereset' => 'Limpar',
+'undeletecomment' => 'Comentário:',
+'undeletedarticle' => "restaurado \"[[$1]]\"",
+'undeletedrevisions' => "$1 revisões restauradas",
+'undeletedrevisions-files' => "$1 revisões e $2 ficheiro(s) restauradas",
+'undeletedfiles' => "{{PLURAL:$1|ficheiro restaurado|$1 ficheiros restaurados}}",
+'cannotundelete' => 'Restauração falhada; alguém poderá já ter restaurado a página primeiro.',
+'undeletedpage' => "<big>'''$1 foi restaurada'''</big>
+
+Consulte o [[Special:Log/delete|registo de eliminações]] para um registo das eliminações e restaurações mais recentes.",
+
+# Namespace form on various pages
+'namespace' => 'Domínio:',
+'invert' => 'Inverter selecção',
+
+# Contributions
+#
+'contributions' => 'Contribuições do utilizador',
+'mycontris' => 'Minhas contribuições',
+'contribsub' => "Para $1",
+'nocontribs' => 'Não foram encontradas mudanças com este critério.',
+'ucnote' => "Segue as últimas <b>$1</b> mudanças nos últimos <b>$2</b> dias deste utilizador.",
+'uclinks' => "Ver as últimas $1 mudanças; ver os últimos $2 dias.",
+'uctop' => ' (revisão actual)' ,
+'newbies' => 'novatos',
+
+'sp-newimages-showfrom' => 'Mostrar novas imagens começando de $1',
+
+'sp-contributions-newest' => 'Mais recente',
+'sp-contributions-oldest' => 'Mais antigo',
+'sp-contributions-newer' => 'Novo $1',
+'sp-contributions-older' => 'Antigo $1',
+'sp-contributions-newbies-sub' => 'Para novatos',
+
+# What links here
+#
+'whatlinkshere' => 'Artigos afluentes',
+'notargettitle' => 'Sem alvo',
+'notargettext' => 'Não especificou uma página alvo ou utilizador para executar esta função.',
+'linklistsub' => '(Lista de ligações)',
+'linkshere' => "Os seguintes artigos contêm ligações para '''[[:$1]]''':",
+'nolinkshere' => "Não existem ligações para '''[[:$1]]'''.",
+'isredirect' => 'página de redireccionamento',
+'istemplate' => 'inclusão',
+
+# Block/unblock IP
+#
+'blockip' => 'Bloquear utilizador',
+'blockiptext' => "Utilize o formulário abaixo para bloquear o acesso à escrita de um endereço específico de IP ou nome de utilizador.
+Isto só deve ser feito para prevenir vandalismo, e de acordo com a [[{{ns:project}}:Política|política da {{SITENAME}}]]. Preencha com um motivo específico (por exemplo, citando páginas que sofreram vandalismo).",
+'ipaddress' => 'Endereço de IP',
+'ipadressorusername' => 'Endereço de IP ou nome de utilizador',
+'ipbexpiry' => 'Prazo',
+'ipbreason' => 'Motivo',
+'ipbanononly' => 'Bloquear apenas utilizadores anónimos',
+'ipbcreateaccount' => 'Prevenir criação de conta de utilizador',
+'ipbsubmit' => 'Bloquear este utilizador',
+'ipbother' => 'Outro tempo',
+'ipboptions' => '2 horas:2 hours,1 dia:1 day,3 dias:3 days,1 semana:1 week,2 semanas:2 weeks,1 mês:1 month,3 meses:3 months,6 meses:6 months,1 ano:1 year,infinito:infinite',
+'ipbotheroption' => 'outro',
+'badipaddress' => 'O endereço de IP inválido',
+'blockipsuccesssub' => 'Bloqueio bem sucedido',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|$1]] foi bloqueado.<br />Consulte a [[Special:Ipblocklist|lista de IPs bloqueados]] para rever os bloqueios.',
+'unblockip' => 'Desbloquear utilizador',
+'unblockiptext' => 'Utilize o formulário a seguir para restaurar o acesso à escrita para um endereço de IP ou nome de utilizador previamente bloqueado.',
+'ipusubmit' => 'Desbloquear este utilizador',
+'unblocked' => '[[User:$1|$1]] foi desbloqueado',
+'ipblocklist' => 'Lista de IPs bloqueados',
+'blocklistline' => "$1, $2 bloqueou $3 ($4)",
+'ipblocklistempty' => 'A lista de IPs bloqueados encontra-se vazia.',
+'infiniteblock' => 'infinito',
+'expiringblock' => 'expira em $1',
+'anononlyblock' => 'anón. apenas',
+'createaccountblock' => 'criação de conta de utilizador bloqueada',
+'blocklink' => 'bloquear',
+'unblocklink' => 'desbloquear',
+'contribslink' => 'contribs',
+'autoblocker' => "Foi automaticamente bloqueado pois partilha um endereço de IP com \"$1\". Motivo é: \"$2\".",
+'blocklogpage' => 'Registo de bloqueio',
+'blocklogentry' => 'bloqueou \"[[$1]]\" com um tempo de expiração de $2',
+'blocklogtext' => 'Isto é um registo de acções de bloqueio e desbloqueio. Endereços IP sujeitos a bloqueio automático não são listados. Consulte a [[Special:Ipblocklist|lista de IPs bloqueados]] para obter a lista de bloqueios operativos e bloqueios actualmente válidos.',
+'unblocklogentry' => 'desbloqueou $1',
+'range_block_disabled' => 'A funcionalidade de bloquear gamas de IPs encontra-se desactivada.',
+'ipb_expiry_invalid' => 'Tempo de expiração inválido.',
+'ipb_already_blocked' => '"$1" já encontra-se bloqueado',
+'ip_range_invalid' => "Gama de IPs inválida.",
+'proxyblocker' => 'Bloqueador de proxy',
+'ipb_cant_unblock' => 'Erro: Bloqueio com ID $1 não encontrado. Poderá já ter sido desbloqueado.',
+'proxyblockreason' => 'O seu endereço de IP foi bloqueado por ser um proxy público. Por favor contacte o seu fornecedor do serviço de Internet ou o apoio técnico e informe-os deste problema de segurança grave.',
+'proxyblocksuccess' => "Terminado.",
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'O seu endereço IP encontra-se listado como proxy aberto em [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'O seu endereço de IP encontra-se listado como proxy aberto no [http://www.sorbs.net SORBS] DNSBL. Não pode criar uma conta',
+
+# Developer tools
+#
+'lockdb' => 'Trancar base de dados',
+'unlockdb' => 'Destrancar base de dados',
+'lockdbtext' => 'Trancar a base de dados suspenderá a habilidade de todos os utilizadores de editarem páginas, mudarem suas preferências, lista de artigos vigiados e outras coisas que requerem mudanças na base de dados.<br />
+Por favor confirme que realmente pretende fazer isso, e que vai destrancar a base de dados quando a manutenção estiver concluída.',
+'unlockdbtext' => 'Desbloquear a base de dados vai restaurar a habilidade de todos os utilizadores de editar artigos, mudar suas preferências, editar suas listas de artigos vigiados e outras coisas que requerem mudanças na base de dados. Por favor , confirme que realmente pretende fazer isso.',
+'lockconfirm' => 'Sim, eu realmente desejo bloquear a base de dados.',
+'unlockconfirm' => 'Sim, eu realmente desejo desbloquear a base de dados.',
+'lockbtn' => 'Bloquear base de dados',
+'unlockbtn' => 'Desbloquear base de dados',
+'locknoconfirm' => 'Não marcou a caixa de confirmação.',
+'lockdbsuccesssub' => 'Bloqueio bem sucedido',
+'unlockdbsuccesssub' => 'Desbloqueio bem sucedido',
+'lockdbsuccesstext' => 'A base de dados da {{SITENAME}} foi bloqueada.
+<br />Lembre-se de remover o bloqueio após a manutenção.',
+'unlockdbsuccesstext' => 'A base de dados foi desbloqueada.',
+'lockfilenotwritable' => 'O ficheiro de bloqueio da base de dados não pode ser escrito. Para bloquear ou desbloquear a base de dados, este precisa de poder ser escrito pelo servidor Web.',
+'databasenotlocked' => 'A base de dados não encontra-se bloqueada.',
+
+# Make sysop
+'makesysoptitle' => 'Tornar um utilizador num administrador',
+'makesysoptext' => 'Este formulário é utilizado por burocratas para tornar utilizadores comuns em administradores.
+Introduza o nome do utilizador na caixa e clique no botão para tornar o utilizador num administrador',
+'makesysopname' => 'Nome do utilizador:',
+'makesysopsubmit' => 'Tornar este utilizador num administrador',
+'makesysopok' => "<b>Utilizador \"$1\" é agora um administrador</b>",
+'makesysopfail' => "<b>Não foi possível tornar o utilizador \"$1\" num administrador. (Introduziu o nome correctamente?)</b>",
+'setbureaucratflag' => 'Atribuir flag de burocrata',
+'rightslog' => 'Registo de direitos de utilizador',
+'rightslogtext' => 'Este é um registo de mudanças nos direitos dos utilizadores.',
+'rightslogentry' => "Alterado grupo do membro de $1 de $2 para $3",
+'rights' => 'Direitos:',
+'set_user_rights' => 'Definir direitos de utilizador',
+'user_rights_set' => "<b>Direitos de utilizador para \"$1\" actualizados</b>",
+'set_rights_fail' => "<b>Direitos de utilizador para \"$1\" não poderam ser definidos. (Introduziu o nome correctamente?)</b>",
+'makesysop' => 'Tornar um utilizador num administrador',
+'already_sysop' => 'Este utilizador já é um administrador',
+'already_bureaucrat' => 'Este utilizador já é um burocrata',
+'rightsnone' => '(nenhum)',
+# Move page
+#
+'movepage' => 'Mover página',
+'movepagetext' => 'Utilizando o seguinte formulário poderá renomear uma página, movendo todo o histórico para o novo título. O título antigo será transformado num redireccionamento para o novo.
+Links para as páginas antigas não serão mudados; certifique-se de [[Especial:Maintenance|verificar]] redireccionamentos quebrados ou artigos duplos. Você é responsável por certificar-se que os links continuam apontando para onde eles deveriam apontar.
+
+Note que a página \'\'\'não\'\'\' será movida se já existir uma página com o novo título, a não ser que ele esteja vazio ou seja um redircecionamento e não tenha histórico de edições. Isto significa que pode renomear uma página de volta para o nome que tinha antigamente se cometer algum engano e que não pode sobrescrever uma página.
+
+<b>CUIDADO!!!</b>
+Isto pode ser uma mudança drástica e inesperada para uma página popular; por favor, tenha certeza de que compreende as consequências da mudança antes de avançar.',
+'movepagetalktext' => 'A página de "discussão" associada, se existir, será automaticamente movida, \'\'\'a não ser que:\'\'\'
+*Você esteja movendo uma página estre namespaces,
+*Uma página de discussão (não-vazia) já exista sob o novo título, ou
+*Você não marque a caixa abaixo.
+
+Nestes casos, você terá que mover ou mesclar a página manualmente, se desejar.',
+'movearticle' => 'Mover página',
+'movenologin' => 'Não autenticado',
+'movenologintext' => "Deve ser um utilizador registado e [[Special:Userlogin|autenticado]]</a>
+para mover uma página.",
+'newtitle' => 'Para novo título',
+'movepagebtn' => 'Mover página',
+'pagemovedsub' => 'Página movida com sucesso',
+'pagemovedtext' => "Página \"[[$1]]\" movida para \"[[$2]]\".",
+'articleexists' => 'Uma página com este título já existe, ou o título que escolheu é inválido.
+Por favor, escolha outro nome.',
+'talkexists' => "'''A página em si foi movida com sucesso, porém a página de discussão não pode ser movida, pois, já existe uma com este título. Por favor, mescle-as manualmente.'''",
+'movedto' => 'movido para',
+'movetalk' => 'Mover também a página de discussão associada.',
+'talkpagemoved' => 'A página de \"discussão\" correspondente foi movida com sucesso.',
+'talkpagenotmoved' => 'A página de discussão correspondente <strong>não</strong> foi movida.',
+'1movedto2' => "[[$1]] movido para [[$2]]",
+'1movedto2_redir' => '[[$1]] movido para [[$2]] sob redireccionamento',
+'movelogpage' => 'Registo de movimento',
+'movelogpagetext' => 'Abaixo encontra-se uma lista de páginas movidas.',
+'movereason' => 'Motivo',
+'revertmove' => 'reverter',
+'delete_and_move' => 'Eliminar e mover',
+'delete_and_move_text' =>
+'==Eliminação necessária==
+O artigo destinatário "[[$1]]" já existe. Deseja eliminá-lo de modo a poder mover a página?',
+'delete_and_move_confirm' => 'Sim, eliminar a página',
+'delete_and_move_reason' => 'Eliminada para poder mover outra página para este título',
+'selfmove' => "O título fonte e o título destinatário são os mesmos; não é possível mover uma página para o mesmo sítio.",
+'immobile_namespace' => "O título destinatário é de um tipo especial; não é possível mover páginas para esse domínio.",
+
+# Export
+
+'export' => 'Exportação de páginas',
+'exporttext' => 'É possível exportar o texto e o histórico de edições de uma página em particular num ficheiro XML. Poderá então importar esse conteúdo noutra wiki que utilize o software MediaWiki através da página Especial:Import, ou transformar o conteúdo (via XSLT), ou ainda manter o ficheiro por motivos particulares.
+
+Para exportar páginas, introduza os títulos na caixa de texto abaixo, um título por linha, e seleccione se deseja apenas a versão actual ou todas versões.
+
+Se desejar pode utilizar uma ligação, por exemplo [[{{ns:Special}}:Export/{{Mediawiki:mainpage}}]] para o artigo [[{{Mediawiki:mainpage}}]].',
+'exportcuronly' => 'Incluir apenas a revisão actual, não o histórico inteiro',
+'exportnohistory' => "----
+'''Nota:''' a exportação da história completa das páginas através deste formulário foi desactivada devido a motivos de performance.",
+'export-submit' => 'Exportar',
+
+# Namespace 8 related
+
+'allmessages' => 'Todas mensagens de sistema',
+'allmessagesname' => 'Nome',
+'allmessagesdefault' => 'Texto padrão',
+'allmessagescurrent' => 'Texto actual',
+'allmessagestext' => 'Esta é uma lista de todas mensagens de sistema disponíveis no domínio MediaWiki:.',
+'allmessagesnotsupportedUI' => 'O seu actual idioma de interface <b>$1</b> não é suportado pelo Especial:Allmessages deste sítio.',
+'allmessagesnotsupportedDB' => 'Especial:Allmessages não pode ser utilizado devido ao wgUseDatabaseMessages estar desligado.',
+'allmessagesfilter' => 'Filtro de nome de mensagem:',
+'allmessagesmodified' => 'Mostrar apenas modificados',
+
+# Thumbnails
+
+'thumbnail-more' => 'Ampliar',
+'missingimage' => "<b>Imagem não encontrada</b><br /><i>$1</i>",
+'filemissing' => 'Ficheiro não encontrado',
+'thumbnail_error' => 'Erro ao criar miniatura: $1',
+
+# Special:Import
+'import' => 'Importar páginas',
+'importinterwiki' => 'Importação transwiki',
+'import-interwiki-text' => 'Seleccione uma wiki e um título de página a importar.
+As datas das revisões e os seus editores serão mantidos.
+Todas as acções de importação transwiki são registadas no [[Special:Log/import|Registo de importações]].',
+'import-interwiki-history' => 'Copiar todas revisões para esta página',
+'import-interwiki-submit' => 'Importar',
+'import-interwiki-namespace' => 'Transferir páginas para o domínio:',
+'importtext' => 'Por favor exporte o ficheiro da fonte wiki utilizando o utilitário Especial:Export, salve o ficheiro para o seu disco e importe-o aqui.',
+'importstart' => "Importando páginas...",
+'import-revision-count' => '$1 {{PLURAL:$1|revisão|revisões}}',
+'importnopages' => "Não existem páginas a importar.",
+'importfailed' => "Importação falhou: $1",
+'importunknownsource' => "Tipo de fonte de importação desconhecida",
+'importcantopen' => "Não foi possível abrir o ficheiro de importação",
+'importbadinterwiki' => "Ligação de interwiki incorrecta",
+'importnotext' => 'Vazio ou sem texto',
+'importsuccess' => 'Importação bem sucedida!',
+'importhistoryconflict' => 'Existem conflitos de revisões no histórico (poderá já ter importado esta página antes)',
+'importnosources' => 'Não foram definidas fontes de importação transwiki e o carregamento directo de históricos encontra-se desactivado.',
+'importnofile' => 'Nenhum ficheiro de importação foi carregado.',
+'importuploaderror' => 'O carregamento do ficheiro de importação falhou; talvez o ficheiro seja maior do que o tamanho de carregamento permitido.',
+
+# import log
+'importlogpage' => 'Registo de importações',
+'importlogpagetext' => 'Importações administrativas de páginas com revisões noutras wikis.',
+'import-logentry-upload' => 'importado [[$1]] através de ficheiro de importação',
+'import-logentry-upload-detail' => '{{PLURAL:$1|revisão|revisões}}',
+'import-logentry-interwiki' => 'transwiki $1',
+'import-logentry-interwiki-detail' => '{{PLURAL:$1|revisão|revisões}} de $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Pesquisar na {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Marcar como edição menor [alt-i]',
+'tooltip-save' => 'Salvar as alterações [alt-s]',
+'tooltip-preview' => 'Prever as alterações, por favor utilizar antes de salvar! [alt-p]',
+'tooltip-diff' => 'Mostrar alterações que fez a este texto. [alt-v]',
+'tooltip-compareselectedversions' => 'Ver as diferenças entre as duas versões seleccionadas desta página. [alt-v]',
+'tooltip-watch' => 'Adicionar esta página à sua lista de artigos vigiados [alt-w]',
+
+# stylesheets
+'common.css' => '/** o código CSS colocado aqui será aplicado a todos os temas */',
+'monobook.css' => '/* o código CSS colocado aqui terá efeito nos utilizadores do tema Monobook */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF metadata disabled for this server.',
+'nocreativecommons' => 'Creative Commons RDF metadata disabled for this server.',
+'notacceptable' => 'O servidor não pode fornecer os dados num formato que o seu cliente possa ler.',
+
+# Attribution
+
+'anonymous' => 'Utilizador(es) anónimo(s) da {{SITENAME}}',
+'siteuser' => '{{SITENAME}} utilizador $1',
+'lastmodifiedatby' => 'Esta página foi modificada pela última vez a $2, $1 por $3.',
+'and' => 'e',
+'othercontribs' => 'Baseado no trabalho de $1.',
+'others' => 'outros',
+'siteusers' => '{{SITENAME}} utilizador(es) $1',
+'creditspage' => 'Créditos da página',
+'nocredits' => 'Não há informação disponível sobre os créditos desta página.',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Filtro de protecção contra spam',
+'spamprotectiontext' => 'A página que deseja salvar foi bloqueada pelo filtro de spam. Tal bloqueio foi provavelmente causado por uma ligação para um website externo.',
+'spamprotectionmatch' => 'O seguinte texto activou o filtro de spam: $1',
+'subcategorycount' => "{{PLURAL:$1|Existe uma subcategoria|Existem $1 subcategorias}} nesta categoria.",
+'categoryarticlecount' => "{{PLURAL:$1|Existe um artigo|Existem $1 artigos}} nesta categoria.",
+'listingcontinuesabbrev' => " cont.",
+'spambot_username' => 'MediaWiki limpeza de spam',
+'spam_reverting' => 'Revertendo para a última versão não contendo hiperligações para $1',
+'spam_blanking' => 'Todas revisões contendo hiperligações para $1, limpando',
+
+# Info page
+'infosubtitle' => 'Informação para página',
+'numedits' => 'Número de edições (artigo): $1',
+'numtalkedits' => 'Número de edições (página de discussão): $1',
+'numwatchers' => 'Number of watchers: $1',
+'numauthors' => 'Número de autores distintos (artigo): $1',
+'numtalkauthors' => 'Número de autores distintos (página de discussão): $1',
+
+# Math options
+'mw_math_png' => 'Gerar sempre PNG',
+'mw_math_simple' => 'HTML caso seja simples, caso contrário PNG',
+'mw_math_html' => 'HTML se possível, caso contrário PNG',
+'mw_math_source' => 'Deixar como TeX (para navegadores de texto)',
+'mw_math_modern' => 'Recomendado para navegadores modernos',
+'mw_math_mathml' => 'MathML se possível (experimental)',
+
+# Patrolling
+'markaspatrolleddiff' => "Marcar como verificado",
+'markaspatrolledtext' => "Marcar este artigo como verificado",
+'markedaspatrolled' => "Marcado como verificado",
+'markedaspatrolledtext' => "A revisão seleccionada foi marcada como verificada.",
+'rcpatroldisabled' => "Edições verificadas nas Mudanças Recentes desactivadas",
+'rcpatroldisabledtext' => "A funcionalidade de Edições verificadas nas Mudanças Recentes está actualmente desactivada.",
+'markedaspatrollederror' => "Não pode marcar como verificado",
+'markedaspatrollederrortext' => "Precisa de especificar uma revisão para marcar como verificado.",
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Minha página de utilizador\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'A página de utilizador para o ip que está a utilizar para editar\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Minha página de discussão\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussão sobre edições deste endereço de ip\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Minhas preferências\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Lista de artigos vigiados.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Lista das minhas contribuições\');
+ta[\'pt-login\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'You are encouraged to log in, it is not mandatory however.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Sair\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Discussão sobre o conteúdo da página\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Você pode editar esta página. Por favor, utilize o botão Mostrar Previsão antes de salvar.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Adicionar comentário a essa discussão.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Esta página está protegida; você pode exibir seu código, no entanto.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Edições anteriores desta página.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Proteger esta página\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Apagar esta página\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Restaurar edições feitas a esta página antes da eliminação\');
+ta[\'ca-move\'] = new Array(\'m\',\'Mover esta página\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Adicionar esta página aos artigos vigiados\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Remover esta página dos artigos vigiados\');
+ta[\'search\'] = new Array(\'f\',\'Pesquisar nesta wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Página principal\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Visitar a página principal\');
+ta[\'n-portal\'] = new Array(\'\',\'Sobre o projecto\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Informação temática sobre eventos actuais\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'A lista de mudanças recentes nesta wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Carregar página aleatória\');
+ta[\'n-help\'] = new Array(\'\',\'Um local reservado para auxílio.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Ajude-nos\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lista de todas as páginas que ligam-se a esta\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Mudanças recentes em páginas relacionadas a esta\');
+ta[\'feed-rss\'] = new Array(\'\',\'Feed RSS desta página\');
+ta[\'feed-atom\'] = new Array(\'\',\'Feed Atom desta página\');
+ta[\'t-contributions\'] = new Array(\'\',\'Ver as contribuições deste utilizador\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Enviar um e-mail a este utilizador\');
+ta[\'t-upload\'] = new Array(\'u\',\'Carregar imagens ou ficheiros media\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Lista de páginas especiais\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Ver o conteúdo da página\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Ver a página de utilizador\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Ver a página de media\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Esta é uma página especial, não pode ser editada.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Ver a página de projecto\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Ver a página de imagem\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Ver a mensagem de sistema\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Ver a predefinição\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Ver a página de ajuda\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Ver a página da categoria\');',
+
+# image deletion
+'deletedrevision' => 'Apagada versão antiga $1.',
+
+# browsing diffs
+'previousdiff' => '← Ver a alteração anterior',
+'nextdiff' => 'Ver a alteração posterior →',
+
+'imagemaxsize' => 'Limitar imagens nas páginas de descrição a:',
+'thumbsize' => 'Tamanho de miniaturas:',
+'showbigimage' => 'Descarregar versão de maior resolução ($1x$2, $3 KB)',
+
+'newimages' => 'Galeria de novos ficheiros',
+'showhidebots' => '($1 robôs)',
+'noimages' => 'Nada para ver.',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+# variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Utilizador:',
+'speciallogtitlelabel' => 'Título:',
+
+'passwordtooshort' => 'A sua palavra-chave é demasiado curta. Deve ter no mínimo $1 caracteres.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Aviso\'\'\': Este ficheiro pode conter código malicioso, ao executar o seu sistema poderá estar comprometido.
+<hr />',
+
+'fileinfo' => '$1KB, tipo MIME: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadata',
+'metadata-help' => 'Este ficheiro contém informação adicional, provavelmente adicionada a partir da câmara digital ou scanner utilizada para criar ou digitalizar a imagem. Caso o ficheiro tenha sido modificado a partir do seu estado original, alguns detalhes poderão não reflectir completamente as mudanças efectuadas.',
+'metadata-expand' => 'Mostrar restantes detalhes',
+'metadata-collapse' => 'Esconder restantes detalhes',
+#'metadata-fields' => 'Os campos EXIF metadata listados nesta mensagem serão
+#incluídos na apresentação da página de detalhes da imagem quando a tabela da metadata
+#for minimizada. Outros serão escondidos por defeito.
+#* make
+#* model
+#* datetimeoriginal
+#* exposuretime
+#* fnumber
+#* focallength', # ignore list
+# Exif tags
+'exif-imagewidth' =>'Largura',
+'exif-imagelength' =>'Altura',
+'exif-bitspersample' =>'Bits por componente',
+'exif-compression' =>'Esquema de compressão',
+'exif-photometricinterpretation' =>'Composição pixel',
+'exif-orientation' =>'Orientação',
+'exif-samplesperpixel' =>'Número de componentes',
+'exif-planarconfiguration' =>'Arranjo de dados',
+'exif-ycbcrsubsampling' =>'Subsampling ratio of Y to C',
+'exif-ycbcrpositioning' =>'Posicionamento Y e C',
+'exif-xresolution' =>'Resolução horizontal',
+'exif-yresolution' =>'Resolução vertical',
+'exif-resolutionunit' =>'Unit of X and Y resolution',
+'exif-stripoffsets' =>'Localização de dados da imagem',
+'exif-rowsperstrip' =>'Number of rows per strip',
+'exif-stripbytecounts' =>'Bytes per compressed strip',
+'exif-jpeginterchangeformat' =>'Offset to JPEG SOI',
+'exif-jpeginterchangeformatlength' =>'Bytes de dados JPEG',
+'exif-transferfunction' =>'Função de transferência',
+'exif-whitepoint' =>'White point chromaticity',
+'exif-primarychromaticities' =>'Chromaticities of primarities',
+'exif-ycbcrcoefficients' =>'Color space transformation matrix coefficients',
+'exif-referenceblackwhite' =>'Par de valores de referência de preto e branco',
+'exif-datetime' =>'Data e hora de modificação do ficheiro',
+'exif-imagedescription' =>'Título',
+'exif-make' =>'Fabricante da câmara',
+'exif-model' =>'Modelo da câmara',
+'exif-software' =>'Software utilizado',
+'exif-artist' =>'Autor',
+'exif-copyright' =>'Licença',
+'exif-exifversion' =>'Versão Exif',
+'exif-flashpixversion' =>'Versão de Flashpix suportada',
+'exif-colorspace' =>'Espaço de cor',
+'exif-componentsconfiguration' =>'Significado de cada componente',
+'exif-compressedbitsperpixel' =>'Modo de compressão de imagem',
+'exif-pixelydimension' =>'Largura de imagem válida',
+'exif-pixelxdimension' =>'Altura de imagem válida',
+'exif-makernote' =>'Anotações do fabricante',
+'exif-usercomment' =>'Comentários de utilizadores',
+'exif-relatedsoundfile' =>'Ficheiro áudio relacionado',
+'exif-datetimeoriginal' =>'Data e hora de geração de dados',
+'exif-datetimedigitized' =>'Data e hora de digitalização',
+'exif-subsectime' =>'DateTime subseconds',
+'exif-subsectimeoriginal' =>'DateTimeOriginal subseconds',
+'exif-subsectimedigitized' =>'DateTimeDigitized subseconds',
+'exif-exposuretime' =>'Tempo de exposição',
+'exif-exposuretime-format' => '$1 seg ($2)',
+'exif-fnumber' =>'Número F',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'Programa de exposição',
+'exif-spectralsensitivity' =>'Spectral sensitivity',
+'exif-isospeedratings' =>'Taxa de velocidade ISO',
+'exif-oecf' =>'Factor optoelectrónico de conversão.',
+'exif-shutterspeedvalue' =>'Velocidade do obturador',
+'exif-aperturevalue' =>'Abertura',
+'exif-brightnessvalue' =>'Brilho',
+'exif-exposurebiasvalue' =>'Polarização de exposição',
+'exif-maxaperturevalue' =>'Abertura máxima',
+'exif-subjectdistance' =>'Distância do sujeito',
+'exif-meteringmode' =>'Metering mode',
+'exif-lightsource' =>'Fonte de luz',
+'exif-flash' =>'Flash',
+'exif-focallength' =>'Comprimento de foco da lente',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' =>'Área de sujeito',
+'exif-flashenergy' =>'Energia do flash',
+'exif-spatialfrequencyresponse' =>'Spatial frequency response',
+'exif-focalplanexresolution' =>'Focal plane X resolution',
+'exif-focalplaneyresolution' =>'Focal plane Y resolution',
+'exif-focalplaneresolutionunit' =>'Focal plane resolution unit',
+'exif-subjectlocation' =>'Localização de sujeito',
+'exif-exposureindex' =>'Índice de exposição',
+'exif-sensingmethod' =>'Método de sensação',
+'exif-filesource' =>'Fonte do ficheiro',
+'exif-scenetype' =>'Tipo de cena',
+'exif-cfapattern' =>'CFA pattern',
+'exif-customrendered' =>'Custom image processing',
+'exif-exposuremode' =>'Modo de exposição',
+'exif-whitebalance' =>'White Balance',
+'exif-digitalzoomratio' =>'Digital zoom ratio',
+'exif-focallengthin35mmfilm' =>'Focal length in 35 mm film',
+'exif-scenecapturetype' =>'Tipo de captura de cena',
+'exif-gaincontrol' =>'Controlo de cena',
+'exif-contrast' =>'Contraste',
+'exif-saturation' =>'Saturação',
+'exif-sharpness' =>'Sharpness',
+'exif-devicesettingdescription' =>'Descrição das configurações do dispositivo',
+'exif-subjectdistancerange' =>'Distância de alcance do sujeito',
+'exif-imageuniqueid' =>'Identificação única da imagem',
+'exif-gpsversionid' =>'Versão de GPS',
+'exif-gpslatituderef' =>'Latitude Norte ou Sul',
+'exif-gpslatitude' =>'Latitude',
+'exif-gpslongituderef' =>'Longitude Leste ou Oeste',
+'exif-gpslongitude' =>'Longitude',
+'exif-gpsaltituderef' =>'Referência de altitude',
+'exif-gpsaltitude' =>'Altitude',
+'exif-gpstimestamp' =>'Tempo GPS (relógio atómico)',
+'exif-gpssatellites' =>'Satélites utilizados para a medição',
+'exif-gpsstatus' =>'Estado do receptor',
+'exif-gpsmeasuremode' =>'Modo da medição',
+'exif-gpsdop' =>'Precisão da medição',
+'exif-gpsspeedref' =>'Unidade da velocidade',
+'exif-gpsspeed' =>'Velocidade do receptor GPS',
+'exif-gpstrackref' =>'Referência para a direcção do movimento',
+'exif-gpstrack' =>'Direcção do movimento',
+'exif-gpsimgdirectionref' =>'Referência para a direcção da imagem',
+'exif-gpsimgdirection' =>'Direcção da imagem',
+'exif-gpsmapdatum' =>'Utilizados dados do estudo Geodetic',
+'exif-gpsdestlatituderef' =>'Referência para a latitude do destino',
+'exif-gpsdestlatitude' =>'Latitude do destino',
+'exif-gpsdestlongituderef' =>'Referência para a longitude do destino',
+'exif-gpsdestlongitude' =>'Longitude do destino',
+'exif-gpsdestbearingref' =>'Reference for bearing of destination',
+'exif-gpsdestbearing' =>'Bearing of destination',
+'exif-gpsdestdistanceref' =>'Referência de distância para o destino',
+'exif-gpsdestdistance' =>'Distância para o destino',
+'exif-gpsprocessingmethod' =>'Nome do método de processamento do GPS',
+'exif-gpsareainformation' =>'Nome da área do GPS',
+'exif-gpsdatestamp' =>'Data do GPS',
+'exif-gpsdifferential' =>'Correcção do diferencial do GPS',
+
+# Exif attributes
+
+'exif-compression-1' => 'Descomprimido',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normal', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Flipped horizontally', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Rotated 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Flipped vertically', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Rotated 90° CCW and flipped vertically', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Rotated 90° CW', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Rotated 90° CW and flipped vertically', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Rotated 90° CCW', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'formato irregular',
+'exif-planarconfiguration-2' => 'formato plano',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'não existe',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Não definido',
+'exif-exposureprogram-1' => 'Manual',
+'exif-exposureprogram-2' => 'Programa normal',
+'exif-exposureprogram-3' => 'Aperture priority',
+'exif-exposureprogram-4' => 'Shutter priority',
+'exif-exposureprogram-5' => 'Creative program (biased toward depth of field)',
+'exif-exposureprogram-6' => 'Programa de movimento (tende a velocidade de disparo mais rápida)',
+'exif-exposureprogram-7' => 'Modo de retrato (para fotos em <i>closeup</i> com o fundo fora de foco)',
+'exif-exposureprogram-8' => 'Modo de paisagem (para fotos de paisagem com o fundo em foco)',
+
+'exif-subjectdistance-value' => '$1 metros',
+
+
+'exif-lightsource-0' => 'Desconhecida',
+'exif-lightsource-1' => 'Luz do dia',
+'exif-lightsource-2' => 'Fluorescente',
+'exif-lightsource-10' => 'Tempo nublado',
+
+'exif-focalplaneresolutionunit-2' => 'polegadas',
+
+'exif-customrendered-0' => 'Processo normal',
+'exif-customrendered-1' => 'Processo personalizado',
+
+'exif-exposuremode-0' => 'Exposição automática',
+'exif-exposuremode-1' => 'Exposição manual',
+'exif-exposuremode-2' => 'Auto bracket',
+
+'exif-subjectdistancerange-0' => 'Desconhecida',
+'exif-subjectdistancerange-1' => 'Macro',
+'exif-subjectdistancerange-2' => 'Vista próxima',
+'exif-subjectdistancerange-3' => 'Vista distante',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Quilómetros por hora',
+'exif-gpsspeed-m' => 'Milhas por hora',
+'exif-gpsspeed-n' => 'Nós',
+
+# external editor support
+'edit-externally' => 'Editar este ficheiro utilizando uma aplicação externa',
+'edit-externally-help' => 'Consulte as [http://meta.wikimedia.org/wiki/Help:External_editors instruções de instalação] para mais informação.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'todas',
+'imagelistall' => 'todas',
+'watchlistall1' => 'todas',
+'watchlistall2' => 'todas',
+'namespacesall' => 'todas',
+
+# E-mail address confirmation
+'confirmemail' => 'Confirmar endereço de E-mail',
+'confirmemail_noemail' => 'Não possui um endereço de e-mail válido indicado nas suas [[Special:Preferences|preferências de utilizador]].',
+'confirmemail_text' => "Esta wiki requer que valide o seu endereço de e-mail antes de utilizar as funcionalidades que requerem um endereço de e-mail. Active o botão abaixo para enviar uma confirmação para o seu endereço de e-mail. A mensagem incluíra um endereço que contém um código; carregue o endereço no seu navegador para confirmar que o seu endereço de e-mail encontra-se válido.",
+'confirmemail_send' => 'Enviar código de confirmação',
+'confirmemail_sent' => 'E-mail de confirmação enviado.',
+'confirmemail_sendfailed' => 'Não foi possível enviar o email de confirmação. Por favor verifique o seu endereço de e-mail.
+
+Mailer retornou: $1',
+'confirmemail_invalid' => 'Código de confirmação inválido. O código poderá ter expirado.',
+'confirmemail_needlogin' => 'Precisa de $1 para confirmar o seu endereço de correio electrónico.',
+'confirmemail_success' => 'O seu endereço de e-mail foi confirmado. Pode agora se ligar.',
+'confirmemail_loggedin' => 'O seu endereço de e-mail foi agora confirmado.',
+'confirmemail_error' => 'Alguma coisa correu mal ao guardar a sua confirmação.',
+
+'confirmemail_subject' => '{{SITENAME}} confirmação de endereço de e-mail',
+'confirmemail_body' => "Alguém, provavelmente você com o endereço de IP $1, registou uma conta \"$2\" com este endereço de e-mail na {{SITENAME}}.
+
+Para confirmar que esta conta realmente é sua, e para activar
+as funcionalidades de e-mail na {{SITENAME}}, abra o seguinte endereço no seu navegador:
+
+$3
+
+Caso este *não* seja você, não siga o endereço. Este código de confirmação
+irá expirar a $4.",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Try exact match',
+'searchfulltext' => 'Pesquisar no texto completo',
+'createarticle' => 'Criar artigo',
+
+# Trackbacks
+'trackbackbox' => "<div id='mw_trackbacks'>
+Trackbacks for this article:<br />
+$1
+</div>",
+'trackbackremove' => ' ([$1 Eliminar])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'The trackback was successfully deleted.',
+
+# delete conflict
+
+'deletedwhileediting' => 'Aviso: Esta página foi eliminada após você ter começado a editar!',
+'confirmrecreate' => 'O utilizador [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|Discussão]]) eliminou este artigo após você ter começado a editar, pelo seguinte motivo:
+: \'\'$2\'\'
+Por favor confirme que realmente deseja recriar este artigo.',
+'recreate' => 'Recriar',
+'tooltip-recreate' => 'Recriar a página apesar de ter sido eliminada',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Redireccionando para [[$1]]...',
+
+# action=purge
+'confirm_purge' => "Limpar a memória cache desta página?\n\n$1",
+'confirm_purge_button' => 'OK',
+
+'youhavenewmessagesmulti' => "Tem novas mensagens em $1",
+
+'searchcontaining' => "Pesquisar por artigos contendo ''$1''.",
+'searchnamed' => "Pesquisar por artigos intitulados de ''$1''.",
+'articletitles' => "Artigos começandor com ''$1''",
+'hideresults' => 'Esconder resultados',
+
+# DISPLAYTITLE
+'displaytitle' => '(Ligar a esta página como [[$1]])',
+
+'loginlanguagelabel' => 'Idioma: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; página anterior',
+'imgmultipagenext' => 'próxima página &rarr;',
+'imgmultigo' => 'Ir!',
+'imgmultigotopre' => 'Mostrar página',
+
+# Table pager
+'ascending_abbrev' => 'asc',
+'descending_abbrev' => 'desc',
+'table_pager_next' => 'Próxima página',
+'table_pager_prev' => 'Página anterior',
+'table_pager_first' => 'Primeira página',
+'table_pager_last' => 'Última página',
+'table_pager_limit' => 'Mostrar $1 items por página',
+'table_pager_limit_submit' => 'Ir',
+'table_pager_empty' => 'Sem resultados',
+);
+
+
+?>
diff --git a/languages/messages/MessagesPt_br.php b/languages/messages/MessagesPt_br.php
new file mode 100644
index 000000000000..a8495abdc1f4
--- /dev/null
+++ b/languages/messages/MessagesPt_br.php
@@ -0,0 +1,790 @@
+<?php
+/** Brazilian Portugese (Portuguêsi do Brasil)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+#
+# This translation was made by Yves Marques Junqueira
+# and Rodrigo Calanca Nishino from Portuguese Wikipedia
+#
+
+$fallback = 'pt';
+
+$skinNames = array(
+ 'standard' => 'Padrão',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Especial',
+ NS_MAIN => '',
+ NS_TALK => 'Discussão',
+ NS_USER => 'Usuário',
+ NS_USER_TALK => 'Usuário_Discussão',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_Discussão',
+ NS_IMAGE => 'Imagem',
+ NS_IMAGE_TALK => 'Imagem_Discussão',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_Discussão',
+ NS_TEMPLATE => 'Predefinição',
+ NS_TEMPLATE_TALK => 'Predefinição_Discussão',
+ NS_HELP => 'Ajuda',
+ NS_HELP_TALK => 'Ajuda_Discussão',
+ NS_CATEGORY => 'Categoria',
+ NS_CATEGORY_TALK => 'Categoria_Discussão'
+);
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+
+$messages = array(
+# User Toggles
+"tog-underline" => "Sublinha links",
+"tog-highlightbroken" => "Formata links quebrados <a href=\"\" class=\"new\"> como isto </a> (alternative: como isto<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Justifica parágrafos",
+"tog-hideminor" => "Esconder edições secundárias em mudanças recentes",
+"tog-usenewrc" => "Mudanças recentes melhoradas(nem todos os navegadores)",
+"tog-numberheadings" => "Auto-numerar cabeçalhos",
+"tog-showtoolbar" => "Mostrar barra de edição",
+"tog-editondblclick" => "Editar páginas quando houver clique duplo(JavaScript)",
+"tog-editsection"=>"Habilitar seção de edição via links [edit]",
+"tog-editsectiononrightclick"=>"Habilitar seção de edição por clique <br /> com o botão direito no título da seção (JavaScript)",
+"tog-showtoc"=>"Mostrar Tabela de Conteúdos<br />(para artigos com mais de 3 cabeçalhos)",
+"tog-rememberpassword" => "Lembra senha entre sessões",
+"tog-editwidth" => "Caixa de edição com largura completa",
+"tog-watchdefault" => "Observa artigos novos e modificados",
+"tog-minordefault" => "Marca todas as edições como secundárias, por padrão",
+"tog-previewontop" => "Mostrar Previsão antes da caixa de edição ao invés de ser após",
+"tog-nocache" => "Desabilitar caching de página",
+# Dates
+'sunday' => 'Domingo',
+'monday' => 'Segunda',
+'tuesday' => 'Terça-Feira',
+'wednesday' => 'Quarta-Feira',
+'thursday' => 'Quinta-Feira',
+'friday' => 'Sexta-Feira',
+'saturday' => 'Sábado',
+'january' => 'Janeiro',
+'february' => 'Fevereiro',
+'march' => 'Março',
+'april' => 'Abril',
+'may_long' => 'Maio',
+'june' => 'Junho',
+'july' => 'Julho',
+'august' => 'Agosto',
+'september' => 'Setembro',
+'october' => 'Outubro',
+'november' => 'Novembro',
+'december' => 'Dezembro',
+'jan' => 'Jan',
+'feb' => 'Fev',
+'mar' => 'Mar',
+'apr' => 'Abr',
+'may' => 'Mai',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Ago',
+'sep' => 'Set',
+'oct' => 'Out',
+'nov' => 'Nov',
+'dec' => 'Dez',
+
+
+# Bits of text used by many pages:
+#
+"categories" => "Page categories",
+"pagecategories" => "Page categories",
+"category_header" => "Articles in category \"$1\"",
+"subcategories" => "Subcategories",
+
+"mainpage" => "Página principal",
+"mainpagetext" => "Software Wiki instalado com sucesso.",
+"about" => "Sobre",
+"aboutsite" => "Sobre a {{SITENAME}}",
+"aboutpage" => "{{ns:4}}:Sobre",
+"help" => "Ajuda",
+"helppage" => "{{ns:4}}:Ajuda",
+"bugreports" => "Reportagem de 'bugs'",
+"bugreportspage" => "{{ns:4}}:Reportag_Bug",
+"faq" => "FAQ",
+"faqpage" => "{{ns:4}}:FAQ",
+"edithelp" => "Ajuda de edição",
+"edithelppage" => "{{ns:4}}:Como_editar_uma_página",
+"cancel" => "Cancela",
+"qbfind" => "Procura",
+"qbbrowse" => "Folhear",
+"qbedit" => "Editar",
+"qbpageoptions" => "Opções de página",
+"qbpageinfo" => "Informação de página",
+"qbmyoptions" => "Minhas opções",
+"mypage" => "Minha página",
+"mytalk" => "Minha discussão",
+"currentevents" => "Eventos atuais",
+"errorpagetitle" => "Erro",
+"returnto" => "Retorna para $1.",
+"whatlinkshere" => "Páginas que se ligam a essa",
+"help" => "Ajuda",
+"search" => "Busca",
+"searchbutton" => "Busca",
+"go" => "Vai",
+'searcharticle' => "Vai",
+"history" => "Histórico",
+"printableversion" => "Versão para impressão",
+"editthispage" => "Editar esta página",
+"deletethispage" => "Apagar esta página",
+"protectthispage" => "Proteger esta página",
+"unprotectthispage" => "Desproteger esta página",
+"newpage" => "Nova página",
+"talkpage" => "Discutir esta página",
+"postcomment" => "Post a comment",
+"articlepage" => "Ver atigo",
+"userpage" => "Ver página de usuário",
+"projectpage" => "Ver meta página",
+"imagepage" => "Ver página de imagens",
+"viewtalkpage" => "Ver discussões",
+"otherlanguages" => "Outras línguas",
+"redirectedfrom" => "(Redirecionado de $1)",
+"lastmodifiedat" => "Está página foi modificada pela última vez em $2, $1.",
+"viewcount" => "Esta página foi acessada $1 vezes.",
+"protectedpage" => "Página protegida",
+"nbytes" => "$1 bytes",
+"ok" => "OK",
+"retrievedfrom" => "Retirado de \"$1\"",
+"newmessageslink" => "novas mensagens",
+"editsection"=>"editar",
+"editold"=>"editar",
+"toc" => "Conteúdo",
+"showtoc" => "mostrar",
+"hidetoc" => "esconder",
+
+# Main script and global functions
+#
+"nosuchaction" => "Ação não existente",
+"nosuchactiontext" => "A ação especificada pela URL não é
+reconhecida pelo programa da {{SITENAME}}",
+"nosuchspecialpage" => "Não exista esta página especial",
+"nospecialpagetext" => "Você requisitou uma página especial que não é
+reconhecida pelo software da {{SITENAME}}.",
+
+# General errors
+#
+"error" => "Erro",
+"databaseerror" => "Erro no banco de dados",
+"dberrortext" => "Um erro de sintaxe de busca no banco de dados ocorreu.
+A última tentativa de busca no banco de dados foi:
+<blockquote><tt>$1</tt></blockquote>
+na função \"<tt>$2</tt>\".
+MySQL retornou o erro \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Um erro de sintaxe de pesquisa no banco
+de dados ocorreu.
+A última tentativa de pesquisa no banco de dados foi:
+\"$1\"
+com a função\"$2\".
+MySQL retornou o erro \"$3: $4\".",
+"noconnect" => "Desculpe! O wiki está passando por algumas
+dificuldades técnicas, e não pode contactar o servidor de bando de dados.",
+"nodb" => "Não foi possível selecionar o banco de dados $1",
+"cachederror" => "O que segue é uma cópia em cache da página
+solicitada, e pode não estar atualizada.",
+"readonly" => "Banco de dados somente para leitura",
+"enterlockreason" => "Entre com um motivo para trancá-lo, incluindo uma estimativa de quando poderá novamente ser escrito",
+"readonlytext" => "O Banco-de-dados da {{SITENAME}} está atualmente bloqueado para novos
+artigos e outras modificações, provávelmente por uma manutenção rotineira no Bando de Dados,
+mais tarde voltará ao normal.
+
+O administrador que fez o bloqueio oferece a seguinte explicação:
+<p>$1",
+"missingarticle" => "O Banco-de-Dados não encontrou o texto de uma página
+que deveria ser encontrado, chamado \"$1\".
+
+<p>Isto é geralmente causado pela procura de um diff antigo ou um histórico que leva a uma página que foi deletada.
+
+<p>Se isto não for o caso, você pode ter encontrado um bug no software.
+Por favor, comunique isto ao administrador, tenha nota da URL.",
+"internalerror" => "Erro Interno",
+"filecopyerror" => "Não foi possível copiar o arquivo \"$1\" para \"$2\".",
+"filerenameerror" => "Não foi possível renomear o arquivo \"$1\" para \"$2\"",
+"filedeleteerror" => "Não foi possível deletar o arquivo \"$1\".",
+"filenotfound" => "Não foi possível encontrar o arquivo \"$1\".",
+"unexpected" => "Valor não esperado: \"$1\"=\"$2\".",
+"formerror" => "Erro: Não foi possível enviar o formulário",
+"badarticleerror" => "Esta acção não pode ser performada nesta página.",
+"cannotdelete" => "Não foi possível excluir página ou imagem especificada. (Ela já pode ter sido deletada por alguém.)",
+"badtitle" => "Título ruim",
+"badtitletext" => "O título de página requisitado era inválido, vazio, ou
+um link incorreto de inter-linguagem ou título inter-wiki .",
+"perfdisabled" => "Desculpe! Esta opção foi temporariamente desabilitada
+porque tornava o banco de dados lento demais a ponto de impossibilitar o wiki.",
+"perfdisabledsub" => "Aqui está uma cópia salva de $1:",
+
+# Login and logout pages
+#
+"logouttitle" => "Saída de utilizador",
+"logouttext" => "Você agora não está mais autenticado.
+Você pode continuar a usar a {{SITENAME}} anonimamente, ou pode se autenticar
+novamente como o mesmo utilizador ou como um utilizador diferente.",
+
+"welcomecreation" => "<h2>Bem-vindo, $1!</h2><p>Sua conta foi criada.
+Não se esqueça de personalizar suas preferências na {{SITENAME}}.",
+
+"loginpagetitle" => "Login de usuário",
+"yourname" => "Seu nome de usuário",
+"yourpassword" => "Sua senha",
+"yourpasswordagain" => "Redigite sua senha",
+"remembermypassword" => "Lembrar de minha senha em outras sessões.",
+"loginproblem" => "<b>Houve um problema com a sua autenticação.</b><br />Tente novamente!",
+"alreadyloggedin" => "<strong>Utilizador $1, você já está autenticado!</strong><br />",
+
+"login" => "Entrar",
+"userlogin" => "Entrar",
+"logout" => "Sair",
+"userlogout" => "sair",
+"notloggedin" => "Não-logado",
+"createaccount" => "Criar nova conta",
+"createaccountmail" => "por e-Mail",
+"badretype" => "As senhas que você digitou não são iguais.",
+"userexists" => "O nome de usuário que você digitou já existe. Por favor, escolha um nome diferente.",
+"youremail" => "Seu e-mail*",
+"yournick" => "Seu apelido (para assinaturas)",
+"loginerror" => "Erro de autenticação",
+"noname" => "Você não colocou um nome de usuário válido.",
+"loginsuccesstitle" => "Login bem sucedido",
+"loginsuccess" => "Agora você está logado na {{SITENAME}} como \"$1\".",
+"nosuchuser" => "Não há nenhum usuário com o nome \"$1\".
+Verifique sua grafia, ou utilize o formulário a baixo para criar uma nova conta de usuário.",
+"wrongpassword" => "A senha que você entrou é inválida. Por favor tente novamente.",
+"mailmypassword" => "Envie uma nova senha por e-mail",
+"passwordremindertitle" => "Lembrador de senhas da {{SITENAME}}",
+"passwordremindertext" => "Alguém (provavelmente você, do endereço de IP $1)
+solicitou que nós lhe enviássemos uma nova senha para login.
+A senha para o usuário \"$2\" é a partir de agora \"$3\".
+Você pode realizar um login e mudar sua senha agora.",
+"noemail" => "Não há nenhum e-Mail associado ao usuário \"$1\".",
+"passwordsent" => "Uma nova senha está sendo enviada para o endereço de e-Mail
+registrado para \"$1\".
+Por favor, reconecte-se ao recebê-lo.",
+
+# Edit pages
+#
+"summary" => "Sumário",
+"subject" => "Assunto",
+"minoredit" => "Edição menor",
+"watchthis" => "Observar este artigo",
+"savearticle" => "Salvar página",
+"preview" => "Prever",
+"showpreview" => "Mostrar Pré-Visualização",
+"blockedtitle" => "Usuário está bloqueado",
+"blockedtext" => "Seu nome de usuário ou numero de IP foi bloqueado por $1.
+O motivo é:<br />''$2''<p>Você pode contactar $1 ou outro
+[[{{ns:4}}:administradores|administrador]] para discutir sobre o bloqueio.",
+"whitelistedittitle" => "Login necessário para edição",
+"whitelistedittext" => "Você precisa se [[Especial:Userlogin|logar]] para editar artigos.",
+"whitelistreadtitle" => "Login necessário para leitura",
+"whitelistreadtext" => "Você precisa se [[Especial:Userlogin|logar]] para ler artigos.",
+"whitelistacctitle" => "Você não está habilitado a criar uma conta",
+"whitelistacctext" => "Para ter permissão para se criar uma conta neste Wiki você precisará estar [[Especial:Userlogin|logado]] e ter as permissões apropriadas.",
+"accmailtitle" => "Senha enviada.",
+"accmailtext" => "A senha de '$1' foi enviada para $2.",
+"newarticle" => "(Novo)",
+"newarticletext" =>
+"Você seguiu um link para um artigo que não existe.
+Para criá-lo, começe escrevendo na caixa abaixo
+(veja [[{{ns:4}}:Ajuda|a página de ajuda]] para mais informações).
+Se você chegou aqui por engano, apenas clique no botão '''voltar''' do seu navegador.",
+
+"anontalkpagetext" => "---- ''Esta é a página de discussão para um usuário anônimo que não criou uma conta ainda ou que não a usa. Então nós temos que usar o endereço numérico de IP para identificá-lo. Um endereço de IP pode ser compartilhado por vários usuários. Se você é um usuário anônimo e acha irrelevante que os comentários sejam direcionados a você, por favor [[Especial:Userlogin|crie uma conta ou autentique-se]] para evitar futuras confusões com outros usuários anônimos.''",
+"noarticletext" => "(Não há atualmente nenhum texto nesta página)",
+"updated" => "(Atualizado)",
+"note" => "<strong>Nota:</strong>",
+"previewnote" => "Lembre-se que isto é apenas uma previsão. O conteúdo ainda não foi salvo!",
+"previewconflict" => "Esta previsão reflete o texto que está na área de edição acima e como ele aparecerá se você escolher salvar.",
+"editing" => "Editando $1",
+'editinguser' => "Editando $1",
+"editingsection" => "Editando $1 (seção)",
+"editingcomment" => "Editando $1 (comentário)",
+"editconflict" => "Conflito de edição: $1",
+"explainconflict" => "Alguém mudou a página enquanto você a estava editando.
+A área de texto acima mostra o texto original.
+Suas mudanças são mostradas na área abaixo.
+Você terá que mesclar suas modificações no texto existente.
+<b>SOMENTE</b> o texto na área acima será salvo quando você pressionar \"Salvar página\".<br />",
+"yourtext" => "Seu texto",
+"storedversion" => "Versão guardada",
+"editingold" => "<strong>CUIDADO: Você está editando uma revisão desatualizada deste artigo.
+Se você salvá-lo, todas as mudanças feitas a partir desta revisão serão perdidas.</strong>",
+"yourdiff" => "Diferenças",
+/*"copyrightwarning" => "Por favor note que todas as contribuições � {{SITENAME}} são consideradas lançadas sobre a GNU Free Documentation License
+(veja $1 para detalhes).
+Se você não quer que seu texto esteja sobre estes termos, então não os envie.<br />
+Você também promete que está nos enviando um artigo escrito por você mesmo, ou extraindo de uma fonte de domínio público similar.
+<strong>NÃO ENVIE TRABALHO SOB COPYRIGHT SEM PERMISSÃO!</strong>",*/
+"longpagewarning" => "<strong>CUIDADO: Esta página tem $1 kilobytes ; alguns browsers podem ter problemas ao editar páginas maiores que 32kb.
+Por favor considere quebrar a página em sessões menores.</strong>",
+"readonlywarning" => "<strong>CUIDADO: O banco de dados está sendo bloqueado para manutenção.
+No momento não é possível salvar suas edições. Você pode copiar e colar o texto em um arquivo de texto e salvá-lo em seu computador para adicioná-lo ao wiki mais tarde.</strong>",
+"protectedpagewarning" => "<strong>CUIDADO: Apenas os usuários com privilégios de sysop podem editar esta página pois ela foi bloqueada. Certifique-se de que você está seguindo o [[Project:Guia_de_páginas_protegidas|guia de páginas protegidas]].</strong>",
+
+# History pages
+#
+"revhistory" => "Histórico de revisões",
+"nohistory" => "Não há histórico de revisões para esta página.",
+"revnotfound" => "Revisão não encontrada",
+"revnotfoundtext" => "A antiga revisão da página que você está procurando não pode ser encontrada.
+Por favor verifique a URL que você usou para acessar esta página.",
+"loadhist" => "Carregando histórico",
+"currentrev" => "Revisão atual",
+"revisionasof" => "Revisão de $1",
+"cur" => "atu",
+"next" => "prox",
+"last" => "ult",
+"orig" => "orig",
+"histlegend" => "Legenda: (atu) = diferenças da versão atual,
+(ult) = diferença da versão precedente, M = edição minoritária",
+
+# Diffs
+#
+"difference" => "Diferença entre revisões)",
+"loadingrev" => "carregando a busca por diferenças",
+"lineno" => "Linha $1:",
+"editcurrent" => "Editar a versão atual desta página",
+
+# Resultados da Busca
+#
+"searchresults" => "Buscar resultados",
+"searchresulttext" => "Para mais informações sobre busca na {{SITENAME}}, veja [[Project:Procurando|Busca na {{SITENAME}}]].",
+"searchsubtitle" => "Para pedido de busca \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Para pedido de busca \"$1\"",
+"badquery" => "Linha de busca incorretamente formada",
+"badquerytext" => "Nós não pudemos processar seu pedido de busca.
+Isto acoenteceu provavelmente porque você tentou procurar uma palavra de menos que três letras, coisa que o software ainda não consegue realizar. Isto também pode ter ocorrido porque você digitou incorretamente a expressão, por
+exemplo: \"peixes <strong>and and</strong> scales\".
+Por favor realize ouro pedido de busca.",
+"matchtotals" => "A pesquisa \"$1\" resultou $2 títulos de artigos
+e $3 artigos com o texto procurado.",
+"noexactmatch" => "Nenhum artigo com um título exatamente igual a este foi encontrado, tentando na pesquisa completa por texto.",
+"titlematches" => "Resultados nos títulos dos artigos",
+"notitlematches" => "Sem resultados nos títulos dos artigos",
+"textmatches" => "Resultados nos textos dos artigos",
+"notextmatches" => "Sem resultados nos textos dos artigos",
+"prevn" => "anterior $1",
+"nextn" => "próximo $1",
+"viewprevnext" => "Ver ($1) ($2) ($3).",
+"showingresults" => "Mostrando os próximos <b>$1</b> resultados começando com #<b>$2</b>.",
+"showingresultsnum" => "Mostrando <b>$3</b> resultados começando com #<b>$2</b>.",
+"nonefound" => "<strong>Nota</strong>: pesquisas mal sucedidas são geralmente causadas devido o uso de palavras muito comuns como \"tem\" e \"de\",
+que não são indexadas, ou pela especificação de mais de um termo (somente as páginas contendo todos os termos aparecerão nos resultados).",
+"powersearch" => "Pesquisa",
+"powersearchtext" => "
+Procurar nos namespaces :<br />
+$1<br />
+$2 Lista redireciona &nbsp; Procura por $3 $9",
+"blanknamespace" => "(Principal)",
+
+# Preferences page
+#
+"preferences" => "Preferências",
+"prefsnologin" => "Não autenticado",
+"prefsnologintext" => "Você precisa estar [[Special:Userlogin|autenticado]]
+para definir suas preferências.",
+"prefsreset" => "Preferências foram reconfiguradas.",
+"qbsettings" => "Configurações da Barra Rápida",
+"changepassword" => "Mudar senha",
+"skin" => "Aparência(Skin)",
+"math" => "Renderização matemática",
+"dateformat" => "Formato da Data",
+"math_failure" => "Falhou ao checar gramática(parse)",
+"math_unknown_error" => "erro desconhecido",
+"math_unknown_function" => "função desconhecida",
+"math_lexing_error" => "erro léxico",
+"math_syntax_error" => "erro de síntaxe",
+"saveprefs" => "Salvar preferências",
+"resetprefs" => "Redefinir preferências",
+"oldpassword" => "Senha antiga",
+"newpassword" => "Nova senha",
+"retypenew" => "Redigite a nova senha",
+"textboxsize" => "Tamanho da caixa de texto",
+"rows" => "Linhas",
+"columns" => "Colunas",
+"searchresultshead" => "Configurar resultados de pesquisas",
+"resultsperpage" => "Resultados por página",
+"contextlines" => "Linhas por resultados",
+"contextchars" => "Letras de contexto por linha",
+"stubthreshold" => "Threshold for stub display",
+"recentchangescount" => "Número de títulos em Mudanças Recentes",
+"savedprefs" => "Suas preferências foram salvas.",
+"timezonetext" => "Entre com o número de horas que o seu horário local difere do horário do servidor (UTC).",
+"localtime" => "Display de hora local",
+"timezoneoffset" => "Offset",
+"servertime" => "Horário do servidor é",
+"guesstimezone" => "Colocar no navegador",
+"defaultns" => "Procurar nestes namespaces por padrão:",
+
+# Recent changes
+#
+"changes" => "mudanças",
+"recentchanges" => "Mudanças Recentes",
+"recentchangestext" => "Veja as mais novas mudanças na {{SITENAME}} nesta página.
+[[{{ns:4}}:Bem Vindo,_novatos|Bem Vindo, novatos]]!
+Por favor, dê uma olhada nestas páginas: [[{{ns:4}}:FAQ|FAQ da {{SITENAME}}]],
+[[{{ns:4}}:Políticas e Normas| Política da {{SITENAME}}]]
+(especialmente [[{{ns:4}}:Convenções de nomenclatura|convenções de nomenclatura]],
+[[{{ns:4}}:Ponto de vista neutro|Ponto de vista neutro]]),
+e [[{{ns:4}}:Most common {{SITENAME}} faux pas|most common {{SITENAME}} faux pas]].
+
+Se você quer ver a {{SITENAME}} crescer, é muito importante que você não adicione material restrito por outras [[{{ns:4}}:Copyrights|copyrights]].
+Um problema legal poderia realmente prejudicar o projeto de maneira que pedimos, por avor, não faça isso.",
+"rcnote" => "Abaixo estão as últimas <strong>$1</strong> alterações nos últimos <strong>$2</strong> dias.",
+"rcnotefrom" => "Abaixo estão as mudanças desde <b>$2</b> (até <b>$1</b> mostradas).",
+"rclistfrom" => "Mostrar as novas alterações a partir de $1",
+"rclinks" => "Mostrar as últimas $1 mudanças nos últimos $2 dias; $3 edições minoritárias",
+"diff" => "dif",
+"hist" => "hist",
+"hide" => "esconde",
+"show" => "mostra",
+"minoreditletter" => "M",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => "Carregar arquivo",
+"uploadbtn" => "Carregar arquivo",
+"reupload" => "Re-carregar",
+"reuploaddesc" => "Retornar ao formulário de Uploads.",
+"uploadnologin" => "Não autenticado",
+"uploadnologintext" => "Você deve estar [[Special:Userlogin|autenticado]]
+para carregar arquivos.",
+"uploaderror" => "Erro ao Carregar",
+/*"uploadtext" => "'''PARE!''' Antes de você carregar arquivos aqui,
+tenha certeza de ter lido e estar em acordo com a
+[[Project:Política_de_imagens|política de uso de imagens da {{SITENAME}}]].
+
+Para ver ou procurar imagens carregadas,
+vá � [[Special:Imagelist|lista de imagens carregadas]].
+Uploads e deleções são armazenados no
+[[Project:Upload_log|log de uploads]].
+
+Use o formulário a seguir para carregar arquivos de imagens para ilustrar seus artigos. Na maioria dos navegadores, você verá um botão \"Browse...\" , que trárá o diálogo padrão de abertura de arquivo padrão do seu Sistema Operacional.
+Ao escolher um arquivo, o campo de texto próximo ao botão será preenchido.
+Você tembém deve confirmar que não está carregando nenhum arquivo protegido por Diretos Autorais.
+Pressione o botão \"Carregar\" para finalizar o upload.
+Isto pode demorar um pouco se você tem possui uma conexão lenta.
+
+Os formatos ideais são JPEG para fotos, PNG
+para ilustrações, e OGG para sons.
+Por favor, nomeie seus arquivos de forma descritiva para evitar confusões.
+Para incluir uma imagem em um artigo, use um link na forma
+'''<nowiki>[[image:arquivo.jpg]]</nowiki>''' ou
+'''<nowiki>[[image:arquivo.png|texto descritivo]]</nowiki>''' ou
+'''<nowiki>[[media:audio.ogg]]</nowiki> para sons.
+
+Por favor, note que com as páginas da {{SITENAME}}, outros usuários podem modificar ou deletar seus uploads se eles acharem que isto seja útil � {{SITENAME}}, e você possa estar bloqueado para uploads devido a abusos do sistema.",*/
+"uploadlog" => "log de uploads",
+"uploadlogpage" => "Log_de_Uploads",
+"uploadlogpagetext" => "Segue uma lista dos uploads mais recentes.
+Todas as datas mostradas são do servidor (UTC).
+<ul>
+</ul>",
+"filename" => "Nome do arquivo",
+"filedesc" => "Sumário",
+"copyrightpage" => "{{ns:4}}:Copyrights",
+"copyrightpagename" => "Direitos Autorais da {{SITENAME}}",
+
+"uploadedfiles" => "Arquivos carregados",
+"minlength" => "Os nomes das imagens devem ter ao menos três letras.",
+"badfilename" => "O nome da imagem mudou para \"$1\".",
+"badfiletype" => "\".$1\" não está em um formato recomendável.",
+"largefile" => "É recomendado que as imagens não tenham mais que 100k de tamanho.",
+"successfulupload" => "Carregamento efetuado com sucesso",
+/*"fileuploaded" => "Arquivo \"$1\" carregado com sucesso.
+Por favor, siga este link : ($2) para ir � página de descrição e preencha-a com informações sobre o arquivo, como de onde veio , quando e por quem foi criada, e qualquer outra coisa a mais que você saiba.",*/
+"uploadwarning" => "Aviso de Upload",
+"savefile" => "Salvar arquivo",
+"uploadedimage" => "\"[[$1]]\" carregado",
+
+# Image list
+#
+"imagelist" => "Lista de Imagens",
+"imagelisttext" => "A seguir uma lista de $1 imagens organizadas $2.",
+"getimagelist" => "buscando lista de imagens",
+"ilsubmit" => "Procura",
+"showlast" => "Mostrar as $1 imagens organizadas $2.",
+"byname" => "por nome",
+"bydate" => "por data",
+"bysize" => "por tamanho",
+"imgdelete" => "del",
+"imgdesc" => "desc",
+"imglegend" => "Legenda: (desc) = mostrar/editar descrição de imagem.",
+"imghistory" => "Histórico das imagens",
+"revertimg" => "rev",
+"deleteimg" => "del",
+"deleteimgcompletely" => "del",
+"imghistlegend" => "Legenda: (cur) = esta é a imagem atual, (del) = deletar
+esta versão antiga, (rev) = reverter para esta versão antiga.
+<br /><i>Clique em data para ver das imagens carregadas nesta data</i>.",
+"imagelinks" => "Links das imagens",
+"linkstoimage" => "As páginas seguintes apontam para esta imagem:",
+"nolinkstoimage" => "Nenhuma página aponta para esta imagem.",
+
+# Statistics
+#
+"statistics" => "Estatísticas",
+"sitestats" => "Estatísticas do Site",
+"userstats" => "Estatística dos usuários",
+"sitestatstext" => "Há atualmente um total de <b>$1</b> páginas em nosso banco de dados.
+Isto inclui páginas \"talk\", páginas sobre a {{SITENAME}}, páginas de rascunho, redirecionamentos, e outras que provavelmente não são qualificadas como artigos.
+Excluindo estas, há <b>$2</b> páginas que provavelmente são artigos legitimos .<p>
+Há um total de <b>$3</b> páginas vistas, e <b>$4</b> edições de página
+desde a última atualização do software (Janeiro de 2004).
+O que nos leva a aproximadamente <b>$5</b> edições por página, e <b>$6</b> vistas por edição.",
+"userstatstext" => "Há atualmente <b>$1</b> usuários registrados.
+Destes, <b>$2</b> são administradores (veja $3).",
+
+# Maintenance Page
+#
+"disambiguations" => "Páginas de desambiguamento",
+"disambiguationspage" => "{{ns:4}}:Links_para_desambiguar_páginas",
+"disambiguationstext" => "Os artigos a seguir apontam para uma <i>página de desambiguamento</i>. Ao invés disso, eles deveriam apontar para um tópico apropriado.<br /> Uma página é tratada como disambiguamento se ela é por $1.<br />Links de outros namespaces <i>não</i> estão listados aqui.",
+"doubleredirects" => "Double Redirects",
+"doubleredirectstext" => "<b>Atenção:</b> Esta lista pode conter positivos falsos. O que usualmente significa que há texto adicional com links depois do primeiro #REDIRECT.<br />\nCada linha contem links para o primeiro e segundo redirecionamento, bem como a primeira linha do segundo texto redirecionado , geralmente dando o artigo alvo \"real\" , para onde o primeiro redirecionamento deveria apontar.",
+"brokenredirects" => "Redirecionamentos Quebrados",
+"brokenredirectstext" => "Os seguintes redirecionamentos apontam para um artigo inexistente.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Páginas órfãns",
+"unusedimages" => "Imagens não utilizadas",
+"popularpages" => "Páginas populares",
+"nviews" => "$1 visitas",
+"wantedpages" => "Páginas procuradas",
+"nlinks" => "$1 links",
+"allpages" => "Todas as páginas",
+"randompage" => "Página aleatória",
+"shortpages" => "Páginas Curtas",
+"longpages" => "Paginas Longas",
+"listusers" => "Lista de Usuários",
+"specialpages" => "Páginas especiais",
+"spheading" => "Páginas especiais para todos os usuários",
+"recentchangeslinked" => "Páginas relacionadas",
+"rclsub" => "(para páginas linkadas de \"$1\")",
+"newpages" => "Páginas novas",
+"ancientpages" => "Artigos mais antigos",
+"intl" => "Links interlínguas",
+"movethispage" => "Mover esta página",
+"unusedimagestext" => "<p>Por favor note que outros websites como
+as Wikipédias internacionais podem apontar para uma imagem com uma URL direta, e por isto pode estar aparecendo aqui mesmo estando em uso ativo.",
+"booksources" => "Fontes de livros",
+"booksourcetext" => "Segue uma lista de links para outros sites que vendem livros novos e usados , e podem ter informações adicionais sobre livros que você esteja procurando.
+A {{SITENAME}} não é afiliada a nenhum destes empreendimentos, e a lista não deve ser construída como apoio.",
+"alphaindexline" => "$1 para $2",
+
+# Email this user
+#
+"mailnologin" => "Sem endereço ed envio",
+"mailnologintext" => "Você deve estar [[Special:Userlogin|autenticado]]
+e ter um e-mail válido em suas [[Special:Preferences|preferências]]
+para poder enviar e-mails para outros usuários.",
+"emailuser" => "Contactar usuário",
+"emailpage" => "Enviar e-mail ao usuário",
+"emailpagetext" => "Se este usuário disponibilizou um endereço válido de e-mail em suas preferências, o formulário a seguir enviará uma mensagem única.
+O endereço de e-mail que você disponibilizou em suas preferências aparecerá como remetente da mensagem, então, o usuário poderá responder a você diretamente.",
+"noemailtitle" => "Sem endereço de e-mail",
+"noemailtext" => "Este usuário não especificou um endereço de e-mail válido, ou optou por não receber mensagens de outros usuários.",
+"emailfrom" => "De",
+"emailto" => "Para",
+"emailsubject" => "Assunto",
+"emailmessage" => "Mensagem",
+"emailsend" => "Enviar",
+"emailsent" => "E-mail enviado",
+"emailsenttext" => "Sua mensagem foi enviada.",
+
+# Watchlist
+#
+"watchlist" => "Artigos do meu interesse",
+"nowatchlist" => "Você não está monitorando nenhum artigo.",
+"watchnologin" => "Não está autenticado",
+"watchnologintext" => "Você deve estar [[Special:Userlogin|autenticado]]
+para modificar a lista de artigos do seu interesse.",
+/*"addedwatch" => "Adicionados � lista",*/
+"addedwatchtext" => "A página \"$1\" foi adicionada à <a href=\"{{localurle:Special:Watchlist}}\">lista de artigos do seu interesse</a>.
+Modificações futuras neste artigo e páginas de discussão associadas serão listadas aqui,
+e a página aparecerá <b>em negrito</b> na <a href=\"{{localurle:Special:Recentchanges}}\">lista de mudanças recentes</a> para que
+possa achá-la com maior facilidade.</p>
+
+<p>Se você quiser remover futuramente o artigo da sua lista de artigos vigiados, clique em \"Desinteressar-se\" na barra lateral.",
+"removedwatch" => "Removida da lista de monitoramento",
+"removedwatchtext" => "A página \"$1\" não é mais de seu interesse e portanto foi removida de sua lista de monitoramento.",
+"watchthispage" => "Interessar-se por esta página",
+"unwatchthispage" => "Desinteressar-se",
+"notanarticle" => "Não é um artigo",
+"watchnochange" => "Nenhum dos itens monitorados foram editados no período exibido.",
+"watchdetails" => "($1 páginas monitoradas excluindo-se as páginas de discussão;
+$2 páginas editadas desde data limite;
+$3...
+[$4 mostrar e editar a lista completa].)",
+"watchmethod-recent" => "checando edições recentes para os artigos monitorados",
+"watchmethod-list" => "checando páginas monitoradas de edições recentes",
+"removechecked" => "Remover itens selecionados",
+"watchlistcontains" => "Sua lista contém $1 páginas.",
+"watcheditlist" => "Aqui está uma lista alfabética de sua lista de artigos observados. Marque as caixas dos artigos que você deseja remover e clique no botão 'Remover itens selecionados' na parte de baixo da tela.",
+"removingchecked" => "Removendo os itens solicitados de sua lista de monitoramento...",
+"couldntremove" => "Não consegui remover o item '$1'...",
+"iteminvalidname" => "Problema com item '$1', nome inválido...",
+"wlnote" => "Segue as últimas $1 mudanças nas últimas <b>$2</b> horas.",
+
+
+# Delete/protect/revert
+#
+"deletepage" => "Deletar página",
+"confirm" => "Confirmar",
+"excontent" => "conteúdo era: '$1'",
+"exbeforeblank" => "conteúdo antes de apagar era: '$1'",
+"exblank" => "página estava vazia",
+"confirmdelete" => "Confirmar deleção",
+"deletesub" => "(Apagando \"$1\")",
+"historywarning" => "Atenção: A página que você quer deletar tem um histórico:",
+"confirmdeletetext" => "Você está prestes a deletar permanentemente uma página ou imagem junto com todo seu histórico do banco de dados.
+Por favor, confirme que você realmente pretende fazer isto, que você compreende as consequências, e que você está fazendo isto em acordo com a [[{{ns:4}}:Policy| Política da {{SITENAME}}]].",
+"actioncomplete" => "Ação efetuada com sucesso",
+"deletedtext" => "\"$1\" foi deletada.
+Veja $2 para um registro de deleções recentes.",
+"deletedarticle" => "apagado \"$1\"",
+"dellogpage" => "Deletion_log",
+"dellogpagetext" => "Segue uma lista das deleções mais recentes.
+Todos os horários mostrados estão no horário do servidor (UTC).
+<ul>
+</ul>",
+"deletionlog" => "registro de deleções",
+"reverted" => "Revertido para versão mais nova",
+"deletecomment" => "Motivo da deleção",
+"imagereverted" => "Reversão para versão mais atual efetuada com sucesso.",
+"rollback" => "Voltar edições",
+"rollbacklink" => "voltar",
+"rollbackfailed" => "Rollback falhou",
+"cantrollback" => "Não foi possível reverter a edição; o último contribuidor é o único autor deste artigo.",
+"alreadyrolled" => "Não foi possível reverter as edições de [[:$1]]
+por [[User:$2|$2]] ([[User talk:$2|discussão]]); alguém o editou ou já o reverteu.
+
+A última edição foi de [[User:$3|$3]] ([[User talk:$3|Conversar com ele]]).",
+# only shown if there is an edit comment
+"editcomment" => "O comentário de edição era: \"<i>$1</i>\".",
+"revertpage" => "Revertido para a última edição por $1",
+
+# Undelete
+"undelete" => "Restaurar páginas deletadas",
+"undeletepage" => "Ver e restaurar páginas deletadas",
+"undeletepagetext" => "As páginas seguintes foram apagadas mas ainda permanecem no bando de dados e podem ser restauradas. O arquivo pode ser limpo periodicamente.",
+"undeletearticle" => "Restaurar artigo deletado",
+"undeleterevisions" => "$1 revisões arquivadas",
+"undeletehistory" => "Se você restaurar uma página, todas as revisões serão restauradas para o histórico.
+Se uma nova página foi criada com o mesmo nome desde a deleção, as revisões restauradas aparecerão primeiro no histórico e a página existente não será automaticamente recolocada.",
+"undeleterevision" => "Revisões deletadas de $1",
+"undeletebtn" => "Restaurar!",
+"undeletedarticle" => " \"$1\" restaurado",
+
+# Contributions
+#
+"contributions" => "Contribuições de usuários",
+"mycontris" => "Minhas contribuições",
+"contribsub" => "Para $1",
+"nocontribs" => "Não foram encontradas mudanças com este critério.",
+"ucnote" => "Segue as últimas <b>$1</b> mudanças nos últimos <b>$2</b> dias do usuário.",
+"uclinks" => "Ver as últimas $1 mudanças; ver os últimos $2 dias.",
+"uctop" => " (topo)" ,
+
+# What links here
+#
+"whatlinkshere" => "Artigos Relacionado",
+"notargettitle" => "Sem alvo",
+"notargettext" => "Você não especificou um alvo ou usuário para performar esta função.",
+"linklistsub" => "(Lista de links)",
+"linkshere" => "Os seguintes artigos contém links que apontam para cá:",
+/*"nolinkshere" => "Nenhuma página relaciona-se � esta.",*/
+"isredirect" => "página de redirecionamento",
+
+# Block/unblock IP
+#
+"blockip" => "Bloquear endereço de IP",
+/*"blockiptext" => "Utilize o formulário de e-mail � seguir para bloquear o acesso a escrita de um endereço específico de IP.
+Isto só pode ser feito para previnir vandalismo , e em acordo com a [[{{ns:4}}:Policy|política da {{SITENAME}}]].
+Preencha com um motivo específico (por exemplo, citando páginas que sofreram vandalismo).",*/
+"ipaddress" => "Endereço de IP",
+"ipbreason" => "Motivo",
+"ipbsubmit" => "Bloquear este endereço",
+"badipaddress" => "O endereço de IP está mal-formado.",
+"blockipsuccesssub" => "Bloqueio bem sucedido",
+"blockipsuccesstext" => "O endereço de IP \"$1\" Foi bloqueado.
+<br />Veja [[Special:Ipblocklist|Lista de IP's bloqueados]] para rever os bloqueios.",
+"unblockip" => "Desbloquear endereço de IP",
+"unblockiptext" => "Utilize o formulário a seguir para restaurar o acesso a escrita para um endereço de IP previamente bloqueado.",
+"ipusubmit" => "Desbloquear este endereço",
+"ipblocklist" => "Lista de IP's bloqueados",
+"blocklistline" => "$1, $2 bloqueado $3 ($4)",
+"blocklink" => "block",
+"unblocklink" => "unblock",
+"contribslink" => "contribs",
+
+# Developer tools
+#
+"lockdb" => "Trancar Banco de Dados",
+"unlockdb" => "Destrancar Banco de Dados",
+"lockdbtext" => "Trancar o banco de dados suspenderá a habilidade de todos os usuários de editarem páginas, mudarem suas preferências, listas de monitoramento e outras coisas que requerem mudanças no banco de dados.
+Por favor confirme que você realmente pretende fazer isto, e que você vai desbloquear o banco de dados quando sua manutenção estiver completa.",
+"unlockdbtext" => "Desbloquear o banco de dados vai restaurar a habilidade de todos os usuários de editar artigos, mudar suas preferências, editar suas listas de monitoramento e outras coisas que requerem mudanças no banco de dados. Por favor, confirme que você realmente pretende fazer isto.",
+"lockconfirm" => "SIM, eu realmente pretendo trancar o banco de dados.",
+"unlockconfirm" => "SIM, eu realmente pretendo destrancar o banco de dados.",
+"lockbtn" => "Trancar banco",
+"unlockbtn" => "Destrancar banco",
+"locknoconfirm" => "Você não checou a caixa de confirmação.",
+"lockdbsuccesssub" => "Tranca bem sucedida",
+"unlockdbsuccesssub" => "Destranca bem sucedida",
+"lockdbsuccesstext" => "O banco de dados da {{SITENAME}} foi trancado.
+<br />Lembre-se de remover a tranca após a manutenção.",
+"unlockdbsuccesstext" => "O bando de dados da {{SITENAME}} foi destrancado.",
+
+# Move page
+#
+"movepage" => "Mover página",
+"movepagetext" => "Usando o formulário a seguir você poderá renomear uma página, movendo todo o histórico para o novo nome.
+O título antigo será transformado num redirecionamento para o novo título.
+Links para as páginas antigas não serão mudados; certifique-se de checar redirecionamentos quebrados ou artigos duplos.
+Você é responsável por certificar-se que os links continuam apontando para onde eles deveriam apontar.
+
+Note que a página '''não''' será movida se já existe uma página com o novo título, a não ser que ele esteja vazio ou seja um redirecionamento e não tenha histórico de edições. Isto significa que você pode renomear uma págna de volta para o nome que era antigamente se você cometer algum enganoe você não pode sobrescrever uma página.
+
+<b>!!!CUIDADO!!!</b>
+Isto pode ser uma mudança drástica e inexperada para uma página popular;
+por favor tenha certeza de que compreende as consequencias disto antes de proceder.",
+"movepagetalktext" => "A página associada, se existir, será automaticamente movida, '''a não ser que:'''
+*Você esteja movendo uma página estre namespaces,
+*Uma página talk (não-vazia) já exista sob o novo nome, ou
+*Você não marque a caixa abaixo.
+
+Nestes casos, você terá que mover ou mesclar a página manualmente se desejar .",
+"movearticle" => "Mover página",
+"movenologin" => "Não Autenticado",
+"movenologintext" => "Você deve ser um usuário registrado e [[Special:Userlogin|autenticado]]
+para mover uma página.",
+"newtitle" => "Pata novo título",
+"movepagebtn" => "Mover página",
+"pagemovedsub" => "Moção bem sucedida",
+"pagemovedtext" => "Página \"[[$1]]\" movida para \"[[$2]]\".",
+"articleexists" => "Uma página com este nome já existe, ou o nome que você escolheu é inválido.
+Por favor, escolha outro nome.",
+"talkexists" => "A página em si foi movida com sucesso, porém a página de discussão não pode ser movida por que já existe uma com este nome. Por favor, mescle-as manualmente.",
+"movedto" => "movido para",
+"movetalk" => "Mover página de discussão também, se aplicável.",
+"talkpagemoved" => "A página de discussão correspondente foi movida com sucesso.",
+"talkpagenotmoved" => "A página de discussão correspondente <strong>não</strong> foi movida.",
+# Math
+'mw_math_png' => "Sempre renderizar PNG",
+'mw_math_simple' => "HTML se for bem simples e PNG",
+'mw_math_html' => "HTML se possível ou então PNG",
+'mw_math_source' => "Deixar como TeX (para navegadores em modo texto)",
+'mw_math_modern' => "Recomendado para navegadores modernos",
+'mw_math_mathml' => 'MathML',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesQu.php b/languages/messages/MessagesQu.php
new file mode 100644
index 000000000000..c3bcbf95afc5
--- /dev/null
+++ b/languages/messages/MessagesQu.php
@@ -0,0 +1,9 @@
+<?php
+/** Quechua (Runa Simi)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'es';
+?>
diff --git a/languages/messages/MessagesRmy.php b/languages/messages/MessagesRmy.php
new file mode 100644
index 000000000000..e290296164e2
--- /dev/null
+++ b/languages/messages/MessagesRmy.php
@@ -0,0 +1,337 @@
+<?php
+/**
+ * Vlax Romany (Romani)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Niklas Laxström
+ */
+
+/**
+ * Use Romanian as default instead of English
+ */
+$fallback = 'ro';
+
+$namespaceNames = array(
+ NS_MEDIA => 'Mediya',
+ NS_SPECIAL => 'Uzalutno',
+ NS_MAIN => '',
+ NS_TALK => 'Vakyarimata',
+ NS_USER => 'Jeno',
+ NS_USER_TALK => 'Jeno_vakyarimata',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '{{grammar:genitive-pl|$1}}_vakyarimata',
+ NS_IMAGE => 'Chitro',
+ NS_IMAGE_TALK => 'Chitro_vakyarimata',
+ NS_MEDIAWIKI => 'MediyaViki',
+ NS_MEDIAWIKI_TALK => 'MediyaViki_vakyarimata',
+ NS_TEMPLATE => 'Sikavno',
+ NS_TEMPLATE_TALK => 'Sikavno_vakyarimata',
+ NS_HELP => 'Zhutipen',
+ NS_HELP_TALK => 'Zhutipen_vakyarimata',
+ NS_CATEGORY => 'Shopni',
+ NS_CATEGORY_TALK => 'Shopni_vakyarimata'
+);
+
+$messages = array(
+'subcategories' => 'Telekategoriye',
+'mainpage' => 'Sherutni patrin',
+'portal' => 'Maladipnasko than',
+'portal-url' => 'Project:Maladipnasko than',
+'about' => 'Andar',
+'aboutsite' => 'Andar {{SITENAME}}',
+'aboutpage' => 'Project:Andar',
+'article' => 'Lekh',
+'help' => 'Zhutipen',
+'helppage' => 'Project:Źutipen',
+'sitesupport' => 'Denimata',
+'edithelp' => 'Editisaripnasko zhutipen',
+'newwindow' => '(inklel aver filiyastra)',
+'edithelppage' => 'Project:Sar te editisares ek patrin',
+'cancel' => 'Mekh la',
+'qbedit' => 'Editisar',
+'qbpageinfo' => 'Patrinyake janglimata',
+'qbspecialpages' => 'Uzalutne patrya',
+'mypage' => 'Miri patrin',
+'mytalk' => 'Mire vakyarimata',
+'navigation' => 'Phirimos',
+'errorpagetitle' => 'Dosh',
+'returnto' => 'Ja palpale kai $1.',
+'search' => 'Rod',
+'searchbutton' => 'Rod',
+'go' => 'Ja',
+'searcharticle' => 'Ja',
+'history' => 'Puraneder versiye',
+'history_short' => 'Puranipen',
+'printableversion' => 'Printisaripnaski versiya',
+'permalink' => 'Savaxtutno phandipen',
+'print' => 'Printisaripen',
+'edit' => 'Editisar i patrin',
+'editthispage' => 'Editisar i patrin',
+'deletethispage' => 'Khos i patrin',
+'newpage' => 'Nevi patrin',
+'specialpage' => 'Uzalutni patrin',
+'articlepage' => 'Dikh o lekh',
+'talk' => 'Vakyarimata',
+'toolbox' => 'Labnengo moxton',
+'userpage' => 'Dikh i jeneski patrin',
+'viewtalkpage' => 'Dikh i diskucia',
+'otherlanguages' => 'Avre ćhibande',
+'lastmodifiedat' => 'O palutno paruvipen $2, $1.',
+'jumpto' => 'Ja kai:',
+'retrievedfrom' => 'Lino katar "$1"',
+'editsection' => 'editisar',
+'editsectionhint' => 'Editisar o kotor: $1',
+'toc' => 'Ander',
+'showtoc' => 'dikh',
+'hidetoc' => 'garav',
+'nstab-main' => 'Lekh',
+'nstab-user' => 'Jeneski patrin',
+'nstab-media' => 'Mediya patrin',
+'nstab-special' => 'Uzalutno',
+'nstab-image' => 'Chitro',
+'nstab-template' => 'Sikavno',
+'nstab-help' => 'Zhutipen',
+'nstab-category' => 'Kategoriya',
+'wrong_wfQuery_params' => 'Doshalo gin le parametrengo ko wfQuery()<br />I function: $1<br />Query: $2',
+'viewsource' => 'Dikh i sursa',
+'loginpagetitle' => 'Jenesko prinjaripen',
+'yourname' => 'Tiro anav',
+'yourpassword' => 'O nakhavipnasko lav',
+'yourpasswordagain' => 'O nakhavipnasko lav de nevo',
+'loginproblem' => '<b>Sas ek problem le tire prinjaripnaski</b><br />Ker les de nevo!',
+'login' => 'Prinjaripen',
+'userlogin' => 'Prinjaripen / Ker ek akount',
+'userlogout' => 'De avri',
+'nologinlink' => 'Ker ek akount',
+'createaccount' => 'Ker ek nevo akount',
+'youremail' => 'Emailesko adress (kana kames)*',
+'yourrealname' => 'Tiro chacho anav*',
+'yourlanguage' => 'Ćhib:',
+'yournick' => 'I xarni versyunya, le semnaturenge',
+'loginerror' => 'Prinjaripnaski dosh',
+'wrongpassword' => 'O nakhavipnasko lav so thovdyan si doshalo. Mangas tuke te zumaves vi ekvar.',
+'mailmypassword' => 'Bićhal ma o nakhavipnasko lav e-mail-estar!',
+'passwordremindertext' => 'Varekon (shai te aves tu, katar i adresa $1)
+manglyas ek nevo nakahvipnasko lav katar {{SITENAME}}.
+O nakhavipnasko lav le jenesko "$2" akana si "$3".
+Mishto si te jas kai {{SITENAME}} thai te paruves tiro lav sigo.',
+'acct_creation_throttle_hit'=> 'Fal ame nasul, akana si tut $1 akounturya. Nashti te keres aver.',
+'accountcreated' => 'Akount kerdo',
+'image_sample' => 'Misal.jpg',
+'summary' => 'Xarno xalyaripen',
+'minoredit' => 'Kadava si ek tikno editisarimos',
+'watchthis' => 'Dikh kadaya patrin',
+'savearticle' => 'Uxtav i patrin',
+'showpreview' => 'Dikh sar avelas i patrin',
+'showdiff' => 'Dikh le paruvimata',
+'whitelistedittitle' => 'Trebul o [[Special:Userlogin|autentifikaripen]] kashte editisares',
+'whitelistedittext' => 'Trebul te [[Special:Userlogin|autentifikisares]] kashte editisares artikolurya.',
+'whitelistreadtitle' => 'Trebul o autentifikaripen kashte drabares',
+'whitelistreadtext' => 'Trebul te [[Special:Userlogin|autentifikisares]] kashte drabares artikolurya.',
+'whitelistacctitle' => 'Chi shai (nai tuke xakaya) te keres konturya',
+'accmailtitle' => 'O nakhavipnasko lav bićhaldo.',
+'accmailtext' => 'O nakhavipnasko lav andar \'$1\' bićhaldo ko $2.',
+'newarticle' => '(Nevo)',
+'newarticletext' => 'Avilyan kai ek patrin so na si.
+Te keres la, shai te shirdes (astares) te lekhaves ando telutno moxton (dikh [[Project:Źutipen|zhutipnaski patrin]] te janes buteder).
+Kana avilyan kathe doshatar, ja palpale.',
+'noarticletext' => 'Andi \'\'\'{{SITENAME}}\'\'\' nai ji akana ek lekh kadale anavesa.
+* Te shirdes (astares) te keres o lekh, ker klik \'\'\'[{{fullurl:{{FULLPAGENAME}}|action=edit}} kathe]\'\'\'.',
+'editing' => 'Editisaripen $1',
+'editinguser' => 'Editisaripen $1',
+'yourtext' => 'Tiro teksto',
+'storedversion' => 'Akanutni versiya',
+'yourdiff' => 'Ververimata',
+'revhistory' => 'puranipen le versiyango',
+'revnotfoundtext' => 'I puraneder versiya la patrinyaki so tu manglyan na arakhel pes. Mangas tuke te palemdikhes o phandipen so labyardyan kana avilyan kathe.',
+'loadhist' => 'Ladavav o puranipen le versiyango',
+'previousrevision' => '← Purano paruvipen',
+'nextrevision' => 'Nevi paruvipen →',
+'cur' => 'akanutni',
+'last' => 'purani',
+'histlegend' => 'Xalyaripen: (akanutni) = ververimata mamui i akanutni versiya,
+(purani) = ververimata mamui i puraneder versiya, T = tikno editisaripen',
+'deletedrev' => '[khoslo]',
+'histfirst' => 'O mai purano',
+'histlast' => 'O mai nevo',
+'compareselectedversions'=> 'Dikh ververimata mashkar alosarde versiye',
+'prevn' => 'mai neve $1',
+'nextn' => 'mai purane $1',
+'viewprevnext' => 'Dikh ($1) ($2) ($3).',
+'showingresults' => 'Tele si <b>$1</b> rezultaturya shirdindoi le ginestar <b>$2</b>.',
+'showingresultsnum' => 'Tele si <b>$3</b> rezultaturya shirdindoi le ginestar <b>$2</b>.',
+'powersearch' => 'Rod',
+'preferences' => 'Kamimata',
+'changepassword' => 'Paruv o nakhavipnasko lav',
+'skin' => 'Dikhimos',
+'prefs-rc' => 'Neve paruvimata',
+'localtime' => 'Thanutno vaxt',
+'timezoneoffset' => 'Ververipen',
+'changes' => 'paruvimata',
+'recentchanges' => 'Neve paruvimata',
+'recentchangestext' => 'Andi kadaya patrin shai te dikhes le neve paruvimata andi romani {{SITENAME}}.
+
+[[Project:Mishto avilyan|Mishto avilyan ki {{SITENAME}}]]! Shai te dikhes vi le [[lekh]]a so xalyaren sar jal i {{SITENAME}}: [[{{ns:Project}}:Butvarutne pućhimata|butvarutne pućhimata]], [[Project:Forovipen (politika)|forovipen (politika) la {{SITENAME}}ko]] thai o [[Project:Birigyardo jalipen|birigyardo jalipen]].
+But importanto si te na bićhales butya brakhle (arakhle) katar le [[Project:Autorenge xakaya (chachimata)|autorenge xakaya (chachimata)]]. Si te na kerel khonik kadya kashte na avel problemurya ando kado proyekto.',
+'rcnote' => 'Tele si le palutne <strong>$1</strong> paruvimata andar le palutne <strong>$2</strong> divesa.',
+'rclistfrom' => 'Dikh le paruvimata ji kai $1',
+'rclinks' => 'Dikh le palutne $1 paruvimata andar le palutne $2 divesa.<br />$3',
+'diff' => 'ververipen',
+'hist' => 'puranipen',
+'hide' => 'garav',
+'show' => 'dikh',
+'minoreditletter' => 't',
+'upload' => 'Bićhal file',
+'uploadbtn' => 'Bićhal file',
+'filedesc' => 'Xarno xalyaripen',
+'copyrightpage' => 'Project:Autorenge xakaya (chachimata)',
+'badfilename' => 'O chitrosko anav sas paruvdo; o nevo anav si "$1".',
+'imagelist' => 'Patrinipen le chitrengo',
+'imagelistforuser' => 'Kathe si numa le chitre ladavde katar $1.',
+'ilsubmit' => 'Rod',
+'imgdelete' => 'khos',
+'imghistory' => 'Chitrosko puranipen',
+'deleteimg' => 'khosav',
+'deleteimgcompletely' => 'khosav',
+'imagelinks' => 'Chitroske phandimata',
+'unusedtemplates' => 'Bilabyarde sikavne',
+'unusedtemplateswlh' => 'aver phandimata',
+'statistics' => 'Beshimata',
+'sitestats' => 'Site-ske beshimata',
+'userstatstext' => 'Si <b>$1</b> jene rejistrime (lekhavde).
+Mashkar lende <b>$2</b> si administratorurya (dikh $3).',
+'wantedpages' => 'Kamle pajine',
+'allpages' => 'Savore patrya',
+'shortpages' => 'Xarne patrya',
+'deadendpages' => 'Biphandimatenge patrya',
+'listusers' => 'Jenengo patrinipen',
+'specialpages' => 'Uzalutne patrya',
+'spheading' => 'Uzalutne patrya',
+'recentchangeslinked' => 'Pashvipnaske paruvimata',
+'rclsub' => '(le patrinyanca phandle katar "$1")',
+'newpages' => 'Neve patrya',
+'ancientpages' => 'E puraneder lekha',
+'intl' => 'Phandimata mashkar ćhiba',
+'move' => 'Ingerdipen',
+'nextpage' => 'Anglutni patrin ($1)',
+'allarticles' => 'Sa le artikolurya',
+'allpagessubmit' => 'Ja',
+'emailuser' => 'Bićhal e-mail kodoleske',
+'emailfrom' => 'Katar',
+'emailto' => 'Karing',
+'emailsend' => 'Bićhal',
+'watchlist' => 'Dikhipnaske lekha',
+'addedwatch' => 'Thovdi ando patrinipen le patrinyange so arakhav len',
+'addedwatchtext' => 'I patrin "[[:$1]]" sas thovdi andi tiri lista [[Special:Watchlist|le artikolengi so dikhes len]].
+Le neve paruvimata andar kadale patrya thai andar lenge vakyarimatenge patrya thona kathe, vi dikhena pen le <b>thule semnurenca</b> andi patrin le [[Special:Recentchanges|neve paruvimatenge]].
+
+Kana kamesa te khoses kadaya patrin andar tiri lista le patryange so arakhes len ker click kai "Na mai arakh" (opre, kana i patrin dikhel pes).',
+'removedwatchtext' => 'I patrin "[[:$1]]" sas khosli katar o patrinipen le dikhipnaske lekhenca (artikolurya).',
+'watch' => 'Dikh la',
+'unwatch' => 'Na mai dikh',
+'unwatchthispage' => 'Na mai dikh',
+'wlnote' => 'Tele si le palutne $1 paruvimata ande palutne <b>$2</b> ore.',
+'wlsaved' => 'Kadaya si i uxtavni versiunya la tiri listyaki le dikhAceasta este o versiune salvată a listei tale de pagini urmărite.',
+'enotif_newpagetext' => 'Kadaya si ek nevi patrin.',
+'deletepage' => 'Khos i patrin',
+'excontent' => 'o ander sas: \'$1\'',
+'excontentauthor' => 'o ander sas: \'$1\' (thai o korkoro butyarno sas \'$2\')',
+'exblank' => 'i patrin sas chuchi',
+'deletesub' => '(Khosav "$1")',
+'historywarning' => 'Dikh! La patrya so kames to khoses la si la puranipen:',
+'actioncomplete' => 'Agorisardi buti',
+'deletedtext' => '"$1" sas khosli.
+Dikh ando $2 ek patrinipen le palutne butyange khosle.',
+'deletedarticle' => '"$1" sas khosli.',
+'rollback_short' => 'Palemavilipen',
+'rollbacklink' => 'palemavilipen',
+'rollbackfailed' => 'O palemavilipen nashtisardyas te kerel pes.',
+'contributions' => 'Jeneske butya',
+'mycontris' => 'Mire butya',
+'contribsub' => 'Katar $1',
+'uctop' => ' (opre)',
+'sp-contributions-newest'=> 'O mai nevo',
+'sp-contributions-oldest'=> 'O mai purano',
+'sp-contributions-newer'=> 'Mai neve $1',
+'sp-contributions-older'=> 'Mai purane $1',
+'whatlinkshere' => 'So phandel pes kathe',
+'nolinkshere' => 'Ni ek patrin phandel pes (avel) kathe.',
+'contribslink' => 'butya',
+'rights' => 'Chachimata (xakaya):',
+'movearticle' => 'Inger i patrin',
+'pagemovedsub' => 'I patrin sas bićhaldi.',
+'pagemovedtext' => 'I patrin "[[$1]]" sas bićhaldi karing "[[$2]]".',
+'movedto' => 'ingerdi kai',
+'talkpagemoved' => 'Ingerdi vi i phandli vakyarimatengi patrin.',
+'talkpagenotmoved' => 'I phandli vakyarimatengi patrin <strong>nai</strong> ingerdi.',
+'1movedto2' => '[[$1]] bichhaldo kai [[$2]]',
+'allmessages' => 'Toate mesajele',
+'allmessagesname' => 'Anav',
+'lastmodifiedatby' => 'Kadaya patrin sas paruvdi agoreste $2, $1 katar $3.',
+'and' => 'thai',
+'others' => 'aver',
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Miri labyarneski pajina\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Miri labyarneski pajina ki akanutni IP adress\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Miri diskuciyaki pajina\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskucie le editisarimatenge ki akanutni IP adress\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Sar kamav te dikhel pes miri pajina\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'I lista le pajinenge so dikhav lendar (monitorizav).\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Le mire editisarimata\');
+ta[\'pt-login\'] = new Array(\'o\',\'Mishto si te identifikares tut, pale na si musai.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Mishto si te identifikares tut, pale na si musai.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Kathe aćhaves i sesiyunya\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Diskuciya le artikoleske\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Shai te editisares kadaya pajina. Mangas te paledikhes o teksto anglal te uxtaves les.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Kathe shai te thos ek komentaryo ki kadaya diskuciya.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Kadaya pajina si brakhli. Shai numa te dikhes o source-code.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Purane versiune le dokumenteske.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Brakh kadava dokumento.\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Khos kadava dokumento.\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Palemthav le editisarimata kerdine le kadale dokumenteske sar sas anglal lesko khosipen.\');
+ta[\'ca-move\'] = new Array(\'m\',\'Trade kadava dokumento.\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Nai tuke shayutnipen te trades kadava dokumento.\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Thav kadava dokumento andi monitorizaripnaski lista.\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Khos kadava dokumento andar i monitorizaripnaski lista.\');
+ta[\'search\'] = new Array(\'f\',\'Rod andi kadaya Wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'I sherutni pajina\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Dikh i sherutni pajina\');
+ta[\'n-portal\'] = new Array(\'\',\'O proyekto, so shai te keres, kai arakhes solucie.\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Arakh janglimata le akanutne evenimenturenge\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'I lista le neve paruvimatenge kerdini andi kadaya wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Ja ki ek aleatori pajina\');
+ta[\'n-help\'] = new Array(\'\',\'O than kai arakhes zhutipen.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Zhutisar amen\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'I lista sa le wiki pajinenge so aven (si phande) vi kathe\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Neve paruvimata andi kadaya pajina\');
+ta[\'feed-rss\'] = new Array(\'\',\'Kathe te pravares o RSS flukso le kadale pajinyako\');
+ta[\'feed-atom\'] = new Array(\'\',\'Kathe te pravares o Atom flukso le kadale pajinyako\');
+ta[\'t-contributions\'] = new Array(\'\',\'Dikh i lista le editisarimatenge le kadale labyaresko\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Bićhal ek emailo le kadale labyareske\');
+ta[\'t-upload\'] = new Array(\'u\',\'Bićhal imajine vai media files\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'I lista sa le spechiale pajinengi\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Dikh o artikolo\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Dikh i labyarengi pajina\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Dikh i pajina media\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Kadaya si ek spechiali pajina, nashti te editisares la.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Dikh i pajina le proyekteski\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Dikh i imajinyaki pajina\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Dikh o mesajo le sistemesko\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Dikh o formato\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Dikh i zhutipnaski pajina\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Dikh i kategoriya\');',
+'deletedrevision' => 'Khoslo o purano paruvipen $1.',
+'previousdiff' => '← Purano ververipen',
+'nextdiff' => 'Anglutno paruvipen →',
+'showhidebots' => '($1 boturya)',
+'recentchangesall' => 'sa',
+'imagelistall' => 'savore',
+'watchlistall1' => 'savore',
+'watchlistall2' => 'savore',
+'namespacesall' => 'savore',
+'deletedwhileediting' => 'Dikh: Kadaya patrin sas khosli de kana shirdyas (astardyas) te editisares la!',
+);
+?>
diff --git a/languages/messages/MessagesRo.php b/languages/messages/MessagesRo.php
new file mode 100644
index 000000000000..8387fa46a3e4
--- /dev/null
+++ b/languages/messages/MessagesRo.php
@@ -0,0 +1,1625 @@
+<?php
+/** Romanian (Română)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$quickbarSettings = array(
+ 'Fără', 'Fixă, în stânga', 'Fixă, în dreapta', 'Liberă'
+);
+
+$skinNames = array(
+ 'standard' => 'Normală',
+ 'nostalgia' => 'Nostalgie'
+);
+
+$magicWords = array(
+ # ID CASE SYNONYMS
+ 'redirect' => array( 0, '#redirect' ),
+ 'notoc' => array( 0, '__NOTOC__', '__FARACUPRINS__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__FARAEDITSECTIUNE__' ),
+ 'start' => array( 0, '__START__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', '{{NUMARLUNACURENTA}}' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', '{{NUMELUNACURENTA}}' ),
+ 'currentday' => array( 1, 'CURRENTDAY', '{{NUMARZIUACURENTA}}' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', '{{NUMEZIUACURENTA}}' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', '{{ANULCURENT}}' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', '{{ORACURENTA}}' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', '{{NUMARDEARTICOLE}}' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', '{{NUMELUNACURENTAGEN}}' ),
+ 'subst' => array( 0, 'SUBST:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'MSJNOU:' ),
+ 'end' => array( 0, '__END__', '__FINAL__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' ),
+ 'img_right' => array( 1, 'right' ),
+ 'img_left' => array( 1, 'left' ),
+ 'img_none' => array( 1, 'none' ),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre' ),
+ 'int' => array( 0, 'INT:' )
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Discuţie',
+ NS_USER => 'Utilizator',
+ NS_USER_TALK => 'Discuţie_Utilizator',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discuţie_$1',
+ NS_IMAGE => 'Imagine',
+ NS_IMAGE_TALK => 'Discuţie_Imagine',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discuţie_MediaWiki',
+ NS_TEMPLATE => 'Format',
+ NS_TEMPLATE_TALK => 'Discuţie_Format',
+ NS_HELP => 'Ajutor',
+ NS_HELP_TALK => 'Discuţie_Ajutor',
+ NS_CATEGORY => 'Categorie',
+ NS_CATEGORY_TALK => 'Discuţie_Categorie'
+);
+
+$datePreferences = false;
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F Y',
+ 'dmy both' => 'j F Y H:i',
+);
+
+$fallback8bitEncoding = 'iso8859-2';
+
+
+
+$messages = array(
+'tog-underline' => 'Subliniază legăturile',
+'tog-highlightbroken' => 'Formatează legăturile necreate <a href="" class="new">aşa</a> (alternativă: aşa<a href="" class="internal">?</a>).',
+'tog-justify' => 'Aranjează justificat paragrafele',
+'tog-hideminor' => 'Ascunde modificările minore în schimbări recente',
+'tog-extendwatchlist' => 'Extinde lista de articole urmărite pentru a arăta toate schimbările făcute',
+'tog-usenewrc' => 'Schimbări recente avansate (JavaScript)',
+'tog-numberheadings' => 'Numerotează automat secţiunile',
+'tog-showtoolbar' => 'Afişează bara de unelte pentru modificare (JavaScript)',
+'tog-editondblclick' => 'Modifică pagini la dublu clic (JavaScript)',
+'tog-editsection' => 'Activează modificarea secţiunilor prin legăturile [modifică]',
+'tog-editsectiononrightclick'=> 'Activează modificarea secţiunilor prin clic dreapta<br />
+pe titlul secţiunii (JavaScript)',
+'tog-showtoc' => 'Arată cuprinsul (pentru paginile cu mai mult de 3 paragrafe cu titlu)',
+'tog-rememberpassword' => 'Aminteşte-ţi între sesiuni',
+'tog-editwidth' => 'Căsuţa de modificare are lăţime maximă',
+'tog-watchcreations' => 'Adaugă paginile create de mine pe lista de urmărire',
+'tog-watchdefault' => 'Adaugă paginile pe care le modifici la lista ta de urmărire',
+'tog-minordefault' => 'Marchează toate modificările minore din oficiu',
+'tog-previewontop' => 'Arată previzualizarea înainte de a modifica secţiunea',
+'tog-previewonfirst' => 'Arată previzualizarea la prima modificare',
+'tog-nocache' => 'Dezactivează cache-ul paginilor',
+'tog-enotifwatchlistpages'=> 'Trimite-mi un email la modificările paginilor',
+'tog-enotifusertalkpages'=> 'Trimite-mi un email când pagina mea de discuţii este modificată',
+'tog-enotifminoredits' => 'Trimite-mi un email de asemenea pentru modificările minore ale paginilor',
+'tog-enotifrevealaddr' => 'Descoperă-mi adresa email în mesajele de notificare',
+'tog-shownumberswatching'=> 'Arată numărul utilizatorilor care urmăresc',
+'tog-fancysig' => 'Semnătură brută (fără legătură automată)',
+'tog-externaleditor' => 'Utilizează modificator extern ca standard',
+'tog-externaldiff' => 'Utilizează diferenţele externe ca standard',
+'tog-showjumplinks' => 'Activează legăturile de accesibilitate "salt la"',
+'tog-uselivepreview' => 'Utilizează previzualizarea live (JavaScript) (Experimental)',
+'tog-autopatrol' => 'Marchează modificările mele ca patrulate',
+'tog-forceeditsummary' => 'Avertizează-mă când uit să descriu modificările',
+'tog-watchlisthideown' => 'Ascunde modificările mele de pe lista de articole urmărite',
+'tog-watchlisthidebots' => 'Ascunde modificările boţilor de pe lista de articole urmărite',
+'underline-always' => 'Întotdeauna',
+'underline-never' => 'Niciodată',
+'underline-default' => 'Standardul browser-ului',
+'skinpreview' => '(Previzualizare)',
+'sunday' => 'duminică',
+'monday' => 'luni',
+'tuesday' => 'marţi',
+'wednesday' => 'miercuri',
+'thursday' => 'joi',
+'friday' => 'vineri',
+'saturday' => 'sâmbătă',
+'january' => 'ianuarie',
+'february' => 'februarie',
+'march' => 'martie',
+'april' => 'aprilie',
+'may_long' => 'mai',
+'june' => 'iunie',
+'july' => 'iulie',
+'august' => 'august',
+'september' => 'septembrie',
+'october' => 'octombrie',
+'november' => 'noiembrie',
+'december' => 'decembrie',
+'jan' => 'ian',
+'feb' => 'feb',
+'mar' => 'mart',
+'apr' => 'apr',
+'may' => 'mai',
+'jun' => 'iun',
+'jul' => 'iul',
+'aug' => 'aug',
+'sep' => 'sept',
+'oct' => 'oct',
+'nov' => 'nov',
+'dec' => 'dec',
+'categories' => 'Categorii',
+'pagecategories' => '{{PLURAL:$1|Categorie|Categorii}}',
+'category_header' => 'Articole din categoria "$1"',
+'subcategories' => 'Subcategorii',
+'mainpage' => 'Pagina principală',
+'mainpagetext' => '<big>\'\'\'Programul Wiki a fost instalat cu succes.\'\'\'</big>',
+'mainpagedocfooter' => 'Vezi [http://meta.wikimedia.org/wiki/MediaWiki_i18n documentaţia asupra adaptării interfeţei] şi [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Ghidul de utilizator] pentru ajutor la utilizare şi configurare.',
+'portal' => 'Portalul comunităţii',
+'portal-url' => 'Project:Portal Comunitate',
+'about' => 'Despre',
+'aboutsite' => 'Despre {{SITENAME}}',
+'aboutpage' => 'Project:Despre',
+'article' => 'Articol',
+'help' => 'Ajutor',
+'helppage' => 'Project:Ajutor',
+'bugreports' => 'Raportare probleme',
+'bugreportspage' => 'Project:Rapoarte probleme',
+'sitesupport' => 'Donaţii',
+'sitesupport-url' => 'Project:Donaţii',
+'faq' => 'Întrebări frecvente',
+'faqpage' => 'Project:Întrebări frecvente',
+'edithelp' => 'Ajutor pentru modificare',
+'newwindow' => '(se deschide într-o fereastră nouă)',
+'edithelppage' => 'Project:Cum să modifici o pagină',
+'cancel' => 'Renunţă',
+'qbfind' => 'Găseşte<br />
+<small>Diacritice: ă â î ş ţ</small>',
+'qbbrowse' => 'Răsfoieşte',
+'qbedit' => 'Modifică',
+'qbpageoptions' => 'Opţiuni ale paginii',
+'qbpageinfo' => 'Informaţii ale paginii',
+'qbmyoptions' => 'Opţiunile mele',
+'qbspecialpages' => 'Pagini speciale',
+'moredotdotdot' => 'Altele...',
+'mypage' => 'Pagina mea',
+'mytalk' => 'Discuţiile mele',
+'anontalk' => 'Discuţia pentru această adresă IP',
+'navigation' => 'Navigare',
+'metadata_help' => 'Metadata (vezi [[Project:Metadata]] pentru o explicaţie):',
+'currentevents' => 'Discută la cafenea',
+'currentevents-url' => 'Project:Cafenea',
+'disclaimers' => 'Termeni',
+'disclaimerpage' => 'Project:Termeni',
+'privacy' => 'Politica de confidenţialitate',
+'privacypage' => 'Project:Politica de confidenţialitate',
+'errorpagetitle' => 'Eroare',
+'returnto' => 'Înapoi la $1.',
+'tagline' => 'De la {{SITENAME}}',
+'search' => 'Caută',
+'searchbutton' => 'Caută',
+'go' => 'Du-te',
+'searcharticle' => 'Du-te',
+'history' => 'Versiuni mai vechi',
+'history_short' => 'istoric',
+'updatedmarker' => 'încărcat de la ultima mea vizită',
+'info_short' => 'Informaţii',
+'printableversion' => 'Versiune de tipărit',
+'permalink' => 'Legătură permanentă',
+'print' => 'Tipărire',
+'edit' => 'Editează pagina',
+'editthispage' => 'Modifică pagina',
+'delete' => 'Ştergere',
+'deletethispage' => 'Şterge pagina',
+'undelete_short' => 'Recuperarea editărilor $1',
+'protect' => 'Protejare',
+'protectthispage' => 'Protejează pagina',
+'unprotect' => 'Deprotejare',
+'unprotectthispage' => 'Deprotejează pagina',
+'newpage' => 'Pagină nouă',
+'talkpage' => 'Discută pagina',
+'specialpage' => 'Pagină Specială',
+'personaltools' => 'Unelte personale',
+'postcomment' => 'Adaugă un comentariu',
+'articlepage' => 'Vezi articolul',
+'talk' => 'Discuţie',
+'views' => 'Vizualizări',
+'toolbox' => 'Trusa de unelte',
+'userpage' => 'Vezi pagina utilizatorului',
+'projectpage' => 'Vezi pagina proiectului',
+'imagepage' => 'Vezi pagina imaginii',
+'viewtalkpage' => 'Vezi discuţia',
+'otherlanguages' => 'În alte limbi',
+'redirectedfrom' => '(Redirecţionat de la $1)',
+'autoredircomment' => 'Redirecţionat înspre [[$1]]',
+'redirectpagesub' => 'Pagină de redirecţionare',
+'lastmodifiedat' => 'Ultima modificare $2, $1.',
+'viewcount' => 'Această pagină a fost vizitată {{PLURAL:$1|odată|de $1 ori}}.',
+'copyright' => 'Conţinutul este disponibil sub $1.',
+'protectedpage' => 'Pagină protejată',
+'jumpto' => 'Salt la:',
+'jumptonavigation' => 'Navigare',
+'jumptosearch' => 'căutare',
+'badaccess' => 'Eroare permisiune',
+'versionrequired' => 'Este necesară versiunea $1 MediaWiki',
+'versionrequiredtext' => 'Versiunea $1 MediaWiki este necesară pentru a folosi această pagină. Vezi [[Special:Version|versiunea actuală]].',
+'ok' => 'Trimite',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Adus de la "$1"',
+'youhavenewmessages' => 'Aveţi $1 ($2).',
+'newmessageslink' => 'mesaje noi',
+'newmessagesdifflink' => 'comparaţie cu versiunea precedentă',
+'editsection' => 'editează',
+'editold' => 'editează',
+'editsectionhint' => 'Editează secţiunea: $1',
+'toc' => 'Cuprins',
+'showtoc' => 'arată',
+'hidetoc' => 'ascunde',
+'thisisdeleted' => 'Vizualizare sau recuperare $1?',
+'viewdeleted' => 'Vizualizează $1?',
+'restorelink' => '{{PLURAL:$1|o modificare ştearsă|$1 modificări şterse}}',
+'feedlinks' => 'Întreţinere:',
+'feed-invalid' => 'Tip de abonament invalid',
+'nstab-main' => 'Articol',
+'nstab-user' => 'Pagină de utilizator',
+'nstab-media' => 'Pagină Media',
+'nstab-special' => 'Special',
+'nstab-project' => 'Proiect',
+'nstab-image' => 'Fişier',
+'nstab-mediawiki' => 'Mesaj',
+'nstab-template' => 'Format',
+'nstab-help' => 'Ajutor',
+'nstab-category' => 'Categorie',
+'nosuchaction' => 'Această acţiune nu există',
+'nosuchactiontext' => 'Acţiunea specificată în adresă nu este recunoscută de {{SITENAME}}.',
+'nosuchspecialpage' => 'Această pagină specială nu există',
+'nospecialpagetext' => 'Ai cerut o [[Special:Specialpages|pagină specială]] care nu este recunoscută de {{SITENAME}}.',
+'error' => 'Eroare',
+'databaseerror' => 'Eroare la baza de date',
+'dberrortext' => 'A apărut o eroare în execuţia query-ului. Aceasta se poate datora unui query ilegal (vezi $5), sau poate indica o problemă în program. Ultimul query încercat a fost: <blockquote><tt>$1</tt></blockquote> în cadrul funcţiei "<tt>$2</tt>". MySQL a returnat eroarea "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'A apărut o eroare de sintaxă în query. Ultimul query încercat a fost: "$1" din funcţia "$2". MySQL a returnat eroarea "$3: $4".',
+'noconnect' => 'Nu s-a putut conecta baza de date pe $1',
+'nodb' => 'Nu s-a putut selecta baza de date $1',
+'cachederror' => 'Aceasta este o versiune din cache a paginii cerute şi este posibil să nu fie ultima variantă a acesteia.',
+'laggedslavemode' => 'Atenţie: S-ar putea ca pagina să nu conţină ultimele actualizări.',
+'readonly' => 'Baza de date este blocată la scriere',
+'enterlockreason' => 'Precizează motivul pentru blocare, incluzând o estimare a termenului de deblocare a bazei de date',
+'readonlytext' => 'Baza de date {{SITENAME}} este momentan blocată la scriere, probabil pentru o operaţiune de rutină, după care va fi deblocată şi se va reveni la starea normală.
+
+Administratorul care a blocat-o a oferit această explicaţie: $1',
+'missingarticle' => 'Textul "$1" nu a putut fi găsit în baza de date, aşa cum ar fi trebuit. Aceasta nu este o problemă legată de programul care gestionează baza de date, ci probabil o problemă în programul care administrează {{SITENAME}}. Te rugăm să raportezi această problemă unui administrator, incluzând şi adresa acestei pagini.',
+'readonly_lag' => 'Baza de date a fost închisă automatic în timp ce serverele secundare ale bazei de date îl urmează pe cel principal.',
+'internalerror' => 'Eroare internă',
+'filecopyerror' => 'Fişierul "$1" nu a putut fi copiat la "$2".',
+'filerenameerror' => 'Fişierul "$1" nu a putut fi mutat la "$2".',
+'filedeleteerror' => 'Fişierul "$1" nu a putut fi şters.',
+'filenotfound' => 'Fişierul "$1" nu a putut fi găsit.',
+'unexpected' => 'Valoare neaşteptată: "$1"="$2".',
+'formerror' => 'Eroare: datele nu au putut fi trimise',
+'badarticleerror' => 'Această acţiune nu poate fi efectuată pe această pagină.',
+'cannotdelete' => 'Comanda de ştergere nu s-a putut executa! Probabil că ştergerea a fost operată între timp.',
+'badtitle' => 'Titlu invalid',
+'badtitletext' => 'Titlul căutat a fost invalid, gol sau o legătură invalidă inter-linguală sau inter-wiki.',
+'perfdisabled' => 'Ne pare rău! Această opţiune a fost dezactivată temporar în timpul orelor de vârf din motive de performanţă. Te rugăm să revii la altă oră şi să încerci din nou.',
+'perfdisabledsub' => 'Iată o copie salvată de la $1:',
+'perfcached' => 'Datele următoare au fost păstrate în cache şi s-ar putea să nu fie la zi.',
+'perfcachedts' => 'Informaţiile de mai jos provin din \'\'cache\'\'; ultima actualizare s-a efectuat la $1.',
+'wrong_wfQuery_params' => 'Număr incorect de parametri pentru wfQuery()<br />
+Funcţia: $1<br />
+Interogarea: $2',
+'viewsource' => 'Vezi sursa',
+'viewsourcefor' => 'pentru $1',
+'protectedtext' => 'Această pagină a fost protejată la modificare; există mai multe motive posibile pentru aceasta, vezi [[Project:Pagină protejată|Pagină protejată]]. Poţi vedea şi copia sursa acestei pagini:',
+'protectedinterface' => 'Această pagină asigură textul interfeţei pentru software şi este protejată pentru a preveni abuzurile.',
+'editinginterface' => '\'\'\'Avertizare\'\'\': Editezi o pagină care este folosită pentru a furniza textul interfeţei pentru software. Modificările aduse acestei pagini vor afecta aspectul interfeţei utilizatorului pentru alţi utilizatori.',
+'sqlhidden' => '(interogare SQL ascunsă)',
+'logouttitle' => 'Sesiune închisă',
+'logouttext' => 'Sesiunea ta în {{SITENAME}} a fost închisă. Poţi continua să foloseşti {{SITENAME}} anonim, sau poţi să te reautentifici ca acelaşi sau ca alt utilizator.',
+'welcomecreation' => '<h2>Bun venit, $1!</h2><p>A fost creat un cont pentru tine
+Nu uita să-ţi personalizezi preferinţele în {{SITENAME}}.',
+'loginpagetitle' => 'Autentificare utilizator',
+'yourname' => 'Numele de utilizator',
+'yourpassword' => 'Parola',
+'yourpasswordagain' => 'Repetă parola',
+'remembermypassword' => 'Reţine-mi parola între sesiuni',
+'yourdomainname' => 'Domeniul tău',
+'externaldberror' => 'A fost fie o eroare de bază de date pentru o autentificare extenă sau nu aveţi permisiunea să actualizaţi contul extern.',
+'loginproblem' => '<b>A apărut o problemă la autentificarea ta.</b><br />
+Încearcă din nou!',
+'alreadyloggedin' => '<strong>Sunteţi deja autentificat ca $1!</strong><br />',
+'login' => 'Autentificare',
+'loginprompt' => 'Trebuie să ai modulele cookie activate pentru a te autentifica la {{SITENAME}}.',
+'userlogin' => 'Creare cont / Autentificare',
+'logout' => 'Închide sesiunea',
+'userlogout' => 'Închide sesiunea',
+'notloggedin' => 'Nu sunteţi autentificat',
+'nologin' => 'Nu aveţi cont încă? $1.',
+'nologinlink' => 'Creaţi-vă un cont de utilizator acum',
+'createaccount' => 'Creare cont',
+'gotaccount' => 'Aveţi deja un cont de utilizator? $1.',
+'gotaccountlink' => 'Autentificaţi-vă',
+'createaccountmail' => 'după e-mail',
+'badretype' => 'Parolele pe care le-ai introdus diferă.',
+'userexists' => 'Numele de utilizator pe care l-aţi introdus există deja. Încercaţi cu un alt nume.',
+'youremail' => 'Adresa de e-mail (opţional)*',
+'username' => 'Nume de utilizator:',
+'uid' => 'ID utilizator:',
+'yourrealname' => 'Numele dvs. real*',
+'yourlanguage' => 'Limbă interfaţă',
+'yourvariant' => 'Varianta',
+'yournick' => 'Versiune scurtă a numelui, pentru semnături',
+'badsig' => 'Semnătură brută incorectă; verificaţi tag-urile HTML.',
+'email' => 'E-mail',
+'prefs-help-email-enotif'=> 'Această adresă este folosită de asemenea pentru a ţi se trimite notificări prin email dacă ai activat această opţiune.',
+'prefs-help-realname' => '* Numele dumneavoastră real (opţional): Dacă decideţi introducerea numelui real aici, acesta va fi folosit pentru a vă atribui munca.<br />',
+'loginerror' => 'Eroare de autentificare',
+'prefs-help-email' => '*Adresa de e-mail (opţional): Permite altor utilizatori să vă contacteze prin e-mail via {{SITENAME}} fără a vă divulga identitatea. De asemenea, permite recuperarea parolei dacă o uitaţi.',
+'nocookiesnew' => 'Contul a fost creat, dar dvs. nu sunteţi autentificat(ă). {{SITENAME}} foloseşte cookie-uri pentru a reţine utilizatorii autentificaţi. Browser-ul dvs. are modulele cookie dezactivate (disabled). Vă rugăm să le activaţi şi să vă reautentificaţi folosind noul nume de utilizator şi noua parolă.',
+'nocookieslogin' => '{{SITENAME}} foloseşte module cookie pentru a autentifica utilizatorii. Browser-ul dvs. are cookie-urile dezactivate. Vă rugăm să le activaţi şi să incercaţi din nou.',
+'noname' => 'Numele de utilizator pe care l-ai specificat este invalid.',
+'loginsuccesstitle' => 'Autentificare reuşită',
+'loginsuccess' => 'Aţi fost autentificat în {{SITENAME}} ca "$1".',
+'nosuchuser' => 'Nu există nici un utilizator cu numele "$1". Verifică dacă ai scris corect sau foloseşte această pagină pentru a crea un nou utilizator.',
+'nosuchusershort' => 'Nu este nici un utilizator cu numele "$1". Verificaţi dacă aţi scris corect.',
+'nouserspecified' => 'Trebuie să specificaţi un nume de utilizator.',
+'wrongpassword' => 'Parola pe care ai introdus-o este greşită. Te rugăm să încerci din nou.',
+'wrongpasswordempty' => 'Spaţiul pentru introducerea parolei nu a fost completat. Vă rugăm să încercaţi din nou.',
+'mailmypassword' => 'Trimite-mi parola pe e-mail!',
+'passwordremindertitle' => 'Amintirea parolei de la {{SITENAME}}',
+'passwordremindertext' => 'Cineva (probabil tu, de la adresa $1)
+a cerut să ţi se trimită o nouă parolă pentru {{SITENAME}} ($4).
+Parola pentru utilizatorul "$2" este acum "$3".
+Este recomandat să intri pe {{SITENAME}} şi să-ţi schimbi parola cât mai curând.',
+'noemail' => 'Nu este nici o adresă de e-mail înregistrată pentru utilizatorul "$1".',
+'passwordsent' => 'O nouă parolă a fost trimisă la adresa de e-mail a utilizatorului "$1". Te rugăm să te autentifici pe {{SITENAME}} după ce o primeşti.',
+'eauthentsent' => 'Un email de confirmare a fost trimis adresei nominalizate. Înainte de a fi trimis orice alt email acestui cont, trebuie să urmaţi intrucţiunile din email, pentru a confirma că acest cont este într-adevăr al dvs.',
+'mailerror' => 'Eroare la trimitere e-mail: $1',
+'acct_creation_throttle_hit'=> 'Ne pare rău, aţi creat deja $1 conturi de utilizator. Nu mai puteţi crea altul.',
+'emailauthenticated' => 'Adresa de email a fost autentificată la $1.',
+'emailnotauthenticated' => 'Adresa de email nu este autentificată încă. Nici un email nu va fi trimis pentru nici una din întrebuinţările următoare.',
+'noemailprefs' => '<strong>Nu a fost specificată o adresă email</strong>, următoarele nu vor funcţiona.',
+'emailconfirmlink' => 'Confirmaţi adresa dvs. de email',
+'invalidemailaddress' => 'Adresa de email nu a putut fi acceptată pentru că pare a avea un format invalid. Vă rugăm să reintroduceţi o adresă bine formatată sau să goliţi acel câmp.',
+'accountcreated' => 'Contul a fost creat.',
+'accountcreatedtext' => 'Contul utilizatorului pentru $1 a fost creat.',
+'bold_sample' => 'Text aldin',
+'bold_tip' => 'Text aldin',
+'italic_sample' => 'Text cursiv',
+'italic_tip' => 'Text cursiv',
+'link_sample' => 'Titlul legăturii',
+'link_tip' => 'Legătură internă',
+'extlink_sample' => 'http://www.exemplu.ro titlul legăturii',
+'extlink_tip' => 'Legătură externă (nu uitaţi prefixul http://)',
+'headline_sample' => 'Text de titlu',
+'headline_tip' => 'Titlu de nivel 2',
+'math_sample' => 'Introduceţi formula aici',
+'math_tip' => 'Formulă matematică (LaTeX)',
+'nowiki_sample' => 'Introduceţi text neformatat aici',
+'nowiki_tip' => 'Ignoră formatarea wiki',
+'image_sample' => 'Exemplu.jpg',
+'image_tip' => 'Inserează imagine',
+'media_sample' => 'Exemplu.ogg',
+'media_tip' => 'Legătură la fişier media',
+'sig_tip' => 'Semnătura dvs. datată',
+'hr_tip' => 'Linie orizontală (folosiţi-o cumpătat)',
+'summary' => 'Sumar',
+'subject' => 'Subiect / titlu',
+'minoredit' => 'Aceasta este o editare minoră',
+'watchthis' => 'Urmăreşte această pagină',
+'savearticle' => 'Salvează pagina',
+'preview' => 'Previzualizare',
+'showpreview' => 'Arată previzualizare',
+'showlivepreview' => 'Previzualizare live',
+'showdiff' => 'Arată diferenţele',
+'anoneditwarning' => '\'\'\'Avertizare:\'\'\' Nu sunteţi logat(ă). Adresa IP vă va fi înregistrată în istoricul acestei pagini.',
+'missingsummary' => '\'\'\'Atenţie:\'\'\' Nu aţi completat caseta "descriere modificări". Dacă apăsaţi din nou butonul "salvează pagina" modificările vor fi salvate fără descriere.',
+'missingcommenttext' => 'Vă rugăm să introduceţi un comentariu.',
+'blockedtitle' => 'Utilizatorul este blocat',
+'blockedtext' => 'Adresa IP sau contul de utilizator v-a fost blocat de către $1 pentru următorul motiv:
+
+:\'\'$2\'\'
+
+Adresa dumneavoastră IP este $3.
+
+Dacă nu înţelegeţi motivul blocării vă invităm să consultaţi [[Project:Blocare|regulamentul de blocare]]. În cazul în care vă consideraţi nedreptăţit îl puteţi contacta pe $1 sau pe unul dintre ceilalţi [[Project:Administratori|administratori]] pentru a explica situaţia.
+
+\'\'\'Blocarea nu se referă la citirea paginilor {{SITENAME}}, ci doar la modificarea lor.\'\'\'
+
+Pentru a afla cînd vă expiră blocarea căutaţi-vă numele de utilizator sau adresa IP în [[Special:Ipblocklist|lista de utilizatori blocaţi]].',
+'blockedoriginalsource' => 'Sursa pentru \'\'\'$1\'\'\' apare mai jos:',
+'blockededitsource' => 'Textul \'\'\'modificărilor tale\'\'\' la \'\'\'$1\'\'\' este redat mai jos:',
+'whitelistedittitle' => 'Este necesară autentificarea pentru a edita',
+'whitelistedittext' => 'Trebuie să $1 pentru a edita articole.',
+'whitelistreadtitle' => 'Este necesară autentificarea pentru a citi',
+'whitelistreadtext' => 'Trebuie să te [[Special:Userlogin|autentifici]] pentru a citi articole.',
+'whitelistacctitle' => 'Nu ai dreptul de a crea conturi',
+'whitelistacctext' => 'Trebuie să te [[Special:Userlogin|autentifici]] şi să ai permisiunile corecte pentru a crea conturi.',
+'confirmedittitle' => 'Pentru a edita e necesară confirmarea adresei de e-mail',
+'confirmedittext' => 'Trebuie să vă confirmaţi adresa de e-mail înainte de a edita pagini. Vă rugăm să vă setaţi şi să vă validaţi adresa de e-mail cu ajutorul [[Special:Preferences|preferinţelor utilizatorului]].',
+'loginreqtitle' => 'Necesită autentificare',
+'loginreqlink' => 'autentifici',
+'loginreqpagetext' => 'Trebuie să te $1 pentru a vizualiza alte pagini.',
+'accmailtitle' => 'Parola a fost trimisă.',
+'accmailtext' => 'Parola pentru \'$1\' a fost trimisă la $2.',
+'newarticle' => '(Nou)',
+'newarticletext' => 'Ai ajuns la o pagină care nu există. Pentru a o crea, începe să scrii în caseta de mai jos (vezi [[Project:Ajutor|pagina de ajutor]] pentru mai multe informaţii). Dacă ai ajuns aici din greşeală, întoarce-te folosind controalele browser-ului tău',
+'anontalkpagetext' => '---- \'\'Aceasta este pagina de discuţii pentru un utilizator care nu şi-a creat un cont încă, sau care nu s-a autentificat. De aceea trebuie să folosim [[adresă IP|adresa IP]] pentru a identifica această persoană. O adresă IP poate fi folosită în comun de mai mulţi utilizatori. Dacă sunteţi un astfel de utilizator şi credeţi că vă sunt adresate mesaje irelevante, vă rugăm să [[Special:Userlogin|vă creaţi un cont sau să vă autentificaţi]] pentru a evita confuzii cu alţi utilizatori anonimi în viitor.\'\'',
+'noarticletext' => '{{SITENAME}} nu are încă un articol referitor la această pagină. Puteţi [[Special:Search/{{PAGENAME}}|căuta titlul paginii cu acest nume]] în alte pagini sau [{{fullurl:{{FULLPAGENAME}}|action=edit}} edita această pagină].',
+'clearyourcache' => '\'\'\'Notă:\'\'\' După salvare, trebuie să treceţi peste cache-ul browser-ului pentru a vedea modificările. \'\'\'Mozilla/Safari/Konqueror:\'\'\' ţineţi apăsat \'\'Shift\'\' în timp ce apăsaţi \'\'Reload\'\' (sau apăsaţi \'\'Ctrl-Shift-R\'\'), \'\'\'IE:\'\'\' apăsaţi \'\'Ctrl-F5\'\', \'\'\'Opera:\'\'\' apăsaţi \'\'F5\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Sfat:</strong> Foloseşte butonul \'Arată previzualizare\' pentru a testa noul tău css/js înainte de a salva.',
+'usercsspreview' => '\'\'\'Reţine că urmăreşti doar o previzualizare a css-ului tău de utilizator, acesta nu este încă salvat!\'\'\'',
+'userjspreview' => '\'\'\'Reţine că urmăreşti doar un test/o previzualizare a javascript-ului tău de utilizator, acesta nu este încă salvat!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Avertizare:\'\'\' Nu există skin "$1". Aminteşte-ţi că paginile .css and .js specifice utilizatorilor au titluri care încep cu literă mică, de exemplu Utilizator:Foo/monobook.css în comparaţie cu User:Foo/Monobook.css.',
+'updated' => '(Actualizat)',
+'note' => '<strong>Notă:</strong>',
+'previewnote' => 'Aceasta este doar o previzualizare! Pentru a salva pagina în forma actuală, descrieţi succint modificările efectuate şi apăsaţi butonul <strong>Salvează pagina</strong>.',
+'session_fail_preview' => '<strong>Ne pare rău! Nu am putut procesa modificarea dumneavoastră din cauza pierderii datelor sesiunii. Vă rugăm să încercaţi din nou. Dacă tot nu funcţionează, încercaţi să închideţi sesiunea şi să vă autentificaţi din nou.</strong>',
+'previewconflict' => 'Această pre-vizualizare reflectă textul din caseta de sus, respectiv felul în care va arăta articolul dacă alegeţi să-l salvaţi acum.',
+'session_fail_preview_html'=> '<strong>Ne pare rău! Modificările tale nu au putut fi procesate din cauza pierderii datelor sesiunii.</strong>
+
+\'\'Deoarece acest wiki are activat raw HTML, previzualizarea este ascunsă ca măsură de precauţie împotriva atacurilor JavaScript.\'\'
+
+<strong>Dacă această încercare de modificare este legitimă, te rugăm să încerci din nou. Dacă nu funcţionează nici în acest fel, închide sesiunea şi încearcă să te autentifici din nou.</strong>',
+'importing' => 'Se importă $1',
+'editing' => 'modificare $1',
+'editinguser' => 'modificare $1',
+'editingsection' => 'se modifică $1 (secţiune)',
+'editingcomment' => 'modificare $1 (comentariu)',
+'editconflict' => 'Conflict de modificare: $1',
+'explainconflict' => 'Altcineva a modificat această pagină de când ai început să o editezi. Caseta de text de sus conţine pagina aşa cum este ea acum (după editarea celeilalte persoane). Pagina cu modificările tale (aşa cum ai încercat să o salvezi) se află în caseta de jos. Va trebui să editezi manual caseta de sus pentru a reflecta modificările pe care tocmai le-ai făcut în cea de jos. <b>Numai</b> textul din caseta de sus va fi salvat atunci când vei apăsa pe "Salvează pagina".<br />',
+'yourtext' => 'Textul tău',
+'storedversion' => 'Versiunea curentă',
+'nonunicodebrowser' => '<strong>ATENŢIE: Browser-ul dumneavoastră nu este compilant unicode, vă rugăm să îl schimbaţi înainte de a începe modificarea unui articol.</strong>',
+'editingold' => '<strong>ATENŢIE! Modifici o variantă mai veche a acestei pagini! Orice modificări care s-au făcut de la această versiune şi până la cea curentă se vor pierde!</strong>',
+'yourdiff' => 'Diferenţe',
+'copyrightwarning' => '<!-- Gol deocamdată. Avertismentul se află în MediaWiki:Summary -->
+Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details). If you don\'t want your writing to be edited mercilessly and redistributed at will, then don\'t submit it here.<br /> You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. <strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong>',
+'copyrightwarning2' => 'Reţineţi că toate contribuţiile la {{SITENAME}} sunt considerate ca respectând $2 (vezi $1 pentru detalii).<br />
+Dacă nu doriţi ca ceea ce scrieţi să fie modificat fără milă şi redistribuit în voie, atunci nu trimiteţi materialele respective aici. Ceea ce aţi scris a fost compoziţie proprie sau copie dintr-o resursă publică sau liberă (vedeţi $1 pentru detalii).<br />',
+'longpagewarning' => '<strong>ATENŢIE! Conţinutul acestei pagini are $1 KB; unele browsere au probleme la modificarea paginilor în jur de 32 KB sau mai mari. Te rugăm să iei în considerare posibilitatea de a împărţi pagina în mai multe secţiuni.</strong>',
+'longpageerror' => '<strong>EROARE: Textul pe care vrei să-l salvezi are $1 kilobytes,
+ceea ce înseamnă mai mult decât maximum de $2 kilobytes. Salvarea nu este posibilă.</strong>',
+'readonlywarning' => '<strong>ATENŢIE! Baza de date a fost blocată pentru întreţinere, deci nu vei putea să salvezi editările în acest moment. Poţi copia textul într-un fişier text local pentru a modifica conţinutul în {{SITENAME}} când va fi posibil.</strong>',
+'protectedpagewarning' => '<strong>ATENŢIE! Această pagină a fost protejată la scriere şi numai utilizatorii cu privilegii de administrator o pot modifica. Vă rugăm urmaţi sugestiile [[Project:Pagină protejată|despre pagini protejate]] când modificaţi.</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Atenţie:\'\'\' Această pagină poate fi modificată numai de utilizatorii înregistraţi.',
+'templatesused' => 'Formate folosite în această pagină:',
+'edittools' => '<!-- Acest text va apărea după caseta de editare şi formularele de trimitere fişier. -->',
+'nocreatetitle' => 'Creare de pagini limitată',
+'nocreatetext' => 'Acest site a restricţionat abilitatea de creare a paginilor noi. Puteţi edita o pagină deja existentă sau puteţi să vă [[Special:Userlogin|autentificaţi/creaţi]] un cont de utilizator.',
+'revhistory' => 'Istoria versiunilor',
+'nohistory' => 'Nu există istoric pentru această pagină.',
+'revnotfound' => 'Versiunea nu a fost găsită',
+'revnotfoundtext' => 'Versiunea mai veche a paginii pe care aţi cerut-o nu a fost găsită. Vă rugăm să verificaţi legătura pe care aţi folosit-o pentru a accesa această pagină.',
+'loadhist' => 'Încarc istoria versiunilor',
+'currentrev' => 'Versiunea curentă',
+'revisionasof' => 'Versiunea de la data $1',
+'revision-info' => 'Revizia pentru $1; $2',
+'previousrevision' => '←Versiunea anterioară',
+'nextrevision' => 'Versiunea următoare →',
+'currentrevisionlink' => 'afişează versiunea curentă',
+'cur' => 'actuală',
+'next' => 'următoarea',
+'last' => 'prec',
+'orig' => 'orig',
+'histlegend' => 'Legendă: (actuală) = diferenţe faţă de versiunea curentă,
+(prec) = diferenţe faţă de versiunea precedentă, M = modificare minoră',
+'deletedrev' => '[şters]',
+'histfirst' => 'Primele',
+'histlast' => 'Ultimele',
+'rev-deleted-comment' => '(comentariu şters)',
+'rev-deleted-user' => '(nume de utilizator şters)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Revizia acestei pagini a fost ştearsă din arhivele publice. Mai multe detalii la [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} deletion log].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">Revizia acestei pagini a fost ştearsă din arhivele publice.
+Ca administrator la acest site poţi să o vezi; s-ar putea să găseşti mai multe detalii la [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} deletion log].
+</div>',
+'rev-delundel' => 'arată/ascunde',
+'history-feed-title' => 'Revizia istoricului',
+'history-feed-description'=> 'Revizia istoricului pentru această pagină de pe wiki',
+'history-feed-item-nocomment'=> '$1 la $2',
+'history-feed-empty' => 'Pagina solicitată nu există.
+E posibil să fi fost ştearsă sau redenumită.
+Încearcă să [[Special:Search|cauţi]] pe wiki pentru pagini noi semnificative.',
+'revisiondelete' => 'Şterge/recuperează revizii',
+'revdelete-selected' => 'Revizia aleasă pentru [[:$1]]:',
+'revdelete-text' => 'Reviziile şterse vor apărea în istoricul paginii, dar conţinutul lor nu va fi accesibil publicului.
+
+Alţi administratori de pe acest wiki vor putea accesa conţinutul ascuns şi îl pot recupera prin aceeaşi interfaţă, dacă nu este impusă o altă restricţie de către operatorii sitului.',
+'revdelete-legend' => 'Setează restricţii pentru revizie:',
+'revdelete-hide-text' => 'Ascunde textul reviziei',
+'revdelete-hide-comment'=> 'Ascunde descrierea modificării',
+'revdelete-hide-user' => 'Ascunde numele de utilizator/IP-ul editorului',
+'revdelete-hide-restricted'=> 'Aplică aceste restricţii administratorilor şi celorlalţi',
+'revdelete-log' => 'Comentariu log:',
+'revdelete-submit' => 'Aplică reviziilor selectate',
+'revdelete-logentry' => 'vizibilitatea reviziei pentru [[$1]] a fost modificată',
+'difference' => '(Diferenţa dintre versiuni)',
+'loadingrev' => 'se încarcă diferenţa dintre versiuni',
+'lineno' => 'Linia $1:',
+'editcurrent' => 'Modificarea versiunii curente a acestei pagini',
+'selectnewerversionfordiff'=> 'Selectează versiunea mai nouă pentru comparare',
+'selectolderversionfordiff'=> 'Selectează o versiune mai veche pentru comparaţie',
+'compareselectedversions'=> 'Compară versiunile selectate',
+'searchresults' => 'Rezultatele căutării',
+'searchresulttext' => 'Pentru mai multe detalii despre căutarea în {{SITENAME}}, vezi [[Project:Căutare]].',
+'searchsubtitle' => 'Pentru căutarea "[[:$1]]"',
+'searchsubtitleinvalid' => 'Pentru căutarea "$1"',
+'badquery' => 'Căutare invalidă',
+'badquerytext' => 'Căutarea dvs. nu a putut fi procesată.
+Aceasta se întâmplă probabil pentru că aţi încercat să căutaţi un cuvânt format din mai puţin de trei litere.
+E posibil şi să fi introdus greşit o expresie sau un nume, cum ar fi "Mircea cel cel Bătrân".
+Vă rugăm să încercaţi din nou.',
+'matchtotals' => 'Căutarea "$1" a produs $2 rezultate în titluri de articole şi $3 rezultate în texte de articole.',
+'noexactmatch' => '\'\'\'Pagina cu titlul "$1" nu există.\'\'\' Poţi [[:$1|crea această pagină]].',
+'titlematches' => 'Rezultate în titluri de articole',
+'notitlematches' => 'Nici un rezultat în titlurile articolelor',
+'textmatches' => 'Rezultate în textele articolelor',
+'notextmatches' => 'Nici un rezultat în textele articolelor',
+'prevn' => 'anterioarele $1',
+'nextn' => 'următoarele $1',
+'viewprevnext' => 'Vezi ($1) ($2) ($3).',
+'showingresults' => 'Mai jos apar <b>$1</b> rezultate începând cu #<b>$2</b>.',
+'showingresultsnum' => 'Mai jos apar <b>$3</b> rezultate începând cu #<b>$2</b>.',
+'nonefound' => '\'\'\'Notă\'\'\': căutările nereuşite sunt în general datorate căutării unor cuvinte prea comune care nu sunt indexate, sau cautărilor a mai multe cuvinte (numai articolele care conţin \'\'toate\'\' cuvintele specificate apar ca rezultate).',
+'powersearch' => 'Caută',
+'powersearchtext' => 'Caută în secţiunile:<br />
+$1<br />
+$2 Redirecţionări<br />
+Căutări după $3 $9',
+'searchdisabled' => '<p>Ne pare rău! Căutarea după text a fost dezactivată temporar, din motive de performanţă. Între timp puteţi folosi căutarea prin Google mai jos, însă aceasta poate să dea rezultate învechite.</p>',
+'blanknamespace' => '(Principală)',
+'preferences' => 'Preferinţe',
+'prefsnologin' => 'Neautentificat',
+'prefsnologintext' => 'Trebuie să fii [[Special:Userlogin|autentificat]] pentru a-ţi putea salva preferinţele.',
+'prefsreset' => 'Preferinţele au fost resetate.',
+'qbsettings' => 'Setări pentru bara rapidă',
+'changepassword' => 'Schimbă parola',
+'skin' => 'Aspect',
+'math' => 'Aspect formule',
+'dateformat' => 'Formatul datelor',
+'datedefault' => 'Nici o preferinţă',
+'datetime' => 'Data şi ora',
+'math_failure' => 'Nu s-a putut interpreta',
+'math_unknown_error' => 'eroare necunoscută',
+'math_unknown_function' => 'funcţie necunoscută',
+'math_lexing_error' => 'eroare lexicală',
+'math_syntax_error' => 'eroare de sintaxă',
+'math_image_error' => 'Conversiune în PNG eşuată',
+'math_bad_tmpdir' => 'Nu se poate crea sau nu se poate scrie în directorul temporar pentru formule matematice',
+'math_bad_output' => 'Nu se poate crea sau nu se poate scrie în directorul de ieşire pentru formule matematice',
+'math_notexvc' => 'Lipseşte executabilul texvc; vezi math/README pentru configurare.',
+'prefs-personal' => 'Date de utilizator',
+'prefs-rc' => 'Modificări recente şi cioturi',
+'prefs-watchlist' => 'Listă de urmărire',
+'prefs-watchlist-days' => 'Numărul de zile care apar în lista paginilor urmărite:',
+'prefs-watchlist-edits' => 'Numărul de editări care apar în lista extinsă a paginilor urmărite:',
+'prefs-misc' => 'Parametri diverşi',
+'saveprefs' => 'Salvează preferinţele',
+'resetprefs' => 'Resetează preferinţele',
+'oldpassword' => 'Parola veche',
+'newpassword' => 'Parola nouă',
+'retypenew' => 'Repetă parola nouă',
+'textboxsize' => 'Dimensiunile casetei de text',
+'rows' => 'Rânduri:',
+'columns' => 'Coloane',
+'searchresultshead' => 'Parametri căutare',
+'resultsperpage' => 'Numărul de rezultate per pagină',
+'contextlines' => 'Numărul de linii per rezultat',
+'contextchars' => 'Numărul de caractere per linie',
+'stubthreshold' => 'Limita de caractere pentru un ciot',
+'recentchangescount' => 'Numărul de articole pentru schimbări recente',
+'savedprefs' => 'Preferinţele tale au fost salvate.',
+'timezonelegend' => 'Fus orar',
+'timezonetext' => 'Introduceţi numărul de ore diferenţă între ora Dv. locală şi ora serverului (UTC, timp universal). Dacă vă aflaţi în România, diferenţa este 02:00 iarna şi 03:00 vara.',
+'localtime' => 'Ora locală',
+'timezoneoffset' => 'Diferenţa¹',
+'servertime' => 'Ora serverului (UTC)',
+'guesstimezone' => 'Încearcă determinarea automată a diferenţei',
+'allowemail' => 'Activează email de la alţi utilizatori',
+'defaultns' => 'Caută în aceste secţiuni implicit:',
+'default' => 'standard',
+'files' => 'Fişiere',
+'userrights-lookup-user'=> 'Administrare grupuri de utilizatori',
+'userrights-user-editname'=> 'Introdu un nume de utilizator:',
+'editusergroup' => 'Modificare grup de utilizatori',
+'userrights-editusergroup'=> 'Modifică grupul de utilizatori',
+'saveusergroups' => 'Salvează grupul de utilizatori',
+'userrights-groupsmember'=> 'Membru al:',
+'userrights-groupsavailable'=> 'Grupuri disponibile:',
+'userrights-groupshelp' => 'Selectează grupurile din care doreşti ca utilizatorul să fie şters sau în care doreşti să fie adăugat. Grupurile deselectate nu se vor modifica. Poţi deselecta un grup cu CTRL + Clic stânga',
+'group' => 'Grup:',
+'group-bot' => 'Roboţi',
+'group-sysop' => 'Administratori',
+'group-bureaucrat' => 'Birocraţi:',
+'group-all' => '(toţi)',
+'group-bot-member' => 'Robot',
+'group-sysop-member' => 'Administrator',
+'group-bureaucrat-member'=> 'Birocrat',
+'grouppage-bot' => 'Project:Boţi',
+'grouppage-sysop' => 'Project:Administratori',
+'grouppage-bureaucrat' => 'Project:Birocraţi',
+'changes' => 'schimbări',
+'recentchanges' => 'Schimbări recente',
+'recentchangestext' => 'Schimbari recente ... (Log)',
+'rcnote' => 'Mai jos se află ultimele <strong>$1</strong> modificări din ultimele <strong>$2</strong> zile sau din <strong>$3</strong>.',
+'rcnotefrom' => 'Dedesubt sunt modificările de la <b>$2</b> (maxim <b>$1</b> de modificări sunt afişate - schimbă numărul maxim de linii alegând altă valoare mai jos).',
+'rclistfrom' => 'Arată modificările începând de la $1',
+'rcshowhideminor' => '$1 modificările minore',
+'rcshowhidebots' => '$1 roboţii',
+'rcshowhideliu' => '$1 utilizatorii autentificaţi',
+'rcshowhideanons' => '$1 utilizatorii anonimi',
+'rcshowhidepatr' => '$1 modificările patrulate',
+'rcshowhidemine' => '$1 editările mele',
+'rclinks' => 'Arată ultimele $1 modificări din ultimele $2 zile.<br />
+$3',
+'diff' => 'dif',
+'hist' => 'istorie',
+'hide' => 'ascunde',
+'show' => 'arată',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[$1 utilizator/i care urmăresc]',
+'rc_categories' => 'Limitează la categoriile (separate prin "|")',
+'rc_categories_any' => 'Oricare',
+'upload' => 'Trimite fişier',
+'uploadbtn' => 'Trimite fişier',
+'reupload' => 'Re-trimite',
+'reuploaddesc' => 'Întoarcere la formularul de trimitere.',
+'uploadnologin' => 'Nu sunteţi autentificat',
+'uploadnologintext' => 'Trebuie să fiţi [[Special:Userlogin|autentificat]] pentru a putea trimite fişiere.',
+'upload_directory_read_only'=> 'Directorul de trimitere ($1) nu are drepturi de scriere de către server.',
+'uploaderror' => 'Eroare la trimitere fişier',
+'uploadtext' => '<strong>STOP!</strong> Înainte de a trimite un fişier aici, te rugăm să citeşti şi să respecţi [[Project:Politica de utilizare a imaginilor|politica de utilizare a imaginilor]].<br />
+Pentru a vizualiza sau căuta imagini deja trimise, mergi la [[Special:Imagelist|lista de imagini]]. Fişierele noi şi cele şterse sunt contorizate pe pagina [[Special:Log/upload|raport de trimiteri]].<br />
+Foloseşte formularul de mai jos pentru a trimite imagini noi pe care le vei putea folosi pentru a ilustra articolele. În majoritatea browserelor vei vedea un buton "Răsfoire..." (sau "Browse...") care va deschide fereastra standard dialog a sistemului tău de operare pentru alegerea de fişiere. Când alegei un fişier în acest fel, caseta de dialog se va completa cu calea locală către acesta. Este de asemenea necesar să bifezi căsuţa asociată textului în care confirmi că nu violezi nici un drept de autor trimiţând această imagine. În final, apasă pe butonul "Trimite" pentru a trimite efectiv fişierul. Această operaţiune poate dura, mai ales dacă ai o legătură lentă la Internet.<br />
+Formatele preferate sunt JPEG pentru imagini fotografice, PNG pentru desene şi alte imagini cu contururi clare şi OGG pentru fişiere de sunet. Te rugăm să foloseşti nume explicite pentru fişiere ca să eviţi confuziile. Pentru a include o imagine într-un articol, foloseşte o legătură de forma<br />
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Fişier.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Fişier.png|text alternativ]]</nowiki>\'\'\'
+Pentru a include un fişier de sunet într-un articol, foloseşti o legătură de forma
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Fişier.ogg]]</nowiki>\'\'\'
+Te rugăm reţine că, la fel ca şi în cazul celorlalte secţiuni din {{SITENAME}}, alte persoane pot edita sau şterge fişierele pe care le trimiţi dacă e în interesul enciclopediei, şi ţi se poate chiar bloca accesul la trimiterea de fişiere dacă abuzezi de sistem.',
+'uploadlog' => 'Raportul fişierelor trimise',
+'uploadlogpage' => 'Raportul fişierelor trimise',
+'uploadlogpagetext' => 'Găseşti mai jos lista ultimelor fişiere trimise.
+Toate datele/orele sunt afişate ca timp universal (UTC).
+<ul>
+</ul>',
+'filename' => 'Nume fişier',
+'filedesc' => 'Descriere fişier',
+'fileuploadsummary' => 'Descriere:',
+'filestatus' => 'Statutul drepturilor de autor',
+'filesource' => 'Sursa',
+'copyrightpage' => 'Project:Drepturi de autor',
+'copyrightpagename' => 'Drepturi de autor în {{SITENAME}}',
+'uploadedfiles' => 'Fişiere trimise',
+'ignorewarning' => 'Ignoră avertismentul şi salvează fişierul.',
+'ignorewarnings' => 'Ignoră orice avertismente.',
+'minlength' => 'Numele imaginilor trebuie să aibă cel puţin trei litere.',
+'illegalfilename' => 'Numele fişierului "$1" conţine caractere care nu sunt permise în titlurile paginilor. Vă rugăm redenumiţi fişierul şi încercaţi să îl încărcaţi din nou.',
+'badfilename' => 'Numele imaginii a fost schimbat; noul nume este "[[:$1]]".',
+'badfiletype' => '".$1" nu este un format recomandat pentru imagini.',
+'largefile' => 'Este recomandat ca fişierele să nu depăşească $1 KB ca mărime; acest fişier are $2 KB.',
+'largefileserver' => 'Fişierul este mai mare decât este configurat serverul să permită.',
+'emptyfile' => 'Fişierul pe care l-aţi încărcat pare a fi gol. Aceasta poate fi datorită unei greşeli în numele fişierului. Verificaţi dacă într-adevăr doriţi să încărcaţi acest fişier.',
+'fileexists' => 'Un fişier cu acelaşi nume există deja, vă rugăm verificaţi $1 dacă nu sunteţi sigur dacă doriţi să îl modificaţi.',
+'fileexists-forbidden' => 'Un fişier cu acest nume există deja; mergeţi înapoi şi încărcaţi acest fişier sub un nume nou. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Un fişier cu acest nume există deja în magazia de imagini comune; mergeţi înapoi şi încărcaţi fişierul sub un nou nume. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Fişierul a fost trimis',
+'fileuploaded' => 'Fişierul "$1" a fost trimis. Te rugăm să vizitezi această legătură: ($2) pentru a descrie fişierul şi pentru a completa informaţii despre acesta, ca de exemplu de unde provine, când a fost creat şi de către cine, cât şi alte informaţii pe care doreşti să le adaugi. Dacă acest fişier conţine o imagine aceasta poate fi adăgată prin sintaxa următoare:<br /><nowiki>[[</nowiki>{{ns:Image}}:$1|thumb|descriere<nowiki>]]</nowiki>',
+'uploadwarning' => 'Avertizare la trimiterea fişierului',
+'savefile' => 'Salvează fişierul',
+'uploadedimage' => 'a trimis [[$1]]',
+'uploaddisabled' => 'Ne pare rău, trimiterea de imagini este dezactivată.',
+'uploaddisabledtext' => 'Încărcarea de fişiere este dezactivată pe acest wiki.',
+'uploadscripted' => 'Fişierul conţine HTML sau cod script care poate fi interpretat în mod eronat de un browser.',
+'uploadcorrupt' => 'Fişierul este corupt sau are o extensie incorectă. Verifică fişierul şi trimite-l din nou.',
+'uploadvirus' => 'Fişierul conţine un virus! Detalii: $1',
+'sourcefilename' => 'Nume fişier sursă',
+'destfilename' => 'Nume fişier destinaţie',
+'filewasdeleted' => 'Un fişier cu acest nume a fost anterior încărcat şi apoi şters. Ar trebui să verificaţi $1 înainte să îl încărcaţi din nou.',
+'license' => 'Licenţiere',
+'nolicense' => 'Nici una selectată',
+'imagelist' => 'Lista imaginilor',
+'imagelisttext' => 'Mai jos se află lista a $1 imagini ordonate $2.',
+'imagelistforuser' => 'Se afişează numai imagini încărcate de $1.',
+'getimagelist' => 'încarc lista de imagini',
+'ilsubmit' => 'Caută',
+'showlast' => 'Arată ultimele $1 imagini ordonate $2.',
+'byname' => 'după nume',
+'bydate' => 'după dată',
+'bysize' => 'după mărime',
+'imgdelete' => 'şterge',
+'imgdesc' => 'desc',
+'imglegend' => 'Legendă: (desc) = arată/modifică descrierea imaginii.',
+'imghistory' => 'Istoria imaginii',
+'revertimg' => 'rev',
+'deleteimg' => 'şterg',
+'deleteimgcompletely' => 'şterg',
+'imghistlegend' => 'Legendă: (actuală) = versiunea curentă a imaginii, (şterg) = şterge această versiune veche, (rev) = revino la această versiune veche.',
+'imagelinks' => 'Legăturile imaginii',
+'linkstoimage' => 'Următoarele pagini leagă la această imagine:',
+'nolinkstoimage' => 'Nici o pagină nu se leagă la această imagine.',
+'sharedupload' => 'Acest fişier transferat (upload) poate fi folosit în comun de către alte proiecte.',
+'shareduploadwiki' => 'Vă rugăm citiţi [$1 pagina de descriere a fişierului] pentru alte informaţii.',
+'shareduploadwiki-linktext'=> 'pagina descriptivă a fişierului',
+'noimage' => 'Nu există nici un fişier cu acest nume, puteţi să îl $1.',
+'noimage-linktext' => 'trimiteţi',
+'uploadnewversion-linktext'=> 'Încarcă o versiune nouă a acestui fişier',
+'mimesearch' => 'Căutare MIME',
+'mimetype' => 'Tip MIME:',
+'download' => 'descarcă',
+'unwatchedpages' => 'Pagini neurmărite',
+'listredirects' => 'Lista de redirecţionări',
+'unusedtemplates' => 'Formate neutilizate',
+'unusedtemplatestext' => 'Lista de mai jos cuprinde toate formatele care nu sînt incluse în nici o altă pagină. Înainte de a le şterge asiguraţi-vă că într-adevăr nu există legături dinspre alte pagini.',
+'unusedtemplateswlh' => 'alte legături',
+'randomredirect' => 'Redirecţionare aleatorie',
+'statistics' => 'Statistici',
+'sitestats' => 'Statisticile sitului {{SITENAME}}',
+'userstats' => 'Statistici legate de utilizatori',
+'sitestatstext' => 'Există un număr total de <b>$1</b> pagini în baza de date.
+Acest număr include paginile de "discuţii", paginile despre {{SITENAME}}, pagini minimale ("cioturi"), pagini de redirecţionare şi altele care probabil că nu intră de fapt în categoria articolelor reale.
+În afară de acestea, există <b>$2</b> pagini care sunt probabil articole (numărate automat, în funcţie strict de mărime).<br />
+
+\'\'\'$8\'\'\' pagini au fost transferate (upload).
+
+În total au fost <b>$3</b> vizite (accesări) şi <b>$4</b> modificări de la lansarea acestei wiki.
+În medie rezultă <b>$5</b> modificări per pagină sau <b>$6</b> vizualizări la fiecare modificare.
+
+Mărimea [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] este \'\'\'$7\'\'\'.',
+'userstatstext' => 'Există un număr de \'\'\'$1\'\'\' utilizatori înregistraţi. Dintre aceştia \'\'\'$2\'\'\' (sau \'\'\'$4%\'\'\') sunt administratori (vezi \'\'\'$3\'\'\').',
+'disambiguations' => 'Pagini de dezambiguizare',
+'disambiguationspage' => 'Template:Dezambiguizare',
+'disambiguationstext' => 'Următoarele articole conţin legături către cel puţin o <i>pagină de dezambiguizare</i>. Legăturile respective ar trebui făcute către paginile specifice.<br />
+O pagină este considerată ca fiind de dezambiguizare dacă există o legătură în ea dinspre $1.<br />
+Legăturile dinspre alte secţiuni {{SITENAME}} <i>nu sunt</i> luate în considerare aici.',
+'doubleredirects' => 'Redirecţionări duble',
+'doubleredirectstext' => '<b>Atenţie:</b> Această listă poate conţine articole care nu sunt în fapt duble rediriecţionări. Acest lucru înseamnă de obicei că există text adiţional sub primul #REDIRECT.<br />',
+'brokenredirects' => 'Redirecţionări greşite',
+'brokenredirectstext' => 'Următoarele redirecţionări conduc spre articole inexistente.',
+'nbytes' => '{{PLURAL:$1|un octet|$1 octeţi}}',
+'ncategories' => '{{PLURAL:$1|o categorie|$1 categorii}}',
+'nlinks' => '{{PLURAL:$1|o legătură|$1 legături}}',
+'nmembers' => '{{PLURAL:$1|un membru|$1 membri}}',
+'nrevisions' => '{{PLURAL:$1|o revizie|$1 revizii}}',
+'nviews' => '{{PLURAL:$1|o accesare|$1 accesări}}',
+'lonelypages' => 'Pagini orfane',
+'uncategorizedpages' => 'Pagini necategorizate',
+'uncategorizedcategories'=> 'Categorii necategorizate',
+'uncategorizedimages' => 'Imagini necategorizate',
+'unusedcategories' => 'Categorii neutilizate',
+'unusedimages' => 'Pagini neutilizate',
+'popularpages' => 'Pagini populare',
+'wantedcategories' => 'Categorii dorite',
+'wantedpages' => 'Pagini dorite',
+'mostlinked' => 'Cele mai căutate articole',
+'mostlinkedcategories' => 'Cele mai căutate categorii',
+'mostcategories' => 'Articole cu cele mai multe categorii',
+'mostimages' => 'Cele mai căutate imagini',
+'mostrevisions' => 'Articole cu cele mai multe revizuiri',
+'allpages' => 'Toate paginile',
+'prefixindex' => 'Afişare articole începând de la',
+'randompage' => 'Pagină aleatorie',
+'shortpages' => 'Pagini scurte',
+'longpages' => 'Pagini lungi',
+'deadendpages' => 'Pagini fără legături',
+'listusers' => 'Lista de utilizatori',
+'specialpages' => 'Pagini speciale',
+'spheading' => 'Pagini speciale pentru toţi utilizatorii',
+'restrictedpheading' => 'Pagini speciale restricţionate',
+'recentchangeslinked' => 'Modificări corelate',
+'rclsub' => '(cu pagini legate de la "$1")',
+'newpages' => 'Pagini noi',
+'ancientpages' => 'Cele mai vechi articole',
+'intl' => 'Legături între limbi',
+'move' => 'Mutare',
+'movethispage' => 'Mută această pagină',
+'unusedimagestext' => '<p>Te rugăm ţine cont de faptul că alte situri, inclusiv alte versiuni de limbă {{SITENAME}} pot să aibă legături aici fără ca aceste pagini să fie listate aici - această listă se referă strict la {{SITENAME}} în română.</p>',
+'unusedcategoriestext' => 'Următoarele categorii de pagini există şi totuşi nici un articol sau categorie nu le foloseşte.',
+'booksources' => 'Surse de cărţi',
+'categoriespagetext' => 'Următoarele categorii există în wiki.',
+'data' => 'Data',
+'userrights' => 'Administrarea drepturilor de utilizator',
+'groups' => 'Grupuri de utilizatori',
+'booksourcetext' => 'Dedesubt găsiţi o listă de surse de cărţi noi şi vechi, şi e posibil să găsiţi şi alte informaţii legate de volumele pe care le căutaţi.
+{{SITENAME}} nu este afiliat(ă) nici uneia dintre aceste afaceri,
+iar lista de mai jos nu constituie nici un fel de garanţie sau validare a serviciilor respective din partea {{SITENAME}}.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 către $2',
+'version' => 'Versiune',
+'log' => 'Rapoarte',
+'alllogstext' => 'Afişare combinată a încărcărilor, ştergerilor, protecţiilor, blocărilor şi a rapoartelor administratorilor. Puteţi limita vizualizarea selectând tipul raportului, numele de utilizator sau pagina afectată.',
+'logempty' => 'Nici o înregistrare în raport.',
+'nextpage' => 'Pagina următoare ($1)',
+'allpagesfrom' => 'Afişează paginile pornind de la:',
+'allarticles' => 'Toate articolele',
+'allinnamespace' => 'Toate paginile (spaţiu de nume $1)',
+'allnotinnamespace' => 'Toate paginile (în afara spaţiului de nume $1)',
+'allpagesprev' => 'Anterior',
+'allpagesnext' => 'Următor',
+'allpagessubmit' => 'Trimite',
+'allpagesprefix' => 'Afişează paginile cu prefix:',
+'mailnologin' => 'Nu există adresă de trimitere',
+'mailnologintext' => 'Trebuie să fii [[Special:Userlogin|autentificat]] şi să ai o adresă validă de e-mail în [[Special:Preferences|preferinţe]] pentru a trimite e-mail altor utilizatori.',
+'emailuser' => 'Trimite e-mail',
+'emailpage' => 'E-mail către utilizator',
+'emailpagetext' => 'Dacă acest utilizator a introdus o adresă de e-mail validă în pagina de preferinţe atunci formularul de mai jos poate fi folosit pentru a-i trimite un mesaj prin e-mail. Adresa pe care ai introdus-o în pagina ta de preferinţe va apărea ca adresa de origine a mesajului, astfel încât destinatarul să îţi poată răspunde direct.',
+'usermailererror' => 'Obiectul de mail a dat eroare:',
+'defemailsubject' => 'E-mail {{SITENAME}}',
+'noemailtitle' => 'Fără adresă de e-mail',
+'noemailtext' => 'Utilizatorul nu a specificat o adresă validă de e-mail, sau a ales să nu primească e-mail de la alţi utilizatori.',
+'emailfrom' => 'De la',
+'emailto' => 'Către',
+'emailsubject' => 'Subiect',
+'emailmessage' => 'Mesaj',
+'emailsend' => 'Trimite',
+'emailsent' => 'E-mail trimis',
+'emailsenttext' => 'E-mailul tău a fost trimis.',
+'watchlist' => 'Paginile urmărite de mine',
+'watchlistfor' => '(pentru \'\'\'$1\'\'\')',
+'nowatchlist' => 'Nu aţi ales să urmăriţi nici o pagină.',
+'watchlistanontext' => 'Te rugăm să $1 pentru a vizualiza sau edita itemii de pe lista ta de urmărire.',
+'watchlistcount' => '\'\'\'Aveţi $1 elemente în lista de urmărire, incluzând paginile de discuţii.\'\'\'',
+'clearwatchlist' => 'Şterge lista de articole urmărite',
+'watchlistcleartext' => 'Sunteţi sigur că doriţi să le ştergeţi?',
+'watchlistclearbutton' => 'Curăţaţi lista de articole urmărite',
+'watchlistcleardone' => 'Lista de urmărire a fost golită. $1 elemente au fost scoase.',
+'watchnologin' => 'Nu sunteţi autentificat',
+'watchnologintext' => 'Trebuie să fiţi [[Special:Userlogin|autentificat]] pentru a vă modifica lista de pagini urmărite.',
+'addedwatch' => 'Adăugată la lista de pagini urmărite',
+'addedwatchtext' => 'Pagina "[[:$1]]" a fost adăugată la lista ta de [[Special:Watchlist|articole urmărite]]. Modificările viitoare ale acestei pagini şi a paginii asociate de discuţii vor fi listate aici, şi în plus ele vor apărea cu <b>caractere îngroşate</b> în pagina de [[Special:Recentchanges|modificări recente]] pentru evidenţiere.<p>Dacă doreşti să elimini această pagină din lista ta de pagini urmărite în viitor, apasă pe "Nu mai urmări" în bara de comenzi în timp ce această pagină este vizibilă.',
+'removedwatch' => 'Ştearsă din lista de pagini urmărite',
+'removedwatchtext' => 'Pagina "[[:$1]]" a fost eliminată din lista de pagini urmărite.',
+'watch' => 'Urmărire',
+'watchthispage' => 'Urmăreşte pagina',
+'unwatch' => 'Nu mai urmări',
+'unwatchthispage' => 'Nu mai urmări',
+'notanarticle' => 'Nu este un articol',
+'watchnochange' => 'Nici una dintre paginile pe care le urmăriţi nu a fost modificată în perioada de timp afişată.',
+'watchdetails' => '($1 pagini urmărite în afară de paginile de discuţie; $2 pagini editate în total; $3... [$4 lista completă].)',
+'wlheader-enotif' => '*Notificarea email este activată',
+'wlheader-showupdated' => '* Paginile care au modificări de la ultima ta vizită sunt afişate \'\'\'îngroşat\'\'\'',
+'watchmethod-recent' => 'căutarea schimbărilor recente pentru paginile urmărite',
+'watchmethod-list' => 'căutarea paginilor urmărite pentru schimbări recente',
+'removechecked' => 'Elimină elementele bifate din lista de pagini urmărite',
+'watchlistcontains' => 'Lista de pagini urmărite conţine $1 elemente.',
+'watcheditlist' => 'Aceasta este lista alfabetică a tuturor paginilor pe care le urmăreşti. Bifează căsuţele corespunzătoare paginilor pe care doreşti să le elimini din lista de pagini urmărite şi apasă pe butonul corespunzător din partea de jos a paginii.',
+'removingchecked' => 'Se elimină elementele selectate din lista de pagini urmărite...',
+'couldntremove' => 'Elementul \'$1\' nu a putut fi şters...',
+'iteminvalidname' => 'E o problemă cu elementul \'$1\', numele este invalid...',
+'wlnote' => 'Mai jos se află ultimele $1 schimbări din ultimele <b>$2</b> ore.',
+'wlshowlast' => 'Arată ultimele $1 ore $2 zile $3',
+'wlsaved' => 'Aceasta este o versiune salvată a listei tale de pagini urmărite.',
+'wlhideshowown' => '$1 modificările mele.',
+'wlhideshowbots' => '$1 modificările roboţilor.',
+'wldone' => 'Terminat.',
+'enotif_mailer' => 'Sistemul de notificare {{SITENAME}}',
+'enotif_reset' => 'Marchează toate paginile vizitate.',
+'enotif_newpagetext' => 'Aceasta este o pagină nouă.',
+'changed' => 'modificat',
+'created' => 'creat',
+'enotif_subject' => 'Pagina $PAGETITLE de la {{SITENAME}} a fost $CHANGEDORCREATED de $PAGEEDITOR',
+'enotif_lastvisited' => 'Vedeţi $1 pentru toate modificările de la ultima dvs. vizită.',
+'enotif_body' => 'Domnule/Doamnă $WATCHINGUSERNAME,
+
+pagina $PAGETITLE de la {{SITENAME}} a fost $CHANGEDORCREATED în $PAGEEDITDATE de $PAGEEDITOR, vedeţi la $PAGETITLE_URL versiunea curentă.
+
+$NEWPAGE
+
+Sumarul utilizatorului: $PAGESUMMARY $PAGEMINOREDIT
+
+Contactaţi utilizatorul:
+email: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Nu vor mai fi alte notificări în cazul unor viitoare modificări în afara cazului în care vizitaţi pagina. Puteţi de asemenea reseta notificările pentru alte pagini urmărite.
+
+ Al dvs. amic, sistemul de notificare {{SITENAME}}
+
+--
+Pentru a modifica preferinţele listei de urmărire, vizitaţi
+{{fullurl:Special:Watchlist/edit}}
+
+Asistenţă şi suport:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Şterge pagina',
+'confirm' => 'Confirmă',
+'excontent' => 'conţinutul era: \'$1\'',
+'excontentauthor' => 'conţinutul a fost: \'$1\' (şi unicul contribuitor era \'$2\')',
+'exbeforeblank' => 'conţinutul înainte de golire era: \'$1\'',
+'exblank' => 'pagina era goală',
+'confirmdelete' => 'Confirmă ştergere',
+'deletesub' => '(Şterg "$1")',
+'historywarning' => 'Atenţie! Pagina pe care o ştergi are istorie:',
+'confirmdeletetext' => 'Sunteţi pe cale să ştergeţi permanent o pagină sau imagine din baza de date, împreună cu istoria asociată acesteia. Vă rugăm să confirmaţi alegerea făcută de dvs., faptul că înţelegeţi consecinţele acestei acţiuni şi faptul că o faceţi în conformitate cu [[Project:Politica oficială|Proiect:Politica oficială]].',
+'actioncomplete' => 'Acţiune finalizată',
+'deletedtext' => 'Pagina "$1" a fost ştearsă. Vedeţi $2 pentru o listă a elementelor şterse recent.',
+'deletedarticle' => '"<s>[[:$1]]</s>" a fost şters',
+'dellogpage' => 'Ştergere_log',
+'dellogpagetext' => 'Mai jos se află lista celor mai recente elemente şterse. Toate datele/orele sunt listate în timp universal (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'raportul de ştergeri',
+'reverted' => 'Revenire la o versiune mai veche',
+'deletecomment' => 'Motiv pentru ştergere',
+'imagereverted' => 'S-a revenit la o versiune veche.',
+'rollback' => 'Editări de revenire',
+'rollback_short' => 'Revenire',
+'rollbacklink' => 'revenire',
+'rollbackfailed' => 'Revenirea nu s-a putut face',
+'cantrollback' => 'Nu se poate reveni; ultimul contribuitor este autorul acestui articol.',
+'alreadyrolled' => 'Nu se poate reveni peste ultima modificare a articolului [[:$1]]
+făcută de către [[User:$2|$2]] ([[User talk:$2|discuţie]]); altcineva a modificat articolul sau a revenit deja.
+
+Ultima editare a fost făcută de către [[User:$3|$3]] ([[User talk:$3|discuţie]]).',
+'editcomment' => 'Comentariul de modificare a fost: "<i>$1</i>".',
+'revertpage' => 'Reveniri la ultima modificare de către [[Special:Contributions/$2|$2]] ([[User talk:$2|discuţie]]); revenire la ultima versiune de către [[User:$1|$1]]',
+'sessionfailure' => 'Se pare că este o problemă cu sesiunea de autentificare; această acţiune a fost oprită ca o precauţie împotriva hijack. Apăsaţi "back" şi reîncărcaţi pagina de unde aţi venit, apoi reîncercaţi.',
+'protectlogpage' => 'Jurnal_protecţii',
+'protectlogtext' => 'Mai jos se află lista de blocări/deblocări a paginilor. Vezi [[Project:Pagină protejată]] pentru mai multe informaţii.',
+'protectedarticle' => 'a protejat "[[$1]]"',
+'unprotectedarticle' => 'a deprotejat "[[$1]]"',
+'protectsub' => '(Protejare "$1")',
+'confirmprotecttext' => 'Eşti sigur(ă) că doreşti să protejezi pagina?',
+'confirmprotect' => 'Confirmă protejare',
+'protectmoveonly' => 'Protejează doar de mutări',
+'protectcomment' => 'Motiv pentru protejare',
+'unprotectsub' => '(Deprotejând "$1")',
+'confirmunprotecttext' => 'Sunteţi sigur(ă) că doriţi deprotejarea paginii?',
+'confirmunprotect' => 'Confirmă deprotejarea',
+'unprotectcomment' => 'Motiv pentru deprotejare',
+'protect-unchain' => 'Deblochează permisiunile de mutare',
+'protect-text' => 'Poţi vizualiza sau modifica nivelul de protecţie pentru pagina <strong>$1</strong>. Asigură-te că acţionezi în conformitate cu [[Project:Pagină protejată|politica proiectului]].',
+'protect-viewtext' => 'Contul dumneavoastră nu are permisiunile necesare modificării nivelului de protecţie al paginii. Puteţi vizualiza setările curente pentru pagina <strong>$1</strong>:',
+'protect-default' => '(standard)',
+'protect-level-autoconfirmed'=> 'Blochează utilizatorii neînregistraţi',
+'protect-level-sysop' => 'Numai administratorii',
+'restriction-edit' => 'Editează',
+'restriction-move' => 'Mută',
+'undelete' => 'Recuperează pagina ştearsă',
+'undeletepage' => 'Vizualizează şi recuperează pagini şterse',
+'viewdeletedpage' => 'Vezi paginile şterse',
+'undeletepagetext' => 'Următoarele pagini au fost şterse, dar încă se află în arhivă şi pot fi recuperate. Reţine că arhiva se poate şterge din timp în timp.',
+'undeleteextrahelp' => 'Pentru a recupera întreaga pagină lăsaţi toate căsuţele nebifate şi apăsaţi butonul \'\'\'\'\'Recuperează\'\'\'\'\'. Pentru a realiza o recuperare selectivă bifaţi versiunile pe care doriţi să le recuperaţi şi apăsaţi butonul \'\'\'\'\'Recuperează\'\'\'\'\'. Butonul \'\'\'\'\'Resetează\'\'\'\'\' va şterge comentariul şi toate bifările.',
+'undeletearticle' => 'Recuperează articol şters',
+'undeleterevisions' => '$1 versiuni arhivate',
+'undeletehistory' => 'Dacă recuperaţi pagina, toate versiunile asociate vor fi adăugate retroactiv în istorie. Dacă o pagină nouă cu acelaşi nume a fost creată de la momentul ştergerii acesteia, versiunile recuperate vor apărea în istoria paginii, iar versiunea curentă a paginii nu va fi înlocuită automat de către versiunea recuperată.',
+'undeletehistorynoadmin'=> 'Acest articol a fost şters. Motivul ştergerii apare mai jos, alături de detaliile utilzatorilor care au editat această pagină înainte de ştergere. Textul prorpiu-zis al reviziilor şterse este disponibil doar administratorilor.',
+'undeleterevision' => 'Versiunea ştearsă la $1',
+'undeletebtn' => 'Recuperează',
+'undeletereset' => 'Resetează',
+'undeletecomment' => 'Comentariu:',
+'undeletedarticle' => '"[[$1]]" a fost recuperat',
+'undeletedrevisions' => '$1 revizii restaurate',
+'undeletedrevisions-files'=> '$1 {{PLURAL:$1|revizie|revizii}} şi $2 {{PLURAL:$2|fişier|fişiere}} recuperate',
+'undeletedfiles' => '$1 {{PLURAL:$1|revizie recuperată|revizii recuperate}}',
+'cannotundelete' => 'Recuperarea a eşuat; este posibil ca altcineva să fi recuperat pagina deja.',
+'undeletedpage' => '<big>\'\'\'$1 a fost recuperat\'\'\'</big>
+
+Consultaţi [[Special:Log/delete|raportul ştergerilor]] pentru a vedea toate ştergerile şi recuperările recente.',
+'namespace' => 'Spaţiul:',
+'invert' => 'Exclude spaţiul:',
+'contributions' => 'Contribuţii ale utilizatorului',
+'mycontris' => 'Contribuţiile mele',
+'contribsub' => 'Pentru $1',
+'nocontribs' => 'Nu a fost găsită nici o modificare care să satisfacă acest criteriu.',
+'ucnote' => 'Mai jos se află ultimele <b>$1</b> modificări ale utilizatorului din ultimele <b>$2</b> zile.',
+'uclinks' => 'Vezi ultimele $1 modificări; vezi ultimele $2 zile.',
+'uctop' => ' (sus)',
+'newbies' => 'nou veniţi',
+'sp-newimages-showfrom' => 'Arată imaginile noi începând cu $1',
+'sp-contributions-newest'=> 'Ultimele',
+'sp-contributions-oldest'=> 'Primele',
+'sp-contributions-newer'=> 'Următoarele $1',
+'sp-contributions-older'=> 'Anterioarele $1',
+'sp-contributions-newbies-sub'=> 'Pentru începători',
+'whatlinkshere' => 'Ce se leagă aici',
+'notargettitle' => 'Lipsă ţintă',
+'notargettext' => 'Nu ai specificat nici o pagină sau un utilizator ţintă pentru care să se efectueze această operaţiune.',
+'linklistsub' => '(Lista de legături)',
+'linkshere' => 'Următoarele pagini conţin legături către aceasta:',
+'nolinkshere' => 'Nici o pagină nu se leagă aici.',
+'isredirect' => 'pagină de redirecţionare',
+'istemplate' => 'prin includerea formatului',
+'blockip' => 'Blochează utilizator / IP',
+'blockiptext' => 'Pentru a bloca un utilizator completaţi rubricile de mai jos.<br />
+\'\'\'Respectaţi [[Project:Blocare|politica de blocare]].\'\'\'<br />
+Precizaţi motivul blocării; de exemplu indicaţi paginile vandalizate de acest utilizator.',
+'ipaddress' => 'Adresa IP',
+'ipadressorusername' => 'Adresă IP sau nume de utilizator',
+'ipbexpiry' => 'Expiră',
+'ipbreason' => 'Motiv',
+'ipbsubmit' => 'Blochează acest utilizator',
+'ipbother' => 'Alt termen',
+'ipboptions' => '15 minute:15 minutes,1 oră:1 hour,3 ore:3 hours,24 ore:24 hours,48 ore:48 hours,1 săptămână:1 week,1 lună:1 month,nelimitat:infinite',
+'ipbotheroption' => 'altul',
+'badipaddress' => 'Adresa IP este invalidă.',
+'blockipsuccesssub' => 'Utilizatorul a fost blocat',
+'blockipsuccesstext' => 'Adresa IP "$1" a fost blocată.
+<br />Vezi [[Special:Ipblocklist|lista de adrese IP şi conturi blocate]] pentru a revizui adresele blocate.',
+'unblockip' => 'Deblochează adresă IP',
+'unblockiptext' => 'Foloseşte chestionarul de mai jos pentru a restaura
+drepturile de scriere pentru o adresă IP blocată anterior..',
+'ipusubmit' => 'Deblochează adresa',
+'unblocked' => '[[User:$1|$1]] a fost deblocat',
+'ipblocklist' => 'Lista de adrese IP şi conturi blocate',
+'blocklistline' => '$1, $2 a blocat $3 ($4)',
+'infiniteblock' => 'termen nelimitat',
+'expiringblock' => 'expiră la $1',
+'ipblocklistempty' => 'Lista de blocări este goală.',
+'blocklink' => 'blochează',
+'unblocklink' => 'deblochează',
+'contribslink' => 'contribuţii',
+'autoblocker' => 'Autoblocat fiindcă foloseşti aceeaşi [[Adresă IP|adresă IP]] ca şi "$1". Motivul este "$2".',
+'blocklogpage' => 'Jurnal_blocări',
+'blocklogentry' => 'a blocat "[[$1]]" pe o perioadă de $2',
+'blocklogtext' => 'Acesta este un jurnal al acţiunilor de blocare şi deblocare.
+[[Adresă IP|Adresele IP]] blocate automat nu sunt afişate.
+Vizitaţi [[Special:Ipblocklist|lista de adrese blocate]] pentru o listă explicită a adreselor blocate în acest moment.',
+'unblocklogentry' => 'a deblocat $1',
+'range_block_disabled' => 'Abilitatea dezvoltatorilor de a bloca serii de adrese este dezactivată.',
+'ipb_expiry_invalid' => 'Dată de expirare invalidă.',
+'ip_range_invalid' => 'Serie IP invalidă.',
+'proxyblocker' => 'Blocaj de proxy',
+'proxyblockreason' => 'Adresa ta IP a fost blocată pentru că este un proxy deschis. Te rog, contactează provider-ul tău de servicii Internet sau tehnicieni IT şi informează-i asupra acestei probleme serioase de securitate.',
+'proxyblocksuccess' => 'Realizat.',
+'sorbs' => 'Lista neagră DNS a SORBS',
+'sorbsreason' => 'Adresa dumneavoastră IP este listată ca un proxy deschis în [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason'=> 'Adresa dvs. IP este listată la un proxy deschis în lista neagră DNS a [http://www.sorbs.net SORBS]. Nu vă puteţi crea un cont',
+'lockdb' => 'Blochează baza de date',
+'unlockdb' => 'Deblochează baza de date',
+'lockdbtext' => 'Blocarea bazei de date va împiedica pe toţi utilizatorii
+să modifice pagini, să-şi schimbe preferinţele, să-şi modifice listele de
+pagini urmărite şi orice alte operaţiuni care ar necesita schimări
+în baza de date.
+Te rugăm să confirmi că intenţionezi acest lucru şi faptul că vei debloca
+baza de date atunci când vei încheia operaţiunile de întreţinere.',
+'unlockdbtext' => 'Deblocarea bazei de date va permite tuturor utilizatorilor să editeze pagini, să-şi schimbe preferinţele, să-şi editeze listele de pagini urmărite şi orice alte operaţiuni care ar necesita schimări în baza de date. Te rugăm să-ţi confirmi intenţia de a face acest lucru.',
+'lockconfirm' => 'Da, chiar vreau să blochez baza de date.',
+'unlockconfirm' => 'Da, chiar vreau să deblochez baza de date.',
+'lockbtn' => 'Blochează baza de date',
+'unlockbtn' => 'Deblochează baza de date',
+'locknoconfirm' => 'Nu aţi bifat căsuţa de confirmare.',
+'lockdbsuccesssub' => 'Baza de date a fost blocată',
+'unlockdbsuccesssub' => 'Baza de date a fost deblocată',
+'lockdbsuccesstext' => 'Baza de date {{SITENAME}} a fost blocată la scriere.<br />
+Nu uita să o deblochezi după ce termini operaţiunile administrative pentru care ai blocat-o.',
+'unlockdbsuccesstext' => 'Baza de date a fost deblocată.',
+'makesysoptitle' => 'Fă dintr-un utilizator un administrator',
+'makesysoptext' => 'Acest formular este utilizat de birocraţi pentru a transforma utilizatori de rând în administratori.
+Tastează numele utilizatorului în cutie şi apasă butonul pentru a face din utilizator un administrator',
+'makesysopname' => 'Numele utilizatorului:',
+'makesysopsubmit' => 'Fă din acest utilizator un administrator',
+'makesysopok' => '<b>Utilizatorul "$1" este acum administrator</b>',
+'makesysopfail' => '<b>Utilizatorul "$1" nu a putut deveni administrator. (Ai introdus numele corect?)</b>',
+'setbureaucratflag' => 'Acordă şi drepturi de birocrat',
+'rightslog' => 'Raportul drepturilor de utilizator',
+'rightslogtext' => 'Acesta este un raport al modificărilor drepturilor utilizatorilor.',
+'rightslogentry' => 'a schimbat pentru $1 apartenenţa la un grup de la $2 la $3',
+'rights' => 'Drepturi:',
+'set_user_rights' => 'Acordă drepturi de utilizator',
+'user_rights_set' => '<b>Drepturi de utilizator pentru "$1" actualizate</b>',
+'set_rights_fail' => '<b>Nu au putut fi acordate drepturi de utilizator lui "$1". (Ai introdus numele corect?)</b>',
+'makesysop' => 'Fă dintr-un utilizator un administrator',
+'already_sysop' => 'Acest utilizator este deja administrator.',
+'already_bureaucrat' => 'Acest utilizator este deja birocrat.',
+'rightsnone' => '(niciunul)',
+'movepage' => 'Mută pagina',
+'movepagetext' => 'Puteţi folosi formularul de mai jos pentru a redenumi
+o pagină, mutându-i toată istoria sub noul nume.
+Pagina veche va deveni o pagină de redirecţionare către pagina nouă.
+Legăturile către pagina veche nu vor fi redirecţionate către cea nouă;
+nu uitaţi să verificaţi dacă nu există redirecţionări duble sau invalide.
+
+Te rugăm să reţineţi că sunteţi responsabil(ă) pentru a face legăturile vechi să rămână valide.
+
+Reţineţi că pagina \'\'\'nu va fi mutată\'\'\' dacă există deja o
+pagină cu noul titlu, în afară de cazul că este complet goală sau este
+o redirecţionare şi în plus nu are nici o istorie de modificare.
+Cu alte cuvinte, veţi putea muta înapoi o pagină pe care aţi mutat-o
+greşit, dar nu veţi putea suprascrie o pagină validă existentă prin
+mutarea alteia.
+
+<b>ATENŢIE!</b>
+Aceasta poate fi o schimbare drastică şi neaşteptată pentru o pagină populară;
+vă rugăm, să vă asiguraţi că înţelegeţi toate consecinţele înainte de a continua.',
+'movepagetalktext' => 'Pagina asociată de discuţii, dacă există, va fi mutată
+automat odată cu aceasta \'\'\'afară de cazul că\'\'\':
+* Mutaţi pagina în altă secţiune a {{SITENAME}}
+* Există deja o pagină de discuţii cu conţinut (care nu este goală), sau
+* Nu confirmi căsuţa de mai jos.
+
+În oricare din cazurile de mai sus va trebui să muţi sau să unifici
+manual paginile de discuţii, dacă doreşti acest lucru.',
+'movearticle' => 'Mută pagina',
+'movenologin' => 'Nu eşti autentificat',
+'movenologintext' => 'Trebuie să fii un utilizator înregistrat şi să te [[Special:Userlogin|autentifici]] pentru a muta o pagină.',
+'newtitle' => 'Titlul nou',
+'movepagebtn' => 'Mută pagina',
+'pagemovedsub' => 'Pagina a fost mutată',
+'pagemovedtext' => 'Pagina "[[$1]]" a fost mutată la "[[$2]]".',
+'articleexists' => 'O pagină cu acelaşi nume există deja, sau numele pe care l-ai ales este invalid. Te rugăm să alegi un alt nume.',
+'talkexists' => '\'\'\'Pagina în sine a fost mutată, dar pagina de discuţii nu a putut fi mutată deoarece deja există o alta cu acelaşi nume. Te rugăm să unifici manual cele două pagini de discuţii.\'\'\'',
+'movedto' => 'mutată la',
+'movetalk' => 'Mută şi pagina de "discuţii" dacă se poate.',
+'talkpagemoved' => 'Şi pagina de discuţii asociată a fost mutată.',
+'talkpagenotmoved' => 'Pagina asociată de discuţii <strong>nu</strong> a fost mutată.',
+'1movedto2' => '[[$1]] a fost mutată la [[$2]]',
+'1movedto2_redir' => '[[$1]] a fost mutată la [[$2]] prin redirect',
+'movelogpage' => 'Raport mutări',
+'movelogpagetext' => 'Mai jos se află o listă cu paginile mutate.',
+'movereason' => 'Motiv',
+'revertmove' => 'revenire',
+'delete_and_move' => 'Şterge şi mută',
+'delete_and_move_text' => '==Ştergere necesară==
+
+Articolul de destinaţie "[[$1]]" există deja. Doriţi să îl ştergeţi pentru a face loc mutării?',
+'delete_and_move_confirm'=> 'Da, şterge pagina.',
+'delete_and_move_reason'=> 'Şters pentru a face loc mutării',
+'selfmove' => 'Titlurile sursei şi ale destinaţiei sunt aceleaşi; nu puteţi muta o pagină peste ea însăşi.',
+'immobile_namespace' => 'Titlul destinaţiei este al unui tip special; nu se pot muta pagini în acel spaţiu de nume.',
+'export' => 'Exportă pagini',
+'exporttext' => 'Poţi exporta textul şi istoria unei pagini anume sau ale unui grup de pagini în XML. Acesta poate fi apoi importat în alt Wiki care rulează software MediaWiki, poate fi transformat sau păstrat pur şi simplu fiindcă doreşti tu să-l păstrezi.',
+'exportcuronly' => 'Include numai versiunea curentă, nu şi toată istoria',
+'exportnohistory' => '---- \'\'\'Notă:\'\'\' exportarea versiunii complete a paginilor prin acest formular a fost scoasă din uz din motive de performanţă.',
+'export-submit' => 'Exportă',
+'allmessages' => 'Toate mesajele',
+'allmessagesname' => 'Nume',
+'allmessagesdefault' => 'Textul standard',
+'allmessagescurrent' => 'Textul curent',
+'allmessagestext' => 'Aceasta este lista completă a mesajelor disponibile în domeniul "MediaWiki:"',
+'allmessagesnotsupportedUI'=> 'Interfaţa curentă de limbă <b>$1</b> nu este suportată de Special:AllMessages la acest sit.',
+'allmessagesnotsupportedDB'=> '\'\'\'Special:Allmessages\'\'\' nu poate fi folosit deoarece \'\'\'$wgUseDatabaseMessages\'\'\' este închisă.',
+'allmessagesfilter' => 'Filtrare în funcţie de titlul mesajului:',
+'allmessagesmodified' => 'Arată doar mesajele modificate.',
+'thumbnail-more' => 'Extinde',
+'missingimage' => '<b>Imagine lipsă</b><br />
+<i>$1</i>',
+'filemissing' => 'Fişier lipsă',
+'thumbnail_error' => 'Eroare la generarea previzualizării: $1',
+'import' => 'Importă pagini',
+'importinterwiki' => 'Import transwiki',
+'import-interwiki-text' => 'Selectează un wiki şi titlul paginii care trebuie importate. Datele reviziilor şi numele editorilor vor fi salvate. Toate acţiunile de import transwiki pot fi găsite la [[Special:Log/import|log import]]',
+'import-interwiki-history'=> 'Copiază toate versiunile istoricului acestei pagini',
+'import-interwiki-submit'=> 'Importă',
+'importtext' => 'Te rog exportă fişierul din sursa wiki folosind funcţia Special:Export, salvează-l pe discul tău şi trimite-l aici.',
+'importstart' => 'Se importă paginile...',
+'import-revision-count' => '$1 revizie(i)',
+'importnopages' => 'Nu există pagini de importat.',
+'importfailed' => 'Import eşuat: $1',
+'importunknownsource' => 'Tipul sursei de import este necunoscut',
+'importcantopen' => 'Fişierul importat nu a putut fi deschis',
+'importbadinterwiki' => 'Legătură interwiki proastă',
+'importnotext' => 'Gol sau fără text',
+'importsuccess' => 'Import reuşit!',
+'importhistoryconflict' => 'Există istorii contradictorii (se poate să fi importat această pagină înainte)',
+'importnosources' => 'Nici o sursă de import transwiki a fost definită şi încărcările directe ale istoricului sunt oprite.',
+'importnofile' => 'Nici un fişier pentru import nu a fost încărcat.',
+'importuploaderror' => 'Încărcarea fişierului de import nu a avut succes; probabil mărimea fişierului este mai mare decât mărimea maximă acceptată pentru fişiere.',
+'importlogpage' => 'Log import',
+'importlogpagetext' => 'Imoprturi administrative de pagini de la alte wiki, cu istoricul editărilor.',
+'import-logentry-upload'=> '[[$1]] importate prin upload',
+'import-logentry-upload-detail'=> '$1 revizie(i)',
+'import-logentry-interwiki'=> 'transwikificat $1',
+'import-logentry-interwiki-detail'=> '$1 revizie(i) de la $2',
+'accesskey-search' => 'c',
+'accesskey-minoredit' => 'm',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'o',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'Căutare în {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Marcaţi această modificare ca fiind minoră [alt-i]',
+'tooltip-save' => 'Salvează modificările tale [alt-s]',
+'tooltip-preview' => 'Previzualizarea modificărilor tale, foloseşte-o te rog înainte de a salva! [alt-p]',
+'tooltip-diff' => 'Arată ce modificări ai făcut textului. [alt-v]',
+'tooltip-compareselectedversions'=> 'Vezi diferenţele între cele două versiuni selectate de pe această pagină. [alt-v]',
+'tooltip-watch' => 'Adaugă această pagină la lista mea de pagini urmărite [alt-w]',
+'common.css' => '/** CSS plasate aici vor fi aplicate tuturor apariţiilor */',
+'monobook.css' => '/* modificaţi acest fişier pentru a adapta înfăţişarea monobook-ului pentru tot situl*/',
+'nodublincore' => 'Metadatele Dublin Core RDF sunt dezactivate pentru acest server.',
+'nocreativecommons' => 'Metadatele Creative Commons RDF dezactivate pentru acest server.',
+'notacceptable' => 'Serverul wiki nu poate oferi date într-un format pe care clientul tău să-l poată citi.',
+'anonymous' => 'Utilizator(i) anonimi ai {{SITENAME}}',
+'siteuser' => 'Utilizator {{SITENAME}} $1',
+'lastmodifiedatby' => 'Această pagină a fost modificată $2, $1 de către $3.',
+'and' => 'şi',
+'othercontribs' => 'Bazat pe munca lui $1.',
+'others' => 'alţii',
+'siteusers' => 'Utilizator(i) {{SITENAME}} $1',
+'creditspage' => 'Credenţiale',
+'nocredits' => 'Nu există credenţiale disponibile pentru această pagină.',
+'spamprotectiontitle' => 'Filtru de protecţie spam',
+'spamprotectiontext' => 'Pagina pe care doriţi să o salvaţi a fost blocată de filtrul spam. Aceasta se datorează probabil unei legături spre un site extern. Aţi putea verifica următoarea expresie regulată:',
+'spamprotectionmatch' => 'Următorul text a fost oferit de filtrul de spam: $1',
+'subcategorycount' => 'Această categorie conţine {{PLURAL:$1|o subcategorie|$1 subcategorii}}.',
+'categoryarticlecount' => 'Această categorie conţine {{PLURAL:$1|un articol|$1 articole}}.',
+'listingcontinuesabbrev'=> ' cont.',
+'spambot_username' => 'Curăţarea de spam a MediaWiki',
+'spam_reverting' => 'Revenire la ultima versiune care nu conţine legături către $1',
+'spam_blanking' => 'Toate reviziile conţinând legături către $1, au eşuat',
+'infosubtitle' => 'Informaţii pentru pagină',
+'numedits' => 'Număr de modificări (articole): $1',
+'numtalkedits' => 'Număr de modificări (pagina de discuţii): $1',
+'numwatchers' => 'Număr de utilizatori care urmăresc: $1',
+'numauthors' => 'Număr de autori distincţi (articole): $1',
+'numtalkauthors' => 'Număr de autori distincţi (pagini de discuţii): $1',
+'mw_math_png' => 'Întodeauna afişează PNG',
+'mw_math_simple' => 'HTML pentru formule simple, altfel PNG',
+'mw_math_html' => 'HTML dacă este posibil, altfel PNG',
+'mw_math_source' => 'Lasă ca TeX (pentru browser-ele text)',
+'mw_math_modern' => 'Recomandat pentru browser-ele moderne',
+'mw_math_mathml' => 'MathML dacă este posibil (experimental)',
+'markaspatrolleddiff' => 'Marchează ca patrulat',
+'markaspatrolledtext' => 'Marchează acest articol ca patrulat',
+'markedaspatrolled' => 'A fost marcat ca patrulat',
+'markedaspatrolledtext' => 'Modificarea selectată a fost marcată ca patrulată.',
+'rcpatroldisabled' => 'Opţiunea de patrulare a modificărilor recente este dezactivată',
+'rcpatroldisabledtext' => 'Patrularea modificărilor recente este în prezent dezactivată.',
+'markedaspatrollederror'=> 'Nu se poate marca ca patrulat',
+'markedaspatrollederrortext'=> 'Trebuie să specificaţi o revizie care să fie marcată ca patrulată.',
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'history-prevlink\'] = new Array(\'-\',\'Previous\');
+ta[\'history-nextlink\'] = new Array(\'+\',\'Next\');
+ta[\'pt-userpage\'] = new Array(\'.\',\'Pagina mea de utilizator\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Pagina de utilizator pentru adresa IP curentă\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Pagina mea de discuţii\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Discuţii despre editări pentru adresa IP curentă\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Preferinţele mele\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Lista paginilor pe care le monitorizez.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Listă de contribuţii\');
+ta[\'pt-login\'] = new Array(\'o\',\'Eşti încurajat să te autentifici, deşi acest lucru nu este obligatoriu.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Eşti încurajat să te autentifici, deşi acest lucru nu este obligatoriu.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Închide sesiunea\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Discuţie despre articol\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Poţi edita această pagină. Te rugăm să previzualizezi conţinutul înainte de salvare.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Adaugă un comentariu acestei discuţii.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Aceasta pagina este protejată. Poţi sa vezi doar codul sursă.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Versiuni vechi ale acestui document.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Protejează acest document.\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Şterge acest document.\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Restaureaza editările făcute acestui document, înainte să fi fost şters.\');
+ta[\'ca-move\'] = new Array(\'m\',\'Mută acest document.\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Nu aveţi permisiunea să mutaţi acest document.\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Adaugă acest document în lista ta de monitorizare.\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Şterge acest document din lista ta de monitorizare.\');
+ta[\'search\'] = new Array(\'f\',\'Caută în acest wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'Pagina principală\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Vizitează pagina principală\');
+ta[\'n-portal\'] = new Array(\'\',\'Despre proiect, ce poţi face tu, unde găseşti soluţii.\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Găseşte informaţii despre evenimente curente\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Lista ultimelor schimbări realizate în acest wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Mergi spre o pagină aleatoare\');
+ta[\'n-help\'] = new Array(\'\',\'Locul în care găseşti ajutor.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Sprijină-ne\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lista tuturor paginilor wiki care conduc spre această pagină\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Schimbări recente în legătură cu această pagină\');
+ta[\'feed-rss\'] = new Array(\'\',\'Alimentează fluxul RSS pentru această pagină\'); ta[\'feed-atom\'] = new Array(\'\',\'Alimentează fluxul Atom pentru această pagină\'); ta[\'t-contributions\'] = new Array(\'\',\'Vezi lista de contribuţii ale acestui utilizator\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Trimite un e-mail acestui utilizator\');
+ta[\'t-upload\'] = new Array(\'u\',\'Trimite imagini sau fişiere media\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Lista tuturor paginilor speciale\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vezi articolul\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vezi pagina de utilizator\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Vezi pagina media\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Aceasta este o pagină specială, (nu) poţi edita pagina în sine.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Vezi pagina proiectului\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Vezi pagina imaginii\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vezi mesajul de sistem\'); ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vezi formatul\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vezi pagina de ajutor\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vezi categoria\');',
+'deletedrevision' => 'A fost ştearsă vechea revizie $1.',
+'previousdiff' => '← Diferenţa anterioară',
+'nextdiff' => 'Diferenţa următoare →',
+'imagemaxsize' => 'Limitează imaginile pe paginile de descriere la:',
+'thumbsize' => 'Mărime thumbnail:',
+'showbigimage' => 'Descarcă versiunea cu rezoluţie înaltă ($1x$2, $3 KB)',
+'newimages' => 'Galeria de imagini noi',
+'showhidebots' => '($1 roboţi)',
+'noimages' => 'Nimic de văzut.',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+'specialloguserlabel' => 'Utilizator:',
+'speciallogtitlelabel' => 'Titlu:',
+'passwordtooshort' => 'Parola dumneavoastră este prea scurtă. Trebuie să aibă cel puţin $1 caractere.',
+'mediawarning' => '\'\'\'Atenţie\'\'\': Acest fişier poate conţine cod maliţios, executându-l, sistemul dvs. poate fi compromis.<hr />',
+'fileinfo' => '$1KB, tip MIME: <code>$2</code>',
+'metadata' => 'Informaţii',
+'metadata-help' => 'Acest fişier conţine informaţii suplimentare, introduse probabil de aparatul fotografic digital sau scannerul care l-a generat. Dacă fişierul a fost modificat între timp, este posibil ca unele detalii să nu mai fie valabile.',
+'metadata-expand' => 'Afişează detalii suplimentare',
+'metadata-collapse' => 'Ascunde detalii suplimentare',
+'exif-imagewidth' => 'Lăţime',
+'exif-imagelength' => 'Înălţime',
+'exif-bitspersample' => 'Biţi pe componentă',
+'exif-compression' => 'Metodă de comprimare',
+'exif-photometricinterpretation'=> 'Compoziţia pixelilor',
+'exif-orientation' => 'Orientare',
+'exif-samplesperpixel' => 'Numărul de componente',
+'exif-planarconfiguration'=> 'Aranjarea datelor',
+'exif-ycbcrsubsampling' => 'Mostră din fracţia Y/C',
+'exif-ycbcrpositioning' => 'Poziţionarea Y şi C',
+'exif-xresolution' => 'Rezoluţie orizontală',
+'exif-yresolution' => 'Rezoluţie verticală',
+'exif-resolutionunit' => 'Unitate de rezoluţie pentru X şi Y',
+'exif-stripoffsets' => 'Locaţia datelor imaginii',
+'exif-stripbytecounts' => 'Biţi corespunzători benzii comprimate',
+'exif-jpeginterchangeformat'=> 'Offset pentru JPEG SOI',
+'exif-jpeginterchangeformatlength'=> 'Biţi de date JPEG',
+'exif-transferfunction' => 'Funcţia de transfer',
+'exif-whitepoint' => 'Cromaticitatea punctului alb',
+'exif-ycbcrcoefficients'=> 'Tăria culorii coeficienţilor matricei de transformare',
+'exif-referenceblackwhite'=> 'Perechile de valori de referinţă albe şi negre',
+'exif-datetime' => 'Data şi ora modificării fişierului',
+'exif-imagedescription' => 'Titlul imaginii',
+'exif-make' => 'Producătorul aparatului foto',
+'exif-model' => 'Modelul aparatului foto',
+'exif-software' => 'Software folosit',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Titularul drepturilor de autor',
+'exif-exifversion' => 'Versiune exif',
+'exif-flashpixversion' => 'Versiune susţinută de Flashpix',
+'exif-colorspace' => 'Spaţiu de culoare',
+'exif-componentsconfiguration'=> 'Semnificaţia componentelor',
+'exif-compressedbitsperpixel'=> 'Mod de comprimare a imaginii',
+'exif-pixelydimension' => 'Lăţimea validă a imaginii',
+'exif-pixelxdimension' => 'Valind image height',
+'exif-makernote' => 'Observaţiile producătorului',
+'exif-usercomment' => 'Comentariile utilizatorilor',
+'exif-relatedsoundfile' => 'Fişierul audio asemănător',
+'exif-datetimeoriginal' => 'Data şi ora producerii imaginii',
+'exif-datetimedigitized'=> 'Data şi ora digitizării',
+'exif-subsectime' => 'Data/Ora milisecunde',
+'exif-subsectimeoriginal'=> 'Data/Ora/Original milisecunde',
+'exif-subsectimedigitized'=> 'Milisecunde DateTimeDigitized',
+'exif-exposuretime' => 'Timp de expunere',
+'exif-exposuretime-format'=> '$1 sec ($2)',
+'exif-fnumber' => 'Diafragmă',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Program de expunere',
+'exif-spectralsensitivity'=> 'Sensibilitate spectrală',
+'exif-isospeedratings' => 'Evaluarea vitezei ISO',
+'exif-oecf' => 'Factorul de conversie optoelectronic',
+'exif-shutterspeedvalue'=> 'Viteza de închidere',
+'exif-aperturevalue' => 'Diafragmă',
+'exif-brightnessvalue' => 'Luminozitate',
+'exif-exposurebiasvalue'=> 'Ajustarea expunerii',
+'exif-subjectdistance' => 'Distanţa faţă de subiect',
+'exif-meteringmode' => 'Forma de măsurare',
+'exif-lightsource' => 'Sursă de lumină',
+'exif-flash' => 'Bliţ',
+'exif-focallength' => 'Distanţa focală a obiectivului',
+'exif-focallength-format'=> '$1 mm',
+'exif-subjectarea' => 'Suprafaţa subiectului',
+'exif-flashenergy' => 'Energie flash',
+'exif-spatialfrequencyresponse'=> 'Răspunsul frecvenţei spaţiale',
+'exif-focalplanexresolution'=> 'Rezoluţia focală plană X',
+'exif-focalplaneyresolution'=> 'Rezoluţia focală plană Y',
+'exif-focalplaneresolutionunit'=> 'Unitatea de măsură pentru rezoluţia focală plană',
+'exif-subjectlocation' => 'Locaţia subiectului',
+'exif-exposureindex' => 'Indexul expunerii',
+'exif-sensingmethod' => 'Metoda sensibilă',
+'exif-filesource' => 'Fişier sursă',
+'exif-scenetype' => 'Tipul scenei',
+'exif-cfapattern' => 'Mozaic CFA (filtre color)',
+'exif-customrendered' => 'Prelucrarea imaginii',
+'exif-exposuremode' => 'Mod de expunere',
+'exif-whitebalance' => 'Balanţa albă',
+'exif-digitalzoomratio' => 'Raportul zoom-ului digital',
+'exif-focallengthin35mmfilm'=> 'Distanţă focală pentru film de 35 mm',
+'exif-scenecapturetype' => 'Tipul de surprindere a scenei',
+'exif-gaincontrol' => 'Controlul scenei',
+'exif-contrast' => 'Contrast',
+'exif-saturation' => 'Saturaţie',
+'exif-sharpness' => 'Ascuţime',
+'exif-devicesettingdescription'=> 'Descrierea reglajelor aparatului',
+'exif-imageuniqueid' => 'Identificarea imaginii unice',
+'exif-gpsversionid' => 'Versiunea de conversie GPS',
+'exif-gpslatituderef' => 'Latitudine nordică sau sudică',
+'exif-gpslatitude' => 'Latitudine',
+'exif-gpslongituderef' => 'Longitudine estică sau vestică',
+'exif-gpslongitude' => 'Longitudine',
+'exif-gpsaltituderef' => 'Indicarea altitudinii',
+'exif-gpsaltitude' => 'Altitudine',
+'exif-gpstimestamp' => 'ora GPS (ceasul atomic)',
+'exif-gpssatellites' => 'Sateliţi utilizaţi pentru măsurare',
+'exif-gpsstatus' => 'Starea receptorului',
+'exif-gpsmeasuremode' => 'Mod de măsurare',
+'exif-gpsdop' => 'Precizie de măsurare',
+'exif-gpsspeedref' => 'Unitatea de măsură pentru viteză',
+'exif-gpsspeed' => 'Viteza receptorului GPS',
+'exif-gpstrackref' => 'Referinţă pentru direcţia de mişcare',
+'exif-gpstrack' => 'Direcţie de mişcare',
+'exif-gpsimgdirectionref'=> 'Referinţă pentru direcţia imaginii',
+'exif-gpsimgdirection' => 'Direcţia imaginii',
+'exif-gpsmapdatum' => 'Expertiza geodezică a datelor utilizate',
+'exif-gpsdestlatituderef'=> 'Referinţă pentru latitudinea destinaţiei',
+'exif-gpsdestlatitude' => 'Destinaţia latitudinală',
+'exif-gpsdestlongituderef'=> 'Referinţă pentru longitudinea destinaţiei',
+'exif-gpsdestlongitude' => 'Longitudinea destinaţiei',
+'exif-gpsdestbearingref'=> 'Referinţă pentru raportarea destinaţiei',
+'exif-gpsdestbearing' => 'Raportarea destinaţiei',
+'exif-gpsdestdistanceref'=> 'Referinţă pentru distanţa până la destinaţie',
+'exif-gpsdestdistance' => 'Distanţa până la destinaţie',
+'exif-gpsprocessingmethod'=> 'Numele metodei de procesare GPS',
+'exif-gpsareainformation'=> 'Numele domeniului GPS',
+'exif-gpsdatestamp' => 'Data GPS',
+'exif-gpsdifferential' => 'Corecţia diferenţială GPS',
+'exif-compression-1' => 'Necomprimată',
+'exif-compression-6' => 'JPEG',
+'exif-photometricinterpretation-2'=> 'RGB',
+'exif-photometricinterpretation-6'=> 'YCbCr',
+'exif-orientation-1' => 'Normală',
+'exif-orientation-2' => 'Oglindită orizontal',
+'exif-orientation-3' => 'Rotită cu 180°',
+'exif-orientation-4' => 'Oglindită vertical',
+'exif-orientation-5' => 'Rotită 90° în sens opus acelor de ceasornic şi oglindită vertical',
+'exif-orientation-6' => 'Rotită 90° în sensul acelor de ceasornic',
+'exif-orientation-7' => 'Rotită 90° în sensul acelor de ceasornic şi oglindită vertical',
+'exif-orientation-8' => 'Rotită 90° în sens opus acelor de ceasornic',
+'exif-planarconfiguration-1'=> 'format compact',
+'exif-planarconfiguration-2'=> 'format plat',
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h'=> 'FFFF.H',
+'exif-componentsconfiguration-0'=> 'neprecizat',
+'exif-componentsconfiguration-1'=> 'Y',
+'exif-componentsconfiguration-2'=> 'Cb',
+'exif-componentsconfiguration-3'=> 'Cr',
+'exif-componentsconfiguration-4'=> 'R',
+'exif-componentsconfiguration-5'=> 'G',
+'exif-componentsconfiguration-6'=> 'B',
+'exif-exposureprogram-0'=> 'Neprecizat',
+'exif-exposureprogram-1'=> 'Manual',
+'exif-exposureprogram-2'=> 'Program normal',
+'exif-exposureprogram-3'=> 'Prioritate diafragmă',
+'exif-exposureprogram-4'=> 'Prioritate timp',
+'exif-exposureprogram-5'=> 'Program creativ (prioritate dată profunzimii)',
+'exif-exposureprogram-6'=> 'Program acţiune (prioritate dată timpului de expunere scurt)',
+'exif-exposureprogram-7'=> 'Mod portret (focalizare pe subiect şi fundal neclar)',
+'exif-exposureprogram-8'=> 'Mod peisaj (focalizare pe fundal)',
+'exif-subjectdistance-value'=> '$1 metri',
+'exif-meteringmode-0' => 'Necunoscut',
+'exif-meteringmode-1' => 'Medie',
+'exif-meteringmode-3' => 'Punct',
+'exif-meteringmode-4' => 'MultiPunct',
+'exif-meteringmode-5' => 'Model',
+'exif-meteringmode-6' => 'Parţial',
+'exif-meteringmode-255' => 'Alta',
+'exif-lightsource-0' => 'Necunoscută',
+'exif-lightsource-1' => 'Lumină solară',
+'exif-lightsource-2' => 'Fluorescent',
+'exif-lightsource-3' => 'Tungsten (lumină incandescentă)',
+'exif-lightsource-4' => 'Flash',
+'exif-lightsource-9' => 'Vreme frumoasă',
+'exif-lightsource-10' => 'Cer noros',
+'exif-lightsource-11' => 'Umbră',
+'exif-lightsource-12' => 'Fluorescent luminos (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Fluorescent luminos alb (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Fluorescent alb rece (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Fluorescent alb (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Lumină standard A',
+'exif-lightsource-18' => 'Lumină standard B',
+'exif-lightsource-19' => 'Lumină standard C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'Lumină artificială normată ISO în studio',
+'exif-lightsource-255' => 'Altă sursă de lumină',
+'exif-focalplaneresolutionunit-2'=> 'ţoli',
+'exif-sensingmethod-1' => 'Nedefinit',
+'exif-sensingmethod-2' => 'Senzorul suprafeţei color one-chip',
+'exif-sensingmethod-3' => 'Senzorul suprafeţei color two-chip',
+'exif-sensingmethod-4' => 'Senzorul suprafeţei color three-chip',
+'exif-sensingmethod-5' => 'Senzorul suprafeţei color secvenţiale',
+'exif-sensingmethod-7' => 'Senzor triliniar',
+'exif-sensingmethod-8' => 'Senzorul linear al culorii secvenţiale',
+'exif-filesource-3' => 'DSC',
+'exif-scenetype-1' => 'O imagine fotografiată direct',
+'exif-customrendered-0' => 'Prelucrare normală',
+'exif-customrendered-1' => 'Prelucrare nestandard',
+'exif-exposuremode-0' => 'Expunere automată',
+'exif-exposuremode-1' => 'Expunere manuală',
+'exif-exposuremode-2' => 'Serie automată de expuneri',
+'exif-whitebalance-0' => 'Auto-balanţa albă',
+'exif-whitebalance-1' => 'Balanţa manuală albă',
+'exif-scenecapturetype-0'=> 'Standard',
+'exif-scenecapturetype-1'=> 'Portret',
+'exif-scenecapturetype-2'=> 'Portret',
+'exif-scenecapturetype-3'=> 'Scenă nocturnă',
+'exif-gaincontrol-0' => 'Niciuna',
+'exif-gaincontrol-1' => 'Avantajul scăzut de sus',
+'exif-gaincontrol-2' => 'Avantajul mărit de sus',
+'exif-gaincontrol-3' => 'Avantajul scăzut de jos',
+'exif-gaincontrol-4' => 'Avantajul mărit de jos',
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'Redus',
+'exif-contrast-2' => 'Mărit',
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Saturaţie redusă',
+'exif-saturation-2' => 'Saturaţie ridicată',
+'exif-sharpness-0' => 'Normal',
+'exif-sharpness-1' => 'Uşor',
+'exif-sharpness-2' => 'Tare',
+'exif-subjectdistancerange-0'=> 'Necunoscut',
+'exif-subjectdistancerange-1'=> 'Macro',
+'exif-subjectdistancerange-2'=> 'Apropiat',
+'exif-subjectdistancerange-3'=> 'Îndepărtat',
+'exif-gpslatitude-n' => 'latitudine nordică',
+'exif-gpslatitude-s' => 'latitudine sudică',
+'exif-gpslongitude-e' => 'longitudine estică',
+'exif-gpslongitude-w' => 'longitudine vestică',
+'exif-gpsstatus-a' => 'Măsurare în curs',
+'exif-gpsstatus-v' => 'Măsurarea interoperabilităţii',
+'exif-gpsmeasuremode-2' => 'măsurătoare bidimensională',
+'exif-gpsmeasuremode-3' => 'măsurătoare tridimensională',
+'exif-gpsspeed-k' => 'Kilometri pe oră',
+'exif-gpsspeed-m' => 'Mile pe oră',
+'exif-gpsspeed-n' => 'Noduri',
+'exif-gpsdirection-t' => 'Direcţia reală',
+'exif-gpsdirection-m' => 'Direcţie magnetică',
+'edit-externally' => 'Editează acest fişier folosind o aplicaţie externă.',
+'edit-externally-help' => 'Vedeţi [http://meta.wikimedia.org/wiki/Help:External_editors instrucţiuni de instalare] pentru mai multe informaţii.',
+'recentchangesall' => 'tot',
+'imagelistall' => 'toate',
+'watchlistall1' => 'toate',
+'watchlistall2' => 'toate',
+'namespacesall' => 'toate',
+'confirmemail' => 'Confirmă adresa de email',
+'confirmemail_text' => 'Acest wiki necesită validarea adresei de email înaintea folosirii funcţiilor email. Apăsaţi butonul de dedesupt pentru a trimite un email de confirmare către adresa dvs. Acesta va include o legătură care va conţine codul; încărcaţi legătura în browser pentru a valida adresa de email.',
+'confirmemail_send' => 'Trimite un cod de confirmare',
+'confirmemail_sent' => 'E-mailul de confirmare a fost trimis.',
+'confirmemail_sendfailed'=> 'Nu am putut trimite e-mailul de confirmare. Verificaţi adresa după caractere invalide.',
+'confirmemail_invalid' => 'Cod de confirmare invalid. Acest cod poate fi expirat.',
+'confirmemail_needlogin'=> 'Trebuie să vă $1 pentru a vă confirma adresa de email.',
+'confirmemail_success' => 'Adresa de email a fost confirmată. Vă puteţi autentifica şi bucura de wiki.',
+'confirmemail_loggedin' => 'Adresa de email a fost confirmată.',
+'confirmemail_error' => 'Ceva nu a funcţionat la salvarea confirmării.',
+'confirmemail_subject' => 'Confirmare adresă email la {{SITENAME}}',
+'confirmemail_body' => 'Cineva, probabil dumneavoastră de la adresa IP $1, şi-a înregistrat un cont "$2" cu această adresă de email la {{SITENAME}}.
+
+Pentru a confirma că acest cont aparţine într-adevăr dumneavoastră şi să vă activaţi funcţionalităţile email la {{SITENAME}}, deschideţi această legătură în browser:
+
+$3
+
+Dacă *nu* sunteţi dumneavoastră, nu deschideţi legătura. Codul de confirmare va expira la $4.',
+'tryexact' => 'Încearcă varianta exactă',
+'searchfulltext' => 'Caută textul întreg',
+'createarticle' => 'Crează articol',
+'scarytranscludedisabled'=> '[Transcluderea interwiki este dezactivată]',
+'scarytranscludefailed' => '[Şiretlicul formatului a dat greş pentru $1; ne pare rău]',
+'scarytranscludetoolong'=> '[URL-ul este prea lung; ne pare rău]',
+'trackbackbox' => '<div id=\'mw_trackbacks\'>
+Urmăritori la acest articol:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Şterge])',
+'trackbacklink' => 'Urmăritor',
+'trackbackdeleteok' => 'Urmăritorul a fost şters cu succes.',
+'deletedwhileediting' => 'Atenţie: Această pagină a fost ştearsă după ce ai început să o modifici!',
+'confirmrecreate' => 'Utilizatorul [[User:$1|$1]] ([[User talk:$1|discuţie]]) a şters acest articol după ce aţi început să contribuţi la el din motivul:
+: \'\'$2\'\'
+Vă rugăm să confirmaţi faptul că într-adevăr doriţi să recreaţi acest articol.',
+'recreate' => 'Recreează',
+'tooltip-recreate' => 'Recreează',
+'unit-pixel' => 'px',
+'redirectingto' => 'Redirecţionând la [[$1]]...',
+'confirm_purge' => 'Doriţi să reîncărcaţi pagina? $1',
+'confirm_purge_button' => 'Da',
+'youhavenewmessagesmulti'=> 'Aveţi mesaje noi la $1',
+'searchcontaining' => 'Caută articolele care conţin \'\'$1\'\'.',
+'searchnamed' => 'Caută articole cu numele \'\'$1\'\'.',
+'articletitles' => 'Articole începând cu \'\'$1\'\'',
+'hideresults' => 'Ascunde rezultatele',
+'displaytitle' => '(Legătură la această pagină ca [[$1]])',
+'loginlanguagelabel' => 'Limba: $1',
+);
+?>
diff --git a/languages/messages/MessagesRu.php b/languages/messages/MessagesRu.php
new file mode 100644
index 000000000000..45d11ec5b81c
--- /dev/null
+++ b/languages/messages/MessagesRu.php
@@ -0,0 +1,2259 @@
+<?php
+/** Russian (русский язык)
+ *
+ * Based on MessagesEn.php revision 18716 (2007-01-01)
+ * and ru.wikipedia MediaWiki namespace (2007-01-01)
+ *
+ * Maintainer: Alexander Sigachov (alexander.sigachov на Google Mail)
+ *
+ * ВНИМАНИЕ! НЕ РЕДАКТИРУЙТЕ ЭТОТ ФАЙЛ!
+ *
+ * Если необходимо внести изменения в перевод отдельных строк интерфейса,
+ * сделайте это посредством редактирования страниц вида «MediaWiki:*».
+ * Их список можно найти на странице «Special:Allmessages».
+ *
+ */
+
+$separatorTransformTable = array(
+ ',' => "\xc2\xa0", # nbsp
+ '.' => ','
+);
+
+$fallback8bitEncoding = 'windows-1251';
+$linkPrefixExtension = true;
+
+$namespaceNames = array(
+ NS_MEDIA => 'Медиа',
+ NS_SPECIAL => 'Служебная',
+ NS_MAIN => '',
+ NS_TALK => 'Обсуждение',
+ NS_USER => 'Участник',
+ NS_USER_TALK => 'Обсуждение_участника',
+ #NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Обсуждение_{{grammar:genitive|$1}}',
+ NS_IMAGE => 'Изображение',
+ NS_IMAGE_TALK => 'Обсуждение_изображения',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Обсуждение_MediaWiki',
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Обсуждение_шаблона',
+ NS_HELP => 'Справка',
+ NS_HELP_TALK => 'Обсуждение_справки',
+ NS_CATEGORY => 'Категория',
+ NS_CATEGORY_TALK => 'Обсуждение_категории',
+);
+
+
+$quickbarSettings = array(
+ 'Не показывать', 'Неподвижная слева', 'Неподвижная справа', 'Плавающая слева', 'Плавающая справа'
+);
+
+$skinNames = array(
+ 'standard' => 'Стандартное',
+ 'nostalgia' => 'Ностальгия',
+ 'cologneblue' => 'Кёльнская тоска',
+ 'davinci' => 'Да Винчи',
+ 'mono' => 'Моно',
+ 'monobook' => 'Моно-книга',
+ 'myskin' => 'Своё',
+ 'chick' => 'Цыпа'
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'xg j, Y',
+ 'mdy both' => 'H:i, xg j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j xg Y',
+ 'dmy both' => 'H:i, j xg Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y xg j',
+ 'ymd both' => 'H:i, Y xg j',
+
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+
+);
+
+$bookstoreList = array(
+ 'Поиск по библиотекам «Сигла»' => 'http://www.sigla.ru/results.jsp?f=7&t=3&v0=5030030980&f=1003&t=1&v1=&f=4&t=2&v2=&f=21&t=3&v3=&f=1016&t=3&v4=&f=1016&t=3&v5=&bf=4&b=&d=0&ys=&ye=&lng=&ft=&mt=&dt=&vol=&pt=&iss=&ps=&pe=&tr=&tro=&cc=&i=1&v=tagged&s=0&ss=0&st=0&i18n=ru&rlf=&psz=20&bs=20&ce=hJfuypee8JzzufeGmImYYIpZKRJeeOeeWGJIZRrRRrdmtdeee88NJJJJpeeefTJ3peKJJ3UWWPtzzzzzzzzzzzzzzzzzbzzvzzpy5zzjzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzztzzzzzzzbzzzzzzzzzzzzzzzzzzzzzzzzzzzvzzzzzzyeyTjkDnyHzTuueKZePz9decyzzLzzzL*.c8.NzrGJJvufeeeeeJheeyzjeeeeJh*peeeeKJJJJJJJJJJmjHvOJJJJJJJJJfeeeieeeeSJJJJJSJJJ3TeIJJJJ3..E.UEAcyhxD.eeeeeuzzzLJJJJ5.e8JJJheeeeeeeeeeeeyeeK3JJJJJJJJ*s7defeeeeeeeeeeeeeeeeeeeeeeeeeSJJJJJJJJZIJJzzz1..6LJJJJJJtJJZ4....EK*&debug=false',
+ 'Findbook.ru' => 'http://findbook.ru/search/d0?ptype=4&pvalue=$1',
+ 'Яндекс.Маркет' => 'http://market.yandex.ru/search.xml?text=$1',
+ 'ОЗОН' => 'http://www.ozon.ru/?context=advsearch_book&isbn=$1',
+ 'Books.Ru' => 'http://www.books.ru/shop/search/advanced?as%5Btype%5D=books&as%5Bname%5D=&as%5Bisbn%5D=$1&as%5Bauthor%5D=&as%5Bmaker%5D=&as%5Bcontents%5D=&as%5Binfo%5D=&as%5Bdate_after%5D=&as%5Bdate_before%5D=&as%5Bprice_less%5D=&as%5Bprice_more%5D=&as%5Bstrict%5D=%E4%E0&as%5Bsub%5D=%E8%F1%EA%E0%F2%FC&x=22&y=8',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+
+# Note to translators:
+# Please include the English words as synonyms. This allows people
+# from other wikis to contribute more easily.
+#
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#REDIRECT', '#ПЕРЕНАПРАВЛЕНИЕ', '#ПЕРЕНАПР'),
+ 'notoc' => array( 0, '__NOTOC__', '__БЕЗ_ОГЛ__'),
+ 'nogallery' => array( 0, '__NOGALLERY__', '__БЕЗ_ГАЛЕРЕИ__'),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__ОБЯЗ_ОГЛ__'),
+ 'toc' => array( 0, '__TOC__', '__ОГЛ__'),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__БЕЗ_РЕДАКТИРОВАНИЯ_РАЗДЕЛА__'),
+ 'start' => array( 0, '__START__', '__НАЧАЛО__'),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'ТЕКУЩИЙ_МЕСЯЦ'),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME','НАЗВАНИЕ_ТЕКУЩЕГО_МЕСЯЦА'),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN','НАЗВАНИЕ_ТЕКУЩЕГО_МЕСЯЦА_РОД'),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'НАЗВАНИЕ_ТЕКУЩЕГО_МЕСЯЦА_АБР'),
+ 'currentday' => array( 1, 'CURRENTDAY','ТЕКУЩИЙ_ДЕНЬ'),
+ 'currentday2' => array( 1, 'CURRENTDAY2','ТЕКУЩИЙ_ДЕНЬ_2'),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME','НАЗВАНИЕ_ТЕКУЩЕГО_ДНЯ'),
+ 'currentyear' => array( 1, 'CURRENTYEAR','ТЕКУЩИЙ_ГОД'),
+ 'currenttime' => array( 1, 'CURRENTTIME','ТЕКУЩЕЕ_ВРЕМЯ'),
+ 'currenthour' => array( 1, 'CURRENTHOUR' , 'ТЕКУЩИЙ_ЧАС' ),
+ 'localmonth' => array( 1, 'LOCALMONTH', 'МЕСТНЫЙ_МЕСЯЦ' ),
+ 'localmonthname' => array( 1, 'LOCALMONTHNAME', 'НАЗВАНИЕ_МЕСТНОГО_МЕСЯЦА'),
+ 'localmonthnamegen' => array( 1, 'LOCALMONTHNAMEGEN', 'НАЗВАНИЕ_МЕСТНОГО_МЕСЯЦА_РОД'),
+ 'localmonthabbrev' => array( 1, 'LOCALMONTHABBREV', 'НАЗВАНИЕ_МЕСТНОГОМЕСЯЦА_АБР'),
+ 'localday' => array( 1, 'LOCALDAY' , 'МЕСТНЫЙ_ДЕНЬ'),
+ 'localday2' => array( 1, 'LOCALDAY2', 'МЕСТНЫЙ_ДЕНЬ_2'),
+ 'localdayname' => array( 1, 'LOCALDAYNAME', 'НАЗВАНИЕ_МЕСТНОГО_ДНЯ'),
+ 'localyear' => array( 1, 'LOCALYEAR', 'МЕСТНЫЙ_ГОД'),
+ 'localtime' => array( 1, 'LOCALTIME', 'МЕСТНОЕ_ВРЕМЯ'),
+ 'localhour' => array( 1, 'LOCALHOUR', 'МЕСТНЫЙ_ЧАС'),
+ 'numberofpages' => array( 1, 'NUMBEROFPAGES', 'КОЛИЧЕСТВО_СТРАНИЦ'),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES','КОЛИЧЕСТВО_СТАТЕЙ'),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'КОЛИЧЕСТВО_ФАЙЛОВ'),
+ 'numberofusers' => array( 1, 'NUMBEROFUSERS', 'КОЛИЧЕСТВО_УЧАСТНИКОВ'),
+ 'pagename' => array( 1, 'PAGENAME','НАЗВАНИЕ_СТРАНИЦЫ'),
+ 'pagenamee' => array( 1, 'PAGENAMEE','НАЗВАНИЕ_СТРАНИЦЫ_2'),
+ 'namespace' => array( 1, 'NAMESPACE','ПРОСТРАНСТВО_ИМЁН'),
+ 'namespacee' => array( 1, 'NAMESPACEE','ПРОСТРАНСТВО_ИМЁН_2'),
+ 'talkspace' => array( 1, 'TALKSPACE', 'ПРОСТРАНСТВО_ОБСУЖДЕНИЙ'),
+ 'talkspacee' => array( 1, 'TALKSPACEE', 'ПРОСТРАНСТВО_ОБСУЖДЕНИЙ_2'),
+ 'subjectspace' => array( 1, 'SUBJECTSPACE', 'ARTICLESPACE', 'ПРОСТРАНСТВО_СТАТЕЙ' ),
+ 'subjectspacee' => array( 1, 'SUBJECTSPACEE', 'ARTICLESPACEE', 'ПРОСТРАНСТВО_СТАТЕЙ_2' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'ПОЛНОЕ_НАЗВАНИЕ_СТРАНЦЫ' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE', 'ПОЛНОЕ_НАЗВАНИЕ_СТРАНЦЫ_2' ),
+ 'subpagename' => array( 1, 'SUBPAGENAME', 'НАЗВАНИЕ_ПОДСТРАНИЦЫ' ),
+ 'subpagenamee' => array( 1, 'SUBPAGENAMEE', 'НАЗВАНИЕ_ПОДСТРАНИЦЫ_2'),
+ 'basepagename' => array( 1, 'BASEPAGENAME', 'ОСНОВА_НАЗВАНИЯ_СТРАНИЦЫ'),
+ 'basepagenamee' => array( 1, 'BASEPAGENAMEE', 'ОСНОВА_НАЗВАНИЯ_СТРАНИЦЫ_2'),
+ 'talkpagename' => array( 1, 'TALKPAGENAME', 'НАЗВАНИЕ_СТРАНИЦЫ_ОБСУЖДЕНИЯ'),
+ 'talkpagenamee' => array( 1, 'TALKPAGENAMEE', 'НАЗВАНИЕ_СТРАНИЦЫ_ОБСУЖДЕНИЯ_2'),
+ 'subjectpagename' => array( 1, 'SUBJECTPAGENAME', 'ARTICLEPAGENAME', 'НАЗВАНИЕ_СТРАНИЦЫ_СТАТЬИ' ),
+ 'subjectpagenamee' => array( 1, 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE', 'НАЗВАНИЕ_СТРАНИЦЫ_СТАТЬИ_2' ),
+ 'msg' => array( 0, 'MSG:', 'СООБЩ:'),
+ 'subst' => array( 0, 'SUBST:','ПОДСТ:'),
+ 'msgnw' => array( 0, 'MSGNW:', 'СООБЩ_БЕЗ_ВИКИ:'),
+ 'end' => array( 0, '__END__','__КОНЕЦ__'),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'мини'),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'мини=$1'),
+ 'img_right' => array( 1, 'right','справа'),
+ 'img_left' => array( 1, 'left','слева'),
+ 'img_none' => array( 1, 'none', 'без'),
+ 'img_width' => array( 1, '$1px','$1пкс'),
+ 'img_center' => array( 1, 'center', 'centre','центр'),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame','обрамить'),
+ 'img_page' => array( 1, 'page=$1', 'page $1', 'страница=$1', 'страница $1' ),
+ 'int' => array( 0, 'INT:', 'ВНУТР:'),
+ 'sitename' => array( 1, 'SITENAME','НАЗВАНИ_ЕСАЙТА'),
+ 'ns' => array( 0, 'NS:','ПИ:'),
+ 'localurl' => array( 0, 'LOCALURL:', 'ЛОКАЛЬНЫЙ_АДРЕС:'),
+ 'localurle' => array( 0, 'LOCALURLE:', 'ЛОКАЛЬНЫЙ_АДРЕС_2:'),
+ 'server' => array( 0, 'SERVER','СЕРВЕР'),
+ 'servername' => array( 0, 'SERVERNAME', 'НАЗВАНИЕ_СЕРВЕРА'),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'ПУТЬ_К_СКРИПТУ'),
+ 'grammar' => array( 0, 'GRAMMAR:', 'ПАДЕЖ:'),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', '__БЕЗ_ПРЕОБРАЗОВАНИЯ_ЗАГОЛОВКА__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', '__БЕЗ_ПРЕОБРАЗОВАНИЯ_ТЕКСТА__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK','ТЕКУЩАЯ_НЕДЕЛЯ'),
+ 'currentdow' => array( 1, 'CURRENTDOW','ТЕКУЩИЙ_ДЕНЬ_НЕДЕЛИ'),
+ 'localweek' => array( 1, 'LOCALWEEK', 'МЕСТНАЯ_НЕДЕЛЯ' ),
+ 'localdow' => array( 1, 'LOCALDOW', 'МЕСТНЫЙ_ДЕНЬ_НЕДЕЛИ' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'ИД_ВЕРСИИ'),
+ 'revisionday' => array( 1, 'REVISIONDAY', 'ДЕНЬ_ВЕРСИИ' ),
+ 'revisionday2' => array( 1, 'REVISIONDAY2' , 'ДЕНЬ_ВЕРСИИ_2'),
+ 'revisionmonth' => array( 1, 'REVISIONMONTH' , 'МЕСЯЦ_ВЕРСИИ'),
+ 'revisionyear' => array( 1, 'REVISIONYEAR' , 'ГОД_ВЕРСИИ'),
+ 'revisiontimestamp' => array( 1, 'REVISIONTIMESTAMP' ),
+ 'plural' => array( 0, 'PLURAL:', 'МНОЖЕСТВЕННОЕ_ЧИСЛО:' ),
+ 'fullurl' => array( 0, 'FULLURL:', 'ПОЛНЫЙ_АДРЕС:' ),
+ 'fullurle' => array( 0, 'FULLURLE:', 'ПОЛНЫЙ_АДРЕС_2:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:', 'ПЕРВАЯ_БУКВА_МАЛЕНЬКАЯ:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:' , 'ПЕРВАЯ_БУКВА_БОЛЬШАЯ:' ),
+ 'lc' => array( 0, 'LC:' , 'МАЛЕНЬКИМИ_БУКВАМИ:' ),
+ 'uc' => array( 0, 'UC:', 'БОЛЬШИМИ_БУКВАМИ:' ),
+ 'raw' => array( 0, 'RAW:', 'НЕОБРАБ:' ),
+ 'displaytitle' => array( 1, 'DISPLAYTITLE' , 'ПОКАЗАТЬ_ЗАГОЛОВОК' ),
+ 'rawsuffix' => array( 1, 'R' , 'Н' ),
+ 'newsectionlink' => array( 1, '__NEWSECTIONLINK__', '__ССЫЛКА_НА_НОВЫЙ_РАЗДЕЛ__' ),
+ 'currentversion' => array( 1, 'CURRENTVERSION' , 'ТЕКУЩАЯ_ВЕРСИЯ' ),
+ 'urlencode' => array( 0, 'URLENCODE:' , 'ЗАКОДИРОВАННЫЙ_АДРЕС:' ),
+ 'anchorencode' => array( 0, 'ANCHORENCODE', 'КОДИРОВАТЬ_МЕТКУ'),
+ 'currenttimestamp' => array( 1, 'CURRENTTIMESTAMP' , 'ОТМЕТКА_ТЕКУЩЕГО_ВРЕМЕНИ' ),
+ 'localtimestamp' => array( 1, 'LOCALTIMESTAMP' , 'ОТМЕТКА_МЕСТНОГО_ВРЕМЕНИ'),
+ 'directionmark' => array( 1, 'DIRECTIONMARK', 'DIRMARK' , 'НАПРАВЛЕНИЕ_ПИСЬМА' ),
+ 'language' => array( 0, '#LANGUAGE:' , '#ЯЗЫК:' ),
+ 'contentlanguage' => array( 1, 'CONTENTLANGUAGE', 'CONTENTLANG', 'ЯЗЫК_СОДЕРЖАНИЯ' ),
+ 'pagesinnamespace' => array( 1, 'PAGESINNAMESPACE:', 'PAGESINNS:' , 'СТРАНИЦ_В_ПРОСТРАНСТВЕ_ИМЁН:' ),
+ 'numberofadmins' => array( 1, 'NUMBEROFADMINS', 'КОЛИЧЕСТВО_АДМИНИСТРАТОРОВ' ),
+ 'formatnum' => array( 0, 'FORMATNUM', 'ФОРМАТИРОВАТЬ_ЧИСЛО' ),
+ 'padleft' => array( 0, 'PADLEFT', 'ЗАПОЛНИТЬ_СЛЕВА'),
+ 'padright' => array( 0, 'PADRIGHT', 'ЗАПОЛНИТЬ_СПРАВА'),
+ 'special' => array( 0, 'special', 'служебная' ),
+ 'defaultsort' => array( 1, 'DEFAULTSORT:', 'СОРТИРОВКА_ПО_УМОЛЧАНИЮ'),
+);
+
+$linkTrail = '/^([a-zабвгдеёжзийклмнопрстуфхцчшщъыьэюя“»]+)(.*)$/sDu';
+
+$messages = array(
+
+# User preference toggles
+'tog-underline' => 'Подчёркивать ссылки:',
+'tog-highlightbroken' => 'Показывать несуществующие ссылки <a href="" class="new">вот так</a> (иначе вот так<a href="" class="internal">?</a>).',
+'tog-justify' => 'Выравнивать текст по ширине страницы',
+'tog-hideminor' => 'Скрывать малозначимые правки в списке свежих изменений',
+'tog-extendwatchlist' => 'Улучшенный список наблюдения',
+'tog-usenewrc' => 'Улучшенный список свежих изменений (JavaScript)',
+'tog-numberheadings' => 'Автоматически нумеровать заголовки',
+'tog-showtoolbar' => 'Показывать панель инструментов при редактировании (JavaScript)',
+'tog-editondblclick' => 'Править статьи по двойному щелчку (JavaScript)',
+'tog-editsection' => 'Показывать ссылку «править» для каждой секции',
+'tog-editsectiononrightclick' => 'Править секции при правом щелчке мышью на заголовке (JavaScript)',
+'tog-showtoc' => 'Показывать оглавление (для страниц более чем с 3 заголовками)',
+'tog-rememberpassword' => 'Помнить мою учётную запись на этом компьютере',
+'tog-editwidth' => 'Поле редактирования во всю ширину окна браузера',
+'tog-watchcreations' => 'По умолчанию добавлять созданные статьи в список наблюдения',
+'tog-watchdefault' => 'По умолчанию добавлять новые и изменённые статьи в список наблюдения',
+'tog-watchdeletion' => 'Добавлять удалённые мной страницы в список наблюдения',
+'tog-minordefault' => 'По умолчанию помечать изменения как малозначимые',
+'tog-previewontop' => 'Показывать предпросмотр статьи до окна редактирования',
+'tog-previewonfirst' => 'Предварительный просмотр по первому изменению',
+'tog-nocache' => 'Запретить кеширование страниц',
+'tog-enotifwatchlistpages' => 'Уведомлять по эл. почте об изменениях страниц из списка наблюдения',
+'tog-enotifusertalkpages' => 'Уведомлять по эл. почте об изменении персональной страницы обсуждения',
+'tog-enotifminoredits' => 'Уведомлять по эл. почте даже при малозначительных изменениях',
+'tog-enotifrevealaddr' => 'Показывать мой почтовый адрес в сообщениях оповещения',
+'tog-shownumberswatching' => 'Показывать число участников, включивших страницу в свой список наблюдения',
+'tog-fancysig' => 'Простая подпись (без автоматической ссылки)',
+'tog-externaleditor' => 'Использовать по умолчанию внешний редактор',
+'tog-externaldiff' => 'Использовать по умолчанию внешнюю программу сравнения версий',
+'tog-showjumplinks' => 'Включить вспомогательные ссылки «перейти к»',
+'tog-uselivepreview' => 'Использовать быстрый предварительный просмотр (JavaScript, экспериментально)',
+'tog-forceeditsummary' => 'Предупреждать, когда не указано краткое описание изменений',
+'tog-watchlisthideown' => 'Скрывать мои правки из списка наблюдения',
+'tog-watchlisthidebots' => 'Скрывать правки ботов из списка наблюдения',
+'tog-watchlisthideminor' => 'Скрывать малые правки из списка наблюдения',
+'tog-nolangconversion' => 'Отключить преобразование систем письма',
+'tog-ccmeonemails' => 'Отправлять мне копии писем, которые я посылаю другим участникам.',
+
+'underline-always' => 'Всегда',
+'underline-never' => 'Никогда',
+'underline-default' => 'Использовать настройки браузера',
+
+'skinpreview' => '(Предпросмотр)',
+
+# dates
+'sunday' => 'воскресенье',
+'monday' => 'понедельник',
+'tuesday' => 'вторник',
+'wednesday' => 'среда',
+'thursday' => 'четверг',
+'friday' => 'пятница',
+'saturday' => 'суббота',
+'sun' => 'Вс',
+'mon' => 'Пн',
+'tue' => 'Вт',
+'wed' => 'Ср',
+'thu' => 'Чт',
+'fri' => 'Пт',
+'sat' => 'Сб',
+'january' => 'январь',
+'february' => 'февраль',
+'march' => 'март',
+'april' => 'апрель',
+'may_long' => 'май',
+'june' => 'июнь',
+'july' => 'июль',
+'august' => 'август',
+'september' => 'сентябрь',
+'october' => 'октябрь',
+'november' => 'ноябрь',
+'december' => 'декабрь',
+'january-gen' => 'января',
+'february-gen' => 'февраля',
+'march-gen' => 'марта',
+'april-gen' => 'апреля',
+'may-gen' => 'мая',
+'june-gen' => 'июня',
+'july-gen' => 'июля',
+'august-gen' => 'августа',
+'september-gen' => 'сентября',
+'october-gen' => 'октября',
+'november-gen' => 'ноября',
+'december-gen' => 'декабря',
+'jan' => 'янв',
+'feb' => 'фев',
+'mar' => 'мар',
+'apr' => 'апр',
+'may' => 'мая',
+'jun' => 'июн',
+'jul' => 'июл',
+'aug' => 'авг',
+'sep' => 'сен',
+'oct' => 'окт',
+'nov' => 'ноя',
+'dec' => 'дек',
+# Bits of text used by many pages:
+#
+'categories' => 'Категории',
+'pagecategories' => '{{PLURAL:$1|Категория|Категории|Категории}}',
+'category_header' => 'Статьи в категории «$1»',
+'subcategories' => 'Подкатегории',
+'category-media-header' => 'Файлы в категории «$1»',
+
+'linkprefix' => '/^(.*?)(„|«)$/sD',
+'mainpage' => 'Заглавная страница',
+'mainpagetext' => '<big>Вики-движок «MediaWiki» успешно установлен.</big>',
+'mainpagedocfooter' => 'Информацию по работе с этой вики можно найти в [http://meta.wikimedia.org/wiki/%D0%9F%D0%BE%D0%BC%D0%BE%D1%89%D1%8C:%D0%A1%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D0%B5 руководстве пользователя].
+
+== Некоторые полезные ресурсы ==
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Список возможных настроек];
+* [http://www.mediawiki.org/wiki/Help:FAQ Часто задаваемые вопросы и ответы по MediaWiki];
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка уведомлений о выходе новых версий MediaWiki].',
+
+'portal' => 'Сообщество',
+'portal-url' => '{{ns:project}}:Портал сообщества',
+'about' => 'Описание',
+'aboutsite' => 'Описание {{grammar:genitive|{{SITENAME}}}}',
+'aboutpage' => '{{ns:project}}:Описание',
+'article' => 'Статья',
+'help' => 'Справка',
+'helppage' => '{{ns:project}}:Справка',
+'bugreports' => 'Отчёт об ошибке',
+'bugreportspage' => '{{ns:project}}:Отчёт об ошибке',
+'sitesupport' => 'Пожертвования', # To enable, something like 'Donations', '-' to disable
+'sitesupport-url' => '{{ns:project}}:Пожертвования',
+'faq' => 'ЧаВО',
+'faqpage' => '{{ns:project}}:ЧаВО',
+'edithelp' => 'Справка по редактированию',
+'newwindow' => '(в новом окне)',
+'edithelppage' => '{{ns:project}}:Справка по редактированию',
+'cancel' => 'Отменить',
+'qbfind' => 'Поиск',
+'qbbrowse' => 'Просмотреть',
+'qbedit' => 'Править',
+'qbpageoptions' => 'Настройки страницы',
+'qbpageinfo' => 'Сведения о статье',
+'qbmyoptions' => 'Ваши настройки',
+'qbspecialpages' => 'Специальные страницы',
+'moredotdotdot' => 'Далее…',
+'mypage' => 'Личная страница',
+'mytalk' => 'Моя страница обсуждения',
+'anontalk' => 'Обсуждение для этого IP-адреса',
+'navigation' => 'Навигация',
+
+# Metadata in edit box
+'metadata_help' => 'Метаданные (пояснения см. на странице [[{{ns:project}}:Метаданные]]):',
+
+'currentevents' => 'Текущие события',
+'currentevents-url' => 'Текущие события',
+
+'disclaimers' => 'Отказ от ответственности',
+'disclaimerpage' => '{{ns:project}}:Отказ_от_ответственности',
+'privacy' => 'Политика конфиденциальности',
+'privacypage' => '{{ns:project}}:Политика_конфиденциальности',
+'errorpagetitle' => 'Ошибка',
+'returnto' => 'Возврат к странице $1.',
+'tagline' => 'Материал из {{grammar:genitive|{{SITENAME}}}}.',
+'help' => 'Справка',
+'search' => 'Поиск',
+'searchbutton' => 'Найти',
+'go' => 'Перейти',
+'searcharticle' => 'Перейти',
+'history' => 'История',
+'history_short' => 'История',
+'updatedmarker' => 'обновлено с моего последнего посещения',
+'info_short' => 'Информация',
+'printableversion' => 'Версия для печати',
+'permalink' => 'Постоянная ссылка',
+'print' => 'Печать',
+'edit' => 'Править',
+'editthispage' => 'Править эту статью',
+'delete' => 'Удалить',
+'deletethispage' => 'Стереть её',
+'undelete_short' => 'Восстановить $1 {{PLURAL:$1|правку|правки|правок}}',
+'protect' => 'Защитить',
+'protectthispage' => 'Защитить',
+'unprotect' => 'Снять защиту',
+'unprotectthispage' => 'Снять защиту',
+'newpage' => 'Новая статья',
+'talkpage' => 'Обсуждение',
+'specialpage' => 'Служебная страница',
+'personaltools' => 'Личные инструменты',
+'postcomment' => 'Прокомментировать',
+'articlepage' => 'Просмотреть статью',
+'talk' => 'Обсуждение',
+'views' => 'Просмотры',
+'toolbox' => 'Инструменты',
+'userpage' => 'Просмотреть страницу участника',
+'projectpage' => 'Просмотреть страницу проекта',
+'imagepage' => 'Просмотреть страницу изображения',
+'mediawikipage' => 'Показать страницу сообщения',
+'templatepage' => 'Просмотреть страницу шаблона',
+'viewhelppage' => 'Получить справку',
+'categorypage' => 'Просмотреть страницу категории',
+'viewtalkpage' => 'Просмотреть обсуждение',
+'otherlanguages' => 'На других языках',
+'redirectedfrom' => '(Перенаправлено с $1)',
+'redirectpagesub' => 'Страница-перенаправление',
+'lastmodifiedat' => 'Последнее изменение этой страницы: $2, $1.',
+'viewcount' => 'К этой странице обращались $1 {{plural:$1|раз|раза|раз}}.',
+'copyright' => 'Содержимое доступно в соответствии с $1.',
+'protectedpage' => 'Защищённая статья',
+'jumpto' => 'Перейти к:',
+'jumptonavigation' => 'навигация',
+'jumptosearch' => 'поиск',
+
+'badaccess' => 'Ошибка доступа',
+'badaccess-group0' => 'Вы не можете выполнять запрошенное действие.',
+'badaccess-group1' => 'Запрошенное действие могут выполнять только участники из группы $1.',
+'badaccess-group2' => 'Запрошенное действие могут выполнять только участники из групп $1.',
+'badaccess-groups' => 'Запрошенное действие могут выполнять только участники из групп $1.',
+
+'versionrequired' => 'Требуется MediaWiki версии $1',
+'versionrequiredtext' => 'Для работы с этой страницей требуется MediaWiki версии $1. См. [[{{ns:special}}:Version]].',
+
+'widthheight' => '$1 × $2',
+'ok' => 'OK',
+'pagetitle' => '$1 — {{SITENAME}}',
+'retrievedfrom' => 'Получено с $1',
+'youhavenewmessages' => 'Вы получили $1 ($2).',
+'newmessageslink' => 'новые сообщения',
+'newmessagesdifflink' => 'последнее изменение',
+'editsection'=>'править',
+'editold'=>'править',
+'editsectionhint' => 'Править секцию: $1',
+'toc' => 'Содержание',
+'showtoc' => 'показать',
+'hidetoc' => 'убрать',
+'thisisdeleted' => 'Просмотреть или восстановить $1?',
+'viewdeleted' => 'Просмотреть $1?',
+'restorelink' => '{{PLURAL:$1|$1 удалённую правку|$1 удалённые правки|$1 удалённых правок}}',
+'feedlinks' => 'В виде:',
+'feed-invalid' => 'Неправильный тип канала для подписки.',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Статья',
+'nstab-user' => 'Участник',
+'nstab-media' => 'Мультимедиа',
+'nstab-special' => 'Служебная страница',
+'nstab-project' => 'О проекте',
+'nstab-image' => 'Файл',
+'nstab-mediawiki' => 'Сообщение',
+'nstab-template' => 'Шаблон',
+'nstab-help' => 'Справка',
+'nstab-category' => 'Категория',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Такого действия нет',
+'nosuchactiontext' => 'Действие, указанное в URL, не распознаётся программным обеспечением вики',
+'nosuchspecialpage' => 'Такой специальной страницы нет',
+'nospecialpagetext' => 'Запрошенной вами служебной страницы не существует. См. [[{{ns:special}}:Specialpages|список служебных страниц]].',
+
+# General errors
+#
+'error' => 'Ошибка',
+'databaseerror' => 'Ошибка базы данных',
+'dberrortext' => 'Обнаружена ошибка синтаксиса запроса к базе данных.
+Последний запрос к базе данных:
+<blockquote><tt>$1</tt></blockquote>
+произошёл из функции <tt>«$2»</tt>.
+MySQL возвратил ошибку <tt>«$3: $4»</tt>.',
+'dberrortextcl' => 'Обнаружена ошибка синтаксиса запроса к базе данных.
+Последний запрос к базе данных:
+«$1»
+произошёл из функции «$2».
+MySQL возвратил ошибку «$3: $4».',
+'noconnect' => 'Извините, сейчас невозможно связаться с сервером базы данных из-за технических проблем.<br />
+$1',
+'nodb' => 'Невозможно выбрать базу данных $1',
+'cachederror' => 'Ниже представлена кешированная копия запрошенной страницы; возможно, она устарела.',
+'laggedslavemode' => 'Внимание: страница может не содержать последних обновлений.',
+'readonly' => 'Запись в базу данных заблокирована',
+'enterlockreason' => 'Укажите причину и намеченный срок блокировки.',
+'readonlytext' => 'Добавление новых статей и другие изменения базы данных сейчас заблокированы: вероятно, в связи с плановым обслуживанием.
+Заблокировавший оператор оставил следующее разъяснение:
+$1',
+'missingarticle' => 'База данных не нашла текста статьи,
+хотя должна была найти, по имени «$1».
+
+Обычно это вызвано использованием устаревшей ссылки на журнал изменений или различий для статьи, которая была удалена.
+
+Если дело не в этом, то скорее всего, вы обнаружили ошибку в программном обеспечении вики.
+Пожалуйста, сообщите об этом администратору, указав URL.',
+'readonly_lag' => 'База данных автоматически заблокирована от изменений на время пока вторичный сервер БД не синхронизируется с первичным.',
+'internalerror' => 'Внутренняя ошибка',
+'filecopyerror' => 'Невозможно скопировать файл «$1» в «$2».',
+'filerenameerror' => 'Невозможно переименовать файл «$1» в «$2».',
+'filedeleteerror' => 'Невозможно удалить файл «$1».',
+'filenotfound' => 'Невозможно найти файл «$1».',
+'unexpected' => 'Неподходящее значение: «$1»=«$2».',
+'formerror' => 'Ошибка: невозможно передать данные формы',
+'badarticleerror' => 'Это действие не может быть выполнено на данной странице.',
+'cannotdelete' => 'Невозможно удалить указанную страницу или файл. Возможно, его уже удалил кто-то другой.',
+'badtitle' => 'Недопустимое название',
+'badtitletext' => 'Запрашиваемое название статьи неправильно, пусто, либо неправильно указано междуязыковое или междувики название. Возможно, в названии используются недопустимые символы.',
+'perfdisabled' => 'К сожалению, эта возможность временно недоступна в связи с загруженностью сервера.',
+'perfdisabledsub' => 'Это — сохранённая копия от $1:', # obsolete?
+'perfcached' => 'Следующие данные взяты из кеша и могут не содержать последних изменений.',
+'perfcachedts' => 'Следующие данные взяты из кеша, последний раз он обновлялся в $1.',
+'wrong_wfQuery_params' => 'Недопустимые параметры для функции wfQuery()<br />
+Функция: $1<br />
+Запрос: $2',
+'viewsource' => 'Просмотр',
+'viewsourcefor' => 'Страница «$1»',
+'protectedtext' => 'Эта страница закрыта для редактирования.',
+'viewsourcetext' => 'Вы можете просмотреть и скопировать исходный текст этой страницы:',
+'protectedinterface' => 'Эта страница содержит системное сообщение MediaWiki, её могут изменять только администраторы проекта.',
+'editinginterface' => "'''Внимание:''' Вы редактируете страницу, содержащую системное сообщение MediaWiki. Её изменение повлияет на внешний вид интерфейса для других пользователей.",
+'sqlhidden' => '(SQL запрос скрыт)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Стать инкогнито',
+'logouttext' => 'Вы работаете в том же режиме, который был до вашего представления системе. Вы идентифицируетесь не по имени, а по IP-адресу.
+Вы можете продолжить участие в проекте анонимно или начать новый сеанс как тот же самый или другой пользователь. Некоторые страницы могут отображаться, как будто вы ещё представлены системе под именем, для борьбы с этим явлением обновите кеш браузера.',
+
+'welcomecreation' => '== Добро пожаловать, $1! ==
+
+Вы были зарегистрированы.
+Не забудьте провести [[{{ns:special}}:Preferences|персональную настройку сайта]].',
+'loginpagetitle' => 'Представиться системе',
+'yourname' => 'Ваше имя участника',
+'yourpassword' => 'Ваш пароль',
+'yourpasswordagain' => 'Повторный набор пароля:',
+'remembermypassword' => 'Помнить мою учётную запись на этом компьютере',
+'yourdomainname' => 'Ваш домен',
+'externaldberror' => 'Произошла ошибка при аутентификации с помощью внешней базы данных, или у вас недостаточно прав для внесения изменений в свою внешнюю учётную запись.',
+'loginproblem' => '<span style="color:red">Участник не опознан.</span>',
+'alreadyloggedin' => '<strong>Участник $1, вы уже представились системе!</strong><br />',
+
+'login' => 'Представиться системе',
+'loginprompt' => 'Вы должны разрешить «cookies», чтобы представиться системе.',
+'userlogin' => 'Представиться системе',
+'logout' => 'Завершение сеанса',
+'userlogout' => 'Завершение сеанса',
+'notloggedin' => 'Вы не представились системе',
+'nologin' => 'Вы ещё не зарегистрировались? $1.',
+'nologinlink' => 'Создать учётную запись',
+'createaccount' => 'Зарегистрировать нового участника',
+'gotaccount' => 'Вы уже зарегистрированы? $1.',
+'gotaccountlink' => 'Представьтесь',
+'createaccountmail' => 'по эл. почте',
+'badretype' => 'Введённые вами пароли не совпадают.',
+'userexists' => 'Введённое вами имя участника уже занято. Пожалуйста, выберите другое имя.',
+'youremail' => 'Электронная почта *:',
+'username' => 'Регистрационное имя:',
+'uid' => 'Идентификатор пользователя:',
+'yourrealname' => 'Ваше настоящее имя *:',
+'yourlanguage' => 'Язык интерфейса:',
+'yourvariant' => 'Вариант языка',
+'yournick' => 'Ваш псевдоним (для подписей):',
+'badsig' => 'Неверная подпись. Проверьте корректность HTML-тегов.',
+'email' => 'Эл. почта',
+'prefs-help-email-enotif' => 'Этот адрес также используется для отправки по электронной почте оповещений об изменении страниц, если вы активировали соответствующую опцию.',
+'prefs-help-realname' => '* Настоящее имя (необязательное поле): если вы укажите его, то оно будет использовано для того чтобы показать кем был внесена правка страницы.',
+'loginerror' => 'Ошибка опознавания участника',
+'prefs-help-email' => '* Электронная почта (необязательное поле) позволяет другим участникам связаться с вами без раскрытия адреса вашей электронной почты.',
+'nocookiesnew' => 'Участник зарегистрирован, но не представлен. {{SITENAME}} использует «cookies» для представления участников. У вас «cookies» запрещены. Пожалуйста, разрешите их, а затем преставьтесь с вашим новым именем участника и паролем.',
+'nocookieslogin' => '{{SITENAME}} использует «cookies» для представления участников. Вы их отключили. Пожалуйста, включите их и попробуйте снова.',
+'noname' => 'Вы не указали допустимого имени участника.',
+'loginsuccesstitle' => 'Опознание прошло успешно',
+'loginsuccess' => 'Теперь вы работаете под именем $1.',
+'nosuchuser' => 'Участника с именем $1 не существует.
+Проверьте правильность написания или воспользуйтесь формой ниже, чтобы зарегистрировать нового участника.',
+'nosuchusershort' => 'Не существует участника с именем $1. Проверьте написание имени.',
+'nouserspecified' => 'Вы должны указать имя участника.',
+'wrongpassword' => 'Введённый вами пароль неверен. Попробуйте ещё раз.',
+'wrongpasswordempty' => 'Пожалуйста, введите непустой пароль.',
+'mailmypassword' => 'Выслать новый пароль',
+'passwordremindertitle' => 'Напоминание пароля участника {{grammar:genitive|{{SITENAME}}}}',
+'passwordremindertext' => 'Кто-то (вероятно вы, с IP-адреса $1) запросил,
+чтобы мы выслали вам новый пароль участника {{grammar:genitive|{{SITENAME}}}} ($4).
+Пароль для участника $2 теперь: <code>$3</code>.
+Вы должны представиться системе и поменять пароль.
+
+Если вы не посылали запроса на смену пароля, или если вы уже вспомнили свой пароль,
+вы можете проигнорировать данное сообщение и продолжить использовать свой старый пароль.',
+'noemail' => 'Для участника с именем $1 электронный адрес указан не был.',
+'passwordsent' => 'Новый пароль был выслан на адрес электронной почты, указанный для участника $1.
+
+Пожалуйста, представьтесь системе заново после получения пароля.',
+'blocked-mailpassword' => 'Редактирование с вашего IP-адреса запрещено, заблокирована и функция восстановления пароля.',
+'eauthentsent' => 'Временный пароль был отправлен на адрес электронной почты нового участника $1. В письме также описаны действия, которые нужно выполнить, чтобы подтвердить, что этот адрес электронной почты действительно принадлежит вам.',
+'throttled-mailpassword' => 'Функция напоминания пароля уже использовалось в течение последних $1 часов. Для предотвращения злоупотреблений, разрешено запрашивать не более одного напоминания за $1 часов.',
+'mailerror' => 'Ошибка при отправке почты: $1',
+'acct_creation_throttle_hit' => 'К сожалению, вы уже создали $1 учётных записей. Вы не можете создать больше ни одной.',
+'emailauthenticated' => 'Ваш почтовый адрес был сопоставлен с $1.',
+'emailnotauthenticated' => 'Ваш адрес электронной почты ещё не был подтверждён, функции вики-движка по работе с эл. почтой отключены.',
+'noemailprefs' => 'Адрес электронной почты не был указан, функции вики-движка по работе с эл. почтой отключены.',
+'emailconfirmlink' => 'Подтвердить ваш адрес электронной почты',
+'invalidemailaddress' => 'Введённый адрес не может быть принят, так как он не соответствует формату адресов электронной почты. Пожалуйста, введите корректный адрес или оставьте поле пустым.',
+'accountcreated' => 'Учётная запись создана',
+'accountcreatedtext' => 'Создана учётная запись участника $1.',
+
+# Password reset dialog
+'resetpass' => 'Сброс пароля от учётной записи',
+'resetpass_announce' => 'Вы представились с помощью временного пароля, полученного по электронной почте. Для завершения входа в систему, вы должны установить новый пароль.',
+'resetpass_header' => 'Сброс пароля',
+'resetpass_submit' => 'Установить пароль и представиться',
+'resetpass_success' => 'Ваш пароль был успешно изменён! Выполняется вход в систему…',
+'resetpass_bad_temporary' => 'Недействительный временный пароль. Возможно, вы уже изменили ваш пароль, или попробуйте запросить временный пароль снова.',
+'resetpass_forbidden' => 'Возможность смены пароля в данной вики-системе не предусмотрена',
+'resetpass_missing' => 'Форма не содержит данных.',
+
+# Edit page toolbar
+'bold_sample'=>'Полужирное начертание',
+'bold_tip'=>'Полужирное начертание',
+'italic_sample'=>'Курсивное начертание',
+'italic_tip'=>'Курсивное начертание',
+'link_sample'=>'Заголовок ссылки',
+'link_tip'=>'Внутренняя ссылка',
+'extlink_sample'=>'http://www.example.com заголовок ссылки',
+'extlink_tip'=>'Внешняя ссылка (помните о префиксе http:// )',
+'headline_sample'=>'Текст заголовка',
+'headline_tip'=>'Заголовок 2-го уровня',
+'math_sample'=>'Вставьте сюда формулу',
+'math_tip'=>'Математическая формула (формат LaTeX)',
+'nowiki_sample'=>'Вставляйте сюда неотформатированный текст.',
+'nowiki_tip'=>'Не обрабатывать как размеченный текст',
+'image_sample'=>'Example.jpg',
+'image_tip'=>'Встроенное изображение',
+'media_sample'=>'Example.ogg',
+'media_tip'=>'Ссылка на медиа-файл',
+'sig_tip'=>'Ваша подпись и момент времени',
+'hr_tip'=>'Горизонтальная линия (не используйте часто)',
+
+# Edit pages
+#
+'summary' => 'Описание изменений',
+'subject' => 'Тема/заголовок',
+'minoredit' => 'Малое изменение',
+'watchthis' => 'Включить эту страницу в список наблюдения',
+'savearticle' => 'Записать страницу',
+'preview' => 'Предпросмотр',
+'showpreview' => 'Предварительный просмотр',
+'showlivepreview' => 'Быстрый предпросмотр',
+'showdiff' => 'Внесённые изменения',
+'anoneditwarning' => "'''Внимание''': Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.",
+'missingsummary' => "'''Напоминание.''' Вы не дали краткого описания изменений. При повторном нажатии на кнопку «Сохранить», ваши изменения будут сохранены без комментария.",
+'missingcommenttext' => 'Пожалуйста, введите ниже ваше сообщение.',
+'missingcommentheader' => "'''Напоминание:''' Вы не указали заголовок комментария. При повторном нажатии на кнопку «Сохранить», ваш комментарий будет записан без заголовка.",
+'summary-preview' => 'Описание будет',
+'subject-preview' => 'Заголовок будет',
+'blockedtitle' => 'Участник заблокирован',
+'blockedtext' => "<big>'''Ваша учётная запись или IP-адрес заблокированы.'''</big>
+
+Блокировка произведена администратором $1. Указана следующая причина блокировки: ''«$2»''.
+
+Вы можете отправить письмо участнику $1 или любому другому [[{{ns:project}}:Администраторы|администратору]], чтобы обсудить блокировку.
+Обратите внимание, что вы не сможете отправить письмо администратору, если вы не зарегистрированы в Википедии и не подтвердили свой адрес электронной почты в [[{{ns:special}}:Preferences|личных настройках]].
+Ваш IP-адрес — $3. Пожалуйста, указывайте этот адрес во всех своих запросах.",
+'blockedoriginalsource' => "Ниже показан текст страницы «$1».",
+'blockededitsource' => "Ниже показан текст '''ваших изменений''' страницы «$1».",
+'whitelistedittitle' => 'Для изменения требуется авторизация',
+'whitelistedittext' => 'Вы должны $1 для изменения страниц.',
+'whitelistreadtitle' => 'Для чтения требуется авторизация',
+'whitelistreadtext' => 'Вы должны [[{{ns:special}}:Userlogin|зарегистрироваться]] для чтения этих страниц.',
+'whitelistacctitle' => 'У вас нет прав, чтобы создать учётную запись',
+'whitelistacctext' => 'Для того чтобы иметь возможность создавать учётные записи в этой вики, вы должны [[{{ns:special}}:Userlogin|зарегистрироваться]] и иметь соответствующие права.',
+'confirmedittitle' => 'Требуется подтверждение адреса электронной почты',
+'confirmedittext' => 'Вы должны подтвердить ваш адрес электронной почты перед правкой страниц. Пожалуйста, введите и подтвердите ваш адрес эл. почты на [[{{ns:special}}:Preferences|странице настроек]].',
+'loginreqtitle' => 'Требуется авторизация',
+'loginreqlink' => 'представиться',
+'loginreqpagetext' => 'Вы должны $1, чтобы просмотреть другие страницы.',
+'accmailtitle' => 'Пароль выслан.',
+'accmailtext' => 'Пароль для $1 выслан на $2.',
+'newarticle' => '(Новая)',
+'newarticletext' =>
+'Вы перешли по ссылке на статью, которая пока не существует.
+Чтобы создать новую страницу, наберите текст в окне, расположенном ниже
+(см. [[{{ns:help}}:Справка|справочную страницу]] чтобы получить больше информации).
+Если вы оказались здесь по ошибке, просто нажмите кнопку \'\'\'назад\'\'\' вашего браузера.',
+'anontalkpagetext' => "----''Эта страница обсуждения принадлежит анонимному участнику, который ещё не зарегистрировался или который не представился регистрированным именем. Для идентификации используется цифровой IP-адрес. Если вы анонимный участник и полагаете, что получили сообщения, адресованные не вам (один IP-адрес может использоваться несколькими пользователями), пожалуйста, [[{{ns:special}}:Userlogin|представьтесь системе]], чтобы впредь избежать возможной путаницы с другими участниками.''",
+'noarticletext' => "В настоящий момент текст на данной странице отсутствует. Вы можете [[{{ns:special}}:Search/{{PAGENAME}}|найти упоминание данного названия]] в других статьях или '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} создать страницу с таким названием]'''.",
+'clearyourcache' => "'''Замечание:''' Чтобы после сохранения увидеть сделанные изменения, очистите кеш своего браузера: '''Mozilla / Firefox''': ''Ctrl+Shift+R'', '''IE:''' ''Ctrl+F5'', '''Safari''': ''Cmd+Shift+R'', '''Konqueror''': ''F5'', '''Opera''': через меню ''Tools→Preferences''.",
+'usercssjsyoucanpreview' => "<strong>Подсказка:</strong> Используйте кнопку предварительного просмотра, чтобы протестировать ваш новый css-файл или js-файл перед сохранением.",
+'usercsspreview' => '\'\'\'Помните, что это только предварительный просмотр вашего css-файла, он ещё не сохранён!\'\'\'',
+'userjspreview' => '\'\'\'Помните, что это только предварительный просмотр вашего javascrpt-файла, он ещё не сохранён!\'\'\'',
+'userinvalidcssjstitle' => "'''Внимание:''' тема оформления «$1» не найдена. Помните, что пользовательские .css и .js страницы должны иметь название состоящее только из маленьких букв, например «{{ns:user}}:Некто/monobook.css», а не «{{ns:user}}:Некто/Monobook.css».",
+'updated' => '(Обновлена)',
+'note' => '<strong>Примечание:</strong>',
+'previewnote' => 'Это только предварительный просмотр, текст ещё не записан!',
+'session_fail_preview' => '<strong>К сожалению, сервер не смог сохранить ваши изменения из-за потери идентификатора сессии. Это наша временная проблема, извините за неудобства. Пожалуйста, попробуйте сохранить ещё раз. Если это не поможет, сохраните данные в локальном файле, закройте и вновь откройте браузер.</strong>',
+'previewconflict' => 'Этот предварительный просмотр отражает текст в верхнем окне редактирования так, как он будет выглядеть, если вы решите записать его.',
+'session_fail_preview_html' => '<sstrong>Извините! Невозможно принять ваше изменение из-за потери данных HTML-сессии.</sstrong>
+
+\'\'Так как данная вики разрешает использовать чистый HTML, предварительный просмотр отключён в качестве меры предотвращения JavaScript атак.\'\'
+
+<sstrong>Если это добросовестная попытка редактирования, пожалуста, попробуйте ещё раз. Если не получается повторная правка, попробуйте завершить сеанс работы и заново представится.</sstrong>',
+'importing' => 'Импортирование $1',
+'editing' => 'Редактирование $1',
+'editinguser' => 'Для участника <b>$1</b>',
+'editingsection' => 'Редактирование $1 (секция)',
+'editingcomment' => 'Редактирование $1 (комментарий)',
+'editconflict' => 'Конфликт редактирования: $1',
+'explainconflict' => 'Пока вы редактировали эту статью, кто-то внёс в неё изменения. В верхнем окне для редактирования вы видите тот текст статьи, который будет сохранён при нажатии на кнопку «Записать страницу». В нижнем окне для редактирования находится ваш вариант. Чтобы сохранить ваши изменения, перенесите их из нижнего окна для редактирования в верхнее.<br />',
+'yourtext' => 'Ваш текст',
+'storedversion' => 'Сохранённая версия',
+'nonunicodebrowser' => '<strong>ПРЕДУПРЕЖДЕНИЕ: Ваш [[браузер]] не поддерживает кодировку [[Юникод]]. При редактировании статей все не-ASCII символы будут заменены на свои шестнадцатеричные коды.</strong>',
+'editingold' => '<strong>ПРЕДУПРЕЖДЕНИЕ: Вы редактируете устаревшую версию данной страницы. После сохранения страницы будут потеряны изменения, сделанные в последующих версиях.</strong>',
+'yourdiff' => 'Различия',
+'copyrightwarning' => 'Обратите внимание, что все добавления и изменения текста статьи рассматриваются, как выпущенные на условиях лицензии $2 (см. $1).
+Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались кем угодно, не помещайте их сюда.<br />
+Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из
+источника допускающего свободное распространение и изменение своего содержимого.<br />
+<strong>НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!</strong>',
+'copyrightwarning2' => 'Пожалуйста, обратите внимание, что все ваши добавления
+могут быть отредактированы или удалены другими участниками.
+Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.<br />
+Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. $1).<br />
+<strong>НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!</strong>',
+'longpagewarning' => '<strong>ПРЕДУПРЕЖДЕНИЕ: Длина этой страницы составляет $1 килобайт. Страницы, размер которых приближается к 32 КБ или превышает это значение, могут неверно отображаться в некоторых браузерах.
+Пожалуйста, рассмотрите вариант разбиения страницы на меньшие части.</strong>',
+'longpageerror' => "<strong>ОШИБКА: записываемый вами текст имеет размер $1 килобайт, что больше, чем установленный предел $2 килобайта. Страница не может быть сохранена.</strong>",
+'readonlywarning' => '<strong>ПРЕДУПРЕЖДЕНИЕ: база данных заблокирована в связи с процедурами обслуживания,
+поэтому вы не можете записать ваши изменения прямо сейчас.
+Возможно, вам следует сохранить текст в файл на своём диске и поместить его в данный проект позже.</strong>',
+'protectedpagewarning' => '<strong>ПРЕДУПРЕЖДЕНИЕ: эта страница защищена от изменений, и только [[{{ns:project}}:Администраторы|администраторы]] могут редактировать её. См. [[{{ns:project}}:Правила защиты страниц|правила защиты страниц]].</strong>',
+'semiprotectedpagewarning' => "'''Замечание:''' эта статья была защищена; редактировать её могут только зарегистрированные пользователи.",
+'templatesused' => 'Шаблоны, использованные на этой странице:',
+'templatesusedpreview' => 'Шаблоны, используемые в предпросматриваемой странице:',
+'templatesusedsection' => 'Шаблоны, используемые в этой секции:',
+'edittools' => '<!-- Расположенный здесь текст будет показываться под формой редактирования и формой загрузки. -->',
+'nocreatetitle' => 'Создание страниц ограничено',
+'nocreatetext' => 'На этом сайте ограничена возможность создания новых страниц.
+Вы можете вернуться назад и отредактировать существующую страницу, [[{{ns:special}}:Userlogin|представиться системе или создать новую учётную запись]].',
+
+# "Undo" feature
+'undo-success' => 'Правка была отменена. Пожалуйста, нажмите «Записать страницу», чтобы изменения вступили в силу.',
+'undo-failure' => 'Правка не может быть отменена из-за несовместимости промежуточных изменений.',
+'undo-summary' => 'Отмена правки № $1 участника [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]])',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'Невозможно создать учётную запись',
+'cantcreateaccounttext' => 'Регистрация новых участников с этого IP-адреса (<b>$1</b>) запрещена.
+Вероятно, это связано с систематическим вандализмом с этого адреса
+(который может быть общим, например, для школы или интернет-провайдера).',
+
+# History pages
+#
+'revhistory' => 'Журнал изменений',
+'viewpagelogs' => 'Показать журналы для этой страницы',
+'nohistory' => 'Для этой страницы журнал изменений отсутствует.',
+'revnotfound' => 'Версия не найдена',
+'revnotfoundtext' => 'Старая версия страницы не найдена.
+Пожалуйста, проверьте правильность ссылки, которую вы использовали для доступа к этой странице.',
+'loadhist' => 'Загрузка журнала изменений страницы',
+'currentrev' => 'Текущая версия',
+'revisionasof' => 'Версия $1',
+'revision-info' => 'Версия от $1; $2',
+'previousrevision' => '← Предыдущая',
+'nextrevision' => 'Следующая →',
+'currentrevisionlink' => 'Текущая версия',
+'cur' => 'текущ.',
+'next' => 'след.',
+'last' => 'пред.',
+'orig' => 'перв.',
+'histlegend' => "Пояснения: (текущ.) — отличие от текущей версии; (пред.) — отличие от предшествующей версии; '''м''' — малозначимое изменение",
+'deletedrev' => '[удалена]',
+'histfirst' => 'старейшие',
+'histlast' => 'недавние',
+'rev-deleted-comment' => '(комментарий удалён)',
+'rev-deleted-user' => '(имя автора стёрто)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Эта версия страницы была удалена из общедоступного архива.
+Возможно, объяснения даны в [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} журнале удалений].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Эта версия страницы была удалена из общедоступного архива.
+Вы можете просмотреть её, так как являетесь администратором сайта.
+Возможно, объяснения удаления даны в [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} журнале удалений].
+</div>',
+#'rev-delundel' => 'del/undel',
+'rev-delundel' => 'показать/скрыть',
+
+'history-feed-title' => 'История изменений',
+'history-feed-description' => 'История изменений этой страницы в вики',
+'history-feed-item-nocomment' => '$1 в $2', # user at time
+'history-feed-empty' => 'Запрашиваемой страницы не существует.
+Она могла быть удалена или переименована.
+Попробуйте [[{{ns:special}}:Search|найти в вики]] похожие страницы.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Удалить / восстановить версии страницы',
+'revdelete-nooldid-title' => 'Не задана целевая версия',
+'revdelete-nooldid-text' => 'Вы не задали целевую версию (или версии) для выполнения этой функции.',
+'revdelete-selected' => 'Выбранная версия [[:$1]]:',
+'revdelete-text' => "Удалённые версии будут показываться в истории страницы,
+но их содержание будет недоступно обычным посетителям.
+
+Администраторы будут иметь доступ к скрытому содержанию и смогут восстановить его через этот же интерфейс,
+за исключением случаев, когда было установлено дополнительное ограничение владельцем сайта.",
+'revdelete-legend' => 'Установить ограничения:',
+'revdelete-hide-text' => 'Скрыть текст этой версии страницы',
+'revdelete-hide-comment' => 'Скрыть комментарий',
+'revdelete-hide-user' => 'Скрыть имя автора',
+'revdelete-hide-restricted' => 'Применить ограничения также и к администраторам',
+'revdelete-log' => 'Комментарий:',
+'revdelete-submit' => 'Применить к выбранной версии',
+'revdelete-logentry' => 'Изменённая видимость версии страницы для [[$1]]',
+
+# Diffs
+#
+'difference' => '(Различия между версиями)',
+'loadingrev' => 'загрузка версии для различения',
+'lineno' => 'Строка $1:',
+'editcurrent' => 'Редактировать текущую версию данной страницы',
+'selectnewerversionfordiff' => 'Выберите новую версию для сравнения',
+'selectolderversionfordiff' => 'Выберите старую версию для сравнения',
+'compareselectedversions' => 'Сравнить выбранные версии',
+'editundo' => 'отменить',
+'diff-multi' => "({{plural:$1|$1 промежуточная версия не показана|$1 промежуточные версии не показаны|$1 промежуточных версий не показаны.}})",
+
+# Search results
+#
+'searchresults' => 'Результаты поиска',
+'searchresulttext' => 'Для получения более подробной информации о поиске на страницах проекта, см. [[{{ns:project}}:Поиск]].',
+'searchsubtitle' => 'По запросу «[[:$1]]»',
+'searchsubtitleinvalid' => 'По запросу «$1»',
+'badquery' => 'Неправильно сформированный запрос',
+'badquerytext' => 'Невозможно обработать запрос.
+Возможно, Вы попытались найти слово короче трёх букв (это пока не поддерживается) либо допустили опечатку в слове.
+Попробуйте другой запрос.',
+'matchtotals' => 'Запросу «$1» соответствует $2 {{plural:$2|название статьи|названия статей|названий статей}} и тексты $3 {{plural:$3|статьи|статей|статей}}.',
+'noexactmatch' => 'Страницы с названием «$1» не существует.
+
+<span style="display: block; margin: 1.5em 2em">
+<strong>[[:$1|Создать страницу]]</strong></span>',
+'titlematches' => 'Совпадения в названиях статей',
+'notitlematches' => 'Нет совпадений в названиях статей',
+'textmatches' => 'Совпадения в текстах статей',
+'notextmatches' => 'Нет совпадения в текстах статей',
+'prevn' => 'предыдущие $1',
+'nextn' => 'следующие $1',
+'viewprevnext' => 'Просмотреть ($1) ($2) ($3).',
+'showingresults' => 'Ниже {{plural:$1|показан|показаны|показаны}} <strong>$1</strong> {{plural:$1|результат|результата|результатов}}, начиная с №&nbsp;<strong>$2</strong>.oubleredirect',
+'showingresultsnum' => 'Ниже {{plural:$3|показан|показаны|показаны}} <strong>$3</strong> {{plural:$3|результат|результата|результатов}}, начиная с №&nbsp;<strong>$2</strong>.',
+'nonefound' => 'Неудачный поиск может быть вызван попыткой найти общие слова, которые не подлежат индексированию, например — «тоже» и «чтобы» или употреблением более чем одного ключевого слова поиска (показываются только страницы, содержащие все указанные слова для поиска).',
+'powersearch' => 'Искать',
+'powersearchtext' => 'Искать в пространствах имён:<br />$1<br />$2 Показывать перенаправления<br /> Искать $3 $9',
+'searchdisabled' => 'Извините, но встроенный полнотекстовый поиск выключен. Вы можете воспользоваться поиском по сайту через поисковые системы общего назначения, однако имейте в виду, что копия сайта в их кеше может быть несколько устаревшей.',
+
+'blanknamespace' => '(Основное)',
+
+# Preferences page
+#
+'preferences' => 'Настройки',
+'mypreferences' => 'Мои настройки',
+'prefsnologin' => 'Вы не представились системе',
+'prefsnologintext' => 'Вы должны [[{{ns:special}}:Userlogin|представиться системе]], чтобы изменять настройки участника.',
+'prefsreset' => 'Восстановлены настройки по умолчанию.',
+'qbsettings' => 'Панель навигации',
+'changepassword' => 'Сменить пароль',
+'skin' => 'Оформление',
+'math' => 'Отображение формул',
+'dateformat' => 'Формат даты',
+'datedefault' => 'По умолчанию',
+'datetime' => 'Дата и время',
+'math_failure' => 'Невозможно разобрать выражение',
+'math_unknown_error' => 'неизвестная ошибка',
+'math_unknown_function' => 'неизвестная функция',
+'math_lexing_error' => 'лексическая ошибка',
+'math_syntax_error' => 'синтаксическая ошибка',
+'math_image_error' => 'Преобразование в PNG прошло с ошибкой; проверьте правильность установки latex, dvips, gs и convert',
+'math_bad_tmpdir' => 'Не удаётся создать или записать во временный каталог математики',
+'math_bad_output' => 'Не удаётся создать или записать в выходной каталог математики',
+'math_notexvc' => 'Выполняемый файл texvc не найден; См. math/README — справку по настройке.',
+'prefs-personal' => 'Личные данные',
+'prefs-rc' => 'Страница свежих правок',
+'prefs-watchlist' => 'Список наблюдения',
+'prefs-watchlist-days' => 'Число дней, отображаемых в списке наблюдения:',
+'prefs-watchlist-edits' => 'Количество правок, отображаемых в улучшенном списке наблюдения:',
+'prefs-misc' => 'Другие настройки',
+'saveprefs' => 'Записать',
+'resetprefs' => 'Сбросить',
+'oldpassword' => 'Старый пароль:',
+'newpassword' => 'Новый пароль:',
+'retypenew' => 'Повторите ввод нового пароля:',
+'textboxsize' => 'Редактирование',
+'rows' => 'Строк:',
+'columns' => 'Столбцов:',
+'searchresultshead' => 'Результаты поиска',
+'resultsperpage' => 'Количество найденных записей на страницу:',
+'contextlines' => 'Количество показываемых строк для каждой найденной:',
+'contextchars' => 'Количество символов контекста на строку:',
+'stubthreshold' => 'Порог определения болванки:',
+'recentchangescount' => 'Заголовки статей на странице свежих правок:',
+'savedprefs' => 'Ваши настройки сохранены.',
+'timezonelegend' => 'Часовой пояс',
+'timezonetext' => 'Введите смещение (в часах) вашего местного времени
+от времени сервера (UTC — гринвичского).',
+'localtime' => 'Местное время',
+'timezoneoffset' => 'Смещение',
+'servertime' => 'Текущее время сервера',
+'guesstimezone' => 'Заполнить из браузера',
+'allowemail' => 'Разрешить приём электронной почты от других участников',
+'defaultns' => 'По умолчанию, искать в следующих пространствах имён:',
+'default' => 'по умолчанию',
+'files' => 'Файлы',
+
+# User rights
+
+'userrights-lookup-user' => 'Управление группами пользователя',
+'userrights-user-editname' => 'Введите имя участника:',
+'editusergroup' => 'Изменить группы пользователей',
+
+'userrights-editusergroup' => 'Изменить группы участника',
+'saveusergroups' => 'Сохранить группы участника',
+'userrights-groupsmember' => 'Член групп:',
+'userrights-groupsavailable' => 'Доступные группы:',
+'userrights-groupshelp' => 'Выберите группы, в которые вы хотите включить или из которых хотите исключить участника.
+Невыбранные группы не изменятся. Снять выделение с группы можно используя CTRL + левую клавишу мыши.',
+
+# Groups
+'group' => 'Группа:',
+'group-bot' => 'Боты',
+'group-sysop' => 'Администраторы',
+'group-bureaucrat' => 'Бюрократы',
+'group-all' => '(все)',
+
+'group-bot-member' => 'бот',
+'group-sysop-member' => 'администратор',
+'group-bureaucrat-member' => 'бюрократ',
+
+'grouppage-bot' => '{{ns:project}}:Боты',
+'grouppage-sysop' => '{{ns:project}}:Администраторы',
+'grouppage-bureaucrat' => '{{ns:project}}:Бюрократы',
+
+# Recent changes
+#
+'changes' => 'изменения',
+'recentchanges' => 'Свежие правки',
+'recentchangestext' => 'Ниже в хронологическом порядке перечислены последние изменения на страницах {{grammar:genitive|{{SITENAME}}}}.',
+'rcnote' => 'Последние <strong>$1</strong> изменений за <strong>$2</strong> {{plural:$2|день|дня|дней}}, на момент времени $3.',
+'rcnotefrom' => 'Ниже перечислены изменения с <strong>$2</strong> (по <strong>$1</strong>).',
+'rclistfrom' => 'Показать изменения с $1.',
+'rcshowhideminor' => '$1 малые правки',
+'rcshowhidebots' => '$1 ботов',
+'rcshowhideliu' => '$1 представившихся участников',
+'rcshowhideanons' => '$1 анонимов',
+'rcshowhidepatr' => '$1 проверенные правки',
+'rcshowhidemine' => '$1 свои правки',
+'rclinks' => 'Показать последние $1 изменений за $2 {{plural:$2|день|дня|дней}};<br />$3.',
+'diff' => 'разн.',
+'hist' => 'история',
+'hide' => 'Скрыть',
+'show' => 'Показать',
+'minoreditletter' => 'м',
+'newpageletter' => 'Н',
+'boteditletter' => 'б',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 наблюдающих пользователя]',
+'rc_categories' => 'Только из категорий (разделитель «|»)',
+'rc_categories_any' => 'Любой',
+
+# Upload
+#
+'upload' => 'Загрузить файл',
+'uploadbtn' => 'Загрузить файл',
+'reupload' => 'Изменить загрузку',
+'reuploaddesc' => 'Вернуться к форме загрузки.',
+'uploadnologin' => 'Вы не представились системе',
+'uploadnologintext' => 'Вы должны [[{{ns:special}}:Userlogin|представиться системе]],
+чтобы загружать файлы на сервер.',
+'upload_directory_read_only' => 'Веб-сервер не имеет прав записи в папку ($1), в которой предполагается хранить загружаемые файлы.',
+'uploaderror' => 'Ошибка загрузки файла',
+'uploadtext' => "Используя эту форму вы можете загрузить на сервер файлы.
+
+Чтобы просмотреть ранее загруженные файлы,
+перейдите сюда: [[{{ns:special}}:Imagelist|список загруженных изображений]].<br />
+Загрузка и удаление файлов отражаются в [[{{ns:special}}:Log|журнале загрузки файлов]].
+
+Для включения изображения в статью вы можете использовать строки вида:
+*'''<nowiki>[[{{ns:image}}:File.jpg]]</nowiki>'''
+*'''<nowiki>[[{{ns:image}}:File.png|thumb|комментарий]]</nowiki>'''
+
+Для ссылки на медиа-файл вы можете использовать строку вида:
+*'''<nowiki>[[{{ns:media}}:File.ogg]]</nowiki>'''",
+'uploadlog' => 'журнал загрузок',
+'uploadlogpage' => 'Журнал загрузок',
+'uploadlogpagetext' => 'Ниже представлен список последних загрузок файлов.
+Везде используется время сервера (по Гринвичу, UTC).
+<ul>
+</ul>',
+'filename' => 'Имя файла',
+'filedesc' => 'Краткое описание',
+'fileuploadsummary' => 'Краткое описание:',
+'filestatus' => 'Условия распространения',
+'filesource' => 'Источник',
+'copyrightpage' => '{{ns:project}}:Авторское право',
+'copyrightpagename' => 'Авторские права проекта {{SITENAME}}',
+'uploadedfiles' => 'Загруженные файлы',
+'ignorewarning' => 'Игнорировать предупреждения и сохранить файл в любом случае.',
+'ignorewarnings' => 'Игнорировать предупреждения',
+'minlength' => 'Название файла должно содержать хотя бы три символа.',
+'illegalfilename' => 'Имя файла «$1» содержит символы, которые не разрешается использовать в заголовках. Пожалуйста, переименуйте файл и попытайтесь загрузить его снова.',
+'badfilename' => 'Название файла было изменено на $1.',
+'badfiletype' => '«.$1» не является рекомендованным форматом для файлов с изображениями.',
+'large-file' => 'Рекомендуется использовать изображения, размер которых не превышает $1 байт (размер загруженного файла составляет $2 байт).',
+'largefileserver' => 'Размер файла превышает максимально разрешённый.',
+'emptyfile' => 'Загруженный вами файл вероятно пустой. Возможно, это произошло из-за ошибки при наборе имени файла. Пожалуйста, проверьте, действительно ли вы хотите загрузить этот файл.',
+'fileexists' => 'Файл с этим именем уже существует, пожалуйста, проверьте $1, если вы не уверены, что хотите заменить его.',
+'fileexists-forbidden' => 'Файл с этим именем уже существует; пожалуйста, вернитесь назад и загрузите файл под другим именем. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Файл с этим именем уже существует в общем хранилище файлов; пожалуйста, вернитесь назад и загрузите файл под другим именем. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Загрузка успешно завершена',
+'fileuploaded' => 'Файл «$1» успешно загружен.
+
+Пожалуйста, проследуйте по следующей ссылке: ($2) к странице с описанием и заполните информацию о файле, такую как: источник файла, когда и кем был создан файл, а также любую другую информацию известную вам об этом файле.',
+'uploadwarning' => 'Предупреждение',
+'savefile' => 'Записать файл',
+'uploadedimage' => 'загружено «[[$1]]»',
+'uploaddisabled' => 'Загрузка запрещена.',
+'uploaddisabledtext' => 'На этом вики-сайте загрузка файлов запрещена.',
+'uploadscripted' => 'Файл содержит HTML-код или скрипт, который может быть ошибочно обработан браузером.',
+'uploadcorrupt' => 'Файл либо повреждён, либо имеет неверное расширение. Пожалуйста, проверьте файл и попробуйте загрузить его ещё раз.',
+'uploadvirus' => 'Файл содержит вирус! См. $1',
+'sourcefilename' => 'Исходное имя файла',
+'destfilename' => 'Целевое имя файла',
+'watchthisupload' => 'Включить этот файл в список наблюдения',
+'filewasdeleted' => 'Файл с таким именем уже существовал ранее, но был удалён. Пожалуйста, проверьте $1 перед повторной загрузкой.',
+
+'upload-proto-error' => 'Неправильный протокол',
+'upload-proto-error-text' => 'Удалённая загрузка требует адрес начинающийся с <code>http://</code> или <code>ftp://</code>.',
+'upload-file-error' => 'Внутренняя ошибка',
+'upload-file-error-text' => 'Внутренняя ошибка при попытке создать временный файл на сервере. Пожалуйста, обратитесь к системному администратору.',
+'upload-misc-error' => 'Неизвестная ошибка загрузки',
+'upload-misc-error-text' => 'Неизвестная ошибка загрузки. Пожалуйста, проверьте, что адрес верен, и повторите попытку. Если проблема остаётся, обратитесь к системному администратору.',
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => "Невозможно обратить по указанному адресу.",
+'upload-curl-error6-text' => 'Невозможно обратить по указанному адресу. Пожалуйста, проверьте, что адрес верен, а сайт доступен.',
+'upload-curl-error28' => 'Время отведённое на загрузку истекло',
+'upload-curl-error28-text' => 'Сайт слишком долго не отвечает. Пожалуйста, проверьте что сайт работоспособен и после небольшого перерыва попробуйте ещё раз. Возможно, операцию следует провести в другое время, когда сайт менее нагружен.',
+
+'license' => 'Лицензирование',
+'nolicense' => 'Отсутствует',
+'upload_source_url' => ' (правильный, публично доступный интернет-адрес)',
+'upload_source_file' => ' (файл на вашем компьютере)',
+
+# Image list
+#
+'imagelist' => 'Список файлов',
+'imagelisttext' => "Ниже представлен список из '''$1''' {{plural:$1|файла|файлов|файлов}}, отсортированных $2.",
+'imagelistforuser' => "Только изображения, загруженные участником $1.",
+'getimagelist' => 'получение списка файлов',
+'ilsubmit' => 'Искать',
+'showlast' => 'Показать последние $1 {{plural:$1|файл|файла|файлов}}, {{plural:$1|отсортированный|отсортированные|отсортированных}} $2.',
+'byname' => 'по имени',
+'bydate' => 'по дате',
+'bysize' => 'по размеру',
+'imgdelete' => 'удал.',
+'imgdesc' => 'описание',
+'imgfile' => 'файл',
+'imglegend' => 'Пояснения: (описание) — показать/изменить описание файла.',
+'imghistory' => 'Журнал',
+'revertimg' => 'откат.',
+'deleteimg' => 'удал.',
+'deleteimgcompletely' => 'Удалить все версии',
+'imghistlegend' => 'Пояснения: (текущ.) — текущее изображение; (удал.) — удалить эту старую версию; (откат.) — откатиться на эту старую версию.
+<br /><i>Выберите дату, чтобы посмотреть список изображений, загруженных на эту дату.</i>.',
+'imagelinks' => 'Ссылки',
+'linkstoimage' => 'Следующие страницы ссылаются на данный файл:',
+'nolinkstoimage' => 'Нет страниц, ссылающихся на данный файл.',
+'sharedupload' => "Этот файл хранится на [[Викисклад]]е, хранилище изображений и мультимедиа для использования в изданиях [[Фонд Викимедиа|Фонда Викимедиа]].тек
+
+На '''[[Commons:Image:{{PAGENAME}}|странице описания]]''' есть сведения об этом изображении и условии его распространения.",
+'shareduploadwiki' => 'Дополнительную информацию можно найти на $1.',
+'shareduploadwiki-linktext' => 'странице описания файла',
+'noimage' => 'Файла с таким именем не существует, вы можете $1.',
+'noimage-linktext' => 'загрузить его',
+'uploadnewversion-linktext' => 'Загрузить новую версию этого файла',
+'imagelist_date' => 'Дата',
+'imagelist_name' => 'Имя файла',
+'imagelist_user' => 'Участник',
+'imagelist_size' => 'Размер (в байтах)',
+'imagelist_description' => 'Описание',
+'imagelist_search_for' => 'Поиск по имени изображения:',
+
+# Mime search
+#
+'mimesearch' => 'Поиск по MIME',
+'mimetype' => 'MIME-тип:',
+'download' => 'загрузить',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Страницы, за которыми никто не следит',
+
+# List redirects
+'listredirects' => 'Список перенаправлений',
+
+# Unused templates
+'unusedtemplates' => 'Неиспользуемые шаблоны',
+'unusedtemplatestext' => 'На этой странице перечислены все страницы пространства имён «Шаблоны», которые не включены в другие страницы. Не забывайте проверить отсутствие других ссылок на шаблон, перед его удалением.',
+'unusedtemplateswlh' => 'другие ссылки',
+
+# Random redirect
+'randomredirect' => 'Случайное перенаправление',
+
+# Statistics
+#
+'statistics' => 'Статистика',
+'sitestats' => 'Статистика сайта',
+'userstats' => 'Статистика участников',
+'sitestatstext' => "Всего в базе данных содержится '''$1''' {{plural:$1|страница|страницы|страниц}}.
+Это число включает в себя страницы о проекте, страницы обсуждений, незаконченные статьи, перенаправления и другие страницы, которые, не учитываются при подсчёте количества статей.
+За исключением них, есть '''$2''' {{plural:$2|страница|страницы|страниц}}, которые считаются полноценными статьями.
+
+{{plural:$8|Был загружен|Было загружено|Было загружено}} '''$8''' {{plural:$8|файл|файла|файлов}}.
+
+Всего с момента установки вики было сделано '''$3''' просмотров страниц и '''$4''' {{plural:$4|изменение|изменения|изменений}} страниц. Таким образом, в среднем приходится '''$5''' {{plural:$5|изменение|изменения|изменений}} на одну страницу, и '''$6''' просмотров на одно изменение.
+
+Величина [http://meta.wikimedia.org/wiki/Help:Job_queue очереди заданий] составляет '''$7'''.",
+'userstatstext' => "{{plural:$1|Зарегистрировался|Зарегистрировались|Зарегистрировались}} '''$1''' {{plural:$1|участник|участника|участников}}, из которых '''$2''' ($4 %) относятся к группе «$5».",
+'statistics-mostpopular' => 'Наиболее часто просматриваемые страницы',
+
+'disambiguations' => 'Страницы, описывающие многозначные термины',
+'disambiguationspage' => '{{ns:template}}:disambig',
+'disambiguationstext' => 'Следующие статьи ссылаются на <em>многозначные страницы</em>. Вместо этого они, вероятно, должны указывать на соответствующую конкретную статью.<br />Страница считается многозначной, если на ней размещён $1.<br />Ссылки из других пространств имён здесь <em>не</em> приведены.',
+'doubleredirects' => 'Двойные перенаправления',
+'doubleredirectstext' => 'Каждая строка содержит ссылки на первое и второе перенаправления, а также первую строчку страницы второго перенаправления, в которой обычно указывается название страницы, куда должно осуществляться перенаправление. Нужно, чтобы и первое перенаправление ссылалось на эту страницу.',
+'brokenredirects' => 'Разорванные перенаправления',
+'brokenredirectstext' => 'Следующие перенаправления указывают на несуществующие статьи:',
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|байт|байта|байтов}}',
+'ncategories' => '$1 {{PLURAL:$1|категория|категории|категорий}}',
+'nlinks' => '$1 {{PLURAL:$1|ссылка|ссылки|ссылок}}',
+'nmembers' => '$1 {{PLURAL:$1|объект|объекта|объектов}}',
+'nrevisions' => '$1 {{PLURAL:$1|версия|версии|версий}}',
+'nviews' => '$1 {{PLURAL:$1|просмотр|просмотра|просмотров}}',
+
+ 'longpages-summary' => 'укцкцукцукцуцукуцк',
+
+
+'lonelypages' => 'Страницы-сироты',
+'lonelypagestext' => 'На следующие страницы нет ссылок с других страниц данной вики.',
+'uncategorizedpages' => 'Некатегоризованные страницы',
+'uncategorizedcategories' => 'Некатегоризованные категории',
+'uncategorizedimages' => 'Некатегоризованные изображения',
+'unusedcategories' => 'Неиспользуемые категории',
+'unusedimages' => 'Неиспользуемые файлы',
+'popularpages' => 'Популярные страницы',
+'wantedcategories' => 'Требуемые категории',
+'wantedpages' => 'Требуемые страницы',
+'mostlinked' => 'Страницы, на которые больше всего ссылок',
+'mostlinkedcategories' => 'Категории, на которые больше всего ссылок',
+'mostcategories' => 'Страницы, включённые в большое количество категорий',
+'mostimages' => 'Самые используемые изображения',
+'mostrevisions' => 'Наиболее часто редактировавшиеся страницы',
+'allpages' => 'Все страницы',
+'prefixindex' => 'Указатель по началу слов',
+'randompage' => 'Случайная статья',
+'shortpages' => 'Короткие статьи',
+'longpages' => 'Длинные страницы',
+'deadendpages' => 'Тупиковые страницы',
+'deadendpagestext' => 'Следующие страницы не содержат ссылок на другие страницы в этой вики.',
+'listusers' => 'Список участников',
+'specialpages' => 'Спецстраницы',
+'spheading' => 'Служебные страницы',
+'restrictedpheading' => 'Служебные страницы с ограниченным доступом',
+'recentchangeslinked' => 'Связанные правки',
+'rclsub' => '(на страницах, ссылки на которые есть на странице «$1»)',
+'newpages' => 'Новые статьи',
+'newpages-username' => 'Участник:',
+'ancientpages' => 'Статьи по дате последнего редактирования',
+'intl' => 'Межъязыковые ссылки',
+'move' => 'Переименовать',
+'movethispage' => 'Переименовать эту страницу',
+'unusedimagestext' => 'Пожалуйста, учтите, что другие веб-сайты могут использовать прямую ссылку (URL) на это изображение, и поэтому изображение может активно использоваться несмотря на его вхождение в этот список.',
+'unusedcategoriestext' => 'Существуют следующие страницы категорий, не содержащие статей или других категорий.',
+
+# Book sources
+'booksources' => 'Источники книг',
+'booksources-search-legend' => 'Поиск информации о книге',
+'booksources-go' => 'Найти',
+'booksources-text' => 'На этой странице приведён список ссылок на сайты, где вы, возможно, найдёте дополнительную информацию о книге. Это интернет-магазины и системы поиска в библиотечных каталогах.',
+
+'categoriespagetext' => 'В вики имеются следующие категории.',
+'data' => 'Данные',
+'userrights' => 'Управление правами участников',
+'groups' => 'Группы участников',
+
+# FIXME: Other sites, of course, may have affiliate relations with the booksellers list
+'booksourcetext' => '',
+'isbn' => 'ISBN',
+'alphaindexline' => 'от $1 до $2',
+'version' => 'Версия MediaWiki',
+'log' => 'Журналы',
+'alllogstext' => 'Комбинированный показ журналов загрузки, удаления, защиты, блокировки и администрирования.
+Вы можете отфильтровать результаты по типу журнала, имени пользователя или затронутой странице.',
+'logempty' => 'Совпадающие элементы в журнале отсутствуют.',
+
+# Special:Allpages
+'nextpage' => 'Следующая страница ($1)',
+'prevpage' => 'Предыдущая страница ($1)',
+'allpagesfrom' => 'Вывести страницы, начинающиеся на:',
+'allarticles' => 'Все статьи',
+'allnotinnamespace' => 'Все страницы (кроме пространства имён «$1»)',
+'allpagesprev' => 'Предыдущие',
+'allpagesnext' => 'Следующие',
+'allinnamespace' => 'Все страницы (пространство имён «$1»)',
+'allpagessubmit' => 'Выполнить',
+'allpagesprefix' => 'Найти страницы, начинающиеся с:',
+'allpagesbadtitle' => 'Заголовок данной страницы не является допустимым, он содержит интервики, межязыковый префикс или запрещённые в заголовках символы.',
+
+# Special:Listusers
+'listusersfrom' => 'Показать участников, начиная с:',
+
+# Email this user
+#
+'mailnologin' => 'Адрес для отправки отсутствует',
+'mailnologintext' => 'Вы должны [[{{ns:special}}:Userlogin|представиться системе]]
+и иметь действительный адрес электронной почты в ваших [[{{ns:special}}:Preferences|настройках]],
+чтобы иметь возможность отправлять электронную почту другим участникам.',
+'emailuser' => 'Письмо участнику',
+'emailpage' => 'Отправить электронное письмо участнику',
+'emailpagetext' => 'Если этот участник указал действительный адрес электронной почты в своих настройках, то, заполнив форму ниже, можно отправить ему сообщение.
+Электронный адрес, который вы указали в своих настройках, будет указан в поле «От кого» письма, поэтому получатель будет иметь возможность ответить.',
+'usermailererror' => 'При отправке сообщения электронной почты произошла ошибка:',
+'defemailsubject' => '{{SITENAME}} e-mail',
+'noemailtitle' => 'Адрес электронной почты отсутствует',
+'noemailtext' => 'Этот участник не указал действительный адрес электронной почты или указал, что не желает получать письма от других участников.',
+'emailfrom' => 'От кого',
+'emailto' => 'Кому',
+'emailsubject' => 'Тема письма',
+'emailmessage' => 'Сообщение',
+'emailsend' => 'Отправить',
+'emailccme' => 'отправить мне копию этого сообщения',
+'emailccsubject'=> 'Копия вашего сообщения для $1: $2',
+'emailsent' => 'Письмо отправлено',
+'emailsenttext' => 'Ваше электронное сообщение отправлено.',
+
+# Watchlist
+
+'watchlist' => 'Список наблюдения',
+'watchlistfor' => "(участника '''$1''')",
+'nowatchlist' => 'Ваш список наблюдения пуст.',
+'watchlistanontext' => 'Вы должны $1, чтобы просмотреть или отредактировать список наблюдения.',
+'watchlistcount' => "'''В вашем списке наблюдения $1 {{plural:$1|страница|страницы|страниц}}, включая страницы обсуждения.'''",
+'clearwatchlist' => 'Очистить список наблюдения',
+'watchlistcleartext' => 'Вы уверены, что хотите удалить их?',
+'watchlistclearbutton' => 'Очистить список наблюдения',
+'watchlistcleardone' => 'Ваш список наблюдения очищен. $1 {{plural:$1|страница удалена|страницы удалены|страниц удалено}} из списка.',
+'watchnologin' => 'Нужно представиться системе',
+'watchnologintext' => 'Вы должны [[{{ns:special}}:Userlogin|представиться системе]], чтобы иметь возможность изменять свой список наблюдения',
+'addedwatch' => 'Добавлена в список наблюдения',
+'addedwatchtext' => "Страница «[[:$1]]» была добавлена в ваш [[{{ns:special}}:Watchlist|список наблюдения]]. Последующие изменения этой страницы и связанной с ней страницы обсуждения будут отмечаться в этом списке, а также будут выделены жирным шрифтом на странице со [[{{ns:special}}:Recentchanges|списком свежих изменений]], чтобы их было легче заметить.
+
+Если позже вы захотите удалить страницу из списка наблюдения, нажмите кнопку «не следить» в верхней правой части страницы.",
+'removedwatch' => 'Удалена из списка наблюдения',
+'removedwatchtext' => 'Страница «[[:$1]]» была удалена из вашего списка наблюдения.',
+'watch' => 'Следить',
+'watchthispage' => 'Наблюдать за этой страницей',
+'unwatch' => 'Не следить',
+'unwatchthispage' => 'Прекратить наблюдение',
+'notanarticle' => 'Не статья',
+'watchnochange' => 'Ничто из списка наблюдения не изменялось в рассматриваемый период.',
+'watchdetails' => '* В вашем списке наблюдения находится $1 {{plural:$1|страница|страницы|страниц}} (не считая страниц обсуждения)
+* [[{{ns:special}}:Watchlist/edit|Показать и отредактировать полный список]]
+* [[{{ns:special}}:Watchlist/clear|Удалить все страницы из списка]]',
+'wlheader-enotif' => '* Уведомление по эл. почте включено.',
+'wlheader-showupdated' => "* Страницы, изменившиеся с вашего последнего их посещения, выделены '''жирным''' шрифтом.",
+'watchmethod-recent'=> 'просмотр последних изменений для наблюдаемых страниц',
+'watchmethod-list' => 'просмотр наблюдаемых страниц для последних изменений',
+'removechecked' => 'Удалить выбранные элементы из списка наблюдения',
+'watchlistcontains' => 'Ваш список наблюдения содержит $1 {{plural:$1|страница|страницы|страниц}}.',
+'watcheditlist' => "Ниже представлен упорядоченный по алфавиту список наблюдаемых вами страниц. Отметьте страницы, которые вы хотите удалить из вашего списка наблюдения, и нажмите на кнопку ''«Удалить выбранные элементы из списка наблюдения»'' внизу страницы.",
+'removingchecked' => 'Удаление выбранных элементов из списка наблюдения…',
+'couldntremove' => 'Невозможно удалить элемент «$1»…',
+'iteminvalidname' => 'Проблема с элементом «$1», недопустимое название…',
+'wlnote' => 'Ниже следуют последние $1 {{plural:$1|изменение|изменения|изменений}} за {{plural:$2|последний|последние|последние}} <strong>$2</strong> {{plural:$2|час|часа|часов}}.',
+'wlshowlast' => 'Показать за последние $1 часов $2 дней $3',
+'wlsaved' => 'Это сохранённая версия вашего списка наблюдения',
+'watchlist-show-bots' => 'Показать правки ботов',
+'watchlist-hide-bots' => 'Скрыть правки ботов',
+'watchlist-show-own' => 'Показать свои правки',
+'watchlist-hide-own' => 'Скрыть свои правки',
+'watchlist-show-minor' => 'Показать малые правки',
+'watchlist-hide-minor' => 'Скрыть малые правки',
+'wldone' => 'Сделано.',
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => 'Добавление в список наблюдения…',
+'unwatching' => 'Удаление из списка наблюдения…',
+
+'enotif_mailer' => '{{SITENAME}} Служба извещений по почте',
+'enotif_reset' => 'Отметить все страницы как просмотренные',
+'enotif_newpagetext' => 'Это новая страница.',
+'changed' => 'изменена',
+'created' => 'создана',
+'enotif_subject' => 'Страница проекта «{{SITENAME}}» $PAGETITLE была $CHANGEDORCREATED участником $PAGEEDITOR',
+'enotif_lastvisited' => 'См. $1 для просмотра всех изменений произошедших с вашего последнего посещения.',
+'enotif_body' => '$WATCHINGUSERNAME,
+
+$PAGEEDITDATE страница проекта «{{SITENAME}}» $PAGETITLE была $CHANGEDORCREATED пользователем $PAGEEDITOR, см. $PAGETITLE_URL для просмотра текущей версии.
+
+$NEWPAGE
+
+Краткое описание изменения: $PAGESUMMARY $PAGEMINOREDIT
+
+Обратиться к изменившему:
+эл. почта $PAGEEDITOR_EMAIL
+вики $PAGEEDITOR_WIKI
+
+Не будет никаких других уведомлений в случае дальнейших изменений, если Вы не посещаете эту страницу. Вы могли также повторно установить флаги уведомления для всех ваших наблюдаемых страниц в вашем списке наблюдения.
+
+ Система оповещения {{grammar:genitive|{{SITENAME}}}}
+
+--
+Чтобы изменить настройки вашего списка наблюдения обратитесь к
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Обратная связь и помощь:
+{{fullurl:{{ns:help}}:Оглавление}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Удалить страницу',
+'confirm' => 'Подтверждение',
+'excontent' => 'содержимое: «$1»',
+'excontentauthor' => 'содержимое: «$1» (единственным автором был [[{{ns:special}}:Contributions/$2|$2]])',
+'exbeforeblank' => 'содержимое до очистки: «$1»',
+'exblank' => 'страница была пуста',
+'confirmdelete' => 'Подтвердить удаление',
+'deletesub' => '(«$1» удаляется)',
+'historywarning' => 'Предупреждение: у страницы, которую вы собираетесь удалить, есть история изменений:',
+'confirmdeletetext' => 'Вы запросили полное удаление страницы (изображения) и всей её истории изменений из базы данных.
+Пожалуйста, подтвердите, что вы действительно желаете это сделать, понимаете последствия своих действий,
+и делаете это в соответствии с правилами, изложенными в разделе [[{{ns:project}}:Правила]].',
+'actioncomplete' => 'Действие выполнено',
+'deletedtext' => '«$1» была удалена.
+См. $2 для просмотра списка последних удалений.',
+'deletedarticle' => 'удалена «[[$1]]»',
+'dellogpage' => 'Список удалений',
+'dellogpagetext' => 'Ниже приведён список последних удалений.',
+'deletionlog' => 'список удалений',
+'reverted' => 'Откачено к ранней версии',
+'deletecomment' => 'Причина удаления',
+'imagereverted' => 'Откат к ранней версии осуществлён.',
+'rollback' => 'Откатить изменения',
+'rollback_short' => 'Откат',
+'rollbacklink' => 'откатить',
+'rollbackfailed' => 'Ошибка при совершении отката',
+'cantrollback' => 'Невозможно откатить изменения; последний, кто вносил изменения, является единственным автором этой статьи.',
+'alreadyrolled' => 'Невозможно откатить последние изменения [[:$1]],
+сделанные [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|Обсуждение]]); кто-то другой уже отредактировал или откатил эту страницу.
+
+Последние изменения внёс [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|Обсуждение]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Изменение было пояснено так: <em>«$1»</em>.',
+'revertpage' => 'Правки [[{{ns:special}}:Contributions/$2|$2]] ([[User_talk:$2|обсуждение]]) откачены к версии [[User:$1|$1]]',
+'sessionfailure' => 'Похоже, возникли проблемы с текущим сеансом работы;
+это действие было отменено в целях предотвращения «захвата сеанса».
+Пожалуйста, нажмите кнопку «Назад» и перезагрузите страницу, с которой вы пришли.',
+'protectlogpage' => 'Журнал защиты',
+'protectlogtext' => 'Ниже приведён журнал установок и снятий защиты со статей.',
+'protectedarticle' => 'защищена страница «[[$1]]»',
+'unprotectedarticle' => 'снята защита со страницы «[[$1]]»',
+'protectsub' =>'(Установка защиты для «$1»)',
+'confirmprotecttext' => 'Вы действительно хотите установить защиту этой страницы?',
+'confirmprotect' => 'Подтвердите установку защиты страницы',
+'protectmoveonly' => 'Защитить только от переименования',
+'protectcomment' => 'Причина установки защиты',
+'unprotectsub' =>'(Снятие защиты «$1»)',
+'confirmunprotecttext' => 'Вы действительно хотите снять защиту этой страницы?',
+'confirmunprotect' => 'Подтвердите снятие защиты страницы',
+'unprotectcomment' => 'Причина снятия защиты',
+'protect-unchain' => 'Разблокировать переименование страницы',
+'protect-text' => 'Здесь вы можете просмотреть и изменить уровень защиты для страницы <strong>[[:$1]]</strong>.',
+'protect-viewtext' => 'У вас недостаточно прав для изменения уровня защиты страницы. Текущие установки для страницы <strong>[[:$1]]</strong>:',
+'protect-default' => '(по умолчанию)',
+'protect-level-autoconfirmed' => 'Защитить от незарегистрированных и новых участников',
+'protect-level-sysop' => 'Только администраторы',
+
+# restrictions (nouns)
+'restriction-edit' => 'Правка',
+'restriction-move' => 'Переименование',
+
+# Undelete
+'undelete' => 'Просмотреть удалённые страницы',
+'undeletepage' => 'Просмотр и восстановление удалённых страниц',
+'viewdeletedpage' => 'Просмотреть удалённые страницы',
+'undeletepagetext' => 'Следующие страницы были удалены, однако они всё ещё находятся в архиве, и поэтому могут быть восстановлены. Архив периодически очищается.',
+'undeleteextrahelp' => "Для полного восстановления страницы оставьте все отметки пустыми и нажмите '''«Восстановить»'''. Для частичного восстановления отметьте те версии страницы, которые нужно восстановить и нажмите '''«Восстановить»'''. Нажмите '''«Очистить»''', чтобы снять все отметки и очистить поле комментария.",
+'undeletearticle' => 'Восстановить удалённую страницу',
+'undeleterevisions' => 'В архиве $1 {{plural:$1|версия|версии|версий}}',
+'undeletehistory' => 'Если вы восстановите страницу, все её версии будут также восстановлены вместе с журналом изменений.
+Если с момента удаления была создана новая страница с таким же названием, восстановленные версии будут указаны в журнале изменений перед новыми записями, и текущая версия существующей страницы автоматически заменена не будет.',
+'undeletehistorynoadmin' => 'Статья была удалена. Причина удаления и список участников, редактировавших статью до её удаления, показаны ниже. Текст удалённой статьи могут просмотреть только администраторы.',
+'undeleterevision' => 'Стёртая версия от $1',
+'undeleterevision-missing' => "Неправильная версия. Ошибочная ссылка, или указанная версия страницы была удалена из архива.",
+'undeletebtn' => 'Восстановить',
+'undeletereset' => 'Очистить',
+'undeletecomment' => 'Комментарий:',
+'undeletedarticle' => '«[[$1]]» восстановлена',
+'undeletedrevisions' => '$1 {{plural:$1|изменение|изменения|изменений}} восстановлено',
+'undeletedrevisions-files' => '$1 {{plural:$1|версия|версии|версий}} и $2 {{plural:$2|файл|файла|файлов}} восстановлено',
+'undeletedfiles' => '$1 {{plural:$1|файл|файла|файлов}} {{plural:$1|восстановлен|восстановлено|восстановлено}}',
+'cannotundelete' => 'Ошибка восстановления. Возможно, кто-то другой уже восстановил страницу.',
+'undeletedpage' => "<big>'''Страница «$1» была восстановлена.'''</big>
+
+Для просмотра списка последних удалений и восстановлений см. [[{{ns:special}}:Log/delete|журнал удалений]].",
+
+# Namespace form on various pages
+'namespace' => 'Пространство имён:',
+'invert' => 'Обратить выделенное',
+
+# Contributions
+#
+'contributions' => 'Вклад участника',
+'mycontris' => 'Мой вклад',
+'contribsub' => 'Вклад $1',
+'nocontribs' => 'Изменений, соответствующих заданным условиям, найдено не было.',
+'ucnote' => 'Ниже приводятся последние <strong>$1</strong> изменений, сделанных этим участником за последние <strong>$2</strong> дня(ей).',
+'uclinks' => 'Просмотреть $1 {{plural:$1|последнее изменение|последних изменения|последних изменений}}; просмотреть за {{plural:$2|последний|последние|последние}} $2 {{plural:$2|день|дня|дней}}.',
+'uctop' => ' (последняя)' ,
+'newbies' => 'новичков',
+
+'sp-contributions-newest' => 'недавние',
+'sp-contributions-oldest' => 'старейшие',
+'sp-contributions-newer' => 'следующие $1',
+'sp-contributions-older' => 'предыдущие $1',
+'sp-contributions-newbies-sub' => 'Вклад новичков',
+'sp-contributions-blocklog' => 'Журнал блокировок',
+
+'sp-newimages-showfrom' => 'Показать новые изображения, начиная с $1',
+
+# What links here
+#
+'whatlinkshere' => 'Ссылки сюда',
+'notargettitle' => 'Не указана цель',
+'notargettext' => 'Вы не указали целевую страницу или участника для этого действия.',
+'linklistsub' => '(Список ссылок)',
+'linkshere' => "Следующие страницы ссылаются на '''[[:$1]]''':",
+'nolinkshere' => "На страницу '''[[:$1]]''' отсутствуют ссылки с других страниц.",
+'isredirect' => 'страница-перенаправление',
+'istemplate' => 'включение',
+
+# Block/unblock IP
+#
+'blockip' => 'Заблокировать участника',
+'blockiptext' => 'Используйте форму ниже, чтобы заблокировать возможность записи с определённого IP-адреса.
+Это может быть сделано только для предотвращения вандализма и только в соответствии с
+правилами изложенными в разделе [[{{ns:project}}:Правила]].
+Ниже укажите конкретную причину (к примеру, процитируйте некоторые страницы с признаками вандализма).',
+'ipaddress' => 'IP-адрес',
+'ipadressorusername' => 'IP-адрес или имя участника',
+'ipbexpiry' => 'Закончится через',
+'ipbreason' => 'Причина',
+'ipbanononly' => 'Блокировать только анонимных участников',
+'ipbcreateaccount' => 'Запретить создание новых учётных записей',
+'ipbenableautoblock' => 'Автоматически блокировать использованные участником IP-адреса',
+'ipbsubmit' => 'Заблокировать этот адрес/участника',
+'ipbother' => 'Другое время',
+'ipboptions' => '15 минут:15 minutes,2 часа:2 hours,6 часов:6 hours,12 часов:12 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',
+'ipbotheroption' => 'иное',
+'badipaddress' => 'IP-адрес записан в неправильном формате, или участника с таким именем не существует.',
+'blockipsuccesssub' => 'Блокировка произведена',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|«$1»]] заблокирован.
+<br />См. [[{{ns:special}}:Ipblocklist|список заблокированных IP-адресов]].',
+'unblockip' => 'Разблокировать IP-адрес',
+'unblockiptext' => 'Используйте форму ниже, чтобы восстановить возможность записи с ранее заблокированного
+IP-адреса.',
+'ipusubmit' => 'Разблокировать этот адрес',
+'unblocked' => '[[User:$1|$1]] разблокирован.',
+'ipblocklist' => 'Список заблокированных IP-адресов и пользователей',
+'blocklistline' => '$1, $2 заблокировал $3 ($4)',
+'infiniteblock' => 'бессрочная блокировка',
+'expiringblock' => 'блокировка завершится $1',
+'anononlyblock' => 'только анонимов',
+'noautoblockblock' => 'автоблокировка отключена',
+'createaccountblock' => 'создание учётных записей заблокировано',
+'ipblocklistempty' => 'Список блокировок пуст.',
+'blocklink' => 'заблокировать',
+'unblocklink' => 'разблокировать',
+'contribslink' => 'вклад',
+'autoblocker' => 'Вы автоматически заблокированы из-за совпадения вашего IP-адреса с «$1». Причина его блокировки — «$2».',
+'blocklogpage' => 'Журнал блокировок',
+'blocklogentry' => '«[[$1]]» заблокирован на период $2',
+'blocklogtext' => 'Это — журнал блокирования и разблокирования участников. Автоматически блокируемые IP-адреса здесь не указываются. См. [[{{ns:special}}:Ipblocklist|Список текущих запретов и блокировок]].',
+'unblocklogentry' => '«$1» разблокирован',
+'range_block_disabled' => 'Администраторам запрещено блокировать диапазоны.',
+'ipb_expiry_invalid' => 'Недопустимый период действия.',
+'ipb_already_blocked' => '«$1» уже заблокирован.',
+'ip_range_invalid' => 'Недопустимый диапазон IP-адресов.\n',
+'proxyblocker' => 'Блокировка прокси',
+'ipb_cant_unblock' => 'Ошибка. Блокировка с идентификатором «$1» не найдена. Возможно, участника уже разблокировали.',
+'proxyblockreason' => 'Ваш IP-адрес заблокирован потому что это открытый прокси. Пожалуйста, свяжитесь с вашим интернет-провайдером или службой поддержки и сообщите им об этой серьёзной проблеме безопасности.',
+'proxyblocksuccess' => 'Выполнено.',
+'sorbsreason' => 'Ваш IP-адрес числится как открытый прокси в DNSBL.',
+'sorbs_create_account_reason' => 'Ваш IP-адрес числится как открытый прокси в DNSBL. Вы не можете создать учётную запись.',
+
+# Developer tools
+#
+'lockdb' => 'Сделать базу данных доступной только для чтения',
+'unlockdb' => 'Восстановить возможность записи в базу данных',
+'lockdbtext' => 'Блокировка базы данных приостановит для всех участников возможность редактировать страницы, изменять настройки,
+изменять списки наблюдения и производить другие действия, требующие доступа к базе данных.
+Пожалуйста, подтвердите, что это — именно то, что вы хотите сделать, и что вы снимете блокировку как только закончите
+процедуру обслуживания базы данных.',
+'unlockdbtext' => 'Разблокирование базы данных восстановит для всех участников
+возможность редактировать страницы, изменять настройки, изменять списки наблюдения и производить
+другие действия, требующие доступа к базе данных.
+Пожалуйста, подтвердите, что вы намерены это сделать.',
+'lockconfirm' => 'Да, я действительно хочу заблокировать базу данных на запись.',
+'unlockconfirm' => 'Да, я действительно хочу снять блокировку базы данных.',
+'lockbtn' => 'Сделать базу данных доступной только для чтения',
+'unlockbtn' => 'Восстановить возможность записи в базу данных',
+'locknoconfirm' => 'Вы не поставили галочку в поле подтверждения.',
+'lockdbsuccesssub' => 'База данных заблокирована',
+'unlockdbsuccesssub' => 'База данных разблокирована',
+'lockdbsuccesstext' => 'База данных проекта была заблокирована.
+<br />Не забудьте [[{{ns:special}}:Unlockdb|убрать блокировку]] после завершения процедуры обслуживания.',
+'unlockdbsuccesstext' => 'База данных проекта была разблокирована.',
+'lockfilenotwritable' => 'Нет права на запись в файл блокировки базы данных. Чтобы заблокировать или разблокировать БД, веб-сервер должен иметь разрешение на запись в этот файл.',
+'databasenotlocked' => 'База данных не была заблокирована.',
+
+# Make sysop
+'makesysoptitle' => 'Сделать пользователя администратором',
+'makesysoptext' => 'Эта форма предназначена для бюрократов, и позволяет присваивать участникам статус администратора.
+Наберите имя участника и нажмите кнопку, чтобы сделать участника администратором',
+'makesysopname' => 'Имя участника:',
+'makesysopsubmit' => 'Сделать этого участника администратором',
+'makesysopok' => '<strong>Участнику [[Участник:$1|$1]] присвоен статус администратора</strong>',
+'makesysopfail' => '<strong>Участника $1 невозможно сделать администратором. (Вы уверены, что правильно ввели его имя?)</strong>',
+'setbureaucratflag' => 'Установить флаг «Бюрократ»',
+'rightslog' => 'Журнал прав пользователя',
+'rightslogtext' => 'Это журнал изменений прав пользователей.',
+'rightslogentry' => 'Для участника $1 изменены права доступа: с $2 на $3',
+'rights' => 'Права:',
+'set_user_rights' => 'Установить права пользователя',
+'user_rights_set' => '<strong>Права пользователя $1 обновлены</strong></strong>',
+'set_rights_fail' => '<strong>Невозможно установить права для пользователя $1. (Проверьте, правильно ли введено его имя)</strong>',
+'makesysop' => 'Присвоить участнику статус администратора',
+'already_sysop' => 'Этот участник уже является администратором',
+'already_bureaucrat' => 'Этот участник уже является бюрократом',
+'rightsnone' => '(нет)',
+
+# Move page
+#
+'movepage' => 'Переименовать страницу',
+'movepagetext' => 'Воспользовавшись формой ниже, вы переименуете страницу, одновременно переместив на новое место её журнал изменений.
+Старое название станет перенаправлением на новое название.
+Ссылки на старое название не будут изменены (пожалуйста, проверьте наличие [[{{ns:special}}:DoubleRedirects|двойных]] и [[{{ns:special}}:BrokenRedirects|разорванных]] перенаправлений).
+Вы обязаны убедиться в том, что ссылки и далее указывают туда, куда предполагалось.
+
+Обратите внимание, что страница \'\'\'не будет\'\'\' переименована, если страница с новым названием уже существует (кроме случаев, если она является перенаправлением или пуста и не имеет истории правок). Это означает, что вы можете переименовать страницу обратно в то название, которое у него только что было, если вы переименовали по ошибке, но вы не можете случайно затереть существующую страницу.
+
+\'\'\'ПРЕДУПРЕЖДЕНИЕ!\'\'\'
+Переименование может привести к масштабным и неожиданным изменениям для \'\'популярных\'\' страниц. Пожалуйста, прежде чем вы продолжите, убедитесь, что вы понимаете все возможные последствия.',
+'movepagetalktext' => 'Присоединённая страница обсуждения, если таковая есть,
+будет также автоматически переименована, \'\'\'кроме случаев, когда:\'\'\'
+
+*Не пустая страница обсуждения уже существует под таким же именем или
+*Вы не поставили галочку в поле ниже.
+
+В этих случаях, вы будете вынуждены переместить или объединить страницы вручную,
+если это нужно.',
+'movearticle' => 'Переименовать страницу',
+'movenologin' => 'Вы не представились системе',
+'movenologintext' => 'Вы должны [[{{ns:special}}:Userlogin|представиться системе]],
+чтобы иметь возможность переименовать страницы.',
+'newtitle' => 'Новое название',
+'movepagebtn' => 'Переименовать страницу',
+'pagemovedsub' => 'Страница переименована',
+'pagemovedtext' => 'Страница [[$1|«$1»]] переименована в [[$2|«$2»]].',
+'articleexists' => 'Страница с таким именем уже существует или указанное вами название недопустимо.
+Пожалуйста, выберите другое название.',
+'talkexists' => "'''Страница была переименована, но страница обсуждения
+не может быть переименована, потому что страница с таким названием уже
+существует. Пожалуйста, объедините их вручную.'''",
+'movedto' => 'переименована в',
+'movetalk' => 'Переименовать соответствующую страницу обсуждения',
+'talkpagemoved' => 'Соответствующая страница обсуждения также переименована.',
+'talkpagenotmoved' => 'Соответствующая страница обсуждения <strong>не</strong> была переименована.',
+'1movedto2' => '«[[$1]]» переименована в «[[$2]]»',
+'1movedto2_redir' => '«[[$1]]» переименована в «[[$2]]», установлено перенаправление',
+'movelogpage' => 'Журнал переименований',
+'movelogpagetext' => 'Ниже представлен список переименованных страниц.',
+'movereason' => 'Причина',
+'revertmove' => 'откат',
+'delete_and_move' => 'Удалить и переименовать',
+'delete_and_move_text' =>
+'==Требуется удаление==
+
+Страница с именем [[$1|«$1»]] уже существует. Вы хотите её удалить, чтобы сделать возможным переименование?',
+'delete_and_move_reason' => 'Удалено для возможности переименования',
+'delete_and_move_confirm' => 'Да, удалить эту страницу',
+'selfmove' => 'Невозможно переименовать страницу: исходное и новое имя страницы совпадают.',
+'immobile_namespace' => 'Невозможно переименовать страницу: новое или старое имя содержит зарезервированное служебное слово.',
+
+# Export
+
+'export' => 'Экспортирование статей',
+'exporttext' => 'Вы можете экспортировать текст и журнал изменений конкретной страницы или набора страниц в XML, который потом может быть импортирован в другой вики-проект, работающий на программном обеспечении MediaWiki.
+
+Чтобы экспортировать статьи, введите их наименования в поле редактирования, одно название на строку, и выберите хотите ли вы экспортировать всю историю изменений статей или только последние версии статей.
+
+Вы также можете использовать специальный адрес для экспорта только последней версии. Например для страницы «{{int:mainpage}}» это будет адрес [[{{ns:Special}}:Export/{{int:mainpage}}]].',
+'exportcuronly' => 'Включать только текущую версию, без полной предыстории',
+'exportnohistory' => "----
+'''Замечание:''' экспорт полной истории изменений страниц отключен из-за проблем с производительностью.",
+'export-submit' => 'Экспортировать',
+
+# Namespace 8 related
+
+'allmessages' => 'Системные сообщения',
+'allmessagesname' => 'Сообщение',
+'allmessagesdefault' => 'Текст по умолчанию',
+'allmessagescurrent' => 'Текущий текст',
+'allmessagestext' => 'Ниже представлен список системных сообщений, доступных в пространстве имён «MediaWiki».',
+'allmessagesnotsupportedUI' => 'Текущий установленный язык <strong>$1</strong> не поддерживается Special:Allmessages на этом сайте.',
+'allmessagesnotsupportedDB' => "'''Special:Allmessages''' не поддерживается, так как отключена опция '''wgUseDatabaseMessages'''.",
+'allmessagesfilter' => 'Фильтр в формате регулярного выражения:',
+'allmessagesmodified' => 'Показать только изменённые',
+
+# Thumbnails
+
+'thumbnail-more' => 'Увеличить',
+'missingimage' => '<strong>Изображение не найдено</strong><br /><em>$1</em>\n',
+'filemissing' => 'Файл не найден',
+'thumbnail_error' => 'Ошибка создания миниатюры: $1',
+
+# Special:Import
+'import' => 'Импортирование страниц',
+'importinterwiki' => 'Межвики импорт',
+'import-interwiki-text' => 'Укажите вики и название импортируемой страницы.
+Даты изменений и имена авторов будут сохранены.
+Все операции межвики импорта регистрируются в [[{{ns:special}}:Log/import|соответствующем журнале]].',
+'import-interwiki-history' => 'Копировать всю историю изменений этой страницы',
+'import-interwiki-submit' => 'Импортировать',
+'import-interwiki-namespace' => 'Помещать страницы в пространство имён:',
+
+'importtext' => 'Пожалуйста, экспортируйте страницу из исходной вики используя инструмент Special:Export, сохраните файл на диск, а затем загрузите его сюда.',
+'importstart' => "Импортирование страниц…",
+'import-revision-count' => '$1 {{PLURAL:$1|версия|версии|версий}}',
+'importnopages' => "Нет страниц для импортирования.",
+'importfailed' => 'Не удалось импортировать: $1',
+'importunknownsource' => "Неизвестный тип импортируемой страницы",
+'importcantopen' => "Невозможно открыть импортируемый файл",
+'importbadinterwiki' => "Неправильная интервики-ссылка",
+'importnotext' => 'Текст отсутствует',
+'importsuccess' => 'Импортировано выполнено!',
+'importhistoryconflict' => 'Конфликт существующих версий (возможно, эта страница уже была импортирована)',
+'importnosources' => 'Не был выбран источник межвики импорта, прямая загрузка истории изменений отключена.',
+'importnofile' => 'Файл для импорта не был загружен.',
+'importuploaderror' => 'Ошибка загрузки файла для импорта, возможно размер файла превышает установленную норму.',
+
+# import log
+'importlogpage' => 'Журнал импорта',
+'importlogpagetext' => 'Импортирование администраторами страниц с историей изменений из других вики.',
+'import-logentry-upload' => '«[[$1]]» — импорт из файла',
+'import-logentry-upload-detail' => '$1 версий',
+'import-logentry-interwiki' => '«$1» — межвики импорт',
+'import-logentry-interwiki-detail' => '$1 версий из $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Искать [alt-f]',
+'tooltip-minoredit' => 'Отметить это изменение как незначительное [alt-i]',
+'tooltip-save' => 'Сохранить ваши изменения [alt-s]',
+'tooltip-preview' => 'Предварительный просмотр страницы, пожалуйста, используйте перед сохранением! [alt-p]',
+'tooltip-diff' => 'Показать изменения, сделанные по отношению к исходному тексту. [alt-v]',
+'tooltip-compareselectedversions' => 'Посмотреть разницу между двумя выбранными версиями этой страницы. [alt-v]',
+'tooltip-watch' => 'Добавить текущую страницу в список наблюдения [alt-w]',
+
+# stylesheets
+'common.css' => '/** Размещённый здесь CSS будет применяться ко всем темам оформления */',
+'monobook.css' => '/* Размещённый здесь CSS будет применяться к теме оформления Monobook */
+
+/*
+Это нужно чтобы в окошке поиска кнопки не разбивались на 2 строки
+к сожалению в main.css для кнопки Go прописаны паддинги .5em.
+Что хорошо для "Go" плохо для "Перейти" --st0rm
+*/
+
+#searchGoButton {
+ padding-left: 0em;
+ padding-right: 0em;
+ font-weight: bold;
+}',
+#'monobook.js' => '/* edit this file to change js things in the monobook skin */',
+
+# Metadata
+'nodublincore' => 'Метаданные Dublin Core RDF запрещены для этого сервера.',
+'nocreativecommons' => 'Метаданные Creative Commons RDF запрещены для этого сервера.',
+'notacceptable' => 'Вики-сервер не может предоставить данные в формате, который мог бы прочитать ваш браузер.<br />
+The wiki server can\'t provide data in a format your client can read.',
+
+# Attribution
+
+'anonymous' => 'Анонимные пользователи {{grammar:genitive|{{SITENAME}}}}',
+'siteuser' => 'Участник {{grammar:genitive|{{SITENAME}}}} $1',
+'lastmodifiedatby' => 'Эта страница последний раз была изменена $2, $1 участником $3.',
+'and' => 'и',
+'othercontribs' => 'Основано на работе $1.',
+'others' => 'другие',
+'siteusers' => 'Участник(и) {{grammar:genitive|{{SITENAME}}}} $1',
+'creditspage' => 'Благодарности',
+'nocredits' => 'Нет списка участников для этой статьи',
+
+# Spam protection
+
+'spamprotectiontitle' => 'Спам-фильтр',
+'spamprotectiontext' => 'Страница, которую вы пытаетесь сохранить, заблокирована спам-фильтром. Вероятнее всего она содержит ссылку на внешний сайт.',
+'spamprotectionmatch' => 'Следующее сообщение было получено от спам-фильтра: $1.',
+'subcategorycount' => 'В этой категории $1 {{PLURAL:$1|подкатегория|подкатегории|подкатегорий}}.',
+'category-media-count' => "В этой категории $1 {{PLURAL:$1|файл|файла|файлов}}.",
+'categoryarticlecount' => 'В этой категории $1 {{PLURAL:$1|статья|статьи|статей}}.',
+'listingcontinuesabbrev' => ' (продолжение)',
+'spambot_username' => 'Чистка спама',
+'spam_reverting' => 'Откат к последней версии, не содержащей ссылки на $1',
+'spam_blanking' => 'Все версии содержат ссылки на $1, очистка',
+
+# Info page
+'infosubtitle' => 'Информация о странице',
+'numedits' => 'Число правок (статья): $1',
+'numtalkedits' => 'Число правок (страница обсуждения): $1',
+'numwatchers' => 'Число наблюдателей: $1',
+'numauthors' => 'Число различных авторов (статья): $1',
+'numtalkauthors' => 'Число различных авторов (страница обсуждения): $1',
+
+# Math options
+'mw_math_png' => 'Всегда генерировать PNG',
+'mw_math_simple' => 'HTML в простых случаях, иначе PNG',
+'mw_math_html' => 'HTML, если возможно, иначе PNG',
+'mw_math_source' => 'Оставить в разметке ТеХ (для текстовых браузеров)',
+'mw_math_modern' => 'Как рекомендуется для современных браузеров',
+'mw_math_mathml' => 'MathML, если возможно (экспериментальная опция)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Отметить как проверенную',
+'markaspatrolledtext' => 'Отметить эту статью как проверенную',
+'markedaspatrolled' => 'Отмечена как проверенная',
+'markedaspatrolledtext' => 'Выбранная версия отмечена как проверенная.',
+'rcpatroldisabled' => 'Патрулирование последних изменений запрещено',
+'rcpatroldisabledtext' => 'Возможность патрулирования последних изменений в настоящее время отключена.',
+'markedaspatrollederror' => "Невозможно отметить как проверенную",
+'markedaspatrollederrortext' => "Вы должны указать редакцию, которая будет отмечена как проверенная.",
+'markedaspatrollederror-noautopatrol' => 'Вам не разрешено отмечать собственные правки как проверенные.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Моя страница пользователя\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Страница пользователя для моего IP\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Моя страница обсуждений\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Страница обсуждений для моего IP\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Мои настройки\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Список страниц моего наблюдения\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Список страниц, которые я редактировал\');
+ta[\'pt-login\'] = new Array(\'o\',\'Здесь можно зарегистрироваться в системе, но это необязательно\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Здесь можно зарегистрироваться в системе, но это необязательно\');
+ta[\'pt-logout\'] = new Array(\'\',\'Отказаться от регистрации\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Обсуждение статьи\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Эту статью можно изменять. Перед сохранением изменений, пожалуйста, нажмите кнопку предварительного просмотра для визуальной проверки результата\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Добавить комментарий к обсуждению\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Эта страница защищена от изменений, но вы можете посмотреть и скопировать её исходный текст\');
+ta[\'ca-history\'] = new Array(\'h\',\'Журнал изменений страницы\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Защитить страницу от изменений\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Удалить эту страницу\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Восстановить исправления страницы, сделанные до того, как она была удалена\');
+ta[\'ca-move\'] = new Array(\'m\',\'Переименовать страницу\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Добавить эту страницу в ваш список наблюдения\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Удалить эту страницу из вашего списка наблюдения\');
+ta[\'search\'] = new Array(\'f\',\'Искать это слово\');
+ta[\'p-logo\'] = new Array(\'\',\'Заглавная страница\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Перейти на заглавную страницу\');
+ta[\'n-portal\'] = new Array(\'\',\'О проекте, о том, что вы можете сделать, где что находится\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Список текущих событий\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Список последних изменений\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Посмотреть случайную страницу\');
+ta[\'n-help\'] = new Array(\'\',\'Справочник по проекту «{{SITENAME}}»\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Поддержите проект\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Список всех страниц, которые ссылаются на эту страницу\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Последние изменения в страницах, которые ссылаются на эту страницу\');
+ta[\'feed-rss\'] = new Array(\'\',\'Трансляция в формате RSS для этой страницы\');
+ta[\'feed-atom\'] = new Array(\'\',\'Трансляция в формате Atom для этой страницы\');
+ta[\'t-contributions\'] = new Array(\'\',\'Список страниц, которые изменял этот участник\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Отправить письмо этому участнику\');
+ta[\'t-upload\'] = new Array(\'u\',\'Загрузить изображения или мультимедиа-файлы\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Список служебных страниц\');
+ta[\'t-print\']=new Array(\'\', \'Версия без кнопок, пригодная для распечатки\');
+ta[\'t-permalink\'] = new Array(\'\', \'Ссылка на текущую версию этой статьи\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Содержание статьи\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Персональная страница участника\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Мультимедиа-файл\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Это служебная страница, она недоступна для редактирования\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Страница проекта\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Страница изображения\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Страница сообщения MediaWiki\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Страница шаблона\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Страница справки\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Страница категории\');',
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Размещённый здесь код JavaScript будет загружен всем пользователям при обращении к какой-либо странице */',
+
+# image deletion
+'deletedrevision' => 'Удалена старая версия $1.',
+
+# browsing diffs
+'previousdiff' => '← К предыдущему изменению',
+'nextdiff' => 'К следующему изменению →',
+
+'imagemaxsize' => 'Ограничивать изображения на странице изображений до:',
+'thumbsize' => 'Размер уменьшенной версии изображения:',
+'showbigimage' => 'Загрузить с высоким разрешением ($1 × $2, $3 КБ)',
+
+'newimages' => 'Галерея новых файлов',
+'showhidebots' => '($1 ботов)',
+'noimages' => 'Изображения отсутствуют.',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Участник:',
+'speciallogtitlelabel' => 'Заголовок:',
+
+'passwordtooshort' => 'Введённый пароль слишком короткий. Пароль должен состоять не менее чем из $1 символов.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Внимание\'\'\': этот файл может содержать вредоносный программный код, выполнение которого способно подвергнуть риску вашу систему. <hr />',
+'fileinfo' => '$1 КБ, MIME-тип: <code>$2</code>',
+
+# Exif data
+'metadata' => 'Метаданные',
+'metadata-help' => 'Файл содержит дополнительные данные, обычно добавляемые цифровыми камерами или сканерами. Если файл после создания редактировался, то некоторые параметры могут не соответствовать текущему изображению.',
+'metadata-expand' => 'Показать дополнительные данные',
+'metadata-collapse' => 'Скрыть дополнительные данные',
+'metadata-fields' => 'Поля метаданных, перечисленные в этом списке, будут показаны на странице изображения по умолчанию, остальные будут скрыты.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# Exif tags
+'exif-imagewidth' =>'Ширина',
+'exif-imagelength' =>'Высота',
+'exif-bitspersample' =>'Глубина цвета',
+'exif-compression' =>'Метод сжатия',
+'exif-photometricinterpretation' =>'Цветовая модель',
+'exif-orientation' =>'Ориентация кадра',
+'exif-samplesperpixel' =>'Количество цветовых компонентов',
+'exif-planarconfiguration' =>'Принцип организации данных',
+'exif-ycbcrsubsampling' =>'Отношение размеров компонент Y и C',
+'exif-ycbcrpositioning' =>'Порядок размещения компонент Y и C',
+'exif-xresolution' =>'Горизонтальное разрешение',
+'exif-yresolution' =>'Вертикальное разрешение',
+'exif-resolutionunit' =>'Единица измерения разрешения',
+'exif-stripoffsets' =>'Положение блока данных',
+'exif-rowsperstrip' =>'Количество строк в 1 блоке',
+'exif-stripbytecounts' =>'Размер сжатого блока',
+'exif-jpeginterchangeformat' =>'Положение начала блока preview',
+'exif-jpeginterchangeformatlength' =>'Размер данных блока preview',
+'exif-transferfunction' =>'Функция преобразования цветового пространства',
+'exif-whitepoint' =>'Цветность белой точки',
+'exif-primarychromaticities' =>'Цветность основных цветов',
+'exif-ycbcrcoefficients' =>'Коэффициенты преобразования цветовой модели',
+'exif-referenceblackwhite' =>'Положение белой и чёрной точек',
+'exif-datetime' =>'Дата и время изменения файла',
+'exif-imagedescription' =>'Название изображения',
+'exif-make' =>'Производитель камеры',
+'exif-model' =>'Модель камеры',
+'exif-software' =>'Программное обеспечение',
+'exif-artist' =>'Автор',
+'exif-copyright' =>'Владелец авторского права',
+'exif-exifversion' =>'Версия Exif',
+'exif-flashpixversion' =>'Поддерживаемая версия FlashPix',
+'exif-colorspace' =>'Цветовое пространство',
+'exif-componentsconfiguration' =>'Конфигурация цветовых компонентов',
+'exif-compressedbitsperpixel' =>'Глубина цвета после сжатия',
+'exif-pixelydimension' =>'Полная высота изображения',
+'exif-pixelxdimension' =>'Полная ширина изображения',
+'exif-makernote' =>'Дополнительные данные производителя',
+'exif-usercomment' =>'Дополнительный комментарий',
+'exif-relatedsoundfile' =>'Файл звукового комментария',
+'exif-datetimeoriginal' =>'Оригинальные дата и время',
+'exif-datetimedigitized' =>'Дата и время оцифровки',
+'exif-subsectime' =>'Доли секунд времени изменения файла',
+'exif-subsectimeoriginal' =>'Доли секунд оригинального времени',
+'exif-subsectimedigitized' =>'Доли секунд времени оцифровки',
+'exif-exposuretime' =>'Время экспозиции',
+'exif-exposuretime-format' => '$1 с ($2)',
+'exif-fnumber' =>'Число диафрагмы',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'Программа экспозиции',
+'exif-spectralsensitivity' =>'Спектральная чувствительность',
+'exif-isospeedratings' =>'Светочувствительность ISO',
+'exif-oecf' =>'OECF (коэффициент оптоэлектрического преобразования)',
+'exif-shutterspeedvalue' =>'Выдержка',
+'exif-aperturevalue' =>'Диафрагма',
+'exif-brightnessvalue' =>'Яркость',
+'exif-exposurebiasvalue' =>'Компенсация экспозиции',
+'exif-maxaperturevalue' =>'Минимальное число диафрагмы',
+'exif-subjectdistance' =>'Расстояние до объекта',
+'exif-meteringmode' =>'Режим замера экспозиции',
+'exif-lightsource' =>'Источник света',
+'exif-flash' =>'Статус вспышки',
+'exif-focallength' =>'Фокусное расстояние',
+'exif-focallength-format' =>'$1 мм',
+'exif-subjectarea' =>'Положение и площадь объекта съёмки',
+'exif-flashenergy' =>'Энергия вспышки',
+'exif-spatialfrequencyresponse' =>'Пространственная частотная характеристика',
+'exif-focalplanexresolution' =>'Разрешение по X в фокальной плоскости',
+'exif-focalplaneyresolution' =>'Разрешение по Y в фокальной плоскости',
+'exif-focalplaneresolutionunit' =>'Единица измерения разрешения в фокальной плоскости',
+'exif-subjectlocation' =>'Положение объекта относительно левого верхнего угла',
+'exif-exposureindex' =>'Индекс экспозиции',
+'exif-sensingmethod' =>'Тип сенсора',
+'exif-filesource' =>'Источник файла',
+'exif-scenetype' =>'Тип сцены',
+'exif-cfapattern' =>'Тип цветового фильтра',
+'exif-customrendered' =>'Дополнительная обработка',
+'exif-exposuremode' =>'Режим выбора экспозиции',
+'exif-whitebalance' =>'Баланс белого',
+'exif-digitalzoomratio' =>'Коэффициент цифрового увеличения (цифровой зум)',
+'exif-focallengthin35mmfilm' =>'Эквивалентное фокусное расстояние (для 35 мм плёнки)',
+'exif-scenecapturetype' =>'Тип сцены при съёмке',
+'exif-gaincontrol' =>'Повышение яркости',
+'exif-contrast' =>'Контрастность',
+'exif-saturation' =>'Насыщенность',
+'exif-sharpness' =>'Резкость',
+'exif-devicesettingdescription' =>'Описание предустановок камеры',
+'exif-subjectdistancerange' =>'Расстояние до объекта съёмки',
+'exif-imageuniqueid' =>'Номер изображения (ID)',
+
+'exif-gpsversionid' =>'Версия блока GPS-информации',
+'exif-gpslatituderef' =>'Индекс широты',
+'exif-gpslatitude' =>'Широта',
+'exif-gpslongituderef' =>'Индекс долготы',
+'exif-gpslongitude' =>'Долгота',
+'exif-gpsaltituderef' =>'Индекс высоты',
+'exif-gpsaltitude' =>'Высота',
+'exif-gpstimestamp' =>'Точное время по UTC',
+'exif-gpssatellites' =>'Описание использованных спутников',
+'exif-gpsstatus' =>'Статус приёмника в момент съёмки',
+'exif-gpsmeasuremode' =>'Метод измерения положения',
+'exif-gpsdop' =>'Точность измерения',
+'exif-gpsspeedref' =>'Единицы измерения скорости',
+'exif-gpsspeed' =>'Скорость движения',
+'exif-gpstrackref' =>'Тип азимута приёмника GPS (истинный, магнитный)',
+'exif-gpstrack' =>'Азимут приёмника GPS',
+'exif-gpsimgdirectionref' =>'Тип азимута изображения (истинный, магнитный)',
+'exif-gpsimgdirection' =>'Азимут изображения',
+'exif-gpsmapdatum' =>'Использованная геодезическая система координат',
+'exif-gpsdestlatituderef' =>'Индекс долготы объекта',
+'exif-gpsdestlatitude' =>'Долгота объекта',
+'exif-gpsdestlongituderef' =>'Индекс широты объекта',
+'exif-gpsdestlongitude' =>'Широта объекта',
+'exif-gpsdestbearingref' =>'Тип пеленга объекта (истинный, магнитный)',
+'exif-gpsdestbearing' =>'Пеленг объекта',
+'exif-gpsdestdistanceref' =>'Единицы измерения расстояния',
+'exif-gpsdestdistance' =>'Расстояние',
+'exif-gpsprocessingmethod' =>'Метод вычисления положения',
+'exif-gpsareainformation' =>'Название области GPS',
+'exif-gpsdatestamp' =>'Дата',
+'exif-gpsdifferential' =>'Дифференциальная поправка',
+
+# Exif attributes
+
+'exif-compression-1' => 'Несжатый',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Нормальная', // 0th row: top; 0th column: left
+'exif-orientation-2' => 'Отражено по горизонтали', // 0th row: top; 0th column: right
+'exif-orientation-3' => 'Повёрнуто на 180°', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => 'Отражено по вертикали', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => 'Повёрнуто на 90° против часовой стрелки и отражено по вертикали', // 0th row: left; 0th column: top
+'exif-orientation-6' => 'Повёрнуто на 90° по часовой стрелке', // 0th row: right; 0th column: top
+'exif-orientation-7' => 'Повёрнуто на 90° по часовой стрелке и отражено по вертикали', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => 'Повёрнуто на 90° против часовой стрелки', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'формат «chunky»',
+'exif-planarconfiguration-2' => 'формат «planar»',
+
+'exif-xyresolution-i' => '$1 точек на дюйм',
+'exif-xyresolution-c' => '$1 точек на сантиметр',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'не существует',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Неизвестно',
+'exif-exposureprogram-1' => 'Ручной режим',
+'exif-exposureprogram-2' => 'Программный режим (нормальный)',
+'exif-exposureprogram-3' => 'Приоритет диафрагмы',
+'exif-exposureprogram-4' => 'Приоритет выдержки',
+'exif-exposureprogram-5' => 'Художественная программа (на основе нужной глубины резкости)',
+'exif-exposureprogram-6' => 'Спортивный режим (с минимальной выдержкой)',
+'exif-exposureprogram-7' => 'Портретный режим (для снимков на близком расстоянии, с фоном не в фокусе)',
+'exif-exposureprogram-8' => 'Пейзажный режим (для пейзажных снимков, с фоном в фокусе)',
+
+'exif-subjectdistance-value' => '$1 метров',
+
+'exif-meteringmode-0' => 'Неизвестно',
+'exif-meteringmode-1' => 'Средний',
+'exif-meteringmode-2' => 'Центровзвешенный',
+'exif-meteringmode-3' => 'Точечный',
+'exif-meteringmode-4' => 'Мультиточечный',
+'exif-meteringmode-5' => 'Матричный',
+'exif-meteringmode-6' => 'Частичный',
+'exif-meteringmode-255' => 'Другой',
+
+'exif-lightsource-0' => 'Неизвестно',
+'exif-lightsource-1' => 'Дневной свет',
+'exif-lightsource-2' => 'Лампа дневного света',
+'exif-lightsource-3' => 'Лампа накаливания',
+'exif-lightsource-4' => 'Вспышка',
+'exif-lightsource-9' => 'Хорошая погода',
+'exif-lightsource-10' => 'Облачно',
+'exif-lightsource-11' => 'Тень',
+'exif-lightsource-12' => 'Лампа дневного света тип D (5700 − 7100K)',
+'exif-lightsource-13' => 'Лампа дневного света тип N (4600 − 5400K)',
+'exif-lightsource-14' => 'Лампа дневного света тип W (3900 − 4500K)',
+'exif-lightsource-15' => 'Лампа дневного света тип WW (3200 − 3700K)',
+'exif-lightsource-17' => 'Стандартный источник света типа A',
+'exif-lightsource-18' => 'Стандартный источник света типа B',
+'exif-lightsource-19' => 'Стандартный источник света типа C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'Студийная лампа стандарта ISO',
+'exif-lightsource-255' => 'Другой источник света',
+
+'exif-focalplaneresolutionunit-2' => 'дюймов',
+
+'exif-sensingmethod-1' => 'Неопределённый',
+'exif-sensingmethod-2' => 'Однокристальный матричный цветной сенсор',
+'exif-sensingmethod-3' => 'Цветной сенсор с двумя матрицами',
+'exif-sensingmethod-4' => 'Цветной сенсор с тремя матрицами',
+'exif-sensingmethod-5' => 'Матричный сенсор с последовательным измерением цвета',
+'exif-sensingmethod-7' => 'Трёхцветный линейный сенсор',
+'exif-sensingmethod-8' => 'Линейный сенсор с последовательным измерением цвета',
+
+'exif-filesource-3' => 'Цифровой фотоаппарат',
+
+'exif-scenetype-1' => 'Изображение сфотографировано напрямую',
+
+'exif-customrendered-0' => 'Не производилась',
+'exif-customrendered-1' => 'Нестандартная обработка',
+
+'exif-exposuremode-0' => 'Автоматическая экспозиция',
+'exif-exposuremode-1' => 'Ручная установка экспозиции',
+'exif-exposuremode-2' => 'Брэкетинг',
+
+'exif-whitebalance-0' => 'Автоматический баланс белого',
+'exif-whitebalance-1' => 'Ручная установка баланса белого',
+
+'exif-scenecapturetype-0' => 'Стандартный',
+'exif-scenecapturetype-1' => 'Ландшафт',
+'exif-scenecapturetype-2' => 'Портрет',
+'exif-scenecapturetype-3' => 'Ночная съёмка',
+
+'exif-gaincontrol-0' => 'Нет',
+'exif-gaincontrol-1' => 'Небольшое увеличение',
+'exif-gaincontrol-2' => 'Большое увеличение',
+'exif-gaincontrol-3' => 'Небольшое уменьшение',
+'exif-gaincontrol-4' => 'Сильное уменьшение',
+
+'exif-contrast-0' => 'Нормальная',
+'exif-contrast-1' => 'Мягкое повышение',
+'exif-contrast-2' => 'Сильное повышение',
+
+'exif-saturation-0' => 'Нормальная',
+'exif-saturation-1' => 'Небольшая насыщенность',
+'exif-saturation-2' => 'Большая насыщенность',
+
+'exif-sharpness-0' => 'Нормальная',
+'exif-sharpness-1' => 'Мягкое повышение',
+'exif-sharpness-2' => 'Сильное повышение',
+
+'exif-subjectdistancerange-0' => 'Неизвестно',
+'exif-subjectdistancerange-1' => 'Макросъёмка',
+'exif-subjectdistancerange-2' => 'Съёмка с близкого расстояния',
+'exif-subjectdistancerange-3' => 'Съёмка издалека',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'северной широты',
+'exif-gpslatitude-s' => 'южной широты',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'восточной долготы',
+'exif-gpslongitude-w' => 'западной долготы',
+
+'exif-gpsstatus-a' => 'Измерение не закончено',
+'exif-gpsstatus-v' => 'Готов к передаче данных',
+
+'exif-gpsmeasuremode-2' => 'Измерение 2-х координат',
+'exif-gpsmeasuremode-3' => 'Измерение 3-х координат',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'км/час',
+'exif-gpsspeed-m' => 'миль/час',
+'exif-gpsspeed-n' => 'узлов',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'истинный',
+'exif-gpsdirection-m' => 'магнитный',
+
+# external editor support
+'edit-externally' => 'Редактировать этот файл, используя внешнюю программу',
+'edit-externally-help' => 'Подробности см. на странице [http://meta.wikimedia.org/wiki/Help:External_editors Meta:Help:External_editors].',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'все',
+'imagelistall' => 'все',
+'watchlistall1' => 'все',
+'watchlistall2' => 'все',
+'namespacesall' => 'все',
+
+# E-mail address confirmation
+'confirmemail' => 'Подтверждение адреса электронной почты',
+'confirmemail_noemail' => 'Вы не задали адрес электронной почты в [[{{ns:special}}:Preferences|настройках]], либо он некорректен.',
+'confirmemail_text' => 'Вики-движок требует подтверждения адреса электронной почты перед тем, как начать с ним работать.
+Нажмите на кнопку, чтобы на указанный адрес было отправлено письмо, содержащее ссылку на специальную страницу, после открытия которой в браузере адрес электронной почты будет считается подтверждённым.',
+'confirmemail_pending' => '<div class="error">
+Письмо с кодом подтверждения уже было отправлено.
+Если вы недавно создали учётную запись, то, вероятно,
+вам следует подождать несколько минут пока письмо придёт перед тем, как запросить код ещё раз.
+</div>',
+'confirmemail_send' => 'Отправить письмо с запросом на подтверждение',
+'confirmemail_sent' => 'Письмо с запросом на подтверждение отправлено.',
+'confirmemail_oncreate' => 'Письмо с кодом подтверждения было отправлено на указанный вами почтовый ящик.
+Данный код не требуется для входа в систему, однако вы должны указать его,
+прежде чем будет разрешено использование возможностей электронной почты в этом проекте.',
+'confirmemail_sendfailed' => 'Невозможно отправить письмо с запросом на подтверждение. Проверьте правильность адреса электронной почты.
+
+Ответ сервера: $1',
+'confirmemail_invalid' => 'Неправильный код подтверждения или срок действия кода истёк.',
+'confirmemail_needlogin' => 'Вы должны $1 для подтверждения вашего адреса электронной почты.',
+'confirmemail_success' => 'Ваш адрес электронной почты подтверждён.',
+'confirmemail_loggedin' => 'Ваш адрес электронной почты подтверждён.',
+'confirmemail_error' => 'Во время процедуры подтверждения адреса электронной почты произошла ошибка.',
+
+'confirmemail_subject' => '{{SITENAME}}:Запрос на подтверждение адреса эл. почты',
+'confirmemail_body' => 'Кто-то с IP-адресом $1 зарегистрировал на сервере проекта {{SITENAME}} учётную запись
+«$2», указав ваш адрес электронной почты.
+
+Чтобы подтвердить, что вы разрешаете использовать ваш адрес электронной почты в этом проекте, откройте в браузере приведённую ниже ссылку (это нужно сделать до $4):
+
+$3
+
+Если вы не отправляли подобного запроса, просто проигнорируйте данное письмо.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Строгий поиск',
+'searchfulltext' => 'Полнотекстовый поиск',
+'createarticle' => 'Создать статью',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[«Interwiki transcluding» отключён]',
+'scarytranscludefailed' => '[К сожалению, не удалось обращение к шаблону $1]',
+'scarytranscludetoolong' => '[К сожалению, URL слишком длинный]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackback для этой статьи:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 удалить])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'Trackback был удалён.',
+
+# delete conflict
+
+'deletedwhileediting' => 'Внимание: пока вы редактировали эту страницу она была удалена!',
+'confirmrecreate' => 'Участник [[User:$1|$1]] ([[User talk:$1|обсуждение]]) удалил эту страницу после того, как вы начали её редактировать, причина удаления:
+: \'\'$2\'\'
+Пожалуйста, подтвердите, что вы хотите восстановить эту страницу.',
+'recreate' => 'Создать заново',
+'tooltip-recreate' => 'Восстановить страницу несмотря на то, что она была удалена',
+
+'unit-pixel' => ' пикс.',
+
+# HTML dump
+'redirectingto' => 'Перенаправление на страницу [[$1]]…',
+
+# action=purge
+'confirm_purge' => "Очистить кеш этой страницы?\n\n$1",
+'confirm_purge_button' => 'OK',
+
+'youhavenewmessagesmulti' => "Вы получили новые сообщения на $1",
+
+'searchcontaining' => "Поиск статей, содержащих «$1».",
+'searchnamed' => "Поиск статей называющихся «$1».",
+'articletitles' => "Статьи, начинающиеся с «$1»",
+'hideresults' => 'Скрыть результаты',
+
+# DISPLAYTITLE
+'displaytitle' => '(Ссылка на эту страницу — $1)',
+
+'loginlanguagelabel' => 'Язык: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '← предыдущая страница',
+'imgmultipagenext' => 'следующая страница →',
+'imgmultigo' => 'Перейти!',
+'imgmultigotopre' => 'Перейти на страницу',
+
+# Table pager
+'ascending_abbrev' => 'возр',
+'descending_abbrev' => 'убыв',
+'table_pager_next' => 'Следующая страница',
+'table_pager_prev' => 'Предыдущая страница',
+'table_pager_first' => 'Первая страница',
+'table_pager_last' => 'Последняя страница',
+'table_pager_limit' => 'Показать $1 элементов на странице',
+'table_pager_limit_submit' => 'Выполнить',
+'table_pager_empty' => 'Не найдено',
+
+# Auto-summaries
+'autosumm-blank' => 'Полностью удалено содержимое страницы',
+'autosumm-replace' => 'Содержимое страницы заменено на «$1»',
+'autoredircomment' => 'Перенаправление на [[$1]]',
+'autosumm-new' => 'Новая: $1',
+
+# Size units
+'size-bytes' => '$1 байт',
+'size-kilobytes' => '$1 КБ',
+'size-megabytes' => '$1 МБ',
+'size-gigabytes' => '$1 ГБ',
+
+);
+
+?>
diff --git a/languages/messages/MessagesSc.php b/languages/messages/MessagesSc.php
new file mode 100644
index 000000000000..c0f11717fc66
--- /dev/null
+++ b/languages/messages/MessagesSc.php
@@ -0,0 +1,655 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_SPECIAL => 'Speciale',
+ NS_MAIN => '',
+ NS_TALK => 'Contièndha',
+ NS_USER => 'Utente',
+ NS_USER_TALK => 'Utente_discussioni',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_discussioni',
+ NS_IMAGE => 'Immàgini',
+ NS_IMAGE_TALK => 'Immàgini_contièndha'
+);
+
+$quickbarSettings = array(
+ "Nessuno", "Fisso a sinistra", "Fisso a destra", "Fluttuante a sinistra"
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'H:i, M j, Y',
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j M Y',
+ 'dmy both' => 'H:i, j M Y',
+
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'H:i, Y M j',
+);
+
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+$messages = array(
+# User Toggles
+
+"tog-underline" => "Sottolinea links",
+"tog-highlightbroken" => "Evidenzia i links che puntano ad articoli ancora da scrivere",
+"tog-justify" => "Paragrafo: giustificato",
+"tog-hideminor" => "Nascondi le modifiche minori nella pagina \"Modifiche recenti\"",
+"tog-numberheadings" => "Auto-numerazione dei titoli di paragrafo",
+"tog-rememberpassword" => "Ricorda la password (non limitare a una sessione - richiede uso di cookies)",
+"tog-editwidth" => "Casella di edizione ampliata alla massima larghezza",
+"tog-editondblclick" => "Doppio click per modificare l'articolo (richiede JavaScript)",
+"tog-watchdefault" => "Notifica articoli nuovi e modificati",
+"tog-minordefault" => "Indica ogni modifica come minore (solo come predefinito)",
+
+# Dates
+#
+
+'sunday' => "Domiga",
+'monday' => "Lúnis",
+'tuesday' => "Màrtis",
+'wednesday' => "Mércuris",
+'thursday' => "Zóbia",
+'friday' => "Canàbara",
+'saturday' => "Sàudu",
+'january' => "Ghenàlliu",
+'february' => "Fiàrzu",
+'march' => "Màrtu",
+'april' => "Abríli",
+'may_long' => "Màzu",
+'june' => "Làmparas",
+'july' => "Luglio",
+'august' => "Agosto",
+'september' => "Settembre",
+'october' => "Ottobre",
+'november' => "Novembre",
+'december' => "Dicembre",
+'jan' => "Gen",
+'feb' => "Feb",
+'mar' => "Mar",
+'apr' => "Apr",
+'may' => "Mag",
+'jun' => "Giu",
+'jul' => "Lug",
+'aug' => "Ago",
+'sep' => "Set",
+'oct' => "Ott",
+'nov' => "Nov",
+'dec' => "Dic",
+
+# Bits of text used by many pages:
+#
+'mainpage' => 'Pàggina principali',
+'about' => 'A proposito di',
+'aboutsite' => 'A proposito di {{SITENAME}}',
+'aboutpage' => '{{ns:project}}:About',
+'help' => 'Aiuto',
+'helppage' => '{{ns:project}}:Aiuto',
+'bugreports' => 'Segnalazioni di malfunzionamento',
+'bugreportspage' => '{{ns:project}}:Malfunzionamenti',
+'faq' => 'FAQ',
+'faqpage' => '{{ns:project}}:FAQ',
+"edithelp" => "Guida per la modifica o la scrittura di un articolo",
+"edithelppage" => "{{ns:project}}:Come_scrivere_un_articolo",
+"cancel" => "Cancella",
+"qbfind" => "Trova",
+"qbbrowse" => "Sfoglia",
+"qbedit" => "Modifica",
+"qbpageoptions" => "Opzioni pagina",
+"qbpageinfo" => "Informazioni sulla pagina",
+"qbmyoptions" => "Le mie preferenze",
+"mypage" => "La mia pagina",
+"mytalk" => "Le mie discussioni",
+"currentevents" => "Attualità",
+"errorpagetitle" => "Errore",
+"returnto" => "Torna a $1.",
+"tagline" => "Da {{SITENAME}}",
+"whatlinkshere" => "Pagine che linkano questa",
+"help" => "Aiuto",
+"search" => "Cerca",
+"searchbutton" => "Cerca",
+"history" => "Versioni precedenti",
+"printableversion" => "Versione stampabile",
+"editthispage" => "Modifica questo articolo",
+"deletethispage" => "Cancella questa pagina",
+"protectthispage" => "Proteggi questa pagina",
+"unprotectthispage" => "Togli la protezione a questa pagina",
+"talkpage" => "Discussione sull'articolo",
+"articlepage" => "Leggi articolo",
+"userpage" => "Vedi pagina Utente",
+"projectpage" => "Vedi pagina meta",
+"imagepage" => "Vedi pagina immagine",
+"otherlanguages" => "Altre lingue",
+"redirectedfrom" => "(Reindirizzamento da $1)",
+"lastmodifiedat" => "Ultima modifica il $2, $1.",
+"viewcount" => "Questo articolo è stato letto $1 volte.",
+"protectedpage" => "Pagina protetta",
+"nbytes" => "$1 bytes",
+"go" => "Vai",
+'searcharticle' => "Vai",
+"ok" => "OK",
+"retrievedfrom" => "Ricavato da \"$1\"",
+
+# Main script and global functions
+#
+"nosuchaction" => "Operazione non riconosciuta",
+"nosuchactiontext" => "L'operazione richiesta con la URL immessa non è stata riconosciuta dal software di {{SITENAME}}",
+"nosuchspecialpage" => "Nessuna simile pagina speciale è disponibile",
+"nospecialpagetext" => "Hai richiesto una pagina speciale che non è stata riconosciuta dal software di {{SITENAME}}, o che non è disponibile.",
+
+# General errors
+#
+"error" => "Errore",
+"databaseerror" => "Errore del database",
+"dberrortext" => "Errore di sintassi nella richiesta inoltrata al database.
+L'ultima richiesta inoltrata al database è stata:
+<blockquote><tt>$1</tt></blockquote>
+dalla funzione \"<tt>$2</tt>\".
+MySQL ha restituito un errore \"<tt>$3: $4</tt>\".",
+"noconnect" => "Connessione al database fallita su $1",
+"nodb" => "Selezione del database $1 fallita",
+"readonly" => "Accesso al database temporaneamente disabilitato",
+"enterlockreason" => "Fornisci una spiegazione sui motivi del blocco, includendo le probabili data ed ora di riattivazione o di rimozione del blocco.",
+"readonlytext" => "Il database di {{SITENAME}} è al momento bloccato, e non consente nuove immissioni né modifiche, molto probabilmente per manutenzione server, nel qual caso il database sarà presto di nuovo completamente accessibile.
+L/'amministratore di sistema che ha imposto il blocco, ha lasciato questa nota:
+<p>$1",
+"missingarticle" => "Il database non ha trovato il testo di una pagina, che invece avrebbe dovuto trovare, intitolata \"$1\".
+Questo non è un errore del database, ma più probabilmente un problema del software.
+Per favore, segnalate l'accaduto ad un administrator, segnalando la URL e l'ora dell'incidente.",
+"internalerror" => "Errore interno",
+"filecopyerror" => "Non è stato possibile copiare il file \"$1\" come \"$2\".",
+"filerenameerror" => "Non è stato possibile rinominare il file \"$1\" in \"$2\".",
+"filedeleteerror" => "Non è stato possibile cancellare il file \"$1\".",
+"filenotfound" => " Non è stato possibile trovare il file \"$1\".",
+"unexpected" => "Valore imprevisto: \"$1\"=\"$2\".",
+"formerror" => "Errore: il modulo non è stato inviato correttamente",
+"badarticleerror" => "Questa operazione non è consentita su questa pagina.",
+"cannotdelete" => "Impossibile cancellare la pagina o l'immagine richiesta.",
+"badtitle" => "Titolo non corretto",
+"badtitletext" => "La pagina richiesta non è disponibile, potrebbe essere non valida, vuota, o potrebbe trattarsi di un errore in un link interlinguistico o fra diverse versioni di {{SITENAME}}.",
+"perfdisabled" => "Siamo davvero rammaricati, ma questa funzionalità è temporaneamente disabilitata durante le ore di maggiore accesso al database per ragioni di accessibilità al resto del sito! Torna fra le 02:00 e le 14:00 UTC e riprova. Grazie.",
+
+# Login and logout pages
+#
+"logouttitle" => "Logout Utente",
+"logouttext" => "Logout effettuato.
+Ora puoi continuare ad usare {{SITENAME}} come utente anonimo (ma il tuo indirizzo IP resterà riconoscibile), oppure puoi nuovamente richiedere il login con il precedente username, oppure come uno diverso.",
+
+"welcomecreation" => "<h2>Benvenuto, $1!</h2><p>Il tuo account è stato creato con successo.<br />Grazie per aver scelto di far crescere {{SITENAME}} con il tuo aiuto.<br />Per rendere {{SITENAME}} più tua, e per usarla più scorrevolmente, non dimenticare di personalizzare le tue preferenze.",
+
+"loginpagetitle" => "Login",
+"yourname" => "Il tuo user name",
+"yourpassword" => "La tua password",
+"yourpasswordagain" => "Ripeti la password",
+"remembermypassword" => "Ricorda la mia password per più sessioni (richiede uso dei cookies).",
+"loginproblem" => "<b>Si è verificato un errore durante il tuo tentativo di login.</b><br />Riprova, sarai più fortunato!",
+"alreadyloggedin" => "<strong>Ehi, Utente $1, hai già fatto il login, sei già connesso al nostro server!</strong><br />",
+
+"login" => "Log in",
+"userlogin" => "Log in",
+"logout" => "Log out",
+"userlogout" => "Log out",
+"createaccount" => "Crea nuovo account",
+"badretype" => "Le password che hai immesso non coincidono, sono diverse fra loro.",
+"userexists" => "Siamo spiacenti. Lo user name che hai scelto è già usato da un altro Utente. Ti preghiamo perciò di voler scegliere uno user name diverso.",
+"youremail" => "La tua e-mail",
+"yournick" => "Il tuo diminutivo o soprannome (per le firme)",
+"loginerror" => "Errore di Login",
+"noname" => "Lo user name indicato non è valido, non è possibile creare un account a questo nome.",
+"loginsuccesstitle" => "Login effettuato con successo!",
+"loginsuccess" => "Sei stato ammesso alla connessione al server di {{SITENAME}} con il nome utente di \"$1\".",
+"nosuchuser" => "Attenzione<br /><br />a seguito di verifica, non ci risulta alcun Utente con il nome di \"$1\".<br /><br />
+Controlla per favore il nome digitato, oppure usa il modulo qui sotto per creare un nuovo user account.",
+"wrongpassword" => "La password immessa non è corretta.<br /><br />Riprova, per favore.",
+"mailmypassword" => "Spediscimi una nuova password in posta elettronica",
+"passwordremindertitle" => "Servizio Password Reminder di {{SITENAME}}",
+"passwordremindertext" => "Qualcuno (probabilmente tu, con indirizzo IP $1)
+ha richiesto l'invio di una nuova password per il login a {{SITENAME}}.
+La password per l'Utente \"$2\" è ora \"$3\".
+Per evidenti ragioni di sicurezza, dovresti fare un log in il prima possibile, e cambiare la password immediatamente.",
+"noemail" => "Nessuna casella e-mail risulta registrata per l'Utente \"$1\".",
+"passwordsent" => "Una nuova password è stata inviata alla casella e-mail registrata per l'Utente \"$1\".
+Per favore, fai subito un log in non appena la ricevi.",
+
+# Edit pages
+#
+"summary" => "Oggetto",
+"minoredit" => "Questa è una modifica minore",
+"watchthis" => "Tieni d'occhio questo articolo",
+"savearticle" => "Salva la pagina",
+"preview" => "Anteprima",
+"showpreview" => "Visualizza Anteprima",
+"blockedtitle" => "Questo User name corrisponde purtroppo ad un Utente che è stato disabilitato alla modifica degli articoli.",
+"blockedtext" => "Il tuo User name o il tuo indirizzo IP sono stati bloccati da $1.<br />
+La motivazione del blocco è la seguente:<br />:''$2''<p>Se lo desideri, puoi contattare $1, o uno degli altri
+[[{{ns:project}}:administrators|administrators]] per discutere del blocco.",
+"newarticle" => "(Nuovo)",
+"newarticletext" => "Scrivi qui il tuo testo.",
+"noarticletext" => "(L'articolo è vuoto, potresti gentilmente iniziare l'articolo oppure richiedere la cancellazione di questa pagina)",
+"updated" => "(Aggiornato)",
+"note" => "<strong>Nota:</strong>",
+"previewnote" => "Tieni presente che questa è solo una ANTEPRIMA, e che la tua versione non è ancora stata salvata!",
+"previewconflict" => "Questa anteprima rappresenta il testo nella casella di edizione di sopra, l'articolo apparirà n questa forma se sceglierai di salvare la pagina.",
+"editing" => "Modifica di $1",
+'editinguser' => "Modifica di $1",
+"editconflict" => "Conflitto di edizione: $1",
+"explainconflict" => "Qualcun altro ha salvato una sua versione dell'articolo nel tempo in cui tu stavi preparando la tua versione.<br />
+La casella di modifica di sopra contiene il testo dell'articolo nella sua forma attuale (cioè il testo attualmente online). Le tue modifiche sono invece contenute nella casella di modifica inferiore.
+Dovrai inserire, se lo desideri, le tue modifiche nel testo esistente, e perciò scriverle nella casella di sopra.
+<b>Soltanto</b> il testo nella casella di sopra sarà sakvato se premerai il bottone \"Salva\".<br />",
+"yourtext" => "Il tuo testo",
+"storedversion" => "Versione in archivio",
+"editingold" => "<strong>ATTENZIONE: Stai modificando una versione dell'articolo non aggiornata.
+Se la salvi così, tutti i cambiamenti apportati dopo questa revisione verranno persi per sempre.</strong>",
+"yourdiff" => "Differenze",
+/*"copyrightwarning" => "Nota, per favore, che tutti i contributi a {{SITENAME}} si considerano rilasciati sotto licenza di tipo GNU Free Documentation License
+(vedi $1 per maggiori dettagli).
+Se non vuoi che il tuo testo possa essere modificato e ridistribuito da chiunque senza pietà e senza altri limiti, allora non inviarlo a {{SITENAME}}, ma realizza piuttosto un tuo sito web personale.<br />
+Con l'invio di questo testo stai garantendo, a tua responsabilità, che il testo è stato scritto da te personalmente ed originalmente, oppure che è stato copiato da una fonte di publico dominio, o una simile fonte, oppure che hai ottenuto espressa autorizzazione ad usare questo testo e che puoi dimostrarlo.
+<strong>NON USARE MATERIALE COPERTO DA DIRITTO DI AUTORE (COPYRIGHT - (c)) IN MANCANZA DI ESPRESSA AUTORIZZAZIONE!!!</strong>",*/
+
+
+# History pages
+#
+"revhistory" => "Cronologia delle versioni di questa pagina.",
+"nohistory" => "Cronologia delle versioni di questa pagina non reperibile.",
+"revnotfound" => "Versione non trovata",
+"revnotfoundtext" => "La versione precedente di questo articolo che hai richiesto, non è stata trovata.
+Controlla per favore la URL che hai usato per accedere a questa pagina.",
+"loadhist" => "Caricamento cronologia di questa pagina",
+"currentrev" => "Versione attuale",
+"revisionasof" => "Revisione $1",
+"cur" => "corr",
+"next" => "succ",
+"last" => "prec",
+"orig" => "orig",
+"histlegend" => "Legend: (corr) = differenze con la versione corrente,
+(prec) = differenze con la versione precedente, M = modifica minore",
+
+# Diffs
+#
+"difference" => "(Differenze fra le revisioni)",
+"loadingrev" => "caricamento revisione per differenze",
+"lineno" => "Riga $1:",
+"editcurrent" => "Modifica la versione corrente di questa pagina",
+
+# Search results
+#
+"searchresults" => "Risultato della ricerca",
+"searchresulttext" => "Per maggiori informazioni sulla ricerca interna di {{SITENAME}}, vedi [[Project:Ricerca|Ricerca in {{SITENAME}}]].",
+"searchsubtitle" => "Richiesta \"[[:$1]]\"",
+"searchsubtitleinvalid" => "Richiesta \"$1\"",
+"badquery" => "Richiesta mal inoltrata",
+"badquerytext" => "La tua richiesta non ha potuto essere processata.
+Questo potrebbe dipendere dall'aver ricercato una parola di meno di tre caratteri.
+Oppure potresti aver scritto male la richiesta, per esempio \"pesce and and azzurro\".
+Per favore, riprova.",
+"matchtotals" => "La ricerca per la voce \"$1\" ha trovato<br />$2 riscontri nei titoli degli articoli e<br />$3 riscontri nei testi degli articoli.",
+"titlematches" => "Nei titoli degli articoli",
+"notitlematches" => "Voce richiesta non trovata in titoli di articolo",
+"textmatches" => "Nel testo degli articoli",
+"notextmatches" => "Voce richiesta non trovata in testi di articolo",
+"prevn" => "precedenti $1",
+"nextn" => "successivi $1",
+"viewprevnext" => "Vedi ($1) ($2) ($3).",
+"showingresults" => "Qui di seguito <b>$1</b> risultati, partendo dal numero #<b>$2</b>.",
+"nonefound" => "<strong>Nota</strong>: la ricerca di parole troppo comuni, come \"avere\" o \"essere\", che non sono indicizzate, può causare un esito negativo, così come indicare più di un termine da ricercare (solo le pagine che contengano tutti i termini ricercati verrebbero infatti visualizzate fra i risultati).",
+"powersearch" => "Ricerca",
+"powersearchtext" => "
+Cerca fra i campi :<br />
+$1<br />
+$2 Elenca i redirects &nbsp; cerca per $3 $9",
+
+
+# Preferences page
+#
+"preferences" => "Preferenze",
+"prefsnologin" => "Non hai eseguito il login",
+"prefsnologintext" => "Devi avere eseguito il [[Special:Userlogin|login]]
+per poter personalizzare le tue preferenze.",
+"prefsreset" => "Le tue Preferenze sono state ripescate dalla memoria di sistema del potente server di {{SITENAME}}.",
+"qbsettings" => "Settaggio della barra menu",
+"changepassword" => "Cambia password",
+"skin" => "Aspetto",
+"saveprefs" => "Salva preferenze",
+"resetprefs" => "Resetta preferenze",
+"oldpassword" => "Vecchia password",
+"newpassword" => "Nuova password",
+"retypenew" => "Riscrivi qui la nuova password",
+"textboxsize" => "Dimensione della casella di edizione",
+"rows" => "Righe",
+"columns" => "Colonne",
+"searchresultshead" => "Settaggio delle preferenze per la ricerca",
+"resultsperpage" => "Risultati da visualizzare per pagina",
+"contextlines" => "Righe di testo da mostrare per ciascun risultato",
+"contextchars" => "Caratteri per linea",
+"stubthreshold" => "Threshold for stub display",
+"recentchangescount" => "Numero di titoli nelle \"modifiche recenti\"",
+"savedprefs" => "Le tue preferenze sono state salvate.",
+"timezonetext" => "Immetti il numero di ore di differenza fra la tua ora locale e la ora del server (UTC).",
+"localtime" => "Ora Locale",
+"timezoneoffset" => "Offset",
+
+# Recent changes
+#
+"recentchanges" => "Ultime Modifiche",
+"rcnote" => "Qui di seguito sono elencate le ultime <strong>$1</strong> pagine modificate negli ultimi <strong>$2</strong> giorni.",
+"rcnotefrom" => " Qui di seguito sono elencate le modifiche da <b>$2</b> (fino a <b>$1</b>).",
+"rclistfrom" => "Mostra modifiche a partire da $1",
+# "rclinks" => "Mostra le ultime $1 modifiche nelle ultime $2 ore / negli ultimi $3 giorni",
+"rclinks" => " Mostra le ultime $1 modifiche negli ultimi $2 giorni.",
+"diff" => "diff",
+"hist" => "cron",
+"hide" => "nascondi",
+"show" => "mostra",
+"minoreditletter" => "M",
+"newpageletter" => "N",
+
+# Upload
+#
+"upload" => "Upload file",
+"uploadbtn" => "Upload file",
+"reupload" => "Ri-upload",
+"reuploaddesc" => "Torna al modulo per lo upload.",
+"uploadnologin" => "Devi fare il login per eseguire questa operazione.",
+"uploadnologintext" => "Devi eseguire [[Special:Userlogin|il login]]
+per fare lo upload di files.",
+"uploaderror" => "Errore di Upload",
+"uploadtext" => "'''FERMA!''' Prima di effettuare un upload su {{SITENAME}}, accertati di avere ben letto e soprattutto compreso
+[[Project:Image_use_policy|le regole di {{SITENAME}} sull'uso delle immagini]].
+
+Per visualizzare o cercare immagini precedentemente caricate su {{SITENAME}}, vai alla [[Special:Imagelist|lista delle immagini già caricate]].
+Uploads e cancellazioni delle immagini sono registrati nello
+[[Project:Upload_log|upload log]].
+
+Usa il modulo sottostante per caricare nuovi files immagine da utilizzare per arricchire ed illustrare i tuoi articoli.
+Sulla maggior parte dei browsers, dovresti vedere un bottone con la scritta \"Browse...\" (oppure \"Sfoglia...\", che aprirà una comune finestra di dialogo.
+Scegliendo uno dei files sul tuo PC, il nome di questo file verrà scritto in automatico nella casella di testo a fianco al bottone.
+Devi anche selezionare la casellina nella quale affermi che con questo upload non stai violando nessun copyright.
+Premi poi il bottone \"Upload\" per completare il caricamento.
+Il caricamento può richiedere qualche minuto se hai una connessione ad Internet lenta, o se l'immagine è eccessivamente pesante (sconsigliato).
+
+I formati immagine preferibili sono il JPEG per immagini fotografiche, il PNG
+per disegni ed altre immagini iconiche o simboliche, il OGG per i suoni.
+Per cortesia, rinomina i tuoi files, prima di caricarli, usando un nome il più possibile descrittivo del contenuto, così da evitare confusioni.
+Per inserire la nuova immagine in un articolo, usa semplicemente un link nella forma
+'''<nowiki>[[image:file.jpg]]</nowiki>''' o
+'''<nowiki>[[image:file.png|alt text, testo alternativo]]</nowiki>''' o
+'''<nowiki>[[media:file.ogg]]</nowiki>''' per i suoni.
+
+Tieni presente che, come per tutte le pagine di {{SITENAME}}, chiunque può modificare o sostituire o cancellare i tuoi files ove ritenga che ciò sia negli interessi della nostra enciclopedia. Tieni anche presente che, in caso di abuso, o di sovraccarico sul sistema, potresti essere bloccato (oltre ad essere perseguito per le connesse responsabilità).",
+"uploadlog" => "upload log",
+"uploadlogpage" => "Upload_log",
+"uploadlogpagetext" => "Qui di seguito la lista degli ultimi files caricati sul server di {{SITENAME}}.
+Tutti i tempi indicati sono calcolati sul fuso orario del server (UTC).
+<ul>
+</ul>",
+"filename" => "Nome del file",
+"filedesc" => "Oggetto",
+"copyrightpage" => "{{ns:project}}:Copyrights",
+"copyrightpagename" => "{{SITENAME}} copyright",
+"uploadedfiles" => "Files Caricati in {{SITENAME}}",
+"minlength" => "I nomi dei file immagine debbono essere lunghi almeno tre caratteri, ma è preferibile usare nomi lumghi, purché descrittivi.",
+"badfilename" => "Il nome del file immagine è stato convertito in \"$1\".",
+"badfiletype" => "\".$1\" non è un tipo di file raccomandato per le immagini, almeno ai nostri fini.",
+"largefile" => "Il peso raccomandato per le immagini deve essere inferiore a 100kb.",
+"successfulupload" => "Caricamento completato",
+"fileuploaded" => "File \"$1\" correttamente caricato sul server.
+Segui questo link: ($2) per modificare la pagina di descrizione del file che hai appena caricato, e immetti le informazioni che ritieni opportune (cosa rappresenta, dove lo hai trovato, chi lo ha creato e quando, etc) oltre ad una nota circa la situazione di copyright sul file. Non omettere la nota sul copytright, o il file verrebbe cancellato molto presto.",
+"uploadwarning" => "Avviso di Upload",
+"savefile" => "Salva file",
+"uploadedimage" => "caricato \"[[$1]]\"",
+
+# Image list
+#
+"imagelist" => "Lista delle immagini",
+"imagelisttext" => "Qui di seguito una lista di $1 immagini, ordinate per $2.",
+"getimagelist" => "ricerca nella lista delle immagini",
+"ilsubmit" => "Cerca",
+"showlast" => "Mostra le ultime $1 immagini ordinate per $2.",
+"byname" => "nome",
+"bydate" => "data",
+"bysize" => "peso",
+"imgdelete" => "canc",
+"imgdesc" => "desc",
+"imglegend" => "Legenda: (desc) = mostra/modifica descrizione immagine.",
+"imghistory" => "Storia di questa immagine",
+"revertimg" => "ripr",
+"deleteimg" => "canc",
+"deleteimgcompletely" => "canc",
+"imghistlegend" => "Legenda: (cur) = immagine corrente, (canc) = cancella questa vecchia versione, (ripr) = ripristina questa vecchia versione come versione attuale.
+<br /><i>Clicca su una data per vedere tutte le immagini che sono state caricate in quella data </i>.",
+"imagelinks" => "Link alle immagini",
+"linkstoimage" => "Le pagine seguenti linkano questa immagine:",
+"nolinkstoimage" => "Nessuna pagina linka questa immagine.",
+
+# Statistics
+#
+"statistics" => "Statistiche",
+"sitestats" => "Statistiche del sito",
+"userstats" => "Statistiche del {{SITENAME}}",
+"sitestatstext" => "Ci sono ben <b>$1</b> pagine nel database.
+Questa cifra comprende le pagine \"talk\" (discussione), pagine su {{SITENAME}}, articoli esigui (\"stub\"), redirects, e altre pagine che probabilmente non andrebbero conteggiate fra gli articoli.
+Escludendo queste, ci sono ben <b>$2</b> pagine che sono con buona probabilità propriamente degli articoli.<p>
+Ci sono state un totale di <b>$3</b> pagine viste, e <b>$4</b> modifiche agli articoli da quando il software è stato potenziato (Dicembre, 2002).
+Questa media rivela che ci sono state una media di <b>$5</b> modifiche per ciascun articolo, e che l'articolo è stato letto <b>$6</b> volte per ciascuna modifica.",
+"userstatstext" => "Ci sono <b>$1</b> Utenti registrati.
+<b>$2</b> di questi hanno il grado di amministratori (vedi $3).",
+
+# Maintenance Page
+#
+"disambiguations" => "Disambiguation pages",
+"disambiguationspage" => "{{ns:project}}:Links_to_disambiguating_pages",
+"disambiguationstext" => "The following articles link to a <i>disambiguation page</i>. They should link to the appropriate topic instead.<br />A page is treated as dismbiguation if it is linked from $1.<br />Links from other namespaces are <i>not</i> listed here.",
+"doubleredirects" => "Doppi Redirects",
+"doubleredirectstext" => "<b>Attenzione:</b> Questa lista può talvolta contenere dei risultati non corretti. Ciò potrebbe magari accadere perchè vi sono del testo aggiuntivo o dei link dopo il tag #REDIRECT.<br />\nOgni riga contiene i link al primo ed al secondo redirect, oltre alla prima riga di testo del secondo redirect che di solito contiene il \"reale\" articolo di destinazione, quello al quale anche il primo redirect dovrebbe puntare.",
+"brokenredirects" => "Redirects errati",
+"brokenredirectstext" => "I seguenti redirects puntano ad articoli non ancora creati.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Pagine solitarie",
+"unusedimages" => "Immagini non utilizzate",
+"popularpages" => "Pagine più viste",
+"nviews" => "$1 visite",
+"wantedpages" => "Articoli più richiesti",
+"nlinks" => "$1 links",
+"allpages" => "Tutte le pagine",
+"randompage" => "Una pagina a caso",
+"shortpages" => "Pagine corte",
+"longpages" => "Pagine lunghe",
+"listusers" => "Elenco degli Utenti",
+"specialpages" => "Pagine speciali",
+"spheading" => "Pagine speciali",
+"recentchangeslinked" => "Modifiche correlate",
+"rclsub" => "(alle pagine linkate da \"$1\")",
+"newpages" => "Pagine nuove",
+"movethispage" => "Sposta questa pagina",
+"unusedimagestext" => "<p>Nota che altri siti web, come la {{SITENAME}} internazionale, potrebbero aver messo un link ad una immagine per mezzo di una URL diretta, perciò le immagini potrebbero essere listate qui anche essendo magari in uso.",
+
+# Email this user
+#
+"mailnologin" => "No send address",
+"mailnologintext" => "Devi fare il [[Special:Userlogin|login]]
+ed aver registrato una valida casella e-mail nelle tue [[Special:Preferences|preferenze]] per mandare posta elettronica ad altri Utenti.",
+"emailuser" => "Manda una E-mail a questo Utente",
+"emailpage" => "E-mail user",
+"emailpagetext" => "Se questo Utente ha registrato una valida casella e-mail, il modulo qui sotto ti consentirà di scrivergli un solo messaggio.
+La e-mail che hai indicato nelle tue preferenze apparirà nel campo \"From\" della mail, così che il destinatario possa, solo se lo desidera però, risponderti.",
+"noemailtitle" => "Nessun indirizzo e-mail",
+"noemailtext" => "Questo Utente non ha registrato alcuna casella e-mail,
+oppure ha scelto di non ricevere posta elettronica dagli altri Utenti.",
+"emailfrom" => "From",
+"emailto" => "To",
+"emailsubject" => "Subject",
+"emailmessage" => "Message",
+"emailsend" => "Send",
+"emailsent" => "E-mail inviata",
+"emailsenttext" => "La tua e-mail è stata inviata.",
+
+# Watchlist
+#
+"watchlist" => "Osservati Speciali",
+"nowatchlist" => "Non hai indicato articoli da tenere d'occhio.",
+"watchnologin" => "Manca il login",
+"watchnologintext" => "Devi prima fare il [[Special:Userlogin|login]]
+per modificare la tua lista di osservati speciali.",
+"addedwatch" => "Aggiunto agli Osservati Speciali",
+"addedwatchtext" => " La pagina \"$1\" è stata aggiunta alla tua <a href=\"" .
+ "{{localurle:Special:Watchlist}}\"> lista di osservati speciali </a>.
+Le future modifiche a questa pagina ed alla relativa pagina di discussione saranno elencate qui, e la pagina apparirà in <b>grassetto</b> nella pagina delle <a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">modifiche recenti</a> per essere più facile da tener d'occhio.</p>
+
+<p>Se in seguito vorrai togliere questo articolo dalla tua lista di osservati speciali, clicca \" Smetti di seguire \" nella barra dei menu.",
+"removedwatch" => "Rimosso dalla lista degli Osservati Speciali",
+"removedwatchtext" => "La pagina \"$1\" è stata rimossa dalla lista degli Osservati Speciali.",
+"watchthispage" => "Segui questo articolo",
+"unwatchthispage" => "Smetti di seguire",
+"notanarticle" => "Non è un articolo",
+
+
+# Delete/protect/revert
+#
+"deletepage" => "Cancella pagina",
+"confirm" => "Conferma",
+"confirmdelete" => "Conferma cancellazione",
+"deletesub" => "(Cancellazione di \"$1\")",
+"confirmdeletetext" => "Stai per cancellare permanentemente dal database una pagina o una immagine, insieme a tutta la sua cronologia.
+Per cortesia, conferma che è tua intenzione procedere a tale cancellazione, conferma che hai piena consapevolezza delle conseguenze della tua azione, e conferma che la tua azione è pienamente ottemperante alle regole stabilite nella
+[[{{ns:project}}:Policy]].",
+"actioncomplete" => "Azione completata",
+"deletedtext" => "La pagina \"$1\" è stata cancellata.
+Vedi $2 per un elenco delle pagine cancellate di recente.",
+"deletedarticle" => "Cancellata \"$1\"",
+"dellogpage" => "Deletion_log",
+"dellogpagetext" => "Qui di seguito, un elenco delle pagine cancellate di recente.
+Tutti i tempi sono in ora del server (UTC).
+<ul>
+</ul>",
+"deletionlog" => "deletion log",
+"reverted" => "Ripristinata versione precedente",
+"deletecomment" => "Motivazione della cancellazione",
+"imagereverted" => "Versione precedente correttamente ripristinata.",
+"rollback" => "Usa una revisione precdente",
+"cantrollback" => "Impossibile tornare ad una versione precedente: l'ultima modifica è stata apportata dall'unico utente che abbia lavorato a questo articolo.",
+"revertpage" => "Riportata alla revisione precedente da $1",
+
+# Undelete
+"undelete" => "Recupera una pagina cancellata",
+"undeletepage" => "Vedi e recupera pagine cancellate",
+"undeletepagetext" => "Le pagine qui di seguito indicate sono state cancellate, ma sono ancora in archivio e pertanto possono essere recuperate. L'archivio viene svuotato periodicamente.",
+"undeletearticle" => "Recupera un articolo cancellato",
+"undeleterevisions" => "$1 revisioni in archivio",
+"undeletehistory" => "Se recuperi questo articolo, tutte le sue revisioni verranno recuperate nella relativa cronologia.
+Se una nuova pagina è stata creata con questo stesso nome dopo la cancellazione, le revisioni recuperate saranno inserite nella cronologia e la versione attualmente online della pagina non verrà modificata.",
+"undeleterevision" => "Cancellata revisione $1",
+"undeletebtn" => "RIPRISTINA!",
+"undeletedarticle" => "Recuperata \"$1\"",
+
+# Contributions
+#
+"contributions" => "Contributi di questo Utente",
+"contribsub" => "Per $1",
+"nocontribs" => "Nessuna modifica trovata conformemente a questi criteri.",
+"ucnote" => "Qui sotto troverai le ultime <b>$1</b> modifiche effettuate da questo Utente negli ultimi <b>$2</b> giorni.",
+"uclinks" => "Vedi le ultime $1 modifiche; vedi gli ultimi $2 giorni.",
+"uctop" => " (ultima per la pagina)" ,
+
+# What links here
+#
+"whatlinkshere" => "Pagine che linkano questa",
+"notargettitle" => "Dati mancanti",
+"notargettext" => "Non hai specificato una pagina o un Utente in relazione al quale eseguire l'operazione richiesta.",
+"linklistsub" => "(Lista di links)",
+"linkshere" => "Le seguenti pagine contengono link che puntano qui:",
+"nolinkshere" => "Nessuna pagina contiene links che puntano a questa.",
+"isredirect" => "redirect",
+
+# Block/unblock IP
+#
+"blockip" => "Blocca indirizzo IP",
+"blockiptext" => "Usa il modulo sottostante per bloccare l'accesso con diritto di scrittura da uno specifico indirizzo IP.
+Questo blocco deve essere operato SOLO per prevenire atti di vandalismo, ed in stretta osservanza dei principi tutti della [[{{ns:project}}:Policy|policy di {{SITENAME}}]]. Il blocco non può in nessun caso essere applicato per motivi ideologici.
+Scrivi un motivo specifico per il quale questo indirizzo IP dovrebbe a tuo avviso essere bloccato (per esempio, cita i titoli di pagine eventualmente già oggetto di vandalismo editoriale).",
+"ipaddress" => "Indirizzo IP (IP Address)",
+"ipbreason" => "Motivazione",
+"ipbsubmit" => "Blocca questo indirizzo IP",
+"badipaddress" => "L'indirizzo IP indicato non è corretto.",
+"blockipsuccesssub" => "Blocco eseguito",
+"blockipsuccesstext" => " L'indirizzo IP \"$1\" è stato bloccato.
+<br />Vedi [[Special:Ipblocklist|lista IP bloccati]].",
+"unblockip" => " Sblocca indirizzo IP",
+"unblockiptext" => "Usa il modulo sottostante per restituire il diritto di scrittura ad un indirizzo IP precedentemente bloccato.",
+"ipusubmit" => "Sblocca questo indirizzo IP",
+"ipblocklist" => "Lista degli indirizzi IP bloccati",
+"blocklistline" => "$1, $2 ha bloccato $3 ($4)",
+"blocklink" => "blocca",
+"unblocklink" => "sblocca",
+"contribslink" => "contributi",
+
+# Developer tools
+#
+"lockdb" => "Blocca il database",
+"unlockdb" => "Sblocca il database",
+"lockdbtext" => "Bloccare il database sospenderà la possibilità per tutti gli Utenti di modificare le pagine o di crearne di nuove, di cambiare le loro preferenze, di modificare le loro liste di Osservati Speciali, ed in genere non consentirà a nessuno di eseguire operazioni che richiedano modifiche del database.<br /><br />
+Per cortesia, conferma che questo è effettivamente quanto tu intendi ora effettuare e, soprattutto, che il prima possibile sbloccherai nuovamente il database, ripristinandone la corretta funzionalità, non appena avrai terminato le tue manutenzioni.",
+"unlockdbtext" => "Sbloccare il database ripristinerà la possibilità per tutti gli Utenti di modificare le pagine o di crearne di nuove, di cambiare le loro preferenze, di modificare le loro liste di Osservati Speciali, ed in genere di eseguire operazioni che richiedano modifiche del database.
+Per cortesia, conferma che questo è effettivamente quanto tu intendi ora effettuare.",
+"lockconfirm" => "Sì, effettivamente intendo, sotto la mia responsabilità, bloccare il database.",
+"unlockconfirm" => " Sì, effettivamente intendo, sotto la mia responsabilità, sbloccare il database.",
+"lockbtn" => "Blocca il database",
+"unlockbtn" => "Sblocca il database",
+"locknoconfirm" => "Non hai spuntato la casellina di conferma.",
+"lockdbsuccesssub" => "Blocco del database eseguito",
+"unlockdbsuccesssub" => "Sblocco del database eseguito, rimosso blocco",
+"lockdbsuccesstext" => "Il database di {{SITENAME}} è stato bloccato.
+<br />Ricordati di rimuovere il blocco non appena avrai terminatoi le tue manutenzioni.",
+"unlockdbsuccesstext" => " Il database di {{SITENAME}} è stato sbloccato.",
+
+# Move page
+#
+"movepage" => "Spostamento di pagina",
+"movepagetext" => "Con il modulo sottostante puoi rinominare una pagina, spostando anche tutta la sua cronologia al nuovo nome.
+Il vecchior titolo diverrà automaticamente un redirect che punta al nuovo titolo.
+I link alla vecchia pagina non saranno aggiornati (e punteranno quindi al redirect); accertati di [[Special:Manutenzioni|controllare con cura]] che non si creino doppi redirects o redirects interrotti.
+Resta nella tua responsabilità di accertarti che i link continuino a puntare verso dove devono dirigersi.
+
+Nota bene: la pagina '''non''' sarà spostata se vi fosse già un articolo con il nuovo nome, a meno che non sia una pagina vuota o un redirect e che non abbia cronologia. Questo significa che, se commetti un errore, puoi nuovamente rinominare una pagina col vecchio titolo, ma non puoi sovrascrivere una pagina già esistente.
+
+<b>ATTENZIONE!</b>
+Questo cambiamento drastico potrebbe creare inattesi contrattempi, specialmente se si tratta di una pagina molto visitata. Accertati di aver ben valutato le conseguenze dello spostamento, prima di procedere. Nel dubbio, contatta un Amministratore.",
+"movepagetalktext" => "La corrispondente pagina di discussione, se esiste, sarà spostata automaticamente insieme all'articolo, '''tranne che nei seguenti casi:'''
+*Spostamento della pagina fra i namespaces,
+*Una pagina di discussione (non vuota) già esiste per il nuovo nome, oppure
+*Hai deselezionato la casellina qui sotto.
+
+In questi casi, se lo ritieni opportuno, dovrai spostare o aggiungere manualmente la pagina di discussione.",
+"movearticle" => "Rinomina articolo",
+"movenologin" => "Non hai effettuato il login",
+"movenologintext" => "Devi essere un Utente registrato ed aver effettuato il [[Special:Userlogin|login]]
+per poter spostare una pagina.",
+"newtitle" => "Al nuovo titolo di",
+"movepagebtn" => "Sposta questa pagina",
+"pagemovedsub" => "Spostamento effettuato con successo",
+"pagemovedtext" => "Pagina \"[[$1]]\" rinominata in \"[[$2]]\".",
+"articleexists" => "Una pagina con questo nome esiste già, oppure il nome che hai scelto non è valido.<br />
+Scegli, per cortesia, un titolo diverso per l'articolo.",
+"talkexists" => "La pagina è stata spostata correttamente, ma la pagina di dicussione non poteva essere spostata perché ne esiste già un'altra con il nuovo titolo. Per favore, modifica manualmente i contenuti delle due pagine discussione, così da mantenerle entrambe per non perdere potenzialmente interessanti riflessioni.",
+"movedto" => "spostata a",
+"movetalk" => "Sposta anche la corrispondente pagina \"discussione\", se possibile.",
+"talkpagemoved" => "Anche la corrispondente pagina di discussione è stata spostata.",
+"talkpagenotmoved" => "La corrispondente pagina di discussione <strong>non è stata spostata</strong>."
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesSd.php b/languages/messages/MessagesSd.php
new file mode 100644
index 000000000000..f4cc7db11e22
--- /dev/null
+++ b/languages/messages/MessagesSd.php
@@ -0,0 +1,12 @@
+<?php
+/** Sindhi language file ( सिनधि )
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+#FIXME: inherit almost everything for now
+
+$rtl = true;
+
+?>
diff --git a/languages/messages/MessagesSk.php b/languages/messages/MessagesSk.php
new file mode 100644
index 000000000000..825a33c2ebac
--- /dev/null
+++ b/languages/messages/MessagesSk.php
@@ -0,0 +1,1924 @@
+<?php
+/**
+ * Slovak (Slovenčina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * Translators: Valasek, helix84, Palica, Liso, Maros
+ */
+
+
+$quickbarSettings = array(
+ 'Žiadne', 'Ukotvené vľavo', 'Ukotvené vpravo', 'Plávajúce vľavo'
+);
+
+$datePreferences = array(
+ 'default',
+ 'dmyt',
+ 'short dmyt',
+ 'tdmy',
+ 'short dmyt',
+ 'ISO 8601',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'dmyt',
+ 'short dmyt',
+ 'tdmy',
+ 'short tdmy',
+);
+
+$dateFormats = array(
+ /*
+ 'Default',
+ '15. január 2001 16:12',
+ '15. jan. 2001 16:12',
+ '16:12, 15. január 2001',
+ '16:12, 15. jan. 2001',
+ 'ISO 8601' => '2001-01-15 16:12:34'*/
+
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. F Y',
+ 'dmy both' => 'H:i, j. F Y',
+
+ 'dmyt time' => 'H:i',
+ 'dmyt date' => 'j. F Y',
+ 'dmyt both' => 'j. F Y H:i',
+
+ 'short dmyt time' => 'H:i',
+ 'short dmyt date' => 'j. M. Y',
+ 'short dmyt both' => 'j. M. Y H:i',
+
+ 'tdmy time' => 'H:i',
+ 'tdmy date' => 'j. F Y',
+ 'tdmy both' => 'H:i, j. F Y',
+
+ 'short tdmy time' => 'H:i',
+ 'short tdmy date' => 'j. M. Y',
+ 'short tdmy both' => 'H:i, j. M. Y',
+
+);
+
+$bookstoreList = array(
+ 'Bibsys' => 'http://ask.bibsys.no/ask/action/result?cmd=&kilde=biblio&fid=isbn&term=$1',
+ 'BokBerit' => 'http://www.bokberit.no/annet_sted/bocker/$1.html',
+ 'Bokkilden' => 'http://www.bokkilden.no/ProductDetails.aspx?ProductId=$1',
+ 'Haugenbok' => 'http://www.haugenbok.no/searchresults.cfm?searchtype=simple&isbn=$1',
+ 'Akademika' => 'http://www.akademika.no/sok.php?isbn=$1',
+ 'Gnist' => 'http://www.gnist.no/sok.php?isbn=$1',
+ 'Amazon.co.uk' => 'http://www.amazon.co.uk/exec/obidos/ISBN=$1',
+ 'Amazon.de' => 'http://www.amazon.de/exec/obidos/ISBN=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
+);
+
+# Note to translators:
+# Please include the English words as synonyms. This allows people
+# from other wikis to contribute more easily.
+#
+$magicWords = array(
+ # ID CASE SYNONYMS
+ 'redirect' => array( 0, '#redirect', '#presmeruj' ),
+ 'notoc' => array( 0, '__NOTOC__', '__BEZOBSAHU__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__VYNÚŤOBSAH__' ),
+ 'toc' => array( 0, '__TOC__', '__OBSAH__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__NEUPRAVUJSEKCIE__' ),
+ 'start' => array( 0, '__START__', '__ŠTART__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'MESIAC' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'MENOMESIACA' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'MENOAKTUÁLNEHOMESIACAGEN' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'MENOAKTUÁLNEHOMESIACASKRATKA' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'AKTUÁLNYDEŇ' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'MENOAKTUÁLNEHODŇA' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'AKTUÁLNYROK' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'AKTUÁLNYČAS' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'POČETČLÁNKOV' ),
+ 'pagename' => array( 1, 'PAGENAME', 'MENOSTRÁNKY' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'MENNÝPRIESTOR' ),
+ 'msg' => array( 0, 'MSG:', 'SPRÁVA:' ),
+ 'subst' => array( 0, 'SUBST:' ),
+ 'msgnw' => array( 0, 'MSGNW:' ),
+ 'end' => array( 0, '__END__', '__KONIEC__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'náhľad', 'náhľadobrázka' ),
+ 'img_right' => array( 1, 'right', 'vpravo' ),
+ 'img_left' => array( 1, 'left', 'vľavo' ),
+ 'img_none' => array( 1, 'none', 'žiadny' ),
+ 'img_width' => array( 1, '$1px', '$1bod' ),
+ 'img_center' => array( 1, 'center', 'centre', 'stred' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'rám' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'MENOLOKALITY' ),
+ 'ns' => array( 0, 'NS:', 'MP:' ),
+ 'localurl' => array( 0, 'LOCALURL:' ),
+ 'localurle' => array( 0, 'LOCALURLE:' ),
+ 'server' => array( 0, 'SERVER' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'GRAMATIKA:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__' ),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'AKTUÁLNYTÝŽDEŇ' ),
+ 'currentdow' => array( 1, 'CURRENTDOW' ),
+ 'revisionid' => array( 1, 'REVISIONID' ),
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Médiá',
+ NS_SPECIAL => 'Špeciálne',
+ NS_MAIN => '',
+ NS_TALK => 'Diskusia',
+ NS_USER => 'Redaktor',
+ NS_USER_TALK => 'Diskusia_s_redaktorom',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Diskusia_k_{{grammar:datív|$1}}',
+ NS_IMAGE => 'Obrázok',
+ NS_IMAGE_TALK => 'Diskusia_k_obrázku',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Diskusia_k_MediaWiki',
+ NS_TEMPLATE => 'Šablóna',
+ NS_TEMPLATE_TALK => 'Diskusia_k_šablóne',
+ NS_HELP => 'Pomoc',
+ NS_HELP_TALK => 'Diskusia_k_pomoci',
+ NS_CATEGORY => 'Kategória',
+ NS_CATEGORY_TALK => 'Diskusia_ku_kategórii'
+);
+
+# Compatbility with old names
+$namespaceAliases = array(
+ "Komentár" => NS_TALK,
+ "Komentár_k_redaktorovi" => NS_USER_TALK,
+ "Komentár_k_Wikipédii" => NS_PROJECT_TALK,
+ "Komentár_k_obrázku" => NS_IMAGE_TALK,
+ "Komentár_k_MediaWiki" => NS_MEDIAWIKI_TALK,
+);
+
+$separatorTransformTable = array(
+ ',' => "\xc2\xa0",
+ '.' => ','
+);
+
+$linkTrail = '/^([a-záäčďéíľĺňóôŕšťúýž]+)(.*)$/sDu';
+
+
+$messages = array(
+'tog-underline' => 'Podčiarkuj odkazy',
+'tog-highlightbroken' => 'Neexistujúce odkazy zobrazuj červenou',
+'tog-justify' => 'Zarovnávaj odstavce',
+'tog-hideminor' => 'V posledných úpravách neukazuj drobné úpravy',
+'tog-extendwatchlist' => 'Rozšír zoznam sledovaných, aby ukazoval všetky súvisiace zmeny',
+'tog-usenewrc' => 'Špeciálne zobrazenie posledných úprav (vyžaduje JavaScript)',
+'tog-numberheadings' => 'Automaticky čísluj odstavce',
+'tog-showtoolbar' => 'Zobrazuj upravovací panel nástrojov',
+'tog-editondblclick' => 'Upravuj stránky po dvojitom kliknutí (JavaScript)',
+'tog-editsection' => 'Umožni upravovať sekcie cez odkazy [úprava]',
+'tog-editsectiononrightclick'=> 'Umožni upravovať sekcie po kliknutí pravým tlačidlom na nadpisy sekcií (JavaScript)',
+'tog-showtoc' => 'Zobraz obsah (pre stránky s viac ako 3 nadpismi)',
+'tog-rememberpassword' => 'Pamätaj si heslo aj nabudúce',
+'tog-editwidth' => 'Maximálna šírka okna na úpravy',
+'tog-watchcreations' => 'Pridaj stránky, ktoré vytvorím do môjho zoznamu sledovaných stránok',
+'tog-watchdefault' => 'Upozorňuj na nové a novo upravené stránky',
+'tog-minordefault' => 'Označ všetky zmeny štandardne ako drobné',
+'tog-previewontop' => 'Zobrazuj ukážku pred oknom na úpravy, a nie až za ním',
+'tog-previewonfirst' => 'Zobraz náhľad pri prvom upravovaní',
+'tog-nocache' => 'Vypni ukladanie stránok do vyrovnávacej pamäte',
+'tog-enotifwatchlistpages'=> 'Pošli mi email keď sa stránka zmení',
+'tog-enotifusertalkpages'=> 'Pošli mi email po zmene mojej redaktorskej diskusnej stránky',
+'tog-enotifminoredits' => 'Pošli mi email aj o drobných úpravách stránok',
+'tog-enotifrevealaddr' => 'Zobraz moju emailovú adresu v notifikačných emailoch',
+'tog-shownumberswatching'=> 'Zobraz počet sledujúcich používateľov',
+'tog-fancysig' => 'Nespracovávať podpisy (bez automatických odkazov)',
+'tog-externaleditor' => 'Používaj štandardne externý editor',
+'tog-externaldiff' => 'Používaj štandardne externý diff',
+'tog-showjumplinks' => 'Používaj odkazy „skočiť na“ pre lepšiu dostupnosť',
+'tog-uselivepreview' => 'Použitie živého náhľadu (JavaScript) (experimentálna funkcia)',
+'tog-autopatrol' => 'Označ úpravy, ktoré urobím, ako strážené',
+'tog-forceeditsummary' => 'Upozorni ma, keď neuvádzam zhrnutie úprav',
+'tog-watchlisthideown' => 'Skry moje úpravy zo zoznamu sledovaných',
+'tog-watchlisthidebots' => 'Skry úpravy botov zo zoznamu sledovaných',
+'tog-nolangconversion' => 'Vypni konverziu variantov',
+'tog-ccmeonemails' => 'Pošli mi kópie mojich emailov, ktoré pošlem ostatným používateľom',
+
+'underline-always' => 'Vždy',
+'underline-never' => 'Nikdy',
+'underline-default' => 'Štandardné nastavenie prehliadača',
+'skinpreview' => '(Náhľad)',
+'sunday' => 'nedeľa',
+'monday' => 'pondelok',
+'tuesday' => 'utorok',
+'wednesday' => 'streda',
+'thursday' => 'štvrtok',
+'friday' => 'piatok',
+'saturday' => 'sobota',
+'sun' => 'Ned',
+'mon' => 'Pon',
+'tue' => 'Uto',
+'wed' => 'Str',
+'thu' => 'Štv',
+'fri' => 'Pia',
+'sat' => 'Sob',
+'january' => 'január',
+'february' => 'február',
+'march' => 'marec',
+'april' => 'apríl',
+'may_long' => 'máj',
+'june' => 'jún',
+'july' => 'júl',
+'august' => 'august',
+'september' => 'september',
+'october' => 'október',
+'november' => 'november',
+'december' => 'december',
+'january-gen' => 'januára',
+'february-gen' => 'februára',
+'march-gen' => 'marca',
+'april-gen' => 'apríla',
+'may-gen' => 'mája',
+'june-gen' => 'júna',
+'july-gen' => 'júla',
+'august-gen' => 'augusta',
+'september-gen' => 'septembra',
+'october-gen' => 'októbra',
+'november-gen' => 'novembra',
+'december-gen' => 'decembra',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'máj',
+'jun' => 'jún',
+'jul' => 'júl',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dec',
+'categories' => '{{PLURAL:$1|Kategória|Kategórie|Kategórie}}',
+'pagecategories' => '{{PLURAL:$1|Kategória|Kategórie|Kategórie}}',
+'category_header' => 'stránky v kategórii „$1“',
+'subcategories' => 'Podkategórie',
+'category-media-header' => 'Multimediálne súbory v kategórii "$1"',
+'mainpage' => 'Hlavná stránka',
+'mainpagetext' => 'Wiki softvér bol úspešne nainštalovaný.',
+'mainpagedocfooter' => 'Pre pomoc a konfiguračné nastavenia prosím pozrite [http://meta.wikimedia.org/wiki/MediaWiki_i18n documentation on customizing the interface] a [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide User\'s Guide].',
+'portal' => 'Portál komunity',
+'portal-url' => 'Project:Portál komunity',
+'about' => 'Projekt',
+'aboutsite' => 'O {{GRAMMAR:lokál|{{SITENAME}}}}',
+'aboutpage' => 'Project:Úvod',
+'article' => 'Stránka s obsahom',
+'help' => 'Pomoc',
+'helppage' => 'Pomoc:Obsah',
+'bugreports' => 'Oznámenia o chybách',
+'bugreportspage' => 'Project:Oznámenia o chybách',
+'sitesupport' => 'Donácie',
+'sitesupport-url' => 'Project:Dotácie',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => 'Ako upravovať stránku',
+'newwindow' => '(otvorí v novom okne)',
+'edithelppage' => 'Pomoc:Ako upravovať stránku',
+'cancel' => 'Zrušiť',
+'qbfind' => 'Nájdi',
+'qbbrowse' => 'Listuj',
+'qbedit' => 'Upravuj',
+'qbpageoptions' => 'Možnosti stránky',
+'qbpageinfo' => 'Informácie o stránke',
+'qbmyoptions' => 'Moje nastavenia',
+'qbspecialpages' => 'Špeciálne stránky',
+'moredotdotdot' => 'Viac...',
+'mypage' => 'Moja stránka',
+'mytalk' => 'Moja diskusia',
+'anontalk' => 'Diskusia k tejto IP adrese',
+'navigation' => 'Navigácia',
+'metadata_help' => 'Metadáta (vysvetlenie pozri na [[Project:Metadata]]):',
+'currentevents' => 'Aktuality',
+'currentevents-url' => 'Aktuality',
+'disclaimers' => 'Vylúčenie zodpovednosti',
+'disclaimerpage' => 'Project:Vylúčenie zodpovednosti',
+'privacy' => 'Ochrana osobných údajov',
+'privacypage' => 'Project:Ochrana osobných údajov',
+'errorpagetitle' => 'Chyba',
+'returnto' => 'Späť na $1.',
+'tagline' => 'Z {{GRAMMAR:genitív|{{SITENAME}}}}',
+'search' => 'Hľadaj',
+'searchbutton' => 'Hľadaj',
+'go' => 'Choď',
+'searcharticle' => 'Choď',
+'history' => 'história stránky',
+'history_short' => 'História',
+'updatedmarker' => 'aktualizované od mojej poslednej návštevy',
+'info_short' => 'Informácie',
+'printableversion' => 'Verzia na tlač',
+'permalink' => 'Trvalý odkaz',
+'print' => 'Tlač',
+'edit' => 'úprava',
+'editthispage' => 'Upravuj túto stránku',
+'delete' => 'Vymaž',
+'deletethispage' => 'Vymaž túto stránku',
+'undelete_short' => 'Obnov $1 úprav',
+'protect' => 'Zamkni',
+'protectthispage' => 'Zamkni túto stránku',
+'unprotect' => 'Odomkni',
+'unprotectthispage' => 'Odomkni túto stránku',
+'newpage' => 'Nová stránka',
+'talkpage' => 'Diskusia k stránke',
+'specialpage' => 'Špeciálna stránka',
+'personaltools' => 'Osobné nástroje',
+'postcomment' => 'Pridaj komentár',
+'articlepage' => 'Zobraz stránku',
+'talk' => 'Diskusia',
+'views' => 'Zobrazení',
+'toolbox' => 'Nástroje',
+'userpage' => 'Zobraz stránku redaktora',
+'projectpage' => 'Zobraz projektovú stránku',
+'imagepage' => 'Zobraz popisnú stránku obrázka',
+'mediawikipage' => 'Zobraz stránku so správou',
+'templatepage' => 'Zobraziť stránku šablóny',
+'viewhelppage' => 'Zobraziť stránku Pomocníka',
+'categorypage' => 'Zobraz stránku kategórie',
+'viewtalkpage' => 'Zobraz diskusiu k stránke',
+'otherlanguages' => 'Iné jazyky',
+'redirectedfrom' => '(Presmerované z $1)',
+'redirectpagesub' => 'Presmerovacia stránka',
+'lastmodifiedat' => 'Čas poslednej úpravy tejto stránky je $2, $1.',
+'viewcount' => 'Táto stránka bola navštívená $1-krát.',
+'copyright' => 'Obsah je dostupný pod $1.',
+'protectedpage' => 'Zamknutá stránka',
+'jumpto' => 'Skoč na:',
+'jumptonavigation' => 'navigácia',
+'jumptosearch' => 'hľadanie',
+'badaccess' => 'Chyba povolenia',
+'badaccess-group0' => 'Nemáte povolenie na vykonanie požadovanej akcie.',
+'badaccess-group1' => 'Akciu, ktorú požadujete môže vykonať iba člen skupiny $1.',
+'badaccess-group2' => 'Akciu, ktorú požadujete môže vykonať iba člen jednej zo skupín $1.',
+'badaccess-groups' => 'Akciu, ktorú požadujete môže vykonať iba člen jednej zo skupín $1.',
+'versionrequired' => 'Požadovaná verzia MediaWiki $1',
+'versionrequiredtext' => 'Na použitie tejto stránky je požadovaná verzia MediaWiki $1. Pozri [[Special:Version]]',
+'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Zdroj: "$1"',
+'youhavenewmessages' => 'Máte $1 ($2).',
+'newmessageslink' => 'nové správy',
+'newmessagesdifflink' => 'diff s predposlednou revíziou',
+'editsection' => 'úprava',
+'editold' => 'upraviť',
+'editsectionhint' => 'Upravuj sekciu: $1',
+'toc' => 'Obsah',
+'showtoc' => 'zobraz',
+'hidetoc' => 'schovaj',
+'thisisdeleted' => 'Zobraziť alebo obnoviť $1?',
+'viewdeleted' => 'Zobraziť $1?',
+'restorelink' => '{{PLURAL:$1|jedna zmazaná úprava|$1 zmazané úpravy|$1 zmazaných úprav}}',
+'feedlinks' => 'Kanál:',
+'feed-invalid' => 'Neplatný typ feedu.',
+'nstab-main' => 'Stránka',
+'nstab-user' => 'Stránka redaktora',
+'nstab-media' => 'Médiá',
+'nstab-special' => 'Špeciálne',
+'nstab-project' => 'Projektová stránka',
+'nstab-image' => 'Súbor',
+'nstab-mediawiki' => 'Správa',
+'nstab-template' => 'Šablóna',
+'nstab-help' => 'Pomoc',
+'nstab-category' => 'Kategória',
+'nosuchaction' => 'Takáto akcia neexistuje',
+'nosuchactiontext' => 'Softvér MediaWiki nepozná akciu,
+ktorú vyžadujete pomocou URL.',
+'nosuchspecialpage' => 'Takáto špeciálna stránka neexistuje',
+'nospecialpagetext' => 'Softvér MediaWiki nepozná takúto špeciálnu stránku, zoznam špeciálnych stránok nájdete na [[Special:Specialpages]].',
+'error' => 'Chyba',
+'databaseerror' => 'Chyba v databáze',
+'dberrortext' => 'Nastala syntaktická chyba v príkaze na prehľadávanie databázy.
+Posledný pokus o prehľadávanie bol:
+<blockquote><tt>$1</tt></blockquote>
+z funkcie "<tt>$2</tt>".
+MySQL vrátil chybu "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Nastala syntaktická chyba pri dotaze do databázy.
+Posledný pokus o dotaz do databázy znel:
+"$1"
+z funkcie "$2".
+MySQL vrátil chybu "$3: $4".',
+'noconnect' => 'Prepáčte! Wiki má technické problémy a nemôže kontaktovať databázový server. <br />
+$1',
+'nodb' => 'Neviem vybrať databázu $1',
+'cachederror' => 'Nasledujúca stránka je odložená kópia vyžiadanej stránky a nemusí byť aktuálna.',
+'laggedslavemode' => 'Varovanie: Je možné, že stránka neobsahuje posledné aktualizácie.',
+'readonly' => 'Databáza je zamknutá',
+'enterlockreason' => 'Zadajte dôvod požadovaného zamknutia vrátane odhadu, kedy očakávate odomknutie',
+'readonlytext' => 'Databáza je momentálne zamknutá, nové stránky a úpravy sú zablokované, pravdepodobne z dôvodu údržby databázy. Po skončení tejto údržby bude {{SITENAME}} opäť fungovať normálne.
+
+Správca, ktorý nariadil uzamknutie, uvádza tento dôvod: $1',
+'missingarticle' => 'Databáza nenašla text stránky, ktorý by mala nájsť, menovite "$1".
+
+Toto je zvyčajne zapríčinené odkazovaním na staršie verzie alebo odkazom na stránku, ktorý bol zmazaný.
+
+Ak to nie je ten prípad, možno ste našli chybu s softvéri. Prosím ohláste túto chybu správcovi, uveďte aj názov stránky - odkaz (URL).',
+'readonly_lag' => 'The databáza bola automaticky zamknutá pokým záložné databázové servery nedoženú hlavný server',
+'internalerror' => 'Vnútorná chyba',
+'filecopyerror' => 'Neviem skopírovať súbor "$1" na "$2".',
+'filerenameerror' => 'Neviem premenovať súbor "$1" na "$2".',
+'filedeleteerror' => 'Neviem vymazať súbor "$1".',
+'filenotfound' => 'Neviem nájsť súbor "$1".',
+'unexpected' => 'Nečakaná hodnota: "$1"="$2".',
+'formerror' => 'Chyba: neviem spracovať formulár',
+'badarticleerror' => 'Na tejto stránke túto akciu nemožno vykonať.',
+'cannotdelete' => 'Neviem zmazať danú stránku alebo súbor. (Možno už bol zmazaný niekým iným.)',
+'badtitle' => 'Neplatný nadpis',
+'badtitletext' => 'Požadovaný nadpis bol neplatný, nezadaný, alebo nesprávne odkazovaný z inej jazykovej verzie {{GRAMMAR:genitív|{{SITENAME}}}}. Mohol tiež obsahovať jeden alebo viac znakov, ktoré nie je možné použiť v nadpisoch.',
+'perfdisabled' => 'Prepáčte! Táto funkcia bola dočasne vypnutá,
+pretože tak spomaľuje databázu, že nikto nemôže používať
+wiki.',
+'perfdisabledsub' => 'Tu je uložená kópia z $1:',
+'perfcached' => '<span style="color:#ff0000"><strong>Nasledujúce dáta sú z dočasnej pamäte a nemusia byť úplne aktuálne:</strong></span>',
+'perfcachedts' => 'Nasledujúce údaje pochádzajú z cache a naposledy boli aktualizované $1.',
+'wrong_wfQuery_params' => 'Nesprávny parameter v wfQuery()<br />
+Funkcia: $1<br />
+Dotaz: $2',
+'viewsource' => 'Zobraz zdroj',
+'viewsourcefor' => '$1',
+'protectedtext' => 'Táto stránka bola zamknutá na zabránenie úprav; pravdepodobne existuje
+veľa dôvodov prečo je to tak, prosíme pozrite
+[[Project:Zamknutá stránka]].
+
+Môžete si pozrieť a skopírovať zdroj tejto stránky:',
+'protectedinterface' => 'Táto stránka poskytuje text používateľského rozhrania a aby sa predišlo zneužitiam, upravovať ju môžu iba [[Project:Správcovia|správcovia]].',
+'editinginterface' => '\'\'\'Varovanie:\'\'\' Upravujete stránku, ktorá poskytuje text používateľského rozhrania. Zmeny tejto stránky ovplyvnia vzhľad používateľského rozhrania ostatných používateľov.',
+'sqlhidden' => '(SQL príkaz na prehľadávanie je skrytý)',
+'logouttitle' => 'Odhlásiť redaktora',
+'logouttext' => 'Práve ste sa odhlásili.
+Odteraz môžete používať {{GRAMMAR:akuzatív|{{SITENAME}}}} ako anonymný redaktor alebo sa môžete
+opäť prihlásiť pod rovnakým alebo odlišným redaktorským menom. Uvedomte si, že niektoré stránky sa môžu
+naďalej zobrazovať ako keby ste boli prihlásený, až kým nevymažete
+vyrovnávaciu pamäť vášho prehliadača.',
+'welcomecreation' => '== Vitaj, $1! ==
+
+Vaše konto je vytvorené. Nezabudnite si nastaviť vaše redaktorské nastavenia.',
+'loginpagetitle' => 'Prihlásenie redaktora',
+'yourname' => 'Vaše redaktorské meno',
+'yourpassword' => 'Vaše heslo',
+'yourpasswordagain' => 'Zopakujte heslo',
+'remembermypassword' => 'Pamätať si heslo aj po vypnutí počítača.',
+'yourdomainname' => 'Vaša doména',
+'externaldberror' => 'Buď nastala chyba externej autentifikačnej databázy alebo Vám nie je povolené aktualizovať Váš externý účet.',
+'loginproblem' => '<b>Nastal problém pri vašom prihlasovaní.</b><br />Skúste znova!',
+'alreadyloggedin' => '\'\'\'Užívateľ $1, vy už ste prihlásený!\'\'\'<br />',
+'login' => 'Prihlásenie',
+'loginprompt' => 'Na prihlásenie do {{GRAMMAR:genitív|{{SITENAME}}}} musíte mať zapnuté koláčiky (cookies).',
+'userlogin' => 'Vytvorte si konto alebo sa prihláste',
+'logout' => 'Odhlásenie',
+'userlogout' => 'Odhlásenie',
+'notloggedin' => 'Neprihlásený/á',
+'nologin' => 'Nemáte ešte účet? $1.',
+'nologinlink' => 'Vytvoriť nový účet',
+'createaccount' => 'Vytvoriť nový účet',
+'gotaccount' => 'Máte už vytvorený účet? $1.',
+'gotaccountlink' => 'Prihlásenie',
+'createaccountmail' => 'e-mailom',
+'badretype' => 'Zadané heslá nie sú rovnaké.',
+'userexists' => 'Zadané redaktorské meno už používa niekto iný. Zadajte iné meno.',
+'youremail' => 'Váš e-mail²',
+'username' => 'Používateľské meno:',
+'uid' => 'ID užívateľa:',
+'yourrealname' => 'Skutočné meno *:',
+'yourlanguage' => 'Jazyk:',
+'yourvariant' => 'Variant',
+'yournick' => 'Prezývka:',
+'badsig' => 'Neplatný podpis v pôvodnom tvare; skontrolujte HTML tagy.',
+'email' => 'E-mail',
+'prefs-help-email-enotif'=> 'Táto adresa sa používa aj na posielanie e-mailových upozornení, ak ste túto možnosť povolili.',
+'prefs-help-realname' => '¹ Skutočné meno (nepovinné): ak sa rozhodnete ho poskytnúť, bude použité na označenie Vašej práce.',
+'loginerror' => 'Chyba pri prihlasovaní',
+'prefs-help-email' => '² E-mail (nepovinné): Umožní iným ľuďom kontaktovať Vás z Vašej užívateľskej a diskusnej, bez potreby uverejňovania Vašej e-mailovej adresy a môže byť použité na poslanie nového hesla, ak zabudnete pôvodné.',
+'nocookiesnew' => 'Redaktorské konto bolo vytvorené, ale nie ste prihlásený. {{SITENAME}} používa koláčiky (cookies) na prihlásenie. Vy máte koláčiky (cookies) vypnuté. Zapnite ich a potom sa prihláste s vaším novým redaktorským menom a heslom.',
+'nocookieslogin' => '{{SITENAME}} používa koláčiky (cookies) na prihlásenie. Vy máte koláčiky vypnuté. Prosíme, zapnite ich a skúste znovu.',
+'noname' => 'Nezadali ste platné redaktorské meno.',
+'loginsuccesstitle' => 'Prihlásenie úspešné',
+'loginsuccess' => 'Teraz ste prihlásený do {{GRAMMAR:genitív|{{SITENAME}}}} ako "$1".',
+'nosuchuser' => 'Redaktorské meno "$1" neexistuje. Skontrolujte preklepy alebo sa prihláste ako nový redaktor pomocou dolu uvedeného formulára.',
+'nosuchusershort' => 'V súčasnosti neexistuje redaktor s menom "$1". Skontrolujte preklepy.',
+'nouserspecified' => 'Musíte uviesť meno používateľa.',
+'wrongpassword' => 'Zadané heslo je nesprávne. Skúste znovu.',
+'wrongpasswordempty' => 'Zadané heslo bolo prázdne. Skúste prosím znova.',
+'mailmypassword' => 'Pošlite mi e-mailom dočasné heslo',
+'passwordremindertitle' => 'Oznámenie o hesle z {{GRAMMAR:genitív|{{SITENAME}}}}',
+'passwordremindertext' => 'Niekto (pravdepodobne vy, z IP adresy $1)
+požiadal, aby sme vám zaslali nové prihlasovacie heslo do {{GRAMMAR:genitív|{{SITENAME}}}} ($4).
+Heslo pre redaktora "$2" je teraz "$3".
+Teraz by ste sa mali prihlásiť a zmeniť vaše heslo.
+
+Ak túto požiadavku poslal niekto iný alebo ste si spomenuli svoje heslo a neželáte
+si ho zmeniť, môžete túto správu ignorovať a naďalej používať svoje staré heslo.',
+'noemail' => 'Redaktor "$1" nezadal e-mailovú adresu.',
+'passwordsent' => 'Nové heslo bolo zaslané na e-mailovú adresu
+redaktora "$1".
+Prosím, prihláste sa znovu, keď ho obdržíte.',
+'blocked-mailpassword' => 'Boli zablokované úpravy z vašej IP adresy, a tak nie je dovolené použiť funkciu znovuvyžiadania hesla, aby sa zabránilo zneužitiu.',
+'eauthentsent' => 'Email s potvrdením bol zaslaný na uvedenú emailovú adresu.
+Predtým ako sa na účet pošle akákoľvek ďalšia pošta, musíte splniť inštrukcie v emaili, aby sa potvrdilo, že účet je skutočne Váš.',
+'throttled-mailpassword'=> 'V priebehu posledných $1 hodín už došlo k vyžiadaniu hesla.
+Aby sa zabránilo zneužitiu, vyžiadanie hesla je možné vykonať iba raz za $1 hodín.',
+'mailerror' => 'Chyba pri posielaní e-mailu: $1',
+'acct_creation_throttle_hit'=> 'Prepáčte, už máte vytvorených $1 účtov. Nemôžete ich z tejto IP adresy vytvoriť za 24 hodín viac. Toto je opatrenie proti vandalizmu.',
+'emailauthenticated' => 'Vaša e-mailová adresa bola overená na $1.',
+'emailnotauthenticated' => 'Vaša e-mailová adresa ešte nebola overená. Preto nemôžete prijať emaily pre žiadnu z nasledovných funkcií.',
+'noemailprefs' => '<strong>Nezadali ste žiadnu e-mailovú adresu</strong>, nasledujúce
+nástroje nebudú prístupné.',
+'emailconfirmlink' => 'Potvrďte vašu e-mailovú adresu',
+'invalidemailaddress' => 'E-mailovú adresu nemožno akceptovať, pretože sa zdá, že má neplatný formát. Zadajte dobre naformátovanú adresu alebo nechajte príslušné políčko prázdne.',
+'accountcreated' => 'Účet vytvorený',
+'accountcreatedtext' => 'Používateľský účet pre $1 bol vytvorený.',
+'bold_sample' => 'Tučný text',
+'bold_tip' => 'Tučný text',
+'italic_sample' => 'Kurzíva',
+'italic_tip' => 'Kurzíva',
+'link_sample' => 'Názov odkazu',
+'link_tip' => 'Interný odkaz',
+'extlink_sample' => 'http://www.example.com názov odkazu',
+'extlink_tip' => 'Externý odkaz (nezabudnite prefix http://)',
+'headline_sample' => 'Text nadpisu',
+'headline_tip' => 'Text nadpisu úrovne 2',
+'math_sample' => 'Sem vložte vzorec',
+'math_tip' => 'Matematický vzorec (LaTeX)',
+'nowiki_sample' => 'Sem vložte neformátovaný text',
+'nowiki_tip' => 'Ignoruj wiki formátovanie',
+'image_sample' => 'Príklad.jpg',
+'image_tip' => 'Vložený obrázok',
+'media_sample' => 'Príklad.ogg',
+'media_tip' => 'Odkaz na media súbor',
+'sig_tip' => 'Váš podpis s dátumom a časom',
+'hr_tip' => 'Horizontálna čiara (používajte zriedka)',
+'summary' => 'Zhrnutie úprav',
+'subject' => 'Téma/nadpis',
+'minoredit' => 'Toto je drobná úprava',
+'watchthis' => 'Sleduj úpravy tejto stránky',
+'savearticle' => 'Ulož stránku',
+'preview' => 'Náhľad',
+'showpreview' => 'Zobraz náhľad',
+'showlivepreview' => 'Živý náhľad',
+'showdiff' => 'Zobraz rozdiely',
+'anoneditwarning' => 'Nie ste [[Special:Userlogin|prihlásený]]. Vaša [[IP adresa]] bude zaznamenaná v <span class="plainlinks"> [{{fullurl:{{FULLPAGENAME}}|action=history}} histórii úprav]</span> tejto stránky.',
+'missingsummary' => '\'\'\'Upozornenie:\'\'\' Neposkytli ste zhrnutie úprav. Ak kliknete znova na Uložiť, Vaše úpravy sa uložia bez zhrnutia úprav.',
+'missingcommenttext' => 'Prosím, dolu napíšte komentár.',
+'missingcommentheader' => '\'\'\'Pripomienka:\'\'\' Neposkutli ste predmet/hlavičku tohto komentára. Ak znova kliknete na tlačidlo Uložiť, vaša úprava sa uloží bez nej.',
+'summary-preview' => 'Náhľad zhrnutia',
+'subject-preview' => 'Náhľad predmetu/hlavičky',
+'blockedtitle' => 'Redaktor je zablokovaný',
+'blockedtext' => 'Vaše redaktorské meno alebo IP adresu zablokoval $1.
+Udáva tento dôvod:<br />\'\'$2\'\'
+
+Môžete kontaktovať $1 alebo s jedného z ďalších
+[[{{ns:project}}:Správcovia|správcov]] a prediskutovať blokovanie.
+
+Uvedomte si, že nemôžete použiť funkciu "Pošli e-mail redaktorovi", pokiaľ nemáte registrovanú platnú e-mailovú adresu vo vašich [[Special:Preferences|nastaveniach]].
+
+Vaša IP adresa je $3. Prosíme, zahrňte túto adresu do každého dotazu, ktorý posielate.',
+'blockedoriginalsource' => 'Zdroj \'\'\'$1\'\'\' je zobrazený nižšie:',
+'blockededitsource' => 'Text \'\'\'Vašich úprav\'\'\' stránky \'\'\'$1\'\'\' je zobrazený nižšie:',
+'whitelistedittitle' => 'Na úpravu je nutné prihlásenie',
+'whitelistedittext' => 'Na úpravu stránok sa musíte najskôr $1.',
+'whitelistreadtitle' => 'Je potrebné sa prihlásiť, aby ste mohli čítať',
+'whitelistreadtext' => 'Na čítanie stránok musíte byť [[Special:Userlogin|prihlásený/á]]',
+'whitelistacctitle' => 'Nemáte dovolené vytvorenie konta',
+'whitelistacctext' => 'Na umožnenie vytvorenia konta v tomto Wiki musíte byť [[Special:Userlogin|prihlásený/á]] a mať primerané práva.',
+'confirmedittitle' => 'Aby ste mohli upravovať je potrebné potvrdenie e-mailu',
+'confirmedittext' => 'Pred úpravami stránok musíte potvrdiť vašu emailovú adresu. Prosím, nastavte a overte svoju emailovú adresu v [[Special:Preferences|používateľských nastaveniach]].',
+'loginreqtitle' => 'Nutné prihlásenie',
+'loginreqlink' => 'prihlásiť',
+'loginreqpagetext' => 'Na prezeranie ďalších stránok sa musíte $1.',
+'accmailtitle' => 'Heslo odoslané.',
+'accmailtext' => 'Heslo pre \'$1\' bolo poslané na $2.',
+'newarticle' => '(Nový)',
+'newarticletext' => 'Sledovali ste odkaz na stránku, ktorá zatiaľ neexistuje.
+Stránku vytvoríte tak, že začnete písať do dolného poľa a potom stlačíte tlačidlo "Ulož stránku".
+(Viac informácií nájdete na stránkach [[{{ns:help}}:Obsah|Pomocníka]]).
+Ak ste sa sem dostali nechtiac, iba kliknite na tlačidlo \'\'\'späť\'\'\' vo svojom prehliadači.',
+'anontalkpagetext' => '<br />
+----
+\'\'Toto je diskusná stránka anonymného redaktora, ktorý nemá vytvorené svoje konto alebo ho nepoužíva. Preto musíme na jeho identifikáciu použiť numerickú IP adresu. Je možné, že takúto IP adresu používajú viacerí redaktori. Ak ste anonymný redaktor a máte pocit, že vám boli adresované irelevantné diskusné príspevky, zriaďte si konto alebo sa prihláste ([[Special:Userlogin|Zriadenie konta alebo prihlásenie]]), aby sa zamedzilo budúcim zámenám s inými anonymnými redaktormi\'\'',
+'noarticletext' => '{{MediaWiki Noarticletext NS {{NAMESPACE}}}}',
+'clearyourcache' => '\'\'\'Poznámka:\'\'\' Aby sa zmeny prejavili, po uložení musíte vymazať vyrovnávaciu pamäť vášho prehliadača: \'\'\'Mozilla:\'\'\' \'\'Ctrl-Shift-R\'\', \'\'\'IE:\'\'\' \'\'Ctrl-F5\'\', \'\'\'Safari:\'\'\' \'\'Cmd-Shift-R\'\', \'\'\'Konqueror:\'\'\' \'\'F5\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Tip:</strong> Použite tlačítko \'Zobraz náhľad\' na otestovanie Vášho nového CSS/JS pred uložením.',
+'usercsspreview' => '\'\'\'Nezabudnite, že toto je iba náhľad Vášho užívateľského CSS, ešte nebolo uložené!\'\'\'',
+'userjspreview' => '\'\'\'Nezabudnite, že iba testujete/náhľad vášho užívateľského JavaScriptu, ešte nebol uložený!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Varovanie:\'\'\' Neexistuje skin "$1". Pamätajte, že vlastné .css a .js stránky používajú názov s malými písmenami, napr. Redaktor:Foo/monobook.css na rozdiel od Redaktor:Foo/Monobook.css.',
+'updated' => '(Aktualizovaný)',
+'note' => '<strong>Poznámka: </strong>',
+'previewnote' => 'Nezabudnite, toto je len náhľad vami upravovanej stránky. Zmeny ešte nie sú uložené!',
+'session_fail_preview' => '<strong>Prepáčte, nemohli sme spracovať Váš príspevok kvôli strate údajov relácie (session). Skúste to prosím ešte raz. Ak to nebude fungovať, skúste sa odhlásiť a znovu prihlásiť.</strong>',
+'previewconflict' => 'Tento náhľad upravenej stránky zobrazuje text z horného poľa s textom tak, ako sa zobrazí potom, keď ju uložíte.',
+'session_fail_preview_html'=> '<strong>Prepáčte! Nemohli sme spracovať Vašu úpravu kvôli strate údajov relácie.</strong>
+
+\'\'Pretože táto wiki má použitie HTML umožnené, náhľad sa nezobrazí (prevencia pred JavaScript útokmi).\'\'
+
+<strong>Ak je toto legitímny pokus o úpravu, skúste prosím znova. Ak to stále nefunguje, skúste sa odhlásiť a znovu prihlásiť.</strong>',
+'importing' => 'Importuje sa $1',
+'editing' => 'Úprava stránky $1',
+'editinguser' => 'Úprava stránky $1',
+'editingsection' => 'Úprava stránky $1 (sekcia)',
+'editingcomment' => 'Úprava stránky $1 (komentár)',
+'editconflict' => 'Konflikt pri úprave: $1',
+'explainconflict' => 'Niekto iný zmenil túto stránku, zatiaľ čo
+ste ju upravovali vy.
+Horné okno na úpravy obsahuje text stránky tak, ako je momentálne platný.
+Vaše úpravy sú uvedené v dolnom okne na úpravy.
+Budete musieť zlúčiť vaše zmeny s existujúcim textom.
+<b>Iba</b> obsah horného okna sa uloží, keď
+stlačíte "Ulož stránku".<br />',
+'yourtext' => 'Váš text',
+'storedversion' => 'Uložená verzia',
+'nonunicodebrowser' => '<strong>UPOZORNENIE: Váš prehliadač nepodporuje unicode. Dočasným riešením ako bezpečne upravovať stránky je, že ne-ASCII znaky sa v upravovacom textovom poli zobrazia ako zodpovedajúce hexadecimálne hodnoty.</strong>',
+'editingold' => '<div style="background: #FFBDBD; border: 1px solid #BB7979; color: #000000; font-weight: bold; margin: 2em 0 1em; padding: .5em 1em; vertical-align: middle; clear: both;">POZOR: Upravujete starú
+verziu tejto stránky. Ak vašu úpravu uložíte, prepíšete tým všetky úpravy, ktoré nasledovali po tejto starej verzii.</div>',
+'yourdiff' => 'Rozdiely',
+'copyrightwarning' => 'Nezabudnite, že všetky príspevky do {{GRAMMAR:genitív|{{SITENAME}}}} sa považujú za príspevky pod licenciou $2 (podrobnosti pozri pod $1). Ak nechcete, aby bolo to, čo ste napísali, neúprosne upravované a ďalej ľubovoľne rozširované, tak sem váš text neumiestňujte.<br />
+
+Týmto sa právne zaväzujete, že ste tento text buď napísali sám, alebo že je skopírovaný
+z voľného diela (public domain) alebo podobného zdroja neobmedzeného autorskými právami.
+<strong>NEUMIESTŇUJTE TU BEZ POVOLENIA DIELA CHRÁNENÉ AUTORSKÝM PRÁVOM!</strong>',
+'copyrightwarning2' => 'Prosím uvedomte si, že všetky príspevky do {{GRAMMAR:genitív|{{SITENAME}}}} môžu byť upravované, skracované alebo odstránené inými príspievateľmi. Ak nechcete, aby Vaše texty boli menené, tak ich tu neuverejňujte.<br />
+
+Týmto sa právne zaväzujete, že ste tento text buď napísali sám, alebo že je skopírovaný
+z voľného diela (public domain) alebo podobného zdroja neobmedzeného autorskými právami (podrobnosti: $1).
+<strong>NEUMIESTŇUJTE SEM BEZ POVOLENIA DIELA CHRÁNENÉ AUTORSKÝM PRÁVOM!</strong>',
+'longpagewarning' => '<strong>POZOR: Táto stránka má $1 kilobajtov; niektoré
+prehliadače by mohli mať problémy s úpravou stránok, ktorých veľkosť sa blíži k alebo presahuje 32kb.
+Zvážte, či by nebolo možné rozdeliť stránku na menšie sekcie.</strong>',
+'longpageerror' => '<strong>CHYBA: Text, ktorý ste poslali má $1 kilobajtov, čo je viac ako maximum $2 kilobajtov. Nie je možné ho uložiť.</strong>',
+'readonlywarning' => '<strong>POZOR: Databáza bola počas upravovania stránky zamknutá z dôvodu údržby,
+takže stránku momentálne nemôžete uložiť. Môžete skopírovať a vložiť
+text do textového súboru a uložiť si ho na neskôr.</strong>',
+'protectedpagewarning' => '<strong>POZOR: Táto stránka bola zamknutá, takže ju môžu upravovať iba redaktori s oprávnením správcu. Uistite sa, že rozumiete [[Project:Pravidlá zamykania stránok|pravidlám zamykania stránok]].</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Poznámka:\'\'\' Táto stránka bola zamknutá tak, aby ju mohli upravovať iba registrovaní používatelia.',
+'templatesused' => 'Šablóny použité na tejto stránke:',
+'templatesusedpreview' => 'Šablóny použité v tomto náhľade:',
+'templatesusedsection' => 'Šablóny použité v tejto sekcii:',
+'edittools' => '<!-- Tento text sa zobrazí pod upravovacím a nahrávacím formulárom. -->',
+'nocreatetitle' => 'Tvorba nových stránok bola obmedzená',
+'nocreatetext' => 'Na tejto stránke je tvorba nových stránok obmedzená.
+Teraz sa môžete vrátiť späť a upravovať existujúcu stránku alebo [[Special:Userlogin|sa prihlásiť alebo vytvoriť účet]].',
+'undofailed' => 'Vrátenie sa nepodarilo',
+'explainundofailed' => 'Úpravu nie je možné vrátiť, pretože za ňou nasledujú ďalšie úpravy, čo by spôsobilo konflikt. Prosím, vraťte zmeny ručne.',
+'undosucceeded' => 'Vrátenie úspešné',
+'explainundosucceeded' => 'Úprava bola úspešne vrátená. Prosím, kliknite na uložiť, čím sa zmeny aplikujú.',
+'undo-summary' => 'Používateľ [[Special:Contributions/$2]] ([[User talk:$2]]) vrátil revíziu $1',
+'cantcreateaccounttitle'=> 'Nedá sa vytvoriť účet',
+'cantcreateaccounttext' => 'Vytvorenie účtu z tejto IP adresy (<b>$1</b>) bolo zablokované. Pravdepodobne je to kvôli sústavnému vandalizmu z adresy vašej školy či poskytovateľa internetového poskytovateľa.',
+'revhistory' => 'Predošlé verzie',
+'viewpagelogs' => 'Zobraziť záznamy pre túto stránku',
+'nohistory' => 'Pre túto stránku neexistuje história.',
+'revnotfound' => 'Predošlá verzia nebola nájdená',
+'revnotfoundtext' => 'Požadovaná staršia verzia stránky nebola nájdená.
+Prosím skontrolujte URL adresu, ktorú ste použili na prístup k tejto stránke.',
+'loadhist' => 'Sťahovanie histórie stránky',
+'currentrev' => 'Aktuálna verzia',
+'revisionasof' => 'Verzia zo dňa a času $1',
+'revision-info' => 'Revízia z $1; $2',
+'previousrevision' => '← Staršia verzia',
+'nextrevision' => 'Novšia verzia →',
+'currentrevisionlink' => 'Zobrazenie aktuálnej úpravy',
+'cur' => 'aktuálna',
+'next' => 'ďalšia',
+'last' => 'posledná',
+'orig' => 'pôvodná',
+'histlegend' => 'Legenda: (aktuálna) = rozdiel oproti aktuálnej verzii,
+(posledná) = rozdiel oproti predchádzajúcej verzii, D = drobná úprava',
+'deletedrev' => '[zmazané]',
+'histfirst' => 'Najskorší',
+'histlast' => 'Posledný',
+'rev-deleted-comment' => '(komentár odstránený)',
+'rev-deleted-user' => '(používateľské meno odstránené)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Táto revízia stránky bola odstránená z verejných archívov.
+Podrobnosti nájdete v [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} zázname mazaní].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Táto revízia stránky bola odstránená z verejných archívov.
+Ako správca tohto projektu si ju môžete prezrieť;
+podrobnosti môžu byť v [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} zázname mazaní].
+</div>',
+'rev-delundel' => 'ukáž/skry',
+'history-feed-title' => 'História úprav',
+'history-feed-description'=> 'História úprav pre túto stránku na wiki',
+'history-feed-item-nocomment'=> '$1 na $2',
+'history-feed-empty' => 'Požadovaná stránka neexistuje.
+Možno bola zmazaná z wiki alebo premenovaná.
+Skúste [[Special:Search|vyhľadávať na wiki]] relevantné nové stránky.',
+'revisiondelete' => 'Zmazať/obnoviť revízie',
+'revdelete-nooldid-title'=> 'Chýba cieľová revízia',
+'revdelete-nooldid-text'=> 'Nešpecifikovali ste cieľovú revíziu alebo revízie, na ktorých sa má táto funkcia vykonať.',
+'revdelete-selected' => 'Vyber revíziu [[:$1]]:',
+'revdelete-text' => 'Zmazané revízie sú stále viditeľné v histórii úprav stránky,
+ale ich obsah nebude prístupný verejnosti.
+
+Iní správcovia tejto wiki budú stále môcť pristupovať k skrytému obsahu a môžu
+ho znova obnoviť použitím tohto rozhrania v prípade, že operátormi projektu
+nie sú stanovené ďakšie obmedzenia.',
+'revdelete-legend' => 'Nastav obmedzenia revízie:',
+'revdelete-hide-text' => 'Skry text revízie',
+'revdelete-hide-comment'=> 'Skry zhrnutie úprav',
+'revdelete-hide-user' => 'Skry používateľské meno/IP redaktora',
+'revdelete-hide-restricted'=> 'Použi tieto obmedzenia na správcov ako aj na ostatných',
+'revdelete-log' => 'Komentár záznamu:',
+'revdelete-submit' => 'Použi na zvolenú revíziu',
+'revdelete-logentry' => 'viditeľnosť revízie bola zmenená pre [[$1]]',
+'difference' => '(Rozdiel medzi revíziami)',
+'loadingrev' => 'Sťahujem verzie, na zobrazenie rozdielov',
+'lineno' => 'Riadok $1:',
+'editcurrent' => 'Upraviť aktuálnu verziu tejto stránky',
+'selectnewerversionfordiff'=> 'Vybrať na porovnanie novšiu verziu',
+'selectolderversionfordiff'=> 'Vybrať na porovnanie staršiu verziu',
+'compareselectedversions'=> 'Porovnaj označené verzie',
+'editundo' => 'Vrátiť',
+'searchresults' => 'Výsledky vyhľadávania',
+'searchresulttext' => 'Viac informácií o vyhľadávaní vo {{GRAMMAR:lokál|{{SITENAME}}}} je uvedených na $1.',
+'searchsubtitle' => 'Na vyhľadávací dotaz "[[:$1]]"',
+'searchsubtitleinvalid' => 'Na vyhľadávací dotaz "$1"',
+'badquery' => 'Nesprávne formulovaná požiadavka na vyhľadávanie',
+'badquerytext' => 'Váš text na prehľadávanie sme nemohli spracovať. Dôvodom je pravdepodobne to, že ste hľadali slovo kratšie ako tri písmená, čo zatiaľ {{SITENAME}} neumožňuje. Alebo ste možno výraz zle napísali, napríklad „dom a a záhrada“. Skúste iný text na prehľadávanie.',
+'matchtotals' => 'Výsledkom dotazu "$1" je {{plural:$2|jeden názov stránky|$3 názvy stránok|$3 názvov stránok}}
+a text {{plural:$3|jednej stránky|$3 názvy stránok|$3 názvov stránok}}.',
+'noexactmatch' => '\'\'\'Neexistuje stránka nazvaná "$1"\'\'\'. Chcete \'\'\'[[:$1|vytvoriť novú stránku]]\'\'\' s týmto názvom?',
+'titlematches' => 'Vyhovujúce názvy stránok',
+'notitlematches' => 'V názvoch stránok nebola nájdená zhoda',
+'textmatches' => 'Zhody v textoch stránok',
+'notextmatches' => 'V textoch stránok nebola nájdená zhoda',
+'prevn' => 'predošlá $1',
+'nextn' => 'ďalšia $1',
+'viewprevnext' => 'Zobraz ($1) ($2) ($3).',
+'showingresults' => 'Nižšie je zobrazených <b>$1</b> výsledkov, počnúc od #<b>$2</b>.',
+'showingresultsnum' => 'Nižšie je zobrazených <b>$3</b> výsledkov, počnúc od #<b>$2</b>.',
+'nonefound' => '<strong>Poznámka</strong>: bezvýsledné vyhľadávania sú často spôsobené buď snahou hľadať príliš bežné, obyčajné slová (napríklad slovo \'\'je\'\'), pretože tieto sa nezaraďujú do indexu vyhľadávača, alebo uvedením viac ako jedného vyhľadávaného výrazu, pretože výsledky uvádzajú len stránky obsahujúce všetky vyhľadávané výrazy.',
+'powersearch' => 'Vyhľadávanie',
+'powersearchtext' => 'Vyhľadávania v menných priestoroch :<br />
+$1<br />
+$2 Zoznam presmerovaní &nbsp; Hľadanie pre $3 $9',
+'searchdisabled' => 'Prepáčte! Fulltextové vyhľadávanie bolo dočasne vypnuté z dôvodu preťaženia. Zatiaľ môžete použiť hľadanie pomocou Google, ktoré však nemusí byť aktuálne.',
+'blanknamespace' => '(Hlavný)',
+'preferences' => 'Nastavenia',
+'mypreferences' => 'nastavenia',
+'prefsnologin' => 'Nie ste prihlásený/á',
+'prefsnologintext' => 'Musíte byť [[Special:Userlogin|prihlásený/á]], aby ste mohli zmeniť vaše nastavenia.',
+'prefsreset' => 'Boli obnovené pôvodné nastavenia.',
+'qbsettings' => 'Bočný panel',
+'changepassword' => 'Zmeniť heslo',
+'skin' => 'Vzhľad',
+'math' => 'Vykreslenie matematiky',
+'dateformat' => 'Formát dátumu',
+'datedefault' => 'Predvolený',
+'datetime' => 'Dátum a čas',
+'math_failure' => 'Syntaktická analýza (parsing) neúspešná',
+'math_unknown_error' => 'neznáma chyba',
+'math_unknown_function' => 'neznáma funkcia',
+'math_lexing_error' => 'lexikálna chyba',
+'math_syntax_error' => 'syntaktická chyba',
+'math_image_error' => 'PNG konverzia neúspešná; skontrolujte správnosť inštalácie programov: latex, dvips, gs a convert',
+'math_bad_tmpdir' => 'Nemôžem zapisovať alebo vytvoriť dočasný matematický adresár',
+'math_bad_output' => 'Nemôžem zapisovať alebo vytvoriť výstupný matematický adresár',
+'math_notexvc' => 'Chýbajúci program texvc; konfigurácia je popísaná v math/README.',
+'prefs-personal' => 'Profil',
+'prefs-rc' => 'Posledné úpravy',
+'prefs-watchlist' => 'Sledované stránky',
+'prefs-watchlist-days' => 'Koľko dní zobrazovať v sledovaných stránkach:',
+'prefs-watchlist-edits' => 'Počet úprav, ktorý sa zobrazí v rozšírenom zozname sledovaných:',
+'prefs-misc' => 'Rôzne',
+'saveprefs' => 'Ulož nastavenia',
+'resetprefs' => 'Obnoviť pôvodné nastavenia',
+'oldpassword' => 'Staré heslo:',
+'newpassword' => 'Nové heslo:',
+'retypenew' => 'Nové heslo (ešte raz):',
+'textboxsize' => 'Úpravy',
+'rows' => 'Riadky',
+'columns' => 'Stĺpce',
+'searchresultshead' => 'Vyhľadávanie',
+'resultsperpage' => 'Počet vyhovujúcich výsledkov zobrazených na strane',
+'contextlines' => 'Počet zobrazených riadkov z kažnej nájdenej stránky',
+'contextchars' => 'Počet kontextových znakov v riadku',
+'stubthreshold' => 'Hranica pre zobrazenie nedokončených stránok (výhonkov):',
+'recentchangescount' => 'Počet nadpisov uvedených v posledných úpravách',
+'savedprefs' => 'Vaše nastavenia boli uložené.',
+'timezonelegend' => 'Časové pásmo',
+'timezonetext' => 'Počet hodín, o ktorý sa váš miestny čas odlišuje od času na serveri (UTC).',
+'localtime' => 'Miestny čas',
+'timezoneoffset' => 'Rozdiel¹',
+'servertime' => 'Aktuálny čas na serveri',
+'guesstimezone' => 'Prevziať z prehliadača',
+'allowemail' => 'Povoľ prijímanie e-mailov od iných redaktorov',
+'defaultns' => 'Štandardne vyhľadávaj v týchto menných priestoroch:',
+'default' => 'predvolený',
+'files' => 'Súbory',
+'userrights-lookup-user'=> 'Spravuj skupiny redaktorov',
+'userrights-user-editname'=> 'Napíš meno redaktora:',
+'editusergroup' => 'Uprav skupinu Redaktora',
+'userrights-editusergroup'=> 'Uprav skupinu',
+'saveusergroups' => 'Ulož skupinu',
+'userrights-groupsmember'=> 'Člen skupiny:',
+'userrights-groupsavailable'=> 'Dostupné skupiny:',
+'userrights-groupshelp' => 'Označte skupiny, do ktorých chcete pridať alebo z ktorých chcete
+odobrať redaktora. Neoznačené skupiny nebudú zmenené. Odobrať skupinu možete pomocou CTRL + kliknutie ľavým tlačidlom',
+'group' => 'Skupina:',
+'group-bot' => 'Boti',
+'group-sysop' => 'Správcovia',
+'group-bureaucrat' => 'Byrokrati',
+'group-all' => '(všetci)',
+'group-bot-member' => 'Bot',
+'group-sysop-member' => 'Správca',
+'group-bureaucrat-member'=> 'Byrokrat',
+'grouppage-bot' => 'Project:Boti',
+'grouppage-sysop' => 'Project:Správcovia',
+'grouppage-bureaucrat' => 'Project:Byrokrati',
+'changes' => 'úpravy',
+'recentchanges' => 'Posledné úpravy',
+'recentchangestext' => 'Pomocou tejto stránky sledujete posledné úpravy stránok {{GRAMMAR:genitív|{{SITENAME}}}}.
+Pozrite si stránky [[Project:Vitajte|Vitajte!]], [[Project:FAQ|{{SITENAME}} FAQ]].
+
+Ak chcete, aby {{SITENAME}} uspela, je veľmi dôležité, aby ste nepridávali
+materiál obmedzený inými [[Project:Autorské právo|autorskými právami]].
+Právne záväzky môžu projekt vážne poškodiť, takže Vás prosíme, aby ste to nerobili.',
+'rcnote' => 'Tu je posledných <strong>$1</strong> úprav počas posledných <strong>$2</strong> dní ($3).',
+'rcnotefrom' => 'Nižšie sú zobrazené úpravy od <b>$2</b> (do <b>$1</b>).',
+'rclistfrom' => 'Zobraz nové úpravy počnúc od $1',
+'rcshowhideminor' => '$1 drobné úpravy',
+'rcshowhidebots' => '$1 botov',
+'rcshowhideliu' => '$1 prihlásených používateľov',
+'rcshowhideanons' => '$1 anonymných používateľov',
+'rcshowhidepatr' => '$1 úpravy strážených stránok',
+'rcshowhidemine' => '$1 moje úpravy',
+'rclinks' => 'Zobraz posledných $1 úprav v posledných $2 dňoch<br />$3',
+'diff' => 'rozdiel',
+'hist' => 'história',
+'hide' => 'skryť',
+'show' => 'zobraz',
+'minoreditletter' => 'D',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[sledujúcich redaktorov: $1]',
+'rc_categories' => 'Obmedziť na kategórie (oddeľte "|")',
+'rc_categories_any' => 'akékoľvek',
+'upload' => 'Nahranie súboru',
+'uploadbtn' => 'Nahrať súbor',
+'reupload' => 'Zopakovať nahranie',
+'reuploaddesc' => 'Späť k formuláru na nahranie.',
+'uploadnologin' => 'Nie ste prihlásený',
+'uploadnologintext' => 'Musíte byť [[Special:Userlogin|prihlásený/á]], aby ste mohli nahrávať súbory.',
+'upload_directory_read_only'=> 'Nie je možné zapisovať webovým servrom do adresára pre nahrávanie ($1).',
+'uploaderror' => 'Chyba pri nahrávaní',
+'uploadtext' => 'Tento formulár použite na nahrávanie súborov, na zobrazenie alebo hľadanie už nahraných súborov choďte na [[Special:Imagelist|zoznam nahraných súborov]], nahrávania a mazania sa tiež zaznamenávajú v [[Special:Log/upload|zázname nahrávaní]].
+
+Na začlenenie obrázku do stránky použite odkaz v tvare
+
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Súbor.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Súbor.png|alternatívny text]]</nowiki>\'\'\'
+alebo pre priamy odkaz na súbor
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Súbor.ogg]]</nowiki>\'\'\'',
+'uploadlog' => 'Záznam nahrávaní',
+'uploadlogpage' => 'Záznam nahrávaní',
+'uploadlogpagetext' => 'Nižšie je zoznam nedávno nahraných súborov.
+Všetky uvedené časy sú časy na serveri (UTC).',
+'filename' => 'Meno súboru',
+'filedesc' => 'Opis súboru',
+'fileuploadsummary' => 'Zhrnutie:',
+'filestatus' => 'Stav autorských práv',
+'filesource' => 'Zdroj',
+'copyrightpage' => 'Project:Autorské práva',
+'copyrightpagename' => 'autorské práva {{GRAMMAR:genitív|{{SITENAME}}}}',
+'uploadedfiles' => 'Nahrané súbory',
+'ignorewarning' => 'Ignorovať varovanie a súbor napriek tomu uložiť.',
+'ignorewarnings' => 'Ignorovať všetky varovania',
+'minlength' => 'Názvy obrázkov musia obsahovať najmenej tri písmená.',
+'illegalfilename' => 'Názov súboru "$1" obsahuje znaky, ktoré nie sú povolené v názvoch stránok. Prosím premenujte súbor a skúste ho nahrať znovu.',
+'badfilename' => 'Meno obrázka bolo zmenené na "$1".',
+'badfiletype' => '".$1" nie je odporúčaný formát obrázkového súboru.',
+'largefile' => 'Odporúčame, aby obrázky neprekročili veľkosť $1 bajtov, veľkosť tohto súboru je $2 bajtov',
+'largefileserver' => 'Tento súbor je väčší ako je možné nahrať na server (z dôvodu obmedzenia veľkosti súboru v konfigurácii servera).',
+'emptyfile' => 'Zdá sa, že súbor, ktorý ste nahrali je prázdny. Mohlo sa stať, že ste urobili v názve súboru preklep. Prosím, skontrolujte, či skutočne chcete nahrať tento súbor.',
+'fileexists' => 'Súbor s týmto názvom už existuje, prosím skontrolujte $1 ak nie ste si istý, či ho chcete zmeniť.',
+'fileexists-forbidden' => 'Súbor s týmto názvom už existuje; choďte prosím späť a nahrajte tento súbor pod iným názvom. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Súbor s týmto názvom už existuje v zdieľanom úložisku súborov; choďte prosím späť a nahrajte tento súbor pod iným názvom. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Nahranie bolo úspešné',
+'fileuploaded' => 'Súbor "$1" bol úspešne nahraný.
+Nasledujte tento odkaz ($2) na stránku, na ktorej zadáte informácie na opis súboru, napríklad odkiaľ pochádza, kedy a kým bol vytvorený a všetko ostatné, čo o ňom prípadne viete. Ak je nahraný súbor obrázok, možno ho takto vložiť do stránky: <tt><nowiki>[[{{ns:Image}}:$1|thumb|Opis]]</nowiki></tt>',
+'uploadwarning' => 'Varovanie pri nahrávaní',
+'savefile' => 'Ulož súbor',
+'uploadedimage' => 'nahraný „[[$1]]“',
+'uploaddisabled' => 'Prepáčte, nahrávanie je vypnuté.',
+'uploaddisabledtext' => 'Nahrávanie súborov na túto wiki je vypnuté.',
+'uploadscripted' => 'Tento súbor obsahuje kód HTML alebo skript, ktorý može byť chybne interpretovaný prehliadačom.',
+'uploadcorrupt' => 'Tento súbor je závadný alebo má nesprávnu príponu. Skontrolujte súbor a nahrajte ho znova.',
+'uploadvirus' => 'Súbor obsahuje vírus! Detaily: $1',
+'sourcefilename' => 'Názov zdrojového súboru',
+'destfilename' => 'Názov cieľového súboru',
+'watchthisupload' => 'Sleduj túto stránku',
+'filewasdeleted' => 'Súbor s týmto názvom bol už nahraný a následne zmazaný. Mali by ste skontrolovať $1 predtým, ako budete pokračovať na opätovné nahranie.',
+'upload-proto-error' => 'Nesprávny protokol',
+'upload-proto-error-text'=> 'Vzdialené nahrávanie vyžaduje, aby URL začínali <code>http://</code> alebo <code>ftp://</code>.',
+'upload-file-error' => 'Vnútorná chyba',
+'upload-file-error-text'=> 'Vyskytla sa vnútorná chyba pri pokuse vytvoriť dočasný súbor na serveri. Prosím, kontaktujte správcu systému.',
+'upload-misc-error' => 'Neznáma chyba pri nahrávaní',
+'upload-misc-error-text'=> 'Počas nahrávania sa vyskytla neznáma chyba. Prosím, overte, že URL je platný a dostupný a skúste znova. Ak problém pretrváva, kontaktujte správcu systému.',
+'upload-curl-error6' => 'Nedostupný URL',
+'upload-curl-error6-text'=> 'Poskytnutý URL nebol dostupný. Prosím, skontrolujte znova, že URL je správny a lokalita je dostupná.',
+'upload-curl-error28' => 'Vypršal čas vyhradený pre nahrávanie',
+'upload-curl-error28-text'=> 'Lokalite trvala odpoveď príliš dlho. Prosím, skontrolujte, či je lokalita dopstupná, chvíľu počkajte a skúste znova. Možno je potrebné skúsiť nahrávanie v čase, kedy je lokalita menej zaťažená.',
+'license' => 'Licencovanie',
+'nolicense' => 'Nič nebolo vybrané',
+'upload_source_url' => ' (platný, verejne prístupný URL)',
+'upload_source_file' => ' (súbor na Vašom počítači)',
+'imagelist' => 'Zoznam nahraných obrázkov',
+'imagelisttext' => 'Tu je zoznam $1 obrázkov zoradený $2.',
+'imagelistforuser' => 'Zobrazuje iba obrázky nahrané redaktorom $1.',
+'getimagelist' => 'sťahujem zoznam nahraných obrázkov',
+'ilsubmit' => 'Vyhľadávanie',
+'showlast' => 'Zobraz posledných $1 obrázkov zoradených $2.',
+'byname' => 'podľa mena',
+'bydate' => 'podľa dátumu',
+'bysize' => 'podľa veľkosti',
+'imgdelete' => 'zmazať',
+'imgdesc' => 'opis',
+'imgfile' => 'súbor',
+'imglegend' => 'Vysvetlivky: (opis) = zobraz/uprav opis obrázku.',
+'imghistory' => 'História súboru',
+'revertimg' => 'obnov',
+'deleteimg' => 'zmazať',
+'deleteimgcompletely' => 'Vymaž všetky verzie',
+'imghistlegend' => 'Vysvetlivky: (aktuálna) = toto je aktuálny obrázok, (zmazať) = zmaž
+túto starú verziu, (pôvodná) = vráť sa k tejto starej verzii.
+<br /><i>Kliknite na dátum, aby sa zobrazil obrázok nahraný v ten deň</i>.',
+'imagelinks' => 'Odkazy na obrázok',
+'linkstoimage' => 'Na tento obrázok odkazujú nasledujúce stránky:',
+'nolinkstoimage' => 'Žiadne stránky neobsahujú odkazy na tento obrázok.',
+'sharedupload' => 'Toto je zdieľaný súbor a je možné ho používať na iných projektoch.',
+'shareduploadwiki' => 'Ďalšie informácie pozrite na $1.',
+'shareduploadwiki-linktext'=> 'stránka opisu súboru',
+'noimage' => 'Súbor s takým menom neexistuje, môžete ho $1',
+'noimage-linktext' => 'nahrať',
+'uploadnewversion-linktext'=> 'Nahrajte novú verziu tohto súboru.',
+'imagelist_date' => 'Dátum',
+'imagelist_name' => 'Názov',
+'imagelist_user' => 'Užívateľ',
+'imagelist_size' => 'Veľkosť (v bajtoch)',
+'imagelist_description' => 'Popis',
+'imagelist_search_for' => 'Hľadať názov obrázka:',
+'mimesearch' => 'MIME vyhľadávanie',
+'mimetype' => 'MIME typ:',
+'download' => 'download',
+'unwatchedpages' => 'Nesledované stránky',
+'listredirects' => 'Zoznam presmerovaní',
+'unusedtemplates' => 'Nepoužité šablóny',
+'unusedtemplatestext' => 'Táto stránka obsahuje zoznam všetkých stránok v mennom prisetore Šablóna:, ktoré nie sú vložené v žiadnej inej stránke. Pred zmazaním nezabudnite skontrolovať ostatné odkazy!',
+'unusedtemplateswlh' => 'iné odkazy',
+'randomredirect' => 'Náhodná presmerovacia stránka',
+'statistics' => 'Štatistiky',
+'sitestats' => 'Štatistika webu',
+'userstats' => 'Štatistika k redaktorom',
+'sitestatstext' => '{{SITENAME}} momentálne má \'\'\'$2\'\'\' stránok.
+Do toho sa nezapočítavajú presmerovania, diskusné stránky, popisné stránky obrázkov, stránky používateľských profilov, šablóny, stránky Pomocníka, portály, stránky bez odkazov na iné stránky a stránky o {{GRAMMAR:lokál|{{SITENAME}}}}.
+Vrátane týchto máme spolu \'\'\'$1\'\'\' stránok.
+
+Celkovo bolo nahraných \'\'\'$8\'\'\' súborov.
+
+Celkovo boli stránky navštívené \'\'\'$3\'\'\'-krát a upravené \'\'\'$4\'\'\'-krát. To znamená, že pripadá priemerne \'\'\'$5\'\'\' úprav na každú stránku a \'\'\'$6\'\'\' návštev na každú úpravu (od posledného vylepšenia (upgrade) softvéru 20. júla 2002).
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue Dĺžka frontu úloh] je momentálne \'\'\'$7\'\'\'.',
+'userstatstext' => 'Celkovo je \'\'\'$1\'\'\' zaregistrovaných redaktorov,
+z čoho \'\'\'$2\'\'\' (alebo \'\'\'$4%\'\'\') sú administrátormi (pozri $5).',
+'statistics-mostpopular'=> 'Najčastejšie prezerané stránky',
+'disambiguations' => 'Stránky na rozlíšenie viacerých významov',
+'disambiguationspage' => 'Šablóna:Rozlišovacia stránka',
+'disambiguationstext' => 'Tieto stránky obsahujú odkazy na <i>stránku na rozlíšenie viacerých významov</i>. Namiesto toho by mali obsahovať odkazy na stránku s príslušnou témou. <br>Stránka sa považuje za stránku na rozlíšenie viacerých významov, ak $1 na ňu obsahuje odkaz.<br>Odkazy z iných menných priestorov tu <i>nie</i> sú uvedené.',
+'doubleredirects' => 'Dvojité presmerovania',
+'doubleredirectstext' => 'Každý riadok obsahuje odkaz na prvé a druhé presmerovanie a tiež prvý riadok z textu na ktorý odkazuje druhé presmerovanie, ktoré zvyčajne odkazuje na "skutočný" cieľ, na ktorý má odkazovať prvé presmerovanie.',
+'brokenredirects' => 'Pokazené presmerovania',
+'brokenredirectstext' => 'Tieto presmerovania odkazujú na neexistujúcu stránku.',
+'nbytes' => '$1 {{PLURAL:$1|bajt|bajty|bajtov}}',
+'ncategories' => '$1 {{PLURAL:$1|kategória|kategórie|kategórií}}',
+'nlinks' => '$1 {{PLURAL:$1|odkaz|odkazy|odkazov}}',
+'nmembers' => '$1 {{PLURAL:$1|člen|členovia|členov}}',
+'nrevisions' => '$1 {{PLURAL:$1|revízia|revízie|revízií}}',
+'nviews' => '$1 {{PLURAL:$1|návšteva|návštevy|návštev}}',
+'lonelypages' => 'Opustené stránky',
+'lonelypagestext' => 'Na nasledujúce stránky neodkazujú žiadne iné stránky z tejto wiki.',
+'uncategorizedpages' => 'Nekategorizované stránky',
+'uncategorizedcategories'=> 'Nekategorizované kategórie',
+'uncategorizedimages' => 'Nekategorizované obrázky',
+'unusedcategories' => 'Nepoužité kategórie',
+'unusedimages' => 'Opustené obrázky',
+'popularpages' => 'Populárne stránky',
+'wantedcategories' => 'Žiadané kategórie',
+'wantedpages' => 'Žiadané stránky',
+'mostlinked' => 'Najčastejšie odkazované stránky',
+'mostlinkedcategories' => 'Najčastejšie odkazované kategórie',
+'mostcategories' => 'Stránky s najväčším počtom kategórií',
+'mostimages' => 'Najčastejšie odkazované obrázky',
+'mostrevisions' => 'Stránky s najväčším počtom revízií',
+'allpages' => 'Všetky stránky',
+'prefixindex' => 'Index prefixu',
+'randompage' => 'Náhodná stránka',
+'shortpages' => 'Krátke stránky',
+'longpages' => 'Dlhé stránky',
+'deadendpages' => 'Slepé stránky',
+'deadendpagestext' => 'Nasledujúce stránky neodkazujú na žiadne iné stránky z tejto wiki.',
+'listusers' => 'Zoznam redaktorov',
+'specialpages' => 'Špeciálne stránky',
+'spheading' => 'Špeciálne stránky pre všetkých redaktorov',
+'restrictedpheading' => 'Obmedzené špeciálne stránky',
+'recentchangeslinked' => 'Súvisiace úpravy',
+'rclsub' => '(na stránky, na ktoré odkazuje "$1")',
+'newpages' => 'Nové stránky',
+'newpages-username' => 'Meno používateľa:',
+'ancientpages' => 'Najdávnejšie upravované stránky',
+'intl' => 'Mezijazykové odkazy',
+'move' => 'Presuň',
+'movethispage' => 'Presuň túto stránku',
+'unusedimagestext' => '<p>Prosím, uvedomte si, že iné web stránky môžu odkazovať na tento obrázok priamo URL adresou a tak tu môžu byť uvedené napriek tomu, že ich externé stránky používajú.</p>',
+'unusedcategoriestext' => 'Nasledovné stránky kategórií existujú napriek tomu, že ich nepoužíva žiadna iná stránka ani kategória.',
+'booksources' => 'Knižné zdroje',
+'categoriespagetext' => 'Nasledujúce kategórie existujú vo wiki.',
+'data' => 'Dáta',
+'userrights' => 'Spravovanie redaktorských práv',
+'groups' => 'Skupiny redaktorov',
+'booksourcetext' => 'Nižšie je uvedený zoznam odkazov k iným web stránkam, ktoré predávajú nové alebo použité knihy a prípadne majú ďalšie informácie o knihách, ktoré hľadáte. {{SITENAME}} nie je so žiadnym z týchto predajcov v obchodnom spojení a tento zoznam nemožno chápať ako ich podporu.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 do $2',
+'version' => 'Zobraz verziu MediaWiki',
+'log' => 'Záznamy',
+'alllogstext' => 'Kombinované zobrazenie nahrávaní, mazaní, zamknutí, blokovaní a akcií sysopa.
+Môžete zmenšiť rozsah, ak zvolíte typ záznamu, meno redaktora alebo dotyčnú stránku.',
+'logempty' => 'V zázname neboli nájdené zodpovedajúce položky.',
+'nextpage' => 'Ďalšia stránka ($1)',
+'allpagesfrom' => 'Zobraz stránky od:',
+'allarticles' => 'Všetky stránky',
+'allinnamespace' => 'Všetky stránky (menný priestor $1)',
+'allnotinnamespace' => 'Všetky stránky (nie z menného priestoru $1)',
+'allpagesprev' => 'Predchádzajúci',
+'allpagesnext' => 'Ďalší',
+'allpagessubmit' => 'Choď',
+'allpagesprefix' => 'Zobraz stránky s predponou:',
+'allpagesbadtitle' => 'Zadaný názov stránky je neplatný alebo mal medzijazykový alebo interwiki prefix. Môže obsahovať jeden alebo viac znakov, ktoré nie je možné použiť v názve stránky.',
+'listusersfrom' => 'Zobraziť používateľov počnúc:',
+'mailnologin' => 'Žiadna adresa na zaslanie',
+'mailnologintext' => 'Musíte byť [[Special:Userlogin|prihlásený]] a mať platnú e-mailovú adresu vo vašich [[Special:Preferences|nastaveniach]], aby ste mohli iným redaktorom posielať e-maily.',
+'emailuser' => 'E-mail tomuto redaktorovi',
+'emailpage' => 'E-mail redaktorovi',
+'emailpagetext' => 'Ak tento redaktor zadal platnú e-mailovú adresu vo svojich nastaveniach,
+môžete mu pomocou dole uvedeného formulára poslať e-mail.
+E-mailová adresa, ktorú ste zadali vo vašich nastaveniach sa zobrazí
+ako adresa odosielateľa e-mailu, aby bol príjemca schopný vám
+odpovedať.',
+'usermailererror' => 'Emailový program vrátil chybu:',
+'defemailsubject' => 'email {{GRAMMAR:genitív|{{SITENAME}}}}',
+'noemailtitle' => 'Chýba e-mailová adresa',
+'noemailtext' => 'Tento redaktor nešpecifikoval platnú e-mailovú adresu
+alebo sa rozhodol, že nebude prijímať e-maily od druhých redaktorov.',
+'emailfrom' => 'Odosielateľ',
+'emailto' => 'Príjemca',
+'emailsubject' => 'Vec',
+'emailmessage' => 'Správa',
+'emailsend' => 'Odoslať',
+'emailccme' => 'Pošli mi emailom kópiu mojej správy.',
+'emailccsubject' => 'Kópia správy pre $1: $2',
+'emailsent' => 'E-mail bol odoslaný',
+'emailsenttext' => 'Vaša e-mailová správa bola odoslaná.',
+'watchlist' => 'Sledované stránky',
+'watchlistfor' => '(používateľa \'\'\'$1\'\'\')',
+'nowatchlist' => 'V zozname sledovaných stránok nemáte žiadne položky.',
+'watchlistanontext' => 'Prosím $1 pre prezeranie alebo úpravu Vášho zoznamu sledovaných stránok.',
+'watchlistcount' => '\'\'\'Na zozname sledovaných máte $1 položiek (vrátane diskusných stránok).\'\'\'',
+'clearwatchlist' => 'Vyčistiť zoznam sledovaných',
+'watchlistcleartext' => 'Určite ich chcete odstrániť?',
+'watchlistclearbutton' => 'Vyčistiť zoznam sledovaných',
+'watchlistcleardone' => 'Váš zoznam sledovaných bol vyčistený. $1 položiek bolo odstránených.',
+'watchnologin' => 'Nie ste prihlásený/á',
+'watchnologintext' => 'Musíte byť [[Special:Userlogin|prihlásený/á]], aby ste mohli modifikovať vaše sledované stránky.',
+'addedwatch' => 'Pridaná do zoznamu sledovaných stránok',
+'addedwatchtext' => 'Stránka [[$1]] bola pridaná do [[Special:Watchlist|sledovaných stránok]]. Budú tam uvedené ďalšie úpravy tejto stránky a jej diskusie a stránka bude zobrazená \'\'\'tučne\'\'\' v [[Special:Recentchanges|zozname posledných úprav]], aby ste ju ľahšie našli.
+
+Ak budete chcieť neskôr stránku odstrániť zo sledovaných stránok, kliknite na "nesleduj" v horných záložkách.',
+'removedwatch' => 'Odstránená zo zoznamu sledovaných stránok',
+'removedwatchtext' => 'Stránka "$1" bol odstránená z vášho zoznamu sledovaných stránok.',
+'watch' => 'Sleduj',
+'watchthispage' => 'Sleduj túto stránku',
+'unwatch' => 'Nesleduj',
+'unwatchthispage' => 'Nesleduj túto stránku',
+'notanarticle' => 'Toto nie je stránka',
+'watchnochange' => 'V rámci zobrazeného času nebola upravená žiadna z Vašich sledovaných stránok.',
+'watchdetails' => '($1 sledovaných stránok, nepočítajúc stránky diskusie;
+$2 úprav stránok spolu od ukončenia;
+$3...
+[[Special:Watchlist/edit|zobraz a upravuj úplný zoznam]].)',
+'wlheader-enotif' => '* Upozorňovanie e-mailom je zapnuté.',
+'wlheader-showupdated' => '* Stránky, ktoré boli zmené od vašej poslednej návštevy sú zobrazené \'\'\'tučne\'\'\'.',
+'watchmethod-recent' => 'kontrolujem posledné úpravy sledovaných stránok',
+'watchmethod-list' => 'kontrolujem sledované stránky na posledné úpravy',
+'removechecked' => 'Odstráň vybrané položky zo zoznamu sledovaných stránok',
+'watchlistcontains' => 'Váš zoznam sledovaných stránok obsahuje $1 položiek.',
+'watcheditlist' => 'Tu je abecedný zoznam vašich
+sledovaných stránok. Označte stránky, ktoré chcete odstrániť a kliknite na tlačidlo
+\'Odstráň vybrané\'
+na spodnej časti obrazovky (odstránie stránky v hlavnom mennom priestore tiež odstráni príslušnú diskusnú stránku a naopak).',
+'removingchecked' => 'Odstraňujem požadované položky zo zoznamu sledovaných stránok...',
+'couldntremove' => 'Nemôžem odstrániť položku \'$1\'...',
+'iteminvalidname' => 'Problém s položkou \'$1\', neplatné meno...',
+'wlnote' => 'Nižšie je posledných $1 zmien v posledných <b>$2</b> hodinách.',
+'wlshowlast' => 'Zobraz posledných $1 hodín $2 dní $3',
+'wlsaved' => 'Toto je uložená verzia zoznamu vašich sledovaných stránok.',
+'wlhideshowown' => '$1 moje úpravy.',
+'wlhideshowbots' => '$1 úprav botov.',
+'wldone' => 'Hotovo.',
+'enotif_mailer' => 'Upozorňovač {{GRAMMAR:genitív|{{SITENAME}}}}',
+'enotif_reset' => 'Vynulovať upozornenia (nastav ich status na "navštívené")',
+'enotif_newpagetext' => 'Toto je nová stránka.',
+'changed' => 'zmene',
+'created' => 'vytvorení',
+'enotif_subject' => '{{SITENAME}} - stránka $PAGETITLE bola $CHANGEDORCREATED $PAGEEDITOR',
+'enotif_lastvisited' => 'Pozrite $1 pre všetky zmeny od vašej poslednej návštevy.',
+'enotif_body' => 'Drahý $WATCHINGUSERNAME,
+
+na {{GRAMMAR:lokál|{{SITENAME}}}} došlo $PAGEEDITDATE k $CHANGEDORCREATED stránky $PAGETITLE redaktorom $PAGEEDITOR, pozrite si aktuálnu verziu $PAGETITLE_URL .
+
+$NEWPAGE
+
+Zhrnutie: $PAGESUMMARY $PAGEMINOREDIT
+Kontaktujte redaktora:
+mail $PAGEEDITOR_EMAIL
+wiki $PAGEEDITOR_WIKI
+
+Nedostanete ďalšie upozornenia, aj ak bude stránka znovu upravovaná, kým nenavštívíte túto stránku. Možete tiež vynulovať upozornenia pre všetky vaše sledované stránky.
+
+ Váš upozorňovací systém {{GRAMMAR:genitív|{{SITENAME}}}}
+
+--
+Pre zmenu nastavenia vašich sledovaných stránok navštívte
+{{fullurl:Special:Watchlist/edit}}
+
+Návrhy a ďalšia pomoc:
+{{fullurl:Pomoc:Obsah}}',
+'deletepage' => 'Zmazať stránku',
+'confirm' => 'Potvrdiť',
+'excontent' => 'obsah bol: \'$1\'',
+'excontentauthor' => 'obsah bol: \'$1\' (a jediný autor bol \'[[Special:Contributions/$2]]\')',
+'exbeforeblank' => 'obsah pred vyčistením stránky bol: \'$1\'',
+'exblank' => 'stránka bola prázdna',
+'confirmdelete' => 'Potvrdiť zmazanie',
+'deletesub' => '(Mažem "$1")',
+'historywarning' => 'POZOR: Stránka, ktorú chcete zmazať má históriu:',
+'confirmdeletetext' => 'Idete trvalo zmazať z databázy stránku alebo obrázok spolu so všetkými jeho/jej predošlými verziami. Potvrďte, že máte v úmysle tak urobiť, že ste si vedomý následkov, a že to robíte v súlade so [[Project:Zásady a smernice|zásadami a smernicami {{GRAMMAR:genitív|{{SITENAME}}}}]].',
+'actioncomplete' => 'Akcia ukončená',
+'deletedtext' => '"$1" bol zmazaný.
+Na $2 nájdete zoznam posledných zmazaní.',
+'deletedarticle' => '„[[$1]]“ zmazaný',
+'dellogpage' => 'Záznam zmazaní',
+'dellogpagetext' => 'Tu je zoznam posledných zmazaní.
+Všetky zobrazené časy sú časy na serveri (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'záznam zmazaní',
+'reverted' => 'Obnovené na skoršiu verziu',
+'deletecomment' => 'Dôvod na zmazanie',
+'imagereverted' => 'Obnovenie skoršej verzie bolo úspešné.',
+'rollback' => 'Rollback úprav',
+'rollback_short' => 'Rollback',
+'rollbacklink' => 'rollback',
+'rollbackfailed' => 'Rollback neúspešný',
+'cantrollback' => 'Nemôžem úpravu vrátiť späť, posledný autor je jediný autor tejto stránky.',
+'alreadyrolled' => 'Nemôžem vrátiť späť poslednú úpravu [[$1]] od [[User:$2|$2]] ([[User talk:$2|Diskusia]]); niekto iný buď upravoval stránku, alebo už vrátil späť.
+
+Autorom poslednej úpravy je [[User:$3|$3]] ([[User talk:$3|Diskusia]]).',
+'editcomment' => 'Komentár k úprave bol: "<i>$1</i>".',
+'revertpage' => 'Posledné úpravy používateľa [[Special:Contributions/$2|$2]] ([[User_talk:$2|diskusia]]) vrátené; bola obnovená posledná úprava $1',
+'sessionfailure' => 'Zdá sa, že je problém s vašou prihlasovacou reláciou;
+táto akcia bola zrušená ako prevencia proti zneužitiu relácie (session).
+Prosím, stlačte "naspäť", obnovte stránku, z ktorej ste sa sem dostali, a skúste to znova.',
+'protectlogpage' => 'Záznam_zamknutí',
+'protectlogtext' => 'Nižšie je zoznam zamknutí/odomknutí stránok.
+Pre dodatočné informácie pozrite [[Project:Zamknutá stránka]].',
+'protectedarticle' => 'zamyká "[[$1]]"',
+'unprotectedarticle' => 'odomyká "[[$1]]"',
+'protectsub' => '(Zamykám "$1")',
+'confirmprotecttext' => 'Skutočne chcete zamknúť túto stránku?',
+'confirmprotect' => 'Potvrďte zamknutie',
+'protectmoveonly' => 'Zamkni iba presuny stránky',
+'protectcomment' => 'Dôvod zamknutia',
+'unprotectsub' => '(Odomykám "$1")',
+'confirmunprotecttext' => 'Skutočne chcete odomknúť túto stránku?',
+'confirmunprotect' => 'Potvrďte odomknutie',
+'unprotectcomment' => 'Dôvod odomknutia',
+'protect-unchain' => 'Odomknúť povolenia pre presun',
+'protect-text' => 'Úroveň ochrany stránky [[$1]] si môžete pozrieť tu.
+Uistite sa prosím, že dodržiavate [[Project:Chránená stránka|zásady projektu]].',
+'protect-viewtext' => 'Váš účet nemá povolenie meniť úrovne ochrany stránky. Tu sú aktuálne nastavenia stránky [[$1]]:',
+'protect-default' => '(predvolené)',
+'protect-level-autoconfirmed'=> 'Zablokuj neregistrovaných používateľov',
+'protect-level-sysop' => 'Len pre správcov',
+'restriction-edit' => 'Úprava',
+'restriction-move' => 'Presun',
+'undelete' => 'Obnov zmazanú stránku',
+'undeletepage' => 'Zobraz a obnov zmazané stránky',
+'viewdeletedpage' => 'Zobraz zmazané stránky',
+'undeletepagetext' => 'Tieto stránky boli zmazané, ale sú stále v archíve a
+môžu byť obnovené. Archív môže byť pravidelne vyprázdnený.',
+'undeleteextrahelp' => 'Ak chcete obnoviť celú stránku, nechajte všetky zaškrtávacie polia nezaškrtnuté a kliknite na \'\'\'\'\'Obnov!\'\'\'\'\'.
+Ak chcete vykonať selektívnu obnovu, zašktrnite polia zodpovedajúce revíziám, ktoré sa majú obnoviť a kliknite na \'\'\'\'\'Obnov\'\'\'\'\'.
+Kliknutie na \'\'\'\'\'Reset\'\'\'\'\' vyčistí pole s komentárom a všetky zaškrtávacie polia.',
+'undeletearticle' => 'Obnov zmazanú stránku',
+'undeleterevisions' => '$1 {{PLURAL:verzia je archivovaná|verzie sú archivované|verzií je archivovaných}}',
+'undeletehistory' => 'Ak obnovíte túto stránku, obnovia sa aj všetky predchádzajúce verzie do zoznamu predchádzajúcich verzií.
+Ak bola od zmazania vytvorená nová stránka s rovnakým názvom, zobrazia sa
+obnovené verzie ako posledné úpravy novej stránky a aktuálna verzia novej stránky
+nebude automaticky nahradená.',
+'undeletehistorynoadmin'=> 'Táto stránka bola zmazaná. Dôvod zmazania je zobrazený dolu v zhrnutí spolu s podrobnosťami o používateľoch, ktorí túto stránku upravovali pred zmazaním. Samotný text týchto zmazaných revízií je prístupný iba správcom.',
+'undeleterevision' => 'Zmazaná verzia zo dňa a času $1',
+'undeleterevision-missing'=> 'Neplatná alebo chýbajúca revízia. Zrejme ste použili zlý odkaz alebo revízia bola obnovená alebo odstránená z histórie.',
+'undeletebtn' => 'Obnov!',
+'undeletereset' => 'Reset',
+'undeletecomment' => 'Komentár:',
+'undeletedarticle' => 'obnovený „[[$1]]“',
+'undeletedrevisions' => '$1 verzií obnovených',
+'undeletedrevisions-files'=> '$1 revízií a $2 súbor(ov) obnovených',
+'undeletedfiles' => '$1 súbor(ov) obnovený(ch)',
+'cannotundelete' => 'Obnovenie sa nepodarilo; pravdepodobne niekto iný obnovil stránku skôr ako Vy.',
+'undeletedpage' => '<big>\'\'\'$1 bol obnovený\'\'\'</big>
+
+Zoznam posledných mazaní a obnovení nájdete v [[Special:Log/delete|Zázname mazaní]].',
+'namespace' => 'Menný priestor:',
+'invert' => 'Invertovať výber',
+'contributions' => 'Príspevky redaktora',
+'mycontris' => 'Moje príspevky',
+'contribsub' => 'Pre $1',
+'nocontribs' => 'Neboli nájdené úpravy, ktoré by zodpovedali týmto kritériám.',
+'ucnote' => 'Nižšie je posledných <b>$1</b> úprav od tohto redaktora uskutočnených počas posledných <b>$2</b> dní.',
+'uclinks' => 'Zobraz posledných $1 úprav; zobraz posledných $2 dní.',
+'uctop' => '(posledná úprava)',
+'newbies' => 'začiatočníci',
+'sp-newimages-showfrom' => 'Zobraz nové obrázky počínajúc $1',
+'sp-contributions-newest'=> 'Najnovšie',
+'sp-contributions-oldest'=> 'Najstaršie',
+'sp-contributions-newer'=> 'Novších $1',
+'sp-contributions-older'=> 'Starších $1',
+'sp-contributions-newbies-sub'=> 'Pre nováčikov',
+'whatlinkshere' => 'Odkazy na túto stránku',
+'whatlinkshere-barrow' => '&lt;',
+'notargettitle' => 'Nebol zadaný cieľ',
+'notargettext' => 'Nezadali ste cieľovú stránku alebo redaktora,
+na ktorý/-ého chcete aplikovať túto funkciu.',
+'linklistsub' => '(Zoznam odkazov)',
+'linkshere' => 'Nasledujúce stránky odkazujú na \'\'\'[[:$1]]\'\'\':',
+'nolinkshere' => 'Žiadne stránky neodkazujú na \'\'\'[[:$1]]\'\'\'.',
+'isredirect' => 'presmerovacia stránka',
+'istemplate' => 'použitá',
+'blockip' => 'Zablokovať redaktora',
+'blockiptext' => 'Použite dolu uvedený formulár na zablokovanie možnosti zápisov uskutočnených z IP adresy alebo od redaktora.
+Mali by ste to urobiť len na zabránenie vandalizmu a v súlade so [[Project:Zásady a smernice|zásadami a smernicami {{GRAMMAR:genitív|{{SITENAME}}}}]].
+Nižšie uveďte konkrétny dôvod (napríklad uveďte konkrétne stránky, ktoré padli za obeť vandalizmu).',
+'ipaddress' => 'IP adresa/meno redaktora',
+'ipadressorusername' => 'IP adresa/meno redaktora',
+'ipbexpiry' => 'Ukončenie',
+'ipbreason' => 'Dôvod',
+'ipbanononly' => 'Blokovať iba anonymných používateľov.',
+'ipbcreateaccount' => 'Zabráň vytváraniu účtov',
+'ipbenableautoblock' => 'Automaticky blokovať poslednú IP adresu, ktorú tento používateľ použil, a všetky ďalšie adresy, z ktorých sa pokúsi upravovať.',
+'ipbsubmit' => 'Zablokovať tohto redaktora',
+'ipbother' => 'Iný čas',
+'ipboptions' => '2 hodiny:2 hours,1 deň:1 day,3 dni:3 days,1 týždeň:1 week,2 týždne:2 weeks,1 mesiac:1 month,3 mesiace:3 months,6 mesiacov:6 months,1 rok:1 year,na neurčito:infinite',
+'ipbotheroption' => 'iný čas',
+'badipaddress' => 'IP adresa má nesprávny formát.',
+'blockipsuccesssub' => 'Zablokovanie bolo úspešné',
+'blockipsuccesstext' => '"$1" bol/a zablokovaný/á.<br />
+[[Special:Ipblocklist|IP block list]] obsahuje zoznam blokovaní.',
+'unblockip' => 'Odblokovať redaktora',
+'unblockiptext' => 'Použite nižšie uvedený formulár na obnovenie možnosti zápisov
+z doteraz zablokovanej IP adresy alebo od redaktora.',
+'ipusubmit' => 'Odblokovať túto adresu',
+'unblocked' => '[[User:$1|$1]] bol odblokovaný',
+'ipblocklist' => 'Zablokovaní/é redaktori/IP adresy',
+'blocklistline' => '$1, $2 zablokoval $3 (ukončenie $4)',
+'infiniteblock' => 'na neurčito',
+'expiringblock' => 'ukončenie $1',
+'anononlyblock' => 'iba anon.',
+'noautoblockblock' => 'automatické blokovanie vypnuté',
+'createaccountblock' => 'tvorba účtov bola zablokovaná',
+'ipblocklistempty' => 'Zoznam blokovaných je prázdny.',
+'blocklink' => 'zablokovať',
+'unblocklink' => 'odblokuj',
+'contribslink' => 'príspevky',
+'autoblocker' => 'Ste zablokovaný, pretože zdieľate IP adresu s "$1". Dôvod "$2".',
+'blocklogpage' => 'Záznam_blokovaní',
+'blocklogentry' => 'zablokoval/a "[[$1]]" s časom ukončenia $2',
+'blocklogtext' => 'Toto je zoznam blokovaní a odblokovaní redaktorov. Automaticky
+blokované IP adresy nie sú zahrnuté. Viď zoznam
+[[Special:Ipblocklist|aktuálnych zákazov a blokovaní]].',
+'unblocklogentry' => 'odblokoval/a "$1"',
+'range_block_disabled' => 'Možnosť správcov vytvárať rozsah zablokovaní je vypnutá.',
+'ipb_expiry_invalid' => 'Neplatný čas ukončenia.',
+'ipb_already_blocked' => '"$1" je už zablokovaný',
+'ip_range_invalid' => 'Neplatný IP rozsah.',
+'proxyblocker' => 'Blokovač proxy',
+'ipb_cant_unblock' => 'Chyba: ID bloku $1 nenájdený. Možno už bol odblokovaný.',
+'proxyblockreason' => 'Vaša IP adresa bola zablokovaná, pretože je otvorená proxy. Prosím kontaktujte vášho internetového poskytovateľa alebo technickú podporu a informujte ich o tomto vážnom bezpečnostnom probléme.',
+'proxyblocksuccess' => 'Hotovo.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Vaša IP adresa je vedená ako nezabezpečený proxy server v [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason'=> 'Vaša IP adresa je vedená ako nezabezpečený proxy server v [http://www.sorbs.net SORBS] DNSBL. Nemôžete si vytvoriť účet.',
+'lockdb' => 'Zamknúť databázu',
+'unlockdb' => 'Odomknúť databázu',
+'lockdbtext' => 'Zamknutím databázy sa preruší možnosť všetkých
+redaktorov upravovať stránky, meniť svoje nastavenia, upravovať sledované stránky a
+iné veci vyžadujúce zmeny v databáze.
+Potvrďte, že to naozaj chcete urobiť, a že
+odomknete databázu po ukončení údržby.',
+'unlockdbtext' => 'Odomknutie databázy obnoví schopnosť všetkých
+redaktorov upravovať stránky, meniť svoje nastavenia, upravovať svoj zoznam sledovaných stránok a
+iné veci vyžadujúce zmeny v databáze.
+Potvrďte, že to naozaj chcete urobiť.',
+'lockconfirm' => 'Áno, naozaj chcem zamknúť databázu.',
+'unlockconfirm' => 'Áno, naozaj chcem odomknúť databázu.',
+'lockbtn' => 'Zamknúť databázu',
+'unlockbtn' => 'Odomknúť databázu',
+'locknoconfirm' => 'Neoznačili ste potvrdzovacie pole.',
+'lockdbsuccesssub' => 'Zamknutie databázy úspešné',
+'unlockdbsuccesssub' => 'Databáza bola úspešne odomknutá',
+'lockdbsuccesstext' => 'Databáza bola dočasne zamknutá.',
+'unlockdbsuccesstext' => 'Databáza {{GRAMMAR:genitív|{{SITENAME}}}} bola odomknutá.',
+'lockfilenotwritable' => 'Súbor, ktorý zamyká databázu nie je zapisovateľný. Aby bolo možné zamknúť či odomknúť databázu, je potrebné, aby doňho mohol web server zapisovať.',
+'databasenotlocked' => 'Databáza nie je zamknutá.',
+'makesysoptitle' => 'Urob z redaktora správcu',
+'makesysoptext' => 'Tento formulár je používaný byrokratmi na zmenu redaktorov na správcov.
+Do poľa napíšte meno redaktora a potvrďte zmenu redaktora na správcu',
+'makesysopname' => 'Meno redaktora:',
+'makesysopsubmit' => 'Urob z tohto redaktora správcu',
+'makesysopok' => '<b>Redaktor "$1" je teraz správcom(sysop)</b>',
+'makesysopfail' => '<b>Redaktor "$1" nemôže byť správcom. (Zadali ste meno správne?)</b>',
+'setbureaucratflag' => 'Nastav príznak byrokrat',
+'rightslog' => 'Záznam užívateľských práv',
+'rightslogtext' => 'Toto je záznam zmien redaktorových práv.',
+'rightslogentry' => 'členstvo v skupine zmenené pre $1 z $2 na $3',
+'rights' => 'Práva:',
+'set_user_rights' => 'Nastav redaktorove práva',
+'user_rights_set' => '<b>Redaktorove práva pre „$1“ aktualizované</b>',
+'set_rights_fail' => '<b>Redaktorove práva pre "$1" nemohli byť nastavené. (zadali ste meno správne?)</b>',
+'makesysop' => 'Urob z redaktora správcu',
+'already_sysop' => 'Tento redaktor už je správca',
+'already_bureaucrat' => 'Tento redaktor už je byrokrat',
+'rightsnone' => '(žiadne)',
+'movepage' => 'Presunúť stránku',
+'movepagetext' => 'Pomocou tohto formulára premenujete stránku a premiestnite všetky jej predchádzajúce verzie pod zadané nové meno.
+Starý názov sa stane presmerovacou stránkou na nový názov.
+Odkazy na starú stránku sa však nezmenia, ubezpečte sa, že ste skontrolovali
+výskyt dvojitých alebo pokazených presmerovaní.
+Vy ste zodpovedný za to, aby odkazy naďalej ukazovali
+tam, kam majú.
+
+Uvedomte si, že stránka sa \'\'\'nepremiestni\'\'\', ak pod novým názvom
+už stránka existuje. Toto neplatí iba ak je stránka prázdna alebo presmerovacia a nemá
+žiadne predchádzajúce verzie. To znamená, že môžete premenovať stránku späť na názov,
+ktorý mala pred premenovaním, ak ste sa pomýlili, a že nemôžete prepísať
+existujúcu stránku.
+
+<b>POZOR!</b>
+Toto môže byť drastická a nečakaná zmena pre populárnu stránku;
+ubezpečte sa preto, skôr ako budete pokračovať, že chápete
+dôsledky svojho činu.',
+'movepagetalktext' => 'Príslušná diskusná stránka (ak existuje) bude premiestnená spolu so samotnou stránkou; \'\'\'nestane sa tak, iba ak:\'\'\'
+*už existuje Diskusná stránka pod týmto novým menom, alebo
+*nezaškrtnete nižšie sa nachádzajúci textový rámček.
+
+V takých prípadoch budete musieť, ak si to želáte, premiestniť alebo zlúčiť stránku ručne.',
+'movearticle' => 'Presuň stránku',
+'movenologin' => 'Nie ste prihlásený',
+'movenologintext' => 'Musíte byť registrovaný redaktor a [[Special:Userlogin|prihlásený]], aby ste mohli presunúť stránku.',
+'newtitle' => 'Na nový názov',
+'movepagebtn' => 'Presunúť stránku',
+'pagemovedsub' => 'Presun bol úspešný',
+'pagemovedtext' => 'Stránka "[[$1]]" bola presunutá na "[[$2]]".',
+'articleexists' => 'Stránka s týmto názvom už existuje alebo
+vami zadaný názov je neplatný.
+Prosím vyberte si iný názov.',
+'talkexists' => '\'\'\'Samotná stránka bola úspešne premiestnená,
+ale diskusná stránka sa nedala premiestniť,
+pretože už jedna existuje pod zadaným novým názvom.
+Prosím, zlúčte ich ručne.\'\'\'',
+'movedto' => 'presunutý na',
+'movetalk' => 'Premiestniť aj "diskusnú" stránku, ak je to možné.',
+'talkpagemoved' => 'Príslušná diskusná stránka bola tiež premiestnená.',
+'talkpagenotmoved' => 'Príslušná diskusná stránka <strong>nebola</strong> premiestnená.',
+'1movedto2' => '[[$1]] premiestnená na [[$2]]',
+'1movedto2_redir' => '[[$1]] premiestnená na [[$2]] výmenou presmerovania',
+'movelogpage' => 'Záznam presunov',
+'movelogpagetext' => 'Tu je zoznam posledných presunutí.',
+'movereason' => 'Dôvod',
+'revertmove' => 'obnova',
+'delete_and_move' => 'Vymaž a presuň',
+'delete_and_move_text' => '==Je potrebné zmazať stránku==
+
+Cieľová stránka "[[$1]]" už existuje. Chcete ho vymazať a vytvoriť tak priestor pre presun?',
+'delete_and_move_confirm'=> 'Áno, zmaž stránku',
+'delete_and_move_reason'=> 'Vymaž, aby sa umožnil presun',
+'selfmove' => 'Zdrojový a cieľový názov sú rovnaké; nemôžem presunúť stránku na seba samú.',
+'immobile_namespace' => 'Cieľový názov je špeciálneho typu; nemôžem presunúť stránku do tohto menného priestoru.',
+'export' => 'Export stránok',
+'exporttext' => 'Môžete exportovať text a históriu úprav konkrétnej
+stránky alebo množiny stránok do XML; tieto môžu byť potom importované do iného
+wiki používajúceho MediaWiki softvér pomocou stránky Special:Import.
+
+Pre export stránok zadajte názvy do tohto poľa, jeden názov na riadok, a zvoľte, či chcete iba súčasnú verziu s informáciou o poslednej úprave alebo aj všetky staršie verzie s históriou úprav.
+
+V druhom prípade môžete tiež použiť odkaz, napr. [[Special:Export/{{Mediawiki:Mainpage}}]] pre stránku {{Mediawiki:Mainpage}}.',
+'exportcuronly' => 'Zahrň iba aktuálnu verziu, nie kompletnú históriu',
+'exportnohistory' => '----',
+'export-submit' => 'Export',
+'allmessages' => 'Všetky systémové správy',
+'allmessagesname' => 'Názov',
+'allmessagesdefault' => 'štandardný text',
+'allmessagescurrent' => 'aktuálny text',
+'allmessagestext' => 'Toto je zoznam všetkých správ dostupných v mennom priestore MediaWiki.',
+'allmessagesnotsupportedUI'=> 'Special:AllMessages na tejto lokalite (site) nepodporuje jazyk pre vaše rozhranie (\'\'\'$1\'\'\').',
+'allmessagesnotsupportedDB'=> 'Special:AllMessages nie je podporované, pretože je vypnuté wgUseDatabaseMessages.',
+'allmessagesfilter' => 'Filter názvov správ:',
+'allmessagesmodified' => 'Zobraz iba zmenené',
+'thumbnail-more' => 'Zväčšiť',
+'missingimage' => '<b>Chýbajúci obrázok</b><br /><i>$1</i>\n',
+'filemissing' => 'Chýbajúci súbor',
+'thumbnail_error' => 'Chyba pri vytváraní náhľadu: $1',
+'import' => 'Import stránok',
+'importinterwiki' => 'Transwiki import',
+'import-interwiki-text' => 'Zvoľte wiki a názov stránky, ktorá sa má importovať.
+Dátumy revízií a mná redaktorov budú zachované.
+Všetky transwiki importy sa zaznamenávajú v [[Special:Log/import|Zázname importov]].',
+'import-interwiki-history'=> 'Skopírovať všetky historické revízie tejto stránky',
+'import-interwiki-submit'=> 'Importovať',
+'import-interwiki-namespace'=> 'Presunúť stránky do menného priestoru:',
+'importtext' => 'Prosím exportujte súbor zo zdrojov wiki použitím nástroja Special:Export, uložte na váš disk a nahrajte tu.',
+'importstart' => 'Importujú sa stránky...',
+'import-revision-count' => '$1 {{PLURAL:$1|revízia|revízie|revízií}}',
+'importnopages' => 'Žiadne stránky pre import.',
+'importfailed' => 'Chyba pri importe: $1',
+'importunknownsource' => 'Neznámy typ zdroja pre import',
+'importcantopen' => 'Nedal sa otvoriť súbor importu',
+'importbadinterwiki' => 'Zlý interwiki odkaz',
+'importnotext' => 'Prázdny alebo žiadny text',
+'importsuccess' => 'Import úspešný!',
+'importhistoryconflict' => 'Existujú konfliktné histórie revízií (možno už bola táto stránka importovaná)',
+'importnosources' => 'Neboli definované žiadne zdroje pre transwiki import a priame nahranie histórie je vypnuté.',
+'importnofile' => 'Nebol nahraný import súbor.',
+'importuploaderror' => 'Nahrávanie importovaného súboru sa nepodarilo; možno súbor presahuje najväčšiu povolenú veľkosť.',
+'importlogpage' => 'Záznam importov',
+'importlogpagetext' => 'Administratívny import stránok vrátane histórie úprav z iných wiki.',
+'import-logentry-upload'=> 'importovaný $1 pomocou nahrania súboru',
+'import-logentry-upload-detail'=> '$1 {{PLURAL:$1|revízia|revízie|revízií}}',
+'import-logentry-interwiki'=> 'Transwiki import $1 úspešný',
+'import-logentry-interwiki-detail'=> '$1 revízií z $2',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'Hľadaj v tomto wiki [alt-f]',
+'tooltip-minoredit' => 'Označ toto ako drobnú úpravu [alt-i]',
+'tooltip-save' => 'Uloží vaše úpravy [alt-s]',
+'tooltip-preview' => 'Náhľad úprav, prosím použite pred uložením! [alt-p]',
+'tooltip-diff' => 'Ukáž, aké zmeny ste urobili v texte. [alt-v]',
+'tooltip-compareselectedversions'=> 'Zobraz rozdiely medzi dvoma vybranými verziami tejto stránky. [alt-v]',
+'tooltip-watch' => 'Pridaj túto stránku k sledovaným. [alt-w]',
+'monobook.css' => '/* úpravou tohto súboru si prispôsobíte skin monobook pre celú wiki */',
+'nodublincore' => 'Dublin Core RDF metadata sú pre tento server vypnuté.',
+'nocreativecommons' => 'Creative Commons RDF metadata sú pre tento server vypnuté.',
+'notacceptable' => 'Wiki server nedokáže poskytovať dáta vo formáte, v akom ich váš klient vie čítať.',
+'anonymous' => 'Anonymný redaktor/i {{GRAMMAR:genitív|{{SITENAME}}}}',
+'siteuser' => 'Redaktor {{GRAMMAR:genitív|{{SITENAME}}}} $1',
+'lastmodifiedatby' => 'Táto stránka bola naposledy upravovaná $2, $1 redaktorom $3.',
+'and' => 'a',
+'othercontribs' => 'Založené na práci redaktora $1.',
+'others' => 'iné',
+'siteusers' => 'Redaktori {{GRAMMAR:genitív|{{SITENAME}}}} $1',
+'creditspage' => 'Autori stránky',
+'nocredits' => 'Pre túto stránku neexistujú žiadne dostupné ocenenia.',
+'spamprotectiontitle' => 'Filter na ochranu pred spamom',
+'spamprotectiontext' => 'Stránka, ktorú ste chceli uložiť, bola blokovaná filtrom na spam. Pravdepodobne to spôsobil link na externú internetovú lokalitu (site).',
+'spamprotectionmatch' => 'Nasledujúci text aktivoval náš spam filter: $1',
+'subcategorycount' => 'V tejto kategórii {{PLURAL:$1|je jedna podkategória|sú $1 podkategórie|je $1 podkategórií}}.',
+'categoryarticlecount' => 'V tejto kategórii {{PLURAL:$1|je jedna stránka|sú $1 stránky|je $1 stránok}}.',
+'category-media-count' => 'V tejto kategórii {{PLURAL:$1|je jeden súbor|sú $1 súbory|je $1 súborov}}.',
+'listingcontinuesabbrev'=> ' pokrač.',
+'spambot_username' => 'MediaWiki čistenie spamu',
+'spam_reverting' => 'Revertujem na poslednú verziu, ktorá neobsahuje odkazy na $1',
+'spam_blanking' => 'Všetky revízie obsahovali odkaz na $1, odstraňujem obsah',
+'infosubtitle' => 'Informácie o stránke',
+'numedits' => 'Počet úprav (stránka): $1',
+'numtalkedits' => 'Počet úprav (diskusná stránka): $1',
+'numwatchers' => 'Počet zobrazení: $1',
+'numauthors' => 'Počet odlišných autorov (stránka): $1',
+'numtalkauthors' => 'Počet odlišných autorov (diskusná stránka): $1',
+'mw_math_png' => 'Vždy vykresľuj PNG',
+'mw_math_simple' => 'Na jednoduché použi HTML, inak PNG',
+'mw_math_html' => 'Ak sa dá, použi HTML, inak PNG',
+'mw_math_source' => 'Ponechaj TeX (pre textové prehliadače)',
+'mw_math_modern' => 'Odporúčané pre moderné prehliadače',
+'mw_math_mathml' => 'MathML (experimentálne)',
+'markaspatrolleddiff' => 'Označ ako strážený',
+'markaspatrolledtext' => 'Označ túto stránku ako stráženú',
+'markedaspatrolled' => 'Označené ako strážené',
+'markedaspatrolledtext' => 'Vybraná verzia bola označená na stráženie.',
+'rcpatroldisabled' => 'Stráženie posledných zmien bolo vypnuté',
+'rcpatroldisabledtext' => 'Funkcia stráženia posledných zmien je momentálne vypnutá.',
+'markedaspatrollederror'=> 'Nie je možné označiť ako strážený',
+'markedaspatrollederrortext'=> 'Pre označenie ako strážený je potrebné uviesť revíziu, ktorá sa má označiť ako strážená.',
+'monobook.js' => '/* bublinové tipy a prístupové klávesy */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Moja redaktorská stránka\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Stránka redaktora pre ip adresu, ktorú upravujete ako\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Moja diskusná stránka\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskusia o úpravách z tejto ip adresy\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Moje nastavenia\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Zoznam stránok, na ktorých sledujete zmeny.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Zoznam mojich príspevkov\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Odporúčame Vám prihlásiť sa, nie je to však povinné.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Odporúčame Vám prihlásiť sa, nie je to však povinné.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Odhlásenie\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskusia o obsahu stránky\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Môžete upravovať túto stránku. Prosíme, pred uložením použite tlačidlo Zobraziť náhľad.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Pridaj komentár k tejto diskusii.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Táto stránka je zamknutá. Môžete však vidieť jej zdrojový text.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Minulé verzie tejto stránky.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Zamkni túto stránku\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Vymaž túto stránku\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Obnov úpravy tejtoto stránky až po dobu jeho vymazania\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Presuň túto stránku\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Pridať túto stránku do zoznamu sledovaných stránok\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Odstrániť túto stránku zo sledovaných stránok\');
+ ta[\'search\'] = new Array(\'f\',\'Prehľadávanie tejto wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Hlavná stránka\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Navštíviť Hlavnú stránku\');
+ ta[\'n-portal\'] = new Array(\'\',\'O projekte, ako môžete prispieť, kde čo nájsť\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Aktuálne udalosti a ich pozadie\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Zoznam posledných úprav vo wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Zobrazenie náhodnej stránky\');
+ ta[\'n-help\'] = new Array(\'\',\'Pozrieť si pomoc.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Podporte nás\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Zoznam všetkých wiki stránok, ktoré sem odkazujú\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Posledné úpravy v stránkach, ktoré odkazujú na túto stránku\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed pre túto stránku\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed pre túto stránku\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Pozrieť si zoznam príspevkov od tohto redaktora\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Poslať e-mail tomuto redaktorovi\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Nahranie obrázkových alebo multimediálnych súborov\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Zoznam všetkých špeciálnych stránok\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Pozrieť si obsah stránky\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Pozrieť si stránku redaktora\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Pozrieť si stránku médií\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Toto je špeciálna stránka, nemôžete ju upravovať.\');
+ ta[\'ca-nstab-project\'] = new Array(\'c\',\'Pozrieť si stránku projektu\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Pozrieť si stránku obrázku\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Pozrieť si systémovú stránku\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Pozrieť si šablónu\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Pozrieť si stránku Pomocníka\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Pozrieť si stránku s kategóriami\');',
+'deletedrevision' => 'Zmazať staré verzie $1.',
+'previousdiff' => '← Choď na predchádzajúcu verziu',
+'nextdiff' => 'Choď na ďalšiu verziu →',
+'imagemaxsize' => 'Obmedz obrázky na popisnej stránke obrázka na:',
+'thumbsize' => 'Veľkosť náhľadu:',
+'showbigimage' => 'Stiahnuť tento obrázok vo väčšom rozlíšení ($1x$2, $3 KB)',
+'newimages' => 'Galéria nových obrázkov',
+'showhidebots' => '($1 botov)',
+'noimages' => 'Nič na zobrazenie.',
+'specialloguserlabel' => 'Redaktor:',
+'speciallogtitlelabel' => 'Názov:',
+'passwordtooshort' => 'Vaše heslo je príliš krátke. Musí mať dĺžku aspoň $1 znakov.',
+'mediawarning' => '\'\'\'Upozornenie\'\'\': Tento súbor môže obsahovať nebezpečný programový kód, po spustení ktorého by bol váš systém kompromitovaný.
+<hr />',
+'fileinfo' => '$1KB, MIME : <code>$2</code>',
+'metadata' => 'Metadáta',
+'metadata-help' => 'Tento súbor obsahuje ďalšie informácie, pravdepodobne pochádzajúce z digitálneho fotoaparátu či skenera ktorý ho vytvoril alebo digitalizoval. Ak bol súbor zmenený, niektoré podrobnosti sa nemusia plne zhodovať so zmeneným obrázkom.',
+'metadata-expand' => 'Zobraz detaily EXIF',
+'metadata-collapse' => 'Skry detaily EXIF',
+'metadata-fields' => 'Polia EXIF metadát uvedených v tejto správe sa zobrazia na stránke obrázka vtedy, keď je tabuľka metadát zbalená. Ostatné sa štandardne nezobrazia.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+'exif-imagewidth' => 'Šírka',
+'exif-imagelength' => 'Výška',
+'exif-bitspersample' => 'Bitov na zložku',
+'exif-compression' => 'Kompresná schéma',
+'exif-photometricinterpretation'=> 'Pixelové zloženie',
+'exif-orientation' => 'Orientácia',
+'exif-samplesperpixel' => 'Počet zložiek',
+'exif-planarconfiguration'=> 'Rozloženie dát',
+'exif-ycbcrsubsampling' => 'Pomer podvzorkovania Y ku C',
+'exif-ycbcrpositioning' => 'Poloha Y a C',
+'exif-xresolution' => 'Horizontálne rozlíšenie',
+'exif-yresolution' => 'Vertikálne rozlíšenie',
+'exif-resolutionunit' => 'Jednotky horizontálneho a verikálneho rozlíšenia',
+'exif-stripoffsets' => 'Umiestnenie obrazových dát',
+'exif-rowsperstrip' => 'Počet riadkov na pás',
+'exif-stripbytecounts' => 'Bajtov na komprimovaný prúžok',
+'exif-jpeginterchangeformat'=> 'Offset k JPEG SOI',
+'exif-jpeginterchangeformatlength'=> 'Bytov JPEG dát',
+'exif-transferfunction' => 'Prenosová funkcia',
+'exif-whitepoint' => 'Chromaticita bieleho bodu',
+'exif-primarychromaticities'=> 'Chromaticity primárností',
+'exif-ycbcrcoefficients'=> 'Koeficienty transformačnej matice farebného priestoru',
+'exif-referenceblackwhite'=> 'Dvojica bielych a čiernych referenčných hodnôt',
+'exif-datetime' => 'Dátum a čas zmeny súboru',
+'exif-imagedescription' => 'Názov obrázka',
+'exif-make' => 'Výrobca aparátu',
+'exif-model' => 'Model aparátu',
+'exif-software' => 'Použitý softvér',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Držiteľ autorských práv',
+'exif-exifversion' => 'Verzia exif tagu',
+'exif-flashpixversion' => 'Podporovaná verzia Flashpix',
+'exif-colorspace' => 'Farebný priestor',
+'exif-componentsconfiguration'=> 'Význam jednotlivých zložiek',
+'exif-compressedbitsperpixel'=> 'Kompresný režim obrázka',
+'exif-pixelydimension' => 'platná šírka obrázka',
+'exif-pixelxdimension' => 'Platná vyška obrázka',
+'exif-makernote' => 'Poznámky výrobcu',
+'exif-usercomment' => 'Komentáre používateľa',
+'exif-relatedsoundfile' => 'Súvisiaci zvukový súbor',
+'exif-datetimeoriginal' => 'Dátum a čas vytvorenia dát',
+'exif-datetimedigitized'=> 'Dátum a čas digitalizácie',
+'exif-subsectime' => 'Subsekundy DateTime',
+'exif-subsectimeoriginal'=> 'Zlomky sekundy DateTimeOriginal',
+'exif-subsectimedigitized'=> 'Zlomky sekundy DateTimeDigitized',
+'exif-exposuretime' => 'Expozičný čas',
+'exif-exposuretime-format'=> '$1 sekundy ($2)',
+'exif-fnumber' => 'Číslo F',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Expozičný program',
+'exif-spectralsensitivity'=> 'Spektrálna citlivosť',
+'exif-isospeedratings' => 'Rýchlostné ohodnotenie ISO',
+'exif-oecf' => 'Optoelektronický konverzný činiteľ',
+'exif-shutterspeedvalue'=> 'Rýchlosť uzávierky',
+'exif-aperturevalue' => 'Clona',
+'exif-brightnessvalue' => 'Jas',
+'exif-exposurebiasvalue'=> 'Expozičné skreslenie',
+'exif-maxaperturevalue' => 'Maximálna krajinná clona',
+'exif-subjectdistance' => 'Vzdialenosť subjektu',
+'exif-meteringmode' => 'Merací režim',
+'exif-lightsource' => 'Svetelný zdroj',
+'exif-flash' => 'Blesk',
+'exif-focallength' => 'Ohnisková vzdialenosť šošoviek',
+'exif-focallength-format'=> '$1 mm',
+'exif-subjectarea' => 'Oblasť subjektu',
+'exif-flashenergy' => 'Energia blesku',
+'exif-spatialfrequencyresponse'=> 'Priestorová frekvenčná odozva',
+'exif-focalplanexresolution'=> 'Horizontálne rozlíšenie ohniskovej roviny',
+'exif-focalplaneyresolution'=> 'Vertikálne rozlíšenie ohniskovej roviny',
+'exif-focalplaneresolutionunit'=> 'Jednotka rozlíšenia v ohniskovej rovine',
+'exif-subjectlocation' => 'Umiestnenie subjektu',
+'exif-exposureindex' => 'Expozičný index',
+'exif-sensingmethod' => 'Snímacia metóda',
+'exif-filesource' => 'Zdroj súboru',
+'exif-scenetype' => 'Typ scény',
+'exif-cfapattern' => 'Vzor CFA',
+'exif-customrendered' => 'Ručné spracovanie obrazu',
+'exif-exposuremode' => 'Expozičný režim',
+'exif-whitebalance' => 'Vyváženie bielej',
+'exif-digitalzoomratio' => 'Rozsah digitálneho zoomu',
+'exif-focallengthin35mmfilm'=> 'Ohnisková vzdialenosť 35 mm filmu',
+'exif-scenecapturetype' => 'Typ zachytenia scény',
+'exif-gaincontrol' => 'Riadenie scény',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Sýtosť',
+'exif-sharpness' => 'Ostrosť',
+'exif-devicesettingdescription'=> 'Opis nastavení zariadenia',
+'exif-subjectdistancerange'=> 'Rozsah vzdialenosti subjektu',
+'exif-imageuniqueid' => 'Jedinečný ID obrázka',
+'exif-gpsversionid' => 'Verzia GPS tagu',
+'exif-gpslatituderef' => 'Severná alebo južná šírka',
+'exif-gpslatitude' => 'Zemepisná šírka',
+'exif-gpslongituderef' => 'Západná alebo východná dĺžka',
+'exif-gpslongitude' => 'Zemepisná dĺžka',
+'exif-gpsaltituderef' => 'Referencia výšky',
+'exif-gpsaltitude' => 'Výška',
+'exif-gpstimestamp' => 'Čas GPS (atómové hodiny)',
+'exif-gpssatellites' => 'Satelity použité pri meraní',
+'exif-gpsstatus' => 'Stav prijímača',
+'exif-gpsmeasuremode' => 'Režim merania',
+'exif-gpsdop' => 'Presnosť merania',
+'exif-gpsspeedref' => 'Rýchlostná jednotka',
+'exif-gpsspeed' => 'Rýchlosť prijímača GPS',
+'exif-gpstrackref' => 'Referencia pre smer pohybu',
+'exif-gpstrack' => 'Smer pohybu',
+'exif-gpsimgdirectionref'=> 'Referencia pre smer obrázka',
+'exif-gpsimgdirection' => 'Smer obrázka',
+'exif-gpsmapdatum' => 'Použité údaje geodetického prieskumu',
+'exif-gpsdestlatituderef'=> 'Referencia zemepisnej šírky cieľa',
+'exif-gpsdestlatitude' => 'Zemepisná šírka cieľa',
+'exif-gpsdestlongituderef'=> 'Referencia zemepisnej dĺžky cieľa',
+'exif-gpsdestlongitude' => 'Zemepisná dĺžka cieľa',
+'exif-gpsdestbearingref'=> 'Referencia polohy cieľa',
+'exif-gpsdestbearing' => 'Smer k cieľu',
+'exif-gpsdestdistanceref'=> 'Referencia vzdialenosti cieľa',
+'exif-gpsdestdistance' => 'Vzdialenosť k cieľu',
+'exif-gpsprocessingmethod'=> 'Názov GPS metódy spracovania',
+'exif-gpsareainformation'=> 'Názov GPS oblasti',
+'exif-gpsdatestamp' => 'Dátum GPS',
+'exif-gpsdifferential' => 'Diferenciálna korekcia GPS',
+'exif-compression-1' => 'Bez kompresie',
+'exif-compression-6' => 'JPEG',
+'exif-photometricinterpretation-2'=> 'RGB',
+'exif-photometricinterpretation-6'=> 'YCbCr',
+'exif-orientation-1' => 'Normálna',
+'exif-orientation-2' => 'Horizontálne prevrátená',
+'exif-orientation-3' => 'Otočená o 180°',
+'exif-orientation-4' => 'Vertikálne prevrátená',
+'exif-orientation-5' => 'Otočená o 90° proti smeru hodinových ručičiek a vertikálne prevrátená',
+'exif-orientation-6' => 'Otočená o 90° v smere hodinových ručičiek',
+'exif-orientation-7' => 'Otočená o 90° v smere hodinových ručičiek a vertikálne prevrátená',
+'exif-orientation-8' => 'Otočená o 90° proti smeru hodinových ručičiek',
+'exif-planarconfiguration-1'=> 'masívny formát',
+'exif-planarconfiguration-2'=> 'rovinný formát',
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h'=> 'FFFF.H',
+'exif-componentsconfiguration-0'=> 'neexistuje',
+'exif-componentsconfiguration-1'=> 'Y',
+'exif-componentsconfiguration-2'=> 'Cb',
+'exif-componentsconfiguration-3'=> 'Cr',
+'exif-componentsconfiguration-4'=> 'R',
+'exif-componentsconfiguration-5'=> 'G',
+'exif-componentsconfiguration-6'=> 'B',
+'exif-exposureprogram-0'=> 'Nedefinovaný',
+'exif-exposureprogram-1'=> 'Ručný',
+'exif-exposureprogram-2'=> 'Normálny program',
+'exif-exposureprogram-3'=> 'Priorita clony',
+'exif-exposureprogram-4'=> 'Priorita uzávierky',
+'exif-exposureprogram-5'=> 'Tvorivý program (skreslený smerom k hĺbke poľa)',
+'exif-exposureprogram-6'=> 'Akčný program (skreslený smerom k rýchlosti uzávierky)',
+'exif-exposureprogram-7'=> 'Režim portrét (pre detailné zábery s nezaostreným pozadím)',
+'exif-exposureprogram-8'=> 'Režim krajinka (pre fotografie krajiny so zaostreným pozadím)',
+'exif-subjectdistance-value'=> '$1 metrov',
+'exif-meteringmode-0' => 'Neznámy',
+'exif-meteringmode-1' => 'Priemer',
+'exif-meteringmode-2' => 'Vážený priemer',
+'exif-meteringmode-3' => 'Bod',
+'exif-meteringmode-4' => 'Viacero bodov',
+'exif-meteringmode-5' => 'Vzor',
+'exif-meteringmode-6' => 'Čiastočný',
+'exif-meteringmode-255' => 'Iný',
+'exif-lightsource-0' => 'Neznámy',
+'exif-lightsource-1' => 'Denné svetlo',
+'exif-lightsource-2' => 'Fluorescenčný',
+'exif-lightsource-3' => 'Volfrám (inkandescentné svetlo)',
+'exif-lightsource-4' => 'Blesk',
+'exif-lightsource-9' => 'Dobré počasie',
+'exif-lightsource-10' => 'Hmlisté počasie',
+'exif-lightsource-11' => 'Tieň',
+'exif-lightsource-12' => 'Fluorescenčné denné svetlo (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Flourescenčná denná biela (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Fuorescenčná chladná biela (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Fluorescenčná biela (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Štandardné svetlo A',
+'exif-lightsource-18' => 'Štandardné svetlo B',
+'exif-lightsource-19' => 'Štandardné svetlo C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO štúdiový volfrám',
+'exif-lightsource-255' => 'Iný svetelný zdroj',
+'exif-focalplaneresolutionunit-2'=> 'palcov',
+'exif-sensingmethod-1' => 'Nedefinovaná',
+'exif-sensingmethod-2' => 'Jednočipový farebný snímač oblasti',
+'exif-sensingmethod-3' => 'Dvojčipový farebný snímač oblasti',
+'exif-sensingmethod-4' => 'Trojčipový farebný snímač oblasti',
+'exif-sensingmethod-5' => 'Sekvenčný farebný snímač oblasti',
+'exif-sensingmethod-7' => 'Trilineárny snímač',
+'exif-sensingmethod-8' => 'Sekvenčný farebný lineárny snímač',
+'exif-filesource-3' => 'DSC',
+'exif-scenetype-1' => 'Priamo odfotený obrázok',
+'exif-customrendered-0' => 'Normálne spracovanie',
+'exif-customrendered-1' => 'Ručné spracovanie',
+'exif-exposuremode-0' => 'Automatická expozícia',
+'exif-exposuremode-1' => 'Ručná expozícia',
+'exif-exposuremode-2' => 'Auto bracket',
+'exif-whitebalance-0' => 'Automatické vyváženie bielej',
+'exif-whitebalance-1' => 'Ručné vyváženie bielej',
+'exif-scenecapturetype-0'=> 'Štandardný',
+'exif-scenecapturetype-1'=> 'Krajinka',
+'exif-scenecapturetype-2'=> 'Portrét',
+'exif-scenecapturetype-3'=> 'Nočná scéna',
+'exif-gaincontrol-0' => 'Žiadne',
+'exif-gaincontrol-1' => 'Slabé zosilnenie nahor',
+'exif-gaincontrol-2' => 'Silné zosilnenie nahor',
+'exif-gaincontrol-3' => 'Slabé zosilnenie nadol',
+'exif-gaincontrol-4' => 'Silné zosilnenie nadol',
+'exif-contrast-0' => 'Normálny',
+'exif-contrast-1' => 'Mäkký',
+'exif-contrast-2' => 'Tvrdý',
+'exif-saturation-0' => 'Normálna',
+'exif-saturation-1' => 'Nízka sýtosť',
+'exif-saturation-2' => 'Výsoká sýtosť',
+'exif-sharpness-0' => 'Normálna',
+'exif-sharpness-1' => 'Mäkká',
+'exif-sharpness-2' => 'Tvrdá',
+'exif-subjectdistancerange-0'=> 'Neznámy',
+'exif-subjectdistancerange-1'=> 'Makro',
+'exif-subjectdistancerange-2'=> 'Blízky pohľad',
+'exif-subjectdistancerange-3'=> 'Ďaleký pohľad',
+'exif-gpslatitude-n' => 'Severná šírka',
+'exif-gpslatitude-s' => 'Južná šírka',
+'exif-gpslongitude-e' => 'Východná dĺžka',
+'exif-gpslongitude-w' => 'Západná dĺžka',
+'exif-gpsstatus-a' => 'Prebieha meranie',
+'exif-gpsstatus-v' => 'Interoperabilita merania',
+'exif-gpsmeasuremode-2' => '2-rozmerné meranie',
+'exif-gpsmeasuremode-3' => '3-rozmerné meranie',
+'exif-gpsspeed-k' => 'Kilometrov za hodinu',
+'exif-gpsspeed-m' => 'Míľ za hodinu',
+'exif-gpsspeed-n' => 'Uzlov',
+'exif-gpsdirection-t' => 'Skutočný smer',
+'exif-gpsdirection-m' => 'Magnetický smer',
+'edit-externally' => 'Uprav tento súbor pomocou externého programu',
+'edit-externally-help' => 'Viac informácií poskytnú inštrukcie pre nastavenie [http://meta.wikimedia.org/wiki/Help:External_editors externého editora].',
+'recentchangesall' => 'všetky',
+'imagelistall' => 'všetky',
+'watchlistall1' => 'všetky',
+'watchlistall2' => 'všetky',
+'namespacesall' => 'všetky',
+'confirmemail' => 'Potvrdiť e-mailovú adresu',
+'confirmemail_noemail' => 'Nenastavili ste platnú emailovú adresu vo svojich [[Special:Preferences|Nastaveniach]].',
+'confirmemail_text' => 'Táto wiki vyžaduje, aby ste potvrdili platnosť Vašej e-mailovej adresy
+pred používaním e-mailových funkcií. Kliknite na tlačidlo dole, aby sa na Vašu adresu odoslal potvrdzovací
+e-mail. V e-maili bude aj odkaz obsahujúci kód; načítajte odkaz
+do Vášho prehliadača pre potvrdenie, že Vaša e-mailová adresa je platná.',
+'confirmemail_send' => 'Odoslať potvrdzovací kód',
+'confirmemail_sent' => 'Potvrdzovací e-mail odoslaný.',
+'confirmemail_sendfailed'=> 'Nebolo možné odoslať potvrdzovací e-mail. Skontrolujte neplatné znaky v adrese.
+
+Program, ktorý odosielal poštu vrátil: $1',
+'confirmemail_invalid' => 'Neplatný potvrdzovací kód. Kód možno vypršal.',
+'confirmemail_needlogin'=> 'Musíte sa $1 na potvrdenie Vašej emailovaj adresy.',
+'confirmemail_success' => 'Vaša e-mailová adresa bola potvrdená. Môžete sa prihlásiť a využívať wiki.',
+'confirmemail_loggedin' => 'Vaša e-mailová adresa bola potvrdená.',
+'confirmemail_error' => 'Niečo sa pokazilo pri ukladaní vášho potvrdenia.',
+'confirmemail_subject' => '{{SITENAME}} - potvrdenie e-mailovej adresy',
+'confirmemail_body' => 'Niekto, pravdepodobne vy z IP adresy $1, zaregistroval účet
+"$2" s touto e-mailovou adresou na {{GRAMMAR:lokál|{{SITENAME}}}}.
+
+Pre potvrdenie, že tento účet skutočne patrí Vám a pre aktivovanie
+e-mailových funkcií na {{GRAMMAR:lokál|{{SITENAME}}}}, otvorte tento odkaz vo vašom prehliadači:
+
+$3
+
+Ak ste to *neboli* Vy, neotvárajte odkaz. Tento potvrdzovací kód
+vyprší o $4.',
+'tryexact' => 'Skúste presné vyhľadávanie',
+'searchfulltext' => 'Fulltextové vyhľadávanie',
+'createarticle' => 'Vytvoriť stránku',
+'scarytranscludedisabled'=> '[Transklúzia interwiki je vypnutá]',
+'scarytranscludefailed' => '[Nepodarilo sa priniesť šablónu pre $1; prepáčte]',
+'scarytranscludetoolong'=> '[URL je príliš dlhé; prepáčte]',
+'trackbackbox' => '<div id="mw_trackbacks">
+Trackback pre túto stránku:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 Zmazať])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'Trackback úspešne zmazaný.',
+'deletedwhileediting' => 'Varovanie: Táto stránka bola zmazaná potom, ako ste začali s úpravami!',
+'confirmrecreate' => 'Redaktor [[User:$1|$1]] ([[User talk:$1|diskusia]]) zmazal túto stránku potom, ako ste ho začal upravovať s odôvodnením:
+: \'\'$2\'\'
+Prosím potvrďte, že ho chcete skutočne znovu vytvoriť.',
+'recreate' => 'Znova vytvoriť',
+'tooltip-recreate' => 'Znovu vytvoriť stránku napriek tomu, že bola zmazaná',
+'unit-pixel' => 'px',
+'redirectingto' => 'Presmerovanie na [[$1]]...',
+'confirm_purge' => 'Vyčistiť cache pamäť tejto stránky?
+
+$1',
+'confirm_purge_button' => 'OK',
+'youhavenewmessagesmulti'=> 'Máte nové správy na $1',
+'searchcontaining' => 'Hľadaj stránky obsahujúce \'\'$1\'\'.',
+'searchnamed' => 'Hľadaj stránky s názvom \'\'$1\'\'.',
+'articletitles' => 'Stránky začínajúce na \'\'$1\'\'',
+'hideresults' => 'Skry výsledky',
+'displaytitle' => '(Odkazujte na túto stránku ako [[$1]])',
+'loginlanguagelabel' => 'Jazyk: $1',
+'imgmultipageprev' => '&larr; predošlá stránka',
+'imgmultipagenext' => 'ďalšia stránka &rarr;',
+'imgmultigo' => 'Spustiť',
+'imgmultigotopre' => 'Choď na stránku',
+'ascending_abbrev' => 'vzostupne',
+'descending_abbrev' => 'zostupne',
+'table_pager_next' => 'Nasledujúca stránka',
+'table_pager_prev' => 'Predošlá stránka',
+'table_pager_first' => 'Prvá stránka',
+'table_pager_last' => 'Posledná stránka',
+'table_pager_limit' => 'Zobraz $1 položiek na stránku',
+'table_pager_limit_submit'=> 'Spusti',
+'table_pager_empty' => 'Bez výsledkov',
+'autosumm-blank' => 'Odstraňujem obsah stránky',
+'autosumm-replace' => 'Nahrádzam stránku textom \'$1\'',
+'autoredircomment' => 'Presmerovanie na [[$1]]',
+'autosumm-new' => 'Nová stránka: $1',
+);
+
+?>
diff --git a/languages/messages/MessagesSl.php b/languages/messages/MessagesSl.php
new file mode 100644
index 000000000000..3da314ee3242
--- /dev/null
+++ b/languages/messages/MessagesSl.php
@@ -0,0 +1,1587 @@
+<?php
+/** Slovenian (Slovenščina)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+#
+# Revision/
+# Inačica 1.00.00 XJamRastafire 2003-07-08 |NOT COMPLETE
+# 1.00.10 XJamRastafire 2003-11-03 |NOT COMPLETE
+# ______________________________________________________
+# 1.00.20 XJamRastafire 2003-11-05 | COMPLETE
+# 1.00.30 romanm 2003-11-07 | minor changes
+# 1.00.31 romanm 2003-11-11 | merged incorrectly broken lines
+# 1.00.32 romanm 2003-11-19 | merged incorrectly broken lines
+# 1.00.40 romanm 2003-11-21 | fixed Google search
+
+
+$quickbarSettings = array(
+ 'Brez', 'Levo nepomično', 'Desno nepomično', 'Levo leteče'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Posebno',
+ NS_MAIN => '',
+ NS_TALK => 'Pogovor',
+ NS_USER => 'Uporabnik',
+ NS_USER_TALK => 'Uporabniški_pogovor',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Pogovor_{{grammar:mestnik|$1}}',
+ NS_IMAGE => 'Slika',
+ NS_IMAGE_TALK => 'Pogovor_o_sliki',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Pogovor_o_MediaWiki',
+ NS_TEMPLATE => 'Predloga',
+ NS_TEMPLATE_TALK => 'Pogovor_o_predlogi',
+ NS_HELP => 'Pomoč',
+ NS_HELP_TALK => 'Pogovor_o_pomoči',
+ NS_CATEGORY => 'Kategorija',
+ NS_CATEGORY_TALK => 'Pogovor_o_kategoriji'
+);
+
+$datePreferences = false;
+$fallback8bitEncoding = "iso-8859-2";
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+
+$messages = array(
+'tog-underline' => 'Podčrtavanje povezav:',
+'tog-highlightbroken' => 'Oblikuj pretrgane povezave <a href="" class="new">kot</a> (druga možnost: kot<a href="" class="internal">?</a>)',
+'tog-justify' => 'Poravnavaj odstavke',
+'tog-hideminor' => 'Skrij manjše popravke v zadnjih spremembah',
+'tog-extendwatchlist' => 'Izboljšan spisek nadzorov',
+'tog-usenewrc' => 'Izboljšane zadnje spremembe (ni za vse brskalnike)',
+'tog-numberheadings' => 'Samodejno številči poglavja',
+'tog-showtoolbar' => 'Prikaži urejevalno orodno vrstico',
+'tog-editondblclick' => 'Omogoči urejanje strani z dvojnim klikom (JavaScript)',
+'tog-editsection' => 'Omogoči urejanje delov prek povezav [spremeni]',
+'tog-editsectiononrightclick'=> 'Omogoči urejanje delov z desnim klikanjem naslovov delov (JavaScript)',
+'tog-showtoc' => 'Prikaži vsebino (strani z več kot tremi naslovi)',
+'tog-rememberpassword' => 'Geslo si zapomni skozi vse seje',
+'tog-editwidth' => 'Urejevalno polje naj ima vso širino',
+'tog-watchcreations' => 'Vse ustvarjene strani dodaj na spisek nadzorov',
+'tog-watchdefault' => 'Dodaj na spisek nadzorov vse članke, ki sem jih ustvaril/-a ali spremenil/-a',
+'tog-minordefault' => 'Vsa urejanja označi kot manjša',
+'tog-previewontop' => 'Prikaži predogled pred urejevalnim poljem in ne za njim',
+'tog-previewonfirst' => 'Ob začetku urejanja prikaži predogled',
+'tog-nocache' => 'Onemogoči predpomnenje strani',
+'tog-enotifwatchlistpages'=> 'Ob spremembah strani mi pošlji e-pošto',
+'tog-enotifusertalkpages'=> 'Pošlji e-pošto ob spremembah moje pogovorne strani',
+'tog-enotifminoredits' => 'Pošlji e-pošto tudi za manjše spremembe strani',
+'tog-enotifrevealaddr' => 'V sporočilih z obvestili o spremembah razkrij moj e-poštni naslov',
+'tog-shownumberswatching'=> 'Prikaži število uporabnikov, ki spremljajo temo',
+'tog-fancysig' => 'Surovi podpisi (brez samodejne povezave; <b>ne</b> uporabljajte <b>predlog</b> ali <b>zunanjih povezav</b>)',
+'tog-externaleditor' => 'Po privzetem uporabljaj zunanji urejevalnik',
+'tog-externaldiff' => 'Po privzetem uporabljaj zunanje primerjanje',
+'tog-showjumplinks' => 'Prikaži pomožni povezavi »Skoči na«',
+'tog-uselivepreview' => 'Uporabi hitri predogled (JavaScript) (preizkusno)',
+'tog-autopatrol' => 'Vsa moja urejanja označi kot preverjena',
+'tog-forceeditsummary' => 'Ob vpisu praznega povzetka urejanja me opozori',
+'tog-watchlisthideown' => 'Na spisku nadzorov skrij moja urejanja',
+'tog-watchlisthidebots' => 'Na spisku nadzorov skrij urejanja botov',
+'underline-always' => 'Vedno',
+'underline-never' => 'Nikoli',
+'underline-default' => 'Privzeto (brskalnik)',
+'skinpreview' => '(Predogled)',
+'sunday' => 'nedelja',
+'monday' => 'ponedeljek',
+'tuesday' => 'torek',
+'wednesday' => 'sreda',
+'thursday' => 'četrtek',
+'friday' => 'petek',
+'saturday' => 'sobota',
+'january' => 'januar',
+'february' => 'februar',
+'march' => 'marec',
+'april' => 'april',
+'may_long' => 'maj',
+'june' => 'junij',
+'july' => 'julij',
+'august' => 'avgust',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'december',
+'jan' => 'jan.',
+'feb' => 'feb.',
+'mar' => 'mar.',
+'apr' => 'apr.',
+'may' => 'maj',
+'jun' => 'jun.',
+'jul' => 'jul.',
+'aug' => 'avg.',
+'sep' => 'sep.',
+'oct' => 'okt.',
+'nov' => 'nov.',
+'dec' => 'dec.',
+'january-gen' => 'januarja',
+'february-gen' => 'februarja',
+'march-gen' => 'marca',
+'april-gen' => 'aprila',
+'may-gen' => 'maja',
+'june-gen' => 'junija',
+'july-gen' => 'julija',
+'august-gen' => 'avgusta',
+'september-gen' => 'septembra',
+'october-gen' => 'oktobra',
+'november-gen' => 'novembra',
+'december-gen' => 'decembra',
+'categories' => 'Kategorije',
+'pagecategories' => '{{plural:$1|Kategorija|Kategoriji|Kategorije|Kategorije|Kategorije}}',
+'category_header' => 'Strani v kategoriji »$1«',
+'subcategories' => 'Podkategorije',
+'mainpage' => 'Glavna stran',
+'mainpagetext' => 'Wikiprogramje ste uspešno naložili!',
+'mainpagedocfooter' => 'Za uporabo in pomoč pri nastavitvi, prosimo, preglejte [http://meta.wikimedia.org/wiki/MediaWiki_i18n dokumentacijo za prilagajanje vmesnika]
+in [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Uporabniški priročnik].',
+'portal' => 'Portal občestva',
+'portal-url' => 'Project:Portal občestva',
+'about' => 'O projektu',
+'aboutsite' => '{{UCFIRST:{{GRAMMAR:orodnik|{{SITENAME}}}}}}',
+'aboutpage' => 'Project:{{UCFIRST:{{GRAMMAR:orodnik|{{SITENAME}}}}}}',
+'article' => 'Članek',
+'help' => 'Pomoč',
+'helppage' => 'Help:Vsebina',
+'bugreports' => 'Poročila o hroščih',
+'bugreportspage' => 'Project:Poročila o hroščih',
+'sitesupport' => 'Denarni prispevki',
+'sitesupport-url' => 'Project:Zbiranje prispevkov',
+'faq' => 'Najpogostejša vprašanja',
+'faqpage' => 'Project:Najpogostejša vprašanja',
+'edithelp' => 'Pomoč pri urejanju',
+'newwindow' => '(odpre se novo okno)',
+'edithelppage' => 'Help:Urejanje slovenskih strani',
+'cancel' => 'Prekliči',
+'qbfind' => 'Poišči',
+'qbbrowse' => 'Prebrskaj',
+'qbedit' => 'Uredi',
+'qbpageoptions' => 'Možnosti strani',
+'qbpageinfo' => 'Podatki o strani',
+'qbmyoptions' => 'Moje možnosti',
+'qbspecialpages' => 'Posebne strani',
+'moredotdotdot' => 'Več ...',
+'mypage' => 'Moja stran',
+'mytalk' => 'Pogovor',
+'anontalk' => 'Pogovorna stran IP',
+'navigation' => 'Navigacija',
+'metadata_help' => 'Metapodatki (za razlago glej [[Project:Metapodatki]]):',
+'currentevents' => 'Trenutni dogodki',
+'currentevents-url' => 'Project:Trenutni dogodki',
+'disclaimers' => 'Zanikanja odgovornosti',
+'disclaimerpage' => 'Project:Splošno_zanikanje_odgovornosti',
+'privacy' => 'Politika zasebnosti',
+'privacypage' => 'wikimedia:Politika_zasebnosti',
+'errorpagetitle' => 'Napaka',
+'returnto' => 'Vrnitev na: $1.',
+'tagline' => 'Iz {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'search' => 'Iskanje',
+'searchbutton' => 'Iskanje',
+'go' => 'Pojdi na',
+'searcharticle' => 'Pojdi na',
+'history' => 'Zgodovina strani',
+'history_short' => 'Zgodovina strani',
+'updatedmarker' => 'Posodobljeno od mojega zadnjega obiska',
+'info_short' => 'Sporočilo',
+'printableversion' => 'Različica za tisk',
+'permalink' => 'Trajna povezava',
+'print' => 'Tisk',
+'edit' => 'Uredite stran',
+'editthispage' => 'Uredi stran',
+'delete' => 'Briši',
+'deletethispage' => 'Briši stran',
+'undelete_short' => 'Vrni $1 {{plural:$1|izbrisano urejanje|izbrisani urejanji|izbrisana urejanja|izbrisanih urejanj|izbrisanih urejanj}}',
+'protect' => 'Zaščiti',
+'protectthispage' => 'Zaščiti stran',
+'unprotect' => 'Odstrani zaščito',
+'unprotectthispage' => 'Odstrani zaščito strani',
+'newpage' => 'Nova stran',
+'talkpage' => 'Pogovorite se o strani',
+'specialpage' => 'Posebna stran',
+'personaltools' => 'Osebna orodja',
+'postcomment' => 'Objavite pripombo',
+'articlepage' => 'Prikaže članek',
+'talk' => 'Pogovor',
+'views' => 'Pogled',
+'toolbox' => 'Pripomočki',
+'userpage' => 'Prikaži uporabnikovo stran',
+'projectpage' => 'Prikaži projektno stran',
+'imagepage' => 'Prikaže stran z datoteko',
+'viewtalkpage' => '&lt; Pogovor',
+'otherlanguages' => 'V drugih jezikih',
+'redirectedfrom' => '(Preusmerjeno z $1)',
+'autoredircomment' => 'preusmeritev na [[$1]]',
+'redirectpagesub' => 'Preusmeritvena stran',
+'lastmodifiedat' => 'Čas zadnje spremembe: $2, $1.',
+'viewcount' => 'Stran je bila naložena $1-krat.',
+'copyright' => 'Besedilo je na razpolago pod pogoji $1.',
+'protectedpage' => 'Zaščitena stran',
+'jumpto' => 'Skoči na:',
+'jumptonavigation' => 'navigacija',
+'jumptosearch' => 'iskanje',
+'badaccess' => 'Napaka pri dovoljenju',
+'versionrequired' => 'Potrebna je različica MediaWiki $1',
+'versionrequiredtext' => 'Za uporabo strani je potrebna različica MediaWiki $1. Glejte [[Special:Version]].',
+'ok' => 'V redu',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Vzpostavljeno iz »$1«',
+'youhavenewmessages' => 'Imate $1 ($2)',
+'newmessageslink' => 'novo sporočilo',
+'newmessagesdifflink' => 'zadnja sprememba',
+'editsection' => 'spremeni',
+'editold' => 'spremeni',
+'editsectionhint' => 'Spremeni razdelek: $1',
+'toc' => 'Vsebina',
+'showtoc' => 'prikaži',
+'hidetoc' => 'skrij',
+'thisisdeleted' => 'Prikažem ali vrnem $1?',
+'viewdeleted' => 'Prikažem $1?',
+'restorelink' => '$1 {{plural:$1|izbrisana redakcija|izbrisani redakciji|izbrisane redakcije|izbrisanih redakcij|izbrisanih redakcij}}',
+'feedlinks' => 'Podajanje:',
+'feed-invalid' => 'Neveljavna vrsta naročniškega dovoda.',
+'nstab-main' => 'Članek',
+'nstab-user' => 'Uporabniška stran',
+'nstab-media' => 'Predstavnostna stran',
+'nstab-special' => 'Posebno',
+'nstab-project' => 'Projektna stran',
+'nstab-image' => 'Datoteka',
+'nstab-mediawiki' => 'Sporočilo',
+'nstab-template' => 'Predloga',
+'nstab-help' => 'Pomoč',
+'nstab-category' => 'Kategorija',
+'nosuchaction' => 'Tako dejanje ne obstaja',
+'nosuchactiontext' => 'Dejanja, ki ga je označil spletni naslov, wiki ne prepozna.',
+'nosuchspecialpage' => 'Posebna stran, ki ste jo zahtevali, ne obstaja',
+'nospecialpagetext' => 'Posebne strani, ki ste jo zahtevali, programje {{GRAMMAR:rodilnik|{{SITENAME}}}} ne prepozna ali pa nimate dostopa do nje. Seznam vseh prepoznanih posebnih strani je na razpolago na strani [[Special:Specialpages]].',
+'error' => 'Napaka',
+'databaseerror' => 'Napaka zbirke podatkov',
+'dberrortext' => 'Iskanje ali drugo želeno dejanje je verjetno zahtevalo preveč časa. Mogoči razlogi so: <ul> <li>Iskanje z vsemi besedami v narekovajih. Poskusite najprej iskati brez njih. Kadar to ni zadosti, vpišite še nekaj iskalnih pojmov ali dodajte besedo ali dve zunaj narekovajev, s čimer boste označili splošno predmetno področje. <li>Zelo obsežen spisek nadzorov (verjetno čez 10.000 strani) ob obremenjenih strežnikih. <li>Morda ste poskušali dejanje izvesti ob začasni izredni obremenitvi strežnikov. Ob izrednih obremenitvah lahko pride do nenadnega končanja številnih pomembnih opravil, da se dosežejo običajni odzivni časi. Če se zahtevano dejanje sicer izvede brez težav, poskusite znova v nekaj minutah. </ul> <p>Splošno sporočilo o napaki je: <p> Prišlo je do napake zbirke podatkov. Vzrok bi lahko bil nesprejemljiv iskalni niz (glejte $5) ali programski hrošč. Zadnje poskušano iskanje: <blockquote><tt>$1</tt></blockquote> znotraj funkcije »<tt>$2</tt>«. MySQL je vrnil napako »<tt>$3: $4</tt>«. <p>Če je zgornja napaka 2013, je vaš postopek končal upravljavec podatkovnega bremena. Prosimo, poskusite z ustreznejšim iskanjem ali iskanje ponovite ob manj obremenjenih strežnikih. Opravičujemo se za nevšečnosti.</p>',
+'dberrortextcl' => 'Pri iskanju v zbirki podatkov je prišlo do skladenjske napake. Zadnje iskanje v zbirki podatkov: »$1« iz funkcije »$2«. MySQL je vrnil napako »$3: $4«.',
+'noconnect' => 'S PB na $1 se ne morem povezati.',
+'nodb' => 'Zbirke podatkov \'$1\' ne morem izbrati',
+'cachederror' => 'To je shranjen in morda neposodobljen prepis želene strani.',
+'laggedslavemode' => 'Opozorilo: stran morda ne vsebuje najnovejših posodobitev',
+'readonly' => 'Zbirka podatkov je zaklenjena',
+'enterlockreason' => 'Vnesite razlog za zaklenitev in oceno, kdaj bo urejanje spet mogoče',
+'readonlytext' => 'Zbirka podatkov je za urejanja in druge spremembe začasno zaklenjena. To navadno pomeni, da nadgrajujejo programje strežnikov ali pa rutinsko vzdrževanje zbirke.
+
+Sistemski skrbnik, ki jo je zaklenil, je podal naslednjo razlago: \'\'"$1"\'\'',
+'missingarticle' => 'Zbirka podatkov bi besedilo strani »$1« morala najti, vendar ji žal ni uspelo.
+
+Morda stran s tem imenom še ni bila ustvarjena. Če je tako, jo lahko ustvarite z izbiro povezave »Uredite stran«.
+
+Kadar gre za nedavno spremenjeno stran, jo poskusite minuto ali dve pozneje ponovno poiskati. Morda pa ste sledili zastareli povezavi na primerjavo ali zgodovino izbrisane strani.
+
+Kadar to ni tako, ste morda odkrili hrošč v programju. Prosimo, obvestite katerega izmed [[Project:Administratorji|administratorjev]] in pri tem navedite spletni naslov.',
+'readonly_lag' => 'Podatkovna zbirka se je samodejno zaklenila, dokler se podrejeni strežniki ne uskladijo z glavnim.',
+'internalerror' => 'Notranja napaka',
+'filecopyerror' => 'Datoteke »$1« ni mogoče prepisati v »$2«.',
+'filerenameerror' => 'Datoteke »$1« ni mogoče preimenovati v »$2«.',
+'filedeleteerror' => 'Datoteke »$1« ni mogoče izbrisati.',
+'filenotfound' => 'Datoteke »$1« ne najdem.',
+'unexpected' => 'Nepričakovana vrednost: "$1"="$2".',
+'formerror' => 'Napaka: obrazca ni mogoče predložiti',
+'badarticleerror' => 'Na tej strani dejanja ne morem izvesti. Morda je bila stran med predložitvijo vaše zahteve že izbrisana.',
+'cannotdelete' => 'Navedene strani ali datoteke ni mogoče izbrisati. Morda jo je izbrisal že kdo drug.',
+'badtitle' => 'Nepravilen naslov',
+'badtitletext' => 'Navedeni naslov strani je neveljaven, prazen, napačno povezan k drugim jezikom oziroma wikiprojektom ali pa vsebuje [[Project:Dogovori o poimenovanjih#Previdno s posebnimi znaki|nepodprte znake]].',
+'perfdisabled' => 'Naveden je shranjeni prepis $1:',
+'perfdisabledsub' => 'Naveden je shranjeni prepis $1:',
+'perfcached' => 'Navedeni podatki morda niso popolnoma posodobljeni.',
+'perfcachedts' => 'Prikazani podatki so shranjeni v predpomnilniku. Čas zadnje osvežitve: $1.',
+'wrong_wfQuery_params' => 'Nepravilni parametri za wfQuery()<br />
+Funkcija: $1<br />
+Iskanje: $2',
+'viewsource' => 'Izvorno besedilo',
+'viewsourcefor' => 'za $1',
+'protectedtext' => '<strong style="font-size:130%">Stran je [[Project:Zaščitena stran|zaščitena]] pred urejanjem.</strong>
+
+* \'\'\'Če je stran [[Project:Pravila zaščite strani|popolnoma zaščitena]], jo lahko urejajo le [[Project:Administratorji|administratorji]]; če je [[Project:Delna zaščita|zaščitena delno]], jo lahko urejajo tudi uveljavljeni [[Project:Čemu se registrirati?|registrirani uporabniki]].\'\'\'
+* \'\'\'Odstranitev zaščite lahko zahtevate [[Project:Pod lipo|Pod lipo]]\'\'\'.
+
+<p style="border-top:1px solid #ccc;margin-top:1.5em;padding-top:.5em">Lahko si ogledate in prepišete izvorno besedilo strani:</p>',
+'protectedinterface' => 'Prikazana stran vsebuje besedilo ali drug element uporabniškega vmesnika programja. Zaradi preprečevanja zlorabe je zaščitena.',
+'editinginterface' => '\'\'\'Opozorilo:\'\'\' Urejate stran, ki vsebuje besedilo ali drug element uporabniškega vmesnika programja. Spremembe te strani bodo vplivale na podobo uporabniškega vmesnika. To stran lahko urejajo le [[Project:Administratorji|administratorji]]. Prosimo, da pri spremembah upoštevate soglasje občestva.',
+'sqlhidden' => '(SQL-poizvedovanje je skrito)',
+'logouttitle' => 'Odjava uporabnika',
+'logouttext' => 'Odjavili ste se. {{GRAMMAR:tožilnik|{{SITENAME}}}} lahko zdaj uporabljate neprijavljeni ali pa se ponovno prijavite. Morda bodo nekatere strani še naprej prikazane, kot da ste prijavljeni. To lahko popravite z izpraznitvijo predpomnilnika.',
+'welcomecreation' => '== Dobrodošli, $1! ==
+
+Ustvarili ste račun. Če želite, si lahko prilagodite [[Special:Preferences|nastavitve]] za delo v {{GRAMMAR:dajalnik|{{SITENAME}}}}. Želimo vam uspešno sodelovanje!',
+'loginpagetitle' => 'Prijava uporabnika',
+'yourname' => 'Uporabniško ime',
+'yourpassword' => 'Geslo',
+'yourpasswordagain' => 'Ponovno vpišite geslo',
+'remembermypassword' => 'Zapomni si me (samodejna prijava)',
+'yourdomainname' => 'Domena',
+'externaldberror' => 'Pri potrjevanju istovetnosti je prišlo do notranje napake ali pa za osveževanje zunanjega računa nimate dovoljenja.',
+'loginproblem' => '<b>Prijava ni uspela.</b><br />Prosimo, poskusite znova!',
+'alreadyloggedin' => '<div class="alreadyloggedin">Uporabnik $1, ste že prijavljeni!</div>',
+'login' => 'Prijava',
+'loginprompt' => '<!--Za prijavo v {{GRAMMAR:tožilnik|{{SITENAME}}}} omogočite piškotke.-->',
+'userlogin' => 'Prijavite se / registrirajte se',
+'logout' => 'Odjava',
+'userlogout' => 'Odjava',
+'notloggedin' => 'Niste prijavljeni',
+'nologin' => 'Še nimate uporabniškega računa? $1!',
+'nologinlink' => 'Registrirajte se',
+'createaccount' => 'Ustvari račun',
+'gotaccount' => 'Račun že imate? $1.',
+'gotaccountlink' => 'Prijavite se',
+'createaccountmail' => 'Po e-pošti',
+'badretype' => 'Gesli, ki ste ju vnesli, se ne ujemata.',
+'userexists' => 'Uporabniško ime, ki ste ga vnesli, je že zasedeno. Prosimo, izberite si drugo.',
+'youremail' => 'E-pošta (neobvezno)*',
+'username' => 'Uporabniško ime:',
+'uid' => 'ID-številka:',
+'yourrealname' => 'Vaše pravo ime*',
+'yourlanguage' => 'Jezik vmesnika:',
+'yourvariant' => 'Jezikovna različica',
+'yournick' => 'Podpis (uporabite ~~~~):',
+'badsig' => 'Neveljaven surovi podpis; preverite oznake HTML.',
+'email' => 'E-pošta',
+'prefs-help-email-enotif'=> 'Če ste tako izbrali, se naslov uporablja tudi za pošiljanje sporočil o spremembah.',
+'prefs-help-realname' => '<!-- ¹ Pravo ime (neobvezno): če se odločite, da ga boste navedli, bo uporabljeno za priznavanje vašega dela. -->',
+'loginerror' => 'Napaka ob prijavi',
+'prefs-help-email' => '<nowiki>*</nowiki>E-pošta (neobvezno): Vpisan e-poštni naslov omogoča drugim, da vam lahko pošiljajo elektronsko pošto brez razkritja vaše istovetnosti.',
+'nocookiesnew' => 'Uporabniški račun je ustvarjen, vendar niste prijavljeni. {{SITENAME}} za prijavo uporabnikov uporablja piškotke, ki pa so pri vas onemogočeni. Prosimo, omogočite jih, nato pa se s svojim uporabniškim imenom in geslom ponovno poskusite prijaviti.',
+'nocookieslogin' => '{{SITENAME}} za prijavljanje uporabnikov uporablja piškotke. Ker jih imate onemogočene, vas prosimo, da jih omogočite in se ponovno prijavite.',
+'noname' => 'Niste vnesli veljavnega uporabniškega imena.',
+'loginsuccesstitle' => 'Uspešno ste se prijavili',
+'loginsuccess' => 'Sedaj ste vpisani v {{GRAMMAR:tožilnik|{{SITENAME}}}} kot "$1".',
+'nosuchuser' => 'Uporabnik z imenom »$1« ne obstaja.
+Preverite črkovanje ali pa si z uporabo prikazanega obrazca ustvarite nov uporabniški račun.',
+'nosuchusershort' => 'Uporabnik z imenom »$1« ne obstaja. Preverite črkovanje.',
+'nouserspecified' => 'Prosimo, vpišite uporabniško ime.',
+'wrongpassword' => 'Vnesli ste napačno geslo. Prosimo, poskusite znova.',
+'wrongpasswordempty' => 'Vpisali ste prazno geslo. Prosimo, poskusite znova.',
+'mailmypassword' => 'Pošlji mi novo geslo',
+'passwordremindertitle' => 'Geselski opomnik iz {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'passwordremindertext' => 'Nekdo (verjetno vi, z IP-naslova $1)
+je zahteval, da vam pošljemo novo prijavno geslo za {{GRAMMAR:tožilnik|{{SITENAME}}}} ($4).
+Geslo uporabnika \'\'$2\'\' je odslej \'\'$3\'\'.
+Z njim se lahko prijavite in ga spremenite.
+
+Če je geslo zahteval nekdo drug ali ste se spomnili starega in ga ne želite več spremeniti, lahko sporočilo prezrete in se še naprej prijavljate s starim.',
+'noemail' => 'Elektronska pošta uporabnika »$1« ni zapisana.',
+'passwordsent' => 'Na naslov elektronske pošte, vpisane za "$1", smo poslali novo geslo. Ko ga boste prejeli, se lahko ponovno prijavite.',
+'eauthentsent' => 'E-sporočilo je poslano na navedeni e-naslov. Če želite tja poslati še katero, po v omenjenem sporočilu navedenih navodilih potrdite lastništvo naslova.',
+'mailerror' => 'Napaka pri pošiljanju pošte: $1',
+'acct_creation_throttle_hit'=> 'Obiskovalci {{GRAMMAR:rodilnik|{{SITENAME}}}} so s tem [[IP-naslov]]om v zadnjih 24 urah ustvarili že $1 {{plural:$1|uporabniški račun|uporabniška računa|uporabniške račune|uporabniških računov|uporabniških računov}} in s tem dosegli največje dopustno število v omenjenem časovnem obdobju. Novih računov zato s tem IP-naslovom trenutno žal ne morete več ustvariti.
+
+== Urejate prek posredniškega strežnika? ==
+
+Če urejate prek AOL ali iz Bližnjega vzhoda, Afrike, Avstralije, Nove Zelandije ali iz šole, knjižnice ali podjetja, si IP-naslov morda delite z drugimi uporabniki. Če je tako, ste to sporočilo morda prejeli, čeprav niste ustvarili še nobenega računa. Znova se lahko poskusite registrirati po nekaj urah.',
+'emailauthenticated' => 'Čas potrditve vašega e-poštnega naslova: $1',
+'emailnotauthenticated' => 'Vaš e-poštni naslov še ni potrjen. Za navedene
+možnosti se e-pošte ne bo pošiljalo.',
+'noemailprefs' => '<strong>E-poštnega naslova niste vnesli</strong>, zato naslednje možnosti ne bodo delovale.',
+'emailconfirmlink' => 'Potrdite svoj e-poštni naslov',
+'invalidemailaddress' => 'E-poštni naslov zaradi neveljavne oblike ni sprejemljiv. Prosimo, vpišite pravilno oblikovanega ali polje izpraznite.',
+'accountcreated' => 'Račun je ustvarjen',
+'accountcreatedtext' => 'Uporabniški račun za »$1« je ustvarjen.',
+'bold_sample' => 'Krepko besedilo',
+'bold_tip' => 'Krepko besedilo',
+'italic_sample' => 'Ležeče besedilo',
+'italic_tip' => 'Ležeče besedilo',
+'link_sample' => 'Naslov povezave',
+'link_tip' => 'Notranja povezava',
+'extlink_sample' => 'http://www.zgled.com naslov povezave',
+'extlink_tip' => 'Zunanja povezava (ne pozabite na predpono http://)',
+'headline_sample' => 'Besedilo naslovne vrstice',
+'headline_tip' => 'Naslovna vrstica druge ravni',
+'math_sample' => 'Tu vnesite enačbo',
+'math_tip' => 'Matematična enačba (TeX/LaTeX)',
+'nowiki_sample' => 'Tu vnesite neoblikovano besedilo',
+'nowiki_tip' => 'Prezri wikioblikovanje',
+'image_sample' => 'Zgled.jpg',
+'image_tip' => 'Povezava na sliko',
+'media_sample' => 'Zgled.ogg',
+'media_tip' => 'Povezava na predstavnostno datoteko',
+'sig_tip' => 'Vaš podpis z datumom',
+'hr_tip' => 'Vodoravna črta (uporabljajte zmerno)',
+'summary' => 'Povzetek urejanja',
+'subject' => 'Tema/naslov',
+'minoredit' => 'Manjše urejanje',
+'watchthis' => 'Opazuj članek',
+'savearticle' => 'Shrani stran',
+'preview' => 'Predogled',
+'showpreview' => 'Prikaži predogled',
+'showlivepreview' => 'Predogled v živo',
+'showdiff' => 'Prikaži spremembe',
+'anoneditwarning' => '\'\'\'Opozorilo\'\'\': niste prijavljeni. V zgodovino strani se bo zapisal vaš IP-naslov.',
+'missingsummary' => '\'\'\'Opozorilo:\'\'\' Niste napisali povzetka urejanja. Ob ponovnem kliku gumba \'\'Shrani\'\' se bo vaše urejanje shranilo brez njega.',
+'missingcommenttext' => 'Prosimo, vpišite v spodnje polje komentar.',
+'blockedtitle' => 'Uporabnik je blokiran.',
+'blockedtext' => 'Urejanje z vašim uporabniškim imenom oziroma IP-naslovom je $1 onemogočil(-a).
+Vzrok:<br />\'\'$2\'\'<br />O blokiranju se lahko pogovorite z $1 ali katerim drugim
+[[Project:Administratorji|administratorjem]].
+
+Vedite, da lahko ukaz »Pošlji uporabniku e-pismo« uporabite le, če ste v nastavitvah vpisali in potrdili svoj elektronski naslov.
+
+Vaš IP-naslov je $3. Prosimo, vključite ga v vse morebitne poizvedbe.',
+'blockedoriginalsource' => 'Izvorno besedilo strani \'\'\'$1\'\'\' je na razpolago spodaj:',
+'blockededitsource' => 'Besedilo \'\'\'vaših urejanj\'\'\' strani \'\'\'$1\'\'\' je prikazano spodaj:',
+'whitelistedittitle' => 'Za urejanje se morate prijaviti',
+'whitelistedittext' => 'Za urejanje strani se $1.',
+'whitelistreadtitle' => 'Za ogled se je treba prijaviti',
+'whitelistreadtext' => 'Za ogled strani se morate [[Special:Userlogin|prijaviti]]',
+'whitelistacctitle' => 'Za izdelavo uporabniškega računa nimate dovoljenja.',
+'whitelistacctext' => 'V tem wikiju lahko račune odpirajo le [[Special:Userlogin|prijavljeni]] uporabniki z ustreznimi uporabniškimi pravicami.',
+'confirmedittitle' => 'Za urejanje je potrebna e-poštna potrditev',
+'confirmedittext' => 'Pred urejanjem strani morate potrditi svoj e-poštni naslov. Prosimo, da ga z uporabo [[Special:Preferences|uporabniških nastavitev]] vpišete in potrdite.',
+'loginreqtitle' => 'Treba se je prijaviti',
+'loginreqlink' => 'prijava',
+'loginreqpagetext' => 'Za ogled drugih strani morate $1.',
+'accmailtitle' => 'Geslo je poslano.',
+'accmailtext' => 'Geslo za \'$1\' je poslano na $2.',
+'newarticle' => '(Nov)',
+'newarticletext' => 'Sledili ste povezavi na stran, ki še ne obstaja.
+Da bi stran ustvarili, vnesite v spodnji obrazec besedilo
+(za več informacij glej [[Help:Vsebina|pomoč]]).
+Če ste sem prišli po pomoti, v svojem brskalniku kliknite gumb \'\'Nazaj\'\'.',
+'anontalkpagetext' => '---- \'\'To je pogovorna stran za nepodpisanega uporabnika, ki še ni ustvaril računa ali, ki ga ne uporablja. Zaradi tega moramo uporabiti števčen [[IP address]] za njegovo/njeno ugotavljanje istovetnosti. Takšen IP naslov si lahko deli več uporabnikov. Če ste nepodpisan uporabnik in če menite, da so nepomembne pripombe namenjene vam, prosimo [[Special:Userlogin|ustvarite račun ali pa se vpišite]], da preprečite naslednje zmede z drugimi nepodpisanimi uporabniki.\'\'',
+'noarticletext' => 'Na tej strani ni trenutno nobenega besedila. Naslov strani lahko poskusite [[{{ns:special}}:Search/{{PAGENAME}}|poiskati]] na drugih straneh ali pa [{{fullurl:{{FULLPAGENAME}}|action=edit}} stran uredite].',
+'clearyourcache' => '\'\'\'Opomba:\'\'\' Da bodo spremembe prišle do veljave, po shranitvi izpraznite predpomnilnik svojega brskalnika: \'\'\'Mozilla/Safari:\'\'\' držite \'\'Shift\'\' in kliknite \'\'Reload\'\' (ali pritisnite \'\'Ctrl-Shift-R\'\'), \'\'\'Internet Explorer:\'\'\' \'\'Ctrl-F5\'\', \'\'\'Opera/Konqueror:\'\'\' \'\'F5\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Nasvet:</strong> Za preizkušanje svojega novega CSS/JS pred shranjevanjem uporabite gumb \'\'Prikaži predogled\'\'.',
+'usercsspreview' => '\'\'\'OPOZORILO: svoj uporabniški CSS le predogledujete in ga še niste shranili!\'\'\'',
+'userjspreview' => '\'\'\'Svoj uporabniški Javascript le predogledujete in še ni shranjen!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Opozorilo:\'\'\' koža »$1« ne obstaja. Vedite, da .css in .js strani po meri uporabljajo naslov z malo začetnico, npr. User:Blabla/monobook.css namesto User:Blabla/Monobook.css.',
+'updated' => '(Posodobljeno)',
+'note' => '<strong>Opomba:</strong>',
+'previewnote' => '<strong>Stran le predogledujete in še ni shranjena!</strong>',
+'session_fail_preview' => '<strong>Zaradi izgube podatkov o seji nam vašega urejanja žal ni uspelo obdelati. Prosimo, poskusite znova. Če bo spet prišlo do napake, se odjavite in ponovno prijavite. Za nevšečnosti se opravičujemo.</strong>',
+'previewconflict' => 'V prikazanem predogledu je v zgornjem predelu urejanja navedeno besedilo, kakor se bo prikazalo, če ga boste shranili.',
+'session_fail_preview_html'=> '<strong>Zaradi izgube podatkov o seji nam vašega urejanja žal ni uspelo obdelati.</strong>
+
+\'\'Ker ima ta wiki vklopljen surovi HTML, je predogled zaradi preprečevanja napadov z JavaScriptom skrit.\'\'
+
+<strong>Če gre za dobronameren poskus urejanja, vas prosimo, da poskusite znova. Če bo spet prišlo do napake, se odjavite in ponovno prijavite. Za nevšečnosti se opravičujemo.</strong>',
+'importing' => 'Uvažam $1',
+'editing' => 'Urejanje $1',
+'editinguser' => 'Urejanje $1',
+'editingsection' => 'Urejanje $1 (razdelek)',
+'editingcomment' => 'Urejanje $1 (pripomba)',
+'editconflict' => 'Navzkrižje urejanj: $1',
+'explainconflict' => 'Med vašim urejanjem je stran spremenil nekdo drug. Zgornje besedilno območje vsebuje njeno trenutno vsebino in bo edino, ki se bo ob izbiri ukaza »Shrani stran« shranilo. V spodnjem območju so prikazane vaše spremembe, ki jih boste morali vključiti v zgornje.<br />',
+'yourtext' => 'Vaše besedilo',
+'storedversion' => 'Shranjena različica',
+'nonunicodebrowser' => '<strong>OPOMBA</strong>: Vaš brskalnik ne podpira Unicode, zato boste pri urejanju strani z nelatiničnimi znaki morda imeli težave. Za obhod te težave se bodo <strong>ne-ASCII-znaki v urejevalnem polju spodaj pojavili kot šestnajstiške kode</strong>.',
+'editingold' => '<div style="background: #FFBDBD; border: 1px solid #BB7979; color: #000000; font-weight: bold; margin: 2em 0 1em; padding: .5em 1em; vertical-align: middle; clear: both;">Urejate staro redakcijo strani. Če jo boste shranili, bodo vse poznejše spremembe [[Pomoč:Vračanje|razveljavljene]].</div>',
+'yourdiff' => 'Primerjava',
+'copyrightwarning' => 'Vsi prispevki k {{GRAMMAR:dajalnik|{{SITENAME}}}} se obravnavajo kot objave pod pogoji $2 (za podrobnosti glej $1). Če niste pripravljeni na neusmiljeno urejanje in prosto razširjanje vašega gradiva, ga ne prispevajte.
+
+Poleg tega zagotavljate, da ste prispevke napisali oziroma ustvarili sami ali pa prepisali iz javno dostopnega ali podobnega prostega vira oziroma da pri tem ne kršite avtorskih pravic.
+<strong>NE DODAJAJTE AVTORSKO ZAŠČITENEGA DELA BREZ DOVOLJENJA !</strong>',
+'copyrightwarning2' => 'Vsi prispevki k {{GRAMMAR:dajalnik|{{SITENAME}}}} se lahko urejajo, spreminjajo ali odstranijo s strani drugih uporabnikov. Če niste pripravljeni na neusmiljeno urejanje in prosto razširjanje vašega gradiva, ga ne prispevajte.
+
+Poleg tega zagotavljate, da ste prispevke napisali oziroma ustvarili sami ali pa prepisali iz javno dostopnega ali podobnega prostega vira oziroma da pri tem ne kršite avtorskih pravic ($1).
+<strong>NE DODAJAJTE AVTORSKO ZAŠČITENEGA DELA BREZ DOVOLJENJA !</strong>',
+'longpagewarning' => '<div id="longpagewarning" style="border-width:1px;border-style:solid;border-color:#aaaaaa;padding:3px">Stran je dolga $1 {{plural:$1|kilobajt|kilobajta|kilobajte|kilobajtov|kilobajtov}}. To je morda več, kot bi želeli, zato premislite o razdelitvi na podstrani oziroma arhiviranju.</div>',
+'longpageerror' => '<strong>NAPAKA: Predloženo besedilo je dolgo $1 {{plural:$1|kilobajt|kilobajta|kilobajte|kilobajtov|kilobajtov}}, s čimer presega največjo dovoljeno dolžino $2 {{plural:$2|kilobajta|kilobajtov|kilobajtov|kilobajtov|kilobajtov}}. Zato ga žal ni mogoče shraniti.</strong>',
+'readonlywarning' => '<strong>OPOZORILO: Zbirka podatkov je zaradi vzdrževanja začasno zaklenjena, kar pomeni, da sprememb ne morete shraniti. Prosimo, prenesite besedilo v urejevalnik in ga dodajte pozneje.</strong>',
+'protectedpagewarning' => '<span style="color: red; background-color: white;" id="protectedpagewarning"><strong>OPOMBA:</strong> Stran je zaklenjena in jo lahko urejajo le sodelavci z vzdrževalnimi pravicami. Pri urejanju sledite [[Project:Smernice_zaščitenih_strani|smernicam zaščitenih strani]].</span>',
+'semiprotectedpagewarning'=> '<span id="semiprotectedpagewarning">\'\'\'Opomba:\'\'\' Stran je [[Project:Delna zaščita|zaščitena]] in jo lahko urejajo le uveljavljeni uporabniki.</span>',
+'templatesused' => 'Na strani uporabljene predloge:',
+'edittools' => '<!-- To besedilo bo prikazano pod urejevalnim poljem in poljem za nalaganje. -->',
+'nocreatetitle' => 'Članka nisem našel',
+'nocreatetext' => 'Članka s tem naslovom - \'\'\'{{PAGENAME}}\'\'\' - še nimamo, lahko pa ga [[Special:Search/{{PAGENAME}}|poskusite poiskati]] ali pa se [[Special:Userlogin|prijavite]] in ga ustvarite.
+
+Kot neregistriran uporabnik lahko vsebino, ki ste jo želeli objaviti, dodate na stran [[Project:Članki za objavo]].
+
+Za več podatkov {{GRAMMAR:orodnik|{{SITENAME}} si, prosimo, preberite [[Project:Uvod|uvod]].',
+'revhistory' => 'Zgodovina strani',
+'nohistory' => 'Stran nima zgodovine urejanja.',
+'revnotfound' => 'Redakcije ne najdem',
+'revnotfoundtext' => 'Redakcije strani, ki ste jo poskušali pridobiti, ni mogoče najti. Prosimo, preverite spletni naslov, ki ste ga uporabili za dostop do strani.',
+'loadhist' => 'Nalagam zgodovino strani',
+'currentrev' => 'Trenutna redakcija',
+'revisionasof' => 'Redakcija: $1',
+'previousrevision' => '← Starejša redakcija',
+'nextrevision' => 'Novejša redakcija →',
+'currentrevisionlink' => 'poglejte trenutno redakcijo',
+'cur' => 'tren',
+'next' => 'nasl',
+'last' => 'prej',
+'orig' => 'izvi',
+'histlegend' => 'Za ogled redakcije kliknite njen datum.
+
+Napotek: (tren) = primerjava s trenutno redakcijo,
+(prej) = primerjava s prejšnjo redakcijo, <b>m</b> = manjše urejanje',
+'deletedrev' => '[izbrisano]',
+'histfirst' => 'Najstarejše',
+'histlast' => 'Najnovejše',
+'rev-deleted-comment' => '(pripomba je bila odstranjena)',
+'rev-deleted-user' => '(uporabniško ime je bilo odstranjeno)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Prikazana redakcija je bila iz javnih arhivov odstranjena.
+Podrobnosti so morda na razpolago v [{{fullurl:Special:Log/delete|page=Rev-deleted-text-permission dnevniku brisanja}}].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Prikazana redakacija strani je bila iz javnih arhivov odstranjena. Ogledate si jo lahko, ker ste administrator spletišča. Podrobnosti so morda navedene v [{{fullurl:Special:Log/delete|page=Rev-deleted-text-view dnevniku brisanja}}].
+</div>',
+'rev-delundel' => 'pokaži/skrij',
+'history-feed-title' => 'Zgodovina strani',
+'history-feed-description'=> 'Zgodovina navedene strani {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'history-feed-item-nocomment'=> '$1 ob $2',
+'history-feed-empty' => 'Želena stran ne obstaja. Morda je bila iz {{GRAMMAR:rodilnik|{{SITENAME}}}} izbrisana ali pa jo je kdo preimenoval. Prosimo, poskusite v {{GRAMMAR:dajalnik|{{SITENAME}}}} [[Special:Search|poiskati]] ustrezajoče nove strani.',
+'revisiondelete' => 'Izbriši/obnovi redakcije',
+'revdelete-selected' => 'Izbrana redakcija strani [[:$1]]:',
+'revdelete-text' => 'Izbrisane redakcije bodo v zgodovini strani še vedno navedene, vendar bo njihova vsebina za javnost nedostopna.
+
+Do skrite vsebine bodo še vedno lahko dostopali drugi administratorji in jo z uporabo istega vmesnika tudi obnovili, razen kjer bodo operaterji spletišča uveljavili dodatne omejitve.',
+'revdelete-legend' => 'Nastavitve z redakcijami povezanih omejitev:',
+'revdelete-hide-text' => 'Skrij besedilo redakcije',
+'revdelete-hide-comment'=> 'Skrij povzetek urejanja',
+'revdelete-hide-user' => 'Skrij urejevalčevo uporabniško ime/IP-naslov',
+'revdelete-hide-restricted'=> 'Omejitve naj veljajo za vse uporabnike, z administratorji vred',
+'revdelete-log' => 'Dnevniški komentar:',
+'revdelete-submit' => 'Uporabi za izbrano redakcijo',
+'revdelete-logentry' => 'sprememba vidnosti redakcij strani [[$1]]',
+'difference' => '(Primerjava redakcij)',
+'loadingrev' => 'nalagam različico za primerjanje',
+'lineno' => 'Vrstica $1:',
+'editcurrent' => 'Uredi trenutno različico strani',
+'selectnewerversionfordiff'=> 'Za primerjavo izberite novejšo redakcijo.',
+'selectolderversionfordiff'=> 'Za primerjavo izberite starejšo redakcijo.',
+'compareselectedversions'=> 'Primerjaj izbrani redakciji',
+'searchresults' => 'Izid iskanja',
+'searchresulttext' => 'Za več sporočil o iskanju v {{GRAMMAR:dajalnik|{{SITENAME}}}} glej [[Project:Iskanje|Iščem v {{GRAMMAR:dajalnik|{{SITENAME}}}}]].',
+'searchsubtitleinvalid' => 'Za povpraševanje "$1"',
+'badquery' => 'Napačno oblikovana iskalna poizvedba',
+'badquerytext' => 'Vaš iskalni niz žal ni bilo mogoče obdelati. Nekaj nasvetov:
+* Izogibajte se iskanju z vsemi besedami v narekovajih. Dodajte jih tudi nekaj zunaj njih, s čimer označite tudi splošno področje iskanja, ali najprej poskusite z iskanjem brez narekovajev.
+* Iščite le besede z vsaj dvema črkama, razen kadar je krajša beseda del izraza v narekovajih.',
+'matchtotals' => 'Poizvedba »$1« se ujema z $2 {{plural:$2|naslovom|naslovoma|naslovi|naslovi|naslovi}} člankov in z besedilom $3 {{plural:$3|članka|člankov|člankov|člankov|člankov}}.',
+'noexactmatch' => '\'\'\'Stran z naslovom \'\'$1\'\' ne obstaja.\'\'\' Lahko [[:$1|jo ustvarite]].',
+'titlematches' => 'Ujemanje z naslovom članka',
+'notitlematches' => 'Iskanih besed ne vsebuje noben naslov članka',
+'textmatches' => 'Ujemanje z besedilom članka',
+'notextmatches' => 'Iskanih besed ne vsebuje nobeno besedilo članka',
+'prevn' => '{{plural:$1|prejšnja|prejšnji|prejšnje|prejšnjih|prejšnjih}} $1',
+'nextn' => '{{plural:$1|naslednja|naslednji|naslednjih|naslednjih|naslednjih}} $1',
+'viewprevnext' => 'Prikazujem ($1) ($2) ($3).',
+'showingresults' => 'Prikazujem <strong>$1</strong> {{plural:$1|zadetek|zadetka|zadetke|zadetkov|zadetkov}}, začenši s št. <strong>$2</strong>.',
+'showingresultsnum' => 'Prikazujem \'\'\'$3\'\'\' {{plural:$1|zadetek|zadetka|zadetke|zadetkov|zadetkov}}, začenši s št. \'\'\'$2\'\'\'.',
+'nonefound' => '\'\'\'Opomba\'\'\': neuspešna poizvedovanja so pogosta ob iskanju vsakdanjih besed, na primer \'\'imeti\'\' in \'\'iz\'\', ki jih ni na seznamu. Ker gre za zelo pogoste besede, boste skoraj zagotovo iskali uspešneje z zožitvijo tematskega področja.',
+'powersearch' => 'Iskanje',
+'powersearchtext' => '
+Iskanje v imenskem prostoru :<br />
+$1<br />
+$2 Seznam se preusmerja Iskanje za $3 $9',
+'searchdisabled' => '<p>Zaradi hitrejšega delovanja {{GRAMMAR:rodilnik|{{SITENAME}}}} je iskanje po vsej zbirki podatkov začasno onemogočeno. Uporabite lahko Googlov ali Yahoojev iskalnik, vendar so njihovi podatki morda že zastareli.</p>',
+'blanknamespace' => '(Osnovno)',
+'preferences' => 'Nastavitve',
+'prefsnologin' => 'Niste prijavljeni',
+'prefsnologintext' => 'Za spreminjanje uporabniških nastavitev se [[Special:Userlogin|prijavite]].',
+'prefsreset' => 'Nastavitve so ponastavljene.',
+'qbsettings' => 'Nastavitve hitre vrstice',
+'changepassword' => 'Zamenjava gesla',
+'skin' => 'Koža',
+'math' => 'Prikaz matematičnega besedila',
+'dateformat' => 'Zapis datuma',
+'datedefault' => 'Kakor koli',
+'datetime' => 'Datum in čas',
+'math_failure' => 'Ni mi uspelo razčleniti',
+'math_unknown_error' => 'neznana napaka',
+'math_unknown_function' => 'neznana funkcija',
+'math_lexing_error' => 'slovarska napaka',
+'math_syntax_error' => 'skladenjska napaka',
+'math_image_error' => 'Pretvarjanje v PNG ni uspelo; preverite, ali so latex, dvips, gs, in convert pravilno nameščeni.',
+'math_bad_tmpdir' => 'Začasne mape za matematiko ne morem ustvariti ali pisati vanjo.',
+'math_bad_output' => 'Izhodne mape za matematiko ne morem ustvariti ali pisati vanjo.',
+'math_notexvc' => 'Manjka izvedbena datoteka \'texvc\'; za njeno namestitev si poglejte math/README.',
+'prefs-personal' => 'Podatki o uporabniku',
+'prefs-rc' => 'Zadnje spremembe',
+'prefs-watchlist' => 'Spisek nadzorov',
+'prefs-watchlist-days' => 'Število dni za prikaz na spisku nadzorov:',
+'prefs-watchlist-edits' => 'Število urejanj za prikaz na razširjenem spisku nadzorov:',
+'prefs-misc' => 'Druge nastavitve',
+'saveprefs' => 'Shrani',
+'resetprefs' => 'Ponastavi',
+'oldpassword' => 'Staro geslo:',
+'newpassword' => 'Novo geslo:',
+'retypenew' => 'Ponovno vpišite geslo:',
+'textboxsize' => 'Urejanje',
+'rows' => 'Razsežnosti urejevalnega polja: vrstic:',
+'columns' => 'stolpcev:',
+'searchresultshead' => 'Nastavitve poizvedovanja',
+'resultsperpage' => 'Prikazanih zadetkov na stran:',
+'contextlines' => 'Vrstic na zadetek:',
+'contextchars' => 'Znakov na vrstico:',
+'stubthreshold' => 'Prag za prikaz škrbin:',
+'recentchangescount' => 'Število naslovov v zadnjih spremembah:',
+'savedprefs' => 'Spremembe ste uspešno shranili!',
+'timezonelegend' => 'Časovni pas',
+'timezonetext' => 'Vnesite časovno razliko med vašim krajevnim in strežniškim časom (UTC).',
+'localtime' => 'Krajevni čas:',
+'timezoneoffset' => 'Izravnava¹:',
+'servertime' => 'Strežniški čas:',
+'guesstimezone' => 'Izpolni iz brskalnika',
+'allowemail' => 'Drugim uporabnikom omogoči pošiljanje e-pošte',
+'defaultns' => 'Navadno išči v naslednjih imenskih prostorih:',
+'default' => 'privzeto',
+'files' => 'Datoteke',
+'userrights-lookup-user'=> 'Upravljanje z uporabniškimi skupinami',
+'userrights-user-editname'=> 'Vpišite uporabniško ime:',
+'editusergroup' => 'Uredi uporabniške skupine',
+'userrights-editusergroup'=> 'Urejanje uporabniških skupin',
+'saveusergroups' => 'Shrani spremembe',
+'userrights-groupsmember'=> 'Član skupine:',
+'userrights-groupsavailable'=> 'Skupine, ki so na razpolago:',
+'userrights-groupshelp' => 'Izberite skupine, iz katerih želite odstraniti ali vanje dodati uporabnika.
+Neoznačene skupine ne bodo spremenjene. Skupino lahko odznačite z levim klikom in hkratnim pritiskom tipke CTRL.',
+'group' => 'Skupina:',
+'group-bot' => 'Boti',
+'group-sysop' => 'Administratorji',
+'group-bureaucrat' => 'Birokrati',
+'group-all' => '(vsi)',
+'group-sysop-member' => 'Administrator',
+'group-bureaucrat-member'=> 'Birokrat',
+'grouppage-bot' => 'Project:Boti',
+'grouppage-sysop' => 'Project:Administratorji',
+'grouppage-bureaucrat' => 'Project:Birokrati',
+'changes' => 'spremembe',
+'recentchanges' => 'Zadnje spremembe',
+'recentchangestext' => 'Na tej strani lahko spremljajte najnedavnejše spremembe wikija.',
+'rcnote' => 'Prikazujem {{plural:$1|zadnjo|zadnji|zadnje|zadnjih|zadnjih}} <strong>$1</strong> {{plural:$1|spremembo|spremembi|spremembe|sprememb|sprememb}} v {{plural:$2|zadnjem|zadnjih|zadnjih|zadnjih|zadnjih}} <strong>$2</strong> {{plural:$2|dnevu|dneh|dneh|dneh|dneh}}, kot v $3.',
+'rcnotefrom' => 'Navedene so spremembe od <b>$2</b> dalje (prikazujem jih do <b>$1</b>).',
+'rclistfrom' => 'Prikaži spremembe od $1 naprej.',
+'rcshowhideminor' => '$1 manjša urejanja',
+'rcshowhidebots' => '$1 bote',
+'rcshowhideliu' => '$1 prijavljene uporabnike',
+'rcshowhideanons' => '$1 brezimne uporabnike',
+'rcshowhidepatr' => '$1 pregledana urejanja',
+'rcshowhidemine' => '$1 moja urejanja',
+'rclinks' => 'Prikaži {{plural:$1|zadnjo|zadnji|zadnje|zadnjih|zadnjih}} $1 {{plural:$1|spremembo|spremembi|spremembe|sprememb|sprememb}} v {{plural:$2|zadnjem $2 dnevu|zadnjih $2 dneh|zadnjih $2 dneh|zadnjih $2 dneh|zadnjih $2 dneh}};<br />$3',
+'diff' => 'prim',
+'hist' => 'zgod',
+'hide' => 'skrij',
+'show' => 'prikaži',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'number_of_watching_users_pageview'=> '[temo {{plural:$1|spremlja|spremljata|spremljajo|spremlja|spremlja}} $1 {{plural:$1|uporabnik|uporabnika|uporabniki|uporabnikov|uporabnikov}}]',
+'rc_categories' => 'Omejitev na kategorije (ločite jih z »|«)',
+'rc_categories_any' => 'Katero koli',
+'upload' => 'Naloži datoteko',
+'uploadbtn' => 'Naloži datoteko',
+'reupload' => 'Naloži drugo',
+'reuploaddesc' => 'Vrnitev na obrazec za nalaganje.',
+'uploadnologin' => 'Niste prijavljeni',
+'uploadnologintext' => 'Za nalaganje datotek se [[Special:Userlogin|prijavite]].',
+'upload_directory_read_only'=> 'V mapo za nalaganje datotek ($1) spletni strežnik ne more pisati.',
+'uploaderror' => 'Napaka',
+'uploadtext' => 'Spodnji obrazec lahko uporabite za nalaganje datotek; za ogled ali iskanje že naloženih pojdite na [[Special:Imagelist|seznam naloženih datotek]]. Naložitve in izbrisi so zapisani tudi v [[Special:Log/upload|dnevniku nalaganja]].
+
+Datoteko lahko na želeno stran vključite z naslednjo skladnjo
+
+* \'\'\'<nowiki>[[{{ns:Image}}:File.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[{{ns:Image}}:File.png|alt text]]</nowiki>\'\'\'
+ali za neposredno povezavo z datoteko
+* \'\'\'<nowiki>[[{{ns:Media}}:File.ogg]]</nowiki>\'\'\'',
+'uploadlog' => 'dnevnik nalaganja',
+'uploadlogpage' => 'Dnevnik nalaganja datotek',
+'uploadlogpagetext' => 'Prikazan je seznam nedavno naloženih predstavnostnih datotek. Vsi navedeni časi so strežniški čas (UTC). Vedite, da polje »Uporabnik« razlikuje med malimi in velikimi črkami.',
+'filename' => 'Ime datoteke',
+'filedesc' => 'Povzetek',
+'fileuploadsummary' => 'Povzetek (avtor, spletni naslov vira ipd.):',
+'filestatus' => 'Položaj avtorskih pravic',
+'filesource' => 'Vir',
+'copyrightpage' => 'Project:Avtorske pravice {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'copyrightpagename' => 'Avtorske pravice {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'uploadedfiles' => 'Naložene datoteke',
+'ignorewarning' => 'Naloži kljub opozorilu',
+'ignorewarnings' => 'Prezri vsa opozorila',
+'minlength' => 'Imena datotek morajo vsebovati vsaj tri črke.',
+'illegalfilename' => 'Ime datoteke »$1« vsebuje v naslovih strani prepovedane znake. Prosimo, poskusite datoteko naložiti pod drugim imenom.',
+'badfilename' => 'Ime datoteke se je samodejno popravilo v »$1«.',
+'badfiletype' => '».$1« ni priporočeni format datotek. Priporočeni so: \'\'\'[[JPEG|JPG/JPEG]]\'\'\' za fotografije; \'\'\'[[SVG]]\'\'\' za ikone, logotipe, risbe, zemljevide, zastave ipd.; \'\'\'[[PNG]]\'\'\', kadar je na razpolago rastrska slika; \'\'\'[[GIF]]\'\'\' za animacije; \'\'\'[[Ogg]]\'\'\' ali \'\'\'[[MIDI]]\'\'\' za zvok ter \'\'\'Ogg\'\'\'/\'\'\'[[Theora]]\'\'\' za video.
+
+Opomba: včasih je zaradi varnostnih težav preprečeno nalaganje sicer dovoljenih datotečnih formatov.',
+'largefile' => 'Zaželeno je, da datoteke ne presegajo velikosti $1 bajtov; ta datoteka ima $2 bajtov.',
+'largefileserver' => 'Velikost datoteke presega strežnikove nastavitve.',
+'emptyfile' => 'Naložena datoteka je morda prazna. Do tega bi lahko prišlo zaradi slovnične napake v imenu. Ali datoteko resnično želite naložiti?',
+'fileexists' => 'Datoteka s tem imenom že obstaja. Preden jo povozite, preverite stran $1. Da preprečite navzkrižja z že obstoječimi datotekami, uporabljajte za datoteke opisna imena (npr. »Eifflov stolp, Pariz, ponoči.jpg«).',
+'fileexists-forbidden' => 'Datoteka s tem imenom že obstaja in je ni mogoče prepisati. Poskusite svojo datoteko naložiti pod drugim imenom. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Datoteka s tem imenom že obstaja v skupnem repozitoriju datotek. Prosimo, vrnite se in naložite svojo datoteko pod drugim imenom.
+[[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Datoteko ste uspešno naložili',
+'fileuploaded' => 'Datoteka »$1« se je uspešno naložila.
+Prosimo, sledite povezavi »$2« na opisno stran datoteke in nanjo dodajte naslednje podatke: opis , vir oziroma imetnika avtorskih pravic in licenco datoteke. Če gre za sliko, jo lahko vstavite z naslednjo skladnjo:<br /><nowiki>[[</nowiki>{{ns:Image}}:$1|thumb|Opis<nowiki>]]</nowiki>',
+'uploadwarning' => 'Opozorilo!',
+'savefile' => 'Shrani datoteko',
+'uploadedimage' => '- naložena datoteka »[[$1]]«',
+'uploaddisabled' => 'Nalaganje je onemogočeno',
+'uploaddisabledtext' => 'Nalaganje datotek je na tem wikiju onemogočeno.',
+'uploadscripted' => 'Datoteka vsebuje HTML- ali skriptno kodo, ki bi jo lahko brskalnik razlagal napačno.',
+'uploadcorrupt' => 'Datoteka je poškodovana ali pa ima napačno končnico. Prosimo, preverite jo in znova naložite.',
+'uploadvirus' => 'Datoteka morda vsebuje virus! Podrobnosti: $1',
+'sourcefilename' => 'Ime izvorne datoteke',
+'destfilename' => 'Ime ciljne datoteke',
+'filewasdeleted' => 'Datoteka s tem imenom je bila nekoč že naložena in potem izbrisana. Preden jo znova naložite, preverite $1.',
+'license' => 'Dovoljenje',
+'nolicense' => 'Nobeno (opomba: datoteka bo morda izbrisana)',
+'imagelist' => 'Seznam datotek',
+'imagelisttext' => 'Prikazujem $1 $2 {{plural:$1|razvrščeno datoteko|razvrščeni datoteki|razvrščene datoteke|razvrščenih datotek|razvrščenih datotek}}.',
+'imagelistforuser' => 'To prikaže le slike, ki jih je naložil uporabnik »$1«.',
+'getimagelist' => 'pridobivam seznam datotek',
+'ilsubmit' => 'Išči',
+'showlast' => 'Prikaži {{plural:$1|zadnjo|zadnji|zadnje|zadnjih|zadnjih}} $1 $2 {{plural:$1|razvrščeno|razvrščeni|razvrščene|razvrščenih|razvrščenih}} {{plural:$1|datoteko|datoteki|datoteke|datotek|datotek}}.',
+'byname' => 'po imenu',
+'bydate' => 'po datumu',
+'bysize' => 'po velikosti',
+'imgdelete' => 'briši',
+'imgdesc' => 'opis',
+'imglegend' => 'Napotek: (opis) = prikaži/uredi opis datoteke.',
+'imghistory' => 'Prejšnje različice',
+'revertimg' => 'vrni',
+'deleteimg' => 'briši',
+'deleteimgcompletely' => 'briši',
+'imghistlegend' => 'Napotek: (tren) = trenutna datoteka, (briši) = briši zadnjo različico, (vrni) = vrni datoteko na zadnjo različico.
+<br />\'\'Za ogled določenega dne naložene datoteke kliknite datum\'\'.',
+'imagelinks' => 'Strani z datoteko',
+'linkstoimage' => 'Datoteka je del naslednjih strani slovenske {{GRAMMAR:rodilnik|{{SITENAME}}}} (strani drugih projektov niso navedene):',
+'nolinkstoimage' => 'Z datoteko se ne povezuje nobena stran.',
+'sharedupload' => 'Datoteka se s tega mesta lahko uporabi tudi v drugih projektih.',
+'shareduploadwiki' => 'Nadaljnje informacije najdete na strani $1.',
+'shareduploadwiki-linktext'=> 'Opisna stran datoteke',
+'noimage' => 'Datoteka s tem imenom ne obstaja; lahko jo $1.',
+'noimage-linktext' => 'naložite',
+'uploadnewversion-linktext'=> 'Naložite novo različico datoteke',
+'mimesearch' => 'Iskanje po MIME-tipu',
+'mimetype' => 'MIME-tip:',
+'download' => 'naloži',
+'unwatchedpages' => 'Nespremljane strani',
+'listredirects' => 'Seznam preusmeritev',
+'unusedtemplates' => 'Osirotele predloge',
+'unusedtemplatestext' => 'Naslednji seznam podaja vse strani v imenskem prostoru predlog, ki niso vključene v nobeno stran. Preden jih izbrišete, preverite še druge povezave nanje.',
+'unusedtemplateswlh' => 'druge povezave',
+'randomredirect' => 'Naključna preusmeritev',
+'statistics' => 'Statistika',
+'sitestats' => 'Statistika {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'userstats' => 'Uporabniška statistika',
+'sitestatstext' => 'V podatkovni zbirki je skupno \'\'\'$1\'\'\' strani.
+Med te so vštete tudi \'\'pogovorne\'\' strani, strani o {{GRAMMAR:mestnik|{{SITENAME}}}}, najmanjše \'\'škrbinske\'\' strani, preusmeritve in še druge, ki niso članki. Če izključimo te zadnje, obstaja \'\'\'$2\'\'\' strani; ki so po vsej verjetnosti prave strani z vsebino.
+
+Naloženih je \'\'\'$8\'\'\' {{plural:{{NUMBEROFFILES}}|datoteka|datoteki|datoteke|datotek|datotek}}.
+
+Od postavitve wikija je bilo opravljenih \'\'\'$3\'\'\' pregledov in \'\'\'$4\'\'\' urejanj strani.
+To da skupaj povprečno \'\'\'$5\'\'\' urejanj na stran in \'\'\'$6\'\'\' pogledov na urejanje.
+
+Dolžina [http://meta.wikimedia.org/wiki/Help:Job_queue čakalne vrste delovnih nalog]: \'\'\'$7\'\'\'.',
+'userstatstext' => 'Registriralo se je \'\'\'$1\'\'\' uporabnikov. Med temi je \'\'\'$2\'\'\' (oz. \'\'\'$4%\'\'\') administratorjev (glej $3).',
+'disambiguations' => 'Razločitvene strani',
+'disambiguationspage' => 'Template:Razločitev',
+'disambiguationstext' => 'Naslednji članki povezujejo na <i>razločitveno stran</i>. Morali bi povezovati na pripadajoči članek.<br />Stran je razločitvena, če je povezana z $1.<br />Povezave iz drugih imenskih prostorov tu <i>niso</i> prikazane.',
+'doubleredirects' => 'Dvojne preusmeritve',
+'doubleredirectstext' => '<b>Pozor:</b> seznam morda vsebuje neprave člane. To navadno pomeni, da pod prvim ukazom #REDIRECT obstaja dodatno besedilo s povezavami.<br />
+Vsaka vrstica vsebuje povezave k prvi in drugi preusmeritvi ter prvo vrstico besedila druge preusmeritve. To navadno da pravi ciljni članek, h kateremu naj kaže prva preusmeritev.',
+'brokenredirects' => 'Pretrgane preusmeritve',
+'brokenredirectstext' => 'Naslednje preusmeritve kažejo na neobstoječe strani.',
+'nbytes' => '$1 {{plural:$1|zlog|zloga|zlogi|zlogov|zlogov}}',
+'ncategories' => '$1 {{PLURAL:$1|category|kategorij}}',
+'nlinks' => '$1 {{plural:$1|povezava|povezavi|povezave|povezav|povezav}}',
+'nmembers' => '$1 {{plural:$1|element|elementa|elementi|elementov|elementov}}',
+'nrevisions' => '$1 {{plural:$1|redakcija|redakciji|redakcije|redakcij|redakcij}}',
+'nviews' => '$1-krat pregledano',
+'lonelypages' => 'Osirotele strani',
+'uncategorizedpages' => 'Nekategorizirane strani',
+'uncategorizedcategories'=> 'Nekategorizirane kategorije',
+'uncategorizedimages' => 'Nekategorizirane slike',
+'unusedcategories' => 'Osirotele kategorije',
+'unusedimages' => 'Osirotele datoteke',
+'popularpages' => 'Priljubljene strani',
+'wantedcategories' => 'Želene kategorije',
+'wantedpages' => 'Želene strani',
+'mostlinked' => 'Strani, na katere se največ povezuje',
+'mostlinkedcategories' => 'Kategorije z največ elementi',
+'mostcategories' => 'Članki z največ kategorijami',
+'mostimages' => 'Najbolj uporabljane datoteke',
+'mostrevisions' => 'Največkrat urejane strani',
+'allpages' => 'Vse strani',
+'prefixindex' => 'Iskanje po začetnih črkah',
+'randompage' => 'Naključni članek',
+'shortpages' => 'Kratke strani',
+'longpages' => 'Dolge strani',
+'deadendpages' => 'Članki brez delujočih povezav',
+'listusers' => 'Seznam uporabnikov',
+'specialpages' => 'Posebne strani',
+'spheading' => 'Posebne strani za vse uporabnike',
+'restrictedpheading' => 'Omejene posebne strani',
+'recentchangeslinked' => 'Sorodne spremembe',
+'rclsub' => '(na straneh, na katere se povezuje »$1«)',
+'newpages' => 'Nove strani',
+'ancientpages' => 'Najdlje nespremenjeni članki',
+'intl' => 'Medjezikovne povezave',
+'move' => 'Prestavi',
+'movethispage' => 'Prestavi stran',
+'unusedimagestext' => '<p>Prosimo, upoštevajte, da lahko druge spletne strani datoteko uporabljajo neposredno z navedbo spletnega naslova. Zato so datoteke lahko navedene, čeprav se uporabljajo.</p>',
+'unusedcategoriestext' => 'Naslednje strani kategorij obstajajo, vendar jih ne uporablja noben članek ali druga kategorija.',
+'booksources' => 'Prepoznava ISBN-številk',
+'categoriespagetext' => 'V wikiju obstajajo naslednje kategorije.',
+'data' => 'Podatki',
+'userrights' => 'Upravljanje s pravicami uporabnikov',
+'groups' => 'Uporabniške skupine',
+'booksourcetext' => 'Prikazan je seznam strani, ki prodajajo nove ali rabljene knjige in kjer lahko dobite dodatne podatke o iskanih knjigah. {{SITENAME}} ne služi z nobenim med posli in spisek ni kazalnik njihovih uspehov.',
+'alphaindexline' => '$1 do $2',
+'version' => 'Različica',
+'log' => 'Dnevniki',
+'alllogstext' => 'Združeno so prikazani dnevniki sprememb uporabniških pravic, preimenovanj uporabnikov, nalaganja predstavnostnih datotek, prestavljanja in zaščite strani, brisanja, registracij uporabnikov, sprememb položaja botov ter blokiranja in deblokiranja uporabnikov. Pogled lahko zožite z izbiro dnevnika, uporabniškega imena ali strani. Vedite, da polje »Uporabnik« razlikuje med malimi in velikimi črkami.',
+'logempty' => 'O tej strani ni v dnevniku ničesar.',
+'nextpage' => 'Naslednja stran ($1)',
+'allpagesfrom' => 'Prikaži strani, ki se začnejo na:',
+'allarticles' => 'Vsi članki',
+'allinnamespace' => 'Vse strani (imenski prostor $1)',
+'allnotinnamespace' => 'Vse strani (brez imenskega prostora $1)',
+'allpagesprev' => 'Predhodna',
+'allpagesnext' => 'Naslednja',
+'allpagessubmit' => 'Pojdi',
+'allpagesprefix' => 'Prikaži strani z začetnimi črkami:',
+'mailnologin' => 'Manjka naslov pošiljatelja',
+'mailnologintext' => 'Za pošiljanje pošte se [[Special:Userlogin|prijavite]] in v [[Special:Preferences|nastavitvah]] vpišite veljaven \'\'\'overjen\'\'\' e-poštni naslov.',
+'emailuser' => 'Pošlji uporabniku e-pismo',
+'emailpage' => 'Pošlji uporabniku e-pismo',
+'emailpagetext' => 'S spodnjim obrazcem lahko uporabniku pošljete e-poštno sporočilo. Da bo prejemnik lahko odgovoril neposredno vam, bo v glavi sporočila zapisan \'\'\'vaš e-poštni naslov\'\'\' (kot ste ga vpisali v [[Special:Preferences|uporabniških nastavitvah]]).',
+'usermailererror' => 'Predmet e-pošte je vrnil napako:',
+'defemailsubject' => 'Elektronska pošta {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'noemailtitle' => 'Ni e-poštnega naslova.',
+'noemailtext' => 'Uporabnik ni navedel veljavnega e-poštnega naslova ali pa elektronske pošte ne želi prejemati.',
+'emailfrom' => 'Od',
+'emailto' => 'Za',
+'emailsubject' => 'Predmet',
+'emailmessage' => 'Sporočilo',
+'emailsend' => 'Pošlji',
+'emailsent' => 'E-pismo je poslano!',
+'emailsenttext' => 'E-pismo je poslano.',
+'watchlist' => 'Spisek nadzorov',
+'nowatchlist' => 'Vaš spisek nadzorov je prazen.',
+'watchlistcount' => '\'\'\'Na spisku nadzorov imate, vštevši pogovorne strani, $1 {{plural:$1|predmet|predmeta|predmete|predmetov|predmetov}}.\'\'\'',
+'clearwatchlist' => 'Izprazni spisek nadzorov',
+'watchlistcleartext' => 'Jih resnično želite odstraniti?',
+'watchlistclearbutton' => 'Izprazni spisek nadzorov',
+'watchlistcleardone' => 'Spisek nadzorov je izpraznjen. Odstranjenih je bilo $1 predmetov.',
+'watchnologin' => 'Niste prijavljeni',
+'watchnologintext' => 'Za urejanje spiska nadzorov se [[Special:Userlogin|prijavite]].',
+'addedwatch' => 'Dodano na spisek nadzorov',
+'addedwatchtext' => 'Stran »\'\'\'<nowiki>$1</nowiki>\'\'\'« je bila dodana na vaš [[Special:Watchlist|spisek nadzorov]], kjer bodo odslej navedene njene morebitne spremembe in spremembe pripadajoče pogovorne strani. Za lažjo izbiro bodo tudi v [[Special:Recentchanges|seznamu zadnjih sprememb]] prikazane <b>krepko</b>. Če jo želite odstraniti s spiska, kliknite zavihek »Prenehaj opazovati«.',
+'removedwatch' => 'Odstranjena s spiska nadzorov',
+'removedwatchtext' => 'Stran »<nowiki>$1</nowiki>« je odstranjena z vašega spiska nadzorov.',
+'watch' => 'Opazuj',
+'watchthispage' => 'Opazuj stran',
+'unwatch' => 'Prenehaj opazovati',
+'unwatchthispage' => 'Prenehaj opazovati stran',
+'notanarticle' => 'Ni članek',
+'watchnochange' => 'V prikazanem časovnem obdobju se ni spremenila nobena med nadzorovanimi stranmi.',
+'watchdetails' => '{{Site notice}}
+Spremljate <strong>$1</strong> (pogovorne strani niso vštete). Svoj spisek nadzorov lahko [[Special:Watchlist/edit|pregledate in uredite]] ali pa z njega [[Special:Watchlist/clear|odstranite vse predmete]].',
+'wlheader-enotif' => '* Obveščanje po elektronski pošti je omogočeno.',
+'wlheader-showupdated' => '* Od vašega zadnjega ogleda spremenjene strani so prikazanje \'\'\'krepko\'\'\'.',
+'watchmethod-recent' => 'med nedavnimi urejanji iščem spremljane strani',
+'watchmethod-list' => 'med spremljanimi stranmi iščem nedavna urejanja',
+'removechecked' => 'Odstrani označene strani s spiska nadzorov',
+'watchlistcontains' => 'Spremljate $1 {{plural:$1|stran|strani|strani|strani|strani}}.',
+'watcheditlist' => 'Na naslednjem seznamu so po abecedi navedene strani na vašem spisku nadzorov. Če želite katero odstraniti, jo označite in kliknite gumb \'\'Odstrani označene strani s spiska nadzorov\'\' na dnu strani. Odstranitev strani pomeni tudi odstranitev njene pogovorne strani in obratno. Če je na seznamu katera izmed povezav rdeča, je bila stran izbrisana, vendar jo lahko še vedno spremljate.',
+'removingchecked' => 'Odstranjevanje označenih strani s spiska nadzorov ...',
+'couldntremove' => '\'$1\' ste s svojega spiska nadzorov že odstranili.
+
+Ste osvežili to stran? Če je tako, lahko svoj spisek nadzorov varno osvežite s klikom povezave »spisek nadzorov« na vrhu zaslona.
+<br />',
+'iteminvalidname' => 'Težava z izbiro \'$1\', neveljavno ime ...',
+'wlnote' => 'Navedenih je {{plural:$1|zadnja|zadnji|zadnje|zadnjih|zadnjih}} $1 {{plural:$1|sprememba|spremembi|spremembe|sprememb}} v {{plural:$2|zadnji|zadnjih|zadnjih|zadnjih|zadnjih}} <b>$2</b> {{plural:$2|uri|urah|urah|urah|urah}}.',
+'wlshowlast' => 'Prikaži zadnjih $1 ur; $2 dni; $3;',
+'wlsaved' => 'To je shranjena različica vašega spiska nadzorov. Da je obremenitev strežnikov čim manjša, se spisek nadzorov osveži enkrat na dan.',
+'wlhideshowown' => '$1 moja urejanja.',
+'wlhideshowbots' => '$1 urejanja botov',
+'wldone' => 'Končano.',
+'enotif_mailer' => '{{SITENAME}} - obvestilni poštar',
+'enotif_reset' => 'Označi vse strani kot prebrane',
+'enotif_newpagetext' => 'To je nova stran.',
+'changed' => 'spremenjena',
+'created' => 'ustvarjena',
+'enotif_subject' => 'Stran {{GRAMMAR:rodilnik|{{SITENAME}}}} $PAGETITLE je $CHANGEDORCREATED $PAGEEDITOR',
+'enotif_lastvisited' => 'Za spremembe po vašem zadnjem obisku glejte $1.',
+'enotif_body' => '$WATCHINGUSERNAME,
+
+stran v {{GRAMMAR:dajalnik|{{SITENAME}}}} $PAGETITLE je bila $PAGEEDITDATE $CHANGEDORCREATED s strani $PAGEEDITOR,
+za trenutno redakcijo glejte {{fullurl:$PAGETITLE_RAWURL}}
+
+$NEWPAGE
+
+Urejevalčev povzetek: $PAGESUMMARY $PAGEMINOREDIT
+
+Navežite stik z urejevalcem:
+e-pošta {{fullurl:Special:Emailuser|target=$PAGEEDITOR_RAWURL}}
+wiki {{fullurl:User:$PAGEEDITOR_RAWURL}}
+
+Nadaljnjih obvestil do obiska strani ne boste prejemali. Na spisku nadzorov lahko znova nastavite zastavice obveščanj za vse spremljane strani.
+
+ Vaš opozorilni sistem slovenskega {{GRAMMAR:rodilnik|{{SITENAME}}}}
+
+--
+Za spremembo nastavitev spiska nadzorov obiščite
+{{fullurl:Special:Watchlist|edit=yes}}
+
+Povratna sporočila in pomoč:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Briši stran',
+'confirm' => 'Potrdi',
+'excontent' => 'vsebina: \'$1\'',
+'excontentauthor' => 'vsebina: \'$1\' (edini urejevalec pa \'$2\')',
+'exbeforeblank' => 'vsebina pred brisanjem: \'$1\'',
+'exblank' => 'prazna stran',
+'confirmdelete' => 'Potrdi brisanje',
+'deletesub' => '(Brišem »$1«)',
+'historywarning' => 'OPOZORILO: stran, ki jo želite izbrisati, ima zgodovino:',
+'confirmdeletetext' => 'Iz zbirke podatkov boste izbrisali stran ali sliko skupaj z vso njeno zgodovino.
+Prosimo, \'\'\'potrdite\'\'\', da to resnično želite, da razumete posledice dejanja in da se ravnate po [[Project:Pravila|pravilih]].',
+'actioncomplete' => 'Poseg je končan',
+'deletedtext' => '»\'\'\'$1\'\'\'« je bila izbrisana.
+Za zapise nedavnih brisanj glej $2.',
+'deletedarticle' => 'je izbrisal(-a) »$1«',
+'dellogpage' => 'Dnevnik brisanja',
+'dellogpagetext' => 'Prikazan je seznam nedavnih brisanj z navedenim strežniškim časom (UTC). Vedite, da polje »Uporabnik« razlikuje med malimi in velikimi črkami.',
+'deletionlog' => 'dnevnik brisanja',
+'reverted' => 'Obnova prejšnje redakcije',
+'deletecomment' => 'Razlog za brisanje',
+'imagereverted' => 'Prejšnjo redakcijo ste uspešno obnovili',
+'rollback' => 'Vrni spremembe',
+'rollback_short' => 'Vrni',
+'rollbacklink' => 'vrni',
+'rollbackfailed' => 'Vrnitev ni uspela.',
+'cantrollback' => 'Urejanja ne morem vrniti; zadnji urejevalec je hkrati edini.',
+'alreadyrolled' => 'Ne morem vrniti zadnje spremembe [[:$1]]
+od uporabnika [[Uporabnik:$2|$2]] ([[Pogovor z uporabnikom:$2|Pogovor]]); nekdo drug je že spremenil ali vrnil članek.
+
+Zadnja sprememba od uporabnika [[Uporabnik:$3|$3]] ([[Pogovor z uporabnikom:$3|Pogovor]]).',
+'editcomment' => 'Pripomba k spremembi: »\'\'$1\'\'«.',
+'revertpage' => 'vrnitev sprememb uporabnika »[[Special:Contributions/$2|$2]]« ([[User talk:$2|pogovor]]) na zadnje urejanje uporabnika »$1«',
+'sessionfailure' => 'Vaša prijava ni uspela; da bi preprečili ugrabitev seje, je bilo dejanje preklicano. Prosimo, izberite »Nazaj« in ponovno naložite stran, s katere prihajate, nato poskusite znova.',
+'protectlogpage' => 'Dnevnik zaščit strani',
+'protectlogtext' => 'Prikazan je seznam zaščit in odstranitev zaščit strani. Za več podatkov glejte [[Project:Zaščitena stran]] in [[Project:Pravila zaščite]]. Vedite, da polje »Uporabnik« razlikuje med malimi in velikimi črkami.',
+'protectedarticle' => 'Zaščita strani "[[$1]]"',
+'unprotectedarticle' => 'Zaščita strani $1 je odstranjena.',
+'protectsub' => '(Zaščita strani »$1«)',
+'confirmprotecttext' => 'Ali stran res želite \'\'\'zaščititi\'\'\'?',
+'confirmprotect' => 'Potrdite zaščito',
+'protectmoveonly' => 'Zaščiti LE PRED PREMIKANJEM',
+'protectcomment' => 'Razlog:',
+'unprotectsub' => '(Odstranjujem zaščito strani »$1«)',
+'confirmunprotecttext' => 'Ali res želite \'\'\'odstraniti\'\'\' zaščito strani?',
+'confirmunprotect' => 'Potrdite odstranitev zaščite',
+'unprotectcomment' => 'Razlog za odstranitev zaščite',
+'protect-unchain' => 'Deblokiraj dovoljenja za premikanje',
+'protect-text' => 'Tu si lahko ogledate in spremenite raven zaščitenosti strani \'\'\'$1\'\'\'.',
+'protect-viewtext' => 'S svojim računom ne morete spreminjati ravni zaščitenosti strani. Trenutne nastavitve za stran »[[$1]]« so naslednje:',
+'protect-default' => 'Omogoči urejanje vsem uporabnikom',
+'protect-level-autoconfirmed'=> 'Blokiraj neregistrirane uporabnike',
+'protect-level-sysop' => 'Blokiraj vse uporabnike (razen administratorjev)',
+'restriction-edit' => 'Urejanje',
+'restriction-move' => 'Prestavljanje',
+'undelete' => 'Obnovi izbrisano stran',
+'undeletepage' => 'Prikaži izbrisane strani in jih obnovi',
+'viewdeletedpage' => 'Pregled izbrisanih strani',
+'undeletepagetext' => 'Naslednje strani so izbrisane, vendar so še vedno v arhivu in jih lahko obnovite. Arhiv je treba občasno počistiti.',
+'undeleteextrahelp' => 'Da bi obnovili celotno stran z vso njeno zgodovino, pustite vsa potrditvena polja prazna in kliknite \'\'\'\'\'Obnovi\'\'\'\'\'. Če želite obnoviti le določene redakcije strani, pred klikom gumba \'\'\'\'\'Obnovi\'\'\'\'\' označite ustrezna potrditvena polja. Klik gumba \'\'\'\'\'Ponastavi\'\'\'\'\' bo izpraznil polje za vnos razloga in vsa potrditvena polja.
+
+Prosimo, ravnajte se po [[Project:Pravila obnove|pravilih obnove strani]] in navedite ustrezen razlog.',
+'undeletearticle' => 'Obnovite izbrisani članek',
+'undeleterevisions' => '{{plural:$1|Arhivirana je|Arhivirani sta|Arhivirane so|Arhiviranih je|Arhiviranih ni}} $1 {{plural:$1|redakcija|redakciji|redakcije|redakcij|redakcij}}',
+'undeletehistory' => 'Z obnovo strani se bodo po privzetem obnovile tudi vse pripadajoče redakcije. Če se želite temu izogniti, označite le želene.
+
+Kjer je bila po brisanju ustvarjena nova stran s tem imenom, se trenutna redakcija obstoječe strani ne bo samodejno zamenjala, temveč se bodo obnovljene redakcije pojavile v prejšnji zgodovini. Pazite, da se temu izognete, razen seveda, kadar resnično nameravate združiti zgodovini obeh strani.',
+'undeletehistorynoadmin'=> 'Stran je izbrisana. Razlog za izbris je skupaj s podrobnostmi o uporabnikih, ki so jo urejali pred izbrisom, naveden v prikazanem povzetku. Dejansko besedilo izbrisanih redakcij je dostopno le administratorjem.',
+'undeleterevision' => 'Redakcija uporabnika $1 je izbrisana',
+'undeletebtn' => 'Obnovi',
+'undeletereset' => 'Ponastavi',
+'undeletecomment' => 'Razlog:',
+'undeletedarticle' => 'je obnovil(-a) »$1«',
+'undeletedrevisions' => 'obnovljeno: $1 {{plural:$1|redakcija|redakciji|redakcije|redakcij|redakcij}}',
+'undeletedfiles' => 'Obnovili ste $1 {{PLURAL:datoteka|datoteki|datoteke|datotek|datotek}}',
+'cannotundelete' => 'Obnova ni uspela. Morda je stran obnovil že kdo drug.',
+'undeletedpage' => '<big>\'\'\'Obnovili ste stran \'$1\'.\'\'\'</big>
+
+Nedavna brisanja in obnove so zapisani v [[Special:Log/delete|dnevniku brisanja]].',
+'namespace' => 'Imenski prostor:',
+'invert' => 'Obrni izbor',
+'contributions' => 'Uporabnikovi prispevki',
+'mycontris' => 'Prispevki',
+'contribsub' => 'Uporabnik: $1',
+'nocontribs' => 'Ne najdem nobene merilom ustrezajoče spremembe.',
+'ucnote' => 'Prikazujem {{plural:$1|zadnje|zadnji|zadnje|zadnjih|zadnjih}} <strong>$1</strong> uporabnikovih {{plural:$1|urejanj|urejanji|urejanja|urejanj|urejanj}} v {{plural:$2|zadnjem|zadnjih|zadnjih|zadnjih|zadnjih}} <strong>$2</strong> {{plural:$2|dnevu|dneh|dneh|dneh|dneh}}.',
+'uclinks' => 'Prikaži {{plural:$1|zadnjo|zadnji|zadnje|zadnjih}} $1 {{plural:spremembo|spremembi|spremembe|sprememb|sprememb}}; prikaži {{plural:$2|zadnji|zadnja|zadnje|zadnjih|zadnjih}} $2 {{plural:$2|dan|dni|dni|dni|dni}}.',
+'uctop' => ' (vrh)',
+'newbies' => 'novinci',
+'sp-newimages-showfrom' => 'Prikaži datoteke, naložene od $1 naprej',
+'sp-contributions-newest'=> 'Najnovejši',
+'sp-contributions-oldest'=> 'Najstarejši',
+'sp-contributions-newer'=> '{{plural:$1|novejših|novejša|novejše|novejših|novejših}} $1',
+'sp-contributions-older'=> '{{plural:$1|starejših|starejša|starejše|starejših|starejših}} $1',
+'sp-contributions-newbies-sub'=> 'Prispevki novincev',
+'whatlinkshere' => 'Kaj se povezuje sem',
+'notargettitle' => 'Ni cilja',
+'notargettext' => 'Niste navedli ciljne strani ali uporabnika za izvedbo ukaza.',
+'linklistsub' => '(Seznam povezav)',
+'linkshere' => 'Sem kažejo naslednje strani:',
+'nolinkshere' => 'Sem ne kaže nobena stran.',
+'isredirect' => 'preusmeritvena stran',
+'istemplate' => 'vključitev',
+'blockip' => 'Blokiranje IP-naslova ali uporabniškega imena',
+'blockiptext' => 'Naslednji obrazec vam omogoča, da določenemu IP-naslovu ali uporabniškemu imenu preprečite urejanje. To storimo le zaradi zaščite pred nepotrebnim uničevanjem in po [[Project:Pravila blokiranja|pravilih]]. Vnesite tudi razlog, \'\'na primer\'\' seznam strani, ki jih je uporabnik po nepotrebnem kvaril.',
+'ipaddress' => 'IP-naslov',
+'ipadressorusername' => 'IP-naslov ali uporabniško ime',
+'ipbexpiry' => 'Pretek',
+'ipbreason' => 'Razlog',
+'ipbsubmit' => 'Blokiraj naslov',
+'ipbother' => 'Drugačen čas',
+'ipboptions' => 'nedoločen čas:indefinite,15 minut:15 minutes,1 uro:1 hour,3 ure:3 hours,1 dan:1 day,2 dni:2 days,3 dni:3 days,1 teden:1 week,2 tedna:2 weeks,1 mesec:1 month,3 mesece:3 months,6 mesecev:6 months,1 leto:1 year,neomejeno dolgo:infinite',
+'ipbotheroption' => 'drugo',
+'badipaddress' => 'Neveljaven IP-naslov ali uporabniško ime.',
+'blockipsuccesssub' => 'Blokiranje je uspelo',
+'blockipsuccesstext' => 'IP-naslov ali uporabniški račun »[[User:$1|$1]]« ([[User talk$1|pogovor]]) je blokiran.
+
+*Preglejte [[Special:Contributions/$1|prispevke s tega naslova/uporabniškega računa]].
+*Preglejte [[Special:Ipblocklist|seznam blokiranih IP-naslovov]].
+*Preglejte [[Special:Log/block|dnevnik blokiranja]], kjer so navedeni ukrepi drugih administratorjev v zvezi s tem uporabnikom.
+
+Ne pozabite blokiranemu uporabniku na njegovi [[User talk:$1|pogovorni strani]] razložiti, zakaj ste ga blokirali.',
+'unblockip' => 'Omogočite urejanje IP-naslovu',
+'unblockiptext' => 'Z naslednjim obrazcem lahko obnovite možnost urejanja z blokiranega IP-naslova ali uporabniškega računa.',
+'ipusubmit' => 'Deblokiraj naslov',
+'ipblocklist' => 'Seznam blokiranih IP-naslovov',
+'blocklistline' => '$1, $2 je blokiral(-a) $3 ($4)',
+'infiniteblock' => 'neomejen čas',
+'expiringblock' => 'preteče: $1',
+'ipblocklistempty' => 'Seznam blokiranih uporabnikov je prazen.',
+'blocklink' => 'blokiraj',
+'unblocklink' => 'deblokiraj',
+'contribslink' => 'prispevki',
+'autoblocker' => 'Ker si delite IP-naslov z »$1«, vam je urejanje samodejno onemogočeno. Razlog: »$2«.',
+'blocklogpage' => 'Dnevnik blokiranja',
+'blocklogentry' => 'uporabnika »$1« sem blokiral(-a) za $2',
+'blocklogtext' => 'Prikazan je dnevnik blokiranja in deblokiranja uporabnikov. Samodejno blokirani IP-naslovi niso navedeni. Trenutno veljavna blokiranja so navedena na [[Special:Ipblocklist|seznamu blokiranih IP-naslovov]].',
+'unblocklogentry' => 'je deblokiral(-a) »$1«',
+'range_block_disabled' => 'Možnost administratorjev za blokiranje urejanja IP-razponom je onemogočena.',
+'ipb_expiry_invalid' => 'Neveljaven čas preteka',
+'ip_range_invalid' => 'Neveljaven IP-razpon.',
+'proxyblocker' => 'Blokator posredniških strežnikov',
+'proxyblockreason' => 'Ker uporabljate odprti posredniški strežnik, je urejanje z vašega IP-naslova preprečeno. Gre za resno varnostno težavo, o kateri obvestite svojega internetnega ponudnika.',
+'proxyblocksuccess' => 'Storjeno.',
+'sorbsreason' => 'Vaš IP-naslov je v [http://www.sorbs.net SORBS] DNSBL uvrščen med odprte posredniške strežnike.',
+'sorbs_create_account_reason'=> 'Vaš IP-naslov je v [http://www.sorbs.net SORBS] DNSBL naveden kot odprti posredniški strežnik. Računa zato žal ne morete ustvariti.',
+'lockdb' => 'Zakleni zbirko podatkov',
+'unlockdb' => 'Odkleni zbirko podatkov',
+'lockdbtext' => 'Zaklenitev zbirke podatkov bo vsem uporabnikom preprečila možnost urejanja strani, spreminjanja nastavitev, urejanja spiska nadzorov in drugih stvari, ki zahtevajo spremembe zbirke podatkov. Prosimo, potrdite, da jo resnično želite zakleniti in da jo boste po končanem vzdrževanju spet odklenili.',
+'unlockdbtext' => 'Odklenitev zbirke podatkov bo vsem uporabnikom obnovila možnost urejanja strani, spreminjanja nastavitev, urejanja seznamov nadzorov in drugih stvari, ki zahtevajo spremembe zbirke. Prosimo, potrdite nedvomni namen.',
+'lockconfirm' => 'Da, zbirko podatkov želim zakleniti.',
+'unlockconfirm' => 'Da, zbirko podatkov želim odkleniti.',
+'lockbtn' => 'Zakleni zbirko podatkov',
+'unlockbtn' => 'Odkleni zbirko podatkov',
+'locknoconfirm' => 'Namere niste potrdili.',
+'lockdbsuccesssub' => 'Zbirko podatkov ste uspešno zaklenili',
+'unlockdbsuccesssub' => 'Zbirka podatkov je odklenjena',
+'lockdbsuccesstext' => 'Podatkovna baza {{GRAMMAR:rodilnik|{{SITENAME}}}} je bila zaklenjena.
+<br />Ne pozabite odkleniti, ko boste končali z vzdrževanjem.',
+'unlockdbsuccesstext' => 'Zbirka podatkov {{GRAMMAR:rodilnik|{{SITENAME}}}} je spet odklenjena.',
+'makesysoptitle' => 'Povišaj uporabnika v administratorja',
+'makesysoptext' => 'Obrazec uporabljajo birokrati za povišanje navadnih uporabnikov v administratorje.
+Da izbranega uporabnika povišate, vpišite njegovo ime v okence in pritisnite gumb.',
+'makesysopname' => 'Ime uporabnika:',
+'makesysopsubmit' => 'Povišanje uporabnika v administratorja',
+'makesysopok' => '<b>Uporabnik »$1« je odslej administrator</b>',
+'makesysopfail' => '<b>Uporabnika »$1« ni mogoče povišati v administratorja. (Ste uporabniško ime pravilno vnesli?)</b>',
+'setbureaucratflag' => 'Nastavi za birokrata',
+'rightslog' => 'Dnevnik_uporabniških_pravic',
+'rightslogtext' => 'Prikazan je dnevnik sprememb uporabniških pravic.',
+'rightslogentry' => '- sprememba pravic uporabnika $1 iz $2 v $3',
+'rights' => 'Pravice:',
+'set_user_rights' => 'Uredi uporabnikove pravice',
+'user_rights_set' => '<strong>Pravice uporabnika »$1« so osvežene</strong>',
+'set_rights_fail' => '<strong>Pravic uporabnika »$1« ni mogoče spremeniti. Ste ime pravilno vnesli?</strong>',
+'makesysop' => 'Povišanje uporabnikov v administratorje',
+'already_sysop' => 'Uporabnik je že administrator!',
+'already_bureaucrat' => 'Uporabnik je že birokrat!',
+'rightsnone' => '(nobeno)',
+'movepage' => 'Prestavitev strani',
+'movepagetext' => 'Z naslednjim obrazcem lahko stran preimenujete in hkrati prestavite tudi vso njeno zgodovino. Dosedanja stran se bo spremenila v preusmeritev na prihodnje mesto.
+
+\'\'\'Povezave na dosedanji naslov strani se ne bodo spremenile, zato vas prosimo, da po prestavitvi strani z uporabo pripomočka »Kaj se povezuje sem« popravite vse dvojne preusmeritve, ki bodo morda nastale.\'\'\' Odgovorni ste, da bodo povezave še naprej kazale na prava mesta.
+
+Kjer stran z izbranim novim imenom že obstaja, dejanje \'\'\'ne\'\'\' bo izvedeno, razen če je sedanja stran prazna ali preusmeritvena in brez zgodovine urejanj. To pomeni, da lahko, če se zmotite, strani vrnete prvotno ime, ne morete pa prepisati že obstoječe strani.
+
+<b>OPOZORILO!</b>
+Prestavitev strani je lahko za priljubljeno stran velika in nepričakovana sprememba, zato pred izbiro ukaza dobro premislite.',
+'movepagetalktext' => 'Če obstaja, bo samodejno prestavljena tudi pripadajoča pogovorna stran, \'\'\'razen kadar\'\'\'
+*stran prestavljate prek imenskih prostorov,
+*pod novim imenom že obstaja neprazna pogovorna stran ali
+*ste odkljukali spodnji okvirček.
+
+Če je tako, boste morali pogovorno stran, če želite, prestaviti ali povezati ročno. Če tega ne morete storiti, predlagajte prestavitev na strani [[Project:Želene prestavitve]], vsekakor pa tega \'\'\'\'\'ne\'\'\'\'\' počnite s preprostim izrezanjem in prilepljenjem vsebine, saj bi tako pokvarili zgodovino urejanja strani.',
+'movearticle' => 'Prestavi stran',
+'movenologin' => 'Niste prijavljeni',
+'movenologintext' => 'Za prestavljanje strani morate biti registrirani in [[Special:Userlogin|prijavljeni]].',
+'newtitle' => 'Na naslov',
+'movepagebtn' => 'Prestavi stran',
+'pagemovedsub' => 'Uspešno prestavljeno',
+'pagemovedtext' => 'Stran »[[$1]]« ste prestavili na naslov »[[$2]]«.',
+'articleexists' => '\'\'\'Stran ni bilo mogoče prestaviti!\'\'\' Izbrano ime je že zasedeno ali pa ni veljavno. Prosimo, izberite drugo ime ali za pomoč prosite katerega izmed [[Project:Administratorji|administratorjev]].',
+'talkexists' => 'Sama stran je bila uspešno prestavljena, pripadajoča pogovorna stran pa ne, ker že obstaja na novem naslovu. Prosimo, združite ju ročno. Če tega ne morete storiti, prosite za pomoč katerega izmed [[Project:Administratorji|administratorjev]], nikakor pa tega NE počnite z izrezanjem in prilepljenjem vsebine.',
+'movedto' => 'prestavljeno na',
+'movetalk' => 'Če je mogoče, prestavi tudi pogovorno stran.',
+'talkpagemoved' => 'Prestavljena je tudi pripadajoča pogovorna stran.',
+'talkpagenotmoved' => 'Pripadajoča pogovorna stran <strong>ni</strong> prestavljena. Bodisi ne obstaja ali pa ste sami določili, naj se ne prestavi.',
+'1movedto2' => '- prestavitev [[$1]] na [[$2]]',
+'1movedto2_redir' => '- prestavitev [[$1]] na [[$2]] čez preusmeritev',
+'movelogpage' => 'Dnevnik prestavljanja strani',
+'movelogpagetext' => 'Prikazujem seznam [[Pomoč:Prestavljanje strani|prestavljenih strani]]. Vedite, da polje »Uporabnik« razlikuje med malimi in velikimi črkami.',
+'movereason' => 'Razlog',
+'revertmove' => 'vrni',
+'delete_and_move' => 'Briši in prestavi',
+'delete_and_move_text' => '==Treba bi bilo brisati==
+
+<span style="color: red" class="deleteandmovetextwarning">Ciljna stran »[[$1]]« že obstaja. Ali jo želite, da bi pripravili prostor za prestavitev, izbrisati?</span>',
+'delete_and_move_confirm'=> 'Da, izbriši stran',
+'delete_and_move_reason'=> 'Izbrisano z namenom pripraviti prostor za prestavitev.',
+'selfmove' => '\'\'\'Naslova vira in cilja sta enaka; stran ni mogoče prestaviti samo vase.\'\'\' Prosimo, preverite, ali niste naslova cilja namesto v polje »Na naslov« vpisali v polje »Razlog«.',
+'immobile_namespace' => 'Kot cilj ste določili naslov posebne vrste. V ta imenski prostor stran ni mogoče prestaviti.',
+'export' => 'Izvoz strani',
+'exporttext' => 'Besedilo in urejevalno zgodovino ene ali več strani lahko izvozite v obliki XML. V prihodnosti bo to vsebino morda mogoče izvoziti v drug wiki, ki ga bo poganjalo programje MediaWiki, v trenutni različici pa so možnosti za to zelo omejene (kjer je omogočeno orodje \'\'Special:Import\'\', lahko vsebino z njegovo uporabo uvozijo administratorji).
+
+Če želite izvoziti članke, v spodnje polje vpišite njihove naslove (enega v vsako vrstico) in označite, ali želite le trenutno različico s podatki o trenutnem urejanju ali tudi vse prejšnje z vrsticami o zgodovini strani.
+
+Če gre za slednje, lahko uporabite tudi povezavo, npr. [[Special:Export/{{MediaWiki:Mainpage}}]] za
+članek {{MediaWiki:Mainpage}}.',
+'exportcuronly' => 'Vključi le trenutno redakcijo, ne pa celotne zgodovine.',
+'exportnohistory' => '----
+\'\'\'Opomba:\'\'\' izvoz celotne zgodovine strani je do nadaljnjega zaradi preobremenjenosti strežnikov onemogočen. Popolno zgodovino lahko najdete v [http://download.wikimedia.org/ izmetih zbirke podatkov] — administratorji strežnikov Wikimedije.',
+'export-submit' => 'Izvozi',
+'allmessages' => 'Sistemska sporočila',
+'allmessagesname' => 'Ime',
+'allmessagesdefault' => 'Prednastavljeno besedilo',
+'allmessagescurrent' => 'Trenutno besedilo',
+'allmessagestext' => 'Navedena so v imenskem prostoru MediaWiki dostopna sistemska sporočila. Urejajo jih lahko [[Project:Administratorji|administratorji]] in drugi sodelavci z vzdrževalnimi pravicami.',
+'allmessagesnotsupportedUI'=> 'Vašega trenutnega jezika vmesnika (\'\'\'$1\'\'\') [[Special:Allmessages]] spletišča ne podpirajo.',
+'allmessagesnotsupportedDB'=> 'Ker je wgUseDatabaseMessages izključeno, Special:Allmessages ni podprto.',
+'allmessagesfilter' => 'Filter pogostih izrazov:',
+'allmessagesmodified' => 'Prikaži le spremenjeno',
+'thumbnail-more' => 'Povečaj',
+'missingimage' => '<b>Manjkajoča slika</b><br /><i>$1</i>',
+'filemissing' => 'Datoteka manjka',
+'thumbnail_error' => 'Napaka pri izdelavi sličice: $1',
+'import' => 'Uvoz strani',
+'importinterwiki' => 'Transwikiuvoz',
+'importtext' => 'Z uporabo orodja Special:Export izvozite datoteko iz izvornega wikija, shranite jo na disk in naložite tu.',
+'importfailed' => 'Uvoz ni uspel: $1',
+'importnotext' => 'Prazno ali brez besedila',
+'importsuccess' => 'Uspešno uvoženo!',
+'importhistoryconflict' => 'Zgodovina strani vključuje navzkrižno redakcijo (morda je bila stran naložena že prej)',
+'importnosources' => 'Na tem wikiju je ta možnost onemogočena.',
+'importnofile' => 'Uvožena ni bila nobena datoteka.',
+'importuploaderror' => 'Uvoz datoteke ni uspel; morda velikost datoteke presega največjo dovoljeno velikost uvoza.',
+'tooltip-search' => 'Preiščite {{GRAMMAR:tožilnik|{{SITENAME}}}} [alt-f]',
+'tooltip-minoredit' => 'Označite kot manjše urejanje [alt-i]',
+'tooltip-save' => 'Shranite vnesene spremembe (ste si jih predogledali?) [alt-s]',
+'tooltip-preview' => 'Pred shranjevanjem si, prosimo, predoglejte stran! [alt-p]',
+'tooltip-diff' => 'Preglejte spremembe, ki ste jih vnesli. [alt-v]',
+'tooltip-compareselectedversions'=> 'Preglejte razlike med izbranima redakcijama. [alt-v]',
+'tooltip-watch' => 'Dodajte stran na svoj spisek nadzorov. [alt-w]',
+'nodublincore' => 'Metapodatki Dublin Core RDF so na tem strežniku onemogočeni.',
+'nocreativecommons' => 'Metapodatki Creative Commons RDF so za ta strežnik onemogočeni.',
+'notacceptable' => 'V obliki, ki jo lahko bere vaš odjemalec, wikistrežnik podatkov ne more ponuditi.',
+'anonymous' => 'Brezimni uporabnik(i) {{GRAMMAR:rodilnik|{{SITENAME}}}}',
+'siteuser' => 'Uporabnik $1',
+'lastmodifiedatby' => 'Stran je zadnjič urejal(a) $3 (čas spremembe: $2, $1).',
+'and' => 'in',
+'othercontribs' => '<!--Temelji na delu $1. Ne deluje pravilno-->Prispevki uporabnika.',
+'others' => 'drugi',
+'siteusers' => 'Uporabnik(i) $1',
+'creditspage' => 'Zasluge za stran',
+'nocredits' => 'Ni dostopnih podatkov o zaslugah za stran.',
+'spamprotectiontitle' => 'Zaščita pred neželenimi sporočili',
+'spamprotectiontext' => 'Stran, ki ste jo želeli shraniti, je zaščita pred spamom blokirala, saj je vsebovala povezavo na zunanjo stran, navedeno na [[m:spam blacklist|črni listi spama]]. Če povezave (glejte spodaj) niste dodali vi, je verjetno obstajala že v prejšnji redakciji ali pa jo je dodalo vohunsko programje (\'\'spyware\'\') na vašem računalniku.
+
+Da boste stran lahko shranili, boste morali odstraniti vse na črni listi navedene spletne naslove.
+
+Če mislite, da zaščita preprečuje urejanje neustrezno, vas prosimo, da na [[m:talk:spam blacklist|pogovorni strani črne liste]] predlagate njen popravek. Sledi odlomek strani, ki je sprožila zaščito.',
+'spamprotectionmatch' => 'Naslednje besedilo je sprožilo naš filter neželenih sporočil: $1',
+'subcategorycount' => 'Kategorija {{plural:$1|ima|ima|ima|ima|nima}} $1 {{plural:$1|podkategorijo|podkategoriji|podkategorije|podkategorij|podkategorij}}.',
+'categoryarticlecount' => 'V tem delu kategorije {{plural:$1|je|sta|so|je|ni}} $1 {{plural:$1|stran|strani|strani|strani|strani}}.',
+'listingcontinuesabbrev'=> ' nadalj.',
+'spambot_username' => 'MediaWiki čiščenje navlake',
+'spam_reverting' => 'Vračanje na zadnjo redakcijo brez povezav na $1',
+'spam_blanking' => 'Vse redakcije so vsebovale povezave na $1, izpraznjujem',
+'infosubtitle' => 'Podatki o strani',
+'numedits' => 'Število urejanj (članek): $1',
+'numtalkedits' => 'Število urejanj (pogovorna stran): $1',
+'numwatchers' => 'Število oseb, ki spremljajo stran: $1',
+'numauthors' => 'Število avtorjev: $1',
+'numtalkauthors' => 'Število avtorjev (pogovorna stran): $1',
+'mw_math_png' => 'Vedno prikaži PNG',
+'mw_math_simple' => 'Kadar je dovolj preprosto, uporabi HTML, sicer pa PNG',
+'mw_math_html' => 'Kadar je mogoče, uporabi HTML, sicer pa PNG',
+'mw_math_source' => 'Pusti v TeX-ovi obliki (za besedilne brskalnike)',
+'mw_math_modern' => 'Priporočeno za sodobne brskalnike',
+'mw_math_mathml' => 'če je le mogoče, uporabi MathML (preizkusno)',
+'markaspatrolleddiff' => 'Označite kot nadzorovano',
+'markaspatrolledtext' => 'Označite članek kot nadzorovan',
+'markedaspatrolled' => 'Označeno kot nadzorovano',
+'markedaspatrolledtext' => 'Izbrano različico ste označili kot nadzorovano.',
+'rcpatroldisabled' => 'Spremljanje zadnjih sprememb je onemogočeno.',
+'rcpatroldisabledtext' => 'Spremljanje zadnjih sprememb je začasno onemogočeno.',
+'markedaspatrollederror'=> 'Ni mogoče označiti kot pregledano',
+'markedaspatrollederrortext'=> 'Določite redakcijo, ki jo želite označiti kot pregledano.',
+'monobook.js' => '/* plavajoča polja in bližnjične tipke */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Vaša uporabniška stran\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Uporabniška stran IP-naslova, ki ga uporabljate\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Vaša pogovorna stran\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Pogovor o urejanjih s tega IP-naslova\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Vaše nastavitve\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Seznam strani, katerih spremembe spremljate\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Seznam vaših prispevkov\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Prijava ni obvezna, vendar je zaželena\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Prijava ni obvezna, vendar je zaželena\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Odjavite se\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Pogovor o strani\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Stran lahko uredite. Preden jo shranite, uporabite gumb za predogled.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Začnite novo razpravo\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Stran je zaščitena, ogledate si lahko njeno izvorno kodo\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Prejšnje redakcije strani\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Zaščitite stran\');
+ ta[\'ca-unprotect\'] = new Array(\'=\',\'Odstranite zaščito strani\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Brišite stran\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Obnovite pred izbrisom napravljena urejanja strani.\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Preimenujte stran\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Za prestavljanje nimate dovoljenja\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Dodajte stran na seznam nadzorov\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Odstranite stran s seznama nadzorov\');
+ ta[\'search\'] = new Array(\'f\',\'Preiščite wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Glavna stran\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Obiščite Glavno stran\');
+ ta[\'n-Dobrodošli\'] = new Array (\'\',\'Dobrodošli v {{GRAMMAR:dajalnik|{{SITENAME}}}} - osnovni napotki za delo\');
+ ta[\'n-Stik-z-nami\'] = new Array (\'\',\'Kako navezati stik s sodelavci projekta\');
+ ta[\'n-portal\'] = new Array(\'\',\'O projektu, kaj lahko storite, kje lahko kaj najdete\');
+ ta[\'n-Izbrani-članki\'] = new Array(\'\',\'Izbrani članki - najboljše v {{GRAMMAR:dajalnik|{{SITENAME}}}}\');
+ ta[\'n-Izbrane-osebe\'] = new Array(\'\',\'Izbrane osebe - najboljše biografije\');
+ ta[\'n-Pod-lipo\'] = new Array(\'\',\'Osrednja pogovorna stran {{GRAMMAR:rodilnik|{{SITENAME}}}}\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Spoznajte ozadje trenutnih dogodkov\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Seznam zadnjih sprememb {{GRAMMAR:rodilnik|{{SITENAME}}}}\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Naložite naključno stran\');
+ ta[\'n-help\'] = new Array(\'\',\'Kraj za pomoč\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Podprite nas\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Seznam vseh s trenutno povezanih strani\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Zadnje spremembe na s trenutno povezanih straneh\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS-dovod strani\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom-dovod strani\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Preglejte seznam uporabnikovih prispevkov\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Pošljite uporabniku e-pismo\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Naložite slike ali predstavnostne datoteke\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Preglejte seznam vseh posebnih strani\');
+ ta[\'t-print\'] = new Array(\'\',\'Natisljiva različica strani\');
+ ta[\'t-permalink\'] = new Array(\'\',\'Trajna povezava na dano redakcijo strani\');
+ ta[\'t-cite\'] = new Array(\'\',\'Navede bibliografske podatke za prikazani članek\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Prikaže članek\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Prikaže uporabniško stran\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Prikaže stran s predstavnostno vsebino\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Te posebne strani ne morete urejati\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Prikaže stran projekta\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Prikaže stran s sliko ali drugo datoteko\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Prikaže sistemsko sporočilo\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Prikaže stran predloge\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Prikaže stran s pomočjo\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Prikaže stran kategorije\');',
+'deletedrevision' => 'Prejšnja redakcija $1 je izbrisana.',
+'previousdiff' => '← Pojdi na prejšnje urejanje',
+'nextdiff' => 'Novejše urejanje →',
+'imagemaxsize' => 'Slike na opisnih straneh omeji na:',
+'thumbsize' => 'Velikost sličice (thumbnail):',
+'showbigimage' => 'Prikaži različico višje ločljivosti ($1 × $2, $3 kB)',
+'newimages' => 'Galerija novih datotek',
+'showhidebots' => '($1 bote)',
+'noimages' => 'Nič ni videti/datoteke ni.',
+'specialloguserlabel' => 'Uporabnik:',
+'speciallogtitlelabel' => 'Naslov:',
+'passwordtooshort' => 'Vaše geslo je prekratko. Imeti mora najmanj $1 {{plural:$1|znak|znaka|znake|znakov|znakov}}.',
+'mediawarning' => '\'\'\'Opozorilo\'\'\': Tovrstni tip datotek lahko vsebuje kodo, ki bi mogla ogroziti vaš sistem.
+<hr />',
+'fileinfo' => '$1KB, MIME-tip: <code>$2</code>',
+'metadata' => 'Metapodatki',
+'metadata-help' => 'Datoteka vsebuje še druge podatke, ki jih je verjetno dodal za njeno ustvaritev oziroma digitalizacijo uporabljeni fotografski aparat ali optični bralnik. Če je bila datoteka pozneje spremenjena, podatki sprememb morda ne izražajo popolnoma.',
+'metadata-expand' => 'Razširi seznam',
+'metadata-collapse' => 'Skrči seznam',
+'exif-imagewidth' => 'Širina',
+'exif-imagelength' => 'Višina',
+'exif-bitspersample' => 'Bitov na barvni gradnik',
+'exif-compression' => 'Shema stiskanja',
+'exif-photometricinterpretation'=> 'Sestava točke',
+'exif-orientation' => 'Usmerjenost',
+'exif-samplesperpixel' => 'Število gradnikov',
+'exif-planarconfiguration'=> 'Poravnava podatkov',
+'exif-ycbcrsubsampling' => 'Podvzorčno razmerje med Y in C',
+'exif-ycbcrpositioning' => 'Razmestitev Y in C',
+'exif-xresolution' => 'Vodoravna ločljivost',
+'exif-yresolution' => 'Navpična ločljivost',
+'exif-resolutionunit' => 'Enota ločljivosti X in Y',
+'exif-stripoffsets' => 'Mesto podatkov slike',
+'exif-rowsperstrip' => 'Število vrstic na pas',
+'exif-stripbytecounts' => 'Zlogov na pas stiskanja.',
+'exif-jpeginterchangeformat'=> 'Odtis na JPEG SOI',
+'exif-jpeginterchangeformatlength'=> 'Zlogov JPEG-podatkov',
+'exif-transferfunction' => 'Funkcija prenosa',
+'exif-whitepoint' => 'Kromatičnost bele točke',
+'exif-primarychromaticities'=> 'Kromatičnosti osnovnih barv',
+'exif-ycbcrcoefficients'=> 'Koeficient matrice transformacije barvnega prostora',
+'exif-referenceblackwhite'=> 'Par črnih in belih referenčnih vrednosti',
+'exif-datetime' => 'Datum in čas spremembe datoteke',
+'exif-imagedescription' => 'Naslov slike',
+'exif-make' => 'Proizvajalec fotoaparata',
+'exif-model' => 'Model fotoaparata',
+'exif-software' => 'Uporabljeno programje',
+'exif-artist' => 'Fotograf',
+'exif-copyright' => 'Imetnik avtorskih pravic',
+'exif-exifversion' => 'Različica Exif',
+'exif-flashpixversion' => 'Podprta različica Flashpix',
+'exif-colorspace' => 'Barvni prostor',
+'exif-componentsconfiguration'=> 'Pomen posameznih gradnikov',
+'exif-compressedbitsperpixel'=> 'Velikost točke po stiskanju (v bitih)',
+'exif-pixelydimension' => 'Veljavna širina slike',
+'exif-pixelxdimension' => 'Veljavna višina slike',
+'exif-makernote' => 'Opombe proizvajalca',
+'exif-usercomment' => 'Uporabniške pripombe',
+'exif-relatedsoundfile' => 'Pripadajoča zvočna datoteka',
+'exif-datetimeoriginal' => 'Datum in čas ustvaritve podatkov',
+'exif-datetimedigitized'=> 'Datum in čas digitalizacije',
+'exif-subsectime' => 'Čas pomnilnika (1/100 s)',
+'exif-subsectimeoriginal'=> 'Čas zajema',
+'exif-subsectimedigitized'=> 'Digitalizacijski čas (1/100 s)',
+'exif-exposuretime' => 'Čas osvetlitve',
+'exif-exposuretime-format'=> '$1 s ($2)',
+'exif-fnumber' => 'Goriščno razmerje',
+'exif-exposureprogram' => 'Program osvetlitve',
+'exif-spectralsensitivity'=> 'Spektralna občutljivost',
+'exif-isospeedratings' => 'Občutljivost filma ali tipala (ISO)',
+'exif-oecf' => 'Optoelektronski pretvorbeni faktor',
+'exif-shutterspeedvalue'=> 'Hitrost zaklopa',
+'exif-aperturevalue' => 'Zaslonka',
+'exif-brightnessvalue' => 'Svetlost',
+'exif-exposurebiasvalue'=> 'Popravek osvetlitve',
+'exif-maxaperturevalue' => 'Največja vrednost zaslonke',
+'exif-subjectdistance' => 'Oddaljenost predmeta',
+'exif-meteringmode' => 'Način merjenja svetlobe',
+'exif-lightsource' => 'Svetlobni vir',
+'exif-flash' => 'Bliskavica',
+'exif-focallength' => 'Goriščna razdalja leč',
+'exif-subjectarea' => 'Površina predmeta',
+'exif-flashenergy' => 'Energija bliskavice',
+'exif-spatialfrequencyresponse'=> 'Odziv prostorske frekvence',
+'exif-focalplanexresolution'=> 'Ločljivost goriščne ravnine X',
+'exif-focalplaneyresolution'=> 'Ločljivost goriščne ravnine Y',
+'exif-focalplaneresolutionunit'=> 'Enota ločljivosti goriščne ravnine',
+'exif-subjectlocation' => 'Položaj predmeta',
+'exif-exposureindex' => 'Indeks osvetlitve',
+'exif-sensingmethod' => 'Zaznavni postopek',
+'exif-filesource' => 'Vir datoteke',
+'exif-scenetype' => 'Vrsta prizora',
+'exif-cfapattern' => 'Matrica filtracije barv',
+'exif-customrendered' => 'Obdelava slike po meri',
+'exif-exposuremode' => 'Nastavitev osvetlitve',
+'exif-whitebalance' => 'Ravnotežje belega',
+'exif-digitalzoomratio' => 'Razmerje digitalne povečave',
+'exif-focallengthin35mmfilm'=> 'Goriščna razdalja pri 35-milimetrskem filmu',
+'exif-scenecapturetype' => 'Način zajema prizora',
+'exif-gaincontrol' => 'Ojačanje',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Nasičenost',
+'exif-sharpness' => 'Ostrina',
+'exif-devicesettingdescription'=> 'Opis nastavitev naprave',
+'exif-subjectdistancerange'=> 'Območje oddaljenosti predmeta',
+'exif-imageuniqueid' => 'ID slike',
+'exif-gpsversionid' => 'Različica GPS-oznake',
+'exif-gpslatituderef' => 'Severna ali južna zemljepisna širina',
+'exif-gpslatitude' => 'Zemljepisna širina',
+'exif-gpslongituderef' => 'Vzhodna ali zahodna zemljepisna dolžina',
+'exif-gpslongitude' => 'Zemljepisna dolžina',
+'exif-gpsaltituderef' => 'Referenca višine',
+'exif-gpsaltitude' => 'Višina',
+'exif-gpstimestamp' => 'GPS-čas (atomska ura)',
+'exif-gpssatellites' => 'Za merjenje uporabljeni sateliti',
+'exif-gpsstatus' => 'Položaj sprejemnika',
+'exif-gpsmeasuremode' => 'Način merjenja',
+'exif-gpsdop' => 'Natančnost merjenja',
+'exif-gpsspeedref' => 'Enota hitrosti',
+'exif-gpsspeed' => 'Hitrost GPS-sprejemnika',
+'exif-gpstrackref' => 'Referenca smeri gibanja',
+'exif-gpstrack' => 'Smer merjenja',
+'exif-gpsimgdirectionref'=> 'Referenca smeri slike',
+'exif-gpsimgdirection' => 'Smer slike',
+'exif-gpsmapdatum' => 'Uporabljeni geodetski podatki',
+'exif-gpsdestlatituderef'=> 'Referenca zemljepisne širine cilja',
+'exif-gpsdestlatitude' => 'Zemljepisna širina cilja',
+'exif-gpsdestlongituderef'=> 'Referenca zemljepisne dolžine cilja',
+'exif-gpsdestlongitude' => 'Zemljepisna dolžina cilja',
+'exif-gpsdestbearingref'=> 'Referenca smeri cilja',
+'exif-gpsdestbearing' => 'Smer cilja',
+'exif-gpsdestdistanceref'=> 'Referenca razdalje do cilja',
+'exif-gpsdestdistance' => 'Razdalja do cilja',
+'exif-gpsprocessingmethod'=> 'Ime postopka obdelave GPS-opazovanj',
+'exif-gpsareainformation'=> 'Ime GPS-območja',
+'exif-gpsdatestamp' => 'GPS-datum',
+'exif-gpsdifferential' => 'Diferencialni popravek GPS',
+'exif-compression-1' => 'Nestisnjeno',
+'exif-orientation-1' => 'Navadna',
+'exif-orientation-2' => 'Vodoravno zrcaljeno',
+'exif-orientation-3' => 'Zasukano za 180°',
+'exif-orientation-4' => 'Navpično zrcaljeno',
+'exif-orientation-5' => 'Zasukano za 90° v levo in navpično zrcaljeno',
+'exif-orientation-6' => 'Zasukano za 90° v desno',
+'exif-orientation-7' => 'Zasukano za 90° v desno in navpično zrcaljeno',
+'exif-orientation-8' => 'Zasukano za 90° v levo',
+'exif-planarconfiguration-1'=> 'grudast format',
+'exif-planarconfiguration-2'=> 'ravninski format',
+'exif-xyresolution-i' => '$1 dpi ({{plural:$1|točka/palec|točki/palec|točke/palec|točk/palec|točk/palec}})',
+'exif-xyresolution-c' => '$1 dpc ({{plural:$1|točka/centimeter|točki/centimeter|točke/centimeter|točk/centimeter|točk/centimeter}})',
+'exif-componentsconfiguration-0'=> 'ne obstaja',
+'exif-exposureprogram-0'=> 'Ni določen',
+'exif-exposureprogram-1'=> 'Ročno',
+'exif-exposureprogram-2'=> 'Navaden',
+'exif-exposureprogram-3'=> 'Prednost zaslonke',
+'exif-exposureprogram-4'=> 'Prednost zaklopa',
+'exif-exposureprogram-5'=> 'Ustvarjalni program (prednost globinske ostrine)',
+'exif-exposureprogram-6'=> 'Akcijski program (prednost kratke osvetlitve)',
+'exif-exposureprogram-7'=> 'Portretna nastavitev (fotografije od blizu, ozadje ni ostro)',
+'exif-exposureprogram-8'=> 'Pokrajinska nastavitev (fotografije pokrajine, ostro ozadje)',
+'exif-subjectdistance-value'=> '$1 {{plural:$1|meter|metra|metre|metrov|metrov}}',
+'exif-meteringmode-0' => 'Neznan',
+'exif-meteringmode-1' => 'Povprečno',
+'exif-meteringmode-2' => 'Središčno obteženo povprečno',
+'exif-meteringmode-3' => 'Točkovno',
+'exif-meteringmode-4' => 'Večtočkovno',
+'exif-meteringmode-5' => 'Vzorčno',
+'exif-meteringmode-6' => 'Delno',
+'exif-meteringmode-255' => 'Drugače',
+'exif-lightsource-0' => 'Neznan',
+'exif-lightsource-1' => 'Dnevna svetloba',
+'exif-lightsource-2' => 'Fluorescenčen',
+'exif-lightsource-3' => 'Volfram (žarnica)',
+'exif-lightsource-4' => 'Bliskavica',
+'exif-lightsource-9' => 'Lepo vreme',
+'exif-lightsource-10' => 'Oblačno',
+'exif-lightsource-11' => 'Senca',
+'exif-lightsource-12' => 'Dnevni fluorescenčen (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Dnevni bel fluorescenčen (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Hladen bel fluorescenčen (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Bel fluorescenčen (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Običajna svetloba A',
+'exif-lightsource-18' => 'Običajna svetloba B',
+'exif-lightsource-19' => 'Običajna svetloba C',
+'exif-lightsource-24' => 'ISO-ateljejski volfram',
+'exif-lightsource-255' => 'Drugačen',
+'exif-focalplaneresolutionunit-2'=> 'palcev',
+'exif-sensingmethod-1' => 'Nedoločen',
+'exif-sensingmethod-2' => 'Enočipno barvno ploskovno tipalo',
+'exif-sensingmethod-3' => 'Dvočipno barvno ploskovno tipalo',
+'exif-sensingmethod-4' => 'Tričipno barvno ploskovno tipalo',
+'exif-sensingmethod-5' => 'Zaporedno barvno ploskovno tipalo',
+'exif-sensingmethod-7' => 'Trikratno tipalo',
+'exif-sensingmethod-8' => 'Zaporedno barvno črtno tipalo',
+'exif-scenetype-1' => 'Neposredno fotografirana slika',
+'exif-customrendered-0' => 'Navaden postopek',
+'exif-customrendered-1' => 'Prilagojen postopek',
+'exif-exposuremode-0' => 'Samodejno',
+'exif-exposuremode-1' => 'Ročno',
+'exif-exposuremode-2' => 'Samodejna konzola',
+'exif-whitebalance-0' => 'Samodejno',
+'exif-whitebalance-1' => 'Ročno',
+'exif-scenecapturetype-0'=> 'Navadni',
+'exif-scenecapturetype-1'=> 'Pokrajina',
+'exif-scenecapturetype-2'=> 'Portret',
+'exif-scenecapturetype-3'=> 'Nočni prizor',
+'exif-gaincontrol-0' => 'Brez',
+'exif-gaincontrol-1' => 'Nizko ojačanje zgoraj',
+'exif-gaincontrol-2' => 'Visoko ojačanje zgoraj',
+'exif-gaincontrol-3' => 'Nizko ojačanje spodaj',
+'exif-gaincontrol-4' => 'Visoko ojačanje spodaj',
+'exif-contrast-0' => 'Navaden',
+'exif-contrast-1' => 'Nizek',
+'exif-contrast-2' => 'Visok',
+'exif-saturation-0' => 'Navadna',
+'exif-saturation-1' => 'Nizka nasičenost',
+'exif-saturation-2' => 'Visoka nasičenost',
+'exif-sharpness-0' => 'Navadna',
+'exif-sharpness-1' => 'Mehka',
+'exif-sharpness-2' => 'Trda',
+'exif-subjectdistancerange-0'=> 'Neznano',
+'exif-subjectdistancerange-1'=> 'Makro',
+'exif-subjectdistancerange-2'=> 'Pogled od blizu',
+'exif-subjectdistancerange-3'=> 'Pogled od daleč',
+'exif-gpslatitude-n' => 'Severna zemljepisna širina',
+'exif-gpslatitude-s' => 'Južna zemljepisna širina',
+'exif-gpslongitude-e' => 'Vzhodna zemljepisna dolžina',
+'exif-gpslongitude-w' => 'Zahodna zemljepisna dolžina',
+'exif-gpsstatus-a' => 'Merjenje poteka',
+'exif-gpsstatus-v' => 'Interoperabilnost merjenja',
+'exif-gpsmeasuremode-2' => 'Dvorazsežnostno merjenje',
+'exif-gpsmeasuremode-3' => 'Trirazsežnostno merjenje',
+'exif-gpsspeed-k' => 'Kilometri na uro',
+'exif-gpsspeed-m' => 'Milje na uro',
+'exif-gpsspeed-n' => 'Vozli',
+'exif-gpsdirection-t' => 'Pravi azimut',
+'exif-gpsdirection-m' => 'Magnetni azimut',
+'edit-externally' => 'Uredite datoteko z uporabo zunanjega orodja',
+'edit-externally-help' => 'Za več informacij glej [http://meta.wikimedia.org/wiki/Help:External_editors navodila za namestitev].',
+'recentchangesall' => 'vse',
+'imagelistall' => 'vse',
+'watchlistall1' => 'vse',
+'watchlistall2' => 'vse',
+'namespacesall' => 'vse',
+'confirmemail' => 'Potrditev naslova elektronske pošte',
+'confirmemail_text' => 'Za uporabo e-poštnih možnosti {{GRAMMAR:rodilnik|{{SITENAME}}}} morate najprej potrditi svoj e-poštni naslov. S klikom spodnjega gumba pošljite nanj potrditveno sporočilo in sledite prejetim navodilom. Ali ste svoj e-poštni naslov že potrdili, lahko preverite v [[Special:Preferences|nastavitvah]].',
+'confirmemail_send' => 'Pošlji mi potrditveno sporočilo',
+'confirmemail_sent' => 'Potrditveno e-sporočilo je bilo poslano.',
+'confirmemail_sendfailed'=> 'Potrditvenega sporočila ni bilo mogoče poslati. Prosimo, preverite, če niste naslova vnesli napačno.',
+'confirmemail_invalid' => 'Potrditveno geslo je neveljavno. Morda je poteklo.',
+'confirmemail_needlogin'=> 'Za potrditev svojega e-poštnega se morate $1.',
+'confirmemail_success' => 'Vaš e-poštni naslov je potrjen. Zdaj se lahko prijavite in uporabljate wiki.',
+'confirmemail_loggedin' => 'Svoj elektronski naslov ste uspešno potrdili.',
+'confirmemail_error' => 'Vaša potrditev se žal ni shranila.',
+'confirmemail_subject' => 'Potrditev e-poštnega naslova',
+'confirmemail_body' => 'Nekdo z IP-naslovom »$1« (verjetno vi) je v {{GRAMMAR:dajalnik|{{SITENAME}}}} ustvaril račun »$2« in zanj vpisal vaš elektronski naslov. Da bi potrdili, da ta resnično pripada vam in s tem lahko začeli uporabljati e-poštne storitve {{GRAMMAR:rodilnik|{{SITENAME}}}}, odprite naslednjo povezavo:
+
+$3
+
+Če tega niste napravili vi, povezavi ne sledite. Potrditveno geslo bo poteklo do $4.',
+'tryexact' => 'Poskusite z natančnim zadetkom',
+'searchfulltext' => 'Preišči vse besedilo',
+'createarticle' => 'Ustvarite stran',
+'scarytranscludedisabled'=> '[prevključevanje med wikiji je onemogočeno]',
+'scarytranscludefailed' => '[pridobivanje predloge za $1 žal ni uspelo]',
+'scarytranscludetoolong'=> '[Spletni naslov je žal predolg; se opravičujemo]',
+'trackbackbox' => '<div id=\'mw_trackbacks\'>
+Sledilniki članka:<br />
+$1
+</div>',
+'trackbackremove' => ' ([Izbris $1])',
+'trackbacklink' => 'Sledilnik',
+'trackbackdeleteok' => 'Sledilnik je uspešno izbrisan.',
+'deletedwhileediting' => '\'\'Opozorilo:\'\' Med vašim urejanjem je eden izmed administratorjev stran izbrisal. Razloge za to si lahko pogledate v [[Special:Log/delete|dnevniku brisanja]].',
+'confirmrecreate' => 'Medtem ko ste stran urejali, jo je uporabnik [[User:$1|$1]] ([[User talk:$1|pogovor]]) izbrisal z razlogom:
+:\'\'$2\'\'
+Prosimo, potrdite, da jo resnično želite znova ustvariti.',
+'recreate' => 'Ponovno ustvari',
+'tooltip-recreate' => '<noinclude>Ta stran je namenoma (skoraj) prazna.</noinclude>',
+'unit-pixel' => ' točk',
+'redirectingto' => 'Preusmerjam na »[[$1]]« ...',
+'confirm_purge' => 'Osvežim predpomnjenje strani?
+
+$1',
+'confirm_purge_button' => 'Osveži',
+'youhavenewmessagesmulti'=> 'Na $1 imate novo sporočilo',
+'searchcontaining' => 'Poišči članke, ki vsebujejo \'\'$1\'\'.',
+'searchnamed' => 'Poišči članke, ki se imenujejo \'\'$1\'\'.',
+'articletitles' => 'Članki, ki se začnejo na \'\'$1\'\'',
+'hideresults' => 'Skrij zadetke',
+'displaytitle' => '(Poveži na to stran kot [[$1]])',
+);
+?>
diff --git a/languages/messages/MessagesSq.php b/languages/messages/MessagesSq.php
new file mode 100644
index 000000000000..7e4b5603944f
--- /dev/null
+++ b/languages/messages/MessagesSq.php
@@ -0,0 +1,1496 @@
+<?php
+/** Albanian (Shqip)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Asnjë', 'Lidhur majtas', 'Lidhur djathtas', 'Pezull majtas', 'Pezull djathtas'
+);
+
+$skinNames = array(
+ 'standard' => 'Standarte',
+ 'nostalgia' => 'Nostalgjike',
+ 'cologneblue' => 'Kolonjë Blu'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciale',
+ NS_MAIN => '',
+ NS_TALK => 'Diskutim',
+ NS_USER => 'Përdoruesi',
+ NS_USER_TALK => 'Përdoruesi_diskutim',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_diskutim',
+ NS_IMAGE => 'Figura',
+ NS_IMAGE_TALK => 'Figura_diskutim',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_diskutim',
+ NS_TEMPLATE => 'Stampa',
+ NS_TEMPLATE_TALK => 'Stampa_diskutim',
+ NS_HELP => 'Ndihmë',
+ NS_HELP_TALK => 'Ndihmë_diskutim'
+);
+
+# Compatbility with alt names
+$namespaceAliases = array(
+ 'Perdoruesi' => NS_USER,
+ 'Perdoruesi_diskutim' => NS_USER_TALK,
+);
+
+$datePreferences = array(
+ 'default',
+ 'dmy',
+ 'ISO 8601',
+);
+$defaultDateFormat = 'dmy';
+$dateFormats = array(
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j F Y',
+ 'dmy both' => 'j F Y H:i',
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+$messages = array(
+'tog-underline' => 'Nënvizo lidhjet',
+'tog-highlightbroken' => 'Trego lidhjet e faqeve bosh <a href="" class="new">kështu </a> (ndryshe: kështu<a href="" class="internal">?</a>).',
+'tog-justify' => 'Rregullim i kryeradhës',
+'tog-hideminor' => 'Mos trego redaktimet e vogla',
+'tog-extendwatchlist' => 'Zgjero listën mbikqyrëse të tregojë të tëra ndryshimet përkatëse',
+'tog-usenewrc' => 'Tregoji me formatin e ri (jo për të gjithë shfletuesit)',
+'tog-numberheadings' => 'Numëro automatikish mbishkrimet',
+'tog-showtoolbar' => 'Trego butonat e redaktimit',
+'tog-editondblclick' => 'Redakto faqet me dopjo-shtypje (JavaScript)',
+'tog-editsection' => 'Lejo redaktimin e seksioneve me [redakto] lidhje',
+'tog-editsectiononrightclick'=> 'Lejo redaktimin e seksioneve me djathtas-shtypje<br /> mbi emrin e seksionit (JavaScript)',
+'tog-showtoc' => 'Trego tabelën e përmbajtjeve<br />(për faqet me më shume se 3 tituj)',
+'tog-rememberpassword' => 'Mbaj mënd fjalëkalimin për vizitën e ardhshme',
+'tog-editwidth' => 'Kutija e redaktimit ka gjerësi te plotë',
+'tog-watchcreations' => 'Shto faqet që krijoj tek lista mbikqyrëse',
+'tog-watchdefault' => 'Shto faqet që redaktoj tek lista mbikqyrëse',
+'tog-minordefault' => 'Shëno të gjitha redaktimet si të vogla paraprakisht',
+'tog-previewontop' => 'Trego parapamjen përpara kutisë redaktuese, jo mbas saj',
+'tog-previewonfirst' => 'Trego parapamje në redaktim të parë',
+'tog-nocache' => 'Mos ruaj kopje te faqeve',
+'tog-enotifwatchlistpages'=> 'Më ço email kur ndryshojnë faqet',
+'tog-enotifusertalkpages'=> 'Më ço email kur ndryshon faqja ime e diskutimit',
+'tog-enotifminoredits' => 'Më ço email kur ka redaktime të vogla të faqeve',
+'tog-enotifrevealaddr' => 'Trego adresën time në email-et njoftuese',
+'tog-shownumberswatching'=> 'Trego numrin e përdoruesve mbikqyrës',
+'tog-fancysig' => 'Mos e përpuno nënshkrimin për formatim',
+'tog-externaleditor' => 'Përdor program të jashtëm për redaktime',
+'tog-externaldiff' => 'Përdor program të jashtëm për të treguar ndryshimet',
+'tog-showjumplinks' => 'Lejo lidhjet e afrueshmërisë "kapërce tek"',
+'tog-uselivepreview' => 'Trego parapamjen e menjëhershme (JavaScript) (Eksperimentale)',
+'tog-autopatrol' => 'Shënoji si të patrulluara redaktimet e mia',
+'tog-forceeditsummary' => 'Më pyet kur e le përmbledhjen e redaktimit bosh',
+'tog-watchlisthideown' => 'Fshih redaktimet e mia nga lista mbikqyrëse',
+'tog-watchlisthidebots' => 'Fshih redaktimet e robotëve nga lista mbikqyrëse',
+'underline-always' => 'gjithmonë',
+'underline-never' => 'asnjëherë',
+'underline-default' => 'sipas shfletuesit',
+'skinpreview' => '(Parapamje)',
+'sunday' => 'E diel',
+'monday' => 'E hënë',
+'tuesday' => 'E martë',
+'wednesday' => 'E mërkurë',
+'thursday' => 'E enjte',
+'friday' => 'E premte',
+'saturday' => 'E shtunë',
+'january' => 'Janar',
+'february' => 'Shkurt',
+'march' => 'Mars',
+'april' => 'Prill',
+'may_long' => 'Maj',
+'june' => 'Qershor',
+'july' => 'Korrik',
+'august' => 'Gusht',
+'september' => 'Shtator',
+'october' => 'Tetor',
+'november' => 'Nëntor',
+'december' => 'Dhjetor',
+'jan' => 'Jan',
+'feb' => 'Shk',
+'mar' => 'Mar',
+'apr' => 'Pri',
+'may' => 'Maj',
+'jun' => 'Qer',
+'jul' => 'Kor',
+'aug' => 'Gus',
+'sep' => 'Sht',
+'oct' => 'Tet',
+'nov' => 'Nën',
+'dec' => 'Dhj',
+'categories' => 'Kategoritë',
+'pagecategories' => '{{PLURAL:$1|Kategoria|Kategoritë}}',
+'category_header' => 'Artikuj në kategorinë "$1"',
+'subcategories' => 'Nën-kategori',
+'mainpage' => 'Faqja Kryesore',
+'mainpagetext' => 'Wiki software u instalua me sukses.',
+'mainpagedocfooter' => 'Ju lutem shikoni [http://meta.wikimedia.org/wiki/Help:Contents dokumentacionin përkatës].
+
+
+== Fillimisht ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Parazgjedhjet e MediaWiki-t]
+* [http://www.mediawiki.org/wiki/Help:FAQ Pyetjet e shpeshta rreth MediaWiki-t]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Njoftime rreth MediaWiki-t]',
+'portal' => 'Wikiportal',
+'portal-url' => 'Project:Wikiportal',
+'about' => 'Rreth',
+'aboutsite' => 'Rreth {{SITENAME}}',
+'aboutpage' => 'Project:Rreth',
+'article' => 'Artikulli',
+'help' => 'Ndihmë',
+'helppage' => 'Help:Ndihmë',
+'bugreports' => 'Kontakt',
+'bugreportspage' => '{{SITENAME}}:Kontakt',
+'sitesupport' => 'Dhurime',
+'sitesupport-url' => 'Project:Dhurime',
+'faq' => 'Pyetje e Përgjigje',
+'faqpage' => 'Project:Pyetje e Përgjigje',
+'edithelp' => 'Ndihmë për redaktim',
+'newwindow' => '(hapet në një dritare të re)',
+'edithelppage' => 'Help:Si redaktohet një faqe',
+'cancel' => 'Harroji',
+'qbfind' => 'Kërko',
+'qbbrowse' => 'Shfletoni',
+'qbedit' => 'Redaktoni',
+'qbpageoptions' => 'Opsionet e faqes',
+'qbpageinfo' => 'Informacion mbi faqen',
+'qbmyoptions' => 'Opsionet e mia',
+'qbspecialpages' => 'Faqet speciale',
+'moredotdotdot' => 'Më shumë...',
+'mypage' => 'Faqja ime',
+'mytalk' => 'Diskutimet e mia',
+'anontalk' => 'Diskutimet për këtë IP',
+'navigation' => 'Shfleto',
+'metadata_help' => 'Metadata (shikoni [[Project:Metadata]] për sqarimin):',
+'currentevents' => 'Ngjarjet e tanishme',
+'currentevents-url' => 'Ngjarjet e tanishme',
+'disclaimers' => 'Shfajësimet',
+'disclaimerpage' => 'Project:Shfajësimet e përgjithshme',
+'privacy' => 'Rreth të dhënave vetjake',
+'privacypage' => 'Project:Politika vetjake',
+'errorpagetitle' => 'Gabim',
+'returnto' => 'Kthehu tek $1.',
+'tagline' => 'Nga {{SITENAME}}, Enciklopedia e Lirë',
+'search' => 'Kërko',
+'searchbutton' => 'Kërko',
+'go' => 'Shko',
+'searcharticle' => 'Shko',
+'history' => 'Historiku i faqes',
+'history_short' => 'Historiku',
+'updatedmarker' => 'ndryshuar nga vizita e fundit',
+'info_short' => 'Informacion',
+'printableversion' => 'Version shtypi',
+'permalink' => 'Lidhja e përhershme',
+'print' => 'Shtype',
+'edit' => 'Redaktoni',
+'editthispage' => 'Redaktoni faqen',
+'delete' => 'grise',
+'deletethispage' => 'Grise faqen',
+'undelete_short' => 'Restauroni $1 redaktime',
+'protect' => 'Mbroje',
+'protectthispage' => 'Mbroje faqen',
+'unprotect' => 'Liroje',
+'unprotectthispage' => 'Liroje faqen',
+'newpage' => 'Faqe e re',
+'talkpage' => 'Diskutoni faqen',
+'specialpage' => 'Faqe speciale',
+'personaltools' => 'Mjete vetjake',
+'postcomment' => 'Shtoni koment',
+'articlepage' => 'Shikoni artikullin',
+'talk' => 'Diskutimet',
+'views' => 'Shikime',
+'toolbox' => 'Mjete',
+'userpage' => 'Shikoni faqen',
+'projectpage' => 'Shikoni projekt-faqen',
+'imagepage' => 'Shikoni faqen e figurës',
+'viewtalkpage' => 'Shikoni diskutimet',
+'otherlanguages' => 'Në gjuhë të tjera',
+'redirectedfrom' => '(Përcjellë nga $1)',
+'autoredircomment' => 'Përcjellur tek [[$1]]',
+'redirectpagesub' => 'Faqe përcjellëse',
+'lastmodifiedat' => 'Kjo faqe është ndryshuar për herë te fundit më $2, $1.',
+'viewcount' => 'Kjo faqe është parë $1 herë.',
+'copyright' => 'Përmbajtja është në disponim nëpërmjet licensës $1.',
+'protectedpage' => 'Faqe e mbrojtur',
+'jumpto' => 'Shko te:',
+'jumptonavigation' => 'navigacion',
+'jumptosearch' => 'kërko',
+'badaccess' => 'Gabim leje',
+'versionrequired' => 'Nevojitet versioni $1 i MediaWiki-it',
+'versionrequiredtext' => 'Nevojitet versioni $1 i MediaWiki-it për përdorimin e kësaj faqeje. Shikoni [[Special:Version|versionin]] tuaj.',
+'ok' => 'Shkoni',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Marrë nga "$1"',
+'youhavenewmessages' => 'Keni $1 ($2).',
+'newmessageslink' => 'mesazhe të reja',
+'newmessagesdifflink' => 'ndryshimi i fundit',
+'editsection' => 'redaktoni',
+'editold' => 'redaktoni',
+'editsectionhint' => 'Redaktoni seksionin:
+Edit section: $1',
+'toc' => 'Tabela e përmbajtjeve',
+'showtoc' => 'trego',
+'hidetoc' => 'fshih',
+'thisisdeleted' => 'Shikoni ose restauroni $1?',
+'viewdeleted' => 'Do ta shikosh $1?',
+'restorelink' => '$1 redaktime të grisura',
+'feedlinks' => 'Ushqyes:',
+'feed-invalid' => 'Lloji i burimit të pajtimit është i pavlefshëm.',
+'nstab-main' => 'Artikulli',
+'nstab-user' => 'Përdoruesi',
+'nstab-media' => 'Media-faqe',
+'nstab-special' => 'Speciale',
+'nstab-project' => 'Projekt-faqe',
+'nstab-image' => 'Figura',
+'nstab-mediawiki' => 'Mesazhi',
+'nstab-template' => 'Stampa',
+'nstab-help' => 'Ndihmë',
+'nstab-category' => 'Kategori',
+'nosuchaction' => 'Nuk ekziston ky veprim',
+'nosuchactiontext' => 'Veprimi i caktuar nga URL nuk
+njihet nga wiki software',
+'nosuchspecialpage' => 'Nuk ekziston kjo faqe',
+'nospecialpagetext' => 'Keni kërkuar një faqe speciale që nuk njihet nga wiki software.',
+'error' => 'Gabim',
+'databaseerror' => 'Gabim regjistri',
+'dberrortext' => 'Ka ndodhur një gabim me pyetjen e regjistrit. Kjo mund të ndodhi n.q.s. pyetja nuk është e vlehshme (shikoni $5),
+ose mund të jetë një yçkël e softuerit. Pyetja e fundit që i keni bërë regjistrit ishte:
+<blockquote><tt>$1</tt></blockquote>
+nga funksioni "<tt>$2</tt>".
+MySQL kthehu gabimin "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Ka ndodhur një gabim me formatin e pyetjes së regjistrit. Pyetja e fundit qe i keni bërë regjistrit ishte:
+"$1"
+nga funksioni "$2".
+MySQL kthehu gabimin "$3: $4".',
+'noconnect' => 'Ju kërkojmë ndjesë! Difekt teknik, rifillojmë së shpejti.<br />
+$1',
+'nodb' => 'Nuk mund të zgjidhja regjistrin $1',
+'cachederror' => 'Kjo është një kopje e faqes së kërkuar dhe mund të jetë e vjetër.',
+'laggedslavemode' => 'Kujdes: Kjo faqe mund të mos jetë përtërirë nga shërbyesi kryesorë dhe mund të ketë informacion të vjetër',
+'readonly' => 'Regjistri i bllokuar',
+'enterlockreason' => 'Fusni një arsye për bllokimin, gjithashtu fusni edhe kohën se kur pritet të çbllokohet',
+'readonlytext' => 'Regjistri i {{SITENAME}}-s është i bllokuar dhe nuk lejon redaktime dhe
+artikuj të rinj. Ka mundësi të jetë bllokuar për mirëmbajtje,
+dhe do të kthehet në gjëndje normale mbas mirëmbajtjes.
+
+Mirëmbajtësi i cili e bllokoi dha këtë arsye: $1',
+'missingarticle' => 'Regjistri nuk e gjeti tekstin e faqes që duhet të kishte gjetur, të quajtur "$1".
+
+Kjo ndodh zakonisht kur ndjek një ndryshim ose lidhje historie tek një
+faqe që është grisur.
+
+Në qoftë se ky nuk është rasti, atëherë mund të keni gjetur një yçkël në softuerin.
+Tregojani këtë përmbledhje një administruesi, duke shënuar edhe URL-in.',
+'readonly_lag' => 'Regjistri është bllokuar automatikisht për t\'i dhënë kohë shërbyesve skllevër për të arritur kryesorin. Ju lutemi provojeni përsëri më vonë.',
+'internalerror' => 'Gabim i brendshëm',
+'filecopyerror' => 'Nuk munda të kopjojë skedën "$1" tek "$2".',
+'filerenameerror' => 'Nuk munda të ndërrojë emrin e skedës "$1" në "$2".',
+'filedeleteerror' => 'Nuk munda të gris skedën "$1".',
+'filenotfound' => 'Nuk munda të gjejë skedën "$1".',
+'unexpected' => 'Vlerë e papritur: "$1"="$2".',
+'formerror' => 'Gabim: nuk munda të dërgoj formularin',
+'badarticleerror' => 'Ky veprim nuk mund të bëhet në këtë faqe.',
+'cannotdelete' => 'Nuk munda të gris këtë faqe ose figurë të dhënë. (Ka mundësi të jetë grisur nga dikush tjeter.)',
+'badtitle' => 'Titull i pasaktë',
+'badtitletext' => 'Titulli i faqes që kërkuat nuk ishte i saktë, ishte bosh, ose ishte një lidhje gabim me një titull wiki internacional.',
+'perfdisabled' => 'Ju kërkoj ndjesë! Ky veprim është bllokuar përkohsisht sepse e ngadalëson regjistrin aq shumë sa nuk e përdor dot njeri tjetër.',
+'perfdisabledsub' => 'Kjo është nje kopje e ruajtur nga $1:',
+'perfcached' => 'Informacioni i mëposhtëm është kopje e ruajtur dhe mund të mos jetë i freskët:',
+'perfcachedts' => 'Informacioni i mëposhtëm është një kopje e rifreskuar më $1.',
+'wrong_wfQuery_params' => 'Parametra gabim tek wfQuery()<br />
+Funksioni: $1<br />
+Pyetja: $2',
+'viewsource' => 'Shikoni tekstin',
+'viewsourcefor' => 'e $1',
+'protectedtext' => 'Kjo faqe është e mbrojtur që të mos redaktohet; mund të ketë
+disa arsye përse kjo është bërë, ju lutem shikoni
+[[Project:Faqe e mbrojtur|faqe e mbrojtur]].
+
+Mund të shikoni dhe kopjoni tekstin e kësaj faqeje:',
+'protectedinterface' => 'Kjo faqe përmban tekst për pamjen gjuhësorë të softuerit dhe është e mbrojtur për të penguar keqpërdorimet.',
+'editinginterface' => '\'\'\'Kujdes:\'\'\' Po redaktoni një faqe që përdoret për tekstin ose pamjen e softuerit. Ndryshimet e kësaj faqeje do të prekin tekstin ose pamjen për të gjithë përdoruesit e tjerë.',
+'sqlhidden' => '(Pyetje SQL e fshehur)',
+'logouttitle' => 'Përdoruesi doli',
+'logouttext' => 'Keni dalë jashtë {{SITENAME}}-s. Mund të vazhdoni të përdorni {{SITENAME}}-n anonimisht, ose mund të hyni brënda përsëri.',
+'welcomecreation' => '== Mirësevini, $1! ==
+
+Llogaria juaj është hapur. Mos harroni të ndryshoni parapëlqimet e {{SITENAME}}-s.',
+'loginpagetitle' => 'Hyrje përdoruesi',
+'yourname' => 'Fusni nofkën tuaj',
+'yourpassword' => 'Fusni fjalëkalimin tuaj',
+'yourpasswordagain' => 'Fusni fjalëkalimin përsëri',
+'remembermypassword' => 'Mbaj mënd fjalëkalimin tim për tërë vizitat e ardhshme.',
+'yourdomainname' => 'Faqja juaj',
+'externaldberror' => 'Ose kishte një gabim tek regjistri i identifikimit të jashtëm, ose nuk ju lejohet të përtërini llogarinë tuaje të jashtme.',
+'loginproblem' => '<b>Kishte një problem me hyrjen tuaj.</b><br />Provojeni përsëri!',
+'alreadyloggedin' => '<font color=red><b>Përdorues $1, keni hyrë brënda më parë!</b></font><br />',
+'login' => 'Hyni',
+'loginprompt' => 'Duhet të pranoni "biskota" për të hyrë brënda në {{SITENAME}}.',
+'userlogin' => 'Hyni ose hapni një llogari',
+'logout' => 'Dalje',
+'userlogout' => 'Dalje',
+'notloggedin' => 'Nuk keni hyrë brenda',
+'nologin' => 'Nuk keni një llogari? $1.',
+'nologinlink' => 'Hapeni',
+'createaccount' => 'Hap një llogari',
+'gotaccount' => 'Keni një llogari? $1.',
+'gotaccountlink' => 'Hyni',
+'createaccountmail' => 'me email',
+'badretype' => 'Fjalëkalimet nuk janë njësoj.',
+'userexists' => 'Nofka që përdorët është në përdorim. Zgjidhni një nofkë tjetër.',
+'youremail' => 'Adresa e email-it*',
+'username' => 'Nofka e përdoruesit:',
+'uid' => 'Nr. i identifikimit:',
+'yourrealname' => 'Emri juaj i vërtetë*',
+'yourlanguage' => 'Ndërfaqja gjuhësore',
+'yourvariant' => 'Varianti',
+'yournick' => 'Nënshkrimi',
+'badsig' => 'Sintaksa e signaturës është e pavlefshme, kontrolloni HTML-in.',
+'email' => 'Email',
+'prefs-help-email-enotif'=> 'Kjo adresë përdoret dhe për tu dërguar njoftime nëse keni mundësuar këtë parapëlqim.',
+'prefs-help-realname' => '* Emri i vërtetë (opsion): Për të përmendur emrin tuaj si kontribuues në varësi nga puna juaj këtu.',
+'loginerror' => 'Gabim hyrje',
+'prefs-help-email' => '* Email (me dëshirë): mund të përdoret për tu kontaktuar nga përdorues të tjerë pa u treguar adresën, për ndërrimin e fjalëkalimit të llogarisë nëse e harroni, apo mjete të tjera.',
+'nocookiesnew' => 'Llogaria e përdoruesit u hap, por nuk keni hyrë brenda akoma. {{SITENAME}} përdor "biskota" për të futur brenda përdoruesit. Prandaj, duhet të pranoni biskota dhe të provoni përsëri me nofkën dhe fjalëkalimin tuaj.',
+'nocookieslogin' => '{{SITENAME}} përdor "biskota" për të futur brenda përdoruesit. Prandaj, duhet të pranoni "biskota" dhe të provoni përsëri.',
+'noname' => 'Nuk keni dhënë një emër të saktë.',
+'loginsuccesstitle' => 'Hyrje me sukses',
+'loginsuccess' => 'Keni hyrë brënda në {{SITENAME}} si "$1".',
+'nosuchuser' => 'Nuk ka ndonjë përdorues me emrin "$1". Kontrolloni gërmat, ose përdorni formularin e mëposhtëm për të hapur një llogari të re.',
+'nosuchusershort' => 'Nuk ka asnjë përdorues me emrin "$1".',
+'nouserspecified' => 'Ju duhet të jepni një nofkë',
+'wrongpassword' => 'Fjalëkalimi që futët nuk është i saktë. Provoni përsëri!',
+'wrongpasswordempty' => 'Fjalëkalimi juaj ishte bosh. Ju lutemi provoni përsëri.',
+'mailmypassword' => 'Më dërgo një fjalëkalim të ri tek adresa ime',
+'passwordremindertitle' => 'Kërkesë për fjalëkalim të ri tek {{SITENAME}}',
+'passwordremindertext' => 'Dikush (ndoshta ju, nga adresa IP $1) kërkoi një fjalëkalim të ri për hyrje tek {{SITENAME}} ($4). Mund të përdoret fjalëkalimi "$3" për llogarinë e përdoruesit "$2" në qoftë se dëshironi. Nëse përdorni këtë fjalëkalim këshillohet ta ndërroni fjalëkalimin tuaj sapo të hyni.
+
+Në qoftë se nuk e përdorni këtë fjalëkalim të ri, atëherë do të vazhdojë të përdoret ai i vjetri. Nuk ka nevojë ta ndryshoni fjalëkalimin në qoftë se nuk ishit ju që kërkuat fjalëkalim të ri.',
+'noemail' => 'Regjistri nuk ka adresë për përdoruesin "$1".',
+'passwordsent' => 'Një fjalëkalim i ri është dërguar tek adresa e regjistruar për "$1". Provojeni përsëri hyrjen mbasi ta keni marrë fjalëkalimin.',
+'eauthentsent' => 'Një email konfirmues u dërgua te adresa e dhënë. Para se të pranohen email nga përdoruesit e tjerë duhet që adressa e juaj të vërtetohet. Ju lutemi ndiqni këshillat në email-in e sapodërguar.',
+'mailerror' => 'Gabim duke dërguar postën: $1',
+'acct_creation_throttle_hit'=> 'Më vjen keq, por brenda 24 orëve të fundit është hapur një llogari $1 me IP-adresën tuaj dhe në moment nuk mundeni të hapni më. Provoni 24 orë më vonë prap.',
+'emailauthenticated' => 'Adresa juaj është vërtetuar më $1.',
+'emailnotauthenticated' => 'Adresa juaj nuk është vërtetuar akoma prandaj nuk mund të merrni e-mail.',
+'noemailprefs' => '<strong>Detyrohet një adresë email-i për të përdorur këtë mjet.</strong>',
+'emailconfirmlink' => 'Vërtetoni adresën tuaj',
+'invalidemailaddress' => 'Adresa email e dhënë nuk mund të pranohet sepse nuk duket e rregullt. Ju lutem fusni një adresë të rregullt ose boshatisni kutinë e shtypit.',
+'accountcreated' => 'Llogarija e Përdoruesit u krijua',
+'accountcreatedtext' => 'Llogarija e Përdoruesit për $1 u krijua',
+'bold_sample' => 'Tekst i trashë',
+'bold_tip' => 'Tekst i trashë',
+'italic_sample' => 'Tekst i pjerrët',
+'italic_tip' => 'Tekst i pjerrët',
+'link_sample' => 'Titulli i lidhjes',
+'link_tip' => 'Lidhje e brëndshme',
+'extlink_sample' => '{{SERVER}} Titulli i lidhjes',
+'extlink_tip' => 'Lidhje e jashtme (most harro prefiksin http://)',
+'headline_sample' => 'Titull shembull',
+'headline_tip' => 'Titull i nivelit 2',
+'math_sample' => 'Vendos formulen ketu',
+'math_tip' => 'Formulë matematike (LaTeX)',
+'nowiki_sample' => 'Vendos tekst që nuk duhet të formatohet',
+'nowiki_tip' => 'Mos përdor format wiki',
+'image_sample' => 'Shembull.jpg',
+'image_tip' => 'Vendos një figurë',
+'media_sample' => 'Shembull.ogg',
+'media_tip' => 'Lidhje media-skedash',
+'sig_tip' => 'Firma juaj me gjithë kohë',
+'hr_tip' => 'vijë horizontale (përdoreni rallë)',
+'summary' => 'Përmbledhje',
+'subject' => 'Subjekt/Titull',
+'minoredit' => 'Ky është një redaktim i vogël',
+'watchthis' => 'Mbikqyre këtë faqe',
+'savearticle' => 'Kryej ndryshimet',
+'preview' => 'Parapamje',
+'showpreview' => 'Trego parapamjen',
+'showlivepreview' => 'Parapamje e menjëhershme',
+'showdiff' => 'Trego ndryshimet',
+'anoneditwarning' => 'Ju nuk jeni regjistruar. IP adresa juaj do të regjistrohet në historinë e redaktimeve të kësaj faqe.
+You are not logged in. Your IP address will be recorded in this page\'s edit history.',
+'missingsummary' => '\'\'\'Vërejtje:\'\'\' Ju nuk keni shtuar një përmbledhje për redaktimet.',
+'missingcommenttext' => 'Ju lutemi shtoni një koment në vazhdim.',
+'blockedtitle' => 'Përdoruesi është bllokuar',
+'blockedtext' => 'Emri juaj ose adresa e IP-së është bllokuar nga $1. Arsyeja e dhënë është kjo:<br />\'\'$2\'\'<br />Mund të kontaktoni $1 ose një nga [[Project:Administruesit|administruesit]] e tjerë për të diskutuar bllokimin.
+
+Vini re se nuk mund të përdorni "dërgoji email këtij përdoruesi" n.q.s. nuk keni një adresë të saktë të rregjistruar në [[Special:Preferences|parapëlqimet e përdoruesit]].
+
+Adresa e IP-së që keni është $3. Jepni këtë adresë në çdo ankesë.',
+'whitelistedittitle' => 'Duhet të hyni brënda për të redaktuar',
+'whitelistedittext' => 'Duhet të $1 për të redaktuar artikuj.',
+'whitelistreadtitle' => 'Duhet të hyni brënda për të lexuar',
+'whitelistreadtext' => 'Duhet të [[Special:Userlogin|hyni brënda]] për të lexuar artikuj.',
+'whitelistacctitle' => 'Nuk ju lejohet të hapni një llogari',
+'whitelistacctext' => 'Duhet të [[Special:Userlogin|hyni brënda]] dhe të keni të drejta të posaçme pasi tu lejohet të hapni llogari në Wiki.',
+'confirmedittitle' => 'Nevojitet adresë email-i e vërtetuar për të redaktuar',
+'confirmedittext' => 'Ju duhet së pari ta vërtetoni e-mail adresen para se të redaktoni. Ju lutem plotësoni dhe vërtetoni e-mailin tuaj te [[{ns:special}}:Preferences|parapëlqimet]] e juaja.',
+'loginreqtitle' => 'Detyrohet hyrja',
+'loginreqlink' => 'hyni',
+'loginreqpagetext' => 'Ju duhet $1 për të parë faqe e tjera.',
+'accmailtitle' => 'Fjalëkalimi u dërgua.',
+'accmailtext' => 'Fjalëkalimi për \'$1\' u dërgua tek $2.',
+'newarticle' => '(I Ri)',
+'newarticletext' => '<div style="border: 1px solid #ccc; padding: 7px;">{{SITENAME}} nuk ka akoma një \'\'{{NAMESPACE}} faqe\'\' të quajtur \'\'\'{{PAGENAME}}\'\'\'. Shtypni \'\'\'redaktoni\'\'\' më sipër ose [[Special:Search/{{PAGENAME}}|bëni një kërkim për {{PAGENAME}}]]</div>',
+'anontalkpagetext' => '---- \'\'Kjo është një faqe diskutimi për një përdorues anonim i cili nuk ka hapur akoma një llogari ose nuk e përdor atë. Prandaj, më duhet të përdor numrin e adresës [[IP adresë|IP]] për ta identifikuar. Kjo adresë mund të përdoret nga disa njerëz. Në qoftë se jeni një përdorues anonim dhe mendoni se komente kot janë drejtuar ndaj jush, ju lutem [[Special:Userlogin|krijoni një llogari ose hyni brënda]] për të mos u ngatarruar me përdorues të tjerë anonim.\'\'',
+'noarticletext' => 'Tani për tani nuk ka tekst në këtë faqe, mund ta [[Special:Search/{{PAGENAME}}|kërkoni]] këtë titull në faqe të tjera ose mund ta [{{fullurl:{{FULLPAGENAME}}|action=edit}} filloni] atë.',
+'clearyourcache' => '\'\'\'Shënim:\'\'\' Pasi të ruani parapëlqimet ose pasi të kryeni ndryshimet, duhet të pastroni \'\'cache\'\'-në e shfletuesit tuaj për të parë ndryshimet: për \'\'\'Mozilla/Safari/Konqueror\'\'\' shtypni \'\'Ctrl+Shift+Reload\'\' (ose \'\'ctrl+shift+r\'\'), për \'\'\'IE\'\'\' \'\'Ctrl+f5\'\', \'\'\'Opera\'\'\': \'\'F5\'\'.',
+'usercssjsyoucanpreview'=> '<strong>Këshillë:</strong> Përdorni butonin \'Trego parapamjen\' për të provuar ndryshimet tuaja të faqeve css/js përpara se të kryeni ndryshimet.',
+'usercsspreview' => '\'\'\'Vini re se kjo është vetëm një provë ose parapamje e faqes tuaj CSS, ajo nuk është ruajtur akoma!\'\'\'',
+'userjspreview' => '\'\'\'Vini re se kjo është vetëm një provë ose parapamje e faqes tuaj JavaScript, ajo nuk është ruajtur akoma!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Kujdes:\'\'\' Nuk ka pamje të quajtur "$1". Vini re se faqet .css dhe .js përdorin titull me gërma të vogla, p.sh. Përdoruesi:Foo/monobook.css, jo Përdoruesi:Foo/Monobook.css.',
+'updated' => '(E ndryshuar)',
+'note' => '<strong>Shënim:</strong>',
+'previewnote' => 'Kini kujdes se kjo është vetëm një parapamje, nuk është ruajtur akoma!',
+'session_fail_preview' => '<strong>Ju kërkoj ndjesë. Nuk munda të kryej redaktimin tuaj sepse humba disa të dhëna. Provojeni përsëri dhe nëse nuk punon provoni të dilni dhe të hyni përsëri.</strong>',
+'previewconflict' => 'Kjo parapamje reflekton tekstin sipër kutisë së redaktimit siç do të duket kur të kryeni ndryshimin.',
+'importing' => 'Duke importuar $1',
+'editing' => 'Duke redaktuar $1',
+'editinguser' => 'Duke redaktuar $1',
+'editingsection' => 'Duke redaktuar $1 (seksion)',
+'editingcomment' => 'Duke redaktuar $1 (koment)',
+'editconflict' => 'Konflikt redaktimi: $1',
+'explainconflict' => 'Dikush tjetër ka ndryshuar këtë faqe kur ju po e redaktonit. Kutiza e redaktimit mësipërme tregon tekstin e faqes siç ekziston tani. Ndryshimet juaja janë treguar poshtë kutisë së redaktimit. Ju duhet të përputhni ndryshimet tuaja me tekstin ekzistues. <b>Vetëm</b> teksti në kutinë e sipërme të redaktimit do të ruhet kur të shtypni "Ruaje faqen".',
+'yourtext' => 'Teksti juaj',
+'storedversion' => 'Versioni i ruajtur',
+'nonunicodebrowser' => '<strong>KUJDES: Shfletuesi juaj nuk përdor dot unikode, ju lutem ndryshoni shfletues para se të redaktoni artikuj.</strong>',
+'editingold' => '<strong>KUJDES: Po redaktoni një version të vjetër të kësaj faqeje. Në qoftë se e ruani, çdo ndryshim i bërë deri tani do të humbet.</strong>',
+'yourdiff' => 'Ndryshimet',
+'copyrightwarning' => 'Kontributet tek {{SITENAME}} janë të konsideruara të dhëna nën licensën $2 (shikoni $1 për hollësirat).<br />
+\'\'\'NDALOHET DHËNIA E PUNIMEVE PA PASUR LEJE NGA AUTORI NË MOSPËRPUTHJE ME KËTË LICENSË!\'\'\'<br />',
+'copyrightwarning2' => 'Ju lutem vini re se të gjitha kontributet tek {{SITENAME}} mund të redaktohen, ndryshohen apo fshihen nga përdorues të tjerë. Në qoftë se nuk dëshironi që shkrimet tuaja të redaktohen pa mëshirë mos i jepni këtu.<br />
+Po na premtoni që ç\'ka po jepni këtu e keni kontributin tuaj ose e keni kopjuar nga domeni publik apo nga burime të tjera të lira sipas ligjeve përkatëse (shikoni $1 për hollësirat).
+<strong>NDALOHET DHËNIA E PUNIMEVE PA PASUR LEJE NGA AUTORI NË MOSPËRPUTHJE ME KËTË LICENSË!</strong>',
+'longpagewarning' => 'KUJDES: Kjo faqe është $1 kilobytes e gjatë; disa
+shfletues mund të kenë probleme për të redaktuar faqe që afrohen ose janë akoma më shumë se 32kb.
+Konsideroni ta ndani faqen në disa seksione më të vogla.',
+'longpageerror' => '<strong>GABIM: Tesksti që ju po e redaktoni ka madhësi $1 KB dhe kjo është më shumë se maksimumi i lejuar prej $2 KB. Ndryshimet nuk mund të ruhen.</strong>',
+'readonlywarning' => 'KUJDES: Regjistri është bllokuar për mirëmbajtje,
+kështuqë nuk do keni mundësi të ruani redaktimet e tuaja tani. Mund të kopjoni dhe ruani tekstin në një skedë për më vonë.',
+'protectedpagewarning' => 'KUJDES: Kjo faqe është bllokuar kështuqë vetëm përdorues me titullin sysop mund ta redaktojnë. Ju lutem ndiqni rregullat e dhëna tek [[Project:Faqe e mbrojtur|faqet e mbrojtura]].',
+'semiprotectedpagewarning'=> '\'\'\'Shënim:\'\'\' Redaktimi i kësaj faqeje mund të bëhet vetëm nga përdorues të regjistruar.',
+'templatesused' => 'Stampa të përdorura në këtë faqe:',
+'edittools' => '<!-- Teksti këtu do të tregohet poshtë kutive të redaktimit dhe ngarkimit të skedave. -->',
+'nocreatetitle' => 'Krijimi i faqeve të reja është i kufizuar.',
+'nocreatetext' => 'Mundësia për të krijuar faqe të reja është kufizuar. Duhet të [[Special:Userlogin|hyni ose të hapni një llogari]] për të krijuar faqe të reja, ose mund të ktheheni mbrapsh dhe të redaktoni një faqe ekzistuese.',
+'revhistory' => 'Historia e redaktimeve',
+'nohistory' => 'Nuk ka histori redaktimesh për këtë faqe.',
+'revnotfound' => 'Versioni nuk u gjet',
+'revnotfoundtext' => 'Versioni i vjetër i faqes së kërkuar nuk mund të gjehej.Ju lutem kontrolloni URL-in që përdorët për të ardhur tek kjo faqe.',
+'loadhist' => 'Duke ngarkuar historinë e faqes',
+'currentrev' => 'Versioni i tanishëm',
+'revisionasof' => 'Versioni i $1',
+'previousrevision' => '← Version më i vjetër',
+'nextrevision' => 'Version më i ri →',
+'currentrevisionlink' => 'shikoni versionin e tanishëm',
+'cur' => 'tani',
+'next' => 'mbas',
+'last' => 'fund',
+'orig' => 'Origjinal',
+'histlegend' => 'Legjenda: (tani) = ndryshimet me versionin e tanishëm,
+(fund) = ndryshimet me versionin e parardhshëm, V = redaktim i vogël',
+'deletedrev' => '[u gris]',
+'histfirst' => 'Së pari',
+'histlast' => 'Së fundmi',
+'rev-deleted-comment' => '(kometi u largua)',
+'rev-deleted-user' => '(përdoruesi u largua)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks">
+Ky version i faqes është shlyer nga arkivi publik i faqes.
+Shiko tek [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} regjistri i grisjeve], ndoshta gjenden atje më shumë informacione rreth kësaj.
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Ky version i faqes është shlyer nga arkivi publik i faqes. Ju si Administrator mund ta shikoni akoma këtë.
+Shiko tek [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} regjistri i grisjeve], ndoshta gjenden atje më shumë informacione rreth kësaj.
+</div>',
+'rev-delundel' => 'trego/fshih',
+'history-feed-title' => 'Historiku i versioneve',
+'history-feed-description'=> 'Historiku i versioneve për këtë faqe në wiki',
+'history-feed-item-nocomment'=> '$1 tek $2',
+'history-feed-empty' => 'Faqja që kërkuat nuk ekziston. Ajo mund të jetë grisur nga wiki ose mund të jetë zhvendosur nën një emër tjetër. Mund të provoni ta gjeni duke e [[Special:Search|kërkuar]].',
+'revisiondelete' => 'Shlyj/Reparo versionet',
+'revdelete-selected' => 'Versionet e zgjedhura për [[:$1]]:',
+'revdelete-text' => 'Përmbajtja dhe pjesët e tjera nuk janë të dukshme për të gjithë, por figurojnë në historikun e versioneve. Administratorët munden përmbajtjen e larguar ta shikojnë dhe restaurojnë, përveç në rastet kur një gjë e tillë është ndaluar ekstra.',
+'revdelete-legend' => 'Vendosni kufizimet për versionin:',
+'revdelete-hide-text' => 'Fshihe tekstin e versionit',
+'revdelete-hide-comment'=> 'fshih komentin e redaktimit',
+'revdelete-hide-user' => 'Fshihe emrin/IP-në të redaktuesit',
+'revdelete-hide-restricted'=> 'Këto përkufizme vlejnë edhe për Admintratorët (jo vetëm për përdoruesit "normal")',
+'revdelete-log' => 'Arsyeja:',
+'revdelete-submit' => 'Apliko te versionet e zgjedhura',
+'revdelete-logentry' => 'Pamja e versionit u ndryshua për [[$1]]',
+'difference' => '(Ndryshime midis versioneve)',
+'loadingrev' => 'duke ngarkuar versionin për ndryshimin',
+'lineno' => 'Rreshti $1:',
+'editcurrent' => 'Redaktoni versionin e tanishëm të kësaj faqeje',
+'selectnewerversionfordiff'=> 'Zgjidhni një version më të ri për krahasim',
+'selectolderversionfordiff'=> 'Zgjidhni një version më të vjetër për krahasim',
+'compareselectedversions'=> 'Krahasoni versionet e zgjedhura',
+'searchresults' => 'Përfundimet e kërkimit',
+'searchresulttext' => '<!-- -->',
+'searchsubtitle' => 'Kërkim për "[[$1]]"',
+'searchsubtitleinvalid' => 'Kërkim për "$1"',
+'badquery' => 'Pyetje kërkese e formuluar gabim',
+'badquerytext' => 'Nuk munda t\'i përgjigjem pyetjes tuaj. Kjo ka mundësi të ketë ndodhur ngaqë provuat të kërkoni për një fjalë me më pak se tre gërma, gjë që s\'mund të behet akoma. Ka mundësi që edhe të keni shtypur keq pyetjen, për shembull "peshku dhe dhe halat". Provoni një pyetje tjetër.',
+'matchtotals' => 'Pyetja "$1" u përpuq $2 tituj faqesh
+dhe teksti i $3 artikujve te pasardhshëm.',
+'noexactmatch' => '<span style="font-size: 135%; font-weight: bold; margin-left: .6em">Faqja me atë titull nuk është krijuar akoma</span>
+
+<span style="display: block; margin: 1.5em 2em">
+Mund të [[$1|filloni një artikull]] me këtë titull.
+
+<span style="display:block; font-size: 89%; margin-left:.2em">Ju lutem kërkoni {{SITENAME}}-n përpara se të krijoni një artikull të ri se mund të jetë nën një titull tjetër.</span>
+</span>',
+'titlematches' => 'Tituj faqesh që përputhen',
+'notitlematches' => 'Nuk ka asnjë titull faqeje që përputhet',
+'textmatches' => 'Tekst faqesh që përputhet',
+'notextmatches' => 'Nuk ka asnjë tekst faqeje që përputhet',
+'prevn' => '$1 më para',
+'nextn' => '$1 më pas',
+'viewprevnext' => 'Shikoni ($1) ($2) ($3).',
+'showingresults' => 'Më poshtë tregohen <b>$1</b> përfundime duke filluar me #<b>$2</b>.',
+'showingresultsnum' => 'Më poshtë tregohen <b>$3</b> përfundime duke filluar me #<b>$2</b>.',
+'nonefound' => '<strong>Shënim</strong>: kërkimet pa përfundime ndodhin kur kërkoni për fjalë që rastisen shpesh si "ke" and "nga", të cilat nuk janë të futura në regjistër, ose duke dhënë më shumë se një fjalë (vetëm faqet që i kanë të gjitha ato fjalë do të tregohen si përfundime).',
+'powersearch' => 'Kërko',
+'powersearchtext' => 'Kërko në hapësirën:<br />
+$1<br />
+$2 Lidhje përcjellëse Kërko për $3 $9',
+'searchdisabled' => '<p>Kërkimi me tekst të plotë është bllokuar tani për tani ngaqë shërbyesi është shumë i ngarkuar; shpresojmë ta nxjerrim prapë në gjendje normale pas disa punimeve. Deri atëherë mund të përdorni Google-in për kërkime:</p>',
+'blanknamespace' => '(Artikujt)',
+'preferences' => 'Parapëlqimet',
+'prefsnologin' => 'Nuk keni hyrë brenda',
+'prefsnologintext' => 'Duhet të keni [[Special:Userlogin|hyrë brenda]] për të ndryshuar parapëlqimet e përdoruesit.',
+'prefsreset' => 'Parapëlqimet janë rikthyer siç ishin.',
+'qbsettings' => 'Vendime të shpejta',
+'changepassword' => 'Ndërroni fjalëkalimin',
+'skin' => 'Pamja',
+'math' => 'Formula',
+'dateformat' => 'Data',
+'datedefault' => 'Parazgjedhje',
+'datetime' => 'Data dhe Ora',
+'math_failure' => 'Nuk e kuptoj',
+'math_unknown_error' => 'gabim i panjohur',
+'math_unknown_function' => 'funksion i panjohur',
+'math_lexing_error' => 'gabim leximi',
+'math_syntax_error' => 'gabim sintakse',
+'math_image_error' => 'Konversioni PNG dështoi; kontrolloni për ndonjë gabim instalimi të latex-it, dvips-it, gs-it, dhe convert-it.',
+'math_bad_tmpdir' => 'Nuk munda të shkruaj ose krijoj dosjen e përkohshme për matematikë',
+'math_bad_output' => 'Nuk munda të shkruaj ose të krijoj prodhimin matematik në dosjen',
+'math_notexvc' => 'Mungon zbatuesi texvc; ju lutem shikoni math/README për konfigurimin.',
+'prefs-personal' => 'Përdoruesi',
+'prefs-rc' => 'Ndryshime së fundmi',
+'prefs-watchlist' => 'Lista mbikqyrëse',
+'prefs-watchlist-days' => 'Numri i ditëve të treguara tek lista mbikqyrëse:',
+'prefs-watchlist-edits' => 'Numri i redaktimeve të treguara tek lista mbikqyrëse e zgjeruar:',
+'prefs-misc' => 'Të ndryshme',
+'saveprefs' => 'Ruaj parapëlqimet',
+'resetprefs' => 'Rikthe parapëlqimet',
+'oldpassword' => 'I vjetri',
+'newpassword' => 'I riu',
+'retypenew' => 'I riu përsëri',
+'textboxsize' => 'Redaktimi',
+'rows' => 'Rreshta',
+'columns' => 'Kolona',
+'searchresultshead' => 'Kërkimi',
+'resultsperpage' => 'Sa përputhje të tregohen për faqe',
+'contextlines' => 'Sa rreshta të tregohen për përputhje',
+'contextchars' => 'Sa germa të tregohen për çdo rresht',
+'stubthreshold' => 'Kufiri për tregimin e cungjeve',
+'recentchangescount' => 'Numri i titujve në ndryshime së fundmi',
+'savedprefs' => 'Parapëlqimet tuaja janë ruajtur.',
+'timezonelegend' => 'Ora',
+'timezonetext' => 'Fusni numrin e orëve prej të cilave ndryshon ora lokale nga ajo e shërbyesit (UTC).',
+'localtime' => 'Tregimi i orës lokale',
+'timezoneoffset' => 'Ndryshimi',
+'servertime' => 'Ora e shërbyesit tani është',
+'guesstimezone' => 'Gjeje nga shfletuesi',
+'allowemail' => 'Lejo përdoruesit të më dërgojnë email',
+'defaultns' => 'Kërko automatikisht vetëm në këto hapësira:',
+'default' => 'parazgjedhje',
+'files' => 'Figura',
+'userrights-lookup-user'=> 'Ndrysho grupet e përdoruesit',
+'userrights-user-editname'=> 'Fusni emrin e përdoruesit:',
+'editusergroup' => 'Trego zgjedhjet',
+'userrights-editusergroup'=> 'Anëtarësimi tek grupet',
+'saveusergroups' => 'Kryej ndryshimet',
+'userrights-groupsmember'=> 'Anëtar i:',
+'userrights-groupsavailable'=> 'Të mundshme:',
+'userrights-groupshelp' => 'Duke zgjedhur nga lista e anëtarësimit mund të çanëtarësosh, dhe duke zgjedhur nga lista e grupeve të mundshme mund të anëtarësosh. Nuk do të ndryshojë anëtarësimi tek grupet e pazgjedhura. Mund të zgjedhësh ose çzgjedhësh duke mbajtur shtypur butonin Ctrl dhe majtas-shtypur.',
+'group' => 'Grupi:',
+'group-bot' => 'Robot',
+'group-sysop' => 'Administrues',
+'group-bureaucrat' => 'Burokrat',
+'group-all' => '(të gjitha)',
+'group-bot-member' => 'Robot',
+'group-sysop-member' => 'Administrues',
+'group-bureaucrat-member'=> 'Burokrat',
+'grouppage-bot' => 'Project:Robotë',
+'grouppage-sysop' => 'Project:Administrues',
+'grouppage-bureaucrat' => 'Project:Burokratë',
+'changes' => 'ndryshime',
+'recentchanges' => 'Ndryshime së fundmi',
+'recentchangestext' => 'Ndiqni ndryshime së fundmi tek kjo faqe.',
+'rcnote' => 'Më poshtë janë <strong>$1</strong> ndryshime së fundmi gjatë <strong>$2</strong> ditëve sipas të dhënave nga $3.',
+'rcnotefrom' => 'Më poshtë janë ndryshime së fundmi nga <b>$2</b> (treguar deri në <b>$1</b>).',
+'rclistfrom' => 'Trego ndryshime së fundmi duke filluar nga $1',
+'rcshowhideminor' => '$1 redaktimet e vogla',
+'rcshowhidebots' => '$1 robotët',
+'rcshowhideliu' => '$1 përdoruesit e regjistruar',
+'rcshowhideanons' => '$1 përdoruesit anonim',
+'rcshowhidepatr' => '$1 redaktime të patrulluara',
+'rcshowhidemine' => '$1 redaktimet e mia',
+'rclinks' => 'Trego $1 ndryshime gjatë $2 ditëve<br />$3',
+'diff' => 'ndrysh',
+'hist' => 'hist',
+'hide' => 'fshih',
+'show' => 'trego',
+'minoreditletter' => 'v',
+'newpageletter' => 'R',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[nën mbikqyrje nga $1 përdorues]',
+'rc_categories' => 'Kufizimi i kategorive (të ndara me "|")',
+'rc_categories_any' => 'Të gjitha',
+'upload' => 'Ngarkoni skeda',
+'uploadbtn' => 'Ngarkoje',
+'reupload' => 'Ngarkojeni përsëri',
+'reuploaddesc' => 'Kthehu tek formulari i dhënies.',
+'uploadnologin' => 'Nuk keni hyrë brënda',
+'uploadnologintext' => 'Duhet të keni [[Special:Userlogin|hyrë brenda]] për të dhënë skeda.',
+'upload_directory_read_only'=> 'Skedari i ngarkimit ($1) nuk mund të shkruhet nga shërbyesi.',
+'uploaderror' => 'Gabim dhënie',
+'uploadtext' => '\'\'\'NDALO!\'\'\' Përpara se të jepni këtu skedë, lexoni dhe ndiqni [[Project:Rregullat e përdorimit të figurave|Rregullat e përdorimit të figurave]] të {{SITENAME}}-s. Mos jepni skeda për të cilat autori (ose ju) nuk ka dhënë të drejtë për përdorim nën licencat e përdorura nga {{SITENAME}}.
+
+Për të parë ose për të kërkuar figurat e dhëna më parë,
+shkoni tek [[Special:Imagelist|lista e figurave të dhëna]].
+Dhëniet dhe grisjet janë të regjistruara në [[Special:Log|faqen e regjistrave]].
+
+Përdorni formularin e më poshtëm për të dhënë skeda të figurave të reja për tu përdorur në ilustrimet e artikujve. Për shumicën e shfletuesve, do të shihni një buton "Browse...", i cili do të hapi dialogun standard të skedave të sistemit operativ që përdorni.
+
+Për të vendosur një figurë në një artikull, përdorni lidhjen sipas formës
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Skeda.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Skeda.png|tekst përshkrues]]</nowiki>\'\'\'
+ose të tjerë
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Skeda.ogg]]</nowiki>\'\'\'.
+
+Përdorni stampa tek përshkrimi për të cilësuar licencën e duhur.',
+'uploadlog' => 'regjistër dhënjesh',
+'uploadlogpage' => 'Regjistri i ngarkimeve',
+'uploadlogpagetext' => 'Më poshtë është një listë e skedave më të reja që janë ngarkuar.
+Të gjithë orët janë me orën e shërbyesit (UTC).
+<ul>
+</ul>',
+'filename' => 'Emri i skedës',
+'filedesc' => 'Përmbledhje',
+'fileuploadsummary' => 'Përshkrimi:',
+'filestatus' => 'Gjendja e të drejtave të autorit',
+'filesource' => 'Burimi',
+'copyrightpage' => 'Project:Të drejta autori',
+'copyrightpagename' => '{{SITENAME}} Të drejta autori',
+'uploadedfiles' => 'Ngarkoni skeda',
+'ignorewarning' => 'Shpërfille paralajmërimin dhe ruaje skedën.',
+'ignorewarnings' => 'Shpërfill çdo paralajmërim',
+'minlength' => 'Emrat e skedave duhet të kenë të paktën tre germa.',
+'illegalfilename' => 'Skeda "$1" përmban gërma që nuk lejohen tek titujt e faqeve. Ju lutem ndërrojani emrin dhe provoni ta ngarkoni përsëri.',
+'badfilename' => 'Emri i skedës është ndërruar në "$1".',
+'badfiletype' => '".$1" nuk rekomandohet si tip skede.',
+'largefile' => 'Rekomandohet që skedat të mos kalojnë $1B në madhësi. Kjo skedë është $2B.',
+'largefileserver' => 'Skeda është më e madhe se sa serveri e lejon këtë.',
+'emptyfile' => 'Skeda që keni dhënë është bosh ose mbi madhësinë e lejushme. Kjo gjë mund të ndodhi nëse shtypni emrin gabim, prandaj kontrolloni nëse dëshironi të jepni skedën me këtë emër.',
+'fileexists' => 'Ekziston një skedë me atë emër, ju lutem kontrolloni $1 në qoftë se nuk jeni të sigurt nëse dëshironi ta zëvendësoni.',
+'fileexists-forbidden' => 'Ekziston një skedë me të njëjtin emër. Ju lutemi kthehuni prapë dhe ngarkoni këtë skedë me një emër të ri. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Ekziston një skedë me të njëjtin emër në magazinën e përbashkët. Ju lutem kthehuni mbrapsh dhe ngarkojeni këtë skedë me një emër të ri. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Dhënie e sukseshme',
+'fileuploaded' => 'Skeda "$1" u ngarkua me sukses. Ju lutem ndiqni këtë lidhje : ($2) për të shkuar tek faqja e përshkrimit dhe për të futur
+informacion për skedën, si p.sh. ku e gjetët, kur u bë, kush e bëri, dhe çdo gjë tjetër që na duhet të dimë për të.',
+'uploadwarning' => 'Kujdes dhënie',
+'savefile' => 'Ruaj skedën',
+'uploadedimage' => 'dha "[[$1]]"',
+'uploaddisabled' => 'Ndjesë, dhëniet janë bllokuar në këtë shërbyes dhe nuk është gabimi juaj.',
+'uploaddisabledtext' => 'Ngarkimi i skedave është ndaluar tek ky wiki.',
+'uploadscripted' => 'Skeda përmban HTML ose kode të tjera që mund të interpretohen gabimisht nga një shfletues.',
+'uploadcorrupt' => 'Skeda është e dëmtuar ose ka emër të gabuar. Ju lutemi kontrolloni skedën dhe ngarkoni atë përsëri.',
+'uploadvirus' => 'Skeda përmban një virus! Detaje: $1',
+'sourcefilename' => 'Emri i skedës',
+'destfilename' => 'Emri mbas dhënies',
+'filewasdeleted' => 'Një skedë më këtë emër është ngarkuar një here dhe pastaj është grisur. Duhet të shikoni $1 përpara se ta ngarkoni përsëri.',
+'license' => 'Licensimi',
+'nolicense' => 'Asnjë nuk është zgjedhur',
+'imagelist' => 'Lista e figurave',
+'imagelisttext' => 'Më poshtë është një listë e $1 figurave të renditura sipas $2.',
+'imagelistforuser' => 'Kjo faqe tregon skedat të ngarkuara nga $1.',
+'getimagelist' => 'duke ngarkuar të gjithë listën e figurave',
+'ilsubmit' => 'Kërko',
+'showlast' => 'Trego $1 figurat e fundit të renditura sipas $2.',
+'byname' => 'emrit',
+'bydate' => 'datës',
+'bysize' => 'madhësisë',
+'imgdelete' => 'gris',
+'imgdesc' => 'për',
+'imglegend' => 'Legjendë: (për) = trego/redakto përshkrimin e skedës.',
+'imghistory' => 'Historia e skedës',
+'revertimg' => 'ktheje',
+'deleteimg' => 'grise',
+'deleteimgcompletely' => 'grise',
+'imghistlegend' => 'Legjendë: (tani) = kjo është skeda e tanishme, (grise) = grise
+këtë version të vjetër, (ktheje) = ktheje në këtë version të vjetër.
+<br /><i>Shtyp datën për të parë skedën e dhënë në atë ditë</i>.',
+'imagelinks' => 'Lidhje skedash',
+'linkstoimage' => 'Këto faqe lidhen tek kjo skedë:',
+'nolinkstoimage' => 'Asnjë faqe nuk lidhet tek kjo skedë.',
+'sharedupload' => 'Kjo skedë është një ngarkim i përbashkët dhe mund të përdoret nga projekte të tjera.',
+'shareduploadwiki' => 'Ju lutem shikoni $1 për më shumë informacion.',
+'shareduploadwiki-linktext'=> 'faqja përshkruese e skedës',
+'noimage' => 'Një skedë me këtë emër nuk ekziston akoma, ju mundeni ta $1 atë.',
+'noimage-linktext' => 'ngarkoni',
+'uploadnewversion-linktext'=> 'Ngarkoni një version të ri të kësaj skede',
+'mimesearch' => 'Kërkime MIME',
+'mimetype' => 'Lloji MIME:',
+'download' => 'shkarkim',
+'unwatchedpages' => 'Shiko faqet e pambikqyrura',
+'listredirects' => 'Lista e përcjellimeve',
+'unusedtemplates' => 'Stampa të papërdorura',
+'unusedtemplatestext' => 'Kjo faqe jep listën e të gjitha faqeve nën hapësirën Stampa të cilat nuk janë përdorur në faqe të tjera. Kujtohu të kontrollosh edhe për lidhje tek stampat përpara se t\'i grisësh si të papërdorura.',
+'unusedtemplateswlh' => 'lidhje',
+'randomredirect' => 'Përcjellim i rastit',
+'statistics' => 'Statistika',
+'sitestats' => 'Statistikat e faqeve',
+'userstats' => 'Statistikat e përdoruesve',
+'sitestatstext' => 'Gjënden \'\'\'$1\'\'\' faqe në totalin e regjistrit. Këto përfshijnë faqet e "diskutimit", faqe rreth {{SITENAME}}-s, faqe "cungje" të vogla, përcjellime, dhe faqe të tjera që ndoshta nuk kualifikohen si artikuj. Duke mos i përfshirë këto, gjënden \'\'\'$2\'\'\' faqe që janë artikuj të ligjshëm.
+
+Janë bërë \'\'\'$3\'\'\' shikime dhe \'\'\'$4\'\'\' redaktime faqesh që nga dita kur wiki u hap. Kjo do të thotë se janë bërë afërsisht \'\'\'$5\'\'\' redaktime për faqe, dhe \'\'\'$6\'\'\' shikime për redaktim.
+
+Gjithashtu janë ngarkuar \'\'\'$8\'\'\' skeda.
+
+Gjatësia e [http://meta.wikimedia.org/wiki/Help:Job_queue radhës së punëve] është \'\'\'$7\'\'\'.',
+'userstatstext' => 'Gjënden \'\'\'$1\'\'\' përdorues të regjistruar. \'\'\'$2\'\'\' prej tyre (ose \'\'\'$4\'\'\'%) janë me titull administrues (shikoni [[Special:Listusers|Listën e përdoruesve]] dhe $3).',
+'disambiguations' => 'Faqe kthjelluese',
+'disambiguationspage' => 'Template:Kthjellim',
+'disambiguationstext' => 'Artikujt që vijojnë lidhen tek një <i>faqe kthjelluese</i>. Ato duhet të lidhen tek tema e përshtatshme.
+
+Një faqe trajtohet si kthjelluese nëse lidhet nga $1.
+
+Lidhje nga hapësira të tjera përveç asaj kryesore <b>nuk</b> jepen këtu.',
+'doubleredirects' => 'Përcjellime dopjo',
+'doubleredirectstext' => '<b>Kujdes:</b> Kjo listë mund të ketë lidhje gabim. D.m.th. ka tekst dhe lidhje mbas #REDIRECT-it të parë.
+
+<br />
+Çdo rresht ka lidhje tek përcjellimi i parë dhe i dytë, gjithashtu ka edhe rreshtin e parë të tekstit të përcjellimit të dytë, duke dhënë dhe artikullin e "vërtetë", me të cilin përcjellimi i parë duhet të lidhet.',
+'brokenredirects' => 'Përcjellime të prishura',
+'brokenredirectstext' => 'Përcjellimet që vijojnë lidhen tek një artikull që s\'ekziston.',
+'nbytes' => '$1 bytes',
+'ncategories' => '$1 kategori',
+'nlinks' => '$1 lidhje',
+'nmembers' => '$1 anëtarë',
+'nrevisions' => '$1 redaktime',
+'nviews' => '$1 shikime',
+'lonelypages' => 'Faqe të palidhura',
+'uncategorizedpages' => 'Faqe të pakategorizuara',
+'uncategorizedcategories'=> 'Kategori të pakategorizuara',
+'uncategorizedimages' => 'Figura të pakategorizuara',
+'unusedcategories' => 'Kategori të papërdorura',
+'unusedimages' => 'Figura të papërdorura',
+'popularpages' => 'Artikuj të frekuentuar shpesh',
+'wantedcategories' => 'Kategori më të dëshiruara',
+'wantedpages' => 'Artikuj më të dëshiruar',
+'mostlinked' => 'Faqe më të lidhura',
+'mostlinkedcategories' => 'Kategori më të lidhura',
+'mostcategories' => 'Artikuj më të kategorizuar',
+'mostimages' => 'Figura më të lidhura',
+'mostrevisions' => 'Artikuj më të redaktuar',
+'allpages' => 'Të gjitha faqet',
+'prefixindex' => 'Treguesi i parashtesave',
+'randompage' => 'Artikull i rastit',
+'shortpages' => 'Artikuj të shkurtër',
+'longpages' => 'Artikuj të gjatë',
+'deadendpages' => 'Faqe pa rrugëdalje',
+'listusers' => 'Lista e përdoruesve',
+'specialpages' => 'Faqet speciale',
+'spheading' => 'Faqe speciale për të gjithë përdoruesit',
+'restrictedpheading' => 'Faqe speciale të kufizuara',
+'recentchangeslinked' => 'Ndryshimet fqinje',
+'rclsub' => '(për faqet e lidhura nga "$1")',
+'newpages' => 'Artikuj të rinj',
+'ancientpages' => 'Artikuj më të vjetër',
+'intl' => 'Gjuhë-lidhje',
+'move' => 'Zhvendose',
+'movethispage' => 'Zhvendose faqen',
+'unusedimagestext' => '<p>Ju lutem, vini re se hapësira të tjera si p.sh ato që kanë të bëjnë me gjuhë të ndryshme mund të lidhin
+një figurë me një URL në mënyrë direkte, kështuqë ka mundësi që këto figura të rreshtohen këtu megjithëse janë në përdorim.</p>',
+'unusedcategoriestext' => 'Kategoritë në vazhdim ekzistojnë edhe pse asnjë artikull ose kategori nuk i përdor ato.',
+'booksources' => 'Burime librash',
+'categoriespagetext' => 'Ndodhen këto kategori:',
+'data' => 'Të dhëna',
+'userrights' => 'Ndrysho privilegjet e përdoruesve',
+'groups' => 'Grupet e përdoruesve',
+'booksourcetext' => 'Më poshtë është një listë me faqe interneti që shesin libra të rinj dhe të përdorur. Atje mund të gjeni më shumë informacione për librat që kërkoni. {{SITENAME}} nuk ka marrëdhënie biznesi me asnjërin prej këtyre firmave dhe nuk përfiton prej tyre. Për këtë arsye nuk duhet të shikohet kjo listë si reklamë.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 deri në $2',
+'version' => 'Versioni',
+'log' => 'Regjistrat',
+'alllogstext' => 'Kjo faqe tregon një pamje të përmbledhur të regjistrave të ngarkimeve, grisjeve, mbrojtjeve, bllokimeve, dhe të veprimeve administrative. Mundeni të kufizoni informactionin sipas tipit të regjistrit, emrit të përdoruesit, si dhe faqes në çështje.',
+'logempty' => 'Nuk ka asnjë përputhje në regjistër.',
+'nextpage' => 'Faqja më pas ($1)',
+'allpagesfrom' => 'Trego faqet duke filluar nga:',
+'allarticles' => 'Të gjithë artikujt',
+'allinnamespace' => 'Të gjitha faqet (hapësira $1)',
+'allnotinnamespace' => 'Të gjitha faqet (jo në hapësirën $1)',
+'allpagesprev' => 'Më para',
+'allpagesnext' => 'Më pas',
+'allpagessubmit' => 'Shko',
+'allpagesprefix' => 'Trego faqet me parashtesë:',
+'mailnologin' => 'S\'ka adresë dërgimi',
+'mailnologintext' => 'Duhet të keni [[{ns:special}}:Userlogin|hyrë brenda]] dhe të keni një adresë të saktë në [[{ns:special}}:Preferences|parapëlqimet]] tuaja për tu dërguar email përdoruesve të tjerë.',
+'emailuser' => 'Email përdoruesit',
+'emailpage' => 'Dërgo email përdoruesve',
+'emailpagetext' => 'Në qoftë se ky përdorues ka dhënë një adresë të saktë në parapëlqimet, formulari më poshtë do t\'i dërgojë një mesazh.
+
+Adresa e email-it që keni dhënë në parapëlqimet do të duket si pjesa "From" e adresës së mesazhit, kështuqë marrësi do të ketë mundësi tu përgjigjet.',
+'usermailererror' => 'Objekti postal ktheu gabimin:',
+'defemailsubject' => '{{SITENAME}} email',
+'noemailtitle' => 'S\'ka adresë email-i',
+'noemailtext' => 'Ky përdorues s\'ka dhënë një adresë të saktë,
+ose ka vendosur të mos pranojë mesazhe email-i nga përdorues të tjerë.',
+'emailfrom' => 'Nga',
+'emailto' => 'Për',
+'emailsubject' => 'Subjekti',
+'emailmessage' => 'Mesazh',
+'emailsend' => 'Dërgo',
+'emailsent' => 'Email-i u dërgua',
+'emailsenttext' => 'Email-i është dërguar.',
+'watchlist' => 'Lista mbikqyrëse',
+'nowatchlist' => 'Nuk keni asnjë faqe në listën mbikqyrëse.',
+'watchlistcount' => '\'\'\'Keni $1 faqe nën mbikqyrje duke përfshirë dhe faqet e diskutimit.\'\'\'',
+'clearwatchlist' => 'Pastroni listën mbikqyrëse',
+'watchlistcleartext' => 'Dëshironi me të vërtetë ta boshatisni listën?',
+'watchlistclearbutton' => 'Boshatise listën mbikqyrëse',
+'watchlistcleardone' => 'Lista mbikqyrëse është boshatisur. Janë hequr $1 faqe.',
+'watchnologin' => 'Nuk keni hyrë brënda',
+'watchnologintext' => 'Duhet të keni [[Special:Userlogin|hyrë brenda]] për të ndryshuar listën mbikqyrëse.',
+'addedwatch' => 'U shtua tek lista mbikqyrëse',
+'addedwatchtext' => 'Faqja "$1" është shtuar [[Special:Watchlist|listës mbikqyrëse]] tuaj. Ndryshimet e ardhshme të kësaj faqeje dhe faqes së diskutimit të saj do të jepen më poshtë, dhe emri i faqes do të duket i \'\'\'trashë\'\'\' në [[Special:Recentchanges|listën e ndryshimeve së fundmi]] për t\'i dalluar më kollaj.
+
+Në qoftë se dëshironi të hiqni një faqe nga lista mbikqyrëse më vonë, shtypni "çmbikqyre" në tabelën e sipërme.',
+'removedwatch' => 'U hoq nga lista mibkqyrëse',
+'removedwatchtext' => 'Faqja "$1" është hequr nga lista mbikqyrëse e juaj.',
+'watch' => 'Mbikqyre',
+'watchthispage' => 'Mbikqyre këtë faqe',
+'unwatch' => 'Çmbikqyre',
+'unwatchthispage' => 'Mos e mbikqyr',
+'notanarticle' => 'Nuk është artikull',
+'watchnochange' => 'Asnjë nga artikujt nën mbikqyrje nuk është redaktuar gjatë kohës së dhënë.',
+'watchdetails' => '*\'\'\'$1\'\'\' faqe nën mbikqyrje duke mos numëruar faqet e diskutimit
+*\'\'\'$2\'\'\' faqe brënda përkufizimit janë redaktuar
+<!--*$3...-->
+<center>\'\'\'[$4 Trego dhe redakto tërë listën]\'\'\'</center>',
+'wlheader-enotif' => '* Njoftimi me email është lejuar.',
+'wlheader-showupdated' => '* Faqet që kanë ndryshuar nga vizita juaj e fundit do të tregohen të \'\'\'trasha\'\'\'',
+'watchmethod-recent' => 'duke parë ndryshime së fundmi për faqe nën mbikqyrje',
+'watchmethod-list' => 'duke parë faqet nën mbikqyrje për ndryshime së fundmi',
+'removechecked' => 'Hiq të zgjedhurat',
+'watchlistcontains' => 'Lista mbikqyrëse e juaj ka $1 faqe.',
+'watcheditlist' => 'Këtu jepet një listë e alfabetizuar e faqeve nën mbikqyrje. Zgjidhni kutinë e secilës faqe që dëshironi të hiqni nga lista dhe shtypni butonin \'Hiq të zgjedhurat\' në fund të faqes.',
+'removingchecked' => 'Duke hequr artikujt e zgjedhur nga lista mbikqyrëse...',
+'couldntremove' => 'S\'mundi të heq arikullin \'$1\'...',
+'iteminvalidname' => 'Problem me artikullin \'$1\', titull jo i saktë...',
+'wlnote' => 'Më poshtë janë $1 ndryshimet e <b>$2</b> orëve së fundmi.',
+'wlshowlast' => 'Trego $1 orët $2 ditët $3',
+'wlsaved' => 'Kjo është një kopje e ruajtur e listës mbikqyrëse tuaj.',
+'wlhideshowown' => '$1 redaktimet e mia.',
+'wlhideshowbots' => '$1 redaktime robotësh.',
+'wldone' => 'Veprim i mbaruar',
+'enotif_mailer' => 'Postieri njoftues i {{SITENAME}}',
+'enotif_reset' => 'Shënoi të gjitha faqet të vizituara',
+'enotif_newpagetext' => 'Kjo është një faqe e re.',
+'changed' => 'ndryshuar',
+'created' => 'u krijua',
+'enotif_subject' => '{{SITENAME}} faqja $PAGETITLE u $CHANGEDORCREATED prej $PAGEEDITOR',
+'enotif_lastvisited' => 'Shikoni $1 për të gjitha ndryshimet që prej vizitës tuaj të fundit.',
+'enotif_body' => 'I/E dashur $WATCHINGUSERNAME,
+
+faqja $PAGETITLE tek {{SITENAME}} është $CHANGEDORCREATED më $PAGEEDITDATE nga $PAGEEDITOR, shikoni $PAGETITLE_URL për versionin e tanishëm.
+
+$NEWPAGE
+
+Përmbledhja e redaktorit: $PAGESUMMARY $PAGEMINOREDIT
+
+Mund të lidheni me redaktorin nëpërmjet:
+email: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Nuk do të ketë njoftime të tjera në rast se ka ndryshime vijuese në qoftë se nuk vizitoni faqen. Gjithashtu mund të ktheni gjendjen e njoftimeve për të gjitha faqet nën mbikqyrje.
+
+ Miku juaj njoftues nga {{SITENAME}}
+
+--
+Për të ndryshuar parapëlqimet e mbikqyrjes shikoni {{fullurl:Special:Watchlist/edit}}
+
+Për të na dhënë përshtypjet tuaja ose për ndihmë të mëtejshme:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Grise faqen',
+'confirm' => 'Konfirmoni',
+'excontent' => 'përmbajtja ishte: \'$1\'',
+'excontentauthor' => 'përmbajtja ishte: \'$1\' (dhe i vetmi redaktor ishte \'$2\')',
+'exbeforeblank' => 'përmbajtja përpara boshatisjes ishte: \'$1\'',
+'exblank' => 'faqja është bosh',
+'confirmdelete' => 'Konfirmoni grisjen',
+'deletesub' => '(Duke grisur "$1")',
+'historywarning' => 'Kujdes: Faqja që jeni bërë gati për të grisur ka histori:',
+'confirmdeletetext' => 'Jeni duke grisur \'\'\'përfundimisht\'\'\' një faqe ose një skedë me tër historinë e saj nga regjistri. Ju lutem konfirmoni që keni ndër mënd ta bëni këtë gjë, që i kuptoni se cilat janë pasojat, dhe që po veproni në përputhje me [[Project:Rregullat]].',
+'actioncomplete' => 'Veprim i mbaruar',
+'deletedtext' => '"$1" është grisur nga regjistri. Shikoni $2 për një pasqyrë të grisjeve së fundmi.',
+'deletedarticle' => 'grisi "$1"',
+'dellogpage' => 'Regjistri i grisjeve',
+'dellogpagetext' => 'Më poshtë është një listë e grisjeve më të fundit.
+Të gjitha kohët janë sipas orës së shërbyesit (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'regjistrin e grisjeve',
+'reverted' => 'Kthehu tek një version i vjetër',
+'deletecomment' => 'Arsyeja',
+'imagereverted' => 'Kthimi tek një version i sukseshëm.',
+'rollback' => 'Riktheji mbrapsh redaktimet',
+'rollback_short' => 'Riktheje',
+'rollbacklink' => 'riktheje',
+'rollbackfailed' => 'Rikthimi dështoi',
+'cantrollback' => 'Nuk munda ta kthejë redaktimin; redaktori i fundit është i vetmi autor i këtij artikulli.',
+'alreadyrolled' => 'Nuk munda ta rikthej redaktimin e fundit e [[:$1]] nga [[User:$2|$2]] ([[User talk:$2|diskutim]]); dikush tjetër e ka redaktuar ose rikthyer këtë faqe.
+
+Redaktimi i fundit është bërë nga [[User:$3|$3]] ([[User talk:$3|diskutim]]).',
+'editcomment' => 'Komenti i redaktimit ishte: "<i>$1</i>".',
+'revertpage' => 'Ndryshimet e [[Special:Contributions/$2|$2]] ([[User talk:$2|diskutimet]]) u kthyen mbrapsh. Faqja tani ndodhet në versionin e fundit nga [[User:$1|$1]].',
+'sessionfailure' => 'Më duket se ka një problem me seancën tuaj të hyrjes. Veprimi juaj nuk është kryer për tu mbrojtur nga ndonjë veprim dashakeq kundrejt shfletimit tuaj. Ju lutem kthehuni mbrapsh, rifreskoni faqen prej nga erdhët dhe provojeni përsëri veprimin.',
+'protectlogpage' => 'Regjistri i mbrojtjeve',
+'protectlogtext' => 'Më poshtë është një listë e "mbrojtjeve/lirimeve" të faqeve. Shikoni [[Project:Faqe e mbrojtur|faqe e mbrojtur]] për më shumë informacion.',
+'protectedarticle' => 'mbrojti [[$1]]',
+'unprotectedarticle' => 'lirojë [[$1]]',
+'protectsub' => '(Duke ndryshuar mbrojtjen e "$1")',
+'confirmprotecttext' => 'Dëshironi të mbroni këtë faqe?',
+'confirmprotect' => 'Konfirmoni',
+'protectmoveonly' => 'Mbroje vetëm nga zhvendosjet',
+'protectcomment' => 'Arsyeja',
+'unprotectsub' => '(Duke liruar "$1")',
+'confirmunprotecttext' => 'Dëshironi të lironi këtë faqe?',
+'confirmunprotect' => 'Konfirmoni lirimin',
+'unprotectcomment' => 'Arsyeja',
+'protect-unchain' => 'Ndrysho lejen e zhvendosjeve',
+'protect-text' => 'Këtu mund të shikoni dhe ndryshoni nivelin e mbrojtjes për faqen [[$1]]. Ju lutem ndiqni rregullat e dhëna tek [[Project:Faqe e mbrojtur|faqet e mbrojtura]].',
+'protect-viewtext' => 'Llogaria juaj nuk lejohet të ndryshojë nivelin e mbrojtjes. Niveli i mbrojtjes për faqen [[$1]] është:',
+'protect-default' => '(parazgjedhje)',
+'protect-level-autoconfirmed'=> 'Blloko përdoruesit pa llogari',
+'protect-level-sysop' => 'Vetëm administruesit',
+'restriction-edit' => 'Redaktoni',
+'restriction-move' => 'Zhvendoseni',
+'undelete' => 'Restauroni faqet e grisura',
+'undeletepage' => 'Shikoni ose restauroni faqet e grisura',
+'viewdeletedpage' => 'Shikoni faqet e grisura',
+'undeletepagetext' => 'Më poshtë janë faqet që janë grisur por që gjënden akoma në arkiv dhe
+mund të restaurohen. Arkivi boshatiset periodikisht.',
+'undeleteextrahelp' => 'Lini bosh të gjitha kutitë e zgjedhjes dhe shqypni \'\'\'\'\'Restauro!\'\'\'\'\' për të restauruar të gjitha versionet e faqes. Për të bërë një restaurim të pjesshëm zgjidhni kutitë e versioneve që dëshironi të restauroni dhe shtypni \'\'\'\'\'Restauro!\'\'\'\'\'. Mund të boshatisni të gjitha zgjedhjet dhe arsyen duke shtypur \'\'\'\'\'Boshatis\'\'\'\'\'.',
+'undeletearticle' => 'Restauro artikullin e grisur',
+'undeleterevisions' => '$1 versione u futën në arkiv',
+'undeletehistory' => 'N.q.s. restauroni një faqe, të gjitha versionet do të restaurohen në histori. N.q.s. një faqe e re me të njëjtin titull është krijuar që nga grisja, versionet e restauruara do të duken më përpara në histori, dhe versioni i faqes së fundit nuk do të shkëmbehet automatikisht.',
+'undeletehistorynoadmin'=> 'Kjo faqe është grisur. Arsyeja për grisjen është dhënë tek përmbledhja më poshtë bashkë me hollësitë e përdoruesve që e kanë redaktuar.',
+'undeleterevision' => 'U gris versioni i $1',
+'undeletebtn' => 'Restauro!',
+'undeletereset' => 'Boshatis',
+'undeletecomment' => 'Arsyeja:',
+'undeletedarticle' => 'u restaurua "$1"',
+'undeletedrevisions' => '$1 versione u restauruan',
+'undeletedrevisions-files'=> '$1 versione dhe $2 skeda janë restauruar',
+'undeletedfiles' => '$1 skeda u restauruan',
+'cannotundelete' => 'Restaurimi dështoi; dikush tjetër mund ta ketë restauruar faqen përpara jush.',
+'undeletedpage' => '<big>\'\'\'$1 është restauruar\'\'\'</big>
+
+Shikoni [[Special:Log/delete|regjistrin e grisjeve]] për grisjet dhe restaurimet së fundmi.',
+'namespace' => 'Hapësira:',
+'invert' => 'Kundër zgjedhjes',
+'contributions' => 'Kontributet',
+'mycontris' => 'Redaktimet e mia',
+'contribsub' => 'Për $1',
+'nocontribs' => 'Nuk ka asnjë ndryshim që përputhet me këto kritere.',
+'ucnote' => 'Më poshtë janë redaktimet më të fundit të <b>$1</b> gjatë <b>$2</b> ditëve.',
+'uclinks' => 'Shikoni $1 redaktimet e fundit; shikoni $2 ditët e fundit.',
+'uctop' => ' (sipër)',
+'newbies' => 'të njomtët',
+'sp-newimages-showfrom' => 'duke filluar nga $1',
+'sp-contributions-newest'=> 'Më të rejat',
+'sp-contributions-oldest'=> 'Më të vjetrat',
+'sp-contributions-newer'=> '$1 më para',
+'sp-contributions-older'=> '$1 më pas',
+'sp-contributions-newbies-sub'=> 'Për newbies',
+'whatlinkshere' => 'Lidhjet këtu',
+'notargettitle' => 'Asnjë artikull',
+'notargettext' => 'Nuk keni dhënë asnjë artikull ose përdorues mbi të cilin të përdor këtë funksion.',
+'linklistsub' => '(Listë lidhjesh)',
+'linkshere' => 'Faqet e mëposhtëme lidhen këtu:',
+'nolinkshere' => 'Asnjë faqe nuk lidhet këtu.',
+'isredirect' => 'faqe përcjellëse',
+'istemplate' => 'përfshirë',
+'blockip' => 'Blloko përdorues',
+'blockiptext' => 'Përdorni formularin e mëposhtëm për të hequr lejen e shkrimit për një përdorues ose IP-ë specifike.
+Kjo duhet bërë vetëm në raste vandalizmi, dhe në përputhje me [[Project:Rregullat|rregullat e {{SITENAME}}-s]].
+Plotësoni arsyen specifike më poshtë (p.sh., tregoni faqet specifike që u vandalizuan).',
+'ipaddress' => 'IP Adresë/përdorues',
+'ipadressorusername' => 'Adresë IP ose emër përdoruesi',
+'ipbexpiry' => 'Afati',
+'ipbreason' => 'Arsyeja',
+'ipbsubmit' => 'Blloko këtë përdorues',
+'ipbother' => 'Kohë tjetër',
+'ipboptions' => '1 Orë:1 hour,2 Orë:2 hours,6 Orë:6 hours,1 Ditë:1 day,3 Ditë:3 days,1 Javë:1 week,2 Javë:2 weeks,1 Muaj:1 month,3 Muaj:3 months,1 Vjet:1 year,Pa kufi:indefinite',
+'ipbotheroption' => 'tjetër',
+'badipaddress' => 'Nuk ka asnjë përdorues me atë emër',
+'blockipsuccesssub' => 'Bllokimi u bë me sukses',
+'blockipsuccesstext' => 'Përdoruesi [[User:$1|$1]] ([[User talk:$1|diskutimet]] · [[Special:Contributions/$1|kontributet]]) u bllokua.
+<br />Veprimi u regjistrua te [[Special:Log/block|Regjistri i bllokimeve]]. Shiko këtu [{{fullurl:Special:Ipblocklist|action=unblock&ip=$1}} për ta çbllokuar] përdoruesin.',
+'unblockip' => 'Çblloko përdoruesin',
+'unblockiptext' => 'Përdor formularin e më poshtëm për t\'i ridhënë leje shkrimi
+një përdoruesi ose IP adreseje të bllokuar.',
+'ipusubmit' => 'Çblloko këtë adresë',
+'unblocked' => '[[Përdoruesi:$1|$1]] është çbllokuar',
+'ipblocklist' => 'Lista e përdoruesve dhe e IP adresave të bllokuara',
+'blocklistline' => '$1, $2 bllokoi $3 ($4)',
+'infiniteblock' => 'pakufi',
+'expiringblock' => 'kalon $1',
+'ipblocklistempty' => 'Lista e bllokimeve është bosh.',
+'blocklink' => 'blloko',
+'unblocklink' => 'çblloko',
+'contribslink' => 'kontribute',
+'autoblocker' => 'I bllokuar automatikisht sepse përdor të njëjtën IP adresë si "$1". Arsye "$2".',
+'blocklogpage' => 'Regjistri i bllokimeve',
+'blocklogentry' => 'bllokoi "[[$1]]" për një kohëzgjatje prej $2',
+'blocklogtext' => 'Ky është një regjistër bllokimesh dhe çbllokimesh të përdoruesve. IP-të e bllokuara automatikisht nuk janë të dhëna. Shikoni dhe [[{ns:special}}:Ipblocklist|listën e IP-ve të bllokuara]] për një listë të bllokimeve të tanishme.',
+'unblocklogentry' => 'çbllokoi "$1"',
+'range_block_disabled' => 'Mundësia e administruesve për të bllokuar me shtrirje është çaktivizuar.',
+'ipb_expiry_invalid' => 'Afati i kohës është gabim.',
+'ip_range_invalid' => 'Shtrirje IP gabim.',
+'proxyblocker' => 'Bllokuesi i ndërmjetëseve',
+'proxyblockreason' => 'IP adresa juaj është bllokuar sepse është një ndërmjetëse e hapur. Ju lutem lidhuni me kompaninë e shërbimeve të Internetit që përdorni dhe i informoni për këtë problem sigurije.',
+'proxyblocksuccess' => 'Mbaruar.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Adresa IP e juaj është radhitur si ndërmjetëse e hapur tek lista [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason'=> 'Adresa IP e juaj është radhitur si ndërmjetëse e hapur tek lista [http://www.sorbs.net SORBS] DNSBL. Nuk ju lejohet të hapni një llogari.',
+'lockdb' => 'Blloko regjistrin',
+'unlockdb' => 'Çblloko regjistrin',
+'lockdbtext' => 'Bllokimi i regjistrit do të ndërpresi mundësinë e përdoruesve për të redaktuar faqet, për të ndryshuar parapëlqimet, për të ndryshuar listat mbikqyrëse të tyre, dhe për gjëra të tjera për të cilat nevojiten shkrime në regjistër.
+Ju lutem konfirmoni që dëshironi me të vërtetë të kryeni këtë veprim, dhe se do të çbllokoni regjistrin kur të mbaroni së kryeri mirëmbajtjen.',
+'unlockdbtext' => 'Çbllokimi i regjistrit do të lejojë mundësinë e të gjithë përdoruesve për të redaktuar faqe, për të ndryshuar parapëlqimet e tyre, për të ndryshuar listat mbikqyrëse të tyre, dhe gjëra të tjera për të cilat nevojiten shkrime në regjistër. Ju lutem konfirmoni që dëshironi me të vërtetë të kryeni këtë veprim.',
+'lockconfirm' => 'Po, dëshiroj me të vërtetë të bllokoj regjistrin.',
+'unlockconfirm' => 'Po, dëshiroj me të vërtetë të çbllokoj regjistrin',
+'lockbtn' => 'Blloko regjistrin',
+'unlockbtn' => 'Çblloko regjistrin',
+'locknoconfirm' => 'Nuk vendose kryqin tek kutia konfirmuese.',
+'lockdbsuccesssub' => 'Regjistri u bllokua me sukses',
+'unlockdbsuccesssub' => 'Regjistri u çbllokua me sukses',
+'lockdbsuccesstext' => 'Regjistri i {{SITENAME}} është bllokuar.
+<br />Kujtohu ta çbllokosh mbasi të kesh mbaruar mirëmbajtjen.',
+'unlockdbsuccesstext' => 'Regjistri i {{SITENAME}} është çbllokuar.',
+'makesysoptitle' => 'Jepini privilegjin e titullit administrues',
+'makesysoptext' => 'Ky formular përdoret për tu dhënë titullin [[Project:Administruesit|administrues]] një përdoruesi të thjeshtë. Kini kujdes, mbasi të jetë dhënë, vetëm një \'\'zhvillues\'\' mund t\'ia heqi këtë titull një administruesi.',
+'makesysopname' => 'Emri i përdoruesit:',
+'makesysopsubmit' => 'Jepini privilegjin',
+'makesysopok' => '<b>Përdoruesi \'$1\' u bë administrues</b>',
+'makesysopfail' => '<b>Përdoruesi \'$1\' nuk mund të bëhej administrues. (Kontrolloni nëse emrin e keni shtypur saktësisht)</b>',
+'setbureaucratflag' => 'Jepi titullin burokrat',
+'rightslog' => 'Regjistri i privilegjeve',
+'rightslogtext' => 'Ky është një regjistër për ndryshimet e titujve të përdoruesve.',
+'rightslogentry' => 'ndryshoi privilegjet e $1 prej "$2" në "$3"',
+'rights' => 'Privilegje:',
+'set_user_rights' => 'Vendosni privilegjet e përdoruesve',
+'user_rights_set' => '<b>Privilegjet për përdoruesin "$1" u freskuan</b>',
+'set_rights_fail' => '<b>Nuk mund të vendoseshin privilegjet për përdoruesin "$1". (Vendosët emrin e saktë?)</b>',
+'makesysop' => 'Jepni titullin administrues',
+'already_sysop' => 'Ky përdorues është bërë administrues më parë',
+'already_bureaucrat' => 'Ky përdorues është bërë burokrat më parë',
+'rightsnone' => '(asnjë)',
+'movepage' => 'Zhvendose faqen',
+'movepagetext' => 'Duke përdorur formularin e mëposhtëm do të ndërroni titullin e një faqeje, duke zhvendosur gjithë historinë përkatëse tek titulli i ri. Titulli i vjetër do të bëhet një faqe përcjellëse tek titulli i ri. Lidhjet tek faqja e vjetër nuk do të ndryshohen; duhet të kontrolloni [[{ns:special}}:Maintenance|mirëmbajtjen]] për përcjellime të dyfishta ose të prishura.
+Keni përgjegjësinë për tu siguruar që lidhjet të vazhdojnë të jenë të sakta.
+
+Vini re se kjo faqe \'\'\'nuk\'\'\' do të zhvendoset n.q.s. ekziston një faqe me titullin e ri, përveçse kur ajo të jetë bosh ose një përcjellim dhe të mos ketë një histori të vjetër. Kjo do të thotë se mund ta zhvendosni një faqe prapë tek emri
+i vjetër n.q.s. keni bërë një gabim, dhe s\'mund ta prishësh një faqe që ekziston.
+
+<b>KUJDES!</b>
+Ky mund të jetë një ndryshim i madh dhe gjëra të papritura mund të ndodhin për një faqe të shumë-frekuentuar; ju lutem, kini kujdes dhe mendohuni mirë para se të përdorni këtë funksion.',
+'movepagetalktext' => 'Faqja a bashkangjitur e diskutimit, n.q.s. ekziston, do të zhvendoset automatikisht \'\'\'përveçse\'\'\' kur:
+*Zhvendosni një faqe midis hapësirave të ndryshme,
+*Një faqe diskutimi jo-boshe ekziston nën titullin e ri, ose
+*Nuk zgjidhni kutinë më poshtë.
+
+Në ato raste, duhet ta zhvendosni ose përpuqni faqen vetë n.q.s. dëshironi.',
+'movearticle' => 'Zhvendose faqen',
+'movenologin' => 'Nuk keni hyrë brenda',
+'movenologintext' => 'Duhet të keni hapur një llogari dhe të keni [[Special:Userlogin|hyrë brenda]] për të zhvendosur një faqe.',
+'newtitle' => 'Tek titulli i ri',
+'movepagebtn' => 'Zhvendose faqen',
+'pagemovedsub' => 'Zhvendosja doli me sukses',
+'pagemovedtext' => 'Faqja "[[$1]]" u zhvendos tek "[[$2]]".',
+'articleexists' => 'Një faqe me atë titull ekziston, ose titulli që zgjodhët nuk është i saktë. Ju lutem zgjidhni një tjetër.',
+'talkexists' => 'Faqja për vete u zhvendos, ndërsa faqja e diskutimit nuk u zhvendos sepse një e tillë ekziston tek titulli i ri. Ju lutem, përpuqini vetë.',
+'movedto' => 'zhvendosur tek',
+'movetalk' => 'Zhvendos edhe faqen e diskutimeve, në qoftë se është e mundur.',
+'talkpagemoved' => 'Faqja e diskutimeve korrespondente u zhvendos gjithashtu.',
+'talkpagenotmoved' => 'Faqja e diskutimeve korrespondente <strong>nuk</strong> u zhvendos.',
+'1movedto2' => '[[$1]] u zhvendos tek [[$2]]',
+'1movedto2_redir' => '[[$1]] u zhvendos tek [[$2]] dhe u krijua një faqe përcjellimi',
+'movelogpage' => 'Regjistri i zhvendosjeve',
+'movelogpagetext' => 'Më poshtë është një listë e faqeve të zhvendosura',
+'movereason' => 'Arsyeja',
+'revertmove' => 'ktheje',
+'delete_and_move' => 'Grise dhe zhvendose',
+'delete_and_move_text' => '==Nevojitet grisje==
+
+Faqja "[[$1]]" ekziston, dëshironi ta grisni për të mundësuar zhvendosjen?',
+'delete_and_move_confirm'=> 'Po, grise faqen',
+'delete_and_move_reason'=> 'U gris për të liruar vendin për përcjellim',
+'selfmove' => 'Nuk munda ta zhvendos faqen sepse titulli i ri është i njëjtë me të vjetrin.',
+'immobile_namespace' => 'Titulli i dëshiruar i faqes është i veçantë; Faqja nuk mund të zhvendoset në hapësira me emër tjetër.',
+'export' => 'Eksportoni faqe',
+'exporttext' => 'Mund të eksportoni tekstin dhe historinë e redaktimit e një faqeje ose disa faqesh të mbështjesha në XML; kjo mund të importohet në një wiki tjetër që përdor softuerin MediaWiki (tani për tani, ky opsion nuk është përfshirë tek {{SITENAME}}).
+
+Për të eksportuar faqe, thjesht shtypni një emër për çdo rresht, ose krijoni lidhje të tipit [[Special:Export/{{msg:MediaWiki:Mainpage}}]] si [[{{msg:MediaWiki:Mainpage}}]].',
+'exportcuronly' => 'Përfshi vetëm versionin e fundit, jo të gjithë historinë',
+'exportnohistory' => '\'\'\'Shënim:\'\'\' Eksportimi i historisë së faqes për shkaqe të rendimentit nuk është e mundshme.',
+'allmessages' => 'Mesazhet e sistemit',
+'allmessagesname' => 'Emri',
+'allmessagesdefault' => 'Teksti i parazgjedhur',
+'allmessagescurrent' => 'Teksti i tanishëshm',
+'allmessagestext' => 'Kjo është një listë e të gjitha faqeve në hapësirën MediaWiki:',
+'allmessagesnotsupportedUI'=> 'Ndërfaqja gjuhësore e juaj, <b>$1</b>, nuk mbulohet nga special:Allmessages në këto faqe.',
+'allmessagesnotsupportedDB'=> 'special:Allmessages not supported because wgUseDatabaseMessages is off.',
+'allmessagesfilter' => 'Veço me shprehje të rregullta:',
+'allmessagesmodified' => 'Trego vetëm të ndryshuarat',
+'thumbnail-more' => 'Zmadho',
+'missingimage' => '<b>Mungon figura</b><br /><i>$1</i>',
+'filemissing' => 'Mungon skeda',
+'thumbnail_error' => 'Gabim gjatë krijimit të figurës përmbledhëse: $1',
+'import' => 'Importo faqe',
+'importinterwiki' => 'Import ndër-wiki',
+'importtext' => 'Ju lutem eksportoni këtë skedë nga burimi wiki duke përdorur mjetin Special:Export, ruajeni në diskun tuaj dhe ngarkojeni këtu.',
+'importfailed' => 'Importimi dështoi: $1',
+'importnotext' => 'Bosh ose pa tekst',
+'importsuccess' => 'Importim i sukseshëm!',
+'importhistoryconflict' => 'Ekzistojnë versione historiku në konflikt (kjo faqe mund të jetë importuar më parë)',
+'importnosources' => 'Nuk ka asnjë burim importi të përcaktuar dhe ngarkimet historike të drejtpërdrejta janë ndaluar.',
+'importnofile' => 'Nuk u ngarkua asnjë skedë importi.',
+'importuploaderror' => 'Ngarkimi i skedës së importit dështoi. Ndoshta skeda kishte madhësi më të madhe se lejohet.',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'Kërko {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Shënoje këtë redaktim të vogël [alt-i]',
+'tooltip-save' => 'Kryej ndryshimet [alt-s]',
+'tooltip-preview' => 'Shiko parapamjen e ndryshimeve, përdoreni këtë para se të kryeni ndryshimet! [alt-p]',
+'tooltip-diff' => 'Show which changes you made to the text. [alt-v]',
+'tooltip-compareselectedversions'=> 'Shikoni krahasimin midis dy versioneve të zgjedhura të kësaj faqeje. [alt-v]',
+'tooltip-watch' => 'Mbikqyre këtë faqe [alt-w]',
+'monobook.css' => '/* redaktoni këtë faqe për të përshtatur pamjen Monobook për tëra faqet tuaja */',
+'nodublincore' => 'Dublin Core RDF metadata nuk është i mundshëm për këtë server.',
+'nocreativecommons' => 'Creative Commons RDF metadata nuk është i mundshëm për këtë server.',
+'notacceptable' => 'Wiki server nuk mundet ti përgatit të dhënat për klintin tuaj.',
+'anonymous' => 'Përdorues anonim të {{SITENAME}}',
+'siteuser' => 'Përdoruesi $1 i {{SITENAME}}',
+'lastmodifiedatby' => 'Kjo faqe është redaktuar së fundit më $2, $1 nga $3.',
+'and' => 'dhe',
+'othercontribs' => 'Bazuar mbi punën e $1',
+'others' => 'të tjerë',
+'siteusers' => 'Përdoruesit $1 e {{SITENAME}}',
+'creditspage' => 'Statistika e faqes',
+'nocredits' => 'Për këtë faqe nuk ka informacione.',
+'spamprotectiontitle' => 'Mbrojtje ndaj teksteve të padëshiruara',
+'spamprotectiontext' => 'Faqja që dëshironit të ruani është bllokuar nga filtri i teksteve të padëshiruara. Ka mundësi që kjo të ketë ndodhur për shkak të ndonjë lidhjeje të jashtme.',
+'spamprotectionmatch' => 'Teksti në vijim është cilësuar i padëshiruar nga softueri: $1',
+'subcategorycount' => 'Gjënden $1 nën-kategori në këtë kategori.',
+'categoryarticlecount' => 'Ndodhen $1 artikuj nën këtë kategori.',
+'listingcontinuesabbrev'=> ' vazh.',
+'spambot_username' => 'MediaWiki spam-pastrues',
+'spam_reverting' => 'U kthye tek versioni i fundit që s\'ka lidhje tek $1',
+'spam_blanking' => 'U boshatis sepse të gjitha versionet kanë lidhje tek $1',
+'infosubtitle' => 'Informacion për faqen',
+'numedits' => 'Numri i versioneve të artikullit: $1',
+'numtalkedits' => 'Numrii versioneve të diskutimit të artikullit: $1',
+'numwatchers' => 'Numri i mbikqyrësve: $1',
+'numauthors' => 'Numri i autorëve të artikullit: $1',
+'numtalkauthors' => 'Numri i diskutuesve për artikullin: $1',
+'mw_math_png' => 'Gjithmonë PNG',
+'mw_math_simple' => 'HTML në qoftë se është e thjeshtë ose ndryshe PNG',
+'mw_math_html' => 'HTML në qoftë se është e mundur ose ndryshe PNG',
+'mw_math_source' => 'Lëre si TeX (për shfletuesit tekst)',
+'mw_math_modern' => 'E rekomanduar për shfletuesit modern',
+'mw_math_mathml' => 'MathML',
+'markaspatrolleddiff' => 'Shënoje si të patrulluar',
+'markaspatrolledtext' => 'Shënoje këtë artikull të patrulluar',
+'markedaspatrolled' => 'Shënoje të patrulluar',
+'markedaspatrolledtext' => 'Versioni i zgjedhur është shënuar i patrulluar.',
+'rcpatroldisabled' => 'Kontrollimi i ndryshimeve së fundmi është bllokuar',
+'rcpatroldisabledtext' => 'Kontrollimi i ndryshimeve së fundmi nuk është i mundshëm për momentin.',
+'markedaspatrollederror'=> 'Nuk munda ta shënoj të patrulluar',
+'markedaspatrollederrortext'=> 'Duhet të përcaktoni versionin për tu shënuar i patrulluar.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Faqja juaj e përdoruesit\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Faqja e përdoruesve anonim nga kjo adresë IP\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Faqja juaj e diskutimeve\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Faqja e diskutimeve të përdoruesve anonim për këtë adresë IP\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Parapëlqimet tuaja\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Lista e faqeve nën mbikqyrjen tuaj.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Lista e kontributeve tuaja\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Të hysh brenda nuk është e detyrueshme, por ka shumë përparësi.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Të hysh brenda nuk është e detyrueshme, por ka shumë përparësi.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Dalje\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskuto për përmbajtjen e faqes\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Ju mund ta redaktoni këtë faqe. Përdorni butonin >>Trego parapamjen<< para se t\'i kryeni ndryshimet.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Fillo një temë të re diskutimi.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Kjo faqe është e mbrojtur. Ju mundeni vetëm ta shikoni burimin e tekstit.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Versione të mëparshme të artikullit.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Mbroje këtë faqe\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Grise këtë faqe\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Faqja u restaurua\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Me anë të zhvendosjes mund ta ndryshoni titullin e artikullit\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Ti nuk ke të drejtë ta zhvendosish këtë faqe\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Shtoje faqen në lisën e faqeve nën mbikqyrje\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Hiqe faqen nga lista e faqeve nën mbikqyrje.\');
+ ta[\'search\'] = new Array(\'f\',\'Kërko në projekt\');
+ ta[\'p-logo\'] = new Array(\'\',\'Figura e Faqes Kryesore\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Vizitoni Faqen kryesore\');
+ ta[\'n-portal\'] = new Array(\'\',\'Mbi projektin, çka mund të bëni për të dhe ku gjenden faqet.\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Informacion rreth ngjarjeve aktuale.\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Lista e ndryshimeve së fundmi në projekt\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Shikoni një artikull të rastit.\');
+ ta[\'n-help\'] = new Array(\'\',\'Vendi ku mund të gjeni ndihmë.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Përkrahni projektin\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lista e faqeve që lidhen tek kjo faqe\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Lista e ndryshimeve të faqeve që lidhen tek kjo faqe\');
+ ta[\'feed-rss\'] = new Array(\'\',\'Burimi ushqyes "RSS" për këtë faqe \');
+ ta[\'feed-atom\'] = new Array(\'\',\'Burimi ushqyes "Atom" për këtë faqe\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Shiko listën e kontributeve për përdoruesin në fjalë\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Dërgoni një email përdoruesit\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Ngarkoni figura ose skeda të tjera\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lista e të gjitha faqeve speciale.\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Shikoni përmbajtjen e atikullit.\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Shikoni faqen e përdoruesit\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Shikoni faqen e skedës\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Kjo është një faqe speciale. Ju nuk mundeni ta redaktoni këtë faqe\');
+ ta[\'ca-nstab-project\'] = new Array(\'c\',\'Shikoni faqen e projektit\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Shikoni faqen e figurës\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Shikoni mesazhet e sistemit\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Shikoni stampën\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Shikoni faqet ndihmëse\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Shikoni faqen e kategorisë\');',
+'deletedrevision' => 'Gris versionin e vjetër $1.',
+'previousdiff' => '← Ndryshimi më para',
+'nextdiff' => 'Ndryshimi më pas →',
+'imagemaxsize' => 'Kufizo pamjen e figurave në faqet përshkruese në rezolucionin:',
+'thumbsize' => 'Madhësia fotove përmbledhëse:',
+'showbigimage' => 'Shkarkoni versionin me rezolucion më të lartë ($1x$2, $3 KB)',
+'newimages' => 'Galeria e figurave të reja',
+'showhidebots' => '($1 robotët)',
+'noimages' => 'S\'ka gjë për të parë.',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+'specialloguserlabel' => 'Përdoruesi:',
+'speciallogtitlelabel' => 'Titulli:',
+'passwordtooshort' => 'Fjalëkalimi juaj është shumë i shkurtër. Ai duhet të ketë së paku $1 shkronja.',
+'mediawarning' => '\'\'\'Warning\'\'\': This file may contain malicious code, by executing it your system may be compromised.<hr />',
+'fileinfo' => '$1KB, lloji MIME: <code>$2</code>',
+'metadata' => 'Metadata',
+'metadata-help' => 'Kjo skedë përmban hollësira të tjera të cilat mund të jenë shtuar nga kamera ose skaneri dixhital që është përdorur për ta krijuar. Në qoftë se skeda është ndryshuar nga gjendja origjinale, disa hollësira mund të mos pasqyrojnë skedën e tanishme.',
+'metadata-expand' => 'Trego hollësirat',
+'metadata-collapse' => 'Fshih hollësirat',
+'exif-imagewidth' => 'Gjerësia',
+'exif-imagelength' => 'Gjatësia',
+'exif-bitspersample' => 'Bit për komponent',
+'exif-compression' => 'Lloji i ngjeshjes',
+'exif-photometricinterpretation'=> 'Përbërja pixel',
+'exif-orientation' => 'Orientimi',
+'exif-samplesperpixel' => 'Numri i përbërësve',
+'exif-ycbcrpositioning' => 'Pozicioni Y dhe C',
+'exif-xresolution' => 'Rezolucioni horizontal',
+'exif-yresolution' => 'Rezolucioni vertikal',
+'exif-rowsperstrip' => 'Numri i rreshtave për shirit',
+'exif-datetime' => 'Data dhe ora e ndryshimit të skedës',
+'exif-imagedescription' => 'Titulli i figurës',
+'exif-make' => 'Prodhuesi i kamerës',
+'exif-model' => 'Modeli i kamerës',
+'exif-software' => 'Softueri i përdorur',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Mbajtësi i të drejtave të autorit',
+'exif-exifversion' => 'Versioni Exif-it',
+'exif-colorspace' => 'Hapësira e ngjyrave',
+'exif-compressedbitsperpixel'=> 'Lloji i ngjeshjes së figurës',
+'exif-pixelydimension' => 'Gjerësia e vlefshme e figurës',
+'exif-pixelxdimension' => 'Valind image height',
+'exif-makernote' => 'Shënimet e prodhuesit',
+'exif-usercomment' => 'Vërejtjet e përdoruesit',
+'exif-relatedsoundfile' => 'Skeda audio shoqëruese',
+'exif-datetimeoriginal' => 'Data dhe koha e prodhimit të të dhënave',
+'exif-datetimedigitized'=> 'Data dhe ora e dixhitalizimit',
+'exif-exposuretime' => 'Kohëzgjatja e ekspozimit',
+'exif-fnumber' => 'Numri F',
+'exif-shutterspeedvalue'=> 'Shpejtësia e mbyllësit',
+'exif-aperturevalue' => 'Apertura',
+'exif-brightnessvalue' => 'Ndriçimi',
+'exif-subjectdistance' => 'Largësia e subjektit',
+'exif-lightsource' => 'Burimi i dritës',
+'exif-flash' => 'Blici',
+'exif-focallength' => 'Gjatësia e vatrës',
+'exif-flashenergy' => 'Energjia e blicit',
+'exif-subjectlocation' => 'Vendndodhja e subjektit',
+'exif-filesource' => 'Burimi i skedës',
+'exif-contrast' => 'Kontrasti',
+'exif-saturation' => 'Mbushja',
+'exif-sharpness' => 'Ashpërsia',
+'exif-subjectdistancerange'=> 'Shtrirja e largësisë së subjektit',
+'exif-gpslatituderef' => 'Gjerësi veriore ose jugore',
+'exif-gpslatitude' => 'Gjerësia gjeografike',
+'exif-gpslongituderef' => 'Gjatësi lindore ose perëndimore',
+'exif-gpslongitude' => 'Gjatësia gjeografike',
+'exif-gpsaltituderef' => 'Lartësia orientuese',
+'exif-gpsaltitude' => 'Lartësia',
+'exif-gpssatellites' => 'Janë përdorur satelitë për matjen',
+'exif-gpstrack' => 'Drejtimi i lëvizjes',
+'exif-gpsimgdirection' => 'Orientimi i figurës',
+'exif-compression-1' => 'E pangjeshur',
+'exif-compression-6' => 'JPEG',
+'exif-photometricinterpretation-2'=> 'RGB',
+'exif-photometricinterpretation-6'=> 'YCbCr',
+'exif-orientation-1' => 'Normal',
+'exif-orientation-2' => 'E kthyer horizontalisht',
+'exif-orientation-3' => 'E rrotulluar 180°',
+'exif-orientation-4' => 'E kthyer vertikalisht',
+'exif-orientation-5' => 'E rrotulluar 90° kundër orës dhe e kthyer vertikalisht',
+'exif-orientation-6' => 'E rrotulluar 90° sipas orës',
+'exif-orientation-7' => 'E rrotulluar 90° sipas orës dhe e kthyer vertikalisht',
+'exif-orientation-8' => 'E rrotulluar 90° kundër orës',
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h'=> 'FFFF.H',
+'exif-componentsconfiguration-0'=> 'nuk ekziston',
+'exif-componentsconfiguration-1'=> 'Y',
+'exif-componentsconfiguration-2'=> 'Cb',
+'exif-componentsconfiguration-3'=> 'Cr',
+'exif-componentsconfiguration-4'=> 'R',
+'exif-componentsconfiguration-5'=> 'G',
+'exif-componentsconfiguration-6'=> 'B',
+'exif-exposureprogram-4'=> 'Përparësia e mbyllësit',
+'exif-subjectdistance-value'=> '$1 metra',
+'exif-meteringmode-0' => 'E panjohur',
+'exif-meteringmode-1' => 'Mesatare',
+'exif-meteringmode-6' => 'E pjesshme',
+'exif-meteringmode-255' => 'Tjetër',
+'exif-lightsource-0' => 'I panjohur',
+'exif-lightsource-1' => 'Ditë',
+'exif-lightsource-4' => 'Blic',
+'exif-lightsource-9' => 'Kohë e hapur',
+'exif-lightsource-10' => 'Kohë e vrenjtur',
+'exif-lightsource-11' => 'Hije',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-255' => 'Tjetër burim drite',
+'exif-filesource-3' => 'DSC',
+'exif-scenecapturetype-1'=> 'Peizazh',
+'exif-scenecapturetype-2'=> 'Portret',
+'exif-scenecapturetype-3'=> 'Pamje nate',
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'I dobët',
+'exif-contrast-2' => 'I fortë',
+'exif-saturation-0' => 'Normale',
+'exif-saturation-1' => 'mbushje e pakët',
+'exif-saturation-2' => 'mbushje e shumtë',
+'exif-sharpness-0' => 'Normale',
+'exif-sharpness-1' => 'E butë',
+'exif-sharpness-2' => 'E fortë',
+'exif-subjectdistancerange-0'=> 'E panjohur',
+'exif-subjectdistancerange-2'=> 'Pamje nga afër',
+'exif-subjectdistancerange-3'=> 'Pamje nga larg',
+'exif-gpslatitude-n' => 'Gjerësi veriore',
+'exif-gpslatitude-s' => 'Gjerësi jugore',
+'exif-gpslongitude-e' => 'Gjatësi lindore',
+'exif-gpslongitude-w' => 'Gjatësi perëndimore',
+'exif-gpsstatus-a' => 'Duke bërë matje',
+'exif-gpsmeasuremode-2' => 'matje në 2 madhësi',
+'exif-gpsmeasuremode-3' => 'matje në 3 madhësi',
+'exif-gpsspeed-k' => 'Kilometra në orë',
+'exif-gpsspeed-m' => 'Milje në orë',
+'exif-gpsspeed-n' => 'Nyje',
+'exif-gpsdirection-t' => 'Drejtimi i vërtetë',
+'exif-gpsdirection-m' => 'Drejtimi magnetik',
+'edit-externally' => 'Ndryshoni këtë skedë me një mjet të jashtëm',
+'edit-externally-help' => 'Shikoni [http://meta.wikimedia.org/wiki/Help:External_editors udhëzimet e instalimit] për më shumë informacion.',
+'recentchangesall' => 'të gjitha',
+'imagelistall' => 'të gjitha',
+'watchlistall1' => 'të gjitha',
+'watchlistall2' => 'të gjitha',
+'namespacesall' => 'të gjitha',
+'confirmemail' => 'Vërtetoni adresën tuaj',
+'confirmemail_text' => 'Për të marrë email duhet të vërtetoni adresen tuaj. Shtypni butonin e mëposhtëm për të dërguar një email vërtetimi tek adresa juaj. Email-i do të përmbajë një lidhje me kod të shifruar. Duke ndjekur lidhjen nëpërmjet shfletuesit tuaj do të vërtetoni adresën.',
+'confirmemail_send' => 'Dërgo vërtetimin',
+'confirmemail_sent' => 'Email-i për vërtetim është dërguar.',
+'confirmemail_sendfailed'=> 'Nuk munda të dërgoj email-in e vërtetimit. Kontrolloni adresën tuaj për gabime shtypi.',
+'confirmemail_invalid' => 'Kodi i shifrimit të vërtetimit është gabim ose ka skaduar.',
+'confirmemail_needlogin'=> 'Ju duhet të $1 për ta konfirmuar email-adresën',
+'confirmemail_success' => 'Adresa juaj është vërtetuar. Mund të hyni brënda dhe të përdorni wiki-n.',
+'confirmemail_loggedin' => 'Adresa juaj është vërtetuar.',
+'confirmemail_error' => 'Pati gabim gjatë ruajtjes së vërtetimit tuaj.',
+'confirmemail_subject' => 'Vërtetim adrese nga {{SITENAME}}',
+'confirmemail_body' => 'Dikush, me siguri ju nga IP adresa $1, ka hapur llogarinë "$2" tek {{SITENAME}} dhe ka dhënë këtë adresë email-i.
+
+Në qoftë se është me të vertetë llogaria juaj, vërtetoni këtë adresë duke ndjekur lidhjen e mëposhtme për të mundësuar përdorimin e mjeteve që kërkojnë email tek {{SITENAME}}:
+
+$3
+
+Në qoftë se nuk është llogaria juaj atëhere mos e ndiqni lidhjen. Kodi i shifruar do të skadojë më $4.',
+'tryexact' => 'Kërko përputhje të plotë',
+'searchfulltext' => 'Kërko tekstin e plotë',
+'createarticle' => 'Krijo artikull',
+'scarytranscludedisabled'=> '[Lidhja Interwiki nuk është i mundshëm]',
+'scarytranscludefailed' => '[ju kërkoj ndjesë, marrja e stampës $1 dështoi]',
+'scarytranscludetoolong'=> '[ju kërkoj ndjesë, URL-i është tepër i gjatë]',
+'trackbackbox' => '<div id="mw_trackbacks">
+Lidhje ndjekëse për këtë artikull:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 hiqe])',
+'trackbacklink' => 'Lidhje ndjekëse',
+'trackbackdeleteok' => 'Lidhja ndjekëse u hoq.',
+'deletedwhileediting' => 'Kujdes! Kjo faqe është grisur pasi ju keni filluar redaktimin!',
+'confirmrecreate' => 'Përdoruesi [[User:$1|$1]] ([[User talk:$1|diskutime]]) grisi këtë artikull mbasi ju filluat ta redaktoni për arsyen:
+: \'\'$2\'\'
+Ju lutem konfirmoni nëse dëshironi me të vertetë ta ri-krijoni këtë artikull.',
+'recreate' => 'Rikrijo',
+'unit-pixel' => 'px',
+'redirectingto' => 'Përcjellin tek [[$1]]...',
+'confirm_purge' => 'Pastro cache për këtë faqe?
+
+$1',
+'confirm_purge_button' => 'Shko',
+'youhavenewmessagesmulti'=> 'Ju keni mesazh të ri në $1',
+'searchcontaining' => 'Kërko për artikuj që përmbajnë \'\'$1\'\'.',
+'searchnamed' => 'Kërko për artikuj të quajtur \'\'$1\'\'.',
+'articletitles' => 'Artikuj që fillojnë me \'\'$1\'\'',
+'hideresults' => 'Fshih rezultatet',
+'displaytitle' => '(Lidhje te kjo faqe si [[$1]])',
+'loginlanguagelabel' => 'Gjuha: $1',
+);
+?>
diff --git a/languages/messages/MessagesSr.php b/languages/messages/MessagesSr.php
new file mode 100644
index 000000000000..94ff5ca24cf1
--- /dev/null
+++ b/languages/messages/MessagesSr.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Serbian
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'sr-ec';
+$linkTrail = '/^([abvgdđežzijklljmnnjoprstćufhcčdžšабвгдђежзијклљмнњопрстћуфхцчџш]+)(.*)$/usD';
+
+?>
diff --git a/languages/messages/MessagesSr_ec.php b/languages/messages/MessagesSr_ec.php
new file mode 100644
index 000000000000..9f99c9d8c5a1
--- /dev/null
+++ b/languages/messages/MessagesSr_ec.php
@@ -0,0 +1,2214 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$namespaceNames = array(
+ NS_MEDIA => "Медија",
+ NS_SPECIAL => "Посебно",
+ NS_MAIN => "",
+ NS_TALK => "Разговор",
+ NS_USER => "Корисник",
+ NS_USER_TALK => "Разговор_са_корисником",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => "Разговор_о_$1",
+ NS_IMAGE => "Слика",
+ NS_IMAGE_TALK => "Разговор_о_слици",
+ NS_MEDIAWIKI => "МедијаВики",
+ NS_MEDIAWIKI_TALK => "Разговор_о_МедијаВикију",
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Разговор_о_шаблону',
+ NS_HELP => 'Помоћ',
+ NS_HELP_TALK => 'Разговор_о_помоћи',
+ NS_CATEGORY => 'Категорија',
+ NS_CATEGORY_TALK => 'Разговор_о_категорији',
+);
+
+# Aliases to latin namespaces
+$namespaceAliases = array(
+ "Medija" => NS_MEDIA,
+ "Posebno" => NS_SPECIAL,
+ "Razgovor" => NS_TALK,
+ "Korisnik" => NS_USER,
+ "Razgovor_sa_korisnikom" => NS_USER_TALK,
+ "Razgovor_o_$1" => NS_PROJECT_TALK,
+ "Slika" => NS_IMAGE,
+ "Razgovor_o_slici" => NS_IMAGE_TALK,
+ "MedijaViki" => NS_MEDIAWIKI,
+ "Razgovor_o_MedijaVikiju" => NS_MEDIAWIKI_TALK,
+ 'Šablon' => NS_TEMPLATE,
+ 'Razgovor_o_šablonu' => NS_TEMPLATE_TALK,
+ 'Pomoć' => NS_HELP,
+ 'Razgovor_o_pomoći' => NS_HELP_TALK,
+ 'Kategorija' => NS_CATEGORY,
+ 'Razgovor_o_kategoriji' => NS_CATEGORY_TALK,
+);
+
+
+$quickbarSettings = array(
+ "Никаква", "Причвршћена лево", "Причвршћена десно", "Плутајућа лево"
+);
+
+$skinNames = array(
+ "Обична", "Носталгија", "Келнско плаво", "Педингтон", "Монпарнас"
+);
+
+$extraUserToggles = array(
+ 'nolangconversion',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'hh:mm d. month y.',
+ 'hh:mm d month y',
+ 'hh:mm dd.mm.yyyy',
+ 'hh:mm d.m.yyyy',
+ 'hh:mm d. mon y.',
+ 'hh:mm d mon y',
+ 'h:mm d. month y.',
+ 'h:mm d month y',
+ 'h:mm dd.mm.yyyy',
+ 'h:mm d.m.yyyy',
+ 'h:mm d. mon y.',
+ 'h:mm d mon y',
+);
+
+$datePreferences = array(
+ 'default',
+ 'hh:mm d. month y.',
+ 'hh:mm d month y',
+ 'hh:mm dd.mm.yyyy',
+ 'hh:mm d.m.yyyy',
+ 'hh:mm d. mon y.',
+ 'hh:mm d mon y',
+ 'h:mm d. month y.',
+ 'h:mm d month y',
+ 'h:mm dd.mm.yyyy',
+ 'h:mm d.m.yyyy',
+ 'h:mm d. mon y.',
+ 'h:mm d mon y',
+);
+
+$defaultDateFormat = 'hh:mm d. month y.';
+
+$dateFormats = array(
+ /*
+ 'Није битно',
+ '06:12, 5. јануар 2001.',
+ '06:12, 5 јануар 2001',
+ '06:12, 05.01.2001.',
+ '06:12, 5.1.2001.',
+ '06:12, 5. јан 2001.',
+ '06:12, 5 јан 2001',
+ '6:12, 5. јануар 2001.',
+ '6:12, 5 јануар 2001',
+ '6:12, 05.01.2001.',
+ '6:12, 5.1.2001.',
+ '6:12, 5. јан 2001.',
+ '6:12, 5 јан 2001',
+ */
+
+ 'hh:mm d. month y. time' => 'H:i',
+ 'hh:mm d month y time' => 'H:i',
+ 'hh:mm dd.mm.yyyy time' => 'H:i',
+ 'hh:mm d.m.yyyy time' => 'H:i',
+ 'hh:mm d. mon y. time' => 'H:i',
+ 'hh:mm d mon y time' => 'H:i',
+ 'h:mm d. month y. time' => 'G:i',
+ 'h:mm d month y time' => 'G:i',
+ 'h:mm dd.mm.yyyy time' => 'G:i',
+ 'h:mm d.m.yyyy time' => 'G:i',
+ 'h:mm d. mon y. time' => 'G:i',
+ 'h:mm d mon y time' => 'G:i',
+
+ 'hh:mm d. month y. date' => 'j. F Y.',
+ 'hh:mm d month y date' => 'j F Y',
+ 'hh:mm dd.mm.yyyy date' => 'd.m.Y',
+ 'hh:mm d.m.yyyy date' => 'j.n.Y',
+ 'hh:mm d. mon y. date' => 'j. M Y.',
+ 'hh:mm d mon y date' => 'j M Y',
+ 'h:mm d. month y. date' => 'j. F Y.',
+ 'h:mm d month y date' => 'j F Y',
+ 'h:mm dd.mm.yyyy date' => 'd.m.Y',
+ 'h:mm d.m.yyyy date' => 'j.n.Y',
+ 'h:mm d. mon y. date' => 'j. M Y.',
+ 'h:mm d mon y date' => 'j M Y',
+
+ 'hh:mm d. month y. both' =>'H:i, j. F Y.',
+ 'hh:mm d month y both' =>'H:i, j F Y',
+ 'hh:mm dd.mm.yyyy both' =>'H:i, d.m.Y',
+ 'hh:mm d.m.yyyy both' =>'H:i, j.n.Y',
+ 'hh:mm d. mon y. both' =>'H:i, j. M Y.',
+ 'hh:mm d mon y both' =>'H:i, j M Y',
+ 'h:mm d. month y. both' =>'G:i, j. F Y.',
+ 'h:mm d month y both' =>'G:i, j F Y',
+ 'h:mm dd.mm.yyyy both' =>'G:i, d.m.Y',
+ 'h:mm d.m.yyyy both' =>'G:i, j.n.Y',
+ 'h:mm d. mon y. both' =>'G:i, j. M Y.',
+ 'h:mm d mon y both' =>'G:i, j M Y',
+);
+
+/* NOT USED IN STABLE VERSION */
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#Преусмери', '#redirect', '#преусмери', '#ПРЕУСМЕРИ' ),
+ 'notoc' => array( 0, '__NOTOC__', '__БЕЗСАДРЖАЈА__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__ФОРСИРАНИСАДРЖАЈ__' ),
+ 'toc' => array( 0, '__TOC__', '__САДРЖАЈ__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__БЕЗ_ИЗМЕНА__', '__БЕЗИЗМЕНА__' ),
+ 'start' => array( 0, '__START__', '__ПОЧЕТАК__' ),
+ 'end' => array( 0, '__END__', '__КРАЈ__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'ТРЕНУТНИМЕСЕЦ' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'ТРЕНУТНИМЕСЕЦИМЕ' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'ТРЕНУТНИМЕСЕЦГЕН' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'ТРЕНУТНИМЕСЕЦСКР' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'ТРЕНУТНИДАН' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'ТРЕНУТНИДАНИМЕ' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'ТРЕНУТНАГОДИНА' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'ТРЕНУТНОВРЕМЕ' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'БРОЈЧЛАНАКА' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'БРОЈДАТОТЕКА', 'БРОЈФАЈЛОВА' ),
+ 'pagename' => array( 1, 'PAGENAME', 'СТРАНИЦА' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'СТРАНИЦЕ' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'ИМЕНСКИПРОСТОР' ),
+ 'namespacee' => array( 1, 'NAMESPACEE', 'ИМЕНСКИПРОСТОРИ' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'ПУНОИМЕСТРАНЕ' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE', 'ПУНОИМЕСТРАНЕЕ' ),
+ 'msg' => array( 0, 'MSG:', 'ПОР:' ),
+ 'subst' => array( 0, 'SUBST:', 'ЗАМЕНИ:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'НВПОР:' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'мини' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'мини=$1' ),
+ 'img_right' => array( 1, 'right', 'десно', 'д' ),
+ 'img_left' => array( 1, 'left', 'лево', 'л' ),
+ 'img_none' => array( 1, 'none', 'н', 'без' ),
+ 'img_width' => array( 1, '$1px', '$1пискел' , '$1п' ),
+ 'img_center' => array( 1, 'center', 'centre', 'центар', 'ц' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'оквир', 'рам' ),
+ 'int' => array( 0, 'INT:', 'ИНТ:' ),
+ 'sitename' => array( 1, 'SITENAME', 'ИМЕСАЈТА' ),
+ 'ns' => array( 0, 'NS:', 'ИП:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'ЛОКАЛНААДРЕСА:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'ЛОКАЛНЕАДРЕСЕ:' ),
+ 'server' => array( 0, 'SERVER', 'СЕРВЕР' ),
+ 'servername' => array( 0, 'SERVERNAME', 'ИМЕСЕРВЕРА' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'СКРИПТА' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'ГРАМАТИКА:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', '__БЕЗКН__', '__BEZKN__' ),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', '__БЕЗЦЦ__' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'ТРЕНУТНАНЕДЕЉА' ),
+ 'currentdow' => array( 1, 'CURRENTDOW', 'ТРЕНУТНИДОВ' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'ИДРЕВИЗИЈЕ' ),
+ 'plural' => array( 0, 'PLURAL:', 'МНОЖИНА:' ),
+ 'fullurl' => array( 0, 'FULLURL:', 'ПУНУРЛ:' ),
+ 'fullurle' => array( 0, 'FULLURLE:', 'ПУНУРЛЕ:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:', 'ЛЦПРВИ:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:', 'УЦПРВИ:' ),
+ 'lc' => array( 0, 'LC:', 'ЛЦ:' ),
+ 'uc' => array( 0, 'UC:', 'УЦ:' ),
+);
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+
+$messages = array(
+# stylesheets
+'common.css' => '/** CSS koji važi za sve skinove */',
+'monobook.css' => '/** Samo za MonoBook skin */',
+
+# User preference toggles
+'tog-underline' => 'Подвуци везе',
+'tog-highlightbroken' => 'Форматирај покварене везе <a href="" class="new">овако</a> (алтернатива: овако<a href="" class="internal">?</a>).',
+'tog-justify' => 'Уравнај пасусе',
+'tog-hideminor' => 'Сакриј мале измене у списку скорашњих измена',
+'tog-extendwatchlist' => 'Побољшан списак надгледања',
+'tog-usenewrc' => 'Побољшан списак скорашњих измена (захтева JavaScript)',
+'tog-numberheadings' => 'Аутоматски нумериши поднаслове',
+'tog-showtoolbar' => 'Прикажи дугмиће за измене (захтева JavaScript)',
+'tog-editondblclick' => 'Мењај странице двоструким кликом (захтева JavaScript)',
+'tog-editsection' => 'Омогући измену делова [уреди] везама',
+'tog-editsectiononrightclick' => 'Омогући измену делова десним кликом<br />на њихове наслове (захтева JavaScript)',
+'tog-showtoc' => 'Прикажи садржај (у чланцима са више од 3 поднаслова)',
+'tog-rememberpassword' => 'Памти лозинку кроз више сеанси',
+'tog-editwidth' => 'Поље за измене има пуну ширину',
+'tog-watchcreations' => 'Додај странице које правим у мој списак надгледања',
+'tog-watchdefault' => 'Додај странице које мењам у мој списак надгледања',
+'tog-minordefault' => 'Означи све измене малим испрва',
+'tog-previewontop' => 'Прикажи претпреглед пре поља за измену',
+'tog-previewonfirst' => 'Прикажи претпреглед при првој измени',
+'tog-nocache' => 'Онемогући кеширање страница',
+'tog-enotifwatchlistpages' => 'Пошаљи ми е-пошту када се промени страна коју надгледам',
+'tog-enotifusertalkpages' => 'Пошаљи ми е-пошту када се промени моја корисничка страна за разговор',
+'tog-enotifminoredits' => 'Пошаљи ми е-пошту такође за мале измене страна',
+'tog-enotifrevealaddr' => 'Откриј адресу моје е-поште у пошти обавештења',
+'tog-shownumberswatching' => 'Прикажи број корисника који надгледају',
+'tog-fancysig' => 'Чист потпис (без аутоматских веза)',
+'tog-externaleditor' => 'Користи спољашњи уређивач по подразумеваним подешавањима',
+'tog-externaldiff' => 'Користи спољашњи програм за приказ разлика по подразумеваним подешавањима',
+'tog-showjumplinks' => 'Омогући "скочи на" везе',
+'tog-uselivepreview' => 'Користи живи претпреглед (захтева JavaScript) (експериментално)',
+'tog-autopatrol' => 'Означи измене које правим патролираним',
+'tog-forceeditsummary' => 'Упозори ме кад не унесем опис измене',
+'tog-watchlisthideown' => 'Сакриј моје измене са списка надгледања',
+'tog-watchlisthidebots' => 'Сакриј измене ботова са списка надгледања',
+'tog-nolangconversion' => 'Искључи конверзију варијанти',
+
+'underline-always' => 'Увек',
+'underline-never' => 'Никад',
+'underline-default' => 'По подешавањима браузера',
+
+'skinpreview' => '(Преглед)',
+
+# dates
+'sunday' => 'недеља',
+'monday' => 'понедељак',
+'tuesday' => 'уторак',
+'wednesday' => 'среда',
+'thursday' => 'четвртак',
+'friday' => 'петак',
+'saturday' => 'субота',
+'sun' => 'нед',
+'mon' => 'пон',
+'tue' => 'уто',
+'wed' => 'сре',
+'thu' => 'чет',
+'fri' => 'пет',
+'sat' => 'суб',
+'january' => 'јануар',
+'february' => 'фебруар',
+'march' => 'март',
+'april' => 'април',
+'may_long' => 'мај',
+'june' => 'јун',
+'july' => 'јул',
+'august' => 'август',
+'september' => 'септембар',
+'october' => 'октобар',
+'november' => 'новембар',
+'december' => 'децембар',
+'january-gen' => 'јануара',
+'february-gen' => 'фебруара',
+'march-gen' => 'марта',
+'april-gen' => 'априла',
+'may-gen' => 'маја',
+'june-gen' => 'јуна',
+'july-gen' => 'јула',
+'august-gen' => 'августа',
+'september-gen' => 'септембра',
+'october-gen' => 'октобра',
+'november-gen' => 'новембра',
+'december-gen' => 'децембра',
+'jan' => 'јан',
+'feb' => 'феб',
+'mar' => 'мар',
+'apr' => 'апр',
+'may' => 'мај',
+'jun' => 'јун',
+'jul' => 'јул',
+'aug' => 'авг',
+'sep' => 'сеп',
+'oct' => 'окт',
+'nov' => 'нов',
+'dec' => 'дец',
+# Bits of text used by many pages:
+#
+'categories' => 'Категорије страница',
+'pagecategories' => '{{PLURAL:$1|Категорија|Категорије|Категорије}} страница',
+'category_header' => 'Чланака у категорији "$1"',
+'subcategories' => 'Поткатегорије',
+
+'mainpage' => 'Главна страна',
+'mainpagetext' => '<big>\'\'\'МедијаВики је успешно инсталиран.\'\'\'</big>',
+'mainpagedocfooter' => "Молимо видите [http://meta.wikimedia.org/wiki/Help:Contents кориснички водич] за информације о употреби вики софтвера.
+
+== За почетак ==
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Помоћ у вези са подешавањима]
+* [http://www.mediawiki.org/wiki/Help:FAQ Најчешће постављена питања]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Мејлинг листа о издањима МедијаВикија]",
+
+'portal' => 'Радионица',
+'portal-url' => 'Project:Радионица',
+'about' => 'О...',
+'aboutsite' => 'О пројекту {{SITENAME}}',
+'aboutpage' => 'Project:О',
+'article' => 'Чланак',
+'help' => 'Помоћ',
+'helppage' => '{{ns:help}}:Садржај',
+'bugreports' => 'Пријаве грешака',
+'bugreportspage' => 'Project:Пријаве_грешака',
+'sitesupport' => 'Донације',
+'sitesupport-url' => 'Project:Донације',
+'faq' => 'НПП',
+'faqpage' => 'Project:НПП',
+'edithelp' => 'Помоћ око уређивања',
+'newwindow' => '(нови прозор)',
+'edithelppage' => '{{ns:help}}:Уређивање',
+'cancel' => 'Поништи',
+'qbfind' => 'Пронађи',
+'qbbrowse' => 'Прелиставај',
+'qbedit' => 'Измени',
+'qbpageoptions' => 'Опције странице',
+'qbpageinfo' => 'Информације о страници',
+'qbmyoptions' => 'Моје опције',
+'qbspecialpages' => 'Посебне странице',
+'moredotdotdot' => 'Још...',
+'mypage' => 'Моја страница',
+'mytalk' => 'Мој разговор',
+'anontalk' => 'Разговор за ову ИП адресу',
+'navigation' => 'Навигација',
+
+# Metadata in edit box
+'metadata_help' => 'Метаподаци (види [[Project:Метаподаци]] за објашњење):',
+
+'currentevents' => 'Тренутни догађаји',
+'currentevents-url' => 'Тренутни догађаји',
+'disclaimers' => 'Одрицање одговорности',
+'disclaimerpage' => 'Project:Одрицање одговорности',
+'privacy' => 'Политика приватности',
+'privacypage' => 'Project:Политика приватности',
+'errorpagetitle' => 'Грешка',
+'returnto' => 'Повратак на $1.',
+'tagline' => 'Из пројекта {{SITENAME}}',
+'help' => 'Помоћ',
+'search' => 'претрага',
+'searchbutton' => 'Тражи',
+'go' => 'Иди',
+'searcharticle' => 'Иди',
+'history' => 'Историја странице',
+'history_short' => 'историја',
+'updatedmarker' => 'ажурирано од моје последње посете',
+'info_short' => 'Информације',
+'printableversion' => 'Верзија за штампу',
+'permalink' => 'Пермалинк',
+'print' => 'Штампа',
+'edit' => 'Уреди',
+'editthispage' => 'Уреди ову страницу',
+'delete' => 'обриши',
+'deletethispage' => 'Обриши ову страницу',
+'undelete_short' => 'врати {{PLURAL:$1|једну обрисану измену|$1 обрисане измене|$1 обрисаних измена}}',
+'protect' => 'заштити',
+'protectthispage' => 'Заштити ову страницу',
+'unprotect' => 'Склони заштиту',
+'unprotectthispage' => 'Склони заштиту са ове странице',
+'newpage' => 'Нова страница',
+'talkpage' => 'Разговор о овој страници',
+'specialpage' => 'Посебна страница',
+'personaltools' => 'Лични алати',
+'postcomment' => 'Пошаљи коментар',
+'articlepage' => 'Погледај чланак',
+'talk' => 'Разговор',
+'views' => 'Прегледи',
+'toolbox' => 'алати',
+'userpage' => 'Погледај корисничку страну',
+'projectpage' => 'Погледај страну пројекта',
+'imagepage' => 'Погледај страну слике',
+'mediawikipage' => 'Види страницу поруке',
+'templatepage' => 'Види страницу шаблона',
+'viewhelppage' => 'Види страницу помоћи',
+'categorypage' => 'Види страницу категорије',
+'viewtalkpage' => 'Погледај разговор',
+'otherlanguages' => 'Остали језици',
+'redirectedfrom' => '(Преусмерено са $1)',
+'autoredircomment' => 'Преусмерење на [[$1]]',
+'redirectpagesub' => 'Страна преусмерења',
+'lastmodifiedat' => 'Ова страница је последњи пут измењена $2, $1.',
+'viewcount' => 'Овој страници је приступљено {{PLURAL:$1|једном|$1 пута|$1 пута}}.',
+'copyright' => 'Садржај је објављен под $1.',
+'protectedpage' => 'Заштићена страница',
+'jumpto' => 'Скочи на:',
+'jumptonavigation' => 'навигација',
+'jumptosearch' => 'претрага',
+
+'badaccess' => 'Грешка у дозволама',
+'badaccess-group0' => 'Није вам дозвољено да извршите акцију коју сте покренули.',
+'badaccess-group1' => 'Акција коју сте покренули је резеревисана за кориснике у групи $1.',
+'badaccess-group2' => 'Акција коју сте покренули је резервисана за кориснике из једне од група $1.',
+'badaccess-groups' => 'Акција коју сте покренули је резервисана за кориснике из једне од група $1.',
+
+'versionrequired' => 'Верзија $1 МедијаВикија је потребна',
+'versionrequiredtext' => 'Верзија $1 МедијаВикија је потребна да би се користила ова страна. Погледајте [[{{ns:special}}:Version|верзију]]',
+
+'ok' => 'да',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Добављено из "$1"',
+'youhavenewmessages' => 'Имате $1 ($2).',
+'newmessageslink' => 'нових порука',
+'newmessagesdifflink' => 'најсвежије измене',
+'editsection' => 'уреди',
+'editold' => 'уреди',
+'editsectionhint' => 'Уреди део: $1',
+'toc' => 'Садржај',
+'showtoc' => 'прикажи',
+'hidetoc' => 'сакриј',
+'thisisdeleted' => 'Погледај или врати $1?',
+'viewdeleted' => 'Погледај $1?',
+'restorelink' => '{{PLURAL:$1|једна обрисана измена|$1 обрисане измене|$1 обрисаних измена}}',
+'feedlinks' => 'Фид:',
+'feed-invalid' => 'Лош тип фида пријаве.',
+'feed-atom' => 'Атом',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Чланак',
+'nstab-user' => 'Корисничка страна',
+'nstab-media' => 'Медиј',
+'nstab-special' => 'Посебна',
+'nstab-project' => 'Страна пројекта',
+'nstab-image' => 'Слика',
+'nstab-mediawiki' => 'Порука',
+'nstab-template' => 'Шаблон',
+'nstab-help' => 'Помоћ',
+'nstab-category' => 'Категорија',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Нема такве акције',
+'nosuchactiontext' => 'Акцију наведену у УРЛ-у вики софтвер
+није препознао.',
+'nosuchspecialpage' => 'Нема такве посебне странице',
+'nospecialpagetext' => 'Тражили сте непостојећу посебну страницу. Списак свих посебних страница се може наћи на [[{{ns:special}}:Specialpages]].',
+
+# General errors
+#
+'error' => 'Грешка',
+'databaseerror' => 'Грешка у бази',
+'dberrortext' => 'Десила се синтаксна грешка упита базе.
+Ово можда указује на грешке у софтверу.
+Последњи покушани упит је био:
+<blockquote><tt>$1</tt></blockquote>
+из функције "<tt>$2</tt>".
+MySQL је вратио грешку "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Десила се синтаксна грешка упита базе.
+Последњи покушани упит је био:
+"$1"
+из функције "$2".
+MySQL је вратио грешку "$3: $4".',
+'noconnect' => 'Жао нам је! Вики има техничке потешкоће, и не може да се повеже се сервером базе.',
+'nodb' => 'Не могу да изаберем базу $1',
+'cachederror' => 'Ово је кеширана копија захтеване странице, и можда није ажурирана.',
+'laggedslavemode' => 'Упозорење: могуће је да страна није скоро ажурирана.',
+'readonly' => 'База је закључана',
+'enterlockreason' => 'Унесите разлог за закључавање, укључујући процену
+времена откључавања',
+'readonlytext' => 'База података је тренутно закључана за нове
+уносе и остале измене, вероватно због рутинског одржавања,
+после чега ће бити враћена у уобичајено стање.
+Администратор који ју је закључао дао је ово објашњење: $1',
+'missingarticle' => 'База није нашла текст странице
+који је требало, назван "$1".
+
+Ово је обично изазвано праћењем застареле "разл" везе или везе ка историји
+странице која је обрисана.
+
+Ако ово није случај, можда сте пронашли грешку у софтверу.
+Молимо вас пријавите ово једном од [[Project:Администратори|администратора]], заједно са УРЛ-ом.',
+'readonly_lag' => 'База података је аутоматски закључана док слејв сервери не сустигну мастер',
+'internalerror' => 'Интерна грешка',
+'filecopyerror' => 'Не могу да ископирам фајл "$1" на "$2".',
+'filerenameerror' => 'Не могу да преименујем фајл "$1" у "$2".',
+'filedeleteerror' => 'Не могу да обришем фајл "$1".',
+'filenotfound' => 'Не могу да нађем фајл "$1".',
+'unexpected' => 'Неочекивана вредност: "$1"="$2".',
+'formerror' => 'Грешка: не могу да пошаљем упитник',
+'badarticleerror' => 'Ова акција не може бити извршена на овој страници.',
+'cannotdelete' => 'Не могу да обришем наведену страницу или фајл. (Могуће је да је неко други већ обрисао.)',
+'badtitle' => 'Лош наслов',
+'badtitletext' => 'Захтевани наслов странице је био неисправан, празан или
+неисправно повезан међујезички или интервики наслов. Можда садржи један или више карактера који не могу да се употребљавају у насловима.',
+'perfdisabled' => 'Жао нам је! Ова могућност је привремено онемогућена јер успорава базу до те мере да више нико не може да користи вики.',
+'perfdisabledsub' => 'Овде је снимљена копија $1:', # obsolete?
+'perfcached' => 'Следећи подаци су кеширани и не морају бити у потпуности ажурирани.',
+'perfcachedts' => 'Следећи подаци су кеширани и последњи пут су ажурирани: $1',
+'wrong_wfQuery_params' => 'Нетачни параметри за wfQuery()<br />
+Функција: $1<br />
+Претрага: $2',
+'viewsource' => 'погледај код',
+'viewsourcefor' => 'за $1',
+'protectedtext' => 'Ова страница је закључана за измене.
+
+Можете гледати и копирати садржај ове стране:',
+'protectedinterface' => '\'\'\'Упозорење:\'\'\' Мењате страну која се користи да пружи текст интерфејса за софтвер. Измене на овој страни ће утицати на изглед корисничког интерфејса за остале кориснике.',
+'editinginterface' => "'''Упозорење:''' Уређујете страницу чија је намена уписивање текста за интерфејс софтвера. Измене у овој страници ће променити изглед корисничког интефејса свих корисника.",
+'sqlhidden' => '(SQL претрага сакривена)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Одјави се',
+'logouttext' => '<strong>Сада сте одјављени.</strong><br />
+Можете да наставите да користите пројекат {{SITENAME}} анонимно, или се поново пријавити као други корисник. Обратите пажњу да неке странице могу наставити да се приказују као да сте још увек пријављени, док не очистите кеш свог браузера.',
+
+'welcomecreation' => '== Добродошли, $1! ==
+
+Ваш налог је направљен.
+Не заборавите да прилагодите себи своја {{SITENAME}} подешавања.',
+
+'loginpagetitle' => 'Пријављивање',
+'yourname' => 'Корисничко име',
+'yourpassword' => 'Ваша лозинка',
+'yourpasswordagain' => 'Поновите лозинку',
+'remembermypassword' => 'Запамти ме',
+'yourdomainname' => 'Ваш домен',
+'externaldberror' => 'Дошло је или до грешке при спољашњој аутентификацији базе података или вам није дозвољено да ажурирате свој спољашњи налог.',
+'loginproblem' => '<b>Било је проблема са вашим пријављивањем.</b><br />Покушајте поново!',
+'alreadyloggedin' => '<strong>Корисниче $1, већ сте пријављени!</strong><br />',
+
+'login' => 'Пријави се',
+'loginprompt' => 'Морате да имате омогућене колачиће (\'\'cookies\'\') да бисте се пријавили на {{SITENAME}}.',
+'userlogin' => 'Региструј се / Пријави се',
+'logout' => 'Одјави се',
+'userlogout' => 'Одјави се',
+'notloggedin' => 'Нисте пријављени',
+'nologin' => 'Немате налог? $1.',
+'nologinlink' => 'Направите налог',
+'createaccount' => 'Направи налог',
+'gotaccount' => 'Већ имате налог? $1.',
+'gotaccountlink' => 'Пријави се',
+'createaccountmail' => 'е-поштом',
+'badretype' => 'Лозинке које сте унели се не поклапају.',
+'userexists' => 'Корисничко име које сте унели већ је у употреби. Молимо изаберите друго име.',
+'youremail' => 'Адреса ваше е-поште *',
+'username' => 'Корисничко име:',
+'uid' => 'Кориснички ИД:',
+'yourrealname' => 'Ваше право име *',
+'yourlanguage' => 'Језик:',
+'yourvariant' => 'Варијанта:',
+'yournick' => 'Надимак:',
+'badsig' => 'Грешка у потпису; проверите HTML тагове.',
+'email' => 'Е-пошта',
+'prefs-help-email-enotif' => 'Ова адреса се такође користи да вам се шаљу обавештења преко е-поште ако сте омогућили ту опцију.',
+'prefs-help-realname' => '* Право име (опционо): ако изаберете да дате име, ово ће бити коришћено за приписивање за ваш рад.',
+'loginerror' => 'Грешка при пријављивању',
+'prefs-help-email' => '* Е-пошта (опционо): Омогућује осталима да вас контактирају преко ваше корисничке стране или стране за разговора без потребе да одајете свој идентитет.',
+'nocookiesnew' => 'Кориснички налог је направљен, али нисте пријављени. {{SITENAME}} користи колачиће (\'\'cookies\'\') да би се корисници пријавили. Ви сте онемогућили колачиће на свом рачунару. Молимо омогућите их, а онда се пријавите са својим новим корисничким именом и лозинком.',
+'nocookieslogin' => '{{SITENAME}} користи колачиће (\'\'cookies\'\') да би се корисници пријавили. Ви сте онемогућили колачиће на свом рачунару. Молимо омогућите их и покушајте поново са пријавом.',
+'noname' => 'Нисте изабрали исправно корисничко име.',
+'loginsuccesstitle' => 'Пријављивање успешно',
+'loginsuccess' => '\'\'\'Сада сте пријављени на {{SITENAME}} као "$1".\'\'\'',
+'nosuchuser' => 'Не постоји корисник са именом "$1". Проверите да ли сте добро написали или направите нови кориснички налог.',
+'nosuchusershort' => 'Не постоји корисник са именом "$1". Проверите да ли сте добро написали.',
+'nouserspecified' => 'Морате да назначите корисничко име.',
+'wrongpassword' => 'Лозинка коју сте унели је неисправна. Молимо покушајте поново.',
+'wrongpasswordempty' => 'Лозинка коју сте унели је празна. Молимо покушајте поново.',
+'mailmypassword' => 'Пошаљи ми лозинку',
+'passwordremindertitle' => '{{SITENAME}} подсетник за шифру',
+'passwordremindertext' => 'Неко (вероватно ви, са ИП адресе $1)
+је захтевао да вам пошаљемо нову лозинку за {{SITENAME}} ($4).
+Лозинка за корисника "$2" је сада "$3".
+Сада треба да се пријавите и промените своју лозинку.
+
+Ако је неко други поднео овај захтев или уколико сте се сетили своје лозинке и више не желите да је мењате, можете да игноришете ову поруку и наставите да користите своју стару шифру.',
+'noemail' => 'Не постоји адреса е-поште за корисника "$1".',
+'passwordsent' => 'Нова шифра је послата на адресу е-поште корисника "$1".
+Молимо пријавите се пошто је примите.',
+'blocked-mailpassword' => 'Вашој ИП адреси је блокиран приступ уређивању, из ког разлога није могуће користити функцију подсећања лозинке, ради превенције извршења недозвољене акције.',
+'eauthentsent' => 'Е-пошта за потврду је послата на назначену адресу е-поште. Пре него што се било која друга е-пошта пошаље на налог, мораћете да пратите упутства у е-пошти, да бисте потврдили да је налог заиста ваш.',
+'throttled-mailpassword' => 'Подсетник лозинке вам је већ послао једну поруку у задњих $1 сати. Ради превенције извршења недозвољене акције, подсетник шаље само једну поруку у року од $1 сати.',
+'mailerror' => 'Грешка при слању е-поште: $1',
+'acct_creation_throttle_hit' => 'Жао нам је, већ сте направили $1 корисничка имена. Више није дозвољено.',
+'emailauthenticated' => 'Ваша адреса е-поште је потврђена: $1.',
+'emailnotauthenticated' => 'Ваша адреса е-поште још увек није потврђена. Е-пошта неће бити послата ни за једну од следећих могућности.',
+'noemailprefs' => 'Назначите адресу е-поште како би ове могућности радиле.',
+'emailconfirmlink' => 'Потврдите вашу адресу е-поште',
+'invalidemailaddress' => 'Адреса е-поште не може бити примљена јер изгледа није правилног формата. Молимо унесите добро-форматирану адресу или испразните то поље.',
+'accountcreated' => 'Налог је направљен',
+'accountcreatedtext' => 'Кориснички налог за $1 је направљен.',
+
+# Edit page toolbar
+'bold_sample' => 'подебљан текст',
+'bold_tip' => 'подебљан текст',
+'italic_sample' => 'курзиван текст',
+'italic_tip' => 'курзиван текст',
+'link_sample' => 'наслов везе',
+'link_tip' => 'унутрашња веза',
+'extlink_sample' => 'http://www.adresa.com опис адресе',
+'extlink_tip' => 'спољашња веза (не заборавите префикс http://)',
+'headline_sample' => 'Наслов',
+'headline_tip' => 'Наслов другог нивоа',
+'math_sample' => 'Овде унесите формулу',
+'math_tip' => 'Математичка формула (LaTeX)',
+'nowiki_sample' => 'Додај неформатирани текст овде',
+'nowiki_tip' => 'Игнориши вики форматирање',
+'image_sample' => 'име_слике.jpg',
+'image_tip' => 'Уклопљена слика',
+'media_sample' => 'име_медија_фајла.mp3',
+'media_tip' => 'Путања ка мултимедијалном фајлу',
+'sig_tip' => 'Ваш потпис са тренутним временом',
+'hr_tip' => 'Хоризонтална линија',
+
+# Edit pages
+#
+'summary' => 'Опис измене',
+'subject' => 'Тема/наслов',
+'minoredit' => 'Ово је мала измена',
+'watchthis' => 'Надгледај овај чланак',
+'savearticle' => 'Сними страницу',
+'preview' => 'Претпреглед',
+'showpreview' => 'Прикажи претпреглед',
+'showlivepreview' => 'Живи претпреглед',
+'showdiff' => 'Прикажи промене',
+'anoneditwarning' => 'Нисте пријављени. Ваша ИП адреса ће бити забележена у историји измена ове стране.',
+'missingsummary' => '\'\'\'Подсетник:\'\'\' Нисте унели опис измене. Уколико кликнете Сними страницу поново, ваше измене ће бити снимљене без описа.',
+'missingcommenttext' => 'Молимо унестите коментар испод.',
+'missingcommentheader' => "'''Подсетник:''' Нисте навели наслов овог коментара. Уколико кликнете ''Сними поново'', ваш коментар ће бити снимљен без наслова.",
+'blockedtitle' => 'Корисник је блокиран',
+'blockedtext' => '<big>\'\'\'Ваше корисничко име или ИП адреса је блокирано.\'\'\'</big>
+
+Блокирао вас је корисник $1. Разлог за блокирање је \'\'$2\'\'.
+
+Можете контактирати корисника $1 или неког другог [[{{ns:project}}:Администратори|администратора]] како бисте разговарали о блокади. Не можете да користите опцију "Пошаљи е-пошту овом кориснику" уколико немате ваљану адресу е-поште наведену у вашим [[{ns:special}}:Preferences|подешавањима]]. Ваша тренутна ИП адреса је $3. Молимо укључите ово у сваки ваш захтев.',
+'blockedoriginalsource' => 'Извор \'\'\'$1\'\'\' је приказан испод:',
+'blockededitsource' => 'Текст \'\'\'ваших измена\'\'\' за \'\'\'$1\'\'\' је приказан испод:',
+'whitelistedittitle' => 'Обавезно је пријављивање за уређивање',
+'whitelistedittext' => 'Морате да се [[{{ns:special}}:Userlogin|пријавите]] да бисте мењали чланке.',
+'whitelistreadtitle' => 'Обавезно је пријављивање за читање',
+'whitelistreadtext' => 'Морате да се [[{{ns:special}}:Userlogin|пријавите]] да бисте читали чланке.',
+'whitelistacctitle' => 'Није вам дозвољено да направите налог',
+'whitelistacctext' => 'Да би вам било дозвољено да правите налоге на овом викију морате да се [[{{ns:special}}:Userlogin|пријавите]] и имате одговарајућа овлашћења.',
+'confirmedittitle' => 'Потребна је потврда адресе е-поштe за уређивање',
+'confirmedittext' => 'Морате потврдити вашу адресу е-поште пре уређивања страна. Молимо поставите и потврдите адресу ваше е-поште преко ваших [[{{ns:special}}:Preferences|корисничких подешавања]].',
+'loginreqtitle' => 'Потребно [[{{ns:special}}:Userlogin|пријављивање]]',
+'loginreqlink' => 'пријава',
+'loginreqpagetext' => 'Морате $1 да бисте видели остале стране.',
+'accmailtitle' => 'Лозинка је послата.',
+'accmailtext' => 'Лозинка за налог "$1" је послата на адресу $2.',
+'newarticle' => '(Нови)',
+'newarticletext' => 'Пратили сте везу ка страници која још не постоји.
+Да бисте је направили, почните да куцате у пољу испод
+(погледајте [[{{ns:help}}:Садржај|помоћ]] за више информација).
+Ако сте дошли овде грешком, само кликните дугме \'\'\'back\'\'\' дугме вашег браузера.',
+'anontalkpagetext' => '---- \'\'Ово је страница за разговор за анонимног корисника који још није направио налог или га не користи. Због тога морамо да користимо бројчану ИП адресу како бисмо идентификовали њега или њу. Такву адресу може делити више корисника. Ако сте анонимни корисник и мислите да су вам упућене небитне примедбе, молимо вас да [[{{ns:special}}:Userlogin|направите налог или се пријавите]] да бисте избегли будућу забуну са осталим анонимним корисницима.\'\'',
+'noarticletext' => 'Тренутно нема текста на овој страници. Можете [[{{ns:special}}:Search/{{PAGENAME}}|претражити овај назив]] у осталим страницама или [{{fullurl:{{FULLPAGENAME}}|action=edit}} уредити ову страницу].',
+'clearyourcache' => '\'\'\'Запамтите:\'\'\' Након снимања, можда морате очистити кеш вашег браузера да бисте видели промене. \'\'\'Mozilla / Firefox / Safari:\'\'\' држите \'\'Shift\'\' док кликћете \'\'Reload\'\' или притисните \'\'Shift+Ctrl+R\'\' (\'\'Cmd-Shift-R\'\' на \'\'Apple Mac\'\' машини); \'\'\'IE:\'\'\' држите \'\'Ctrl\'\' док кликћете \'\'Refresh\'\' или притисните \'\'Ctrl-F5\'\'; \'\'\'Konqueror:\'\'\': само кликните \'\'Reload\'\' дугме или притисните \'\'F5\'\'; корисници \'\'\'Оpera\'\'\' браузера можда морају да у потпуности очисте свој кеш преко \'\'Tools→Preferences\'\'.',
+'usercssjsyoucanpreview' => '<strong>Савет:</strong> Кориситите \'Прикажи претпреглед\' дугме да тестирате свој нови CSS/JS пре снимања.',
+'usercsspreview' => '\'\'\'Запамтите ово је само претпреглед вашег CSS и да још увек није снимљен!\'\'\'',
+'userjspreview' => '\'\'\'Запамтите ово је само претпреглед ваше JavaScript-е и да још увек није снимљен!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Пажња:\'\'\' Не постоји кожа "$1". Запамтите да личне .css и .js користе мала почетна слова, нпр. Корисник:Петар/monobook.css а не Корисник:Петар/Monobook.css.',
+'updated' => '(Ажурирано)',
+'note' => '<strong>Напомена:</strong>',
+'previewnote' => '<strong>Ово само претпреглед; измене још нису сачуване!</strong>',
+'session_fail_preview' => '<strong>Жао нам је! Нисмо могли да обрадимо вашу измену због губитка података сеансе. Молимо покушајте касније. Ако и даље не ради, покушајте да се одјавите и поново пријавите.</strong>',
+'previewconflict' => 'Овај претпреглед осликава како ће текст у
+текстуалном пољу изгледати ако се одлучите да га снимите.',
+'session_fail_preview_html' => '<strong>Жао нам је! Нисмо могли да обрадимо вашу измену због губитка података сеансе.</strong>
+
+\'\'Због тога што ова вики има омогућен сиров HTML, претпреглед је сакривен као предострожност против JavaScript напада.\'\'
+
+<strong>Ако сте покушали да направите праву измену, молимо покушајте поново. Ако и даље не ради, покушајте да се одјавите и поново пријавите.</strong>',
+'importing' => 'Увоз у току: $1',
+'editing' => 'Уређујете $1',
+'editinguser' => 'Уређујете $1',
+'editingsection' => 'Уређујете $1 (део)',
+'editingcomment' => 'Уређујете $1 (коментар)',
+'editconflict' => 'Сукобљене измене: $1',
+'explainconflict' => 'Неко други је променио ову страницу откад сте ви почели да је мењате.
+Горње текстуално поље садржи текст странице какав тренутно постоји.
+Ваше измене су приказане у доњем тексту.
+Мораћете да унесете своје промене у постојећи текст.
+<b>Само</b> текст у горњем текстуалном пољу ће бити снимљен када
+притиснете "Сними страницу".<br />',
+'yourtext' => 'Ваш текст',
+'storedversion' => 'Ускладиштена верзија',
+'nonunicodebrowser' => '<strong>УПОЗОРЕЊЕ: Ваш браузер не подржава уникод. Молимо промените га пре него што почнете са уређивањем чланка.</strong>',
+'editingold' => '<strong>ПАЖЊА: Ви мењате старију ревизију ове странице.
+Ако је снимите, све промене учињене од ове ревизије биће изгубљене.</strong>',
+'yourdiff' => 'Разлике',
+'copyrightwarning' => 'Напомена: За све ваше доприносе се сматра да су издати под $2 (видите $1 за детаље). Ако не желите да се ваши доприноси немилосрдно мењају, не шаљите их овде.<br />
+Такође нам обећавате да сте ово сами написали или прекопирали из извора у јавном власништву или сличног слободног извора.
+<strong>НЕ ШАЉИТЕ РАДОВЕ ЗАШТИЋЕНЕ АУТОРСКИМ ПРАВИМА БЕЗ ДОЗВОЛЕ!</strong>',
+'copyrightwarning2' => 'Напомена: Све ваше доприносе остали корисници могу да мењају или уклоне. Ако не желите да се ваши доприноси немилосрдно мењају, не шаљите их овде.<br />
+Такође нам обећавате да сте ово сами написали или прекопирали из извора у јавном власништву или сличног слободног извора (видите $1 за детаље).
+<strong>НЕ ШАЉИТЕ РАДОВЕ ЗАШТИЋЕНЕ АУТОРСКИМ ПРАВИМА БЕЗ ДОЗВОЛЕ!</strong>',
+'longpagewarning' => '<strong>ПАЖЊА: Ова страница има $1 килобајта; неки браузери имају проблема са уређивањем страна које имају близу или више од 32 килобајта. Молимо вас да размотрите разбијање странице на мање делове.</strong>',
+'longpageerror' => '<strong>ГРЕШКА: Текст који снимате је велик $1 килобајта, што је веће од максимално дозвољене величине која износи $2 килобајта. Немогуће је снимити страницу.</strong>',
+'readonlywarning' => '<strong>ПАЖЊА: База је управо закључана због одржавања,
+тако да сада нећете моћи да снимите своје измене. Можда би било добро да ископирате текст у неки едитор текста и снимите га за касније.</strong>',
+'protectedpagewarning' => '<strong>ПАЖЊА: Ова страница је закључана тако да само корисници са
+администраторским привилегијама могу да је мењају. Уверите се
+да пратите [[{{ns:project}}:Правила о заштити страница|правила о заштити страница]].',
+'semiprotectedpagewarning' => '\'\'\'Напомена:\'\'\' Ова страница је закључана тако да је само регистровани корисници могу уређивати.',
+'templatesused' => 'Шаблони који се користе на овој страници:',
+'edittools' => '<!-- Текст одавде ће бити показан испод формулара за уређивање и слање слика. -->',
+'nocreatetitle' => 'Прављење странице ограничено',
+'nocreatetext' => 'На овом сајту је ограничено прављење нових страница. Можете се вратити и уредити већ постојећу страну или [[Посебно:Userlogin|се пријавити или направити налог]].',
+'cantcreateaccounttitle' => 'Не може да се направи налог',
+'cantcreateaccounttext' => 'Прављење налога са ове ИП адресе (<b>$1</b>) је блокирано.
+Ово је вероватно због учесталог вандализма из ваше школе или Интернет сервис провајдера.',
+
+# History pages
+#
+'revhistory' => 'Историја измена',
+'viewpagelogs' => 'Погледај протоколе за ову страну',
+'nohistory' => 'Не постоји историја измена за ову страницу.',
+'revnotfound' => 'Ревизија није пронађена',
+'revnotfoundtext' => 'Старија ревизија ове странице коју сте затражили није нађена.
+Молимо вас да проверите УРЛ који сте употребили да бисте приступили овој страници.',
+'loadhist' => 'Учитавам историју странице',
+'currentrev' => 'Тренутна ревизија',
+'revisionasof' => 'Ревизија од $1',
+'revision-info' => 'Ревизија од $1; $2',
+'previousrevision' => '← Претходна ревизија',
+'nextrevision' => 'Следећа ревизија →',
+'currentrevisionlink' => 'Тренутна ревизија',
+'cur' => 'трен',
+'next' => 'след',
+'last' => 'посл',
+'orig' => 'ориг',
+'histlegend' => 'Одабирање разлика: одаберите кутијице ревизија за упоређивање и притисните ентер или дугме на дну.<br />
+Објашњење: (трен) = разлика са тренутном верзијом,
+(посл) = разлика са претходном верзијом, М = мала измена',
+'deletedrev' => '[обрисан]',
+'histfirst' => 'Најраније',
+'histlast' => 'Последње',
+'rev-deleted-comment' => '(коментар уклоњен)',
+'rev-deleted-user' => '(корисничко име уклоњено)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Ревизија ове странице је уклоњена из јавних архива.
+Могуће да има више детаља у [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} историји брисања].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Ревизија ове странице је уклоњена из јавних архива.
+Као администратор, можете да је погледате;
+Могуће да има више детаља у [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} историји брисања].
+</div>',
+'rev-delundel' => 'покажи/сакриј',
+
+'history-feed-title' => 'Историја ревизија',
+'history-feed-description' => 'Историја ревизија за ову страну на викију',
+'history-feed-item-nocomment' => '$1, $2', # user at time
+'history-feed-empty' => 'Тражена страница не постоји.
+Могуће да је обрисана из викија или преименована.
+Покушајте [[Посебно:Search|да претражите вики]] за релевантне нове стране.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Обриши/врати ревизију',
+'revdelete-nooldid-title' => 'Нема одабране ревизије',
+'revdelete-nooldid-text' => 'Нисте одабрали жељену ревизију или ревизије како бисте укључили ове функције.',
+'revdelete-selected' => 'Изабрано ревизија од [[:$1]]:',
+'revdelete-text' => 'Обрисане ревизије ће се и даље појављивати на историји странице,
+али ће њихов садржај бити скривен јавности.
+
+Остали администратори на овој Википедији ће и даље имати могућност да виде скривени садржај и моћи ће да га врате поново путем ове исте команде, све уколико нису примењене додатне рестрикције оператора сајта.',
+'revdelete-legend' => 'Постави рестрикције ревизија:',
+'revdelete-hide-text' => 'Сакриј текст ревизије',
+'revdelete-hide-comment' => 'Сакриј опис измене',
+'revdelete-hide-user' => 'Сакриј корисничко име/ИП адресу корисника који је уређивао страницу',
+'revdelete-hide-restricted' => 'Примени ове рестрикције за администраторе исто као и за остале',
+'revdelete-log' => 'Коментар протокола:',
+'revdelete-submit' => 'Примени на изабране ревизије',
+'revdelete-logentry' => 'промењен приказ ревизије за [[$1]]',
+
+# Diffs
+#
+'difference' => '(Разлика између ревизија)',
+'loadingrev' => 'учитавам ревизију за разлику',
+'lineno' => 'Линија $1:',
+'editcurrent' => 'Измени тренутну верзију ове странице',
+'selectnewerversionfordiff' => 'Изабери новију верзију за упоређивање',
+'selectolderversionfordiff' => 'Изабери старију верзију за упоређивање',
+'compareselectedversions' => 'Упореди означене верзије',
+
+# Search results
+#
+'searchresults' => 'Резултати претраге',
+'searchresulttext' => 'За више информација о претраживању сајта {{SITENAME}}, погледајте [[{{ns:project}}:Претраживање|Претраживање сајта {{SITENAME}}]].',
+'searchsubtitle' => 'Тражили сте \'\'\'[[:$1]]\'\'\'',
+'searchsubtitleinvalid' => 'Тражили сте \'\'\'$1\'\'\'',
+'badquery' => 'Лоше обликован упит за претрагу',
+'badquerytext' => 'Нисмо могли да обрадимо ваш упит.
+Ово је вероватно због тога што сте покушали да тражите
+реч краћу од три слова, што тренутно није подржано.
+Такође је могуће да сте погрешно укуцали израз, на
+пример "риба има има крљушти".
+Молимо вас покушајте неким другим упитом.',
+'matchtotals' => 'Упит "$1" је нађен у $2 наслова чланака
+и текст $3 чланака.',
+'noexactmatch' => 'Не постоји страница са насловом "$1". Можете [[$1|направити ову страницу]].',
+'titlematches' => 'Наслов странице одговара',
+'notitlematches' => 'Ниједан наслов странице не одговара',
+'textmatches' => 'Текст странице одговара',
+'notextmatches' => 'Ниједан текст странице не одговара',
+'prevn' => 'претходних $1',
+'nextn' => 'следећих $1',
+'viewprevnext' => 'Погледај ($1) ($2) ($3).',
+'showingresults' => 'Приказујем испод <b>$1</b> резултата почев од #<b>$2</b>.',
+'showingresultsnum' => 'Приказујем испод <b>$3</b> резултате почев од #<b>$2</b>.',
+'nonefound' => '\'\'\'Напомена\'\'\': неуспешне претраге су
+често изазване тражењем честих речи као "је" или "од",
+које нису индексиране, или навођењем више од једног израза за тражење (само странице
+које садрже све изразе који се траже ће се појавити у резултату).',
+'powersearch' => 'Тражи',
+'powersearchtext' => 'Претрага у именским просторима:<br />$1<br />$2 Излистај преусмерења<br />Тражи $3 $9',
+'searchdisabled' => 'Претрага за сајт {{SITENAME}} је онемогућена. У међувремену, можете користити Гугл претрагу. Имајте на уму да индекси Гугла за сајт {{SITENAME}} могу бити застарели.',
+
+'blanknamespace' => '(Главно)',
+
+# Preferences page
+#
+'preferences' => 'Подешавања',
+'mypreferences' => 'Моја подешавања',
+'prefsnologin' => 'Нисте пријављени',
+'prefsnologintext' => 'Морате бити [[{{ns:special}}:Userlogin|пријављени]]
+да бисте подешавали корисничка подешавања.',
+'prefsreset' => 'Враћена су ускладиштена подешавања.',
+'qbsettings' => 'Брза палета',
+'changepassword' => 'Промени лозинку',
+'skin' => 'Кожа',
+'math' => 'Математике',
+'dateformat' => 'Формат датума',
+'datedefault' => 'Није битно',
+'datetime' => 'Датум и време',
+'math_failure' => 'Неуспех при парсирању',
+'math_unknown_error' => 'непозната грешка',
+'math_unknown_function' => 'непозната функција',
+'math_lexing_error' => 'речничка грешка',
+'math_syntax_error' => 'синтаксна грешка',
+'math_image_error' => 'PNG конверзија неуспешна; проверите тачну инсталацију latex-а, dvips-а, gs-а и convert-а',
+'math_bad_tmpdir' => 'Не могу да напишем или направим привремени math директоријум',
+'math_bad_output' => 'Не могу да напишем или направим директоријум за math излаз.',
+'math_notexvc' => 'Недостаје извршно texvc; молимо погледајте math/README да бисте подесили.',
+'prefs-personal' => 'Корисничка подешавања',
+'prefs-rc' => 'Скорашње измене',
+'prefs-watchlist' => 'Списак надгледања',
+'prefs-watchlist-days' => 'Број дана који треба да се види на списку надгледања:',
+'prefs-watchlist-edits' => 'Број измена који треба да се види на проширеном списку надгледања:',
+'prefs-misc' => 'Разно',
+'saveprefs' => 'Сачувај',
+'resetprefs' => 'Врати',
+'oldpassword' => 'Стара лозинка:',
+'newpassword' => 'Нова лозинка:',
+'retypenew' => 'Поново откуцајте нову лозинку:',
+'textboxsize' => 'Величине текстуалног поља',
+'rows' => 'Редова',
+'columns' => 'Колона',
+'searchresultshead' => 'Претрага',
+'resultsperpage' => 'Погодака по страници:',
+'contextlines' => 'Линија по поготку:',
+'contextchars' => 'Карактера контекста по линији:',
+'stubthreshold' => 'Граница за приказивање клица:',
+'recentchangescount' => 'Број наслова у скорашњим изменама:',
+'savedprefs' => 'Ваша подешавања су сачувана.',
+'timezonelegend' => 'Временска зона',
+'timezonetext' => 'Број сати за који се ваше локално време разликује од серверског времена (UTC).',
+'localtime' => 'Локално време',
+'timezoneoffset' => 'Одступање¹',
+'servertime' => 'Време на серверу',
+'guesstimezone' => 'Попуни из браузера',
+'allowemail' => 'Омогући е-пошту од других корисника',
+'defaultns' => 'По стандарду тражи у овим именским просторима:',
+'default' => 'стандард',
+'files' => 'Фајлови',
+
+# User rights
+'userrights-lookup-user' => 'Управљај корисничким групама',
+'userrights-user-editname' => 'Унесите корисничко име:',
+'editusergroup' => 'Мењај групе корисника',
+
+'userrights-editusergroup' => 'Промени корисничке групе',
+'saveusergroups' => 'Сачувај корисничке групе',
+'userrights-groupsmember' => 'Члан:',
+'userrights-groupsavailable' => 'Доступне групе:',
+'userrights-groupshelp' => 'Одабране групе од којих желите да се уклони корисник или да се дода.
+Неодабране групе неће бити промењене. Можете да деселектујете групу користећи CTRL + леви клик',
+
+# Groups
+'group' => 'Група:',
+'group-bot' => 'ботови',
+'group-sysop' => 'администратори',
+'group-bureaucrat' => 'бирократе',
+'group-all' => '(сви)',
+
+'group-bot-member' => 'бот',
+'group-sysop-member' => 'администратор',
+'group-bureaucrat-member' => 'бирократа',
+
+'grouppage-bot' => 'Project:Ботови',
+'grouppage-sysop' => 'Project:Списак администратора',
+'grouppage-bureaucrat' => 'Project:Бирократе',
+
+# Recent changes
+#
+'changes' => 'измене',
+'recentchanges' => 'Скорашње измене',
+'recentchangestext' => 'Овде пратите најскорије измене на викију.',
+
+'rcnote' => 'Испод је последњих <strong>$1</strong> промена у последњих <strong>$2</strong> дана.',
+'rcnotefrom' => 'Испод су промене од <b>$2</b> (до <b>$1</b> приказано).',
+'rclistfrom' => 'Покажи нове промене почев од $1',
+'rcshowhideminor' => '$1 мале измене',
+'rcshowhidebots' => '$1 ботове',
+'rcshowhideliu' => '$1 пријављене кориснике',
+'rcshowhideanons' => '$1 анонимне кориснике',
+'rcshowhidepatr' => '$1 патролиране измене',
+'rcshowhidemine' => '$1 сопствене измене',
+'rclinks' => 'Покажи последњих $1 промена у последњих $2 дана<br />$3',
+'diff' => 'разл',
+'hist' => 'ист',
+'hide' => 'сакриј',
+'show' => 'покажи',
+'minoreditletter' => 'м',
+'newpageletter' => 'Н',
+'boteditletter' => 'б',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 корисник/а који надгледа/ју]',
+'rc_categories' => 'Ограничи на категорије (раздвоји са "|")',
+'rc_categories_any' => 'Било који',
+
+# Upload
+#
+'upload' => 'Пошаљи фајл',
+'uploadbtn' => 'Пошаљи фајл',
+'reupload' => 'Поново пошаљи',
+'reuploaddesc' => 'Врати се на упитник за слање.',
+'uploadnologin' => 'Нисте пријављени',
+'uploadnologintext' => 'Морате бити [[{{ns:special}}:Userlogin|пријављени]]
+да бисте слали фајлове.',
+'upload_directory_read_only' => 'На директоријум за слање ($1) сервер не може да пише.',
+'uploaderror' => 'Грешка при слању',
+'uploadtext' => 'Користите доњи образац да пошаљете фајлове. За гледање или претраживање већ послатих слика, идите на [[{{ns:special}}:Imagelist|списак послатих фајлова]]. Слања и брисања се бележе у [[{{ns:special}}:Log/upload|историји слања]]
+
+Да бисте убацили слику на страну, користите везу у облику
+\'\'\'<nowiki>[[{{ns:image}}:Фајл.jpg]]</nowiki>\'\'\',
+\'\'\'<nowiki>[[{{ns:image}}:Фајл.png|опис слике]]</nowiki>\'\'\' или
+\'\'\'<nowiki>[[{{ns:media}}:Фајл.ogg]]</nowiki>\'\'\' за директно повезивање на фајл.',
+'uploadlog' => 'историја слања',
+'uploadlogpage' => 'историја слања',
+'uploadlogpagetext' => 'Испод је списак најскоријих слања.',
+'filename' => 'Име фајла',
+'filedesc' => 'Опис',
+'fileuploadsummary' => 'Опис:',
+'filestatus' => 'Статус ауторског права',
+'filesource' => 'Извор',
+'copyrightpage' => 'Project:Ауторска права',
+'copyrightpagename' => 'Ауторска права пројекта {{SITENAME}}',
+'uploadedfiles' => 'Послати фајлови',
+'ignorewarning' => 'Игнориши упозорења и сними датотеку.',
+'ignorewarnings' => 'Игнориши сва упозорења',
+'minlength' => 'Имена слика морају имати бар три слова.',
+'illegalfilename' => 'Фајл "$1" садржи карактере који нису дозвољени у називима страница. Молимо Вас промените име фајла и поново га пошаљите.',
+'badfilename' => 'Име слике је промењено у "$1".',
+'badfiletype' => '".$1" није препоручени формат слике.',
+'largefile' => 'Препоручује се да слике не пређу величину од $1 бајтова; ова слика има $2 бајтова.',
+'largefileserver' => 'Овај фајл је већи него што је подешено да сервер дозволи.',
+'emptyfile' => 'Фајл који сте послали делује да је празан. Ово је могуће због грешке у имену фајла. Молимо проверите да ли стварно желите да пошаљете овај фајл.',
+'fileexists' => 'Фајл са овим именом већ постоји. Молимо проверите $1 ако нисте сигурни да ли желите да га промените.',
+'fileexists-forbidden' => 'Фајл са овим именом већ постоји; молимо вратите се и пошаљите овај фајл под новим именом. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Фајл са овим именом већ постоји у заједничкој остави; молимо вратите се и пошаљите овај фајл под новим именом. [[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'Успешно слање',
+'fileuploaded' => 'Фајл "$1" је успешно послат.
+Молим пратите ову везу: $2 до странице за опис и унесите
+информације о фајлу, нпр. одакле је, када и
+ко га је направио, и било шта друго што знате о њему.
+Ако је ово слика, можете је унети овако: <tt><nowiki>[[Image:$1|thumb|Опис]]</nowiki></tt>',
+'uploadwarning' => 'Упозорење при слању',
+'savefile' => 'Сними фајл',
+'uploadedimage' => 'послао "[[$1]]"',
+'uploaddisabled' => 'Слање фајлова је искључено.',
+'uploaddisabledtext' => 'Слања фајлова су онемогућена на овом викију.',
+'uploadscripted' => 'Овај фајл садржи ХТМЛ или код скрипте које интернет браузер може погрешно да интерпретира.',
+'uploadcorrupt' => 'Фајл је неисправан или има нетачну екстензију. Молимо проверите фајл и пошаљите га поново.',
+'uploadvirus' => 'Фајл садржи вирус! Детаљи: $1',
+'sourcefilename' => 'Име фајла извора',
+'destfilename' => 'Циљано име фајла',
+'watchthisupload' => 'Надгледај страницу',
+'filewasdeleted' => 'Фајл са овим именом је раније послат, а касније обрисан. Требало би да проверите $1 пре него што наставите са поновним слањем.',
+
+'upload-proto-error' => 'Некоректни протокол',
+'upload-proto-error-text' => 'Слање екстерних фајлова захтева УРЛове који почињу са <code>http://</code> или <code>ftp://</code>.',
+'upload-file-error' => 'Интерна грешка',
+'upload-file-error-text' => 'Десила се интерна грешка при покушају прављења привременог фајла на серверу. Контактирајте систем администратора.',
+'upload-misc-error' => 'Непозната грешка при слању фајла',
+'upload-misc-error-text' => 'Непозната грешка при слању фајла. Проверите да ли је УРЛ исправан и покушајте поново. Ако проблем остане, контактирајте систем администратора.',
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => "УРЛ није доступан",
+'upload-curl-error6-text' => 'УРЛ који сте унели није доступан. Урадите дупли клик на УРЛ да проверите да ли је адреса доступна.',
+'upload-curl-error28' => 'Тајмаут грешка',
+'upload-curl-error28-text' => 'Сајту је требало превише времена да одговори. Проверите да ли сајт ради, или сачекајте мало и покушајте поново.',
+
+'license' => 'Лиценца',
+'nolicense' => 'Нема',
+'upload_source_url' => ' (валидан, јавно доступан УРЛ)',
+'upload_source_file' => ' (фајл на вашем рачунару)',
+
+# Image list
+#
+'imagelist' => 'Списак слика',
+'imagelisttext' => 'Испод је списак од \'\'\'$1\'\'\' {{plural:$1|фајла|фајла|фајлова}} поређаних $2.',
+'imagelistforuser' => 'Ово је списак слика које је послао корисник $1.',
+'getimagelist' => 'прибављам списак слика',
+'ilsubmit' => 'Тражи',
+'showlast' => 'Прикажи последњих $1 слика поређаних $2.',
+'bydate' => 'по датуму',
+'byname' => 'по имену',
+'bysize' => 'по величини',
+'imgdelete' => 'обр',
+'imgdesc' => 'опис',
+'imgfile' => 'фајл',
+'imghistory' => 'историја слике',
+'imglegend' => 'Објашњење: (опис) = прикажи/измени опис слике.',
+'revertimg' => 'врт',
+'deleteimg' => 'обр',
+'deleteimgcompletely' => 'Обриши све ревизије овог фајла',
+'imghistlegend' => 'Објашњење: (трен) = ово је тренутна слика, (обр) = обриши
+ову стару верзију, (врт) = врати на ову стару верзију.
+<br /><i>Кликните на датум да видите слику послату тог датума</i>.',
+'imagelinks' => 'Употреба слике',
+'linkstoimage' => 'Следеће странице користе овај фајл:',
+'nolinkstoimage' => 'Нема страница које користе овај фајл.',
+'sharedupload' => 'Ова слика је са заједничке оставе и можда је користе остали пројекти.',
+'shareduploadwiki' => 'Молимо погледајте $1 за даље информације.',
+'shareduploadwiki-linktext' => 'страна за опис фајла',
+'noimage' => 'Не постоји фајл са овим именом, можете га $1',
+'noimage-linktext' => 'послати',
+'uploadnewversion-linktext' => 'Пошаљите новију верзију овог фајла',
+'imagelist_date' => 'Датум',
+'imagelist_name' => 'Име',
+'imagelist_user' => 'Корисник',
+'imagelist_size' => 'Величина (бајтови)',
+'imagelist_description' => 'Опис слике',
+'imagelist_search_for' => 'Тражи име слике:',
+
+# Mime search
+#
+'mimesearch' => 'МИМЕ претрага',
+'mimetype' => 'МИМЕ тип:',
+'download' => 'Преузми',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Ненадгледане странице',
+
+# List redirects
+'listredirects' => 'Списак преусмерења',
+
+# Unused templates
+'unusedtemplates' => 'Неискоришћени шаблони',
+'unusedtemplatestext' => 'Ова страна наводи све странице у именском простору шаблона које нису укључене ни на једној другој страни. Не заборавите да проверите остале везе ка шаблонима пре него што их обришете.',
+'unusedtemplateswlh' => 'остале везе',
+
+# Random redirect
+'randomredirect' => 'Случајно преусмерење',
+
+# Statistics
+#
+'statistics' => 'Статистике',
+'sitestats' => 'Статистике сајта',
+'userstats' => 'Статистике корисника',
+'sitestatstext' => 'Постоји укупно \'\'\'$1\'\'\' страница у бази података. Овај број укључује стране за разговор, странице о сајту, преусмерења, чланке без иједне повезнице и остале странице које се не могу рачунати као чланци. Не рачунајући њих, постоји \'\'\'$2\'\'\' страница које су вероватно легитимни чланци.
+
+На овај сајт је послато \'\'\'$8\'\'\' слика.
+
+Странице су укупно погледане \'\'\'$3\'\'\' пута и \'\'\'$4\'\'\' измена од постављања викија. Ово значи да је било у просеку \'\'\'$5\'\'\' измена по страници и \'\'\'$6\'\'\' погледа по страници.
+
+Дужина реда за послове износи \'\'\'$7\'\'\'',
+'userstatstext' => 'Постоји \'\'\'$1\'\'\' регистрованих корисника, од којих су \'\'\'$2\'\'\' (или $4%) администратори (погледајте $3).',
+'statistics-mostpopular' => 'Најпосећеније странице',
+
+'disambiguations' => 'Странице за вишезначне одреднице',
+'disambiguationspage' => '{{ns:template}}:Вишезначна одредница',
+'disambiguationstext' => 'Следећи чланци се повезују са <i>вишезначном одредницом</i>. Уместо тога, они би требало да се повезују са одговарајућом темом.<br />Страница се третира да је вишезначна одредница ако је повезана са $1.<br />Повезнице из осталих именских простора <i>нису</i> наведене овде.',
+
+'doubleredirects' => 'Двострука преусмерења',
+'doubleredirectstext' => 'Сваки ред садржи везе на прво и друго преусмерење, као и на прву линију текста другог преусмерења, што обично даје "прави" циљни чланак, на који би прво преусмерење и требало да показује.',
+
+'brokenredirects' => 'Покварена преусмерења',
+'brokenredirectstext' => 'Следећа преусмерења су повезана на непостојећи чланак.',
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|бајт|бајта|бајтова}}',
+'ncategories' => '$1 {{PLURAL:$1|категорија|категорије|категорија}}',
+'nlinks' => '$1 {{PLURAL:$1|веза|везе|веза}}',
+'nmembers' => '$1 {{PLURAL:$1|чланак|чланка|чланака}}',
+'nrevisions' => '$1 {{PLURAL:$1|ревизија|ревизије|ревизија}}',
+'nviews' => '$1 пута погледано',
+
+'lonelypages' => 'Сирочићи',
+'lonelypagestext' => 'Следеће странице нису повезане са других страница на овом викију.',
+'uncategorizedpages' => 'Странице без категорије',
+'uncategorizedcategories' => 'Категорије без категорија',
+'uncategorizedimages' => 'Слике без категорија',
+'unusedcategories' => 'Неискоришћене категорије',
+'unusedimages' => 'Неискоришћени фајлови',
+'popularpages' => 'Популарне странице',
+'wantedcategories' => 'Тражене категорије',
+'wantedpages' => 'Тражене странице',
+'mostlinked' => 'Највише повезане стране',
+'mostlinkedcategories' => 'Највише повезане категорије',
+'mostcategories' => 'Чланци са највише категорија',
+'mostimages' => 'Највише повезане слике',
+'mostrevisions' => 'Чланци са највише ревизија',
+'allpages' => 'Све странице',
+'prefixindex' => 'Списак префикса',
+'randompage' => 'Случајна страница',
+'shortpages' => 'Кратке странице',
+'longpages' => 'Дугачке странице',
+'deadendpages' => 'Странице без интерних веза',
+'deadendpagestext' => 'Следеће странице не вежу на друге странице на овом викију.',
+'listusers' => 'Списак корисника',
+'specialpages' => 'Посебне странице',
+'spheading' => 'Посебне странице за све кориснике',
+'restrictedpheading' => 'Заштићене посебне странице',
+'recentchangeslinked' => 'Сродне промене',
+'rclsub' => '(на странице повезане од "$1")',
+'newpages' => 'Нове странице',
+'newpages-username' => 'Корисничко име:',
+'ancientpages' => 'Најстарији чланци',
+'intl' => 'Међујезичке везе',
+'move' => 'премести',
+'movethispage' => 'премести ову страницу',
+'unusedimagestext' => '<p>Обратите пажњу да се други веб сајтови
+могу повезивати на слику директним УРЛ-ом, и тако могу још увек бити приказани овде упркос
+активној употреби.',
+'unusedcategoriestext' => 'Наредне стране категорија постоје иако их ни један други чланак или категорија не користе.',
+
+'booksources' => 'Штампани извори',
+'categoriespagetext' => 'Следеће категорије већ постоје на викију',
+'data' => 'Подаци',
+'userrights' => 'Управљање корисничким правима',
+'groups' => 'Корисничке групе',
+
+'booksourcetext' => 'Испод је списак веза ка другим сајтовима који
+продају нове и коришћене књиге, и такође могу имати даљње информације
+о књигама које тражите.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 у $2',
+'version' => 'Верзија',
+'log' => 'Протоколи',
+'alllogstext' => 'Комбиновани приказ историја слања, брисања, заштите, блокирања и администраторских права.
+Можете сузити преглед одабиром типа историје, корисничког имена или тражене странице.',
+'logempty' => 'Протокол је празан.',
+
+# Special:Allpages
+'nextpage' => 'Следећа страница ($1)',
+'allpagesfrom' => 'Прикажи странице почетно са:',
+'allarticles' => 'Сви чланци',
+'allinnamespace' => 'Све странице ($1 именски простор)',
+'allnotinnamespace' => 'Све странице (које нису у $1 именском простору)',
+'allpagesprev' => 'Претходна',
+'allpagesnext' => 'Следећа',
+'allpagessubmit' => 'Иди',
+'allpagesprefix' => 'Прикажи стране са префиксом:',
+'allpagesbadtitle' => 'Дати назив странице није добар или садржи међујезички или интервики префикс. Могуће је да садржи карактере који не могу да се користе у називима.',
+
+# Special:Listusers
+'listusersfrom' => 'Прикажи кориснике почевши од:',
+
+# Email this user
+#
+'mailnologin' => 'Нема адресе за слање',
+'mailnologintext' => 'Морате бити [[{{ns:special}}:Userlogin|пријављени]]
+и имати исправну адресу е-поште у вашим [[Special:Preferences|подешавањима]]
+да бисте слали е-пошту другим корисницима.',
+'emailuser' => 'Пошаљи е-пошту овом кориснику',
+'emailpage' => 'Пошаљи е-писмо кориснику',
+'emailpagetext' => 'Ако је овај корисник унео исправну адресу е-поште у
+своја корисничка подешавања, упитник испод ће послати једну поруку.
+Адреса е-поште коју сте ви унели у својим корисничким подешавањима ће се појавити
+као "From" адреса поруке, тако да ће прималац моћи да одговори.',
+'usermailererror' => 'Објекат поште је вратио грешку:',
+'defemailsubject' => '{{SITENAME}} е-пошта',
+'noemailtitle' => 'Нема адресе е-поште',
+'noemailtext' => 'Овај корисник није навео исправну адресу е-поште,
+или је изабрао да не прима е-пошту од других корисника.',
+'emailfrom' => 'Од',
+'emailto' => 'За',
+'emailsubject' => 'Тема',
+'emailmessage' => 'Порука',
+'emailsend' => 'Пошаљи',
+'emailccme' => 'Пошаљи ми копију моје поруке у моје сандуче е-поште.',
+'emailccsubject' => 'Копија ваше поруке на $1: $2',
+'emailsent' => 'Порука послата',
+'emailsenttext' => 'Ваша порука је послата електронском поштом.',
+
+# Watchlist
+'watchlist' => 'Мој списак надгледања',
+'watchlistfor' => '(за \'\'\'$1\'\'\')',
+'nowatchlist' => 'Немате ништа на свом списку надгледања.',
+'watchlistanontext' => 'Молимо $1 да бисте гледали или мењали ставке на вашем списку надгледања.',
+'watchlistcount' => '\'\'\'Имате $1 {{plural:$1|ставку|ставке|ставки}} на вашем списку надгледања, укључујући стране за разговор.\'\'\'',
+'clearwatchlist' => 'Обриши списак надгледања',
+'watchlistcleartext' => 'Да ли сте сигурни да желите да их уклоните?',
+'watchlistclearbutton' => 'Обриши списак надгледања',
+'watchlistcleardone' => 'Ваш списак надгледања је обрисан. $1 {{plural:$1|ставка|ставке|ставки}} је уклоњено.',
+'watchnologin' => 'Нисте пријављени',
+'watchnologintext' => 'Морате бити [[{{ns:special}}:Userlogin|пријављени]] да бисте мењали списак надгледања.',
+'addedwatch' => 'Додато списку надгледања',
+'addedwatchtext' => 'Страница "[[:$1]]" је додата вашем [[{{ns:special}}:Watchlist|списку надгледања]] .
+Будуће промене на овој страници и њој придруженој страници за разговор биће наведене овде, и страница ће бити \'\'\'подебљана\'\'\' у [[{{ns:special}}:Recentchanges|списку скорашњих измена]] да би се лакше уочила.
+
+Ако касније желите да уклоните страницу са вашег списка надгледања, кликните на "не надгледај" на бочној палети.',
+'removedwatch' => 'Уклоњено са списка надгледања',
+'removedwatchtext' => 'Страница "[[:$1]]" је уклоњена са вашег списка надгледања.',
+'watch' => 'надгледај',
+'watchthispage' => 'Надгледај ову страницу',
+'unwatch' => 'Прекини надгледање',
+'unwatchthispage' => 'Прекини надгледање',
+'notanarticle' => 'Није чланак',
+'watchnochange' => 'Ништа што надгледате није промењено у приказаном времену.',
+'watchdetails' => '* $1 страница надгледано не рачунајући странице за разговор;
+* [[{{ns:special}}:Watchlist/edit|прикажи и мењај потпуни списак]]
+* [[{{ns:special}}:Watchlist/clear|уклони све странице]]',
+'wlheader-enotif' => '* Обавештавање е-поштом је омогућено.',
+'wlheader-showupdated' => '* Странице које су измењене од када сте их последњи пут посетили су приказане \'\'\'подебљано\'\'\'',
+'watchmethod-list' => 'проверавам има ли скорашњих измена у надгледаним страницама',
+'watchmethod-recent' => 'проверавам има ли надгледаних страница у скорашњим изменама',
+'removechecked' => 'Уклони обележене уносе са списка надгледања',
+'watchlistcontains' => 'Ваш списак надгледања садржи $1 страница.',
+'watcheditlist' => 'Овде је азбучни списак страница
+које надгледате. Обележите кућице страница које желите да уклоните
+са свог списка надгледања и кликните на дугме \'уклони обележене\'
+на дну екрана (уклањање странице такође уклања и пратећу страну за разговор и обрнуто).',
+'removingchecked' => 'Уклањам обележене ствари са списка надгледања...',
+'couldntremove' => 'Не могу да уклоним ставку \'$1\'...',
+'iteminvalidname' => 'Проблем са ставком \'$1\', неисправно име...',
+'wlnote' => 'Испод је последњих $1 измена у последњих <b>$2</b> сати.',
+'wlshowlast' => 'Прикажи последњих $1 сати $2 дана $3',
+'wlsaved' => 'Ово је сачувана верзија вашег списка надгледања.',
+'wlhideshowown' => '$1 мојe изменe.',
+'wlhideshowbots' => '$1 измена ботова.',
+'wldone' => 'Готово.',
+
+'enotif_mailer' => '{{SITENAME}} пошта обавештења',
+'enotif_reset' => 'Означи све стране као посећене',
+'enotif_newpagetext' => 'Ово је нови чланак.',
+'changed' => 'промењена',
+'created' => 'направљена',
+'enotif_subject' => '{{SITENAME}} страница $PAGETITLE је била $CHANGEDORCREATED од стране $PAGEEDITOR',
+'enotif_lastvisited' => 'Погледајте $1 за све промене од ваше последње посете.',
+'enotif_body' => 'Драги $WATCHINGUSERNAME,
+
+{{SITENAME}} страницаа $PAGETITLE је била $CHANGEDORCREATED ($PAGEEDITDATE) од стране $PAGEEDITOR,
+погледајте $PAGETITLE_URL за тренутну верзију.
+
+$NEWPAGE
+
+Опис измене уредника: $PAGESUMMARY $PAGEMINOREDIT
+
+Контактирајте уредника:
+пошта: $PAGEEDITOR_EMAIL
+вики: $PAGEEDITOR_WIKI
+
+Неће бити других обавештења у случају даљих промена уколико не посетите ову страну.
+Такође можете да ресетујете заставице за обавештења за све ваше надгледане стране на вашем списку надгледања.
+
+ Ваш пријатељски {{SITENAME}} систем обавештавања
+
+--
+Да промените подешавања везана за списак надгледања посетите
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Фидбек и даља помоћ:
+{{fullurl:{{ns:help}}:Садржај}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Обриши страницу',
+'confirm' => 'Потврди',
+'excontent' => 'садржај је био: \'$1\'',
+'excontentauthor' => 'садржај је био: \'$1\' (а једину измену је направио \'$2\')',
+'exbeforeblank' => 'садржај пре брисања је био: \'$1\'',
+'exblank' => 'страница је била празна',
+'confirmdelete' => 'Потврди брисање',
+'deletesub' => '(Бришем "$1")',
+'historywarning' => 'Пажња: страница коју желите да обришете има историју:',
+'confirmdeletetext' => 'На путу сте да трајно обришете страницу
+или слику заједно са њеном историјом из базе података.
+Молимо вас потврдите да намеравате да урадите ово, да разумете
+последице, и да ово радите у складу са
+[[{{ns:project}}:Правила и смернице|правилима]].',
+'actioncomplete' => 'Акција завршена',
+'deletedtext' => 'Чланак "$1" је обрисан.
+Погледајте $2 за запис о скорашњим брисањима.',
+'deletedarticle' => 'обрисан "[[$1]]"',
+'dellogpage' => 'историја брисања',
+'dellogpagetext' => 'Испод је списак најскоријих брисања.',
+'deletionlog' => 'историја брисања',
+'reverted' => 'Враћено на ранију ревизију',
+'deletecomment' => 'Разлог за брисање',
+'imagereverted' => 'Враћање на ранију верзију је успешно.',
+'rollback' => 'Врати измене',
+'rollback_short' => 'Врати',
+'rollbacklink' => 'врати',
+'rollbackfailed' => 'Враћање није успело',
+'cantrollback' => 'Не могу да вратим измену; последњи аутор је уједно и једини.',
+'alreadyrolled' => 'Не могу да вратим последњу измену [[:$1]]
+од корисника [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|разговор]]); неко други је већ изменио или вратио чланак.
+
+Последњу измену је направио корисник [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|разговор]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Коментар измене је: "<i>$1</i>".',
+'revertpage' => 'Враћене измене од [[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|разговор]]) на последњу измену од корисника [[{{ns:user}}:$1|$1]]',
+'sessionfailure' => 'Изгледа да постоји проблем са вашом сеансом пријаве;
+ова акција је прекинута као предострожност против преотимања сеанси.
+Молимо кликните "back" и поново учитајте страну одакле сте дошли, а онда покушајте поново.',
+'protectlogpage' => 'историја закључавања',
+'protectlogtext' => 'Испод је списак закључавања и откључавања страница.',
+'protectedarticle' => 'заштитио $1',
+'unprotectedarticle' => 'скинуо заштиту са $1',
+'protectsub' => '(стављање заштите "$1")',
+'confirmprotecttext' => 'Да ли заиста желите да заштитите ову страницу?',
+'confirmprotect' => 'Потврдите заштиту',
+'protectmoveonly' => 'Заштићено само од померања',
+'protectcomment' => 'Разлог заштите',
+'unprotectsub' => '(скидање заштите "$1")',
+'confirmunprotecttext' => 'Да ли заиста желите да скинете заштиту са ове странице?',
+'confirmunprotect' => 'Потврдите скидање заштите',
+'unprotectcomment' => 'Разлог за скидање заштите',
+'protect-unchain' => 'Откључај дозволе премештања',
+'protect-text' => 'Овде можете погледати и мењати ниво заштите за страницу <strong>$1</strong>.',
+'protect-viewtext' => 'Ваш налог нема приступ изменама
+нивоа заштите. Ово су тренутна подешавања за страницу <strong>$1</strong>:',
+'protect-default' => '(стандард)',
+'protect-level-autoconfirmed' => 'Блокирај нерегистроване кориснике',
+'protect-level-sysop' => 'Само за администраторе',
+
+# restrictions (nouns)
+'restriction-edit' => 'Уређивање',
+'restriction-move' => 'Премештање',
+
+# Undelete
+'undelete' => 'Погледај обрисане странице',
+'undeletepage' => 'Погледај и врати обрисане странице',
+'viewdeletedpage' => 'Погледај обрисане стране',
+'undeletepagetext' => 'Следеће странице су обрисане али су још увек у архиви и
+могу бити враћене. Архива може бити периодично чишћена.',
+'undeleteextrahelp' => 'Да вратите целу страну, оставите све кућице неоткаченим и кликните на \'\'\'\'\'Врати\'\'\'\'\'. Да извршите селективно враћање, откачите кућице које одговарају ревизији која треба да се врати и кликните на \'\'\'\'\'Врати\'\'\'\'\'. Кликом на \'\'\'\'\'Поништи\'\'\'\'\' ћете обрисати поље за коментар и све кућице.',
+'undeletearticle' => 'Врати обрисани чланак',
+'undeleterevisions' => '$1 ревизија архивирано',
+'undeletehistory' => 'Ако вратите страницу, све ревизије ће бити враћене њеној историји.
+Ако је нова страница истог имена направљена од брисања, враћене
+ревизије ће се појавити у ранијој историји, а тренутна ревизија садашње странице
+неће бити аутоматски замењена.',
+'undeletehistorynoadmin' => 'Ова страна је обрисана. Разлог за брисање се налази у опису испод, заједно са детаљима о кориснику који је мењао ову страну пре брисања. Стварни текст ових обрисаних ревизија је доступан само администраторима.',
+'undeleterevision' => 'Обрисана ревизија од $1',
+'undeleterevision-missing' => 'Некоректна или непостојећа ревизија. Можда је ваш линк погрешан, или је ревизија рестаурирана, или обрисана из архиве.',
+'undeletebtn' => 'Врати!',
+'undeletereset' => 'Поништи',
+'undeletecomment' => 'Коментар:',
+'undeletedarticle' => 'вратио "[[$1]]"',
+'undeletedrevisions' => '$1 ревизија враћено',
+'undeletedrevisions-files' => '$1 {{plural:$1|ревизија|ревизије|ревизија}} и $2 {{plural:$2|фајл|фајла|фајлова}} враћено',
+'undeletedfiles' => '$1 {{plural:$1|фајл враћен|фајла враћена|фајлова враћено}}',
+'cannotundelete' => 'Враћање обрисане верзије није успело; неко други је вратио страницу пре вас.',
+'undeletedpage' => '<big>\'\'\'Страна $1 је враћена\'\'\'</big>
+
+Погледајте [[{{ns:special}}:Log/delete|историју брисања]] за списак скорашњих брисања и враћања.',
+
+# Namespace form on various pages
+'namespace' => 'Именски простор:',
+'invert' => 'Обрни селекцију',
+
+# Contributions
+#
+'contributions' => 'Прилози корисника',
+'mycontris' => 'Моји прилози',
+'contribsub' => 'За $1',
+'nocontribs' => 'Нису нађене промене које задовољавају ове услове.',
+'ucnote' => 'Испод је последњих <b>$1</b> промена у последњих <b>$2</b> дана.',
+'uclinks' => 'Гледај последњих $1 промена; гледај последњих $2 дана.',
+'uctop' => ' (врх)',
+'newbies' => 'новајлије',
+
+'sp-newimages-showfrom' => 'Прикажи нове слике почевши од $1',
+
+'sp-contributions-newest' => 'Најновијих',
+'sp-contributions-oldest' => 'Најстаријих',
+'sp-contributions-newer' => 'Новијих $1',
+'sp-contributions-older' => 'Старијих $1',
+'sp-contributions-newbies-sub' => 'За новајлије',
+
+# What links here
+#
+'whatlinkshere' => 'Шта је повезано овде',
+'notargettitle' => 'Нема циља',
+'notargettext' => 'Нисте навели циљну страницу или корисника
+на коме би се извела ова функција.',
+'linklistsub' => '(списак веза)',
+'linkshere' => 'Следеће странице су повезане овде:',
+'nolinkshere' => 'Ни једна страница није повезана овде.',
+'isredirect' => 'преусмеривач',
+'istemplate' => 'укључивање',
+
+# Block/unblock IP
+#
+'blockip' => 'Блокирај корисника',
+'blockiptext' => 'Употребите доњи упитник да бисте уклонили право писања
+са одређене ИП адресе или корисничког имена.
+Ово би требало да буде урађено само да би се спречио вандализам, и у складу
+са [[{{ns:project}}:Политика|политиком]].
+Унесите конкретан разлог испод (на пример, наводећи које
+странице су вандализоване).',
+'ipaddress' => 'ИП адреса',
+'ipadressorusername' => 'ИП адреса или корисничко име',
+'ipbexpiry' => 'Трајање',
+'ipbreason' => 'Разлог',
+'ipbanononly' => 'Блокирај само анонимне кориснике',
+'ipbcreateaccount' => 'Спречи прављење налога',
+'ipbenableautoblock' => 'Аутоматски блокирај последњу ИП адресу овог корисника, и сваку следећу адресу са које се покуша уређивање.',
+'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',
+'ipbotheroption' => 'остало',
+'badipaddress' => 'Лоша ИП адреса',
+'blockipsuccesssub' => 'Блокирање је успело',
+'blockipsuccesstext' => '[[{{ns:special}}:Contributions/$1|$1]] је блокиран.
+<br />Видите [[{{ns:special}}:Ipblocklist|списак блокирања]] да бисте прегледали блокирања.',
+'unblockip' => 'Одблокирај корисника',
+'unblockiptext' => 'Употребите доњи упитник да бисте вратили право писања
+раније блокираној ИП адреси или корисничком имену.',
+'ipusubmit' => 'Одблокирај ову адресу',
+'unblocked' => '[[{{ns:user}}:$1|$1]] је одблокиран',
+'ipblocklist' => 'Списак блокираних ИП адреса и корисника',
+'blocklistline' => '$1, $2 блокирао корисника [[{{ns:user}}:$3|$3]], (истиче $4)',
+'infiniteblock' => 'бесконачан',
+'expiringblock' => 'истиче $1',
+'anononlyblock' => 'само анонимни',
+'noautoblockblock' => 'Аутоблокирање је онемогућено',
+'createaccountblock' => 'блокирано прављење налога',
+'ipblocklistempty' => 'Списак блокирања је празан.',
+'blocklink' => 'блокирај',
+'unblocklink' => 'одблокирај',
+'contribslink' => 'прилози',
+'autoblocker' => 'Аутоматски сте блокирани јер је вашу ИП адресу скоро користио "[[{{ns:user}}:$1|$1]]". Разлог за блокирање корисника $1 је: "\'\'\'$2\'\'\'".',
+'blocklogpage' => 'историја блокирања',
+'blocklogentry' => 'је блокирао "[[$1]]" са временом истицања блокаде од $2',
+'blocklogtext' => 'Ово је историја блокирања и одблокирања корисника. Аутоматски
+блокиране ИП адресе нису наведене. Погледајте [[{{ns:special}}:Ipblocklist|списак блокираних ИП адреса]] за списак тренутних забрана и блокирања.',
+'unblocklogentry' => 'одблокирао "$1"',
+'range_block_disabled' => 'Администраторска могућност да блокира блокове ИП адреса је искључена.',
+'ipb_expiry_invalid' => 'Погрешно време трајања.',
+'ipb_already_blocked' => '"$1" је већ блокиран',
+'ip_range_invalid' => 'Нетачан блок ИП адреса.',
+'proxyblocker' => 'Блокер проксија',
+'ipb_cant_unblock' => 'Грешка: ИД блока $1 није нађен. Могуће је да је већ одблокиран.',
+'proxyblockreason' => 'Ваша ИП адреса је блокирана јер је она отворени прокси. Молимо контактирајте вашег Интернет сервис провајдера или техничку подршку и обавестите их о овом озбиљном сигурносном проблему.',
+'proxyblocksuccess' => 'Урађено.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Ваша ИП адреса је на списку као отворен прокси на [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Ваша ИП адреса се налази на списку као отворени прокси на [http://www.sorbs.net SORBS] DNSBL. Не можете да направите налог',
+
+# Developer tools
+#
+'lockdb' => 'Закључај базу',
+'unlockdb' => 'Откључај базу',
+'lockdbtext' => 'Закључавање базе ће свим корисницима укинути могућност измене страница,
+промене корисничких подешавања, измене списка надгледања, и свега осталог
+што захтева промене у бази.
+Молимо потврдите да је ово заиста оно што намеравате да урадите и да ћете
+откључати базу када завршите посао око њеног одржавања.',
+'unlockdbtext' => 'Откључавање базе ће свим корисницима вратити могућност измене страница,
+промене корисничких подешавања, измене списка надгледања, и свега осталог
+што захтева промене у бази.
+Молимо потврдите да је ово заиста оно што намеравате да урадите.',
+'lockconfirm' => 'Да, заиста желим да закључам базу.',
+'unlockconfirm' => 'Да, заиста желим да откључам базу.',
+'lockbtn' => 'Закључај базу',
+'unlockbtn' => 'Откључај базу',
+'locknoconfirm' => 'Нисте потврдили своју намеру.',
+'lockdbsuccesssub' => 'База је закључана',
+'unlockdbsuccesssub' => 'База је откључана',
+'lockdbsuccesstext' => 'База података је закључана.
+<br />Не заборавите да је [[{{ns:special}}:Unlockdb|откључате]] када завршите са одржавањем.',
+'unlockdbsuccesstext' => 'База података је откључана.',
+'lockfilenotwritable' => 'По фајлу за закључавање базе података не може да се пише. Да бисте закључали или откључали базу, по овом фајлу мора да буде омогућено писање од стране веб сервера.',
+'databasenotlocked' => 'База података није закључана.',
+
+# Make sysop
+'makesysoptitle' => 'Претворите корисника у администратора',
+'makesysoptext' => 'Овај упитник користе бирократе да се обични корисници претворе у администраторе. Унесите име корисника у поље и притисните дугме да би корисник постао администратор',
+'makesysopname' => 'Име корисника:',
+'makesysopsubmit' => 'Додајте овом кориснику администраторска овлашћења',
+'makesysopok' => '<b>Корисник "$1" је сада администратор</b>',
+'makesysopfail' => '<b>Корисник "$1" не може да постане администратор. (Да ли сте правилно унели име?)</b>',
+'setbureaucratflag' => 'Постави права бирократе',
+'rightslog' => 'историја корисничких права',
+'rightslogtext' => 'Ово је историја измена корисничких права.',
+'rightslogentry' => 'је променио права за $1 са $2 на $3',
+'rights' => 'Права:',
+'set_user_rights' => 'Постави права корисника',
+'user_rights_set' => '<b>Права за корисника "$1" промењена</b>',
+'set_rights_fail' => '<b>Корисничка права за "$1" нису могла да се подесе. (Да ли сте правилно унели име?)</b>',
+'makesysop' => 'Давање администраторских овлашћења кориснику',
+'already_sysop' => 'Овај корисник је већ администратор',
+'already_bureaucrat' => 'Овај корисник је већ бирократа',
+'rightsnone' => '(нема)',
+
+# Move page
+#
+'movepage' => 'Премештање странице',
+'movepagetext' => 'Доњи упитник ће преименовати страницу, премештајући сву
+њену историју на ново име.
+Стари наслов ће постати преусмерење на нови наслов.
+Везе ка старом наслову неће бити промењене; обавезно
+потражите [[{{ns:special}}:DoubleRedirects|двострука]] или [[{{ns:special}}:BrokenRedirects|покварена преусмерења]].
+На вама је одговорност да везе и даље иду тамо где би и требало да иду.
+
+Обратите пажњу да страница \'\'\'неће\'\'\' бити померена ако већ постоји
+страница са новим насловом, осим ако је она празна или преусмерење и нема
+историју промена. Ово значи да не можете преименовати страницу на оно име
+са кога сте је преименовали ако погрешите, и не можете преписати
+постојећу страницу.
+
+<b>ПАЖЊА!</b>
+Ово може бити драстична и неочекивана промена за популарну страницу;
+молимо да будете сигурни да разумете последице овога пре него што
+наставите.',
+'movepagetalktext' => 'Одговарајућа страница за разговор, ако постоји, биће аутоматски премештена истовремено \'\'\'осим ако:\'\'\'
+*Непразна страница за разговор већ постоји под новим именом, или
+*Одбележите доњу кућицу.
+
+У тим случајевима, мораћете ручно да преместите или спојите страницу уколико то желите.',
+'movearticle' => 'Премести страницу',
+'movenologin' => 'Нисте пријављени',
+'movenologintext' => 'Морате бити регистровани корисник и [[Special:Userlogin|пријављени]]
+да бисте преместили страницу.',
+'newtitle' => 'Нови наслов',
+'movepagebtn' => 'премести страницу',
+'pagemovedsub' => 'Премештање успело',
+'pagemovedtext' => 'Страница "[[$1]]" премештена је на "[[$2]]".',
+'articleexists' => 'Страница под тим именом већ постоји, или је
+име које сте изабрали неисправно.
+Молимо изаберите друго име.',
+'talkexists' => '\'\'\'Сама страница је успешно премештена, али
+страница за разговор није могла бити премештена јер таква већ постоји на новом наслову. Молимо вас да их спојите ручно.\'\'\'',
+'movedto' => 'премештена на',
+'movetalk' => 'Премести "страницу за разговор" такође, ако је могуће.',
+'talkpagemoved' => 'Одговарајућа страница за разговор је такође премештена.',
+'talkpagenotmoved' => 'Одговарајућа страница за разговор <strong>није</strong> премештена.',
+'1movedto2' => 'је променио име чланку [[$1]] у [[$2]]',
+'1movedto2_redir' => 'је променио име чланку [[$1]] у [[$2]] путем преусмерења',
+'movelogpage' => 'историја премештања',
+'movelogpagetext' => 'Испод је списак премештања чланака.',
+'movereason' => 'Разлог',
+'revertmove' => 'врати',
+'delete_and_move' => 'Обриши и премести',
+'delete_and_move_text' => '==Потребно брисање==
+
+Циљани чланак "[[$1]]" већ постоји. Да ли желите да га обришете да бисте направили место за премештање?',
+'delete_and_move_confirm' => 'Да, обриши страницу',
+'delete_and_move_reason' => 'Обрисано како би се направило место за премештање',
+'selfmove' => 'Изворни и циљани назив су исти; страна не може да се премести преко саме себе.',
+'immobile_namespace' => 'Циљани назив је посебног типа; не могу да преместе стране у тај именски простор.',
+
+# Export
+
+'export' => 'Извези странице',
+'exporttext' => 'Можете извозити текст и историју промена одређене
+странице или групе страница у XML формату. Ово онда може бити увезено у други
+вики који користи МедијаВики софтвер преко {{ns:special}}:Import странице.
+
+Да бисте извозили странице, унесите називе у текстуалном пољу испод, са једним насловом по реду, и одаберите да ли желите тренутну верзију са свим старим верзијама или само тренутну верзију са информацијама о последњој измени.
+
+У другом случају, можете такође користити везу, нпр. [[{{ns:special}}:Export/{{int:mainpage}}]] за страницу {{int:mainpage}}.',
+'exportcuronly' => 'Укључи само тренутну ревизију, не целу историју',
+'exportnohistory' => '----
+\'\'\'Напомена:\'\'\' извожење пуне историје страна преко овог формулара је онемогућено због серверских разлога.',
+'export-submit' => 'Извоз',
+
+# Namespace 8 related
+
+'allmessages' => 'Системске поруке',
+'allmessagesname' => 'Име',
+'allmessagesdefault' => 'Стандардни текст',
+'allmessagescurrent' => 'Тренутни текст',
+'allmessagestext' => 'Ово је списак свих порука које су у {{ns:MediaWiki}} именском простору',
+'allmessagesnotsupportedUI' => 'Страница {{ns:special}}:Allmessages не подржава вВаш тренутни језик интерфејса <b>$1</b> на овој вики.',
+'allmessagesnotsupportedDB' => 'Страница {{ns:special}}:Allmessages не може да се користи зато што је \'\'\'$wgUseDatabaseMessages\'\'\' искључен.',
+'allmessagesfilter' => 'Филтер за имена порука:',
+'allmessagesmodified' => 'Прикажи само измењене',
+
+# Thumbnails
+'thumbnail-more' => 'увећај',
+'missingimage' => '<b>Овде недостаје слика</b><br /><i>$1</i>',
+'filemissing' => 'Недостаје фајл',
+'thumbnail_error' => 'Грешка при прављењу умањене слике: $1',
+
+# Special:Import
+'import' => 'Увоз страница',
+'importinterwiki' => 'Трансвики увожење',
+'import-interwiki-text' => 'Одаберите вики и назив стране за увоз.
+Датуми ревизије и имена уредника ће бити сачувани.
+Сви трансвики увози су забележени у [[Посебно:Log/import|историји увоза]].',
+'import-interwiki-history' => 'Копирај све ревизије ове стране',
+'import-interwiki-submit' => 'Увези',
+'import-interwiki-namespace' => 'Пребаци странице у именски простор:',
+'importtext' => 'Молимо извезите фајл из изворног викија користећи {{ns:special}}:Export, сачувајте га код себе и пошаљите овде.',
+'importstart' => 'Увожење страна у току...',
+'import-revision-count' => '$1 {{plural:$1|ревизија|ревизије|ревизија}}',
+'importnopages' => 'Нема страна за увоз.',
+'importfailed' => 'Увоз није успео: $1',
+'importunknownsource' => 'Непознати тип извора уноса',
+'importcantopen' => 'Неуспешно отварање фајла за увоз',
+'importbadinterwiki' => 'Лоша интервики веза',
+'importnotext' => 'Страница је празна или без текста.',
+'importsuccess' => 'Успешан увоз!',
+'importhistoryconflict' => 'Постоји конфликтна историја ревизија (можда је ова страница већ увезена раније)',
+'importnosources' => 'Није дефинисан ниједан извор трансвики увожења и директна слања историја су онемогућена.',
+'importnofile' => 'Није послат ниједан увозни фајл.',
+'importuploaderror' => 'Слање увозног фајла није било успешно; могуће је да је фајл већи од дозвољене величине за слање.',
+
+# import log
+'importlogpage' => 'историја увоза',
+'importlogpagetext' => 'Административни увози страница са историјама измена са других викија.',
+'import-logentry-upload' => 'увезао [[$1]] путем слања фајла',
+'import-logentry-upload-detail' => '$1 ревизија/е',
+'import-logentry-interwiki' => 'преместио са другог викија: $1',
+'import-logentry-interwiki-detail' => '$1 ревизија/е од $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Претражите вики [alt-f]',
+'tooltip-minoredit' => 'Назначите да се ради о малој измени [alt-i]',
+'tooltip-save' => 'Снимите Ваше измене [alt-s]',
+'tooltip-preview' => 'Претпреглед Ваших измена, молимо користите ово пре снимања! [alt-p]',
+'tooltip-diff' => 'Прикажи које промене сте направили на тексту. [alt-v]',
+'tooltip-compareselectedversions' => 'Погледаj разлике између две одабране верзије ове странице. [alt-v]',
+'tooltip-watch' => 'Додајте ову страницу на Ваш списак надгледања [alt-w]',
+
+# stylesheets
+'common.css' => '/** CSS стављен овде ће се односити на све коже */',
+'monobook.css' => '/* CSS стављен овде ће се односити на кориснике Монобук коже */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF метаподаци онемогућени за овај сервер.',
+'nocreativecommons' => 'Creative Commons RDF метаподаци онемогућени за овај сервер.',
+'notacceptable' => 'Вики сервер не може да пружи податке у оном формату који ваш клијент може да прочита.',
+
+# Attribution
+
+'anonymous' => 'Анонимни корисник сајта {{SITENAME}}',
+'siteuser' => '{{SITENAME}} корисник $1',
+'lastmodifiedatby' => 'Ову страницу је последњи пут променио $3 у $2, $1.',
+'and' => 'и',
+'othercontribs' => 'Базирано на раду корисника $1.',
+'others' => 'остали',
+'siteusers' => '{{SITENAME}} корисник (корисници) $1',
+'creditspage' => 'Заслуге за страницу',
+'nocredits' => 'Нису доступне информације о заслугама за ову страницу.',
+
+# Spam protection
+'spamprotectiontitle' => 'Филтер за заштиту од нежељених порука',
+'spamprotectiontext' => 'Страна коју желите да сачувате је блокирана од стране филтера за нежељене поруке. Ово је вероватно изазвано везом ка спољашњем сајту.',
+'spamprotectionmatch' => 'Следећи текст је изазвао наш филтер за нежељене поруке: $1',
+'subcategorycount' => 'У овој категорији се налази {{plural:$1|једна поткатегорија|$1 поткатегорије|$1 поткатегорија}}.',
+'categoryarticlecount' => 'У овој категорији се налази {{plural:$1|Један чланак|$1 чланка|$1 чланака}}.',
+'listingcontinuesabbrev' => ' наст.',
+'spambot_username' => 'Чишћење нежељених порука у МедијаВикију',
+'spam_reverting' => 'Враћање на стару ревизију која не садржи везе ка $1',
+'spam_blanking' => 'Све ревизије су садржале везе ка $1, пражњење',
+
+# Info page
+'infosubtitle' => 'Информације за страницу',
+'numedits' => 'Број промена (чланак): $1',
+'numtalkedits' => 'Број промена (страница за разговор): $1',
+'numwatchers' => 'Број корисника који надгледају: $1',
+'numauthors' => 'Број различитих аутора (чланак): $1',
+'numtalkauthors' => 'Број различитих аутора (страница за разговор): $1',
+
+# Math options
+'mw_math_png' => 'Увек прикажи PNG',
+'mw_math_simple' => 'HTML ако је врло једноставно, иначе PNG',
+'mw_math_html' => 'HTML ако је могуће, иначе PNG',
+'mw_math_source' => 'Остави као ТеХ (за текстуалне браузере)',
+'mw_math_modern' => 'Препоручено за савремене браузере',
+'mw_math_mathml' => 'MathML ако је могуће (експериментално)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Означи као патролиран',
+'markaspatrolledtext' => 'Означи овај чланак као патролиран',
+'markedaspatrolled' => 'Означен као патролиран',
+'markedaspatrolledtext' => 'Изабрана ревизија је означена као патролирана.',
+'rcpatroldisabled' => 'Патрола скорашњих измена онемогућена',
+'rcpatroldisabledtext' => 'Патрола скорашњих измена је тренутно онемогућена.',
+'markedaspatrollederror' => 'Немогуће означити као патролирано',
+'markedaspatrollederrortext' => 'Морате изабрати ревизију да бисте означили као патролирано.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Моја корисничка страница\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Корисничка страница ИП адресе са које уређујете\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Моја страница за разговор\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Разговор о прилозима са ове ИП адресе\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Моја корисничка подешавања\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Списак чланака које надгледате\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Списак мојих прилога\');
+ta[\'pt-login\'] = new Array(\'o\',\'Препоручује се да се пријавите, али није обавезно\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Препоручује се да се пријавите, али није обавезно\');
+ta[\'pt-logout\'] = new Array(\'\',\'Одјави се\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Разговор о чланку\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Можете уредити ову страницу. Молимо користите претпреглед пре сачувавања.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Додајте коментар на ову дискусију\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Ова страница је закључана. Можете видети њен извор\');
+ta[\'ca-history\'] = new Array(\'h\',\'Претходне верзије ове странице\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Заштити ову страницу\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Обриши ову страницу\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Враћати измене које су начињене пре брисања странице\');
+ta[\'ca-move\'] = new Array(\'m\',\'Премести ову страницу\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Додајте ову страницу на Ваш списак надгледања\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Уклоните ову страницу са Вашег списка надгледања\');
+ta[\'search\'] = new Array(\'f\',\'Претражите овај вики\');
+ta[\'p-logo\'] = new Array(\'\',\'Главна страна\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Посетите главну страну\');
+ta[\'n-portal\'] = new Array(\'\',\'О пројекту, шта можете да радите и где да пронађете ствари\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Сазнајте више о актуелностима\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Списак скорашњих измена на викију\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Учитавај случајну страницу\');
+ta[\'n-help\'] = new Array(\'\',\'Место где можете да научите нешто\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Подржите нас\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Списак свих страница које везују на ову\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Скорашње измене на чланцима повезаним са ове странице\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS фид за ову страницу\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom фид за ову страницу\');
+ta[\'t-contributions\'] = new Array(\'\',\'Погледај списак прилога овог корисника\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Пошаљи електронску пошту овом кориснику\');
+ta[\'t-upload\'] = new Array(\'u\',\'Пошаљи слике и медија фајлове\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Списак свих посебних страница\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Погледајте чланак\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Погледајте корисничку страницу\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Погледајте медија страницу\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Ово је посебна страница, не можете је мењати\');
+ta[\'ca-nstab-wp\'] = new Array(\'c\',\'Погледајте страницу о пројекту\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Погледајте страницу слике\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Погледајте системску поруку\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Погледајте шаблон\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Погледајте страницу за помоћ\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Погледајте страницу категорије\');',
+
+# image deletion
+'deletedrevision' => 'Обрисана стара ревизија $1.',
+
+# browsing diffs
+'previousdiff' => '← Претходна измена',
+'nextdiff' => 'Следећа измена →',
+
+'imagemaxsize' => 'Ограничи слике на странама за разговор о сликама на:',
+'thumbsize' => 'Величина умањеног приказа :',
+'showbigimage' => 'Прикажи слику веће резолуције ($1x$2, $3 Kb)',
+
+'newimages' => 'Галерија нових слика',
+'showhidebots' => '($1 ботове)',
+'noimages' => 'Нема ништа да се види',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+# variants for Serbian language
+'variantname-sr-ec' => 'ћирилица',
+'variantname-sr-el' => 'latinica',
+'variantname-sr-jc' => 'јекав',
+'variantname-sr-jl' => 'jekav',
+'variantname-sr' => 'disable',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Корисник:',
+'speciallogtitlelabel' => 'Наслов:',
+
+'passwordtooshort' => 'Ваша шифра је превише кратка. Мора да има бар $1 карактера.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Упозорење\'\'\': Овај фајл садржи лош код, његовим извршавањем можете да угрозите ваш систем.<hr />',
+
+'fileinfo' => '$1KB, МИМЕ тип: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Метаподаци',
+'metadata-help' => 'Овај фајл садржи додатне информације, које су вероватно додали дигитални фотоапарат или скенер који су коришћени да би се направила или дигитализовала слика. Ако је првобитно стање фајла промењено, могуће је да неки детаљи не описују у потпуности измењену слику.',
+'metadata-expand' => 'Покажи детаље',
+'metadata-collapse' => 'Сакриј детаље',
+'metadata-fields' => 'Поља EXIF метаподатака наведена у овој поруци ће бити убачена на страну о слици када се рашири табела за метаподатке. Остала ће бити сакривена по подразумеваном.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# Exif tags
+'exif-imagewidth' => 'Ширина',
+'exif-imagelength' => 'Висина',
+'exif-bitspersample' => 'Битова по компоненти',
+'exif-compression' => 'Шема компресије',
+'exif-photometricinterpretation' => 'Композиција пиксела',
+'exif-orientation' => 'Оријентација',
+'exif-samplesperpixel' => 'Број компоненти',
+'exif-planarconfiguration' => 'Принцип распореда података',
+'exif-ycbcrsubsampling' => 'Однос компоненте Y према C',
+'exif-ycbcrpositioning' => 'Размештај компонената Y и C',
+'exif-xresolution' => 'Хоризонатална резолуција',
+'exif-yresolution' => 'Вертикална резолуција',
+'exif-resolutionunit' => 'Јединица резолуције',
+'exif-stripoffsets' => 'Положај блока података',
+'exif-rowsperstrip' => 'Број редова у блоку',
+'exif-stripbytecounts' => 'Величина компресованог блока',
+'exif-jpeginterchangeformat' => 'Удаљеност ЈПЕГ прегледа од почетка фајла',
+'exif-jpeginterchangeformatlength' => 'Количина бајтова ЈПЕГ прегледа',
+'exif-transferfunction' => 'Функција преобликовања колор простора',
+'exif-whitepoint' => 'Хромацитет беле тачке',
+'exif-primarychromaticities' => 'Хромацитет примарних боја',
+'exif-ycbcrcoefficients' => 'Матрични коефицијенти трансформације колор простора',
+'exif-referenceblackwhite' => 'Место беле и црне тачке',
+'exif-datetime' => 'Датум последње промене фајла',
+'exif-imagedescription' => 'Име слике',
+'exif-make' => 'Произвођач камере',
+'exif-model' => 'Модел камере',
+'exif-software' => 'Коришћен софтвер',
+'exif-artist' => 'Аутор',
+'exif-copyright' => 'Носилац права',
+'exif-exifversion' => 'Exif верзија',
+'exif-flashpixversion' => 'Подржана верзија Флешпикса',
+'exif-colorspace' => 'Простор боје',
+'exif-componentsconfiguration' => 'Значење сваке од компоненти',
+'exif-compressedbitsperpixel' => 'Мод компресије слике',
+'exif-pixelydimension' => 'Пуна висина слике',
+'exif-pixelxdimension' => 'Пуна ширина слике',
+'exif-makernote' => 'Напомене произвођача',
+'exif-usercomment' => 'Кориснички коментар',
+'exif-relatedsoundfile' => 'Повезани звучни запис',
+'exif-datetimeoriginal' => 'Датум и време сликања',
+'exif-datetimedigitized' => 'Датум и време дигитализације',
+'exif-subsectime' => 'Део секунде у којем је сликано',
+'exif-subsectimeoriginal' => 'Део секунде у којем је фотографисано',
+'exif-subsectimedigitized' => 'Део секунде у којем је дигитализовано',
+'exif-exposuretime' => 'Експозиција',
+'exif-exposuretime-format' => '$1 сек ($2)',
+'exif-fnumber' => 'F број отвора бленде',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' => 'Програм експозиције',
+'exif-spectralsensitivity' => 'Спектрална осетљивост',
+'exif-isospeedratings' => 'ИСО вредност',
+'exif-oecf' => 'Оптоелектронски фактор конверзије',
+'exif-shutterspeedvalue' => 'Брзина затварача',
+'exif-aperturevalue' => 'Отвор бленде',
+'exif-brightnessvalue' => 'Светлост',
+'exif-exposurebiasvalue' => 'Компензација експозиције',
+'exif-maxaperturevalue' => 'Минимални број отвора бленде',
+'exif-subjectdistance' => 'Удаљеност до објекта',
+'exif-meteringmode' => 'Режим мерача времена',
+'exif-lightsource' => 'Извор светлости',
+'exif-flash' => 'Блиц',
+'exif-focallength' => 'Фокусна даљина сочива',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' => 'Положај и површина објекта снимка',
+'exif-flashenergy' => 'Енергија блица',
+'exif-spatialfrequencyresponse' => 'Просторна фреквенцијска карактеристика',
+'exif-focalplanexresolution' => 'Водоравна резолуција фокусне равни',
+'exif-focalplaneyresolution' => 'Хоризонатлна резолуција фокусне равни',
+'exif-focalplaneresolutionunit' => 'Јединица резолуције фокусне равни',
+'exif-subjectlocation' => 'Положај субјекта',
+'exif-exposureindex' => 'Индекс експозиције',
+'exif-sensingmethod' => 'Тип сензора',
+'exif-filesource' => 'Изворни фајл',
+'exif-scenetype' => 'Тип сцене',
+'exif-cfapattern' => 'CFA шаблон',
+'exif-customrendered' => 'Додатна обрада слике',
+'exif-exposuremode' => 'Режим избора експозиције',
+'exif-whitebalance' => 'Баланс беле боје',
+'exif-digitalzoomratio' => 'Однос дигиталног зума',
+'exif-focallengthin35mmfilm' => 'Еквивалент фокусне даљине за 35 mm филм',
+'exif-scenecapturetype' => 'Тип сцене на снимку',
+'exif-gaincontrol' => 'Контрола осветљености',
+'exif-contrast' => 'Контраст',
+'exif-saturation' => 'Сатурација',
+'exif-sharpness' => 'Оштрина',
+'exif-devicesettingdescription' => 'Опис подешавања уређаја',
+'exif-subjectdistancerange' => 'Распон удаљености субјеката',
+'exif-imageuniqueid' => 'Јединствени идентификатор слике',
+'exif-gpsversionid' => 'Верзија блока ГПС-информације',
+'exif-gpslatituderef' => 'Северна или јужна ширина',
+'exif-gpslatitude' => 'Ширина',
+'exif-gpslongituderef' => 'Источна или западна дужина',
+'exif-gpslongitude' => 'Дужина',
+'exif-gpsaltituderef' => 'Висина испод или изнад мора',
+'exif-gpsaltitude' => 'Висина',
+'exif-gpstimestamp' => 'Време по ГПС-у (атомски сат)',
+'exif-gpssatellites' => 'Употребљени сателити',
+'exif-gpsstatus' => 'Статус пријемника',
+'exif-gpsmeasuremode' => 'Режим мерења',
+'exif-gpsdop' => 'Прецизност мерења',
+'exif-gpsspeedref' => 'Јединица брзине',
+'exif-gpsspeed' => 'Брзина ГПС пријемника',
+'exif-gpstrackref' => 'Тип азимута пријемника (прави или магнетни)',
+'exif-gpstrack' => 'Азимут пријемника',
+'exif-gpsimgdirectionref' => 'Тип азимута слике (прави или магнетни)',
+'exif-gpsimgdirection' => 'Азимут слике',
+'exif-gpsmapdatum' => 'Коришћени геодетски координатни систем',
+'exif-gpsdestlatituderef' => 'Индекс географске ширине објекта',
+'exif-gpsdestlatitude' => 'Географска ширина објекта',
+'exif-gpsdestlongituderef' => 'Индекс географске дужине објекта',
+'exif-gpsdestlongitude' => 'Географска дужина објекта',
+'exif-gpsdestbearingref' => 'Индекс азимута објекта',
+'exif-gpsdestbearing' => 'Азимут објекта',
+'exif-gpsdestdistanceref' => 'Мерне јединице удаљености објекта',
+'exif-gpsdestdistance' => 'Удаљеност објекта',
+'exif-gpsprocessingmethod' => 'Име методе обраде ГПС података',
+'exif-gpsareainformation' => 'Име ГПС подручја',
+'exif-gpsdatestamp' => 'ГПС датум',
+'exif-gpsdifferential' => 'ГПС диференцијална корекција',
+
+# Exif attributes
+
+'exif-compression-1' => 'Некомпресован',
+'exif-compression-6' => 'ЈПЕГ',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Нормално',
+'exif-orientation-2' => 'Обрнуто по хоризонтали',
+'exif-orientation-3' => 'Заокренуто 180°',
+'exif-orientation-4' => 'Обрнуто по вертикали',
+'exif-orientation-5' => 'Заокренуто 90° супротно од смера казаљке на сату и обрнуто по вертикали',
+'exif-orientation-6' => 'Заокренуто 90° у смеру казаљке на сату',
+'exif-orientation-7' => 'Заокренуто 90° у смеру казаљке на сату и обрнуто по вертикали',
+'exif-orientation-8' => 'Заокренуто 90° супротно од смера казаљке на сату',
+
+'exif-planarconfiguration-1' => 'делимични формат',
+'exif-planarconfiguration-2' => 'планарни формат',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'не постоји',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Непознато',
+'exif-exposureprogram-1' => 'Ручно',
+'exif-exposureprogram-2' => 'Нормални програм',
+'exif-exposureprogram-3' => 'Приоритет отвора бленде',
+'exif-exposureprogram-4' => 'Приоритет затварача',
+'exif-exposureprogram-5' => 'Уметнички програм (на бази нужне дубине поља)',
+'exif-exposureprogram-6' => 'Спортски програм (на бази што бржег затварача)',
+'exif-exposureprogram-7' => 'Портретни режим (за крупне кадрове са неоштром позадином)',
+'exif-exposureprogram-8' => 'Режим пејзажа (за слике пејзажа са оштром позадином)',
+
+'exif-subjectdistance-value' => '$1 метара',
+
+'exif-meteringmode-0' => 'Непознато',
+'exif-meteringmode-1' => 'Просек',
+'exif-meteringmode-2' => 'Просек са тежиштем на средини',
+'exif-meteringmode-3' => 'Тачка',
+'exif-meteringmode-4' => 'Више тачака',
+'exif-meteringmode-5' => 'Матрични',
+'exif-meteringmode-6' => 'Делимични',
+'exif-meteringmode-255' => 'Друго',
+
+'exif-lightsource-0' => 'Непознато',
+'exif-lightsource-1' => 'Дневна светлост',
+'exif-lightsource-2' => 'Флуоресцентно',
+'exif-lightsource-3' => 'Волфрам (светло)',
+'exif-lightsource-4' => 'Блиц',
+'exif-lightsource-9' => 'Лепо време',
+'exif-lightsource-10' => 'Облачно време',
+'exif-lightsource-11' => 'Сенка',
+'exif-lightsource-12' => 'Флуоресцентна светлост (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Флуоресцентна светлост (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Флуоресцентна светлост (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Бела флуоресценција (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Стандардно светло А',
+'exif-lightsource-18' => 'Стандардно светло Б',
+'exif-lightsource-19' => 'Стандардно светло Ц',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ИСО студијски волфрам',
+'exif-lightsource-255' => 'Други извор светла',
+
+'exif-focalplaneresolutionunit-2' => 'инчи',
+
+'exif-sensingmethod-1' => 'Недефинисано',
+'exif-sensingmethod-2' => 'Једнокристални матрични сензор',
+'exif-sensingmethod-3' => 'Двокристални матрични сензор',
+'exif-sensingmethod-4' => 'Трокристални матрични сензор',
+'exif-sensingmethod-5' => 'Секвенцијални матрични сензор',
+'exif-sensingmethod-7' => 'Тробојни линеарни сензор',
+'exif-sensingmethod-8' => 'Секвенцијални линеарни сензор',
+
+'exif-filesource-3' => 'Дигитални фотоапарат',
+
+'exif-scenetype-1' => 'Директно фотографисана слика',
+
+'exif-customrendered-0' => 'Нормални процес',
+'exif-customrendered-1' => 'Нестадардни процес',
+
+'exif-exposuremode-0' => 'Аутоматски',
+'exif-exposuremode-1' => 'Ручно',
+'exif-exposuremode-2' => 'Аутоматски са задатим распоном',
+
+'exif-whitebalance-0' => 'Аутоматски',
+'exif-whitebalance-1' => 'Ручно',
+
+'exif-scenecapturetype-0' => 'Стандардно',
+'exif-scenecapturetype-1' => 'Пејзаж',
+'exif-scenecapturetype-2' => 'Портрет',
+'exif-scenecapturetype-3' => 'Ноћно',
+
+'exif-gaincontrol-0' => 'Нема',
+'exif-gaincontrol-1' => 'Мало повећање',
+'exif-gaincontrol-2' => 'Велико повећање',
+'exif-gaincontrol-3' => 'Мало смањење',
+'exif-gaincontrol-4' => 'Велико смањење',
+
+'exif-contrast-0' => 'Нормално',
+'exif-contrast-1' => 'Меко',
+'exif-contrast-2' => 'Тврдо',
+
+'exif-saturation-0' => 'Нормално',
+'exif-saturation-1' => 'Ниска сатурација',
+'exif-saturation-2' => 'Висока сатурација',
+
+'exif-sharpness-0' => 'Нормално',
+'exif-sharpness-1' => 'Меко',
+'exif-sharpness-2' => 'Тврдо',
+
+'exif-subjectdistancerange-0' => 'Непознато',
+'exif-subjectdistancerange-1' => 'Крупни кадар',
+'exif-subjectdistancerange-2' => 'Блиски кадар',
+'exif-subjectdistancerange-3' => 'Далеки кадар',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Север',
+'exif-gpslatitude-s' => 'Југ',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Исток',
+'exif-gpslongitude-w' => 'Запад',
+
+'exif-gpsstatus-a' => 'Мерење у току',
+'exif-gpsstatus-v' => 'Спреман за пренос',
+
+'exif-gpsmeasuremode-2' => 'Дводимензионално мерење',
+'exif-gpsmeasuremode-3' => 'Тродимензионално мерење',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Километри на час',
+'exif-gpsspeed-m' => 'Миље на час',
+'exif-gpsspeed-n' => 'Чворови',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Прави правац',
+'exif-gpsdirection-m' => 'Магнетни правац',
+
+# external editor support
+'edit-externally' => 'Измените овај фајл користећи спољашњу апликацију',
+'edit-externally-help' => 'Погледајте [http://meta.wikimedia.org/wiki/Help:External_editors упутство за подешавање] за више информација.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'све',
+'imagelistall' => 'све',
+'watchlistall1' => 'све',
+'watchlistall2' => 'све',
+'namespacesall' => 'сви',
+
+# E-mail address confirmation
+'confirmemail' => 'Потврдите адресу е-поште',
+'confirmemail_noemail' => 'Немате потврђену адресу ваше е-поште у вашим [[Special:Preferences|корисничким подешавањима интерфејса]].',
+'confirmemail_text' => 'Ова вики захтева да потврдите адресу ваше е-поште пре него што користите могућности е-поште. Активирајте дугме испод како бисте послали пошту за потврду на вашу адресу. Пошта укључује везу која садржи код; учитајте ту везу у ваш браузер да бисте потврдили да је адреса ваше е-поште валидна.',
+'confirmemail_send' => 'Пошаљи код за потврду',
+'confirmemail_sent' => 'Е-пошта за потврђивање послата.',
+'confirmemail_sendfailed' => 'Пошта за потврђивање није послата. Проверита адресу због неправилних карактера.',
+'confirmemail_invalid' => 'Нетачан код за потврду. Могуће је да је код истекао.',
+'confirmemail_needlogin' => 'Морате да се $1 да бисте потврдили адресу ваше е-поште.',
+'confirmemail_success' => 'Адреса ваше е-поште је потврђена. Можете сада да се пријавите и уживате у викију.',
+'confirmemail_loggedin' => 'Адреса ваше е-поште је сада потврђена.',
+'confirmemail_error' => 'Нешто је пошло по злу приликом снимања ваше потврде.',
+
+'confirmemail_subject' => '{{SITENAME}} адреса е-поште за потврђивање',
+'confirmemail_body' => 'Неко, вероватно ви, је са ИП адресе $1 регистровао налог "$2" са овом адресом е-поште на сајту {{SITENAME}}.
+
+Да потврдите да овај налог стварно припада вама и да активирате могућност е-поште на сајту {{SITENAME}}, отворите ову везу у вашем браузеру:
+
+$3
+
+Ако ово *нисте* ви, не пратите везу. Овај код за потврду ће истећи у $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Покушај тачно',
+'searchfulltext' => 'Претражи цео текст',
+'createarticle' => 'Направи чланак',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Интервики укључивање је онемогућено]',
+'scarytranscludefailed' => '[Доношење шаблона неуспешно; жао нам је]',
+'scarytranscludetoolong' => '[УРЛ је предугачак; жао нам је]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Враћања за овај чланак:<br />
+$1
+</div>',
+'trackbackremove' => '([$1 Брисање])',
+'trackbacklink' => 'Враћање',
+'trackbackdeleteok' => 'Враћање је успешно обрисано.',
+
+# delete conflict
+'deletedwhileediting' => 'Упозорење: Ова страна је обрисана пошто сте почели уређивање!',
+'confirmrecreate' => 'Корисник [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|разговор]]) је обрисао овај чланак пошто сте почели уређивање са разлогом:
+: \'\'$2\'\'
+Молимо потврдите да стварно желите да поново направите овај чланак.',
+'recreate' => 'Поново направи',
+'tooltip-recreate' => 'Поново направите ову страну упркос томе што је обрисана',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Преусмеравам на [[$1]]...',
+
+# action=purge
+'confirm_purge' => 'Да ли желите очистити кеш ове странице?
+
+$1',
+'confirm_purge_button' => 'Да',
+
+'youhavenewmessagesmulti' => 'Имате нових порука на $1',
+'searchcontaining' => 'Претражи чланке који садрже \'\'$1\'\'.',
+'searchnamed' => 'Претражи чланке који се зову \'\'$1\'\'.',
+'articletitles' => 'Чланци почевши од \'\'$1\'\'',
+'hideresults' => 'Сакриј резултате',
+
+# DISPLAYTITLE
+'displaytitle' => '(Веза ка овој страни као [[$1]])',
+
+'loginlanguagelabel' => 'Језик: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; претходна страница',
+'imgmultipagenext' => 'следећа страница &rarr;',
+'imgmultigo' => 'Иди!',
+'imgmultigotopre' => 'Иди на страницу',
+
+# Table pager
+'ascending_abbrev' => 'раст',
+'descending_abbrev' => 'опад',
+'table_pager_next' => 'Следећа страница',
+'table_pager_prev' => 'Претходна страница',
+'table_pager_first' => 'Прва страница',
+'table_pager_last' => 'Последња страница',
+'table_pager_limit' => 'Прикажи $1 делова информације по страници',
+'table_pager_limit_submit' => 'Иди',
+'table_pager_empty' => 'Без резултата',
+
+);
+
+?>
diff --git a/languages/messages/MessagesSr_el.php b/languages/messages/MessagesSr_el.php
new file mode 100644
index 000000000000..d97d638597b4
--- /dev/null
+++ b/languages/messages/MessagesSr_el.php
@@ -0,0 +1,2217 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => "Medija",
+ NS_SPECIAL => "Posebno",
+ NS_MAIN => "",
+ NS_TALK => "Razgovor",
+ NS_USER => "Korisnik",
+ NS_USER_TALK => "Razgovor_sa_korisnikom",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => "Razgovor_o_$1",
+ NS_IMAGE => "Slika",
+ NS_IMAGE_TALK => "Razgovor_o_slici",
+ NS_MEDIAWIKI => "MedijaViki",
+ NS_MEDIAWIKI_TALK => "Razgovor_o_MedijaVikiju",
+ NS_TEMPLATE => 'Šablon',
+ NS_TEMPLATE_TALK => 'Razgovor_o_šablonu',
+ NS_HELP => 'Pomoć',
+ NS_HELP_TALK => 'Razgovor_o_pomoći',
+ NS_CATEGORY => 'Kategorija',
+ NS_CATEGORY_TALK => 'Razgovor_o_kategoriji',
+);
+
+# Aliases to cyrillic namespaces
+$namespaceAliases = array(
+ "Медија" => NS_MEDIA,
+ "Посебно" => NS_SPECIAL,
+ "Разговор" => NS_TALK,
+ "Корисник" => NS_USER,
+ "Разговор_са_корисником" => NS_USER_TALK,
+ "Разговор_о_$1" => NS_PROJECT_TALK,
+ "Слика" => NS_IMAGE,
+ "Разговор_о_слици" => NS_IMAGE_TALK,
+ "МедијаВики" => NS_MEDIAWIKI,
+ "Разговор_о_МедијаВикију" => NS_MEDIAWIKI_TALK,
+ 'Шаблон' => NS_TEMPLATE,
+ 'Разговор_о_шаблону' => NS_TEMPLATE_TALK,
+ 'Помоћ' => NS_HELP,
+ 'Разговор_о_помоћи' => NS_HELP_TALK,
+ 'Категорија' => NS_CATEGORY,
+ 'Разговор_о_категорији' => NS_CATEGORY_TALK,
+);
+
+
+$quickbarSettings = array(
+ "Nikakva", "Pričvršćena levo", "Pričvršćena desno", "Plutajuća levo"
+);
+
+$skinNames = array(
+ "Obična", "Nostalgija", "Kelnsko plavo", "Pedington", "Monparnas"
+);
+
+$extraUserToggles = array(
+ 'nolangconversion',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'hh:mm d. month y.',
+ 'hh:mm d month y',
+ 'hh:mm dd.mm.yyyy',
+ 'hh:mm d.m.yyyy',
+ 'hh:mm d. mon y.',
+ 'hh:mm d mon y',
+ 'h:mm d. month y.',
+ 'h:mm d month y',
+ 'h:mm dd.mm.yyyy',
+ 'h:mm d.m.yyyy',
+ 'h:mm d. mon y.',
+ 'h:mm d mon y',
+);
+
+$datePreferences = array(
+ 'default',
+ 'hh:mm d. month y.',
+ 'hh:mm d month y',
+ 'hh:mm dd.mm.yyyy',
+ 'hh:mm d.m.yyyy',
+ 'hh:mm d. mon y.',
+ 'hh:mm d mon y',
+ 'h:mm d. month y.',
+ 'h:mm d month y',
+ 'h:mm dd.mm.yyyy',
+ 'h:mm d.m.yyyy',
+ 'h:mm d. mon y.',
+ 'h:mm d mon y',
+);
+
+$defaultDateFormat = 'hh:mm d. month y.';
+
+$dateFormats = array(
+ /*
+ 'Није битно',
+ '06:12, 5. јануар 2001.',
+ '06:12, 5 јануар 2001',
+ '06:12, 05.01.2001.',
+ '06:12, 5.1.2001.',
+ '06:12, 5. јан 2001.',
+ '06:12, 5 јан 2001',
+ '6:12, 5. јануар 2001.',
+ '6:12, 5 јануар 2001',
+ '6:12, 05.01.2001.',
+ '6:12, 5.1.2001.',
+ '6:12, 5. јан 2001.',
+ '6:12, 5 јан 2001',
+ */
+
+ 'hh:mm d. month y. time' => 'H:i',
+ 'hh:mm d month y time' => 'H:i',
+ 'hh:mm dd.mm.yyyy time' => 'H:i',
+ 'hh:mm d.m.yyyy time' => 'H:i',
+ 'hh:mm d. mon y. time' => 'H:i',
+ 'hh:mm d mon y time' => 'H:i',
+ 'h:mm d. month y. time' => 'G:i',
+ 'h:mm d month y time' => 'G:i',
+ 'h:mm dd.mm.yyyy time' => 'G:i',
+ 'h:mm d.m.yyyy time' => 'G:i',
+ 'h:mm d. mon y. time' => 'G:i',
+ 'h:mm d mon y time' => 'G:i',
+
+ 'hh:mm d. month y. date' => 'j. F Y.',
+ 'hh:mm d month y date' => 'j F Y',
+ 'hh:mm dd.mm.yyyy date' => 'd.m.Y',
+ 'hh:mm d.m.yyyy date' => 'j.n.Y',
+ 'hh:mm d. mon y. date' => 'j. M Y.',
+ 'hh:mm d mon y date' => 'j M Y',
+ 'h:mm d. month y. date' => 'j. F Y.',
+ 'h:mm d month y date' => 'j F Y',
+ 'h:mm dd.mm.yyyy date' => 'd.m.Y',
+ 'h:mm d.m.yyyy date' => 'j.n.Y',
+ 'h:mm d. mon y. date' => 'j. M Y.',
+ 'h:mm d mon y date' => 'j M Y',
+
+ 'hh:mm d. month y. both' =>'H:i, j. F Y.',
+ 'hh:mm d month y both' =>'H:i, j F Y',
+ 'hh:mm dd.mm.yyyy both' =>'H:i, d.m.Y',
+ 'hh:mm d.m.yyyy both' =>'H:i, j.n.Y',
+ 'hh:mm d. mon y. both' =>'H:i, j. M Y.',
+ 'hh:mm d mon y both' =>'H:i, j M Y',
+ 'h:mm d. month y. both' =>'G:i, j. F Y.',
+ 'h:mm d month y both' =>'G:i, j F Y',
+ 'h:mm dd.mm.yyyy both' =>'G:i, d.m.Y',
+ 'h:mm d.m.yyyy both' =>'G:i, j.n.Y',
+ 'h:mm d. mon y. both' =>'G:i, j. M Y.',
+ 'h:mm d mon y both' =>'G:i, j M Y',
+);
+
+
+/* NOT USED IN STABLE VERSION */
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#Preusmeri', '#redirect', '#preusmeri', '#PREUSMERI' ),
+ 'notoc' => array( 0, '__NOTOC__', '__BEZSADRŽAJA__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__FORSIRANISADRŽAJ__' ),
+ 'toc' => array( 0, '__TOC__', '__SADRŽAJ__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__BEZ_IZMENA__', '__BEZIZMENA__' ),
+ 'start' => array( 0, '__START__', '__POČETAK__' ),
+ 'end' => array( 0, '__END__', '__KRAJ__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH', 'TRENUTNIMESEC' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME', 'TRENUTNIMESECIME' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN', 'TRENUTNIMESECGEN' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV', 'TRENUTNIMESECSKR' ),
+ 'currentday' => array( 1, 'CURRENTDAY', 'TRENUTNIDAN' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME', 'TRENUTNIDANIME' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR', 'TRENUTNAGODINA' ),
+ 'currenttime' => array( 1, 'CURRENTTIME', 'TRENUTNOVREME' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES', 'BROJČLANAKA' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES', 'BROJDATOTEKA', 'BROJFAJLOVA' ),
+ 'pagename' => array( 1, 'PAGENAME', 'STRANICA' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE', 'STRANICE' ),
+ 'namespace' => array( 1, 'NAMESPACE', 'IMENSKIPROSTOR' ),
+ 'namespacee' => array( 1, 'NAMESPACEE', 'IMENSKIPROSTORI' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME', 'PUNOIMESTRANE' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE', 'PUNOIMESTRANEE' ),
+ 'msg' => array( 0, 'MSG:', 'POR:' ),
+ 'subst' => array( 0, 'SUBST:', 'ZAMENI:' ),
+ 'msgnw' => array( 0, 'MSGNW:', 'NVPOR:' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb', 'mini' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1', 'mini=$1' ),
+ 'img_right' => array( 1, 'right', 'desno', 'd' ),
+ 'img_left' => array( 1, 'left', 'levo', 'l' ),
+ 'img_none' => array( 1, 'none', 'n', 'bez' ),
+ 'img_width' => array( 1, '$1px', '$1piskel' , '$1p' ),
+ 'img_center' => array( 1, 'center', 'centre', 'centar', 'c' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame', 'okvir', 'ram' ),
+ 'int' => array( 0, 'INT:', 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME', 'IMESAJTA' ),
+ 'ns' => array( 0, 'NS:', 'IP:' ),
+ 'localurl' => array( 0, 'LOCALURL:', 'LOKALNAADRESA:' ),
+ 'localurle' => array( 0, 'LOCALURLE:', 'LOKALNEADRESE:' ),
+ 'server' => array( 0, 'SERVER', 'SERVER' ),
+ 'servername' => array( 0, 'SERVERNAME', 'IMESERVERA' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH', 'SKRIPTA' ),
+ 'grammar' => array( 0, 'GRAMMAR:', 'GRAMATIKA:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__', '__БЕЗКН__', '__BEZKN__' ),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__', '__BEZCC__' ),
+ 'currentweek' => array( 1, 'CURRENTWEEK', 'TRENUTNANEDELJA' ),
+ 'currentdow' => array( 1, 'CURRENTDOW', 'TRENUTNIDOV' ),
+ 'revisionid' => array( 1, 'REVISIONID', 'IDREVIZIJE' ),
+ 'plural' => array( 0, 'PLURAL:', 'MNOŽINA:' ),
+ 'fullurl' => array( 0, 'FULLURL:', 'PUNURL:' ),
+ 'fullurle' => array( 0, 'FULLURLE:', 'PUNURLE:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:', 'LCPRVI:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:', 'UCPRVI:' ),
+ 'lc' => array( 0, 'LC:', 'LC:' ),
+ 'uc' => array( 0, 'UC:', 'UC:' ),
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+
+$messages = array(
+# stylesheets
+'common.css' => '/** CSS koji važi za sve skinove */',
+'monobook.css' => '/** Samo za MonoBook skin */',
+
+# User preference toggles
+'tog-underline' => 'Podvuci veze',
+'tog-highlightbroken' => 'Formatiraj pokvarene veze <a href="" class="new">ovako</a> (alternativa: ovako<a href="" class="internal">?</a>).',
+'tog-justify' => 'Uravnaj pasuse',
+'tog-hideminor' => 'Sakrij male izmene u spisku skorašnjih izmena',
+'tog-extendwatchlist' => 'Poboljšan spisak nadgledanja',
+'tog-usenewrc' => 'Poboljšan spisak skorašnjih izmena (zahteva JavaScript)',
+'tog-numberheadings' => 'Automatski numeriši podnaslove',
+'tog-showtoolbar' => 'Prikaži dugmiće za izmene (zahteva JavaScript)',
+'tog-editondblclick' => 'Menjaj stranice dvostrukim klikom (zahteva JavaScript)',
+'tog-editsection' => 'Omogući izmenu delova [uredi] vezama',
+'tog-editsectiononrightclick' => 'Omogući izmenu delova desnim klikom<br />na njihove naslove (zahteva JavaScript)',
+'tog-showtoc' => 'Prikaži sadržaj (u člancima sa više od 3 podnaslova)',
+'tog-rememberpassword' => 'Pamti lozinku kroz više seansi',
+'tog-editwidth' => 'Polje za izmene ima punu širinu',
+'tog-watchcreations' => 'Dodaj stranice koje pravim u moj spisak nadgledanja',
+'tog-watchdefault' => 'Dodaj stranice koje menjam u moj spisak nadgledanja',
+'tog-minordefault' => 'Označi sve izmene malim isprva',
+'tog-previewontop' => 'Prikaži pretpregled pre polja za izmenu',
+'tog-previewonfirst' => 'Prikaži pretpregled pri prvoj izmeni',
+'tog-nocache' => 'Onemogući keširanje stranica',
+'tog-enotifwatchlistpages' => 'Pošalji mi e-poštu kada se promeni strana koju nadgledam',
+'tog-enotifusertalkpages' => 'Pošalji mi e-poštu kada se promeni moja korisnička strana za razgovor',
+'tog-enotifminoredits' => 'Pošalji mi e-poštu takođe za male izmene strana',
+'tog-enotifrevealaddr' => 'Otkrij adresu moje e-pošte u pošti obaveštenja',
+'tog-shownumberswatching' => 'Prikaži broj korisnika koji nadgledaju',
+'tog-fancysig' => 'Čist potpis (bez automatskih veza)',
+'tog-externaleditor' => 'Koristi spoljašnji uređivač po podrazumevanim podešavanjima',
+'tog-externaldiff' => 'Koristi spoljašnji program za prikaz razlika po podrazumevanim podešavanjima',
+'tog-showjumplinks' => 'Omogući "skoči na" veze',
+'tog-uselivepreview' => 'Koristi živi pretpregled (zahteva JavaScript) (eksperimentalno)',
+'tog-autopatrol' => 'Označi izmene koje pravim patroliranim',
+'tog-forceeditsummary' => 'Upozori me kad ne unesem opis izmene',
+'tog-watchlisthideown' => 'Sakrij moje izmene sa spiska nadgledanja',
+'tog-watchlisthidebots' => 'Sakrij izmene botova sa spiska nadgledanja',
+'tog-nolangconversion' => 'Isključi konverziju varijanti',
+
+'underline-always' => 'Uvek',
+'underline-never' => 'Nikad',
+'underline-default' => 'Po podešavanjima brauzera',
+
+'skinpreview' => '(Pregled)',
+
+# dates
+'sunday' => 'nedelja',
+'monday' => 'ponedeljak',
+'tuesday' => 'utorak',
+'wednesday' => 'sreda',
+'thursday' => 'četvrtak',
+'friday' => 'petak',
+'saturday' => 'subota',
+'sun' => 'ned',
+'mon' => 'pon',
+'tue' => 'uto',
+'wed' => 'sre',
+'thu' => 'čet',
+'fri' => 'pet',
+'sat' => 'sub',
+'january' => 'januar',
+'february' => 'februar',
+'march' => 'mart',
+'april' => 'april',
+'may_long' => 'maj',
+'june' => 'jun',
+'july' => 'jul',
+'august' => 'avgust',
+'september' => 'septembar',
+'october' => 'oktobar',
+'november' => 'novembar',
+'december' => 'decembar',
+'january-gen' => 'januara',
+'february-gen' => 'februara',
+'march-gen' => 'marta',
+'april-gen' => 'aprila',
+'may-gen' => 'maja',
+'june-gen' => 'juna',
+'july-gen' => 'jula',
+'august-gen' => 'avgusta',
+'september-gen' => 'septembra',
+'october-gen' => 'oktobra',
+'november-gen' => 'novembra',
+'december-gen' => 'decembra',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'maj',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'avg',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dec',
+# Bits of text used by many pages:
+#
+'categories' => 'Kategorije stranica',
+'pagecategories' => '{{PLURAL:$1|Kategorija|Kategorije|Kategorije}} stranica',
+'category_header' => 'Članaka u kategoriji "$1"',
+'subcategories' => 'Potkategorije',
+
+'mainpage' => 'Glavna strana',
+'mainpagetext' => '<big>\'\'\'MedijaViki je uspešno instaliran.\'\'\'</big>',
+'mainpagedocfooter' => "Molimo vidite [http://meta.wikimedia.org/wiki/Help:Contents korisnički vodič] za informacije o upotrebi viki softvera.
+
+== Za početak ==
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Pomoć u vezi sa podešavanjima]
+* [http://www.mediawiki.org/wiki/Help:FAQ Najčešće postavljena pitanja]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce Mejling lista o izdanjima MedijaVikija]",
+
+'portal' => 'Radionica',
+'portal-url' => 'Project:Radionica',
+'about' => 'O...',
+'aboutsite' => 'O projektu {{SITENAME}}',
+'aboutpage' => 'Project:O',
+'article' => 'Članak',
+'help' => 'Pomoć',
+'helppage' => '{{ns:help}}:Sadržaj',
+'bugreports' => 'Prijave grešaka',
+'bugreportspage' => 'Project:Prijave_grešaka',
+'sitesupport' => 'Donacije',
+'sitesupport-url' => 'Project:Donacije',
+'faq' => 'NPP',
+'faqpage' => 'Project:NPP',
+'edithelp' => 'Pomoć oko uređivanja',
+'newwindow' => '(novi prozor)',
+'edithelppage' => '{{ns:help}}:Uređivanje',
+'cancel' => 'Poništi',
+'qbfind' => 'Pronađi',
+'qbbrowse' => 'Prelistavaj',
+'qbedit' => 'Izmeni',
+'qbpageoptions' => 'Opcije stranice',
+'qbpageinfo' => 'Informacije o stranici',
+'qbmyoptions' => 'Moje opcije',
+'qbspecialpages' => 'Posebne stranice',
+'moredotdotdot' => 'Još...',
+'mypage' => 'Moja stranica',
+'mytalk' => 'Moj razgovor',
+'anontalk' => 'Razgovor za ovu IP adresu',
+'navigation' => 'Navigacija',
+
+# Metadata in edit box
+'metadata_help' => 'Metapodaci (vidi [[Project:Metapodaci]] za objašnjenje):',
+
+'currentevents' => 'Trenutni događaji',
+'currentevents-url' => 'Trenutni događaji',
+'disclaimers' => 'Odricanje odgovornosti',
+'disclaimerpage' => 'Project:Odricanje odgovornosti',
+'privacy' => 'Politika privatnosti',
+'privacypage' => 'Project:Politika privatnosti',
+'errorpagetitle' => 'Greška',
+'returnto' => 'Povratak na $1.',
+'tagline' => 'Iz projekta {{SITENAME}}',
+'help' => 'Pomoć',
+'search' => 'pretraga',
+'searchbutton' => 'Traži',
+'go' => 'Idi',
+'searcharticle' => 'Idi',
+'history' => 'Istorija stranice',
+'history_short' => 'istorija',
+'updatedmarker' => 'ažurirano od moje poslednje posete',
+'info_short' => 'Informacije',
+'printableversion' => 'Verzija za štampu',
+'permalink' => 'Permalink',
+'print' => 'Štampa',
+'edit' => 'Uredi',
+'editthispage' => 'Uredi ovu stranicu',
+'delete' => 'obriši',
+'deletethispage' => 'Obriši ovu stranicu',
+'undelete_short' => 'vrati {{PLURAL:$1|jednu obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}',
+'protect' => 'zaštiti',
+'protectthispage' => 'Zaštiti ovu stranicu',
+'unprotect' => 'Skloni zaštitu',
+'unprotectthispage' => 'Skloni zaštitu sa ove stranice',
+'newpage' => 'Nova stranica',
+'talkpage' => 'Razgovor o ovoj stranici',
+'specialpage' => 'Posebna stranica',
+'personaltools' => 'Lični alati',
+'postcomment' => 'Pošalji komentar',
+'articlepage' => 'Pogledaj članak',
+'talk' => 'Razgovor',
+'views' => 'Pregledi',
+'toolbox' => 'alati',
+'userpage' => 'Pogledaj korisničku stranu',
+'projectpage' => 'Pogledaj stranu projekta',
+'imagepage' => 'Pogledaj stranu slike',
+'mediawikipage' => 'Vidi stranicu poruke',
+'templatepage' => 'Vidi stranicu šablona',
+'viewhelppage' => 'Vidi stranicu pomoći',
+'categorypage' => 'Vidi stranicu kategorije',
+'viewtalkpage' => 'Pogledaj razgovor',
+'otherlanguages' => 'Ostali jezici',
+'redirectedfrom' => '(Preusmereno sa $1)',
+'autoredircomment' => 'Preusmerenje na [[$1]]',
+'redirectpagesub' => 'Strana preusmerenja',
+'lastmodifiedat' => 'Ova stranica je poslednji put izmenjena $2, $1.',
+'viewcount' => 'Ovoj stranici je pristupljeno {{PLURAL:$1|jednom|$1 puta|$1 puta}}.',
+'copyright' => 'Sadržaj je objavljen pod $1.',
+'protectedpage' => 'Zaštićena stranica',
+'jumpto' => 'Skoči na:',
+'jumptonavigation' => 'navigacija',
+'jumptosearch' => 'pretraga',
+
+'badaccess' => 'Greška u dozvolama',
+'badaccess-group0' => 'Nije vam dozvoljeno da izvršite akciju koju ste pokrenuli.',
+'badaccess-group1' => 'Akcija koju ste pokrenuli je rezerevisana za korisnike u grupi $1.',
+'badaccess-group2' => 'Akcija koju ste pokrenuli je rezervisana za korisnike iz jedne od grupa $1.',
+'badaccess-groups' => 'Akcija koju ste pokrenuli je rezervisana za korisnike iz jedne od grupa $1.',
+
+'versionrequired' => 'Verzija $1 MedijaVikija je potrebna',
+'versionrequiredtext' => 'Verzija $1 MedijaVikija je potrebna da bi se koristila ova strana. Pogledajte [[{{ns:special}}:Version|verziju]]',
+
+'ok' => 'da',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Dobavljeno iz "$1"',
+'youhavenewmessages' => 'Imate $1 ($2).',
+'newmessageslink' => 'novih poruka',
+'newmessagesdifflink' => 'najsvežije izmene',
+'editsection' => 'uredi',
+'editold' => 'uredi',
+'editsectionhint' => 'Uredi deo: $1',
+'toc' => 'Sadržaj',
+'showtoc' => 'prikaži',
+'hidetoc' => 'sakrij',
+'thisisdeleted' => 'Pogledaj ili vrati $1?',
+'viewdeleted' => 'Pogledaj $1?',
+'restorelink' => '{{PLURAL:$1|jedna obrisana izmena|$1 obrisane izmene|$1 obrisanih izmena}}',
+'feedlinks' => 'Fid:',
+'feed-invalid' => 'Loš tip fida prijave.',
+'feed-atom' => 'Atom',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Članak',
+'nstab-user' => 'Korisnička strana',
+'nstab-media' => 'Medij',
+'nstab-special' => 'Posebna',
+'nstab-project' => 'Strana projekta',
+'nstab-image' => 'Slika',
+'nstab-mediawiki' => 'Poruka',
+'nstab-template' => 'Šablon',
+'nstab-help' => 'Pomoć',
+'nstab-category' => 'Kategorija',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Nema takve akcije',
+'nosuchactiontext' => 'Akciju navedenu u URL-u viki softver
+nije prepoznao.',
+'nosuchspecialpage' => 'Nema takve posebne stranice',
+'nospecialpagetext' => 'Tražili ste nepostojeću posebnu stranicu. Spisak svih posebnih stranica se može naći na [[{{ns:special}}:Specialpages]].',
+
+# General errors
+#
+'error' => 'Greška',
+'databaseerror' => 'Greška u bazi',
+'dberrortext' => 'Desila se sintaksna greška upita baze.
+Ovo možda ukazuje na greške u softveru.
+Poslednji pokušani upit je bio:
+<blockquote><tt>$1</tt></blockquote>
+iz funkcije "<tt>$2</tt>".
+MySQL je vratio grešku "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Desila se sintaksna greška upita baze.
+Poslednji pokušani upit je bio:
+"$1"
+iz funkcije "$2".
+MySQL je vratio grešku "$3: $4".',
+'noconnect' => 'Žao nam je! Viki ima tehničke poteškoće, i ne može da se poveže se serverom baze.',
+'nodb' => 'Ne mogu da izaberem bazu $1',
+'cachederror' => 'Ovo je keširana kopija zahtevane stranice, i možda nije ažurirana.',
+'laggedslavemode' => 'Upozorenje: moguće je da strana nije skoro ažurirana.',
+'readonly' => 'Baza je zaključana',
+'enterlockreason' => 'Unesite razlog za zaključavanje, uključujući procenu
+vremena otključavanja',
+'readonlytext' => 'Baza podataka je trenutno zaključana za nove
+unose i ostale izmene, verovatno zbog rutinskog održavanja,
+posle čega će biti vraćena u uobičajeno stanje.
+Administrator koji ju je zaključao dao je ovo objašnjenje: $1',
+'missingarticle' => 'Baza nije našla tekst stranice
+koji je trebalo, nazvan "$1".
+
+Ovo je obično izazvano praćenjem zastarele "razl" veze ili veze ka istoriji
+stranice koja je obrisana.
+
+Ako ovo nije slučaj, možda ste pronašli grešku u softveru.
+Molimo vas prijavite ovo jednom od [[Project:Administratori|administratora]], zajedno sa URL-om.',
+'readonly_lag' => 'Baza podataka je automatski zaključana dok slejv serveri ne sustignu master',
+'internalerror' => 'Interna greška',
+'filecopyerror' => 'Ne mogu da iskopiram fajl "$1" na "$2".',
+'filerenameerror' => 'Ne mogu da preimenujem fajl "$1" u "$2".',
+'filedeleteerror' => 'Ne mogu da obrišem fajl "$1".',
+'filenotfound' => 'Ne mogu da nađem fajl "$1".',
+'unexpected' => 'Neočekivana vrednost: "$1"="$2".',
+'formerror' => 'Greška: ne mogu da pošaljem upitnik',
+'badarticleerror' => 'Ova akcija ne može biti izvršena na ovoj stranici.',
+'cannotdelete' => 'Ne mogu da obrišem navedenu stranicu ili fajl. (Moguće je da je neko drugi već obrisao.)',
+'badtitle' => 'Loš naslov',
+'badtitletext' => 'Zahtevani naslov stranice je bio neispravan, prazan ili
+neispravno povezan međujezički ili interviki naslov. Možda sadrži jedan ili više karaktera koji ne mogu da se upotrebljavaju u naslovima.',
+'perfdisabled' => 'Žao nam je! Ova mogućnost je privremeno onemogućena jer usporava bazu do te mere da više niko ne može da koristi viki.',
+'perfdisabledsub' => 'Ovde je snimljena kopija $1:', # obsolete?
+'perfcached' => 'Sledeći podaci su keširani i ne moraju biti u potpunosti ažurirani.',
+'perfcachedts' => 'Sledeći podaci su keširani i poslednji put su ažurirani: $1',
+'wrong_wfQuery_params' => 'Netačni parametri za wfQuery()<br />
+Funkcija: $1<br />
+Pretraga: $2',
+'viewsource' => 'pogledaj kod',
+'viewsourcefor' => 'za $1',
+'protectedtext' => 'Ova stranica je zaključana za izmene.
+
+Možete gledati i kopirati sadržaj ove strane:',
+'protectedinterface' => '\'\'\'Upozorenje:\'\'\' Menjate stranu koja se koristi da pruži tekst interfejsa za softver. Izmene na ovoj strani će uticati na izgled korisničkog interfejsa za ostale korisnike.',
+'editinginterface' => "'''Upozorenje:''' Uređujete stranicu čija je namena upisivanje teksta za interfejs softvera. Izmene u ovoj stranici će promeniti izgled korisničkog intefejsa svih korisnika.",
+'sqlhidden' => '(SQL pretraga sakrivena)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Odjavi se',
+'logouttext' => '<strong>Sada ste odjavljeni.</strong><br />
+Možete da nastavite da koristite projekat {{SITENAME}} anonimno, ili se ponovo prijaviti kao drugi korisnik. Obratite pažnju da neke stranice mogu nastaviti da se prikazuju kao da ste još uvek prijavljeni, dok ne očistite keš svog brauzera.',
+
+'welcomecreation' => '== Dobrodošli, $1! ==
+
+Vaš nalog je napravljen.
+Ne zaboravite da prilagodite sebi svoja {{SITENAME}} podešavanja.',
+
+'loginpagetitle' => 'Prijavljivanje',
+'yourname' => 'Korisničko ime',
+'yourpassword' => 'Vaša lozinka',
+'yourpasswordagain' => 'Ponovite lozinku',
+'remembermypassword' => 'Zapamti me',
+'yourdomainname' => 'Vaš domen',
+'externaldberror' => 'Došlo je ili do greške pri spoljašnjoj autentifikaciji baze podataka ili vam nije dozvoljeno da ažurirate svoj spoljašnji nalog.',
+'loginproblem' => '<b>Bilo je problema sa vašim prijavljivanjem.</b><br />Pokušajte ponovo!',
+'alreadyloggedin' => '<strong>Korisniče $1, već ste prijavljeni!</strong><br />',
+
+'login' => 'Prijavi se',
+'loginprompt' => 'Morate da imate omogućene kolačiće (\'\'cookies\'\') da biste se prijavili na {{SITENAME}}.',
+'userlogin' => 'Registruj se / Prijavi se',
+'logout' => 'Odjavi se',
+'userlogout' => 'Odjavi se',
+'notloggedin' => 'Niste prijavljeni',
+'nologin' => 'Nemate nalog? $1.',
+'nologinlink' => 'Napravite nalog',
+'createaccount' => 'Napravi nalog',
+'gotaccount' => 'Već imate nalog? $1.',
+'gotaccountlink' => 'Prijavi se',
+'createaccountmail' => 'e-poštom',
+'badretype' => 'Lozinke koje ste uneli se ne poklapaju.',
+'userexists' => 'Korisničko ime koje ste uneli već je u upotrebi. Molimo izaberite drugo ime.',
+'youremail' => 'Adresa vaše e-pošte *',
+'username' => 'Korisničko ime:',
+'uid' => 'Korisnički ID:',
+'yourrealname' => 'Vaše pravo ime *',
+'yourlanguage' => 'Jezik:',
+'yourvariant' => 'Varijanta:',
+'yournick' => 'Nadimak:',
+'badsig' => 'Greška u potpisu; proverite HTML tagove.',
+'email' => 'E-pošta',
+'prefs-help-email-enotif' => 'Ova adresa se takođe koristi da vam se šalju obaveštenja preko e-pošte ako ste omogućili tu opciju.',
+'prefs-help-realname' => '* Pravo ime (opciono): ako izaberete da date ime, ovo će biti korišćeno za pripisivanje za vaš rad.',
+'loginerror' => 'Greška pri prijavljivanju',
+'prefs-help-email' => '* E-pošta (opciono): Omogućuje ostalima da vas kontaktiraju preko vaše korisničke strane ili strane za razgovora bez potrebe da odajete svoj identitet.',
+'nocookiesnew' => 'Korisnički nalog je napravljen, ali niste prijavljeni. {{SITENAME}} koristi kolačiće (\'\'cookies\'\') da bi se korisnici prijavili. Vi ste onemogućili kolačiće na svom računaru. Molimo omogućite ih, a onda se prijavite sa svojim novim korisničkim imenom i lozinkom.',
+'nocookieslogin' => '{{SITENAME}} koristi kolačiće (\'\'cookies\'\') da bi se korisnici prijavili. Vi ste onemogućili kolačiće na svom računaru. Molimo omogućite ih i pokušajte ponovo sa prijavom.',
+'noname' => 'Niste izabrali ispravno korisničko ime.',
+'loginsuccesstitle' => 'Prijavljivanje uspešno',
+'loginsuccess' => '\'\'\'Sada ste prijavljeni na {{SITENAME}} kao "$1".\'\'\'',
+'nosuchuser' => 'Ne postoji korisnik sa imenom "$1". Proverite da li ste dobro napisali ili napravite novi korisnički nalog.',
+'nosuchusershort' => 'Ne postoji korisnik sa imenom "$1". Proverite da li ste dobro napisali.',
+'nouserspecified' => 'Morate da naznačite korisničko ime.',
+'wrongpassword' => 'Lozinka koju ste uneli je neispravna. Molimo pokušajte ponovo.',
+'wrongpasswordempty' => 'Lozinka koju ste uneli je prazna. Molimo pokušajte ponovo.',
+'mailmypassword' => 'Pošalji mi lozinku',
+'passwordremindertitle' => '{{SITENAME}} podsetnik za šifru',
+'passwordremindertext' => 'Neko (verovatno vi, sa IP adrese $1)
+je zahtevao da vam pošaljemo novu lozinku za {{SITENAME}} ($4).
+Lozinka za korisnika "$2" je sada "$3".
+Sada treba da se prijavite i promenite svoju lozinku.
+
+Ako je neko drugi podneo ovaj zahtev ili ukoliko ste se setili svoje lozinke i više ne želite da je menjate, možete da ignorišete ovu poruku i nastavite da koristite svoju staru šifru.',
+'noemail' => 'Ne postoji adresa e-pošte za korisnika "$1".',
+'passwordsent' => 'Nova šifra je poslata na adresu e-pošte korisnika "$1".
+Molimo prijavite se pošto je primite.',
+'blocked-mailpassword' => 'Vašoj IP adresi je blokiran pristup uređivanju, iz kog razloga nije moguće koristiti funkciju podsećanja lozinke, radi prevencije izvršenja nedozvoljene akcije.',
+'eauthentsent' => 'E-pošta za potvrdu je poslata na naznačenu adresu e-pošte. Pre nego što se bilo koja druga e-pošta pošalje na nalog, moraćete da pratite uputstva u e-pošti, da biste potvrdili da je nalog zaista vaš.',
+'throttled-mailpassword' => 'Podsetnik lozinke vam je već poslao jednu poruku u zadnjih $1 sati. Radi prevencije izvršenja nedozvoljene akcije, podsetnik šalje samo jednu poruku u roku od $1 sati.',
+'mailerror' => 'Greška pri slanju e-pošte: $1',
+'acct_creation_throttle_hit' => 'Žao nam je, već ste napravili $1 korisnička imena. Više nije dozvoljeno.',
+'emailauthenticated' => 'Vaša adresa e-pošte je potvrđena: $1.',
+'emailnotauthenticated' => 'Vaša adresa e-pošte još uvek nije potvrđena. E-pošta neće biti poslata ni za jednu od sledećih mogućnosti.',
+'noemailprefs' => 'Naznačite adresu e-pošte kako bi ove mogućnosti radile.',
+'emailconfirmlink' => 'Potvrdite vašu adresu e-pošte',
+'invalidemailaddress' => 'Adresa e-pošte ne može biti primljena jer izgleda nije pravilnog formata. Molimo unesite dobro-formatiranu adresu ili ispraznite to polje.',
+'accountcreated' => 'Nalog je napravljen',
+'accountcreatedtext' => 'Korisnički nalog za $1 je napravljen.',
+
+# Edit page toolbar
+'bold_sample' => 'podebljan tekst',
+'bold_tip' => 'podebljan tekst',
+'italic_sample' => 'kurzivan tekst',
+'italic_tip' => 'kurzivan tekst',
+'link_sample' => 'naslov veze',
+'link_tip' => 'unutrašnja veza',
+'extlink_sample' => 'http://www.adresa.com opis adrese',
+'extlink_tip' => 'spoljašnja veza (ne zaboravite prefiks http://)',
+'headline_sample' => 'Naslov',
+'headline_tip' => 'Naslov drugog nivoa',
+'math_sample' => 'Ovde unesite formulu',
+'math_tip' => 'Matematička formula (LaTeX)',
+'nowiki_sample' => 'Dodaj neformatirani tekst ovde',
+'nowiki_tip' => 'Ignoriši viki formatiranje',
+'image_sample' => 'ime_slike.jpg',
+'image_tip' => 'Uklopljena slika',
+'media_sample' => 'ime_medija_fajla.mp3',
+'media_tip' => 'Putanja ka multimedijalnom fajlu',
+'sig_tip' => 'Vaš potpis sa trenutnim vremenom',
+'hr_tip' => 'Horizontalna linija',
+
+# Edit pages
+#
+'summary' => 'Opis izmene',
+'subject' => 'Tema/naslov',
+'minoredit' => 'Ovo je mala izmena',
+'watchthis' => 'Nadgledaj ovaj članak',
+'savearticle' => 'Snimi stranicu',
+'preview' => 'Pretpregled',
+'showpreview' => 'Prikaži pretpregled',
+'showlivepreview' => 'Živi pretpregled',
+'showdiff' => 'Prikaži promene',
+'anoneditwarning' => 'Niste prijavljeni. Vaša IP adresa će biti zabeležena u istoriji izmena ove strane.',
+'missingsummary' => '\'\'\'Podsetnik:\'\'\' Niste uneli opis izmene. Ukoliko kliknete Snimi stranicu ponovo, vaše izmene će biti snimljene bez opisa.',
+'missingcommenttext' => 'Molimo unestite komentar ispod.',
+'missingcommentheader' => "'''Podsetnik:''' Niste naveli naslov ovog komentara. Ukoliko kliknete ''Snimi ponovo'', vaš komentar će biti snimljen bez naslova.",
+'blockedtitle' => 'Korisnik je blokiran',
+'blockedtext' => '<big>\'\'\'Vaše korisničko ime ili IP adresa je blokirano.\'\'\'</big>
+
+Blokirao vas je korisnik $1. Razlog za blokiranje je \'\'$2\'\'.
+
+Možete kontaktirati korisnika $1 ili nekog drugog [[{{ns:project}}:Administratori|administratora]] kako biste razgovarali o blokadi. Ne možete da koristite opciju "Pošalji e-poštu ovom korisniku" ukoliko nemate valjanu adresu e-pošte navedenu u vašim [[{ns:special}}:Preferences|podešavanjima]]. Vaša trenutna IP adresa je $3. Molimo uključite ovo u svaki vaš zahtev.',
+'blockedoriginalsource' => 'Izvor \'\'\'$1\'\'\' je prikazan ispod:',
+'blockededitsource' => 'Tekst \'\'\'vaših izmena\'\'\' za \'\'\'$1\'\'\' je prikazan ispod:',
+'whitelistedittitle' => 'Obavezno je prijavljivanje za uređivanje',
+'whitelistedittext' => 'Morate da se [[{{ns:special}}:Userlogin|prijavite]] da biste menjali članke.',
+'whitelistreadtitle' => 'Obavezno je prijavljivanje za čitanje',
+'whitelistreadtext' => 'Morate da se [[{{ns:special}}:Userlogin|prijavite]] da biste čitali članke.',
+'whitelistacctitle' => 'Nije vam dozvoljeno da napravite nalog',
+'whitelistacctext' => 'Da bi vam bilo dozvoljeno da pravite naloge na ovom vikiju morate da se [[{{ns:special}}:Userlogin|prijavite]] i imate odgovarajuća ovlašćenja.',
+'confirmedittitle' => 'Potrebna je potvrda adrese e-pošte za uređivanje',
+'confirmedittext' => 'Morate potvrditi vašu adresu e-pošte pre uređivanja strana. Molimo postavite i potvrdite adresu vaše e-pošte preko vaših [[{{ns:special}}:Preferences|korisničkih podešavanja]].',
+'loginreqtitle' => 'Potrebno [[{{ns:special}}:Userlogin|prijavljivanje]]',
+'loginreqlink' => 'prijava',
+'loginreqpagetext' => 'Morate $1 da biste videli ostale strane.',
+'accmailtitle' => 'Lozinka je poslata.',
+'accmailtext' => 'Lozinka za nalog "$1" je poslata na adresu $2.',
+'newarticle' => '(Novi)',
+'newarticletext' => 'Pratili ste vezu ka stranici koja još ne postoji.
+Da biste je napravili, počnite da kucate u polju ispod
+(pogledajte [[{{ns:help}}:Sadržaj|pomoć]] za više informacija).
+Ako ste došli ovde greškom, samo kliknite dugme \'\'\'back\'\'\' dugme vašeg brauzera.',
+'anontalkpagetext' => '---- \'\'Ovo je stranica za razgovor za anonimnog korisnika koji još nije napravio nalog ili ga ne koristi. Zbog toga moramo da koristimo brojčanu IP adresu kako bismo identifikovali njega ili nju. Takvu adresu može deliti više korisnika. Ako ste anonimni korisnik i mislite da su vam upućene nebitne primedbe, molimo vas da [[{{ns:special}}:Userlogin|napravite nalog ili se prijavite]] da biste izbegli buduću zabunu sa ostalim anonimnim korisnicima.\'\'',
+'noarticletext' => 'Trenutno nema teksta na ovoj stranici. Možete [[{{ns:special}}:Search/{{PAGENAME}}|pretražiti ovaj naziv]] u ostalim stranicama ili [{{fullurl:{{FULLPAGENAME}}|action=edit}} urediti ovu stranicu].',
+'clearyourcache' => '\'\'\'Zapamtite:\'\'\' Nakon snimanja, možda morate očistiti keš vašeg brauzera da biste videli promene. \'\'\'Mozilla / Firefox / Safari:\'\'\' držite \'\'Shift\'\' dok klikćete \'\'Reload\'\' ili pritisnite \'\'Shift+Ctrl+R\'\' (\'\'Cmd-Shift-R\'\' na \'\'Apple Mac\'\' mašini); \'\'\'IE:\'\'\' držite \'\'Ctrl\'\' dok klikćete \'\'Refresh\'\' ili pritisnite \'\'Ctrl-F5\'\'; \'\'\'Konqueror:\'\'\': samo kliknite \'\'Reload\'\' dugme ili pritisnite \'\'F5\'\'; korisnici \'\'\'Opera\'\'\' brauzera možda moraju da u potpunosti očiste svoj keš preko \'\'Tools→Preferences\'\'.',
+'usercssjsyoucanpreview' => '<strong>Savet:</strong> Korisitite \'Prikaži pretpregled\' dugme da testirate svoj novi CSS/JS pre snimanja.',
+'usercsspreview' => '\'\'\'Zapamtite ovo je samo pretpregled vašeg CSS i da još uvek nije snimljen!\'\'\'',
+'userjspreview' => '\'\'\'Zapamtite ovo je samo pretpregled vaše JavaScript-e i da još uvek nije snimljen!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Pažnja:\'\'\' Ne postoji koža "$1". Zapamtite da lične .css i .js koriste mala početna slova, npr. Korisnik:Petar/monobook.css a ne Korisnik:Petar/Monobook.css.',
+'updated' => '(Ažurirano)',
+'note' => '<strong>Napomena:</strong>',
+'previewnote' => '<strong>Ovo samo pretpregled; izmene još nisu sačuvane!</strong>',
+'session_fail_preview' => '<strong>Žao nam je! Nismo mogli da obradimo vašu izmenu zbog gubitka podataka seanse. Molimo pokušajte kasnije. Ako i dalje ne radi, pokušajte da se odjavite i ponovo prijavite.</strong>',
+'previewconflict' => 'Ovaj pretpregled oslikava kako će tekst u
+tekstualnom polju izgledati ako se odlučite da ga snimite.',
+'session_fail_preview_html' => '<strong>Žao nam je! Nismo mogli da obradimo vašu izmenu zbog gubitka podataka seanse.</strong>
+
+\'\'Zbog toga što ova viki ima omogućen sirov HTML, pretpregled je sakriven kao predostrožnost protiv JavaScript napada.\'\'
+
+<strong>Ako ste pokušali da napravite pravu izmenu, molimo pokušajte ponovo. Ako i dalje ne radi, pokušajte da se odjavite i ponovo prijavite.</strong>',
+'importing' => 'Uvoz u toku: $1',
+'editing' => 'Uređujete $1',
+'editinguser' => 'Uređujete $1',
+'editingsection' => 'Uređujete $1 (deo)',
+'editingcomment' => 'Uređujete $1 (komentar)',
+'editconflict' => 'Sukobljene izmene: $1',
+'explainconflict' => 'Neko drugi je promenio ovu stranicu otkad ste vi počeli da je menjate.
+Gornje tekstualno polje sadrži tekst stranice kakav trenutno postoji.
+Vaše izmene su prikazane u donjem tekstu.
+Moraćete da unesete svoje promene u postojeći tekst.
+<b>Samo</b> tekst u gornjem tekstualnom polju će biti snimljen kada
+pritisnete "Snimi stranicu".<br />',
+'yourtext' => 'Vaš tekst',
+'storedversion' => 'Uskladištena verzija',
+'nonunicodebrowser' => '<strong>UPOZORENJE: Vaš brauzer ne podržava unikod. Molimo promenite ga pre nego što počnete sa uređivanjem članka.</strong>',
+'editingold' => '<strong>PAŽNJA: Vi menjate stariju reviziju ove stranice.
+Ako je snimite, sve promene učinjene od ove revizije biće izgubljene.</strong>',
+'yourdiff' => 'Razlike',
+'copyrightwarning' => 'Napomena: Za sve vaše doprinose se smatra da su izdati pod $2 (vidite $1 za detalje). Ako ne želite da se vaši doprinosi nemilosrdno menjaju, ne šaljite ih ovde.<br />
+Takođe nam obećavate da ste ovo sami napisali ili prekopirali iz izvora u javnom vlasništvu ili sličnog slobodnog izvora.
+<strong>NE ŠALJITE RADOVE ZAŠTIĆENE AUTORSKIM PRAVIMA BEZ DOZVOLE!</strong>',
+'copyrightwarning2' => 'Napomena: Sve vaše doprinose ostali korisnici mogu da menjaju ili uklone. Ako ne želite da se vaši doprinosi nemilosrdno menjaju, ne šaljite ih ovde.<br />
+Takođe nam obećavate da ste ovo sami napisali ili prekopirali iz izvora u javnom vlasništvu ili sličnog slobodnog izvora (vidite $1 za detalje).
+<strong>NE ŠALJITE RADOVE ZAŠTIĆENE AUTORSKIM PRAVIMA BEZ DOZVOLE!</strong>',
+'longpagewarning' => '<strong>PAŽNJA: Ova stranica ima $1 kilobajta; neki brauzeri imaju problema sa uređivanjem strana koje imaju blizu ili više od 32 kilobajta. Molimo vas da razmotrite razbijanje stranice na manje delove.</strong>',
+'longpageerror' => '<strong>GREŠKA: Tekst koji snimate je velik $1 kilobajta, što je veće od maksimalno dozvoljene veličine koja iznosi $2 kilobajta. Nemoguće je snimiti stranicu.</strong>',
+'readonlywarning' => '<strong>PAŽNJA: Baza je upravo zaključana zbog održavanja,
+tako da sada nećete moći da snimite svoje izmene. Možda bi bilo dobro da iskopirate tekst u neki editor teksta i snimite ga za kasnije.</strong>',
+'protectedpagewarning' => '<strong>PAŽNJA: Ova stranica je zaključana tako da samo korisnici sa
+administratorskim privilegijama mogu da je menjaju. Uverite se
+da pratite [[{{ns:project}}:Pravila o zaštiti stranica|pravila o zaštiti stranica]].',
+'semiprotectedpagewarning' => '\'\'\'Napomena:\'\'\' Ova stranica je zaključana tako da je samo registrovani korisnici mogu uređivati.',
+'templatesused' => 'Šabloni koji se koriste na ovoj stranici:',
+'edittools' => '<!-- Tekst odavde će biti pokazan ispod formulara za uređivanje i slanje slika. -->',
+'nocreatetitle' => 'Pravljenje stranice ograničeno',
+'nocreatetext' => 'Na ovom sajtu je ograničeno pravljenje novih stranica. Možete se vratiti i urediti već postojeću stranu ili [[Posebno:Userlogin|se prijaviti ili napraviti nalog]].',
+'cantcreateaccounttitle' => 'Ne može da se napravi nalog',
+'cantcreateaccounttext' => 'Pravljenje naloga sa ove IP adrese (<b>$1</b>) je blokirano.
+Ovo je verovatno zbog učestalog vandalizma iz vaše škole ili Internet servis provajdera.',
+
+# History pages
+#
+'revhistory' => 'Istorija izmena',
+'viewpagelogs' => 'Pogledaj protokole za ovu stranu',
+'nohistory' => 'Ne postoji istorija izmena za ovu stranicu.',
+'revnotfound' => 'Revizija nije pronađena',
+'revnotfoundtext' => 'Starija revizija ove stranice koju ste zatražili nije nađena.
+Molimo vas da proverite URL koji ste upotrebili da biste pristupili ovoj stranici.',
+'loadhist' => 'Učitavam istoriju stranice',
+'currentrev' => 'Trenutna revizija',
+'revisionasof' => 'Revizija od $1',
+'revision-info' => 'Revizija od $1; $2',
+'previousrevision' => '← Prethodna revizija',
+'nextrevision' => 'Sledeća revizija →',
+'currentrevisionlink' => 'Trenutna revizija',
+'cur' => 'tren',
+'next' => 'sled',
+'last' => 'posl',
+'orig' => 'orig',
+'histlegend' => 'Odabiranje razlika: odaberite kutijice revizija za upoređivanje i pritisnite enter ili dugme na dnu.<br />
+Objašnjenje: (tren) = razlika sa trenutnom verzijom,
+(posl) = razlika sa prethodnom verzijom, M = mala izmena',
+'deletedrev' => '[obrisan]',
+'histfirst' => 'Najranije',
+'histlast' => 'Poslednje',
+'rev-deleted-comment' => '(komentar uklonjen)',
+'rev-deleted-user' => '(korisničko ime uklonjeno)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Revizija ove stranice je uklonjena iz javnih arhiva.
+Moguće da ima više detalja u [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} istoriji brisanja].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Revizija ove stranice je uklonjena iz javnih arhiva.
+Kao administrator, možete da je pogledate;
+Moguće da ima više detalja u [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} istoriji brisanja].
+</div>',
+'rev-delundel' => 'pokaži/sakrij',
+
+'history-feed-title' => 'Istorija revizija',
+'history-feed-description' => 'Istorija revizija za ovu stranu na vikiju',
+'history-feed-item-nocomment' => '$1, $2', # user at time
+'history-feed-empty' => 'Tražena stranica ne postoji.
+Moguće da je obrisana iz vikija ili preimenovana.
+Pokušajte [[Posebno:Search|da pretražite viki]] za relevantne nove strane.',
+
+# Revision deletion
+#
+'revisiondelete' => 'Obriši/vrati reviziju',
+'revdelete-nooldid-title' => 'Nema odabrane revizije',
+'revdelete-nooldid-text' => 'Niste odabrali željenu reviziju ili revizije kako biste uključili ove funkcije.',
+'revdelete-selected' => 'Izabrano revizija od [[:$1]]:',
+'revdelete-text' => 'Obrisane revizije će se i dalje pojavljivati na istoriji stranice,
+ali će njihov sadržaj biti skriven javnosti.
+
+Ostali administratori na ovoj Vikipediji će i dalje imati mogućnost da vide skriveni sadržaj i moći će da ga vrate ponovo putem ove iste komande, sve ukoliko nisu primenjene dodatne restrikcije operatora sajta.',
+'revdelete-legend' => 'Postavi restrikcije revizija:',
+'revdelete-hide-text' => 'Sakrij tekst revizije',
+'revdelete-hide-comment' => 'Sakrij opis izmene',
+'revdelete-hide-user' => 'Sakrij korisničko ime/IP adresu korisnika koji je uređivao stranicu',
+'revdelete-hide-restricted' => 'Primeni ove restrikcije za administratore isto kao i za ostale',
+'revdelete-log' => 'Komentar protokola:',
+'revdelete-submit' => 'Primeni na izabrane revizije',
+'revdelete-logentry' => 'promenjen prikaz revizije za [[$1]]',
+
+# Diffs
+#
+'difference' => '(Razlika između revizija)',
+'loadingrev' => 'učitavam reviziju za razliku',
+'lineno' => 'Linija $1:',
+'editcurrent' => 'Izmeni trenutnu verziju ove stranice',
+'selectnewerversionfordiff' => 'Izaberi noviju verziju za upoređivanje',
+'selectolderversionfordiff' => 'Izaberi stariju verziju za upoređivanje',
+'compareselectedversions' => 'Uporedi označene verzije',
+
+# Search results
+#
+'searchresults' => 'Rezultati pretrage',
+'searchresulttext' => 'Za više informacija o pretraživanju sajta {{SITENAME}}, pogledajte [[{{ns:project}}:Pretraživanje|Pretraživanje sajta {{SITENAME}}]].',
+'searchsubtitle' => 'Tražili ste \'\'\'[[:$1]]\'\'\'',
+'searchsubtitleinvalid' => 'Tražili ste \'\'\'$1\'\'\'',
+'badquery' => 'Loše oblikovan upit za pretragu',
+'badquerytext' => 'Nismo mogli da obradimo vaš upit.
+Ovo je verovatno zbog toga što ste pokušali da tražite
+reč kraću od tri slova, što trenutno nije podržano.
+Takođe je moguće da ste pogrešno ukucali izraz, na
+primer "riba ima ima krljušti".
+Molimo vas pokušajte nekim drugim upitom.',
+'matchtotals' => 'Upit "$1" je nađen u $2 naslova članaka
+i tekst $3 članaka.',
+'noexactmatch' => 'Ne postoji stranica sa naslovom "$1". Možete [[$1|napraviti ovu stranicu]].',
+'titlematches' => 'Naslov stranice odgovara',
+'notitlematches' => 'Nijedan naslov stranice ne odgovara',
+'textmatches' => 'Tekst stranice odgovara',
+'notextmatches' => 'Nijedan tekst stranice ne odgovara',
+'prevn' => 'prethodnih $1',
+'nextn' => 'sledećih $1',
+'viewprevnext' => 'Pogledaj ($1) ($2) ($3).',
+'showingresults' => 'Prikazujem ispod <b>$1</b> rezultata počev od #<b>$2</b>.',
+'showingresultsnum' => 'Prikazujem ispod <b>$3</b> rezultate počev od #<b>$2</b>.',
+'nonefound' => '\'\'\'Napomena\'\'\': neuspešne pretrage su
+često izazvane traženjem čestih reči kao "je" ili "od",
+koje nisu indeksirane, ili navođenjem više od jednog izraza za traženje (samo stranice
+koje sadrže sve izraze koji se traže će se pojaviti u rezultatu).',
+'powersearch' => 'Traži',
+'powersearchtext' => 'Pretraga u imenskim prostorima:<br />$1<br />$2 Izlistaj preusmerenja<br />Traži $3 $9',
+'searchdisabled' => 'Pretraga za sajt {{SITENAME}} je onemogućena. U međuvremenu, možete koristiti Gugl pretragu. Imajte na umu da indeksi Gugla za sajt {{SITENAME}} mogu biti zastareli.',
+
+'blanknamespace' => '(Glavno)',
+
+# Preferences page
+#
+'preferences' => 'Podešavanja',
+'mypreferences' => 'Moja podešavanja',
+'prefsnologin' => 'Niste prijavljeni',
+'prefsnologintext' => 'Morate biti [[{{ns:special}}:Userlogin|prijavljeni]]
+da biste podešavali korisnička podešavanja.',
+'prefsreset' => 'Vraćena su uskladištena podešavanja.',
+'qbsettings' => 'Brza paleta',
+'changepassword' => 'Promeni lozinku',
+'skin' => 'Koža',
+'math' => 'Matematike',
+'dateformat' => 'Format datuma',
+'datedefault' => 'Nije bitno',
+'datetime' => 'Datum i vreme',
+'math_failure' => 'Neuspeh pri parsiranju',
+'math_unknown_error' => 'nepoznata greška',
+'math_unknown_function' => 'nepoznata funkcija',
+'math_lexing_error' => 'rečnička greška',
+'math_syntax_error' => 'sintaksna greška',
+'math_image_error' => 'PNG konverzija neuspešna; proverite tačnu instalaciju latex-a, dvips-a, gs-a i convert-a',
+'math_bad_tmpdir' => 'Ne mogu da napišem ili napravim privremeni math direktorijum',
+'math_bad_output' => 'Ne mogu da napišem ili napravim direktorijum za math izlaz.',
+'math_notexvc' => 'Nedostaje izvršno texvc; molimo pogledajte math/README da biste podesili.',
+'prefs-personal' => 'Korisnička podešavanja',
+'prefs-rc' => 'Skorašnje izmene',
+'prefs-watchlist' => 'Spisak nadgledanja',
+'prefs-watchlist-days' => 'Broj dana koji treba da se vidi na spisku nadgledanja:',
+'prefs-watchlist-edits' => 'Broj izmena koji treba da se vidi na proširenom spisku nadgledanja:',
+'prefs-misc' => 'Razno',
+'saveprefs' => 'Sačuvaj',
+'resetprefs' => 'Vrati',
+'oldpassword' => 'Stara lozinka:',
+'newpassword' => 'Nova lozinka:',
+'retypenew' => 'Ponovo otkucajte novu lozinku:',
+'textboxsize' => 'Veličine tekstualnog polja',
+'rows' => 'Redova',
+'columns' => 'Kolona',
+'searchresultshead' => 'Pretraga',
+'resultsperpage' => 'Pogodaka po stranici:',
+'contextlines' => 'Linija po pogotku:',
+'contextchars' => 'Karaktera konteksta po liniji:',
+'stubthreshold' => 'Granica za prikazivanje klica:',
+'recentchangescount' => 'Broj naslova u skorašnjim izmenama:',
+'savedprefs' => 'Vaša podešavanja su sačuvana.',
+'timezonelegend' => 'Vremenska zona',
+'timezonetext' => 'Broj sati za koji se vaše lokalno vreme razlikuje od serverskog vremena (UTC).',
+'localtime' => 'Lokalno vreme',
+'timezoneoffset' => 'Odstupanje¹',
+'servertime' => 'Vreme na serveru',
+'guesstimezone' => 'Popuni iz brauzera',
+'allowemail' => 'Omogući e-poštu od drugih korisnika',
+'defaultns' => 'Po standardu traži u ovim imenskim prostorima:',
+'default' => 'standard',
+'files' => 'Fajlovi',
+
+# User rights
+'userrights-lookup-user' => 'Upravljaj korisničkim grupama',
+'userrights-user-editname' => 'Unesite korisničko ime:',
+'editusergroup' => 'Menjaj grupe korisnika',
+
+'userrights-editusergroup' => 'Promeni korisničke grupe',
+'saveusergroups' => 'Sačuvaj korisničke grupe',
+'userrights-groupsmember' => 'Član:',
+'userrights-groupsavailable' => 'Dostupne grupe:',
+'userrights-groupshelp' => 'Odabrane grupe od kojih želite da se ukloni korisnik ili da se doda.
+Neodabrane grupe neće biti promenjene. Možete da deselektujete grupu koristeći CTRL + levi klik',
+
+# Groups
+'group' => 'Grupa:',
+'group-bot' => 'botovi',
+'group-sysop' => 'administratori',
+'group-bureaucrat' => 'birokrate',
+'group-all' => '(svi)',
+
+'group-bot-member' => 'bot',
+'group-sysop-member' => 'administrator',
+'group-bureaucrat-member' => 'birokrata',
+
+'grouppage-bot' => 'Project:Botovi',
+'grouppage-sysop' => 'Project:Spisak administratora',
+'grouppage-bureaucrat' => 'Project:Birokrate',
+
+# Recent changes
+#
+'changes' => 'izmene',
+'recentchanges' => 'Skorašnje izmene',
+'recentchangestext' => 'Ovde pratite najskorije izmene na vikiju.',
+
+'rcnote' => 'Ispod je poslednjih <strong>$1</strong> promena u poslednjih <strong>$2</strong> dana.',
+'rcnotefrom' => 'Ispod su promene od <b>$2</b> (do <b>$1</b> prikazano).',
+'rclistfrom' => 'Pokaži nove promene počev od $1',
+'rcshowhideminor' => '$1 male izmene',
+'rcshowhidebots' => '$1 botove',
+'rcshowhideliu' => '$1 prijavljene korisnike',
+'rcshowhideanons' => '$1 anonimne korisnike',
+'rcshowhidepatr' => '$1 patrolirane izmene',
+'rcshowhidemine' => '$1 sopstvene izmene',
+'rclinks' => 'Pokaži poslednjih $1 promena u poslednjih $2 dana<br />$3',
+'diff' => 'razl',
+'hist' => 'ist',
+'hide' => 'sakrij',
+'show' => 'pokaži',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1 korisnik/a koji nadgleda/ju]',
+'rc_categories' => 'Ograniči na kategorije (razdvoji sa "|")',
+'rc_categories_any' => 'Bilo koji',
+
+# Upload
+#
+'upload' => 'Pošalji fajl',
+'uploadbtn' => 'Pošalji fajl',
+'reupload' => 'Ponovo pošalji',
+'reuploaddesc' => 'Vrati se na upitnik za slanje.',
+'uploadnologin' => 'Niste prijavljeni',
+'uploadnologintext' => 'Morate biti [[{{ns:special}}:Userlogin|prijavljeni]]
+da biste slali fajlove.',
+'upload_directory_read_only' => 'Na direktorijum za slanje ($1) server ne može da piše.',
+'uploaderror' => 'Greška pri slanju',
+'uploadtext' => 'Koristite donji obrazac da pošaljete fajlove. Za gledanje ili pretraživanje već poslatih slika, idite na [[{{ns:special}}:Imagelist|spisak poslatih fajlova]]. Slanja i brisanja se beleže u [[{{ns:special}}:Log/upload|istoriji slanja]]
+
+Da biste ubacili sliku na stranu, koristite vezu u obliku
+\'\'\'<nowiki>[[{{ns:image}}:Fajl.jpg]]</nowiki>\'\'\',
+\'\'\'<nowiki>[[{{ns:image}}:Fajl.png|opis slike]]</nowiki>\'\'\' ili
+\'\'\'<nowiki>[[{{ns:media}}:Fajl.ogg]]</nowiki>\'\'\' za direktno povezivanje na fajl.',
+'uploadlog' => 'istorija slanja',
+'uploadlogpage' => 'istorija slanja',
+'uploadlogpagetext' => 'Ispod je spisak najskorijih slanja.',
+'filename' => 'Ime fajla',
+'filedesc' => 'Opis',
+'fileuploadsummary' => 'Opis:',
+'filestatus' => 'Status autorskog prava',
+'filesource' => 'Izvor',
+'copyrightpage' => 'Project:Autorska prava',
+'copyrightpagename' => 'Autorska prava projekta {{SITENAME}}',
+'uploadedfiles' => 'Poslati fajlovi',
+'ignorewarning' => 'Ignoriši upozorenja i snimi datoteku.',
+'ignorewarnings' => 'Ignoriši sva upozorenja',
+'minlength' => 'Imena slika moraju imati bar tri slova.',
+'illegalfilename' => 'Fajl "$1" sadrži karaktere koji nisu dozvoljeni u nazivima stranica. Molimo Vas promenite ime fajla i ponovo ga pošaljite.',
+'badfilename' => 'Ime slike je promenjeno u "$1".',
+'badfiletype' => '".$1" nije preporučeni format slike.',
+'largefile' => 'Preporučuje se da slike ne pređu veličinu od $1 bajtova; ova slika ima $2 bajtova.',
+'largefileserver' => 'Ovaj fajl je veći nego što je podešeno da server dozvoli.',
+'emptyfile' => 'Fajl koji ste poslali deluje da je prazan. Ovo je moguće zbog greške u imenu fajla. Molimo proverite da li stvarno želite da pošaljete ovaj fajl.',
+'fileexists' => 'Fajl sa ovim imenom već postoji. Molimo proverite $1 ako niste sigurni da li želite da ga promenite.',
+'fileexists-forbidden' => 'Fajl sa ovim imenom već postoji; molimo vratite se i pošaljite ovaj fajl pod novim imenom. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Fajl sa ovim imenom već postoji u zajedničkoj ostavi; molimo vratite se i pošaljite ovaj fajl pod novim imenom. [[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'Uspešno slanje',
+'fileuploaded' => 'Fajl "$1" je uspešno poslat.
+Molim pratite ovu vezu: $2 do stranice za opis i unesite
+informacije o fajlu, npr. odakle je, kada i
+ko ga je napravio, i bilo šta drugo što znate o njemu.
+Ako je ovo slika, možete je uneti ovako: <tt><nowiki>[[Image:$1|thumb|Opis]]</nowiki></tt>',
+'uploadwarning' => 'Upozorenje pri slanju',
+'savefile' => 'Snimi fajl',
+'uploadedimage' => 'poslao "[[$1]]"',
+'uploaddisabled' => 'Slanje fajlova je isključeno.',
+'uploaddisabledtext' => 'Slanja fajlova su onemogućena na ovom vikiju.',
+'uploadscripted' => 'Ovaj fajl sadrži HTML ili kod skripte koje internet brauzer može pogrešno da interpretira.',
+'uploadcorrupt' => 'Fajl je neispravan ili ima netačnu ekstenziju. Molimo proverite fajl i pošaljite ga ponovo.',
+'uploadvirus' => 'Fajl sadrži virus! Detalji: $1',
+'sourcefilename' => 'Ime fajla izvora',
+'destfilename' => 'Ciljano ime fajla',
+'watchthisupload' => 'Nadgledaj stranicu',
+'filewasdeleted' => 'Fajl sa ovim imenom je ranije poslat, a kasnije obrisan. Trebalo bi da proverite $1 pre nego što nastavite sa ponovnim slanjem.',
+
+'upload-proto-error' => 'Nekorektni protokol',
+'upload-proto-error-text' => 'Slanje eksternih fajlova zahteva URLove koji počinju sa <code>http://</code> ili <code>ftp://</code>.',
+'upload-file-error' => 'Interna greška',
+'upload-file-error-text' => 'Desila se interna greška pri pokušaju pravljenja privremenog fajla na serveru. Kontaktirajte sistem administratora.',
+'upload-misc-error' => 'Nepoznata greška pri slanju fajla',
+'upload-misc-error-text' => 'Nepoznata greška pri slanju fajla. Proverite da li je URL ispravan i pokušajte ponovo. Ako problem ostane, kontaktirajte sistem administratora.',
+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
+'upload-curl-error6' => "URL nije dostupan",
+'upload-curl-error6-text' => 'URL koji ste uneli nije dostupan. Uradite dupli klik na URL da proverite da li je adresa dostupna.',
+'upload-curl-error28' => 'Tajmaut greška',
+'upload-curl-error28-text' => 'Sajtu je trebalo previše vremena da odgovori. Proverite da li sajt radi, ili sačekajte malo i pokušajte ponovo.',
+
+'license' => 'Licenca',
+'nolicense' => 'Nema',
+'upload_source_url' => ' (validan, javno dostupan URL)',
+'upload_source_file' => ' (fajl na vašem računaru)',
+
+# Image list
+#
+'imagelist' => 'Spisak slika',
+'imagelisttext' => 'Ispod je spisak od \'\'\'$1\'\'\' {{plural:$1|fajla|fajla|fajlova}} poređanih $2.',
+'imagelistforuser' => 'Ovo je spisak slika koje je poslao korisnik $1.',
+'getimagelist' => 'pribavljam spisak slika',
+'ilsubmit' => 'Traži',
+'showlast' => 'Prikaži poslednjih $1 slika poređanih $2.',
+'bydate' => 'po datumu',
+'byname' => 'po imenu',
+'bysize' => 'po veličini',
+'imgdelete' => 'obr',
+'imgdesc' => 'opis',
+'imgfile' => 'fajl',
+'imghistory' => 'istorija slike',
+'imglegend' => 'Objašnjenje: (opis) = prikaži/izmeni opis slike.',
+'revertimg' => 'vrt',
+'deleteimg' => 'obr',
+'deleteimgcompletely' => 'Obriši sve revizije ovog fajla',
+'imghistlegend' => 'Objašnjenje: (tren) = ovo je trenutna slika, (obr) = obriši
+ovu staru verziju, (vrt) = vrati na ovu staru verziju.
+<br /><i>Kliknite na datum da vidite sliku poslatu tog datuma</i>.',
+'imagelinks' => 'Upotreba slike',
+'linkstoimage' => 'Sledeće stranice koriste ovaj fajl:',
+'nolinkstoimage' => 'Nema stranica koje koriste ovaj fajl.',
+'sharedupload' => 'Ova slika je sa zajedničke ostave i možda je koriste ostali projekti.',
+'shareduploadwiki' => 'Molimo pogledajte $1 za dalje informacije.',
+'shareduploadwiki-linktext' => 'strana za opis fajla',
+'noimage' => 'Ne postoji fajl sa ovim imenom, možete ga $1',
+'noimage-linktext' => 'poslati',
+'uploadnewversion-linktext' => 'Pošaljite noviju verziju ovog fajla',
+'imagelist_date' => 'Datum',
+'imagelist_name' => 'Ime',
+'imagelist_user' => 'Korisnik',
+'imagelist_size' => 'Veličina (bajtovi)',
+'imagelist_description' => 'Opis slike',
+'imagelist_search_for' => 'Traži ime slike:',
+
+# Mime search
+#
+'mimesearch' => 'MIME pretraga',
+'mimetype' => 'MIME tip:',
+'download' => 'Preuzmi',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Nenadgledane stranice',
+
+# List redirects
+'listredirects' => 'Spisak preusmerenja',
+
+# Unused templates
+'unusedtemplates' => 'Neiskorišćeni šabloni',
+'unusedtemplatestext' => 'Ova strana navodi sve stranice u imenskom prostoru šablona koje nisu uključene ni na jednoj drugoj strani. Ne zaboravite da proverite ostale veze ka šablonima pre nego što ih obrišete.',
+'unusedtemplateswlh' => 'ostale veze',
+
+# Random redirect
+'randomredirect' => 'Slučajno preusmerenje',
+
+# Statistics
+#
+'statistics' => 'Statistike',
+'sitestats' => 'Statistike sajta',
+'userstats' => 'Statistike korisnika',
+'sitestatstext' => 'Postoji ukupno \'\'\'$1\'\'\' stranica u bazi podataka. Ovaj broj uključuje strane za razgovor, stranice o sajtu, preusmerenja, članke bez ijedne poveznice i ostale stranice koje se ne mogu računati kao članci. Ne računajući njih, postoji \'\'\'$2\'\'\' stranica koje su verovatno legitimni članci.
+
+Na ovaj sajt je poslato \'\'\'$8\'\'\' slika.
+
+Stranice su ukupno pogledane \'\'\'$3\'\'\' puta i \'\'\'$4\'\'\' izmena od postavljanja vikija. Ovo znači da je bilo u proseku \'\'\'$5\'\'\' izmena po stranici i \'\'\'$6\'\'\' pogleda po stranici.
+
+Dužina reda za poslove iznosi \'\'\'$7\'\'\'',
+'userstatstext' => 'Postoji \'\'\'$1\'\'\' registrovanih korisnika, od kojih su \'\'\'$2\'\'\' (ili $4%) administratori (pogledajte $3).',
+'statistics-mostpopular' => 'Najposećenije stranice',
+
+'disambiguations' => 'Stranice za višeznačne odrednice',
+'disambiguationspage' => '{{ns:template}}:Višeznačna odrednica',
+'disambiguationstext' => 'Sledeći članci se povezuju sa <i>višeznačnom odrednicom</i>. Umesto toga, oni bi trebalo da se povezuju sa odgovarajućom temom.<br />Stranica se tretira da je višeznačna odrednica ako je povezana sa $1.<br />Poveznice iz ostalih imenskih prostora <i>nisu</i> navedene ovde.',
+
+'doubleredirects' => 'Dvostruka preusmerenja',
+'doubleredirectstext' => 'Svaki red sadrži veze na prvo i drugo preusmerenje, kao i na prvu liniju teksta drugog preusmerenja, što obično daje "pravi" ciljni članak, na koji bi prvo preusmerenje i trebalo da pokazuje.',
+
+'brokenredirects' => 'Pokvarena preusmerenja',
+'brokenredirectstext' => 'Sledeća preusmerenja su povezana na nepostojeći članak.',
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|bajt|bajta|bajtova}}',
+'ncategories' => '$1 {{PLURAL:$1|kategorija|kategorije|kategorija}}',
+'nlinks' => '$1 {{PLURAL:$1|veza|veze|veza}}',
+'nmembers' => '$1 {{PLURAL:$1|članak|članka|članaka}}',
+'nrevisions' => '$1 {{PLURAL:$1|revizija|revizije|revizija}}',
+'nviews' => '$1 puta pogledano',
+
+'lonelypages' => 'Siročići',
+'lonelypagestext' => 'Sledeće stranice nisu povezane sa drugih stranica na ovom vikiju.',
+'uncategorizedpages' => 'Stranice bez kategorije',
+'uncategorizedcategories' => 'Kategorije bez kategorija',
+'uncategorizedimages' => 'Slike bez kategorija',
+'unusedcategories' => 'Neiskorišćene kategorije',
+'unusedimages' => 'Neiskorišćeni fajlovi',
+'popularpages' => 'Popularne stranice',
+'wantedcategories' => 'Tražene kategorije',
+'wantedpages' => 'Tražene stranice',
+'mostlinked' => 'Najviše povezane strane',
+'mostlinkedcategories' => 'Najviše povezane kategorije',
+'mostcategories' => 'Članci sa najviše kategorija',
+'mostimages' => 'Najviše povezane slike',
+'mostrevisions' => 'Članci sa najviše revizija',
+'allpages' => 'Sve stranice',
+'prefixindex' => 'Spisak prefiksa',
+'randompage' => 'Slučajna stranica',
+'shortpages' => 'Kratke stranice',
+'longpages' => 'Dugačke stranice',
+'deadendpages' => 'Stranice bez internih veza',
+'deadendpagestext' => 'Sledeće stranice ne vežu na druge stranice na ovom vikiju.',
+'listusers' => 'Spisak korisnika',
+'specialpages' => 'Posebne stranice',
+'spheading' => 'Posebne stranice za sve korisnike',
+'restrictedpheading' => 'Zaštićene posebne stranice',
+'recentchangeslinked' => 'Srodne promene',
+'rclsub' => '(na stranice povezane od "$1")',
+'newpages' => 'Nove stranice',
+'newpages-username' => 'Korisničko ime:',
+'ancientpages' => 'Najstariji članci',
+'intl' => 'Međujezičke veze',
+'move' => 'premesti',
+'movethispage' => 'premesti ovu stranicu',
+'unusedimagestext' => '<p>Obratite pažnju da se drugi veb sajtovi
+mogu povezivati na sliku direktnim URL-om, i tako mogu još uvek biti prikazani ovde uprkos
+aktivnoj upotrebi.',
+'unusedcategoriestext' => 'Naredne strane kategorija postoje iako ih ni jedan drugi članak ili kategorija ne koriste.',
+
+'booksources' => 'Štampani izvori',
+'categoriespagetext' => 'Sledeće kategorije već postoje na vikiju',
+'data' => 'Podaci',
+'userrights' => 'Upravljanje korisničkim pravima',
+'groups' => 'Korisničke grupe',
+
+'booksourcetext' => 'Ispod je spisak veza ka drugim sajtovima koji
+prodaju nove i korišćene knjige, i takođe mogu imati daljnje informacije
+o knjigama koje tražite.',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 u $2',
+'version' => 'Verzija',
+'log' => 'Protokoli',
+'alllogstext' => 'Kombinovani prikaz istorija slanja, brisanja, zaštite, blokiranja i administratorskih prava.
+Možete suziti pregled odabirom tipa istorije, korisničkog imena ili tražene stranice.',
+'logempty' => 'Protokol je prazan.',
+
+# Special:Allpages
+'nextpage' => 'Sledeća stranica ($1)',
+'allpagesfrom' => 'Prikaži stranice početno sa:',
+'allarticles' => 'Svi članci',
+'allinnamespace' => 'Sve stranice ($1 imenski prostor)',
+'allnotinnamespace' => 'Sve stranice (koje nisu u $1 imenskom prostoru)',
+'allpagesprev' => 'Prethodna',
+'allpagesnext' => 'Sledeća',
+'allpagessubmit' => 'Idi',
+'allpagesprefix' => 'Prikaži strane sa prefiksom:',
+'allpagesbadtitle' => 'Dati naziv stranice nije dobar ili sadrži međujezički ili interviki prefiks. Moguće je da sadrži karaktere koji ne mogu da se koriste u nazivima.',
+
+# Special:Listusers
+'listusersfrom' => 'Prikaži korisnike počevši od:',
+
+# Email this user
+#
+'mailnologin' => 'Nema adrese za slanje',
+'mailnologintext' => 'Morate biti [[{{ns:special}}:Userlogin|prijavljeni]]
+i imati ispravnu adresu e-pošte u vašim [[Special:Preferences|podešavanjima]]
+da biste slali e-poštu drugim korisnicima.',
+'emailuser' => 'Pošalji e-poštu ovom korisniku',
+'emailpage' => 'Pošalji e-pismo korisniku',
+'emailpagetext' => 'Ako je ovaj korisnik uneo ispravnu adresu e-pošte u
+svoja korisnička podešavanja, upitnik ispod će poslati jednu poruku.
+Adresa e-pošte koju ste vi uneli u svojim korisničkim podešavanjima će se pojaviti
+kao "From" adresa poruke, tako da će primalac moći da odgovori.',
+'usermailererror' => 'Objekat pošte je vratio grešku:',
+'defemailsubject' => '{{SITENAME}} e-pošta',
+'noemailtitle' => 'Nema adrese e-pošte',
+'noemailtext' => 'Ovaj korisnik nije naveo ispravnu adresu e-pošte,
+ili je izabrao da ne prima e-poštu od drugih korisnika.',
+'emailfrom' => 'Od',
+'emailto' => 'Za',
+'emailsubject' => 'Tema',
+'emailmessage' => 'Poruka',
+'emailsend' => 'Pošalji',
+'emailccme' => 'Pošalji mi kopiju moje poruke u moje sanduče e-pošte.',
+'emailccsubject' => 'Kopija vaše poruke na $1: $2',
+'emailsent' => 'Poruka poslata',
+'emailsenttext' => 'Vaša poruka je poslata elektronskom poštom.',
+
+# Watchlist
+'watchlist' => 'Moj spisak nadgledanja',
+'watchlistfor' => '(za \'\'\'$1\'\'\')',
+'nowatchlist' => 'Nemate ništa na svom spisku nadgledanja.',
+'watchlistanontext' => 'Molimo $1 da biste gledali ili menjali stavke na vašem spisku nadgledanja.',
+'watchlistcount' => '\'\'\'Imate $1 {{plural:$1|stavku|stavke|stavki}} na vašem spisku nadgledanja, uključujući strane za razgovor.\'\'\'',
+'clearwatchlist' => 'Obriši spisak nadgledanja',
+'watchlistcleartext' => 'Da li ste sigurni da želite da ih uklonite?',
+'watchlistclearbutton' => 'Obriši spisak nadgledanja',
+'watchlistcleardone' => 'Vaš spisak nadgledanja je obrisan. $1 {{plural:$1|stavka|stavke|stavki}} je uklonjeno.',
+'watchnologin' => 'Niste prijavljeni',
+'watchnologintext' => 'Morate biti [[{{ns:special}}:Userlogin|prijavljeni]] da biste menjali spisak nadgledanja.',
+'addedwatch' => 'Dodato spisku nadgledanja',
+'addedwatchtext' => 'Stranica "[[:$1]]" je dodata vašem [[{{ns:special}}:Watchlist|spisku nadgledanja]] .
+Buduće promene na ovoj stranici i njoj pridruženoj stranici za razgovor biće navedene ovde, i stranica će biti \'\'\'podebljana\'\'\' u [[{{ns:special}}:Recentchanges|spisku skorašnjih izmena]] da bi se lakše uočila.
+
+Ako kasnije želite da uklonite stranicu sa vašeg spiska nadgledanja, kliknite na "ne nadgledaj" na bočnoj paleti.',
+'removedwatch' => 'Uklonjeno sa spiska nadgledanja',
+'removedwatchtext' => 'Stranica "[[:$1]]" je uklonjena sa vašeg spiska nadgledanja.',
+'watch' => 'nadgledaj',
+'watchthispage' => 'Nadgledaj ovu stranicu',
+'unwatch' => 'Prekini nadgledanje',
+'unwatchthispage' => 'Prekini nadgledanje',
+'notanarticle' => 'Nije članak',
+'watchnochange' => 'Ništa što nadgledate nije promenjeno u prikazanom vremenu.',
+'watchdetails' => '* $1 stranica nadgledano ne računajući stranice za razgovor;
+* [[{{ns:special}}:Watchlist/edit|prikaži i menjaj potpuni spisak]]
+* [[{{ns:special}}:Watchlist/clear|ukloni sve stranice]]',
+'wlheader-enotif' => '* Obaveštavanje e-poštom je omogućeno.',
+'wlheader-showupdated' => '* Stranice koje su izmenjene od kada ste ih poslednji put posetili su prikazane \'\'\'podebljano\'\'\'',
+'watchmethod-list' => 'proveravam ima li skorašnjih izmena u nadgledanim stranicama',
+'watchmethod-recent' => 'proveravam ima li nadgledanih stranica u skorašnjim izmenama',
+'removechecked' => 'Ukloni obeležene unose sa spiska nadgledanja',
+'watchlistcontains' => 'Vaš spisak nadgledanja sadrži $1 stranica.',
+'watcheditlist' => 'Ovde je azbučni spisak stranica
+koje nadgledate. Obeležite kućice stranica koje želite da uklonite
+sa svog spiska nadgledanja i kliknite na dugme \'ukloni obeležene\'
+na dnu ekrana (uklanjanje stranice takođe uklanja i prateću stranu za razgovor i obrnuto).',
+'removingchecked' => 'Uklanjam obeležene stvari sa spiska nadgledanja...',
+'couldntremove' => 'Ne mogu da uklonim stavku \'$1\'...',
+'iteminvalidname' => 'Problem sa stavkom \'$1\', neispravno ime...',
+'wlnote' => 'Ispod je poslednjih $1 izmena u poslednjih <b>$2</b> sati.',
+'wlshowlast' => 'Prikaži poslednjih $1 sati $2 dana $3',
+'wlsaved' => 'Ovo je sačuvana verzija vašeg spiska nadgledanja.',
+'wlhideshowown' => '$1 moje izmene.',
+'wlhideshowbots' => '$1 izmena botova.',
+'wldone' => 'Gotovo.',
+
+'enotif_mailer' => '{{SITENAME}} pošta obaveštenja',
+'enotif_reset' => 'Označi sve strane kao posećene',
+'enotif_newpagetext' => 'Ovo je novi članak.',
+'changed' => 'promenjena',
+'created' => 'napravljena',
+'enotif_subject' => '{{SITENAME}} stranica $PAGETITLE je bila $CHANGEDORCREATED od strane $PAGEEDITOR',
+'enotif_lastvisited' => 'Pogledajte $1 za sve promene od vaše poslednje posete.',
+'enotif_body' => 'Dragi $WATCHINGUSERNAME,
+
+{{SITENAME}} stranicaa $PAGETITLE je bila $CHANGEDORCREATED ($PAGEEDITDATE) od strane $PAGEEDITOR,
+pogledajte $PAGETITLE_URL za trenutnu verziju.
+
+$NEWPAGE
+
+Opis izmene urednika: $PAGESUMMARY $PAGEMINOREDIT
+
+Kontaktirajte urednika:
+pošta: $PAGEEDITOR_EMAIL
+viki: $PAGEEDITOR_WIKI
+
+Neće biti drugih obaveštenja u slučaju daljih promena ukoliko ne posetite ovu stranu.
+Takođe možete da resetujete zastavice za obaveštenja za sve vaše nadgledane strane na vašem spisku nadgledanja.
+
+ Vaš prijateljski {{SITENAME}} sistem obaveštavanja
+
+--
+Da promenite podešavanja vezana za spisak nadgledanja posetite
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Fidbek i dalja pomoć:
+{{fullurl:{{ns:help}}:Sadržaj}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Obriši stranicu',
+'confirm' => 'Potvrdi',
+'excontent' => 'sadržaj je bio: \'$1\'',
+'excontentauthor' => 'sadržaj je bio: \'$1\' (a jedinu izmenu je napravio \'$2\')',
+'exbeforeblank' => 'sadržaj pre brisanja je bio: \'$1\'',
+'exblank' => 'stranica je bila prazna',
+'confirmdelete' => 'Potvrdi brisanje',
+'deletesub' => '(Brišem "$1")',
+'historywarning' => 'Pažnja: stranica koju želite da obrišete ima istoriju:',
+'confirmdeletetext' => 'Na putu ste da trajno obrišete stranicu
+ili sliku zajedno sa njenom istorijom iz baze podataka.
+Molimo vas potvrdite da nameravate da uradite ovo, da razumete
+posledice, i da ovo radite u skladu sa
+[[{{ns:project}}:Pravila i smernice|pravilima]].',
+'actioncomplete' => 'Akcija završena',
+'deletedtext' => 'Članak "$1" je obrisan.
+Pogledajte $2 za zapis o skorašnjim brisanjima.',
+'deletedarticle' => 'obrisan "[[$1]]"',
+'dellogpage' => 'istorija brisanja',
+'dellogpagetext' => 'Ispod je spisak najskorijih brisanja.',
+'deletionlog' => 'istorija brisanja',
+'reverted' => 'Vraćeno na raniju reviziju',
+'deletecomment' => 'Razlog za brisanje',
+'imagereverted' => 'Vraćanje na raniju verziju je uspešno.',
+'rollback' => 'Vrati izmene',
+'rollback_short' => 'Vrati',
+'rollbacklink' => 'vrati',
+'rollbackfailed' => 'Vraćanje nije uspelo',
+'cantrollback' => 'Ne mogu da vratim izmenu; poslednji autor je ujedno i jedini.',
+'alreadyrolled' => 'Ne mogu da vratim poslednju izmenu [[:$1]]
+od korisnika [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|razgovor]]); neko drugi je već izmenio ili vratio članak.
+
+Poslednju izmenu je napravio korisnik [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|razgovor]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Komentar izmene je: "<i>$1</i>".',
+'revertpage' => 'Vraćene izmene od [[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|razgovor]]) na poslednju izmenu od korisnika [[{{ns:user}}:$1|$1]]',
+'sessionfailure' => 'Izgleda da postoji problem sa vašom seansom prijave;
+ova akcija je prekinuta kao predostrožnost protiv preotimanja seansi.
+Molimo kliknite "back" i ponovo učitajte stranu odakle ste došli, a onda pokušajte ponovo.',
+'protectlogpage' => 'istorija zaključavanja',
+'protectlogtext' => 'Ispod je spisak zaključavanja i otključavanja stranica.',
+'protectedarticle' => 'zaštitio $1',
+'unprotectedarticle' => 'skinuo zaštitu sa $1',
+'protectsub' => '(stavljanje zaštite "$1")',
+'confirmprotecttext' => 'Da li zaista želite da zaštitite ovu stranicu?',
+'confirmprotect' => 'Potvrdite zaštitu',
+'protectmoveonly' => 'Zaštićeno samo od pomeranja',
+'protectcomment' => 'Razlog zaštite',
+'unprotectsub' => '(skidanje zaštite "$1")',
+'confirmunprotecttext' => 'Da li zaista želite da skinete zaštitu sa ove stranice?',
+'confirmunprotect' => 'Potvrdite skidanje zaštite',
+'unprotectcomment' => 'Razlog za skidanje zaštite',
+'protect-unchain' => 'Otključaj dozvole premeštanja',
+'protect-text' => 'Ovde možete pogledati i menjati nivo zaštite za stranicu <strong>$1</strong>.',
+'protect-viewtext' => 'Vaš nalog nema pristup izmenama
+nivoa zaštite. Ovo su trenutna podešavanja za stranicu <strong>$1</strong>:',
+'protect-default' => '(standard)',
+'protect-level-autoconfirmed' => 'Blokiraj neregistrovane korisnike',
+'protect-level-sysop' => 'Samo za administratore',
+
+# restrictions (nouns)
+'restriction-edit' => 'Uređivanje',
+'restriction-move' => 'Premeštanje',
+
+# Undelete
+'undelete' => 'Pogledaj obrisane stranice',
+'undeletepage' => 'Pogledaj i vrati obrisane stranice',
+'viewdeletedpage' => 'Pogledaj obrisane strane',
+'undeletepagetext' => 'Sledeće stranice su obrisane ali su još uvek u arhivi i
+mogu biti vraćene. Arhiva može biti periodično čišćena.',
+'undeleteextrahelp' => 'Da vratite celu stranu, ostavite sve kućice neotkačenim i kliknite na \'\'\'\'\'Vrati\'\'\'\'\'. Da izvršite selektivno vraćanje, otkačite kućice koje odgovaraju reviziji koja treba da se vrati i kliknite na \'\'\'\'\'Vrati\'\'\'\'\'. Klikom na \'\'\'\'\'Poništi\'\'\'\'\' ćete obrisati polje za komentar i sve kućice.',
+'undeletearticle' => 'Vrati obrisani članak',
+'undeleterevisions' => '$1 revizija arhivirano',
+'undeletehistory' => 'Ako vratite stranicu, sve revizije će biti vraćene njenoj istoriji.
+Ako je nova stranica istog imena napravljena od brisanja, vraćene
+revizije će se pojaviti u ranijoj istoriji, a trenutna revizija sadašnje stranice
+neće biti automatski zamenjena.',
+'undeletehistorynoadmin' => 'Ova strana je obrisana. Razlog za brisanje se nalazi u opisu ispod, zajedno sa detaljima o korisniku koji je menjao ovu stranu pre brisanja. Stvarni tekst ovih obrisanih revizija je dostupan samo administratorima.',
+'undeleterevision' => 'Obrisana revizija od $1',
+'undeleterevision-missing' => 'Nekorektna ili nepostojeća revizija. Možda je vaš link pogrešan, ili je revizija restaurirana, ili obrisana iz arhive.',
+'undeletebtn' => 'Vrati!',
+'undeletereset' => 'Poništi',
+'undeletecomment' => 'Komentar:',
+'undeletedarticle' => 'vratio "[[$1]]"',
+'undeletedrevisions' => '$1 revizija vraćeno',
+'undeletedrevisions-files' => '$1 {{plural:$1|revizija|revizije|revizija}} i $2 {{plural:$2|fajl|fajla|fajlova}} vraćeno',
+'undeletedfiles' => '$1 {{plural:$1|fajl vraćen|fajla vraćena|fajlova vraćeno}}',
+'cannotundelete' => 'Vraćanje obrisane verzije nije uspelo; neko drugi je vratio stranicu pre vas.',
+'undeletedpage' => '<big>\'\'\'Strana $1 je vraćena\'\'\'</big>
+
+Pogledajte [[{{ns:special}}:Log/delete|istoriju brisanja]] za spisak skorašnjih brisanja i vraćanja.',
+
+# Namespace form on various pages
+'namespace' => 'Imenski prostor:',
+'invert' => 'Obrni selekciju',
+
+# Contributions
+#
+'contributions' => 'Prilozi korisnika',
+'mycontris' => 'Moji prilozi',
+'contribsub' => 'Za $1',
+'nocontribs' => 'Nisu nađene promene koje zadovoljavaju ove uslove.',
+'ucnote' => 'Ispod je poslednjih <b>$1</b> promena u poslednjih <b>$2</b> dana.',
+'uclinks' => 'Gledaj poslednjih $1 promena; gledaj poslednjih $2 dana.',
+'uctop' => ' (vrh)',
+'newbies' => 'novajlije',
+
+'sp-newimages-showfrom' => 'Prikaži nove slike počevši od $1',
+
+'sp-contributions-newest' => 'Najnovijih',
+'sp-contributions-oldest' => 'Najstarijih',
+'sp-contributions-newer' => 'Novijih $1',
+'sp-contributions-older' => 'Starijih $1',
+'sp-contributions-newbies-sub' => 'Za novajlije',
+
+# What links here
+#
+'whatlinkshere' => 'Šta je povezano ovde',
+'notargettitle' => 'Nema cilja',
+'notargettext' => 'Niste naveli ciljnu stranicu ili korisnika
+na kome bi se izvela ova funkcija.',
+'linklistsub' => '(spisak veza)',
+'linkshere' => 'Sledeće stranice su povezane ovde:',
+'nolinkshere' => 'Ni jedna stranica nije povezana ovde.',
+'isredirect' => 'preusmerivač',
+'istemplate' => 'uključivanje',
+
+# Block/unblock IP
+#
+'blockip' => 'Blokiraj korisnika',
+'blockiptext' => 'Upotrebite donji upitnik da biste uklonili pravo pisanja
+sa određene IP adrese ili korisničkog imena.
+Ovo bi trebalo da bude urađeno samo da bi se sprečio vandalizam, i u skladu
+sa [[{{ns:project}}:Politika|politikom]].
+Unesite konkretan razlog ispod (na primer, navodeći koje
+stranice su vandalizovane).',
+'ipaddress' => 'IP adresa',
+'ipadressorusername' => 'IP adresa ili korisničko ime',
+'ipbexpiry' => 'Trajanje',
+'ipbreason' => 'Razlog',
+'ipbanononly' => 'Blokiraj samo anonimne korisnike',
+'ipbcreateaccount' => 'Spreči pravljenje naloga',
+'ipbenableautoblock' => 'Automatski blokiraj poslednju IP adresu ovog korisnika, i svaku sledeću adresu sa koje se pokuša uređivanje.',
+'ipbsubmit' => 'Blokiraj ovog korisnika',
+'ipbother' => 'Ostalo vreme',
+'ipboptions' => '2 sata:2 hours,1 dan:1 day,3 dana:3 days,1 nedelja:1 week,2 nedelje:2 weeks,1 mesec:1 month,3 meseca:3 months,6 meseci:6 months,1 godina:1 year,beskonačno:infinite',
+'ipbotheroption' => 'ostalo',
+'badipaddress' => 'Loša IP adresa',
+'blockipsuccesssub' => 'Blokiranje je uspelo',
+'blockipsuccesstext' => '[[{{ns:special}}:Contributions/$1|$1]] je blokiran.
+<br />Vidite [[{{ns:special}}:Ipblocklist|spisak blokiranja]] da biste pregledali blokiranja.',
+'unblockip' => 'Odblokiraj korisnika',
+'unblockiptext' => 'Upotrebite donji upitnik da biste vratili pravo pisanja
+ranije blokiranoj IP adresi ili korisničkom imenu.',
+'ipusubmit' => 'Odblokiraj ovu adresu',
+'unblocked' => '[[{{ns:user}}:$1|$1]] je odblokiran',
+'ipblocklist' => 'Spisak blokiranih IP adresa i korisnika',
+'blocklistline' => '$1, $2 blokirao korisnika [[{{ns:user}}:$3|$3]], (ističe $4)',
+'infiniteblock' => 'beskonačan',
+'expiringblock' => 'ističe $1',
+'anononlyblock' => 'samo anonimni',
+'noautoblockblock' => 'Autoblokiranje je onemogućeno',
+'createaccountblock' => 'blokirano pravljenje naloga',
+'ipblocklistempty' => 'Spisak blokiranja je prazan.',
+'blocklink' => 'blokiraj',
+'unblocklink' => 'odblokiraj',
+'contribslink' => 'prilozi',
+'autoblocker' => 'Automatski ste blokirani jer je vašu IP adresu skoro koristio "[[{{ns:user}}:$1|$1]]". Razlog za blokiranje korisnika $1 je: "\'\'\'$2\'\'\'".',
+'blocklogpage' => 'istorija blokiranja',
+'blocklogentry' => 'je blokirao "[[$1]]" sa vremenom isticanja blokade od $2',
+'blocklogtext' => 'Ovo je istorija blokiranja i odblokiranja korisnika. Automatski
+blokirane IP adrese nisu navedene. Pogledajte [[{{ns:special}}:Ipblocklist|spisak blokiranih IP adresa]] za spisak trenutnih zabrana i blokiranja.',
+'unblocklogentry' => 'odblokirao "$1"',
+'range_block_disabled' => 'Administratorska mogućnost da blokira blokove IP adresa je isključena.',
+'ipb_expiry_invalid' => 'Pogrešno vreme trajanja.',
+'ipb_already_blocked' => '"$1" je već blokiran',
+'ip_range_invalid' => 'Netačan blok IP adresa.',
+'proxyblocker' => 'Bloker proksija',
+'ipb_cant_unblock' => 'Greška: ID bloka $1 nije nađen. Moguće je da je već odblokiran.',
+'proxyblockreason' => 'Vaša IP adresa je blokirana jer je ona otvoreni proksi. Molimo kontaktirajte vašeg Internet servis provajdera ili tehničku podršku i obavestite ih o ovom ozbiljnom sigurnosnom problemu.',
+'proxyblocksuccess' => 'Urađeno.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Vaša IP adresa je na spisku kao otvoren proksi na [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Vaša IP adresa se nalazi na spisku kao otvoreni proksi na [http://www.sorbs.net SORBS] DNSBL. Ne možete da napravite nalog',
+
+# Developer tools
+#
+'lockdb' => 'Zaključaj bazu',
+'unlockdb' => 'Otključaj bazu',
+'lockdbtext' => 'Zaključavanje baze će svim korisnicima ukinuti mogućnost izmene stranica,
+promene korisničkih podešavanja, izmene spiska nadgledanja, i svega ostalog
+što zahteva promene u bazi.
+Molimo potvrdite da je ovo zaista ono što nameravate da uradite i da ćete
+otključati bazu kada završite posao oko njenog održavanja.',
+'unlockdbtext' => 'Otključavanje baze će svim korisnicima vratiti mogućnost izmene stranica,
+promene korisničkih podešavanja, izmene spiska nadgledanja, i svega ostalog
+što zahteva promene u bazi.
+Molimo potvrdite da je ovo zaista ono što nameravate da uradite.',
+'lockconfirm' => 'Da, zaista želim da zaključam bazu.',
+'unlockconfirm' => 'Da, zaista želim da otključam bazu.',
+'lockbtn' => 'Zaključaj bazu',
+'unlockbtn' => 'Otključaj bazu',
+'locknoconfirm' => 'Niste potvrdili svoju nameru.',
+'lockdbsuccesssub' => 'Baza je zaključana',
+'unlockdbsuccesssub' => 'Baza je otključana',
+'lockdbsuccesstext' => 'Baza podataka je zaključana.
+<br />Ne zaboravite da je [[{{ns:special}}:Unlockdb|otključate]] kada završite sa održavanjem.',
+'unlockdbsuccesstext' => 'Baza podataka je otključana.',
+'lockfilenotwritable' => 'Po fajlu za zaključavanje baze podataka ne može da se piše. Da biste zaključali ili otključali bazu, po ovom fajlu mora da bude omogućeno pisanje od strane veb servera.',
+'databasenotlocked' => 'Baza podataka nije zaključana.',
+
+# Make sysop
+'makesysoptitle' => 'Pretvorite korisnika u administratora',
+'makesysoptext' => 'Ovaj upitnik koriste birokrate da se obični korisnici pretvore u administratore. Unesite ime korisnika u polje i pritisnite dugme da bi korisnik postao administrator',
+'makesysopname' => 'Ime korisnika:',
+'makesysopsubmit' => 'Dodajte ovom korisniku administratorska ovlašćenja',
+'makesysopok' => '<b>Korisnik "$1" je sada administrator</b>',
+'makesysopfail' => '<b>Korisnik "$1" ne može da postane administrator. (Da li ste pravilno uneli ime?)</b>',
+'setbureaucratflag' => 'Postavi prava birokrate',
+'rightslog' => 'istorija korisničkih prava',
+'rightslogtext' => 'Ovo je istorija izmena korisničkih prava.',
+'rightslogentry' => 'je promenio prava za $1 sa $2 na $3',
+'rights' => 'Prava:',
+'set_user_rights' => 'Postavi prava korisnika',
+'user_rights_set' => '<b>Prava za korisnika "$1" promenjena</b>',
+'set_rights_fail' => '<b>Korisnička prava za "$1" nisu mogla da se podese. (Da li ste pravilno uneli ime?)</b>',
+'makesysop' => 'Davanje administratorskih ovlašćenja korisniku',
+'already_sysop' => 'Ovaj korisnik je već administrator',
+'already_bureaucrat' => 'Ovaj korisnik je već birokrata',
+'rightsnone' => '(nema)',
+
+# Move page
+#
+'movepage' => 'Premeštanje stranice',
+'movepagetext' => 'Donji upitnik će preimenovati stranicu, premeštajući svu
+njenu istoriju na novo ime.
+Stari naslov će postati preusmerenje na novi naslov.
+Veze ka starom naslovu neće biti promenjene; obavezno
+potražite [[{{ns:special}}:DoubleRedirects|dvostruka]] ili [[{{ns:special}}:BrokenRedirects|pokvarena preusmerenja]].
+Na vama je odgovornost da veze i dalje idu tamo gde bi i trebalo da idu.
+
+Obratite pažnju da stranica \'\'\'neće\'\'\' biti pomerena ako već postoji
+stranica sa novim naslovom, osim ako je ona prazna ili preusmerenje i nema
+istoriju promena. Ovo znači da ne možete preimenovati stranicu na ono ime
+sa koga ste je preimenovali ako pogrešite, i ne možete prepisati
+postojeću stranicu.
+
+<b>PAŽNJA!</b>
+Ovo može biti drastična i neočekivana promena za popularnu stranicu;
+molimo da budete sigurni da razumete posledice ovoga pre nego što
+nastavite.',
+'movepagetalktext' => 'Odgovarajuća stranica za razgovor, ako postoji, biće automatski premeštena istovremeno \'\'\'osim ako:\'\'\'
+*Neprazna stranica za razgovor već postoji pod novim imenom, ili
+*Odbeležite donju kućicu.
+
+U tim slučajevima, moraćete ručno da premestite ili spojite stranicu ukoliko to želite.',
+'movearticle' => 'Premesti stranicu',
+'movenologin' => 'Niste prijavljeni',
+'movenologintext' => 'Morate biti registrovani korisnik i [[Special:Userlogin|prijavljeni]]
+da biste premestili stranicu.',
+'newtitle' => 'Novi naslov',
+'movepagebtn' => 'premesti stranicu',
+'pagemovedsub' => 'Premeštanje uspelo',
+'pagemovedtext' => 'Stranica "[[$1]]" premeštena je na "[[$2]]".',
+'articleexists' => 'Stranica pod tim imenom već postoji, ili je
+ime koje ste izabrali neispravno.
+Molimo izaberite drugo ime.',
+'talkexists' => '\'\'\'Sama stranica je uspešno premeštena, ali
+stranica za razgovor nije mogla biti premeštena jer takva već postoji na novom naslovu. Molimo vas da ih spojite ručno.\'\'\'',
+'movedto' => 'premeštena na',
+'movetalk' => 'Premesti "stranicu za razgovor" takođe, ako je moguće.',
+'talkpagemoved' => 'Odgovarajuća stranica za razgovor je takođe premeštena.',
+'talkpagenotmoved' => 'Odgovarajuća stranica za razgovor <strong>nije</strong> premeštena.',
+'1movedto2' => 'je promenio ime članku [[$1]] u [[$2]]',
+'1movedto2_redir' => 'je promenio ime članku [[$1]] u [[$2]] putem preusmerenja',
+'movelogpage' => 'istorija premeštanja',
+'movelogpagetext' => 'Ispod je spisak premeštanja članaka.',
+'movereason' => 'Razlog',
+'revertmove' => 'vrati',
+'delete_and_move' => 'Obriši i premesti',
+'delete_and_move_text' => '==Potrebno brisanje==
+
+Ciljani članak "[[$1]]" već postoji. Da li želite da ga obrišete da biste napravili mesto za premeštanje?',
+'delete_and_move_confirm' => 'Da, obriši stranicu',
+'delete_and_move_reason' => 'Obrisano kako bi se napravilo mesto za premeštanje',
+'selfmove' => 'Izvorni i ciljani naziv su isti; strana ne može da se premesti preko same sebe.',
+'immobile_namespace' => 'Ciljani naziv je posebnog tipa; ne mogu da premeste strane u taj imenski prostor.',
+
+# Export
+
+'export' => 'Izvezi stranice',
+'exporttext' => 'Možete izvoziti tekst i istoriju promena određene
+stranice ili grupe stranica u XML formatu. Ovo onda može biti uvezeno u drugi
+viki koji koristi MedijaViki softver preko {{ns:special}}:Import stranice.
+
+Da biste izvozili stranice, unesite nazive u tekstualnom polju ispod, sa jednim naslovom po redu, i odaberite da li želite trenutnu verziju sa svim starim verzijama ili samo trenutnu verziju sa informacijama o poslednjoj izmeni.
+
+U drugom slučaju, možete takođe koristiti vezu, npr. [[{{ns:special}}:Export/{{int:mainpage}}]] za stranicu {{int:mainpage}}.',
+'exportcuronly' => 'Uključi samo trenutnu reviziju, ne celu istoriju',
+'exportnohistory' => '----
+\'\'\'Napomena:\'\'\' izvoženje pune istorije strana preko ovog formulara je onemogućeno zbog serverskih razloga.',
+'export-submit' => 'Izvoz',
+
+# Namespace 8 related
+
+'allmessages' => 'Sistemske poruke',
+'allmessagesname' => 'Ime',
+'allmessagesdefault' => 'Standardni tekst',
+'allmessagescurrent' => 'Trenutni tekst',
+'allmessagestext' => 'Ovo je spisak svih poruka koje su u {{ns:MediaWiki}} imenskom prostoru',
+'allmessagesnotsupportedUI' => 'Stranica {{ns:special}}:Allmessages ne podržava vVaš trenutni jezik interfejsa <b>$1</b> na ovoj viki.',
+'allmessagesnotsupportedDB' => 'Stranica {{ns:special}}:Allmessages ne može da se koristi zato što je \'\'\'$wgUseDatabaseMessages\'\'\' isključen.',
+'allmessagesfilter' => 'Filter za imena poruka:',
+'allmessagesmodified' => 'Prikaži samo izmenjene',
+
+# Thumbnails
+'thumbnail-more' => 'uvećaj',
+'missingimage' => '<b>Ovde nedostaje slika</b><br /><i>$1</i>',
+'filemissing' => 'Nedostaje fajl',
+'thumbnail_error' => 'Greška pri pravljenju umanjene slike: $1',
+
+# Special:Import
+'import' => 'Uvoz stranica',
+'importinterwiki' => 'Transviki uvoženje',
+'import-interwiki-text' => 'Odaberite viki i naziv strane za uvoz.
+Datumi revizije i imena urednika će biti sačuvani.
+Svi transviki uvozi su zabeleženi u [[Posebno:Log/import|istoriji uvoza]].',
+'import-interwiki-history' => 'Kopiraj sve revizije ove strane',
+'import-interwiki-submit' => 'Uvezi',
+'import-interwiki-namespace' => 'Prebaci stranice u imenski prostor:',
+'importtext' => 'Molimo izvezite fajl iz izvornog vikija koristeći {{ns:special}}:Export, sačuvajte ga kod sebe i pošaljite ovde.',
+'importstart' => 'Uvoženje strana u toku...',
+'import-revision-count' => '$1 {{plural:$1|revizija|revizije|revizija}}',
+'importnopages' => 'Nema strana za uvoz.',
+'importfailed' => 'Uvoz nije uspeo: $1',
+'importunknownsource' => 'Nepoznati tip izvora unosa',
+'importcantopen' => 'Neuspešno otvaranje fajla za uvoz',
+'importbadinterwiki' => 'Loša interviki veza',
+'importnotext' => 'Stranica je prazna ili bez teksta.',
+'importsuccess' => 'Uspešan uvoz!',
+'importhistoryconflict' => 'Postoji konfliktna istorija revizija (možda je ova stranica već uvezena ranije)',
+'importnosources' => 'Nije definisan nijedan izvor transviki uvoženja i direktna slanja istorija su onemogućena.',
+'importnofile' => 'Nije poslat nijedan uvozni fajl.',
+'importuploaderror' => 'Slanje uvoznog fajla nije bilo uspešno; moguće je da je fajl veći od dozvoljene veličine za slanje.',
+
+# import log
+'importlogpage' => 'istorija uvoza',
+'importlogpagetext' => 'Administrativni uvozi stranica sa istorijama izmena sa drugih vikija.',
+'import-logentry-upload' => 'uvezao [[$1]] putem slanja fajla',
+'import-logentry-upload-detail' => '$1 revizija/e',
+'import-logentry-interwiki' => 'premestio sa drugog vikija: $1',
+'import-logentry-interwiki-detail' => '$1 revizija/e od $2',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Pretražite viki [alt-f]',
+'tooltip-minoredit' => 'Naznačite da se radi o maloj izmeni [alt-i]',
+'tooltip-save' => 'Snimite Vaše izmene [alt-s]',
+'tooltip-preview' => 'Pretpregled Vaših izmena, molimo koristite ovo pre snimanja! [alt-p]',
+'tooltip-diff' => 'Prikaži koje promene ste napravili na tekstu. [alt-v]',
+'tooltip-compareselectedversions' => 'Pogledaj razlike između dve odabrane verzije ove stranice. [alt-v]',
+'tooltip-watch' => 'Dodajte ovu stranicu na Vaš spisak nadgledanja [alt-w]',
+
+# stylesheets
+'common.css' => '/** CSS stavljen ovde će se odnositi na sve kože */',
+'monobook.css' => '/* CSS stavljen ovde će se odnositi na korisnike Monobuk kože */',
+
+# Metadata
+'nodublincore' => 'Dublin Core RDF metapodaci onemogućeni za ovaj server.',
+'nocreativecommons' => 'Creative Commons RDF metapodaci onemogućeni za ovaj server.',
+'notacceptable' => 'Viki server ne može da pruži podatke u onom formatu koji vaš klijent može da pročita.',
+
+# Attribution
+
+'anonymous' => 'Anonimni korisnik sajta {{SITENAME}}',
+'siteuser' => '{{SITENAME}} korisnik $1',
+'lastmodifiedatby' => 'Ovu stranicu je poslednji put promenio $3 u $2, $1.',
+'and' => 'i',
+'othercontribs' => 'Bazirano na radu korisnika $1.',
+'others' => 'ostali',
+'siteusers' => '{{SITENAME}} korisnik (korisnici) $1',
+'creditspage' => 'Zasluge za stranicu',
+'nocredits' => 'Nisu dostupne informacije o zaslugama za ovu stranicu.',
+
+# Spam protection
+'spamprotectiontitle' => 'Filter za zaštitu od neželjenih poruka',
+'spamprotectiontext' => 'Strana koju želite da sačuvate je blokirana od strane filtera za neželjene poruke. Ovo je verovatno izazvano vezom ka spoljašnjem sajtu.',
+'spamprotectionmatch' => 'Sledeći tekst je izazvao naš filter za neželjene poruke: $1',
+'subcategorycount' => 'U ovoj kategoriji se nalazi {{plural:$1|jedna potkategorija|$1 potkategorije|$1 potkategorija}}.',
+'categoryarticlecount' => 'U ovoj kategoriji se nalazi {{plural:$1|Jedan članak|$1 članka|$1 članaka}}.',
+'listingcontinuesabbrev' => ' nast.',
+'spambot_username' => 'Čišćenje neželjenih poruka u MedijaVikiju',
+'spam_reverting' => 'Vraćanje na staru reviziju koja ne sadrži veze ka $1',
+'spam_blanking' => 'Sve revizije su sadržale veze ka $1, pražnjenje',
+
+# Info page
+'infosubtitle' => 'Informacije za stranicu',
+'numedits' => 'Broj promena (članak): $1',
+'numtalkedits' => 'Broj promena (stranica za razgovor): $1',
+'numwatchers' => 'Broj korisnika koji nadgledaju: $1',
+'numauthors' => 'Broj različitih autora (članak): $1',
+'numtalkauthors' => 'Broj različitih autora (stranica za razgovor): $1',
+
+# Math options
+'mw_math_png' => 'Uvek prikaži PNG',
+'mw_math_simple' => 'HTML ako je vrlo jednostavno, inače PNG',
+'mw_math_html' => 'HTML ako je moguće, inače PNG',
+'mw_math_source' => 'Ostavi kao TeH (za tekstualne brauzere)',
+'mw_math_modern' => 'Preporučeno za savremene brauzere',
+'mw_math_mathml' => 'MathML ako je moguće (eksperimentalno)',
+
+# Patrolling
+'markaspatrolleddiff' => 'Označi kao patroliran',
+'markaspatrolledtext' => 'Označi ovaj članak kao patroliran',
+'markedaspatrolled' => 'Označen kao patroliran',
+'markedaspatrolledtext' => 'Izabrana revizija je označena kao patrolirana.',
+'rcpatroldisabled' => 'Patrola skorašnjih izmena onemogućena',
+'rcpatroldisabledtext' => 'Patrola skorašnjih izmena je trenutno onemogućena.',
+'markedaspatrollederror' => 'Nemoguće označiti kao patrolirano',
+'markedaspatrollederrortext' => 'Morate izabrati reviziju da biste označili kao patrolirano.',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Moja korisnička stranica\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Korisnička stranica IP adrese sa koje uređujete\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Moja stranica za razgovor\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Razgovor o prilozima sa ove IP adrese\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Moja korisnička podešavanja\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Spisak članaka koje nadgledate\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Spisak mojih priloga\');
+ta[\'pt-login\'] = new Array(\'o\',\'Preporučuje se da se prijavite, ali nije obavezno\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Preporučuje se da se prijavite, ali nije obavezno\');
+ta[\'pt-logout\'] = new Array(\'\',\'Odjavi se\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Razgovor o članku\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Možete urediti ovu stranicu. Molimo koristite pretpregled pre sačuvavanja.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Dodajte komentar na ovu diskusiju\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Ova stranica je zaključana. Možete videti njen izvor\');
+ta[\'ca-history\'] = new Array(\'h\',\'Prethodne verzije ove stranice\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Zaštiti ovu stranicu\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Obriši ovu stranicu\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Vraćati izmene koje su načinjene pre brisanja stranice\');
+ta[\'ca-move\'] = new Array(\'m\',\'Premesti ovu stranicu\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Dodajte ovu stranicu na Vaš spisak nadgledanja\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Uklonite ovu stranicu sa Vašeg spiska nadgledanja\');
+ta[\'search\'] = new Array(\'f\',\'Pretražite ovaj viki\');
+ta[\'p-logo\'] = new Array(\'\',\'Glavna strana\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Posetite glavnu stranu\');
+ta[\'n-portal\'] = new Array(\'\',\'O projektu, šta možete da radite i gde da pronađete stvari\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Saznajte više o aktuelnostima\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Spisak skorašnjih izmena na vikiju\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Učitavaj slučajnu stranicu\');
+ta[\'n-help\'] = new Array(\'\',\'Mesto gde možete da naučite nešto\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Podržite nas\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Spisak svih stranica koje vezuju na ovu\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Skorašnje izmene na člancima povezanim sa ove stranice\');
+ta[\'feed-rss\'] = new Array(\'\',\'RSS fid za ovu stranicu\');
+ta[\'feed-atom\'] = new Array(\'\',\'Atom fid za ovu stranicu\');
+ta[\'t-contributions\'] = new Array(\'\',\'Pogledaj spisak priloga ovog korisnika\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Pošalji elektronsku poštu ovom korisniku\');
+ta[\'t-upload\'] = new Array(\'u\',\'Pošalji slike i medija fajlove\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Spisak svih posebnih stranica\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Pogledajte članak\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Pogledajte korisničku stranicu\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Pogledajte medija stranicu\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Ovo je posebna stranica, ne možete je menjati\');
+ta[\'ca-nstab-wp\'] = new Array(\'c\',\'Pogledajte stranicu o projektu\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Pogledajte stranicu slike\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Pogledajte sistemsku poruku\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Pogledajte šablon\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Pogledajte stranicu za pomoć\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Pogledajte stranicu kategorije\');',
+
+# image deletion
+'deletedrevision' => 'Obrisana stara revizija $1.',
+
+# browsing diffs
+'previousdiff' => '← Prethodna izmena',
+'nextdiff' => 'Sledeća izmena →',
+
+'imagemaxsize' => 'Ograniči slike na stranama za razgovor o slikama na:',
+'thumbsize' => 'Veličina umanjenog prikaza :',
+'showbigimage' => 'Prikaži sliku veće rezolucije ($1x$2, $3 Kb)',
+
+'newimages' => 'Galerija novih slika',
+'showhidebots' => '($1 botove)',
+'noimages' => 'Nema ništa da se vidi',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+# variants for Serbian language
+'variantname-sr-ec' => 'ћирилица',
+'variantname-sr-el' => 'latinica',
+'variantname-sr-jc' => 'jekav',
+'variantname-sr-jl' => 'jekav',
+'variantname-sr' => 'disable',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Korisnik:',
+'speciallogtitlelabel' => 'Naslov:',
+
+'passwordtooshort' => 'Vaša šifra je previše kratka. Mora da ima bar $1 karaktera.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Upozorenje\'\'\': Ovaj fajl sadrži loš kod, njegovim izvršavanjem možete da ugrozite vaš sistem.<hr />',
+
+'fileinfo' => '$1KB, MIME tip: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metapodaci',
+'metadata-help' => 'Ovaj fajl sadrži dodatne informacije, koje su verovatno dodali digitalni fotoaparat ili skener koji su korišćeni da bi se napravila ili digitalizovala slika. Ako je prvobitno stanje fajla promenjeno, moguće je da neki detalji ne opisuju u potpunosti izmenjenu sliku.',
+'metadata-expand' => 'Pokaži detalje',
+'metadata-collapse' => 'Sakrij detalje',
+'metadata-fields' => 'Polja EXIF metapodataka navedena u ovoj poruci će biti ubačena na stranu o slici kada se raširi tabela za metapodatke. Ostala će biti sakrivena po podrazumevanom.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# Exif tags
+'exif-imagewidth' => 'Širina',
+'exif-imagelength' => 'Visina',
+'exif-bitspersample' => 'Bitova po komponenti',
+'exif-compression' => 'Šema kompresije',
+'exif-photometricinterpretation' => 'Kompozicija piksela',
+'exif-orientation' => 'Orijentacija',
+'exif-samplesperpixel' => 'Broj komponenti',
+'exif-planarconfiguration' => 'Princip rasporeda podataka',
+'exif-ycbcrsubsampling' => 'Odnos komponente Y prema C',
+'exif-ycbcrpositioning' => 'Razmeštaj komponenata Y i C',
+'exif-xresolution' => 'Horizonatalna rezolucija',
+'exif-yresolution' => 'Vertikalna rezolucija',
+'exif-resolutionunit' => 'Jedinica rezolucije',
+'exif-stripoffsets' => 'Položaj bloka podataka',
+'exif-rowsperstrip' => 'Broj redova u bloku',
+'exif-stripbytecounts' => 'Veličina kompresovanog bloka',
+'exif-jpeginterchangeformat' => 'Udaljenost JPEG pregleda od početka fajla',
+'exif-jpeginterchangeformatlength' => 'Količina bajtova JPEG pregleda',
+'exif-transferfunction' => 'Funkcija preoblikovanja kolor prostora',
+'exif-whitepoint' => 'Hromacitet bele tačke',
+'exif-primarychromaticities' => 'Hromacitet primarnih boja',
+'exif-ycbcrcoefficients' => 'Matrični koeficijenti transformacije kolor prostora',
+'exif-referenceblackwhite' => 'Mesto bele i crne tačke',
+'exif-datetime' => 'Datum poslednje promene fajla',
+'exif-imagedescription' => 'Ime slike',
+'exif-make' => 'Proizvođač kamere',
+'exif-model' => 'Model kamere',
+'exif-software' => 'Korišćen softver',
+'exif-artist' => 'Autor',
+'exif-copyright' => 'Nosilac prava',
+'exif-exifversion' => 'Exif verzija',
+'exif-flashpixversion' => 'Podržana verzija Flešpiksa',
+'exif-colorspace' => 'Prostor boje',
+'exif-componentsconfiguration' => 'Značenje svake od komponenti',
+'exif-compressedbitsperpixel' => 'Mod kompresije slike',
+'exif-pixelydimension' => 'Puna visina slike',
+'exif-pixelxdimension' => 'Puna širina slike',
+'exif-makernote' => 'Napomene proizvođača',
+'exif-usercomment' => 'Korisnički komentar',
+'exif-relatedsoundfile' => 'Povezani zvučni zapis',
+'exif-datetimeoriginal' => 'Datum i vreme slikanja',
+'exif-datetimedigitized' => 'Datum i vreme digitalizacije',
+'exif-subsectime' => 'Deo sekunde u kojem je slikano',
+'exif-subsectimeoriginal' => 'Deo sekunde u kojem je fotografisano',
+'exif-subsectimedigitized' => 'Deo sekunde u kojem je digitalizovano',
+'exif-exposuretime' => 'Ekspozicija',
+'exif-exposuretime-format' => '$1 sek ($2)',
+'exif-fnumber' => 'F broj otvora blende',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' => 'Program ekspozicije',
+'exif-spectralsensitivity' => 'Spektralna osetljivost',
+'exif-isospeedratings' => 'ISO vrednost',
+'exif-oecf' => 'Optoelektronski faktor konverzije',
+'exif-shutterspeedvalue' => 'Brzina zatvarača',
+'exif-aperturevalue' => 'Otvor blende',
+'exif-brightnessvalue' => 'Svetlost',
+'exif-exposurebiasvalue' => 'Kompenzacija ekspozicije',
+'exif-maxaperturevalue' => 'Minimalni broj otvora blende',
+'exif-subjectdistance' => 'Udaljenost do objekta',
+'exif-meteringmode' => 'Režim merača vremena',
+'exif-lightsource' => 'Izvor svetlosti',
+'exif-flash' => 'Blic',
+'exif-focallength' => 'Fokusna daljina sočiva',
+'exif-focallength-format' =>'$1 mm',
+'exif-subjectarea' => 'Položaj i površina objekta snimka',
+'exif-flashenergy' => 'Energija blica',
+'exif-spatialfrequencyresponse' => 'Prostorna frekvencijska karakteristika',
+'exif-focalplanexresolution' => 'Vodoravna rezolucija fokusne ravni',
+'exif-focalplaneyresolution' => 'Horizonatlna rezolucija fokusne ravni',
+'exif-focalplaneresolutionunit' => 'Jedinica rezolucije fokusne ravni',
+'exif-subjectlocation' => 'Položaj subjekta',
+'exif-exposureindex' => 'Indeks ekspozicije',
+'exif-sensingmethod' => 'Tip senzora',
+'exif-filesource' => 'Izvorni fajl',
+'exif-scenetype' => 'Tip scene',
+'exif-cfapattern' => 'CFA šablon',
+'exif-customrendered' => 'Dodatna obrada slike',
+'exif-exposuremode' => 'Režim izbora ekspozicije',
+'exif-whitebalance' => 'Balans bele boje',
+'exif-digitalzoomratio' => 'Odnos digitalnog zuma',
+'exif-focallengthin35mmfilm' => 'Ekvivalent fokusne daljine za 35 mm film',
+'exif-scenecapturetype' => 'Tip scene na snimku',
+'exif-gaincontrol' => 'Kontrola osvetljenosti',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Saturacija',
+'exif-sharpness' => 'Oštrina',
+'exif-devicesettingdescription' => 'Opis podešavanja uređaja',
+'exif-subjectdistancerange' => 'Raspon udaljenosti subjekata',
+'exif-imageuniqueid' => 'Jedinstveni identifikator slike',
+'exif-gpsversionid' => 'Verzija bloka GPS-informacije',
+'exif-gpslatituderef' => 'Severna ili južna širina',
+'exif-gpslatitude' => 'Širina',
+'exif-gpslongituderef' => 'Istočna ili zapadna dužina',
+'exif-gpslongitude' => 'Dužina',
+'exif-gpsaltituderef' => 'Visina ispod ili iznad mora',
+'exif-gpsaltitude' => 'Visina',
+'exif-gpstimestamp' => 'Vreme po GPS-u (atomski sat)',
+'exif-gpssatellites' => 'Upotrebljeni sateliti',
+'exif-gpsstatus' => 'Status prijemnika',
+'exif-gpsmeasuremode' => 'Režim merenja',
+'exif-gpsdop' => 'Preciznost merenja',
+'exif-gpsspeedref' => 'Jedinica brzine',
+'exif-gpsspeed' => 'Brzina GPS prijemnika',
+'exif-gpstrackref' => 'Tip azimuta prijemnika (pravi ili magnetni)',
+'exif-gpstrack' => 'Azimut prijemnika',
+'exif-gpsimgdirectionref' => 'Tip azimuta slike (pravi ili magnetni)',
+'exif-gpsimgdirection' => 'Azimut slike',
+'exif-gpsmapdatum' => 'Korišćeni geodetski koordinatni sistem',
+'exif-gpsdestlatituderef' => 'Indeks geografske širine objekta',
+'exif-gpsdestlatitude' => 'Geografska širina objekta',
+'exif-gpsdestlongituderef' => 'Indeks geografske dužine objekta',
+'exif-gpsdestlongitude' => 'Geografska dužina objekta',
+'exif-gpsdestbearingref' => 'Indeks azimuta objekta',
+'exif-gpsdestbearing' => 'Azimut objekta',
+'exif-gpsdestdistanceref' => 'Merne jedinice udaljenosti objekta',
+'exif-gpsdestdistance' => 'Udaljenost objekta',
+'exif-gpsprocessingmethod' => 'Ime metode obrade GPS podataka',
+'exif-gpsareainformation' => 'Ime GPS područja',
+'exif-gpsdatestamp' => 'GPS datum',
+'exif-gpsdifferential' => 'GPS diferencijalna korekcija',
+
+# Exif attributes
+
+'exif-compression-1' => 'Nekompresovan',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normalno',
+'exif-orientation-2' => 'Obrnuto po horizontali',
+'exif-orientation-3' => 'Zaokrenuto 180°',
+'exif-orientation-4' => 'Obrnuto po vertikali',
+'exif-orientation-5' => 'Zaokrenuto 90° suprotno od smera kazaljke na satu i obrnuto po vertikali',
+'exif-orientation-6' => 'Zaokrenuto 90° u smeru kazaljke na satu',
+'exif-orientation-7' => 'Zaokrenuto 90° u smeru kazaljke na satu i obrnuto po vertikali',
+'exif-orientation-8' => 'Zaokrenuto 90° suprotno od smera kazaljke na satu',
+
+'exif-planarconfiguration-1' => 'delimični format',
+'exif-planarconfiguration-2' => 'planarni format',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'ne postoji',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Nepoznato',
+'exif-exposureprogram-1' => 'Ručno',
+'exif-exposureprogram-2' => 'Normalni program',
+'exif-exposureprogram-3' => 'Prioritet otvora blende',
+'exif-exposureprogram-4' => 'Prioritet zatvarača',
+'exif-exposureprogram-5' => 'Umetnički program (na bazi nužne dubine polja)',
+'exif-exposureprogram-6' => 'Sportski program (na bazi što bržeg zatvarača)',
+'exif-exposureprogram-7' => 'Portretni režim (za krupne kadrove sa neoštrom pozadinom)',
+'exif-exposureprogram-8' => 'Režim pejzaža (za slike pejzaža sa oštrom pozadinom)',
+
+'exif-subjectdistance-value' => '$1 metara',
+
+'exif-meteringmode-0' => 'Nepoznato',
+'exif-meteringmode-1' => 'Prosek',
+'exif-meteringmode-2' => 'Prosek sa težištem na sredini',
+'exif-meteringmode-3' => 'Tačka',
+'exif-meteringmode-4' => 'Više tačaka',
+'exif-meteringmode-5' => 'Matrični',
+'exif-meteringmode-6' => 'Delimični',
+'exif-meteringmode-255' => 'Drugo',
+
+'exif-lightsource-0' => 'Nepoznato',
+'exif-lightsource-1' => 'Dnevna svetlost',
+'exif-lightsource-2' => 'Fluorescentno',
+'exif-lightsource-3' => 'Volfram (svetlo)',
+'exif-lightsource-4' => 'Blic',
+'exif-lightsource-9' => 'Lepo vreme',
+'exif-lightsource-10' => 'Oblačno vreme',
+'exif-lightsource-11' => 'Senka',
+'exif-lightsource-12' => 'Fluorescentna svetlost (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Fluorescentna svetlost (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Fluorescentna svetlost (W 3900 – 4500K)',
+'exif-lightsource-15' => 'Bela fluorescencija (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Standardno svetlo A',
+'exif-lightsource-18' => 'Standardno svetlo B',
+'exif-lightsource-19' => 'Standardno svetlo C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO studijski volfram',
+'exif-lightsource-255' => 'Drugi izvor svetla',
+
+'exif-focalplaneresolutionunit-2' => 'inči',
+
+'exif-sensingmethod-1' => 'Nedefinisano',
+'exif-sensingmethod-2' => 'Jednokristalni matrični senzor',
+'exif-sensingmethod-3' => 'Dvokristalni matrični senzor',
+'exif-sensingmethod-4' => 'Trokristalni matrični senzor',
+'exif-sensingmethod-5' => 'Sekvencijalni matrični senzor',
+'exif-sensingmethod-7' => 'Trobojni linearni senzor',
+'exif-sensingmethod-8' => 'Sekvencijalni linearni senzor',
+
+'exif-filesource-3' => 'Digitalni fotoaparat',
+
+'exif-scenetype-1' => 'Direktno fotografisana slika',
+
+'exif-customrendered-0' => 'Normalni proces',
+'exif-customrendered-1' => 'Nestadardni proces',
+
+'exif-exposuremode-0' => 'Automatski',
+'exif-exposuremode-1' => 'Ručno',
+'exif-exposuremode-2' => 'Automatski sa zadatim rasponom',
+
+'exif-whitebalance-0' => 'Automatski',
+'exif-whitebalance-1' => 'Ručno',
+
+'exif-scenecapturetype-0' => 'Standardno',
+'exif-scenecapturetype-1' => 'Pejzaž',
+'exif-scenecapturetype-2' => 'Portret',
+'exif-scenecapturetype-3' => 'Noćno',
+
+'exif-gaincontrol-0' => 'Nema',
+'exif-gaincontrol-1' => 'Malo povećanje',
+'exif-gaincontrol-2' => 'Veliko povećanje',
+'exif-gaincontrol-3' => 'Malo smanjenje',
+'exif-gaincontrol-4' => 'Veliko smanjenje',
+
+'exif-contrast-0' => 'Normalno',
+'exif-contrast-1' => 'Meko',
+'exif-contrast-2' => 'Tvrdo',
+
+'exif-saturation-0' => 'Normalno',
+'exif-saturation-1' => 'Niska saturacija',
+'exif-saturation-2' => 'Visoka saturacija',
+
+'exif-sharpness-0' => 'Normalno',
+'exif-sharpness-1' => 'Meko',
+'exif-sharpness-2' => 'Tvrdo',
+
+'exif-subjectdistancerange-0' => 'Nepoznato',
+'exif-subjectdistancerange-1' => 'Krupni kadar',
+'exif-subjectdistancerange-2' => 'Bliski kadar',
+'exif-subjectdistancerange-3' => 'Daleki kadar',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Sever',
+'exif-gpslatitude-s' => 'Jug',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Istok',
+'exif-gpslongitude-w' => 'Zapad',
+
+'exif-gpsstatus-a' => 'Merenje u toku',
+'exif-gpsstatus-v' => 'Spreman za prenos',
+
+'exif-gpsmeasuremode-2' => 'Dvodimenzionalno merenje',
+'exif-gpsmeasuremode-3' => 'Trodimenzionalno merenje',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'Kilometri na čas',
+'exif-gpsspeed-m' => 'Milje na čas',
+'exif-gpsspeed-n' => 'Čvorovi',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Pravi pravac',
+'exif-gpsdirection-m' => 'Magnetni pravac',
+
+# external editor support
+'edit-externally' => 'Izmenite ovaj fajl koristeći spoljašnju aplikaciju',
+'edit-externally-help' => 'Pogledajte [http://meta.wikimedia.org/wiki/Help:External_editors uputstvo za podešavanje] za više informacija.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'sve',
+'imagelistall' => 'sve',
+'watchlistall1' => 'sve',
+'watchlistall2' => 'sve',
+'namespacesall' => 'svi',
+
+# E-mail address confirmation
+'confirmemail' => 'Potvrdite adresu e-pošte',
+'confirmemail_noemail' => 'Nemate potvrđenu adresu vaše e-pošte u vašim [[Special:Preferences|korisničkim podešavanjima interfejsa]].',
+'confirmemail_text' => 'Ova viki zahteva da potvrdite adresu vaše e-pošte pre nego što koristite mogućnosti e-pošte. Aktivirajte dugme ispod kako biste poslali poštu za potvrdu na vašu adresu. Pošta uključuje vezu koja sadrži kod; učitajte tu vezu u vaš brauzer da biste potvrdili da je adresa vaše e-pošte validna.',
+'confirmemail_send' => 'Pošalji kod za potvrdu',
+'confirmemail_sent' => 'E-pošta za potvrđivanje poslata.',
+'confirmemail_sendfailed' => 'Pošta za potvrđivanje nije poslata. Proverita adresu zbog nepravilnih karaktera.',
+'confirmemail_invalid' => 'Netačan kod za potvrdu. Moguće je da je kod istekao.',
+'confirmemail_needlogin' => 'Morate da se $1 da biste potvrdili adresu vaše e-pošte.',
+'confirmemail_success' => 'Adresa vaše e-pošte je potvrđena. Možete sada da se prijavite i uživate u vikiju.',
+'confirmemail_loggedin' => 'Adresa vaše e-pošte je sada potvrđena.',
+'confirmemail_error' => 'Nešto je pošlo po zlu prilikom snimanja vaše potvrde.',
+
+'confirmemail_subject' => '{{SITENAME}} adresa e-pošte za potvrđivanje',
+'confirmemail_body' => 'Neko, verovatno vi, je sa IP adrese $1 registrovao nalog "$2" sa ovom adresom e-pošte na sajtu {{SITENAME}}.
+
+Da potvrdite da ovaj nalog stvarno pripada vama i da aktivirate mogućnost e-pošte na sajtu {{SITENAME}}, otvorite ovu vezu u vašem brauzeru:
+
+$3
+
+Ako ovo *niste* vi, ne pratite vezu. Ovaj kod za potvrdu će isteći u $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => 'Pokušaj tačno',
+'searchfulltext' => 'Pretraži ceo tekst',
+'createarticle' => 'Napravi članak',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[Interviki uključivanje je onemogućeno]',
+'scarytranscludefailed' => '[Donošenje šablona neuspešno; žao nam je]',
+'scarytranscludetoolong' => '[URL je predugačak; žao nam je]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+Vraćanja za ovaj članak:<br />
+$1
+</div>',
+'trackbackremove' => '([$1 Brisanje])',
+'trackbacklink' => 'Vraćanje',
+'trackbackdeleteok' => 'Vraćanje je uspešno obrisano.',
+
+# delete conflict
+'deletedwhileediting' => 'Upozorenje: Ova strana je obrisana pošto ste počeli uređivanje!',
+'confirmrecreate' => 'Korisnik [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|razgovor]]) je obrisao ovaj članak pošto ste počeli uređivanje sa razlogom:
+: \'\'$2\'\'
+Molimo potvrdite da stvarno želite da ponovo napravite ovaj članak.',
+'recreate' => 'Ponovo napravi',
+'tooltip-recreate' => 'Ponovo napravite ovu stranu uprkos tome što je obrisana',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Preusmeravam na [[$1]]...',
+
+# action=purge
+'confirm_purge' => 'Da li želite očistiti keš ove stranice?
+
+$1',
+'confirm_purge_button' => 'Da',
+
+'youhavenewmessagesmulti' => 'Imate novih poruka na $1',
+'searchcontaining' => 'Pretraži članke koji sadrže \'\'$1\'\'.',
+'searchnamed' => 'Pretraži članke koji se zovu \'\'$1\'\'.',
+'articletitles' => 'Članci počevši od \'\'$1\'\'',
+'hideresults' => 'Sakrij rezultate',
+
+# DISPLAYTITLE
+'displaytitle' => '(Veza ka ovoj strani kao [[$1]])',
+
+'loginlanguagelabel' => 'Jezik: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; prethodna stranica',
+'imgmultipagenext' => 'sledeća stranica &rarr;',
+'imgmultigo' => 'Idi!',
+'imgmultigotopre' => 'Idi na stranicu',
+
+# Table pager
+'ascending_abbrev' => 'rast',
+'descending_abbrev' => 'opad',
+'table_pager_next' => 'Sledeća stranica',
+'table_pager_prev' => 'Prethodna stranica',
+'table_pager_first' => 'Prva stranica',
+'table_pager_last' => 'Poslednja stranica',
+'table_pager_limit' => 'Prikaži $1 delova informacije po stranici',
+'table_pager_limit_submit' => 'Idi',
+'table_pager_empty' => 'Bez rezultata',
+
+);
+
+?>
diff --git a/languages/messages/MessagesSr_jc.php b/languages/messages/MessagesSr_jc.php
new file mode 100644
index 000000000000..8bc334de734f
--- /dev/null
+++ b/languages/messages/MessagesSr_jc.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# Inherit everything for now
+$fallback = 'sr-ec';
+
+?>
diff --git a/languages/messages/MessagesSr_jl.php b/languages/messages/MessagesSr_jl.php
new file mode 100644
index 000000000000..8bc334de734f
--- /dev/null
+++ b/languages/messages/MessagesSr_jl.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# Inherit everything for now
+$fallback = 'sr-ec';
+
+?>
diff --git a/languages/messages/MessagesSu.php b/languages/messages/MessagesSu.php
new file mode 100644
index 000000000000..3cf4fff15570
--- /dev/null
+++ b/languages/messages/MessagesSu.php
@@ -0,0 +1,1030 @@
+<?php
+/** Sundanese language file (Basa Sunda)
+ *
+ * Source: http://su.wikipedia.org/
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Média',
+ NS_SPECIAL => 'Husus',
+ NS_MAIN => '',
+ NS_TALK => 'Obrolan',
+ NS_USER => 'Pamaké',
+ NS_USER_TALK => 'Obrolan_pamaké',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Obrolan_$1',
+ NS_IMAGE => 'Gambar',
+ NS_IMAGE_TALK => 'Obrolan_gambar',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Obrolan_MediaWiki',
+ NS_TEMPLATE => 'Citakan',
+ NS_TEMPLATE_TALK => 'Obrolan_citakan',
+ NS_HELP => 'Pitulung',
+ NS_HELP_TALK => 'Obrolan_pitulung',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Obrolan_kategori',
+);
+
+
+$messages = array(
+
+# dates
+'sunday' => 'Minggu',
+'monday' => 'Senén',
+'tuesday' => 'Salasa',
+'wednesday' => 'Rebo',
+'thursday' => 'Kemis',
+'friday' => 'Jumaah',
+'saturday' => 'Saptu',
+'january' => 'Januari',
+'february' => 'Pébruari',
+'march' => 'Maret',
+'april' => 'April',
+'may' => 'Méi',
+'may_long' => 'Méi',
+'june' => 'Juni',
+'july' => 'Juli',
+'august' => 'Agustus',
+'september' => 'Séptémber',
+'october' => 'Oktober',
+'november' => 'Nopémber',
+'december' => 'Désémber',
+'jan' => 'Jan',
+'feb' => 'Péb',
+'mar' => 'Mar',
+'apr' => 'Apr',
+'may' => 'Méi',
+'jun' => 'Jun',
+'jul' => 'Jul',
+'aug' => 'Ags',
+'sep' => 'Sép',
+'oct' => 'Okt',
+'nov' => 'Nop',
+'dec' => 'Dés',
+
+# other messages
+
+'1movedto2' => 'mindahkeun $1 ka $2',
+'1movedto2_redir' => '$1 dipindahkeun ka $2',
+'monobook.css' => ' /* édit koropak ieu pikeun nyaluyukeun kulit \'\'monobook\'\' pikeun sakabéh situs */',
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Kaca pamaké kuring\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Kaca pamaké pikeun IP nu ku anjeun keur diédit\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Kaca obrolan kuring\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Sawala ngeunaan éditan ti alamat IP ieu\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Préferénsi kuring\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Daptar kaca nu diawaskeun ku anjeun parobahanana.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Daptar kontribusi kuring\');
+ta[\'pt-login\'] = new Array(\'o\',\'Anjeun leuwih hadé asup log, sanajan teu wajib.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Anjeun leuwih hadé asup log, sanajan teu wajib.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Kaluar log\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Sawala ngeunaan eusi kaca\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Anjeun bisa ngédit kaca ieu. Mangga pigunakeun tombol sawangan saméméh nyimpen.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Tambihan koméntar kana sawala ieu.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Kaca ieu dikonci, tapi anjeun masih bisa muka sumberna.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Vérsi heubeul kaca ieu.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Konci kaca ieu\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Hapus kaca ieu\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Simpen deui éditan kaca ieu nu geus dijieun saméméh dihapus\');
+ta[\'ca-move\'] = new Array(\'m\',\'Pindahkeun kaca ieu\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Anjeun teu wenang mindahkeun kaca ieu\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Tambahkeun kaca ieu kana awaskeuneun kuring\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Kaluarkeun kaca ieu tina awaskeuneun kuring\');
+ta[\'search\'] = new Array(\'f\',\'Téangan wiki ieu\');
+ta[\'p-logo\'] = new Array(\'\',\'Tepas\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Sindang ka Tepas\');
+ta[\'n-portal\'] = new Array(\'\',\'Ngeunaan proyékna, naon nu bisa dipigawé, di mana néangan naon\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Panggihan iber ngeunaan naon baé nu keur lumangsung\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Daptar nu anyar robah na wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Muatkeun kaca naon baé\');
+ta[\'n-help\'] = new Array(\'\',\'Tempat pikeun néangan.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Support us\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Daptar kaca-kaca wiki nu numbu ka dieu\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Nu anyar robah na kaca-kaca nu numbu ka dieu\');
+ta[\'feed-rss\'] = new Array(\'\',\'Asupan RSS pikeun kaca ieu\');
+ta[\'feed-atom\'] = new Array(\'\',\'Asupan atom pikeun kaca ieu\');
+ta[\'t-contributions\'] = new Array(\'\',\'Témbongkeun béréndélan kontribusi pamaké ieu\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Kirim surélék ka pamaké ieu\');
+ta[\'t-upload\'] = new Array(\'u\',\'Muatkeun koropak gambar atawa média\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Daptar sadaya kaca husus\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Témbongkeun eusi kaca\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Témbongkeun kaca pamaké\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Témbongkeun kaca média\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Ieu kaca husus, anjeun teu bisa ngédit ku sorangan.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Témbongkeun kaca proyék\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Témbongkeun kaca gambar\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Témbongkeun pesen sistim\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Témbongkeun citakan\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Témbongkeun kaca pitulung\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Témbongkeun kaca kategori\');',
+'about' => 'Ngeunaan',
+'aboutpage' => '{{ns:project}}:Ngeunaan',
+'aboutsite' => 'Ngeunaan {{SITENAME}}',
+'accmailtext' => 'Sandi keur \'$1\' geus dikirim ka $2.',
+'accmailtitle' => 'Sandi geus dikirim.',
+'acct_creation_throttle_hit' => 'Punten, anjeun geus nyieun $1 rekening, teu bisa nyieun deui.',
+'actioncomplete' => 'Peta geus réngsé',
+'addedwatch' => 'Geus ditambahkeun ka awaskeuneun',
+'addedwatchtext' => 'Kaca "$1" geus ditambahkeun ka [[Special:Watchlist|awaskeuneun]] anjeun.
+Jaga, 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.
+
+<p>Mun jaga anjeun moal deui ngawaskeun parobahan na kaca éta, klik tumbu "Eureun ngawaskeun" na lajursisi.',
+'allarticles' => 'Sadaya artikel',
+'allinnamespace' => 'Sadaya kaca ($1 ngaranspasi)',
+'alllogstext' => 'Témbongan gabungan log muatan, hapusan, koncian, peungpeukan, jeung kuncén. Bisa dipondokkeun ku cara milih tipe log, ngaran pamaké, atawa kaca nu dimaksud.',
+'allmessages' => 'Sadaya pesen sistim',
+'allmessagescurrent' => 'Téks kiwari',
+'allmessagesdefault' => 'Téks ti dituna',
+'allmessagesname' => 'Ngaran',
+'allmessagesnotsupportedDB' => 'Special:AllMessages teu dirojong sabab wgUseDatabaseMessages pareum.',
+'allmessagesnotsupportedUI' => 'Basa antarbeungeut anjeun kiwari <b>$1</b> teu dirojong ku Special:AllMessages na loka ieu.',
+'allmessagestext' => 'Ieu mangrupa daptar sadaya pesen sistim nu aya na spasi ngaran MediaWiki:.',
+'allnotinnamespace' => 'Sadaya kaca (teu na $1 ngaranspasi)',
+'allowemail' => 'Buka koropak pikeun nampa surélék ti nu séjén',
+'allpages' => 'Sadaya kaca',
+'allpagesfrom' => 'Pintonkeun kaca ti mimiti:',
+'allpagesnext' => 'Salajengna',
+'allpagesprev' => 'Saméméhna',
+'allpagessubmit' => 'Jung',
+'alphaindexline' => '$1 ka $2',
+'already_bureaucrat' => 'Pamaké ieu geus boga kalungguhan birokrat',
+'already_sysop' => 'Pamaké ieu geus boga kalungguhan kuncén',
+'alreadyloggedin' => '<strong>Pamaké $1, anjeun geus asup log!</strong><br />',
+'alreadyrolled' => 'Teu bisa mulangkeun édit ahir [[:$1]] ku [[User:$2|$2]] ([[User talk:$2|Obrolan]]); geus aya nu ngédit atawa mulangkeun kacana.
+
+Édit ahir ku [[User:$3|$3]] ([[User talk:$3|Obrolan]]).',
+'ancientpages' => 'Kaca pangheubeulna',
+'and' => 'jeung',
+'anontalk' => 'Obrolan pikeun IP ieu',
+'anontalkpagetext' => '----\'\'Ieu mangrupa kaca sawala pikeun pamaké anonim nu can (henteu) nyieun rekening, kusabab kitu [[alamat IP]] dipaké dina hal ieu pikeun nyirikeun anjeunna. Alamat IP ieu bisa dipaké ku sababaraha urang. Mun anjeun salasahiji pamaké anonim sarta ngarasa aya koméntar nu teu pakait geus ditujukeun ka anjeun, leuwih hadé [[Special:Userlogin|nyieun rekening atawa asup log]] sangkan teu pahili jeung pamaké anonim séjén.\'\'',
+'anonymous' => 'Pamaké anonim {{SITENAME}}',
+'article' => 'Kaca eusi',
+'articleexists' => 'Kaca nu ngaranna kitu geus aya, atawa ngaran nu dipilih ku anjeun teu sah. Mangga pilih ngaran séjén.',
+'articlepage' => 'Témbongkeun kaca eusi',
+'autoblocker' => 'Otomatis dipeungpeuk sabab alamat IP anjeun sarua jeung "$1". Alesan "$2".',
+'badarticleerror' => 'Peta ieu teu bisa dipigawé na kaca ieu.',
+'badfilename' => 'Ngaran gambar geus dirobah jadi "$1".',
+'badfiletype' => '".$1" lain format koropak gambar nu dianjurkeun.',
+'badipaddress' => 'Alamat IP teu sah',
+'badquery' => 'Pamundut néang formatna salah',
+'badquerytext' => 'Kami teu bisa ngolah \'\'query\'\' anjeun, biasana sabab anjeun nyoba néang kecap nu ukur hiji/dua aksara, nu mémang can dirojong; bisa ogé alatan anjeun salah ngetik. Mangga cobian deui.',
+'badretype' => 'Sandi nu diasupkeun teu cocog.',
+'badsig' => 'Parafna teu valid; pariksa tag HTML-na geura.',
+'badtitle' => 'Judul goréng',
+'badtitletext' => 'Judul kaca nu dipénta teu sah, kosong, atawa judul antarbasa atawa antarwikina salah tumbu.',
+'blanknamespace' => '(Utama)',
+'blockedtext' => 'Ngaran pamaké atawa alamat IP anjeun dipeungpeuk ku $1. Alesanana:<br />\'\'$2\'\'<p>Anjeun bisa nepungan $1 atawa salasahiji [[{{ns:project}}:Kuncén|Kuncén]] séjén pikeun nyawalakeun hal ieu.
+
+Catet yén anjeun teu bisa maké fungsi "surélékan pamaké ieu" mun anjeun teu ngadaptarkeun alamat surélék nu sah kana [[Special:Preferences|préferénsi pamaké]] anjeun.
+
+Alamat IP anjeun $3, lampirkeun alamat ieu dina unggal \'\'query\'\' anjeun.',
+'blockedtitle' => 'Pamaké dipeungpeuk',
+'blockip' => 'Peungpeuk pamaké',
+'blockipsuccesssub' => 'Meungpeuk geus hasil',
+'blockipsuccesstext' => '"$1" dipeungpeuk.
+<br />Tempo [[Special:Ipblocklist|daptar peungpeuk IP]] pikeun nempoan deui peungpeuk.',
+'blockiptext' => 'Paké formulir di handap pikeun meungpeuk aksés nulis ti alamat IP atawa ngaran pamaké husus. Ieu sakuduna ditujukeun pikeun nyegah vandalisme, sarta saluyu jeung [[{{ns:project}}:Kawijakan|kawijakan]]. Eusi alesan nu jéntré (misal, ngarujuk kaca tinangtu nu geus diruksak).',
+'blocklink' => 'peungpeuk',
+'blocklistline' => '$1, $2 dipeungpeuk $3 (kadaluwarsa $4)',
+'blocklogentry' => 'dipeungpeuk "$1" nepi ka $2',
+'blocklogpage' => 'Log_peungpeuk',
+'blocklogtext' => 'Ieu mangrupa log peta meungpeuk jeung muka peungpeuk pamaké, teu kaasup alamat IP nu dipeungpeukna otomatis. Tempo [[Special:Ipblocklist|daptar peungpeuk IP]] pikeun daptar cegahan jeung peungpeuk.',
+'bold_sample' => 'Téks kandel',
+'bold_tip' => 'Téks kandel',
+'booksources' => 'Sumber buku',
+'booksourcetext' => 'Di handap ieu daptar tumbu ka situs séjén nu ngajual buku anyar tur urut, sarta bisa jadi boga iber ngeunaan buku nu ditéang. {{SITENAME}} teu aya patalina jeung salasahiji bisnis ieu, sarta daptar ieu ulah dianggap salaku iklan.',
+'brokenredirects' => 'Alihan buntu',
+'brokenredirectstext' => 'Alihan di handap numbu ka kaca nu teu aya.',
+'bugreports' => 'Laporan kutu',
+'bugreportspage' => 'Project:Laporan_kutu',
+'bydate' => 'dumasar titimangsa',
+'byname' => 'dumasar ngaran',
+'bysize' => 'dumasar ukuran',
+'cachederror' => 'Kanggo kaca nu dipénta, di handap ieu mangrupa salinan ti nu aya, tiasa waé tos tinggaleun jaman.',
+'cancel' => 'Bolay',
+'cannotdelete' => 'Teu bisa ngahapus kaca atawa gambar nu dimaksud (bisa jadi geus aya nu ngahapus saméméhna).',
+'cantrollback' => 'Éditan teu bisa dibalikkeun; kontribusi panungtung ngarupakeun hiji-hijina panulis kaca ieu.',
+'categories' => 'Kategori',
+'categoriespagetext' => 'Kategori-kategori di handap ieu aya na wiki.',
+'category_header' => 'Artikel-artikel na kategori "$1"',
+'categoryarticlecount' => 'Aya $1 artikel na kategori ieu.',
+'changed' => 'geus robah',
+'changepassword' => 'Robah sandi',
+'changes' => 'robahan',
+'clearyourcache' => '\'\'\'Catetan:\'\'\' Sanggeus nyimpen, anjeun perlu ngosongkeun \'\'cache\'\' panyungsi anjeun pikeun nempo parobahanana:
+\'\'\'Mozilla/Safari/Konqueror:\'\'\' pencét & tahan \'\'Shift\'\' bari ngaklik \'\'Reload\'\' (atawa pencét \'\'Ctrl-Shift-R\'\'), \'\'\'IE:\'\'\' pencét \'\'Ctrl-F5\'\', \'\'\'Opera:\'\'\' pencét \'\'F5\'\'.',
+'columns' => 'Kolom',
+'compareselectedversions' => 'Bandingkeun vérsi nu dipilih',
+'confirm' => 'Konfirmasi',
+'confirm_purge' => 'Hapus \'\'cache\'\' kaca ieu?
+
+$1',
+'confirm_purge_button' => 'Heug',
+'confirmdelete' => 'Konfirmasi ngahapus',
+'confirmdeletetext' => 'Anjeun rék ngahapus hiji kaca atawa gambar katut jujutanana tina database, mangga yakinkeun yén anjeun mémang niat midamel ieu, yén anjeun ngartos kana sagala konsékuénsina, sarta yén anjeun ngalakukeun ieu saluyu jeung [[{{ns:project}}:Kawijakan|kawijakan {{SITENAME}}]].',
+'confirmemail' => 'Konfirmasi alamat surélék',
+'confirmemail_body' => 'Aya, sigana mah anjeun ti alamat IP $1, geus ngadaptarkeun rekening "$2" maké alamat surélék ieu na {{SITENAME}}.
+
+Pikeun mastikeun yén rekening ieu mémang kagungan sarta ngakifkeun fitur surélék di {{SITENAME}}, buka tumbu di handap ieu kana panyungsi/\'\'browser\'\' anjeun:
+
+$3
+
+Mun ieu *lain* anjeun, tumbuna ulah dituturkeun. Sandi konfirmasi ieu bakal kadaluwarsa $4.',
+'confirmemail_error' => 'Aya nu salah nalika nyimpen konfirmasi anjeun.',
+'confirmemail_invalid' => 'Sandi konfirmasi salah, meureun alatan sandina geus kadaluwarsa.',
+'confirmemail_loggedin' => 'Alamat surélék anjeun geus dikonfirmasi.',
+'confirmemail_send' => 'Kirimkeun surat konfirmasi sandi',
+'confirmemail_sendfailed' => 'Surat konfirmasi teu kakirim. Pariksa alamatna, bisi salah.',
+'confirmemail_sent' => 'Surélék konfirmasi geus dikirim.',
+'confirmemail_subject' => 'Konfirmasi alamat surélék {{SITENAME}}',
+'confirmemail_success' => 'Alamat surélék anjeun geus dikonfirmasi, ayeuna anjeun geus bisa migunakeun wikina.',
+'confirmemail_text' => 'Wiki ieu merlukeun anjeun sangkan méré konfirmasi alamat surélék saméméh migunakeun fitur surélék. Aktifkeun tombol di handap pikeun ngirimkeun surat konfirmasi ka alamat anjeun. Suratna ngandung tumbu nu ngandung sandina; muatkeun tumbuna kana panyungsi anjeun pikeun ngonfirmasi yén alamat surélék anjeun sah.',
+'confirmprotect' => 'Konfirmasi ngonci',
+'confirmprotecttext' => 'Naha anjeun leres hoyong ngonci kaca ieu?',
+'confirmrecreate' => 'Pamaké [[User:$1|$1]] ([[User talk:$1|ngobrol]]) geus ngahapus artikel ieu nalika anjeun ngédit kalawan alesan:
+: \'\'$2\'\'
+mangga pastikeun yén anjeun rék nyieun deui artikel ieu.',
+'confirmunprotect' => 'Konfirmasi muka konci',
+'confirmunprotecttext' => 'Naha anjeun leres hoyong muka konci kaca ieu?',
+'contextchars' => 'Karakter kontéks per baris',
+'contextlines' => 'Jumlah baris sakali némbongan',
+'contribslink' => 'sumbang',
+'contribsub' => 'Pikeun $1',
+'contributions' => 'Kontribusi pamaké',
+/*'copyright' => 'Sadaya kandungan ieu loka aya dina panangtayungan <a class=\'internal\' href="{{localurle:{{ns:project}}:Téks_Lisénsi Dokumén Bébas GNU}}">Lisénsi Dokumén Bébas GNU</a> (tingal <b><a class=\'internal\' href="{{localurle:{{ns:project}}:Hak cipta}}">Hak cipta</a></b> sangkan leuwih jéntré).<br />',*/
+'copyrightpage' => '{{ns:project}}:Hak cipta',
+'copyrightpagename' => 'Hak cipta {{SITENAME}}',
+/*'copyrightwarning' => 'Parobahan jieunan anjeun bakal geuwat katémbong.
+* Pikeun nyoba-nyoba, mangga pigunakeun [[{{ns:project}}:Kotrétan|kotrétan]].
+* Anjeun dirojong pisan pikeun nyieun, ngembangkeun, sarta ngaronjatkeun mutu artikel; tapi, éditan goréng bakal kaawaskeun sahingga bisa geuwat dihapus/diropéa deui.
+* \'\'\'Mangga\'\' [[{{ns:project}}:Cutat rujukan|cutat rujukan anjeun]]\'\' sahingga nu séjén bisa mariksa karya anjeun.
+----
+Perhatikeun yén sadaya kontribusi ka MediaWiki dianggap medal dina panangtayungan Lisénsi Dokumén Bébas GNU (tempo $1 pikeun jéntréna). Mun anjeun teu miharep tulisan anjeun dirobah sarta disebarkeun deui, ulah dilebetkeun ka dieu.<br />
+Anjeun ogé jangji yén tulisan ieu dijieun ku sorangan, atawa disalin ti \'\'domain\'\' umum atawa sumberdaya bébas séjénna. <strong>ULAH NGALEBETKEUN KARYA NU MIBANDA HAK CIPTA TANPA IDIN!</strong>',*/
+'copyrightwarning2' => 'Catet yén sadaya kontribusi ka {{SITENAME}} bisa diédit, dirobah, atawa dihapus ku kontributor séjén. Mun anjeun teu miharep tulisan anjeun dirobah, ulah ngintunkeun ka dieu.<br />
+Anjeun ogé mastikeun yén ieu téh pituin tulisan anjeun, atawa salinan ti domain umum atawa sumberdaya bébas séjénna (tempo $1 pikeun écésna).
+<strong>ULAH NGINTUNKEUN KARYA NU MIBANDA HAK CIPTA TANPA WIDI!</strong>',
+'couldntremove' => 'Teu bisa ngahapus \'$1\'...',
+'createaccount' => 'Jieun rekening anyar',
+'createaccountmail' => 'ku surélék',
+'createarticle' => 'Jieun artikel',
+'created' => 'geus dijieun',
+'creditspage' => 'Pangajén kaca',
+'cur' => 'kiw',
+'currentevents' => 'Keur lumangsung',
+'currentevents-url' => 'Keur lumangsung',
+'currentrev' => 'Révisi kiwari',
+'currentrevisionlink' => 'Témbongkeun révisi kiwari',
+'databaseerror' => 'Kasalahan gudang data',
+'datedefault' => 'Tanpa préferénsi',
+'dateformat' => 'Format titimangsa',
+'datetime' => 'Titimangsa jeung wanci',
+'dberrortext' => 'Kasalahan rumpaka mundut databasis.
+Ieu bisa nunjukkeun ayana kutu na parabot leuleusna.
+Pamundut databasis nu panungtungan nyaéta:
+<blockquote><tt>$1</tt></blockquote>
+ti antara fungsi "<tt>$2</tt>".
+Kasalahan MySQL nu mulang "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Kasalahan rumpaka mundut databasis.
+Pamuncut databasis nu panungtungan nyaéta:
+"$1"
+ti antara fungsi "$2".
+Kasalahan MySQL nu mulang "$3: $4".',
+'deadendpages' => 'Kaca buntu',
+'default' => 'ti dituna',
+'defaultns' => 'Téang ti antara spasingaran ieu luyu jeung ti dituna:',
+'defemailsubject' => 'Surélék {{SITENAME}}',
+'delete' => 'Hapus',
+'delete_and_move' => 'Hapus jeung pindahkeun',
+'delete_and_move_reason' => 'Hapus sangkan bisa mindahkeun',
+'delete_and_move_text' => '==Merlukeun hapusan==
+
+Artikel nu dituju "[[$1]]" geus aya. Badé dihapus baé sangkan bisa mindahkeun?',
+'deletecomment' => 'Alesan ngahapus',
+'deletedarticle' => 'ngahapus "$1"',
+'deletedrev' => '[dihapus]',
+'deletedrevision' => 'Révisi heubeul nu dihapus $1.',
+'deletedtext' => '"$1" geus dihapus. Tempo $2 pikeun rékaman hapusan anyaran ieu.',
+'deletedwhileediting' => 'Awas: kaca ieu geus dihapus nalika anjeun ngédit!',
+'deleteimg' => 'hap',
+'deleteimgcompletely' => 'Hapus sadaya révisi',
+'deletepage' => 'Hapus kaca',
+'deletesub' => '(Ngahapus "$1")',
+'deletethispage' => 'Hapus kaca ieu',
+'deletionlog' => 'log hapusan',
+'dellogpage' => 'Log_hapusan',
+'dellogpagetext' => 'Di handap ieu daptar hapusan nu ahir-ahir, sakabéh wanci dumasar wanci server (UTC).
+<ul>
+</ul>',
+'destfilename' => 'Ngaran koropak tujuan',
+'diff' => 'béda',
+'difference' => '(Béda antarrévisi)',
+'disambiguations' => 'Kaca disambiguasi',
+'disambiguationspage' => 'Project:Tumbu_ka_kaca_disambiguasi',
+'disambiguationstext' => 'Kaca ieu numbu ka <i>kaca disambiguasi</i>, nu sakuduna mah numbu ka kaca nu ditujul.<br />Hiji kaca dianggap salaku disambiguasi mun numbu ti $1.<br />Tumbu ti ngaranspasi séjén <i>teu</i> dibéréndélkeun di dieu.',
+'disclaimerpage' => '{{ns:project}}:Bantahan_umum',
+'disclaimers' => 'Bantahan',
+'doubleredirects' => 'Alihan ganda',
+'doubleredirectstext' => 'Unggal baris ngandung tumbu ka pangalihan kahiji jeung kadua, kitu ogé téks dina baris kahiji pangalihan kadua, nu biasana méré kaca tujuan nu bener, nu sakuduna ditujul dina pangalihan kahiji.',
+'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.',
+'edit' => 'Édit',
+'edit-externally' => 'Édit koropak ieu migunakeun aplikasi éksternal',
+'edit-externally-help' => 'Tempo [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] pikeun émbaran leuwih jéntré.',
+'editcomment' => 'Komentar ngéditna: "<i>$1</i>".',
+'editconflict' => 'Konflik éditan: $1',
+'editcurrent' => 'Édit vérsi kiwari kaca ieu',
+'edithelp' => 'Pitulung ngédit',
+'edithelppage' => 'Pitulung:Ngédit',
+'editing' => 'Ngédit $1',
+'editinguser' => 'Ngédit $1',
+'editingcomment' => 'Ngédit $1 (pamanggih)',
+'editingold' => '<strong>PERHATOSAN: Anjeun ngédit révisi kadaluwarsa kaca ieu. Mun ku anjeun disimpen, sagala parobahan nu dijieun sanggeus révisi ieu bakal leungit.</strong>',
+'editingsection' => 'Ngédit $1 (bagian)',
+'editsection' => 'édit',
+'editold' => 'édit',
+'editthispage' => 'Édit kaca ieu',
+'editusergroup' => 'Édit Golongan Pamaké',
+'email' => 'Surélék',
+'emailauthenticated' => 'Alamat surélék anjeun geus dioténtikasi $1.',
+'emailconfirmlink' => 'Konfirmasi alamat surélék anjeun',
+'emailfrom' => 'Ti',
+'emailmessage' => 'Pesen',
+'emailnotauthenticated' => 'Alamat surélék anjeun can dioténtikasi. Moal aya surélék nu bakal dikirim pikeun fitur-fitur di handap ieu.',
+'emailpage' => 'Surélékan pamaké',
+'emailpagetext' => 'Mun pamaké ieu ngasupkeun alamat surélék nu sah na préferénsi pamakéna, formulir di handap bakal ngirimkeun hiji pesen. Alamat surélék nu ku anjeun diasupkeun kana préferénsi pamaké anjeun bakal katémbong salaku alamat "Ti" surélékna, sahingga nu dituju bisa ngabales.',
+'emailsend' => 'Kirim',
+'emailsent' => 'Surélék geus dikirim',
+'emailsenttext' => 'Pesen surélék anjeun geus dikirim.',
+'emailsubject' => 'Ngeunaan',
+'emailto' => 'Ka',
+'emailuser' => 'Surélékan pamaké ieu',
+'emptyfile' => 'Koropak nu dimuatkeun ku anjeun jigana kosong. Hal ieu bisa jadi alatan sarupaning \'\'typo\'\' na ngaran koropakna. Mangga parios deui yén anjeun leres-leres hoyong ngamuat koropak éta.',
+'enotif_body' => 'Sadérék $WATCHINGUSERNAME,
+
+Kaca $PAGETITLE na {{SITENAME}} geus $CHANGEDORCREATED tanggal $PAGEEDITDATE ku $PAGEEDITOR. Mangga tingal {{fullurl:$PAGETITLE_RAWURL}} pikeun vérsi kiwari.
+
+$NEWPAGE
+
+Ringkesan éditor: $PAGESUMMARY $PAGEMINOREDIT
+
+Kontak éditor:
+surat {{fullurl:Special:Emailuser|target=$PAGEEDITOR_RAWURL}}
+wiki {{fullurl:User:$PAGEEDITOR_RAWURL}}
+
+Mun anjeun teu sindang deui ka ieu kaca, parobahan salajengna moal diémbarkeun. Anjeun bisa ogé nyetél deui umbul-umbul pikeun sadaya kaca nu aya na daptar awaseun anjeun.
+
+ Sistim émbaran {{SITENAME}} pikeun anjeun
+
+--
+Pikeun ngarobah setélan dabtar awaseun anjeun, sindang ka {{fullurl:Special:Watchlist|edit=yes}}
+
+Asupan jeung bantuan salajengna:
+{{fullurl:{{ns:project}}:Pitulung}}',
+'enotif_lastvisited' => 'Tempo {{fullurl:$PAGETITLE_RAWURL|diff=0&oldid=$OLDID}} pikeun sadaya parobahan ti saprak anjeun ninggalkeun ieu kaca.',
+'enotif_mailer' => 'Surat Émbaran {{SITENAME}}',
+'enotif_newpagetext' => 'Kaca ieu anyar.',
+'enotif_reset' => 'Tandaan sadaya kaca nu geus dilongok',
+'enotif_subject' => 'Kaca $PAGETITLE {{SITENAME}} geus $CHANGEDORCREATED ku $PAGEEDITOR',
+'enterlockreason' => 'Asupkeun alesan pikeun ngonci, kaasup kira-kira iraha konci ieu rék dibuka',
+'error' => 'Kasalahan',
+'errorpagetitle' => 'Kasalahan',
+'exbeforeblank' => 'eusi méméh dikosongkeun nyéta:',
+'exblank' => 'kaca ieu kosong',
+'excontent' => 'eusina nu heubeul:',
+'excontentauthor' => 'eusina: \'$1\' (nu dikontribusi ku \'$2\' wungkul)',
+'exif-artist' => 'Pangarang',
+'explainconflict' => 'Aya nu geus ngarobah kaca ieu saprak anjeun mimiti ngédit. Téks béh luhur ngandung téks kaca nu aya kiwari, parobahan anjeun ditémbongkeun di béh handap. Anjeun kudu ngagabungkeun parobahan anjeun kana téks nu kiwari.
+<b>Ngan</b> téks nu béh luhur nu bakal disimpen nalika anjeun mencét "Simpen".
+<p>',
+'export' => 'Ékspor kaca',
+'exportcuronly' => 'Asupkeun ukur révisi kiwari, teu sakabéh jujutan',
+'exporttext' => 'Anjeun bisa ngékspor téks sarta jujutan éditan ti kaca tinangtu atawa ti sababaraha kaca nu ngagunduk na sababaraha XML; ieu salajengna tiasa diimpor ka wiki séjén nu ngajalankeun software MediaWiki, ditransformasikeun, atawa ukur disimpen pikeun kaperluan anjeun pribadi.',
+'extlink_sample' => 'Judul tumbu http://www.conto.com',
+'extlink_tip' => 'Tumbu kaluar (inget awalan http://)',
+'faq' => 'NLD',
+'faqpage' => '{{ns:project}}:NLD',
+'feedlinks' => 'Asupan:',
+'filecopyerror' => 'Teu bisa nyalin koropak "$1" ka "$2".',
+'filedeleteerror' => 'Teu bisa ngahapus koropak "$1".',
+'filedesc' => 'Ringkesna',
+'fileexists' => 'Koropak nu ngaranna kieu geus aya, mangga parios $1 mun anjeun teu yakin rék ngaganti.',
+'fileexists-forbidden' => 'Koropak nu ngaranna ieu geus aya; mangga balik deui sarta muatkeun koropakna maké ngaran nu béda. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'Koropak nu ngaranna ieu geus aya dina gudang koropak babagi (\'\'shared file repository\'\'); mangga balik deui sarta muatkeun koropak ieu maké ngaran nu béda. [[Image:$1|thumb|center|$1]]',
+'filemissing' => 'Koropak leungit',
+'filename' => 'Ngaran koropak',
+'filenotfound' => 'Teu bisa manggihan koropak "$1".',
+'filerenameerror' => 'Teu bisa ngaganti ngaran koropak "$1" jadi "$2".',
+'files' => 'Koropak',
+'filesource' => 'Sumber',
+'filestatus' => 'Status hak cipta',
+'fileuploaded' => 'Koropak "$1" geus réngsé dimuat. Tuturkeun tumbu ieu: $2 pikeun kaca dadaran sarta iber ngeunaan koropakna, kayaning ti mana asalna, dijieun iraha jeung ku saha, sarta nu séjénna nu anjeun nyaho.',
+'fileuploadsummary' => 'Ringkesan:',
+'formerror' => 'Kasalahan: teu bisa ngirim formulir',
+'go' => 'Jung',
+'searcharticle' => 'Jung',
+'guesstimezone' => 'Eusian ti panyungsi',
+'headline_sample' => 'Téks judul',
+'headline_tip' => 'Judul tingkat 2',
+'help' => 'Pitulung',
+'helppage' => '{{ns:project}}:Pitulung',
+'hide' => 'sumputkeun',
+'hidetoc' => 'sumputkeun',
+'hist' => 'juj',
+'histfirst' => 'Pangheubeulna',
+'histlast' => 'Pangahirna',
+'histlegend' => 'Pilihan béda: tandaan wadah buleud vérsina pikeun ngabandingkeun sarta pencét énter atawa tombol di handap.<br />
+Katerangan: (kiw) = bédana jeung vérsi kiwari,
+(ahir) = bédana jeung vérsi nu harita, m = éditan minor.',
+'history' => 'Jujutan kaca',
+'history_short' => 'Jujutan',
+'historywarning' => 'Perhatosan: Kaca nu rék dihapus mibanda jujutan:',
+'hr_tip' => 'Garis horizontal (use sparingly)',
+'ignorewarning' => 'Ulah diwaro, simpen baé koropakna.',
+'illegalfilename' => 'Ngaran koropak "$1" ngandung aksara nu teu diwenangkeun pikeun judul kaca. Mangga gentos ngaranna tur cobi muatkeun deui.',
+'ilsubmit' => 'Téang',
+'image_sample' => 'Conto.jpg',
+'imagelinks' => 'Tumbu gambar',
+'imagelist' => 'Daptar gambar',
+'imagelistall' => 'kabéh',
+'imagelisttext' => 'Di handap ieu daptar $1 gambar nu disusun $2.',
+'imagemaxsize' => 'Watesan gambar na kaca dadaran gambar nepi ka:',
+'imagepage' => 'Témbongkeun kaca gambar',
+'imagereverted' => 'Malikkeun deui ka vérsi nu saméméhna geus réngsé.',
+'imgdelete' => 'hap',
+'imgdesc' => 'dad',
+'imghistlegend' => 'Katerangan: (kiw) = ieu salaku gambar kiwari, (hps) = hapus vérsi heubeul ieu, (blk) = balikkeun ka vérsi heubeul ieu.
+<br /><i>Klik na titimangsa pikeun nempo gambar nu dimuat poé éta</i>.',
+'imghistory' => 'Jujutan gambar',
+'imglegend' => 'Katerangan: (desc) = témbongkeun/édit dadaran gambar.',
+'immobile_namespace' => 'Judul nu dituju kaasup kana tipe husus, teu bisa mindahkeun kaca ka ngaranspasi kitu.',
+'import' => 'Impor kaca',
+'importfailed' => 'Ngimpor gagal: $1',
+'importhistoryconflict' => 'Aya révisi jujutan nu béntrok (may have imported this page before)',
+'importinterwiki' => 'Impor transwiki',
+'importnotext' => 'Kosong atawa teu aya téks',
+'importsuccess' => 'Ngimpor geus hasil!',
+'importtext' => 'Mangga ékspor koropakna ti sumber nu dipaké ku wiki migunakeun fungsi Special:Export, simpen na piringan anjeun, teras muatkeun di dieu.',
+'info_short' => 'Iber',
+'infosubtitle' => 'Iber pikeun kaca',
+'internalerror' => 'Kasalahan internal',
+'intl' => 'Tumbu antarbasa',
+'invalidemailaddress' => 'Alamat surélék teu bisa ditarima sabab formatna salah. Mangga lebetkeun alamat nu formatna bener atawa kosongkeun.',
+'invert' => 'Balikkeun pilihan',
+'ip_range_invalid' => 'Angka IP teu bener.',
+'ipaddress' => 'Alamat IP/ngaran pamaké',
+'ipadressorusername' => 'Alamat IP atawa ngaran pamaké',
+'ipb_expiry_invalid' => 'Wanci daluwarsa teu bener.',
+'ipbexpiry' => 'Kadaluarsa',
+'ipblocklist' => 'Daptar alamat IP jeung ngaran pamaké nu dipeungpeuk',
+'ipboptions' => '2 jam:2 jam,sapoé:sapoé,3 poé:3 poé,saminggu:saminggu,2 minggu:2 minggu,sabulan:sabulan,3 bulan:3 bulan,6 bulan:6 bulan,sataun:sataun,tanpa wates:tanpa wates',
+'ipbother' => 'Waktu séjén',
+'ipbotheroption' => 'séjénna',
+'ipbreason' => 'Alesan',
+'ipbsubmit' => 'Peungpeuk pamaké ieu',
+'ipusubmit' => 'Buka peungpeuk pikeun pamaké ieu',
+'isredirect' => 'Kaca alihan',
+'italic_sample' => 'Tulisan déngdék',
+'italic_tip' => 'Tulisan déngdék',
+'iteminvalidname' => 'Masalah dina \'$1\', ngaran teu bener...',
+'laggedslavemode' => 'Awas: kandungan kaca bisa baé teu mutahir.',
+'largefile' => 'Dianjurkeun sangkan ukuran gambar teu leuwih ti 100k.',
+'last' => 'ahir',
+'lastmodifiedat' => 'Kaca ieu panungtungan dirobah $2, $1.',
+'lastmodifiedatby' => 'Kaca ieu panungtungan dirobah $2, $1 ku $3.',
+'lineno' => 'Baris ka-$1:',
+'link_sample' => 'Judul tumbu',
+'link_tip' => 'Tumbu internal',
+'linklistsub' => '(Daptar tumbu)',
+'linkshere' => 'Kaca di handap ieu numbu ka dieu:',
+'linkstoimage' => 'Kaca nu numbu ka gambar ieu:',
+'listingcontinuesabbrev' => ' (samb.)',
+'listusers' => 'Daptar pamaké',
+'loadhist' => 'Keur ngamuat jujutan kaca',
+'loadingrev' => 'ngamuat béda révisi',
+'localtime' => 'Témbongan wanci lokal',
+'lockbtn' => 'Konci database',
+'lockconfirm' => 'Leres pisan, simkuring hoyong ngonci database.',
+'lockdb' => 'Konci database',
+'lockdbsuccesssub' => 'Database geus hasil dikonci',
+'lockdbsuccesstext' => 'Database dikonci.
+<br />Ulah poho muka konci mun maintenance geus bérés.',
+'lockdbtext' => 'Ngonci gudang data bakal numpurkeun kabisa sakabéh pamaké pikeun ngédit kaca, ngarobah préferénsina, ngédit awaskeuneunana, sarta hal séjén nu merlukeun parobahan na gudang data. Konfirmasikeun yén ieu nu dimaksud ku anjeun, sarta anjeun bakal muka konci gudang data nalika pangropéa anjeun geus réngsé.',
+'locknoconfirm' => 'Anjeun teu nyontréngan kotak konfirmasi.',
+'log' => 'Log',
+'login' => 'Asup log',
+'loginerror' => 'Kasalahan asup log',
+'loginpagetitle' => 'Asup log pamaké',
+'loginproblem' => '<b>Aya masalah na \'\'login\'\' anjeun.</b><br />Coba deui!',
+'loginprompt' => 'Anjeun kudu boga \'\'cookies\'\' sangkan bisa asup log ka {{SITENAME}}.',
+'loginreqlink' => 'asup log',
+'loginreqpagetext' => 'Muné hayang muka kaca séjénna, Anjeun kudu $1.',
+'loginreqtitle' => 'Kudu asup log',
+'loginsuccess' => 'Anjeun ayeuna geus asup log ka {{SITENAME}} salaku "$1".',
+'loginsuccesstitle' => 'Asup log geus hasil',
+'logout' => 'Kaluar log',
+'logouttext' => 'Anjeun ayeuna geus kaluar log. Anjeun bisa neruskeun migunakeun {{SITENAME}} bari anonim, atawa bisa asup log deui maké pamaké nu sarua atawa nu béda. Perlu dicatet yén sababaraha kaca bakal terus némbongan saolah-olah anjeun asup log kénéh nepi ka anjeun ngosongkeun \'\'cache\'\' panyungsi anjeun.',
+'logouttitle' => 'Kaluar log pamaké',
+'lonelypages' => 'Kaca-kaca nunggelis',
+'longpages' => 'Kaca-kaca paranjang',
+'longpagewarning' => 'PERHATOSAN: Kaca ieu panjangna $1 kilobytes; sababaraha panyungsi boga masalah dina ngédit kaca nu panjangna nepi ka 32kb. Please consider breaking the page into smaller sections.',
+'mailerror' => 'Kasalahan ngirim surat: $1',
+'mailmypassword' => 'Kirim sandi anyar ngaliwatan surélék',
+'mailnologin' => 'Euweuh alamat ngirim',
+'mailnologintext' => 'Anjeun kudu <a href="{{localurl:Special:Userlogin">asup log</a> sarta boga alamat surélék nu sah na <a href="{{localurl:Special:Preferences">préferénsi</a> anjeun sangkan bisa nyurélékan pamaké séjén.',
+'mainpage' => 'Tepas',
+'mainpagedocfooter' => 'Mangga tingal \'\'[http://meta.wikimedia.org/wiki/MediaWiki_i18n documentation on customizing the interface]\'\' jeung [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Tungtunan Pamaké] pikeun pitulung maké jeung konfigurasi.',
+'mainpagetext' => '\'\'Software\'\' Wiki geus diinstal.',
+'makesysop' => 'Ngangkat pamaké jadi kuncén',
+'makesysopfail' => '<b>Pamaké "$1" teu bisa dijadikeun kuncén. (Ngaran nu diasupkeun bener teu?)</b>',
+'makesysopname' => 'Ngaran pamaké:',
+'makesysopok' => '<b>Pamaké "$1" ayeuna geus jadi kuncén</b>',
+'makesysopsubmit' => 'Angkat pamaké ieu jadi kuncén',
+'makesysoptext' => 'Formulir ieu dipaké ku birokrat pikeun ngangkat pamaké biasa jadi kuncén. Ketik ngaran pamaké na kotak, terus pencét tombol pikeun ngangkat pamaké jadi kuncén.',
+'makesysoptitle' => 'Ngangkat pamaké jadi kuncén',
+'markaspatrolleddiff' => 'Tandaan salaku geus diriksa',
+'markaspatrolledtext' => 'Tandaan artikel ieu salaku geus diriksa',
+'markedaspatrolled' => 'Tandaan salaku geus diriksa',
+'markedaspatrolledtext' => 'Révisi nu dipilih geus ditandaan salaku geus diriksa.',
+'matchtotals' => '\'\'Query\'\' "$1" cocog jeung $2 judul kaca sarta tulisan na $3 kaca.',
+'math_sample' => 'Asupkeun rumus di dieu',
+'math_syntax_error' => 'Kasalahan rumpaka',
+'math_tip' => 'Rumus matematis (LaTeX)',
+'math_unknown_error' => 'Kasalahan teu kanyahoan',
+'math_unknown_function' => 'fungsi teu kanyahoan',
+'media_sample' => 'Conto.mp3',
+'media_tip' => 'Tumbu koropak média',
+'mimetype' => 'MIME type:',
+'minlength' => 'Ngaran gambar sahenteuna kudu tilu aksara.',
+'minoredit' => 'Ieu éditan minor',
+'missingimage' => '<b>Gambar leungit</b><br /><i>$1</i>',
+'moredotdotdot' => 'Deui...',
+'move' => 'Pindahkeun',
+'movearticle' => 'Pindahkeun kaca',
+'movedto' => 'dipindahkeun ka',
+'movelogpage' => 'Log mindahkeun',
+'movelogpagetext' => 'Di handap ieu béréndélan kaca nu dipindahkeun.',
+'movenologin' => 'Can asup log',
+'movenologintext' => 'Anjeun kudu jadi pamaké nu kadaptar tur [[Special:Userlogin|asup log]] pikeun mindahkeun kaca.',
+'movepage' => 'Pindahkeun kaca',
+'movepagebtn' => 'Pindahkeun kaca',
+'movepagetalktext' => 'Kaca obrolan nu patali, mun aya, bakal sacara otomatis kapindahkeun, \'\'\'iwal:\'\'\'
+*Anjeun mindahkeun kacana meuntas spasingaran nu béda,
+*Kaca obrolan dina ngaran nu anyar geus aya eusian, atawa
+*Anjeun teu nyontréngan kotak di handap.
+
+Dina kajadian kitu, mun hayang (jeung perlu) anjeun kudu mindahkeun atawa ngagabungkeun kacana sacara manual.',
+'movepagetext' => 'Migunakeun formulir di handap bakal ngaganti ngaran hiji kaca, mindahkeun sadaya jujutanana ka ngaran anyar.
+Judul nu heubeul bakal jadi kaca alihan ka judul nu anyar.
+Tumbu ka judul kaca nu heubeul mola robah; pastikeun yén anjeun [[Special:Maintenance|marios]] alihan ganda atawa alihan nu buntu.
+Anjeun tanggel waler pikeun mastikeun yén tumbu-tumbu tetep nujul ka tempat nu sakuduna dituju.
+
+Catet yén kacana \'\'\'moal\'\'\' pindah mun geus aya kaca na judul nu anyar, iwal mun kosong atawa mangrupa alihan sarta teu mibanda jujutan éditan heubeul. Ieu ngandung harti yén anjeun bisa ngaganti ngaran hiji kaca balik deui ka nu cikénéh diganti ngaranna mun anjeun nyieun kasalahan, sarta anjeun teu bisa nimpah kaca nu geus aya.
+
+<b>AWAS!</b> This can be a drastic and unexpected change for a popular page;
+please be sure you understand the consequences of this before
+proceeding.',
+'movereason' => 'Alesan',
+'movetalk' => 'Mun bisa, kaca "obrolan" ogé pindahkeun.',
+'movethispage' => 'Pindahkeun kaca ieu',
+'mw_math_html' => 'Mun bisa HTML, mun henteu PNG',
+'mw_math_mathml' => 'Mun bisa MathML (uji coba)',
+'mw_math_modern' => 'Dianjurkeun pikeun panyungsi modérn',
+'mw_math_simple' => 'Mun basajan HTML, mun henteu PNG',
+'mw_math_source' => 'Antep salaku TeX (pikeun panyungsi tulisan)',
+'mycontris' => 'Kontribusi kuring',
+'mypage' => 'Kaca kuring',
+'mytalk' => 'Obrolan kuring',
+'namespace' => 'Ngaranspasi:',
+'namespacesall' => 'kabéh',
+'navigation' => 'Pituduh',
+'nbytes' => '$1 bait',
+'ncategories' => '$1 kategori',
+'newarticle' => '(Anyar)',
+'newarticletext' => 'Anjeun geus nuturkeun tumbu ka kaca nu can aya.
+Pikeun nyieun kaca, mimitian ku ngetik jeroeun kotak di handap
+(tempo [[{{ns:project}}:Pitulung|kaca pitulung]] pikeun leuwih écés).
+Mun anjeun ka dieu teu ngahaja, klik baé tombol \'\'\'back\'\'\' na panyungsi anjeun.',
+'newbies' => 'anyaran',
+'newimages' => 'Galeri gambar anyar',
+'newmessageslink' => 'pesen anyar',
+'newpage' => 'Kaca anyar',
+'newpageletter' => 'A',
+'newpages' => 'Kaca anyar',
+'newpassword' => 'Sandi anyar',
+'newtitle' => 'Ka judul anyar',
+'newwindow' => '(buka na jandéla anyar)',
+'next' => 'salajengna',
+'nextdiff' => 'Ka béda salajengna, jung&rarr;',
+'nextn' => '$1 salajengna',
+'nextpage' => 'Kaca salajengna ($1)',
+'nextrevision' => 'Révisi nu leuwih anyar&rarr;',
+'nlinks' => '$1 tumbu',
+'noarticletext' => '(Kiwari can aya téks na kaca ieu. Mun anjeun geus kungsi nyieun kaca ieu, mangga klik [{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=purge}} di dieu].)',
+'noconnect' => 'Punten! Wiki ngalaman sababaraha kasusah téhnis sarta teu bisa ngontak server database.',
+'nocontribs' => 'Taya robahan nu kapanggih cocog jeung patokan ieu.',
+'nocookieslogin' => '{{SITENAME}} migunakeun \'\'cookies\'\' pikeun ngasupkeun pamaké kana log. Anjeun boga \'\'cookies\'\' nu ditumpurkeun. Mangga pungsikeun sarta cobian deui.',
+'nocookiesnew' => 'Rekening pamaké geus dijieun, tapi anjeun can asup log. {{SITENAME}} maké \'\'cookies\'\' pikeun ngasupkeun log pamaké. Anjeun boga \'\'cookies\'\' nu ditumpurkeun. Mangga fungsikeun, teras asup log migunakeun ngaran pamaké sarta sandi nu anyar.',
+'nocredits' => 'Teu aya émbaran pangajén pikeun kaca ieu.',
+'nodb' => 'Teu bisa milih database $1',
+'noemail' => 'Teu aya alamat surélék karékam pikeun "$1".',
+'noemailprefs' => '<strong>Teu aya alamat surélék</strong>, fitur di handap moal bisa jalan.',
+'noemailtext' => 'Pamaké ieu teu méré alamat surélék nu sah atawa milih teu narima surélék ti pamaké séjén.',
+'noemailtitle' => 'Teu aya alamat surélék',
+'noexactmatch' => '<span style="font-size: 135%; font-weight: bold; margin-left: .6em">Teu aya kaca nu judulna kitu</span>
+
+<span style="display: block; margin: 1.5em 2em">
+Coba saksrak na téks lengkep, atawa \'\'\'[[<nowiki>$1</nowiki>|nyieun artikel nu judulna kitu]]\'\'\' atawa [[{{ns:project}}:Artikel pamundut|mundut dijieunna éta artikel]].
+
+<span style="display:block; font-size: 89%; margin-left:.2em">Mangga sungsi {{SITENAME}} saméméh nyieun artikel anyar, pikeun ngahindarkeun artikel ganda nu ukur béda éjahan/ngaran.</span>
+</span>',
+'nohistory' => 'Teu aya jujutan édit pikeun kaca ieu.',
+'noimages' => 'Taya nanaon.',
+'nolinkshere' => 'Euweuh kaca nu numbu ka dieu.',
+'nolinkstoimage' => 'Teu aya kaca nu numbu ka gambar ieu.',
+'nologin' => 'Teu gaduh rekening? $1.',
+'nologinlink' => 'Jieun rekening',
+'noname' => 'Anjeun teu nuliskeun ngaran pamaké nu sah.',
+'nonefound' => '<strong>Catetan</strong>: panéangan nu teu hasil mindeng disababkeun ku néang kecap umum kawas "ti" nu teu diasupkeun kana indéks, atawa alatan nangtukeun leuwih ti hiji istilah panéang (ngan kaca-kaca nu ngandung sakabéh istilah panéang nu bakal némbongan).',
+'nonunicodebrowser' => '<strong>AWAS: Panyungsi anjeung teu maké unicode, mangga robah heula méméh ngédit artikel.</strong>',
+'nospecialpagetext' => 'Anjeun geus ménta kaca husus nu teu dipikawanoh ku wiki.',
+'nosuchaction' => 'Teu aya peta kitu',
+'nosuchactiontext' => 'Peta nu diketik na URL teu dipikawanoh ku wiki',
+'nosuchspecialpage' => 'Teu aya kaca husus nu kitu',
+'nosuchuser' => 'Teu aya pamaké nu ngaranna "$1". Pariksa éjahanana, atawa paké formulir di handap pikeun nyieun rekening pamaké anyar.',
+'nosuchusershort' => 'Taya pamaké nu ngaranna "$1", pariksa éjahanana!',
+'notacceptable' => '\'\'Server\'\' wiki teu bisa nyadiakeun data dina format nu bisa dibaca ku klien anjeun.',
+'notanarticle' => 'Sanés kaca eusi',
+'notargettext' => 'Anjeun can nangtukeun hiji targét atawa pamaké pikeun migawé sangkan fungsi ieu jalan.',
+'notargettitle' => 'Taya tujuleun',
+'note' => '<strong>Catetan:</strong>',
+'notextmatches' => 'Teu aya téks kaca nu cocog',
+'notitlematches' => 'Teu aya judul kaca nu cocog',
+'notloggedin' => 'Can asup log',
+'nowatchlist' => 'Anjeun teu boga awaskeuneun.',
+'nowiki_sample' => 'Asupkeun téks nu teu diformat di dieu',
+'nowiki_tip' => 'Format wiki tong diwaro',
+'nrevisions' => '$1 révisi',
+'nstab-category' => 'Kategori',
+'nstab-help' => 'Pitulung',
+'nstab-image' => 'Gambar',
+'nstab-main' => 'Artikel',
+'nstab-media' => 'Média',
+'nstab-mediawiki' => 'Pesen',
+'nstab-special' => 'Husus',
+'nstab-template' => 'Citakan',
+'nstab-user' => 'Kaca pamaké',
+'nstab-project' => 'Ngeunaan',
+'numauthors' => 'Jumlah pangarang nu béda (artikel): $1',
+'number_of_watching_users_pageview' => '[$1 pamaké nu ngawaskeun]',
+'numedits' => 'Jumlah éditan (artikel): $1',
+'numtalkauthors' => 'Jumlah pangarang nu béda (kaca sawala): $1',
+'numtalkedits' => 'Jumlah éditan (kaca sawala): $1',
+'numwatchers' => 'Jumlah nu ngawaskeun: $1',
+'nviews' => '$1 témbongan',
+'ok' => 'Heug',
+'oldpassword' => 'Sandi heubeul',
+'orig' => 'asli',
+'othercontribs' => 'Dumasar karya $1.',
+'otherlanguages' => 'Basa séjén',
+'others' => 'Séjénna',
+'pagecategories' => 'Kategori',
+'pagemovedsub' => 'Mindahkeun geus hasil!',
+'pagemovedtext' => 'Kaca "[[$1]]" dipindahkeun ka "[[$2]]".',
+'pagetitle' => '$1 - {{SITENAME}}',
+'passwordremindertext' => 'Aya (jigana anjeun ti alamat IP $1) nu ménta sangkan dikiriman sandi anyar asup log {{SITENAME}}. Sandi keur pamaké "$2" ayeuna nyaéta "$3". Anjeun kudu asup log sarta ngarobah sandi anjeun ayeuna.',
+'passwordremindertitle' => 'Pangéling sandi ti {{SITENAME}}',
+'passwordsent' => 'Sandi anyar geus dikirim ka alamat surélék nu kadaptar pikeun "$1". Mangga asup log deui satutasna katarima.',
+'passwordtooshort' => 'Sandi anjeun pondok teuing, sahanteuna kudu $1 karakter.',
+'perfcached' => 'Data di handap ieu di-\'\'cache\'\' sarta meureun teu mutahir:',
+'perfdisabled' => 'Punten! Fungsi ieu pikeun samentawis ditumpurkeun sabab ngahambat database nepi ka titik di mana teu saurang ogé bisa migunakeun wiki.',
+'perfdisabledsub' => 'Ieu salaku salinan nu diteundeun ti $1:',
+'permalink' => 'Tumbu permanén',
+'personaltools' => 'Parabot pribadi',
+'popularpages' => 'Kaca-kaca kawentar',
+'portal' => 'Panglawungan',
+'portal-url' => '{{ns:project}}: Panglawungan',
+'postcomment' => 'Kirim koméntar',
+'powersearch' => 'Téang',
+'powersearchtext' => 'Téang na spasi-ngaran:<br />
+$1<br />
+$2 Daptarkeun alihan &nbsp; Téang $3 $9',
+'preferences' => 'Préferénsi',
+'prefs-help-email' => '* Surélék (pilihan): batur bisa ngontak anjeun tina kaca pamaké atawa obrolanana tanpa kudu nyebutkeun idéntitas anjeun.',
+'prefs-help-email-enotif' => 'Alamat ieu ogé dipaké pikeun ngirim surélék iber, mun anjeun ngajalankeun pilihanana.',
+'prefs-help-realname' => '* Ngaran asli (pilihan): mun anjeun milih ngeusian, bakal dipaké pikeun nandaan kontribusi anjeun.',
+'prefs-misc' => 'Pangaturan rupa-rupa',
+'prefs-personal' => 'Data pamaké',
+'prefs-rc' => 'Panémbong robahan anyar jeung tukung',
+'prefsnologin' => 'Can asup log',
+'prefsnologintext' => 'Anjeun kudu [[Special:Userlogin|asup log]] pikeun ngatur préferénsi pamaké.',
+'prefsreset' => 'Préferénsi geus disét ulang tina arsip.',
+'preview' => 'Sawangan',
+'previewconflict' => 'Sawangan ieu mangrupa eunteung pikeun téks na rohangan ngédit sakumaha bakal katémbong mun ku anjeun disimpen.',
+'previewnote' => 'Inget yén ieu ukur sawangan, can disimpen!',
+'previousdiff' => '&larr; Ka béda saméméhna',
+'previousrevision' => '&larr;Révisi leuwih heubeul',
+'prevn' => '$1 saméméhna',
+'print' => 'Citak',
+'printableversion' => 'Vérsi citakeun',
+'privacy' => 'Kawijakan privasi',
+'privacypage' => 'Project:Kawijakan privasi',
+'protect' => 'Konci',
+'protectcomment' => 'Alesan ngonci',
+'protectedarticle' => 'ngonci $1',
+'protectedpage' => 'Kaca nu dikonci',
+'protectedpagewarning' => '<strong>PERHATOSAN: Kaca ieu dikonci sahingga ngan bisa dirobah ku pamaké nu statusna kuncén. Pastikeun yén anjeun tumut kana [[{{ns:project}}:tungtunan_kaca_nu_dikonci\'|tungtunan kaca nu dikonci]].</strong>',
+'protectedtext' => 'Kaca ieu dikonci tina ngédit; aya sababaraha alesan pangna dikonci, mangga tingal [[{{ns:project}}:Kaca nu dikonci|kaca nu dikonci]].
+
+Anjeun bisa muka sarta nyalin sumber kaca ieu:',
+'protectlogpage' => 'Log_koncian',
+'protectlogtext' => 'Di handap ieu mangrupa daptar koncian kaca. Tempo [[{{ns:project}}:Kaca nu dikonci|kaca nu dikonci]] pikeun iber leuwih lengkep.',
+'protectmoveonly' => 'Konci tina dipindahkeun wungkul',
+'protectsub' => '(Ngonci "$1")',
+'protectthispage' => 'Konci kaca ieu',
+'proxyblocker' => 'Pameungpeuk proxy',
+'proxyblockreason' => 'Alamat IP anjeun dipeungpeuk sabab mangrupa proxy muka. Mangga tepungan \'\'Internet service provider\'\' atanapi \'\'tech support\'\' anjeun, béjakeun masalah serius ieu.',
+'proxyblocksuccess' => 'Réngsé.',
+'qbbrowse' => 'Sungsi',
+'qbedit' => 'Édit',
+'qbfind' => 'Panggihan',
+'qbmyoptions' => 'Kaca kuring',
+'qbpageinfo' => 'Kontéx',
+'qbpageoptions' => 'Kaca ieu',
+'qbspecialpages' => 'Kaca husus',
+'randompage' => 'Kaca acak',
+'range_block_disabled' => 'Pangabisa kuncén pikeun nyieun sarupaning peungpeuk geus ditumpurkeun.',
+'rclinks' => 'Témbongkeun $1 parobahan ahir dina $2 poé ahir<br />$3',
+'rclistfrom' => 'Témbongkeun nu anyar robah nepi ka $1',
+'rclsub' => '(ka kaca nu numbu ti "$1")',
+'rcnote' => 'Di handap ieu <strong>$1</strong> parobahan ahir na <strong>$2</strong> poé ieu.',
+'rcnotefrom' => 'Di handap ieu parobahan saprak <b>$2</b> (nu ditémbongkeun nepi ka <b>$1</b>).',
+'rcpatroldisabled' => 'Ronda Nu Anyar Robah ditumpurkeun',
+'rcpatroldisabledtext' => 'Fitur Ronda Nu Anyar Robah kiwari ditumpurkeun.',
+'readonly' => 'Database dikonci',
+'readonlytext' => 'database kiwar keur di konci pikeun éntri anyar sarta parobahan séjénna, meureun pikeun pangropéa database rutin, nu satutasna mah bakal normal deui. Kuncén nu ngonci ngécéskeun kieu:
+<p>$1',
+'readonlywarning' => 'PERHATOSAN: Database dikonci pikeun diropéa, anjeun moal bisa nyimpen éditan anjeun ayeuna. Cobi \'\'cut-n-paste\'\' téksna ka na koropak téks sarta simpen dina waktu séjén.',
+'recentchanges' => 'Nu anyar robah',
+'recentchangesall' => 'sadaya',
+'recentchangescount' => 'Jumlah judul nu anyar robah',
+'recentchangeslinked' => 'Parobahan nu patali',
+'recentchangestext' => 'Lacak parobahan ka wiki panganyarna na kaca ieu.',
+'redirectedfrom' => '(Dialihkeun ti $1)',
+'remembermypassword' => 'Inget sandi kuring liwat sési.',
+'removechecked' => 'Kaluarkeun nu dicontang tina awaskeuneun',
+'removedwatch' => 'Dikaluarkeun ti awaskeuneun',
+'removedwatchtext' => 'Kaca "$1" geus dikaluarkeun ti awaskeuneun anjeun.',
+'removingchecked' => 'Ngaluarkeun kaca nu dipilih tina awaskeuneun...',
+'resetprefs' => 'Sét ulang préferénsi',
+'restorelink' => '$1 éditan dihapus',
+'resultsperpage' => 'Hasil nu ditémbongkeun per kaca',
+'retrievedfrom' => 'Disalin ti "$1"',
+'returnto' => 'Balik deui ka $1.',
+'retypenew' => 'Ketik ulang sandi',
+'reupload' => 'Muat ulang',
+'reuploaddesc' => 'Balik ka formulir muatan.',
+'reverted' => 'Malikkeun ka révisi nu ti heula',
+'revertimg' => 'blk',
+'revertpage' => 'Malikkeun éditan $2, diganti deui ka vérsi ahir ku $1',
+'revhistory' => 'Jujutan révisi',
+'revisionasof' => 'Révisi nurutkeun $1',
+'revnotfound' => 'Révisi teu kapanggih',
+'revnotfoundtext' => 'Révisi heubeul kaca nu dipénta ku anjeun teu bisa kapanggih.
+Please check the URL you used to access this page.',
+'rights' => 'Hak:',
+'rightslogtext' => 'Ieu mangrupa log parobahan hak-hak pamaké.',
+'rollback' => 'Balikkeun éditan',
+'rollback_short' => 'Balikkeun',
+'rollbackfailed' => 'Gagal malikkeun',
+'rollbacklink' => 'balikkeun',
+'rows' => 'Baris',
+'savearticle' => 'Simpen',
+'savedprefs' => 'Préferénsi anjeun geus disimpen.',
+'savefile' => 'Simpen koropak',
+'saveprefs' => 'Simpen préferénsi',
+'saveusergroups' => 'Simpen Grup Pamaké',
+'search' => 'Téang',
+'searchbutton' => 'Téang',
+'searchdisabled' => '<p style="margin: 1.5em 2em 1em">Punten! Néangan téks lengkep di {{SITENAME}} kanggo samentawis ditumpurkeun pikeun alesan kinerja. Jalaran kitu, saheulaanan anjeun bisa nyungsi di Google di handap ieu.
+<span style="font-size: 89%; display: block; margin-left: .2em">Catet yén indéxna ngeunaan eusi {{SITENAME}} bisa jadi teu mutahir.</span></p>',
+'searchsubtitle' => 'Pikeun pamundut "[[:$1]]"',
+'searchsubtitleinvalid' => 'Pikeun pamundut "$1"',
+'searchresults' => 'Hasil néangan',
+'searchresultshead' => 'Aturan hasil néang',
+'searchresulttext' => 'Pikeun iber nu leuwih lengkep ngeunaan nyaksrak di {{SITENAME}}, buka [[{{ns:project}}:Nyaksrak|Nyaksrak {{SITENAME}}]].',
+'selectnewerversionfordiff' => 'Pilih vérsi nu leuwih anyar pikeun babandingan',
+'selectolderversionfordiff' => 'Pilih vérsi nu leuwih heubeul pikeun babandingan',
+'selfmove' => 'Judul sumber jeung tujuanana sarua, lain gé mindahkeun atuh!',
+'servertime' => 'Waktu server ayeuna',
+'session_fail_preview' => '<strong>Punten! Kami teu bisa ngolah Sorryditan anjeun alatan leungitna data sési. Mangga cobian deui. Mun tetep teu bisa, cobi kaluar log lajeng lebet deui.</strong>',
+'sessionfailure' => 'Sigana aya masalah jeung termin log anjeun; peta ieu geus dibolaykeun salaku pépéling pikeun ngalawan ayana pangbajak. Mangga pencét "back" jeung muat ulang ti kaca asal anjeun, lajeng cobaan deui.',
+'set_rights_fail' => '<b>HAk pamaké pikeun "$1" teu bisa diatur. (Ngaran nu diasupkeun geus bener can?)</b>',
+'set_user_rights' => 'Atur hak pamaké',
+'setbureaucratflag' => 'Atur bandéra birokrat',
+'shareduploadwiki' => 'Mangga aos $1 pikeun émbaran leuwih jéntré.',
+'shortpages' => 'Kaca-kaca parondok',
+'show' => 'témbongkeun',
+'showbigimage' => 'Buka vérsi résolusi alus ($1x$2, $3 KB)',
+'showdiff' => 'Témbongkeun parobahan',
+'showingresults' => 'Di handap ieu némbongkeun <b>$1</b> hasil tina #<b>$2</b>.',
+'showingresultsnum' => 'Di handap ieu némbongkeun <b>$3</b> hasil tina #<b>$2</b>.',
+'showlast' => 'Témbongkeun $1 gambar ahir dumasar $2.',
+'showpreview' => 'Témbongkeun sawangan',
+'showtoc' => 'témbongkeun',
+'sig_tip' => 'Tawis leungeun anjeun tur cap wanci',
+'sitestats' => 'Statistika {{SITENAME}}',
+'sitestatstext' => 'Jumlah-jamléh aya \'\'\'$1\'\'\' kaca na database, kaasup kaca "obrolan", kaca-kaca ngeunaan MédiaWiki, kaca "tukung", alihan, sarta nu séjénna nu meureun teu kaasup artikel. Lian ti nu éta, aya \'\'\'$2\'\'\' kaca nu dianggap artikel nu bener.
+
+jumlah-jamléh geus aya \'\'\'$3\'\'\' kaca ulasan sarta \'\'\'$4\'\'\' éditan ti saprak Wiki ieu ngadeg. Jadi hartina aya rata-rata \'\'\'$5\'\'\' éditan per kaca sarta \'\'\'$6\'\'\' ulasan per édit.',
+'sitesupport' => 'Sumbangan',
+'sitesupport-url' => 'Project:Ngarojong loka',
+'siteuser' => 'Pamaké $1 {{SITENAME}}',
+'siteusers' => 'Pamaké $1 {{SITENAME}}',
+'skin' => 'Kulit',
+'speciallogtitlelabel' => 'Judul:',
+'specialloguserlabel' => 'Pamaké:',
+'specialpage' => 'Kaca Husus',
+'specialpages' => 'Kaca husus',
+'spheading' => 'Kaca husus pikeun sadaya pamaké',
+'statistics' => 'Statistik',
+'storedversion' => 'Vérsi nu disimpen',
+'subcategories' => 'Subkategori',
+'subcategorycount' => 'Aya $1 subkategori na kategori ieu.',
+'subject' => 'Jejer/Judul',
+'successfulupload' => 'Ngamuat geus hasil',
+'summary' => 'Ringkesan',
+'talk' => 'Sawala',
+'talkexists' => 'Kacana geus hasil dipindahkeun, ngan kaca obrolanana teu bisa dipindahkeun sabab geus aya nu anyar na judul anyar. Mangga gabungkeun sacara manual.',
+'talkpage' => 'Sawalakeun kaca ieu',
+'talkpagemoved' => 'Kaca obrolanana geus ogé dipindahkeun.',
+'talkpagenotmoved' => 'Kaca obrolan nu patali <strong>teu</strong> dipindahkeun.',
+'templatesused' => 'Citaka nu dipaké na kaca ieu:',
+'textboxsize' => 'Ukuran kotak téks',
+'textmatches' => 'Téks kaca nu cocog',
+'thisisdeleted' => 'Témbongkeun atawa simpen deui $1?',
+'thumbnail-more' => 'Gedéan',
+'thumbsize' => 'Thumbnail size:',
+'timezonelegend' => 'Wewengkon wanci',
+'timezonetext' => 'Asupkeun sabaraha jam bédana antara wanci di tempat anjeun jeung wanci server (UTC).',
+'titlematches' => 'Judul artikel nu cocog',
+'toc' => 'Daptar eusi',
+'tog-editondblclick' => 'Édit kaca ku klik ganda (JavaScript)',
+'tog-fancysig' => 'Paraf kasar (tanpa tumbu otomatis)',
+'tog-hideminor' => 'Sumputkeun éditan minor dina nu anyar robah',
+'tog-justify' => 'Lempengkeun alinéa',
+'tog-minordefault' => 'Tandaan sadaya éditan salaku minor luyu jeung ti dituna',
+'tog-previewonfirst' => 'Témbongkeun sawangan dina éditan munggaran',
+'tog-previewontop' => 'Témbongkeun sawangan méméh kotak édit (lain sanggeusna)',
+'tog-rememberpassword' => 'Inget sandi liwat sési',
+'tog-shownumberswatching' => 'Témbongkeun jumlah nu ngawaskeun',
+'tog-showtoc' => 'Témbongkeun daptar eusi<br />(pikeun kaca nu leuwih ti tilu subjudul)',
+'tog-showtoolbar' => 'Témbongkeun \'\'toolbar\'\' édit (JavaScript)',
+'tog-underline' => 'Garis-handapan tumbu',
+'tog-watchdefault' => 'Tambahkeun kaca nu diédit ku anjeun kana awaskeuneun anjeun',
+'toolbox' => 'Kotak parabot',
+'tooltip-compareselectedversions' => 'Tempo béda antara dua vérsi kaca ieu nu dipilih [alt-v].',
+'tooltip-diff' => 'Témbongkeun parobahan mana nu geus dijieun. [alt-v]',
+'tooltip-minoredit' => 'Tandaan ieu salaku éditan minor [alt-i]',
+'tooltip-preview' => 'Sawang heula robahan anjeun, pami tos leres mangga simpen! [alt-p]',
+'tooltip-save' => 'Simpen parobahan anjeun [alt-s]',
+'tooltip-search' => 'Téang wiki ieu [alt-f]',
+'tooltip-watch' => 'Tambahkeun kaca ieu kana awaskeuneun kuring [alt-w]',
+'uclinks' => 'Témbongkeun $1 parobahan ahir; témbongkeun $2 poé ahir.',
+'ucnote' => 'Di handap ieu mangrupa parobahan ahir <b>$1</b> pamaké salila <b>$2</b> poé ahir.',
+'uctop' => ' (tempo)',
+'uid' => 'ID pamaké:',
+'unblockip' => 'Buka peungpeuk pamaké',
+'unblockiptext' => 'Paké formulir di handap pikeun mulangkeun aksés nulis ka alamat IP atawa ngaran pamaké nu saméméhna dipeungpeuk.',
+'unblocklink' => 'buka peungpeuk',
+'unblocklogentry' => 'peungpeuk dibuka "$1"',
+'uncategorizedcategories' => 'Kategori nu can dikategorikeun',
+'uncategorizedpages' => 'Kaca nu can dikategorikeun',
+'undelete' => 'Simpen deui kaca nu dihapus',
+'undelete_short' => 'Tong dihapus',
+'undeletearticle' => 'Simpen deui kaca nu dihapus',
+'undeletebtn' => 'Simpen deui!',
+'undeletedarticle' => 'disimpen "$1"',
+'undeletedrevisions' => '$1 révisi disimpen deui',
+'undeletehistory' => 'Mun anjeun nyimpen deui kacana, sadaya révisi bakal disimpen deui dina jujutan. Mun aya kaca anyar nu ngaranna sarua dijieun deui satutasna dihapus, révisi nu disimpen tadi bakal némbongan salaku jujutan nu ti heula, sarta révisi kiwari kaca nu hirup moal otomatis kaganti.',
+'undeletehistorynoadmin' => 'Artikel ieu geus dihapus. Alesanana bisa dibaca dina katrangan di handap, katut saha waé nu geus ngédit ieu artikel saméméh dihapus. Téks aktual révisi nu geus dihapus ieu ngan bisa dibuka ku [[{{ns:project}}:Kuncén|kuncén]].',
+'undeletepage' => 'Témbongkeun atawa simpen deui kaca nu geus dihapus',
+'undeletepagetext' => 'Kaca di handap ieu geus dihapus tapi masih kénéh aya na arsip sarta bisa disimpen deui. Arsip aya kalana dibersihan.',
+'undeleterevision' => 'Révisi nu dihapus sakumaha $1',
+'undeleterevisions' => '$1 révisi diarsipkeun',
+'underline-always' => 'Salawasna',
+'underline-never' => 'Ulah',
+'unlockbtn' => 'Buka konci database',
+'unlockconfirm' => 'Muhun, kuring hayang muka konci database.',
+'unlockdb' => 'Buka konci database',
+'unlockdbsuccesssub' => 'Konci database geus dibuka',
+'unlockdbsuccesstext' => 'Database geus teu dikonci.',
+'unlockdbtext' => 'Muka konci database bakal mulangkeun kabisa sakabéh pamaké pikeun ngédit kaca, ngarobah préferénsina, ngédit awaskeuneunana, sarta hal-hal séjén nu merlukeun parobahan na database. Pastikeun yén ieu ngarupakeun hal nu diniatkeun ku anjeun.',
+'unprotect' => 'Buka konci',
+'unprotectcomment' => 'Alesan muka konci',
+'unprotectedarticle' => 'muka konci $1',
+'unprotectsub' => '(Muka konci "$1")',
+'unprotectthispage' => 'Buka konci kaca ieu',
+'unusedcategories' => 'Kategori nu teu kapaké',
+'unusedcategoriestext' => 'Kaca kategori di handap ieu aya, tapi taya artikel nu diasupkeun kana kategori ieu.',
+'unusedimages' => 'Gambar-gambar nu teu kapaké',
+'unusedimagestext' => '<p>Perhatikeun yén jalaloka séjén bisa numbukeun ka hiji gambar ku URL langsung, sahingga masih didaptarkeun di dieu najan sabenerna dipaké.',
+'unwatch' => 'Eureun ngawaskeun',
+'unwatchthispage' => 'Eureun ngawaskeun',
+'upload' => 'Muatkeun koropak',
+'uploadbtn' => 'Muatkeun koropak',
+'uploaddisabled' => 'Punten, ngamuat ayeuna ditumpurkeun.',
+'uploadedfiles' => 'Koropak nu geus dimuat',
+'uploadedimage' => '"$1" geus dimuat',
+'uploaderror' => 'Kasalahan muat',
+'uploadlog' => 'log muatan',
+'uploadlogpage' => 'Log_muatan',
+'uploadlogpagetext' => 'Di handap mangrupa daptar muatan koropak nu panganyarna. Titimangsa nu katémbong dumasar titimangsa server (UTC).
+<ul>
+</ul>',
+'uploadnewversion-linktext' => 'ngamuatkeun vérsi anyar koropak ieu',
+'uploadnologin' => 'Can asup log',
+'uploadnologintext' => 'Anjeun kudu [[Special:Userlogin|asup log]] pikeun ngamuat koropak.',
+'uploadscripted' => 'Koropak ieu ngandung kode HTML atawa skrip nu bisa dibaca ngaco ku panyungsi ramat (\'\'web browser\'\').',
+'uploadtext' => '<strong>HEUP!</strong> Méméh anjeun ngamuat di dieu, pastikeun yén anjeun geus maca sarta tumut ka [[Special:Image_use_policy|kawijakan maké gambar]].
+<p>Mun geus aya koropak na wiki nu ngaranna sarua jeung nu disebutkeun ku anjeun, koropak nu geus lila bakal diganti otomatis. Mangka, iwal ti pikeun ngaropéa hiji koropak, tangtu leuwih hadé mun anjeun mariksa heula bisi koropak nu sarupa geus aya.
+<p>Pikeun némbongkeun atawa néang gambar-gambar nu pernah dimuat saméméhna, mangga lebet ka [[Special:Imagelist|daptar gambar nu dimuat]]. Muatan sarta hapusan kadaptar dina log [[{{ns:project}}:Upload_log|log muatan]].
+</p><p>Paké formulir di handap pikeun ngamuat koropak gambar anyar pikeun ilustrasi kaca anjeun. Na kalolobaan panyungsi, anjeun bakal manggihan tombol "Sungsi/\'\'Browse\'\'...", nu bakal nganteur ka dialog muka-koropak nu baku na sistim operasi anjeun. Milih hiji koropak bakal ngeusian ngaran koropakna kana rohangan téks gigireun tombol nu tadi. Anjeun ogé kudu nyontréng kotak nu nandakeun yén anjeun teu ngarumpak hak cipta batur ku dimuatna ieu koropak. Pencét tombol "Muatkeun/\'\'Upload\'\'" pikeun ngeréngsékeun muatan. Prosés ieu bisa lila mun anjeun migunakeun sambungan internét nu lambat.
+<p>Format nu dianjurkeun nyéta JPEG pikeun gambar fotografik, PNG pikeun hasil ngagambar sarta gambar séjénna, sarta OGG pikeun sora. Pilih ngaran koropak nu déskriptif sangkan teu ngalieurkeun. Pikeun ngasupkeun gambarna na kaca séjén, pigunakeun tumbu dina wujud <b>[[Image:file.jpg]]</b> atawa <b>[[Image:file.ogg]]</b> pikeun sora.
+<p>Catet yén salaku kaca wiki, nu séjén bisa ngarobah atawa ngahapus muatan anjeun mun maranéhna nganggap ieu saluyu jeung kapentingan proyék, sarta anjeun bisa waé dipeungpeuk ti ngamuat koropak mun anjeun ngaruksak/ngaganggu sistim.',
+'uploadvirus' => 'Koropakna ngandung virus! Katrangan: $1',
+'uploadwarning' => 'Pépéling ngamuat',
+'user_rights_set' => '<b>Hak pamaké pikeun "$1" geus dirobah</b>',
+'usercssjsyoucanpreview' => '<strong>Tip:</strong> Pigunakeun tombol \'Témbongkeun sawangan\' pikeun nyoba css/js anyar anjeun méméh nyimpen.',
+'usercsspreview' => '\'\'\'Inget yén anjeun ukur nyawang css pamaké anjeun, can disimpen!\'\'\'',
+'userexists' => 'Ngaran pamaké nu diasupkeun ku anjeun geus aya nu maké. Mangga pilih ngaran nu séjén.',
+'userjspreview' => '\'\'\'Inget yén anjeun ukur nguji/nyawang \'\'javascript\'\' pamaké anjeun, can disimpen!\'\'\'',
+'userlogin' => 'Nyieun rekening atawa asup log',
+'userlogout' => 'Kaluar log',
+'username' => 'Landihan:',
+'userpage' => 'Témbongkeun kaca pamaké',
+'userrights-user-editname' => 'Enter a username:',
+'userstats' => 'Statistik pamaké',
+'userstatstext' => 'Aya \'\'\'$1\'\'\' pamaké nu kadaptar.
+\'\'\'$2\'\'\' di antarana kuncén (tempo $3).',
+'version' => 'Vérsi',
+'viewcount' => 'Kaca ieu geus dibuka $1 kali.',
+'viewdeletedpage' => 'Témbongkeun kaca nu dihapus',
+'viewprevnext' => 'Témbongkeun ($1) ($2) ($3).',
+'views' => 'Témbongan',
+'viewsource' => 'Témbongkeun sumber',
+'viewtalkpage' => 'Témbongkeun sawala',
+'wantedcategories' => 'Kategori nu dipikabutuh',
+'wantedpages' => 'Kaca nu dipikabutuh',
+'watch' => 'Awaskeun',
+'watchdetails' => '($1 kaca diawaskeun, teu kaasup kaca obrolan; jumlah-jamléh $2 kaca diédit saprak cutoff; $3...
+[[\'$4\'|témbongkeun jeung édit daptar lengkepna]].)',
+'watcheditlist' => 'Ieu daptar nurutkeun abjad kaca-kaca awaskeuneun anjeun. Contréng kotak kaca nu teu moal deui diawaskeun, teras klik tombol \'piceun nu dicontréng\' na dadasar layar.',
+'watchlist' => 'Awaskeuneun',
+'watchlistall1' => 'sadaya',
+'watchlistall2' => 'sadaya',
+'watchlistcontains' => 'Anjeun ngawaskeun $1 kaca.',
+'watchmethod-list' => 'mariksa nu anyar robah na kaca nu diawaskeun',
+'watchmethod-recent' => 'mariksa nu anyar robah na kaca nu diawaskeun',
+'watchnochange' => 'Sadaya awaseun anjeun taya nu diédit dina jangka wanci nu ditémbongkeun.',
+'watchnologin' => 'Can asup log',
+'watchnologintext' => 'Anjeun kudu [[Special:Userlogin|asup log]] pikeun ngarobah awaskeuneun.',
+'watchthis' => 'Awaskeun kaca ieu',
+'watchthispage' => 'Awaskeun kaca ieu',
+'welcomecreation' => '<h2>Wilujeng sumping, $1!</h2><p>Rekening anjeun geus dijieun. Tong hilap ngarobih préferénsi {{SITENAME}} anjeun.',
+'whatlinkshere' => 'Nu numbu ka dieu',
+'whitelistacctext' => 'Sangkan diwenangkeun nyieun rekening na wiki ieu, anjeun kudu asup [[Special:Userlogin|log]] sarta boga kawenangan nu cukup.',
+'whitelistacctitle' => 'Anjeun teu diwenangkeun nyieun rekening',
+'whitelistedittext' => 'Anjeun kudu asup [[Special:Userlogin|log]] sangkan bisa ngédit.',
+'whitelistedittitle' => 'Perlu asup log sangkan bisa ngédit',
+'whitelistreadtext' => 'Anjeun kudu asup \'\'[[Special:Userlogin|log]]\'\' sangkan bisa maca.',
+'whitelistreadtitle' => 'Perlu asup log pikeun maca',
+'projectpage' => 'Témbongkeun kaca proyék',
+'wlheader-enotif' => '* Pangémbar surélék difungsikeun.',
+'wlheader-showupdated' => '* Kaca nu robah ti panungtungan anjeun sindang ditémbongkeun kalawan \'\'\'kandel\'\'\'',
+'wlhideshowbots' => '$1 éditan bot.',
+'wlhideshowown' => '$1 éditan kuring.',
+'wlnote' => 'Di handap ieu mangrupa $1 robahan ahir salila <b>$2</b> jam.',
+'wlsaved' => 'Ieu mangrupa vérsi simpenan awaskeuneun anjeun.',
+'wlshowlast' => 'Témbongkeun $1 jam $2 poé $3 ahir',
+'wrongpassword' => 'Sandi nu diasupkeun teu cocog. Mangga cobian deui.',
+'wrongpasswordempty' => 'Sandina can kaeusian. Cobaan deui!',
+'youhavenewmessages' => 'Anjeun boga $1 ($2).',
+'yourdiff' => 'Béda',
+'yourdomainname' => 'Domain anjeun',
+'youremail' => 'Surélék anjeun*',
+'yourlanguage' => 'Basa antarbeungeut',
+'yourname' => 'Ngaran pamaké anjeun',
+'yournick' => 'Landihan anjeun (pikeun tawis leungeun)',
+'yourpassword' => 'Sandi anjeun',
+'yourpasswordagain' => 'Ketik deui sandi anjeun',
+'yourrealname' => 'Ngaran anjeun*',
+'yourtext' => 'Tulisan anjeun',
+'yourvariant' => 'Varian basa',
+);
+
+
+?>
diff --git a/languages/messages/MessagesSv.php b/languages/messages/MessagesSv.php
new file mode 100644
index 000000000000..ae7d770d251b
--- /dev/null
+++ b/languages/messages/MessagesSv.php
@@ -0,0 +1,1668 @@
+<?php
+/**
+ * Swedish (Svenska)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ 'Ingen', 'Fast vänster', 'Fast höger', 'Flytande vänster'
+);
+
+$skinNames = array(
+ 'standard' => "Standard",
+ 'nostalgia' => "Nostalgi",
+ 'cologneblue' => "Cologne Blå",
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Diskussion',
+ NS_USER => 'Användare',
+ NS_USER_TALK => 'Användardiskussion',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1diskussion',
+ NS_IMAGE => 'Bild',
+ NS_IMAGE_TALK => 'Bilddiskussion',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki-diskussion',
+ NS_TEMPLATE => 'Mall',
+ NS_TEMPLATE_TALK => 'Malldiskussion',
+ NS_HELP => 'Hjälp',
+ NS_HELP_TALK => 'Hjälpdiskussion',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Kategoridiskussion'
+);
+
+$namespaceAliases = array(
+ // For compatibility with 1.7 and older
+ 'MediaWiki_diskussion' => NS_MEDIAWIKI_TALK,
+ 'Hjälp_diskussion' => NS_HELP_TALK
+);
+
+$linkTrail = '/^([a-zåäöéÅÄÖÉ]+)(.*)$/sDu';
+$separatorTransformTable = array(
+ ',' => "\xc2\xa0", // @bug 2749
+ '.' => ','
+);
+
+$dateFormats = array(
+ 'mdy time' => 'H.i',
+ 'mdy date' => 'F j, Y',
+ 'mdy both' => 'F j, Y "kl." H.i',
+
+ 'dmy time' => 'H.i',
+ 'dmy date' => 'j F Y',
+ 'dmy both' => 'j F Y "kl." H.i',
+
+ 'ymd time' => 'H.i',
+ 'ymd date' => 'Y F j',
+ 'ymd both' => 'Y F j "kl." H.i',
+);
+
+$messages = array(
+'tog-underline' => 'Stryk under länkar',
+'tog-highlightbroken' => 'Formatera trasiga länkar <a href="" class="new">så här</a> (alternativt: <a href="" class="internal">så här</a>).',
+'tog-justify' => 'Justera indrag',
+'tog-hideminor' => 'Visa inte mindre redigeringar i Senaste ändringar',
+'tog-extendwatchlist' => 'Utöka övervakningslistan till att visa alla ändringar',
+'tog-usenewrc' => 'Avancerad Senaste ändringar (Javascript)',
+'tog-numberheadings' => 'Numrerade rubriker',
+'tog-showtoolbar' => 'Visa verktygsrad',
+'tog-editondblclick' => 'Redigera sidor med dubbelklick (Javascript)',
+'tog-editsection' => 'Visa [redigera]-länkar för att redigera sektioner',
+'tog-editsectiononrightclick'=> 'Högerklick på rubriker redigerar sektioner',
+'tog-showtoc' => 'Visa innehållsförteckning (vid minst fyra underrubriker)',
+'tog-rememberpassword' => 'Kom ihåg lösenordet till nästa besök',
+'tog-editwidth' => 'Full bredd på redigeringsrutan',
+'tog-watchcreations' => 'Lägg automatiskt till sidor du skapar till din övervakningslista.',
+'tog-watchdefault' => 'Övervaka nya och ändrade artiklar',
+'tog-watchdeletion' => 'Lägg till sidor du raderar till din övervakningslista',
+'tog-minordefault' => 'Markera automatiskt ändringar som mindre',
+'tog-previewontop' => 'Visa förhandsgranskning före texten, istället för efter',
+'tog-previewonfirst' => 'Visa förhandsgranskning vid första redigeringen',
+'tog-nocache' => 'Stäng av cachning av sidor',
+'tog-enotifwatchlistpages'=> 'Skicka e-post till mig när någon övervakad sida ändras',
+'tog-enotifusertalkpages'=> 'Skicka e-post till mig när något händer på min diskussionssida',
+'tog-enotifminoredits' => 'Skicka mig e-post även för små redigeringar',
+'tog-enotifrevealaddr' => 'Visa min e-postaddress i e-post om uppdateringar',
+'tog-shownumberswatching'=> 'Visa antalet betraktande användare',
+'tog-fancysig' => 'Rå signatur, utan automatisk länk',
+'tog-externaleditor' => 'Använd extern editor automatiskt',
+'tog-externaldiff' => 'Använd externt diff-verktyg',
+'tog-showjumplinks' => 'Aktivera "hoppa till"-tillgänglighetslänkar',
+'tog-uselivepreview' => 'Använd direktuppdaterad förhandsgranskning (Javascript, på försöksstadiet)',
+'tog-forceeditsummary' => 'Påminn mig om jag inte fyller i en redigeringskommentar',
+'tog-watchlisthideown' => 'Visa inte mina redigeringar på övervakningslistan',
+'tog-watchlisthidebots' => 'Visa inte robotredigeringar på övervakningslistan',
+'tog-nolangconversion' => 'Konvertera inte mellan språkvarianter',
+'tog-ccmeonemails' => 'Skicka mig kopior av epost jag skickar till andra användare',
+'underline-always' => 'Alltid',
+'underline-never' => 'Aldrig',
+'underline-default' => 'Webbläsarens standardinställning',
+'skinpreview' => '(Förhandsvisning)',
+'sunday' => 'söndag',
+'monday' => 'måndag',
+'tuesday' => 'tisdag',
+'wednesday' => 'onsdag',
+'thursday' => 'torsdag',
+'friday' => 'fredag',
+'saturday' => 'lördag',
+'sun' => 'sön',
+'mon' => 'mån',
+'tue' => 'tis',
+'wed' => 'ons',
+'thu' => 'tor',
+'fri' => 'fre',
+'sat' => 'lör',
+'january' => 'januari',
+'february' => 'februari',
+'march' => 'mars',
+'april' => 'april',
+'may_long' => 'maj',
+'june' => 'juni',
+'july' => 'juli',
+'august' => 'augusti',
+'september' => 'september',
+'october' => 'oktober',
+'november' => 'november',
+'december' => 'december',
+'january-gen' => 'januaris',
+'february-gen' => 'februaris',
+'march-gen' => 'mars',
+'april-gen' => 'aprils',
+'may-gen' => 'majs',
+'june-gen' => 'junis',
+'july-gen' => 'julis',
+'august-gen' => 'augustis',
+'september-gen' => 'septembers',
+'october-gen' => 'oktobers',
+'november-gen' => 'novembers',
+'december-gen' => 'decembers',
+'jan' => 'jan',
+'feb' => 'feb',
+'mar' => 'mar',
+'apr' => 'apr',
+'may' => 'maj',
+'jun' => 'jun',
+'jul' => 'jul',
+'aug' => 'aug',
+'sep' => 'sep',
+'oct' => 'okt',
+'nov' => 'nov',
+'dec' => 'dec',
+'categories' => 'Kategorier',
+'pagecategories' => '{{PLURAL:$1|Kategori|Kategorier}}',
+'category_header' => 'Artiklar i kategorin "$1"',
+'subcategories' => 'Underkategorier',
+'category-media-header' => 'Media i kategorin "$1"',
+'mainpage' => 'Huvudsida',
+'mainpagetext' => 'Installation av wikimjukvara klar.',
+'mainpagedocfooter' => 'För anpassning av användargränssnittet, se [http://meta.wikimedia.org/wiki/MediaWiki_localization dokumentation]. För hjälp med användning och konfiguration, se [http://meta.wikimedia.org/wiki/Help:Contents användarguiden] på Meta.',
+'portal' => 'Deltagarportalen',
+'portal-url' => 'Project:Deltagarportalen',
+'about' => 'Om',
+'aboutsite' => 'Om {{SITENAME}}',
+'aboutpage' => 'Project:Om',
+'article' => 'Artikel',
+'help' => 'Hjälp',
+'helppage' => 'Help:Innehåll',
+'bugreports' => 'Felrapporter',
+'bugreportspage' => 'Project:Felrapporter',
+'sitesupport' => 'Donationer',
+'sitesupport-url' => 'Project:Donationer',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => 'Redigeringshjälp',
+'newwindow' => '(öppnas i ett nytt fönster)',
+'edithelppage' => 'Help:Hur man redigerar en sida',
+'cancel' => 'Avbryt',
+'qbfind' => 'Hitta',
+'qbbrowse' => 'Bläddra igenom',
+'qbedit' => 'Redigera',
+'qbpageoptions' => 'Sidinställningar',
+'qbpageinfo' => 'Sidinformation',
+'qbmyoptions' => 'Mina inställningar',
+'qbspecialpages' => 'Specialsidor',
+'moredotdotdot' => 'Mer...',
+'mypage' => 'Min sida',
+'mytalk' => 'Min diskussionssida',
+'anontalk' => 'Diskussionssidan för denna IP-adress',
+'navigation' => 'Navigering',
+'metadata_help' => 'Metadata (se [[Project:Metadata]] för förklaring):',
+'currentevents' => 'Aktuella händelser',
+'currentevents-url' => 'Aktuella händelser',
+'disclaimers' => 'Förbehåll',
+'disclaimerpage' => 'Project:Allmänt förbehåll',
+'privacy' => 'Integritetspolicy',
+'privacypage' => 'Project:Integritetspolicy',
+'errorpagetitle' => 'Fel',
+'returnto' => 'Tillbaka till $1.',
+'tagline' => '{{SITENAME}}',
+'search' => 'Sök',
+'searchbutton' => 'Sök',
+'go' => 'Gå till',
+'searcharticle' => 'Gå till',
+'history' => 'Versionshistorik',
+'history_short' => 'Historik',
+'updatedmarker' => 'uppdaterad sedan senaste besöket',
+'info_short' => 'Information',
+'printableversion' => 'Utskriftsvänlig version',
+'permalink' => 'Permanent länk',
+'print' => 'Skriv ut',
+'edit' => 'Redigera',
+'editthispage' => 'Redigera denna sida',
+'delete' => 'radera',
+'deletethispage' => 'Radera denna sida',
+'undelete_short' => 'Återställ {{PLURAL:$1|en version|$1 versioner}}',
+'protect' => 'Skrivskydda',
+'protectthispage' => 'Skydda denna sida',
+'unprotect' => 'ta bort skrivskydd',
+'unprotectthispage' => 'Ta bort skrivskyddet från den här sidan',
+'newpage' => 'Ny sida',
+'talkpage' => 'Diskussionssida',
+'specialpage' => 'Specialsida',
+'personaltools' => 'Personliga verktyg',
+'postcomment' => 'Skicka en kommentar',
+'articlepage' => 'Visa artikel',
+'talk' => 'diskussion',
+'views' => 'Visningar',
+'toolbox' => 'Verktygslåda',
+'userpage' => 'Visa användarsida',
+'projectpage' => 'Visa projektsida',
+'imagepage' => 'Visa bildsida',
+'mediawikipage' => 'Visa meddelandesida',
+'templatepage' => 'Visa mallsida',
+'viewhelppage' => 'Visa hjälpsida',
+'categorypage' => 'Visa kategorisida',
+'viewtalkpage' => 'Visa diskussionssida',
+'otherlanguages' => 'Andra språk',
+'redirectedfrom' => '(Omdirigerad från $1)',
+'redirectpagesub' => 'Omdirigeringssida',
+'lastmodifiedat' => 'Sidan ändrades senast $2, $1.',
+'viewcount' => 'Sidan har visats {{PLURAL:$1|en gång|$1 gånger}}.',
+'copyright' => 'All text tillgänglig under $1.',
+'protectedpage' => 'Skyddad sida',
+'jumpto' => 'Hoppa till:',
+'jumptonavigation' => 'navigering',
+'jumptosearch' => 'sök',
+'badaccess' => 'Behörighetsfel',
+'badaccess-group0' => 'Du har inte tillåtelse att utföra den åtgärd du har begärt.',
+'badaccess-group1' => 'Funktionen du vill använda är begränsad till användare i gruppen $1.',
+'badaccess-group2' => 'Funktionen du vill använda är begränsad till användare i grupperna $1.',
+'badaccess-groups' => 'Funktionen du vill använda är begränsad till användare i grupperna $1.',
+'versionrequired' => 'Version $1 av MediaWiki krävs',
+'versionrequiredtext' => 'För att kunna använda den här sidan, behövs version $1 av MediaWiki. Se [[Special:Version]].',
+'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Den här artikeln är hämtad från $1',
+'youhavenewmessages' => 'Du har $1 ($2).',
+'newmessageslink' => 'nya meddelanden',
+'newmessagesdifflink' => 'ändring mot tidigare version',
+'editsection' => 'redigera',
+'editold' => 'redigera',
+'editsectionhint' => 'Redigera avsnitt: $1',
+'toc' => 'Innehåll',
+'showtoc' => 'visa',
+'hidetoc' => 'göm',
+'thisisdeleted' => 'Visa eller återställ $1?',
+'viewdeleted' => 'Visa $1?',
+'restorelink' => '{{PLURAL:$1|en raderad version|$1 raderade versioner}}',
+'feedlinks' => 'Matning:',
+'feed-invalid' => 'Ogiltig matningstyp.',
+'nstab-main' => 'Artikel',
+'nstab-user' => 'Användarsida',
+'nstab-media' => 'Media',
+'nstab-special' => 'Special',
+'nstab-project' => 'projektsida',
+'nstab-image' => 'Bild',
+'nstab-mediawiki' => 'systemmeddelande',
+'nstab-template' => 'Mall',
+'nstab-help' => 'Hjälp',
+'nstab-category' => 'Kategori',
+'nosuchaction' => 'Funktionen finns inte',
+'nosuchactiontext' => 'Den funktion som specificerats i URL:en kan inte
+hittas av programvaran',
+'nosuchspecialpage' => 'Någon sådan specialsida finns inte',
+'nospecialpagetext' => 'Du har begärt en specialsida som {{SITENAME}}s programvara inte kan hitta.',
+'error' => 'Fel',
+'databaseerror' => 'Databasfel',
+'dberrortext' => 'Ett syntaxfel i databasfrågan har uppstått.
+Den senaste utförda databasfrågan var:
+<blockquote><tt>$1</tt></blockquote>
+från funktionen "<tt>$2</tt>".
+MySQL returnerade felen "$3<tt>: $4</tt>".',
+'dberrortextcl' => 'Ett felaktigt utformat sökbegrepp har påträffats. Senaste sökbegrepp var: "$1" från funktionen "$2". MySQL svarade med felmeddelandet "$3: $4"',
+'noconnect' => 'Kunde inte ansluta till databasen på $1',
+'nodb' => 'Kunde inte välja databasen $1',
+'cachederror' => 'Detta är en cachad kopia av den efterfrågade sidan. Det är inte säkert att den är aktuell.',
+'laggedslavemode' => '<b>Observera: det kan dröja en stund innan de senaste redigeringarna blir synliga.</b>',
+'readonly' => 'Databasen är skrivskyddad',
+'enterlockreason' => 'Ange varför sidan skrivskyddats, och ge en uppskattning av hur länge skrivskyddet bör behållas.',
+'readonlytext' => 'Databasen är tillfälligt låst för ändringar, förmodligen på grund av rutinmässigt underhåll. Efter avslutat arbete kommer den att återgå till normalläge. Den utvecklare som skrivskyddade den har angivit följande anledning: <p>$1',
+'missingarticle' => 'Databasen borde ha funnit sidan "$1", men det gjorde den inte. Den vanligaste orsaken till denna typ av fel är vanligen en utdaterad jämförelse mellan sidversioner (diff) eller en länk från versionshistoriken till en sida som raderats. Om inte något av detta stämmer, kan du ha hittat en bugg i mjukvaran. Rapportera gärna buggar direkt i [http://bugzilla.wikimedia.org/ Bugzilla]; du kan även posta dem på sidan för [[Project:Felrapporter|felrapporter]], eller kontakta en [[Project:Administratörer|administratör]] och be honom eller henne skicka informationen vidare. Oavsett vilket av alternativen du väljer, notera url:en (webbadressen).',
+'readonly_lag' => 'Databasen har automatiskt låsts tills dess att databasservrarna återfår kontakten med huvudservern.',
+'internalerror' => 'Internt fel',
+'filecopyerror' => 'Kunde inte kopiera filen "$1" till "$2".',
+'filerenameerror' => 'Kunde inte byta namn på filen "$1" till "$2".',
+'filedeleteerror' => 'Kunde inte radera filen "$1".',
+'filenotfound' => 'Kunde inte hitta filen "$1".',
+'unexpected' => 'Oväntat värde: "$1"="$2".',
+'formerror' => 'Fel: Kunde inte sända formulär',
+'badarticleerror' => 'Den åtgärden kan inte utföras på den här sidan.',
+'cannotdelete' => 'Det gick inte att radera sidan eller bilden, kanske för att någon annan redan raderat den.',
+'badtitle' => 'Felaktig titel',
+'badtitletext' => 'Den sidtiteln är antingen inte tillåten, sidan är tom, eller så är sidan
+felaktigt länkad till.',
+'perfdisabled' => 'Denna funktion har tyvärr stängts av tillfälligt, eftersom den gör databasen så långsam att ingen kan använda wikin.',
+'perfdisabledsub' => 'Här är en sparad kopia från $1:',
+'perfcached' => 'Sidan är hämtad ur ett cacheminne; det är inte säkert att det är den senaste versionen.',
+'perfcachedts' => 'Sidan är hämtad ur ett cacheminne och uppdaterades senast $1.',
+'wrong_wfQuery_params' => 'Felaktiga parametrar för wfQuery()<br /> Funktion: $1<br /> Förfrågan: $2',
+'viewsource' => 'Visa wikitext',
+'viewsourcefor' => 'för $1',
+'protectedpagetext' => 'Den här sidan har skrivskyddats för att förhindra redigering.',
+'viewsourcetext' => 'Du kan se och kopiera sidans wikikod:',
+'protectedinterface' => 'Denna sida innehåller text för mjukvarans gränssnitt, och är skrivskyddad för att förebygga missbruk.',
+'editinginterface' => '\'\'\'Varning:\'\'\' Du redigerar en sida som används till texten i gränssnittet. Ändringar på denna sida kommer att påverka gränssnittets utseende för alla användare.',
+'sqlhidden' => '(gömd SQL-förfrågan)',
+'logouttitle' => 'Användarutloggning',
+'logouttext' => 'Du är nu utloggad från ditt användarkonto.',
+'welcomecreation' => '<h2>Välkommen, $1!</h2><p>Ditt konto har skapats. Glöm inte att justera dina inställningar.',
+'loginpagetitle' => 'Användarinloggning',
+'yourname' => 'Ditt användarnamn',
+'yourpassword' => 'Ditt lösenord',
+'yourpasswordagain' => 'Upprepa lösenord',
+'remembermypassword' => 'Automatisk inloggning i framtiden.',
+'yourdomainname' => 'Din domän',
+'externaldberror' => 'Antingen inträffade autentiseringsproblem med en extern databas, eller så får du inte uppdatera ditt externa konto.',
+'loginproblem' => '<b>Det uppstod problem vid inloggningen.</b><br />Pröva igen!',
+'alreadyloggedin' => '<strong>$1, du är redan inloggad!</strong><br />',
+'login' => 'Logga in',
+'loginprompt' => 'Inloggning är inte nödvändig för att läsa och skriva i {{SITENAME}}, men det har många fördelar. Bland annat får du tillgång till en rad användbara finesser och personliga inställningar. (Inloggningen använder [[cookie]]s)',
+'userlogin' => 'Skapa ett konto eller logga in',
+'logout' => 'Logga ut',
+'userlogout' => 'Logga ut',
+'notloggedin' => 'Ej inloggad',
+'nologin' => 'Saknar du ett användarkonto? $1.',
+'nologinlink' => 'Skapa ett användarkonto',
+'createaccount' => 'Skapa ett konto',
+'gotaccount' => 'Har du redan ett användarkonto? $1.',
+'gotaccountlink' => 'Logga in',
+'createaccountmail' => 'med e-post',
+'badretype' => 'De lösenord du uppgett överenstämmer inte med varandra.',
+'userexists' => 'Detta användarnamn är upptaget. Välj ett annat användarnamn.',
+'youremail' => 'Din e-postadress',
+'username' => 'Användarnamn:',
+'uid' => 'Användar-ID:',
+'yourrealname' => 'Ditt riktiga namn*',
+'yourlanguage' => 'Språk',
+'yourvariant' => 'Variant',
+'yournick' => 'Ditt smeknamn (till signaturer)',
+'badsig' => 'Det är något fel med råsignaturen, kontrollera HTML-koden.',
+'email' => 'E-post',
+'prefs-help-email-enotif'=> 'Om du slagit på funktionen för att få meddelanden om uppdateringar i mail, kommer denna adress att användas även för det.',
+'prefs-help-realname' => '¹ Riktigt namn (valfritt): Om du väljer att ange ditt riktiga namn, kommer det att användas för att tillskriva dig ditt arbete.',
+'loginerror' => 'Inloggningsproblem',
+'prefs-help-email' => '² E-post (valfritt): Gör det möjligt för andra användare att kontakta dig, utan att du behöver avslöja din identitet och/eller e-postadress.',
+'nocookiesnew' => 'Användarkontot skapades, men du blev inte inloggad. {{SITENAME}} använder cookies för att logga in användare. Du har stängt av cookies i din bläddrare. Om du slår på cookies kan du logga in med ditt nya användarnamn och lösenord.',
+'nocookieslogin' => '{{SITENAME}} använder cookies för att logga in användare. Du har stängt av cookies i din webbläsare. Försök igen med stöd för cookies aktiverat.',
+'noname' => 'Du har angett ett ogiltigt användarnamn.',
+'loginsuccesstitle' => 'Inloggningen lyckades',
+'loginsuccess' => 'Du är nu inloggad på {{SITENAME}} med användarnamnet "$1".',
+'nosuchuser' => 'Det finns ingen användare som heter "$1".
+Kontrollera stavningen, eller använd formuläret nedan för att skapa ett nytt konto.',
+'nosuchusershort' => 'Det finns ingen användare som heter "$1". Kontrollera att du stavat rätt.',
+'nouserspecified' => 'Du måste ange ett användarnamn.',
+'wrongpassword' => 'Lösenordet du angav är felaktigt. Försök igen',
+'wrongpasswordempty' => 'Lösenordet som angavs var blankt. Var god försök igen.',
+'mailmypassword' => 'Sänd mig ett nytt lösenord',
+'passwordremindertitle' => 'Nytt lösenord från {{SITENAME}}',
+'passwordremindertext' =>
+'Någon - förmodligen du - har från IP-numret $1 bett oss sända dig ett
+nytt lösenord för ditt användarkonto på {{SITENAME}} ($4).
+Lösenordet för användaren "$2" är nu "$3".
+
+Du bör nu logga in, och byta lösenord.
+
+Om det inte var du som gjorde denna begäran, eller om du har kommit på
+ditt gamla lösenord och inte längre önskar ändra det så kan du ignorera
+detta meddelande och fortsätta använda ditt gamla lösenord.',
+'noemail' => 'Användaren "$1" har inte registrerat någon e-postadress.',
+'passwordsent' => 'Ett nytt lösenord har skickats till den e-postadress som användaren "$1" har registrerat. När du får meddelandet, var god logga in igen.',
+'blocked-mailpassword' => 'Din IP-adress är blockerad, därför kan den inte användas för att få ett nytt lösenord.',
+'eauthentsent' => 'Ett e-brev för bekräftelse har skickats till den e-postadress som angivits. Du måste följa instruktionerna i e-brevet för att bekräfta att kontot verkligen är ditt, innan någon annan epost kan skickas härifrån till kontot,',
+'throttled-mailpassword' => 'Ett nytt lösenord har redan skickats under de senaste $1 timmarna. För att förhindra missbruk skickas bara ett nytt lösenord på under den tiden.',
+'mailerror' => 'Fel vid skickande av e-post: $1',
+'acct_creation_throttle_hit'=> 'Du har redan skapat $1 användare och kan inte göra fler.',
+'emailauthenticated' => 'Din e-postadress bekräftades den $1.',
+'emailnotauthenticated' => 'Din e-postadress är ännu inte bekräftad. Ingen e-post kommer att skickas vad gäller det följande:',
+'noemailprefs' => 'Det krävs att en e-postadress uppgivits för att dessa funktioner skall gå att använda.',
+'emailconfirmlink' => 'Bekräfta din e-postadress',
+'invalidemailaddress' => 'Denna e-postadressen kan inte godtas då formatet verkar vara felaktigt. Skriv in en adress på korrekt format, eller töm fältet.',
+'accountcreated' => 'Användarkontot har skapats',
+'accountcreatedtext' => 'Användarkontot $1 har skapats.',
+'resetpass' => 'Välj nytt lösenord',
+'resetpass_announce' => 'Du loggade in med ett temporärt lösenord. För att slutföra inloggningen måste du välja ett nytt lösenord.',
+'resetpass_header' => 'Välj nytt lösenord',
+'resetpass_submit' => 'Spara lösenord och logga in',
+'resetpass_success' => 'Ditt lösenord ändrades. Du är nu inloggad.',
+'resetpass_bad_temporary' => 'Ditt temporära lösenord är felaktigt. Du kanske redan har loggat in med det eller begärt att få ett nytt tillfälligt lösenord.',
+'resetpass_forbidden' => 'Lösenord kan inte ändras på den här wikin.',
+'resetpass_missing' => 'Formulärdata saknas.',
+'bold_sample' => 'Fet text',
+'bold_tip' => 'Fet stil',
+'italic_sample' => 'Kursiv text',
+'italic_tip' => 'Kursiv stil',
+'link_sample' => 'länkens namn',
+'link_tip' => 'Intern länk',
+'extlink_sample' => 'http://www.exempel.com länkens namn',
+'extlink_tip' => 'Extern länk (kom ihåg prefixet http://)',
+'headline_sample' => 'Rubriktext',
+'headline_tip' => 'Rubrik i nivå 2',
+'math_sample' => 'Skriv formeln här',
+'math_tip' => 'Matematisk formel (LaTeX)',
+'nowiki_sample' => 'Skriv in icke-wiki-formaterad text här',
+'nowiki_tip' => 'Strunta i wikiformatering',
+'image_sample' => 'Exempel.jpg',
+'image_tip' => 'Inbäddad bild',
+'media_sample' => 'Exempel.mp3',
+'media_tip' => 'Länk till mediafil',
+'sig_tip' => 'Din signatur med tidsstämpel',
+'hr_tip' => 'Horisontell linje (använd sparsamt)',
+'summary' => 'Sammanfattning',
+'subject' => 'Rubrik/uppslagsord',
+'minoredit' => 'Mindre ändring (m)',
+'watchthis' => 'Bevaka denna sida',
+'savearticle' => 'Spara',
+'preview' => 'Förhandsgranska',
+'showpreview' => 'Visa förhandsgranskning',
+'showlivepreview' => 'Automatiskt uppdaterad förhandsvisning',
+'showdiff' => 'Visa ändringar',
+'anoneditwarning' => 'Du är inte inloggad. Därför kommer din IP-adress att synas i historiken för den här sidan när du sparar din redigering.',
+'missingsummary' => '\'\'\'OBS:\'\'\' Du glömde att skriva en redigeringskommentar. Om du trycker på "Spara" igen så kommer din redigering att sparas utan redigeringskommentar.',
+'missingcommenttext' => 'Var god och skriv in en kommentar nedan.',
+'missingcommentheader' => '\'\'\'OBS:\'\'\' Du har inte skrivit någon rubrik till den här kommentaren. Om du trycker på "Spara" igen, så sparas kommentaren utan någon rubrik.',
+'summary-preview' => 'Sammanfattningsförhandsgranskning',
+'subject-preview' => 'Rubrikförhandsgranskning',
+'blockedtitle' => 'Användaren är spärrad',
+'blockedtext' => 'Du har försökt redigera en sida på {{SITENAME}}, men för närvarande kan du inte redigera sidor. Ditt användarnamn eller din IP-adress har blivit blockerat av $1 med motiveringen: \'\'$2\'\'.<br />
+Du kan kontakta $1 eller någon annan av [[Project:Administratörer|administratörerna]] för att diskutera blockeringen.<br />
+Observera att du inte kan använda dig av funktionen [[Special:Emailuser/$1|skicka e-post till $1]] om du inte är en registrerad användare och [[Special:Userlogin|inloggad]] och har uppgivit din e-postadress i dina inställningar. Om du inte har ett användarkonto, kan du [[Special:Userlogin|registrera ett]] för att kunna skicka wiki-mail.<br />
+Din IP-adress är $3. Vänligen ange denna IP-adress i alla förfrågningar i ärendet som du gör.',
+'blockedoriginalsource' => 'Källkoden för \'\'\'$1\'\'\' visas nedan:',
+'blockededitsource' => 'Texten för \'\'\'dina ändringar\'\'\' av \'\'\'$1\'\'\' visas nedanför:',
+'whitelistedittitle' => 'Redigering kräver inloggning',
+'whitelistedittext' => 'Du måste $1 för att kunna redigera artiklar.',
+'whitelistreadtitle' => 'Läsning kräver inloggning',
+'whitelistreadtext' => 'För att kunna läsa artiklar, måste du [[Special:Userlogin|logga in]].',
+'whitelistacctitle' => 'Du kan inte skapa konton',
+'whitelistacctext' => 'För att kunna skapa konton på denna wiki måste du vara [[Special:Userlogin|inloggad]] och ha rätt behörighet.',
+'confirmedittitle' => 'E-postbekräftelse krävs för redigering',
+'confirmedittext' => 'Du måste bekräfta din e-postadress innan du kan redigera sidor. Var vänlig ställ in och validera din e-postadress genom dina [[Special:Preferences|användarinställningar]].',
+'loginreqtitle' => 'Inloggning krävs',
+'loginreqlink' => 'login',
+'loginreqpagetext' => 'Du måste $1 för att visa andra sidor.',
+'accmailtitle' => 'Lösenordet är skickat.',
+'accmailtext' => 'Lösenordet för \'$1\' har skickats till $2.',
+'newarticle' => '(Ny)',
+'newarticletext' => 'Du har klickat på en röd länk, en sida som inte finns ännu. Du kan hjälpa till genom att själv skriva vad du vet om ämnet i fältet nedan (du kan läsa mer på [[Project:Help|hjälpsidan]]). Om du inte vill skriva något kan du bara trycka på "tillbaka" i din webbläsare.',
+'anontalkpagetext' => '---- \'\'Detta är en diskussionssida för en användare som inte har loggat in. [[{{SITENAME}}]] måste därför använda personens numeriska [[IP-adress]] för identifiera honom eller henne. En sådan IP-adress kan ibland användas av flera olika personer. Om du får meddelanden här som inte tycks vara riktade till dig, kan du gärna [[Special:Userlogin|logga in]]. Då undviker du framtida förväxlingar.\'\'',
+'noarticletext' => '<div class="plainlinks" style="border: 1px solid #ccc; padding: 7px;">\'\'\'{{SITENAME}} har inte någon artikel om "{{PAGENAME}}" ännu.\'\'\'<br />
+*Du kan \'\'\'[{{fullurl:{{FULLPAGENAME}}|action=edit}} redigera den här sidan]\'\'\' för att skapa en ny artikel.<br />
+*Du kan också [[Special:Search/{{PAGENAME}}|söka efter {{PAGENAME}}]] i andra artiklar på {{SITENAME}}.<br />
+*Det kan också hända att artikeln har raderats. Se då i [{{fullurl:Special:Log/delete|page={{FULLPAGENAMEE}}}} raderingsloggen].<br />
+----<br />
+*Om du har skapat artikeln under de senaste minuterna kan du ändå få upp denna sida ifall {{SITENAME}}s cache inte hunnit uppdateras. Vänligen vänta då en liten stund och se om artikeln syns senare innan du försöker skapa den igen.</div>',
+'clearyourcache' => '\'\'\'Obs:\'\'\' Sedan du sparat sidan, måste du tömma din webbläsares cache för att se ändringarna. \'\'\'Mozilla/Safari/Firefox:\'\'\' håll ner \'\'skift\'\' och klicka på \'\'reload\'\' eller tryck \'\'ctrl-shift-r\'\', (cmd-shift-R på mac:ar); \'\'\'Internet Explorer:\'\'\' håll ner ctr och klicka på "Refresh" eller tryck \'\'ctrl-f5\'\', \'\'\'Konqueror:\'\'\': klicka helt enkelt på "Reload" eller F5; \'\'\'Opera:\'\'\' tryck \'\'F5\'\'',
+'usercssjsyoucanpreview'=> '<strong>Tips:</strong> Använd \'Visa förhandsgranskning\' för att testa din nya css/js innan du sparar.',
+'usercsspreview' => '\'\'\'Observera att du bara förhandsgranskar din användar-css - den har inte sparats än.\'\'\'',
+'userjspreview' => '\'\'\'Observera att du bara testar/förhandsgranskar ditt javascript! Det är inte sparat än.\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Varning:\'\'\' Skalet "$1" finns inte. Kom ihåg att .css- och .js-sidor för enskilda användare börjar på liten bokstav. Exempel: Användare:Foo/monobook.css i stället för Användare:Foo/Monobook.css.',
+'updated' => '(Uppdaterad)',
+'note' => '<strong>Obs!</strong>',
+'previewnote' => 'Observera att detta är en förhandsvisning, och att sidan ännu inte sparats!',
+'session_fail_preview' => '<strong>Databasen kunde inte bearbeta redigeringen på grund av ett bortfall av sessionsdata. Försök igen; om det fortfarande inte fungerar, prova att öppna om redigeringssidan, logga ut och logga in igen eller vänta ett tag på att felet fixas.</strong>',
+'previewconflict' => 'Den här förhandsvisningen är resultatet av den
+redigerbara texten ovanför,
+så som det kommer att se ut om du väljer att spara.',
+'session_fail_preview_html'=> '<strong>Beklagar! Vi kunde inte databehandla din redigering på grund av att sessionens data gått förlorad.</strong>
+
+\'\'Eftersom denna wiki har aktiverat rå HTML, så döljs förhandsvisningen som en förebyggande säkerhetsåtgärd med syfte att förhindra JavaScript-attacker.\'\'',
+'importing' => 'Importerar $1',
+'editing' => 'Redigerar $1',
+'editinguser' => 'Redigerar $1',
+'editingsection' => 'Redigerar $1 (avsnitt)',
+'editingcomment' => 'Redigerar $1 (kommentar)',
+'editconflict' => 'Redigeringskonflikt: $1',
+'explainconflict' => 'Någon har ändrat den här sidan efter att du började att redigera den.
+Det översta textblocket innehåller den nuvarande texten, och din version syns i det nedersta blocket. Om du infogar dina ändringar i texten i den översta rutan, bibehålls alla ändringar - både dina, och den andres. <strong>Endast</strong> texten i den översta textboxen sparas när du trycker "Spara sida".
+<p>',
+'yourtext' => 'Din text',
+'storedversion' => 'Den sparade versionen',
+'nonunicodebrowser' => '<strong>VARNING: Din webbläsare saknar stöd för unicode. Var vänlig åtgärda detta, förslagsvis genom att uppgradera din webbläsare, innan du redigerar någon artikel. Artiklar riskerar annars att förstöras.</strong>',
+'editingold' => '<strong>VARNING: Du redigerar en gammal version av denna sida. Om du sparar den kommer alla ändringar som har gjorts sedan denna version att skrivas över.</strong>',
+'yourdiff' => 'Skillnader',
+'copyrightwarning' => 'Observera att alla bidrag till {{SITENAME}} är att betrakta som utgivna under $2 (se $1 för detaljer). Om du inte vill att din text ska redigeras eller kopieras efter andras gottfinnande skall du inte skriva något här.<br />
+Du lovar oss också att du skrev texten själv, eller kopierade från kulturellt allmängods som inte skyddas av upphovsrätt, eller liknande källor. <strong>LÄGG INTE UT UPPHOVSRÄTTSSKYDDAT MATERIAL HÄR UTAN TILLÅTELSE!</strong>',
+'copyrightwarning2' => 'Observera att alla bidrag till {{SITENAME}} kan komma att redigeras, ändras, eller tas bort av andra deltagare. Om du inte vill se din text förändrad efter andras gottfinnade skall du inte skriva in någon text här.<br />
+Du lovar oss också att du skrev texten själv, eller kopierade från kulturellt allmängods som inte skyddas av upphovsrätt, eller liknande källor - se $1 för detaljer.
+<strong>LÄGG INTE UT UPPHOVSRÄTTSSKYDDAT MATERIAL HÄR UTAN TILLÅTELSE!</strong>',
+'longpagewarning' => 'Om du använder en väldigt gammal webbläsare kan du ha problem med att redigera den här artikeln, eftersom vissa äldre webbläsare inte klarar artiklar större än 32 kB, och den här är $1 kB.',
+'longpageerror' => '<strong>FEL: Texten som du försöker spara är $1 kilobyte, vilket är mer än det maximalt tillåtna $2 kilobyte. Den kan inte sparas.</strong>',
+'readonlywarning' => '<strong>VARNING: Databasen är tillfälligt låst för underhåll. Du kommer inte att kunna spara
+dina ändringar just nu. Det kan vara klokt att kopiera över texten till din egen dator, tills databasen är upplåst igen.</strong>',
+'protectedpagewarning' => '<strong>VARNING: Den här sidan har låsts så att bara administratörer kan redigera den.
+Försäkra dig om att du följer riktlinjerna för redigering av skyddade sidor.</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Observera:\'\'\' Denna sida har delvis skrivskyddats, så att endast registrerade användare kan redigera den.',
+'templatesused' => 'Mallar som används på den här sidan:',
+'templatesusedpreview' => 'Mallar som används i förhandsgranskningen:',
+'templatesusedsection' => 'Mallar som används i det här avsnittet:',
+'edittools' => '<!-- Denna text kommer att visas nedanför redigeringsrutor och uppladdningsformulär. -->',
+'nocreatetitle' => 'Skapande av sidor begränsat',
+'nocreatetext' => 'Denna wiki har begränsat möjligheterna att skapa nya sidor. Du kan redigera existerande sidor, eller [[Special:Userlogin|logga in eller skapa ett användarkonto]].',
+'undo-success' => 'Ändringen kunde ogöras. Resultatet visas i redigeringsrutan, spara det genom att trycka på "spara".',
+'undo-failure' => 'På grund av senare redigeringar kunde inte ändringen ogöras.',
+'undo-summary' => 'Ogör ändring $1 av [[Special:Contributions/$2]] ([[Användardiskussion:$2]])',
+'cantcreateaccounttitle' => 'Kontot kan inte skapas',
+'cantcreateaccounttext' => 'Registrering av konton har blockerats för den här IP-adressen (<b>$1</b>). Det beror antagligen på återkommande klotter och vandalism från adressen.',
+'revhistory' => 'Versionshistorik',
+'viewpagelogs' => 'Visa loggar för denna sida',
+'nohistory' => 'Den här sidan har ingen versionshistorik.',
+'revnotfound' => 'Versionen hittades inte',
+'revnotfoundtext' => 'Den gamla versionen av den sida du frågade efter kan inte hittas. Kontrollera den URL du använde för att nå den här sidan.',
+'loadhist' => 'Läser sidans versioner',
+'currentrev' => 'Nuvarande version',
+'revisionasof' => 'Versionen från $1',
+'revision-info' => 'Version från den $1; $2',
+'previousrevision' => '← Äldre version',
+'nextrevision' => 'Nyare version →',
+'currentrevisionlink' => 'Nuvarande version',
+'cur' => 'nuvarande',
+'next' => 'nästa',
+'last' => 'föregående',
+'orig' => 'original',
+'histlegend' => 'Förklaring: (nuvarande) = skillnad mot nuvarande version; (föregående) = skillnad mot föregående version; \'\'\'m\'\'\' = mindre ändring.',
+'deletedrev' => '[raderad]',
+'histfirst' => 'Första',
+'histlast' => 'Senaste',
+'rev-deleted-comment' => '(kommentar borttagen)',
+'rev-deleted-user' => '(användarnamn borttaget)',
+'rev-deleted-text-permission'=> '<div class="mw-warning plainlinks"> Denna version av sidan har avlägsnats från de öppna arkiven. Det kan finnas detaljer i [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} borttagningsloggen]. </div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks"> Denna version av sidan har avlägsnats från de öppna arkiven. Som administratör på denna wiki kan du se den; det kan finnas detaljer i [{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} borttagningsloggen]. </div>',
+'rev-delundel' => 'visa/göm',
+'history-feed-title' => 'Versionshistorik',
+'history-feed-description'=> 'Versionshistorik för denna sida på wikin',
+'history-feed-item-nocomment'=> '$1 den $2',
+'history-feed-empty' => 'Den begärda sidan finns inte.
+Den kan ha tagits bort från wikin eller bytt namn.
+Prova att [[Special:Search|söka på wikin]] för relevanta nya sidor.',
+'revisiondelete' => 'Ta bort/återställ versioner',
+'revdelete-nooldid-title' => 'Ingen version angiven',
+'revdelete-nooldid-text' => 'Du angav inte vilken eller vilka versioner du vill utföra funktionen på.',
+'revdelete-selected' => 'Vald version av [[:$1|$1]]:',
+'revdelete-text' => 'Borttagna versioner kommer fortfarande att synas i historiken, men deras innehåll kommer ej att vara tillgängligt för allmänheten. Andra administratörer på denna wiki kommer fortfarande att kunna läsa det dolda innehållet och kan återställa artikeln genom samma gränssnitt, om inte en ytterligare begränsning har utfärdats av sajtens ägare.',
+'revdelete-legend' => 'Ange begränsningar för version:',
+'revdelete-hide-text' => 'Dölj versionstext',
+'revdelete-hide-comment'=> 'Dölj redigeringskommentar',
+'revdelete-hide-user' => 'Dölj den redigerandes användarnamn/IP-address',
+'revdelete-hide-restricted'=> 'Låt dessa begränsningar gälla administratörer likväl som andra',
+'revdelete-log' => 'Loggkommentar:',
+'revdelete-submit' => 'Tillämpa på vald version',
+'revdelete-logentry' => 'om [[:$1|$1]] visas eller ej har ändrats',
+'difference' => '(Skillnad mellan versioner)',
+'loadingrev' => 'läser version för att se skillnad',
+'lineno' => 'Rad $1:',
+'editcurrent' => 'Redigera sidans nuvarande version',
+'selectnewerversionfordiff'=> 'Välj en nyare version för jämförelse',
+'selectolderversionfordiff'=> 'Välj en äldre version för jämförelse',
+'compareselectedversions'=> 'Jämför angivna versioner',
+'editundo' => 'ogör',
+'diff-multi' => '({{plural:$1|En mellanliggande version|$1 mellanliggande versioner}} visas inte.)',
+'searchresults' => 'Sökresultat',
+'searchresulttext' => 'Läs mera om [[Project:Sökning|sökning på {{SITENAME}}]].',
+'searchsubtitle' => 'Du sökte efter [[:$1]]',
+'searchsubtitleinvalid' => 'För sökbegreppet $1',
+'badquery' => 'Felaktigt utformat sökbegrepp',
+'badquerytext' => 'Tyvärr, den sökningen fungerade inte. Detta beror troligen på att att du har försökt söka på ett ord som är kortare än tre bokstäver, vilket i nuläget inte stöds. Det kan också vara som så att du har skrivit in uttrycket fel, till exempel "katt och och råtta". Vänligen försök igen.',
+'matchtotals' => 'Sökordet "$1" gav $2 träffar i uppslagsord, och $3 träffar i texten på artiklar.',
+'noexactmatch' => '\'\'\'Det finns ingen artikel med titeln "$1".\'\'\' Du kan [[:$1|skapa denna sida]].',
+'titlematches' => 'Träffar i uppslagsord',
+'notitlematches' => 'Det finns ingen artikel vars titel överensstämmer med sökordet.',
+'textmatches' => 'Artikeltexter som innehåller sökordet:',
+'notextmatches' => 'Det finns inga artiklar som innehåller sökordet',
+'prevn' => 'förra $1',
+'nextn' => 'nästa $1',
+'viewprevnext' => 'Visa ($1) ($2) ($3).',
+'showingresults' => 'Nedan visas <b>$1</b> resultat som startar med nummer <b>$2</b>.',
+'showingresultsnum' => 'Nedan visas <b>$3</b> resultat, som börjar med #<b>$2</b>.',
+'nonefound' => '<strong>Observera:</strong>: Sökningar utan träffar beror ofta på att man försöker söka efter vanliga ord som "har" och "från". Dessa indexeras inte, och fungerar inte som söktermer. Försök istället hitta mera specifika ord.',
+'powersearch' => 'Sök',
+'powersearchtext' => 'Sök i namnrymderna :<br />
+$1<br />
+$2 Lista omdirigeringar &nbsp; Sök efter $3 $9',
+'searchdisabled' => 'Fulltextssökning på {{SITENAME}} har tyvärr tillfälligt stängts av p.g.a. prestandaproblem. Tills detta har fixats, kan du använda Google-sökningen nedan. Resultaten därifrån kan dock vara något föråldrade.',
+'blanknamespace' => '(Artiklar)',
+'preferences' => 'Inställningar',
+'mypreferences' => 'Mina inställningar',
+'prefsnologin' => 'Du är inte inloggad',
+'prefsnologintext' => 'Du måste vara [[Special:Userlogin|inloggad]] för att kunna ändra i inställningar.',
+'prefsreset' => 'Inställningarna har återställts till ursprungsvärdena.',
+'qbsettings' => 'Inställningar för snabbmeny',
+'changepassword' => 'Byt lösenord',
+'skin' => 'Utseende',
+'math' => 'Matematik',
+'dateformat' => 'Datumformat',
+'datedefault' => 'Ovidkommande',
+'datetime' => 'Datum och tid',
+'math_failure' => 'Misslyckades med att tolka formel.',
+'math_unknown_error' => 'okänt fel',
+'math_unknown_function' => 'okänd funktion',
+'math_lexing_error' => 'regelfel',
+'math_syntax_error' => 'syntaxfel',
+'math_image_error' => 'Konvertering till PNG-format misslyckades; kontrollera om latex, dvips, gs och convert är korrekt installerade',
+'math_bad_tmpdir' => 'Kan inte skriva till eller skapa temporär mapp för matematikresultat',
+'math_bad_output' => 'Kan inte skriva till eller skapa mapp för matematikresultat',
+'math_notexvc' => 'Applicationen texvc saknas; läs math/README för konfigureringsanvisningar.',
+'prefs-personal' => 'Mitt konto',
+'prefs-rc' => 'SÄ och stubbar',
+'prefs-watchlist' => 'Övervakningslistan',
+'prefs-watchlist-days' => 'Antal dagar som ska visas på övervakningslistan:',
+'prefs-watchlist-edits' => 'Antal redigeringar som visas i utökad övervakningslista:',
+'prefs-misc' => 'Diverse',
+'saveprefs' => 'Spara inställningar',
+'resetprefs' => 'Återställ ursprungliga inställningar',
+'oldpassword' => 'Gammalt lösenord',
+'newpassword' => 'Nytt lösenord',
+'retypenew' => 'Upprepa det nya lösenordet',
+'textboxsize' => 'Redigering',
+'rows' => 'Rader',
+'columns' => 'Kolumner',
+'searchresultshead' => 'Sökresultat',
+'resultsperpage' => 'Träffar per sida',
+'contextlines' => 'Antal rader per träff',
+'contextchars' => 'Bokstäver per rad',
+'stubthreshold' => 'Visa länkar i avvikande färg till artiklar som är kortare än',
+'recentchangescount' => 'Antalet artiklar i "senaste ändringarna":',
+'savedprefs' => 'Dina inställningar har sparats',
+'timezonelegend' => 'Tidszon',
+'timezonetext' => 'Ange skillnaden i timmar mellan din lokala tid och serverns tid (UTC).',
+'localtime' => 'Lokal tid',
+'timezoneoffset' => 'Utjämna',
+'servertime' => 'Serverns klocka är',
+'guesstimezone' => 'Fyll i från webbläsare',
+'allowemail' => 'Tillåt e-post från andra användare',
+'defaultns' => 'Sök i följande namnrymder som förval:',
+'default' => 'ursprungsinställning',
+'files' => 'Filer',
+'userrights-lookup-user'=> 'Hantera användargrupper',
+'userrights-user-editname'=> 'Skriv in ett användarnamn:',
+'editusergroup' => 'Ändra användargrupper',
+'userrights-editusergroup'=> 'Redigera användargrupper',
+'saveusergroups' => 'Spara användargrupper',
+'userrights-groupsmember'=> 'Medlem i:',
+'userrights-groupsavailable'=> 'Tillgängliga grupper:',
+'userrights-groupshelp' => 'Markera de grupper, som du vill lägga till eller ta bort användare i. De grupper som du inte markerar, kommer inte att förändras. Du kan avmarkera en grupp med CTRL + vänsterklick.',
+'group' => 'Grupp:',
+'group-bot' => 'Robotar',
+'group-sysop' => 'Administratörer',
+'group-bureaucrat' => 'Byråkrater',
+'group-all' => '(alla)',
+'group-bot-member' => 'Robot',
+'group-sysop-member' => 'Administratör',
+'group-bureaucrat-member'=> 'Byråkrat',
+'grouppage-bot' => 'Project:Robotar',
+'grouppage-sysop' => 'Project:Administratörer',
+'grouppage-bureaucrat' => 'Project:Byråkrater',
+'changes' => 'ändringar',
+'recentchanges' => 'Senaste ändringarna',
+'recentchangestext' => 'Följ de senaste ändringarna i wikin på denna sida.',
+'rcnote' => 'Nedan visas de senaste <strong>$1</strong> ändringarna under de senaste <strong>$2</strong> dagarna, per $3.',
+'rcnotefrom' => 'Nedan visas de senaste <strong>$1</strong> ändringarna sedan <strong>$2</strong>.',
+'rclistfrom' => 'Visa ändringar efter $1',
+'rcshowhideminor' => '$1 mindre ändringar',
+'rcshowhidebots' => '$1 robotredigeringar',
+'rcshowhideliu' => '$1 ändringar av inloggade användare',
+'rcshowhideanons' => '$1 ändringar av oinloggade användare',
+'rcshowhidepatr' => '$1 kontrollerade redigeringar',
+'rcshowhidemine' => '$1 mina ändringar',
+'rclinks' => 'Visa de senaste $1 ändringarna under de senaste $2 dagarna<br />
+$3',
+'diff' => 'skillnad',
+'hist' => 'historik',
+'hide' => 'Göm',
+'show' => 'Visa',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview'=> '[$1 användare bevakar]',
+'rc_categories' => 'Begränsa till följande kategorier (separera med "|")',
+'rc_categories_any' => 'Vilken som helst',
+'upload' => 'Ladda upp filer',
+'uploadbtn' => 'Ladda upp filen',
+'reupload' => 'Ladda upp på nytt',
+'reuploaddesc' => 'Tillbaka till uppladdningsformulär.',
+'uploadnologin' => 'Inte inloggad',
+'uploadnologintext' => 'Du måste vara [[Special:Userlogin|inloggad]] för att kunna ladda upp filer.',
+'upload_directory_read_only'=> 'Webbservern kan inte skriva till uppladdningskatalogen ($1).',
+'uploaderror' => 'Fel vid uppladdningen',
+'uploadtext' => 'Använd formuläret nedan för att ladda upp filer. För att titta på eller leta efter bilder som redan har laddats upp, se [[Special:Imagelist|lista över uppladdade filer]]. Uppladdningar och borttagningar loggförs också i [[Special:Log/upload|uppladdningsloggen]]. För att infoga en bild på en sida, använd en länk i i följande format:
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:File.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:File.png|alt text]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:File.ogg]]</nowiki>\'\'\'
+om du vill länka direkt till filen.',
+'uploadlog' => 'Uppladdningar',
+'uploadlogpage' => 'Uppladdningslogg',
+'uploadlogpagetext' => 'Nedan följer en lista med de senaste uppladdade filerna.
+Alla tider visas efter serverns tid (UTC).
+<ul>
+</ul>',
+'filename' => 'Filnamn',
+'filedesc' => 'Beskrivning',
+'fileuploadsummary' => 'Beskrivning<br />och licens:',
+'filestatus' => 'Upphovsrättslig status',
+'filesource' => 'Källa',
+'copyrightpage' => 'Project:Upphovsrätt',
+'copyrightpagename' => '{{SITENAME}} upphovsrätt',
+'uploadedfiles' => 'Uppladdade filer',
+'ignorewarning' => 'Ignorera varning och spara ändå.',
+'ignorewarnings' => 'Ignorera eventuella varningar',
+'minlength' => 'Bildfilens namn måste vara minst tre bokstäver långt',
+'illegalfilename' => 'Filnamnet "$1" innehåller tecken som inte är tillåtna i sidtitlar. Byt namn på filen och försök ladda upp igen.',
+'badfilename' => 'Bildens namn har blivit ändrat till "$1".',
+'badfiletype' => '".$1" är inte ett rekommenderat bildformat.',
+'largefile' => 'Bilder bör inte vara större än $1 bytes, denna är $2 bytes',
+'largefileserver' => 'Denna fil är större än vad servern ställts in att tillåta.',
+'emptyfile' => 'Filen du laddade upp verkar vara tom; felet kan bero på ett stavfel i filnamnet. Kontrollera om du verkligen vill ladda upp denna fil.',
+'fileexists' => 'Det finns redan en fil med detta namn. Titta på $1, såvida du inte är säker på att du vill ändra den.',
+'fileexists-forbidden' => 'En fil med detta namn finns redan; vänligen backa och ladda upp din fil under ett annat namn [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'En fil med detta namn finns redan bland de delade filerna; vänligen backa och ladda upp din fil under ett annat namn. [[Image:$1|thumb|center|$1]]',
+'successfulupload' => 'Uppladdningen lyckades',
+'fileuploaded' => 'Filen "$1" laddades upp korrekt.
+Följ länken ($2) till beskrivningssidan, och fyll där i
+information om filen: var den kommer ifrån,
+när den skapades, vem som gjort den, om själva innehållet, och så mycket om möjligt annat du vet om den.',
+'uploadwarning' => 'Uppladdningsvarning',
+'savefile' => 'Spara fil',
+'uploadedimage' => '"[[$1]]" laddades upp',
+'uploaddisabled' => 'Uppladdningsfunktionen är avstängd',
+'uploaddisabledtext' => 'Uppladdning av filer är avstängd på den här wikin',
+'uploadscripted' => 'Denna fil innehåller HTML eller script, som webbläsare kan komma att tolka felaktigt.',
+'uploadcorrupt' => 'Antingen har det blivit något fel på filen, eller så har den en felaktig filändelse. Kontrollera din fil, och ladda upp på nytt.',
+'uploadvirus' => 'Filen innehåller virus! Detaljer: $1',
+'sourcefilename' => 'Ursprungsfilens namn',
+'destfilename' => 'Nytt filnamn',
+'watchthisupload' => 'Bevaka sidan',
+'filewasdeleted' => 'En fil med detta namn har tidigare laddats upp och därefter tagits bort. Du bör kontrollera $1 innan du fortsätter att ladda upp den.',
+'upload-proto-error' => 'Felaktigt protokoll',
+'upload-proto-error-text' => 'Fjärruppladdning kräver URL:ar som börjar med <code>http://</code> eller <code>ftp://</code>.',
+'upload-file-error' => 'Internt fel',
+'upload-file-error-text' => 'Ett internt fel inträffade när en temporär fil skulle skapas på servern. Kontakta en systemadministratör.',
+'upload-misc-error' => 'Okänt uppladdningsfel',
+'upload-misc-error-text' => 'Ett okänt fel inträffade under uppladdningen. Kontrollera att URL:en giltig och frösök igen. Om problemet kvarstår, kontakta en systemadministratör.',
+'upload-curl-error6' => 'URL:en kunde inte nås',
+'upload-curl-error6-text' => 'Den angivna URL:en kunde inte nås. Kontrollera att den är korrekt och att webbplatsern fungerar.',
+'upload-curl-error28' => 'Timeout för uppladdningen',
+'upload-curl-error28-text' => 'Webbplatsen tog för lång tid på sig att svara. Kontrollera att den är uppe och försök igen om en liten stund.',
+'license' => 'Licens',
+'nolicense' => 'Ingen angiven',
+'upload_source_url' => ' (en giltig URL som är allmänt åtkomlig)',
+'upload_source_file' => ' (en fil på din dator)',
+'imagelist' => 'Bildlista',
+'imagelisttext' => 'Nedan finns en lista med <strong>$1</strong> {{plural:$1|bild|bilder}} sorterad <strong>$2</strong>.',
+'imagelistforuser' => 'Listan visar endast bilder som är uppladdade av $1.',
+'getimagelist' => 'hämta bildlista',
+'ilsubmit' => 'Sök',
+'showlast' => 'Visa de senaste $1 bilderna sorterade $2.',
+'byname' => 'efter namn',
+'bydate' => 'efter datum',
+'bysize' => 'efter storlek',
+'imgdelete' => 'ta bort',
+'imgdesc' => 'beskrivning',
+'imgfile' => 'fil',
+'imglegend' => 'Bildtext: (beskrivning) = visa/redigera bildtext.',
+'imghistory' => 'Bildhistorik',
+'revertimg' => 'återgå',
+'deleteimg' => 'radera',
+'deleteimgcompletely' => 'radera',
+'imghistlegend' => 'Beskrivning: (nuvarande) = detta är den nuvarande bilden,
+(ta bort) = ta bort den gamla version, (återgå) = återgå till en gammal version.
+<br /><i>Klicka på ett datum för att se bilden som laddades upp den dagen</i>.',
+'imagelinks' => 'Bildlänkar',
+'linkstoimage' => 'Följande sidor länkar till denna bild:',
+'nolinkstoimage' => 'Inga sidor länkar till den här bilden.',
+'sharedupload' => 'Denna fil är uppladdad som delad, och kan användas av andra projekt.',
+'shareduploadwiki' => 'Vänligen se $1 för mer information.',
+'shareduploadwiki-linktext'=> 'Filens beskrivningssida',
+'noimage' => 'Det finns ingen fil med detta namn. Du kan $1.',
+'noimage-linktext' => 'ladda upp den',
+'uploadnewversion-linktext'=> 'Ladda upp en ny version av denna fil',
+'imagelist_date' => 'Datum',
+'imagelist_name' => 'Filnamn',
+'imagelist_user' => 'Användare',
+'imagelist_size' => 'Storlek (bytes)',
+'imagelist_description' => 'Filbeskrivning',
+'imagelist_search_for' => 'Sök efter bildnamn:',
+'mimesearch' => 'MIME-sökning',
+'mimetype' => 'MIME-typ:',
+'download' => 'ladda ner',
+'unwatchedpages' => 'Oövervakade sidor',
+'listredirects' => 'Lista över omdirigeringar',
+'unusedtemplates' => 'Oanvända mallar',
+'unusedtemplatestext' => 'Denna sida listar alla de sidor i namnrymden Mall som inte inkluderas på någon annan sida. Innan mallarna raderas, kontrollera att det inte finns andra länkar till dem.',
+'unusedtemplateswlh' => 'andra länkar',
+'randomredirect' => 'Slumpvald omdirigering',
+'statistics' => 'Statistik',
+'sitestats' => 'Statistiksida',
+'userstats' => 'Användarstatistik',
+'sitestatstext' => 'I databasen finns just nu <b>$1</b> sidor, inklusive diskussionssidor, sidor om {{SITENAME}}, korta stumpartiklar, omdirigeringssidor, och andra sidor som inte kan räknas som artiklar. Om man tar bort ovanstående, återstår <b>$2</b> riktiga artiklar.
+
+\'\'\'$8\'\'\' filer har laddats upp.
+
+Sedan denna wiki startades har sidor visats totalt <b>$3</b> gånger, och <b>$4</b> sidor har ändrats. Detta är i genomsnitt <b>$5</b> ändringar per sida, och <b>$6</b> sidvisningar per ändring.
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue Jobbkön]s längd är för tillfället \'\'\'$7\'\'\'.',
+'userstatstext' => 'Det finns \'\'\'$1\'\'\' registrerade användare. Av dem är \'\'\'$2\'\'\' (eller \'\'\'$4%\'\'\') $5.',
+'statistics-mostpopular' => 'Mest besökta sidor',
+'disambiguations' => 'Sidor som länkar till förgreningssidor',
+'disambiguationspage' => 'Template:Förgrening',
+'disambiguationstext' => 'Följande artiklar länkar till \'\'förgreningssidor\'\'. Länkarna behöver ofta ändras så att de länkar till en artikel istället.<br />En sida anses vara en förgreningssida om den länkar till $1. <br />Länkar från andra namnrymder är <i>inte</i> listade här.',
+'doubleredirects' => 'Dubbla omdirigeringar',
+'doubleredirectstext' => '<b>OBS!</b> Denna lista kan innehålla falska resultat. Detta betyder normalt att det finns ytterligare text under den första #REDIRECT.<br />Varje rad innehåller en länk till den första och andra omdirigering och den första raden av den andra omdirigeringen ger oftast den "riktiga" artikeln, vilket egentligen den första omdirigeringen ska peka på.',
+'brokenredirects' => 'Dåliga omdirigeringar',
+'brokenredirectstext' => 'Följande länkar omdirigerar till en artikel som inte existerar.',
+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
+'ncategories' => '$1 {{PLURAL:$1|kategori|kategorier}}',
+'nlinks' => '$1 {{PLURAL:$1|länk|länkar}}',
+'nmembers' => '$1 {{PLURAL:$1|medlem|medlemmar}}',
+'nrevisions' => '$1 {{PLURAL:$1|ändring|ändringar}}',
+'nviews' => '$1 {{PLURAL:$1|visning|visningar}}',
+'lonelypages' => 'Föräldralösa sidor',
+'lonelypagestext' => 'Följande sidor länkas inte till från någon annan sida på den här wikin.',
+'uncategorizedpages' => 'Ej kategoriserade sidor',
+'uncategorizedcategories'=> 'Ej kategoriserade kategorier',
+'uncategorizedimages' => 'Bilder utan kategori',
+'unusedcategories' => 'Tomma kategorier',
+'unusedimages' => 'Oanvända bilder',
+'popularpages' => 'Populära sidor',
+'wantedcategories' => 'Önskade kategorier',
+'wantedpages' => 'Önskade sidor',
+'mostlinked' => 'Sidor med flest länkar till sig',
+'mostlinkedcategories' => 'Kategorier med flest länkar till sig',
+'mostcategories' => 'Artiklar med flest kategorier',
+'mostimages' => 'Bilder med flest länkar till sig',
+'mostrevisions' => 'Artiklar med flest ändringar',
+'allpages' => 'Alla sidor',
+'prefixindex' => 'Prefixindex',
+'randompage' => 'Slumpartikel',
+'shortpages' => 'Korta sidor',
+'longpages' => 'Långa sidor',
+'deadendpages' => 'Sidor utan länkar',
+'deadendpagestext' => 'Följande sidor saknar länkar till andra sidor på den här wikin.',
+'listusers' => 'Användarlista',
+'specialpages' => 'Specialsidor',
+'spheading' => 'Specialsidor för alla användare',
+'restrictedpheading' => 'Specialsidor med begränsad åtkomst',
+'recentchangeslinked' => 'Ändringar på angränsande sidor',
+'rclsub' => '(som "$1" länkar till)',
+'newpages' => 'Nya sidor',
+'newpages-username' => 'Användare:',
+'ancientpages' => 'Äldsta artiklarna',
+'intl' => 'Interwiki-länkar',
+'move' => 'Flytta',
+'movethispage' => 'Flytta denna sida',
+'unusedimagestext' => '<p>Lägg märke till att andra hemsidor kan länka till bilder
+med en direkt URL, och kan därför bli listade här trots att de används kontinuerligt.',
+'unusedcategoriestext' => 'Dessa existerande kategorier innehåller inga artiklar eller underkategorier.',
+'booksources' => 'Bokkällor',
+'booksources-search-legend' => 'Sök efter bokkällor',
+'booksources-go' => 'Sök',
+'booksources-text' => 'Nedan följer en lista över länkar till webbplatser som säljer nya och begagnade böcker, och som kanske har ytterligare information om de böcker du söker.',
+'categoriespagetext' => 'Följande kategorier finns på {{SITENAME}}.',
+'data' => 'Data',
+'userrights' => 'Användarrättigheter',
+'groups' => 'Användargrupper',
+'isbn' => 'ISBN',
+'alphaindexline' => '$1 till $2',
+'version' => 'Version',
+'log' => 'Loggar',
+'alllogstext' => 'Kombinerad visning av uppladdningar av bilder, raderinger och skrivskydd av sidor, blockeringar av IP-adresser/användare, och byråkratlogg. Du får ofta färre träffar om du väljer typ av logg, användarnamn, eller sida.',
+'logempty' => 'Inga matchande träffar i loggen.',
+'nextpage' => 'Nästa sida ($1)',
+'prevpage' => 'Föregående sida ($1)',
+'allpagesfrom' => 'Visa sidor från och med:',
+'allarticles' => 'Alla artiklar',
+'allinnamespace' => 'Alla sidor (i namnrymden $1)',
+'allnotinnamespace' => 'Alla sidor (inte i namnrymden $1)',
+'allpagesprev' => 'Föregående',
+'allpagesnext' => 'Nästa',
+'allpagessubmit' => 'Utför',
+'allpagesprefix' => 'Visa sidor med prefixet:',
+'allpagesbadtitle' => 'Den sökta sidtiteln var ogiltig eller så innehöll den ett prefix för annan språkversion eller interwiki-prefix. Titeln kan innehålla bokstäver som inte är tillåtna i sidtitlar.',
+'listusersfrom' => 'Visa användare från och med:',
+'mailnologin' => 'Ingen adress att skicka till',
+'mailnologintext' => 'För att kunna skicka e-post till andra användare, måste du vara [[Special:Userlogin|inloggad]] och ha angivit en korrekt e-postadress i dina [[Special:Preferences|användarinställningar]].',
+'emailuser' => 'Skicka e-post till den här användaren',
+'emailpage' => 'Skicka e-post till annan användare',
+'emailpagetext' => 'Om den här användaren har skrivit in en korrekt e-postadress i sina
+användarinställningar, kommer formuläret nedan att skicka ett meddelande.
+Den e-postadress du har angivit i dina användarinställningar kommer att skrivas
+i "Från"-fältet i detta meddelande, så mottagaren har möjlighet att svara.',
+'usermailererror' => 'Fel i hanteringen av mail:',
+'defemailsubject' => '{{SITENAME}} e-post',
+'noemailtitle' => 'Ingen e-postadress',
+'noemailtext' => 'Den här användaren har antingen inte angivet en korrekt e-postadress, valt att inte ta emot mail från andra användare, eller inte verifierat sin e-postadress.',
+'emailfrom' => 'Från',
+'emailto' => 'Till',
+'emailsubject' => 'Ämne',
+'emailmessage' => 'Meddelande',
+'emailsend' => 'Skicka',
+'emailccme' => 'Skicka en kopia av meddelandet till mig.',
+'emailccsubject' => 'Kopia av ditt meddelande till $1: $2',
+'emailsent' => 'E-post har nu skickats',
+'emailsenttext' => 'Din e-post har skickats.',
+'watchlist' => 'Min övervakningslista',
+'watchlistfor' => '(för \'\'\'$1\'\'\')',
+'nowatchlist' => 'Du har inga sidor i din övervakningslista.',
+'watchlistanontext' => '$1 för att se eller redigera din övervakningslista.',
+'watchlistcount' => '\'\'\'Du har $1 poster på din övervakningslista, inklusive diskussionssidor.\'\'\'',
+'clearwatchlist' => 'Töm övervakningslistan',
+'watchlistcleartext' => 'Är du säker på att du vill ta bort dem?',
+'watchlistclearbutton' => 'Töm övervakningslista',
+'watchlistcleardone' => 'Din övervakningslista har tömts. $1 poster togs bort.',
+'watchnologin' => 'Du är inte inloggad',
+'watchnologintext' => 'Du måste vara [[Special:Userlogin|inloggad]] för att kunna göra ändringar i din övervakningslista.',
+'addedwatch' => 'Tillagd på övervakningslistan',
+'addedwatchtext' => 'Sidan "[[:$1|$1]]" har satts upp på din [[Special:Watchlist|övervakningslista]].
+Framtida ändringar av den här sidan och dess diskussionssida kommer att listas där, och sidan kommer att markeras med \'\'\'fet stil\'\'\' i [[Special:Recentchanges|listan över de senaste ändringarna]] för att synas bättre.<br /><br />
+Om du inte längre vill att sidan skall finnas på din övervakningslista, klicka på "avbevaka" uppe till höger.',
+'removedwatch' => 'Borttagen från övervakningslista',
+'removedwatchtext' => 'Sidan "$1" har blivit borttagen från din övervakningslista',
+'watch' => 'bevaka',
+'watchthispage' => 'Bevaka denna sida',
+'unwatch' => 'avbevaka',
+'unwatchthispage' => 'Stoppa övervakningen av denna sida',
+'notanarticle' => 'Inte en artikel',
+'watchnochange' => 'Inga av dina övervakade sidor har ändrats inom den visade tidsperioden.',
+'watchdetails' => '$1 sidor övervakade (utöver diskussionssidor). [[Special:Watchlist/edit|Visa och redigera hela listan]].',
+'wlheader-enotif' => '* Bekräftelse per e-post är aktiverad.',
+'wlheader-showupdated' => '* Sidor som ändrats sedan ditt senaste besök visas i \'\'\'fet stil.\'\'\'',
+'watchmethod-recent' => 'letar efter övervakade sidor bland nyligen gjorda ändringar',
+'watchmethod-list' => 'letar i övervakningslistan efter nyligen gjorda ändringar',
+'removechecked' => 'Ta bort markerade sidor från övervakningslistan',
+'watchlistcontains' => 'Din övervakningslista innehåller $1 sidor.',
+'watcheditlist' => 'Här är hela din övervakningslista, i alfabetisk ordning. Kryssa i rutan vid de sidor du vill ta bort från din övervakningslista, och klicka på knappen \'Ta bort\' längst ner på sidan.',
+'removingchecked' => 'Tar bort markerade sidor från övervakningslistan...',
+'couldntremove' => 'Kunde inte ta bort artikeln \'$1\'...',
+'iteminvalidname' => 'Problem med sidan \'$1\', ogiltigt namn...',
+'wlnote' => 'Nedan finns de senaste $1 ändringarna under de senaste <b>$2</b> timmarna.',
+'wlshowlast' => 'Visa senaste $1 timmarna $2 dagarna $3',
+'wlsaved' => 'Detta är en sparad version av din övervakningslista.',
+'wlhideshowown' => '$1 mina redigeringar',
+'wlhideshowbots' => '$1 robotredigeringar',
+'wldone' => 'Klar.',
+'enotif_mailer' => '{{SITENAME}}s system för att få meddelanden om förändringar per e-post',
+'enotif_reset' => 'Markera alla sidor som besökta',
+'enotif_newpagetext' => 'Detta är en ny sida.',
+'changed' => 'ändrad',
+'created' => 'skapad',
+'enotif_subject' => '{{SITENAME}}-sidan $PAGETITLE har blivit $CHANGEDORCREATED av $PAGEEDITOR',
+'enotif_lastvisited' => 'På $1 återfinner du alla ändringar sedan ditt senaste besök.',
+'enotif_body' => '$WATCHINGUSERNAME,
+
+{{SITENAME}}-sidan $PAGETITLE har blivit $CHANGEDORCREATED $PAGEEDITDATE av $PAGEEDITOR; den nuvarande versionen hittar du på $PAGETITLE_URL.
+
+$NEWPAGE
+
+Angiven sammanfattning av redigeringen: $PAGESUMMARY $PAGEMINOREDIT
+
+Kontakta användaren:
+e-post: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Såvida du inte besöker sidan, kommer du inte att få flera meddelanden om ändringar av sidan. Du kan också ta bort flaggan för meddelanden om ändringar på alla sidor i din övervakningslista.
+
+Hälsningar från {{SITENAME}}s meddelandesystem
+
+--
+För att ändra inställningarna i din övervakningslista, besök
+{{fullurl:Special:Watchlist/edit}}
+
+Feedback och hjälp:
+{{fullurl:Help:Innehåll}}',
+'deletepage' => 'Ta bort sida',
+'confirm' => 'Bekräfta',
+'excontent' => 'Före radering: \'$1\'',
+'excontentauthor' => 'sidan innehöll \'$1\' (den enda som skrivit var \'$2\')',
+'exbeforeblank' => 'Före tömning: \'$1\'',
+'exblank' => 'sidan var tom',
+'confirmdelete' => 'Bekräfta borttagning',
+'deletesub' => '(Tar bort "$1")',
+'historywarning' => 'Varning: Sidan du håller på att radera har en historik:',
+'confirmdeletetext' => 'Du håller på att permanent ta bort en sida,
+eller bild med all dess historik, från databasen.
+Bekräfta att du förstår vad du håller på med och vilka konsekvenser
+detta leder till, och att det följer {{SITENAME}}s allmänna riktlinjer.',
+'actioncomplete' => 'Genomfört',
+'deletedtext' => '"$1" har blivit borttagen. Artikelns historia finns kvar i [[Special:Undelete/$1]]. Se loggen över de senaste raderingarna, $2',
+'deletedarticle' => 'raderade "$1"',
+'dellogpage' => 'Raderingar',
+'dellogpagetext' => 'Nedan listas de senaste raderingarna och återställningarna.',
+'deletionlog' => 'raderingslogg',
+'reverted' => 'Återgått till tidigare version',
+'deletecomment' => 'Anledning till borttagning',
+'imagereverted' => 'Återställningen av nyare artikelversion lyckades',
+'rollback' => 'Rulla tillbaka ändringar',
+'rollback_short' => 'Återställning',
+'rollbacklink' => 'rulla tillbaka',
+'rollbackfailed' => 'Tillbakarullning misslyckades',
+'cantrollback' => 'Det gick inte att rulla tillbaka, då artikeln redigerats av en enda användare och äldre versioner saknas.',
+'alreadyrolled' => 'Det gick inte att rulla tillbaka den sista redigeringen av [[User:$2|$2]] ([[User talk:$2|diskussion]]) på sidan [[:$1|$1]]. Någon annan har redan rullat tillbaka, eller redigerat sidan. Sidan ändrades senast av [[User:$3|$3]] ([[User talk:$3|diskussion]]).',
+'editcomment' => 'Redigeringskommentaren var: "<i>$1</i>".',
+'revertpage' => 'Återställt redigeringar av [[Special:Contributions/$2|$2]] ([[User talk:$2|användardiskussion]]); återställd till senaste version av [[User:$1|$1]]',
+'sessionfailure' => 'Något med din session som inloggad är på tok. Din begärda åtgärd har avbrutits, för att förhindra att någon kapar din session. Klicka på "Tillbaka" i din webbläsare och ladda om den sida du kom ifrån. Försök sedan igen.',
+'protectlogpage' => 'Skrivskydd',
+'protectlogtext' => 'Detta är en lista över applicerande och borttagande av skrivskydd.',
+'protectedarticle' => 'skyddade [[$1]]',
+'unprotectedarticle' => 'tog bort skydd av $1',
+'protectsub' => '(Skyddar "$1")',
+'confirmprotecttext' => 'Genom att skrivskydda en sida låser du den så att den inte kan redigeras av besökare. I grunden strider detta mot tanken bakom {{SITENAME}} och ska därför användas restriktivt.
+
+Vill du skrivskydda denna sida?',
+'confirmprotect' => 'Bekräfta skrivskydd av sida',
+'protectmoveonly' => 'Enbart skydd mot flyttning av sida',
+'protectcomment' => 'Anledning till skydd av sidan',
+'unprotectsub' => '(Tog bort skydd av "$1")',
+'confirmunprotecttext' => 'Vill du låsa upp den här sidan?',
+'confirmunprotect' => 'Bekräfta borttagning av skrivskydd',
+'unprotectcomment' => 'Anledning till att skrivskyddet tas bort',
+'protect-unchain' => 'Lås upp flyttillstånd',
+'protect-text' => 'Du kan visa och ändra skyddsnivån av artikeln <strong>$1</strong>. Kontrollera att du följer riktlinjerna.',
+'protect-viewtext' => 'Ditt konto har inte tillstånd att ändra sidskyddsnivåer. Detta är nuvarande status för artikel <strong>$1</strong>:',
+'protect-default' => '(standard)',
+'protect-level-autoconfirmed'=> 'Enbart registrerade användare',
+'protect-level-sysop' => 'Enbart administratörer',
+'restriction-edit' => 'Redigering av sidan',
+'restriction-move' => 'Flytt av sidan',
+'undelete' => 'Återställ borttagna sidor',
+'undeletepage' => 'Visa och återställ borttagna sidor',
+'viewdeletedpage' => 'Visa raderade sidor',
+'undeletepagetext' => 'Följande sidor har blivit borttagna, men finns fortfarande i ett arkiv och kan återställas. Arkivet kan ibland rensas på gamla versioner.',
+'undeleteextrahelp' => '* För att återställa alla versioner, välj \'\'\'Återställ\'\'\' utan att kryssa i några rutor.
+* För att återställa bara vissa versioner, kryssa i de kryssrutor som hör till de versioner som ska återställas och välj \'\'\'Återställ\'\'\'.
+* \'\'\'Rensa\'\'\' tömmer kommentarfältet och kryssrutorna.',
+'undeletearticle' => 'Återställ borttagen artikel',
+'undeleterevisions' => '$1 versioner arkiverade',
+'undeletehistory' => 'Om du återställer sidan, kommer alla tidigare versioner att återfinnas i versionshistoriken. Om en ny sida med samma namn har skapats sedan sidan raderades, kommer den återskapade historiken automatiskt att återfinnas i den äldre historiken. Den nuvarande versionen kommer alltså inte att ersättas av de raderade och återskapade.',
+'undeletehistorynoadmin'=> 'Den här artikeln har blivit raderad. Anledningen till detta anges i sammanfattningen nedan, tillsammans med uppgifter om de användare som redigerat sidan innan den raderades. Enbart administratörerna har tillgång till den raderade texten.',
+'undeleterevision' => 'borttagen version från den $1',
+'undeleterevision-missing' => 'Versionen finns inte eller är felaktig. Versionen kan ha återställts eller tagits bort från arkivet, du kan också ha följt en felaktig länk.',
+'undeletebtn' => 'Återställ',
+'undeletereset' => 'Rensa',
+'undeletecomment' => 'Kommentar:',
+'undeletedarticle' => 'återställde "$1"',
+'undeletedrevisions' => '{{PLURAL:$1|en version återställd|$1 versioner återställda}}',
+'undeletedrevisions-files'=> '$1 {{PLURAL:$1|version|versioner}} och $2 {{PLURAL:$2|fil|filer}} återställda',
+'undeletedfiles' => '$1 {{PLURAL:$1|fil återställd|filer återställda}}',
+'cannotundelete' => 'Återställning misslyckades; kanske någon redan har återställt sidan.',
+'undeletedpage' => '<big>\'\'\'$1 har återställts\'\'\'</big>
+
+I [[Special:Log/delete|borttagningsloggen]] kan du hitta information om nyligen borttagna och återställda sidor.',
+'namespace' => 'Namnrymd:',
+'invert' => 'Uteslut vald namnrymd',
+'contributions' => 'Användarbidrag',
+'mycontris' => 'Mina bidrag',
+'contribsub' => 'För $1',
+'nocontribs' => 'Inga ändringar hittades, som motsvarar dessa kriterier',
+'ucnote' => 'Nedan visas denna användarens senaste <b>$1</b> ändringar, under de senaste <b>$2</b> dagarna.',
+'uclinks' => 'Visa de senaste $1 ändringarna. Visa de senaste $2 dagarna.',
+'uctop' => ' (senaste)',
+'newbies' => 'Nykomlingar',
+'sp-newimages-showfrom' => 'Visa nya bilder från och med $1',
+'sp-contributions-newest'=> 'Nyaste',
+'sp-contributions-oldest'=> 'Äldsta',
+'sp-contributions-newer'=> '$1 nyare',
+'sp-contributions-older'=> '$1 äldre',
+'sp-contributions-newbies-sub'=> 'För nybörjare',
+'whatlinkshere' => 'Sidor som länkar hit',
+'notargettitle' => 'Inget mål',
+'notargettext' => 'Du har inte angivit någon sida eller användare att utföra denna funktion på.',
+'linklistsub' => '(Länklista)',
+'linkshere' => 'Följande sidor länkar till [[:$1]]:',
+'nolinkshere' => 'Inga sidor länkar till [[:$1]].',
+'isredirect' => 'transportsida',
+'istemplate' => 'inkluderad som mall',
+'blockip' => 'Blockera IP-adress',
+'blockiptext' => 'Formuläret nedan används för att blockera specifika användarnamns eller IP-adressers möjlighet att redigera sidor. Detta bör göras endast för att förhindra vandalism, och enligt gällande [[Project:Policy|policy]]. Ange orsaken nedan (exempelvis genom att nämna sidor som blivit vandaliserade).',
+'ipaddress' => 'IP-adress',
+'ipadressorusername' => 'IP-adress eller användarnamn',
+'ipbexpiry' => 'Varaktighet',
+'ipbreason' => 'Anledning',
+'ipbanononly' => 'Blockera bara oinloggade användare',
+'ipbcreateaccount' => 'Förhindra registrering av användarkonton',
+'ipbenableautoblock' => 'Blockera automatiskt IP-adresser som användaren försöker redigera ifrån',
+'ipbsubmit' => 'Blockera den här IP-adressen',
+'ipbother' => 'Annan tidsperiod',
+'ipboptions' => '2 timmar:2 hours,1 dag:1 day,3 dagar:3 days,1 vecka:1 week,2 veckor:2 weeks,1 månad:1 month,3 månader:3 months,6 månader:6 months,1 år:1 year,oändlig:infinite',
+'ipbotheroption' => 'annan tidsperiod',
+'badipaddress' => 'Du har inte skrivit IP-adressen korrekt.',
+'blockipsuccesssub' => 'Blockeringen är utförd',
+'blockipsuccesstext' => 'IP-adressen "$1" har blockerats.<br /><br />
+Lämna gärna besked om detta på [[User talk:$1|användarens diskussionssida]]. För att se alla blockeringar som ligger just nu, gå till [[Special:Ipblocklist|listan över blockeringar]].<br /><br />
+En logg över blockeringar och borttagningar av blockeringar finns på [[Special:Log/Block]].',
+'unblockip' => 'Ta bort blockering av IP-adress',
+'unblockiptext' => 'Använd formuläret nedan för att ta bort blockeringen av en IP-adress.',
+'ipusubmit' => 'Ta bort blockeringen av den här adressen',
+'unblocked' => 'Blockeringen av [[User:$1|$1]] har hävts',
+'ipblocklist' => 'Lista över blockerade IP-adresser',
+'blocklistline' => '$1: $2 blockerar $3, blockeringen upphör $4',
+'infiniteblock' => 'evig',
+'expiringblock' => 'förfaller $1',
+'anononlyblock' => 'endast för oinloggade',
+'noautoblockblock' => 'utan automatisk blockering',
+'createaccountblock' => 'kontoregistrering blockerad',
+'ipblocklistempty' => 'Listan över blockerade IP-adresser är tom',
+'blocklink' => 'blockera',
+'unblocklink' => 'ta bort blockering',
+'contribslink' => 'bidrag',
+'autoblocker' => 'Automatisk blockering eftersom du har samma IP-adress som "$1". Motivering till blockeringen: "$2".',
+'blocklogpage' => 'Blockeringar',
+'blocklogentry' => 'blockerade "$1" ($2)',
+'blocklogtext' => 'Detta är en logg över blockeringar och avblockeringar. Automatiskt blockerade IP-adresser listas ej. En lista över IP-adresser och användare som för närvarande är blockerade finns på [[Special:Ipblocklist|IP-blocklistan]].',
+'unblocklogentry' => 'tog bort blockering av "$1"',
+'range_block_disabled' => 'Möjligheten för administratörer att blockera intervall av IP-adresser har stängts av.',
+'ipb_expiry_invalid' => 'Förfallotiden ogiltig',
+'ipb_already_blocked' => '"$1" är redan blockerad',
+'ip_range_invalid' => 'Ogiltigt IP-intervall.',
+'proxyblocker' => 'Proxy-block',
+'ipb_cant_unblock' => 'Fel: Hittade inte blockering $1. Det är möjligt att den redan har upphävts.',
+'proxyblockreason' => 'Din IP-adress har blivit blockerad eftersom den tillhör en öppen proxy. Kontakta din internetleverantör eller din organisations eller företags tekniska support, och informera dem om denna allvarliga säkerhetsrisk.',
+'proxyblocksuccess' => 'Gjort.',
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Din IP-adress finns med på [http://www.sorbs.net SORBS] DNSBL:s lista över öppna proxies.',
+'sorbs_create_account_reason'=> 'Din IP-adress finns med på [http://www.sorbs.net SORBS] DNSBL-lista över öppna proxyn. Du kan därför inte skapa något användarkonto.',
+'lockdb' => 'Lås databas',
+'unlockdb' => 'Lås upp databas',
+'lockdbtext' => 'En låsning av databasen hindrar alla användare från att redigera sidor, ändra inställningar och andra saker som kräver ändringar i databasen.
+Bekräfta att du verkligen vill göra detta, och att du kommer att låsa upp databasen när underhållet är utfört.',
+'unlockdbtext' => 'Om du låser upp databasen kommer alla användare att åter kunna redigera sidor, ändra sina inställningar och så vidare. Bekräfta att du vill göra detta.',
+'lockconfirm' => 'Ja, jag vill verkligen låsa databasen.',
+'unlockconfirm' => 'Ja, jag vill låsa upp databasen.',
+'lockbtn' => 'Lås databasen',
+'unlockbtn' => 'Lås upp databasen',
+'locknoconfirm' => 'Du har inte bekräftat låsningen.',
+'lockdbsuccesssub' => 'Databasen har låsts',
+'unlockdbsuccesssub' => 'Databasen har låsts upp',
+'lockdbsuccesstext' => 'Databasen är nu låst.
+<br />Kom ihåg att ta bort låsningen när du är färdig med ditt underhåll.',
+'unlockdbsuccesstext' => 'Databasen är upplåst.',
+'lockfilenotwritable' => 'Det går inte att skriva till databasens låsfil. För att låsa eller låsa upp databasen, så måste webbservern kunna skriva till den filen.',
+'databasenotlocked' => 'Databasen är inte låst.',
+'makesysoptitle' => 'Gör en användare till administratör',
+'makesysoptext' => 'Det här formuläret används av byråkrater för att göra vanliga användare till administratörer.
+Skriv användarens namn i rutan och tryck på knappen för att göra användaren till administratör',
+'makesysopname' => 'Användarens namn:',
+'makesysopsubmit' => 'Ge den här användaren administratörsrättigheter',
+'makesysopok' => '<b>Användaren "$1" är nu administratör</b>',
+'makesysopfail' => '<b>Det gick inte att ge användaren "$1" administratörsrättigheter. (Skrev du rätt namn?)</b>',
+'setbureaucratflag' => 'Gör till byråkrat',
+'rightslog' => 'Logg över användarrättigheter',
+'rightslogtext' => 'Detta är en logg över förändringar i användares rättigheter.',
+'rightslogentry' => 'grupptillhörighet för $1 ändrad från $2 till $3',
+'rights' => 'Rättigheter:',
+'set_user_rights' => 'Inställning av användarrättigheter',
+'user_rights_set' => '<b>Användaren "$1"s behörighet har uppdaterats</b>',
+'set_rights_fail' => '<b>"$1"s användarrättigheter kunde inte ställas in. (Skrev du in användarnamnet korrekt?)</b>',
+'makesysop' => 'Ge en användare administratörsrättigheter',
+'already_sysop' => 'Denna användare är redan administratör',
+'already_bureaucrat' => 'Denna användare är redan byråkrat',
+'rightsnone' => '(inga)',
+'movepage' => 'Flytta sida',
+'movepagetext' => '\'\'\'Om en diskussionssida hör till sidan,\'\'\' kommer denna automatiskt att flyttas med såvida inte * flytten spänner över flera [[Project:Namnrymd|namnrymder]], eller * en diskussionssida redan finns på den tilltänkta destinationen, eller * rutan nedan är urklickad. Ibland är det önskvärt att flytta denna diskussionssida manuellt.',
+'movepagetalktext' => 'Diskussionssidan kommer att även den automatiskt flyttas \'\'\'om inte\'\'\':
+*Det redan finns en diskussionssida som inte är tom med det nya namnet, eller
+*Du avmarkerar rutan nedan.',
+'movearticle' => 'Flytta sida',
+'movenologin' => 'Inte inloggad',
+'movenologintext' => 'För att kunna flytta en sida, måste du måste vara registrerad som användare, och [[Special:Userlogin|inloggad]].',
+'newtitle' => 'Till det nya uppslagsordet',
+'movepagebtn' => 'Flytta sidan',
+'pagemovedsub' => 'Flyttningen lyckades',
+'pagemovedtext' => 'Sidan "[[$1]]" flyttad till "[[$2]]".
+
+[[{{ns:Special}}:Whatlinkshere/$2|Kontrollera]] gärna att flytten inte orsakat några dubbla omdirigeringar.',
+'articleexists' => 'Antingen existerar redan en sida med det namnet, eller så har du valt ett namn som inte är tillåtet.
+Välj något annat namn istället.',
+'talkexists' => 'Sidan flyttades, men eftersom en annan diskussionssida redan fanns på destinationen kunde diskussionssidan inte flyttas med. Försök att manuellt sammanfoga de bägge diskusionssidornas innehåll till en sida.',
+'movedto' => 'flyttad till',
+'movetalk' => 'Flytta även diskussionssidan ifall det går.',
+'talkpagemoved' => 'Den diskussionssida som hör till flyttades också.',
+'talkpagenotmoved' => 'Den diskussionssida som hör till flyttades <strong>inte</strong>.',
+'1movedto2' => 'flyttade [[$1]] till [[$2]]',
+'1movedto2_redir' => 'flyttade [[$1]] till [[$2]], som var en omdirigeringssida',
+'movelogpage' => 'Sidflyttningar',
+'movelogpagetext' => 'Listan nedan visar sidor som flyttats.',
+'movereason' => 'Anledning',
+'revertmove' => 'flytta tillbaka',
+'delete_and_move' => 'Radera och flytta',
+'delete_and_move_text' => '==Radering krävs== Den titel du vill flytta artikeln till, "[[:$1|$1]]", finns redan. Vill du radera den för att möjliggöra flytt av denna sida dit?',
+'delete_and_move_confirm'=> 'Ja, radera sidan',
+'delete_and_move_reason'=> 'Raderad för att flytta hit en annan sida.',
+'selfmove' => 'Ursprungstitel och destinationstitel är identiska. Sidan kan inte flyttas till sig själv.',
+'immobile_namespace' => 'Det går inte att flytta artiklar till den namnrymd du angivit, då denna ej kan utökas.',
+'export' => 'Exportera sidor',
+'exporttext' => 'Du kan exportera en eller flera sidors text och versionshistorik i XML-format. Filen kan sedan importeras till en annan MediaWiki-wiki m h a sidan Special:Import (importera).
+
+För att exportera sidor skriv in artikeluppslagen i rutan nedan, en sida per rad. Välj om du vill exportera den nuvarande versionen tillsammans med alla de gamla, med sidans historik, eller bara den nuvarande versionen med information om den sista redigeringen.
+
+I det sistnämnda fallet kan du även använda en länk, exempel [[Special:Export/{{Mediawiki:Mainpage}}]] för sidan {{Mediawiki:Mainpage}}.',
+'exportcuronly' => 'Inkludera endast den nuvarande versionen, inte hela historien',
+'exportnohistory' => '---- \'\'\'OBS:\'\'\' export av fullständig artikelhistorik med hjälp av detta formulär har stängts av på grund av prestandaskäl.',
+'export-submit' => 'Exportera',
+'allmessages' => 'Systemmeddelanden',
+'allmessagesname' => 'Namn',
+'allmessagesdefault' => 'Standardtext',
+'allmessagescurrent' => 'Nuvarande text',
+'allmessagestext' => 'Detta är en lista över alla meddelanden i namnrymden MediaWiki',
+'allmessagesnotsupportedUI'=> 'Språket <b>$1</b>, som du valt för gränssnittet, stöds inte av \'\'Special:Allmessages\'\' på denna webbplats.',
+'allmessagesnotsupportedDB'=> 'Det finns inte stöd för \'\'Special:Allmessages\'\', eftersom \'\'\'$wgUseDatabaseMessages\'\'\' är avstängd.',
+'allmessagesfilter' => 'Filter för meddelandenamn:',
+'allmessagesmodified' => 'Visa bara ändrade',
+'thumbnail-more' => 'Förstora',
+'missingimage' => '<b>Bild saknas</b><br /><i>$1</i>',
+'filemissing' => 'Fil saknas',
+'thumbnail_error' => 'Ett fel uppstod när minibilden skulle skapas: $1',
+'import' => 'Importera sidor',
+'importinterwiki' => 'Transwiki-import',
+'import-interwiki-text' => 'Välj en wiki och sidtitel att importera.
+Versionshistorik (datum och redaktörer) kommer att bevaras.
+All överföring mellan wikier (transwiki) listas i [[Special:Log/import|importloggen]].',
+'import-interwiki-history'=> 'Kopiera hela versionshistoriken för denna artikel',
+'import-interwiki-submit'=> 'Importera',
+'import-interwiki-namespace'=> 'Överför sidorna till namnrymden:',
+'importtext' => 'Exportera filen från ursprungs-wikin genom Special:Export, spara den till din hårddisk och ladda upp den här.',
+'importstart' => 'Importerar sidor....',
+'import-revision-count' => '$1 {{plural:$1|version|versioner}}',
+'importnopages' => 'Det finns inga sidor att importera.',
+'importfailed' => 'Importen misslyckades: $1',
+'importunknownsource' => 'Okänd typ av importkälla',
+'importcantopen' => 'Misslyckades med att öppna importfilen.',
+'importbadinterwiki' => 'Felaktig interwiki-länk',
+'importnotext' => 'Tom eller ingen text',
+'importsuccess' => 'Importen lyckades!',
+'importhistoryconflict' => 'Det föreligger en konflikt i versionshistoriken (kanske har denna sida importerats tidigare)',
+'importnosources' => 'Inga källor för transwiki-import har angivits, och direkt uppladdning av historik har stängts av.',
+'importnofile' => 'Ingen fil att importera har laddats upp.',
+'importuploaderror' => 'Importfilen kunde inte laddas upp; kanske är den större än vad filer som skall laddas upp får vara.',
+'importlogpage' => 'Importlogg',
+'importlogpagetext' => 'Administrativa sidimporter med versionshistorik från andra wikier.',
+'import-logentry-upload'=> '[[$1]] har importerats genom uppladdning av fil',
+'import-logentry-upload-detail'=> '$1 {{plural:$1|version|versioner}}',
+'import-logentry-interwiki'=> 'överförde $1 mellan wikier',
+'import-logentry-interwiki-detail'=> '$1 {{plural:$1|version|versioner}} från $2',
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions'=> 'v',
+'accesskey-watch' => 'w',
+'tooltip-search' => 'Sök i den här wikin [alt-f]',
+'tooltip-minoredit' => 'Markera som mindre ändring [alt-i]',
+'tooltip-save' => 'Spara dina ändringar [alt-s]',
+'tooltip-preview' => 'Det är bra om du förhandsgranskar dina ändringar innan du sparar! [alt-p]',
+'tooltip-diff' => 'Visa vilka förändringar du har gjort av texten. [alt-v]',
+'tooltip-compareselectedversions'=> 'Visa skillnaden mellan de två markerade versionerna av den här sidan. [alt-v]',
+'tooltip-watch' => 'Lägg till den här sidan i din bevakningslista [alt-w]',
+'common.css' => '/** CSS som skrivs här nedan påverkar alla skal **/',
+'monobook.css' => '/*CSS som skrivs in här kommer att påverka alla användare av skalet Monobook */',
+'nodublincore' => 'Dublin Core RDF metadata avstängt på den här servern.',
+'nocreativecommons' => 'Creative Commons RDF metadata avstängd på denna server.',
+'notacceptable' => 'Den här wiki-servern kan inte erbjuda data i ett format som din klient kan läsa.',
+'anonymous' => 'Anonym användare av {{SITENAME}}',
+'siteuser' => '{{SITENAME}} användare $1',
+'lastmodifiedatby' => 'Den här sidan ändrades senast $2, $1 av $3.',
+'and' => 'och',
+'othercontribs' => 'Baserad på arbete av $1.',
+'others' => 'andra',
+'siteusers' => '{{SITENAME}} användare $1',
+'creditspage' => 'Användare som bidragit till sidan',
+'nocredits' => 'Det finns ingen information tillgänglig om vem som bidragit till denna sida.',
+'spamprotectiontitle' => 'Spamfilter',
+'spamprotectiontext' => 'Sidan du ville spara blockerades av spamfiltret. Detta orsakades troligen av en extern länk på sidan.',
+'spamprotectionmatch' => 'Följande text aktiverade vårt spamfilter: $1',
+'subcategorycount' => 'Det finns {{PLURAL:$1|en underkategori|$1 underkategorier}} till den här kategorin.',
+'categoryarticlecount' => 'Det finns {{PLURAL:$1|en artikel|$1 artiklar}} i den här kategorin.',
+'category-media-count' => 'Det finns {{PLURAL:$1|en fil|$1 filer}} i den här kategorin.',
+'listingcontinuesabbrev'=> ' forts.',
+'spambot_username' => 'MediaWikis spampatrull',
+'spam_reverting' => 'Återställer till den senaste versionen som inte innehåller länkar till $1',
+'spam_blanking' => 'Alla versioner innehöll en länk till $1, blankar',
+'infosubtitle' => 'Information om sida',
+'numedits' => 'Antal redigeringar (artikel): $1',
+'numtalkedits' => 'Antal redigeringar (diskussionssida): $1',
+'numwatchers' => 'Antal användare som bevakar sidan: $1',
+'numauthors' => 'Antal olika bidragsgivare (artikel): $1',
+'numtalkauthors' => 'Antal olika bidragsgivare (diskussionssida): $1',
+'mw_math_png' => 'Rendera alltid PNG',
+'mw_math_simple' => 'HTML om mycket enkel, annars PNG',
+'mw_math_html' => 'HTML om möjligt, annars PNG',
+'mw_math_source' => 'Låt vara TeX (för textbaserade webbläsare)',
+'mw_math_modern' => 'Har du modern webbläsare, använd detta alternativ',
+'mw_math_mathml' => 'MathML om möjligt (experimentellt)',
+'markaspatrolleddiff' => 'Märk upp som patrullerad',
+'markaspatrolledtext' => 'Märk den här artikeln som patrullerad',
+'markedaspatrolled' => 'Markerad som patrullerad',
+'markedaspatrolledtext' => 'Den valda versionen har märkts som patrullerad.',
+'rcpatroldisabled' => 'Patrullering av Senaste ändringar är avstängd.',
+'rcpatroldisabledtext' => 'Funktionen "patrullering av Senaste ändringar" är tillfälligt avstängd.',
+'markedaspatrollederror'=> 'Kan inte markera som patrullerad',
+'markedaspatrollederrortext'=> 'Du måste ange version för att kunna markera som patrullerad.',
+'markedaspatrollederror-noautopatrol' => 'Du har inte tillåtelse att markera dina egna redigeringar som patrullerade.',
+'monobook.js' => '/* redigera denna fil för att anpassa javascript för hela webbplatsen */
+
+/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Min användarsida\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Användarsida för ip-numret du redigerar från\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Min diskussionssida\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Diskussion om redigeringar från det här ip-numret\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Mina inställningar\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'Lista över sidor som övervakas\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Lista över mina bidrag\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Du får gärna logga in, men det är inte nödvändigt\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Du får gärna logga in, men det är inte nödvändigt\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Logga ut\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Diskussion om sidans innehåll\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Du kan redigera den här sidan. Var vänlig och förhandsgranska innan du sparar.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Lägg till en kommentar i den här diskussionen\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Den här sidan är skrivskyddad. Du kan se källtexten.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Tidigare versioner av sidan\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Skydda den här sidan\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Radera den här sidan\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Återställ alla redigeringar som gjorts innan sidan raderades\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Flytta den här sidan\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Du har inte behörighet att flytta sidan\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Lägg till sidan på din övervakningslista\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Ta bort sidan från din övervakningslista\');
+ ta[\'search\'] = new Array(\'f\',\'Sök på {{SITENAME}}\');
+ ta[\'p-logo\'] = new Array(\'\',\'Huvudsida\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Gå till huvudsidan\');
+ ta[\'n-portal\'] = new Array(\'\',\'Om {{SITENAME}}, vad som kan göras, var man kan hitta olika funktioner\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Information om aktuella händelser\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Lista över de senaste ändringarna på {{SITENAME}}\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Gå till en slumpmässigt vald artikel\');
+ ta[\'n-help\'] = new Array(\'\',\'Hjälp och information om {{SITENAME}}\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Stöd {{SITENAME}}\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lista över alla sidor på {{SITENAME}} som länkar hit\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Visa senaste ändringarna av sidor som den här sidan länkar till\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS-matning för den här sidan\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom-matning för den här sidan\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Visa lista över bidrag från den här användaren\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Skicka e-post till den här användaren\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Ladda upp bilder eller mediafiler\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lista över alla speciella sidor\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Visa sidan\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Visa användarsidan\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Visa mediesidan\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Detta är en specialsida och kan inte redigeras\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Visa projektsidan\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Se bildsidan\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Se systemmeddelandet\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Se mallen\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Se hjälpsidan\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Se kategorisidan\');',
+'common.js' => '/* JavaScript som skrivs här körs varje gång en användare laddar en sida. */',
+'deletedrevision' => 'Raderade gammal sidversion $1.',
+'previousdiff' => '← Gå till föregående ändring',
+'nextdiff' => 'Gå till nästa ändring →',
+'imagemaxsize' => 'Begränsa bilders storlek på bildbeskrivningssidor till:',
+'thumbsize' => 'Storlek på minibild:',
+'showbigimage' => 'Ladda ner högupplöst version ($1x$2, $3 KB)',
+'newimages' => 'Galleri över nya bilder',
+'showhidebots' => '($1 robotar)',
+'noimages' => 'Ingenting att se.',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr-jc' => 'sr-jc',
+'variantname-sr-jl' => 'sr-jl',
+'variantname-sr' => 'sr',
+'specialloguserlabel' => 'Användare:',
+'speciallogtitlelabel' => 'Titel:',
+'passwordtooshort' => 'Ditt lösenord är för kort. Det måste innehålla minst $1 tecken.',
+'mediawarning' => '\'\'\'Varning:\'\'\': Denna fil kan innehålla programkod som, om den körs, kan skada din dator.',
+'fileinfo' => '$1KB, MIME-typ: <code>$2</code>',
+'metadata' => 'Metadata',
+'metadata-help' => 'Det här filen innehåller extrainformation som troligen lades till när bilden togs av en digitalkamera eller när det digitaliserades av en scanner. Om filen har modifierats kan det hända att vissa detaljer inte överensstämmer med den modifierade bilden.',
+'metadata-expand' => 'Visa utökade detaljer',
+'metadata-collapse' => 'Dölj utökade detaljer',
+'metadata-fields' => 'EXIF-fält som listas i det här meddelandet visas på
+bildsidan när metadatatabellen är minimerad. Övriga fält
+är gömda som standard, men visas när tabellen expanderas.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+'exif-imagewidth' => 'Bredd',
+'exif-imagelength' => 'Höjd',
+'exif-bitspersample' => 'Bitar per komponent',
+'exif-compression' => 'Komprimeringsalgoritm',
+'exif-photometricinterpretation'=> 'Pixelsammansättning',
+'exif-orientation' => 'Position',
+'exif-samplesperpixel' => 'Antal komponenter',
+'exif-xresolution' => 'Upplösning i horisontalplan',
+'exif-yresolution' => 'Upplösning i vertikalplan',
+'exif-jpeginterchangeformatlength'=> 'Antal bytes JPEG-data',
+'exif-transferfunction' => 'Överföringsfunktion',
+'exif-whitepoint' => 'VItpunktens renhet',
+'exif-primarychromaticities'=> 'Primärfärgernas renhet',
+'exif-datetime' => 'Ändringstidpunkt',
+'exif-imagedescription' => 'Bildtitel',
+'exif-make' => 'Kameratillverkare',
+'exif-model' => 'Kameramodell',
+'exif-software' => 'Använd mjukvara',
+'exif-artist' => 'Skapare',
+'exif-copyright' => 'Den som äger upphovsrätten',
+'exif-exifversion' => 'Exif-version',
+'exif-flashpixversion' => 'Flashpix-version som stöds',
+'exif-colorspace' => 'Färgrymd',
+'exif-componentsconfiguration'=> 'Komponentanalys',
+'exif-compressedbitsperpixel'=> 'Bildkomprimeringsläge',
+'exif-pixelydimension' => 'Giltig bildbredd',
+'exif-pixelxdimension' => 'Giltig bildhöjd',
+'exif-makernote' => 'Tillverkarkommentarer',
+'exif-usercomment' => 'Kommentarer',
+'exif-relatedsoundfile' => 'Relaterad ljudfil',
+'exif-datetimeoriginal' => 'Exponeringstidpunkt',
+'exif-datetimedigitized'=> 'Tidpunkt för digitalisering',
+'exif-exposuretime' => 'Exponeringstid',
+'exif-exposuretime-format'=> '$1 sek ($2)',
+'exif-fnumber' => 'F-nummer',
+'exif-fnumber-format' => 'f/$1',
+'exif-exposureprogram' => 'Exponeringsprogram',
+'exif-shutterspeedvalue'=> 'Slutarhastighet',
+'exif-aperturevalue' => 'Bländare',
+'exif-brightnessvalue' => 'Ljusstyrka',
+'exif-exposurebiasvalue'=> 'Exponeringsbias',
+'exif-subjectdistance' => 'Avstånd till motivet',
+'exif-lightsource' => 'Ljuskälla',
+'exif-flash' => 'Blixt',
+'exif-focallength' => 'Linsens brännvidd',
+'exif-focallength-format'=> '$1 mm',
+'exif-flashenergy' => 'Blixteffekt',
+'exif-focalplanexresolution'=> 'Upplösning i fokalplan x',
+'exif-focalplaneyresolution'=> 'Upplösning i fokalplan y',
+'exif-focalplaneresolutionunit'=> 'Enhet för upplösning i fokalplan',
+'exif-subjectlocation' => 'Motivets läge',
+'exif-exposureindex' => 'Exponeringsindex',
+'exif-sensingmethod' => 'Avkänning',
+'exif-filesource' => 'Filkälla',
+'exif-cfapattern' => 'CFA-mönster',
+'exif-customrendered' => 'Anpassad bildbehandling',
+'exif-exposuremode' => 'Exponeringsläge',
+'exif-whitebalance' => 'Vitbalans',
+'exif-digitalzoomratio' => 'Digitalt zoomomfång',
+'exif-focallengthin35mmfilm'=> 'Brännvidd på 35 mm film',
+'exif-scenecapturetype' => 'Motivprogram',
+'exif-gaincontrol' => 'Bildförstärkning',
+'exif-contrast' => 'Kontrast',
+'exif-saturation' => 'Mättnad',
+'exif-sharpness' => 'Skärpa',
+'exif-devicesettingdescription'=> 'Beskrivning av apparatens inställning',
+'exif-imageuniqueid' => 'Unikt bild-ID',
+'exif-gpslatituderef' => 'Nordlig eller sydlig latitud',
+'exif-gpslatitude' => 'Latitud',
+'exif-gpslongituderef' => 'Östlig eller västlig longitud',
+'exif-gpslongitude' => 'Longitud',
+'exif-gpsaltituderef' => 'Referenshöjd',
+'exif-gpsaltitude' => 'Höjd',
+'exif-gpstimestamp' => 'GPS-tid (atomur)',
+'exif-gpsstatus' => 'Mottagarstatus',
+'exif-gpsmeasuremode' => 'Mätmetod',
+'exif-gpsdop' => 'Mätnoggrannhet',
+'exif-gpsspeedref' => 'Hastighetsenhet',
+'exif-gpsspeed' => 'GPS-mottagarens hastighet',
+'exif-gpstrackref' => 'Referenspunkt för rörelsens riktning',
+'exif-gpstrack' => 'Rörelsens riktning',
+'exif-gpsdestlatituderef'=> 'Referenspunkt för målets latitud',
+'exif-gpsdestlatitude' => 'Målets latitud',
+'exif-gpsdestlongituderef'=> 'Referenspunkt för målets longitud',
+'exif-gpsdestlongitude' => 'Målets longitud',
+'exif-gpsdestbearing' => 'Riktning mot målet',
+'exif-gpsdestdistanceref'=> 'Referenspunkt för avstånd till målet',
+'exif-gpsdestdistance' => 'Avstånd till målet',
+'exif-gpsdatestamp' => 'GPS-datum',
+'exif-compression-1' => 'Inte komprimerad',
+'exif-compression-6' => 'JPEG',
+'exif-photometricinterpretation-2'=> 'RGB',
+'exif-photometricinterpretation-6'=> 'YCbCr',
+'exif-orientation-1' => 'Normal',
+'exif-orientation-2' => 'Spegelvänd horisontellt',
+'exif-orientation-3' => 'Roterad 180°',
+'exif-orientation-4' => 'Spegelvänd vertikalt',
+'exif-orientation-5' => 'Roterad 90° moturs och spegelvänd vertikalt',
+'exif-orientation-6' => 'Roterad 90° medurs',
+'exif-orientation-7' => 'Roterad 90° medurs och spegelvänd vertikalt',
+'exif-orientation-8' => 'Roterad 90° moturs',
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h'=> 'FFFF.H',
+'exif-componentsconfiguration-0'=> 'saknas',
+'exif-componentsconfiguration-1'=> 'Y',
+'exif-componentsconfiguration-2'=> 'Cb',
+'exif-componentsconfiguration-3'=> 'Cr',
+'exif-componentsconfiguration-4'=> 'R',
+'exif-componentsconfiguration-5'=> 'G',
+'exif-componentsconfiguration-6'=> 'B',
+'exif-exposureprogram-0'=> 'Inte definierad',
+'exif-exposureprogram-1'=> 'Manuell inställning',
+'exif-exposureprogram-2'=> 'Normalprogram',
+'exif-exposureprogram-3'=> 'Prioritet för bländare',
+'exif-exposureprogram-4'=> 'Prioritet för slutare',
+'exif-exposureprogram-5'=> 'Konstnärligt program (prioriterar skärpedjup)',
+'exif-exposureprogram-6'=> 'Rörelseprogram (prioriterar kortare slutartid)',
+'exif-exposureprogram-7'=> 'Porträttläge (för närbilder med bakgrunden ofokuserad)',
+'exif-exposureprogram-8'=> 'Landskapsläge (för foton av landskap med bakgrunden i fokus)',
+'exif-subjectdistance-value'=> '$1 meter',
+'exif-meteringmode-0' => 'Okänd',
+'exif-meteringmode-1' => 'Medelvärde',
+'exif-meteringmode-2' => 'Centrumviktat medelvärde',
+'exif-meteringmode-255' => 'Annan',
+'exif-lightsource-0' => 'Okänd',
+'exif-lightsource-1' => 'Dagsljus',
+'exif-lightsource-3' => 'Glödlampa',
+'exif-lightsource-4' => 'Blixt',
+'exif-lightsource-10' => 'Molnigt',
+'exif-lightsource-11' => 'Skugga',
+'exif-lightsource-255' => 'Annan ljuskälla',
+'exif-focalplaneresolutionunit-2'=> 'tum',
+'exif-sensingmethod-1' => 'Ej angivet',
+'exif-filesource-3' => 'DSC',
+'exif-customrendered-0' => 'Normal',
+'exif-customrendered-1' => 'Anpassad',
+'exif-exposuremode-0' => 'Automatisk exponering',
+'exif-exposuremode-1' => 'Manuell exponering',
+'exif-exposuremode-2' => 'Automatisk alternativexponering',
+'exif-whitebalance-0' => 'Automatisk vitbalans',
+'exif-whitebalance-1' => 'Manuell vitbalans',
+'exif-scenecapturetype-1'=> 'Landskap',
+'exif-scenecapturetype-2'=> 'Porträtt',
+'exif-scenecapturetype-3'=> 'Nattfotografering',
+'exif-gaincontrol-0' => 'Ingen',
+'exif-gaincontrol-1' => 'Ökning av lågnivåförstärkning',
+'exif-gaincontrol-2' => 'Ökning av högnivåförstärkning',
+'exif-gaincontrol-3' => 'Sänkning av lågnivåförstärkning',
+'exif-gaincontrol-4' => 'Sänkning av högnivåförstärkning',
+'exif-contrast-0' => 'Normal',
+'exif-contrast-1' => 'Mjuk',
+'exif-contrast-2' => 'Skarp',
+'exif-saturation-0' => 'Normal',
+'exif-saturation-1' => 'Låg mättnadsgrad',
+'exif-saturation-2' => 'Hög mättnadsgrad',
+'exif-sharpness-0' => 'Normal',
+'exif-subjectdistancerange-0'=> 'Okänd',
+'exif-subjectdistancerange-2'=> 'Närbild',
+'exif-subjectdistancerange-3'=> 'Avståndsbild',
+'exif-gpslatitude-n' => 'Nordlig latitud',
+'exif-gpslatitude-s' => 'Sydlig latitud',
+'exif-gpslongitude-e' => 'Östlig longitud',
+'exif-gpslongitude-w' => 'Västlig longitud',
+'exif-gpsstatus-a' => 'Mätning pågår',
+'exif-gpsmeasuremode-2' => 'Tvådimensionell mätning',
+'exif-gpsmeasuremode-3' => 'Tredimensionell mätning',
+'exif-gpsspeed-k' => 'Kilometer i timmen',
+'exif-gpsspeed-m' => 'Miles i timmen',
+'exif-gpsspeed-n' => 'Knop',
+'exif-gpsdirection-t' => 'Sann bäring',
+'exif-gpsdirection-m' => 'Magnetisk bäring',
+'edit-externally' => 'Redigera denna fil med hjälp av extern programvara',
+'edit-externally-help' => 'Se [http://meta.wikimedia.org/wiki/Help:External_editors instruktioner] för mer information.',
+'recentchangesall' => 'alla',
+'imagelistall' => 'alla',
+'watchlistall1' => 'alla',
+'watchlistall2' => 'alla',
+'namespacesall' => 'alla',
+'confirmemail' => 'Bekräfta e-postadress',
+'confirmemail_noemail' => 'Du har inte givit någon fungerande e-postadress i dina [[Special:Preferences|inställningar]].',
+'confirmemail_text' => 'Innan du kan använda {{SITENAME}}s funktioner för e-post måste du bekräfta din e-postadress. Aktivera knappen nedan för att skicka en bekräftelsekod till din e-postadress. Mailet kommer att innehålla en länk, som innehåller en kod. Genom att klicka på den länken eller kopiera den till din webbläsares fönster för webbadresser, bekräftar du att din e-postadress fungerar.',
+'confirmemail_pending' => 'En bekräftelsekod har redan skickats till din epostadress. Om du skapade ditt konto nyligen, så kanske du vill vänta några minuter innan du begär en ny kod.',
+'confirmemail_send' => 'Skicka bekräftelsekod',
+'confirmemail_sent' => 'E-post med bekräftelse skickat.',
+'confirmemail_oncreate' => 'En bekräftelsekod skickades till din epostadress. Koden behövs inte för att logga in, men om du behöver koden om du vill få tillgång de epostbaserade funktionerna på wikin.',
+'confirmemail_sendfailed'=> 'E-post med bekräftelse kunde inte skickas. Kontrollera om adressen innehåller ogiltiga tecken.',
+'confirmemail_invalid' => 'Ogiltig bekräftelsekod. Dess giltighetstid kan ha löpt ut.',
+'confirmemail_needlogin'=> 'Du behöver $1 för att bekräfta din e-postadress',
+'confirmemail_success' => 'Din e-postadress har bekräftats och du kan logga in på wikin.',
+'confirmemail_loggedin' => 'Din e-postadress är nu bekräftad.',
+'confirmemail_error' => 'Någonting gick fel när din bekräftelse skulle sparas.',
+'confirmemail_subject' => 'Bekräftelse av e-postadress på {{SITENAME}}',
+'confirmemail_body' => 'Någon, troligen du, har från IP-adressen $1 registrerat användarkontot "$2" på {{SITENAME}} och uppgivit denna e-postadress. För att bekräfta att detta konto verkligen är ditt, och för att aktivera möjligheten att skicka e-post via kontot på {{SITENAME}}, klicka på denna länk:
+
+$3
+
+Om det \'\'\'inte\'\'\' är du som registrerat kontot, följ inte länken. Efter $4 kommer denna bekräftelsekod inte att fungera.',
+'tryexact' => 'Försök hitta exakt matchning',
+'searchfulltext' => 'Fulltextsökning',
+'createarticle' => 'Skapa artikel',
+'scarytranscludedisabled' => '[Interwiki-inklusion är inte aktiverad]',
+'scarytranscludefailed' => '[Beklagar, hämtning av mall för $1 misslyckades]',
+'scarytranscludetoolong'=> '[Beklagar, URL:en är för lång]',
+'trackbackbox' => '<div id="mw_trackbacks"> Till denna artikel finns följande trackback:<br /> $1 </div>',
+'trackbackremove' => '([$1 Ta bort])',
+'trackbacklink' => 'Trackback',
+'trackbackdeleteok' => 'Trackback har tagits bort.',
+'deletedwhileediting' => 'Varning: Denna sida har tagits bort efter att du började redigera den!',
+'confirmrecreate' => 'Användaren [[User:$1|$1]] ([[User talk:$1|diskussion]]) raderade den här artikeln efter att du påbörjade redigering av den med motiveringen: : \'\'$2\'\' Bekräfta att du verkligen vill återskapa artikeln.',
+'recreate' => 'Återskapa',
+'tooltip-recreate' => 'Återskapa sidan fast den har tagits bort',
+'unit-pixel' => 'px',
+'redirectingto' => 'Omdirigerar till [[:$1|$1]]...',
+'confirm_purge' => 'Rensa denna sidas cache?
+
+$1',
+'confirm_purge_button' => 'OK',
+'youhavenewmessagesmulti'=> 'Du har nya meddelanden på $1',
+'searchcontaining' => 'Leta efter artiklar som innehåller \'\'$1\'\'.',
+'searchnamed' => 'Leta efter artiklar som heter \'\'$1\'\'.',
+'articletitles' => 'Artiklar som börjar med \'\'$1\'\'',
+'hideresults' => 'Göm resultat',
+'displaytitle' => '(Länka till denna sida som [[:$1|$1]])',
+'loginlanguagelabel' => 'Språk: $1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; föregående sida',
+'imgmultipagenext' => 'nästa sida &rarr;',
+'imgmultigo' => 'Gå',
+'imgmultigotopre' => 'Gå till sida',
+
+# Table pager
+'ascending_abbrev' => 'stigande',
+'descending_abbrev' => 'fallande',
+'table_pager_next' => 'Nästa sida',
+'table_pager_prev' => 'Föregående sida',
+'table_pager_first' => 'Första sidan',
+'table_pager_last' => 'Sista sidan',
+'table_pager_limit' => 'Visa $1 poster per sida',
+'table_pager_limit_submit' => 'Utför',
+'table_pager_empty' => 'Inga resultat',
+
+# Auto-summaries
+'autosumm-blank' => 'Tar bort sidans innehåll',
+'autosumm-replace' => 'Ersätter sidans innehåll med \'$1\'',
+'autoredircomment' => 'Omdirigerar till [[$1]]',
+'autosumm-new' => 'Ny sida: $1',
+
+);
+
+?>
diff --git a/languages/messages/MessagesTa.php b/languages/messages/MessagesTa.php
new file mode 100644
index 000000000000..f663229afffe
--- /dev/null
+++ b/languages/messages/MessagesTa.php
@@ -0,0 +1,731 @@
+<?php
+/**
+ * Tamil (தமிழ்)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+
+$quickbarSettings = array(
+ "எதுவுமில்லை", "இடம் நிலைத்த", "வலம் நிலைத்த", "இடம் மிதப்பு"
+);
+
+$skinNames = array(
+ 'standard' => "இயல்பான",
+ 'nostalgia' => "பசுமை நினைவு (Nostalgia)",
+ 'cologneblue' => "கொலோன் (Cologne) நீலம் Blue",
+ 'smarty' => "பாடிங்டன் (Paddington)",
+ 'montparnasse' => "மொண்ட்பார்னாசே (Montparnasse)",
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'ஊடகம்',
+ NS_SPECIAL => 'சிறப்பு',
+ NS_MAIN => '',
+ NS_TALK => 'பேச்சு',
+ NS_USER => 'பயனர்',
+ NS_USER_TALK => 'பயனர்_பேச்சு',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_பேச்சு',
+ NS_IMAGE => 'படிமம்',
+ NS_IMAGE_TALK => 'படிமப்_பேச்சு',
+ NS_MEDIAWIKI => 'மீடியாவிக்கி',
+ NS_MEDIAWIKI_TALK => 'மீடியாவிக்கி_பேச்சு',
+ NS_TEMPLATE => 'வார்ப்புரு',
+ NS_TEMPLATE_TALK => 'வார்ப்புரு_பேச்சு',
+ NS_HELP => 'உதவி',
+ NS_HELP_TALK => 'உதவி_பேச்சு',
+ NS_CATEGORY => 'பகுப்பு',
+ NS_CATEGORY_TALK => 'பகுப்பு_பேச்சு',
+);
+
+$namespaceAliases = array(
+ 'விக்கிபீடியா' => NS_PROJECT,
+ 'விக்கிபீடியா_பேச்சு' => NS_PROJECT_TALK,
+ 'உருவப்_பேச்சு' => NS_IMAGE_TALK
+);
+$linkTrail = "/^([\xE0\xAE\x80-\xE0\xAF\xBF]+)(.*)$/sDu";
+
+
+$messages = array(
+
+# User Toggles
+#
+
+"tog-underline" => "இணைப்புகளுக்கு அடிக்கோடிடு",
+"tog-highlightbroken" => "முறிந்த இணைப்புகளை வடிவமை <a href=\"\" class=\"புதிது\">இதைப் போல </a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "பந்திகளை ஓரச் சீர்மைப் (Justify) படுத்து",
+"tog-hideminor" => "அண்மைய மாற்றங்களில் சிறிய தொகுப்புகளை மறை",
+"tog-usenewrc" => "மேம்படுத்தப்பட்ட அண்மைய மாற்றங்கள் (எல்லா உலாவிகளுக்குமல்ல)",
+"tog-numberheadings" => "தலைப்புகளுக்கு தானியங்கி இலக்கமிடு",
+"tog-editondblclick" => "இரட்டைச் சொடுக்கில் பக்கங்களைத் தொகு (ஜாவாஸ்கிரிப்ட்)",
+"tog-editsection"=>"இணைப்புவழி (தொகுப்பு) பிரிவுத் தொகுப்பை செயல்படுத்து",
+"tog-editsectiononrightclick"=>"வலச் சொடுக்குவழி பிரிவுத் தலைப்பு தொகுப்பதை செயல் படுத்து (ஜாவாஸ்கிரிப்ட்)",
+"tog-showtoc"=>"உள்ளடக்க அட்டவணையைக் காண்பி<br />(மூன்றுக்கு மேற்பட்ட தலைப்புகளையுடைய கட்டுரைகளுக்கு)",
+"tog-rememberpassword" => "அமர்வுகளுக்கு இடையே கடவுச்சொல்லை ஞாபகத்தில் வைத்துக்கொள்",
+"tog-editwidth" => "தொகுப்புக் கட்டம் முழு அகலத்தைக் கொண்டது",
+"tog-watchdefault" => "நீங்கள் தொகுத்த பக்கங்களை, உங்கள் கவனிப்புப் பட்டியலில்(watchlist) சேருங்கள்",
+"tog-minordefault" => "முன்னிருப்பாக (By default) அனைத்து தொகுப்புகளையும் சிறியது என குறித்துக்கொள்.",
+"tog-previewontop" => "தொகுப்புப் பெட்டிக்கு முன்பே முன்தோற்றத்தைக் காட்டுக. பின்னர் அல்ல.",
+"tog-nocache" => "பக்க இடைமாற்றை (cache) முடக்கு",
+
+
+# Dates
+#
+
+'sunday' => "ஞாயிறு",
+'monday' => "திங்கள்",
+'tuesday' => "செவ்வாய்",
+'wednesday' => "புதன்",
+'thursday' => "வியாழன்",
+'friday' => "வெள்ளி",
+'saturday' => "சனி",
+'january' => "ஜனவரி",
+'february' => "பெப்ரவரி",
+'march' => "மார்ச்",
+'april' => "ஏப்ரில்",
+'may_long' => "மே",
+'june' => "ஜூன்",
+'july' => "ஜூலை",
+'august' => "ஆகஸ்ட்",
+'september' => "செப்டெம்பர்",
+'october' => "அக்டோபர்",
+'november' => "நவம்பர்",
+'december' => "டிசம்பர்",
+'jan' => "ஜன",
+'feb' => "பெப்",
+'mar' => "மார்",
+'apr' => "ஏப்",
+'may' => "மே",
+'jun' => "ஜூன்",
+'jul' => "ஜூலை",
+'aug' => "ஆக",
+'sep' => "செப்",
+'oct' => "அக்",
+'nov' => "நவ",
+'dec' => "டிச",
+
+# Bits of text used by many pages:
+#
+"categories" => "பக்க வகைகள்",
+"pagecategories" => "பக்க வகைகள்",
+"category_header" => "பகுப்புகளிலுள்ள கட்டுரைகள் \"$1\"",
+"subcategories" => "துணை வகைகள்",
+
+"mainpage" => "முதற் பக்கம்",
+"mainpagetext" => "விக்கி மென்பொருள் வெற்றிகரமாக உள்ளிடப்பட்டது.",
+"about" => "விபரம்",
+"aboutsite" => "விக்கிபீடியா பற்றி",
+"aboutpage" => "விக்கிபீடியா:விபரம்",
+"help" => "உதவி",
+"helppage" => "விக்கிபீடியா:உதவி",
+"bugreports" => "வழு அறிக்கை",
+"bugreportspage" => "விக்கிபீடியா:வழு அறிக்கைகள்",
+"faq" => "அடிக்கடி கேட்கப்படும் கேள்விகள்",
+"faqpage" => "விக்கிபீடியா:அடிக்கடி கேட்கப்படும் கேள்விகள்",
+"edithelp" => "தொகுத்தலுக்கான உதவி",
+"edithelppage" => "விக்கிபீடியா : ஒருவர் பக்கமொன்றைத் தொகுப்பது எப்படி?",
+"cancel" => "விடு",
+"qbfind" => "தேடு",
+"qbbrowse" => "உலவு",
+"qbedit" => "தொகு",
+"qbpageoptions" => "பக்க விருப்பத் தேர்வுகள்",
+"qbpageinfo" => "பக்கத் தகவல்கள்",
+"qbmyoptions" => "எனது விருப்பத் தேர்வுகள்",
+"mypage" => "எனது பக்கம்",
+"mytalk" => "எனது பேச்சு",
+"currentevents" => "தற்போதைய நிகழ்வுகள்",
+"errorpagetitle" => "தவறு",
+"returnto" => "$1 க்குத் திரும்பு.",
+"whatlinkshere" => "இங்கு இணைக்கப்பட்டுள்ள பக்கங்கள்",
+"help" => "உதவி",
+"search" => "தேடு",
+"searchbutton" => "தேடு",
+"go" => "செல்",
+'searcharticle' => "செல்",
+"history" => "பக்க வரலாறு",
+"printableversion" => "அச்சுக்குகந்த பதிப்பு",
+"editthispage" => "இப்பக்கத்தை தொகு",
+"deletethispage" => "இப்பக்கத்தை நீக்கு",
+"protectthispage" => "இப் பக்கத்தை காப்புச் செய்",
+"unprotectthispage" => "இப் பக்கத்தை காப்பு நீக்கு",
+"newpage" => "புதிய பக்கம்",
+"talkpage" => "இப் பக்கம்பற்றிக் கலந்துரையாடு",
+"postcomment" => "கருத்துக்களை அனுப்பு",
+"articlepage" => "கட்டுரையைப் பார்",
+"userpage" => "பயனர்பக்கம் பார்",
+"projectpage" => "மீ (meta) பக்கம் பார்",
+"imagepage" => "படிமப் பக்கம் பார்",
+"viewtalkpage" => "கலந்துரையாடல்களைப் பார்",
+"otherlanguages" => "ஏனைய மொழிகள்",
+"redirectedfrom" => "($1 இலிருந்து மீள் வழிப்படுத்தப்பட்டது)",
+"lastmodifiedat" => "இப்பக்கம் கடைசியாகத் திருத்த்ப்பட்டது $2, $1.",
+"viewcount" => "இப்பக்கம் $1 முறை அணுகப்பட்டது .",
+"protectedpage" => "பாதுகாக்கப்பட்ட பக்கம்",
+"nbytes" => "$1 பைட்டுகள் (bytes)",
+"ok" => "சரி",
+"retrievedfrom" => "\"$1\" இலிருந்து மீள்விக்கப்பட்டது",
+"newmessageslink" => "புதிய செய்திகள்",
+"editsection"=>"தொகு",
+"editold"=>"தொகு",
+"toc" => "பொருளடக்கம்",
+"showtoc" => "காட்டு",
+"hidetoc" => "மறை",
+"thisisdeleted" => "$1 பார்க்கவா மீள்விக்கவா?",
+"restorelink" => "$1 நீக்கப்பட்ட தொகுப்புகள்",
+
+# Main script and global functions
+#
+"nosuchaction" => "அவ்வித செயற்பாடுகள் எதுவுமில்லை",
+"nosuchactiontext" => "யூஆர்எல்(URL) இனால் குறிப்பிடப்பட்ட செயற்பாடு விக்கிபீடியா மென்பொருளினால் அடையாளம் காணப்படவில்லை",
+"nosuchspecialpage" => "அவ்வாறான சிறப்புப் பக்கங்கள் எதுவுமில்லை",
+"nospecialpagetext" => "நீங்கள் கோரிய விசேட பக்கம் விக்கிபீடியா மென்பொருளினால் அடையாளம் காணப்படவில்லை",
+# General errors
+#
+"error" => "தவறு",
+"databaseerror" => "தரவுத்தள தவறு",
+"dberrortext" => "ஒரு தரவுத்தள வினவல் தொடரமைப்புத் தவறு ஏற்பட்டுள்ளது.
+கடைசியாக முயற்சிக்கப்பட்ட தரவுத்தள வினவல்:
+<blockquote><tt>$1</tt></blockquote>
+செயலுக்குள்(function) இருந்து \"<tt>$2</tt>\".
+MySQL returned error \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "ஒரு தரவுத்தள வினவல் தொடரமைப்புத் தவறு ஏற்பட்டுள்ளது.
+கடைசியாக முயற்சிக்கப்பட்ட தரவுத்தள வினவல்:
+\"$1\"
+செயலுக்குள்(function) இருந்து \"$2\".
+MySQL returned error \"$3: $4\".",
+"noconnect" => "மன்னிக்கவும்! இந்த விக்கி தளத்தில் தொழில் நுட்பப் பிரச்சனை ஏற்பட்டுள்ளது, தரவுத்தள வழங்கனுடன் தொடர்பு கொள்ளமுடியவில்லை.",
+"nodb" => "தரவுத்தள $1 தெரிவுசெய்ய முடியவில்லை",
+"cachederror" => "கீழே இருப்பது கோரப்பட்ட பக்கத்தினுடைய ஒரு இடைமாற்று (cached) நகலாகும், இது நிகழ்நிலைக்குச் சரியாக (up to date) இல்லாதிருக்கக் கூடும்.",
+"readonly" => "தரவுத்தளம் பூட்டப்பட்டது",
+"enterlockreason" => "பூட்டுக்கான காரணத்தைத் தருக. பூட்டு எப்பொழுது திறக்கப்படும் என்பதையும் குறிப்பிடுக.",
+"readonlytext" => "விக்கிபீடியா தரவுத்தளம் தற்போது பூட்டப்பட்டுள்ளது. வழமையான பராமரிப்புக்காகவாக இருக்கலாம். புதிய பதிவுகளோ திருத்த்ங்களோ செய்ய முடியாது. இதன் பின்னர் இயல்பு நிலைக்குக் கொண்டுவரப்படும்.
+இந்த விளக்கத்தை இதனைப் பூட்டிய நிர்வாகி வழங்கியுள்ளார்:
+<p>$1",
+"missingarticle" => "கண்டுபிடித்திருக்கவேண்டிய பக்கத்தின் எழுத்துக்களை தரவுத்தளம் கண்டுபிடிக்கவில்லை. பக்கத்தின் பெயர் \"$1\".
+
+<p>நீக்கப்பட்ட பக்கமொன்றுக்கு வழக்கிழந்த வேறுபாடு (diff) அல்லது வரலாறு (History) இணைப்பைப் பின்பற்றுவதன் மூலம் இது வழக்கமாக ஏற்படுகிறது.
+<p>அப்படியில்லாவிட்டால் இது ஒரு மென்பொருள் வழுவாக இருக்கக்கூடும். யூஆரெல் (URL) ஐக் குறித்துக் கொண்டு அதைத் தயவுசெய்து ஒரு நிர்வாகிக்கு அறிவிக்கவும்.",
+"internalerror" => "உள்ளகத் தவறு",
+"filecopyerror" => "கோப்பை நகல் செய்ய முடியவில்லை\"$1\" to \"$2\".",
+"filerenameerror" => "கோப்பை பெயர்மாற்ற முடியவில்லை\"$1\" to \"$2\".",
+"filedeleteerror" => "கோப்பை நீக்க முடியவில்லை\"$1\".",
+"filenotfound" => "கோப்பைக் கண்டுபிடிக்க முடியவில்லை\"$1\".",
+"unexpected" => "எதிர்பாராத பெறுமானம்: \"$1\"=\"$2\".",
+"formerror" => "தவறு: படிவத்தை சமர்ப்பிக்க முடியவில்லை",
+"badarticleerror" => "இச் செயற்பாட்டை இப்பக்கத்தில் செயற்படுத்த முடியாது.",
+"cannotdelete" => "குறிக்கப்பட்ட பக்கத்தையோ படிமத்தையோ நீக்க முடியாது. (வேறு யாராலோ ஏற்கெனவே நீக்கப்பட்டிருக்கலாம்.)",
+"badtitle" => "பழுதுள்ள தலைப்பு",
+"badtitletext" => "கோரப்பட்ட பக்கத்தின் தலைப்பு செல்லாது, வெறுமை, அல்லது பிழையாக இணைக்கப்பட்ட மொழிகளிடை அல்லது விக்கியிடைத் தலைப்பாகும்.",
+"perfdisabled" => "மன்னிக்கவும்! இந்த வசதி தற்காலிகமாக செயலற்றதாக்கப்பட்டுள்ளது. ஏனெனில் இது விக்கியை ஒருவரும் பயன்படுத்த முடியாத அளவுக்கு வேகத்தைக் குறைத்துள்ளது.",
+"perfdisabledsub" => "இதோ $1: இலிருந்து ஒரு சேமிக்கப்பட்ட ஒரு நகல்",
+"wrong_wfQuery_params" => "பிழையான அளபுருக்கள்(parameters) wfQuery()<br />
+செயல் (Function): $1<br />
+வினவல் (Query): $2",
+"viewsource" => "மூலத்தைப் பார்",
+"protectedtext" => "தொகுப்பதைத் தடுப்பதற்காக இப் பக்கம் பூட்டப்பட்டுள்ளது. இதற்குப் பல காரணங்கள் உண்டு. தயவுசெய்து
+[[{{ns:project}}:Protected page]] ஐப் பார்க்கவும்.
+
+நீங்கள் இப் பக்கத்தைப் பார்க்கவும், நகல் எடுக்கவும் முடியும்:",
+
+# Login and logout pages
+#
+"logouttitle" => "பயனர் விடுபதிகை",
+"logouttext" => "நீங்கள் இப்பொழுது விடுபதிகையில் உள்ளீர்கள்.
+நீங்கள் தொடர்ந்தும் விக்கிபீடியாவை அடையாளமின்றி உபயோகிக்கலாம், அல்லது அதே பயனராகவோ வேறு பயனராகவோ மீண்டும் புகுபதிகை செய்யலாம். உங்கள் உலவியின் இடைமாற்று (browser cache) அழிக்கப்படும்வரை சில பக்கங்கள் தொடர்ந்தும் புகுபதிகையில் உள்ளது போன்றே காட்சி தரும் என்பதைக் கவனிக்கவும்",
+
+"welcomecreation" => "<h2>வருக, $1!</h2><p>உங்கள் கணக்கு உருவாக்கப்பட்டுள்ளது.
+உங்கள் விக்கிபீடியா விருப்புகளை சொந்தமயப் (personalize) படுத்த மறவாதீர்கள்.",
+"loginpagetitle" => "பயனர் புகுபதிகை",
+"yourname" => "உங்கள் பயனர்பெயர்",
+"yourpassword" => "உங்கள் கடவுச்சொல்",
+"yourpasswordagain" => "கடவுச்சொல்லைத் திரும்ப எழுதவும்",
+"remembermypassword" => "எனது கடவுச்சொல்லை அமர்வுகளிடையே (across sessions) ஞாபகத்தில் வைத்திருக்கவும்.",
+"loginproblem" => "உங்கள் புகுபதிகை தொடர்பில் பிரச்சினை உண்டு.
+திரும்ப முயலவும்!",
+"alreadyloggedin" => "பயனர் $1, நீங்கள் ஏற்கெனவே புகு பதிகையில் உள்ளீர்கள்!",
+"login" => "புகுபதிகை",
+"userlogin" => "புகுபதிகை",
+"logout" => "விடுபதிகை",
+"userlogout" => "விடுபதிகை",
+"notloggedin" => "புகுபதிகையில் இல்லை",
+"createaccount" => "புதிய கணக்கு உருவாக்கு",
+"createaccountmail" => "மின்னஞ்சல் மூலம்",
+"badretype" => "நீங்கள் பதிந்த கடவுச்சொல் பொருத்தமாக இல்லை.",
+"userexists" => "நீங்கள் பதிந்த கடவுச் சொல் ஏற்கெனவே உபயோகத்தில் உள்ளது. தயவுசெய்து வேறு பெயர் தெரியவும்.",
+"youremail" => "உங்கள் மின்னஞ்சல்*",
+"yournick" => "உங்கள் அழைக்கும் பெயர் (கையொப்பத்துக்காக)",
+"loginerror" => "புகுபதிகைத் தவறு", "noname" => "நீங்கள் கொடுத்த பயனர் பெயர் செல்லுபடி இல்லை.",
+"loginsuccesstitle" => "புகுபதிகை வெற்றி",
+"loginsuccess" => "நீங்கள் இப்பொழுது \"$1\" ஆக விக்கிபீடியாவில் புகுபதிகை செய்துள்ளீர்கள்.",
+"nosuchuser" => "\"$1\" பெயரில் பயனர் எவருமில்லை. எழுத்துப் பிழைகளைச் சரி பார்க்கவும், அல்லது பின்வரும் படிவத்தை உபயோகித்து புதிய பயனர் கணக்கொன்றை உருவாக்கவும்.",
+"wrongpassword" => "நீங்கள் கொடுத்த கடவுச் சொல் சரியல்ல. மீண்டும் முயற்சிக்கவும்.",
+"mailmypassword" => "புதிய கடவுச் சொல்லொன்றை அஞ்சல் செய்யவும்",
+"passwordremindertitle" => "விக்கிபீடியாவிலிருந்து கடவுச் சொல் நினைவூட்டல்",
+"passwordremindertext" => "யாரோ ஒருவர் (நீங்களாக இருக்கலாம், IP முகவரி $1 இலிருந்து) புதிய விக்கிபீடியா புகுபதிகை கடவுச்சொல் ஒன்று அனுப்பும்படி கோரியுள்ளார். பயனர் \"$2\" க்கான கடவுச்சொல் இப்பொழுது \"$3\". நீங்கள் புகுபதிகை செய்து கடவுச்சொல்லை மாற்றிக்கொள்ளவும்.", "noemail" => "பயனை \"$1\" க்கு மின்னஞ்சல் முகவரி எதுவும் பதியப்பட்டிருக்கவில்லை.",
+"passwordsent" => "\"$1\" பெயரில் பதியப்பட்டுள்ள மின்னஞ்சல் முகவரிக்கு ஒரு புதிய கடவுச்சொல் அனுப்பப்பட்டுள்ளது. பெற்றுக்கொண்டதும் தயவுசெய்து மீண்டும் புகுபதிகை செய்யவும்.",
+# Edit pages
+"summary" => "சுருக்கம்",
+"subject" => "உட்பொருள்/தலைப்புகள்",
+"minoredit" => "இது ஒரு சிறு (minor) தொகுப்பு",
+"watchthis" => "இக் கட்டுரையைக் கவனிக்கவும் (watch)",
+"savearticle" => "பக்கத்தை சேமிக்கவும்",
+"preview" => "முன்தோற்றம்",
+"showpreview" => "முன்தோற்றம் காட்டு",
+"blockedtitle" => "பயனர் தடுக்கப்பட்டுள்ளார்",
+"blockedtext" => "உங்கள் பயனர் பெயர் அல்லது IP முகவரி $1 ஆல் தடுக்கப்பட்டுள்ளது. கொடுக்கப்பட்ட காரணம்: $2
+இது பற்றிப் பேசுவதற்கு $1 ஐயோ அல்லது [[{{ns:project}}:Administrators|நிர்வாகிகளில்]] ஒருவரையோ நீங்கள் தொடர்புகொள்ளலாம்.
+பயனர் விருப்பத் தேர்வுகளில்</wiki/Special:Preferences> உங்களுடைய செல்லுபடியாகக்கூடிய மின்னஞ்சல் முகவரி பதியப்பட்டிராவிட்டால் \"email this user\" வசதியை நீங்கள் உபயோகிக்க முடியாது என்பதைக் கவனிக்கவும்.
+உங்கள் IP முகவரி $3. தயவுசெய்து இந்த ஐபி முகவரியை விசாரிப்புகளைச் செய்யும்போது குறிப்பிடவும்.
+
+Note to AOL users
+
+குறிப்பிட்ட ஏஓஎல் (AOL) பயனர் ஒருவருடைய தொடர்ந்த விஷமச் செயல்கள் காரணமாக விக்கிபீடியா அடிக்கடி ஏஓஎல் (AOL) proxy யை தடுக்கிறது. துரதிர்ஷ்டவசமாக ஒரு proxy வழங்கனை பெருமளவு ஏஓஎல் (AOL) பயனர்கள் பயன்படுத்தக் கூடும், அதனால் அப்பாவி AOL பயனர்களும் அடிக்கடி தடுக்கப்படுகிறார்கள். இதனாலேற்படும் வசதியீனங்களுக்கு மன்னிப்புக் கோருகிறோம். இது உங்களுக்கு நிகழ்ந்திருந்தால், தயவுசெய்து ஒரு ஏஓஎல் (AOL) மின்னஞ்சல் முகவரியை உபயோகித்து, நிர்வாகியொருவருக்கு அஞ்சல் செயுங்கள். மேலே கொடுக்கப்பட்டுள்ள ஐபி முகவரியைக் குறிப்பிட மறவாதீர்கள்.",
+"whitelistedittitle" => "தொகுப்பதற்கு புகுபதிகை (login) செய்யப்படவேண்டும்.",
+"whitelistedittext" => " கட்டுரைகளைத் தொகுப்பதற்கு (edit) நீங்கள் புகுபதிகை (login) </wiki/Special:Userlogin>வேண்டும்.",
+"whitelistreadtitle" => "வாசிப்பதற்கு புகுபதிகை (login) செய்ய வேண்டும்",
+"whitelistreadtext" => " கட்டுரைகளை வாசிப்பதற்கு நீங்கள் புகுபதிகை (login) </wiki/Special:Userlogin> செய்யவேண்டும்.",
+"whitelistacctitle" => "கணக்கொன்று உருவாக்குவதற்கு நீங்கள் அனுமதிக்கப்படவில்லை.",
+"whitelistacctext" => "இந்த விக்கியில் கணக்கு ஏற்படுத்துவதற்கு, நீங்கள் log </wiki/Special:Userlogin> செய்வதுடன் உரிய அனுமதியும் பெற்றிருக்க வேண்டும்.",
+"accmailtitle" => "கடவுச்சொல் அனுப்பப்பட்டுள்ளது.",
+"accmailtext" => "'$1' உடைய கடவுச்சொல் $2 க்கு அனுப்பப்பட்டுள்ளது.",
+"newarticle" => "(புதிது)",
+"newarticletext" => "ஒரு இணைப்பினூடாக நீங்கள் வந்துள்ள இப் பக்கம் இன்னும் உருவாக்கப்படவில்லை. பக்கத்தை உருவாக்குவதற்குக் கீழேயுள்ள கட்டத்துள் தட்டச்சிடத் தொடங்குங்கள். (மேலதிக விபரங்களுக்கு உதவிப் பக்கங்களைப் பார்க்கவும்). நீங்கள் தவறுதலாக இங்கே வந்திருந்தால், உங்கள் உலாவி (browser) யின் பின்னே (back) பொத்தானைச் சொடுக்கவும்.",
+"anontalkpagetext" => "---- இது இன்னும் கணக்கொன்று ஏற்படுத்தாத அல்லது இதனை வழமையாகப் பயன்படுத்தாத பயனர்களுக்குரிய கலந்துரையாடல் பக்கமாகும். அதனால் நாங்கள் இவரை அடையாளம் காண்பதற்கு எண்சார்ந்த ஐபி (IP) முகவரி XXXயை உபயோகிக்கிறோம். இவ்வாறான ஐபி (IP) முகவரிகள் பல பயனர்(user) களினால் பகிர்ந்துகொள்ளப்படலாம். நீங்கள் ஒரு முகவரியற்ற பயனராயிருந்து, தொடர்பற்ற கருத்துக்கள் உங்களைக் குறித்துச் சொல்லப்பட்டிருப்பதாக நீங்கள் உணர்ந்தால், முகவரியற்ற ஏனைய பயனர்களுடனான குழப்பங்களை எதிர்காலத்தில் தவிர்ப்பதற்கு, தயவுசெய்து கணக்கொன்றை ஏற்படுத்துங்கள் அல்லது புகுபதிகை (login) செய்யுங்கள் </wiki/Special:Userlogin>.",
+"noarticletext" => "(இப் பக்கத்தில் தற்பொழுது எழுத்துக்கள் எதுவுமில்லை)",
+"updated" => "(இற்றைப்படுத்தப்பட்டது Updated)",
+"note" => "Note:",
+"previewnote" => "இது ஒரு முன்தோற்றம் (preview) மட்டுமே என்பதையும், இன்னும் சேமிக்கப்படவில்லை என்பதையும் ஞாபகத்தில் வைத்திருக்கவும்!",
+"previewconflict" => "இந்த முன்தோற்றம் உரை தொகுப்புப் பகுதியின் மேற்பகுதியிலுள்ள உரையைப் பிரதிபலிக்கின்றது. நீங்கள் இப்பொழுது சேமித்தால் மேற்படி தோற்றமே கிடைக்கும்.",
+"editing" => "தொகுத்தல் (Editting) $1",
+'editinguser' => "தொகுத்தல் (Editting) $1",
+"editingsection" => "தொகுத்தல் (Editting) $1 (பிரிவு)",
+"editingcomment" => "தொகுத்தல் (Editting) $1 (கருத்து)",
+"editconflict" => "முரண்பாடுகளைத் தொகுக்கவும் (edit): $1",
+"explainconflict" => "நீங்கள் தொகுக்கத் தொடங்கியதின் பின்னர் யாரோஒருவர் இப் பக்கங்களில் மாற்றங்கள் செய்துள்ளார். உரைப் பகுதியின் (text area ) மேற்பக்கம் தற்போதுள்ள உரைகளைக் கொண்டிருக்கும், நீங்கள் செய்த மாற்றங்கள் உரையின் கீழ்ப்பக்கம் காணப்படும். நீங்கள் உங்களுடைய மாற்றங்களை ஏற்கெனவேயிருக்கும் உரையுடன் ஒருங்கிணைக்க வேண்டியிருக்கும்.
+ \"Save page\" ஐ அழுத்தும்போது உரைப்பகுதியின் மேற்பக்கத்திலுள்ள உரை மட்டுமே சேமிக்கப்படும்.<br />",
+
+"yourtext" => "உங்கள் உரை",
+"storedversion" => "சேமிக்கப்பட்ட பதிப்பு",
+"editingold" => "எச்சரிக்கை: நீங்கள் தொகுத்துக்கொண்டிருப்பது இப் பக்கத்தின் பழைய திருத்தமொன்றை(revision)யாகும். இதை நீங்கள் சேமித்தால், மேற்படி திருத்தத்தின் பின்பு நீங்கள் செய்த மாற்றங்கள் அனைத்தும் இழக்கப்படும்.",
+"yourdiff" => "வித்தியாசங்கள்",
+/*"copyrightwarning" => "விக்கிபீடியாவுக்கான ஆக்கங்கள் அனைத்தும் ஜிஎன்யூ விடுதலை மனப்பாங்கொடு உருவான ஆவண அனுமதி (GNU Free Documentation License) முறையின் கீழ் வழங்கப்பட்டதாகவே கருதப்படும் என்பதைத் தயவு செய்து கவனிக்கவும். (விபரங்களுக்கு $1 ஐப் பார்க்க).
+
+உங்களுடைய எழுத்துக்கள் கடுமையாகத் தொகுக்கப்படுவதையோ, விரும்பியபடி விநியோகிக்கப்படுவதையோ நீங்கள் விரும்பாவிடில் இங்கே சமர்ப்பிக்காதீர்.<br />
+அத்துடன் நீங்களே இதை எழுதியதாகவோ, அல்லது வேறு பொதுக் களம் (domain) அல்லது அது போன்ற விடுதலையளிக்கும் மூலங்களிலிருந்து பிரதி பண்ணியிருப்பதாகவோ உறுதி கூறுகிறீர்கள்.
+<strong>பதிப்புரிமையுள்ள ஆக்கங்களை அனுமதியின்றி சமர்ப்பிக்க வேண்டாம்!</strong>",*/
+"longpagewarning" => "<strong>எச்சரிக்கை: இந்தப் பக்கம் $1 கிலோபைட்ஸ் நீளமானது; 32kb யை அண்மிக்கும் அல்லது அதிலும் கூடிய அளவுள்ள பக்கங்களைத் தொகுப்பதில் சில உலாவிகளுக்கு (browsers) பிரச்சினை உண்டு.
+தயவுசெய்து பக்கங்களைச் சிறிய பகுதிகளாகப் பிரிப்பது பற்றிக் கவனத்தில் எடுக்கவும்.</strong>",
+"readonlywarning" => "<strong>எச்சரிக்கை: பராமரிப்புக்காகத் தரவுத்தளம் பூட்டப்பட்டுள்ளது, எனவே உங்கள் தொகுப்புக்களை இப்பொழுது சேமிக்க முடியாது. உங்கள் உரையை (text) இன்னொரு உரைக் கோப்பில் (text file) வெட்டி ஒட்டி சேமித்துவைத்துப் பின்பு உபயோகிக்கலாம்.</strong>",
+"protectedpagewarning" => "<strong>எச்சரிக்கை: முறைமை செயற்படுத்துனர் (sysop) முன்னுரிமையுள்ள பயனர்கள் மட்டுமே தொகுக்கும் விதத்தில் இந்த பக்கம் பூட்டப்பட்டுள்ளது. நீங்கள்
+[[Project:Protected_page_guidelines|காக்கப்பட்ட பக்கங்களுக்கான வழிகாட்டல்களைப் பின்பற்றுவதை உறுதி செய்துகொள்ளவும்]].</strong>",
+
+# History pages
+#
+"revhistory" => "திருத்த (revision) வரலாறு",
+"nohistory" => "இப் பக்கத்துக்குத் தொகுப்பு வரலாறு இல்லை.",
+"revnotfound" => "திருத்தம்(revision) காணப்படவில்லை",
+"revnotfoundtext" => "இப் பக்கத்துக்குரிய, நீங்கள் கோரிய பழைய திருத்தம் (revision) காணப்படவில்லை.
+இந்தப் பக்கத்தை அணுகுவதற்கு நீங்கள் பயன்படுத்திய URL ஐத் தயவுசெய்து சரி பார்க்கவும்.",
+"loadhist" => "பக்க வரலாறு ஏற்றப்படுகிறது",
+"currentrev" => "நடைமுறையிலுள்ள திருத்தம்",
+"revisionasof" => "$1 இல் நிலவும் திருத்தம் (Revision)",
+"cur" => "நடப்பு",
+"next" => "அடுத்த",
+"last" => "கடைசி",
+"orig" => "மூலம்",
+"histlegend" => "குறியீட்டு விளக்கம்: (நடப்பு) = நடைமுறையிலுள்ள பதிப்புடனான (version) வேறுபாடு,
+(கடைசி) = முந்திய பதிப்புடனான வேறுபாடு, M = சிறு தொகுப்பு",
+
+# Diffs
+#
+"difference" => "(திருத்தங்கள்(revisions) இடையிலான வேறுபாடு)",
+"loadingrev" => "diff க்காகத் திருத்தம் ஏற்றம் செய்யப்படுகிறது",
+"lineno" => "வரிசை $1:",
+"editcurrent" => "இப் பக்கத்தின் தற்போதைய பதிப்பைத் தொகுக்கவும்(edit)",
+
+# Search results
+#
+"searchresults" => "தேடல் முடிவுகள்",
+"searchresulttext" => "விக்கிபீடியாவில் தேடுவதற்கான மேலதிக விபரங்களுக்கு, [[விக்கிபீடியா:தேடல்|விக்கிபீடியாவில் தேடல்]] ஐப் பார்க்க.",
+"searchsubtitle" => "வினவலுக்காக\"[[:$1]]\"",
+"searchsubtitleinvalid" => "வினவலுக்காக\"$1\"",
+"badquery" => "பழுதுடன் செய்யப்பட்ட தேடல் வினவல் (search query)",
+"badquerytext" => "உங்களுடைய வினவலை எங்களால் செயலாக்க முடியவில்லை.
+இது ஏனென்றால், சிலவேளை மூன்று எழுத்துக்கள் நீளத்திலும் சிறிதான சொல்லைத் தேட முயன்றிருக்கலாம், இது இன்னும் ஆதரிக்கப்படவில்லை.
+தொடரை நீங்கள் பிழையாகத் தட்டச்சிட்டதனாலும் இது நேர்ந்திருக்கக்கூடும், உதாரணமாக \"fish and and scales\".
+தயவுசெய்து இன்னொரு வினவலை (query) முயலுங்கள்.",
+"matchtotals" => "வினவல் (query) \"$1\" $2 கட்டுரைத்,தலைப்புக்களுடனும், $3 கட்டுரை உரைகளுடனும் பொருந்தியுள்ளது.",
+"noexactmatch" => "சரியாக இத் தலைப்பையுடைய பக்கமெதுவும் இல்லை, முழு உரைத் தேடல் நடைபெறுகிறது.",
+"titlematches" => "கட்டுரைத் தலைப்பு பொருந்துகிறது",
+"notitlematches" => "ஒரு கட்டுரைத் தலைப்பும் பொருந்தவில்லை",
+"textmatches" => "கட்டுரை உரை (text) பொருந்துகிறது",
+"notextmatches" => "கட்டுரை உரை (text) எதுவும் பொருந்தவில்லை",
+"prevn" => "முன் $1",
+"nextn" => "அடுத்த $1",
+"viewprevnext" => "பார் ($1) ($2) ($3).",
+"showingresults" => "#<b>$2</b> உடன் தொடங்கும் <b>$1</b> முடிவுகள் கீழே காட்டப்பட்டுள்ளன.",
+"showingresultsnum" => "#<b>$2</b> உடன் தொடங்கும் <b>$3</b> முடிவுகள் கீழே காட்டப்பட்டுள்ளன.",
+
+"nonefound" => "<strong>குறிப்பு</strong>: \"have\", \"from\" போன்ற பொதுவான, அட்டவணைப்படுத்தப்படாத, சொற்களைத் தேடும்போதோ அல்லது ஒன்றுக்கு மேற்பட்ட தேடலுக்கான சொற்களைக் குறிப்பிடும் போதோதான் (எல்லாத் தேடுதலுக்கான சொற்களையும் கொண்ட பக்கங்கள் மட்டுமே தேடல் முடிவில் காணப்படும்) தேடல் அடிக்கடி தோல்வியில் முடிகின்றது.",
+"powersearch" => "தேடு",
+"powersearchtext" => "பெயர்வெளிகளில் (namespaces) இல் தேடுக:<br />
+$1<br />
+$2 பட்டியல் &nbsp; $3 $9 க்கான தேடலை மீள்வழிப்படுத்துகிறது",
+"searchdisabled" => "<p>மன்னிக்கவும்! செயற்திறன் காரணங்களுக்காக முழு அளவு உரை தேடல் தற்காலிகமாக முடக்கப்பட்டுள்ளது. அதுவரை நீங்கள் கீழேயுள்ள கூகிள் (Google) தேடலைப் பயன்படுத்தலாம். இது சில சமயம் இற்றைப்படுத்தப்படாததாய் இருக்கக்கூடும்.</p>",
+"blanknamespace" => "(முதன்மை)",
+
+# Preferences page
+#
+"preferences" => "முன்னுரிமைகள்",
+"prefsnologin" => "புகுபதிகை செய்யப்படவில்லை",
+"prefsnologintext" => "பயனர் விருப்பத் தேர்வுகளை அமைப்பதற்கு நீங்கள் [[Special:Userlogin|புகுபதிகை செய்ய வேண்டும்]].",
+"prefsreset" => "உங்கள் விருப்புகள் சேமிப்பிலிருந்து மீட்டமைக்கப்பட்டுள்ளன (reset).",
+"qbsettings" => "விரைவுச் சட்ட அமைவுகள்",
+"changepassword" => "கடவுச்சொல்லை மாற்று",
+"skin" => "தோல் (Skin)",
+"math" => "பதிப்புவரை கணிதம் (Rendering math)",
+"dateformat" => "திகதி வடிவம்",
+"math_failure" => "பாகுபடுத்தல் (parse) தோல்வி",
+"math_unknown_error" => "அறியப்படாத தவறு",
+"math_unknown_function" => "அறியப்படாத பணி",
+"math_lexing_error" => "தொகுத்தல் (lexing) தவறு",
+"math_syntax_error" => "தொடரமைப்புத் தவறு (syntax error)",
+"saveprefs" => "விருப்பத் தேர்வுகளைச் சேமி",
+"resetprefs" => "விருப்பத் தேர்வுகளை மீட்டமை (Reset)",
+"oldpassword" => "பழைய கடவுச்சொல்",
+"newpassword" => "புதிய கடவுச்சொல்",
+"retypenew" => "புதிய கடவுச்சொல்லை மீண்டும் அச்சிடு",
+"textboxsize" => "உரைக் கட்ட (Textbox) அளவுகள்",
+"rows" => "வரிசைகள்",
+"columns" => "நிரல்கள் (Columns)",
+"searchresultshead" => "தேடல் முடிவு அமைவுகள் (settings)",
+"resultsperpage" => "ஒரு பக்கத்துக்குக் காட்டப்படவேண்டிய அடிகள் (Hits)",
+"contextlines" => "அடித்தலொன்றுக்குக் காட்டப்பட வேண்டிய வரிகள்",
+"contextchars" => "ஒரு வரிக்கான இடம்சார் (context) எழுத்துக்கள்",
+"stubthreshold" => "அடிப்படைக் காட்சிப்படுத்தலுக்கான மாறுநிலை (Threshold)",
+"recentchangescount" => "அண்மைய மாற்றங்களில் தலைப்புகள் எண்ணிக்கை",
+"savedprefs" => "உங்கள் விருப்புகள் சேமிக்கப்பட்டுள்ளன.",
+"timezonetext" => " வழங்கன் (server) நேரத்துக்கும் (UTC) உங்கள் உள்ளூர் நேரத்துக்குமுள்ள வேறுபாட்டை மணிகளில் பதிக.",
+"localtime" => "உள்ளூர் நேரக் காட்சிப்பாடு (display)",
+"timezoneoffset" => "நேர இடைவெளி",
+"servertime" => "தற்போது வழங்கன் (Server) நேரம்",
+"guesstimezone" => "உலவி (browser) யிலிருந்து நிரப்புக.",
+"defaultns" => "முன்னிருப்பாக இந்த பெயர்வெளிகளில் (namespaces) தேடவும்:",
+
+# Recent changes
+#
+"changes" => "மாற்றங்கள்",
+"recentchanges" => "அண்மைய மாற்றங்கள்",
+"rcnote" => "கீழே காணப்படுவது கடைசி $2 நாட்களில் செய்யப்பட்ட $1 மாற்றங்களாகும்.",
+"rcnotefrom" => "கீழே காணப்படுவது $2 இலிருந்து செய்யப்பட்ட மாற்றங்கள் ($1வரை காட்டப்பட்டுள்ளது).",
+"rclistfrom" => "$1 தொடக்கம் செய்யப்பட்ட புதிய மாற்றங்களைக் காட்டவும்",
+"rclinks" => "கடைசி $2 மணித்தியாலங்கள் / கடைசி $3 நாட்களில் செய்யப்பட்ட கடைசி $1 மாற்றங்களைக் காட்டு",
+"rclinks" => "கடைசி $2 நாட்களில் கடைசி $1 மாற்றங்களைக் காட்டு .",
+"diff" => "வேறுபாடு",
+"hist" => "வரலாறு",
+"hide" => "மறை",
+"show" => "காட்டு",
+"minoreditletter" => "M",
+"newpageletter" => "N",
+# Upload
+"upload" => "கோப்பைப் பதிவேற்று (Upload file)",
+"uploadbtn" => "கோப்பைப் பதிவேற்று (Upload file)",
+"reupload" => "மீளப் பதிவேற்று (Re-upload)",
+"reuploaddesc" => "பதிவேற்றும் படிவத்துக்கு மீளச் செல்.",
+"uploadnologin" => "புகுபதிகை (login) செய்யப்படவில்லை",
+"uploadnologintext" => "கோப்புகளைப் பதிவேற்றம் செய்வதற்கு நீங்கள்[[Special:Userlogin|புகுபதிகை செய்திருக்க வேண்டும்]].",
+"uploaderror" => "ஏற்றுத் தவறு",
+"uploadtext" => "நிறுத்தவும்! இங்கே பதிவேற்றம் செய்யுமுன், விக்கிபீடியாவின் [[Project:Image_use_policy|படிமம் பயன்படுத்தற் கொள்கை]] யை வாசித்துப் பின்பற்றுவதை உறுதிப்படுத்திக் கொள்ளவும்.
+நீங்கள் குறித்த பெயருடைய கோப்பு எற்கெனவே விக்கிபீடியாவில் இருக்குமாயின், அது எச்சரிக்கை கொடாமல் பிரதியீடு செய்யப்படும். எனவே கோப்பொன்றை இற்றைப்படுத்துவது (update) உங்கள் நோக்கமாக இல்லாவிடில், அதே பெயரில் வேறு கோப்பு உள்ளதா என முதலில் அறிந்து கொள்ளவும்.
+முன்னர் பதிவேற்றம் செய்யப்பட்ட படிமங்களைப் பார்ப்பதற்கு அல்லது தேடுவதற்கு, [[Special:Imagelist|பதிவேற்றம் செய்யப்பட்ட படிமங்களின் பட்டிய]] லுக்குச் செல்லவும். பதிவேற்றங்களும் நீக்கல்களும் [[Project:Upload_log|பதிவேற்றப் பதிகையில் (upload log)]] பதியப்பட்டுள்ளன.
+உங்கள் கட்டுரைகளில் பயன்படவுள்ள புதிய படிமங்களைப் பதிவேற்றுவதற்கு கீழேயுள்ள படிவத்தைப் பயன்படுத்தவும். பெரும்பாலான உலவிகளில், கோப்புத் திறக்கும் உரையாடல் பெட்டியைக் காட்டும் உங்கள் இயக்க முறைமையின் (operating system) இயல்பான ஒரு \"Browse...\" பொத்தானைக் காணலாம்.ஒரு கோப்பைத் தெரிவுசெய்யும்பொது, அதன் பெயர், பொத்தானுக்கு அருகிலுள்ள உரைப்புலத்தில் (text field) நிரப்பப்படும். கோப்பைப் பதிவேற்றம் செய்வதன் மூலம்எந்தப் பதிப்புரிமையையும் மீற்வில்லை என்பதை உறுதிப்படுத்த அதற்குரிய கட்டத்திலும் நீங்கள் குறியிடவேண்டும். பதிவேற்றத்தை நிறைவுசெய்வதற்கு \"Upload\" பொத்தானை அழுத்தவும். உங்கள் வலையக இணைப்பு வேகம் குறைந்ததாக இருப்பின், இதற்குச் சிறிது நேரன் எடுக்கக்கூடும்.
+புகைப்படப் படிமங்களுக்கு JPEG யும், வரைபடங்களுக்கும் ஏனைய குறியீட்டுப் (iconic) படிமங்களுக்கும் PNG யும், ஒலிக் கோப்புகளுக்கு OGG யும் விரும்பத்தக்க வடிவங்களாகும்.
+
+
+குழ்ப்பத்தைத் தவிர்ப்பதற்குத் தயவுசெய்து உங்கள் கோப்புகளுக்கு விபரமாகப் பெயரிடவும்.உங்கள் கட்டுரைகளில் படிமங்களைச் சேர்ப்பதற்கு,
+'''<nowiki>[[image:file.jpg]]</nowiki>''' அல்லது '''<nowiki>[[image:file.png|alt text]]</nowiki>''' இணைப்பு வடிவத்தையும், ஒலிகளுக்கு '''<nowiki>[[media:file.ogg]]</nowiki>''' இணைப்புவடிவத்தையும் பயன்படுத்தவும்.
+
+விக்கிபீடியா பக்கங்களைப் பொறுத்தவரை, கலைக் கழஞ்சியத்துக்கு உதவும் என்று மற்றவர்கள் கருதினால், உங்கள் பதிவேற்றத்தைத் தொகுக்கவோ அல்லது நீக்கவோ முடியும். அத்துடன் நீங்கள் இந்த முறைமையைத் துஷ்பிரயோகம் செய்தால், பதிவேற்றம் செய்வதிலிருந்து தடுக்கப்படவும் கூடும் என்பதையும் கவனிக்கவும்.",
+
+"uploadlog" => "பதிவேற்றப் பதிகை (Upload_log)",
+"uploadlogpage" => "பதிவேற்றப் பதிகை (Upload_log)",
+"uploadlogpagetext" => "கீழேயுள்ளது மிக அண்மையில் பதிவேற்றம் செய்யப்பட்ட கோப்புகளின் பட்டியலாகும்.
+காட்டப்பட்டுள்ள எல்லா நேரங்களும் வழங்கன் நேரமாகும்(UTC).
+<ul>
+</ul>",
+"filename" => "கோப்புப் பெயர்",
+"filedesc" => "சுருக்கம்",
+"filestatus" => "பதிப்புரிமை நிலை",
+"filesource" => "மூலம்",
+"copyrightpage" => "விக்கிபீடியா:பதிப்புரிமை",
+"copyrightpagename" => "விக்கிபீடியா பதிப்புரிமை",
+"uploadedfiles" => "ஏற்றப்பட்ட (Uploaded) கோப்புகள்",
+"minlength" => "படிமத்தின் (Image) பெயர் குறைந்தது மூன்று எழுத்துக்களாவது இருக்க வேண்டும்.",
+"badfilename" => "படிமப் (Image) பெயர் \"$1\" ஆக மாற்றப்பட்டுள்ளது.",
+"badfiletype" => "\".$1\" இது ஒரு சிபாரிசு செய்யப்பட்ட படிமக் கோப்பு வடிவம் (format) அல்ல.",
+"largefile" => "படிமங்களிமன் அளவு 100k க்கு மேற்படாதிருக்க சிபாரிசு செய்யப்படுகிறது.",
+"successfulupload" => "வெற்றிகரமான பதிவேற்றுதல் (upload)",
+"fileuploaded" => "File \"$1\" வெற்றிகரமாக பதிவேற்றப்பட்டது (uploaded).
+தயவுசெய்து விபரிப்புப் பக்கத்துக்குப் பின்வரும் இணைப்பைப் பின்பற்றவும்: ($2) அத்துடன் கோப்புப் பற்றிய, எங்கிருந்து கிடைத்தது, எப்பொழுது, யாரால் உருவாக்கப்பட்டது மற்றும் உங்களுக்குத் தெரிந்த இன்னோரன்ன தகவல்களையும் நிரப்பவும்.",
+"uploadwarning" => "பதிவேற்றுதல் எச்சரிக்கை",
+"savefile" => "கோப்பைச் சேமி",
+"uploadedimage" => "பதிவேற்றப்பட்டது \"[[$1]]\"",
+
+# Image list
+#
+"imagelist" => "படிமங்களின் பட்டியல்",
+"imagelisttext" => "கீழ் வருவது $2 பாகுபடுத்தப்பட்ட $1 படிமங்களின் பட்டியலாகும்.",
+"getimagelist" => "படிமப் பட்டியல் பெற்றுக் கொள்ளப்படுகிறது (fetching)",
+"ilsubmit" => "தேடல்",
+"showlast" => "$2 பாகுபடுத்தப்பட்ட கடைசி $1 படிமங்களைக் காட்டுக.",
+"byname" => "பெயர் வழி",
+"bydate" => "திகதி வழி",
+"bysize" => "அளவு வழி",
+"imgdelete" => "நீக்கு",
+"imgdesc" => "விபரம்",
+"imglegend" => "குறியீட்டு அட்டவணை: (விபரம்) = படிம விபரங்களைக் காட்டு/தொகு.",
+"imghistory" => "படிம வரலாறு",
+"revertimg" => "மீள்",
+"deleteimg" => "நீக்கு",
+"deleteimgcompletely" => "நீக்கு",
+"imghistlegend" => "குறியீட்டு அட்டவணை: (நடப்பு) = இது நடப்பிலுள்ள (current) படிமம், (நீக்கு) = இந்த பழைய பதிப்பை நீக்கு, (திரும்பு) = இப் பழைய பதிப்புக்குத் திரும்பு.
+<br /><i>அந்தத் திகதியில் பதிவேற்றம் செய்யப்பட்ட படிமங்களைப் பார்ப்பதற்கு, திகதி மீது சொடுக்கவும்</i>.",
+"imagelinks" => "படிம இணைப்புகள்",
+"linkstoimage" => "பின்வரும் பக்கங்கள் இப் படிமத்துக்கு இணைக்கப்பட்டுள்ளன:",
+"nolinkstoimage" => "இப் படிமத்துக்கு இணைக்கப்பட்டுள்ள பக்கங்கள் எதுவும் இல்லை.",
+
+# Statistics
+#
+"statistics" => "புள்ளி விபரங்கள்",
+"sitestats" => "தள புள்ளி விபரங்கள்",
+"userstats" => "பயனர் புள்ளி விபரங்கள்",
+"sitestatstext" => "<b>$1</b> மொத்தப் பக்கங்கள் தரவுத் தளத்தில் உள்ளன.
+இது \"talk\" பக்கங்கள், விக்கிபீடியா பற்றிய பக்கங்கள், குறைந்த அளவு \"stub\"
+பக்கங்கள், வழிமாற்றிகள் (redirects), மற்றும் கட்டுரைத் தரத்தில் இல்லாதிருக்கக்கூடிய ஏனையவற்றையும் உள்ளடக்கும். இவை தவிர்த்து, <b>$2</b> பக்கங்கள் முறையான (legitimate) ஆன கட்டுரைகளாக இருக்கக்கூடும்.<p>
+இங்கே மொத்தமாக <b>$3</b> பக்கங்கள் பார்க்கப்பட்டதுடன், மென்பொருள் தரமுயர்த்த்ப்பட்டதிலிருந்து (நவம்பர் 20, 2003) <b>$4</b> பக்கங்கள் தொகுக்கப்பட்டுள்ளன. இது ஒரு பக்கத்துக்கு <b>$5</b> சராசரித் தொகுப்புக்களும், ஒரு தொகுப்புக்கு <b>$6</b> பார்வைகளும் ஆகின்றது.",
+"userstatstext" => "<b>$1</b> பதிவு செய்யப்பட்ட பயனர்கள் உள்ளனர்.
+இவர்களில் <b>$2</b> பேர் நிர்வாகிகள்($3 பார்க்கவும்).",
+
+# Maintenance Page
+#
+"disambiguations" => "கவர்படுநிலைதீர் (Disambiguation) பக்கங்கள்",
+"disambiguationspage" => "விக்கிபீடியா:கவர்படுநிலைதீர்_பக்க_இணைப்புகள்",
+"disambiguationstext" => "இக் கட்டுரைகள் ஒரு <i>கவர்படுநிலைதீர் (disambiguation) பக்கத்து</i>க்கு இணைக்கப்பட்டுள்ளன. பதிலாக இவை பொருத்தமான தலைப்புக்களுக்கு இணைக்கப்பட வேண்டும்.<br />ஒரு பக்கம் $1 இலிருந்து இணைப்புக் கொடுபட்டிருந்தால் கவர்படுநிலைத் தீர்வாகக் (disambiguation) கருதப்படும்.<br /> ஏனைய பெயர்வெளிகளிலிருந்தான இணைப்புக்கள் இங்கே பட்டியலிடப்<i>படவில்லை</i>.",
+"doubleredirects" => "இரட்டை வழிமாற்றுகள் (Redirects)",
+"doubleredirectstext" => "<b>கவனிக்கவும்:</b> இந்தப் பட்டியல் போலியான நேர்மதிப்பு (positives) களைக் கொண்டிருக்கக்கூடும். இது வழக்கமாக, இணைப்புடன் கூடிய மேலதிக உரை முதலாவது #வழிமாற்றுக்குக் கீழ் இருப்பதைக் குறிக்கும்.<br />\nஒவ்வொரு வரியும், முதலாம் இரண்டாம் வழிமாற்றுகளுக்கு இணைப்புகளைக் கொண்டிருப்பதுடன், இரண்டாவது வழிமாற்று உரையின் முதல் வரிக்கும் இணைப்பைக் கொண்டிருக்கும், இது வழக்கமாக முதலாவது வழிமாற்று குறித்துக் காட்ட வேண்டிய \"real\" இலக்குக் கட்டுரையைக் (taget article) கொடுக்கும்.",
+"brokenredirects" => "முறிந்த வழிமாற்றுகள்(Redirects)",
+"brokenredirectstext" => "பின்வரும் வழிமாற்றுகள் ஒரு இல்லாத கட்டுரைகு இணைப்புக் கொடுபட்டுள்ளது.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "உறவிலிப்(Orphaned) பக்கங்கள்",
+"unusedimages" => "உபயோகப்படுத்தப்படாத படிமங்கள்",
+"popularpages" => "பிரபலமான பக்கங்கள்",
+"nviews" => "$1 காட்சிகள்",
+"wantedpages" => "வேண்டிய பக்கங்கள்",
+"nlinks" => "$1 இணைப்புகள்",
+"allpages" => "எல்ல பக்கங்கள்",
+"randompage" => "குறிப்பில்வழிப் (Random) பக்கம்",
+"shortpages" => "குறும் பக்கங்கள்",
+"longpages" => "நீளமான பக்கங்கள்",
+"listusers" => "பயனர் அட்டவணை",
+"specialpages" => "விசேட பக்கங்கள்",
+"spheading" => "எல்லாப் பயனர்களுக்குமான விசேட பக்கங்கள்",
+"recentchangeslinked" => "தொடர்பான மாற்றங்கள்",
+"rclsub" => "(\"$1\" இலிருந்து இணைக்கப்பட்ட பக்கங்களுக்கு)",
+"newpages" => "புதிய பக்கங்கள்",
+"ancientpages" => "மிகப்பழைய கட்டுரைகள்",
+"intl" => "மொழியிடை இணைப்புகள்",
+"movethispage" => "இப்பக்கத்தை அசை",
+"unusedimagestext" => "<p>இண்டர்நஷனல் விக்கிபீடியா போன்ற மற்ற வலைத் தளங்களில், நேரடி URL மூலம் ஒரு படிமம் இனைக்கப்பட்டிருக்கக் கூடுமென்பதுடன், செயல்படு (active) பயன்பாட்டில் இருந்தும் கூட இங்கே பட்டியலிடப்பட்டிருக்கக்கூடும் என்பதையும் கவனிக்கவும்.",
+"booksources" => "நூல் மூலங்கள்",
+"booksourcetext" => "புதிய, பயன்படுத்திய புத்தகங்களை விற்பதுடன், நீங்கள் தேடும் நூல்கள்பற்றிய மேலதிக தகவல்களையும் தரக்கூடிய வேறு தளங்களுடனான இணைப்புகளின் பட்டியல் கீழே தரப்பட்டுள்ளது. விக்கிபீடியா இந்த வியாபார நிறுவனங்கள் எதனுடனும் கூட்டு வைத்திருக்கவில்லை. அத்துடன் இந்தப் பக்கத்தை ஒரு உத்தரவாதமாக (endorsement) அர்த்தப்படுத்திக்கொள்ளக் கூடாது.",
+
+"alphaindexline" => "$1 to $2",
+
+# Email this user
+#
+"mailnologin" => "அனுப்பும் முகவரி இல்லை",
+"mailnologintext" => "நீங்கள்[[Special:Userlogin|புகுபதிகை செய்திருப்பதுடன்]]
+ஏனைய பயனர்களுக்கு மின்னஞ்சல் அனுப்பக்கூடியத்தாக செல்லுபடியாகக்கூடிய மின்னஞ்சல் முகவரியொன்றும் உங்களுடைய [[Special:Preferences|விருப்பத் தெரிவுகளில்]] கொடுபட்டிருக்கவேண்டும்.",
+"emailuser" => "இப் பயனருக்கு மின்னஞ்சல் செய்",
+"emailpage" => "மின்னஞ்சல் பயனர்",
+"emailpagetext" => "இப் பயனர் ஒரு செல்லுபடியாகக்கூடிய மின்னஞ்சல் முகவரியை அவரது பயனர் விருப்பத்தேர்வுகளில் கொடுத்திருந்தால், கீழ் வரும் படிவம் ஒரு தனித்த செய்தியை அனுப்பும்.
+பயனர் விருப்பத்தேர்வுகளில் நீங்கள் கொடுத்துள்ள மின்னஞ்சல் முகவரி, பெறுனர் பதில் எழுத முடியும் வகையில், அஞ்சலின் \"From\" முகவரியாகக் காட்சி தரும்.",
+"noemailtitle" => "மின்னஞ்சல் முகவரி இல்லை",
+"noemailtext" => "இப் பயனர் ஒரு செல்லுபடியாகக்கூடிய மின்னஞ்சல் முகவரியைக் குறிப்பிடவில்லை அல்லது பிற பயனர்களிடமிருந்து மின்னஞ்சல் பெறும் விருப்பத் தேர்வைத் தெரிவு செய்யவில்லை.",
+"emailfrom" => "அனுப்புனர்",
+"emailto" => "பெறுனர்",
+"emailsubject" => "உட்பொருள்",
+"emailmessage" => "செய்தி",
+"emailsend" => "அனுப்பு",
+"emailsent" => "மின்னஞ்சல் அனுப்பப்பட்டது",
+"emailsenttext" => "உங்கள் மின்னஞ்சல் செய்தி அனுப்பப்பட்டது.",
+# Watchlist
+"watchlist" => "என்னுடைய கவனிப்புப் பட்டியல்(watchlist)",
+"nowatchlist" => "உங்களுடைய கவனிப்புப் பட்டியலில் ஒரு விடயமும் இல்லை.",
+"watchnologin" => "புகுபதிகை செயப்படவில்லை",
+"watchnologintext" => "உங்கள் கவனிப்புப் பட்டியலில் திருத்தம் செய்வதற்கு, நீங்கள்[[Special:Userlogin|புகுபதிகை செய்திருக்கவேண்டும்]].",
+"addedwatch" => "கவனிப்புப் பட்டியலில் சேர்க்கப்பட்டது",
+"addedwatchtext" => "பக்கம்\"$1\" உங்கள்<a href=\"" .
+ "{{localurle:Special:Watchlist}}\">கவனிப்புப் பக்கத்தில்</a> சேர்க்கப்பட்டுள்ளது.
+இந்தப் பக்கத்துக்கு எதிகாலத்தில் செய்யப்படவுள்ள மாற்றங்களும், அதனோடிணைந்த பேச்சுப் பக்கமும், அங்கே பட்டியலிடப்படும். அத்துடன் தெரிந்தெடுக்க வசதியாக <a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">அண்மைய மாற்றங்களின் பட்டியலில்</a> இது தடித்த எழுத்துக்களில் காட்டப்படும்.
+பின்னர், இப் பக்கத்தை உங்கள் கவனிப்புப் பட்டியலிலிருந்து நீக்க விரும்பினால், பக்கச் சட்டத் (sidebar) திலுள்ள \"Stop watching\" ஐச் சொடுக்கவும்.",
+"removedwatch" => "கவனிப்புப் பட்டியலிலிருந்து நீக்கப்பட்டது",
+"removedwatchtext" => "இந்தப் பக்கம் \"$1\" உங்கள் கவனிப்புப் பட்டியலிலிருந்து நீக்கப்பட்டது.",
+"watchthispage" => "இந்தப் பக்கத்தைக் கவனிக்கவும்",
+"unwatchthispage" => "கவனிப்பதை நிறுத்தவும்",
+"notanarticle" => "ஒரு கட்டுரை அல்ல",
+"watchnochange" => "காட்சிப்படுத்தப்பட்ட கால இடைவெளியில், கவனிப்பிலுள்ள, உங்கள் விடயமெதுவும் தொகுக்கப்பட்டிருக்கவில்லை.",
+"watchdetails" => "(பேச்சுப் பக்கங்களைக் கணக்கிடாமல், $1 பக்கங்கள் கவனிக்கப்பட்டன; வெட்டுநிலை (cutoff) யிலிருந்து, மொத்தம் $2 பக்கங்கள் தொகுக்கப்பட்டன; $3... [$4 முழுப் பட்டியலையும் காண்பித்துத் தொகுக்கவும்].)",
+"watchmethod-recent" => "கவனிக்கப்படுகின்ற பக்கங்களுக்காக, அண்மைய தொகுப்புகள் தேடிப் பார்க்கப்படுகிறன",
+"watchmethod-list" => "அண்மைய தொகுப்புகளுக்காக, கவனிக்கப்படுகின்ற பக்கங்கள் தேடிப் பார்க்கப்படுகிறன",
+"removechecked" => "குறியிடப்பட்ட விடயங்களைக் கவனிப்புப் பட்டியலிலிருந்து நீக்குக.",
+"watchlistcontains" => "உங்கள் கவனிப்புப் பட்டியல் $1 பக்கங்களைக் கொண்டுள்ளது.",
+"watcheditlist" => "இதோ உங்கள் கவனிப்புப் பக்கங்களுக்கான ஒரு அகரவரிசைப் பட்டியல். உங்கள் கவனிப்புப் பட்டியலிலிருந்து நீக்க விரும்பும் பக்கங்களுக்கான கட்டங்களில் குறியிட்டு, திரையின் கீழ்ப் பாகத்திலுள்ள 'குறியிடப்பட்டதை நீக்குக' பொத்தானைச் சொடுக்கவும்.",
+"removingchecked" => "கோரப்பட்ட விடயங்கள் கவனிப்புப் பட்டியலிலிருந்து நீக்கப்படுகின்றன ...",
+"couldntremove" => "விடயம்'$1' ஐ நீக்க முடியவில்லை...",
+"iteminvalidname" => "விடயம் '$1' தொடர்பில் பிரச்சினை உள்ளது, செல்லுபடியாகாத பெயர்...",
+"wlnote" => "பின்வருவன, கடைசி $2 மணிகளில் செய்யப்பட்ட, கடைசி $1 மாற்றங்களாகும்.",
+"wlshowlast" => "கடைசியைக் காட்டு",
+
+# Delete/protect/revert
+"deletepage" => "பக்கத்தை நீக்கு",
+"confirm" => "உறுதிசெய்",
+"excontent" => "இருந்த உள்ளடக்கம்: '$1'",
+"exbeforeblank" => "வெறுமைப்படுத்த (blanking) முன்னிருந்த உள்ளடக்கம்: '$1'",
+"exblank" => "பக்கம் வெறுமையாய் இருந்தது",
+"confirmdelete" => "நீக்குதலை உறுதிப்படுத்து",
+"deletesub" => "(\"$1\" நீக்கப்படுகிறது)",
+"historywarning" => "எச்சரிக்கை: நீங்கள் நீக்கவுள்ள பக்கத்துக்கு ஒரு வரலாறு உண்டு:",
+"actioncomplete" => "செயற்பாடு நிறைவுற்றது",
+"deletedtext" => "\"$1\" நீக்கப்பட்டு விட்டது. அண்மைய நீக்குதல்களின் பதிவுக்கு $2 ஐப் பார்க்க.",
+"deletedarticle" => "\"$1\" நீக்கப்பட்டது",
+"dellogpage" => "நீக்கல்_பதிவு",
+"dellogpagetext" => "கீழே காணப்படுவது மிக அண்மைய நீக்கல்களின் அட்டவணையாகும். எல்லா நேரங்களும் வழங்கன்(server) நேரங்களாகும்(UTC).",
+"deletionlog" => "நீக்கல்_பதிவு",
+"reverted" => "முன் திருத்தத்துக்கு மீள்விக்கப்பட்டுள்ளது",
+"deletecomment" => "நீக்கலுக்கான காரணம்",
+"imagereverted" => "வெற்றிகரமாக முன்னைய திருத்தத்துக்கு மீழ்விக்கப்பட்டது.",
+"rollback" => "முன்நிலையாக்கத் (Roll back ) தொகுப்புகள்",
+"rollbacklink" => "முன்நிலையாக்கு",
+"rollbackfailed" => "முன்நிலையாக்கம் (Rollback) தோல்வி",
+"cantrollback" => "தொகுப்பை மீழ்விக்க முடியாது; கடைசிப் பங்களிப்பாளரே (contributor) இக் கட்டுரையின் ஆசிரியராகும்.",
+"alreadyrolled" => " ( [[User:$3|$3]] ([[User talk:$3|Talk]]) ஆல் செய்யப்பட்ட [[:$1]] திகதிய கடைசித் தொகுப்பை முன்நிலையாக்க முடியாது; வேறு யாரோ இக் கட்டுரையை ஏற்கெனவே தொகுத்தோ அல்லது முன்நிலையாக்கியோ உள்ளார்.
+கடைசியாகத் தொகுத்தவர்[[User:$3|$3]] ([[User talk:$3|Talk]]).",
+# only shown if there is an edit comment
+"editcomment" => "தொகுப்புக்குரிய கருத்துரை (comment): \"$1\".",
+"revertpage" => "$1 ஆல் கடைசித் தொகுப்புக்கு முன்நிலையாக்கப்பட்டது",
+# Undelete
+"undelete" => "நீக்கப்பட்ட பக்கங்களை மீட்டெடு",
+"undeletepage" => "பார்ப்பதுடன், நீக்கப்பட்ட பக்கங்களை மீட்டெடு",
+"undeletepagetext" => "பின்வரும் பக்கங்கள் நீக்கப்பட்டுவிட்டன எனினும் காப்பகத்திலுள்ளதுடன் அவற்றை மீட்டெடுக்கவும் முடியும். காப்பகம் காலத்துக்குக் காலம் சுத்தப்படுத்தப்படலாம்.",
+"undeletearticle" => "நீக்கப்பட்ட கட்டுரையை மீட்டெடு",
+"undeleterevisions" => "$1 திருத்தங்கள் காப்பகப்படுத்த்ப்பட்டன",
+"undeletehistory" => "இந்தப் பக்கத்தை நீங்கள் மீள்வித்தால், எல்லாத் திருத்தங்களும் வரலாற்றுக்கு மீள்விக்கப்படும். நீக்குதலின் பின்னர், அதே பெயருடைய வேறொரு புதிய பக்கம் உருவாக்கப்பட்டிருந்தால், மீள்விக்கப்பட்ட திருத்தங்கள் முன்னைய வரலாற்றிலேயே காணப்படும், அத்துடன் உயிர்ப்பு நிலையிலுள்ள () நடப்புத் திருத்தம் தன்னியக்கமாகப் பிரதியீடு செய்யப்பட மாட்டாது.",
+"undeleterevision" => "$1 திருத்தத்தை நீக்கு",
+"undeletebtn" => "மீட்டெடு!",
+"undeletedarticle" => "\"$1\" மீட்டெடுக்கப்பட்டது",
+
+# Contributions
+#
+"contributions" => "பயனர் பங்களிப்புக்கள்",
+"mycontris" => "என் பங்களிப்புக்கள்",
+"contribsub" => "$1 க்காக",
+"nocontribs" => "இந்த நிபந்தனையுடன் ஒத்துப்போகும் வகையில் மாற்றங்களெதுவும் காணப்படவில்லை.",
+"ucnote" => "பின்வருவது கடந்த <b>$2</b> நாட்களில் இப் பயனரினால் செய்யப்பட்ட கடைசி <b>$1</b> மாற்றங்களாகும்.",
+"uclinks" => "கடைசி $1 மாற்றங்களைக் காண்க; கடைசி $2 நாட்களைப் பார்.",
+"uctop" => " (மேல்)" ,
+
+# What links here
+#
+"whatlinkshere" => "இப் பக்கத்தை இணைத்தவை",
+"notargettitle" => "இலக்கு இல்லை",
+"notargettext" => "நீங்கள் இந்தச் செயலை எந்தப் பயனர் அல்லது பக்கம் தொடர்பில் செய்வது என்பதைக் குறிப்பிடவில்லை.",
+"linklistsub" => "(இணைப்புகளின் பட்டியல்)",
+"linkshere" => "பின்வரும் பக்கங்களில் இப்பக்கம் இணைக்கப்பட்டுள்ளது:",
+"nolinkshere" => "எந்தப் பக்கத்திலும் இந்தப் பக்கம் இணைக்கப்படவில்லை.",
+"isredirect" => "வழிமாற்றுப் பக்கம்",
+
+# Block/unblock IP
+#
+"blockip" => "பயனரைத் தடு",
+"blockiptext" => "ஒரு குறிப்பிட்ட ஐபி முகவரி அல்லது பயனரிடமிருந்து எழுத்து அணுக்கத்தைத் தடுப்பதற்குக் கீழேயுள்ள படிவத்தை உபயோகிக்கவும். இது விஷமத்தனத்தைத் தடுப்பதற்கும் [[{{ns:project}}:Policy|விக்கிபீடியா கொள்கை]]க்கு எற்புடைய வகையிலும் மட்டுமே பயன்படுத்தப்பட வேண்டும்.
+குறிப்பிட்ட காரணமொன்றைக் கீழே நிரப்புக (உதாரணமாக், விஷமத்தனம் செய்யப்பட்ட (vandalized) பக்கங்களை எடுத்துக் காட்டவும்).",
+"ipaddress" => "ஐபி (IP) முகவரி/பயனர்பெயர்",
+"ipbreason" => "காரணம்",
+"ipbsubmit" => "இப் பயனரைத் தடு",
+"badipaddress" => "அந்தப் பெயரில் பயனர் எவரும் இல்லை",
+"blockipsuccesssub" => "தடுப்பு வெற்றி",
+"blockipsuccesstext" => "\"$1\" தடுக்கப்பட்டுள்ளார்.
+<br />தடுப்பை மீளாய்வு செய்ய [[Special:Ipblocklist|IP block list]] ஐப் பார்க்கவும்.",
+"unblockip" => "பயனர் தடை நீக்கு",
+"unblockiptext" => "முன்னர் தடுக்கப்பட்ட ஐபி முகவரி அல்லது பயனர்பெயரின் எழுத்து அணுக்கத்தை மீழ்விப்பதற்கு கீழேயுள்ள படிவத்தை உபயோகிக்கவும்.",
+"ipusubmit" => "இம் முகவரியைத் தடை நீக்கு",
+"ipblocklist" => "தடுக்கப்பட்ட ஐபி முகவரிகளினதும், பயனர் பெயர்களினதும் பட்டியல்",
+"blocklistline" => "$1, $2 blocked $3 ($4)",
+"blocklink" => "தடு",
+"unblocklink" => "தடை நீக்கு",
+"contribslink" => "contribs",
+"autoblocker" => "நீங்கள் \"$1\" உடன் ஒரே ஐபி முகவரியைப் பகிர்ந்துகொள்வதால் தானியங்கித் தடை விதிக்கப்பட்டுள்ளது. காரணம் \"$2\".",
+"blocklogpage" => "தடைப்_பதிவு (Block_log)",
+"blocklogentry" => 'தடுக்கப்பட்டது "$1"',
+"blocklogtext" => "இது ஒரு பயனரின் தடுப்பு தடை நீக்கல் செயற்பாடுகளுக்கான பதிவாகும். தானியங்கி முறையில் தடுக்கப்படும் ஐபி முகவரிகள் இப்பட்டியலில் இடம்பெறா. தற்போது செயற்பாட்டிலுள்ள தடைகளையும்் முடக்கங்களையும் [[Special:Ipblocklist|ஐபி தடுப்பு பட்டியலில்]] பார்க்க.",
+"unblocklogentry" => 'தடுப்பு நீக்கப்பட்டது "$1"',
+
+# Developer tools
+#
+"lockdb" => "தரவுத்தளத்தைப் பூட்டு",
+"unlockdb" => "தரவுத்தளத்தைத் திற",
+"lockdbtext" => "தரவுத்தளத்தைப் பூட்டுதல், பயனர்கள் பக்கங்களைத் தொகுக்கவும், விருப்பத் தேர்வுகளை மாற்றவும், கவனிப்புப் பட்டியல்களைத் தொகுக்கவும், மற்றும் தரவுத்தளத்தில் மாற்றங்கள் தேவைப்படும் பிற விடயங்களைச் செய்யவும் முடியாமல் இடை நிறுத்தும். இதுதான் உங்களுக்கு வேண்டியது என்பதையும், பராமரிப்பு முடிந்ததும் தரவுத்தளத்தைத் திறந்துவிடுவீர்கள் என்பதையும் தயவுசெய்து உறுதிப்படுத்தவும்.",
+"unlockdbtext" => "தரவுத்தளத்தைத் திறத்தல், பக்கங்களைத் தொகுக்கவும், விருப்பத் தேர்வுகளை மாற்றவும், கவனிப்புப் பட்டியல்களைத் தொகுக்கவும், மற்றும் தரவுத்தளத்தில் மாற்றங்கள் தேவைப்படும் பிற விடயங்களைச் செய்யவும் கூடிய திறனைப் பயனர்களுக்கு மீள்விக்கும். இதுதான் நீங்கள் செய்ய விரும்புகிறீர்கள் என்பதைத் தயவுசெய்து உறுதிப்படுத்துங்கள்.",
+"lockconfirm" => "ஆம், நான் உண்மையில் தரவுத்தளத்தைப் பூட்ட விரும்புகிறேன்.",
+"unlockconfirm" => "ஆம், நான் உண்மையில் தரவுத்தளத்தைத் திறக்க விரும்புகிறேன்.",
+"lockbtn" => "தரவுத்தளத்தைப் பூட்டுக",
+"unlockbtn" => "தரவுத்தளத்தைத் திறக்கவும்",
+"locknoconfirm" => "நீங்கள் உறுதிப்படுத்தல் கட்டத்துள் குறியிடவில்லை.",
+"lockdbsuccesssub" => "தரவுத்தளப் பூட்டல் வெற்றி",
+"unlockdbsuccesssub" => "தரவுத்தளப் பூட்டு நீக்கப்பட்டது",
+"lockdbsuccesstext" => "விக்கிபீடியா தரவுத்தளம் பூட்டப் பட்டது.
+<br />பராமரிப்பு முடிவடைந்ததும் பூட்டை நீக்க மறவாதீர்.",
+"unlockdbsuccesstext" => "விக்கிபீடியா தரவுத்தளம் திறக்கப்பட்டது.",
+
+# Move page
+#
+"movepage" => "பக்கத்தை நகர்த்து",
+"movepagetext" => "பின்வரும் படிவத்தைப் பயன்படுத்துவது, பக்கமொன்றின் பெயரை மாற்றி, இதனுடைய முழு வரலாற்றையும் புதிய பெயருக்கு நகர்த்தும். பழைய தலைப்பு, புதிய பக்கத்துக்கான ஒர் வழிகாட்டும் பக்கமாக ஆகும். பழைய பக்கத் தலைப்புக்கு உள்ள இணைப்புக்கள் மாறமாட்டா; இரட்டை அல்லது முறிந்த வழிமாற்றுகள் உள்ளனவா என்பதைச் சரி பார்த்து உறுதிசெய்யவும். இணைப்புகள் எவ்விடத்துக்குச் சென்றடைய வேண்டுமோ அவ்விடத்தைத் தொடர்ந்தும் குறிப்பதை உறுதி செய்து கொள்வது உங்கள் பொறுப்பாகும்.<br />
+ஏற்கெனவே புதிய தலைப்பில் ஒரு பக்கம் இருந்தால், இந்தப் பக்கம் வெறுமையாகவோ அல்லது ஒரு வழிமாற்றுப் பக்கமாகவோ இருப்பதுடன் பழைய தொகுப்பு வரலாறும் இல்லாதிருந்தால்தான், இப் பக்கம் நகர்த்தப்படும் என்பதைக் கவனிக்கவும். தற்செயலாக, நீங்கள் தவறு செய்துவிட்டால், எந்தப் பெயரிலிருந்து பெயர் மாற்றம் செய்தீர்களோ அதே பெயருக்கு மீண்டும் மாற்றமுடியும் என்பதுடன் ஏற்கெனவே இருக்கும் பக்கமொன்றை மேலெழுத (overwrite) முடியாது என்பதையும் இது குறிக்கின்றது.
+<b>எச்சரிக்கை!</b>
+இது பிரபலமான ஒரு பக்கத்துக்குச் செய்யும் கடுமையானதும், எதிர்பாராததுமான மாற்றமாக இருக்கக்கூடும்; தொடர்வதற்கு முன் இதன் விளைவுகளை விளங்கிக்கொண்டிருக்கிறீர்கள் என்பதை உறுதிப்படுத்திக் கொள்ளவும்.",
+"movepagetalktext" => "*நீங்கள் பக்கத்தைப் பெயர்வெளிகள் (namespaces) இடையே நகர்த்துகிறீர்கள் என்றோ,
+*ஒரு வெறுமையில்லாத பேச்சுப் பக்கம் புதிய பெயரில் ஏற்கெனவேயிருந்தோ, அல்லது
+*நீங்கள் கீழேயுள்ள கட்டத்தில் குறியிடாமல் விடுகிறீர்கள் என்றோ.
+ '''இல்லாவிடில்''' சேர்ந்திருக்கும் பேச்சுப் பக்கம், ஏதாவது இருந்தால், தன்னியக்கமாக அதனுடன் நகர்த்தப்படும்.
+இப்படியான சந்தர்ப்பங்களில், விரும்பினால், நகர்த்தலையோ அல்லது ஒன்றிணைத்தலையோ நீங்கள் கைவினையாகச் செய்யவேண்டியிருக்கும்.",
+"movearticle" => "பக்கத்தை இடம்பெயர்",
+"movenologin" => "புகுபதிகை செய்யப்படவில்லை",
+"movenologintext" => "இப் பக்கத்தை இடம்பெயர்ப்பதற்கு, நீங்கள் ஒரு பதிவு செய்யப்பட்ட பயனராயும்
+[[Special:Userlogin|புகுபதிகை செய்தும்]]
+இருக்க வேண்டும்.",
+"newtitle" => "புதிய தலைப்புக்கு",
+"movepagebtn" => "பக்கத்தை நகர்த்து",
+"pagemovedsub" => "நகர்த்தல் வெற்றி",
+"pagemovedtext" => "பக்கம் \"[[$1]]\" \"[[$2]]\" க்கு நகர்த்தப்பட்டுள்ளது.",
+"articleexists" => "அந்தப் பெயரையுடைய பக்கம் ஏற்கெனவே உள்ளது அல்லது நீங்கள் தெரிவு செய்த பெயர் செல்லுபடியாகாது. தயவுசெய்து வேறு பெயரைத் தெரியவும்.",
+"talkexists" => "பக்கம் வெற்றிகரமாக நகர்த்தப்பட்டது, ஆனால் பேச்சுப் பக்கத்தை நகர்த்த முடியவில்லை ஏனெனில் புதிய தலைப்பில் இன்னொன்று உள்ளது. தயவுசெய்து கையால் (manually) ஒன்றுகலக்கவும்.",
+"movedto" => "நகர்த்தப்பட்ட இடம்",
+"movetalk" => "தக்கதாயின் \"talk\" பக்கத்தையும் நகர்த்தவும்.",
+"talkpagemoved" => "ஒத்த பேச்சுப் பக்கமும் நகர்த்தப்பட்டுள்ளது.",
+"talkpagenotmoved" => "ஒத்த பெச்சுப் பக்கம் <strong>நகர்த்தப்படவில்லை</strong>.",
+
+"export" => "ஏற்றுமதிப் பக்கங்கள்",
+"exporttext" => "ஒரு பக்கத்தினதோ அல்லது ஒரு தொகுதி பக்கங்களினதோ உரையையும், தொகுப்பு வரலாற்றையும், ஏதாவது XML இல் சுற்றி (wrapped in) ஏற்றுமதி செய்ய முடியும்; இதைப் மீடியாவிக்கி மென்பொருளிலியங்கும் இன்னொரு விக்கிக்கு இறக்குமதி செய்து, அதில் மாற்றம் செய்யலாம் அல்லது உங்கள் தனிப்பட்ட தேவைக்கு வைத்துக்கொள்ளலாம்.",
+"exportcuronly" => "நடப்புத் திருத்தத்தை மட்டும் சேர்க்கவும்",
+);
+
+
+?>
diff --git a/languages/messages/MessagesTe.php b/languages/messages/MessagesTe.php
new file mode 100644
index 000000000000..41fb86f86dff
--- /dev/null
+++ b/languages/messages/MessagesTe.php
@@ -0,0 +1,844 @@
+<?php
+/** Telugu (Telugu)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'మీడియా',
+ NS_SPECIAL => 'ప్రత్యేక',
+ NS_MAIN => '',
+ NS_TALK => 'చర్చ',
+ NS_USER => 'సభ్యుడు',
+ NS_USER_TALK => 'సభ్యులపై_చర్చ',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_చర్చ',
+ NS_IMAGE => 'బొమ్మ',
+ NS_IMAGE_TALK => 'బొమ్మపై_చర్చ',
+ NS_MEDIAWIKI => 'మీడియావికీ',
+ NS_MEDIAWIKI_TALK => 'మీడియావికీ_చర్చ',
+ NS_TEMPLATE => 'మూస',
+ NS_TEMPLATE_TALK => 'మూస_చర్చ',
+ NS_HELP => 'సహాయము',
+ NS_HELP_TALK => 'సహాయము_చర్చ',
+ NS_CATEGORY => 'వర్గం',
+ NS_CATEGORY_TALK => 'వర్గం_చర్చ'
+);
+
+$namespaceAliases = array(
+ 'సభ్యునిపై_చర్చ' => NS_USER_TALK,
+ 'బొమ్మపై_చర్చ' => NS_IMAGE_TALK
+);
+
+
+$linkTrail = "/^([\xE0\xB0\x81-\xE0\xB1\xAF]+)(.*)$/sDu";
+
+// nobody seems to use these anymore
+/*$digitTransformTable = array(
+ '0' => '౦',
+ '1' => '౧',
+ '2' => '౨',
+ '3' => '౩',
+ '4' => '౪',
+ '5' => '౫',
+ '6' => '౬',
+ '7' => '౭',
+ '8' => '౮',
+ '9' => '౯'
+);*/
+
+$messages = array(
+'tog-underline' => 'లింకుల కింద గీతగీయి:',
+'tog-highlightbroken' => 'తెగిపోయిన లింకులను <a href="" class="new">ఇలా చూపించు</a> (ఇంకో పధ్ధతి: <a href="" class="internal">?</a>).',
+'tog-justify' => 'పేరాలను ఇరు పక్కలా సమానంగా సర్దు',
+'tog-hideminor' => 'ఇటీవలి మార్పులలో చిన్న మార్పులను దాచిపెట్టు',
+'tog-usenewrc' => 'మెరుగైన ఇటీవలి మార్పులు (జావాస్క్రిప్టు)',
+'tog-numberheadings' => 'శీర్షికలకు ఆటోమాటిక్‌గా వరుస సంఖ్యలు పెట్టు',
+'tog-showtoolbar' => 'మార్పు పరికరాలపెట్టె చూపించు (జావాస్క్రిప్టు)',
+'tog-editondblclick' => 'డబుల్‌ క్లిక్కు జరిగినప్పుడు పేజీలని మార్చు (జావాస్క్రిప్టు)',
+'tog-editsection' => '[మార్చు] లింకు ద్వారా విభాగం మార్పు కావాలి',
+'tog-editsectiononrightclick'=> 'విభాగం పేరు మీద కుడి క్లిక్కుతో విభాగం<br /> మార్పు కావాలి (జావాస్క్రిప్టు)',
+'tog-showtoc' => 'విషయసూచిక చూపించు (3 కంటే ఎక్కువ శీర్షికలున్న పేజీలకు)',
+'tog-rememberpassword' => 'అన్ని సెషన్లలోనూ గుర్తుపెట్టుకో',
+'tog-editwidth' => 'మార్పుల బాక్సు పూర్తి వెడల్పు ఉంటుంది',
+'tog-watchdefault' => 'నేను మార్చె అన్ని పేజీలను నా వీక్షణ జాబితాకు చేర్చు',
+'tog-minordefault' => 'ప్రత్యేకంగా ఏమీ చెయ్యకపొతే అన్ని మార్పులను చిన్న మార్పులుగా గుర్తించు',
+'tog-previewontop' => 'వ్యాసం మార్పుల తరువాత ఎలావుంటుందో మార్పుల‌ బాక్సుకు పైన చూపు',
+'tog-previewonfirst' => 'మొదటి మార్పు చెసినప్పుడు వ్యాసం ఎలావుంటుందో ముందుగా చూపించు',
+'tog-nocache' => 'పాత పేజీలను దాచి వాటిని తరువాత చూపవద్దు',
+'tog-enotifwatchlistpages'=> 'నేను వీక్షించే పేజీల మార్పులు జరిగినప్పుడు నాకు ఈ-మెయిల్‌ పంపించు',
+'tog-enotifusertalkpages'=> 'నా గురించి చర్చ పేజీలో మార్పు జరిగినపుడు నాకు ఈ-మెయిల్‌ పంపించు',
+'tog-enotifminoredits' => 'చిన్న మార్పుల గురించి కూడా నాకు ఈ-మెయిల్‌ పంపించు',
+'tog-enotifrevealaddr' => 'ప్రకటన మెయిల్‌లలో నా ఈ-మెయిల్‌ చిరునామా చూపించు',
+'tog-shownumberswatching'=> 'వీకషకుల సంఖ్యను చూపించు',
+'tog-fancysig' => 'సంతకం మాత్రమే (ఆటోమెటిక్‌ లింకు లేకుండా)',
+'tog-externaleditor' => 'ఏమీ చేయనప్పుడు ముందుగా బయటి ఎడిటరును వాడు',
+'underline-always' => 'ఎల్లప్పుడూ',
+'underline-never' => 'ఎప్పటికీ వద్దు',
+'sunday' => 'ఆదివారము',
+'monday' => 'సోమవారము',
+'tuesday' => 'మంగళవారము',
+'wednesday' => 'బుధవారము',
+'thursday' => 'గురువారము',
+'friday' => 'శుక్రవారము',
+'saturday' => 'శనివారము',
+'january' => 'జనవరి',
+'february' => 'ఫిబ్రవరి',
+'march' => 'మార్చి',
+'april' => 'ఏప్రిల్',
+'may_long' => 'మే',
+'june' => 'జూన్',
+'july' => 'జూలై',
+'august' => 'ఆగష్టు',
+'september' => 'సెప్టెంబర్',
+'october' => 'అక్టోబర్',
+'november' => 'నవంబర్',
+'december' => 'డిసెంబర్',
+'jan' => 'జనవరి',
+'feb' => 'ఫిబ్రవరి',
+'mar' => 'మార్చి',
+'apr' => 'ఏప్రిల్',
+'may' => 'మే',
+'jun' => 'జూన్',
+'jul' => 'జూలై',
+'aug' => 'ఆగష్టు',
+'sep' => 'సెప్టెంబర్',
+'oct' => 'అక్టోబర్',
+'nov' => 'నవంబర్',
+'dec' => 'డిసెంబర్‌',
+'categories' => 'వర్గాలు',
+'pagecategories' => '{{PLURAL:$1|వర్గం|వర్గాలు}}',
+'category_header' => '"$1" వర్గంలో వ్యాసాలు',
+'subcategories' => 'ఉపవర్గములు',
+'mainpage' => 'మొదటి పేజీ',
+'portal' => 'సముదాయ పందిరి',
+'about' => 'గురించి',
+'aboutsite' => '{{SITENAME}} గురించి',
+'aboutpage' => 'Project:గురించి',
+'article' => 'వ్యాసము',
+'help' => 'సహాయము',
+'bugreportspage' => 'Project:Bug reports',
+'sitesupport' => 'విరాళములు',
+'sitesupport-url' => 'Project:Site support',
+'faq' => 'తరచూ అడిగే ప్రశ్నలు',
+'faqpage' => 'Project:తరచూ అడిగే ప్రశ్నలు',
+'newwindow' => '(కొత్త విండోలో వస్తుంది)',
+'cancel' => 'రద్దు',
+'qbpageoptions' => 'ఈ పేజీ',
+'qbspecialpages' => 'ప్రత్యేక పేజీలు',
+'moredotdotdot' => 'ఇంకా...',
+'mypage' => 'నా పేజీ',
+'mytalk' => 'నా గురించి చర్చ',
+'anontalk' => 'ఈ ఐ.పి.కి సంబంధించిన చర్చ',
+'navigation' => 'మార్గదర్శకము',
+'currentevents' => 'ప్రస్తుత ఘటనలు',
+'disclaimers' => 'అస్వీకారములు',
+'disclaimerpage' => 'Project:సాధారణ అస్వీకారము',
+'errorpagetitle' => 'లోపం',
+'returnto' => 'తిరిగి $1 పేజీకి వెళ్లు.',
+'tagline' => '{{SITENAME}} నుండి',
+'search' => 'అన్వేషణ',
+'searchbutton' => 'అన్వేషణ',
+'go' => 'వెళ్లు',
+'searcharticle' => 'వెళ్లు',
+'history' => 'పేజీ చరిత్ర',
+'history_short' => 'చరిత్ర',
+'updatedmarker' => 'నేను కిందటిసారి వచ్చిన తరువాత జరిగిన మార్పులు',
+'printableversion' => 'ముద్రణా సంచిక',
+'permalink' => 'శాశ్వత లింకు',
+'print' => 'ముద్రించు',
+'edit' => 'మార్చు',
+'editthispage' => 'ఈ పేజీని మార్చు',
+'delete' => 'తుడిచివేయి',
+'deletethispage' => 'ఈ పేజీని తుడిచివేయి',
+'undelete_short' => '{{PLURAL:$1|ఒక్క రచనను|$1 రచనలను}} పునఃస్థాపించు',
+'protect' => 'కాపాడు',
+'protectthispage' => 'ఈ పేజీని సంరక్షించు',
+'newpage' => 'కొత్త పేజీ',
+'talkpage' => 'ఈ పేజీని చర్చించు',
+'specialpage' => 'ప్రత్యేక పేజీ',
+'personaltools' => 'స్వకీయమైన పరికరాలు',
+'postcomment' => 'వ్యాఖ్యానము చేయండి',
+'articlepage' => 'వ్యాసము చూడండి',
+'talk' => 'చర్చ',
+'toolbox' => 'పరికరాలపెట్టె',
+'imagepage' => 'బొమ్మ పేజీని చూపించు',
+'viewtalkpage' => 'చర్చ చూపించు',
+'otherlanguages' => 'ఇతర భాషలలొ',
+'redirectedfrom' => '($1 నుండి మళ్ళించబడింది)',
+'redirectpagesub' => 'దారిమార్పు పేజీ',
+'lastmodifiedat' => 'ఈ పేజీకి $2, $1న చివరి మార్పు జరిగినది.',
+'viewcount' => 'ఈ పేజీ {{PLURAL:$1|ఒక్క సారి|$1 సార్లు}} దర్శించబడింది.',
+'copyright' => 'విషయ సంగ్రహం $1 కి లోబడి లభ్యం.',
+'protectedpage' => 'సంరక్షణలోని పేజీ',
+'badaccess' => 'అనుమతి లోపం',
+'ok' => 'సరే',
+'pagetitle' => '$1 - {{SITENAME}}',
+'youhavenewmessages' => 'మీకు $1 ఉన్నాయి ($2).',
+'newmessageslink' => 'కొత్త సందేశాలు',
+'newmessagesdifflink' => 'క్రితం సంచికతో గల తేడాలు',
+'editsection' => '<small>మార్చు</small>',
+'toc' => 'విషయ సూచిక',
+'showtoc' => 'చూపించు',
+'thisisdeleted' => '$1ను చూస్తారా, పునస్స్థాపిస్తారా?',
+'restorelink' => '{{PLURAL:$1|ఒక్క తొలగించబడిన మార్పు|$1 తొలగించబడిన మార్పులు}}',
+'nstab-main' => 'వ్యాసము',
+'nstab-user' => 'సభ్యుని పేజీ',
+'nstab-media' => 'మాధ్యమం',
+'nstab-special' => 'ప్రత్యేక',
+'nstab-image' => 'ఫైలు',
+'nstab-mediawiki' => 'సందేశము',
+'nstab-template' => 'మూస',
+'nstab-help' => 'సహాయము',
+'nstab-category' => 'వర్గము',
+'nosuchspecialpage' => 'అటువంటి ప్రత్యేక పేజీ లేదు',
+'nospecialpagetext' => 'మీరు అడిగిన ప్రత్యేకపేజీ సరైనది కాదు. సరైన ప్రత్యేకపేజీల జాబితా [[Special:Specialpages]] వద్ద ఉంది.',
+'error' => 'లోపం',
+'noconnect' => 'సారీ! సాంకేతిక ఇబ్బందుల వలన డాటాబేసు సర్వరును సంప్రదించలేక పోతున్నాం.<br />
+$1',
+'cachederror' => 'కింది పీజీ ముందే సేకరించి పెట్టుకున్నది, కాబట్టి తాజా మార్పులు దీనిలో లేకపోవచ్చు.',
+'laggedslavemode' => 'హెచ్చరిక: పేజీలో ఇటీవల జరిగిన మార్పులు ఉండకపోవచ్చు.',
+'readonly' => 'డేటాబేసు లాక్‌చెయ్యబడింది',
+'readonlytext' => 'డేటాబేసు ప్రస్తుతం లాకు చేయబడింది. మార్పులు, చేర్పులు ప్రస్తుతం చెయ్యలేరు. మామూలుగా జరిగే నిర్వహణ కొరకు ఇది జరిగి ఉండవచ్చు; అది పూర్తి కాగానే తిరిగి మామూలుగా పనిచేస్తుంది.
+
+దీనిని లాకు చేసిన నిర్వాహకుడు ఇలా తెలియజేస్తున్నాడు: $1',
+'readonly_lag' => 'అనుచర (స్లేవ్) డేటాబేసు సర్వర్లు, ప్రధాన (మాస్టరు) సర్వరును అందుకునేందుకుగాను, డేటాబేసు ఆటోమాటిక్‌గా లాకు అయింది.',
+'filecopyerror' => 'ఫైలు "$1"ని "$2"కు కాపీ చెయ్యటం కుదరలేదు.',
+'filerenameerror' => 'ఫైలు "$1" పేరును "$2"గా మార్చటం కుదరలేదు.',
+'filedeleteerror' => 'ఫైలు "$1"ని తీసివేయటం కుదరలేదు.',
+'filenotfound' => 'ఫైలు "$1" కనబడలేదు.',
+'unexpected' => 'అనుకోని విలువ: "$1"="$2".',
+'badarticleerror' => 'ఈ పేజీపై ఈ పని చేయడం కుదరదు.',
+'cannotdelete' => 'అడిగిన పేజీ లేదా ఫైలును తీసివేయటం కుదరలేదు. (ఇప్పటికే ఎవరైనా తీసివేసి ఉండవచ్చు)',
+'perfdisabled' => 'క్షమించండి! ఈ అంశంవలన డేటాబేసు బాగా స్లో అయిపోయి, ఎవరూ వికీని వాడుకోలేరు. కాబట్టి, ప్రస్తుతానికి ఈ అంశాన్ని అందుబాటులో లేకుండా చేస్తున్నాం.',
+'perfcached' => 'కింది డేటా ముందే సేకరించి పెట్టుకున్నది. కాబట్టి తాజా డేటాతో పోలిస్తే తేడాలుండవచ్చు.',
+'viewsource' => 'మూలాన్ని చూపించు',
+'protectedtext' => 'ఈ పేజీకి మార్పులు జరగకుండా సంరక్షించబడినది.
+
+ఈ పేజీ మూలాన్ని మీరు వీక్షించవచ్చు లేదా కాపీ తీయవచ్చు:',
+'logouttitle' => 'సభ్యుని నిష్క్రమణ',
+'logouttext' => '<strong>మీరు వికీపీడియా నుండి నిష్క్రమించారు.</strong><br />
+{{SITENAME}}ను అజ్ఞాతంగా వడుతుండొచ్చు లేదా వేరే సభ్యనామంతో గాని ఇదే సభ్యనామంతో గాని మళ్ళీ లాగిన్‌ కావచ్చు. ఒక గమనిక: బ్రౌజరులోని పాత పేజి కాపీలను తీసివేసే వరకు కొన్ని పేజీలు మీరింకా లాగిన్‌ అయి ఉన్నట్లు గానే చూపించవచ్చు.',
+'welcomecreation' => '== స్వాగతం, $1! ==
+
+మీ అకౌంటు సృష్టించబడింది. మీ {{SITENAME}} అభిరుచులను మార్చుకోవడం మరువకండి.',
+'loginpagetitle' => 'సభ్యుని లాగిన్',
+'yourname' => 'సభ్యనామము',
+'yourpassword' => 'మీ సంకేతపదం',
+'yourpasswordagain' => 'మళ్లీ సంకేతపదం ఇవ్వండి',
+'remembermypassword' => 'నన్ను గుర్తుపెట్టుకో',
+'yourdomainname' => 'మీ డోమైను',
+'loginproblem' => '<b>మీ లాగిన్‌తో ఏదో ఇబ్బంది ఉంది.</b><br />మళ్ళీ ప్రయత్నించండి!',
+'alreadyloggedin' => '<strong>$1 గారు, మీరిప్పటికే లాగిన్ అయి ఉన్నారు!</strong><br />',
+'login' => 'లాగిన్',
+'loginprompt' => '{{SITENAME}}లోకి లాగిన్‌ అవ్వాలంటే, మీ బ్రౌజరు కూకీలను దాచగలిగి ఉండాలి.',
+'userlogin' => 'అకౌంటు సృష్టించు లేదా లాగిన్ అవ్వు',
+'logout' => 'నిష్క్రమించు',
+'userlogout' => 'నిష్క్రమించు',
+'notloggedin' => 'లాగిన్ అయిలేరు',
+'nologin' => 'సభ్యత్వం లేదా? $1.',
+'nologinlink' => 'ఎకౌంటు సృష్టించుకోండి',
+'createaccount' => 'అకౌంటు సృష్టించు',
+'gotaccount' => 'ఇప్పటికే ఎకౌంటు ఉందా? $1.',
+'gotaccountlink' => 'లాగిన్ అవండి',
+'createaccountmail' => 'ఈ-మెయిల్‌ ద్వారా',
+'badretype' => 'మీరు ఇచ్చిన రెండు సంకేతపదాలు ఒకదానితో మరొకటి సరిపోలడం లేదు.',
+'userexists' => 'ఈ సభ్యనామం ఇప్పటికే వాడుక లో ఉంది. వేరే పేరు ఎంచుకోండి.',
+'youremail' => 'మీ ఈ-మెయిల్*',
+'yourrealname' => 'అసలు పేరు*',
+'yourlanguage' => 'భాష:',
+'yournick' => 'ముద్దు పేరు',
+'email' => 'ఈ-మెయిల్',
+'prefs-help-email-enotif'=> 'మీరు ఈ-మెయిల్‌ ప్రకటనలు కావాలని ఎంచుకుంటే, అవి ఈ చిరునామాకే వస్తాయి.',
+'prefs-help-realname' => '* అసలు పేరు (తప్పనిసరి కాదు): మీ అసలు పేరు ఇవాలని ఎంచికుంటే, మీ రచనలపై మీ పేరు దరకాస్తు అవుతుంది.',
+'loginerror' => 'లాగిన్ దోషము',
+'prefs-help-email' => '* ఈ-మెయిల్‌ (తప్పనిసరి కాదు): మీ ఈ-మెయిల్‌ చిరునామా బయట పెట్టకుండానే, ఇతరులు మిమ్మల్ని సంప్రదించడానికి వీలు కలగ చేస్తుంది.',
+'nocookieslogin' => 'సభ్యుల లాగిన్ కొరకు {{SITENAME}} కూకీలను వాడుతుంది. మీ కంప్యూటర్ కూకీలు దాచుకోటానికి సిద్ధంగా లేదు. దానిని సిద్ధంచేసి మళ్ళీ ప్రయత్నించండి.',
+'noname' => 'మీరు సరైన సభ్యనామం ఇవ్వలేదు.',
+'loginsuccesstitle' => 'లాగిన్ విజయవంతమైనది',
+'loginsuccess' => 'సుస్వాగతము "$1" గారు, మీరు ఇప్పుడు {{SITENAME}}లో ప్రవేశించారు.',
+'nosuchuser' => '"$1" అనే పేరుతో సభ్యులు లేరు. పేరు సరి చూసుకోండి, లేదా కింది ఫారం ఉపయోగించి, కొత్త అకౌంటు సృష్టించండి.',
+'nosuchusershort' => '"$1" అనే పేరుతో సభ్యులు లేరు. పేరు సరి చూసుకోండి.',
+'wrongpassword' => 'ఈ సంకేతపదం సరైనది కాదు. దయచేసి మళ్లీ ప్రయత్నించండి.',
+'wrongpasswordempty' => 'ఖాళీ సంకేతపదం ఇచ్చారు. మళ్ళీ ప్రయత్నించండి.',
+'mailmypassword' => 'నా సంకేతపదం మర్చిపోయాను, కొత్తది ఈ-మెయిల్‌లొ పంపించు',
+'passwordremindertitle' => '{{SITENAME}} నుండి సంకేతపదము యొక్క జ్ఞాపక సూచకం',
+'passwordremindertext' => 'కొత్త {{SITENAME}} ($4) సంకేతపదం పంపించమని ఎవరో (బహుశ మీరే, ఐ.పీ. చిరునామా $1 నుండి) అడిగారు. సభ్యుడు "$2" యొక్క కొత్త సంకేతపదం "$3". మీరు లాగిన్‌ అయి, సంకేత పదం మార్చుకోవాలి.
+
+మరెవరో ఈ మనవి చేసినా లేదా మీకు మీ పాత సంకేతపదం గుర్తుకు వచ్చి దానిని మార్చకుడదని అనుకున్నా, మీరు ఈ సందేశాన్ని మరచి మీ పాత సంకేతపదాన్ని వాడటం కొనసాగించవచ్చు.',
+'noemail' => 'సభ్యుడు "$1"కి ఈ-మెయిల్‌ చిరునామా నమోదయి లేదు.',
+'passwordsent' => '"$1" గారు! మీరు నమోదు చేసుకున్న ఈ-మెయిల్ చిరునామాకు ఒక కొత్త సంకేతపదము పంపబడినది.
+అది అందిన తర్వాత దయచేసి మరలా లాగిన్‌ అవ్వండి.',
+'eauthentsent' => 'ఇచ్చిన ఈ-మెయిల్ అడ్రసుకు ధృవీకరణ మెయిల్ వెళ్ళింది.
+మరిన్ని మెయిళ్ళు పంపే ముందు, మీరు ఆ మెయిల్‌లో సూచించినట్లుగా ఈ చిరునామా మీదేననిి ధృవీకరించండి.',
+'acct_creation_throttle_hit'=> 'క్షమించండి, మీరిప్పటికే $1 అకౌంట్లు సృష్టించారు. ఇహ కుదరదు.',
+'emailauthenticated' => 'మీ ఈ-మెయిల్ చిరునామా $1న ధృవీకరింపబడింది.',
+'emailnotauthenticated' => 'మీ ఈ-మెయిల్‌ చిరునామా <ధృవీకరణ ఇంకా కాలేదు</s. కింద ఇచ్చిన వాటికి సంబంధించి ఈ-మెయిల్‌ పంపబడదు.',
+'noemailprefs' => 'కింది అంశాలు పని చెయ్యటానికి ఈ-మెయిల్‌ చిరునామాను నమొదుచయ్యండి.',
+'emailconfirmlink' => 'మీ ఈ-మెయిల్ చిరునామాను ధృవీకరించండి',
+'extlink_tip' => 'బయటి లింకు (దాని ముందు http:// ఇవ్వటం మరువకండి)',
+'sig_tip' => 'టైంస్టాంపుతో సహా మీ సంతకం',
+'hr_tip' => 'అడ్డం లైను (అరుదుగా వాడండి)',
+'summary' => 'సారాంశము',
+'subject' => 'విషయం/శీర్షిక',
+'minoredit' => 'ఇది ఒక చిన్న మార్పు',
+'watchthis' => 'ఈ పేజీ మీద కన్నేసి ఉంచు',
+'savearticle' => 'పేజీ భధ్రపరచు',
+'preview' => 'సరిచూడు',
+'showpreview' => 'సరిచూడు',
+'showdiff' => 'తేడాలు చూపించు',
+'anoneditwarning' => 'మీరు లాగిన్ అయిలేరు. ఈ పేజీ చరిత్రలో మీ ఐ.పి.అడ్రసు నమొదు అవుతుంది.',
+'blockedtitle' => 'సభ్యునిపై నిరోధం అమలయింది',
+'blockedtext' => 'మీ సభ్యనామం లేదా ఐ.పి.అడ్రసును $1 నిరోధించారు.
+వారు ఇచ్చిన కారణం:<br />\'\'$2\'\'<br />ఈ నిరోధంపై చర్చించేందుకు $1ను గాని, మరెవరైనా [[Project:నిర్వాహకులు|నిర్వాహకులను]] గాని సంప్రదించండి.
+
+[[Special:Preferences|మీ అభిరుచులలో]] మీ ఈ-మెయిల్ అడ్రసు ఇచ్చిఉంటే తప్ప, "ఈ సభ్యునికి ఈ-మెయిల్ పంపు" అనే అంశాన్ని వాడుకోలేరని గమనించండి.
+
+మీ ఐ.పి.అడ్రసు $3. మీరు రాయబోయే ప్రతి జాబులోను ఈ అడ్రసును కూడా రాయండి.',
+'whitelistedittitle' => 'మార్పులు చెయ్యడానికి లాగిన్‌ అయి ఉండాలి',
+'whitelistedittext' => 'పేజీలకి మార్పులు చెయ్యడానికి మీరు $1 అయి ఉండాలి.',
+'whitelistreadtitle' => 'చదవడానికి లాగిన్‌ అయి వుండాలి',
+'whitelistreadtext' => 'పేజీలు చదవడానికి [[Special:Userlogin|లాగిన్‌]] అయి ఉండాలి.',
+'whitelistacctitle' => 'మీకు అకౌంటు సృష్టించే అనుమతి లేదు',
+'whitelistacctext' => 'ఈ వికీలో అకౌంట్లను సృష్టించడానికి మీరు [[Special:Userlogin|లాగిన్‌]] అయి ఉండాలి, మరియు తగువిధమైన అనుమతులు ఉండాలి.',
+'confirmedittitle' => 'మార్పులు చేసేముందు ఈ-మెయిల్ చిరునామా ధృవీకరణ తప్పనిసరి',
+'confirmedittext' => 'పేజీల్లో మార్పులు చేసేముందు మీ ఈ-మెయిల్ చిరునామా ధృవీకరించాలి. [[Special:Preferences|మీ అభిరుచుల]]లో మీ ఈ-మెయిల్ చిరునామా రాసి, ధృవీకరించండి.',
+'loginreqtitle' => 'లాగిన్‌ ఆవసరము',
+'loginreqlink' => 'లాగిన్',
+'loginreqpagetext' => 'ఇతర పేజీలు చూడడానికి మీరు $1 అయి ఉండాలి.',
+'accmailtitle' => 'సంకేతపదం పంపించబడింది.',
+'accmailtext' => '"$1" యొక్క సంకేతపదం $2కు పంపించబడింది.',
+'newarticle' => '(కొత్తది)',
+'newarticletext' => 'ఈ లింకుకు సంబంధించిన పేజీ ఉనికిలొ లేదు. కింది పెట్టెలో మీ రచనను టైపు చేసి ఆ పేజీని సృష్టించండి (దీనిపై సమాచారం కొరకు [[Help:Contents|సహాయం]] పేజీ చూడండి). మీరిక్కడికి పొరపాటున వచ్చి ఉంటే, మీ బ్రౌజరు \'\'\'back\'\'\' మీట నొక్కండి.',
+'anontalkpagetext' => '----\'\'ఇది ఒక అజ్ఞాత సభ్యుని చర్చా పేజీ. ఆ సభ్యుడు ఇంకా అకౌంటు సృష్టించ లేదు, లేదా దానిని ఉపయోగించడం లేదు. కాబట్టి వారి ఐ.పీ. అడ్రసే ఆ సభ్యుని గుర్తింపు. ఆ ఐ.పి. అడ్రసు చాలా మంది సభ్యులు వాడే అవకాశం ఉంది. మీరూ ఓ అజ్ఞాత సభ్యులైతే, ఒకే ఐ.పీ. అడ్రసు కారణంగా వేరే సభ్యులకు ఉద్దేశించిన వ్యాఖ్యానాలు మీకూ వర్తించే అవకాశం ఉంది. ఇకనుండి ఈ అయోమయం లేకుండా ఉండాలంటే, [[Special:Userlogin|అకౌంటు సృష్టించండి లేదా లాగిన్‌ అవండి]].\'\'',
+'noarticletext' => 'ప్రస్తుతం ఈ పేజీ ఖాళీగా ఉంది, మీరు ఈ పేజీ శీర్షిక కొసం వెరె పెజీలు [[Special:Search/{{PAGENAME}}|వెతకవచ్చు]] లేదా [{{fullurl:{{FULLPAGENAME}}|action=edit}} ఈ పెజీని మార్చ] వచ్చు.',
+'clearyourcache' => '\'\'\'గమనిక:\'\'\' భద్రపరచిన తరువాత, మార్పులను చూడాలంటే మీ బ్రౌజరులొ దాచబడిన పాత కాపీని తీసివేయాల్సిరావచ్చు. \'\'\'మొజిల్లా/ ఫైర్‌ఫాక్స్‌/ సఫారి:\'\'\' \'\'shift\'\' కీని నొక్కి పెట్టి \'\'Reload\'\' నొక్కండి, లేదా \'\'Ctrl-shift-R\'\' నొక్కండి (యాపుల్‌ మాక్‌‌లో \'\'Cmd-shift-R\'\'); \'\'\'IE:\'\'\' \'\'Ctrl\'\' నొక్కి పెట్టి, \'\'Refresh\'\' నొక్కండి, లేదా \'\'Ctrl-F5\'\' నొక్కండి; \'\'\'కాంకరర్‌:\'\'\': \'\'Reload\'\' మీట నొక్కండి, లేదా \'\'F5\'\' నొక్కండి; \'\'\'ఒపేరా\'\'\'ను వాడే వారు \'\'Tools→Preferences\'\'కు వెళ్ళి పాత పేజీల కాపీలనన్నిటిని పూర్తిగా తీసివేయ వలసిన అవసరం రావచ్చు.',
+'note' => '<strong>గమనిక:</strong>',
+'previewnote' => '<strong>మీరు సరిచూసుకుంటున్నారు అంతే, ఇంకా భద్రపరచలేదని గుర్తుంచుకోండి!</strong>',
+'session_fail_preview' => '<strong>క్షమించండి! సెషను డేటా పోవడం వలన మీ మార్పులను స్వీకరించలేకపోతున్నాం.
+మళ్ళీ ప్రయత్నించండి. అయినా పని జరక్కపోతే, ఓ సారి లాగౌట్ అయి, మళ్ళీ లాగిన్ అయి ప్రయత్నించండి.</strong>',
+'previewconflict' => 'భద్రపరచిన తరువాత పై టెక్స్ట్‌ ఏరియాలోని టెక్స్టు ఇలాగ కనిపిస్తుంది.',
+'importing' => '$1 దిగుమతి అవుతూంది',
+'editing' => '$1కి మార్పులు',
+'editinguser' => '$1కి మార్పులు',
+'editingsection' => '$1కు మార్పులు (విభాగం)',
+'editconflict' => 'మార్పులలో ఘర్షణ: $1',
+'explainconflict' => 'మీరు మార్పులు చెయ్యడం మొదలుపెట్టిన తరువాత, ఇతర సభ్యులు ఈ పేజీలో మార్పులు చేసారు. పైన ఉన్న టెక్స్ట్ ఏరియాలో ప్రస్తుతపు సంచిక ఉన్నది. మీరు చేసిన మార్పులు కింద ఉన్న టెక్స్ట్ ఏరియాలో చూపించబడ్డాయి. మీరు మీ మార్పులను ప్రస్తుతపు సంచికతో విలీనం చెయ్యవలసి ఉంటుంది. మీరు "పేజీని భద్రపరుచు"ను నొక్కినపుడు, పైన ఉన్న సంచిక <b>మాత్రమే</b> భద్రపరచబడుతుంది.<br />',
+'editingold' => '<strong>హెచ్చ రిక: ఈ పేజీ యొక్క కాలం చెల్లిన సంచికను మీరు మరుస్తున్నారు. దీనిని భద్రపరిస్తే, ఆ సంచిక తరువాత ఈ పేజీలో జరిగిన మార్పులన్నీ పోతాయి.</strong>',
+'yourdiff' => 'తేడాలు',
+'copyrightwarning' => '{{SITENAME}}కు సమర్పించే అన్ని రచనలూ $2కు లోబడి ప్రచురింపబడినట్లుగా భావించబడతాయి (వివరాలకు $1 చూడండి). మీ రచనలను ఎవ్వరూ మార్చ రాదనీ లెదా వేరే ఎవ్వరూ వాడుకో రాదని మీరు భావిస్తే, ఇక్కడ ప్రచురించకండి.<br /> మీ స్వీయ రచనను గాని, సార్వజనీనమైన రచననుగాని, ఇతర ఉచిత వనరుల నుండి సేకరించిన రచననుగాని మాత్రమే ప్రచురిస్తున్నానని కూడా మీరు ప్రమాణం చేస్తున్నారు. <strong>కాపీహక్కులుగల రచనను తగిన అనుమతి లేకుండా సమర్పించకండి!</strong>',
+'longpagewarning' => '<strong>హెచ్చరిక: ఈ పేజీ సైజు $1 కిలోబైట్లు ఉంది; 32kb కంటే పెద్ద పేజీల తోటి కొన్ని బ్రౌజర్లు ఇబ్బంది పడతాయి. పేజీని చిన్న పేజీలుగా విడగొట్టడానికి అవకాశం ఉందేమో చూడండి. </strong>',
+'readonlywarning' => '<strong>హెచ్చరిక: నిర్వహణ కొరకు డేటాబేసు లాకు చెయ్యబడింది కాబట్టి, మీ మార్పులు, చేర్పులను ఇప్పుడు భద్రపరచలేరు. మీ మార్పులను ఒక టెక్స్టు ఫైలులోకి కాపీ చేసి, భద్రపరచుకొని, తరువాత సమర్పించండి.</strong>',
+'protectedpagewarning' => '<strong>హెచ్చరిక: ఈ పేజీ సంరక్షించబడినది, నిర్వాహకులు మాత్రమే మార్చగలరు. మీరు [[Project:Protected page guidelines|రక్షిత పేజీ మార్గదర్శకాలను]] పాటిస్తున్నారని నిర్ధారించుకోండి.</strong>',
+'semiprotectedpagewarning'=> '\'\'\'గమనిక:\'\'\' నమోదయిన సభ్యులు మాత్రమే మార్పులు చెయ్యగలిగేలా ఈ పేజీ లాకు చెయ్యబడింది.',
+'templatesused' => 'ఈ పేజీలో వాడిన మూసలు:',
+'revhistory' => 'సంచికల చరిత్ర',
+'nohistory' => 'ఈ పేజీకి మార్పుల చరిత్ర లేదు.',
+'revnotfound' => 'సంచిక కనబడలేదు',
+'currentrev' => 'ప్రస్తుతపు సంచిక',
+'revisionasof' => '$1 నాటి సంచిక',
+'previousrevision' => '←పాత సంచిక',
+'nextrevision' => 'దీని తరువాతి సంచిక→',
+'currentrevisionlink' => 'ప్రస్తుతపు సంచిక',
+'cur' => 'ప్రస్తుత',
+'next' => 'తరువాయి',
+'last' => 'గత',
+'histlegend' => 'తేడా ఎంపిక: సంచికల యొక్క రేడియో బాక్సులను ఎంచుకొని ఎంటర్‌ నొక్కండి, లేదా పైన/ కింద ఉన్న మీటను నొక్కండి.<br />
+సూచిక: (ప్రస్తుత) = ప్రస్తుత సంచికతో కల తేడాలు, (గత) = ఇంతకు ముందరి సంచికతో గల తేడాలు, చి = చిన్న మార్పు',
+'deletedrev' => '[తొలగించబడినది]',
+'histfirst' => 'తొట్టతొలి',
+'histlast' => 'చిట్టచివరి',
+'difference' => '(సంచికల మధ్య తేడా)',
+'editcurrent' => 'ఈ పేజీ యొక్క ప్రస్తుతపు సంచికను సరిదిద్దండి',
+'selectnewerversionfordiff'=> 'పోల్చేందుకు ఒక కొత్త సంచికను ఎంచుకోండి',
+'selectolderversionfordiff'=> 'పోల్చేందుకు ఒక పాత సంచికను ఎంచుకోండి',
+'compareselectedversions'=> 'ఎంచుకున్న సంచికలను పోల్చిచూడు',
+'searchresults' => 'అన్వేషణ ఫలితాలు',
+'searchresulttext' => '{{SITENAME}}లో అన్వేషించే విషయమై మరింత సమాచారం కొరకు [[Project:Searching|{{SITENAME}}లో అన్వేషణ]] చూడండి.',
+'badquery' => 'అన్వేషణ ప్రశ్న యొక్క రూపం సరిగా లేదు',
+'badquerytext' => 'అన్వేషణ చెయ్యలేక పోయాం.
+దీనికి కారణం మీరిచ్చిన ప్రశ్న మూడక్షరాల కంటే చిన్నది అయి ఉండవచ్చు. లేదా మీరు రాయడమే తప్పుగా రాసి ఉండవచ్చు, ఉదాహరణకు "ఇడ్లీ మరియు మరియు దోస". సరిచూసి మళ్ళీ ప్రయత్నించండి.',
+'matchtotals' => '"$1" కొరకు అన్వేషించగా $2 పేజీ పేర్లు, $3 పేజీలలోని పాఠం సరిపోలాయి',
+'titlematches' => 'వ్యాస శీర్షిక సరిపోయింది',
+'prevn' => 'క్రితం $1',
+'nextn' => 'తరువాతి $1',
+'showingresults' => '#<b>$2</b> తో మొదలుకొని, <b>$1</b> వరకు ఫలితాలు కింద ఉన్నాయి.',
+'showingresultsnum' => '#<b>$2</b> తో మొదలుకొని, <b>$3</b> ఫలితాలు కింద ఉన్నాయి.',
+'powersearch' => 'అన్వేషణ',
+'powersearchtext' => 'Search in namespaces:<br />$1<br />$2 List redirects<br />Search for $3 $9',
+'searchdisabled' => '{{SITENAME}} అన్వేషణ తాత్కాలికంగా పని చెయ్యడం లేదు. ఈలోగా మీరు గూగుల్‌ ఉపయోగించి అన్వేషించవచ్చు. ఒక గమనిక: గూగుల్‌ ద్వారా కాలదోషం పట్టిన ఫలితాలు రావడానికి అవకాశం ఉంది.',
+'blanknamespace' => '(మొదటి)',
+'preferences' => 'నా అభిరుచులు',
+'prefsnologin' => 'లాగిన్‌ అయిలేరు',
+'prefsnologintext' => 'అభిరుచులను నిశ్చయించుకోడానికి, మీరు [[Special:Userlogin|లాగిన్‌]] అయి ఉండాలి.',
+'prefsreset' => 'ఇదివరకటి అభిరుచులు పునరుధ్ధరించబడ్డాయి.',
+'changepassword' => 'సంకేతపదం మార్చండి',
+'skin' => 'తొడుగు',
+'dateformat' => 'తేదీ ఆకృతి',
+'datedefault' => 'ఏదైనా పరవాలేదు',
+'datetime' => 'తేదీ, సమయం',
+'prefs-personal' => 'సభ్యుని వివరాలు',
+'prefs-rc' => 'ఇటీవలి మార్పులు, మొలకలు',
+'prefs-misc' => 'ఇతరాలు',
+'saveprefs' => 'భధ్రపరచు',
+'resetprefs' => 'మునుపటి వలె',
+'oldpassword' => 'పాత సంకేతపదము',
+'newpassword' => 'కొత్త సంకేతపదము',
+'retypenew' => 'సంకేతపదం, మళ్ళీ',
+'textboxsize' => 'మార్పులు',
+'rows' => 'వరుసలు',
+'columns' => 'వరుసలు:',
+'searchresultshead' => 'అన్వేషణ',
+'resultsperpage' => 'పేజీకి ఫలితాలు:',
+'contextlines' => 'హిట్టుకు లైన్లు:',
+'contextchars' => 'లైనుకు సందర్భాలు:',
+'stubthreshold' => 'మొలకలు చూపేందుకు, కనీస బైట్లు',
+'recentchangescount' => '"ఇటీవలి మార్పులు"లో ఉండే శీర్షికలు',
+'savedprefs' => 'మీ అభిరుచులు భద్రపరచబడ్డయి.',
+'timezonelegend' => 'టైం జోను',
+'timezonetext' => 'సర్వరు సమయానికి (యు.టీ.సీ.), మీ స్థానిక సమయానికి మధ్య గల తేడా, గంటల్లో.',
+'localtime' => 'స్థానిక సమయం',
+'timezoneoffset' => 'తేడా¹',
+'servertime' => 'సర్వరు సమయం',
+'guesstimezone' => 'తేడాను బ్రౌజరు నుండి తీసుకో',
+'allowemail' => 'ఇతర సభ్యుల నుండి ఈ-మెయిల్ రానివ్వు',
+'defaultns' => 'డిఫాల్టుగా ఈ నేంస్పేసులలో అన్వేషించు:',
+'default' => 'డిఫాల్టు',
+'files' => 'ఫైళ్ళు',
+'changes' => 'మార్పులు, చేర్పులు',
+'recentchanges' => 'ఇటీవలి మార్పులు',
+'recentchangestext' => 'వికీలో ఇటీవలి కాలంలో జరిగిన మార్పులను ఈ పేజీలో చూడండి.',
+'rcnote' => '$3 నాటికి, గత <strong>$2</strong> రోజులలో చేసిన చివరి <strong>$1</strong> మార్పులు కింద ఉన్నాయి',
+'rcnotefrom' => '<b>$2</b> నుండి జరిగిన మార్పులు (<b>$1</b> వరకు చూపబడ్డాయి).',
+'rclistfrom' => '$1 వద్ద మొదలు పెట్టి కొత్త మార్పులు చూపించు',
+'rcshowhideminor' => 'చిన్న మార్పులను $1',
+'rcshowhidebots' => 'బాట్లను $1',
+'rcshowhideliu' => 'లాగిన్ అయ్యున్న సభ్యులను $1',
+'rcshowhideanons' => 'అజ్ఞాత సభ్యులను $1',
+'rcshowhidemine' => 'నా మార్పులను $1',
+'rclinks' => 'గత $2 రోజుల లోని చివరి $1 మార్పులను చూపించు <br />$3',
+'diff' => 'తేడాలు',
+'hist' => 'చరిత్ర',
+'hide' => 'దాచు',
+'show' => 'చూపించు',
+'minoreditletter' => 'చి',
+'newpageletter' => 'కొ',
+'number_of_watching_users_pageview'=> '[$1 వీక్షిస్తున్న సభ్యులు]',
+'upload' => 'ఫైలు అప్‌లోడ్',
+'uploadbtn' => 'ఫైలు అప్‌లోడు చెయ్యి',
+'reupload' => 'మళ్ళీ అప్‌లోడు చెయ్యి',
+'reuploaddesc' => 'మళ్ళీ అప్‌లోడు ఫారంకు వెళ్ళు.',
+'uploadnologin' => 'లాగిన్‌ అయిలేరు',
+'uploadnologintext' => 'ఫైలు అప్‌లోడు చెయ్యాలంటే, మీరు [[Special:Userlogin|లాగిన్‌]] కావాలి',
+'uploaderror' => 'అప్‌లోడు లోపం',
+'uploadtext' => 'కింది ఫారంను ఉపయోగించి ఫైళ్ళు అప్‌లోడు చెయ్యండి,
+ఇదివరలో అప్‌లోడు చేసిన బొమ్మలను చూడడానికి లేదా వెతకడానికి [[Special:Imagelist|అప్‌లోడు అయిన ఫైళ్ళ జాబితా]]కు వెళ్ళండి,
+అప్‌లోడులు, తొలగింపులు [[Special:Log/upload|అప్‌లోడు దినచర్య]]లొ నమోదవుతాయి.
+
+బొమ్మను ఏదైనా పేజీలో చేర్చడానికి,
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:File.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:File.png|ప్రత్యామ్న్యయ పాఠ్యం]]</nowiki>\'\'\'
+అని లింకు చెయ్యవచ్చు. లేదా
+* \'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:File.ogg]]</nowiki>\'\'\'
+అని రాసి సరాసరి బొమ్మ ఫైలుకే లింకు ఇవ్వవచ్చు.',
+'uploadlogpage' => 'అప్‌లోడ్ దినచర్య',
+'uploadlogpagetext' => 'ఇటీవల జరిగిన ఫైలు అప్‌లోడుల జాబితా ఇది.',
+'filename' => 'ఫైలు పేరు',
+'filedesc' => 'సారాంశం',
+'fileuploadsummary' => 'సారాంశం:',
+'filestatus' => 'కాపీహక్కు స్థితి',
+'filesource' => 'మూలం',
+'copyrightpage' => 'Project:ప్రచురణ హక్కులు',
+'copyrightpagename' => '{{SITENAME}} ప్రచురణ హక్కు',
+'ignorewarning' => 'హెచ్చరికను పట్టించుకోకుండా ఫైలును భద్రపరచు.',
+'ignorewarnings' => 'హెచ్చరికలను పట్టించుకోవద్దు',
+'minlength' => 'ఫైలు పేరులో కనీసం మూడు అక్షరాలు ఉండాలి.',
+'illegalfilename' => 'ఫైలు పేరు "$1"లోని కొన్ని అక్షరాలు, పేజీ శీర్షికలలో వాడకూడనివి ఉన్నాయి. ఫైలు పేరు మార్చి, మళ్ళీ అప్‌లోడు చెయ్యడానికి ప్రయత్నించండి.',
+'badfilename' => 'ఫైలు పేరు "$1"కి మార్చబడినది.',
+'badfiletype' => '".$1" అనేది బొమ్మ ఫైలుకి శిఫార్సు చేసిన ఆకృతి కాదు.',
+'largefile' => 'ఫైలుయొక్క పరిమాణం $1 బైట్లకంటె ఎక్కువ వుండకూడదని శిఫార్సు చేయటమైనది, ఈ ఫైలు $2 బైట్లు',
+'fileexists' => 'ఈ పేరుతో ఒక ఫైలు ఇప్పటికే ఉంది. దీనిని మీరు మార్చాలో లేదో తెలియకపోతె ఫైలు $1ని చూడండి.',
+'fileexists-forbidden' => 'ఈ పేరుతో ఇప్పటికే ఒక ఫైలు ఉంది; దీన్ని మరో పేరుతో అప్‌లోడు చెయ్యండి.
+[[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'ఈ పేరుతో ఇప్పటికే ఒక ఫైలు అందరి ఫైళ్ళ ఖజానాలో ఉంది; దీన్ని మరో పేరుతో అప్‌లోడు చెయ్యండి.
+[[Image:$1|thumb|center|$1]]',
+'fileuploaded' => 'ఫైలు $1 అప్‌లోడు అయింది.
+ఈ లింకు: $2 ను అనుసరించి వివరణ పేజీకి వెళ్ళి, ఫైలుకు
+సంబంధించిన వివరాలను - ఎక్కడినుండి వచ్చింది, ఎవరు ఎప్పుడు తయారుచేసారు,
+ఇంకా మీకు దీని గురించి తెలిసిన విషయాలు - అక్కడ రాయండి. ఇది ఒక బొమ్మ అయితే, దాన్ని పేజీలలో ఇలా
+వాడవచ్చు: <tt><nowiki>[[{{ns:Image}}:$1|thumb|వివరణ]]</nowiki></tt>',
+'uploadwarning' => 'అప్‌లోడు హెచ్చరిక',
+'savefile' => 'ఫైలు భధ్రపరచు',
+'uploadedimage' => '"[[$1]]" అప్‌లోడు అయింది',
+'uploaddisabled' => 'క్షమించండి, అప్‌లోడు చెయ్యడం ప్రస్తుతానికి ఆపబడింది',
+'uploadcorrupt' => 'ఫైలు చెడిపోయింది లేదా దాని పేరులోని పొడగింపు తప్పు. ఒకసారి సరిచూసి మళ్ళీ ప్రయత్నించండి.',
+'uploadvirus' => 'ఈ ఫైలులో వైరస్‌ ఉంది! వివరాలు: $1',
+'sourcefilename' => 'మూలం ఫైలు పేరు',
+'destfilename' => 'ఉద్దేశించిన ఫైలు పేరు',
+'imagelist' => 'ఫైళ్ళ జాబితా',
+'imagelisttext' => '$2 పేర్చిన $1 ఫైళ్ళ జాబితా ఇది.',
+'imagelistforuser' => '$1 అప్‌లోడు చేసిన బొమ్మలను మాత్రమే ఇది చూపిస్తుంది.',
+'showlast' => '$2 పేర్చిన గత $1 ఫైళ్ళను చూపించు',
+'byname' => 'పేర్ల వారీగ',
+'bydate' => 'తేదీ వారీగ',
+'bysize' => 'సైజు వారీగ',
+'imgdesc' => 'వివరణ',
+'imglegend' => 'సూచిక: (వివరణ) = ఫైలు వివరణను చూపు/మార్చు.',
+'imghistory' => 'ఫైలు చరిత్ర',
+'deleteimgcompletely' => 'ఈ ఫైలు యొక్క అన్ని సంచికలను తీసివేయి',
+'imghistlegend' => 'సూచిక: (ప్రస్తుతం) = ఇది ప్రస్తుతం ఉన్న ఫైలు, (తీసివేయి) = ఈ పాత సంచికను తీసివేయి, (తిప్పు) = ఈ పాత సంచికకు తిప్పు. <br /><i>తేదీని నొక్కి, ఆ తేదీన అప్‌లోడు చేసిన ఫైలును చూడండి</i>.',
+'imagelinks' => 'లింకులు',
+'linkstoimage' => 'కింది పేజీలలో ఈ ఫైలుకు లింకులు ఉన్నాయి:',
+'nolinkstoimage' => 'ఈ ఫైలుకు లింకున్న పేజీలు లేవు.',
+'shareduploadwiki' => 'మరింత సమాచారం కొరకు [$1 ఫైలు వివరణ పేజీ] చూడండి.',
+'shareduploadwiki-linktext'=> 'ఫైలు వివరణ పేజీ',
+'noimage' => 'ఆ పేరుతో ఫైలేమీ లేదు, మీరు $1',
+'noimage-linktext' => 'దాన్ని అప్‌లోడు చెయ్యవచ్చు',
+'listredirects' => 'దారిమార్పుల జాబితా',
+'unusedtemplates' => 'వాడని మూసలు',
+'statistics' => 'గణాంకాలు',
+'sitestats' => '{{SITENAME}} గణాంకాలు',
+'userstats' => 'సభ్యుల గణాంకాలు',
+'sitestatstext' => 'ప్రస్తుతము తెలుగు వికిపీడియాలో \'\'\'$2\'\'\' వ్యాసాలున్నాయి.
+{{SITENAME}}కు సంబంధించిన పేజీలు, "చర్చ" పేజీలు, "మొలక" పేజీలు, "దారిమార్పు" పేజీలు, మరియు {{SITENAME}}కు వ్యాసాలుగా భావించడానికి వీలుకాని ఇతర పేజీలు కలుపుకొని డేటాబేసులో మొత్తము \'\'\'$1\'\'\' సక్రమమైన పేజీలు వున్నాయి.
+
+\'\'\'$8\'\'\' ఫైళ్ళు అప్‌లోడ్ చేయబడ్డాయి.
+
+తెలుగు {{SITENAME}} ప్రారంభమైనప్పటినుండి మొత్తము \'\'\'$3\'\'\' పేజీ దర్శనలు, \'\'\'$4\'\'\' పేజీ మార్పులు జరిగాయి.
+అంటే, సగటున ప్రతీ పేజీకి \'\'\'$5\'\'\' మార్పులు మరియు ప్రతీ మార్పుకి \'\'\'$6\'\'\' దర్శనలు.
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue చేయవలసిన పనుల జాబితా] పొడవు \'\'\'$7\'\'\'.',
+'userstatstext' => 'ప్రస్తుతము \'\'\'$1\'\'\' మంది నమోదు చేసుకున్న సభ్యులు ఉన్నారు. అందులో \'\'\'$2\'\'\' (లేదా \'\'\'$4%\'\'\') మంది నిర్వాహకులు ($3 చూడండి).',
+'disambiguations' => 'అయోమయ నివృత్తి పేజీలు',
+'disambiguationspage' => 'Template:అయోమయ నివృత్తి',
+'disambiguationstext' => 'కింది పేజీలకు ఏదో ఒక <i>అయోమయ నివృత్తి పేజీ</i>కి చూపుతున్నాయి. అలాకాక వాటికి సంబంధిత విష్యానికి చూపుతుండాాలి. <br />ఏదైనా పేజీకి $1 నుండి లింకు ఉన్నట్లయితే ఆ పేజీ అయోమయ నివృత్తి పేజీగా భావింపబడుతుంది. <br />ఇతర నేంస్పేసుల నుండి ఉండే లింకుల గురించి ఇక్కడ ప్రస్తావన<i>లేదు</i>.',
+'doubleredirects' => 'జంట దారిమార్పులు',
+'doubleredirectstext' => 'ప్రతీ వరుసలోను మొదటి, రెండవ దారిమార్పు లింకులు, రెండో దారిమార్పు పేజీలోని వ్యాసపు మొదటి లైను ఉన్నాయి. మొదటి దారిమార్పు యొక్క అసలైన లక్ష్యం ఈ రెండో దారిమార్పు పేజీయే!',
+'brokenredirects' => 'తెగిపోయిన దారిమార్పులు',
+'brokenredirectstext' => 'కింది దారిమార్పులు లేని పేజీలకు మాళ్ళించుతున్నాయి.',
+'nbytes' => '$1 {{PLURAL:$1|బైటు|బైట్లు}}',
+'ncategories' => '$1 {{PLURAL:$1|వర్గం|వర్గాలు}}',
+'nlinks' => '{{FORMATNUM|$1}} {{PLURAL:$1|లింకు|లింకులు}}',
+'nrevisions' => '{{PLURAL:$1|ఒక సంచిక|$1 సంచికలు}}',
+'nviews' => '$1 {{PLURAL:$1|దర్శనము|దర్శనలు}}',
+'lonelypages' => 'అనాధ పేజీలు',
+'uncategorizedpages' => 'వర్గీకరించని పేజీలు',
+'uncategorizedcategories'=> 'వర్గీకరించని వర్గములు',
+'unusedcategories' => 'ఉపయోగించని వర్గాలు',
+'unusedimages' => 'ఉపయోగించబడని ఫైళ్ళు',
+'wantedcategories' => 'కోరిన వర్గాలు',
+'wantedpages' => 'కోరిన పేజీలు',
+'mostlinked' => 'అధిక లింకులు చూపే పేజీలు',
+'mostlinkedcategories' => 'అధిక లింకులు చూపే వర్గాలు',
+'mostcategories' => 'అధిక వర్గాలలో చేరిన వ్యాసాలు',
+'mostimages' => 'అధిక లింకులు గల బొమ్మలు',
+'mostrevisions' => 'అధిక సంచికలు గల వ్యాసాలు',
+'allpages' => 'అన్ని పేజీలు',
+'randompage' => 'యాధృచ్ఛిక పేజీ',
+'shortpages' => 'చిన్న పేజీలు',
+'longpages' => 'పొడవు పేజీలు',
+'deadendpages' => 'అగాధ (డెడ్ఎండ్) పేజీలు',
+'listusers' => 'సభ్యుల జాబితా',
+'specialpages' => 'ప్రత్యేక పేజీలు',
+'spheading' => 'సభ్యులందరి ప్రత్యేక పేజీలు',
+'restrictedpheading' => 'నియంత్రిత ప్రత్యేక పేజీలు',
+'recentchangeslinked' => 'సంబంధిత మార్పులు',
+'rclsub' => '("$1" నుండి లింకున్న పేజీలకు)',
+'newpages' => 'కొత్త పేజీలు',
+'ancientpages' => 'పాత పేజీలు',
+'move' => 'తరలించు',
+'movethispage' => 'ఈ పేజీని తరలించు',
+'unusedimagestext' => '<p>ఇతర వెబ్ సైట్లు సూటి యు.ఆర్.ఎల్ ద్వారా ఇక్కడి బొమ్మలకు లింకు ఇవ్వవచ్చు. అటువంటి లింకులున్న బొమ్మలు కూడా ఇక్కడ చేరి ఉండవచ్చునని గమనించండి.</p>',
+'unusedcategoriestext' => 'కింది వర్గాలకు పేజీలైతే ఉన్నాయి గానీ, వీటిని వ్యాసాలు గానీ, ఇతర వర్గాలు గానీ ఉపయోగించడం లేదు.',
+'booksources' => 'పుస్తక మూలాలు',
+'categoriespagetext' => 'వికీలో ఈ కింది వర్గాలు ఉన్నాయి.',
+'data' => 'డాటా',
+'booksourcetext' => 'కొత్త, పాత పుస్తకాలమ్మే సైట్ల జాబితా ఇది. మీకవసరమైన పుస్తకాల గురించి మరింత సమాచారం కూడా అక్కడ దొరకొచ్చు.',
+'alphaindexline' => '$1 నుండి $2',
+'version' => 'సంచిక',
+'log' => 'దినచర్య పేజీలు',
+'alllogstext' => 'అప్‌లోడు, తొలగింపు, సంరక్షణ, నిరోధం, నిర్వహణల లాగ్ ఇది. ప్రత్యేకించి ఒక లాగ్ రకాన్ని గానీ, ఓ సభ్యుని పేరు గానీ, ఓ పేజీని గాని ఎంచుకుని సంబంధిత లాగ్‌ను మాత్రమే చూడవచ్చు కూడా.',
+'nextpage' => 'తరువాతి పేజీ ($1)',
+'allpagesfrom' => 'ఇక్కడ మొదలు పెట్టి పేజీలు చూపించు:',
+'allarticles' => 'అన్ని వ్యాసములు',
+'allinnamespace' => 'అన్ని పేజీలు ($1 namespace)',
+'allnotinnamespace' => 'అన్ని పేజీలు ($1 నేంస్పేస్ లేనివి)',
+'allpagesprev' => 'పూర్వపు',
+'allpagesnext' => 'తర్వాతి',
+'allpagessubmit' => 'వెళ్లు',
+'mailnologintext' => 'ఇతరులకు ఈ-మెయిల్‌ పంపించాలంటే, మీరు [[Special:Userlogin|లాగిన్‌]] అయి ఉండాలి, మరియు మీ [[Special:Preferences|అభిరుచుల]]లో సరైన ఈ-మెయిల్‌ చిరునామా ఇచ్చి ఉండాలి.',
+'emailuser' => 'ఈ సభ్యునికి ఈ-మెయిల్‌ పంపు',
+'emailpage' => 'సభ్యునికి ఈ-మెయిల్ పంపు',
+'emailpagetext' => 'ఈ సభ్యుడు తన అభిరుచులలో సరైన ఈ-మెయిల్‌ చిరునామా ఇచ్చి ఉంటే, కింది ఫారం మీ సందేశాన్ని పంపిస్తుంది. మీ అభిరుచులలో మీరిచ్చిన ఈ-మెయిల్‌ చిరునామా "నుండి" ఆ సందేశంలో వచ్చినట్లుగా ఉంటుంది. ఆ సభ్యుడు ఈ చిరునామాకు జవాబు పంపుగలరు.',
+'defemailsubject' => '{{SITENAME}} ఇ-మెయిల్',
+'noemailtitle' => 'ఈ-మెయిల్‌ చిరునామా లేదు',
+'noemailtext' => 'ఈ సభ్యుడు సరైన ఈ-మెయిల్‌ చిరునామా ఇవ్వలేదు, లేదా ఇతరుల నుండి ఈ-మెయిల్‌‌లను అందుకోవడానికి సుముఖంగా లేరు.',
+'emailfrom' => 'నుండి',
+'emailto' => 'కు',
+'emailsubject' => 'విషయం',
+'emailmessage' => 'సందేశం',
+'emailsend' => 'పంపించు',
+'emailsent' => 'ఈ-మెయిల్‌ వెళ్ళింది',
+'emailsenttext' => 'మీ ఈ-మెయిల్‌ సందేశం పంపబడింది.',
+'watchlist' => 'నా వీక్షణ జాబితా',
+'nowatchlist' => 'మీ వీక్షణ జాబితా ఖాళీగా ఉంది.',
+'watchnologin' => 'లాగిన్‌ అయిలేరు',
+'watchnologintext' => 'మీ వీక్షణ జాబితాను మార్చడానికి మీరు [[Special:Userlogin|లాగిన్‌]] అయి ఉండాలి.',
+'addedwatch' => 'వీక్షణ జాబితాలో చేరింది',
+'addedwatchtext' => '"$1" పేజీ మీ [[Special:వీక్షణ జాబితా|వీక్షణ జాబితా]]కు చేరింది. ఇకముందు ఈ పేజీలోను, దీని చర్చా పేజీలోను జరిగే మార్పుచేర్పులన్నీ అక్కడ చేరతాయి. సులభంగా గుర్తించడానికై [[Special:Recentchanges|ఇటీవలి మార్పుల జాబితా]]లో ఈ పేజీ పేరు \'\'\'బొద్దుగా\'\'\' కనపడుతుంది.
+
+వీక్షణ జాబితా నుండి ఈ పేజీ తొలగించాలంటే, "Unwatch"ను నొక్కండి.',
+'removedwatch' => 'వీక్షణ జాబితా నుండి తొలగించబడినది',
+'removedwatchtext' => '"[[:$1]]" పేజీ మీ వీక్షణ జాబితా నుండి తొలగించబడినది.',
+'watch' => 'వీక్షించు',
+'watchthispage' => 'ఈ పేజీ మీద కన్నేసి ఉంచు',
+'unwatch' => 'వీక్షించ వద్దు',
+'unwatchthispage' => 'వీక్షణను ఆపు',
+'notanarticle' => 'వ్యాసం పేజీ కాదు',
+'watchnochange' => 'మీ వీక్షణ జాబితాలోని ఏ పేజీలోనూ ఈ కాల అవధిలో మార్పులు జరగలేదు.',
+'watchdetails' => '* చర్చా పేజీలు కాకుండా $1 పేజీలు వీక్షణ జాబితాలో ఉన్నాయి
+* [[Special:Watchlist/edit|పూర్తి వీక్షణ జాబితాను చూపించు, మార్చు]]
+* [[Special:Watchlist/clear|అన్ని పేజీలను తీసివేయి]]',
+'wlheader-enotif' => '* ఈ-మెయిల్‌ ప్రకటనలు పంపబడతాయి.',
+'wlheader-showupdated' => '* మీ గత సందర్శన తరువాత మారిన పేజీలు \'\'\'బొద్దు\'\'\'గా చూపించబడ్డాయి.',
+'watchmethod-recent' => 'వీక్షణ జాబితాలోని పేజీల కొరకు ఇటీవలి మార్పులు పరిశీలించబడుతున్నాయి',
+'watchmethod-list' => 'ఇటీవలి మార్పుల కొరకు వీక్షణ జాబితాలోని పేజీలు పరిశీలించబడుతున్నాయి',
+'removechecked' => 'టిక్కు పెట్టిన వాటిని వీక్షణ జాబితా నుండి తొలగించు',
+'watchlistcontains' => 'మీ వీక్షణ జాబితాలో $1 పేజీలు ఉన్నాయి.',
+'watcheditlist' => 'ఇది అక్షర క్రమంలో మీ వీక్షణ జాబితాలోని వ్యాసాల పేజీల పట్టిక. మీరు తీసివేయదలచుకున్న పేజీలకు ఎదురుగానున్న చెక్‌బాక్స్‌లో టిక్కు పెట్టి కిందనున్న \'టిక్కు పెట్టిన వాటిని వీక్షణ జాబితా నుండి తొలగించు\' అనే మీటను నొక్కండి (వ్యాసం పేజీని తొలగించినపుడు సంబంధిత చర్చా పేజీ కూడా పోతుంది. అలాగే చర్చా పేజీని తొలగించినపుడు సంబంధిత వ్యాసం పేజీ కూడా పోతుంది).',
+'couldntremove' => '\'$1\'ను తొలగించటం కుదరలేదు...',
+'wlnote' => 'గత <b>$2</b> గంటలలోని చివరి $1 మార్పులు కింద ఉన్నాయి.',
+'wlshowlast' => 'గత $1 గంటలు $2 రోజులు $3 చూపించు',
+'wlsaved' => 'ఇది భద్రపరచబడిన మీ వీక్షణ జాబితా.',
+'wlhideshowown' => 'నా మార్పులను $1',
+'wlhideshowbots' => 'బాట్ల మార్పులను $1',
+'enotif_mailer' => '{{SITENAME}} ప్రకటన మెయిల్‌ పంపునది',
+'enotif_reset' => 'అన్ని పేజీలను చూసినట్లుగా గుర్తించు',
+'enotif_newpagetext' => 'ఇది ఒక కొత్త పేజీ.',
+'changed' => 'మార్చబడింది',
+'created' => 'సృష్టించబడింది',
+'enotif_lastvisited' => 'మీ గత సందర్శన తరువాత జరిగిన మార్పుల కొరకు $1 చూడండి.',
+'deletepage' => 'పేజీని తుడిచివేయి',
+'confirm' => 'ధృవీకరించు',
+'excontent' => 'ఇదివరకు విషయ సంగ్రహం: \'$1\'',
+'excontentauthor' => 'ఇదివరకు విషయ సంగ్రహం: \'$1\' (మరియు దీని ఒకేఒక్క రచయిత \'$2\')',
+'exbeforeblank' => 'ఖాళీ చెయ్యకముందు పేజీలో ఉన్న విషయ సంగ్రహం: \'$1\'',
+'exblank' => 'పేజీ ఖాళీగా ఉంది',
+'confirmdelete' => 'తొలగింపును ధృవీకరించండి',
+'deletesub' => '("$1" తొలగింపబడుతుంది)',
+'historywarning' => 'హెచ్చరిక: మీరు తొలగించబోయే పేజీకి చరిత్ర ఉంది:',
+'confirmdeletetext' => 'మీరో పేజీనో, బొమ్మనో శాశ్వతంగా డేటాబేసు నుండి తీసెయ్యబోతున్నారు. మీరు చెయ్యదలచింది ఇదేననీ, దీని పర్యవసానాలు మీకు తెలుసనీ, దీన్ని [[Project::Policy|నిభందనల]] ప్రకారమే చేస్తున్నారనీ నిర్ధారించుకోండి.',
+'actioncomplete' => 'పని పూర్తయింది',
+'deletedtext' => '"$1" తుడిచివేయబడింది. ఇటీవలి తుడిచివేతలకు సంబంధించిన నివేదిక కొరకు $2 చూడండి.',
+'deletedarticle' => '"$1" తుడిచివేయబడినది',
+'dellogpage' => 'తొలగింపు దినచర్య పేజి',
+'dellogpagetext' => 'ఇది ఇటీవలి తుడిచివేతల జాబితా.',
+'deletionlog' => 'తొలగింపు దినచర్య పేజి',
+'deletecomment' => 'తుడిచివేతకు కారణము',
+'imagereverted' => 'విజయవంతంగా పాత సంచికకు వెళ్ళింది.',
+'cantrollback' => 'రచనను వెనక్కి తీసుకువెళ్ళలేము; ఈ పేజీకి ఇదొక్కటే రచన.',
+'alreadyrolled' => '[[:$1]]లో [[User:$2|$2]] ([[User talk:$2|చర్చ]]) చేసిన చివరి మార్పును రోల్‌బాక్ చెయ్యలేము; మరెవరో ఆ పేజీని రోల్‌బాక్ చేసారు, లేదా మార్చారు.
+
+చివరి మార్పులు చేసినవారు: [[User:$3|$3]] ([[User talk:$3|చర్చ]]).',
+'revertpage' => '[[Special:Contributions/$2|$2]] ([[User_talk:$2|చర్చ]]) చేసిన మార్పులను [[User:$1|$1]] వైనక్కు తేసుకువెళ్ళారు',
+'protectlogpage' => 'సంరక్షణ దినచర్య',
+'protectlogtext' => 'పేజీ సంరక్షణ గురించిన వివరాల జాబితా క్రింద వున్నది.',
+'protectedarticle' => '"[[$1]]" సంరక్షించబడింది.',
+'protectmoveonly' => 'తరలింపుల నుండి మాత్రమే సంరక్షించు',
+'protectcomment' => 'సంరక్షించడానికి కారణం',
+'protect-text' => 'ఈ పెజీ <strong>$1></strong> ఎంత సంరక్షణలొ వుందో మీరు ఇక్కడ చూడవచ్చు, మార్చవచ్చు.',
+'undelete' => 'తుడిచివేయబడ్డ పేజీలను చూపించు',
+'undeletepage' => 'తుడిచివేయబడిన పేజీలను చూపించు, పునఃస్థాపించు',
+'undeletepagetext' => 'కీంది పేజీలు తుడిచివేయబడినవి, కానీ పునఃస్థాపనకు వీలుగా సంగ్రహంలో ఉన్నాయి. సంగ్రహం నిర్ణీత వ్యవధులలో పూర్తిగా ఖాళీ చేయబడుతుంటుంది.',
+'undeletearticle' => 'తుడిచివేసిన పేజీని పునఃస్థాపించు',
+'undeletehistory' => 'పేజీని పునఃస్థాపిస్తే, అన్ని సంచికలూ చరిత్రలోకి పునఃస్థాపించబడతాయి.
+తుడిచివేయబడిన తరువాత, అదే పేరుతో వేరే పేజీ సృష్టించబడి ఉంటే, పునఃస్థాపించిన సంచికలు ముందరి చరిత్రలోకి వెళ్తాయి. పేజీ ప్రస్తుతపు సంచిక మాత్రం ఆటోమాటిక్‌గా తీసివేయబడదు.',
+'undeletehistorynoadmin'=> 'ఈ వ్యాసం తుడిచివేయబడినది. తుడిచివేయడానికి కారణము, పేజీలో మార్పులు చేసిన సభ్యులతో సహా కింద సారాంశంలో చూపబడింది. తుడిచివేయబడిన సంచికలలోని విషయ సంగ్రహం నిర్వాహకులకు మాత్రమే అందుబాటులో ఉంది.',
+'undeletebtn' => 'పునఃస్థాపించు',
+'undeletedarticle' => '"[[$1]]" పునఃస్థాపన జరిగింది',
+'undeletedrevisions' => '$1 సంచికల పునఃస్థాపన జరిగింది',
+'namespace' => 'నేంస్పేసు:',
+'invert' => 'ఎంపికను తిరగవెయ్యి',
+'contributions' => 'సభ్యుని రచనలు',
+'mycontris' => 'నా మార్పులు-చేర్పులు',
+'contribsub' => '$1 కొరకు',
+'nocontribs' => 'ఈ విధమైన మార్పులేమీ దొరకలేదు.',
+'ucnote' => 'గత <b>$2</b> రోజులలో సభ్యుడు చేసిన చివరి <b>$1</b> మార్పులు కింద ఉన్నాయి.',
+'uclinks' => 'చివరి $1 మార్పులు చూపించు; గత $2 రోజుల మార్పులు చూపించు.',
+'sp-contributions-newest'=> 'అన్నిటికంటే కొత్తవి',
+'sp-contributions-oldest'=> 'అన్నిటికంటే పాతవి',
+'sp-contributions-newer'=> 'కొత్త $1',
+'sp-contributions-older'=> 'పాత $1',
+'whatlinkshere' => 'ఇక్కడికి లింకు చేస్తున్న పేజీలు',
+'notargettitle' => 'గమ్యం లేదు',
+'notargettext' => 'ఈ పని ఏ పేజీ లేదా సభ్యునిపై జరగాలనే గమ్యాన్ని మీరు సూచించలేదు.',
+'linkshere' => 'కింది పేజీలలో ఇక్కడికి లింకులు ఉన్నాయి:',
+'nolinkshere' => 'ఇక్కడికి ఏ పేజీ నుండీ లింకు లేదు.',
+'isredirect' => 'దారిమార్పు పేజీ',
+'blockip' => 'సభ్యుని నిరోధించు',
+'ipadressorusername' => 'ఐ.పి. చిరునామా లేదా సభ్యనామం',
+'ipbexpiry' => 'అంతమయ్యే గడువు',
+'ipbreason' => 'కారణం',
+'ipbsubmit' => 'ఈ సభ్యుని నిరోధించు',
+'ipbother' => 'వేరే గడువు',
+'ipboptions' => '2 గంటలు:2 గంటలు,1 రోజు:1 రోజు,3 రోజులు:3 రోజులు,1 వారం:1 వారం,2 వారాలు:2 వారాలు,1 నెల:1 నెల,3 నెలలు:3 నెలలు,6 నెలలు:6 నెలలు,1 సంవత్సరం:1 సంవత్సరం,ఎప్పటికీ:ఎప్పటికీ',
+'ipbotheroption' => 'వేరే',
+'badipaddress' => 'సరైన ఐ.పి. అడ్రసు కాదు',
+'blockipsuccesssub' => 'నిరోధం విజయవంతం అయింది',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] నిరోధించబడింది.
+<br />నిరోధాల సమీక్ష కొరకు [[Special:Ipblocklist|ఐ.పి. నిరొధాల జాబితా]] చూడండి.',
+'unblockip' => 'సభ్యునిపై నిరోధాన్ని తొలగించు',
+'unblockiptext' => 'కింది ఫారం ఉపయోగించి, నిరోధించబడిన ఐ.పీ. చిరునామా లేదా సభ్యునికి తిరిగి రచనలు చేసే అధికారం ఇవ్వవచ్చు.',
+'ipusubmit' => 'ఈ చిరునామాపై నిరోధం తొలగించు',
+'unblocked' => '[[User:$1|$1]]పై నిరోధం తొలగించబడింది',
+'ipblocklist' => 'నిరోధించబడిన ఐ.పీ చిరునామాలు మరియు సభ్యులు',
+'blocklistline' => '$1, $2లు $3 ($4)ను నిరోధించారు.',
+'blocklink' => 'నిరోధించు',
+'unblocklink' => 'నిరోధం తొలగించు',
+'contribslink' => 'రచనలు',
+'autoblocker' => 'మీ ఐ.పీ. అడ్రసును "[[User:$1|$1]]" ఇటీవల వాడుట చేత, అది ఆటోమాటిక్‌గా నిరోధించబడినది. $1ను నిరోధించడానికి కారణం: "\'\'\'$2\'\'\'"',
+'blocklogpage' => 'నిరోద దినచర్య పేజి',
+'blocklogentry' => '"[[$1]]" పై నిరోధం అమలయింది. నిరోధ కాలం $2',
+'blocklogtext' => 'సభ్యుల నిరోధాలు, పునస్థాపనల దినచర్య పేజీ ఇది. ఆటోమాటిక్‌గా నిరోధానికి గురైన ఐ.పి. అడ్రసులు ఈ జాబితాలో ఉండవు. ప్రస్తుతం అమల్లో ఉన్న నిరోధాలు, నిషేధాల కొరకు [[Special:Ipblocklist|ఐ.పి. నిరోధాల జాబితా]]ను చూడండి.',
+'unblocklogentry' => '$1పై నిరోధం తొలగించబడింది',
+'ipb_expiry_invalid' => 'అంతమయ్యే గడువు సరైనది కాదు.',
+'lockdb' => 'డాటాబేసును లాక్‌ చెయ్యి',
+'lockdbtext' => 'డాటాబేసును లాక్‌ చెయ్యడం వలన సభ్యులు పేజీలు మార్చడం, అభిరుచులు మార్చడం, వీక్షణ జాబితాను మార్చడం వంటి డాటాబేసు ఆధారిత పనులు చెయ్యలేరు. మీరు చెయ్యదలచినది ఇదేనని, మీ పని కాగానే తిరిగి డాటాబేసును ప్రారంభిస్తాననీ ధృవీకరించండి.',
+'lockconfirm' => 'అవును, డేటాబేసును లాకు చెయ్యాలని నిజంగానే అనుకుంటున్నాను.',
+'lockbtn' => 'డాటాబేసును లాక్‌ చెయ్యి',
+'locknoconfirm' => 'మీరు ధృవీకరణ పెట్టెలో టిక్కు పెట్టలేదు.',
+'lockdbsuccesssub' => 'డాటాబేసు లాకు విజయవంతం అయ్యింది.',
+'lockdbsuccesstext' => 'డాటాబేసు లాకయింది.<br />పని పూర్తి కాగానే లాకు తియ్యడం మర్చిపోకండి.',
+'makesysoptext' => 'మామూలు సభ్యులను నిర్వాహకులు చెయ్యడానికి అధికారులు ఈ ఫారంను వాడతారు. దీని కొరకు సభ్యుని పేరు పెట్టెలో టైపు చేసి, మీట నొక్కండి.',
+'makesysopname' => 'సభ్యుని పేరు:',
+'makesysopsubmit' => 'ఈ సభ్యుని నిర్వాహకుడిని చెయ్యి',
+'makesysopok' => '<b>సభ్యుడు "$1" ఇప్పుడు నిర్వాహకుడు</b>',
+'makesysopfail' => '<b>సభ్యుడు "$1"ని నిర్వాహకుడిగా మార్చలేక పోయాం. (పేరు సరిగానే రాసారా?)</b>',
+'rights' => 'హక్కులు:',
+'makesysop' => 'సభ్యుడిని నిర్వాహకుడిగా మార్చు',
+'already_sysop' => 'ఈ సభ్యుడు ఇప్పటికే నిర్వాహకుడు',
+'already_bureaucrat' => 'ఈ సభ్యుడు ఇప్పటికే అధికారి',
+'movepage' => 'పేజీని తరలించు',
+'movepagetext' => 'కీంది ఫారం ఉపయోగించి, పేజీ పేరు మార్చవచ్చు. దాంతో పాటు దాని చరిత్ర అంతా కొత్త పేజీ చరిత్రగా మారుతుంది. పాత పేజీ కొత్త దానికి దారిమార్పు పేజీ అవుతుంది. పాత పేజీని చేరుకునే లింకులు అలాగే ఉంటాయి; తెగిపోయిన దారిమార్పులు, జంట దారిమార్పులు లేవని నిర్ధారించుకోండి. లింకులన్నీ అనుకున్నట్లుగా, చేరవలసిన చోటికే చేరుతున్నాయని నిర్ధారించుకోవలసిన బాధ్యత మీదే.
+
+ఒకవేళ కొత్త పేజీ పేరుతో ఇప్పటికే ఒక పేజీ ఉండి - అది ఖాళీగా లేకున్నా / చరితం ఉన్నా- పేజీ తరలింపు \'\'\'జరగదు\'\'\'. అంటే కొత్తపేరును మార్చి తిరిగి పాతపేరుకు తీసుకురాగలరు మరియు ఇప్పటికే వున్న పేజీని తుడిచివేయలేరు.
+
+<b>హెచ్చరిక!</b>
+బాగా జనరంజకమైన అయిన పేజీని మారుస్తున్నారేమో చూడండి; దాని పరిణామాలను అర్ధం చేసుకుని ముందుకుసాగండి.',
+'movepagetalktext' => 'దానితో పాటు సంబంధిత చర్చా పేజీ కూడా ఆటోమాటిక్‌‌గా తరలించబడుతుంది, \'\'\'కింది సందర్భాలలో తప్ప:\'\'\'
+*ఒక నేంస్పేసు నుండి ఇంకోదానికి తరలించేటపుడు,
+*కొత్త పేరుతో ఇప్పటికే ఒక చర్చా పేజీ ఉంటే,
+*కింది చెక్‌బాక్సులో టిక్కు పెట్టకపోతే.
+
+ఆ సందర్భాలలో, మీరు చర్చా పేజీని కూడా పనిగట్టుకుని తరలించవలసి ఉంటుంది, లేదా ఏకీకృత పరచవలసి ఉంటుంది.',
+'movearticle' => 'పేజీని తరలించు',
+'movenologin' => 'లాగిన్‌ అయిలేరు',
+'movenologintext' => 'పేజీని తరలించడానికి మీరు [[Special:Userlogin|లాగిన్‌]] అయిఉండాలి.',
+'newtitle' => 'కొత్త పేరుకి',
+'movepagebtn' => 'పేజీని తరలించు',
+'pagemovedsub' => 'తరలింపు విజయవంతమైనది',
+'pagemovedtext' => '"[[$1]]" పేజీ "[[$2]]"కు తరలించబడింది.',
+'articleexists' => 'ఆ పేరుతో ఇప్పటికే ఒక పేజీ ఉంది, లేదా మీరు ఎంచుకున్న పేరు సరైనది కాదు. వేరే పేరు ఎంచుకోండి.',
+'talkexists' => '\'\'\'పేజీని జయప్రదంగా తరలించాము, కానీ చర్చా పేజీని తరలించలేక పోయాము. కొత్త పేరుతో చర్చ పేజీ ఇప్పటికే ఉంది, ఆ రెంటినీ మీరే ఏకీకృతం చెయ్యండి.\'\'\'',
+'movedto' => 'తరలింపు',
+'movetalk' => 'కూడా వున్న చర్చ పేజీని తరలించు',
+'talkpagemoved' => 'సంబంధిత చర్చా పేజీ కూడా తరలించబడింది.',
+'talkpagenotmoved' => 'సంబంధిత చర్చా పేజీని తరలించబడ<strong>లేదు</strong>.',
+'1movedto2' => '$1, $2కు తరలించబడింది',
+'movelogpage' => 'తరలింపు దినచర్య',
+'movelogpagetext' => 'కింద తరలించిన పేజీల జాబితా ఉన్నది.',
+'movereason' => 'కారణము',
+'delete_and_move' => 'తొలగించి, తరలించు',
+'delete_and_move_text' => '==తొలగింపు అవసరం==
+
+ఉద్దేశించిన వ్యాసం "[[$1]]" ఇప్పటికే ఉనికిలో ఉంది. ప్రస్తుత తరలింపుకు వీలుగా దాన్ని తొలగించేయమంటారా?',
+'delete_and_move_confirm'=> 'అవును, పేజీని తొలగించు',
+'delete_and_move_reason'=> 'తరలింపుకు వీలుగా తొలగించబడింది',
+'selfmove' => 'మూలం, గమ్యం పేర్లు ఒకటే; పేజీని దాని పైకే తరలించడం కుదరదు.',
+'export' => 'ఎగుమతి పేజీలు',
+'allmessages' => 'అన్ని సిస్టం సందేశాలు',
+'allmessagesname' => 'పేరు',
+'allmessagestext' => 'మీడియావికీ నేంస్పేసులో ఉన్న అన్ని సిస్టం సందేశాల జాబితా ఇది.',
+'thumbnail-more' => 'పెద్దది చెయ్యి',
+'missingimage' => '<b>తప్పిపోయిన బొమ్మ</b><br /><i>$1</i>',
+'filemissing' => 'ఫైలు కనపడుటలేదు',
+'thumbnail_error' => '$1: నఖచిత్రం తయారుచెయ్యడంలో లోపం జరిగింది',
+'importfailed' => 'దిగుమతి కాలేదు: $1',
+'tooltip-diff' => 'పాఠానికి మీరు చేసిన మార్పులను చూపుంచు. [alt-v]',
+'anonymous' => '{{SITENAME}} యొక్క అజ్ఞాత సభ్యులు',
+'siteuser' => '{{SITENAME}} సభ్యుడు $1',
+'lastmodifiedatby' => 'ఈ పేజీకి $3 $2, $1న చివరి మార్పు చేసారు.',
+'and' => 'మరియు',
+'siteusers' => '{{SITENAME}} సభ్యులు $1',
+'spamprotectiontitle' => 'స్పాం సంరక్షణ ఫిల్టరు',
+'spamprotectiontext' => 'మీరు భద్రపరచదలచిన పేజీని మా స్పాం ఫిల్టరు నిరోధించింది. బహుశా ఇది ఏదైనా బయటి సైటుకు ఇచ్చిన లింకు కారణంగా జరిగి ఉండవచ్చు.',
+'spamprotectionmatch' => 'మా స్పాం ఫిల్టరును ప్రేరేపించిన రచన భాగం ఇది: $1',
+'subcategorycount' => 'ఈ వర్గములో {{PLURAL:$1|ఒక ఉపవర్గము ఉంది|$1 ఉపవర్గములు ఉన్నాయి}}.',
+'categoryarticlecount' => 'ఈ వర్గంలో {{PLURAL:$1|ఒక వ్యాసం ఉంది|$1 వ్యాసాలున్నాయి}}.',
+'numedits' => 'మార్పుల సంఖ్య (వ్యాసం): $1',
+'numtalkedits' => 'మార్పుల సంఖ్య (చర్చా పేజీ): $1',
+'numwatchers' => 'వీక్షకుల సంఖ్య: $1',
+'numauthors' => 'భిన్నమైన రచయితల సంఖ్య (వ్యాసం): $1',
+'numtalkauthors' => 'భిన్నమైన రచయితల సంఖ్య (చర్చా పేజీ): $1',
+'mw_math_html' => 'వీలైతే ఎచ్‌టీఎంఎల్ లేకపోతే పింగ్',
+'mw_math_source' => 'టెక్ గానే ఉండనివ్వు (టెక్స్ట్‌ బ్రౌజర్ల కొరకు)',
+'markaspatrolleddiff' => 'పరీక్షించినట్లుగా గుర్తు పెట్టు',
+'markaspatrolledtext' => 'ఈ వ్యాసాన్ని పరీక్షించినట్లుగా గుర్తు పెట్టు',
+'markedaspatrolled' => 'పరీక్షింపబడినట్లు గుర్తింపబడింది',
+'markedaspatrolledtext' => 'ఎంచుకున్న సంచిక పరీక్షించబడినట్లుగా గుర్తింపబడింది.',
+'deletedrevision' => 'పాత సంచిక $1 తొలగించబడినది.',
+'previousdiff' => '← మునుపటి తేడా',
+'nextdiff' => 'తరువాతి తేడా →',
+'imagemaxsize' => 'బొమ్మ వివరణ పేజీలో బొమ్మ ఉండవలసిన సైజు:',
+'thumbsize' => 'నఖచిత్రం వైశాల్యం:',
+'showbigimage' => 'మరింత స్పష్టమైన సంచికను డౌనులోడు చేసుకోండి ($1x$2, $3 KB)',
+'newimages' => 'కొత్త ఫైళ్ళ కొలువు',
+'noimages' => 'చూసేందుకు ఏమీ లేదు.',
+'passwordtooshort' => 'మీ సంకేతపదము మరీ చిన్నదయినది. అది కనీసం $1 అక్షరాల పొడవు ఉండాలి.',
+'mediawarning' => '\'\'\'హెచ్చరిక\'\'\': ఈ ఫైలులో హానికరమైన కోడ్‌ ఉండవచ్చు, దానిని పనిచేయిస్తే మీ సిస్టము దెబ్బతినవచ్చు.<hr />',
+'metadata' => 'మెటాడేటా',
+'exif-pixelxdimension' => 'బొమ్మ సరైన ఎత్తు',
+'edit-externally' => 'బయటి అప్లికేషను వాడి ఈ ఫైలును మార్చు',
+'edit-externally-help' => 'మరింత సమాచారం కొరకు [http://meta.wikimedia.org/wiki/Help:External_editors సెటప్‌ సూచనలు] చూడండి.',
+'recentchangesall' => 'అన్నీ',
+'watchlistall1' => 'అన్నీ',
+'watchlistall2' => 'అన్నీ',
+'namespacesall' => 'అన్నీ',
+'confirmemail' => 'ఈ-మెయిల్ చిరునామా ధృవీకరించండి',
+'confirmemail_text' => 'ఈ వికీలో ఈ-మెయిల్ అంశాల్ని వాడుకునే ముందు మీ ఈ-మెయిల్ చిరునామాను నిర్ధారించవలసిన అవసరం ఉంది.
+కింది మీటను నొక్కగానే మీరిచ్చిన చిరునామాకు ధృవీకరణ మెయిలు వెళ్తుంది. ఆ మెయిల్లో ఒక సంకేతం కలిగిన ఒక లింకు ఉంటుంది; ఆ లింకును మీ బ్రౌజరులో తెరవండి. ఈ-మెయిల్ చిరునామా ధృవీకరణ అయిపోతుంది.',
+'confirmemail_send' => 'ఒక ధృవీకరణ సంకేతాన్ని పంపించు',
+'confirmemail_sent' => 'ధృవీకరణ ఈ-మెయిలును పంపబడినది',
+'confirmemail_sendfailed'=> 'ధృవీకరణ మెయిలును పంపలేకపోయాము. చిరునామాలో తప్పులున్నాయేమో చూసుకోండి.',
+'confirmemail_invalid' => 'ధృవీకరణ సంకేతం సరైనది కాదు. దానికి కాలం చెల్లి ఉండవచ్చు.',
+'confirmemail_success' => 'మీ ఈ-మెయిల్ చిరునామా ధృవీకరణ అయింది. ఇక లాగిన్ అయి, వికీని అస్వాదించండి.',
+'confirmemail_loggedin' => 'మీ ఈ-మెయిల్ చిరునామా ఇప్పుడు రూఢి అయింది.',
+'confirmemail_error' => 'మీ ధృవీకరణను భద్రపరచడంలో ఏదో లోపం జరిగింది.',
+'confirmemail_subject' => '{{SITENAME}} ఈ-మెయిల్ చిరునామా ధృవీకరణ',
+'confirmemail_body' => 'ఈ ఈ-మెయిల్ చిరునామాతో $1 ఐ.పి. అడ్రసు నుండి ఎవరో, బహుశా మీరే, {{SITENAME}}లో "$2" అనే ఎకౌంటును సృష్టించారు.
+
+ఈ ఎకౌంటు నిజంగా మీదేనని ధృవీకరించేందుకు, అలాగే {{SITENAME}}లో
+ఈ-మెయిల్‌ను వాడటం మొదలుపెట్టేందుకు కింది లింకును మీ బ్రౌజరులో తెరవండి:
+
+$3
+
+ఒకవేళ అది మీరు *కాకపోతే* ఏమీ చెయ్యకండి. నిర్ధారణ కొరకు మేము పంపిన ఈ సంకేతం
+$4తో కాలం చెల్లుతుంది.',
+'tryexact' => 'ఖచ్చితమైన పోలిక కొరకు ప్రయత్నించు',
+'createarticle' => 'వ్యాసాన్ని సృష్టించు',
+'scarytranscludetoolong'=> '[యుఆర్‌ఎల్ మరీ పొడుగ్గా ఉంది; క్షమించండి]',
+'deletedwhileediting' => 'హెచ్చరిక: మీరు మార్పులు చేయటం మొదలుపెట్టాక, ఈ పేజీ తొలగించబడింది.',
+'confirmrecreate' => 'మీరు పేజీ రాయటం మొదలుపెట్టిన తరువాత [[User:$1|$1]] ([[User talk:$1|చర్చ]]) దానిని తీసివేసారు. దానికి ఈ కారణం ఇచ్చారు: \'\'$2\'\'
+మీరు ఈ పేజీని మళ్ళీ తయారు చేయాలనుకుంటున్నారని ధృవీకరించండి.',
+'tooltip-recreate' => 'పేజీ తుడిచివేయబడ్డాకానీ మళ్ళీ సృష్టించు',
+'redirectingto' => '[[$1]]కు మళ్ళించబడుతుంది...',
+'confirm_purge' => 'ఈ పేజీ యొక్క పాత కాపీని తొలగించమంటారా?
+
+$1',
+'confirm_purge_button' => 'సరే',
+'articletitles' => '\'\'$1\'\'తొ మొదలయ్యే వ్యాసాలు',
+);
+?>
diff --git a/languages/messages/MessagesTg.php b/languages/messages/MessagesTg.php
new file mode 100644
index 000000000000..caccbe1da4af
--- /dev/null
+++ b/languages/messages/MessagesTg.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Tajik (Тоҷикӣ)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ * @author Francis Tyers
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => "Медиа",
+ NS_SPECIAL => "Вижа",
+ NS_MAIN => "",
+ NS_TALK => "Баҳс",
+ NS_USER => "Корбар",
+ NS_USER_TALK => "Баҳси_корбар",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => "Баҳси_$1",
+ NS_IMAGE => "Акс",
+ NS_IMAGE_TALK => "Баҳси_акс",
+ NS_MEDIAWIKI => "Медиавики",
+ NS_MEDIAWIKI_TALK => "Баҳси_медиавики",
+ NS_TEMPLATE => "Шаблон",
+ NS_TEMPLATE_TALK => "Баҳси_шаблон",
+ NS_HELP => "Роҳнамо",
+ NS_HELP_TALK => "Баҳси_роҳнамо",
+ NS_CATEGORY => "Гурӯҳ",
+ NS_CATEGORY_TALK => "Баҳси_гурӯҳ",
+);
+
+$linkTrail = '/^([a-zабвгдеёжзийклмнопрстуфхчшъэюяғӣқўҳҷцщыь]+)(.*)$/sDu';
+
+?>
diff --git a/languages/messages/MessagesTh.php b/languages/messages/MessagesTh.php
new file mode 100644
index 000000000000..14dbaeec9c53
--- /dev/null
+++ b/languages/messages/MessagesTh.php
@@ -0,0 +1,215 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+#--------------------------------------------------------------------------
+# ผู้แปล (Translators)
+# - วรากร อึ้งวิเชียร (Varakorn Ungvichian)
+# - จักรกฤช วงศ์สระหลวง (Jakkrit Vongsraluang) / PaePae
+#--------------------------------------------------------------------------
+
+
+$namespaceNames = array(
+ NS_MEDIA => 'สื่อ',
+ NS_SPECIAL => 'พิเศษ',
+ NS_MAIN => '',
+ NS_TALK => 'พูดคุย',
+ NS_USER => 'ผู้ใช้',
+ NS_USER_TALK => 'คุยกับผู้ใช้',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'คุยเรื่อง$1',
+ NS_IMAGE => 'ภาพ',
+ NS_IMAGE_TALK => 'คุยเรื่องภาพ',
+ NS_MEDIAWIKI => 'มีเดียวิกิ',
+ NS_MEDIAWIKI_TALK => 'คุยเรื่องมีเดียวิกิ',
+ NS_TEMPLATE => 'แม่แบบ',
+ NS_TEMPLATE_TALK => 'คุยเรื่องแม่แบบ',
+ NS_HELP => 'วิธีใช้',
+ NS_HELP_TALK => 'คุยเรื่องวิธีใช้',
+ NS_CATEGORY => 'หมวดหมู่',
+ NS_CATEGORY_TALK => 'คุยเรื่องหมวดหมู่',
+);
+
+$quickbarSettings = array(
+ "ไม่มี", "อยู่ทางซ้าย", "อยู่ทางขวา", "ลอยทางซ้าย"
+);
+
+$linkTrail = '/^([a-z]+)(.*)\$/sD';
+
+
+$messages = array(
+
+# User Toggles
+#
+
+"tog-underline" => "ขีดเส้นใต้ลิงก์",
+"tog-highlightbroken" => "จัดลิงก์ที่ไม่มี <a href=\"\" class=\"new\">เป็น ดังนี้</a> (หรือ เป็นดังนี้<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "จัดย่อหน้าให้เรียบร้อย",
+"tog-hideminor" => "ไม่แสดงการแก้ไขย่อยใน recent changes",
+"tog-usenewrc" => "Enhanced recent changes (ไม่สามารถใช้ได้กับทุกเว็บบราวเซอร์)",
+"tog-numberheadings" => "ใส่ตัวเลขหน้าหัวข้อโดยอัตโนมัติ",
+"tog-showtoolbar" => "Show edit toolbar",
+"tog-editondblclick" => "แก้ไขหน้าโดยใช้ double click (ผ่าน JavaScript)",
+"tog-editsection"=>"สามารถแก้ไขเฉพาะส่วนโดยใช้ลิงก์ [แก้ไข]",
+"tog-editsectiononrightclick"=>"สามารถแก้ไขเฉพาะส่วนโดยใช้ right click<br /> บนชื่อส่วนย่อย (ผ่าน JavaScript)",
+"tog-showtoc"=>"แสดงสารบัญ<br />(สำหรับบทความที่มีมากกว่า 3 หัวข้อ)",
+"tog-rememberpassword" => "จำ password ระหว่าง session",
+"tog-editwidth" => "กล่องสำหรับการแก้ไขกว้างเต็มหน้าจอ",
+"tog-watchdefault" => "นำหน้าที่แก้ไขไปใส่ watchlist",
+"tog-minordefault" => "กำหนด default ให้การแก้ไขทุกครั้งเป็นการแก้ไขย่อย",
+"tog-previewontop" => "แสดง preview ก่อนกล่องสำหรับการแก้ไข",
+"tog-nocache" => "ไม่นำหน้าต่าง ๆ มาใส่ใน cache",
+
+
+# Dates
+#
+
+'sunday' => "วันอาทิตย์",
+'monday' => "วันจันทร์",
+'tuesday' => "วันอังคาร",
+'wednesday' => "วันพุธ",
+'thursday' => "วันพฤหัสบดี",
+'friday' => "วันศุกร์",
+'saturday' => "วันเสาร์",
+'january' => "มกราคม",
+'february' => "กุมภาพันธ์",
+'march' => "มีนาคม",
+'april' => "เมษายน",
+'may_long' => "พฤษภาคม",
+'june' => "มิถุนายน",
+'july' => "กรกฎาคม",
+'august' => "สิงหาคม",
+'september' => "กันยายน",
+'october' => "ตุลาคม",
+'november' => "พฤศจิกายน",
+'december' => "ธันวาคม",
+'jan' => "ม.ค.",
+'feb' => "ก.พ.",
+'mar' => "มี.ค.",
+'apr' => "เม.ย.",
+'may' => "พ.ค.",
+'jun' => "มิ.ย.",
+'jul' => "ก.ค.",
+'aug' => "ส.ค.",
+'sep' => "ก.ย.",
+'oct' => "ต.ค.",
+'nov' => "พ.ย.",
+'dec' => "ธ.ค.",
+
+# Bits of text used by many pages:
+#
+"categories" => "ประเภทของหน้า",
+"pagecategories" => "ประเภทของหน้า",
+"category_header" => "บทความในประเภท \"$1\"",
+"subcategories" => "ประเภทย่อย",
+
+"mainpage" => "หน้าหลัก",
+"mainpagetext" => "Wiki software ถูกติดตั้งเรียบร้อยแล้ว",
+"about" => "เกี่ยวกับ",
+"aboutsite" => "เกี่ยวกับ {{SITENAME}}",
+"aboutpage" => "{{ns:project}}:เกี่ยวกับ",
+"help" => "ความช่วยเหลือ",
+"helppage" => "{{ns:project}}:ความช่วยเหลือ",
+"bugreports" => "รายงาน bug",
+"bugreportspage" => "{{ns:project}}:รายงาน bug",
+"sitesupport" => "การบริจาค",
+"faq" => "FAQ",
+"faqpage" => "{{ns:project}}:FAQ",
+"edithelp" => "ความช่วยเหลือในการแก้ไขหน้า",
+"edithelppage" => "{{ns:project}}:การแก้ไขหน้า",
+"cancel" => "ยกเลิก",
+"qbfind" => "ค้นหา",
+"qbbrowse" => "ค้น",
+"qbedit" => "แก้ไข",
+"qbpageoptions" => "หน้านี้",
+"qbpageinfo" => "บริบท",
+"qbmyoptions" => "หน้าของฉัน",
+"qbspecialpages" => "หน้าพิเศษ",
+"moredotdotdot" => "อื่น ๆ ...",
+"mypage" => "หน้าของฉัน",
+"mytalk" => "หน้าพูดคุยของฉัน",
+"currentevents" => "เหตุการณ์ปัจจุบัน",
+"errorpagetitle" => "ความผิดพลาด",
+"returnto" => "กลับไปยัง $1.",
+"tagline" => "จาก {{SITENAME}}, สารานุกรมฟรี",
+"whatlinkshere" => "หน้าที่ลิงก์มายังที่นี่",
+"help" => "ความช่วยเหลือ",
+"search" => "ค้นหา",
+"searchbutton" => "ค้นหา",
+"go" => "ไป",
+'searcharticle' => "ไป",
+"history" => "ประวัติของหน้านี้",
+"printableversion" => "Printable version",
+"editthispage" => "แก้ไขหน้านี้",
+"deletethispage" => "ลบหน้านี้",
+"protectthispage" => "ป้องกันหน้านี้",
+"unprotectthispage" => "ยกเลิกการป้องกันหน้านี้",
+"newpage" => "หน้าใหม่",
+"talkpage" => "พูดคุยเกี่ยวกับหน้านี้",
+"postcomment" => "Post a comment",
+"articlepage" => "View article",
+"userpage" => "View user page",
+"projectpage" => "View meta page",
+"imagepage" => "View image page",
+"viewtalkpage" => "View discussion",
+"otherlanguages" => "Other languages",
+"redirectedfrom" => "(Redirected from $1)",
+"lastmodifiedat" => "This page was last modified $2, $1.",
+"viewcount" => "This page has been accessed $1 times.",
+"protectedpage" => "Protected page",
+
+"nbytes" => "$1 ไบต์",
+"ok" => "OK",
+"retrievedfrom" => "Retrieved from \"$1\"",
+"newmessageslink" => "ข้อความ",
+"editsection"=>"แก้ไข",
+"editold"=>"แก้ไข",
+"toc" => "สารบัญ",
+"showtoc" => "แสดงสารบัญ",
+"hidetoc" => "ซ่อนสารบัญ",
+"thisisdeleted" => "แสดงหรือคืน $1?",
+"restorelink" => "$1 การแก้ไขที่ลบแล้ว",
+
+# Main script and global functions
+#
+"nosuchaction" => "ไม่มีการกระทำดังกล่าว",
+"nosuchactiontext" => "การกระทำที่บอกไว้ใน URL ไม่
+เป็นที่ยอมรับของ wiki",
+"nosuchspecialpage" => "ไม่มีหน้าพิเศษดังกล่าว",
+"nospecialpagetext" => "คุณได้ขอหน้าพิเศษที่ไม่
+เป็นที่ยอมรับของ wiki",
+
+# Login and logout pages
+#
+"loginpagetitle" => "ล็อกอินผู้ใช้",
+"yourname" => "ชื่อผู้ใช้",
+"yourpassword" => "รหัสผ่าน",
+"yourpasswordagain" => "พิมพ์รหัสผ่านอีกครั้ง",
+
+"login" => "ล็อกอิน",
+"loginprompt" => "ต้อง enable cookie เพื่อล็อกอินสู่ {{SITENAME}} ได้",
+"userlogin" => "ล็อกอิน",
+"logout" => "ล็อกเอาท์",
+"userlogout" => "ล็อกเอาท์",
+"notloggedin" => "ไม่ได้ล็อกอินไว้",
+"createaccount" => "สร้าง account ใหม่",
+"createaccountmail" => "ผ่านอีเมล์",
+"badretype" => "รหัสผ่านที่พิมพ์ไว้ไม่เหมือนกัน",
+"userexists" => "ชื่อผู้ใช้ที่พิมพ์ไว้ถูกใช้แล้ว โปรดเลือกชื่ออื่น",
+"youremail" => "อีเมล์ของคุณ*",
+
+# Edit pages
+#
+"newarticletext" =>
+"คุณได้ตามลิงก์ที่นำไปยังหน้าที่ยังไม่ปรากฏอยู่
+เพื่อเริ่มสร้างหน้าใหม่ พิมพ์ลงในกล่องข้างล่างนี้
+(ดู[[{{ns:project}}:ความช่วยเหลือ|หน้าความช่วยเหลือ]]สำหรับข้อมูลเพิ่มเติม)
+If you are here by mistake, just click your browser's '''back''' button.",
+"noarticletext" => "(ไม่มีข้อความในหน้านี้)",
+"updated" => "(ได้รับการแก้ไขแล้ว)",
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesTlh.php b/languages/messages/MessagesTlh.php
new file mode 100644
index 000000000000..073b07d7edd0
--- /dev/null
+++ b/languages/messages/MessagesTlh.php
@@ -0,0 +1,30 @@
+<?php
+/** Klingon (tlhIngan-Hol)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => "Doch",
+ NS_SPECIAL => "le'",
+ NS_MAIN => "",
+ NS_TALK => "ja'chuq",
+ NS_USER => "lo'wI'",
+ NS_USER_TALK => "lo'wI'_ja'chuq",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => "$1_ja'chuq",
+ NS_IMAGE => "nagh_beQ",
+ NS_IMAGE_TALK => "nagh_beQ_ja'chuq",
+ NS_MEDIAWIKI => "MediaWiki",
+ NS_MEDIAWIKI_TALK => "MediaWiki_ja'chuq",
+ NS_TEMPLATE => "chen'ay'",
+ NS_TEMPLATE_TALK => "chen'ay'_ja'chuq",
+ NS_HELP => "QaH",
+ NS_HELP_TALK => "QaH_ja'chuq",
+ NS_CATEGORY => "Segh",
+ NS_CATEGORY_TALK => "Segh_ja'chuq"
+);
+
+
+?>
diff --git a/languages/messages/MessagesTr.php b/languages/messages/MessagesTr.php
new file mode 100644
index 000000000000..d83b2a3ccae3
--- /dev/null
+++ b/languages/messages/MessagesTr.php
@@ -0,0 +1,1113 @@
+<?php
+/**
+ * Turkish (Türkçe)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Özel',
+ NS_MAIN => '',
+ NS_TALK => 'Tartışma',
+ NS_USER => 'Kullanıcı',
+ NS_USER_TALK => 'Kullanıcı_mesaj',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_tartışma',
+ NS_IMAGE => 'Resim',
+ NS_IMAGE_TALK => 'Resim_tartışma',
+ NS_MEDIAWIKI => 'MedyaViki',
+ NS_MEDIAWIKI_TALK => 'MedyaViki_tartışma',
+ NS_TEMPLATE => 'Şablon',
+ NS_TEMPLATE_TALK => 'Şablon_tartışma',
+ NS_HELP => 'Yardım',
+ NS_HELP_TALK => 'Yardım_tartışma',
+ NS_CATEGORY => 'Kategori',
+ NS_CATEGORY_TALK => 'Kategori_tartışma',
+);
+
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+
+$messages = array(
+'tog-underline' => 'Bağlatıların altını çiz',
+'tog-highlightbroken' => 'Boş bağlantıları <a href="" class="new">bu şekilde</a> (alternatif: bu şekilde<a href="" class="internal">?</a>) göster.',
+'tog-justify' => 'Paragraf iki yana yaslayarak ayarla',
+'tog-hideminor' => 'Küçük değişiklikleri "Son değişiklikler" sayfasında gizle',
+'tog-extendwatchlist' => 'Gelişmiş izleme listesi',
+'tog-usenewrc' => 'Gelişmiş son değişiklikler listesi (her tarayıcı için uygun değil)',
+'tog-numberheadings' => 'Başlıkları otomatik numaralandır',
+'tog-showtoolbar' => 'Değişiklik yaparken yardımcı düğmeleri göster. (JavaScript)',
+'tog-editondblclick' => 'Sayfayı çift tıklayarak değiştirmeye başla (JavaScript)',
+'tog-editsection' => 'Bölümleri [değiştir] bağlantıları ile değiştirme hakkı ver',
+'tog-editsectiononrightclick'=> 'Bölüm başlığına sağ tıklayarak bölümde değişikliğe izin ver.(JavaScript)',
+'tog-showtoc' => 'İçindekiler tablosunu oluştur<br />(3 taneden fazla başlığı olan sayfalar için)',
+'tog-rememberpassword' => 'Parolayı hatırla',
+'tog-editwidth' => 'Yazma alanı tam genişlikte olsun',
+'tog-watchcreations' => 'Yaratmış olduğum sayfaları izleme listeme ekle',
+'tog-watchdefault' => 'Değişiklik yapılan sayfayı izleme listesine ekle',
+'tog-minordefault' => 'Değişikliği \'küçük değişiklik\' olarak seçili getir',
+'tog-previewontop' => 'Önizlemeyi yazma alanın üstünde göster',
+'tog-previewonfirst' => 'Değiştirmede önizlemeyi göster',
+'tog-nocache' => 'Sayfaları bellekleme',
+'tog-enotifwatchlistpages'=> 'Sayfa değişikliklerinde bana e-posta gönder',
+'tog-enotifusertalkpages'=> 'Kullanıcı sayfamda değişiklik olduğunda bana e-posta gönder',
+'tog-enotifminoredits' => 'Sayfalardaki küçük değişikliklerde de bana e-posta gönder',
+'tog-shownumberswatching'=> 'İzleyen kullanıcı sayısını göster',
+'tog-fancysig' => 'Ham imza (İmzanız yukarda belirttiğiniz gibi görünür. Sayfanıza otomatik bağlantı yaratılmaz)',
+'tog-externaleditor' => 'Değişiklikleri başka editör programı ile yap',
+'tog-externaldiff' => 'Karşılaştırmaları dış programa yaptır.',
+'tog-showjumplinks' => '"Git" bağlantısı etkinleştir',
+'tog-uselivepreview' => 'Canlı önizleme özelliğini kullan (JavaScript) (daha deneme aşamasında)',
+'tog-autopatrol' => 'Yaptığım değişiklikleri kontrol edilmiş olarak işaretle',
+'tog-forceeditsummary' => 'Özeti boş bıraktığımda beni uyar',
+'tog-watchlisthideown' => 'İzleme listemden benim değişikliklerimi gizle',
+'tog-watchlisthidebots' => 'İzleme listemden bot değişikliklerini gizle',
+'underline-always' => 'Daima',
+'underline-never' => 'Asla',
+'underline-default' => 'Tarayıcı karar versin',
+'skinpreview' => '(Önizleme)',
+'sunday' => 'Pazar',
+'monday' => 'Pazartesi',
+'tuesday' => 'Salı',
+'wednesday' => 'Çarşamba',
+'thursday' => 'Perşembe',
+'friday' => 'Cuma',
+'saturday' => 'Cumartesi',
+'january' => 'Ocak',
+'february' => 'Şubat',
+'march' => 'Mart',
+'april' => 'Nisan',
+'may_long' => 'Mayıs',
+'june' => 'Haziran',
+'july' => 'Temmuz',
+'august' => 'Ağustos',
+'september' => 'Eylül',
+'october' => 'Ekim',
+'november' => 'Kasım',
+'december' => 'Aralık',
+'jan' => 'Ocak',
+'feb' => 'Şubat',
+'mar' => 'Mart',
+'apr' => 'Nisan',
+'may' => 'Mayıs',
+'jun' => 'Haziran',
+'jul' => 'Temmuz',
+'aug' => 'Ağustos',
+'sep' => 'Eylül',
+'oct' => 'Ekim',
+'nov' => 'Kasım',
+'dec' => 'Aralık',
+'categories' => 'Sayfa kategorileri',
+'pagecategories' => 'Sayfa {{PLURAL:$1|kategorisi|kategorileri}}',
+'category_header' => '"$1" kategorisindeki sayfalar',
+'subcategories' => 'Alt Kategoriler',
+'mainpage' => 'Ana Sayfa',
+'mainpagetext' => '<big>\'\'\'MediaWiki başarı ile kuruldu.\'\'\'</big>',
+'portal' => 'Topluluk portalı',
+'portal-url' => 'Project:Topluluk portalı',
+'about' => 'Hakkında',
+'aboutsite' => '{{SITENAME}} Hakkında',
+'aboutpage' => 'Project:Hakkında',
+'article' => 'Madde',
+'help' => 'Yardım',
+'helppage' => 'Yardım:İçindekiler',
+'bugreports' => 'Hata Raporları',
+'bugreportspage' => 'Project:Hata raporları',
+'sitesupport' => 'Bağışlar',
+'sitesupport-url' => 'Project:Bağış',
+'faq' => 'SSS',
+'faqpage' => 'Project:SSS',
+'edithelp' => 'Nasıl değiştirilir?',
+'newwindow' => '(yeni bir pencerede açılır)',
+'edithelppage' => 'Yardım:Sayfa nasıl değiştirilir',
+'cancel' => 'İptal',
+'qbfind' => 'Bul',
+'qbbrowse' => 'Tara',
+'qbedit' => 'Değiştir',
+'qbpageoptions' => 'Bu sayfa',
+'qbpageinfo' => 'Bağlam',
+'qbmyoptions' => 'Sayfalarım',
+'qbspecialpages' => 'Özel sayfalar',
+'moredotdotdot' => 'Daha...',
+'mypage' => 'Sayfam',
+'mytalk' => 'Mesaj Sayfam',
+'anontalk' => 'Bu IP\'nin mesajları',
+'navigation' => 'Sitede yol bulma',
+'metadata_help' => 'Metadata (bunun açıklama için [[Project:Metadata]] bakınız):',
+'currentevents' => 'Güncel olaylar',
+'currentevents-url' => 'Güncel olaylar',
+'disclaimers' => 'Feragatname',
+'disclaimerpage' => 'Project:Genel_Bilgi_Paktı',
+'privacy' => 'Gizlilik ilkesi',
+'privacypage' => 'Project:Gizlilik_ilkesi',
+'errorpagetitle' => 'Hata',
+'returnto' => '$1.',
+'tagline' => '{{SITENAME}}, özgür ansiklopedi',
+'search' => 'Ara',
+'searchbutton' => 'Ara',
+'go' => 'Git',
+'searcharticle' => 'Git',
+'history' => 'Sayfanın geçmişi',
+'history_short' => 'Geçmiş',
+'updatedmarker' => 'son ziyaretimden sonra güncellenmiş',
+'printableversion' => 'Basılmaya uygun görünüm',
+'permalink' => 'Son haline bağlantı',
+'print' => 'Bastır',
+'edit' => 'Değiştir',
+'editthispage' => 'Sayfayı değiştir',
+'delete' => 'Sil',
+'deletethispage' => 'Sayfayı sil',
+'undelete_short' => '$1 değişikliği geri getir',
+'protect' => 'Korumaya al',
+'protectthispage' => 'Sayfayı koruma altına al',
+'unprotect' => 'Korumayı kaldır',
+'unprotectthispage' => 'Sayfa korumasını kaldır',
+'newpage' => 'Yeni sayfa',
+'talkpage' => 'Sayfayı tartış',
+'specialpage' => 'Özel Sayfa',
+'personaltools' => 'Kişisel aletler',
+'postcomment' => 'Yorum ekle',
+'articlepage' => 'Maddeye git',
+'talk' => 'Tartışma',
+'views' => 'Görünümler',
+'toolbox' => 'Araçlar',
+'userpage' => 'Kullanıcı sayfasını görüntüle',
+'projectpage' => 'Proje sayfasına bak',
+'viewtalkpage' => 'Tartışma sayfasına git',
+'otherlanguages' => 'Diğer diller',
+'redirectedfrom' => '($1 sayfasından yönlendirildi)',
+'autoredircomment' => '[[$1]] sayfasına yönlendirildi',
+'redirectpagesub' => 'Yönlendirme sayfası',
+'lastmodifiedat' => 'Bu sayfa son olarak $2, $1 tarihinde güncellenmiştir.',
+'viewcount' => 'Bu sayfaya $1 defa erişilmiş.',
+'copyright' => 'İçerik $1 altındadır.',
+'protectedpage' => 'Korumalı sayfa',
+'jumpto' => 'Git ve:',
+'jumptonavigation' => 'kullan',
+'jumptosearch' => 'ara',
+'badaccess' => 'İzin hatası',
+'versionrequired' => 'MedyaViki\'nin $1 sürümü gerekiyor',
+'ok' => 'TAMAM',
+'retrievedfrom' => '"$1"\'dan alındı',
+'youhavenewmessages' => 'Yeni <u>$1</u> var. ($2)',
+'newmessageslink' => 'mesajınız',
+'newmessagesdifflink' => 'Bir önceki sürüme göre eklenen yazı farkı',
+'editsection' => 'değiştir',
+'editold' => 'değiştir',
+'editsectionhint' => 'Değiştirilen bölüm: $1',
+'toc' => 'Konu başlıkları',
+'showtoc' => 'göster',
+'hidetoc' => 'gizle',
+'thisisdeleted' => '$1 görmek veya geri getirmek istermisin?',
+'viewdeleted' => '$1 gör?',
+'restorelink' => 'silinmiş $1 değişikliği',
+'nstab-main' => 'Madde',
+'nstab-user' => 'kullanıcı sayfası',
+'nstab-media' => 'Medya',
+'nstab-special' => 'Özel',
+'nstab-project' => 'Proje sayfası',
+'nstab-image' => 'Dosya',
+'nstab-mediawiki' => 'arayüz metni',
+'nstab-template' => 'şablon',
+'nstab-help' => 'yardım',
+'nstab-category' => 'Kategori',
+'nosuchspecialpage' => 'Bu isimde bir özel sayfa yok',
+'nospecialpagetext' => 'Bulunmayan bir özel sayfaya girdiniz. Varolan tüm özel sayfaları [[Special:Specialpages]] sayfasında görebilirsiniz.',
+'error' => 'Hata',
+'databaseerror' => 'Veritabanı hatası',
+'dberrortext' => 'Veritabanı hatası.
+Bu bir yazılım hatası olabilir.
+"<tt>$2</tt>" işlevinden denenen son sorgulama:
+<blockquote><tt>$1</tt></blockquote>.
+
+MySQL\'in rapor ettiği hata "<tt>$3: $4</tt>".',
+'cachederror' => 'Aşağıdaki, istediğiniz sayfanın önbellekteki kopyasıdır ve güncel olmayabilir.',
+'readonly' => 'Veritabanı kilitlendi',
+'readonlytext' => 'Veritabanı olağan bakım/onarım çalışmaları sebebiyle, geçici olarak giriş ve değişiklik yapmaya kapatılmıştır. Kısa süre sonra normale dönecektir.
+
+Veritabanını kilitleyen operatörün açıklaması: $1',
+'internalerror' => 'Yazılım hatası',
+'unexpected' => 'beklenmeyen değer: "$1"="$2".',
+'badarticleerror' => 'Yapmak istediğiniz işlem geçersizdir.',
+'cannotdelete' => 'Belirtilen sayfa ya da görüntü silinemedi. (başka bir kullanıcı tarafından silinmiş olabilir).',
+'badtitle' => 'Geçersiz başlık',
+'perfdisabled' => 'Özür dileriz! Bu özellik, veritabanını kullanılamayacak derecede yavaşlattığı için, geçici olarak kullanımdan çıkarıldı.',
+'perfcached' => 'Veriler daha önceden hazırlanmış olabilir. Bu sebeple güncel olmayabilir!',
+'perfcachedts' => 'Aşağıda saklanmış bilgiler bulunmaktadır, son güncelleme zamanı: $1.',
+'viewsource' => 'Kaynağı gör',
+'viewsourcefor' => '$1 için',
+'protectedtext' => 'Bu sayfa değiştirilmemesi için \'\'\'koruma altına alınmıştır\'\'\' ya da yalnız kayıtlı kullanıcılar tarafından değiştirilebilir. Bunun bir çok değişik sebebi olabilir. [[Project:Koruma altına alınmış sayfa|Koruma altına alınma sebepleri]] ile ilgili sayfaya gözatınız. Bunun nedenini [[{{TALKPAGENAME}}|sayfasında tartışabilirsiniz]].
+
+Bu sayfanın kaynak koduna bakıp kopyalayabilirsiniz:',
+'editinginterface' => '<div style="background: #FFBDBD; border: 1px solid #BB7979; color: #000000; font-weight: bold; margin: 2em 0 1em; padding: .5em 1em; vertical-align: middle; clear: both;">UYARI: Yazılım için arayüz sağlamakta kullanılan bir sayfayı değiştirmektesiniz. Bu sayfadaki değişiklikler kullanıcı arayüzünü diğer kullanıcılar için de değiştirecektir.</div>',
+'logouttitle' => 'Oturumu kapat',
+'logouttext' => 'Oturumu kapattınız.
+Şimdi kimliğinizi belirtmeksizin {{SITENAME}} sitesini kullanmaya devam edebilirsiniz, ya da yeniden oturum açabilirsiniz (ister aynı kullanıcı adıyla, ister başka bir kullanıcı adıyla). Web tarayıcınızın önbelleğini temizleyene kadar bazı sayfalar sanki hala oturumunuz açıkmış gibi görünebilir.',
+'welcomecreation' => '== Hoşgeldiniz, $1! ==
+
+Hesabınız yaratıldı. {{SITENAME}} tercihlerinizi değiştirmeyi unutmayın.',
+'loginpagetitle' => 'Oturum aç',
+'yourname' => 'Kullanıcı adınız',
+'yourpassword' => 'Parolanız',
+'yourpasswordagain' => 'Parolayı yeniden yaz',
+'remembermypassword' => 'Parolayı hatırla.',
+'yourdomainname' => 'Alan adınız',
+'alreadyloggedin' => '<span style="color:#ff0000"><b>$1 rumuzlu kullanıcı, halen açık bir oturum var!</b></span><br />',
+'login' => 'Oturum aç',
+'loginprompt' => 'Dikkat: {{SITENAME}} sitesinde oturum açabilmek için tarayıcınızda çerezlerin (cookies) aktifleştirilmiş olması gerekmektedir.<br />
+Kullanıcı adınız Türkçe karakter, boşluk \'\'\'içerebilir\'\'\'. Kullanıcı adınıza e-posta adresi \'\'\'girmemeniz\'\'\' tavsiye edilir.',
+'userlogin' => 'Oturum aç ya da yeni hesap edin',
+'logout' => 'Oturumu kapat',
+'userlogout' => 'Oturumu kapat',
+'notloggedin' => 'Oturum açık değil',
+'nologin' => 'Daha üye değil misiniz? $1.',
+'nologinlink' => 'Eğer şimdiye kadar kayıt olmadıysanız bu bağlantıyı takip edin.',
+'createaccount' => 'Yeni hesap aç',
+'gotaccount' => 'Daha önceden kayıt oldunuz mu? $1.',
+'gotaccountlink' => 'Eğer önceden hesap açtırdıysanız bu bağlantıdan giriş yapınız.',
+'createaccountmail' => 'e-posta ile',
+'badretype' => 'Girdiğiniz parolalar birbirini tutmuyor.',
+'userexists' => 'Girdiğiniz kullanıcı adı kullanımda. Lütfen farklı bir kullanıcı adı seçin.',
+'youremail' => 'E-posta adresiniz*',
+'username' => 'Kullanıcı adı:',
+'uid' => 'Kayıt numarası:',
+'yourrealname' => 'Gerçek isminiz*',
+'yourlanguage' => 'Arayüz dili',
+'yourvariant' => 'Sizce',
+'yournick' => 'İmzalarda gözükmesini istediğiniz isim',
+'email' => 'E-posta',
+'prefs-help-realname' => '* Gerçek isim (isteğe bağlı): eğer gerçek isminizi vermeyi seçerseniz, çalışmanızı size atfederken kullanılacaktır.',
+'loginerror' => 'Oturum açma hatası.',
+'prefs-help-email' => '* E-posta (isteğe bağlı): Diğer kullanıcıların kullanıcı sayfanız aracılığıyla <strong>adresinizi bilmeksizin</strong> sizle iletişim kurmasını sağlar.',
+'nocookieslogin' => '{{SITENAME}} sitesinde oturum açabilmek için çerezlerinizin açık olması gerekiyor. Sizin çerezleriniz kapalı. Lütfen açınız ve bir daha deneyiniz.',
+'loginsuccesstitle' => 'Oturum açıldı',
+'loginsuccess' => '{{SITENAME}} sitesinde "$1" kullanıcı adıyla oturum açmış bulunmaktasınız.',
+'wrongpassword' => 'Parolayı yanlış girdiniz. Lütfen tekrar deneyiniz.',
+'wrongpasswordempty' => 'Boş parola girdiniz. Lütfen tekrar deneyiniz.',
+'mailmypassword' => 'Bana e-posta ile yeni bir parola gönder',
+'passwordremindertitle' => '{{SITENAME}} sitesinden şifre hatırlatıcısı.',
+'passwordremindertext' => '$1 IP adresinden (muhtemelen siz) {{SERVERNAME}} için yeni bir {{SITENAME}} ($4) parolası gönderilmesi istendi.
+"$2" rumuzlu kullanıcının yeni parolası: "$3"
+Oturum açıp parolanızı değiştirmelisiniz.
+
+Parola değişimini siz istemediyseniz, ya da parolanızı hatırlayıp değiştirmekten vazgeçtiyseniz bu iletiyi görmezden gelip eski parolanızı kullanmaya devam edebilirsiniz.',
+'noemail' => '"$1" adlı kullanıcıya kayıtlı bir e-posta adresi yok.',
+'passwordsent' => '"$1" adına kayıtlı e-posta adresine yeni bir parola gönderildi. Oturumu, lütfen, iletiyi aldıktan sonra açın.',
+'eauthentsent' => 'Kaydedilen adrese onay kodu içeren bir e-posta gönderildi.
+E-postadaki yönerge uygulanıp adresin size ait olduğu onaylanmadıkça başka e-posta gönderilmeyecek.',
+'mailerror' => 'E-posta gönderim hatası: $1',
+'acct_creation_throttle_hit'=> '$1 tane kullanıcı hesabı açtırmış durumdasınız. Daha fazla açtıramazsınız.',
+'emailauthenticated' => 'E-posta adresiniz $1 tarihinde doğrulanmıştı.',
+'emailnotauthenticated' => 'E-posta adresiniz henüz onaylanmadı.
+Aşağıdaki işlevlerin hiçbiri için e-posta gönderilmeyecektir.',
+'emailconfirmlink' => 'E-posta adresinizi doğrulayın',
+'invalidemailaddress' => 'E-posta adresi geçersizdir. Lütfen geçerli bir adres yazın ya da metin kutusunun içeriğini silin.',
+'accountcreated' => 'Hesap açıldı',
+'accountcreatedtext' => '$1 için bir kullanıcı hesabı açıldı.',
+'bold_sample' => 'Kalın yazı',
+'bold_tip' => 'Kalın yazı',
+'italic_sample' => 'İtalik yazı',
+'italic_tip' => 'İtalik yazı',
+'link_sample' => 'Sayfanın başlığı',
+'link_tip' => 'İç bağlantı',
+'extlink_sample' => '{{SERVER}} adres açıklaması',
+'extlink_tip' => 'Dış bağlantı (Adresin önüne http:// koymayı unutmayın)',
+'headline_sample' => 'Başlık yazısı',
+'headline_tip' => '2. seviye başlık',
+'math_sample' => 'Matematiksel-ifadeyi-girin',
+'math_tip' => 'Matematik formülü (LaTeX formatında)',
+'nowiki_sample' => 'Serbest format yazınızı buraya yazınız',
+'nowiki_tip' => 'wiki formatlamasını devre dışı bırak',
+'image_sample' => 'Örnek.jpg',
+'image_tip' => 'Resim ekleme',
+'media_sample' => 'Örnek.ogg',
+'media_tip' => 'Medya dosyasına bağlantı',
+'sig_tip' => 'İmzanız ve tarih',
+'hr_tip' => 'Yatay çizgi (çok sık kullanmayın)',
+'summary' => 'Özet',
+'subject' => 'Konu/başlık',
+'minoredit' => 'Küçük değişiklik',
+'watchthis' => 'Sayfayı izle',
+'savearticle' => 'Sayfayı kaydet',
+'preview' => 'Önizleme',
+'showpreview' => 'Önizlemeyi göster',
+'showlivepreview' => 'Canlı önizleme',
+'showdiff' => 'Değişiklikleri göster',
+'anoneditwarning' => 'Oturum açmadığınızdan maddenin değişiklik kayıtlarına rumuzunuz yerine IP adresiniz kaydedilecektir.',
+'missingsummary' => '\'\'\'Uyarı:\'\'\' Herhangi bir özet yazmadın. Kaydet tuşu bir daha bastığında sayfayı özetsiz kaydetilecek.',
+'missingcommenttext' => 'Lütfen aşağıda bir açıklama yazınız.',
+'blockedtitle' => 'Kullanıcı erişimi engellendi.',
+'blockedtext' => 'Erişiminiz $1 tarafından durdurulmuştur.
+Sebep:<br />\'\'$2\'\'<br />$1 ya da başka bir [[Project:Yöneticiler|yönetici]] ile bu durumu görüşebilirsiniz.
+
+Eğer [[Special:Preferences|tercihler]] kısmında geçerli bir e-posta adresi girmediyseniz "Kullanıcıya e-posta gönder" özelliğini kullanamazsınız.
+
+Sizin IP adresiniz $3. Lütfen sorgu yaparken bu adresi kullanınız.',
+'whitelistedittitle' => 'Değişiklik yapmak için oturum açmalısınız',
+'whitelistedittext' => 'Değişiklik yapabilmek için $1.',
+'whitelistreadtitle' => 'Okumak için oturum açmalısınız',
+'whitelistreadtext' => 'Sayfaları okuyabilmek için [[Special:Userlogin|oturum açmalısınız]].',
+'whitelistacctitle' => 'Hesap açma izniniz yok.',
+'confirmedittitle' => 'Değişiklik yapmak için e-posta onaylaması gerekiyor',
+'confirmedittext' => 'Sayfa değiştirmeden önce e-posta adresinizi onaylamalısınız. Lütfen [[Special:Preferences|tercihler]] kısmından e-postanızı ekleyin ve onaylayın.',
+'loginreqtitle' => 'Oturum açmanız gerekiyor',
+'loginreqlink' => 'oturum aç',
+'accmailtitle' => 'Parola gönderildi.',
+'accmailtext' => '\'$1\' kullanıcısına ait parola $2 adresine gönderildi.',
+'newarticle' => '(Yeni)',
+'newarticletext' => 'Henüz varolmayan bir sayfaya konulmuş bir bağlantıya tıkladınız. Bu sayfayı yaratmak için aşağıdaki metin kutusunu kullanınız. Bilgi için [[Help:İçindekiler|yardım sayfasına]] bakınız. Buraya yanlışlıkla geldiyseniz, programınızın \'\'\'Geri\'\'\' tuşuna tıklayınız.',
+'anontalkpagetext' => '<hr style="clear: both;" />
+\'\'Bu kayıtlı olmayan ya da sisteme girmeyip anonim kalmış bir kullanıcının mesaj sayfasıdır. Bu sebeple IP adresi ile gösterilmektedir. Bu tür IP adresleri diğer insanlar tarafından da kullanılabilir. Eğer siz de bir anonim kullanıcı iseniz ve yöneltilen yorumlar sizle ilgili değilse [[Special:Userlogin|kayıt olun ya da sisteme girin ki]] ileride başka yanlış anlaşılma olmasın.\'\'<br /><nowiki>[</nowiki><small>[[Yerel internet kayıtçıları|RIR]] [[WHOIS]] bakış: [http://ws.arin.net/whois/?queryinput={{PAGENAMEE}} Amerika] [http://www.ripe.net/fcgi-bin/whois?searchtext={{PAGENAMEE}} Avrupa] [http://www.afrinic.net/cgi-bin/whois?query={{PAGENAMEE}} Afrika] [http://www.apnic.net/apnic-bin/whois.pl?searchtext={{PAGENAMEE}} Asya-Pasifik] [http://www.lacnic.net/cgi-bin/lacnic/whois?lg=EN&query={{PAGENAMEE}} Latin Amerika/Karayip]</small><nowiki>]</nowiki>',
+'noarticletext' => 'Bu sayfa boştur. Bu başlığı diğer sayfalarda [[Special:Search/{{PAGENAME}}|arayabilir]] veya bu sayfayı siz [{{fullurl:{{FULLPAGENAME}}|action=edit}} yazabilirsiniz].',
+'clearyourcache' => '\'\'\'Not:\'\'\' Ayarlarınızı kaydettikten sonra, tarayıcınızın belleğini de temizlemeniz gerekmektedir: \'\'\'Mozilla / Firefox / Safari:\'\'\' \'\'Shift\'\' e basılıyken safyayı yeniden yükleyerek veya \'\'Ctrl-Shift-R\'\' yaparak (Apple Mac için \'\'Cmd-Shift-R\'\');, \'\'\'IE:\'\'\' \'\'Ctrl-F5\'\', \'\'\'Konqueror:\'\'\' Sadece sayfayı yeniden yükle tuşuna basarak.',
+'usercssjsyoucanpreview'=> '<strong>İpucu:</strong> Sayfayı kaydetmeden önce <font style="border: 1px solid #0; background: #EEEEEE; padding : 2px">\'\'\'önizlemeyi göster\'\'\'</font>\'e tıklayarak yaptığınız yeni sayfayı gözden geçirin.',
+'usercsspreview' => '\'\'\'Sadece test ediyorsun ya da önizleme görüyorsun - kullanıcı CSS dosyası henüz kaydolmadı.\'\'\'',
+'userjspreview' => '\'\'\'Sadece test ediyorsun ya da önizleme görüyorsun - kullanıcı JavaScript\'i henüz kaydolmadı.\'\'\'',
+'userinvalidcssjstitle' => '\'\'Uyarı:\'\'\' "$1" adıyla bir tema yoktur. tema-adı.css ve .js dosyalarının adları küçük harf ile yazması gerek, yani User:Temel/\'\'\'M\'\'\'onobook.css değil, User:Temel/\'\'\'m\'\'\'onobook.css.',
+'updated' => '(Güncellendi)',
+'note' => '<strong>Not: </strong>',
+'previewnote' => 'Bu yalnızca bir önizlemedir, ve değişiklikleriniz henüz kaydedilmemiştir!',
+'session_fail_preview' => 'Özür dileriz. Oturum açılması ile ilgili veri kaybından kaynaklı değişikliğinizi kaydedemedik. Lütfen tekrar deneyiniz. Eğer bu yöntem işe yaramazsa oturumu kapatıp tekrar sisteme geri giriş yapınız.',
+'editing' => '"$1" sayfasını değiştirmektesiniz',
+'editinguser' => '"$1" sayfasını değiştirmektesiniz',
+'editingsection' => '"$1" sayfasında bölüm değiştirmektesiniz',
+'editingcomment' => '$1 sayfasına mesaj eklemektesiniz.',
+'editconflict' => 'Değişiklik çakışması: $1',
+'explainconflict' => 'Siz sayfayı değiştirirken başka biri de değişiklik yaptı.
+Yukarıdaki yazı sayfanın şu anki halini göstermektedir.
+Sizin değişiklikleriniz alta gösterilmiştir. Son değişiklerinizi yazının içine eklemeniz gerekecektir. "Sayfayı kaydet"e bastığınızda <b>sadece</b> yukarıdaki yazı kaydedilecektir. <br />',
+'yourtext' => 'Sizin metniniz',
+'storedversion' => 'Kaydedilmiş metin',
+'editingold' => '<strong>DİKKAT: Sayfanın eski bir sürümünde değişiklik yapmaktasınız.
+Kaydettiğinizde bu tarihli sürümden günümüze kadar olan değişiklikler yok olacaktır.</strong>',
+'yourdiff' => 'Karşılaştırma',
+'copyrightwarning' => '<strong>Lütfen dikkat:</strong> {{SITENAME}} sitesine yapılan bütün katkılar <i>$2</i>
+sözleşmesi kapsamındadır (ayrıntılar için $1\'a bakınız).
+Yaptığınız katkının başka katılımcılarca acımasızca değiştirilmesini ya da özgürce ve sınırsızca başka yerlere dağıtılmasını istemiyorsanız, katkıda bulunmayınız.<br />
+Ayrıca, buraya katkıda bulunarak, bu katkının kendiniz tarafından yazıldığına, ya da kamuya açık bir kaynaktan ya da başka bir özgür kaynaktan kopyalandığına güvence vermiş oluyorsunuz.<br />
+<strong><center>TELİF HAKKI İLE KORUNAN HİÇBİR ÇALIŞMAYI BURAYA EKLEMEYİNİZ!</center></strong>',
+'longpagewarning' => '<strong>UYARI: Bu sayfa $1 kilobayt büyüklüğündedir; bazı tarayıcılar değişiklik yaparken 32kb ve üstü büyüklüklerde sorunlar yaşayabilir. Sayfayı bölümlere ayırmaya çalışın.</strong>',
+'readonlywarning' => '<strong>DİKKAT: Bakım nedeni ile veritabanı şu anda kilitlidir. Bu sebeple değişiklikleriniz şu anda kaydedilememektedir. Yazdıklarınızı başka bir editöre alıp saklayabilir ve daha sonra tekrar buraya getirip kaydedebilirsiniz</strong>',
+'protectedpagewarning' => 'UYARI: Bu sayfa koruma altına alınmıştır ve yalnızca yönetici olanlar tarafından değiştirilebilir. Bu sayfayı değiştirirken lütfen [[Project:Koruma altına alınmış sayfa|korumalı sayfa kurallarını]] uygulayınız.',
+'semiprotectedpagewarning'=> '\'\'\'Uyarı\'\'\': Bu sayfa sadece kayıtlı kullanıcı olanlar tarafından değiştirilebilir.',
+'templatesused' => 'Bu sayfada kullanılan şablonlar:',
+'revhistory' => 'Sürüm geçmişi',
+'nohistory' => 'Bu sayfanın geçmiş sürümü yok.',
+'revnotfound' => 'Sürüm bulunmadı',
+'loadhist' => 'Sayfa geçmişi yükleniyor',
+'currentrev' => 'Güncel sürüm',
+'revisionasof' => 'Sayfanın $1 tarihindeki hali',
+'previousrevision' => '← Önceki hali',
+'nextrevision' => 'Sonraki hali →',
+'currentrevisionlink' => 'en güncel halini göster',
+'cur' => 'fark',
+'next' => 'sonraki',
+'last' => 'son',
+'orig' => 'asıl',
+'histlegend' => '(fark) = güncel sürümle aradaki fark,
+(son) = önceki sürümle aradaki fark, K= küçük değişiklik',
+'deletedrev' => '[silindi]',
+'histfirst' => 'En eski',
+'histlast' => 'En yeni',
+'rev-deleted-comment' => '(yorum silindi)',
+'rev-deleted-user' => '(kullanıcı adı silindi)',
+'rev-delundel' => 'göster/gizle',
+'revisiondelete' => 'Sürümleri sil/geri getir',
+'revdelete-hide-comment'=> 'Özeti gösterme',
+'revdelete-hide-user' => 'Değişikliği yapan kullanıcı adını/IP\'i gizle',
+'revdelete-hide-restricted'=> 'Bu kısıtlamaları yöneticilere ve kullanıcılara uygula',
+'revdelete-submit' => 'Seçilen sürüme uygula',
+'difference' => '(Sürümler arası farklar)',
+'lineno' => '$1. satır:',
+'editcurrent' => 'Sayfanın şu anki sürümünü değiştir',
+'compareselectedversions'=> 'Seçilen sürümleri karşılaştır',
+'searchresults' => 'Arama sonuçları',
+'searchresulttext' => '{{SITENAME}} içinde arama yapmak konusunda bilgi almak için [[Project:Arama|"{{SITENAME}} içinde arama"]] sayfasına bakabilirsiniz.',
+'searchsubtitle' => 'Aranan: "[[:$1]]" [[Special:Allpages/$1|&#x5B;Indeks&#x5D;]]',
+'noexactmatch' => '<span style="font-size: 135%; font-weight: bold; margin-left: .6em">Başlığı bu olan bir madde bulunamadı.</span> <span style="display: block; margin: 1.5em 2em"> Bu maddenin yazılmasını [[:$1|\'\'\'siz başlatabilirsiniz\'\'\']], ya da bu maddenin yazılması isteğini [[Project:Madde istekleri|istenen maddeler listesine]] ekleyebilirsiniz. <span style="display:block; font-size: 89%; margin-left:.2em">Yeni bir madde yaratmadan önce lütfen site içinde deatylı arama yapınız. İstediğiniz madde başka bir adla zaten var olabilir.</span> </span>',
+'titlematches' => 'Madde adı eşleşiyor',
+'notitlematches' => 'Hiçbir başlıkta bulunamadı',
+'textmatches' => 'Sayfa metni eşleşiyor',
+'notextmatches' => 'Hiçbir sayfada bulunamadı',
+'prevn' => 'önceki $1',
+'nextn' => 'sonraki $1',
+'viewprevnext' => '($1) ($2) ($3).',
+'showingresults' => '<b>$2.</b> sonuçtan başlayarak <b>$1</b> sonuç aşağıdadır:',
+'showingresultsnum' => '<b>$2.</b> sonuçtan başlayarak <b>$3</b> sonuç aşağıdadır:',
+'powersearch' => 'Ara',
+'powersearchtext' => 'Arama yapılacak alanları seçin :<br />
+$1<br />
+$2 yönlendirmeleri listele &nbsp; Aranacak: $3 $9',
+'searchdisabled' => '{{SITENAME}} sitesinde arama yapma geçici olarak durdurulmuştur. Bu arada Google kullanarak {{SITENAME}} içinde arama yapabilirsiniz. Arama sitelerinde indekslemelerinin biraz eski kalmış olabileceğini göz önünde bulundurunuz.',
+'blanknamespace' => '(Ana)',
+'preferences' => 'Tercihler',
+'prefsnologin' => 'Oturum açık değil',
+'qbsettings' => 'Hızlı erişim sütun ayarları',
+'changepassword' => 'Parola değiştir',
+'skin' => 'Tema',
+'math' => 'Matematiksel semboller',
+'dateformat' => 'Tarih gösterimi',
+'datedefault' => 'Tercih yok',
+'datetime' => 'Tarih ve saat',
+'math_unknown_error' => 'bilinmeyen hata',
+'prefs-personal' => 'Kullanıcı bilgileri',
+'prefs-rc' => 'Son değişiklikler',
+'prefs-watchlist' => 'İzleme listesi',
+'prefs-watchlist-days' => 'İzleme listesinde görüntülenecek gün sayısı:',
+'prefs-watchlist-edits' => 'Genişletilmiş izleme listesinde gösterilecek değişiklik sayısı:',
+'prefs-misc' => 'Diğer ayarlar',
+'saveprefs' => 'Değişiklikleri kaydet',
+'resetprefs' => 'Ayarları ilk durumuna getir',
+'oldpassword' => 'Eski parola',
+'newpassword' => 'Yeni parola',
+'retypenew' => 'Yeni parolayı tekrar girin',
+'textboxsize' => 'Sayfa yazma alanı',
+'rows' => 'Satır',
+'columns' => 'Sütun',
+'searchresultshead' => 'Arama',
+'resultsperpage' => 'Sayfada gösterilecek bulunan madde sayısı',
+'contextlines' => 'Bulunan madde için ayrılan satır sayısı',
+'contextchars' => 'Satırdaki karakter sayısı',
+'stubthreshold' => 'Taslak olarak sınıflandırılabilmek için alt sınır',
+'recentchangescount' => 'Son değişiklikler sayfasındaki madde sayısı',
+'savedprefs' => 'Ayarlar kaydedildi.',
+'timezonelegend' => 'Saat dilimi',
+'timezonetext' => 'Viki sunucusu (UTC/GMT) ile aranızdaki saat farkı. (Türkiye için +02:00)',
+'localtime' => 'Şu an sizin saatiniz',
+'timezoneoffset' => 'Saat farkı',
+'servertime' => 'Viki sunucusunda şu anki saat',
+'guesstimezone' => 'Tarayıcınız sizin yerinize doldursun',
+'allowemail' => 'Diğer kullanıcılar size e-posta atabilsin',
+'defaultns' => 'Aramayı aşağıdaki seçili alanlarda yap.',
+'default' => 'orijinal',
+'files' => 'Dosyalar',
+'userrights-lookup-user'=> 'Kullanıcı gruplarını yönet',
+'userrights-user-editname'=> 'Kullanıcı adı giriniz:',
+'editusergroup' => 'Kullanıcı grupları düzenle',
+'userrights-editusergroup'=> 'Kullanıcı grupları düzenle',
+'group' => 'Grup:',
+'group-bot' => 'Botlar',
+'group-sysop' => 'Yöneticiler',
+'group-bureaucrat' => 'Bürokratlar',
+'group-all' => '(hepsi)',
+'group-sysop-member' => 'Yönetici',
+'group-bureaucrat-member'=> 'Bürokrat',
+'grouppage-bot' => 'Project:Botlar',
+'grouppage-sysop' => 'Project:Yöneticiler',
+'grouppage-bureaucrat' => 'Project:Yöneticiler#Bürokratlar',
+'changes' => 'değişiklik',
+'recentchanges' => 'Son değişiklikler',
+'recentchangestext' => 'Yapılan en son değişiklikleri bu sayfadan izleyin.',
+'rcnote' => '$3 (UTC) tarihinde son <strong>$2</strong> günde yapılan <strong>$1</strong> değişiklik:',
+'rcnotefrom' => '<b>$2</b> tarihinden itibaren yapılan değişiklikler aşağıdadır (en fazla <b>$1</b> adet madde gösterilmektedir).',
+'rclistfrom' => '$1 tarihinden beri yapılan değişiklikleri göster',
+'rcshowhideminor' => 'küçük değişiklikleri $1',
+'rcshowhidebots' => 'botları $1',
+'rcshowhideliu' => 'kayıtlı kullanıcıları $1',
+'rcshowhideanons' => 'anonim kullanıcıları $1',
+'rcshowhidepatr' => 'izlenmiş değişiklikleri $1',
+'rcshowhidemine' => 'değişikliklerimi $1',
+'rclinks' => 'Son $2 günde yapılan son $1 değişikliği göster;<br /> $3',
+'diff' => 'fark',
+'hist' => 'geçmiş',
+'hide' => 'gizle',
+'show' => 'göster',
+'minoreditletter' => 'K',
+'newpageletter' => 'Y',
+'upload' => 'Dosya yükle',
+'uploadbtn' => 'Dosya yükle',
+'reupload' => 'Yeniden yükle',
+'reuploaddesc' => 'Yükleme formuna geri dön.',
+'uploadnologin' => 'Oturum açık değil',
+'uploadnologintext' => 'Dosya yükleyebilmek için [[Special:Userlogin|oturum aç]]manız gerekiyor.',
+'uploaderror' => 'Yükleme hatası',
+'uploadtext' => 'Dosya yüklemek için aşağıdaki formu kullanın,
+Önceden yüklenmiş resimleri görmek için [[Special:Imagelist|resim listesine]] bakın,
+yüklenenler ve silinmişler [[Special:Log/upload|yükleme kaydı sayfasında da]] görülebilir.
+
+Sayfaya resim koymak için;
+*\'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Örnek.jpg]]</nowiki>\'\'\'
+*\'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:Örnek.png|açıklama]]</nowiki>\'\'\'
+veya doğrudan bağlantı için
+*\'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:Örnek.ogg]]</nowiki>\'\'\'',
+'uploadlog' => 'yükleme kaydı',
+'uploadlogpage' => 'Dosya yükleme kayıtları',
+'uploadlogpagetext' => 'Aşağıda en son eklenen dosyaların bir listesi bulunmaktadır.',
+'filename' => 'Dosya',
+'filedesc' => 'Dosya ile ilgili açıklama',
+'fileuploadsummary' => 'Açıklama:',
+'filestatus' => 'Telif hakkı durumu',
+'filesource' => 'Kaynak',
+'copyrightpage' => 'Project:Telif hakları',
+'copyrightpagename' => '{{SITENAME}} telif hakları',
+'uploadedfiles' => 'Yüklenen dosyalar',
+'ignorewarning' => 'Uyarıyı önemsemeyip dosyayı yükle',
+'ignorewarnings' => 'Uyarıyı önemseme',
+'badfilename' => 'Görüntü dosyasının ismi "$1" olarak değiştirildi.',
+'badfiletype' => '".$1" önerilen bir görüntü formatı değildir.',
+'largefile' => 'Resimlerin boyutlarının $1 baytı geçmemesi gerekiyor, bu dosya $2 bayt uzunluğunda',
+'largefileserver' => 'Bu dosyanın uzunluğu sunucuda izin verilenden daha büyüktür.',
+'fileexists' => 'Bu isimde bir dosya mevcut. Eğer değiştirmekten emin değilseniz ilk önce $1 dosyasına bir gözatın.',
+'successfulupload' => 'Yükleme başarılı',
+'fileuploaded' => '$1 dosyası başarı ile yüklendi.
+
+Lütfen $2 bağlantısını takip ederek dosya ile ilgili açıklama yazısı yazınız. Dosya nerden geldi, kim tarafından ne zaman oluşturuldu ya da hakında bildiğiniz diğer bilgiler gibi.
+
+Eğer bu bir resim ise <tt><nowiki>[[{{ns:Image}}:$1|thumb|açıklama]]</nowiki></tt> şeklinde sayfaya yerleştirebilirsiniz. (açıklama yerine resim ile ilgili yazı yazınız)',
+'uploadwarning' => 'Yükleme uyarısı',
+'savefile' => 'Dosyayı kaydet',
+'uploadedimage' => 'Yüklenen: "[[$1]]"',
+'uploaddisabled' => 'Geçici olarak şu anda herhangi bir dosya yüklenmez. Biraz sonra bir daha deneyiniz.',
+'uploaddisabledtext' => 'Bu wikide dosya yükleme özelliği iptal edilmiştir.',
+'uploadvirus' => 'Bu dosya virüslüdür! Detayları: $1',
+'sourcefilename' => 'Yüklemek istediğiniz dosya',
+'destfilename' => '{{SITENAME}} sitesindeki dosya adı',
+'imagelist' => 'Resim listesi',
+'ilsubmit' => 'Ara',
+'showlast' => 'En son $1 dosyayı $2 göster.',
+'byname' => 'alfabetik sırayla',
+'bydate' => 'kronolojik sırayla',
+'bysize' => 'boyut sırasıyla',
+'imgdelete' => 'sil',
+'imgdesc' => 'tanım',
+'imglegend' => 'Gösterim: (tanım) = Dosyanın açıklamasını göster ya da değiştir.',
+'imghistory' => 'Dosya geçmişi',
+'deleteimg' => 'sil',
+'deleteimgcompletely' => 'Dosyayı tamamen silin',
+'imagelinks' => 'Kullanıldığı sayfalar',
+'linkstoimage' => 'Bu görüntü dosyasına bağlantısı olan sayfalar:',
+'nolinkstoimage' => 'Bu görüntü dosyasına bağlanan sayfa yok.',
+'sharedupload' => 'Bu dosya ortak alana yüklenmiştir ve diğer projelerde de kullanılıyor olabilir.',
+'shareduploadwiki-linktext'=> 'dosya açıklama sayfası',
+'noimage' => 'Bu isimde dosya yok. Siz $1.',
+'noimage-linktext' => 'yükleyebilirsiniz',
+'uploadnewversion-linktext'=> 'Dosyanın yenisini yükleyin',
+'mimesearch' => 'MIME araması',
+'mimetype' => 'MIME tipi:',
+'download' => 'yükle',
+'unwatchedpages' => 'İzlenmeyen sayfalar',
+'listredirects' => 'Yönlendirmeleri listele',
+'unusedtemplates' => 'Kullanılmayan şablonlar',
+'unusedtemplatestext' => 'Bu sayfa şablon alan adında bulunan ve diğer sayfalara eklenmemiş olan şablonları göstermektedir. Şablonlara olan diğer bağlantıları da kontrol etmeden silmeyiniz.',
+'unusedtemplateswlh' => 'diğer bağlantılar',
+'randomredirect' => 'Rastgele yönlendirme',
+'statistics' => 'İstatistikler',
+'sitestats' => '{{SITENAME}} sitesi istatistikleri',
+'userstats' => 'Kullanıcı istatistikleri',
+'sitestatstext' => '{{SITENAME}} sitesinde şu anda \'\'\'$2\'\'\' geçerli sayfa mevcuttur.
+
+Bu sayıya; "yönlendirme", "tartışma", "resim", "kullanıcı", "yardım", "{{SITENAME}}", "şablon" alanlarındakiler ve iç bağlantı içermeyen maddeler dahil değildir. Geçerli madde sayısına bu sayfaların sayısı eklendiğinde ise toplam \'\'\'$1\'\'\' sayfa mevcuttur.
+
+$8 tane dosya yüklenmiştir.
+
+Site kurulduğundan bu güne kadar toplam \'\'\'$4\'\'\' sayfa değişikliği ve sayfa başına ortalama \'\'\'$5\'\'\' katkı olmuştur.
+
+Toplam sayfa görüntülenme sayısı \'\'\'$3\'\'\', değişiklik başına görüntüleme sayısı \'\'\'$6\'\'\' olmuştur.
+
+Şu andaki [http://meta.wikimedia.org/wiki/Help:Job_queue iş kuyruğu] sayısı \'\'\'$7\'\'\'.',
+'userstatstext' => 'Şu anda \'\'\'$1\'\'\' kayıtlı kullanıcımız var. Bunlardan <b>$2</b> tanesi (ya da %$4) yöneticidir. (bakın $3)',
+'disambiguations' => 'Anlam ayrım sayfaları',
+'disambiguationspage' => 'Şablon:Anlam ayrım',
+'disambiguationstext' => 'Aşağıdaki maddeler <i>anlam ayrım sayfaları</i>na bağlıdırlar. Onun yerine uygun başlığa yönlendirilmeliler.<br />Sayfalar, $1\'den bağlanılması halinde "anlam ayrım" sayfası olarak sınıflandırılıyor.<br />Diğer alan adlarına ait bağlantılar listelen<b>me</b>miştir:',
+'doubleredirects' => 'Yönlendirmeye olan yönlendirmeler',
+'doubleredirectstext' => 'Her satır, ikinci yönlendirme metninin ilk satırının (genellikle ikinci yönlendirmenin de işaret etmesi gereken "asıl" hedefin) yanısıra ilk ve ikinci yönlendirmeye bağlantılar içerir.',
+'brokenredirects' => 'Varolmayan maddeye yapılmış yönlendirmeler',
+'brokenredirectstext' => 'Aşağıdaki yönlendirme, mevcut olmayan bir sayfaya işaret ediyor.',
+'nbytes' => '$1 bayt',
+'ncategories' => '$1 kategori',
+'nlinks' => '$1 bağlantı',
+'nmembers' => '$1 üye',
+'nrevisions' => '$1 gözden geçirme',
+'nviews' => '$1 görünüm',
+'lonelypages' => 'Kendisine hiç bağlantı olmayan sayfalar',
+'uncategorizedpages' => 'Herhangi bir kategoride olmayan sayfalar',
+'uncategorizedcategories'=> 'Herhangi bir kategoride olmayan kategoriler',
+'uncategorizedimages' => 'Herhangi bir kategoride olmayan resimler',
+'unusedcategories' => 'Kullanılmayan kategoriler',
+'unusedimages' => 'Kullanılmayan resimler',
+'popularpages' => 'Popüler sayfalar',
+'wantedcategories' => 'İstenen kategoriler',
+'wantedpages' => 'İstenen sayfalar',
+'mostlinked' => 'Kendisine en fazla bağlantı verilmiş sayfalar',
+'mostlinkedcategories' => 'En çok maddeye sahip kategoriler',
+'mostcategories' => 'En fazla kategoriye bağlanmış sayfalar',
+'mostimages' => 'En çok kullanılan resimler',
+'mostrevisions' => 'En çok değişikliğe uğramış sayfalar',
+'allpages' => 'Tüm sayfalar',
+'randompage' => 'Rastgele sayfa',
+'shortpages' => 'Kısa sayfalar',
+'longpages' => 'Uzun sayfalar',
+'deadendpages' => 'Başka sayfalara bağlantısı olmayan sayfalar',
+'listusers' => 'Kullanıcı listesi',
+'specialpages' => 'Özel sayfalar',
+'spheading' => 'Tüm kullanıcıları ilgilendirebilecek özel sayfalar',
+'restrictedpheading' => 'Yöneticilerin yetkileri ile ilgili özel sayfalar',
+'recentchangeslinked' => 'İlgili değişiklikler',
+'rclsub' => '("$1" sayfasına bağlanan sayfalarda)',
+'newpages' => 'Yeni sayfalar',
+'ancientpages' => 'En son değişiklik tarihi en eski olan maddeler',
+'intl' => 'Diller arası bağlantılar',
+'move' => 'Adını değiştir',
+'movethispage' => 'Sayfayı taşı',
+'booksources' => 'Kaynak kitaplar',
+'categoriespagetext' => 'Vikide aşağıdaki kategoriler mevcuttur.',
+'data' => 'Veri',
+'userrights' => 'Kullanıcı hakları yönetimi.',
+'groups' => 'Kullanıcı grupları',
+'booksourcetext' => 'Aşağıda yeni ve kullanılmış kitap satan sitelerin linklerinin bir listesi var. Ayrıca aradığınız kitaplar hakkında daha fazla bilgiyi de bu sayfalarda bulabilirsiniz.',
+'alphaindexline' => '$1 \'den $2\'e',
+'version' => 'Sürüm',
+'log' => 'Kayıtlar',
+'alllogstext' => '[[Special:Log/upload|Yükleme]], [[Special:Log/delete|silme]], [[Special:Log/move|taşıma]], [[Special:Log/protect|koruma altına alma]], [[Special:Log/newusers|yeni kullanıcı]], [[Special:Log/renameuser|kullanıcıların yeniden adlandırmaları]], [[Special:Log/block|erişim engelleme]], [[Special:Log/rights|yönetici hareketlerinin]] ve [[Special:Log/makebot|botların durumunun]] tümünün kayıtları.
+
+Kayıt tipini, kullanıcı ismini, sayfa ismini girerek listeyi daraltabilirsiniz.',
+'logempty' => 'Kayıtlarda eşleşen bilgi yok.',
+'nextpage' => 'Sonraki sayfa ($1)',
+'allpagesfrom' => 'Listelemeye başlanılacak harfler:',
+'allarticles' => 'Tüm maddeler',
+'allinnamespace' => 'Tüm sayfalar ($1 sayfaları)',
+'allnotinnamespace' => 'Tüm sayfalar ($1 alanında olmayanlar)',
+'allpagesprev' => 'Önceki',
+'allpagesnext' => 'Sonraki sayfa',
+'allpagessubmit' => 'Getir',
+'allpagesprefix' => 'Yazdığınız harflerle başlayan sayfaları göster:',
+'mailnologin' => 'Gönderi adresi yok.',
+'mailnologintext' => 'Diğer kullanıcılara e-posta gönderebilmeniz için [[Special:Userlogin|oturum aç]]malısınız ve [[Special:Preferences|tercihler]] sayfasında geçerli bir e-posta adresiniz olmalı.',
+'emailuser' => 'Kullanıcıya e-posta gönder',
+'emailpage' => 'Kullanıcıya e-posta gönder',
+'emailpagetext' => 'Aşağıdaki form kullanıcı hesabıyla ilişkilendirilmiş geçerli bir e-posta
+adresi olduğu takdirde ilgili kişiye bir e-posta gönderecek.
+
+Yanıt alabilmeniz için "From" (Kimden) kısmına tercih formunda belirttiğiniz e-posta adresi eklenecek.',
+'defemailsubject' => '{{SITENAME}} e-posta',
+'noemailtitle' => 'e-posta adresi yok',
+'noemailtext' => 'Kullanıcı e-posta adresi belirtmemiş ya da diğer kullanıcılardan posta almak istemiyor.',
+'emailfrom' => 'Kimden',
+'emailto' => 'Kime',
+'emailsubject' => 'Konu',
+'emailmessage' => 'E-posta',
+'emailsend' => 'Gönder',
+'emailsent' => 'E-posta gönderildi',
+'emailsenttext' => 'e-postanız gönderildi.',
+'watchlist' => 'İzleme listem',
+'watchlistfor' => '(\'\'\'$1\'\'\' için)',
+'watchlistanontext' => 'Lütfen izleme listenizdeki maddeleri görmek yada değiştirmek için $1.',
+'watchlistcount' => '\'\'\'İzleme listenizde $1 sayfa var (tartışma ve mesaj sayfa dahil).\'\'\'',
+'clearwatchlist' => 'İzleme listesini temizle',
+'watchlistcleartext' => 'İzleme listenizi tamamen silmek istediğinizden emin misiniz?',
+'watchlistclearbutton' => 'İzleme listemi sil.',
+'watchlistcleardone' => 'İzleme listesi silindi - $1 madde listeden çıkarıldı.',
+'watchnologin' => 'Oturum açık değil.',
+'watchnologintext' => 'İzleme listenizi değiştirebilmek için [[Special:Userlogin|oturum açmalısınız]].',
+'addedwatch' => 'İzleme listesine kaydedildi.',
+'addedwatchtext' => '"$1" adlı sayfa [[Special:Watchlist|izleme listenize]] kaydedildi.
+
+Gelecekte, bu sayfaya ve ilgili tartışma sayfasına yapılacak değişiklikler burada listelenecektir.
+
+Kolayca seçilebilmeleri için de [[Special:Recentchanges|son değişiklikler listesi]] başlığı altında koyu harflerle listeleneceklerdir.
+
+Sayfayı izleme listenizden çıkarmak istediğinizde "sayfayı izlemeyi durdur" bağlantısına tıklayabilirsiniz.',
+'removedwatch' => 'İzleme listenizden silindi',
+'removedwatchtext' => '"$1" sayfası izleme listenizden silinmiştir.',
+'watch' => 'İzlemeye al',
+'watchthispage' => 'Sayfayı izle',
+'unwatch' => 'Sayfa izlemeyi durdur',
+'unwatchthispage' => 'Sayfa izlemeyi durdur',
+'watchnochange' => 'Gösterilen zaman aralığında izleme listenizdeki sayfaların hiçbiri güncellenmemiş.',
+'watchdetails' => '* Tartışma sayfaları hariç $1 sayfa izleme listenizdedir.
+* [[Special:Watchlist/edit|İzleme listesinin tamamını göster ve yapılandır]]
+* [[Special:Watchlist/clear|İzleme listesini tamamen boşalt]]',
+'wlheader-enotif' => '* E-mail ile haber verme açılmıştır.',
+'wlheader-showupdated' => '* Son ziyaretinizden sonraki sayfa değişikleri \'\'\'kalın\'\'\' olarak gösterilmiştir.',
+'watchmethod-recent' => 'son değişiklikler arasında izledğiniz sayfalar aranıyor',
+'watchmethod-list' => 'izleme listenizdeki sayfalar kontrol ediliyor',
+'removechecked' => 'İşaretli sayfaları izleme listesinden sil',
+'watchlistcontains' => 'İzleme listenizde $1 sayfa var.',
+'watcheditlist' => 'İzlediğiniz sayfaların alfabetik listesi aşağıdadır.
+Sayfaları izleme listesinden çıkarmak için yanlarındaki
+kutucukları işaretleyip sayfanın altındaki \'işaretlenenleri sil\'
+düğmesini tıklayınız.',
+'removingchecked' => 'İşaretlenen sayfalar izleme listesinden siliniyor...',
+'wlnote' => '{{CURRENTTIME}} {{CURRENTMONTHNAME}} {{CURRENTDAY}} (UTC) tarihinde son <b>$2</b> saatte yapılan $1 değişiklik aşağıdadır.',
+'wlshowlast' => 'Son $1 saati $2 günü göster $3',
+'wlsaved' => 'İzleme listenizin kaydedilmiş sürümüdür.',
+'wlhideshowown' => 'Kendi değişikliklerimi $1.',
+'wlhideshowbots' => 'Bot tarafından yapılan değişiklikleri $1',
+'wldone' => 'Tamam.',
+'enotif_reset' => 'Tüm sayfaları ziyaret edilmiş olarak işaretle',
+'enotif_newpagetext' => 'Yeni bir sayfa.',
+'changed' => 'değiştirildi',
+'created' => 'yaratıldı',
+'enotif_body' => 'Sayın $WATCHINGUSERNAME,
+
+{{SITENAME}} sitesindeki $PAGETITLE başlıklı sayfa $PAGEEDITDATE tarihinde $PAGEEDITOR tarafından $CHANGEDORCREATED. Geçerli sürüme $PAGETITLE_URL adresinden ulaşabilirsiniz.
+
+$NEWPAGE
+
+Açıklaması: $PAGESUMMARY $PAGEMINOREDIT
+
+Sayfayı değiştiren kullanıcının erişim bilgileri:
+e-posta: $PAGEEDITOR_EMAIL
+Viki: $PAGEEDITOR_WIKI
+
+Bahsi geçen sayfayı ziyaret etmediğiniz sürece sayfayla ilgili başka değişiklik uyarısı gönderilmeyecektir. Uyarı ayarlarını izleme listenizdeki tüm sayfalar için değiştirebilirsiniz.
+
+{{SITENAME}} uyarı sistemi.
+
+--
+Ayarları değiştirmek için:
+{{fullurl:Special:Watchlist/edit}}
+
+Yardım ve öneriler için:
+{{fullurl:Help:Contents}}',
+'deletepage' => 'Sayfayı sil',
+'confirm' => 'Onayla',
+'excontent' => 'eski içerik: \'$1\'',
+'excontentauthor' => 'eski içerik: \'$1\' (\'$2\' katkıda bulunmuş olan tek kullanıcı)',
+'exbeforeblank' => 'Silinmeden önceki içerik: \'$1\'',
+'exblank' => 'sayfa içeriği boş',
+'confirmdelete' => 'Silme işlemini onayla',
+'deletesub' => '("$1" siliniyor)',
+'historywarning' => 'Uyarı: Silmek üzere olduğunuz sayfanın geçmişi vardır:',
+'confirmdeletetext' => 'Bir sayfayı veya resmi tüm geçmişi ile birlikte veritabanından kalıcı olarak silmek üzeresiniz.
+Lütfen sonuçlarını anladığınızı, [[Special:Whatlinkshere/{{FULLPAGENAME}}|sayfaya bağlantılarını]] kontrol ettikten sonra ve [[Project:Silme politikası]]\'e uygunluğunu dikkate alarak, bunu yapmak istediğinizi onaylayınız.',
+'actioncomplete' => 'İşlem tamamlandı.',
+'deletedtext' => '"$1" silindi.
+yakın zamanda silinenleri görmek için: $2.',
+'deletedarticle' => '"$1" silindi',
+'dellogpage' => 'Silme kayıtları',
+'dellogpagetext' => 'Aşağıdaki liste son silme kayıtlarıdır.',
+'deletionlog' => 'silme kayıtları',
+'reverted' => 'Önceki sürüm geri getirildi',
+'deletecomment' => 'Silme nedeni',
+'rollback' => 'değişiklikleri geri al',
+'rollback_short' => 'geri al',
+'rollbacklink' => 'eski haline getir',
+'rollbackfailed' => 'geri alma işlemi başarısız',
+'cantrollback' => 'Değişiklikler geri alınamıyor, son katkıda bulunan sayfaya katkıda bulunmuş tek kişi',
+'editcomment' => 'Değiştirme notu: "<i>$1</i>" idi.',
+'revertpage' => '[[User:$2|$2]] tarafından yapılan değişiklikler geri alınarak, [[User:$1|$1]] tarafından değiştirilmiş önceki sürüm geri getirildi.',
+'protectlogpage' => 'Koruma kayıtları',
+'protectlogtext' => 'Korumaya alma/kaldırma ile ilgili değişiklikleri görmektesiniz.
+Daha fazla bilgi için [[Project:Koruma altına alınmış sayfa]] sayfasına bakabilirsiniz.',
+'protectedarticle' => '"[[$1]]" koruma altında alındı',
+'unprotectedarticle' => 'koruma kaldırıldı: "[[$1]]"',
+'confirmprotecttext' => 'Bu sayfayı gerçekten korumaya almak istiyormusunuz?',
+'confirmprotect' => 'Korumayı onayla',
+'protectmoveonly' => 'Sadece isim değişikliğinden koru',
+'protectcomment' => 'Koruma altına alma nedeni',
+'unprotectsub' => '(koruma kaldırılır "$1")',
+'confirmunprotecttext' => 'Gerçekten sayfanın korumasını kaldırmak istiyor musunuz?',
+'confirmunprotect' => 'Korumayı kaldırmayı onayla',
+'unprotectcomment' => 'Korumayı kaldırmak için neden',
+'protect-text' => '[[$1]] sayfasının koruma durumunu buradan görebilir ve değiştirebilirsiniz. Lütfen [[Project:Koruma politikası|koruma politikasına]] uygun hareket ettiğinizden emin olunuz.',
+'protect-default' => '(standart)',
+'protect-level-autoconfirmed'=> 'kayıtlı olmayan değiştirmesin',
+'protect-level-sysop' => 'sadece yöneticiler',
+'restriction-edit' => 'Düzenle',
+'restriction-move' => 'Taşı',
+'undelete' => 'Silinmiş sayfaları göster',
+'undeletepage' => 'Sayfanın silinmiş sürümlerine göz at ve geri getir.',
+'viewdeletedpage' => 'Silinen sayfalara bak',
+'undeletearticle' => 'Silinmiş sayfayı geri getir',
+'undeletebtn' => 'Geri getir!',
+'undeletereset' => 'Vazgeç',
+'undeletecomment' => 'Neden:',
+'undeletedarticle' => '"$1" geri getirildi.',
+'undeletedrevisions' => 'Toplam $1 kayıt geri getirildi.',
+'namespace' => 'Alan adı:',
+'invert' => 'Seçili haricindekileri göster',
+'contributions' => 'Kullanıcının katkıları',
+'mycontris' => 'Katkılarım',
+'contribsub' => '$1',
+'nocontribs' => 'Bu kriterlere uyan değişiklik bulunamadı',
+'uctop' => '(son)',
+'newbies' => 'yeni başlayanlar',
+'sp-contributions-newest'=> 'En yeni',
+'sp-contributions-oldest'=> 'En eski',
+'sp-contributions-newer'=> 'Sonraki $1',
+'sp-contributions-older'=> 'Önceki $1',
+'sp-contributions-newbies-sub'=> 'Yeni kullanıcılar için',
+'whatlinkshere' => 'Sayfaya bağlantılar',
+'linklistsub' => '(Bağlantı listesi)',
+'linkshere' => 'Buraya bağlantısı olan sayfalar:',
+'nolinkshere' => 'Buraya bağlanan sayfa yok.',
+'isredirect' => 'yönlendirme sayfası',
+'istemplate' => 'ekleme',
+'blockip' => 'Bu IP\'den erişimi engelle',
+'blockiptext' => 'Aşağıdaki formu kullanarak belli bir IP\'nin veya kullanıcının erişimini engelleyebilirsiniz. Bu sadece vandalizmi engellemek için ve [[Project:Kurallar|kurallara]] uygun olarak yapılmalı. Aşağıya mutlaka engelleme ile ilgili bir açıklama yazınız. (örnek: -Şu- sayfalarda vandalizm yapmıştır).',
+'ipaddress' => 'IP Adresi',
+'ipadressorusername' => 'IP adresi veya kullanıcı adı',
+'ipbexpiry' => 'Bitiş süresi',
+'ipbreason' => 'Sebep',
+'ipbsubmit' => 'Bu kullanıcıyı engelle',
+'ipbother' => 'Farklı zaman',
+'ipboptions' => '15 dakika:15 minutes,1 saat:1 hour,3 saat:3 hours,24 saat:24 hours,48 saat:48 hours,1 hafta:1 week,1 ay:1 month,süresiz:indefinite',
+'ipbotheroption' => 'farklı',
+'badipaddress' => 'Geçersiz IP adresi',
+'blockipsuccesssub' => 'IP adresi engelleme işlemi başarılı oldu',
+'blockipsuccesstext' => '"$1" engellendi.
+<br />[[Special:Ipblocklist|IP adresi engellenenler]] listesine bakınız .',
+'unblockip' => 'Kullanıcının engellemesini kaldır',
+'ipusubmit' => 'Bu adresin engellemesini kaldır',
+'ipblocklist' => 'Erişimi durdurulmuş kullanıcılar ve IP adresleri listesi',
+'blocklistline' => '$1, $2 blok etti: $3 ($4)',
+'infiniteblock' => 'süresiz',
+'expiringblock' => '$1 tarihinde doluyor',
+'ipblocklistempty' => 'Erişimi engellenmiş kimse yok.',
+'blocklink' => 'engelle',
+'unblocklink' => 'engellemeyi kaldır',
+'contribslink' => 'Katkılar',
+'autoblocker' => 'Otomatik olarak engellendiniz çünkü yakın zamanda IP adresiniz "[[User:$1|$1]]" kullanıcısı tarafından kullanılmıştır. $1 isimli kullanıcının engellenmesi için verilen sebep: "\'\'\'$2\'\'\'"',
+'blocklogpage' => 'Erişim engelleme kayıtları',
+'blocklogentry' => '"[[$1]]" erişimi $2 durduruldu. Sebep',
+'blocklogtext' => 'Burada kullanıcı erişimine yönelik engelleme ya da engelleme kaldırma kayıtları listelenmektedir. Otomatik IP adresi engellemeleri listeye dahil değildir. Şu anda erişimi durdurulmuş kullanıcıları [[Special:Ipblocklist|IP engelleme listesi]] sayfasından görebilirsiniz.',
+'unblocklogentry' => '$1 kullanıcının engellemesi kaldırıldı',
+'ipb_expiry_invalid' => 'Geçersiz bitiş zamanı.',
+'ip_range_invalid' => 'Geçersiz IP aralığı.',
+'lockdb' => 'Veritabanı kilitli',
+'lockbtn' => 'Veritabanı kilitli',
+'rights' => 'Haklar:',
+'user_rights_set' => '<b>"$1" için kullanıcı hakları güncellendi</b>',
+'already_sysop' => 'Bu kullanıcı zaten yönetici',
+'already_bureaucrat' => 'Bu kullanıcı zaten bürokrat',
+'movepage' => 'İsim değişikliği',
+'movepagetext' => 'Aşağıdaki form kullanılarak sayfanın adı değiştirilir. Beraberinde tüm geçmiş kayıtları da yeni isme aktarılır. Eski isim yeni isme yönlendirme haline dönüşür. Eski başlığa dogru olan bağlantılar olduğu gibi kalır; çift veya geçersiz yönlendirmeleri [[Special:Maintenance|kontrol ediniz.]] Yapacağınız bu değişikllike tüm bağlantıların olması gerektiği gibi çalıştığından sizin sorumlu olduğunuzu unutmayınız.
+
+Eğer yeni isimde bir isim zaten mevcutsa, isim değişikliği \'\'\'yapılmayacaktır\'\'\', ancak varolan sayfa içerik olarak boş ise veya sadece yönlendirme ise ve hiç geçmiş hali yoksa isim değişikliği mümkün olacaktır. Bu yanı zamanda demektir ki, yaptığınız isim değişikliğini ilk ismine değiştirerek geri alabilirsiniz ve hiç bir başka sayfaya da dokunmamış olursunuz.
+
+<b>UYARI!</b>
+Bu değişim popüler bir sayfa için beklenmeyen sonuçlar doğurabilir; lütfen değişikliği yapmadan önce olabilecekleri göz önüne alın.',
+'movepagetalktext' => 'İlişikteki tartışma sayfası da (eğer varsa) otomatik olarak yeni isme taşınacaktır. Ama şu durumlarda \'\'\'taşınmaz\'\'\':
+
+*Alanlar arası bir taşıma ise, (örnek: "Project:" --> "Help:")
+*Yeni isimde bir tartışma sayfası zaten var ise,
+*Alttaki kutucuğu seçmediyseniz.
+
+Bu durumlarda sayfayı kendiniz aktarmalısınız.',
+'movearticle' => 'Eski isim',
+'movenologin' => 'Sistemde değilsiniz.',
+'movenologintext' => 'Sayfanın adını değiştirebilmek için kayıtlı ve [[Special:Userlogin|sisteme]] giriş yapmış olmanız gerekmektedir.',
+'newtitle' => 'Yeni isim',
+'movepagebtn' => 'İsmi değiştir',
+'pagemovedsub' => 'İsim değişikliği tamamlandı.',
+'pagemovedtext' => '"[[$1]]" sayfası "[[$2]]" sayfasına aktarıldı.',
+'articleexists' => 'Bu isimde bir sayfa bulunmakta veya seçmiş olduğunuz isim geçersizdir.
+Lütfen başka bir isim deneyiniz.',
+'movedto' => 'taşındı:',
+'movetalk' => 'Varsa "tartışma" sayfasını da aktar.',
+'talkpagemoved' => 'İlgili tartışma sayfası da aktarıldı.',
+'talkpagenotmoved' => 'İlgili tartışma sayfası <strong>aktarılmadı</strong>.',
+'1movedto2' => '[[$1]] sayfasının yeni adı: [[$2]]',
+'1movedto2_redir' => '[[$1]] sayfasının yeni adı: [[$2]]',
+'movelogpage' => 'İsim değişikliği kayıtları',
+'movelogpagetext' => 'Aşağıda bulunan liste adı değiştirilmiş sayfaları gösterir.',
+'movereason' => 'Sebep',
+'revertmove' => 'geriye al',
+'delete_and_move' => 'Sil ve taşı',
+'delete_and_move_text' => '==Silinmesi gerekiyor==
+
+Hedef "[[$1]]" maddesi zaten mevcut. O maddeyi silerek isim değişikliğine devam etmek istiyor musunuz?',
+'delete_and_move_confirm'=> 'Evet, sayfayı sil',
+'delete_and_move_reason'=> 'İsim değişikliğinin gerçekleşmesi için silindi.',
+'selfmove' => 'Olmasını istediğiniz isim ile mevcut isim aynı. Değişiklik mümkün değil.',
+'export' => 'Sayfa kaydet',
+'exporttext' => 'You can export the text and editing history of a particular page or
+set of pages wrapped in some XML. This can be imported into another wiki using MediaWiki
+via the Special:Import page.
+
+To export pages, enter the titles in the text box below, one title per line, and
+select whether you want the current version as well as all old versions, with the page
+history lines, or just the current version with the info about the last edit.
+
+In the latter case you can also use a link, e.g. [[Special:Export/{{int:Mainpage}}]] for the page {{int:Mainpage}}.',
+'allmessages' => 'Viki arayüz metinleri',
+'allmessagesname' => 'İsim',
+'allmessagesdefault' => 'Orjinal metin',
+'allmessagescurrent' => 'Kullanımdaki metin',
+'allmessagestext' => 'Bu liste MediaWiki\'de mevcut olan tüm terimlerin listesidir',
+'allmessagesfilter' => 'Metin ayrıştırıcı filtresi:',
+'allmessagesmodified' => 'Sadece değiştirilmişleri göster',
+'thumbnail-more' => 'Büyüt',
+'missingimage' => '<b>Bulunmayan resim</b><br /><i>$1</i>',
+'filemissing' => 'Dosya bulunmadı',
+'tooltip-search' => '{{SITENAME}} içinde ara [alt-f]',
+'tooltip-minoredit' => 'Küçük değişiklik olarak işaretle [alt-i]',
+'tooltip-save' => 'Değişiklikleri kaydet [alt-s]',
+'tooltip-preview' => 'Önizleme; kaydetmeden önce bu özelliği kullanarak değişikliklerinizi gözden geçirin! [alt-p]',
+'tooltip-diff' => 'Metine yaptığınız değişiklikleri gösterir. [alt-v]',
+'tooltip-compareselectedversions'=> 'Seçilmiş iki sürüm arasındaki farkları göster. [alt-v]',
+'tooltip-watch' => 'Sayfayı izleme listene ekle [alt-w]',
+'monobook.css' => '/* monobook temasının ayarlarını değiştirmek için burayı değiştirin. Tüm sitede etkili olur. */',
+'siteuser' => '{{SITENAME}} kullanıcı $1',
+'lastmodifiedatby' => 'Sayfa en son $3 tarafından $2, $1 tarihinde değiştirildi.',
+'and' => 've',
+'others' => 'diğerleri',
+'siteusers' => '{{SITENAME}} kullanıcılar $1',
+'spamprotectiontitle' => 'Spam karşı koruma filtresi',
+'spamprotectiontext' => 'Kaydetmek istediğiniz sayfa spam filtresi tarafından blok edildi. Büyük ihtimalle bir dış bağlantıdan kaynaklanmaktadır.',
+'subcategorycount' => 'Bu kategoride $1 altkategori var.',
+'categoryarticlecount' => 'Bu kategoride $1 madde var.',
+'listingcontinuesabbrev'=> ' (devam)',
+'numwatchers' => 'izleyici sayısı: $1',
+'mw_math_png' => 'Daima PNG resim formatına çevir',
+'mw_math_simple' => 'Çok basitse HTML, değilse PNG',
+'mw_math_html' => 'Mümkünse HTML, değilse PNG',
+'mw_math_source' => 'Değiştirmeden TeX olarak bırak (metin tabanlı tarayıcılar için)',
+'mw_math_modern' => 'Modern tarayıcılar için tavsiye edilen',
+'mw_math_mathml' => 'Mümkünse MathML (daha deneme aşamasında)',
+'monobook.js' => '/* Kısa yol tuşları ve yardım balonları */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'Kişisel sayfam\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'The user page for the ip you\'re editing as\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Mesaj sayfam\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Bu IP adresinden yapılmış değişiklikleri tartış\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Ayarlarım\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'İzlemeye aldığım sayfalar\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'Yaptığım katkıların listesi\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Oturum açmanız tavsiye olunur ama mecbur değilsiniz.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Oturum açmanız tavsiye olunur ama mecbur değilsiniz.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Sistemden çık\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'İçerik ile ilgili görüş belirt\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Bu sayfayı değiştirebilirsiniz. Kaydetmeden önce önizleme yapmayı unutmayın.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Bu tartışmaya yorum ekleyin.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Bu sayfa kormu altında. Kaynak kodunu sadece görebilirsiniz. Değiştiremezsiniz.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Bu sayfanın geçmiş versiyonları.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Bu sayfayı koru\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Sayfayı sil\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Sayfayı silinmeden önceki haline geri getirin\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Sayfanın adını değiştir\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Bu sayfanın adını değiştirmeye yetkiniz yok\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Bu sayfayı izlemeye al\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Bu sayfayı izlemeyi bırakın\');
+ ta[\'search\'] = new Array(\'f\',\'Bu vikide arama yap\');
+ ta[\'p-logo\'] = new Array(\'\',\'Ana sayfa\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Başlangıç sayfasına dönün\');
+ ta[\'n-portal\'] = new Array(\'\',\'Proje üzerine, ne nerdedir, neler yapılabilir\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Güncel olaylarla ilgili son bilgiler\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'Vikide yapılmış son değişikliklerin listesi.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Rastgele bir maddeye gidin\');
+ ta[\'n-help\'] = new Array(\'\',\'Yardım almak için.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Maddi destek\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Bu sayfaya bağlantı vermiş diğer viki sayfalarının listesi\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Bu sayfaya bağlantı veren sayfalardaki son değişiklikler\');
+ ta[\'feed-rss\'] = new Array(\'\',\'Bu sayfa için RSS beslemesi\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Bu sayfa için atom beslemesi\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Kullanıcının katkı listesini gör\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Kullanıcıya e-posta gönder\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Sisteme resim ya da medya dosyaları yükleyin\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Tüm özel sayfaların listesini göster\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Sayfayı göster\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Kullanıcı sayfasını göster\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Medya sayfasını göster\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Bu özel sayfa olduğu için değişiklik yapamazsınız.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Proje sayfasını göster\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Resim sayfasını göster\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Sistem mesajını göster\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Şablonu göster\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Yardım sayfasını görmek için tıklayın\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Kategori sayfasını göster\');',
+'deletedrevision' => '$1 sayılı eski sürüm silindi.',
+'previousdiff' => '← Önceki sürümle aradaki fark',
+'nextdiff' => 'Sonraki sürümle aradaki fark →',
+'imagemaxsize' => 'Resim açıklamalar sayfalarındaki resmin en büyük boyutu:',
+'thumbsize' => 'Küçük boyut:',
+'showbigimage' => 'Yüksek çözünürlüklü resim indirilir ($1 · $2, $3 KB)',
+'newimages' => 'Yeni resimler',
+'showhidebots' => '(botları $1)',
+'specialloguserlabel' => 'Kullanıcı:',
+'speciallogtitlelabel' => 'Başlık:',
+'passwordtooshort' => 'Parolanız çok kısa. En az $1 harf ve/veya rakam içermeli.',
+'mediawarning' => '\'\'\'DİKKAT!\'\'\': Bu dosyada kötü amaçlı (virüs gibi) kısım bulunabilir ve işletim sisteminize zarar verebilir.
+<hr />',
+'metadata' => 'Resim detayları',
+'metadata-expand' => 'Ayrıntıları göster',
+'metadata-collapse' => 'Ayrıntıları gösterme',
+'exif-make' => 'Kamera markası',
+'exif-model' => 'Kamera modeli',
+'exif-artist' => 'Yaratıcısı',
+'exif-colorspace' => 'Renk aralığı',
+'exif-datetimeoriginal' => 'Çekim saati ve tarihi',
+'exif-exposuretime' => 'Çekim süresi',
+'exif-exposuretime-format'=> '$1 saniye ($2)',
+'exif-fnumber' => 'F numarası',
+'exif-spectralsensitivity'=> 'Spektral duyarlılık',
+'exif-aperturevalue' => 'Açıklık',
+'exif-brightnessvalue' => 'parlaklık',
+'exif-lightsource' => 'Işık durumu',
+'exif-exposureindex' => 'Poz dizini',
+'exif-scenetype' => 'Çekim tipi',
+'exif-digitalzoomratio' => 'Yakınlaştırma oranı',
+'exif-contrast' => 'Karşıtlık',
+'exif-saturation' => 'Doygunluk',
+'exif-sharpness' => 'Netlik',
+'exif-gpslatitude' => 'Enlem',
+'exif-gpslongitude' => 'Boylam',
+'exif-gpsaltitude' => 'Yükseklik',
+'exif-gpstimestamp' => 'GPS saati (atom saati)',
+'exif-gpssatellites' => 'Ölçmek için kullandığı uydular',
+'exif-compression-1' => 'Sıkıştırılmamış',
+'exif-orientation-3' => '180° döndürülmüş',
+'exif-exposureprogram-1'=> 'Elle',
+'exif-subjectdistance-value'=> '$1 metre',
+'exif-meteringmode-0' => 'Bilinmiyor',
+'exif-meteringmode-1' => 'Orta',
+'exif-meteringmode-255' => 'Diğer',
+'exif-lightsource-0' => 'Bilinmiyor',
+'exif-lightsource-2' => 'Floresan',
+'exif-lightsource-9' => 'Açık',
+'exif-lightsource-10' => 'Kapalı',
+'exif-lightsource-11' => 'Gölge',
+'exif-lightsource-15' => 'Beyaz floresan (WW 3200 – 3700K)',
+'exif-sensingmethod-1' => 'Tanımsız',
+'exif-scenecapturetype-0'=> 'Standart',
+'exif-scenecapturetype-2'=> 'Portre',
+'exif-scenecapturetype-3'=> 'Gece çekimi',
+'exif-subjectdistancerange-0'=> 'Bilinmiyor',
+'exif-subjectdistancerange-1'=> 'Makro',
+'edit-externally' => 'Dosya üzerinde bilgisayarınızda bulunan uygulamalar ile değişiklikler yapın',
+'edit-externally-help' => 'Daha fazla bilgi için metadaki [http://meta.wikimedia.org/wiki/Help:External_editors dış uygulama ayarları] (İngilizce) sayfasına bakabilirsiniz.',
+'imagelistall' => 'Tümü',
+'watchlistall1' => 'Hepsini göster',
+'watchlistall2' => 'Hepsini göster',
+'namespacesall' => 'Hepsi',
+'confirmemail' => 'E-posta adresini onayla',
+'confirmemail_text' => 'Viki\'nin e-posta işlevlerini kullanmadan önce e-posta adresinizin
+doğrulanması gerekiyor. Adresinize onay e-postası göndermek için aşağıdaki
+butonu tıklayın. Gönderilecek iletide adresinizi onaylamak için tarayıcınızla
+erişebileceğiniz, onay kodu içeren bir bağlantı olacak.',
+'confirmemail_send' => 'Onay kodu gönder',
+'confirmemail_sent' => 'Onay e-postası gönderildi.',
+'confirmemail_sendfailed'=> 'Onay kodu gönderilemedi. Adreste geçersiz harf ya da işaret olmadığından emin misiniz?',
+'confirmemail_invalid' => 'Geçersiz onay kodu. Onay kodunun son kullanma tarihi geçmiş olabilir.',
+'confirmemail_needlogin'=> '$1 yapmak için önce e-posta adresinizi onaylamalısınız.',
+'confirmemail_success' => 'E-posta adresiniz onaylandı. Oturum açıp Viki\'nin tadını çıkarabilirsiniz.',
+'confirmemail_loggedin' => 'E-posta adresiniz onaylandı.',
+'confirmemail_error' => 'Onayınız bilinmeyen bir hata nedeniyle kaydedilemedi.',
+'confirmemail_subject' => '{{SITENAME}} e-posta adres onayı.',
+'confirmemail_body' => '$1 internet adresinden yapılan erişimle {{SITENAME}} sitesinde
+bu e-posta adresi ile ilişkilendirilen $2 kullanıcı hesabı
+açıldı.
+
+Bu e-posta adresinin bahsi geçen kullanıcı hesabına ait olduğunu
+onaylamak ve {{SITENAME}} sitesindeki e-posta işlevlerini aktif hale
+getirmek için aşağıdakı bağlantıyı tıklayın.
+
+$3
+
+Bahsi geçen kullanıcı hesabı size ait değilse yapmanız gereken
+birşey yok.
+
+Bu onay kodu $4 tarihine kadar geçerli olacak.',
+'createarticle' => 'Sayfayı oluştur',
+'deletedwhileediting' => 'Uyarı: Bu sayfa siz değişiklik yapmaya başladıktan sonra silinmiş!',
+'redirectingto' => 'Yönlendirme [[$1]]...',
+'confirm_purge' => 'Sayfa önbelleği temizlesin mi? $1',
+'confirm_purge_button' => 'Tamam',
+'youhavenewmessagesmulti'=> '$1\'de yeni mesajınız var.',
+'articletitles' => '\'\'$1\'\' ile başlayan maddeler',
+'displaytitle' => '(Bu sayfaya [[$1]] olarak bağlan)',
+);
+?>
diff --git a/languages/messages/MessagesTt.php b/languages/messages/MessagesTt.php
new file mode 100644
index 000000000000..31428403b835
--- /dev/null
+++ b/languages/messages/MessagesTt.php
@@ -0,0 +1,793 @@
+<?php
+/**
+ * Tatarish (Tatarça)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Maxsus',
+ NS_MAIN => '',
+ NS_TALK => 'Bäxäs',
+ NS_USER => 'Äğzä',
+ NS_USER_TALK => "Äğzä_bäxäse",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_bäxäse',
+ NS_IMAGE => "Räsem",
+ NS_IMAGE_TALK => "Räsem_bäxäse",
+ NS_MEDIAWIKI => "MediaWiki",
+ NS_MEDIAWIKI_TALK => "MediaWiki_bäxäse",
+ NS_TEMPLATE => "Ürnäk",
+ NS_TEMPLATE_TALK => "Ürnäk_bäxäse",
+ NS_HELP => "Yärdäm",
+ NS_HELP_TALK => "Yärdäm_bäxäse",
+ NS_CATEGORY => "Törkem",
+ NS_CATEGORY_TALK => "Törkem_bäxäse"
+);
+
+$datePreferences = false;
+
+$defaultDateFormat = 'dmy';
+
+$dateFormats = array(
+ 'mdy time' => 'H:i',
+ 'mdy date' => 'M j, Y',
+ 'mdy both' => 'H:i, M j, Y',
+ 'dmy time' => 'H:i',
+ 'dmy date' => 'j. M Y',
+ 'dmy both' => 'j. M Y, H:i',
+ 'ymd time' => 'H:i',
+ 'ymd date' => 'Y M j',
+ 'ymd both' => 'H:i, Y M j',
+ 'ISO 8601 time' => 'xnH:xni:xns',
+ 'ISO 8601 date' => 'xnY-xnm-xnd',
+ 'ISO 8601 both' => 'xnY-xnm-xnd"T"xnH:xni:xns',
+);
+
+$magicWords = array(
+# ID CASE SYNONYMS
+ 'redirect' => array( 0, '#yünältü', '#REDIRECT'),
+ 'notoc' => array( 0, '__ETYUQ__', '__NOTOC__'),
+ 'forcetoc' => array( 0, '__ETTIQ__', '__FORCETOC__'),
+ 'toc' => array( 0, '__ET__', '__TOC__'),
+ 'noeditsection' => array( 0, '__BÜLEMTÖZÄTÜYUQ__', '__NOEDITSECTION__'),
+ 'start' => array( 0, '__BAŞLAW__', '__START__'),
+ 'currentmonth' => array( 1, 'AĞIMDAĞI_AY', 'CURRENTMONTH'),
+ 'currentmonthname' => array( 1, 'AĞIMDAĞI_AY_İSEME', 'CURRENTMONTHNAME'),
+ 'currentday' => array( 1, 'AĞIMDAĞI_KÖN', 'CURRENTDAY'),
+ 'currentdayname' => array( 1, 'AĞIMDAĞI_KÖN_İSEME', 'CURRENTDAYNAME'),
+ 'currentyear' => array( 1, 'AĞIMDAĞI_YIL', 'CURRENTYEAR'),
+ 'currenttime' => array( 1, 'AĞIMDAĞI_WAQIT', 'CURRENTTIME'),
+ 'numberofarticles' => array( 1, 'MÄQÄLÄ_SANI', 'NUMBEROFARTICLES'),
+ 'currentmonthnamegen' => array( 1, 'AĞIMDAĞI_AY_İSEME_GEN', 'CURRENTMONTHNAMEGEN'),
+ 'pagename' => array( 1, 'BİTİSEME', 'PAGENAME'),
+ 'namespace' => array( 1, 'İSEMARA', 'NAMESPACE'),
+ 'subst' => array( 0, 'TÖPÇEK:', 'SUBST:'),
+ 'msgnw' => array( 0, 'MSGNW:' ),
+ 'end' => array( 0, '__AZAQ__', '__END__'),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' ),
+ 'img_right' => array( 1, 'uñda', 'right'),
+ 'img_left' => array( 1, 'sulda', 'left'),
+ 'img_none' => array( 1, 'yuq', 'none'),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame' ),
+ 'int' => array( 0, 'EÇKE:', 'INT:'),
+ 'sitename' => array( 1, 'SÄXİFÄİSEME', 'SITENAME'),
+ 'ns' => array( 0, 'İA:', 'NS:'),
+ 'localurl' => array( 0, 'URINLIURL:', 'LOCALURL:'),
+ 'localurle' => array( 0, 'URINLIURLE:', 'LOCALURLE:'),
+ 'server' => array( 0, 'SERVER' )
+);
+
+$fallback8bitEncoding = "windows-1254";
+
+$linkTrail = '/^([a-zäçğıñöşü“»]+)(.*)$/sDu';
+
+$messages = array(
+'skinpreview' => '(Küzläw)',
+
+# Dates
+'sunday' => 'Yäkşämbe',
+'monday' => 'Düşämbe',
+'tuesday' => 'Sişämbe',
+'wednesday' => 'Çärşämbe',
+'thursday' => 'Pänceşämbe',
+'friday' => 'Comğa',
+'saturday' => 'Şimbä',
+'sun' => 'Yäk',
+'mon' => 'Düş',
+'tue' => 'Siş',
+'wed' => 'Çär',
+'thu' => 'Pän',
+'fri' => 'Com',
+'sat' => 'Şim',
+'january' => 'Ğínwar',
+'february' => 'Febräl',
+'march' => 'Mart',
+'april' => 'Äpril',
+'may_long' => 'May',
+'june' => 'Yün',
+'july' => 'Yül',
+'august' => 'August',
+'september' => 'Sentäber',
+'october' => 'Öktäber',
+'november' => 'Nöyäber',
+'december' => 'Dekäber',
+'jan' => 'Ğín',
+'feb' => 'Feb',
+'mar' => 'Mar',
+'apr' => 'Äpr',
+'may' => 'May',
+'jun' => 'Yün',
+'jul' => 'Yül',
+'aug' => 'Aug',
+'sep' => 'Sen',
+'oct' => 'Ökt',
+'nov' => 'Nöy',
+'dec' => 'Dek',
+
+# Bits of text used by many pages
+'categories' => 'Cíıntıqlar',
+'pagecategories' => '{{PLURAL:$1|Cíıntıq|Cíıntıqlar}}',
+'pagecategorieslink' => '{{ns:special}}:Categories',
+'category_header' => '«$1» cíıntığınıñ mäqäläläre',
+'subcategories' => 'Eçke cíıntıqlar',
+
+'linkprefix' => '/^(.*?)([a-zäçğıñöşüA-ZÄÇĞİÑÖŞÜ«„]+)$/sDu',
+'mainpage' => 'Täwge Bit',
+'mainpagetext' => 'Wiki programı uñışlı quyıldı.',
+
+'portal' => 'Cämğiät üzäge',
+'portal-url' => '{{ns:project}}:Cämğiät Üzäge',
+'about' => 'Turında',
+'aboutsite' => '{{SITENAME}} Turında',
+'aboutpage' => '{{ns:project}}:Turında',
+'article' => 'Eçtälek bite',
+'help' => 'Yärdäm',
+'helppage' => '{{ns:help}}:Eçtälek',
+'bugreports' => 'Xatanamä',
+'bugreportspage' => '{{ns:project}}:Xata_yomğağı',
+'sitesupport' => 'Ximäyäçegä',
+'sitesupport-url' => '{{ns:project}}:Ximäyäçegä',
+'faq' => 'YBS',
+'faqpage' => '{{ns:project}}:YBS',
+'edithelp' => 'Üzgärtü xaqında',
+'newwindow' => '(yaña täräzädä açılır)',
+'edithelppage' => '{{ns:help}}:Üzgärtü',
+'cancel' => 'Kiräkmi',
+'qbfind' => 'Tap',
+'qbbrowse' => 'Qaraw',
+'qbedit' => 'Üzgärtü',
+'qbpageoptions' => 'Bu bit',
+'qbpageinfo' => 'Eçtälek',
+'qbmyoptions' => 'Bitlärem',
+'qbspecialpages' => 'Maxsus bitlär',
+'moredotdotdot' => 'Kübräk...',
+'mypage' => 'Bitem',
+'mytalk' => 'Bäxäsem',
+'anontalk' => 'Bu IP turında bäxäs',
+'navigation' => 'Küçü',
+
+'currentevents' => 'Xäzerge waqíğalar',
+'currentevents-url' => 'Xäzerge waqíğalar',
+
+'errorpagetitle' => 'Xata',
+'returnto' => '«$1» bitenä qaytu.',
+'tagline' => "{{SITENAME}}'dan",
+'search' => 'Ezläw',
+'searchbutton' => 'Ezläw',
+'go' => 'Küç',
+'searcharticle' => 'Küç',
+'history' => 'Bit taríxı',
+'history_short' => 'Taríx',
+'info_short' => 'Belem',
+'printableversion' => 'Bastırulı yurama',
+'edit' => 'Üzgärtü',
+'editthispage' => 'Bit üzgärtü',
+'delete' => 'Beter',
+'deletethispage' => 'Beter bu bitne',
+'undelete_short' => 'Torğız',
+'protect' => 'Yaqla',
+'protectthispage' => 'Yaqla bu bitne',
+'unprotect' => 'İreklä',
+'unprotectthispage' => 'İreklä bu biten',
+'newpage' => 'Yaña bit',
+'talkpage' => 'Bit turında bäxäs',
+'specialpage' => 'Maxsus Bit',
+'personaltools' => 'Şäxes qoralı',
+'postcomment' => 'Yazma qaldıru',
+'addsection' => '+',
+'articlepage' => 'Eçtälek biten kürü',
+'talk' => 'Bäxäs',
+'toolbox' => 'Äsbäptirä',
+'userpage' => 'Äğzä biten qaraw',
+'imagepage' => 'Räsem biten qaraw',
+'viewtalkpage' => 'Bäxäsen qaraw',
+'otherlanguages' => 'Başqa tellärdä',
+'redirectedfrom' => '(«$1» bitennän yünältelde)',
+'viewcount' => 'Bu bit $1 märtäbä qaralğan.',
+'copyright' => 'Eçtälek $1 buyınça ireşüle.',
+'protectedpage' => 'Yaqlanğan bit',
+'jumpto' => 'Küç:',
+'jumptosearch' => 'ezläw',
+
+'retrievedfrom' => 'Bu bitneñ çığanağı: "$1"',
+'newmessageslink' => 'yaña xäbär',
+'editsection' => 'üzgärtü',
+'editold' => 'üzgärtü',
+'toc' => 'Eçtälek tezmäse',
+'showtoc' => 'kürsät',
+'hidetoc' => 'yäşer',
+'thisisdeleted' => 'Qaraw/torğızu: $1',
+'restorelink' => '$1 beterelgän bit',
+'feedlinks' => 'Tasma:',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Mäqälä',
+'nstab-user' => 'Äğzä bite',
+'nstab-media' => 'Media bite',
+'nstab-special' => 'Maxsus',
+'nstab-project' => 'Proyekt bite',
+'nstab-image' => 'Räsem',
+'nstab-mediawiki' => 'Sätir',
+'nstab-template' => 'Äzerlämä',
+'nstab-help' => 'Yärdäm',
+'nstab-category' => 'Cíıntıq',
+
+# Main script and global functions
+'nosuchaction' => 'Andí ğämäl barlıqta yuq',
+'nosuchspecialpage' => 'Andí maxsus bit yuq',
+
+# General errors
+'error' => 'Xata',
+'databaseerror' => 'Biremlek xatası',
+'readonly' => 'Biremlek yabılğan ide',
+'internalerror' => 'Eçke xata',
+'filecopyerror' => 'Bu «$1» biremen «$2» iseme belän küpli almím.',
+'filerenameerror' => 'Bu «$1» biremen «$2» iseme belän küçerä almím.',
+'filedeleteerror' => 'Bu «$1» biremen beterep bulmí.',
+'filenotfound' => 'Bu «$1» biremen tabalmím.',
+'formerror' => 'Xata: formını künderä almím',
+'badtitle' => 'Yaraqsız başlıq',
+'badtitletext' => 'The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one more characters which cannot be used in titles.',
+'perfdisabled' => 'Kiçer! Biremlekneñ äkren buluına säbäple, bu mömkinlek waqıtlıça sünderelgän ide.',
+'perfdisabledsub' => '$1 biteneñ saqlanğan yuraması bu:', # obsolete?
+'perfcached' => 'Astağı belem alxäterdän alındı wä anıñ xäzerge xäl belän turı kilmäwe bar:',
+'viewsource' => 'Mäqälä çığanağı',
+
+# Login and logout pages
+'logouttitle' => 'Äğzä çığuı',
+'welcomecreation' => "== Räxim it, $1! ==
+
+Sineñ xísabıñ yasaldı. {{SITENAME}}'dağı köyläwläreñne dä üzgärtergä onıtma.",
+'loginpagetitle' => 'Atama belän kerü',
+'yourname' => 'İreşü isemeñ',
+'yourpassword' => 'Sersüzeñ',
+'yourpasswordagain' => 'Sersüz qabat',
+'remembermypassword' => 'Tanı mine kergändä.',
+'loginproblem' => '<b>Kerüeñ waqıtında nindider qíınlıq bulıp çıqtı.</b><br />Qabat kerep qara!',
+'alreadyloggedin' => '<strong>«$1» atlı äğzä, sin kergänseñ iç inde!</strong><br />',
+'login' => 'İreşü',
+'userlogin' => 'Xísap yasaw yä ki kerü',
+'logout' => 'Çığış',
+'userlogout' => 'Çığış',
+'notloggedin' => 'Kermädeñ äle',
+'createaccount' => 'Yaña xísap yasaw',
+'createaccountmail' => 'email buyınça',
+'badretype' => 'Kertelgän sersüzeñ kileşmi.',
+'userexists' => 'Äle genä kertkäneñ äğzä iseme qullanıla inde. Başqa isem sayla zínhar.',
+'youremail' => "Email'ıñ*",
+'yourrealname' => 'Çın isemeñ*',
+'yournick' => 'Atamañ:',
+'loginerror' => 'Kerü xatası',
+'loginsuccesstitle' => 'Uñışlı kergänbez',
+'loginsuccess' => "Sin {{SITENAME}}'ğa «$1» atama belän kergän buldıñ.",
+'wrongpassword' => 'Sin kertän sersüz xatalı axrısı. Tağın kertep qara zínhar.',
+'mailmypassword' => 'Yaña sersüzne xat belän cibär',
+'passwordremindertitle' => '{{SITENAME}} sersüz xäterlätkeçe',
+'passwordsent' => 'Yaña sersüz «$1» terkälüendä kertelgän e-mail buyınça cibärelde.
+Anı alğaç monda tağın kerep qara.',
+'mailerror' => 'Xat künderü xatası: $1',
+
+# Edit page toolbar
+'bold_sample' => 'Qalın mäten',
+'bold_tip' => 'Qalın mäten',
+'italic_sample' => 'Awışlı mäten',
+'italic_tip' => 'Awışlı mäten',
+'link_sample' => 'Läñker başlığı',
+'link_tip' => 'Eçke läñker',
+'extlink_sample' => 'http://www.example.com läñker başlığı',
+'extlink_tip' => 'Tışqı läñker (alğı http:// quşımtasın onıtma)',
+'headline_sample' => 'Başlıq mätene',
+'headline_tip' => '2. däräcäle başlıq',
+'math_sample' => 'Formulnı monda kert',
+'math_tip' => 'İsäpläw formulı (LaTeX)',
+'nowiki_sample' => 'Taqır mäten urnaştıram',
+'nowiki_tip' => 'Wiki-qalıp eşkärtmäskä',
+'image_sample' => 'Example.jpg',
+'image_tip' => 'Quşılğan räsem',
+'media_sample' => 'Example.ogg',
+'sig_tip' => 'Ímzañ belän zaman/waqıt tamğası',
+'hr_tip' => 'Yatma sızıq (siräk qullan)',
+
+# Edit pages
+'summary' => 'Yomğaq',
+'subject' => 'Ni turında/başlıq',
+'minoredit' => 'Bu waq-töyäk üzgärmä genä',
+'watchthis' => 'Bitne küzätep torası',
+'savearticle' => 'Saqla biremne',
+'preview' => 'Küzläw',
+'showpreview' => 'Qarap alu...',
+'blockedtitle' => 'Qullanuçı tíıldı',
+'whitelistedittitle' => 'Üzgärtü öçen, kerü täläp itelä',
+'whitelistedittext' => 'Bitlärne üzgärtü öçen,
+säxifägä isem belän [[Special:Userlogin|keräse]].',
+'whitelistreadtitle' => 'Uqu öçen kerü täläp itelä',
+'whitelistreadtext' => 'Bitlärne uqu öçen,
+säxifägä isem belän [[Special:Userlogin|keräse]].',
+'whitelistacctitle' => 'Siña xísap yasaw tíılğan',
+'loginreqtitle' => 'Kerergä Kiräk',
+'loginreqlink' => 'keräse',
+'accmailtitle' => 'Sersüz künderelde.',
+'accmailtext' => "Bu '$1' öçen digän sersüz '$2' adrésına cibärelde.",
+'newarticle' => '(Yaña)',
+'newarticletext' => "Bulmağan bitkä kürsätkän läñker buyınça küçkänseñ.
+Bu bit başlaw öçen, eçtälegen astağı qırda cía başla
+(kübräge [[Yärdäm:Eçtälek|yärdäm bitendä]] tarwírlana).
+Xata çığuınnan monda eläkkänseñ ikän, browserıñnıñ '''kire''' sädäfenä genä basası.",
+'clearyourcache' => "'''İskärmä:''' Saqlawdan soñ, üzgärmälärne kürü öçen browserıñnıñ alxäteren buşatası bar: '''Mozilla:''' click ''reload''(yä ki ''ctrl-r''), '''IE / Opera:''' ''ctrl-f5'', '''Safari:''' ''cmd-r'', '''Konqueror''' ''ctrl-r''.",
+
+
+
+
+'updated' => '(Yañartıldı)',
+'note' => '<strong>İskärmä:</strong>',
+
+
+
+'editing' => 'Üzgärtü: $1',
+'editconflict' => 'Üzgärtü qíınlığı: $1',
+'yourtext' => 'Mäteneñ',
+'storedversion' => 'Saqlanğan yurama',
+'editingold' => '<strong>KİSÄTMÄ: Sin bu bitneñ iskergän yuramasın üzgärtäsen.
+Ägär sin monı saqlísıñ ikän, şul yuramadan soñ yasalğan üzgärmälär yuğalır.</strong>',
+'yourdiff' => 'Ayırmalar',
+'longpagewarning' => "KİSÄTMÄ:</font> Bu bit zurlığı $1 KB; qayber browserlarda 32 KB'tan da zurraq bulğan bitlärne kürsätkändä qíınlıqlar bula.
+Zínhar, bu bitneñ wağraq kisäklärgä bülü turında uylap qara.",
+'protectedpagewarning' => 'KİSÄTMÄ: Bu bit yaqlanğan ide wä anı idäräçe xoquqı iä bulğan genä keşe üzgärtä ala. Kübrägen <a href="/wiki/{{SITENAME}}:Bit_yaqlaw_qullanması">bit yaqlaw qullanmasında</a> uqıp bula.',
+
+# History pages
+'loadhist' => 'Bit taríxın yökläw',
+'currentrev' => 'Ağımdağı yurama',
+'cur' => 'xäzer',
+'next' => 'kiläse',
+'last' => 'soñğı',
+'orig' => 'çığn',
+
+# Diffs
+'difference' => '(Yuramalar ayırması)',
+'lineno' => '$1. yul:',
+'editcurrent' => 'Bu bitneñ ağımdağı yuramanı üzgärtü',
+'compareselectedversions' => 'Saylanğan yurama çağıştıru',
+
+# Search results
+'searchresults' => 'Ezläw näticäse',
+'badquery' => 'Ezläw sorawı xata belän cíılğan',
+'titlematches' => 'Mäqälä başlığı kileşä',
+'notitlematches' => 'Kileşkän bit başlığı yuq',
+'notextmatches' => 'Kileşkän bit mätene yuq',
+'prevn' => 'uzğan $1',
+'nextn' => 'kiläse $1',
+'showingresults' => 'Asta <b>$1</b> näticä kürsätelä <b>$2</b>. keremnän başlap.',
+'showingresultsnum' => 'Asta <b>$3</b> näticä kürsätelä <b>$2</b>. keremnän başlap.',
+'powersearch' => 'Ezläw',
+'blanknamespace' => '(Töp)',
+
+# Preferences page
+'preferences' => 'Köyläwlar',
+'mypreferences' => 'Köyläwem',
+'prefsnologin' => 'Kermägänseñ',
+'qbsettings' => 'Tiztirä caylawı',
+'changepassword' => 'Sersüz üzgärtü',
+'skin' => 'Tışlaw',
+'dateformat' => 'Waqıt qalıbı',
+'math_failure' => 'Uqí almadım',
+'math_unknown_error' => 'tanılmağan xata',
+'math_unknown_function' => 'tanılmağan funksí',
+'math_lexing_error' => 'nöhü xatası',
+'math_syntax_error' => 'nöhü xatası',
+'prefs-misc' => 'Başqa köyläwlär',
+'saveprefs' => 'Saqla köyläwlärne',
+'resetprefs' => 'Awdar köyläwne',
+'oldpassword' => 'İske sersüz',
+'newpassword' => 'Yaña sersüz',
+'retypenew' => 'Yaña sersüz (qabat)',
+'textboxsize' => 'Mätenqır ülçäme',
+'rows' => 'Yul:',
+'columns' => 'Buy:',
+'searchresultshead' => 'Ezläw',
+'resultsperpage' => 'Bit sayın näticä sanı',
+'recentchangescount' => 'Soñğı üzgärtmä tezmäsendä başlıq sanı',
+'savedprefs' => 'Köyläwläreñ saqlandı.',
+'timezonelegend' => 'Waqıt quşağı',
+'localtime' => 'Cirle waqıt belän kürsätäse',
+'timezoneoffset' => 'Çigenü',
+'servertime' => 'Serverda xäzerge waqıt',
+'guesstimezone' => 'Browserdan alası',
+'defaultns' => 'Ğädättä bu isemarada ezlise:',
+'files' => 'Fayllar',
+
+'group-bot-member' => 'Bot',
+
+# Recent changes
+'changes' => 'üzgärmä',
+'recentchanges' => 'Soñğı üzgärtmälär',
+'recentchangestext' => 'Bu bittä wikidä bulğan iñ soñğı üzgärtmäläre kürsätelä.',
+'rcnote' => 'Asta söñğı <strong>$2</strong> kön eçendä bulğan soñğı <strong>$1</strong> üzgärmä kürsätelä.',
+'rcnotefrom' => 'Asta <b>$2</b> zamanınnan soñ bulğan üzgärtmälär (<b>$1</b> tikle).',
+'rclistfrom' => '$1 zamannan soñ bulğan üzgärtmälär.',
+'rclinks' => 'Soñğı $2 kön eçendä bulğan $1 üzgärtmä<br />$3',
+'diff' => 'ayırma',
+'hist' => 'taríx',
+'hide' => 'yäşer',
+'show' => 'kürsät',
+'minoreditletter' => 'w',
+'newpageletter' => 'Y',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+
+# Upload
+'upload' => 'Birem yökläw',
+'uploadbtn' => 'Yöklä biremne',
+'reupload' => 'Qabat yökläw',
+'reuploaddesc' => 'Yökläw bitenä qaytu.',
+'uploadnologin' => 'Kermädeñ',
+'uploadnologintext' => 'Birem yökläw öçen,
+säxifägä isem belän [[Special:Userlogin|keräse]].',
+'uploaderror' => 'Yökläw xatası',
+'uploadlog' => 'yökläw könlege',
+'uploadlogpage' => 'Yökläw_könlege',
+'uploadlogpagetext' => 'Asta soñğı arada yöklängän birem tezmäse kiterelä.',
+'filename' => 'Birem iseme',
+'filedesc' => 'Yomğaq',
+'fileuploadsummary' => 'Yomğaq:',
+'filestatus' => 'Qälämxaq xäläte',
+'filesource' => 'Çığanaq',
+'copyrightpage' => '{{ns:project}}:Qälämxaq',
+'copyrightpagename' => '{{SITENAME}} qälämxaqı',
+'uploadedfiles' => 'Yöklängän biremnär',
+'ignorewarning' => 'Kisätmägä qaramíçı biremne härxäldä saqla.',
+'minlength' => 'Räsem iseme iñ kimendä öç xäreftän bulırğa tieş.',
+'badfilename' => 'Räsem iseme «$1» itep üzgärtelde.',
+'badfiletype' => '«.$1» törendä räsemnärne qullanırğa kiñäş itelmi.',
+'successfulupload' => 'Yökläw uñışlı uzdı',
+'uploadwarning' => 'Yökläw kisätmäse',
+'savefile' => 'Saqla biremne',
+'uploadedimage' => 'yöklände "$1"',
+'uploaddisabled' => 'Ğafu it, yökläw sünderelgän kileş tora.',
+'uploadcorrupt' => 'Bu birem yä üze watıq, yä quşımtası yaraqsız. Birem tikşerüdän soñ qabat yöklä zínhar.',
+
+# Image list
+'imagelist' => 'Räsem tezmäse',
+'ilsubmit' => 'Ezläw',
+'showlast' => 'Soñğı $1 räsem kürsätäse, $2 tezep.',
+'byname' => 'isem buyınça',
+'bydate' => 'waqıt buyınça',
+'bysize' => 'zurlıq buyınça',
+'imgdelete' => 'beter',
+'imgdesc' => 'añlatma',
+'imgfile' => 'fayl',
+'imglegend' => 'Añlatma: (täsw) = räsem täswiren qaraw/üzgärtü.',
+'imghistory' => 'Räsem taríxı',
+'revertimg' => 'qayart',
+'deleteimg' => 'beter',
+'deleteimgcompletely' => 'Bar yuramalarnı beter',
+'imghistlegend' => 'Añlatma: (ağımdağı) = ağımdağı räsem, (beter) = iske
+yurama beterü, (qaytart) = iske yurama qaytartu.
+<br /><i>Fälän köndä yöklängän räsemne kürü öçen şul könne törtäse</i>.',
+'imagelinks' => 'Räsem läñkerläre',
+
+# Statistics
+'statistics' => 'Nöfüs',
+'sitestats' => '{{SITENAME}} nöfüse',
+'userstats' => 'Qullanuçı nöfüse',
+
+'disambiguations' => 'Saylaqbit tezmäse',
+'disambiguationspage' => '{{ns:template}}:Disambig',
+
+'doubleredirects' => 'Küpmälle yünältü',
+
+'brokenredirects' => 'Watıq Yünältülär',
+'brokenredirectstext' => 'Kiläse yünältülär bulmağan bitlärgä qarílar.',
+
+# Miscellaneous special pages
+'nbytes' => '$1 bayt',
+'nlinks' => '$1 läñker',
+'nviews' => '$1 qaraw',
+'lonelypages' => 'Yätim bitlär',
+'uncategorizedpages' => 'Cíıntıqlanmağan bitlär',
+'unusedimages' => 'Qullanılmağan räsemnär',
+'popularpages' => 'Ğämäli bitlär',
+'wantedpages' => 'Kiräkle bitlär',
+'allpages' => 'Bar bitlär',
+'randompage' => 'Berär bit kürü',
+'shortpages' => 'Qısqa bitlär',
+'longpages' => 'Ozın bitlär',
+'listusers' => 'Äğzä isemlege',
+'specialpages' => 'Maxsus bitlär',
+'spheading' => 'Bar keşelär öçen',
+'recentchangeslinked' => 'Bäyle üzgärmä',
+'rclsub' => '(«$1» bite belän bäyle bitlärgä)',
+'newpages' => 'Yaña bitlär',
+'ancientpages' => 'İñ iske bitlär',
+'intl' => 'Tel-ara läñker',
+'move' => 'Küçerü',
+'movethispage' => 'Bu bit küçerü',
+'booksources' => 'Kitap çığanağı',
+'categoriespagetext' => "Bu wiki'dä kiläse cíıntıqlar bar.",
+'version' => 'Yurama',
+
+# Special:Allpages
+'nextpage' => 'Kiläse bit ($1)',
+
+# E-mail user
+'emailuser' => 'E-mail künderü',
+'emailpage' => 'E-mail künderü',
+'noemailtitle' => 'E-mail adres kürsätelmäde',
+'emailfrom' => 'Kemnän',
+'emailto' => 'Kemgä',
+'emailsubject' => 'Ni turında',
+'emailmessage' => 'Xäbär',
+'emailsend' => 'Künder',
+'emailsent' => 'E-mail künderelde',
+'emailsenttext' => "E-mail'ıñ künderelde.",
+
+# Watchlist
+'watchlist' => 'Saqtezmäm',
+'nowatchlist' => 'Saqtezmäñdä kertemnär yuq.',
+'watchnologin' => 'Kermädeñ',
+'watchnologintext' => 'Saqtezmäñ üzgärtü öçen, säxifägä isem belän [[Special:Userlogin|keräse]].',
+'addedwatch' => 'Saqtezmägä quşıldı',
+'addedwatchtext' => '«[[:$1]]» isemle mäqälä [[{{ns:special}}:Saqtezmä|saqtezmäseñä]] salındı.
+Future changes to this page and its associated Talk page will be listed there,
+and the page will appear \'\'\'bolded\'\'\' in the [[Special:Recentchanges|list of recent changes]] to
+make it easier to pick out.
+
+If you want to remove the page from your watchlist later, click "Unwatch" in the sidebar.',
+'removedwatch' => 'Saqtezmädän salındı',
+'removedwatchtext' => '«[[:$1]]» atlı bit saqtezmäñnän töşerelde.',
+'watch' => 'Saqlaw',
+'watchthispage' => 'Bitne küzätep torası',
+'notanarticle' => 'Eçtälek belän bit tügel',
+'removechecked' => 'Tamğalanğan keremne saqtezmädän salası',
+'watchlistcontains' => 'Saqtezmäñ eçenä $1 bit kertelgän.',
+'removingchecked' => 'Tamğalanğan keremnärne saqtezmädän salu...',
+'couldntremove' => 'Bu «$1» keremne beterä almím...',
+'wlnote' => 'Asta soñğı <b>$2</b> säğät eçendä yasalğan $1 üzgärmä kürsätelä.',
+'wlsaved' => 'Bu yurama säqtezmäñdä saqlanğan buldı',
+
+# Delete/protect/revert
+'deletepage' => 'Beter bitne',
+'confirm' => 'Raslaw',
+'excontent' => 'eçtälege ide:',
+'exblank' => 'bit buş ide',
+'confirmdelete' => 'Beterüne raslaw',
+'deletesub' => '(«$1» beterü)',
+'historywarning' => 'Íğtíbar: Beterergä telägän biteneñ üz taríxı bar:',
+'actioncomplete' => 'Ğämäl tämam',
+'deletedtext' => '«$1» beterelgän buldı.
+Soñğı beterülär $2 bitendä terkälenä.',
+'deletedarticle' => '«$1» beterelde',
+'dellogpage' => 'Beterü_köndälege',
+'deletionlog' => 'beterü köndälege',
+'reverted' => 'Aldağı yuramanı qaytart',
+'deletecomment' => 'Beterü säbäbe',
+'imagereverted' => 'Aldağı yuramağa küçü uñışlı uzdı.',
+'editcomment' => 'Bu üzgärtü taswírı: "<i>$1</i>".', # only shown if there is an edit comment
+'protectlogpage' => 'Yaqlaw_köndälege',
+'protectedarticle' => '[[$1]] yaqlandı',
+'unprotectedarticle' => '[[$1]] ireklände',
+'protectsub' => '(«$1» yaqlaw)',
+'confirmprotect' => 'Yaqlawnı raslaw',
+'protectcomment' => 'Yaqlaw säbäbe',
+'confirmunprotect' => 'Yaqlaw töşerüen raslaw',
+'unprotectcomment' => 'İrekläw säbäbe',
+
+# Undelete
+'undelete' => 'Beterelgän bit torğızu',
+'undeletearticle' => 'Beterelgän bit torğızu',
+'undeletebtn' => 'Torğız!',
+'undeletedarticle' => '«$1» torğızıldı',
+
+# Contributions
+'contributions' => 'Äğzä qatnaşuı',
+'mycontris' => 'Qatnaşuım',
+'contribsub' => '$1 öçen',
+'uctop' => ' (öskä)',
+
+# What links here
+'whatlinkshere' => 'Kem bäyle moña',
+'notargettitle' => 'Maqsatsız',
+'linklistsub' => '(Läñker tezmäse)',
+'nolinkshere' => 'Moña bäyle bitlär yuq.',
+'isredirect' => 'küçerelü bite',
+
+# Block/unblock
+'blockip' => 'Qullanuçı tíu',
+'ipaddress' => 'IP Adres/äğzäisem',
+'ipbexpiry' => 'İskerer',
+'ipbreason' => 'Säbäp',
+'ipbsubmit' => 'Bu keşene tíu',
+'badipaddress' => 'Xatalı IP adrésı',
+'blockipsuccesssub' => 'Tíu uzdı',
+'blockipsuccesstext' => '«$1» tíılğan buldı.
+<br />See [[Special:Ipblocklist|IP block list]] to review blocks.',
+'unblockip' => 'Äğzäne irekläw',
+'ipusubmit' => 'Bu adresnı irekläw',
+'ipblocklist' => 'Tíılğan IP/äğzä tezmäse',
+'blocklink' => 'tíu',
+'contribslink' => 'qatnaşuı',
+'blocklogpage' => 'Tíu_köndälege',
+'ipb_expiry_invalid' => 'İskärü waqıtı xatalı.',
+'ip_range_invalid' => 'Xatalı IP arası.',
+'proxyblocker' => 'Proxy tíu',
+'proxyblocksuccess' => 'Buldı.',
+'sorbs' => 'DNSBL',
+
+# Developer tools
+'lockdb' => 'Biremlekne yozaqlaw',
+'unlockdb' => 'Biremlek irekläw',
+'lockconfirm' => 'Äye, min biremlekne çınlap ta yozaqlarğa buldım.',
+'lockbtn' => 'Biremlekne yozaqlaw',
+'lockdbsuccesssub' => 'Biremlek yözaqlandı',
+'unlockdbsuccesssub' => 'Biremlek yozağı salındı',
+'unlockdbsuccesstext' => 'Bu biremlek yozağı salınğan ide.',
+
+# Make sysop
+'makesysoptitle' => 'Äğzäne idäräçe itep quyu',
+'makesysopname' => 'Bu äğzäne:',
+'makesysopsubmit' => 'Bu äğzäne idäräçe itep quy',
+'makesysopok' => '<b>«$1» isemle äğzä idäräçe buldı</b>',
+'setbureaucratflag' => 'Näzir itep quyası',
+'rights' => 'Xoquqlar:',
+'set_user_rights' => 'Äğzä xoquqın üzgärt',
+'user_rights_set' => '<b>«$1» atlı äğzä xoquqı yañartıldı</b>',
+'makesysop' => 'Äğzäne idäräçe itep quyu',
+
+# Move page
+'movepage' => 'Bit küçerü',
+'movepagetalktext' => "Bäyle bulğan bäxäs bite kiläse oçraqlarda töp bite belän beryulı '''küçerelmi qala''':
+* Töp bit [[Yärdäm:İsemara|isemara]] arqılı küçerelä;
+* Yaña başlıq astında buş bulmağan ikençe bit bulğanda;
+* Astağı tamğaqır sünderelgän bulsa.
+
+Bu äytelgän oçraqlarda bäxäs biten ayırım küçerergä turı kiler.",
+'movearticle' => 'Küçeräse bit',
+'movenologin' => 'Kermädeñ',
+'newtitle' => 'Yaña başlıq',
+'movepagebtn' => 'Küçer bitne',
+'pagemovedsub' => 'Küçerü uñışlı uzdı',
+'pagemovedtext' => 'Bu «[[$1]]» atlı bit «[[$2]]» iseme belän küçerelde.',
+'articleexists' => 'Andí atlı bit bar inde,
+yä isä saylanğan isem yaraqsız buldı. Başqa isem sayla zínhar.',
+'movedto' => 'küçerelde:',
+'movetalk' => 'Mömkin bulsa, «bäxäs» biten dä küçer.',
+'talkpagemoved' => 'Aña bäyle bäxäs bite şulay uq küçerelde.',
+'talkpagenotmoved' => 'Aña bäyle bäxäs bite <strong>küçerelmäde</strong>.',
+'1movedto2' => '$1 moña küçte: $2',
+'1movedto2_redir' => '$1 moña küçte: $2 (yünältü aşa)',
+
+# Namespace 8 related
+'allmessages' => 'Säxifäneñ bar sätirläre',
+'allmessagestext' => 'Bu säxifäneñ MediaWiki: atarasında bulğan yazmalar tezmäse.',
+
+# Thumbnails
+'thumbnail-more' => 'Zuraytası',
+'missingimage' => '<b>Bulmağan räsem</b><br /><i>$1</i>',
+
+# Special:Import
+'import' => 'Bitlärne yökläw',
+'importfailed' => 'Yökläw xatası: $1',
+'importnotext' => 'Buş yä ki mäten tügel',
+'importsuccess' => 'Yökläw uñışlı buldı!',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# Tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => "{{SITENAME}}'dä ezläw [alt-f]",
+'tooltip-minoredit' => 'Bu üzgärtmä waq-töyäk dip bilgelä [alt-i]',
+'tooltip-save' => 'Üzgärtüne saqlaw [alt-s]',
+
+# Stylesheets
+'common.css' => '/** CSS placed here will be applied to all skins */',
+'monobook.css' => '/* CSS placed here will affect users of the Monobook skin */',
+
+# Attribution
+'anonymous' => "{{SITENAME}}'nıñ tanılmağan kerüçe",
+'siteuser' => '{{SITENAME}} ägzäse $1',
+'and' => 'wä',
+'othercontribs' => '«$1» eşenä nigezlänä.',
+'others' => 'başqalar',
+'siteusers' => '{{SITENAME}} ägzäse $1',
+'creditspage' => 'Bit yasawında qatnaşqan',
+
+# Spam protection
+'spamprotectiontitle' => 'Çüpläwdän saqlanu eläge',
+'subcategorycount' => 'Bu cíıntıqnıñ $1 eçke cíıntıq bar.',
+'categoryarticlecount' => 'Bu cíıntıqqa $1 mäqälä kerä.',
+
+# Info page
+'infosubtitle' => 'Bit turında',
+'numedits' => 'Üzgärtü sanı (mäqälä):',
+'numtalkedits' => 'Üzgärtü sanı (bäxäs bite):',
+'numwatchers' => 'Küzätep toruçı sanı:',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => "/* äsbäpkiñäş wä ireşü töymäläre */
+ta = new Object();
+ta['pt-userpage'] = new Array('.','Şäxsi bitem');
+ta['pt-anonuserpage'] = new Array('.','The user page for the ip you're editing as');
+ta['pt-mytalk'] = new Array('n','Bäxäs bitem');
+ta['pt-anontalk'] = new Array('n','Discussion about edits from this ip address');
+ta['pt-preferences'] = new Array('','Köyläwlärem');
+ta['pt-watchlist'] = new Array('l','The list of pages you're monitoring for changes.');
+ta['pt-mycontris'] = new Array('y','Qatnaşuım tezmäse');
+ta['pt-login'] = new Array('o','You are encouraged to log in, it is not mandatory however.');
+ta['pt-anonlogin'] = new Array('o','You are encouraged to log in, it is not mandatory however.');
+ta['pt-logout'] = new Array('','Çığış');
+ta['ca-talk'] = new Array('t','Discussion about the content page');
+ta['ca-edit'] = new Array('e','You can edit Bu bit. Please use the preview button before saving.');
+ta['ca-addsection'] = new Array('+','Bu bäxästä yazma östäw.');
+ta['ca-viewsource'] = new Array('e','Bu bit yaqlanğan ide. Anıñ çığanağın kürä alasıñ.');
+ta['ca-history'] = new Array('h','Bu bitneñ soñğı yuramaları.');
+ta['ca-protect'] = new Array('=','Bu bit yaqlaw');
+ta['ca-delete'] = new Array('d','Bu bit beterü');
+ta['ca-undelete'] = new Array('d','Restore the edits done to Bu bit before it was deleted');
+ta['ca-move'] = new Array('m','Bu bit küçerü');
+ta['ca-nomove'] = new Array('','Bu bit küçerü öçen xoquqlarıñ citmi');
+ta['ca-watch'] = new Array('w','Bu bitne saqtezmägä östäw');
+ta['ca-unwatch'] = new Array('w','Bu bitne saqtezmädän töşerü');
+ta['search'] = new Array('e','Äydä, ezlä monı');
+ta['p-logo'] = new Array('','Täwge Bit');
+ta['n-mainpage'] = new Array('z','Täwge Bitkä küçü');
+ta['n-portal'] = new Array('','About the project, what you can do, where to find things');
+ta['n-currentevents'] = new Array('','Find background information on current events');
+ta['n-recentchanges'] = new Array('r','The list of recent changes in the wiki.');
+ta['n-randompage'] = new Array('x','Berär nindi bit kürsätä');
+ta['n-help'] = new Array('','The place to find out.');
+ta['n-sitesupport'] = new Array('','Ximäyäçe bul');
+ta['t-whatlinkshere'] = new Array('j','List of all wiki pages that link here');
+ta['t-recentchangeslinked'] = new Array('k','Recent changes in pages linking to Bu bit');
+ta['feed-rss'] = new Array('','Bu bitneñ RSS tasması');
+ta['feed-atom'] = new Array('','Bu bitneñ Atom tasması');
+ta['t-contributions'] = new Array('','View the list of contributions of this user');
+ta['t-emailuser'] = new Array('','Send a mail to this user');
+ta['t-upload'] = new Array('u','Upload images or media files');
+ta['t-specialpages'] = new Array('q','Bar maxsus bitlär tezmäse');
+ta['ca-nstab-main'] = new Array('c','Bu bit eçtälegen kürü');
+ta['ca-nstab-user'] = new Array('c','Bu äğzä biten kürü');
+ta['ca-nstab-media'] = new Array('c','Bu media biten kürü');
+ta['ca-nstab-special'] = new Array('','Bu bit maxsus, wä sin anı üzgärtä almísıñ.');
+ta['ca-nstab-project'] = new Array('a','Proékt biten kürü');
+ta['ca-nstab-image'] = new Array('c','Bu räsem biten kürü');
+ta['ca-nstab-mediawiki'] = new Array('c','Bu säxifä sätiren kürü');
+ta['ca-nstab-template'] = new Array('c','Bu qalıpnı kürü');
+ta['ca-nstab-help'] = new Array('c','Bu yärdäm biten kürü');
+ta['ca-nstab-category'] = new Array('c','View the category page');",
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* Any JavaScript here will be loaded for all users on every page load. */',
+
+);
+
+?>
diff --git a/languages/messages/MessagesTyv.php b/languages/messages/MessagesTyv.php
new file mode 100644
index 000000000000..dadacb398e27
--- /dev/null
+++ b/languages/messages/MessagesTyv.php
@@ -0,0 +1,307 @@
+<?php
+/** Tyvan localization (Тыва дыл)
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+# From friends at tyvawiki.org
+
+$namespaceNames = array(
+ NS_MEDIA => 'Медиа', //Media
+ NS_SPECIAL => 'Тускай', //Special
+ NS_MAIN => '',
+ NS_TALK => 'Чугаа', //Talk
+ NS_USER => 'Aжыглакчы', //User
+ NS_USER_TALK => 'Aжыглакчы_чугаа', //User_talk
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_чугаа', //_talk
+ NS_IMAGE => 'Чурук', //Image
+ NS_IMAGE_TALK => 'Чурук_чугаа', //Image_talk
+ NS_MEDIAWIKI => 'МедиаВики', //MediaWiki
+ NS_MEDIAWIKI_TALK => 'МедиаВики_чугаа', //MediaWiki_talk
+ NS_TEMPLATE => 'Хээ', //Template
+ NS_TEMPLATE_TALK => 'Хээ_чугаа', //Template_talk
+ NS_HELP => 'Дуза', //Help
+ NS_HELP_TALK => 'Дуза_чугаа', //Help_talk
+ NS_CATEGORY => 'Бөлүк', //Category
+ NS_CATEGORY_TALK => 'Бөлүк_чугаа', //Category_talk
+);
+
+$skinNames = array(
+ 'standard' => 'Classic', //Classic
+ 'nostalgia' => 'Nostalgia', //Nostalgia
+ 'cologneblue' => 'Cologne Blue', //Cologne Blue
+ 'davinci' => 'ДаВинчи', //DaVinci
+ 'mono' => 'Моно', //Mono
+ 'monobook' => 'Моно-Ном', //MonoBook
+ 'myskin' => 'MySkin', //MySkin
+ 'chick' => 'Chick' //Chick
+);
+
+$bookstoreList = array(
+ 'ОЗОН' => 'http://www.ozon.ru/?context=advsearch_book&isbn=$1',
+ 'Books.Ru' => 'http://www.books.ru/shop/search/advanced?as%5Btype%5D=books&as%5Bname%5D=&as%5Bisbn%5D=$1&as%5Bauthor%5D=&as%5Bmaker%5D=&as%5Bcontents%5D=&as%5Binfo%5D=&as%5Bdate_after%5D=&as%5Bdate_before%5D=&as%5Bprice_less%5D=&as%5Bprice_more%5D=&as%5Bstrict%5D=%E4%E0&as%5Bsub%5D=%E8%F1%EA%E0%F2%FC&x=22&y=8',
+ 'Яндекс.Маркет' => 'http://market.yandex.ru/search.xml?text=$1',
+ 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1',
+ 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
+ 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
+ 'Barnes & Noble' => 'http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1'
+);
+
+$fallback8bitEncoding = "windows-1251";
+
+
+$messages = array(
+
+# User preference toggles
+'tog-hideminor' => 'Сөөлгү өскерлиишкиннер арында бичии өскерлиишкиннер чажырар', //Hide minor edits in recent changes
+'tog-showtoolbar' => 'Редактолаар херекселтер көргүзер (JavaScript)', //Show edit toolbar (JavaScript)
+'tog-editondblclick' => 'Арынны өскертирде ийи катап базар (JavaScript)', //Edit pages on double click (JavaScript)
+
+'underline-always' => 'Кезээде', //Always
+'underline-never' => 'Кажан-даа', //Never
+'underline-default' => 'Browser default', //Browser default
+
+# dates
+'sunday' => 'Чеди дугаар хүн', //Sunday
+'monday' => 'Бир дугаар хүн', //Monday
+'tuesday' => 'Ийи дугаар хүн', //Tuesday
+'wednesday' => 'Үш дугаар хүн', //Wednesday
+'thursday' => 'Дөрт дугаар хүн', //Thursday
+'friday' => 'Беш дугаар хүн', //Friday
+'saturday' => 'Алды дугаар хүн', //Saturday
+'january' => 'Бир ай', //January
+'february' => 'ийи ай', //February
+'march' => 'Үш ай', //March
+'april' => 'Дөрт ай', //April
+'may_long' => 'Беш ай', //May
+'june' => 'Алды ай', //June
+'july' => 'Чеди ай', //July
+'august' => 'Сес ай', //August
+'september' => 'Тос ай', //September
+'october' => 'Он ай', //October
+'november' => 'Он бир ай', //November
+'december' => 'Он ийи ай', //December
+'jan' => '1.ай', //Jan
+'feb' => '2.ай', //Feb
+'mar' => '3.ай', //Mar
+'apr' => '4.ай', //Apr
+'may' => '5.ай', //May
+'jun' => '6.ай', //Jun
+'jul' => '7.ай', //Jul
+'aug' => '8.ай', //Aug
+'sep' => '9.ай', //Sep
+'oct' => '10.ай', //Oct
+'nov' => '11.ай', //Nov
+'dec' => '12.ай', //Dec
+
+# Bits of text used by many pages:
+#
+'categories' => 'Бөлүктер', //Categories
+'pagecategories' => 'Бөлүктер', //{{PLURAL:$1|Category|Categories}}
+'category_header' => '"$1" бөлүкте чүүлдер', //Articles in category $1
+'subcategories' => 'Бичии бөлүктер', //Subcategories
+
+'mainpage' => 'Кол Арын', //Main Page
+
+'about' => 'Дугайында', //About
+'aboutsite' => '{{SITENAME}} дугайында', //About {{SITENAME}}
+'aboutpage' => 'Project:Дугайында', //Project:About
+'article' => 'Азыраары арын', //Content page
+'help' => 'Дуза', //Help
+'helppage' => 'Дуза:Допчузу', //Help:Contents
+'sitesupport' => 'Белектер', //Donations
+'newwindow' => '(чаа козенектен ажар)', //(opens in new window)
+'edithelppage' => 'Дуза:Өскертир', //Help:Editing
+'cancel' => 'Ап каар', //Cancel (Солуур)
+'qbfind' => 'Тывар', //Find
+'qbbrowse' => 'Көөр', //Browse
+'qbedit' => 'Редакторлаар', //Edit
+'qbpageoptions' => 'Бо арын', //This page
+'qbpageinfo' => 'Context', //Context
+'qbmyoptions' => 'Мээң арыннарым', //My pages
+'qbspecialpages' => 'Тускай арыннар', //Special pages
+'moredotdotdot' => 'Ам-даа...', //More...
+'mypage' => 'Мээң арыным', //My page
+'mytalk' => 'Мээң чугаалажырым', //My talk чугааm?
+'anontalk' => 'Бо ИП-адрестиң чугаа', //Talk for this IP
+'navigation' => 'Навигация', //Navigation
+
+
+'errorpagetitle' => "Частырыг", //Error
+'returnto' => "{{grammar:directive1|$1}} дедир.", //Return to $1.
+'tagline' => "{{grammar:ablative|{{SITENAME}}}}", //From {{SITENAME}}
+'whatlinkshere' => 'Pages that link here', //Pages that link here
+'help' => 'Дуза', //Help
+'search' => 'Дилээр', //Search
+'searchbutton' => 'Дилээр', //Search
+'go' => 'Чоруур', //Go
+'searcharticle' => 'Чоруур', //Go
+'history' => 'Арынның Төөгүзү', //Page history
+'history_short' => 'Төөгү', //History
+'printableversion' => 'Саазынга үндүрерин көөр', //Printable version (Парлатынар арын)
+'permalink' => 'Permanent link',
+'print' => 'Саазынга үндүрер', //Print
+'edit' => 'Өскертир', //Edit
+'editthispage' => 'Бо арынны өскертир', //Edit this page
+'delete' => 'Ап каар', //Delete
+'deletethispage' => 'Бо арынны ап каар', //Delete this page
+'protect' => 'Камгалал', //Protect
+'protectthispage' => 'Бо арынны камгалаар', //Protect this page
+'unprotect' => 'Камгалалды ап каар', //unprotect
+'unprotectthispage' => 'Бо арынның камгалалын ап каар', //Unprotect this page
+'newpage' => 'Чаа Арын', //New page
+'talkpage' => 'Бо арын дугайында чугаалажыр', //Discuss this page
+'specialpage' => 'Тускай Арын', //Special Page
+'personaltools' => 'Херекселдер', //Personal tools
+'articlepage' => 'Допчу арынны көргүзер', //View content page
+'talk' => 'Чугаалажыр', //Discussion
+'userpage' => 'Ажыглакчыниң арынын көргүзер', //View user page
+'imagepage' => 'Чурук арынын көргүзер', //View image page
+'viewtalkpage' => 'Чугаалажыры көргүзер', //View discussion
+'otherlanguages' => 'Өске дылдарга', //In other languages
+'lastmodifiedat' => 'Бо арын сөөлгү каттап $1 өскерилген.', //This page was last modified $2, $1.
+//'viewcount' => 'Бо арын $1 каттап ажыттынган.', //This page has been accesed $1 times.
+'retrievedfrom' => "\"$1\" арынында парлаттынган", //Retrieved from \"$1\"
+'newmessageslink' => 'чаа чагаалар', //new messages
+'editsection'=>'өскертир', //edit
+'editold'=>'өскертир', //edit
+'toc' => 'Допчу', //Contents
+'showtoc' => 'көргүзер', //show
+'hidetoc' => 'чажырар', //hide
+'restorelink' => "$1 балаттынган өскерилгелер", //$1 deleted edits
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Чүүл', //Article
+'nstab-user' => 'Ажыглакчының арыны', //User page
+'nstab-media' => 'Медиа арыны', //Media page
+'nstab-special' => 'Тускай', //Special
+'nstab-project' => 'Проект арыны', //Project page
+'nstab-image' => 'Файл', //File
+'nstab-mediawiki' => 'Чагаа', //Message
+'nstab-template' => 'Хээ', //Template
+'nstab-help' => 'Дуза', //Help
+'nstab-category' => 'Бөлүк', //Category
+
+# Main script and global functions
+#
+'nosuchspecialpage' => 'Ындыг арын чок', //No such special page
+
+# General errors
+#
+'noconnect' => 'Буруулуг болдувус! Викиде чамдык техниктиг бергедээшкиннер бар болганындан database серверинче коштунмаан. <br />
+$1', //Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server.
+'laggedslavemode' => 'Оваарымчалыг: Бо арында чаартыышкыннар чок болуп болур', //Warning: Page may not contain recent updates.
+
+# Login and logout pages
+#
+'yourname' => 'Aжыглакчының ады', //Username
+'yourpassword' => 'Чажыт сөс', //Password
+'remembermypassword' => 'Мени сактып алыр', //Remember me
+'createaccountmail' => 'email-биле', //by e-mail
+'badretype' => 'Силернин парлаан чажыт созуңер таарышпас.', //The passwords you entered do not match.
+'userexists' => 'Силернин парлаан адыңар амгы уеде ажыглаттынып турар. өске аттан шилип алыңар.', //Username entered is already in use. Please choose a different name.
+'username' => 'Aжыглакчының ады:', //Username:
+'yourrealname' => 'Шын адыңар *', //Real name *
+'yourlanguage' => 'Дылыңар:', //Language:
+'yournick' => 'Шола ат:', //Nickname:
+
+# Edit page toolbar
+'bold_sample'=>'Карартыр', //Bold text
+'italic_sample'=>'Ийлендирер', //Italic text
+'nowiki_sample'=>'Форматтаваан текстини бээр салыр', //Insert non-formatted text here
+
+# Edit pages
+#
+'watchthis' => 'Бо арынны көөр', //Watch this page
+'accmailtitle' => 'Чажыт сөс чоргустунган.', //Password sent.
+'accmailtext' => '"{{grammar:genitive|$1}}" чажыт сөстү {{grammar:directive1|$2}} чоргузуптувус.', //The password for "$1" has been sent to $2.
+'newarticle' => '(Чаа)', //(New)
+'yourtext' => 'Силерниң сөзүглел', //Your text
+
+# History pages
+#
+'next' => 'соонда', //next
+
+# Diffs
+#
+'compareselectedversions' => 'Шилип алган хевирлери деңнээр', //Compare selected versions
+
+# Preferences page
+#
+'preferences' => 'Дээре деп санаарылар', //Preferences
+'prefs-personal' => 'Ажыглакчының медээлери', //User profile
+'saveprefs' => 'Шыгжаар', //Save
+'oldpassword' => 'Эгри чажыт сөс:', //Old password:
+'newpassword' => 'Чаа чажыт сөс:', //New password:
+'searchresultshead' => 'Дилээр', //Search
+'files' => 'Файлдар', //Files
+
+# Recent changes
+#
+'recentchanges' => 'Өскерлиишкиннер', //Recent changes
+'hide' => 'Чажырар', //Hide
+'show' => 'көргүзер', //show
+
+# Upload
+#
+'filename' => 'Файлдың ады', //Filename
+'filesource' => 'Эгези', //Source
+
+# Image list
+#
+'ilsubmit' => 'Дилээр', //Search
+
+# Miscellaneous special pages
+#
+'randompage' => 'Даап арын', //Random page
+'specialpages' => 'Тускай арыннар', //Special pages
+'spheading' => 'Шупту ажыглакчыниң тускай арыннар', //Special pages for all users
+'newpages' => 'Чаа Арыннар', //New pages
+
+
+# Special:Allpages
+'allarticles' => 'Шупту чүүлдер', //All articles
+'allpagesprev' => 'Пертинде', //Previous
+'allpagesnext' => 'Соонда', //Next
+'allpagessubmit' => 'Чоруур', //Go
+
+# E this user
+#
+'emailmessage' => 'Дыңнадыры', //Message
+
+# Watchlist
+#
+'enotif_newpagetext'=> 'Бо чаа арын-дыр.', //This is a new page.
+
+# Delete/protect/revert
+#
+'actioncomplete' => 'Ажыл доосту', //Action complete
+
+# Contributions
+#
+'contributions' => 'Ажыглакчыниң деткимчемнер', //User contributions
+'mycontris' => 'Мээң деткимчемнерим', //My contributions
+
+# Block/unblock IP
+#
+'ipaddress' => 'ИП-адрес', //IP Address
+'ipadressorusername' => 'ИП-адрес азы aжыглaкчының aды', //IP Address or username
+'badipaddress' => 'Багай ИП-адрес', //Invalid IP address
+'infiniteblock' => 'кезээ-мөңгеде', //infinite
+
+# Make sysop
+'makesysopname' => 'Ажыглакчыниң ады:', //Name of the user:
+
+# Namespace 8 related
+
+'allmessages' => 'Системниң дыңнадырылар', //System messages
+'allmessagesname' => 'Ат', //Name
+'allmessagesdefault' => 'Default сөзүглел', //Default text
+'allmessagescurrent' => 'Амгы сөзүглел', //Current text
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Ажыглакчы:', //User:
+
+);
+?>
diff --git a/languages/messages/MessagesUdm.php b/languages/messages/MessagesUdm.php
new file mode 100644
index 000000000000..c1acc8c37aad
--- /dev/null
+++ b/languages/messages/MessagesUdm.php
@@ -0,0 +1,51 @@
+<?php
+/** Udmurt (Удмурт)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ *
+ */
+
+$fallback = 'ru';
+
+$namespaceNames = array(
+ NS_MEDIA => 'Медиа',
+ NS_SPECIAL => 'Панель',
+ NS_MAIN => '',
+ NS_TALK => 'Вераськон',
+ NS_USER => 'Викиавтор',
+ NS_USER_TALK => 'Викиавтор_сярысь_вераськон',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_сярысь_вераськон',
+ NS_IMAGE => 'Суред',
+ NS_IMAGE_TALK => 'Суред_сярысь_вераськон',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_сярысь_вераськон',
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Шаблон_сярысь_вераськон',
+ NS_HELP => 'Валэктон',
+ NS_HELP_TALK => 'Валэктон_сярысь_вераськон',
+ NS_CATEGORY => 'Категория',
+ NS_CATEGORY_TALK => 'Категория_сярысь_вераськон',
+);
+
+$linkTrail = '/^([a-zа-яёӝӟӥӧӵ“»]+)(.*)$/sDu';
+$fallback8bitEncoding = 'windows-1251';
+$separatorTransformTable = array(',' => ' ', '.' => ',' );
+
+$messages = array(
+'linkprefix' => '/^(.*?)(„|«)$/sDu',
+'article' => 'Статья',
+'createaccount' => 'выль вики-авторлэн регистрациез',
+'edit' => 'тупатыны',
+'hist' => 'история',
+'history' => 'Бамлэн историез',
+'history_short' => 'история',
+'login' => 'Википедие пырон',
+'mycontris' => 'мынам статьяосы',
+'mytalk' => 'викиавтор сярысь вераськон',
+'nstab-user' => 'викиавтор',
+'preferences' => 'настройкаос',
+);
+
+?>
diff --git a/languages/messages/MessagesUg.php b/languages/messages/MessagesUg.php
new file mode 100644
index 000000000000..9531c0101bc4
--- /dev/null
+++ b/languages/messages/MessagesUg.php
@@ -0,0 +1,10 @@
+<?php
+/** Uyghur (Oyghurque)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$rtl = true;
+
+?>
diff --git a/languages/messages/MessagesUk.php b/languages/messages/MessagesUk.php
new file mode 100644
index 000000000000..59492e993b0f
--- /dev/null
+++ b/languages/messages/MessagesUk.php
@@ -0,0 +1,826 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Медіа',
+ NS_SPECIAL => 'Спеціальні',
+ NS_MAIN => '',
+ NS_TALK => 'Обговорення',
+ NS_USER => 'Користувач',
+ NS_USER_TALK => 'Обговорення_користувача',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Обговорення_$1',
+ NS_IMAGE => 'Зображення',
+ NS_IMAGE_TALK => 'Обговорення_зображення',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Обговорення_MediaWiki',
+ NS_TEMPLATE => 'Шаблон',
+ NS_TEMPLATE_TALK => 'Обговорення_шаблону',
+ NS_HELP => 'Довідка',
+ NS_HELP_TALK => 'Обговорення_довідки',
+ NS_CATEGORY => 'Категорія',
+ NS_CATEGORY_TALK => 'Обговорення_категорії'
+);
+
+$quickbarSettings = array(
+ "Не показувати панель", "Фіксована зліва", "Фіксована справа", "Плаваюча зліва"
+);
+
+$skinNames = array(
+ 'standard' => "Стандартне",
+ 'nostalgia' => "Ностальгія",
+ 'cologneblue' => "Кельнське Синє"
+);
+
+
+$datePreferences = false;
+
+$fallback8bitEncoding = "windows-1251";
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+$linkTrail = "/^([a-z]+)(.*)\$/sD";
+
+
+$messages = array(
+# User Toggles
+
+"tog-underline" => "Підкреслювати зв'язки",
+"tog-highlightbroken" => "Форматувати неіснуючі зв'язки <a href=\"\" class=\"new\">ось так</a> (Альтернатива: ось так<a href=\"\" class=\"internal\">?</a>).",
+"tog-justify" => "Вирівнювати параграфи",
+"tog-hideminor" => "Ховати незначні зміни в списку недавніх змін",
+"tog-usenewrc" => "Покращений список недавніх змін (підтримується не всіма браузерами)",
+"tog-numberheadings" => "Автоматично нумерувати заголовки",
+"tog-editondblclick" => "Редагувати статті при подвійному натисканні кнопки миші (JavaScript)",
+"tog-editsection"=>"Редагувати секції по зв'язку [прав.]",
+"tog-editsectiononrightclick"=>"Редагувати секції по правій кнопці миші на назві секції (JavaScript)",
+"tog-showtoc"=>"Показувати зміст (для статей з більше ніж 3-ма заголовками)",
+"tog-rememberpassword" => "Запам'ятовувати пароль між сеансами",
+"tog-editwidth" => "Розширяти вікно для редагування до меж вікна браузера",
+"tog-watchdefault" => "Слідкувати за новими та зміненими статтями",
+"tog-minordefault" => "Спочатку вважати всі зміни незначними",
+"tog-previewontop" => "Показувати попередній текст до вікна редагування, а не післе",
+"tog-nocache" => "Заборонити кешування статей",
+# Dates
+'sunday' => "неділя",
+'monday' => "понеділок",
+'tuesday' => "вівторок",
+'wednesday' => "середа",
+'thursday' => "четвер",
+'friday' => "п'ятниця",
+'saturday' => "субота",
+'january' => "січень",
+'february' => "лютий",
+'march' => "березень",
+'april' => "квітень",
+'may_long' => "травень",
+'june' => "червень",
+'july' => "липень",
+'august' => "серпень",
+'september' => "вересень",
+'october' => "жовтень",
+'november' => "листопад",
+'december' => "грудень",
+'january-gen' => 'січня',
+'february-gen' => 'лютого',
+'march-gen' => 'березня',
+'april-gen' => 'квітня',
+'may-gen' => 'травня',
+'june-gen' => 'червня',
+'july-gen' => 'липня',
+'august-gen' => 'серпня',
+'september-gen' => 'вересня',
+'october-gen' => 'жовтня',
+'november-gen' => 'листопада',
+'december-gen' => 'грудня',
+'jan' => "січ",
+'feb' => "лют",
+'mar' => "бер",
+'apr' => "квіт",
+'may' => "трав",
+'jun' => "черв",
+'jul' => "лип",
+'aug' => "серп",
+'sep' => "вер",
+'oct' => "жов",
+'nov' => "лист",
+'dec' => "груд",
+
+# Bits of text used by many pages:
+#
+"mainpage" => "Головна стаття",
+"mainpagetext" => "Програмне забезпечення вікі встановлено.",
+"about" => "Про",
+"aboutsite" => "Про {{SITENAME}}",
+"aboutpage" => "{{ns:project}}:Про",
+"help" => "Довідка",
+"helppage" => "{{ns:project}}:Довідка",
+"bugreports" => "Звіт про помилку",
+"bugreportspage" => "{{ns:project}}:Звіт_про_помилку",
+"sitesupport" => "Sitesupport",
+"faq" => "Часті питання",
+"faqpage" => "{{ns:project}}:Часті питання",
+"edithelp" => "Довідка про редагування",
+"edithelppage" => "{{ns:project}}:Як_редагувати_статті",
+"cancel" => "Відмінити",
+"qbfind" => "Знайти",
+"qbbrowse" => "Переглянути",
+"qbedit" => "Редагувати",
+"qbpageoptions" => "Настройки статті",
+"qbpageinfo" => "Інформація про статтю",
+"qbmyoptions" => "Ваші настройки",
+"mypage" => "Ваша особиста сторінка",
+"mytalk" => "Ваше особисте обговорення",
+"currentevents" => "Поточні події",
+"errorpagetitle" => "Помилка",
+"returnto" => "Повернутися до $1.",
+"whatlinkshere" => "Статті, що вказують на дану",
+"help" => "Довідка",
+"search" => "Пошук",
+"searchbutton" => "Пошук",
+"go" => "Перейти",
+'searcharticle' => "Перейти",
+"history" => "Старі версії",
+"printableversion" => "Версія для друку",
+"editthispage" => "Редагувати дану статтю",
+"deletethispage" => "Вилучити дану статтю",
+"protectthispage" => "Встановити захист",
+"unprotectthispage" => "Зняти захист",
+"newpage" => "Нова стаття",
+"talkpage" => "Обговорити статтю",
+"postcomment" => "Прокоментувати",
+"articlepage" => "Переглянути статтю",
+"userpage" => "Переглянути сторінку користувача",
+"projectpage" => "Переглянути мета-сторінку",
+"imagepage" => "Переглянути сторінку зображення",
+"viewtalkpage" => "Переглянути обговорення",
+"otherlanguages" => "Іншими мовами",
+"redirectedfrom" => "(Перенаправлено з $1)",
+"lastmodifiedat" => "Остання зміна $2, $1.",
+"viewcount" => "Цю статтю переглядали $1 разів.",
+"protectedpage" => "Захищена стаття",
+"nbytes" => "$1 байт(ів)",
+"ok" => "OK",
+"retrievedfrom" => "Отримано від \"$1\"",
+"newmessageslink" => "нові повідомлення",
+"editsection"=>"ред.",
+"editold"=>"ред.",
+"toc" => "Зміст",
+"showtoc" => "показати",
+"hidetoc" => "сховати",
+"thisisdeleted" => "Переглянути або відновити $1?",
+"restorelink" => "$1 змін вилучено",
+
+# Main script and global functions
+#
+"nosuchaction" => "Такої дії не існує",
+"nosuchactiontext" => "Дія, вказана в URL, не розпізнається програмним забезпеченням {{SITENAME}}",
+"nosuchspecialpage" => "Такої спеціальної сторінки не існує",
+"nospecialpagetext" => "Спеціальна сторінка не розпізнається програмним забезпеченням {{SITENAME}}.",
+
+# General errors
+#
+"error" => "Помилка",
+"databaseerror" => "Помилка бази даних",
+"dberrortext" => "Знайдено помилку синтаксису запиту до бази даних.
+Останній запит до бази даних:
+<blockquote><tt>$1</tt></blockquote>
+відбувся з функції \"<tt>$2</tt>\".
+MySQL повернув помилку \"<tt>$3: $4</tt>\".",
+"dberrortextcl" => "Знайдено помилку синтаксису запиту до бази даних.
+Останній запит до бази даних:
+\"$1\"
+відбувся з функції \"$2\".
+MySQL повернув помилку \"$3: $4\".",
+"noconnect" => "Тяжко вибачаємось! В зв'язку з технічними неполадками зараз неможливо зв'язатися з сервером баз даних.",
+"nodb" => "Неможливо вибрати базу даних $1",
+"cachederror" => "Нижче відображена кеш-копія запитаної статті, можливо вона застаріла.",
+"readonly" => "Запис в базу даних заблоковано",
+"enterlockreason" => "Введіть обґрунтування блокування та інформацію про те, коли блокування буде знято",
+"readonlytext" => "Внесення нових статей та інші зміни бази даних {{SITENAME}} в даний момент заблоковано, ймовірно, через планове сервісне обслуговування бази даних,
+по закінченню якого нормальний стан буде відновлено.
+Заблокувавший адміністратор дав наступні пояснення:
+<p>$1",
+"missingarticle" => "База даних не знайшла текст статті,
+хоча повинна була знайти під іменем \"$1\".
+<p>Це може бути викликано використанням застарілого посилання на журнал змін або відмінностей для статті, що була вилучена.
+<p>Якщо справа не в цьому, то, швидше за все, ви знайшли помилку в програмному забезпеченні {{SITENAME}}.
+Будь-ласка, повідомте про це адміністратору, вказавши URL.",
+"internalerror" => "Внутрішня помилка",
+"filecopyerror" => "Неможливо скопіювати файл \"$1\" в \"$2\".",
+"filerenameerror" => "Неможливо перейменувати файл \"$1\" в \"$2\".",
+"filedeleteerror" => "Неможливо вилучити файл \"$1\".",
+"filenotfound" => "Неможливо знайти файл \"$1\".",
+"unexpected" => "Неочікуване значення: \"$1\"=\"$2\".",
+"formerror" => "Помилка: неможливо прийняти форму",
+"badarticleerror" => "Ця дія не може бути виконана над даною статтею.",
+"cannotdelete" => "Неможливо вилучити вказану статтю чи файл. (Можливо, його вже вилучив хтось інший.)",
+"badtitle" => "Недопустима назва",
+"badtitletext" => "Невірна назва статті, пуста, або невірно вказано міжмовна або між-вікі назва.",
+"perfdisabled" => "Вибачаємося! Ця можливість тимчасово недоступна через обмеженість ресурсів.",
+"perfdisabledsub" => "Це - збережена копія від $1:",
+"viewsource" => "Переглянути початковий текст",
+"protectedtext" => "Ця сторінка була заблокована, щоб не допустити
+зміни; для цього можуть бути різні причини, подивіться будь-ласка
+[[{{ns:project}}:Захищена стаття]].
+
+You can view and copy the source of this page:",
+
+# Login and logout pages
+#
+"logouttitle" => "Вийти з системи",
+"logouttext" => "Ви працюєте в тому ж режимі, який був до вашої реєстрації в системі. Ви ідентифікуєтесь не з іменем, а з IP-адресом.
+Ви можете продовжувати використовувати {{SITENAME}} анонімно, або почати новий сеанс як той же самий чи інший користувач.",
+
+"welcomecreation" => "<h2>Вітаємо Вас, $1!</h2><p>Ви зареєстровані.
+Не забудьте налаштувати {{SITENAME}} так, як Вам зручно.",
+
+"loginpagetitle" => "Вхід в систему",
+"yourname" => "Ваше ім'я",
+"yourpassword" => "Ваш пароль",
+"yourpasswordagain" => "Повторний набір пароля",
+"remembermypassword" => "Запам'ятовувати ваш пароль між сеансами.",
+"loginproblem" => "<b>Проблема при вході в систему.</b><br />попробуйте ще раз!",
+"alreadyloggedin" => "<strong>Користувач $1, ви вже ввійшли в систему!</strong><br />",
+"login" => "Вхід в систему",
+"userlogin" => "Вхід в систему",
+"logout" => "Вийти з системи",
+"userlogout" => "Вийти з системи",
+"notloggedin" => "Ви не ввійшли в систему",
+"createaccount" => "Зареєструвати нового користувача",
+"badretype" => "Введені вами паролі не співпадають.",
+"userexists" => "Введене вами ім'я користувача вже існує. Виберіть будь-ласка інше ім'я.",
+"youremail" => "Адреса вашої електронної пошти*",
+"yournick" => "Ваш псевдонім (для підписів)",
+"loginerror" => "Помилка при вході в систему",
+"noname" => "Користувача з таким іменем не існує.",
+"loginsuccesstitle" => "Успішний вхід в систему",
+"loginsuccess" => "Тепер ви працюєте в {{SITENAME}} під іменем \"$1\".",
+"nosuchuser" => "Користувача з таким іменем \"$1\" не існує.
+Перевірте вірність написання, або скористайтеся формою, що нижче, щоб зареєструвати нового користувача.",
+"wrongpassword" => "Введений вами пароль невірний. Попробуйте ще раз.",
+"mailmypassword" => "Відправити вам новий пароль",
+"passwordremindertitle" => "Пам'ятка пароля {{SITENAME}}",
+"passwordremindertext" => "Хтось (можливо, ви - з IP-адреси $1)
+зробив запит на відправлення вам нового пароля користувача проекту {{SITENAME}}.
+Пароль користувача \"$2\" тепер такий: \"$3\".
+Тепер вам необхідно ввійти в систему й змінити пароль.",
+"noemail" => "Для користувача \"$1\" не вказано адресу електронної пошти.",
+"passwordsent" => "Новий пароль відправлено на адресу електронної пошти, вказану для \"$1\".
+Будь-ласка, ввійдіть в систему після отримання пароля.",
+
+# Edit pages
+#
+"summary" => "Короткий опис",
+"subject" => "Тема/заголовок",
+"minoredit" => "Це незначна зміна",
+"watchthis" => "Спостерігати за цією статтею",
+"savearticle" => "Зберегти статтю",
+"preview" => "Попередній перегляд",
+"showpreview" => "Показати попередній варіант",
+"blockedtitle" => "Користувача заблоковано",
+"blockedtext" => "Ваш користувач чи IP-адреса заблоковані $1.
+Причина блокування:<br />''$2''<p>Ви можете зв'язатися з $1 чи іншим
+[[{{ns:project}}:Администратори|администратором]] що обговорити блокування.
+Зверніть увагу, що ви не можете використовувати функцію \"Надіслати електронного листа користувачу\", якщо ви не вказали адресу вашої електронної пошти в Ваших [[Спеціальні:Настройки|настройках]]
+Ваша IP-адреса - $3. Будь-ласка, вказуйте, якщо будете запитувати про блокування.
+==Зауваження для користувачів America On-Line==
+Через багаторазові акти вандалізму одного з користувачів AOL, {{SITENAME}} часто блокує проксі-сервери AOL. Один й той же сервер може використовуватися різними користувачами, тому, нажаль, невинні користувачі AOL часто бувають _неспеціальне_ заблоковані. Ми вибачаємося за незручності.
+Якщо це відбулося з Вами, відправте, будь-ласка, електронною поштою листа адміністратору. Не забудьте вказати вашу IP-адресу, вказану вище.",
+"newarticle" => "(Нова)",
+"newarticletext" => "Ви перейшли на статтю, яка поки що не існує.
+Щоб створити нову статтю, наберіть текст в вікні нижче
+(див. [[{{ns:project}}:Довідка|довідкову статтю]] щоб отримати більше інформації).
+Якщо ви опинились тут помилково, просто натисніть кнопку браузера '''назад'''.",
+"anontalkpagetext" => "---- ''Це сторінка обговорення, що належить анонімному користувачу, який ще не зареєструвався або не скористався зареєстрованим ім'ям. Тому ми вимушені використовувати [[IP-адресу]] для його ідентифікації. Одна IP-адреса може використовуватися декількома користувачами. Якщо ви - анонімний користувач і вважаєте, що отримали коментарі, адресовані не вам, будь ласка [[Спеціальні:Вхід_в_систему|зареєструйтесь або ввійдіть в систему як зареєстрований користувач]], щоб в майбутньому уникнути можливої плутанини з іншими анонімними користувачами.''",
+"noarticletext" => "(На даний момент текст в цієї статті відсутній)",
+"updated" => "(Оновлена)",
+"note" => "<strong>Зауваження:</strong>",
+"previewnote" => "Зверніть увагу, - це тільки попередній перегляд, і текст ще не збережено!",
+"previewconflict" => "Цей попередній перегляд відображає текст з вікна редагування так, як він буде виглядіти, якщо ви вирішите записати його.",
+"editing" => "Редагування $1",
+'editinguser' => "Редагування $1",
+"editingsection" => "Редагування $1 (секція)",
+"editingcomment" => "Редагування $1 (коментар)",
+"editconflict" => "Конфлікт редакцій: $1",
+"explainconflict" => "Ще хтось змінив цю статтю з того часу, як ви розпочали її змінювати.
+В верхній частині тексту показано, як стаття виглядить зараз. Ваші зміни показані в нижній частині тексту.
+Вам необхідно буде скомпонувати ваші зміни в існуючий текст.
+Якщо ви натиснете \"Зберегти статтю\", то буде збережено <b>тільки</b> текст в верхньому вікні редагування.<br />",
+"yourtext" => "Ваш текст",
+"storedversion" => "Збережена версія",
+"editingold" => "<strong>ПОПЕРЕДЖЕННЯ: Ви редагуєте застарівшу версію даної статті.
+Якщо ви збережете її, будь-які редагування, зроблені між версіями, будуть втрачені.</strong>",
+"yourdiff" => "Відмінності",
+/*"copyrightwarning" => "Будь ласка, зверніть увагу, що будь-які добавлення
+й зміни в {{SITENAME}} розглядаються як випущені на умовах
+GNU Free Documentation License без незмінюваних секцій
+(див. $1, щоб взнати подробиці).
+Якщо ви не бажаєте, щоб написане вами безжалісно редагувалось
+і розповсюджувалося за бажанням будь-кого, - не пишіть тут.<br />
+
+Ви також зобов'язуєтесь, що написане вами тут належить вам чи взято з джерела,
+що є суспільною власністю чи подібним вільним джерелом.
+<strong>НЕ ПУБЛІКУЙТЕ ТУТ БЕЗ ДОЗВОЛУ ТВОРИ, ЩО Є ОБ'ЄКТОМ АВТОРСКОГО ПРАВА,
+Й ЛІЦЕНЗІЯ ЯКИХ НЕ ДОЗВОЛЯЄ ПОДІБНОЇ ПУБЛІКАЦІЇ!</strong>",*/
+"longpagewarning" => "<strong>ПОПЕРЕДЖЕННЯ: Довжина цієї статті $1 кілобайт; статті, розмір яких перевищує 32кб. можуть створювати проблеми для деяких браузерів.
+Розгляньте, будь-ласка, варіанти розбиття статті на менші частини.</strong>",
+"readonlywarning" => "<strong>ПОПЕРЕДЖЕННЯ: База даних заблокована в зв’язку з процедурами обслуговування,
+тому ви не можете записати ваші зміни в даний момент.
+Можливо, вам варто зберегти текст в локальний файл (на свому диску) й записати його в {{SITENAME}} пізніше.</strong>",
+"protectedpagewarning" => "<strong>ПОПЕРЕДЖЕННЯ: Ця стаття заблокована, так що тільки користувачі с правом
+Сисоп можуть змінювати її. Будь-ласка, перегляньте
+[[Project:Правила захисту статей'>правила захисту статей]].</strong>",
+
+# History pages
+#
+"revhistory" => "Журнал редагувань",
+"nohistory" => "Для цієї статті відсутній журнал редагувань.",
+"revnotfound" => "Версію не знайдено",
+"revnotfoundtext" => "Неможливо знайти необхідну вам версію статті.
+Будь-ласка, перевірте правильність URL, який ви використовували для доступу до цієї статті.",
+"loadhist" => "Завантаження журналу редагувань статті",
+"currentrev" => "Поточна версія",
+"revisionasof" => "Версія $1",
+"cur" => "поточн.",
+"next" => "наст.",
+"last" => "ост.",
+"orig" => "ориг.",
+"histlegend" => "Пояснення: (поточн.) = відмінності від поточної версії,
+(ост.) = відмінності від попередньої версії, M = незначне редагування",
+
+# Diffs
+#
+"difference" => "(відмінності між версіями)",
+"loadingrev" => "завантаження версії для розрізнення",
+"lineno" => "Рядок $1:",
+"editcurrent" => "Редагувати поточну версію поточної статті",
+
+# Search results
+#
+"searchresults" => "Результати пошуку",
+"searchresulttext" => "Для отримання детальнішої інформації про пошук в {{SITENAME}}, див. [[Project:Пошук|Пошук в {{SITENAME}}]].",
+"searchsubtitle" => "На запит \"[[:$1]]\"",
+"searchsubtitleinvalid" => "На запит \"$1\"",
+"badquery" => "Невірно зфомульований запит",
+"badquerytext" => "Неможливо обробити ваш запит.
+Можливо, причина в тому, що ви намагались знайти слово, яке коротше трьох букв, що поки-що не підтримується.
+Можливо також, що ви допустили опечатку в запиті.
+Попробуйте інший запит.",
+"matchtotals" => "Запиту \"$1\" відповідає(ють) $2 назва(и) статті(ей) й тексти $3 статті(ей).",
+"noexactmatch" => "Статті з такою назвою не існує, проводиться пошук по всьому тексту.",
+"titlematches" => "Збіг в назвах статей",
+"notitlematches" => "Немає збігу в назвах статей",
+"textmatches" => "Збіг в текстах статей",
+"notextmatches" => "Немає збігу в текстах статей",
+"prevn" => "попередня $1",
+"nextn" => "наступна $1",
+"viewprevnext" => "Переглянути ($1) ($2) ($3).",
+"showingresults" => "Нижче показано <b>$1</b> результатів, починаючи з #<b>$2</b>.",
+"showingresultsnum" => " Нижче показано <b>$3</b> результатів, починаючи з #<b>$2</b>.",
+"nonefound" => "<strong>Зауваження:</strong>: До невдалого пошуку часто може приводити спроба знайти загальні слова, які не підлягають індексації, наприклад - \"також\" and \"що\", або використання більш ніж одного ключового для пошуку слова (показуються тільки статті, що містять всі вказані для пошуку слова).",
+"powersearch" => "Пошук",
+"powersearchtext" => "
+Пошук в просторі імен :<br />
+$1<br />
+$2 Показувати перенаправлення Пошук на $3 $9",
+"searchdisabled" => "<p>Повнотекстовий пошук тимчасово недоступний через перевантаження сервера; передбачається, що ця функція буде знову включена після установки нового обладнання. Поки що ми пропонуємо вам скористатися пошуковою машиною google:</p>",
+"blanknamespace" => "(Основне)",
+
+# Preferences page
+#
+"preferences" => "Настройки",
+"prefsnologin" => "Ви не ввійшли в систему",
+"prefsnologintext" => "Ви повинні [[Спеціальні:Вхід_в_систему|ввійти в систему]]
+щоб змінити настройки користувача.",
+"prefsreset" => "Настройки були повернуті в стандартний стан.",
+"qbsettings" => "Настройки панелі навігації",
+"changepassword" => "Змінити пароль",
+"skin" => "Оформлення",
+"math" => "Відображення математики",
+"dateformat" => "Формат дати",
+"math_failure" => "Неможливо розібрати вираз",
+"math_unknown_error" => "невідома помилка",
+"math_unknown_function" => "невідома функція",
+"math_lexing_error" => "лексична помилка",
+"math_syntax_error" => "синтаксична помилка",
+"saveprefs" => "Зберегти настройки",
+"resetprefs" => "Встановити стандартні настройки",
+"oldpassword" => "Старий пароль",
+"newpassword" => "Новий пароль",
+"retypenew" => "Повторіть ввід нового пароля",
+"textboxsize" => "Розміри поля вводу",
+"rows" => "Рядків",
+"columns" => "Стовпчиків",
+"searchresultshead" => "Настройки для результатів пошуку",
+"resultsperpage" => "Кількість результатів на сторінку",
+"contextlines" => "Кількість рядків на результат",
+"contextchars" => "Кількість символів контексту на рядок",
+"stubthreshold" => "Поріг визначення заглушки",
+"recentchangescount" => "Кількість заголовків статей на сторінці нових редагувань",
+"savedprefs" => "Ваші настройки збережено.",
+"timezonetext" => "Введіть зміщення (в годинах) вашого місцевого часу
+від часу сервера (UTC - по Гринвічу).",
+"localtime" => "Місцевий час",
+"timezoneoffset" => "Зміщення",
+"servertime" => "Час сервера",
+"guesstimezone" => "Заповнити з браузера",
+"defaultns" => "По замовчанню, шукати в таких просторах імен:",
+
+# Recent changes
+#
+"changes" => "редагування",
+"recentchanges" => "Нові редагування",
+# This is the default text, and can be overriden by editing [[{{ns:project}}::Recentchanges]]
+"recentchangestext" => "На цій сторінці представлені останні редагування в {{SITENAME}}.",
+"rcnote" => "Нижче відображені останні <strong>$1</strong> редагувань за останні(й) <strong>$2</strong> день(і,ів).",
+"rcnotefrom" => "Нижче відображені редагування з <b>$2</b> (до <b>$1</b>).",
+"rclistfrom" => "Показати редагування починаючи з $1",
+# "rclinks" => "Show last $1 changes in last $2 hours / last $3 days",
+# "rclinks" => "Show last $1 changes in last $2 days.",
+"rclinks" => "Показати останні $1 редагування за останні(й) $2 день(і,ів); $3 незначних редагувань.",
+"diff" => "різн.",
+"hist" => "журнал",
+"hide" => "сховати",
+"show" => "показати",
+"minoreditletter" => "М",
+"newpageletter" => "Н",
+
+# Upload
+#
+"upload" => "Завантажити файл",
+"uploadbtn" => "Завантажити файл",
+"reupload" => "Завантажити повторно",
+"reuploaddesc" => "Повернутися до форми завантаження.",
+"uploadnologin" => "Ви не ввійшли в систему",
+"uploadnologintext" => "Ви повинні [[Спеціальні:Вхід_в_систему|ввійти в систему,]]
+щоб завантажувати файли.",
+"uploaderror" => "Помилка завантаження файлу",
+"uploadtext" => "'''СТІЙ!''' До того як почати завантажувати файли, переконайтесь, що ви прочитали й дієте відповідно
+[[Project:Правила_використання_зображеннь|правилам використання зображень {{SITENAME}}]].
+
+Якщо файл з вказаним вами іменем вже існує
+в {{SITENAME}}, то він буде замінений без попередження.
+Тому, якщо ви не збираєтесь обновляти файл,
+було б непогано перевірити, чи існує вже
+такий файл.
+
+Щоб переглянути раніше завантажені файли,
+зайдіть на: [[Спеціальні:Список зображень|список завантажених зображень]].
+Завантаження й вилучення відображаються в
+[[Project:Журнал завантажень|журналі завантажень]].
+
+Використовуйте відображену нижче форму завантаження нових файлів зображень, що ілюструють ваші статті.
+В більшості браузерів появиться кнопка \"Переглянути...\", натиснувши яку ви можете викликати стандартний діалог
+відкриття файлів операційної системи.
+Вибір фалу призводить до заповнення текстового поля після кнопки.
+Ви також повинні встановити галочку, що підтверджеє, що ви не порушуєте авторських прав завантажуючи цей файл.
+Нтисніть кнопку \"Завантажити\", щоб провести завантаження.
+Завагтаження може тривати деякий час, якщо у вас повільне інтернет-з'єднання.
+
+Перевагу бажано надавати наступним форматам; JPEG - для фотографій, PNG -
+для малюнків и невеликих зображень, OGG - для звуків та музики.
+Будь-ласка, щоб попередити виникнення путанини, називайте ваші файли відповідно до їх змісту.
+Для включення зображення в статтю, використовуйте ссилки такого вигляду:
+'''<nowiki>[[зображення:file.jpg]]</nowiki>''' або '''<nowiki>[[зображення:file.png|альтернативний текст]]</nowiki>'''
+або '''<nowiki>[[звук:file.ogg]]</nowiki>''' для звуків.
+
+Будь-ласка, зверніть увагу, що аналогічно текстам статей {{SITENAME}}, інші можуть редагувати чи вилучати завантажені вами файли, якщо вони вважають, що це покращить енциклопедію, а ви можете бути заблоковані, якщо ваші дії шкодять системі.",
+"uploadlog" => "журнал завантажень",
+"uploadlogpage" => "Журнал_завантажень",
+"uploadlogpagetext" => "Нижче представлено список найновіших завантажень файлів.
+Скрізь використовується час сервера (по Гринвічу, UTC).
+<ul>
+</ul>",
+"filename" => "Назва файлу",
+"filedesc" => "Опис файлу",
+"copyrightpage" => "{{ns:project}}:Авторське право",
+"copyrightpagename" => "Авторські права в {{SITENAME}}",
+"uploadedfiles" => "Завантажені файли",
+"minlength" => "Назва зображення повинна містити хоча б три символи.",
+"badfilename" => "Назва зображення було змінено на \"$1\".",
+"badfiletype" => "\".$1\" не є рекомендованим форматом для файлів зображень.",
+"largefile" => "Рекомендується використовувати файли зображень, розмір яких меньший 100 кілобайт.",
+"successfulupload" => "Завантаження успішно завершено",
+"fileuploaded" => "Файл \"$1\" успішно завантажено.
+Будь-ласка, перейдіть за наступним посиланням: ($2) до сторінки з описом і внесіть наступну інформацію про файл: джерело файлу, коли й ким він був створений, та іншу інформацію про цей файл.",
+"uploadwarning" => "Попередження",
+"savefile" => "Зберегти файл",
+"uploadedimage" => "завантажено \"[[$1]]\"",
+"uploaddisabled" => "Вибачте, можливість завантаження на даний сервер відключена.",
+
+# Image list
+#
+"imagelist" => "Список зображень",
+"imagelisttext" => "Нижче відображено список з $1 зображень, відсортованих $2.",
+"getimagelist" => "отримання списку зображень",
+"ilsubmit" => "Шукати",
+"showlast" => "Показати останні $1 зображень, відсортованих $2.",
+"byname" => "за назвою",
+"bydate" => "за датою",
+"bysize" => "за розміром",
+"imgdelete" => "вилуч.",
+"imgdesc" => "опис",
+"imglegend" => "Пояснення: (опис) = показати/змінити опис зображення.",
+"imghistory" => "Журнал зображення",
+"revertimg" => "відкот.",
+"deleteimg" => "вилуч.",
+"deleteimgcompletely" => "вилуч.",
+"imghistlegend" => "Пояснення: (поточ.) = це - поточне зображення, (вилуч.) = вилучити цю стару версію, (відкот.) = відкотитися до цієї старої версії.
+<br /><i>Виберіть дату, щоб переглянути список зображень, звантажених на цю дату</i>.",
+"imagelinks" => "Посилання зображення",
+"linkstoimage" => "Наступні статті посилаються на дане зображення:",
+"nolinkstoimage" => "Статті, що посилаються на дане зображення, відсутні.",
+
+# Statistics
+#
+"statistics" => "Статистика",
+"sitestats" => "Статистика сайту",
+"userstats" => "Статистика користувачів",
+"sitestatstext" => "Загалом в базі даних <b>$1</b> статей.
+Сюди входять сторінки \"обговорень\", статті про {{SITENAME}}, мінімальні статті-\"заглушки\", перенаправлення, та інші сторінки, які, можливо, не повинні розглядатися як статті.
+За виключенням них, є <b>$2</b> сторінок, які, швидше за все, повноцінні статті.<p>
+Всього зроблено <b>$3</b> переглядів та <b>$4</b> редагувань статей
+з моменту обновлення програмного забезпечення (20 липня 2002).
+Таким чином, в середньому на одну статтю припадає <b>$5</b> редагувань та <b>$6</b> переглядів на одне редагування.",
+"userstatstext" => "Зареєструвалося <b>$1</b> користувачів, з яких
+<b>$2</b> - адміністратори (див. $3).",
+
+# Maintenance Page
+#
+"disambiguations" => "Багатозначні статті",
+"disambiguationspage" => "{{SITENAME}}:Посилання_на_багатозначні_статті",
+"disambiguationstext" => "Наступна статті посилаються на <i>багатозначні статті</i>. Замість цього вони повинні вказувати на відповідну конкретну статтю.<br />Стаття вважається багатозначною, якщо на неї вказує $1.<br />Посилання з інших просторів імен тут <i>не</i> вказані.",
+"doubleredirects" => "Подвійні перенаправлення",
+"doubleredirectstext" => "<b>Увага:</b> Цей список може містити невірні елементи. Це значить, що після першої директиви #REDIRECT йде додатковий текст з посиланнями.<br />\nКожен рядок містить посилання на перше та друге перенаправлення, а також перший рядок тексту другого перенаправлення, що, звичайно, містить \"реальне\" перенаправленне на необхідну статтю, куди повинно вказувати й перше перенаправленне.",
+"brokenredirects" => "Розірвані перенаправлення",
+"brokenredirectstext" => "Наступні перенаправлення вказують на неіснуючі статті.",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "Статті-сироти",
+"unusedimages" => "Зображення, що не використовуються",
+"popularpages" => "Популярні статті",
+"nviews" => "$1 переглядів",
+"wantedpages" => "Необхідні статті",
+"nlinks" => "$1 посилань",
+"allpages" => "Всі статті",
+"randompage" => "Випадкова стаття",
+"shortpages" => "Короткі статті",
+"longpages" => "Довгі статті",
+"listusers" => "Список користувачів",
+"specialpages" => "Спеціальні сторінки",
+"spheading" => "Спеціальні сторінки",
+"recentchangeslinked" => "Пов'язані редагування",
+"rclsub" => "(на статті, посилання на які є на \"$1\")",
+"newpages" => "Нові статті",
+"ancientpages" => "Самі старі статті",
+"movethispage" => "Перемістити її",
+"unusedimagestext" => "<p>Будь-ласка, врахуйте, що інші веб-сайти (подібно інших мовних розділів {{SITENAME}}) можуть використовувати пряме посилання (URL) на це зображення, і тому зображення може активно використовуватися не дивлячись на його присутність в цьому списку.",
+"booksources" => "Джерела книг",
+"booksourcetext" => "Нижче наведено список посилань на інші веб-сайти, де продаються нові та такі, що були в користуванні книги, а також там може бути інформація про книги, які ви шукаєте.
+{{SITENAME}} ніяк не зв’язані з будь-якими з них, і цей список не може розглядатися як їх підтримка.",
+"alphaindexline" => "від $1 до $2",
+
+# Email this user
+#
+"mailnologin" => "Відсутня адреса для відправки",
+"mailnologintext" => "Ви повинні [[Спеціальні:Вхід_в_систему|ввійти в систему]]
+й мати адресу електронної пошти в ваших [[Спеціальні:Настройки|настройках]],
+щоб мати можливість відправляти електронну пошту іншим користувачам.",
+"emailuser" => "Відправити електронного листа цьому користувачу",
+"emailpage" => "Відправити електронного листа користувачу",
+"emailpagetext" => "Якщо цей користувач вказав справжню адресу електронної пошти в своїх настройках, то заповнивши наведену нижче форму, можна відправити йому повідомлення.
+Електронна адреса, яку ви вказали в своїх настройках, буде вказана в полі \"Від кого\" листа, тому отримувач буде мати можливість відповісти.",
+
+"noemailtitle" => "Відсутня адреса електронної пошти",
+"noemailtext" => "Цей користувач не вказав справжньої адреси електронної пошти, або вказав, що не бажає отримувати листи від інших користувачів.",
+"emailfrom" => "Від кого",
+"emailto" => "Кому",
+"emailsubject" => "Тема листа",
+"emailmessage" => "Повідомлення",
+"emailsend" => "Відіслати",
+"emailsent" => "Електронне повідомлення відіслано",
+"emailsenttext" => "Ваше електронне повідомлення відіслано.",
+
+# Watchlist
+#
+"watchlist" => "Ваш список спостереження",
+"nowatchlist" => "Ваш список спостереження пустий.",
+"watchnologin" => "Ви не ввійшли в систему",
+"watchnologintext" => "Ви повинні [[Спеціальні:Реєстрація|ввійти в систему]],
+щоб змінювати список спостереження.",
+"addedwatch" => "Добавлена в список спостереження",
+"addedwatchtext" => "Стаття \"$1\" добавлена в ваш <a href=\"" .
+ "{{localurle:Спеціальні:Список_спостереження}}\">список спостереження</a>.
+Наступні редагування цієї статті й пов'язані з нею дискусії будуть відображатися тут,
+а також будуть відображатися <b>жирним шрифтом</b> на сторінці з <a href=\"" .
+ "{{localurle:Спеціальні:Останні_редагування}}\">списком останніх редагувань</a>, щоб їх було
+легше помітити.</p>
+
+<p>Якщо пізніше ви захочете вилучити статтю з свого списку спостереження, виберіть \"Відмінити спостереження\" в списку інструментів.",
+"removedwatch" => "Вилучена з списку спостереження",
+"removedwatchtext" => "Стаття \"$1\" була вилучена з вашого списку спостереження.",
+"watchthispage" => "Спостерігати за нею",
+"unwatchthispage" => "Відмінити спостереження",
+"notanarticle" => "Не стаття",
+"watchnochange" => "За вказаний період в статтях з списку спостереження нічого не змінено.",
+"watchdetails" => "($1 статей, за якими ведеться спостереження, не враховуючи сторінок обговорення;
+$2 всього змінено статей після відсічки;
+$3...
+[$4 показати й відредагувати повний список].)",
+"watchmethod-recent" => "перегляд останніх редагувань статей за якими ведеться спостереження",
+"watchmethod-list" => "перегляд статей за якими ведеться спостереження",
+"removechecked" => "Вилучити вибрані елементи зі списку спостереження",
+"watchlistcontains" => "Ваш список спостереження містить $1 статей.",
+"watcheditlist" => "Нижче відображено алфавітний список статей за якими ви спостерігаєте.
+Відмітьте статті, які ви хочете вилучити з вашого
+списку спостереження й натисніть кнопку 'вилучити вибрані'
+внизу екрану.",
+"removingchecked" => "Вилучення вибраних елементів зі списку спостереження...",
+"couldntremove" => "Неможливо вилучити елемент '$1'...",
+"iteminvalidname" => "Проблема з елементом '$1', недопустиме назва...",
+"wlnote" => "Нище наведено останні $1 редагувань за останні <b>$2</b> годин.",
+
+
+# Delete/protect/revert
+#
+"deletepage" => "Вилучити статтю",
+"confirm" => "Підтвердження",
+"excontent" => "зміст: '$1'",
+"exbeforeblank" => "зміст до очистки: '$1'",
+"exblank" => "стаття була пуста",
+"confirmdelete" => "Підтвердити вилучення",
+"deletesub" => "(\"$1\" вилучається)",
+"historywarning" => "Попередження: Стаття, яку ви збираєтеся вилучити, має журнал редагувань:",
+"confirmdeletetext" => "Ви ось-ось назавжди вилучите статтю чи файл і всі її журнали редагувань з бази даних.
+Будь-ласка, підтвердіть, що ви бажаєте зробити це, що ви повністю розумієте наслідки й що ви робите це в відповідності з
+[[{{ns:project}}:Правила|правилами {{SITENAME}}]].",
+"actioncomplete" => "Дію виконано",
+"deletedtext" => "\"$1\" було вилучено.
+Див. $2 для перегляду списку останніх вилучень.",
+"deletedarticle" => "вилучено \"$1\"",
+"dellogpage" => "Список_вилучень",
+"dellogpagetext" => "Нижче наведено список самих свіжих вилучень.
+Всюди використовується час сервера (по Гринвічу, UTC).
+<ul>
+</ul>",
+"deletionlog" => "список вилучень",
+"reverted" => "Відновлено з старої версії",
+"deletecomment" => "Причина вилучення",
+"imagereverted" => "Повернення до молодшої версії проведено.",
+"rollback" => "Відкинути редагування",
+"rollbacklink" => "відкинути",
+"cantrollback" => "Неможливо відкинути редагування; останній хто редагував є єдиним автором цієї статті.",
+"rollbackfailed" => "Відкинути зміни не вдалося",
+"alreadyrolled" => "Неможливо відкинути останні редагування [[:$1]],
+зроблені [[User:$2|$2]] ([[User talk:$2|Talk]]); хтось інший вже змінив чи відкинув редагування цієї статті.
+Остані редагування зробив [[User:$3|$3]] ([[User talk:$3|Talk]]).",
+# only shown if there is an edit comment
+"editcomment" => "Редагування прокоментовано так: \"<i>$1</i>\".",
+"revertpage" => "Відкинуть всі редагування до зробленого $1",
+"protectlogpage" => "Журнал_захисту",
+"protectlogtext" => "Нижче наведено список установок й зняття захисту з сторінки.
+Додаткова інформація: [[{{ns:project}}:Захищена стаття]].",
+"protectedarticle" => "захист на [[$1]] встановлено",
+"unprotectedarticle" => "захист з [[$1]] знято",
+
+# Undelete
+"undelete" => "Відновити вилучену статтю",
+"undeletepage" => "Переглянути й відновити вилучені статті",
+"undeletepagetext" => "Наступні статті було вилучено, але вони ще в архіві і тому можуть бути відновлені. Архів періодично очищається.",
+"undeletearticle" => "Відновити вилучену статтю",
+"undeleterevisions" => "В архіві $1 версій",
+"undeletehistory" => "Якщо ви відновите статтю, всі версії будуть також відновлені, разом з журналом редагувань.
+Якщо з моменту вилучення було створено статтю з такою ж назвою, відновлені версії будуть вказані в журналі редагувань перед новими записами, але поточна версія існуючої статті не буде замінена автоматично.",
+"undeleterevision" => "Вилучена версія від $1",
+"undeletebtn" => "Відновити!",
+"undeletedarticle" => "\"$1\" відновлена",
+
+# Contributions
+#
+"contributions" => "Вклад користувача",
+"mycontris" => "Ваш вклад",
+"contribsub" => "Для $1",
+"nocontribs" => "Редагувань, що задовольняють заданим умовам не знайдено.",
+"ucnote" => "Нижче наводяться останні <b>$1</b> редагувань, зроблених цим користувачем за останні <b>$2</b> дні.",
+"uclinks" => "Переглянути $1 останніх редагувань; за останні $2 дні.",
+"uctop" => " (наверху)" ,
+
+# What links here
+#
+"whatlinkshere" => "Посилання на неї",
+"notargettitle" => "Не вказана ціль",
+"notargettext" => "Ви не вказали цільову статтю чи користувача, для яких необхідно виконати цю функцію.",
+"linklistsub" => "(Список посилань)",
+"linkshere" => "Ці статті вказують сюди:",
+"nolinkshere" => "Сюди не вказує жодна стаття.",
+"isredirect" => "сторінка-перенаправлення",
+
+# Block/unblock IP
+#
+"blockip" => "Заблокувати IP-адресу",
+"blockiptext" => "Використовуйте форму що нижче, щоб заблокувати можливість збереження з вказаної IP-адреси.
+Це може бути зроблене виключно для попередження вандалізму і тільки в відповідності до
+[[{{ns:project}}:Правила|правил {{SITENAME}}]].
+Нище вкажіть конкретную причину (наприклад, процитуйте деякі статті з ознаками вандалізму).",
+"ipaddress" => "IP-адреса/Імя користувача",
+"ipbreason" => "Причина",
+"ipbsubmit" => "Заблокувати доступ цьому користувачу",
+"badipaddress" => "Користувача з таким іменем не існує.",
+"blockipsuccesssub" => "Блокування проведено",
+"blockipsuccesstext" => "\"$1\" заблоковано.
+<br />См. [[Спеціальні:Список_заблокованих_IP|список заблокованих IP]] щоб взнати, які IP-адреси заблоковані.",
+"unblockip" => "Розблокувати IP-адресу",
+"unblockiptext" => "Використовуйте форму що нижче, щоб відновити можливість збереження раніше заблокованої
+IP-адреси.",
+"ipusubmit" => "Розблокувати цю адресу",
+"ipblocklist" => "Список заблокованих IP-адрес й користувачів",
+"blocklistline" => "$1, $2 заблоковано $3 ($4)",
+"blocklink" => "заблокувати",
+"unblocklink" => "розблокувати",
+"contribslink" => "вклад",
+"autoblocker" => "Доступ заблоковано автоматично, тому що ви використовуєте ту ж адресу, що і \"$1\". Причина: \"$2\".",
+
+# Developer tools
+#
+"lockdb" => "Заблокувати базу даних (режим \"тільки для читання\")",
+"unlockdb" => "Розблокувати базу даних",
+"lockdbtext" => "Блокування бази даних унеможливить редагування статей, настройок, списків спостереження та
+виконувати інші дії, що вимагають доступу до бази даних.
+Будь-ласка, підтвердіть, що це - саме те, що ви хочете зробити, і що ви відміните блокування коли закінчите обслуговування бази даних.",
+"unlockdbtext" => "Разблокування бази даних надасть можливість знову
+редагувати статті, настройки, списки спостереження та виконувати інші дії, що вимагають доступу до бази даних.
+Будь-ласка, підтвердіть, що це - саме те, що ви хочете зробити.",
+"lockconfirm" => "Так, я дійсно хочу заблокувати базу даних (перейти в режим ''тільки для читання'').",
+"unlockconfirm" => "Так, я дійсно хочу розблокувати базу даних.",
+"lockbtn" => "Заблокувати базу даних (режим ''тільки для читання'')",
+"unlockbtn" => "Розблокувати базу даних",
+"locknoconfirm" => "Ви не поставили галочку в поле підтвердження.",
+"lockdbsuccesssub" => "Базу даних заблоковано",
+"unlockdbsuccesssub" => "Базу даних розблоковано",
+"lockdbsuccesstext" => "Базу даних {{SITENAME}} заблоковано.
+<br />Не забудьте її розблокувати після завершення обслуговування.",
+"unlockdbsuccesstext" => "Базу даних {{SITENAME}} розблоковано.",
+
+# Move page
+#
+"movepage" => "Перемістити статтю",
+"movepagetext" => "За допомогою форми що нижче, ви можете перейменувати статтю, одночасно перемістивши на нове місце і журнал її редагувань.
+Стаття з старою назвою стане перенаправленням на нову статтю.
+Посилання на стару назву не будуть змінені; обов'язково
+[[Спеціальні:Обслуговування|перевірте]], що не з'явилося подвійних чи розірваних перенаправлень.
+Ви відповідаєте за те, щоб переконатися, що посилання далі вказують туди,
+куди припускалося.
+
+Зверніть увагу, що стаття '''не''' буде переміщена, якщо стаття
+з новою назвою вже існує, якщо тільки вона не пуста і не є
+перенаправленням, а журнал її редагувань порожній. Це означає, що ви
+можете повернути статті стару назву, якщо ви перейменували її
+помилково, але ви не можете затерти існуючу статтю.
+
+<b>ПОПЕРЕДЖЕННЯ!</b>
+
+Дана дія може стати причиною серйозних та неочікуваних змін популярних статей;
+будь-ласка, перед продовженням переконайтесь, що ви впевнені й розумієте можливі наслідки.",
+"movepagetalktext" => "Приєднана сторінка обговорення, якщо така існує,
+також буде автоматично переміщена, '''крім наступних випадків:'''
+*Ви переміщаєте статтю з одного простору імен в інший,
+*Непуста сторінка обговорення з таким іменем вже існує, або
+*Ви не поставили галочку в полі, що нижче.
+
+В цих випадках, ви будете вимушені перемістити чи об'єднати статті вручну,
+якщо це потрібно.",
+"movearticle" => "Перемістити статтю",
+"movenologin" => "Ви не ввійшли в систему",
+"movenologintext" => "Ви повинні ввійти в систему [[Спеціальні:Вхід_в_систему]]
+щоб перемістити статтю.",
+"newtitle" => "Нова назва",
+"movepagebtn" => "Перемістити статтю",
+"pagemovedsub" => "Переміщення виконано",
+"pagemovedtext" => "Назва статті \"[[$1]]\" змінено на \"[[$2]]\".",
+"articleexists" => "Сторінка з такою назвою вже існує, або
+вибрана вами назва недопустима.
+Будь-ласка, виберіть іншу назву.",
+"talkexists" => "Стаття була перейменована, але сторінка обговорення
+не може бути переміщена, бо сторінка з такаю назвою вже
+існує. Будь-ласка, об'єднайте їх вручну.",
+"movedto" => "тепер називається",
+"movetalk" => "Перемістити також і сторінку обговорення , якщо це можливо.",
+"talkpagemoved" => "Відповідна сторінка обговорення також переміщена.",
+"talkpagenotmoved" => "Відповідна сторінка обговорення <strong>не</strong> переміщена.",
+
+# Math
+
+'mw_math_png' => "Завжди генерувати PNG",
+'mw_math_simple' => "HTML в простих випадках, інакше PNG",
+'mw_math_html' => "HTML якщо можливо, інакше PNG",
+'mw_math_source' => "Залишити в вигляді ТеХ (для текстових браузерів)",
+'mw_math_modern' => "Рекомендовано для сучасних браузерів",
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesUr.php b/languages/messages/MessagesUr.php
new file mode 100644
index 000000000000..d53543ded76d
--- /dev/null
+++ b/languages/messages/MessagesUr.php
@@ -0,0 +1,33 @@
+<?php
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+ # Underlines seriously harm legibility. Force off:
+ 'underline' => 0,
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'زریعہ',
+ NS_SPECIAL => 'خاص',
+ NS_MAIN => '',
+ NS_TALK => 'تبادلۂ_خیال',
+ NS_USER => 'صارف',
+ NS_USER_TALK => 'تبادلۂ_خیال_صارف',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'تبادلۂ_خیال_$1',
+ NS_IMAGE => 'تصویر',
+ NS_IMAGE_TALK => 'تبادلۂ_خیال_تصویر',
+ NS_MEDIAWIKI => 'میڈیاوکی',
+ NS_MEDIAWIKI_TALK => 'تبادلۂ_خیال_میڈیاوکی',
+ NS_TEMPLATE => 'سانچہ',
+ NS_TEMPLATE_TALK => 'تبادلۂ_خیال_سانچہ',
+ NS_HELP => 'معاونت',
+ NS_HELP_TALK => 'تبادلۂ_خیال_معاونت',
+ NS_CATEGORY => 'زمرہ',
+ NS_CATEGORY_TALK => 'تبادلۂ_خیال_زمرہ',
+);
+
+
+?>
diff --git a/languages/messages/MessagesUz.php b/languages/messages/MessagesUz.php
new file mode 100644
index 000000000000..c3b3aacb4cd7
--- /dev/null
+++ b/languages/messages/MessagesUz.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Uzbek (Oʻzbek)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$linkTrail = '/^([a-zʻʼ]+)(.*)$/sDu';
+
+?>
diff --git a/languages/messages/MessagesVec.php b/languages/messages/MessagesVec.php
new file mode 100644
index 000000000000..ddc2da784963
--- /dev/null
+++ b/languages/messages/MessagesVec.php
@@ -0,0 +1,1175 @@
+<?php
+/** Venitian ( Vèneto )
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$fallback = 'it';
+
+$quickbarSettings = array(
+ 'Nessun', 'Fisso a sinistra', 'Fisso a destra', 'Fluttuante a sinistra'
+);
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Speciale',
+ NS_MAIN => '',
+ NS_TALK => 'Discussion',
+ NS_USER => 'Utente',
+ NS_USER_TALK => 'Discussion_utente',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discussion_$1',
+ NS_IMAGE => 'Imagine',
+ NS_IMAGE_TALK => 'Discussion_imagine',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discussion_MediaWiki',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Discussion_template',
+ NS_HELP => 'Aiuto',
+ NS_HELP_TALK => 'Discussion_aiuto',
+ NS_CATEGORY => 'Categoria',
+ NS_CATEGORY_TALK => 'Discussion_categoria'
+);
+
+$messages = array(
+'tog-underline' => 'Sottolinea links',
+'tog-highlightbroken' => 'Evidenzsia i links che i punta a <br />arthicołi ancora da scrivere',
+'tog-justify' => 'Paragrafo: giustificato',
+'tog-hideminor' => 'Nascondi le modifiche minori<br />nella pagina "Modifiche recenti"',
+'tog-numberheadings' => 'Auto-numerazione dei<br />titoli di paragrafo',
+'tog-editondblclick' => 'Doppio click per modificare l\'articolo<br />(richiede JavaScript)',
+'tog-editsection' => 'Modifega de łe sezsioni tramite el cołegamento [modifica]',
+'tog-editsectiononrightclick'=> 'Modifega de łe sezsion tramite clic destro sul titoło (richiede JavaScript)',
+'tog-showtoc' => 'Mostra l\'indexe par łe paxène con pì de 3 sezsion',
+'tog-rememberpassword' => 'Ricorda la password<br />(non limitare a una sessione<br />- richiede uso di cookies)',
+'tog-editwidth' => 'Casella di edizione ampliata<br />alla massima larghezza',
+'tog-watchcreations' => 'Xonta łe paxène creae a i osservati speciałi',
+'tog-watchdefault' => 'Xonta łe paxène modifegae a i osservati speciałi',
+'tog-minordefault' => 'Indica ogni modifica come minore<br />(solo come predefinito)',
+'tog-watchlisthideown' => 'Scondi łe me modifeghe ne i osservati speciałi',
+'tog-watchlisthidebots' => 'Scondi le modifighe de i bot ne i oservati speciałi',
+'skinpreview' => 'Anteprima',
+'sunday' => 'Domenica',
+'monday' => 'Luni',
+'tuesday' => 'Marti',
+'wednesday' => 'Mèrcoli',
+'thursday' => 'Xòbia',
+'friday' => 'Vènerdi',
+'saturday' => 'Sabo',
+'january' => 'genaro',
+'february' => 'Febraro',
+'march' => 'Marzso',
+'april' => 'Apriłe',
+'may_long' => 'Majo',
+'july' => 'lujo',
+'august' => 'Agosto',
+'september' => 'Setenbre',
+'october' => 'Otobre',
+'november' => 'Novenbre',
+'december' => 'Diçenbre',
+'jan' => 'Gen',
+'feb' => 'Feb',
+'mar' => 'Mar',
+'apr' => 'Apr',
+'may' => 'Mag',
+'jul' => 'Lug',
+'aug' => 'Ago',
+'sep' => 'Set',
+'oct' => 'Oto',
+'nov' => 'Nov',
+'dec' => 'Diç',
+'categories' => 'Categorie',
+'pagecategories' => '{{PLURAL:$1|Categoria|Categorie}}',
+'category_header' => 'Voçi n\'te ła categoria "$1"',
+'mainpage' => 'Paxèna prinzsipałe',
+'mainpagetext' => '\'\'\'MediaWiki xè stà instałà con sucesso.\'\'\'',
+'mainpagedocfooter' => 'Consult the [http://meta.wikimedia.org/wiki/Help:Contents User\'s Guide] for information on using the wiki software.
+
+== Getting started ==
+
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]',
+'portal-url' => 'Project:Portałe Comunità',
+'about' => 'Se parla de',
+'aboutsite' => 'Se parla de {{SITENAME}}',
+'aboutpage' => 'Project:Se parla de',
+'article' => 'Voçe',
+'help' => 'Ciacołe',
+'helppage' => 'Help:Ciacołe',
+'bugreports' => 'Malfunzsionamenti',
+'bugreportspage' => 'Project:Malfunzsionamenti',
+'sitesupport' => 'Donazsion',
+'sitesupport-url' => 'Project:Donasioni',
+'newwindow' => '(se verde in una nova finestra)',
+'edithelppage' => 'Help:Come scrivere un articolo',
+'cancel' => 'Anuła',
+'qbedit' => 'Modifega',
+'qbpageoptions' => 'Opzsion paxèna',
+'qbpageinfo' => 'Informazsion su ła paxèna',
+'qbmyoptions' => 'Le me opzsion',
+'qbspecialpages' => 'Paxène speciałi',
+'moredotdotdot' => 'More...',
+'mypage' => 'La me paxèna',
+'mytalk' => 'le me discussión',
+'anontalk' => 'Discussion par sto IP',
+'navigation' => 'Navigazsión',
+'currentevents' => 'Atuałità',
+'currentevents-url' => 'Atuałità',
+'errorpagetitle' => 'Erór',
+'search' => 'Serca',
+'searchbutton' => 'Serca',
+'history' => 'Versión precedenti',
+'history_short' => 'Cronołogia',
+'info_short' => 'Informazsion',
+'printableversion' => 'Version de stampa',
+'edit' => 'Modifega',
+'editthispage' => 'Modifica voçe',
+'delete' => 'Scanceła',
+'deletethispage' => 'Scanceła paxèna',
+'protect' => 'Proteggi',
+'protectthispage' => 'Protegi sta paxèna',
+'unprotect' => 'sbloca',
+'unprotectthispage' => 'Cava protezsion',
+'newpage' => 'Nova paxèna',
+'talkpage' => 'Discussion',
+'specialpage' => 'Paxèna Speciałe',
+'articlepage' => 'Varda voçe',
+'talk' => 'Discussion',
+'userpage' => 'Varda paxèna Utente',
+'projectpage' => 'Varda ła paxèna de servizsio',
+'imagepage' => 'Paxèna imagine',
+'viewtalkpage' => 'Varda ła paxèna de discussion',
+'otherlanguages' => 'Altre łengoe',
+'redirectedfrom' => '(Reindirizzamento da $1)',
+'autoredircomment' => 'Redirect a ła paxèna [[$1]]',
+'redirectpagesub' => 'Paxèna de redirect',
+'lastmodifiedat' => 'Ultima modifica $2, $1.',
+'viewcount' => 'Sta paxèna xè stà leta {{PLURAL:$1|na volta|$1 volte}}.',
+'copyright' => 'Contenuto disponibile sotto $1.',
+'protectedpage' => 'Paxèna proteta',
+'jumptonavigation' => 'Navigazsion',
+'jumptosearch' => 'zserca',
+'badaccess' => 'Eròr ne i permessi',
+'versionrequired' => 'Verzsion $1 de MediaWiki richiesta',
+'versionrequiredtext' => 'Par usare sta paxèna xè necessario dispore de ła verzsion $1 del software MediaWiki. Varda [[Special:Version]]',
+'youhavenewmessages' => 'Te ghè $1 ($2).',
+'newmessageslink' => 'Novi messaj',
+'newmessagesdifflink' => 'diff to penultimate revision',
+'editsectionhint' => 'Modifica sezsión: $1',
+'hidetoc' => 'scondi',
+'viewdeleted' => 'Vedito $1?',
+'restorelink' => '$1 edit scancełai',
+'feed-invalid' => 'Modałità de sotoscrizsion de el feed non vałida.',
+'nstab-main' => 'Voçe',
+'nstab-media' => 'Media page',
+'nstab-image' => 'Imagine',
+'nosuchaction' => 'Operazsion non riconoszua',
+'nosuchactiontext' => 'L\'operazione richiesta con la URL immessa non è stata riconosciuta dal software MediaWiki',
+'nosuchspecialpage' => 'Non xè disponibiłe nesuna paxèna speciałe con sto nome',
+'nospecialpagetext' => 'Hai richiesto una pagina speciale che non è stata riconosciuta dal software MediaWiki, o che non è disponibile.',
+'error' => 'Erór',
+'dberrortext' => 'Errore de sintassi ne la richiesta inoltrà al database.
+L\'ultima richiesta inoltrà al database l\'è stà:
+<blockquote><tt>$1</tt></blockquote>
+da la funzsion "<tt>$2</tt>".
+MySQL gà restituio un errore "<tt>$3: $4</tt>".',
+'dberrortextcl' => 'Se gà verificà un errore de sintassi ne la richiesta al database.
+L\'ultuma richiesta al database l\'è stà:
+"$1"
+da la funzsion "$2".
+MySQL gà restituio l\'errore "$3: $4".',
+'noconnect' => 'Connessione al database fallita su $1',
+'nodb' => 'Selezione del database $1 fallita',
+'cachederror' => 'La seguente xè na copia de riserva de la pagina richiesta, e podarìa non essere aggiornà.',
+'laggedslavemode' => 'Atenzsion: la paxèna podaria non contegnere gli ultimi aggiornamenti.',
+'readonly' => 'Accesso al database temporaneamente disabilitato',
+'enterlockreason' => 'Fornisi na spiegazsion sui motivi del blocco, includendo le probabili data ed ora de riattivazsion o de rimozsion del blocco.',
+'readonlytext' => 'Il database di {{SITENAME}} è al momento bloccato, e non consente nuove immissioni né modifiche, molto probabilmente per manutenzione server, nel qual caso il database sarà presto di nuovo completamente accessibile.<br />
+L\'amministratore di sistema che ha imposto il blocco, ha lasciato questa nota:
+<p>:$1</p>',
+'missingarticle' => 'Il database non ha trovato il testo di una pagina, che invece avrebbe dovuto trovare, intitolata "$1".<br />
+Questo non è un errore del database, ma più probabilmente un problema del software.<br />
+Per favore, segnalate l\'accaduto ad un amministratore di sistema, segnalando la URL e l\'ora dell\'incidente.',
+'internalerror' => 'Eròr interno',
+'filecopyerror' => 'Non xè stà possibiłe copiare el file "$1" come "$2".',
+'filerenameerror' => 'Non xè stà possibile rinominare el file "$1" in "$2".',
+'filedeleteerror' => 'Non xè stà possibiłe scancełare el file "$1".',
+'filenotfound' => 'Non xè stà possibile trovare el file "$1".',
+'formerror' => 'Erór: el modulo non xè stà invià correttamente',
+'badarticleerror' => 'Stà operazsión non xè consentia su stà paxèna.',
+'cannotdelete' => 'Non xè mia possibiłe scancełare la paxèna o l\'imagine richiesta.',
+'badtitle' => 'El titoło non xè mia coreto',
+'badtitletext' => 'La paxèna richiesta non xè disponibiłe, ła podaria essare non vałida, voda, o podaria trattarzse de un erór in un cołegamento interlinguistico o fra diverzse verzsion de {{SITENAME}}.',
+'perfdisabled' => 'Siamo davvero rammaricati, ma questa funzionalità è temporaneamente disabilitata durante le ore di maggiore accesso al database, per ragioni di accessibilità al resto del sito!<br />Torna fra le 02:00 e le 14:00 UTC e riprova.<br /><br />Grazie.',
+'perfcached' => 'Sta quà xè na copia \'\'cache\'\' e quindi non podaria essere completamente agiornà:',
+'wrong_wfQuery_params' => 'Parametri errai par wfQuery()<br />
+Funzsion: $1<br />
+Query: $2',
+'viewsource' => 'Varda ła fonte',
+'protectedinterface' => 'Sta paxèna contegne un elemento che fa parte de l\'interfaccia utente del software; è quindi xè proteta par evitare possibiłi abusi.',
+'editinginterface' => '\'\'\'Atenzsion:\'\'\' El testo de sta paxèna fa parte de l\'interfaccia utente del sito. Tute łe modifiche apportae a sta paxèna łe se riflette su i messaj vixuałixai par tuti i utenti.',
+'logouttitle' => 'Logout Utente',
+'logouttext' => 'Logout effettuato.
+Ora puoi continuare ad usare {{SITENAME}} come utente anonimo (ma il tuo indirizzo IP resterà riconoscibile), oppure puoi nuovamente richiedere il login con il precedente username, oppure come uno diverso.',
+'welcomecreation' => '<h2>Benvegnù, $1!</h2><p>El to account l\'è stà creà con sucesso.<br />
+Grasie par aver scelto de far cresere {{SITENAME}} co\'l to aiuto.<br />
+Par rendere {{SITENAME}} più tua, e par usarla più scorrevolmente, non dimenticare de personalixare le to preferense.',
+'loginpagetitle' => 'Login',
+'yourname' => 'El to nome utente (solo la prima en maiuscolo)',
+'yourpassword' => 'Scegli na password',
+'yourpasswordagain' => 'Scrivi la password de novo',
+'remembermypassword' => 'Ricorda la mia password per più sessioni (richiede uso dei cookies).',
+'externaldberror' => 'Si gà verificà un erór con el server de autenticazsion esterno, oppure non se dispone de łe autorixazsion necessarie par aggiornar el proprio açesso esterno.',
+'loginproblem' => '<b>Si gà verificà un errore durante el to tentativo de login.</b><br />Riproa, te sarè più fortunà!',
+'alreadyloggedin' => '<strong>Ehi, Utente $1, te ghe xà fato el login, te si xà conesso al nostro server!</strong><br />',
+'loginprompt' => 'Par acedere a {{SITENAME}} xè necessario abiłitare i cookie.',
+'logout' => 'Và fora',
+'userlogout' => 'và fora',
+'nologin' => 'Non gheto gnancora n\'acezso? $1.',
+'nologinlink' => 'Crealo ora',
+'createaccount' => 'Crea un novo accesso',
+'gotaccount' => 'Gheto xà un to account? $1.',
+'createaccountmail' => 'via email',
+'badretype' => 'Le password che te ghè immesso non le coincide, le xè diverse fra lore.',
+'userexists' => 'Siamo spiacenti.<br />Lo user name che hai scelto è già usato da un altro Utente.<br />Ti preghiamo perciò di voler scegliere uno user name diverso.',
+'youremail' => 'La to e-mail',
+'yourrealname' => 'El to vero nome*',
+'yourlanguage' => 'Linguaggio del l\'interfaccia',
+'yourvariant' => 'Variante de linguaggio',
+'yournick' => 'El to soranome (par łe firme)',
+'badsig' => 'Erór ne ła firma non standard, verifica i tag HTML.',
+'email' => 'E-mail',
+'loginerror' => 'Errore de Login',
+'noname' => 'Lo user name indicato non è valido, non è possibile creare un account a questo nome.',
+'loginsuccesstitle' => 'Login effettuato con successo!',
+'loginsuccess' => '\'\'\'El cołegamento al server de {{SITENAME}} con el nome utente "$1" xè ativo.\'\'\'',
+'nosuchuser' => 'Attenzione<br /><br />a seguito di verifica, non ci risulta alcun Utente con il nome di "$1".<br /><br />
+Controlla per favore il nome digitato, oppure usa il modulo qui sotto per creare un nuovo user account.',
+'nosuchusershort' => 'Non xè registrà nessun utente de nome "$1". Verifica el nome inserio.',
+'wrongpassword' => 'La password che te ghe messo non l\'è mia giusta.<br /><br />Riprova, per favore.',
+'wrongpasswordempty' => 'La password inseria xè voda. Riproa.',
+'mailmypassword' => 'Spediscimi una nuova password in posta elettronica',
+'passwordremindertext' => 'Qualcuno (probabilmente ti, con indirizso IP $1) gà richiesto l\'invio de na nova password de acezso a {{SITENAME}} ($4).
+La password par l\'utente "$2" xè stà impostà a "$3".
+Xè opportuno eseguire n\'acezso quanto prima e cambiare ła password immediatamente.',
+'noemail' => 'Nessuna casella e-mail risulta registrata per l\'Utente "$1".',
+'passwordsent' => 'Una nuova password è stata inviata alla casella e-mail registrata per l\'Utente "$1".
+Per favore, fai subito un log in non appena la ricevi.',
+'eauthentsent' => 'Una email de conferma xè stà invià a l\'indirizzo che te ghè indicà. Prima che qualunque altra mail te vengna invià, te devi seguire le istruzsioni contegnue ne la mail ricevuta, par confermar che quell\'indirizzo xè veramente el tuo.',
+'mailerror' => 'Ghe xè stà un eror nel mandare l\'email: $1',
+'acct_creation_throttle_hit'=> 'Me despiase, te ghe xà creà $1 account. Non te pol crearghine ancora.',
+'emailauthenticated' => 'El to indiriszo de e-mail l\'è stado autenticado su $1.',
+'emailnotauthenticated' => 'El to indirizso email non xè ancora stà autenticà. Nessuna email la verrà invià tramite le funzsioni che seguono.',
+'emailconfirmlink' => 'Conferma el to indiriszo de e-mail',
+'invalidemailaddress' => 'L\'indiriszo email no\'l pode essere accettà parché el gà un formato non valido. Per favore inserisci un indirizso valido o svoda la caseła.',
+'accountcreated' => 'Acesso creà',
+'accountcreatedtext' => 'Xè stà creà un acesso par l\'utente $1.',
+'bold_sample' => 'Grasseto',
+'bold_tip' => 'Grasseto',
+'link_sample' => 'Nome del link',
+'link_tip' => 'Link interno',
+'extlink_sample' => 'http://www.titolochevuoitu.com titolo del link',
+'extlink_tip' => 'Link esterno (ricordate el prefisso http:// )',
+'headline_sample' => 'Intestazsión',
+'headline_tip' => 'Sottointestazsión',
+'math_sample' => 'Insert formula here',
+'math_tip' => 'Mathematical formula (LaTeX)',
+'image_tip' => 'Imagine',
+'media_sample' => 'Example.ogg',
+'media_tip' => 'Media file link',
+'minoredit' => 'Sta quà l\'è na modifica minore',
+'watchthis' => 'Tegni d\'ocio sta voçe',
+'showpreview' => 'Mostra anteprima',
+'showlivepreview' => 'Live preview',
+'anoneditwarning' => '\'\'\'Atenzsion:\'\'\' Acesso non effettuà. Ne ła cronołogia de ła paxèna verà redjstrà l\'indirizso IP.',
+'missingsummary' => '\'\'\'Reminder:\'\'\' You have not provided an edit summary. If you click Save again, your edit will be saved without one.',
+'missingcommenttext' => 'Please enter a comment below.',
+'blockedtitle' => 'Stò nome utente corrisponde purtroppo a n\'Utente che xè stà disabilità a ła modifica de łe voçi.',
+'blockedtext' => 'Sto nome utente o indirizso IP i xè stà blocai da $1.
+La motivazsion del bloco xè ła seguente:<br />:\'\'$2\'\'<br />Se te lo desideri, te podi contatare $1 o un altro [[Project:administrators|aministrador]] par discutere de el blocco.
+
+Si noti che ła funzsion \'Scrivi a l\'utente\' non xè attiva se non xè stà registrà un indiriszo e-mail vałido ne łe proprie [[Special:Preferences|preferenzse]].
+
+Specificare l\'indirizso IP coinvolto ($3) in qualsiasi richiesta de chiarimenti.',
+'blockedoriginalsource' => 'El codezse sorjente de \'\'\'$1\'\'\' el vegne mostrà de seguito:',
+'blockededitsource' => 'Łe \'\'\'modifeghe\'\'\' apportae a \'\'\'$1\'\'\' łe vegne mostrae de seguito:',
+'whitelistedittitle' => 'Occorre esser registrai par poder modificar la paxèna.',
+'whitelistedittext' => 'Par modificare łe paxène ghe xè bisogno $1.',
+'whitelistreadtitle' => 'Bisogna essere registrai par lexere ła paxèna',
+'whitelistreadtext' => 'Xe necessario effettuar el [[Special:Userlogin|login]] par lexere i articoli.',
+'whitelistacctitle' => 'Non te ghè el permesso de creare un account',
+'whitelistacctext' => 'To be allowed to create accounts in this Wiki you have to [[Special:Userlogin|log]] in and have the appropriate permissions.',
+'confirmedittitle' => 'Ghe vole ła conferma e-mail par scrivare',
+'confirmedittext' => 'Te devi confermar l\'indirizso e-mail prime de editare le paxène. Par piaxèr sistema e valida el to indirizso e--mail usando [[Special:Preferences|user preferences]].',
+'loginreqtitle' => 'Login Required',
+'loginreqlink' => 'login',
+'loginreqpagetext' => 'You must $1 to view other pages.',
+'accmailtitle' => 'Password spedia.',
+'accmailtext' => 'La password par \'$1\' l\'è sta spedia a $2.',
+'newarticle' => '(Novo)',
+'newarticletext' => 'El cołegamento appena seguio corisponde a na paxèna non ancora esistente.
+Se te desideri creare ła paxèna ora, basta comiçciare a scrivere el testo ne ła caseła qui sotto
+(fare riferimento a łe [[Project:Aiuto|paxène de aiuto]] par majori informazsion).
+Se el cołegamento xè stà seguio par eror, xè suficiente far clic sul botòn \'\'\'Indrio\'\'\' del proprio browser.',
+'anontalkpagetext' => '----
+
+
+
+
+
+---- \'\'Sta quà l\'è la paxèna de discussion de un utente anonimo che non\'l se ga ancora registrà o che non effettua el login. De conseguenzsa xè necessario identificarlo tramite l\'[[Indirizzo IP|indirizzo IP]] numerico. Tale indirizso el pode esser condivixo da diversi utenti. Se te sì un utente anonimo e te pensi che ghe sia sta commenti irrilevanti, te podi [[Special:Userlogin|registrarte o effettuare el login]] par evitare confuxion con altri utenti in futuro.\'\'',
+'noarticletext' => 'In sto momento ła paxèna richiesta xè voda. Xè possibiłe [Special:Search/{{PAGENAME}}|çercar sto titoło]] ne łe altre paxène del sito oppure [{{fullurl:{{FULLPAGENAME}}|action=edit}} modificar ła paxèna \'desso].',
+'clearyourcache' => '\'\'\'Nota:\'\'\' dopo aver salvà, te devi pulire la cache del to browser par veder i cambiamenti: \'\'\'Mozilla:\'\'\' clicca su \'\'reload\'\' (oppure \'\'ctrl-r\'\'), \'\'\'IE / Opera:\'\'\' \'\'ctrl-f5\'\', \'\'\'Safari:\'\'\' \'\'cmd-r\'\', \'\'\'Konqueror\'\'\' \'\'ctrl-r\'\'.',
+'previewnote' => 'Tegni presente che sta qua xè solo n\'anteprima, e che la to verzsion NON xè stà ancora salvà!',
+'session_fail_preview' => '<strong>Purtroppo non xè stà possibiłe salvare le to modifiche parché i dati de la sezsion i xè andai persi. Per favore, riproa.<br />
+Se te rizsevi sto messajo de erór pì olte, proa a scołegarte (struca su "và fora" in alto a destra) e a cołegarte novamente.</strong>',
+'previewconflict' => 'Questa anteprima rappresenta il testo nella casella di edizione di sopra, l\'articolo apparirà in questa forma se sceglierai di salvare la pagina ora.',
+'importing' => 'Importing $1',
+'editingsection' => 'Modifica $1 (sezsion)',
+'editingcomment' => 'Modifica $1 (commento)',
+'editconflict' => 'Conflitto de edizsion: $1',
+'explainconflict' => 'Qualcun altro ga salvà na so verszion de ła voçe nel tempo in cui te stavi preparando ła to verszion.<br /> La caselła de modifica de sora contegne el testo de la voçe ne ła so forma attuałe (el testo attualmente online). Le to modifiche łe xè inveçe contegnue ne ła caseła de modifica inferiore. Te dovarè inserire, se te vołi, le to modifiche nel testo esistente, e perciò scrivarle ne ła caseła de sora. <b>Soltanto</b> el testo ne ła caseła de sora sarà salvà se te struchi el botón "Salva".<br />',
+'yourtext' => 'El to testo',
+'storedversion' => 'Versione in archivio',
+'editingold' => '<strong>Attenzsion: Te stè modificando na verzsion de ła voçe non aggiornà. Se te la salvi così, tuti i cambiamenti apportai dopo sta verzsion i verrà persi.</strong>',
+'yourdiff' => 'Differense',
+'copyrightwarning2' => 'Ocio che tuti i contributi a {{SITENAME}} i pode essere editai, alterai, o rimossi da altri contributori.
+Se non te voli che i to scriti vengna modificà senzsa pietà, alora non inserirli qua.<br />
+Sapi che te stè promettendo che te stè inserendo un testo scrito de to pugno, o copià da na fonte de pubblico dominio o similarmente libera (vedi $1 par i dettagli).
+<strong>NON INSERIRE OPERE PROTETTE DA COPYRIGHT SENZSA PERMESSO!</strong>',
+'longpagewarning' => '<strong>ATENZSION: Sta paxèna xè longa $1 kilobyte; alcuni browser podaria prexentar dei problemi ne ła modifega de paxèna che se aviçina o supera i 32 KB. Valuta l\'opportunità de sudividere ła paxèna in sezsion pì piccołe.</strong>',
+'longpageerror' => '<strong>ERROR: The text you have submitted is $1 kilobytes
+long, which is longer than the maximum of $2 kilobytes. It cannot be saved.</strong>',
+'protectedpagewarning' => '<strong>ATENZSION: Sta paxèna xè sta protetta e soło i aministradori i pode modificarla. Varda, par essere sicuro ła [[Project:Guida a le paxène protette|Guida a le paxène protette]].</strong>',
+'semiprotectedpagewarning'=> '\'\'\'Nota:\'\'\' Sta paxèna xè stà blocà in modo che solo i utenti registrai i poda modefegarla.',
+'revhistory' => 'Cronołogia de łe verzsion de sta paxèna.',
+'nohistory' => 'Cronołogia de łe verzsion de sta paxèna non xè reperibiłe.',
+'revnotfound' => 'Verzsion non trovà',
+'revnotfoundtext' => 'La verzsion richiesta de ła paxèna non xè stà trovà.
+Verifica ła URL usà par açedere a sta paxèna.',
+'loadhist' => 'Caricamento cronologia de sta paxèna',
+'currentrev' => 'Verzsion atuałe',
+'revisionasof' => 'Revixion $1',
+'previousrevision' => '← Verzsion manco reçente',
+'nextrevision' => 'Verzsion pì reçente →',
+'currentrevisionlink' => 'Varda ła verzsion atuałe',
+'histlegend' => 'Legenda: (corr) = differenzse con la versión corrente,
+(prec) = differenzse con la versión precedente, m = modifica minore',
+'deletedrev' => '[scancełà]',
+'rev-delundel' => 'mostra/scondi',
+'history-feed-title' => 'Cronołogia',
+'history-feed-description'=> 'Cronołogia de ła paxèna su sto sito',
+'history-feed-empty' => 'La paxèna richiesta non esiste; podaria essere stà scancełà dal sito o rinominà. Verifica con la [[Special:Search|paxèna de ricerca]] se ghe xè nove paxène.',
+'revisiondelete' => 'Scanceła o ripristina verzsion',
+'revdelete-selected' => 'Verzsion selezsionae de [[:$1]]:',
+'revdelete-hide-text' => 'Scondi el testo de ła verzsion',
+'revdelete-hide-comment'=> 'Scondi l\'oggetto de ła modifega',
+'revdelete-hide-user' => 'Scondi el nome o l\'indirizso IP dell\'autore',
+'revdelete-submit' => 'Applica a ła revixion selezsionà',
+'difference' => '(Diferenzse fra łe verzsion)',
+'loadingrev' => 'caricamento revixion par differenzse',
+'editcurrent' => 'Modifica la verzsion corente de stà paxèna',
+'selectnewerversionfordiff'=> 'Selezsiona na verzsion pì reçente par el confronto',
+'selectolderversionfordiff'=> 'Selezsiona na verzsion manco reçente par el confronto',
+'compareselectedversions'=> 'Confronta łe verzsión selezsionà',
+'searchresults' => 'Risultato della ricerca',
+'searchresulttext' => 'Per maggiori informazioni sulla ricerca interna di {{SITENAME}}, vedi [[Project:Ricerca|Ricerca in {{SITENAME}}]].',
+'badquery' => 'Richiesta non xè posta bén',
+'badquerytext' => 'La to richiesta non ła pode esser processà. Questo podria dipendare da l\'aver zsercà na paroła in manco de tre carateri. Oppure te podarezsi aver scritto małe ła richiesta, par esempio "pesce and and azzurro". Per favore, riproa.',
+'matchtotals' => 'La ricerca per l\'esprezsion "$1" gà trovà<br />$2 riscontri nei titołi de le voci e<br />$3 riscontri ne i testi de le voci.',
+'noexactmatch' => '\'\'\'La paxèna "$1" non ła esiste.\'\'\' Xè possibiłe [[:$1|crearla ora]].',
+'titlematches' => 'Nei titołi de łe voçi',
+'notitlematches' => 'Voce richiesta non trovata in titoli di articolo',
+'textmatches' => 'Nel testo degli articoli',
+'notextmatches' => 'Voce richiesta non trovata in testi di articolo',
+'viewprevnext' => 'Varda ($1) ($2) ($3).',
+'showingresults' => 'Qui de seguito \'\'\'$1\'\'\' risultati, partendo dal numero #\'\'\'$2\'\'\'.',
+'showingresultsnum' => 'Qui de seguito \'\'\'$3\'\'\' risultati, partendo dal numero #\'\'\'$2\'\'\'.',
+'nonefound' => '<strong>Nota</strong>: la ricerca di parole troppo comuni, come "avere" o "essere", che non sono indicizzate, può causare un esito negativo, così come indicare più di un termine da ricercare (solo le pagine che contengano tutti i termini ricercati verrebbero infatti visualizzate fra i risultati).',
+'powersearch' => 'Zserca',
+'powersearchtext' => '
+Cerca fra i campi :<br />
+$1<br />
+$2 Elenca i redirects &nbsp; cerca per $3 $9',
+'blanknamespace' => '(Prinzsipałe)',
+'preferences' => 'Preferenzse',
+'prefsnologin' => 'Non te ghè eseguio el login',
+'prefsnologintext' => 'Te ghè da aver eseguio el [[Special:Userlogin|login]]
+par poder personalixare le to preferenzse.',
+'prefsreset' => 'Le to Preferenzse xè stà ripescae da la memoria de sistema del potente server de {{SITENAME}}.',
+'qbsettings' => 'Settaggio barra menu',
+'changepassword' => 'Cambia ła password',
+'skin' => 'Aspetto',
+'math' => 'Formułe matematiche',
+'dateformat' => 'Formato de la data',
+'datedefault' => 'Nesuna preferenzsa',
+'math_failure' => 'Failed to parse',
+'math_unknown_error' => 'unknown error',
+'math_unknown_function' => 'unknown function',
+'math_lexing_error' => 'lexing error',
+'math_syntax_error' => 'syntax error',
+'math_image_error' => 'Converzsion in PNG fałía',
+'math_bad_tmpdir' => 'Can\'t write to or create math temp directory',
+'math_bad_output' => 'Can\'t write to or create math output directory',
+'math_notexvc' => 'Missing texvc executable; please see math/README to configure.',
+'prefs-personal' => 'Profiło utente',
+'prefs-rc' => 'Ultime modifeghe',
+'prefs-misc' => 'Preferenzse varie',
+'saveprefs' => 'Salva preferenze',
+'resetprefs' => 'Resetta preferenzse',
+'oldpassword' => 'Vecia password:',
+'newpassword' => 'Nova password',
+'retypenew' => 'Riscrivi la nuova password',
+'textboxsize' => 'Dimensione della casella di edizione',
+'rows' => 'Righe',
+'columns' => 'Cołone:',
+'searchresultshead' => 'Settaggio preferenze di ricerca',
+'resultsperpage' => 'Numero de risultati par paxèna:',
+'contextlines' => 'Righe de testo par ciascun risultato',
+'contextchars' => 'Caratteri par linea:',
+'stubthreshold' => 'Stub visualizzati',
+'recentchangescount' => 'Numero titołi in "modifeghe reçenti"',
+'savedprefs' => 'Le to preferenzse łe xè stà salvae.',
+'timezonetext' => 'Immetti il numero di ore di differenza fra la tua ora locale e la ora del server (UTC).',
+'localtime' => 'Ora Locale',
+'guesstimezone' => 'Usa l\'ora del to browser',
+'allowemail' => 'Consenti la ricezsion de e-mail da altri utenti (1)',
+'defaultns' => 'Szerca in sti namespace se non diversamente specificà:',
+'default' => 'default',
+'files' => 'Imagini',
+'userrights-lookup-user'=> 'Gestion de i gruppi utente',
+'userrights-user-editname'=> 'Inserire el nome utente:',
+'userrights-groupshelp' => 'Selezsionar i gruppi ai quałi se vołe assoçiare o rimovere l\'utente. L\'appartenenzsa ai gruppi non selezsionai non verrà modifegà. Par desełezsionare un gruppo, premere Ctrl + el tasto sinistro del mouse.',
+'group-sysop' => 'Aministradori',
+'group-sysop-member' => 'Aministrador',
+'changes' => 'cambiamenti',
+'recentchanges' => 'Ultime modifeghe',
+'recentchangestext' => 'Sta paxèna presenta łe ultime modifeghe aportae ai contenuti de el sito.',
+'rcnote' => 'De seguito xè ełencae łe <strong>$1</strong> modifiche pì reçenti aportae ne i ultimi <strong>$2</strong> jorni, agiornae a $3.',
+'rcnotefrom' => ' Qui di seguito sono elencate le modifiche da <b>$2</b> (fino a <b>$1</b>).',
+'rclistfrom' => 'Mostra łe modifeghe aportae a partire da $1',
+'rcshowhideminor' => '$1 le modifeghe minori',
+'rcshowhideliu' => '$1 gli utenti registrai',
+'rcshowhidepatr' => '$1 łe modifeghe controłae',
+'rcshowhidemine' => '$1 łe me modifeghe',
+'rclinks' => 'Mostra le ultime $1 modifiche nei ultimi $2 giorni<br />$3',
+'hide' => 'scondi',
+'show' => 'Mostra',
+'reupload' => 'Ri-upload',
+'reuploaddesc' => 'Torna al modulo per lo upload.',
+'uploadnologin' => 'Te devi fare el login par exeguire sta operazsion.',
+'uploadnologintext' => 'Te ghè da exeguire [[Special:Userlogin|el login]]
+par fare el upload de files.',
+'uploaderror' => 'Errore di Upload',
+'uploadtext' => 'Usa el moduło sotostante par caricare i novi file. Par vixualixare o riçercare i file xà caricai, consulta el [[Special:Imagelist|log de i file caricai]]. Caricamenti e scancełazsioni de file i xè registrai ne el [[Special:Log/upload|log de i upload]].
+
+Par inserire un\'imagine in na paxèna, fare un cołegamento de sto tipo:
+\'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:file.jpg]]</nowiki>\'\'\' o
+\'\'\'<nowiki>[[</nowiki>{{ns:Image}}<nowiki>:file.png|testo alternativo]]</nowiki>\'\'\'; usare inveçe
+\'\'\'<nowiki>[[</nowiki>{{ns:Media}}<nowiki>:file.ogg]]</nowiki>\'\'\' par cołegare diretamente gli altri tipi de file.',
+'uploadlog' => 'File caricai',
+'uploadlogpage' => 'Log dei file caricai',
+'uploadlogpagetext' => 'Qui di seguito la lista degli ultimi files caricati sul server di {{SITENAME}}.
+Tutti i tempi indicati sono calcolati sul fuso orario del server (UTC).
+<ul>
+</ul>',
+'filedesc' => 'Oggetto',
+'fileuploadsummary' => 'Sommario:',
+'filestatus' => 'Stato del copyright',
+'filesource' => 'Sorgente',
+'copyrightpagename' => '{{SITENAME}} copyright',
+'uploadedfiles' => 'Files Caricati in {{SITENAME}}',
+'ignorewarning' => 'Ignore warning and save file anyway.',
+'ignorewarnings' => 'Ignora i messaggi de avvertimento del sistema',
+'minlength' => 'I nomi de i file imagine i deve essere longhi almancoo tre caratteri.',
+'illegalfilename' => 'Il nomefile "$1" contiene caratteri che xè permessi nei titoli delle pagine. Per favore rinomina el file e prova a ricaricarlo.',
+'badfilename' => 'El nome de el file imagine xè stà convertio in "$1".',
+'badfiletype' => '".$1" non xè mia un tipo de file raccomandà par łe imagini, almanco par i nostri fini.',
+'largefile' => 'Se raccomanda de non superar łe dimenzsion de $1 byte par ciascun file; sto file xè grande $2 byte.',
+'largefileserver' => 'This file is bigger than the server is configured to allow.',
+'emptyfile' => 'El file che te ghè caricà xè apparentemente vuoto. Podaria essere par un errore nel nome del file. Per favore controlla se te vol veramente caricar stò file.',
+'fileexists' => 'Un file con sto nome el esiste xà, per favore controła $1 se non te sì sicuro de volerlo sovrascrivere.',
+'fileexists-forbidden' => 'Un file con sto nome el esiste xà; per favore torna indrio e cambia el nome che te voi dare al file. [[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden'=> 'Un file con sto nome esiste xè ne l\'archivio de risorse multimediałi condivixe. Per favore torna indrio e cambia el nome che te voi dare al file. [[Image:$1|thumb|center|$1]]',
+'fileuploaded' => 'El file "$1" xè stà correttamente caricà sul server.
+Segui el cołegamento: $2 par modificare ła paxèna de descrizsion del file appena caricà, indicando ła fonte, l\'autore, ła data de creazsion e ogni altra informazsion che te ghè. Se se trata de n\'imagine, ła se pode inserire ne łe paxène con el comando:<br /><nowiki>[[</nowiki>{{ns:Image}}:$1|thumb|Descrizsion<nowiki>]]</nowiki>',
+'uploadwarning' => 'Avixo de Upload',
+'uploadedimage' => 'gà caricà "[[$1]]"',
+'uploaddisabledtext' => 'El caricamento dei file non xè attivo su sto sito.',
+'uploadscripted' => 'Sto file contegne codexe HTML o de script, che podaria essere interpretà eroneamente da un browser web.',
+'uploadvirus' => 'Sto file contegne un virus! Detagli: $1',
+'destfilename' => 'Destination filename',
+'filewasdeleted' => 'Un file con sto nome xè stato xà caricà e scancełà in passato. Verifica $1 prima de caricarlo de novo.',
+'license' => 'Licensing',
+'nolicense' => 'Nessuna liçenzsa indicà',
+'imagelist' => 'Imagini',
+'imagelisttext' => 'Qui de seguito na łista de $1 imagini, ordinae par $2.',
+'imagelistforuser' => 'This shows only images uploaded by $1.',
+'getimagelist' => 'rizserca ne la lista de le immagini',
+'ilsubmit' => 'Zserca',
+'showlast' => 'Lista di $1, fra le ultime immagini, ordinate per $2.',
+'bysize' => 'peso',
+'imglegend' => 'Legenda: (desc) = mostra/modifica descrizsion imagine.',
+'imghistory' => 'Cronołogia de sta imagine',
+'imghistlegend' => 'Legenda: (corr) = imagine corente, (canc) = scanceła sta verzsion vecia, (ripr) = ripristina sta verzsion vecia come verzsion atuałe.
+<br />\'\'Clicca su una data par vardare l\'imagine corrispondente.\'\'',
+'imagelinks' => 'Collegamenti a le immagini',
+'linkstoimage' => 'Le paxène seguenti riciama sta imagine:',
+'nolinkstoimage' => 'Nessuna paxèna linka sta imagine.',
+'noimage' => 'Un file con sto nome non esiste; $1?',
+'noimage-linktext' => 'carica ora',
+'uploadnewversion-linktext'=> 'Carica na nova verzsion de sto file',
+'mimesearch' => 'MIME search',
+'mimetype' => 'MIME type:',
+'unwatchedpages' => 'Paxène non osservae',
+'listredirects' => 'List redirects',
+'unusedtemplateswlh' => 'altri cołegamenti',
+'sitestats' => 'Statistiche del sito',
+'userstats' => 'Statistiche dei utenti',
+'sitestatstext' => 'El database contegne complessivamente \'\'\'{{FORMATNUM|$1}}\'\'\' paxène.
+Sta çifra comprende anca łe paxène de discussion, quełe de servizsio de {{SITENAME}}, łe voçi pì esigue ("stub"), i redirect e altre paxène che probabilmente non łe va considerae tra i contenuti de el sito. Escludendo łe paxène sora descritte, ghe ne xè \'\'\'{{FORMATNUM|$2}}\'\'\' de contenuti veri e propri.
+
+Xè stà inoltre caricà \'\'\'{{FORMATNUM|$8}}\'\'\' file.
+
+Dall\'instałazsione del sito sino a sto momento ghe xè stà visitae \'\'\'{{FORMATNUM|$3}}\'\'\' paxène ed eseguie \'\'\'{{FORMATNUM|$4}}\'\'\' modifeghe, pari a na media de \'\'\'{{FORMATNUM|$5}}\'\'\' modifeghe par paxèna e \'\'\'{{FORMATNUM|$6}}\'\'\' richieste de lettura par ciascuna modifica.
+
+La [http://meta.wikimedia.org/wiki/Help:Job_queue coda] contegne \'\'\'{{FORMATNUM|$7}}\'\'\' proçessi.',
+'userstatstext' => 'In sto momento ghe xè \'\'\'$1\'\'\' utenti registrai, dei quałi \'\'\'$2\'\'\' (pari al \'\'\'$4%\'\'\') xè aministradori (varda $3).',
+'disambiguations' => 'Paxène de disambiguazsion',
+'disambiguationspage' => 'Template:Disambigua',
+'disambiguationstext' => 'Le paxène ne ła lista che segue contegne dei cołegamenti a <i>paxène de disambigua</i> piuttosto che a l\'argomento coreto cui i fà riferimento.<br />Le xè considerae paxène de disambigua tute quełe che contegne cołegamenti al $1.<br />I cołegamenti da altri namespace <i>non</i> xè considerai ne ła lista che segue.',
+'doubleredirectstext' => '<b>Atenzsion:</b> Stà lista la pode talvolta contegnere dei risultati non corretti. Podaria magari accadere perchè ghe fusse del testo aggiuntivo o dei link dopo el tag #REDIRECT.<br /> Ogni riga contegne i link al primo ed al secondo redirect, oltre a la prima riga de testo del secondo redirect che de solito contegne el "reale" articolo de destinazsion, quello al quale anca el primo redirect dovaria puntare.',
+'brokenredirects' => 'Redirect erái',
+'brokenredirectstext' => 'I seguenti redirect i punta a articoli non ancora creai.',
+'nbytes' => '$1 bytes',
+'ncategories' => '$1 categories',
+'lonelypages' => 'Paxène solitarie',
+'uncategorizedpages' => 'Paxène prive de categorie',
+'uncategorizedcategories'=> 'Categorie prive de categorie',
+'uncategorizedimages' => 'Imagini prive de categorie',
+'unusedcategories' => 'Categorie non utilixae',
+'unusedimages' => 'Imagini non utilixae',
+'popularpages' => 'Paxène pì viste',
+'wantedpages' => 'Paxène pì richieste',
+'mostlinked' => 'Paxène piassè linkae',
+'mostlinkedcategories' => 'Categorie piazsé riciamae',
+'mostcategories' => 'Arthicołi con piazsé categorie',
+'mostimages' => 'Most linked to images',
+'mostrevisions' => 'Voçi con piazsé revixión',
+'allpages' => 'Tute łe paxène',
+'randompage' => 'Paxèna a caso',
+'shortpages' => 'Paxène corte',
+'longpages' => 'Paxène longhe',
+'deadendpages' => 'Paxène senzsa uscita',
+'listusers' => 'Elenco dei utenti',
+'specialpages' => 'Paxène speciałi',
+'spheading' => 'Paxène speciałi par tuti i utenti',
+'restrictedpheading' => 'Paxène speciałi par i aministradori',
+'recentchangeslinked' => 'Modifeghe corełae',
+'rclsub' => '(a łe paxène linkae da "$1")',
+'newpages' => 'Paxène nove',
+'ancientpages' => 'Paxène pì vece',
+'intl' => 'Link a altri linguaggi',
+'unusedimagestext' => '<p>Nota che altri siti web, come la {{SITENAME}} internazionale, potrebbero aver messo un link ad una immagine per mezzo di una URL diretta, perciò le immagini potrebbero essere listate qui, essendo inutilizzate in questa versione di {{SITENAME}}, anche essendo magari in uso altrove.',
+'unusedcategoriestext' => 'Le paxène de łe categorie indicae de seguito łe xè stà creae ma non contegne nessuna paxèna né sotocategoria.',
+'categoriespagetext' => 'In {{SITENAME}} ghèmo ste categorie',
+'data' => 'Data',
+'version' => 'Verzsion',
+'log' => 'Logs',
+'alllogstext' => 'Vixualixazsion unificà de i log de upload, scancełazsión, protezsión, blocking e de aministrazsión. Te podi restringere i criteri de rizserca selezsionando el tipo de log, username, o la paxèna interessà.',
+'logempty' => 'No matching items in log.',
+'nextpage' => 'Paxèna dopo ($1)',
+'allpagesfrom' => 'Mostra łe paxène cominzsiando da:',
+'allarticles' => 'Tuti le voçi',
+'allinnamespace' => 'Tute łe paxène ($1 namespace)',
+'allnotinnamespace' => 'Tute łe paxène (no ne el namespace $1)',
+'allpagesprev' => 'Preçedenti',
+'allpagesnext' => 'Prozsime',
+'allpagessubmit' => 'Và',
+'allpagesprefix' => 'Mostra łe voçi che inizsia con:',
+'mailnologin' => 'No send address',
+'mailnologintext' => 'Par inviare messaj e-mail ad altri utenti xè neçessario [[Special:Userlogin|açedere al sito]] e aver registrà un indirizso vałido ne łe proprie [[Special:Preferences|preferenzse]].',
+'emailpage' => 'Scrivi una e-mail all\'utente',
+'emailpagetext' => 'Se sto Utente gà registrà na casella e-mail valida, el modulo qui sotto te consentirà di scriverghe un solo messaggio. La e-mail che te ghè indicà ne le to preferenzse la apparirà nel campo "Da" de la mail, così che el destinatario possa, solo se el lo desidera però, risponderte.',
+'defemailsubject' => '{{SITENAME}} e-mail',
+'noemailtitle' => 'Nessun indirizso e-mail',
+'noemailtext' => 'Questo Utente non ha registrato alcuna casella e-mail, oppure ha scelto di non ricevere posta elettronica dagli altri Utenti.',
+'emailmessage' => 'Messajo',
+'emailsent' => 'E-mail invià',
+'emailsenttext' => 'La to e-mail xè stà invià',
+'watchlist' => 'osservati speciali',
+'watchlistfor' => '(par \'\'\'$1\'\'\')',
+'nowatchlist' => 'Non hai indicato articoli da tenere d\'occhio.',
+'watchlistanontext' => 'Per vixualixare e modifegar l\'ełenco de i osservati speciałi xè necessario $1.',
+'watchlistcount' => '\'\'\'La lista de i osservati speciałi contegne {{FORMATNUM|$1}} elementi (comprexe łe paxène de discussion).\'\'\'',
+'clearwatchlist' => 'Svoda ła lista de i osservati speciałi',
+'watchlistcleartext' => 'Conferma ła rimozsion de tuti gli elementi.',
+'watchlistclearbutton' => 'Svoda ła łista',
+'watchlistcleardone' => 'La łista de i osservati speciałi xè stà svodada. I xè stà eliminai $1 ełementi.',
+'watchnologin' => 'No ghe xe el login',
+'watchnologintext' => 'Devi prima fare il [[Special:Userlogin|login]]
+per modificare la tua lista di osservati speciali.',
+'addedwatch' => 'Xontà ai tòi Osservati Speciali',
+'addedwatchtext' => 'La paxèna "$1" l\'è stà xontà a la tua [[Special:Watchlist|lista de osservati speciali]].
+Le future modifiche a stà pagina e a la relativa pagina de discussion le sarà elencae qui, e la paxèna apparirà in \'\'\'grasseto\'\'\' ne la paxèna de le [[Special:Recentchanges|modifiche recenti]] par essere pì facile da tener d\'ocio.
+
+Se pì avanti te vorè tojere stò articolo da la to lista de Osservati Speciali, clicca "Non seguire" nella barra dei menu.',
+'removedwatch' => 'Rimosso dalla lista degli Osservati Speciali',
+'removedwatchtext' => 'La paxèna "$1" xè stà rimossa da ła łista de i toi Osservati Speciałi.',
+'watchthispage' => 'Segui sta voçe',
+'notanarticle' => 'Non xè na voçe',
+'watchnochange' => 'Nezsun de i to ojeti osservai l\'è stà edità nel periodo mostrà.',
+'watchdetails' => '* $1 ojeti osservai no i contegne discussioni
+* [[Special:Watchlist/edit|Mostra e modifica tuti i osservati speciałi]]',
+'wlheader-enotif' => '* Xe attivà la notifica via e-mail.',
+'wlheader-showupdated' => '* Le paxène che xe stà modificà da la to ultima visita le xe evidensià en \'\'\'grasseto\'\'\'',
+'watchmethod-recent' => 'controło de łe modifeghe reçenti par i osservati speciałi',
+'watchmethod-list' => 'controło de i osservati speciałi par modifeghe reçenti',
+'watchlistcontains' => 'La lista de i osservati speciałi contiene $1 paxène.',
+'watcheditlist' => 'De seguito łe xè ełencae tute łe paxène osservae, in ordine alfabetico. Selezsionare łe casełe rełative a łe paxène che se desidera eliminar da ła lista e fare clic sul boton \'Ełimina ełementi sełezsionà da ła łista\' in fondo a l\'ełenco par rimoverle. Quando vegne eliminà na paxèna da ła łista, anca ła corrispondente paxèna de discussion cessa de essere osservà (e viceversa).',
+'couldntremove' => 'Non xè possibile rimuovere la paxèna \'$1\'...',
+'iteminvalidname' => 'Problemi con la voçe \'$1\', nome non vałido...',
+'wlnote' => 'Sotto te trovi le ultime $1 modifiche, nelle ultime <b>$2</b> ore.',
+'wlsaved' => 'Questa l\'è na version salvà de la to lista de articoli sotto osservasión.',
+'wlhideshowown' => '$1 le me modifeghe.',
+'wlhideshowbots' => '$1 modifighe del bot.',
+'enotif_reset' => 'Segna tute łe paxène visitae',
+'enotif_newpagetext' => 'Sta quà xe na nova paxèna.',
+'changed' => 'cambià',
+'created' => 'Creà',
+'enotif_subject' => '{{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED by $PAGEEDITOR',
+'enotif_lastvisited' => 'Varda $1 par tutte le modifiche da la to ultima visita.',
+'enotif_body' => 'Caro $WATCHINGUSERNAME,
+
+ła paxèna $PAGETITLE de {{SITENAME}} xè stà $CHANGEDORCREATED el $PAGEEDITDATE da $PAGEEDITOR, varda $PAGETITLE_URL par ła verzsione atuałe.
+
+$NEWPAGE
+
+Sommario del redattore: $PAGESUMMARY $PAGEMINOREDIT
+
+Contatta el redattore:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+Non ghe sarà altre notifiche in caso de ulteriori cambiamenti, a manco che ti non te visiti sta paxèna. Te podi anca rexettar l\'avvixo de notifica par tuti gli osservati speciałi de ła to łista.
+
+ El to amichevole sistema de notifica de {{SITENAME}}
+
+--
+Par cambiare łe impostazsion de i to osservati speciałi, visita
+{{fullurl:Special:Watchlist/edit}}
+
+Par riscontri e ulteriore assistenzsa:
+{{fullurl:Help:Ciacołe}}',
+'deletepage' => 'Scanceła paxèna',
+'excontent' => 'el contenuto xera: \'$1\'',
+'exbeforeblank' => 'El contenuto prima de lo svodamento xera: \'$1\'',
+'exblank' => 'ła paxèna l\'era voda',
+'confirmdelete' => 'Conferma scancełazsión',
+'deletesub' => '(Scancełazsion de "$1")',
+'historywarning' => 'Atenzsion: La paxèna che te stè par scancełar gà na cronołogia:',
+'confirmdeletetext' => 'Te stè par scancełar permanentemente da el database na paxèna o na imagine, insieme a tuta la so cronołogia.
+Par cortesia, conferma che l\'è to intenzsion proçedere a tałe scancełazsion, conferma che te ghè piena consapevołezsa de łe conseguenzse de la to azsion, e conferma che la to azsion l\'è pienamente ottemperante a łe regołe stabilíe ne ła
+[[Project:Policy]].',
+'actioncomplete' => 'Azsión completà',
+'deletedtext' => 'La paxèna "$1" l\'è stà scancełà. Varda $2 par un ełenco de łe paxène scancełae de reçente.',
+'deletedarticle' => 'Scancełà "$1"',
+'dellogpage' => 'Scancełazsión',
+'dellogpagetext' => 'Qui de seguito, un ełenco de łe paxène scancełae de reçente.',
+'deletionlog' => 'Log de scancełasión',
+'reverted' => 'Ripristinata versione precedente',
+'deletecomment' => 'Motivazsion de ła scancełazsion',
+'imagereverted' => 'Version precedente correttamente ripristinata.',
+'rollback' => 'Usa una revisione precedente',
+'rollbackfailed' => 'Rollback non riuzsio',
+'cantrollback' => 'No xè mia possibiłe tornar a na verzsión precedente: l\'ultima modifica xè stà apportà da l\'unico utente che gà laorà a stò arthicoło.',
+'alreadyrolled' => 'Non xè mia possibile effettuare el rollback de [[:$1]] da [[User:$2|$2]] ([[User talk:$2|discussion]]); qualcun altro gà xà modificà o effetuà el rollback de sta voçe. L\'ultima modefega l\'è stà fata da [[User:$3|$3]] ([[User talk:$3|discussion]]).',
+'editcomment' => 'El commento a la modifica xera: "<i>$1</i>".',
+'revertpage' => 'Anułate łe modifeghe de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]]), riportà a ła verzsion preçedente de [[User:$1|$1]]',
+'protectlogpage' => 'Log de protezsión',
+'protectedarticle' => 'proteto "[[$1]]"',
+'unprotectedarticle' => 'unprotected "[[$1]]"',
+'protectsub' => '(Protezsion de "$1")',
+'confirmprotecttext' => 'Sito sicuro de voler protezxere stà paxèna?',
+'confirmprotect' => 'Conferma la protezsion',
+'protectmoveonly' => 'Protegi soło dallo spostamento',
+'protectcomment' => 'Motivo de ła protezsion',
+'unprotectsub' => '(Sbloco de "$1")',
+'confirmunprotecttext' => 'Sito sicuro de voler sproteggere sta paxèna?',
+'confirmunprotect' => 'Conferma sprotezsion',
+'protect-unchain' => 'Scołega i permessi de spostamento',
+'protect-level-autoconfirmed'=> 'Solo utenti registrai',
+'protect-level-sysop' => 'Solo aministradori',
+'restriction-edit' => 'Modifega',
+'undelete' => 'Recupera na paxèna scancełà',
+'undeletepage' => 'Varda e recupera paxène scancełae',
+'viewdeletedpage' => 'Varda łe paxène scancełae',
+'undeletepagetext' => 'Le pagine qui di seguito indicate sono state cancellate, ma sono ancora in archivio e pertanto possono essere recuperate. L\'archivio viene svuotato periodicamente.',
+'undeleteextrahelp' => 'Par recuperare l\'intera paxèna, lazsia tute łe casełe desełezsionae e fa clic su \'\'\'\'\'Ripristina\'\'\'\'\'. Par effettuare un ripristino sełetivo, selezsiona łe casełe corrispondenti a łe revixion da ripristinare e fa clic su \'\'\'\'\'Ripristina\'\'\'\'\'. Faxendo clic su \'\'\'\'\'Reset\'\'\'\'\' łe verà deselezsionae tute łe casełe e svodà lo spazsio par el commento.',
+'undeletearticle' => 'Recupera na voçe scancełà',
+'undeletehistory' => 'Recuperando sta paxèna, tute łe so revixion verà inserie de novo ne ła rełativa cronołogia. Se dopo ła scancełazsion xè stà creà na nova paxèna con lo stesso titoło, łe revixion recuperae sarà inserie ne ła cronołogia e ła verzsion attualmente online de ła paxèna non verrà modifegà.',
+'undeletehistorynoadmin'=> 'La paxèna xè stà scanceła. El motivo de ła scancełazsion xè indicà de seguito, assieme ai dati de i utenti che i gavea modifegà ła paxèna prima de ła scancełazsion. El testo contegnù ne łe revixion scancełae xè disponibiłe solo a i aministradori.',
+'undeleterevision' => 'Scancełà revixion $1',
+'undeletebtn' => 'RIPRISTINA!',
+'undeletedarticle' => 'Recuperà "$1"',
+'undeletedrevisions' => '$1 revixion recuperae',
+'undeletedrevisions-files'=> '$1 revixion e $2 file recuperai',
+'undeletedfiles' => '$1 file recuperai',
+'cannotundelete' => 'El recupero no\'l xè riusìo: qualcun altro podariae avere xà recuperà ła paxèna.',
+'undeletedpage' => '<big>\'\'\'$1 xè stà recuperà\'\'\'</big>
+
+Consultare el [[Special:Log/delete|log delle scancełazsioni]] par vardare łe scancełazsion e i recuperi pì reçenti.',
+'invert' => 'inverti ła selezsión',
+'mycontris' => 'i me contributi',
+'nocontribs' => 'Nessuna modifica trovata conformemente a questi criteri.',
+'ucnote' => 'Qui sotto troverai le ultime <b>$1</b> modifiche effettuate da questo Utente negli ultimi <b>$2</b> giorni.',
+'uclinks' => 'Vedi le ultime $1 modifiche; vedi gli ultimi $2 giorni.',
+'uctop' => ' (ultima par ła paxèna)',
+'newbies' => 'newbies',
+'sp-newimages-showfrom' => 'Mostra łe imagini pì reçenti a partire da $1',
+'sp-contributions-older'=> '$1 manco reçenti',
+'whatlinkshere' => 'Paxène che le punta qua',
+'notargettext' => 'Non hai specificato una pagina o un Utente in relazione al quale eseguire l\'operazione richiesta.',
+'linklistsub' => '(Lista di link)',
+'linkshere' => 'Le seguenti paxène le contegne link che punta qua:',
+'nolinkshere' => 'Nessuna paxèna contegne links che punta a sta quà.',
+'istemplate' => 'inclusion',
+'blockip' => 'Blocca indirizso IP',
+'blockiptext' => 'Usare el moduło sottostante par bloccare l\'accesso in scrittura ad uno speçifico utente o indirizso IP. El bloco dev\'essere operà par prevegnere ati de vandalismo e in stretta osservanzsa de ła [[Project:Policy|policy de {{SITENAME}}]]. Speçificare in dettałio el motivo de el bloco nel campo seguente (ad es. indicando i titołi de łe paxène oggeto de vandalismo).',
+'ipaddress' => 'Indiriszo IP (IP Address)',
+'ipadressorusername' => 'Indiriszo IP o nome utente',
+'ipbexpiry' => 'Scadenzsa',
+'ipbreason' => 'Motivazsión',
+'ipbsubmit' => 'Blocca sto indirizso IP',
+'ipbother' => 'Other time',
+'ipboptions' => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
+'ipbotheroption' => 'other',
+'badipaddress' => 'L\'indirizso IP indicà non xè coreto.',
+'blockipsuccesssub' => 'Blocco eseguio',
+'blockipsuccesstext' => 'L\'indirizzo IP "$1" l\'è sta bloccà.
+<br />Varda [[Special:Ipblocklist|lista IP bloccati]].',
+'unblockip' => ' Sblocca indirizzo IP',
+'unblockiptext' => 'Usa il modulo sottostante per restituire il diritto di scrittura ad un indirizzo IP precedentemente bloccato.',
+'ipusubmit' => 'Sblocca sto indirizso IP',
+'ipblocklist' => 'Indiriszi IP bloccai',
+'blocklistline' => '$1, $2 gà bloccà $3 fino al $4',
+'infiniteblock' => 'infinito',
+'ipblocklistempty' => 'La lista de i indiriszi IP bloccai xè voda',
+'autoblocker' => 'Bloccà automaticamente parché l\'indirisso IP xè condiviso con "$1". Motivo "$2".',
+'blocklogpage' => 'Block_log',
+'blocklogentry' => 'bloccà "$1" par un periodo di $2',
+'blocklogtext' => 'Sto qua xè un elenco de azsioni de blocco e sblocco degli indirizzi IP. Gli indirizzi bloccai in automatico non xè elencai. Vrda [[Special:Ipblocklist|elenco IP bloccati]] per l\'elenco degli indirizzi il cui blocco xè operativo.',
+'ipb_expiry_invalid' => 'Tempo de scadenzsa non valido. Controlla el [http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html manuale de tar] par la sintassi esatta.',
+'ip_range_invalid' => 'Intervało IP non vałido.',
+'proxyblocksuccess' => 'Fatto.',
+'lockdb' => 'Blocca el database',
+'unlockdb' => 'Sbloca el database',
+'lockdbtext' => 'Bloccare il database sospenderà la possibilità per tutti gli Utenti di modificare le pagine o di crearne di nuove, di cambiare le loro preferenze, di modificare le loro liste di Osservati Speciali, ed in genere non consentirà a nessuno di eseguire operazioni che richiedano modifiche del database.<br /><br />
+Per cortesia, conferma che questo è effettivamente quanto tu intendi ora effettuare e, soprattutto, che il prima possibile sbloccherai nuovamente il database, ripristinandone la corretta funzionalità, non appena avrai terminato le tue manutenzioni.',
+'unlockdbtext' => 'Sbloccare il database ripristinerà la possibilità per tutti gli Utenti di modificare le pagine o di crearne di nuove, di cambiare le loro preferenze, di modificare le loro liste di Osservati Speciali, ed in genere di eseguire operazioni che richiedano modifiche del database.
+Per cortesia, conferma che questo è effettivamente quanto tu intendi ora effettuare.',
+'lockconfirm' => 'Sì, effettivamente intendo, sotto la mia responsabilità, bloccare il database.',
+'unlockconfirm' => ' Sì, effettivamente intendo, sotto la mia responsabilità, sbloccare il database.',
+'lockbtn' => 'Blocca el database',
+'unlockbtn' => 'Sbloca el database',
+'locknoconfirm' => 'Non hai spuntato la casellina di conferma.',
+'lockdbsuccesssub' => 'Blocco de el database eseguio',
+'unlockdbsuccesssub' => 'Sblocco del database eseguito, rimosso blocco',
+'lockdbsuccesstext' => 'Il database di {{SITENAME}} è stato bloccato.
+<br />Ricordati di rimuovere il blocco non appena avrai terminatoi le tue manutenzioni.',
+'unlockdbsuccesstext' => ' Il database di {{SITENAME}} è stato sbloccato.',
+'makesysoptitle' => 'Rendi aministradore un utente',
+'makesysoptext' => 'Sto form xè usà dai burocrati par far diventare amistradori i utenti normali.
+Scrivi el nome de l\'utente ne la caseła e struca el botón par far diventare aministradore un utente.',
+'makesysopname' => 'Nome dell\'utente:',
+'makesysopsubmit' => 'Fa diventar sto utente un aministrador',
+'makesysopok' => '\'\'\'L\'utente \'$1\' adesso xè un aministrador\'\'\'',
+'makesysopfail' => '<b>Impossibiłe far diventare aministrador l\'utente "$1". Verificare che el nome utente sia stà scrito coretamente.</b>',
+'setbureaucratflag' => 'Imposta i diritti del burocrate',
+'set_user_rights' => 'Imposta diritti utente',
+'makesysop' => 'Rendi un utente aministrador',
+'already_sysop' => 'Sto utente l\'è xà un aministradór',
+'already_bureaucrat' => 'Sto utente l\'è xà un burocrate',
+'movepage' => 'Spostamento de paxèna',
+'movepagetext' => 'Con el modulo sottostante te podi rinominar na paxèna, spostando anca tuta la so cronołogia al novo nome. El vecio titoło diverrà automaticamente un redirect che punta al novo titoło. I link a la vecia paxèna non sarà agiornai (e i punterà quindi al redirect); azsertai de [[Special:Manutenzsion|controłare con cura]] che non se crea doppi redirects o redirects interroti. Resta ne la to responsabilità de accertarte che i link i continua a puntare verso dove i deve dirigerse. Nota ben: la paxèna \'\'\'non\'\'\' sarà spostà se ve fusse xà una voçe con el novo nome, a meno che non sia na paxèna voda o un redirect, e sempre che non abbia cronologia. Questo significa che, se te commetti un error, te podi novamente rinominar na paxèna col vecio titoło, ma non te podi sovrascriver na paxèna xà esistente. <b>ATTENZSION!</b> Sto cambiamento drastico podaria crear inattesi contrattempi, specialmente se se tratta de na paxèna molto visità. Accertai de aver ben valutà le conseguenzse de lo spostamento, prima de procedere. Nel dubbio, contatta un Aministrador.',
+'movepagetalktext' => 'La corrispondente paxèna de discussion sarà spostà automaticamente insieme a ła paxèna prinçipałe, \'\'\'tranne che nei seguenti casi:\'\'\'
+* Lo spostamento de ła paxèna xè tra namespace diversi
+* In corrispondenzsa del novo titoło esiste xà na paxèna de discussion (non voda)
+* La caseła chi soto xè stà desełezsionà.',
+'movearticle' => 'Rinomina voçe',
+'movenologin' => 'Non te ghè efetuà el login',
+'movenologintext' => 'Te ghè da esser un Utente registrà ed aver effettuà el [[Special:Userlogin|login]] par poder spostare na paxèna.',
+'newtitle' => 'Al novo titoło de',
+'movepagebtn' => 'Sposta sta paxèna',
+'pagemovedtext' => 'Paxèna "[[$1]]" rinominà in "[[$2]]".',
+'articleexists' => 'Na paxèna con sto nome la existe xà, oppure el nome che te ghè zselto non xè vałido.<br /> Zsegli, per cortexia, un titoło diverso par ła voçe.',
+'talkexists' => 'La pagina è stata spostata correttamente, ma non si è potuto spostare la pagina di discussione perché ne esiste già un\'altra con il nuovo titolo. Per favore, modifica manualmente i contenuti delle due pagine discussione, così da mantenerle entrambe per non perdere potenzialmente interessanti riflessioni.',
+'movedto' => 'spostà a',
+'movetalk' => 'Sposta anche la corrispondente pagina "discussione", se possibile.',
+'talkpagemoved' => 'Anca ła corrispondente paxèna de discussion xè stà spostatà.',
+'talkpagenotmoved' => 'La corrispondente paxèna de discussion <strong>non xè stà spostà</strong>.',
+'1movedto2' => '[[$1]] spostà a [[$2]]',
+'1movedto2_redir' => '$1 spostà a $2 co\'n redirect',
+'movelogpage' => 'Move log',
+'movelogpagetext' => 'Lista de paxène spostae.',
+'movereason' => 'Reason',
+'delete_and_move' => 'Scanceła e sposta',
+'delete_and_move_text' => '==Scancełazsion richiesta==
+
+La voçe specificà come destinazsion "[[$1]]" l\'esiste già. Vóto scancełarlo par proseguire con ło spostamento?',
+'delete_and_move_confirm'=> 'Si! Scancèła ła paxèna',
+'delete_and_move_reason'=> 'Scancełà par rendere possibile lo spostamento',
+'selfmove' => 'El novo titoło xè uguałe al vecio; impossibiłe spostare ła paxèna su se stessa.',
+'immobile_namespace' => 'El titolo de destinazsion l\'è de tipo speciale; impossibile spostar paxène in quel namespace.',
+'export' => 'Esporta paxène',
+'exporttext' => 'Te podi esportar el testo e modificar ła cronołogia de na speçifica paxèna o de un gruppo de paxène raggruppae in XML; questo el pode in seguito essere importà in un altro wiki che utilixa el software MediaWiki, trasformà, o tegnù semplicemente par el to personałe divertimento.',
+'exportcuronly' => 'Includi soło ła verzion attuałe, non l\'intera cronołogia',
+'exportnohistory' => '----
+\'\'\'Ocio!\'\'\' par motivi de potenzsa xè stà disabiłità l\'esportazsion de tuta ła storia de łe paxène fata co \'sto modeło',
+'allmessages' => 'Tuti i messaj de sistema',
+'allmessagesdefault' => 'Testo de default',
+'allmessagescurrent' => 'Testo come che el xe \'deso',
+'allmessagestext' => 'Sta quà l\'è na lista de tutti i messaggi disponibili nel namespace MediaWiki:',
+'allmessagesnotsupportedUI'=> 'El linguaggio che te ghè scelto (\'\'\'$1\'\'\') non l\'è mia supportà da \'\'\'Special:Allmessages\'\'\' in sto sito.',
+'allmessagesnotsupportedDB'=> '\'\'\'Special:Allmessages\'\'\' no\'l xè supportà parché \'\'\'$wgUseDatabaseMessages\'\'\' no\'l xè ativo.',
+'allmessagesfilter' => 'Filto su i messaj:',
+'allmessagesmodified' => 'Mostra soło quełi modefegà.',
+'missingimage' => '<b>Missing image</b><br /><i>$1</i>',
+'import' => 'Importa paxène',
+'importinterwiki' => 'Transwiki import',
+'import-interwiki-text' => 'Selezsionare un projeto wiki e el titoło de ła paxèna da importare.
+Le date de publicazsion e i nomi de i autori de łe varie verzsion i sarà conservai.
+Tute łe operazsion de importazsion trans-wiki łe xè registrae nel [[Special:Log/import|log de importazsion]].',
+'import-interwiki-history'=> 'Copia l\'intera cronołogia de sta paxèna',
+'importtext' => 'Per favore, esporta el file da la wiki de origine usando l\'utility Special:Export, salvalo su el to disco e fa l\'upload qua.',
+'importstart' => 'Importazsion de łe paxène in corso...',
+'import-revision-count' => '{{PLURAL:$1|una revixion importà|$1 revixion importae}}',
+'importnopages' => 'Nessuna paxèna da importar.',
+'importfailed' => 'Importazsion falía: $1',
+'importunknownsource' => 'Tipo de origine sconozsuo par l\'importazsion',
+'importcantopen' => 'Impozsibiłe verdere el file de importazsion',
+'importbadinterwiki' => 'Cołegamento inter-wiki errà',
+'importnotext' => 'Testo vodo o mancante',
+'importsuccess' => 'Importazsion avvegnù con successo!',
+'importhistoryconflict' => 'Esiste revision de la cronołogia in conflitto (sta paxèna podaria essere xà sta importà)',
+'importnosources' => 'Non xè stà definia na fonte par l\'importazsion transwiki; l\'importazsion direta de ła cronołogia non xè ativa.',
+'importnofile' => 'Non xè stà caricà nessun file par l\'importazsion,',
+'importuploaderror' => 'El caricamento de le imamgini xè falío, forse parché el file l\'è pì grosso del quel che xè permesso.',
+'importlogpage' => 'Importazsion',
+'importlogpagetext' => 'Registro de łe importazsion d\'uffiçio de paxène provenienti da altre wiki, complete de cronołogia.',
+'import-logentry-upload'=> 'gà importà [[$1]] tramite upload',
+'import-logentry-upload-detail'=> '{{PLURAL:$1|una revixion importà|$1 revixion importae}}',
+'import-logentry-interwiki'=> 'gà trasferio da altra wiki ła paxèna $1',
+'import-logentry-interwiki-detail'=> '{{PLURAL:$1|una revixion importà|$1 revixion importae}} da $2',
+'accesskey-diff' => 'v',
+'tooltip-search' => 'Zserca in {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Segnała come modifega minore [alt-i]',
+'tooltip-save' => 'Salva łe modifeghe [alt-s]',
+'tooltip-preview' => 'Anteprima de łe modifeghe (consilià, prima de salvare!) [alt-p]',
+'tooltip-diff' => 'Varda łe modifeghe apportae al testo. [alt-v]',
+'tooltip-compareselectedversions'=> 'Varda łe diferenzse tra łe do verzsion selezsionà de sta paxèna. [alt-v]',
+'notacceptable' => 'El server wiki non xè in grado di fornire i dati in un formato łeggibiłe dal client utilixà.',
+'anonymous' => 'Utente(/i) anonimo(/i) de {{SITENAME}}',
+'lastmodifiedatby' => 'Sta paxèna xè stà modificà l\'ultima volta el $2, $1 da $3.',
+'creditspage' => 'Crediti de ła paxèna',
+'subcategorycount' => 'Sta categoria contegne {{PLURAL:$1|na sotocategoria| {{FORMATNUM|$1}} sotocategorie}}.',
+'categoryarticlecount' => 'Ghè $1 voçi in sta categoria.',
+'listingcontinuesabbrev'=> '&nbsp;',
+'spam_blanking' => 'Paxèna svodà, tute łe verzsion contegneva cołegamenti a $1',
+'infosubtitle' => 'Informazsion par la paxèna',
+'numtalkedits' => 'Numero de modifeghe (paxèna de discussion): $1',
+'numtalkauthors' => 'Numero de autori distinti (paxèna de discussion): $1',
+'mw_math_png' => 'Always render PNG',
+'mw_math_simple' => 'HTML if very simple or else PNG',
+'mw_math_html' => 'HTML if possible or else PNG',
+'mw_math_source' => 'Leave it as TeX (for text browsers)',
+'mw_math_modern' => 'Raccomandà par i browser pì novi',
+'mw_math_mathml' => 'MathML if possible (experimental)',
+'markaspatrolleddiff' => 'Segna la modifica come verificà',
+'markaspatrolledtext' => 'Segna sto arthicoło come verificà',
+'markedaspatrolled' => 'Segnà come verificà',
+'markedaspatrolledtext' => 'La revixion selezsionà xè stà segnà come verificata.',
+'rcpatroldisabled' => 'Recent Changes Patrol disabled',
+'markedaspatrollederror'=> 'Impossibiłe contrassegnare ła voçe come verificà',
+'markedaspatrollederrortext'=> 'Occorre speçificare na revixion da contrazsegnare come verificà.',
+'monobook.js' => '/* tooltips and access keys */
+ var ta = new Object();
+ ta[\'pt-userpage\'] = new Array(\'.\',\'La me paxèna utente\');
+ ta[\'pt-anonuserpage\'] = new Array(\'.\',\'La paxèna utente de l\'ip che te stè usando\');
+ ta[\'pt-mytalk\'] = new Array(\'n\',\'Le me discussion\');
+ ta[\'pt-anontalk\'] = new Array(\'n\',\'Discussioni riguardo le modifiche fate da sto ip\');
+ ta[\'pt-preferences\'] = new Array(\'\',\'Le me preferenzse\');
+ ta[\'pt-watchlist\'] = new Array(\'l\',\'La lista de le paxène che te stè tegnendo soto ocio.\');
+ ta[\'pt-mycontris\'] = new Array(\'y\',\'La lista de i me contributi\');
+ ta[\'pt-login\'] = new Array(\'o\',\'Te consigliemo de registrarte, ma non l\'è obbligatorio.\');
+ ta[\'pt-anonlogin\'] = new Array(\'o\',\'Te consigliemo de registrarte, ma non l\'è obbligatorio.\');
+ ta[\'pt-logout\'] = new Array(\'\',\'Log out (esci)\');
+ ta[\'ca-talk\'] = new Array(\'t\',\'Varda łe discussion rełative a la voçe\');
+ ta[\'ca-edit\'] = new Array(\'e\',\'Te podi modificar sta paxèna. Per favor usa el botton de anteprima prima de salvare.\');
+ ta[\'ca-addsection\'] = new Array(\'+\',\'Xonta un commento a sta discussion.\');
+ ta[\'ca-viewsource\'] = new Array(\'e\',\'Sta paxèna xè proteta, ma te podi vedar el suo codexe sorjente.\');
+ ta[\'ca-history\'] = new Array(\'h\',\'Verzsion preçedenti de sta paxèna.\');
+ ta[\'ca-protect\'] = new Array(\'=\',\'Protedj sta paxèna\');
+ ta[\'ca-delete\'] = new Array(\'d\',\'Scanceła sta paxèna\');
+ ta[\'ca-undelete\'] = new Array(\'d\',\'Ripristina la paxèna come l\'era prima de ła scancełazsion\');
+ ta[\'ca-move\'] = new Array(\'m\',\'Sposta sta paxèna a un altro titoło\');
+ ta[\'ca-nomove\'] = new Array(\'\',\'Non te ghè el permezso de spostar sta paxèna\');
+ ta[\'ca-watch\'] = new Array(\'w\',\'Xonta sta paxèna a l\'elenco de łe paxène che te tegni soto ocio\');
+ ta[\'ca-unwatch\'] = new Array(\'w\',\'Cava sta paxèna da l\'elenco de łe paxène che te tegni soto ocio\');
+ ta[\'search\'] = new Array(\'f\',\'Serca sta wiki\');
+ ta[\'p-logo\'] = new Array(\'\',\'Paxèna prinzsipałe\');
+ ta[\'n-mainpage\'] = new Array(\'z\',\'Visita la Paxèna prinzsipałe\');
+ ta[\'n-portal\'] = new Array(\'\',\'Descrizsion del projeto, cosa te podi far, e dove trovar le robe\');
+ ta[\'n-currentevents\'] = new Array(\'\',\'Eventi de atuałità\');
+ ta[\'n-recentchanges\'] = new Array(\'r\',\'La lista de le ultime modifiche a sta wiki.\');
+ ta[\'n-randompage\'] = new Array(\'x\',\'Mostra na paxèna a caso\');
+ ta[\'n-help\'] = new Array(\'\',\'Raccolta de manuałi.\');
+ ta[\'n-sitesupport\'] = new Array(\'\',\'Iútane\');
+ ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Lista de tute le paxène che le porta a sta\' quà\');
+ ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Lista de le ultime modifiche a le paxène linkae da sta quà.\');
+ ta[\'feed-rss\'] = new Array(\'\',\'RSS feed for this page\');
+ ta[\'feed-atom\'] = new Array(\'\',\'Atom feed for this page\');
+ ta[\'t-contributions\'] = new Array(\'\',\'Lista de i contributi de sto utente\');
+ ta[\'t-emailuser\'] = new Array(\'\',\'Manda n\'E.mail a sto utente\');
+ ta[\'t-upload\'] = new Array(\'u\',\'Meti imagini o file multimediałi su {{SITENAME}}\');
+ ta[\'t-specialpages\'] = new Array(\'q\',\'Lista de tute łe paxène speciali\');
+ ta[\'ca-nstab-main\'] = new Array(\'c\',\'Varda la voçe rełativa\');
+ ta[\'ca-nstab-user\'] = new Array(\'c\',\'Varda la paxèna utente\');
+ ta[\'ca-nstab-media\'] = new Array(\'c\',\'Vedi la paxèna de el file multimediale\');
+ ta[\'ca-nstab-special\'] = new Array(\'\',\'Sta quà xè na paxèna speciale, non la pode essere modificà.\');
+ ta[\'ca-nstab-project\'] = new Array(\'a\',\'Varda la paxèna del projeto\');
+ ta[\'ca-nstab-image\'] = new Array(\'c\',\'Varda la paxèna dell\'imagine\');
+ ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Varda el messajo de sistema\');
+ ta[\'ca-nstab-template\'] = new Array(\'c\',\'Varda el template\');
+ ta[\'ca-nstab-help\'] = new Array(\'c\',\'Varda la paxèna de aiuto\');
+ ta[\'ca-nstab-category\'] = new Array(\'c\',\'Varda la paxèna de la categoria\');',
+'deletedrevision' => 'Vecia verzsion scancełà $1',
+'nextdiff' => 'Next diff →',
+'imagemaxsize' => 'Limita łe imagini o łe paxène de descrizsion de łe imagini a:',
+'newimages' => 'Imagini nove',
+'noimages' => 'Non ghè gnente da vardare.',
+'speciallogtitlelabel' => 'Titolo',
+'passwordtooshort' => 'La to password l\'è massa breve. La deve contegnere almanco $1 caratteri.',
+'mediawarning' => '\'\'\'Warning\'\'\': This file may contain malicious code, by executing it your system may be compromised.<hr />',
+'fileinfo' => 'Dimenzsion: $1 KB, Tipo MIME: <code>$2</code>',
+'metadata' => 'Metadata',
+'metadata-help' => 'This file contains additional information, probably added from the digital camera or scanner used to create or digitize it. If the file has been modified from its original state, some details may not fully reflect the modified image.',
+'metadata-expand' => 'Show extended details',
+'metadata-collapse' => 'Hide extended details',
+'exif-imagewidth' => 'Larghezsa',
+'exif-imagelength' => 'Altezsa',
+'exif-bitspersample' => 'Bit par campione',
+'exif-compression' => 'Meccanismo de comprezsion',
+'exif-photometricinterpretation'=> 'Strutura de i pixel',
+'exif-samplesperpixel' => 'Numero de łe componenti',
+'exif-planarconfiguration'=> 'Disposizsion de i dati',
+'exif-ycbcrsubsampling' => 'Raporto de campionamento Y / C',
+'exif-ycbcrpositioning' => 'Posizsionamento componenti Y e C',
+'exif-xresolution' => 'Risoluzsion orixontałe',
+'exif-yresolution' => 'Risoluzsion verticałe',
+'exif-resolutionunit' => 'Unità de mixura rizsoluzsion X e Y',
+'exif-stripoffsets' => 'Posizsion de i dati imagine',
+'exif-rowsperstrip' => 'Numero righe par striscia',
+'exif-stripbytecounts' => 'Numero de byte par strizsia compressa',
+'exif-jpeginterchangeformat'=> 'Posizsion byte SOI JPEG',
+'exif-jpeginterchangeformatlength'=> 'Numero de byte de dati JPEG',
+'exif-transferfunction' => 'Funzsione de trasferimento',
+'exif-whitepoint' => 'Coordinate cromatiche de el punto de bianco',
+'exif-primarychromaticities'=> 'Coordinate cromatiche de i cołori primari',
+'exif-ycbcrcoefficients'=> 'Coeficienti matriçe de trasformazsion spazsi de i cołori',
+'exif-referenceblackwhite'=> 'Copia de vałori de riferimento (nero e bianco)',
+'exif-datetime' => 'Data e ora de modifica de el file',
+'exif-imagedescription' => 'Descrizsion de l\'imagine',
+'exif-make' => 'Produtore fotocamera',
+'exif-model' => 'Modeło fotocamera',
+'exif-copyright' => 'nformazsion su el copyright',
+'exif-exifversion' => 'Verzsion de el formato Exif',
+'exif-flashpixversion' => 'Verzsione Flashpix supportà',
+'exif-colorspace' => 'Spazio de i cołori',
+'exif-componentsconfiguration'=> 'Significato de ciascuna componente',
+'exif-compressedbitsperpixel'=> 'Modalità de compression imagine',
+'exif-pixelydimension' => 'Larghezsa efetiva imagine',
+'exif-pixelxdimension' => 'Altezsa efetiva imagine',
+'exif-makernote' => 'Note de el produtore',
+'exif-usercomment' => 'Note de l\'utente',
+'exif-relatedsoundfile' => 'File audio cołegà',
+'exif-datetimeoriginal' => 'Data e ora de creazsion de i dati',
+'exif-datetimedigitized'=> 'Data e ora de digitałixazsion',
+'exif-subsectime' => 'Data e ora, frazsion de secondo',
+'exif-subsectimeoriginal'=> 'Data e ora de creazsion, frazsion de secondo',
+'exif-subsectimedigitized'=> 'Data e ora de digitałixazsion, frazsion de secondo',
+'exif-exposuretime' => 'Tempo de esposizsion',
+'exif-fnumber' => 'Rapporto focałe',
+'exif-exposureprogram' => 'Programa de esposizsion',
+'exif-spectralsensitivity'=> 'Sensibilità spetrałe',
+'exif-isospeedratings' => 'Sensibiłità ISO',
+'exif-oecf' => 'Fattore de converzsion optoełetronica',
+'exif-shutterspeedvalue'=> 'Tenpo de esposizsion',
+'exif-exposurebiasvalue'=> 'Corezsion esposizsion',
+'exif-maxaperturevalue' => 'Mazsima vérta',
+'exif-subjectdistance' => 'Distanzsa de el sojeto',
+'exif-meteringmode' => 'Metodo de misurazsion',
+'exif-lightsource' => 'Sorgente łuminoxa',
+'exif-flash' => 'Caratteristiche e stato de el flash',
+'exif-focallength' => 'Distanzsa focałe obiettivo',
+'exif-subjectarea' => 'Area inquadrante el sojeto',
+'exif-spatialfrequencyresponse'=> 'Risposta in frequenzsa spazsiałe',
+'exif-focalplanexresolution'=> 'Risoluzsion X sul piano focałe',
+'exif-focalplaneyresolution'=> 'Risoluzsion Y sul piano focałe',
+'exif-focalplaneresolutionunit'=> 'Unità de misura risoluzsion sul piano focałe',
+'exif-subjectlocation' => 'Posizsion de el sojeto',
+'exif-exposureindex' => 'Sensibilità impostà',
+'exif-sensingmethod' => 'Metodo de riłevazsion',
+'exif-scenetype' => 'Tipo de inquadratura',
+'exif-cfapattern' => 'Disposizione filtro cołore',
+'exif-customrendered' => 'Elaborazsion personałixà',
+'exif-exposuremode' => 'Modalità de espoxizsion',
+'exif-whitebalance' => 'Biłanciamento de el bianco',
+'exif-digitalzoomratio' => 'Rapporto zoom digitałe',
+'exif-focallengthin35mmfilm'=> 'Focałe equivalente su 35 mm',
+'exif-scenecapturetype' => 'Tipo de acquixizsion',
+'exif-gaincontrol' => 'Controło inquadratura',
+'exif-contrast' => 'Controło contrasto',
+'exif-saturation' => 'Controło saturazsion',
+'exif-sharpness' => 'Controło nitidezsa',
+'exif-devicesettingdescription'=> 'Descrizsion impostazsioni dispositivo',
+'exif-subjectdistancerange'=> 'Scała distanzsa sojeto',
+'exif-imageuniqueid' => 'ID univoco imagine',
+'exif-gpsversionid' => 'Verzsion de i tag GPS',
+'exif-gpsaltituderef' => 'Riferimento par l\'altitudine',
+'exif-gpstimestamp' => 'Ora GPS (orołogio atomico)',
+'exif-gpssatellites' => 'Satelliti usai par ła mixurazsion',
+'exif-gpsstatus' => 'Stato de el riçevitore',
+'exif-gpsmeasuremode' => 'Modalità de misurazsion',
+'exif-gpsdop' => 'Precixion de ła mixurazsion',
+'exif-gpsspeedref' => 'Unità de mixura de ła veloçità',
+'exif-gpsspeed' => 'Veloçità del riçevitore GPS',
+'exif-gpstrackref' => 'Riferimento par ła direzsion movimento',
+'exif-gpstrack' => 'Direzsion de el movimento',
+'exif-gpsimgdirectionref'=> 'Riferimento par ła direzsion de l\'imagine',
+'exif-gpsimgdirection' => 'Direzsion de l\'immagine',
+'exif-gpsmapdatum' => 'Rilevamento geodetico usà',
+'exif-gpsdestlatituderef'=> 'Riferimento par ła latitudine de ła destinazsion',
+'exif-gpsdestlatitude' => 'Latitudine de ła destinazsion',
+'exif-gpsdestlongituderef'=> 'Riferimento par ła longitudine de ła destinazsion',
+'exif-gpsdestlongitude' => 'Longitudine de ła destinazsion',
+'exif-gpsdestbearingref'=> 'Riferimento par ła direzsion de ła destinazsion',
+'exif-gpsdestbearing' => 'Direzsion de ła destinazsion',
+'exif-gpsdestdistanceref'=> 'Riferimento par ła distanzsa de ła destinazsion',
+'exif-gpsdestdistance' => 'Distanzsa de ła destinazsion',
+'exif-gpsprocessingmethod'=> 'Nome de el metodo de elaborazsion GPS',
+'exif-gpsareainformation'=> 'Nome de ła xòna GPS',
+'exif-gpsdifferential' => 'Corezsion diferenzsiałe GPS',
+'exif-orientation-1' => 'Normałe',
+'exif-orientation-2' => 'Roerzsà orixontalmente',
+'exif-orientation-3' => 'Ruotà de 180°',
+'exif-orientation-4' => 'Roersà verticalmente',
+'exif-orientation-5' => 'Ruotà 90° in senso antiorario e roersà verticalmente',
+'exif-orientation-6' => 'Ruotà 90° in senso orario',
+'exif-orientation-7' => 'Ruotà 90° in senso orario e capovolto verticalmente',
+'exif-orientation-8' => 'Ruotà 90° in senso antiorario',
+'exif-planarconfiguration-1'=> 'a blochi (chunky)',
+'exif-xyresolution-i' => '$1 punti par połiçe (dpi)',
+'exif-xyresolution-c' => '$1 punti par çentimetro (dpc)',
+'exif-exposureprogram-0'=> 'Non definio',
+'exif-exposureprogram-1'=> 'Manuałe',
+'exif-exposureprogram-4'=> 'Priorità all\'esposizsion',
+'exif-exposureprogram-5'=> 'Artistico (orientà a ła profondità de campo)',
+'exif-exposureprogram-6'=> 'Sportivo (orientà a ła veloçità de riprexa)',
+'exif-meteringmode-0' => 'Sconozsuo',
+'exif-meteringmode-2' => 'Media pesà çentrà',
+'exif-meteringmode-6' => 'Parzsiałe',
+'exif-lightsource-0' => 'Sconozsua',
+'exif-lightsource-1' => 'Luçe diurna',
+'exif-lightsource-2' => 'Lampada a floreçenzsa',
+'exif-lightsource-3' => 'Lampada al tungsteno (a incandeçenzsa)',
+'exif-lightsource-9' => 'Tenpo beło',
+'exif-lightsource-10' => 'Nùvoło',
+'exif-lightsource-11' => 'In ombrìa',
+'exif-lightsource-12' => 'Daylight fluorescent (D 5700 – 7100K)',
+'exif-lightsource-13' => 'Day white fluorescent (N 4600 – 5400K)',
+'exif-lightsource-14' => 'Cool white fluorescent (W 3900 – 4500K)',
+'exif-lightsource-15' => 'White fluorescent (WW 3200 – 3700K)',
+'exif-lightsource-17' => 'Luçe standard A',
+'exif-lightsource-18' => 'Luçe standard B',
+'exif-lightsource-19' => 'Luçe standard C',
+'exif-lightsource-20' => 'Iłuminante D55',
+'exif-lightsource-21' => 'Iłuminante D65',
+'exif-lightsource-22' => 'Iłuminante D75',
+'exif-lightsource-23' => 'Iłuminante D50',
+'exif-lightsource-255' => 'Altra sorgente łuminoxa',
+'exif-focalplaneresolutionunit-2'=> 'połiçi',
+'exif-sensingmethod-1' => 'Non definio',
+'exif-sensingmethod-2' => 'Sensore area cołore a 1 chip',
+'exif-sensingmethod-3' => 'Sensore area cołore a 2 chip',
+'exif-sensingmethod-4' => 'Sensore area cołore a 3 chip',
+'exif-sensingmethod-5' => 'Sensore area cołore sequenzsiałe',
+'exif-sensingmethod-7' => 'Sensore triłineare',
+'exif-sensingmethod-8' => 'Sensore łineare cołore sequenzsiałe',
+'exif-scenetype-1' => 'Fotografia direta',
+'exif-customrendered-0' => 'Processo normałe',
+'exif-customrendered-1' => 'Processo personałixà',
+'exif-exposuremode-0' => 'Esposizsion automatega',
+'exif-exposuremode-1' => 'Esposizsion manuałe',
+'exif-exposuremode-2' => 'Bracketing automatego',
+'exif-whitebalance-0' => 'Biłanciamento de el bianco automatico',
+'exif-whitebalance-1' => 'Biłanciamento de el bianco manuałe',
+'exif-scenecapturetype-2'=> 'Ritrato',
+'exif-scenecapturetype-3'=> 'Noturna',
+'exif-gaincontrol-1' => 'Enfasi par basso guadagno',
+'exif-gaincontrol-2' => 'Enfasi par alto guadagno',
+'exif-gaincontrol-3' => 'Deenfasi par basso guadagno',
+'exif-gaincontrol-4' => 'Deenfasi par alto guadagno',
+'exif-contrast-0' => 'Normałe',
+'exif-saturation-0' => 'Normałe',
+'exif-saturation-1' => 'Bassa saturazsion',
+'exif-saturation-2' => 'Alta saturazsion',
+'exif-sharpness-0' => 'Normałe',
+'exif-sharpness-1' => 'Minore nitidezsa',
+'exif-sharpness-2' => 'Major nitidezsa',
+'exif-subjectdistancerange-0'=> 'Sconozsua',
+'exif-subjectdistancerange-2'=> 'Sojeto viçin',
+'exif-subjectdistancerange-3'=> 'Sojeto łontano',
+'exif-gpsstatus-a' => 'Mixurazsion in corzso',
+'exif-gpsstatus-v' => 'Mixurazsion interoperabiłe',
+'exif-gpsmeasuremode-2' => 'Misurazsion bidimensionałe',
+'exif-gpsmeasuremode-3' => 'Misurazsion tridimensionałe',
+'exif-gpsspeed-k' => 'Chiłometri orari',
+'exif-gpsdirection-t' => 'Direzsion reałe',
+'exif-gpsdirection-m' => 'Direzsion magnetica',
+'edit-externally' => 'Modifica stò file usando un programma esterno',
+'edit-externally-help' => 'Per maggiori informazioni varda le [http://meta.wikimedia.org/wiki/Help:External_editors istruzsioni] (in inglese)',
+'namespacesall' => 'all',
+'confirmemail' => 'Conferma indirizso e-mail',
+'confirmemail_text' => 'Stà wiki richiede che el to indirizso email vengna verificà prima de poder usare le funzsioni connesse all\'email. Struca el botton sotto par inviare na mail de conferma al to indirizso. La mail include un link contenente un codice; inseriszi el link nel to browser par confermar che el to indirizso email xè valido.',
+'confirmemail_send' => 'Spedisi un codice de conferma via mail.',
+'confirmemail_sent' => 'Email de conferma invià.',
+'confirmemail_sendfailed'=> 'Impossibiłe inviar na mail de conferma. Controła che l\'indirizso non contengna caratteri non vałidi.',
+'confirmemail_invalid' => 'Codice de conferma non valido. El codice podarìa esser scadù.',
+'confirmemail_needlogin'=> 'Xè necessario $1 par confermare el proprio indirizso e-mail.',
+'confirmemail_success' => 'El to indirizso email l\'è stato confermà. Ora te podi loggarte e gòderte la wiki.',
+'confirmemail_loggedin' => 'El to indirizso email xè stà confermà.',
+'confirmemail_error' => 'Qualcosa l\'è andà storto nel salvar la to conferma.',
+'confirmemail_subject' => '{{SITENAME}}: email par la conferma dell\'indirizso',
+'confirmemail_body' => 'Qualcuno, probabilmente ti stesso dall\'indirizso IP $1, ga registrà n\'account "$2" con sto indirizso e-mail su {{SITENAME}}.
+
+Par confermar che deto account realmente el te apartegne e poder attivar łe opzsioni relative a łe e-mail su {{SITENAME}}, apri el cołegamento seguente con el to browser:
+
+$3
+
+Se l\'account *non* xè el tuo, non visitare el cołegamento. El codexe de conferma scadrà a łe $4.',
+'createarticle' => 'Crea voçe',
+'deletedwhileediting' => 'Attenzsion: Sta paxèna xè stà scancełà dopo che te ghè scominzsià a modificarla!',
+'confirmrecreate' => 'L\'utente [[User:$1|$1]] ([[User talk:$1|discussion]]) ga scancełà sta voçe dopo che te ghè inizsià a modificarla, con ła seguente motivazsion: \'\'$2\'\'
+Per favore conferma che te vołi veramente ricrear sta voçe.',
+'tooltip-recreate' => 'Ricrea ła paxèna anca se xè stà scancełà',
+'confirm_purge' => 'Vóto scancełar ła cache in sta paxèna?
+
+$1',
+'confirm_purge_button' => 'OK',
+'searchcontaining' => 'Riçerca de łe voçi che contegne \'\'$1\'\'.',
+'articletitles' => 'Rizserca de łe voçi che łe inizsia par \'\'$1\'\'',
+'hideresults' => 'Hide results',
+'displaytitle' => '(Par i cołegamenti a sta paxèna, usare [[$1]])',
+);
+?>
diff --git a/languages/messages/MessagesVi.php b/languages/messages/MessagesVi.php
new file mode 100644
index 000000000000..db0e7316ed4b
--- /dev/null
+++ b/languages/messages/MessagesVi.php
@@ -0,0 +1,1344 @@
+<?php
+/**
+ * Based on Language.php 1.645
+ * @package MediaWiki
+ * @subpackage Language
+ * Compatible to MediaWiki 1.5
+ * Initial translation by Trần Thế Trung and Nguyễn Thanh Quang
+ * Last update 28 August 2005 (UTC)
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Phương_tiện',
+ NS_SPECIAL => 'Đặc_biệt',
+ NS_MAIN => '',
+ NS_TALK => 'Thảo_luận',
+ NS_USER => 'Thành_viên',
+ NS_USER_TALK => 'Thảo_luận_Thành_viên',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Thảo_luận_$1',
+ NS_IMAGE => 'Hình',
+ NS_IMAGE_TALK => 'Thảo_luận_Hình',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Thảo_luận_MediaWiki',
+ NS_TEMPLATE => 'Tiêu_bản',
+ NS_TEMPLATE_TALK => 'Thảo_luận_Tiêu_bản',
+ NS_HELP => 'Trợ_giúp',
+ NS_HELP_TALK => 'Thảo_luận_Trợ_giúp',
+ NS_CATEGORY => 'Thể_loại',
+ NS_CATEGORY_TALK => 'Thảo_luận_Thể_loại'
+);
+
+$quickbarSettings = array(
+ 'Không', 'Trái', 'Phải', 'Nổi bên trái'
+);
+
+$skinNames = array(
+ 'standard' => 'Cổ điển',
+ 'nostalgia' => 'Vọng cổ',
+ 'myskin' => 'Cá nhân'
+);
+
+$magicWords = array(
+ 'redirect' => array( 0, '#redirect' , '#đổi' ),
+ 'notoc' => array( 0, '__NOTOC__' , '__KHÔNGMỤCMỤC__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__', '__LUÔNMỤCLỤC__' ),
+ 'toc' => array( 0, '__TOC__' , '__MỤCLỤC__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__', '__KHÔNGSỬAMỤC__' ),
+ 'start' => array( 0, '__START__' , '__BẮTĐẦU__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH' , 'THÁNGNÀY' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME' , 'TÊNTHÁNGNÀY' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN' , 'TÊNDÀITHÁNGNÀY' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV' , 'TÊNNGẮNTHÁNGNÀY' ),
+ 'currentday' => array( 1, 'CURRENTDAY' , 'NGÀYNÀY' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME' , 'TÊNNGÀYNÀY' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR' , 'NĂMNÀY' ),
+ 'currenttime' => array( 1, 'CURRENTTIME' , 'GIỜNÀY' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES' , 'SỐBÀI' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES' , 'SỐTẬPTIN' ),
+ 'pagename' => array( 1, 'PAGENAME' , 'TÊNTRANG' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE' , 'TÊNTRANG2' ),
+ 'namespace' => array( 1, 'NAMESPACE' , 'KHÔNGGIANTÊN' ),
+ 'msg' => array( 0, 'MSG:' , 'NHẮN:' ),
+ 'subst' => array( 0, 'SUBST:' , 'THẾ:' ),
+ 'msgnw' => array( 0, 'MSGNW:' , 'NHẮNMỚI:' ),
+ 'end' => array( 0, '__END__' , '__KẾT__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' , 'nhỏ' ),
+ 'img_right' => array( 1, 'right' , 'phải' ),
+ 'img_left' => array( 1, 'left' , 'trái' ),
+ 'img_none' => array( 1, 'none' , 'không' ),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre' , 'giữa' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame' , 'khung'),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME' , 'TÊNMẠNG' ),
+ 'ns' => array( 0, 'NS:' ),
+ 'localurl' => array( 0, 'LOCALURL:' ),
+ 'localurle' => array( 0, 'LOCALURLE:' ),
+ 'server' => array( 0, 'SERVER' , 'MÁYCHỦ' ),
+ 'servername' => array( 0, 'SERVERNAME' , 'TÊNMÁYCHỦ' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH' , '' ),
+ 'grammar' => array( 0, 'GRAMMAR:' , 'NGỮPHÁP' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__',
+'__NOTC__', '__KHÔNGCHUYỂNTÊN__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__',
+'__NOCC__', '__KHÔNGCHUYỂNNỘIDUNG__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK' , 'TUẦNNÀY' ),
+ 'currentdow' => array( 1, 'CURRENTDOW' ),
+ 'revisionid' => array( 1, 'REVISIONID' , 'SỐBẢN' ),
+ );
+
+$datePreferences = array(
+ 'default',
+ 'vi normal',
+ 'vi longmonth',
+ 'vi shortcolon',
+ 'vi short',
+ 'ISO 8601',
+);
+
+$defaultDateFormat = 'vi normal';
+
+$dateFormats = array(
+ 'vi normal time' => 'H:i',
+ 'vi normal date' => '"ngày" j M "năm" Y',
+ 'vi normal both' => 'H:i, "ngày" j M "năm" Y',
+
+ 'vi longmonth time' => 'H:i',
+ 'vi longmonth date' => '"ngày" j F "năm" Y',
+ 'vi longmonth both' => 'H:i, "ngày" j F "năm" Y',
+
+ 'vi shortcolon time' => 'H:i',
+ 'vi shortcolon date' => 'j/n/Y',
+ 'vi shortcolon both' => 'H:i, j/n/Y',
+
+ 'vi short time' => 'H"h"i',
+ 'vi short date' => 'j/n/Y',
+ 'vi short both' => 'H"h"i, j/n/Y',
+);
+
+$datePreferenceMigrationMap = array(
+ 'default',
+ 'vi normal',
+ 'vi normal',
+ 'vi normal',
+);
+
+
+$linkTrail = "/^([a-zàâçéèêîôûäëïöüùÇÉÂÊÎÔÛÄËÏÖÜÀÈÙ]+)(.*)$/sDu";
+$separatorTransformTable = array(',' => '.', '.' => ',' );
+
+
+$messages = array(
+# User Toggles
+
+'tog-editwidth' => 'Cửa sổ soạn thảo mở rộng',
+'tog-editondblclick' => 'Nhấn đúp để soạn thảo trang (JavaScript)',
+'tog-editsection' => 'Bấm liên kết [sửa] để soạn bài',
+'tog-editsectiononrightclick' => 'Bấm góc phải cạnh đề mục để soạn mục này (JavaScript)',
+'tog-fancysig' => 'Chữ ký không có liên kết đến trang cá nhân',
+'tog-hideminor' => 'Giấu <i>thay đổi</i> nhỏ',
+'tog-justify' => 'Căn đều hai bên đoạn văn',
+'tog-minordefault' => 'Các soạn thảo của tôi được mặc định là thay đổi nhỏ',
+'tog-nocache' => 'Không lưu trang trong bộ nhớ đệm',
+'tog-numberheadings' => 'Đánh số tự động các đề mục',
+'tog-previewonfirst' => 'Luôn xem thử trước khi lưu soạn thảo',
+'tog-previewontop' => 'Phần xem thử nằm trên hộp soạn thảo',
+'tog-rememberpassword' => 'Nhớ mật khẩu của tôi (cookie)',
+'tog-showtoc' => 'Hiển thị mục lục (cho bài có trên 3 đề mục)',
+'tog-showtoolbar' => 'Hiển thị thanh soạn thảo (JavaScript)',
+'tog-usenewrc' => 'Thay đổi gần đây nhiều chức năng (JavaScript)',
+'tog-underline' => 'Gạch chân liên kết',
+'tog-watchdefault' => 'Tự động theo dõi bài tôi viết hoặc sửa',
+'tog-highlightbroken' => 'Liên kết đến trang chưa có <a href="" class="new">như này</a> (nếu không thì <a href="" class="internal">như này</a>).',
+'tog-enotifminoredits' => 'Gửi thông báo cho tôi về cả sửa đổi nhỏ',
+'tog-enotifrevealaddr' => 'Thể hiện địa chỉ thư của tôi trong thư thông báo',
+'tog-enotifusertalkpages' => 'Gửi tôi thông báo khi trang thảo luận với tôi thay đổi',
+'tog-enotifwatchlistpages' => 'Gửi tôi thông báo về thay đổi của trang',
+'tog-externaldiff' => 'Mặc định dùng so sánh bên ngoài',
+'tog-externaleditor' => 'Mặc định dùng soạn thảo bên ngoài',
+'tog-shownumberswatching' => 'Xem số người xem',
+
+'underline-always' => 'Luôn',
+'underline-default' => 'Mặc định của trình duyệt',
+'underline-never' => 'Không bao giờ',
+
+# Dates
+'sunday' => 'chủ nhật',
+'monday' => 'thứ hai',
+'tuesday' => 'thứ ba',
+'wednesday' => 'thứ tư',
+'thursday' => 'thứ năm',
+'friday' => 'thứ sáu',
+'saturday' => 'thứ bảy',
+'january' => 'tháng Một',
+'february' => 'tháng Hai',
+'march' => 'tháng Ba',
+'april' => 'tháng Tư',
+'may_long' => 'tháng Năm',
+'june' => 'tháng Sáu',
+'july' => 'tháng Bảy',
+'august' => 'tháng Tám',
+'september' => 'tháng Chín',
+'october' => 'tháng Mười',
+'november' => 'tháng Mười một',
+'december' => 'tháng Mười hai',
+'jan' => 'tháng 1',
+'feb' => 'tháng 2',
+'mar' => 'tháng 3',
+'apr' => 'tháng 4',
+'may' => 'tháng 5',
+'jun' => 'tháng 6',
+'jul' => 'tháng 7',
+'aug' => 'tháng 8',
+'sep' => 'tháng 9',
+'oct' => 'tháng 10',
+'nov' => 'tháng 11',
+'dec' => 'tháng 12',
+
+# Bits of text used by many pages:
+'categories' => 'Thể loại',
+'pagecategories' => 'Thể loại',
+'category_header' => 'Các bài trong Thể loại "$1"',
+'subcategories' => 'Tiểu thể loại',
+'subcategorycount' => 'Thể loại này có $1 tiểu thể loại.',
+'allarticles' => 'Mọi bài',
+'mainpage' => 'Trang đầu',
+'mainpagetext' => 'Phần mềm {{SITENAME}} đã cài đặt.',
+'portal' => 'Cộng đồng',
+'portal-url' => '{{ns:4}}:Cộng_đồng',
+'about' => 'Giới thiệu',
+'aboutsite' => 'Giới thiệu {{SITENAME}}',
+'aboutpage' => '{{ns:4}}:Giới_thiệu',
+'article' => 'Bài',
+'help' => 'Trợ giúp',
+'helppage' => '{{ns:4}}:Trợ giúp',
+'bugreports' => 'Báo lỗi',
+'bugreportspage' => '{{ns:4}}:Báo lỗi',
+'sitesupport' => 'Quyên góp',
+'faq' => 'FAQ',
+'faqpage' => '{{ns:4}}:FAQ',
+'edithelp' => 'Trợ giúp',
+'edithelppage' => 'Trợ_giúp:Soạn thảo',
+'cancel' => 'Bỏ',
+'qbfind' => 'Tìm kiếm',
+'qbbrowse' => 'Dẫn lái',
+'qbedit' => 'Sửa',
+'qbpageoptions' => 'Lựa chọn',
+'qbpageinfo' => 'Thông tin',
+'qbmyoptions' => 'Lựa chọn của tôi',
+'qbspecialpages' => 'Trang đặc biệt',
+'moredotdotdot' => 'Thêm nữa...',
+'mypage' => 'Trang của tôi',
+'mytalk' => 'Thảo luận với tôi',
+'anontalk' => 'Thảo luận với IP này',
+'navigation' => 'Dẫn lái',
+'currentevents' => 'Thời sự',
+'disclaimers' => 'Cảnh báo',
+'disclaimerpage' => '{{ns:4}}:Cảnh báo chung',
+'errorpagetitle' => 'Lỗi',
+'returnto' => 'Quay lại $1.',
+'tagline' => 'Bài từ dự án mở {{SITENAME}}.',
+'whatlinkshere' => 'Liên kết tới đây',
+'help' => 'Trợ giúp',
+'search' => 'Tìm kiếm',
+'searchbutton' => 'Tìm kiếm',
+'history' => 'Lịch sử',
+'printableversion' => 'Bản để in',
+'edit' => 'Sửa',
+'editthispage' => 'Sửa trang này',
+'delete' => 'Xóa',
+'deletethispage' => 'Xóa trang này',
+'undelete_short' => 'Phục hồi',
+'protect' => 'Khóa',
+'protectthispage' => 'Khóa trang này',
+'unprotect' => 'Mở',
+'unprotectthispage' => 'Mở trang này',
+'newpage' => 'Trang mới',
+'talkpage' => 'Trang thảo luận',
+'specialpage' => 'Trang đặc biệt',
+'personaltools' => 'Công cụ cá nhân',
+'postcomment' => 'Thêm bàn luận',
+'articlepage' => 'Xem bài',
+'talk' => 'Thảo luận',
+'toolbox' => 'Công cụ',
+'userpage' => 'Trang thành viên',
+'projectpage' => 'Trang Wikipedia',
+'imagepage' => 'Trang hình',
+'viewtalkpage' => 'Trang thảo luận',
+'otherlanguages' => 'Ngôn ngữ khác',
+'redirectedfrom' => '(đổi hướng từ $1)',
+'lastmodifiedat' => 'Lần sửa cuối : $2, $1.',
+'viewcount' => 'Trang này đã được đọc $1 lần.',
+'copyright' => 'Bản quyền $1.',
+'protectedpage' => 'Trang bị khóa',
+'nbytes' => '$1 byte',
+'go' => 'Xem',
+'searcharticle' => 'Xem',
+'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'history' => 'Lịch sử trang',
+'history_short' => 'Lịch sử',
+'retrievedfrom' => 'Lấy từ « $1 »',
+'newmessageslink' => 'tin nhắn mới',
+'editsection' => 'Sửa',
+'editold' => 'Sửa',
+'toc' => 'Mục lục',
+'showtoc' => 'xem',
+'hidetoc' => 'giấu',
+'thisisdeleted' => 'Xem hay phục hồi $1 ?',
+'restorelink' => 'Phục hồi 1 sửa đổi',
+'feedlinks' => 'Nạp:',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Bài',
+'nstab-user' => 'Trang thành viên',
+'nstab-media' => 'Phương tiện',
+'nstab-special' => 'Đặc biệt',
+'nstab-project' => 'Giới thiệu',
+'nstab-image' => 'Hình',
+'nstab-mediawiki' => 'Tin nhắn',
+'nstab-template' => 'Tiêu bản',
+'nstab-help' => 'Trợ giúp',
+'nstab-category' => 'Thể loại',
+
+# Main script and global functions
+'nosuchaction' => 'Không hiểu',
+'nosuchactiontext' => 'Phần mềm không hiểu bạn muốn làm gì.',
+'nosuchspecialpage' => 'Không tìm thấy',
+'nospecialpagetext' => 'Không có trang đặc biệt này.',
+
+# General errors
+'error' => 'Lỗi',
+'badaccess' => 'Lỗi truy cập',
+'databaseerror' => 'Lỗi cơ sở dữ liệu',
+'dberrortext' => "Lỗi cú pháp trong cơ sở dữ liệu. Truy vấn vừa rồi là:
+<blockquote><tt>$1</tt></blockquote>
+từ hàm \"<tt>$2</tt>\".
+MySQL báo lỗi \"<tt>$3: $4</tt>\".",
+'dberrortextcl' => 'Một truy vấn cơ sở dữ liệu có lỗi cú pháp. Truy vấn vừa rồi là:
+"$1"
+thực hiện bởi hàm "$2"
+MySQL báo lỗi "$3 : $4".',
+'noconnect' => "Hiện tại không kết nối với cơ sở dữ liệu được.",
+'nodb' => 'Không thấy cơ sở dữ liệu $1',
+'cachederror' => 'Đây là bản sao của trang bạn yêu cầu, có thể không cập nhật.',
+'readonly' => 'Cơ sở dữ liệu bị khóa',
+'enterlockreason' => 'Nêu lý do khóa, thời gian khóa',
+'readonlytext' => "Cơ sở dữ liệu {{SITENAME}} hiện bị khóa, có thể để bảo trì, sau đó sẽ trở lại bìn thường. Lý do khóa :
+<p>$1",
+'missingarticle' => 'Cơ sở dữ liệu không thấy trang "$1".
+Đây không phải lỗi cơ sở dữ liệu, mà có thể là lỗi phần mềm.
+Xin báo lỗi này cho người quản lý, nói rõ tên trang bị lỗi.',
+'internalerror' => 'Lỗi nội bộ',
+'filecopyerror' => 'Không sao chép « $1 » đến « $2 » được.',
+'fileinfo' => '$1Ko, type MIME: <tt>$2</tt>',
+'filerenameerror' => 'Không đổi tên « $1 » đến « $2 » được.',
+'filedeleteerror' => 'Không xóa « $1 » được.',
+'filenotfound' => 'Không thấy "$1".',
+'unexpected' => 'Chưa ngờ tới : "$1"="$2".',
+'formerror' => 'Lỗi: không gửi đơn đi được.',
+'badarticleerror' => 'Không thực hiện được hành động như vậy trên trang này.',
+'cannotdelete' => "Không xóa trang được.",
+'badtitle' => 'Đề mục sai',
+'badtitletext' => 'Đề mục sai, rỗng hay liên kết liên ngôn ngữ sai.',
+'laggedslavemode' => 'Chú ý : trang có thể chưa được cập nhật phiên bản cuối.',
+'readonly_lag' => 'Cơ sở dữ liệu bị khóa để các máy chủ cập nhật thông tin của nhau.',
+'perfdisabled' => 'Chức năng này bị khóa vì nó làm chậm cơ sở dữ liệu.',
+'perfdisabledsub' => 'Đây là bản lưu của $1:',
+'viewsource' => 'Xem mã nguồn',
+'protectedtext' => 'Trang này đã bị khóa. Xem [[{{ns:4}}:Trang bị khóa]] để biết các lý do.',
+'allmessagesnotsupportedDB' => 'Đặc biệt:AllMessages không xem được do wgUseDatabaseMessages bị khóa.',
+'allmessagesnotsupportedUI' => 'Đặc biệt:AllMessages không hỗ trợ ngôn ngữ (<b>$1</b>).',
+'wrong_wfQuery_params' => 'Tham số sai trong wfQuery()<br />
+Hàm : $1<br />
+Truy vấn : $2',
+'versionrequired' => 'Cần phiên bản $1 của MediaWiki',
+'versionrequiredtext' => 'Cần phiên bản $1 của MediaWiki để xem trang này. Xem [[Đặc_biệt:Phiên_bản]]',
+'sqlhidden' => '(giấu truy vấn sql)',
+
+# Login and logout pages
+#
+'logouttitle' => 'Đăng xuất',
+'logouttext' => "Bạn đã đang xuất.
+Bạn vẫn dùng {{SITENAME}} được như người vô danh, hoặc đăng nhập lại, có thể dưới tài khoản khác.",
+
+'welcomecreation' => "<h2>Chào mừng, $1!</h2><p>Tài khoản của bạn đã mở. Mời bạn vào trang Lựa chọn cá nhân dành cho bạn.",
+
+'loginpagetitle' => 'Đăng nhập',
+'yourname' => 'Tên',
+'yourpassword' => 'Mật khẩu',
+'yourpasswordagain' => 'Vào lại mật khẩu',
+'remembermypassword' => 'Nhớ mật khẩu (cookie)',
+'loginproblem' => '<b>Trục trặc đăng nhập.</b><br />Mời thử lại!',
+'alreadyloggedin' => '\'\'\'$1, bạn đã đăng nhập rồi!\'\'\'<br />',
+
+'login' => 'Đăng nhập',
+'loginprompt' => 'Bạn cần bật cookie để đăng nhập vào {{SITENAME}}.',
+'userlogin' => 'Mở tài khoản hay đăng nhập',
+'logout' => 'Đăng xuất',
+'userlogout' => 'Đăng xuất',
+'notloggedin' => 'Chưa đăng nhập',
+'createaccount' => 'Mở tài khoản',
+'createaccountmail' => 'qua thư điện tử',
+'badretype' => '2 mật khẩu không khớp.',
+'userexists' => "Tên thành viên đã có người lấy. Xin chọn tên khác.",
+'youremail' => 'Thư điện tử *',
+'yournick' => 'Chữ ký trong thảo luận (dùng ~~~)',
+'yourrealname' => 'Tên thật *',
+'prefs-help-realname' => '* <strong>Tên thật</strong> (tùy): tên này (nếu được nhập) sẽ được dùng trong các đóng góp của bạn.',
+'prefs-help-email' => '* <strong>Thư điện tử</strong> (tùy): người khác có thể gửi thư từ trang này cho bạn mà họ vẫn không biết địa chỉ thư của bạn; địa chỉ thư còn giúp gửi bạn mật khẩu nếu bạn quên.',
+'loginerror' => 'Lỗi đăng nhập',
+'nocookiesnew' => "Tài khoản đã mở, nhưng bạn chưa được đăng nhập. Xin bật cookies và đăng nhập lại.",
+'nocookieslogin' => " Xin bật cookies và đăng nhập lại.",
+'noname' => "Chưa nhập tên.",
+'loginsuccesstitle' => "Đăng nhập thành công.",
+'loginsuccess' => "Bạn đã đăng nhập vào {{SITENAME}} với tên
+\"$1\".",
+'nosuchuser' => "Thành viên \"$1\" không tồn tại. Xin kiểm tra lại tên, hoặc mở tài khoản mới.",
+'nosuchusershort' => 'Không có « $1 ». Xin kiểm tra lại.',
+'wrongpassword' => 'Mật khẩu sai, xin nhập lại.',
+'mailmypassword' => 'Gửi tôi mật khẩu',
+'passwordremindertitle' => "Mật khẩu {{SITENAME}}",
+'passwordremindertext' => "Ai đó (có thể là bạn) có địa chỉ IP $1 đã xin gửi mật khẩu mới tới thư điện tử của bạn. Mật khẩu mới của \"$2\" là \"$3\". Bạn nên đăng nhập và thay đổi mật khẩu này.",
+'noemail' => "Thành viên \"$1\" không có thư điện tử.",
+'passwordsent' => "Mật khẩu mới đã được gửi tới thư điện tử của thành viên \"$1\". Xin đăng nhập ngay khi nhận được.",
+'mailerror' => 'Lỗi gửi thư : $1',
+'acct_creation_throttle_hit' => 'Bạn đã mở $1 tài khoản. Không thể mở thêm được nữa.',
+
+'eauthentsent' => 'Thư xác nhận đã được gửi. Trước khi dùng chức năng nhận thư, bạn cần thực hiện hướng dẫn trong thư xác nhận, để đảm bảo tài khoản thuộc về bạn.',
+'emailauthenticated' => 'Địa chỉ thư điện tử của bạn được xác nhận tại $1.',
+'emailconfirmlink' => 'Xác nhận địa chỉ thư điện tử',
+'emailnotauthenticated' => 'Địa chỉ thư điện tử của bạn chưa được xác nhận. Chức năng thư điện tử chưa bật.',
+
+# Edit page toolbar
+'bold_sample' => 'Chữ đậm',
+'bold_tip' => 'Chữ đậm',
+'italic_sample' => 'Chữ xiên',
+'italic_tip' => 'Chữ xiên',
+'link_sample' => 'Liên kết',
+'link_tip' => 'Liên kết',
+'extlink_sample' => 'http://www.vidu.com liên kết ngoài',
+'extlink_tip' => 'Liên kết ngoài (nhớ http://)',
+'headline_sample' => 'Đề mục',
+'headline_tip' => 'Đề mục cấp 2',
+'math_sample' => 'Nhập công thức toán vào đây',
+'math_tip' => 'Công thức toán (LaTeX)',
+'nowiki_sample' => 'Nhập dòng chữ không theo định dạng wiki vào đây',
+'nowiki_tip' => 'Không theo định dạng wiki',
+'image_sample' => 'Ví dụ.jpg',
+'image_tip' => 'Chèn hình',
+'media_sample' => 'Ví dụ.ogg',
+'media_tip' => 'Liên kết phương tiện',
+'sig_tip' => 'Ký tên có ngày',
+'hr_tip' => 'Dòng kẻ ngang (không nên lạm dụng)',
+
+# Edit pages
+'summary' => 'Tóm tắt&nbsp;',
+'subject' => 'Đề mục',
+'minoredit' => 'Sửa đổi nhỏ',
+'watchthis' => 'Theo dõi bài này',
+'savearticle' => 'Lưu',
+'preview' => 'Xem thử',
+'showpreview' => 'Xem thử',
+'blockedtitle' => 'Thành viên bị chặn',
+"blockedtext" => "Bạn bị chặn bởi $1 vì:<br />$2<p>Bạn có thể liên hệ với $1 hoặc các [[{{ns:4}}:Người quản lý|người quản lý]] khác để thảo luận.",
+'whitelistedittitle' => 'Cần đăng nhập để sửa bài',
+'whitelistedittext' => 'Bạn cần [[Đặc_biệt:Userlogin|đăng nhập]] để viết bài.',
+'whitelistreadtitle' => 'Cần đăng nhập để đọc bài',
+'whitelistreadtext' => 'Bạn cần [[Đặc_biệt:Userlogin|đăng nhập]] để đọc bài.',
+'whitelistacctitle' => 'Bạn không được phép mở tài khoản.',
+'whitelistacctext' => 'Bạn cần [[Đặc_biệt:Userlogin|đăng nhập]] để mở tài khoản.', // Looxix
+'loginreqtitle' => 'Cần nhập tên',
+'accmailtitle' => 'Đã gửi mật khẩu.',
+'accmailtext' => 'Mật khẩu của « $1 » đã được gửi đến $2.',
+
+'newarticle' => '(mới)',
+'newarticletext' => 'Nhập nội dung bài viết vào đây.',
+'anontalkpagetext' => "---- ''Đây là trang thảo luận của một người vô danh (chưa mở tài khoản hoặc không dùng tài khoản). Chúng ta chỉ có thể dùng [[địa chỉ IP]] để liên hệ. Nhiều thành viên có thể có chung địa chỉ này. Nếu bạn, một thành viên vô danh, nhận được tin nhắn không liên quan đến bạn, bạn có thể [[Đặc_biệt:Userlogin|mở tài khoản]] để tránh nhầm lẫn này.",
+'noarticletext' => "(Trang này hiện chưa có gì)",
+'clearyourcache' => "'''Chú ý:''' Sau khi lưu, bạn cần tái truy cập để xem sự thay đổi : Mozilla / Konqueror : ctrl-r, Firefox / IE / Opera : ctrl-f5, Safari : cmd-r.",
+'updated' => '(Cập nhật)',
+'note' => '<strong>Chú ý :</strong>',
+'previewnote' => "Chú ý, đây chỉ là thử nghiệm, chưa lưu!",
+'previewconflict' => "Trang này có vẻ như đã được lưu bởi người khác sau khi bạn bắt đầu sửa.",
+'editing' => 'Soạn thảo $1',
+'editinguser' => 'Soạn thảo $1',
+'editingsection' => 'Soạn thảo $1',
+'editingcomment' => 'Soạn thảo $1',
+'editconflict' => 'Sửa đổi mâu thuẫn : $1',
+'explainconflict' => "<b>Trang này có đã được lưu bởi người khác sau khi bạn bắt đầu sửa. Phía trên là bản vừa được lưu. Phía dưới là sửa đổi của bạn. Bạn phải sửa lại từ bản đã lưu.<br />",
+'yourtext' => 'Nội dung bạn nhập',
+'storedversion' => 'Phiên bản lưu',
+"editingold" => "<strong>Chú ý: bạn đang sửa một phiên bản cũ. Nếu bạn lưu, các sửa đổi trên phiên bản mới hơn sẽ mất.</strong>",
+"yourdiff" => "Khác",
+/*"copyrightwarning" => "*Xin dùng [[{{ns:4}}:Chỗ thử|chỗ thử soạn thảo]] nếu bạn chỉ muốn thử nghiệm.
+*Xin đọc thêm hướng dẫn về [[Trợ giúp:Soạn thảo|soạn thảo]] và [[Trợ giúp:Viết bài mới|viết bài mới]].
+*Mọi đóng góp cho {{SITENAME}} đều tuân theo GNU Free Documentation Licence (Xem $1). Nếu bạn không muốn nội dung bạn nhập bị người khác sửa, đừng viết vào đây. <br /><b>KHÔNG LẤY TÀI LIỆU TỪ NGUỒN KHÁC MÀ CHƯA XIN PHÉP!</b>",*/
+'copyrightwarning2' => "*Xin dùng [[{{ns:4}}:Chỗ thử|chỗ thử soạn thảo]] nếu bạn chỉ muốn thử nghiệm.
+*Xin đọc thêm hướng dẫn về [[Trợ giúp:Soạn thảo|soạn thảo]] và [[Trợ giúp:Viết bài mới|viết bài mới]].
+*Mọi đóng góp cho {{SITENAME}} đều tuân theo GNU Free Documentation Licence (Xem $1). Nếu bạn không muốn nội dung bạn nhập bị người khác sửa, đừng viết vào đây. <br /><b>KHÔNG LẤY TÀI LIỆU TỪ NGUỒN KHÁC MÀ CHƯA XIN PHÉP!</b>",
+"longpagewarning" => "<strong>Chú ý : Trang này dài $1 kb; nhiều trình duyệt không tải được trang dài hơn 32 kb. Bạn nên chia nhỏ trang này thành nhiều trang.</strong>",
+"readonlywarning" => "<strong>Chú ý : trang này bị khóa để bảo trì. Bạn chỉ có thể sao nội dung để sửa đổi trên máy cá nhân.</strong>",
+"protectedpagewarning" => "<strong>Chú ý : trang này bị khóa. Chỉ có quản lý viên mới sửa được. Chú ý tuân thủ [[{{ns:4}}:Trang_bị_khóa|quy định về trang bị khóa]].<strong>",
+
+# History pages
+#
+'revhistory' => 'Bản cũ',
+'nohistory' => "Trang này chưa có lịch sử.",
+'revnotfound' => 'Không thấy',
+'revnotfoundtext' => "Không thấy phiên bản trước của trang này. Xin kiểm tra lại.",
+
+'loadhist' => 'Đang mở lịch sử...',
+'currentrev' => 'Hiện nay',
+'revisionasof' => '$1',
+'cur' => 'nay',
+'next' => 'sau',
+'last' => 'cũ',
+'orig' => 'gốc',
+'histlegend' => "Chú thích : (nay) = so sánh với bản hiện nay,
+(cũ) = so sánh với bản trước, n = sửa nhỏ",
+'selectnewerversionfordiff' => 'Chọn bản mới hơn',
+'selectolderversionfordiff' => 'Chọn bản cũ hơn',
+'previousdiff' => '&larr; So với trước',
+'previousrevision' => '&larr; Bản trước',
+'nextdiff' => 'So với sau &rarr;',
+'nextrevision' => 'Bản sau &rarr;',
+
+
+# Category pages
+#
+'categoriespagetext' => "Các thể loại :",
+'categoryarticlecount' => "Có $1 bài trong thể loại này.",
+
+
+# Diffs
+#
+'difference' => '(Khác biệt giữa các bản)',
+'loadingrev' => 'đang lấy các bản để so sánh',
+'lineno' => 'Dòng $1:',
+'editcurrent' => 'Sửa bản hiện nay',
+
+
+# Search results
+#
+'searchresults' => 'Kết quả tìm',
+'searchresulttext' => "Xem thêm [[{{ns:4}}:Tìm_kiếm|hướng dẫn tìm kiếm {{SITENAME}}]].",
+'searchsubtitle' => "Cho truy vấn \"[[:$1]]\"",
+'searchsubtitleinvalid' => "Cho truy vấn \"$1\"",
+'badquery' => 'Truy vấn sai',
+'badquerytext' => "Truy vấn sai: ngắn hơn 3 chữ cái, hoặc sai chính tả ví dụ như \"mèo và và chuột\". Xin mời thử lại.",
+'matchtotals' => "Truy vấn \"$1\" phù hợp với $2 tên bài và câu chữ trong $3 bài.",
+'noexactmatch' => "Không có trang tên như này, xin thử công cụ tìm.",
+'titlematches' => "Đề mục tương tự",
+'notitlematches' => "Không có tên bài nào có nội dung tương tự",
+'textmatches' => "Câu chữ tương tự",
+'notextmatches' => "Không có câu chữ nào trong các bài có nội dung tương tự",
+'prevn' => '$1 trước',
+'nextn' => '$1 sau',
+'viewprevnext' => 'Xem ($1) ($2) ($3).',
+'showingresults' => "Xem <b>$1</b> kết quả bắt đầu từ #<b>$2</b>.",
+'showingresultsnum' => "Xem <b>$3</b> kết quả bắt đầu từ #<b>$2</b>.",
+'nonefound' => "<strong>Chú ý</strong>: viết truy vấn tìm kiếm dài quá có thể gây khó khăn khi tìm.",
+'powersearch' => "Tìm",
+'powersearchtext' => "
+Tìm trong :<br />
+$1<br />
+$2 gồm cả trang đổi hướng &nbsp; Tìm $3 $9",
+'searchdisabled' => "<p>Công cụ tìm kiếm hiện bị khóa. Chức năng này sẽ được mở lại khi có điều kiện lắp thêm máy chủ. Hiện tại có thể tìm với Google:</p>",
+"blanknamespace" => "(Chính)",
+
+# Preferences page
+#
+'preferences' => 'Lựa chọn cá nhân',
+'prefsnologin' => 'Chưa đăng nhập',
+'prefsnologintext' => "Bạn phải [[Đặc_biệt:Userlogin|đăng nhập]] để sửa các Lựa chọn cá nhân của bạn.",
+'prefsreset' => 'Các Lựa chọn cá nhân đã được mặc định lại.',
+'qbsettings' => 'Các lựa chọn cho thanh công cụ',
+'changepassword' => 'Đổi mật khẩu',
+'skin' => 'Ngoại hình',
+'math' => 'Công thức toán',
+'dateformat' => 'Ngày tháng',
+'datedefault' => 'Không lựa chọn',
+'math_failure' => 'Lỗi toán',
+'math_unknown_error' => 'lỗi chưa rõ',
+'math_unknown_function' => 'hàm chưa rõ',
+'math_lexing_error' => 'lỗi chính tả',
+'math_syntax_error' => 'lỗi ngữ pháp',
+'math_image_error' => "Không chuyển sang định dạng PNG được, xin kiểm tra lại cài đặt Latex, dvips, gs và convert",
+'math_bad_tmpdir' => "Không tạo mới hay viết vào thư mục tạm thời được",
+'math_bad_output' => "Không tạo mới hay viết vào thư mục kết quả được",
+'math_notexvc' => "Không thấy 'texvc'. Xem math/README để cài đặt lại.",
+'prefs-personal' => 'Thông tin cá nhân',
+'prefs-rc' => 'Thay đổi gần đây',
+'prefs-misc' => 'Lựa chọn khác',
+'saveprefs' => 'Lưu lựa chọn',
+'resetprefs' => 'Mặc định lại lựa chọn',
+'oldpassword' => 'Mật khẩu cũ',
+'newpassword' => 'Mật khẩu mới&nbsp;',
+'retypenew' => 'Gõ lại',
+'textboxsize' => 'Kích thước cửa sổ soạn thảo',
+'rows' => 'Hàng&nbsp;',
+'columns' => 'Cột',
+'searchresultshead' => 'Xem kết quả tìm kiếm',
+'resultsperpage' => 'Số kết quả trong một trang&nbsp;',
+'contextlines' => 'Số hàng trong một kết quả',
+'contextchars' => 'Số chữ trong một hàng',
+'stubthreshold' => 'Độ lớn tối thiểu của bài ngắn',
+'recentchangescount' => 'Số đề mục trong Thay đổi gần đây',
+'savedprefs' => 'Đã lưu các lựa chọn cá nhân.',
+'timezonelegend' => 'Múi giờ',
+'timezonetext' => "Nếu không chọn, giờ mặc định UTC sẽ được dùng.",
+'localtime' => 'Giờ địa phương',
+'timezoneoffset' => 'Chênh giờ¹',
+'servertime' => 'Giờ máy chủ',
+'guesstimezone' => 'Dùng giờ của trình duyệt',
+"defaultns" => "Mặc định tìm kiếm trong không gian tên :",
+'yourlanguage' => "Ngôn ngữ&nbsp;",
+
+# Recent changes
+#
+"changes" => "sửa đổi",
+"recentchanges" => "Thay đổi gần đây",
+"recentchangestext" => "[[{{ns:4}}:Chào mừng người mới đến|Chào mừng]] bạn! Trang này dùng để theo dõi các thay đổi gần đây trên {{SITENAME}}.",
+'rcnote' => "<strong>$1</strong> thay đổi của <strong>$2</strong> ngày qua.",
+'rcnotefrom' => "Thay đổi từ <strong>$2</strong> (<b>$1</b> tối đa).",
+'rclistfrom' => "Xem thay đổi từ $1.",
+'rclinks' => "Xem $1 thay đổi của $2 ngày qua; $3.", // Looxix
+'diff' => 'khác',
+'hist' => 'sử',
+'hide' => 'giấu',
+'show' => 'xem',
+'minoreditletter' => 'n',
+'newpageletter' => 'M',
+
+# Upload
+#
+'upload' => 'Tải lên',
+'uploadbtn' => 'Tải lên',
+'reupload' => 'Tải lại',
+'reuploaddesc' => 'Quay lại.',
+
+'uploadnologin' => 'Chưa đăng nhập',
+'uploadnologintext' => "Bạn phải [[Đặc_biệt:Userlogin|đăng nhập]] để tải lên tệp tin.",
+'uploaderror' => "Lỗi",
+'uploadtext' => "Trước khi truyền hình lên:
+*Kiểm tra hình ảnh đã tải lên trước đây tại [[Đặc_biệt:Imagelist|danh sách những hình đã tải lên]].
+Khi truyền hình lên:
+*Tuân thủ [[{{ns:4}}:Quy định về hình ảnh|quy định về sử dụng hình ảnh]].
+*Ghi rõ thẻ quyền. Ví dụ {{<nowiki>PD</nowiki>}} hay {{<nowiki>GFDL</nowiki>}},... Xem thêm [[{{ns:4}}:Thẻ quyền cho hình ảnh|thẻ quyền cho hình ảnh]].
+*Dùng định dạng JPEG cho ảnh chụp, PNG cho hình vẽ, và OGG cho âm thanh hay video.
+*Ghi tóm lược về hình ảnh giúp người khác có thể dùng lại hình của bạn.
+Sau khi truyền hình lên:
+*Thông tin tải lên và xóa bỏ được ghi trong [[{{ns:4}}:Nhật trình tải lên|nhật trình tải lên]].
+*Để cho hình vào bài, xem [[{{ns:4}}:Cú pháp hình ảnh|cú pháp hình ảnh]].
+*Người khác có thể sửa hoặc xóa những thông tin bạn tải lên, và bạn có thể bị cấm tải lên nếu lạm dụng hệ thống.",
+"uploadlog" => "Nhật trình tải lên",
+"uploadlogpage" => "Nhật_trình_tải_lên",
+"uploadlogpagetext" => "Danh sách các tệp tin đã tải lên, theo giờ máy chủ (UTC).
+<ul>
+</ul>",
+'filename' => 'Tên&nbsp;',
+'filedesc' => 'Mô tả&nbsp;',
+'filestatus' => 'Bản quyền',
+'filesource' => 'Nguồn',
+'copyrightpage' => "{{ns:4}}:Bản quyền",
+'copyrightpagename' => "giấy phép {{SITENAME}}",
+'uploadedfiles' => "Đã tải xong",
+'minlength' => "Tên phải dài hơn hai chữ.",
+'illegalfilename' => 'Tên « $1 » có chứa ký tự không dùng được cho tên trang. Xin hãy đổi tên và tải lại.',
+'badfilename' => 'Đổi thành tên « $1 ».',
+'badfiletype' => '« .$1 » không phải là định dạng ảnh phù hợp.',
+'largefile' => 'Kích thước tập tin không nên vượt quá 100Kb.',
+'successfulupload' => 'Đã tải xong',
+'fileuploaded' => "Tập tin \"$1\" đã được tải lên thành công.
+Xin hãy theo liên kết: $2 đến trang mô tả và điền vào thông tin về tập tin, chẳng hạn như nó đến từ đâu, được tạo ra khi nào và bởi ai, và các chi tiết khác mà bạn biết về nó.
+Nếu đây là hình ảnh, bạn có thể cho vào trong trang như sau:
+<tt><nowiki>[[Image:$1|thumb|Mô tả hình]]</nowiki></tt>.",
+'uploadwarning' => 'Chú ý!',
+'savefile' => 'Lưu tệp tin',
+'uploadedimage' => 'đã tải lên « [[$1]] »',
+'uploaddisabled' => 'Xin lỗi, chức năng tải lên bị khóa.',
+'uploadcorrupt' => "Tập tin bị hỏng hoặc có đuôi không chuẩn. Xin kiểm tra và tải lại.",
+'fileexists' => "'Một tệp tin với tên này đã tồn tại, xin hãy kiểm tra $1 nếu bạn không muốn thay đổi nó.",
+'filemissing' => 'Không thấy tệp tin này',
+
+# Image list
+'imagelist' => 'Danh sách hình',
+'imagelisttext' => 'Danh sách $1 hình xếp theo $2.',
+'getimagelist' => 'Đang lấy danh sách hình',
+'ilsubmit' => 'Tìm',
+'showlast' => 'Xem $1 hình mới nhất xếp theo $2.',
+'byname' => 'tên',
+'bydate' => 'ngày',
+'bysize' => 'kích cỡ',
+'imgdelete' => 'xóa',
+'imgdesc' => 'tả',
+'imglegend' => "Chú thích: (tả) = xem/sửa mô tả về hình.",
+'imghistory' => 'Lịch sử hình',
+'revertimg' => 'hồi',
+'deleteimg' => 'xóa',
+'deleteimgcompletely' => 'xóa hẳn',
+'imghistlegend' => "Chú thích: (nay) = Hình hiện nay, (xóa) = Xóa bản cũ, (hồi) = Phục hồi bản cũ.
+<br /><i>Ấn vào ngày để xem hình tải lên ngày đó</i>.",
+'imagelinks' => 'Liên kết đến hình',
+'linkstoimage' => 'Các trang sau có liên kết đến hình:',
+'nolinkstoimage' => 'Không có trang nào chứa liên kết đến hình.',
+'showbigimage' => 'Tái xuống bản có độ phân giải cao ($1x$2, $3 Kb)',
+'imagemaxsize' => 'Giới hạn độ phân giải ảnh là:&nbsp;',
+'newimages' => 'Trang trưng bày hình ảnh mới',
+'noimages' => 'Không có hình nào.',
+# image deletion
+'deletedrevision' => 'Đã xóa phiên bản cũ $1.',
+
+# Statistics
+
+'statistics' => 'Thống kê',
+'sitestats' => 'Thống kê',
+'userstats' => 'Thống kê thành viên',
+'sitestatstext' =>'<p style="font-size: 125%; margin-bottom: 0px">Hiện đang có <b>$2</b> [[{{ns:4}}:Bài bách khoa là gì?|bài viết]].</p>
+
+Con số này không bao gồm các trang [[{{ns:4}}:Trang_thảo_luận|thảo luận]], các trang giới thiệu {{SITENAME}}, các [[{{ns:4}}:Trang_đổi_hướng|trang đổi hướng]], và các trang không được coi là có nội dung (ví dụ: không liên kết đến trang khác). Khi tính các trang đó vào, có <b>$1</b> trang.
+
+Đã có tổng cộng <b>$3</b> lần xem, và <b>$4</b> lần sửa kể từ khi dự án này được thiết lập. Trung bình có <b>$5</b> lần sửa cho mỗi trang, và <b>$6</b> lần xem cho mỗi sửa đổi.',
+'userstatstext' => "Có <b>$1</b> thành viên đã đăng ký, trong đó có <b>$2</b> là [[{{ns:4}}:Người quản lý|người quản lý]].",
+
+# Maintenance Page
+#
+'disambiguations' => 'Trang định hướng',
+'disambiguationspage' => "{{ns:4}}:Trang_định_hướng",
+'disambiguationstext' => "Những trang sau đây liên kết đến một <i>trang định hướng</i>. Lẽ ra chúng nên liên kết thẳng đến một trang phù hợp.<br />Xin xem thêm [$1 thông tin về trang định hướng].<br />Chú ý, dưới đây <i>không</i> liệt kê liên kết từ các không gian tên khác.",
+'doubleredirects' => 'Đổi hướng kép',
+'doubleredirectstext' => "Mỗi hàng có chứa các liên kết đến trang chuyển hướng thứ nhất và thứ hai, cũng như dòng đầu tiên của nội dung trang chuyển hướng thứ hai, thường chỉ tới trang đích \"thực sự\", là nơi mà trang chuyển hướng đầu tiên phải trỏ đến.",
+'brokenredirects' => 'Đổi hướng sai',
+'brokenredirectstext' => 'Các trang đổi hướng sau đây liên kết đến một trang không tồn tại.',
+
+
+# Miscellaneous special pages
+'uncategorizedpages' => 'Trang chưa xếp thể loại',
+'uncategorizedcategories' => 'Thể loại chưa phân loại',
+'unusedimages' => 'Hình chưa dùng',
+'nlinks' => '$1 liên kết',
+'allpages' => 'Tất cả các trang',
+'deadendpages' => 'Trang đường cùng',
+'lonelypages' => 'Trang mồ côi',
+'popularpages' => 'Trang nhiều người đọc',
+'nviews' => '$1 lần xem',
+'wantedpages' => 'Trang cần viết',
+'randompage' => 'Trang ngẫu nhiên',
+'shortpages' => 'Bài ngắn',
+'longpages' => 'Bài dài',
+'listusers' => 'Danh sách thành viên',
+'specialpages' => 'Các trang đặc biệt',
+'spheading' => 'Các trang đặc biệt',
+'recentchangeslinked' => 'Thay đổi liên quan',
+'rclsub' => "(trang liên kết đến \"$1\")",
+'newpages' => 'Các bài mới nhất',
+'ancientpages' => 'Các bài cũ nhất',
+'move' => 'đổi tên',
+'movethispage' => 'Đổi tên trang này',
+'unusedimagestext' => '<p>Xin lưu ý là các địa chỉ mạng bên ngoài có thể liên kết đến một hình ở đây qua một địa chỉ trực tiếp, dù hình này được liệt kê là chưa dùng.</p>',
+'booksources' => "Nguồn tham khảo",
+'booksourcetext' => "Dưới đây là danh sách các liên kết đến các địa chỉ bán sách cũ hoặc mới, và có thể có thông tin chi tiết về những sách mà bạn đang tìm. {{SITENAME}} không hề liên quan gì với những công ty trên đây, và danh sách này không nên được hiểu là một sự chứng nhận nào đó đối với những công ty trên.",
+'alphaindexline' => '$1 đến $2',
+'version' => 'Phiên bản',
+
+# All pages
+#
+'allinnamespace' => "Mọi trang (không gian $1)",
+'allpagesnext' => "Sau",
+'allpagesprev' => "Trước",
+'allpagessubmit' => "Hiển thị",
+
+# Email this user
+#
+'mailnologin' => 'Không có địa chỉ gửi thư',
+'mailnologintext' => 'Bạn phải [[Đặc_biệt:Userlogin|đăng nhập]] và có khai báo một địa chỉ thư điện tử hợp lệ trong phần [[Đặc_biệt:Preferences|lựa chọn cá nhân]] thì mới gửi được thư cho người khác.',
+'emailuser' => 'Gửi thư cho người này',
+'emailpage' => 'Gửi thư',
+'emailpagetext' => 'Nếu người này đã cung cấp địa chỉ thư điện tử, biểu mẫu dưới đây sẽ cho bạn gửi thư. Địa chỉ thư điện tử của bạn sẽ xuất hiện trong phần địa chỉ người gửi của bức thư, nên người nhận có thể trả lời lại bạn.',
+'noemailtitle' => 'Không có địa chỉ nhận thư',
+'noemailtext' => 'Người này không cung cấp một địa chỉ thư hợp lệ, hoặc đã chọn không nhận thư từ người khác.',
+
+'emailfrom' => 'Từ',
+'emailto' => 'Đến',
+'emailsubject' => 'Chủ đề',
+'emailmessage' => 'Nội dung',
+'emailsend' => 'Gửi',
+'emailsent' => 'Đã gửi',
+'emailsenttext' => 'Thư của bạn đã được gửi.',
+'usermailererror' => 'Lỗi gửi thư:',
+'defemailsubject' => 'thư gửi từ {{SITENAME}}',
+
+# Watchlist
+#
+'watchlist' => 'Trang tôi theo dõi',
+'nowatchlist' => "Chưa có gì.",
+'watchnologin' => 'Chưa đăng nhập',
+'watchnologintext' => "Bạn phải [[Đặc_biệt:Userlogin|đăng nhập]] mới sửa đổi được danh sách theo dõi.",
+'addedwatch' => 'Đã vào danh sách theo dõi',
+'addedwatchtext' => "Trang \"$1\" đã được cho vào [[Đặc_biệt:Watchlist|danh sách theo dõi]].
+Những sửa đổi đối với trang này và trang thảo luận của nó sẽ được liệt kê, và được <b>in đậm</b> trong [[Đặc_biệt:Recentchanges|danh sách các thay đổi mới]].
+<p>Nếu bạn muốn cho trang này ra khỏi danh sách theo dõi, nhấn vào \"Ngừng theo dõi\" ở trên.",
+'removedwatch' => 'Đã ra khỏi danh sách theo dõi',
+'removedwatchtext' => "Trang « $1 » đã ra khỏi danh sách theo dõi.",
+'watch' => 'Theo dõi',
+'watchthispage' => 'Theo dõi trang này',
+'unwatch' => 'ngừng theo dõi',
+'unwatchthispage' => 'Ngừng theo dõi',
+'notanarticle' => 'Không phải bài viết',
+'watchnochange' => 'Không có trang nào bạn theo dõi được sửa đổi.',
+'watchdetails' => "* Bạn theo dõi $1 trang không kể trang thảo luận. $3 <br />
+*[$4 Xem và sửa lại danh sách]", // Looxix
+'watchmethod-recent'=> 'Dưới đây hiện thay đổi mới với các trang theo dõi.',
+'watchmethod-list' => 'Dưới đây hiện danh sách các trang theo dõi.',
+'removechecked' => 'Ngưng theo dõi mục đã chọn',
+'watchlistcontains' => "Danh sách theo dõi của bạn có $1 trang.",
+'watcheditlist' => 'Đây là sắp xếp theo chữ cái các trang bạn theo dõi. Chọn các trang bạn muốn ngưng theo dõi và nhấn "Ngưng theo dõi mục đã chọn".',
+'removingchecked' => 'Đang ngưng theo dõi trang yêu cầu...',
+'couldntremove' => "Không thể ngưng theo dõi trang '$1'...",
+'iteminvalidname' => "Tên trang '$1' không hợp lệ...",
+'wlnote' => "$1 sửa đổi mới trong <b>$2</b> giờ qua.",
+'wlshowlast' => "Xem $1 giờ $2 ngày qua, hoặc $3",
+'wlsaved' => 'Đây là bản lưu danh sách theo dõi.',
+
+# Delete/protect/revert
+
+'deletepage' => 'Xóa trang',
+'confirm' => 'Khẳng định',
+'excontent' => 'nội dung cũ là:',
+'exbeforeblank' => 'nội dung trước khi xóa là:',
+'exblank' => 'trang rỗng',
+'confirmdelete' => 'Khẳng định xóa',
+'deletesub' => "(Xóa \"$1\")",
+'historywarning' => '<b>Chú ý</b>: trang bạn sắp xóa đã có lịch sử:',
+'confirmdeletetext' => "Bạn sắp xóa hẳn một trang hoặc hình cùng với tất cả lịch sử của nó khỏi cơ sở dữ liệu. Xin khẳng định bạn hiểu rõ hậu quả có thể xảy ra, và bạn thực hiện đúng [[{{ns:4}}:Quy_định|quy định]].",
+'actioncomplete' => 'Xong',
+'deletedtext' => "\"$1\" đã được xóa. Xem danh sách các xóa bỏ gần nhất tại $2.",
+'deletedarticle' => "đã xóa \"$1\"",
+'dellogpage' => 'Nhật trình xóa',
+'dellogpagetext' => 'Danh sách xóa mới, theo giờ máy chủ (UTC).
+<ul>
+</ul>',
+'deletionlog' => 'nhật trình xóa',
+'reverted' => 'Đã quay lại phiên bản cũ',
+'deletecomment' => 'Lý do',
+'imagereverted' => 'Đã quay lại phiên bản cũ.',
+'rollback' => 'Quay lại sửa đổi cũ',
+'rollback_short' => 'Quay lại',
+'rollbacklink' => 'quay lại',
+'rollbackfailed' => 'Không quay lại được',
+'cantrollback' => 'Không quay lại được; trang này có 1 tác giả.',
+'alreadyrolled' => "Không thể quay lại phiên bản của [[:$1]] bởi [[Thành_viên:$2|$2]] ([[Thảo_luận_thành_viên:$2|Thảo luận]]). Đã có sửa đổi lần cuối bởi [[Thành_viên:$3|$3]] ([[Thảo_luận_thành_viên:$3|Thảo luận]]).",
+# only shown if there is an edit comment
+'editcomment' => "Tóm lược sửa đổi: \"<i>$1</i>\".",
+'revertpage' => "đã hủy sửa đổi của $2, quay về phiên bản của $1",
+'sessionfailure' => 'Có thể có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy tải lại trang và thử lại.',
+'protectlogpage' => 'Nhật trình khóa',
+'protectlogtext' => "Danh sách khóa/mở (xem [[{{ns:4}}:Các trang bị khóa|các trang bị khóa]]).",
+'protectedarticle' => "đã khóa $1",
+'unprotectedarticle' => "đã mở $1",
+'protectsub' =>"(Khóa \"$1\")",
+'confirmprotecttext' => 'Bạn thật sự muốn khóa trang này?',
+'confirmprotect' => 'Khẳng định khóa',
+'protectmoveonly' => 'Chỉ không cho di chuyển',
+'protectcomment' => 'Lý do',
+'unprotectsub' =>"(Mở \"$1\")",
+'confirmunprotecttext' => 'Bạn thật sự muốn mở trang này?',
+'confirmunprotect' => 'Khẳng định mở',
+'unprotectcomment' => 'Lý do',
+
+# Groups
+'editusergroup' => 'Sửa các nhóm thành viên',
+
+
+'userrights-lookup-user' => 'Quản lý nhóm thành viên',
+'userrights-user-editname' => 'Nhập tên thành viên:',
+
+# user groups editing
+#
+'userrights-editusergroup' => 'Sửa nhóm thành viên',
+'saveusergroups' => 'Lưu nhóm thành viên',
+'userrights-groupsmember' => 'Thành viên của:',
+'userrights-groupsavailable' => 'Các nhóm hiện nay:',
+'userrights-groupshelp' => 'Chọn nhóm mà bạn muốn thêm hay bớt thành viên. Các nhóm không được chọn sẽ không thay đổi. Có thể chọn nhóm bằng CTRL + Chuột trái',
+
+# Special:Undelete
+'undelete' => 'Khôi phục',
+'undeletepage' => 'Xem và khôi phục trang bị xóa',
+'undeletepagetext' => 'Các trang sau có thể khôi phục được từ thùng rác. Thùng rác được xóa định kỳ.',
+'undeletearticle' => 'Khôi phục',
+'undeleterevisions' => "$1 bản được lưu",
+'undeletehistory' => 'Nếu bạn khôi phục trang này, tất cả các phiên bản của nó sẽ được phục hồi vào lịch sử của trang. Nếu một trang mới có cùng tên đã được tạo ra kể từ khi xóa trang này, các phiên bản được khôi phục sẽ xuất hiện trong lịch sử trước, và phiên bản hiện hành của trang mới sẽ không bị thay thế.',
+'undeleterevision' => "Xóa lúc $1",
+'undeletebtn' => 'Khôi phục',
+'undeletedarticle' => "đã khôi phục \"$1\"",
+'undeletedrevisions' => "$1 bản được khôi phục",
+
+# Contributions
+'contributions' => 'Đóng góp',
+'mycontris' => 'Đóng góp của tôi',
+'contribsub' => "Của $1",
+'nocontribs' => 'Không tìm thấy.',
+'ucnote' => "</b>$1</b> thay đổi mới của người này trong <b>$2</b> ngày qua.",
+'uclinks' => "Xem $1 thay đổi mới; xem $2 ngày qua.",
+'uctop' => '(mới nhất)' ,
+'newbies' => 'người mới',
+
+# What links here
+'whatlinkshere' => 'Liên kết đến đây',
+'notargettitle' => 'Không hiểu',
+'notargettext' => 'Xin chỉ rõ trang mục tiêu.',
+'linklistsub' => '(Các liên kết)',
+'linkshere' => 'Các trang sau liên kết đến đây:',
+'nolinkshere' => 'Không có liên kết đến đây.',
+'isredirect' => 'trang đổi hướng',
+
+# Block/unblock IP
+
+'blockip' => 'Cấm thành viên',
+'blockiptext' => "Mẫu dưới để cấm một địa chỉ IP hoặc một tài khoản.
+Chức năng này chỉ nên dùng để ngăn những hành vi phá hoại, và phải tuân theo [[{{ns:4}}:Quy_định|quy_định]]. Xin cho biết lý do cấm.",
+'ipaddress' => 'Địa chỉ IP/tên tài khoản',
+'ipbexpiry' => 'Thời hạn',
+'ipbreason' => 'Lý do',
+'ipbsubmit' => 'Cấm',
+'badipaddress' => 'Địa chỉ IP không hợp lệ',
+'blockipsuccesssub' => 'Đã cấm',
+'blockipsuccesstext' => "\"$1\" đã bị cấm.
+<br />Xem lại những lần cấm tại [[Đặc_biệt:Ipblocklist|danh sách cấm]].",
+'unblockip' => 'Bỏ cấm',
+'unblockiptext' => 'Mẫu sau để khôi phục lại quyền sửa bài đối với một địa chỉ IP hoặc tài khoản đã bị cấm trước đó.',
+'ipusubmit' => 'Bỏ cấm',
+'ipblocklist' => 'Danh sách cấm',
+'blocklistline' => "$1, $2 đã cấm $3 (thời hạn $4)",
+'blocklink' => 'cấm',
+'unblocklink' => 'bỏ cấm',
+'contribslink' => 'đóng góp',
+'autoblocker' => "Bị tự động cấm vì dùng chung địa chỉ IP với \"$1\". Lý do \"$2\".",
+'blocklogpage' => 'Nhật trình cấm',
+'blocklogentry' => 'đã cấm "$1", thời hạn $2',
+'blocklogtext' => 'Nhật trình lưu những lần cấm và bỏ cấm. Các địa chỉ IP bị cấm tự động không được liệt kê. Xem thêm
+[[Đặc_biệt:Ipblocklist|danh sách cấm]].',
+'unblocklogentry' => 'đã hết cấm "$1"',
+'range_block_disabled' => 'Không được cấm hàng loạt.',
+'ipb_expiry_invalid' => 'Thời điểm hết hạn không hợp lệ.',
+'ip_range_invalid' => "Dải IP không hợp lệ.",
+'proxyblocker' => 'Chặn proxy',
+'proxyblockreason' => 'Địa chỉ IP của bạn đã bị cấm vì là proxy mở. Xin hãy liên hệ nhà cung cấp dịch vụ Internet hoặc bộ phận hỗ trợ kỹ thuật của bạn và thông báo với họ về vấn đề an ninh nghiêm trọng này.',
+'proxyblocksuccess' => "Đã xong.",
+// Chỗ này có thể lỗi
+'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Địa chỉ IP của bạn bị liệt kê là một proxy mở theo [http://www.sorbs.net SORBS] DNSBL.',
+'sorbs_create_account_reason' => 'Địa chỉ IP của bạn bị liệt kê là một proxy mở theo [http://www.sorbs.net SORBS] DNSBL. Bạn không thể mở được tài khoản.',
+
+# Developer tools
+'lockdb' => 'Khóa cơ sở dữ liệu',
+'unlockdb' => 'Mở cơ sở dữ liệu',
+'lockdbtext' => 'Khóa cơ sở dữ liệu sẽ không cho phép người dùng sửa đổi các trang, thay đổi thông số cá nhân của họ, sửa danh sách theo dõi, và những thao tác khác đòi hỏi phải thay đổi trong cơ sở dữ liệu.
+Xin hãy khẳng định là bạn có ý định thực hiện điều này, và bạn sẽ mở khóa cơ sở dữ liệu khi xong công việc bảo trì của bạn.',
+'unlockdbtext' => 'Mở khóa cơ sở dữ liệu sẽ lại cho phép các người dùng có thể sửa đổi trang, thay đổi thông số cá nhân của họ, sửa đổi danh sách theo dõi của họ, và nhiều thao tác khác đòi hỏi phải có thay đổi trong cơ sở dữ liệu.
+Xin hãy khẳng định đây là điều bạn định làm.',
+'lockconfirm' => 'Vâng, tôi thực sự muốn khóa cơ sở dữ liệu.',
+'unlockconfirm' => 'Vâng, tôi thực sự muốn mở cơ sở dữ liệu.',
+'lockbtn' => 'Khóa cơ sở dữ liệu',
+'unlockbtn' => 'Mở cơ sở dữ liệu',
+'locknoconfirm' => 'Bạn đã không chọn vào ô khẳng định.',
+'lockdbsuccesssub' => 'Khóa thành công cơ sở dữ liệu',
+'unlockdbsuccesssub' => 'Mở thành công cơ sở dữ liệu',
+'lockdbsuccesstext' => 'Cơ sở dữ liệu đã bị khóa.
+<br />Nhớ bỏ khóa sau khi bảo trì xong.',
+'unlockdbsuccesstext' => 'Cơ sở dữ liệu đã được mở khóa.',
+
+# Special:Makesysop
+'makesysoptitle' => 'Phong một thành viên làm quản lý',
+'makesysoptext' => 'Mẫu này được các tổng quản lý dùng để phong các thành viên bình thường thành người quản lý.
+Hãy gõ tên của thành viên cần phong quyền quản lý vào ô này và nhấn nút.',
+'makesysopname' => 'Tên thành viên:',
+'makesysopsubmit' => 'Phong quyền quản lý cho thành viên này',
+'makesysopok' => "<b>Thành viên \"$1\" đã thành quản lý</b>",
+'makesysopfail' => "<b>Thành viên \"$1\" không thể trở thành quản lý được. (Liệu bạn có nhập tên đúng không?)</b>",
+'setbureaucratflag' => 'Đặt cờ tổng quản lý',
+'rightslogtext' => 'Đây là nhật trình lưu những thay đổi đối với các quyền hạn thành viên.',
+'rights' => 'Quyền:',
+'set_user_rights' => 'Đặt quyền hạn cho thành viên',
+'user_rights_set' => "<b>Quyền hạn thành viên của \"$1\" đã được cập nhật</b>",
+'set_rights_fail' => "<b>Quyền hạn thành viên của \"$1\" không thể xác lập được. (Liệu bạn có gõ sai tên không?)</b>",'makesysop' => 'Phong một thành viên làm quản lý',
+
+
+# Spam
+'spamprotectiontitle' => 'Bộ lọc chống thư rác',
+'spamprotectiontext' => 'Trang bạn muốn lưu bị bộ lọc thư rác chặn lại. Đây có thể do một liên kết dẫn tới một địa chỉ bên ngoài.',
+'spamprotectionmatch' => 'Nội dung sau đây đã kích hoạt bộ lọc thư rác: $1',
+
+'subcategorycount' => "Có $1 tiểu thể loại trong thể loại này.",
+'categoryarticlecount' => "Có $1 bài trong thể loại này.",
+'listingcontinuesabbrev' => " tiếp",
+
+# Patrolling
+#
+'markaspatrolleddiff' => "Đánh dấu tuần tra",
+'markaspatrolledtext' => "Đánh dấu tuần tra",
+'markedaspatrolled' => "Đã đánh dấu tuần tra",
+'markedaspatrolledtext' => "Bản được đánh dấu đã tuần tra.",
+'rcpatroldisabled' => "\"Thay đổi gần đây\" của các trang tuần tra không bật",
+'rcpatroldisabledtext' => "Chức năng \"thay đổi gần đây\" của các trang tuần tra hiện không được bật.",
+
+# Move page
+
+'movepage' => 'Di chuyển',
+'movepagetext' => 'Dùng mẫu dưới đây sẽ đổi tên một trang, đồng thời chuyển tất cả lịch sử của nó sang tên mới.
+*Tên cũ sẽ tự động đổi hướng sang tên mới.
+*Trang sẽ <b>không</b> bị chuyển nếu đã có một trang tại tên mới, trừ khi nó rỗng hoặc là trang đổi hướng và không có lịch sử sửa đổi. Điều này có nghĩa là bạn có thể đổi tên một trang lại như trước lúc nó được đổi tên nếu bạn nhầm, và bạn không thể ghi đè một trang đã có sẵn.
+*Những liên kết đến tên trang cũ sẽ không thay đổi; cần [[Đặc_biệt:DoubleRedirects|kiểm tra]] những trang chuyển hướng kép và sai.<br />
+<b>Bạn phải đảm bảo những liên kết tiếp tục trỏ đến đúng trang cần thiết.</b>',
+'movepagetalktext' => 'Trang thảo luận đi kèm nếu có, sẽ được tự động chuyển theo \'\'\'trừ khi:\'\'\'
+*Bạn đang chuyển xuyên qua không gian tên,
+*Một trang thảo luận đã tồn tại dưới tên bạn chọn, hoặc
+*Bạn không chọn vào ô bên dưới.
+
+Trong những trường hợp này, bạn phải di chuyển hoặc hợp nhất trang theo kiểu thủ công nếu muốn.',
+'movearticle' => 'Di chuyển',
+'movenologin' => 'Chưa đăng nhập',
+'movenologintext' => "Bạn phải [[Đặc_biệt:Userlogin|đăng nhập]] mới di chuyển trang được.",
+'newtitle' => 'Tên mới',
+'movepagebtn' => 'Di chuyển',
+'pagemovedsub' => 'Di chuyển thành công',
+'pagemovedtext' => "Trang \"[[$1]]\" đổi thành \"[[$2]]\".",
+'articleexists' => 'Đã có một trang với tên đó, hoặc tên bạn chọn không hợp lệ.
+Xin hãy chọn tên khác.',
+'talkexists' => 'Trang được di chuyển thành công, nhưng trang thảo luận tương ứng không thể chuyển được vì đã có một trang thảo luận ở tên mới.
+Xin hãy hợp nhất chúng lại.',
+'movedto' => 'đổi thành',
+'movetalk' => 'Di chuyển trang "thảo luận" nếu có.',
+'talkpagemoved' => 'Trang thảo luận tương ứng đã chuyển.',
+'talkpagenotmoved' => 'Trang thảo luận tương ứng <strong>không</strong> chuyển.',
+'1movedto2' => "$1 đổi thành $2",
+'1movedto2_redir' => '$1 đổi thành $2 qua đổi hướng',
+'movereason' => 'Lý do',
+
+# Export page
+'export' => 'Xuất các trang',
+'exporttext' => 'Bạn có thể xuất nội dung và lịch sử sửa đổi của một trang hay tập hợp trang nào đó vào trong các XML. Trong tương lai, cũng có thể nhập vào một mạng khác chạy phần mềm MediaWiki.
+
+Để xuất nội dung các bài, gõ vào tên bài trong cửa sổ dưới đây, mỗi tên một hàng, và cho biết là bạn muốn chọn phiên bản hiện tại cùng với các phiên bản cũ của nó, với các dòng về lịch sử trang, hay chỉ phiên bản hiện hành với thông tin về lần sửa đổi cuối cùng.',
+'exportcuronly' => 'Chỉ xuất phiên bản hiện hành, không xuất tất cả lịch sử trang',
+
+# Namespace 8 related
+'allmessages' => 'Thông báo hệ thống',
+'allmessagesname' => 'Tên thông báo',
+'allmessagesdefault' => 'Nội dung mặc định',
+'allmessagescurrent' => 'Nội dung hiện thời',
+'allmessagestext' => 'Đây là toàn bộ thông báo hệ thống có trong không gian tên MediaWiki: .',
+'allmessagesnotsupportedUI' => 'Ngôn ngữ giao diện hiện tại của bạn <b>$1</b> không được Đặc_biệt:AllMessages hỗ trợ tại đây.',
+'allmessagesnotsupportedDB' => 'Đặc_biệt:AllMessages không được hỗ trợ vì wgUseDatabaseMessages bị tắt.',
+
+# Thumbnails
+'thumbnail-more' => 'Phóng lớn',
+'missingimage' => "<b>Không có hình</b><br /><i>$1</i>",
+'filemissing' => 'Không có tệp tin',
+
+# Special:Import
+'import' => 'Nhập các trang',
+'importtext' => 'Xin hãy xuất tập tin từ wiki nguồn sử dụng công cụ Đặc_biệt:Export, lưu nó vào đĩa và tải lên ở đây.',
+'importfailed' => "Không nhập được: $1",
+'importnotext' => 'Trang trống không có nội dung',
+'importsuccess' => 'Nhập thành công!',
+'importhistoryconflict' => 'Có mâu thuẫn trong lịch sử của các phiên bản (trang này có thể đã được nhập vào trước đó)',
+
+# Keyboard access keys for power users
+'accesskey-compareselectedversions' => 'v',
+'accesskey-minoredit' => 'i',
+'accesskey-preview' => 'p',
+'accesskey-save' => 's',
+'accesskey-search' => 'f',
+
+# tooltip help for the main actions
+'tooltip-search' => 'Tìm kiếm [alt-f]',
+'tooltip-minoredit' => 'Đánh dấu đây là sửa đổi nhỏ [alt-i]',
+'tooltip-save' => 'Lưu lại những thay đổi của bạn [alt-s]',
+'tooltip-preview' => 'Xem thử những thay đổi trước khi lưu! [alt-p]',
+'tooltip-compareselectedversions' => 'Xem khác biệt giữa hai phiên bản của trang này. [alt-v]',
+'tooltip-watch' => 'Cho trang này vào danh sách theo dõi [alt-w]',
+
+# Metadata
+'nodublincore' => 'Máy chủ không hỗ trợ siêu dữ liệu Dublin Core RDF.',
+'nocreativecommons' => 'Máy chủ không hỗ trợ siêu dữ liệu Creative Commons RDF.',
+'notacceptable' => 'Máy chủ không thể cho ra định dạng dữ liệu tương thích với phần mềm của bạn.',
+
+# Attribution
+'anonymous' => "Thành viên vô danh của {{SITENAME}}",
+'siteuser' => "Thành viên $1 của {{SITENAME}}",
+'lastmodifiedatby' => "Trang này được $3 cập nhật lần cuối lúc $2, $1.",
+'and' => 'và',
+'othercontribs' => "dựa trên công trình của $1.",
+'others' => 'những người khác',
+'siteusers' => "Thành viên $1 của {{SITENAME}}",
+'creditspage' => 'Trang ghi nhận đóng góp',
+'nocredits' => 'Không có thông tin ghi nhận đóng góp cho trang này.',
+
+# confirmemail
+'confirmemail' => 'Xác nhận thư điện tử',
+'confirmemail_text' => 'Cần kiểm tra địa chỉ thư điện tử trước khi lưu. Ấn nút bên dưới để gửi thư xác nhận đến địa chỉ. Thư xác nhận có một mã xác nhận; khi bạn nhập mã xác nhận vào đây, địa chỉ thư điện tử của bạn sẽ được xác nhận.',
+'confirmemail_send' => 'Gửi thư xác nhận',
+'confirmemail_sent' => 'Thư xác nhận đã được gửi',
+'confirmemail_sendfailed' => 'Không thể gửi thư xác nhận. Xin kiểm tra lại địa chỉ thư.',
+'confirmemail_invalid' => 'Mã xác nhận sai. Mã này có thể đã hết hạn',
+'confirmemail_success' => 'Thư điện tử của bạn đã được xác nhận. Bạn có thể đăng nhập được.',
+'confirmemail_loggedin' => 'Địa chỉ thư điện tử của bạn đã được xác nhận',
+'confirmemail_error' => 'Có trục trặc',
+'confirmemail_subject' => 'Xác nhận thư điện tử tại {{SITENAME}}',
+'confirmemail_body' => 'Ai đó, có thể là bạn, với địa chỉ thư điện tử $1, đã mở tài khoản "$2" dùng địa chỉ này ở {{SITENAME}}.
+
+Để xác nhận rằng tài khoản này của bạn và dùng chức năng thư điện tử ở {{SITENAME}}, xin mở địa chỉ mạng sau :
+
+$3
+
+Nếu không phải bạn, đừng mở địa chỉ này. Mã xác nhận này sẽ hết hạn lúc $4.',
+
+# Math
+'mw_math_png' => 'Luôn cho ra dạng hình PNG',
+'mw_math_simple' => 'HTML nếu rất đơn giản, nếu không PNG',
+'mw_math_html' => 'HTML nếu có thể, nếu không PNG',
+'mw_math_source' => 'Để là TeX (cho trình duyệt văn bản)',
+'mw_math_modern' => 'Dành cho trình duyệt hiện đại',
+'mw_math_mathml' => 'MathML nếu có thể',
+
+'usercssjsyoucanpreview' => "'''Chú ý :''' xem thử trước để kiểm tra trang css/js mới trước khi lưu.",
+'usercsspreview' => "'''Bạn đang xem thử trang css và nó chưa được lưu !'''",
+'userjspreview' => "'''Bạn đang xem thử trang Javascript và nó chưa được lưu !'''",
+
+# stylesheets
+'monobook.css' => '/* edit this file to customize the monobook skin for the entire site */',
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Trang của tôi\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Trang của IP bạn đang dùng\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Thảo luận với tôi\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Thảo luận với địa chỉ IP này\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Lựa chọn cá nhân của tôi\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Thay đổi của các trang tôi theo dõi.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Đóng góp của tôi\');
+ta[\'pt-login\'] = new Array(\'o\',\'Đăng nhập sẽ có lợi hơn, tuy nhiên không bắt buộc.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Không đăng nhập vẫn tham gia được, tuy nhiên đăng nhập sẽ lợi hơn.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Đăng xuất\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Thảo luận về trang này\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Bạn có thể sửa được trang này. Xin xem thử trước khi lưu.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Thêm bình luận vào đây.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Trang này được khóa. Bạn có thể xem mã nguồn.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Những phiên bản cũ của trang này.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Khóa trang này lại\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Xóa trang này\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Khôi phục lại những sửa đổi trên trang này trước khi nó bị xóa\');
+ta[\'ca-move\'] = new Array(\'m\',\'Di chuyển trang này\');
+ta[\'ca-nomove\'] = new Array(\'\',\'Bạn không thể di chuyển trang này\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Thêm trang này vào danh sách theo dõi\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Bỏ trang này khỏi danh sách theo dõi\');
+ta[\'search\'] = new Array(\'f\',\'Tìm kiếm\');
+ta[\'p-logo\'] = new Array(\'\',\'Trang đầu\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Trang đầu của dự án mở\');
+ta[\'n-portal\'] = new Array(\'\',\'Giới thiệu dự án, cách sử dụng, tìm kiếm thông tin ở đây\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Xem thời sự\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Danh sách các thay đổi gần đây\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Xem trang ngẫu nhiên\');
+ta[\'n-help\'] = new Array(\'\',\'Nơi tìm hiểu thêm cách dùng.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Quyên góp xây dựng dự án mở\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Các trang liên kết đến đây\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Thay đổi gần đây của các trang liên kết đến đây\');
+ta[\'feed-rss\'] = new Array(\'\',\'Nạp RSS cho trang này\');
+ta[\'feed-atom\'] = new Array(\'\',\'Nạp Atom cho trang này\');
+ta[\'t-contributions\'] = new Array(\'\',\'Xem đóng góp của người này\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Gửi thư cho người này\');
+ta[\'t-upload\'] = new Array(\'u\',\'Tải hình ảnh hoặc tệp tin lên\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Danh sách các trang đặc biệt\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Xem trang này\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Xem trang về người này\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Xem trang phương tiện\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Đây là một trang dặc biệt, bạn không thể sửa đổi được nó.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Xem trang dự án\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Xem trang hình\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Xem thông báo hệ thống\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Xem tiêu bản\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Xem trang trợ giúp\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Xem trang thể loại\');',
+
+
+# EXIF
+'exif-imagewidth' => 'Bề ngang',
+'exif-imagelength' => 'Chiều cao',
+'exif-compression' => 'Kiểu nén',
+'exif-samplesperpixel' => 'Số mẫu trên điểm ảnh',
+'exif-xresolution' => 'Phân giải trên bề ngang',
+'exif-yresolution' => 'Phân giải theo chiều cao',
+'exif-jpeginterchangeformat' => 'Vị trí SOI JPEG',
+'exif-jpeginterchangeformatlength' => 'Kích cỡ (byte) của JPEG',
+'exif-transferfunction' => 'Hàm chuyển đổi',
+'exif-datetime' => 'Ngày tháng sửa',
+'exif-imagedescription' => 'Tiêu đề của hình',
+'exif-make' => 'Hãng máy ảnh',
+'exif-model' => 'Kiểu máy ảnh',
+'exif-software' => 'Phần mềm đã dùng',
+'exif-artist' => 'Tác giả',
+'exif-copyright' => 'Bản quyền',
+'exif-exifversion' => 'Phiên bản exif',
+'exif-makernote' => 'Lưu ý của nhà sản xuất',
+'exif-relatedsoundfile' => 'Tệp âm thanh liên quan',
+'exif-flash' => 'Đèn chớp',
+'exif-whitebalance' => 'Độ sáng trắng',
+'exif-contrast' => 'Độ tương phản',
+'exif-saturation' => 'Độ bão hòa',
+'exif-compression-1' => 'Không nén',
+'exif-orientation-1' => 'Thường',
+'exif-orientation-2' => 'Lộn ngược theo phương ngang',
+'exif-orientation-3' => 'Quay 180°',
+'exif-orientation-4' => 'Lộn ngược theo phương dọc',
+'exif-orientation-5' => 'Quay 90° bên trái và lộn thẳng đứng',
+'exif-orientation-6' => 'Quay 90° bên phải',
+'exif-orientation-7' => 'Quay 90° bên phải và lộn thẳng đứng',
+'exif-orientation-8' => 'Quay 90° bên trái',
+'exif-componentsconfiguration-0' => 'không có',
+'exif-aperturevalue' => 'Độ mở ống kính',
+'exif-bitspersample' => 'Bit trên mẫu',
+'exif-brightnessvalue' => 'Độ sáng',
+'exif-cfapattern' => 'Mẫu CFA',
+'exif-colorspace' => 'Không gian màu',
+'exif-componentsconfiguration' => 'Ý nghĩa thành phần',
+'exif-compressedbitsperpixel' => 'Độ nén (bit/điểm)',
+'exif-contrast-0' => 'Thường',
+'exif-contrast-1' => 'Nhẹ',
+'exif-contrast-2' => 'Mạnh',
+'exif-customrendered' => 'Sửa hình thủ công',
+'exif-customrendered-0' => 'Thường',
+'exif-customrendered-1' => 'Thủ công',
+
+
+# Info
+"infosubtitle" => "Thông tin về trang",
+"numedits" => "Số lần sửa đổi (bài chính): $1",
+"numtalkedits" => "Số lần sửa đổi (trang thảo luận): $1",
+"numwatchers" => "Số người theo dõi: $1",
+"numauthors" => "Số người sửa đổi khác nhau (bài chính): $1",
+"numtalkauthors" => "Số người sửa đổi khác nhau (trang thảo luận): $1",
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Thành viên:',
+'speciallogtitlelabel' => 'Tên bài:',
+
+#Logs
+'alllogstext' => 'Xem nhật trình tải lên, xóa, khóa, cấm, quản lý. Có thể xem theo từng loại, theo tên thành viên, hoặc tên trang.',
+'allnotinnamespace' => 'Mọi trang (không trong không gian $1)',
+'allpagesfrom' => 'Xem trang từ:',
+
+# new stuffs
+'already_bureaucrat' => 'Người này đã là tổng quản lý',
+'already_sysop' => 'Người này đã là quản lý',
+'changed' => 'Đã sửa',
+'compareselectedversions' => 'So sánh các bản đã chọn',
+'createarticle' => 'Viết bài mới',
+'created' => 'đã viết mới',
+'currentevents-url' => 'Thời_sự',
+'currentrevisionlink' => 'xem bản hiện nay',
+'data' => 'dữ liệu',
+'default' => 'mặc định',
+'delete_and_move' => 'Xóa và đổi tên',
+'delete_and_move_reason' => 'Xóa để có chỗ đổi tên',
+'delete_and_move_text' => ' ==Cần xóa==
+Bài với tên "[[$1]]" đã tồn tại. Bạn có muốn xóa nó để di chuyển tới tên này không?',
+'deletedrev' => '[đã xóa]',
+'destfilename' => 'Tên mới',
+'edit-externally'=> 'Sửa bằng phần mềm bên ngoài',
+'edit-externally-help' => '* Xem thêm [http://meta.wikimedia.org/wiki/Help:External_editors hướng dẫn bằng tiếng Anh]',
+
+'emptyfile' => 'Tệp tin tải lên là rỗng. Xin kiểm tra lại tên tệp tin.',
+'enotif_body' => 'Gửi $WATCHINGUSERNAME, trang $PAGETITLE tại {{SITENAME}} đã được $CHANGEDORCREATED vào $PAGEEDITDATE bởi $PAGEEDITOR, xem {{fullurl:$PAGETITLE_RAWURL}} để biết phiên bản hiện nay. Tóm tắt của $NEWPAGE: $PAGESUMMARY $PAGEMINOREDIT Liên hệ người sửa: thư {{fullurl:Special:Emailuser|target=$PAGEEDITOR_RAWURL}} {{fullurl:User:$PAGEEDITOR_RAWURL}} Sẽ không có thông báo mới nếu bạn không xem trang này. Bạn có thể thay đổi các cài đặt về các trang theo dõi. Hệ thống thông báo {{SITENAME}} -- Để thay đổi cài đặt, mời vào {{fullurl:Special:Watchlist|edit=yes}} Góp ý của bạn: {{fullurl:Help:Contents}}',
+'enotif_lastvisited' => 'Xem {{fullurl:$PAGETITLE_RAWURL|diff=0&oldid=$OLDID}} để biết các thay đổi từ khi bạn xem lần cuối.',
+'enotif_mailer' => 'Thông báo của {{SITENAME}}',
+'enotif_newpagetext' => 'Trang này mới',
+'enotif_reset' => 'Đánh dấu đã xem mọi trang',
+'enotif_subject' => '$PAGETITLE tại {{SITENAME}} đã thay đổi $CHANGEDORCREATED bởi $PAGEEDITOR',
+'excontentauthor' => 'nội dung cũ: "$1" (người viết duy nhất "$2")',
+'externaldberror' => 'Có thể có lỗi cơ sở dữ liệu hoặc bạn không thể cập nhật tài khoản bên ngoài.',
+'files' => 'Tệp tin',
+'histfirst' => 'cũ nhất',
+'histlast' => 'mới nhất',
+'imagelistall' => 'tất cả',
+'immobile_namespace' => 'Tên mới đặc biệt; không đổi sang tên đó được.',
+'importinterwiki' => 'Nhập giữa các wiki',
+'importnosources' => 'Không có nguồn nhập giữa wiki và việc nhập lịch sử bị tắt.',
+'info_short' => 'Thông tin',
+'intl' => 'Liên kết liên ngôn ngữ',
+'invalidemailaddress' => 'Địa chỉ thư điện tử có vẻ sai. Xin nhập lại.',
+'invert' => 'Đảo ngược lựa chọn',
+'ipboptions' => '2 giờ:2 hours,1 ngày:1 day,3 ngày:3 days,1 tuần:1 week,2 tuần:2 weeks,1 tháng:1 month,3 tháng:3 months,6 tháng:6 months,1 năm:1 year,vô hạn:infinite',
+'ipbother' => 'Thời hạn khác',
+'ipbotheroption' => 'khác',
+'log' => 'Nhật trình',
+"mainpagedocfooter" => "Xin đọc [http://meta.wikimedia.org/wiki/MediaWiki_i18n tài liệu hướng dẫn cách tùy biến giao diện] và [http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Cẩm nang sử dụng] (bằng tiếng Anh) để biết cách dùng và thiết lập thông số.",
+'mediawarning' => " '''Cảnh báo''': Tệp tin này có thể làm hại máy tính của bạn. <hr />",
+'movelogpage' => 'Nhật trình đổi tên',
+'movelogpagetext' => 'Các trang bị đổi tên.',
+'namespace' => 'Không gian:',
+"newwindow" => "(mở cửa sổ mới)",
+'nextpage' => 'Bài sau ($1)',
+'noemailprefs' => '<strong>Không có địa chỉ thư điện tử</strong>, chức năng sau có thể không hoạt động.',
+'noimages' => 'Chưa có hình',
+'nonunicodebrowser' => '<strong>CHU Y: Trinh duyet cua ban khong ho tro Unicode, xin sua lai truoc khi viet bai.</strong><strong>WARNING: Your browser is not unicode compliant, please change it before editing an article.</strong>',
+'number_of_watching_users_pageview' => ' [$1 người xem]',
+'passwordtooshort' => 'Mật khẩu cần chứa ít nhất $1 chữ.',
+'perfcached' => 'Dữ liệu sau lấy từ bộ nhớ đệm và có thể không cập nhật:',
+'prefs-help-email-enotif' => 'Địa chỉ thư này cũng được dùng để gửi bạn thư thông báo nếu bạn lựa chọn chức năng này.',
+'print' => 'In',
+'recentchangesall' => 'tất cả',
+'restrictedpheading' => 'Trang đặc biệt hạn chế',
+'revertmove' => 'lùi lại',
+'saveusergroups' => 'Lưu nhóm thành viên',
+'scarytranscludedisabled' => 'Liên wiki bị tắt',
+'scarytranscludefailed' => 'Tiêu bản cho $1 bị tắt',
+'scarytranscludetoolong' => 'Địa chỉ mạng dài quá',
+'searchfulltext' => 'Tìm toàn văn',
+'shareduploadwiki' => 'Xin xem thêm [$1 mô tả tệp tin]',
+'showdiff' => 'Xem thay đổi',
+'sourcefilename' => 'Tên tệp tin nguồn',
+
+'templatesused' => 'Các tiêu bản dùng trong trang này',
+'thumbsize' => 'Kích thước thu nhỏ:&nbsp;',
+'tooltip-diff' => 'Xem thay đổi bạn đã thực hiện [alt-v]',
+'tryexact' => 'Thử tìm đoạn văn khớp chính xác với từ khóa',
+'upload_directory_read_only' => 'Thư mục tải lên không ghi vào được',
+'uploadvirus' => 'Tệp tin có virút: $1',
+'userrights' => 'Quản lý quyền thành viên',
+'views' => 'Xem',
+'watchlistall1' => 'tất cả',
+'watchlistall2' => 'tất cả',
+'wlheader-enotif' => '* Đã bật thông báo qua thư điện tử.',
+'wlheader-showupdated' => "* Các trang đã thay đổi từ lần cuối bạn xem chúng được in '''đậm'''",
+'wlhideshowown' => '$1 sửa đổi của tôi',
+'yourdomainname' => 'Tên miền của bạn',
+'yourvariant' => 'Ngôn ngữ địa phương',
+'sitesupport-url' => '{{ns:4}}:Quyên_góp',
+'uploadnewversion-linktext' => 'Tải lên phiên bản mới',
+'selfmove' => 'Tên mới giống tên cũ; không đổi tên được.',
+'ipadressorusername' => 'Địa chỉ IP hay tên thành viên',
+'fileinfo' => ' $1Ko, kiểu MIME: <tt>$2</tt>',
+'groups' => 'Các nhóm',
+'noimage' => 'Không có hình này, bạn có thể [$1 tải nó lên]',
+'proxyblocksuccess' => "Xong.",
+
+'namespacesall' => 'tất cả',
+'fileuploadsummary' => 'tóm tắt',
+'prefixindex' => 'Mục lục theo không gian tên',
+'mostlinked'=>'Trang được liên kết đến nhiều nhất',
+'unusedcategories' => 'Thể loại chưa dùng',
+'permalink' => 'Liên kết thường trực',
+'noimage-linktext' => 'tải lên',
+'nolicense' => 'chưa chọn',
+
+# Còn cần việt hóa phần exif rất dài nữa
+
+// exifgps:
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesVls.php b/languages/messages/MessagesVls.php
new file mode 100644
index 000000000000..4844183890f4
--- /dev/null
+++ b/languages/messages/MessagesVls.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * West Flemish (West-Vlams)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+*/
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Specioal',
+ NS_MAIN => '',
+ NS_TALK => 'Discuusje',
+ NS_USER => 'Gebruker',
+ NS_USER_TALK => 'Discuusje_gebruker',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => 'Discuusje_$1',
+ NS_IMAGE => 'Ofbeeldienge',
+ NS_IMAGE_TALK => 'Discuusje_ofbeeldienge',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'Discuusje_MediaWiki',
+ NS_TEMPLATE => 'Patrôon',
+ NS_TEMPLATE_TALK => 'Discuusje_patrôon',
+ NS_HELP => 'Ulpe',
+ NS_HELP_TALK => 'Discuusje_ulpe',
+ NS_CATEGORY => 'Categorie',
+ NS_CATEGORY_TALK => 'Discuusje_categorie',
+);
+
+?>
diff --git a/languages/messages/MessagesWa.php b/languages/messages/MessagesWa.php
new file mode 100644
index 000000000000..282e350b5964
--- /dev/null
+++ b/languages/messages/MessagesWa.php
@@ -0,0 +1,1768 @@
+<?php
+/**
+ * Walloon (Walon)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ "Nole bår", "Aclawêye a hintche", "Aclawêye a droete", "Flotante a hintche", "Flotante a droete"
+);
+
+# lists "no preferences", normall (long) walloon date,
+# short walloon date, and ISO format
+# MW_DATE_DMY is alias for long format, as it is dd mmmmm yyyy.
+$datePreferences = array(
+ 'default',
+ 'dmy',
+ 'walloon short',
+ 'ISO 8601'
+);
+
+$datePreferenceMigrationMap = array(
+ 0 => 'default',
+ 2 => 'dmy',
+ 4 => 'walloon short',
+);
+$defaultDateFormat = 'dmy';
+
+$dateFormats = array(
+ 'walloon short time' => 'H:i'
+);
+
+$namespaceNames = array(
+ NS_MEDIA => "Media", /* Media */
+ NS_SPECIAL => "Sipeciås", /* Special */
+ NS_MAIN => "",
+ NS_TALK => "Copene", /* Talk */
+ NS_USER => "Uzeu", /* User */
+ NS_USER_TALK => "Uzeu_copene", /* User_talk */
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_copene',
+ NS_IMAGE => "Imådje", /* Image */
+ NS_IMAGE_TALK => "Imådje_copene", /* Image_talk */
+ NS_MEDIAWIKI => "MediaWiki", /* MediaWiki */
+ NS_MEDIAWIKI_TALK => "MediaWiki_copene", /* MediaWiki_talk */
+ NS_TEMPLATE => "Modele",
+ NS_TEMPLATE_TALK => "Modele_copene",
+ NS_HELP => "Aidance",
+ NS_HELP_TALK => "Aidance_copene",
+ NS_CATEGORY => "Categoreye",
+ NS_CATEGORY_TALK => "Categoreye_copene",
+);
+
+# definixha del cogne po les limeros
+# (number format definition)
+# en: 12,345.67 -> wa: 12 345,67
+$separatorTransformTable = array(',' => "\xc2\xa0", '.' => ',' );
+
+#$linkTrail = '/^([a-zåâêîôûçéèA-ZÅÂÊÎÔÛÇÉÈ]+)(.*)$/sDu';
+$linkTrail = '/^([a-zåâêîôûçéè]+)(.*)$/sDu';
+
+#
+# NOTE:
+# sysop = manaedjeu
+# bureaucrat = mwaisse-manaedjeu
+#
+
+$messages = array(
+# User preference toggles
+'tog-underline' => 'Sorlignî les loyéns',
+'tog-highlightbroken' => 'Håyner les vudes loyéns <a href="" class="new">come çouchal</a><br /> &nbsp;&nbsp;&nbsp; (oudonbén: come çouchal<a href="" class="internal">?</a>).',
+'tog-justify' => 'Djustifyî les hagnons',
+'tog-hideminor' => 'Èn nén moster les <i>dierins candjmints</i> mineurs',
+'tog-extendwatchlist' => 'Ragrandi l\' djivêye po mostrer tos les candjmints',
+'tog-usenewrc' => 'Ramidrés <i>dierins candjmints</i> (JavaScript)',
+'tog-numberheadings' => 'Limerotaedje otomatike des tites',
+'tog-showtoolbar' => 'Mostrer l\' bår d\' usteyes e môde candjmint (JavaScript)',
+'tog-editondblclick' => 'Candjî les pådjes avou on dobe-clitch (JavaScript)',
+'tog-editsection' => 'Eployî les loyéns «[candjî]» po candjî rén k\' ene seccion',
+'tog-editsectiononrightclick' => 'Candjî les seccions avou on dobe-clitch sol tite (JavaScript)',
+'tog-showtoc' => 'Mostrer l\' tåvlea d\' ådvins<br />(po ls årtikes avou pus di 3 seccions)',
+'tog-rememberpassword' => 'Rimimbrer li scret inte les sessions',
+'tog-editwidth' => 'Li boesse d\' aspougnaedje prind tote li lårdjeu',
+'tog-watchcreations' => 'Mete les pådjes ki dj\' askepieye dins l\' djivêye des pådjes shuvowes',
+'tog-watchdefault' => 'Shuve les årtikes ki dj\' fwai ou ki dj\' candje',
+'tog-minordefault' => 'Prémete mes candjmints come mineurs',
+'tog-previewontop' => 'Prévey l\' årtike å dzeu del boesse d\' aspougnaedje',
+'tog-previewonfirst' => 'Prévey l\' årtike å prumî candjmint',
+'tog-nocache' => 'Èn nén eployî d\' muchete pol håynaedje des pådjes',
+'tog-enotifwatchlistpages' => 'M\' emiler cwand ene pådje shuvowe candje',
+'tog-enotifusertalkpages' => 'M\' emiler cwand l\' pådje di copene da minne candje',
+'tog-enotifminoredits' => 'M\' emiler eto po les ptits candjmints',
+'tog-enotifrevealaddr' => 'Moster mi adresse emile dins les emiles di notifiaedje',
+'tog-shownumberswatching' => 'Mostrer l\' nombe d\' uzeus ki shuvèt l\' pådje',
+'tog-fancysig' => 'Sinateure brute (sins loyén otomatike)',
+'tog-showjumplinks' => 'Mete en alaedje les loyéns di naiviaedje «potchî a» å dzeu del pådje (pol pea «Myskin» et ds ôtes)',
+'tog-uselivepreview' => 'Eployî l\' prévoeyaedje abeye (JavaScript) (Esperimintå)',
+'tog-forceeditsummary' => 'M\' advierti cwand dji lai vude on rascourti',
+'tog-watchlisthideown' => 'Èn nén mostrer les candjmints da minne',
+'tog-watchlisthidebots' => 'Èn nén mostrer les candjmints des robots',
+
+'underline-always' => 'Tofer',
+'underline-never' => 'Måy',
+'underline-default' => 'Valixhance do betchteu',
+
+'skinpreview' => '(vey divant)',
+
+# dates
+'sunday' => 'dimegne',
+'monday' => 'londi',
+'tuesday' => 'mårdi',
+'wednesday' => 'mierkidi',
+'thursday' => 'djudi',
+'friday' => 'vénrdi',
+'saturday' => 'semdi',
+'january' => 'djanvî',
+'february' => 'fevrî',
+'march' => 'måss',
+'april' => 'avri',
+'may_long' => 'may',
+'june' => 'djun',
+'july' => 'djulete',
+'august' => 'awousse',
+'september' => 'setimbe',
+'october' => 'octôbe',
+'november' => 'nôvimbe',
+'december' => 'decimbe',
+'jan' => 'dja',
+'feb' => 'fev',
+'mar' => 'mås',
+'apr' => 'avr',
+'may' => 'may',
+'jun' => 'djn',
+'jul' => 'djl',
+'aug' => 'awo',
+'sep' => 'set',
+'oct' => 'oct',
+'nov' => 'nôv',
+'dec' => 'dec',
+
+# Bits of text used by many pages:
+#
+'categories' => 'Categoreyes',
+'pagecategories' => '{{PLURAL:$1|Categoreye|Categoreyes}}',
+'category_header' => 'Årtikes el categoreye «$1»',
+'subcategories' => 'Dizo-categoreyes',
+#'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD',
+'mainpage' => 'Mwaisse pådje',
+'mainpagetext' => '<big>\'\'\'Li programe Wiki a stî astalé a l\' idêye.\'\'\'</big>',
+
+'portal' => 'Inte di nozôtes',
+'portal-url' => '{{ns:project}}:Inte di nozôtes',
+'about' => 'Åd fwait',
+'aboutsite' => 'Åd fwait di {{SITENAME}}',
+'aboutpage' => '{{ns:project}}:Åd fwait',
+'article' => 'Årtike',
+'help' => 'Aidance',
+'helppage' => '{{ns:help}}:Aidance',
+'bugreports' => 'Rapoirts di bugs',
+'bugreportspage' => '{{ns:project}}:Rapoirts di bugs',
+'sitesupport' => 'Ecwårlaedje',
+'sitesupport-url' => '{{ns:project}}:Ecwårlaedje',
+'faq' => 'FAQ',
+'faqpage' => '{{ns:project}}:FAQ',
+'edithelp' => 'Aidance',
+'newwindow' => '(drovant en on novea purnea)',
+'edithelppage' => '{{ns:help}}:Kimint candjî ene pådje',
+'cancel' => 'Rinoncî',
+'qbfind' => 'Trover',
+'qbbrowse' => 'Foyter',
+'qbedit' => 'Candjî',
+'qbpageoptions' => 'Cisse pådje ci',
+'qbpageinfo' => 'Contecse',
+'qbmyoptions' => 'Mes pådjes',
+'qbspecialpages' => 'Pådjes sipeciåles',
+'moredotdotdot' => 'Co dpus...',
+'mypage' => 'Mi pådje',
+'mytalk' => 'Mi copinaedje',
+'anontalk' => 'Pådje di copene po ciste adresse IP',
+'navigation' => 'Naiviaedje',
+
+# Metadata in edit box
+'metadata_help' => 'Meta-dnêyes (loukîz [[{{ns:project}}:Meta-dnêyes]] po pus di racsegnes)',
+
+'currentevents' => 'Actouwålités',
+'currentevents-url' => 'Actouwålités',
+
+'errorpagetitle' => 'Aroke',
+'returnto' => 'Rivni al pådje «$1».',
+'tagline' => 'Èn årtike di {{SITENAME}}.',
+'search' => 'Cweri',
+'searchbutton' => 'Cweri',
+'go' => 'Potchî',
+'searcharticle' => 'Potchî',
+'history' => 'Istwere del pådje',
+'history_short' => 'Istwere',
+'updatedmarker' => 'candjî dispoy mi dierinne vizite',
+'info_short' => 'Informåcions',
+'printableversion' => 'Modêye sicrirece-amiståve',
+'print' => 'Imprimer',
+'edit' => 'Candjî',
+'editthispage' => 'Candjî l\' pådje',
+'delete' => 'Disfacer',
+'deletethispage' => 'Disfacer l\' pådje',
+'undelete_short' => 'Rapexhî $1 candjmints',
+'protect' => 'Protedjî',
+'protectthispage' => 'Protedjî l\' pådje',
+'unprotect' => 'Disprotedjî',
+'unprotectthispage' => 'Disprotedjî l\' pådje',
+'newpage' => 'Novele pådje',
+'talkpage' => 'Copene sol pådje',
+'specialpage' => 'Pådje sipeciåle',
+'personaltools' => 'Usteyes da vosse',
+'postcomment' => 'Sicrire on comintaire',
+'articlepage' => 'Vey l\' årtike',
+'talk' => 'Copene',
+'toolbox' => 'Boesse ås usteyes',
+'userpage' => 'Vey li pådje di l\' uzeu',
+'projectpage' => 'Vey li meta-pådje',
+'imagepage' => 'Vey li pådje di l\' imådje',
+'viewtalkpage' => 'Vey li pådje di copene',
+'otherlanguages' => 'Ôtes lingaedjes',
+'redirectedfrom' => '(Redjiblé di $1)',
+'autoredircomment' => 'Redjiblaedje viè [[$1]]',
+'redirectpagesub' => 'Pådje di redjiblaedje',
+'lastmodifiedat' => 'Cisse pådje a stî candjeye pol dierin côp li $2, $1.',
+'viewcount' => 'Cisse pådje la a stî léjhowe {{PLURAL:$1|on côp|$1 côps}}.',
+'copyright' => 'Li contnou est dizo l\' $1.',
+'protectedpage' => 'Pådje protedjeye',
+'jumpto' => 'Potchî a:',
+'jumptonavigation' => 'naiviaedje',
+'jumptosearch' => 'cweri',
+
+'badaccess' => 'Åk n\' a nén stî avou les permissions',
+
+'versionrequired' => 'I vs fåt l\' modêye $1 di MediaWiki',
+'versionrequiredtext' => 'I vs fåt l\' modêye $1 di MediaWiki po-z eployî cisse pådje ci. Loukîz a [[Special:Version]]',
+
+'ok' => '\'l est bon',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => 'Prin del pådje «$1»',
+'youhavenewmessages' => 'Vos avoz des $1 ($2).',
+'newmessageslink' => 'noveas messaedjes',
+'newmessagesdifflink' => 'dierin candjmint',
+'editsection' => 'candjî',
+'editsectionhint' => 'Candjî l\' seccion: $1',
+'editold' => 'candjî',
+'toc' => 'Ådvins',
+'showtoc' => 'mostrer',
+'hidetoc' => 'catchî',
+'thisisdeleted' => 'Vey ou rapexhî $1?',
+'viewdeleted' => 'Vey $1?',
+'restorelink' => '{{PLURAL:$1|on candjmint disfacé|$1 candjmints disfacés}}',
+'feedlinks' => 'Sindicåcion:',
+'feed-invalid' => 'Sôre di sindicåcion nén valide.',
+#'anonnotice' => '-',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => 'Årtike',
+'nstab-user' => 'Pådje di l\' uzeu',
+'nstab-media' => 'Media',
+'nstab-special' => 'Sipeciås',
+'nstab-project' => 'Pådje',
+'nstab-image' => 'Imådje',
+'nstab-mediawiki' => 'Messaedje',
+'nstab-template' => 'Modele',
+'nstab-help' => 'Aidance',
+'nstab-category' => 'Categoreye',
+
+# Main script and global functions
+#
+'nosuchaction' => 'Nole sifwaite accion',
+'nosuchactiontext' => 'L\' accion specifieye pal hårdêye n\' est nén ricnoxhowe på wiki.',
+'nosuchspecialpage' => 'Nole sifwaite pådje',
+'nospecialpagetext' => 'Vos avoz dmandé ene pådje sipeciåle nén valide, po ene djivêye des pådjes sipeciåles valides, loukîz a [[{{ns:special}}:Specialpages]].',
+
+# General errors
+#
+'error' => 'Aroke',
+'databaseerror' => 'Åk n\' a nén stî avou l\' båze di dnêyes',
+'dberrortext' => 'Åk n\' a nén stî avou l\' sintacse do cweraedje del båze di dnêyes.
+Çoula pout esse cåze d\' on bug dins l\' programe.
+Li dierin cweraedje del båze di dnêyes di sayî esteut:
+<blockquote><tt>$1</tt></blockquote>
+a pårti del fonccion «<tt>$2</tt>».
+MySQL a rtourné l\' aroke «<tt>$3: $4</tt>».',
+'dberrortextcl' => 'Åk n\' a nén stî avou l\' sintacse do cweraedje del båze di dnêyes.
+Li dierin cweraedje del båze di dnêyes di sayî esteut:
+«$1»
+a pårti del fonccion «$2».
+MySQL a rtourné l\' aroke «$3: $4».',
+'noconnect' => 'Mande escuzes! Li wiki a des rujhes tecnikes pol moumint, eyet c\' est nén possibe di s\' raloyî al båze di dnêyes. <br />
+$1',
+'nodb' => 'Dji n\' sai tchoezi l\' båze di dnêyes $1',
+'cachederror' => 'Çou ki shût c\' est ene copeye e muchete del pådje k\' a stî dmandêye, et ça s\' pout ki ça n\' soeye nén a djoû.',
+'internalerror' => 'Divintrinne aroke',
+'filecopyerror' => 'Dji n\' a savou copyî l\' fitchî «$1» viè «$2».',
+'filerenameerror' => 'Dji n\' a savou rlomer l\' fitchî «$1» e «$2».',
+'filedeleteerror' => 'Dji n\' a savou disfacer l\' fitchî «$1».',
+'filenotfound' => 'Dji n\' a savou trover l\' fitchî «$1».',
+'unexpected' => 'Valixhance nén ratindowe: «$1»=«$2».',
+'badarticleerror' => 'Cisse accion la n\' si pout nén fé so cisse pådje ci.',
+'cannotdelete' => 'Dji n\' sai disfacer l\' pådje ou l\' imådje dimandêye (ça s\' pôreut k\' ene ôte sakî l\' a ddja disfacé).',
+'badtitle' => 'Måva tite',
+'badtitletext' => 'Li tite del pådje dimandêye n\' esteut nén valide, il estet vude, oudonbén c\' esteut on cron loyén eterlingaedje ou eterwiki. Ça s\' pout k\' il åye onk ou sacwants caracteres ki n\' polèt nén esse eployîs dins les tites.',
+'perfdisabled' => 'Mande escuzes! mins cisse fonccionålité ci a stî essoctêye pol moumint
+pask\' ele est trop pezante pol båze di dnêyes, ki dvént si télmint
+londjinne k\' on s\' endè pout pus siervi a môde di djin.',
+'perfdisabledsub' => 'Vochal ene copeye k\' a stî schapêye di $1:', # obsolete?
+'perfcached' => 'Les dnêyes ki shuvèt c\' est ene copeye e muchete, et ça s\' pout ki ça n\' soeye nén ttafwaitmint a djoû.',
+'perfcachedts' => 'Les dnêyes ki shuvèt c\' est ene copeye e muchete, ey elle ont stî metowes a djoû pol dierin côp li $1.',
+'wrong_wfQuery_params' => 'Parametes incoreks po wfQuery()<br />
+Fonccion: $1<br />
+Cweraedje: $2',
+'viewsource' => 'Vey côde sourdant',
+'viewsourcefor' => 'po $1',
+'protectedtext' => 'Cisse pådje chal a stî protedjeye siconte des candjmints;
+i gn a sacwantès råjhons po çoula, loukîz
+[[{{ns:project}}:Pådje protedjeye]] s\' i vs plait.
+
+Mins nerén vos ploz vey eyet copyî li côde sourdant del pådje:',
+'protectedinterface' => 'Cisse pådje ci dene on tecse d\' eterface pol programe, eyet elle a stî protedjeye po s\' waeranti siconte des abus.',
+'editinginterface' => '\'\'\'Asteme:\'\'\' Vos candjîz ene pådje k\' est eployeye po dner on tecse d\' eterface pol programe. Les candjmints a cisse pådje ci vont-st aveur èn efet so l\' eterface d\' uzeu des ôtes uzeus.',
+
+# Login and logout pages
+#
+'logouttitle' => 'Dislodjaedje',
+'logouttext' => '<strong>Vos vs avoz dislodjî.</strong><br />
+Vos ploz continouwer a naivyî so {{SITENAME}} anonimmint, oudonbén
+vos relodjî dizo l\' minme uzeu ou dizo èn uzeu diferin. Notez ki des
+pådjes k\' i gn a si pôrént continowuer a vey come si vos estîz elodjî,
+disk\' a tant ki vos vudrîz l\' muchete di vosse betchteu waibe.',
+
+'welcomecreation' => '== Bénvnowe, $1! ==
+
+Vosse conte a stî ahivé.
+Èn rovyîz nén di candjî les preferinces di {{SITENAME}} a vosse môde.',
+
+'loginpagetitle' => 'Elodjaedje',
+'yourname' => 'Vosse no d\' elodjaedje',
+'yourpassword' => 'Vosse sicret',
+'yourpasswordagain' => 'Ritapez vosse sicret',
+'remembermypassword' => 'Rimimbrer m\' sicret inte les sessions.',
+'yourdomainname' => 'Vosse dominne',
+'loginproblem' => '<b>Åk n\' a nén stî tot vs elodjant.</b><br />Rissayîz s\' i vs plait!',
+'alreadyloggedin' => '<span style="color:#ff0000"><strong>Uzeu $1, vos estoz ddja elodjî!</strong></span><br />',
+
+'login' => 'S\' elodjî',
+'loginprompt' => 'Vos dvoz permete les coûkes po vs elodjî so {{SITENAME}}.',
+'userlogin' => 'S\' elodjî',
+'logout' => 'Si dislodjî',
+'userlogout' => 'Si dislodjî',
+'notloggedin' => 'Nén elodjî',
+'nologin' => 'Vos n\' avoz nén d\' conte so ç\' wiki ci? $1.',
+'nologinlink' => 'Ahivez on conte da vosse',
+'createaccount' => 'Ahiver on novea conte',
+'gotaccount' => 'Vos avoz ddja on conte so ç\' wiki ci? $1.',
+'gotaccountlink' => 'Elodjîz vs',
+'createaccountmail' => 'pa emile',
+'badretype' => 'Vos avoz dné deus screts diferins.',
+'userexists' => 'Li no d\' uzeu ki vs avoz tchoezi est ddja eployî. Tchoezixhoz è èn ôte s\' i vs plait.',
+'youremail' => 'Vost emile*',
+'username' => 'No d\' elodjaedje:',
+'uid' => 'Limero d\' l\' uzeu:',
+'yourrealname' => 'Li vraiy no da vosse*',
+'yourlanguage' => 'Lingaedje po l\' eterface',
+'yourvariant' => 'Variante do lingaedje',
+'yournick' => 'Vosse no metou (po les sinateures)',
+'email' => 'Emile',
+'prefs-help-email-enotif' => 'Ciste adresse chal est ossu eployeye po vs evoyî des notifiaedjes pa emile si vos avoz tchoezi cisse tchuze la.',
+'prefs-help-realname' => '* Li vraiy no da vosse (opcionel): si vos tchoezixhoz del diner i serè-st eployî po les contribouwaedjes da vosse.',
+'loginerror' => 'Aroke d\' elodjaedje',
+'prefs-help-email' => '* Emile (opcionel): Permete di rçure des emiles ki ds ôtes uzeus vos polèt evoyî a pårti del pådje d\' uzeu da vosse, sins ki voste adresse emile ni soeye håynêye.',
+'nocookiesnew' => 'Li conte a stî ahivé, mins vos n\' estoz nén elodjî. {{SITENAME}} eploye des coûkes po l\' elodjaedje des uzeus. Vos avoz dismetou l\' sopoirt des coûkes dins vosse betchteu waibe; rimetoz l\' en alaedje et relodjîz vs avou vosse novea no d\' elodjaedje eyet scret, s\' i vs plait.',
+'nocookieslogin' => '{{SITENAME}} eploye des coûkes po l\' elodjaedje des uzeus. Vos avoz dismetou l\' sopoirt des coûkes dins vosse betchteu waibe; rimetoz l\' en alaedje et relodjîz vs s\' i vs plait.',
+'noname' => 'Vos n\' avoz nén dné di no d\' uzeu valide.',
+'loginsuccesstitle' => 'Vos estoz elodjî',
+'loginsuccess' => '\'\'\'L\' elodjaedje a stî comifåt, asteure vos estoz elodjî dins {{SITENAME}} dizo l\' no d\' uzeu «$1».\'\'\'',
+'nosuchuser' => 'I g na nou uzeu dizo l\' no «$1».
+Verifyîz çou k\' vos avoz tapé, oudonbén rimplixhoz les ôtes tchamps
+et clitchîz sol boton po-z ahiver on novea conte.',
+'nosuchusershort' => 'I g na nou uzeu dizo l\' no «$1». Verifyîz çou k\' vos avoz tapé.',
+'nouserspecified' => 'Vos dvoz dner on no d\' elodjaedje.',
+'wrongpassword' => 'Li scret ki vs avoz dné est måva. Rissayîz s\' i vs plait.',
+'wrongpasswordempty' => 'Vos avoz dné on vude sicret. Rissayîz s\' i vs plait.',
+'mailmypassword' => 'M\' emiler on novea scret',
+'passwordremindertitle' => 'Rimimbraedje do scret po {{SITENAME}}',
+'passwordremindertext' => 'Ene sakî (probåblumint vos-minme, avou l\' adresse IP $1) a dmandé k\' on vs emile on novea scret po {{SITENAME}} ($4).
+Li scret po l\' uzeu «$2» est asteure «$3».
+Po pus di såvrité, vos vos dvrîz elodjî eyet rcandjî vosse sicret å pus abeye.
+
+Si ene ôte sakî a fwait l\' dimande, ou si vos vs avoz rtrové l\' vî scret eyet nel plus vleur candjî, vos ploz djusse ignorer ci messaedje ci eyet continouwer avou l\' vî scret.',
+'noemail' => 'I n\' a pont d\' adresse emile di cnoxhowe po l\' uzeu «$1».',
+'passwordsent' => 'On novea scret a stî emilé a l\' adresse emile
+racsegneye po l\' uzeu «$1».
+Relodjîz vs avou ç\' noû scret on côp ki vos l\' åroz rçuvou s\' i vs plait.',
+'eauthentsent' => 'Èn emile d\' acertinaedje a stî evoyî a l\' adresse emile tchoezeye.
+Divant d\' poleur evoyî èn ôte emile a ci conte la, vos dvroz shure les instruccions di l\' emile ki vos alez rçure, po-z acertiner ki l\' conte est bén da vosse.',
+#'signupend' => '{{int:loginend}}',
+'mailerror' => 'Åk n\' a nén stî tot-z evoyant l\' emile: $1',
+'acct_creation_throttle_hit' => 'Mande escuzes, mins vos avoz ddja ahivé $1 contes. Vos n\' endè ploz nén fé des ôtes.',
+'emailauthenticated' => 'Voste adresse emile a stî acertinêye li $1.',
+'emailnotauthenticated' => 'Voste adresse emile n\' a nén co stî acertinêye. Nol emile ni serè-st evoyî po les fonccions shuvantes.',
+'noemailprefs' => '<strong>Dinez ene adresse emile po ces fonccions si mete en alaedje.</strong>',
+'emailconfirmlink' => 'Acertinaedje di voste adresse emile',
+'invalidemailaddress' => 'L\' adresse emile ni pout nén esse acceptêye la k\' i shonnreut k\' ele soeye dins ene cogne nén valide. Tapez ene adresse emile sicrîte comifåt oudobén vudîz l\' tchamp, s\' i vs plait.',
+'accountcreated' => 'Conte ahivé',
+'accountcreatedtext' => 'Li conte d\' uzeu «$1» a stî ahivé.',
+
+# Edit page toolbar
+'bold_sample' => 'Cråssès letes',
+'bold_tip' => 'Tecse e cråssès letes',
+'italic_sample' => 'Clintcheyès letes',
+'italic_tip' => 'Tecse e clintcheyès letes',
+'link_sample' => 'Tecse pol loyén',
+'link_tip' => 'Divintrin loyén',
+'extlink_sample' => 'http://www.egzimpe.com tecse pol hårdêye',
+'extlink_tip' => 'Difoûtrinne hårdêye (en rovyîz nén di mete «http://» pa dvant)',
+'headline_sample' => 'Tecse di tite',
+'headline_tip' => 'Tite di 2inme livea',
+'math_sample' => 'Tapez l\' formule matematike chal',
+'math_tip' => 'Formule matematike (LaTeX)',
+'nowiki_sample' => 'Tapez l\' tecse nén wiki chal',
+'nowiki_tip' => 'Èn nén analijhî des côdes wiki, eyet purade les håyner sins formater',
+'image_sample' => 'Egzimpe.jpg',
+'image_tip' => 'Ravalêye imådje',
+'media_sample' => 'Egzimpe.ogg',
+'media_tip' => 'Loyén viè on fitchî multimedia (come do son evnd)',
+'sig_tip' => 'Li sinateure da vosse, avou l\' date et l\' eure',
+'hr_tip' => 'Roye di coûtchî (a n\' nén eployî d\' trop)',
+
+# Edit pages
+#
+'summary' => 'Rascourti',
+'subject' => 'Sudjet/tiestire',
+'minoredit' => 'Ci n\' est k\' ene tchitcheye',
+'watchthis' => 'Shuve cist årtike',
+'savearticle' => 'Schaper l\' pådje',
+'preview' => 'Vey divant',
+'showpreview' => 'Vey divant',
+'showdiff' => 'Vey les candjmints',
+'anoneditwarning' => '\'\'\'Asteme:\'\'\' Vos n\' estoz nén elodjî. Voste adresse IP serè rashiowe dins l\' istwere di cisse pådje ci.',
+'missingsummary' => '\'\'\'Asteme:\'\'\' Vos n\' avoz nén dné on tecse di rascourti po vosse candjmint. Si vos rclitchîz sol boton «Schaper», li candjmint da vosse serè schapé sins nou tecse di rascourti po l\' istwere del pådje.',
+'missingcommenttext' => 'Tapez on comintaire chal pa dzo s\' i vs plait.',
+'blockedtitle' => 'L\' uzeu est bloké',
+'blockedtext' => 'Vosse no d\' uzeu ou voste adresse IP a stî blokêye pa $1.
+Li råjhon dnêye est:<br />\'\'$2\'\'<p>Vos ploz contacter $1 oudonbén onk des
+[[{{ns:project}}:Manaedjeus|manaedjeus]] po discuter do blocaedje.
+
+Notez ki vos n\' poloz nén eployî l\' fonccion «emiler a l\' uzeu» a moens ki vos åyîz ene adresse emile valide dins vos [[{{ns:special}}:Preferences|preferinces]].
+
+Voste adresse IP est $3. S\' i vs plait racsegnoz ciste adresse IP la dins les dmandes ki vos frîz.',
+'whitelistedittitle' => 'S\' elodjî po candjî',
+'whitelistedittext' => 'I vs fåt $1 po pleur candjî les årtikes.',
+'whitelistreadtitle' => 'S\' elodjî po lére',
+'whitelistreadtext' => 'I vs fåt [[{{ns:special}}:Userlogin|elodjî]] po pleur lére les årtikes.',
+'whitelistacctitle' => 'Vos n\' avoz nén l\' permission d\' ahiver on conte chal',
+'whitelistacctext' => 'Po pleur ahiver on conte so ç\' Wiki chal, vos dvoz esse [[{{ns:special}}:Userlogin|elodjî]] ey aveur les bounès permissions.',
+'confirmedittitle' => 'Acertiner vost emile po candjî',
+'confirmedittext' => 'I vs fåt acertiner vost emile po pleur candjî les årtikes. Dinez èn emile eyet l\' acertiner dins vos [[{{ns:special}}:Preferences|preferinces d\' uzeu]].',
+'loginreqtitle' => 'I vs fåt esse elodjî',
+'loginreqlink' => 'elodjî',
+'loginreqpagetext' => 'Vos vs divoz $1 po vey des ôtès pådjes.',
+'accmailtitle' => 'Li scret a stî evoyî.',
+'accmailtext' => 'Li scret po «$1» a stî evoyî a $2.',
+'newarticle' => '(Novea)',
+'newarticletext' => 'Vos avoz clitchî so on loyén viè ene pådje ki n\' egzistêye nén co.
+Mins \'\'\'vos\'\'\' l\' poloz askepyî! Po çoula, vos n\' avoz k\' a
+cmincî a taper vosse tecse dins l\' boesse di tecse chal pa dzo
+(alez vey li [[{{ns:project}}:Aidance|pådje d\' aidance]] po pus d\' informåcion).
+Si vos n\' voloz nén scrire cisse pådje chal, clitchîz simplumint
+sol boton \'\'\'En erî\'\'\' di vosse betchteu waibe po rivni al pådje di dvant.',
+#'newarticletextanon' => '{{int:newarticletext}}',
+'anontalkpagetext' => '---- \'\'Çouchal, c\' est li pådje di copene po èn uzeu anonime ki n\' a nén (co) fwait on conte por lu s\' elodjî, ou ki n\' l\' eploye nén. Ça fwait k\' on doet eployî si adresse IP limerike po l\' idintifyî. Come ene sifwaite adresse IP pout esse eployeye pa pus d\' èn uzeu, i s\' pout ki vos voeyoz chal des rmåkes et des messaedjes ki n\' sont nén por vos. Loukîz s\' i vs plait po [[{{ns:special}}:Userlogin|fé on novea conte ou s\' elodjî]] po n\' pus aveur d\' ecramiaedje avou des ôtes uzeus anonimes.\'\'',
+'noarticletext' => 'I gn a pol moumint nou tecse e cisse pådje chal, vos ploz [[{{ns:special}}:Search/{{PAGENAME}}|cweri après l\' tite di cisse pådje ci]] dins des ôtès pådjes, oudonbén [{{fullurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} ahiver l\' pådje].',
+#'noarticletextanon' => '{{int:noarticletext}}',
+'clearyourcache' => '\'\'\'Note:\'\'\' après aveur schapé l\' pådje, vos l\' divoz rafrister, po pleur vey les candjmints dins vosse betchteu waibe: \'\'\'Mozilla / Firefox / Safari:\'\'\' tchôkîz so \'\'Shift\'\' to clitchant so \'\'Rafrister\'\', ou co fjhoz \'\'Ctrl-Shift-R\'\' (\'\'Cmd-Shift-R\'\' so on Macintosh); \'\'\'IE:\'\'\' tchôkîz so \'\'Ctrl\'\' tot clitchant so \'\'Rafrister\'\', ou co fjhoz \'\'Ctrl-F5\'\'; \'\'\'Konqueror:\'\'\' simplumint clitchîz so \'\'Rafrister\'\' ou l\' tape \'\'F5\'\'; les uzeus d\' \'\'\'Opera\'\'\' dvront motoit netyî pår leu muchete, dins \'\'Usteyes→Preferinces\'\'.',
+'usercssjsyoucanpreview' => '<strong>Racsegne:</strong> eployîz l\' boton «Vey divant» po sayî vosse novea CSS/JS divant del schaper.',
+'usercsspreview' => '\'\'\'Èn rovyîz nén ki c\' est djusse on prévoeyaedje di vosse stîle CSS d\' uzeu, i n\' a nén co stî schapé!\'\'\'',
+'userjspreview' => '\'\'\'Èn rovyîz nén ki c\' est djusse on prévoeyaedje/saye di vosse JavaScript d\' uzeu, i n\' a nén co stî schapé!\'\'\'',
+'userinvalidcssjstitle' => '\'\'\'Asteme:\'\'\' I n\' a pont d\' pea lomêye «$1». Tuzez ki les pådjes .css eyet .js des uzeus eployèt des tite e ptitès letes, metans {{ns:user}}:Toto/monobook.css et nén {{ns:user}}:Toto/Monobook.css.',
+'updated' => '(Ramidré)',
+'note' => '<strong>Note:</strong>',
+'previewnote' => '<strong>Èn rovyîz nén ki c\' est djusse on prévoeyaedje, li pådje n\' est nén co schapêye!</strong>',
+'session_fail_preview' => '<strong>Mande escuzes! Mins dji n\' a nén polou traitî vosse candjmint paski les dnêyes del session ont stî pierdowes.
+Rissayîz s\' i vs plait. Si çoula n\' va todi nén, sayîz di vs dislodjî eyet di vs relodjî.</strong>',
+'previewconflict' => 'Ci prévoeyaedje ci mostere kimint kel tecse del boesse di tecse do dzeu sereut håyné si vos decidez di clitchî so «schaper».',
+# obsoleted?
+'editing' => 'Candjant $1',
+'editinguser' => 'Candjant $1',
+'editingsection' => 'Candjant $1 (seccion)',
+'editingcomment' => 'Candjant $1 (comintaire)',
+'editconflict' => 'Conflit inte deus candjmints: $1',
+'explainconflict' => 'Ene sakî a candjî l\' pådje do tins ki vos estîz a scrire.
+Li boesse di tecse do dzeur mostere li tecse del pådje come il est
+pol moumint sol sierveu. Li tecse da vosse est sol boesse di tecse do dzo.
+Les diferinces sont håynêyes å mitan. Vos dvoz mete vos candjmints dins
+l\' tecse d\' asteure (å dzeur) si vos lez vloz co evoyî.
+<b>Seulmint</b> li tecse do dzeur serè candjî cwand vos clitchroz sol
+boton «Schaper l\' pådje».<br />',
+'yourtext' => 'Li tecse da vosse',
+'storedversion' => 'Modêye sol sierveu',
+'nonunicodebrowser' => '<strong>ASTEME: li betchteu waibe da vosse ni sopoite nén l\' ecôdaedje unicôde, cåze di çoula les caracteres nén-ASCII vont aparexhe dins l\' boesse di tecse come des côdes hecsadecimås, insi vos pôroz tot l\' minme candjî l\' pådje.</strong>',
+'editingold' => '<strong>ASTEME: Vos estoz ki candje ene viye modêye del pådje.
+Si vos l\' schapez, tos les candjmints k\' ont stî fwaits
+dispoy adon si vont piede.</strong>',
+'yourdiff' => 'Diferinces',
+'copyrightwarning' => 'Notez ki tos les contribouwaedjes fwaits po {{SITENAME}}
+dvèt esse dizo l\' licince $2 (loukîz $1 po pus di racsegnes).
+Si vos n\' voloz nén ki vosse tecse poye esse candjî eyet
+spårdou pa tot l\' minme kî, adon nel evoyîz nén chal.
+<br />
+Vos nos acertinez eto ki vos avoz scrît l\' tecse
+vos-minme, oudonbén l\' avoz copyî d\' on sourdant libe
+(dominne publik ou on sourdant pareymint libe).
+<br />
+<strong>N\' EVOYÎZ NÉN DES TECSES DIZO ABONDROETS SINS PERMISSION!</strong>',
+'copyrightwarning2' => 'Notez ki tos les contribouwaedjes fwaits po {{SITENAME}}
+polèt esse esse candjîs ou disfacés pa des ôtes contribouweus.
+Si vos n\' voloz nén scrire des årtikes ki polèt esse
+candjîs pa des ôtes, adon nels evoyîz nén chal.
+<br />
+Vos nos acertinez eto ki vos avoz scrît l\' tecse
+vos-minme, oudonbén l\' avoz copyî d\' on sourdant libe
+(voeyoz $1 po pus di racsegnes).
+<br />
+<strong>N\' EVOYÎZ NÉN DES TECSES DIZO ABONDROETS SINS PERMISSION!</strong>',
+'longpagewarning' => '<strong>ASTEME: Cisse pådje fwait $1 kilo-octets; des
+betchteus waibes k\' i gn a polèt aveut des rujhes po-z aspougnî
+des pådjes k\' aprepièt ou di pus di 32Ko.
+Vos dvrîz tuzer a pårti l\' pådje e pus ptits bokets.</strong>',
+'longpageerror' => '<strong>AROKE: Li tecse ki vos avoz evoyî fwait di pus d\' $1 kilo-octets, çou k\' est pus ki l\' macsimom di $2 kilo-octets. C\' est nén possible del schaper sol sierveu.</strong>',
+'readonlywarning' => '<strong>ASTEME: On-z overe sol båze di dnêyes pol moumint, ey elle a stî metowe e mode seulmint-lére.
+Do côp, vos n\' såroz schaper vos candjmints asteure; motoit vos dvrîz copyî et aclaper l\' tecse dins on fitchî da vosse pol poleur rimete pus tård.</strong>',
+'protectedpagewarning' => '<strong>ASTEME: Cisse pådje chal a stî protedjeye siconte
+des candjmints, seulmint les uzeus avou èn accès di manaedjeu el polèt candjî.
+Acertinez vs ki vos shuvoz les [[{{ns:project}}:Pådje_protedjeye|rîles po les pådjes protedjeyes]].</strong>',
+'semiprotectedpagewarning' => '\'\'\'Note:\'\'\' cisse pådje ci a stî protedjeye po k\' seulmint les uzeus edjîstrés el polexhe candjî.',
+'templatesused' => 'Modeles eployîs e cisse pådje ci:',
+'edittools' => '<div id="editpage-specialchars" class="plainlinks" style="margin-top:1px; border-width:1px; border-style:solid; border-color:#aaaaaa; padding:2px;">
+<small>Ahessåvès letes (clitchîz po les taper):
+<charinsert>Å å Ç ç É é Ê ê È è Î î Ô ô Û û</charinsert> ·
+<charinsert>«+» [+] [[+]] {{+}} </charinsert> ·
+<charinsert>– — ~ | € ° º</charinsert>
+</small></div>',
+'nocreatetitle' => 'Ahivaedje di pådjes limité',
+'nocreatetext' => 'Cisse waibe ci a limité l\' possibilité d\' ahiver des novelès pådjes. Vos ploz rivni en erî eyet candjî ene pådje k\' egzistêye dedja, oudonbén, [[{{ns:special}}:Userlogin|vos elodjî ou ahiver on conte d\' uzeu]].',
+
+# History pages
+#
+'revhistory' => 'Istwere des modêyes',
+'nohistory' => 'I n\' a pont d\' istwere des modêyes po cisse pådje chal.',
+'revnotfound' => 'Modêye nén trovêye',
+'revnotfoundtext' => 'Li viye modêye del pådje ki vos avoz dmandé n\' a nén stî trovêye.
+Verifyîz l\' hårdêye ki vs avoz eployî po-z ariver sol pådje s\' i vs plait.',
+'loadhist' => 'Tcherdjaedje del pådje di l\' istwere',
+'currentrev' => 'Modêye d\' asteure',
+'revisionasof' => 'Modêye do $1',
+'previousrevision' => '←Modêye di dvant',
+'nextrevision' => 'Modêye shuvante→',
+'currentrevisionlink' => 'vey li modêye d\' asteure',
+'cur' => 'ast.',
+'next' => 'shuv.',
+'last' => 'dif.',
+'orig' => 'oridj.',
+'histlegend' => 'Tchoezi les modêyes a comparer: clitchîz so les botons radio des deus modêyes
+ki vos vloz comparer et s\' tchôkîz sol tape «enter» ou clitchîz sol
+boton do dzo.<br />
+Ledjinde: (ast.) = diferince avou l\' modêye d\' asteure,
+(dif.) = diferince avou l\' modêye di dvant, M = candjmint mineur.',
+'deletedrev' => '[disfacé]',
+'histfirst' => 'Li pus vî',
+'histlast' => 'Li dierin',
+'rev-deleted-comment' => '(comintaire oisté)',
+'rev-deleted-user' => '(no d\' elodjaedje oisté)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+Cisse modêye ci del pådje a stî oistêye foû des årtchives publikes.
+I gn a motoit des racsegnes sol [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} djournå des disfaçaedjes].
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+Cisse modêye ci del pådje a stî oistêye foû des årtchives publikes.
+Come manaedjeu so ç\' wiki ci, vos avoz l\' droet del vey; i gn a motoit des detays sol [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} djournå des disfaçaedjes].
+</div>',
+'rev-delundel' => 'mostrer/catchî',
+
+'history-feed-item-nocomment' => '$1 li $2', # user at time
+
+# Revision deletion
+#
+'revisiondelete' => 'Disfacer/rapexhî des modêyes',
+'revdelete-selected' => 'Tchoezeye modêye di [[:$1]]:',
+'revdelete-text' => 'Les disfacêyès modêyes vont continouwer d\' aparexhe dins l\' pådje di l\' istwere, mins leu contnou n\' serè nén veyåve do publik.
+
+Les ôtes manaedjeus so ç\' wiki ci pôront todi vey li contnou catchî eyet l\' rapexhî åd triviè di cisse minme eterface ci, a moens k\' ene restriccion di pus ni soeye metowe en alaedje pås mwaisses-manaedjeus del waibe.',
+'revdelete-legend' => 'Defini des restriccions sol modêye:',
+'revdelete-hide-text' => 'Catchî l\' tecse del modêye',
+'revdelete-hide-comment' => 'Catchî l\' comintaire di candjmint',
+'revdelete-hide-user' => 'Catchî l\' no d\' uzeu/adresse IP do candjeu',
+'revdelete-hide-restricted' => 'Apliker ces restrictions ossu åzès manaedjeus',
+'revdelete-log' => 'Comintaire pol djournå:',
+'revdelete-submit' => 'Apliker al modêye tchoezeye',
+'revdelete-logentry' => 'li veyåvisté des modêyes a stî candjeye po [[$1]]',
+
+# Diffs
+#
+'difference' => '(Diferinces inte les modêyes)',
+'loadingrev' => 'tcherdjaedje del modêye po les diferinces',
+'lineno' => 'Roye $1:',
+'editcurrent' => 'Candjî li modêye do moumint di cisse pådje chal',
+'selectnewerversionfordiff' => 'Tchoezi ene nouve modêye po comparer',
+'selectolderversionfordiff' => 'Tchoezi ene modêye pus viye po comparer',
+'compareselectedversions' => 'Comparer les modêyes tchoezeyes',
+
+# Search results
+#
+'searchresults' => 'Rizultats do cweraedje',
+'searchresulttext' => 'Po pus di racsegnes sol manire di fé des cweraedjes so {{SITENAME}}, loukîz [[{{ns:project}}:Cweraedje|Cweraedje so {{SITENAME}}]].',
+'searchsubtitle' => 'Pol cweraedje «[[:$1]]»',
+'searchsubtitleinvalid' => 'Pol cweraedje «$1»',
+'badquery' => 'Halcrosse tchinne di cweraedje',
+'badquerytext' => 'Vosse cweraedje èn s\' a nén polou fé.
+C\' est motoit bén paski vos avoz sayî d\' cweri
+après on mot di moens di troes letes, çou ki n\' est
+nén co sopoirté.
+I s\' pout eto ki vos avoz må tapé l\' ratourneure,
+metans «oujhea eyet eyet plomes».
+Rissayîz avou ene ôte tchinne di cweraedje.',
+'matchtotals' => 'Li cweraedje «$1» a trové $2 {{PLURAL:$2|årtike|årtikes}} avou l\' tite ki corespond eyet $3 {{PLURAL:$3|årtike|årtikes}} avou do tecse ki corespond.',
+'noexactmatch' => '\'\'\'I n\' a nole pådje avou l\' tite «$1».\'\'\' Vos poloz [[:$1|ahiver cisse pådje la]].',
+'titlematches' => 'Årtikes avou on tite ki corespond',
+'notitlematches' => 'Nol årtike avou on tite ki corespond',
+'textmatches' => 'Årtikes avou do tecse ki corespond',
+'notextmatches' => 'Nol årtike avou do tecse ki corespond',
+'prevn' => '$1 di dvant',
+'nextn' => '$1 shuvants',
+'viewprevnext' => 'Vey ($1) ($2) ($3).',
+'showingresults' => 'Chal pa dzo <b>$1</b> rizultats a pårti do limero <b>$2</b>.',
+'showingresultsnum' => 'Chal pa dzo <b>$3</b> rizultats a pårti do limero <b>$2</b>.',
+'nonefound' => '\'\'\'Note\'\'\': des cweraedjes ki n\' dinèt nou rzultat c\' est sovint li cweraedje di ptits mots trop corants (come «les», «des») ki n\' sont nén indecsés, oudonbén des cweraedjes di pus d\' on mot (seulmint les pådjes avou tos les mots dmandés sront håynêyes dins l\' rizultat do cweraedje).',
+'powersearch' => 'Cweri',
+'powersearchtext' => 'Cweraedje ezès espåces di nos:<br />$1<br />$2 Håyner les redjiblaedjes &nbsp; Cweri après $3 $9',
+'searchdisabled' => 'Mande escuzes! Li cweraedje å dvins des årtikes a stî dismetou pol moumint, cåze ki l\' sierveu est fortcherdjî. Tot ratindant, vos ploz eployî Google po fé les rcweraedjes so {{SITENAME}}, mins çoula pout esse ene miete vî.',
+
+'blanknamespace' => '(Mwaisse)',
+
+# Preferences page
+#
+'preferences' => 'Preferinces',
+'prefsnologin' => 'Vos n\' estoz nén elodjî',
+'prefsnologintext' => 'I vs fåt esse [[{{ns:special}}:Userlogin|elodjî]] po pleur candjî vos preferinces.',
+'prefsreset' => 'Les preferinces ont stî rmetowes come d\' avance a pårti des wårdêyès valixhances.',
+'qbsettings' => 'Apontiaedjes pol bår di menu',
+'changepassword' => 'Candjî l\' sicret',
+'skin' => 'Pea',
+'math' => 'Formules matematikes',
+'dateformat' => 'Cogne del date',
+'datedefault' => 'Nole preferince',
+'datetime' => 'Cogne del date',
+'math_unknown_error' => 'aroke nén cnoxhowe',
+'math_unknown_function' => 'fonccion nén cnoxhowe',
+'math_syntax_error' => 'aroke di sintacse',
+'math_image_error' => 'Li cviersaedje e PNG a fwait berwete; verifyîz ki les programes latex, dvips, gs eyet convert ont stî astalés comifåt',
+'math_bad_tmpdir' => 'Dji n\' sai nén scrire ou ahiver l\' ridant timporaire po les formules matematikes',
+'math_bad_output' => 'Dji n\' sai nén scrire ou ahiver l\' ridant po les fitchîs di rexhowe des formules matematikes',
+'math_notexvc' => 'I manke li fitchî enondåve texvc; lijhoz math/README po-z apontyî.',
+'prefs-personal' => 'Dinêyes da vosse',
+'prefs-rc' => 'Håynaedje des dierins candjmints',
+'prefs-watchlist' => 'Djivêye des shuvous',
+'prefs-watchlist-days' => 'Nombe di djoûs a mostrer dins l\' djivêye:',
+'prefs-watchlist-edits' => 'Nombe di candjmints a mostrer dins l\' djivêye:',
+'prefs-misc' => 'Totes sôres',
+'saveprefs' => 'Schaper les preferinces',
+'resetprefs' => 'Rimete les prémetowès valixhances',
+'oldpassword' => 'Vî scret',
+'newpassword' => 'Noû scret',
+'retypenew' => 'Ritapez l\' noû scret',
+'textboxsize' => 'Grandeu del boesse di tecse',
+'rows' => 'Royes',
+'columns' => 'Colones',
+'searchresultshead' => 'Håynaedje des rzultats di cweraedje',
+'resultsperpage' => 'Nombe di responses a håyner so ene pådje',
+'contextlines' => 'Nombe di royes a håyner po ene response',
+'contextchars' => 'Nombe di caracteres di contecse pa roye',
+'stubthreshold' => 'Grandeu minimom po håyner les courts årtikes',
+'recentchangescount' => 'Nombe di tites dins les dierins candjmints',
+'savedprefs' => 'Vos preferinces ont stî schapêyes.',
+'timezonelegend' => 'Coisse d\' eureye',
+'timezonetext' => 'Tapez li nombe d\' eures di diferince avou l\' tins univiersel (UTC).',
+'localtime' => 'Håyner l\' eure locåle',
+'timezoneoffset' => 'Diferince d\' eures¹',
+'servertime' => 'L\' eure sol sierveu',
+'guesstimezone' => 'Prinde d\' après l\' betchteu',
+'allowemail' => 'Permete di rçure des emiles d\' ôtes uzeus',
+'defaultns' => 'Prémetous spåces di nos pol cweraedje:',
+'default' => 'prémetou',
+'files' => 'Fitchîs',
+
+# User rights
+'userrights-lookup-user' => 'Manaedjî les groupes d\' uzeus',
+'userrights-user-editname' => 'Tapez on no d\' uzeu:',
+'editusergroup' => 'Candjî les groupes d\' uzeus',
+
+'userrights-editusergroup' => 'Candjî groupes d\' uzeus',
+'saveusergroups' => 'Schaper des groupes d\' uzeus',
+'userrights-groupsmember' => 'Mimbes di:',
+'userrights-groupsavailable' => 'Groupes k\' i gn a:',
+'userrights-groupshelp' => 'Tchoezixhoz les groupes ki vos vloz ki l\' uzeu (èn) soeye (pus) mimbe.
+Les groupes nén tchoezis èn seront nén candjîs. Vos ploz distchoezi on groupe tot fjhant Ctrl + clitch di hintche',
+
+# Groups
+'group' => 'Groupe:',
+'group-bot' => 'Robots',
+'group-sysop' => 'Manaedjeus',
+'group-bureaucrat' => 'Mwaisse-manaedjeus',
+'group-all' => '(tertos)',
+
+'group-bot-member' => 'Robot',
+'group-sysop-member' => 'Manaedjeu',
+'group-bureaucrat-member' => 'Mwaisse-manaedjeu',
+
+'grouppage-bot' => '{{ns:project}}:Robots',
+'grouppage-sysop' => '{{ns:project}}:Manaedjeus',
+'grouppage-bureaucrat' => '{{ns:project}}:Mwaisse-manaedjeus',
+
+# Recent changes
+#
+'changes' => 'candjmints',
+'recentchanges' => 'Dierins candjmints',
+'recentchangestext' => 'Shuvoz chal les dierins candjmints k\' i gn a yeu dsu {{SITENAME}}.',
+'rcnote' => 'Chal pa dzo les <strong>$1</strong> dierins candjmints des dierins <strong>$2</strong> djoûs, å $3.',
+'rcnotefrom' => 'Chal pa dzo les candjmints dispoy li <b>$2</b> (disk\' a <b>$1</b> di mostrés).',
+'rclistfrom' => 'Mostrer les candjmints k\' i gn a yeu a pårti do $1',
+'rcshowhideminor' => '$1 candjmints mineurs',
+'rcshowhidebots' => '$1 robots',
+'rcshowhideliu' => '$1 uzeus eredjîstrés',
+'rcshowhideanons' => '$1 uzeus anonimes',
+'rcshowhidepatr' => '$1 candjmints rwaitîs',
+'rcshowhidemine' => '$1 candjmints da minne',
+'rclinks' => 'Mostrer les $1 dierins candjmints des dierins $2 djoûs.<br />$3',
+'diff' => 'dif.',
+'hist' => 'ist.',
+'hide' => 'catch.',
+'show' => 'håy.',
+#'minoreditletter' => 'm',
+#'newpageletter' => 'N',
+#'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[shuvou pa $1 uzeu(s)]',
+'rc_categories' => 'Limiter åzès categoreyes (separer avou des «|»)',
+'rc_categories_any' => 'Totes',
+
+# Upload
+#
+'upload' => 'Eberweter on fitchî',
+'uploadbtn' => 'Eberweter',
+# NOTE: 'En erî' purade ki 'Reberweter'; la ki c' est çou ki ç' boton la
+# fwait: rivni al pådje d' eberwetaedje
+'reupload' => 'En erî',
+'reuploaddesc' => 'Rivni al pådje d\' eberwetaedje.',
+'uploadnologin' => 'Nén elodjî',
+'uploadnologintext' => 'I vs fåt esse [[{{ns:special}}:Userlogin|elodjî]] por vos pleur eberweter des fitchîs.',
+'upload_directory_read_only' => 'Li sierveu waibe èn pout nén scrire sol ridant d\' eberwetaedje ($1).',
+'uploaderror' => 'Aroke d\' eberwetaedje',
+'uploadtext' => 'Eployîz les boesses d\' intrêye chal pa dzo po-z eberweter des noveas fitchîs d\' imådjes po vos årtikes. Sol plupårt des betchteus, vos voeroz on boton «Foyter...» (ou «Browse...») ki vs permetrè di foyter dins les ridants del deure plake da vosse po tchoezi l\' fitchî, çou ki rimplirè otomaticmint li tchamp do no do fitchî k\' est a costé.
+
+Po håyner ou cweri des imådjes k\' ont ddja stî rçuvowes, alez sol [[{{ns:special}}:Imagelist|djivêye des imådjes dedja eberwetêyes]]. Les eberwetaedjes et disfaçaedjes sont metous èn on [[{{ns:special}}:Log/upload|djournå des eberwetaedjes]].
+
+Po håyner l\' imådje dins èn årtike, eployîz on loyén del foûme
+* \'\'\'<nowiki>[[</nowiki>{{ns:image}}<nowiki>:fitchî.jpg]]</nowiki>\'\'\'
+* \'\'\'<nowiki>[[</nowiki>{{ns:image}}<nowiki>:fitchî.png|thumb|tecse a mete padzo]]</nowiki>\'\'\'
+ou co po les sons
+* \'\'\'<nowiki>[[</nowiki>{{ns:media}}<nowiki>:fitchî.ogg]]</nowiki>\'\'\'',
+
+'uploadlog' => 'djournå des eberwetaedjes',
+'uploadlogpage' => 'Djournå_des_eberwetaedjes',
+'uploadlogpagetext' => 'Chal pa dzo li djivêye des dierins eberwetaedjes.',
+'filename' => 'No do fitchî',
+'filedesc' => 'Discrijhaedje',
+'fileuploadsummary' => 'Discrijhaedje:',
+'filestatus' => 'Abondroets ey eployaedje',
+'filesource' => 'Sourdant',
+'copyrightpage' => '{{ns:project}}:Abondroets',
+'copyrightpagename' => 'Abondroets {{SITENAME}}',
+'uploadedfiles' => 'Fitchîs eberwetés',
+'ignorewarning' => 'Passer houte des adviertixhmints eyet schaper tot l\' minme li fitchî.',
+'ignorewarnings' => 'Passer houte des adviertixhmints',
+'minlength' => 'Les imådjes divèt aveur des nos di pol moens troes letes.',
+'illegalfilename' => 'Li no d\' fitchî «$1» a des caracteres ki n\' si polèt nén eployî dins l\' tite d\' ene pådje. Candjîz l\' no do fitchî eyet sayîz del reberweter s\' i vs plait.',
+'badfilename' => 'Li no d\' l\' imådje a stî candjî a «$1».',
+'badfiletype' => '«.$1» n\' est nén ene sôre d\' imådje ricmandêye.',
+'largefile' => 'C\' est mî k\' les imådjes åyexhe ene grandeu di moens di $1 octets, ci fitchî chal fwait $2 octets.',
+'largefileserver' => 'Ci fitchî ci est pus pezant ki çou k\' li sierveu est apontyî po-z accepter.',
+'emptyfile' => 'I shonnreut kel fitchî k\' vos eberwetez soeye vude. Çoula pout esse cåze d\' ene aroke di tapaedje dins l\' no do fitchî. Acertinez si vos vloz evoyî po do bon ç\' fitchî ci, s\' i vs plait.',
+'fileexists' => 'On fitchî avou ç\' no la egzistêye dedja, loukîz s\' i vs plait a $1 po vs acertiner ki vos vloz bén replaecî l\' fitchî avou l\' ci ki vos eberwetez asteure, oubén si vos l\' voloz eberweter dizo èn ôte no.',
+'fileexists-forbidden' => 'I gn a ddja on fitchî avou ç\' no la; rivnoz s\' i vs plait en erî et s\' reberwetez l\' fitchî dizo èn ôte no. [[{{ns:image}}:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => 'I gn a ddja on fitchî avou ç\' no la e ridant des fitchîs pårtaedjîs; rivnoz s\' i vs plait en erî et s\' reberwetez l\' fitchî dizo èn ôte no. [[{{ns:image}}:$1|thumb|center|$1]]',
+'successfulupload' => 'L\' eberwetaedje a stî comifåt',
+'fileuploaded' => 'L\' eberwetaedje do fitchî «$1» a stî å paire des pôces.
+Shuvoz ci loyén chal: ($2) pol pådje di discrijhaedje eyet rimplixhoz les
+informåcions sol fitchî, come di wice k\' i vént, cwand il a stî
+fwait, et pa kî, et tot l\' minme kéne informåcion interessante ki vos ploz
+saveur åd fwait do fitchî.',
+'uploadwarning' => 'Adviertixhmint so l\' eberwetaedje',
+'savefile' => 'Schaper l\' fitchî',
+'uploadedimage' => 'eberwetaedje di «[[$1]]»',
+'uploaddisabled' => 'Eberwetaedje di fitchîs dismetou',
+'uploaddisabledtext' => 'Mande escuzes, mins l\' eberwetaedje di fitchîs a stî dismetou pol moumint.',
+'uploadscripted' => 'Ci fitchî ci a-st å dvins do côde HTML ou on scripe ki pôreut esse må comprin pa on betchteu waibe.',
+'uploadcorrupt' => 'Li fitchî est cron oudonbén il a-st ene mwaijhe cawete. Verifyîz l\' fitchî eyet l\' reberweter s\' i vs plait.',
+'uploadvirus' => 'Li fitchî a-st on virusse! Detays: $1',
+'sourcefilename' => 'No d\' fitchî so vosse copiutrece',
+'destfilename' => 'No d\' fitchî a eployî so {{SITENAME}}',
+
+'filewasdeleted' => 'On fitchî avou ç\' no la a ddja stî disfacé. Vos dvrîz loukî å $1 divant d\' continouwer.',
+
+'license' => 'Licince di l\' imådje',
+'nolicense' => 'Nole licince tchoezeye',
+#'licenses' => '-', # Don't duplicate this in translations
+
+# Image list
+#
+'imagelist' => 'Djivêye des imådjes',
+'imagelisttext' => 'Chal pa dzo c\' est ene djivêye di <strong>$1</strong> imådjes relîtes <strong>$2</strong>.',
+'imagelistforuser' => 'Çouci n\' mostere ki les imådjes eberwetêyes pa $1.',
+'getimagelist' => 'dji fwait l\' djivêye des imådjes',
+'ilsubmit' => 'Cweri',
+'showlast' => 'Mostrer les $1 dierinnès imådjes relîtes $2.',
+'byname' => 'påzès nos',
+'bydate' => 'pazès dates',
+'bysize' => 'pa grandeu',
+'imgdelete' => 'oist.',
+'imgdesc' => 'disc.',
+'imglegend' => 'Ledjinde: (disc.) = håyner/candjî l\' discrijhaedje di l\' imådje.',
+'imghistory' => 'Istwere di l\' imådje',
+'revertimg' => 'mod.',
+'deleteimg' => 'oist.',
+'deleteimgcompletely' => 'Disfacer totes les modêyes di ç\' fitchî ci.',
+'imghistlegend' => 'Ledjinde: (ast.) = c\' est l\' imådje k\' i gn a asteure, (oist.) = oister (disfacer)
+cisse viye modêye la, (mod.) = rivni a cisse viye modêye la.
+<br /><i>Clitchîz sol date po vey l\' imådje evoyeye a cisse date la.</i>',
+'imagelinks' => 'Loyéns viè ciste imådje chal',
+'linkstoimage' => 'Les pådjes shuvantes eployèt ciste imådje chal:',
+'nolinkstoimage' => 'I n\' a nole pådje k\' eploye ciste imådje chal.',
+'sharedupload' => 'Ci fitchî ci est so on ridant pårtaedjî ey i s\' pout k\' i soeye eployî pa ds ôtes pordjets.',
+'shareduploadwiki' => 'Loukîz li $1 po pus di racsegnes.',
+'shareduploadwiki-linktext' => 'pådje di discrijhaedje',
+'noimage' => 'I n\' a nou fitchî avou ç\' no la, vos l\' poloz $1',
+'noimage-linktext' => 'eberweter',
+'uploadnewversion-linktext' => 'Eberweter ene nouve modêye di ci fitchî ci',
+
+# Mime search
+#
+'mimesearch' => 'Cweraedje MIME',
+'mimetype' => 'sôre MIME:',
+'download' => 'aberweter',
+
+# Unwatchedpages
+#
+'unwatchedpages' => 'Pådjes nén shuvowes',
+
+# List redirects
+'listredirects' => 'Djivêye des redjiblaedjes',
+
+# Unused templates
+'unusedtemplates' => 'Modeles nén eployîs',
+'unusedtemplatestext' => 'Cisse pådje ci mostere totes les pådjes di modele (espåce di lomaedje «{{ns:template}}») ki n\' sont nén eployîs dins ene ôte pådje. Rimimbrez vs di verifyî s\' i n\' a nén des ôtes loyéns divant delzès disfacer.',
+'unusedtemplateswlh' => 'ôtes loyéns',
+
+# Random redirect
+'randomredirect' => 'Redjiblaedje a l\' astcheyance',
+
+# Statistics
+#
+'statistics' => 'Sitatistikes',
+'sitestats' => 'Sitatistikes di {{SITENAME}}',
+'userstats' => 'Sitatistikes des uzeus',
+'sitestatstext' => 'I gn a \'\'\'$1\'\'\' pådjes å totå el båze di dnêyes.
+Çoula tot contant les pådjes di «Copenes», les pådjes åd fwait di {{SITENAME}}, les pådjes «djermons» (pådjes sins waire di contnou), les redjiblaedjes, eyet co ds ôtes ki n\' sont nén vormint des årtikes.
+Si on n\' conte nén ces la, i gn a \'\'\'$2\'\'\' pådjes ki sont
+probåblumint des vraiys årtikes.
+
+\'\'\'$8\'\'\' fitchîz ont stî eberwetés.
+
+I gn a-st avou å totå \'\'\'$3\'\'\' riwaitaedjes di pådjes, eyet \'\'\'$4\'\'\' candjmints do contnou des pådjes dispoy ki ci wiki chal est en alaedje.
+Dj\' ô bén k\' i gn a ene moyene di \'\'\'$5\'\'\' candjmints par pådje, eyet \'\'\'$6\'\'\' riwaitaedjes po on candjmint.
+
+Li longueur del [http://meta.wikimedia.org/wiki/Help:Job_queue cawêye des bouyes] est di \'\'\'$7\'\'\'.',
+'userstatstext' => 'I gn a \'\'\'$1\'\'\' uzeus d\' eredjîstrés.
+\'\'\'$2\'\'\' (ou \'\'\'$4%\'\'\') di zels sont eto des manaedjeus (riloukîz a $3).',
+
+'disambiguations' => 'Pådjes d\' omonimeye',
+'disambiguationspage' => '{{ns:template}}:Omonimeye',
+'disambiguationstext' => 'Les årtikes shuvants ont des loyéns viè ene <i>pådje d\' omonimeye</i>. I dvrént purade loyî viè l\' boun årtike.<br />
+Ene pådje est considerêye come pådje d\' omonimeye si elle aparexhe e $1.<br />
+Les loyéns a pårti d\' ôtes espåces di lomaedje èn sont <i>nén</i> håynés chal.',
+
+'doubleredirects' => 'Dobes redjiblaedjes',
+'doubleredirectstext' => 'Tchaeke roye a-st on loyén viè l\' prumî eyet l\' deujhinme redjiblaedje, avou on mostraedje del prumire roye do tecse do deujhinme redjiblaedje, çou ki å pus sovint dene li «vraiy» årtike såme, ki l\' prumî redjiblaedje divreut evoyî viè lu.',
+
+'brokenredirects' => 'Pierdous redjiblaedjes',
+'brokenredirectstext' => 'Les redjiblaedjes shuvants evoyèt so ene pådje ki n\' egzistêye nén.',
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|octet|octets}}',
+'ncategories' => '$1 {{PLURAL:$1|categoreye|categoreyes}}',
+'nlinks' => '$1 {{PLURAL:$1|loyén|loyéns}}',
+'nmembers' => '$1 {{PLURAL:$1|mimbe|mimbes}}',
+'nrevisions' => '$1 {{PLURAL:$1|modêye|modêyes}}',
+'nviews' => 'léjhowe $1 {{PLURAL:$1|côp|côps}}',
+
+'lonelypages' => 'Pådjes ôrfulinnes',
+'uncategorizedpages' => 'Pådjes sins nole categoreye',
+'uncategorizedcategories' => 'Categoreyes nén categorijheyes',
+'unusedcategories' => 'Categoreyes nén eployeyes',
+'unusedimages' => 'Imådjes nén eployeyes',
+'popularpages' => 'Pådjes les pus léjhowes',
+'wantedcategories' => 'Categoreyes les pus rcwerowes',
+'wantedpages' => 'Pådjes les pus rcwerowes',
+'mostlinked' => 'Pådjes les pus loyeyes',
+'mostlinkedcategories' => 'Categoreyes les pus loyeyes',
+'mostcategories' => 'Årtikes avou l\' pus di categoreyes',
+'mostimages' => 'Imådjes les pus loyeyes',
+'mostrevisions' => 'Årtikes avou l\' pus di candjmints',
+'allpages' => 'Totes les pådjes',
+'prefixindex' => 'Indecse pa betchete',
+'randompage' => 'Årtike a l\' astcheyance',
+'shortpages' => 'Coûtès pådjes',
+'longpages' => 'Longowès pådjes',
+'deadendpages' => 'Pådjes sins nou loyén wiki',
+'listusers' => 'Djivêye des uzeus',
+'specialpages' => 'Pådjes sipeciåles',
+'spheading' => 'Pådjes sipeciåles po tos ls uzeus',
+'restrictedpheading' => 'Pådjes sipeciåles po les manaedjeus',
+'recentchangeslinked' => 'Candjmints aloyîs',
+'rclsub' => '(ezès pådjes ki «$1» a-st on loyén dzeu)',
+'newpages' => 'Novelès pådjes',
+'ancientpages' => 'Viyès pådjes',
+'intl' => 'Loyéns eterlingaedjes',
+'move' => 'Displaecî',
+'movethispage' => 'Displaecî cisse pådje',
+'unusedimagestext' => '<p>Notez tot l\' minme ki d\' ôtès waibes polèt aveur des loyéns viè ces imådjes la gråcès a ene direke hårdêye. Do côp, ces imådjes aparexhèt chal, mågré k\' ele soeyexhe eployeyes.</p>',
+'unusedcategoriestext' => 'Les pådjes di categoreye shuvantes egzistént, mins i n\' a nol årtike ni categoreye å dvins.',
+
+'booksources' => 'Sourdants po les lives',
+'categoriespagetext' => 'I gn a les categoreyes shuvantes sol wiki.',
+'data' => 'Dinêyes',
+'userrights' => 'Manaedjî les liveas des uzeus',
+'groups' => 'Groupes d\' uzeus',
+
+'booksourcetext' => 'Chal pa dzo c\' est ene djivêye di hårdêyes viè des waibes ki vindèt des lives, noûs ou di deujhinme mwin, et ki polèt aveur pus d\' informåcions åd fwait des lives ki vos cweroz après.',
+'isbn' => 'ISBN',
+'alphaindexline' => 'di $1 a $2',
+'version' => 'Modêye des programes',
+'log' => 'Djournås',
+'alllogstext' => 'Håynaedje etercroejhlé des djournås d\' eberwetaedje, disfaçaedje, protedjaedje, blocaedje eyet manaedjeus.
+Vos ploz limiter l\' håynaedje tot tchoezixhant ene sôre di djournå, on no d\' uzeu, ou l\' tite d\' ene pådje.',
+'logempty' => 'Rén n\' corespond dins l\' djournå.',
+
+# Special:Allpages
+'nextpage' => 'Pådje shuvante ($1)',
+'allpagesfrom' => 'Håyner les pådjes a pårti di:',
+'allarticles' => 'Tos les årtikes',
+'allinnamespace' => 'Totes les pådjes (espåce di lomaedje $1)',
+'allnotinnamespace' => 'Totes les pådjes (foû d\' l\' espåce di lomaedje $1)',
+'allpagesprev' => 'Di dvant',
+'allpagesnext' => 'Shuvant',
+'allpagessubmit' => 'I va',
+'allpagesprefix' => 'Håyner les pådjes avou l\' betchete:',
+
+# E this user
+#
+'mailnologin' => 'Nole adresse d\' evoyeu',
+'mailnologintext' => 'Po-z evoyî èn emile a èn ôte uzeu i vs fåt esse [[{{ns:special}}:Userlogin|elodjî]] eyet aveur ene adresse emile d\' evoyeu ki soeye valide dins vos [[{{ns:special}}:Preferences|preferinces]].',
+'emailuser' => 'Emiler a l\' uzeu',
+'emailpage' => 'Emilaedje a èn uzeu',
+'emailpagetext' => 'Si cist uzeu chal a dné ene adresse emile valide dins
+ses preferinces, vos lyi ploz evoyî èn emile a pårti di cisse pådje chal.
+L\' adresse emile k\' i gn a dins vos preferinces serè-st eployeye
+come adresse di l\' evoyeu (adresse «From:» di l\' emile),
+po ki l\' riçuveu poye risponde.',
+'usermailererror' => 'Åk n\' a nén stî tot voyant l\' emile:',
+'defemailsubject' => 'Emile da {{SITENAME}}',
+'noemailtitle' => 'Pont d\' adresse emile',
+'noemailtext' => 'Cist uzeu chal n\' a nén dné d\' adresse emile
+valide, ou n\' vout nén rçure des emiles des ôtes uzeus.
+Do côp, c\' est nén possibe di lyi evoyî èn emile.',
+'emailfrom' => 'Di',
+'emailto' => 'Po',
+'emailsubject' => 'Sudjet',
+'emailmessage' => 'Messaedje',
+'emailsend' => 'Evoyî',
+'emailsent' => 'Emile evoyî',
+'emailsenttext' => 'Vost emilaedje a stî evoyî comifåt.',
+
+# Watchlist
+#
+'watchlist' => 'Pådjes shuvowes',
+'nowatchlist' => 'Vosse djivêye des pådjes a shuve est vude.',
+'watchlistcount' => '\'\'\'Vos avoz $1 cayets dins vosse djivêye des shuvous, tot contant les pådjes di copene.\'\'\'',
+'clearwatchlist' => 'Netyî l\' djivêye des shuvous',
+'watchlistcleartext' => 'Estoz seur delzès voleur oister?',
+'watchlistclearbutton' => 'Netyî l\' djivêye',
+'watchlistcleardone' => 'Vosse djivêye des shuvous a stî netieye. {{PLURAL:$1|$1 cayet a stî bodjî|$1 cayets ont stî bodjîs}} foû.',
+'watchnologin' => 'Vos n\' estoz nén elodjî',
+'watchnologintext' => 'I vs fåt esse [[{{ns:special}}:Userlogin|elodjî]] po pleur candjî vosse djivêye des pådjes a shuve.',
+'addedwatch' => 'Radjouté ås shuvous',
+'addedwatchtext' => 'Li pådje «$1» a stî radjoutêye a vosse [[{{ns:special}}:Watchlist|djivêye des pådjes a shuve]].
+Tos les candjmints k\' i gn årè di cisse pådje chal,
+eyet di si pådje di copene, seront håynés chal, eyet li pådje serè metowe e \'\'\'cråssès letes\'\'\'
+el [[{{ns:special}}:Recentchanges|djivêye des dierins candjmints]] po k\' ça soeye pus åjhey por vos del rimårker.
+
+Si vos vloz bodjî l\' pådje foû di vosse djivêye des shuvous, clitchîz so «Èn pus shuve li pådje» dins l\' bår di menu sol costé.',
+'removedwatch' => 'Bodjî foû des shuvous',
+'removedwatchtext' => 'Li pådje «$1» a stî bodjeye foû di vosse djivêye des pådjes a shuve.',
+'watch' => 'Shuve',
+'watchthispage' => 'Shuve cisse pådje',
+'unwatch' => 'Èn pus shuve',
+'unwatchthispage' => 'Èn pus shuve li pådje',
+'notanarticle' => 'Nén èn årtike',
+'watchnochange' => 'Nole des pådjes di vosse djivêye di pådjes a shuve n\' a stî candjeye dins l\' termene di tins dmandêye.',
+# NOTE: Messages.php n' eploye nén PLURAL
+'watchdetails' => '* {{PLURAL:$1|$1 pådje shuvowe|$1 pådjes shuvowes}} (sins conter les pådjes di copene)
+* [[{{ns:special}}:Watchlist/edit|Håyner eyet candjî l\' djivêye etire]]
+* [[{{ns:special}}:Watchlist/clear|Bodjî totes les pådjes foû del djivêye]]',
+'wlheader-enotif' => '* Li notifiaedje pa emile est en alaedje.',
+'wlheader-showupdated' => '* Les pådjes k\' ont candjî dispoy vosse dierinne vizite sont metowes e \'\'\'cråssès letes\'\'\'',
+'watchmethod-recent' => 'Cwerant après les pådjes k\' ont stî candjeyes dierinnmint ki sont eto des pådjes shuvowes',
+'watchmethod-list' => 'Cwerant après les pådjes shuvowes k\' ont stî candjeyes dierinnmint',
+'removechecked' => 'Bodjî les cayets tchoezis foû del djivêye des pådjes a shuve',
+# NOTE: Messages.php n' eploye nén PLURAL
+'watchlistcontains' => 'I gn a {{PLURAL:$1|$1 pådje|$1 pådjes}} e vosse djivêye des pådjes a shuve.',
+'watcheditlist' => 'Vochal ene djivêye alfabetike di vos pådjes shuvowes.
+Clitchîz so les boesses po les pådjes ki vos vloz bodjî di vosse djivêye di pådjes a shuve, poy clitchîz sol boton do dzo po lzès bodjî evoye (bodjî evoye ene pådje di contnou oistêye si pådje di copene avou et årvierdimint).',
+'removingchecked' => 'Bodjant les cayets dmandés foû del djivêye...',
+'couldntremove' => 'Dji n\' sai bodjî l\' cayet «$1» foû del djivêye...',
+'iteminvalidname' => 'Åk n\' a nén stî avou «$1», li no n\' est nén valide...',
+'wlnote' => 'Chal pa dzo les $1 dierins candjmints des <b>$2</b> dierinnès eures.',
+'wlshowlast' => 'Mostrer les dierin(nè)s $1 eures, $2 djoûs $3',
+'wlsaved' => 'Çouchal, c\' est ene modêye k\' a stî schapêye di vosse djivêye di pådjes shuvowes.',
+'wlhideshowown' => '$1 les candjmints da minne.',
+'wlhideshowbots' => '$1 les candjmints des robots.',
+'wldone' => 'Fwait.',
+
+'enotif_mailer' => 'Notifiaedje pa emile di {{SITENAME}}',
+'enotif_reset' => 'Mårker totes les pådjes come vizitêyes',
+'enotif_newpagetext' => 'C\' est ene nouve pådje.',
+'changed' => 'candjeye',
+'created' => 'ahivêye',
+'enotif_subject' => 'Li pådje «$PAGETITLE» so {{SITENAME}} a stî $CHANGEDORCREATED pa $PAGEEDITOR',
+'enotif_lastvisited' => 'Loukîz $1 po tos les candjmints dispoy vosse dierinne vizite.',
+'enotif_body' => 'Binamé $WATCHINGUSERNAME,
+
+Li pådje «$PAGETITLE» so {{SITENAME}} a stî $CHANGEDORCREATED li $PAGEEDITDATE pa $PAGEEDITOR, loukîz $PAGETITLE_URL pol modêye do moumint.
+
+$NEWPAGE
+
+Comintaire do candjeu: $PAGESUMMARY $PAGEMINOREDIT
+
+Contak do candjeu:
+emile: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+I n\' årè nén d\' ôtes notifiaedjes po ds ôtes candjmints di ç\' minme pådje ci tant k\' vos n\' l\' åroz nén vizitêye. Vos ploz eto rimete a noû les drapeas di notifiaedje po totes les pådjes di vosse djivêye des pådjes a shuve.
+
+
+ Vosse binamé sistinme di notifiaedje so {{SITENAME}}
+
+--
+Po candjî l\' apontiaedje di vosse djivêye a shuve, loukîz
+{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+Po pus d\' aidance:
+{{fullurl:{{ns:help}}:Aidance}}',
+
+# Delete/protect/revert
+#
+'deletepage' => 'Disfacer l\' pådje',
+'confirm' => 'Acertiner',
+'excontent' => 'li contnou esteut: «$1»',
+'excontentauthor' => 'li contnou esteut: «$1» (eyet l\' seu contribouweu esteut «$2»)',
+'exbeforeblank' => 'li contnou dvant l\' disfaçaedje esteut: «$1»',
+'exblank' => 'li pådje esteut vude',
+'confirmdelete' => 'Acertinaedje do disfaçaedje',
+'deletesub' => '(Disfaçaedje di «$1»)',
+'historywarning' => 'Asteme: Li pådje ki vos alez disfacer a-st ene istwere:',
+'confirmdeletetext' => 'Vos alez disfacer po tofer del båze di dnêyes ene
+pådje ou ene imådje, avou tote si istwere.
+Acertinez s\' i vs plait ki c\' est bén çoula ki vos vloz fé,
+ki vos comprindoz les consecwinces, et ki vos fjhoz çoula
+tot [[{{ns:project}}:Rîles a shure|shuvant les rîles]].',
+'actioncomplete' => 'Fwait',
+'deletedtext' => 'Li pådje «$1» a stî disfacêye. Loukîz li $2 po ene
+djivêye des dierins disfaçaedjes.',
+'deletedarticle' => 'pådje «$1» disfacêye',
+'dellogpage' => 'Djournå_des_disfaçaedjes',
+'dellogpagetext' => 'Chal pa dzo c\' est l\' djivêye des dierins disfaçaedjes.',
+'deletionlog' => 'djournå des disfaçaedjes',
+'reverted' => 'Rimetou ene modêye di dvant',
+'deletecomment' => 'Råjhon do disfaçaedje',
+'imagereverted' => 'Li rmetaedje del modêye di dvant a stî comifåt.',
+'cantrollback' => 'Dji n\' sai disfé les candjmints; li dierin contribouweu est li seu oteur po cist årtike ci.',
+'alreadyrolled' => 'Dji n\' sai disfé li dierin candjmint di [[:$1]]
+fwait pa [[{{ns:user}}:$2|$2]] ([[{{ns:user_talk}}:$2|Copene]]);
+ene sakî d\' ôte a ddja candjî l\' årtike ou ddja rmetou l\' modêye di dvant.
+
+Li dierin candjmint a stî fwait pa [[{{ns:user}}:$3|$3]] ([[{{ns:user_talk}}:$3|Copene]]).',
+# only shown if there is an edit comment
+'editcomment' => 'Li comintaire do candjmint esteut: «<i>$1</i>».',
+'revertpage' => 'Disfwait li candjmint da [[{{ns:special}}:Contributions/$2|$2]] ([[{{ns:user_talk}}:$2|copene]]); li dierin candjmint est asteure da [[{{ns:user}}:$1|$1]]',
+'protectlogpage' => 'Djournå_des_protedjaedjes',
+'protectlogtext' => 'Chal pa dzo c\' est ene djivêye des protedjaedjes et disprotedjaedjes des pådjes.
+Loukîz [[{{ns:project}}:Pådje protedjeye]] po pus di racsegnes.',
+'protectedarticle' => '«[[$1]]» protedjî',
+'unprotectedarticle' => '«[[$1]]» disprotedjî',
+'protectsub' => '(Protedjant «$1»)',
+'confirmprotecttext' => 'Voloz vs vormint protedjî cisse pådje ci?',
+'confirmprotect' => 'Acertinez l\' protedjaedje',
+'protectmoveonly' => 'Protedjî seulmint conte les displaeçaedjes',
+'protectcomment' => 'Råjhon po protedjî',
+'unprotectsub' => '(Disprotedjant «$1»)',
+'confirmunprotecttext' => 'Voloz vs vormint disprotedjî cisse pådje ci?',
+'confirmunprotect' => 'Acertinez l\' disprotedjaedje',
+'unprotectcomment' => 'Råjhon po disprotedjî',
+'protect-unchain' => 'Disbloker les permissions di displaeçaedje',
+'protect-text' => 'Vos ploz droci vey eyet candjî l\' livea d\' protedjaedje pol pådje <strong>$1</strong>.
+S\' i vs plait acertinez vs di bén shure les [[{{ns:project}}:Pådje_protedjeye|rîles po les pådjes protedjeyes]].',
+'protect-viewtext' => 'Vosse conte d\' uzeu n\' a nén les permissions k\' i fåt po candjî les liveas d\' protedjaedje. Voci les cis metous pol moumint pol pådje <strong>$1</strong>:',
+'protect-default' => '(prémetou)',
+'protect-level-autoconfirmed' => 'Bloker les uzeus nén eredjîstrés',
+'protect-level-sysop' => 'Seulmint les manaedjeus',
+
+# restrictions (nouns)
+'restriction-edit' => 'Candjî',
+'restriction-move' => 'Displaecî',
+
+# Undelete
+'undelete' => 'Rapexhî des disfacêyès pådjes',
+'undeletepage' => 'Vey et rapexhî des disfacêyès pådjes',
+'viewdeletedpage' => 'Vey les disfacêyès pådjes',
+'undeletepagetext' => 'Les pådjes shuvantes ont stî disfacêyes mins ele sont co ezès årtchives, do côp ele polèt esse rapexheyes.',
+'undeleteextrahelp' => 'Po rapexhî l\' pådje etire, leyîz vudes totes les boesses a clitchî eyet clitchîz sol boton «\'\'\'Rapexhî\'\'\'». Po rapexhî seulmint des modêyes k\' i gn a, tchoezixhoz les cenes ki vos vloz avou les boesses a clitchî, eyet poy clitchîz sol boton «\'\'\'Rapexhî\'\'\'». Si vos clitchîz sol boton «\'\'\'Netyî\'\'\'», çoula neteyrè l\' tchamp d\' comintaire eyet totes les boesses a clitchî.',
+'undeletearticle' => 'Rapexhî on disfacé årtike',
+'undeleterevisions' => '$1 modêyes ezès årtchives',
+'undeletehistory' => 'Si vos rapexhîz l\' pådje, l\' istwere del pådje
+serè rapexheye eto, avou totes les modêyes co ezès årtchives.
+Si ene novele pådje avou l\' minme no a stî askepieye dispoy li disfaçaedje
+di cisse chal, les rapexheyès modêyes seront metowes e l\' istwere mins
+c\' est l\' modêye do moumint, et nén l\' cisse rapexheye, ki
+srè håynêye.',
+'undeletehistorynoadmin' => 'Cist årtike a stî disfacé. Li råjhon do
+disfaçaedje est dnêye chal pa dzo, avou les detays des uzeus k\' ont
+candjî l\' pådje divant do disfaçaedje. Li tecse di ces modêyes disfacêyes
+ni pout esse veyou ki des manaedjeus.',
+'undeleterevision' => 'Modêye disfacêye li $1',
+'undeletebtn' => 'Rapexhî!',
+'undeletereset' => 'Netyî',
+'undeletecomment' => 'Comintaire:',
+'undeletedarticle' => 'a rapexhî l\' pådje «[[$1]]»',
+# NOTE: Messages.php n' eploye nén PLURAL
+'undeletedrevisions' => '{{PLURAL:$1|ene modêye di rapexheye|$1 modêyes di rapexheyes}}',
+'undeletedpage' => '<big>\'\'\'Li pådje $1 a stî rapexheye.\'\'\'
+
+Loukîz l\' [[{{ns:special}}:Log/delete|djournå des disfaçaedjes]] po ene djivêye des dierins disfaçaedjes eyet rapexhaedjes.',
+
+# Namespace form on various pages
+'namespace' => 'Espåce di lomaedje:',
+'invert' => 'Tchuze å rvier',
+
+# Contributions
+#
+'contributions' => 'Ovraedjes di l\' uzeu',
+'mycontris' => 'Mi ovraedje',
+'contribsub' => 'Po l\' uzeu $1',
+'nocontribs' => 'Nou candjmint di trové ki corespondreut a ç\' critere la.',
+'ucnote' => 'Chal pa dzo les <b>$1</b> dierins candjmints di l\' uzeu so les <b>$2</b> dierins djoûs.',
+'uclinks' => 'Vey les $1 dierins candjmints; vey les $2 dierins djoûs.',
+
+'sp-contributions-newest' => 'Dierins ovraedjes',
+'sp-contributions-oldest' => 'Prumîs ovraedjes',
+'sp-contributions-newer' => '$1 di dvant',
+'sp-contributions-older' => '$1 shuvants',
+
+
+# What links here
+#
+'whatlinkshere' => 'Pådjes ki loynut chal',
+'linklistsub' => '(Djivêye des loyéns)',
+'linkshere' => 'Les pådjes ki shuvèt ont des loyéns viè cisse ci:',
+'nolinkshere' => 'Nole pådje avou des loyéns viè cisse ci.',
+'isredirect' => 'pådje di redjiblaedje',
+
+# Block/unblock IP
+#
+'blockip' => 'Bloker èn uzeu',
+'blockiptext' => 'Rimplixhoz les tchamps chal pa dzo po bloker
+l\' accès e scrijhaedje d\' èn uzeu dné ou a pårt d\' ene
+adresse IP dnêye. Çouci èn doet esse fwait ki po-z arester les
+vandales, et çoula doet esse fwait tot shuvant les
+[[{{ns:project}}:Rîles a shure|rîles di {{SITENAME}}]].
+Dinez ene råjhon do blocaedje (eg: dijhoz les pådjes k\' ont
+stî vandalijheyes).',
+'ipaddress' => 'Adresse IP/no d\' uzeu',
+'ipadressorusername' => 'Adresse IP ou no d\' uzeu',
+'ipbexpiry' => 'Tins do blocaedje',
+'ipbreason' => 'Råjhon',
+'ipbsubmit' => 'Bloker cist uzeu',
+'ipbother' => 'Ôte termene',
+'ipboptions' => '2 eures:2 hours,1 djoû:1 day,3 djoûs:3 days,1 samwinne:1 week,2 samwinnes:2 weeks,1 moes:1 month,3 moes:3 months,6 moes:6 months,1 anêye:1 year,po todi:infinite',
+'ipbotheroption' => 'ôte',
+'badipaddress' => 'Nol uzeu avou ç\' no la, ou adresse IP nén valide',
+'blockipsuccesssub' => 'Li blocaedje a stî comifåt',
+'blockipsuccesstext' => '«[[{{ns:special}}:Contributions/$1|$1]]» a stî bloké.<br />Loukîz li [[{{ns:special}}:Ipblocklist|djivêye des blocaedjes]] po candjî on blocaedje.',
+'unblockip' => 'Disbloker èn uzeu',
+'unblockiptext' => 'Rimplixhoz les tchamps chal pa dzo po ridner accès e scrijhaedje a èn uzeu ou adresse IP k\' estént blokés.',
+'ipusubmit' => 'Disbloker ciste adresse ci',
+'ipblocklist' => 'Djivêye d\' adresses IP et di nos d\' uzeus ki sont blokés',
+'blocklistline' => '$1, $2 a bloké $3 ($4)',
+'infiniteblock' => 'po todi',
+'expiringblock' => 'disk\' å $1',
+'ipblocklistempty' => 'Li djivêye des blocaedjes est vude.',
+'blocklink' => 'bloker',
+'unblocklink' => 'disbloker',
+'contribslink' => 'contribouwaedjes',
+'autoblocker' => 'Bloké otomaticmint paski vos eployîz li minme adresse IP ki «[[{{ns:user}}:$1|$1]]». Råjhon do blocaedje «\'\'\'$2\'\'\'».',
+'blocklogpage' => 'Djournå_des_blocaedjes',
+'blocklogentry' => '«[[$1]]» a stî bloké po ene termene di $2',
+'blocklogtext' => 'Çouchal, c\' est on djournå des blocaedjes eyet disblocaedjes d\' uzeus. Les adresses IP blokêyes otomaticmint èn sont nén håynêyes. Loukîz li [[{{ns:special}}:Ipblocklist|djivêye des adresses IP blokêyes]] po vey les blocaedjes d\' adresses IP do moumint.',
+'unblocklogentry' => '«$1» a stî disbloké',
+'range_block_disabled' => 'Li possibilité po les manaedjeus di bloker des fortchetes d\' adresses IP a stî dismetowe.',
+'ipb_expiry_invalid' => 'Tins di blocaedje nén valide.',
+'ip_range_invalid' => 'Fortchete d\' adresses IP nén valide.',
+'proxyblocker' => 'Blocaedje di procsi',
+'proxyblockreason' => 'Voste adresse IP a stî blokêye paski c\' est on procsi k\' est å lådje. Contactez vost ahesseu Internet ou l\' siervice di sopoirt tecnike eyet lzî dire po çoula, la k\' c\' est on problinme di såvrité serieus.',
+'proxyblocksuccess' => 'Fwait.',
+#'sorbs' => 'SORBS DNSBL',
+'sorbsreason' => 'Voste adresse IP si trove dins l\' djivêye des procsis å lådje di [http://www.sorbs.net SORBS DNSBL].',
+'sorbs_create_account_reason' => 'Voste adresse IP si trove dins l\' djivêye des procsis å lådje di [http://www.sorbs.net SORBS DNSBL]. Vos n\' poloz nén ahiver on conte d\' uzeu.',
+
+# Developer tools
+#
+
+# Make sysop
+'makesysoptitle' => 'Diner a èn uzeu on livea di manaedjeu',
+'makesysoptext' => 'Cisse pådje ci c\' est po les mwaisses-manaedjeus («burocrates») poleur hôssî l\' livea d\' èn uzeu do livea d\' simpe uzeu eredjîstré, å ci d\' manaedjeu.
+Tapez l\' no d\' l\' uzeu dins l\' boesse di tecse poy clitchîz sol boton po ndè fé on manaedjeu.',
+'makesysopname' => 'Li no d\' l\' uzeu:',
+'makesysopsubmit' => 'Endè fé on manaedjeu',
+'makesysopok' => '<b>Asteure l\' uzeu «$1» a l\' livea d\' manaedjeu</b>',
+'makesysopfail' => '<b>L\' uzeu «$1» èn pout nén esse fwait on manaedjeu. (Avoz vs tapé l\' no bén comifåt?)</b>',
+'setbureaucratflag' => 'Mete li drapea mwaisse-manaedjeu',
+'rightslog' => 'Djournå des droets des uzeus',
+'rightslogtext' => 'Çouchal, c\' est on djournå des candjmints des droets des uzeus.',
+'rightslogentry' => 'l\' uzeu «$1» a stî candjî do groupe «$2» viè «$3»',
+'rights' => 'Droets:',
+'set_user_rights' => 'Defini les droets d\' l\' uzeu',
+'user_rights_set' => '<b>Les droets po l\' uzeu «$1» ont stî metous a djoû</b>',
+'set_rights_fail' => '<b>Les droets po l\' uzeu «$1» n\' ont nén polou esse definis. (Avoz vs tapé l\' no bén comifåt?)</b>',
+'makesysop' => 'Diner a èn uzeu on livea di manaedjeu',
+'already_sysop' => 'Cist uzeu ci a ddja l\' livea di manaedjeu',
+'already_bureaucrat' => 'Cist uzeu ci a ddja l\' livea di mwaisse-manaedjeu',
+'rightsnone' => '(nouk)',
+
+# Move page
+#
+'movepage' => 'Displaecî l\' pådje',
+'movepagetext' => 'Chal vos ploz candjî l\' no d\' ene pådje,
+dj\' ô bén displaecî l\' pådje, eyet si istwere, viè l\' novea no.
+Li vî tite divénrè-st ene pådje di redjiblaedje viè l\' novele.
+Les loyéns viè l\' viye pådje èn seront nén candjîs; acertinez vs di
+[[{{ns:special}}:DoubleRedirects|verifyî]] s\' i n\' a nén des dobes
+ou crons redjiblaedjes.
+Vos estoz responsåve di fé çou k\' i fåt po k\' les loyéns
+continouwexhe di moenner la k\' i fåt.
+
+Notez k\' el pådje èn serè \'\'\'nén\'\'\' displaeceye s\' i gn a ddja ene
+pådje avou l\' novea tite, a moens k\' ele soeye vude, ou ene pådje
+di redjiblaedje, et k\' ele n\' åye nole istwere.
+Çoula vout dire ki vos ploz ri-displaecî ene pådje viè l\' no k\' ele
+aveut djusse divant, et insi disfé vosse prumî displaeçaedje, å cas ou vos vs
+rindrîz conte ki vos avoz fwait ene flotche; ey eto ki vos n\' poloz nén
+spotchî par accidint ene pådje k\' egzistêye dedja.
+
+<b>ASTEME!</b>
+On displaeçaedje pout esse on consecant et nén atindou candjmint po ene
+pådje foirt léjhowe; s\' i vs plait tuzez bén åzès consecwinces divant
+d\' continouwer.',
+'movepagetalktext' => 'Li pådje di copene associeye, s\' end a ene, serè
+displaeceye otomaticmint avou, \'\'\'a moens ki:\'\'\'
+*Vos displaecîz l\' pådje d\' èn espåce di lomaedje a èn ôte,
+*Ene pådje di copene nén vude egzistêye dedja dizo l\' novea no,
+*Vos disclitchrîz l\' boesse a clitchî chal pa dzo.
+
+Dins ces cas la, vos dvroz displaecî l\' pådje di copene al mwin, ou rcopyî
+si contnou, si vos l\' vloz mete adlé l\' novea no
+d\' l\' årtike.',
+'movearticle' => 'Displaecî di',
+'movenologin' => 'Nén elodjî',
+'movenologintext' => 'I vs fåt esse èn uzeu eredjîstré eyet esse [[{{ns:special}}:Userlogin|elodjî]] por vos pleur displaecî ene pådje.',
+'newtitle' => 'Viè l\' novea tite',
+'movepagebtn' => 'Displaecî',
+'pagemovedsub' => 'Li displaçaedje a stî comifåt',
+'pagemovedtext' => 'Li pådje «[[$1]]» a stî displaceye viè «[[$2]]».',
+'articleexists' => 'Ene pådje egzistêye dedja avou ç\' no la, oudonbén
+li no k\' vos avoz tchoezi n\' est nén valide.
+Tchoezixhoz è èn ôte s\' i vs plait.',
+'talkexists' => '\'\'\'Li pådje leye minme a stî displaeceye comifåt, mins nén li pådje di copene, ca i gn aveut ddja ene pådje di copene k\' egzistéve al novele plaece. I vs fårè copyî l\' tecse del pådje di copene al mwin.\'\'\'',
+'movedto' => 'displaecî viè',
+'movetalk' => 'Displaecî li pådje di copene avou, si ça astchait.',
+'talkpagemoved' => 'Li pådje di copene corespondante a stî displaeceye avou.',
+'talkpagenotmoved' => 'Li pådje di copene corespondante n\' a <strong>nén</strong> stî displaeceye.',
+'1movedto2' => '[[$1]] displaecî viè [[$2]]',
+'1movedto2_redir' => '[[$1]] displaecî viè [[$2]] pa dsu on redjiblaedje',
+'movelogpage' => 'Djournå des displaçaedjes',
+'movelogpagetext' => 'Chal pa dzo c\' est ene djivêye des pådjes k\' on stî displaceyes.',
+'movereason' => 'Råjhon',
+'revertmove' => 'disfé',
+'delete_and_move' => 'Disfacer et displaecî',
+'delete_and_move_text' => '==I gn a mezåjhe di disfacer==
+
+L\' årtike såme «[[$1]]» egzistêye dedja. El voloz vs disfacer po vs permete di displaecî l\' ôte?',
+'delete_and_move_confirm' => 'Oyi, disfacer l\' pådje',
+'delete_and_move_reason' => 'Disfacé po permete on displaeçaedje',
+'selfmove' => 'Les tites sourdant et såme sont les minmes; ene pådje ni pout nén esse displaeceye so leye minme.',
+'immobile_namespace' => 'Li tite såme est d\' ene sôre especiåle; on n\' pout nén displaecî des pådjes dins cist espåce di lomaedje la.',
+
+# Export
+'export' => 'Ricopyî des pådjes foû',
+'exporttext' => 'Vos ploz rcopyî foû l\' tecse eyet l\' istwere des candjmints d\' ene pådje dinêye, ou co di sacwantes pådjes, eyet l\' aveur dins on fitchî e cogne XML. Çoula pout adon esse ristitchî dins èn ôte wiki k\' eploye MediaWiki, åd triviè del pådje di rstitchaedje (Special:Import).
+
+Po rcopyî des pådjes foû, metoz les tites des pådjes dins l\' boesse di tecse chal pa dzo, on tite pa roye, eyet tchoezixhoz si vos vloz totes les modêyes avou l\' istwere, ou rén kel dierinne modêye avou fok les racsegnes sol dierin candjmint.
+
+Dins ç\' dierin cas, vos ploz eto eployî ene hårdêye, eg: [[{{ns:special}}:Export/{{Mediawiki:mainpage}}]] pol pådje «{{Mediawiki:mainpage}}».',
+'exportcuronly' => 'Inclure fok li modêye do moumint, nén tote l\' istwere',
+'exportnohistory' => '----
+\'\'\'Note:\'\'\' li rcopiaedje foû di tote l\' istwere des pådjes a stî dismetou cåze di problinmes di tchedje des sierveus.',
+
+# Namespace 8 related
+'allmessages' => 'Tos les messaedjes ratournåves',
+'allmessagesname' => 'No del variåve',
+'allmessagesdefault' => 'Tecse prémetou',
+'allmessagescurrent' => 'Tecse pol moumint',
+'allmessagestext' => 'Çouchal est ene djivêye di tos les messaedjes k\' i gn a dins l\' espåce di lomaedje \'\'MediaWiki:\'\'',
+'allmessagesnotsupportedUI' => 'Vosse lingaedje do moumint po l\' eterface (<b>$1</b>) n\' est nén sopoirté pa Special:AllMessages so cisse waibe chal.',
+'allmessagesnotsupportedDB' => '\'\'\'Special:AllMessages\'\'\' n\' est nén sopoirté paski \'\'\'$wgUseDatabaseMessages\'\'\' est dismetou.',
+'allmessagesfilter' => 'Erîlêye ratourneure pol passete:',
+'allmessagesmodified' => 'Seulmint les cis candjîs',
+
+# Thumbnails
+'thumbnail-more' => 'Ragrandi',
+'missingimage' => '<b>Imådje mancante:</b><br /><i>$1</i>',
+'filemissing' => 'Fitchî mancant',
+'thumbnail_error' => 'Åk n\' a nén stî tot fjhant l\' pitite imådje: $1',
+
+# Special:Import
+'import' => 'Ristitchî des pådjes',
+'importtext' => 'S\' vs plait ricopyîz l\' fitchî foû do sourdant wiki avou l\' usteye di rcopiaedje foû (Special:Export), el schaper so voste éndjole, et poy l\' eberweter droci.',
+'importfailed' => 'Li ristitchaedje a fwait berwete: $1',
+'importnotext' => 'Vude ou pont d\' tecse',
+'importsuccess' => 'Li ristitchaedje a stî comifåt!',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => 'Cweri so {{SITENAME}} [alt-f]',
+'tooltip-minoredit' => 'Mete çouci come on candjmint mineur [alt-i]',
+'tooltip-save' => 'Schaper vos candjmints [alt-s]',
+'tooltip-preview' => 'Prévey vos candjmints, fijhoz l\' divant d\' schaper s\' i vs plait! [alt-p]',
+'tooltip-diff' => 'Mostrer les candjmints ki vos avoz fwait e tecse. [alt-v]',
+'tooltip-compareselectedversions' => 'Mostrer les diferinces etur les deus modêyes tchoezeyes di cisse pådje ci. [alt-v]',
+'tooltip-watch' => 'Radjouter cisse pådje ci a vosse djivêye des shuvous [alt-w]',
+
+# stylesheets
+'monobook.css' => '/* candjî ci fitchî ci po candjî l\' foye di stîle eyet l\' rivnance del waibe etire */',
+#'monobook.js' => '/* candjî ci fitchî ci po candjî l\' javascripe do stîle monobook */',
+
+# Metadata
+'notacceptable' => 'Li sierveu wiki èn vos pout nén dner les dnêyes dins ene cogne ki vosse cliyint sait lére.',
+
+# Attribution
+'anonymous' => 'Uzeu(s) anonime(s) di {{SITENAME}}',
+'siteuser' => 'Uzeu d\' {{SITENAME}} «$1»',
+'lastmodifiedatby' => 'Cisse pådje a stî candjeye pol dierin côp li $2, $1 pa $3.',
+'and' => 'eyet',
+'othercontribs' => 'Båzé so l\' ovraedje da $1.',
+'others' => 'des ôtes',
+'siteusers' => 'Uzeu(s) d\' {{SITENAME}} «$1»',
+'creditspage' => 'Pådje di credits',
+'nocredits' => 'I n\' a pont d\' informåcion di credits po cisse pådje ci.',
+
+# Spam protection
+'subcategorycount' => 'I gn a {{PLURAL:$1|ene dizo-categoreye|$1 dizo-categoreyes}} e cisse categoreye ci.',
+'categoryarticlecount' => 'I gn a {{PLURAL:$1|èn årtike|$1 årtikes}} e cisse categoreye ci.',
+'listingcontinuesabbrev' => ' cont.',
+
+# Info page
+'infosubtitle' => 'Informåcions pol pådje',
+'numedits' => 'Nombe di candjmints (årtike): $1',
+'numtalkedits' => 'Nombe di candjmints (pådje di copene): $1',
+'numwatchers' => 'Nombe di shuveus: $1',
+'numauthors' => 'Nombe d\' oteurs diferins (årtike): $1',
+'numtalkauthors' => 'Nombe d\' oteurs diferins (pådje di copene): $1',
+
+# Math options
+'mw_math_png' => 'Håyner tofer come ene imådje PNG',
+'mw_math_simple' => 'Håyner en HTML si c\' est foirt simpe, ôtmint e PNG',
+'mw_math_html' => 'Håyner en HTML si c\' est possibe, ôtmint e PNG',
+'mw_math_source' => 'El leyî e TeX (po les betchteus e môde tecse)',
+'mw_math_modern' => 'Ricmandé po les betchteus modienes',
+'mw_math_mathml' => 'Eployî MathML si c\' est possibe (esperimintå)',
+
+
+# NOTE: les apostrofes divèt esse escapêyes.
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* <pre> <nowiki> */
+/* tooltips and access keys */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'Pådje d\\\' uzeu da minne\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'Li pådje d\\\' uzeu po l\\\' adresse IP ki vos eployîz pol moumint\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'Pådje di copene da minne\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'Pådje di copene po les candjmints fwaits a pårti di ciste adresse IP ci\');
+ta[\'pt-preferences\'] = new Array(\'\',\'Mes preferinces\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'Li djivêye des pådjes ki vos shujhoz po cwand ele sont candjeyes.\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'Djivêye des ovraedjes da minne\');
+ta[\'pt-login\'] = new Array(\'o\',\'Vos estoz ecoraedjî d\\\' vos elodjî, mins nerén, c\\\' est nén oblidjî.\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'Vos estoz ecoraedjî d\\\' vos elodjî, mins nerén, c\\\' est nén oblidjî.\');
+ta[\'pt-logout\'] = new Array(\'\',\'Vos dislodjî\');
+ta[\'ca-talk\'] = new Array(\'t\',\'Copene åd fwait do contnou del pådje\');
+ta[\'ca-edit\'] = new Array(\'e\',\'Vos ploz candjî cisse pådje ci. S\\\' i vs plait, eployîz l\\\' boton «Vey divant» po vs acertiner k\\\' tot est comifåt dvant d\\\' schaper vos candjmints.\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'Radjouter on comintaire a cisse copene ci.\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'Cisse pådje ci est protedjeye. Vos ploz seulmint vey li côde sourdant, mins nén l\\\' candjî.\');
+ta[\'ca-history\'] = new Array(\'h\',\'Viyès modêyes del pådje.\');
+ta[\'ca-protect\'] = new Array(\'=\',\'Protedjî cisse pådje ci\');
+ta[\'ca-delete\'] = new Array(\'d\',\'Disfacer ci pådje ci\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'Rapexhî les candjmitns fwaits al pådje divant k\\\' ele soeyexhe disfacêye\');
+ta[\'ca-move\'] = new Array(\'m\',\'Displaecî cisse pådje ci\');
+ta[\'ca-watch\'] = new Array(\'w\',\'Radjouter cisse pådje ci al djivêye di vos årtikes shuvous\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'Bodjî cisse pådje ci di vosse djivêye des årtikes shuvous\');
+ta[\'search\'] = new Array(\'f\',\'Cweri so ci wiki chal\');
+ta[\'p-logo\'] = new Array(\'\',\'Mwaisse pådje\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'Vizitez li Mwaisse pådje\');
+ta[\'n-portal\'] = new Array(\'\',\'Åd fwait do pordjet, çou k\\\' vos ploz fé, wice trover des sacwès\');
+ta[\'n-currentevents\'] = new Array(\'\',\'Des informåcions so des evenmints d\\\' actouwålité\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'Li djivêye des dierins candjmints k\\\' i gn a-st avou sol wiki.\');
+ta[\'n-randompage\'] = new Array(\'x\',\'Tcherdjî ene pådje a l\\\' astcheyance\');
+ta[\'n-help\'] = new Array(\'\',\'Li plaece po trover les responses a vos kesses so l\\\' eployaedje do wiki.\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'Sopoirter l\\\' pordjet\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'Djivêye di totes les pådjes k\\\' ont des loyéns viè cisse pådje ci\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'Dierins candjmints fwaits so des pådjes ki cisse pådje ci a des loyéns viè zeles\');
+ta[\'feed-rss\'] = new Array(\'\',\'Sindicåcion RSS po cisse pådje ci\');
+ta[\'feed-atom\'] = new Array(\'\',\'Sindicåcion Atom po cisse pådje ci\');
+ta[\'t-contributions\'] = new Array(\'\',\'Vey li djivêye des ovraedjes fwait pa cist uzeu ci\');
+ta[\'t-emailuser\'] = new Array(\'\',\'Evoyî èn emile a cist uzeu ci\');
+ta[\'t-upload\'] = new Array(\'u\',\'Eberweter sol sierveu des imådjes ou fitchîs media\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'Djivêye di totes les pådjes sipeciåles\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'Vey li pådje di contnou\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'Vey li pådje di l\\\' uzeu\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'Vey li pådje di media\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'Çouchal, c\\\' est ene pådje sipeciåle, vos n\\\' poloz nén candjî l\\\' pådje leyminme.\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'Vey li pådje di pordjet\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'Vey li pådje d\\\' imådje\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'Vey li messaedje ratournåve do sistinme\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'Vey li modele\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'Vey li pådje d\\\' aidance\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'Vey li pådje di categoreye\');
+/* </nowiki> </pre> */',
+
+# image deletion
+'deletedrevision' => 'Viye modêye $1 disfacêye.',
+
+# browsing diffs
+'previousdiff' => '← Diferinces des candjmints di dvant',
+'nextdiff' => 'Diferinces des candjmints shuvants →',
+
+'imagemaxsize' => 'Limite pol håynaedje ezès pådjes d\' imådje:',
+'thumbsize' => 'Grandeu po les imådjetes (thumb):',
+'showbigimage' => 'Aberweter l\' grande modêye ($1x$2, $3 Ko)',
+
+'newimages' => 'Galreye des nouvès imådjes',
+'showhidebots' => '($1 robots)',
+'noimages' => 'I n\' a rén a vey.',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+#'variantname-zh-cn' => 'cn',
+#'variantname-zh-tw' => 'tw',
+#'variantname-zh-hk' => 'hk',
+#'variantname-zh-sg' => 'sg',
+#'variantname-zh' => 'zh',
+# variants for Serbian language
+#'variantname-sr-ec' => 'sr-ec',
+#'variantname-sr-el' => 'sr-el',
+#'variantname-sr-jc' => 'sr-jc',
+#'variantname-sr-jl' => 'sr-jl',
+#'variantname-sr' => 'sr',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => 'Uzeu:',
+'speciallogtitlelabel' => 'Tite:',
+
+'passwordtooshort' => 'Li scret est pår trop court. I doet esse di pol moens $1 caracteres.',
+
+# Media Warning
+'mediawarning' => '\'\'\'Asteme\'\'\': Ci fitchî chal pôreut esse evirussé, si vos l\' enondez vos pôrîz infecter l\' sistinme da vosse.<hr />',
+
+'fileinfo' => '$1Ko, sôre MIME: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Meta-dnêyes',
+'metadata-help' => 'Ci fitchî chal a des informåcions di rawete, motoit bén radjoutêyes pa l\' aparey foto limerike ou l\' sicanrece eployeye po fé l\' imådje. Si l\' imådje a stî candjeye dispoy adon, i s\' pout ki sacwants detays ni corespondexhe pus totafwait.',
+'metadata-expand' => 'Mostrer les stindous detays',
+'metadata-collapse' => 'Catchî les stindous detays',
+'metadata-fields' => 'Les tchamps di meta-dnêyes EXIF metous chal vont esse
+håynés ezès pådjes d\' imådje cwand l\' tåvlea di meta-dnêyes
+est raptiti. Les ôtes seront catchîs.
+* make
+* model
+* datetimeoriginal
+* exposuretime
+* fnumber
+* focallength',
+
+# Exif tags
+'exif-imagewidth' => 'Lårdjeur',
+'exif-imagelength' => 'Hôteur',
+'exif-bitspersample' =>'Bits pa compôzant',
+'exif-photometricinterpretation' =>'Compôzaedje des picsels',
+'exif-orientation' => 'Oryintåcion',
+'exif-samplesperpixel' =>'Nombe di compôzants',
+'exif-xresolution' => 'Finté d\' coûtchî',
+'exif-yresolution' => 'Finté d\' astampé',
+'exif-resolutionunit' => 'Unité pol finté d\' coûtchî/astampé',
+'exif-datetime' => 'Date ey eure ki l\' fitchî a stî candjî',
+'exif-imagedescription' => 'Tite di l\' imådje',
+'exif-make' => 'Måke del camera',
+'exif-model' => 'Modele del camera',
+'exif-software' => 'Programe eployî',
+'exif-artist' => 'Oteur',
+'exif-copyright' => 'Ditinteu des abondroets',
+'exif-exifversion' => 'Modêye d\' exif',
+'exif-colorspace' => 'Espåce di coleurs',
+'exif-makernote' => 'Notes do fabricant',
+'exif-usercomment' => 'Comintaires di l\' uzeu',
+'exif-datetimeoriginal' => 'Date ey eure ki les dnêyes ont stî fwaites',
+'exif-datetimedigitized' => 'Date ey eure do scanaedje',
+'exif-exposuretime-format' => '$1 seg ($2)',
+'exif-fnumber-format' =>'f/$1',
+'exif-lightsource' => 'Sourdant del loumire',
+'exif-focallength-format' =>'$1 mm',
+'exif-filesource' => 'Fitchî sourdant',
+'exif-scenetype' => 'Sôre di sinne',
+'exif-whitebalance' => 'Balance di blancs',
+'exif-digitalzoomratio' => 'Rapoirt di zoumaedje limerike',
+'exif-contrast' => 'Contrasse',
+'exif-saturation' => 'Saturaedje',
+'exif-gpslatituderef' => 'Latitude Nôr ou Sud',
+'exif-gpslatitude' => 'Latitude',
+'exif-gpslongituderef' => 'Londjitude Ess ou Ouwess',
+'exif-gpslongitude' => 'Londjitude',
+'exif-gpsaltituderef' => 'Referince di hôteur',
+'exif-gpsaltitude' => 'Hôteur',
+'exif-gpstimestamp' => 'Tins do GPS (ôrlodje atomike)',
+'exif-gpssatellites' => 'Sipoutniks eployîs pol mezuraedje',
+'exif-gpsmeasuremode' => 'Môde di mzuraedje',
+'exif-gpsdop' => 'Precizion di mzuraedje',
+'exif-gpsareainformation' => 'No del redjon GPS',
+'exif-gpsdatestamp' => 'Date do GPS',
+'exif-gpsdifferential' => 'Coridjaedje diferenciel do GPS',
+
+# Exif attributes
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => 'Normå', # 0th row: top; 0th column: left
+'exif-orientation-3' => 'Tourné di 180°', # 0th row: bottom; 0th column: right
+
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => 'n\' egzistêye nén',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => 'Nén defini',
+'exif-exposureprogram-1' => 'Al mwin',
+'exif-exposureprogram-2' => 'Programaedje normå',
+
+'exif-subjectdistance-value' => '$1 metes',
+
+'exif-meteringmode-0' => 'Nén cnoxhou',
+'exif-meteringmode-1' => 'Moyene',
+'exif-meteringmode-255' => 'Ôte',
+
+'exif-lightsource-0' => 'Nén cnoxhou',
+'exif-lightsource-1' => 'Loumire do djoû',
+'exif-lightsource-9' => 'Bon tins',
+'exif-lightsource-10' => 'Tins avou des nûlêyes',
+'exif-lightsource-17' => 'Loumire standård A',
+'exif-lightsource-18' => 'Loumire standård B',
+'exif-lightsource-19' => 'Loumire standård C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-255' => 'Ôte sourdant d\' loumire',
+
+'exif-focalplaneresolutionunit-2' => 'pôces',
+
+'exif-sensingmethod-1' => 'Nén defineye',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => 'On poitrait saetchî directumint',
+
+
+
+'exif-whitebalance-0' => 'Balance di blancs otomatike',
+'exif-whitebalance-1' => 'Balance di blancs al mwin',
+
+'exif-scenecapturetype-3' => 'Sinne di nute',
+
+
+'exif-contrast-0' => 'Normå',
+'exif-contrast-1' => 'Doûs',
+'exif-contrast-2' => 'Deur',
+
+'exif-saturation-0' => 'Normå',
+'exif-saturation-1' => 'Fwebe saturaedje',
+'exif-saturation-2' => 'Foirt saturaedje',
+
+'exif-sharpness-0' => 'Normåle',
+'exif-sharpness-1' => 'Doûce',
+'exif-sharpness-2' => 'Deure',
+
+'exif-subjectdistancerange-0' => 'Nén cnoxhowe',
+'exif-subjectdistancerange-2' => 'Did près',
+'exif-subjectdistancerange-3' => 'Did lon',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => 'Latitude Nôr',
+'exif-gpslatitude-s' => 'Latitude Sud',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => 'Londjitude Ess',
+'exif-gpslongitude-w' => 'Londjitude Ouwess',
+
+
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => 'km/h',
+'exif-gpsspeed-m' => 'miles/h',
+'exif-gpsspeed-n' => 'nuks',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+
+# external editor support
+'edit-externally' => 'Candjî ç\' fitchî ci avou on dfoûtrin programe',
+'edit-externally-help' => 'Loukîz les [http://meta.wikimedia.org/wiki/Help:External_editors instruccions d\' apontiaedje] po pus di racsegnes.',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => 'totafwait',
+'imagelistall' => 'totafwait',
+'watchlistall1' => 'totafwait',
+'watchlistall2' => 'totafwait',
+'namespacesall' => 'tos',
+
+# E-mail address confirmation
+'confirmemail' => 'Acertinaedje di l\' adresse emile',
+'confirmemail_text' => 'Ci wiki chal a mezåjhe ki vos acertinîz voste adresse emile
+divant d\' poleur eployî les fonccions d\' emilaedje. Clitchîz sol boton
+chal pa dzo po-z evoyî èn emile d\' acertinaedje a voste adresse.
+Li messaedje a-st å dvins ene hårdêye (loyén) avou on côde;
+tcherdjîz l\' hårdêye dins l\' betchteu waibe da vosse, eyet
+acertinez ki l\' adresse emile est djusse tot dnant l\' côde.',
+'confirmemail_send' => 'Emiler on côde d\' acertinaedje',
+'confirmemail_sent' => 'L\' emile d\' acertinaedje a stî evoyî.',
+'confirmemail_sendfailed' => 'Dji n\' a savou evoyî l\' emile d\' acertinaedje. Verifyîz ki l\' adresse est bén djusse.',
+'confirmemail_invalid' => 'Côde d\' acertinaedje nén valide. Motoit k\' il esteut trop vî.',
+'confirmemail_needlogin' => 'I vs fåt $1 po pleur acertiner voste adresse emile.',
+'confirmemail_success' => 'Voste adresse emile a stî acertinêye. Vos vs poloz asteure elodjî eyet profiter do wiki.',
+'confirmemail_loggedin' => 'Voste adresse emile a stî acertinêye.',
+
+'confirmemail_subject' => 'Acertinaedje di l\' adresse emile po {{SITENAME}}',
+'confirmemail_body' => 'Ene sakî, probåblumint vos-minme, avou l\' adresse IP $1,
+a-st ahivé on conte so {{SITENAME}} avou ciste adresse
+emile ci eyet come no d\' elodjaedje «$2».
+
+Po-z acertiner ki ç\' conte ci est bén da vosse eyet mete
+en alaedje les fonccions d\' emilaedje so {{SITENAME}},
+alez drovî avou vosse betchteu waibe li hårdêye ki shût:
+
+$3
+
+Si c\' est *nén* vos k\' a-st ahivé l\' conte, adon èn shuvoz
+nén l\' hårdêye. Ci côde d\' acertinaedje ci va-st espirer
+po l\' $4.',
+
+# Inputbox extension, may be useful in other contexts as well
+'createarticle' => 'Ahiver årtike',
+
+# Scary transclusion
+
+
+# delete conflict
+'deletedwhileediting' => 'Asteme: Cisse pådje ci a stî disfacêye sol tins ki vos scrijhîz!',
+'confirmrecreate' => 'L\' uzeu [[{{ns:user}}:$1|$1]] ([[{{ns:user_talk}}:$1|copene]]) a disfacé cist årtike ci après ki vos avoz cmincî a scrire, li råjhon k\' il a dné c\' est:
+: \'\'$2\'\'.
+Acertinez s\' i vs plait ki vos vloz vormint rifé cist årtike ci.',
+'recreate' => 'Rifé',
+#'tooltip-recreate' => '',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => 'Redjiblant viè [[$1]]...',
+
+# action=purge
+'confirm_purge' => 'Netyî l\' muchete di cisse pådje ci?
+
+$1',
+'confirm_purge_button' => '\'l est bon',
+
+'youhavenewmessagesmulti' => 'Vos avoz des noveas messaedjes so $1',
+'searchcontaining' => 'Cweri après des årtikes k\' ont «\'\'$1\'\'» å dvins.',
+'searchnamed' => 'Cweri après des årtikes lomés «\'\'$1\'\'».',
+'articletitles' => 'Årtikes ki cmincèt avou «\'\'$1\'\'»',
+'hideresults' => 'Catchî les rzultats',
+
+# Makebot - FIXME move to the extension
+'makebot' => 'Diner ou rsaetchî l\' livea d\' robot',
+'makebot-header' => '\'\'\'On mwaisse-manaedjeu sol wiki pout eployî cisse pådje ci po dner ou rsaetchî l\' [[{{ns:help}}:Robots|livea d\' robot]] a èn ôte conte d\' uzeu.\'\'\'<br />El livea d\' robot fwait ki les candjmints da cist uzeu la si polèt catchî dins l\' pådje des [[{{special}}:Recentchanges|dierins candjmints]] et des sfwaitès djivêyes, çou k\' est ahessåve po mårker les uzeus ki fjhèt des candjmints otomatikes. Çoula doet esse fwait tot shuvant les rîles ki s\' aplikèt.',
+'makebot-username' => 'No d\' uzeu:',
+'makebot-search' => 'I va',
+'makebot-change' => 'Candjî l\' livea:',
+'makebot-grant' => 'Diner',
+'makebot-revoke' => 'Rissaetchî',
+'makebot-comment' => 'Comintaire:',
+'makebot-logpage' => 'Djournå des liveas d\' robot',
+'makebot-granted' => '[[{{ns:user}}:$1|$1]] a-st asteure li livea d\' robot.',
+'makebot-isbot' => '[[{{ns:user}}:$1|$1]] a l\' livea d\' robot.',
+'makebot-logentrygrant' => 'a dné l\' livea d\' robot a [[$1]]',
+'makebot-logentryrevoke' => 'a rsaetchî l\' livea d\' robot da [[$1]]',
+'makebot-logpagetext' => 'Çouchal, c\' est on djournå des dinaedjes eyet rsaetchaedjes do [[{{ns:help}}:Robots|livea d\' robot]] a des uzeus.',
+'makebot-notbot' => '[[{{ns:user}}:$1|$1]] n\' a nén l\' livea d\' robot',
+'makebot-privileged' => '[[{{ns:user}}:$1|$1]] a ddja on livea d\' [[{{ns:special}}:Listadmins|manaedjeu ou mwaisse-manaedjeu]], ça fwait k\' i n\' pout nén eployî ç\' conte la po on robot.',
+'makebot-revoked' => '[[{{ns:user}}:$1|$1]] n\' a pus d\' livea d\' robot.',
+
+);
+
+?>
diff --git a/languages/messages/MessagesXal.php b/languages/messages/MessagesXal.php
new file mode 100644
index 000000000000..b281cd3be4ca
--- /dev/null
+++ b/languages/messages/MessagesXal.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+# Kalmyk stub localization;
+
+$namespaceNames = array(
+ NS_MEDIA => 'Аһар',
+ NS_SPECIAL => 'Көдлхнə',
+ NS_MAIN => '',
+ NS_TALK => 'Ухалвр',
+ NS_USER => 'Орлцач',
+ NS_USER_TALK => 'Орлцачна_тускар_ухалвр',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_тускар_ухалвр',
+ NS_IMAGE => 'Зург',
+ NS_IMAGE_TALK => 'Зургин_тускар_ухалвр',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_тускар_ухалвр',
+ NS_TEMPLATE => 'Зура',
+ NS_TEMPLATE_TALK => 'Зуран_тускар_ухалвр',
+ NS_HELP => 'Цəəлһлһн',
+ NS_HELP_TALK => 'Цəəлһлһин_тускар_ухалвр',
+ NS_CATEGORY => 'Янз',
+ NS_CATEGORY_TALK => 'Янзин_тускар_ухалвр',
+);
+
+$fallback8bitEncoding = "windows-1251";
+
+
+$messages = array(
+
+'edit' => 'Чиклх',
+'article' => 'Халх',
+'history' => 'Чикллһнə бүрткл',
+'nstab-main' => 'Халх',
+'nstab-user' => 'Орлцач',
+'nstab-template' => 'Зура',
+'nstab-help' => 'Цəəлһлһн',
+'nstab-category' => 'Янз',
+'talkpage' => 'Ухалвр',
+'history_short' => 'Чикллһнə бүрткл',
+
+
+'createaccount' => 'Выль вики-авторлэн регистрациез',
+'login' => 'Оруллһн',
+'mycontris' => 'Мини өгүллһдүд',
+'mytalk' => 'Мини күүндлһн бəəрм',
+'preferences' => 'Дурллһн',
+
+);
+
+
+?>
diff --git a/languages/messages/MessagesYi.php b/languages/messages/MessagesYi.php
new file mode 100644
index 000000000000..19a307dfa8fa
--- /dev/null
+++ b/languages/messages/MessagesYi.php
@@ -0,0 +1,586 @@
+<?php
+/** Yiddish (ייִדיש)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+$fallback = 'he';
+
+$namespaceNames = array(
+ NS_MEDIA => 'מעדיע',
+ NS_SPECIAL => 'באַזונדער',
+ NS_MAIN => '',
+ NS_TALK => 'רעדן',
+ NS_USER => 'באַניצער',
+ NS_USER_TALK => 'באַניצער_רעדן',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_רעדן',
+ NS_IMAGE => 'בילד',
+ NS_IMAGE_TALK => 'בילד_רעדן',
+ NS_MEDIAWIKI => 'מעדיעװיקי',
+ NS_MEDIAWIKI_TALK => 'מעדיעװיקי_רעדן',
+ NS_TEMPLATE => 'מוסטער',
+ NS_TEMPLATE_TALK => 'מוסטער_רעדן',
+ NS_HELP => 'הילף',
+ NS_HELP_TALK => 'הילף_רעדן',
+ NS_CATEGORY => 'קאַטעגאָריע',
+ NS_CATEGORY_TALK => 'קאַטעגאָריע_רעדן'
+);
+
+$namespaceAliases = array(
+ 'באזונדער' => NS_SPECIAL,
+ 'באנוצער' => NS_USER,
+ 'באנוצער_רעדן' => NS_USER_TALK,
+ 'מעדיעוויקי' => NS_MEDIAWIKI,
+ 'מעדיעוויקי_רעדן' => NS_MEDIAWIKI_TALK,
+ 'קאטעגאריע' => NS_CATEGORY,
+ 'קאטעגאריע_רעדן' => NS_CATEGORY_TALK,
+ 'באניצער' => NS_USER,
+ 'באניצער_רעדן' => NS_USER_TALK,
+);
+
+$rtl = true;
+$defaultUserOptionOverrides = array(
+ # Swap sidebar to right side by default
+ 'quickbar' => 2,
+);
+
+/**
+ * Magic words.
+ * Disabling the Hebrew ones.
+ */
+$magicWords = array(
+ 'redirect' => array( 0, '#REDIRECT' ),
+ 'notoc' => array( 0, '__NOTOC__' ),
+ 'nogallery' => array( 0, '__NOGALLERY__' ),
+ 'forcetoc' => array( 0, '__FORCETOC__' ),
+ 'toc' => array( 0, '__TOC__' ),
+ 'noeditsection' => array( 0, '__NOEDITSECTION__' ),
+ 'start' => array( 0, '__START__' ),
+ 'currentmonth' => array( 1, 'CURRENTMONTH' ),
+ 'currentmonthname' => array( 1, 'CURRENTMONTHNAME' ),
+ 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN' ),
+ 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV' ),
+ 'currentday' => array( 1, 'CURRENTDAY' ),
+ 'currentday2' => array( 1, 'CURRENTDAY2' ),
+ 'currentdayname' => array( 1, 'CURRENTDAYNAME' ),
+ 'currentyear' => array( 1, 'CURRENTYEAR' ),
+ 'currenttime' => array( 1, 'CURRENTTIME' ),
+ 'currenthour' => array( 1, 'CURRENTHOUR' ),
+ 'localmonth' => array( 1, 'LOCALMONTH' ),
+ 'localmonthname' => array( 1, 'LOCALMONTHNAME' ),
+ 'localmonthnamegen' => array( 1, 'LOCALMONTHNAMEGEN' ),
+ 'localmonthabbrev' => array( 1, 'LOCALMONTHABBREV' ),
+ 'localday' => array( 1, 'LOCALDAY' ),
+ 'localday2' => array( 1, 'LOCALDAY2' ),
+ 'localdayname' => array( 1, 'LOCALDAYNAME' ),
+ 'localyear' => array( 1, 'LOCALYEAR' ),
+ 'localtime' => array( 1, 'LOCALTIME' ),
+ 'localhour' => array( 1, 'LOCALHOUR' ),
+ 'numberofpages' => array( 1, 'NUMBEROFPAGES' ),
+ 'numberofarticles' => array( 1, 'NUMBEROFARTICLES' ),
+ 'numberoffiles' => array( 1, 'NUMBEROFFILES' ),
+ 'numberofusers' => array( 1, 'NUMBEROFUSERS' ),
+ 'pagename' => array( 1, 'PAGENAME' ),
+ 'pagenamee' => array( 1, 'PAGENAMEE' ),
+ 'namespace' => array( 1, 'NAMESPACE' ),
+ 'namespacee' => array( 1, 'NAMESPACEE' ),
+ 'talkspace' => array( 1, 'TALKSPACE' ),
+ 'talkspacee' => array( 1, 'TALKSPACEE' ),
+ 'subjectspace' => array( 1, 'SUBJECTSPACE', 'ARTICLESPACE' ),
+ 'subjectspacee' => array( 1, 'SUBJECTSPACEE', 'ARTICLESPACEE' ),
+ 'fullpagename' => array( 1, 'FULLPAGENAME' ),
+ 'fullpagenamee' => array( 1, 'FULLPAGENAMEE' ),
+ 'subpagename' => array( 1, 'SUBPAGENAME' ),
+ 'subpagenamee' => array( 1, 'SUBPAGENAMEE' ),
+ 'basepagename' => array( 1, 'BASEPAGENAME' ),
+ 'basepagenamee' => array( 1, 'BASEPAGENAMEE' ),
+ 'talkpagename' => array( 1, 'TALKPAGENAME' ),
+ 'talkpagenamee' => array( 1, 'TALKPAGENAMEE' ),
+ 'subjectpagename' => array( 1, 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ),
+ 'subjectpagenamee' => array( 1, 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ),
+ 'msg' => array( 0, 'MSG:' ),
+ 'subst' => array( 0, 'SUBST:' ),
+ 'msgnw' => array( 0, 'MSGNW:' ),
+ 'end' => array( 0, '__END__' ),
+ 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' ),
+ 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1'),
+ 'img_right' => array( 1, 'right' ),
+ 'img_left' => array( 1, 'left' ),
+ 'img_none' => array( 1, 'none' ),
+ 'img_width' => array( 1, '$1px' ),
+ 'img_center' => array( 1, 'center', 'centre' ),
+ 'img_framed' => array( 1, 'framed', 'enframed', 'frame' ),
+ 'img_page' => array( 1, 'page=$1', 'page $1' ),
+ 'int' => array( 0, 'INT:' ),
+ 'sitename' => array( 1, 'SITENAME' ),
+ 'ns' => array( 0, 'NS:' ),
+ 'localurl' => array( 0, 'LOCALURL:' ),
+ 'localurle' => array( 0, 'LOCALURLE:' ),
+ 'server' => array( 0, 'SERVER' ),
+ 'servername' => array( 0, 'SERVERNAME' ),
+ 'scriptpath' => array( 0, 'SCRIPTPATH' ),
+ 'grammar' => array( 0, 'GRAMMAR:' ),
+ 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
+ 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
+ 'currentweek' => array( 1, 'CURRENTWEEK' ),
+ 'currentdow' => array( 1, 'CURRENTDOW' ),
+ 'localweek' => array( 1, 'LOCALWEEK' ),
+ 'localdow' => array( 1, 'LOCALDOW' ),
+ 'revisionid' => array( 1, 'REVISIONID' ),
+ 'revisionday' => array( 1, 'REVISIONDAY' ),
+ 'revisionday2' => array( 1, 'REVISIONDAY2' ),
+ 'revisionmonth' => array( 1, 'REVISIONMONTH' ),
+ 'revisionyear' => array( 1, 'REVISIONYEAR' ),
+ 'revisiontimestamp' => array( 1, 'REVISIONTIMESTAMP' ),
+ 'plural' => array( 0, 'PLURAL:' ),
+ 'fullurl' => array( 0, 'FULLURL:' ),
+ 'fullurle' => array( 0, 'FULLURLE:' ),
+ 'lcfirst' => array( 0, 'LCFIRST:' ),
+ 'ucfirst' => array( 0, 'UCFIRST:' ),
+ 'lc' => array( 0, 'LC:' ),
+ 'uc' => array( 0, 'UC:' ),
+ 'raw' => array( 0, 'RAW:' ),
+ 'displaytitle' => array( 1, 'DISPLAYTITLE' ),
+ 'rawsuffix' => array( 1, 'R' ),
+ 'newsectionlink' => array( 1, '__NEWSECTIONLINK__' ),
+ 'currentversion' => array( 1, 'CURRENTVERSION' ),
+ 'urlencode' => array( 0, 'URLENCODE:' ),
+ 'anchorencode' => array( 0, 'ANCHORENCODE' ),
+ 'currenttimestamp' => array( 1, 'CURRENTTIMESTAMP' ),
+ 'localtimestamp' => array( 1, 'LOCALTIMESTAMP' ),
+ 'directionmark' => array( 1, 'DIRECTIONMARK', 'DIRMARK' ),
+ 'language' => array( 0, '#LANGUAGE:' ),
+ 'contentlanguage' => array( 1, 'CONTENTLANGUAGE', 'CONTENTLANG' ),
+ 'pagesinnamespace' => array( 1, 'PAGESINNAMESPACE:', 'PAGESINNS:' ),
+ 'numberofadmins' => array( 1, 'NUMBEROFADMINS' ),
+ 'formatnum' => array( 0, 'FORMATNUM' ),
+ 'padleft' => array( 0, 'PADLEFT' ),
+ 'padright' => array( 0, 'PADRIGHT' ),
+ 'special' => array( 0, 'special', ),
+ 'defaultsort' => array( 1, 'DEFAULTSORT:' ),
+);
+
+$messages = array(
+'tog-usenewrc' => 'פֿאַרבעסערטע "לעצטע ענדערונגען" (JavaScript)',
+'tog-watchdefault' => 'נאָכפֿאָלג אױטאָמאַטיש די װערטן װאָס איך באַאַרבעט',
+'tog-previewontop' => 'צײַגן דעם "פֿאָרויסיקע װײַזונג" גלײַך בײַם ערשטע באַאַרבעטונג',
+'tog-fancysig' => '<br />
+Raw signatures (without automatic link)',
+'sunday' => 'זונטיק',
+'monday' => 'מאָנטיק',
+'tuesday' => 'דינסטיק',
+'wednesday' => 'מיטװאָך',
+'thursday' => 'דאָנערשטיק',
+'friday' => 'פֿרײַטיק',
+'saturday' => 'שבת',
+'january' => 'יאַנואַר',
+'february' => 'פֿעברואַר',
+'march' => 'מאַרץ',
+'april' => 'אַפּריל',
+'may_long' => 'מײַ',
+'june' => 'יוני',
+'july' => 'יולי',
+'august' => 'אױגוסט',
+'september' => 'סעפּטעמבער',
+'october' => 'אָקטאָבער',
+'november' => 'נאָװעמבער',
+'december' => 'דעצעמבער',
+'jan' => 'יאַנ׳',
+'feb' => 'פֿעב׳',
+'mar' => 'מאַר׳',
+'apr' => 'אַפּר׳',
+'may' => 'מײַ',
+'jun' => 'יונ׳',
+'jul' => 'יול׳',
+'aug' => 'אױג׳',
+'sep' => 'סעפּ׳',
+'oct' => 'אָקט׳',
+'nov' => 'נאָװ׳',
+'dec' => 'דעץ׳',
+'categories' => 'קאַטעגאָריעס',
+'pagecategories' => '{{PLURAL:$1|קאַטעגאָריע|קאַטעגאָריעס}}',
+'category_header' => 'אַרטיקלען אין קאַטעגאָריע "$1"',
+'subcategories' => 'אונטערקאַטעגאָריעס',
+'mainpage' => 'ערשטע זײַט',
+'portal' => 'געמיינדע',
+'portal-url' => 'Project:געמיינדע',
+'about' => 'איבער',
+'help' => 'הילף',
+'helppage' => 'Help:אינהאַלט',
+'sitesupport' => 'נדבֿות',
+'sitesupport-url' => 'Project:נדבֿות',
+'edithelp' => 'הילף ווי צו באַאַרבעטן',
+'newwindow' => '(עס ווערט געהעפֿנט אין אַ נײַעם פענסטער)',
+'cancel' => 'מבטל זײַן',
+'qbedit' => 'ענדערן',
+'mytalk' => 'מײַן רעדן בלאַט',
+'navigation' => 'נאַװיגאַציע',
+'currentevents' => 'נײַקײטן',
+'currentevents-url' => '{{ns:project}}:נײַקײטן',
+'disclaimers' => '
+פֿאַרלײקענען',
+'privacy' => 'פערזענלעכקײַט דורכפֿירונג',
+'returnto' => 'צוריקקערן צו $1.',
+'tagline' => 'פֿון {{SITENAME}}',
+'search' => 'זוכן',
+'searchbutton' => 'זוכן',
+'go' => 'גײן',
+'searcharticle' => 'גײן',
+'history' => 'אױפֿלאַגעס / מחברים',
+'history_short' => 'געשיכטע',
+'printableversion' => 'דרוק פֿעיקע װערסיע',
+'permalink' => 'אײביקער בונד',
+'edit' => 'ענדערן און פארעכטן',
+'delete' => 'אַראָפּנעמען',
+'protect' => 'אױסהיטן',
+'unprotect' => 'באַפֿרײַען',
+'newpage' => 'א נײַעם בלאַט',
+'talkpage' => 'רעדן',
+'specialpage' => 'באַזונדער',
+'talk' => 'רעדן און שמועסן',
+'toolbox' => 'מכשירים',
+'otherlanguages' => 'אין אַנדערע שפראַכן',
+'redirectedfrom' => '(אַריבערגעפֿירט פון $1)',
+'lastmodifiedat' => 'די לעצטע ענדערונג פון די בלאט איז געווען $2, $1.',
+'copyright' => 'אינהאַלט שטייט אונטער $1.',
+'jumptosearch' => 'זוכן',
+'ok' => 'יאָ',
+'youhavenewmessages' => 'דו האָסט $1 ($2).',
+'newmessageslink' => 'אַ נײַעם מעלדונג',
+'newmessagesdifflink' => 'אונטערשייד פון לעצטע ווערסיע',
+'editsection' => 'בעאַרבעטן',
+'toc' => 'אינהאַלט',
+'showtoc' => 'װאַיִזן',
+'hidetoc' => 'באַהאַלטן',
+'thisisdeleted' => 'זעה אדער שטעל צוריק $1?',
+'viewdeleted' => 'װאַיִזן $1?',
+'nstab-main' => 'אַרטיקל',
+'nstab-user' => 'באַנוצער זײַט',
+'nstab-media' => 'מעדיע',
+'nstab-special' => 'באַזונדער',
+'nstab-image' => 'בילד',
+'nstab-mediawiki' => 'בשׂורה',
+'nstab-template' => 'מוסטער',
+'nstab-help' => 'הילף',
+'nstab-category' => 'קאַטעגאָריע',
+'logouttext' => '<strong>האָסט זיך ארויסלאָגירט מיט הצלחה.</strong>',
+'yourname' => 'באַנוצער־נאָמען',
+'yourpassword' => 'שפּריכװאָרט',
+'remembermypassword' => 'געדיינק מיך',
+'login' => 'אַרײַנלאָגירן',
+'loginprompt' => 'איר מוסט ערלויבן קיכלעך ("cookies") אויף צו אַרײַנלאָגירן אינעם {{SITENAME}}.',
+'userlogin' => 'אײַנלאָגירן / זיך אײַנשרײַבן',
+'logout' => 'אַרױסלאָגירן',
+'userlogout' => 'אַרױסלאָגירן',
+'notloggedin' => 'נישט איינגעשריבן',
+'youremail' => 'בליצאַדרעס (*)',
+'username' => 'באַנוצער־נאָמען:',
+'uid' => 'באַנוצער־נומער:',
+'yourlanguage' => 'שפּראַך:',
+'yourvariant' => 'װאַריאַנט',
+'yournick' => 'אונטערשריפט',
+'email' => 'בליצבריוו',
+'loginsuccess' => '\'\'\'דו ביסט יעצט אַרײַנלאָגירט אַלץ "$1" אינעם {{SITENAME}}.\'\'\'',
+'bold_sample' => 'טייפּט דאָ אַריין די ווארט אדער ווערטער וואס זאל זיין מיט דיקע אותיות',
+'bold_tip' => 'דאס טוישט צו \'\'\'בּאָלד (דיק)\'\'\' די אויסגעוועלטע ווארט.',
+'italic_sample' => 'דאס וועט מאכן \'\'שיף\'\' די אויסגעוועלט ווארט.',
+'italic_tip' => 'דאס וועט מאכן \'\'שיף\'\' די אויסגעוועלט פאנט.',
+'link_sample' => 'שרײַבט דאָ אַרײַן די װערטער װאָס װעט זײַן אַ לינק צו {{SITENAME}} אַרטיקל אין דעם נושא',
+'link_tip' => 'מאך דאס א \'\'\'לינק\'\'\' צו א וויקיפעדיע ארטיקל',
+'headline_sample' => 'לייג דא אריין דעם טעקסט פונעם נייעם קעפּל',
+'headline_tip' => 'אַ נײַער קעפּל, (אײַנצוטײלן דעם אַרטיקל)',
+'nowiki_sample' => 'אינסערט נישט-פארמארטירטע טעקסט דא',
+'nowiki_tip' => 'דאָס וועט איגנאָרירן די וויקי פֿאָרמאַטינג קאָוד',
+'image_tip' => 'לייג ארויף א בילד',
+'sig_tip' => 'אייער אינטערשריפט, מיט א צייט סטעמפּל ווען איר האט אונטערגעשריבן.',
+'hr_tip' => 'א שטרייך אין די ברייט, (נישט נוצן אפט)',
+'summary' => 'קורץ וואָרט',
+'minoredit' => '‏איך האָב נאָר עטוואָס באַאַרבעט',
+'watchthis' => 'זײט אױפֿפּאַסן',
+'savearticle' => 'זײט אױפֿהיט',
+'preview' => 'פאראויסיגע ווייזונג',
+'showpreview' => 'פֿאָרױסיקע װײַזונג',
+'showdiff' => 'ווײַז מײַן בײַטונג',
+'blockedtext' => 'דיין באנוצער נאמען אדער דיין IP אדרעס איז פאַרשפאַרט געווארן דורך $1 פון וועגן $2.
+<p>קענסט זיך ווענדן צו $1 אדער צו אנדערע [[{{ns:Project}}:Administrators|דירעקטארס]] צו דורכרעדן וועגן דעם.<p>
+
+Note that you may not use the "e-mail this user" feature unless you have a valid e-mail address registered in your [[{{ns:Special}}:Preferences|user preferences]].
+
+Your IP address is $3. Please include this address in any queries you make.',
+'loginreqlink' => 'login',
+'newarticletext' => '\'\'\'דער בלאַט עקזיסטירט נאָך נישט!\'\'\' איר קענט יעצט שרײַבן אַ נײַעם אַרטיקל אין די אונטערשטע קעסטל. (זעהט דעם [[הילף:ווי צו שרייבן ווערטן|הילף בלאַט]] ווי אַזוי צו שרײַבן אַרטיקלען).',
+'clearyourcache' => '<div dir="ltr">
+\'\'\'Note:\'\'\' After saving, you have to bypass your browser\'s cache to see the changes. \'\'\'Mozilla/Safari/Konqueror:\'\'\' hold down \'\'Shift\'\' while clicking \'\'Reload\'\' (or press \'\'Ctrl-Shift-R\'\'), \'\'\'IE:\'\'\' press \'\'Ctrl-F5\'\', \'\'\'Opera:\'\'\' press \'\'F5\'\'.
+</div>',
+'previewnote' => '<strong>דאס איז נאָר אין אַ פֿאָרויסיקע ווייזונג, דער אַרטיקל איז דערווייל נאָך נישט געהיט!</strong>',
+'editing' => 'בעארבעטן $1',
+'editinguser' => 'בעארבעטן $1',
+'editconflict' => 'ענדערן קאנפליקט: $1',
+'editingold' => '<div style="background: #FFBDBD; border: 1px solid #BB7979; color: #000000; font-weight: bold; margin: 2em 0 1em; padding: .5em 1em; vertical-align: middle; clear: both;">פאָרזיכטיג! \'\'באארבעטסט יעצט נישט קיין אקטועלע ווערסיע, אויב דו וועסט היטן דעם באארבעטונג, וועט די לעצטע ענדרענונגען גיין קאַפוט.\'\'<!-- [[{{ns:Project}}:Reverting|removed]] -->.‎</div>',
+'copyrightwarning' => '<small>ביטע מערק אויף אז דיינע אלע טיילונגען אינעם \'\'\'{{SITENAME}}\'\'\' איז אונטער דעם [http://www.gnu.org/copyleft/fdl.html $2] דערלויבן (מער פרטים זעה $1). אויב דו וויִלסט נישט זאלן דיינע טיילונגען דערשיינען ווערן און זאלן אנדערע קענען קאפירן דיין אינהאַלט - ביטע שרייב זיי נישט אַהער. איר זאגט צו אז איר האט געשריבן אן אייגענעם אינהאַלט, אדער האט איר באקומען א ערלויבונג צו איר שרייבן</small>',
+'currentrev' => 'נײַע באַאַרבעטונג',
+'previousrevision' => '→ Older revision',
+'nextrevision' => 'Newer revision ←',
+'last' => 'צו לעצט',
+'histlegend' => 'Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.<br />
+Legend: (cur) = difference with current version,
+(צו לעצט) = difference with preceding version, מ = minor edit.',
+'difference' => '(אונטערשייד צווישן באַאַרבעטונגען)',
+'compareselectedversions'=> 'פארגלייך סעלעקטירטע ווערסיעס',
+'searchresulttext' => 'לערנען מער ווי צו זוכן אינעם {{SITENAME}} [[{{ns:Help}}:זוכן|קוועטשט אַהער]]',
+'searchsubtitle' => '[[:$1]]',
+'searchsubtitleinvalid' => '$1',
+'noexactmatch' => 'דערווייל איז נאָך נישטאָ א בלאט מיט דעם טיטל.<br /> איר זײַט געלאדנט [[:$1|אויפשרייבן א נייעם בלאט]], אדער [[Project:בעטן ווערטן|בעטן פון פריינד]] זאלן זיי שרייבן.',
+'viewprevnext' => '($1) ($2) ($3).',
+'powersearch' => 'זוכן',
+'blanknamespace' => '(אַרטיקל)',
+'preferences' => 'אײַנשטעלן',
+'changepassword' => 'שפּריכװאָרט איבערמאַכן',
+'skin' => 'סקין',
+'math' => 'פאָרמאַל',
+'datetime' => 'דאַטע אונד צײַט',
+'prefs-personal' => 'באַנוצער פראָפֿיל',
+'prefs-rc' => 'לעצטע ענדערונגען',
+'prefs-misc' => 'באַאַרבעטן',
+'saveprefs' => 'אױפֿהיטן',
+'resetprefs' => 'צוריק שטעלן צום נאָרמאַל',
+'oldpassword' => 'אַלטע שפּריכװאָרט:',
+'newpassword' => 'נייע פּעסוואָרד:',
+'retypenew' => 'שפריכוואָרט ווידער שרײַבן:',
+'textboxsize' => 'באַאַרבעטן',
+'rows' => 'שורות:',
+'columns' => 'זײַלן:',
+'searchresultshead' => 'זוכן',
+'recentchangescount' => 'דער צאָל פון ליניעס אין די לעצטע ענדערונגען:',
+'allowemail' => 'ערלויבן אנדערע צו אײַך שיקן בליצבריוון',
+'files' => 'טעקעס',
+'changes' => 'ענדערונגען',
+'recentchanges' => 'לעצטע ענדערונגען',
+'rcnote' => 'אונטער זײַנען די לעצטע <strong>$1</strong> ענדערונגען אין די לעצטע <strong>$2</strong> טאָג. $3',
+'rclistfrom' => 'װײַזן די נײַע ענדערונגען זײַט $1',
+'rcshowhideminor' => '$1 מינערדיקע רעדאַקטירן',
+'rcshowhidebots' => '$1 ראָבאָטן',
+'rcshowhideliu' => '$1 אײַנגעשריבינע באַנוצערס',
+'rcshowhideanons' => '$1 אַנאָנימע באַנוצערס',
+'rcshowhidepatr' => '$1 טעכנישע אַקציעס',
+'rcshowhidemine' => '$1 מײַנע טיילונגען',
+'rclinks' => 'װײַזן די לעצטע $1 ענדערונגען אין דעם לעצטע $2 טאָג.<br />$3',
+'diff' => 'אונטערשייד',
+'hist' => 'געשיכטע',
+'hide' => 'באַהאַלטן',
+'show' => 'װאַיִזן',
+'minoreditletter' => 'מ',
+'newpageletter' => 'נ',
+'sectionlink' => '←',
+'upload' => 'בילדער/פיילס אַרױפֿלאָדירן',
+'uploadbtn' => 'טעקע אַרױפֿלאָדירן',
+'uploadlog' => 'אויפלאָדירע לאָגבוך',
+'savefile' => 'טעקע אױפֿהיטן',
+'uploadedimage' => 'אַרױפֿלאָדירט "[[$1]]"',
+'imagelisttext' => 'Below is a list of $1 files sorted $2.',
+'ilsubmit' => 'זוכן',
+'statistics' => 'סטאַטיסטיק',
+'sitestatstext' => 'יעצט איז דא \'\'\'$2\'\'\' אַרטיקלען אינעם [[{{SITENAME}}]].
+
+און \'\'\'$1\'\'\' בלעטער (אריינגערעכנט מיט די אַרומנעמיקע בלעטער ווי "רעדן בלעטער", "רידיירעקטן" א.א.וו).
+
+‎\'\'\'$8\'\'\' files have been uploaded.‎
+
+\'\'\'$4\'\'\' באַאַרבעטונגען.
+דורכשניטלעך \'\'\'$5\'\'\' באַאַרבעטונגען פאַר יעדן בלאַט.',
+'disambiguationspage' => '{{ns:template}}:באַטײַטן',
+'brokenredirects' => 'צובראָכענע רידיירעקטן',
+'nbytes' => '$1 bytes',
+'nlinks' => '$1 לינקן',
+'wantedpages' => 'װינטשט זײטן',
+'mostcategories' => 'אַרטיקלען מיט די מערקסטע קאַטעגאָריעס',
+'mostrevisions' => 'אַרטיקלען מיט די מערקסטע באַאַרבעטונגען',
+'randompage' => 'צופֿעליקער אַרטיקל',
+'specialpages' => 'ספּעציעלע זײטן',
+'recentchangeslinked' => 'פֿאַרבונדענע ענדערונגען',
+'ancientpages' => 'עלטסטער זײטן',
+'move' => 'באַװעגן',
+'booksources' => 'דרויסנדיקע ליטעראַטור ISBN',
+'categoriespagetext' => 'די ווײַטערדיקע קאַטעגאָריען עקסיסטירט אין {{SITENAME}}.',
+'allpagessubmit' => 'גיין',
+'emailpage' => 'אימעיל\'ט דעם באנוצער.',
+'defemailsubject' => 'וויקיפעדיער בליצבריוו',
+'emailfrom' => 'פון',
+'emailto' => 'צו',
+'emailsubject' => 'טעמע',
+'emailmessage' => 'מעלדונג',
+'emailsend' => 'שיקן',
+'watchlist' => 'אַכטונגע ליסט',
+'addedwatch' => 'צוגעלייגט געוואָרן צום "אַכטונגע ליסט"',
+'addedwatchtext' => 'דער אַרטיקל "[[:$1]]" איז צוגעלײגט געוואָרן צו דײַן [[{{ns:Special}}:Watchlist|אַכטונגע ליסט]].
+
+<div dir="ltr">
+Future changes to this page and its associated Talk page will be listed there,
+and the page will appear \'\'\'bolded\'\'\' in the [[{{ns:Special}}:Recentchanges|list of recent changes]] to
+make it easier to pick out.
+
+<p>If you want to remove the page from your watchlist later, click "Stop watching" in the sidebar.</p>
+</div>',
+'removedwatch' => 'אַראָפּגענומען פונעם "אַכטונגע ליסט"',
+'removedwatchtext' => 'דער אַרטיקל "[[:$1]]" איז אָפּגעראַמעט געוואָרן פון דײַן אַכטונגע ליסט',
+'watch' => 'אױפֿפּאַסן',
+'watchthispage' => 'זײט אױפֿפּאַסן',
+'unwatch' => 'אויפֿהערן אויפֿפּאַסן',
+'wlhideshowown' => '$1 מײנע רעדאַקטירן.',
+'wlhideshowbots' => '$1 ראָבאָט רעדאַקטירן.',
+'deletepage' => 'זײט אַראָפּנעמען',
+'excontent' => 'מיטן אינהאַלט: \'$1\'',
+'excontentauthor' => 'מיטן אינהאַלט: \'$1\' (זיין איינציגער באַאַרבעטער: \'$2\')',
+'rollback_short' => 'אויפֿריכטן',
+'rollbacklink' => 'צוריקדרייען',
+'revertpage' => 'אויפֿגעריכט פון באַנוצער $2 צוריק צום לעצטע ווערסיע פון באַנוצער $1',
+'undeletebtn' => 'Restore!',
+'namespace' => 'באַגרעניצן צו:',
+'invert' => 'ווײַז אַלע אויסער די',
+'contributions' => 'באנוצער\'ס אלע טיילונגען',
+'mycontris' => 'מײַנע טיילונגען',
+'whatlinkshere' => 'װאָס די אױף דאָס זײט פֿאַרבינדט',
+'blockip' => 'באַניצער אַרױסטרײבן',
+'ipbother' => 'אַנדער צײַט',
+'ipboptions' => '15 מינוטן:15 minutes,
+1 שעה:1 hour,
+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',
+'ipbotheroption' => 'אַנדער',
+'infiniteblock' => 'אויף אייביק',
+'blocklink' => 'אַרױסטרײַבן',
+'unblocklink' => 'באַפֿרײַען',
+'contribslink' => 'באַנוצערס שרײַבונגען',
+'blocklogentry' => 'פֿאַשפּאַרט "[[$1]]" אויף אַ תקופה פון $2',
+'pagemovedsub' => 'באַוועגט מיט הצלחה',
+'pagemovedtext' => 'Page "[[$1]]" באַוועגנט צו "[[$2]]".',
+'movedto' => 'באַוועגנט צו',
+'1movedto2' => '[[:$1]] באַוועגנט צו [[:$2]]',
+'1movedto2_redir' => '[[:$1]] באַוועגט צו [[:$2]] פון',
+'revertmove' => 'צוריקדרייען',
+'allmessagesname' => 'נאָמען',
+'tooltip-search' => 'זוכן {{SITENAME}} [alt-f]',
+'tooltip-diff' => 'Show which changes you made to the text. [alt-v]',
+'lastmodifiedatby' => 'די לעצטע ענדערונג פון די בלאט איז געווען $2, $1 ביי $3.',
+'and' => 'און',
+'subcategorycount' => 'ס\'איז דאָ $1 אונטערקאַטעגאָריעס צו די קאַטעגאָריע.',
+'categoryarticlecount' => 'ס\'איז דאָ $1 אַרטיקלען אין די קאַטעגאָריע.',
+'monobook.js' => '/* <div style="direction: ltr;"><pre> */
+var ta = new Object();
+ta["pt-userpage"] = [".", "מיין באניצער בלאט"];
+ta["pt-anonuserpage"] = [".", "באניצער בלאט פון אנינונימער באניצער"];
+ta["pt-mytalk"] = ["n", "מיין רעדן בלאט"];
+ta["pt-anontalk"] = ["n", "רעדן אויף אנינונימע באטייליגען"];
+ta["pt-preferences"] = ["", "מיינע פעיווערעטס"];
+ta["pt-watchlist"] = ["l", "אויפפּאסן בלעטער"];
+ta["pt-mycontris"] = ["y", "מיינע באטייליגונגן"];
+ta["pt-login"] = ["o", "ביטע איינשרייבן, אבער עס איז נישט קיין חוב"];
+ta["pt-anonlogin"] = ["o", "סבעסער איינשרייבן, אבער עס איז נישט קיין חוב"];
+ta["pt-logout"] = ["", "זיך אויסשרייבן"];
+ta["ca-talk"] = ["t", "שמועס אויף דעם בלאט"];
+ta["ca-edit"] = ["e", "קענסט פארעכטן דעם בלאט. ביטע זיך באניצן מיט קנעפל \"פאראויסיגע ווייזונג\" בעפארן אויפהיטן."];
+ta["ca-addsection"] = ["+", "לייג צו אייער ווארט צו דעם שמועס"];
+ta["ca-viewsource"] = ["e", "דאס איז א פארשלאסן בלאט, קענסט נאר קוקן איר מקור"];
+ta["ca-history"] = ["h", "פריערדיגע ווערסיעס פון דעם בלאט."];
+ta["ca-protect"] = ["=", "הגנו על דף זה"];
+ta["ca-delete"] = ["d", "אויסמעקן דעם בלאט"];
+ta["ca-undelete"] = ["d", "צוריק דרייען די ענדערונגען פון דעם בלאט פארן מעקן"];
+ta["ca-move"] = ["m", "פירט אריבער דעם בלאט"];
+ta["ca-watch"] = ["w", "לייגט צו דעם בלאט אויפצופאסן"];
+ta["ca-unwatch"] = ["w", "נעמט אראפ דעם בלאט פון אויפפאסן"];
+ta["search"] = ["f", "זוכט אינעם סייט"];
+ta["p-logo"] = ["", "הויפט זייט"];
+ta["n-mainpage"] = ["z", "באזוכט דעם הויפט זייט"];
+ta["n-portal"] = ["", "גייט אריין אין די געמיינדע צו שמועסן"];
+ta["n-currentevents"] = ["", "לעצטע אינפארמאציע איבער טואונגען פון וויקיפעדיע"];
+ta["n-recentchanges"] = ["r", "ליסטע פון לעצטע ענדערונגען"];
+ta["n-randompage"] = ["x", "וועלט אויס א צופעליגער בלאט"];
+ta["n-help"] = ["", "הילף"];
+ta["n-sitesupport"] = ["", "צדקה אויפצוהאלטן דעם סייט"];
+ta["t-whatlinkshere"] = ["j", "אלע בלעטער וואס פארבינדען צו דעם בלאט"];
+ta["t-recentchangeslinked"] = ["k", "אלע ענדערונגען פון בלעטער וואס זענען אהער פארבינדען"];
+ta["feed-rss"] = ["", "לייגט צו אן אטאמאטישער אפדעיט פון אר.עס.עס. RSS"];
+ta["feed-atom"] = ["", "לייג צו אן אטאמאטישער אפדעיט דורך אטאם Atom"];
+ta["t-contributions"] = ["", "אלע שרייבאכצער פון דעם באנוצער"];
+ta["t-emailuser"] = ["", "שיקט אן אימעיל פאר דעם באניצער"];
+ta["t-upload"] = ["u", "לייגט ארויף פיילס און בילדער"];
+ta["t-specialpages"] = ["q", "אלע ספעציעלע בלעטער"];
+ta["ca-nstab-main"] = ["c", "בליקט אינעם אינהאלט בלאט"];
+ta["ca-nstab-user"] = ["c", "קוקט אין באניצער בלאט"];
+ta["ca-nstab-media"] = ["c", "קוקט אין די מידיע בלעטער"];
+ta["ca-nstab-special"] = ["", "דאס איז א ספעציעלע בלאט, מקען איר נישט ענדערן"];
+ta["ca-nstab-project"] = ["a", "צפו בדף המיזם"];
+ta["ca-nstab-image"] = ["c", "צפו בדף תיאור התמונה"];
+ta["ca-nstab-mediawiki"] = ["c", "צפו בהודעת המערכת"];
+ta["ca-nstab-template"] = ["c", "צפו בתבנית"];
+ta["ca-nstab-help"] = ["c", "באזוכט די הילף בלעטער"];
+ta["ca-nstab-category"] = ["c", "באזוכט די קאטעגאריע בלעטער"];
+
+function bidiSwitchSetup() {
+ var editform = document.getElementById("wpTextbox1");
+ if (editform == null) {
+ return;
+ }
+
+ bidiAddButton(editform, "Default", function(style) {
+ style.direction = "inherit";
+ style.unicodeBidi = "inherit";
+ });
+ bidiAddButton(editform, "dir=ltr", function(style) {
+ style.direction = "ltr";
+ });
+ bidiAddButton(editform, "dir=rtl", function(style) {
+ style.direction = "rtl";
+ });
+ bidiAddButton(editform, "bidi=normal", function(style) {
+ style.unicodeBidi = "normal";
+ });
+ bidiAddButton(editform, "bidi=override", function(style) {
+ style.unicodeBidi = "bidi-override";
+ });
+}
+
+function bidiAddButton(before, label, action) {
+ var button = document.createElement("input");
+ button.type = "button";
+ button.value = label;
+ button.onclick = function(event) {
+ var box = document.getElementById("wpTextbox1");
+ if (box == null) {
+ alert("Broken! Edit box missing.");
+ } else {
+ //var style = document.getOverrideStyle(box, null);
+ var style = box.style;
+ action(style);
+ }
+ }
+ before.parentNode.insertBefore(button, before);
+}
+
+hookEvent(\'load\', bidiSwitchSetup);
+
+/* </pre></div> */',
+'previousdiff' => 'פריעריגע אונטערשייד →',
+'nextdiff' => 'קומענדיקע אונטערשייד ←',
+'newimages' => 'גאַלעריע אויף נײַע בילדער',
+'showhidebots' => '($1 ראָבאָמן)',
+'exif-artist' => 'מחבר',
+'exif-componentsconfiguration-0'=> 'עס עקזיסטירט נישט.',
+'recentchangesall' => 'אַלע',
+'imagelistall' => 'אַלע',
+'watchlistall1' => 'אַלע',
+'watchlistall2' => 'אַלע',
+'namespacesall' => 'אַלע',
+'confirm_purge' => '<span dir="ltr">Clear the cache of this page?</span> $1',
+'confirm_purge_button' => 'יאָ',
+);
+?>
diff --git a/languages/messages/MessagesZa.php b/languages/messages/MessagesZa.php
new file mode 100644
index 000000000000..acf1e456f65e
--- /dev/null
+++ b/languages/messages/MessagesZa.php
@@ -0,0 +1,9 @@
+<?php
+/** Zhuang (壮语)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'zh-cn';
+?>
diff --git a/languages/messages/MessagesZh.php b/languages/messages/MessagesZh.php
new file mode 100644
index 000000000000..a97bba1594dd
--- /dev/null
+++ b/languages/messages/MessagesZh.php
@@ -0,0 +1,7 @@
+<?php
+
+# Stub message file for converter code "zh"
+
+$fallback = 'zh-cn';
+
+?>
diff --git a/languages/messages/MessagesZh_cn.php b/languages/messages/MessagesZh_cn.php
new file mode 100644
index 000000000000..ce4911bce368
--- /dev/null
+++ b/languages/messages/MessagesZh_cn.php
@@ -0,0 +1,856 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Talk',
+ NS_USER => 'User',
+ NS_USER_TALK => 'User_talk',
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1_talk',
+ NS_IMAGE => 'Image',
+ NS_IMAGE_TALK => 'Image_talk',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Template_talk',
+ NS_HELP => 'Help',
+ NS_HELP_TALK => 'Help_talk',
+ NS_CATEGORY => 'Category',
+ NS_CATEGORY_TALK => 'Category_talk'
+);
+
+$namespaceAliases = array(
+ "特殊" => NS_SPECIAL,
+ "对话" => NS_TALK,
+ "用户" => NS_USER,
+ "用户对话" => NS_USER_TALK,
+ # This has never worked so it's unlikely to annoy anyone if I disable it -- TS
+ #"{{SITENAME}}_对话" => NS_PROJECT_TALK
+ "图像" => NS_IMAGE,
+ "图像对话" => NS_IMAGE_TALK,
+);
+
+$quickbarSettings = array(
+ "无", /* "None" */
+ "左侧固定", /* "Fixed left" */
+ "右侧固定", /* "Fixed right" */
+ "左侧漂移" /* "Floating left" */
+);
+
+$skinNames = array(
+ 'standard' => "标准",
+ 'nostalgia' => "怀旧",
+ 'cologneblue' => "科隆香水蓝"
+);
+
+$extraUserToggles = array(
+ 'nolangconversion',
+);
+$datePreferences = false;
+$defaultDateFormat = 'zh';
+$dateFormats = array(
+ 'zh time' => 'H:i',
+ 'zh date' => 'Y年Mj日',
+ 'zh both' => 'H:i Y年Mj日',
+);
+
+$messages = array(
+# User Toggles
+
+"tog-underline" => "下划链接", /* "Underline links", */
+/* "Format broken links <a href=\"\" class=\"new\">like this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).", */
+"tog-highlightbroken" => "毁坏链接格式<a href=\"\" class=\"new\">像这样</a> (或者像这个<a href=\"\" class=\"internal\">?</a>)",
+"tog-justify" => "段落对齐", /* "Justify paragraphs", */
+"tog-hideminor" => "最近更改中隐藏细微修改", /* "Hide minor edits in recent changes", */
+"tog-usenewrc" => "最近更改增强(只适用部分浏览器)", /* "Enhanced recent changes (not for all browsers)", */
+"tog-numberheadings" => "标题自动编号",
+"tog-showtoolbar" => "Show edit toolbar", /* "Auto-number headings", */
+"tog-editondblclick" => "双击页面编辑(JavaScript)",
+"tog-editsection"=>"允许通过点击[编辑]链接编辑段落",
+"tog-editsectiononrightclick"=>"允许右击标题编辑段落(JavaScript)",
+"tog-showtoc"=>"显示目录<br />(针对一页超过3个标题的文章)",
+"tog-rememberpassword" => "下次登陆记住密码", /* "Remember password across sessions", */
+"tog-editwidth" => "编辑栏位宽度", /* "Edit box has full width", */
+"tog-editondblclick" => "双击编辑页面(Javascript)", /* "Edit pages on double click (JavaScript)", */
+"tog-watchdefault" => "监视新的以及更改过的文章", /* "Watch new and modified articles", */
+"tog-minordefault" => "细微编辑为默认设置", /* "Mark all edits minor by default", */
+"tog-previewontop" => "在编辑框上方显示预览", /* "Show preview before edit box and not after it" */
+# Dates
+
+'sunday' => "星期日",
+'monday' => "星期一",
+'tuesday' => "星期二",
+'wednesday' => "星期三",
+'thursday' => "星期四",
+'friday' => "星期五",
+'saturday' => "星期六",
+'january' => "1月",
+'february' => "2月",
+'march' => "3月",
+'april' => "4月",
+'may_long' => "5月",
+'june' => "6月",
+'july' => "7月",
+'august' => "8月",
+'september' => "9月",
+'october' => "10月",
+'november' => "11月",
+'december' => "12月",
+'jan' => "1月",
+'feb' => "2月",
+'mar' => "3月",
+'apr' => "4月",
+'may' => "5月",
+'jun' => "6月",
+'jul' => "7月",
+'aug' => "8月",
+'sep' => "9月",
+'oct' => "10月",
+'nov' => "11月",
+'dec' => "12月",
+
+# Bits of text used by many pages:
+#
+"categories" => "页面分类",
+"pagecategories" => "页面分类",
+"category_header" => "类别”$1“中的条目",
+"subcategories" => "附分类",
+"mainpage" => "首页",
+"about" => "关于",
+"aboutsite" => "关于{{SITENAME}}",
+"aboutpage" => "{{ns:project}}:关于",
+"help" => "帮助",
+"helppage" => "{{ns:project}}:帮助",
+"bugreports" => "错误报告",
+"bugreportspage" => "{{ns:project}}:错误报告",
+"faq" => "常见问题解答",
+"faqpage" => "{{ns:project}}:常见问题解答",
+"edithelp" => "编辑帮助",
+"edithelppage" => "{{ns:project}}:如何编辑页面",
+"cancel" => "取消",
+"qbfind" => "寻找",
+"qbbrowse" => "浏览",
+"qbedit" => "编辑",
+"qbpageoptions" => "页面选项",
+"qbpageinfo" => "页面信息",
+"qbmyoptions" => "我的选项",
+"mypage" => "我的页面",
+"mytalk" => "我的对话页",
+"currentevents" => "新闻动态",
+"errorpagetitle" => "错误",
+"returnto" => "返回到$1.",
+"whatlinkshere" => "链入页面",
+"help" => "帮助",
+"search" => "搜索",
+"searchbutton" => "搜索",
+"go" => "进入",
+'searcharticle' => "进入",
+"history" => "较早版本",
+"printableversion" => "可打印版",
+"editthispage" => "编辑本页",
+"deletethispage" => "删除本页",
+"protectthispage" => "保护本页",
+"unprotectthispage" => "解除保护",
+"newpage" => "新页面",
+"talkpage" => "讨论本页",
+ "postcomment" => "发表评论",
+"articlepage" => "查看文章",
+"userpage" => "查看用户页",
+"projectpage" => "查看meta页",
+"imagepage" => "查看图像页面",
+"viewtalkpage" => "查看讨论",
+"otherlanguages" => "其它语言",
+"redirectedfrom" => "(重定向自$1)",
+"lastmodifiedat" => "最后更改$2, $1.",
+"viewcount" => "本页面已经被浏览$1次。",
+"protectedpage" => "被保护页",
+"nbytes" => "$1字节",
+"ok" => "OK",
+"retrievedfrom" => "取自\"$1\"",
+"newmessageslink" => "新信息",
+"editsection"=>"编辑",
+"editold"=>"编辑",
+"toc" => "目录",
+"showtoc" => "显示",
+"hidetoc" => "隐藏",
+
+# Main script and global functions
+#
+"nosuchaction" => "没有这个命令",
+"nosuchactiontext" => "URL请求的命令无法被 {{SITENAME}} 软件识别。",
+"nosuchspecialpage" => "没有这个特殊页。",
+
+"nospecialpagetext" => "您请求的页面无法被 {{SITENAME}} 软件识别。",
+
+# General errors
+#
+"error" => "错误",
+"databaseerror" => "数据库错误",
+"dberrortext" => "数据库指令语法错误。
+这可能是由于非法搜索指令所引起的(见 $5),
+也可能是由于软件自身的错误所引起。
+最后一次数据库指令是:
+<blockquote><tt>$1</tt></blockquote>
+来自于函数 \"<tt>$2</tt>\"。
+MySQL返回错误 \"<tt>$3: $4</tt>\"。",
+"noconnect" => "无法在 $1上连接数据库",
+"nodb" => "无法选择数据库 $1",
+"readonly" => "数据库禁止访问",
+"enterlockreason" => "请输入禁止访问原因, 包括估计重新开放的时间",
+"readonlytext" => "{{SITENAME}}数据库目前禁止输入新内容及更改,
+这很可能是由于数据库正在维修,之后即可恢复。
+管理员有如下解释:
+<p>$1",
+"missingarticle" => "数据库找不到文字\"$1\"。
+
+<p>通常这是由于修订历史页上过时的链接到已经被删除的页面所导致的。
+
+<p>如果情况不是这样,您可能找到了软件内的一个臭虫。
+请记录下URL地址,并向管理员报告。",
+"internalerror" => "内部错误",
+"filecopyerror" => "无法复制文件\"$1\"到\"$2\"。",
+"filerenameerror" => "无法重命名文件\"$1\" 到\"$2\"。",
+"filedeleteerror" => "无法删除文件 \"$1\"。",
+"filenotfound" => "找不到文件 \"$1\"。",
+"unexpected" => "不正常值: \"$1\"=\"$2\"。",
+"formerror" => "错误:无法提交表单",
+"badarticleerror" => "无法在本页上进行此项操作。",
+"cannotdelete" => "无法删除选定的页面或图像(它可能已经被其他人删除了)。",
+"badtitle" => "错误的标题",
+"badtitletext" => "所请求页面的标题是无效的、不存在,跨语言或跨wiki链接的标题错误。",
+"perfdisabled" => "抱歉!由于此项操作有可能造成数据库瘫痪,目前暂时无法使用。",
+"perfdisabledsub" => "这里是自$1的复制版本:",
+
+# 登录与登出
+#
+"logouttitle" => "用户退出",
+"logouttext" => "您现在已经退出。
+您可以继续以匿名方式使用Wikipeida,或再次以相同或不同用户身份登录。",
+
+"welcomecreation" => "<h2>欢迎,$1!</h2><p>您的帐号已经建立,不要忘记设置{{SITENAME}}个人参数。",
+
+"loginpagetitle" => "用户登录",
+"yourname" => "您的用户名",
+"yourpassword" => "您的密码",
+"yourpasswordagain" => "再次输入密码",
+"remembermypassword" => "下次登录记住密码。",
+"loginproblem" => "<b>登录有问题。</b><br />再试一次!",
+"alreadyloggedin" => "<strong>用户$1,您已经登录了!</strong><br />",
+
+"login" => "登录",
+"userlogin" => "用户登录",
+"logout" => "退出",
+"userlogout" => "用户退出",
+"createaccount" => "创建新帐号",
+ "createaccountmail" => "通过eMail",
+"badretype" => "你所输入的密码并不相同。",
+"userexists" => "您所输入的用户名已有人使用。请另选一个。",
+"youremail" => "您的电子邮件*",
+"yournick" => "绰号(签名时用)",
+"loginerror" => "登录错误",
+"noname" => "你没有输入一个有效的用户名。",
+"loginsuccesstitle" => "登录成功",
+"loginsuccess" => "你现在以 \"$1\"的身份登录{{SITENAME}}。",
+"nosuchuser" => "找不到用户 \"$1\"。
+检查您的拼写,或者用下面的表格建立一个新帐号。",
+"wrongpassword" => "您输入的密码错误,请再试一次。",
+"mailmypassword" => "将新密码寄给我",
+"passwordremindertitle" => "{{SITENAME}}密码提醒",
+"passwordremindertext" => "有人(可能是您,来自IP地址$1)要求我们将新的{{SITENAME}}登录密码寄给你。
+用户 \"$2\" 的密码现在是 \"$3\"。
+请立即登录并更改密码。",
+"noemail" => "用户\"$1\"没有登记电子邮件地址。",
+"passwordsent" => "用户\"$1\"的新密码已经寄往所登记的电子邮件地址。
+请在收到后再登录。",
+
+# 编辑
+#
+"summary" => "简述",
+"subject" => "主题",
+"minoredit" => "这是一个小修改",
+"watchthis" => "监视本页",
+"savearticle" => "保存本页",
+"preview" => "预览",
+"showpreview" => "显示预览",
+"blockedtitle" => "用户被封",
+"blockedtext" => "您的用户名或IP地址已被$1封。
+理由是:<br />'''$2'''<p>您可以与$1向其他任何[[{{ns:project}}:管理员|管理员]]询问。",
+ "whitelistedittitle" => "登录后才可编辑",
+ "whitelistedittext" => "您必须先[[Special:Userlogin|登录]]才可编辑页面。",
+ "whitelistreadtitle" => "登录后才可阅读",
+ "whitelistreadtext" => "您必须先[[Special:Userlogin|登录]]才可阅读页面。",
+ "whitelistacctitle" => "您被禁止建立帐号",
+ "whitelistacctext" => "在本Wiki中建立帐号您必须先[[Special:Userlogin|登录]]并拥有相关权限。",
+ "accmailtitle" => "密码寄出",
+ "accmailtext" => "'$1'的密码已经寄到$2。",
+"newarticle" => "(新)",
+"newarticletext" =>
+"您从一个链接进入了一个并不存在的页面。
+要创建该页面,请在下面的编辑框中输入内容(详情参见{{ns:project}}:帮助|帮助页面]])。
+如果您不小心来到本页面,直接点击您浏览器中的“返回”按钮。",
+
+"anontalkpagetext" => "---- ''这是一个还未建立帐号的匿名用户的对话页。我们因此只能用[[IP地址]]来与他/她联络。该IP地址可能由几名用户共享。如果您是一名匿名用户并认为本页上的评语与您无关,请[[Special:Userlogin|创建新帐号或登录]]以避免在未来于其他匿名用户混淆。''",
+"noarticletext" => "(本页目前没有内容)",
+"updated" => "(已更新)",
+"note" => "<strong>注意:</strong>",
+"previewnote" => "请记住这只是预览,内容还未保存!",
+"previewconflict" => "这个预览显示了上面文字编辑区中的内容。它将在你选择保存后出现。",
+"editing" => "正在编辑$1",
+'editinguser' => "正在编辑$1",
+"editingsection" => "正在编辑$1 (段落)",
+"editingcomment" => "正在编辑$1 (评论)",
+"editconflict" => "编辑冲突:$1",
+"explainconflict" => "有人在你开始编辑后更改了页面。
+上面的文字框内显示的是目前本页的内容。
+你所做的修改显示在下面的文字框中。
+你应当将你所做的修改加入现有的内容中。
+<b>只有</b>在上面文字框中的内容会在你点击\"保存页面\"后被保存。<br />",
+"yourtext" => "您的文字",
+"storedversion" => "已保存版本",
+"editingold" => "<strong>警告:你正在编辑的是本页的旧版本。
+如果你保存它的话,在本版本之后的任何修改都会丢失。</strong>",
+"yourdiff" => "差别",
+/*"copyrightwarning" => "请注意对{{SITENAME}}的任何贡献都将被认为是在GNU自由文档协议证书下发布。
+(细节请见$1).
+如果您不希望您的文字被任意修改和再散布,请不要提交。<br />
+您同时也向我们保证你所提交的内容是你自己所作,或得自一个不受版权保护或相似自由的来源。
+<strong>不要在未获授权的情况下发表!</strong>",*/
+
+"longpagewarning" => "<strong>警告:本页长度达$1KB;一些浏览器将无法编辑长过32KB的文章。请考虑将本文切割成几个小段落。</strong>",
+
+"readonlywarning" => "<strong>警告:数据库被锁以进行维护,所以您目前将无法保存您的修改。您或许希望先将本断文字复制并保存到文本文件,然后等一会儿再修改。</strong>",
+"protectedpagewarning" => "<strong>警告:本页已经被保护,只有拥有管理员权限的用户才可修改。请确认您遵守
+[[Project:Protected_page_guidelines|保护页面守则]].</strong>",
+
+# History pages
+#
+"revhistory" => "修订历史",
+"nohistory" => "没有本页的修订记录。",
+"revnotfound" => "没有找到修订记录",
+"revnotfoundtext" => "您请求的更早版本的修订记录没有找到。
+请检查您请求本页面用的 URL 是否正确。",
+"loadhist" => "载入页面修订历史",
+"currentrev" => "当前修订版本",
+"revisionasof" => "$1的修订版本",
+"cur" => "当前",
+"next" => "后继",
+"last" => "先前",
+"orig" => "初始",
+"histlegend" => "说明:(当前)指与当前修订版本比较;(先前)指与前一个修订版本比较,小 指细微修改。",
+
+# Diffs
+#
+"difference" => "(修订版本间差异)",
+"loadingrev" => "载入修订版本比较",
+"lineno" => "第 $1 行:",
+"editcurrent" => "编辑本页的当前修订版本",
+
+# Search results
+#
+"searchresults" => "搜索结果",
+"searchresulttext" => "有关搜索{{SITENAME}}的更多详情,参见[[Project:搜索|搜索{{SITENAME}}]]。",
+"searchsubtitle" => "查询\"[[:$1]]\"",
+"searchsubtitleinvalid" => "查询\"$1\"",
+"badquery" => "搜索查询不正确",
+"badquerytext" => "我们无法处理您的查询。
+这可能是由于您试图搜索一个短于3个字母的外文单词,
+或者您错误地输入了搜索项,例如\"汽车和和火车\"。
+请再尝试一个新的搜索项。",
+"matchtotals" => "搜索项\"$1\"与$2条文章的题目相符,和$3条文章相符。",
+
+"noexactmatch" => "没有文章与搜索项完全匹配,请尝试完整文字搜索。",
+"titlematches" => "文章题目相符",
+"notitlematches" => "没有找到匹配文章题目",
+"textmatches" => "文章内容相符",
+"notextmatches" => "没有文章内容匹配",
+
+"prevn" => "先前$1",
+"nextn" => "之后$1",
+"viewprevnext" => "查看 ($1) ($2) ($3).",
+"showingresults" => "下面显示<b>$1</b>条结果,从第<b>$2</b>条开始",
+"nonefound" => "<strong>注意:</strong>失败的搜索往往是由于试图搜索诸如“的”或“和”之类的常见字所引起。",
+"powersearch" => "搜索",
+"powersearchtext" => "
+搜索名字空间:<br />$1<br />$2列出重定向页面;搜索$3 $9",
+
+"searchdisabled" => "<p>{{SITENAME}}内部搜索功能由于高峰时段服务器超载而停止使用。
+您可以暂时通过
+<a href=\"http://google.com/\">google</a>搜索{{SITENAME}}。
+谢谢您的耐心。",
+
+# Preferences page
+#
+"preferences" => "参数设置",
+"prefsnologin" => "还未登录",
+"prefsnologintext" => "您必须先[[Special:Userlogin|登录]]才能设置个人参数。",
+"prefsreset" => "参数重新设置。",
+"qbsettings" => "快速导航条设置",
+"changepassword" => "更改密码",
+"skin" => "Skin",
+"math" => "数学显示",
+"math_failure" => "无法解析",
+"math_unknown_error" => "未知错误",
+"math_unknown_function" => "未知函数",
+"math_lexing_error" => "句法错误",
+"math_syntax_error" => "语法错误",
+"saveprefs" => "保存参数设置",
+"resetprefs" => "重设参数",
+"oldpassword" => "旧密码",
+"newpassword" => "新密码",
+"retypenew" => "重复新密码",
+"textboxsize" => "文字框尺寸",
+"rows" => "行",
+"columns" => "列",
+"searchresultshead" => "搜索结果设定",
+"resultsperpage" => "每页显示链接数",
+"contextlines" => "每链接行数",
+"contextchars" => "每行字数",
+"stubthreshold" => "stub显示基本限制",
+"recentchangescount" => "最近更改页行数",
+"savedprefs" => "您的个人参数设置已经保存。",
+"timezonetext" => "输入当地时间与服务器时间(UTC)的时差。",
+"localtime" => "当地时间",
+"timezoneoffset" => "差",
+
+# Recent changes
+#
+"changes" => "更改",
+"recentchanges" => "最近更改",
+"recentchangestext" => "本页跟踪{{SITENAME}}内最新的更改。
+[[{{ns:project}}:欢迎,新来者|欢迎,新来者]]!
+请参见这些页面:[[{{ns:project}}:常见问题解答|{{SITENAME}}常见问题解答]]、
+[[{{ns:project}}:守则与指导|{{SITENAME}}守则]]
+(特别是[[{{ns:project}}:命名常规|命名常规]]、
+[[{{ns:project}}:中性的观点|中立观点]])
+和[[{{ns:project}}:最常见失礼行为|最常见失礼行为]]。
+
+如果您希望 {{SITENAME}} 成功,那么请您不要增加受其它[[{{ns:project}}:版权信息|版权]]
+限制的材料,这一点将非常重要。相关的法律责任会伤害本项工程,所以请不要这样做。
+此外请参见",
+
+"rcnote" => "下面是最近<strong>$2</strong>天内最新的<strong>$1</strong>次改动。",
+"rcnotefrom" => "下面是自<b>$2</b>(最多显示<b>$1</b>)。",
+"rclistfrom" => "显示自$1以来的新更改",
+"rclinks" => "显示最近 $2 天内最新的 $1 次改动。<br />$3",
+"diff" => "差异",
+"hist" => "历史",
+"hide" => "隐藏",
+"show" => "显示",
+"minoreditletter" => "小",
+"newpageletter" => "新",
+
+# Upload
+#
+"upload" => "上载文件",
+"uploadbtn" => "上载文件",
+"reupload" => "重新上载",
+"reuploaddesc" => "返回上载表单。",
+"uploadnologin" => "未登录",
+"uploadnologintext" => "您必须先[[Special:Userlogin|登录]]
+才能上载文件。",
+"uploaderror" => "上载错误",
+"uploadtext" => "'''停止!'''在您上载之前,请先阅读并遵守{{SITENAME}}
+[[Project:Image use policy|图像使用守则]]。
+
+如果您要查看或搜索之前上载的图像,
+请到[[Special:Imagelist|已上载图像列表]].
+所有上载与删除行为都被记录在
+[[Project:上载纪录|上载纪录]]内。
+
+使用下面的表单来上载用在条目内新的图像文件。
+在绝大多数浏览器内,你会看到一个\"浏览...\"按钮,点击它后就会跳出一个打开文件对话框。
+选择一个文件后文件名将出现在按钮旁边的文字框中。
+您也必须点击旁边的复选框确认您所上载的文件并没有违反相关版权法律。
+点击\"上载\" 按钮完成上载程序。
+如果您使用的是较慢的网络连接的话那么这个上载过程会需要一些时间。
+
+我们建议照相图片使用JPEG格式,绘图及其他图标图像使用PNG格式,音像则使用OGG格式。
+请使用具有描述性的语言来命名您的文件以避免混乱。
+要在文章中加入图像,使用以下形式的连接:
+'''<nowiki>[[图像:file.jpg]]</nowiki>'''或者
+'''<nowiki>[[图像:file.png|解释文字]]</nowiki>'''
+或'''<nowiki>[[media:file.ogg]]</nowiki>'''来连接音像文件。
+
+请注意在{{SITENAME}}页面中,其他人可能会为了百科全书的利益而编辑或删除您的上载文件,
+而如果您滥用上载系统,您则有可能被禁止使用上载功能。",
+"uploadlog" => "上载纪录",
+"uploadlogpage" => "上载纪录",
+"uploadlogpagetext" => "以下是最近上载的文件的一览表。
+所有显示的时间都是服务器时间(UTC)。
+<ul>
+</ul>",
+"filename" => "文件名",
+"filedesc" => "简述",
+"copyrightpage" => "{{ns:project}}:版权信息",
+"copyrightpagename" => "{{SITENAME}}版权",
+"uploadedfiles" => "已上载文件",
+"minlength" => "图像名字必须至少有三个字母。",
+"badfilename" => "图像名已被改为\"$1\"。",
+"badfiletype" => "\".$1\"不是所推荐的图像文件格式。",
+"largefile" => "我们建议图像大小不超过100kb。",
+"successfulupload" => "上载成功",
+"fileuploaded" => "文件\"$1\"上载成功。
+请根据连接($2)到图像描述页添加有关文件信息,例如它的来源,在何时由谁创造,
+以及其他任何您知道的关于改图像的信息。",
+"uploadwarning" => "上载警告",
+"savefile" => "保存文件",
+"uploadedimage" => "已上载\"[[$1]]\"",
+
+# Image list
+#
+"imagelist" => "图像列表",
+"imagelisttext" => "以下是按$2排列的$1幅图像列表。",
+"getimagelist" => "正在获取图像列表",
+"ilsubmit" => "搜索",
+"showlast" => "显示按$2排列的最后$1幅图像。",
+"byname" => "名字",
+"bydate" => "日期",
+"bysize" => "大小",
+"imgdelete" => "删",
+"imgdesc" => "述",
+"imglegend" => "说明:(述) = 显示/编辑图像描述页。",
+"imghistory" => "图像历史",
+"revertimg" => "复",
+"deleteimg" => "删",
+"deleteimgcompletely" => "删",
+"imghistlegend" => "egend: (现) = 目前的图像,(删) = 删除旧版本,
+(复) = 恢复到旧版本。
+<br /><i>点击日期查看当天上载的图像</i>.",
+"imagelinks" => "图像链接",
+
+"linkstoimage" => "以下页面连接到本图像:",
+"nolinkstoimage" => "没有页面连接到本图像。",
+
+# Statistics
+#
+"statistics" => "统计",
+"sitestats" => "站点统计",
+"userstats" => "用户统计",
+"sitestatstext" => "数据库中共有 <b>$1</b> 页页面;
+其中包括对话页、关于 {{SITENAME}} 的页面、最少量的\"stub\"页、重定向的页面,
+以及未达到条目质量的页面;除此之外还有 <b>$2</b> 页可能是合乎标准的条目。
+<p>从系统软件升级以来,全站点共有页面浏览 <b>$3</b> 次,
+页面编辑 <b>$4</b> 次,每页平均编辑 <b>$5</b> 次,
+各次编辑后页面的每个版本平均浏览 <b>$6</b> 次。",
+
+# Maintenance Page
+#
+"disambiguations" => "消含糊页",
+"disambiguationspage" => "{{ns:project}}:Links_to_disambiguating_pages",
+"disambiguationstext" => "以下的条目都有到消含糊页的链接,但它们应该是链到适当的题目。<br />一个页面会被视为消含糊页如果它是链自$1.<br />由其它他名字空间来的链接<i>不会</i>在这儿被列出来。",
+"doubleredirects" => "双重重定向",
+"doubleredirectstext" => "<b>请注意:</b> 这列表可能包括不正确的反应。
+这通常表示在那页面第一个#REDIRECT之下还有文字。<br />\n
+每一行都包含到第一跟第二个重定向页的链接,以及第二个重定向页的第一行文字,
+通常显示的都会是\“真正\” 的目标页面,也就是第一个重定向页应该指向的条目。",
+"brokenredirects" => "损坏的重定向页",
+"brokenredirectstext" => "以下的重定向页指向的是不存在的条目。",
+
+
+# Miscellaneous special pages
+#
+"lonelypages" => "孤立页面",
+"unusedimages" => "未使用图像",
+"popularpages" => "热点条目",
+"nviews" => "$1次浏览",
+"wantedpages" => "待撰页面",
+"nlinks" => "$1个链接",
+"allpages" => "所有页面",
+"randompage" => "随机页面",
+"shortpages" => "短条目",
+"longpages" => "长条目",
+"listusers" => "用户列表",
+"specialpages" => "特殊页面",
+"spheading" => "特殊页面",
+"recentchangeslinked" => "链出更改",
+"rclsub" => "(从 \"$1\"链出的页面)",
+"newpages" => "新页面",
+"intl" => "跨语言链接",
+"movethispage" => "移动本页",
+"unusedimagestext" => "<p>请注意其他网站(例如其他语言版本的{{SITENAME}})
+有可能直接链接本图像,所以这里列出的图像有可能依然被使用。",
+"booksources" => "战外书源",
+"booksourcetext" => "以下是链接到销售书籍的网站列表,
+因此有可能拥有您所寻找的图书的进一步资料。
+{{SITENAME}}与这些公司并没有任何商业关系,因此本表不应该
+被看作是一种背书。",
+"alphaindexline" => "$1 到 $2",
+
+# Email this user
+#
+"mailnologin" => "无电邮地址",
+"mailnologintext" => "您必须先[[Special:Userlogin|登录]]
+并在[[Special:Preferences|参数设置]]
+中有一个有效的e-mail地址才可以电邮其他用户。",
+"emailuser" => "E-mail该用户",
+"emailpage" => "E-mail用户",
+"emailpagetext" => "如果该用户已经在他或她的参数设置页中输入了有效的e-mail地址,以下的表格将寄一个信息给该用户。您在您参数设置中所输入的e-mail地址将出现在邮件“发件人”一栏中,这样该用户就可以回复您。",
+"noemailtitle" => "无e-mail地址",
+"noemailtext" => "该用户还没有指定一个有效的e-mail地址,
+或者选择不接受来自其他用户的e-mail。",
+
+"emailfrom" => "发件人",
+"emailto" => "收件人",
+"emailsubject" => "主题",
+"emailmessage" => "信息",
+"emailsend" => "发送",
+"emailsent" => "E-mail已发送",
+"emailsenttext" => "您的e-mail已经发出。",
+
+# Watchlist
+#
+"watchlist" => "监视列表",
+"nowatchlist" => "您的监视列表为空。",
+"watchnologin" => "未登录",
+"watchnologintext" => "您必须先[[Special:Userlogin|登录]]
+才能更改您的监视列表",
+"addedwatch" => "加入到监视列表",
+"addedwatchtext" => "本页(“$1”)已经被加入到您的<a href=\"" .
+ "{{localurle:Special:Watchlist}}\">监视列表</a>中。
+未来有关它或它的对话页的任何修改将会在本页中列出,
+而且还会在<a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">最近更改列表</a>中
+以<b>粗体</b>形式列出。</p>
+
+<p>如果您之后想将该页面从监视列表中删除,点击导航条中的“停止监视”链接。",
+"removedwatch" => "停止监视",
+"removedwatchtext" => "页面“$1”已经从您的监视页面中移除。",
+"watchthispage" => "监视本页",
+"unwatchthispage" => "停止监视",
+"notanarticle" => "不是条目",
+ "watchnochange" => "在显示的时间段内您所监视的页面没有更改。",
+ "watchdetails" => "($1个页面(不含对话页)被监视;
+ 总共$2个页面被编辑;
+ $3...
+ [$4 显示并编辑完整列表].)",
+ "watchmethod-recent" => "检查被监视页面的最近编辑",
+ "watchmethod-list" => "checking watched pages for recent edits",
+ "removechecked" => "将被选页面从监视列表中移除",
+ "watchlistcontains" => "您的监视列表包含$1个页面。",
+ "watcheditlist" => "这里是您所监视的页面的列表。要移除某一页面,只要选择该页面然后点击”移除页面“按钮。",
+ "removingchecked" => "移除页面...",
+ "couldntremove" => "无法移除'$1'...",
+ "iteminvalidname" => "页面'$1'错误,无效命名...",
+ "wlnote" => "以下是最近<b>$2</b>小时内的最后$1次修改。",
+
+# Delete/protect/revert
+#
+"deletepage" => "删除页面",
+"confirm" => "确认",
+"confirmdelete" => "确认删除",
+"deletesub" => "(正在删除“$1”)",
+"confirmdeletetext" => "您即将从数据库中永远删除一个页面或图像以及其历史。
+请确定您要进行此项操作,并且了解其后果,同时您的行为符合[[{{ns:project}}:守则与指导]]。",
+"actioncomplete" => "操作完成",
+"deletedtext" => "“$1”已经被删除。
+最近删除的纪录请参见$2。",
+"deletedarticle" => "已删除“$1”",
+
+"dellogpage" => "删除纪录",
+"dellogpagetext" => "以下是最近删除的纪录列表。
+所有的时间都是使用服务器时间(UTC)。
+<ul>
+</ul>",
+"deletionlog" => "删除纪录",
+"reverted" => "恢复到早期版本",
+"deletecomment" => "删除理由",
+"imagereverted" => "恢复到早期版本操作完成。",
+"rollback" => "Roll back",
+"rollbacklink" => "rollback",
+"cantrollback" => "无法恢复编辑;最后的巩县者是本文的唯一作者。",
+"revertpage" => "恢复到$1的最后一次编辑",
+
+# Undelete
+"undelete" => "恢复被删页面",
+"undeletepage" => "浏览及恢复被删页面",
+"undeletepagetext" => "以下页面已经被删除,但依然在档案中并可以被恢复。
+档案库可能被定时清理。",
+"undeletearticle" => "恢复被删文章",
+"undeleterevisions" => "$1版本存档",
+"undeletehistory" => "如果您恢复了该页面,所有版本都会被恢复到修订历史中。
+如果本页删除后有一个同名的新页面建立,
+被恢复的版本将会称为较新的历史,而新页面的当前版本将无法被自动复原。",
+"undeleterevision" => "删除$1时的版本",
+"undeletebtn" => "恢复!",
+"undeletedarticle" => "已经恢复“$1”",
+
+# Contributions
+#
+"contributions" => "用户贡献",
+"mycontris" => "我的贡献",
+"contribsub" => "为$1",
+"nocontribs" => "没有找到符合特征的更改。",
+"ucnote" => "以下是该用户最近<b><$2/b>天内的最后<b>$1</b>次修改。",
+"uclinks" => "参看最后$1次修改;参看最后$2天。",
+"uctop" => " (顶)" ,
+
+# What links here
+#
+"whatlinkshere" => "链入页面",
+"notargettitle" => "无目标",
+"notargettext" => "您还没有指定一个目标页面或用户以进行此项操作。",
+"linklistsub" => "(链接列表)",
+"linkshere" => "以下页面链接到这里:",
+"nolinkshere" => "没有页面链接到这里。",
+"isredirect" => "重定向页",
+
+# Block/unblock IP
+#
+"blockip" => "查封IP地址",
+"blockiptext" => "用下面的表单来禁止来自某一特定IP地址的修改权限。
+只有在为防止破坏,及符合[[{{ns:project}}:守则与指导]]的情况下才可采取此行动。
+请在下面输入一个具体的理由(例如引述一个被破坏的页面)。",
+"ipaddress" => "IP地址",
+"ipbreason" => "原因",
+"ipbsubmit" => "查封该地址",
+"badipaddress" => "IP地址不正确。",
+"blockipsuccesssub" => "查封成功",
+"blockipsuccesstext" => "IP地址“$1”已经被查封。
+<br />参看[[Special:被封IP地址列表|被封IP地址列表]]以复审查封。",
+"unblockip" => "解除禁封IP地址",
+"unblockiptext" => "用下面的表单来恢复先前被禁封的IP地址的书写权。",
+"ipusubmit" => "解除禁封",
+"ipblocklist" => "被封IP地址列表",
+"blocklistline" => "$1,$2禁封$3 ($4)",
+"blocklink" => "禁封",
+"unblocklink" => "解除禁封",
+"contribslink" => "贡献",
+
+# Developer tools
+#
+"lockdb" => "禁止更改数据库",
+"unlockdb" => "开放更改数据库",
+"lockdbtext" => "锁住数据库将禁止所有用户进行编辑页面、更改参数、编辑监视列表以及其他需要更改数据库的操作。
+请确认您的决定,并且保证您在维护工作结束后会重新开放数据库。",
+"unlockdbtext" => "开放数据库将会恢复所有用户进行编辑页面、修改参数、编辑监视列表以及其他需要更改数据库的操作。
+请确认您的决定。",
+"lockconfirm" => "是的,我确实想要封锁数据库。",
+"unlockconfirm" => "是的,我确实想要开放数据库。",
+"lockbtn" => "数据库上锁",
+"unlockbtn" => "开放数据库",
+"locknoconfirm" => "您并没有勾选确认按钮。",
+"lockdbsuccesssub" => "数据库成功上锁",
+
+"unlockdbsuccesssub" => "数据库开放",
+"lockdbsuccesstext" => "{{SITENAME}}数据库已经上锁。
+<br />请记住在维护完成后重新开放数据库。",
+"unlockdbsuccesstext" => "{{SITENAME}}数据库重新开放。",
+
+# Move page
+#
+"movepage" => "移动页面",
+"movepagetext" => "用下面的表单来重命名一个页面,并将其修订历史同时移动到新页面。
+老的页面将成为新页面的重定向页。
+链接到老页面的链接并不会自动更改;
+请检查双重或损坏重定向链接。
+您应当负责确定所有链接依然会链到指定的页面。
+
+注意如果新页面已经有内容的话,页面将'''不会'''被移动,
+除非新页面无内容或是重定向页,而且没有修订历史。
+这意味着您再必要时可以在移动到新页面后再移回老的页面,
+同时您也无法覆盖现有页面。
+
+<b>警告!</b>
+对一个经常被访问的页面而言这可能是一个重大与唐突的更改;
+请在行动前先了结其所可能带来的后果。",
+"movepagetalktext" => "有关的对话页(如果有的话)将被自动与该页面一起移动,'''除非''':
+*您将页面移动到不同的名字空间(namespaces);
+*新页面已经有一个包含内容的对话页,或者
+*您不勾选下面的复选框。
+
+在这些情况下,您在必要时必须手工移动或合并页面。",
+"movearticle" => "移动页面",
+"movenologin" => "未登录",
+"movenologintext" => "您必须是一名登记用户并且[[Special:Userlogin|登录]]
+后才可移动一个页面。",
+"newtitle" => "新标题",
+"movepagebtn" => "移动页面",
+"pagemovedsub" => "移动成功",
+"pagemovedtext" => "页面“[[$1]]”已经移动到“[[$2]]”。",
+"articleexists" => "该名字的页面已经存在,或者您选择的名字无效。请再选一个名字。",
+"talkexists" => "页面本身移动成功,
+但是由于新标题下已经有对话页存在,所以对话页无法移动。请手工合并两个页面。",
+"movedto" => "移动到",
+"movetalk" => "如果可能的话,请同时移动对话页。",
+"talkpagemoved" => "相应的对话页也已经移动。",
+"talkpagenotmoved" => "相应的对话页<strong>没有</strong>被移动。",
+
+# Math
+
+'mw_math_png' => "永远使用PNG图像", /* "Always render PNG" */
+'mw_math_simple' => "如果是简单的公式使用HTML,否则使用PNG图像", /* "HTML if very simple or else PNG" */
+'mw_math_html' => "如果可以用HTML,否则用PNG图像", /* "HTML if possible or else PNG" */
+'mw_math_source' => "显示为TeX代码(使用文字浏览器时)", /* "Leave it as TeX (for text browsers)" */
+'mw_math_modern' => "推荐为新版浏览器使用", /* "Recommended for modern browsers" */
+
+# some untranslated messages as of 1.4 beta1
+'1movedto2' => "$1移动到$2", //"$1 moved to $2",
+'1movedto2_redir' => "$1重定向到$2", //"$1 moved to $2 over redirect",
+'acct_creation_throttle_hit' => "对不起,您已经注册了$1账号。你不能再注册了。", //"Sorry, you have already created $1 accounts. You can't make any more.",
+'allarticles' => "所有条目", //"All articles",
+'allmessages' => "系统界面", //"All system messages",
+'allmessagesnotsupportedDB' => "系统界面功能处于关闭状态 (wgUseDatabaseMessages)。", //"Special:AllMessages not supported because wgUseDatabaseMessages is off.",
+'allmessagestext' => "这里列出所有可定制的系统界面。", //"This is a list of all system messages available in the MediaWiki: namespace.",
+'allinnamespace' => "所有 $1 名字空间的条目", //"All pages ($1 namespace)",
+'allpagesnext' => "下一页", //"Next",
+'allpagesprev' => "上一页", //"Previous",
+'allpagessubmit' => "提交", //"Go",
+'ancientpages' => "老条目", //"Oldest pages",
+'and' => "和", //"and",
+'anontalk' => "该IP的对话页", //"Talk for this IP",
+'anonymous' => "匿名用户", //"Anonymous user(s) of 1.4",
+'article' => "条目", //"Content page",
+'autoblocker' => "你的IP和被封了的 \"$1\" 是一样的。封锁原因: \"$2\".",//"Autoblocked because you share an IP address with \"$1\". Reason \"$2\".",
+'blocklogentry' => "封锁 $1, $2",//"blocked \"$1\" with an expiry time of $2",
+'blocklogpage' => "封锁记录", //"Block_log",
+'categoriespagetext' => "以下列出所有的页面分类。", //"The following categories exists in the wiki.",
+'categoryarticlecount' => "该类页面共有 $1 条目", //There are $1 articles in this category.",
+'clearyourcache' => "'''注意:''' 保存设置后,要清掉浏览器的缓存才能生效:'''Mozilla:''' ''Ctrl-Shift-R'', '''Internet Explorer:''' ''Ctrl-F5'', '''Safari:''' ''Cmd-Shift-R'', '''Konqueror:''' ''F5''。",
+'edit' => "编辑", //"Edit",
+'navigation' => "导航", //"Navigation",
+'nstab-category' => "分类", //"Category",
+'nstab-help' => "帮助",//"Help",
+'nstab-image' => "图像",//"Image",
+'nstab-main' => "条目", //"Article",
+'nstab-mediawiki' => "界面",//"Message",
+'nstab-special' => "特殊",//"Special",
+'nstab-template' => "模板", //"Template",
+'nstab-user' => "用户页面", //"User page",
+'nstab-project' => "关于", //"About",
+'portal' => "社区",//"Community portal",
+'prefs-help-realname' => "*<strong>真实姓名</strong>(可选):用以对您的贡献署名。<br />",
+'prefs-help-email' => "*<strong>点子邮件</strong>(可选):让他人通过网站在不知道您的电子邮件地址的情况下通过电子邮件与您联络,以及通过电子邮件取得遗忘的密码。", /*"* <strong>Real name</strong> (optional): if you choose to provide it this will be used for giving you attribution for your work.<br />
+* <strong>Email</strong> (optional): Enables people to contact you through the website without you having to reveal your
+email address to them, and it can be used to send you a new password if you forget it.", */
+'prefs-misc' => "杂项", //"Misc settings",
+'prefs-personal' => "用户数据",//"User data",
+'prefs-rc' => "最近更新", //"Recent changes and stub display",
+'skin' => "皮肤", //"Skin",
+'talk' => "讨论",//"Discussion",
+'timezonelegend' => "时区", //"Time zone",
+'toolbox' => "工具",//"Toolbox",
+'watch' => "监视",//"Watch",
+'yourlanguage' => "界面语言", //"Your language"
+'yourrealname' => "真实姓名*", //"Your real name"
+'yourvariant' => "中文字体", //"language variant"
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => '大陆简体',
+'variantname-zh-tw' => '台湾繁体',
+'variantname-zh-hk' => '香港繁体',
+'variantname-zh-sg' => '新加坡简体',
+'variantname-zh' => '不转换',
+
+);
+
+
+
+?>
diff --git a/languages/messages/MessagesZh_hk.php b/languages/messages/MessagesZh_hk.php
new file mode 100644
index 000000000000..164a1985d5db
--- /dev/null
+++ b/languages/messages/MessagesZh_hk.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+# Inherit everything for now
+$fallback = 'zh-tw';
+
+?>
diff --git a/languages/messages/MessagesZh_sg.php b/languages/messages/MessagesZh_sg.php
new file mode 100644
index 000000000000..fc8282d6c9ff
--- /dev/null
+++ b/languages/messages/MessagesZh_sg.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+# Inherit everything for now
+$fallback = 'zh-cn';
+
+?>
diff --git a/languages/messages/MessagesZh_tw.php b/languages/messages/MessagesZh_tw.php
new file mode 100644
index 000000000000..74fe1f8dee30
--- /dev/null
+++ b/languages/messages/MessagesZh_tw.php
@@ -0,0 +1,845 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$fallback = 'zh-cn';
+
+$namespaceNames = array(
+ NS_MEDIA => "媒體",
+ NS_SPECIAL => "特殊",
+ NS_MAIN => "",
+ NS_TALK => "討論",
+ NS_USER => "用戶",
+ NS_USER_TALK => "用戶討論",
+ # NS_PROJECT set by $wgMetaNamespace
+ NS_PROJECT_TALK => '$1討論',
+ NS_IMAGE => "圖像",
+ NS_IMAGE_TALK => "圖像討論",
+ NS_MEDIAWIKI => "媒體維基",
+ NS_MEDIAWIKI_TALK => "媒體維基討論",
+ NS_TEMPLATE => "樣板",
+ NS_TEMPLATE_TALK => "樣板討論",
+ NS_HELP => "幫助",
+ NS_HELP_TALK => "幫助討論",
+ NS_CATEGORY => "分類",
+ NS_CATEGORY_TALK => "分類討論"
+);
+
+$namespaceAliases = array(
+ "對話" => NS_TALK,
+ "用戶對話" => NS_USER_TALK,
+ "維基百科對話" => NS_PROJECT_TALK,
+ "圖像對話" => NS_IMAGE_TALK,
+);
+
+$quickbarSettings = array(
+ "無", /* "None" */
+ "左側固定", /* "Fixed left" */
+ "右側固定", /* "Fixed right" */
+ "左側漂移" /* "Floating left" */
+);
+
+$skinNames = array(
+ "標準",/* "Standard" */
+ "懷舊",/* "Nostalgia" */
+ "科隆香水藍" /* "Cologne Blue" */
+);
+
+$bookstoreList = array(
+ "博客來書店" => "http://www.books.com.tw/exep/openfind_book_keyword.php?cat1=4&key1=$1",
+ "三民書店" => "http://www.sanmin.com.tw/page-qsearch.asp?ct=search_isbn&qu=$1",
+ "天下書店" => "http://www.cwbook.com.tw/cw/TS.jsp?schType=product.isbn&schStr=$1",
+ "新絲書店" => "http://www.silkbook.com/function/Search_List_Book.asp?item=5&text=$1"
+);
+
+
+$messages = array(
+
+/* User toggles */
+ "tog-underline" => "下劃鏈結", /* "Underline links", */
+ "tog-highlightbroken" => "毀壞的鏈結格式<a href=\"\" class=\"new\">像這樣</a> (或者像這個<a href=\"\" class=\"internal\">?</a>)", /* "Format broken links <a href=\"\" class=\"new\">like this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).", */
+ "tog-justify" => "段落對齊", /* "Justify paragraphs", */
+ "tog-hideminor" => "最近更改中隱藏細微修改", /* "Hide minor edits in recent changes", */
+ "tog-usenewrc" => "最近更改增強(只適用部分流覽器)", /* "Enhanced recent changes (not for all browsers)", */
+ "tog-numberheadings" => "標題自動編號",
+ "tog-showtoolbar" => "顯示編輯工具欄",/* "Auto-number headings", */
+ "tog-editondblclick" => "雙擊頁面編輯(JavaScript)",
+ "tog-editsection"=>"允許通過點擊[編輯]鏈結編輯段落",
+ "tog-editsectiononrightclick"=>"允許右擊標題編輯段落(JavaScript)",
+ "tog-showtoc"=>"顯示目錄<br />(針對一頁超過3個標題的文章)",
+ "tog-rememberpassword" => "下次登陸記住密碼",/* "Remember password across sessions", */
+ "tog-editwidth" => "編輯欄位寬度",/* "Edit box has full width", */
+ "tog-editondblclick" => "雙擊編輯頁面(Javascript)",/* "Edit pages on double click (JavaScript)", */
+ "tog-watchdefault" => "監視新的以及更改過的文章",/* "Watch new and modified articles", */
+ "tog-minordefault" => "細微編輯為默認設置",/* "Mark all edits minor by default", */
+ "tog-previewontop" => "在編輯框上方顯示預覽", /* "Show preview before edit box and not after it" */
+
+
+
+# Bits of text used by many pages:
+#
+"categories" => "頁面分類",
+"pagecategories" => "頁面分類",
+"category_header" => "類別”$1“中的條目",
+"subcategories" => "子分類",
+"mainpage" => "首頁",
+"about" => "關於",
+"aboutpage" => "{{ns:project}}:關於",
+"help" => "幫助",
+"helppage" => "{{ns:project}}:幫助",
+"bugreports" => "錯誤報告",
+"bugreportspage" => "{{ns:project}}:錯誤報告",
+"faq" => "常見問題解答",
+"faqpage" => "{{ns:project}}:常見問題解答",
+"edithelp" => "編輯幫助",
+"edithelppage" => "{{ns:project}}:如何編輯頁面",
+"cancel" => "取消",
+"qbfind" => "尋找",
+"qbbrowse" => "瀏覽",
+"qbedit" => "編輯",
+"qbpageoptions" => "頁面選項",
+"qbpageinfo" => "頁面信息",
+"qbmyoptions" => "我的選項",
+"mypage" => "我的頁面",
+"mytalk" => "我的對話頁",
+"currentevents" => "新聞動態",
+"errorpagetitle" => "錯誤",
+"returnto" => "返回到$1.",
+"whatlinkshere" => "鏈入頁面",
+"help" => "幫助",
+"search" => "搜索",
+"searchbutton" => "搜索",
+"go" => "進入",
+'searcharticle' => "進入",
+"history" => "較早版本",
+"printableversion" => "可列印版",
+"editthispage" => "編輯本頁",
+"deletethispage" => "刪除本頁",
+"protectthispage" => "保護本頁",
+"unprotectthispage" => "解除保護",
+"newpage" => "新頁面",
+"talkpage" => "討論本頁",
+ "postcomment" => "發表評論",
+"articlepage" => "查看文章",
+"userpage" => "查看用戶頁",
+"projectpage" => "查看元維基頁",
+"imagepage" => "查看圖像頁面",
+"viewtalkpage" => "查看討論",
+"otherlanguages" => "其它語言",
+"redirectedfrom" => "(重定向自$1)",
+"lastmodifiedat" => "最後更改$2, $1.",
+"viewcount" => "本頁面已經被瀏覽$1次。",
+"protectedpage" => "被保護頁",
+"nbytes" => "$1字節",
+"ok" => "好",
+"retrievedfrom" => "取自\"$1\"",
+"newmessageslink" => "新信息",
+"editsection"=>"編輯",
+"editold"=>"編輯",
+"toc" => "目錄",
+"showtoc" => "顯示",
+ "hidetoc" => "隱藏",
+
+# weekdays, month names
+'sunday' => "星期日",
+'monday' => "星期一",
+'tuesday' => "星期二",
+'wednesday' => "星期三",
+'thursday' => "星期四",
+'friday' => "星期五",
+'saturday' => "星期六",
+
+'january' => "一月",
+'february' => "二月",
+'march' => "三月",
+'april' => "四月",
+'may_long' => "五月",
+'june' => "六月",
+'july' => "七月",
+'august' => "八月",
+'september' => "九月",
+'october' => "十月",
+'november' => "十一月",
+'december' => "十二月",
+
+'jan' => "一月",
+'feb' => "二月",
+'mar' => "三月",
+'apr' => "四月",
+'may' => "五月",
+'jun' => "六月",
+'jul' => "七月",
+'aug' => "八月",
+'sep' => "九月",
+'oct' => "十月",
+'nov' => "十一月",
+'dec' => "十二月",
+
+# Main script and global functions
+#
+"nosuchaction" => "沒有這個命令",
+"nosuchactiontext" => "URL請求的命令無法被{{SITENAME}}軟件識別。",
+"nosuchspecialpage" => "沒有這個特殊頁。",
+
+"nospecialpagetext" => "您請求的頁面無法被{{SITENAME}}軟件識別。",
+
+# General errors
+#
+"error" => "錯誤",
+"databaseerror" => "數據庫錯誤",
+"dberrortext" => "數據庫指令語法錯誤。
+這可能是由於非法搜索指令所引起的(見$5),
+也可能是由於軟件自身的錯誤所引起。
+最後一次數據庫指令是:
+<blockquote><tt>$1</tt></blockquote>
+來自於函數 \"<tt>$2</tt>\"。
+MySQL返回錯誤 \"<tt>$3: $4</tt>\"。",
+"noconnect" => "無法在$1上連接數據庫",
+"nodb" => "無法選擇數據庫 $1",
+"readonly" => "數據庫禁止訪問",
+"enterlockreason" => "請輸入禁止訪問原因, 包括估計重新開放的時間",
+"readonlytext" => "{{SITENAME}}數據庫目前禁止輸入新內容及更改,
+這很可能是由於數據庫正在維修,之後即可恢復。
+管理員有如下解釋:
+<p>$1</p>",
+"missingarticle" => "數據庫找不到文字\"$1\"。
+
+<p>通常這是由於修訂歷史頁上過時的鏈接到已經被刪除的頁面所導致的。</p>
+
+<p>如果情況不是這樣,您可能找到了軟件內的一個臭蟲。
+請記錄下URL地址,並向管理員報告。</p>",
+"internalerror" => "內部錯誤",
+"filecopyerror" => "無法複製文件\"$1\"到\"$2\"。",
+"filerenameerror" => "無法重命名文件\"$1\"到\"$2\"。",
+"filedeleteerror" => "無法刪除文件\"$1\"。",
+"filenotfound" => "找不到文件\"$1\"。",
+"unexpected" => "不正常值:\"$1\"=\"$2\"。",
+"formerror" => "錯誤:無法提交表單",
+"badarticleerror" => "無法在本頁上進行此項操作。",
+"cannotdelete" => "無法刪除選定的頁面或圖像(它可能已經被其他人刪除了)。",
+"badtitle" => "錯誤的標題",
+"badtitletext" => "所請求頁面的標題是無效的、不存在,跨語言或跨維基鏈接的標題錯誤。",
+"perfdisabled" => "抱歉!由於此項操作有可能造成數據庫癱瘓,目前暫時無法使用。",
+"perfdisabledsub" => "這裏是自$1的複製版本:",
+
+# 登錄與登出
+#
+"logouttitle" => "用戶退出",
+"logouttext" => "您現在已經退出。
+您可以繼續以匿名方式使用{{SITENAME}},或再次以相同或不同用戶身份登錄。",
+
+"welcomecreation" => "<h2>歡迎,$1!</h2><p>您的帳號已經建立,不要忘記設置{{SITENAME}}個人參數。</p>",
+
+"loginpagetitle" => "用戶登錄",
+"yourname" => "您的用戶名",
+"yourpassword" => "您的密碼",
+"yourpasswordagain" => "再次輸入密碼",
+"remembermypassword" => "下次登錄記住密碼。",
+"loginproblem" => "<b>登錄有問題。</b><br />再試一次!",
+"alreadyloggedin" => "<strong>用戶$1,您已經登錄了!</strong><br />",
+
+"login" => "登錄",
+"userlogin" => "用戶登錄",
+"logout" => "退出",
+"userlogout" => "用戶退出",
+"createaccount" => "創建新帳號",
+ "createaccountmail" => "通過eMail",
+"badretype" => "你所輸入的密碼並不相同。",
+"userexists" => "您所輸入的用戶名已有人使用。請另選一個。",
+"youremail" => "您的電子郵件*",
+"yournick" => "綽號(簽名時用)",
+"loginerror" => "登錄錯誤",
+"noname" => "你沒有輸入一個有效的用戶名。",
+"loginsuccesstitle" => "登錄成功",
+"loginsuccess" => "你現在以 \"$1\"的身份登錄{{SITENAME}}。",
+"nosuchuser" => "找不到用戶 \"$1\"。
+檢查您的拼寫,或者用下面的表格建立一個新帳號。",
+"wrongpassword" => "您輸入的密碼錯誤,請再試一次。",
+"mailmypassword" => "將新密碼寄給我",
+"passwordremindertitle" => "{{SITENAME}}密碼提醒",
+"passwordremindertext" => "有人(可能是您,來自網址$1)要求我們將新的{{SITENAME}}登錄密碼寄給你。
+用戶 \"$2\" 的密碼現在是 \"$3\"。
+請立即登錄並更改密碼。",
+"noemail" => "用戶\"$1\"沒有登記電子郵件地址。",
+"passwordsent" => "用戶\"$1\"的新密碼已經寄往所登記的電子郵件地址。
+請在收到後再登錄。",
+
+# 編輯
+#
+"summary" => "簡述",
+"subject" => "主題",
+"minoredit" => "這是一個小修改",
+"watchthis" => "監視本頁",
+"savearticle" => "保存本頁",
+"preview" => "預覽",
+"showpreview" => "顯示預覽",
+"blockedtitle" => "用戶被封",
+"blockedtext" => "您的用戶名或網址已被$1封。
+理由是:<br />'''$2'''<p>您可以與$1向其他任何[[{{ns:project}}:管理員|管理員]]詢問。</p>",
+ "whitelistedittitle" => "登錄後才可編輯",
+ "whitelistedittext" => "您必須先[[特殊:登錄]]才可編輯頁面。",
+ "whitelistreadtitle" => "登錄後才可閱讀",
+ "whitelistreadtext" => "您必須先[[特殊:登錄]]才可閱讀頁面。",
+ "whitelistacctitle" => "您被禁止建立帳號",
+ "whitelistacctext" => "在本維基中建立帳號您必須先[[特殊:登錄]]並擁有相關權限。",
+ "accmailtitle" => "密碼寄出",
+ "accmailtext" => "'$1'的密碼已經寄到$2。",
+"newarticle" => "(新)",
+"newarticletext" =>
+"您從一個鏈接進入了一個並不存在的頁面。
+要創建該頁面,請在下面的編輯框中輸入內容(詳情參見[[{{ns:project}}:幫助|幫助頁面]])。
+如果您不小心來到本頁面,直接點擊您瀏覽器中的“返回”按鈕。",
+
+"anontalkpagetext" => "---- ''這是一個還未建立帳號的匿名用戶的對話頁。我們因此只能用[[網址]]來與他/她聯絡。該網址可能由幾名用戶共享。如果您是一名匿名用戶並認為本頁上的評語與您無關,請[[特殊:登錄|創建新帳號或登錄]]以避免在未來於其他匿名用戶混淆。''",
+"noarticletext" => "(本頁目前沒有內容)",
+"updated" => "(已更新)",
+"note" => "<strong>注意:</strong>",
+"previewnote" => "請記住這只是預覽,內容還未保存!",
+"previewconflict" => "這個預覽顯示了上面文字編輯區中的內容。它將在你選擇保存後出現。",
+"editing" => "正在編輯$1",
+'editinguser' => "正在編輯$1",
+"editingsection" => "正在編輯$1 (段落)",
+"editingcomment" => "正在編輯$1 (評論)",
+"editconflict" => "編輯衝突:$1",
+"explainconflict" => "有人在你開始編輯後更改了頁面。
+上面的文字框內顯示的是目前本頁的內容。
+你所做的修改顯示在下面的文字框中。
+你應當將你所做的修改加入現有的內容中。
+<b>只有</b>在上面文字框中的內容會在你點擊\"保存頁面\"後被保存。<br />",
+"yourtext" => "您的文字",
+"storedversion" => "已保存版本",
+"editingold" => "<strong>警告:你正在編輯的是本頁的舊版本。
+如果你保存它的話,在本版本之後的任何修改都會丟失。</strong>",
+"yourdiff" => "差別",
+/*"copyrightwarning" => "請注意對W{{SITENAME}}的任何貢獻都將被認為是在GNU自由文檔協議證書下發佈。
+(細節請見$1).
+如果您不希望您的文字被任意修改和再散佈,請不要提交。<br />
+您同時也向我們保證你所提交的內容是你自己所作,或得自一個不受版權保護或相似自由的來源。
+<strong>不要在未獲授權的情況下發表!</strong>",*/
+
+"longpagewarning" => "<strong>警告:本頁長度達$1千位;一些瀏覽器將無法編輯長過三十二千位的文章。請考慮將本文切割成幾個小段落。</strong>",
+
+"readonlywarning" => "<strong>警告:數據庫被鎖以進行維護,所以您目前將無法保存您的修改。您或許希望先將本斷文字複製並保存到文本文件,然後等一會兒再修改。</strong>",
+"protectedpagewarning" => "<strong>警告:本頁已經被保護,只有擁有管理員權限的用戶才可修改。請確認您遵守
+[[Project:Protected_page_guidelines|保護頁面守則]].</strong>",
+
+# History pages
+#
+"revhistory" => "修訂歷史",
+"nohistory" => "沒有本頁的修訂記錄。",
+"revnotfound" => "沒有找到修訂記錄",
+"revnotfoundtext" => "您請求的更早版本的修訂記錄沒有找到。
+請檢查您請求本頁面用的URL是否正確。",
+"loadhist" => "載入頁面修訂歷史",
+"currentrev" => "當前修訂版本",
+"revisionasof" => "$1的修訂版本",
+"cur" => "當前",
+"next" => "後繼",
+"last" => "先前",
+"orig" => "初始",
+"histlegend" => "說明:(當前)指與當前修訂版本比較;(先前)指與前一個修訂版本比較,小 指細微修改。",
+
+# Diffs
+#
+"difference" => "(修訂版本間差異)",
+"loadingrev" => "載入修訂版本比較",
+"lineno" => "第$1行:",
+"editcurrent" => "編輯本頁的當前修訂版本",
+
+# Search results
+#
+"searchresults" => "搜索結果",
+"searchresulttext" => "有關搜索{{SITENAME}}的更多詳情,參見$1。",
+"searchsubtitle" => "查詢\"[[:$1]]\"",
+"searchsubtitleinvalid" => "查詢\"$1\"",
+"badquery" => "搜索查詢不正確",
+"badquerytext" => "我們無法處理您的查詢。
+這可能是由於您試圖搜索一個短於3個字母的外文單詞,
+或者您錯誤地輸入了搜索項,例如\"汽車和和火車\"。
+請再嘗試一個新的搜索項。",
+"matchtotals" => "搜索項\"$1\"與$2條文章的題目相符,和$3條文章相符。",
+
+"noexactmatch" => "沒有文章與搜索項完全匹配,請嘗試完整文字搜索。",
+"titlematches" => "文章題目相符",
+"notitlematches" => "沒有找到匹配文章題目",
+"textmatches" => "文章內容相符",
+"notextmatches" => "沒有文章內容匹配",
+
+"prevn" => "先前$1",
+"nextn" => "之後$1",
+"viewprevnext" => "查看 ($1) ($2) ($3).",
+"showingresults" => "下面顯示<b>$1</b>條結果,從第<b>$2</b>條開始",
+"nonefound" => "<strong>注意:</strong>失敗的搜索往往是由於試圖搜索諸如“的”或“和”之類的常見字所引起。",
+"powersearch" => "搜索",
+"powersearchtext" => "
+搜索名字空間:<br />$1<br />$2列出重定向頁面;搜索$3 $9",
+
+"searchdisabled" => "<p>{{SITENAME}}內部搜索功能由於高峰時段服務器超載而停止使用。
+您可以暫時通過
+<a href=\"http://google.com.tw/\">google</a>搜索{{SITENAME}}。
+謝謝您的耐心。</p>",
+
+# Preferences page
+#
+"preferences" => "參數設置",
+"prefsnologin" => "還未登錄",
+"prefsnologintext" => "您必須先[[Special:Userlogin|登錄]]才能設置個人參數。",
+"prefsreset" => "參數重新設置。",
+"qbsettings" => "快速導航條設置",
+"changepassword" => "更改密碼",
+"skin" => "皮膚",
+"math" => "數學顯示",
+"math_failure" => "無法解析",
+"math_unknown_error" => "未知錯誤",
+"math_unknown_function" => "未知函數",
+"math_lexing_error" => "句法錯誤",
+"math_syntax_error" => "語法錯誤",
+"saveprefs" => "保存參數設置",
+"resetprefs" => "重設參數",
+"oldpassword" => "舊密碼",
+"newpassword" => "新密碼",
+"retypenew" => "重複新密碼",
+"textboxsize" => "文字框尺寸",
+"rows" => "行",
+"columns" => "列",
+"searchresultshead" => "搜索結果設定",
+"resultsperpage" => "每頁顯示鏈接數",
+"contextlines" => "每鏈接行數",
+"contextchars" => "每行字數",
+"stubthreshold" => "短條目顯示基本限制",
+"recentchangescount" => "最近更改頁行數",
+"savedprefs" => "您的個人參數設置已經保存。",
+"timezonetext" => "輸入當地時間與服務器時間的時差。",
+"localtime" => "當地時間",
+"timezoneoffset" => "時差",
+
+# Recent changes
+#
+"changes" => "更改",
+"recentchanges" => "最近更改",
+"recentchangestext" => "本頁跟蹤{{SITENAME}}內最新的更改。
+[[{{ns:project}}:歡迎,新來者|歡迎,新來者]]!
+請參見這些頁面:[[{{ns:project}}:常見問題解答|{{SITENAME}}常見問題解答]]、
+[[{{ns:project}}:守則與指導|{{SITENAME}}守則]]
+(特別是[[{{ns:project}}:命名常規|命名常規]]、
+[[{{ns:project}}:中性的觀點|中立觀點]])
+和[[{{ns:project}}:最常見失禮行為|最常見失禮行為]]。
+
+如果您希望{{SITENAME}}成功,那麼請您不要增加受其它[[{{ns:project}}:版權信息|版權]]
+限制的材料,這一點將非常重要。相關的法律責任會傷害本項工程,所以請不要這樣做。
+此外請參見",
+
+"rcnote" => "下面是最近<strong>$2</strong>天內最新的<strong>$1</strong>次改動。",
+"rcnotefrom" => "下面是自<b>$2</b>(最多顯示<b>$1</b>)。",
+"rclistfrom" => "顯示自$1以來的新更改",
+"rclinks" => "顯示最近 $2 天內最新的 $1 次改動。<br />$3",
+"diff" => "差異",
+"hist" => "歷史",
+"hide" => "隱藏",
+"show" => "顯示",
+"minoreditletter" => "小",
+"newpageletter" => "新",
+
+# Upload
+#
+"upload" => "上載文件",
+"uploadbtn" => "上載文件",
+"reupload" => "重新上載",
+"reuploaddesc" => "返回上載表單。",
+"uploadnologin" => "未登錄",
+"uploadnologintext" => "您必須先[[Special:Userlogin|登錄]]
+才能上載文件。",
+"uploaderror" => "上載錯誤",
+"uploadtext" => "<strong>停止!</strong>在您上載之前,請先閱讀並遵守{{SITENAME}}<a href=\"" .
+"{{localurle:Project:Image use policy}}\">圖像使用守則</a>。
+<p>如果您要查看或搜索之前上載的圖像,
+請到<a href=\"" . "{{localurle:Special:Imagelist}}" .
+"\">已上載圖像列表</a>.
+所有上載與刪除行為都被記錄在<a href=\"" .
+"{{localurle:Project:Upload image}}\">上載紀錄</a>內。</p>
+<p>使用下面的表單來上載用在條目內新的圖像文件。
+在絕大多數瀏覽器內,你會看到一個\"瀏覽...\"按鈕,點擊它後就會跳出一個打開文件對話框。
+選擇一個文件後文件名將出現在按鈕旁邊的文字框中。
+您也必須點擊旁邊的複選框確認您所上載的文件並沒有違反相關版權法律。
+點擊\"上載\" 按鈕完成上載程序。
+如果您使用的是較慢的網絡連接的話那麼這個上載過程會需要一些時間。</p>
+<p>我們建議照相圖片使用JPEG格式,繪圖及其他圖標圖像使用PNG格式,音像則使用OGG格式。
+請使用具有描述性的語言來命名您的文件以避免混亂。
+要在文章中加入圖像,使用以下形式的連接:
+<b>[[圖像:檔案.jpg]]</b>或者<b>[[圖像:檔案.png|解釋文字]]</b>
+或<b>[[媒體:檔案.ogg]]</b>來連接音像文件。</p>
+<p>請注意在{{SITENAME}}頁面中,其他人可能會為了百科全書的利益而編輯或刪除您的上載文件,
+而如果您濫用上載系統,您則有可能被禁止使用上載功能。</p>",
+"uploadlog" => "上載紀錄",
+"uploadlogpage" => "上載紀錄",
+"uploadlogpagetext" => "以下是最近上載的文件的一覽表。
+所有顯示的時間都是服務器時間。
+<ul>
+</ul>",
+"filename" => "文件名",
+"filedesc" => "簡述",
+"copyrightpage" => "{{ns:project}}:版權信息",
+"copyrightpagename" => "{{SITENAME}}版權",
+"uploadedfiles" => "已上載文件",
+"minlength" => "圖像名字必須至少有三個字母。",
+"badfilename" => "圖像名已被改為\"$1\"。",
+"badfiletype" => "\".$1\"不是所推薦的圖像文件格式。",
+"largefile" => "我們建議圖像大小不超過百千位。",
+"successfulupload" => "上載成功",
+"fileuploaded" => "文件\"$1\"上載成功。
+請根據連接($2)到圖像描述頁添加有關文件信息,例如它的來源,在何時由誰創造,
+以及其他任何您知道的關於改圖像的信息。",
+"uploadwarning" => "上載警告",
+"savefile" => "保存文件",
+"uploadedimage" => "已上載\"[[$1]]\"",
+
+# Image list
+#
+"imagelist" => "圖像列表",
+"imagelisttext" => "以下是按$2排列的$1幅圖像列表。",
+"getimagelist" => "正在獲取圖像列表",
+"ilsubmit" => "搜索",
+"showlast" => "顯示按$2排列的最後$1幅圖像。",
+"byname" => "名字",
+"bydate" => "日期",
+"bysize" => "大小",
+"imgdelete" => "刪",
+"imgdesc" => "述",
+"imglegend" => "說明:(述) = 顯示/編輯圖像描述頁。",
+"imghistory" => "圖像歷史",
+"revertimg" => "回",
+"deleteimg" => "刪",
+"imghistlegend" => "題跋: (現) = 目前的圖像,(刪) = 刪除舊版本,
+(複) = 恢復到舊版本。
+<br /><i>點擊日期查看當天上載的圖像</i>.",
+"imagelinks" => "圖像鏈接",
+
+"linkstoimage" => "以下頁面連接到本圖像:",
+"nolinkstoimage" => "沒有頁面連接到本圖像。",
+
+# Statistics
+#
+"statistics" => "統計",
+"sitestats" => "站點統計",
+"userstats" => "用戶統計",
+"sitestatstext" => "數據庫中共有 <b>$1</b> 頁頁面;
+其中包括對話頁、關於{{SITENAME}}的頁面、最少量的\"stub\"頁、重定向的頁面,
+以及未達到條目質量的頁面;除此之外還有 <b>$2</b> 頁可能是合乎標準的條目。
+<p>從系統軟件升級以來,全站點共有頁面瀏覽 <b>$3</b> 次,
+頁面編輯 <b>$4</b> 次,每頁平均編輯 <b>$5</b> 次,
+各次編輯後頁面的每個版本平均瀏覽 <b>$6</b> 次。</p>",
+
+# Maintenance Page
+#
+"disambiguations" => "消含糊頁",
+"disambiguationspage" => "{{ns:project}}:鏈接到消歧義的頁面",
+"disambiguationstext" => "以下的條目都有到消含糊頁的鏈接,但它們應該是鏈到適當的題目。<br />一個頁面會被視為消含糊頁如果它是鏈自$1.<br />由其它他名字空間來的鏈接<i>不會</i>在這兒被列出來。",
+"doubleredirects" => "雙重重定向",
+"doubleredirectstext" => "<b>請注意:</b> 這列表可能包括不正確的反應。
+這通常表示在那頁面第一個#REDIRECT之下還有文字。<br />\n
+每一行都包含到第一跟第二個重定向頁的鏈接,以及第二個重定向頁的第一行文字,
+通常顯示的都會是\“真正\” 的目標頁面,也就是第一個重定向頁應該指向的條目。",
+"brokenredirects" => "損壞的重定向頁",
+"brokenredirectstext" => "以下的重定向頁指向的是不存在的條目。",
+
+# Miscellaneous special pages
+#
+"lonelypages" => "孤立頁面",
+"unusedimages" => "未使用圖像",
+"popularpages" => "熱點條目",
+"nviews" => "$1次瀏覽",
+"wantedpages" => "待撰頁面",
+"nlinks" => "$1個鏈接",
+"allpages" => "所有頁面",
+"randompage" => "隨機頁面",
+"shortpages" => "短條目",
+"longpages" => "長條目",
+"listusers" => "用戶列表",
+"specialpages" => "特殊頁面",
+"spheading" => "特殊頁面",
+"recentchangeslinked" => "鏈出更改",
+"rclsub" => "(從 \"$1\"鏈出的頁面)",
+"newpages" => "新頁面",
+"intl" => "跨語言鏈接",
+"movethispage" => "移動本頁",
+"unusedimagestext" => "<p>請注意其他網站(例如其他語言版本的{{SITENAME}})
+有可能直接鏈接本圖像,所以這裏列出的圖像有可能依然被使用。</p>",
+"booksources" => "戰外書源",
+"booksourcetext" => "以下是鏈接到銷售書籍的網站列表,
+因此有可能擁有您所尋找的圖書的進一步資料。
+{{SITENAME}}與這些公司並沒有任何商業關係,因此本表不應該
+被看作是一種背書。",
+"alphaindexline" => "$1 到 $2",
+
+# Email this user
+#
+"mailnologin" => "無電郵地址",
+"mailnologintext" => "您必須先[[Special:Userlogin|登錄]]
+並在[[Special:Preferences|參數設置]]
+中有一個有效的電子郵件地址才可以電郵其他用戶。",
+"emailuser" => "電子郵件該用戶",
+"emailpage" => "電子郵件用戶",
+"emailpagetext" => "如果該用戶已經在他或她的參數設置頁中輸入了有效的電子郵件地址,以下的表格將寄一個信息給該用戶。您在您參數設置中所輸入的電子郵件地址將出現在郵件“發件人”一欄中,這樣該用戶就可以回復您。",
+"noemailtitle" => "無電子郵件地址",
+"noemailtext" => "該用戶還沒有指定一個有效的電子郵件地址,
+或者選擇不接受來自其他用戶的電子郵件。",
+
+"emailfrom" => "發件人",
+"emailto" => "收件人",
+"emailsubject" => "主題",
+"emailmessage" => "信息",
+"emailsend" => "發送",
+"emailsent" => "電子郵件已發送",
+"emailsenttext" => "您的電子郵件已經發出。",
+
+# Watchlist
+#
+"watchlist" => "監視列表",
+"nowatchlist" => "您的監視列表為空。",
+"watchnologin" => "未登錄",
+"watchnologintext" => "您必須先[[Special:Userlogin|登錄]]
+才能更改您的監視列表",
+"addedwatch" => "加入到監視列表",
+"addedwatchtext" => "<p>本頁(“$1”)已經被加入到您的<a href=\"" .
+ "{{localurle:Special:Watchlist}}\">監視列表</a>中。
+未來有關它或它的對話頁的任何修改將會在本頁中列出,
+而且還會在<a href=\"" .
+ "{{localurle:Special:Recentchanges}}\">最近更改列表</a>中
+以<b>粗體</b>形式列出。</p>
+
+<p>如果您之後想將該頁面從監視列表中刪除,點擊導航條中的“停止監視”鏈接。</p>",
+"removedwatch" => "停止監視",
+"removedwatchtext" => "頁面“$1”已經從您的監視頁面中移除。",
+"watchthispage" => "監視本頁",
+"unwatchthispage" => "停止監視",
+"notanarticle" => "不是條目",
+ "watchnochange" => "在顯示的時間段內您所監視的頁面沒有更改。",
+ "watchdetails" => "($1個頁面(不含對話頁)被監視;
+ 總共$2個頁面被編輯;
+ $3...
+ [$4 顯示並編輯完整列表].)",
+ "watchmethod-recent" => "檢查被監視頁面的最近編輯",
+ "watchmethod-list" => "checking watched pages for recent edits",
+ "removechecked" => "將被選頁面從監視列表中移除",
+ "watchlistcontains" => "您的監視列表包含$1個頁面。",
+ "watcheditlist" => "這裏是您所監視的頁面的列表。要移除某一頁面,只要選擇該頁面然後點擊”移除頁面“按鈕。",
+ "removingchecked" => "移除頁面...",
+ "couldntremove" => "無法移除'$1'...",
+ "iteminvalidname" => "頁面'$1'錯誤,無效命名...",
+ "wlnote" => "以下是最近<b>$2</b>小時內的最後$1次修改。",
+
+# Delete/protect/revert
+#
+"deletepage" => "刪除頁面",
+"confirm" => "確認",
+"confirmdelete" => "確認刪除",
+"deletesub" => "(正在刪除“$1”)",
+"confirmdeletetext" => "您即將從數據庫中永遠刪除一個頁面或圖像以及其歷史。
+請確定您要進行此項操作,並且瞭解其後果,同時您的行為符合[[{{ns:project}}:守則與指導]]。",
+"actioncomplete" => "操作完成",
+"deletedtext" => "“$1”已經被刪除。
+最近刪除的紀錄請參見$2。",
+"deletedarticle" => "已刪除“$1”",
+
+"dellogpage" => "刪除紀錄",
+"dellogpagetext" => "以下是最近刪除的紀錄列表。
+所有的時間都是使用服務器時間。
+<ul>
+</ul>",
+"deletionlog" => "刪除紀錄",
+"reverted" => "回降到早期版本",
+"deletecomment" => "刪除理由",
+"imagereverted" => "回降到早期版本操作完成。",
+"rollback" => "恢復",
+"rollbacklink" => "恢復",
+"cantrollback" => "無法恢復編輯;最後的鞏縣者是本文的唯一作者。",
+"revertpage" => "回降到$1的最後一次編輯",
+
+# Undelete
+"undelete" => "恢復被刪頁面",
+"undeletepage" => "瀏覽及恢復被刪頁面",
+"undeletepagetext" => "以下頁面已經被刪除,但依然在檔案中並可以被恢復。
+檔案庫可能被定時清理。",
+"undeletearticle" => "恢復被刪文章",
+"undeleterevisions" => "$1版本存檔",
+"undeletehistory" => "如果您恢復了該頁面,所有版本都會被恢復到修訂歷史中。
+如果本頁刪除後有一個同名的新頁面建立,
+被恢復的版本將會稱為較新的歷史,而新頁面的當前版本將無法被自動復原。",
+"undeleterevision" => "刪除$1時的版本",
+"undeletebtn" => "恢復!",
+"undeletedarticle" => "已經恢復“$1”",
+
+# Contributions
+#
+"contributions" => "用戶貢獻",
+"mycontris" => "我的貢獻",
+"contribsub" => "為$1",
+"nocontribs" => "沒有找到符合特徵的更改。",
+"ucnote" => "以下是該用戶最近<b><$2/b>天內的最後<b>$1</b>次修改。",
+"uclinks" => "參看最後$1次修改;參看最後$2天。",
+"uctop" => " (頂)" ,
+
+# What links here
+#
+"whatlinkshere" => "鏈入頁面",
+"notargettitle" => "無目標",
+"notargettext" => "您還沒有指定一個目標頁面或用戶以進行此項操作。",
+"linklistsub" => "(鏈接列表)",
+"linkshere" => "以下頁面鏈接到這裏:",
+"nolinkshere" => "沒有頁面鏈接到這裏。",
+"isredirect" => "重定向頁",
+
+# Block/unblock IP
+#
+"blockip" => "查封網址",
+"blockiptext" => "用下面的表單來禁止來自某一特定網址的修改權限。
+只有在為防止破壞,及符合[[{{ns:project}}:守則與指導]]的情況下才可採取此行動。
+請在下面輸入一個具體的理由(例如引述一個被破壞的頁面)。",
+"ipaddress" => "網址",
+"ipbreason" => "原因",
+"ipbsubmit" => "查封該地址",
+"badipaddress" => "網址不正確。",
+"blockipsuccesssub" => "查封成功",
+"blockipsuccesstext" => "網址“$1”已經被查封。
+<br />參看[[特殊:被封網址列表|被封網址列表]]以復審查封。",
+"unblockip" => "解除禁封網址",
+"unblockiptext" => "用下面的表單來恢復先前被禁封的網址的書寫權。",
+"ipusubmit" => "解除禁封",
+"ipblocklist" => "被封網址列表",
+"blocklistline" => "$1,$2禁封$3 ($4)",
+"blocklink" => "禁封",
+"unblocklink" => "解除禁封",
+"contribslink" => "貢獻",
+
+# Developer tools
+#
+"lockdb" => "禁止更改數據庫",
+"unlockdb" => "開放更改數據庫",
+"lockdbtext" => "鎖住數據庫將禁止所有用戶進行編輯頁面、更改參數、編輯監視列表以及其他需要更改數據庫的操作。
+請確認您的決定,並且保證您在維護工作結束後會重新開放數據庫。",
+"unlockdbtext" => "開放數據庫將會恢復所有用戶進行編輯頁面、修改參數、編輯監視列表以及其他需要更改數據庫的操作。
+請確認您的決定。",
+"lockconfirm" => "是的,我確實想要封鎖數據庫。",
+"unlockconfirm" => "是的,我確實想要開放數據庫。",
+"lockbtn" => "數據庫上鎖",
+"unlockbtn" => "開放數據庫",
+"locknoconfirm" => "您並沒有勾選確認按鈕。",
+"lockdbsuccesssub" => "數據庫成功上鎖",
+
+"unlockdbsuccesssub" => "數據庫開放",
+"lockdbsuccesstext" => "{{SITENAME}}數據庫已經上鎖。
+<br />請記住在維護完成後重新開放數據庫。",
+"unlockdbsuccesstext" => "{{SITENAME}}數據庫重新開放。",
+
+# Move page
+#
+"movepage" => "移動頁面",
+"movepagetext" => "用下面的表單來重命名一個頁面,並將其修訂歷史同時移動到新頁面。
+老的頁面將成為新頁面的重定向頁。
+鏈接到老頁面的鏈接並不會自動更改;
+請[[特殊:檢查|檢查]]雙重或損壞重定向鏈接。
+您應當負責確定所有鏈接依然會鏈到指定的頁面。
+
+注意如果新頁面已經有內容的話,頁面將'''不會'''被移動,
+除非新頁面無內容或是重定向頁,而且沒有修訂歷史。
+這意味著您再必要時可以在移動到新頁面後再移回老的頁面,
+同時您也無法覆蓋現有頁面。
+
+<b>警告!</b>
+對一個經常被訪問的頁面而言這可能是一個重大與唐突的更改;
+請在行動前先了結其所可能帶來的後果。",
+"movepagetalktext" => "有關的對話頁(如果有的話)將被自動與該頁面一起移動,'''除非''':
+*您將頁面移動到不同的名字空間;
+*新頁面已經有一個包含內容的對話頁,或者
+*您不勾選下麵的複選框。
+
+在這些情況下,您在必要時必須手工移動或合併頁面。",
+"movearticle" => "移動頁面",
+"movenologin" => "未登錄",
+"movenologintext" => "您必須是一名登記用戶並且[[Special:Userlogin|登錄]]
+後才可移動一個頁面。",
+"newtitle" => "新標題",
+"movepagebtn" => "移動頁面",
+"pagemovedsub" => "移動成功",
+"pagemovedtext" => "頁面“[[$1]]”已經移動到“[[$2]]”。",
+"articleexists" => "該名字的頁面已經存在,或者您選擇的名字無效。請再選一個名字。",
+"talkexists" => "頁面本身移動成功,
+但是由於新標題下已經有對話頁存在,所以對話頁無法移動。請手工合併兩個頁面。",
+"movedto" => "移動到",
+"movetalk" => "如果可能的話,請同時移動對話頁。",
+"talkpagemoved" => "相應的對話頁也已經移動。",
+"talkpagenotmoved" => "相應的對話頁<strong>沒有</strong>被移動。",
+
+
+# some untranslated messages as of 1.4 beta1
+'1movedto2' => "$1移動到$2", //"$1 moved to $2",
+'1movedto2_redir' => "$1重定向到$2", //"$1 moved to $2 over redirect",
+'acct_creation_throttle_hit' => "對不起,您已經註冊了$1賬號。你不能再註冊了。", //"Sorry, you have already created $1 accounts. You can't make any more.",
+'allarticles' => "所有條目", //"All articles",
+'allmessages' => "系統界面", //"All system messages",
+'allmessagesnotsupportedDB' => "系統界面功能處於關閉狀態 (wgUseDatabaseMessages)。", //"Special:AllMessages not supported because wgUseDatabaseMessages is off.",
+'allmessagestext' => "這裡列出所有可定製的系統界面。", //"This is a list of all system messages available in the MediaWiki: namespace.",
+'allinnamespace' => "所有 $1 名字空間的條目", //"All pages ($1 namespace)",
+'allpagesnext' => "下一頁", //"Next",
+'allpagesprev' => "上一頁", //"Previous",
+'allpagessubmit' => "提交", //"Go",
+'ancientpages' => "老條目", //"Oldest pages",
+'and' => "和", //"and",
+'anontalk' => "該IP的對話頁", //"Talk for this IP",
+'anonymous' => "匿名用戶", //"Anonymous user(s) of 1.4",
+'article' => "條目", //"Content page",
+'autoblocker' => "你的IP和被封了的 \"$1\" 是一樣的。封鎖原因: \"$2\".",//"Autoblocked because you share an IP address with \"$1\". Reason \"$2\".",
+'blocklogentry' => "封鎖 $1, $2",//"blocked \"$1\" with an expiry time of $2",
+'blocklogpage' => "封鎖記錄", //"Block_log",
+'categoriespagetext' => "以下列出所有的頁面分類。", //"The following categories exists in the wiki.",
+'categoryarticlecount' => "該類頁面共有 $1 條目", //There are $1 articles in this category.",
+'clearyourcache' => "'''注意:''' 保存設置後,要清掉瀏覽器的緩存才能生效:'''Mozilla / Firefox:''' ''Ctrl-Shift-R'', '''Internet Explorer:''' ''Ctrl-F5'', '''Safari:''' ''Cmd-Shift-R'', '''Konqueror:''' ''F5''。",
+'edit' => "編輯", //"Edit",
+'navigation' => "導航", //"Navigation",
+'nstab-category' => "分類", //"Category",
+'nstab-help' => "幫助",//"Help",
+'nstab-image' => "圖像",//"Image",
+'nstab-main' => "條目", //"Article",
+'nstab-mediawiki' => "界面",//"Message",
+'nstab-special' => "特殊",//"Special",
+'nstab-template' => "模板", //"Template",
+'nstab-user' => "用戶頁面", //"User page",
+'nstab-project' => "關於", //"About",
+'portal' => "社區",//"Community portal",
+'prefs-help-realname' => "*<strong>真實姓名</strong>(可選):用以對您的貢獻署名。<br />",
+'prefs-help-email' => "*<strong>點子郵件</strong>(可選):讓他人通過網站在不知道您的電子郵件地址的情況下通過電子郵件與您聯絡,以及通過電子郵件取得遺忘的密碼。", /*"* <strong>Real name</strong> (optional): if you choose to provide it this will be used for giving you attribution for your work.<br />
+* <strong>Email</strong> (optional): Enables people to contact you through the website without you having to reveal your
+email address to them, and it can be used to send you a new password if you forget it.", */
+'prefs-misc' => "雜項", //"Misc settings",
+'prefs-personal' => "用戶數據",//"User data",
+'prefs-rc' => "最近更新", //"Recent changes and stub display",
+'skin' => "面板", //"Skin",
+'talk' => "討論",//"Discussion",
+'timezonelegend' => "時區", //"Time zone",
+'toolbox' => "工具",//"Toolbox",
+'watch' => "監視",//"Watch",
+'yourlanguage' => "界面語言", //"Your language"
+'yourrealname' => "真實姓名*", //"Your real name"
+'yourvariant' => "中文字體", //"language variant"
+
+'personaltools' => "個人工具", //"personaltools""
+'history_short' => "沿革",
+"protect" => "封鎖",
+"delete" => "刪除",
+"move" => "移動",
+"tog-nocache" => "停用頁面快取",
+"specialpage" => "特殊頁面",
+"defaultns" => "預設的搜尋範圍",
+"default" => "預設",
+"aboutsite" => "關於 {{SITENAME}}",
+"disclaimers" => "免責聲明",
+"tog-fancysig" => "使用原始簽名 (不產生自動連結)",
+"tog-previewonfirst" => "第一次編輯時顯示原文內容的預覽",
+"copyright" => "本站所有內容允許以下方式利用: $1",
+"loginprompt" => "您必須允許瀏覽器紀錄Cookie才能成功登入 {{SITENAME}} 並順利進行操作",
+);
+
+
+?>
diff --git a/languages/messages/MessagesZh_yue.php b/languages/messages/MessagesZh_yue.php
new file mode 100644
index 000000000000..62fe2a9481ef
--- /dev/null
+++ b/languages/messages/MessagesZh_yue.php
@@ -0,0 +1,2204 @@
+<?php
+/**
+ * Cantonese (粵語/廣東話)
+ *
+ * @package MediaWiki
+ * @subpackage Language
+ */
+
+$quickbarSettings = array(
+ '無', /* "None" */
+ '左邊固定', /* "Fixed left" */
+ '右邊固定', /* "Fixed right" */
+ '左邊浮動', /* "Floating left" */
+ '右邊浮動', /* "Floating right" */
+);
+
+$skinNames = array(
+ 'standard' => '傳統', /* "Classic, Standard" */
+ 'nostalgia' => '懷舊', /* "Nostalgia" */
+ 'cologneblue' => '科倫藍', /* "Cologne Blue" */
+ 'davinci' => '達文西', /* "DaVinci" */
+ 'mono' => '簡單', /* "Mono" */
+ 'monobook' => 'MonoBook',
+ 'myskin' => '我嘅皮', /* "MySkin" */
+ 'chick' => '小妞', /* "Chick" */
+ 'simple' => '簡單' /* "Simple" */
+);
+
+$bookstoreList = array(
+ 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
+ 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
+ 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
+ '亞馬遜' => 'http://www.amazon.com/exec/obidos/ISBN=$1',
+ '博客來書店' => 'http://www.books.com.tw/exep/openfind_book_keyword.php?cat1=4&key1=$1',
+ '三民書店' => 'http://www.sanmin.com.tw/page-qsearch.asp?ct=search_isbn&qu=$1',
+ '天下書店' => 'http://www.cwbook.com.tw/cw/TS.jsp?schType=product.isbn&schStr=$1',
+ '新絲書店' => 'http://www.silkbook.com/function/Search_List_Book.asp?item=5&text=$1'
+);
+
+$datePreferences = array(
+ 'default',
+ 'yue dmy',
+ 'yue mdy',
+ 'yue ymd',
+ 'ISO 8601',
+);
+
+$defaultDateFormat = 'yue';
+
+$dateFormats = array(
+ 'yue time' => 'H:i',
+ 'yue date' => 'Y年n月j日 (D)',
+ 'yue both' => 'Y年n月j日 (D) H:i',
+
+ 'yue dmy time' => 'H:i',
+ 'yue dmy date' => 'j-n-Y',
+ 'yue dmy both' => 'j-n-Y H:i',
+
+ 'yue mdy time' => 'H:i',
+ 'yue mdy date' => 'n-j-Y',
+ 'yue mdy both' => 'n-j-Y H:i',
+
+ 'yue ymd time' => 'H:i',
+ 'yue ymd date' => 'Y-n-j',
+ 'yue ymd both' => 'Y-n-j H:i',
+);
+
+$namespaceNames = array(
+ NS_MEDIA => 'Media',
+ NS_SPECIAL => 'Special',
+ NS_MAIN => '',
+ NS_TALK => 'Talk',
+ NS_USER => 'User',
+ NS_USER_TALK => 'User_talk',
+ # NS_PROJECT => $wgMetaNamespace,
+ NS_PROJECT_TALK => '$1_talk',
+ NS_IMAGE => 'Image',
+ NS_IMAGE_TALK => 'Image_talk',
+ NS_MEDIAWIKI => 'MediaWiki',
+ NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
+ NS_TEMPLATE => 'Template',
+ NS_TEMPLATE_TALK => 'Template_talk',
+ NS_HELP => 'Help',
+ NS_HELP_TALK => 'Help_talk',
+ NS_CATEGORY => 'Category',
+ NS_CATEGORY_TALK => 'Category_talk',
+);
+
+$namespaceAliases = array(
+ "媒體" => NS_MEDIA,
+ "媒体" => NS_MEDIA,
+ "特別" => NS_SPECIAL,
+ "特殊" => NS_SPECIAL,
+ "對話" => NS_TALK,
+ "对话" => NS_TALK,
+ "討論" => NS_TALK,
+ "讨论" => NS_TALK,
+ "用戶" => NS_USER,
+ "用户" => NS_USER,
+ "用戶 對話" => NS_USER_TALK,
+ "用户 对话" => NS_USER_TALK,
+ "用戶 討論" => NS_USER_TALK,
+ "用户 讨论" => NS_USER_TALK,
+ # This has never worked so it's unlikely to annoy anyone if I disable it -- TS
+ #"{$wgMetaNamespace} 討論" => NS_PROJECT_TALK,
+ #"{$wgMetaNamespace} 讨论" => NS_PROJECT_TALK,
+ "圖" => NS_IMAGE,
+ "圖像" => NS_IMAGE,
+ "图" => NS_IMAGE,
+ "图像" => NS_IMAGE,
+ "圖 討論" => NS_IMAGE_TALK,
+ "图 讨论" => NS_IMAGE_TALK,
+ "圖像 討論" => NS_IMAGE_TALK,
+ "图像 讨论" => NS_IMAGE_TALK,
+ "模" => NS_TEMPLATE,
+ "模 討論" => NS_TEMPLATE_TALK,
+ "模 讨论" => NS_TEMPLATE_TALK,
+ "幫手" => NS_HELP,
+ "幫助" => NS_HELP,
+ "說明" => NS_HELP,
+ "帮手" => NS_HELP,
+ "帮助" => NS_HELP,
+ "说明" => NS_HELP,
+ "幫手 討論" => NS_HELP_TALK,
+ "幫助 討論" => NS_HELP_TALK,
+ "說明 討論" => NS_HELP_TALK,
+ "帮手 讨论" => NS_HELP_TALK,
+ "帮助 讨论" => NS_HELP_TALK,
+ "说明 讨论" => NS_HELP_TALK,
+ "類" => NS_CATEGORY,
+ "分類" => NS_CATEGORY,
+ "类" => NS_CATEGORY,
+ "分类" => NS_CATEGORY,
+ "類 討論" => NS_CATEGORY_TALK,
+ "分類 討論" => NS_CATEGORY_TALK,
+ "类 讨论" => NS_CATEGORY_TALK,
+ "分类 讨论" => NS_CATEGORY_TALK,
+);
+
+$linkTrail = '/^([a-z]+)(.*)$/sD';
+
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+# Allowed characters in keys are: A-Z, a-z, 0-9, underscore (_) and
+# hyphen (-). If you need more characters, you may be able to change
+# the regex in MagicWord::initRegex
+
+$messages = array(
+
+# User preference toggles
+'tog-underline' => '連結加底線',
+'tog-highlightbroken' => '格式化連結 <a href="" class="new">好似咁</a>(又或者: 好似咁<a href="" class="internal">?</a>).',
+'tog-justify' => '拍齊段落',
+'tog-hideminor' => '最新更改唔顯示小修改',
+'tog-extendwatchlist' => '展開監視清單去顯示合適嘅更改',
+'tog-usenewrc' => '強化版最近更改(JavaScript)',
+'tog-numberheadings' => '標題自動編號',
+'tog-showtoolbar' => '顯示修改工具列(JavaScript)',
+'tog-editondblclick' => '雙擊可以改嘢(JavaScript)',
+'tog-editsection' => '可以用 [修改] 掣更改個別段落',
+'tog-editsectiononrightclick' => '可以撳右掣更改個別段落(JavaScript)',
+'tog-showtoc' => '喺多過三個段落嘅時候顯示目錄',
+'tog-rememberpassword' => '響呢部電腦度記住我嘅密碼',
+'tog-editwidth' => '全螢幕咁闊嘅修改欄',
+'tog-watchcreations' => '將我開嘅頁面加入監視清單',
+'tog-watchdefault' => '將我修改嘅頁面加入監視清單',
+'tog-watchdeletion' => '將我刪除嘅頁面加入監視清單',
+'tog-minordefault' => '所有編輯預設為小修改',
+'tog-previewontop' => '喺修改欄上方顯示預覽',
+'tog-previewonfirst' => '第一次修改時顯示預覽',
+'tog-nocache' => '停用頁面快取',
+'tog-enotifwatchlistpages' => '當我監視嘅頁面有修改時電郵通知我',
+'tog-enotifusertalkpages' => '個人留言版有修改時電郵通知我',
+'tog-enotifminoredits' => '小修改都要電郵通知我',
+'tog-enotifrevealaddr' => '喺通知信上面話畀人聽我嘅電郵地址',
+'tog-shownumberswatching' => '顯示有幾多人監視',
+'tog-fancysig' => '程式碼簽名(冇自動連結)',
+'tog-externaleditor' => '預設用外掛編輯器',
+'tog-externaldiff' => '預設用外掛比較器',
+'tog-showjumplinks' => '啟用 "跳至" 協助連結',
+'tog-uselivepreview' => '用即時預覽(JavaScript)(實驗緊)',
+'tog-forceeditsummary' => '我冇入修改註解時通知我',
+'tog-watchlisthideown' => '響監視清單度隱藏我嘅編輯',
+'tog-watchlisthidebots' => '響監視清單度隱藏機械人嘅編輯',
+'tog-watchlisthideminor' => '響監視清單度隱藏小修改',
+'tog-nolangconversion' => '唔要用字轉換',
+'tog-ccmeonemails' => '當我寄電郵畀其他人嗰陣寄返封副本畀我',
+
+'underline-always' => '全部',
+'underline-never' => '永不',
+'underline-default' => '瀏覽器預設',
+
+'skinpreview' => '(預覽)',
+
+# dates
+'sunday' => '星期日',
+'monday' => '星期一',
+'tuesday' => '星期二',
+'wednesday' => '星期三',
+'thursday' => '星期四',
+'friday' => '星期五',
+'saturday' => '星期六',
+'sun' => '日',
+'mon' => '一',
+'tue' => '二',
+'wed' => '三',
+'thu' => '四',
+'fri' => '五',
+'sat' => '六',
+'january' => '1月',
+'february' => '2月',
+'march' => '3月',
+'april' => '4月',
+'may_long' => '5月',
+'june' => '6月',
+'july' => '7月',
+'august' => '8月',
+'september' => '9月',
+'october' => '10月',
+'november' => '11月',
+'december' => '12月',
+'january-gen' => '一月',
+'february-gen' => '二月',
+'march-gen' => '三月',
+'april-gen' => '四月',
+'may-gen' => '五月',
+'june-gen' => '六月',
+'july-gen' => '七月',
+'august-gen' => '八月',
+'september-gen' => '九月',
+'october-gen' => '十月',
+'november-gen' => '十一月',
+'december-gen' => '十二月',
+'jan' => '1月',
+'feb' => '2月',
+'mar' => '3月',
+'apr' => '4月',
+'may' => '5月',
+'jun' => '6月',
+'jul' => '7月',
+'aug' => '8月',
+'sep' => '9月',
+'oct' => '10月',
+'nov' => '11月',
+'dec' => '12月',
+# Bits of text used by many pages:
+#
+'categories' => '分類',
+'pagecategories' => '分類',
+'category_header' => '"$1" 分類中嘅文章',
+'subcategories' => '次分類',
+'category-media-header' => '響 "$1" 分類嘅媒體',
+
+'mainpage' => '頭版',
+'mainpagetext' => "<big>'''MediaWiki 已經成功地安裝。'''</big>",
+'mainpagedocfooter' => "參閱[http://meta.wikimedia.org/wiki/Help:Contents 用戶指引](英)以取得使用wiki軟件嘅資料。
+
+==開始使用==
+* [http://www.mediawiki.org/wiki/Help:Configuration_settings 配置設定清單](英)
+* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki 常見問題](英)
+* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki 發佈郵件名單](英)",
+
+'portal' => '社區大堂',
+'portal-url' => 'Project:社區大堂',
+'about' => '關於',
+'aboutsite' => '關於{{SITENAME}}',
+'aboutpage' => 'Project:關於',
+'article' => '內容頁',
+'help' => '幫手',
+'helppage' => 'Help:目錄',
+'bugreports' => '臭蟲回報',
+'bugreportspage' => 'Project:臭蟲回報',
+'sitesupport' => '慷慨解囊',
+'sitesupport-url' => 'Project:支持網站',
+'faq' => 'FAQ',
+'faqpage' => 'Project:FAQ',
+'edithelp' => '編輯協助',
+'newwindow' => '(響新視窗度打開)',
+'edithelppage' => 'Help:編輯',
+'cancel' => '取消',
+'qbfind' => '搵嘢',
+'qbbrowse' => '瀏覽',
+'qbedit' => '編輯',
+'qbpageoptions' => '呢一頁',
+'qbpageinfo' => '附近文字',
+'qbmyoptions' => '我嘅選項',
+'qbspecialpages' => '特殊頁',
+'moredotdotdot' => '更多...',
+'mypage' => '我嘅頁面',
+'mytalk' => '我嘅對話',
+'anontalk' => '同呢個 IP 對話',
+'navigation' => '導航',
+
+# Metadata in edit box
+'metadata_help' => 'Metadata(解釋請睇[[Project:Metadata]])',
+
+'currentevents' => '最近發生嘅事', //唔好釋做「新聞動態」或「時人時事」(Wikipedia specific) -- Man
+'currentevents-url' => '最近發生嘅事',
+
+'disclaimers' => '免責聲明',
+'disclaimerpage' => 'Project:一般免責聲明',
+'privacy' => '私隱政策',
+'privacypage' => 'Project:私隱政策',
+'errorpagetitle' => '錯誤',
+'returnto' => '返去$1 。',
+'tagline' => '出自{{SITENAME}}',
+'whatlinkshere' => '連結嚟呢道嘅頁面',
+'help' => '幫助',
+'search' => '搵嘢',
+'searchbutton' => '搵嘢',
+'go' => '去',
+'searcharticle' => '去',
+'history' => '頁面歷史',
+'history_short' => '歷史',
+'updatedmarker' => '我上次到訪之後嘅修改',
+'info_short' => '資訊',
+'printableversion' => '可打印版本',
+'permalink' => '永久連結',
+'print' => '打印',
+'edit' => '編輯',
+'editthispage' => '編輯呢頁',
+'delete' => '刪除',
+'deletethispage' => '刪除呢頁',
+'undelete_short' => '反刪除$1個修改', //原文為 UNDELETE, 不可譯成 "還原", 下同 -- DC
+'protect' => '保護',
+'protectthispage' => '保護呢頁',
+'unprotect' => '解除保護',
+'unprotectthispage' => '解除保護呢頁',
+'newpage' => '開新頁',
+'talkpage' => '討論呢版',
+'specialpage' => '特別頁',
+'personaltools' => '個人工具',
+'postcomment' => '寫句意見',
+'articlepage' => '睇目錄',
+'talk' => '討論',
+'views' => '去睇',
+'toolbox' => '工具箱',
+'userpage' => '去睇用戶頁',
+'projectpage' => '去睇專題頁',
+'imagepage' => '去睇圖片頁',
+'mediawikipage' => '去睇信息頁',
+'templatepage' => '去睇模頁',
+'viewhelppage' => '去睇幫手頁',
+'categorypage' => '去睇分類頁',
+'viewtalkpage' => '睇討論',
+'otherlanguages' => '其它語言',
+'redirectedfrom' => '(由 $1 重新定向)', //REDIRECT
+'redirectpagesub' => '重新定向頁',
+'lastmodifiedat' => '呢一頁嘅最後修改係響$1 $2。',
+'viewcount' => '呢一頁已經有$1人次睇過。',
+'copyright' => '響版度嘅內容係根據$1嘅條款發佈。',
+'protectedpage' => '受保護頁',
+'jumpto' => '跳去:',
+'jumptonavigation' => '定向',
+'jumptosearch' => '搵嘢',
+
+'badaccess' => '權限錯誤',
+'badaccess-group0' => '你係唔准執行你要求嘅動作。',
+'badaccess-group1' => '你所要求嘅動作只係限制畀$1組嘅用戶。',
+'badaccess-group2' => '你所要求嘅動作只係限制畀$1組嘅其中一位用戶。',
+'badaccess-groups' => '你所要求嘅動作只係限制畀$1組嘅其中一位用戶。',
+
+
+'versionrequired' => '係需要用 $1 版嘅 MediaWiki',
+'versionrequiredtext' => '要用呢一頁,係需要用MediaWiki版本 $1 。睇睇[[Special:Version]]',
+
+'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'retrievedfrom' => '由 "$1" 接收',
+'youhavenewmessages' => '你有$1($2)。',
+'newmessageslink' => '新信息',
+'newmessagesdifflink' => '上次更改',
+'editsection' => '編輯',
+'editold' => '編輯',
+'editsectionhint' => '編輯小節: $1',
+'toc' => '目錄',
+'showtoc' => '展開',
+'hidetoc' => '收埋',
+'thisisdeleted' => '睇下定係還原 $1 ?',
+'viewdeleted' => '去睇$1?',
+'restorelink' => '$1 個已刪除嘅編輯',
+'feedlinks' => 'Feed:',
+'feed-invalid' => '唔正確嘅 feed 類型。',
+
+# Short words for each namespace, by default used in the 'article' tab in monobook
+'nstab-main' => '文章',
+'nstab-user' => '用戶頁',
+'nstab-media' => '媒體頁',
+'nstab-special' => '特別',
+'nstab-project' => '專題頁',
+'nstab-image' => '檔案',
+'nstab-mediawiki' => '信息',
+'nstab-template' => '模',
+'nstab-help' => '幫助頁',
+'nstab-category' => '分類',
+
+# Main script and global functions
+#
+'nosuchaction' => '冇呢個動作',
+'nosuchactiontext' => '呢個 URL 嘅指定動作 wiki 識別唔到',
+'nosuchspecialpage' => '冇呢頁特別頁',
+'nospecialpagetext' => '您所要求嘅特別頁唔啱,喺 [[{{ns:special}}:Specialpages]] 可以搵到所有用得嘅特別頁。',
+
+# General errors
+#
+'error' => '錯誤',
+'databaseerror' => '資料庫錯誤',
+'dberrortext' => '資料庫查詢語法錯咗。
+咁係可能指出軟件中可能有臭蟲。
+最後一次資料庫嘅嘗試係:
+<blockquote><tt>$1</tt></blockquote>
+於 "<tt>$2</tt>" 功能中。
+MySQL 嘅錯誤回應 "<tt>$3: $4</tt>"。',
+'dberrortextcl' => '資料庫查詢語法錯咗。
+最後一次資料庫嘅嘗試係:
+"$1"
+於 "$2"功能中。
+MySQL 嘅錯誤回應 "$3: $4"',
+'noconnect' => '對唔住!Wiki 而家有啲技術問題,連唔上資料庫伺服器。<br />$1',
+'nodb' => '唔能夠選擇伺服器 $1',
+'cachederror' => '以下係已請求頁面嘅快取複本,內容可能唔係最新嘅。',
+'laggedslavemode' => '警告:面頁可能未包括最新嘅更新。',
+'readonly' => '資料庫已經鎖上',
+'enterlockreason' => '請輸入鎖上資料庫嘅原因,包括預計幾耐後會解鎖',
+'readonlytext' => '{{SITENAME}}資料庫而家鎖住咗,唔可以增加新內容或進行其他修改。可能係因為做緊維修,搞掂就會回復正常。
+
+管理員有以下嘅解釋: $1',
+'missingarticle' => '資料庫搵唔到你要嘅文章,「$1」。
+
+通常係因為修訂歷史頁上面,由過時嘅連結去到刪除咗嘅文章所引起嘅。
+
+如果唔係,你可能係搵到軟件裏面嘅臭蟲。
+請記低 URL 地址,向管理員報告。',
+'readonly_lag' => '當從伺服器追上主伺服器嘅時候,資料庫會被自動鎖上',
+'internalerror' => '內部錯誤',
+'filecopyerror' => '唔可以複製檔案 "$1" 到$2"。',
+'filerenameerror' => '唔可以更名檔案 "$1" 到 "$2"。',
+'filedeleteerror' => '唔可以刪除檔案 "$1"。',
+'filenotfound' => '搵唔到檔案 "$1"。',
+'unexpected' => '意外數值。 "$1"="$2"。',
+'formerror' => '錯誤:唔可以遞交表格',
+'badarticleerror' => '呢個動作唔可以喺頁面度進行。',
+'cannotdelete' => '唔可以刪除指定嘅頁面或檔案。(可能呢個頁面或檔案已經刪除咗。)',
+'badtitle' => '錯誤嘅標題',
+'badtitletext' => '所要求嘅頁面標題唔正確、空白,跨語言或者跨維基連結標題錯誤。亦可能係標題包括咗一個或多過一個字元。',
+'perfdisabled' => '對唔住!呢個功能有可能造成資料庫癱瘓,所以要暫時停用。',
+'perfdisabledsub' => '呢個係嚟自 $1 嘅儲存複本。', # obsolete?
+'perfcached' => '以下嘅資料係嚟自快取,可能唔係最新嘅。',
+'perfcachedts' => '以下嘅資料係嚟自快取,上一次嘅更新喺$1。',
+'wrong_wfQuery_params' => 'wfQuery() 嘅參數錯誤<br />
+函數: $1<br />
+查詢: $2',
+'viewsource' => '睇吓原始碼',
+'viewsourcefor' => '$1嘅原始碼',
+'protectedpagetext' => '呢一頁已經鎖咗唔畀改。',
+'viewsourcetext' => '你可以睇吓或者複製呢一頁嘅原始碼:',
+'protectedinterface' => '呢一頁提供軟件嘅介面文字,呢一頁已經鎖上以預防濫用。',
+'editinginterface' => "'''警告:'''你而家編輯緊嘅呢一個用嚟提供介面文字嘅頁面。響呢一頁嘅更改會影響到其他用戶使用中嘅介面外觀。",
+'sqlhidden' => '(SQL 查詢隱藏)',
+
+# Login and logout pages
+#
+'logouttitle' => '用戶登出',
+'logouttext' => '<strong>你而家已經登出咗。</strong><br />
+你仍然可以用匿名身份用{{SITENAME}},又或者重新登入。
+但係留意某啲頁面可能會繼續話您登入咗,除非等你清除瀏覽器嘅快取儲存。',
+
+'welcomecreation' => "== 歡迎, $1! ==
+
+你個戶口已經起好。唔好唔記得去改改你嘅{{SITENAME}}喜好設定喎。",
+
+'loginpagetitle' => '用戶登入',
+'yourname' => '用戶名',
+'yourpassword' => '密碼',
+'yourpasswordagain' => '再輸入密碼',
+'remembermypassword' => '響呢部電腦度記住我嘅密碼',
+'yourdomainname' => '你嘅網域',
+'externaldberror' => '外部驗證資料庫出錯,或者唔允許你更新你嘅外部帳戶。',
+'loginproblem' => '<b>你嘅登入手續出咗問題。</b><br />唔該再試吓登入。',
+'alreadyloggedin' => "<strong>用戶$1,你已經登入咗喇喎!</strong><br />",
+
+'login' => '登入',
+'loginprompt' => '你一定開咗 cookies 先登入到{{SITENAME}}。',
+'userlogin' => '登入/開新戶口',
+'logout' => '登出',
+'userlogout' => '登出',
+'notloggedin' => '未登入',
+'nologin' => '重未有戶口? $1。',
+'nologinlink' => '開一個新嘅戶口',
+'createaccount' => '建立戶口',
+'gotaccount' => '已經有戶口? $1 。',
+'gotaccountlink' => '登入',
+'createaccountmail' => '用電郵',
+'badretype' => '你所入嘅密碼唔一致。',
+'userexists' => '你入嘅用戶名已經有人用緊,唔該揀過另外一個名啦。',
+'youremail' => '電郵 *:',
+'username' => '用戶名:',
+'uid' => '用戶 ID:',
+'yourrealname' => '真實姓名 *:',
+'yourlanguage' => '語言:',
+'yourvariant' => '字體變化:',
+'yournick' => '綽號(簽名時用)',
+'badsig' => '無效嘅程式碼簽名;請檢查 HTML 有無錯。所有屬性都要用雙引號括住。',
+'email' => '電郵',
+'prefs-help-email-enotif' => '如果你已經選呢個項,電郵通知亦都會用呢個電郵地址寄畀你。',
+'prefs-help-realname' => '* 真名(可以選填):你嘅真名,用來喺有需要嘅時候標示你嘅作品。',
+'loginerror' => '登入錯誤',
+'prefs-help-email' => '* 電郵(可以選填):啟用後等人可以響唔知你電郵地址嘅情況之下都可以聯絡你。',
+'nocookiesnew' => '已經建立咗戶口,但你未登入。 {{SITENAME}} 要用 cookies 嚟登入。你已經停咗用 cookies。麻煩啟用返先,然後再用你新嘅用戶名同密碼。',
+'nocookieslogin' => '{{SITENAME}} 要用 cookies 嚟登入。您已經停用 cookies。請先啟用後再度試過喇。',
+'noname' => '你未指定一個有效嘅用戶名。',
+'loginsuccesstitle' => '登入成功',
+'loginsuccess' => "'''你已經成功咁喺{{SITENAME}}登入做「$1」。'''",
+'nosuchuser' => '呢度冇叫做 "$1"嘅用戶。 請檢查你個名嘅輸入方法,或者建立一個新嘅戶口。',
+'nosuchusershort' => '呢度冇叫做 "$1"嘅用戶。 請檢查你個名嘅輸入方法。',
+'nouserspecified' => '你需要指定一個用戶名。',
+'wrongpassword' => '密碼唔啱,麻煩你再試多次。',
+'wrongpasswordempty' => '你都未入密碼,唔該再試多次啦。',
+'mailmypassword' => '寄返個密碼畀我',
+'passwordremindertitle' => '{{SITENAME}}嘅密碼提醒',
+'passwordremindertext' => '有人(可能係你,IP 位置 $1)
+請求我哋傳送個$4嘅 {{SITENAME}} 新登入密碼畀你。
+而家用戶 "$2" 嘅新密碼係 "$3"。
+唔該即刻登入,改咗個密碼。
+
+如果係其他人作出呢個請求,又或者你記得返你嘅密碼而又唔想再轉,
+你可以唔使理呢個信息,繼續用舊密碼。',
+'noemail' => '呢度冇用戶 "$1" 嘅電郵地址記錄。',
+'passwordsent' => '新嘅密碼已經寄咗畀呢位用戶 "$1" 嘅電郵地址。
+收到之後請重新登入。',
+'blocked-mailpassword' => '你嘅IP地址而家被封鎖緊,唔可以用密碼復原功能以防止濫用。',
+'eauthentsent' => '確認電郵已經傳送到指定嘅電郵地址。
+喺其它嘅郵件傳送到呢個戶口之前,你需要按電郵嘅指示,嚟確認呢個戶口真係屬於你嘅。',
+'throttled-mailpassword' => '一個密碼提醒已經響$1個鐘頭之前發送咗。
+為咗防止濫用,響$1個鐘頭之內只可以發送一個密碼提醒。',
+'mailerror' => '傳送電郵錯誤: $1',
+'acct_creation_throttle_hit' => '對唔住,你已經開咗 $1 個戶口,唔可以再開多個戶口。',
+'emailauthenticated' => '你嘅電郵地址已經喺 $1 確認。',
+'emailnotauthenticated' => '你嘅電郵地址重未確認。 任何傳送電郵嘅功能都唔會運作。',
+'noemailprefs' => '設置一個電郵地址令到呢啲功能開始運作。',
+'emailconfirmlink' => '確認你嘅電郵地址',
+'invalidemailaddress' => '呢個電郵地址嘅格式唔啱,所以接受唔到。
+唔該輸入一個啱格式嘅地址,或清咗嗰個空格。',
+'accountcreated' => '戶口已經建立咗',
+'accountcreatedtext' => '$1 嘅用戶戶口已經建立好。',
+
+# Password reset dialog
+'resetpass' => '重設戶口密碼',
+'resetpass_announce' => '你已經用咗一個臨時電郵碼登入。要完成登入,你一定要響呢度定一個新嘅密碼:',
+'resetpass_header' => '重設密碼',
+'resetpass_submit' => '設定密碼同登入',
+'resetpass_success' => '你嘅密碼已經成功咁更改!而家幫你登入緊...',
+'resetpass_bad_temporary' => '唔啱嘅臨時密碼。你可能已經成功咁更改你嘅密碼,又或者重新請求過一個新嘅臨時密碼。',
+'resetpass_forbidden' => '響呢個wiki度唔可以更改密碼',
+'resetpass_missing' => '響資料度搵唔到嘢。',
+
+# Edit page toolbar
+'bold_sample' => '粗體字',
+'bold_tip' => '粗體字',
+'italic_sample' => '斜體字',
+'italic_tip' => '斜體字',
+'link_sample' => '連結標題',
+'link_tip' => '內部連結',
+'extlink_sample' => 'http://www.example.com 連結標題',
+'extlink_tip' => '外部連結(記得要加 http:// 開頭)',
+'headline_sample' => '標題文字',
+'headline_tip' => '二級標題',
+'math_sample' => '喺呢度插入方程式',
+'math_tip' => '數學方程(LaTeX)',
+'nowiki_sample' => '喺呢度插入非格式代文字',
+'nowiki_tip' => '唔理 wiki 格式',
+'image_sample' => 'Example.jpg',
+'image_tip' => '嵌入圖像',
+'media_sample' => 'Example.ogg',
+'media_tip' => '媒體檔案連結',
+'sig_tip' => '你嘅簽名同埋時間戳',
+'hr_tip' => '橫線(請謹慎咁用)',
+
+# Edit pages
+#
+'summary' => '摘要',
+'subject' => '主題/標題',
+'minoredit' => '呢個係小修改',
+'watchthis' => '睇實呢一頁',
+'savearticle' => '儲存呢頁',
+'preview' => '預覽',
+'showpreview' => '顯示預覽',
+'showlivepreview' => '實時預覽',
+'showdiff' => '顯示差異',
+'anoneditwarning' => "'''警告:'''你重未登入。你嘅 IP 位址會喺呢個頁面嘅修訂歷史中記錄落嚟。",
+'missingsummary' => "'''提醒:''' 你未提供編輯摘要。如果你再撳多一下儲存嘅話,咁你儲存嘅編輯就會無摘要。",
+'missingcommenttext' => '請輸入一個註解。',
+'missingcommentheader' => "'''提醒:'''你響呢個註解度並無提供一個主題/標題。如果你再撳一次儲存,你嘅編輯就會無題。",
+'summary-preview' => '摘要預覽',
+'subject-preview' => '標題/頭條預覽',
+'blockedtitle' => '用戶已經封鎖',
+'blockedtext' => "<big>你嘅用戶名或者 IP 位址已經被 $1 封咗。</big>
+
+呢次封鎖係由$1所封嘅。當中嘅原因係''$2''。
+
+你可以聯絡 $1 或者其他嘅[[Project:管理員|管理員]],討論呢次封鎖。
+
+除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,
+否則你係唔可以用「電郵呢個用戶」嘅功能。你嘅 IP 位址係 $3 ,而個封鎖 ID 係 #$5。 請你喺所有查詢都註明呢個位址同埋/或者個封鎖 ID 。",
+'blockedoriginalsource' => "有關'''$1'''嘅原始碼響下面列示:",
+'blockededitsource' => "有關'''你'''對'''$1'''嘅'''編輯'''文字響下面列示:",
+'whitelistedittitle' => '需要登入之後先至可以編輯',
+'whitelistedittext' => '你需要$1去編輯呢頁。',
+'whitelistreadtitle' => '需要登入之後先至睇到',
+'whitelistreadtext' => '你需要[[Special:Userlogin|登入]]先可以去睇呢頁。',
+'whitelistacctitle' => '你唔可以開一個新戶口',
+'whitelistacctext' => '要喺呢個 Wiki 開戶口,你要[[Special:Userlogin|登入]]同提供適當嘅許可。',
+'confirmedittitle' => '要用電郵確定咗先可以改',
+'confirmedittext' => '你個電郵地址要確定咗先可以編輯。唔該先去[[Special:Preferences|喜好設定]]填咗電郵地址,並做埋確認手續。',
+'loginreqtitle' => '需要登入',
+'loginreqlink' => '登入',
+'loginreqpagetext' => '你一定$1去睇其它嘅頁面。',
+'accmailtitle' => '密碼寄咗喇。',
+'accmailtext' => '「$1」嘅密碼已經寄咗去 $2。',
+'newarticle' => '(新)',
+'newarticletext' =>
+"你連連過嚟嘅頁面重未存在。
+要起版新嘅,請您喺下面嗰格度輸入。
+(睇睇[[{{ns:help}}:目錄|自助版]]拎多啲資料。)
+如果你係唔覺意嚟到呢度,撳一次你個瀏覽器'''返轉頭'''個掣。",
+'anontalkpagetext' => "----''呢度係匿名用戶嘅討論頁,佢可能係重未開戶口,或者佢重唔識開戶口。我哋會用數字表示嘅IP地址嚟代表佢。一個IP地址係可以由幾個用戶夾來用。如果你係匿名用戶,同覺得呢啲留言係同你冇關係嘅話,唔該去[[Special:Userlogin|開一個新戶口或登入]],避免喺以後嘅留言會同埋其它用戶混淆。''",
+'noarticletext' => '喺呢一頁而家並冇任何嘅文字,你可以喺其它嘅頁面中[[{{ns:special}}:Search/{{PAGENAME}}|搵呢一頁嘅標題]]或者[{{fullurl:{{FULLPAGENAME}}|action=edit}} 編輯呢一頁]。',
+'clearyourcache' => "'''注意:'''喺儲存之後,你可能要先略過你嘅瀏覽器快取去睇到更改。'''Mozilla / Firefox / Safari:''' 㩒住''Shift''掣再撳''重新載入'',又或者㩒''Ctrl-Shift-R''(喺蘋果Mac中㩒''Cmd-Shift-R''掣); '''IE:''' 㩒住''Ctrl''掣再撳''重新整理'',又或者㩒''Ctrl-F5''掣; '''Konqueror:''' 就咁以撳個''重載''掣,又或者㩒''F5''; '''Opera'''嘅用戶可能需要先喺''工具→喜好設定''之中清佢哋嘅快取。",
+'usercssjsyoucanpreview' => '<strong>提示:</strong>響儲存前,用「顯示預覽」個掣嚟測試你嘅新CSS/JS。',
+'usercsspreview' => '\'\'\'請注意你而家只係預覽緊你嘅用戶CSS樣式表,內容仍未儲存!\'\'\'',
+'userjspreview' => '\'\'\'請注意你而家只係測試/預覽緊你定義嘅JavaScript,佢嘅內容重未儲存!\'\'\'',
+'userinvalidcssjstitle' => "'''警告:''' 未有名稱 \"$1\" 嘅皮。請記住自訂介面的 .css 和 .js 頁面時應使用細楷,例如:User:Foo/monobook.css 而唔係 User:Foo/Monobook.css 。",
+'updated' => '(Updated)',
+'note' => '<strong>Note:</strong>',
+'previewnote' => '<strong>請記住呢個只係預覽;更改嘅内容重未儲存!</strong>',
+'session_fail_preview' => '<strong>對唔住!由於小節嘅資料唔見咗,我哋唔能夠處理你嘅編輯。
+請再試過喇。如果仍然唔得嘅話,試下登出,然後重新登入。</strong>',
+'previewconflict' => '呢個預覽係反映如果你選擇儲存嘅話,嘅上面嘅文字編輯區裏面嘅字會儲存落嚟。',
+'session_fail_preview_html' => '<strong>對唔住!有關嘅程序資料已經遺失,我哋唔能夠處理你嘅編輯。</strong>
+
+\'\'由於哩個 wiki 已經開放咗原 HTML 碼,預覽已經隱藏落嚟以預防 JavaScript 嘅攻擊。\'\'
+
+<strong>如果呢個係正當嘅編輯嘗試,請再試過。如果重係唔得嘅話,請先登出然後再登入。</strong>',
+'importing' => '而家喺度滙入$1',
+'editing' => '而家喺度編輯$1',
+'editinguser' => '而家喺度編輯用戶<b>$1</b>',
+'editingsection' => '而家喺度編輯$1 (小節)',
+'editingcomment' => '而家喺度編輯$1 (評論)',
+'editconflict' => '編輯衝突:$1',
+'explainconflict' => '有其他人喺你開始編輯之後已經更改呢一頁。
+喺上面嗰個空間而家現存嘅頁面文字。
+你嘅更改會喺下面嘅文字空間顯示。
+你需要合併你嘅更改到原有嘅文字。
+喺你撳「儲存頁面」之後,<b>只有</b>喺上面嘅文字區會被儲存。<br />',
+'yourtext' => '您嘅文字',
+'storedversion' => '已經儲存咗嘅版本',
+'nonunicodebrowser' => "<strong>警告:你嘅瀏覽器係唔係用緊 Unicode 。而家暫時有個解決方法,方便你可以安全咁編輯文章:唔係 ASCII 嘅字元會喺編輯框裏面用十六進位編碼顯示。</strong>",
+'editingold' => "<strong>警告:你而家係編輯緊喺呢一頁嘅過時版本。
+如果你儲存佢,喺呢個版本嘅任何更改都會被遺失。</strong>",
+'yourdiff' => '差異',
+'copyrightwarning' => '請留意喺{{SITENAME}}度,所有喺呢度嘅貢獻會被考慮到喺$2之下發出(睇$1有更詳細嘅資訊)。如果你係唔想你編輯嘅文字無喇喇咁被分發,咁就唔好喺呢度遞交。<br />
+你亦都要同我哋保證啲文字係你自己寫嘅,或者係由公有領域或相似嘅自由資源複製落嚟。
+<strong>喺未有任何許可嘅情況之下千祈唔好遞交有版權嘅作品!</strong>',
+'copyrightwarning2' => '請留意喺{{SITENAME}}度,所有嘅貢獻可能會被其他嘅貢獻者編輯、修改,或者刪除。如果你係唔想你編輯嘅文字無喇喇咁被編輯,咁就唔好喺呢度遞交。<br />
+你亦都要同我哋保證啲文字係你自己寫嘅,或者係由公有領域或相似嘅自由資源複製落嚟(睇$1有更詳細嘅資訊)。
+<strong>喺未有任何許可嘅情況之下千祈唔好遞交有版權嘅作品!</strong>',
+'longpagewarning' => "<strong>警告:呢一頁有 $1 kilobytes 咁長;有啲瀏覽器可能會喺就離或者超過 32kb 編輯頁面會出現一啲問題。
+請考慮分割呢個頁面到細啲嘅小節。</strong>",
+'longpageerror' => "<strong>錯誤:你所遞交嘅文字係有 $1 kilobytes 咁長,
+係長過最大嘅 $2 kilobytes。儲唔到你遞交嘅文字。</strong>",
+'readonlywarning' => '<strong>錯誤:資料庫已經鎖上去做保定期保養,
+咁你係唔可以喺而家儲起你嘅編輯。你或者可以將文字儲落一個文字檔度供以後使用。</strong>',
+'protectedpagewarning' => "<strong>警告:呢版已經受到保護,有管理員權限嘅用戶先至可以改。</strong>",
+'semiprotectedpagewarning' => "'''注意:'''呢一頁已經鎖咗,只有已經註冊嘅用戶先至可以改。",
+'templatesused' => '喺呢一頁所用嘅模:',
+'templatesusedpreview' => '喺呢一次預覽所用嘅模:',
+'templatesusedsection' => '喺呢一小節所用嘅模:',
+'edittools' => '<!-- 喺呢度嘅文字會喺編輯框下面同埋上載表格中顯示。 -->',
+'nocreatetitle' => '頁面建立被限制',
+'nocreatetext' => '呢個網站已經限制咗起新版嘅能力。
+你可以番轉頭去編輯一啲已經存在嘅頁面,或者[[Special:Userlogin|登入或開個新戶口]]。',
+
+# "Undo" feature
+'undo-success' => '呢個編輯已經取消。請確認一下,跟住儲存下面嘅更改。',
+'undo-failure' => '呢個編輯唔能夠取消,由於同途中嘅編輯有衝突。',
+'undo-summary' => '取消由[[Special:Contributions/$2|$2]] ([[User talk:$2|對話]])所做嘅修訂 $1',
+
+# Account creation failure
+'cantcreateaccounttitle' => '唔可以開新戶口',
+'cantcreateaccounttext' => '由呢個IP地址 (<b>$1</b>) 嘅新戶口已經被封鎖。
+咁可能係你嘅學校或者網絡供應商 (ISP) 所用嘅 IP地址持續咁進行破壞。',
+
+# History pages
+#
+'revhistory' => '修改歷程',
+'viewpagelogs' => '睇呢頁嘅日誌',
+'nohistory' => '呢版冇歷史。',
+'revnotfound' => '搵唔到歷史',
+'revnotfoundtext' => "呢版無你要搵嗰個版本喎。
+唔該睇下條網址啱唔啱。",
+'loadhist' => '攞緊版嘅歷史',
+'currentrev' => '家下嘅版本',
+'revisionasof' => '喺$1嘅修訂',
+'revision-info' => '喺$1嘅修訂;修訂自$2',
+'previousrevision' => '←之前嘅修訂',
+'nextrevision' => '新啲嘅修訂→',
+'currentrevisionlink' => '家下嘅修訂版本',
+'cur' => '現時',
+'next' => '之後',
+'last' => '最後',
+'orig' => '原本',
+'histlegend' => '選擇唔同版本:響兩個唔同版本嘅圓框分別撳一下,再撳最底的「比較被選版本」掣以作比較。<br />
+說明:(現時)= 同現時修訂版本嘅差別,(先前)= 與前一個修訂版本嘅差別,M = 小修改。',
+'deletedrev' => '[刪除咗]',
+'histfirst' => '最早',
+'histlast' => '最近',
+'rev-deleted-comment' => '(評論已經移除咗)',
+'rev-deleted-user' => '(用戶名已經移除咗)',
+'rev-deleted-text-permission' => '<div class="mw-warning plainlinks">
+呢頁嘅修訂喺公共檔案庫中已經被洗咗。
+喺[{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} 刪除日誌]裏面可能會有更詳細嘅資料。
+</div>',
+'rev-deleted-text-view' => '<div class="mw-warning plainlinks">
+呢頁嘅修訂喺公共檔案庫中已經洗咗。
+作為一個喺呢個網站嘅管理員,你可以去睇吓佢;
+喺[{{fullurl:Special:Log/delete|page={{PAGENAMEE}}}} 刪除日誌]裏面可能會有更詳細嘅資料。
+</div>',
+#'rev-delundel' => '刪/反刪',
+'rev-delundel' => '顯示/隱藏',
+
+'history-feed-title' => '修訂歷史',
+'history-feed-description' => '響哩個wiki嘅哩一頁嘅修訂歷史',
+'history-feed-item-nocomment' => '$1 響 $2', # user at time
+'history-feed-empty' => '要求嘅頁面並唔存在。
+佢可能響哩個 wiki 度刪除咗或者改咗名。
+試吓[[Special:Search|響哩個wiki度搵]]有關新頁面嘅資料。',
+
+# Revision deletion
+#
+'revisiondelete' => '刪除/反刪除修訂',
+'revdelete-nooldid-title' => '無目標修訂',
+'revdelete-nooldid-text' => '你重未指定一個或多個修訂去進行呢個功能。',
+'revdelete-selected' => '揀[[:$1]]嘅修訂:',
+'revdelete-text' => "刪除咗嘅修訂係會仍然出現喺個頁面歷史度,
+但係佢哋嘅文字內容係唔可以供公眾瀏覽。
+
+其他喺呢一個wiki嘅管理員仍然可以睇已經隱藏咗嘅內容,
+同埋可以透過同一個介面去反刪除佢,除非網站營運者已經設定咗附加嘅限制。",
+'revdelete-legend' => '設定修訂限制:',
+'revdelete-hide-text' => '隱藏修訂嘅文字',
+'revdelete-hide-comment' => '隱藏編輯註解',
+'revdelete-hide-user' => '隱藏編輯者嘅用戶名/IP',
+'revdelete-hide-restricted' => '應用呢嘅限制至操作員同埋其他用戶',
+'revdelete-log' => '記錄註解:', // <-- Log Comment: ?
+'revdelete-submit' => '應用到已經選取嘅修訂',
+'revdelete-logentry' => '已經更改[[$1]]嘅修訂可見性',
+
+# Diffs
+#
+'difference' => '(修訂之間嘅差異)',
+'loadingrev' => '載入緊修訂嘅差異',
+'lineno' => "第$1行:",
+'editcurrent' => '編輯呢一頁嘅現時版本',
+'selectnewerversionfordiff' => '選擇一個新啲嘅版本做個比較',
+'selectolderversionfordiff' => '選擇一個舊啲嘅版本做個比較',
+'compareselectedversions' => '比較被選嘅版本',
+'editundo' => '復原',
+'diff-multi' => "(當中有$1次嘅修訂唔會顯示。)",
+
+# Search results
+#
+'searchresults' => '搵嘢結果',
+'searchresulttext' => "有關搵{{SITENAME}}嘅更多資料請參考[[Project:Searching|搵{{SITENAME}}]]。",
+'searchsubtitle' => "你利用'''[[:$1]]'''搵",
+'searchsubtitleinvalid' => "你利用'''$1'''搵",
+'badquery' => '錯誤嘅搵嘢內容格式',
+'badquerytext' => '我哋無法處理閣下嘅搵嘢內容。可能你試圖搵吓3個字元以下長度嘅字詞,
+噉樣嘅字詞目前係唔支援嘅。又或者你輸入嘅條件式唔啱,
+比如好似“fish and and scales”噉。請試吓搵過第二啲嘢啦。',
+'matchtotals' => "有$2個頁面嘅標題以及$3個頁面嘅正文匹配\"$1\"。",
+'noexactmatch' => "'''標題為\"$1\"嘅頁面重未有人開。''' 你可以而家[[:$1|開呢個新頁]]。",
+'titlematches' => '文章標題符合',
+'notitlematches' => '冇頁面嘅標題符合',
+'textmatches' => '頁面文字符合',
+'notextmatches' => '冇頁面文字符合',
+'prevn' => "前$1",
+'nextn' => "後$1",
+'viewprevnext' => "去睇 ($1) ($2) ($3).",
+'showingresults' => "自#<b>$2</b>起顯示最多<b>$1</b>個結果。",
+'showingresultsnum' => "自#<b>$2</b>起顯示<b>$3</b>個結果。",
+'nonefound' => "'''注意''':搵嘢結果為空通常係因為你搵嘅係\"have\"、
+\"from\"等太常用而唔會被索引入數據庫嘅詞,
+又或者係你指定咗太多嘅關鍵字(只有包含所有你指定嘅關鍵字嘅頁面先至會被搵到出嚟)。",
+'powersearch' => '搵嘢',
+'powersearchtext' => "喺以下嘅空間名度搵 :<br />$1<br />$2 彈去清單 &nbsp; $3 嘅搜尋 $9",
+'searchdisabled' => '{{SITENAME}}嘅搜尋功能已經關閉。你可以利用Google嚟搵。不過佢哋對{{SITENAME}}嘅索引可能唔係最新嘅。',
+
+'blanknamespace' => '(主)',
+
+# Preferences page
+#
+'preferences' => '喜好設定',
+'mypreferences' => '我嘅喜好設定',
+'prefsnologin' => '重未登入',
+'prefsnologintext' => "你一定要去[[Special:Userlogin|登入]]設定好用戶喜好值先。",
+'prefsreset' => '喜好設定已經從儲存空間中重設。',
+'qbsettings' => '快捷列',
+'changepassword' => '改密碼',
+'skin' => '皮',
+'math' => '數',
+'dateformat' => '日期格式',
+'datedefault' => '冇喜好',
+'datetime' => '日期同埋時間',
+'math_failure' => '語法拼砌失敗',
+'math_unknown_error' => '唔知錯乜',
+'math_unknown_function' => '唔知乜函數',
+'math_lexing_error' => 'lexing錯誤',
+'math_syntax_error' => '語法錯誤',
+'math_image_error' => 'PNG 轉換失敗;檢查latex、dvips、gs同埋convert係唔係已經正確咁樣安裝',
+'math_bad_tmpdir' => '唔能夠寫入或建立臨時數目錄',
+'math_bad_output' => '唔能夠寫入或建立輸出數目錄',
+'math_notexvc' => 'texvc 執行檔已經遺失;請睇睇 math/README 去較吓。',
+'prefs-personal' => '用戶簡介',
+'prefs-rc' => '最近更改',
+'prefs-watchlist' => '監視清單',
+'prefs-watchlist-days' => '監視清單嘅顯示日數:',
+'prefs-watchlist-edits' => '喺加強版監視清單度嘅顯示編輯數:',
+'prefs-misc' => '雜項',
+'saveprefs' => '儲存',
+'resetprefs' => '重設',
+'oldpassword' => '舊密碼:',
+'newpassword' => '新密碼:',
+'retypenew' => '打多次新密碼:',
+'textboxsize' => '編輯中',
+'rows' => '列:',
+'columns' => '行:',
+'searchresultshead' => '搵嘢',
+'resultsperpage' => '每頁顯示嘅擊中數:',
+'contextlines' => '每一擊顯示嘅行數:',
+'contextchars' => '每一行嘅字數:',
+'stubthreshold' => '楔位文章門檻:',
+'recentchangescount' => '最近更改中嘅標題數。',
+'savedprefs' => '你嘅喜好設定已經儲存。',
+'timezonelegend' => '時區',
+'timezonetext' => '你嘅本地時間同伺服器時間 (UTC) 之間嘅差,以鐘頭為單位。',
+'localtime' => '本地時間',
+'timezoneoffset' => '時間偏移¹',
+'servertime' => '伺機器時間',
+'guesstimezone' => '由瀏覽器填上',
+'allowemail' => '由其它用戶啟用電子郵件',
+'defaultns' => '預設喺呢啲空間名搵嘢:',
+'default' => '預設',
+'files' => '檔案',
+
+# User rights
+'userrights-lookup-user' => '管理用戶組',
+'userrights-user-editname' => '輸入一個用戶名:',
+'editusergroup' => '編輯用戶組',
+
+'userrights-editusergroup' => '編輯用戶組',
+'saveusergroups' => '儲存用戶組',
+'userrights-groupsmember' => '屬於:',
+'userrights-groupsavailable' => '可用嘅組:',
+'userrights-groupshelp' => '選擇你想畀用戶加入或移出嘅組。未選擇嘅組將唔會被改變。你可以用CTRL + 撳滑鼠左掣以取消已經選擇嘅一個組',
+
+# Groups
+#
+'group' => '組:',
+'group-bot' => '機械人',
+'group-sysop' => '操作員',
+'group-bureaucrat' => '事務員',
+'group-all' => '(全部)',
+
+'group-bot-member' => '機械人',
+'group-sysop-member' => '操作員',
+'group-bureaucrat-member' => '事務員',
+
+'grouppage-bot' => '{{ns:project}}:機械人',
+'grouppage-sysop' => '{{ns:project}}:管理員',
+'grouppage-bureaucrat' => '{{ns:project}}:事務員',
+
+# Recent changes
+#
+'changes' => '更改',
+'recentchanges' => '最近更改',
+'recentchangestext' => '追蹤對哩一個 wiki 嘅最後更改。',
+'rcnote' => "以下係響$3,近<strong>$2</strong>日嘅最後<strong>$1</strong>次修改。",
+'rcnotefrom' => "以下係自<b>$2</b>嘅更改(顯示到<b>$1</b>)。",
+'rclistfrom' => "顯示由$1嘅新更改",
+'rcshowhideminor' => '$1小編輯',
+'rcshowhidebots' => '$1機械人',
+'rcshowhideliu' => '$1登入咗嘅用戶',
+'rcshowhideanons' => '$1匿名用戶',
+'rcshowhidepatr' => '$1巡邏過嘅編輯',
+'rcshowhidemine' => '$1我嘅編輯',
+'rclinks' => "顯示最後$1次喺$2日內嘅更改<br />$3",
+'diff' => '差異',
+'hist' => '歷史',
+'hide' => '隱藏',
+'show' => '顯示',
+'minoreditletter' => 'm',
+'newpageletter' => 'N',
+'boteditletter' => 'b',
+'sectionlink' => '→',
+'number_of_watching_users_pageview' => '[$1位用戶監視]',
+'rc_categories' => '限定到分類(以"|"作分隔)',
+'rc_categories_any' => '任何',
+
+# Upload
+#
+'upload' => '上載檔案',
+'uploadbtn' => '上載檔案',
+'reupload' => '再上載',
+'reuploaddesc' => '返到去上載表格。',
+'uploadnologin' => '重未登入',
+'uploadnologintext' => "你必須先[[Special:Userlogin|登入]]去上載檔案。",
+'upload_directory_read_only' => '嗰個上載嘅目錄 ($1) 而家唔能夠被網頁伺服器寫入。',
+'uploaderror' => '上載錯誤',
+'uploadtext' => "用下面嘅表格嚟上載檔案,要睇或者搵嘢之前上載嘅圖像請去[[Special:Imagelist|已上載檔案一覽]],上載同刪除嘅動作會喺[[Special:Log/upload|上載日誌]]裏面記錄落嚟。
+
+如果要喺頁面度引入呢張圖像,可以使用以下方式嘅連結:
+'''<nowiki>[[{{ns:image}}:file.jpg]]</nowiki>''',
+'''<nowiki>[[{{ns:image}}:file.png|替代文字]]</nowiki>''' 或者用
+'''<nowiki>[[{{ns:media}}:file.ogg]]</nowiki>''' 直接連結到檔案。",
+'uploadlog' => 'upload log',
+'uploadlogpage' => '上載日誌',
+'uploadlogpagetext' => '以下係最近檔案上載嘅一覽表。',
+'filename' => '檔名',
+'filedesc' => '摘要',
+'fileuploadsummary' => '摘要:',
+'filestatus' => '版權狀態',
+'filesource' => '來源',
+'copyrightpage' => "Project:版權",
+'copyrightpagename' => "{{SITENAME}}版權",
+'uploadedfiles' => '上載檔案中',
+'ignorewarning' => '總要忽略警告同埋儲存檔案。',
+'ignorewarnings' => '忽略任何警告',
+'minlength' => '檔名必須最少要有三個字。',
+'illegalfilename' => '檔名「$1」含有頁面標題所唔允許嘅字。請試下改檔名再上載。',
+'badfilename' => '檔名已經更改成「$1」。',
+'badfiletype' => "「.$1」唔係建議使用嘅圖像檔案格式。",
+'largefile' => '建議檔案嘅大細唔好大過$1bytes,呢個檔案有$2bytes',
+'largefileserver' => '呢個檔案超過咗伺服器設定允許嘅大細。',
+'emptyfile' => '你上載嘅檔案似乎係空嘅。噉樣可能係因為你打錯咗個檔名。請檢查吓你係唔係真係要上載呢個檔案。',
+'fileexists' => '呢個檔名已經存在,如果您唔肯定係唔係要更改$1,請先檢查佢。',
+'fileexists-forbidden' => '呢個檔案嘅名已經存在;麻煩返轉去用第二個名嚟上載呢個檔案。[[Image:$1|thumb|center|$1]]',
+'fileexists-shared-forbidden' => '共享檔案庫入面已經有一個同名嘅檔案;麻煩返轉去用第二個名嚟上載呢個檔案。[[Image:$1|thumb|center|$1]]',
+'successfulupload' => '成功嘅上載',
+'fileuploaded' => "檔案「$1」上載成功。
+請跟住呢條連結:$2,去描述頁面度填寫檔案嘅有關資訊,
+比如佢嚟自邊度、幾時創建由邊個創建,以及你所知嘅所有其它關於佢嘅嘢。
+如果呢個係一張圖像,你可以噉樣插入佢:<tt><nowiki>[[Image:$1|thumb|描述]]</nowiki></tt>",
+'uploadwarning' => '上載警告',
+'savefile' => '儲存檔案',
+'uploadedimage' => "上載咗\"[[$1]]\"",
+'uploaddisabled' => '上載已停用',
+'uploaddisabledtext' => '呢個 wiki 嘅檔案上載已經停用。',
+'uploadscripted' => '呢個檔案包含可能會誤被瀏覽器解釋執行嘅 HTML 或 script 代碼。',
+'uploadcorrupt' => '呢個檔案已損壞或係用咗錯誤嘅副檔名。請檢查吓個檔案,然後再試下上載多次。',
+'uploadvirus' => '呢個檔案有病毒!詳情:$1',
+'sourcefilename' => '來源檔名',
+'destfilename' => '目標檔名',
+'watchthisupload' => '監視呢頁',
+'filewasdeleted' => '呢個檔案所使用嘅名曾經上載後,跟住就刪除咗。你應該響重新上載佢之前檢查吓$1。',
+'upload-proto-error' => '唔正確嘅協議',
+'upload-proto-error-text' => '遙遠上載需要一個以 <code>http://</code> 或者 <code>ftp://</code> 作為開頭嘅URL。',
+'upload-file-error' => '內部錯誤',
+'upload-file-error-text' => '當響伺服器度建立一個暫存檔時發生咗一個內部錯誤。請聯絡一位系統管理員。',
+'upload-misc-error' => '未知嘅上載錯誤',
+'upload-misc-error-text' => '響上載時發生咗未知嘅錯誤。請確認輸入咗嘅URL係可以訪問嘅,之後再試多一次。如果重有問題嘅話,請聯絡一位系統管理員。',
+'upload-curl-error6' => "唔可以到嗰個URL",
+'upload-curl-error6-text' => '輸入嘅URL唔能夠去到。請重新檢查個URL係正確嘅同埋個網站係已經上綫。',
+'upload-curl-error28' => '上載遇時',
+'upload-curl-error28-text' => '個網站用咗太多時間回應。請檢查個網站已經係上咗綫,等多一陣然後再試過。你可以響冇咁繁忙嘅時間再試。',
+
+'license' => '協議',
+'nolicense' => '未揀',
+'upload_source_url' => ' (一個正確嘅,公眾可到嘅URL)',
+'upload_source_file' => ' (你部電腦裏面嘅一個檔案)',
+
+# Image list
+#
+'imagelist' => '檔案清單',
+'imagelisttext' => "以下係'''$1'''個檔案'''$2'''排序嘅清單。",
+'imagelistforuser' => "只顯示$1上載嘅檔案。",
+'getimagelist' => '獲取檔案清單中',
+'ilsubmit' => '搵嘢',
+'showlast' => '顯示$2排序嘅最後$1個檔案。',
+'byname' => '以檔名',
+'bydate' => '以時間',
+'bysize' => '以大細',
+'imgdelete' => '刪除',
+'imgdesc' => '描述',
+'imgfile' => '檔案',
+'imglegend' => '說明:(描述)顯示/編輯檔案描述。',
+'imghistory' => '檔案歷史',
+'revertimg' => '回復',
+'deleteimg' => '刪除',
+'deleteimgcompletely' => '刪除呢個檔案嘅所有修改',
+'imghistlegend' => '說明:(現) = 呢個係目前嘅檔案,(刪除) = 刪除呢個舊版本,
+(回復) = 恢復到呢個舊版本。
+<br /><i>撳日期嚟睇喺嗰個日期上載嘅檔案。</i>',
+'imagelinks' => '連結',
+'linkstoimage' => '以下嘅頁面連結到呢個檔案:',
+'nolinkstoimage' => '冇個頁面連結到呢個檔案。', //(用原有講法嘅話中文會有歧異)
+'sharedupload' => '呢個檔案係共用嘅上載,可以喺其他計劃中使用。“', //shared upload”討論吓中文點譯好
+'shareduploadwiki' => '更多資訊請睇$1。',
+'shareduploadwiki-linktext' => '檔案描述頁面',
+'noimage' => '冇同名嘅檔案存在,你可以$1。',
+'noimage-linktext' => '上載佢',
+'uploadnewversion-linktext' => '上載呢個檔案嘅一個新版本',
+'imagelist_date' => '日期',
+'imagelist_name' => '名',
+'imagelist_user' => '用戶',
+'imagelist_size' => '大細 (bytes)',
+'imagelist_description' => '描述',
+'imagelist_search_for' => '搵圖像名:',
+
+# Mime search
+#
+'mimesearch' => 'MIME 搜尋',
+'mimetype' => 'MIME 類型:',
+'download' => '下載',
+
+# Unwatchedpages
+#
+'unwatchedpages' => '未監視嘅頁面',
+
+# List redirects
+'listredirects' => '彈嚟彈去一覽',
+
+# Unused templates
+'unusedtemplates' => '未用嘅模',
+'unusedtemplatestext' => '呢一頁列示喺template空間名未包括喺其它頁面嘅全部頁面。請記得喺刪除佢哋之前檢查其它連結到呢個模嘅頁面。',
+'unusedtemplateswlh' => '其它連結',
+
+# Random redirect
+'randomredirect' => '隨便彈',
+
+# Statistics
+#
+'statistics' => '統計',
+'sitestats' => '{{SITENAME}}嘅統計',
+'userstats' => '用戶統計',
+'sitestatstext' => "資料庫中而家有'''$1'''頁。
+其中包括咗「討論」頁、關於{{SITENAME}}嘅頁、好短嘅「楔位」
+文章、重新定向, 以及其他唔計入內容嘅頁。
+唔計非內容頁在內,則總共有'''$2'''頁可能會計入正規嘅內容。
+
+'''$8''' 個檔案已經上載。
+
+呢個Wiki喺建立以嚟,總共有'''$3'''次瀏覽,同埋'''$4'''次編輯。
+平均每個頁面有'''$5'''次瀏覽,同埋'''$6'''次編輯。
+
+[http://meta.wikimedia.org/wiki/Help:Job_queue job queue]嘅長度係'''$7'''。",
+'userstatstext' => "目前有'''$1'''個註冊用戶,其中有'''$2'''人(即'''$4%''')係$5。",
+'statistics-mostpopular' => '最多人睇嘅頁',
+
+'disambiguations' => '分流(一辭多義辨別)頁',
+'disambiguationspage' => 'Template:disambig',
+'disambiguationstext' => "以下呢啲頁面連結去一個<i>分流頁</i>。佢哋先至應該指去正確嘅主題。<br />如果一個頁面連結自$1,噉就會當佢係分流頁。<br />其它空間名嘅連結<i>唔會</i>列到喺呢度。",
+
+'doubleredirects' => '雙重跳轉',
+'doubleredirectstext' => "每一行包括指去第一個同第二個跳轉嘅連結,以及第二個跳轉嘅首行文字。呢行文字通常畀出咗第一個跳轉應該指去嘅嗰個「真正」嘅目標頁面",
+
+'brokenredirects' => '破碎嘅跳轉',
+'brokenredirectstext' => '以下嘅跳轉係指向唔存在嘅頁面:',
+
+
+# Miscellaneous special pages
+#
+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
+'ncategories' => '$1 個分類',
+'nlinks' => '$1 條連結',
+'nmembers' => '$1 位成員',
+'nrevisions' => '$1 次修訂',
+'nviews' => '$1 次瀏覽',
+
+'lonelypages' => '孤立咗嘅頁面',
+'lonelypagestext' => '以下嘅面頁係響呢個wiki度未有連結到其它頁面。',
+'uncategorizedpages' => '未有分類嘅頁面',
+'uncategorizedcategories' => '未有分類嘅分類',
+'uncategorizedimages' => '未有分類嘅圖像',
+'unusedcategories' => '未用嘅分類',
+'unusedimages' => '未用嘅檔案',
+'popularpages' => '受歡迎嘅頁面',
+'wantedcategories' => '被徵求嘅分類',
+'wantedpages' => '被徵求嘅頁面',
+'mostlinked' => '有最多連結嘅頁面',
+'mostlinkedcategories' => '有最多連結嘅分類',
+'mostcategories' => '有最多分類嘅面頁',
+'mostimages' => '有最多連結嘅圖像',
+'mostrevisions' => '有最多修改嘅文章',
+'allpages' => '所有頁面',
+'prefixindex' => '前綴索引',
+'randompage' => '隨機文章',
+'shortpages' => '短頁',
+'longpages' => '長頁',
+'deadendpages' => '掘頭頁',
+'deadendpagestext' => '以下嘅面頁響呢個wiki度連結到其它頁面。',
+'listusers' => '用戶一覽',
+'specialpages' => '特別頁',
+'spheading' => '所有用戶嘅特別頁',
+'restrictedpheading' => '有限制嘅特別頁',
+'recentchangeslinked' => '連結頁嘅更改',
+'rclsub' => "(由\"$1\"已經連結嘅頁面)",
+'newpages' => '新頁面',
+'newpages-username' => '用戶名:',
+'ancientpages' => '舊頁面',
+'intl' => '誇語言連結',
+'move' => '移動',
+'movethispage' => '移動呢一頁',
+'unusedimagestext' => '<p>請留意其它嘅網站會用一個直接嘅URL連結到一幅圖像,
+因此喺呢度用緊嘅圖像可能會仍然喺呢度列示。</p>',
+'unusedcategoriestext' => '以下現存分類頁面存在,但未有其它嘅頁面或者分類去用佢哋。',
+
+# Book sources
+'booksources' => '書籍來源',
+'booksources-search-legend' => '搵書源',
+'booksources-isbn' => 'ISBN:',
+'booksources-go' => '去',
+'booksources-text' => '以下嘅連結清單列出其它一啲賣新書同二手書嘅網站,
+可能可以提供到有關你想搵嘅書嘅更多資料:',
+
+'categoriespagetext' => '喺呢個 wiki 中存在住以下嘅分類。',
+'data' => '資料',
+'userrights' => '用戶權限管理',
+'groups' => '用戶組',
+'isbn' => 'ISBN',
+'alphaindexline' => "$1到$2",
+'version' => '版本',
+'log' => '日誌',
+'alllogstext' => '上載、刪除、保護、封鎖、系統操作 (sysop) 日誌嘅綜合顯示。
+你可以選擇一個日誌類型、用戶名、或者受影響嘅頁面,嚟縮窄顯示嘅範圍。',
+'logempty' => '日誌中冇符合嘅項目。',
+
+
+# Special:Allpages
+'nextpage' => '下一頁 ($1)',
+'prevpage' => '上一頁 ($1)',
+'allpagesfrom' => '顯示以下位置開始嘅頁面:',
+'allarticles' => '所有文章',
+'allinnamespace' => '所有頁面(喺$1空間名入面)', //“namespace”大陸講法係“名稱空間
+'allnotinnamespace' => '所有頁面(唔喺$1空間名入面)',
+'allpagesprev' => '上一頁',
+'allpagesnext' => '下一頁',
+'allpagessubmit' => '去搵',
+'allpagesprefix' => '用以下開頭嘅頁面:',
+'allpagesbadtitle' => '提供嘅頁面名無效,又或者有一個跨語言或跨wiki嘅字頭。佢可能包括一個或多個字係唔可以用響標題度嘅。',
+
+# Special:Listusers
+'listusersfrom' => '顯示由呢個字開始嘅用戶:',
+
+# Email this user
+#
+'mailnologin' => '冇傳送地址',
+'mailnologintext' => "你一定要[[Special:Userlogin|登入咗]]
+同埋喺你嘅[[Special:Preferences|喜好設定]]度有個有效嘅電郵地址
+先可以傳送電郵畀其他用戶。",
+'emailuser' => '發電郵畀呢位用戶',
+'emailpage' => '發電郵畀用戶',
+'emailpagetext' => '如果呢位用戶已經喺佢嘅用戶使用偏好入邊填咗個合法嘅電郵地址,以下表格會發送單單一條訊息。
+你喺你嘅用戶喜好設定入面填寫嘅電郵地址會出現喺呢封電郵「由」嘅地址度,以便收件人可以回覆到。',
+'usermailererror' => '目標郵件地址返回錯誤:',
+'defemailsubject' => "{{SITENAME}} 電郵",
+'noemailtitle' => '無電郵地址',
+'noemailtext' => '呢個用戶重指指定一個有效嘅電郵電址,
+又或者佢揀咗唔收其他用戶畀佢嘅電郵。',
+'emailfrom' => '由',
+'emailto' => '到',
+'emailsubject' => '主題',
+'emailmessage' => '信息',
+'emailsend' => '傳送',
+'emailccme' => '傳送一個我嘅信息電郵畀我。',
+'emailccsubject' => '複製你嘅信息到 $1: $2',
+'emailsent' => '電郵已傳送',
+'emailsenttext' => '你嘅電郵訊息已傳送。',
+
+# Watchlist
+'watchlist' => '我張監視清單',
+'watchlistfor' => "(用戶「'''$1'''」嘅監視清單)",
+'nowatchlist' => '你嘅監視清單度並冇任何項目。',
+'watchlistanontext' => '請先$1去睇或者改響你監視清單度嘅項目。',
+'watchlistcount' => "'''你有 $1 個項目喺你嘅監視清單度,包括埋對話頁。'''",
+'clearwatchlist' => '清除監視清單',
+'watchlistcleartext' => '你係咪肯定想移除全部嘅項目?',
+'watchlistclearbutton' => '清除監視清單',
+'watchlistcleardone' => '你嘅監視清單已經啱啱清除咗。 $1 個項目已經被移除。',
+'watchnologin' => '未登入',
+'watchnologintext' => '您必須先[[Special:Userlogin|登入]]至可以更改您嘅監視清單。',
+'addedwatch' => '加到監視清單度',
+'addedwatchtext' => "頁面「[[:$1]]」已加入到你嘅[[Special:Watchlist|監視清單]]度。
+呢個頁面以及佢個討論頁以後嘅修改都會列喺嗰度,
+佢喺[[Special:Recentchanges|最近更改清單]]度會以'''粗體'''顯示,等你可以容易啲睇到佢。
+
+如果以後你要喺監視清單度刪除佢嘅話,就喺側邊欄度點「唔使監視」。",
+'removedwatch' => '已經由監視清單中刪除',
+'removedwatchtext' => "頁面「[[:$1]]」已經喺你嘅監視清單中刪除。",
+'watch' => '監視',
+'watchthispage' => '監視呢頁',
+'unwatch' => '唔使監視',
+'unwatchthispage' => '停止監視',
+'notanarticle' => '唔係一個內容頁',
+'watchnochange' => '響顯示嘅時間之內,您所監視嘅頁面並無任何嘅更改。',
+'watchdetails' => '* 唔計討論頁,你個監視清單有 $1 版。
+* [[Special:Watchlist/edit|顯示同修改你個監視清單]]
+* [[Special:Watchlist/clear|移除全部嘅頁面]]',
+'wlheader-enotif' => "* 電子郵件通知已經啟用。",
+'wlheader-showupdated' => "* '''粗體字'''嘅頁面係您響上次嚟完之後被人更改過嘅頁面",
+'watchmethod-recent' => '正檢查最近被編輯嘅監視頁面',
+'watchmethod-list' => '正檢查被監視頁面嘅最近編輯',
+'removechecked' => '將剔咗嘅項目由監視清單中刪除',
+'watchlistcontains' => "你嘅監視清單裏面有$1頁。",
+'watcheditlist' => '呢度係以字母順序排列你所監視嘅內容頁嘅一覽表。要喺你個監視清單中移除某個頁面,只需要選擇嗰一頁嘅複選框,然後撳屏幕底部嘅「移除已複選嘅頁面」按鈕。(移除內容頁亦都會一併將佢相應嘅對話頁移除,相反嘅亦都係咁)。',
+'removingchecked' => '刪除緊已經請求嘅項目出監視清單...',
+'couldntremove' => "項目'$1'刪除唔到...",
+'iteminvalidname' => "項目'$1'出錯,無效嘅名稱...",
+'wlnote' => '以下係最近<b>$2</b>小時入面嘅最新$1次修改。',
+'wlshowlast' => '顯示最近 $1 個鐘 $2 日 $3 嘅修改',
+'wlsaved' => '呢個係您嘅監視清單入面儲存咗嘅版本。',
+'watchlist-show-bots' => '顯示機械人嘅編輯',
+'watchlist-hide-bots' => '隱藏機械人嘅編輯',
+'watchlist-show-own' => '顯示我嘅編輯',
+'watchlist-hide-own' => '隱藏我嘅編輯',
+'watchlist-show-minor' => '顯示小修改',
+'watchlist-hide-minor' => '隱藏小修改',
+'wldone' => '完成。',
+# Displayed when you click the "watch" button and it's in the process of watching
+'watching' => '監視緊...',
+'unwatching' => '唔再監視緊...',
+
+'enotif_mailer' => '{{SITENAME}}通知郵遞員',
+'enotif_reset' => '將所有頁面標成已視察',
+'enotif_newpagetext' => '呢個係一個新頁面。',
+'changed' => '已修改',
+'created' => '已建立',
+'enotif_subject' => '{{SITENAME}}嘅頁面$PAGETITLE已由$PAGEEDITOR$CHANGEDORCREATED',
+'enotif_lastvisited' => '你上次視察以嚟嘅修改請睇$1。',
+'enotif_body' => '$WATCHINGUSERNAME先生/小姐你好,
+
+{{SITENAME}}嘅頁面$PAGETITLE已經由$PAGEEDITOR喺$PAGEEDITDATE$CHANGEDORCREATED過,現時版本請睇$PAGETITLE_URL。
+
+$NEWPAGE
+
+編輯者留低嘅摘要:$PAGESUMMARY $PAGEMINOREDIT
+
+連絡呢個編輯者:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+今後唔會再有進一步嘅通知,除非你再次訪問呢個頁面。你亦都可以喺你嘅監視清單度復位所有監視頁面嘅通知標誌。
+
+ {{SITENAME}}通知系統敬上
+
+--
+要修改你嘅監視清單設定,請睇{{fullurl:{{ns:special}}:Watchlist/edit}}
+
+回饋及更多幫助:
+{{fullurl:{{ns:help}}:目錄}}',
+
+# Delete/protect/revert
+#
+'deletepage' => '刪除頁面',
+'confirm' => '確認',
+'excontent' => "內容係:'$1'",
+'excontentauthor' => "內容係:'$1' (而且唯一嘅貢獻者係'[[Special:Contributions/$2|$2]]')",
+'exbeforeblank' => "喺清空之前嘅內容係:'$1'",
+'exblank' => '頁面之前係空嘅',
+'confirmdelete' => '確認刪除',
+'deletesub' => "(\"$1\"刪除中)",
+'historywarning' => '警告:你要刪除嘅頁面有歷史版本:',
+'confirmdeletetext' => "你準備從資料庫度徹底刪除一個頁面或者圖像,包括佢嘅所有歷史版本。
+請確認你打算噉做,而且你知道後果係點,加上確認你噉做冇違反到[[Project:Policy]]。",
+'actioncomplete' => '操作完成',
+'deletedtext' => "\"$1\"已經刪除。
+最近嘅刪除記錄請睇$2。",
+'deletedarticle' => "已經刪除\"[[$1]]\"",
+'dellogpage' => '刪除日誌',
+'dellogpagetext' => '以下係最近嘅刪除清單。',
+'deletionlog' => '刪除日誌',
+'reverted' => '恢復到先前嘅修訂',
+'deletecomment' => '刪除原因',
+'imagereverted' => '恢復到先前版本嘅操作已經成功。',
+'rollback' => '還原修改',
+'rollback_short' => '還原',
+'rollbacklink' => '還原',
+'rollbackfailed' => '還原失敗',
+'cantrollback' => '還原唔到;上一位貢獻者係唯一修改過呢版嘅人。',
+'alreadyrolled' => "無法反轉[[User:$2|$2]]([[User talk:$2|留言]])對[[:$1]]嘅最後編輯;
+有人已經修改過或者反轉咗呢個頁面。
+
+上次編輯係由[[User:$3|$3]]([[User talk:$3|留言]])做嘅。",
+# only shown if there is an edit comment
+'editcomment' => "編輯摘要係:\"<i>$1</i>\".",
+'revertpage' => "已經反轉由[[Special:Contributions/$2|$2]]([[User talk:$2|對話]])所寫嘅編輯,恢復到[[User:$1|$1]]嘅最後版本。",
+'sessionfailure' => '你嘅登入會話 (session) 好似有啲問題;
+為咗防止會話劫持,呢個操作已經取消。
+請撳「返轉頭」然後重新載入你嚟自嘅頁面,然後再試吓啦。',
+'protectlogpage' => '保護日誌',
+'protectlogtext' => "下面係一個保護同埋解除保護頁面嘅一覽表。",
+'protectedarticle' => '已經保護 "[[$1]]"',
+'unprotectedarticle' => '已經唔再保護 "[[$1]]"',
+'protectsub' => '(保護緊「$1」)',
+'confirmprotecttext' => '你係唔係真係要保護呢個頁面?',
+'confirmprotect' => '確認保護',
+'protectmoveonly' => '只保護頁面嘅移動',
+'protectcomment' => '保護原因',
+'unprotectsub' =>"(解除緊\"$1\"嘅保護)",
+'confirmunprotecttext' => '你係唔係真係要解除呢個頁面嘅保護?',
+'confirmunprotect' => '確認解除保護',
+'unprotectcomment' => '解除保護嘅原因',
+'protect-unchain' => '解除移動權限嘅鎖定',
+'protect-text' => '你可以喺呢度睇到同修改頁面<strong>$1</strong>嘅保護等級。',
+'protect-viewtext' => '你嘅戶口並冇修改頁面保護等級嘅權力,呢個係頁面<strong>$1</strong>嘅現時設定:',
+'protect-default' => '(預設)',
+'protect-level-autoconfirmed' => '限制未註冊嘅用戶',
+'protect-level-sysop' => '只限操作員',
+
+# restrictions (nouns)
+'restriction-edit' => '編輯',
+'restriction-move' => '移動',
+
+
+# Undelete
+# 以下翻譯有啲混亂,revision有時指修改嘅動作,有時指修改後嘅嗰個版本,所以翻譯嘅時候好難跟返原文。
+'undelete' => '去睇刪除咗嘅頁面',
+'undeletepage' => '去睇同恢復刪除咗嘅頁面',
+'viewdeletedpage' => '去睇被刪除咗嘅頁面',
+'undeletepagetext' => '以下頁面已經刪除,但係重喺檔庫度可以恢復。
+檔案庫可能會定時清理。',
+'undeleteextrahelp' => "要恢復成個頁面,唔好剔任何嘅核選盒,再撳'''''恢復'''''。
+要恢復已經選擇咗嘅修訂,將要恢復代表有關修訂嘅核選盒剔上,再撳'''''恢復'''''。撳'''''重設'''''會清除註解文字同埋全部嘅核選盒。",
+'undeletearticle' => '恢復刪除咗嘅頁面',
+'undeleterevisions' => "$1嘅修改都已經存檔",
+'undeleterevision-missing' => "唔正確或者遺失咗修訂。你可能有一個壞連結,
+或者嗰個修訂已經響存檔度恢復咗或者刪除咗。",
+'undeletehistory' => '如果你恢復呢個頁面,佢嘅所有修改歷史都會恢復返到嗰篇頁面嘅歷史度。
+如果喺佢刪除之後又新開咗同名嘅頁面,你恢復嘅修改歷史會顯示喺先前歷史度,
+新頁面而家嘅修改唔會自動覆蓋咗去。',
+'undeletehistorynoadmin' => '呢篇文已經刪咗。刪除嘅原因喺下面嘅摘要度,
+連同重有刪除之前編輯過呢個頁面嘅用戶嘅詳細資料。
+所刪除嘅版本嘅實際內容得管理員可以睇到。',
+'undeleterevision' => "已經刪除咗$1嘅修訂",
+'undeletebtn' => '恢復',
+'undeletereset' => '重設',
+'undeletecomment' => '註解:',
+'undeletedarticle' => "已經恢復咗\"[[$1]]\"",
+'undeletedrevisions' => "$1個修訂已經恢復",
+'undeletedrevisions-files' => "$1個修訂同$2個檔案已經恢復",
+'undeletedfiles' => "$1個檔案已經恢復",
+'cannotundelete' => '反刪除失敗;可能有其他人已經反刪除嗰一頁。',
+'undeletedpage' => "<big>'''$1已經成功恢復'''</big>
+
+最近嘅刪除同恢復記錄請睇[[Special:Log/delete]]。",
+
+# Namespace form on various pages
+'namespace' => '空間名:',
+'invert' => '反選',
+
+# Contributions
+#
+'contributions' => '用戶貢獻',
+'mycontris' => '我嘅貢獻',
+'contribsub' => "$1嘅貢獻",
+'nocontribs' => '搵唔到符合呢啲條件嘅修改。',
+'ucnote' => "以下係呢個用戶喺最近<b>$2</b>日內嘅最後<b>$1</b>次修改。",
+'uclinks' => "睇吓最近$2日;睇吓最近嘅$1次修改。",
+'uctop' => ' (最頂)' ,
+'newbies' => '新手',
+
+'sp-newimages-showfrom' => '顯示由$1嘅新圖像',
+
+'sp-contributions-newest' => '最新',
+'sp-contributions-oldest' => '最舊',
+'sp-contributions-newer' => '較新嘅$1次',
+'sp-contributions-older' => '較舊嘅$1次',
+'sp-contributions-newbies-sub' => '新手嘅',
+
+# What links here
+#
+'whatlinkshere' => '有乜嘢連結到呢度',
+'notargettitle' => '冇目標',
+'notargettext' => '你冇指定到呢個功能要用喺嘅對象頁面或用戶。', //會唔會好拗口?所以我唔中意啲乜野保持原文可逆嘅原則,保持原意兼且睇得舒服先至係讀者嘅最大需要
+'linklistsub' => '(連結一覽)',
+'linkshere' => "以下頁面連結到'''[[:$1]]''':",
+'nolinkshere' => "無頁面連結到'''[[:$1]]'''。",
+'isredirect' => '跳轉頁',
+'istemplate' => '包含',
+
+# Block/unblock IP
+#
+'blockip' => '封鎖用戶',
+'blockiptext' => "使用以下嘅表格嚟去阻止指定嘅IP地址或用戶名嘅寫權限。
+僅當僅當為咗避免文章畀人惡意破壞嘅時候先可以使用,而且唔可以違反[[Project:Policy|政策]]。
+喺下面填寫阻止嘅確切原因(比如:引用咗某啲已經破壞咗嘅頁面)。",
+'ipaddress' => 'IP地址',
+'ipadressorusername' => 'IP地址或用戶名',
+'ipbexpiry' => '期限',
+'ipbreason' => '原因',
+'ipbanononly' => '只係封匿名用戶',
+'ipbcreateaccount' => '防止開新戶口',
+'ipbenableautoblock' => '自動封鎖呢個用戶上次用過嘅IP地址,同埋佢地做過編輯嘅地址',
+'ipbsubmit' => '封鎖呢位用戶',
+'ipbother' => '其它時間',
+'ipboptions' => '兩個鐘頭:2 hours,一日:1 day,三日:3 days,一個禮拜:1 week,兩個禮拜:2 weeks,一個月:1 month,三個月:3 months,六個月:6 months,一年:1 year,終身:infinite',
+'ipbotheroption' => '其它',
+'badipaddress' => '無效嘅IP地址',
+'blockipsuccesssub' => '封鎖成功',
+'blockipsuccesstext' => '[[{{ns:Special}}:Contributions/$1|$1]]已經封鎖。
+<br />去[[{{ns:Special}}:Ipblocklist|IP封鎖清單]]睇返封鎖名單。',
+'unblockip' => '解封用戶',
+'unblockiptext' => '使用以下表格恢復之前阻止嘅某個IP地址或者某個用戶名嘅寫權限。',
+'ipusubmit' => '解封呢個地址',
+'unblocked' => '"[[User:$1|$1]]"已經解封',
+'ipblocklist' => 'IP地址同用戶名阻止名單',
+'blocklistline' => "$1,$2已經封鎖咗$3($4)",
+'infiniteblock' => '不設期限',
+'expiringblock' => '$1 期滿',
+'anononlyblock' => '只限匿名',
+'noautoblockblock' => '自動封鎖已經停用',
+'createaccountblock' => '封咗開新戶口',
+'ipblocklistempty' => '封鎖名單係空嘅。',
+'blocklink' => '封',
+'unblocklink' => '解封',
+'contribslink' => '貢獻',
+'autoblocker' => '已經自動封鎖,因為你嘅IP地址冇幾耐之前"[[User:$1|$1]]"使用過。$1\嘅封鎖原因係: 「\'\'\'$2\'\'\'」',
+'blocklogpage' => '封鎖日誌',
+'blocklogentry' => '已封鎖"[[$1]]",到期時間為$2',
+'blocklogtext' => '呢個係封鎖同埋解封動作嘅日誌。自動封鎖IP地址嘅動作冇列出嚟。去[[Special:Ipblocklist|IP封鎖名單]]睇現時生效嘅封鎖名單',
+'unblocklogentry' => '已經解封$1',
+'range_block_disabled' => '操作員嘅建立範圍封鎖已經停用。',
+'ipb_expiry_invalid' => '無效嘅期限。',
+'ipb_already_blocked' => '"$1"已經封鎖咗',
+'ip_range_invalid' => '無效嘅IP範圍',
+'proxyblocker' => 'Proxy 封鎖器',
+'ipb_cant_unblock' => '錯誤:搵唔到封鎖ID$1。可能已經解封咗。',
+'proxyblockreason' => '你嘅IP係一個公開(指任何人都可以用,無須身份認證?)嘅代理地址,因此被封鎖。請聯絡你嘅Internet服務提供商或技術支援,向佢哋報告呢個嚴重嘅安全問題。',
+'proxyblocksuccess' => '完成。',
+'sorbs' => 'DNSBL',
+'sorbsreason' => '你嘅IP地址已經畀響呢個網站度用嘅DNSBL列咗做公開代理。',
+'sorbs_create_account_reason' => '你嘅IP地址已經畀響呢個網站度用嘅DNSBL列咗做公開代理。你唔可以開新戶口。',
+
+
+# Developer tools
+#
+'lockdb' => '鎖定資料庫',
+'unlockdb' => '解除鎖定資料庫',
+'lockdbtext' => '鎖定資料庫會暫停所有用戶去編輯頁面、更改佢哋嘅喜好設定、
+編輯佢哋嘅監視清單嘅能力,同埋其它需要喺資料庫中更改嘅動作。
+請確認你的確係需要要噉做,喺你嘅維護工作完成之後會解除鎖定資料庫。',
+'unlockdbtext' => '解除鎖定資料庫會恢復所有用戶去編輯頁面、更改佢哋嘅喜好設定、
+編輯佢哋嘅監視清單嘅能力,同埋其它需要喺資料庫中更改嘅動作。
+請確認你的確係需要要噉做。',
+'unlockdbtext' => '解除資料庫鎖定以便其他用戶可以恢復進行編輯頁面、修改使用
+偏好、修改監視清單以及其他需要修改資料庫嘅操作。
+請確認你的而且確打算噉做。',
+'lockconfirm' => '係,我真係想去鎖定資料庫。',
+'unlockconfirm' => '係,我真係想去解除鎖定資料庫。',
+'lockbtn' => '鎖定資料庫',
+'unlockbtn' => '解除鎖定資料庫',
+'locknoconfirm' => '你未剔個確認框喎。',
+'lockdbsuccesssub' => '資料庫鎖定已經成功',
+'unlockdbsuccesssub' => '資料庫鎖定已成功移除',
+'lockdbsuccesstext' => '資料庫現已鎖定。
+<br />請一定要記得喺完成系統維護工作之後[[Special:Unlockdb|解除資料庫嘅鎖定]]。',
+'unlockdbsuccesstext' => '資料庫鎖定現已解除。',
+'lockfilenotwritable' => '資料庫封鎖檔案係唔可以寫入嘅。要鎖定或解鎖資料庫,係需要由網頁伺服器中寫入。',
+'databasenotlocked' => '資料庫而家冇鎖到。',
+
+# Make sysop
+'makesysoptitle' => '整一位用戶做操作員',
+'makesysoptext' => '呢一個表格係畀事務員用嘅,去轉普通嘅用戶到管理員。
+喺個框入面打用戶嘅名,然後撳個掣嚟設佢為管理員',
+'makesysopname' => '用戶嘅名:',
+'makesysopsubmit' => '整呢位用戶做一位操作員',
+'makesysopok' => "<b>用戶 \"$1\" 而家係一位操作員</b>",
+'makesysopfail' => "<b>用戶 \"$1\" 唔可以整做一位操作員。(你有冇正確噉樣輸入正確嘅名?)</b>",
+'setbureaucratflag' => '設定事務員旗',
+'rightslog' => '用戶權限日誌',
+'rightslogtext' => '呢個係用戶權力嘅修改日誌。',
+'rightslogentry' => '已經將$1嘅組別從$2改到去$3',
+'rights' => '權力:',
+'set_user_rights' => '設置用戶權限',
+'user_rights_set' => "<b>用戶「$1」嘅權限已經更新</b>",
+'set_rights_fail' => "<b>無法設定用戶「$1」嘅權力。(你有冇打啱個名?)</b>",
+'makesysop' => '整一位用戶做操作員',
+'already_sysop' => '呢位用戶已經係一位管理員',
+'already_bureaucrat' => '呢位用戶已經係一位事務員',
+'rightsnone' => '(無)',
+
+# Move page
+#
+'movepage' => '搬頁',
+'movepagetext' => '使用以下表格會將頁面改名,兼且連同搬埋佢嘅歷史過去。
+舊標題會變成指去新標題嘅跳轉頁。
+指去舊標題嘅連結唔會修改到;請務必要檢查吓有冇雙重跳轉或者死跳轉(嘅情況發生)。
+你有責任確保啲連結依然指去佢哋應該指去嘅地方。
+
+注意如果已經有一個同個新名同名嘅頁面,噉呢個頁面係搬\'\'\'唔到\'\'\'嘅,除非嗰個同名嘅頁面係空嘅或者佢係一個跳轉頁,兼且要之前冇編輯過(冇編輯歷史)先得。噉即係講萬一你搞錯咗,你可以將呢個頁面改返去佢改之前噉,你唔可以覆蓋一個現有嘅頁面。
+
+<b>警告!</b>
+噉樣對於一個好多人經過嘅頁面嚟講可能係一個好大嘅同埋出人意表嘅修改;
+請你喺行動之前確認你清楚噉做嘅後果。',
+'movepagetalktext' => '相應嘅討論頁會連同佢一齊自動搬過去,\'\'\'除非\'\'\':
+*新嘅頁面名下面已經有咗一個非空嘅討論頁,又或者
+*你唔剔下面個框。
+
+喺呢啲情況下,需要嘅話你唯有手動搬同合併個頁面。',
+'movearticle' => '搬頁',
+'movenologin' => '未登入',
+'movenologintext' => "你要係註冊用戶而且要[[Special:Userlogin|登入]]咗先可以搬頁",
+'newtitle' => '到新標題',
+'movepagebtn' => '搬頁',
+'pagemovedsub' => '搬頁成功',
+'pagemovedtext' => "頁面\"[[$1]]\"已經搬到去\"[[$2]]\"。",
+'articleexists' => '已經有頁面叫嗰個名,或者你揀嘅名唔合法。
+請揀過第二個名。',
+'talkexists' => "'''頁面本身已經成功搬咗,但係個討論頁搬唔到,因為已經有一個同名嘅討論頁。請手工合併佢哋。'''",
+'movedto' => '搬去',
+'movetalk' => '搬相應嘅討論頁',
+'talkpagemoved' => '相應嘅討論頁已經搬咗。',
+'talkpagenotmoved' => '相應嘅討論頁<strong>冇</strong>搬到。',
+'1movedto2' => '[[$1]]搬到去[[$2]]',
+'1movedto2_redir' => '[[$1]]通過跳轉搬到去[[$2]]',
+'movelogpage' => '移動日誌',
+'movelogpagetext' => '以下係搬過嘅頁面清單。',
+'movereason' => '原因',
+'revertmove' => '恢復',
+#下面個“and”唔確定表示並列定係表示先後(係先刪除,移動,再恢復舊頁歷史)
+'delete_and_move' => '刪除並移動',
+'delete_and_move_text' =>
+'==需要刪除==
+
+目標文章「[[$1]]」已經存在。你要唔要刪咗佢空個位出嚟畀個搬文動作?',
+'delete_and_move_confirm' => '好,刪咗嗰個頁面',
+'delete_and_move_reason' => '已經刪咗嚟畀位畀個搬文動作',
+'selfmove' => "原始標題同目的標題一樣;唔可以將個頁面搬返去自己度。",
+'immobile_namespace' => "來源或目的標題屬於特別類型;唔可以將頁面搬自或搬去嗰個空間名。",
+
+# Export
+
+'export' => '倒出/導出/匯出(Export)頁面',
+'exporttext' => '你可以倒出文字、編輯某個頁面、編輯封裝(wrap)喺一啲XML度嘅一組頁面。
+呢啲嘢可以用MediaWiki透過 Special:Import 頁倒入去其他wiki度。
+
+要倒出頁面嘅話,就喺下面嘅文字框度打標題名,一行一個標題,
+然後揀你係要現時版本加上所有嘅舊版本同歷史,定係淨係要現時版本同最後編輯嘅相關資訊。
+
+喺後面嗰種情況下,你亦都可以用一個連結,例如[[{{ns:Special}}:Export/{{int:mainpage}}]]對頁面{{int:mainpage}}。',
+'exportcuronly' => '淨係包括而家嘅修訂版本,唔包括完整歷史',
+'exportnohistory' => "----
+'''注意:'''因為性能嘅原因,已經停用禁止咗使用呢個表格倒出頁面嘅完整歷史",
+'export-submit' => '倒出/導出/匯出',
+
+# Namespace 8 related
+
+'allmessages' => '系統信息',
+'allmessagesname' => '名稱',
+'allmessagesdefault' => '預設文字',
+'allmessagescurrent' => '現時文字',
+'allmessagestext' => '以下係 MediaWiki 空間名入邊現有系統訊息嘅清單。',
+'allmessagesnotsupportedUI' => '呢個網站嘅Special:AllMessages唔支持你現時嘅介面語言<b>$1</b>。',
+'allmessagesnotsupportedDB' => '唔可以用\'\'\'Special:AllMessages\'\'\',因為\'\'\'$wgUseDatabaseMessages\'\'\'已經閂咗。',
+'allmessagesfilter' => '訊息名過濾(器):',
+'allmessagesmodified' => '只顯示修改過嘅',
+
+
+# Thumbnails
+
+'thumbnail-more' => '放大',
+'missingimage' => '<b>唔見張圖</b><br /><i>$1</i>',
+'filemissing' => '唔見個檔案',
+'thumbnail_error' => '整唔到縮圖: $1',
+
+# Special:Import
+'import' => '倒入頁面',
+# 未用過Transwiki,唔知係乜,呢段等第二個嚟翻^c^ (Transwiki係需要轉載原修訂歷史到另外一個計劃中,e.g.百科&rarr;詞典)
+'importinterwiki' => 'Transwiki 倒入',
+'import-interwiki-text' => '揀一個 wiki 同埋一頁去倒入。
+修訂日期同編輯者會被保存落嚟。
+所有 transwiki 嘅倒入動作會響[[Special:Log/import|倒入日誌]]度記錄落嚟。',
+'import-interwiki-history' => '複製呢一頁所有嘅歷史版本',
+'import-interwiki-submit' => '倒入',
+'import-interwiki-namespace' => '轉移頁面到空間名:',
+'importtext' => '請由原 wiki 嘅 Special:Export 工具匯出成檔案,儲存喺你個磁碟度,然後再上載到呢度。',
+'importstart' => "倒入頁面中...",
+'import-revision-count' => '$1次修訂',
+'importnopages' => "冇頁面去倒入。",
+'importfailed' => "倒入失敗:$1",
+'importunknownsource' => "不明嘅倒入來源類型",
+'importcantopen' => "唔能夠開個倒入檔案",
+'importbadinterwiki' => "壞嘅跨 wiki 連結",
+'importnotext' => '空白或者唔係文字',
+'importsuccess' => '已經成功倒入!',
+'importhistoryconflict' => '存在有衝突嘅歷史版本(之前可能曾經倒入過呢頁)',
+'importnosources' => '未定義 transwiki 嘅匯入來源,同埋歷史嘅直接上載已經停用。',
+'importnofile' => '冇上載到任何要倒入嘅檔案。',
+'importuploaderror' => '上載要倒入嘅文件失敗;可能文件超過咗允許嘅上載大細。',
+
+# import log
+'importlogpage' => '倒入日誌',
+'importlogpagetext' => '管理員由其它嘅 wiki 倒入頁面同埋佢哋嘅編輯歷史記錄。',
+'import-logentry-upload' => '由檔案上載倒入咗 [[$1]]',
+'import-logentry-upload-detail' => '$1個修訂',
+'import-logentry-interwiki' => 'transwiki咗 $1',
+'import-logentry-interwiki-detail' => '由$2嘅$1個修訂',
+
+# Keyboard access keys for power users
+'accesskey-search' => 'f',
+'accesskey-minoredit' => 'i',
+'accesskey-save' => 's',
+'accesskey-preview' => 'p',
+'accesskey-diff' => 'v',
+'accesskey-compareselectedversions' => 'v',
+'accesskey-watch' => 'w',
+
+# tooltip help for some actions, most are in Monobook.js
+'tooltip-search' => '搵{{SITENAME}} [alt-f]',
+'tooltip-minoredit' => '標為細嘅修訂[alt-i]',
+'tooltip-save' => '保存你嘅更改[alt-s]',
+'tooltip-preview' => '預覽你嘅修改,請喺保存之前先預覽一次先![alt-p]',
+'tooltip-diff' => '顯示你對文章所作嘅修改[alt-v]',
+'tooltip-compareselectedversions' => '顯示該頁面兩個所選版本嘅唔同之處。[alt-v]',
+'tooltip-watch' => '將呢頁加到去你嘅監視清單度[alt-w]',
+
+# stylesheets
+'common.css' => '/* 響呢度放 CSS 碼去改成個網站嘅皮 */',
+'monobook.css' => '/* 響呢度放 CSS 碼去改用戶用嘅 Monobook 皮 */',
+
+# Metadata
+# 元數據(大陸)
+'nodublincore' => 'Dublin Core RDF metadata 已經喺呢一個伺服器上停用。',
+'nocreativecommons' => 'Creative Commons RDF metadata 已經喺呢一個伺服器上停用。',
+'notacceptable' => '呢個 wiki 伺服器唔能夠畀一個可以讀嘅資料畀個客。',
+
+# Attribution
+
+'anonymous' => '{{SITENAME}}嘅匿名用戶',
+'siteuser' => '{{SITENAME}}嘅用戶$1',
+'lastmodifiedatby' => '呢一頁最後響 $1 $2 畀 $3 修改。',
+'and' => '同埋',
+'othercontribs' => '以$1嘅作品為基礎。',
+'others' => '其他',
+'siteusers' => '{{SITENAME}}嘅用戶$1',
+'creditspage' => '頁面信譽', //Page credits
+'nocredits' => '呢一頁並無任何嘅信譽資料可以提供。',
+
+# Spam protection
+
+'spamprotectiontitle' => '隔垃圾器',
+'spamprotectiontext' => '隔垃圾器已經擋住咗你要儲存嘅頁面。噉可能係由指去外部網站嘅連結引起。',
+'spamprotectionmatch' => '以下係觸發我哋嘅反垃圾過濾器嘅文字:$1',
+'subcategorycount' => "呢個類別入邊有$1個細類別。",
+'categoryarticlecount' => "呢個類別入邊有$1篇文章。",
+'category-media-count' => "呢個類別入邊有$1個檔案。",
+'listingcontinuesabbrev' => " 續",
+'spambot_username' => 'MediaWiki垃圾清除',
+'spam_reverting' => '恢復返去最後一個唔包含指去$1嘅連結嘅嗰個版本。',
+'spam_blanking' => '全部版本都含有指去$1嘅連結,留空',
+
+# Info page
+'infosubtitle' => '頁面嘅資訊',
+'numedits' => '編輯次數(文章):$1',
+'numtalkedits' => '編輯次數(討論頁):$1',
+'numwatchers' => '監視者數:$1',
+'numauthors' => '唔同編者嘅數目(文章):$1',
+'numtalkauthors' => '唔同編者嘅數目(討論頁):$1',
+
+# Math options
+'mw_math_png' => '全部用PNG表示',
+'mw_math_simple' => '如果好簡單嘅就用HTML,否則就用PNG',
+'mw_math_html' => '可以嘅話都用HTML,否則就用PNG',
+'mw_math_source' => '保留返用TeX(文字瀏覽器用)',
+'mw_math_modern' => '新式瀏覽器嘅建議選項',
+'mw_math_mathml' => '可以嘅話用MathML(實驗中)',
+
+# Patrolling
+'markaspatrolleddiff' => "標示為已巡查嘅",
+'markaspatrolledtext' => "標示呢篇文為已巡查嘅",
+'markedaspatrolled' => "已經標示做已巡查嘅",
+'markedaspatrolledtext' => "已經選擇咗嘅修訂已經標示咗做已巡查嘅。",
+'rcpatroldisabled' => "最近修改巡查已經停用",
+'rcpatroldisabledtext' => "最近修改嘅巡查功能現時停用中。",
+'markedaspatrollederror' => "唔可以標示做已巡查嘅",
+'markedaspatrollederrortext' => "你需要指定一個修訂用嚟將佢標示做已巡查嘅。",
+'markedaspatrollederror-noautopatrol' => '你係唔准去標示你自己嘅更改做已巡查嘅。',
+
+# Monobook.js: tooltips and access keys for monobook
+'monobook.js' => '/* 工具提示同埋快速鍵 */
+var ta = new Object();
+ta[\'pt-userpage\'] = new Array(\'.\',\'我嘅用戶頁\');
+ta[\'pt-anonuserpage\'] = new Array(\'.\',\'您編輯呢個IP嘅對應用戶頁\');
+ta[\'pt-mytalk\'] = new Array(\'n\',\'我嘅對話頁\');
+ta[\'pt-anontalk\'] = new Array(\'n\',\'對於嚟自呢一個IP地址編輯嘅討論\');
+ta[\'pt-preferences\'] = new Array(\'\',\'我嘅喜好設定\');
+ta[\'pt-watchlist\'] = new Array(\'l\',\'你所監視嘅頁面更改一覽\');
+ta[\'pt-mycontris\'] = new Array(\'y\',\'我嘅貢獻一覽\');
+ta[\'pt-login\'] = new Array(\'o\',\'登入係唔需要嘅,但會帶嚟好多嘅好處\');
+ta[\'pt-anonlogin\'] = new Array(\'o\',\'登入係唔需要嘅,但會帶嚟好多嘅好處\');
+ta[\'pt-logout\'] = new Array(\'\',\'登出\');
+ta[\'ca-talk\'] = new Array(\'t\',\'關於內容頁嘅討論\');
+ta[\'ca-edit\'] = new Array(\'e\',\'你可以編輯呢一頁。請在儲存之前先預覽一吓。\');
+ta[\'ca-addsection\'] = new Array(\'+\',\'開始新嘅討論\');
+ta[\'ca-viewsource\'] = new Array(\'e\',\'呢一頁已經被保護。你可以睇吓呢一頁呢原始碼。\');
+ta[\'ca-history\'] = new Array(\'h\',\'呢一頁之前嘅版本\');
+ta[\'ca-protect\'] = new Array(\'=\',\'保護呢一頁\');
+ta[\'ca-delete\'] = new Array(\'d\',\'刪除呢一頁\');
+ta[\'ca-undelete\'] = new Array(\'d\',\'將呢個頁面還原到被刪除之前嘅狀態\');
+ta[\'ca-move\'] = new Array(\'m\',\'移動呢一頁\');
+ta[\'ca-nomove\'] = new Array(\'\',\'你冇權限去移動呢一頁\');
+ta[\'ca-watch\'] = new Array(\'w\',\'將呢一頁加到去你嘅監視清單\');
+ta[\'ca-unwatch\'] = new Array(\'w\',\'將呢一頁喺你嘅監視清單中移去\');
+ta[\'search\'] = new Array(\'f\',\'搵吓呢個 wiki\');
+ta[\'p-logo\'] = new Array(\'\',\'頭版\');
+ta[\'n-mainpage\'] = new Array(\'z\',\'睇頭版\');
+ta[\'n-portal\'] = new Array(\'\',\'關於呢個計劃,你可以做乜,應該要點做\');
+ta[\'n-currentevents\'] = new Array(\'\',\'提供而家發生嘅事嘅背景資料\');
+ta[\'n-requestedarticles\'] = new Array(\'\',\'請求撰寫嘅新文章\');
+ta[\'n-recentchanges\'] = new Array(\'r\',\'列出呢個 wiki 中嘅最近修改\');
+ta[\'n-randompage\'] = new Array(\'x\',\'是但載入一個頁面\');
+ta[\'n-help\'] = new Array(\'\',\'搵吓點做嘅地方\');
+ta[\'n-sitesupport\'] = new Array(\'\',\'資持我哋\');
+ta[\'t-whatlinkshere\'] = new Array(\'j\',\'列出所有連接過嚟呢度嘅頁面\');
+ta[\'t-recentchangeslinked\'] = new Array(\'k\',\'喺呢個頁面連出嘅頁面更改\');
+ta[\'feed-rss\'] = new Array(\'\',\'呢一頁嘅RSS集合\');
+ta[\'feed-atom\'] = new Array(\'\',\'呢一頁嘅Atom集合\');
+ta[\'t-contributions\'] = new Array(\'\',\'睇吓呢個用戶嘅貢獻一覽\');
+ta[\'t-emailuser\'] = new Array(\'\',\'寄封電子郵件畀呢一位用戶\');
+ta[\'t-upload\'] = new Array(\'u\',\'上載圖像或者多媒體檔案\');
+ta[\'t-specialpages\'] = new Array(\'q\',\'所有特別頁嘅一覽\');
+ta[\'ca-nstab-main\'] = new Array(\'c\',\'睇吓內容頁\');
+ta[\'ca-nstab-user\'] = new Array(\'c\',\'睇吓用戶頁\');
+ta[\'ca-nstab-media\'] = new Array(\'c\',\'睇吓媒體頁\');
+ta[\'ca-nstab-special\'] = new Array(\'\',\'呢個係一個特別頁;你唔能夠嗰一頁進行編輯。\');
+ta[\'ca-nstab-project\'] = new Array(\'a\',\'睇吓專案頁\');
+ta[\'ca-nstab-image\'] = new Array(\'c\',\'睇吓圖像頁\');
+ta[\'ca-nstab-mediawiki\'] = new Array(\'c\',\'睇吓系統信息\');
+ta[\'ca-nstab-template\'] = new Array(\'c\',\'睇吓個模\');
+ta[\'ca-nstab-help\'] = new Array(\'c\',\'睇吓幫助頁\');
+ta[\'ca-nstab-category\'] = new Array(\'c\',\'睇吓分類頁\');',
+
+# Common.js: contains nothing but a placeholder comment
+'common.js' => '/* 響每一次個頁面載入時,所有用戶都會載入呢度所有嘅JavaScript。 */',
+
+# image deletion
+'deletedrevision' => '刪除咗$1嘅舊有修訂。',
+
+# browsing diffs
+'previousdiff' => '← 上一個差異',
+'nextdiff' => '下一個差異 →',
+
+'imagemaxsize' => '限制圖像描述頁中嘅圖像一細到:',
+'thumbsize' => '縮圖大細:',
+'showbigimage' => '下載高解像度嘅版本 ($1x$2, $3 KB)',
+
+'newimages' => '新檔案畫廊',
+'showhidebots' => '($1 機械人)',
+'noimages' => '冇嘢去睇。',
+
+# short names for language variants used for language conversion links.
+# to disable showing a particular link, set it to 'disable', e.g.
+# 'variantname-zh-sg' => 'disable',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-sg' => 'sg',
+'variantname-zh' => 'zh',
+# variants for Serbian language
+'variantname-sr-ec' => 'ec',
+'variantname-sr-el' => 'el',
+'variantname-sr-jc' => 'jc',
+'variantname-sr-jl' => 'jl',
+'variantname-sr' => 'sr',
+# variants for Kazakh language
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-cn' => 'kk-cn',
+'variantname-kk' => 'kk',
+
+# labels for User: and Title: on Special:Log pages
+'specialloguserlabel' => '用戶:',
+'speciallogtitlelabel' => '標題:',
+
+'passwordtooshort' => '您嘅密碼太短喇。佢最少要有 $1 個半形字元。',
+
+# Media Warning
+'mediawarning' => '\'\'\'警告\'\'\':呢個檔案可能有一啲惡意嘅程式編碼,如果執行佢嘅話,您嘅系統可能會被波及。
+<hr />',
+
+'fileinfo' => '$1KB, MIME 類型: <code>$2</code>',
+
+# Metadata
+'metadata' => 'Metadata',
+'metadata-help' => '呢個檔案有額外嘅資料。佢應該係數碼相機或者掃描器整出來嘅。如果佢整咗之後畀人改過,裏面嘅資料未必同改過之後相符。',
+'metadata-expand' => '打開詳細資料',
+'metadata-collapse' => '收埋詳細資料',
+'metadata-fields' => '響呢個信息列出嘅 EXIF 元數據項目會喺圖像頁中包含起嚟,
+而且個元數據表除咗喺下面列出嘅項目之外,其它嘅項目預設會被隱藏。
+* 相機廠商 (make)
+* 相機型號 (model)
+* 原創日期時間 (datetimeoriginal)
+* 曝光長度 (exposuretime)
+* F 值 (fnumber)
+* 鏡頭焦距 (focallength)',
+
+# Exif tags
+'exif-imagewidth' =>'闊',
+'exif-imagelength' =>'高',
+'exif-bitspersample' =>'每部位位元數',
+'exif-compression' =>'壓細方法',
+'exif-photometricinterpretation' =>'像素構成',
+'exif-orientation' =>'攞放方向',
+'exif-samplesperpixel' =>'部位數',
+'exif-planarconfiguration' =>'資料編排',
+'exif-ycbcrsubsampling' =>'Y 到 C 嘅二次抽樣比例',
+'exif-ycbcrpositioning' =>'Y 同 C 位置',
+'exif-xresolution' =>'橫解像度',
+'exif-yresolution' =>'直解像度',
+'exif-resolutionunit' =>'橫直解像度單位',
+'exif-stripoffsets' =>'圖像資料位置',
+'exif-rowsperstrip' =>'每帶行數',
+'exif-stripbytecounts' =>'每壓縮帶 bytes 數',
+'exif-jpeginterchangeformat' =>'JPEG SOI 嘅偏移量',
+'exif-jpeginterchangeformatlength' =>'JPEG 資料嘅 bytes 數',
+'exif-transferfunction' =>'轉移功能',
+'exif-whitepoint' =>'白點色度',
+'exif-primarychromaticities' =>'主要嘅色度',
+'exif-ycbcrcoefficients' =>'顏色空間轉換矩陣系數',
+'exif-referenceblackwhite' =>'黑白對參照值',
+'exif-datetime' =>'檔案更動日期時間',
+'exif-imagedescription' =>'圖名',
+'exif-make' =>'相機廠商',
+'exif-model' =>'相機型號',
+'exif-software' =>'用過嘅軟件',
+'exif-artist' =>'作者',
+'exif-copyright' =>'版權人',
+'exif-exifversion' =>'Exif版本',
+'exif-flashpixversion' =>'支援嘅 Flashpix 版本',
+'exif-colorspace' =>'色彩空間',
+'exif-componentsconfiguration' =>'每個部份嘅意思',
+'exif-compressedbitsperpixel' =>'影像壓縮模式', //Image compression mode, 呢個varible 同 英文唔同嘅?
+'exif-pixelydimension' =>'影像有效闊度',
+'exif-pixelxdimension' =>'影像有效高度',
+'exif-makernote' =>'廠商註腳',
+'exif-usercomment' =>'用家註腳',
+'exif-relatedsoundfile' =>'相關聲音檔',
+'exif-datetimeoriginal' =>'原創日期時間',
+'exif-datetimedigitized' =>'制成數碼日期時間',
+'exif-subsectime' =>'日期時間細秒', //DateTime subseconds
+'exif-subsectimeoriginal' =>'日期時間原細秒', //DateTimeOriginal subseconds
+'exif-subsectimedigitized' =>'日期時間數碼化細秒', //DateTimeDigitized subseconds
+'exif-exposuretime' =>'曝光長度',
+'exif-exposuretime-format' => '$1 秒 ($2)',
+'exif-fnumber' =>'F 值',
+'exif-fnumber-format' =>'f/$1',
+'exif-exposureprogram' =>'曝光程序',
+'exif-spectralsensitivity' =>'光譜敏感度',
+'exif-isospeedratings' =>'ISO 速率',
+'exif-oecf' =>'光電轉換因子',
+'exif-shutterspeedvalue' =>'快門速度',
+'exif-aperturevalue' =>'光圈',
+'exif-brightnessvalue' =>'光度',
+'exif-exposurebiasvalue' =>'曝光偏壓', //Exposure bias
+'exif-maxaperturevalue' =>'最大陸地孔徑',
+'exif-subjectdistance' =>'主體距離',
+'exif-meteringmode' =>'測距模式',
+'exif-lightsource' =>'光源',
+'exif-flash' =>'閃光燈',
+'exif-focallength' =>'鏡頭焦距',
+'exif-focallength-format' =>'$1 毫米',
+'exif-subjectarea' =>'主體面積',
+'exif-flashenergy' =>'閃光燈能量',
+'exif-spatialfrequencyresponse' =>'空間頻率響應',
+'exif-focalplanexresolution' =>'焦點平面 X 嘅解像度',
+'exif-focalplaneyresolution' =>'焦點平面 Y 嘅解像度',
+'exif-focalplaneresolutionunit' =>'焦點平面解像度單位',
+'exif-subjectlocation' =>'主題位置',
+'exif-exposureindex' =>'曝光指數',
+'exif-sensingmethod' =>'感知方法',
+'exif-filesource' =>'檔案來源',
+'exif-scenetype' =>'埸景類型',
+'exif-cfapattern' =>'CFA 形式',
+'exif-customrendered' =>'自訂影像處理', //Custom image processing
+'exif-exposuremode' =>'曝光模式',
+'exif-whitebalance' =>'白平衡',
+'exif-digitalzoomratio' =>'數碼放大比例',
+'exif-focallengthin35mmfilm' =>'以35毫米菲林計嘅焦距',
+'exif-scenecapturetype' =>'場景捕捉類型', //Scene capture type
+'exif-gaincontrol' =>'場景控制', //Scene control
+'exif-contrast' =>'對比',
+'exif-saturation' =>'飽和度',
+'exif-sharpness' =>'清晰度',
+'exif-devicesettingdescription' =>'裝置設定描述',
+'exif-subjectdistancerange' =>'物件距離範圍',
+'exif-imageuniqueid' =>'影像獨有編號',
+'exif-gpsversionid' =>'全球定位版本',
+'exif-gpslatituderef' =>'南北緯',
+'exif-gpslatitude' =>'緯度',
+'exif-gpslongituderef' =>'東西經',
+'exif-gpslongitude' =>'經度',
+'exif-gpsaltituderef' =>'海拔參考點',
+'exif-gpsaltitude' =>'海拔',
+'exif-gpstimestamp' =>'全球定位時間(原子鐘)',
+'exif-gpssatellites' =>'量度用嘅衞星',
+'exif-gpsstatus' =>'接收器狀態',
+'exif-gpsmeasuremode' =>'量度模式',
+'exif-gpsdop' =>'量度準繩度',
+'exif-gpsspeedref' =>'速度單位',
+'exif-gpsspeed' =>'全球定位儀嘅速度',
+'exif-gpstrackref' =>'移動方向參考點',
+'exif-gpstrack' =>'移動方向',
+'exif-gpsimgdirectionref' =>'影像方向參考點',
+'exif-gpsimgdirection' =>'影像方向',
+'exif-gpsmapdatum' =>'用咗嘅大地測量資料',
+'exif-gpsdestlatituderef' =>'目的地緯度參考點',
+'exif-gpsdestlatitude' =>'目的地緯度',
+'exif-gpsdestlongituderef' =>'目的地經度參考點',
+'exif-gpsdestlongitude' =>'目的地經度',
+'exif-gpsdestbearingref' =>'目的地坐向參考點',
+'exif-gpsdestbearing' =>'目的地坐向',
+'exif-gpsdestdistanceref' =>'目的地距離參考點',
+'exif-gpsdestdistance' =>'目的地距離',
+'exif-gpsprocessingmethod' =>'GPS 處理方法名',
+'exif-gpsareainformation' =>'GPS 地區名',
+'exif-gpsdatestamp' =>'GPS 日期',
+'exif-gpsdifferential' =>'GPS 差動修正',
+
+# Exif attributes
+
+'exif-compression-1' => '未壓過',
+'exif-compression-6' => 'JPEG',
+
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
+'exif-orientation-1' => '正常', // 0th row: top; 0th column: left
+'exif-orientation-2' => '左右倒轉', // 0th row: top; 0th column: right
+'exif-orientation-3' => '轉一百八十度', // 0th row: bottom; 0th column: right
+'exif-orientation-4' => '上下倒轉', // 0th row: bottom; 0th column: left
+'exif-orientation-5' => '逆時針轉九十度,再上下倒轉', // 0th row: left; 0th column: top
+'exif-orientation-6' => '順時針轉九十度', // 0th row: right; 0th column: top
+'exif-orientation-7' => '順時針轉九十度,再上下倒轉', // 0th row: right; 0th column: bottom
+'exif-orientation-8' => '逆時針轉九十度', // 0th row: left; 0th column: bottom
+
+'exif-planarconfiguration-1' => 'chunky 格式',
+'exif-planarconfiguration-2' => 'planar 格式',
+
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
+'exif-colorspace-ffff.h' => 'FFFF.H',
+
+'exif-componentsconfiguration-0' => '根本無',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
+
+'exif-exposureprogram-0' => '無定義',
+'exif-exposureprogram-1' => '人手',
+'exif-exposureprogram-2' => '平常程序',
+'exif-exposureprogram-3' => '着重光圈',
+'exif-exposureprogram-4' => '着重快門',
+'exif-exposureprogram-5' => '創作程序(加重景深)',
+'exif-exposureprogram-6' => '動作程序(加大快門速度)',
+'exif-exposureprogram-7' => '人像模式(近睇,背景矇)',
+'exif-exposureprogram-8' => '風景模式(風景相,聚焦背景)',
+
+'exif-subjectdistance-value' => '$1米',
+
+'exif-meteringmode-0' => '唔知',
+'exif-meteringmode-1' => '平均',
+'exif-meteringmode-2' => '中間加權平均',
+'exif-meteringmode-3' => '一點',
+'exif-meteringmode-4' => '多點',
+'exif-meteringmode-5' => '圖案',
+'exif-meteringmode-6' => '部分',
+'exif-meteringmode-255' => '其他',
+
+'exif-lightsource-0' => '唔知',
+'exif-lightsource-1' => '日光',
+'exif-lightsource-2' => '光管',
+'exif-lightsource-3' => '燈泡(鎢絲)',
+'exif-lightsource-4' => '閃光燈',
+'exif-lightsource-9' => '晴朗',
+'exif-lightsource-10' => '有雲',
+'exif-lightsource-11' => '陰影',
+'exif-lightsource-12' => '日光螢光燈 (D 5700 – 7100K)',
+'exif-lightsource-13' => '日光白色螢光燈 (N 4600 – 5400K)',
+'exif-lightsource-14' => '冷白螢光燈 (W 3900 – 4500K)',
+'exif-lightsource-15' => '白色螢光燈 (WW 3200 – 3700K)',
+'exif-lightsource-17' => '標準光 A',
+'exif-lightsource-18' => '標準光 B',
+'exif-lightsource-19' => '標準光 C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
+'exif-lightsource-24' => 'ISO 攝影廠鎢燈',
+'exif-lightsource-255' => '其它光源',
+
+'exif-focalplaneresolutionunit-2' => '吋',
+
+'exif-sensingmethod-1' => '無定義',
+'exif-sensingmethod-2' => '單晶片色彩空間感應器',
+'exif-sensingmethod-3' => '雙晶片色彩空間感應器',
+'exif-sensingmethod-4' => '三晶片色彩空間感應器',
+'exif-sensingmethod-5' => '連續色彩空間感應器',
+'exif-sensingmethod-7' => '三綫感應器',
+'exif-sensingmethod-8' => '連續色彩綫性感應器',
+
+'exif-filesource-3' => 'DSC',
+
+'exif-scenetype-1' => '一張直接映像',
+
+'exif-customrendered-0' => '一般程序',
+'exif-customrendered-1' => '度身程序',
+
+'exif-exposuremode-0' => '自動曝光',
+'exif-exposuremode-1' => '手動曝光',
+'exif-exposuremode-2' => '自動曝光感知調節',
+
+'exif-whitebalance-0' => '自動白平衡',
+'exif-whitebalance-1' => '手動白平衡',
+
+'exif-scenecapturetype-0' => '標準',
+'exif-scenecapturetype-1' => '風景',
+'exif-scenecapturetype-2' => '人像',
+'exif-scenecapturetype-3' => '夜景',
+
+'exif-gaincontrol-0' => '高',
+'exif-gaincontrol-1' => '小增',
+'exif-gaincontrol-2' => '大增',
+'exif-gaincontrol-3' => '小減',
+'exif-gaincontrol-4' => '大減',
+
+'exif-contrast-0' => '平常',
+'exif-contrast-1' => '軟',
+'exif-contrast-2' => '硬',
+
+'exif-saturation-0' => '平常',
+'exif-saturation-1' => '低飽和',
+'exif-saturation-2' => '高飽和',
+
+'exif-sharpness-0' => '平常',
+'exif-sharpness-1' => '軟',
+'exif-sharpness-2' => '硬',
+
+'exif-subjectdistancerange-0' => '唔知',
+'exif-subjectdistancerange-1' => '微觀',
+'exif-subjectdistancerange-2' => '近鏡',
+'exif-subjectdistancerange-3' => '遠鏡',
+
+// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
+'exif-gpslatitude-n' => '北緯',
+'exif-gpslatitude-s' => '南緯',
+
+// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
+'exif-gpslongitude-e' => '東經',
+'exif-gpslongitude-w' => '西經',
+
+'exif-gpsstatus-a' => '度緊',
+'exif-gpsstatus-v' => '互度',
+
+'exif-gpsmeasuremode-2' => '二維量度',
+'exif-gpsmeasuremode-3' => '三維量度',
+
+// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
+'exif-gpsspeed-k' => '千米/小時',
+'exif-gpsspeed-m' => '英里/小時',
+'exif-gpsspeed-n' => '浬',
+
+// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => '真實方向',
+'exif-gpsdirection-m' => '地磁方向',
+
+# external editor support
+'edit-externally' => '用外面程式來改呢個檔案',
+'edit-externally-help' => '去[http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] 睇多啲資料',
+
+# 'all' in various places, this might be different for inflected languages
+'recentchangesall' => '全部',
+'imagelistall' => '全部',
+'watchlistall1' => '全部',
+'watchlistall2' => '全部',
+'namespacesall' => '全部',
+
+# E-mail address confirmation
+'confirmemail' => '確認電郵地址',
+'confirmemail_noemail' => '你唔需要響你嘅[[Special:Preferences|用戶喜好設定]]度設定一個有效嘅電郵地址。',
+'confirmemail_text' => "呢個wiki需要你喺使用電郵功能之前驗證吓你嘅電郵地址。
+啟用下邊個掣嚟發封確認信去你個地址度。
+封信入面會附帶一條包含代碼嘅連結;
+喺你個瀏覽器度打開條連結嚟確認你嘅電郵地址係有效嘅。",
+'confirmemail_pending' => '<div class="error">
+一個確認碼已經電郵咗畀你;
+如果你係啱啱開咗個新戶口嘅,
+你可以響請求一個新嘅確認碼之前等多幾分鐘等佢寄畀你。
+</div>',
+'confirmemail_send' => '寄出確認碼。',
+'confirmemail_sent' => '確認電郵已經寄出。',
+'confirmemail_oncreate' => '一個確認碼已經寄送咗到嘅嘅電郵地址。
+呢個代碼唔係登入嗰陣去用,但係你需要佢去開響呢個wiki度,任何同電郵有關嘅功能。',
+'confirmemail_sendfailed' => '發唔到確認信。請檢查吓個地址有冇無效嘅字。
+
+郵件遞送員回應咗:$1',
+'confirmemail_invalid' => '無效嘅確認碼。個代碼可能已經過咗期。',
+'confirmemail_needlogin' => '你需要先$1去確認你嘅電郵地址。',
+'confirmemail_success' => '你嘅電郵地址已經得到確認。你而家可以登入同盡情享受wiki啦。',
+'confirmemail_loggedin' => '你嘅電郵地址現已得到確認。',
+'confirmemail_error' => '儲存你嘅確認資料嘅時候有小小嘢發生咗意外。',
+
+'confirmemail_subject' => '{{SITENAME}}電郵地址確認',
+'confirmemail_body' => "有人(好有可能係嚟自你嘅IP地址 $1)已經用呢個電郵地址喺{{SITENAME}}度註冊咗帳戶\"$2\"
+
+要確認呢個帳戶的而且確屬於你同埋啟用{{SITENAME}}嘅電郵功能,
+請喺你嘅瀏覽器度打開呢條連結:
+
+$3
+
+如果呢個*唔係*你,請唔好打開條連結。
+呢個確認代碼會喺$4到期。",
+
+# Inputbox extension, may be useful in other contexts as well
+'tryexact' => '試吓精確嘅比較',
+'searchfulltext' => '搵全文',
+'createarticle' => '建立文章',
+
+# Scary transclusion
+'scarytranscludedisabled' => '[跨 wiki 滲漏正停用]',
+'scarytranscludefailed' => '[$1嘅頡取模動作失敗;對唔住]',
+'scarytranscludetoolong' => '[URL 太長;對唔住]',
+
+# Trackbacks
+'trackbackbox' => '<div id="mw_trackbacks">
+呢一篇文嘅過去追蹤:<br />
+$1
+</div>',
+'trackbackremove' => ' ([$1 刪除])',
+'trackbacklink' => '過去追蹤',
+'trackbackdeleteok' => '過去追蹤已經成功噉樣刪除。',
+
+
+# delete conflict
+
+'deletedwhileediting' => '警告:你寫緊文嗰陣,有用戶洗咗呢版!',
+'confirmrecreate' => '你寫緊文嗰陣,阿用戶 [[User:$1|$1]] ([[User talk:$1|talk]]) 洗咗呢一頁。以下係佢個理由:
+: \'\'$2\'\'
+你係咪真係想重新整過呢版?',
+'recreate' => '重新整過',
+'tooltip-recreate' => '即使已經刪除過都要重新整過呢頁',
+
+'unit-pixel' => 'px',
+
+# HTML dump
+'redirectingto' => '重新定向到[[$1]]...',
+
+# action=purge
+'confirm_purge' => "肯定要洗咗呢版個快取版本?\n\n$1",
+'confirm_purge_button' => '肯定',
+
+'youhavenewmessagesmulti' => "你響 $1 有一個新信息",
+
+'searchcontaining' => "搵含有''$1''嘅文章。",
+'searchnamed' => "搵個名係''$1''嘅文章。",
+'articletitles' => "以''$1''開頭嘅文章",
+'hideresults' => '收埋結果',
+
+# DISPLAYTITLE
+'displaytitle' => '(以[[$1]]連結到呢一頁)',
+
+'loginlanguagelabel' => '語言:$1',
+
+# Multipage image navigation
+'imgmultipageprev' => '&larr; 上一版',
+'imgmultipagenext' => '下一版 &rarr;',
+'imgmultigo' => '去!',
+'imgmultigotopre' => '去到第',
+'imgmultigotopost' => '版',
+
+# Table pager
+'ascending_abbrev' => '增',
+'descending_abbrev' => '減',
+'table_pager_next' => '下一版',
+'table_pager_prev' => '上一版',
+'table_pager_first' => '第一版',
+'table_pager_last' => '最後一版',
+'table_pager_limit' => '每一版顯示$1個項目',
+'table_pager_limit_submit' => '去',
+'table_pager_empty' => '無結果',
+
+# Auto-summaries
+'autosumm-blank' => '移除緊響嗰一版嘅全部內容',
+'autosumm-replace' => '用 \'$1\' 取代緊嗰一版',
+'autoredircomment' => '重新定向緊到[[$1]]', # This should be changed to the new naming convention, but existed beforehand.
+'autosumm-new' => '新頁: $1',
+
+);
+
+?>
diff --git a/locale/README b/locale/README
new file mode 100644
index 000000000000..04374885d529
--- /dev/null
+++ b/locale/README
@@ -0,0 +1 @@
+This directory is for .po files generated by ./maintenance/lang2po.php
diff --git a/maintenance/.htaccess b/maintenance/.htaccess
new file mode 100644
index 000000000000..3a4288278871
--- /dev/null
+++ b/maintenance/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/maintenance/Doxyfile b/maintenance/Doxyfile
new file mode 100644
index 000000000000..44e8e4950a30
--- /dev/null
+++ b/maintenance/Doxyfile
@@ -0,0 +1,279 @@
+# Doxyfile 1.4.6
+
+#
+# Some placeholders have been added for MediaWiki usage:
+# {{OUTPUT_DIRECTORY}}
+# {{STRIP_FROM_PATH}}
+# {{INPUT}}
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = MediaWiki
+PROJECT_NUMBER = trunk
+OUTPUT_DIRECTORY = {{OUTPUT_DIRECTORY}}
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = {{STRIP_FROM_PATH}}
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = {{INPUT}}
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.C \
+ *.CC \
+ *.C++ \
+ *.II \
+ *.I++ \
+ *.H \
+ *.HH \
+ *.H++ \
+ *.CS \
+ *.PHP \
+ *.PHP3 \
+ *.M \
+ *.MM \
+ *.PY
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS = LocalSettings.php AdminSettings.php
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = YES
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 1000
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/maintenance/FiveUpgrade.inc b/maintenance/FiveUpgrade.inc
new file mode 100644
index 000000000000..d21d8b433a6a
--- /dev/null
+++ b/maintenance/FiveUpgrade.inc
@@ -0,0 +1,1213 @@
+<?php
+
+require_once( 'cleanupDupes.inc' );
+require_once( 'userDupes.inc' );
+require_once( 'updaters.inc' );
+
+define( 'MW_UPGRADE_COPY', false );
+define( 'MW_UPGRADE_ENCODE', true );
+define( 'MW_UPGRADE_NULL', null );
+define( 'MW_UPGRADE_CALLBACK', null ); // for self-documentation only
+
+class FiveUpgrade {
+ function FiveUpgrade() {
+ global $wgDatabase;
+ $this->conversionTables = $this->prepareWindows1252();
+
+ $this->dbw =& $this->newConnection();
+ $this->dbr =& $this->streamConnection();
+
+ $this->cleanupSwaps = array();
+ $this->emailAuth = false; # don't preauthenticate emails
+ $this->maxLag = 10; # if slaves are lagged more than 10 secs, wait
+ }
+
+ function doing( $step ) {
+ return is_null( $this->step ) || $step == $this->step;
+ }
+
+ function upgrade( $step ) {
+ $this->step = $step;
+
+ $tables = array(
+ 'page',
+ 'links',
+ 'user',
+ 'image',
+ 'oldimage',
+ 'watchlist',
+ 'logging',
+ 'archive',
+ 'imagelinks',
+ 'categorylinks',
+ 'ipblocks',
+ 'recentchanges',
+ 'querycache' );
+ foreach( $tables as $table ) {
+ if( $this->doing( $table ) ) {
+ $method = 'upgrade' . ucfirst( $table );
+ $this->$method();
+ }
+ }
+
+ if( $this->doing( 'cleanup' ) ) {
+ $this->upgradeCleanup();
+ }
+ }
+
+
+ /**
+ * Open a connection to the master server with the admin rights.
+ * @return Database
+ * @access private
+ */
+ function &newConnection() {
+ global $wgDBadminuser, $wgDBadminpassword;
+ global $wgDBserver, $wgDBname;
+ $db = new Database( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname );
+ return $db;
+ }
+
+ /**
+ * Open a second connection to the master server, with buffering off.
+ * This will let us stream large datasets in and write in chunks on the
+ * other end.
+ * @return Database
+ * @access private
+ */
+ function &streamConnection() {
+ $timeout = 3600 * 24;
+ $db =& $this->newConnection();
+ $db->bufferResults( false );
+ $db->query( "SET net_read_timeout=$timeout" );
+ $db->query( "SET net_write_timeout=$timeout" );
+ return $db;
+ }
+
+ /**
+ * Prepare a conversion array for converting Windows Code Page 1252 to
+ * UTF-8. This should provide proper conversion of text that was miscoded
+ * as Windows-1252 by naughty user-agents, and doesn't rely on an outside
+ * iconv library.
+ *
+ * @return array
+ * @access private
+ */
+ function prepareWindows1252() {
+ # Mappings from:
+ # http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT
+ static $cp1252 = array(
+ 0x80 => 0x20AC, #EURO SIGN
+ 0x81 => 0xFFFD, #REPLACEMENT CHARACTER (no mapping)
+ 0x82 => 0x201A, #SINGLE LOW-9 QUOTATION MARK
+ 0x83 => 0x0192, #LATIN SMALL LETTER F WITH HOOK
+ 0x84 => 0x201E, #DOUBLE LOW-9 QUOTATION MARK
+ 0x85 => 0x2026, #HORIZONTAL ELLIPSIS
+ 0x86 => 0x2020, #DAGGER
+ 0x87 => 0x2021, #DOUBLE DAGGER
+ 0x88 => 0x02C6, #MODIFIER LETTER CIRCUMFLEX ACCENT
+ 0x89 => 0x2030, #PER MILLE SIGN
+ 0x8A => 0x0160, #LATIN CAPITAL LETTER S WITH CARON
+ 0x8B => 0x2039, #SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ 0x8C => 0x0152, #LATIN CAPITAL LIGATURE OE
+ 0x8D => 0xFFFD, #REPLACEMENT CHARACTER (no mapping)
+ 0x8E => 0x017D, #LATIN CAPITAL LETTER Z WITH CARON
+ 0x8F => 0xFFFD, #REPLACEMENT CHARACTER (no mapping)
+ 0x90 => 0xFFFD, #REPLACEMENT CHARACTER (no mapping)
+ 0x91 => 0x2018, #LEFT SINGLE QUOTATION MARK
+ 0x92 => 0x2019, #RIGHT SINGLE QUOTATION MARK
+ 0x93 => 0x201C, #LEFT DOUBLE QUOTATION MARK
+ 0x94 => 0x201D, #RIGHT DOUBLE QUOTATION MARK
+ 0x95 => 0x2022, #BULLET
+ 0x96 => 0x2013, #EN DASH
+ 0x97 => 0x2014, #EM DASH
+ 0x98 => 0x02DC, #SMALL TILDE
+ 0x99 => 0x2122, #TRADE MARK SIGN
+ 0x9A => 0x0161, #LATIN SMALL LETTER S WITH CARON
+ 0x9B => 0x203A, #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ 0x9C => 0x0153, #LATIN SMALL LIGATURE OE
+ 0x9D => 0xFFFD, #REPLACEMENT CHARACTER (no mapping)
+ 0x9E => 0x017E, #LATIN SMALL LETTER Z WITH CARON
+ 0x9F => 0x0178, #LATIN CAPITAL LETTER Y WITH DIAERESIS
+ );
+ $pairs = array();
+ for( $i = 0; $i < 0x100; $i++ ) {
+ $unicode = isset( $cp1252[$i] ) ? $cp1252[$i] : $i;
+ $pairs[chr( $i )] = codepointToUtf8( $unicode );
+ }
+ return $pairs;
+ }
+
+ /**
+ * Convert from 8-bit Windows-1252 to UTF-8 if necessary.
+ * @param string $text
+ * @return string
+ * @access private
+ */
+ function conv( $text ) {
+ global $wgUseLatin1;
+ return is_null( $text )
+ ? null
+ : ( $wgUseLatin1
+ ? strtr( $text, $this->conversionTables )
+ : $text );
+ }
+
+ /**
+ * Dump timestamp and message to output
+ * @param string $message
+ * @access private
+ */
+ function log( $message ) {
+ echo wfWikiID() . ' ' . wfTimestamp( TS_DB ) . ': ' . $message . "\n";
+ flush();
+ }
+
+ /**
+ * Initialize the chunked-insert system.
+ * Rows will be inserted in chunks of the given number, rather
+ * than in a giant INSERT...SELECT query, to keep the serialized
+ * MySQL database replication from getting hung up. This way other
+ * things can be going on during conversion without waiting for
+ * slaves to catch up as badly.
+ *
+ * @param int $chunksize Number of rows to insert at once
+ * @param int $final Total expected number of rows / id of last row,
+ * used for progress reports.
+ * @param string $table to insert on
+ * @param string $fname function name to report in SQL
+ * @access private
+ */
+ function setChunkScale( $chunksize, $final, $table, $fname ) {
+ $this->chunkSize = $chunksize;
+ $this->chunkFinal = $final;
+ $this->chunkCount = 0;
+ $this->chunkStartTime = wfTime();
+ $this->chunkOptions = array( 'IGNORE' );
+ $this->chunkTable = $table;
+ $this->chunkFunction = $fname;
+ }
+
+ /**
+ * Chunked inserts: perform an insert if we've reached the chunk limit.
+ * Prints a progress report with estimated completion time.
+ * @param array &$chunk -- This will be emptied if an insert is done.
+ * @param int $key A key identifier to use in progress estimation in
+ * place of the number of rows inserted. Use this if
+ * you provided a max key number instead of a count
+ * as the final chunk number in setChunkScale()
+ * @access private
+ */
+ function addChunk( &$chunk, $key = null ) {
+ if( count( $chunk ) >= $this->chunkSize ) {
+ $this->insertChunk( $chunk );
+
+ $this->chunkCount += count( $chunk );
+ $now = wfTime();
+ $delta = $now - $this->chunkStartTime;
+ $rate = $this->chunkCount / $delta;
+
+ if( is_null( $key ) ) {
+ $completed = $this->chunkCount;
+ } else {
+ $completed = $key;
+ }
+ $portion = $completed / $this->chunkFinal;
+
+ $estimatedTotalTime = $delta / $portion;
+ $eta = $this->chunkStartTime + $estimatedTotalTime;
+
+ printf( "%s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec\n",
+ wfTimestamp( TS_DB, intval( $now ) ),
+ $portion * 100.0,
+ $this->chunkTable,
+ wfTimestamp( TS_DB, intval( $eta ) ),
+ $completed,
+ $this->chunkFinal,
+ $rate );
+ flush();
+
+ $chunk = array();
+ }
+ }
+
+ /**
+ * Chunked inserts: perform an insert unconditionally, at the end, and log.
+ * @param array &$chunk -- This will be emptied if an insert is done.
+ * @access private
+ */
+ function lastChunk( &$chunk ) {
+ $n = count( $chunk );
+ if( $n > 0 ) {
+ $this->insertChunk( $chunk );
+ }
+ $this->log( "100.00% done on $this->chunkTable (last chunk $n rows)." );
+ }
+
+ /**
+ * Chunked inserts: perform an insert.
+ * @param array &$chunk -- This will be emptied if an insert is done.
+ * @access private
+ */
+ function insertChunk( &$chunk ) {
+ // Give slaves a chance to catch up
+ wfWaitForSlaves( $this->maxLag );
+ $this->dbw->insert( $this->chunkTable, $chunk, $this->chunkFunction, $this->chunkOptions );
+ }
+
+
+ /**
+ * Copy and transcode a table to table_temp.
+ * @param string $name Base name of the source table
+ * @param string $tabledef CREATE TABLE definition, w/ $1 for the name
+ * @param array $fields set of destination fields to these constants:
+ * MW_UPGRADE_COPY - straight copy
+ * MW_UPGRADE_ENCODE - for old Latin1 wikis, conv to UTF-8
+ * MW_UPGRADE_NULL - just put NULL
+ * @param callable $callback An optional callback to modify the data
+ * or perform other processing. Func should be
+ * ( object $row, array $copy ) and return $copy
+ * @access private
+ */
+ function copyTable( $name, $tabledef, $fields, $callback = null ) {
+ $fname = 'FiveUpgrade::copyTable';
+
+ $name_temp = $name . '_temp';
+ $this->log( "Migrating $name table to $name_temp..." );
+
+ $table = $this->dbw->tableName( $name );
+ $table_temp = $this->dbw->tableName( $name_temp );
+
+ // Create temporary table; we're going to copy everything in there,
+ // then at the end rename the final tables into place.
+ $def = str_replace( '$1', $table_temp, $tabledef );
+ $this->dbw->query( $def, $fname );
+
+ $numRecords = $this->dbw->selectField( $name, 'COUNT(*)', '', $fname );
+ $this->setChunkScale( 100, $numRecords, $name_temp, $fname );
+
+ // Pull all records from the second, streaming database connection.
+ $sourceFields = array_keys( array_filter( $fields,
+ create_function( '$x', 'return $x !== MW_UPGRADE_NULL;' ) ) );
+ $result = $this->dbr->select( $name,
+ $sourceFields,
+ '',
+ $fname );
+
+ $add = array();
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $copy = array();
+ foreach( $fields as $field => $source ) {
+ if( $source === MW_UPGRADE_COPY ) {
+ $copy[$field] = $row->$field;
+ } elseif( $source === MW_UPGRADE_ENCODE ) {
+ $copy[$field] = $this->conv( $row->$field );
+ } elseif( $source === MW_UPGRADE_NULL ) {
+ $copy[$field] = null;
+ } else {
+ $this->log( "Unknown field copy type: $field => $source" );
+ }
+ }
+ if( is_callable( $callback ) ) {
+ $copy = call_user_func( $callback, $row, $copy );
+ }
+ $add[] = $copy;
+ $this->addChunk( $add );
+ }
+ $this->lastChunk( $add );
+ $this->dbr->freeResult( $result );
+
+ $this->log( "Done converting $name." );
+ $this->cleanupSwaps[] = $name;
+ }
+
+ function upgradePage() {
+ $fname = "FiveUpgrade::upgradePage";
+ $chunksize = 100;
+
+ if( $this->dbw->tableExists( 'page' ) ) {
+ $this->log( 'Page table already exists; aborting.' );
+ die( -1 );
+ }
+
+ $this->log( "Checking cur table for unique title index and applying if necessary" );
+ checkDupes( true );
+
+ $this->log( "...converting from cur/old to page/revision/text DB structure." );
+
+ extract( $this->dbw->tableNames( 'cur', 'old', 'page', 'revision', 'text' ) );
+
+ $this->log( "Creating page and revision tables..." );
+ $this->dbw->query("CREATE TABLE $page (
+ page_id int(8) unsigned NOT NULL auto_increment,
+ page_namespace int NOT NULL,
+ page_title varchar(255) binary NOT NULL,
+ page_restrictions tinyblob NOT NULL default '',
+ page_counter bigint(20) unsigned NOT NULL default '0',
+ page_is_redirect tinyint(1) unsigned NOT NULL default '0',
+ page_is_new tinyint(1) unsigned NOT NULL default '0',
+ page_random real unsigned NOT NULL,
+ page_touched char(14) binary NOT NULL default '',
+ page_latest int(8) unsigned NOT NULL,
+ page_len int(8) unsigned NOT NULL,
+
+ PRIMARY KEY page_id (page_id),
+ UNIQUE INDEX name_title (page_namespace,page_title),
+ INDEX (page_random),
+ INDEX (page_len)
+ ) TYPE=InnoDB", $fname );
+ $this->dbw->query("CREATE TABLE $revision (
+ rev_id int(8) unsigned NOT NULL auto_increment,
+ rev_page int(8) unsigned NOT NULL,
+ rev_text_id int(8) unsigned NOT NULL,
+ rev_comment tinyblob NOT NULL default '',
+ rev_user int(5) unsigned NOT NULL default '0',
+ rev_user_text varchar(255) binary NOT NULL default '',
+ rev_timestamp char(14) binary NOT NULL default '',
+ rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
+ rev_deleted tinyint(1) 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)
+ ) TYPE=InnoDB", $fname );
+
+ $maxold = intval( $this->dbw->selectField( 'old', 'max(old_id)', '', $fname ) );
+ $this->log( "Last old record is {$maxold}" );
+
+ global $wgLegacySchemaConversion;
+ if( $wgLegacySchemaConversion ) {
+ // Create HistoryBlobCurStub entries.
+ // Text will be pulled from the leftover 'cur' table at runtime.
+ echo "......Moving metadata from cur; using blob references to text in cur table.\n";
+ $cur_text = "concat('O:18:\"historyblobcurstub\":1:{s:6:\"mCurId\";i:',cur_id,';}')";
+ $cur_flags = "'object'";
+ } else {
+ // Copy all cur text in immediately: this may take longer but avoids
+ // having to keep an extra table around.
+ echo "......Moving text from cur.\n";
+ $cur_text = 'cur_text';
+ $cur_flags = "''";
+ }
+
+ $maxcur = $this->dbw->selectField( 'cur', 'max(cur_id)', '', $fname );
+ $this->log( "Last cur entry is $maxcur" );
+
+ /**
+ * Copy placeholder records for each page's current version into old
+ * Don't do any conversion here; text records are converted at runtime
+ * based on the flags (and may be originally binary!) while the meta
+ * fields will be converted in the old -> rev and cur -> page steps.
+ */
+ $this->setChunkScale( $chunksize, $maxcur, 'old', $fname );
+ $result = $this->dbr->query(
+ "SELECT cur_id, cur_namespace, cur_title, $cur_text AS text, cur_comment,
+ cur_user, cur_user_text, cur_timestamp, cur_minor_edit, $cur_flags AS flags
+ FROM $cur
+ ORDER BY cur_id", $fname );
+ $add = array();
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $add[] = array(
+ 'old_namespace' => $row->cur_namespace,
+ 'old_title' => $row->cur_title,
+ 'old_text' => $row->text,
+ 'old_comment' => $row->cur_comment,
+ 'old_user' => $row->cur_user,
+ 'old_user_text' => $row->cur_user_text,
+ 'old_timestamp' => $row->cur_timestamp,
+ 'old_minor_edit' => $row->cur_minor_edit,
+ 'old_flags' => $row->flags );
+ $this->addChunk( $add, $row->cur_id );
+ }
+ $this->lastChunk( $add );
+ $this->dbr->freeResult( $result );
+
+ /**
+ * Copy revision metadata from old into revision.
+ * We'll also do UTF-8 conversion of usernames and comments.
+ */
+ #$newmaxold = $this->dbw->selectField( 'old', 'max(old_id)', '', $fname );
+ #$this->setChunkScale( $chunksize, $newmaxold, 'revision', $fname );
+ #$countold = $this->dbw->selectField( 'old', 'count(old_id)', '', $fname );
+ $countold = $this->dbw->selectField( 'old', 'max(old_id)', '', $fname );
+ $this->setChunkScale( $chunksize, $countold, 'revision', $fname );
+
+ $this->log( "......Setting up revision table." );
+ $result = $this->dbr->query(
+ "SELECT old_id, cur_id, old_comment, old_user, old_user_text,
+ old_timestamp, old_minor_edit
+ FROM $old,$cur WHERE old_namespace=cur_namespace AND old_title=cur_title",
+ $fname );
+
+ $add = array();
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $add[] = array(
+ 'rev_id' => $row->old_id,
+ 'rev_page' => $row->cur_id,
+ 'rev_text_id' => $row->old_id,
+ 'rev_comment' => $this->conv( $row->old_comment ),
+ 'rev_user' => $row->old_user,
+ 'rev_user_text' => $this->conv( $row->old_user_text ),
+ 'rev_timestamp' => $row->old_timestamp,
+ 'rev_minor_edit' => $row->old_minor_edit );
+ $this->addChunk( $add );
+ }
+ $this->lastChunk( $add );
+ $this->dbr->freeResult( $result );
+
+
+ /**
+ * Copy page metadata from cur into page.
+ * We'll also do UTF-8 conversion of titles.
+ */
+ $this->log( "......Setting up page table." );
+ $this->setChunkScale( $chunksize, $maxcur, 'page', $fname );
+ $result = $this->dbr->query( "
+ SELECT cur_id, cur_namespace, cur_title, cur_restrictions, cur_counter, cur_is_redirect, cur_is_new,
+ cur_random, cur_touched, rev_id, LENGTH(cur_text) AS len
+ FROM $cur,$revision
+ WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}
+ ORDER BY cur_id", $fname );
+ $add = array();
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $add[] = array(
+ 'page_id' => $row->cur_id,
+ 'page_namespace' => $row->cur_namespace,
+ 'page_title' => $this->conv( $row->cur_title ),
+ 'page_restrictions' => $row->cur_restrictions,
+ 'page_counter' => $row->cur_counter,
+ 'page_is_redirect' => $row->cur_is_redirect,
+ 'page_is_new' => $row->cur_is_new,
+ 'page_random' => $row->cur_random,
+ 'page_touched' => $this->dbw->timestamp(),
+ 'page_latest' => $row->rev_id,
+ 'page_len' => $row->len );
+ #$this->addChunk( $add, $row->cur_id );
+ $this->addChunk( $add );
+ }
+ $this->lastChunk( $add );
+ $this->dbr->freeResult( $result );
+
+ $this->log( "...done with cur/old -> page/revision." );
+ }
+
+ function upgradeLinks() {
+ $fname = 'FiveUpgrade::upgradeLinks';
+ $chunksize = 200;
+ extract( $this->dbw->tableNames( 'links', 'brokenlinks', 'pagelinks', 'cur' ) );
+
+ $this->log( 'Checking for interwiki table change in case of bogus items...' );
+ if( $this->dbw->fieldExists( 'interwiki', 'iw_trans' ) ) {
+ $this->log( 'interwiki has iw_trans.' );
+ } else {
+ $this->log( 'adding iw_trans...' );
+ dbsource( 'maintenance/archives/patch-interwiki-trans.sql', $this->dbw );
+ $this->log( 'added iw_trans.' );
+ }
+
+ $this->log( 'Creating pagelinks table...' );
+ $this->dbw->query( "
+CREATE TABLE $pagelinks (
+ -- Key to the page_id of the page containing the link.
+ pl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ pl_namespace int NOT NULL default '0',
+ pl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY pl_from(pl_from,pl_namespace,pl_title),
+ KEY (pl_namespace,pl_title)
+
+) TYPE=InnoDB" );
+
+ $this->log( 'Importing live links -> pagelinks' );
+ $nlinks = $this->dbw->selectField( 'links', 'count(*)', '', $fname );
+ if( $nlinks ) {
+ $this->setChunkScale( $chunksize, $nlinks, 'pagelinks', $fname );
+ $result = $this->dbr->query( "
+ SELECT l_from,cur_namespace,cur_title
+ FROM $links, $cur
+ WHERE l_to=cur_id", $fname );
+ $add = array();
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $add[] = array(
+ 'pl_from' => $row->l_from,
+ 'pl_namespace' => $row->cur_namespace,
+ 'pl_title' => $this->conv( $row->cur_title ) );
+ $this->addChunk( $add );
+ }
+ $this->lastChunk( $add );
+ } else {
+ $this->log( 'no links!' );
+ }
+
+ $this->log( 'Importing brokenlinks -> pagelinks' );
+ $nbrokenlinks = $this->dbw->selectField( 'brokenlinks', 'count(*)', '', $fname );
+ if( $nbrokenlinks ) {
+ $this->setChunkScale( $chunksize, $nbrokenlinks, 'pagelinks', $fname );
+ $result = $this->dbr->query(
+ "SELECT bl_from, bl_to FROM $brokenlinks",
+ $fname );
+ $add = array();
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $pagename = $this->conv( $row->bl_to );
+ $title = Title::newFromText( $pagename );
+ if( is_null( $title ) ) {
+ $this->log( "** invalid brokenlink: $row->bl_from -> '$pagename' (converted from '$row->bl_to')" );
+ } else {
+ $add[] = array(
+ 'pl_from' => $row->bl_from,
+ 'pl_namespace' => $title->getNamespace(),
+ 'pl_title' => $title->getDBkey() );
+ $this->addChunk( $add );
+ }
+ }
+ $this->lastChunk( $add );
+ } else {
+ $this->log( 'no brokenlinks!' );
+ }
+
+ $this->log( 'Done with links.' );
+ }
+
+ function upgradeUser() {
+ // Apply unique index, if necessary:
+ $duper = new UserDupes( $this->dbw );
+ if( $duper->hasUniqueIndex() ) {
+ $this->log( "Already have unique user_name index." );
+ } else {
+ $this->log( "Clearing user duplicates..." );
+ if( !$duper->clearDupes() ) {
+ $this->log( "WARNING: Duplicate user accounts, may explode!" );
+ }
+ }
+
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ user_id int(5) unsigned NOT NULL auto_increment,
+ user_name varchar(255) binary NOT NULL default '',
+ user_real_name varchar(255) binary NOT NULL default '',
+ user_password tinyblob NOT NULL default '',
+ user_newpassword tinyblob NOT NULL default '',
+ user_email tinytext NOT NULL default '',
+ user_options blob NOT NULL default '',
+ user_touched char(14) binary NOT NULL default '',
+ user_token char(32) binary NOT NULL default '',
+ user_email_authenticated CHAR(14) BINARY,
+ user_email_token CHAR(32) BINARY,
+ user_email_token_expires CHAR(14) BINARY,
+
+ PRIMARY KEY user_id (user_id),
+ UNIQUE INDEX user_name (user_name),
+ INDEX (user_email_token)
+
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'user_id' => MW_UPGRADE_COPY,
+ 'user_name' => MW_UPGRADE_ENCODE,
+ 'user_real_name' => MW_UPGRADE_ENCODE,
+ 'user_password' => MW_UPGRADE_COPY,
+ 'user_newpassword' => MW_UPGRADE_COPY,
+ 'user_email' => MW_UPGRADE_ENCODE,
+ 'user_options' => MW_UPGRADE_ENCODE,
+ 'user_touched' => MW_UPGRADE_CALLBACK,
+ 'user_token' => MW_UPGRADE_COPY,
+ 'user_email_authenticated' => MW_UPGRADE_CALLBACK,
+ 'user_email_token' => MW_UPGRADE_NULL,
+ 'user_email_token_expires' => MW_UPGRADE_NULL );
+ $this->copyTable( 'user', $tabledef, $fields,
+ array( &$this, 'userCallback' ) );
+ }
+
+ function userCallback( $row, $copy ) {
+ $now = $this->dbw->timestamp();
+ $copy['user_touched'] = $now;
+ $copy['user_email_authenticated'] = $this->emailAuth ? $now : null;
+ return $copy;
+ }
+
+ function upgradeImage() {
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ img_name varchar(255) binary NOT NULL default '',
+ img_size int(8) unsigned NOT NULL default '0',
+ img_width int(5) NOT NULL default '0',
+ img_height int(5) NOT NULL default '0',
+ img_metadata mediumblob NOT NULL,
+ img_bits int(3) NOT NULL default '0',
+ img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+ img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown",
+ img_minor_mime varchar(32) NOT NULL default "unknown",
+ img_description tinyblob NOT NULL default '',
+ img_user int(5) unsigned NOT NULL default '0',
+ img_user_text varchar(255) binary NOT NULL default '',
+ img_timestamp char(14) binary NOT NULL default '',
+
+ PRIMARY KEY img_name (img_name),
+ INDEX img_size (img_size),
+ INDEX img_timestamp (img_timestamp)
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'img_name' => MW_UPGRADE_ENCODE,
+ 'img_size' => MW_UPGRADE_COPY,
+ 'img_width' => MW_UPGRADE_CALLBACK,
+ 'img_height' => MW_UPGRADE_CALLBACK,
+ 'img_metadata' => MW_UPGRADE_CALLBACK,
+ 'img_bits' => MW_UPGRADE_CALLBACK,
+ 'img_media_type' => MW_UPGRADE_CALLBACK,
+ 'img_major_mime' => MW_UPGRADE_CALLBACK,
+ 'img_minor_mime' => MW_UPGRADE_CALLBACK,
+ 'img_description' => MW_UPGRADE_ENCODE,
+ 'img_user' => MW_UPGRADE_COPY,
+ 'img_user_text' => MW_UPGRADE_ENCODE,
+ 'img_timestamp' => MW_UPGRADE_COPY );
+ $this->copyTable( 'image', $tabledef, $fields,
+ array( &$this, 'imageCallback' ) );
+ }
+
+ function imageCallback( $row, $copy ) {
+ global $options;
+ if( !isset( $options['noimage'] ) ) {
+ // Fill in the new image info fields
+ $info = $this->imageInfo( $row->img_name );
+
+ $copy['img_width' ] = $info['width'];
+ $copy['img_height' ] = $info['height'];
+ $copy['img_metadata' ] = ""; // loaded on-demand
+ $copy['img_bits' ] = $info['bits'];
+ $copy['img_media_type'] = $info['media'];
+ $copy['img_major_mime'] = $info['major'];
+ $copy['img_minor_mime'] = $info['minor'];
+ }
+
+ // If doing UTF8 conversion the file must be renamed
+ $this->renameFile( $row->img_name, 'wfImageDir' );
+
+ return $copy;
+ }
+
+ function imageInfo( $name, $subdirCallback='wfImageDir', $basename = null ) {
+ if( is_null( $basename ) ) $basename = $name;
+ $dir = call_user_func( $subdirCallback, $basename );
+ $filename = $dir . '/' . $name;
+ $info = array(
+ 'width' => 0,
+ 'height' => 0,
+ 'bits' => 0,
+ 'media' => '',
+ 'major' => '',
+ 'minor' => '' );
+
+ $magic =& wfGetMimeMagic();
+ $mime = $magic->guessMimeType( $filename, true );
+ list( $info['major'], $info['minor'] ) = explode( '/', $mime );
+
+ $info['media'] = $magic->getMediaType( $filename, $mime );
+
+ # Height and width
+ $gis = false;
+ if( $mime == 'image/svg' ) {
+ $gis = wfGetSVGsize( $filename );
+ } elseif( $magic->isPHPImageType( $mime ) ) {
+ $gis = getimagesize( $filename );
+ } else {
+ $this->log( "Surprising mime type: $mime" );
+ }
+ if( $gis ) {
+ $info['width' ] = $gis[0];
+ $info['height'] = $gis[1];
+ }
+ if( isset( $gis['bits'] ) ) {
+ $info['bits'] = $gis['bits'];
+ }
+
+ return $info;
+ }
+
+
+ /**
+ * Truncate a table.
+ * @param string $table The table name to be truncated
+ */
+ function clearTable( $table ) {
+ print "Clearing $table...\n";
+ $tableName = $this->db->tableName( $table );
+ $this->db->query( 'TRUNCATE $tableName' );
+ }
+
+ /**
+ * Rename a given image or archived image file to the converted filename,
+ * leaving a symlink for URL compatibility.
+ *
+ * @param string $oldname pre-conversion filename
+ * @param string $basename pre-conversion base filename for dir hashing, if an archive
+ * @access private
+ */
+ function renameFile( $oldname, $subdirCallback='wfImageDir', $basename=null ) {
+ $newname = $this->conv( $oldname );
+ if( $newname == $oldname ) {
+ // No need to rename; another field triggered this row.
+ return false;
+ }
+
+ if( is_null( $basename ) ) $basename = $oldname;
+ $ubasename = $this->conv( $basename );
+ $oldpath = call_user_func( $subdirCallback, $basename ) . '/' . $oldname;
+ $newpath = call_user_func( $subdirCallback, $ubasename ) . '/' . $newname;
+
+ $this->log( "$oldpath -> $newpath" );
+ if( rename( $oldpath, $newpath ) ) {
+ $relpath = $this->relativize( $newpath, dirname( $oldpath ) );
+ if( !symlink( $relpath, $oldpath ) ) {
+ $this->log( "... symlink failed!" );
+ }
+ return $newname;
+ } else {
+ $this->log( "... rename failed!" );
+ return false;
+ }
+ }
+
+ /**
+ * Generate a relative path name to the given file.
+ * Assumes Unix-style paths, separators, and semantics.
+ *
+ * @param string $path Absolute destination path including target filename
+ * @param string $from Absolute source path, directory only
+ * @return string
+ * @access private
+ * @static
+ */
+ function relativize( $path, $from ) {
+ $pieces = explode( '/', dirname( $path ) );
+ $against = explode( '/', $from );
+
+ // Trim off common prefix
+ while( count( $pieces ) && count( $against )
+ && $pieces[0] == $against[0] ) {
+ array_shift( $pieces );
+ array_shift( $against );
+ }
+
+ // relative dots to bump us to the parent
+ while( count( $against ) ) {
+ array_unshift( $pieces, '..' );
+ array_shift( $against );
+ }
+
+ array_push( $pieces, wfBaseName( $path ) );
+
+ return implode( '/', $pieces );
+ }
+
+ function upgradeOldImage() {
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ -- Base filename: key to image.img_name
+ oi_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of the archived file.
+ -- This is generally a timestamp and '!' prepended to the base name.
+ oi_archive_name varchar(255) binary NOT NULL default '',
+
+ -- Other fields as in image...
+ oi_size int(8) unsigned NOT NULL default 0,
+ oi_width int(5) NOT NULL default 0,
+ oi_height int(5) NOT NULL default 0,
+ oi_bits int(3) NOT NULL default 0,
+ oi_description tinyblob NOT NULL default '',
+ oi_user int(5) unsigned NOT NULL default '0',
+ oi_user_text varchar(255) binary NOT NULL default '',
+ oi_timestamp char(14) binary NOT NULL default '',
+
+ INDEX oi_name (oi_name(10))
+
+) TYPE=InnoDB;
+END;
+ $fields = array(
+ 'oi_name' => MW_UPGRADE_ENCODE,
+ 'oi_archive_name' => MW_UPGRADE_ENCODE,
+ 'oi_size' => MW_UPGRADE_COPY,
+ 'oi_width' => MW_UPGRADE_CALLBACK,
+ 'oi_height' => MW_UPGRADE_CALLBACK,
+ 'oi_bits' => MW_UPGRADE_CALLBACK,
+ 'oi_description' => MW_UPGRADE_ENCODE,
+ 'oi_user' => MW_UPGRADE_COPY,
+ 'oi_user_text' => MW_UPGRADE_ENCODE,
+ 'oi_timestamp' => MW_UPGRADE_COPY );
+ $this->copyTable( 'oldimage', $tabledef, $fields,
+ array( &$this, 'oldimageCallback' ) );
+ }
+
+ function oldimageCallback( $row, $copy ) {
+ global $options;
+ if( !isset( $options['noimage'] ) ) {
+ // Fill in the new image info fields
+ $info = $this->imageInfo( $row->oi_archive_name, 'wfImageArchiveDir', $row->oi_name );
+ $copy['oi_width' ] = $info['width' ];
+ $copy['oi_height'] = $info['height'];
+ $copy['oi_bits' ] = $info['bits' ];
+ }
+
+ // If doing UTF8 conversion the file must be renamed
+ $this->renameFile( $row->oi_archive_name, 'wfImageArchiveDir', $row->oi_name );
+
+ return $copy;
+ }
+
+
+ function upgradeWatchlist() {
+ $fname = 'FiveUpgrade::upgradeWatchlist';
+ $chunksize = 100;
+
+ extract( $this->dbw->tableNames( 'watchlist', 'watchlist_temp' ) );
+
+ $this->log( 'Migrating watchlist table to watchlist_temp...' );
+ $this->dbw->query(
+"CREATE TABLE $watchlist_temp (
+ -- Key to user_id
+ wl_user int(5) unsigned NOT NULL,
+
+ -- Key to page_namespace/page_title
+ -- Note that users may watch patches which do not exist yet,
+ -- or existed in the past but have been deleted.
+ wl_namespace int NOT NULL default '0',
+ wl_title varchar(255) binary NOT NULL default '',
+
+ -- Timestamp when user was last sent a notification e-mail;
+ -- cleared when the user visits the page.
+ -- FIXME: add proper null support etc
+ wl_notificationtimestamp varchar(14) binary NOT NULL default '0',
+
+ UNIQUE KEY (wl_user, wl_namespace, wl_title),
+ KEY namespace_title (wl_namespace,wl_title)
+
+) TYPE=InnoDB;", $fname );
+
+ // Fix encoding for Latin-1 upgrades, add some fields,
+ // and double article to article+talk pairs
+ $numwatched = $this->dbw->selectField( 'watchlist', 'count(*)', '', $fname );
+
+ $this->setChunkScale( $chunksize, $numwatched * 2, 'watchlist_temp', $fname );
+ $result = $this->dbr->select( 'watchlist',
+ array(
+ 'wl_user',
+ 'wl_namespace',
+ 'wl_title' ),
+ '',
+ $fname );
+
+ $add = array();
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $now = $this->dbw->timestamp();
+ $add[] = array(
+ 'wl_user' => $row->wl_user,
+ 'wl_namespace' => Namespace::getSubject( $row->wl_namespace ),
+ 'wl_title' => $this->conv( $row->wl_title ),
+ 'wl_notificationtimestamp' => '0' );
+ $this->addChunk( $add );
+
+ $add[] = array(
+ 'wl_user' => $row->wl_user,
+ 'wl_namespace' => Namespace::getTalk( $row->wl_namespace ),
+ 'wl_title' => $this->conv( $row->wl_title ),
+ 'wl_notificationtimestamp' => '0' );
+ $this->addChunk( $add );
+ }
+ $this->lastChunk( $add );
+ $this->dbr->freeResult( $result );
+
+ $this->log( 'Done converting watchlist.' );
+ $this->cleanupSwaps[] = 'watchlist';
+ }
+
+ function upgradeLogging() {
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ -- Symbolic keys for the general log type and the action type
+ -- within the log. The output format will be controlled by the
+ -- action field, but only the type controls categorization.
+ log_type char(10) NOT NULL default '',
+ log_action char(10) NOT NULL default '',
+
+ -- Timestamp. Duh.
+ log_timestamp char(14) NOT NULL default '19700101000000',
+
+ -- The user who performed this action; key to user_id
+ log_user int unsigned NOT NULL default 0,
+
+ -- Key to the page affected. Where a user is the target,
+ -- this will point to the user page.
+ log_namespace int NOT NULL default 0,
+ log_title varchar(255) binary NOT NULL default '',
+
+ -- Freeform text. Interpreted as edit history comments.
+ log_comment varchar(255) NOT NULL default '',
+
+ -- LF separated list of miscellaneous parameters
+ log_params blob NOT NULL default '',
+
+ KEY type_time (log_type, log_timestamp),
+ KEY user_time (log_user, log_timestamp),
+ KEY page_time (log_namespace, log_title, log_timestamp)
+
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'log_type' => MW_UPGRADE_COPY,
+ 'log_action' => MW_UPGRADE_COPY,
+ 'log_timestamp' => MW_UPGRADE_COPY,
+ 'log_user' => MW_UPGRADE_COPY,
+ 'log_namespace' => MW_UPGRADE_COPY,
+ 'log_title' => MW_UPGRADE_ENCODE,
+ 'log_comment' => MW_UPGRADE_ENCODE,
+ 'log_params' => MW_UPGRADE_ENCODE );
+ $this->copyTable( 'logging', $tabledef, $fields );
+ }
+
+ function upgradeArchive() {
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ ar_namespace int NOT NULL default '0',
+ ar_title varchar(255) binary NOT NULL default '',
+ ar_text mediumblob NOT NULL default '',
+
+ ar_comment tinyblob NOT NULL default '',
+ ar_user int(5) unsigned NOT NULL default '0',
+ ar_user_text varchar(255) binary NOT NULL,
+ ar_timestamp char(14) binary NOT NULL default '',
+ ar_minor_edit tinyint(1) NOT NULL default '0',
+
+ ar_flags tinyblob NOT NULL default '',
+
+ ar_rev_id int(8) unsigned,
+ ar_text_id int(8) unsigned,
+
+ KEY name_title_timestamp (ar_namespace,ar_title,ar_timestamp)
+
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'ar_namespace' => MW_UPGRADE_COPY,
+ 'ar_title' => MW_UPGRADE_ENCODE,
+ 'ar_text' => MW_UPGRADE_COPY,
+ 'ar_comment' => MW_UPGRADE_ENCODE,
+ 'ar_user' => MW_UPGRADE_COPY,
+ 'ar_user_text' => MW_UPGRADE_ENCODE,
+ 'ar_timestamp' => MW_UPGRADE_COPY,
+ 'ar_minor_edit' => MW_UPGRADE_COPY,
+ 'ar_flags' => MW_UPGRADE_COPY,
+ 'ar_rev_id' => MW_UPGRADE_NULL,
+ 'ar_text_id' => MW_UPGRADE_NULL );
+ $this->copyTable( 'archive', $tabledef, $fields );
+ }
+
+ function upgradeImagelinks() {
+ global $wgUseLatin1;
+ if( $wgUseLatin1 ) {
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ -- Key to page_id of the page containing the image / media link.
+ il_from int(8) unsigned NOT NULL default '0',
+
+ -- Filename of target image.
+ -- This is also the page_title of the file's description page;
+ -- all such pages are in namespace 6 (NS_IMAGE).
+ il_to varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY il_from(il_from,il_to),
+ KEY (il_to)
+
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'il_from' => MW_UPGRADE_COPY,
+ 'il_to' => MW_UPGRADE_ENCODE );
+ $this->copyTable( 'imagelinks', $tabledef, $fields );
+ }
+ }
+
+ function upgradeCategorylinks() {
+ global $wgUseLatin1;
+ if( $wgUseLatin1 ) {
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ cl_from int(8) unsigned NOT NULL default '0',
+ cl_to varchar(255) binary NOT NULL default '',
+ cl_sortkey varchar(86) binary NOT NULL default '',
+ cl_timestamp timestamp NOT NULL,
+
+ UNIQUE KEY cl_from(cl_from,cl_to),
+ KEY cl_sortkey(cl_to,cl_sortkey),
+ KEY cl_timestamp(cl_to,cl_timestamp)
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'cl_from' => MW_UPGRADE_COPY,
+ 'cl_to' => MW_UPGRADE_ENCODE,
+ 'cl_sortkey' => MW_UPGRADE_ENCODE,
+ 'cl_timestamp' => MW_UPGRADE_COPY );
+ $this->copyTable( 'categorylinks', $tabledef, $fields );
+ }
+ }
+
+ function upgradeIpblocks() {
+ global $wgUseLatin1;
+ if( $wgUseLatin1 ) {
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ ipb_id int(8) NOT NULL auto_increment,
+ ipb_address varchar(40) binary NOT NULL default '',
+ ipb_user int(8) unsigned NOT NULL default '0',
+ ipb_by int(8) unsigned NOT NULL default '0',
+ ipb_reason tinyblob NOT NULL default '',
+ ipb_timestamp char(14) binary NOT NULL default '',
+ ipb_auto tinyint(1) NOT NULL default '0',
+ ipb_expiry char(14) binary NOT NULL default '',
+
+ PRIMARY KEY ipb_id (ipb_id),
+ INDEX ipb_address (ipb_address),
+ INDEX ipb_user (ipb_user)
+
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'ipb_id' => MW_UPGRADE_COPY,
+ 'ipb_address' => MW_UPGRADE_COPY,
+ 'ipb_user' => MW_UPGRADE_COPY,
+ 'ipb_by' => MW_UPGRADE_COPY,
+ 'ipb_reason' => MW_UPGRADE_ENCODE,
+ 'ipb_timestamp' => MW_UPGRADE_COPY,
+ 'ipb_auto' => MW_UPGRADE_COPY,
+ 'ipb_expiry' => MW_UPGRADE_COPY );
+ $this->copyTable( 'ipblocks', $tabledef, $fields );
+ }
+ }
+
+ function upgradeRecentchanges() {
+ // There's a format change in the namespace field
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ rc_id int(8) NOT NULL auto_increment,
+ rc_timestamp varchar(14) binary NOT NULL default '',
+ rc_cur_time varchar(14) binary NOT NULL default '',
+
+ rc_user int(10) unsigned NOT NULL default '0',
+ rc_user_text varchar(255) binary NOT NULL default '',
+
+ rc_namespace int NOT NULL default '0',
+ rc_title varchar(255) binary NOT NULL default '',
+
+ rc_comment varchar(255) binary NOT NULL default '',
+ rc_minor tinyint(3) unsigned NOT NULL default '0',
+
+ rc_bot tinyint(3) unsigned NOT NULL default '0',
+ rc_new tinyint(3) unsigned NOT NULL default '0',
+
+ rc_cur_id int(10) unsigned NOT NULL default '0',
+ rc_this_oldid int(10) unsigned NOT NULL default '0',
+ rc_last_oldid int(10) unsigned NOT NULL default '0',
+
+ rc_type tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_title varchar(255) binary NOT NULL default '',
+
+ rc_patrolled tinyint(3) unsigned NOT NULL default '0',
+
+ rc_ip char(15) NOT NULL default '',
+
+ PRIMARY KEY rc_id (rc_id),
+ INDEX rc_timestamp (rc_timestamp),
+ INDEX rc_namespace_title (rc_namespace, rc_title),
+ INDEX rc_cur_id (rc_cur_id),
+ INDEX new_name_timestamp(rc_new,rc_namespace,rc_timestamp),
+ INDEX rc_ip (rc_ip)
+
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'rc_id' => MW_UPGRADE_COPY,
+ 'rc_timestamp' => MW_UPGRADE_COPY,
+ 'rc_cur_time' => MW_UPGRADE_COPY,
+ 'rc_user' => MW_UPGRADE_COPY,
+ 'rc_user_text' => MW_UPGRADE_ENCODE,
+ 'rc_namespace' => MW_UPGRADE_COPY,
+ 'rc_title' => MW_UPGRADE_ENCODE,
+ 'rc_comment' => MW_UPGRADE_ENCODE,
+ 'rc_minor' => MW_UPGRADE_COPY,
+ 'rc_bot' => MW_UPGRADE_COPY,
+ 'rc_new' => MW_UPGRADE_COPY,
+ 'rc_cur_id' => MW_UPGRADE_COPY,
+ 'rc_this_oldid' => MW_UPGRADE_COPY,
+ 'rc_last_oldid' => MW_UPGRADE_COPY,
+ 'rc_type' => MW_UPGRADE_COPY,
+ 'rc_moved_to_ns' => MW_UPGRADE_COPY,
+ 'rc_moved_to_title' => MW_UPGRADE_ENCODE,
+ 'rc_patrolled' => MW_UPGRADE_COPY,
+ 'rc_ip' => MW_UPGRADE_COPY );
+ $this->copyTable( 'recentchanges', $tabledef, $fields );
+ }
+
+ function upgradeQuerycache() {
+ // There's a format change in the namespace field
+ $tabledef = <<<END
+CREATE TABLE $1 (
+ -- A key name, generally the base name of of the special page.
+ qc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qc_namespace int NOT NULL default '0',
+ qc_title char(255) binary NOT NULL default '',
+
+ KEY (qc_type,qc_value)
+
+) TYPE=InnoDB
+END;
+ $fields = array(
+ 'qc_type' => MW_UPGRADE_COPY,
+ 'qc_value' => MW_UPGRADE_COPY,
+ 'qc_namespace' => MW_UPGRADE_COPY,
+ 'qc_title' => MW_UPGRADE_ENCODE );
+ $this->copyTable( 'querycache', $tabledef, $fields );
+ }
+
+ /**
+ * Rename all our temporary tables into final place.
+ * We've left things in place so a read-only wiki can continue running
+ * on the old code during all this.
+ */
+ function upgradeCleanup() {
+ $this->renameTable( 'old', 'text' );
+
+ foreach( $this->cleanupSwaps as $table ) {
+ $this->swap( $table );
+ }
+ }
+
+ function renameTable( $from, $to ) {
+ $this->log( "Renaming $from to $to..." );
+
+ $fromtable = $this->dbw->tableName( $from );
+ $totable = $this->dbw->tableName( $to );
+ $this->dbw->query( "ALTER TABLE $fromtable RENAME TO $totable" );
+ }
+
+ function swap( $base ) {
+ $this->renameTable( $base, "{$base}_old" );
+ $this->renameTable( "{$base}_temp", $base );
+ }
+
+}
+
+?>
diff --git a/maintenance/Makefile b/maintenance/Makefile
new file mode 100644
index 000000000000..97f8b60bfa5f
--- /dev/null
+++ b/maintenance/Makefile
@@ -0,0 +1,20 @@
+.PHONY: help test test-light
+help:
+ # Run 'make test' to run the parser tests.
+ # Run 'make doc' to run the phpdoc generation.
+ # Run 'make doxydoc' (unsupported doxygen generation).
+
+test:
+ php parserTests.php
+
+test-light:
+ php parserTests.php --color=light
+
+doc:
+ php mwdocgen.php -all
+ echo 'Doc generation done. Look at ./docs/html/'
+
+doxydoc:
+ cd .. && doxygen maintenance/mwdoxygen.cfg
+ echo 'Doc generation done. Look at ./docs/html/'
+
diff --git a/maintenance/README b/maintenance/README
new file mode 100644
index 000000000000..9eb69ba86ae8
--- /dev/null
+++ b/maintenance/README
@@ -0,0 +1,85 @@
+== MediaWiki Maintenance ==
+
+The .sql scripts in this directory are not intended to be run standalone,
+although this is appropriate in some cases, e.g. manual creation of blank tables
+prior to an import.
+
+Most of the PHP scripts need to be run from the command line. Prior to doing so,
+ensure that the LocalSettings.php file in the directory above points to the
+proper installation.
+
+Certain scripts will require elevated access to the database. In order to
+provide this, first create a MySQL user with "all" permissions on the wiki
+database, and then place their username and password in an AdminSettings.php
+file in the directory above. See AdminSettings.sample for specifics on this.
+
+=== Brief explanation of files ===
+
+A lot of the files in this directory are PHP scripts used to perform various
+maintenance tasks on the wiki database, e.g. rebuilding link tables, updating
+the search indices, etc. The files in the "archives" directory are used to
+upgrade the database schema when updating the software. Some schema definitions
+for alternative (as yet unsupported) database management systems are stored
+here too.
+
+The "storage" directory contains scripts and resources useful for working with
+external storage clusters, and are not likely to be particularly useful to the
+vast majority of installations. This directory does contain the compressOld
+scripts, however, which can be useful for compacting old data.
+
+=== Maintenance scripts ===
+
+As noted above, these should be run from the command line. Not all scripts are
+listed, as some are Wikimedia-specific, and some are not applicable to most
+installations.
+
+ changePassword.php
+ Reset the password of a specified user
+
+ cleanupSpam.php
+ Mass-revert insertion of linkspam
+
+ deleteOldRevisions.php
+ Erase old revisions of pages from the database
+
+ dumpBackup.php
+ Backup dump script
+
+ dumpHTML.php
+ Produce an HTML dump of a wiki
+
+ importDump.php
+ XML dump importer
+
+ importImages.php
+ Imports images into the wiki
+
+ importTextFile.php
+ Imports the contents of a text file into a wiki page
+
+ nukePage.php
+ Wipe a page and all revisions from the database
+
+ reassignEdits.php
+ Reassign edits from one user to another
+
+ rebuildImages.php
+ Update image metadata records
+
+ rebuildMessages.php
+ Update the MediaWiki namespace after changing site language
+
+ rebuildtextindex.php
+ Rebuild the fulltext search indices
+
+ refreshLinks.php
+ Rebuild the link tables
+
+ removeUnusedAccounts.php
+ Remove user accounts which have made no edits
+
+ runJobs.php
+ Immediately complete all jobs in the job queue
+
+ update.php
+ Check and upgrade the database schema to the current version \ No newline at end of file
diff --git a/maintenance/addwiki.php b/maintenance/addwiki.php
new file mode 100644
index 000000000000..b7843632b24b
--- /dev/null
+++ b/maintenance/addwiki.php
@@ -0,0 +1,234 @@
+<?php
+
+$wgNoDBParam = true;
+
+require_once( "commandLine.inc" );
+require_once( "rebuildInterwiki.inc" );
+require_once( "languages/Names.php" );
+if ( count( $args ) != 3 ) {
+ wfDie( "Usage: php addwiki.php <language> <site> <dbname>\n" );
+}
+
+addWiki( $args[0], $args[1], $args[2] );
+
+# -----------------------------------------------------------------
+
+function addWiki( $lang, $site, $dbName )
+{
+ global $IP, $wgLanguageNames, $wgDefaultExternalStore;
+
+ $name = $wgLanguageNames[$lang];
+
+ $dbw =& wfGetDB( DB_WRITE );
+ $common = "/home/wikipedia/common";
+ $maintenance = "$IP/maintenance";
+
+ print "Creating database $dbName for $lang.$site\n";
+
+ # Set up the database
+ $dbw->query( "SET table_type=Innodb" );
+ $dbw->query( "CREATE DATABASE $dbName" );
+ $dbw->selectDB( $dbName );
+
+ print "Initialising tables\n";
+ dbsource( "$maintenance/tables.sql", $dbw );
+ dbsource( "$IP/extensions/OAI/update_table.sql", $dbw );
+ dbsource( "$IP/extensions/AntiSpoof/mysql/patch-antispoof.sql", $dbw );
+ $dbw->query( "INSERT INTO site_stats(ss_row_id) VALUES (1)" );
+
+ # Initialise external storage
+ if ( is_array( $wgDefaultExternalStore ) ) {
+ $stores = $wgDefaultExternalStore;
+ } elseif ( $stores ) {
+ $stores = array( $wgDefaultExternalStore );
+ } else {
+ $stores = array();
+ }
+ if ( count( $stores ) ) {
+ require_once( 'ExternalStoreDB.php' );
+ print "Initialising external storage $store...\n";
+ global $wgDBuser, $wgDBpassword, $wgExternalServers;
+ foreach ( $stores as $storeURL ) {
+ if ( !preg_match( '!^DB://(.*)$!', $storeURL, $m ) ) {
+ continue;
+ }
+
+ $cluster = $m[1];
+
+ # Hack
+ $wgExternalServers[$cluster][0]['user'] = $wgDBuser;
+ $wgExternalServers[$cluster][0]['password'] = $wgDBpassword;
+
+ $store = new ExternalStoreDB;
+ $extdb =& $store->getMaster( $cluster );
+ $extdb->query( "SET table_type=InnoDB" );
+ $extdb->query( "CREATE DATABASE $dbName" );
+ $extdb->selectDB( $dbName );
+ dbsource( "$maintenance/storage/blobs.sql", $extdb );
+ $extdb->immediateCommit();
+ }
+ }
+
+ $wgTitle = Title::newMainPage();
+ $wgArticle = new Article( $wgTitle );
+ $ucsite = ucfirst( $site );
+
+ $wgArticle->insertNewArticle( "
+==This subdomain is reserved for the creation of a $ucsite in '''[[:en:{$name}|{$name}]]''' language==
+
+If you can write in this language and want to collaborate in the creation of this encyclopedia then '''you''' can make it.
+
+Go ahead. Translate this page and start working on your encyclopedia.
+
+For help, see '''[[m:Help:How to start a new Wikipedia|how to start a new Wikipedia]]'''.
+
+==Sister projects==
+[http://meta.wikipedia.org Meta-Wikipedia] | [http://www.wiktionary.org Wikitonary] | [http://www.wikibooks.org Wikibooks] | [http://www.wikinews.org Wikinews] | [http://www.wikiquote.org Wikiquote] | [http://www.wikisource.org Wikisource]
+
+See the [http://www.wikipedia.org Wikipedia portal] for other language Wikipedias.
+
+[[aa:]]
+[[af:]]
+[[als:]]
+[[ar:]]
+[[de:]]
+[[en:]]
+[[as:]]
+[[ast:]]
+[[ay:]]
+[[az:]]
+[[be:]]
+[[bg:]]
+[[bn:]]
+[[bo:]]
+[[bs:]]
+[[cs:]]
+[[co:]]
+[[cs:]]
+[[cy:]]
+[[da:]]
+[[el:]]
+[[eo:]]
+[[es:]]
+[[et:]]
+[[eu:]]
+[[fa:]]
+[[fi:]]
+[[fr:]]
+[[fy:]]
+[[ga:]]
+[[gl:]]
+[[gn:]]
+[[gu:]]
+[[he:]]
+[[hi:]]
+[[hr:]]
+[[hy:]]
+[[ia:]]
+[[id:]]
+[[is:]]
+[[it:]]
+[[ja:]]
+[[ka:]]
+[[kk:]]
+[[km:]]
+[[kn:]]
+[[ko:]]
+[[ks:]]
+[[ku:]]
+[[ky:]]
+[[la:]]
+[[ln:]]
+[[lo:]]
+[[lt:]]
+[[lv:]]
+[[hu:]]
+[[mi:]]
+[[mk:]]
+[[ml:]]
+[[mn:]]
+[[mr:]]
+[[ms:]]
+[[mt:]]
+[[my:]]
+[[na:]]
+[[nah:]]
+[[nds:]]
+[[ne:]]
+[[nl:]]
+[[no:]]
+[[oc:]]
+[[om:]]
+[[pa:]]
+[[pl:]]
+[[ps:]]
+[[pt:]]
+[[qu:]]
+[[ro:]]
+[[ru:]]
+[[sa:]]
+[[si:]]
+[[sk:]]
+[[sl:]]
+[[sq:]]
+[[sr:]]
+[[sv:]]
+[[sw:]]
+[[ta:]]
+[[te:]]
+[[tg:]]
+[[th:]]
+[[tk:]]
+[[tl:]]
+[[tr:]]
+[[tt:]]
+[[ug:]]
+[[uk:]]
+[[ur:]]
+[[uz:]]
+[[vi:]]
+[[vo:]]
+[[xh:]]
+[[yo:]]
+[[za:]]
+[[zh:]]
+[[zu:]]
+", '', false, false );
+
+ print "Adding to dblists\n";
+
+ # Add to dblist
+ $file = fopen( "$common/all.dblist", "a" );
+ fwrite( $file, "$dbName\n" );
+ fclose( $file );
+
+ # Update the sublists
+ system("cd $common && ./refresh-dblist");
+
+ print "Constructing interwiki SQL\n";
+ # Rebuild interwiki tables
+ $sql = getRebuildInterwikiSQL();
+ $tempname = tempnam( '/tmp', 'addwiki' );
+ $file = fopen( $tempname, 'w' );
+ if ( !$file ) {
+ wfDie( "Error, unable to open temporary file $tempname\n" );
+ }
+ fwrite( $file, $sql );
+ fclose( $file );
+ print "Sourcing interwiki SQL\n";
+ dbsource( $tempname, $dbw );
+ #unlink( $tempname );
+
+ # Create the upload dir
+ global $wgUploadDirectory;
+ if( file_exists( $wgUploadDirectory ) ) {
+ echo "$wgUploadDirectory already exists.\n";
+ } else {
+ echo "Creating $wgUploadDirectory...\n";
+ mkdir( $wgUploadDirectory, 0777 );
+ chmod( $wgUploadDirectory, 0777 );
+ }
+
+ print "Script ended. You now want to run sync-common-all to publish *dblist files (check them for duplicates first)\n";
+}
+?>
diff --git a/maintenance/apache-ampersand.diff b/maintenance/apache-ampersand.diff
new file mode 100644
index 000000000000..f281ce15ee19
--- /dev/null
+++ b/maintenance/apache-ampersand.diff
@@ -0,0 +1,53 @@
+--- orig/apache_1.3.26/src/modules/standard/mod_rewrite.h Wed Mar 13 13:05:34 2002
++++ apache_1.3.26/src/modules/standard/mod_rewrite.h Tue Oct 15 14:07:21 2002
+@@ -447,6 +447,7 @@
+ static char *rewrite_mapfunc_toupper(request_rec *r, char *key);
+ static char *rewrite_mapfunc_tolower(request_rec *r, char *key);
+ static char *rewrite_mapfunc_escape(request_rec *r, char *key);
++static char *rewrite_mapfunc_ampescape(request_rec *r, char *key);
+ static char *rewrite_mapfunc_unescape(request_rec *r, char *key);
+ static char *select_random_value_part(request_rec *r, char *value);
+ static void rewrite_rand_init(void);
+--- orig/apache_1.3.26/src/modules/standard/mod_rewrite.c Wed May 29 10:39:23 2002
++++ apache_1.3.26/src/modules/standard/mod_rewrite.c Tue Oct 15 14:07:49 2002
+@@ -502,6 +502,9 @@
+ else if (strcmp(a2+4, "unescape") == 0) {
+ new->func = rewrite_mapfunc_unescape;
+ }
++ else if (strcmp(a2+4, "ampescape") == 0) {
++ new->func = rewrite_mapfunc_ampescape;
++ }
+ else if (sconf->state == ENGINE_ENABLED) {
+ return ap_pstrcat(cmd->pool, "RewriteMap: internal map not found:",
+ a2+4, NULL);
+@@ -2982,6 +2985,30 @@
+
+ value = ap_escape_uri(r->pool, key);
+ return value;
++}
++
++static char *rewrite_mapfunc_ampescape(request_rec *r, char *key)
++{
++ /* We only need to escape the ampersand */
++ char *copy = ap_palloc(r->pool, 3 * strlen(key) + 3);
++ const unsigned char *s = (const unsigned char *)key;
++ unsigned char *d = (unsigned char *)copy;
++ unsigned c;
++
++ while ((c = *s)) {
++ if (c == '&') {
++ *d++ = '%';
++ *d++ = '2';
++ *d++ = '6';
++ }
++ else {
++ *d++ = c;
++ }
++ ++s;
++ }
++ *d = '\0';
++
++ return copy;
+ }
+
+ static char *rewrite_mapfunc_unescape(request_rec *r, char *key)
diff --git a/maintenance/archives/.htaccess b/maintenance/archives/.htaccess
new file mode 100644
index 000000000000..3a4288278871
--- /dev/null
+++ b/maintenance/archives/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/maintenance/archives/patch-archive-rev_id.sql b/maintenance/archives/patch-archive-rev_id.sql
new file mode 100644
index 000000000000..375001b8e1af
--- /dev/null
+++ b/maintenance/archives/patch-archive-rev_id.sql
@@ -0,0 +1,6 @@
+-- New field in archive table to preserve revision IDs across undeletion.
+-- Added 2005-03-10
+
+ALTER TABLE /*$wgDBprefix*/archive
+ ADD
+ ar_rev_id int(8) unsigned;
diff --git a/maintenance/archives/patch-archive-text_id.sql b/maintenance/archives/patch-archive-text_id.sql
new file mode 100644
index 000000000000..f59715ff7b65
--- /dev/null
+++ b/maintenance/archives/patch-archive-text_id.sql
@@ -0,0 +1,14 @@
+-- New field in archive table to preserve text source IDs across undeletion.
+--
+-- Older entries containing NULL in this field will contain text in the
+-- ar_text and ar_flags fields, and will cause the (re)creation of a new
+-- text record upon undeletion.
+--
+-- Newer ones will reference a text.old_id with this field, and the existing
+-- entries will be used as-is; only a revision record need be created.
+--
+-- Added 2005-05-01
+
+ALTER TABLE /*$wgDBprefix*/archive
+ ADD
+ ar_text_id int(8) unsigned;
diff --git a/maintenance/archives/patch-backlinkindexes.sql b/maintenance/archives/patch-backlinkindexes.sql
new file mode 100644
index 000000000000..5facd9ea1b88
--- /dev/null
+++ b/maintenance/archives/patch-backlinkindexes.sql
@@ -0,0 +1,19 @@
+--
+-- patch-backlinkindexes.sql
+--
+-- Per bug 6440 / http://bugzilla.wikimedia.org/show_bug.cgi?id=6440
+--
+-- Improve performance of the "what links here"-type queries
+--
+
+ALTER TABLE /*$wgDBprefix*/pagelinks
+ DROP INDEX pl_namespace,
+ ADD INDEX pl_namespace(pl_namespace, pl_title, pl_from);
+
+ALTER TABLE /*$wgDBprefix*/templatelinks
+ DROP INDEX tl_namespace,
+ ADD INDEX tl_namespace(tl_namespace, tl_title, tl_from);
+
+ALTER TABLE /*$wgDBprefix*/imagelinks
+ DROP INDEX il_to,
+ ADD INDEX il_to(il_to, il_from);
diff --git a/maintenance/archives/patch-bot.sql b/maintenance/archives/patch-bot.sql
new file mode 100644
index 000000000000..ce61884c4427
--- /dev/null
+++ b/maintenance/archives/patch-bot.sql
@@ -0,0 +1,11 @@
+-- Add field to recentchanges for easy filtering of bot entries
+-- edits by a user with 'bot' in user.user_rights should be
+-- marked 1 in rc_bot.
+
+-- Change made 2002-12-15 by Brion VIBBER <brion@pobox.com>
+-- this affects code in Article.php, User.php SpecialRecentchanges.php
+-- column also added to buildTables.inc
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD COLUMN rc_bot tinyint(3) unsigned NOT NULL default '0'
+ AFTER rc_minor;
diff --git a/maintenance/archives/patch-cache.sql b/maintenance/archives/patch-cache.sql
new file mode 100644
index 000000000000..5651c3ce6c11
--- /dev/null
+++ b/maintenance/archives/patch-cache.sql
@@ -0,0 +1,41 @@
+-- patch-cache.sql
+-- 2003-03-22 <brion@pobox.com>
+--
+-- Add 'last touched' fields to cur and user tables.
+-- These are useful for maintaining cache consistency.
+-- (Updates to OutputPage.php and elsewhere.)
+--
+-- cur_touched should be set to the current time whenever:
+-- * the page is updated
+-- * a linked page is created
+-- * a linked page is destroyed
+--
+-- The cur_touched time will then be compared against the
+-- timestamps of cached pages to ensure consistency; if
+-- cur_touched is later, the page must be regenerated.
+
+ALTER TABLE /*$wgDBprefix*/cur
+ ADD COLUMN cur_touched char(14) binary NOT NULL default '';
+
+-- Existing pages should be initialized to the current
+-- time so they don't needlessly rerender until they are
+-- changed for the first time:
+
+UPDATE /*$wgDBprefix*/cur
+ SET cur_touched=NOW()+0;
+
+-- user_touched should be set to the current time whenever:
+-- * the user logs in
+-- * the user saves preferences (if no longer default...?)
+-- * the user's newtalk status is altered
+--
+-- The user_touched time should also be checked against the
+-- timestamp reported by a browser requesting revalidation.
+-- If user_touched is later than the reported last modified
+-- time, the page should be rerendered with new options and
+-- sent again.
+
+ALTER TABLE /*$wgDBprefix*/user
+ ADD COLUMN user_touched char(14) binary NOT NULL default '';
+UPDATE /*$wgDBprefix*/user
+ SET user_touched=NOW()+0;
diff --git a/maintenance/archives/patch-categorylinks.sql b/maintenance/archives/patch-categorylinks.sql
new file mode 100644
index 000000000000..53c82fc0db9e
--- /dev/null
+++ b/maintenance/archives/patch-categorylinks.sql
@@ -0,0 +1,39 @@
+--
+-- Track category inclusions *used inline*
+-- This tracks a single level of category membership
+-- (folksonomic tagging, really).
+--
+CREATE TABLE /*$wgDBprefix*/categorylinks (
+ -- Key to page_id of the page defined as a category member.
+ cl_from int(8) unsigned NOT NULL default '0',
+
+ -- Name of the category.
+ -- This is also the page_title of the category's description page;
+ -- all such pages are in namespace 14 (NS_CATEGORY).
+ cl_to varchar(255) binary NOT NULL default '',
+
+ -- The title of the linking page, or an optional override
+ -- to determine sort order. Sorting is by binary order, which
+ -- isn't always ideal, but collations seem to be an exciting
+ -- and dangerous new world in MySQL...
+ --
+ -- For MySQL 4.1+ with charset set to utf8, the sort key *index*
+ -- needs cut to be smaller than 1024 bytes (at 3 bytes per char).
+ -- To sort properly on the shorter key, this field needs to be
+ -- the same shortness.
+ cl_sortkey varchar(86) binary NOT NULL default '',
+
+ -- This isn't really used at present. Provided for an optional
+ -- sorting method by approximate addition time.
+ cl_timestamp timestamp NOT NULL,
+
+ UNIQUE KEY cl_from(cl_from,cl_to),
+
+ -- This key is trouble. It's incomplete, AND it's too big
+ -- when collation is set to UTF-8. Bleeeacch!
+ KEY cl_sortkey(cl_to,cl_sortkey),
+
+ -- Not really used?
+ KEY cl_timestamp(cl_to,cl_timestamp)
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-drop-user_newtalk.sql b/maintenance/archives/patch-drop-user_newtalk.sql
new file mode 100644
index 000000000000..6ec84fb35dd6
--- /dev/null
+++ b/maintenance/archives/patch-drop-user_newtalk.sql
@@ -0,0 +1,3 @@
+-- Patch for email authentication T.Gries/M.Arndt 27.11.2004
+-- Table user_newtalk is dropped, as the table watchlist is now also used for storing user_talk-page notifications
+DROP TABLE /*$wgDBprefix*/user_newtalk;
diff --git a/maintenance/archives/patch-drop_img_type.sql b/maintenance/archives/patch-drop_img_type.sql
new file mode 100644
index 000000000000..e37376176bc1
--- /dev/null
+++ b/maintenance/archives/patch-drop_img_type.sql
@@ -0,0 +1,3 @@
+-- img_type is no longer used, delete it
+
+ALTER TABLE /*$wgDBprefix*/image DROP COLUMN img_type;
diff --git a/maintenance/archives/patch-email-authentication.sql b/maintenance/archives/patch-email-authentication.sql
new file mode 100644
index 000000000000..b35b10f15e66
--- /dev/null
+++ b/maintenance/archives/patch-email-authentication.sql
@@ -0,0 +1,3 @@
+-- Added early in 1.5 alpha development, removed 2005-04-25
+
+ALTER TABLE /*$wgDBprefix*/user DROP COLUMN user_emailauthenticationtimestamp;
diff --git a/maintenance/archives/patch-email-notification.sql b/maintenance/archives/patch-email-notification.sql
new file mode 100644
index 000000000000..f9bc0440bade
--- /dev/null
+++ b/maintenance/archives/patch-email-notification.sql
@@ -0,0 +1,11 @@
+-- Patch for email notification on page changes T.Gries/M.Arndt 11.09.2004
+
+-- A new column 'wl_notificationtimestamp' is added to the table 'watchlist'.
+-- When a page watched by a user X is changed by someone else, an email is sent to the watching user X
+-- if and only if the field 'wl_notificationtimestamp' is '0'. The time/date of sending the mail is then stored in that field.
+-- Further pages changes do not trigger new notification mails as long as user X has not re-visited that page.
+-- The field is reset to '0' when user X re-visits the page or when he or she resets all notification timestamps
+-- ("notification flags") at once by clicking the new button on his/her watchlist page.
+-- T. Gries/M. Arndt 11.09.2004 - December 2004
+
+ALTER TABLE /*$wgDBprefix*/watchlist ADD (wl_notificationtimestamp varchar(14) binary);
diff --git a/maintenance/archives/patch-externallinks.sql b/maintenance/archives/patch-externallinks.sql
new file mode 100644
index 000000000000..52fb5bae101c
--- /dev/null
+++ b/maintenance/archives/patch-externallinks.sql
@@ -0,0 +1,13 @@
+--
+-- Track links to external URLs
+--
+CREATE TABLE /*$wgDBprefix*/externallinks (
+ el_from int(8) unsigned NOT NULL default '0',
+ el_to blob NOT NULL,
+ el_index blob NOT NULL,
+
+ KEY (el_from, el_to(40)),
+ KEY (el_to(60), el_from),
+ KEY (el_index(60))
+) TYPE=InnoDB;
+
diff --git a/maintenance/archives/patch-filearchive.sql b/maintenance/archives/patch-filearchive.sql
new file mode 100644
index 000000000000..cc50f2ae1259
--- /dev/null
+++ b/maintenance/archives/patch-filearchive.sql
@@ -0,0 +1,51 @@
+--
+-- Record of deleted file data
+--
+CREATE TABLE /*$wgDBprefix*/filearchive (
+ -- Unique row id
+ fa_id int not null auto_increment,
+
+ -- Original base filename; key to image.img_name, page.page_title, etc
+ fa_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of archived file, if an old revision
+ fa_archive_name varchar(255) binary default '',
+
+ -- Which storage bin (directory tree or object store) the file data
+ -- is stored in. Should be 'deleted' for files that have been deleted;
+ -- any other bin is not yet in use.
+ fa_storage_group varchar(16),
+
+ -- SHA-1 of the file contents plus extension, used as a key for storage.
+ -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg
+ --
+ -- If NULL, the file was missing at deletion time or has been purged
+ -- from the archival storage.
+ fa_storage_key varchar(64) binary default '',
+
+ -- Deletion information, if this file is deleted.
+ fa_deleted_user int,
+ fa_deleted_timestamp char(14) binary default '',
+ fa_deleted_reason text,
+
+ -- Duped fields from image
+ fa_size int(8) unsigned default '0',
+ fa_width int(5) default '0',
+ fa_height int(5) default '0',
+ fa_metadata mediumblob,
+ fa_bits int(3) default '0',
+ fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+ fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") default "unknown",
+ fa_minor_mime varchar(32) default "unknown",
+ fa_description tinyblob,
+ fa_user int(5) unsigned default '0',
+ fa_user_text varchar(255) binary default '',
+ fa_timestamp char(14) binary default '',
+
+ PRIMARY KEY (fa_id),
+ INDEX (fa_name, fa_timestamp), -- pick out by image name
+ INDEX (fa_storage_group, fa_storage_key), -- pick out dupe files
+ INDEX (fa_deleted_timestamp), -- sort by deletion time
+ INDEX (fa_deleted_user) -- sort by deleter
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-hitcounter.sql b/maintenance/archives/patch-hitcounter.sql
new file mode 100644
index 000000000000..260f717f03a1
--- /dev/null
+++ b/maintenance/archives/patch-hitcounter.sql
@@ -0,0 +1,9 @@
+--
+-- hitcounter table is used to buffer page hits before they are periodically
+-- counted and added to the cur_counter column in the cur table.
+-- December 2003
+--
+
+CREATE TABLE /*$wgDBprefix*/hitcounter (
+ hc_id INTEGER UNSIGNED NOT NULL
+) TYPE=HEAP MAX_ROWS=25000;
diff --git a/maintenance/archives/patch-image_name_primary.sql b/maintenance/archives/patch-image_name_primary.sql
new file mode 100644
index 000000000000..5bd882646f78
--- /dev/null
+++ b/maintenance/archives/patch-image_name_primary.sql
@@ -0,0 +1,6 @@
+-- Make the image name index unique
+
+ALTER TABLE /*$wgDBprefix*/image DROP INDEX img_name;
+
+ALTER TABLE /*$wgDBprefix*/image
+ ADD PRIMARY KEY img_name (img_name);
diff --git a/maintenance/archives/patch-image_name_unique.sql b/maintenance/archives/patch-image_name_unique.sql
new file mode 100644
index 000000000000..5cf02d41e451
--- /dev/null
+++ b/maintenance/archives/patch-image_name_unique.sql
@@ -0,0 +1,6 @@
+-- Make the image name index unique
+
+ALTER TABLE /*$wgDBprefix*/image DROP INDEX img_name;
+
+ALTER TABLE /*$wgDBprefix*/image
+ ADD UNIQUE INDEX img_name (img_name);
diff --git a/maintenance/archives/patch-img_exif.sql b/maintenance/archives/patch-img_exif.sql
new file mode 100644
index 000000000000..2fd78f761a25
--- /dev/null
+++ b/maintenance/archives/patch-img_exif.sql
@@ -0,0 +1,3 @@
+-- Extra image exif metadata, added for 1.5 but quickly removed.
+
+ALTER TABLE /*$wgDBprefix*/image DROP img_exif;
diff --git a/maintenance/archives/patch-img_media_type.sql b/maintenance/archives/patch-img_media_type.sql
new file mode 100644
index 000000000000..2356fc631643
--- /dev/null
+++ b/maintenance/archives/patch-img_media_type.sql
@@ -0,0 +1,17 @@
+-- media type columns, added for 1.5
+-- this alters the scheme for 1.5, img_type is no longer used.
+
+ALTER TABLE /*$wgDBprefix*/image ADD (
+ -- Media type as defined by the MEDIATYPE_xxx constants
+ img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+
+ -- major part of a MIME media type as defined by IANA
+ -- see http://www.iana.org/assignments/media-types/
+ img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown",
+
+ -- minor part of a MIME media type as defined by IANA
+ -- the minor parts are not required to adher to any standard
+ -- but should be consistent throughout the database
+ -- see http://www.iana.org/assignments/media-types/
+ img_minor_mime varchar(32) NOT NULL default "unknown"
+);
diff --git a/maintenance/archives/patch-img_metadata.sql b/maintenance/archives/patch-img_metadata.sql
new file mode 100644
index 000000000000..407e4325a92a
--- /dev/null
+++ b/maintenance/archives/patch-img_metadata.sql
@@ -0,0 +1,6 @@
+-- Moving img_exif to img_metadata, so the name won't be so confusing when we
+-- Use it for Ogg metadata or something like that.
+
+ALTER TABLE /*$wgDBprefix*/image ADD (
+ img_metadata mediumblob NOT NULL
+);
diff --git a/maintenance/archives/patch-img_width.sql b/maintenance/archives/patch-img_width.sql
new file mode 100644
index 000000000000..c99bd46d6c4c
--- /dev/null
+++ b/maintenance/archives/patch-img_width.sql
@@ -0,0 +1,18 @@
+-- Extra image metadata, added for 1.5
+
+-- NOTE: as by patch-img_media_type.sql, the img_type
+-- column is no longer used and has therefore be removed from this patch
+
+ALTER TABLE /*$wgDBprefix*/image ADD (
+ img_width int(5) NOT NULL default 0,
+ img_height int(5) NOT NULL default 0,
+ img_bits int(5) NOT NULL default 0
+);
+
+ALTER TABLE /*$wgDBprefix*/oldimage ADD (
+ oi_width int(5) NOT NULL default 0,
+ oi_height int(5) NOT NULL default 0,
+ oi_bits int(3) NOT NULL default 0
+);
+
+
diff --git a/maintenance/archives/patch-indexes.sql b/maintenance/archives/patch-indexes.sql
new file mode 100644
index 000000000000..23eec07d18f4
--- /dev/null
+++ b/maintenance/archives/patch-indexes.sql
@@ -0,0 +1,24 @@
+--
+-- patch-indexes.sql
+--
+-- Fix up table indexes; new to stable release in November 2003
+--
+
+ALTER TABLE /*$wgDBprefix*/links
+ DROP INDEX l_from,
+ ADD INDEX l_from (l_from);
+
+ALTER TABLE /*$wgDBprefix*/brokenlinks
+ DROP INDEX bl_to,
+ ADD INDEX bl_to (bL_to);
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD INDEX rc_timestamp (rc_timestamp),
+ ADD INDEX rc_namespace_title (rc_namespace, rc_title),
+ ADD INDEX rc_cur_id (rc_cur_id);
+
+ALTER TABLE /*$wgDBprefix*/archive
+ ADD KEY name_title_timestamp (ar_namespace,ar_title,ar_timestamp);
+
+ALTER TABLE /*$wgDBprefix*/watchlist
+ ADD KEY namespace_title (wl_namespace,wl_title);
diff --git a/maintenance/archives/patch-interwiki-trans.sql b/maintenance/archives/patch-interwiki-trans.sql
new file mode 100644
index 000000000000..2384a66a0eba
--- /dev/null
+++ b/maintenance/archives/patch-interwiki-trans.sql
@@ -0,0 +1,2 @@
+ALTER TABLE /*$wgDBprefix*/interwiki
+ ADD COLUMN iw_trans TINYINT(1) NOT NULL DEFAULT 0;
diff --git a/maintenance/archives/patch-interwiki.sql b/maintenance/archives/patch-interwiki.sql
new file mode 100644
index 000000000000..90b162ef3d30
--- /dev/null
+++ b/maintenance/archives/patch-interwiki.sql
@@ -0,0 +1,20 @@
+-- Creates interwiki prefix<->url mapping table
+-- used from 2003-08-21 dev version.
+-- Import the default mappings from maintenance/interwiki.sql
+
+CREATE TABLE /*$wgDBprefix*/interwiki (
+ -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
+ iw_prefix char(32) NOT NULL,
+
+ -- The URL of the wiki, with "$1" as a placeholder for an article name.
+ -- Any spaces in the name will be transformed to underscores before
+ -- insertion.
+ iw_url char(127) NOT NULL,
+
+ -- A boolean value indicating whether the wiki is in this project
+ -- (used, for example, to detect redirect loops)
+ iw_local BOOL NOT NULL,
+
+ UNIQUE KEY iw_prefix (iw_prefix)
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-inverse_timestamp.sql b/maintenance/archives/patch-inverse_timestamp.sql
new file mode 100644
index 000000000000..0f7d66f13c64
--- /dev/null
+++ b/maintenance/archives/patch-inverse_timestamp.sql
@@ -0,0 +1,15 @@
+-- Removes the inverse_timestamp field from early 1.5 alphas.
+-- This field was used in the olden days as a crutch for sorting
+-- limitations in MySQL 3.x, but is being dropped now as an
+-- unnecessary burden. Serious wikis should be running on 4.x.
+--
+-- Updater added 2005-03-13
+
+ALTER TABLE /*$wgDBprefix*/revision
+ DROP COLUMN inverse_timestamp,
+ DROP INDEX page_timestamp,
+ DROP INDEX user_timestamp,
+ DROP INDEX usertext_timestamp,
+ ADD INDEX page_timestamp (rev_page,rev_timestamp),
+ ADD INDEX user_timestamp (rev_user,rev_timestamp),
+ ADD INDEX usertext_timestamp (rev_user_text,rev_timestamp);
diff --git a/maintenance/archives/patch-ipb_anon_only.sql b/maintenance/archives/patch-ipb_anon_only.sql
new file mode 100644
index 000000000000..b3738168aab8
--- /dev/null
+++ b/maintenance/archives/patch-ipb_anon_only.sql
@@ -0,0 +1,44 @@
+-- Add extra option fields to the ipblocks table, add some extra indexes,
+-- convert infinity values in ipb_expiry to something that sorts better,
+-- extend ipb_address and range fields, add a unique index for block conflict
+-- detection.
+
+-- Conflicts in the new unique index can be handled by creating a new
+-- table and inserting into it instead of doing an ALTER TABLE.
+
+
+DROP TABLE IF EXISTS /*$wgDBprefix*/ipblocks_newunique;
+
+CREATE TABLE /*$wgDBprefix*/ipblocks_newunique (
+ ipb_id int(8) NOT NULL auto_increment,
+ ipb_address tinyblob NOT NULL,
+ ipb_user int(8) unsigned NOT NULL default '0',
+ ipb_by int(8) unsigned NOT NULL default '0',
+ ipb_reason tinyblob NOT NULL,
+ ipb_timestamp char(14) binary NOT NULL default '',
+ ipb_auto bool NOT NULL default 0,
+ ipb_anon_only bool NOT NULL default 0,
+ ipb_create_account bool NOT NULL default 1,
+ ipb_expiry char(14) binary NOT NULL default '',
+ ipb_range_start tinyblob NOT NULL,
+ ipb_range_end tinyblob NOT NULL,
+
+ PRIMARY KEY ipb_id (ipb_id),
+ UNIQUE INDEX ipb_address_unique (ipb_address(255), ipb_user, ipb_auto),
+ INDEX ipb_user (ipb_user),
+ INDEX ipb_range (ipb_range_start(8), ipb_range_end(8)),
+ INDEX ipb_timestamp (ipb_timestamp),
+ INDEX ipb_expiry (ipb_expiry)
+
+) TYPE=InnoDB;
+
+INSERT IGNORE INTO /*$wgDBprefix*/ipblocks_newunique
+ (ipb_id, ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry, ipb_range_start, ipb_range_end, ipb_anon_only, ipb_create_account)
+ SELECT ipb_id, ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry, ipb_range_start, ipb_range_end, 0 , ipb_user=0
+ FROM /*$wgDBprefix*/ipblocks;
+
+DROP TABLE IF EXISTS /*$wgDBprefix*/ipblocks_old;
+RENAME TABLE /*$wgDBprefix*/ipblocks TO /*$wgDBprefix*/ipblocks_old;
+RENAME TABLE /*$wgDBprefix*/ipblocks_newunique TO /*$wgDBprefix*/ipblocks;
+
+UPDATE /*$wgDBprefix*/ipblocks SET ipb_expiry='infinity' WHERE ipb_expiry='';
diff --git a/maintenance/archives/patch-ipb_expiry.sql b/maintenance/archives/patch-ipb_expiry.sql
new file mode 100644
index 000000000000..0f106d7010f6
--- /dev/null
+++ b/maintenance/archives/patch-ipb_expiry.sql
@@ -0,0 +1,8 @@
+-- Adds the ipb_expiry field to ipblocks
+
+ALTER TABLE /*$wgDBprefix*/ipblocks ADD ipb_expiry char(14) binary NOT NULL default '';
+
+-- All IP blocks have one day expiry
+UPDATE /*$wgDBprefix*/ipblocks SET ipb_expiry = date_format(date_add(ipb_timestamp,INTERVAL 1 DAY),"%Y%m%d%H%i%s") WHERE ipb_user = 0;
+
+-- Null string is fine for user blocks, since this indicates infinity
diff --git a/maintenance/archives/patch-ipb_optional_autoblock.sql b/maintenance/archives/patch-ipb_optional_autoblock.sql
new file mode 100644
index 000000000000..f31b83595532
--- /dev/null
+++ b/maintenance/archives/patch-ipb_optional_autoblock.sql
@@ -0,0 +1,3 @@
+-- Add an extra option field "ipb_enable_autoblock" into the ipblocks table. This allows a block to be placed that does not trigger any autoblocks.
+
+ALTER TABLE /*$wgDBprefix*/ipblocks ADD COLUMN ipb_enable_autoblock bool NOT NULL default '1';
diff --git a/maintenance/archives/patch-ipb_range_start.sql b/maintenance/archives/patch-ipb_range_start.sql
new file mode 100644
index 000000000000..c31e2d9cc919
--- /dev/null
+++ b/maintenance/archives/patch-ipb_range_start.sql
@@ -0,0 +1,25 @@
+-- Add the range handling fields
+ALTER TABLE /*$wgDBprefix*/ipblocks
+ ADD ipb_range_start varchar(32) NOT NULL default '',
+ ADD ipb_range_end varchar(32) NOT NULL default '',
+ ADD INDEX ipb_range (ipb_range_start(8), ipb_range_end(8));
+
+
+-- Initialise fields
+-- Only range blocks match ipb_address LIKE '%/%', this fact is used in the code already
+UPDATE /*$wgDBprefix*/ipblocks
+ SET
+ ipb_range_start = LPAD(HEX(
+ (SUBSTRING_INDEX(ipb_address, '.', 1) << 24)
+ + (SUBSTRING_INDEX(SUBSTRING_INDEX(ipb_address, '.', 2), '.', -1) << 16)
+ + (SUBSTRING_INDEX(SUBSTRING_INDEX(ipb_address, '.', 3), '.', -1) << 24)
+ + (SUBSTRING_INDEX(SUBSTRING_INDEX(ipb_address, '/', 1), '.', -1)) ), 8, '0' ),
+
+ ipb_range_end = LPAD(HEX(
+ (SUBSTRING_INDEX(ipb_address, '.', 1) << 24)
+ + (SUBSTRING_INDEX(SUBSTRING_INDEX(ipb_address, '.', 2), '.', -1) << 16)
+ + (SUBSTRING_INDEX(SUBSTRING_INDEX(ipb_address, '.', 3), '.', -1) << 24)
+ + (SUBSTRING_INDEX(SUBSTRING_INDEX(ipb_address, '/', 1), '.', -1))
+ + ((1 << (32 - SUBSTRING_INDEX(ipb_address, '/', -1))) - 1) ), 8, '0' )
+
+ WHERE ipb_address LIKE '%/%';
diff --git a/maintenance/archives/patch-ipblocks.sql b/maintenance/archives/patch-ipblocks.sql
new file mode 100644
index 000000000000..8e47798b0e28
--- /dev/null
+++ b/maintenance/archives/patch-ipblocks.sql
@@ -0,0 +1,6 @@
+-- For auto-expiring blocks --
+
+ALTER TABLE /*$wgDBprefix*/ipblocks
+ ADD ipb_auto tinyint(1) NOT NULL default '0',
+ ADD ipb_id int(8) NOT NULL auto_increment,
+ ADD PRIMARY KEY (ipb_id);
diff --git a/maintenance/archives/patch-job.sql b/maintenance/archives/patch-job.sql
new file mode 100644
index 000000000000..d904fbebd0d7
--- /dev/null
+++ b/maintenance/archives/patch-job.sql
@@ -0,0 +1,20 @@
+
+-- Jobs performed by parallel apache threads or a command-line daemon
+CREATE TABLE /*$wgDBprefix*/job (
+ job_id int(9) unsigned NOT NULL auto_increment,
+
+ -- Command name, currently only refreshLinks is defined
+ job_cmd varchar(255) NOT NULL default '',
+
+ -- Namespace and title to act on
+ -- Should be 0 and '' if the command does not operate on a title
+ job_namespace int NOT NULL,
+ job_title varchar(255) binary NOT NULL,
+
+ -- Any other parameters to the command
+ -- Presently unused, format undefined
+ job_params blob NOT NULL,
+
+ PRIMARY KEY job_id (job_id),
+ KEY (job_cmd, job_namespace, job_title)
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-langlinks.sql b/maintenance/archives/patch-langlinks.sql
new file mode 100644
index 000000000000..9c3b7e5415e5
--- /dev/null
+++ b/maintenance/archives/patch-langlinks.sql
@@ -0,0 +1,14 @@
+CREATE TABLE /*$wgDBprefix*/langlinks (
+ -- page_id of the referring page
+ ll_from int(8) unsigned NOT NULL default '0',
+
+ -- Language code of the target
+ ll_lang varchar(10) binary NOT NULL default '',
+
+ -- Title of the target, including namespace
+ ll_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY (ll_from, ll_lang),
+ KEY (ll_lang, ll_title)
+) TYPE=InnoDB;
+
diff --git a/maintenance/archives/patch-linkscc-1.3.sql b/maintenance/archives/patch-linkscc-1.3.sql
new file mode 100644
index 000000000000..e397fcb9d951
--- /dev/null
+++ b/maintenance/archives/patch-linkscc-1.3.sql
@@ -0,0 +1,6 @@
+--
+-- linkscc table used to cache link lists in easier to digest form.
+-- New schema for 1.3 - removes old lcc_title column.
+-- May 2004
+--
+ALTER TABLE /*$wgDBprefix*/linkscc DROP COLUMN lcc_title; \ No newline at end of file
diff --git a/maintenance/archives/patch-linkscc.sql b/maintenance/archives/patch-linkscc.sql
new file mode 100644
index 000000000000..91d4da56bc84
--- /dev/null
+++ b/maintenance/archives/patch-linkscc.sql
@@ -0,0 +1,12 @@
+--
+-- linkscc table used to cache link lists in easier to digest form
+-- November 2003
+--
+-- Format later updated.
+--
+
+CREATE TABLE /*$wgDBprefix*/linkscc (
+ lcc_pageid INT UNSIGNED NOT NULL UNIQUE KEY,
+ lcc_cacheobj MEDIUMBLOB NOT NULL
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-linktables.sql b/maintenance/archives/patch-linktables.sql
new file mode 100644
index 000000000000..bb9bd03350d9
--- /dev/null
+++ b/maintenance/archives/patch-linktables.sql
@@ -0,0 +1,70 @@
+--
+-- Track links that do exist
+-- l_from and l_to key to cur_id
+--
+DROP TABLE IF EXISTS /*$wgDBprefix*/links;
+CREATE TABLE /*$wgDBprefix*/links (
+ -- Key to the page_id of the page containing the link.
+ l_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to the page_id of the link target.
+ -- An unfortunate consequence of this is that rename
+ -- operations require changing the links entries for
+ -- all links to the moved page.
+ l_to int(8) unsigned NOT NULL default '0',
+
+ UNIQUE KEY l_from(l_from,l_to),
+ KEY (l_to)
+
+) TYPE=InnoDB;
+
+--
+-- Track links to pages that don't yet exist.
+-- bl_from keys to cur_id
+-- bl_to is a text link (namespace:title)
+--
+DROP TABLE IF EXISTS /*$wgDBprefix*/brokenlinks;
+CREATE TABLE /*$wgDBprefix*/brokenlinks (
+ -- Key to the page_id of the page containing the link.
+ bl_from int(8) unsigned NOT NULL default '0',
+
+ -- Text of the target page title ("namesapce:title").
+ -- Unfortunately this doesn't split the namespace index
+ -- key and therefore can't easily be joined to anything.
+ bl_to varchar(255) binary NOT NULL default '',
+ UNIQUE KEY bl_from(bl_from,bl_to),
+ KEY (bl_to)
+
+) TYPE=InnoDB;
+
+--
+-- Track links to images *used inline*
+-- il_from keys to cur_id, il_to keys to image_name.
+-- We don't distinguish live from broken links.
+--
+DROP TABLE IF EXISTS /*$wgDBprefix*/imagelinks;
+CREATE TABLE /*$wgDBprefix*/imagelinks (
+ -- Key to page_id of the page containing the image / media link.
+ il_from int(8) unsigned NOT NULL default '0',
+
+ -- Filename of target image.
+ -- This is also the page_title of the file's description page;
+ -- all such pages are in namespace 6 (NS_IMAGE).
+ il_to varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY il_from(il_from,il_to),
+ KEY (il_to)
+
+) TYPE=InnoDB;
+
+--
+-- Stores (possibly gzipped) serialized objects with
+-- cache arrays to reduce database load slurping up
+-- from links and brokenlinks.
+--
+DROP TABLE IF EXISTS /*$wgDBprefix*/linkscc;
+CREATE TABLE /*$wgDBprefix*/linkscc (
+ lcc_pageid INT UNSIGNED NOT NULL UNIQUE KEY,
+ lcc_cacheobj MEDIUMBLOB NOT NULL
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-list.txt b/maintenance/archives/patch-list.txt
new file mode 100644
index 000000000000..93a63bfd18b3
--- /dev/null
+++ b/maintenance/archives/patch-list.txt
@@ -0,0 +1,182 @@
+List of database patches and upgrades as the PediaWiki software evolves...
+
+* 2002-11-23: Search index format changed for UTF-8 wikis
+For wikis using the UTF-8 languages, the search index entries
+need to be rebuild to allow searching to work. (Other wikis
+that have been run through the old phase2->phase3 conversion
+script should also be reindexed to catch apostrophe misplacement.)
+
+Run rebuildIndex.php on your wiki.
+
+
+
+* 2002-11-27: Watchlist format changed
+Converts the user_watchlist entries out to a separate table which
+links user_id<->cur_id and can be more handily queried.
+
+Run upgradeWatchlist.php on your wiki.
+
+
+
+* 2002-12-14: Recentchanges table bot/hidden column
+Adds a column to indicate changes by registered bots (or perhaps
+later other admin actions) that should be hidden from the default
+Recentchanges list because people think they're tedious, but should
+still be available in article histories, contribs lists, and
+power-user RC lists.
+
+Run bot.sql against your database.
+
+
+
+* 2002-12-17: Watchlist format changed again
+Now using namespace, title instead of cur_id. This can track deleted/
+recreated pages better, makes it easier to handle talk pages (now with
+the auto-watch feature there's a lot more watching of talk pages!)
+and whatnot.
+
+Run patch-watchlist.sql against your database. If all is well, drop
+the oldwatchlist table which is no longer needed. (Note that this update
+also drops the vestigial user_watchlist column.)
+
+
+
+* 2002-12-26: TeX math rendering adds 'math' table
+A new 'math' table is used to cache TeX sections.
+
+Run patch-math.sql against your database, and add 'tmp' and 'math'
+subdirectories to your tree alongside the upload directory, and copy
+the 'math' source subdirectory under the wiki's PHP directory and run
+"make" to compile the texvc evaluator. (whew!)
+
+TeX support requires TeX, OCaml, and ImageMagick. If you don't want
+to use TeX support on your wiki, you can globally disable it by
+setting $wgUseTeX=false in LocalSettings.php.
+
+
+
+* 2003-01-25: searchindex table
+A new 'searchindex' table separates the fulltext index fields from
+'cur'. This enables use of InnoDB tables, which don't support fulltext
+search, for the main data, and will keep junk out of the backup dumps.
+
+Run patch-searchindex.sql on the database. If you wish to change table
+tables on the others, use 'alter table' manually. (See MySQL docs.)
+
+
+* 2003-01-24: Talk pages for anonymous users
+A new table user_newtalk contains a list of talk pages that were
+changed, both pages by anonymous and those by non-anonymous users.
+
+Run patch-usernewtalk.sql if your database was created before
+this date.
+
+
+* 2003-02-02: Math table changed
+Rerun patch-math.sql to recreate it.
+
+* 2003-02-03: Index added to USER table for performance reasons. Run
+patch-userindex.sql to create it.
+
+
+* 2003-02-09: Random table & inverse timestamps
+The random page queue table has been removed in favor of a column
+in the cur table. This eliminates the ssllooww queue refill step;
+pre-storing random indices in an indexed column means we can do the
+random sort instantly; each element is re-randomized upon selection.
+
+Also, an inverse_timestamp field has been added to the cur and old
+tables. This will allow fast index-based sorting in history lists,
+user contribs, linked recentchanges, etc with MySQL 3, which doesn't
+allow DESC ordering on an indexed field. This may be removed later
+when MySQL is found to be stable.
+
+
+* 2003-03-22: Last touched fields for caching
+'Last touched' timestamp fields have been added to the cur and user
+tables to aid in maintaining cache consistency. Web clients will
+be forced to reload a page if it has been touched since the client's
+cached copy (this will catch indirect changes like creation of
+linked pages) or if a user changes preferences or logs in anew (so
+visual changes and login status are taken into account).
+
+Run patch-cache.sql on the database to set these fields up. This is
+required for changes to OutputPage.php and elsewhere to continue
+working on an older database.
+
+
+* 2003-05-23: Index for "Oldest articles"
+"Oldest articles" needs an index on namespace, redirect and timestamp
+to be reasonably fast. (patch-oldestindex.sql)
+
+OutputPage.php User.php maintenance/buildTables.inc maintenance/patch-cache.sql maintenance/patch-list.txt
+
+* 2003-09: Ipblocks auto-expiry update
+patch-ipblocks.sql
+
+* Interwiki URL table
+Moves the interwiki prefix<->url mapping table from a static array
+into the database. If you've got a custom table, be sure to make
+your changes!
+
+Run patch-interwiki.sql to create the interwiki table, then the
+plain interwiki.sql to load up the default set of mappings.
+
+* 2003-05-30: File upload license fields
+Adds fields to 'image' table.
+INCOMPLETE, DO NOT USE
+
+
+* 2003-08-21: Interwiki URL table
+Moves the interwiki prefix<->url mapping table from a static array
+into the database. If you've got a custom table, be sure to make
+your changes!
+
+Run patch-interwiki.sql to create the interwiki table, then the
+plain interwiki.sql to load up the default set of mappings.
+
+* 2003-09: Ipblocks auto-expiry update
+patch-ipblocks.sql
+
+* Interwiki URL table
+Moves the interwiki prefix<->url mapping table from a static array
+into the database. If you've got a custom table, be sure to make
+your changes!
+
+Run patch-interwiki.sql to create the interwiki table, then the
+plain interwiki.sql to load up the default set of mappings.
+
+* 2003-11: Indexes
+Fixes up indexes on links, brokenlinks, recentchanges, watchlist,
+and archive tables to boost speed.
+
+Run patch-indexes.sql.
+
+* 2003-11: linkscc table creation
+patch-linkscc.sql
+
+
+* 2004-01-25: recentchanges additional index
+Adds an index to recentchanges to optimize Special:Newpages
+patch-rc-newindex.sql
+
+* 2004-02-14: Adds the ipb_expiry field to ipblocks
+patch-ipb_expiry.sql
+
+
+* 2004-03-11: Recreate links tables to avoid duplicating titles
+everywhere. **Rebuild your links after this with refreshLinks.php**
+
+patch-linktables.sql
+
+
+* 2004-04: Add user_real_name field
+patch-user-realname.sql
+
+* 2004-05-08: Add querycache table for caching special pages and generic
+ object cache to cover some slow operations w/o memcached.
+patch-querycache.sql
+patch-objectcache.sql
+
+* 2004-05-14: Add categorylinks table for handling category membership
+patch-categorylinks.sql
diff --git a/maintenance/archives/patch-log_params.sql b/maintenance/archives/patch-log_params.sql
new file mode 100644
index 000000000000..ff6527ec645e
--- /dev/null
+++ b/maintenance/archives/patch-log_params.sql
@@ -0,0 +1 @@
+ALTER TABLE /*$wgDBprefix*/logging ADD log_params blob NOT NULL;
diff --git a/maintenance/archives/patch-logging-times-index.sql b/maintenance/archives/patch-logging-times-index.sql
new file mode 100644
index 000000000000..e66ceec4496f
--- /dev/null
+++ b/maintenance/archives/patch-logging-times-index.sql
@@ -0,0 +1,9 @@
+--
+-- patch-logging-times-index.sql
+--
+-- Add a very humble index on logging times
+--
+
+ALTER TABLE /*$wgDBprefix*/logging
+ ADD INDEX times (log_timestamp);
+
diff --git a/maintenance/archives/patch-logging-title.sql b/maintenance/archives/patch-logging-title.sql
new file mode 100644
index 000000000000..c5da0dc046e2
--- /dev/null
+++ b/maintenance/archives/patch-logging-title.sql
@@ -0,0 +1,6 @@
+-- 1.4 betas were missing the 'binary' marker from logging.log_title,
+-- which causes a collation mismatch error on joins in MySQL 4.1.
+
+ALTER TABLE /*$wgDBprefix*/logging
+ CHANGE COLUMN log_title
+ log_title varchar(255) binary NOT NULL default '';
diff --git a/maintenance/archives/patch-logging.sql b/maintenance/archives/patch-logging.sql
new file mode 100644
index 000000000000..54146fb78aaa
--- /dev/null
+++ b/maintenance/archives/patch-logging.sql
@@ -0,0 +1,37 @@
+-- Add the logging table and adjust recentchanges to accomodate special pages
+-- 2004-08-24
+
+CREATE TABLE /*$wgDBprefix*/logging (
+ -- Symbolic keys for the general log type and the action type
+ -- within the log. The output format will be controlled by the
+ -- action field, but only the type controls categorization.
+ log_type char(10) NOT NULL default '',
+ log_action char(10) NOT NULL default '',
+
+ -- Timestamp. Duh.
+ log_timestamp char(14) NOT NULL default '19700101000000',
+
+ -- The user who performed this action; key to user_id
+ log_user int unsigned NOT NULL default 0,
+
+ -- Key to the page affected. Where a user is the target,
+ -- this will point to the user page.
+ log_namespace int NOT NULL default 0,
+ log_title varchar(255) binary NOT NULL default '',
+
+ -- Freeform text. Interpreted as edit history comments.
+ log_comment varchar(255) NOT NULL default '',
+
+ -- LF separated list of miscellaneous parameters
+ log_params blob NOT NULL,
+
+ KEY type_time (log_type, log_timestamp),
+ KEY user_time (log_user, log_timestamp),
+ KEY page_time (log_namespace, log_title, log_timestamp)
+
+) TYPE=InnoDB;
+
+
+-- Change from unsigned to signed so we can store special pages
+ALTER TABLE recentchanges
+ MODIFY rc_namespace tinyint(3) NOT NULL default '0';
diff --git a/maintenance/archives/patch-math.sql b/maintenance/archives/patch-math.sql
new file mode 100644
index 000000000000..aee24a8af7e9
--- /dev/null
+++ b/maintenance/archives/patch-math.sql
@@ -0,0 +1,28 @@
+-- Creates table math used for caching TeX blocks. Needs to be run
+-- on old installations when adding TeX support (2002-12-26)
+-- Or, TeX can be disabled via $wgUseTeX=false in LocalSettings.php
+
+-- Note: math table has changed, and this script needs to be run again
+-- to create it. (2003-02-02)
+
+DROP TABLE IF EXISTS /*$wgDBprefix*/math;
+CREATE TABLE /*$wgDBprefix*/math (
+ -- Binary MD5 hash of the latex fragment, used as an identifier key.
+ math_inputhash varchar(16) NOT NULL,
+
+ -- Not sure what this is, exactly...
+ math_outputhash varchar(16) NOT NULL,
+
+ -- texvc reports how well it thinks the HTML conversion worked;
+ -- if it's a low level the PNG rendering may be preferred.
+ math_html_conservativeness tinyint(1) NOT NULL,
+
+ -- HTML output from texvc, if any
+ math_html text,
+
+ -- MathML output from texvc, if any
+ math_mathml text,
+
+ UNIQUE KEY math_inputhash (math_inputhash)
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-mimesearch-indexes.sql b/maintenance/archives/patch-mimesearch-indexes.sql
new file mode 100644
index 000000000000..bd348c46c26c
--- /dev/null
+++ b/maintenance/archives/patch-mimesearch-indexes.sql
@@ -0,0 +1,22 @@
+-- Add indexes to the mime types in image for use on Special:MIMEsearch,
+-- changes a query like
+--
+-- SELECT img_name FROM image WHERE img_major_mime = "image" AND img_minor_mime = "svg";
+-- from:
+-- +-------+------+---------------+------+---------+------+------+-------------+
+-- | table | type | possible_keys | key | key_len | ref | rows | Extra |
+-- +-------+------+---------------+------+---------+------+------+-------------+
+-- | image | ALL | NULL | NULL | NULL | NULL | 194 | Using where |
+-- +-------+------+---------------+------+---------+------+------+-------------+
+-- to:
+-- +-------+------+-------------------------------+----------------+---------+-------+------+-------------+
+-- | table | type | possible_keys | key | key_len | ref | rows | Extra |
+-- +-------+------+-------------------------------+----------------+---------+-------+------+-------------+
+-- | image | ref | img_major_mime,img_minor_mime | img_minor_mime | 32 | const | 4 | Using where |
+-- +-------+------+-------------------------------+----------------+---------+-------+------+-------------+
+
+ALTER TABLE /*$wgDBprefix*/image
+ ADD INDEX img_major_mime (img_major_mime);
+ALTER TABLE /*$wgDBprefix*/image
+ ADD INDEX img_minor_mime (img_minor_mime);
+
diff --git a/maintenance/archives/patch-objectcache.sql b/maintenance/archives/patch-objectcache.sql
new file mode 100644
index 000000000000..18572aa099c9
--- /dev/null
+++ b/maintenance/archives/patch-objectcache.sql
@@ -0,0 +1,9 @@
+-- For a few generic cache operations if not using Memcached
+CREATE TABLE /*$wgDBprefix*/objectcache (
+ keyname char(255) binary not null default '',
+ value mediumblob,
+ exptime datetime,
+ unique key (keyname),
+ key (exptime)
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-oldestindex.sql b/maintenance/archives/patch-oldestindex.sql
new file mode 100644
index 000000000000..930214fdefcd
--- /dev/null
+++ b/maintenance/archives/patch-oldestindex.sql
@@ -0,0 +1,5 @@
+-- Add index for "Oldest articles" (Special:Ancientpages)
+-- 2003-05-23 Erik Moeller <moeller@scireview.de>
+
+ALTER TABLE /*$wgDBprefix*/cur
+ ADD INDEX namespace_redirect_timestamp(cur_namespace,cur_is_redirect,cur_timestamp);
diff --git a/maintenance/archives/patch-page_len.sql b/maintenance/archives/patch-page_len.sql
new file mode 100644
index 000000000000..c32dc8d44ef2
--- /dev/null
+++ b/maintenance/archives/patch-page_len.sql
@@ -0,0 +1,16 @@
+-- Page length field (in bytes) for current revision of page.
+-- Since page text is now stored separately, it may be compressed
+-- or otherwise difficult to calculate. Additionally, the field
+-- can be indexed for handy 'long' and 'short' page lists.
+--
+-- Added 2005-03-12
+
+ALTER TABLE /*$wgDBprefix*/page
+ ADD page_len int(8) unsigned NOT NULL,
+ ADD INDEX (page_len);
+
+-- Not accurate if upgrading from intermediate
+-- 1.5 alpha and have revision compression on.
+UPDATE /*$wgDBprefix*/page, /*$wgDBprefix*/text
+ SET page_len=LENGTH(old_text)
+ WHERE page_latest=old_id;
diff --git a/maintenance/archives/patch-page_no_title_convert.sql b/maintenance/archives/patch-page_no_title_convert.sql
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/maintenance/archives/patch-page_no_title_convert.sql
diff --git a/maintenance/archives/patch-pagelinks.sql b/maintenance/archives/patch-pagelinks.sql
new file mode 100644
index 000000000000..7240cff9678d
--- /dev/null
+++ b/maintenance/archives/patch-pagelinks.sql
@@ -0,0 +1,56 @@
+--
+-- Create the new pagelinks table to merge links and brokenlinks data,
+-- and populate it.
+--
+-- Unlike the old links and brokenlinks, these records will not need to be
+-- altered when target pages are created, deleted, or renamed. This should
+-- reduce the amount of severe database frustration that happens when widely-
+-- linked pages are altered.
+--
+-- Fixups for brokenlinks to pages in namespaces need to be run after this;
+-- this is done by updaters.inc if run through the regular update scripts.
+--
+-- 2005-05-26
+--
+
+--
+-- Track page-to-page hyperlinks within the wiki.
+--
+CREATE TABLE /*$wgDBprefix*/pagelinks (
+ -- Key to the page_id of the page containing the link.
+ pl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ pl_namespace int NOT NULL default '0',
+ pl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY pl_from(pl_from,pl_namespace,pl_title),
+ KEY (pl_namespace,pl_title)
+
+) TYPE=InnoDB;
+
+
+-- Import existing-page links
+INSERT
+ INTO /*$wgDBprefix*/pagelinks (pl_from,pl_namespace,pl_title)
+ SELECT l_from,page_namespace,page_title
+ FROM /*$wgDBprefix*/links, /*$wgDBprefix*/page
+ WHERE l_to=page_id;
+
+-- import brokenlinks
+-- NOTE: We'll have to fix up individual entries that aren't in main NS
+INSERT INTO /*$wgDBprefix*/pagelinks (pl_from,pl_namespace,pl_title)
+ SELECT bl_from, 0, bl_to
+ FROM /*$wgDBprefix*/brokenlinks;
+
+-- For each namespace do something like:
+--
+-- UPDATE /*$wgDBprefix*/pagelinks
+-- SET pl_namespace=$ns,
+-- pl_title=TRIM(LEADING '$prefix:' FROM pl_title)
+-- WHERE pl_namespace=0
+-- AND pl_title LIKE '$likeprefix:%'";
+--
diff --git a/maintenance/archives/patch-parsercache.sql b/maintenance/archives/patch-parsercache.sql
new file mode 100644
index 000000000000..854e6c57ce20
--- /dev/null
+++ b/maintenance/archives/patch-parsercache.sql
@@ -0,0 +1,15 @@
+--
+-- parsercache table, for cacheing complete parsed articles
+-- before they are imbedded in the skin.
+--
+
+CREATE TABLE /*$wgDBprefix*/parsercache (
+ pc_pageid INT(11) NOT NULL,
+ pc_title VARCHAR(255) NOT NULL,
+ pc_prefhash CHAR(32) NOT NULL,
+ pc_expire DATETIME NOT NULL,
+ pc_data MEDIUMBLOB NOT NULL,
+ PRIMARY KEY (pc_pageid, pc_prefhash),
+ KEY(pc_title),
+ KEY(pc_expire)
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-profiling.sql b/maintenance/archives/patch-profiling.sql
new file mode 100644
index 000000000000..bafd2b67ae5e
--- /dev/null
+++ b/maintenance/archives/patch-profiling.sql
@@ -0,0 +1,10 @@
+-- profiling table
+-- This is optional
+
+CREATE TABLE /*$wgDBprefix*/profiling (
+ pf_count int NOT NULL default 0,
+ pf_time float NOT NULL default 0,
+ pf_name varchar(255) NOT NULL default '',
+ pf_server varchar(30) NOT NULL default '',
+ UNIQUE KEY pf_name_server (pf_name, pf_server)
+) TYPE=HEAP;
diff --git a/maintenance/archives/patch-querycache.sql b/maintenance/archives/patch-querycache.sql
new file mode 100644
index 000000000000..7df9129e93a0
--- /dev/null
+++ b/maintenance/archives/patch-querycache.sql
@@ -0,0 +1,16 @@
+-- Used for caching expensive grouped queries
+
+CREATE TABLE /*$wgDBprefix*/querycache (
+ -- A key name, generally the base name of of the special page.
+ qc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qc_namespace int NOT NULL default '0',
+ qc_title char(255) binary NOT NULL default '',
+
+ KEY (qc_type,qc_value)
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-querycacheinfo.sql b/maintenance/archives/patch-querycacheinfo.sql
new file mode 100644
index 000000000000..0e34b3a56b4a
--- /dev/null
+++ b/maintenance/archives/patch-querycacheinfo.sql
@@ -0,0 +1,12 @@
+CREATE TABLE /*$wgDBprefix*/querycache_info (
+
+ -- Special page name
+ -- Corresponds to a qc_type value
+ qci_type varchar(32) NOT NULL default '',
+
+ -- Timestamp of last update
+ qci_timestamp char(14) NOT NULL default '19700101000000',
+
+ UNIQUE KEY ( qci_type )
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-querycachetwo.sql b/maintenance/archives/patch-querycachetwo.sql
new file mode 100644
index 000000000000..cda5b90d07c0
--- /dev/null
+++ b/maintenance/archives/patch-querycachetwo.sql
@@ -0,0 +1,22 @@
+-- Used for caching expensive grouped queries that need two links (for example double-redirects)
+
+CREATE TABLE /*$wgDBprefix*/querycachetwo (
+ -- A key name, generally the base name of of the special page.
+ qcc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qcc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qcc_namespace int NOT NULL default '0',
+ qcc_title char(255) binary NOT NULL default '',
+
+ -- Target namespace+title2
+ qcc_namespacetwo int NOT NULL default '0',
+ qcc_titletwo char(255) binary NOT NULL default '',
+
+ KEY qcc_type (qcc_type,qcc_value),
+ KEY qcc_title (qcc_type,qcc_namespace,qcc_title),
+ KEY qcc_titletwo (qcc_type,qcc_namespacetwo,qcc_titletwo)
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-random-dateindex.sql b/maintenance/archives/patch-random-dateindex.sql
new file mode 100644
index 000000000000..5d514cc36928
--- /dev/null
+++ b/maintenance/archives/patch-random-dateindex.sql
@@ -0,0 +1,54 @@
+-- patch-random-dateindex.sql
+-- 2003-02-09
+--
+-- This patch does two things:
+-- * Adds cur_random column to replace random table
+-- (Requires change to SpecialRandom.php)
+-- random table no longer needs refilling
+-- Note: short-term duplicate results *are* possible, but very unlikely on large wiki
+--
+-- * Adds inverse_timestamp columns to cur and old and indexes
+-- to allow descending timestamp sort in history, contribs, etc
+-- (Requires changes to Article.php, DatabaseFunctions.php,
+-- ... )
+-- cur_timestamp inverse_timestamp
+-- 99999999999999 - 20030209222556 = 79969790777443
+-- 99999999999999 - 20030211083412 = 79969788916587
+--
+-- We won't need this on MySQL 4; there will be a removal patch later.
+
+-- Indexes:
+-- cur needs (cur_random) for random sort
+-- cur and old need (namespace,title,timestamp) index for history,watchlist,rclinked
+-- cur and old need (user,timestamp) index for contribs
+-- cur and old need (user_text,timestamp) index for contribs
+
+ALTER TABLE /*$wgDBprefix*/cur
+ DROP INDEX cur_user,
+ DROP INDEX cur_user_text,
+ ADD COLUMN cur_random real unsigned NOT NULL,
+ ADD COLUMN inverse_timestamp char(14) binary NOT NULL default '',
+ ADD INDEX (cur_random),
+ ADD INDEX name_title_timestamp (cur_namespace,cur_title,inverse_timestamp),
+ ADD INDEX user_timestamp (cur_user,inverse_timestamp),
+ ADD INDEX usertext_timestamp (cur_user_text,inverse_timestamp);
+
+UPDATE /*$wgDBprefix*/cur SET
+ inverse_timestamp=99999999999999-cur_timestamp,
+ cur_random=RAND();
+
+ALTER TABLE /*$wgDBprefix*/old
+ DROP INDEX old_user,
+ DROP INDEX old_user_text,
+ ADD COLUMN inverse_timestamp char(14) binary NOT NULL default '',
+ ADD INDEX name_title_timestamp (old_namespace,old_title,inverse_timestamp),
+ ADD INDEX user_timestamp (old_user,inverse_timestamp),
+ ADD INDEX usertext_timestamp (old_user_text,inverse_timestamp);
+
+UPDATE /*$wgDBprefix*/old SET
+ inverse_timestamp=99999999999999-old_timestamp;
+
+-- If leaving wiki publicly accessible in read-only mode during
+-- the upgrade, comment out the below line; leave 'random' table
+-- in place until the new software is installed.
+DROP TABLE /*$wgDBprefix*/random;
diff --git a/maintenance/archives/patch-rc-newindex.sql b/maintenance/archives/patch-rc-newindex.sql
new file mode 100644
index 000000000000..2315ff374a7c
--- /dev/null
+++ b/maintenance/archives/patch-rc-newindex.sql
@@ -0,0 +1,9 @@
+--
+-- patch-rc-newindex.sql
+-- Adds an index to recentchanges to optimize Special:Newpages
+-- 2004-01-25
+--
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD INDEX new_name_timestamp(rc_new,rc_namespace,rc_timestamp);
+
diff --git a/maintenance/archives/patch-rc-patrol.sql b/maintenance/archives/patch-rc-patrol.sql
new file mode 100644
index 000000000000..1839c1ee2b42
--- /dev/null
+++ b/maintenance/archives/patch-rc-patrol.sql
@@ -0,0 +1,9 @@
+--
+-- patch-rc-patrol.sql
+-- Adds a row to recentchanges for the patrolling feature
+-- 2004-08-09
+--
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD COLUMN rc_patrolled tinyint(3) unsigned NOT NULL default '0';
+
diff --git a/maintenance/archives/patch-rc_id.sql b/maintenance/archives/patch-rc_id.sql
new file mode 100644
index 000000000000..6dd9ef4a0987
--- /dev/null
+++ b/maintenance/archives/patch-rc_id.sql
@@ -0,0 +1,7 @@
+-- Primary key in recentchanges
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD rc_id int(8) NOT NULL auto_increment,
+ ADD PRIMARY KEY rc_id (rc_id);
+
+
diff --git a/maintenance/archives/patch-rc_ip.sql b/maintenance/archives/patch-rc_ip.sql
new file mode 100644
index 000000000000..a68a22cb25f1
--- /dev/null
+++ b/maintenance/archives/patch-rc_ip.sql
@@ -0,0 +1,7 @@
+-- Adding the rc_ip field for logging of IP addresses in recentchanges
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD rc_ip char(15) NOT NULL default '',
+ ADD INDEX rc_ip (rc_ip);
+
+
diff --git a/maintenance/archives/patch-rc_len.sql b/maintenance/archives/patch-rc_len.sql
new file mode 100644
index 000000000000..920f755b6ef8
--- /dev/null
+++ b/maintenance/archives/patch-rc_len.sql
@@ -0,0 +1,9 @@
+--
+-- patch-rc_len.sql
+-- Adds two rows to recentchanges to hold the text size befor and after the edit
+-- 2006-12-03
+--
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD COLUMN rc_old_len int(10), ADD COLUMN rc_new_len int(10);
+
diff --git a/maintenance/archives/patch-rc_type.sql b/maintenance/archives/patch-rc_type.sql
new file mode 100644
index 000000000000..1097771b1948
--- /dev/null
+++ b/maintenance/archives/patch-rc_type.sql
@@ -0,0 +1,9 @@
+-- recentchanges improvements --
+
+ALTER TABLE /*$wgDBprefix*/recentchanges
+ ADD rc_type tinyint(3) unsigned NOT NULL default '0',
+ ADD rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0',
+ ADD rc_moved_to_title varchar(255) binary NOT NULL default '';
+
+UPDATE /*$wgDBprefix*/recentchanges SET rc_type=1 WHERE rc_new;
+UPDATE /*$wgDBprefix*/recentchanges SET rc_type=3 WHERE rc_namespace=4 AND (rc_title='Deletion_log' OR rc_title='Upload_log');
diff --git a/maintenance/archives/patch-rc_user_text-index.sql b/maintenance/archives/patch-rc_user_text-index.sql
new file mode 100644
index 000000000000..f6acc99213ca
--- /dev/null
+++ b/maintenance/archives/patch-rc_user_text-index.sql
@@ -0,0 +1,7 @@
+-- Add an index to recentchanges on rc_user_text
+--
+-- Added 2006-11-08
+--
+
+ ALTER TABLE /*$wgDBprefix*/recentchanges
+ADD INDEX rc_user_text(rc_user_text, rc_timestamp); \ No newline at end of file
diff --git a/maintenance/archives/patch-recentchanges-utindex.sql b/maintenance/archives/patch-recentchanges-utindex.sql
new file mode 100644
index 000000000000..4ebe316507ba
--- /dev/null
+++ b/maintenance/archives/patch-recentchanges-utindex.sql
@@ -0,0 +1,4 @@
+--- July 2006
+--- Index on recentchanges.( rc_namespace, rc_user_text )
+--- Helps the username filtering in Special:Newpages
+ALTER TABLE /*$wgDBprefix*/recentchanges ADD INDEX `rc_ns_usertext` ( `rc_namespace` , `rc_user_text` ); \ No newline at end of file
diff --git a/maintenance/archives/patch-redirect.sql b/maintenance/archives/patch-redirect.sql
new file mode 100644
index 000000000000..d377f1b1e21b
--- /dev/null
+++ b/maintenance/archives/patch-redirect.sql
@@ -0,0 +1,28 @@
+--
+-- Create the new redirect table.
+-- For each redirect, this table contains exactly one row defining its target
+--
+CREATE TABLE /*$wgDBprefix*/redirect (
+ -- Key to the page_id of the redirect page
+ rd_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ rd_namespace int NOT NULL default '0',
+ rd_title varchar(255) binary NOT NULL default '',
+
+ PRIMARY KEY rd_from (rd_from),
+ KEY rd_ns_title (rd_namespace,rd_title,rd_from)
+) TYPE=InnoDB;
+
+-- Import existing redirects
+-- Using ignore because some of the redirect pages contain more than one link
+INSERT IGNORE
+ INTO /*$wgDBprefix*/redirect (rd_from,rd_namespace,rd_title)
+ SELECT pl_from,pl_namespace,pl_title
+ FROM /*$wgDBprefix*/pagelinks, /*$wgDBprefix*/page
+ WHERE pl_from=page_id AND page_is_redirect=1;
+
+
diff --git a/maintenance/archives/patch-rename-group.sql b/maintenance/archives/patch-rename-group.sql
new file mode 100644
index 000000000000..026b60bdc4de
--- /dev/null
+++ b/maintenance/archives/patch-rename-group.sql
@@ -0,0 +1,10 @@
+-- Rename groups table to groups, which is not a keyword
+-- It was called group in a few alpha versions
+
+RENAME TABLE /*$wgDBprefix*/`group` TO /*$wgDBprefix*/groups;
+ALTER TABLE /*$wgDBprefix*/groups
+ CHANGE group_id gr_id int(5) unsigned NOT NULL auto_increment,
+ CHANGE group_name gr_name varchar(50) NOT NULL default '',
+ CHANGE group_description gr_description varchar(255) NOT NULL default '',
+ CHANGE group_rights gr_rights tinyblob;
+
diff --git a/maintenance/archives/patch-rename-user_groups-and_rights.sql b/maintenance/archives/patch-rename-user_groups-and_rights.sql
new file mode 100644
index 000000000000..650f260455ed
--- /dev/null
+++ b/maintenance/archives/patch-rename-user_groups-and_rights.sql
@@ -0,0 +1,9 @@
+
+ALTER TABLE /*$wgDBprefix*/user_groups
+ CHANGE user_id ug_user INT(5) UNSIGNED NOT NULL DEFAULT '0',
+ CHANGE group_id ug_group INT(5) UNSIGNED NOT NULL DEFAULT '0';
+
+ALTER TABLE /*$wgDBprefix*/user_rights
+ CHANGE user_id ur_user INT(5) UNSIGNED NOT NULL,
+ CHANGE user_rights ur_rights TINYBLOB NOT NULL;
+
diff --git a/maintenance/archives/patch-restructure.sql b/maintenance/archives/patch-restructure.sql
new file mode 100644
index 000000000000..acf306c234af
--- /dev/null
+++ b/maintenance/archives/patch-restructure.sql
@@ -0,0 +1,147 @@
+-- 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(8) 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(20) unsigned NOT NULL default '0',
+ page_is_redirect tinyint(1) unsigned NOT NULL default '0',
+ page_is_new tinyint(1) unsigned NOT NULL default '0',
+ page_random real unsigned NOT NULL,
+ page_touched char(14) binary NOT NULL default '',
+ page_latest int(8) unsigned NOT NULL,
+ page_len int(8) 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(8) unsigned NOT NULL auto_increment,
+ rev_page int(8) unsigned NOT NULL,
+ rev_comment tinyblob NOT NULL,
+ rev_user int(5) unsigned NOT NULL default '0',
+ rev_user_text varchar(255) binary NOT NULL default '',
+ rev_timestamp char(14) binary NOT NULL default '',
+ rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
+ rev_deleted tinyint(1) 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/archives/patch-rev_deleted.sql b/maintenance/archives/patch-rev_deleted.sql
new file mode 100644
index 000000000000..3af0c1d72692
--- /dev/null
+++ b/maintenance/archives/patch-rev_deleted.sql
@@ -0,0 +1,11 @@
+--
+-- Add rev_deleted flag to revision table.
+-- Deleted revisions can thus continue to be listed in history
+-- and user contributions, and their text storage doesn't have
+-- to be disturbed.
+--
+-- 2005-03-31
+--
+
+ALTER TABLE /*$wgDBprefix*/revision
+ ADD rev_deleted tinyint(1) unsigned NOT NULL default '0';
diff --git a/maintenance/archives/patch-rev_text_id.sql b/maintenance/archives/patch-rev_text_id.sql
new file mode 100644
index 000000000000..44ef438ce631
--- /dev/null
+++ b/maintenance/archives/patch-rev_text_id.sql
@@ -0,0 +1,17 @@
+--
+-- Adds rev_text_id field to revision table.
+-- This is a key to text.old_id, so that revisions can be stored
+-- for non-save operations without duplicating text, and so that
+-- a back-end storage system can provide its own numbering system
+-- if necessary.
+--
+-- rev.rev_id and text.old_id are no longer assumed to be the same.
+--
+-- 2005-03-28
+--
+
+ALTER TABLE /*$wgDBprefix*/revision
+ ADD rev_text_id int(8) unsigned NOT NULL;
+
+UPDATE /*$wgDBprefix*/revision
+ SET rev_text_id=rev_id;
diff --git a/maintenance/archives/patch-searchindex.sql b/maintenance/archives/patch-searchindex.sql
new file mode 100644
index 000000000000..2b9b67020e26
--- /dev/null
+++ b/maintenance/archives/patch-searchindex.sql
@@ -0,0 +1,40 @@
+-- Break fulltext search index out to separate table from cur
+-- This is being done mainly to allow us to use InnoDB tables
+-- for the main db while keeping the MyISAM fulltext index for
+-- search.
+
+-- 2002-12-16, 2003-01-25 Brion VIBBER <brion@pobox.com>
+
+-- Creating searchindex table...
+DROP TABLE IF EXISTS /*$wgDBprefix*/searchindex;
+CREATE TABLE /*$wgDBprefix*/searchindex (
+ -- Key to page_id
+ si_page int(8) unsigned NOT NULL,
+
+ -- Munged version of title
+ si_title varchar(255) NOT NULL default '',
+
+ -- Munged version of body text
+ si_text mediumtext NOT NULL,
+
+ UNIQUE KEY (si_page)
+
+) TYPE=MyISAM;
+
+-- Copying data into new table...
+INSERT INTO /*$wgDBprefix*/searchindex
+ (si_page,si_title,si_text)
+ SELECT
+ cur_id,cur_ind_title,cur_ind_text
+ FROM /*$wgDBprefix*/cur;
+
+
+-- Creating fulltext index...
+ALTER TABLE /*$wgDBprefix*/searchindex
+ ADD FULLTEXT si_title (si_title),
+ ADD FULLTEXT si_text (si_text);
+
+-- Dropping index columns from cur table.
+ALTER TABLE /*$wgDBprefix*/cur
+ DROP COLUMN cur_ind_title,
+ DROP COLUMN cur_ind_text;
diff --git a/maintenance/archives/patch-ss_images.sql b/maintenance/archives/patch-ss_images.sql
new file mode 100644
index 000000000000..e1950eb6cb54
--- /dev/null
+++ b/maintenance/archives/patch-ss_images.sql
@@ -0,0 +1,5 @@
+-- More statistics, for version 1.6
+
+ALTER TABLE /*$wgDBprefix*/site_stats ADD ss_images int(10) default '0';
+SELECT @images := COUNT(*) FROM /*$wgDBprefix*/image;
+UPDATE /*$wgDBprefix*/site_stats SET ss_images=@images;
diff --git a/maintenance/archives/patch-ss_total_articles.sql b/maintenance/archives/patch-ss_total_articles.sql
new file mode 100644
index 000000000000..b4a48cf7b3aa
--- /dev/null
+++ b/maintenance/archives/patch-ss_total_articles.sql
@@ -0,0 +1,6 @@
+-- Faster statistics, as of 1.4.3
+
+ALTER TABLE /*$wgDBprefix*/site_stats
+ ADD ss_total_pages bigint(20) default -1,
+ ADD ss_users bigint(20) default -1,
+ ADD ss_admins int(10) default -1;
diff --git a/maintenance/archives/patch-templatelinks.sql b/maintenance/archives/patch-templatelinks.sql
new file mode 100644
index 000000000000..49bd9c5ef292
--- /dev/null
+++ b/maintenance/archives/patch-templatelinks.sql
@@ -0,0 +1,19 @@
+--
+-- Track template inclusions.
+--
+CREATE TABLE /*$wgDBprefix*/templatelinks (
+ -- Key to the page_id of the page containing the link.
+ tl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ tl_namespace int NOT NULL default '0',
+ tl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY tl_from(tl_from,tl_namespace,tl_title),
+ KEY (tl_namespace,tl_title)
+
+) TYPE=InnoDB;
+
diff --git a/maintenance/archives/patch-trackbacks.sql b/maintenance/archives/patch-trackbacks.sql
new file mode 100644
index 000000000000..4193d0580d55
--- /dev/null
+++ b/maintenance/archives/patch-trackbacks.sql
@@ -0,0 +1,10 @@
+CREATE TABLE /*$wgDBprefix*/trackbacks (
+ tb_id INTEGER AUTO_INCREMENT PRIMARY KEY,
+ tb_page INTEGER REFERENCES page(page_id) ON DELETE CASCADE,
+ tb_title VARCHAR(255) NOT NULL,
+ tb_url VARCHAR(255) NOT NULL,
+ tb_ex TEXT,
+ tb_name VARCHAR(255),
+
+ INDEX (tb_page)
+);
diff --git a/maintenance/archives/patch-transcache.sql b/maintenance/archives/patch-transcache.sql
new file mode 100644
index 000000000000..a244bff89801
--- /dev/null
+++ b/maintenance/archives/patch-transcache.sql
@@ -0,0 +1,7 @@
+CREATE TABLE /*$wgDBprefix*/transcache (
+ tc_url VARCHAR(255) NOT NULL,
+ tc_contents TEXT,
+ tc_time INT NOT NULL,
+ UNIQUE INDEX tc_url_idx(tc_url)
+) TYPE=InnoDB;
+
diff --git a/maintenance/archives/patch-user-realname.sql b/maintenance/archives/patch-user-realname.sql
new file mode 100644
index 000000000000..96edaa4322d5
--- /dev/null
+++ b/maintenance/archives/patch-user-realname.sql
@@ -0,0 +1,5 @@
+-- Add a 'real name' field where users can specify the name they want
+-- used for author attribution or other places that real names matter.
+
+ALTER TABLE user
+ ADD (user_real_name varchar(255) binary NOT NULL default '');
diff --git a/maintenance/archives/patch-user_editcount.sql b/maintenance/archives/patch-user_editcount.sql
new file mode 100644
index 000000000000..cdde36dc33fb
--- /dev/null
+++ b/maintenance/archives/patch-user_editcount.sql
@@ -0,0 +1,5 @@
+ALTER TABLE /*$wgDBprefix*/user
+ ADD COLUMN user_editcount int;
+
+-- Don't initialize values immediately... or should we?
+-- They will be lazy-evaluated, or batch-filled via maintenance/initEditCount.php
diff --git a/maintenance/archives/patch-user_email_token.sql b/maintenance/archives/patch-user_email_token.sql
new file mode 100644
index 000000000000..d4d633b776cd
--- /dev/null
+++ b/maintenance/archives/patch-user_email_token.sql
@@ -0,0 +1,12 @@
+--
+-- E-mail confirmation token and expiration timestamp,
+-- for verification of e-mail addresses.
+--
+-- 2005-04-25
+--
+
+ALTER TABLE /*$wgDBprefix*/user
+ ADD COLUMN user_email_authenticated CHAR(14) BINARY,
+ ADD COLUMN user_email_token CHAR(32) BINARY,
+ ADD COLUMN user_email_token_expires CHAR(14) BINARY,
+ ADD INDEX (user_email_token);
diff --git a/maintenance/archives/patch-user_groups.sql b/maintenance/archives/patch-user_groups.sql
new file mode 100644
index 000000000000..50f9999355c0
--- /dev/null
+++ b/maintenance/archives/patch-user_groups.sql
@@ -0,0 +1,25 @@
+--
+-- User permissions have been broken out to a separate table;
+-- this allows sites with a shared user table to have different
+-- permissions assigned to a user in each project.
+--
+-- This table replaces the old user_rights field which used a
+-- comma-separated blob.
+--
+CREATE TABLE /*$wgDBprefix*/user_groups (
+ -- Key to user_id
+ ug_user int(5) unsigned NOT NULL default '0',
+
+ -- Group names are short symbolic string keys.
+ -- The set of group names is open-ended, though in practice
+ -- only some predefined ones are likely to be used.
+ --
+ -- At runtime $wgGroupPermissions will associate group keys
+ -- with particular permissions. A user will have the combined
+ -- permissions of any group they're explicitly in, plus
+ -- the implicit '*' and 'user' groups.
+ ug_group char(16) NOT NULL default '',
+
+ PRIMARY KEY (ug_user,ug_group),
+ KEY (ug_group)
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-user_nameindex.sql b/maintenance/archives/patch-user_nameindex.sql
new file mode 100644
index 000000000000..9bf0aab1bb91
--- /dev/null
+++ b/maintenance/archives/patch-user_nameindex.sql
@@ -0,0 +1,13 @@
+--
+-- Change the index on user_name to a unique index to prevent
+-- duplicate registrations from creeping in.
+--
+-- Run maintenance/userDupes.php or through the updater first
+-- to clean up any prior duplicate accounts.
+--
+-- Added 2005-06-05
+--
+
+ ALTER TABLE /*$wgDBprefix*/user
+ DROP INDEX user_name,
+ADD UNIQUE INDEX user_name(user_name);
diff --git a/maintenance/archives/patch-user_newpass_time.sql b/maintenance/archives/patch-user_newpass_time.sql
new file mode 100644
index 000000000000..47b332baafe1
--- /dev/null
+++ b/maintenance/archives/patch-user_newpass_time.sql
@@ -0,0 +1,4 @@
+-- Timestamp of the last time when a new password was
+-- sent, for throttling purposes
+ALTER TABLE /*$wgDBprefix*/user ADD user_newpass_time char(14) binary;
+
diff --git a/maintenance/archives/patch-user_registration.sql b/maintenance/archives/patch-user_registration.sql
new file mode 100644
index 000000000000..65fd99df35e6
--- /dev/null
+++ b/maintenance/archives/patch-user_registration.sql
@@ -0,0 +1,9 @@
+--
+-- New user field for tracking registration time
+-- 2005-12-21
+--
+
+ALTER TABLE /*$wgDBprefix*/user
+ -- Timestamp of account registration.
+ -- Accounts predating this schema addition may contain NULL.
+ ADD user_registration CHAR(14) BINARY;
diff --git a/maintenance/archives/patch-user_rights.sql b/maintenance/archives/patch-user_rights.sql
new file mode 100644
index 000000000000..a32ef4571914
--- /dev/null
+++ b/maintenance/archives/patch-user_rights.sql
@@ -0,0 +1,21 @@
+-- Split user table into two parts:
+-- user
+-- user_rights
+-- The later contains only the permissions of the user. This way,
+-- you can store the accounts for several wikis in one central
+-- database but keep user rights local to the wiki.
+
+CREATE TABLE /*$wgDBprefix*/user_rights (
+ -- Key to user_id
+ ur_user int(5) unsigned NOT NULL,
+
+ -- Comma-separated list of permission keys
+ ur_rights tinyblob NOT NULL,
+
+ UNIQUE KEY ur_user (ur_user)
+
+) TYPE=InnoDB;
+
+INSERT INTO /*$wgDBprefix*/user_rights SELECT user_id,user_rights FROM /*$wgDBprefix*/user;
+
+ALTER TABLE /*$wgDBprefix*/user DROP COLUMN user_rights;
diff --git a/maintenance/archives/patch-user_token.sql b/maintenance/archives/patch-user_token.sql
new file mode 100644
index 000000000000..797dc98f66a7
--- /dev/null
+++ b/maintenance/archives/patch-user_token.sql
@@ -0,0 +1,15 @@
+-- user_token patch
+-- 2004-09-23
+
+ALTER TABLE /*$wgDBprefix*/user ADD user_token char(32) binary NOT NULL default '';
+
+UPDATE /*$wgDBprefix*/user SET user_token = concat(
+ substring(rand(),3,4),
+ substring(rand(),3,4),
+ substring(rand(),3,4),
+ substring(rand(),3,4),
+ substring(rand(),3,4),
+ substring(rand(),3,4),
+ substring(rand(),3,4),
+ substring(rand(),3,4)
+);
diff --git a/maintenance/archives/patch-userindex.sql b/maintenance/archives/patch-userindex.sql
new file mode 100644
index 000000000000..c039b2f34479
--- /dev/null
+++ b/maintenance/archives/patch-userindex.sql
@@ -0,0 +1 @@
+ ALTER TABLE /*$wgDBprefix*/user ADD INDEX ( `user_name` ); \ No newline at end of file
diff --git a/maintenance/archives/patch-userlevels-defaultgroups.sql b/maintenance/archives/patch-userlevels-defaultgroups.sql
new file mode 100644
index 000000000000..065653da9450
--- /dev/null
+++ b/maintenance/archives/patch-userlevels-defaultgroups.sql
@@ -0,0 +1,30 @@
+--
+-- Provide default groups
+-- Should probably be inserted when someone create a new database
+--
+
+INSERT INTO /*$wgDBprefix*/groups (gr_id,gr_name,gr_description,gr_rights)
+ VALUES (
+ 1,':group-anon-name',':group-anon-desc',
+ 'read,edit,createaccount'
+ );
+INSERT INTO /*$wgDBprefix*/groups (gr_id,gr_name,gr_description,gr_rights)
+ VALUES (
+ 2,':group-loggedin-name',':group-loggedin-desc',
+ 'read,edit,move,upload,validate,createaccount'
+ );
+INSERT INTO /*$wgDBprefix*/groups (gr_id,gr_name,gr_description,gr_rights)
+ VALUES (
+ 3,':group-admin-name',':group-admin-desc',
+ 'read,edit,move,upload,validate,createaccount,delete,undelete,protect,block,upload,asksql,rollback,patrol,editinterface,import'
+ );
+INSERT INTO /*$wgDBprefix*/groups (gr_id,gr_name,gr_description,gr_rights)
+ VALUES (
+ 4,':group-bureaucrat-name',':group-bureaucrat-desc',
+ 'read,edit,move,upload,validate,createaccount,delete,undelete,protect,block,upload,asksql,rollback,patrol,editinterface,import,makesysop'
+ );
+INSERT INTO /*$wgDBprefix*/groups (gr_id,gr_name,gr_description,gr_rights)
+ VALUES (
+ 5,':group-steward-name',':group-steward-desc',
+ 'read,edit,move,upload,validate,createaccount,delete,undelete,protect,block,upload,asksql,rollback,patrol,editinterface,import,makesysop,userrights,grouprights,siteadmin'
+ );
diff --git a/maintenance/archives/patch-userlevels-rights.sql b/maintenance/archives/patch-userlevels-rights.sql
new file mode 100644
index 000000000000..7f1cabfc8812
--- /dev/null
+++ b/maintenance/archives/patch-userlevels-rights.sql
@@ -0,0 +1,5 @@
+-- Oct. 24 2004
+-- Adds the gr_rights field missing from early dev work
+
+-- Hold group name and description
+ALTER TABLE /*$wgDBprefix*/groups ADD gr_rights tinyblob;
diff --git a/maintenance/archives/patch-userlevels.sql b/maintenance/archives/patch-userlevels.sql
new file mode 100644
index 000000000000..ab3a9a7ba803
--- /dev/null
+++ b/maintenance/archives/patch-userlevels.sql
@@ -0,0 +1,22 @@
+-- Oct. 1st 2004 - Ashar Voultoiz
+-- Implement the new sitelevels
+--
+-- This is under development to provide a showcase in HEAD :o)
+
+-- Hold group name and description
+CREATE TABLE /*$wgDBprefix*/groups (
+ gr_id int(5) unsigned NOT NULL auto_increment,
+ gr_name varchar(50) NOT NULL default '',
+ gr_description varchar(255) NOT NULL default '',
+ gr_rights tinyblob,
+ PRIMARY KEY (gr_id)
+
+) TYPE=InnoDB;
+
+-- Relation table between user and groups
+CREATE TABLE /*$wgDBprefix*/user_groups (
+ ug_user int(5) unsigned NOT NULL default '0',
+ ug_group int(5) unsigned NOT NULL default '0',
+ PRIMARY KEY (ug_user,ug_group)
+
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-usernewtalk.sql b/maintenance/archives/patch-usernewtalk.sql
new file mode 100644
index 000000000000..fb8c86557148
--- /dev/null
+++ b/maintenance/archives/patch-usernewtalk.sql
@@ -0,0 +1,20 @@
+--- This table stores all the IDs of users whose talk
+--- page has been changed (the respective row is deleted
+--- when the user looks at the page).
+--- The respective column in the user table is no longer
+--- required and therefore dropped.
+
+CREATE TABLE /*$wgDBprefix*/user_newtalk (
+ user_id int(5) NOT NULL default '0',
+ user_ip varchar(40) NOT NULL default '',
+ KEY user_id (user_id),
+ KEY user_ip (user_ip)
+) TYPE=MyISAM;
+
+INSERT INTO
+ /*$wgDBprefix*/user_newtalk (user_id, user_ip)
+ SELECT user_id, ''
+ FROM user
+ WHERE user_newtalk != 0;
+
+ALTER TABLE /*$wgDBprefix*/user DROP COLUMN user_newtalk;
diff --git a/maintenance/archives/patch-usernewtalk2.sql b/maintenance/archives/patch-usernewtalk2.sql
new file mode 100644
index 000000000000..477109b79460
--- /dev/null
+++ b/maintenance/archives/patch-usernewtalk2.sql
@@ -0,0 +1,6 @@
+CREATE TABLE /*$wgDBprefix*/user_newtalk (
+ user_id int(5) NOT NULL default '0',
+ user_ip varchar(40) NOT NULL default '',
+ INDEX user_id (user_id),
+ INDEX user_ip (user_ip)
+);
diff --git a/maintenance/archives/patch-val_ip.sql b/maintenance/archives/patch-val_ip.sql
new file mode 100644
index 000000000000..9214218dc54d
--- /dev/null
+++ b/maintenance/archives/patch-val_ip.sql
@@ -0,0 +1,4 @@
+-- Column added 2005-05-24
+
+ALTER TABLE /*$wgDBprefix*/validate
+ ADD COLUMN val_ip varchar(20) NOT NULL default '';
diff --git a/maintenance/archives/patch-validate.sql b/maintenance/archives/patch-validate.sql
new file mode 100644
index 000000000000..3fa7e844ec33
--- /dev/null
+++ b/maintenance/archives/patch-validate.sql
@@ -0,0 +1,13 @@
+-- For article validation
+
+DROP TABLE IF EXISTS /*$wgDBprefix*/validate;
+CREATE TABLE /*$wgDBprefix*/validate (
+ `val_user` int(11) NOT NULL default '0',
+ `val_page` int(11) unsigned NOT NULL default '0',
+ `val_revision` int(11) unsigned NOT NULL default '0',
+ `val_type` int(11) unsigned NOT NULL default '0',
+ `val_value` int(11) default '0',
+ `val_comment` varchar(255) NOT NULL default '',
+ `val_ip` varchar(20) NOT NULL default '',
+ KEY `val_user` (`val_user`,`val_revision`)
+) TYPE=InnoDB;
diff --git a/maintenance/archives/patch-watchlist-null.sql b/maintenance/archives/patch-watchlist-null.sql
new file mode 100644
index 000000000000..37ffc16351cd
--- /dev/null
+++ b/maintenance/archives/patch-watchlist-null.sql
@@ -0,0 +1,9 @@
+-- Set up wl_notificationtimestamp with NULL support.
+-- 2005-08-17
+
+ALTER TABLE /*$wgDBprefix*/watchlist
+ CHANGE wl_notificationtimestamp wl_notificationtimestamp varchar(14) binary;
+
+UPDATE /*$wgDBprefix*/watchlist
+ SET wl_notificationtimestamp=NULL
+ WHERE wl_notificationtimestamp='0';
diff --git a/maintenance/archives/patch-watchlist.sql b/maintenance/archives/patch-watchlist.sql
new file mode 100644
index 000000000000..adee010b6720
--- /dev/null
+++ b/maintenance/archives/patch-watchlist.sql
@@ -0,0 +1,30 @@
+-- Convert watchlists to new new format ;)
+
+-- Ids just aren't convenient when what we want is to
+-- treat article and talk pages as equivalent.
+-- Better to use namespace (drop the 1 bit!) and title
+
+-- 2002-12-17 by Brion Vibber <brion@pobox.com>
+-- affects, affected by changes to SpecialWatchlist.php, User.php,
+-- Article.php, Title.php, SpecialRecentchanges.php
+
+DROP TABLE IF EXISTS watchlist2;
+CREATE TABLE watchlist2 (
+ wl_user int(5) unsigned NOT NULL,
+ wl_namespace tinyint(2) unsigned NOT NULL default '0',
+ wl_title varchar(255) binary NOT NULL default '',
+ UNIQUE KEY (wl_user, wl_namespace, wl_title)
+) TYPE=MyISAM PACK_KEYS=1;
+
+INSERT INTO watchlist2 (wl_user,wl_namespace,wl_title)
+ SELECT DISTINCT wl_user,(cur_namespace | 1) - 1,cur_title
+ FROM watchlist,cur WHERE wl_page=cur_id;
+
+ALTER TABLE watchlist RENAME TO oldwatchlist;
+ALTER TABLE watchlist2 RENAME TO watchlist;
+
+-- Check that the new one is correct, then:
+-- DROP TABLE oldwatchlist;
+
+-- Also should probably drop the ancient and now unused:
+ALTER TABLE user DROP COLUMN user_watch;
diff --git a/maintenance/archives/rebuildRecentchanges.inc b/maintenance/archives/rebuildRecentchanges.inc
new file mode 100644
index 000000000000..54f6cb38c6a1
--- /dev/null
+++ b/maintenance/archives/rebuildRecentchanges.inc
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Rebuild recent changes table
+ *
+ * @deprecated
+ * @package MediaWiki
+ * @subpackage MaintenanceArchive
+ */
+
+/** */
+function rebuildRecentChangesTable()
+{
+ $sql = "DROP TABLE IF EXISTS recentchanges";
+ wfQuery( $sql );
+
+ $sql = "CREATE TABLE recentchanges (
+ rc_timestamp varchar(14) binary NOT NULL default '',
+ rc_cur_time varchar(14) binary NOT NULL default '',
+ rc_user int(10) unsigned NOT NULL default '0',
+ rc_user_text varchar(255) binary NOT NULL default '',
+ rc_namespace tinyint(3) unsigned NOT NULL default '0',
+ rc_title varchar(255) binary NOT NULL default '',
+ rc_comment varchar(255) binary NOT NULL default '',
+ rc_minor tinyint(3) unsigned NOT NULL default '0',
+ rc_new tinyint(3) unsigned NOT NULL default '0',
+ rc_cur_id int(10) unsigned NOT NULL default '0',
+ rc_this_oldid int(10) unsigned NOT NULL default '0',
+ rc_last_oldid int(10) unsigned NOT NULL default '0',
+ INDEX rc_cur_id (rc_cur_id),
+ INDEX rc_cur_time (rc_cur_time),
+ INDEX rc_timestamp (rc_timestamp),
+ INDEX rc_namespace (rc_namespace),
+ INDEX rc_title (rc_title)
+) TYPE=MyISAM PACK_KEYS=1;";
+ wfQuery( $sql );
+
+ print( "Loading from CUR table...\n" );
+
+ $sql = "INSERT INTO recentchanges (rc_timestamp,rc_cur_time,rc_user," .
+ "rc_user_text,rc_namespace,rc_title,rc_comment,rc_minor,rc_new," .
+ "rc_cur_id,rc_this_oldid,rc_last_oldid) SELECT cur_timestamp," .
+ "cur_timestamp,cur_user,cur_user_text,cur_namespace,cur_title," .
+ "cur_comment,cur_minor_edit,cur_is_new,cur_id,0,0 FROM cur " .
+ "ORDER BY cur_timestamp DESC LIMIT 5000";
+ wfQuery( $sql );
+
+ print( "Loading from OLD table...\n" );
+
+ $sql = "INSERT INTO recentchanges (rc_timestamp,rc_cur_time,rc_user," .
+ "rc_user_text,rc_namespace,rc_title,rc_comment,rc_minor,rc_new," .
+ "rc_cur_id,rc_this_oldid,rc_last_oldid) SELECT old_timestamp,''," .
+ "old_user,old_user_text,old_namespace,old_title,old_comment," .
+ "old_minor_edit,0,0,old_id,0 FROM old ORDER BY old_timestamp " .
+ "DESC LIMIT 5000";
+ wfQuery( $sql );
+
+ $sql = "SELECT rc_timestamp FROM recentchanges " .
+ "ORDER BY rc_timestamp DESC LIMIT 5000,1";
+ $res = wfQuery( $sql );
+ $obj = wfFetchObject( $res );
+ $ts = $obj->rc_timestamp;
+
+ $sql = "DELETE FROM recentchanges WHERE rc_timestamp < '{$ts}'";
+ wfQuery( $sql );
+
+ rebuildRecentChangesTablePass2();
+}
+
+function rebuildRecentChangesTablePass2()
+{
+ $ns = $id = $count = 0;
+ $title = $ct = "";
+
+ print( "Updating links...\n" );
+
+ $sql = "SELECT rc_namespace,rc_title,rc_timestamp FROM recentchanges " .
+ "ORDER BY rc_namespace,rc_title,rc_timestamp DESC";
+ $res = wfQuery( $sql );
+
+ while ( $obj = wfFetchObject( $res ) ) {
+ if ( ! ( $ns == $obj->rc_namespace &&
+ 0 == strcmp( $title, wfStrencode( $obj->rc_title ) ) ) ) {
+
+ $ns = $obj->rc_namespace;
+ $title = wfStrencode( $obj->rc_title );
+
+ $sql = "SELECT cur_id,cur_timestamp FROM cur WHERE " .
+ "cur_namespace={$ns} AND cur_title='{$title}'";
+ $res2 = wfQuery( $sql );
+ $obj2 = wfFetchObject( $res2 );
+
+ $id = $obj2->cur_id;
+ $ct = $obj2->cur_timestamp;
+ }
+ $sql = "SELECT old_id FROM old WHERE old_namespace={$ns} " .
+ "AND old_title='{$title}' AND old_timestamp < '" .
+ "{$obj->rc_timestamp}' ORDER BY old_timestamp DESC LIMIT 1";
+ $res2 = wfQuery( $sql );
+
+ if ( 0 != wfNumRows( $res2 ) ) {
+ $obj2 = wfFetchObject( $res2 );
+
+ $sql = "UPDATE recentchanges SET rc_cur_id={$id},rc_cur_time=" .
+ "'{$ct}',rc_last_oldid={$obj2->old_id} WHERE " .
+ "rc_namespace={$ns} AND rc_title='{$title}' AND " .
+ "rc_timestamp='{$obj->rc_timestamp}'";
+ wfQuery( $sql );
+ } else {
+ $sql = "UPDATE recentchanges SET rc_cur_id={$id},rc_cur_time=" .
+ "'{$ct}' WHERE rc_namespace={$ns} AND rc_title='{$title}' " .
+ "AND rc_timestamp='{$obj->rc_timestamp}'";
+ wfQuery( $sql );
+ }
+
+ if ( 0 == ( ++$count % 500 ) ) {
+ printf( "%d records processed.\n", $count );
+ }
+ }
+}
+
+
+?>
diff --git a/maintenance/archives/upgradeWatchlist.php b/maintenance/archives/upgradeWatchlist.php
new file mode 100644
index 000000000000..b4605a5007de
--- /dev/null
+++ b/maintenance/archives/upgradeWatchlist.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @deprecated
+ * @package MediaWiki
+ * @subpackage MaintenanceArchive
+ */
+
+/** */
+print "This script is obsolete!";
+print "It is retained in the source here in case some of its
+code might be useful for ad-hoc conversion tasks, but it is
+not maintained and probably won't even work as is.";
+exit();
+
+# Convert watchlists to new format
+
+global $IP;
+require_once( "../LocalSettings.php" );
+require_once( "$IP/Setup.php" );
+
+$wgTitle = Title::newFromText( "Rebuild links script" );
+set_time_limit(0);
+
+$wgDBuser = "wikiadmin";
+$wgDBpassword = $wgDBadminpassword;
+
+$sql = "DROP TABLE IF EXISTS watchlist";
+wfQuery( $sql, DB_MASTER );
+$sql = "CREATE TABLE watchlist (
+ wl_user int(5) unsigned NOT NULL,
+ wl_page int(8) unsigned NOT NULL,
+ UNIQUE KEY (wl_user, wl_page)
+) TYPE=MyISAM PACK_KEYS=1";
+wfQuery( $sql, DB_MASTER );
+
+$lc = new LinkCache;
+
+# Now, convert!
+$sql = "SELECT user_id,user_watch FROM user";
+$res = wfQuery( $sql, DB_SLAVE );
+$nu = wfNumRows( $res );
+$sql = "INSERT into watchlist (wl_user,wl_page) VALUES ";
+$i = $n = 0;
+while( $row = wfFetchObject( $res ) ) {
+ $list = explode( "\n", $row->user_watch );
+ $bits = array();
+ foreach( $list as $title ) {
+ if( $id = $lc->addLink( $title ) and ! $bits[$id]++) {
+ $sql .= ($i++ ? "," : "") . "({$row->user_id},{$id})";
+ }
+ }
+ if( ($n++ % 100) == 0 ) echo "$n of $nu users done...\n";
+}
+echo "$n users done.\n";
+if( $i ) {
+ wfQuery( $sql, DB_MASTER );
+}
+
+
+# Add index
+# is this necessary?
+$sql = "ALTER TABLE watchlist
+ ADD INDEX wl_user (wl_user),
+ ADD INDEX wl_page (wl_page)";
+#wfQuery( $sql, DB_MASTER );
+
+?>
diff --git a/maintenance/attachLatest.php b/maintenance/attachLatest.php
new file mode 100644
index 000000000000..f4c11c0193ba
--- /dev/null
+++ b/maintenance/attachLatest.php
@@ -0,0 +1,73 @@
+<?php
+// quick hackjob to fix damages imports on wikisource
+// page records have page_latest wrong
+
+/**
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+require_once( 'commandLine.inc' );
+
+$fixit = isset( $options['fix'] );
+$fname = 'attachLatest';
+
+echo "Looking for pages with page_latest set to 0...\n";
+$dbw =& wfGetDB( DB_MASTER );
+$result = $dbw->select( 'page',
+ array( 'page_id', 'page_namespace', 'page_title' ),
+ array( 'page_latest' => 0 ),
+ $fname );
+
+$n = 0;
+while( $row = $dbw->fetchObject( $result ) ) {
+ $pageId = intval( $row->page_id );
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $name = $title->getPrefixedText();
+ $latestTime = $dbw->selectField( 'revision',
+ 'MAX(rev_timestamp)',
+ array( 'rev_page' => $pageId ),
+ $fname );
+ if( !$latestTime ) {
+ echo wfWikiID()." $pageId [[$name]] can't find latest rev time?!\n";
+ continue;
+ }
+
+ $revision = Revision::loadFromTimestamp( $dbw, $title, $latestTime );
+ if( is_null( $revision ) ) {
+ echo wfWikiID()." $pageId [[$name]] latest time $latestTime, can't find revision id\n";
+ continue;
+ }
+ $id = $revision->getId();
+ echo wfWikiID()." $pageId [[$name]] latest time $latestTime, rev id $id\n";
+ if( $fixit ) {
+ $article = new Article( $title );
+ $article->updateRevisionOn( $dbw, $revision );
+ }
+ $n++;
+}
+$dbw->freeResult( $result );
+echo "Done! Processed $n pages.\n";
+if( !$fixit ) {
+ echo "This was a dry run; rerun with --fix to update page_latest.\n";
+}
+
+?>
diff --git a/maintenance/attribute.php b/maintenance/attribute.php
new file mode 100644
index 000000000000..3326180c0a2c
--- /dev/null
+++ b/maintenance/attribute.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Script for re-attributing edits
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( "commandLine.inc" );
+
+# Parameters
+if ( count( $args ) < 2 ) {
+ print "Not enough parameters\n";
+ if ( $wgWikiFarm ) {
+ print "Usage: php attribute.php <language> <site> <source> <destination>\n";
+ } else {
+ print "Usage: php attribute.php <source> <destination>\n";
+ }
+ exit;
+}
+
+$source = $args[0];
+$dest = $args[1];
+
+$dbr =& wfGetDB( DB_SLAVE );
+extract( $dbr->tableNames( 'page', 'revision','user' ));
+$eSource = $dbr->strencode( $source );
+$eDest = $dbr->strencode( $dest );
+
+# Get user id
+$res = $dbr->query( "SELECT user_id FROM $user WHERE user_name='$eDest'" );
+$row = $dbr->fetchObject( $res );
+if ( !$row ) {
+ print "Warning: the target name \"$dest\" does not exist";
+ $uid = 0;
+} else {
+ $uid = $row->user_id;
+}
+
+# Initialise files
+$logfile = fopen( "attribute.log", "a" );
+$sqlfile = fopen( "attribute.sql", "a" );
+
+fwrite( $logfile, "* $source &rarr; $dest\n" );
+
+fwrite( $sqlfile,
+"-- Changing attribution SQL file
+-- Generated with attribute.php
+-- $source -> $dest ($uid)
+");
+
+$omitTitle = "Wikipedia:Changing_attribution_for_an_edit";
+
+# Get revisions
+print "\nPage revisions\n\n";
+
+$res = $dbr->query( "SELECT page_namespace, page_title, rev_id, rev_timestamp
+FROM $revision,$page
+WHERE rev_user_text='$eSource' and rev_page=page_id" );
+$row = $dbr->fetchObject( $res );
+
+if ( $row ) {
+/*
+ if ( $row->old_title=='Votes_for_deletion' && $row->old_namespace == 4 ) {
+ # We don't have that long
+ break;
+ }
+*/
+ fwrite( $logfile, "**Revision IDs: " );
+ fwrite( $sqlfile, "UPDATE $revision SET rev_user=$uid, rev_user_text='$eDest' WHERE rev_id IN (\n" );
+
+ for ( $first=true; $row; $row = $dbr->fetchObject( $res ) ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $fullTitle = $title->getPrefixedDbKey();
+ if ( $fullTitle == $omitTitle ) {
+ continue;
+ }
+
+ print "$fullTitle\n";
+ $url = $title->getFullUrl( "oldid={$row->rev_id}" );
+
+ # Output
+ fwrite( $sqlfile, " " );
+ if ( $first ) {
+ $first = false;
+ } else {
+ fwrite( $sqlfile, ", " );
+ fwrite( $logfile, ", " );
+ }
+
+ fwrite( $sqlfile, "{$row->rev_id} -- $url\n" );
+ fwrite( $logfile, "[$url {$row->rev_id}]" );
+
+ }
+ fwrite( $sqlfile, ");\n" );
+ fwrite( $logfile, "\n" );
+}
+
+print "\n";
+
+fclose( $sqlfile );
+fclose( $logfile );
+
+?>
diff --git a/maintenance/backup.inc b/maintenance/backup.inc
new file mode 100644
index 000000000000..1a8ff4febbf5
--- /dev/null
+++ b/maintenance/backup.inc
@@ -0,0 +1,292 @@
+<?php
+/**
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+class DumpDBZip2Output extends DumpPipeOutput {
+ function DumpDBZip2Output( $file ) {
+ parent::DumpPipeOutput( "dbzip2", $file );
+ }
+}
+
+class BackupDumper {
+ var $reportingInterval = 100;
+ var $reporting = true;
+ var $pageCount = 0;
+ var $revCount = 0;
+ var $server = null; // use default
+ var $pages = null; // all pages
+ var $skipHeader = false; // don't output <mediawiki> and <siteinfo>
+ var $skipFooter = false; // don't output </mediawiki>
+ var $startId = 0;
+ var $endId = 0;
+ var $sink = null; // Output filters
+ var $stubText = false; // include rev_text_id instead of text; for 2-pass dump
+
+ function BackupDumper( $args ) {
+ $this->stderr = fopen( "php://stderr", "wt" );
+
+ // Built-in output and filter plugins
+ $this->registerOutput( 'file', 'DumpFileOutput' );
+ $this->registerOutput( 'gzip', 'DumpGZipOutput' );
+ $this->registerOutput( 'bzip2', 'DumpBZip2Output' );
+ $this->registerOutput( 'dbzip2', 'DumpDBZip2Output' );
+ $this->registerOutput( '7zip', 'Dump7ZipOutput' );
+
+ $this->registerFilter( 'latest', 'DumpLatestFilter' );
+ $this->registerFilter( 'notalk', 'DumpNotalkFilter' );
+ $this->registerFilter( 'namespace', 'DumpNamespaceFilter' );
+
+ $this->sink = $this->processArgs( $args );
+ }
+
+ /**
+ * @param string $name
+ * @param string $class name of output filter plugin class
+ */
+ function registerOutput( $name, $class ) {
+ $this->outputTypes[$name] = $class;
+ }
+
+ /**
+ * @param string $name
+ * @param string $class name of filter plugin class
+ */
+ function registerFilter( $name, $class ) {
+ $this->filterTypes[$name] = $class;
+ }
+
+ /**
+ * Load a plugin and register it
+ * @param string $class Name of plugin class; must have a static 'register'
+ * method that takes a BackupDumper as a parameter.
+ * @param string $file Full or relative path to the PHP file to load, or empty
+ */
+ function loadPlugin( $class, $file ) {
+ if( $file != '' ) {
+ require_once( $file );
+ }
+ $register = array( $class, 'register' );
+ call_user_func_array( $register, array( &$this ) );
+ }
+
+ /**
+ * @param array $args
+ * @return array
+ * @static
+ */
+ function processArgs( $args ) {
+ $sink = null;
+ $sinks = array();
+ foreach( $args as $arg ) {
+ if( preg_match( '/^--(.+?)(?:=(.+?)(?::(.+?))?)?$/', $arg, $matches ) ) {
+ @list( $full, $opt, $val, $param ) = $matches;
+ switch( $opt ) {
+ case "plugin":
+ $this->loadPlugin( $val, $param );
+ break;
+ case "output":
+ if( !is_null( $sink ) ) {
+ $sinks[] = $sink;
+ }
+ if( !isset( $this->outputTypes[$val] ) ) {
+ wfDie( "Unrecognized output sink type '$val'\n" );
+ }
+ $type = $this->outputTypes[$val];
+ $sink = new $type( $param );
+ break;
+ case "filter":
+ if( is_null( $sink ) ) {
+ $this->progress( "Warning: assuming stdout for filter output\n" );
+ $sink = new DumpOutput();
+ }
+ if( !isset( $this->filterTypes[$val] ) ) {
+ wfDie( "Unrecognized filter type '$val'\n" );
+ }
+ $type = $this->filterTypes[$val];
+ $filter = new $type( $sink, $param );
+
+ // references are lame in php...
+ unset( $sink );
+ $sink = $filter;
+
+ break;
+ case "report":
+ $this->reportingInterval = intval( $val );
+ break;
+ case "server":
+ $this->server = $val;
+ break;
+ case "force-normal":
+ if( !function_exists( 'utf8_normalize' ) ) {
+ dl( "php_utfnormal.so" );
+ if( !function_exists( 'utf8_normalize' ) ) {
+ wfDie( "Failed to load UTF-8 normalization extension. " .
+ "Install or remove --force-normal parameter to use slower code.\n" );
+ }
+ }
+ break;
+ default:
+ $this->processOption( $opt, $val, $param );
+ }
+ }
+ }
+
+ if( is_null( $sink ) ) {
+ $sink = new DumpOutput();
+ }
+ $sinks[] = $sink;
+
+ if( count( $sinks ) > 1 ) {
+ return new DumpMultiWriter( $sinks );
+ } else {
+ return $sink;
+ }
+ }
+
+ function processOption( $opt, $val, $param ) {
+ // extension point for subclasses to add options
+ }
+
+ function dump( $history, $text = MW_EXPORT_TEXT ) {
+ # Notice messages will foul up your XML output even if they're
+ # relatively harmless.
+ ini_set( 'display_errors', false );
+
+ $this->initProgress( $history );
+
+ $db =& $this->backupDb();
+ $exporter = new WikiExporter( $db, $history, WikiExporter::STREAM, $text );
+
+ $wrapper = new ExportProgressFilter( $this->sink, $this );
+ $exporter->setOutputSink( $wrapper );
+
+ if( !$this->skipHeader )
+ $exporter->openStream();
+
+ if( is_null( $this->pages ) ) {
+ if( $this->startId || $this->endId ) {
+ $exporter->pagesByRange( $this->startId, $this->endId );
+ } else {
+ $exporter->allPages();
+ }
+ } else {
+ $exporter->pagesByName( $this->pages );
+ }
+
+ if( !$this->skipFooter )
+ $exporter->closeStream();
+
+ $this->report( true );
+ }
+
+ /**
+ * Initialise starting time and maximum revision count.
+ * We'll make ETA calculations based an progress, assuming relatively
+ * constant per-revision rate.
+ * @param int $history WikiExporter::CURRENT or WikiExporter::FULL
+ */
+ function initProgress( $history = WikiExporter::FULL ) {
+ $table = ($history == WikiExporter::CURRENT) ? 'page' : 'revision';
+ $field = ($history == WikiExporter::CURRENT) ? 'page_id' : 'rev_id';
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $this->maxCount = $dbr->selectField( $table, "MAX($field)", '', 'BackupDumper::dump' );
+ $this->startTime = wfTime();
+ }
+
+ function &backupDb() {
+ global $wgDBadminuser, $wgDBadminpassword;
+ global $wgDBname, $wgDebugDumpSql;
+ $flags = ($wgDebugDumpSql ? DBO_DEBUG : 0) | DBO_DEFAULT; // god-damn hack
+ $db = new Database( $this->backupServer(), $wgDBadminuser, $wgDBadminpassword, $wgDBname, false, $flags );
+ $timeout = 3600 * 24;
+ $db->query( "SET net_read_timeout=$timeout" );
+ $db->query( "SET net_write_timeout=$timeout" );
+ return $db;
+ }
+
+ function backupServer() {
+ global $wgDBserver;
+ return $this->server
+ ? $this->server
+ : $wgDBserver;
+ }
+
+ function reportPage() {
+ $this->pageCount++;
+ }
+
+ function revCount() {
+ $this->revCount++;
+ $this->report();
+ }
+
+ function report( $final = false ) {
+ if( $final xor ( $this->revCount % $this->reportingInterval == 0 ) ) {
+ $this->showReport();
+ }
+ }
+
+ function showReport() {
+ if( $this->reporting ) {
+ $delta = wfTime() - $this->startTime;
+ $now = wfTimestamp( TS_DB );
+ if( $delta ) {
+ $rate = $this->pageCount / $delta;
+ $revrate = $this->revCount / $delta;
+ $portion = $this->revCount / $this->maxCount;
+ $eta = $this->startTime + $delta / $portion;
+ $etats = wfTimestamp( TS_DB, intval( $eta ) );
+ } else {
+ $rate = '-';
+ $revrate = '-';
+ $etats = '-';
+ }
+ $this->progress( sprintf( "%s: %s %d pages (%0.3f/sec), %d revs (%0.3f/sec), ETA %s [max %d]",
+ $now, wfWikiID(), $this->pageCount, $rate, $this->revCount, $revrate, $etats, $this->maxCount ) );
+ }
+ }
+
+ function progress( $string ) {
+ fwrite( $this->stderr, $string . "\n" );
+ }
+}
+
+class ExportProgressFilter extends DumpFilter {
+ function ExportProgressFilter( &$sink, &$progress ) {
+ parent::DumpFilter( $sink );
+ $this->progress = $progress;
+ }
+
+ function writeClosePage( $string ) {
+ parent::writeClosePage( $string );
+ $this->progress->reportPage();
+ }
+
+ function writeRevision( $rev, $string ) {
+ parent::writeRevision( $rev, $string );
+ $this->progress->revCount();
+ }
+}
+
+?>
diff --git a/maintenance/backupPrefetch.inc b/maintenance/backupPrefetch.inc
new file mode 100644
index 000000000000..413247d75ed0
--- /dev/null
+++ b/maintenance/backupPrefetch.inc
@@ -0,0 +1,203 @@
+<?php
+
+// Some smart guy removed XMLReader's global constants from PHP 5.1
+// and replaced them with class constants. Breaking source compatibility
+// is SUPER awesome, and I love languages which do this constantly!
+$xmlReaderConstants = array(
+ "NONE",
+ "ELEMENT",
+ "ATTRIBUTE",
+ "TEXT",
+ "CDATA",
+ "ENTITY_REF",
+ "ENTITY",
+ "PI",
+ "COMMENT",
+ "DOC",
+ "DOC_TYPE",
+ "DOC_FRAGMENT",
+ "NOTATION",
+ "WHITESPACE",
+ "SIGNIFICANT_WHITESPACE",
+ "END_ELEMENT",
+ "END_ENTITY",
+ "XML_DECLARATION",
+ "LOADDTD",
+ "DEFAULTATTRS",
+ "VALIDATE",
+ "SUBST_ENTITIES" );
+foreach( $xmlReaderConstants as $name ) {
+ $fullName = "XMLREADER_$name";
+ $newName = "XMLReader::$name";
+ if( !defined( $fullName ) ) {
+ if( defined( $newName ) ) {
+ define( $fullName, constant( $newName ) );
+ } else {
+ // broken or missing the extension...
+ }
+ }
+}
+
+/**
+ * Readahead helper for making large MediaWiki data dumps;
+ * reads in a previous XML dump to sequentially prefetch text
+ * records already normalized and decompressed.
+ *
+ * This can save load on the external database servers, hopefully.
+ *
+ * Assumes that dumps will be recorded in the canonical order:
+ * - ascending by page_id
+ * - ascending by rev_id within each page
+ * - text contents are immutable and should not change once
+ * recorded, so the previous dump is a reliable source
+ *
+ * Requires PHP 5 and the XMLReader PECL extension.
+ */
+class BaseDump {
+ var $reader = null;
+ var $atEnd = false;
+ var $atPageEnd = false;
+ var $lastPage = 0;
+ var $lastRev = 0;
+
+ function BaseDump( $infile ) {
+ $this->reader = new XMLReader();
+ $this->reader->open( $infile );
+ }
+
+ /**
+ * Attempts to fetch the text of a particular page revision
+ * from the dump stream. May return null if the page is
+ * unavailable.
+ *
+ * @param int $page ID number of page to read
+ * @param int $rev ID number of revision to read
+ * @return string or null
+ */
+ function prefetch( $page, $rev ) {
+ $page = intval( $page );
+ $rev = intval( $rev );
+ while( $this->lastPage < $page && !$this->atEnd ) {
+ $this->debug( "BaseDump::prefetch at page $this->lastPage, looking for $page" );
+ $this->nextPage();
+ }
+ if( $this->lastPage > $page || $this->atEnd ) {
+ $this->debug( "BaseDump::prefetch already past page $page looking for rev $rev [$this->lastPage, $this->lastRev]" );
+ return null;
+ }
+ while( $this->lastRev < $rev && !$this->atEnd && !$this->atPageEnd ) {
+ $this->debug( "BaseDump::prefetch at page $this->lastPage, rev $this->lastRev, looking for $page, $rev" );
+ $this->nextRev();
+ }
+ if( $this->lastRev == $rev && !$this->atEnd ) {
+ $this->debug( "BaseDump::prefetch hit on $page, $rev [$this->lastPage, $this->lastRev]" );
+ return $this->nextText();
+ } else {
+ $this->debug( "BaseDump::prefetch already past rev $rev on page $page [$this->lastPage, $this->lastRev]" );
+ return null;
+ }
+ }
+
+ function debug( $str ) {
+ wfDebug( $str . "\n" );
+ //global $dumper;
+ //$dumper->progress( $str );
+ }
+
+ /**
+ * @access private
+ */
+ function nextPage() {
+ if( $this->skipTo( 'page', 'mediawiki' ) ) {
+ if( $this->skipTo( 'id' ) ) {
+ $this->lastPage = intval( $this->nodeContents() );
+ $this->lastRev = 0;
+ $this->atPageEnd = false;
+ }
+ } else {
+ $this->atEnd = true;
+ }
+ }
+
+ /**
+ * @access private
+ */
+ function nextRev() {
+ if( $this->skipTo( 'revision' ) ) {
+ if( $this->skipTo( 'id' ) ) {
+ $this->lastRev = intval( $this->nodeContents() );
+ }
+ } else {
+ $this->atPageEnd = true;
+ }
+ }
+
+ /**
+ * @access private
+ */
+ function nextText() {
+ $this->skipTo( 'text' );
+ return strval( $this->nodeContents() );
+ }
+
+ /**
+ * @access private
+ */
+ function skipTo( $name, $parent='page' ) {
+ if( $this->atEnd ) {
+ return false;
+ }
+ while( $this->reader->read() ) {
+ if( $this->reader->nodeType == XMLREADER_ELEMENT &&
+ $this->reader->name == $name ) {
+ return true;
+ }
+ if( $this->reader->nodeType == XMLREADER_END_ELEMENT &&
+ $this->reader->name == $parent ) {
+ $this->debug( "BaseDump::skipTo found </$parent> searching for <$name>" );
+ return false;
+ }
+ }
+ return $this->close();
+ }
+
+ /**
+ * Shouldn't something like this be built-in to XMLReader?
+ * Fetches text contents of the current element, assuming
+ * no sub-elements or such scary things.
+ * @return string
+ * @access private
+ */
+ function nodeContents() {
+ if( $this->atEnd ) {
+ return null;
+ }
+ if( $this->reader->isEmptyElement ) {
+ return "";
+ }
+ $buffer = "";
+ while( $this->reader->read() ) {
+ switch( $this->reader->nodeType ) {
+ case XMLREADER_TEXT:
+// case XMLREADER_WHITESPACE:
+ case XMLREADER_SIGNIFICANT_WHITESPACE:
+ $buffer .= $this->reader->value;
+ break;
+ case XMLREADER_END_ELEMENT:
+ return $buffer;
+ }
+ }
+ return $this->close();
+ }
+
+ /**
+ * @access private
+ */
+ function close() {
+ $this->reader->close();
+ $this->atEnd = true;
+ return null;
+ }
+}
+
+?>
diff --git a/maintenance/benchmarkPurge.php b/maintenance/benchmarkPurge.php
new file mode 100644
index 000000000000..69127681dca8
--- /dev/null
+++ b/maintenance/benchmarkPurge.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Squid purge benchmark script
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( "commandLine.inc" );
+
+/** @todo document */
+function benchSquid( $urls, $trials = 1 ) {
+ $start = wfTime();
+ for( $i = 0; $i < $trials; $i++) {
+ SquidUpdate::purge( $urls );
+ }
+ $delta = wfTime() - $start;
+ $pertrial = $delta / $trials;
+ $pertitle = $pertrial / count( $urls );
+ return sprintf( "%4d titles in %6.2fms (%6.2fms each)",
+ count( $urls ), $pertrial * 1000.0, $pertitle * 1000.0 );
+}
+
+/** @todo document */
+function randomUrlList( $length ) {
+ $list = array();
+ for( $i = 0; $i < $length; $i++ ) {
+ $list[] = randomUrl();
+ }
+ return $list;
+}
+
+/** @todo document */
+function randomUrl() {
+ global $wgServer, $wgArticlePath;
+ return $wgServer . str_replace( '$1', randomTitle(), $wgArticlePath );
+}
+
+/** @todo document */
+function randomTitle() {
+ $str = '';
+ $length = mt_rand( 1, 20 );
+ for( $i = 0; $i < $length; $i++ ) {
+ $str .= chr( mt_rand( ord('a'), ord('z') ) );
+ }
+ return ucfirst( $str );
+}
+
+if( !$wgUseSquid ) {
+ wfDie( "Squid purge benchmark doesn't do much without squid support on.\n" );
+} else {
+ printf( "There are %d defined squid servers:\n", count( $wgSquidServers ) );
+ #echo implode( "\n", $wgSquidServers ) . "\n";
+ if( isset( $options['count'] ) ) {
+ $lengths = array( intval( $options['count'] ) );
+ } else {
+ $lengths = array( 1, 10, 100 );
+ }
+ foreach( $lengths as $length ) {
+ $urls = randomUrlList( $length );
+ $trial = benchSquid( $urls );
+ print "$trial\n";
+ }
+}
+?> \ No newline at end of file
diff --git a/maintenance/build-intl-wiki.sql b/maintenance/build-intl-wiki.sql
new file mode 100644
index 000000000000..f094c8b788fc
--- /dev/null
+++ b/maintenance/build-intl-wiki.sql
@@ -0,0 +1,31 @@
+-- Experimental: create shared international database
+-- for new interlinking code.
+--
+
+CREATE DATABASE intl;
+
+GRANT DELETE,INSERT,SELECT,UPDATE ON intl.*
+TO wikiuser@'%' IDENTIFIED BY 'userpass';
+GRANT DELETE,INSERT,SELECT,UPDATE ON intl.*
+TO wikiuser@localhost IDENTIFIED BY 'userpass';
+GRANT DELETE,INSERT,SELECT,UPDATE ON intl.*
+TO wikiuser@localhost.localdomain IDENTIFIED BY 'userpass';
+
+USE intl;
+
+CREATE TABLE ilinks (
+ lang_from varchar(5) default NULL,
+ lang_to varchar(5) default NULL,
+ title_from tinyblob,
+ title_to tinyblob,
+ target_exists tinyint(1) default NULL
+) TYPE=MyISAM;
+
+CREATE TABLE recentchanges (
+ user_name tinyblob,
+ user_lang varchar(5) default NULL,
+ date timestamp(14) NOT NULL,
+ message tinyblob
+) TYPE=MyISAM;
+
+
diff --git a/maintenance/changePassword.php b/maintenance/changePassword.php
new file mode 100644
index 000000000000..591a82b3ecef
--- /dev/null
+++ b/maintenance/changePassword.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Change the password of a given user
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+class ChangePassword {
+ var $dbw;
+ var $user, $password;
+
+ function ChangePassword( $user, $password ) {
+ $this->user = User::newFromName( $user );
+ $this->password = $password;
+
+ $this->dbw =& wfGetDB( DB_MASTER );
+ }
+
+ function main() {
+ $fname = 'ChangePassword::main';
+
+ $this->dbw->update( 'user',
+ array(
+ 'user_password' => wfEncryptPassword( $this->user->getID(), $this->password )
+ ),
+ array(
+ 'user_id' => $this->user->getID()
+ ),
+ $fname
+ );
+ }
+}
+
+$optionsWithArgs = array( 'user', 'password' );
+require_once 'commandLine.inc';
+
+if( in_array( '--help', $argv ) )
+ wfDie(
+ "Usage: php changePassword.php [--user=user --password=password | --help]\n" .
+ "\toptions:\n" .
+ "\t\t--help\tshow this message\n" .
+ "\t\t--user\tthe username to operate on\n" .
+ "\t\t--password\tthe password to use\n"
+ );
+
+$cp = new ChangePassword( @$options['user'], @$options['password'] );
+$cp->main();
+?>
diff --git a/maintenance/changeuser.sql b/maintenance/changeuser.sql
new file mode 100644
index 000000000000..ad1c6da6fff7
--- /dev/null
+++ b/maintenance/changeuser.sql
@@ -0,0 +1,12 @@
+set @oldname = 'At18';
+set @newname = 'Alfio';
+
+update low_priority /*$wgDBprefix*/user set user_name=@newname where user_name=@oldname;
+update low_priority /*$wgDBprefix*/user_newtalk set user_ip=@newname where user_ip=@oldname;
+update low_priority /*$wgDBprefix*/cur set cur_user_text=@newname where cur_user_text=@oldname;
+update low_priority /*$wgDBprefix*/old set old_user_text=@newname where old_user_text=@oldname;
+update low_priority /*$wgDBprefix*/archive set ar_user_text=@newname where ar_user_text=@oldname;
+update low_priority /*$wgDBprefix*/ipblocks set ipb_address=@newname where ipb_address=@oldname;
+update low_priority /*$wgDBprefix*/oldimage set oi_user_text=@newname where oi_user_text=@oldname;
+update low_priority /*$wgDBprefix*/recentchanges set rc_user_text=@newname where rc_user_text=@oldname;
+
diff --git a/maintenance/checkUsernames.php b/maintenance/checkUsernames.php
new file mode 100644
index 000000000000..60e52181a416
--- /dev/null
+++ b/maintenance/checkUsernames.php
@@ -0,0 +1,34 @@
+<?php
+error_reporting(E_ALL ^ E_NOTICE);
+require_once 'commandLine.inc';
+
+class checkUsernames {
+ var $stderr, $log;
+
+ function checkUsernames() {
+ $this->stderr = fopen( 'php://stderr', 'wt' );
+ }
+ function main() {
+ $fname = 'checkUsernames::main';
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $res = $dbr->select( 'user',
+ array( 'user_id', 'user_name' ),
+ null,
+ $fname
+ );
+
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ( ! User::isValidUserName( $row->user_name ) ) {
+ $out = sprintf( "%s: %6d: '%s'\n", wfWikiID(), $row->user_id, $row->user_name );
+ fwrite( $this->stderr, $out );
+ wfDebugLog( 'checkUsernames', $out );
+ }
+ }
+ }
+}
+
+$cun = new checkUsernames();
+$cun->main();
+?>
diff --git a/maintenance/cleanupCaps.php b/maintenance/cleanupCaps.php
new file mode 100644
index 000000000000..afcd1b33fcc9
--- /dev/null
+++ b/maintenance/cleanupCaps.php
@@ -0,0 +1,158 @@
+<?php
+/*
+ * Script to clean up broken page links when somebody turns on $wgCapitalLinks.
+ *
+ * Usage: php cleanupCaps.php [--dry-run]
+ * Options:
+ * --dry-run don't actually try moving them
+ *
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @author Brion Vibber <brion at pobox.com>
+ * @package MediaWiki
+ * @subpackage maintenance
+ */
+
+$options = array( 'dry-run' );
+
+require_once( 'commandLine.inc' );
+require_once( 'FiveUpgrade.inc' );
+
+class CapsCleanup extends FiveUpgrade {
+ function CapsCleanup( $dryrun = false, $namespace=0 ) {
+ parent::FiveUpgrade();
+
+ $this->maxLag = 10; # if slaves are lagged more than 10 secs, wait
+ $this->dryrun = $dryrun;
+ $this->namespace = intval( $namespace );
+ }
+
+ function cleanup() {
+ global $wgCapitalLinks;
+ if( $wgCapitalLinks ) {
+ echo "\$wgCapitalLinks is on -- no need for caps links cleanup.\n";
+ return false;
+ }
+
+ $this->runTable( 'page', 'WHERE page_namespace=' . $this->namespace,
+ array( &$this, 'processPage' ) );
+ }
+
+ function init( $count, $table ) {
+ $this->processed = 0;
+ $this->updated = 0;
+ $this->count = $count;
+ $this->startTime = wfTime();
+ $this->table = $table;
+ }
+
+ function progress( $updated ) {
+ $this->updated += $updated;
+ $this->processed++;
+ if( $this->processed % 100 != 0 ) {
+ return;
+ }
+ $portion = $this->processed / $this->count;
+ $updateRate = $this->updated / $this->processed;
+
+ $now = wfTime();
+ $delta = $now - $this->startTime;
+ $estimatedTotalTime = $delta / $portion;
+ $eta = $this->startTime + $estimatedTotalTime;
+
+ printf( "%s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n",
+ wfTimestamp( TS_DB, intval( $now ) ),
+ $portion * 100.0,
+ $this->table,
+ wfTimestamp( TS_DB, intval( $eta ) ),
+ $this->processed,
+ $this->count,
+ $this->processed / $delta,
+ $updateRate * 100.0 );
+ flush();
+ }
+
+ function runTable( $table, $where, $callback ) {
+ $fname = 'CapsCleanup::buildTable';
+
+ $count = $this->dbw->selectField( $table, 'count(*)', '', $fname );
+ $this->init( $count, 'page' );
+ $this->log( "Processing $table..." );
+
+ $tableName = $this->dbr->tableName( $table );
+ $sql = "SELECT * FROM $tableName $where";
+ $result = $this->dbr->query( $sql, $fname );
+
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $updated = call_user_func( $callback, $row );
+ }
+ $this->log( "Finished $table... $this->updated of $this->processed rows updated" );
+ $this->dbr->freeResult( $result );
+ }
+
+ function processPage( $row ) {
+ global $wgContLang;
+
+ $current = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $display = $current->getPrefixedText();
+ $upper = $row->page_title;
+ $lower = $wgContLang->lcfirst( $row->page_title );
+ if( $upper == $lower ) {
+ $this->log( "\"$display\" already lowercase." );
+ return $this->progress( 0 );
+ }
+
+ $target = Title::makeTitle( $row->page_namespace, $lower );
+ $targetDisplay = $target->getPrefixedText();
+ if( $target->exists() ) {
+ $this->log( "\"$display\" skipped; \"$targetDisplay\" already exists" );
+ return $this->progress( 0 );
+ }
+
+ if( $this->dryrun ) {
+ $this->log( "\"$display\" -> \"$targetDisplay\": DRY RUN, NOT MOVED" );
+ $ok = true;
+ } else {
+ $ok = $current->moveTo( $target, false, 'Converting page titles to lowercase' );
+ $this->log( "\"$display\" -> \"$targetDisplay\": $ok" );
+ }
+ if( $ok === true ) {
+ $this->progress( 1 );
+
+ if( $row->page_namespace == $this->namespace ) {
+ $talk = $target->getTalkPage();
+ $xrow = $row;
+ $row->page_namespace = $talk->getNamespace();
+ if( $talk->exists() ) {
+ return $this->processPage( $row );
+ }
+ }
+ } else {
+ $this->progress( 0 );
+ }
+ }
+
+}
+
+$wgUser->setName( 'Conversion script' );
+$ns = isset( $options['namespace'] ) ? $options['namespace'] : 0;
+$caps = new CapsCleanup( isset( $options['dry-run'] ), $ns );
+$caps->cleanup();
+
+?>
diff --git a/maintenance/cleanupDupes.inc b/maintenance/cleanupDupes.inc
new file mode 100644
index 000000000000..5db6bb39413e
--- /dev/null
+++ b/maintenance/cleanupDupes.inc
@@ -0,0 +1,130 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * If on the old non-unique indexes, check the cur table for duplicate
+ * entries and remove them...
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+function fixDupes( $fixthem = false) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $cur = $dbw->tableName( 'cur' );
+ $old = $dbw->tableName( 'old' );
+ $dbw->query( "LOCK TABLES $cur WRITE, $old WRITE" );
+ echo "Checking for duplicate cur table entries... (this may take a while on a large wiki)\n";
+ $res = $dbw->query( <<<END
+SELECT cur_namespace,cur_title,count(*) as c,min(cur_id) as id
+ FROM $cur
+ GROUP BY cur_namespace,cur_title
+HAVING c > 1
+END
+ );
+ $n = $dbw->numRows( $res );
+ echo "Found $n titles with duplicate entries.\n";
+ if( $n > 0 ) {
+ if( $fixthem ) {
+ echo "Correcting...\n";
+ } else {
+ echo "Just a demo...\n";
+ }
+ while( $row = $dbw->fetchObject( $res ) ) {
+ $ns = intval( $row->cur_namespace );
+ $title = $dbw->addQuotes( $row->cur_title );
+
+ # Get the first responding ID; that'll be the one we keep.
+ $id = $dbw->selectField( 'cur', 'cur_id', array(
+ 'cur_namespace' => $row->cur_namespace,
+ 'cur_title' => $row->cur_title ) );
+
+ echo "$ns:$row->cur_title (canonical ID $id)\n";
+ if( $id != $row->id ) {
+ echo " ** minimum ID $row->id; ";
+ $timeMin = $dbw->selectField( 'cur', 'cur_timestamp', array(
+ 'cur_id' => $row->id ) );
+ $timeFirst = $dbw->selectField( 'cur', 'cur_timestamp', array(
+ 'cur_id' => $id ) );
+ if( $timeMin == $timeFirst ) {
+ echo "timestamps match at $timeFirst; ok\n";
+ } else {
+ echo "timestamps don't match! min: $timeMin, first: $timeFirst; ";
+ if( $timeMin > $timeFirst ) {
+ $id = $row->id;
+ echo "keeping minimum: $id\n";
+ } else {
+ echo "keeping first: $id\n";
+ }
+ }
+ }
+
+ if( $fixthem ) {
+ $dbw->query( <<<END
+INSERT
+ INTO $old
+ (old_namespace, old_title, old_text,
+ old_comment, old_user, old_user_text,
+ old_timestamp, old_minor_edit, old_flags,
+ inverse_timestamp)
+SELECT cur_namespace, cur_title, cur_text,
+ cur_comment, cur_user, cur_user_text,
+ cur_timestamp, cur_minor_edit, '',
+ inverse_timestamp
+ FROM $cur
+ WHERE cur_namespace=$ns
+ AND cur_title=$title
+ AND cur_id != $id
+END
+ );
+ $dbw->query( <<<END
+DELETE
+ FROM $cur
+ WHERE cur_namespace=$ns
+ AND cur_title=$title
+ AND cur_id != $id
+END
+ );
+ }
+ }
+ }
+ $dbw->query( 'UNLOCK TABLES' );
+ if( $fixthem ) {
+ echo "Done.\n";
+ } else {
+ echo "Run again with --fix option to delete the duplicates.\n";
+ }
+}
+
+function checkDupes( $fixthem = false, $indexonly = false ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ if( $dbw->indexExists( 'cur', 'name_title' ) &&
+ $dbw->indexUnique( 'cur', 'name_title' ) ) {
+ echo wfWikiID().": cur table has the current unique index; no duplicate entries.\n";
+ } elseif( $dbw->indexExists( 'cur', 'name_title_dup_prevention' ) ) {
+ echo wfWikiID().": cur table has a temporary name_title_dup_prevention unique index; no duplicate entries.\n";
+ } else {
+ echo wfWikiID().": cur table has the old non-unique index and may have duplicate entries.\n";
+ if( !$indexonly ) {
+ fixDupes( $fixthem );
+ }
+ }
+}
+
+?>
diff --git a/maintenance/cleanupDupes.php b/maintenance/cleanupDupes.php
new file mode 100644
index 000000000000..3aea2304080e
--- /dev/null
+++ b/maintenance/cleanupDupes.php
@@ -0,0 +1,37 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * If on the old non-unique indexes, check the cur table for duplicate
+ * entries and remove them...
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+$options = array( 'fix', 'index' );
+
+/** */
+require_once( 'commandLine.inc' );
+require_once( 'cleanupDupes.inc' );
+$wgTitle = Title::newFromText( 'Dupe cur entry cleanup script' );
+
+checkDupes( isset( $options['fix'] ), isset( $options['index'] ) );
+
+?>
diff --git a/maintenance/cleanupImages.php b/maintenance/cleanupImages.php
new file mode 100644
index 000000000000..8ae5561a5f10
--- /dev/null
+++ b/maintenance/cleanupImages.php
@@ -0,0 +1,168 @@
+<?php
+/*
+ * Script to clean up broken, unparseable upload filenames.
+ *
+ * Usage: php cleanupImages.php [--fix]
+ * Options:
+ * --fix Actually clean up titles; otherwise just checks for them
+ *
+ * Copyright (C) 2005-2006 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @author Brion Vibber <brion at pobox.com>
+ * @package MediaWiki
+ * @subpackage maintenance
+ */
+
+require_once( 'commandLine.inc' );
+require_once( 'cleanupTable.inc' );
+
+class ImageCleanup extends TableCleanup {
+ function __construct( $dryrun = false ) {
+ parent::__construct( 'image', $dryrun );
+ }
+
+ function processPage( $row ) {
+ global $wgContLang;
+
+ $source = $row->img_name;
+ if( $source == '' ) {
+ // Ye olde empty rows. Just kill them.
+ $this->killRow( $source );
+ return $this->progress( 1 );
+ }
+
+ $cleaned = $source;
+
+ // About half of old bad image names have percent-codes
+ $cleaned = rawurldecode( $cleaned );
+
+ // Some are old latin-1
+ $cleaned = $wgContLang->checkTitleEncoding( $cleaned );
+
+ // Many of remainder look like non-normalized unicode
+ $cleaned = UtfNormal::cleanUp( $cleaned );
+
+ $title = Title::makeTitleSafe( NS_IMAGE, $cleaned );
+
+ if( is_null( $title ) ) {
+ $this->log( "page $source ($cleaned) is illegal." );
+ $safe = $this->buildSafeTitle( $cleaned );
+ $this->pokeFile( $source, $safe );
+ return $this->progress( 1 );
+ }
+
+ if( $title->getDbKey() !== $source ) {
+ $munged = $title->getDbKey();
+ $this->log( "page $source ($munged) doesn't match self." );
+ $this->pokeFile( $source, $munged );
+ return $this->progress( 1 );
+ }
+
+ $this->progress( 0 );
+ }
+
+ function killRow( $name ) {
+ if( $this->dryrun ) {
+ $this->log( "DRY RUN: would delete bogus row '$name'" );
+ } else {
+ $this->log( "deleting bogus row '$name'" );
+ $db = wfGetDB( DB_MASTER );
+ $db->delete( 'image',
+ array( 'img_name' => $name ),
+ __METHOD__ );
+ }
+ }
+
+ function filePath( $name ) {
+ return wfImageDir( $name ) . "/$name";
+ }
+
+ function pokeFile( $orig, $new ) {
+ $path = $this->filePath( $orig );
+ if( !file_exists( $path ) ) {
+ $this->log( "missing file: $path" );
+ return $this->killRow( $orig );
+ }
+
+ $db = wfGetDB( DB_MASTER );
+ $version = 0;
+ $final = $new;
+
+ while( $db->selectField( 'image', 'img_name',
+ array( 'img_name' => $final ), __METHOD__ ) ) {
+ $this->log( "Rename conflicts with '$final'..." );
+ $version++;
+ $final = $this->appendTitle( $new, "_$version" );
+ }
+
+ $finalPath = $this->filePath( $final );
+
+ if( $this->dryrun ) {
+ $this->log( "DRY RUN: would rename $path to $finalPath" );
+ } else {
+ $this->log( "renaming $path to $finalPath" );
+ $db->begin();
+ $db->update( 'image',
+ array( 'img_name' => $final ),
+ array( 'img_name' => $orig ),
+ __METHOD__ );
+ $dir = dirname( $finalPath );
+ if( !file_exists( $dir ) ) {
+ if( !mkdir( $dir, 0777, true ) ) {
+ $this->log( "RENAME FAILED, COULD NOT CREATE $dir" );
+ $db->rollback();
+ return;
+ }
+ }
+ if( rename( $path, $finalPath ) ) {
+ $db->commit();
+ } else {
+ $this->log( "RENAME FAILED" );
+ $db->rollback();
+ }
+ }
+ }
+
+ function appendTitle( $name, $suffix ) {
+ return preg_replace( '/^(.*)(\..*?)$/',
+ "\\1$suffix\\2", $name );
+ }
+
+ function buildSafeTitle( $name ) {
+ global $wgLegalTitleChars;
+ $x = preg_replace_callback(
+ "/([^$wgLegalTitleChars])/",
+ array( $this, 'hexChar' ),
+ $name );
+
+ $test = Title::makeTitleSafe( NS_IMAGE, $x );
+ if( is_null( $test ) || $test->getDbKey() !== $x ) {
+ $this->log( "Unable to generate safe title from '$name', got '$x'" );
+ return false;
+ }
+
+ return $x;
+ }
+}
+
+$wgUser->setName( 'Conversion script' );
+$caps = new ImageCleanup( !isset( $options['fix'] ) );
+$caps->cleanup();
+
+?>
diff --git a/maintenance/cleanupSpam.php b/maintenance/cleanupSpam.php
new file mode 100644
index 000000000000..65d6bc4d34be
--- /dev/null
+++ b/maintenance/cleanupSpam.php
@@ -0,0 +1,112 @@
+<?php
+
+require_once( 'commandLine.inc' );
+require_once( "$IP/includes/LinkFilter.php" );
+
+function cleanupArticle( $id, $domain ) {
+ $title = Title::newFromID( $id );
+ if ( !$title ) {
+ print "Internal error: no page for ID $id\n";
+ return;
+ }
+
+ print $title->getPrefixedDBkey() . " ...";
+ $rev = Revision::newFromTitle( $title );
+ $reverted = false;
+ $revId = $rev->getId();
+ $currentRevId = $revId;
+ $regex = LinkFilter::makeRegex( $domain );
+
+ while ( $rev && preg_match( $regex, $rev->getText() ) ) {
+ # Revision::getPrevious can't be used in this way before MW 1.6 (Revision.php 1.26)
+ #$rev = $rev->getPrevious();
+ $revId = $title->getPreviousRevisionID( $revId );
+ if ( $revId ) {
+ $rev = Revision::newFromTitle( $title, $revId );
+ } else {
+ $rev = false;
+ }
+ }
+ if ( $revId == $currentRevId ) {
+ // The regex didn't match the current article text
+ // This happens e.g. when a link comes from a template rather than the page itself
+ print "False match\n";
+ } else {
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->immediateBegin();
+ if ( !$rev ) {
+ // Didn't find a non-spammy revision, blank the page
+ print "blanking\n";
+ $article = new Article( $title );
+ $article->updateArticle( '', wfMsg( 'spam_blanking', $domain ),
+ false, false );
+
+ } else {
+ // Revert to this revision
+ print "reverting\n";
+ $article = new Article( $title );
+ $article->updateArticle( $rev->getText(), wfMsg( 'spam_reverting', $domain ), false, false );
+ }
+ $dbw->immediateCommit();
+ wfDoUpdates();
+ }
+}
+//------------------------------------------------------------------------------
+
+
+
+
+$username = wfMsg( 'spambot_username' );
+$fname = $username;
+$wgUser = User::newFromName( $username );
+// Create the user if necessary
+if ( !$wgUser->getID() ) {
+ $wgUser->addToDatabase();
+}
+
+if ( !isset( $args[0] ) ) {
+ print "Usage: php cleanupSpam.php <hostname>\n";
+ exit(1);
+}
+$spec = $args[0];
+$like = LinkFilter::makeLike( $spec );
+if ( !$like ) {
+ print "Not a valid hostname specification: $spec\n";
+ exit(1);
+}
+
+$dbr =& wfGetDB( DB_SLAVE );
+
+if ( $options['all'] ) {
+ // Clean up spam on all wikis
+ $dbr =& wfGetDB( DB_SLAVE );
+ print "Finding spam on " . count($wgLocalDatabases) . " wikis\n";
+ $found = false;
+ foreach ( $wgLocalDatabases as $db ) {
+ $count = $dbr->selectField( "`$db`.externallinks", 'COUNT(*)',
+ array( 'el_index LIKE ' . $dbr->addQuotes( $like ) ), $fname );
+ if ( $count ) {
+ $found = true;
+ passthru( "php cleanupSpam.php $db $spec | sed s/^/$db: /" );
+ }
+ }
+ if ( $found ) {
+ print "All done\n";
+ } else {
+ print "None found\n";
+ }
+} else {
+ // Clean up spam on this wiki
+ $res = $dbr->select( 'externallinks', array( 'DISTINCT el_from' ),
+ array( 'el_index LIKE ' . $dbr->addQuotes( $like ) ), $fname );
+ $count = $dbr->numRows( $res );
+ print "Found $count articles containing $spec\n";
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ cleanupArticle( $row->el_from, $spec );
+ }
+ if ( $count ) {
+ print "Done\n";
+ }
+}
+
+?>
diff --git a/maintenance/cleanupTable.inc b/maintenance/cleanupTable.inc
new file mode 100644
index 000000000000..cc551bce9c18
--- /dev/null
+++ b/maintenance/cleanupTable.inc
@@ -0,0 +1,86 @@
+<?php
+
+require_once( 'FiveUpgrade.inc' );
+
+abstract class TableCleanup extends FiveUpgrade {
+ function __construct( $table, $dryrun = false ) {
+ parent::__construct();
+
+ $this->targetTable = $table;
+ $this->maxLag = 10; # if slaves are lagged more than 10 secs, wait
+ $this->dryrun = $dryrun;
+ }
+
+ function cleanup() {
+ if( $this->dryrun ) {
+ echo "Checking for bad titles...\n";
+ } else {
+ echo "Checking and fixing bad titles...\n";
+ }
+ $this->runTable( $this->targetTable,
+ '', //'WHERE page_namespace=0',
+ array( $this, 'processPage' ) );
+ }
+
+ function init( $count, $table ) {
+ $this->processed = 0;
+ $this->updated = 0;
+ $this->count = $count;
+ $this->startTime = wfTime();
+ $this->table = $table;
+ }
+
+ function progress( $updated ) {
+ $this->updated += $updated;
+ $this->processed++;
+ if( $this->processed % 100 != 0 ) {
+ return;
+ }
+ $portion = $this->processed / $this->count;
+ $updateRate = $this->updated / $this->processed;
+
+ $now = wfTime();
+ $delta = $now - $this->startTime;
+ $estimatedTotalTime = $delta / $portion;
+ $eta = $this->startTime + $estimatedTotalTime;
+
+ printf( "%s %s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n",
+ wfWikiID(),
+ wfTimestamp( TS_DB, intval( $now ) ),
+ $portion * 100.0,
+ $this->table,
+ wfTimestamp( TS_DB, intval( $eta ) ),
+ $this->processed,
+ $this->count,
+ $this->processed / $delta,
+ $updateRate * 100.0 );
+ flush();
+ }
+
+ function runTable( $table, $where, $callback ) {
+ $fname = 'CapsCleanup::buildTable';
+
+ $count = $this->dbw->selectField( $table, 'count(*)', '', $fname );
+ $this->init( $count, $table );
+ $this->log( "Processing $table..." );
+
+ $tableName = $this->dbr->tableName( $table );
+ $sql = "SELECT * FROM $tableName $where";
+ $result = $this->dbr->query( $sql, $fname );
+
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $updated = call_user_func( $callback, $row );
+ }
+ $this->log( "Finished $table... $this->updated of $this->processed rows updated" );
+ $this->dbr->freeResult( $result );
+ }
+
+ function hexChar( $matches ) {
+ return sprintf( "\\x%02x", ord( $matches[1] ) );
+ }
+
+ abstract function processPage( $row );
+
+}
+
+?>
diff --git a/maintenance/cleanupTitles.php b/maintenance/cleanupTitles.php
new file mode 100644
index 000000000000..12e07b67ad88
--- /dev/null
+++ b/maintenance/cleanupTitles.php
@@ -0,0 +1,141 @@
+<?php
+/*
+ * Script to clean up broken, unparseable titles.
+ *
+ * Usage: php cleanupTitles.php [--fix]
+ * Options:
+ * --fix Actually clean up titles; otherwise just checks for them
+ *
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @author Brion Vibber <brion at pobox.com>
+ * @package MediaWiki
+ * @subpackage maintenance
+ */
+
+require_once( 'commandLine.inc' );
+require_once( 'cleanupTable.inc' );
+
+class TitleCleanup extends TableCleanup {
+ function __construct( $dryrun = false ) {
+ parent::__construct( 'page', $dryrun );
+ }
+
+ function processPage( $row ) {
+ global $wgContLang;
+
+ $current = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $display = $current->getPrefixedText();
+
+ $verified = UtfNormal::cleanUp( $display );
+
+ $title = Title::newFromText( $verified );
+
+ if( is_null( $title ) ) {
+ $this->log( "page $row->page_id ($display) is illegal." );
+ $this->moveIllegalPage( $row );
+ return $this->progress( 1 );
+ }
+
+ if( !$title->equals( $current ) ) {
+ $this->log( "page $row->page_id ($display) doesn't match self." );
+ $this->moveInconsistentPage( $row, $title );
+ return $this->progress( 1 );
+ }
+
+ $this->progress( 0 );
+ }
+
+ function moveIllegalPage( $row ) {
+ $legal = 'A-Za-z0-9_/\\\\-';
+ $legalized = preg_replace_callback( "!([^$legal])!",
+ array( &$this, 'hexChar' ),
+ $row->page_title );
+ if( $legalized == '.' ) $legalized = '(dot)';
+ if( $legalized == '_' ) $legalized = '(space)';
+ $legalized = 'Broken/' . $legalized;
+
+ $title = Title::newFromText( $legalized );
+ if( is_null( $title ) ) {
+ $clean = 'Broken/id:' . $row->page_id;
+ $this->log( "Couldn't legalize; form '$legalized' still invalid; using '$clean'" );
+ $title = Title::newFromText( $clean );
+ } elseif( $title->exists() ) {
+ $clean = 'Broken/id:' . $row->page_id;
+ $this->log( "Legalized for '$legalized' exists; using '$clean'" );
+ $title = Title::newFromText( $clean );
+ }
+
+ $dest = $title->getDbKey();
+ if( $this->dryrun ) {
+ $this->log( "DRY RUN: would rename $row->page_id ($row->page_namespace,'$row->page_title') to ($row->page_namespace,'$dest')" );
+ } else {
+ $this->log( "renaming $row->page_id ($row->page_namespace,'$row->page_title') to ($row->page_namespace,'$dest')" );
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'page',
+ array( 'page_title' => $dest ),
+ array( 'page_id' => $row->page_id ),
+ 'cleanupTitles::moveInconsistentPage' );
+ }
+ }
+
+ function moveInconsistentPage( $row, $title ) {
+ if( $title->exists() || $title->getInterwiki() ) {
+ if( $title->getInterwiki() ) {
+ $prior = $title->getPrefixedDbKey();
+ } else {
+ $prior = $title->getDbKey();
+ }
+ $clean = 'Broken/' . $prior;
+ $verified = Title::makeTitleSafe( $row->page_namespace, $clean );
+ if( $verified->exists() ) {
+ $blah = "Broken/id:" . $row->page_id;
+ $this->log( "Couldn't legalize; form '$clean' exists; using '$blah'" );
+ $verified = Title::makeTitleSafe( $row->page_namespace, $blah );
+ }
+ $title = $verified;
+ }
+ if( is_null( $title ) ) {
+ wfDie( "Something awry; empty title.\n" );
+ }
+ $ns = $title->getNamespace();
+ $dest = $title->getDbKey();
+ if( $this->dryrun ) {
+ $this->log( "DRY RUN: would rename $row->page_id ($row->page_namespace,'$row->page_title') to ($row->page_namespace,'$dest')" );
+ } else {
+ $this->log( "renaming $row->page_id ($row->page_namespace,'$row->page_title') to ($ns,'$dest')" );
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'page',
+ array(
+ 'page_namespace' => $ns,
+ 'page_title' => $dest
+ ),
+ array( 'page_id' => $row->page_id ),
+ 'cleanupTitles::moveInconsistentPage' );
+ $linkCache =& LinkCache::singleton();
+ $linkCache->clear();
+ }
+ }
+}
+
+$wgUser->setName( 'Conversion script' );
+$caps = new TitleCleanup( !isset( $options['fix'] ) );
+$caps->cleanup();
+
+?>
diff --git a/maintenance/cleanupWatchlist.php b/maintenance/cleanupWatchlist.php
new file mode 100644
index 000000000000..027859a435b2
--- /dev/null
+++ b/maintenance/cleanupWatchlist.php
@@ -0,0 +1,140 @@
+<?php
+/*
+ * Script to remove broken, unparseable titles in the Watchlist.
+ *
+ * Usage: php cleanupWatchlist.php [--fix]
+ * Options:
+ * --fix Actually remove entries; without will only report.
+ *
+ * Copyright (C) 2005,2006 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @author Brion Vibber <brion at pobox.com>
+ * @package MediaWiki
+ * @subpackage maintenance
+ */
+
+$options = array( 'fix' );
+
+require_once( 'commandLine.inc' );
+require_once( 'FiveUpgrade.inc' );
+
+class WatchlistCleanup extends FiveUpgrade {
+ function WatchlistCleanup( $dryrun = false ) {
+ parent::FiveUpgrade();
+
+ $this->maxLag = 10; # if slaves are lagged more than 10 secs, wait
+ $this->dryrun = $dryrun;
+ }
+
+ function cleanup() {
+ $this->runTable( 'watchlist',
+ '',
+ array( &$this, 'processEntry' ) );
+ }
+
+ function init( $count, $table ) {
+ $this->processed = 0;
+ $this->updated = 0;
+ $this->count = $count;
+ $this->startTime = wfTime();
+ $this->table = $table;
+ }
+
+ function progress( $updated ) {
+ $this->updated += $updated;
+ $this->processed++;
+ if( $this->processed % 100 != 0 ) {
+ return;
+ }
+ $portion = $this->processed / $this->count;
+ $updateRate = $this->updated / $this->processed;
+
+ $now = wfTime();
+ $delta = $now - $this->startTime;
+ $estimatedTotalTime = $delta / $portion;
+ $eta = $this->startTime + $estimatedTotalTime;
+
+ printf( "%s %s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n",
+ wfWikiID(),
+ wfTimestamp( TS_DB, intval( $now ) ),
+ $portion * 100.0,
+ $this->table,
+ wfTimestamp( TS_DB, intval( $eta ) ),
+ $this->processed,
+ $this->count,
+ $this->processed / $delta,
+ $updateRate * 100.0 );
+ flush();
+ }
+
+ function runTable( $table, $where, $callback ) {
+ $fname = 'WatchlistCleanup::runTable';
+
+ $count = $this->dbw->selectField( $table, 'count(*)', '', $fname );
+ $this->init( $count, 'watchlist' );
+ $this->log( "Processing $table..." );
+
+ $tableName = $this->dbr->tableName( $table );
+ $sql = "SELECT * FROM $tableName $where";
+ $result = $this->dbr->query( $sql, $fname );
+
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $updated = call_user_func( $callback, $row );
+ }
+ $this->log( "Finished $table... $this->updated of $this->processed rows updated" );
+ $this->dbr->freeResult( $result );
+ }
+
+ function processEntry( $row ) {
+ global $wgContLang;
+
+ $current = Title::makeTitle( $row->wl_namespace, $row->wl_title );
+ $display = $current->getPrefixedText();
+
+ $verified = UtfNormal::cleanUp( $display );
+
+ $title = Title::newFromText( $verified );
+
+ if( $row->wl_user == 0 || is_null( $title ) || !$title->equals( $current ) ) {
+ $this->log( "invalid watch by {$row->wl_user} for ({$row->wl_namespace}, \"{$row->wl_title}\")" );
+ $this->removeWatch( $row );
+ return $this->progress( 1 );
+ }
+
+ $this->progress( 0 );
+ }
+
+ function removeWatch( $row ) {
+ if( !$this->dryrun) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'watchlist', array(
+ 'wl_user' => $row->wl_user,
+ 'wl_namespace' => $row->wl_namespace,
+ 'wl_title' => $row->wl_title ),
+ 'WatchlistCleanup::removeWatch' );
+ $this->log( '- removed' );
+ }
+ }
+}
+
+$wgUser->setName( 'Conversion script' );
+$caps = new WatchlistCleanup( !isset( $options['fix'] ) );
+$caps->cleanup();
+
+?>
diff --git a/maintenance/clear_interwiki_cache.php b/maintenance/clear_interwiki_cache.php
new file mode 100644
index 000000000000..97869728de34
--- /dev/null
+++ b/maintenance/clear_interwiki_cache.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * This script is used to clear the interwiki links for ALL languages in
+ * memcached.
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once('commandLine.inc');
+
+$dbr =& wfGetDB( DB_SLAVE );
+$res = $dbr->select( 'interwiki', array( 'iw_prefix' ), false );
+$prefixes = array();
+while ( $row = $dbr->fetchObject( $res ) ) {
+ $prefixes[] = $row->iw_prefix;
+}
+
+foreach ( $wgLocalDatabases as $db ) {
+ print "$db ";
+ foreach ( $prefixes as $prefix ) {
+ $wgMemc->delete("$db:interwiki:$prefix");
+ }
+}
+print "\n";
+?>
diff --git a/maintenance/clear_stats.php b/maintenance/clear_stats.php
new file mode 100644
index 000000000000..00cfd0ce2b47
--- /dev/null
+++ b/maintenance/clear_stats.php
@@ -0,0 +1,31 @@
+<?php
+require_once('commandLine.inc');
+
+foreach ( $wgLocalDatabases as $db ) {
+ noisyDelete("$db:stats:request_with_session");
+ noisyDelete("$db:stats:request_without_session");
+ noisyDelete("$db:stats:pcache_hit");
+ noisyDelete("$db:stats:pcache_miss_invalid");
+ noisyDelete("$db:stats:pcache_miss_expired");
+ noisyDelete("$db:stats:pcache_miss_absent");
+ noisyDelete("$db:stats:pcache_miss_stub");
+ noisyDelete("$db:stats:image_cache_hit");
+ noisyDelete("$db:stats:image_cache_miss");
+ noisyDelete("$db:stats:image_cache_update");
+ noisyDelete("$db:stats:diff_cache_hit");
+ noisyDelete("$db:stats:diff_cache_miss");
+ noisyDelete("$db:stats:diff_uncacheable");
+}
+
+function noisyDelete( $key ) {
+ global $wgMemc;
+ /*
+ print "$key ";
+ if ( $wgMemc->delete($key) ) {
+ print "deleted\n";
+ } else {
+ print "FAILED\n";
+ }*/
+ $wgMemc->delete($key);
+}
+?>
diff --git a/maintenance/commandLine.inc b/maintenance/commandLine.inc
new file mode 100644
index 000000000000..18a1d71298e2
--- /dev/null
+++ b/maintenance/commandLine.inc
@@ -0,0 +1,245 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+$wgRequestTime = microtime(true);
+
+/** */
+# Abort if called from a web server
+if ( isset( $_SERVER ) && array_key_exists( 'REQUEST_METHOD', $_SERVER ) ) {
+ print "This script must be run from the command line\n";
+ exit();
+}
+
+if( version_compare( PHP_VERSION, '5.0.0' ) < 0 ) {
+ print "Sorry! This version of MediaWiki requires PHP 5; you are running " .
+ PHP_VERSION . ".\n\n" .
+ "If you are sure you already have PHP 5 installed, it may be " .
+ "installed\n" .
+ "in a different path from PHP 4. Check with your system administrator.\n";
+ die( -1 );
+}
+
+define('MEDIAWIKI',true);
+
+# Process command line arguments
+# $options becomes an array with keys set to the option names
+# $optionsWithArgs is an array of GNU-style options that take an argument. The arguments are returned
+# in the values of $options.
+# $args becomes a zero-based array containing the non-option arguments
+
+if ( !isset( $optionsWithArgs ) ) {
+ $optionsWithArgs = array();
+}
+$optionsWithArgs[] = 'conf'; # For specifying the location of LocalSettings.php
+
+$self = array_shift( $argv );
+$IP = realpath( dirname( __FILE__ ) . '/..' );
+#chdir( $IP );
+require_once( "$IP/StartProfiler.php" );
+
+$options = array();
+$args = array();
+
+
+# Parse arguments
+for( $arg = reset( $argv ); $arg !== false; $arg = next( $argv ) ) {
+ if ( $arg == '--' ) {
+ # End of options, remainder should be considered arguments
+ $arg = next( $argv );
+ while( $arg !== false ) {
+ $args[] = $arg;
+ $arg = next( $argv );
+ }
+ break;
+ } elseif ( substr( $arg, 0, 2 ) == '--' ) {
+ # Long options
+ $option = substr( $arg, 2 );
+ if ( in_array( $option, $optionsWithArgs ) ) {
+ $param = next( $argv );
+ if ( $param === false ) {
+ echo "$arg needs an value after it\n";
+ die( -1 );
+ }
+ $options[$option] = $param;
+ } else {
+ $bits = explode( '=', $option, 2 );
+ if( count( $bits ) > 1 ) {
+ $option = $bits[0];
+ $param = $bits[1];
+ } else {
+ $param = 1;
+ }
+ $options[$option] = $param;
+ }
+ } elseif ( substr( $arg, 0, 1 ) == '-' ) {
+ # Short options
+ for ( $p=1; $p<strlen( $arg ); $p++ ) {
+ $option = $arg{$p};
+ if ( in_array( $option, $optionsWithArgs ) ) {
+ $param = next( $argv );
+ if ( $param === false ) {
+ echo "$arg needs an value after it\n";
+ die( -1 );
+ }
+ $options[$option] = $param;
+ } else {
+ $options[$option] = 1;
+ }
+ }
+ } else {
+ $args[] = $arg;
+ }
+}
+
+
+# General initialisation
+
+$wgCommandLineMode = true;
+# Turn off output buffering if it's on
+@ob_end_flush();
+$sep = PATH_SEPARATOR;
+
+if (!isset( $wgUseNormalUser ) ) {
+ $wgUseNormalUser = false;
+}
+
+if ( file_exists( '/home/wikipedia/common/langlist' ) ) {
+ $wgWikiFarm = true;
+ $cluster = trim( file_get_contents( '/etc/cluster' ) );
+ require_once( "$IP/includes/SiteConfiguration.php" );
+
+ # Get $wgConf
+ require( "$IP/wgConf.php" );
+
+ if ( empty( $wgNoDBParam ) ) {
+ # Check if we were passed a db name
+ $db = array_shift( $args );
+ list( $site, $lang ) = $wgConf->siteFromDB( $db );
+
+ # If not, work out the language and site the old way
+ if ( is_null( $site ) || is_null( $lang ) ) {
+ if ( !$db ) {
+ $lang = 'aa';
+ } else {
+ $lang = $db;
+ }
+ if ( isset( $args[0] ) ) {
+ $site = array_shift( $args );
+ } else {
+ $site = 'wikipedia';
+ }
+ }
+ } else {
+ $lang = 'aa';
+ $site = 'wikipedia';
+ }
+
+ # This is for the IRC scripts, which now run as the apache user
+ # The apache user doesn't have access to the wikiadmin_pass command
+ if ( $_ENV['USER'] == 'apache' ) {
+ #if ( posix_geteuid() == 48 ) {
+ $wgUseNormalUser = true;
+ }
+
+ putenv( 'wikilang='.$lang);
+
+ $DP = $IP;
+ ini_set( 'include_path', ".:$IP:$IP/includes:$IP/languages:$IP/maintenance" );
+
+ #require_once( $IP.'/includes/ProfilerStub.php' );
+ require_once( $IP.'/includes/Defines.php' );
+ require_once( $IP.'/CommonSettings.php' );
+
+ $bin = '/home/wikipedia/bin';
+ if ( $wgUseRootUser ) {
+ $wgDBuser = $wgDBadminuser = 'root';
+ $wgDBpassword = $wgDBadminpassword = trim(`$bin/mysql_root_pass`);
+ } elseif ( !$wgUseNormalUser ) {
+ $wgDBuser = $wgDBadminuser = 'wikiadmin';
+ $wgDBpassword = $wgDBadminpassword = trim(`$bin/wikiadmin_pass`);
+ }
+} else {
+ $wgWikiFarm = false;
+ if ( isset( $options['conf'] ) ) {
+ $settingsFile = $options['conf'];
+ } else {
+ $settingsFile = "$IP/LocalSettings.php";
+ }
+
+ if ( ! is_readable( $settingsFile ) ) {
+ print "A copy of your installation's LocalSettings.php\n" .
+ "must exist in the source directory.\n";
+ exit( 1 );
+ }
+ $wgCommandLineMode = true;
+ $DP = $IP;
+ #require_once( $IP.'/includes/ProfilerStub.php' );
+ require_once( $IP.'/includes/Defines.php' );
+ require_once( $settingsFile );
+ ini_set( 'include_path', ".$sep$IP$sep$IP/includes$sep$IP/languages$sep$IP/maintenance" );
+
+ if ( is_readable( $IP.'/AdminSettings.php' ) ) {
+ require_once( $IP.'/AdminSettings.php' );
+ }
+}
+
+# Turn off output buffering again, it might have been turned on in the settings files
+if( ob_get_level() ) {
+ ob_end_flush();
+}
+# Same with these
+$wgCommandLineMode = true;
+
+if ( empty( $wgUseNormalUser ) && isset( $wgDBadminuser ) ) {
+ $wgDBuser = $wgDBadminuser;
+ $wgDBpassword = $wgDBadminpassword;
+
+ if( $wgDBservers ) {
+ foreach ( $wgDBservers as $i => $server ) {
+ $wgDBservers[$i]['user'] = $wgDBuser;
+ $wgDBservers[$i]['password'] = $wgDBpassword;
+ }
+ }
+}
+
+if ( defined( 'MW_CMDLINE_CALLBACK' ) ) {
+ $fn = MW_CMDLINE_CALLBACK;
+ $fn();
+}
+
+ini_set( 'memory_limit', -1 );
+
+$wgShowSQLErrors = true;
+
+require_once( 'Setup.php' );
+require_once( 'install-utils.inc' );
+$wgTitle = null; # Much much faster startup than creating a title object
+set_time_limit(0);
+
+// --------------------------------------------------------------------
+// Functions
+// --------------------------------------------------------------------
+
+function wfWaitForSlaves( $maxLag ) {
+ global $wgLoadBalancer;
+ if ( $maxLag ) {
+ list( $host, $lag ) = $wgLoadBalancer->getMaxLag();
+ while ( $lag > $maxLag ) {
+ $name = @gethostbyaddr( $host );
+ if ( $name !== false ) {
+ $host = $name;
+ }
+ print "Waiting for $host (lagged $lag seconds)...\n";
+ sleep($maxLag);
+ list( $host, $lag ) = $wgLoadBalancer->getMaxLag();
+ }
+ }
+}
+
+
+
+?>
diff --git a/maintenance/convertLinks.inc b/maintenance/convertLinks.inc
new file mode 100644
index 000000000000..5f8c27a542cd
--- /dev/null
+++ b/maintenance/convertLinks.inc
@@ -0,0 +1,220 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+function convertLinks() {
+ global $wgDBtype;
+ if( $wgDBtype == 'postgres' ) {
+ print "Links table already ok on Postgres.\n";
+ return;
+ }
+
+ print "Converting links table to ID-ID...\n";
+
+ global $wgLang, $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname;
+ global $noKeys, $logPerformance, $fh;
+
+ $numRows = $tuplesAdded = $numBadLinks = $curRowsRead = 0; #counters etc
+ $totalTuplesInserted = 0; # total tuples INSERTed into links_temp
+
+ $reportCurReadProgress = true; #whether or not to give progress reports while reading IDs from cur table
+ $curReadReportInterval = 1000; #number of rows between progress reports
+
+ $reportLinksConvProgress = true; #whether or not to give progress reports during conversion
+ $linksConvInsertInterval = 1000; #number of rows per INSERT
+
+ $initialRowOffset = 0;
+ #$finalRowOffset = 0; # not used yet; highest row number from links table to process
+
+ # Overwrite the old links table with the new one. If this is set to false,
+ # the new table will be left at links_temp.
+ $overwriteLinksTable = true;
+
+ # Don't create keys, and so allow duplicates in the new links table.
+ # This gives a huge speed improvement for very large links tables which are MyISAM. (What about InnoDB?)
+ $noKeys = false;
+
+
+ $logPerformance = false; # output performance data to a file
+ $perfLogFilename = "convLinksPerf.txt";
+ #--------------------------------------------------------------------
+
+ $dbw =& wfGetDB( DB_MASTER );
+ extract( $dbw->tableNames( 'cur', 'links', 'links_temp', 'links_backup' ) );
+
+ $res = $dbw->query( "SELECT l_from FROM $links LIMIT 1" );
+ if ( $dbw->fieldType( $res, 0 ) == "int" ) {
+ print "Schema already converted\n";
+ return;
+ }
+
+ $res = $dbw->query( "SELECT COUNT(*) AS count FROM $links" );
+ $row = $dbw->fetchObject($res);
+ $numRows = $row->count;
+ $dbw->freeResult( $res );
+
+ if ( $numRows == 0 ) {
+ print "Updating schema (no rows to convert)...\n";
+ createTempTable();
+ } else {
+ if ( $logPerformance ) { $fh = fopen ( $perfLogFilename, "w" ); }
+ $baseTime = $startTime = getMicroTime();
+ # Create a title -> cur_id map
+ print "Loading IDs from $cur table...\n";
+ performanceLog ( "Reading $numRows rows from cur table...\n" );
+ performanceLog ( "rows read vs seconds elapsed:\n" );
+
+ $dbw->bufferResults( false );
+ $res = $dbw->query( "SELECT cur_namespace,cur_title,cur_id FROM $cur" );
+ $ids = array();
+
+ while ( $row = $dbw->fetchObject( $res ) ) {
+ $title = $row->cur_title;
+ if ( $row->cur_namespace ) {
+ $title = $wgLang->getNsText( $row->cur_namespace ) . ":$title";
+ }
+ $ids[$title] = $row->cur_id;
+ $curRowsRead++;
+ if ($reportCurReadProgress) {
+ if (($curRowsRead % $curReadReportInterval) == 0) {
+ performanceLog( $curRowsRead . " " . (getMicroTime() - $baseTime) . "\n" );
+ print "\t$curRowsRead rows of $cur table read.\n";
+ }
+ }
+ }
+ $dbw->freeResult( $res );
+ $dbw->bufferResults( true );
+ print "Finished loading IDs.\n\n";
+ performanceLog( "Took " . (getMicroTime() - $baseTime) . " seconds to load IDs.\n\n" );
+ #--------------------------------------------------------------------
+
+ # Now, step through the links table (in chunks of $linksConvInsertInterval rows),
+ # convert, and write to the new table.
+ createTempTable();
+ performanceLog( "Resetting timer.\n\n" );
+ $baseTime = getMicroTime();
+ print "Processing $numRows rows from $links table...\n";
+ performanceLog( "Processing $numRows rows from $links table...\n" );
+ performanceLog( "rows inserted vs seconds elapsed:\n" );
+
+ for ($rowOffset = $initialRowOffset; $rowOffset < $numRows; $rowOffset += $linksConvInsertInterval) {
+ $sqlRead = "SELECT * FROM $links ";
+ $sqlRead = $dbw->limitResult($sqlRead, $linksConvInsertInterval,$rowOffset);
+ $res = $dbw->query($sqlRead);
+ if ( $noKeys ) {
+ $sqlWrite = array("INSERT INTO $links_temp (l_from,l_to) VALUES ");
+ } else {
+ $sqlWrite = array("INSERT IGNORE INTO $links_temp (l_from,l_to) VALUES ");
+ }
+
+ $tuplesAdded = 0; # no tuples added to INSERT yet
+ while ( $row = $dbw->fetchObject($res) ) {
+ $fromTitle = $row->l_from;
+ if ( array_key_exists( $fromTitle, $ids ) ) { # valid title
+ $from = $ids[$fromTitle];
+ $to = $row->l_to;
+ if ( $tuplesAdded != 0 ) {
+ $sqlWrite[] = ",";
+ }
+ $sqlWrite[] = "($from,$to)";
+ $tuplesAdded++;
+ } else { # invalid title
+ $numBadLinks++;
+ }
+ }
+ $dbw->freeResult($res);
+ #print "rowOffset: $rowOffset\ttuplesAdded: $tuplesAdded\tnumBadLinks: $numBadLinks\n";
+ if ( $tuplesAdded != 0 ) {
+ if ($reportLinksConvProgress) {
+ print "Inserting $tuplesAdded tuples into $links_temp...";
+ }
+ $dbw->query( implode("",$sqlWrite) );
+ $totalTuplesInserted += $tuplesAdded;
+ if ($reportLinksConvProgress)
+ print " done. Total $totalTuplesInserted tuples inserted.\n";
+ performanceLog( $totalTuplesInserted . " " . (getMicroTime() - $baseTime) . "\n" );
+ }
+ }
+ print "$totalTuplesInserted valid titles and $numBadLinks invalid titles were processed.\n\n";
+ performanceLog( "$totalTuplesInserted valid titles and $numBadLinks invalid titles were processed.\n" );
+ performanceLog( "Total execution time: " . (getMicroTime() - $startTime) . " seconds.\n" );
+ if ( $logPerformance ) { fclose ( $fh ); }
+ }
+ #--------------------------------------------------------------------
+
+ if ( $overwriteLinksTable ) {
+ $dbConn = Database::newFromParams( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname );
+ if (!($dbConn->isOpen())) {
+ print "Opening connection to database failed.\n";
+ return;
+ }
+ # Check for existing links_backup, and delete it if it exists.
+ print "Dropping backup links table if it exists...";
+ $dbConn->query( "DROP TABLE IF EXISTS $links_backup", DB_MASTER);
+ print " done.\n";
+
+ # Swap in the new table, and move old links table to links_backup
+ print "Swapping tables '$links' to '$links_backup'; '$links_temp' to '$links'...";
+ $dbConn->query( "RENAME TABLE links TO $links_backup, $links_temp TO $links", DB_MASTER );
+ print " done.\n\n";
+
+ $dbConn->close();
+ print "Conversion complete. The old table remains at $links_backup;\n";
+ print "delete at your leisure.\n";
+ } else {
+ print "Conversion complete. The converted table is at $links_temp;\n";
+ print "the original links table is unchanged.\n";
+ }
+}
+
+#--------------------------------------------------------------------
+
+function createTempTable() {
+ global $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname;
+ global $noKeys;
+ $dbConn = Database::newFromParams( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname );
+
+ if (!($dbConn->isOpen())) {
+ print "Opening connection to database failed.\n";
+ return;
+ }
+ $links_temp = $dbConn->tableName( 'links_temp' );
+
+ print "Dropping temporary links table if it exists...";
+ $dbConn->query( "DROP TABLE IF EXISTS $links_temp");
+ print " done.\n";
+
+ print "Creating temporary links table...";
+ if ( $noKeys ) {
+ $dbConn->query( "CREATE TABLE $links_temp ( " .
+ "l_from int(8) unsigned NOT NULL default '0', " .
+ "l_to int(8) unsigned NOT NULL default '0')");
+ } else {
+ $dbConn->query( "CREATE TABLE $links_temp ( " .
+ "l_from int(8) unsigned NOT NULL default '0', " .
+ "l_to int(8) unsigned NOT NULL default '0', " .
+ "UNIQUE KEY l_from(l_from,l_to), " .
+ "KEY (l_to))");
+ }
+ print " done.\n\n";
+}
+
+function performanceLog( $text ) {
+ global $logPerformance, $fh;
+ if ( $logPerformance ) {
+ fwrite( $fh, $text );
+ }
+}
+
+function getMicroTime() { # return time in seconds, with microsecond accuracy
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec + (float)$sec);
+}
+
+
+
+?>
diff --git a/maintenance/convertLinks.php b/maintenance/convertLinks.php
new file mode 100644
index 000000000000..5939b943b0a8
--- /dev/null
+++ b/maintenance/convertLinks.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Convert from the old links schema (string->ID) to the new schema (ID->ID)
+ * The wiki should be put into read-only mode while this script executes
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( "commandLine.inc" );
+require_once( "convertLinks.inc" );
+
+convertLinks();
+
+?>
diff --git a/maintenance/counter.php b/maintenance/counter.php
new file mode 100644
index 000000000000..d84c877d8c8d
--- /dev/null
+++ b/maintenance/counter.php
@@ -0,0 +1,5 @@
+<?php
+function print_c($last, $current) {
+ echo str_repeat( chr(8), strlen( $last ) ) . $current;
+}
+?>
diff --git a/maintenance/createAndPromote.php b/maintenance/createAndPromote.php
new file mode 100644
index 000000000000..43ddcdd1cd9c
--- /dev/null
+++ b/maintenance/createAndPromote.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * Maintenance script to create an account and grant it administrator rights
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+require_once( 'commandLine.inc' );
+
+if( !count( $args ) == 2 ) {
+ echo( "Please provide a username and password for the new account.\n" );
+ die( 1 );
+}
+
+$username = $args[0];
+$password = $args[1];
+
+echo( wfWikiID() . ": Creating and promoting User:{$username}..." );
+
+# Validate username and check it doesn't exist
+$user = User::newFromName( $username );
+if( !is_object( $user ) ) {
+ echo( "invalid username.\n" );
+ die( 1 );
+} elseif( 0 != $user->idForName() ) {
+ echo( "account exists.\n" );
+ die( 1 );
+}
+
+# Insert the account into the database
+$user->addToDatabase();
+$user->setPassword( $password );
+$user->setToken();
+
+# Promote user
+$user->addGroup( 'sysop' );
+
+# Increment site_stats.ss_users
+$ssu = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
+$ssu->doUpdate();
+
+echo( "done.\n" );
+
+?>
diff --git a/maintenance/database.sql b/maintenance/database.sql
new file mode 100644
index 000000000000..dea9954248f2
--- /dev/null
+++ b/maintenance/database.sql
@@ -0,0 +1,7 @@
+-- SQL script to create database for wiki. This is run from
+-- the installation script which replaces the variables with
+-- their values from local settings.
+--
+
+DROP DATABASE IF EXISTS `{$wgDBname}`;
+CREATE DATABASE `{$wgDBname}`;
diff --git a/maintenance/delete-idle-wiki-users.pl b/maintenance/delete-idle-wiki-users.pl
new file mode 100644
index 000000000000..aef68ccd7e64
--- /dev/null
+++ b/maintenance/delete-idle-wiki-users.pl
@@ -0,0 +1,138 @@
+#!/usr/bin/perl
+#
+# Nuke idle wiki accounts from the wiki's user database.
+#
+# Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# 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.,
+# 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+my $database = "DBI:mysql:database=wikidb;host=localhost";
+my $dbuser = "wikiuser";
+my $dbpasswd = "password";
+
+use strict;
+use DBI();
+
+my $verbose = 0;
+my $for_real = 1;
+
+sub do_db_op
+{
+ my ($dbh, $sql) = @_;
+
+ if ($verbose >= 3) {
+ print $sql . ";\n"
+ }
+
+ if ($for_real == 1) {
+ $dbh->do($sql);
+ }
+}
+
+sub undo_user
+{
+ my ($ref, $dbh, $sth, $killed);
+
+ # Connect to the database.
+ $dbh = DBI->connect($database, $dbuser, $dbpasswd, {RaiseError => 1});
+
+ $sth = $dbh->prepare("SELECT * FROM user");
+ $sth->execute();
+
+ $ref = $sth->fetchrow_hashref();
+
+ if ($sth->rows == 0) {
+ print "There is no user in this wiki.\n";
+ return;
+ }
+
+ while ($ref = $sth->fetchrow_hashref()) {
+ my ($user_id, $user_name, $cph, $oph, $edits);
+
+ $user_name = $ref->{user_name};
+ $user_id = $ref->{user_id};
+ if ($verbose >= 2) {
+ print "Annihilating user " . $user_name .
+ " has user_id " . $user_id . ".\n";
+ }
+
+ $cph = $dbh->prepare("SELECT * FROM cur where " .
+ "cur_user = $user_id" .
+ " AND " .
+ "cur_user_text = " . $dbh->quote("$user_name"));
+ $cph->execute();
+
+ $oph = $dbh->prepare("SELECT * FROM old where " .
+ "old_user = $user_id" .
+ " AND " .
+ "old_user_text = " . $dbh->quote("$user_name"));
+ $oph->execute();
+
+ $edits = $cph->rows + $oph->rows;
+
+ $cph->finish();
+ $oph->finish();
+
+ if ($edits == 0) {
+ if ($verbose >= 2) {
+ print "Keeping user " . $user_name .
+ ", user_id " . $user_id . ".\n";
+ }
+
+ do_db_op($dbh,
+ "DELETE FROM user WHERE user_name = " .
+ $dbh->quote("$user_name") .
+ " AND " .
+ "user_id = $user_id");
+
+ $killed++;
+ }
+ }
+
+ $sth->finish();
+
+ $dbh->disconnect();
+
+ if ($verbose >= 1) {
+ print "Killed " . $killed . " users\n";
+ }
+}
+
+my (@users, $user, $this, $opts);
+
+@users = ();
+$opts = 1;
+
+foreach $this (@ARGV) {
+ if ($opts == 1 && $this eq '-v') {
+ $verbose++;
+ } elsif ($opts == 1 && $this eq '--verbose') {
+ $verbose = 1;
+ } elsif ($opts == 1 && $this eq '--') {
+ $opts = 0;
+ } else {
+ push(@users, $this);
+ }
+}
+
+undo_user();
+
diff --git a/maintenance/deleteBatch.php b/maintenance/deleteBatch.php
new file mode 100644
index 000000000000..14da6d84e3a1
--- /dev/null
+++ b/maintenance/deleteBatch.php
@@ -0,0 +1,88 @@
+<?php
+
+# delete a batch of pages
+# Usage: php deleteBatch.php [-u <user>] [-r <reason>] [-i <interval>] <listfile>
+# where
+# <listfile> is a file where each line contains the title of a page to be deleted.
+# <user> is the username
+# <reason> is the delete reason
+# <interval> is the number of seconds to sleep for after each delete
+
+$oldCwd = getcwd();
+$optionsWithArgs = array( 'u', 'r', 'i' );
+require_once( 'commandLine.inc' );
+
+chdir( $oldCwd );
+
+# Options processing
+
+$filename = 'php://stdin';
+$user = 'Delete page script';
+$reason = '';
+$interval = 0;
+
+if ( isset( $args[0] ) ) {
+ $filename = $args[0];
+}
+if ( isset( $options['u'] ) ) {
+ $user = $options['u'];
+}
+if ( isset( $options['r'] ) ) {
+ $reason = $options['r'];
+}
+if ( isset( $options['i'] ) ) {
+ $interval = $options['i'];
+}
+
+$wgUser = User::newFromName( $user );
+
+
+# Setup complete, now start
+
+$file = fopen( $filename, 'r' );
+if ( !$file ) {
+ print "Unable to read file, exiting\n";
+ exit;
+}
+
+$dbw =& wfGetDB( DB_MASTER );
+
+for ( $linenum = 1; !feof( $file ); $linenum++ ) {
+ $line = trim( fgets( $file ) );
+ if ( $line == '' ) {
+ continue;
+ }
+ $page = Title::newFromText( $line );
+ if ( is_null( $page ) ) {
+ print "Invalid title '$line' on line $linenum\n";
+ continue;
+ }
+ if( !$page->exists() ) {
+ print "Skipping nonexistent page '$line'\n";
+ continue;
+ }
+
+
+ print $page->getPrefixedText();
+ $dbw->begin();
+ if( $page->getNamespace() == NS_IMAGE ) {
+ $art = new ImagePage( $page );
+ } else {
+ $art = new Article( $page );
+ }
+ $success = $art->doDeleteArticle( $reason );
+ $dbw->immediateCommit();
+ if ( $success ) {
+ print "\n";
+ } else {
+ print " FAILED\n";
+ }
+
+ if ( $interval ) {
+ sleep( $interval );
+ }
+ wfWaitForSlaves( 5 );
+}
+
+
+?>
diff --git a/maintenance/deleteDefaultMessages.php b/maintenance/deleteDefaultMessages.php
new file mode 100644
index 000000000000..76924002184a
--- /dev/null
+++ b/maintenance/deleteDefaultMessages.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * Deletes all pages in the MediaWiki namespace which were last edited by
+ * "MediaWiki default".
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ require_once( 'commandLine.inc' );
+ deleteDefaultMessages();
+}
+
+function deleteDefaultMessages() {
+ $user = 'MediaWiki default';
+ $reason = 'No longer required';
+
+ global $wgUser;
+ $wgUser = User::newFromName( $user );
+ $wgUser->addGroup( 'bot' );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( array( 'page', 'revision' ),
+ array( 'page_namespace', 'page_title' ),
+ array(
+ 'page_namespace' => NS_MEDIAWIKI,
+ 'page_latest=rev_id',
+ 'rev_user_text' => 'MediaWiki default',
+ )
+ );
+
+ $dbw =& wfGetDB( DB_MASTER );
+
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ( function_exists( 'wfWaitForSlaves' ) ) {
+ wfWaitForSlaves( 5 );
+ }
+ $dbw->ping();
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $article = new Article( $title );
+ $dbw->begin();
+ $article->doDeleteArticle( $reason );
+ $dbw->commit();
+ }
+}
+?>
diff --git a/maintenance/deleteImageMemcached.php b/maintenance/deleteImageMemcached.php
new file mode 100644
index 000000000000..6af0e3a9fa61
--- /dev/null
+++ b/maintenance/deleteImageMemcached.php
@@ -0,0 +1,60 @@
+<?php
+// php deleteImageMemcached.php --until "2005-09-05 00:00:00" --sleep 0 --report 10
+$optionsWithArgs = array( 'until', 'sleep', 'report' );
+
+require_once 'commandLine.inc';
+
+class DeleteImageCache {
+ var $until, $sleep, $report;
+
+ function DeleteImageCache( $until, $sleep, $report ) {
+ $this->until = $until;
+ $this->sleep = $sleep;
+ $this->report = $report;
+ }
+
+ function main() {
+ global $wgMemc;
+ $fname = 'DeleteImageCache::main';
+
+ ini_set( 'display_errors', false );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $res = $dbr->select( 'image',
+ array( 'img_name' ),
+ array( "img_timestamp < {$this->until}" ),
+ $fname
+ );
+
+ $i = 0;
+ $total = $this->getImageCount();
+
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ($i % $this->report == 0)
+ printf("%s: %13s done (%s)\n", wfWikiID(), "$i/$total", wfPercent( $i / $total * 100 ));
+ $md5 = md5( $row->img_name );
+ $wgMemc->delete( wfMemcKey( 'Image', $md5 ) );
+
+ if ($this->sleep != 0)
+ usleep( $this->sleep );
+
+ ++$i;
+ }
+ }
+
+ function getImageCount() {
+ $fname = 'DeleteImageCache::getImageCount';
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ return $dbr->selectField( 'image', 'COUNT(*)', array(), $fname );
+ }
+}
+
+$until = preg_replace( "/[^\d]/", '', $options['until'] );
+$sleep = (int)$options['sleep'] * 1000; // milliseconds
+$report = (int)$options['report'];
+
+$dic = new DeleteImageCache( $until, $sleep, $report );
+$dic->main();
+?>
diff --git a/maintenance/deleteOldRevisions.inc b/maintenance/deleteOldRevisions.inc
new file mode 100644
index 000000000000..dd48028a9191
--- /dev/null
+++ b/maintenance/deleteOldRevisions.inc
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * Support functions for the deleteOldRevisions script
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+require_once( 'purgeOldText.inc' );
+
+function DeleteOldRevisions( $delete = false ) {
+
+ # Data should come off the master, wrapped in a transaction
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ $tbl_pag = $dbw->tableName( 'page' );
+ $tbl_rev = $dbw->tableName( 'revision' );
+
+ # Get "active" revisions from the page table
+ echo( "Searching for active revisions..." );
+ $res = $dbw->query( "SELECT page_latest FROM $tbl_pag" );
+ while( $row = $dbw->fetchObject( $res ) ) {
+ $cur[] = $row->page_latest;
+ }
+ echo( "done.\n" );
+
+ # Get all revisions that aren't in this set
+ echo( "Searching for inactive revisions..." );
+ $set = implode( ', ', $cur );
+ $res = $dbw->query( "SELECT rev_id FROM $tbl_rev WHERE rev_id NOT IN ( $set )" );
+ while( $row = $dbw->fetchObject( $res ) ) {
+ $old[] = $row->rev_id;
+ }
+ echo( "done.\n" );
+
+ # Inform the user of what we're going to do
+ $count = count( $old );
+ echo( "$count old revisions found.\n" );
+
+ # Delete as appropriate
+ if( $delete && $count ) {
+ echo( "Deleting..." );
+ $set = implode( ', ', $old );
+ $dbw->query( "DELETE FROM $tbl_rev WHERE rev_id IN ( $set )" );
+ echo( "done.\n" );
+ }
+
+ # This bit's done
+ # Purge redundant text records
+ $dbw->commit();
+ if( $delete ) {
+ PurgeRedundantText( true );
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/deleteOldRevisions.php b/maintenance/deleteOldRevisions.php
new file mode 100644
index 000000000000..9695a8c5b7ad
--- /dev/null
+++ b/maintenance/deleteOldRevisions.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * Delete old (non-current) revisions from the database
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+$options = array( 'delete', 'help' );
+require_once( 'commandLine.inc' );
+require_once( 'deleteOldRevisions.inc' );
+
+echo( "Delete Old Revisions\n\n" );
+
+if( @$options['help'] ) {
+ ShowUsage();
+} else {
+ DeleteOldRevisions( @$options['delete'] );
+}
+
+function ShowUsage() {
+ echo( "Deletes non-current revisions from the database.\n\n" );
+ echo( "Usage: php deleteOldRevisions.php [--delete|--help]\n\n" );
+ echo( "delete : Performs the deletion\n" );
+ echo( " help : Show this usage information\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/deleteOrphanedRevisions.inc.php b/maintenance/deleteOrphanedRevisions.inc.php
new file mode 100644
index 000000000000..7cfb1c6bb518
--- /dev/null
+++ b/maintenance/deleteOrphanedRevisions.inc.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Support functions for the deleteOrphanedRevisions maintenance script
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+/**
+ * Delete one or more revisions from the database
+ * Do this inside a transaction
+ *
+ * @param $id Array of revision id values
+ * @param $db Database class (needs to be a master)
+ */
+function deleteRevisions( $id, &$dbw ) {
+ if( !is_array( $id ) )
+ $id = array( $id );
+ $dbw->delete( 'revision', array( 'rev_id' => $id ), 'deleteRevision' );
+}
+
+/**
+ * Spit out script usage information and exit
+ */
+function showUsage() {
+ echo( "Finds revisions which refer to nonexisting pages and deletes them from the database\n" );
+ echo( "USAGE: php deleteOrphanedRevisions.php [--report]\n\n" );
+ echo( " --report : Prints out a count of affected revisions but doesn't delete them\n\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/deleteOrphanedRevisions.php b/maintenance/deleteOrphanedRevisions.php
new file mode 100644
index 000000000000..b4f5b5172efc
--- /dev/null
+++ b/maintenance/deleteOrphanedRevisions.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Maintenance script to delete revisions which refer to a nonexisting page
+ * Sometimes manual deletion done in a rush leaves crap in the database
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ * @todo More efficient cleanup of text records
+ */
+
+$options = array( 'report', 'help' );
+require_once( 'commandLine.inc' );
+require_once( 'deleteOrphanedRevisions.inc.php' );
+echo( "Delete Orphaned Revisions\n" );
+
+if( isset( $options['help'] ) )
+ showUsage();
+
+$report = isset( $options['report'] );
+
+$dbw =& wfGetDB( DB_MASTER );
+$dbw->immediateBegin();
+extract( $dbw->tableNames( 'page', 'revision' ) );
+
+# Find all the orphaned revisions
+echo( "Checking for orphaned revisions..." );
+$sql = "SELECT rev_id FROM {$revision} LEFT JOIN {$page} ON rev_page = page_id WHERE page_namespace IS NULL";
+$res = $dbw->query( $sql, 'deleteOrphanedRevisions' );
+
+# Stash 'em all up for deletion (if needed)
+while( $row = $dbw->fetchObject( $res ) )
+ $revisions[] = $row->rev_id;
+$dbw->freeResult( $res );
+$count = count( $revisions );
+echo( "found {$count}.\n" );
+
+# Nothing to do?
+if( $report || $count == 0 ) {
+ $dbw->immediateCommit();
+ exit();
+}
+
+# Delete each revision
+echo( "Deleting..." );
+deleteRevisions( $revisions, $dbw );
+echo( "done.\n" );
+
+# Close the transaction and call the script to purge unused text records
+$dbw->immediateCommit();
+require_once( 'purgeOldText.inc' );
+PurgeRedundantText( true );
+
+?> \ No newline at end of file
diff --git a/maintenance/deleteRevision.php b/maintenance/deleteRevision.php
new file mode 100644
index 000000000000..eb65e234062b
--- /dev/null
+++ b/maintenance/deleteRevision.php
@@ -0,0 +1,40 @@
+<?php
+require_once( 'commandLine.inc' );
+
+$dbw =& wfGetDB( DB_MASTER );
+
+if ( count( $args ) == 0 ) {
+ echo "Usage: php deleteRevision.php <revid> [<revid> ...]\n";
+ exit(1);
+}
+
+echo "Deleting revision(s) " . implode( ',', $args ) . " from ".wfWikiID()."...\n";
+
+$affected = 0;
+foreach ( $args as $revID ) {
+ $dbw->insertSelect( 'archive', array( 'page', 'revision' ),
+ array(
+ 'ar_namespace' => 'page_namespace',
+ 'ar_title' => 'page_title',
+ 'ar_comment' => 'rev_comment',
+ 'ar_user' => 'rev_user',
+ 'ar_user_text' => 'rev_user_text',
+ 'ar_timestamp' => 'rev_timestamp',
+ 'ar_minor_edit' => 'rev_minor_edit',
+ 'ar_rev_id' => 'rev_id',
+ 'ar_text_id' => 'rev_text_id',
+ ), array(
+ 'rev_id' => $revID,
+ 'page_id = rev_page'
+ ), $fname
+ );
+ if ( !$dbw->affectedRows() ) {
+ echo "Revision $revID not found\n";
+ } else {
+ $affected += $dbw->affectedRows();
+ $dbw->delete( 'revision', array( 'rev_id' => $revID ) );
+ }
+}
+
+print "Deleted $affected revisions\n";
+?>
diff --git a/maintenance/dtrace/counts.d b/maintenance/dtrace/counts.d
new file mode 100644
index 000000000000..bedb45473623
--- /dev/null
+++ b/maintenance/dtrace/counts.d
@@ -0,0 +1,23 @@
+/*
+ * This software is in the public domain.
+ *
+ * $Id$
+ */
+
+#pragma D option quiet
+
+self int tottime;
+BEGIN {
+ tottime = timestamp;
+}
+
+php$target:::function-entry
+ @counts[copyinstr(arg0)] = count();
+}
+
+END {
+ printf("Total time: %dus\n", (timestamp - tottime) / 1000);
+ printf("# calls by function:\n");
+ printa("%-40s %@d\n", @counts);
+}
+
diff --git a/maintenance/dtrace/tree.d b/maintenance/dtrace/tree.d
new file mode 100644
index 000000000000..a799cb12fc39
--- /dev/null
+++ b/maintenance/dtrace/tree.d
@@ -0,0 +1,26 @@
+/*
+ * This software is in the public domain.
+ *
+ * $Id$
+ */
+
+#pragma D option quiet
+
+self int indent;
+self int times[int];
+
+php$target:::function-entry
+{
+ @counts[copyinstr(arg0)] = count();
+ printf("%*s", self->indent, "");
+ printf("-> %s\n", copyinstr(arg0));
+ self->times[self->indent] = timestamp;
+ self->indent += 2;
+}
+
+php$target:::function-return
+{
+ self->indent -= 2;
+ printf("%*s", self->indent, "");
+ printf("<- %s %dus\n", copyinstr(arg0), (timestamp - self->times[self->indent]) / 1000);
+}
diff --git a/maintenance/dumpBackup.php b/maintenance/dumpBackup.php
new file mode 100644
index 000000000000..ef5d47c92dc3
--- /dev/null
+++ b/maintenance/dumpBackup.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+$originalDir = getcwd();
+
+$optionsWithArgs = array( 'pagelist', 'start', 'end' );
+
+require_once( 'commandLine.inc' );
+require_once( 'SpecialExport.php' );
+require_once( 'maintenance/backup.inc' );
+
+$dumper = new BackupDumper( $argv );
+
+if( isset( $options['quiet'] ) ) {
+ $dumper->reporting = false;
+}
+
+if ( isset( $options['pagelist'] ) ) {
+ $olddir = getcwd();
+ chdir( $originalDir );
+ $pages = file( $options['pagelist'] );
+ chdir( $olddir );
+ if ( $pages === false ) {
+ wfDie( "Unable to open file {$options['pagelist']}\n" );
+ }
+ $pages = array_map( 'trim', $pages );
+ $dumper->pages = array_filter( $pages, create_function( '$x', 'return $x !== "";' ) );
+}
+
+if( isset( $options['start'] ) ) {
+ $dumper->startId = intval( $options['start'] );
+}
+if( isset( $options['end'] ) ) {
+ $dumper->endId = intval( $options['end'] );
+}
+$dumper->skipHeader = isset( $options['skip-header'] );
+$dumper->skipFooter = isset( $options['skip-footer'] );
+
+$textMode = isset( $options['stub'] ) ? WikiExporter::STUB : WikiExporter::TEXT;
+
+if( isset( $options['full'] ) ) {
+ $dumper->dump( WikiExporter::FULL, $textMode );
+} elseif( isset( $options['current'] ) ) {
+ $dumper->dump( WikiExporter::CURRENT, $textMode );
+} else {
+ $dumper->progress( <<<END
+This script dumps the wiki page database into an XML interchange wrapper
+format for export or backup.
+
+XML output is sent to stdout; progress reports are sent to stderr.
+
+Usage: php dumpBackup.php <action> [<options>]
+Actions:
+ --full Dump complete history of every page.
+ --current Includes only the latest revision of each page.
+
+Options:
+ --quiet Don't dump status reports to stderr.
+ --report=n Report position and speed after every n pages processed.
+ (Default: 100)
+ --server=h Force reading from MySQL server h
+ --start=n Start from page_id n
+ --end=n Stop before page_id n (exclusive)
+ --skip-header Don't output the <mediawiki> header
+ --skip-footer Don't output the </mediawiki> footer
+ --stub Don't perform old_text lookups; for 2-pass dump
+
+Fancy stuff:
+ --plugin=<class>[:<file>] Load a dump plugin class
+ --output=<type>:<file> Begin a filtered output stream;
+ <type>s: file, gzip, bzip2, 7zip
+ --filter=<type>[:<options>] Add a filter on an output branch
+
+END
+);
+}
+
+?>
diff --git a/maintenance/dumpHTML.inc b/maintenance/dumpHTML.inc
new file mode 100644
index 000000000000..702c7df9011a
--- /dev/null
+++ b/maintenance/dumpHTML.inc
@@ -0,0 +1,1008 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+define( 'REPORTING_INTERVAL', 10 );
+
+require_once( 'includes/ImagePage.php' );
+require_once( 'includes/CategoryPage.php' );
+require_once( 'includes/RawPage.php' );
+
+class DumpHTML {
+ # Destination directory
+ var $dest;
+
+ # Skip existing files
+ var $noOverwrite = false;
+
+ # Show interlanguage links?
+ var $interwiki = true;
+
+ # Depth of HTML directory tree
+ var $depth = 3;
+
+ # Directory that commons images are copied into
+ var $sharedStaticDirectory;
+
+ # Directory that the images are in, after copying
+ var $destUploadDirectory;
+
+ # Relative path to image directory
+ var $imageRel = 'upload';
+
+ # Copy commons images instead of symlinking
+ var $forceCopy = false;
+
+ # Make a copy of all images encountered
+ var $makeSnapshot = false;
+
+ # Don't image description pages in doEverything()
+ var $noSharedDesc = false;
+
+ # Make links assuming the script path is in the same directory as
+ # the destination
+ var $alternateScriptPath = false;
+
+ # Original values of various globals
+ var $oldArticlePath = false, $oldCopyrightIcon = false;
+
+ # Has setupGlobals been called?
+ var $setupDone = false;
+
+ # Has to compress html pages
+ var $compress = false;
+
+ # List of raw pages used in the current article
+ var $rawPages;
+
+ # Skin to use
+ var $skin = 'htmldump';
+
+ # Checkpoint stuff
+ var $checkpointFile = false, $checkpoints = false;
+
+ var $startID = 1, $endID = false;
+
+ var $sliceNumerator = 1, $sliceDenominator = 1;
+
+ # Max page ID, lazy initialised
+ var $maxPageID = false;
+
+ # UDP profiling
+ var $udpProfile, $udpProfileCounter = 0, $udpProfileInit = false;
+
+ function DumpHTML( $settings = array() ) {
+ foreach ( $settings as $var => $value ) {
+ $this->$var = $value;
+ }
+ }
+
+ function loadCheckpoints() {
+ if ( $this->checkpoints !== false ) {
+ return true;
+ } elseif ( !$this->checkpointFile ) {
+ return false;
+ } else {
+ $lines = @file( $this->checkpointFile );
+ if ( $lines === false ) {
+ print "Starting new checkpoint file \"{$this->checkpointFile}\"\n";
+ $this->checkpoints = array();
+ } else {
+ $lines = array_map( 'trim', $lines );
+ $this->checkpoints = array();
+ foreach ( $lines as $line ) {
+ list( $name, $value ) = explode( '=', $line, 2 );
+ $this->checkpoints[$name] = $value;
+ }
+ }
+ return true;
+ }
+ }
+
+ function getCheckpoint( $type, $defValue = false ) {
+ if ( !$this->loadCheckpoints() ) {
+ return false;
+ }
+ if ( !isset( $this->checkpoints[$type] ) ) {
+ return false;
+ } else {
+ return $this->checkpoints[$type];
+ }
+ }
+
+ function setCheckpoint( $type, $value ) {
+ if ( !$this->checkpointFile ) {
+ return;
+ }
+ $this->checkpoints[$type] = $value;
+ $blob = '';
+ foreach ( $this->checkpoints as $type => $value ) {
+ $blob .= "$type=$value\n";
+ }
+ file_put_contents( $this->checkpointFile, $blob );
+ }
+
+ function doEverything() {
+ if ( $this->getCheckpoint( 'everything' ) == 'done' ) {
+ print "Checkpoint says everything is already done\n";
+ return;
+ }
+ $this->doArticles();
+ $this->doCategories();
+ $this->doRedirects();
+ if ( $this->sliceNumerator == 1 ) {
+ $this->doSpecials();
+ }
+ $this->doLocalImageDescriptions();
+
+ if ( !$this->noSharedDesc ) {
+ $this->doSharedImageDescriptions();
+ }
+
+ $this->setCheckpoint( 'everything', 'done' );
+ }
+
+ /**
+ * Write a set of articles specified by start and end page_id
+ * Skip categories and images, they will be done separately
+ */
+ function doArticles() {
+ if ( $this->endID === false ) {
+ $end = $this->getMaxPageID();
+ } else {
+ $end = $this->endID;
+ }
+ $start = $this->startID;
+
+ # Start from the checkpoint
+ $cp = $this->getCheckpoint( 'article' );
+ if ( $cp == 'done' ) {
+ print "Articles already done\n";
+ return;
+ } elseif ( $cp !== false ) {
+ $start = $cp;
+ print "Resuming article dump from checkpoint at page_id $start of $end\n";
+ } else {
+ print "Starting from page_id $start of $end\n";
+ }
+
+ # Move the start point to the correct slice if it isn't there already
+ $start = $this->modSliceStart( $start );
+
+ $this->setupGlobals();
+
+ $mainPageObj = Title::newMainPage();
+ $mainPage = $mainPageObj->getPrefixedDBkey();
+
+ for ( $id = $start, $i = 0; $id <= $end; $id += $this->sliceDenominator, $i++ ) {
+ wfWaitForSlaves( 20 );
+ if ( !( $i % REPORTING_INTERVAL) ) {
+ print "Processing ID: $id\r";
+ $this->setCheckpoint( 'article', $id );
+ }
+ if ( !($i % (REPORTING_INTERVAL*10) ) ) {
+ print "\n";
+ }
+ $title = Title::newFromID( $id );
+ if ( $title ) {
+ $ns = $title->getNamespace() ;
+ if ( $ns != NS_CATEGORY && $ns != NS_MEDIAWIKI &&
+ $title->getPrefixedDBkey() != $mainPage ) {
+ $this->doArticle( $title );
+ }
+ }
+ }
+ $this->setCheckpoint( 'article', 'done' );
+ print "\n";
+ }
+
+ function doSpecials() {
+ $this->doMainPage();
+
+ $this->setupGlobals();
+ print "Special:Categories...";
+ $this->doArticle( SpecialPage::getTitleFor( 'Categories' ) );
+ print "\n";
+ }
+
+ /** Write the main page as index.html */
+ function doMainPage() {
+
+ print "Making index.html ";
+
+ // Set up globals with no ../../.. in the link URLs
+ $this->setupGlobals( 0 );
+
+ $title = Title::newMainPage();
+ $text = $this->getArticleHTML( $title );
+
+ # Parse the XHTML to find the images
+ $images = $this->findImages( $text );
+ $this->copyImages( $images );
+
+ $file = fopen( "{$this->dest}/index.html", "w" );
+ if ( !$file ) {
+ print "\nCan't open index.html for writing\n";
+ return false;
+ }
+ fwrite( $file, $text );
+ fclose( $file );
+ print "\n";
+ }
+
+ function doImageDescriptions() {
+ $this->doLocalImageDescriptions();
+ if ( !$this->noSharedDesc ) {
+ $this->doSharedImageDescriptions();
+ }
+ }
+
+ /**
+ * Dump image description pages that don't have an associated article, but do
+ * have a local image
+ */
+ function doLocalImageDescriptions() {
+ global $wgSharedUploadDirectory;
+ $chunkSize = 1000;
+
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $cp = $this->getCheckpoint( 'local image' );
+ if ( $cp == 'done' ) {
+ print "Local image descriptions already done\n";
+ return;
+ } elseif ( $cp !== false ) {
+ print "Writing image description pages starting from $cp\n";
+ $conds = array( 'img_name >= ' . $dbr->addQuotes( $cp ) );
+ } else {
+ print "Writing image description pages for local images\n";
+ $conds = false;
+ }
+
+ $this->setupGlobals();
+ $i = 0;
+
+ do {
+ $res = $dbr->select( 'image', array( 'img_name' ), $conds, __METHOD__,
+ array( 'ORDER BY' => 'img_name', 'LIMIT' => $chunkSize ) );
+ $numRows = $dbr->numRows( $res );
+
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ # Update conds for the next chunk query
+ $conds = array( 'img_name > ' . $dbr->addQuotes( $row->img_name ) );
+
+ // Slice the result set with a filter
+ if ( !$this->sliceFilter( $row->img_name ) ) {
+ continue;
+ }
+
+ wfWaitForSlaves( 10 );
+ if ( !( ++$i % REPORTING_INTERVAL ) ) {
+ print "{$row->img_name}\n";
+ if ( $row->img_name !== 'done' ) {
+ $this->setCheckpoint( 'local image', $row->img_name );
+ }
+ }
+ $title = Title::makeTitle( NS_IMAGE, $row->img_name );
+ if ( $title->getArticleID() ) {
+ // Already done by dumpHTML
+ continue;
+ }
+ $this->doArticle( $title );
+ }
+ $dbr->freeResult( $res );
+ } while ( $numRows );
+
+ $this->setCheckpoint( 'local image', 'done' );
+ print "\n";
+ }
+
+ /**
+ * Dump images which only have a real description page on commons
+ */
+ function doSharedImageDescriptions() {
+ list( $start, $end ) = $this->sliceRange( 0, 255 );
+
+ $cp = $this->getCheckpoint( 'shared image' );
+ if ( $cp == 'done' ) {
+ print "Shared description pages already done\n";
+ return;
+ } elseif ( $cp !== false ) {
+ print "Writing description pages for commons images starting from directory $cp/255\n";
+ $start = $cp;
+ } else {
+ print "Writing description pages for commons images\n";
+ }
+
+ $this->setupGlobals();
+ $i = 0;
+ for ( $hash = $start; $hash <= $end; $hash++ ) {
+ $this->setCheckpoint( 'shared image', $hash );
+
+ $dir = sprintf( "%s/%01x/%02x", $this->sharedStaticDirectory,
+ intval( $hash / 16 ), $hash );
+ $handle = @opendir( $dir );
+ while ( $handle && $file = readdir( $handle ) ) {
+ if ( $file[0] == '.' ) {
+ continue;
+ }
+ if ( !(++$i % REPORTING_INTERVAL ) ) {
+ print "$i\r";
+ }
+
+ $title = Title::makeTitleSafe( NS_IMAGE, $file );
+ $this->doArticle( $title );
+ }
+ if ( $handle ) {
+ closedir( $handle );
+ }
+ }
+ $this->setCheckpoint( 'shared image', 'done' );
+ print "\n";
+ }
+
+ function doCategories() {
+ $chunkSize = 1000;
+
+ $this->setupGlobals();
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $cp = $this->getCheckpoint( 'category' );
+ if ( $cp == 'done' ) {
+ print "Category pages already done\n";
+ return;
+ } elseif ( $cp !== false ) {
+ print "Resuming category page dump from $cp\n";
+ $conds = array( 'cl_to >= ' . $dbr->addQuotes( $cp ) );
+ } else {
+ print "Starting category pages\n";
+ $conds = false;
+ }
+
+ $i = 0;
+ do {
+ $res = $dbr->select( 'categorylinks', 'DISTINCT cl_to', $conds, __METHOD__,
+ array( 'ORDER BY' => 'cl_to', 'LIMIT' => $chunkSize ) );
+ $numRows = $dbr->numRows( $res );
+
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ // Set conditions for next chunk
+ $conds = array( 'cl_to > ' . $dbr->addQuotes( $row->cl_to ) );
+
+ // Filter pages from other slices
+ if ( !$this->sliceFilter( $row->cl_to ) ) {
+ continue;
+ }
+
+ wfWaitForSlaves( 10 );
+ if ( !(++$i % REPORTING_INTERVAL ) ) {
+ print "{$row->cl_to}\n";
+ if ( $row->cl_to != 'done' ) {
+ $this->setCheckpoint( 'category', $row->cl_to );
+ }
+ }
+ $title = Title::makeTitle( NS_CATEGORY, $row->cl_to );
+ $this->doArticle( $title );
+ }
+ $dbr->freeResult( $res );
+ } while ( $numRows );
+
+ $this->setCheckpoint( 'category', 'done' );
+ print "\n";
+ }
+
+ function doRedirects() {
+ print "Doing redirects...\n";
+
+ $chunkSize = 10000;
+ $end = $this->getMaxPageID();
+ $cp = $this->getCheckpoint( 'redirect' );
+ if ( $cp == 'done' ) {
+ print "Redirects already done\n";
+ return;
+ } elseif ( $cp !== false ) {
+ print "Resuming redirect generation from page_id $cp\n";
+ $start = intval( $cp );
+ } else {
+ $start = 1;
+ }
+
+ $this->setupGlobals();
+ $dbr =& wfGetDB( DB_SLAVE );
+ $i = 0;
+
+ for ( $chunkStart = $start; $chunkStart <= $end; $chunkStart += $chunkSize ) {
+ $chunkEnd = min( $end, $chunkStart + $chunkSize - 1 );
+ $conds = array(
+ 'page_is_redirect' => 1,
+ "page_id BETWEEN $chunkStart AND $chunkEnd"
+ );
+ # Modulo slicing in SQL
+ if ( $this->sliceDenominator != 1 ) {
+ $n = intval( $this->sliceNumerator );
+ $m = intval( $this->sliceDenominator );
+ $conds[] = "page_id % $m = $n";
+ }
+ $res = $dbr->select( 'page', array( 'page_id', 'page_namespace', 'page_title' ),
+ $conds, __METHOD__ );
+
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ if ( !(++$i % (REPORTING_INTERVAL*10) ) ) {
+ printf( "Done %d redirects (%2.3f%%)\n", $i, $row->page_id / $end * 100 );
+ $this->setCheckpoint( 'redirect', $row->page_id );
+ }
+ $this->doArticle( $title );
+ }
+ $dbr->freeResult( $res );
+ }
+ $this->setCheckpoint( 'redirect', 'done' );
+ }
+
+ /** Write an article specified by title */
+ function doArticle( $title ) {
+ global $wgTitle, $wgSharedUploadPath, $wgSharedUploadDirectory;
+ global $wgUploadDirectory;
+
+ if ( $this->noOverwrite ) {
+ $fileName = $this->dest.'/'.$this->getHashedFilename( $title );
+ if ( file_exists( $fileName ) ) {
+ return;
+ }
+ }
+
+ $this->profile();
+
+ $this->rawPages = array();
+ $text = $this->getArticleHTML( $title );
+
+ if ( $text === false ) {
+ return;
+ }
+
+ # Parse the XHTML to find the images
+ $images = $this->findImages( $text );
+ $this->copyImages( $images );
+
+ # Write to file
+ $this->writeArticle( $title, $text );
+
+ # Do raw pages
+ wfMkdirParents( "{$this->dest}/raw", 0755 );
+ foreach( $this->rawPages as $record ) {
+ list( $file, $title, $params ) = $record;
+
+ $path = "{$this->dest}/raw/$file";
+ if ( !file_exists( $path ) ) {
+ $article = new Article( $title );
+ $request = new FauxRequest( $params );
+ $rp = new RawPage( $article, $request );
+ $text = $rp->getRawText();
+
+ print "Writing $file\n";
+ $file = fopen( $path, 'w' );
+ if ( !$file ) {
+ print("Can't open file $fullName for writing\n");
+ continue;
+ }
+ fwrite( $file, $text );
+ fclose( $file );
+ }
+ }
+
+ wfIncrStats( 'dumphtml_article' );
+ }
+
+ /** Write the given text to the file identified by the given title object */
+ function writeArticle( &$title, $text ) {
+ $filename = $this->getHashedFilename( $title );
+
+ # Temporary hack for current dump, this should be moved to
+ # getFriendlyName() at the earliest opportunity.
+ #
+ # Limit filename length to 255 characters, so it works on ext3.
+ # Titles are in fact limited to 255 characters, but dumpHTML
+ # adds a suffix which may put them over the limit.
+ $length = strlen( $filename );
+ if ( $length > 255 ) {
+ print "Warning: Filename too long ($length bytes). Skipping.\n";
+ return;
+ }
+
+ $fullName = "{$this->dest}/$filename";
+ $fullDir = dirname( $fullName );
+
+ if ( $this->compress ) {
+ $fullName .= ".gz";
+ $text = gzencode( $text, 9 );
+ }
+
+ wfMkdirParents( $fullDir, 0755 );
+
+ wfSuppressWarnings();
+ $file = fopen( $fullName, 'w' );
+ wfRestoreWarnings();
+
+ if ( !$file ) {
+ die("Can't open file '$fullName' for writing.\nCheck permissions or use another destination (-d).\n");
+ return;
+ }
+
+ fwrite( $file, $text );
+ fclose( $file );
+ }
+
+ /** Set up globals required for parsing */
+ function setupGlobals( $currentDepth = NULL ) {
+ global $wgUser, $wgTitle, $wgStylePath, $wgArticlePath, $wgMathPath;
+ global $wgUploadPath, $wgLogo, $wgMaxCredits, $wgSharedUploadPath;
+ global $wgHideInterlanguageLinks, $wgUploadDirectory, $wgThumbnailScriptPath;
+ global $wgSharedThumbnailScriptPath, $wgEnableParserCache, $wgHooks, $wgServer;
+ global $wgRightsUrl, $wgRightsText, $wgCopyrightIcon, $wgEnableSidebarCache;
+ global $wgGenerateThumbnailOnParse;
+
+ static $oldLogo = NULL;
+
+ if ( !$this->setupDone ) {
+ $wgHooks['GetLocalURL'][] =& $this;
+ $wgHooks['GetFullURL'][] =& $this;
+ $wgHooks['SiteNoticeBefore'][] =& $this;
+ $wgHooks['SiteNoticeAfter'][] =& $this;
+ $this->oldArticlePath = $wgServer . $wgArticlePath;
+ }
+
+ if ( is_null( $currentDepth ) ) {
+ $currentDepth = $this->depth;
+ }
+
+ if ( $this->alternateScriptPath ) {
+ if ( $currentDepth == 0 ) {
+ $wgScriptPath = '.';
+ } else {
+ $wgScriptPath = '..' . str_repeat( '/..', $currentDepth - 1 );
+ }
+ } else {
+ $wgScriptPath = '..' . str_repeat( '/..', $currentDepth );
+ }
+
+ $wgArticlePath = str_repeat( '../', $currentDepth ) . '$1';
+
+ # Logo image
+ # Allow for repeated setup
+ if ( !is_null( $oldLogo ) ) {
+ $wgLogo = $oldLogo;
+ } else {
+ $oldLogo = $wgLogo;
+ }
+
+ if ( strpos( $wgLogo, $wgUploadPath ) === 0 ) {
+ # If it's in the upload directory, rewrite it to the new upload directory
+ $wgLogo = "$wgScriptPath/{$this->imageRel}/" . substr( $wgLogo, strlen( $wgUploadPath ) + 1 );
+ } elseif ( $wgLogo{0} == '/' ) {
+ # This is basically heuristic
+ # Rewrite an absolute logo path to one relative to the the script path
+ $wgLogo = $wgScriptPath . $wgLogo;
+ }
+
+ # Another ugly hack
+ if ( !$this->setupDone ) {
+ $this->oldCopyrightIcon = $wgCopyrightIcon;
+ }
+ $wgCopyrightIcon = str_replace( 'src="/images',
+ 'src="' . htmlspecialchars( $wgScriptPath ) . '/images', $this->oldCopyrightIcon );
+
+ $wgStylePath = "$wgScriptPath/skins";
+ $wgUploadPath = "$wgScriptPath/{$this->imageRel}";
+ $wgSharedUploadPath = "$wgUploadPath/shared";
+ $wgMaxCredits = -1;
+ $wgHideInterlanguageLinks = !$this->interwiki;
+ $wgThumbnailScriptPath = $wgSharedThumbnailScriptPath = false;
+ $wgEnableParserCache = false;
+ $wgMathPath = "$wgScriptPath/math";
+ $wgEnableSidebarCache = false;
+ $wgGenerateThumbnailOnParse = true;
+
+ if ( !empty( $wgRightsText ) ) {
+ $wgRightsUrl = "$wgScriptPath/COPYING.html";
+ }
+
+ $wgUser = new User;
+ $wgUser->setOption( 'skin', $this->skin );
+ $wgUser->setOption( 'editsection', 0 );
+
+ $this->destUploadDirectory = "{$this->dest}/{$this->imageRel}";
+ if ( realpath( $this->destUploadDirectory ) == realpath( $wgUploadDirectory ) ) {
+ print "Disabling image snapshot because the destination is the same as the source\n";
+ $this->makeSnapshot = false;
+ }
+ $this->sharedStaticDirectory = "{$this->destUploadDirectory}/shared";
+
+ $this->setupDone = true;
+ }
+
+ /** Reads the content of a title object, executes the skin and captures the result */
+ function getArticleHTML( &$title ) {
+ global $wgOut, $wgTitle, $wgArticle, $wgUser;
+
+ $linkCache =& LinkCache::singleton();
+ $linkCache->clear();
+ $wgTitle = $title;
+ if ( is_null( $wgTitle ) ) {
+ return false;
+ }
+
+ $ns = $wgTitle->getNamespace();
+ if ( $ns == NS_SPECIAL ) {
+ $wgOut = new OutputPage;
+ $wgOut->setParserOptions( new ParserOptions );
+ SpecialPage::executePath( $wgTitle );
+ } else {
+ /** @todo merge with Wiki.php code */
+ if ( $ns == NS_IMAGE ) {
+ $wgArticle = new ImagePage( $wgTitle );
+ } elseif ( $ns == NS_CATEGORY ) {
+ $wgArticle = new CategoryPage( $wgTitle );
+ } else {
+ $wgArticle = new Article( $wgTitle );
+ }
+ $rt = Title::newFromRedirect( $wgArticle->fetchContent() );
+ if ( $rt != NULL ) {
+ return $this->getRedirect( $rt );
+ } else {
+ $wgOut = new OutputPage;
+ $wgOut->setParserOptions( new ParserOptions );
+
+ $wgArticle->view();
+ }
+ }
+
+
+ $sk =& $wgUser->getSkin();
+ ob_start();
+ $sk->outputPage( $wgOut );
+ $text = ob_get_contents();
+ ob_end_clean();
+
+ return $text;
+ }
+
+ function getRedirect( $rt ) {
+ $url = $rt->escapeLocalURL();
+ $text = $rt->getPrefixedText();
+ return <<<ENDTEXT
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Refresh" content="0;url=$url" />
+</head>
+<body>
+ <p>Redirecting to <a href="$url">$text</a></p>
+</body>
+</html>
+ENDTEXT;
+ }
+
+ /** Returns image paths used in an XHTML document */
+ function findImages( $text ) {
+ global $wgOutputEncoding, $wgDumpImages;
+ $parser = xml_parser_create( $wgOutputEncoding );
+ xml_set_element_handler( $parser, 'wfDumpStartTagHandler', 'wfDumpEndTagHandler' );
+
+ $wgDumpImages = array();
+ xml_parse( $parser, $text );
+ xml_parser_free( $parser );
+
+ return $wgDumpImages;
+ }
+
+ /**
+ * Copy a file specified by a URL to a given directory
+ *
+ * @param string $srcPath The source URL
+ * @param string $srcPathBase The base directory of the source URL
+ * @param string $srcDirBase The base filesystem directory of the source URL
+ * @param string $destDirBase The base filesystem directory of the destination URL
+ */
+ function relativeCopy( $srcPath, $srcPathBase, $srcDirBase, $destDirBase ) {
+ $rel = substr( $srcPath, strlen( $srcPathBase ) + 1 ); // +1 for slash
+ $sourceLoc = "$srcDirBase/$rel";
+ $destLoc = "$destDirBase/$rel";
+ #print "Copying $sourceLoc to $destLoc\n";
+ if ( !file_exists( $destLoc ) ) {
+ wfMkdirParents( dirname( $destLoc ), 0755 );
+ if ( function_exists( 'symlink' ) && !$this->forceCopy ) {
+ if ( !symlink( $sourceLoc, $destLoc ) ) {
+ print "Warning: unable to create symlink at $destLoc\n";
+ }
+ } else {
+ if ( !copy( $sourceLoc, $destLoc ) ) {
+ print "Warning: unable to copy $sourceLoc to $destLoc\n";
+ }
+ }
+ }
+ }
+
+ /**
+ * Copy an image, and if it is a thumbnail, copy its parent image too
+ */
+ function copyImage( $srcPath, $srcPathBase, $srcDirBase, $destDirBase ) {
+ global $wgUploadPath, $wgUploadDirectory, $wgSharedUploadPath;
+ $this->relativeCopy( $srcPath, $srcPathBase, $srcDirBase, $destDirBase );
+ if ( substr( $srcPath, strlen( $srcPathBase ) + 1, 6 ) == 'thumb/' ) {
+ # The image was a thumbnail
+ # Copy the source image as well
+ $rel = substr( $srcPath, strlen( $srcPathBase ) + 1 );
+ $parts = explode( '/', $rel );
+ $rel = "{$parts[1]}/{$parts[2]}/{$parts[3]}";
+ $newSrc = "$srcPathBase/$rel";
+ $this->relativeCopy( $newSrc, $srcPathBase, $srcDirBase, $destDirBase );
+ }
+ }
+
+ /**
+ * Copy images (or create symlinks) from commons to a static directory.
+ * This is necessary even if you intend to distribute all of commons, because
+ * the directory contents is used to work out which image description pages
+ * are needed.
+ *
+ * Also copies math images, and full-sized images if the makeSnapshot option
+ * is specified.
+ *
+ */
+ function copyImages( $images ) {
+ global $wgUploadPath, $wgUploadDirectory, $wgSharedUploadPath, $wgSharedUploadDirectory,
+ $wgMathPath, $wgMathDirectory;
+ # Find shared uploads and copy them into the static directory
+ $sharedPathLength = strlen( $wgSharedUploadPath );
+ $mathPathLength = strlen( $wgMathPath );
+ $uploadPathLength = strlen( $wgUploadPath );
+ foreach ( $images as $escapedImage => $dummy ) {
+ $image = urldecode( $escapedImage );
+
+ if ( substr( $image, 0, $sharedPathLength ) == $wgSharedUploadPath ) {
+ $this->copyImage( $image, $wgSharedUploadPath, $wgSharedUploadDirectory, $this->sharedStaticDirectory );
+ } elseif ( substr( $image, 0, $mathPathLength ) == $wgMathPath ) {
+ $this->relativeCopy( $image, $wgMathPath, $wgMathDirectory, "{$this->dest}/math" );
+ } elseif ( $this->makeSnapshot && substr( $image, 0, $uploadPathLength ) == $wgUploadPath ) {
+ $this->copyImage( $image, $wgUploadPath, $wgUploadDirectory, $this->destUploadDirectory );
+ }
+ }
+ }
+
+ function onGetFullURL( &$title, &$url, $query ) {
+ global $wgContLang, $wgArticlePath;
+
+ $iw = $title->getInterwiki();
+ if ( $title->isExternal() && $wgContLang->getLanguageName( $iw ) ) {
+ if ( $title->getDBkey() == '' ) {
+ $url = str_replace( '$1', "../$iw/index.html", $wgArticlePath );
+ } else {
+ $url = str_replace( '$1', "../$iw/" . wfUrlencode( $this->getHashedFilename( $title ) ),
+ $wgArticlePath );
+ }
+ $url .= $this->compress ? ".gz" : "";
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ function onGetLocalURL( &$title, &$url, $query ) {
+ global $wgArticlePath;
+
+ if ( $title->isExternal() ) {
+ # Default is fine for interwiki
+ return true;
+ }
+
+ $url = false;
+ if ( $query != '' ) {
+ parse_str( $query, $params );
+ if ( isset($params['action']) && $params['action'] == 'raw' ) {
+ if ( $params['gen'] == 'css' || $params['gen'] == 'js' ) {
+ $file = 'gen.' . $params['gen'];
+ } else {
+ $file = $this->getFriendlyName( $title->getPrefixedDBkey() );
+ // Clean up Monobook.css etc.
+ if ( preg_match( '/^(.*)\.(css|js)_[0-9a-f]{4}$/', $file, $matches ) ) {
+ $file = $matches[1] . '.' . $matches[2];
+ }
+ }
+ $this->rawPages[$file] = array( $file, $title, $params );
+ $url = str_replace( '$1', "raw/" . wfUrlencode( $file ), $wgArticlePath );
+ }
+ }
+ if ( $url === false ) {
+ $url = str_replace( '$1', wfUrlencode( $this->getHashedFilename( $title ) ), $wgArticlePath );
+ }
+ $url .= $this->compress ? ".gz" : "";
+ return false;
+ }
+
+ function getHashedFilename( &$title ) {
+ if ( '' != $title->mInterwiki ) {
+ $dbkey = $title->getDBkey();
+ } else {
+ $dbkey = $title->getPrefixedDBkey();
+ }
+
+ $mainPage = Title::newMainPage();
+ if ( $mainPage->getPrefixedDBkey() == $dbkey ) {
+ return 'index.html';
+ }
+
+ return $this->getHashedDirectory( $title ) . '/' .
+ $this->getFriendlyName( $dbkey ) . '.html';
+ }
+
+ function getFriendlyName( $name ) {
+ global $wgLang;
+ # Replace illegal characters for Windows paths with underscores
+ $friendlyName = strtr( $name, '/\\*?"<>|~', '_________' );
+
+ # Work out lower case form. We assume we're on a system with case-insensitive
+ # filenames, so unless the case is of a special form, we have to disambiguate
+ if ( function_exists( 'mb_strtolower' ) ) {
+ $lowerCase = $wgLang->ucfirst( mb_strtolower( $name ) );
+ } else {
+ $lowerCase = ucfirst( strtolower( $name ) );
+ }
+
+ # Make it mostly unique
+ if ( $lowerCase != $friendlyName ) {
+ $friendlyName .= '_' . substr(md5( $name ), 0, 4);
+ }
+ # Handle colon specially by replacing it with tilde
+ # Thus we reduce the number of paths with hashes appended
+ $friendlyName = str_replace( ':', '~', $friendlyName );
+
+ return $friendlyName;
+ }
+
+ /**
+ * Get a relative directory for putting a title into
+ */
+ function getHashedDirectory( &$title ) {
+ if ( '' != $title->getInterwiki() ) {
+ $pdbk = $title->getDBkey();
+ } else {
+ $pdbk = $title->getPrefixedDBkey();
+ }
+
+ # Find the first colon if there is one, use characters after it
+ $p = strpos( $pdbk, ':' );
+ if ( $p !== false ) {
+ $dbk = substr( $pdbk, $p + 1 );
+ $dbk = substr( $dbk, strspn( $dbk, '_' ) );
+ } else {
+ $dbk = $pdbk;
+ }
+
+ # Split into characters
+ preg_match_all( '/./us', $dbk, $m );
+
+ $chars = $m[0];
+ $length = count( $chars );
+ $dir = '';
+
+ for ( $i = 0; $i < $this->depth; $i++ ) {
+ if ( $i ) {
+ $dir .= '/';
+ }
+ if ( $i >= $length ) {
+ $dir .= '_';
+ } else {
+ $c = $chars[$i];
+ if ( ord( $c ) >= 128 || preg_match( '/[a-zA-Z0-9!#$%&()+,[\]^_`{}-]/', $c ) ) {
+ if ( function_exists( 'mb_strtolower' ) ) {
+ $dir .= mb_strtolower( $c );
+ } else {
+ $dir .= strtolower( $c );
+ }
+ } else {
+ $dir .= sprintf( "%02X", ord( $c ) );
+ }
+ }
+ }
+ return $dir;
+ }
+
+ /**
+ * Calculate the start end end of a job based on the current slice
+ * @param integer $start
+ * @param integer $end
+ * @return array of integers
+ */
+ function sliceRange( $start, $end ) {
+ $count = $end - $start + 1;
+ $each = $count / $this->sliceDenominator;
+ $sliceStart = $start + intval( $each * ( $this->sliceNumerator - 1 ) );
+ if ( $this->sliceNumerator == $this->sliceDenominator ) {
+ $sliceEnd = $end;
+ } else {
+ $sliceEnd = $start + intval( $each * $this->sliceNumerator ) - 1;
+ }
+ return array( $sliceStart, $sliceEnd );
+ }
+
+ /**
+ * Adjust a start point so that it belongs to the current slice, where slices are defined by integer modulo
+ * @param integer $start
+ * @param integer $base The true start of the range; the minimum start
+ */
+ function modSliceStart( $start, $base = 1 ) {
+ return $start - ( $start % $this->sliceDenominator ) + $this->sliceNumerator - 1 + $base;
+ }
+
+ /**
+ * Determine whether a string belongs to the current slice, based on hash
+ */
+ function sliceFilter( $s ) {
+ return crc32( $s ) % $this->sliceDenominator == $this->sliceNumerator - 1;
+ }
+
+ /**
+ * No site notice
+ */
+ function onSiteNoticeBefore( &$text ) {
+ $text = '';
+ return false;
+ }
+ function onSiteNoticeAfter( &$text ) {
+ $text = '';
+ return false;
+ }
+
+ function getMaxPageID() {
+ if ( $this->maxPageID === false ) {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $this->maxPageID = $dbr->selectField( 'page', 'max(page_id)', false, __METHOD__ );
+ }
+ return $this->maxPageID;
+ }
+
+ function profile() {
+ global $wgProfiler;
+
+ if ( !$this->udpProfile ) {
+ return;
+ }
+ if ( !$this->udpProfileInit ) {
+ $this->udpProfileInit = true;
+ } elseif ( $this->udpProfileCounter == 1 % $this->udpProfile ) {
+ $wgProfiler->getFunctionReport();
+ $wgProfiler = new DumpHTML_ProfilerStub;
+ }
+ if ( $this->udpProfileCounter == 0 ) {
+ $wgProfiler = new ProfilerSimpleUDP;
+ $wgProfiler->setProfileID( 'dumpHTML' );
+ }
+ $this->udpProfileCounter = ( $this->udpProfileCounter + 1 ) % $this->udpProfile;
+ }
+}
+
+class DumpHTML_ProfilerStub {
+ function profileIn() {}
+ function profileOut() {}
+ function getOutput() {}
+ function close() {}
+ function getFunctionReport() {}
+}
+
+/** XML parser callback */
+function wfDumpStartTagHandler( $parser, $name, $attribs ) {
+ global $wgDumpImages;
+
+ if ( $name == 'IMG' && isset( $attribs['SRC'] ) ) {
+ $wgDumpImages[$attribs['SRC']] = true;
+ }
+}
+
+/** XML parser callback */
+function wfDumpEndTagHandler( $parser, $name ) {}
+
+# vim: syn=php
+?>
diff --git a/maintenance/dumpHTML.php b/maintenance/dumpHTML.php
new file mode 100644
index 000000000000..2c0c29c44715
--- /dev/null
+++ b/maintenance/dumpHTML.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/**
+ * Usage:
+ * php dumpHTML.php [options...]
+ *
+ * -d <dest> destination directory
+ * -s <start> start ID
+ * -e <end> end ID
+ * -k <skin> skin to use (defaults to htmldump)
+ * --no-overwrite skip existing HTML files
+ * --checkpoint <file> use a checkpoint file to allow restarting of interrupted dumps
+ * --slice <n/m> split the job into m segments and do the n'th one
+ * --images only do image description pages
+ * --shared-desc only do shared (commons) image description pages
+ * --no-shared-desc don't do shared image description pages
+ * --categories only do category pages
+ * --redirects only do redirects
+ * --special only do miscellaneous stuff
+ * --force-copy copy commons instead of symlink, needed for Wikimedia
+ * --interlang allow interlanguage links
+ * --image-snapshot copy all images used to the destination directory
+ * --compress generate compressed version of the html pages
+ * --udp-profile <N> profile 1/N rendering operations using ProfilerSimpleUDP
+ */
+
+
+$optionsWithArgs = array( 's', 'd', 'e', 'k', 'checkpoint', 'slice', 'udp-profile' );
+
+$profiling = false;
+
+if ( $profiling ) {
+ define( 'MW_CMDLINE_CALLBACK', 'wfSetupDump' );
+ function wfSetupDump() {
+ global $wgProfiling, $wgProfileToDatabase, $wgProfileSampleRate;
+ $wgProfiling = true;
+ $wgProfileToDatabase = false;
+ $wgProfileSampleRate = 1;
+ }
+}
+
+if ( in_array( '--udp-profile', $argv ) ) {
+ define( 'MW_FORCE_PROFILE', 1 );
+}
+
+require_once( "commandLine.inc" );
+require_once( "dumpHTML.inc" );
+
+error_reporting( E_ALL & (~E_NOTICE) );
+
+if ( !empty( $options['s'] ) ) {
+ $start = $options['s'];
+} else {
+ $start = 1;
+}
+
+if ( !empty( $options['e'] ) ) {
+ $end = $options['e'];
+} else {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $end = $dbr->selectField( 'page', 'max(page_id)', false );
+}
+
+if ( !empty( $options['d'] ) ) {
+ $dest = $options['d'];
+} else {
+ $dest = "$IP/static";
+}
+
+$skin = isset( $options['k'] ) ? $options['k'] : 'htmldump';
+
+if ( $options['slice'] ) {
+ $bits = explode( '/', $options['slice'] );
+ if ( count( $bits ) != 2 || $bits[0] < 1 || $bits[0] > $bits[1] ) {
+ print "Invalid slice specification";
+ exit;
+ }
+ $sliceNumerator = $bits[0];
+ $sliceDenominator = $bits[1];
+} else {
+ $sliceNumerator = $sliceDenominator = 1;
+}
+
+$wgHTMLDump = new DumpHTML( array(
+ 'dest' => $dest,
+ 'forceCopy' => $options['force-copy'],
+ 'alternateScriptPath' => $options['interlang'],
+ 'interwiki' => $options['interlang'],
+ 'skin' => $skin,
+ 'makeSnapshot' => $options['image-snapshot'],
+ 'checkpointFile' => $options['checkpoint'],
+ 'startID' => $start,
+ 'endID' => $end,
+ 'sliceNumerator' => $sliceNumerator,
+ 'sliceDenominator' => $sliceDenominator,
+ 'noOverwrite' => $options['no-overwrite'],
+ 'compress' => $options['compress'],
+ 'noSharedDesc' => $options['no-shared-desc'],
+ 'udpProfile' => $options['udp-profile'],
+));
+
+
+if ( $options['special'] ) {
+ $wgHTMLDump->doSpecials();
+} elseif ( $options['images'] ) {
+ $wgHTMLDump->doImageDescriptions();
+} elseif ( $options['categories'] ) {
+ $wgHTMLDump->doCategories();
+} elseif ( $options['redirects'] ) {
+ $wgHTMLDump->doRedirects();
+} elseif ( $options['shared-desc'] ) {
+ $wgHTMLDump->doSharedImageDescriptions();
+} else {
+ print "Creating static HTML dump in directory $dest. \n";
+ $dbr =& wfGetDB( DB_SLAVE );
+ $server = $dbr->getProperty( 'mServer' );
+ print "Using database {$server}\n";
+
+ if ( !isset( $options['e'] ) ) {
+ $wgHTMLDump->doEverything();
+ } else {
+ $wgHTMLDump->doArticles();
+ }
+}
+
+if ( isset( $options['debug'] ) ) {
+ #print_r($GLOBALS);
+ # Workaround for bug #36957
+ $globals = array_keys( $GLOBALS );
+ #sort( $globals );
+ $sizes = array();
+ foreach ( $globals as $name ) {
+ $sizes[$name] = strlen( serialize( $GLOBALS[$name] ) );
+ }
+ arsort($sizes);
+ $sizes = array_slice( $sizes, 0, 20 );
+ foreach ( $sizes as $name => $size ) {
+ printf( "%9d %s\n", $size, $name );
+ }
+}
+
+if ( $profiling ) {
+ echo $wgProfiler->getOutput();
+}
+
+?>
diff --git a/maintenance/dumpInterwiki.inc b/maintenance/dumpInterwiki.inc
new file mode 100644
index 000000000000..2039f2df4bf3
--- /dev/null
+++ b/maintenance/dumpInterwiki.inc
@@ -0,0 +1,220 @@
+<?php
+/**
+ * Rebuild interwiki table using the file on meta and the language list
+ * Wikimedia specific!
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+class Site {
+ var $suffix, $lateral, $url;
+
+ function Site( $s, $l, $u ) {
+ $this->suffix = $s;
+ $this->lateral = $l;
+ $this->url = $u;
+ }
+
+ function getURL( $lang ) {
+ $xlang = str_replace( '_', '-', $lang );
+ return "http://$xlang.{$this->url}/wiki/\$1";
+ }
+}
+
+function getRebuildInterwikiDump() {
+ global $langlist, $languageAliases, $prefixRewrites;
+
+ # Multi-language sites
+ # db suffix => db suffix, iw prefix, hostname
+ $sites = array(
+ 'wiki' => new Site( 'wiki', 'w', 'wikipedia.org' ),
+ 'wiktionary' => new Site( 'wiktionary', 'wikt', 'wiktionary.org' ),
+ 'wikiquote' => new Site( 'wikiquote', 'q', 'wikiquote.org' ),
+ 'wikibooks' => new Site( 'wikibooks', 'b', 'wikibooks.org' ),
+ 'wikinews' => new Site( 'wikinews', 'n', 'wikinews.org' ),
+ 'wikisource' => new Site( 'wikisource', 's', 'wikisource.org' ),
+ 'wikimedia' => new Site( 'wikimedia', 'chapter', 'wikimedia.org' ),
+ 'wikiversity' => new Site( 'wikiversity', 'v', 'wikiversity.org' ),
+ );
+
+ # List of language prefixes likely to be found in multi-language sites
+ $langlist = array_map( "trim", file( "/home/wikipedia/common/langlist" ) );
+
+ # List of all database names
+ $dblist = array_map( "trim", file( "/home/wikipedia/common/all.dblist" ) );
+
+ # Special-case hostnames
+ $specials = array(
+ 'sourceswiki' => 'sources.wikipedia.org',
+ 'quotewiki' => 'wikiquote.org',
+ 'textbookwiki' => 'wikibooks.org',
+ 'sep11wiki' => 'sep11.wikipedia.org',
+ 'metawiki' => 'meta.wikimedia.org',
+ 'commonswiki' => 'commons.wikimedia.org',
+ );
+
+ # Extra interwiki links that can't be in the intermap for some reason
+ $extraLinks = array(
+ array( 'm', 'http://meta.wikimedia.org/wiki/$1', 1 ),
+ array( 'meta', 'http://meta.wikimedia.org/wiki/$1', 1 ),
+ array( 'sep11', 'http://sep11.wikipedia.org/wiki/$1', 1 ),
+ );
+
+ # Language aliases, usually configured as redirects to the real wiki in apache
+ # Interlanguage links are made directly to the real wiki
+ # Something horrible happens if you forget to list an alias here, I can't
+ # remember what
+ $languageAliases = array(
+ 'zh-cn' => 'zh',
+ 'zh-tw' => 'zh',
+ 'dk' => 'da',
+ 'nb' => 'no',
+ );
+
+ # Special case prefix rewrites, for the benefit of Swedish which uses s:t
+ # as an abbreviation for saint
+ $prefixRewrites = array(
+ 'svwiki' => array ( 's' => 'src'),
+ );
+
+ # Construct a list of reserved prefixes
+ $reserved = array();
+ foreach ( $langlist as $lang ) {
+ $reserved[$lang] = 1;
+ }
+ foreach ( $languageAliases as $alias => $lang ) {
+ $reserved[$alias] = 1;
+ }
+ foreach( $sites as $site ) {
+ $reserved[$site->lateral] = 1;
+ }
+
+ # Extract the intermap from meta
+ $intermap = wfGetHTTP( 'http://meta.wikimedia.org/w/index.php?title=Interwiki_map&action=raw', 30 );
+ $lines = array_map( 'trim', explode( "\n", trim( $intermap ) ) );
+
+ if ( !$lines || count( $lines ) < 2 ) {
+ wfDie( "m:Interwiki_map not found" );
+ }
+
+ $iwArray = array();
+ # Global iterwiki map
+ foreach ( $lines as $line ) {
+ if ( preg_match( '/^\|\s*(.*?)\s*\|\|\s*(.*?)\s*$/', $line, $matches ) ) {
+ $prefix = strtolower( $matches[1] );
+ $url = $matches[2];
+ if ( preg_match( '/(wikipedia|wiktionary|wikisource|wikiquote|wikibooks|wikimedia)\.org/', $url ) ) {
+ $local = 1;
+ } else {
+ $local = 0;
+ }
+
+ if ( empty( $reserved[$prefix] ) ) {
+ $imap = array( "iw_prefix" => $prefix, "iw_url" => $url, "iw_local" => $local );
+ makeLink ($imap, "__global");
+ }
+ }
+ }
+
+ # Exclude Wikipedia for Wikipedia
+ makeLink ( array ('iw_prefix' => 'wikipedia', 'is_url' => null ), "_wiki" );
+
+ #Multilanguage sites
+ foreach ($sites as $site)
+ $sql .= makeLanguageLinks ( $site, "_".$site->suffix );
+
+
+ foreach ( $dblist as $db ) {
+ if ( isset( $specials[$db] ) ) {
+ # Special wiki
+ # Has interwiki links and interlanguage links to wikipedia
+
+ makeLink( array( 'iw_prefix' => $db, 'iw_url' => "wiki"), "__sites" );
+ # Links to multilanguage sites
+ foreach ( $sites as $targetSite ) {
+ makeLink( array( 'iw_prefix' => $targetSite->lateral,
+ 'iw_url' =>$targetSite->getURL( 'en' ),
+ 'iw_local' => 1 ), $db );
+ }
+
+ } else {
+ # Find out which site this DB belongs to
+ $site = false;
+ foreach( $sites as $candidateSite ) {
+ $suffix = $candidateSite->suffix;
+ if ( preg_match( "/(.*)$suffix$/", $db, $matches ) ) {
+ $site = $candidateSite;
+ break;
+ }
+ }
+ makeLink( array( 'iw_prefix' => $db, 'iw_url' => $site->suffix), "__sites" );
+ if ( !$site ) {
+ print "Invalid database $db\n";
+ continue;
+ }
+ $lang = $matches[1];
+ $host = "$lang." . $site->url;
+
+ # Lateral links
+ foreach ( $sites as $targetSite ) {
+ if ( $targetSite->suffix != $site->suffix ) {
+ makeLink( array( 'iw_prefix' => $targetSite->lateral,
+ 'iw_url' => $targetSite->getURL( $lang ),
+ 'iw_local' => 1 ), $db );
+ }
+ }
+
+ if ( $site->suffix == "wiki" ) {
+ makeLink( array('iw_prefix' => 'w',
+ 'iw_url' => "http://en.wikipedia.org/wiki/$1",
+ 'iw_local' => 1), $db );
+ }
+
+ }
+ }
+ foreach ( $extraLinks as $link )
+ makeLink( $link, "__global" );
+}
+
+# ------------------------------------------------------------------------------------------
+
+# Returns part of an INSERT statement, corresponding to all interlanguage links to a particular site
+function makeLanguageLinks( &$site, $source ) {
+ global $langlist, $languageAliases;
+ # Actual languages with their own databases
+ foreach ( $langlist as $targetLang ) {
+ makeLink( array( $targetLang, $site->getURL( $targetLang ), 1 ), $source );
+ }
+
+ # Language aliases
+ foreach ( $languageAliases as $alias => $lang ) {
+ makeLink( array( $alias, $site->getURL( $lang ), 1 ), $source );
+ }
+}
+
+function makeLink( $entry, $source ) {
+ global $prefixRewrites, $dbFile;
+ if ( isset( $prefixRewrites[$source] ) && isset( $prefixRewrites[$source][$entry[0]] ) )
+ $entry[0] = $prefixRewrites[$source][$entry[0]];
+ if (!array_key_exists("iw_prefix",$entry))
+ $entry = array("iw_prefix" => $entry[0], "iw_url" => $entry[1], "iw_local" => $entry[2]);
+ if ( array_key_exists($source,$prefixRewrites) &&
+ array_key_exists($entry['iw_prefix'],$prefixRewrites[$source]))
+ $entry['iw_prefix'] = $prefixRewrites[$source][$entry['iw_prefix']];
+ if ($dbFile)
+ dba_insert("{$source}:{$entry['iw_prefix']}", trim("{$entry['iw_local']} {$entry['iw_url']}"),$dbFile);
+ else
+ print "{$source}:{$entry['iw_prefix']} {$entry['iw_url']} {$entry['iw_local']}\n";
+
+ }
+
+?>
diff --git a/maintenance/dumpInterwiki.php b/maintenance/dumpInterwiki.php
new file mode 100644
index 000000000000..411260acd86d
--- /dev/null
+++ b/maintenance/dumpInterwiki.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Rebuild interwiki table using the file on meta and the language list
+ * Wikimedia specific!
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+$oldCwd = getcwd();
+
+$optionsWithArgs = array( "o" );
+include_once( "commandLine.inc" );
+include_once( "dumpInterwiki.inc" );
+chdir( $oldCwd );
+
+# Output
+if ( isset( $options['o'] ) ) {
+ # To database specified with -o
+ $dbFile = dba_open( $options['o'], "n", "cdb_make" );
+}
+
+getRebuildInterwikiDump();
+?>
diff --git a/maintenance/dumpLinks.php b/maintenance/dumpLinks.php
new file mode 100644
index 000000000000..f040f390fce8
--- /dev/null
+++ b/maintenance/dumpLinks.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.org/
+ *
+ * Quick demo hack to generate a plaintext link dump,
+ * per the proposed wiki link database standard:
+ * http://www.usemod.com/cgi-bin/mb.pl?LinkDatabase
+ *
+ * Includes all (live and broken) intra-wiki links.
+ * Does not include interwiki or URL links.
+ * Dumps ASCII text to stdout; command-line.
+ *
+ * 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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+require_once 'commandLine.inc';
+
+$dbr =& wfGetDB( DB_SLAVE );
+$result = $dbr->select( array( 'pagelinks', 'page' ),
+ array(
+ 'page_id',
+ 'page_namespace',
+ 'page_title',
+ 'pl_namespace',
+ 'pl_title' ),
+ array( 'page_id=pl_from' ),
+ 'dumpLinks',
+ array( 'ORDER BY page_id' ) );
+
+$lastPage = null;
+while( $row = $dbr->fetchObject( $result ) ) {
+ if( $lastPage != $row->page_id ) {
+ if( isset( $lastPage ) ) {
+ print "\n";
+ }
+ $page = Title::makeTitle( $row->page_namespace, $row->page_title );
+ print $page->getPrefixedUrl();
+ $lastPage = $row->page_id;
+ }
+ $link = Title::makeTitle( $row->pl_namespace, $row->pl_title );
+ print " " . $link->getPrefixedUrl();
+}
+if( isset( $lastPage ) )
+ print "\n";
+
+?>
diff --git a/maintenance/dumpReplayLog.php b/maintenance/dumpReplayLog.php
new file mode 100644
index 000000000000..aa1d5b9aee14
--- /dev/null
+++ b/maintenance/dumpReplayLog.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+error_reporting(E_ALL);
+
+/** */
+require_once( "commandLine.inc" );
+require_once( 'includes/SpecialExport.php' );
+
+/** */
+function dumpReplayLog( $start ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $recentchanges = $dbw->tableName( 'recentchanges' );
+ $result =& $dbw->safeQuery( "SELECT * FROM $recentchanges WHERE rc_timestamp >= "
+ . $dbw->timestamp( $start ) . ' ORDER BY rc_timestamp');
+
+ global $wgInputEncoding;
+ echo '<' . '?xml version="1.0" encoding="' . $wgInputEncoding . '" ?' . ">\n";
+ echo "<wikilog version='experimental'>\n";
+ echo "<!-- Do not use this script for any purpose. It's scary. -->\n";
+ while( $row = $dbw->fetchObject( $result ) ) {
+ echo dumpReplayEntry( $row );
+ }
+ echo "</wikilog>\n";
+ $dbw->freeResult( $result );
+}
+
+/** */
+function dumpReplayEntry( $row ) {
+ $title = Title::MakeTitle( $row->rc_namespace, $row->rc_title );
+ switch( $row->rc_type ) {
+ case RC_EDIT:
+ case RC_NEW:
+ # Edit
+ $dbr =& wfGetDB( DB_MASTER );
+
+ $out = " <edit>\n";
+ $out .= " <title>" . xmlsafe( $title->getPrefixedText() ) . "</title>\n";
+
+ # Get previous edit timestamp
+ if( $row->rc_last_oldid ) {
+ $s = $dbr->selectRow( 'old',
+ array( 'old_timestamp' ),
+ array( 'old_id' => $row->rc_last_oldid ) );
+ $out .= " <lastedit>" . wfTimestamp2ISO8601( $s->old_timestamp ) . "</lastedit>\n";
+ } else {
+ $out .= " <newpage/>\n";
+ }
+
+ if( $row->rc_this_oldid ) {
+ $s = $dbr->selectRow( 'old', array( 'old_id as id','old_timestamp as timestamp',
+ 'old_user as user', 'old_user_text as user_text', 'old_comment as comment',
+ 'old_text as text', 'old_flags as flags' ),
+ array( 'old_id' => $row->rc_this_oldid ) );
+ $out .= revision2xml( $s, true, false );
+ } else {
+ $s = $dbr->selectRow( 'cur', array( 'cur_id as id','cur_timestamp as timestamp','cur_user as user',
+ 'cur_user_text as user_text', 'cur_restrictions as restrictions','cur_comment as comment',
+ 'cur_text as text' ),
+ array( 'cur_id' => $row->rc_cur_id ) );
+ $out .= revision2xml( $s, true, true );
+ }
+ $out .= " </edit>\n";
+ break;
+ case RC_LOG:
+ $dbr =& wfGetDB( DB_MASTER );
+ $s = $dbr->selectRow( 'logging',
+ array( 'log_type', 'log_action', 'log_timestamp', 'log_user',
+ 'log_namespace', 'log_title', 'log_comment' ),
+ array( 'log_timestamp' => $row->rc_timestamp,
+ 'log_user' => $row->rc_user ) );
+ $ts = wfTimestamp2ISO8601( $row->rc_timestamp );
+ $target = Title::MakeTitle( $s->log_namespace, $s->log_title );
+ $out = " <log>\n";
+ $out .= " <type>" . xmlsafe( $s->log_type ) . "</type>\n";
+ $out .= " <action>" . xmlsafe( $s->log_action ) . "</action>\n";
+ $out .= " <timestamp>" . $ts . "</timestamp>\n";
+ $out .= " <contributor><username>" . xmlsafe( $row->rc_user_text ) . "</username></contributor>\n";
+ $out .= " <target>" . xmlsafe( $target->getPrefixedText() ) . "</target>\n";
+ $out .= " <comment>" . xmlsafe( $s->log_comment ) . "</comment>\n";
+ $out .= " </log>\n";
+ break;
+ case RC_MOVE:
+ case RC_MOVE_OVER_REDIRECT:
+ $target = Title::MakeTitle( $row->rc_moved_to_ns, $row->rc_moved_to_title );
+ $out = " <move>\n";
+ $out .= " <title>" . xmlsafe( $title->getPrefixedText() ) . "</title>\n";
+ $out .= " <target>" . xmlsafe( $target->getPrefixedText() ) . "</target>\n";
+ if( $row->rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $out .= " <override/>\n";
+ }
+ $ts = wfTimestamp2ISO8601( $row->rc_timestamp );
+ $out .= " <id>$row->rc_cur_id</id>\n";
+ $out .= " <timestamp>$ts</timestamp>\n";
+ if($row->rc_user_text) {
+ $u = "<username>" . xmlsafe( $row->rc_user_text ) . "</username>";
+ $u .= "<id>$row->rc_user</id>";
+ } else {
+ $u = "<ip>" . xmlsafe( $row->rc_user_text ) . "</ip>";
+ }
+ $out .= " <contributor>$u</contributor>\n";
+ $out .= " </move>\n";
+ }
+ return $out;
+}
+
+
+if( isset( $options['start'] ) ) {
+ $start = wfTimestamp( TS_MW, $options['start'] );
+ dumpReplayLog( $start );
+} else {
+ echo "This is an experimental script to encapsulate data from recent edits.\n";
+ echo "Usage: php dumpReplayLog.php --start=20050118032544\n";
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/dumpSisterSites.php b/maintenance/dumpSisterSites.php
new file mode 100644
index 000000000000..50e121e604a5
--- /dev/null
+++ b/maintenance/dumpSisterSites.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Quickie page name dump script for SisterSites usage.
+ * http://www.eekim.com/cgi-bin/wiki.pl?SisterSites
+ *
+ * Copyright (C) 2006 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+require_once( 'commandLine.inc' );
+
+$dbr = wfGetDB( DB_SLAVE );
+$dbr->bufferResults( false );
+$result = $dbr->select( 'page',
+ array( 'page_namespace', 'page_title' ),
+ array(
+ 'page_namespace' => NS_MAIN,
+ 'page_is_redirect' => 0,
+ ),
+ 'dumpSisterSites' );
+
+while( $row = $dbr->fetchObject( $result ) ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $url = $title->getFullUrl();
+ $text = $title->getPrefixedText();
+ echo "$url $text\n";
+}
+
+$dbr->freeResult( $result );
+
+?>
diff --git a/maintenance/dumpTextPass.php b/maintenance/dumpTextPass.php
new file mode 100644
index 000000000000..8c1563ad032e
--- /dev/null
+++ b/maintenance/dumpTextPass.php
@@ -0,0 +1,371 @@
+<?php
+/**
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+$originalDir = getcwd();
+
+require_once( 'commandLine.inc' );
+require_once( 'SpecialExport.php' );
+require_once( 'maintenance/backup.inc' );
+
+/**
+ * Stream wrapper around 7za filter program.
+ * Required since we can't pass an open file resource to XMLReader->open()
+ * which is used for the text prefetch.
+ */
+class SevenZipStream {
+ var $stream;
+
+ private function stripPath( $path ) {
+ $prefix = 'mediawiki.compress.7z://';
+ return substr( $path, strlen( $prefix ) );
+ }
+
+ function stream_open( $path, $mode, $options, &$opened_path ) {
+ if( $mode{0} == 'r' ) {
+ $options = 'e -bd -so';
+ } elseif( $mode{0} == 'w' ) {
+ $options = 'a -bd -si';
+ } else {
+ return false;
+ }
+ $arg = wfEscapeShellArg( $this->stripPath( $path ) );
+ $command = "7za $options $arg";
+ if( !wfIsWindows() ) {
+ // Suppress the stupid messages on stderr
+ $command .= ' 2>/dev/null';
+ }
+ $this->stream = popen( $command, $mode );
+ return ($this->stream !== false);
+ }
+
+ function url_stat( $path, $flags ) {
+ return stat( $this->stripPath( $path ) );
+ }
+
+ // This is all so lame; there should be a default class we can extend
+
+ function stream_close() {
+ return fclose( $this->stream );
+ }
+
+ function stream_flush() {
+ return fflush( $this->stream );
+ }
+
+ function stream_read( $count ) {
+ return fread( $this->stream, $count );
+ }
+
+ function stream_write( $data ) {
+ return fwrite( $this->stream, $data );
+ }
+
+ function stream_tell() {
+ return ftell( $this->stream );
+ }
+
+ function stream_eof() {
+ return feof( $this->stream );
+ }
+
+ function stream_seek( $offset, $whence ) {
+ return fseek( $this->stream, $offset, $whence );
+ }
+}
+stream_wrapper_register( 'mediawiki.compress.7z', 'SevenZipStream' );
+
+
+class TextPassDumper extends BackupDumper {
+ var $prefetch = null;
+ var $input = "php://stdin";
+ var $history = WikiExporter::FULL;
+ var $fetchCount = 0;
+ var $prefetchCount = 0;
+
+ var $failures = 0;
+ var $maxFailures = 200;
+ var $failureTimeout = 5; // Seconds to sleep after db failure
+
+ function dump() {
+ # This shouldn't happen if on console... ;)
+ header( 'Content-type: text/html; charset=UTF-8' );
+
+ # Notice messages will foul up your XML output even if they're
+ # relatively harmless.
+// ini_set( 'display_errors', false );
+
+ $this->initProgress( $this->history );
+
+ $this->db =& $this->backupDb();
+
+ $this->egress = new ExportProgressFilter( $this->sink, $this );
+
+ $input = fopen( $this->input, "rt" );
+ $result = $this->readDump( $input );
+
+ if( WikiError::isError( $result ) ) {
+ wfDie( $result->getMessage() );
+ }
+
+ $this->report( true );
+ }
+
+ function processOption( $opt, $val, $param ) {
+ $url = $this->processFileOpt( $val, $param );
+
+ switch( $opt ) {
+ case 'prefetch':
+ require_once 'maintenance/backupPrefetch.inc';
+ $this->prefetch = new BaseDump( $url );
+ break;
+ case 'stub':
+ $this->input = $url;
+ break;
+ case 'current':
+ $this->history = WikiExporter::CURRENT;
+ break;
+ case 'full':
+ $this->history = WikiExporter::FULL;
+ break;
+ }
+ }
+
+ function processFileOpt( $val, $param ) {
+ switch( $val ) {
+ case "file":
+ return $param;
+ case "gzip":
+ return "compress.zlib://$param";
+ case "bzip2":
+ return "compress.bzip2://$param";
+ case "7zip":
+ return "mediawiki.compress.7z://$param";
+ default:
+ return $val;
+ }
+ }
+
+ /**
+ * Overridden to include prefetch ratio if enabled.
+ */
+ function showReport() {
+ if( !$this->prefetch ) {
+ return parent::showReport();
+ }
+
+ if( $this->reporting ) {
+ $delta = wfTime() - $this->startTime;
+ $now = wfTimestamp( TS_DB );
+ if( $delta ) {
+ $rate = $this->pageCount / $delta;
+ $revrate = $this->revCount / $delta;
+ $portion = $this->revCount / $this->maxCount;
+ $eta = $this->startTime + $delta / $portion;
+ $etats = wfTimestamp( TS_DB, intval( $eta ) );
+ $fetchrate = 100.0 * $this->prefetchCount / $this->fetchCount;
+ } else {
+ $rate = '-';
+ $revrate = '-';
+ $etats = '-';
+ $fetchrate = '-';
+ }
+ $this->progress( sprintf( "%s: %s %d pages (%0.3f/sec), %d revs (%0.3f/sec), %0.1f%% prefetched, ETA %s [max %d]",
+ $now, wfWikiID(), $this->pageCount, $rate, $this->revCount, $revrate, $fetchrate, $etats, $this->maxCount ) );
+ }
+ }
+
+ function readDump( $input ) {
+ $this->buffer = "";
+ $this->openElement = false;
+ $this->atStart = true;
+ $this->state = "";
+ $this->lastName = "";
+ $this->thisPage = 0;
+ $this->thisRev = 0;
+
+ $parser = xml_parser_create( "UTF-8" );
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
+
+ xml_set_element_handler( $parser, array( &$this, 'startElement' ), array( &$this, 'endElement' ) );
+ xml_set_character_data_handler( $parser, array( &$this, 'characterData' ) );
+
+ $offset = 0; // for context extraction on error reporting
+ $bufferSize = 512 * 1024;
+ do {
+ $chunk = fread( $input, $bufferSize );
+ if( !xml_parse( $parser, $chunk, feof( $input ) ) ) {
+ wfDebug( "TextDumpPass::readDump encountered XML parsing error\n" );
+ return new WikiXmlError( $parser, 'XML import parse failure', $chunk, $offset );
+ }
+ $offset += strlen( $chunk );
+ } while( $chunk !== false && !feof( $input ) );
+ xml_parser_free( $parser );
+
+ return true;
+ }
+
+ function getText( $id ) {
+ $this->fetchCount++;
+ if( isset( $this->prefetch ) ) {
+ $text = $this->prefetch->prefetch( $this->thisPage, $this->thisRev );
+ if( $text === null ) {
+ // Entry missing from prefetch dump
+ } elseif( $text === "" ) {
+ // Blank entries may indicate that the prior dump was broken.
+ // To be safe, reload it.
+ } else {
+ $this->prefetchCount++;
+ return $text;
+ }
+ }
+ while( true ) {
+ try {
+ return $this->doGetText( $id );
+ } catch (DBQueryError $ex) {
+ $this->failures++;
+ if( $this->failures > $this->maxFailures ) {
+ throw $ex;
+ } else {
+ $this->progress( "Database failure $this->failures " .
+ "of allowed $this->maxFailures! " .
+ "Pausing $this->failureTimeout seconds..." );
+ sleep( $this->failureTimeout );
+ }
+ }
+ }
+ }
+
+ /**
+ * May throw a database error if, say, the server dies during query.
+ */
+ private function doGetText( $id ) {
+ $id = intval( $id );
+ $row = $this->db->selectRow( 'text',
+ array( 'old_text', 'old_flags' ),
+ array( 'old_id' => $id ),
+ 'TextPassDumper::getText' );
+ $text = Revision::getRevisionText( $row );
+ $stripped = str_replace( "\r", "", $text );
+ $normalized = UtfNormal::cleanUp( $stripped );
+ return $normalized;
+ }
+
+ function startElement( $parser, $name, $attribs ) {
+ $this->clearOpenElement( null );
+ $this->lastName = $name;
+
+ if( $name == 'revision' ) {
+ $this->state = $name;
+ $this->egress->writeOpenPage( null, $this->buffer );
+ $this->buffer = "";
+ } elseif( $name == 'page' ) {
+ $this->state = $name;
+ if( $this->atStart ) {
+ $this->egress->writeOpenStream( $this->buffer );
+ $this->buffer = "";
+ $this->atStart = false;
+ }
+ }
+
+ if( $name == "text" && isset( $attribs['id'] ) ) {
+ $text = $this->getText( $attribs['id'] );
+ $this->openElement = array( $name, array( 'xml:space' => 'preserve' ) );
+ if( strlen( $text ) > 0 ) {
+ $this->characterData( $parser, $text );
+ }
+ } else {
+ $this->openElement = array( $name, $attribs );
+ }
+ }
+
+ function endElement( $parser, $name ) {
+ if( $this->openElement ) {
+ $this->clearOpenElement( "" );
+ } else {
+ $this->buffer .= "</$name>";
+ }
+
+ if( $name == 'revision' ) {
+ $this->egress->writeRevision( null, $this->buffer );
+ $this->buffer = "";
+ $this->thisRev = "";
+ } elseif( $name == 'page' ) {
+ $this->egress->writeClosePage( $this->buffer );
+ $this->buffer = "";
+ $this->thisPage = "";
+ } elseif( $name == 'mediawiki' ) {
+ $this->egress->writeCloseStream( $this->buffer );
+ $this->buffer = "";
+ }
+ }
+
+ function characterData( $parser, $data ) {
+ $this->clearOpenElement( null );
+ if( $this->lastName == "id" ) {
+ if( $this->state == "revision" ) {
+ $this->thisRev .= $data;
+ } elseif( $this->state == "page" ) {
+ $this->thisPage .= $data;
+ }
+ }
+ $this->buffer .= htmlspecialchars( $data );
+ }
+
+ function clearOpenElement( $style ) {
+ if( $this->openElement ) {
+ $this->buffer .= wfElement( $this->openElement[0], $this->openElement[1], $style );
+ $this->openElement = false;
+ }
+ }
+}
+
+
+$dumper = new TextPassDumper( $argv );
+
+if( true ) {
+ $dumper->dump();
+} else {
+ $dumper->progress( <<<END
+This script postprocesses XML dumps from dumpBackup.php to add
+page text which was stubbed out (using --stub).
+
+XML input is accepted on stdin.
+XML output is sent to stdout; progress reports are sent to stderr.
+
+Usage: php dumpTextPass.php [<options>]
+Options:
+ --stub=<type>:<file> To load a compressed stub dump instead of stdin
+ --prefetch=<type>:<file> Use a prior dump file as a text source, to save
+ pressure on the database.
+ (Requires PHP 5.0+ and the XMLReader PECL extension)
+ --quiet Don't dump status reports to stderr.
+ --report=n Report position and speed after every n pages processed.
+ (Default: 100)
+ --server=h Force reading from MySQL server h
+ --current Base ETA on number of pages in database instead of all revisions
+END
+);
+}
+
+?>
diff --git a/maintenance/dumpUploads.php b/maintenance/dumpUploads.php
new file mode 100644
index 000000000000..8ba4e87bf242
--- /dev/null
+++ b/maintenance/dumpUploads.php
@@ -0,0 +1,116 @@
+<?php
+
+require_once 'commandLine.inc';
+
+class UploadDumper {
+
+ function __construct( $args ) {
+ global $IP, $wgUseSharedUploads;
+ $this->mAction = 'fetchUsed';
+ $this->mBasePath = $IP;
+ $this->mShared = $wgUseSharedUploads;
+
+ if( isset( $args['help'] ) ) {
+ $this->mAction = 'help';
+ }
+
+ if( isset( $args['base'] ) ) {
+ $this->mBasePath = $args['base'];
+ }
+ }
+
+ function run() {
+ $this->{$this->mAction}();
+ }
+
+ function help() {
+ echo <<<END
+Generates list of uploaded files which can be fed to tar or similar.
+By default, outputs relative paths against the parent directory of
+\$wgUploadDirectory.
+
+Usage:
+php dumpUploads.php [options] > list-o-files.txt
+
+Options:
+--base=<path> Set base relative path instead of wiki include root
+
+FIXME: other options not implemented yet ;)
+
+--local List all local files, used or not. No shared files included.
+--used Skip local images that are not used
+--shared Include images used from shared repository
+
+END;
+ }
+
+ /**
+ * Fetch a list of all or used images from a particular image source.
+ * @param string $table
+ * @param string $directory Base directory where files are located
+ * @param bool $shared true to pass shared-dir settings to hash func
+ */
+ function fetchUsed() {
+ $dbr = wfGetDB( DB_SLAVE );
+ $image = $dbr->tableName( 'image' );
+ $imagelinks = $dbr->tableName( 'imagelinks' );
+
+ $sql = "SELECT DISTINCT il_to, img_name
+ FROM $imagelinks
+ LEFT OUTER JOIN $image
+ ON il_to=img_name";
+ $result = $dbr->query( $sql );
+
+ while( $row = $dbr->fetchObject( $result ) ) {
+ if( is_null( $row->img_name ) ) {
+ if( $this->mShared ) {
+ $this->outputShared( $row->il_to );
+ }
+ } else {
+ $this->outputLocal( $row->il_to );
+ }
+ }
+ $dbr->freeResult( $result );
+ }
+
+ function outputLocal( $name ) {
+ global $wgUploadDirectory;
+ return $this->outputItem( $name, $wgUploadDirectory, false );
+ }
+
+ function outputShared( $name ) {
+ global $wgSharedUploadDirectory;
+ return $this->outputItem( $name, $wgSharedUploadDirectory, true );
+ }
+
+ function outputItem( $name, $directory, $shared ) {
+ $filename = $directory .
+ wfGetHashPath( $name, $shared ) .
+ $name;
+ $rel = $this->relativePath( $filename, $this->mBasePath );
+ echo "$rel\n";
+ }
+
+ /**
+ * Return a relative path to $path from the base directory $base
+ * For instance relativePath( '/foo/bar/baz', '/foo' ) should return
+ * 'bar/baz'.
+ */
+ function relativePath( $path, $base) {
+ $path = explode( DIRECTORY_SEPARATOR, $path );
+ $base = explode( DIRECTORY_SEPARATOR, $base );
+ while( count( $base ) && $path[0] == $base[0] ) {
+ array_shift( $path );
+ array_shift( $base );
+ }
+ foreach( $base as $prefix ) {
+ array_unshift( $path, '..' );
+ }
+ return implode( DIRECTORY_SEPARATOR, $path );
+ }
+}
+
+$dumper = new UploadDumper( $options );
+$dumper->run();
+
+?> \ No newline at end of file
diff --git a/maintenance/edit.php b/maintenance/edit.php
new file mode 100644
index 000000000000..33e0607be71a
--- /dev/null
+++ b/maintenance/edit.php
@@ -0,0 +1,68 @@
+<?php
+
+$optionsWithArgs = array( 'u', 's' );
+
+require_once( 'commandLine.inc' );
+
+if ( count( $args ) == 0 || isset( $options['help'] ) ) {
+ print <<<EOT
+Edit an article from the command line
+
+Usage: php edit.php [options...] <title>
+
+Options:
+ -u <user> Username
+ -s <summary> Edit summary
+ -m Minor edit
+ -b Bot (hidden) edit
+ -a Enable autosummary
+ --no-rc Do not show the change in recent changes
+
+If the specified user does not exist, it will be created.
+The text for the edit will be read from stdin.
+
+EOT;
+ exit( 1 );
+}
+
+$userName = isset( $options['u'] ) ? $options['u'] : 'Maintenance script';
+$summary = isset( $options['s'] ) ? $options['s'] : '';
+$minor = isset( $options['m'] );
+$bot = isset( $options['b'] );
+$autoSummary = isset( $options['a'] );
+$noRC = isset( $options['no-rc'] );
+
+$wgUser = User::newFromName( $userName );
+if ( !$wgUser ) {
+ print "Invalid username\n";
+ exit( 1 );
+}
+if ( $wgUser->isAnon() ) {
+ $wgUser->addToDatabase();
+}
+
+$wgTitle = Title::newFromText( $args[0] );
+if ( !$wgTitle ) {
+ print "Invalid title\n";
+ exit( 1 );
+}
+
+$wgArticle = new Article( $wgTitle );
+
+# Read the text
+$text = file_get_contents( 'php://stdin' );
+
+# Do the edit
+print "Saving... ";
+$success = $wgArticle->doEdit( $text, $summary,
+ ( $minor ? EDIT_MINOR : 0 ) |
+ ( $bot ? EDIT_FORCE_BOT : 0 ) |
+ ( $autoSummary ? EDIT_AUTOSUMMARY : 0 ) |
+ ( $noRC ? EDIT_SUPPRESS_RC : 0 ) );
+if ( $success ) {
+ print "done\n";
+} else {
+ print "failed\n";
+ exit( 1 );
+}
+?>
diff --git a/maintenance/eval.php b/maintenance/eval.php
new file mode 100644
index 000000000000..4e477f4c962e
--- /dev/null
+++ b/maintenance/eval.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * PHP lacks an interactive mode, but this can be very helpful when debugging.
+ * This script lets a command-line user start up the wiki engine and then poke
+ * about by issuing PHP commands directly.
+ *
+ * Unlike eg Python, you need to use a 'return' statement explicitly for the
+ * interactive shell to print out the value of the expression. Multiple lines
+ * are evaluated separately, so blocks need to be input without a line break.
+ * Fatal errors such as use of undeclared functions can kill the shell.
+ *
+ * To get decent line editing behavior, you should compile PHP with support
+ * for GNU readline (pass --with-readline to configure).
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+$wgForceLoadBalancing = (getenv('MW_BALANCE') ? true : false);
+$wgUseNormalUser = (getenv('MW_WIKIUSER') ? true : false);
+if (getenv('MW_PROFILING')) {
+ define('MW_CMDLINE_CALLBACK', 'wfSetProfiling');
+}
+function wfSetProfiling() { $GLOBALS['wgProfiling'] = true; }
+
+$optionsWithArgs = array( 'd' );
+
+/** */
+require_once( "commandLine.inc" );
+
+if ( isset( $options['d'] ) ) {
+ $d = $options['d'];
+ if ( $d > 0 ) {
+ $wgDebugLogFile = '/dev/stdout';
+ }
+ if ( $d > 1 ) {
+ foreach ( $wgLoadBalancer->mServers as $i => $server ) {
+ $wgLoadBalancer->mServers[$i]['flags'] |= DBO_DEBUG;
+ }
+ }
+ if ( $d > 2 ) {
+ $wgDebugFunctionEntry = true;
+ }
+}
+
+
+while ( ( $line = readconsole( '> ' ) ) !== false ) {
+ $val = eval( $line . ";" );
+ if( is_null( $val ) ) {
+ echo "\n";
+ } elseif( is_string( $val ) || is_numeric( $val ) ) {
+ echo "$val\n";
+ } else {
+ var_dump( $val );
+ }
+ if ( function_exists( "readline_add_history" ) ) {
+ readline_add_history( $line );
+ }
+}
+
+print "\n";
+
+?>
diff --git a/maintenance/fetchInterwiki.pl b/maintenance/fetchInterwiki.pl
new file mode 100644
index 000000000000..cb56a6df477e
--- /dev/null
+++ b/maintenance/fetchInterwiki.pl
@@ -0,0 +1,102 @@
+#!/usr/bin/env perl
+# Copyright (C) 2005 Ævar Arnfjörð Bjarmason
+use strict;
+use warnings;
+use Socket;
+
+# Conf
+my $map = &get(&url('http://usemod.com/intermap.txt'));
+
+# --- #
+my $cont;
+my @map = split /\n/, $map;
+
+$cont .= '<?php
+# Note: this file is generated by maintenance/fetchInterwiki.pl
+# Edit and rerun that script rather than modifying this directly.
+
+/* private */ $wgValidInterwikis = array(
+';
+
+$cont .= "\t# The usemod interwiki map\n";
+for (my $i=0;$i<=$#map;++$i) {
+ my ($name, $url) = $map[$i] =~ m#^([^ ]+) (.+)#i;
+ $cont .= "\t'$name' => '$url\$1',\n";
+}
+
+my @iso = qw(
+aa ab af als am ar as ay az ba be bg bh bi bn bo bs ca chr co cs csb cy da de dk:da dz el en eo
+es et eu fa fi fj fo fr fy ga gd gl gn gu gv ha he hi hr hu hy ia id ik io is it iu ja jv ka kk
+kl km kn ko ks ku ky la lo lt lv mg mi mk ml mn mo mr ms my na nah nb nds ne nl no oc om or pa
+pl ps pt qu rm rn ro ru rw sa sd sg sh si sk sl sm sn so sq sr ss st su sv sw ta te tg th ti tk
+tl tn to tp tpi tr ts tt tw ug uk ur uz vi vo wa wo xh yi yo za zh zh-cn zh-tw zu);
+
+$cont .= '
+ # Some custom additions:
+ "ReVo" => "http://purl.org/NET/voko/revo/art/$1.html",
+ # eg [[ReVo:cerami]], [[ReVo:astero]] - note X-sensitive!
+ "EcheI" => "http://www.ikso.net/cgi-bin/wiki.pl?$1",
+ "E\\xc4\\x89eI" => "http://www.ikso.net/cgi-bin/wiki.pl?$1",
+ "UnuMondo" => "http://unumondo.com/cgi-bin/wiki.pl?$1", # X-sensitive!
+ "JEFO" => "http://esperanto.jeunes.free.fr/vikio/index.php?$1",
+ "PMEG" => "http://www.bertilow.com/pmeg/$1.php",
+ # ekz [[PMEG:gramatiko/kunligaj vortetoj/au]]
+ "EnciclopediaLibre" => "http://enciclopedia.us.es/wiki.phtml?title=$1",
+
+ # Wikipedia-specific stuff:
+ # Special cases
+ "w" => "http://www.wikipedia.org/wiki/$1",
+ "m" => "http://meta.wikipedia.org/wiki/$1",
+ "meta" => "http://meta.wikipedia.org/wiki/$1",
+ "sep11" => "http://sep11.wikipedia.org/wiki/$1",
+ "simple"=> "http://simple.wikipedia.com/wiki.cgi?$1",
+ "wiktionary" => "http://wiktionary.wikipedia.org/wiki/$1",
+ "PageHistory" => "http://www.wikipedia.org/w/wiki.phtml?title=$1&action=history",
+ "UserContributions" => "http://www.wikipedia.org/w/wiki.phtml?title=Special:Contributions&target=$1",
+ "BackLinks" => "http://www.wikipedia.org/w/wiki.phtml?title=Special:Whatlinkshere&target=$1",
+
+ # ISO 639 2-letter language codes
+';
+
+for(my $i=0; $i<=$#iso;++$i) {
+ my @arr = split /:/, $iso[$i];
+ $cont .= "\t";
+ $cont .= "'$arr[0]' => 'http://";
+
+ if ($arr[1]) {
+ $cont .= $arr[1];
+ } else {
+ $cont .= $arr[0];
+ }
+ $cont .= ".wikipedia.org/wiki/\$1',\n";
+}
+
+$cont .= '
+);
+?>
+';
+
+open IW, ">Interwiki.php";
+print IW $cont;
+close IW;
+
+sub get {
+ my ($host, $url) = @_;
+ my $cont;
+ my $eat;
+
+ my $proto = getprotobyname('tcp');
+ socket(Socket, AF_INET, SOCK_STREAM, $proto);
+ my $iaddr = inet_aton("$host");
+ my $port = getservbyname('http', 'tcp');
+ my $sin = sockaddr_in($port, $iaddr);
+ connect(Socket, $sin);
+ send Socket, "GET $url HTTP/1.0\r\nHost: $host\r\n\r\n",0;
+ while (<Socket>) {
+ $cont .= $_ if $eat; # mmm, food
+ ++$eat if ($_ =~ /^(\n|\r\n|)$/);
+ }
+ return $cont;
+}
+
+sub url {my ($server, $path) = $_[0] =~ m#.*(?=//)//([^/]*)(.*)#g;}
diff --git a/maintenance/findhooks.php b/maintenance/findhooks.php
new file mode 100644
index 000000000000..4f446f2b2af0
--- /dev/null
+++ b/maintenance/findhooks.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Simple script that try to find documented hook and hooks actually
+ * in the code and show what's missing.
+ *
+ * This script assumes that:
+ * - hooks names in hooks.txt are at the beginning of a line and single quoted.
+ * - hooks names in code are the first parameter of wfRunHooks.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @author Ashar Voultoiz <hashar@altern.org>
+ * @copyright Copyright © Ashar voultoiz
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public Licence 2.0 or later
+ */
+
+/** This is a command line script*/
+include('commandLine.inc');
+
+
+# GLOBALS
+
+$doc = $IP . '/docs/hooks.txt';
+$pathinc = $IP . '/includes/';
+
+
+# FUNCTIONS
+
+/**
+ * @return array of documented hooks
+ */
+function getHooksFromDoc() {
+ global $doc;
+ $content = file_get_contents( $doc );
+ preg_match_all( "/\n'(.*?)'/", $content, $m);
+ return $m[1];
+}
+
+/**
+ * Get hooks from a php file
+ * @param $file Full filename to the PHP file.
+ * @return array of hooks found.
+ */
+function getHooksFromFile( $file ) {
+ $content = file_get_contents( $file );
+ preg_match_all( "/wfRunHooks\(\s*\'(.*?)\'/", $content, $m);
+ return $m[1];
+}
+
+/**
+ * Get hooks from the source code.
+ * @param $path Directory where the include files can be found
+ * @return array of hooks found.
+ */
+function getHooksFromPath( $path ) {
+ $hooks = array();
+ if( $dh = opendir($path) ) {
+ while(($file = readdir($dh)) !== false) {
+ if( filetype($path.$file) == 'file' ) {
+ $hooks = array_merge( $hooks, getHooksFromFile($path.$file) );
+ }
+ }
+ closedir($dh);
+ }
+ return $hooks;
+}
+
+/**
+ * Nicely output the array
+ * @param $msg A message to show before the value
+ * @param $arr An array
+ * @param $sort Boolean : wheter to sort the array (Default: true)
+ */
+function printArray( $msg, $arr, $sort = true ) {
+ if($sort) asort($arr);
+ foreach($arr as $v) print "$msg: $v\n";
+}
+
+
+# MAIN
+
+$documented = getHooksFromDoc($doc);
+$potential = getHooksFromPath($pathinc);
+
+$todo = array_diff($potential, $documented);
+$deprecated = array_diff($documented, $potential);
+
+// let's show the results:
+printArray('undocumented', $todo );
+printArray('not found', $deprecated );
+
+?>
diff --git a/maintenance/fixSlaveDesync.php b/maintenance/fixSlaveDesync.php
new file mode 100644
index 000000000000..d2dffe543f61
--- /dev/null
+++ b/maintenance/fixSlaveDesync.php
@@ -0,0 +1,195 @@
+<?php
+
+$wgUseRootUser = true;
+require_once( 'commandLine.inc' );
+
+//$wgDebugLogFile = '/dev/stdout';
+
+$slaveIndexes = array();
+for ( $i = 1; $i < count( $wgDBservers ); $i++ ) {
+ if ( $wgLoadBalancer->isNonZeroLoad( $i ) ) {
+ $slaveIndexes[] = $i;
+ }
+}
+/*
+foreach ( $wgLoadBalancer->mServers as $i => $server ) {
+ $wgLoadBalancer->mServers[$i]['flags'] |= DBO_DEBUG;
+}*/
+$reportingInterval = 1000;
+
+if ( isset( $args[0] ) ) {
+ desyncFixPage( $args[0] );
+} else {
+ $dbw =& wfGetDB( DB_MASTER );
+ $maxPage = $dbw->selectField( 'page', 'MAX(page_id)', false, 'fixDesync.php' );
+ $corrupt = findPageLatestCorruption();
+ foreach ( $corrupt as $id => $dummy ) {
+ desyncFixPage( $id );
+ }
+ /*
+ for ( $i=1; $i <= $maxPage; $i++ ) {
+ desyncFixPage( $i );
+ if ( !($i % $reportingInterval) ) {
+ print "$i\n";
+ }
+ }*/
+}
+
+function findPageLatestCorruption() {
+ $desync = array();
+ $n = 0;
+ $dbw =& wfGetDB( DB_MASTER );
+ $masterIDs = array();
+ $res = $dbw->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ );
+ print "Number of pages: " . $dbw->numRows( $res ) . "\n";
+ while ( $row = $dbw->fetchObject( $res ) ) {
+ $masterIDs[$row->page_id] = $row->page_latest;
+ if ( !( ++$n % 10000 ) ) {
+ print "$n\r";
+ }
+ }
+ print "\n";
+ $dbw->freeResult( $res );
+
+ global $slaveIndexes;
+ foreach ( $slaveIndexes as $i ) {
+ $slaveIDs = array();
+ $db =& wfGetDB( $i );
+ $res = $db->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( isset( $masterIDs[$row->page_id] ) && $masterIDs[$row->page_id] != $row->page_latest ) {
+ $desync[$row->page_id] = true;
+ print $row->page_id . "\t";
+ }
+ }
+ $db->freeResult( $res );
+ }
+ print "\n";
+ return $desync;
+}
+
+function desyncFixPage( $pageID ) {
+ global $slaveIndexes;
+ $fname = 'desyncFixPage';
+
+ # Check for a corrupted page_latest
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+ $realLatest = $dbw->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ),
+ $fname, 'FOR UPDATE' );
+ #list( $masterFile, $masterPos ) = $dbw->getMasterPos();
+ $found = false;
+ foreach ( $slaveIndexes as $i ) {
+ $db =& wfGetDB( $i );
+ /*
+ if ( !$db->masterPosWait( $masterFile, $masterPos, 10 ) ) {
+ echo "Slave is too lagged, aborting\n";
+ $dbw->commit();
+ sleep(10);
+ return;
+ }*/
+ $latest = $db->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), $fname );
+ $max = $db->selectField( 'revision', 'MAX(rev_id)', false, $fname );
+ if ( $latest != $realLatest && $realLatest < $max ) {
+ print "page_latest corrupted in page $pageID, server $i\n";
+ $found = true;
+ break;
+ }
+ }
+ if ( !$found ) {
+ print "page_id $pageID seems fine\n";
+ $dbw->commit();
+ return;
+ }
+
+ # Find the missing revisions
+ $res = $dbw->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ),
+ $fname, 'FOR UPDATE' );
+ $masterIDs = array();
+ while ( $row = $dbw->fetchObject( $res ) ) {
+ $masterIDs[] = $row->rev_id;
+ }
+ $dbw->freeResult( $res );
+
+ $res = $db->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ), $fname );
+ $slaveIDs = array();
+ while ( $row = $db->fetchObject( $res ) ) {
+ $slaveIDs[] = $row->rev_id;
+ }
+ $db->freeResult( $res );
+ if ( count( $masterIDs ) < count( $slaveIDs ) ) {
+ $missingIDs = array_diff( $slaveIDs, $masterIDs );
+ if ( count( $missingIDs ) ) {
+ print "Found " . count( $missingIDs ) . " lost in master, copying from slave... ";
+ $dbFrom = $db;
+ $dbTo = $dbw;
+ $found = true;
+ $toMaster = true;
+ } else {
+ $found = false;
+ }
+ } else {
+ $missingIDs = array_diff( $masterIDs, $slaveIDs );
+ if ( count( $missingIDs ) ) {
+ print "Found " . count( $missingIDs ) . " missing revision(s), copying from master... ";
+ $dbFrom = $dbw;
+ $dbTo = $db;
+ $found = true;
+ $toMaster = false;
+ } else {
+ $found = false;
+ }
+ }
+
+ if ( $found ) {
+ foreach ( $missingIDs as $rid ) {
+ print "$rid ";
+ # Revision
+ $row = $dbFrom->selectRow( 'revision', '*', array( 'rev_id' => $rid ), $fname );
+ if ( $toMaster ) {
+ $id = $dbw->selectField( 'revision', 'rev_id', array( 'rev_id' => $rid ),
+ $fname, 'FOR UPDATE' );
+ if ( $id ) {
+ echo "Revision already exists\n";
+ $found = false;
+ break;
+ } else {
+ $dbw->insert( 'revision', get_object_vars( $row ), $fname, 'IGNORE' );
+ }
+ } else {
+ foreach ( $slaveIndexes as $i ) {
+ $db =& wfGetDB( $i );
+ $db->insert( 'revision', get_object_vars( $row ), $fname, 'IGNORE' );
+ }
+ }
+
+ # Text
+ $row = $dbFrom->selectRow( 'text', '*', array( 'old_id' => $row->rev_text_id ), $fname );
+ if ( $toMaster ) {
+ $dbw->insert( 'text', get_object_vars( $row ), $fname, 'IGNORE' );
+ } else {
+ foreach ( $slaveIndexes as $i ) {
+ $db =& wfGetDB( $i );
+ $db->insert( 'text', get_object_vars( $row ), $fname, 'IGNORE' );
+ }
+ }
+ }
+ print "done\n";
+ }
+
+ if ( $found ) {
+ print "Fixing page_latest... ";
+ if ( $toMaster ) {
+ #$dbw->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), $fname );
+ } else {
+ foreach ( $slaveIndexes as $i ) {
+ $db =& wfGetDB( $i );
+ $db->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), $fname );
+ }
+ }
+ print "done\n";
+ }
+ $dbw->commit();
+}
+
+?>
diff --git a/maintenance/fixTimestamps.php b/maintenance/fixTimestamps.php
new file mode 100644
index 000000000000..784e35cdfc0d
--- /dev/null
+++ b/maintenance/fixTimestamps.php
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * This script fixes timestamp corruption caused by one or more webservers
+ * temporarily being set to the wrong time. The time offset must be known and
+ * consistent. Start and end times (in 14-character format) restrict the search,
+ * and must bracket the damage. There must be a majority of good timestamps in the
+ * search period.
+ */
+
+require_once( 'commandLine.inc' );
+
+if ( count( $args ) < 3 ) {
+ echo "Usage: php fixTimestamps.php <offset in hours> <start time> <end time>\n";
+ exit(1);
+}
+
+$offset = $args[0] * 3600;
+$start = $args[1];
+$end = $args[2];
+$fname = 'fixTimestamps.php';
+$grace = 60; // maximum normal clock offset
+
+# Find bounding revision IDs
+$dbw =& wfGetDB( DB_MASTER );
+$revisionTable = $dbw->tableName( 'revision' );
+$res = $dbw->query( "SELECT MIN(rev_id) as minrev, MAX(rev_id) as maxrev FROM $revisionTable " .
+ "WHERE rev_timestamp BETWEEN '{$start}' AND '{$end}'", $fname );
+$row = $dbw->fetchObject( $res );
+
+if ( is_null( $row->minrev ) ) {
+ echo "No revisions in search period.\n";
+ exit(0);
+}
+
+$minRev = $row->minrev;
+$maxRev = $row->maxrev;
+
+# Select all timestamps and IDs
+$sql = "SELECT rev_id, rev_timestamp FROM $revisionTable " .
+ "WHERE rev_id BETWEEN $minRev AND $maxRev";
+if ( $offset > 0 ) {
+ $sql .= " ORDER BY rev_id DESC";
+ $expectedSign = -1;
+} else {
+ $expectedSign = 1;
+}
+
+$res = $dbw->query( $sql, $fname );
+
+$lastNormal = 0;
+$badRevs = array();
+$numGoodRevs = 0;
+
+while ( $row = $dbw->fetchObject( $res ) ) {
+ $timestamp = wfTimestamp( TS_UNIX, $row->rev_timestamp );
+ $delta = $timestamp - $lastNormal;
+ $sign = $delta == 0 ? 0 : $delta / abs( $delta );
+ if ( $sign == 0 || $sign == $expectedSign ) {
+ // Monotonic change
+ $lastNormal = $timestamp;
+ ++ $numGoodRevs;
+ continue;
+ } elseif ( abs( $delta ) <= $grace ) {
+ // Non-monotonic change within grace interval
+ ++ $numGoodRevs;
+ continue;
+ } else {
+ // Non-monotonic change larger than grace interval
+ $badRevs[] = $row->rev_id;
+ }
+}
+$dbw->freeResult( $res );
+
+$numBadRevs = count( $badRevs );
+if ( $numBadRevs > $numGoodRevs ) {
+ echo
+"The majority of revisions in the search interval are marked as bad.
+
+Are you sure the offset ($offset) has the right sign? Positive means the clock
+was incorrectly set forward, negative means the clock was incorrectly set back.
+
+If the offset is right, then increase the search interval until there are enough
+good revisions to provide a majority reference.
+";
+
+ exit(1);
+} elseif ( $numBadRevs == 0 ) {
+ echo "No bad revisions found.\n";
+ exit(0);
+}
+
+printf( "Fixing %d revisions (%.2f%% of revisions in search interval)\n",
+ $numBadRevs, $numBadRevs / ($numGoodRevs + $numBadRevs) * 100 );
+
+$fixup = -$offset;
+$sql = "UPDATE $revisionTable " .
+ "SET rev_timestamp=DATE_FORMAT(DATE_ADD(rev_timestamp, INTERVAL $fixup SECOND), '%Y%m%d%H%i%s') " .
+ "WHERE rev_id IN (" . $dbw->makeList( $badRevs ) . ')';
+//echo "$sql\n";
+$dbw->query( $sql, $fname );
+echo "Done\n";
+
+?>
diff --git a/maintenance/fixUserRegistration.php b/maintenance/fixUserRegistration.php
new file mode 100644
index 000000000000..af8a68c2b001
--- /dev/null
+++ b/maintenance/fixUserRegistration.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Fix the user_registration field.
+ * In particular, for values which are NULL, set them to the date of the first edit
+ */
+
+require_once( 'commandLine.inc' );
+
+$fname = 'fixUserRegistration.php';
+
+$dbr =& wfGetDB( DB_SLAVE );
+$dbw =& wfGetDB( DB_MASTER );
+
+// Get user IDs which need fixing
+$res = $dbr->select( 'user', 'user_id', 'user_registration IS NULL', $fname );
+
+while ( $row = $dbr->fetchObject( $res ) ) {
+ $id = $row->user_id;
+ // Get first edit time
+ $timestamp = $dbr->selectField( 'revision', 'MIN(rev_timestamp)', array( 'rev_user' => $id ), $fname );
+ // Update
+ if ( !empty( $timestamp ) ) {
+ $dbw->update( 'user', array( 'user_registration' => $timestamp ), array( 'user_id' => $id ), $fname );
+ print "$id $timestamp\n";
+ } else {
+ print "$id NULL\n";
+ }
+}
+print "\n";
+
+?>
diff --git a/maintenance/fuzz-tester.php b/maintenance/fuzz-tester.php
new file mode 100644
index 000000000000..0ee052b2b21a
--- /dev/null
+++ b/maintenance/fuzz-tester.php
@@ -0,0 +1,2458 @@
+<?php
+/**
+* @package MediaWiki
+* @subpackage Maintainance
+* @author Nick Jenkins ( http://nickj.org/ ).
+* @copyright 2006 Nick Jenkins
+* @licence GNU General Public Licence 2.0
+
+Started: 18 May 2006.
+
+Description:
+ Performs fuzz-style testing of MediaWiki's parser and forms.
+
+How:
+ - Generate lots of nasty wiki text.
+ - Ask the Parser to render that wiki text to HTML, or ask MediaWiki's forms
+ to deal with that wiki text.
+ - Check MediaWiki's output for problems.
+ - Repeat.
+
+Why:
+ - To help find bugs.
+ - To help find security issues, or potential security issues.
+
+What type of problems are being checked for:
+ - Unclosed tags.
+ - Errors or interesting warnings from Tidy.
+ - PHP errors / warnings / notices.
+ - MediaWiki internal errors.
+ - Very slow responses.
+ - No response from apache.
+ - Optionally checking for malformed HTML using the W3C validator.
+
+Background:
+ Many of the wikiFuzz class methods are a modified PHP port,
+ of a "shameless" Python port, of LCAMTUF'S MANGELME:
+ - http://www.securiteam.com/tools/6Z00N1PBFK.html
+ - http://www.securityfocus.com/archive/1/378632/2004-10-15/2004-10-21/0
+
+Video:
+ There's an XviD video discussing this fuzz tester. You can get it from:
+ http://files.nickj.org/MediaWiki/Fuzz-Testing-MediaWiki-xvid.avi
+
+Requirements:
+ To run this, you will need:
+ - Command-line PHP5, with PHP-curl enabled (not all installations have this
+ enabled - try "apt-get install php5-curl" if you're on Debian to install).
+ - the Tidy standalone executable. ("apt-get install tidy").
+
+Optional:
+ - If you want to run the curl scripts, you'll need standalone curl installed
+ ("apt-get install curl")
+ - For viewing the W3C validator output on a command line, the "html2text"
+ program may be useful ("apt-get install html2text")
+
+Saving tests and test results:
+ Any of the fuzz tests which find problems are saved for later review.
+ In order to help track down problems, tests are saved in a number of
+ different formats. The default filename extensions and their meanings are:
+ - ".test.php" : PHP script that reproduces just that one problem using PHP-Curl.
+ - ".curl.sh" : Shell script that reproduces that problem using standalone curl.
+ - ".data.bin" : The serialized PHP data so that this script can re-run the test.
+ - ".info.txt" : A human-readable text file with details of the field contents.
+
+Wiki configuration for testing:
+ You should make some additions to LocalSettings.php in order to catch the most
+ errors. Note this configuration is for **TESTING PURPOSES ONLY**, and is IN NO
+ WAY, SHAPE, OR FORM suitable for deployment on a hostile network. That said,
+ personally I find these additions to be the most helpful for testing purposes:
+
+ // --------- Start ---------
+ // Everyone can do everything. Very useful for testing, yet useless for deployment.
+ $wgGroupPermissions['*']['autoconfirmed'] = true;
+ $wgGroupPermissions['*']['block'] = true;
+ $wgGroupPermissions['*']['bot'] = true;
+ $wgGroupPermissions['*']['delete'] = true;
+ $wgGroupPermissions['*']['deletedhistory'] = true;
+ $wgGroupPermissions['*']['deleterevision'] = true;
+ $wgGroupPermissions['*']['editinterface'] = true;
+ $wgGroupPermissions['*']['hiderevision'] = true;
+ $wgGroupPermissions['*']['import'] = true;
+ $wgGroupPermissions['*']['importupload'] = true;
+ $wgGroupPermissions['*']['minoredit'] = true;
+ $wgGroupPermissions['*']['move'] = true;
+ $wgGroupPermissions['*']['patrol'] = true;
+ $wgGroupPermissions['*']['protect'] = true;
+ $wgGroupPermissions['*']['proxyunbannable'] = true;
+ $wgGroupPermissions['*']['renameuser'] = true;
+ $wgGroupPermissions['*']['reupload'] = true;
+ $wgGroupPermissions['*']['reupload-shared'] = true;
+ $wgGroupPermissions['*']['rollback'] = true;
+ $wgGroupPermissions['*']['siteadmin'] = true;
+ $wgGroupPermissions['*']['trackback'] = true;
+ $wgGroupPermissions['*']['unwatchedpages'] = true;
+ $wgGroupPermissions['*']['upload'] = true;
+ $wgGroupPermissions['*']['userrights'] = true;
+ $wgGroupPermissions['*']['renameuser'] = true;
+ $wgGroupPermissions['*']['makebot'] = true;
+ $wgGroupPermissions['*']['makesysop'] = true;
+
+ // Enable weird and wonderful options:
+ // Increase default error reporting level.
+ error_reporting (E_ALL); // At a later date could be increased to E_ALL | E_STRICT
+ $wgBlockOpenProxies = true; // Some block pages require this to be true in order to test.
+ $wgEnableUploads = true; // enable uploads.
+ //$wgUseTrackbacks = true; // enable trackbacks; However this breaks the viewPageTest, so currently disabled.
+ $wgDBerrorLog = "/root/mediawiki-db-error-log.txt"; // log DB errors, replace with suitable path.
+ $wgShowSQLErrors = true; // Show SQL errors (instead of saying the query was hidden).
+
+ // Install & enable Parser Hook extensions to increase code coverage. E.g.:
+ require_once("extensions/ParserFunctions/ParserFunctions.php");
+ require_once("extensions/Cite/Cite.php");
+ require_once("extensions/inputbox/inputbox.php");
+ require_once("extensions/Sort/Sort.php");
+ require_once("extensions/wikihiero/wikihiero.php");
+ require_once("extensions/CharInsert/CharInsert.php");
+ require_once("extensions/FixedImage/FixedImage.php");
+
+ // Install & enable Special Page extensions to increase code coverage. E.g.:
+ require_once("extensions/Cite/SpecialCite.php");
+ require_once("extensions/Filepath/SpecialFilepath.php");
+ require_once("extensions/Makebot/Makebot.php");
+ require_once("extensions/Makesysop/SpecialMakesysop.php");
+ require_once("extensions/Renameuser/SpecialRenameuser.php");
+ require_once("extensions/LinkSearch/LinkSearch.php");
+ // --------- End ---------
+
+ Also add/change this in AdminSettings.php:
+ // --------- Start ---------
+ $wgEnableProfileInfo = true;
+ $wgDBserver = "localhost"; // replace with DB server hostname
+ // --------- End ---------
+
+Usage:
+ Run with "php fuzz-tester.php".
+ To see the various command-line options, run "php fuzz-tester.php --help".
+ To stop the script, press Ctrl-C.
+
+Console output:
+ - If requested, first any previously failed tests will be rerun.
+ - Then new tests will be generated and run. Any tests that fail will be saved,
+ and a brief message about why they failed will be printed on the console.
+ - The console will show the number of tests run, time run, number of tests
+ failed, number of tests being done per minute, and the name of the current test.
+
+TODO:
+ Some known things that could improve this script:
+ - Logging in with cookie jar storage needed for some tests (as there are some
+ pages that cannot be tested without being logged in, and which are currently
+ untested - e.g. Special:Emailuser, Special:Preferences, adding to Watchist).
+ - Testing of Timeline extension (I cannot test as ploticus has/had issues on
+ my architecture).
+
+*/
+
+/////////////////////////// COMMAND LINE HELP ////////////////////////////////////
+
+// This is a command line script, load MediaWiki env (gives command line options);
+include('commandLine.inc');
+
+// if the user asked for an explanation of command line options.
+if ( isset( $options["help"] ) ) {
+ print <<<ENDS
+MediaWiki $wgVersion fuzz tester
+Usage: php {$_SERVER["SCRIPT_NAME"]} [--quiet] [--base-url=<url-to-test-wiki>]
+ [--directory=<failed-test-path>] [--include-binary]
+ [--w3c-validate] [--delete-passed-retests] [--help]
+ [--user=<username>] [--password=<password>]
+ [--rerun-failed-tests] [--max-errors=<int>]
+ [--max-runtime=<num-minutes>]
+ [--specific-test=<test-name>]
+
+Options:
+ --quiet : Hides passed tests, shows only failed tests.
+ --base-url : URL to a wiki on which to run the tests.
+ The "http://" is optional and can be omitted.
+ --directory : Full path to directory for storing failed tests.
+ Will be created if it does not exist.
+ --include-binary : Includes non-alphanumeric characters in the tests.
+ --w3c-validate : Validates pages using the W3C's web validator.
+ Slow. Currently many pages fail validation.
+ --user : Login name of a valid user on your test wiki.
+ --password : Password for the valid user on your test wiki.
+ --delete-passed-retests : Will delete retests that now pass.
+ Requires --rerun-failed-tests to be meaningful.
+ --rerun-failed-tests : Whether to rerun any previously failed tests.
+ --max-errors : Maximum number of errors to report before exiting.
+ Does not include errors from --rerun-failed-tests
+ --max-runtime : Maximum runtime, in minutes, to run before exiting.
+ Only applies to new tests, not --rerun-failed-tests
+ --specific-test : Runs only the specified fuzz test.
+ Only applies to new tests, not --rerun-failed-tests
+ --help : Show this help message.
+
+Example:
+ If you wanted to fuzz test a nightly MediaWiki checkout using cron for 1 hour,
+ and only wanted to be informed of errors, and did not want to redo previously
+ failed tests, and wanted a maximum of 100 errors, then you could do:
+ php {$_SERVER["SCRIPT_NAME"]} --quiet --max-errors=100 --max-runtime=60
+
+
+ENDS;
+
+ exit( 0 );
+}
+
+
+// if we got command line options, check they look valid.
+$validOptions = array ("quiet", "base-url", "directory", "include-binary",
+ "w3c-validate", "user", "password", "delete-passed-retests",
+ "rerun-failed-tests", "max-errors",
+ "max-runtime", "specific-test", "help" );
+if (!empty($options)) {
+ $unknownArgs = array_diff (array_keys($options), $validOptions);
+ foreach ($unknownArgs as $invalidArg) {
+ print "Ignoring invalid command-line option: --$invalidArg\n";
+ }
+}
+
+
+///////////////////////////// CONFIGURATION ////////////////////////////////////
+
+// URL to some wiki on which we can run our tests.
+if (!empty($options["base-url"])) {
+ define("WIKI_BASE_URL", $options["base-url"]);
+} else {
+ define("WIKI_BASE_URL", $wgServer . $wgScriptPath . '/');
+}
+
+// The directory name where we store the output.
+// Example for Windows: "c:\\temp\\wiki-fuzz"
+if (!empty($options["directory"])) {
+ define("DIRECTORY", $options["directory"] );
+} else {
+ define("DIRECTORY", "{$wgUploadDirectory}/fuzz-tests");
+}
+
+// Should our test fuzz data include binary strings?
+define("INCLUDE_BINARY", isset($options["include-binary"]) );
+
+// Whether we want to validate HTML output on the web.
+// At the moment very few generated pages will validate, so not recommended.
+define("VALIDATE_ON_WEB", isset($options["w3c-validate"]) );
+// URL to use to validate our output:
+define("VALIDATOR_URL", "http://validator.w3.org/check");
+
+// Location of Tidy standalone executable.
+define("PATH_TO_TIDY", "/usr/bin/tidy");
+
+// The name of a user who has edited on your wiki. Used
+// when testing the Special:Contributions and Special:Userlogin page.
+if (!empty($options["user"])) {
+ define("USER_ON_WIKI", $options["user"] );
+} else {
+ define("USER_ON_WIKI", "nickj");
+}
+
+// The password of the above user. Used when testing the login page,
+// and to do this we sometimes need to login successfully.
+if (!empty($options["password"])) {
+ define("USER_PASSWORD", $options["password"] );
+} else {
+ // And no, this is not a valid password on any public wiki.
+ define("USER_PASSWORD", "nickj");
+}
+
+// If we have a test that failed, and then we run it again, and it passes,
+// do you want to delete it or keep it?
+define("DELETE_PASSED_RETESTS", isset($options["delete-passed-retests"]) );
+
+// Do we want to rerun old saved tests at script startup?
+// Set to true to help catch regressions, or false if you only want new stuff.
+define("RERUN_OLD_TESTS", isset($options["rerun-failed-tests"]) );
+
+// File where the database errors are logged. Should be defined in LocalSettings.php.
+define("DB_ERROR_LOG_FILE", $wgDBerrorLog );
+
+// Run in chatty mode (all output, default), or run in quiet mode (only prints out details of failed tests)?
+define("QUIET", isset($options["quiet"]) );
+
+// The maximum runtime, if specified.
+if (!empty($options["max-runtime"]) && intval($options["max-runtime"])>0) {
+ define("MAX_RUNTIME", intval($options["max-runtime"]) );
+}
+
+// The maximum number of problems to find, if specified. Excludes retest errors.
+if (!empty($options["max-errors"]) && intval($options["max-errors"])>0) {
+ define("MAX_ERRORS", intval($options["max-errors"]) );
+}
+
+// if the user has requested a specific test (instead of all tests), and the test they asked for looks valid.
+if (!empty($options["specific-test"])) {
+ if (class_exists($options["specific-test"]) && get_parent_class($options["specific-test"])=="pageTest") {
+ define("SPECIFIC_TEST", $options["specific-test"] );
+ }
+ else {
+ print "Ignoring invalid --specific-test\n";
+ }
+}
+
+// Define the file extensions we'll use:
+define("PHP_TEST" , ".test.php");
+define("CURL_TEST", ".curl.sh" );
+define("DATA_FILE", ".data.bin");
+define("INFO_FILE", ".info.txt");
+define("HTML_FILE", ".wiki_preview.html");
+
+// If it goes wrong, we want to know about it.
+error_reporting(E_ALL | E_STRICT);
+
+//////////////// A CLASS THAT GENERATES RANDOM NASTY WIKI & HTML STRINGS //////////////////////
+
+class wikiFuzz {
+
+ // Only some HTML tags are understood with params by MediaWiki, the rest are ignored.
+ // List the tags that accept params below, as well as what those params are.
+ public static $data = array(
+ "B" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "CAPTION" => array("CLASS", "ID", "STYLE", "align", "lang", "dir", "title"),
+ "CENTER" => array("CLASS", "STYLE", "ID", "lang", "dir", "title"),
+ "DIV" => array("CLASS", "STYLE", "ID", "align", "lang", "dir", "title"),
+ "FONT" => array("CLASS", "STYLE", "ID", "lang", "dir", "title", "face", "size", "color"),
+ "H1" => array("STYLE", "CLASS", "ID", "align", "lang", "dir", "title"),
+ "H2" => array("STYLE", "CLASS", "ID", "align", "lang", "dir", "title"),
+ "HR" => array("STYLE", "CLASS", "ID", "WIDTH", "lang", "dir", "title", "size", "noshade"),
+ "LI" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", "type", "value"),
+ "TABLE" => array("STYLE", "CLASS", "ID", "BGCOLOR", "WIDTH", "ALIGN", "BORDER", "CELLPADDING",
+ "CELLSPACING", "lang", "dir", "title", "summary", "frame", "rules"),
+ "TD" => array("STYLE", "CLASS", "ID", "BGCOLOR", "WIDTH", "ALIGN", "COLSPAN", "ROWSPAN",
+ "VALIGN", "abbr", "axis", "headers", "scope", "nowrap", "height", "lang",
+ "dir", "title", "char", "charoff"),
+ "TH" => array("STYLE", "CLASS", "ID", "BGCOLOR", "WIDTH", "ALIGN", "COLSPAN", "ROWSPAN",
+ "VALIGN", "abbr", "axis", "headers", "scope", "nowrap", "height", "lang",
+ "dir", "title", "char", "charoff"),
+ "TR" => array("CLASS", "STYLE", "ID", "BGCOLOR", "ALIGN", "VALIGN", "lang", "dir", "title", "char", "charoff"),
+ "UL" => array("CLASS", "STYLE", "ID", "lang", "dir", "title", "type"),
+ "P" => array("style", "class", "id", "align", "lang", "dir", "title"),
+ "blockquote" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", "cite"),
+ "span" => array("CLASS", "ID", "STYLE", "align", "lang", "dir", "title"),
+ "code" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "tt" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "small" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "big" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "s" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "u" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "del" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", "datetime", "cite"),
+ "ins" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", "datetime", "cite"),
+ "sub" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "sup" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "ol" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", "type", "start"),
+ "br" => array("CLASS", "ID", "STYLE", "title", "clear"),
+ "cite" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "var" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "dl" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "ruby" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "rt" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "rp" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "dt" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "dl" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "em" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "strong" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "i" => array("CLASS", "ID", "STYLE", "lang", "dir", "title"),
+ "thead" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", 'align', 'char', 'charoff', 'valign'),
+ "tfoot" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", 'align', 'char', 'charoff', 'valign'),
+ "tbody" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", 'align', 'char', 'charoff', 'valign'),
+ "colgroup" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", 'align', 'char', 'charoff', 'valign', 'span', 'width'),
+ "col" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", 'align', 'char', 'charoff', 'valign', 'span', 'width'),
+ "pre" => array("CLASS", "ID", "STYLE", "lang", "dir", "title", "width"),
+
+ // extension tags that accept parameters:
+ "sort" => array("order", "class"),
+ "ref" => array("name"),
+ "categorytree" => array("hideroot", "mode", "style"),
+ );
+
+ // The types of the HTML that we will be testing were defined above
+ // Note: this needs to be initialized later to be equal to: array_keys(wikiFuzz::$data);
+ // as such, it also needs to also be publicly modifiable.
+ public static $types;
+
+
+ // Some attribute values.
+ static private $other = array("&","=",":","?","\"","\n","%n%n%n%n%n%n%n%n%n%n%n%n","\\");
+ static private $ints = array(
+ // various numbers
+ "0","-1","127","-7897","89000","808080","90928345",
+ "0xfffffff","ffff",
+
+ // Different ways of saying: '
+ "&#0000039;", // Long UTF-8 Unicode encoding
+ "&#39;", // dec version.
+ "&#x27;", // hex version.
+ "&#xA7;", // malformed hex variant, MSB not zero.
+
+ // Different ways of saying: "
+ "&#0000034;", // Long UTF-8 Unicode encoding
+ "&#34;",
+ "&#x22;", // hex version.
+ "&#xA2;", // malformed hex variant, MSB not zero.
+
+ // Different ways of saying: <
+ "<",
+ "&#0000060", // Long UTF-8 Unicode encoding without semicolon (Mediawiki wants the colon)
+ "&#0000060;", // Long UTF-8 Unicode encoding with semicolon
+ "&#60;",
+ "&#x3C;", // hex version.
+ "&#xBC;", // malformed hex variant, MSB not zero.
+ "&#x0003C;", // mid-length hex version
+ "&#X00003C;", // slightly longer hex version, with capital "X"
+
+ // Different ways of saying: >
+ ">",
+ "&#0000062;", // Long UTF-8 Unicode encoding
+ "&#62;",
+ "&#x3E;", // hex version.
+ "&#xBE;", // malformed variant, MSB not zero.
+
+ // Different ways of saying: [
+ "&#0000091;", // Long UTF-8 Unicode encoding
+ "&#91;",
+ "&#x5B;", // hex version.
+
+ // Different ways of saying: {{
+ "&#0000123;&#0000123;", // Long UTF-8 Unicode encoding
+ "&#123;&#123;",
+ "&#x7B;&#x7B;", // hex version.
+
+ // Different ways of saying: |
+ "&#0000124;", // Long UTF-8 Unicode encoding
+ "&#124;",
+ "&#x7C;", // hex version.
+ "&#xFC;", // malformed hex variant, MSB not zero.
+
+ // a "lignature" - http://www.robinlionheart.com/stds/html4/spchars#ligature
+ "&zwnj;"
+ );
+
+ // Defines various wiki-related bits of syntax, that can potentially cause
+ // MediaWiki to do something other than just print that literal text.
+ static private $ext = array(
+ // links, templates, parameters.
+ "[[", "]]", "{{", "}}", "|", "[", "]", "{{{", "}}}", "|]]",
+
+ // wiki tables.
+ "\n{|", "\n|}",
+ "!",
+ "\n!",
+ "!!",
+ "||",
+ "\n|-", "| ", "\n|",
+
+ // section headings.
+ "=", "==", "===", "====", "=====", "======",
+
+ // lists (ordered and unordered) and indentation.
+ "\n*", "*", "\n:", ":",
+ "\n#", "#",
+
+ // definition lists (dl, dt, dd), newline, and newline with pre, and a tab.
+ "\n;", ";", "\n ",
+
+ // Whitespace: newline, tab, space.
+ "\n", "\t", " ",
+
+ // Some XSS attack vectors from http://ha.ckers.org/xss.html
+ "&#x09;", // tab
+ "&#x0A;", // newline
+ "&#x0D;", // carriage return
+ "\0", // null character
+ " &#14; ", // spaces and meta characters
+ "'';!--\"<XSS>=&{()}", // compact injection of XSS & SQL tester
+
+ // various NULL fields
+ "%00",
+ "&#00;",
+ "\0",
+
+ // horizontal rule.
+ "-----", "\n-----",
+
+ // signature, redirect, bold, italics.
+ "~~~~", "#REDIRECT [[", "'''", "''",
+
+ // comments.
+ "<!--", "-->",
+
+ // quotes.
+ "\"", "'",
+
+ // tag start and tag end.
+ "<", ">",
+
+ // implicit link creation on URIs.
+ "http://",
+ "https://",
+ "ftp://",
+ "irc://",
+ "news:",
+ 'gopher://',
+ 'telnet://',
+ 'nntp://',
+ 'worldwind://',
+ 'mailto:',
+
+ // images.
+ "[[image:",
+ ".gif",
+ ".png",
+ ".jpg",
+ ".jpeg",
+ 'thumbnail=',
+ 'thumbnail',
+ 'thumb=',
+ 'thumb',
+ 'right',
+ 'none',
+ 'left',
+ 'framed',
+ 'frame',
+ 'enframed',
+ 'centre',
+ 'center',
+ "Image:",
+ "[[:Image",
+ 'px',
+
+ // misc stuff to throw at the Parser.
+ '%08X',
+ '/',
+ ":x{|",
+ "\n|+",
+ "<noinclude>",
+ "</noinclude>",
+ " \302\273",
+ " :",
+ " !",
+ " ;",
+ "\302\253",
+ "[[category:",
+ "?=",
+ "(",
+ ")",
+ "]]]",
+ "../",
+ "{{{{",
+ "}}}}",
+ "[[Special:",
+ "<includeonly>",
+ "</includeonly>",
+ "<!--MWTEMPLATESECTION=",
+ '<!--MWTOC-->',
+
+ // implicit link creation on booknum, RFC, and PubMed ID usage (both with and without IDs)
+ "ISBN 2",
+ "RFC 000",
+ "PMID 000",
+ "ISBN ",
+ "RFC ",
+ "PMID ",
+
+ // magic words:
+ '__NOTOC__',
+ '__FORCETOC__',
+ '__NOEDITSECTION__',
+ '__START__',
+ '__NOTITLECONVERT__',
+ '__NOCONTENTCONVERT__',
+ '__END__',
+ '__TOC__',
+ '__NOTC__',
+ '__NOCC__',
+ "__FORCETOC__",
+ "__NEWSECTIONLINK__",
+ "__NOGALLERY__",
+
+ // more magic words / internal templates.
+ '{{PAGENAME}}',
+ '{{PAGENAMEE}}',
+ '{{NAMESPACE}}',
+ "{{MSG:",
+ "}}",
+ "{{MSGNW:",
+ "}}",
+ "{{INT:",
+ "}}",
+ '{{SITENAME}}',
+ "{{NS:",
+ "}}",
+ "{{LOCALURL:",
+ "}}",
+ "{{LOCALURLE:",
+ "}}",
+ "{{SCRIPTPATH}}",
+ "{{GRAMMAR:gentiv|",
+ "}}",
+ "{{REVISIONID}}",
+ "{{SUBPAGENAME}}",
+ "{{SUBPAGENAMEE}}",
+ "{{ns:0}}",
+ "{{fullurle:",
+ "}}",
+ "{{subst:",
+ "}}",
+ "{{UCFIRST:",
+ "}}",
+ "{{UC:",
+ '{{SERVERNAME}}',
+ '{{SERVER}}',
+ "{{RAW:",
+ "}}",
+ "{{PLURAL:",
+ "}}",
+ "{{LCFIRST:",
+ "}}",
+ "{{LC:",
+ "}}",
+ '{{CURRENTWEEK}}',
+ '{{CURRENTDOW}}',
+ "{{INT:{{LC:contribs-showhideminor}}|",
+ "}}",
+ "{{INT:googlesearch|",
+ "}}",
+ "{{BASEPAGENAME}}",
+ "{{CONTENTLANGUAGE}}",
+ "{{PAGESINNAMESPACE:}}",
+ "{{#language:",
+ "}}",
+
+ // Some raw link for magic words.
+ "{{NUMBEROFPAGES:R",
+ "}}",
+ "{{NUMBEROFUSERS:R",
+ "}}",
+ "{{NUMBEROFARTICLES:R",
+ "}}",
+ "{{NUMBEROFFILES:R",
+ "}}",
+ "{{NUMBEROFADMINS:R",
+ "}}",
+ "{{padleft:",
+ "}}",
+ "{{padright:",
+ "}}",
+
+ // internal Math "extension":
+ "<math>",
+ "</math>",
+
+ // Parser extension functions:
+ "{{#expr:",
+ "{{#if:",
+ "{{#ifeq:",
+ "{{#ifexist:",
+ "{{#ifexpr:",
+ "{{#switch:",
+ "{{#time:",
+ "}}",
+
+ // references table for the Cite extension.
+ "<references/>",
+
+ // Internal Parser tokens - try inserting some of these.
+ "UNIQ25f46b0524f13e67NOPARSE",
+ "UNIQ17197916557e7cd6-HTMLCommentStrip46238afc3bb0cf5f00000002",
+ "\x07UNIQ17197916557e7cd6-HTMLCommentStrip46238afc3bb0cf5f00000002-QINU",
+
+ // Inputbox extension:
+ "<inputbox>\ntype=search\nsearchbuttonlabel=\n",
+ "</inputbox>",
+
+ // charInsert extension:
+ "<charInsert>",
+ "</charInsert>",
+
+ // wikiHiero extension:
+ "<hiero>",
+ "</hiero>",
+
+ // Image gallery:
+ "<gallery>",
+ "</gallery>",
+
+ // FixedImage:
+ "<fundraising/>",
+
+ // Timeline extension: currently untested.
+
+ // Nowiki:
+ "<nOwIkI>",
+ "</nowiki>",
+
+ // an external image to test the external image displaying code
+ "http://debian.org/Pics/debian.png",
+ );
+
+ /**
+ ** Randomly returns one element of the input array.
+ */
+ static public function chooseInput(array $input) {
+ $randindex = wikiFuzz::randnum(count($input) - 1);
+ return $input[$randindex];
+ }
+
+ // Max number of parameters for HTML attributes.
+ static private $maxparams = 10;
+
+ /**
+ ** Returns random number between finish and start.
+ */
+ static public function randnum($finish,$start=0) {
+ return mt_rand($start,$finish);
+ }
+
+ /**
+ ** Returns a mix of random text and random wiki syntax.
+ */
+ static private function randstring() {
+ $thestring = "";
+
+ for ($i=0; $i<40; $i++) {
+ $what = wikiFuzz::randnum(1);
+
+ if ($what == 0) { // include some random wiki syntax
+ $which = wikiFuzz::randnum(count(wikiFuzz::$ext) - 1);
+ $thestring .= wikiFuzz::$ext[$which];
+ }
+ else { // include some random text
+ $char = INCLUDE_BINARY
+ // Decimal version:
+ // "&#" . wikiFuzz::randnum(255) . ";"
+ // Hex version:
+ ? "&#x" . str_pad(dechex(wikiFuzz::randnum(255)), wikiFuzz::randnum(2, 7), "0", STR_PAD_LEFT) . ";"
+ : chr(wikiFuzz::randnum(126,32));
+
+ $length = wikiFuzz::randnum(8);
+ $thestring .= str_repeat ($char, $length);
+ }
+ }
+ return $thestring;
+ }
+
+ /**
+ ** Returns either random text, or random wiki syntax, or random data from "ints",
+ ** or random data from "other".
+ */
+ static private function makestring() {
+ $what = wikiFuzz::randnum(2);
+ if ($what == 0) {
+ return wikiFuzz::randstring();
+ }
+ elseif ($what == 1) {
+ return wikiFuzz::$ints[wikiFuzz::randnum(count(wikiFuzz::$ints) - 1)];
+ }
+ else {
+ return wikiFuzz::$other[wikiFuzz::randnum(count(wikiFuzz::$other) - 1)];
+ }
+ }
+
+
+ /**
+ ** Strips out the stuff that Mediawiki balks at in a page's title.
+ ** Implementation copied/pasted from cleanupTable.inc & cleanupImages.php
+ */
+ static public function makeTitleSafe($str) {
+ $legalTitleChars = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF";
+ return preg_replace_callback(
+ "/([^$legalTitleChars])/",
+ create_function(
+ // single quotes are essential here,
+ // or alternative escape all $ as \$
+ '$matches',
+ 'return sprintf( "\\x%02x", ord( $matches[1] ) );'
+ ),
+ $str );
+ }
+
+ /**
+ ** Returns a string of fuzz text.
+ */
+ static private function loop() {
+ switch ( wikiFuzz::randnum(3) ) {
+ case 1: // an opening tag, with parameters.
+ $string = "";
+ $i = wikiFuzz::randnum(count(wikiFuzz::$types) - 1);
+ $t = wikiFuzz::$types[$i];
+ $arr = wikiFuzz::$data[$t];
+ $string .= "<" . $t . " ";
+ $num_params = min(wikiFuzz::$maxparams, count($arr));
+ for ($z=0; $z<$num_params; $z++) {
+ $badparam = $arr[wikiFuzz::randnum(count($arr) - 1)];
+ $badstring = wikiFuzz::makestring();
+ $string .= $badparam . "=" . wikiFuzz::getRandQuote() . $badstring . wikiFuzz::getRandQuote() . " ";
+ }
+ $string .= ">\n";
+ return $string;
+ case 2: // a closing tag.
+ $i = wikiFuzz::randnum(count(wikiFuzz::$types) - 1);
+ return "</". wikiFuzz::$types[$i] . ">";
+ case 3: // a random string, between tags.
+ return wikiFuzz::makeString();
+ }
+ return ""; // catch-all, should never be called.
+ }
+
+ /**
+ ** Returns one of the three styles of random quote: ', ", and nothing.
+ */
+ static private function getRandQuote() {
+ switch ( wikiFuzz::randnum(3) ) {
+ case 1 : return "'";
+ case 2 : return "\"";
+ default: return "";
+ }
+ }
+
+ /**
+ ** Returns fuzz text, with the parameter indicating approximately how many lines of text you want.
+ */
+ static public function makeFuzz($maxtypes = 2) {
+ $page = "";
+ for ($k=0; $k<$maxtypes; $k++) {
+ $page .= wikiFuzz::loop();
+ }
+ return $page;
+ }
+}
+
+
+//////// MEDIAWIKI PAGES TO TEST, AND HOW TO TEST THEM ///////
+
+/**
+ ** A page test has just these things:
+ ** 1) Form parameters.
+ ** 2) the URL we are going to test those parameters on.
+ ** 3) Any cookies required for the test.
+ ** Declared abstract because it should be extended by a class
+ ** that supplies these parameters.
+ */
+abstract class pageTest {
+ protected $params;
+ protected $pagePath;
+ protected $cookie = "";
+
+ public function getParams() {
+ return $this->params;
+ }
+
+ public function getPagePath() {
+ return $this->pagePath;
+ }
+
+ public function getCookie() {
+ return $this->cookie;
+ }
+}
+
+
+/**
+ ** a page test for the "Edit" page. Tests Parser.php and Sanitizer.php.
+ */
+class editPageTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=WIKIFUZZ";
+
+ $this->params = array (
+ "action" => "submit",
+ "wpMinoredit" => wikiFuzz::makeFuzz(2),
+ "wpPreview" => wikiFuzz::makeFuzz(2),
+ "wpSection" => wikiFuzz::makeFuzz(2),
+ "wpEdittime" => wikiFuzz::makeFuzz(2),
+ "wpSummary" => wikiFuzz::makeFuzz(2),
+ "wpScrolltop" => wikiFuzz::makeFuzz(2),
+ "wpStarttime" => wikiFuzz::makeFuzz(2),
+ "wpAutoSummary" => wikiFuzz::makeFuzz(2),
+ "wpTextbox1" => wikiFuzz::makeFuzz(40) // the main wiki text, need lots of this.
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpSection"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpEdittime"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpSummary"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpScrolltop"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpStarttime"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpAutoSummary"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpTextbox1"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Listusers".
+ */
+class listusersTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Listusers";
+
+ $this->params = array (
+ "title" => wikiFuzz::makeFuzz(2),
+ "group" => wikiFuzz::makeFuzz(2),
+ "username" => wikiFuzz::makeFuzz(2),
+ "Go" => wikiFuzz::makeFuzz(2),
+ "limit" => wikiFuzz::chooseInput( array("0", "-1", "---'----------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "offset" => wikiFuzz::chooseInput( array("0", "-1", "--------'-----0", "+1", "81343242346234234", wikiFuzz::makeFuzz(2)) )
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Search".
+ */
+class searchTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Search";
+
+ $this->params = array (
+ "action" => "index.php/Special:Search",
+ "ns0" => wikiFuzz::makeFuzz(2),
+ "ns1" => wikiFuzz::makeFuzz(2),
+ "ns2" => wikiFuzz::makeFuzz(2),
+ "ns3" => wikiFuzz::makeFuzz(2),
+ "ns4" => wikiFuzz::makeFuzz(2),
+ "ns5" => wikiFuzz::makeFuzz(2),
+ "ns6" => wikiFuzz::makeFuzz(2),
+ "ns7" => wikiFuzz::makeFuzz(2),
+ "ns8" => wikiFuzz::makeFuzz(2),
+ "ns9" => wikiFuzz::makeFuzz(2),
+ "ns10" => wikiFuzz::makeFuzz(2),
+ "ns11" => wikiFuzz::makeFuzz(2),
+ "ns12" => wikiFuzz::makeFuzz(2),
+ "ns13" => wikiFuzz::makeFuzz(2),
+ "ns14" => wikiFuzz::makeFuzz(2),
+ "ns15" => wikiFuzz::makeFuzz(2),
+ "redirs" => wikiFuzz::makeFuzz(2),
+ "search" => wikiFuzz::makeFuzz(2),
+ "offset" => wikiFuzz::chooseInput( array("", "0", "-1", "--------'-----0", "+1", "81343242346234234", wikiFuzz::makeFuzz(2)) ),
+ "fulltext" => wikiFuzz::chooseInput( array("", "0", "1", "--------'-----0", "+1", wikiFuzz::makeFuzz(2)) ),
+ "searchx" => wikiFuzz::chooseInput( array("", "0", "1", "--------'-----0", "+1", wikiFuzz::makeFuzz(2)) )
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Recentchanges".
+ */
+class recentchangesTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Recentchanges";
+
+ $this->params = array (
+ "action" => wikiFuzz::makeFuzz(2),
+ "title" => wikiFuzz::makeFuzz(2),
+ "namespace" => wikiFuzz::chooseInput( range(-1, 15) ),
+ "Go" => wikiFuzz::makeFuzz(2),
+ "invert" => wikiFuzz::chooseInput( array("-1", "---'----------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "hideanons" => wikiFuzz::chooseInput( array("-1", "------'-------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ 'limit' => wikiFuzz::chooseInput( array("0", "-1", "---------'----0", "+1", "81340909772349234", wikiFuzz::makeFuzz(2)) ),
+ "days" => wikiFuzz::chooseInput( array("-1", "----------'---0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "hideminor" => wikiFuzz::chooseInput( array("-1", "-----------'--0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "hidebots" => wikiFuzz::chooseInput( array("-1", "---------'----0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "hideliu" => wikiFuzz::chooseInput( array("-1", "-------'------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "hidepatrolled" => wikiFuzz::chooseInput( array("-1", "-----'--------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "hidemyself" => wikiFuzz::chooseInput( array("-1", "--'-----------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ 'categories_any'=> wikiFuzz::chooseInput( array("-1", "--'-----------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ 'categories' => wikiFuzz::chooseInput( array("-1", "--'-----------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ 'feed' => wikiFuzz::chooseInput( array("-1", "--'-----------0", "+1", "8134", wikiFuzz::makeFuzz(2)) )
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Prefixindex".
+ */
+class prefixindexTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Prefixindex";
+
+ $this->params = array (
+ "title" => "Special:Prefixindex",
+ "namespace" => wikiFuzz::randnum(-10,101),
+ "Go" => wikiFuzz::makeFuzz(2)
+ );
+
+ // sometimes we want 'prefix', sometimes we want 'from', and sometimes we want nothing.
+ if (wikiFuzz::randnum(3) == 0) {
+ $this->params["prefix"] = wikiFuzz::chooseInput( array("-1", "-----'--------0", "+++--+1",
+ wikiFuzz::randnum(-10,8134), wikiFuzz::makeFuzz(2)) );
+ }
+ if (wikiFuzz::randnum(3) == 0) {
+ $this->params["from"] = wikiFuzz::chooseInput( array("-1", "-----'--------0", "+++--+1",
+ wikiFuzz::randnum(-10,8134), wikiFuzz::makeFuzz(2)) );
+ }
+ }
+}
+
+
+/**
+ ** a page test for "Special:MIMEsearch".
+ */
+class mimeSearchTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:MIMEsearch";
+
+ $this->params = array (
+ "action" => "/wiki/index.php/Special:MIMEsearch",
+ "mime" => wikiFuzz::makeFuzz(3),
+ 'limit' => wikiFuzz::chooseInput( array("0", "-1", "-------'------0", "+1", "81342321351235325", wikiFuzz::makeFuzz(2)) ),
+ 'offset' => wikiFuzz::chooseInput( array("0", "-1", "-----'--------0", "+1", "81341231235365252234324", wikiFuzz::makeFuzz(2)) )
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Log".
+ */
+class specialLogTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Log";
+
+ $this->params = array (
+ "type" => wikiFuzz::chooseInput( array("", wikiFuzz::makeFuzz(2)) ),
+ "par" => wikiFuzz::makeFuzz(2),
+ "user" => wikiFuzz::makeFuzz(2),
+ "page" => wikiFuzz::makeFuzz(2),
+ "from" => wikiFuzz::makeFuzz(2),
+ "until" => wikiFuzz::makeFuzz(2),
+ "title" => wikiFuzz::makeFuzz(2)
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Userlogin", with a successful login.
+ */
+class successfulUserLoginTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Userlogin&action=submitlogin&type=login&returnto=" . wikiFuzz::makeFuzz(2);
+
+ $this->params = array (
+ "wpName" => USER_ON_WIKI,
+ // sometimes real password, sometimes not:
+ 'wpPassword' => wikiFuzz::chooseInput( array( wikiFuzz::makeFuzz(2), USER_PASSWORD ) ),
+ 'wpRemember' => wikiFuzz::makeFuzz(2)
+ );
+
+ $this->cookie = "wikidb_session=" . wikiFuzz::chooseInput( array("1" , wikiFuzz::makeFuzz(2) ) );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Userlogin".
+ */
+class userLoginTest extends pageTest {
+ function __construct() {
+
+ $this->pagePath = "index.php/Special:Userlogin";
+
+ $this->params = array (
+ 'wpRetype' => wikiFuzz::makeFuzz(2),
+ 'wpRemember' => wikiFuzz::makeFuzz(2),
+ 'wpRealName' => wikiFuzz::makeFuzz(2),
+ 'wpPassword' => wikiFuzz::makeFuzz(2),
+ 'wpName' => wikiFuzz::makeFuzz(2),
+ 'wpMailmypassword'=> wikiFuzz::makeFuzz(2),
+ 'wpLoginattempt' => wikiFuzz::makeFuzz(2),
+ 'wpEmail' => wikiFuzz::makeFuzz(2),
+ 'wpDomain' => wikiFuzz::chooseInput( array("", "local", wikiFuzz::makeFuzz(2)) ),
+ 'wpCreateaccountMail' => wikiFuzz::chooseInput( array("", wikiFuzz::makeFuzz(2)) ),
+ 'wpCreateaccount' => wikiFuzz::chooseInput( array("", wikiFuzz::makeFuzz(2)) ),
+ 'wpCookieCheck' => wikiFuzz::chooseInput( array("", wikiFuzz::makeFuzz(2)) ),
+ 'type' => wikiFuzz::chooseInput( array("signup", "login", "", wikiFuzz::makeFuzz(2)) ),
+ 'returnto' => wikiFuzz::makeFuzz(2),
+ 'action' => wikiFuzz::chooseInput( array("", "submitlogin", wikiFuzz::makeFuzz(2)) )
+ );
+
+ $this->cookie = "wikidb_session=" . wikiFuzz::chooseInput( array("1" , wikiFuzz::makeFuzz(2) ) );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Ipblocklist" (also includes unblocking)
+ */
+class ipblocklistTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Ipblocklist";
+
+ $this->params = array (
+ 'wpUnblockAddress'=> wikiFuzz::makeFuzz(2),
+ 'ip' => wikiFuzz::chooseInput( array("20398702394", "", "Nickj2", wikiFuzz::makeFuzz(2),
+ // something like an IP address, sometimes invalid:
+ ( wikiFuzz::randnum(300,-20) . "." . wikiFuzz::randnum(300,-20) . "."
+ . wikiFuzz::randnum(300,-20) . "." .wikiFuzz::randnum(300,-20) ) ) ),
+ 'id' => wikiFuzz::makeFuzz(2),
+ 'wpUnblockReason' => wikiFuzz::makeFuzz(2),
+ 'action' => wikiFuzz::chooseInput( array(wikiFuzz::makeFuzz(2), "success", "submit", "unblock") ),
+ 'wpEditToken' => wikiFuzz::makeFuzz(2),
+ 'wpBlock' => wikiFuzz::chooseInput( array(wikiFuzz::makeFuzz(2), "") ),
+ 'limit' => wikiFuzz::chooseInput( array("0", "-1", "--------'-----0", "+1",
+ "09700982312351132098234", wikiFuzz::makeFuzz(2)) ),
+ 'offset' => wikiFuzz::chooseInput( array("0", "-1", "------'-------0", "+1",
+ "09700980982341535324234234", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["action"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["ip"]);
+ if (wikiFuzz::randnum(2) == 0) unset($this->params["id"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["wpUnblockAddress"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Newimages".
+ */
+class newImagesTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Newimages";
+
+ $this->params = array (
+ 'hidebots' => wikiFuzz::chooseInput( array(wikiFuzz::makeFuzz(2), "1", "", "-1") ),
+ 'wpIlMatch' => wikiFuzz::makeFuzz(2),
+ 'until' => wikiFuzz::makeFuzz(2),
+ 'from' => wikiFuzz::makeFuzz(2)
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["until"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["from"]);
+ }
+}
+
+
+/**
+ ** a page test for the "Special:Imagelist" page.
+ */
+class imagelistTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Imagelist";
+
+ $this->params = array (
+ 'sort' => wikiFuzz::chooseInput( array("bysize", "byname" , "bydate", wikiFuzz::makeFuzz(2)) ),
+ 'limit' => wikiFuzz::chooseInput( array("0", "-1", "--------'-----0", "+1", "09700982312351132098234", wikiFuzz::makeFuzz(2)) ),
+ 'offset' => wikiFuzz::chooseInput( array("0", "-1", "------'-------0", "+1", "09700980982341535324234234", wikiFuzz::makeFuzz(2)) ),
+ 'wpIlMatch' => wikiFuzz::makeFuzz(2)
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Export".
+ */
+class specialExportTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Export";
+
+ $this->params = array (
+ 'action' => wikiFuzz::chooseInput( array("submit", "", wikiFuzz::makeFuzz(2)) ),
+ 'pages' => wikiFuzz::makeFuzz(2),
+ 'curonly' => wikiFuzz::chooseInput( array("", "0", "-1", wikiFuzz::makeFuzz(2)) ),
+ 'listauthors' => wikiFuzz::chooseInput( array("", "0", "-1", wikiFuzz::makeFuzz(2)) ),
+ 'history' => wikiFuzz::chooseInput( array("0", "-1", "------'-------0", "+1", "09700980982341535324234234", wikiFuzz::makeFuzz(2)) ),
+
+ );
+
+ // For the time being, need to disable "submit" action as Tidy barfs on MediaWiki's XML export.
+ if ($this->params['action'] == 'submit') $this->params['action'] = '';
+
+ // Sometimes remove the history field.
+ if (wikiFuzz::randnum(2) == 0) unset($this->params["history"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Booksources".
+ */
+class specialBooksourcesTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Booksources";
+
+ $this->params = array (
+ 'go' => wikiFuzz::makeFuzz(2),
+ // ISBN codes have to contain some semi-numeric stuff or will be ignored:
+ 'isbn' => "0X0" . wikiFuzz::makeFuzz(2)
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Allpages".
+ */
+class specialAllpagesTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special%3AAllpages";
+
+ $this->params = array (
+ 'from' => wikiFuzz::makeFuzz(2),
+ 'namespace' => wikiFuzz::chooseInput( range(-1, 15) ),
+ 'go' => wikiFuzz::makeFuzz(2)
+ );
+ }
+}
+
+
+/**
+ ** a page test for the page History.
+ */
+class pageHistoryTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Main_Page&action=history";
+
+ $this->params = array (
+ 'limit' => wikiFuzz::chooseInput( array("-1", "0", "-------'------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ 'offset' => wikiFuzz::chooseInput( array("-1", "0", "------'-------0", "+1", "9823412312312412435", wikiFuzz::makeFuzz(2)) ),
+ "go" => wikiFuzz::chooseInput( array("first", "last", wikiFuzz::makeFuzz(2)) ),
+ "dir" => wikiFuzz::chooseInput( array("prev", "next", wikiFuzz::makeFuzz(2)) ),
+ "diff" => wikiFuzz::chooseInput( array("-1", "--------'-----0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "oldid" => wikiFuzz::chooseInput( array("prev", "-1", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ "feed" => wikiFuzz::makeFuzz(2)
+ );
+ }
+}
+
+
+/**
+ ** a page test for the Special:Contributions".
+ */
+class contributionsTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Contributions/" . USER_ON_WIKI;
+
+ $this->params = array (
+ 'target' => wikiFuzz::chooseInput( array(wikiFuzz::makeFuzz(2), "newbies") ),
+ 'namespace' => wikiFuzz::chooseInput( array(-1, 15, 1, wikiFuzz::makeFuzz(2)) ),
+ 'offset' => wikiFuzz::chooseInput( array("0", "-1", "------'-------0", "+1", "982342131232131231241", wikiFuzz::makeFuzz(2)) ),
+ 'bot' => wikiFuzz::chooseInput( array("", "-1", "0", "1", wikiFuzz::makeFuzz(2)) ),
+ 'go' => wikiFuzz::chooseInput( array("-1", 'prev', 'next', wikiFuzz::makeFuzz(2)) )
+ );
+ }
+}
+
+
+/**
+ ** a page test for viewing a normal page, whilst posting various params.
+ */
+class viewPageTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Main_Page";
+
+ $this->params = array (
+ "useskin" => wikiFuzz::chooseInput( array("chick", "cologneblue", "myskin",
+ "nostalgia", "simple", "standard", wikiFuzz::makeFuzz(2)) ),
+ "uselang" => wikiFuzz::chooseInput( array( wikiFuzz::makeFuzz(2),
+ "ab", "af", "an", "ar", "arc", "as", "ast", "av", "ay", "az", "ba",
+ "bat-smg", "be", "bg", "bm", "bn", "bo", "bpy", "br", "bs", "ca",
+ "ce", "cs", "csb", "cv", "cy", "da", "de", "dv", "dz", "el", "en",
+ "eo", "es", "et", "eu", "fa", "fi", "fo", "fr", "fur", "fy", "ga",
+ "gn", "gsw", "gu", "he", "hi", "hr", "hu", "ia", "id", "ii", "is",
+ "it", "ja", "jv", "ka", "km", "kn", "ko", "ks", "ku", "kv", "la",
+ "li", "lo", "lt", "lv", "mk", "ml", "ms", "nah", "nap", "nds",
+ "nds-nl", "nl", "nn", "no", "non", "nv", "oc", "or", "os", "pa",
+ "pl", "pms", "ps", "pt", "pt-br", "qu", "rmy", "ro", "ru", "sc",
+ "sd", "sk", "sl", "sq", "sr", "sr-ec", "sr-el", "sr-jc", "sr-jl",
+ "su", "sv", "ta", "te", "th", "tlh", "tr", "tt", "ty", "tyv", "udm",
+ "ug", "uk", "ur", "utf8", "vec", "vi", "wa", "xal", "yi", "za",
+ "zh", "zh-cn", "zh-hk", "zh-sg", "zh-tw", "zh-tw") ),
+ "returnto" => wikiFuzz::makeFuzz(2),
+ "feed" => wikiFuzz::chooseInput( array("atom", "rss", wikiFuzz::makeFuzz(2)) ),
+ "rcid" => wikiFuzz::makeFuzz(2),
+ "action" => wikiFuzz::chooseInput( array("view", "raw", "render", wikiFuzz::makeFuzz(2), "markpatrolled") ),
+ "printable" => wikiFuzz::makeFuzz(2),
+ "oldid" => wikiFuzz::makeFuzz(2),
+ "redirect" => wikiFuzz::makeFuzz(2),
+ "diff" => wikiFuzz::makeFuzz(2),
+ "search" => wikiFuzz::makeFuzz(2),
+ "rdfrom" => wikiFuzz::makeFuzz(2), // things from Article.php from here on:
+ "token" => wikiFuzz::makeFuzz(2),
+ "tbid" => wikiFuzz::makeFuzz(2),
+ "action" => wikiFuzz::chooseInput( array("purge", wikiFuzz::makeFuzz(2)) ),
+ "wpReason" => wikiFuzz::makeFuzz(2),
+ "wpEditToken" => wikiFuzz::makeFuzz(2),
+ "from" => wikiFuzz::makeFuzz(2),
+ "bot" => wikiFuzz::makeFuzz(2),
+ "summary" => wikiFuzz::makeFuzz(2),
+ "direction" => wikiFuzz::chooseInput( array("next", "prev", wikiFuzz::makeFuzz(2)) ),
+ "section" => wikiFuzz::makeFuzz(2),
+ "preload" => wikiFuzz::makeFuzz(2),
+
+ );
+
+ // Tidy does not know how to valid atom or rss, so exclude from testing for the time being.
+ if ($this->params["feed"] == "atom") unset($this->params["feed"]);
+ else if ($this->params["feed"] == "rss") unset($this->params["feed"]);
+
+ // Raw pages cannot really be validated
+ if ($this->params["action"] == "raw") unset($this->params["action"]);
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["rcid"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["diff"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["rdfrom"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["oldid"]);
+
+ // usually don't want action == purge.
+ if (wikiFuzz::randnum(6) > 1) unset($this->params["action"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Allmessages".
+ */
+class specialAllmessagesTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Allmessages";
+
+ // only really has one parameter
+ $this->params = array (
+ "ot" => wikiFuzz::chooseInput( array("php", "html", wikiFuzz::makeFuzz(2)) )
+ );
+ }
+}
+
+/**
+ ** a page test for "Special:Newpages".
+ */
+class specialNewpages extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Newpages";
+
+ $this->params = array (
+ "namespace" => wikiFuzz::chooseInput( range(-1, 15) ),
+ "feed" => wikiFuzz::chooseInput( array("atom", "rss", wikiFuzz::makeFuzz(2)) ),
+ 'limit' => wikiFuzz::chooseInput( array("-1", "0", "-------'------0", "+1", "8134", wikiFuzz::makeFuzz(2)) ),
+ 'offset' => wikiFuzz::chooseInput( array("-1", "0", "------'-------0", "+1", "9823412312312412435", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // Tidy does not know how to valid atom or rss, so exclude from testing for the time being.
+ if ($this->params["feed"] == "atom") unset($this->params["feed"]);
+ else if ($this->params["feed"] == "rss") unset($this->params["feed"]);
+ }
+}
+
+/**
+ ** a page test for "redirect.php"
+ */
+class redirectTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "redirect.php";
+
+ $this->params = array (
+ "wpDropdown" => wikiFuzz::makeFuzz(2)
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpDropdown"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Confirmemail"
+ */
+class confirmEmail extends pageTest {
+ function __construct() {
+ // sometimes we send a bogus confirmation code, and sometimes we don't.
+ $this->pagePath = "index.php?title=Special:Confirmemail" . wikiFuzz::chooseInput( array("", "/" . wikiFuzz::makeTitleSafe(wikiFuzz::makeFuzz(1)) ) );
+
+ $this->params = array (
+ "token" => wikiFuzz::makeFuzz(2)
+ );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Watchlist"
+ ** Note: this test would be better if we were logged in.
+ */
+class watchlistTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Watchlist";
+
+ $this->params = array (
+ "remove" => wikiFuzz::chooseInput( array("Remove checked items from watchlist", wikiFuzz::makeFuzz(2))),
+ 'days' => wikiFuzz::chooseInput( array(0, -1, -230, "--", 3, 9, wikiFuzz::makeFuzz(2)) ),
+ 'hideOwn' => wikiFuzz::chooseInput( array("", "0", "1", wikiFuzz::makeFuzz(2)) ),
+ 'hideBots' => wikiFuzz::chooseInput( array("", "0", "1", wikiFuzz::makeFuzz(2)) ),
+ 'namespace'=> wikiFuzz::chooseInput( array("", "0", "1", wikiFuzz::makeFuzz(2)) ),
+ 'action' => wikiFuzz::chooseInput( array("submit", "clear", wikiFuzz::makeFuzz(2)) ),
+ 'id[]' => wikiFuzz::makeFuzz(2),
+ 'edit' => wikiFuzz::makeFuzz(2),
+ 'token' => wikiFuzz::chooseInput( array("", "1243213", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // sometimes we specifiy "reset", and sometimes we don't.
+ if (wikiFuzz::randnum(3) == 0) $this->params["reset"] = wikiFuzz::chooseInput( array("", "0", "1", wikiFuzz::makeFuzz(2)) );
+ }
+}
+
+
+/**
+ ** a page test for "Special:Blockme"
+ */
+class specialBlockmeTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Blockme";
+
+ $this->params = array ( );
+
+ // sometimes we specify "ip", and sometimes we don't.
+ if (wikiFuzz::randnum(1) == 0) {
+ $this->params["ip"] = wikiFuzz::chooseInput( array("10.12.41.213", wikiFuzz::randnum(-10,8134), wikiFuzz::makeFuzz(2)) );
+ }
+ }
+}
+
+
+/**
+ ** a page test for "Special:Movepage"
+ */
+class specialMovePage extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Movepage";
+
+ $this->params = array (
+ "action" => wikiFuzz::chooseInput( array("success", "submit", "", wikiFuzz::makeFuzz(2)) ),
+ 'wpEditToken' => wikiFuzz::chooseInput( array('', 0, 34987987, wikiFuzz::makeFuzz(2)) ),
+ 'target' => wikiFuzz::chooseInput( array("x", wikiFuzz::makeTitleSafe(wikiFuzz::makeFuzz(2)) ) ),
+ 'wpOldTitle' => wikiFuzz::chooseInput( array("z", wikiFuzz::makeTitleSafe(wikiFuzz::makeFuzz(2)), wikiFuzz::makeFuzz(2) ) ),
+ 'wpNewTitle' => wikiFuzz::chooseInput( array("y", wikiFuzz::makeTitleSafe(wikiFuzz::makeFuzz(2)), wikiFuzz::makeFuzz(2) ) ),
+ 'wpReason' => wikiFuzz::chooseInput( array(wikiFuzz::makeFuzz(2)) ),
+ 'wpMovetalk' => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ 'wpDeleteAndMove' => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ 'wpConfirm' => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ 'talkmoved' => wikiFuzz::chooseInput( array("1", wikiFuzz::makeFuzz(2), "articleexists", 'notalkpage') ),
+ 'oldtitle' => wikiFuzz::makeFuzz(2),
+ 'newtitle' => wikiFuzz::makeFuzz(2),
+ 'wpMovetalk' => wikiFuzz::chooseInput( array("1", "0", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(2) == 0) unset($this->params["wpEditToken"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["target"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["wpNewTitle"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpReason"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpOldTitle"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Undelete"
+ */
+class specialUndelete extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Undelete";
+
+ $this->params = array (
+ "action" => wikiFuzz::chooseInput( array("submit", "", wikiFuzz::makeFuzz(2)) ),
+ 'wpEditToken' => wikiFuzz::chooseInput( array('', 0, 34987987, wikiFuzz::makeFuzz(2)) ),
+ 'target' => wikiFuzz::chooseInput( array("x", wikiFuzz::makeTitleSafe(wikiFuzz::makeFuzz(2)) ) ),
+ 'timestamp' => wikiFuzz::chooseInput( array("125223", wikiFuzz::makeFuzz(2) ) ),
+ 'file' => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ 'restore' => wikiFuzz::chooseInput( array("0", "1", wikiFuzz::makeFuzz(2)) ),
+ 'preview' => wikiFuzz::chooseInput( array("0", "1", wikiFuzz::makeFuzz(2)) ),
+ 'wpComment' => wikiFuzz::makeFuzz(2)
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(2) == 0) unset($this->params["wpEditToken"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["target"]);
+ if (wikiFuzz::randnum(1) == 0) unset($this->params["restore"]);
+ if (wikiFuzz::randnum(1) == 0) unset($this->params["preview"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Unlockdb"
+ */
+class specialUnlockdb extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Unlockdb";
+
+ $this->params = array (
+ "action" => wikiFuzz::chooseInput( array("submit", "success", "", wikiFuzz::makeFuzz(2)) ),
+ 'wpEditToken' => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ 'wpLockConfirm' => wikiFuzz::chooseInput( array("0", "1", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpEditToken"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["action"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpLockConfirm"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Lockdb"
+ */
+class specialLockdb extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Lockdb";
+
+ $this->params = array (
+ "action" => wikiFuzz::chooseInput( array("submit", "success", "", wikiFuzz::makeFuzz(2)) ),
+ 'wpEditToken' => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ 'wpLockReason' => wikiFuzz::makeFuzz(2),
+ 'wpLockConfirm'=> wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpEditToken"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["action"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpLockConfirm"]);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Userrights"
+ */
+class specialUserrights extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Userrights";
+
+ $this->params = array (
+ 'wpEditToken' => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ 'user-editname' => wikiFuzz::chooseInput( array("Nickj2", "Nickj2\n<xyz>", wikiFuzz::makeFuzz(2)) ),
+ 'ssearchuser' => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ 'saveusergroups'=> wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)), "Save User Groups"),
+ 'member[]' => wikiFuzz::chooseInput( array("0", "bot", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "available[]" => wikiFuzz::chooseInput( array("0", "sysop", "bureaucrat", "1", "++--34234", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(3) == 0) unset($this->params['ssearchuser']);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params['saveusergroups']);
+ }
+}
+
+
+/**
+ ** a test for page protection and unprotection.
+ */
+class pageProtectionForm extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Main_Page";
+
+ $this->params = array (
+ "action" => "protect",
+ 'wpEditToken' => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ "mwProtect-level-edit" => wikiFuzz::chooseInput( array('', 'autoconfirmed', 'sysop', wikifuzz::makeFuzz(2)) ),
+ "mwProtect-level-move" => wikiFuzz::chooseInput( array('', 'autoconfirmed', 'sysop', wikifuzz::makeFuzz(2)) ),
+ "mwProtectUnchained" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ 'mwProtect-reason' => wikiFuzz::chooseInput( array("because it was there", wikifuzz::makeFuzz(2)) )
+ );
+
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["mwProtectUnchained"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params['mwProtect-reason']);
+ }
+}
+
+
+/**
+ ** a page test for "Special:Blockip".
+ */
+class specialBlockip extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Blockip";
+
+ $this->params = array (
+ "action" => wikiFuzz::chooseInput( array("submit", "", wikiFuzz::makeFuzz(2)) ),
+ 'wpEditToken' => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ "wpBlockAddress" => wikiFuzz::chooseInput( array("20398702394", "", "Nickj2", wikiFuzz::makeFuzz(2),
+ // something like an IP address, sometimes invalid:
+ ( wikiFuzz::randnum(300,-20) . "." . wikiFuzz::randnum(300,-20) . "."
+ . wikiFuzz::randnum(300,-20) . "." .wikiFuzz::randnum(300,-20) ) ) ),
+ "ip" => wikiFuzz::chooseInput( array("20398702394", "", "Nickj2", wikiFuzz::makeFuzz(2),
+ // something like an IP address, sometimes invalid:
+ ( wikiFuzz::randnum(300,-20) . "." . wikiFuzz::randnum(300,-20) . "."
+ . wikiFuzz::randnum(300,-20) . "." .wikiFuzz::randnum(300,-20) ) ) ),
+ "wpBlockOther" => wikiFuzz::chooseInput( array('', 'Nickj2', wikifuzz::makeFuzz(2)) ),
+ "wpBlockExpiry" => wikiFuzz::chooseInput( array("other", "2 hours", "1 day", "3 days", "1 week", "2 weeks",
+ "1 month", "3 months", "6 months", "1 year", "infinite", wikiFuzz::makeFuzz(2)) ),
+ "wpBlockReason" => wikiFuzz::chooseInput( array("because it was there", wikifuzz::makeFuzz(2)) ),
+ "wpAnonOnly" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "wpCreateAccount" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "wpBlock" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) )
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpBlockOther"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpBlockExpiry"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpBlockReason"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpAnonOnly"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpCreateAccount"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["wpBlockAddress"]);
+ if (wikiFuzz::randnum(4) == 0) unset($this->params["ip"]);
+ }
+}
+
+
+/**
+ ** a test for the imagepage.
+ */
+class imagepageTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Image:Small-email.png";
+
+ $this->params = array (
+ "image" => wikiFuzz::chooseInput( array("Small-email.png", wikifuzz::makeFuzz(2)) ),
+ "wpReason" => wikifuzz::makeFuzz(2),
+ "oldimage" => wikiFuzz::chooseInput( array("Small-email.png", wikifuzz::makeFuzz(2)) ),
+ "wpEditToken" => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["image"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpReason"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["oldimage"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpEditToken"]);
+ }
+}
+
+
+/**
+ ** a test for page deletion form.
+ */
+class pageDeletion extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Main_Page&action=delete";
+
+ $this->params = array (
+ "wpEditToken" => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ "wpReason" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "wpConfirm" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(5) == 0) unset($this->params["wpReason"]);
+ if (wikiFuzz::randnum(5) == 0) unset($this->params["wpEditToken"]);
+ if (wikiFuzz::randnum(5) == 0) unset($this->params["wpConfirm"]);
+ }
+}
+
+
+
+/**
+ ** a test for Revision Deletion.
+ */
+class specialRevisionDelete extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Revisiondelete";
+
+ $this->params = array (
+ "target" => wikiFuzz::chooseInput( array("Main Page", wikifuzz::makeFuzz(2)) ),
+ "oldid" => wikifuzz::makeFuzz(2),
+ "oldid[]" => wikifuzz::makeFuzz(2),
+ "wpReason" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "revdelete-hide-text" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "revdelete-hide-comment" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "revdelete-hide-user" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "revdelete-hide-restricted" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["target"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["oldid"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["oldid[]"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["wpReason"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["revdelete-hide-text"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["revdelete-hide-comment"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["revdelete-hide-user"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["revdelete-hide-restricted"]);
+ }
+}
+
+
+/**
+ ** a test for Special:Import.
+ */
+class specialImport extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Import";
+
+ $this->params = array (
+ "action" => "submit",
+ "source" => wikiFuzz::chooseInput( array("upload", "interwiki", wikifuzz::makeFuzz(2)) ),
+ "MAX_FILE_SIZE" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikifuzz::makeFuzz(2)) ),
+ "xmlimport" => wikiFuzz::chooseInput( array("/var/www/hosts/mediawiki/wiki/AdminSettings.php", "1", "++--34234", wikiFuzz::makeFuzz(2)) ),
+ "namespace" => wikiFuzz::chooseInput( array(wikiFuzz::randnum(30,-6), wikiFuzz::makeFuzz(2)) ),
+ "interwiki" => wikiFuzz::makeFuzz(2),
+ "interwikiHistory" => wikiFuzz::makeFuzz(2),
+ "frompage" => wikiFuzz::makeFuzz(2),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["action"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["source"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["MAX_FILE_SIZE"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["xmlimport"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["interwiki"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["interwikiHistory"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["frompage"]);
+
+ // Note: Need to do a file upload to fully test this Special page.
+ }
+}
+
+
+
+/**
+ ** a test for thumb.php
+ */
+class thumbTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "thumb.php";
+
+ $this->params = array (
+ "f" => wikiFuzz::chooseInput( array("..", "\\", "small-email.png", wikifuzz::makeFuzz(2)) ),
+ "w" => wikiFuzz::chooseInput( array("80", wikiFuzz::randnum(6000,-200), wikifuzz::makeFuzz(2)) ),
+ "r" => wikiFuzz::chooseInput( array("0", wikifuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["f"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["w"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["r"]);
+ }
+}
+
+
+/**
+ ** a test for trackback.php
+ */
+class trackbackTest extends pageTest {
+ function __construct() {
+ $this->pagePath = "trackback.php";
+
+ $this->params = array (
+ "url" => wikifuzz::makeFuzz(2),
+ "blog_name" => wikiFuzz::chooseInput( array("80", wikiFuzz::randnum(6000,-200), wikifuzz::makeFuzz(2)) ),
+ "article" => wikiFuzz::chooseInput( array("Main Page", wikifuzz::makeFuzz(2)) ),
+ "title" => wikiFuzz::chooseInput( array("Main Page", wikifuzz::makeFuzz(2)) ),
+ "excerpt" => wikifuzz::makeFuzz(2),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["title"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["excerpt"]);
+ }
+}
+
+
+/**
+ ** a test for profileinfo.php
+ */
+class profileInfo extends pageTest {
+ function __construct() {
+ $this->pagePath = "profileinfo.php";
+
+ $this->params = array (
+ "expand" => wikifuzz::makeFuzz(2),
+ "sort" => wikiFuzz::chooseInput( array("time", "count", "name", wikifuzz::makeFuzz(2)) ),
+ "filter" => wikiFuzz::chooseInput( array("Main Page", wikifuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["sort"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["filter"]);
+ }
+}
+
+
+/**
+ ** a test for Special:Cite (extension Special page).
+ */
+class specialCite extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:Cite";
+
+ $this->params = array (
+ "page" => wikiFuzz::chooseInput( array("\" onmouseover=\"alert(1);\"", "Main Page", wikifuzz::makeFuzz(2)) ),
+ "id" => wikiFuzz::chooseInput( array("-1", "0", "------'-------0", "+1", "-9823412312312412435", wikiFuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["page"]);
+ if (wikiFuzz::randnum(6) == 0) unset($this->params["id"]);
+ }
+}
+
+
+/**
+ ** a test for Special:Filepath (extension Special page).
+ */
+class specialFilepath extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Filepath";
+
+ $this->params = array (
+ "file" => wikiFuzz::chooseInput( array("Small-email.png", "Small-email.png" . wikifuzz::makeFuzz(1), wikiFuzz::makeFuzz(2)) ),
+ );
+ }
+}
+
+
+/**
+ ** a test for Special:Makebot (extension Special page).
+ */
+class specialMakebot extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Makebot";
+
+ $this->params = array (
+ "username" => wikiFuzz::chooseInput( array("Nickj2", "192.168.0.2", wikifuzz::makeFuzz(1) ) ),
+ "dosearch" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikifuzz::makeFuzz(2)) ),
+ "grant" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikifuzz::makeFuzz(2)) ),
+ "comment" => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ "token" => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(2) == 0) unset($this->params["dosearch"]);
+ if (wikiFuzz::randnum(2) == 0) unset($this->params["grant"]);
+ if (wikiFuzz::randnum(5) == 0) unset($this->params["token"]);
+ }
+}
+
+
+/**
+ ** a test for Special:Makesysop (extension Special page).
+ */
+class specialMakesysop extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Makesysop";
+
+ $this->params = array (
+ "wpMakesysopUser" => wikiFuzz::chooseInput( array("Nickj2", "192.168.0.2", wikifuzz::makeFuzz(1) ) ),
+ "action" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikifuzz::makeFuzz(2)) ),
+ "wpMakesysopSubmit" => wikiFuzz::chooseInput( array("0", "1", "++--34234", wikifuzz::makeFuzz(2)) ),
+ "wpEditToken" => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ "wpSetBureaucrat" => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["wpMakesysopSubmit"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["wpEditToken"]);
+ if (wikiFuzz::randnum(3) == 0) unset($this->params["wpSetBureaucrat"]);
+ }
+}
+
+
+/**
+ ** a test for Special:Renameuser (extension Special page).
+ */
+class specialRenameuser extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php/Special:Renameuser";
+
+ $this->params = array (
+ "oldusername" => wikiFuzz::chooseInput( array("Nickj2", "192.168.0.2", wikifuzz::makeFuzz(1) ) ),
+ "newusername" => wikiFuzz::chooseInput( array("Nickj2", "192.168.0.2", wikifuzz::makeFuzz(1) ) ),
+ "token" => wikiFuzz::chooseInput( array("20398702394", "", wikiFuzz::makeFuzz(2)) ),
+ );
+ }
+}
+
+
+/**
+ ** a test for Special:Linksearch (extension Special page).
+ */
+class specialLinksearch extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special%3ALinksearch";
+
+ $this->params = array (
+ "target" => wikifuzz::makeFuzz(2),
+ );
+
+ // sometimes we don't want to specify certain parameters.
+ if (wikiFuzz::randnum(10) == 0) unset($this->params["target"]);
+ }
+}
+
+
+/**
+ ** a test for Special:CategoryTree (extension Special page).
+ */
+class specialCategoryTree extends pageTest {
+ function __construct() {
+ $this->pagePath = "index.php?title=Special:CategoryTree";
+
+ $this->params = array (
+ "target" => wikifuzz::makeFuzz(2),
+ "from" => wikifuzz::makeFuzz(2),
+ "until" => wikifuzz::makeFuzz(2),
+ "showas" => wikifuzz::makeFuzz(2),
+ "mode" => wikiFuzz::chooseInput( array("pages", "categories", "all", wikifuzz::makeFuzz(2)) ),
+ );
+
+ // sometimes we do want to specify certain parameters.
+ if (wikiFuzz::randnum(5) == 0) $this->params["notree"] = wikiFuzz::chooseInput( array("1", 0, "", wikiFuzz::makeFuzz(2)) );
+ }
+}
+
+
+
+/**
+ ** selects a page test to run.
+ */
+function selectPageTest($count) {
+
+ // if the user only wants a specific test, then only ever give them that.
+ if (defined("SPECIFIC_TEST")) {
+ $testType = SPECIFIC_TEST;
+ return new $testType ();
+ }
+
+ // Some of the time we test Special pages, the remaining
+ // time we test using the standard edit page.
+ switch ($count % 100) {
+ case 0 : return new successfulUserLoginTest();
+ case 1 : return new listusersTest();
+ case 2 : return new searchTest();
+ case 3 : return new recentchangesTest();
+ case 4 : return new prefixindexTest();
+ case 5 : return new mimeSearchTest();
+ case 6 : return new specialLogTest();
+ case 7 : return new userLoginTest();
+ case 8 : return new ipblocklistTest();
+ case 9 : return new newImagesTest();
+ case 10: return new imagelistTest();
+ case 11: return new specialExportTest();
+ case 12: return new specialBooksourcesTest();
+ case 13: return new specialAllpagesTest();
+ case 14: return new pageHistoryTest();
+ case 15: return new contributionsTest();
+ case 16: return new viewPageTest();
+ case 17: return new specialAllmessagesTest();
+ case 18: return new specialNewpages();
+ case 19: return new searchTest();
+ case 20: return new redirectTest();
+ case 21: return new confirmEmail();
+ case 22: return new watchlistTest();
+ case 23: return new specialBlockmeTest();
+ case 24: return new specialUndelete();
+ case 25: return new specialMovePage();
+ case 26: return new specialUnlockdb();
+ case 27: return new specialLockdb();
+ case 28: return new specialUserrights();
+ case 29: return new pageProtectionForm();
+ case 30: return new specialBlockip();
+ case 31: return new imagepageTest();
+ case 32: return new pageDeletion();
+ case 33: return new specialRevisionDelete();
+ case 34: return new specialImport();
+ case 35: return new thumbTest();
+ case 36: return new trackbackTest();
+ case 37: return new profileInfo();
+ case 38: return new specialCite();
+ case 39: return new specialFilepath();
+ case 40: return new specialMakebot();
+ case 41: return new specialMakesysop();
+ case 42: return new specialRenameuser();
+ case 43: return new specialLinksearch();
+ case 44: return new specialCategoryTree();
+ default: return new editPageTest();
+ }
+}
+
+
+/////////////////////// SAVING OUTPUT /////////////////////////
+
+/**
+ ** Utility function for saving a file. Currently has no error checking.
+ */
+function saveFile($data, $name) {
+ file_put_contents($name, $data);
+}
+
+
+/**
+ ** Returns a test as an experimental GET-to-POST URL.
+ ** This doesn't seem to always work though, and sometimes the output is too long
+ ** to be a valid GET URL, so we also save in other formats.
+ */
+function getAsURL(pageTest $test) {
+ $used_question_mark = (strpos($test->getPagePath(), "?") !== false);
+ $retval = "http://get-to-post.nickj.org/?http://" . WIKI_BASE_URL . $test->getPagePath();
+ foreach ($test->getParams() as $param => $value) {
+ if (!$used_question_mark) {
+ $retval .= "?";
+ $used_question_mark = true;
+ }
+ else {
+ $retval .= "&";
+ }
+ $retval .= $param . "=" . urlencode($value);
+ }
+ return $retval;
+}
+
+
+/**
+ ** Saves a plain-text human-readable version of a test.
+ */
+function saveTestAsText(pageTest $test, $filename) {
+ $str = "Test: " . $test->getPagePath();
+ foreach ($test->getParams() as $param => $value) {
+ $str .= "\n$param: $value";
+ }
+ $str .= "\nGet-to-post URL: " . getAsURL($test) . "\n";
+ saveFile($str, $filename);
+}
+
+
+/**
+ ** Saves a test as a standalone basic PHP script that shows this one problem.
+ ** Resulting script requires PHP-Curl be installed in order to work.
+ */
+function saveTestAsPHP(pageTest $test, $filename) {
+ $str = "<?php\n"
+ . "\$params = " . var_export(escapeForCurl($test->getParams()), true) . ";\n"
+ . "\$ch = curl_init();\n"
+ . "curl_setopt(\$ch, CURLOPT_POST, 1);\n"
+ . "curl_setopt(\$ch, CURLOPT_POSTFIELDS, \$params );\n"
+ . "curl_setopt(\$ch, CURLOPT_URL, " . var_export(WIKI_BASE_URL . $test->getPagePath(), true) . ");\n"
+ . "curl_setopt(\$ch, CURLOPT_RETURNTRANSFER,1);\n"
+ . ($test->getCookie() ? "curl_setopt(\$ch, CURLOPT_COOKIE, " . var_export($test->getCookie(), true) . ");\n" : "")
+ . "\$result=curl_exec(\$ch);\n"
+ . "curl_close (\$ch);\n"
+ . "print \$result;\n"
+ . "?>\n";
+ saveFile($str, $filename);
+}
+
+
+/**
+ ** Escapes a value so that it can be used on the command line by Curl.
+ ** Specifically, "<" and "@" need to be escaped if they are the first character,
+ ** otherwise curl interprets these as meaning that we want to insert a file.
+ */
+function escapeForCurl(array $input_params) {
+ $output_params = array();
+ foreach ($input_params as $param => $value) {
+ if (strlen($value) > 0 && ( $value[0] == "@" || $value[0] == "<")) {
+ $value = "\\" . $value;
+ }
+ $output_params[$param] = $value;
+ }
+ return $output_params;
+}
+
+
+/**
+ ** Saves a test as a standalone CURL shell script that shows this one problem.
+ ** Resulting script requires standalone Curl be installed in order to work.
+ */
+function saveTestAsCurl(pageTest $test, $filename) {
+ $str = "#!/bin/bash\n"
+ . "curl --silent --include --globoff \\\n"
+ . ($test->getCookie() ? " --cookie " . escapeshellarg($test->getCookie()) . " \\\n" : "");
+ foreach (escapeForCurl($test->getParams()) as $param => $value) {
+ $str .= " -F " . escapeshellarg($param) . "=" . escapeshellarg($value) . " \\\n";
+ }
+ $str .= " " . escapeshellarg(WIKI_BASE_URL . $test->getPagePath()); // beginning space matters.
+ $str .= "\n";
+ saveFile($str, $filename);
+ chmod($filename, 0755); // make executable
+}
+
+
+/**
+ ** Saves the internal data structure to file.
+ */
+function saveTestData (pageTest $test, $filename) {
+ saveFile(serialize($test), $filename);
+}
+
+
+/**
+ ** saves a test in the various formats.
+ */
+function saveTest(pageTest $test, $testname) {
+ $base_name = DIRECTORY . "/" . $testname;
+ saveTestAsText($test, $base_name . INFO_FILE);
+ saveTestAsPHP ($test, $base_name . PHP_TEST );
+ saveTestAsCurl($test, $base_name . CURL_TEST);
+ saveTestData ($test, $base_name . DATA_FILE);
+}
+
+
+//////////////////// MEDIAWIKI OUTPUT /////////////////////////
+
+/**
+ ** Asks MediaWiki for the HTML output of a test.
+ */
+function wikiTestOutput(pageTest $test) {
+
+ $ch = curl_init();
+
+ // specify the cookie, if required.
+ if ($test->getCookie()) curl_setopt($ch, CURLOPT_COOKIE, $test->getCookie());
+ curl_setopt($ch, CURLOPT_POST, 1); // save form using a POST
+
+ $params = escapeForCurl($test->getParams());
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $params ); // load the POST variables
+
+ curl_setopt($ch, CURLOPT_URL, WIKI_BASE_URL . $test->getPagePath() ); // set url to post to
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
+
+ $result=curl_exec ($ch);
+
+ // if we encountered an error, then say so, and return an empty string.
+ if (curl_error($ch)) {
+ print "\nCurl error #: " . curl_errno($ch) . " - " . curl_error ($ch);
+ $result = "";
+ }
+
+ curl_close ($ch);
+
+ return $result;
+}
+
+
+//////////////////// HTML VALIDATION /////////////////////////
+
+/*
+ ** Asks the validator whether this is valid HTML, or not.
+ */
+function validateHTML($text) {
+
+ $params = array ("fragment" => $text);
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_POST, 1); // save form using a POST
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $params); // load the POST variables
+ curl_setopt($ch, CURLOPT_URL, VALIDATOR_URL); // set url to post to
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
+
+ $result=curl_exec ($ch);
+
+ // if we encountered an error, then log it, and exit.
+ if (curl_error($ch)) {
+ trigger_error("Curl error #: " . curl_errno($ch) . " - " . curl_error ($ch) );
+ print "Curl error #: " . curl_errno($ch) . " - " . curl_error ($ch) . " - exiting.\n";
+ exit();
+ }
+
+ curl_close ($ch);
+
+ $valid = (strpos($result, "Failed validation") === false ? true : false);
+
+ return array($valid, $result);
+}
+
+
+/**
+ ** Get tidy to check for no HTML errors in the output file (e.g. unescaped strings).
+ */
+function tidyCheckFile($name) {
+ $file = DIRECTORY . "/" . $name;
+ $command = PATH_TO_TIDY . " -output /tmp/out.html -quiet $file 2>&1";
+ $x = `$command`;
+
+ // Look for the most interesting Tidy errors and warnings.
+ if ( strpos($x,"end of file while parsing attributes") !== false
+ || strpos($x,"attribute with missing trailing quote mark") !== false
+ || strpos($x,"missing '>' for end of tag") !== false
+ || strpos($x,"Error:") !== false) {
+ print "\nTidy found something - view details with: $command";
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+/**
+ ** Returns whether or not an database error log file has changed in size since
+ ** the last time this was run. This is used to tell if a test caused a DB error.
+ */
+function dbErrorLogged() {
+ static $filesize;
+
+ // first time running this function
+ if (!isset($filesize)) {
+ // create log if it does not exist
+ if (!file_exists(DB_ERROR_LOG_FILE)) {
+ saveFile("", DB_ERROR_LOG_FILE);
+ }
+ $filesize = filesize(DB_ERROR_LOG_FILE);
+ return false;
+ }
+
+ $newsize = filesize(DB_ERROR_LOG_FILE);
+ // if the log has grown, then assume the current test caused it.
+ if ($newsize != $filesize) {
+ $filesize = $newsize;
+ return true;
+ }
+
+ return false;
+}
+
+////////////////// TOP-LEVEL PROBLEM-FINDING FUNCTION ////////////////////////
+
+/**
+ ** takes a page test, and runs it and tests it for problems in the output.
+ ** Returns: False on finding a problem, or True on no problems being found.
+ */
+function runWikiTest(pageTest $test, &$testname, $can_overwrite = false) {
+
+ // by default don't overwrite a previous test of the same name.
+ while ( ! $can_overwrite && file_exists(DIRECTORY . "/" . $testname . DATA_FILE)) {
+ $testname .= "-" . mt_rand(0,9);
+ }
+
+ $filename = DIRECTORY . "/" . $testname . DATA_FILE;
+
+ // Store the time before and after, to find slow pages.
+ $before = microtime(true);
+
+ // Get MediaWiki to give us the output of this test.
+ $wiki_preview = wikiTestOutput($test);
+
+ $after = microtime(true);
+
+ // if we received no response, then that's interesting.
+ if ($wiki_preview == "") {
+ print "\nNo response received for: $filename";
+ return false;
+ }
+
+ // save output HTML to file.
+ $html_file = DIRECTORY . "/" . $testname . HTML_FILE;
+ saveFile($wiki_preview, $html_file);
+
+ // if there were PHP errors in the output, then that's interesting too.
+ if ( strpos($wiki_preview, "<b>Warning</b>: " ) !== false
+ || strpos($wiki_preview, "<b>Fatal error</b>: ") !== false
+ || strpos($wiki_preview, "<b>Notice</b>: " ) !== false
+ || strpos($wiki_preview, "<b>Error</b>: " ) !== false ) {
+ $error = substr($wiki_preview, strpos($wiki_preview, "</b>:") + 7, 50);
+ // Avoid probable PHP bug with bad session ids; http://bugs.php.net/bug.php?id=38224
+ if ($error != "Unknown: The session id contains illegal character") {
+ print "\nPHP error/warning/notice in HTML output: $html_file ; $error";
+ return false;
+ }
+ }
+
+ // if there was a MediaWiki Backtrace message in the output, then that's also interesting.
+ if (strpos($wiki_preview, "Backtrace:") !== false) {
+ print "\nInternal MediaWiki error in HTML output: $html_file";
+ return false;
+ }
+
+ // if there was a Parser error comment in the output, then that's potentially interesting.
+ if (strpos($wiki_preview, "!-- ERR") !== false) {
+ print "\nParser Error comment in HTML output: $html_file";
+ return false;
+ }
+
+ // if a database error was logged, then that's definitely interesting.
+ if (dbErrorLogged()) {
+ print "\nDatabase Error logged for: $filename";
+ return false;
+ }
+
+ // validate result
+ $valid = true;
+ if (VALIDATE_ON_WEB) {
+ list ($valid, $validator_output) = validateHTML($wiki_preview);
+ if (!$valid) print "\nW3C web validation failed - view details with: html2text " . DIRECTORY . "/" . $testname . ".validator_output.html";
+ }
+
+ // Get tidy to check the page, unless it is a test which produces XML.
+ if (!$test instanceof trackbackTest && !$test instanceof specialExportTest) {
+ $valid = tidyCheckFile( $testname . HTML_FILE ) && $valid;
+ }
+
+ // if it took more than 2 seconds to render, then it may be interesting too. (Possible DoS attack?)
+ if (($after - $before) >= 2) {
+ print "\nParticularly slow to render (" . round($after - $before, 2) . " seconds): $filename";
+ return false;
+ }
+
+ if( $valid ) {
+ // Remove temp HTML file if test was valid:
+ unlink( $html_file );
+ } elseif( VALIDATE_ON_WEB ) {
+ saveFile($validator_output, DIRECTORY . "/" . $testname . ".validator_output.html");
+ }
+
+ return $valid;
+}
+
+
+/////////////////// RERUNNING OLD TESTS ///////////////////
+
+/**
+ ** We keep our failed tests so that they can be rerun.
+ ** This function does that retesting.
+ */
+function rerunPreviousTests() {
+ print "Retesting previously found problems.\n";
+
+ $dir_contents = scandir (DIRECTORY);
+
+ // sort file into the order a normal person would use.
+ natsort ($dir_contents);
+
+ foreach ($dir_contents as $file) {
+
+ // if file is not a test, then skip it.
+ // Note we need to escape any periods or will be treated as "any character".
+ $matches = array();
+ if (!ereg("(.*)" . str_replace(".", "\.", DATA_FILE) . "$", $file, $matches)) continue;
+
+ // reload the test.
+ $full_path = DIRECTORY . "/" . $file;
+ $test = unserialize(file_get_contents($full_path));
+
+ // if this is not a valid test, then skip it.
+ if (! $test instanceof pageTest) {
+ print "\nSkipping invalid test - $full_path";
+ continue;
+ }
+
+ // The date format is in Apache log format, which makes it easier to locate
+ // which retest caused which error in the Apache logs (only happens usually if
+ // apache segfaults).
+ if (!QUIET) print "[" . date ("D M d H:i:s Y") . "] Retesting $file (" . get_class($test) . ")";
+
+ // run test
+ $testname = $matches[1];
+ $valid = runWikiTest($test, $testname, true);
+
+ if (!$valid) {
+ saveTest($test, $testname);
+ if (QUIET) {
+ print "\nTest: " . get_class($test) . " ; Testname: $testname\n------";
+ } else {
+ print "\n";
+ }
+ }
+ else {
+ if (!QUIET) print "\r";
+ if (DELETE_PASSED_RETESTS) {
+ $prefix = DIRECTORY . "/" . $testname;
+ if (is_file($prefix . DATA_FILE)) unlink($prefix . DATA_FILE);
+ if (is_file($prefix . PHP_TEST )) unlink($prefix . PHP_TEST );
+ if (is_file($prefix . CURL_TEST)) unlink($prefix . CURL_TEST);
+ if (is_file($prefix . INFO_FILE)) unlink($prefix . INFO_FILE);
+ }
+ }
+ }
+
+ print "\nDone retesting.\n";
+}
+
+
+////////////////////// MAIN LOOP ////////////////////////
+
+
+// first check whether CURL is installed, because sometimes it's not.
+if( ! function_exists('curl_init') ) {
+ die("Could not find 'curl_init' function. Is the curl extension compiled into PHP?\n");
+}
+
+// Initialization of types. wikiFuzz doesn't have a constructor because we want to
+// access it staticly and not have any globals.
+wikiFuzz::$types = array_keys(wikiFuzz::$data);
+
+// Make directory if doesn't exist
+if (!is_dir(DIRECTORY)) {
+ mkdir (DIRECTORY, 0700 );
+}
+// otherwise, we first retest the things that we have found in previous runs
+else if (RERUN_OLD_TESTS) {
+ rerunPreviousTests();
+}
+
+// seed the random number generator
+mt_srand(crc32(microtime()));
+
+// main loop.
+$start_time = date("U");
+$num_errors = 0;
+if (!QUIET) print "Beginning main loop. Results are stored in the " . DIRECTORY . " directory.\n";
+if (!QUIET) print "Press CTRL+C to stop testing.\n";
+
+for ($count=0; true; $count++) {
+ if (!QUIET) {
+ // spinning progress indicator.
+ switch( $count % 4 ) {
+ case '0': print "\r/"; break;
+ case '1': print "\r-"; break;
+ case '2': print "\r\\"; break;
+ case '3': print "\r|"; break;
+ }
+ print " $count";
+ }
+
+ // generate a page test to run.
+ $test = selectPageTest($count);
+
+ $mins = ( date("U") - $start_time ) / 60;
+ if (!QUIET && $mins > 0) {
+ print ". $num_errors poss errors. "
+ . floor($mins) . " mins. "
+ . round ($count / $mins, 0) . " tests/min. "
+ . get_class($test); // includes the current test name.
+ }
+
+ // run this test against MediaWiki, and see if the output was valid.
+ $testname = $count;
+ $valid = runWikiTest($test, $testname, false);
+
+ // save the failed test
+ if (!$valid) {
+ if (QUIET) {
+ print "\nTest: " . get_class($test) . " ; Testname: $testname\n------";
+ } else {
+ print "\n";
+ }
+ saveTest($test, $testname);
+ $num_errors += 1;
+ }
+
+ // stop if we have reached max number of errors.
+ if (defined("MAX_ERRORS") && $num_errors>=MAX_ERRORS) {
+ break;
+ }
+
+ // stop if we have reached max number of mins runtime.
+ if (defined("MAX_RUNTIME") && $mins>=MAX_RUNTIME) {
+ break;
+ }
+}
+
+?>
diff --git a/maintenance/generateSitemap.php b/maintenance/generateSitemap.php
new file mode 100644
index 000000000000..b8d6a5d6c150
--- /dev/null
+++ b/maintenance/generateSitemap.php
@@ -0,0 +1,470 @@
+<?php
+define( 'GS_MAIN', -2 );
+define( 'GS_TALK', -1 );
+/**
+ * Creates a Google sitemap for the site
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @copyright Copyright © 2005, Jens Frank <jeluf@gmx.de>
+ * @copyright Copyright © 2005, Brion Vibber <brion@pobox.com>
+ *
+ * @link http://www.google.com/webmasters/sitemaps/docs/en/about.html
+ * @link http://www.google.com/schemas/sitemap/0.84/sitemap.xsd
+ *
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+class GenerateSitemap {
+ /**
+ * The maximum amount of urls in a sitemap file
+ *
+ * @link http://www.google.com/schemas/sitemap/0.84/sitemap.xsd
+ *
+ * @var int
+ */
+ var $url_limit;
+
+ /**
+ * The maximum size of a sitemap file
+ *
+ * @link http://www.google.com/webmasters/sitemaps/docs/en/protocol.html#faq_sitemap_size
+ *
+ * @var int
+ */
+ var $size_limit;
+
+ /**
+ * The path to prepend to the filename
+ *
+ * @var string
+ */
+ var $fspath;
+
+ /**
+ * The path to append to the domain name
+ *
+ * @var string
+ */
+ var $path;
+
+ /**
+ * Whether or not to use compression
+ *
+ * @var bool
+ */
+ var $compress;
+
+ /**
+ * The number of entries to save in each sitemap file
+ *
+ * @var array
+ */
+ var $limit = array();
+
+ /**
+ * Key => value entries of namespaces and their priorities
+ *
+ * @var array
+ */
+ var $priorities = array(
+ // Custom main namespaces
+ GS_MAIN => '0.5',
+ // Custom talk namesspaces
+ GS_TALK => '0.1',
+ // MediaWiki standard namespaces
+ NS_MAIN => '1.0',
+ NS_TALK => '0.1',
+ NS_USER => '0.5',
+ NS_USER_TALK => '0.1',
+ NS_PROJECT => '0.5',
+ NS_PROJECT_TALK => '0.1',
+ NS_IMAGE => '0.5',
+ NS_IMAGE_TALK => '0.1',
+ NS_MEDIAWIKI => '0.0',
+ NS_MEDIAWIKI_TALK => '0.1',
+ NS_TEMPLATE => '0.0',
+ NS_TEMPLATE_TALK => '0.1',
+ NS_HELP => '0.5',
+ NS_HELP_TALK => '0.1',
+ NS_CATEGORY => '0.5',
+ NS_CATEGORY_TALK => '0.1',
+ );
+
+ /**
+ * A one-dimensional array of namespaces in the wiki
+ *
+ * @var array
+ */
+ var $namespaces = array();
+
+ /**
+ * When this sitemap batch was generated
+ *
+ * @var string
+ */
+ var $timestamp;
+
+ /**
+ * A database slave object
+ *
+ * @var object
+ */
+ var $dbr;
+
+ /**
+ * A resource pointing to the sitemap index file
+ *
+ * @var resource
+ */
+ var $findex;
+
+
+ /**
+ * A resource pointing to a sitemap file
+ *
+ * @var resource
+ */
+ var $file;
+
+ /**
+ * A resource pointing to php://stderr
+ *
+ * @var resource
+ */
+ var $stderr;
+
+ /**
+ * Constructor
+ *
+ * @param string $fspath The path to prepend to the filenames, used to
+ * save them somewhere else than in the root directory
+ * @param string $path The path to append to the domain name
+ * @param bool $compress Whether to compress the sitemap files
+ */
+ function GenerateSitemap( $fspath, $path, $compress ) {
+ global $wgScriptPath;
+
+ $this->url_limit = 50000;
+ $this->size_limit = pow( 2, 20 ) * 10;
+ $this->fspath = isset( $fspath ) ? $fspath : '';
+ $this->path = isset( $path ) ? $path : $wgScriptPath;
+ $this->compress = $compress;
+
+ $this->stderr = fopen( 'php://stderr', 'wt' );
+ $this->dbr =& wfGetDB( DB_SLAVE );
+ $this->generateNamespaces();
+ $this->timestamp = wfTimestamp( TS_ISO_8601, wfTimestampNow() );
+ $this->findex = fopen( "{$this->fspath}sitemap-index-" . wfWikiID() . ".xml", 'wb' );
+ }
+
+ /**
+ * Generate a one-dimensional array of existing namespaces
+ */
+ function generateNamespaces() {
+ $fname = 'GenerateSitemap::generateNamespaces';
+
+ $res = $this->dbr->select( 'page',
+ array( 'page_namespace' ),
+ array(),
+ $fname,
+ array(
+ 'GROUP BY' => 'page_namespace',
+ 'ORDER BY' => 'page_namespace',
+ )
+ );
+
+ while ( $row = $this->dbr->fetchObject( $res ) )
+ $this->namespaces[] = $row->page_namespace;
+ }
+
+ /**
+ * Get the priority of a given namespace
+ *
+ * @param int $namespace The namespace to get the priority for
+ +
+ * @return string
+ */
+
+ function priority( $namespace ) {
+ return isset( $this->priorities[$namespace] ) ? $this->priorities[$namespace] : $this->guessPriority( $namespace );
+ }
+
+ /**
+ * If the namespace isn't listed on the priority list return the
+ * default priority for the namespace, varies depending on whether it's
+ * a talkpage or not.
+ *
+ * @param int $namespace The namespace to get the priority for
+ *
+ * @return string
+ */
+ function guessPriority( $namespace ) {
+ return Namespace::isMain( $namespace ) ? $this->priorities[GS_MAIN] : $this->priorities[GS_TALK];
+ }
+
+ /**
+ * Return a database resolution of all the pages in a given namespace
+ *
+ * @param int $namespace Limit the query to this namespace
+ *
+ * @return resource
+ */
+ function getPageRes( $namespace ) {
+ $fname = 'GenerateSitemap::getPageRes';
+
+ return $this->dbr->select( 'page',
+ array(
+ 'page_namespace',
+ 'page_title',
+ 'page_touched',
+ ),
+ array( 'page_namespace' => $namespace ),
+ $fname
+ );
+ }
+
+ /**
+ * Main loop
+ *
+ * @access public
+ */
+ function main() {
+ global $wgContLang;
+
+ fwrite( $this->findex, $this->openIndex() );
+
+ foreach ( $this->namespaces as $namespace ) {
+ $res = $this->getPageRes( $namespace );
+ $this->file = false;
+ $this->generateLimit( $namespace );
+ $length = $this->limit[0];
+ $i = $smcount = 0;
+
+ $fns = $wgContLang->getFormattedNsText( $namespace );
+ $this->debug( "$namespace ($fns)" );
+ while ( $row = $this->dbr->fetchObject( $res ) ) {
+ if ( $i++ === 0 || $i === $this->url_limit + 1 || $length + $this->limit[1] + $this->limit[2] > $this->size_limit ) {
+ if ( $this->file !== false ) {
+ $this->write( $this->file, $this->closeFile() );
+ $this->close( $this->file );
+ }
+ $filename = $this->sitemapFilename( $namespace, $smcount++ );
+ $this->file = $this->open( $this->fspath . $filename, 'wb' );
+ $this->write( $this->file, $this->openFile() );
+ fwrite( $this->findex, $this->indexEntry( $filename ) );
+ $this->debug( "\t$filename" );
+ $length = $this->limit[0];
+ $i = 1;
+ }
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $date = wfTimestamp( TS_ISO_8601, $row->page_touched );
+ $entry = $this->fileEntry( $title->getFullURL(), $date, $this->priority( $namespace ) );
+ $length += strlen( $entry );
+ $this->write( $this->file, $entry );
+ // generate pages for language variants
+ if($wgContLang->hasVariants()){
+ $variants = $wgContLang->getVariants();
+ foreach($variants as $vCode){
+ if($vCode==$wgContLang->getCode()) continue; // we don't want default variant
+ $entry = $this->fileEntry( $title->getFullURL('',$vCode), $date, $this->priority( $namespace ) );
+ $length += strlen( $entry );
+ $this->write( $this->file, $entry );
+ }
+ }
+ }
+ if ( $this->file ) {
+ $this->write( $this->file, $this->closeFile() );
+ $this->close( $this->file );
+ }
+ }
+ fwrite( $this->findex, $this->closeIndex() );
+ fclose( $this->findex );
+ }
+
+ /**
+ * gzopen() / fopen() wrapper
+ *
+ * @return resource
+ */
+ function open( $file, $flags ) {
+ return $this->compress ? gzopen( $file, $flags ) : fopen( $file, $flags );
+ }
+
+ /**
+ * gzwrite() / fwrite() wrapper
+ */
+ function write( &$handle, $str ) {
+ if ( $this->compress )
+ gzwrite( $handle, $str );
+ else
+ fwrite( $handle, $str );
+ }
+
+ /**
+ * gzclose() / fclose() wrapper
+ */
+ function close( &$handle ) {
+ if ( $this->compress )
+ gzclose( $handle );
+ else
+ fclose( $handle );
+ }
+
+ /**
+ * Get a sitemap filename
+ *
+ * @static
+ *
+ * @param int $namespace The namespace
+ * @param int $count The count
+ *
+ * @return string
+ */
+ function sitemapFilename( $namespace, $count ) {
+ $ext = $this->compress ? '.gz' : '';
+ return "sitemap-".wfWikiID()."-NS_$namespace-$count.xml$ext";
+ }
+
+ /**
+ * Return the XML required to open an XML file
+ *
+ * @static
+ *
+ * @return string
+ */
+ function xmlHead() {
+ return '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
+ }
+
+ /**
+ * Return the XML schema being used
+ *
+ * @static
+ *
+ * @returns string
+ */
+ function xmlSchema() {
+ return 'http://www.google.com/schemas/sitemap/0.84';
+ }
+
+ /**
+ * Return the XML required to open a sitemap index file
+ *
+ * @return string
+ */
+ function openIndex() {
+ return $this->xmlHead() . '<sitemapindex xmlns="' . $this->xmlSchema() . '">' . "\n";
+ }
+
+ /**
+ * Return the XML for a single sitemap indexfile entry
+ *
+ * @static
+ *
+ * @param string $filename The filename of the sitemap file
+ *
+ * @return string
+ */
+ function indexEntry( $filename ) {
+ return
+ "\t<sitemap>\n" .
+ "\t\t<loc>$filename</loc>\n" .
+ "\t\t<lastmod>{$this->timestamp}</lastmod>\n" .
+ "\t</sitemap>\n";
+ }
+
+ /**
+ * Return the XML required to close a sitemap index file
+ *
+ * @static
+ *
+ * @return string
+ */
+ function closeIndex() {
+ return "</sitemapindex>\n";
+ }
+
+ /**
+ * Return the XML required to open a sitemap file
+ *
+ * @return string
+ */
+ function openFile() {
+ return $this->xmlHead() . '<urlset xmlns="' . $this->xmlSchema() . '">' . "\n";
+ }
+
+ /**
+ * Return the XML for a single sitemap entry
+ *
+ * @static
+ *
+ * @param string $url An RFC 2396 compilant URL
+ * @param string $date A ISO 8601 date
+ * @param string $priority A priority indicator, 0.0 - 1.0 inclusive with a 0.1 stepsize
+ *
+ * @return string
+ */
+ function fileEntry( $url, $date, $priority ) {
+ return
+ "\t<url>\n" .
+ "\t\t<loc>$url</loc>\n" .
+ "\t\t<lastmod>$date</lastmod>\n" .
+ "\t\t<priority>$priority</priority>\n" .
+ "\t</url>\n";
+ }
+
+ /**
+ * Return the XML required to close sitemap file
+ *
+ * @static
+ * @return string
+ */
+ function closeFile() {
+ return "</urlset>\n";
+ }
+
+ /**
+ * Write a string to stderr followed by a UNIX newline
+ */
+ function debug( $str ) {
+ fwrite( $this->stderr, "$str\n" );
+ }
+
+ /**
+ * Populate $this->limit
+ */
+ function generateLimit( $namespace ) {
+ $title = Title::makeTitle( $namespace, str_repeat( "\xf0\xa8\xae\x81", 63 ) . "\xe5\x96\x83" );
+
+ $this->limit = array(
+ strlen( $this->openFile() ),
+ strlen( $this->fileEntry( $title->getFullUrl(), wfTimestamp( TS_ISO_8601, wfTimestamp() ), $this->priority( $namespace ) ) ),
+ strlen( $this->closeFile() )
+ );
+ }
+}
+
+if ( in_array( '--help', $argv ) ) {
+ echo
+ "Usage: php generateSitemap.php [host] [options]\n" .
+ "\thost = hostname\n" .
+ "\toptions:\n" .
+ "\t\t--help\tshow this message\n" .
+ "\t\t--fspath\tThe file system path to save to, e.g /tmp/sitemap/\n" .
+ "\t\t--path\tThe http path to use, e.g. /wiki\n" .
+ "\t\t--compress=[yes|no]\tcompress the sitemap files, default yes\n";
+ die( -1 );
+}
+
+if ( isset( $argv[1] ) && strpos( $argv[1], '--' ) !== 0 )
+ $_SERVER['SERVER_NAME'] = $argv[1];
+
+$optionsWithArgs = array( 'fspath', 'path', 'compress' );
+require_once 'commandLine.inc';
+
+$gs = new GenerateSitemap( @$options['fspath'], @$options['path'], @$options['compress'] !== 'no' );
+$gs->main();
+?>
diff --git a/maintenance/getLagTimes.php b/maintenance/getLagTimes.php
new file mode 100644
index 000000000000..f2c06f6a7a9f
--- /dev/null
+++ b/maintenance/getLagTimes.php
@@ -0,0 +1,23 @@
+<?php
+
+require 'commandLine.inc';
+
+if( empty( $wgDBservers ) ) {
+ echo "This script dumps replication lag times, but you don't seem to have\n";
+ echo "a multi-host db server configuration.\n";
+} else {
+ $lags = $wgLoadBalancer->getLagTimes();
+ foreach( $lags as $n => $lag ) {
+ $host = $wgDBservers[$n]["host"];
+ if( IP::isValid( $host ) ) {
+ $ip = $host;
+ $host = gethostbyaddr( $host );
+ } else {
+ $ip = gethostbyname( $host );
+ }
+ $stars = str_repeat( '*', intval( $lag ) );
+ printf( "%10s %20s %3d %s\n", $ip, $host, $lag, $stars );
+ }
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/getSlaveServer.php b/maintenance/getSlaveServer.php
new file mode 100644
index 000000000000..ebeddc4c2309
--- /dev/null
+++ b/maintenance/getSlaveServer.php
@@ -0,0 +1,7 @@
+<?php
+
+require_once( dirname(__FILE__).'/commandLine.inc' );
+$i = $wgLoadBalancer->getReaderIndex();
+print $wgDBservers[$i]['host'] . "\n";
+
+?>
diff --git a/maintenance/importDump.php b/maintenance/importDump.php
new file mode 100644
index 000000000000..22709f64619e
--- /dev/null
+++ b/maintenance/importDump.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+$optionsWithArgs = array( 'report' );
+
+require_once( 'commandLine.inc' );
+require_once( 'SpecialImport.php' );
+
+class BackupReader {
+ var $reportingInterval = 100;
+ var $reporting = true;
+ var $pageCount = 0;
+ var $revCount = 0;
+ var $dryRun = false;
+
+ function BackupReader() {
+ $this->stderr = fopen( "php://stderr", "wt" );
+ }
+
+ function reportPage( $page ) {
+ $this->pageCount++;
+ }
+
+ function handleRevision( $rev ) {
+ $title = $rev->getTitle();
+ if (!$title) {
+ $this->progress( "Got bogus revision with null title!" );
+ return;
+ }
+ $display = $title->getPrefixedText();
+ $timestamp = $rev->getTimestamp();
+ #echo "$display $timestamp\n";
+
+ $this->revCount++;
+ $this->report();
+
+ if( !$this->dryRun ) {
+ call_user_func( $this->importCallback, $rev );
+ }
+ }
+
+ function report( $final = false ) {
+ if( $final xor ( $this->pageCount % $this->reportingInterval == 0 ) ) {
+ $this->showReport();
+ }
+ }
+
+ function showReport() {
+ if( $this->reporting ) {
+ $delta = wfTime() - $this->startTime;
+ if( $delta ) {
+ $rate = $this->pageCount / $delta;
+ $revrate = $this->revCount / $delta;
+ } else {
+ $rate = '-';
+ $revrate = '-';
+ }
+ $this->progress( "$this->pageCount ($rate pages/sec $revrate revs/sec)" );
+ }
+ }
+
+ function progress( $string ) {
+ fwrite( $this->stderr, $string . "\n" );
+ }
+
+ function importFromFile( $filename ) {
+ if( preg_match( '/\.gz$/', $filename ) ) {
+ $filename = 'compress.zlib://' . $filename;
+ }
+ $file = fopen( $filename, 'rt' );
+ return $this->importFromHandle( $file );
+ }
+
+ function importFromStdin() {
+ $file = fopen( 'php://stdin', 'rt' );
+ return $this->importFromHandle( $file );
+ }
+
+ function importFromHandle( $handle ) {
+ $this->startTime = wfTime();
+
+ $source = new ImportStreamSource( $handle );
+ $importer = new WikiImporter( $source );
+
+ $importer->setPageCallback( array( &$this, 'reportPage' ) );
+ $this->importCallback = $importer->setRevisionCallback(
+ array( &$this, 'handleRevision' ) );
+
+ return $importer->doImport();
+ }
+}
+
+if( wfReadOnly() ) {
+ wfDie( "Wiki is in read-only mode; you'll need to disable it for import to work.\n" );
+}
+
+$reader = new BackupReader();
+if( isset( $options['quiet'] ) ) {
+ $reader->reporting = false;
+}
+if( isset( $options['report'] ) ) {
+ $reader->reportingInterval = intval( $options['report'] );
+}
+if( isset( $options['dry-run'] ) ) {
+ $reader->dryRun = true;
+}
+
+if( isset( $args[0] ) ) {
+ $result = $reader->importFromFile( $args[0] );
+} else {
+ $result = $reader->importFromStdin();
+}
+
+if( WikiError::isError( $result ) ) {
+ echo $result->getMessage() . "\n";
+} else {
+ echo "Done!\n";
+ echo "You might want to run rebuildrecentchanges.php to regenerate\n";
+ echo "the recentchanges page.";
+}
+
+?>
diff --git a/maintenance/importImages.inc.php b/maintenance/importImages.inc.php
new file mode 100644
index 000000000000..bf48c0c7c1bd
--- /dev/null
+++ b/maintenance/importImages.inc.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * Support functions for the importImages script
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+/**
+ * Search a directory for files with one of a set of extensions
+ *
+ * @param $dir Path to directory to search
+ * @param $exts Array of extensions to search for
+ * @return mixed Array of filenames on success, or false on failure
+ */
+function findFiles( $dir, $exts ) {
+ if( is_dir( $dir ) ) {
+ if( $dhl = opendir( $dir ) ) {
+ while( ( $file = readdir( $dhl ) ) !== false ) {
+ if( is_file( $dir . '/' . $file ) ) {
+ list( $name, $ext ) = splitFilename( $dir . '/' . $file );
+ if( array_search( strtolower( $ext ), $exts ) !== false )
+ $files[] = $dir . '/' . $file;
+ }
+ }
+ return $files;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Split a filename into filename and extension
+ *
+ * @param $filename Filename
+ * @return array
+ */
+function splitFilename( $filename ) {
+ $parts = explode( '.', $filename );
+ $ext = $parts[ count( $parts ) - 1 ];
+ unset( $parts[ count( $parts ) - 1 ] );
+ $fname = implode( '.', $parts );
+ return array( $fname, $ext );
+}
+
+/**
+ * Given an image hash, check that the structure exists to save the image file
+ * and create it if it doesn't
+ *
+ * @param $hash Part of an image hash, e.g. /f/fd/
+ */
+function makeHashPath( $hash ) {
+ global $wgUploadDirectory;
+ $parts = explode( '/', substr( $hash, 1, strlen( $hash ) - 2 ) );
+ if( !is_dir( $wgUploadDirectory . '/' . $parts[0] ) )
+ mkdir( $wgUploadDirectory . '/' . $parts[0] );
+ if( !is_dir( $wgUploadDirectory . '/' . $hash ) )
+ mkdir( $wgUploadDirectory . '/' . $hash );
+}
+
+
+?> \ No newline at end of file
diff --git a/maintenance/importImages.php b/maintenance/importImages.php
new file mode 100644
index 000000000000..abf0ec097e7a
--- /dev/null
+++ b/maintenance/importImages.php
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * Maintenance script to import one or more images from the local file system into
+ * the wiki without using the web-based interface
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+require_once( 'commandLine.inc' );
+require_once( 'importImages.inc.php' );
+echo( "Import Images\n\n" );
+
+# Need a directory and at least one extension
+if( count( $args ) > 1 ) {
+
+ $dir = array_shift( $args );
+
+ # Check the allowed extensions
+ while( $ext = array_shift( $args ) )
+ $exts[] = ltrim( $ext, '.' );
+
+ # Search the directory given and pull out suitable candidates
+ $files = findFiles( $dir, $exts );
+
+ # Set up a fake user for this operation
+ if( isset( $options['user'] ) ) {
+ $wgUser = User::newFromName( $options['user'] );
+ } else {
+ $wgUser = User::newFromName( 'Image import script' );
+ }
+ if ( $wgUser->isAnon() ) {
+ $wgUser->addToDatabase();
+ }
+
+ # Get the upload comment
+ $comment = isset( $options['comment'] )
+ ? $options['comment']
+ : 'Importing image file';
+
+ # Get the license specifier
+ $license = isset( $options['license'] ) ? $options['license'] : '';
+
+ # Batch "upload" operation
+ foreach( $files as $file ) {
+
+ $base = wfBaseName( $file );
+
+ # Validate a title
+ $title = Title::makeTitleSafe( NS_IMAGE, $base );
+ if( is_object( $title ) ) {
+
+ # Check existence
+ $image = new Image( $title );
+ if( !$image->exists() ) {
+
+ global $wgUploadDirectory;
+
+ # copy() doesn't create paths so if the hash path doesn't exist, we
+ # have to create it
+ makeHashPath( wfGetHashPath( $image->name ) );
+
+ # Stash the file
+ echo( "Saving {$base}..." );
+
+ if( copy( $file, $image->getFullPath() ) ) {
+
+ echo( "importing..." );
+
+ # Grab the metadata
+ $image->loadFromFile();
+
+ # Record the upload
+ if( $image->recordUpload( '', $comment, $license ) ) {
+
+ # We're done!
+ echo( "done.\n" );
+
+ } else {
+ echo( "failed.\n" );
+ }
+
+ } else {
+ echo( "failed.\n" );
+ }
+
+ } else {
+ echo( "{$base} could not be imported; a file with this name exists in the wiki\n" );
+ }
+
+ } else {
+ echo( "{$base} could not be imported; a valid title cannot be produced\n" );
+ }
+
+ }
+
+
+} else {
+ showUsage();
+}
+
+exit();
+
+function showUsage( $reason = false ) {
+ if( $reason )
+ echo( $reason . "\n" );
+ echo <<<END
+USAGE: php importImages.php [options] <dir> <ext1> ...
+
+<dir> : Path to the directory containing images to be imported
+<ext1+> File extensions to import
+
+Options:
+--user=<username> Set username of uploader, default 'Image import script'
+--comment=<text> Set upload summary comment, default 'Importing image file'
+--license=<code> Use an optional license template
+
+END;
+ exit();
+}
+
+?>
diff --git a/maintenance/importLogs.inc b/maintenance/importLogs.inc
new file mode 100644
index 000000000000..154657c887ac
--- /dev/null
+++ b/maintenance/importLogs.inc
@@ -0,0 +1,144 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Attempt to import existing log pages into the log tables.
+ *
+ * Not yet complete.
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( 'GlobalFunctions.php' );
+require_once( 'Database.php' );
+require_once( 'Article.php' );
+require_once( 'LogPage.php' );
+
+/**
+ * Log importer
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+class LogImporter {
+ var $dummy = false;
+
+ function LogImporter( $type ) {
+ $this->type = $type;
+ $this->db =& wfGetDB( DB_MASTER );
+ $this->actions = $this->setupActions();
+ }
+
+ function setupActions() {
+ $actions = array();
+ foreach( LogPage::validActions( $this->type ) as $action ) {
+ $key = "{$this->type}/$action";
+ $actions[$key] = $this->makeLineRegexp( $this->type, $action );
+ }
+ return $actions;
+ }
+
+ function makeLineRegexp( $type, $action ) {
+ $linkRegexp = '(?:\[\[)?([^|\]]+?)(?:\|[^\]]+?)?(?:\]\])?';
+ $linkRegexp2 = '\[\[([^|\]]+?)(?:\|[^\]]+?)?\]\]';
+
+ $text = LogPage::actionText( $type, $action );
+ $text = preg_quote( $text, '/' );
+ $text = str_replace( '\$1', $linkRegexp, $text );
+ $text = '^(.*?) ' . $linkRegexp2 . ' ' . $text;
+ $text .= '(?: <em>\((.*)\)<\/em>)?';
+ $text = "/$text/";
+ return $text;
+ }
+
+ function importText( $text ) {
+ if( $this->dummy ) {
+ print $text;
+ var_dump( $this->actions );
+ }
+ $lines = explode( '<li>', $text );
+ foreach( $lines as $line ) {
+ if( preg_match( '!^(.*)</li>!', $line, $matches ) ) {
+ $this->importLine( $matches[1] );
+ }
+ }
+ }
+
+ function fixDate( $date ) {
+ # Yuck! Parsing multilingual date formats??!!!!???!!??!
+ # 01:55, 23 Aug 2004 - won't take in strtotimr
+ # "Aug 23 2004 01:55" - seems ok
+ # TODO: multilingual attempt to extract from the data in Language
+ if( preg_match( '/^(\d+:\d+(?::\d+)?), (.*)$/', $date, $matches ) ) {
+ $date = $matches[2] . ' ' . $matches[1];
+ }
+ $n = strtotime( $date ) + date("Z");
+ # print gmdate( 'D, d M Y H:i:s T', $n ) . "\n";
+ $timestamp = wfTimestamp( TS_MW, $n );
+ return $timestamp;
+ }
+
+ function importLine( $line ) {
+ foreach( $this->actions as $action => $regexp ) {
+ if( preg_match( $regexp, $line, $matches ) ) {
+ if( $this->dummy ) {
+ #var_dump( $matches );
+ }
+ $date = $this->fixDate( $matches[1] );
+ $user = Title::newFromText( $matches[2] );
+ $target = Title::newFromText( $matches[3] );
+ if( isset( $matches[4] ) ) {
+ $comment = $matches[4];
+ } else {
+ $comment = '';
+ }
+
+ $insert = array(
+ 'log_type' => $this->type,
+ 'log_action' => preg_replace( '!^.*/!', '', $action ),
+ 'log_timestamp' => $date,
+ 'log_user' => intval( User::idFromName( $user->getText() ) ),
+ 'log_namespace' => $target->getNamespace(),
+ 'log_title' => $target->getDBkey(),
+ 'log_comment' => wfUnescapeWikiText( $comment ),
+ );
+ if( $this->dummy ) {
+ var_dump( $insert );
+ } else {
+ # FIXME: avoid duplicates!
+ $this->db->insert( 'logging', $insert );
+ }
+ break;
+ }
+ }
+ }
+}
+
+function wfUnescapeWikiText( $text ) {
+ $text = str_replace(
+ array( '&#91;', '&#124;', '&#39;', 'ISBN&#32;', '&#58;//' , "\n&#61;", '&#123;&#123;' ),
+ array( '[', '|', "'", 'ISBN ' , '://' , "\n=", '{{' ),
+ $text );
+ return $text;
+}
+
+?>
diff --git a/maintenance/importLogs.php b/maintenance/importLogs.php
new file mode 100644
index 000000000000..6187c2e6e1fb
--- /dev/null
+++ b/maintenance/importLogs.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( "commandLine.inc" );
+require_once( "importLogs.inc" );
+
+#print $text;
+#exit();
+
+foreach( LogPage::validTypes() as $type ) {
+ if( $type == '' ) continue;
+
+ $page = LogPage::logName( $type );
+ $log = new Article( Title::makeTitleSafe( NS_PROJECT, $page ) );
+ $text = $log->fetchContent();
+
+ $importer = new LogImporter( $type );
+ $importer->dummy = true;
+ $importer->importText( $text );
+}
+
+?>
diff --git a/maintenance/importPhase2.php b/maintenance/importPhase2.php
new file mode 100644
index 000000000000..a73657b536b6
--- /dev/null
+++ b/maintenance/importPhase2.php
@@ -0,0 +1,370 @@
+<?php
+# MediaWiki 'phase 2' to current format import script
+# (import format current as of 1.2.0, March 2004)
+#
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# Portions by Lee Daniel Crocker, 2002
+# http://www.mediawiki.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
+
+/**
+ * @todo document
+ * @deprecated
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+die( "This import script is not currently maintained.
+If you need it you'll have to modify it as necessary.\n");
+
+if ( ! is_readable( "../LocalSettings.php" ) ) {
+ print "A copy of your installation's LocalSettings.php\n" .
+ "must exist in the source directory.\n";
+ exit();
+}
+
+$wgCommandLineMode = true;
+ini_set("implicit_flush", 1);
+
+$DP = "../includes";
+require_once( "../LocalSettings.php" );
+require_once( "../AdminSettings.php" );
+
+$wgDBuser = $wgDBadminuser;
+$wgDBpassword = $wgDBadminpassword;
+
+$sep = ( DIRECTORY_SEPARATOR == "\\" ) ? ";" : ":";
+ini_set( "include_path", "$IP$sep$include_path" );
+
+require_once( "Setup.php" );
+
+require_once( "../install-utils.inc" );
+require_once( "InitialiseMessages.inc" );
+require_once( "rebuildlinks.inc" );
+require_once( "rebuildrecentchanges.inc" );
+require_once( "rebuildtextindex.inc" );
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+class Phase2Importer {
+ var $olddb, $titleCache;
+
+ function Phase2Importer( $database ) {
+ $this->olddb = $database;
+ $this->titleCache = new TitleCache;
+ }
+
+ function importAll() {
+ $this->importCurData();
+ $this->fixCurTitles();
+
+ $this->importOldData();
+ $this->fixOldTitles();
+
+ $this->importUserData();
+ $this->fixUserOptions();
+
+ $this->importWatchlists();
+
+ $this->importLinkData();
+
+ /*
+ # For some reason this is broken. RecentChanges will just start anew...
+ rebuildRecentChangesTablePass1();
+ rebuildRecentChangesTablePass2();
+ */
+
+ print "Rebuilding search index:\n";
+ dropTextIndex();
+ rebuildTextIndex();
+ createTextIndex();
+
+ initialiseMessages();
+ }
+
+ # Simple import functions; for the most part these are pretty straightforward.
+ # MySQL copies everything over to the new database and tweaks a few things.
+ function importCurData() {
+ print "Clearing pages from default install, if any...\n";
+ wfQuery( "DELETE FROM cur", DB_MASTER );
+
+ print "Importing current revision data...\n";
+ wfQuery( "INSERT INTO cur (cur_id,cur_namespace,cur_title,cur_text,cur_comment,
+ cur_user,cur_user_text,cur_timestamp,cur_restrictions,cur_counter,
+ cur_is_redirect,cur_minor_edit,cur_is_new,cur_random,cur_touched)
+ SELECT cur_id,0,cur_title,cur_text,cur_comment,
+ cur_user,cur_user_text,cur_timestamp,REPLACE(cur_restrictions,'is_',''),cur_counter,
+ cur_text like '#redirect%',cur_minor_edit,0,RAND(),NOW()+0,
+ FROM {$this->olddb}.cur", DB_MASTER );
+ $n = mysql_affected_rows();
+ print "$n rows imported.\n";
+ }
+
+ function importOldData() {
+ print "Clearing old revision data from default install, if any...\n";
+ wfQuery( "DELETE FROM old", DB_MASTER );
+
+ print "Importing old revision data...\n";
+ wfQuery( "INSERT INTO old (old_id,old_namespace,old_title,old_text,old_comment,
+ old_user,old_user_text,old_timestamp,old_minor_edit,old_flags)
+ SELECT old_id,0,old_title,old_text,old_comment,
+ old_user,old_user_text,old_timestamp,old_minor_edit,''
+ FROM {$this->olddb}.old", DB_MASTER );
+ $n = mysql_affected_rows();
+ print "$n rows imported.\n";
+ }
+
+ function importUserData() {
+ print "Clearing users from default install, if any...\n";
+ wfQuery( "DELETE FROM user", DB_MASTER );
+
+ print "Importing user data...\n";
+ wfQuery( "INSERT INTO $newdb.user (user_id,user_name,user_rights,
+ user_password,user_newpassword,user_email,user_options,user_touched)
+ SELECT user_id,user_name,REPLACE(user_rights,'is_',''),
+ MD5(CONCAT(user_id,'-',MD5(user_password))),'',user_email,user_options,NOW()+0
+ FROM {$this->olddb}.user", DB_MASTER );
+ $n = mysql_affected_rows();
+ print "$n rows imported.\n";
+ }
+
+ # A little less clean...
+ function importWatchlists() {
+ print "Clearing watchlists from default install, if any...\n";
+ wfQuery( "DELETE FROM watchlist", DB_MASTER );
+
+ print "Importing watchlists...";
+ $res = wfQuery( "SELECT user_id,user_watch FROM {$this->olddb}.user WHERE user_watch != ''", DB_MASTER );
+ $total = wfNumRows( $res );
+ $n = 0;
+ print " ($total total)\n";
+
+ while( $row = wfFetchObject( $res ) ) {
+ $id = intval( $row->user_id );
+ $list = explode( "\n", $row->user_watch );
+ foreach( $list as $page ) {
+ $title = $this->titleCache->fetch( $page );
+ if( is_null( $title ) ) {
+ print "Caught bad title '{$row->title}'\n";
+ } else {
+ $ns = $title->getNamespace();
+ $t = wfStrencode( $title->getDBkey() );
+ wfQuery( "INSERT INTO watchlist(wl_user,wl_namespace,wl_title) VALUES ($id,$ns,'$t')", DB_MASTER );
+ }
+ }
+ if( ++$n % 50 == 0 ) {
+ print "$n\n";
+ }
+ }
+ wfFreeResult( $res );
+ }
+
+ function importLinkData() {
+ # MUST BE CALLED BEFORE! fixCurTitles()
+ print "Clearing links from default install, if any...\n";
+ wfQuery( "DELETE FROM links", DB_MASTER );
+ wfQuery( "DELETE FROM brokenlinks", DB_MASTER );
+
+ print "Importing live links...";
+ wfQuery( "INSERT INTO links (l_from, l_to)
+ SELECT DISTINCT linked_from,cur_id
+ FROM {$this->olddb}.linked,{$this->olddb}.cur
+ WHERE linked_to=cur_title", DB_MASTER );
+ $n = mysql_affected_rows();
+ print "$n rows imported.\n";
+
+ print "Importing broken links...";
+ wfQuery( "INSERT INTO brokenlinks (bl_from, bl_to)
+ SELECT DISTINCT cur_id,unlinked_to
+ FROM {$this->olddb}.unlinked,{$this->olddb}.cur
+ WHERE unlinked_from=cur_title", DB_MASTER );
+ $n = mysql_affected_rows();
+ print "$n rows imported.\n";
+ }
+
+ # Fixup functions: munge data that's already been brought into tables
+ function fixCurTitles() {
+ $this->fixTitles( "cur" );
+ }
+
+ function fixOldTitles() {
+ $this->fixTitles( "old" );
+ }
+
+ function fixTitles( $table ) {
+ print "Fixing titles in $table...";
+ $res = wfQuery( "SELECT DISTINCT {$table}_title AS title FROM $table", DB_MASTER );
+ $total = wfNumRows( $res );
+ $n = 0;
+ print " ($total total)\n";
+
+ while( $row = wfFetchObject( $res ) ) {
+ $xt = wfStrencode( $row->title );
+ $title = $this->titleCache->fetch( $row->title );
+ if( is_null( $title ) ) {
+ print "Caught bad title '{$row->title}'\n";
+ } else {
+ $ns = $title->getNamespace();
+ $t = wfStrencode( $title->getDBkey() );
+ wfQuery( "UPDATE $table SET {$table}_namespace=$ns,{$table}_title='$t'
+ WHERE {$table}_namespace=0 AND {$table}_title='$xt'", DB_MASTER );
+ }
+ if( ++$n % 50 == 0 ) {
+ print "$n\n";
+ }
+ }
+ wfFreeResult( $res );
+ }
+
+ function rewriteUserOptions( $in )
+ {
+ $s = urldecode( $in );
+ $a = explode( "\n", $s );
+
+ foreach ( $a as $l ) {
+ if ( preg_match( "/^([A-Za-z0-9_]+)=(.*)/", $l, $m ) ) {
+ $ops[$m[1]] = $m[2];
+ }
+ }
+ $nops = array();
+
+ $q = strtolower( $ops["quickBar"] );
+ if ( $q == "none" ) { $q = 0; }
+ else { $q = 1; } # Default to left
+ $nops["quickbar"] = $q;
+
+ if ( $ops["markupNewTopics"] == "inverse" ) {
+ $nops["highlightbroken"] = 1;
+ }
+ $sk = substr( strtolower( $ops["skin"] ), 0, 4 );
+ if ( "star" == $sk ) { $sk = 0; }
+ else if ( "nost" == $sk ) { $sk = 1; }
+ else if ( "colo" == $sk ) { $sk = 2; }
+ else { $sk = 0; }
+ $nops["skin"] = $sk;
+
+ $u = strtolower( $ops["underlineLinks"] );
+ if ( "yes" == $u || "on" == $u ) { $nops["underline"] = 1; }
+ else { $nops["underline"] = 0; }
+
+ $t = ( (int) ($ops["hourDiff"]) );
+ if ( $t < -23 || $t > 23 ) { $t = 0; }
+ if ( 0 != $t ) { $nops["timecorrection"] = $t; }
+
+ $j = strtolower( $ops["justify"] );
+ if ( "yes" == $j || "on" == $j ) { $nops["justify"] = 1; }
+ $n = strtolower( $ops["numberHeadings"] );
+ if ( "yes" == $n || "on" == $n ) { $nops["numberheadings"] = 1; }
+ $h = strtolower( $ops["hideMinor"] );
+ if ( "yes" == $h || "on" == $h ) { $nops["hideminor"] = 1; }
+ $r = strtolower( $ops["rememberPassword"] );
+ if ( "yes" == $r || "on" == $r ) { $nops["rememberpassword"] = 1; }
+ $s = strtolower( $ops["showHover"] );
+ if ( "yes" == $s || "on" == $s ) { $nops["hover"] = 1; }
+
+ $c = $ops["cols"];
+ if ( $c < 20 || $c > 200 ) { $nops["cols"] = 80; }
+ else { $nops["cols"] = $c; }
+ $r = $ops["rows"];
+ if ( $r < 5 || $r > 100 ) { $nops["rows"] = 20; }
+ else { $nops["rows"] = $r; }
+ $r = $ops["resultsPerPage"];
+ if ( $r < 3 || $r > 500 ) { $nops["searchlimit"] = 20; }
+ else { $nops["searchlimit"] = $r; }
+ $r = $ops["viewRecentChanges"];
+ if ( $r < 10 || $r > 1000 ) { $nops["rclimit"] = 50; }
+ else { $nops["rclimit"] = $r; }
+ $nops["rcdays"] = 3;
+
+ $a = array();
+ foreach ( $nops as $oname => $oval ) {
+ array_push( $a, "$oname=$oval" );
+ }
+ $s = implode( "\n", $a );
+ return $s;
+ }
+
+ function fixUserOptions() {
+ print "Fixing user options...";
+ $res = wfQuery( "SELECT user_id,user_options FROM user", DB_MASTER );
+ $total = wfNumRows( $res );
+ $n = 0;
+ print " ($total total)\n";
+
+ while( $row = wfFetchObject( $res ) ) {
+ $id = intval( $row->user_id );
+ $option = wfStrencode( $this->rewriteUserOptions( $row->user_options ) );
+ wfQuery( "UPDATE user SET user_options='$option' WHERE user_id=$id LIMIT 1", DB_MASTER );
+ if( ++$n % 50 == 0 ) {
+ print "$n\n";
+ }
+ }
+ wfFreeResult( $res );
+ }
+
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+class TitleCache {
+ var $hash = array();
+
+ function &fetch( $dbkey ) {
+ if( !isset( $hash[$dbkey] ) ) {
+ $hash[$dbkey] = Title::newFromDBkey( $dbkey );
+ }
+ return $hash[$dbkey];
+ }
+
+}
+
+#
+print "You should have already run the installer to create a fresh, blank database.\n";
+print "Data will be inserted into '$wgDBname'. THIS SHOULD BE EMPTY AND ANY DATA IN IN WILL BE ERASED!\n";
+print "\nIf that's not what you want, ABORT NOW!\n\n";
+
+print "Please enter the name of the old 'phase 2'-format database that will be used as a source:\n";
+print "Old database name [enciclopedia]: ";
+$olddb = readconsole();
+if( empty( $olddb ) ) $olddb = "enciclopedia";
+
+if( $olddb == $wgDBname ) {
+ die( "Can't upgrade in-place! You must create a new database and copy data into it.\n" );
+}
+
+print "\nSource database: '$olddb'\n";
+print " Dest database: '$wgDBname'\n";
+print "Is this correct? Anything in '$wgDBname' WILL BE DESTROYED. [y/N] ";
+$response = readconsole();
+if( strtolower( $response{0} ) != 'y' ) {
+ die( "\nAborted by user.\n" );
+}
+
+print "Starting import....\n";
+
+$wgTitle = Title::newFromText( "Conversion script" );
+$importer = new Phase2Importer( $olddb );
+$importer->importAll();
+
+?>
diff --git a/maintenance/importTextFile.php b/maintenance/importTextFile.php
new file mode 100644
index 000000000000..92c31fd0fa1a
--- /dev/null
+++ b/maintenance/importTextFile.php
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * Maintenance script allows creating or editing pages using
+ * the contents of a text file
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+$options = array( 'help', 'nooverwrite' );
+$optionsWithArgs = array( 'title', 'user', 'comment' );
+require_once( 'commandLine.inc' );
+echo( "Import Text File\n\n" );
+
+if( isset( $options['help'] ) ) {
+ showHelp();
+} else {
+
+ $filename = $args[0];
+ echo( "Using {$filename}..." );
+ if( is_file( $filename ) ) {
+
+ $title = isset( $options['title'] ) ? $options['title'] : titleFromFilename( $filename );
+ $title = Title::newFromUrl( $title );
+ echo( "\nUsing title '" . $title->getPrefixedText() . "'..." );
+
+ if( is_object( $title ) ) {
+
+ if( !$title->exists() || !isset( $options['nooverwrite'] ) ) {
+
+ $text = file_get_contents( $filename );
+ $user = isset( $options['user'] ) ? $options['user'] : 'MediaWiki default';
+ $user = User::newFromName( $user );
+ echo( "\nUsing username '" . $user->getName() . "'..." );
+
+ if( is_object( $user ) ) {
+
+ $wgUser =& $user;
+ $comment = isset( $options['comment'] ) ? $options['comment'] : 'Importing text file';
+ $comment = str_replace( '_', ' ', $comment );
+
+ echo( "\nPerforming edit..." );
+ $article = new Article( $title );
+ $article->doEdit( $text, $comment );
+ echo( "done.\n" );
+
+ } else {
+ echo( "invalid username.\n" );
+ }
+
+ } else {
+ echo( "page exists.\n" );
+ }
+
+ } else {
+ echo( "invalid title.\n" );
+ }
+
+ } else {
+ echo( "does not exist.\n" );
+ }
+
+}
+
+function titleFromFilename( $filename ) {
+ $parts = explode( '/', $filename );
+ $parts = explode( '.', $parts[ count( $parts ) - 1 ] );
+ return $parts[0];
+}
+
+function showHelp() {
+ echo( "Import the contents of a text file into a wiki page.\n\n" );
+ echo( "USAGE: php importTextFile.php [--help|--title <title>|--user <user>|--comment <comment>|--nooverwrite] <filename>\n\n" );
+ echo( " --help: Show this help information\n" );
+ echo( " --title <title> : Title for the new page; if not supplied, the filename is used as a base for the title\n" );
+ echo( " --user <user> : User to be associated with the edit; if not supplied, a default is used\n" );
+ echo( "--comment <comment> : Edit summary to be associated with the edit; underscores are transformed into spaces; if not supplied, a default is used\n" );
+ echo( " --nooverwrite : Don't overwrite existing page content\n" );
+ echo( " <filename> : Path to the file containing the wikitext to import\n\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/importUseModWiki.php b/maintenance/importUseModWiki.php
new file mode 100644
index 000000000000..15f5e4442e39
--- /dev/null
+++ b/maintenance/importUseModWiki.php
@@ -0,0 +1,365 @@
+<?php
+
+/**
+ * Import data from a UseModWiki into a MediaWiki wiki
+ * 2003-02-09 Brion VIBBER <brion@pobox.com>
+ * Based loosely on Magnus's code from 2001-2002
+ *
+ * Updated limited version to get something working temporarily
+ * 2003-10-09
+ * Be sure to run the link & index rebuilding scripts!
+ *
+ * Some more munging for charsets etc
+ * 2003-11-28
+ *
+ * Partial fix for pages starting with lowercase letters (??)
+ * and CamelCase and /Subpage link conversion
+ * 2004-11-17
+ *
+ * Rewrite output to create Special:Export format for import
+ * instead of raw SQL. Should be 'future-proof' against future
+ * schema changes.
+ * 2005-03-14
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+if( php_sapi_name() != 'cli' ) {
+ echo "Please customize the settings and run me from the command line.";
+ die( -1 );
+}
+
+/** Set these correctly! */
+$wgImportEncoding = "CP1252"; /* We convert all to UTF-8 */
+$wgRootDirectory = "/kalman/Projects/wiki2002/wiki/lib-http/db/wiki";
+
+/* On a large wiki, you might run out of memory */
+@ini_set( 'memory_limit', '40M' );
+
+/* globals */
+$wgFieldSeparator = "\xb3"; # Some wikis may use different char
+ $FS = $wgFieldSeparator ;
+ $FS1 = $FS."1" ;
+ $FS2 = $FS."2" ;
+ $FS3 = $FS."3" ;
+
+# Unicode sanitization tools
+require_once( '../includes/normal/UtfNormal.php' );
+
+$usercache = array();
+
+importPages();
+
+# ------------------------------------------------------------------------------
+
+function importPages()
+{
+ global $wgRootDirectory;
+
+ $gt = '>';
+ echo <<<END
+<?xml version="1.0" encoding="UTF-8" ?$gt
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.1/"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.1/
+ http://www.mediawiki.org/xml/export-0.1.xsd"
+ version="0.1"
+ xml:lang="en">
+<!-- generated by importUseModWiki.php -->
+
+END;
+ $letters = array(
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
+ 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'other' );
+ foreach( $letters as $letter ) {
+ $dir = "$wgRootDirectory/page/$letter";
+ if( is_dir( $dir ) )
+ importPageDirectory( $dir );
+ }
+ echo <<<END
+</mediawiki>
+
+END;
+}
+
+function importPageDirectory( $dir, $prefix = "" )
+{
+ echo "\n<!-- Checking page directory " . xmlCommentSafe( $dir ) . " -->\n";
+ $mydir = opendir( $dir );
+ while( $entry = readdir( $mydir ) ) {
+ if( preg_match( '/^(.+)\.db$/', $entry, $m ) ) {
+ echo importPage( $prefix . $m[1] );
+ } else {
+ if( is_dir( "$dir/$entry" ) ) {
+ if( $entry != '.' && $entry != '..' ) {
+ importPageDirectory( "$dir/$entry", "$entry/" );
+ }
+ } else {
+ echo "<!-- File '" . xmlCommentSafe( $entry ) . "' doesn't seem to contain an article. Skipping. -->\n";
+ }
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+
+/* fetch_ functions
+ Grab a given item from the database
+ */
+
+function useModFilename( $title ) {
+ $c = substr( $title, 0, 1 );
+ if(preg_match( '/[A-Z]/i', $c ) ) {
+ return strtoupper( $c ) . "/$title";
+ }
+ return "other/$title";
+}
+
+function fetchPage( $title )
+{
+ global $FS,$FS1,$FS2,$FS3, $wgRootDirectory;
+
+ $fname = $wgRootDirectory . "/page/" . useModFilename( $title ) . ".db";
+ if( !file_exists( $fname ) ) {
+ echo "Couldn't open file '$fname' for page '$title'.\n";
+ die( -1 );
+ }
+
+ $page = splitHash( $FS1, file_get_contents( $fname ) );
+ $section = splitHash( $FS2, $page["text_default"] );
+ $text = splitHash( $FS3, $section["data"] );
+
+ return array2object( array( "text" => $text["text"] , "summary" => $text["summary"] ,
+ "minor" => $text["minor"] , "ts" => $section["ts"] ,
+ "username" => $section["username"] , "host" => $section["host"] ) );
+}
+
+function fetchKeptPages( $title )
+{
+ global $FS,$FS1,$FS2,$FS3, $wgRootDirectory, $wgTimezoneCorrection;
+
+ $fname = $wgRootDirectory . "/keep/" . useModFilename( $title ) . ".kp";
+ if( !file_exists( $fname ) ) return array();
+
+ $keptlist = explode( $FS1, file_get_contents( $fname ) );
+ array_shift( $keptlist ); # Drop the junk at beginning of file
+
+ $revisions = array();
+ foreach( $keptlist as $rev ) {
+ $section = splitHash( $FS2, $rev );
+ $text = splitHash( $FS3, $section["data"] );
+ if ( $text["text"] && $text["minor"] != "" && ( $section["ts"]*1 > 0 ) ) {
+ array_push( $revisions, array2object( array ( "text" => $text["text"] , "summary" => $text["summary"] ,
+ "minor" => $text["minor"] , "ts" => $section["ts"] ,
+ "username" => $section["username"] , "host" => $section["host"] ) ) );
+ } else {
+ echo "<!-- skipped a bad old revision -->\n";
+ }
+ }
+ return $revisions;
+}
+
+function splitHash ( $sep , $str ) {
+ $temp = explode ( $sep , $str ) ;
+ $ret = array () ;
+ for ( $i = 0; $i+1 < count ( $temp ) ; $i++ ) {
+ $ret[$temp[$i]] = $temp[++$i] ;
+ }
+ return $ret ;
+ }
+
+
+/* import_ functions
+ Take a fetched item and produce SQL
+ */
+
+function checkUserCache( $name, $host )
+{
+ global $usercache;
+
+ if( $name ) {
+ if( in_array( $name, $usercache ) ) {
+ $userid = $usercache[$name];
+ } else {
+ # If we haven't imported user accounts
+ $userid = 0;
+ }
+ $username = str_replace( '_', ' ', $name );
+ } else {
+ $userid = 0;
+ $username = $host;
+ }
+ return array( $userid, $username );
+}
+
+function importPage( $title )
+{
+ global $usercache;
+
+ echo "\n<!-- Importing page " . xmlCommentSafe( $title ) . " -->\n";
+ $page = fetchPage( $title );
+
+ $newtitle = xmlsafe( str_replace( '_', ' ', recodeText( $title ) ) );
+
+ $munged = mungeFormat( $page->text );
+ if( $munged != $page->text ) {
+ /**
+ * Save a *new* revision with the conversion, and put the
+ * previous last version into the history.
+ */
+ $next = array2object( array(
+ 'text' => $munged,
+ 'minor' => 1,
+ 'username' => 'Conversion script',
+ 'host' => '127.0.0.1',
+ 'ts' => time(),
+ 'summary' => 'link fix',
+ ) );
+ $revisions = array( $page, $next );
+ } else {
+ /**
+ * Current revision:
+ */
+ $revisions = array( $page );
+ }
+ $xml = <<<END
+ <page>
+ <title>$newtitle</title>
+
+END;
+
+ # History
+ $revisions = array_merge( $revisions, fetchKeptPages( $title ) );
+ if(count( $revisions ) == 0 ) {
+ return $sql;
+ }
+
+ foreach( $revisions as $rev ) {
+ $text = xmlsafe( recodeText( $rev->text ) );
+ $minor = ($rev->minor ? '<minor/>' : '');
+ list( $userid, $username ) = checkUserCache( $rev->username, $rev->host );
+ $username = xmlsafe( recodeText( $username ) );
+ $timestamp = xmlsafe( timestamp2ISO8601( $rev->ts ) );
+ $comment = xmlsafe( recodeText( $rev->summary ) );
+
+ $xml .= <<<END
+ <revision>
+ <timestamp>$timestamp</timestamp>
+ <contributor><username>$username</username></contributor>
+ $minor
+ <comment>$comment</comment>
+ <text>$text</text>
+ </revision>
+
+END;
+ }
+ $xml .= "</page>\n\n";
+ return $xml;
+}
+
+# Whee!
+function recodeText( $string ) {
+ global $wgImportEncoding;
+ # For currently latin-1 wikis
+ $string = str_replace( "\r\n", "\n", $string );
+ $string = @iconv( $wgImportEncoding, "UTF-8", $string );
+ $string = wfMungeToUtf8( $string ); # Any old &#1234; stuff
+ return $string;
+}
+
+function wfUtf8Sequence($codepoint) {
+ if($codepoint < 0x80) return chr($codepoint);
+ if($codepoint < 0x800) return chr($codepoint >> 6 & 0x3f | 0xc0) .
+ chr($codepoint & 0x3f | 0x80);
+ if($codepoint < 0x10000) return chr($codepoint >> 12 & 0x0f | 0xe0) .
+ chr($codepoint >> 6 & 0x3f | 0x80) .
+ chr($codepoint & 0x3f | 0x80);
+ if($codepoint < 0x100000) return chr($codepoint >> 18 & 0x07 | 0xf0) . # Double-check this
+ chr($codepoint >> 12 & 0x3f | 0x80) .
+ chr($codepoint >> 6 & 0x3f | 0x80) .
+ chr($codepoint & 0x3f | 0x80);
+ # Doesn't yet handle outside the BMP
+ return "&#$codepoint;";
+}
+
+function wfMungeToUtf8($string) {
+ $string = preg_replace ( '/&#([0-9]+);/e', 'wfUtf8Sequence($1)', $string );
+ $string = preg_replace ( '/&#x([0-9a-f]+);/ie', 'wfUtf8Sequence(0x$1)', $string );
+ # Should also do named entities here
+ return $string;
+}
+
+function timestamp2ISO8601( $ts ) {
+ #2003-08-05T18:30:02Z
+ return gmdate( 'Y-m-d', $ts ) . 'T' . gmdate( 'H:i:s', $ts ) . 'Z';
+}
+
+function xmlsafe( $string ) {
+ /**
+ * The page may contain old data which has not been properly normalized.
+ * Invalid UTF-8 sequences or forbidden control characters will make our
+ * XML output invalid, so be sure to strip them out.
+ */
+ $string = UtfNormal::cleanUp( $string );
+
+ $string = htmlspecialchars( $string );
+ return $string;
+}
+
+function xmlCommentSafe( $text ) {
+ return str_replace( '--', '\\-\\-', xmlsafe( recodeText( $text ) ) );
+}
+
+
+function array2object( $arr ) {
+ $o = (object)0;
+ foreach( $arr as $x => $y ) {
+ $o->$x = $y;
+ }
+ return $o;
+}
+
+
+/**
+ * Make CamelCase and /Talk links work
+ */
+function mungeFormat( $text ) {
+ global $nowiki;
+ $nowiki = array();
+ $staged = preg_replace_callback(
+ '/(<nowiki>.*?<\\/nowiki>|(?:http|https|ftp):\\S+|\[\[[^]\\n]+]])/s',
+ 'nowikiPlaceholder', $text );
+
+ # This is probably not 100% correct, I'm just
+ # glancing at the UseModWiki code.
+ $upper = "[A-Z]";
+ $lower = "[a-z_0-9]";
+ $any = "[A-Za-z_0-9]";
+ $camel = "(?:$upper+$lower+$upper+$any*)";
+ $subpage = "(?:\\/$any+)";
+ $substart = "(?:\\/$upper$any*)";
+
+ $munged = preg_replace( "/(?!\\[\\[)($camel$subpage*|$substart$subpage*)\\b(?!\\]\\]|>)/",
+ '[[$1]]', $staged );
+
+ $final = preg_replace( '/' . preg_quote( placeholder() ) . '/es',
+ 'array_shift( $nowiki )', $munged );
+ return $final;
+}
+
+
+function placeholder( $x = null ) {
+ return '\xffplaceholder\xff';
+}
+
+function nowikiPlaceholder( $matches ) {
+ global $nowiki;
+ $nowiki[] = $matches[1];
+ return placeholder();
+}
+
+?>
diff --git a/maintenance/initEditCount.php b/maintenance/initEditCount.php
new file mode 100644
index 000000000000..9d165cfba51a
--- /dev/null
+++ b/maintenance/initEditCount.php
@@ -0,0 +1,85 @@
+<?php
+
+require_once "commandLine.inc";
+
+if( isset( $options['help'] ) ) {
+ die( "Batch-recalculate user_editcount fields from the revision table.
+Options:
+ --quick Force the update to be done in a single query.
+ --background Force replication-friendly mode; may be inefficient but
+ avoids locking tables or lagging slaves with large updates;
+ calculates counts on a slave if possible.
+
+Background mode will be automatically used if the server is MySQL 4.0
+(which does not support subqueries) or if multiple servers are listed
+in \$wgDBservers, usually indicating a replication environment.
+
+");
+}
+$dbw = wfGetDB( DB_MASTER );
+$user = $dbw->tableName( 'user' );
+$revision = $dbw->tableName( 'revision' );
+
+$dbver = $dbw->getServerVersion();
+
+// Autodetect mode...
+$backgroundMode = count( $wgDBservers ) > 1 ||
+ ($dbw instanceof DatabaseMySql && version_compare( $dbver, '4.1' ) < 0);
+
+if( isset( $options['background'] ) ) {
+ $backgroundMode = true;
+} elseif( isset( $options['quick'] ) ) {
+ $backgroundMode = false;
+}
+
+if( $backgroundMode ) {
+ echo "Using replication-friendly background mode...\n";
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $chunkSize = 100;
+ $lastUser = $dbr->selectField( 'user', 'MAX(user_id)', '', __FUNCTION__ );
+
+ $start = microtime( true );
+ $migrated = 0;
+ for( $min = 0; $min <= $lastUser; $min += $chunkSize ) {
+ $max = $min + $chunkSize;
+ $result = $dbr->query(
+ "SELECT
+ user_id,
+ COUNT(rev_user) AS user_editcount
+ FROM $user
+ LEFT OUTER JOIN $revision ON user_id=rev_user
+ WHERE user_id > $min AND user_id <= $max
+ GROUP BY user_id",
+ __FUNCTION__ );
+
+ while( $row = $dbr->fetchObject( $result ) ) {
+ $dbw->update( 'user',
+ array( 'user_editcount' => $row->user_editcount ),
+ array( 'user_id' => $row->user_id ),
+ __FUNCTION__ );
+ ++$migrated;
+ }
+ $dbr->freeResult( $result );
+
+ $delta = microtime( true ) - $start;
+ $rate = ($delta == 0.0) ? 0.0 : $migrated / $delta;
+ printf( "%s %d (%0.1f%%) done in %0.1f secs (%0.3f accounts/sec).\n",
+ $wgDBname,
+ $migrated,
+ min( $max, $lastUser ) / $lastUser * 100.0,
+ $delta,
+ $rate );
+
+ wfWaitForSlaves( 10 );
+ }
+} else {
+ // Subselect should work on modern MySQLs etc
+ echo "Using single-query mode...\n";
+ $sql = "UPDATE $user SET user_editcount=(SELECT COUNT(*) FROM $revision WHERE rev_user=user_id)";
+ $dbw->query( $sql );
+}
+
+echo "Done!\n";
+
+?>
diff --git a/maintenance/initStats.php b/maintenance/initStats.php
new file mode 100644
index 000000000000..291de1eeb8f6
--- /dev/null
+++ b/maintenance/initStats.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * Maintenance script to re-initialise or update the site statistics table
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Brion Vibber
+ * @author Rob Church <robchur@gmail.com>
+ * @licence GNU General Public Licence 2.0 or later
+ */
+
+$options = array( 'help', 'update', 'noviews' );
+require_once( 'commandLine.inc' );
+echo( "Refresh Site Statistics\n\n" );
+$dbr =& wfGetDB( DB_SLAVE );
+$fname = 'initStats';
+
+if( isset( $options['help'] ) ) {
+ showHelp();
+ exit();
+}
+
+echo( "Counting total edits..." );
+$edits = $dbr->selectField( 'revision', 'COUNT(*)', '', $fname );
+$edits += $dbr->selectField( 'archive', 'COUNT(*)', '', $fname );
+echo( "{$edits}\nCounting number of articles..." );
+
+global $wgContentNamespaces;
+$good = $dbr->selectField( 'page', 'COUNT(*)', array( 'page_namespace' => $wgContentNamespaces, 'page_is_redirect' => 0, 'page_len > 0' ), $fname );
+echo( "{$good}\nCounting total pages..." );
+
+$pages = $dbr->selectField( 'page', 'COUNT(*)', '', $fname );
+echo( "{$pages}\nCounting number of users..." );
+
+$users = $dbr->selectField( 'user', 'COUNT(*)', '', $fname );
+echo( "{$users}\nCounting number of admins..." );
+
+$admin = $dbr->selectField( 'user_groups', 'COUNT(*)', array( 'ug_group' => 'sysop' ), $fname );
+echo( "{$admin}\nCounting number of images..." );
+
+$image = $dbr->selectField( 'image', 'COUNT(*)', '', $fname );
+echo( "{$image}\n" );
+
+if( !isset( $options['noviews'] ) ) {
+ echo( "Counting total page views..." );
+ $views = $dbr->selectField( 'page', 'SUM(page_counter)', '', $fname );
+ echo( "{$views}\n" );
+}
+
+echo( "\nUpdating site statistics..." );
+
+$dbw =& wfGetDB( DB_MASTER );
+$values = array( 'ss_total_edits' => $edits,
+ 'ss_good_articles' => $good,
+ 'ss_total_pages' => $pages,
+ 'ss_users' => $users,
+ 'ss_admins' => $admin,
+ 'ss_images' => $image );
+$conds = array( 'ss_row_id' => 1 );
+$views = array( 'ss_total_views' => isset( $views ) ? $views : 0 );
+
+if( isset( $options['update'] ) ) {
+ $dbw->update( 'site_stats', $values, $conds, $fname );
+} else {
+ $dbw->delete( 'site_stats', $conds, $fname );
+ $dbw->insert( 'site_stats', array_merge( $values, $conds, $views ), $fname );
+}
+
+echo( "done.\n\n" );
+
+function showHelp() {
+ echo( "Re-initialise the site statistics tables.\n\n" );
+ echo( "Usage: php initStats.php [--update|--noviews]\n\n" );
+ echo( " --update : Update the existing statistics (preserves the ss_total_views field)\n" );
+ echo( "--noviews : Don't update the page view counter\n\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/installExtension.php b/maintenance/installExtension.php
new file mode 100644
index 000000000000..f6b2dff4abce
--- /dev/null
+++ b/maintenance/installExtension.php
@@ -0,0 +1,642 @@
+<?php
+/**
+ * Copyright (C) 2006 Daniel Kinzler, brightbyte.de
+ *
+ * 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
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+$optionsWithArgs = array( 'target', 'repository', 'repos' );
+
+require_once( 'commandLine.inc' );
+
+define('EXTINST_NOPATCH', 0);
+define('EXTINST_WRITEPATCH', 6);
+define('EXTINST_HOTPATCH', 10);
+
+class InstallerRepository {
+ var $path;
+
+ function InstallerRepository( $path ) {
+ $this->path = $path;
+ }
+
+ function printListing( ) {
+ trigger_error( 'override InstallerRepository::printListing()', E_USER_ERROR );
+ }
+
+ function getResource( $name ) {
+ trigger_error( 'override InstallerRepository::getResource()', E_USER_ERROR );
+ }
+
+ /*static*/ function makeRepository( $path, $type = NULL ) {
+ if ( !$type ) {
+ preg_match( '!(([-+\w]+)://)?.*?(\.[-\w\d.]+)?$!', $path, $m );
+ $proto = @$m[2];
+
+ if( !$proto ) $type = 'dir';
+ else if ( ( $proto == 'http' || $proto == 'https' )
+ && preg_match( '!([^\w]svn|svn[^\w])!i', $path) ) $type = 'svn'; #HACK!
+ else $type = $proto;
+ }
+
+ if ( $type == 'dir' || $type == 'file' ) return new LocalInstallerRepository( $path );
+ else if ( $type == 'http' || $type == 'http' ) return new WebInstallerRepository( $path );
+ else return new SVNInstallerRepository( $path );
+ }
+}
+
+class LocalInstallerRepository extends InstallerRepository {
+
+ function LocalInstallerRepository ( $path ) {
+ InstallerRepository::InstallerRepository( $path );
+ }
+
+ function printListing( ) {
+ $ff = glob( "{$this->path}/*" );
+ if ( $ff === false || $ff === NULL ) {
+ ExtensionInstaller::error( "listing directory $repos failed!" );
+ return false;
+ }
+
+ foreach ( $ff as $f ) {
+ $n = basename($f);
+
+ if ( !is_dir( $f ) ) {
+ if ( !preg_match( '/(.*)\.(tgz|tar\.gz|zip)/', $n, $m ) ) continue;
+ $n = $m[1];
+ }
+
+ print "\t$n\n";
+ }
+ }
+
+ function getResource( $name ) {
+ $path = $this->path . '/' . $name;
+
+ if ( !file_exists( $path ) || !is_dir( $path ) ) $path = $this->path . '/' . $name . '.tgz';
+ if ( !file_exists( $path ) ) $path = $this->path . '/' . $name . '.tar.gz';
+ if ( !file_exists( $path ) ) $path = $this->path . '/' . $name . '.zip';
+
+ return new LocalInstallerResource( $path );
+ }
+}
+
+class WebInstallerRepository extends InstallerRepository {
+
+ function WebInstallerRepository ( $path ) {
+ InstallerRepository::InstallerRepository( $path );
+ }
+
+ function printListing( ) {
+ ExtensionInstaller::note( "listing index from {$this->path}..." );
+
+ $txt = @file_get_contents( $this->path . '/index.txt' );
+ if ( $txt ) {
+ print $txt;
+ print "\n";
+ }
+ else {
+ $txt = file_get_contents( $this->path );
+ if ( !$txt ) {
+ ExtensionInstaller::error( "listing index from {$this->path} failed!" );
+ print ( $txt );
+ return false;
+ }
+
+ $ok = preg_match_all( '!<a\s[^>]*href\s*=\s*['."'".'"]([^/'."'".'"]+)\.tgz['."'".'"][^>]*>.*?</a>!si', $txt, $m, PREG_SET_ORDER );
+ if ( !$ok ) {
+ ExtensionInstaller::error( "listing index from {$this->path} does not match!" );
+ print ( $txt );
+ return false;
+ }
+
+ foreach ( $m as $l ) {
+ $n = $l[1];
+ print "\t$n\n";
+ }
+ }
+ }
+
+ function getResource( $name ) {
+ $path = $this->path . '/' . $name . '.tgz';
+ return new WebInstallerResource( $path );
+ }
+}
+
+class SVNInstallerRepository extends InstallerRepository {
+
+ function SVNInstallerRepository ( $path ) {
+ InstallerRepository::InstallerRepository( $path );
+ }
+
+ function printListing( ) {
+ ExtensionInstaller::note( "SVN list {$this->path}..." );
+ $txt = wfShellExec( 'svn ls ' . escapeshellarg( $this->path ), $code );
+ if ( $code !== 0 ) {
+ ExtensionInstaller::error( "svn list for {$this->path} failed!" );
+ return false;
+ }
+
+ $ll = preg_split('/(\s*[\r\n]\s*)+/', $txt);
+
+ foreach ( $ll as $line ) {
+ if ( !preg_match('!^(.*)/$!', $line, $m) ) continue;
+ $n = $m[1];
+
+ print "\t$n\n";
+ }
+ }
+
+ function getResource( $name ) {
+ $path = $this->path . '/' . $name;
+ return new SVNInstallerResource( $path );
+ }
+}
+
+class InstallerResource {
+ var $path;
+ var $isdir;
+ var $islocal;
+
+ function InstallerResource( $path, $isdir, $islocal ) {
+ $this->path = $path;
+
+ $this->isdir= $isdir;
+ $this->islocal = $islocal;
+
+ preg_match( '!([-+\w]+://)?.*?(\.[-\w\d.]+)?$!', $path, $m );
+
+ $this->protocol = @$m[1];
+ $this->extensions = @$m[2];
+
+ if ( $this->extensions ) $this->extensions = strtolower( $this->extensions );
+ }
+
+ function fetch( $target ) {
+ trigger_error( 'override InstallerResource::fetch()', E_USER_ERROR );
+ }
+
+ function extract( $file, $target ) {
+
+ if ( $this->extensions == '.tgz' || $this->extensions == '.tar.gz' ) { #tgz file
+ ExtensionInstaller::note( "extracting $file..." );
+ wfShellExec( 'tar zxvf ' . escapeshellarg( $file ) . ' -C ' . escapeshellarg( $target ), $code );
+
+ if ( $code !== 0 ) {
+ ExtensionInstaller::error( "failed to extract $file!" );
+ return false;
+ }
+ }
+ else if ( $this->extensions == '.zip' ) { #zip file
+ ExtensionInstaller::note( "extracting $file..." );
+ wfShellExec( 'unzip ' . escapeshellarg( $file ) . ' -d ' . escapeshellarg( $target ) , $code );
+
+ if ( $code !== 0 ) {
+ ExtensionInstaller::error( "failed to extract $file!" );
+ return false;
+ }
+ }
+ else {
+ ExtensionInstaller::error( "unknown extension {$this->extensions}!" );
+ return false;
+ }
+
+ return true;
+ }
+
+ /*static*/ function makeResource( $url ) {
+ preg_match( '!(([-+\w]+)://)?.*?(\.[-\w\d.]+)?$!', $url, $m );
+ $proto = @$m[2];
+ $ext = @$m[3];
+ if ( $ext ) $ext = strtolower( $ext );
+
+ if ( !$proto ) return new LocalInstallerResource( $url, $ext ? false : true );
+ else if ( $ext && ( $proto == 'http' || $proto == 'http' || $proto == 'ftp' ) ) return new WebInstallerResource( $url );
+ else return new SVNInstallerResource( $url );
+ }
+}
+
+class LocalInstallerResource extends InstallerResource {
+ function LocalInstallerResource( $path ) {
+ InstallerResource::InstallerResource( $path, is_dir( $path ), true );
+ }
+
+ function fetch( $target ) {
+ if ( $this->isdir ) return ExtensionInstaller::copyDir( $this->path, dirname( $target ) );
+ else return $this->extract( $this->path, dirname( $target ) );
+ }
+
+}
+
+class WebInstallerResource extends InstallerResource {
+ function WebInstallerResource( $path ) {
+ InstallerResource::InstallerResource( $path, false, false );
+ }
+
+ function fetch( $target ) {
+ $tmp = wfTempDir() . '/' . basename( $this->path );
+
+ ExtensionInstaller::note( "downloading {$this->path}..." );
+ $ok = copy( $this->path, $tmp );
+
+ if ( !$ok ) {
+ ExtensionInstaller::error( "failed to download {$this->path}" );
+ return false;
+ }
+
+ $this->extract( $tmp, dirname( $target ) );
+ unlink($tmp);
+
+ return true;
+ }
+}
+
+class SVNInstallerResource extends InstallerResource {
+ function SVNInstallerResource( $path ) {
+ InstallerResource::InstallerResource( $path, true, false );
+ }
+
+ function fetch( $target ) {
+ ExtensionInstaller::note( "SVN checkout of {$this->path}..." );
+ wfShellExec( 'svn co ' . escapeshellarg( $this->path ) . ' ' . escapeshellarg( $target ), $code );
+
+ if ( $code !== 0 ) {
+ ExtensionInstaller::error( "checkout failed for {$this->path}!" );
+ return false;
+ }
+
+ return true;
+ }
+}
+
+class ExtensionInstaller {
+ var $source;
+ var $target;
+ var $name;
+ var $dir;
+ var $tasks;
+
+ function ExtensionInstaller( $name, $source, $target ) {
+ if ( !is_object( $source ) ) $source = InstallerResource::makeResource( $source );
+
+ $this->name = $name;
+ $this->source = $source;
+ $this->target = realpath( $target );
+ $this->extdir = "$target/extensions";
+ $this->dir = "{$this->extdir}/$name";
+ $this->incpath = "extensions/$name";
+ $this->tasks = array();
+
+ #TODO: allow a subdir different from "extensions"
+ #TODO: allow a config file different from "LocalSettings.php"
+ }
+
+ function note( $msg ) {
+ print "$msg\n";
+ }
+
+ function warn( $msg ) {
+ print "WARNING: $msg\n";
+ }
+
+ function error( $msg ) {
+ print "ERROR: $msg\n";
+ }
+
+ function prompt( $msg ) {
+ if ( function_exists( 'readline' ) ) {
+ $s = readline( $msg );
+ }
+ else {
+ if ( !@$this->stdin ) $this->stdin = fopen( 'php://stdin', 'r' );
+ if ( !$this->stdin ) die( "Failed to open stdin for user interaction!\n" );
+
+ print $msg;
+ flush();
+
+ $s = fgets( $this->stdin );
+ }
+
+ $s = trim( $s );
+ return $s;
+ }
+
+ function confirm( $msg ) {
+ while ( true ) {
+ $s = $this->prompt( $msg . " [yes/no]: ");
+ $s = strtolower( trim($s) );
+
+ if ( $s == 'yes' || $s == 'y' ) return true;
+ else if ( $s == 'no' || $s == 'n' ) return false;
+ else print "bad response: $s\n";
+ }
+ }
+
+ function deleteContents( $dir ) {
+ $ff = glob( $dir . "/*" );
+ if ( !$ff ) return;
+
+ foreach ( $ff as $f ) {
+ if ( is_dir( $f ) && !is_link( $f ) ) $this->deleteContents( $f );
+ unlink( $f );
+ }
+ }
+
+ function copyDir( $dir, $tgt ) {
+ $d = $tgt . '/' . basename( $dir );
+
+ if ( !file_exists( $d ) ) {
+ $ok = mkdir( $d );
+ if ( !$ok ) {
+ ExtensionInstaller::error( "failed to create director $d" );
+ return false;
+ }
+ }
+
+ $ff = glob( $dir . "/*" );
+ if ( $ff === false || $ff === NULL ) return false;
+
+ foreach ( $ff as $f ) {
+ if ( is_dir( $f ) && !is_link( $f ) ) {
+ $ok = ExtensionInstaller::copyDir( $f, $d );
+ if ( !$ok ) return false;
+ }
+ else {
+ $t = $d . '/' . basename( $f );
+ $ok = copy( $f, $t );
+
+ if ( !$ok ) {
+ ExtensionInstaller::error( "failed to copy $f to $t" );
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ function setPermissions( $dir, $dirbits, $filebits ) {
+ if ( !chmod( $dir, $dirbits ) ) ExtensionInstaller::warn( "faield to set permissions for $dir" );
+
+ $ff = glob( $dir . "/*" );
+ if ( $ff === false || $ff === NULL ) return false;
+
+ foreach ( $ff as $f ) {
+ $n= basename( $f );
+ if ( $n{0} == '.' ) continue; #HACK: skip dot files
+
+ if ( is_link( $f ) ) continue; #skip link
+
+ if ( is_dir( $f ) ) {
+ ExtensionInstaller::setPermissions( $f, $dirbits, $filebits );
+ }
+ else {
+ if ( !chmod( $f, $filebits ) ) ExtensionInstaller::warn( "faield to set permissions for $f" );
+ }
+ }
+
+ return true;
+ }
+
+ function fetchExtension( ) {
+ if ( $this->source->islocal && $this->source->isdir && realpath( $this->source->path ) === $this->dir ) {
+ $this->note( "files are already in the extension dir" );
+ return true;
+ }
+
+ if ( file_exists( $this->dir ) && glob( $this->dir . "/*" ) ) {
+ if ( $this->confirm( "{$this->dir} exists and is not empty.\nDelete all files in that directory?" ) ) {
+ $this->deleteContents( $this->dir );
+ }
+ else {
+ return false;
+ }
+ }
+
+ $ok = $this->source->fetch( $this->dir );
+ if ( !$ok ) return false;
+
+ if ( !file_exists( $this->dir ) && glob( $this->dir . "/*" ) ) {
+ $this->error( "{$this->dir} does not exist or is empty. Something went wrong, sorry." );
+ return false;
+ }
+
+ if ( file_exists( $this->dir . '/README' ) ) $this->tasks[] = "read the README file in {$this->dir}";
+ if ( file_exists( $this->dir . '/INSTALL' ) ) $this->tasks[] = "read the INSTALL file in {$this->dir}";
+ if ( file_exists( $this->dir . '/RELEASE-NOTES' ) ) $this->tasks[] = "read the RELEASE-NOTES file in {$this->dir}";
+
+ #TODO: configure this smartly...?
+ $this->setPermissions( $this->dir, 0755, 0644 );
+
+ $this->note( "fetched extension to {$this->dir}" );
+ return true;
+ }
+
+ function patchLocalSettings( $mode ) {
+ #NOTE: if we get a better way to hook up extensions, that should be used instead.
+
+ $f = $this->dir . '/install.settings';
+ $t = $this->target . '/LocalSettings.php';
+
+ #TODO: assert version ?!
+ #TODO: allow custom installer scripts + sql patches
+
+ if ( !file_exists( $f ) ) {
+ $this->warn( "No install.settings file provided!" );
+ $this->tasks[] = "Please read the instructions and edit LocalSettings.php manually to activate the extension.";
+ return '?';
+ }
+ else {
+ $this->note( "applying settings patch..." );
+ }
+
+ $settings = file_get_contents( $f );
+
+ if ( !$settings ) {
+ $this->error( "failed to read settings from $f!" );
+ return false;
+ }
+
+ $settings = str_replace( '{{path}}', $this->incpath, $settings );
+
+ if ( $mode == EXTINST_NOPATCH ) {
+ $this->tasks[] = "Please put the following into your LocalSettings.php:" . "\n$settings\n";
+ $this->note( "Skipping patch phase, automatic patching is off." );
+ return true;
+ }
+
+ if ( $mode == EXTINST_HOTPATCH ) {
+ #NOTE: keep php extension for backup file!
+ $bak = $this->target . '/LocalSettings.install-' . $this->name . '-' . wfTimestamp(TS_MW) . '.bak.php';
+
+ $ok = copy( $t, $bak );
+
+ if ( !$ok ) {
+ $this->warn( "failed to create backup of LocalSettings.php!" );
+ return false;
+ }
+ else {
+ $this->note( "created backup of LocalSettings.php at $bak" );
+ }
+ }
+
+ $localsettings = file_get_contents( $t );
+
+ if ( !$settings ) {
+ $this->error( "failed to read $t for patching!" );
+ return false;
+ }
+
+ $marker = "<@< extension {$this->name} >@>";
+ $blockpattern = "/\n\s*#\s*BEGIN\s*$marker.*END\s*$marker\s*/smi";
+
+ if ( preg_match( $blockpattern, $localsettings ) ) {
+ $localsettings = preg_replace( $blockpattern, "\n", $localsettings );
+ $this->warn( "removed old configuration block for extension {$this->name}!" );
+ }
+
+ $newblock= "\n# BEGIN $marker\n$settings\n# END $marker\n";
+
+ $localsettings = preg_replace( "/\?>\s*$/si", "$newblock?>", $localsettings );
+
+ if ( $mode != EXTINST_HOTPATCH ) {
+ $t = $this->target . '/LocalSettings.install-' . $this->name . '-' . wfTimestamp(TS_MW) . '.php';
+ }
+
+ $ok = file_put_contents( $t, $localsettings );
+
+ if ( !$ok ) {
+ $this->error( "failed to patch $t!" );
+ return false;
+ }
+ else if ( $mode == EXTINST_HOTPATCH ) {
+ $this->note( "successfully patched $t" );
+ }
+ else {
+ $this->note( "created patched settings file $t" );
+ $this->tasks[] = "Replace your current LocalSettings.php with ".basename($t);
+ }
+
+ return true;
+ }
+
+ function printNotices( ) {
+ if ( !$this->tasks ) {
+ $this->note( "Installation is complete, no pending tasks" );
+ }
+ else {
+ $this->note( "" );
+ $this->note( "PENDING TASKS:" );
+ $this->note( "" );
+
+ foreach ( $this->tasks as $t ) {
+ $this->note ( "* " . $t );
+ }
+
+ $this->note( "" );
+ }
+
+ return true;
+ }
+
+}
+
+$tgt = isset ( $options['target'] ) ? $options['target'] : $IP;
+
+$repos = @$options['repository'];
+if ( !$repos ) $repos = @$options['repos'];
+if ( !$repos ) $repos = @$wgExtensionInstallerRepository;
+
+if ( !$repos && file_exists("$tgt/.svn") && is_dir("$tgt/.svn") ) {
+ $svn = file_get_contents( "$tgt/.svn/entries" );
+
+ if ( preg_match( '!url="(.*?)"!', $svn, $m ) ) {
+ $repos = dirname( $m[1] ) . '/extensions';
+ }
+}
+
+if ( !$repos ) $repos = 'http://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions';
+
+if( !isset( $args[0] ) && !@$options['list'] ) {
+ die( "USAGE: installExtension.php [options] <name> [source]\n" .
+ "OPTIONS: \n" .
+ " --list list available extensions. <name> is ignored / may be omitted.\n" .
+ " --repository <n> repository to fetch extensions from. May be a local directoy,\n" .
+ " an SVN repository or a HTTP directory\n" .
+ " --target <dir> mediawiki installation directory to use\n" .
+ " --nopatch don't create a patched LocalSettings.php\n" .
+ " --hotpatch patched LocalSettings.php directly (creates a backup)\n" .
+ "SOURCE: specifies the package source directly. If given, the repository is ignored.\n" .
+ " The source my be a local file (tgz or zip) or directory, the URL of a\n" .
+ " remote file (tgz or zip), or a SVN path.\n"
+ );
+}
+
+$repository = InstallerRepository::makeRepository( $repos );
+
+if ( isset( $options['list'] ) ) {
+ $repository->printListing();
+ exit(0);
+}
+
+$name = $args[0];
+
+$src = isset( $args[1] ) ? $args[1] : $repository->getResource( $name );
+
+#TODO: detect $source mismatching $name !!
+
+$mode = EXTINST_WRITEPATCH;
+if ( isset( $options['nopatch'] ) || @$wgExtensionInstallerNoPatch ) $mode = EXTINST_NOPATCH;
+else if ( isset( $options['hotpatch'] ) || @$wgExtensionInstallerHotPatch ) $mode = EXTINST_HOTPATCH;
+
+if ( !file_exists( "$tgt/LocalSettings.php" ) ) {
+ die("can't find $tgt/LocalSettings.php\n");
+}
+
+if ( $mode == EXTINST_HOTPATCH && !is_writable( "$tgt/LocalSettings.php" ) ) {
+ die("can't write to $tgt/LocalSettings.php\n");
+}
+
+if ( !file_exists( "$tgt/extensions" ) ) {
+ die("can't find $tgt/extensions\n");
+}
+
+if ( !is_writable( "$tgt/extensions" ) ) {
+ die("can't write to $tgt/extensions\n");
+}
+
+$installer = new ExtensionInstaller( $name, $src, $tgt );
+
+$installer->note( "Installing extension {$installer->name} from {$installer->source->path} to {$installer->dir}" );
+
+print "\n";
+print "\tTHIS TOOL IS EXPERIMENTAL!\n";
+print "\tEXPECT THE UNEXPECTED!\n";
+print "\n";
+
+if ( !$installer->confirm("continue") ) die("aborted\n");
+
+$ok = $installer->fetchExtension();
+
+if ( $ok ) $ok = $installer->patchLocalSettings( $mode );
+
+if ( $ok ) $ok = $installer->printNotices();
+
+if ( $ok ) $installer->note( "$name extension installed." );
+?>
diff --git a/maintenance/interwiki.sql b/maintenance/interwiki.sql
new file mode 100644
index 000000000000..b0df555768c7
--- /dev/null
+++ b/maintenance/interwiki.sql
@@ -0,0 +1,180 @@
+-- Based more or less on the public interwiki map from MeatballWiki
+-- Default interwiki prefixes...
+
+REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES
+('abbenormal','http://www.ourpla.net/cgi-bin/pikie.cgi?$1',0),
+('acadwiki','http://xarch.tu-graz.ac.at/autocad/wiki/$1',0),
+('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1',0),
+('advogato','http://www.advogato.org/$1',0),
+('aiwiki','http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?$1',0),
+('alife','http://news.alife.org/wiki/index.php?$1',0),
+('annotation','http://bayle.stanford.edu/crit/nph-med.cgi/$1',0),
+('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1',0),
+('arxiv','http://www.arxiv.org/abs/$1',0),
+('aspienetwiki','http://aspie.mela.de/Wiki/index.php?title=$1',0),
+('bemi','http://bemi.free.fr/vikio/index.php?$1',0),
+('benefitswiki','http://www.benefitslink.com/cgi-bin/wiki.cgi?$1',0),
+('brasilwiki','http://rio.ifi.unizh.ch/brasilienwiki/index.php/$1',0),
+('bridgeswiki','http://c2.com/w2/bridges/$1',0),
+('c2find','http://c2.com/cgi/wiki?FindPage&value=$1',0),
+('cache','http://www.google.com/search?q=cache:$1',0),
+('ciscavate','http://ciscavate.org/index.php/$1',0),
+('cliki','http://ww.telent.net/cliki/$1',0),
+('cmwiki','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0),
+('codersbase','http://www.codersbase.com/$1',0),
+('commons','http://commons.wikimedia.org/wiki/$1',0),
+('consciousness','http://teadvus.inspiral.org/',0),
+('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1',0),
+('creationmatters','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0),
+('dejanews','http://www.deja.com/=dnc/getdoc.xp?AN=$1',0),
+('demokraatia','http://wiki.demokraatia.ee/',0),
+('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0),
+('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1',0),
+('diveintoosx','http://diveintoosx.org/$1',0),
+('docbook','http://docbook.org/wiki/moin.cgi/$1',0),
+('dolphinwiki','http://www.object-arts.com/wiki/html/Dolphin/$1',0),
+('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1',0),
+('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0),
+('eĉei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0),
+('echei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0),
+('ecxei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0),
+('efnetceewiki','http://purl.net/wiki/c/$1',0),
+('efnetcppwiki','http://purl.net/wiki/cpp/$1',0),
+('efnetpythonwiki','http://purl.net/wiki/python/$1',0),
+('efnetxmlwiki','http://purl.net/wiki/xml/$1',0),
+('eljwiki','http://elj.sourceforge.net/phpwiki/index.php/$1',0),
+('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0),
+('elibre','http://enciclopedia.us.es/index.php/$1',0),
+('eokulturcentro','http://esperanto.toulouse.free.fr/wakka.php?wiki=$1',0),
+('evowiki','http://www.evowiki.org/index.php/$1',0),
+('finalempire','http://final-empire.sourceforge.net/cgi-bin/wiki.pl?$1',0),
+('firstwiki','http://firstwiki.org/index.php/$1',0),
+('foldoc','http://www.foldoc.org/foldoc/foldoc.cgi?$1',0),
+('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0),
+('fr.be','http://fr.wikinations.be/$1',0),
+('fr.ca','http://fr.ca.wikinations.org/$1',0),
+('fr.fr','http://fr.fr.wikinations.org/$1',0),
+('fr.org','http://fr.wikinations.org/$1',0),
+('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0),
+('gamewiki','http://gamewiki.org/wiki/index.php/$1',0),
+('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1',0),
+('gentoo-wiki','http://gentoo-wiki.com/$1',0),
+('globalvoices','http://cyber.law.harvard.edu/dyn/globalvoices/wiki/$1',0),
+('gmailwiki','http://www.gmailwiki.com/index.php/$1',0),
+('google','http://www.google.com/search?q=$1',0),
+('googlegroups','http://groups.google.com/groups?q=$1',0),
+('gotamac','http://www.got-a-mac.org/$1',0),
+('greencheese','http://www.greencheese.org/$1',0),
+('hammondwiki','http://www.dairiki.org/HammondWiki/index.php3?$1',0),
+('haribeau','http://wiki.haribeau.de/cgi-bin/wiki.pl?$1',0),
+('hewikisource','http://he.wikisource.org/wiki/$1',1),
+('herzkinderwiki','http://www.herzkinderinfo.de/Mediawiki/index.php/$1',0),
+('hrwiki','http://www.hrwiki.org/index.php/$1',0),
+('iawiki','http://www.IAwiki.net/$1',0),
+('imdb','http://us.imdb.com/Title?$1',0),
+('infosecpedia','http://www.infosecpedia.org/pedia/index.php/$1',0),
+('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0),
+('jefo','http://www.esperanto-jeunes.org/vikio/index.php?$1',0),
+('jiniwiki','http://www.cdegroot.com/cgi-bin/jini?$1',0),
+('jspwiki','http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=$1',0),
+('kerimwiki','http://wiki.oxus.net/$1',0),
+('kmwiki','http://www.voght.com/cgi-bin/pywiki?$1',0),
+('knowhow','http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?$1',0),
+('lanifexwiki','http://opt.lanifex.com/cgi-bin/wiki.pl?$1',0),
+('lasvegaswiki','http://wiki.gmnow.com/index.php/$1',0),
+('linuxwiki','http://www.linuxwiki.de/$1',0),
+('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1',0),
+('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0),
+('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0),
+('lutherwiki','http://www.lutheranarchives.com/mw/index.php/$1',0),
+('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0),
+('mbtest','http://www.usemod.com/cgi-bin/mbtest.pl?$1',0),
+('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0),
+('mediazilla','http://bugzilla.wikipedia.org/$1',1),
+('memoryalpha','http://www.memory-alpha.org/en/index.php/$1',0),
+('metaweb','http://www.metaweb.com/wiki/wiki.phtml?title=$1',0),
+('metawiki','http://sunir.org/apps/meta.pl?$1',0),
+('metawikipedia','http://meta.wikimedia.org/wiki/$1',0),
+('moinmoin','http://purl.net/wiki/moin/$1',0),
+('mozillawiki','http://wiki.mozilla.org/index.php/$1',0),
+('muweb','http://www.dunstable.com/scripts/MuWebWeb?$1',0),
+('netvillage','http://www.netbros.com/?$1',0),
+('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1',0),
+('openfacts','http://openfacts.berlios.de/index.phtml?title=$1',0),
+('openwiki','http://openwiki.com/?$1',0),
+('opera7wiki','http://nontroppo.org/wiki/$1',0),
+('orgpatterns','http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?$1',0),
+('osi reference model','http://wiki.tigma.ee/',0),
+('pangalacticorg','http://www.pangalactic.org/Wiki/$1',0),
+('personaltelco','http://www.personaltelco.net/index.cgi/$1',0),
+('patwiki','http://gauss.ffii.org/$1',0),
+('phpwiki','http://phpwiki.sourceforge.net/phpwiki/index.php?$1',0),
+('pikie','http://pikie.darktech.org/cgi/pikie?$1',0),
+('pmeg','http://www.bertilow.com/pmeg/$1.php',0),
+('ppr','http://c2.com/cgi/wiki?$1',0),
+('purlnet','http://purl.oclc.org/NET/$1',0),
+('pythoninfo','http://www.python.org/cgi-bin/moinmoin/$1',0),
+('pythonwiki','http://www.pythonwiki.de/$1',0),
+('pywiki','http://www.voght.com/cgi-bin/pywiki?$1',0),
+('raec','http://www.raec.clacso.edu.ar:8080/raec/Members/raecpedia/$1',0),
+('revo','http://purl.org/NET/voko/revo/art/$1.html',0),
+('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0),
+('s23wiki','http://is-root.de/wiki/index.php/$1',0),
+('scoutpedia','http://www.scoutpedia.info/index.php/$1',0),
+('seapig','http://www.seapig.org/$1',0),
+('seattlewiki','http://seattlewiki.org/wiki/$1',0),
+('seattlewireless','http://seattlewireless.net/?$1',0),
+('seeds','http://www.IslandSeeds.org/wiki/$1',0),
+('senseislibrary','http://senseis.xmp.net/?$1',0),
+('shakti','http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/$1',0),
+('slashdot','http://slashdot.org/article.pl?sid=$1',0),
+('smikipedia','http://www.smikipedia.org/$1',0),
+('sockwiki','http://wiki.socklabs.com/$1',0),
+('sourceforge','http://sourceforge.net/$1',0),
+('squeak','http://minnow.cc.gatech.edu/squeak/$1',0),
+('strikiwiki','http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?$1',0),
+('susning','http://www.susning.nu/$1',0),
+('svgwiki','http://www.protocol7.com/svg-wiki/default.asp?$1',0),
+('tavi','http://tavi.sourceforge.net/$1',0),
+('tejo','http://www.tejo.org/vikio/$1',0),
+('terrorwiki','http://www.liberalsagainstterrorism.com/wiki/index.php/$1',0),
+('tmbw','http://www.tmbw.net/wiki/index.php/$1',0),
+('tmnet','http://www.technomanifestos.net/?$1',0),
+('tmwiki','http://www.EasyTopicMaps.com/?page=$1',0),
+('turismo','http://www.tejo.org/turismo/$1',0),
+('theopedia','http://www.theopedia.com/$1',0),
+('twiki','http://twiki.org/cgi-bin/view/$1',0),
+('twistedwiki','http://purl.net/wiki/twisted/$1',0),
+('uea','http://www.tejo.org/uea/$1',0),
+('unreal','http://wiki.beyondunreal.com/wiki/$1',0),
+('ursine','http://wiki.ursine.ca/$1',0),
+('usej','http://www.tejo.org/usej/$1',0),
+('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0),
+('visualworks','http://wiki.cs.uiuc.edu/VisualWorks/$1',0),
+('warpedview','http://www.warpedview.com/index.php/$1',0),
+('webdevwikinl','http://www.promo-it.nl/WebDevWiki/index.php?page=$1',0),
+('webisodes','http://www.webisodes.org/$1',0),
+('webseitzwiki','http://webseitz.fluxent.com/wiki/$1',0),
+('why','http://clublet.com/c/c/why?$1',0),
+('wiki','http://c2.com/cgi/wiki?$1',0),
+('wikia','http://www.wikia.com/wiki/$1',0),
+('wikibooks','http://en.wikibooks.org/wiki/$1',1),
+('wikicities','http://www.wikicities.com/index.php/$1',0),
+('wikif1','http://www.wikif1.org/$1',0),
+('wikihow','http://www.wikihow.com/$1',0),
+('wikinfo','http://www.wikinfo.org/wiki.php?title=$1',0),
+('wikimedia','http://wikimediafoundation.org/wiki/$1',0),
+('wikiquote','http://en.wikiquote.org/wiki/$1',1),
+('wikinews','http://en.wikinews.org/wiki/$1',0),
+('wikisource','http://sources.wikipedia.org/wiki/$1',1),
+('wikispecies','http://species.wikipedia.org/wiki/$1',1),
+('wikitravel','http://wikitravel.org/en/$1',0),
+('wikiworld','http://WikiWorld.com/wiki/index.php/$1',0),
+('wiktionary','http://en.wiktionary.org/wiki/$1',1),
+('wlug','http://www.wlug.org.nz/$1',0),
+('wlwiki','http://winslowslair.supremepixels.net/wiki/index.php/$1',0),
+('ypsieyeball','http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?$1',0),
+('zwiki','http://www.zwiki.org/$1',0),
+('zzz wiki','http://wiki.zzz.ee/',0),
+('wikt','http://en.wiktionary.org/wiki/$1',1);
+
diff --git a/maintenance/language/alltrans.php b/maintenance/language/alltrans.php
new file mode 100644
index 000000000000..f8db9c0dfbbf
--- /dev/null
+++ b/maintenance/language/alltrans.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * Get all the translations messages, as defined in the English language file.
+ */
+
+require_once( dirname(__FILE__).'/../commandLine.inc' );
+
+$wgEnglishMessages = array_keys( Language::getMessagesFor( 'en' ) );
+foreach( $wgEnglishMessages as $key ) {
+ echo "$key\n";
+}
+
+?>
diff --git a/maintenance/language/checkLanguage.php b/maintenance/language/checkLanguage.php
new file mode 100644
index 000000000000..11c8ec92c297
--- /dev/null
+++ b/maintenance/language/checkLanguage.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Check a language file.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+require_once( dirname(__FILE__).'/../commandLine.inc' );
+require_once( 'languages.inc' );
+
+/**
+ * Check a language.
+ *
+ * @param $code The language code.
+ */
+function checkLanguage( $code ) {
+ global $wgLanguages, $wgGeneralMessages, $wgRequiredMessagesNumber, $wgDisplayLevel, $wgLinks, $wgWikiLanguage, $wgChecks;
+
+ # Get messages
+ $messages = $wgLanguages->getMessages( $code );
+ $messagesNumber = count( $messages['translated'] );
+
+ # Skip the checks if specified
+ if ( $wgDisplayLevel == 0 ) {
+ return;
+ }
+
+ # Untranslated messages
+ if ( in_array( 'untranslated', $wgChecks ) ) {
+ $untranslatedMessages = $wgLanguages->getUntranslatedMessages( $code );
+ $untranslatedMessagesNumber = count( $untranslatedMessages );
+ $wgLanguages->outputMessagesList( $untranslatedMessages, $code, "\n$untranslatedMessagesNumber messages of $wgRequiredMessagesNumber are not translated to $code, but exist in en:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+
+ # Duplicate messages
+ if ( in_array( 'duplicate', $wgChecks ) ) {
+ $duplicateMessages = $wgLanguages->getDuplicateMessages( $code );
+ $duplicateMessagesNumber = count( $duplicateMessages );
+ $wgLanguages->outputMessagesList( $duplicateMessages, $code, "\n$duplicateMessagesNumber messages of $messagesNumber are translated the same in en and $code:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+
+ # Obsolete messages
+ if ( in_array( 'obsolete', $wgChecks ) ) {
+ $obsoleteMessages = $messages['obsolete'];
+ $obsoleteMessagesNumber = count( $obsoleteMessages );
+ $wgLanguages->outputMessagesList( $obsoleteMessages, $code, "\n$obsoleteMessagesNumber messages of $messagesNumber are not exist in en (or are in the ignored list), but still exist in $code:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+
+ # Messages without variables
+ if ( in_array( 'variables', $wgChecks ) ) {
+ $messagesWithoutVariables = $wgLanguages->getMessagesWithoutVariables( $code );
+ $messagesWithoutVariablesNumber = count( $messagesWithoutVariables );
+ $wgLanguages->outputMessagesList( $messagesWithoutVariables, $code, "\n$messagesWithoutVariablesNumber messages of $messagesNumber in $code don't use some variables while en uses them:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+
+ # Empty messages
+ if ( in_array( 'empty', $wgChecks ) ) {
+ $emptyMessages = $wgLanguages->getEmptyMessages( $code );
+ $emptyMessagesNumber = count( $emptyMessages );
+ $wgLanguages->outputMessagesList( $emptyMessages, $code, "\n$emptyMessagesNumber messages of $messagesNumber in $code are empty or -:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+
+ # Messages with whitespace
+ if ( in_array( 'whitespace', $wgChecks ) ) {
+ $messagesWithWhitespace = $wgLanguages->getMessagesWithWhitespace( $code );
+ $messagesWithWhitespaceNumber = count( $messagesWithWhitespace );
+ $wgLanguages->outputMessagesList( $messagesWithWhitespace, $code, "\n$messagesWithWhitespaceNumber messages of $messagesNumber in $code have a trailing whitespace:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+
+ # Non-XHTML messages
+ if ( in_array( 'xhtml', $wgChecks ) ) {
+ $nonXHTMLMessages = $wgLanguages->getNonXHTMLMessages( $code );
+ $nonXHTMLMessagesNumber = count( $nonXHTMLMessages );
+ $wgLanguages->outputMessagesList( $nonXHTMLMessages, $code, "\n$nonXHTMLMessagesNumber messages of $messagesNumber in $code are not well-formed XHTML:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+
+ # Messages with wrong characters
+ if ( in_array( 'chars', $wgChecks ) ) {
+ $messagesWithWrongChars = $wgLanguages->getMessagesWithWrongChars( $code );
+ $messagesWithWrongCharsNumber = count( $messagesWithWrongChars );
+ $wgLanguages->outputMessagesList( $messagesWithWrongChars, $code, "\n$messagesWithWrongCharsNumber messages of $messagesNumber in $code include hidden chars which should not be used in the messages:", $wgDisplayLevel, $wgLinks, $wgWikiLanguage );
+ }
+}
+
+# Show help
+if ( isset( $options['help'] ) ) {
+ echo <<<END
+Run this script to check a specific language file, or all of them.
+Parameters:
+ * lang: Language code (default: the installation default language). You can also specify "all" to check all the languages.
+ * help: Show this help.
+ * level: Show the following level (default: 2).
+ * links: Link the message values (default off).
+ * wikilang: For the links, what is the content language of the wiki to display the output in (default en).
+ * whitelist: Make only the following checks (form: code,code).
+ * blacklist: Don't make the following checks (form: code,code).
+ * duplicate: Additionally check for messages which are translated the same to English (default off).
+ * noexif: Don't check for EXIF messages (a bit hard and boring to translate), if you know that they are currently not translated and want to focus on other problems (default off).
+Check codes (ideally, all of them should result 0; all the checks are executed by default):
+ * untranslated: Messages which are required to translate, but are not translated.
+ * obsolete: Messages which are untranslatable, but translated.
+ * variables: Messages without variables which should be used.
+ * empty: Empty messages.
+ * whitespace: Messages which have trailing whitespace.
+ * xhtml: Messages which are not well-formed XHTML.
+ * chars: Messages with hidden characters.
+Display levels (default: 2):
+ * 0: Skip the checks (useful for checking syntax).
+ * 1: Show only the stub headers and number of wrong messages, without list of messages.
+ * 2: Show only the headers and the message keys, without the message values.
+ * 3: Show both the headers and the complete messages, with both keys and values.
+
+END;
+ exit();
+}
+
+# Get the language code
+if ( isset( $options['lang'] ) ) {
+ $wgCode = $options['lang'];
+} else {
+ $wgCode = $wgContLang->getCode();
+}
+
+# Get the display level
+if ( isset( $options['level'] ) ) {
+ $wgDisplayLevel = $options['level'];
+} else {
+ $wgDisplayLevel = 2;
+}
+
+# Get the links options
+$wgLinks = isset( $options['links'] );
+$wgWikiLanguage = isset( $options['wikilang'] ) ? $options['wikilang'] : 'en';
+
+# Get the checks to do
+$wgChecks = array( 'untranslated', 'obsolete', 'variables', 'empty', 'whitespace', 'xhtml', 'chars' );
+if ( isset( $options['whitelist'] ) ) {
+ $wgChecks = explode( ',', $options['whitelist'] );
+} elseif ( isset( $options['blacklist'] ) ) {
+ $wgChecks = array_diff( $wgChecks, explode( ',', $options['blacklist'] ) );
+}
+
+# Add duplicate option if specified
+if ( isset( $options['duplicate'] ) ) {
+ $wgChecks[] = 'duplicate';
+}
+
+# Should check for EXIF?
+$wgCheckEXIF = !isset( $options['noexif'] );
+
+# Get language objects
+$wgLanguages = new languages( $wgCheckEXIF );
+
+# Get the general messages
+$wgGeneralMessages = $wgLanguages->getGeneralMessages();
+$wgRequiredMessagesNumber = count( $wgGeneralMessages['required'] );
+
+# Check the language
+if ( $wgCode == 'all' ) {
+ foreach ( $wgLanguages->getLanguages() as $language ) {
+ if ( $language != 'en' && $language != 'enRTL' ) {
+ checkLanguage( $language );
+ }
+ }
+} else {
+ # Can't check English
+ if ( $wgCode == 'en' ) {
+ echo "Current selected language is English, which cannot be checked.\n";
+ } else if ( $wgCode == 'enRTL' ) {
+ echo "Current selected language is RTL English, which cannot be checked.\n";
+ } else {
+ checkLanguage( $wgCode );
+ }
+}
+
+?>
diff --git a/maintenance/language/date-formats.php b/maintenance/language/date-formats.php
new file mode 100644
index 000000000000..962c2f8ccb02
--- /dev/null
+++ b/maintenance/language/date-formats.php
@@ -0,0 +1,45 @@
+<?php
+
+$ts = '20010115123456';
+
+
+$IP = dirname( __FILE__ ) . '/../..';
+require_once( "$IP/maintenance/commandLine.inc" );
+
+foreach ( glob( "$IP/languages/messages/Messages*.php" ) as $filename ) {
+ $base = basename( $filename );
+ if ( !preg_match( '/Messages(.*)\.php$/', $base, $m ) ) {
+ continue;
+ }
+ $code = str_replace( '_', '-', strtolower( $m[1] ) );
+ print "$code ";
+ $lang = Language::factory( $code );
+ $prefs = $lang->getDatePreferences();
+ if ( !$prefs ) {
+ $prefs = array( 'default' );
+ }
+ print "date: ";
+ foreach ( $prefs as $index => $pref ) {
+ if ( $index > 0 ) {
+ print ' | ';
+ }
+ print $lang->date( $ts, false, $pref );
+ }
+ print "\n$code time: ";
+ foreach ( $prefs as $index => $pref ) {
+ if ( $index > 0 ) {
+ print ' | ';
+ }
+ print $lang->time( $ts, false, $pref );
+ }
+ print "\n$code both: ";
+ foreach ( $prefs as $index => $pref ) {
+ if ( $index > 0 ) {
+ print ' | ';
+ }
+ print $lang->timeanddate( $ts, false, $pref );
+ }
+ print "\n\n";
+}
+
+?>
diff --git a/maintenance/language/diffLanguage.php b/maintenance/language/diffLanguage.php
new file mode 100644
index 000000000000..2aaa5902a8ce
--- /dev/null
+++ b/maintenance/language/diffLanguage.php
@@ -0,0 +1,159 @@
+<?php
+# MediaWiki web-based config/installation
+# Copyright (C) 2004 Ashar Voultoiz <thoane@altern.org> and others
+# http://www.mediawiki.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
+
+/**
+ * Usage: php DiffLanguage.php [lang [file]]
+ *
+ * lang: Enter the language code following "Language" of the LanguageXX.php you
+ * want to check. If using linux you might need to follow case aka Zh and not
+ * zh.
+ *
+ * file: A php language file you want to include to compare mediawiki
+ * Language{Lang}.php against (for example Special:Allmessages PHP output).
+ *
+ * The goal is to get a list of messages not yet localised in a languageXX.php
+ * file using the language.php file as reference.
+ *
+ * The script then print a list of wgAllMessagesXX keys that aren't localised, a
+ * percentage of messages correctly localised and the number of messages to be
+ * translated.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** This script run from the commandline */
+require_once( dirname(__FILE__).'/../parserTests.inc' );
+require_once( dirname(__FILE__).'/../commandLine.inc' );
+
+if( isset($options['help']) ) { usage(); wfDie(); }
+
+$wgLanguageCode = ucfirstlcrest($wgLanguageCode);
+/** Language messages we will use as reference. By default 'en' */
+$referenceMessages = $wgAllMessagesEn;
+$referenceLanguage = 'En';
+$referenceFilename = 'Language'.$referenceLanguage.'.php';
+/** Language messages we will test. */
+$testMessages = array();
+$testLanguage = '';
+/** whereas we use an external language file */
+$externalRef = false;
+
+# FUNCTIONS
+/** @todo more informations !! */
+function usage() {
+echo 'php DiffLanguage.php [lang [file]] [--color=(yes|no|light)]'."\n";
+}
+
+/** Return a given string with first letter upper case, the rest lowercase */
+function ucfirstlcrest($string) {
+ return strtoupper(substr($string,0,1)).strtolower(substr($string,1));
+}
+
+/**
+ * Return a $wgAllmessages array shipped in MediaWiki
+ * @param string $languageCode Formated language code
+ * @return array The MediaWiki default $wgAllMessages array requested
+ */
+function getMediawikiMessages($languageCode = 'En') {
+
+ $foo = "wgAllMessages$languageCode";
+ global $$foo, $wgSkinNamesEn;
+
+ // it might already be loaded in LocalSettings.php
+ if(!isset($$foo)) {
+ global $IP;
+ $langFile = $IP.'/languages/classes/Language'.$languageCode.'.php';
+ if (file_exists( $langFile ) ) {
+ print "Including $langFile\n";
+ global $wgNamespaceNamesEn;
+ include($langFile);
+ } else wfDie("ERROR: The file $langFile does not exist !\n");
+ }
+ return $$foo;
+}
+
+/**
+ * Return a $wgAllmessages array in a given file. Language of the array
+ * need to be given cause we can not detect which language it provides
+ * @param string $filename Filename of the file containing a message array
+ * @param string $languageCode Language of the external array
+ * @return array A $wgAllMessages array from an external file.
+ */
+function getExternalMessages($filename, $languageCode) {
+ print "Including external file $filename.\n";
+ include($filename);
+ $foo = "wgAllMessages$languageCode";
+ return $$foo;
+}
+
+# MAIN ENTRY
+if ( isset($args[0]) ) {
+ $lang = ucfirstlcrest($args[0],1);
+
+ // eventually against another language file we will use as reference instead
+ // of the default english language.
+ if( isset($args[1])) {
+ // we assume the external file contain an array of messages for the
+ // lang we are testing
+ $referenceMessages = getExternalMessages( $args[1], $lang );
+ $referenceLanguage = $lang;
+ $referenceFilename = $args[1];
+ $externalRef = true;
+ }
+
+ // Load datas from MediaWiki
+ $testMessages = getMediawikiMessages($lang);
+ $testLanguage = $lang;
+} else {
+ usage();
+ wfDie();
+}
+
+/** parsertest is used to do differences */
+$myParserTest = new ParserTest();
+
+# Get all references messages and check if they exist in the tested language
+$i = 0;
+
+$msg = "MW Language{$testLanguage}.php against ";
+if($externalRef) { $msg .= 'external file '; }
+else { $msg .= 'internal file '; }
+$msg .= $referenceFilename.' ('.$referenceLanguage."):\n----\n";
+echo $msg;
+
+// process messages
+foreach($referenceMessages as $index => $ref)
+{
+ // message is not localized
+ if(!(isset($testMessages[$index]))) {
+ $i++;
+ print "'$index' => \"$ref\",\n";
+ // Messages in the same language differs
+ } elseif( ($lang == $referenceLanguage) AND ($testMessages[$index] != $ref)) {
+ print "\n$index differs:\n";
+ print $myParserTest->quickDiff($testMessages[$index],$ref,'tested','reference');
+ }
+}
+
+echo "\n----\n".$msg;
+echo "$referenceLanguage language is complete at ".number_format((100 - $i/count($wgAllMessagesEn) * 100),2)."%\n";
+echo "$i unlocalised messages of the ".count($wgAllMessagesEn)." messages available.\n";
+?>
diff --git a/maintenance/language/dumpMessages.php b/maintenance/language/dumpMessages.php
new file mode 100644
index 000000000000..bd7e2aeda626
--- /dev/null
+++ b/maintenance/language/dumpMessages.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( dirname(__FILE__).'/../commandLine.inc' );
+$wgMessageCache->disableTransform();
+$messages = array();
+$wgEnglishMessages = array_keys( Language::getMessagesFor( 'en' ) );
+foreach ( $wgEnglishMessages as $key )
+{
+ $messages[$key] = wfMsg( $key );
+}
+print "MediaWiki $wgVersion language file\n";
+print serialize( $messages );
+
+?>
diff --git a/maintenance/language/function-list.php b/maintenance/language/function-list.php
new file mode 100644
index 000000000000..84efb29d4f45
--- /dev/null
+++ b/maintenance/language/function-list.php
@@ -0,0 +1,44 @@
+<?php
+
+define( 'MEDIAWIKI', 1 );
+define( 'NOT_REALLY_MEDIAWIKI', 1 );
+
+class Language {}
+foreach ( glob( 'Language*.php' ) as $file ) {
+ if ( $file != 'Language.php' ) {
+ require_once( $file );
+ }
+}
+
+$removedFunctions = array( 'date', 'time', 'timeanddate', 'formatMonth', 'formatDay',
+ 'getMonthName', 'getMonthNameGen', 'getMonthAbbreviation', 'getWeekdayName',
+ 'userAdjust', 'dateFormat', 'timeSeparator', 'timeDateSeparator', 'timeBeforeDate',
+ 'monthByLatinNumber', 'getSpecialMonthName',
+
+ 'commafy'
+);
+
+$numRemoved = 0;
+$total = 0;
+$classes = get_declared_classes();
+ksort( $classes );
+foreach ( $classes as $class ) {
+ if ( !preg_match( '/^Language/', $class ) || $class == 'Language' || $class == 'LanguageConverter' ) {
+ continue;
+ }
+
+ print "$class\n";
+ $methods = get_class_methods( $class );
+ print_r( $methods );
+
+ if ( !count( array_diff( $methods, $removedFunctions ) ) ) {
+ print "removed\n";
+ $numRemoved++;
+ }
+ $total++;
+ print "\n";
+}
+
+print "$numRemoved will be removed out of $total\n";
+
+?>
diff --git a/maintenance/language/lang2po.php b/maintenance/language/lang2po.php
new file mode 100644
index 000000000000..520d8d6e5734
--- /dev/null
+++ b/maintenance/language/lang2po.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Convert Language files to .po files !
+ *
+ * Todo:
+ * - generate .po header
+ * - fix escaping of \
+ */
+
+/** This is a command line script */
+require_once(dirname(__FILE__).'/../commandLine.inc');
+require_once(dirname(__FILE__).'/languages.inc');
+
+define('ALL_LANGUAGES', true);
+define('XGETTEXT_BIN', 'xgettext');
+define('MSGMERGE_BIN', 'msgmerge');
+
+// used to generate the .pot
+define('XGETTEXT_OPTIONS', '-n --keyword=wfMsg --keyword=wfMsgForContent --keyword=wfMsgHtml --keyword=wfMsgWikiHtml ');
+define('MSGMERGE_OPTIONS', ' -v ');
+
+define('LOCALE_OUTPUT_DIR', $IP.'/locale');
+
+
+if( isset($options['help']) ) { usage(); wfDie(); }
+// default output is WikiText
+if( !isset($options['lang']) ) { $options['lang'] = ALL_LANGUAGES; }
+
+function usage() {
+print <<<END
+Usage: php lang2po.php [--help] [--lang=<langcode>] [--stdout]
+ --help: this message.
+ --lang: a lang code you want to generate a .po for (default: all languages).
+
+END;
+}
+
+
+/**
+ * Return a dummy header for later edition.
+ * @return string A dummy header
+ */
+function poHeader() {
+return
+'# SOME DESCRIPTIVE TITLE.
+# Copyright (C) 2005 MediaWiki
+# This file is distributed under the same license as the MediaWiki package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: bugzilllaaaaa\n"
+"POT-Creation-Date: 2005-08-16 20:13+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: VARIOUS <nobody>\n"
+"Language-Team: LANGUAGE <nobody>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+';
+}
+
+/**
+ * generate and write a file in .po format.
+ *
+ * @param string $langcode Code of a language it will process.
+ * @param array &$messages Array containing the various messages.
+ * @return string Filename where stuff got saved or false.
+ */
+function generatePo($langcode, &$messages) {
+ $data = poHeader();
+
+ // Generate .po entries
+ foreach($messages as $identifier => $content) {
+ $data .= "msgid \"$identifier\"\n";
+
+ // Escape backslashes
+ $tmp = str_replace('\\', '\\\\', $content);
+ // Escape doublelquotes
+ $tmp = preg_replace( "/(?<!\\\\)\"/", '\"', $tmp);
+ // Rewrite multilines to gettext format
+ $tmp = str_replace("\n", "\"\n\"", $tmp);
+
+ $data .= 'msgstr "'. $tmp . "\"\n\n";
+ }
+
+ // Write the content to a file in locale/XX/messages.po
+ $dir = LOCALE_OUTPUT_DIR.'/'.$langcode;
+ if( !is_dir($dir) ) { mkdir( $dir, 0770 ); }
+ $filename = $dir.'/fromlanguagefile.po';
+
+ $file = fopen( $filename , 'wb' );
+ if( fwrite( $file, $data ) ) {
+ fclose( $file );
+ return $filename;
+ } else {
+ fclose( $file );
+ return false;
+ }
+}
+
+function generatePot() {
+ global $IP;
+ $curdir = getcwd();
+ chdir($IP);
+ exec( XGETTEXT_BIN
+ .' '.XGETTEXT_OPTIONS
+ .' -o '.LOCALE_OUTPUT_DIR.'/wfMsg.pot'
+ .' includes/*php'
+ );
+ chdir($curdir);
+}
+
+function applyPot($langcode) {
+ $langdir = LOCALE_OUTPUT_DIR.'/'.$langcode;
+
+ $from = $langdir.'/fromlanguagefile.po';
+ $pot = LOCALE_OUTPUT_DIR.'/wfMsg.pot';
+ $dest = $langdir.'/messages.po';
+
+ // Merge template and generate file to get final .po
+ exec(MSGMERGE_BIN.MSGMERGE_OPTIONS." $from $pot -o $dest ");
+ // delete no more needed file
+// unlink($from);
+}
+
+// Generate a template .pot based on source tree
+echo "Getting 'gettext' default messages from sources:";
+generatePot();
+echo "done.\n";
+
+
+$langTool = new languages();
+
+// Do all languages
+foreach ( $langTool->getMessages() as $langcode) {
+ echo "Loading messages for $langcode:\t";
+ require_once( Language::getClassFileName( $langcode ) );
+ $arr = 'wgAllMessages'.$langcode;
+ if(!@is_array($$arr)) {
+ echo "NONE FOUND\n";
+ } else {
+ echo "ok\n";
+ if( ! generatePo($langcode, $$arr) ) {
+ echo "ERROR: Failed to wrote file.\n";
+ } else {
+ echo "Applying template:";
+ applyPot($langcode);
+ }
+ }
+}
+?>
diff --git a/maintenance/language/langmemusage.php b/maintenance/language/langmemusage.php
new file mode 100644
index 000000000000..54b6a58c4d65
--- /dev/null
+++ b/maintenance/language/langmemusage.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Dumb program that tries to get the memory usage
+ * for each language file.
+ */
+
+/** This is a command line script */
+require_once(dirname(__FILE__).'/../commandLine.inc');
+require_once(dirname(__FILE__).'/languages.inc');
+
+$langtool = new languages();
+
+if ( ! function_exists( 'memory_get_usage' ) )
+ wfDie( "You must compile PHP with --enable-memory-limit\n" );
+
+$memlast = $memstart = memory_get_usage();
+
+print 'Base memory usage: '.$memstart."\n";
+
+foreach ( $langtool->getLanguages() as $langcode ) {
+ Language::factory( $langcode );
+ $memstep = memory_get_usage();
+ printf( "%12s: %d\n", $langcode, ($memstep- $memlast) );
+ $memlast = $memstep;
+}
+
+$memend = memory_get_usage();
+
+echo ' Total Usage: '.($memend - $memstart)."\n";
+?>
diff --git a/maintenance/language/languages.inc b/maintenance/language/languages.inc
new file mode 100644
index 000000000000..946c6cb2cf97
--- /dev/null
+++ b/maintenance/language/languages.inc
@@ -0,0 +1,396 @@
+<?php
+/**
+ * Handle messages in the language files.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+require_once( 'messageTypes.inc' );
+
+class languages {
+ private $mLanguages; # List of languages
+ private $mRawMessages; # Raw list of the messages in each language
+ private $mMessages; # Messages in each language (except for English), divided to groups
+ private $mGeneralMessages; # General messages in English, divided to groups
+ private $mIgnoredMessages; # All the messages which should be exist only in the English file
+ private $mOptionalMessages; # All the messages which may be translated or not, depending on the language
+
+ /**
+ * Load the list of languages: all the Messages*.php
+ * files in the languages directory.
+ *
+ * @param $exif Treat the EXIF messages?
+ */
+ function __construct( $exif = true ) {
+ global $wgIgnoredMessages, $wgOptionalMessages, $wgEXIFMessages;
+ $this->mIgnoredMessages = $wgIgnoredMessages;
+ if ( $exif ) {
+ $this->mOptionalMessages = array_merge( $wgOptionalMessages );
+ } else {
+ $this->mOptionalMessages = array_merge( $wgOptionalMessages, $wgEXIFMessages );
+ }
+
+ $this->mLanguages = array_keys( Language::getLanguageNames( true ) );
+ sort( $this->mLanguages );
+ }
+
+ /**
+ * Get the language list.
+ *
+ * @return The language list.
+ */
+ public function getLanguages() {
+ return $this->mLanguages;
+ }
+
+ /**
+ * Get the ignored messages list.
+ *
+ * @return The ignored messages list.
+ */
+ public function getIgnoredMessages() {
+ return $this->mIgnoredMessages;
+ }
+
+ /**
+ * Get the optional messages list.
+ *
+ * @return The optional messages list.
+ */
+ public function getOptionalMessages() {
+ return $this->mOptionalMessages;
+ }
+
+ /**
+ * Load the raw messages for a specific langauge from the messages file.
+ *
+ * @param $code The langauge code.
+ */
+ private function loadRawMessages( $code ) {
+ if ( isset( $this->mRawMessages[$code] ) ) {
+ return;
+ }
+ $filename = Language::getMessagesFileName( $code );
+ if ( file_exists( $filename ) ) {
+ require( $filename );
+ if ( isset( $messages ) ) {
+ $this->mRawMessages[$code] = $messages;
+ } else {
+ $this->mRawMessages[$code] = array();
+ }
+ } else {
+ $this->mRawMessages[$code] = array();
+ }
+ }
+
+ /**
+ * Load the messages for a specific language (which is not English) and divide them to groups:
+ * all - all the messages.
+ * required - messages which should be translated in order to get a complete translation.
+ * optional - messages which can be translated, the fallback translation is used if not translated.
+ * obsolete - messages which should not be translated, either because they are not exist, or they are ignored messages.
+ * translated - messages which are either required or optional, but translated from English and needed.
+ *
+ * @param $code The language code.
+ */
+ private function loadMessages( $code ) {
+ if ( isset( $this->mMessages[$code] ) ) {
+ return;
+ }
+ $this->loadRawMessages( $code );
+ $this->loadGeneralMessages();
+ $this->mMessages[$code]['all'] = $this->mRawMessages[$code];
+ $this->mMessages[$code]['required'] = array();
+ $this->mMessages[$code]['optional'] = array();
+ $this->mMessages[$code]['obsolete'] = array();
+ $this->mMessages[$code]['translated'] = array();
+ foreach ( $this->mMessages[$code]['all'] as $key => $value ) {
+ if ( isset( $this->mGeneralMessages['required'][$key] ) ) {
+ $this->mMessages[$code]['required'][$key] = $value;
+ $this->mMessages[$code]['translated'][$key] = $value;
+ } else if ( isset( $this->mGeneralMessages['optional'][$key] ) ) {
+ $this->mMessages[$code]['optional'][$key] = $value;
+ $this->mMessages[$code]['translated'][$key] = $value;
+ } else {
+ $this->mMessages[$code]['obsolete'][$key] = $value;
+ }
+ }
+ }
+
+ /**
+ * Load the messages for English and divide them to groups:
+ * all - all the messages.
+ * required - messages which should be translated to other languages in order to get a complete translation.
+ * optional - messages which can be translated to other languages, but it's not required for a complete translation.
+ * ignored - messages which should not be translated to other languages.
+ * translatable - messages which are either required or optional, but can be translated from English.
+ */
+ private function loadGeneralMessages() {
+ if ( isset( $this->mGeneralMessages ) ) {
+ return;
+ }
+ $this->loadRawMessages( 'en' );
+ $this->mGeneralMessages['all'] = $this->mRawMessages['en'];
+ $this->mGeneralMessages['required'] = array();
+ $this->mGeneralMessages['optional'] = array();
+ $this->mGeneralMessages['ignored'] = array();
+ $this->mGeneralMessages['translatable'] = array();
+ foreach ( $this->mGeneralMessages['all'] as $key => $value ) {
+ if ( in_array( $key, $this->mIgnoredMessages ) ) {
+ $this->mGeneralMessages['ignored'][$key] = $value;
+ } else if ( in_array( $key, $this->mOptionalMessages ) ) {
+ $this->mGeneralMessages['optional'][$key] = $value;
+ $this->mGeneralMessages['translatable'][$key] = $value;
+ } else {
+ $this->mGeneralMessages['required'][$key] = $value;
+ $this->mGeneralMessages['translatable'][$key] = $value;
+ }
+ }
+ }
+
+ /**
+ * Get all the messages for a specific langauge (not English), without the
+ * fallback language messages, divided to groups:
+ * all - all the messages.
+ * required - messages which should be translated in order to get a complete translation.
+ * optional - messages which can be translated, the fallback translation is used if not translated.
+ * obsolete - messages which should not be translated, either because they are not exist, or they are ignored messages.
+ * translated - messages which are either required or optional, but translated from English and needed.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The messages in this language.
+ */
+ public function getMessages( $code ) {
+ $this->loadMessages( $code );
+ return $this->mMessages[$code];
+ }
+
+ /**
+ * Get all the general English messages, divided to groups:
+ * all - all the messages.
+ * required - messages which should be translated to other languages in order to get a complete translation.
+ * optional - messages which can be translated to other languages, but it's not required for a complete translation.
+ * ignored - messages which should not be translated to other languages.
+ * translatable - messages which are either required or optional, but can be translated from English.
+ *
+ * @return The general English messages.
+ */
+ public function getGeneralMessages() {
+ $this->loadGeneralMessages();
+ return $this->mGeneralMessages;
+ }
+
+ /**
+ * Get the untranslated messages for a specific language.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The untranslated messages for this language.
+ */
+ public function getUntranslatedMessages( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $requiredGeneralMessages = array_keys( $this->mGeneralMessages['required'] );
+ $requiredMessages = array_keys( $this->mMessages[$code]['required'] );
+ $untranslatedMessages = array();
+ foreach ( array_diff( $requiredGeneralMessages, $requiredMessages ) as $key ) {
+ $untranslatedMessages[$key] = $this->mGeneralMessages['required'][$key];
+ }
+ return $untranslatedMessages;
+ }
+
+ /**
+ * Get the duplicate messages for a specific language.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The duplicate messages for this language.
+ */
+ public function getDuplicateMessages( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $duplicateMessages = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+ if ( $this->mGeneralMessages['translatable'][$key] == $value ) {
+ $duplicateMessages[$key] = $value;
+ }
+ }
+ return $duplicateMessages;
+ }
+
+ /**
+ * Get the messages which do not use some variables.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The messages which do not use some variables in this language.
+ */
+ public function getMessagesWithoutVariables( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $variables = array( '\$1', '\$2', '\$3', '\$4', '\$5', '\$6', '\$7', '\$8', '\$9' );
+ $messagesWithoutVariables = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+ $missing = false;
+ foreach ( $variables as $var ) {
+ if ( preg_match( "/$var/sU", $this->mGeneralMessages['translatable'][$key] ) &&
+ !preg_match( "/$var/sU", $value ) ) {
+ $missing = true;
+ }
+ }
+ if ( $missing ) {
+ $messagesWithoutVariables[$key] = $value;
+ }
+ }
+ return $messagesWithoutVariables;
+ }
+
+ /**
+ * Get the empty messages.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The empty messages for this language.
+ */
+ public function getEmptyMessages( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $emptyMessages = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+ if ( $value === '' || $value === '-' ) {
+ $emptyMessages[$key] = $value;
+ }
+ }
+ return $emptyMessages;
+ }
+
+ /**
+ * Get the messages with trailing whitespace.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The messages with trailing whitespace in this language.
+ */
+ public function getMessagesWithWhitespace( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $messagesWithWhitespace = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+ if ( $this->mGeneralMessages['translatable'][$key] !== '' && $value !== rtrim( $value ) ) {
+ $messagesWithWhitespace[$key] = $value;
+ }
+ }
+ return $messagesWithWhitespace;
+ }
+
+ /**
+ * Get the non-XHTML messages.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The non-XHTML messages for this language.
+ */
+ public function getNonXHTMLMessages( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $wrongPhrases = array(
+ '<hr *\\?>',
+ '<br *\\?>',
+ '<hr/>',
+ '<br/>',
+ );
+ $wrongPhrases = '~(' . implode( '|', $wrongPhrases ) . ')~sDu';
+ $nonXHTMLMessages = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+ if ( preg_match( $wrongPhrases, $value ) ) {
+ $nonXHTMLMessages[$key] = $value;
+ }
+ }
+ return $nonXHTMLMessages;
+ }
+
+ /**
+ * Get the messages which include wrong characters.
+ *
+ * @param $code The langauge code.
+ *
+ * @return The messages which include wrong characters in this language.
+ */
+ public function getMessagesWithWrongChars( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $wrongChars = array(
+ '[LRM]' => "\xE2\x80\x8E",
+ '[RLM]' => "\xE2\x80\x8F",
+ '[LRE]' => "\xE2\x80\xAA",
+ '[RLE]' => "\xE2\x80\xAB",
+ '[POP]' => "\xE2\x80\xAC",
+ '[LRO]' => "\xE2\x80\xAD",
+ '[RLO]' => "\xE2\x80\xAB",
+ '[ZWSP]'=> "\xE2\x80\x8B",
+ '[NBSP]'=> "\xC2\xA0",
+ '[WJ]' => "\xE2\x81\xA0",
+ '[BOM]' => "\xEF\xBB\xBF",
+ '[FFFD]'=> "\xEF\xBF\xBD",
+ );
+ $wrongRegExp = '/(' . implode( '|', array_values( $wrongChars ) ) . ')/sDu';
+ $wrongCharsMessages = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+ if ( preg_match( $wrongRegExp, $value ) ) {
+ foreach ( $wrongChars as $viewableChar => $hiddenChar ) {
+ $value = str_replace( $hiddenChar, $viewableChar, $value );
+ }
+ $wrongCharsMessages[$key] = $value;
+ }
+ }
+ return $wrongCharsMessages;
+ }
+
+ /**
+ * Output a messages list
+ *
+ * @param $messages The messages list
+ * @param $code The language code
+ * @param $text The text to show before the list (optional)
+ * @param $level The display level (optional)
+ * @param $links Show links (optional)
+ * @param $wikilang The langauge of the wiki to display the list in, for the links (optional)
+ */
+ public function outputMessagesList( $messages, $code, $text = '', $level = 2, $links = false, $wikilang = null ) {
+ if ( count( $messages ) == 0 ) {
+ return;
+ }
+ if ( $text ) {
+ echo "$text\n";
+ }
+ if ( $level == 1 ) {
+ echo "[messages are hidden]\n";
+ } else {
+ foreach ( $messages as $key => $value ) {
+ if ( $links ) {
+ $displayKey = ucfirst( $key );
+ if ( !isset( $wikilang ) ) {
+ global $wgContLang;
+ $wikilang = $wgContLang->getCode();
+ }
+ if ( $code == $wikilang ) {
+ $displayKey = "[[MediaWiki:$displayKey|$key]]";
+ } else {
+ $displayKey = "[[MediaWiki:$displayKey/$code|$key]]";
+ }
+ } else {
+ $displayKey = $key;
+ }
+ if ( $level == 2 ) {
+ echo "* $displayKey\n";
+ } else {
+ echo "* $displayKey: '$value'\n";
+ }
+ }
+ }
+ }
+}
+
+?>
diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc
new file mode 100644
index 000000000000..f7f1ffeb0c48
--- /dev/null
+++ b/maintenance/language/messageTypes.inc
@@ -0,0 +1,346 @@
+<?php
+/**
+ * Several types of messages.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** Ignored messages, which should be exist only in the English messages file. */
+$wgIgnoredMessages = array(
+ 'sidebar',
+ 'addsection',
+ 'anonnotice',
+ 'autoblock_whitelist',
+ 'catseparator',
+ 'googlesearch',
+ 'exif-make-value',
+ 'exif-model-value',
+ 'exif-software-value',
+ 'history_copyright',
+ 'licenses',
+ 'loginend',
+ 'loginlanguagelinks',
+ 'markaspatrolledlink',
+ 'newarticletextanon',
+ 'newtalkseperator',
+ 'noarticletextanon',
+ 'number_of_watching_users_RCview',
+ 'pagecategorieslink',
+ 'pubmedurl',
+ 'randompage-url',
+ 'rc-change-size',
+ 'recentchanges-url',
+ 'revision-nav',
+ 'rfcurl',
+ 'shareddescriptionfollows',
+ 'signupend',
+ 'sitenotice',
+ 'sitesubtitle',
+ 'sitetitle',
+ 'talkpagetext',
+ 'trackback',
+ 'trackbackexcerpt',
+ 'widthheight',
+);
+
+/** Optional messages, which may be translated only if changed in the other language. */
+$wgOptionalMessages = array(
+ 'imgmultigotopost',
+ 'linkprefix',
+ 'feed-atom',
+ 'feed-rss',
+ 'allpages-summary',
+ 'booksources-summary',
+ 'ipblocklist-summary',
+ 'listusers-summary',
+ 'longpages-summary',
+ 'preferences-summary',
+ 'specialpages-summary',
+ 'whatlinkshere-summary',
+ 'whatlinkshere-barrow',
+ 'imagelist-summary',
+ 'mimesearch-summary',
+ 'listredirects-summary',
+ 'uncategorizedpages-summary',
+ 'uncategorizedcategories-summary',
+ 'uncategorizedimages-summary',
+ 'popularpages-summary',
+ 'wantedcategories-summary',
+ 'wantedpages-summary',
+ 'mostlinked-summary',
+ 'mostlinkedcategories-summary',
+ 'mostcategories-summary',
+ 'mostimages-summary',
+ 'mostrevisions-summary',
+ 'prefixindex-summary',
+ 'shortpages-summary',
+ 'newpages-summary',
+ 'ancientpages-summary',
+ 'newimages-summary',
+ 'unwatchedpages-summary',
+ 'userrights-summary',
+ 'brokenredirects-summary',
+ 'deadendpages-summary',
+ 'disambiguations-summary',
+ 'doubleredirects-summary',
+ 'lonelypages-summary',
+ 'unusedtemplates-summary',
+ 'variantname-zh-cn',
+ 'variantname-zh-tw',
+ 'variantname-zh-hk',
+ 'variantname-zh-sg',
+ 'variantname-zh',
+ 'variantname-sr-ec',
+ 'variantname-sr-el',
+ 'variantname-sr-jc',
+ 'variantname-sr-jl',
+ 'variantname-sr',
+ 'variantname-kk-tr',
+ 'variantname-kk-kz',
+ 'variantname-kk-cn',
+ 'variantname-kk',
+);
+
+/** EXIF messages, which may be set as optional in several checks, but are generally mandatory */
+$wgEXIFMessages = array(
+ 'exif-imagewidth',
+ 'exif-imagelength',
+ 'exif-bitspersample',
+ 'exif-compression',
+ 'exif-photometricinterpretation',
+ 'exif-orientation',
+ 'exif-samplesperpixel',
+ 'exif-planarconfiguration',
+ 'exif-ycbcrsubsampling',
+ 'exif-ycbcrpositioning',
+ 'exif-xresolution',
+ 'exif-yresolution',
+ 'exif-resolutionunit',
+ 'exif-stripoffsets',
+ 'exif-rowsperstrip',
+ 'exif-stripbytecounts',
+ 'exif-jpeginterchangeformat',
+ 'exif-jpeginterchangeformatlength',
+ 'exif-transferfunction',
+ 'exif-whitepoint',
+ 'exif-primarychromaticities',
+ 'exif-ycbcrcoefficients',
+ 'exif-referenceblackwhite',
+ 'exif-datetime',
+ 'exif-imagedescription',
+ 'exif-make',
+ 'exif-model',
+ 'exif-software',
+ 'exif-artist',
+ 'exif-copyright',
+ 'exif-exifversion',
+ 'exif-flashpixversion',
+ 'exif-colorspace',
+ 'exif-componentsconfiguration',
+ 'exif-compressedbitsperpixel',
+ 'exif-pixelydimension',
+ 'exif-pixelxdimension',
+ 'exif-makernote',
+ 'exif-usercomment',
+ 'exif-relatedsoundfile',
+ 'exif-datetimeoriginal',
+ 'exif-datetimedigitized',
+ 'exif-subsectime',
+ 'exif-subsectimeoriginal',
+ 'exif-subsectimedigitized',
+ 'exif-exposuretime',
+ 'exif-exposuretime-format',
+ 'exif-fnumber',
+ 'exif-fnumber-format',
+ 'exif-exposureprogram',
+ 'exif-spectralsensitivity',
+ 'exif-isospeedratings',
+ 'exif-oecf',
+ 'exif-shutterspeedvalue',
+ 'exif-aperturevalue',
+ 'exif-brightnessvalue',
+ 'exif-exposurebiasvalue',
+ 'exif-maxaperturevalue',
+ 'exif-subjectdistance',
+ 'exif-meteringmode',
+ 'exif-lightsource',
+ 'exif-flash',
+ 'exif-focallength',
+ 'exif-focallength-format',
+ 'exif-subjectarea',
+ 'exif-flashenergy',
+ 'exif-spatialfrequencyresponse',
+ 'exif-focalplanexresolution',
+ 'exif-focalplaneyresolution',
+ 'exif-focalplaneresolutionunit',
+ 'exif-subjectlocation',
+ 'exif-exposureindex',
+ 'exif-sensingmethod',
+ 'exif-filesource',
+ 'exif-scenetype',
+ 'exif-cfapattern',
+ 'exif-customrendered',
+ 'exif-exposuremode',
+ 'exif-whitebalance',
+ 'exif-digitalzoomratio',
+ 'exif-focallengthin35mmfilm',
+ 'exif-scenecapturetype',
+ 'exif-gaincontrol',
+ 'exif-contrast',
+ 'exif-saturation',
+ 'exif-sharpness',
+ 'exif-devicesettingdescription',
+ 'exif-subjectdistancerange',
+ 'exif-imageuniqueid',
+ 'exif-gpsversionid',
+ 'exif-gpslatituderef',
+ 'exif-gpslatitude',
+ 'exif-gpslongituderef',
+ 'exif-gpslongitude',
+ 'exif-gpsaltituderef',
+ 'exif-gpsaltitude',
+ 'exif-gpstimestamp',
+ 'exif-gpssatellites',
+ 'exif-gpsstatus',
+ 'exif-gpsmeasuremode',
+ 'exif-gpsdop',
+ 'exif-gpsspeedref',
+ 'exif-gpsspeed',
+ 'exif-gpstrackref',
+ 'exif-gpstrack',
+ 'exif-gpsimgdirectionref',
+ 'exif-gpsimgdirection',
+ 'exif-gpsmapdatum',
+ 'exif-gpsdestlatituderef',
+ 'exif-gpsdestlatitude',
+ 'exif-gpsdestlongituderef',
+ 'exif-gpsdestlongitude',
+ 'exif-gpsdestbearingref',
+ 'exif-gpsdestbearing',
+ 'exif-gpsdestdistanceref',
+ 'exif-gpsdestdistance',
+ 'exif-gpsprocessingmethod',
+ 'exif-gpsareainformation',
+ 'exif-gpsdatestamp',
+ 'exif-gpsdifferential',
+ 'exif-compression-1',
+ 'exif-compression-6',
+ 'exif-unknowndate',
+ 'exif-photometricinterpretation-2',
+ 'exif-photometricinterpretation-6',
+ 'exif-orientation-1',
+ 'exif-orientation-2',
+ 'exif-orientation-3',
+ 'exif-orientation-4',
+ 'exif-orientation-5',
+ 'exif-orientation-6',
+ 'exif-orientation-7',
+ 'exif-orientation-8',
+ 'exif-planarconfiguration-1',
+ 'exif-planarconfiguration-2',
+ 'exif-xyresolution-i',
+ 'exif-xyresolution-c',
+ 'exif-colorspace-1',
+ 'exif-colorspace-ffff.h',
+ 'exif-componentsconfiguration-0',
+ 'exif-componentsconfiguration-1',
+ 'exif-componentsconfiguration-2',
+ 'exif-componentsconfiguration-3',
+ 'exif-componentsconfiguration-4',
+ 'exif-componentsconfiguration-5',
+ 'exif-componentsconfiguration-6',
+ 'exif-exposureprogram-0',
+ 'exif-exposureprogram-1',
+ 'exif-exposureprogram-2',
+ 'exif-exposureprogram-3',
+ 'exif-exposureprogram-4',
+ 'exif-exposureprogram-5',
+ 'exif-exposureprogram-6',
+ 'exif-exposureprogram-7',
+ 'exif-exposureprogram-8',
+ 'exif-subjectdistance-value',
+ 'exif-meteringmode-0',
+ 'exif-meteringmode-1',
+ 'exif-meteringmode-2',
+ 'exif-meteringmode-3',
+ 'exif-meteringmode-4',
+ 'exif-meteringmode-5',
+ 'exif-meteringmode-6',
+ 'exif-meteringmode-255',
+ 'exif-lightsource-0',
+ 'exif-lightsource-1',
+ 'exif-lightsource-2',
+ 'exif-lightsource-3',
+ 'exif-lightsource-4',
+ 'exif-lightsource-9',
+ 'exif-lightsource-10',
+ 'exif-lightsource-11',
+ 'exif-lightsource-12',
+ 'exif-lightsource-13',
+ 'exif-lightsource-14',
+ 'exif-lightsource-15',
+ 'exif-lightsource-17',
+ 'exif-lightsource-18',
+ 'exif-lightsource-19',
+ 'exif-lightsource-20',
+ 'exif-lightsource-21',
+ 'exif-lightsource-22',
+ 'exif-lightsource-23',
+ 'exif-lightsource-24',
+ 'exif-lightsource-255',
+ 'exif-focalplaneresolutionunit-2',
+ 'exif-sensingmethod-1',
+ 'exif-sensingmethod-2',
+ 'exif-sensingmethod-3',
+ 'exif-sensingmethod-4',
+ 'exif-sensingmethod-5',
+ 'exif-sensingmethod-7',
+ 'exif-sensingmethod-8',
+ 'exif-filesource-3',
+ 'exif-scenetype-1',
+ 'exif-customrendered-0',
+ 'exif-customrendered-1',
+ 'exif-exposuremode-0',
+ 'exif-exposuremode-1',
+ 'exif-exposuremode-2',
+ 'exif-whitebalance-0',
+ 'exif-whitebalance-1',
+ 'exif-scenecapturetype-0',
+ 'exif-scenecapturetype-1',
+ 'exif-scenecapturetype-2',
+ 'exif-scenecapturetype-3',
+ 'exif-gaincontrol-0',
+ 'exif-gaincontrol-1',
+ 'exif-gaincontrol-2',
+ 'exif-gaincontrol-3',
+ 'exif-gaincontrol-4',
+ 'exif-contrast-0',
+ 'exif-contrast-1',
+ 'exif-contrast-2',
+ 'exif-saturation-0',
+ 'exif-saturation-1',
+ 'exif-saturation-2',
+ 'exif-sharpness-0',
+ 'exif-sharpness-1',
+ 'exif-sharpness-2',
+ 'exif-subjectdistancerange-0',
+ 'exif-subjectdistancerange-1',
+ 'exif-subjectdistancerange-2',
+ 'exif-subjectdistancerange-3',
+ 'exif-gpslatitude-n',
+ 'exif-gpslatitude-s',
+ 'exif-gpslongitude-e',
+ 'exif-gpslongitude-w',
+ 'exif-gpsstatus-a',
+ 'exif-gpsstatus-v',
+ 'exif-gpsmeasuremode-2',
+ 'exif-gpsmeasuremode-3',
+ 'exif-gpsspeed-k',
+ 'exif-gpsspeed-m',
+ 'exif-gpsspeed-n',
+ 'exif-gpsdirection-t',
+ 'exif-gpsdirection-m',
+);
+
+?>
diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc
new file mode 100644
index 000000000000..4fbe2ed1883d
--- /dev/null
+++ b/maintenance/language/messages.inc
@@ -0,0 +1,2081 @@
+<?php
+/**
+ * Define the messages structure in the messages file, for a future automated rewriting.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** The structure of the messages, divided to blocks */
+$wgMessageStrucutre = array(
+ 'sidebar' => array(
+ 'sidebar',
+ ),
+ 'toggles' => array(
+ 'tog-underline',
+ 'tog-highlightbroken',
+ 'tog-justify',
+ 'tog-hideminor',
+ 'tog-extendwatchlist',
+ 'tog-usenewrc',
+ 'tog-numberheadings',
+ 'tog-showtoolbar',
+ 'tog-editondblclick',
+ 'tog-editsection',
+ 'tog-editsectiononrightclick',
+ 'tog-showtoc',
+ 'tog-rememberpassword',
+ 'tog-editwidth',
+ 'tog-watchcreations',
+ 'tog-watchdefault',
+ 'tog-watchmoves',
+ 'tog-watchdeletion',
+ 'tog-minordefault',
+ 'tog-previewontop',
+ 'tog-previewonfirst',
+ 'tog-nocache',
+ 'tog-enotifwatchlistpages',
+ 'tog-enotifusertalkpages',
+ 'tog-enotifminoredits',
+ 'tog-enotifrevealaddr',
+ 'tog-shownumberswatching',
+ 'tog-fancysig',
+ 'tog-externaleditor',
+ 'tog-externaldiff',
+ 'tog-showjumplinks',
+ 'tog-uselivepreview',
+ 'tog-forceeditsummary',
+ 'tog-watchlisthideown',
+ 'tog-watchlisthidebots',
+ 'tog-watchlisthideminor',
+ 'tog-nolangconversion',
+ 'tog-ccmeonemails',
+ ),
+ 'underline' => array(
+ 'underline-always',
+ 'underline-never',
+ 'underline-default',
+ ),
+ 'skinpreview' => array(
+ 'skinpreview',
+ ),
+ 'dates' => array(
+ 'sunday',
+ 'monday',
+ 'tuesday',
+ 'wednesday',
+ 'thursday',
+ 'friday',
+ 'saturday',
+ 'sun',
+ 'mon',
+ 'tue',
+ 'wed',
+ 'thu',
+ 'fri',
+ 'sat',
+ 'january',
+ 'february',
+ 'march',
+ 'april',
+ 'may_long',
+ 'june',
+ 'july',
+ 'august',
+ 'september',
+ 'october',
+ 'november',
+ 'december',
+ 'january-gen',
+ 'february-gen',
+ 'march-gen',
+ 'april-gen',
+ 'may-gen',
+ 'june-gen',
+ 'july-gen',
+ 'august-gen',
+ 'september-gen',
+ 'october-gen',
+ 'november-gen',
+ 'december-gen',
+ 'jan',
+ 'feb',
+ 'mar',
+ 'apr',
+ 'may',
+ 'jun',
+ 'jul',
+ 'aug',
+ 'sep',
+ 'oct',
+ 'nov',
+ 'dec',
+ ),
+ 'categories' => array(
+ 'categories',
+ 'pagecategories',
+ 'pagecategorieslink',
+ 'category_header',
+ 'subcategories',
+ 'category-media-header',
+ ),
+ 'mainpage' => array(
+ 'linkprefix',
+ 'mainpage',
+ 'mainpagetext',
+ 'mainpagedocfooter',
+ ),
+ 'miscellaneous1' => array(
+ 'portal',
+ 'portal-url',
+ 'about',
+ 'aboutsite',
+ 'aboutpage',
+ 'article',
+ 'help',
+ 'helppage',
+ 'bugreports',
+ 'bugreportspage',
+ 'sitesupport',
+ 'sitesupport-url',
+ 'faq',
+ 'faqpage',
+ 'edithelp',
+ 'newwindow',
+ 'edithelppage',
+ 'cancel',
+ 'qbfind',
+ 'qbbrowse',
+ 'qbedit',
+ 'qbpageoptions',
+ 'qbpageinfo',
+ 'qbmyoptions',
+ 'qbspecialpages',
+ 'moredotdotdot',
+ 'mypage',
+ 'mytalk',
+ 'anontalk',
+ 'navigation',
+ ),
+ 'metadata_help' => array(
+ 'metadata_help',
+ ),
+ 'currentevents' => array(
+ 'currentevents',
+ 'currentevents-url',
+ ),
+ 'miscellaneous2' => array(
+ 'disclaimers',
+ 'disclaimerpage',
+ 'privacy',
+ 'privacypage',
+ 'errorpagetitle',
+ 'returnto',
+ 'tagline',
+ 'help',
+ 'search',
+ 'searchbutton',
+ 'go',
+ 'searcharticle',
+ 'history',
+ 'history_short',
+ 'updatedmarker',
+ 'info_short',
+ 'printableversion',
+ 'permalink',
+ 'print',
+ 'edit',
+ 'editthispage',
+ 'delete',
+ 'deletethispage',
+ 'undelete_short',
+ 'protect',
+ 'protectthispage',
+ 'unprotect',
+ 'unprotectthispage',
+ 'newpage',
+ 'talkpage',
+ 'specialpage',
+ 'personaltools',
+ 'postcomment',
+ 'addsection',
+ 'articlepage',
+ 'talk',
+ 'views',
+ 'toolbox',
+ 'userpage',
+ 'projectpage',
+ 'imagepage',
+ 'mediawikipage',
+ 'templatepage',
+ 'viewhelppage',
+ 'categorypage',
+ 'viewtalkpage',
+ 'otherlanguages',
+ 'redirectedfrom',
+ 'redirectpagesub',
+ 'lastmodifiedat',
+ 'viewcount',
+ 'copyright',
+ 'protectedpage',
+ 'jumpto',
+ 'jumptonavigation',
+ 'jumptosearch',
+ ),
+ 'badaccess' => array(
+ 'badaccess',
+ 'badaccess-group0',
+ 'badaccess-group1',
+ 'badaccess-group2',
+ 'badaccess-groups',
+ ),
+ 'versionrequired' => array(
+ 'versionrequired',
+ 'versionrequiredtext',
+ ),
+ 'miscellaneous3' => array(
+ 'widthheight',
+ 'ok',
+ 'sitetitle',
+ 'pagetitle',
+ 'sitesubtitle',
+ 'retrievedfrom',
+ 'youhavenewmessages',
+ 'newmessageslink',
+ 'newmessagesdifflink',
+ 'editsection',
+ 'editold',
+ 'editsectionhint',
+ 'toc',
+ 'showtoc',
+ 'hidetoc',
+ 'thisisdeleted',
+ 'viewdeleted',
+ 'restorelink',
+ 'feedlinks',
+ 'feed-invalid',
+ 'feed-atom',
+ 'feed-rss',
+ 'sitenotice',
+ 'anonnotice',
+ ),
+ 'nstab' => array(
+ 'nstab-main',
+ 'nstab-user',
+ 'nstab-media',
+ 'nstab-special',
+ 'nstab-project',
+ 'nstab-image',
+ 'nstab-mediawiki',
+ 'nstab-template',
+ 'nstab-help',
+ 'nstab-category',
+ ),
+ 'main' => array(
+ 'nosuchaction',
+ 'nosuchactiontext',
+ 'nosuchspecialpage',
+ 'nospecialpagetext',
+ ),
+ 'errors' => array(
+ 'error',
+ 'databaseerror',
+ 'dberrortext',
+ 'dberrortextcl',
+ 'noconnect',
+ 'nodb',
+ 'cachederror',
+ 'laggedslavemode',
+ 'readonly',
+ 'enterlockreason',
+ 'readonlytext',
+ 'missingarticle',
+ 'readonly_lag',
+ 'internalerror',
+ 'filecopyerror',
+ 'filerenameerror',
+ 'filedeleteerror',
+ 'filenotfound',
+ 'unexpected',
+ 'formerror',
+ 'badarticleerror',
+ 'cannotdelete',
+ 'badtitle',
+ 'badtitletext',
+ 'perfdisabled',
+ 'perfdisabledsub',
+ 'perfcached',
+ 'perfcachedts',
+ 'querypage-no-updates',
+ 'wrong_wfQuery_params',
+ 'viewsource',
+ 'viewsourcefor',
+ 'protectedpagetext',
+ 'viewsourcetext',
+ 'protectedinterface',
+ 'editinginterface',
+ 'sqlhidden',
+ ),
+ 'login' => array(
+ 'logouttitle',
+ 'logouttext',
+ 'welcomecreation',
+ 'loginpagetitle',
+ 'yourname',
+ 'yourpassword',
+ 'yourpasswordagain',
+ 'remembermypassword',
+ 'yourdomainname',
+ 'externaldberror',
+ 'loginproblem',
+ 'alreadyloggedin',
+ 'login',
+ 'loginprompt',
+ 'userlogin',
+ 'logout',
+ 'userlogout',
+ 'notloggedin',
+ 'nologin',
+ 'nologinlink',
+ 'createaccount',
+ 'gotaccount',
+ 'gotaccountlink',
+ 'createaccountmail',
+ 'badretype',
+ 'userexists',
+ 'youremail',
+ 'username',
+ 'uid',
+ 'yourrealname',
+ 'yourlanguage',
+ 'yourvariant',
+ 'yournick',
+ 'badsig',
+ 'email',
+ 'prefs-help-email-enotif',
+ 'prefs-help-realname',
+ 'loginerror',
+ 'prefs-help-email',
+ 'nocookiesnew',
+ 'nocookieslogin',
+ 'noname',
+ 'loginsuccesstitle',
+ 'loginsuccess',
+ 'nosuchuser',
+ 'nosuchusershort',
+ 'nouserspecified',
+ 'wrongpassword',
+ 'wrongpasswordempty',
+ 'mailmypassword',
+ 'passwordremindertitle',
+ 'passwordremindertext',
+ 'noemail',
+ 'passwordsent',
+ 'blocked-mailpassword',
+ 'eauthentsent',
+ 'throttled-mailpassword',
+ 'loginend',
+ 'signupend',
+ 'mailerror',
+ 'acct_creation_throttle_hit',
+ 'emailauthenticated',
+ 'emailnotauthenticated',
+ 'noemailprefs',
+ 'emailconfirmlink',
+ 'invalidemailaddress',
+ 'accountcreated',
+ 'accountcreatedtext',
+ ),
+ 'resetpass' => array(
+ 'resetpass',
+ 'resetpass_announce',
+ 'resetpass_text',
+ 'resetpass_header',
+ 'resetpass_submit',
+ 'resetpass_success',
+ 'resetpass_bad_temporary',
+ 'resetpass_forbidden',
+ 'resetpass_missing',
+ ),
+ 'toolbar' => array(
+ 'bold_sample',
+ 'bold_tip',
+ 'italic_sample',
+ 'italic_tip',
+ 'link_sample',
+ 'link_tip',
+ 'extlink_sample',
+ 'extlink_tip',
+ 'headline_sample',
+ 'headline_tip',
+ 'math_sample',
+ 'math_tip',
+ 'nowiki_sample',
+ 'nowiki_tip',
+ 'image_sample',
+ 'image_tip',
+ 'media_sample',
+ 'media_tip',
+ 'sig_tip',
+ 'hr_tip',
+ ),
+ 'edit' => array(
+ 'summary',
+ 'subject',
+ 'minoredit',
+ 'watchthis',
+ 'savearticle',
+ 'preview',
+ 'showpreview',
+ 'showlivepreview',
+ 'showdiff',
+ 'anoneditwarning',
+ 'missingsummary',
+ 'missingcommenttext',
+ 'missingcommentheader',
+ 'summary-preview',
+ 'subject-preview',
+ 'blockedtitle',
+ 'blockedtext',
+ 'blockedoriginalsource',
+ 'blockededitsource',
+ 'whitelistedittitle',
+ 'whitelistedittext',
+ 'whitelistreadtitle',
+ 'whitelistreadtext',
+ 'whitelistacctitle',
+ 'whitelistacctext',
+ 'confirmedittitle',
+ 'confirmedittext',
+ 'loginreqtitle',
+ 'loginreqlink',
+ 'loginreqpagetext',
+ 'accmailtitle',
+ 'accmailtext',
+ 'newarticle',
+ 'newarticletext',
+ 'newarticletextanon',
+ 'talkpagetext',
+ 'anontalkpagetext',
+ 'noarticletext',
+ 'noarticletextanon',
+ 'clearyourcache',
+ 'usercssjsyoucanpreview',
+ 'usercsspreview',
+ 'userjspreview',
+ 'userinvalidcssjstitle',
+ 'updated',
+ 'note',
+ 'previewnote',
+ 'previewconflict',
+ 'session_fail_preview',
+ 'session_fail_preview_html',
+ 'importing',
+ 'editing',
+ 'editinguser',
+ 'editingsection',
+ 'editingcomment',
+ 'editconflict',
+ 'explainconflict',
+ 'yourtext',
+ 'storedversion',
+ 'nonunicodebrowser',
+ 'editingold',
+ 'yourdiff',
+ 'copyrightwarning',
+ 'copyrightwarning2',
+ 'longpagewarning',
+ 'longpageerror',
+ 'readonlywarning',
+ 'protectedpagewarning',
+ 'semiprotectedpagewarning',
+ 'templatesused',
+ 'templatesusedpreview',
+ 'templatesusedsection',
+ 'template-protected',
+ 'template-semiprotected',
+ 'edittools',
+ 'nocreatetitle',
+ 'nocreatetext',
+ ),
+ 'undo' => array(
+ 'undo-success',
+ 'undo-failure',
+ 'undo-summary',
+ ),
+ 'cantcreateaccount' => array(
+ 'cantcreateaccounttitle',
+ 'cantcreateaccounttext',
+ ),
+ 'history' => array(
+ 'revhistory',
+ 'viewpagelogs',
+ 'nohistory',
+ 'revnotfound',
+ 'revnotfoundtext',
+ 'loadhist',
+ 'currentrev',
+ 'revisionasof',
+ 'revision-info',
+ 'revision-nav',
+ 'previousrevision',
+ 'nextrevision',
+ 'currentrevisionlink',
+ 'cur',
+ 'next',
+ 'last',
+ 'orig',
+ 'histlegend',
+ 'history_copyright',
+ 'deletedrev',
+ 'histfirst',
+ 'histlast',
+ 'rev-deleted-comment',
+ 'rev-deleted-user',
+ 'rev-deleted-text-permission',
+ 'rev-deleted-text-view',
+ 'rev-delundel',
+ ),
+ 'history-feed' => array(
+ 'history-feed-title',
+ 'history-feed-description',
+ 'history-feed-item-nocomment',
+ 'history-feed-empty',
+ ),
+ 'revdelete' => array(
+ 'revisiondelete',
+ 'revdelete-nooldid-title',
+ 'revdelete-nooldid-text',
+ 'revdelete-selected',
+ 'revdelete-text',
+ 'revdelete-legend',
+ 'revdelete-hide-text',
+ 'revdelete-hide-comment',
+ 'revdelete-hide-user',
+ 'revdelete-hide-restricted',
+ 'revdelete-log',
+ 'revdelete-submit',
+ 'revdelete-logentry',
+ ),
+ 'diffs' => array(
+ 'difference',
+ 'loadingrev',
+ 'lineno',
+ 'editcurrent',
+ 'selectnewerversionfordiff',
+ 'selectolderversionfordiff',
+ 'compareselectedversions',
+ 'editundo',
+ 'diff-multi',
+ ),
+ 'search' => array(
+ 'searchresults',
+ 'searchresulttext',
+ 'searchsubtitle',
+ 'searchsubtitleinvalid',
+ 'badquery',
+ 'badquerytext',
+ 'matchtotals',
+ 'noexactmatch',
+ 'titlematches',
+ 'notitlematches',
+ 'textmatches',
+ 'notextmatches',
+ 'prevn',
+ 'nextn',
+ 'viewprevnext',
+ 'showingresults',
+ 'showingresultsnum',
+ 'nonefound',
+ 'powersearch',
+ 'powersearchtext',
+ 'searchdisabled',
+ 'googlesearch',
+ 'blanknamespace',
+ ),
+ 'preferences' => array(
+ 'preferences',
+ 'preferences-summary',
+ 'mypreferences',
+ 'prefsnologin',
+ 'prefsnologintext',
+ 'prefsreset',
+ 'qbsettings',
+ 'changepassword',
+ 'skin',
+ 'math',
+ 'dateformat',
+ 'datedefault',
+ 'datetime',
+ 'math_failure',
+ 'math_unknown_error',
+ 'math_unknown_function',
+ 'math_lexing_error',
+ 'math_syntax_error',
+ 'math_image_error',
+ 'math_bad_tmpdir',
+ 'math_bad_output',
+ 'math_notexvc',
+ 'prefs-personal',
+ 'prefs-rc',
+ 'prefs-watchlist',
+ 'prefs-watchlist-days',
+ 'prefs-watchlist-edits',
+ 'prefs-misc',
+ 'saveprefs',
+ 'resetprefs',
+ 'oldpassword',
+ 'newpassword',
+ 'retypenew',
+ 'textboxsize',
+ 'rows',
+ 'columns',
+ 'searchresultshead',
+ 'resultsperpage',
+ 'contextlines',
+ 'contextchars',
+ 'stubthreshold',
+ 'recentchangescount',
+ 'savedprefs',
+ 'timezonelegend',
+ 'timezonetext',
+ 'localtime',
+ 'timezoneoffset',
+ 'servertime',
+ 'guesstimezone',
+ 'allowemail',
+ 'defaultns',
+ 'default',
+ 'files',
+ ),
+ 'userrights' => array(
+ 'userrights-lookup-user',
+ 'userrights-user-editname',
+ 'editusergroup',
+ 'userrights-editusergroup',
+ 'saveusergroups',
+ 'userrights-groupsmember',
+ 'userrights-groupsavailable',
+ 'userrights-groupshelp',
+ ),
+ 'group' => array(
+ 'group',
+ 'group-bot',
+ 'group-sysop',
+ 'group-bureaucrat',
+ 'group-all',
+ ),
+ 'group-member' => array(
+ 'group-bot-member',
+ 'group-sysop-member',
+ 'group-bureaucrat-member',
+ ),
+ 'grouppage' => array(
+ 'grouppage-bot',
+ 'grouppage-sysop',
+ 'grouppage-bureaucrat',
+ ),
+ 'recentchanges' => array(
+ 'changes',
+ 'recentchanges',
+ 'recentchanges-url',
+ 'recentchangestext',
+ 'recentchanges-feed-description',
+ 'rcnote',
+ 'rcnotefrom',
+ 'rclistfrom',
+ 'rcshowhideminor',
+ 'rcshowhidebots',
+ 'rcshowhideliu',
+ 'rcshowhideanons',
+ 'rcshowhidepatr',
+ 'rcshowhidemine',
+ 'rclinks',
+ 'diff',
+ 'hist',
+ 'hide',
+ 'show',
+ 'minoreditletter',
+ 'newpageletter',
+ 'boteditletter',
+ 'sectionlink',
+ 'number_of_watching_users_RCview',
+ 'number_of_watching_users_pageview',
+ 'rc_categories',
+ 'rc_categories_any',
+ 'rc-change-size',
+ ),
+ 'upload' => array(
+ 'upload',
+ 'uploadbtn',
+ 'reupload',
+ 'reuploaddesc',
+ 'uploadnologin',
+ 'uploadnologintext',
+ 'upload_directory_read_only',
+ 'uploaderror',
+ 'uploadtext',
+ 'uploadlog',
+ 'uploadlogpage',
+ 'uploadlogpagetext',
+ 'filename',
+ 'filedesc',
+ 'fileuploadsummary',
+ 'filestatus',
+ 'filesource',
+ 'copyrightpage',
+ 'copyrightpagename',
+ 'uploadedfiles',
+ 'ignorewarning',
+ 'ignorewarnings',
+ 'minlength',
+ 'illegalfilename',
+ 'badfilename',
+ 'badfiletype',
+ 'large-file',
+ 'largefileserver',
+ 'emptyfile',
+ 'fileexists',
+ 'fileexists-forbidden',
+ 'fileexists-shared-forbidden',
+ 'successfulupload',
+ 'fileuploaded',
+ 'uploadwarning',
+ 'savefile',
+ 'uploadedimage',
+ 'uploaddisabled',
+ 'uploaddisabledtext',
+ 'uploadscripted',
+ 'uploadcorrupt',
+ 'uploadvirus',
+ 'sourcefilename',
+ 'destfilename',
+ 'watchthisupload',
+ 'filewasdeleted',
+ ),
+ 'upload-errors' => array(
+ 'upload-proto-error',
+ 'upload-proto-error-text',
+ 'upload-file-error',
+ 'upload-file-error-text',
+ 'upload-misc-error',
+ 'upload-misc-error-text',
+ ),
+ 'upload-curl-errors' => array(
+ 'upload-curl-error6',
+ 'upload-curl-error6-text',
+ 'upload-curl-error28',
+ 'upload-curl-error28-text',
+ ),
+ 'licenses' => array(
+ 'license',
+ 'nolicense',
+ 'licenses',
+ 'upload_source_url',
+ 'upload_source_file',
+ ),
+ 'imagelist' => array(
+ 'imagelist',
+ 'imagelist-summary',
+ 'imagelisttext',
+ 'imagelistforuser',
+ 'getimagelist',
+ 'ilsubmit',
+ 'showlast',
+ 'byname',
+ 'bydate',
+ 'bysize',
+ 'imgdelete',
+ 'imgdesc',
+ 'imgfile',
+ 'imglegend',
+ 'imghistory',
+ 'revertimg',
+ 'deleteimg',
+ 'deleteimgcompletely',
+ 'imghistlegend',
+ 'imagelinks',
+ 'linkstoimage',
+ 'nolinkstoimage',
+ 'sharedupload',
+ 'shareduploadwiki',
+ 'shareduploadwiki-linktext',
+ 'shareddescriptionfollows',
+ 'noimage',
+ 'noimage-linktext',
+ 'uploadnewversion-linktext',
+ 'imagelist_date',
+ 'imagelist_name',
+ 'imagelist_user',
+ 'imagelist_size',
+ 'imagelist_description',
+ 'imagelist_search_for',
+ ),
+ 'mimesearch' => array(
+ 'mimesearch',
+ 'mimesearch-summary',
+ 'mimetype',
+ 'download',
+ ),
+ 'unwatchedpages' => array(
+ 'unwatchedpages',
+ 'unwatchedpages-summary',
+ ),
+ 'listredirects' => array(
+ 'listredirects',
+ 'listredirects-summary',
+ ),
+ 'unusedtemplates' => array(
+ 'unusedtemplates',
+ 'unusedtemplates-summary',
+ 'unusedtemplatestext',
+ 'unusedtemplateswlh',
+ ),
+ 'randomredirect' => array(
+ 'randomredirect',
+ ),
+ 'statistics' => array(
+ 'statistics',
+ 'sitestats',
+ 'userstats',
+ 'sitestatstext',
+ 'userstatstext',
+ 'statistics-mostpopular',
+ ),
+ 'disambiguations' => array(
+ 'disambiguations',
+ 'disambiguations-summary',
+ 'disambiguationspage',
+ 'disambiguationstext',
+ ),
+ 'doubleredirects' => array(
+ 'doubleredirects',
+ 'doubleredirects-summary',
+ 'doubleredirectstext',
+ ),
+ 'brokenredirects' => array(
+ 'brokenredirects',
+ 'brokenredirects-summary',
+ 'brokenredirectstext',
+ ),
+ 'specialpages' => array(
+ 'nbytes',
+ 'ncategories',
+ 'nlinks',
+ 'nmembers',
+ 'nrevisions',
+ 'nviews',
+ 'lonelypages',
+ 'lonelypages-summary',
+ 'lonelypagestext',
+ 'uncategorizedpages',
+ 'uncategorizedpages-summary',
+ 'uncategorizedcategories',
+ 'uncategorizedcategories-summary',
+ 'uncategorizedimages',
+ 'uncategorizedimages-summary',
+ 'unusedcategories',
+ 'unusedimages',
+ 'popularpages',
+ 'popularpages-summary',
+ 'wantedcategories',
+ 'wantedcategories-summary',
+ 'wantedpages',
+ 'wantedpages-summary',
+ 'mostlinked',
+ 'mostlinked-summary',
+ 'mostlinkedcategories',
+ 'mostlinkedcategories-summary',
+ 'mostcategories',
+ 'mostcategories-summary',
+ 'mostimages',
+ 'mostimages-summary',
+ 'mostrevisions',
+ 'mostrevisions-summary',
+ 'allpages',
+ 'allpages-summary',
+ 'prefixindex',
+ 'prefixindex-summary',
+ 'randompage',
+ 'randompage-url',
+ 'shortpages',
+ 'shortpages-summary',
+ 'longpages',
+ 'longpages-summary',
+ 'deadendpages',
+ 'deadendpages-summary',
+ 'deadendpagestext',
+ 'listusers',
+ 'listusers-summary',
+ 'specialpages',
+ 'specialpages-summary',
+ 'spheading',
+ 'restrictedpheading',
+ 'recentchangeslinked',
+ 'rclsub',
+ 'newpages',
+ 'newpages-summary',
+ 'newpages-username',
+ 'ancientpages',
+ 'ancientpages-summary',
+ 'intl',
+ 'move',
+ 'movethispage',
+ 'unusedimagestext',
+ 'unusedcategoriestext',
+ ),
+ 'booksources' => array(
+ 'booksources',
+ 'booksources-summary',
+ 'booksources-search-legend',
+ 'booksources-isbn',
+ 'booksources-go',
+ 'booksources-text',
+ ),
+ 'specialpages2' => array(
+ 'categoriespagetext',
+ 'data',
+ 'userrights',
+ 'userrights-summary',
+ 'groups',
+ 'isbn',
+ 'rfcurl',
+ 'pubmedurl',
+ 'alphaindexline',
+ 'version',
+ 'log',
+ 'alllogstext',
+ 'logempty',
+ ),
+ 'allpages' => array(
+ 'nextpage',
+ 'prevpage',
+ 'allpagesfrom',
+ 'allarticles',
+ 'allinnamespace',
+ 'allnotinnamespace',
+ 'allpagesprev',
+ 'allpagesnext',
+ 'allpagessubmit',
+ 'allpagesprefix',
+ 'allpagesbadtitle',
+ ),
+ 'listusers' => array(
+ 'listusersfrom',
+ ),
+ 'emailuser' => array(
+ 'mailnologin',
+ 'mailnologintext',
+ 'emailuser',
+ 'emailpage',
+ 'emailpagetext',
+ 'usermailererror',
+ 'defemailsubject',
+ 'noemailtitle',
+ 'noemailtext',
+ 'emailfrom',
+ 'emailto',
+ 'emailsubject',
+ 'emailmessage',
+ 'emailsend',
+ 'emailccme',
+ 'emailccsubject',
+ 'emailsent',
+ 'emailsenttext',
+ ),
+ 'watchlist' => array(
+ 'watchlist',
+ 'watchlistfor',
+ 'nowatchlist',
+ 'watchlistanontext',
+ 'watchlistcount',
+ 'clearwatchlist',
+ 'watchlistcleartext',
+ 'watchlistclearbutton',
+ 'watchlistcleardone',
+ 'watchnologin',
+ 'watchnologintext',
+ 'addedwatch',
+ 'addedwatchtext',
+ 'removedwatch',
+ 'removedwatchtext',
+ 'watch',
+ 'watchthispage',
+ 'unwatch',
+ 'unwatchthispage',
+ 'notanarticle',
+ 'watchnochange',
+ 'watchdetails',
+ 'wlheader-enotif',
+ 'wlheader-showupdated',
+ 'watchmethod-recent',
+ 'watchmethod-list',
+ 'removechecked',
+ 'watchlistcontains',
+ 'watcheditlist',
+ 'removingchecked',
+ 'couldntremove',
+ 'iteminvalidname',
+ 'wlnote',
+ 'wlshowlast',
+ 'wlsaved',
+ 'watchlist-show-bots',
+ 'watchlist-hide-bots',
+ 'watchlist-show-own',
+ 'watchlist-hide-own',
+ 'watchlist-show-minor',
+ 'watchlist-hide-minor',
+ 'wldone',
+ ),
+ 'watching' => array(
+ 'watching',
+ 'unwatching',
+ ),
+ 'enotif' => array(
+ 'enotif_mailer',
+ 'enotif_reset',
+ 'enotif_newpagetext',
+ 'changed',
+ 'created',
+ 'enotif_subject',
+ 'enotif_lastvisited',
+ 'enotif_body',
+ ),
+ 'deleteprotectrev' => array(
+ 'deletepage',
+ 'confirm',
+ 'excontent',
+ 'excontentauthor',
+ 'exbeforeblank',
+ 'exblank',
+ 'confirmdelete',
+ 'deletesub',
+ 'historywarning',
+ 'confirmdeletetext',
+ 'actioncomplete',
+ 'deletedtext',
+ 'deletedarticle',
+ 'dellogpage',
+ 'dellogpagetext',
+ 'deletionlog',
+ 'reverted',
+ 'deletecomment',
+ 'imagereverted',
+ 'rollback',
+ 'rollback_short',
+ 'rollbacklink',
+ 'rollbackfailed',
+ 'cantrollback',
+ 'alreadyrolled',
+ 'editcomment',
+ 'revertpage',
+ 'sessionfailure',
+ 'protectlogpage',
+ 'protectlogtext',
+ 'protectedarticle',
+ 'unprotectedarticle',
+ 'protectsub',
+ 'confirmprotecttext',
+ 'confirmprotect',
+ 'protectmoveonly',
+ 'protectcomment',
+ 'unprotectsub',
+ 'confirmunprotecttext',
+ 'confirmunprotect',
+ 'unprotectcomment',
+ 'protect-unchain',
+ 'protect-text',
+ 'protect-viewtext',
+ 'protect-default',
+ 'protect-level-autoconfirmed',
+ 'protect-level-sysop',
+ ),
+ 'restrictions' => array(
+ 'restriction-edit',
+ 'restriction-move',
+ ),
+ 'undelete' => array(
+ 'undelete',
+ 'undeletepage',
+ 'viewdeletedpage',
+ 'undeletepagetext',
+ 'undeleteextrahelp',
+ 'undeletearticle',
+ 'undeleterevisions',
+ 'undeletehistory',
+ 'undeletehistorynoadmin',
+ 'undeleterevision',
+ 'undeleterevision-missing',
+ 'undeletebtn',
+ 'undeletereset',
+ 'undeletecomment',
+ 'undeletedarticle',
+ 'undeletedrevisions',
+ 'undeletedrevisions-files',
+ 'undeletedfiles',
+ 'cannotundelete',
+ 'undeletedpage',
+ ),
+ 'nsform' => array(
+ 'namespace',
+ 'invert',
+ ),
+ 'contributions' => array(
+ 'contributions',
+ 'mycontris',
+ 'contribsub',
+ 'nocontribs',
+ 'ucnote',
+ 'uclinks',
+ 'uctop',
+ 'newbies',
+ ),
+ 'sp-contributions' => array(
+ 'sp-contributions-newest',
+ 'sp-contributions-oldest',
+ 'sp-contributions-newer',
+ 'sp-contributions-older',
+ 'sp-contributions-newbies-sub',
+ 'sp-contributions-blocklog',
+ ),
+ 'newimages-showfrom' => array(
+ 'sp-newimages-showfrom',
+ ),
+ 'whatlinkshere' => array(
+ 'whatlinkshere',
+ 'whatlinkshere-summary',
+ 'whatlinkshere-barrow',
+ 'notargettitle',
+ 'notargettext',
+ 'linklistsub',
+ 'linkshere',
+ 'nolinkshere',
+ 'isredirect',
+ 'istemplate',
+ ),
+ 'block' => array(
+ 'blockip',
+ 'blockiptext',
+ 'ipaddress',
+ 'ipadressorusername',
+ 'ipbexpiry',
+ 'ipbreason',
+ 'ipbanononly',
+ 'ipbcreateaccount',
+ 'ipbenableautoblock',
+ 'ipbsubmit',
+ 'ipbother',
+ 'ipboptions',
+ 'ipbotheroption',
+ 'badipaddress',
+ 'blockipsuccesssub',
+ 'blockipsuccesstext',
+ 'unblockip',
+ 'unblockiptext',
+ 'ipusubmit',
+ 'unblocked',
+ 'ipblocklist',
+ 'ipblocklist-summary',
+ 'blocklistline',
+ 'infiniteblock',
+ 'expiringblock',
+ 'anononlyblock',
+ 'noautoblockblock',
+ 'createaccountblock',
+ 'ipblocklistempty',
+ 'blocklink',
+ 'unblocklink',
+ 'contribslink',
+ 'autoblocker',
+ 'blocklogpage',
+ 'blocklogentry',
+ 'blocklogtext',
+ 'unblocklogentry',
+ 'range_block_disabled',
+ 'ipb_expiry_invalid',
+ 'ipb_already_blocked',
+ 'ip_range_invalid',
+ 'proxyblocker',
+ 'ipb_cant_unblock',
+ 'proxyblockreason',
+ 'proxyblocksuccess',
+ 'sorbs',
+ 'sorbsreason',
+ 'sorbs_create_account_reason',
+ ),
+ 'developertools' => array(
+ 'lockdb',
+ 'unlockdb',
+ 'lockdbtext',
+ 'unlockdbtext',
+ 'lockconfirm',
+ 'unlockconfirm',
+ 'lockbtn',
+ 'unlockbtn',
+ 'locknoconfirm',
+ 'lockdbsuccesssub',
+ 'unlockdbsuccesssub',
+ 'lockdbsuccesstext',
+ 'unlockdbsuccesstext',
+ 'lockfilenotwritable',
+ 'databasenotlocked',
+ ),
+ 'makesysop' => array(
+ 'makesysoptitle',
+ 'makesysoptext',
+ 'makesysopname',
+ 'makesysopsubmit',
+ 'makesysopok',
+ 'makesysopfail',
+ 'setbureaucratflag',
+ 'rightslog',
+ 'rightslogtext',
+ 'rightslogentry',
+ 'rights',
+ 'set_user_rights',
+ 'user_rights_set',
+ 'set_rights_fail',
+ 'makesysop',
+ 'already_sysop',
+ 'already_bureaucrat',
+ 'rightsnone',
+ ),
+ 'movepage' => array(
+ 'movepage',
+ 'movepagetext',
+ 'movepagetalktext',
+ 'movearticle',
+ 'movenologin',
+ 'movenologintext',
+ 'newtitle',
+ 'move-watch',
+ 'movepagebtn',
+ 'pagemovedsub',
+ 'pagemovedtext',
+ 'articleexists',
+ 'talkexists',
+ 'movedto',
+ 'movetalk',
+ 'talkpagemoved',
+ 'talkpagenotmoved',
+ '1movedto2',
+ '1movedto2_redir',
+ 'movelogpage',
+ 'movelogpagetext',
+ 'movereason',
+ 'revertmove',
+ 'delete_and_move',
+ 'delete_and_move_text',
+ 'delete_and_move_confirm',
+ 'delete_and_move_reason',
+ 'selfmove',
+ 'immobile_namespace',
+ ),
+ 'export' => array(
+ 'export',
+ 'exporttext',
+ 'exportcuronly',
+ 'exportnohistory',
+ 'export-submit',
+ ),
+ 'allmessages' => array(
+ 'allmessages',
+ 'allmessagesname',
+ 'allmessagesdefault',
+ 'allmessagescurrent',
+ 'allmessagestext',
+ 'allmessagesnotsupportedUI',
+ 'allmessagesnotsupportedDB',
+ 'allmessagesfilter',
+ 'allmessagesmodified',
+ ),
+ 'thumbnails' => array(
+ 'thumbnail-more',
+ 'missingimage',
+ 'filemissing',
+ 'thumbnail_error',
+ ),
+ 'import' => array(
+ 'import',
+ 'importinterwiki',
+ 'import-interwiki-text',
+ 'import-interwiki-history',
+ 'import-interwiki-submit',
+ 'import-interwiki-namespace',
+ 'importtext',
+ 'importstart',
+ 'import-revision-count',
+ 'importnopages',
+ 'importfailed',
+ 'importunknownsource',
+ 'importcantopen',
+ 'importbadinterwiki',
+ 'importnotext',
+ 'importsuccess',
+ 'importhistoryconflict',
+ 'importnosources',
+ 'importnofile',
+ 'importuploaderror',
+ ),
+ 'importlog' => array(
+ 'importlogpage',
+ 'importlogpagetext',
+ 'import-logentry-upload',
+ 'import-logentry-upload-detail',
+ 'import-logentry-interwiki',
+ 'import-logentry-interwiki-detail',
+ ),
+ 'accesskeys' => array(
+ 'accesskey-search',
+ 'accesskey-minoredit',
+ 'accesskey-save',
+ 'accesskey-preview',
+ 'accesskey-diff',
+ 'accesskey-compareselectedversions',
+ 'accesskey-watch',
+ ),
+ 'tooltips' => array(
+ 'tooltip-search',
+ 'tooltip-minoredit',
+ 'tooltip-save',
+ 'tooltip-preview',
+ 'tooltip-diff',
+ 'tooltip-compareselectedversions',
+ 'tooltip-watch',
+ ),
+ 'stylesheets' => array(
+ 'common.css',
+ 'monobook.css',
+ ),
+ 'metadata_cc' => array(
+ 'nodublincore',
+ 'nocreativecommons',
+ 'notacceptable',
+ ),
+ 'attribution' => array(
+ 'anonymous',
+ 'siteuser',
+ 'lastmodifiedatby',
+ 'and',
+ 'othercontribs',
+ 'others',
+ 'siteusers',
+ 'creditspage',
+ 'nocredits',
+ ),
+ 'spamprotection' => array(
+ 'spamprotectiontitle',
+ 'spamprotectiontext',
+ 'spamprotectionmatch',
+ 'subcategorycount',
+ 'categoryarticlecount',
+ 'category-media-count',
+ 'listingcontinuesabbrev',
+ 'spambot_username',
+ 'spam_reverting',
+ 'spam_blanking',
+ ),
+ 'info' => array(
+ 'infosubtitle',
+ 'numedits',
+ 'numtalkedits',
+ 'numwatchers',
+ 'numauthors',
+ 'numtalkauthors',
+ ),
+ 'math' => array(
+ 'mw_math_png',
+ 'mw_math_simple',
+ 'mw_math_html',
+ 'mw_math_source',
+ 'mw_math_modern',
+ 'mw_math_mathml',
+ ),
+ 'patrolling' => array(
+ 'markaspatrolleddiff',
+ 'markaspatrolledlink',
+ 'markaspatrolledtext',
+ 'markedaspatrolled',
+ 'markedaspatrolledtext',
+ 'rcpatroldisabled',
+ 'rcpatroldisabledtext',
+ 'markedaspatrollederror',
+ 'markedaspatrollederrortext',
+ 'markedaspatrollederror-noautopatrol',
+ ),
+ 'monobook.js' => array(
+ 'monobook.js',
+ ),
+ 'common.js' => array(
+ 'common.js',
+ ),
+ 'imagedeletion' => array(
+ 'deletedrevision',
+ ),
+ 'browsediffs' => array(
+ 'previousdiff',
+ 'nextdiff',
+ ),
+ 'imagesize' => array(
+ 'imagemaxsize',
+ 'thumbsize',
+ 'showbigimage',
+ ),
+ 'newimages' => array(
+ 'newimages',
+ 'newimages-summary',
+ 'showhidebots',
+ 'noimages',
+ ),
+ 'variantname-zh' => array(
+ 'variantname-zh-cn',
+ 'variantname-zh-tw',
+ 'variantname-zh-hk',
+ 'variantname-zh-sg',
+ 'variantname-zh',
+ ),
+ 'variantname-sr' => array(
+ 'variantname-sr-ec',
+ 'variantname-sr-el',
+ 'variantname-sr-jc',
+ 'variantname-sr-jl',
+ 'variantname-sr',
+ ),
+ 'variantname-kk' => array(
+ 'variantname-kk-tr',
+ 'variantname-kk-kz',
+ 'variantname-kk-cn',
+ 'variantname-kk',
+ ),
+ 'specialloglabels' => array(
+ 'specialloguserlabel',
+ 'speciallogtitlelabel',
+ ),
+ 'passwordtooshort' => array(
+ 'passwordtooshort',
+ ),
+ 'mediawarning' => array(
+ 'mediawarning',
+ ),
+ 'fileinfo' => array(
+ 'fileinfo',
+ ),
+ 'metadata' => array(
+ 'metadata',
+ 'metadata-help',
+ 'metadata-expand',
+ 'metadata-collapse',
+ 'metadata-fields',
+ ),
+ 'exif' => array(
+ 'exif-imagewidth',
+ 'exif-imagelength',
+ 'exif-bitspersample',
+ 'exif-compression',
+ 'exif-photometricinterpretation',
+ 'exif-orientation',
+ 'exif-samplesperpixel',
+ 'exif-planarconfiguration',
+ 'exif-ycbcrsubsampling',
+ 'exif-ycbcrpositioning',
+ 'exif-xresolution',
+ 'exif-yresolution',
+ 'exif-resolutionunit',
+ 'exif-stripoffsets',
+ 'exif-rowsperstrip',
+ 'exif-stripbytecounts',
+ 'exif-jpeginterchangeformat',
+ 'exif-jpeginterchangeformatlength',
+ 'exif-transferfunction',
+ 'exif-whitepoint',
+ 'exif-primarychromaticities',
+ 'exif-ycbcrcoefficients',
+ 'exif-referenceblackwhite',
+ 'exif-datetime',
+ 'exif-imagedescription',
+ 'exif-make',
+ 'exif-model',
+ 'exif-software',
+ 'exif-artist',
+ 'exif-copyright',
+ 'exif-exifversion',
+ 'exif-flashpixversion',
+ 'exif-colorspace',
+ 'exif-componentsconfiguration',
+ 'exif-compressedbitsperpixel',
+ 'exif-pixelydimension',
+ 'exif-pixelxdimension',
+ 'exif-makernote',
+ 'exif-usercomment',
+ 'exif-relatedsoundfile',
+ 'exif-datetimeoriginal',
+ 'exif-datetimedigitized',
+ 'exif-subsectime',
+ 'exif-subsectimeoriginal',
+ 'exif-subsectimedigitized',
+ 'exif-exposuretime',
+ 'exif-exposuretime-format',
+ 'exif-fnumber',
+ 'exif-fnumber-format',
+ 'exif-exposureprogram',
+ 'exif-spectralsensitivity',
+ 'exif-isospeedratings',
+ 'exif-oecf',
+ 'exif-shutterspeedvalue',
+ 'exif-aperturevalue',
+ 'exif-brightnessvalue',
+ 'exif-exposurebiasvalue',
+ 'exif-maxaperturevalue',
+ 'exif-subjectdistance',
+ 'exif-meteringmode',
+ 'exif-lightsource',
+ 'exif-flash',
+ 'exif-focallength',
+ 'exif-focallength-format',
+ 'exif-subjectarea',
+ 'exif-flashenergy',
+ 'exif-spatialfrequencyresponse',
+ 'exif-focalplanexresolution',
+ 'exif-focalplaneyresolution',
+ 'exif-focalplaneresolutionunit',
+ 'exif-subjectlocation',
+ 'exif-exposureindex',
+ 'exif-sensingmethod',
+ 'exif-filesource',
+ 'exif-scenetype',
+ 'exif-cfapattern',
+ 'exif-customrendered',
+ 'exif-exposuremode',
+ 'exif-whitebalance',
+ 'exif-digitalzoomratio',
+ 'exif-focallengthin35mmfilm',
+ 'exif-scenecapturetype',
+ 'exif-gaincontrol',
+ 'exif-contrast',
+ 'exif-saturation',
+ 'exif-sharpness',
+ 'exif-devicesettingdescription',
+ 'exif-subjectdistancerange',
+ 'exif-imageuniqueid',
+ 'exif-gpsversionid',
+ 'exif-gpslatituderef',
+ 'exif-gpslatitude',
+ 'exif-gpslongituderef',
+ 'exif-gpslongitude',
+ 'exif-gpsaltituderef',
+ 'exif-gpsaltitude',
+ 'exif-gpstimestamp',
+ 'exif-gpssatellites',
+ 'exif-gpsstatus',
+ 'exif-gpsmeasuremode',
+ 'exif-gpsdop',
+ 'exif-gpsspeedref',
+ 'exif-gpsspeed',
+ 'exif-gpstrackref',
+ 'exif-gpstrack',
+ 'exif-gpsimgdirectionref',
+ 'exif-gpsimgdirection',
+ 'exif-gpsmapdatum',
+ 'exif-gpsdestlatituderef',
+ 'exif-gpsdestlatitude',
+ 'exif-gpsdestlongituderef',
+ 'exif-gpsdestlongitude',
+ 'exif-gpsdestbearingref',
+ 'exif-gpsdestbearing',
+ 'exif-gpsdestdistanceref',
+ 'exif-gpsdestdistance',
+ 'exif-gpsprocessingmethod',
+ 'exif-gpsareainformation',
+ 'exif-gpsdatestamp',
+ 'exif-gpsdifferential',
+ ),
+ 'exif-values' => array(
+ 'exif-make-value',
+ 'exif-model-value',
+ 'exif-software-value',
+ ),
+ 'exif-compression' => array(
+ 'exif-compression-1',
+ 'exif-compression-6',
+ ),
+ 'exif-photometricinterpretation' => array(
+ 'exif-photometricinterpretation-2',
+ 'exif-photometricinterpretation-6',
+ ),
+ 'exif-unknowndate' => array(
+ 'exif-unknowndate',
+ ),
+ 'exif-orientation' => array(
+ 'exif-orientation-1',
+ 'exif-orientation-2',
+ 'exif-orientation-3',
+ 'exif-orientation-4',
+ 'exif-orientation-5',
+ 'exif-orientation-6',
+ 'exif-orientation-7',
+ 'exif-orientation-8',
+ ),
+ 'exif-planarconfiguration' => array(
+ 'exif-planarconfiguration-1',
+ 'exif-planarconfiguration-2',
+ ),
+ 'exif-xyresolution' => array(
+ 'exif-xyresolution-i',
+ 'exif-xyresolution-c',
+ ),
+ 'exif-colorspace' => array(
+ 'exif-colorspace-1',
+ 'exif-colorspace-ffff.h',
+ ),
+ 'exif-componentsconfiguration' => array(
+ 'exif-componentsconfiguration-0',
+ 'exif-componentsconfiguration-1',
+ 'exif-componentsconfiguration-2',
+ 'exif-componentsconfiguration-3',
+ 'exif-componentsconfiguration-4',
+ 'exif-componentsconfiguration-5',
+ 'exif-componentsconfiguration-6',
+ ),
+ 'exif-exposureprogram' => array(
+ 'exif-exposureprogram-0',
+ 'exif-exposureprogram-1',
+ 'exif-exposureprogram-2',
+ 'exif-exposureprogram-3',
+ 'exif-exposureprogram-4',
+ 'exif-exposureprogram-5',
+ 'exif-exposureprogram-6',
+ 'exif-exposureprogram-7',
+ 'exif-exposureprogram-8',
+ ),
+ 'exif-subjectdistance-value' => array(
+ 'exif-subjectdistance-value',
+ ),
+ 'exif-meteringmode' => array(
+ 'exif-meteringmode-0',
+ 'exif-meteringmode-1',
+ 'exif-meteringmode-2',
+ 'exif-meteringmode-3',
+ 'exif-meteringmode-4',
+ 'exif-meteringmode-5',
+ 'exif-meteringmode-6',
+ 'exif-meteringmode-255',
+ ),
+ 'exif-lightsource' => array(
+ 'exif-lightsource-0',
+ 'exif-lightsource-1',
+ 'exif-lightsource-2',
+ 'exif-lightsource-3',
+ 'exif-lightsource-4',
+ 'exif-lightsource-9',
+ 'exif-lightsource-10',
+ 'exif-lightsource-11',
+ 'exif-lightsource-12',
+ 'exif-lightsource-13',
+ 'exif-lightsource-14',
+ 'exif-lightsource-15',
+ 'exif-lightsource-17',
+ 'exif-lightsource-18',
+ 'exif-lightsource-19',
+ 'exif-lightsource-20',
+ 'exif-lightsource-21',
+ 'exif-lightsource-22',
+ 'exif-lightsource-23',
+ 'exif-lightsource-24',
+ 'exif-lightsource-255',
+ ),
+ 'exif-focalplaneresolutionunit' => array(
+ 'exif-focalplaneresolutionunit-2',
+ ),
+ 'exif-sensingmethod' => array(
+ 'exif-sensingmethod-1',
+ 'exif-sensingmethod-2',
+ 'exif-sensingmethod-3',
+ 'exif-sensingmethod-4',
+ 'exif-sensingmethod-5',
+ 'exif-sensingmethod-7',
+ 'exif-sensingmethod-8',
+ ),
+ 'exif-filesource' => array(
+ 'exif-filesource-3',
+ ),
+ 'exif-scenetype' => array(
+ 'exif-scenetype-1',
+ ),
+ 'exif-customrendered' => array(
+ 'exif-customrendered-0',
+ 'exif-customrendered-1',
+ ),
+ 'exif-exposuremode' => array(
+ 'exif-exposuremode-0',
+ 'exif-exposuremode-1',
+ 'exif-exposuremode-2',
+ ),
+ 'exif-whitebalance' => array(
+ 'exif-whitebalance-0',
+ 'exif-whitebalance-1',
+ ),
+ 'exif-scenecapturetype' => array(
+ 'exif-scenecapturetype-0',
+ 'exif-scenecapturetype-1',
+ 'exif-scenecapturetype-2',
+ 'exif-scenecapturetype-3',
+ ),
+ 'exif-gaincontrol' => array(
+ 'exif-gaincontrol-0',
+ 'exif-gaincontrol-1',
+ 'exif-gaincontrol-2',
+ 'exif-gaincontrol-3',
+ 'exif-gaincontrol-4',
+ ),
+ 'exif-contrast' => array(
+ 'exif-contrast-0',
+ 'exif-contrast-1',
+ 'exif-contrast-2',
+ ),
+ 'exif-saturation' => array(
+ 'exif-saturation-0',
+ 'exif-saturation-1',
+ 'exif-saturation-2',
+ ),
+ 'exif-sharpness' => array(
+ 'exif-sharpness-0',
+ 'exif-sharpness-1',
+ 'exif-sharpness-2',
+ ),
+ 'exif-subjectdistancerange' => array(
+ 'exif-subjectdistancerange-0',
+ 'exif-subjectdistancerange-1',
+ 'exif-subjectdistancerange-2',
+ 'exif-subjectdistancerange-3',
+ ),
+ 'exif-gpslatitude' => array(
+ 'exif-gpslatitude-n',
+ 'exif-gpslatitude-s',
+ ),
+ 'exif-gpslongitude' => array(
+ 'exif-gpslongitude-e',
+ 'exif-gpslongitude-w',
+ ),
+ 'exif-gpsstatus' => array(
+ 'exif-gpsstatus-a',
+ 'exif-gpsstatus-v',
+ ),
+ 'exif-gpsmeasuremode' => array(
+ 'exif-gpsmeasuremode-2',
+ 'exif-gpsmeasuremode-3',
+ ),
+ 'exif-gpsspeed' => array(
+ 'exif-gpsspeed-k',
+ 'exif-gpsspeed-m',
+ 'exif-gpsspeed-n',
+ ),
+ 'exif-gpsdirection' => array(
+ 'exif-gpsdirection-t',
+ 'exif-gpsdirection-m',
+ ),
+ 'edit-externally' => array(
+ 'edit-externally',
+ 'edit-externally-help',
+ ),
+ 'all' => array(
+ 'recentchangesall',
+ 'imagelistall',
+ 'watchlistall1',
+ 'watchlistall2',
+ 'namespacesall',
+ ),
+ 'confirmemail' => array(
+ 'confirmemail',
+ 'confirmemail_noemail',
+ 'confirmemail_text',
+ 'confirmemail_pending',
+ 'confirmemail_send',
+ 'confirmemail_sent',
+ 'confirmemail_oncreate',
+ 'confirmemail_sendfailed',
+ 'confirmemail_invalid',
+ 'confirmemail_needlogin',
+ 'confirmemail_success',
+ 'confirmemail_loggedin',
+ 'confirmemail_error',
+ 'confirmemail_subject',
+ 'confirmemail_body',
+ ),
+ 'inputbox' => array(
+ 'tryexact',
+ 'searchfulltext',
+ 'createarticle',
+ ),
+ 'scarytransclusion' => array(
+ 'scarytranscludedisabled',
+ 'scarytranscludefailed',
+ 'scarytranscludetoolong',
+ ),
+ 'trackbacks' => array(
+ 'trackbackbox',
+ 'trackback',
+ 'trackbackexcerpt',
+ 'trackbackremove',
+ 'trackbacklink',
+ 'trackbackdeleteok',
+ ),
+ 'deleteconflict' => array(
+ 'deletedwhileediting',
+ 'confirmrecreate',
+ 'recreate',
+ 'tooltip-recreate',
+ ),
+ 'unit-pixel' => array(
+ 'unit-pixel',
+ ),
+ 'htmldump' => array(
+ 'redirectingto',
+ ),
+ 'purge' => array(
+ 'confirm_purge',
+ 'confirm_purge_button',
+ ),
+ 'newmessagesmulti' => array(
+ 'youhavenewmessagesmulti',
+ 'newtalkseperator',
+ ),
+ 'search2' => array(
+ 'searchcontaining',
+ 'searchnamed',
+ 'articletitles',
+ 'hideresults',
+ ),
+ 'displaytitle' => array(
+ 'displaytitle',
+ ),
+ 'catseparator' => array(
+ 'catseparator',
+ ),
+ 'loginlanguage' => array(
+ 'loginlanguagelabel',
+ 'loginlanguagelinks',
+ ),
+ 'imgmulti' => array(
+ 'imgmultipageprev',
+ 'imgmultipagenext',
+ 'imgmultigo',
+ 'imgmultigotopre',
+ 'imgmultigotopost',
+ ),
+ 'tablepager' => array(
+ 'ascending_abbrev',
+ 'descending_abbrev',
+ 'table_pager_next',
+ 'table_pager_prev',
+ 'table_pager_first',
+ 'table_pager_last',
+ 'table_pager_limit',
+ 'table_pager_limit_submit',
+ 'table_pager_empty',
+ ),
+ 'autosumm' => array(
+ 'autosumm-blank',
+ 'autosumm-replace',
+ 'autoredircomment',
+ 'autosumm-new',
+ ),
+ 'autoblock_whitelist' => array(
+ 'autoblock_whitelist',
+ ),
+ 'sizeunits' => array(
+ 'size-bytes',
+ 'size-kilobytes',
+ 'size-megabytes',
+ 'size-gigabytes',
+ ),
+);
+/** Comments for each block */
+$wgBlockComments = array(
+ 'sidebar' => "The sidebar for MonoBook is generated from this message, lines that do not
+begin with * or ** are discarded, furthermore lines that do begin with ** and
+do not contain | are also discarded, but don't depend on this behaviour for
+future releases. Also note that since each list value is wrapped in a unique
+XHTML id it should only appear once and include characters that are legal
+XHTML id names.",
+ 'toggles' => 'User preference toggles',
+ 'underline' => '',
+ 'skinpreview' => '',
+ 'dates' => 'Dates',
+ 'categories' => 'Bits of text used by many pages',
+ 'mainpage' => '',
+ 'miscellaneous1' => '',
+ 'metadata_help' => 'Metadata in edit box',
+ 'currentevents' => '',
+ 'miscellaneous2' => '',
+ 'badaccess' => '',
+ 'versionrequired' => '',
+ 'miscellaneous3' => '',
+ 'nstab' => "Short words for each namespace, by default used in the 'article' tab in monobook",
+ 'main' => 'Main script and global functions',
+ 'errors' => 'General errors',
+ 'login' => 'Login and logout pages',
+ 'resetpass' => 'Password reset dialog',
+ 'toolbar' => 'Edit page toolbar',
+ 'edit' => 'Edit pages',
+ 'undo' => '"Undo" feature',
+ 'cantcreateaccount' => 'Account creation failure',
+ 'history' => 'History pages',
+ 'history-feed' => '',
+ 'revdelete' => 'Revision deletion',
+ 'diffs' => 'Diffs',
+ 'search' => 'Search results',
+ 'preferences' => 'Preferences page',
+ 'userrights' => 'User rights',
+ 'group' => 'Groups',
+ 'group-member' => '',
+ 'grouppage' => '',
+ 'recentchanges' => 'Recent changes',
+ 'upload' => 'Upload',
+ 'upload-errors' => '',
+ 'upload-curl-errors' => 'Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>',
+ 'licenses' => '',
+ 'imagelist' => 'Image list',
+ 'mimesearch' => 'MIME search',
+ 'unwatchedpages' => 'Unwatched pages',
+ 'listredirects' => 'List redirects',
+ 'unusedtemplates' => 'Unused templates',
+ 'randomredirect' => 'Random redirect',
+ 'statistics' => 'Statistics',
+ 'disambiguations' => '',
+ 'doubleredirects' => '',
+ 'brokenredirects' => '',
+ 'specialpages' => 'Miscellaneous special pages',
+ 'booksources' => 'Book sources',
+ 'specialpages2' => '',
+ 'allpages' => 'Special:Allpages',
+ 'listusers' => 'Special:Listusers',
+ 'emailuser' => 'E-mail user',
+ 'watchlist' => 'Watchlist',
+ 'watching' => 'Displayed when you click the "watch" button and it\'s in the process of watching',
+ 'enotif' => '',
+ 'deleteprotectrev' => 'Delete/protect/revert',
+ 'restrictions' => 'Restrictions (nouns)',
+ 'undelete' => 'Undelete',
+ 'nsform' => 'Namespace form on various pages',
+ 'contributions' => 'Contributions',
+ 'sp-contributions' => '',
+ 'newimages-showfrom' => '',
+ 'whatlinkshere' => 'What links here',
+ 'block' => 'Block/unblock',
+ 'developertools' => 'Developer tools',
+ 'makesysop' => 'Make sysop',
+ 'movepage' => 'Move page',
+ 'export' => 'Export',
+ 'allmessages' => 'Namespace 8 related',
+ 'thumbnails' => 'Thumbnails',
+ 'import' => 'Special:Import',
+ 'importlog' => 'Import log',
+ 'accesskeys' => 'Keyboard access keys for power users',
+ 'tooltips' => 'Tooltip help for some actions, most are in Monobook.js',
+ 'stylesheets' => 'Stylesheets',
+ 'metadata_cc' => 'Metadata',
+ 'attribution' => 'Attribution',
+ 'spamprotection' => 'Spam protection',
+ 'info' => 'Info page',
+ 'math' => 'Math options',
+ 'patrolling' => 'Patrolling',
+ 'monobook.js' => 'Monobook.js: tooltips and access keys for monobook',
+ 'common.js' => 'Common.js: contains nothing but a placeholder comment',
+ 'imagedeletion' => 'Image deletion',
+ 'browsediffs' => 'Browsing diffs',
+ 'imagesize' => '',
+ 'newimages' => '',
+ 'variantname-zh' => "Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language",
+ 'variantname-sr' => 'Variants for Serbian language',
+ 'variantname-kk' => 'Variants for Kazakh language',
+ 'specialloglabels' => 'Labels for User: and Title: on Special:Log pages',
+ 'passwordtooshort' => '',
+ 'mediawarning' => 'Media Warning',
+ 'fileinfo' => '',
+ 'metadata' => 'Metadata',
+ 'exif' => 'EXIF tags',
+ 'exif-values' => 'Make & model, can be wikified in order to link to the camera and model name',
+ 'exif-compression' => 'EXIF attributes',
+ 'exif-unknowndate' => '',
+ 'exif-photometricinterpretation' => '',
+ 'exif-orientation' => '',
+ 'exif-planarconfiguration' => '',
+ 'exif-xyresolution' => '',
+ 'exif-colorspace' => '',
+ 'exif-componentsconfiguration' => '',
+ 'exif-exposureprogram' => '',
+ 'exif-subjectdistance-value' => '',
+ 'exif-meteringmode' => '',
+ 'exif-lightsource' => '',
+ 'exif-focalplaneresolutionunit' => '',
+ 'exif-sensingmethod' => '',
+ 'exif-filesource' => '',
+ 'exif-scenetype' => '',
+ 'exif-customrendered' => '',
+ 'exif-exposuremode' => '',
+ 'exif-whitebalance' => '',
+ 'exif-scenecapturetype' => '',
+ 'exif-gaincontrol' => '',
+ 'exif-contrast' => '',
+ 'exif-saturation' => '',
+ 'exif-sharpness' => '',
+ 'exif-subjectdistancerange' => '',
+ 'exif-gpslatitude' => 'Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef',
+ 'exif-gpslongitude' => 'Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef',
+ 'exif-gpsstatus' => '',
+ 'exif-gpsmeasuremode' => '',
+ 'exif-gpsspeed' => 'Pseudotags used for GPSSpeedRef and GPSDestDistanceRef',
+ 'exif-gpsdirection' => 'Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef',
+ 'edit-externally' => 'External editor support',
+ 'all' => "'all' in various places, this might be different for inflected languages",
+ 'confirmemail' => 'E-mail address confirmation',
+ 'inputbox' => 'Inputbox extension, may be useful in other contexts as well',
+ 'scarytransclusion' => 'Scary transclusion',
+ 'trackbacks' => 'Trackbacks',
+ 'deleteconflict' => 'Delete conflict',
+ 'unit-pixel' => '',
+ 'htmldump' => 'HTML dump',
+ 'purge' => 'action=purge',
+ 'newmessagesmulti' => '',
+ 'search2' => '',
+ 'displaytitle' => 'DISPLAYTITLE',
+ 'catseparator' => 'Separator for categories in page lists',
+ 'loginlanguage' => '',
+ 'imgmulti' => 'Multipage image navigation',
+ 'tablepager' => 'Table pager',
+ 'autosumm' => 'Auto-summaries',
+ 'autoblock_whitelist' => 'Autoblock whitelist',
+ 'sizeunits' => 'Size units',
+);
+
+/** Short comments for standalone messages */
+$wgMessageComments = array(
+ 'lastmodifiedat' => '$1 date, $2 time',
+ 'sitenotice' => 'the equivalent to wgSiteNotice',
+ 'perfdisabledsub' => 'obsolete?',
+ 'history-feed-item-nocomment' => 'user at time',
+ 'editcomment' => 'only shown if there is an edit comment',
+ 'lastmodifiedatby' => '$1 date, $2 time, $3 user',
+ 'exif-orientation-1' => '0th row: top; 0th column: left',
+ 'exif-orientation-2' => '0th row: top; 0th column: right',
+ 'exif-orientation-3' => '0th row: bottom; 0th column: right',
+ 'exif-orientation-4' => '0th row: bottom; 0th column: left',
+ 'exif-orientation-5' => '0th row: left; 0th column: top',
+ 'exif-orientation-6' => '0th row: right; 0th column: top',
+ 'exif-orientation-7' => '0th row: right; 0th column: bottom',
+ 'exif-orientation-8' => '0th row: left; 0th column: bottom',
+ 'autoredircomment' => 'This should be changed to the new naming convention, but existed beforehand',
+);
+
+/** Messages which contain dollar signs (which are not followed by numbers), and therefore should use a single apostrophe */
+$wgMessagseWithDollarSigns = array(
+ 'linkprefix',
+ 'enotif_subject',
+ 'enotif_body',
+ 'allmessagesnotsupportedDB',
+);
+
+?>
diff --git a/maintenance/language/rebuildLanguage.php b/maintenance/language/rebuildLanguage.php
new file mode 100644
index 000000000000..1643d30b0d9f
--- /dev/null
+++ b/maintenance/language/rebuildLanguage.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Rewrite the messages array in the files languages/messages/MessagesXX.php.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+require_once( dirname(__FILE__).'/../commandLine.inc' );
+require_once( 'languages.inc' );
+require_once( 'writeMessagesArray.inc' );
+
+/**
+ * Rewrite a messages array.
+ *
+ * @param $code The language code.
+ * @param $write Write to the messages file?
+ */
+function rebuildLanguage( $code, $write ) {
+ global $wgLanguages, $wg;
+
+ # Get messages
+ $messages = $wgLanguages->getMessages( $code );
+ $messages = $messages['all'];
+
+ # Rewrite messages array
+ $messagesText = writeMessagesArray( $messages, $code == 'en' );
+
+ # Write to the file
+ if ( $write ) {
+ $filename = Language::getMessagesFileName( $code );
+ $contents = file_get_contents( $filename );
+ if ( strpos( $contents, '$messages' ) !== false ) {
+ $new = explode( '$messages', $contents );
+ $new = $new[0];
+ $new .= $messagesText;
+ $new .= "\n?>\n";
+ file_put_contents( $filename, $new );
+ echo "Generated and wrote messages in language $code.\n";
+ }
+ } else {
+ echo "Generated messages in language $code.\n";
+ }
+}
+
+# Show help
+if ( isset( $options['help'] ) ) {
+ echo <<<END
+Run this script to rewrite the messages array in the files languages/messages/MessagesXX.php.
+Parameters:
+ * lang: Language code (default: the installation default language). You can also specify "all" to check all the languages.
+ * help: Show this help.
+Options:
+ * dry-run: Don't write the array to the file.
+
+END;
+ exit();
+}
+
+# Get the language code
+if ( isset( $options['lang'] ) ) {
+ $wgCode = $options['lang'];
+} else {
+ $wgCode = $wgContLang->getCode();
+}
+
+# Get the write options
+$wgWriteToFile = !isset( $options['dry-run'] );
+
+# Get language objects
+$wgLanguages = new languages();
+
+# Write all the language
+if ( $wgCode == 'all' ) {
+ foreach ( $wgLanguages->getLanguages() as $language ) {
+ rebuildLanguage( $language, $wgWriteToFile );
+ }
+} else {
+ rebuildLanguage( $wgCode, $wgWriteToFile );
+}
+
+?>
diff --git a/maintenance/language/splitLanguageFiles.inc b/maintenance/language/splitLanguageFiles.inc
new file mode 100644
index 000000000000..500d2cdc001a
--- /dev/null
+++ b/maintenance/language/splitLanguageFiles.inc
@@ -0,0 +1,1168 @@
+<?php
+/**
+ * This is an experimental list. It will later be used with a script to split
+ * the languages files in several parts then the message system will only load
+ * in memory the parts which are actually needed.
+ *
+ * Generated using: grep -r foobar *
+ *
+ * $commonMsg is the default array. Other arrays will only be loaded if needed.
+ */
+$installerMsg = array (
+'mainpagetext',
+'mainpagedocfooter',
+);
+
+$ActionMsg = array (
+'delete' => array(
+ 'delete',
+ 'deletethispage',
+ 'undelete_short1',
+ 'undelete_short',
+ 'undelete',
+ 'undeletepage',
+ 'undeletepagetext',
+ 'undeletearticle',
+ 'undeleterevisions',
+ 'undeletehistory',
+ 'undeleterevision',
+ 'undeletebtn',
+ 'undeletedarticle',
+ 'undeletedrevisions',
+ 'undeletedtext',
+ ),
+'move' => array(
+ 'move',
+ 'movethispage',
+),
+'revert' => array(
+
+),
+'protect' => array(
+ 'confirmprotect',
+ 'confirmprotecttext',
+ 'confirmunprotect',
+ 'confirmunprotecttext',
+ 'protect',
+ 'protectcomment',
+ 'protectmoveonly',
+ 'protectpage',
+ 'protectsub',
+ 'protectthispage',
+ 'unprotect',
+ 'unprotectthispage',
+ 'unprotectsub',
+ 'unprotectcomment',
+),
+);
+
+$CreditsMsg = array(
+'anonymous',
+'siteuser',
+'lastmodifiedby',
+'and',
+'othercontribs',
+'others',
+'siteusers',
+'creditspage',
+'nocredits',
+);
+
+// When showing differences
+$DifferenceMsg = array(
+'previousdiff',
+'nextdiff',
+);
+
+// used on page edition
+$EditMsg = array(
+'bold_sample',
+'bold_tip',
+'italic_sample',
+'italic_tip',
+'link_sample',
+'link_tip',
+'extlink_sample',
+'extlink_tip',
+'headline_sample',
+'headline_tip',
+'math_sample',
+'math_tip',
+'nowiki_sample',
+'nowiki_tip',
+'image_sample',
+'image_tip',
+'media_sample',
+'media_tip',
+'sig_tip',
+'hr_tip',
+
+'accesskey-search',
+'accesskey-minoredit',
+'accesskey-save',
+'accesskey-preview',
+'accesskey-diff',
+'accesskey-compareselectedversions',
+'tooltip-search',
+'tooltip-minoredit',
+'tooltip-save',
+'tooltip-preview',
+'tooltip-diff',
+'tooltip-compareselectedversions',
+'tooltip-watch',
+
+'copyrightwarning',
+'copyrightwarning2',
+'editconflict',
+'editing',
+'editingcomment',
+'editingold',
+'editingsection',
+'explainconflict',
+'infobox',
+'infobox_alert',
+'longpagewarning',
+'nonunicodebrowser',
+'previewconflict',
+'previewnote',
+'protectedpagewarning',
+'readonlywarning',
+'spamprotectiontitle',
+'spamprotectiontext',
+'spamprotectionmatch',
+'templatesused',
+'yourdiff',
+'yourtext',
+);
+
+// Per namespace
+$NamespaceCategory = array (
+'category_header',
+'categoryarticlecount',
+'categoryarticlecount1',
+'listingcontinuesabbrev',
+'subcategories',
+'subcategorycount',
+'subcategorycount1',
+'usenewcategorypage',
+);
+
+$NamespaceImage = array (
+'deletedrevision',
+'edit-externally',
+'edit-externally-help',
+'showbigimage',
+);
+
+$NamespaceSpecialMsg = array(
+'nosuchspecialpage',
+'nospecialpagetext',
+);
+
+
+
+// per special pages
+$SpecialAllMessages = array(
+'allmessages',
+'allmessagesname',
+'allmessagesdefault',
+'allmessagescurrent',
+'allmessagestext',
+'allmessagesnotsupportedUI',
+'allmessagesnotsupportedDB',
+);
+
+
+$SpecialAllPages = array(
+'articlenamespace',
+'allpagesformtext1',
+'allpagesformtext2',
+'allarticles',
+'allpagesprev',
+'allpagesnext',
+'allpagesnamespace',
+'allpagessubmit',
+);
+
+
+$SpecialAskSQLMsg = array(
+'asksql',
+'asksqltext',
+'sqlislogged',
+'sqlquery',
+'querybtn',
+'selectonly',
+'querysuccessful',
+);
+
+$SpecialBlockip = array(
+'blockip',
+'blockiptext',
+'range_block_disabled',
+'ipb_expiry_invalid',
+'ip_range_invalid',
+'ipbexpiry',
+'ipbsubmit',
+);
+
+$SpecialContributions = array(
+'contribsub',
+'contributionsall',
+'newbies',
+'nocontribs',
+'ucnote',
+'uclinks',
+'uctop',
+);
+
+$SpecialExportMsg = array (
+'export',
+'exporttext',
+'exportcuronly',
+);
+
+$SpecialImagelist = array(
+'imagelistall',
+);
+
+$SpecialImportMsg = array (
+'import',
+'importtext',
+'importfailed',
+'importnotext',
+'importsuccess',
+'importhistoryconflict',
+);
+
+$SpecialLockdbMsg = array(
+'lockdb',
+'unlockdb',
+'lockdbtext',
+'unlockdbtext',
+'lockconfirm',
+'unlockconfirm',
+'lockbtn',
+'unlockbtn',
+'locknoconfirm',
+'lockdbsuccesssub',
+'unlockdbsuccesssub',
+'lockdbsuccesstext',
+'unlockdbsuccesstext',
+);
+
+$SpecialLogMsg = array(
+'specialloguserlabel',
+'speciallogtitlelabel',
+);
+
+$SpecialMaintenance = array(
+'maintenance',
+'maintnancepagetext',
+'maintenancebacklink',
+'disambiguations',
+'disambiguationspage',
+'disambiguationstext',
+'doubleredirects',
+'doubleredirectstext',
+'brokenredirects',
+'brokenredirectstext',
+'selflinks',
+'selflinkstext',
+'mispeelings',
+'mispeelingstext',
+'mispeelingspage',
+'missinglanguagelinks',
+'missinglanguagelinksbutton',
+'missinglanguagelinkstext',
+);
+
+$SpecialMakeSysopMsg = array (
+'already_bureaucrat',
+'already_sysop',
+'makesysop',
+'makesysoptitle',
+'makesysoptext',
+'makesysopname',
+'makesysopsubmit',
+'makesysopok',
+'makesysopfail',
+'rights',
+'set_rights_fail',
+'set_user_rights',
+'user_rights_set',
+);
+
+$SpecialMovepageMsg = array(
+'newtitle',
+'movearticle',
+'movenologin',
+'movenologintext',
+'movepage',
+'movepagebtn',
+'movepagetalktext',
+'movepagetext',
+'movetalk',
+'pagemovedsub',
+'pagemovedtext',
+'talkexists',
+'talkpagemoved',
+'talkpagenotmoved',
+
+);
+
+$SpecialPreferencesMsg = array(
+'tog-underline',
+'tog-highlightbroken',
+'tog-justify',
+'tog-hideminor',
+'tog-usenewrc',
+'tog-numberheadings',
+'tog-showtoolbar',
+'tog-editondblclick',
+'tog-editsection',
+'tog-editsectiononrightclick',
+'tog-showtoc',
+'tog-rememberpassword',
+'tog-editwidth',
+'tog-watchdefault',
+'tog-minordefault',
+'tog-previewontop',
+'tog-previewonfirst',
+'tog-nocache',
+'tog-enotifwatchlistpages',
+'tog-enotifusertalkpages',
+'tog-enotifminoredits',
+'tog-enotifrevealaddr',
+'tog-shownumberswatching',
+'tog-rcusemodstyle',
+'tog-showupdated',
+'tog-fancysig',
+'tog-externaleditor',
+
+'imagemaxsize',
+'prefs-help-email',
+'prefs-help-email-enotif',
+'prefs-help-realname',
+'prefs-help-userdata',
+'prefs-misc',
+'prefs-personal',
+'prefs-rc',
+'resetprefs',
+'saveprefs',
+'oldpassword',
+'newpassword',
+'retypenew',
+'textboxsize',
+'rows',
+'columns',
+'searchresultshead',
+'resultsperpage',
+'contextlines',
+'contextchars',
+'stubthreshold',
+'recentchangescount',
+'savedprefs',
+'timezonelegend',
+'timezonetext',
+'localtime',
+'timezoneoffset',
+'servertime',
+'guesstimezone',
+'emailflag',
+'defaultns',
+'default',
+);
+
+$SpecialRecentchangesMsg = array(
+'changes',
+'recentchanges',
+'recentchanges-url',
+'recentchangestext',
+'rcloaderr',
+'rcnote',
+'rcnotefrom',
+'rclistfrom',
+'showhideminor',
+'rclinks',
+'rchide',
+'rcliu',
+'diff',
+'hist',
+'hide',
+'show',
+'tableform',
+'listform',
+'nchanges',
+'minoreditletter',
+'newpageletter',
+'sectionlink',
+'number_of_watching_users_RCview',
+'number_of_watching_users_pageview',
+'recentchangesall',
+);
+
+$SpecialRecentchangeslinkedMsg = array(
+'rclsub',
+);
+
+$SpecialSearchMsg = array(
+'searchresults',
+'searchresulttext',
+'searchquery',
+'badquery',
+'badquerytext',
+'matchtotals',
+'nogomatch',
+'titlematches',
+'notitlematches',
+'textmatches',
+'notextmatches',
+);
+
+$SpecialSitesettingsMsg = array(
+'sitesettings',
+'sitesettings-features',
+'sitesettings-permissions',
+'sitesettings-memcached',
+'sitesettings-debugging',
+'sitesettings-caching',
+'sitesettings-wgShowIPinHeader',
+'sitesettings-wgUseDatabaseMessages',
+'sitesettings-wgUseCategoryMagic',
+'sitesettings-wgUseCategoryBrowser',
+'sitesettings-wgHitcounterUpdateFreq',
+'sitesettings-wgAllowExternalImages',
+'sitesettings-permissions-readonly',
+'sitesettings-permissions-whitelist',
+'sitesettings-permissions-banning',
+'sitesettings-permissions-miser',
+'sitesettings-wgReadOnly',
+'sitesettings-wgReadOnlyFile',
+'sitesettings-wgWhitelistEdit',
+'sitesettings-wgWhitelistRead',
+'sitesettings-wgWhitelistAccount-user',
+'sitesettings-wgWhitelistAccount-sysop',
+'sitesettings-wgWhitelistAccount-developer',
+'sitesettings-wgSysopUserBans',
+'sitesettings-wgSysopRangeBans',
+'sitesettings-wgDefaultBlockExpiry',
+'sitesettings-wgMiserMode',
+'sitesettings-wgDisableQueryPages',
+'sitesettings-wgUseWatchlistCache',
+'sitesettings-wgWLCacheTimeout',
+'sitesettings-cookies',
+'sitesettings-performance',
+'sitesettings-images',
+);
+
+$SpecialStatisticsMsg = array(
+'statistics',
+'sitestats',
+'userstats',
+'sitestatstext',
+'userstatstext',
+);
+
+$SpecialUndelte = array(
+'deletepage',
+);
+
+$SpecialUploadMsg = array(
+'affirmation',
+'badfilename',
+'badfiletype',
+'emptyfile',
+'fileexists',
+'filedesc',
+'filename',
+'filesource',
+'filestatus',
+'fileuploaded',
+'ignorewarning',
+'illegalfilename',
+'largefile',
+'minlength',
+'noaffirmation',
+'reupload',
+'reuploaddesc',
+'savefile',
+'successfulupload',
+'upload',
+'uploadbtn',
+'uploadcorrupt',
+'uploaddisabled',
+'uploadfile',
+'uploadedimage',
+'uploaderror',
+'uploadlink',
+'uploadlog',
+'uploadlogpage',
+'uploadlogpagetext',
+'uploadnologin',
+'uploadnologintext',
+'uploadtext',
+'uploadwarning',
+);
+
+$SpecialUserlevelsMsg = array(
+'saveusergroups',
+'userlevels-editusergroup',
+'userlevels-groupsavailable',
+'userlevels-groupshelp',
+'userlevels-groupsmember',
+);
+
+$SpecialUserloginMsg = array(
+'acct_creation_throttle_hit',
+'loginend',
+'loginsuccesstitle',
+'loginsuccess',
+'nocookiesnew',
+'nocookieslogin',
+'noemail',
+'noname',
+'nosuchuser',
+'mailmypassword',
+'mailmypasswordauthent',
+'passwordremindermailsubject',
+'passwordremindermailbody',
+'passwordsent',
+'passwordsentforemailauthentication',
+'userexists',
+'wrongpassword',
+);
+
+$SpecialValidateMsg = array(
+'val_yes',
+'val_no',
+'val_revision',
+'val_time',
+'val_list_header',
+'val_add',
+'val_del',
+'val_warning',
+'val_rev_for',
+'val_rev_stats_link',
+'val_iamsure',
+'val_clear_old',
+'val_merge_old',
+'val_form_note',
+'val_noop',
+'val_percent',
+'val_percent_single',
+'val_total',
+'val_version',
+'val_tab',
+'val_this_is_current_version',
+'val_version_of',
+'val_table_header',
+'val_stat_link_text',
+'val_view_version',
+'val_validate_version',
+'val_user_validations',
+'val_no_anon_validation',
+'val_validate_article_namespace_only',
+'val_validated',
+'val_article_lists',
+'val_page_validation_statistics',
+);
+
+$SpecialVersionMsg = array(
+'special_version_prefix',
+'special_version_postfix'
+);
+
+$SpecialWatchlistMsg = array(
+'watchlistall1',
+'watchlistall2',
+'wlnote',
+'wlshowlast',
+'wlsaved',
+'wlhideshowown',
+'wlshow',
+'wlhide',
+);
+
+$SpecialWhatlinkshereMsg = array(
+'linklistsub',
+'nolinkshere',
+'isredirect',
+);
+
+
+$commonMsg = array (
+'sunday',
+'monday',
+'tuesday',
+'wednesday',
+'thursday',
+'friday',
+'saturday',
+'january',
+'february',
+'march',
+'april',
+'may_long',
+'june',
+'july',
+'august',
+'september',
+'october',
+'november',
+'december',
+'jan',
+'feb',
+'mar',
+'apr',
+'may',
+'jun',
+'jul',
+'aug',
+'sep',
+'oct',
+'nov',
+'dec',
+'categories',
+'category',
+'linktrail',
+'mainpage',
+'portal',
+'portal-url',
+'about',
+'aboutsite',
+'aboutpage',
+'article',
+'help',
+'helppage',
+'wikititlesuffix',
+'bugreports',
+'bugreportspage',
+'sitesupport',
+'sitesupport-url',
+'faq',
+'faqpage',
+'edithelp',
+'newwindow',
+'edithelppage',
+'cancel',
+'qbfind',
+'qbbrowse',
+'qbedit',
+'qbpageoptions',
+'qbpageinfo',
+'qbmyoptions',
+'qbspecialpages',
+'moredotdotdot',
+'mypage',
+'mytalk',
+'anontalk',
+'navigation',
+'metadata',
+'metadata_page',
+'currentevents',
+'currentevents-url',
+'disclaimers',
+'disclaimerpage',
+'errorpagetitle',
+'returnto',
+'tagline',
+'whatlinkshere',
+'search',
+'go',
+'history',
+'history_short',
+'info_short',
+'printableversion',
+'edit',
+'editthispage',
+'newpage',
+'talkpage',
+'specialpage',
+'personaltools',
+'postcomment',
+'addsection',
+'articlepage',
+'subjectpage',
+'talk',
+'toolbox',
+'userpage',
+'wikipediapage',
+'imagepage',
+'viewtalkpage',
+'otherlanguages',
+'redirectedfrom',
+'lastmodified',
+'viewcount',
+'copyright',
+'poweredby',
+'printsubtitle',
+'protectedpage',
+'administrators',
+'sysoptitle',
+'sysoptext',
+'developertitle',
+'developertext',
+'bureaucrattitle',
+'bureaucrattext',
+'nbytes',
+'ok',
+'sitetitle',
+'pagetitle',
+'sitesubtitle',
+'retrievedfrom',
+'newmessages',
+'newmessageslink',
+'editsection',
+'toc',
+'showtoc',
+'hidetoc',
+'thisisdeleted',
+'restorelink',
+'feedlinks',
+'sitenotice',
+'nstab-main',
+'nstab-user',
+'nstab-media',
+'nstab-special',
+'nstab-wp',
+'nstab-image',
+'nstab-mediawiki',
+'nstab-template',
+'nstab-help',
+'nstab-category',
+'nosuchaction',
+'nosuchactiontext',
+
+
+'error',
+'databaseerror',
+'dberrortext',
+'dberrortextcl',
+'noconnect',
+'nodb',
+'cachederror',
+'laggedslavemode',
+'readonly',
+'enterlockreason',
+'readonlytext',
+'missingarticle',
+'internalerror',
+'filecopyerror',
+'filerenameerror',
+'filedeleteerror',
+'filenotfound',
+'unexpected',
+'formerror',
+'badarticleerror',
+'cannotdelete',
+'badtitle',
+'badtitletext',
+'perfdisabled',
+'perfdisabledsub',
+'perfcached',
+'wrong_wfQuery_params',
+'viewsource',
+'protectedtext',
+'seriousxhtmlerrors',
+'logouttitle',
+'logouttext',
+'welcomecreation',
+
+'loginpagetitle',
+'yourname',
+'yourpassword',
+'yourpasswordagain',
+'newusersonly',
+'remembermypassword',
+'loginproblem',
+'alreadyloggedin',
+'login',
+'loginprompt',
+'userlogin',
+'logout',
+'userlogout',
+'notloggedin',
+'createaccount',
+'createaccountmail',
+'badretype',
+
+'youremail',
+'yourrealname',
+'yourlanguage',
+'yourvariant',
+'yournick',
+'emailforlost',
+'loginerror',
+'nosuchusershort',
+
+'mailerror',
+'emailauthenticated',
+'emailnotauthenticated',
+'invalidemailaddress',
+'disableduntilauthent',
+'disablednoemail',
+
+'summary',
+'subject',
+'minoredit',
+'watchthis',
+'savearticle',
+'preview',
+'showpreview',
+'showdiff',
+'blockedtitle',
+'blockedtext',
+'whitelistedittitle',
+'whitelistedittext',
+'whitelistreadtitle',
+'whitelistreadtext',
+'whitelistacctitle',
+'whitelistacctext',
+'loginreqtitle',
+'loginreqtext',
+'accmailtitle',
+'accmailtext',
+'newarticle',
+'newarticletext',
+'talkpagetext',
+'anontalkpagetext',
+'noarticletext',
+'clearyourcache',
+'usercssjsyoucanpreview',
+'usercsspreview',
+'userjspreview',
+'updated',
+'note',
+'storedversion', // not used ? Editpage ?
+'revhistory',
+'nohistory',
+'revnotfound',
+'revnotfoundtext',
+'loadhist',
+'currentrev',
+'revisionasof',
+'revisionasofwithlink',
+'previousrevision',
+'nextrevision',
+'currentrevisionlink',
+'cur',
+'next',
+'last',
+'orig',
+'histlegend',
+'history_copyright',
+'difference',
+'loadingrev',
+'lineno',
+'editcurrent',
+'selectnewerversionfordiff',
+'selectolderversionfordiff',
+'compareselectedversions',
+
+'prevn',
+'nextn',
+'viewprevnext',
+'showingresults',
+'showingresultsnum',
+'nonefound',
+'powersearch',
+'powersearchtext',
+'searchdisabled',
+'googlesearch',
+'blanknamespace',
+'preferences',
+'prefsnologin',
+'prefsnologintext',
+'prefslogintext',
+'prefsreset',
+'qbsettings',
+'qbsettingsnote',
+'changepassword',
+'skin',
+'math',
+'dateformat',
+
+'math_failure',
+'math_unknown_error',
+'math_unknown_function',
+'math_lexing_error',
+'math_syntax_error',
+'math_image_error',
+'math_bad_tmpdir',
+'math_bad_output',
+'math_notexvc',
+
+
+
+
+
+
+'grouplevels-lookup-group',
+'grouplevels-group-edit',
+'editgroup',
+'addgroup',
+'userlevels-lookup-user',
+'userlevels-user-editname',
+'editusergroup',
+'grouplevels-editgroup',
+'grouplevels-addgroup',
+'grouplevels-editgroup-name',
+'grouplevels-editgroup-description',
+'savegroup',
+
+// common to several pages
+'copyrightpage',
+'copyrightpagename',
+'imagelist',
+'imagelisttext',
+'ilshowmatch',
+'ilsubmit',
+'showlast',
+'byname',
+'bydate',
+'bysize',
+
+
+
+'imgdelete',
+'imgdesc',
+'imglegend',
+'imghistory',
+'revertimg',
+'deleteimg',
+'deleteimgcompletely',
+'imghistlegend',
+'imagelinks',
+'linkstoimage',
+'nolinkstoimage',
+
+// unused ??
+'uploadedfiles',
+'getimagelist',
+
+
+'sharedupload',
+'shareduploadwiki',
+
+// Special pages names
+'orphans',
+'geo',
+'validate',
+'lonelypages',
+'uncategorizedpages',
+'uncategorizedcategories',
+'unusedimages',
+'popularpages',
+'nviews',
+'wantedpages',
+'nlinks',
+'allpages',
+'randompage',
+'randompage-url',
+'shortpages',
+'longpages',
+'deadendpages',
+'listusers',
+'specialpages',
+'spheading',
+'restrictedpheading',
+'recentchangeslinked',
+
+
+'debug',
+'newpages',
+'ancientpages',
+'intl',
+'unusedimagestext',
+'booksources',
+'categoriespagetext',
+'data',
+'userlevels',
+'grouplevels',
+'booksourcetext',
+'isbn',
+'rfcurl',
+'pubmedurl',
+'alphaindexline',
+'version',
+'log',
+'alllogstext',
+'nextpage',
+'mailnologin',
+'mailnologintext',
+'emailuser',
+'emailpage',
+'emailpagetext',
+'usermailererror',
+'defemailsubject',
+'noemailtitle',
+'noemailtext',
+'emailfrom',
+'emailto',
+'emailsubject',
+'emailmessage',
+'emailsend',
+'emailsent',
+'emailsenttext',
+'watchlist',
+'watchlistsub',
+'nowatchlist',
+'watchnologin',
+'watchnologintext',
+'addedwatch',
+'addedwatchtext',
+'removedwatch',
+'removedwatchtext',
+'watch',
+'watchthispage',
+'unwatch',
+'unwatchthispage',
+'notanarticle',
+'watchnochange',
+'watchdetails',
+'watchmethod-recent',
+'watchmethod-list',
+'removechecked',
+'watchlistcontains',
+'watcheditlist',
+'removingchecked',
+'couldntremove',
+'iteminvalidname',
+
+'updatedmarker',
+'email_notification_mailer',
+'email_notification_infotext',
+'email_notification_reset',
+'email_notification_newpagetext',
+'email_notification_to',
+'email_notification_subject',
+'email_notification_lastvisitedrevisiontext',
+'email_notification_body',
+
+'confirm',
+'excontent',
+'exbeforeblank',
+'exblank',
+'confirmdelete',
+'deletesub',
+'historywarning',
+'confirmdeletetext',
+'actioncomplete',
+'deletedtext',
+'deletedarticle',
+'dellogpage',
+'dellogpagetext',
+'deletionlog',
+'reverted',
+'deletecomment',
+'imagereverted',
+'rollback',
+'rollback_short',
+'rollbacklink',
+'rollbackfailed',
+'cantrollback',
+'alreadyrolled',
+'revertpage',
+'editcomment',
+'sessionfailure',
+
+'protectlogpage',
+'protectlogtext',
+
+'protectedarticle',
+'unprotectedarticle',
+
+'contributions',
+'mycontris',
+'notargettitle', // not used ?
+'notargettext', // not used ?
+
+'linkshere',
+
+'ipaddress',
+'ipadressorusername', // not used ?
+'ipbreason',
+
+'badipaddress',
+'noblockreason',
+'blockipsuccesssub',
+'blockipsuccesstext',
+'unblockip',
+'unblockiptext',
+'ipusubmit',
+'ipusuccess',
+'ipblocklist',
+'blocklistline',
+'blocklink',
+'unblocklink',
+'contribslink',
+'autoblocker',
+'blocklogpage',
+'blocklogentry',
+'blocklogtext',
+'unblocklogentry', // not used ?
+
+'proxyblocker',
+'proxyblockreason',
+'proxyblocksuccess',
+'sorbs',
+'sorbsreason',
+
+'setbureaucratflag',
+'bureaucratlog',
+'rightslogtext',
+'bureaucratlogentry',
+
+'articleexists', // not used ?
+
+'movedto',
+'1movedto2',
+'1movedto2_redir',
+'movelogpage',
+'movelogpagetext',
+
+'thumbnail-more',
+'missingimage',
+'filemissing',
+'monobook.css',
+'nodublincore',
+'nocreativecommons',
+'notacceptable',
+
+// used in Article::
+'infosubtitle',
+'numedits',
+'numtalkedits',
+'numwatchers',
+'numauthors',
+'numtalkauthors',
+
+// not used ?
+'mw_math_png',
+'mw_math_simple',
+'mw_math_html',
+'mw_math_source',
+'mw_math_modern',
+'mw_math_mathml',
+
+// Patrolling
+'markaspatrolleddiff',
+'markaspatrolledlink',
+'markaspatrolledtext',
+'markedaspatrolled',
+'markedaspatrolledtext',
+'rcpatroldisabled', // not used ?
+'rcpatroldisabledtext', // not used ?
+
+'monobook.js',
+'newimages',
+'noimages',
+'variantname-zh-cn',
+'variantname-zh-tw',
+'variantname-zh-hk',
+'variantname-zh-sg',
+'variantname-zh',
+'zhconversiontable',
+'passwordtooshort', // sp preferences / userlogin
+);
+?>
diff --git a/maintenance/language/splitLanguageFiles.php b/maintenance/language/splitLanguageFiles.php
new file mode 100644
index 000000000000..2263e611bb9d
--- /dev/null
+++ b/maintenance/language/splitLanguageFiles.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * splitLanguageFiles
+ * Should read each of the languages files then split them in several subpart
+ * under ./languages/XX/ according to the arrays in splitLanguageFiles.inc .
+ *
+ * Also need to rewrite the wfMsg system / message-cache.
+ */
+
+include(dirname(__FILE__).'/../commandLine.inc');
+
+
+?>
diff --git a/maintenance/language/transstat.php b/maintenance/language/transstat.php
new file mode 100644
index 000000000000..e1b6727411bf
--- /dev/null
+++ b/maintenance/language/transstat.php
@@ -0,0 +1,213 @@
+<?php
+/**
+ * Statistics about the localisation.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @author Ashar Voultoiz <thoane@altern.org>
+ *
+ * Output is posted from time to time on:
+ * http://meta.wikimedia.org/wiki/Localization_statistics
+ */
+
+require_once( dirname(__FILE__).'/../commandLine.inc' );
+require_once( 'languages.inc' );
+
+if ( isset( $options['help'] ) ) {
+ showUsage();
+}
+
+# Default output is WikiText
+if ( !isset( $options['output'] ) ) {
+ $options['output'] = 'wiki';
+}
+
+/** Print a usage message*/
+function showUsage() {
+ print <<<END
+Usage: php transstat.php [--help] [--output=csv|text|wiki]
+ --help : this helpful message
+ --output : select an output engine one of:
+ * 'csv' : Comma Separated Values.
+ * 'wiki' : MediaWiki syntax (default).
+ * 'metawiki' : MediaWiki syntax used for Meta-Wiki.
+ * 'text' : Text with tabs.
+Example: php maintenance/transstat.php --output=text
+
+END;
+ exit();
+}
+
+/** A general output object. Need to be overriden */
+class statsOutput {
+ function formatPercent( $subset, $total, $revert = false, $accuracy = 2 ) {
+ return @sprintf( '%.' . $accuracy . 'f%%', 100 * $subset / $total );
+ }
+
+ # Override the following methods
+ function heading() {
+ }
+ function footer() {
+ }
+ function blockstart() {
+ }
+ function blockend() {
+ }
+ function element( $in, $heading = false ) {
+ }
+}
+
+/** Outputs WikiText */
+class wikiStatsOutput extends statsOutput {
+ function heading() {
+ global $IP;
+ $version = SpecialVersion::getVersion( $IP );
+ echo "'''Statistics are based on:''' <code>" . $version . "</code>\n\n";
+ echo "'''Note:''' These statistics can be generated by running <code>php maintenance/language/transstat.php</code>.\n\n";
+ echo "For additional information on specific languages (the message names, the actual problems, etc.), run <code>php maintenance/language/checkLanguage.php --lang=foo</code>.\n\n";
+ echo '{| class="sortable wikitable" border="2" cellpadding="4" cellspacing="0" style="background-color: #F9F9F9; border: 1px #AAAAAA solid; border-collapse: collapse;" width="100%"'."\n";
+ }
+ function footer() {
+ echo "|}\n";
+ }
+ function blockstart() {
+ echo "|-\n";
+ }
+ function blockend() {
+ echo '';
+ }
+ function element( $in, $heading = false ) {
+ echo ($heading ? '!' : '|') . " $in\n";
+ }
+ function formatPercent( $subset, $total, $revert = false, $accuracy = 2 ) {
+ $v = @round(255 * $subset / $total);
+ if ( $revert ) {
+ $v = 255 - $v;
+ }
+ if ( $v < 128 ) {
+ # Red to Yellow
+ $red = 'FF';
+ $green = sprintf( '%02X', 2 * $v );
+ } else {
+ # Yellow to Green
+ $red = sprintf('%02X', 2 * ( 255 - $v ) );
+ $green = 'FF';
+ }
+ $blue = '00';
+ $color = $red . $green . $blue;
+
+ $percent = statsOutput::formatPercent( $subset, $total, $revert, $accuracy );
+ return 'bgcolor="#'. $color .'" | '. $percent;
+ }
+}
+
+/** Outputs WikiText and appends category and text only used for Meta-Wiki */
+class metawikiStatsOutput extends wikiStatsOutput {
+ function heading() {
+ echo "See [[MediaWiki localisation]] to learn how you can help translating MediaWiki.\n\n";
+ parent::heading();
+ }
+ function footer() {
+ parent::footer();
+ echo "\n[[Category:Localisation|Statistics]]\n";
+ }
+}
+
+/** Output text. To be used on a terminal for example. */
+class textStatsOutput extends statsOutput {
+ function element( $in, $heading = false ) {
+ echo $in."\t";
+ }
+ function blockend() {
+ echo "\n";
+ }
+}
+
+/** csv output. Some people love excel */
+class csvStatsOutput extends statsOutput {
+ function element( $in, $heading = false ) {
+ echo $in . ";";
+ }
+ function blockend() {
+ echo "\n";
+ }
+}
+
+# Select an output engine
+switch ( $options['output'] ) {
+ case 'wiki':
+ $wgOut = new wikiStatsOutput();
+ break;
+ case 'metawiki':
+ $wgOut = new metawikiStatsOutput();
+ break;
+ case 'text':
+ $wgOut = new textStatsOutput();
+ break;
+ case 'csv':
+ $wgOut = new csvStatsOutput();
+ break;
+ default:
+ showUsage();
+}
+
+# Languages
+$wgLanguages = new languages();
+
+# Header
+$wgOut->heading();
+$wgOut->blockstart();
+$wgOut->element( 'Language', true );
+$wgOut->element( 'Code', true );
+$wgOut->element( 'Translated', true );
+$wgOut->element( '%', true );
+$wgOut->element( 'Obsolete', true );
+$wgOut->element( '%', true );
+$wgOut->element( 'Problematic', true );
+$wgOut->element( '%', true );
+$wgOut->blockend();
+
+$wgGeneralMessages = $wgLanguages->getGeneralMessages();
+$wgRequiredMessagesNumber = count( $wgGeneralMessages['required'] );
+
+foreach ( $wgLanguages->getLanguages() as $code ) {
+ # Don't check English or RTL English
+ if ( $code == 'en' || $code == 'enRTL' ) {
+ continue;
+ }
+
+ # Calculate the numbers
+ $language = $wgContLang->getLanguageName( $code );
+ $messages = $wgLanguages->getMessages( $code );
+ $messagesNumber = count( $messages['translated'] );
+ $requiredMessagesNumber = count( $messages['required'] );
+ $requiredMessagesPercent = $wgOut->formatPercent( $requiredMessagesNumber, $wgRequiredMessagesNumber );
+ $obsoleteMessagesNumber = count( $messages['obsolete'] );
+ $obsoleteMessagesPercent = $wgOut->formatPercent( $obsoleteMessagesNumber, $messagesNumber, true );
+ $messagesWithoutVariables = $wgLanguages->getMessagesWithoutVariables( $code );
+ $emptyMessages = $wgLanguages->getEmptyMessages( $code );
+ $messagesWithWhitespace = $wgLanguages->getMessagesWithWhitespace( $code );
+ $nonXHTMLMessages = $wgLanguages->getNonXHTMLMessages( $code );
+ $messagesWithWrongChars = $wgLanguages->getMessagesWithWrongChars( $code );
+ $problematicMessagesNumber = count( array_unique( array_merge( $messagesWithoutVariables, $emptyMessages, $messagesWithWhitespace, $nonXHTMLMessages, $messagesWithWrongChars ) ) );
+ $problematicMessagesPercent = $wgOut->formatPercent( $problematicMessagesNumber, $messagesNumber, true );
+
+ # Output them
+ $wgOut->blockstart();
+ $wgOut->element( "$language" );
+ $wgOut->element( "$code" );
+ $wgOut->element( "$requiredMessagesNumber/$wgRequiredMessagesNumber" );
+ $wgOut->element( $requiredMessagesPercent );
+ $wgOut->element( "$obsoleteMessagesNumber/$messagesNumber" );
+ $wgOut->element( $obsoleteMessagesPercent );
+ $wgOut->element( "$problematicMessagesNumber/$messagesNumber" );
+ $wgOut->element( $problematicMessagesPercent );
+ $wgOut->blockend();
+}
+
+# Footer
+$wgOut->footer();
+
+?>
diff --git a/maintenance/language/validate.php b/maintenance/language/validate.php
new file mode 100644
index 000000000000..10d98d37248c
--- /dev/null
+++ b/maintenance/language/validate.php
@@ -0,0 +1,40 @@
+<?php
+
+if ( !isset( $argv[1] ) ) {
+ print "Usage: php {$argv[0]} <filename>\n";
+ exit( 1 );
+}
+array_shift( $argv );
+
+define( 'MEDIAWIKI', 1 );
+define( 'NOT_REALLY_MEDIAWIKI', 1 );
+
+$IP = dirname( __FILE__ ) . '/../..';
+
+require_once( "$IP/includes/Defines.php" );
+require_once( "$IP/languages/Language.php" );
+
+$files = array();
+foreach ( $argv as $arg ) {
+ $files = array_merge( $files, glob( $arg ) );
+}
+
+foreach ( $files as $filename ) {
+ print "$filename...";
+ $vars = getVars( $filename );
+ $keys = array_keys( $vars );
+ $diff = array_diff( $keys, Language::$mLocalisationKeys );
+ if ( $diff ) {
+ print "\nWarning: unrecognised variable(s): " . implode( ', ', $diff ) ."\n";
+ } else {
+ print " ok\n";
+ }
+}
+
+function getVars( $filename ) {
+ require( $filename );
+ $vars = get_defined_vars();
+ unset( $vars['filename'] );
+ return $vars;
+}
+?>
diff --git a/maintenance/language/writeMessagesArray.inc b/maintenance/language/writeMessagesArray.inc
new file mode 100644
index 000000000000..b0d17c59cacf
--- /dev/null
+++ b/maintenance/language/writeMessagesArray.inc
@@ -0,0 +1,145 @@
+<?php
+/**
+ * Write a messages array as a PHP text.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+require_once( 'messages.inc' );
+require_once( 'messageTypes.inc' );
+
+/**
+ * Write a messages array as a PHP text.
+ *
+ * @param $messages The messages array.
+ * @param $ignoredComments Show comments about ignored and optional messages? (For English.)
+ *
+ * @return The PHP text.
+ */
+function writeMessagesArray( $messages, $ignoredComments = false ) {
+ global $wgMessageStrucutre, $wgBlockComments, $wgMessageComments;
+
+ # Sort messages to blocks
+ $sortedMessages['unknown'] = $messages;
+ foreach ( $wgMessageStrucutre as $blockName => $block ) {
+ foreach ( $block as $key ) {
+ if ( array_key_exists( $key, $sortedMessages['unknown'] ) ) {
+ $sortedMessages[$blockName][$key] = $sortedMessages['unknown'][$key];
+ unset( $sortedMessages['unknown'][$key] );
+ }
+ }
+ }
+
+ # Write all the messages
+ $messagesText = "\$messages = array(\n";
+ foreach( $sortedMessages as $block => $messages ) {
+ # Skip if it's the block of unknown messages - handle that in the end of file
+ if ( $block == 'unknown' ) {
+ continue;
+ }
+
+ # Write the block
+ $messagesText .= writeMessagesBlock( $block, $wgBlockComments[$block], $messages, $ignoredComments );
+ }
+ ksort( $sortedMessages['unknown'] );
+ $messagesText .= writeMessagesBlock( 'unknown', 'Unknown messages', $sortedMessages['unknown'], $ignoredComments ); # Write the unknown messages, alphabetically sorted
+ $messagesText .= ");\n";
+
+ return $messagesText;
+}
+
+/**
+ * Write a block of messages to PHP.
+ *
+ * @param $name The block name.
+ * @param $comment The block comment.
+ * @param $messages The block messages.
+ * @param $ignoredComments Show comments about ignored and optional messages? (For English.)
+ *
+ * @return The block, formatted in PHP.
+ */
+function writeMessagesBlock( $name, $comment, $messages, $ignoredComments ) {
+ global $wgMessageComments, $wgMessagseWithDollarSigns;
+ global $wgIgnoredMessages, $wgOptionalMessages;
+ $blockText = '';
+
+ # Skip the block if it includes no messages
+ if ( empty( $messages ) ) {
+ return '';
+ }
+
+ # Format the block comment (if exists); check for multiple lines comments
+ if ( !empty( $comment ) ) {
+ if ( strpos( $comment, "\n" ) === false ) {
+ $blockText .= "# $comment\n";
+ } else {
+ $blockText .= "/*\n$comment\n*/\n";
+ }
+ }
+
+ # Get max key length
+ $maxKeyLength = 0;
+ foreach( array_keys( $messages ) as $key ) {
+ if ( strlen( $key ) > $maxKeyLength ) {
+ $maxKeyLength = strlen( $key );
+ }
+ }
+
+ # Format the messages
+ foreach( $messages as $key => $value ) {
+ # Add the key name
+ $blockText .= "'$key'";
+
+ # Add the appropriate block whitespace
+ for ( $i = 1; $i <= ( $maxKeyLength - strlen( $key ) ); $i++ ) {
+ $blockText .= ' ';
+ }
+
+ # Refer to the value
+ $blockText .= ' => ';
+
+ # Check for the appropriate apostrophe and add the value
+ if ( strpos( $value, "'" ) === false ) {
+ $blockText .= "'$value'";
+ } elseif ( strpos( $value, '"' ) === false && !in_array( $key, $wgMessagseWithDollarSigns ) ) {
+ $blockText .= "\"$value\"";
+ } else {
+ $blockText .= "'" . str_replace( "'", "\'", $value ) . "'";
+ }
+
+ # Comma
+ $blockText .= ',';
+
+ $ignoredComment = "don't translate or duplicate this message to other languages";
+ $optionalComment = "only translate this message to other languages if you have to change it";
+ $showIgnoredOrOptionalComment = in_array( $key, $wgIgnoredMessages ) || in_array( $key, $wgOptionalMessages );
+ if ( $ignoredComments ) {
+ if ( array_key_exists( $key, $wgMessageComments ) ) {
+ $blockText .= ' # ' . $wgMessageComments[$key];
+ if ( $showIgnoredOrOptionalComment ) {
+ $blockText .= '; ';
+ }
+ } elseif ( $showIgnoredOrOptionalComment ) {
+ $blockText .= ' # ';
+ }
+ if ( in_array( $key, $wgIgnoredMessages ) ) {
+ $blockText .= $ignoredComment;
+ } elseif ( in_array( $key, $wgOptionalMessages ) ) {
+ $blockText .= $optionalComment;
+ }
+ } elseif ( array_key_exists( $key, $wgMessageComments ) ) {
+ $blockText .= ' # ' . $wgMessageComments[$key];
+ }
+
+ # Newline
+ $blockText .= "\n";
+ }
+
+ # Newline to end the block
+ $blockText .= "\n";
+
+ return $blockText;
+}
+
+?>
diff --git a/maintenance/mcc.php b/maintenance/mcc.php
new file mode 100644
index 000000000000..93b6ec183ac9
--- /dev/null
+++ b/maintenance/mcc.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ * memcached diagnostic tool
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( 'commandLine.inc' );
+require_once( 'memcached-client.php' );
+
+$mcc = new memcached( array('persistant' => true/*, 'debug' => true*/) );
+$mcc->set_servers( $wgMemCachedServers );
+#$mcc->set_debug( true );
+
+function mccShowHelp($command) {
+
+ if(! $command ) { $command = 'fullhelp'; }
+ $onlyone = true;
+
+ switch ( $command ) {
+
+ case 'fullhelp':
+ // will show help for all commands
+ $onlyone = false;
+
+ case 'get':
+ print "get: grabs something\n";
+ if($onlyone) { break; }
+
+ case 'getsock':
+ print "getsock: lists sockets\n";
+ if($onlyone) { break; }
+
+ case 'set':
+ print "set: changes something\n";
+ if($onlyone) { break; }
+
+ case 'delete':
+ print "delete: deletes something\n";
+ if($onlyone) { break; }
+
+ case 'history':
+ print "history: show command line history\n";
+ if($onlyone) { break; }
+
+ case 'server':
+ print "server: show current memcached server\n";
+ if($onlyone) { break; }
+
+ case 'dumpmcc':
+ print "dumpmcc: shows the whole thing\n";
+ if($onlyone) { break; }
+
+ case 'exit':
+ case 'quit':
+ print "exit or quit: exit mcc\n";
+ if($onlyone) { break; }
+
+ case 'help':
+ print "help: help about a command\n";
+ if($onlyone) { break; }
+
+ default:
+ if($onlyone) {
+ print "$command: command does not exist or no help for it\n";
+ }
+ }
+}
+
+do {
+ $bad = false;
+ $showhelp = false;
+ $quit = false;
+
+ $line = readconsole( '> ' );
+ if ($line === false) exit;
+
+ $args = explode( ' ', $line );
+ $command = array_shift( $args );
+
+ // process command
+ switch ( $command ) {
+ case 'help':
+ // show an help message
+ mccShowHelp(array_shift($args));
+ break;
+
+ case 'get':
+ print "Getting {$args[0]}[{$args[1]}]\n";
+ $res = $mcc->get( $args[0] );
+ if ( array_key_exists( 1, $args ) ) {
+ $res = $res[$args[1]];
+ }
+ if ( $res === false ) {
+ #print 'Error: ' . $mcc->error_string() . "\n";
+ print "MemCached error\n";
+ } elseif ( is_string( $res ) ) {
+ print "$res\n";
+ } else {
+ var_dump( $res );
+ }
+ break;
+
+ case 'getsock':
+ $res = $mcc->get( $args[0] );
+ $sock = $mcc->get_sock( $args[0] );
+ var_dump( $sock );
+ break;
+
+ case 'server':
+ $res = $mcc->get( $args[0] );
+ print $mcc->_buckets[$mcc->_hashfunc( $args[0] ) % $mcc->_bucketcount] . "\n";
+ break;
+
+ case 'set':
+ $key = array_shift( $args );
+ if ( $args[0] == "#" && is_numeric( $args[1] ) ) {
+ $value = str_repeat( '*', $args[1] );
+ } else {
+ $value = implode( ' ', $args );
+ }
+ if ( !$mcc->set( $key, $value, 0 ) ) {
+ #print 'Error: ' . $mcc->error_string() . "\n";
+ print "MemCached error\n";
+ }
+ break;
+
+ case 'delete':
+ $key = implode( ' ', $args );
+ if ( !$mcc->delete( $key ) ) {
+ #print 'Error: ' . $mcc->error_string() . "\n";
+ print "MemCached error\n";
+ }
+ break;
+
+ case 'history':
+ if ( function_exists( 'readline_list_history' ) ) {
+ foreach( readline_list_history() as $num => $line) {
+ print "$num: $line\n";
+ }
+ } else {
+ print "readline_list_history() not available\n";
+ }
+ break;
+
+ case 'dumpmcc':
+ var_dump( $mcc );
+ break;
+
+ case 'quit':
+ case 'exit':
+ $quit = true;
+ break;
+
+ default:
+ $bad = true;
+ } // switch() end
+
+ if ( $bad ) {
+ if ( $command ) {
+ print "Bad command\n";
+ }
+ } else {
+ if ( function_exists( 'readline_add_history' ) ) {
+ readline_add_history( $line );
+ }
+ }
+} while ( !$quit );
+
+?>
diff --git a/maintenance/mctest.php b/maintenance/mctest.php
new file mode 100644
index 000000000000..316620d78eee
--- /dev/null
+++ b/maintenance/mctest.php
@@ -0,0 +1,60 @@
+<?php
+/* $Id$ */
+
+$optionsWithArgs = array( 'i' );
+
+require_once('commandLine.inc');
+
+function microtime_float()
+{
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec + (float)$sec);
+}
+
+
+#$wgDebugLogFile = '/dev/stdout';
+
+if ( isset( $args[0] ) ) {
+ $wgMemCachedServers = array( $args[0] );
+} else {
+ $wgMemCachedServers[] = 'localhost';
+}
+if ( isset( $options['i'] ) ) {
+ $iterations = $options['i'];
+} else {
+ $iterations = 100;
+}
+
+foreach ( $wgMemCachedServers as $server ) {
+ print "$server ";
+ $mcc = new MemCachedClientforWiki( array('persistant' => true) );
+ $mcc->set_servers( array( $server ) );
+ $set = 0;
+ $incr = 0;
+ $get = 0;
+ $time_start=microtime_float();
+ for ( $i=1; $i<=$iterations; $i++ ) {
+ if ( !is_null( $mcc->set( "test$i", $i ) ) ) {
+ $set++;
+ }
+ }
+
+ for ( $i=1; $i<=$iterations; $i++ ) {
+ if ( !is_null( $mcc->incr( "test$i", $i ) ) ) {
+ $incr++;
+ }
+ }
+
+ for ( $i=1; $i<=$iterations; $i++ ) {
+ $value = $mcc->get( "test$i" );
+ if ( $value == $i*2 ) {
+ $get++;
+ }
+ }
+ $exectime=microtime_float()-$time_start;
+
+ print "set: $set incr: $incr get: $get time: $exectime\n";
+}
+
+
+?>
diff --git a/maintenance/moveBatch.php b/maintenance/moveBatch.php
new file mode 100644
index 000000000000..4b0abf7f1387
--- /dev/null
+++ b/maintenance/moveBatch.php
@@ -0,0 +1,95 @@
+<?php
+
+/**
+ * Maintenance script to move a batch of pages
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Tim Starling
+ *
+ * USAGE: php moveBatch.php [-u <user>] [-r <reason>] [-i <interval>] <listfile>
+ *
+ * <listfile> - file with two titles per line, separated with pipe characters;
+ * the first title is the source, the second is the destination
+ * <user> - username to perform moves as
+ * <reason> - reason to be given for moves
+ * <interval> - number of seconds to sleep after each move
+ *
+ * This will print out error codes from Title::moveTo() if something goes wrong,
+ * e.g. immobile_namespace for namespaces which can't be moved
+ */
+
+$oldCwd = getcwd();
+$optionsWithArgs = array( 'u', 'r', 'i' );
+require_once( 'commandLine.inc' );
+
+chdir( $oldCwd );
+
+# Options processing
+
+$filename = 'php://stdin';
+$user = 'Move page script';
+$reason = '';
+$interval = 0;
+
+if ( isset( $args[0] ) ) {
+ $filename = $args[0];
+}
+if ( isset( $options['u'] ) ) {
+ $user = $options['u'];
+}
+if ( isset( $options['r'] ) ) {
+ $reason = $options['r'];
+}
+if ( isset( $options['i'] ) ) {
+ $interval = $options['i'];
+}
+
+$wgUser = User::newFromName( $user );
+
+
+# Setup complete, now start
+
+$file = fopen( $filename, 'r' );
+if ( !$file ) {
+ print "Unable to read file, exiting\n";
+ exit;
+}
+
+$dbw =& wfGetDB( DB_MASTER );
+
+for ( $linenum = 1; !feof( $file ); $linenum++ ) {
+ $line = fgets( $file );
+ if ( $line === false ) {
+ break;
+ }
+ $parts = array_map( 'trim', explode( '|', $line ) );
+ if ( count( $parts ) != 2 ) {
+ print "Error on line $linenum, no pipe character\n";
+ continue;
+ }
+ $source = Title::newFromText( $parts[0] );
+ $dest = Title::newFromText( $parts[1] );
+ if ( is_null( $source ) || is_null( $dest ) ) {
+ print "Invalid title on line $linenum\n";
+ continue;
+ }
+
+
+ print $source->getPrefixedText() . ' --> ' . $dest->getPrefixedText();
+ $dbw->begin();
+ $err = $source->moveTo( $dest, false, $reason );
+ if( $err !== true ) {
+ print "\nFAILED: $err";
+ }
+ $dbw->immediateCommit();
+ print "\n";
+
+ if ( $interval ) {
+ sleep( $interval );
+ }
+ wfWaitForSlaves( 5 );
+}
+
+
+?>
diff --git a/maintenance/mwdocgen.php b/maintenance/mwdocgen.php
new file mode 100644
index 000000000000..de1a7d96d351
--- /dev/null
+++ b/maintenance/mwdocgen.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * Script to easily generate the mediawiki documentation using doxygen.
+ *
+ * By default it will generate the whole documentation but you will be able to
+ * generate just some parts.
+ *
+ * Usage:
+ * php mwdocgen.php
+ *
+ * Then make a selection from the menu
+ *
+ * KNOWN BUGS:
+ *
+ * - pass_thru seems to always use buffering (even with ob_implicit_flush()),
+ * that make output slow when doxygen parses language files.
+ * - the menu doesnt work, got disabled at revision 13740. Need to code it.
+ *
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @author Ashar Voultoiz <thoane@altern.org>
+ * @version first release
+ */
+
+#
+# Variables / Configuration
+#
+
+if( php_sapi_name() != 'cli' ) {
+ echo 'Run me from the command line.';
+ die( -1 );
+}
+
+/** Figure out the base directory for MediaWiki location */
+$mwPath = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR;
+
+/** Global variable: temporary directory */
+$tmpPath = '/tmp/';
+
+/** doxygen binary script */
+$doxygenBin = 'doxygen';
+
+/** doxygen configuration template for mediawiki */
+$doxygenTemplate = $mwPath . 'maintenance/Doxyfile';
+
+/** where Phpdoc should output documentation */
+#$doxyOutput = '/var/www/mwdoc/';
+$doxyOutput = $mwPath . 'docs' . DIRECTORY_SEPARATOR ;
+
+/** MediaWiki subpaths */
+$mwPathI = $mwPath.'includes/';
+$mwPathL = $mwPath.'languages/';
+$mwPathM = $mwPath.'maintenance/';
+$mwPathS = $mwPath.'skins/';
+
+/** Variable to get user input */
+$input = '';
+
+/** shell command that will be run */
+$command = $doxygenBin;
+
+#
+# Functions
+#
+
+function readaline( $prompt = '') {
+ print $prompt;
+ $fp = fopen( "php://stdin", "r" );
+ $resp = trim( fgets( $fp, 1024 ) );
+ fclose( $fp );
+ return $resp;
+ }
+
+/**
+ * Generate a configuration file given user parameters and return the temporary filename.
+ * @param $doxygenTemplate String: full path for the template.
+ * @param $outputDirectory String: directory where the stuff will be output.
+ * @param $stripFromPath String: path that should be stripped out (usually mediawiki base path).
+ * @param $input String: Path to analyze.
+ */
+function generateConfigFile($doxygenTemplate, $outputDirectory, $stripFromPath, $input) {
+ global $tmpPath ;
+
+ $template = file_get_contents($doxygenTemplate);
+
+ // Replace template placeholders by correct values.
+ $tmpCfg = str_replace(
+ array(
+ '{{OUTPUT_DIRECTORY}}',
+ '{{STRIP_FROM_PATH}}',
+ '{{INPUT}}',
+ ),
+ array(
+ $outputDirectory,
+ $stripFromPath,
+ $input,
+ ),
+ $template
+ );
+ $tmpFileName = $tmpPath . 'mwdocgen'. rand() .'.tmp';
+ file_put_contents( $tmpFileName , $tmpCfg ) or die("Could not write doxygen configuration to file $tmpFileName\n");
+
+ return $tmpFileName;
+}
+
+#
+# Main !
+#
+
+unset( $file );
+
+if( is_array( $argv ) && isset( $argv[1] ) ) {
+ switch( $argv[1] ) {
+ case '--all': $input = 0; break;
+ case '--includes': $input = 1; break;
+ case '--languages': $input = 2; break;
+ case '--maintenance': $input = 3; break;
+ case '--skins': $input = 4; break;
+ case '--file':
+ $input = 5;
+ if( isset( $argv[2] ) ) {
+ $file = $argv[2];
+ }
+ break;
+ }
+}
+
+if( $input === '' ) {
+?>Several documentation possibilities:
+ 0 : whole documentation (1 + 2 + 3 + 4)
+ 1 : only includes
+ 2 : only languages
+ 3 : only maintenance
+ 4 : only skins
+ 5 : only a given file<?php
+ while ( !is_numeric($input) )
+ {
+ $input = readaline( "\nEnter your choice [0]:" );
+ if($input == '') {
+ $input = 0;
+ }
+ }
+}
+/*
+switch ($input) {
+case 0:
+ $command .= " -f $mwBaseFiles -d $mwPathI,$mwPathL,$mwPathM,$mwPathS";
+ break;
+case 1:
+ $command .= "-d $mwPathI";
+ break;
+case 2:
+ $command .= "-d $mwPathL";
+ break;
+case 3:
+ $command .= "-d $mwPathM";
+ break;
+case 4:
+ $command .= "-d $mwPathS";
+ break;
+case 5:
+ if( !isset( $file ) ) {
+ $file = readaline("Enter file name $mwPath");
+ }
+ $command .= ' -f '.$mwPath.$file;
+}
+
+$command .= " -t $pdOutput ".$pdOthers;
+
+*/
+
+// TODO : generate a list of paths ))
+$input = $mwPath;
+
+$generatedConf = generateConfigFile($doxygenTemplate, $doxyOutput, $mwPath, $input );
+$command = $doxygenBin . ' ' . $generatedConf ;
+
+?>
+---------------------------------------------------
+Launching the command:
+
+<?php echo $command ?>
+
+---------------------------------------------------
+<?php
+
+passthru($command);
+
+?>
+---------------------------------------------------
+Doxygen execution finished.
+Check above for possible errors.
+
+You might want to deleted the temporary file <?php echo $generatedConf; ?>
+
+<?php
+
+# phpdoc -d ./mediawiki/includes/ ./mediawiki/maintenance/ -f ./mediawiki/*php -t ./mwdoc/ -dn 'MediaWiki' --title 'MediaWiki generated documentation' -o 'HTML:frames:DOM/earthli'
+
+# phpdoc -f ./mediawiki/includes/GlobalFunctions.php -t ./mwdoc/ -dn 'MediaWiki' --title 'MediaWiki generated documentation' -o 'HTML:frames:DOM/earthli'
+
+?>
diff --git a/maintenance/mwdoxygen.cfg b/maintenance/mwdoxygen.cfg
new file mode 100644
index 000000000000..39fae228d7ec
--- /dev/null
+++ b/maintenance/mwdoxygen.cfg
@@ -0,0 +1,1136 @@
+# Doxyfile 1.4.3-20050530
+
+#
+# NOTE: this configuration assume you are running doxygen from the
+# mediawiki root directory. For example:
+# ~/dev/mediawiki-HEAD/
+# The easiest way is to get in the maintenance directory and then:
+# make doxydoc
+#
+# Paths visited are configured by the INPUT variable (around line 450)
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for the MediaWiki project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+PROJECT_NAME = MediaWiki
+PROJECT_NUMBER = 1.6-cvs
+OUTPUT_DIRECTORY = docs
+
+# 2 levels directories, create 4096 of them!
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+USE_WINDOWS_ENCODING = NO
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+ALWAYS_DETAILED_SEC = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+DISTRIBUTE_GROUP_DOC = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+ALIASES =
+
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+SUBGROUPING = YES
+
+
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+SORT_BY_SCOPE_NAME = NO
+
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation.
+SHOW_DIRECTORIES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the progam writes to standard output
+# is used as the file version. See the manual for examples.
+FILE_VERSION_FILTER =
+
+
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+# should be run from maintenance
+# FIXME : includes/normal includes/templates languages are missing
+INPUT = config includes maintenance skins tests
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS = *.php *.inc
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = NO
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/maintenance/mysql5/tables-binary.sql b/maintenance/mysql5/tables-binary.sql
new file mode 100644
index 000000000000..2ab365463861
--- /dev/null
+++ b/maintenance/mysql5/tables-binary.sql
@@ -0,0 +1,1095 @@
+-- Experimental table definitions for MySQL 4.1 and 5.0 with
+-- content-holding fields switched to explicit binary charset.
+--
+-- Binary is used instead of UTF-8 or UCS-2 so that all of
+-- Unicode may be used as UTF-8 (MySQL still does not allow
+-- use of characters outside the BMP in UTF-8 and has no UTF-16
+-- support).
+--
+-- This should provide compatibility with our current MySQL 4.0
+-- behavior (safe for full UTF-8, but ugly sorting) on newer
+-- versions of MySQL server, without the conversion surprises
+-- you get from piggybacking on "Latin-1" fields.
+--
+-- UTF-8 is used for the searchindex fields, as the fulltext index
+-- doesn't seem to like the binary encoding.
+--
+-- Not fully tested, may have surprises!
+--
+-- TODO: Test various fields
+
+-- ------------------------------------------------------------
+
+-- SQL to create the initial tables for the MediaWiki database.
+-- This is read and executed by the install script; you should
+-- not have to run it by itself unless doing a manual install.
+
+--
+-- General notes:
+--
+-- If possible, create tables as InnoDB to benefit from the
+-- superior resiliency against crashes and ability to read
+-- during writes (and write during reads!)
+--
+-- Only the 'searchindex' table requires MyISAM due to the
+-- requirement for fulltext index support, which is missing
+-- from InnoDB.
+--
+--
+-- The MySQL table backend for MediaWiki currently uses
+-- 14-character CHAR or VARCHAR fields to store timestamps.
+-- The format is YYYYMMDDHHMMSS, which is derived from the
+-- text format of MySQL's TIMESTAMP fields.
+--
+-- Historically TIMESTAMP fields were used, but abandoned
+-- in early 2002 after a lot of trouble with the fields
+-- auto-updating.
+--
+-- The Postgres backend uses DATETIME fields for timestamps,
+-- and we will migrate the MySQL definitions at some point as
+-- well.
+--
+--
+-- The /*$wgDBprefix*/ comments in this and other files are
+-- replaced with the defined table prefix by the installer
+-- and updater scripts. If you are installing or running
+-- updates manually, you will need to manually insert the
+-- table prefix if any when running these scripts.
+--
+
+
+--
+-- The user table contains basic account information,
+-- authentication keys, etc.
+--
+-- Some multi-wiki sites may share a single central user table
+-- between separate wikis using the $wgSharedDB setting.
+--
+-- Note that when a external authentication plugin is used,
+-- user table entries still need to be created to store
+-- preferences and to key tracking information in the other
+-- tables.
+--
+CREATE TABLE /*$wgDBprefix*/user (
+ user_id int(5) unsigned NOT NULL auto_increment,
+
+ -- Usernames must be unique, must not be in the form of
+ -- an IP address. _Shouldn't_ allow slashes or case
+ -- conflicts. Spaces are allowed, and are _not_ converted
+ -- to underscores like titles. See the User::newFromName() for
+ -- the specific tests that usernames have to pass.
+ user_name varchar(255) binary NOT NULL default '',
+
+ -- Optional 'real name' to be displayed in credit listings
+ user_real_name varchar(255) binary NOT NULL default '',
+
+ -- Password hashes, normally hashed like so:
+ -- MD5(CONCAT(user_id,'-',MD5(plaintext_password))), see
+ -- wfEncryptPassword() in GlobalFunctions.php
+ user_password tinyblob NOT NULL,
+
+ -- When using 'mail me a new password', a random
+ -- password is generated and the hash stored here.
+ -- The previous password is left in place until
+ -- someone actually logs in with the new password,
+ -- at which point the hash is moved to user_password
+ -- and the old password is invalidated.
+ user_newpassword tinyblob NOT NULL,
+
+ -- Timestamp of the last time when a new password was
+ -- sent, for throttling purposes
+ user_newpass_time char(14) binary,
+
+ -- Note: email should be restricted, not public info.
+ -- Same with passwords.
+ user_email tinytext NOT NULL,
+
+ -- Newline-separated list of name=value defining the user
+ -- preferences
+ user_options blob NOT NULL,
+
+ -- This is a timestamp which is updated when a user
+ -- logs in, logs out, changes preferences, or performs
+ -- some other action requiring HTML cache invalidation
+ -- to ensure that the UI is updated.
+ user_touched char(14) binary NOT NULL default '',
+
+ -- A pseudorandomly generated value that is stored in
+ -- a cookie when the "remember password" feature is
+ -- used (previously, a hash of the password was used, but
+ -- this was vulnerable to cookie-stealing attacks)
+ user_token char(32) binary NOT NULL default '',
+
+ -- Initially NULL; when a user's e-mail address has been
+ -- validated by returning with a mailed token, this is
+ -- set to the current timestamp.
+ user_email_authenticated char(14) binary,
+
+ -- Randomly generated token created when the e-mail address
+ -- is set and a confirmation test mail sent.
+ user_email_token char(32) binary,
+
+ -- Expiration date for the user_email_token
+ user_email_token_expires char(14) binary,
+
+ -- Timestamp of account registration.
+ -- Accounts predating this schema addition may contain NULL.
+ user_registration char(14) binary,
+
+ -- Count of edits and edit-like actions.
+ --
+ -- *NOT* intended to be an accurate copy of COUNT(*) WHERE rev_user=user_id
+ -- May contain NULL for old accounts if batch-update scripts haven't been
+ -- run, as well as listing deleted edits and other myriad ways it could be
+ -- out of sync.
+ --
+ -- Meant primarily for heuristic checks to give an impression of whether
+ -- the account has been used much.
+ --
+ user_editcount int,
+
+ PRIMARY KEY user_id (user_id),
+ UNIQUE INDEX user_name (user_name),
+ INDEX (user_email_token)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- User permissions have been broken out to a separate table;
+-- this allows sites with a shared user table to have different
+-- permissions assigned to a user in each project.
+--
+-- This table replaces the old user_rights field which used a
+-- comma-separated blob.
+--
+CREATE TABLE /*$wgDBprefix*/user_groups (
+ -- Key to user_id
+ ug_user int(5) unsigned NOT NULL default '0',
+
+ -- Group names are short symbolic string keys.
+ -- The set of group names is open-ended, though in practice
+ -- only some predefined ones are likely to be used.
+ --
+ -- At runtime $wgGroupPermissions will associate group keys
+ -- with particular permissions. A user will have the combined
+ -- permissions of any group they're explicitly in, plus
+ -- the implicit '*' and 'user' groups.
+ ug_group char(16) NOT NULL default '',
+
+ PRIMARY KEY (ug_user,ug_group),
+ KEY (ug_group)
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+-- Stores notifications of user talk page changes, for the display
+-- of the "you have new messages" box
+CREATE TABLE /*$wgDBprefix*/user_newtalk (
+ -- Key to user.user_id
+ user_id int(5) NOT NULL default '0',
+ -- If the user is an anonymous user hir IP address is stored here
+ -- since the user_id of 0 is ambiguous
+ user_ip varchar(40) NOT NULL default '',
+ INDEX user_id (user_id),
+ INDEX user_ip (user_ip)
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Core of the wiki: each page has an entry here which identifies
+-- it by title and contains some essential metadata.
+--
+CREATE TABLE /*$wgDBprefix*/page (
+ -- Unique identifier number. The page_id will be preserved across
+ -- edits and rename operations, but not deletions and recreations.
+ page_id int(8) unsigned NOT NULL auto_increment,
+
+ -- A page name is broken into a namespace and a title.
+ -- The namespace keys are UI-language-independent constants,
+ -- defined in includes/Defines.php
+ page_namespace int NOT NULL,
+
+ -- The rest of the title, as text.
+ -- Spaces are transformed into underscores in title storage.
+ page_title varchar(255) binary NOT NULL,
+
+ -- Comma-separated set of permission keys indicating who
+ -- can move or edit the page.
+ page_restrictions tinyblob NOT NULL,
+
+ -- Number of times this page has been viewed.
+ page_counter bigint(20) unsigned NOT NULL default '0',
+
+ -- 1 indicates the article is a redirect.
+ page_is_redirect tinyint(1) unsigned NOT NULL default '0',
+
+ -- 1 indicates this is a new entry, with only one edit.
+ -- Not all pages with one edit are new pages.
+ page_is_new tinyint(1) unsigned NOT NULL default '0',
+
+ -- Random value between 0 and 1, used for Special:Randompage
+ page_random real unsigned NOT NULL,
+
+ -- This timestamp is updated whenever the page changes in
+ -- a way requiring it to be re-rendered, invalidating caches.
+ -- Aside from editing this includes permission changes,
+ -- creation or deletion of linked pages, and alteration
+ -- of contained templates.
+ page_touched char(14) binary NOT NULL default '',
+
+ -- Handy key to revision.rev_id of the current revision.
+ -- This may be 0 during page creation, but that shouldn't
+ -- happen outside of a transaction... hopefully.
+ page_latest int(8) unsigned NOT NULL,
+
+ -- Uncompressed length in bytes of the page's current source text.
+ page_len int(8) unsigned NOT NULL,
+
+ PRIMARY KEY page_id (page_id),
+ UNIQUE INDEX name_title (page_namespace,page_title),
+
+ -- Special-purpose indexes
+ INDEX (page_random),
+ INDEX (page_len)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Every edit of a page creates also a revision row.
+-- This stores metadata about the revision, and a reference
+-- to the text storage backend.
+--
+CREATE TABLE /*$wgDBprefix*/revision (
+ rev_id int(8) unsigned NOT NULL auto_increment,
+
+ -- Key to page_id. This should _never_ be invalid.
+ rev_page int(8) unsigned NOT NULL,
+
+ -- Key to text.old_id, where the actual bulk text is stored.
+ -- It's possible for multiple revisions to use the same text,
+ -- for instance revisions where only metadata is altered
+ -- or a rollback to a previous version.
+ rev_text_id int(8) unsigned NOT NULL,
+
+ -- Text comment summarizing the change.
+ -- This text is shown in the history and other changes lists,
+ -- rendered in a subset of wiki markup by Linker::formatComment()
+ rev_comment tinyblob NOT NULL,
+
+ -- Key to user.user_id of the user who made this edit.
+ -- Stores 0 for anonymous edits and for some mass imports.
+ rev_user int(5) unsigned NOT NULL default '0',
+
+ -- Text username or IP address of the editor.
+ rev_user_text varchar(255) binary NOT NULL default '',
+
+ -- Timestamp
+ rev_timestamp char(14) binary NOT NULL default '',
+
+ -- Records whether the user marked the 'minor edit' checkbox.
+ -- Many automated edits are marked as minor.
+ rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
+
+ -- Not yet used; reserved for future changes to the deletion system.
+ rev_deleted tinyint(1) 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)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Holds text of individual page revisions.
+--
+-- Field names are a holdover from the 'old' revisions table in
+-- MediaWiki 1.4 and earlier: an upgrade will transform that
+-- table into the 'text' table to minimize unnecessary churning
+-- and downtime. If upgrading, the other fields will be left unused.
+--
+CREATE TABLE /*$wgDBprefix*/text (
+ -- Unique text storage key number.
+ -- Note that the 'oldid' parameter used in URLs does *not*
+ -- refer to this number anymore, but to rev_id.
+ --
+ -- revision.rev_text_id is a key to this column
+ old_id int(8) unsigned NOT NULL auto_increment,
+
+ -- Depending on the contents of the old_flags field, the text
+ -- may be convenient plain text, or it may be funkily encoded.
+ old_text mediumblob NOT NULL,
+
+ -- Comma-separated list of flags:
+ -- gzip: text is compressed with PHP's gzdeflate() function.
+ -- utf8: text was stored as UTF-8.
+ -- If $wgLegacyEncoding option is on, rows *without* this flag
+ -- will be converted to UTF-8 transparently at load time.
+ -- object: text field contained a serialized PHP object.
+ -- The object either contains multiple versions compressed
+ -- together to achieve a better compression ratio, or it refers
+ -- to another row where the text can be found.
+ old_flags tinyblob NOT NULL,
+
+ PRIMARY KEY old_id (old_id)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Holding area for deleted articles, which may be viewed
+-- or restored by admins through the Special:Undelete interface.
+-- The fields generally correspond to the page, revision, and text
+-- fields, with several caveats.
+--
+CREATE TABLE /*$wgDBprefix*/archive (
+ ar_namespace int NOT NULL default '0',
+ ar_title varchar(255) binary NOT NULL default '',
+
+ -- Newly deleted pages will not store text in this table,
+ -- but will reference the separately existing text rows.
+ -- This field is retained for backwards compatibility,
+ -- so old archived pages will remain accessible after
+ -- upgrading from 1.4 to 1.5.
+ -- Text may be gzipped or otherwise funky.
+ ar_text mediumblob NOT NULL,
+
+ -- Basic revision stuff...
+ ar_comment tinyblob NOT NULL,
+ ar_user int(5) unsigned NOT NULL default '0',
+ ar_user_text varchar(255) binary NOT NULL,
+ ar_timestamp char(14) binary NOT NULL default '',
+ ar_minor_edit tinyint(1) NOT NULL default '0',
+
+ -- See ar_text note.
+ ar_flags tinyblob NOT NULL,
+
+ -- When revisions are deleted, their unique rev_id is stored
+ -- here so it can be retained after undeletion. This is necessary
+ -- to retain permalinks to given revisions after accidental delete
+ -- cycles or messy operations like history merges.
+ --
+ -- Old entries from 1.4 will be NULL here, and a new rev_id will
+ -- be created on undeletion for those revisions.
+ ar_rev_id int(8) unsigned,
+
+ -- For newly deleted revisions, this is the text.old_id key to the
+ -- actual stored text. To avoid breaking the block-compression scheme
+ -- and otherwise making storage changes harder, the actual text is
+ -- *not* deleted from the text table, merely hidden by removal of the
+ -- page and revision entries.
+ --
+ -- Old entries deleted under 1.2-1.4 will have NULL here, and their
+ -- ar_text and ar_flags fields will be used to create a new text
+ -- row upon undeletion.
+ ar_text_id int(8) unsigned,
+
+ KEY name_title_timestamp (ar_namespace,ar_title,ar_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Track page-to-page hyperlinks within the wiki.
+--
+CREATE TABLE /*$wgDBprefix*/pagelinks (
+ -- Key to the page_id of the page containing the link.
+ pl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ pl_namespace int NOT NULL default '0',
+ pl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY pl_from (pl_from,pl_namespace,pl_title),
+ KEY (pl_namespace,pl_title,pl_from)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Track template inclusions.
+--
+CREATE TABLE /*$wgDBprefix*/templatelinks (
+ -- Key to the page_id of the page containing the link.
+ tl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ tl_namespace int NOT NULL default '0',
+ tl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY tl_from (tl_from,tl_namespace,tl_title),
+ KEY (tl_namespace,tl_title,tl_from)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Track links to images *used inline*
+-- We don't distinguish live from broken links here, so
+-- they do not need to be changed on upload/removal.
+--
+CREATE TABLE /*$wgDBprefix*/imagelinks (
+ -- Key to page_id of the page containing the image / media link.
+ il_from int(8) unsigned NOT NULL default '0',
+
+ -- Filename of target image.
+ -- This is also the page_title of the file's description page;
+ -- all such pages are in namespace 6 (NS_IMAGE).
+ il_to varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY il_from (il_from,il_to),
+ KEY (il_to,il_from)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Track category inclusions *used inline*
+-- This tracks a single level of category membership
+-- (folksonomic tagging, really).
+--
+CREATE TABLE /*$wgDBprefix*/categorylinks (
+ -- Key to page_id of the page defined as a category member.
+ cl_from int(8) unsigned NOT NULL default '0',
+
+ -- Name of the category.
+ -- This is also the page_title of the category's description page;
+ -- all such pages are in namespace 14 (NS_CATEGORY).
+ cl_to varchar(255) binary NOT NULL default '',
+
+ -- The title of the linking page, or an optional override
+ -- to determine sort order. Sorting is by binary order, which
+ -- isn't always ideal, but collations seem to be an exciting
+ -- and dangerous new world in MySQL...
+ --
+ -- For MySQL 4.1+ with charset set to utf8, the sort key *index*
+ -- needs cut to be smaller than 1024 bytes (at 3 bytes per char).
+ -- To sort properly on the shorter key, this field needs to be
+ -- the same shortness.
+ cl_sortkey varchar(86) binary NOT NULL default '',
+
+ -- This isn't really used at present. Provided for an optional
+ -- sorting method by approximate addition time.
+ cl_timestamp timestamp NOT NULL,
+
+ UNIQUE KEY cl_from (cl_from,cl_to),
+
+ -- We always sort within a given category...
+ KEY cl_sortkey (cl_to,cl_sortkey),
+
+ -- Not really used?
+ KEY cl_timestamp (cl_to,cl_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Track links to external URLs
+--
+CREATE TABLE /*$wgDBprefix*/externallinks (
+ -- page_id of the referring page
+ el_from int(8) unsigned NOT NULL default '0',
+
+ -- The URL
+ el_to blob NOT NULL,
+
+ -- In the case of HTTP URLs, this is the URL with any username or password
+ -- removed, and with the labels in the hostname reversed and converted to
+ -- lower case. An extra dot is added to allow for matching of either
+ -- example.com or *.example.com in a single scan.
+ -- Example:
+ -- http://user:password@sub.example.com/page.html
+ -- becomes
+ -- http://com.example.sub./page.html
+ -- which allows for fast searching for all pages under example.com with the
+ -- clause:
+ -- WHERE el_index LIKE 'http://com.example.%'
+ el_index blob NOT NULL,
+
+ KEY (el_from, el_to(40)),
+ KEY (el_to(60), el_from),
+ KEY (el_index(60))
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Track interlanguage links
+--
+CREATE TABLE /*$wgDBprefix*/langlinks (
+ -- page_id of the referring page
+ ll_from int(8) unsigned NOT NULL default '0',
+
+ -- Language code of the target
+ ll_lang varchar(10) binary NOT NULL default '',
+
+ -- Title of the target, including namespace
+ ll_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY (ll_from, ll_lang),
+ KEY (ll_lang, ll_title)
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Contains a single row with some aggregate info
+-- on the state of the site.
+--
+CREATE TABLE /*$wgDBprefix*/site_stats (
+ -- The single row should contain 1 here.
+ ss_row_id int(8) unsigned NOT NULL,
+
+ -- Total number of page views, if hit counters are enabled.
+ ss_total_views bigint(20) unsigned default '0',
+
+ -- Total number of edits performed.
+ ss_total_edits bigint(20) unsigned default '0',
+
+ -- An approximate count of pages matching the following criteria:
+ -- * in namespace 0
+ -- * not a redirect
+ -- * contains the text '[['
+ -- See Article::isCountable() in includes/Article.php
+ ss_good_articles bigint(20) unsigned default '0',
+
+ -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster
+ ss_total_pages bigint(20) default '-1',
+
+ -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
+ ss_users bigint(20) default '-1',
+
+ -- Deprecated, no longer updated as of 1.5
+ ss_admins int(10) default '-1',
+
+ -- Number of images, equivalent to SELECT COUNT(*) FROM image
+ ss_images int(10) default '0',
+
+ UNIQUE KEY ss_row_id (ss_row_id)
+
+) ENGINE=InnoDB;
+
+--
+-- Stores an ID for every time any article is visited;
+-- depending on $wgHitcounterUpdateFreq, it is
+-- periodically cleared and the page_counter column
+-- in the page table updated for the all articles
+-- that have been visited.)
+--
+CREATE TABLE /*$wgDBprefix*/hitcounter (
+ hc_id int unsigned NOT NULL
+) ENGINE=HEAP MAX_ROWS=25000;
+
+
+--
+-- The internet is full of jerks, alas. Sometimes it's handy
+-- to block a vandal or troll account.
+--
+CREATE TABLE /*$wgDBprefix*/ipblocks (
+ -- Primary key, introduced for privacy.
+ ipb_id int(8) NOT NULL auto_increment,
+
+ -- Blocked IP address in dotted-quad form or user name.
+ ipb_address tinyblob NOT NULL,
+
+ -- Blocked user ID or 0 for IP blocks.
+ ipb_user int(8) unsigned NOT NULL default '0',
+
+ -- User ID who made the block.
+ ipb_by int(8) unsigned NOT NULL default '0',
+
+ -- Text comment made by blocker.
+ ipb_reason tinyblob NOT NULL,
+
+ -- Creation (or refresh) date in standard YMDHMS form.
+ -- IP blocks expire automatically.
+ ipb_timestamp char(14) binary NOT NULL default '',
+
+ -- Indicates that the IP address was banned because a banned
+ -- user accessed a page through it. If this is 1, ipb_address
+ -- will be hidden, and the block identified by block ID number.
+ ipb_auto bool NOT NULL default '0',
+
+ -- If set to 1, block applies only to logged-out users
+ ipb_anon_only bool NOT NULL default 0,
+
+ -- Block prevents account creation from matching IP addresses
+ ipb_create_account bool NOT NULL default 1,
+
+ -- Block triggers autoblocks
+ ipb_enable_autoblock bool NOT NULL default '1',
+
+ -- Time at which the block will expire.
+ ipb_expiry char(14) binary NOT NULL default '',
+
+ -- Start and end of an address range, in hexadecimal
+ -- Size chosen to allow IPv6
+ ipb_range_start varchar(32) NOT NULL default '',
+ ipb_range_end varchar(32) NOT NULL default '',
+
+ PRIMARY KEY ipb_id (ipb_id),
+
+ -- Unique index to support "user already blocked" messages
+ -- Any new options which prevent collisions should be included
+ UNIQUE INDEX ipb_address (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only),
+
+ INDEX ipb_user (ipb_user),
+ INDEX ipb_range (ipb_range_start(8), ipb_range_end(8)),
+ INDEX ipb_timestamp (ipb_timestamp),
+ INDEX ipb_expiry (ipb_expiry)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Uploaded images and other files.
+--
+CREATE TABLE /*$wgDBprefix*/image (
+ -- Filename.
+ -- This is also the title of the associated description page,
+ -- which will be in namespace 6 (NS_IMAGE).
+ img_name varchar(255) binary NOT NULL default '',
+
+ -- File size in bytes.
+ img_size int(8) unsigned NOT NULL default '0',
+
+ -- For images, size in pixels.
+ img_width int(5) NOT NULL default '0',
+ img_height int(5) NOT NULL default '0',
+
+ -- Extracted EXIF metadata stored as a serialized PHP array.
+ img_metadata mediumblob NOT NULL,
+
+ -- For images, bits per pixel if known.
+ img_bits int(3) NOT NULL default '0',
+
+ -- Media type as defined by the MEDIATYPE_xxx constants
+ img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+
+ -- major part of a MIME media type as defined by IANA
+ -- see http://www.iana.org/assignments/media-types/
+ img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown",
+
+ -- minor part of a MIME media type as defined by IANA
+ -- the minor parts are not required to adher to any standard
+ -- but should be consistent throughout the database
+ -- see http://www.iana.org/assignments/media-types/
+ img_minor_mime varchar(32) NOT NULL default "unknown",
+
+ -- Description field as entered by the uploader.
+ -- This is displayed in image upload history and logs.
+ img_description tinyblob NOT NULL,
+
+ -- user_id and user_name of uploader.
+ img_user int(5) unsigned NOT NULL default '0',
+ img_user_text varchar(255) binary NOT NULL default '',
+
+ -- Time of the upload.
+ img_timestamp char(14) binary NOT NULL default '',
+
+ PRIMARY KEY img_name (img_name),
+
+ -- Used by Special:Imagelist for sort-by-size
+ INDEX img_size (img_size),
+
+ -- Used by Special:Newimages and Special:Imagelist
+ INDEX img_timestamp (img_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Previous revisions of uploaded files.
+-- Awkwardly, image rows have to be moved into
+-- this table at re-upload time.
+--
+CREATE TABLE /*$wgDBprefix*/oldimage (
+ -- Base filename: key to image.img_name
+ oi_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of the archived file.
+ -- This is generally a timestamp and '!' prepended to the base name.
+ oi_archive_name varchar(255) binary NOT NULL default '',
+
+ -- Other fields as in image...
+ oi_size int(8) unsigned NOT NULL default 0,
+ oi_width int(5) NOT NULL default 0,
+ oi_height int(5) NOT NULL default 0,
+ oi_bits int(3) NOT NULL default 0,
+ oi_description tinyblob NOT NULL,
+ oi_user int(5) unsigned NOT NULL default '0',
+ oi_user_text varchar(255) binary NOT NULL default '',
+ oi_timestamp char(14) binary NOT NULL default '',
+
+ INDEX oi_name (oi_name(10))
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Record of deleted file data
+--
+CREATE TABLE /*$wgDBprefix*/filearchive (
+ -- Unique row id
+ fa_id int NOT NULL auto_increment,
+
+ -- Original base filename; key to image.img_name, page.page_title, etc
+ fa_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of archived file, if an old revision
+ fa_archive_name varchar(255) binary default '',
+
+ -- Which storage bin (directory tree or object store) the file data
+ -- is stored in. Should be 'deleted' for files that have been deleted;
+ -- any other bin is not yet in use.
+ fa_storage_group varchar(16),
+
+ -- SHA-1 of the file contents plus extension, used as a key for storage.
+ -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg
+ --
+ -- If NULL, the file was missing at deletion time or has been purged
+ -- from the archival storage.
+ fa_storage_key varchar(64) binary default '',
+
+ -- Deletion information, if this file is deleted.
+ fa_deleted_user int,
+ fa_deleted_timestamp char(14) binary default '',
+ fa_deleted_reason text,
+
+ -- Duped fields from image
+ fa_size int(8) unsigned default '0',
+ fa_width int(5) default '0',
+ fa_height int(5) default '0',
+ fa_metadata mediumblob,
+ fa_bits int(3) default '0',
+ fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+ fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") default "unknown",
+ fa_minor_mime varchar(32) default "unknown",
+ fa_description tinyblob,
+ fa_user int(5) unsigned default '0',
+ fa_user_text varchar(255) binary default '',
+ fa_timestamp char(14) binary default '',
+
+ PRIMARY KEY (fa_id),
+ INDEX (fa_name, fa_timestamp), -- pick out by image name
+ INDEX (fa_storage_group, fa_storage_key), -- pick out dupe files
+ INDEX (fa_deleted_timestamp), -- sort by deletion time
+ INDEX (fa_deleted_user) -- sort by deleter
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Primarily a summary table for Special:Recentchanges,
+-- this table contains some additional info on edits from
+-- the last few days, see Article::editUpdates()
+--
+CREATE TABLE /*$wgDBprefix*/recentchanges (
+ rc_id int(8) NOT NULL auto_increment,
+ rc_timestamp varchar(14) binary NOT NULL default '',
+ rc_cur_time varchar(14) binary NOT NULL default '',
+
+ -- As in revision
+ rc_user int(10) unsigned NOT NULL default '0',
+ rc_user_text varchar(255) binary NOT NULL default '',
+
+ -- When pages are renamed, their RC entries do _not_ change.
+ rc_namespace int NOT NULL default '0',
+ rc_title varchar(255) binary NOT NULL default '',
+
+ -- as in revision...
+ rc_comment varchar(255) binary NOT NULL default '',
+ rc_minor tinyint(3) unsigned NOT NULL default '0',
+
+ -- Edits by user accounts with the 'bot' rights key are
+ -- marked with a 1 here, and will be hidden from the
+ -- default view.
+ rc_bot tinyint(3) unsigned NOT NULL default '0',
+
+ rc_new tinyint(3) unsigned NOT NULL default '0',
+
+ -- Key to page_id (was cur_id prior to 1.5).
+ -- This will keep links working after moves while
+ -- retaining the at-the-time name in the changes list.
+ rc_cur_id int(10) unsigned NOT NULL default '0',
+
+ -- rev_id of the given revision
+ rc_this_oldid int(10) unsigned NOT NULL default '0',
+
+ -- rev_id of the prior revision, for generating diff links.
+ rc_last_oldid int(10) unsigned NOT NULL default '0',
+
+ -- These may no longer be used, with the new move log.
+ rc_type tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_title varchar(255) binary NOT NULL default '',
+
+ -- If the Recent Changes Patrol option is enabled,
+ -- users may mark edits as having been reviewed to
+ -- remove a warning flag on the RC list.
+ -- A value of 1 indicates the page has been reviewed.
+ rc_patrolled tinyint(3) unsigned NOT NULL default '0',
+
+ -- Recorded IP address the edit was made from, if the
+ -- $wgPutIPinRC option is enabled.
+ rc_ip char(15) NOT NULL default '',
+
+ -- Text length in characters before
+ -- and after the edit
+ rc_old_len int(10) default '0',
+ rc_new_len int(10) default '0',
+
+ PRIMARY KEY rc_id (rc_id),
+ INDEX rc_timestamp (rc_timestamp),
+ INDEX rc_namespace_title (rc_namespace, rc_title),
+ INDEX rc_cur_id (rc_cur_id),
+ INDEX new_name_timestamp (rc_new,rc_namespace,rc_timestamp),
+ INDEX rc_ip (rc_ip),
+ INDEX rc_ns_usertext ( rc_namespace, rc_user_text )
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+CREATE TABLE /*$wgDBprefix*/watchlist (
+ -- Key to user.user_id
+ wl_user int(5) unsigned NOT NULL,
+
+ -- Key to page_namespace/page_title
+ -- Note that users may watch pages which do not exist yet,
+ -- or existed in the past but have been deleted.
+ wl_namespace int NOT NULL default '0',
+ wl_title varchar(255) binary NOT NULL default '',
+
+ -- Timestamp when user was last sent a notification e-mail;
+ -- cleared when the user visits the page.
+ wl_notificationtimestamp varchar(14) binary,
+
+ UNIQUE KEY (wl_user, wl_namespace, wl_title),
+ KEY namespace_title (wl_namespace,wl_title)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+
+--
+-- Used by the math module to keep track
+-- of previously-rendered items.
+--
+CREATE TABLE /*$wgDBprefix*/math (
+ -- Binary MD5 hash of the latex fragment, used as an identifier key.
+ math_inputhash varbinary(16) NOT NULL,
+
+ -- Not sure what this is, exactly...
+ math_outputhash varbinary(16) NOT NULL,
+
+ -- texvc reports how well it thinks the HTML conversion worked;
+ -- if it's a low level the PNG rendering may be preferred.
+ math_html_conservativeness tinyint(1) NOT NULL,
+
+ -- HTML output from texvc, if any
+ math_html text,
+
+ -- MathML output from texvc, if any
+ math_mathml text,
+
+ UNIQUE KEY math_inputhash (math_inputhash)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- When using the default MySQL search backend, page titles
+-- and text are munged to strip markup, do Unicode case folding,
+-- and prepare the result for MySQL's fulltext index.
+--
+-- This table must be MyISAM; InnoDB does not support the needed
+-- fulltext index.
+--
+CREATE TABLE /*$wgDBprefix*/searchindex (
+ -- Key to page_id
+ si_page int(8) unsigned NOT NULL,
+
+ -- Munged version of title
+ si_title varchar(255) NOT NULL default '',
+
+ -- Munged version of body text
+ si_text mediumtext NOT NULL,
+
+ UNIQUE KEY (si_page),
+ FULLTEXT si_title (si_title),
+ FULLTEXT si_text (si_text)
+
+) ENGINE=MyISAM, DEFAULT CHARSET=utf8;
+
+--
+-- Recognized interwiki link prefixes
+--
+CREATE TABLE /*$wgDBprefix*/interwiki (
+ -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
+ iw_prefix char(32) NOT NULL,
+
+ -- The URL of the wiki, with "$1" as a placeholder for an article name.
+ -- Any spaces in the name will be transformed to underscores before
+ -- insertion.
+ iw_url char(127) NOT NULL,
+
+ -- A boolean value indicating whether the wiki is in this project
+ -- (used, for example, to detect redirect loops)
+ iw_local bool NOT NULL,
+
+ -- Boolean value indicating whether interwiki transclusions are allowed.
+ iw_trans tinyint(1) NOT NULL default 0,
+
+ UNIQUE KEY iw_prefix (iw_prefix)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Used for caching expensive grouped queries
+--
+CREATE TABLE /*$wgDBprefix*/querycache (
+ -- A key name, generally the base name of of the special page.
+ qc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qc_namespace int NOT NULL default '0',
+ qc_title char(255) binary NOT NULL default '',
+
+ KEY (qc_type,qc_value)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- For a few generic cache operations if not using Memcached
+--
+CREATE TABLE /*$wgDBprefix*/objectcache (
+ keyname char(255) binary NOT NULL default '',
+ value mediumblob,
+ exptime datetime,
+ UNIQUE KEY (keyname),
+ KEY (exptime)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+--
+-- Cache of interwiki transclusion
+--
+CREATE TABLE /*$wgDBprefix*/transcache (
+ tc_url varchar(255) NOT NULL,
+ tc_contents text,
+ tc_time int NOT NULL,
+ UNIQUE INDEX tc_url_idx (tc_url)
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+CREATE TABLE /*$wgDBprefix*/logging (
+ -- Symbolic keys for the general log type and the action type
+ -- within the log. The output format will be controlled by the
+ -- action field, but only the type controls categorization.
+ log_type char(10) NOT NULL default '',
+ log_action char(10) NOT NULL default '',
+
+ -- Timestamp. Duh.
+ log_timestamp char(14) NOT NULL default '19700101000000',
+
+ -- The user who performed this action; key to user_id
+ log_user int unsigned NOT NULL default 0,
+
+ -- Key to the page affected. Where a user is the target,
+ -- this will point to the user page.
+ log_namespace int NOT NULL default 0,
+ log_title varchar(255) binary NOT NULL default '',
+
+ -- Freeform text. Interpreted as edit history comments.
+ log_comment varchar(255) NOT NULL default '',
+
+ -- LF separated list of miscellaneous parameters
+ log_params blob NOT NULL,
+
+ KEY type_time (log_type, log_timestamp),
+ KEY user_time (log_user, log_timestamp),
+ KEY page_time (log_namespace, log_title, log_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+CREATE TABLE /*$wgDBprefix*/trackbacks (
+ tb_id int auto_increment,
+ tb_page int REFERENCES page(page_id) ON DELETE CASCADE,
+ tb_title varchar(255) NOT NULL,
+ tb_url varchar(255) NOT NULL,
+ tb_ex text,
+ tb_name varchar(255),
+
+ PRIMARY KEY (tb_id),
+ INDEX (tb_page)
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+-- Jobs performed by parallel apache threads or a command-line daemon
+CREATE TABLE /*$wgDBprefix*/job (
+ job_id int(9) unsigned NOT NULL auto_increment,
+
+ -- Command name, currently only refreshLinks is defined
+ job_cmd varchar(255) NOT NULL default '',
+
+ -- Namespace and title to act on
+ -- Should be 0 and '' if the command does not operate on a title
+ job_namespace int NOT NULL,
+ job_title varchar(255) binary NOT NULL,
+
+ -- Any other parameters to the command
+ -- Presently unused, format undefined
+ job_params blob NOT NULL,
+
+ PRIMARY KEY job_id (job_id),
+ KEY (job_cmd, job_namespace, job_title)
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+-- Details of updates to cached special pages
+CREATE TABLE /*$wgDBprefix*/querycache_info (
+
+ -- Special page name
+ -- Corresponds to a qc_type value
+ qci_type varchar(32) NOT NULL default '',
+
+ -- Timestamp of last update
+ qci_timestamp char(14) NOT NULL default '19700101000000',
+
+ UNIQUE KEY ( qci_type )
+
+) ENGINE=InnoDB;
+
+-- For each redirect, this table contains exactly one row defining its target
+CREATE TABLE /*$wgDBprefix*/redirect (
+ -- Key to the page_id of the redirect page
+ rd_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ rd_namespace int NOT NULL default '0',
+ rd_title varchar(255) binary NOT NULL default '',
+
+ PRIMARY KEY rd_from (rd_from),
+ KEY rd_ns_title (rd_namespace,rd_title,rd_from)
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+-- Used for caching expensive grouped queries that need two links (for example double-redirects)
+
+CREATE TABLE /*$wgDBprefix*/querycachetwo (
+ -- A key name, generally the base name of of the special page.
+ qcc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qcc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qcc_namespace int NOT NULL default '0',
+ qcc_title char(255) binary NOT NULL default '',
+
+ -- Target namespace+title2
+ qcc_namespacetwo int NOT NULL default '0',
+ qcc_titletwo char(255) binary NOT NULL default '',
+
+ KEY qcc_type (qcc_type,qcc_value),
+ KEY qcc_title (qcc_type,qcc_namespace,qcc_title),
+ KEY qcc_titletwo (qcc_type,qcc_namespacetwo,qcc_titletwo)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=binary;
diff --git a/maintenance/mysql5/tables.sql b/maintenance/mysql5/tables.sql
new file mode 100644
index 000000000000..356f3bbfff8f
--- /dev/null
+++ b/maintenance/mysql5/tables.sql
@@ -0,0 +1,1086 @@
+-- Experimental table definitions for MySQL 4.1 and 5.0 with
+-- explicit character set support. Not fully tested, may have
+-- surprises!
+--
+-- TODO: Test various fields
+-- TODO: Anything else need to be moved to VARBINARY and BLOB?
+-- TODO: UCS-2 better than UTF-8?
+-- TODO: Find out how to get 4-byte UTF-8 chars into MySQL...
+-- An alternate UCS-2 that does UTF-16 conversion would work.
+-- TODO: Work on collation usage
+
+-- ------------------------------------------------------------
+
+-- SQL to create the initial tables for the MediaWiki database.
+-- This is read and executed by the install script; you should
+-- not have to run it by itself unless doing a manual install.
+
+--
+-- General notes:
+--
+-- If possible, create tables as InnoDB to benefit from the
+-- superior resiliency against crashes and ability to read
+-- during writes (and write during reads!)
+--
+-- Only the 'searchindex' table requires MyISAM due to the
+-- requirement for fulltext index support, which is missing
+-- from InnoDB.
+--
+--
+-- The MySQL table backend for MediaWiki currently uses
+-- 14-character CHAR or VARCHAR fields to store timestamps.
+-- The format is YYYYMMDDHHMMSS, which is derived from the
+-- text format of MySQL's TIMESTAMP fields.
+--
+-- Historically TIMESTAMP fields were used, but abandoned
+-- in early 2002 after a lot of trouble with the fields
+-- auto-updating.
+--
+-- The Postgres backend uses DATETIME fields for timestamps,
+-- and we will migrate the MySQL definitions at some point as
+-- well.
+--
+--
+-- The /*$wgDBprefix*/ comments in this and other files are
+-- replaced with the defined table prefix by the installer
+-- and updater scripts. If you are installing or running
+-- updates manually, you will need to manually insert the
+-- table prefix if any when running these scripts.
+--
+
+
+--
+-- The user table contains basic account information,
+-- authentication keys, etc.
+--
+-- Some multi-wiki sites may share a single central user table
+-- between separate wikis using the $wgSharedDB setting.
+--
+-- Note that when a external authentication plugin is used,
+-- user table entries still need to be created to store
+-- preferences and to key tracking information in the other
+-- tables.
+--
+CREATE TABLE /*$wgDBprefix*/user (
+ user_id int(5) unsigned NOT NULL auto_increment,
+
+ -- Usernames must be unique, must not be in the form of
+ -- an IP address. _Shouldn't_ allow slashes or case
+ -- conflicts. Spaces are allowed, and are _not_ converted
+ -- to underscores like titles. See the User::newFromName() for
+ -- the specific tests that usernames have to pass.
+ user_name varchar(255) binary NOT NULL default '',
+
+ -- Optional 'real name' to be displayed in credit listings
+ user_real_name varchar(255) binary NOT NULL default '',
+
+ -- Password hashes, normally hashed like so:
+ -- MD5(CONCAT(user_id,'-',MD5(plaintext_password))), see
+ -- wfEncryptPassword() in GlobalFunctions.php
+ user_password tinyblob NOT NULL,
+
+ -- When using 'mail me a new password', a random
+ -- password is generated and the hash stored here.
+ -- The previous password is left in place until
+ -- someone actually logs in with the new password,
+ -- at which point the hash is moved to user_password
+ -- and the old password is invalidated.
+ user_newpassword tinyblob NOT NULL,
+
+ -- Timestamp of the last time when a new password was
+ -- sent, for throttling purposes
+ user_newpass_time char(14) binary,
+
+ -- Note: email should be restricted, not public info.
+ -- Same with passwords.
+ user_email tinytext NOT NULL,
+
+ -- Newline-separated list of name=value defining the user
+ -- preferences
+ user_options blob NOT NULL,
+
+ -- This is a timestamp which is updated when a user
+ -- logs in, logs out, changes preferences, or performs
+ -- some other action requiring HTML cache invalidation
+ -- to ensure that the UI is updated.
+ user_touched char(14) binary NOT NULL default '',
+
+ -- A pseudorandomly generated value that is stored in
+ -- a cookie when the "remember password" feature is
+ -- used (previously, a hash of the password was used, but
+ -- this was vulnerable to cookie-stealing attacks)
+ user_token char(32) binary NOT NULL default '',
+
+ -- Initially NULL; when a user's e-mail address has been
+ -- validated by returning with a mailed token, this is
+ -- set to the current timestamp.
+ user_email_authenticated char(14) binary,
+
+ -- Randomly generated token created when the e-mail address
+ -- is set and a confirmation test mail sent.
+ user_email_token char(32) binary,
+
+ -- Expiration date for the user_email_token
+ user_email_token_expires char(14) binary,
+
+ -- Timestamp of account registration.
+ -- Accounts predating this schema addition may contain NULL.
+ user_registration char(14) binary,
+
+ -- Count of edits and edit-like actions.
+ --
+ -- *NOT* intended to be an accurate copy of COUNT(*) WHERE rev_user=user_id
+ -- May contain NULL for old accounts if batch-update scripts haven't been
+ -- run, as well as listing deleted edits and other myriad ways it could be
+ -- out of sync.
+ --
+ -- Meant primarily for heuristic checks to give an impression of whether
+ -- the account has been used much.
+ --
+ user_editcount int,
+
+ PRIMARY KEY user_id (user_id),
+ UNIQUE INDEX user_name (user_name),
+ INDEX (user_email_token)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- User permissions have been broken out to a separate table;
+-- this allows sites with a shared user table to have different
+-- permissions assigned to a user in each project.
+--
+-- This table replaces the old user_rights field which used a
+-- comma-separated blob.
+--
+CREATE TABLE /*$wgDBprefix*/user_groups (
+ -- Key to user_id
+ ug_user int(5) unsigned NOT NULL default '0',
+
+ -- Group names are short symbolic string keys.
+ -- The set of group names is open-ended, though in practice
+ -- only some predefined ones are likely to be used.
+ --
+ -- At runtime $wgGroupPermissions will associate group keys
+ -- with particular permissions. A user will have the combined
+ -- permissions of any group they're explicitly in, plus
+ -- the implicit '*' and 'user' groups.
+ ug_group char(16) NOT NULL default '',
+
+ PRIMARY KEY (ug_user,ug_group),
+ KEY (ug_group)
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+-- Stores notifications of user talk page changes, for the display
+-- of the "you have new messages" box
+CREATE TABLE /*$wgDBprefix*/user_newtalk (
+ -- Key to user.user_id
+ user_id int(5) NOT NULL default '0',
+ -- If the user is an anonymous user hir IP address is stored here
+ -- since the user_id of 0 is ambiguous
+ user_ip varchar(40) NOT NULL default '',
+ INDEX user_id (user_id),
+ INDEX user_ip (user_ip)
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Core of the wiki: each page has an entry here which identifies
+-- it by title and contains some essential metadata.
+--
+CREATE TABLE /*$wgDBprefix*/page (
+ -- Unique identifier number. The page_id will be preserved across
+ -- edits and rename operations, but not deletions and recreations.
+ page_id int(8) unsigned NOT NULL auto_increment,
+
+ -- A page name is broken into a namespace and a title.
+ -- The namespace keys are UI-language-independent constants,
+ -- defined in includes/Defines.php
+ page_namespace int NOT NULL,
+
+ -- The rest of the title, as text.
+ -- Spaces are transformed into underscores in title storage.
+ page_title varchar(255) binary NOT NULL,
+
+ -- Comma-separated set of permission keys indicating who
+ -- can move or edit the page.
+ page_restrictions tinyblob NOT NULL,
+
+ -- Number of times this page has been viewed.
+ page_counter bigint(20) unsigned NOT NULL default '0',
+
+ -- 1 indicates the article is a redirect.
+ page_is_redirect tinyint(1) unsigned NOT NULL default '0',
+
+ -- 1 indicates this is a new entry, with only one edit.
+ -- Not all pages with one edit are new pages.
+ page_is_new tinyint(1) unsigned NOT NULL default '0',
+
+ -- Random value between 0 and 1, used for Special:Randompage
+ page_random real unsigned NOT NULL,
+
+ -- This timestamp is updated whenever the page changes in
+ -- a way requiring it to be re-rendered, invalidating caches.
+ -- Aside from editing this includes permission changes,
+ -- creation or deletion of linked pages, and alteration
+ -- of contained templates.
+ page_touched char(14) binary NOT NULL default '',
+
+ -- Handy key to revision.rev_id of the current revision.
+ -- This may be 0 during page creation, but that shouldn't
+ -- happen outside of a transaction... hopefully.
+ page_latest int(8) unsigned NOT NULL,
+
+ -- Uncompressed length in bytes of the page's current source text.
+ page_len int(8) unsigned NOT NULL,
+
+ PRIMARY KEY page_id (page_id),
+ UNIQUE INDEX name_title (page_namespace,page_title),
+
+ -- Special-purpose indexes
+ INDEX (page_random),
+ INDEX (page_len)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Every edit of a page creates also a revision row.
+-- This stores metadata about the revision, and a reference
+-- to the text storage backend.
+--
+CREATE TABLE /*$wgDBprefix*/revision (
+ rev_id int(8) unsigned NOT NULL auto_increment,
+
+ -- Key to page_id. This should _never_ be invalid.
+ rev_page int(8) unsigned NOT NULL,
+
+ -- Key to text.old_id, where the actual bulk text is stored.
+ -- It's possible for multiple revisions to use the same text,
+ -- for instance revisions where only metadata is altered
+ -- or a rollback to a previous version.
+ rev_text_id int(8) unsigned NOT NULL,
+
+ -- Text comment summarizing the change.
+ -- This text is shown in the history and other changes lists,
+ -- rendered in a subset of wiki markup by Linker::formatComment()
+ rev_comment tinyblob NOT NULL,
+
+ -- Key to user.user_id of the user who made this edit.
+ -- Stores 0 for anonymous edits and for some mass imports.
+ rev_user int(5) unsigned NOT NULL default '0',
+
+ -- Text username or IP address of the editor.
+ rev_user_text varchar(255) binary NOT NULL default '',
+
+ -- Timestamp
+ rev_timestamp char(14) binary NOT NULL default '',
+
+ -- Records whether the user marked the 'minor edit' checkbox.
+ -- Many automated edits are marked as minor.
+ rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
+
+ -- Not yet used; reserved for future changes to the deletion system.
+ rev_deleted tinyint(1) 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)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Holds text of individual page revisions.
+--
+-- Field names are a holdover from the 'old' revisions table in
+-- MediaWiki 1.4 and earlier: an upgrade will transform that
+-- table into the 'text' table to minimize unnecessary churning
+-- and downtime. If upgrading, the other fields will be left unused.
+--
+CREATE TABLE /*$wgDBprefix*/text (
+ -- Unique text storage key number.
+ -- Note that the 'oldid' parameter used in URLs does *not*
+ -- refer to this number anymore, but to rev_id.
+ --
+ -- revision.rev_text_id is a key to this column
+ old_id int(8) unsigned NOT NULL auto_increment,
+
+ -- Depending on the contents of the old_flags field, the text
+ -- may be convenient plain text, or it may be funkily encoded.
+ old_text mediumblob NOT NULL,
+
+ -- Comma-separated list of flags:
+ -- gzip: text is compressed with PHP's gzdeflate() function.
+ -- utf8: text was stored as UTF-8.
+ -- If $wgLegacyEncoding option is on, rows *without* this flag
+ -- will be converted to UTF-8 transparently at load time.
+ -- object: text field contained a serialized PHP object.
+ -- The object either contains multiple versions compressed
+ -- together to achieve a better compression ratio, or it refers
+ -- to another row where the text can be found.
+ old_flags tinyblob NOT NULL,
+
+ PRIMARY KEY old_id (old_id)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Holding area for deleted articles, which may be viewed
+-- or restored by admins through the Special:Undelete interface.
+-- The fields generally correspond to the page, revision, and text
+-- fields, with several caveats.
+--
+CREATE TABLE /*$wgDBprefix*/archive (
+ ar_namespace int NOT NULL default '0',
+ ar_title varchar(255) binary NOT NULL default '',
+
+ -- Newly deleted pages will not store text in this table,
+ -- but will reference the separately existing text rows.
+ -- This field is retained for backwards compatibility,
+ -- so old archived pages will remain accessible after
+ -- upgrading from 1.4 to 1.5.
+ -- Text may be gzipped or otherwise funky.
+ ar_text mediumblob NOT NULL,
+
+ -- Basic revision stuff...
+ ar_comment tinyblob NOT NULL,
+ ar_user int(5) unsigned NOT NULL default '0',
+ ar_user_text varchar(255) binary NOT NULL,
+ ar_timestamp char(14) binary NOT NULL default '',
+ ar_minor_edit tinyint(1) NOT NULL default '0',
+
+ -- See ar_text note.
+ ar_flags tinyblob NOT NULL,
+
+ -- When revisions are deleted, their unique rev_id is stored
+ -- here so it can be retained after undeletion. This is necessary
+ -- to retain permalinks to given revisions after accidental delete
+ -- cycles or messy operations like history merges.
+ --
+ -- Old entries from 1.4 will be NULL here, and a new rev_id will
+ -- be created on undeletion for those revisions.
+ ar_rev_id int(8) unsigned,
+
+ -- For newly deleted revisions, this is the text.old_id key to the
+ -- actual stored text. To avoid breaking the block-compression scheme
+ -- and otherwise making storage changes harder, the actual text is
+ -- *not* deleted from the text table, merely hidden by removal of the
+ -- page and revision entries.
+ --
+ -- Old entries deleted under 1.2-1.4 will have NULL here, and their
+ -- ar_text and ar_flags fields will be used to create a new text
+ -- row upon undeletion.
+ ar_text_id int(8) unsigned,
+
+ KEY name_title_timestamp (ar_namespace,ar_title,ar_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Track page-to-page hyperlinks within the wiki.
+--
+CREATE TABLE /*$wgDBprefix*/pagelinks (
+ -- Key to the page_id of the page containing the link.
+ pl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ pl_namespace int NOT NULL default '0',
+ pl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY pl_from (pl_from,pl_namespace,pl_title),
+ KEY (pl_namespace,pl_title,pl_from)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Track template inclusions.
+--
+CREATE TABLE /*$wgDBprefix*/templatelinks (
+ -- Key to the page_id of the page containing the link.
+ tl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ tl_namespace int NOT NULL default '0',
+ tl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY tl_from (tl_from,tl_namespace,tl_title),
+ KEY (tl_namespace,tl_title,tl_from)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Track links to images *used inline*
+-- We don't distinguish live from broken links here, so
+-- they do not need to be changed on upload/removal.
+--
+CREATE TABLE /*$wgDBprefix*/imagelinks (
+ -- Key to page_id of the page containing the image / media link.
+ il_from int(8) unsigned NOT NULL default '0',
+
+ -- Filename of target image.
+ -- This is also the page_title of the file's description page;
+ -- all such pages are in namespace 6 (NS_IMAGE).
+ il_to varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY il_from (il_from,il_to),
+ KEY (il_to,il_from)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Track category inclusions *used inline*
+-- This tracks a single level of category membership
+-- (folksonomic tagging, really).
+--
+CREATE TABLE /*$wgDBprefix*/categorylinks (
+ -- Key to page_id of the page defined as a category member.
+ cl_from int(8) unsigned NOT NULL default '0',
+
+ -- Name of the category.
+ -- This is also the page_title of the category's description page;
+ -- all such pages are in namespace 14 (NS_CATEGORY).
+ cl_to varchar(255) binary NOT NULL default '',
+
+ -- The title of the linking page, or an optional override
+ -- to determine sort order. Sorting is by binary order, which
+ -- isn't always ideal, but collations seem to be an exciting
+ -- and dangerous new world in MySQL...
+ --
+ -- For MySQL 4.1+ with charset set to utf8, the sort key *index*
+ -- needs cut to be smaller than 1024 bytes (at 3 bytes per char).
+ -- To sort properly on the shorter key, this field needs to be
+ -- the same shortness.
+ cl_sortkey varchar(86) binary NOT NULL default '',
+
+ -- This isn't really used at present. Provided for an optional
+ -- sorting method by approximate addition time.
+ cl_timestamp timestamp NOT NULL,
+
+ UNIQUE KEY cl_from (cl_from,cl_to),
+
+ -- We always sort within a given category...
+ KEY cl_sortkey (cl_to,cl_sortkey),
+
+ -- Not really used?
+ KEY cl_timestamp (cl_to,cl_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Track links to external URLs
+--
+CREATE TABLE /*$wgDBprefix*/externallinks (
+ -- page_id of the referring page
+ el_from int(8) unsigned NOT NULL default '0',
+
+ -- The URL
+ el_to blob NOT NULL,
+
+ -- In the case of HTTP URLs, this is the URL with any username or password
+ -- removed, and with the labels in the hostname reversed and converted to
+ -- lower case. An extra dot is added to allow for matching of either
+ -- example.com or *.example.com in a single scan.
+ -- Example:
+ -- http://user:password@sub.example.com/page.html
+ -- becomes
+ -- http://com.example.sub./page.html
+ -- which allows for fast searching for all pages under example.com with the
+ -- clause:
+ -- WHERE el_index LIKE 'http://com.example.%'
+ el_index blob NOT NULL,
+
+ KEY (el_from, el_to(40)),
+ KEY (el_to(60), el_from),
+ KEY (el_index(60))
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Track interlanguage links
+--
+CREATE TABLE /*$wgDBprefix*/langlinks (
+ -- page_id of the referring page
+ ll_from int(8) unsigned NOT NULL default '0',
+
+ -- Language code of the target
+ ll_lang varchar(10) binary NOT NULL default '',
+
+ -- Title of the target, including namespace
+ ll_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY (ll_from, ll_lang),
+ KEY (ll_lang, ll_title)
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Contains a single row with some aggregate info
+-- on the state of the site.
+--
+CREATE TABLE /*$wgDBprefix*/site_stats (
+ -- The single row should contain 1 here.
+ ss_row_id int(8) unsigned NOT NULL,
+
+ -- Total number of page views, if hit counters are enabled.
+ ss_total_views bigint(20) unsigned default '0',
+
+ -- Total number of edits performed.
+ ss_total_edits bigint(20) unsigned default '0',
+
+ -- An approximate count of pages matching the following criteria:
+ -- * in namespace 0
+ -- * not a redirect
+ -- * contains the text '[['
+ -- See Article::isCountable() in includes/Article.php
+ ss_good_articles bigint(20) unsigned default '0',
+
+ -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster
+ ss_total_pages bigint(20) default '-1',
+
+ -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
+ ss_users bigint(20) default '-1',
+
+ -- Deprecated, no longer updated as of 1.5
+ ss_admins int(10) default '-1',
+
+ -- Number of images, equivalent to SELECT COUNT(*) FROM image
+ ss_images int(10) default '0',
+
+ UNIQUE KEY ss_row_id (ss_row_id)
+
+) ENGINE=InnoDB;
+
+--
+-- Stores an ID for every time any article is visited;
+-- depending on $wgHitcounterUpdateFreq, it is
+-- periodically cleared and the page_counter column
+-- in the page table updated for the all articles
+-- that have been visited.)
+--
+CREATE TABLE /*$wgDBprefix*/hitcounter (
+ hc_id int unsigned NOT NULL
+) ENGINE=HEAP MAX_ROWS=25000;
+
+
+--
+-- The internet is full of jerks, alas. Sometimes it's handy
+-- to block a vandal or troll account.
+--
+CREATE TABLE /*$wgDBprefix*/ipblocks (
+ -- Primary key, introduced for privacy.
+ ipb_id int(8) NOT NULL auto_increment,
+
+ -- Blocked IP address in dotted-quad form or user name.
+ ipb_address tinyblob NOT NULL,
+
+ -- Blocked user ID or 0 for IP blocks.
+ ipb_user int(8) unsigned NOT NULL default '0',
+
+ -- User ID who made the block.
+ ipb_by int(8) unsigned NOT NULL default '0',
+
+ -- Text comment made by blocker.
+ ipb_reason tinyblob NOT NULL,
+
+ -- Creation (or refresh) date in standard YMDHMS form.
+ -- IP blocks expire automatically.
+ ipb_timestamp char(14) binary NOT NULL default '',
+
+ -- Indicates that the IP address was banned because a banned
+ -- user accessed a page through it. If this is 1, ipb_address
+ -- will be hidden, and the block identified by block ID number.
+ ipb_auto bool NOT NULL default '0',
+
+ -- If set to 1, block applies only to logged-out users
+ ipb_anon_only bool NOT NULL default 0,
+
+ -- Block prevents account creation from matching IP addresses
+ ipb_create_account bool NOT NULL default 1,
+
+ -- Block triggers autoblocks
+ ipb_enable_autoblock bool NOT NULL default '1',
+
+ -- Time at which the block will expire.
+ ipb_expiry char(14) binary NOT NULL default '',
+
+ -- Start and end of an address range, in hexadecimal
+ -- Size chosen to allow IPv6
+ ipb_range_start varchar(32) NOT NULL default '',
+ ipb_range_end varchar(32) NOT NULL default '',
+
+ PRIMARY KEY ipb_id (ipb_id),
+
+ -- Unique index to support "user already blocked" messages
+ -- Any new options which prevent collisions should be included
+ UNIQUE INDEX ipb_address (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only),
+
+ INDEX ipb_user (ipb_user),
+ INDEX ipb_range (ipb_range_start(8), ipb_range_end(8)),
+ INDEX ipb_timestamp (ipb_timestamp),
+ INDEX ipb_expiry (ipb_expiry)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Uploaded images and other files.
+--
+CREATE TABLE /*$wgDBprefix*/image (
+ -- Filename.
+ -- This is also the title of the associated description page,
+ -- which will be in namespace 6 (NS_IMAGE).
+ img_name varchar(255) binary NOT NULL default '',
+
+ -- File size in bytes.
+ img_size int(8) unsigned NOT NULL default '0',
+
+ -- For images, size in pixels.
+ img_width int(5) NOT NULL default '0',
+ img_height int(5) NOT NULL default '0',
+
+ -- Extracted EXIF metadata stored as a serialized PHP array.
+ img_metadata mediumblob NOT NULL,
+
+ -- For images, bits per pixel if known.
+ img_bits int(3) NOT NULL default '0',
+
+ -- Media type as defined by the MEDIATYPE_xxx constants
+ img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+
+ -- major part of a MIME media type as defined by IANA
+ -- see http://www.iana.org/assignments/media-types/
+ img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown",
+
+ -- minor part of a MIME media type as defined by IANA
+ -- the minor parts are not required to adher to any standard
+ -- but should be consistent throughout the database
+ -- see http://www.iana.org/assignments/media-types/
+ img_minor_mime varchar(32) NOT NULL default "unknown",
+
+ -- Description field as entered by the uploader.
+ -- This is displayed in image upload history and logs.
+ img_description tinyblob NOT NULL,
+
+ -- user_id and user_name of uploader.
+ img_user int(5) unsigned NOT NULL default '0',
+ img_user_text varchar(255) binary NOT NULL default '',
+
+ -- Time of the upload.
+ img_timestamp char(14) binary NOT NULL default '',
+
+ PRIMARY KEY img_name (img_name),
+
+ -- Used by Special:Imagelist for sort-by-size
+ INDEX img_size (img_size),
+
+ -- Used by Special:Newimages and Special:Imagelist
+ INDEX img_timestamp (img_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Previous revisions of uploaded files.
+-- Awkwardly, image rows have to be moved into
+-- this table at re-upload time.
+--
+CREATE TABLE /*$wgDBprefix*/oldimage (
+ -- Base filename: key to image.img_name
+ oi_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of the archived file.
+ -- This is generally a timestamp and '!' prepended to the base name.
+ oi_archive_name varchar(255) binary NOT NULL default '',
+
+ -- Other fields as in image...
+ oi_size int(8) unsigned NOT NULL default 0,
+ oi_width int(5) NOT NULL default 0,
+ oi_height int(5) NOT NULL default 0,
+ oi_bits int(3) NOT NULL default 0,
+ oi_description tinyblob NOT NULL,
+ oi_user int(5) unsigned NOT NULL default '0',
+ oi_user_text varchar(255) binary NOT NULL default '',
+ oi_timestamp char(14) binary NOT NULL default '',
+
+ INDEX oi_name (oi_name(10))
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Record of deleted file data
+--
+CREATE TABLE /*$wgDBprefix*/filearchive (
+ -- Unique row id
+ fa_id int NOT NULL auto_increment,
+
+ -- Original base filename; key to image.img_name, page.page_title, etc
+ fa_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of archived file, if an old revision
+ fa_archive_name varchar(255) binary default '',
+
+ -- Which storage bin (directory tree or object store) the file data
+ -- is stored in. Should be 'deleted' for files that have been deleted;
+ -- any other bin is not yet in use.
+ fa_storage_group varchar(16),
+
+ -- SHA-1 of the file contents plus extension, used as a key for storage.
+ -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg
+ --
+ -- If NULL, the file was missing at deletion time or has been purged
+ -- from the archival storage.
+ fa_storage_key varchar(64) binary default '',
+
+ -- Deletion information, if this file is deleted.
+ fa_deleted_user int,
+ fa_deleted_timestamp char(14) binary default '',
+ fa_deleted_reason text,
+
+ -- Duped fields from image
+ fa_size int(8) unsigned default '0',
+ fa_width int(5) default '0',
+ fa_height int(5) default '0',
+ fa_metadata mediumblob,
+ fa_bits int(3) default '0',
+ fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+ fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") default "unknown",
+ fa_minor_mime varchar(32) default "unknown",
+ fa_description tinyblob,
+ fa_user int(5) unsigned default '0',
+ fa_user_text varchar(255) binary default '',
+ fa_timestamp char(14) binary default '',
+
+ PRIMARY KEY (fa_id),
+ INDEX (fa_name, fa_timestamp), -- pick out by image name
+ INDEX (fa_storage_group, fa_storage_key), -- pick out dupe files
+ INDEX (fa_deleted_timestamp), -- sort by deletion time
+ INDEX (fa_deleted_user) -- sort by deleter
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Primarily a summary table for Special:Recentchanges,
+-- this table contains some additional info on edits from
+-- the last few days, see Article::editUpdates()
+--
+CREATE TABLE /*$wgDBprefix*/recentchanges (
+ rc_id int(8) NOT NULL auto_increment,
+ rc_timestamp varchar(14) binary NOT NULL default '',
+ rc_cur_time varchar(14) binary NOT NULL default '',
+
+ -- As in revision
+ rc_user int(10) unsigned NOT NULL default '0',
+ rc_user_text varchar(255) binary NOT NULL default '',
+
+ -- When pages are renamed, their RC entries do _not_ change.
+ rc_namespace int NOT NULL default '0',
+ rc_title varchar(255) binary NOT NULL default '',
+
+ -- as in revision...
+ rc_comment varchar(255) binary NOT NULL default '',
+ rc_minor tinyint(3) unsigned NOT NULL default '0',
+
+ -- Edits by user accounts with the 'bot' rights key are
+ -- marked with a 1 here, and will be hidden from the
+ -- default view.
+ rc_bot tinyint(3) unsigned NOT NULL default '0',
+
+ rc_new tinyint(3) unsigned NOT NULL default '0',
+
+ -- Key to page_id (was cur_id prior to 1.5).
+ -- This will keep links working after moves while
+ -- retaining the at-the-time name in the changes list.
+ rc_cur_id int(10) unsigned NOT NULL default '0',
+
+ -- rev_id of the given revision
+ rc_this_oldid int(10) unsigned NOT NULL default '0',
+
+ -- rev_id of the prior revision, for generating diff links.
+ rc_last_oldid int(10) unsigned NOT NULL default '0',
+
+ -- These may no longer be used, with the new move log.
+ rc_type tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_title varchar(255) binary NOT NULL default '',
+
+ -- If the Recent Changes Patrol option is enabled,
+ -- users may mark edits as having been reviewed to
+ -- remove a warning flag on the RC list.
+ -- A value of 1 indicates the page has been reviewed.
+ rc_patrolled tinyint(3) unsigned NOT NULL default '0',
+
+ -- Recorded IP address the edit was made from, if the
+ -- $wgPutIPinRC option is enabled.
+ rc_ip char(15) NOT NULL default '',
+
+ -- Text length in characters before
+ -- and after the edit
+ rc_old_len int(10) default '0',
+ rc_new_len int(10) default '0',
+
+ PRIMARY KEY rc_id (rc_id),
+ INDEX rc_timestamp (rc_timestamp),
+ INDEX rc_namespace_title (rc_namespace, rc_title),
+ INDEX rc_cur_id (rc_cur_id),
+ INDEX new_name_timestamp (rc_new,rc_namespace,rc_timestamp),
+ INDEX rc_ip (rc_ip),
+ INDEX rc_ns_usertext ( rc_namespace, rc_user_text )
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+CREATE TABLE /*$wgDBprefix*/watchlist (
+ -- Key to user.user_id
+ wl_user int(5) unsigned NOT NULL,
+
+ -- Key to page_namespace/page_title
+ -- Note that users may watch pages which do not exist yet,
+ -- or existed in the past but have been deleted.
+ wl_namespace int NOT NULL default '0',
+ wl_title varchar(255) binary NOT NULL default '',
+
+ -- Timestamp when user was last sent a notification e-mail;
+ -- cleared when the user visits the page.
+ wl_notificationtimestamp varchar(14) binary,
+
+ UNIQUE KEY (wl_user, wl_namespace, wl_title),
+ KEY namespace_title (wl_namespace,wl_title)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+
+--
+-- Used by the math module to keep track
+-- of previously-rendered items.
+--
+CREATE TABLE /*$wgDBprefix*/math (
+ -- Binary MD5 hash of the latex fragment, used as an identifier key.
+ math_inputhash varbinary(16) NOT NULL,
+
+ -- Not sure what this is, exactly...
+ math_outputhash varbinary(16) NOT NULL,
+
+ -- texvc reports how well it thinks the HTML conversion worked;
+ -- if it's a low level the PNG rendering may be preferred.
+ math_html_conservativeness tinyint(1) NOT NULL,
+
+ -- HTML output from texvc, if any
+ math_html text,
+
+ -- MathML output from texvc, if any
+ math_mathml text,
+
+ UNIQUE KEY math_inputhash (math_inputhash)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- When using the default MySQL search backend, page titles
+-- and text are munged to strip markup, do Unicode case folding,
+-- and prepare the result for MySQL's fulltext index.
+--
+-- This table must be MyISAM; InnoDB does not support the needed
+-- fulltext index.
+--
+CREATE TABLE /*$wgDBprefix*/searchindex (
+ -- Key to page_id
+ si_page int(8) unsigned NOT NULL,
+
+ -- Munged version of title
+ si_title varchar(255) NOT NULL default '',
+
+ -- Munged version of body text
+ si_text mediumtext NOT NULL,
+
+ UNIQUE KEY (si_page),
+ FULLTEXT si_title (si_title),
+ FULLTEXT si_text (si_text)
+
+) ENGINE=MyISAM, DEFAULT CHARSET=utf8;
+
+--
+-- Recognized interwiki link prefixes
+--
+CREATE TABLE /*$wgDBprefix*/interwiki (
+ -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
+ iw_prefix char(32) NOT NULL,
+
+ -- The URL of the wiki, with "$1" as a placeholder for an article name.
+ -- Any spaces in the name will be transformed to underscores before
+ -- insertion.
+ iw_url char(127) NOT NULL,
+
+ -- A boolean value indicating whether the wiki is in this project
+ -- (used, for example, to detect redirect loops)
+ iw_local bool NOT NULL,
+
+ -- Boolean value indicating whether interwiki transclusions are allowed.
+ iw_trans tinyint(1) NOT NULL default 0,
+
+ UNIQUE KEY iw_prefix (iw_prefix)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Used for caching expensive grouped queries
+--
+CREATE TABLE /*$wgDBprefix*/querycache (
+ -- A key name, generally the base name of of the special page.
+ qc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qc_namespace int NOT NULL default '0',
+ qc_title char(255) binary NOT NULL default '',
+
+ KEY (qc_type,qc_value)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- For a few generic cache operations if not using Memcached
+--
+CREATE TABLE /*$wgDBprefix*/objectcache (
+ keyname char(255) binary NOT NULL default '',
+ value mediumblob,
+ exptime datetime,
+ UNIQUE KEY (keyname),
+ KEY (exptime)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+--
+-- Cache of interwiki transclusion
+--
+CREATE TABLE /*$wgDBprefix*/transcache (
+ tc_url varchar(255) NOT NULL,
+ tc_contents text,
+ tc_time int NOT NULL,
+ UNIQUE INDEX tc_url_idx (tc_url)
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+CREATE TABLE /*$wgDBprefix*/logging (
+ -- Symbolic keys for the general log type and the action type
+ -- within the log. The output format will be controlled by the
+ -- action field, but only the type controls categorization.
+ log_type char(10) NOT NULL default '',
+ log_action char(10) NOT NULL default '',
+
+ -- Timestamp. Duh.
+ log_timestamp char(14) NOT NULL default '19700101000000',
+
+ -- The user who performed this action; key to user_id
+ log_user int unsigned NOT NULL default 0,
+
+ -- Key to the page affected. Where a user is the target,
+ -- this will point to the user page.
+ log_namespace int NOT NULL default 0,
+ log_title varchar(255) binary NOT NULL default '',
+
+ -- Freeform text. Interpreted as edit history comments.
+ log_comment varchar(255) NOT NULL default '',
+
+ -- LF separated list of miscellaneous parameters
+ log_params blob NOT NULL,
+
+ KEY type_time (log_type, log_timestamp),
+ KEY user_time (log_user, log_timestamp),
+ KEY page_time (log_namespace, log_title, log_timestamp)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+CREATE TABLE /*$wgDBprefix*/trackbacks (
+ tb_id int auto_increment,
+ tb_page int REFERENCES page(page_id) ON DELETE CASCADE,
+ tb_title varchar(255) NOT NULL,
+ tb_url varchar(255) NOT NULL,
+ tb_ex text,
+ tb_name varchar(255),
+
+ PRIMARY KEY (tb_id),
+ INDEX (tb_page)
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+-- Jobs performed by parallel apache threads or a command-line daemon
+CREATE TABLE /*$wgDBprefix*/job (
+ job_id int(9) unsigned NOT NULL auto_increment,
+
+ -- Command name, currently only refreshLinks is defined
+ job_cmd varchar(255) NOT NULL default '',
+
+ -- Namespace and title to act on
+ -- Should be 0 and '' if the command does not operate on a title
+ job_namespace int NOT NULL,
+ job_title varchar(255) binary NOT NULL,
+
+ -- Any other parameters to the command
+ -- Presently unused, format undefined
+ job_params blob NOT NULL,
+
+ PRIMARY KEY job_id (job_id),
+ KEY (job_cmd, job_namespace, job_title)
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+-- Details of updates to cached special pages
+CREATE TABLE /*$wgDBprefix*/querycache_info (
+
+ -- Special page name
+ -- Corresponds to a qc_type value
+ qci_type varchar(32) NOT NULL default '',
+
+ -- Timestamp of last update
+ qci_timestamp char(14) NOT NULL default '19700101000000',
+
+ UNIQUE KEY ( qci_type )
+
+) ENGINE=InnoDB;
+
+-- For each redirect, this table contains exactly one row defining its target
+CREATE TABLE /*$wgDBprefix*/redirect (
+ -- Key to the page_id of the redirect page
+ rd_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ rd_namespace int NOT NULL default '0',
+ rd_title varchar(255) binary NOT NULL default '',
+
+ PRIMARY KEY rd_from (rd_from),
+ KEY rd_ns_title (rd_namespace,rd_title,rd_from)
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
+
+-- Used for caching expensive grouped queries that need two links (for example double-redirects)
+
+CREATE TABLE /*$wgDBprefix*/querycachetwo (
+ -- A key name, generally the base name of of the special page.
+ qcc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qcc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qcc_namespace int NOT NULL default '0',
+ qcc_title char(255) binary NOT NULL default '',
+
+ -- Target namespace+title2
+ qcc_namespacetwo int NOT NULL default '0',
+ qcc_titletwo char(255) binary NOT NULL default '',
+
+ KEY qcc_type (qcc_type,qcc_value),
+ KEY qcc_title (qcc_type,qcc_namespace,qcc_title),
+ KEY qcc_titletwo (qcc_type,qcc_namespacetwo,qcc_titletwo)
+
+) ENGINE=InnoDB, DEFAULT CHARSET=utf8;
diff --git a/maintenance/namespace2sql.php b/maintenance/namespace2sql.php
new file mode 100644
index 000000000000..081f609965ab
--- /dev/null
+++ b/maintenance/namespace2sql.php
@@ -0,0 +1,14 @@
+<?php
+#
+# Print SQL to insert namespace names into database.
+# This source code is in the public domain.
+
+require_once( "commandLine.inc" );
+
+for ($i = -2; $i < 16; ++$i) {
+ $nsname = mysql_escape_string( $wgLang->getNsText( $i ) );
+ $dbname = mysql_escape_string( $wgDBname );
+ print "INSERT INTO ns_name(ns_db, ns_num, ns_name) VALUES('$dbname', $i, '$nsname');\n";
+}
+
+?>
diff --git a/maintenance/namespaceDupes.php b/maintenance/namespaceDupes.php
new file mode 100644
index 000000000000..acd3a7085ccf
--- /dev/null
+++ b/maintenance/namespaceDupes.php
@@ -0,0 +1,195 @@
+<?php
+# Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+$options = array( 'fix', 'suffix', 'help' );
+
+/** */
+require_once( 'commandLine.inc' );
+#require_once( 'maintenance/userDupes.inc' );
+
+if(isset( $options['help'] ) ) {
+print <<<END
+usage: namespaceDupes.php [--fix] [--suffix=<text>] [--help]
+ --help : this help message
+ --fix : attempt to automatically fix errors
+ --suffix=<text> : dupes will be renamed with correct namespace with <text>
+ appended after the article name.
+
+END;
+die;
+}
+
+class NamespaceConflictChecker {
+ function NamespaceConflictChecker( &$db ) {
+ $this->db =& $db;
+ }
+
+ function checkAll( $fix, $suffix = '' ) {
+ global $wgContLang;
+ $spaces = $wgContLang->getNamespaces();
+ $ok = true;
+ foreach( $spaces as $ns => $name ) {
+ $ok = $this->checkNamespace( $ns, $name, $fix, $suffix ) && $ok;
+ }
+ return $ok;
+ }
+
+ function checkNamespace( $ns, $name, $fix, $suffix = '' ) {
+ echo "Checking namespace $ns: \"$name\"\n";
+ if( $name == '' ) {
+ echo "... skipping article namespace\n";
+ return true;
+ }
+
+ $conflicts = $this->getConflicts( $ns, $name );
+ $count = count( $conflicts );
+ if( $count == 0 ) {
+ echo "... no conflicts detected!\n";
+ return true;
+ }
+
+ echo "... $count conflicts detected:\n";
+ $ok = true;
+ foreach( $conflicts as $row ) {
+ $resolvable = $this->reportConflict( $row, $suffix );
+ $ok = $ok && $resolvable;
+ if( $fix && ( $resolvable || $suffix != '' ) ) {
+ $ok = $this->resolveConflict( $row, $resolvable, $suffix ) && $ok;
+ }
+ }
+ return $ok;
+ }
+
+ /**
+ * @fixme: do this for reals
+ */
+ function checkPrefix( $key, $prefix, $fix, $suffix = '' ) {
+ echo "Checking prefix \"$prefix\" vs namespace $key\n";
+ return $this->checkNamespace( $key, $prefix, $fix, $suffix );
+ }
+
+ function getConflicts( $ns, $name ) {
+ $page = $this->newSchema() ? 'page' : 'cur';
+ $table = $this->db->tableName( $page );
+
+ $prefix = $this->db->strencode( $name );
+ $likeprefix = str_replace( '_', '\\_', $prefix);
+
+ $sql = "SELECT {$page}_id AS id,
+ {$page}_title AS oldtitle,
+ $ns AS namespace,
+ TRIM(LEADING '$prefix:' FROM {$page}_title) AS title
+ FROM {$table}
+ WHERE {$page}_namespace=0
+ AND {$page}_title LIKE '$likeprefix:%'";
+
+ $result = $this->db->query( $sql, 'NamespaceConflictChecker::getConflicts' );
+
+ $set = array();
+ while( $row = $this->db->fetchObject( $result ) ) {
+ $set[] = $row;
+ }
+ $this->db->freeResult( $result );
+
+ return $set;
+ }
+
+ function reportConflict( $row, $suffix ) {
+ $newTitle = Title::makeTitleSafe( $row->namespace, $row->title );
+ printf( "... %d (0,\"%s\") -> (%d,\"%s\") [[%s]]\n",
+ $row->id,
+ $row->oldtitle,
+ $newTitle->getNamespace(),
+ $newTitle->getDbKey(),
+ $newTitle->getPrefixedText() );
+
+ $id = $newTitle->getArticleId();
+ if( $id ) {
+ echo "... *** cannot resolve automatically; page exists with ID $id ***\n";
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ function resolveConflict( $row, $resolvable, $suffix ) {
+ if( !$resolvable ) {
+ $row->title .= $suffix;
+ $title = Title::makeTitleSafe( $row->namespace, $row->title );
+ echo "... *** using suffixed form [[" . $title->getPrefixedText() . "]] ***\n";
+ }
+ $tables = $this->newSchema()
+ ? array( 'page' )
+ : array( 'cur', 'old' );
+ foreach( $tables as $table ) {
+ $this->resolveConflictOn( $row, $table );
+ }
+ return true;
+ }
+
+ function resolveConflictOn( $row, $table ) {
+ $fname = 'NamespaceConflictChecker::resolveConflictOn';
+ echo "... resolving on $table... ";
+ $newTitle = Title::makeTitleSafe( $row->namespace, $row->title );
+ $this->db->update( $table,
+ array(
+ "{$table}_namespace" => $newTitle->getNamespace(),
+ "{$table}_title" => $newTitle->getDbKey(),
+ ),
+ array(
+ "{$table}_namespace" => 0,
+ "{$table}_title" => $row->oldtitle,
+ ),
+ $fname );
+ echo "ok.\n";
+ return true;
+ }
+
+ function newSchema() {
+ return class_exists( 'Revision' );
+ }
+}
+
+
+
+
+$wgTitle = Title::newFromText( 'Namespace title conflict cleanup script' );
+
+$fix = isset( $options['fix'] );
+$suffix = isset( $options['suffix'] ) ? $options['suffix'] : '';
+$prefix = isset( $options['prefix'] ) ? $options['prefix'] : '';
+$key = isset( $options['key'] ) ? intval( $options['key'] ) : 0;
+$dbw =& wfGetDB( DB_MASTER );
+$duper = new NamespaceConflictChecker( $dbw );
+
+if( $prefix ) {
+ $retval = $duper->checkPrefix( $key, $prefix, $fix, $suffix );
+} else {
+ $retval = $duper->checkAll( $fix, $suffix );
+}
+
+if( $retval ) {
+ echo "\nLooks good!\n";
+ exit( 0 );
+} else {
+ echo "\nOh noeees\n";
+ exit( -1 );
+}
+
+?>
diff --git a/maintenance/nukePage.inc b/maintenance/nukePage.inc
new file mode 100644
index 000000000000..921faba6d288
--- /dev/null
+++ b/maintenance/nukePage.inc
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * Support functions for the nukeArticle script
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+require_once( 'purgeOldText.inc' );
+
+function NukePage( $name, $delete = false ) {
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ $tbl_pag = $dbw->tableName( 'page' );
+ $tbl_rec = $dbw->tableName( 'recentchanges' );
+ $tbl_rev = $dbw->tableName( 'revision' );
+
+ # Get page ID
+ echo( "Searching for \"$name\"..." );
+ $title = Title::newFromText( $name );
+ if( $title ) {
+ $id = $title->getArticleID();
+ $real = $title->getPrefixedText();
+ echo( "found \"$real\" with ID $id.\n" );
+
+ # Get corresponding revisions
+ echo( "Searching for revisions..." );
+ $res = $dbw->query( "SELECT rev_id FROM $tbl_rev WHERE rev_page = $id" );
+ while( $row = $dbw->fetchObject( $res ) ) {
+ $revs[] = $row->rev_id;
+ }
+ $count = count( $revs );
+ echo( "found $count.\n" );
+
+ # Delete the page record and associated recent changes entries
+ if( $delete ) {
+ echo( "Deleting page record..." );
+ $dbw->query( "DELETE FROM $tbl_pag WHERE page_id = $id" );
+ echo( "done.\n" );
+ echo( "Cleaning up recent changes..." );
+ $dbw->query( "DELETE FROM $tbl_rec WHERE rc_cur_id = $id" );
+ echo( "done.\n" );
+ }
+
+ $dbw->commit();
+
+ # Delete revisions as appropriate
+ if( $delete && $count ) {
+ echo( "Deleting revisions..." );
+ DeleteRevisions( $revs );
+ echo( "done.\n" );
+ PurgeRedundantText( true );
+ }
+
+ } else {
+ echo( "not found in database.\n" );
+ $dbw->commit();
+ }
+
+}
+
+function DeleteRevisions( $ids ) {
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ $tbl_rev = $dbw->tableName( 'revision' );
+
+ $set = implode( ', ', $ids );
+ $dbw->query( "DELETE FROM $tbl_rev WHERE rev_id IN ( $set )" );
+
+ $dbw->commit();
+
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/nukePage.php b/maintenance/nukePage.php
new file mode 100644
index 000000000000..b5c3f2831c41
--- /dev/null
+++ b/maintenance/nukePage.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * Erase a page record from the database
+ * Irreversible (can't use standard undelete) and does not update link tables
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+require_once( 'commandLine.inc' );
+require_once( 'nukePage.inc' );
+
+echo( "Erase Page Record\n\n" );
+
+if( isset( $args[0] ) ) {
+ NukePage( $args[0], true );
+} else {
+ ShowUsage();
+}
+
+/** Show script usage information */
+function ShowUsage() {
+ echo( "Remove a page record from the database.\n\n" );
+ echo( "Usage: php nukePage.php <title>\n\n" );
+ echo( " <title> : Page title; spaces escaped with underscores\n\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/oracle/archives/patch-trackbacks.sql b/maintenance/oracle/archives/patch-trackbacks.sql
new file mode 100644
index 000000000000..15d4eef1cade
--- /dev/null
+++ b/maintenance/oracle/archives/patch-trackbacks.sql
@@ -0,0 +1,10 @@
+CREATE SEQUENCE trackbacks_id_seq;
+CREATE TABLE trackbacks (
+ tb_id NUMBER PRIMARY KEY,
+ tb_page NUMBER(8) REFERENCES page(page_id) ON DELETE CASCADE,
+ tb_title VARCHAR(255) NOT NULL,
+ tb_url VARCHAR(255) NOT NULL,
+ tb_ex CLOB,
+ tb_name VARCHAR(255)
+);
+CREATE INDEX tb_name_page_idx ON trackbacks(tb_page);
diff --git a/maintenance/oracle/archives/patch-transcache.sql b/maintenance/oracle/archives/patch-transcache.sql
new file mode 100644
index 000000000000..62ad2c7dfa27
--- /dev/null
+++ b/maintenance/oracle/archives/patch-transcache.sql
@@ -0,0 +1,5 @@
+CREATE TABLE transcache (
+ tc_url VARCHAR2(255) NOT NULL UNIQUE,
+ tc_contents CLOB,
+ tc_time TIMESTAMP NOT NULL
+);
diff --git a/maintenance/oracle/interwiki.sql b/maintenance/oracle/interwiki.sql
new file mode 100644
index 000000000000..09d01c646239
--- /dev/null
+++ b/maintenance/oracle/interwiki.sql
@@ -0,0 +1,178 @@
+-- Based more or less on the public interwiki map from MeatballWiki
+-- Default interwiki prefixes...
+
+CALL add_interwiki('abbenormal','http://www.ourpla.net/cgi-bin/pikie.cgi?$1',0);
+CALL add_interwiki('acadwiki','http://xarch.tu-graz.ac.at/autocad/wiki/$1',0);
+CALL add_interwiki('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1',0);
+CALL add_interwiki('advogato','http://www.advogato.org/$1',0);
+CALL add_interwiki('aiwiki','http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?$1',0);
+CALL add_interwiki('alife','http://news.alife.org/wiki/index.php?$1',0);
+CALL add_interwiki('annotation','http://bayle.stanford.edu/crit/nph-med.cgi/$1',0);
+CALL add_interwiki('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1',0);
+CALL add_interwiki('arxiv','http://www.arxiv.org/abs/$1',0);
+CALL add_interwiki('aspienetwiki','http://aspie.mela.de/Wiki/index.php?title=$1',0);
+CALL add_interwiki('bemi','http://bemi.free.fr/vikio/index.php?$1',0);
+CALL add_interwiki('benefitswiki','http://www.benefitslink.com/cgi-bin/wiki.cgi?$1',0);
+CALL add_interwiki('brasilwiki','http://rio.ifi.unizh.ch/brasilienwiki/index.php/$1',0);
+CALL add_interwiki('bridgeswiki','http://c2.com/w2/bridges/$1',0);
+CALL add_interwiki('c2find','http://c2.com/cgi/wiki?FindPage&value=$1',0);
+CALL add_interwiki('cache','http://www.google.com/search?q=cache:$1',0);
+CALL add_interwiki('ciscavate','http://ciscavate.org/index.php/$1',0);
+CALL add_interwiki('cliki','http://ww.telent.net/cliki/$1',0);
+CALL add_interwiki('cmwiki','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('codersbase','http://www.codersbase.com/$1',0);
+CALL add_interwiki('commons','http://commons.wikimedia.org/wiki/$1',0);
+CALL add_interwiki('consciousness','http://teadvus.inspiral.org/',0);
+CALL add_interwiki('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1',0);
+CALL add_interwiki('creationmatters','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('dejanews','http://www.deja.com/=dnc/getdoc.xp?AN=$1',0);
+CALL add_interwiki('demokraatia','http://wiki.demokraatia.ee/',0);
+CALL add_interwiki('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0);
+CALL add_interwiki('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1',0);
+CALL add_interwiki('diveintoosx','http://diveintoosx.org/$1',0);
+CALL add_interwiki('docbook','http://docbook.org/wiki/moin.cgi/$1',0);
+CALL add_interwiki('dolphinwiki','http://www.object-arts.com/wiki/html/Dolphin/$1',0);
+CALL add_interwiki('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1',0);
+CALL add_interwiki('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0);
+CALL add_interwiki('eĉei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('echei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('ecxei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('efnetceewiki','http://purl.net/wiki/c/$1',0);
+CALL add_interwiki('efnetcppwiki','http://purl.net/wiki/cpp/$1',0);
+CALL add_interwiki('efnetpythonwiki','http://purl.net/wiki/python/$1',0);
+CALL add_interwiki('efnetxmlwiki','http://purl.net/wiki/xml/$1',0);
+CALL add_interwiki('eljwiki','http://elj.sourceforge.net/phpwiki/index.php/$1',0);
+CALL add_interwiki('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('elibre','http://enciclopedia.us.es/index.php/$1',0);
+CALL add_interwiki('eokulturcentro','http://esperanto.toulouse.free.fr/wakka.php?wiki=$1',0);
+CALL add_interwiki('evowiki','http://www.evowiki.org/index.php/$1',0);
+CALL add_interwiki('finalempire','http://final-empire.sourceforge.net/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('firstwiki','http://firstwiki.org/index.php/$1',0);
+CALL add_interwiki('foldoc','http://www.foldoc.org/foldoc/foldoc.cgi?$1',0);
+CALL add_interwiki('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0);
+CALL add_interwiki('fr.be','http://fr.wikinations.be/$1',0);
+CALL add_interwiki('fr.ca','http://fr.ca.wikinations.org/$1',0);
+CALL add_interwiki('fr.fr','http://fr.fr.wikinations.org/$1',0);
+CALL add_interwiki('fr.org','http://fr.wikinations.org/$1',0);
+CALL add_interwiki('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0);
+CALL add_interwiki('gamewiki','http://gamewiki.org/wiki/index.php/$1',0);
+CALL add_interwiki('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1',0);
+CALL add_interwiki('gentoo-wiki','http://gentoo-wiki.com/$1',0);
+CALL add_interwiki('globalvoices','http://cyber.law.harvard.edu/dyn/globalvoices/wiki/$1',0);
+CALL add_interwiki('gmailwiki','http://www.gmailwiki.com/index.php/$1',0);
+CALL add_interwiki('google','http://www.google.com/search?q=$1',0);
+CALL add_interwiki('googlegroups','http://groups.google.com/groups?q=$1',0);
+CALL add_interwiki('gotamac','http://www.got-a-mac.org/$1',0);
+CALL add_interwiki('greencheese','http://www.greencheese.org/$1',0);
+CALL add_interwiki('hammondwiki','http://www.dairiki.org/HammondWiki/index.php3?$1',0);
+CALL add_interwiki('haribeau','http://wiki.haribeau.de/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('hewikisource','http://he.wikisource.org/wiki/$1',1);
+CALL add_interwiki('herzkinderwiki','http://www.herzkinderinfo.de/Mediawiki/index.php/$1',0);
+CALL add_interwiki('hrwiki','http://www.hrwiki.org/index.php/$1',0);
+CALL add_interwiki('iawiki','http://www.IAwiki.net/$1',0);
+CALL add_interwiki('imdb','http://us.imdb.com/Title?$1',0);
+CALL add_interwiki('infosecpedia','http://www.infosecpedia.org/pedia/index.php/$1',0);
+CALL add_interwiki('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0);
+CALL add_interwiki('jefo','http://www.esperanto-jeunes.org/vikio/index.php?$1',0);
+CALL add_interwiki('jiniwiki','http://www.cdegroot.com/cgi-bin/jini?$1',0);
+CALL add_interwiki('jspwiki','http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=$1',0);
+CALL add_interwiki('kerimwiki','http://wiki.oxus.net/$1',0);
+CALL add_interwiki('kmwiki','http://www.voght.com/cgi-bin/pywiki?$1',0);
+CALL add_interwiki('knowhow','http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?$1',0);
+CALL add_interwiki('lanifexwiki','http://opt.lanifex.com/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('lasvegaswiki','http://wiki.gmnow.com/index.php/$1',0);
+CALL add_interwiki('linuxwiki','http://www.linuxwiki.de/$1',0);
+CALL add_interwiki('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1',0);
+CALL add_interwiki('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0);
+CALL add_interwiki('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0);
+CALL add_interwiki('lutherwiki','http://www.lutheranarchives.com/mw/index.php/$1',0);
+CALL add_interwiki('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0);
+CALL add_interwiki('mbtest','http://www.usemod.com/cgi-bin/mbtest.pl?$1',0);
+CALL add_interwiki('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0);
+CALL add_interwiki('mediazilla','http://bugzilla.wikipedia.org/$1',1);
+CALL add_interwiki('memoryalpha','http://www.memory-alpha.org/en/index.php/$1',0);
+CALL add_interwiki('metaweb','http://www.metaweb.com/wiki/wiki.phtml?title=$1',0);
+CALL add_interwiki('metawiki','http://sunir.org/apps/meta.pl?$1',0);
+CALL add_interwiki('metawikipedia','http://meta.wikimedia.org/wiki/$1',0);
+CALL add_interwiki('moinmoin','http://purl.net/wiki/moin/$1',0);
+CALL add_interwiki('mozillawiki','http://wiki.mozilla.org/index.php/$1',0);
+CALL add_interwiki('muweb','http://www.dunstable.com/scripts/MuWebWeb?$1',0);
+CALL add_interwiki('netvillage','http://www.netbros.com/?$1',0);
+CALL add_interwiki('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1',0);
+CALL add_interwiki('openfacts','http://openfacts.berlios.de/index.phtml?title=$1',0);
+CALL add_interwiki('openwiki','http://openwiki.com/?$1',0);
+CALL add_interwiki('opera7wiki','http://nontroppo.org/wiki/$1',0);
+CALL add_interwiki('orgpatterns','http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?$1',0);
+CALL add_interwiki('osi reference model','http://wiki.tigma.ee/',0);
+CALL add_interwiki('pangalacticorg','http://www.pangalactic.org/Wiki/$1',0);
+CALL add_interwiki('personaltelco','http://www.personaltelco.net/index.cgi/$1',0);
+CALL add_interwiki('patwiki','http://gauss.ffii.org/$1',0);
+CALL add_interwiki('phpwiki','http://phpwiki.sourceforge.net/phpwiki/index.php?$1',0);
+CALL add_interwiki('pikie','http://pikie.darktech.org/cgi/pikie?$1',0);
+CALL add_interwiki('pmeg','http://www.bertilow.com/pmeg/$1.php',0);
+CALL add_interwiki('ppr','http://c2.com/cgi/wiki?$1',0);
+CALL add_interwiki('purlnet','http://purl.oclc.org/NET/$1',0);
+CALL add_interwiki('pythoninfo','http://www.python.org/cgi-bin/moinmoin/$1',0);
+CALL add_interwiki('pythonwiki','http://www.pythonwiki.de/$1',0);
+CALL add_interwiki('pywiki','http://www.voght.com/cgi-bin/pywiki?$1',0);
+CALL add_interwiki('raec','http://www.raec.clacso.edu.ar:8080/raec/Members/raecpedia/$1',0);
+CALL add_interwiki('revo','http://purl.org/NET/voko/revo/art/$1.html',0);
+CALL add_interwiki('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0);
+CALL add_interwiki('s23wiki','http://is-root.de/wiki/index.php/$1',0);
+CALL add_interwiki('scoutpedia','http://www.scoutpedia.info/index.php/$1',0);
+CALL add_interwiki('seapig','http://www.seapig.org/$1',0);
+CALL add_interwiki('seattlewiki','http://seattlewiki.org/wiki/$1',0);
+CALL add_interwiki('seattlewireless','http://seattlewireless.net/?$1',0);
+CALL add_interwiki('seeds','http://www.IslandSeeds.org/wiki/$1',0);
+CALL add_interwiki('senseislibrary','http://senseis.xmp.net/?$1',0);
+CALL add_interwiki('shakti','http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/$1',0);
+CALL add_interwiki('slashdot','http://slashdot.org/article.pl?sid=$1',0);
+CALL add_interwiki('smikipedia','http://www.smikipedia.org/$1',0);
+CALL add_interwiki('sockwiki','http://wiki.socklabs.com/$1',0);
+CALL add_interwiki('sourceforge','http://sourceforge.net/$1',0);
+CALL add_interwiki('squeak','http://minnow.cc.gatech.edu/squeak/$1',0);
+CALL add_interwiki('strikiwiki','http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?$1',0);
+CALL add_interwiki('susning','http://www.susning.nu/$1',0);
+CALL add_interwiki('svgwiki','http://www.protocol7.com/svg-wiki/default.asp?$1',0);
+CALL add_interwiki('tavi','http://tavi.sourceforge.net/$1',0);
+CALL add_interwiki('tejo','http://www.tejo.org/vikio/$1',0);
+CALL add_interwiki('terrorwiki','http://www.liberalsagainstterrorism.com/wiki/index.php/$1',0);
+CALL add_interwiki('tmbw','http://www.tmbw.net/wiki/index.php/$1',0);
+CALL add_interwiki('tmnet','http://www.technomanifestos.net/?$1',0);
+CALL add_interwiki('tmwiki','http://www.EasyTopicMaps.com/?page=$1',0);
+CALL add_interwiki('turismo','http://www.tejo.org/turismo/$1',0);
+CALL add_interwiki('theopedia','http://www.theopedia.com/$1',0);
+CALL add_interwiki('twiki','http://twiki.org/cgi-bin/view/$1',0);
+CALL add_interwiki('twistedwiki','http://purl.net/wiki/twisted/$1',0);
+CALL add_interwiki('uea','http://www.tejo.org/uea/$1',0);
+CALL add_interwiki('unreal','http://wiki.beyondunreal.com/wiki/$1',0);
+CALL add_interwiki('ursine','http://ursine.ca/$1',0);
+CALL add_interwiki('usej','http://www.tejo.org/usej/$1',0);
+CALL add_interwiki('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0);
+CALL add_interwiki('visualworks','http://wiki.cs.uiuc.edu/VisualWorks/$1',0);
+CALL add_interwiki('warpedview','http://www.warpedview.com/index.php/$1',0);
+CALL add_interwiki('webdevwikinl','http://www.promo-it.nl/WebDevWiki/index.php?page=$1',0);
+CALL add_interwiki('webisodes','http://www.webisodes.org/$1',0);
+CALL add_interwiki('webseitzwiki','http://webseitz.fluxent.com/wiki/$1',0);
+CALL add_interwiki('why','http://clublet.com/c/c/why?$1',0);
+CALL add_interwiki('wiki','http://c2.com/cgi/wiki?$1',0);
+CALL add_interwiki('wikia','http://www.wikia.com/wiki/index.php/$1',0);
+CALL add_interwiki('wikibooks','http://en.wikibooks.org/wiki/$1',1);
+CALL add_interwiki('wikicities','http://www.wikicities.com/index.php/$1',0);
+CALL add_interwiki('wikif1','http://www.wikif1.org/$1',0);
+CALL add_interwiki('wikinfo','http://www.wikinfo.org/wiki.php?title=$1',0);
+CALL add_interwiki('wikimedia','http://wikimediafoundation.org/wiki/$1',0);
+CALL add_interwiki('wikiquote','http://en.wikiquote.org/wiki/$1',1);
+CALL add_interwiki('wikinews','http://en.wikinews.org/wiki/$1',0);
+CALL add_interwiki('wikisource','http://sources.wikipedia.org/wiki/$1',1);
+CALL add_interwiki('wikispecies','http://species.wikipedia.org/wiki/$1',1);
+CALL add_interwiki('wikitravel','http://wikitravel.org/en/$1',0);
+CALL add_interwiki('wikiworld','http://WikiWorld.com/wiki/index.php/$1',0);
+CALL add_interwiki('wiktionary','http://en.wiktionary.org/wiki/$1',1);
+CALL add_interwiki('wlug','http://www.wlug.org.nz/$1',0);
+CALL add_interwiki('wlwiki','http://winslowslair.supremepixels.net/wiki/index.php/$1',0);
+CALL add_interwiki('ypsieyeball','http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?$1',0);
+CALL add_interwiki('zwiki','http://www.zwiki.org/$1',0);
+CALL add_interwiki('zzz wiki','http://wiki.zzz.ee/',0);
+CALL add_interwiki('wikt','http://en.wiktionary.org/wiki/$1',1);
+
diff --git a/maintenance/oracle/tables.sql b/maintenance/oracle/tables.sql
new file mode 100644
index 000000000000..030f427f87e4
--- /dev/null
+++ b/maintenance/oracle/tables.sql
@@ -0,0 +1,335 @@
+-- SQL to create the initial tables for the MediaWiki database.
+-- This is read and executed by the install script; you should
+-- not have to run it by itself unless doing a manual install.
+
+CREATE SEQUENCE user_user_id_seq;
+
+CREATE TABLE "user" (
+ user_id NUMBER(5) NOT NULL PRIMARY KEY,
+ user_name VARCHAR2(255) DEFAULT '' NOT NULL,
+ user_real_name VARCHAR2(255) DEFAULT '',
+ user_password VARCHAR2(128) DEFAULT '',
+ user_newpassword VARCHAR2(128) default '',
+ user_email VARCHAR2(255) default '',
+ user_options CLOB default '',
+ user_touched TIMESTAMP WITH TIME ZONE,
+ user_token CHAR(32) default '',
+ user_email_authenticated TIMESTAMP WITH TIME ZONE DEFAULT NULL,
+ user_email_token CHAR(32),
+ user_email_token_expires TIMESTAMP WITH TIME ZONE DEFAULT NULL
+);
+CREATE UNIQUE INDEX user_name_idx ON "user" (user_name);
+CREATE INDEX user_email_token_idx ON "user" (user_email_token);
+
+CREATE TABLE user_groups (
+ ug_user NUMBER(5) DEFAULT '0' NOT NULL
+ REFERENCES "user" (user_id)
+ ON DELETE CASCADE,
+ ug_group VARCHAR2(16) NOT NULL,
+ CONSTRAINT user_groups_pk PRIMARY KEY (ug_user, ug_group)
+);
+CREATE INDEX user_groups_group_idx ON user_groups(ug_group);
+
+CREATE TABLE user_newtalk (
+ user_id NUMBER(5) DEFAULT 0 NOT NULL,
+ user_ip VARCHAR2(40) DEFAULT '' NOT NULL
+);
+CREATE INDEX user_newtalk_id_idx ON user_newtalk(user_id);
+CREATE INDEX user_newtalk_ip_idx ON user_newtalk(user_ip);
+
+CREATE SEQUENCE page_page_id_seq;
+CREATE TABLE page (
+ page_id NUMBER(8) NOT NULL PRIMARY KEY,
+ page_namespace NUMBER(5) NOT NULL,
+ page_title VARCHAR(255) NOT NULL,
+ page_restrictions CLOB DEFAULT '',
+ page_counter NUMBER(20) DEFAULT 0 NOT NULL,
+ page_is_redirect NUMBER(1) DEFAULT 0 NOT NULL,
+ page_is_new NUMBER(1) DEFAULT 0 NOT NULL,
+ page_random NUMBER(25, 24) NOT NULL,
+ page_touched TIMESTAMP WITH TIME ZONE,
+ page_latest NUMBER(8) NOT NULL,
+ page_len NUMBER(8) DEFAULT 0
+);
+CREATE UNIQUE INDEX page_id_namespace_title_idx ON page(page_namespace, page_title);
+CREATE INDEX page_random_idx ON page(page_random);
+CREATE INDEX page_len_idx ON page(page_len);
+
+CREATE SEQUENCE rev_rev_id_val;
+CREATE TABLE revision (
+ rev_id NUMBER(8) NOT NULL,
+ rev_page NUMBER(8) NOT NULL
+ REFERENCES page (page_id)
+ ON DELETE CASCADE,
+ rev_text_id NUMBER(8) NOT NULL,
+ rev_comment CLOB,
+ rev_user NUMBER(8) DEFAULT 0 NOT NULL,
+ rev_user_text VARCHAR2(255) DEFAULT '' NOT NULL,
+ rev_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
+ rev_minor_edit NUMBER(1) DEFAULT 0 NOT NULL,
+ rev_deleted NUMBER(1) DEFAULT 0 NOT NULL,
+ CONSTRAINT revision_pk PRIMARY KEY (rev_page, rev_id)
+);
+
+CREATE UNIQUE INDEX rev_id_idx ON revision(rev_id);
+CREATE INDEX rev_timestamp_idx ON revision(rev_timestamp);
+CREATE INDEX rev_page_timestamp_idx ON revision(rev_page, rev_timestamp);
+CREATE INDEX rev_user_timestamp_idx ON revision(rev_user, rev_timestamp);
+CREATE INDEX rev_usertext_timestamp_idx ON revision(rev_user_text, rev_timestamp);
+
+CREATE SEQUENCE text_old_id_val;
+
+CREATE TABLE text (
+ old_id NUMBER(8) NOT NULL,
+ old_text CLOB,
+ old_flags CLOB,
+ CONSTRAINT text_pk PRIMARY KEY (old_id)
+);
+
+CREATE TABLE archive (
+ ar_namespace NUMBER(5) NOT NULL,
+ ar_title VARCHAR2(255) NOT NULL,
+ ar_text CLOB,
+ ar_comment CLOB,
+ ar_user NUMBER(8),
+ ar_user_text VARCHAR2(255) NOT NULL,
+ ar_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
+ ar_minor_edit NUMBER(1) DEFAULT 0 NOT NULL,
+ ar_flags CLOB,
+ ar_rev_id NUMBER(8),
+ ar_text_id NUMBER(8)
+);
+CREATE INDEX archive_name_title_timestamp ON archive(ar_namespace,ar_title,ar_timestamp);
+
+CREATE TABLE pagelinks (
+ pl_from NUMBER(8) NOT NULL
+ REFERENCES page(page_id)
+ ON DELETE CASCADE,
+ pl_namespace NUMBER(4) DEFAULT 0 NOT NULL,
+ pl_title VARCHAR2(255) NOT NULL
+);
+CREATE UNIQUE INDEX pl_from ON pagelinks(pl_from, pl_namespace, pl_title);
+CREATE INDEX pl_namespace ON pagelinks(pl_namespace, pl_title, pl_from);
+
+CREATE TABLE imagelinks (
+ il_from NUMBER(8) NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ il_to VARCHAR2(255) NOT NULL
+);
+CREATE UNIQUE INDEX il_from ON imagelinks(il_from, il_to);
+CREATE INDEX il_to ON imagelinks(il_to, il_from);
+
+CREATE TABLE categorylinks (
+ cl_from NUMBER(8) NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ cl_to VARCHAR2(255) NOT NULL,
+ cl_sortkey VARCHAR2(86) default '',
+ cl_timestamp TIMESTAMP WITH TIME ZONE NOT NULL
+);
+CREATE UNIQUE INDEX cl_from ON categorylinks(cl_from, cl_to);
+CREATE INDEX cl_sortkey ON categorylinks(cl_to, cl_sortkey);
+CREATE INDEX cl_timestamp ON categorylinks(cl_to, cl_timestamp);
+
+--
+-- Contains a single row with some aggregate info
+-- on the state of the site.
+--
+CREATE TABLE site_stats (
+ ss_row_id NUMBER(8) NOT NULL,
+ ss_total_views NUMBER(20) default 0,
+ ss_total_edits NUMBER(20) default 0,
+ ss_good_articles NUMBER(20) default 0,
+ ss_total_pages NUMBER(20) default -1,
+ ss_users NUMBER(20) default -1,
+ ss_admins NUMBER(10) default -1
+);
+CREATE UNIQUE INDEX ss_row_id ON site_stats(ss_row_id);
+
+--
+-- Stores an ID for every time any article is visited;
+-- depending on $wgHitcounterUpdateFreq, it is
+-- periodically cleared and the page_counter column
+-- in the page table updated for the all articles
+-- that have been visited.)
+--
+CREATE TABLE hitcounter (
+ hc_id NUMBER NOT NULL
+);
+
+--
+-- The internet is full of jerks, alas. Sometimes it's handy
+-- to block a vandal or troll account.
+--
+CREATE SEQUENCE ipblocks_ipb_id_val;
+CREATE TABLE ipblocks (
+ ipb_id NUMBER(8) NOT NULL,
+ ipb_address VARCHAR2(40),
+ ipb_user NUMBER(8),
+ ipb_by NUMBER(8) NOT NULL
+ REFERENCES "user" (user_id)
+ ON DELETE CASCADE,
+ ipb_reason CLOB,
+ ipb_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
+ ipb_auto NUMBER(1) DEFAULT 0 NOT NULL,
+ ipb_expiry TIMESTAMP WITH TIME ZONE,
+ CONSTRAINT ipblocks_pk PRIMARY KEY (ipb_id)
+);
+CREATE INDEX ipb_address ON ipblocks(ipb_address);
+CREATE INDEX ipb_user ON ipblocks(ipb_user);
+
+CREATE TABLE image (
+ img_name VARCHAR2(255) NOT NULL,
+ img_size NUMBER(8) NOT NULL,
+ img_width NUMBER(5) NOT NULL,
+ img_height NUMBER(5) NOT NULL,
+ img_metadata CLOB,
+ img_bits NUMBER(3),
+ img_media_type VARCHAR2(10),
+ img_major_mime VARCHAR2(12) DEFAULT 'unknown',
+ img_minor_mime VARCHAR2(32) DEFAULT 'unknown',
+ img_description CLOB NOT NULL,
+ img_user NUMBER(8) NOT NULL REFERENCES "user"(user_id) ON DELETE CASCADE,
+ img_user_text VARCHAR2(255) NOT NULL,
+ img_timestamp TIMESTAMP WITH TIME ZONE,
+ CONSTRAINT image_pk PRIMARY KEY (img_name)
+);
+CREATE INDEX img_size_idx ON image(img_size);
+CREATE INDEX img_timestamp_idx ON image(img_timestamp);
+
+CREATE TABLE oldimage (
+ oi_name VARCHAR2(255) NOT NULL,
+ oi_archive_name VARCHAR2(255) NOT NULL,
+ oi_size NUMBER(8) NOT NULL,
+ oi_width NUMBER(5) NOT NULL,
+ oi_height NUMBER(5) NOT NULL,
+ oi_bits NUMBER(3) NOT NULL,
+ oi_description CLOB,
+ oi_user NUMBER(8) NOT NULL REFERENCES "user"(user_id),
+ oi_user_text VARCHAR2(255) NOT NULL,
+ oi_timestamp TIMESTAMP WITH TIME ZONE NOT NULL
+);
+CREATE INDEX oi_name ON oldimage (oi_name);
+
+CREATE SEQUENCE rc_rc_id_seq;
+CREATE TABLE recentchanges (
+ rc_id NUMBER(8) NOT NULL,
+ rc_timestamp TIMESTAMP WITH TIME ZONE,
+ rc_cur_time TIMESTAMP WITH TIME ZONE,
+ rc_user NUMBER(8) DEFAULT 0 NOT NULL,
+ rc_user_text VARCHAR2(255),
+ rc_namespace NUMBER(4) DEFAULT 0 NOT NULL,
+ rc_title VARCHAR2(255) NOT NULL,
+ rc_comment VARCHAR2(255),
+ rc_minor NUMBER(3) DEFAULT 0 NOT NULL,
+ rc_bot NUMBER(3) DEFAULT 0 NOT NULL,
+ rc_new NUMBER(3) DEFAULT 0 NOT NULL,
+ rc_cur_id NUMBER(8),
+ rc_this_oldid NUMBER(8) NOT NULL,
+ rc_last_oldid NUMBER(8) NOT NULL,
+ rc_type NUMBER(3) DEFAULT 0 NOT NULL,
+ rc_moved_to_ns NUMBER(3),
+ rc_moved_to_title VARCHAR2(255),
+ rc_patrolled NUMBER(3) DEFAULT 0 NOT NULL,
+ rc_ip VARCHAR2(40),
+ rc_old_len NUMBER(10) DEFAULT 0,
+ rc_new_len NUMBER(10) DEFAULT 0,
+ CONSTRAINT rc_pk PRIMARY KEY (rc_id)
+);
+CREATE INDEX rc_timestamp ON recentchanges (rc_timestamp);
+CREATE INDEX rc_namespace_title ON recentchanges(rc_namespace, rc_title);
+CREATE INDEX rc_cur_id ON recentchanges(rc_cur_id);
+CREATE INDEX new_name_timestamp ON recentchanges(rc_new, rc_namespace, rc_timestamp);
+CREATE INDEX rc_ip ON recentchanges(rc_ip);
+
+CREATE TABLE watchlist (
+ wl_user NUMBER(8) NOT NULL
+ REFERENCES "user"(user_id)
+ ON DELETE CASCADE,
+ wl_namespace NUMBER(8) DEFAULT 0 NOT NULL,
+ wl_title VARCHAR2(255) NOT NULL,
+ wl_notificationtimestamp TIMESTAMP WITH TIME ZONE DEFAULT NULL
+);
+CREATE UNIQUE INDEX wl_user_namespace_title ON watchlist
+ (wl_user, wl_namespace, wl_title);
+CREATE INDEX wl_namespace_title ON watchlist(wl_namespace, wl_title);
+
+--
+-- Used by texvc math-rendering extension to keep track
+-- of previously-rendered items.
+--
+CREATE TABLE math (
+ math_inputhash VARCHAR2(16) NOT NULL UNIQUE,
+ math_outputhash VARCHAR2(16) NOT NULL,
+ math_html_conservativeness NUMBER(1) NOT NULL,
+ math_html CLOB,
+ math_mathml CLOB
+);
+
+--
+-- Recognized interwiki link prefixes
+--
+CREATE TABLE interwiki (
+ iw_prefix VARCHAR2(32) NOT NULL UNIQUE,
+ iw_url VARCHAR2(127) NOT NULL,
+ iw_local NUMBER(1) NOT NULL,
+ iw_trans NUMBER(1) DEFAULT 0 NOT NULL
+);
+
+CREATE TABLE querycache (
+ qc_type VARCHAR2(32) NOT NULL,
+ qc_value NUMBER(5) DEFAULT 0 NOT NULL,
+ qc_namespace NUMBER(4) DEFAULT 0 NOT NULL,
+ qc_title VARCHAR2(255)
+);
+CREATE INDEX querycache_type_value ON querycache(qc_type, qc_value);
+
+--
+-- For a few generic cache operations if not using Memcached
+--
+CREATE TABLE objectcache (
+ keyname CHAR(255) DEFAULT '',
+ value CLOB,
+ exptime TIMESTAMP WITH TIME ZONE
+);
+CREATE UNIQUE INDEX oc_keyname_idx ON objectcache(keyname);
+CREATE INDEX oc_exptime_idx ON objectcache(exptime);
+
+CREATE TABLE logging (
+ log_type VARCHAR2(10) NOT NULL,
+ log_action VARCHAR2(10) NOT NULL,
+ log_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
+ log_user NUMBER(8) REFERENCES "user"(user_id),
+ log_namespace NUMBER(4),
+ log_title VARCHAR2(255) NOT NULL,
+ log_comment VARCHAR2(255),
+ log_params CLOB
+);
+CREATE INDEX logging_type_name ON logging(log_type, log_timestamp);
+CREATE INDEX logging_user_time ON logging(log_user, log_timestamp);
+CREATE INDEX logging_page_time ON logging(log_namespace, log_title, log_timestamp);
+
+-- Hold group name and description
+--CREATE TABLE /*$wgDBprefix*/groups (
+-- gr_id int(5) unsigned NOT NULL auto_increment,
+-- gr_name varchar(50) NOT NULL default '',
+-- gr_description varchar(255) NOT NULL default '',
+-- gr_rights tinyblob,
+-- PRIMARY KEY (gr_id)
+--
+--) TYPE=InnoDB;
+
+CREATE OR REPLACE PROCEDURE add_user_right (name VARCHAR2, new_right VARCHAR2) AS
+ user_id "user".user_id%TYPE;;
+ user_is_missing EXCEPTION;;
+BEGIN
+ SELECT user_id INTO user_id FROM "user" WHERE user_name = name;;
+ INSERT INTO user_groups (ug_user, ug_group) VALUES(user_id, new_right);;
+EXCEPTION
+ WHEN NO_DATA_FOUND THEN
+ DBMS_OUTPUT.PUT_LINE('The specified user does not exist.');;
+END add_user_right;;
+;
+
+CREATE OR REPLACE PROCEDURE add_interwiki (prefix VARCHAR2, url VARCHAR2, is_local NUMBER) AS
+BEGIN
+ INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES(prefix, url, is_local);;
+END add_interwiki;;
+; \ No newline at end of file
diff --git a/maintenance/orphans.php b/maintenance/orphans.php
new file mode 100644
index 000000000000..3bfa79f52833
--- /dev/null
+++ b/maintenance/orphans.php
@@ -0,0 +1,207 @@
+<?php
+# Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Look for 'orphan' revisions hooked to pages which don't exist
+ * And 'childless' pages with no revisions.
+ * Then, kill the poor widows and orphans.
+ * Man this is depressing.
+ *
+ * @author <brion@pobox.com>
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+$options = array( 'fix' );
+
+/** */
+require_once( 'commandLine.inc' );
+$wgTitle = Title::newFromText( 'Orphan revision cleanup script' );
+
+checkOrphans( isset( $options['fix'] ) );
+checkSeparation( isset( $options['fix'] ) );
+#checkWidows( isset( $options['fix'] ) );
+
+# ------
+
+function checkOrphans( $fix ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $page = $dbw->tableName( 'page' );
+ $revision = $dbw->tableName( 'revision' );
+
+ if( $fix ) {
+ $dbw->query( "LOCK TABLES $page WRITE, $revision WRITE" );
+ }
+
+ echo "Checking for orphan revision table entries... (this may take a while on a large wiki)\n";
+ $result = $dbw->query( "
+ SELECT *
+ FROM $revision LEFT OUTER JOIN $page ON rev_page=page_id
+ WHERE page_id IS NULL
+ ");
+ $orphans = $dbw->numRows( $result );
+ if( $orphans > 0 ) {
+ global $wgContLang;
+ echo "$orphans orphan revisions...\n";
+ printf( "%10s %10s %14s %20s %s\n", 'rev_id', 'rev_page', 'rev_timestamp', 'rev_user_text', 'rev_comment' );
+ while( $row = $dbw->fetchObject( $result ) ) {
+ $comment = ( $row->rev_comment == '' )
+ ? ''
+ : '(' . $wgContLang->truncate( $row->rev_comment, 40, '...' ) . ')';
+ printf( "%10d %10d %14s %20s %s\n",
+ $row->rev_id,
+ $row->rev_page,
+ $row->rev_timestamp,
+ $wgContLang->truncate( $row->rev_user_text, 17, '...' ),
+ $comment );
+ if( $fix ) {
+ $dbw->delete( 'revision', array( 'rev_id' => $row->rev_id ) );
+ }
+ }
+ if( !$fix ) {
+ echo "Run again with --fix to remove these entries automatically.\n";
+ }
+ } else {
+ echo "No orphans! Yay!\n";
+ }
+
+ if( $fix ) {
+ $dbw->query( "UNLOCK TABLES" );
+ }
+}
+
+/**
+ * @todo DON'T USE THIS YET! It will remove entries which have children,
+ * but which aren't properly attached (eg if page_latest is bogus
+ * but valid revisions do exist)
+ */
+function checkWidows( $fix ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $page = $dbw->tableName( 'page' );
+ $revision = $dbw->tableName( 'revision' );
+
+ if( $fix ) {
+ $dbw->query( "LOCK TABLES $page WRITE, $revision WRITE" );
+ }
+
+ echo "\nChecking for childless page table entries... (this may take a while on a large wiki)\n";
+ $result = $dbw->query( "
+ SELECT *
+ FROM $page LEFT OUTER JOIN $revision ON page_latest=rev_id
+ WHERE rev_id IS NULL
+ ");
+ $widows = $dbw->numRows( $result );
+ if( $widows > 0 ) {
+ global $wgContLang;
+ echo "$widows childless pages...\n";
+ printf( "%10s %11s %2s %s\n", 'page_id', 'page_latest', 'ns', 'page_title' );
+ while( $row = $dbw->fetchObject( $result ) ) {
+ printf( "%10d %11d %2d %s\n",
+ $row->page_id,
+ $row->page_latest,
+ $row->page_namespace,
+ $row->page_title );
+ if( $fix ) {
+ $dbw->delete( 'page', array( 'page_id' => $row->page_id ) );
+ }
+ }
+ if( !$fix ) {
+ echo "Run again with --fix to remove these entries automatically.\n";
+ }
+ } else {
+ echo "No childless pages! Yay!\n";
+ }
+
+ if( $fix ) {
+ $dbw->query( "UNLOCK TABLES" );
+ }
+}
+
+
+function checkSeparation( $fix ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $page = $dbw->tableName( 'page' );
+ $revision = $dbw->tableName( 'revision' );
+ $text = $dbw->tableName( 'text' );
+
+ if( $fix ) {
+ $dbw->query( "LOCK TABLES $page WRITE, $revision WRITE, $text WRITE" );
+ }
+
+ echo "\nChecking for pages whose page_latest links are incorrect... (this may take a while on a large wiki)\n";
+ $result = $dbw->query( "
+ SELECT *
+ FROM $page LEFT OUTER JOIN $revision ON page_latest=rev_id
+ ");
+ $found = 0;
+ while( $row = $dbw->fetchObject( $result ) ) {
+ $result2 = $dbw->query( "
+ SELECT MAX(rev_timestamp) as max_timestamp
+ FROM $revision
+ WHERE rev_page=$row->page_id
+ " );
+ $row2 = $dbw->fetchObject( $result2 );
+ $dbw->freeResult( $result2 );
+ if( $row2 ) {
+ if( $row->rev_timestamp != $row2->max_timestamp ) {
+ if( $found == 0 ) {
+ printf( "%10s %10s %14s %14s\n",
+ 'page_id', 'rev_id', 'timestamp', 'max timestamp' );
+ }
+ ++$found;
+ printf( "%10d %10d %14s %14s\n",
+ $row->page_id,
+ $row->page_latest,
+ $row->rev_timestamp,
+ $row2->max_timestamp );
+ if( $fix ) {
+ # ...
+ $maxId = $dbw->selectField(
+ 'revision',
+ 'rev_id',
+ array(
+ 'rev_page' => $row->page_id,
+ 'rev_timestamp' => $row2->max_timestamp ) );
+ echo "... updating to revision $maxId\n";
+ $maxRev = Revision::newFromId( $maxId );
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $article = new Article( $title );
+ $article->updateRevisionOn( $dbw, $maxRev );
+ }
+ }
+ } else {
+ echo "wtf\n";
+ }
+ }
+
+ if( $found ) {
+ echo "Found $found pages with incorrect latest revision.\n";
+ } else {
+ echo "No pages with incorrect latest revision. Yay!\n";
+ }
+ if( !$fix && $found > 0 ) {
+ echo "Run again with --fix to remove these entries automatically.\n";
+ }
+
+ if( $fix ) {
+ $dbw->query( "UNLOCK TABLES" );
+ }
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/ourusers.php b/maintenance/ourusers.php
new file mode 100644
index 000000000000..9b7af60540c5
--- /dev/null
+++ b/maintenance/ourusers.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+$wikiuser_pass = `wikiuser_pass`;
+$wikiadmin_pass = `wikiadmin_pass`;
+$wikisql_pass = `wikisql_pass`;
+
+if ( @$argv[1] == 'yaseo' ) {
+ $hosts = array(
+ 'localhost',
+ '211.115.107.158',
+ '211.115.107.159',
+ '211.115.107.160',
+ '211.115.107.138',
+ '211.115.107.139',
+ '211.115.107.140',
+ '211.115.107.141',
+ '211.115.107.142',
+ '211.115.107.143',
+ '211.115.107.144',
+ '211.115.107.145',
+ '211.115.107.146',
+ '211.115.107.147',
+ '211.115.107.148',
+ '211.115.107.149',
+ '211.115.107.150',
+ '211.115.107.152',
+ '211.115.107.153',
+ '211.115.107.154',
+ '211.115.107.155',
+ '211.115.107.156',
+ '211.115.107.157',
+ );
+} else {
+ $hosts = array(
+ 'localhost',
+ '10.0.%',
+ '66.230.200.%',
+ );
+}
+
+$databases = array(
+ '%wik%',
+);
+
+print "/*!40100 set old_passwords=1 */;";
+print "/*!40100 set global old_passwords=1 */;";
+
+foreach( $hosts as $host ) {
+ print "--\n-- $host\n--\n\n-- wikiuser\n\n";
+ print "GRANT REPLICATION CLIENT,PROCESS ON *.* TO 'wikiuser'@'$host' IDENTIFIED BY '$wikiuser_pass';\n";
+ print "GRANT ALL PRIVILEGES ON `boardvote%`.* TO 'wikiuser'@'$host' IDENTIFIED BY '$wikiuser_pass';\n";
+ foreach( $databases as $db ) {
+ print "GRANT SELECT, INSERT, UPDATE, DELETE ON `$db`.* TO 'wikiuser'@'$host' IDENTIFIED BY '$wikiuser_pass';\n";
+ }
+
+ print "\n-- wikiadmin\n\n";
+ print "GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'wikiadmin'@'$host' IDENTIFIED BY '$wikiadmin_pass';\n";
+ print "GRANT ALL PRIVILEGES ON `boardvote%`.* TO wikiadmin@'$host' IDENTIFIED BY '$wikiadmin_pass';\n";
+ foreach ( $databases as $db ) {
+ print "GRANT ALL PRIVILEGES ON `$db`.* TO wikiadmin@'$host' IDENTIFIED BY '$wikiadmin_pass';\n";
+ }
+ print "\n";
+}
+?>
diff --git a/maintenance/parserTests.inc b/maintenance/parserTests.inc
new file mode 100644
index 000000000000..c85220d0314b
--- /dev/null
+++ b/maintenance/parserTests.inc
@@ -0,0 +1,1077 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * @todo Make this more independent of the configuration (and if possible the database)
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+$options = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record' );
+$optionsWithArgs = array( 'regex' );
+
+require_once( 'commandLine.inc' );
+require_once( "$IP/includes/ObjectCache.php" );
+require_once( "$IP/includes/BagOStuff.php" );
+require_once( "$IP/includes/Hooks.php" );
+require_once( "$IP/maintenance/parserTestsParserHook.php" );
+require_once( "$IP/maintenance/parserTestsStaticParserHook.php" );
+require_once( "$IP/maintenance/parserTestsParserTime.php" );
+
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+class ParserTest {
+ /**
+ * boolean $color whereas output should be colorized
+ * @private
+ */
+ var $color;
+
+ /**
+ * boolean $lightcolor whereas output should use light colors
+ * @private
+ */
+ var $lightcolor;
+
+ /**
+ * boolean $showOutput Show test output
+ */
+ var $showOutput;
+
+ /**
+ * Sets terminal colorization and diff/quick modes depending on OS and
+ * command-line options (--color and --quick).
+ *
+ * @public
+ */
+ function ParserTest() {
+ global $options;
+
+ # Only colorize output if stdout is a terminal.
+ $this->lightcolor = false;
+ $this->color = !wfIsWindows() && posix_isatty(1);
+
+ if( isset( $options['color'] ) ) {
+ switch( $options['color'] ) {
+ case 'no':
+ $this->color = false;
+ break;
+ case 'light':
+ $this->lightcolor = true;
+ # Fall through
+ case 'yes':
+ default:
+ $this->color = true;
+ break;
+ }
+ }
+ $this->term = $this->color
+ ? new AnsiTermColorer( $this->lightcolor )
+ : new DummyTermColorer();
+
+ $this->showDiffs = !isset( $options['quick'] );
+ $this->quiet = isset( $options['quiet'] );
+ $this->showOutput = isset( $options['show-output'] );
+
+
+ if (isset($options['regex'])) {
+ $this->regex = $options['regex'];
+ } else {
+ # Matches anything
+ $this->regex = '';
+ }
+
+ if( isset( $options['record'] ) ) {
+ $this->recorder = new DbTestRecorder( $this->term );
+ } else {
+ $this->recorder = new TestRecorder( $this->term );
+ }
+
+ $this->hooks = array();
+ $this->functionHooks = array();
+ }
+
+ /**
+ * Remove last character if it is a newline
+ * @private
+ */
+ function chomp($s) {
+ if (substr($s, -1) === "\n") {
+ return substr($s, 0, -1);
+ }
+ else {
+ return $s;
+ }
+ }
+
+ /**
+ * Run a series of tests listed in the given text files.
+ * Each test consists of a brief description, wikitext input,
+ * and the expected HTML output.
+ *
+ * Prints status updates on stdout and counts up the total
+ * number and percentage of passed tests.
+ *
+ * @param array of strings $filenames
+ * @return bool True if passed all tests, false if any tests failed.
+ * @public
+ */
+ function runTestsFromFiles( $filenames ) {
+ $this->recorder->start();
+ $ok = true;
+ foreach( $filenames as $filename ) {
+ $ok = $this->runFile( $filename ) && $ok;
+ }
+ $this->recorder->end();
+ $this->recorder->report();
+ return $ok;
+ }
+
+ private function runFile( $filename ) {
+ $infile = fopen( $filename, 'rt' );
+ if( !$infile ) {
+ wfDie( "Couldn't open $filename\n" );
+ } else {
+ print $this->term->color( 1 ) .
+ "Reading tests from \"$filename\"..." .
+ $this->term->reset() .
+ "\n";
+ }
+
+ $data = array();
+ $section = null;
+ $n = 0;
+ $ok = true;
+ while( false !== ($line = fgets( $infile ) ) ) {
+ $n++;
+ if( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) {
+ $section = strtolower( $matches[1] );
+ if( $section == 'endarticle') {
+ if( !isset( $data['text'] ) ) {
+ wfDie( "'endarticle' without 'text' at line $n of $filename\n" );
+ }
+ if( !isset( $data['article'] ) ) {
+ wfDie( "'endarticle' without 'article' at line $n of $filename\n" );
+ }
+ $this->addArticle($this->chomp($data['article']), $this->chomp($data['text']), $n);
+ $data = array();
+ $section = null;
+ continue;
+ }
+ if( $section == 'endhooks' ) {
+ if( !isset( $data['hooks'] ) ) {
+ wfDie( "'endhooks' without 'hooks' at line $n of $filename\n" );
+ }
+ foreach( explode( "\n", $data['hooks'] ) as $line ) {
+ $line = trim( $line );
+ if( $line ) {
+ $this->requireHook( $line );
+ }
+ }
+ $data = array();
+ $section = null;
+ continue;
+ }
+ if( $section == 'endfunctionhooks' ) {
+ if( !isset( $data['functionhooks'] ) ) {
+ wfDie( "'endfunctionhooks' without 'functionhooks' at line $n of $filename\n" );
+ }
+ foreach( explode( "\n", $data['functionhooks'] ) as $line ) {
+ $line = trim( $line );
+ if( $line ) {
+ $this->requireFunctionHook( $line );
+ }
+ }
+ $data = array();
+ $section = null;
+ continue;
+ }
+ if( $section == 'end' ) {
+ if( !isset( $data['test'] ) ) {
+ wfDie( "'end' without 'test' at line $n of $filename\n" );
+ }
+ if( !isset( $data['input'] ) ) {
+ wfDie( "'end' without 'input' at line $n of $filename\n" );
+ }
+ if( !isset( $data['result'] ) ) {
+ wfDie( "'end' without 'result' at line $n of $filename\n" );
+ }
+ if( !isset( $data['options'] ) ) {
+ $data['options'] = '';
+ }
+ else {
+ $data['options'] = $this->chomp( $data['options'] );
+ }
+ if (preg_match('/\\bdisabled\\b/i', $data['options'])
+ || !preg_match("/{$this->regex}/i", $data['test'])) {
+ # disabled test
+ $data = array();
+ $section = null;
+ continue;
+ }
+ $result = $this->runTest(
+ $this->chomp( $data['test'] ),
+ $this->chomp( $data['input'] ),
+ $this->chomp( $data['result'] ),
+ $this->chomp( $data['options'] ) );
+ $ok = $ok && $result;
+ $this->recorder->record( $this->chomp( $data['test'] ), $result );
+ $data = array();
+ $section = null;
+ continue;
+ }
+ if ( isset ($data[$section] ) ) {
+ wfDie( "duplicate section '$section' at line $n of $filename\n" );
+ }
+ $data[$section] = '';
+ continue;
+ }
+ if( $section ) {
+ $data[$section] .= $line;
+ }
+ }
+ print "\n";
+ return $ok;
+ }
+
+ /**
+ * Run a given wikitext input through a freshly-constructed wiki parser,
+ * and compare the output against the expected results.
+ * Prints status and explanatory messages to stdout.
+ *
+ * @param string $input Wikitext to try rendering
+ * @param string $result Result to output
+ * @return bool
+ */
+ function runTest( $desc, $input, $result, $opts ) {
+ if( !$this->quiet ) {
+ $this->showTesting( $desc );
+ }
+
+ $this->setupGlobals($opts);
+
+ $user = new User();
+ $options = ParserOptions::newFromUser( $user );
+
+ if (preg_match('/\\bmath\\b/i', $opts)) {
+ # XXX this should probably be done by the ParserOptions
+ $options->setUseTex(true);
+ }
+
+ if (preg_match('/title=\[\[(.*)\]\]/', $opts, $m)) {
+ $titleText = $m[1];
+ }
+ else {
+ $titleText = 'Parser test';
+ }
+
+ $noxml = (bool)preg_match( '~\\b noxml \\b~x', $opts );
+
+ $parser = new Parser();
+ foreach( $this->hooks as $tag => $callback ) {
+ $parser->setHook( $tag, $callback );
+ }
+ foreach( $this->functionHooks as $tag => $callback ) {
+ $parser->setFunctionHook( $tag, $callback );
+ }
+ wfRunHooks( 'ParserTestParser', array( &$parser ) );
+
+ $title =& Title::makeTitle( NS_MAIN, $titleText );
+
+ if (preg_match('/\\bpst\\b/i', $opts)) {
+ $out = $parser->preSaveTransform( $input, $title, $user, $options );
+ } elseif (preg_match('/\\bmsg\\b/i', $opts)) {
+ $out = $parser->transformMsg( $input, $options );
+ } elseif( preg_match( '/\\bsection=(\d+)\b/i', $opts, $matches ) ) {
+ $section = intval( $matches[1] );
+ $out = $parser->getSection( $input, $section );
+ } elseif( preg_match( '/\\breplace=(\d+),"(.*?)"/i', $opts, $matches ) ) {
+ $section = intval( $matches[1] );
+ $replace = $matches[2];
+ $out = $parser->replaceSection( $input, $section, $replace );
+ } else {
+ $output = $parser->parse( $input, $title, $options, true, true, 1337 );
+ $out = $output->getText();
+
+ if (preg_match('/\\bill\\b/i', $opts)) {
+ $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) );
+ } else if (preg_match('/\\bcat\\b/i', $opts)) {
+ global $wgOut;
+ $wgOut->addCategoryLinks($output->getCategories());
+ $out = $this->tidy ( implode( ' ', $wgOut->getCategoryLinks() ) );
+ }
+
+ $result = $this->tidy($result);
+ }
+
+ $this->teardownGlobals();
+
+ if( $result === $out && ( $noxml === true || $this->wellFormed( $out ) ) ) {
+ return $this->showSuccess( $desc );
+ } else {
+ return $this->showFailure( $desc, $result, $out );
+ }
+ }
+
+ /**
+ * Set up the global variables for a consistent environment for each test.
+ * Ideally this should replace the global configuration entirely.
+ *
+ * @private
+ */
+ function setupGlobals($opts = '') {
+ # Save the prefixed / quoted table names for later use when we make the temporaries.
+ $db =& wfGetDB( DB_READ );
+ $this->oldTableNames = array();
+ foreach( $this->listTables() as $table ) {
+ $this->oldTableNames[$table] = $db->tableName( $table );
+ }
+ if( !isset( $this->uploadDir ) ) {
+ $this->uploadDir = $this->setupUploadDir();
+ }
+
+ if( preg_match( '/language=([a-z]+(?:_[a-z]+)?)/', $opts, $m ) ) {
+ $lang = $m[1];
+ } else {
+ $lang = 'en';
+ }
+
+ if( preg_match( '/variant=([a-z]+(?:-[a-z]+)?)/', $opts, $m ) )
+ $variant = $m[1];
+ else
+ $variant = false;
+
+
+ $settings = array(
+ 'wgServer' => 'http://localhost',
+ 'wgScript' => '/index.php',
+ 'wgScriptPath' => '/',
+ 'wgArticlePath' => '/wiki/$1',
+ 'wgActionPaths' => array(),
+ 'wgUploadPath' => 'http://example.com/images',
+ 'wgUploadDirectory' => $this->uploadDir,
+ 'wgStyleSheetPath' => '/skins',
+ 'wgSitename' => 'MediaWiki',
+ 'wgServerName' => 'Britney Spears',
+ 'wgLanguageCode' => $lang,
+ 'wgContLanguageCode' => $lang,
+ 'wgDBprefix' => 'parsertest_',
+ 'wgRawHtml' => preg_match('/\\brawhtml\\b/i', $opts),
+ 'wgLang' => null,
+ 'wgContLang' => null,
+ 'wgNamespacesWithSubpages' => array( 0 => preg_match('/\\bsubpage\\b/i', $opts)),
+ 'wgMaxTocLevel' => 999,
+ 'wgCapitalLinks' => true,
+ 'wgNoFollowLinks' => true,
+ 'wgThumbnailScriptPath' => false,
+ 'wgUseTeX' => false,
+ 'wgLocaltimezone' => 'UTC',
+ 'wgAllowExternalImages' => true,
+ 'wgUseTidy' => false,
+ 'wgDefaultLanguageVariant' => $variant,
+ 'wgVariantArticlePath' => false,
+ );
+ $this->savedGlobals = array();
+ foreach( $settings as $var => $val ) {
+ $this->savedGlobals[$var] = $GLOBALS[$var];
+ $GLOBALS[$var] = $val;
+ }
+ $langObj = Language::factory( $lang );
+ $GLOBALS['wgLang'] = $langObj;
+ $GLOBALS['wgContLang'] = $langObj;
+
+ $GLOBALS['wgLoadBalancer']->loadMasterPos();
+ //$GLOBALS['wgMessageCache'] = new MessageCache( new BagOStuff(), false, 0, $GLOBALS['wgDBname'] );
+ $this->setupDatabase();
+
+ global $wgUser;
+ $wgUser = new User();
+ }
+
+ # List of temporary tables to create, without prefix
+ # Some of these probably aren't necessary
+ function listTables() {
+ $tables = array('user', 'page', 'revision', 'text',
+ 'pagelinks', 'imagelinks', 'categorylinks',
+ 'templatelinks', 'externallinks', 'langlinks',
+ 'site_stats', 'hitcounter',
+ 'ipblocks', 'image', 'oldimage',
+ 'recentchanges',
+ 'watchlist', 'math', 'searchindex',
+ 'interwiki', 'querycache',
+ 'objectcache', 'job', 'redirect',
+ 'querycachetwo'
+ );
+
+ // FIXME manually adding additional table for the tasks extension
+ // we probably need a better software wide system to register new
+ // tables.
+ global $wgExtensionFunctions;
+ if( in_array('wfTasksExtension' , $wgExtensionFunctions ) ) {
+ $tables[] = 'tasks';
+ }
+
+ return $tables;
+ }
+
+ /**
+ * Set up a temporary set of wiki tables to work with for the tests.
+ * Currently this will only be done once per run, and any changes to
+ * the db will be visible to later tests in the run.
+ *
+ * @private
+ */
+ function setupDatabase() {
+ static $setupDB = false;
+ global $wgDBprefix;
+
+ # Make sure we don't mess with the live DB
+ if (!$setupDB && $wgDBprefix === 'parsertest_') {
+ # oh teh horror
+ $GLOBALS['wgLoadBalancer'] = LoadBalancer::newFromParams( $GLOBALS['wgDBservers'] );
+ $db =& wfGetDB( DB_MASTER );
+
+ $tables = $this->listTables();
+
+ if (!(strcmp($db->getServerVersion(), '4.1') < 0 and stristr($db->getSoftwareLink(), 'MySQL'))) {
+ # Database that supports CREATE TABLE ... LIKE
+ global $wgDBtype;
+ if( $wgDBtype == 'postgres' ) {
+ $def = 'INCLUDING DEFAULTS';
+ } else {
+ $def = '';
+ }
+ foreach ($tables as $tbl) {
+ $newTableName = $db->tableName( $tbl );
+ $tableName = $this->oldTableNames[$tbl];
+ $db->query("CREATE TEMPORARY TABLE $newTableName (LIKE $tableName $def)");
+ }
+ } else {
+ # Hack for MySQL versions < 4.1, which don't support
+ # "CREATE TABLE ... LIKE". Note that
+ # "CREATE TEMPORARY TABLE ... SELECT * FROM ... LIMIT 0"
+ # would not create the indexes we need....
+ foreach ($tables as $tbl) {
+ $res = $db->query("SHOW CREATE TABLE {$this->oldTableNames[$tbl]}");
+ $row = $db->fetchRow($res);
+ $create = $row[1];
+ $create_tmp = preg_replace('/CREATE TABLE `(.*?)`/', 'CREATE TEMPORARY TABLE `'
+ . $wgDBprefix . $tbl .'`', $create);
+ if ($create === $create_tmp) {
+ # Couldn't do replacement
+ wfDie("could not create temporary table $tbl");
+ }
+ $db->query($create_tmp);
+ }
+
+ }
+
+ # Hack: insert a few Wikipedia in-project interwiki prefixes,
+ # for testing inter-language links
+ $db->insert( 'interwiki', array(
+ array( 'iw_prefix' => 'Wikipedia',
+ 'iw_url' => 'http://en.wikipedia.org/wiki/$1',
+ 'iw_local' => 0 ),
+ array( 'iw_prefix' => 'MeatBall',
+ 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+ 'iw_local' => 0 ),
+ array( 'iw_prefix' => 'zh',
+ 'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
+ 'iw_local' => 1 ),
+ array( 'iw_prefix' => 'es',
+ 'iw_url' => 'http://es.wikipedia.org/wiki/$1',
+ 'iw_local' => 1 ),
+ array( 'iw_prefix' => 'fr',
+ 'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
+ 'iw_local' => 1 ),
+ array( 'iw_prefix' => 'ru',
+ 'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
+ 'iw_local' => 1 ),
+ ) );
+
+ # Hack: Insert an image to work with
+ $db->insert( 'image', array(
+ 'img_name' => 'Foobar.jpg',
+ 'img_size' => 12345,
+ 'img_description' => 'Some lame file',
+ 'img_user' => 1,
+ 'img_user_text' => 'WikiSysop',
+ 'img_timestamp' => $db->timestamp( '20010115123500' ),
+ 'img_width' => 1941,
+ 'img_height' => 220,
+ 'img_bits' => 24,
+ 'img_media_type' => MEDIATYPE_BITMAP,
+ 'img_major_mime' => "image",
+ 'img_minor_mime' => "jpeg",
+ 'img_metadata' => serialize( array() ),
+ ) );
+
+ # Update certain things in site_stats
+ $db->insert( 'site_stats', array( 'ss_row_id' => 1, 'ss_images' => 1, 'ss_good_articles' => 1 ) );
+
+ $setupDB = true;
+ }
+ }
+
+ /**
+ * Create a dummy uploads directory which will contain a couple
+ * of files in order to pass existence tests.
+ * @return string The directory
+ * @private
+ */
+ function setupUploadDir() {
+ global $IP;
+
+ $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images";
+ mkdir( $dir );
+ mkdir( $dir . '/3' );
+ mkdir( $dir . '/3/3a' );
+
+ $img = "$IP/skins/monobook/headbg.jpg";
+ $h = fopen($img, 'r');
+ $c = fread($h, filesize($img));
+ fclose($h);
+
+ $f = fopen( $dir . '/3/3a/Foobar.jpg', 'wb' );
+ fwrite( $f, $c );
+ fclose( $f );
+ return $dir;
+ }
+
+ /**
+ * Restore default values and perform any necessary clean-up
+ * after each test runs.
+ *
+ * @private
+ */
+ function teardownGlobals() {
+ foreach( $this->savedGlobals as $var => $val ) {
+ $GLOBALS[$var] = $val;
+ }
+ if( isset( $this->uploadDir ) ) {
+ $this->teardownUploadDir( $this->uploadDir );
+ unset( $this->uploadDir );
+ }
+ }
+
+ /**
+ * Remove the dummy uploads directory
+ * @private
+ */
+ function teardownUploadDir( $dir ) {
+ // delete the files first, then the dirs.
+ self::deleteFiles(
+ array (
+ "$dir/3/3a/Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
+ )
+ );
+
+ self::deleteDirs(
+ array (
+ "$dir/3/3a",
+ "$dir/3",
+ "$dir/thumb/6/65",
+ "$dir/thumb/6",
+ "$dir/thumb/3/3a/Foobar.jpg",
+ "$dir/thumb/3/3a",
+ "$dir/thumb/3",
+ "$dir/thumb",
+ "$dir",
+ )
+ );
+ }
+
+ /**
+ * @desc delete the specified files, if they exist.
+ * @param array $files full paths to files to delete.
+ */
+ private static function deleteFiles( $files ) {
+ foreach( $files as $file ) {
+ if( file_exists( $file ) ) {
+ unlink( $file );
+ }
+ }
+ }
+
+ /**
+ * @desc delete the specified directories, if they exist. Must be empty.
+ * @param array $dirs full paths to directories to delete.
+ */
+ private static function deleteDirs( $dirs ) {
+ foreach( $dirs as $dir ) {
+ if( is_dir( $dir ) ) {
+ rmdir( $dir );
+ }
+ }
+ }
+
+ /**
+ * "Running test $desc..."
+ * @private
+ */
+ function showTesting( $desc ) {
+ print "Running test $desc... ";
+ }
+
+ /**
+ * Print a happy success message.
+ *
+ * @param string $desc The test name
+ * @return bool
+ * @private
+ */
+ function showSuccess( $desc ) {
+ if( !$this->quiet ) {
+ print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n";
+ }
+ return true;
+ }
+
+ /**
+ * Print a failure message and provide some explanatory output
+ * about what went wrong if so configured.
+ *
+ * @param string $desc The test name
+ * @param string $result Expected HTML output
+ * @param string $html Actual HTML output
+ * @return bool
+ * @private
+ */
+ function showFailure( $desc, $result, $html ) {
+ if( $this->quiet ) {
+ # In quiet mode we didn't show the 'Testing' message before the
+ # test, in case it succeeded. Show it now:
+ $this->showTesting( $desc );
+ }
+ print $this->term->color( '1;31' ) . 'FAILED!' . $this->term->reset() . "\n";
+ if ( $this->showOutput ) {
+ print "--- Expected ---\n$result\n--- Actual ---\n$html\n";
+ }
+ if( $this->showDiffs ) {
+ print $this->quickDiff( $result, $html );
+ if( !$this->wellFormed( $html ) ) {
+ print "XML error: $this->mXmlError\n";
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Run given strings through a diff and return the (colorized) output.
+ * Requires writable /tmp directory and a 'diff' command in the PATH.
+ *
+ * @param string $input
+ * @param string $output
+ * @param string $inFileTail Tailing for the input file name
+ * @param string $outFileTail Tailing for the output file name
+ * @return string
+ * @private
+ */
+ function quickDiff( $input, $output, $inFileTail='expected', $outFileTail='actual' ) {
+ $prefix = wfTempDir() . "/mwParser-" . mt_rand();
+
+ $infile = "$prefix-$inFileTail";
+ $this->dumpToFile( $input, $infile );
+
+ $outfile = "$prefix-$outFileTail";
+ $this->dumpToFile( $output, $outfile );
+
+ $diff = `diff -au $infile $outfile`;
+ unlink( $infile );
+ unlink( $outfile );
+
+ return $this->colorDiff( $diff );
+ }
+
+ /**
+ * Write the given string to a file, adding a final newline.
+ *
+ * @param string $data
+ * @param string $filename
+ * @private
+ */
+ function dumpToFile( $data, $filename ) {
+ $file = fopen( $filename, "wt" );
+ fwrite( $file, $data . "\n" );
+ fclose( $file );
+ }
+
+ /**
+ * Colorize unified diff output if set for ANSI color output.
+ * Subtractions are colored blue, additions red.
+ *
+ * @param string $text
+ * @return string
+ * @private
+ */
+ function colorDiff( $text ) {
+ return preg_replace(
+ array( '/^(-.*)$/m', '/^(\+.*)$/m' ),
+ array( $this->term->color( 34 ) . '$1' . $this->term->reset(),
+ $this->term->color( 31 ) . '$1' . $this->term->reset() ),
+ $text );
+ }
+
+ /**
+ * Insert a temporary test article
+ * @param string $name the title, including any prefix
+ * @param string $text the article text
+ * @param int $line the input line number, for reporting errors
+ * @private
+ */
+ function addArticle($name, $text, $line) {
+ $this->setupGlobals();
+ $title = Title::newFromText( $name );
+ if ( is_null($title) ) {
+ wfDie( "invalid title at line $line\n" );
+ }
+
+ $aid = $title->getArticleID( GAID_FOR_UPDATE );
+ if ($aid != 0) {
+ wfDie( "duplicate article at line $line\n" );
+ }
+
+ $art = new Article($title);
+ $art->insertNewArticle($text, '', false, false );
+ $this->teardownGlobals();
+ }
+
+ /**
+ * Steal a callback function from the primary parser, save it for
+ * application to our scary parser. If the hook is not installed,
+ * die a painful dead to warn the others.
+ * @param string $name
+ */
+ private function requireHook( $name ) {
+ global $wgParser;
+ if( isset( $wgParser->mTagHooks[$name] ) ) {
+ $this->hooks[$name] = $wgParser->mTagHooks[$name];
+ } else {
+ wfDie( "This test suite requires the '$name' hook extension.\n" );
+ }
+ }
+
+
+ /**
+ * Steal a callback function from the primary parser, save it for
+ * application to our scary parser. If the hook is not installed,
+ * die a painful dead to warn the others.
+ * @param string $name
+ */
+ private function requireFunctionHook( $name ) {
+ global $wgParser;
+ if( isset( $wgParser->mFunctionHooks[$name] ) ) {
+ $this->functionHooks[$name] = $wgParser->mFunctionHooks[$name];
+ } else {
+ wfDie( "This test suite requires the '$name' function hook extension.\n" );
+ }
+ }
+
+ /*
+ * Run the "tidy" command on text if the $wgUseTidy
+ * global is true
+ *
+ * @param string $text the text to tidy
+ * @return string
+ * @static
+ * @private
+ */
+ function tidy( $text ) {
+ global $wgUseTidy;
+ if ($wgUseTidy) {
+ $text = Parser::tidy($text);
+ }
+ return $text;
+ }
+
+ function wellFormed( $text ) {
+ $html =
+ Sanitizer::hackDocType() .
+ '<html>' .
+ $text .
+ '</html>';
+
+ $parser = xml_parser_create( "UTF-8" );
+
+ # case folding violates XML standard, turn it off
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
+
+ if( !xml_parse( $parser, $html, true ) ) {
+ $err = xml_error_string( xml_get_error_code( $parser ) );
+ $position = xml_get_current_byte_index( $parser );
+ $fragment = $this->extractFragment( $html, $position );
+ $this->mXmlError = "$err at byte $position:\n$fragment";
+ xml_parser_free( $parser );
+ return false;
+ }
+ xml_parser_free( $parser );
+ return true;
+ }
+
+ function extractFragment( $text, $position ) {
+ $start = max( 0, $position - 10 );
+ $before = $position - $start;
+ $fragment = '...' .
+ $this->term->color( 34 ) .
+ substr( $text, $start, $before ) .
+ $this->term->color( 0 ) .
+ $this->term->color( 31 ) .
+ $this->term->color( 1 ) .
+ substr( $text, $position, 1 ) .
+ $this->term->color( 0 ) .
+ $this->term->color( 34 ) .
+ substr( $text, $position + 1, 9 ) .
+ $this->term->color( 0 ) .
+ '...';
+ $display = str_replace( "\n", ' ', $fragment );
+ $caret = ' ' .
+ str_repeat( ' ', $before ) .
+ $this->term->color( 31 ) .
+ '^' .
+ $this->term->color( 0 );
+ return "$display\n$caret";
+ }
+
+}
+
+class AnsiTermColorer {
+ function __construct( $light ) {
+ $this->light = $light;
+ }
+
+ /**
+ * Return ANSI terminal escape code for changing text attribs/color
+ *
+ * @param string $color Semicolon-separated list of attribute/color codes
+ * @return string
+ * @private
+ */
+ function color( $color ) {
+ $light = $this->light ? "1;" : "";
+ return "\x1b[{$light}{$color}m";
+ }
+
+ /**
+ * Return ANSI terminal escape code for restoring default text attributes
+ *
+ * @return string
+ * @private
+ */
+ function reset() {
+ return "\x1b[0m";
+ }
+}
+
+/* A colour-less terminal */
+class DummyTermColorer {
+ function color( $color ) {
+ return '';
+ }
+
+ function reset() {
+ return '';
+ }
+}
+
+class TestRecorder {
+ function __construct( $term ) {
+ $this->term = $term;
+ }
+
+ function start() {
+ $this->total = 0;
+ $this->success = 0;
+ }
+
+ function record( $test, $result ) {
+ $this->total++;
+ $this->success += ($result ? 1 : 0);
+ }
+
+ function end() {
+ // dummy
+ }
+
+ function report() {
+ if( $this->total > 0 ) {
+ $this->reportPercentage( $this->success, $this->total );
+ } else {
+ wfDie( "No tests found.\n" );
+ }
+ }
+
+ function reportPercentage( $success, $total ) {
+ $ratio = wfPercent( 100 * $success / $total );
+ print $this->term->color( 1 ) . "Passed $success of $total tests ($ratio)... ";
+ if( $success == $total ) {
+ print $this->term->color( 32 ) . "PASSED!";
+ } else {
+ print $this->term->color( 31 ) . "FAILED!";
+ }
+ print $this->term->reset() . "\n";
+ return ($success == $total);
+ }
+}
+
+class DbTestRecorder extends TestRecorder {
+ private $db; ///< Database connection to the main DB
+ private $curRun; ///< run ID number for the current run
+ private $prevRun; ///< run ID number for the previous run, if any
+
+ function __construct( $term ) {
+ parent::__construct( $term );
+ $this->db = wfGetDB( DB_MASTER );
+ }
+
+ /**
+ * Set up result recording; insert a record for the run with the date
+ * and all that fun stuff
+ */
+ function start() {
+ parent::start();
+
+ $this->db->begin();
+
+ // We'll make comparisons against the previous run later...
+ $this->prevRun = $this->db->selectField( 'testrun', 'MAX(tr_id)' );
+
+ $this->db->insert( 'testrun',
+ array(
+ 'tr_date' => $this->db->timestamp(),
+ 'tr_mw_version' => SpecialVersion::getVersion(),
+ 'tr_php_version' => phpversion(),
+ 'tr_db_version' => $this->db->getServerVersion(),
+ 'tr_uname' => php_uname()
+ ),
+ __METHOD__ );
+ $this->curRun = $this->db->insertId();
+ }
+
+ /**
+ * Record an individual test item's success or failure to the db
+ * @param string $test
+ * @param bool $result
+ */
+ function record( $test, $result ) {
+ parent::record( $test, $result );
+ $this->db->insert( 'testitem',
+ array(
+ 'ti_run' => $this->curRun,
+ 'ti_name' => $test,
+ 'ti_success' => $result ? 1 : 0,
+ ),
+ __METHOD__ );
+ }
+
+ /**
+ * Commit transaction and clean up for result recording
+ */
+ function end() {
+ $this->db->commit();
+ parent::end();
+ }
+
+ function report() {
+ if( $this->prevRun ) {
+ $table = array(
+ array( 'previously failing test(s) now PASSING! :)', 0, 1 ),
+ array( 'previously PASSING test(s) removed o_O', 1, null ),
+ array( 'new PASSING test(s) :)', null, 1 ),
+
+ array( 'previously passing test(s) now FAILING! :(', 1, 0 ),
+ array( 'previously FAILING test(s) removed O_o', 0, null ),
+ array( 'new FAILING test(s) :(', null, 0 ),
+ );
+ foreach( $table as $criteria ) {
+ list( $label, $before, $after ) = $criteria;
+ $differences = $this->compareResult( $before, $after );
+ if( $differences ) {
+ $count = count($differences);
+ printf( "%4d %s\n", $count, $label );
+ foreach ($differences as $differing_test_name) {
+ print " * $differing_test_name\n";
+ }
+ }
+ }
+ } else {
+ print "No previous test runs to compare against.\n";
+ }
+ parent::report();
+ }
+
+ /**
+ ** @desc: Returns an array of the test names with changed results, based on the specified
+ ** before/after criteria.
+ */
+ private function compareResult( $before, $after ) {
+ $testitem = $this->db->tableName( 'testitem' );
+ $prevRun = intval( $this->prevRun );
+ $curRun = intval( $this->curRun );
+ $prevStatus = $this->condition( $before );
+ $curStatus = $this->condition( $after );
+
+ // note: requires mysql >= ver 4.1 for subselects
+ if( is_null( $after ) ) {
+ $sql = "
+ select prev.ti_name as t from $testitem as prev
+ where prev.ti_run=$prevRun and
+ prev.ti_success $prevStatus and
+ (select current.ti_success from $testitem as current
+ where current.ti_run=$curRun
+ and prev.ti_name=current.ti_name) $curStatus";
+ } else {
+ $sql = "
+ select current.ti_name as t from $testitem as current
+ where current.ti_run=$curRun and
+ current.ti_success $curStatus and
+ (select prev.ti_success from $testitem as prev
+ where prev.ti_run=$prevRun
+ and prev.ti_name=current.ti_name) $prevStatus";
+ }
+ $result = $this->db->query( $sql, __METHOD__ );
+ $retval = array();
+ while ($row = $this->db->fetchObject( $result )) {
+ $retval[] = $row->t;
+ }
+ $this->db->freeResult( $result );
+ return $retval;
+ }
+
+ /**
+ ** @desc: Helper function for compareResult() database querying.
+ */
+ private function condition( $value ) {
+ if( is_null( $value ) ) {
+ return 'IS NULL';
+ } else {
+ return '=' . intval( $value );
+ }
+ }
+
+}
+
+?>
diff --git a/maintenance/parserTests.php b/maintenance/parserTests.php
new file mode 100644
index 000000000000..bd1477886590
--- /dev/null
+++ b/maintenance/parserTests.php
@@ -0,0 +1,69 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require('parserTests.inc');
+
+if( isset( $options['help'] ) ) {
+ echo <<<ENDS
+MediaWiki $wgVersion parser test suite
+Usage: php parserTests.php [--quick] [--quiet] [--show-output]
+ [--color[=(yes|no|light)]]
+ [--regex=<expression>] [--file=<testfile>]
+ [--help]
+Options:
+ --quick Suppress diff output of failed tests
+ --quiet Suppress notification of passed tests (shows only failed tests)
+ --show-output Show expected and actual output
+ --color Override terminal detection and force color output on or off
+ 'light' option is similar to 'yes' but with color for dark backgrounds
+ --regex Only run tests whose descriptions which match given regex
+ --file Run test cases from a custom file instead of parserTests.txt
+ --help Show this help message
+
+
+ENDS;
+ exit( 0 );
+}
+
+# There is a convention that the parser should never
+# refer to $wgTitle directly, but instead use the title
+# passed to it.
+$wgTitle = Title::newFromText( 'Parser test script do not use' );
+$tester = new ParserTest();
+
+if( isset( $options['file'] ) ) {
+ $files = array( $options['file'] );
+} else {
+ // Default parser tests and any set from extensions or local config
+ $files = $wgParserTestFiles;
+}
+
+# Print out software version to assist with locating regressions
+$version = SpecialVersion::getVersion();
+echo( "This is MediaWiki version {$version}.\n" );
+$ok = $tester->runTestsFromFiles( $files );
+
+exit ($ok ? 0 : -1);
+?>
diff --git a/maintenance/parserTests.txt b/maintenance/parserTests.txt
new file mode 100644
index 000000000000..3d748aef3a0a
--- /dev/null
+++ b/maintenance/parserTests.txt
@@ -0,0 +1,6423 @@
+# MediaWiki Parser test cases
+# Some taken from http://meta.wikimedia.org/wiki/Parser_testing
+# All (C) their respective authors and released under the GPL
+#
+# The syntax should be fairly self-explanatory.
+#
+# Currently supported test options:
+# One of the following three:
+#
+# (default) generate HTML output
+# pst apply pre-save transform
+# msg apply message transform
+#
+# Plus any combination of these:
+#
+# cat add category links
+# ill add inter-language links
+# subpage enable subpages (disabled by default)
+# noxml don't check for XML well formdness
+# title=[[XXX]] run test using article title XXX
+# language=XXX set content language to XXX for this test
+# variant=XXX set the variant of language for this test (eg zh-tw)
+# disabled do not run test
+#
+# For testing purposes, temporary articles can created:
+# !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle
+# where '/' denotes a newline.
+
+# This is the standard article assumed to exist.
+!! article
+Main Page
+!! text
+blah blah
+!! endarticle
+
+###
+### Basic tests
+###
+!! test
+Blank input
+!! input
+!! result
+!! end
+
+
+!! test
+Simple paragraph
+!! input
+This is a simple paragraph.
+!! result
+<p>This is a simple paragraph.
+</p>
+!! end
+
+!! test
+Simple list
+!! input
+* Item 1
+* Item 2
+!! result
+<ul><li> Item 1
+</li><li> Item 2
+</li></ul>
+
+!! end
+
+!! test
+Italics and bold
+!! input
+* plain
+* plain''italic''plain
+* plain''italic''plain''italic''plain
+* plain'''bold'''plain
+* plain'''bold'''plain'''bold'''plain
+* plain''italic''plain'''bold'''plain
+* plain'''bold'''plain''italic''plain
+* plain''italic'''bold-italic'''italic''plain
+* plain'''bold''bold-italic''bold'''plain
+* plain'''''bold-italic'''italic''plain
+* plain'''''bold-italic''bold'''plain
+* plain''italic'''bold-italic'''''plain
+* plain'''bold''bold-italic'''''plain
+* plain l'''italic''plain
+!! result
+<ul><li> plain
+</li><li> plain<i>italic</i>plain
+</li><li> plain<i>italic</i>plain<i>italic</i>plain
+</li><li> plain<b>bold</b>plain
+</li><li> plain<b>bold</b>plain<b>bold</b>plain
+</li><li> plain<i>italic</i>plain<b>bold</b>plain
+</li><li> plain<b>bold</b>plain<i>italic</i>plain
+</li><li> plain<i>italic<b>bold-italic</b>italic</i>plain
+</li><li> plain<b>bold<i>bold-italic</i>bold</b>plain
+</li><li> plain<i><b>bold-italic</b>italic</i>plain
+</li><li> plain<b><i>bold-italic</i>bold</b>plain
+</li><li> plain<i>italic<b>bold-italic</b></i>plain
+</li><li> plain<b>bold<i>bold-italic</i></b>plain
+</li><li> plain l'<i>italic</i>plain
+</li></ul>
+
+!! end
+
+###
+### <nowiki> test cases
+###
+
+!! test
+<nowiki> unordered list
+!! input
+<nowiki>* This is not an unordered list item.</nowiki>
+!! result
+<p>* This is not an unordered list item.
+</p>
+!! end
+
+!! test
+<nowiki> spacing
+!! input
+<nowiki>Lorem ipsum dolor
+
+sed abit.
+ sed nullum.
+
+:and a colon
+</nowiki>
+!! result
+<p>Lorem ipsum dolor
+
+sed abit.
+ sed nullum.
+
+:and a colon
+
+</p>
+!! end
+
+!! test
+nowiki 3
+!! input
+:There is not nowiki.
+:There is <nowiki>nowiki</nowiki>.
+
+#There is not nowiki.
+#There is <nowiki>nowiki</nowiki>.
+
+*There is not nowiki.
+*There is <nowiki>nowiki</nowiki>.
+!! result
+<dl><dd>There is not nowiki.
+</dd><dd>There is nowiki.
+</dd></dl>
+<ol><li>There is not nowiki.
+</li><li>There is nowiki.
+</li></ol>
+<ul><li>There is not nowiki.
+</li><li>There is nowiki.
+</li></ul>
+
+!! end
+
+
+###
+### Comments
+###
+!! test
+Comment test 1
+!! input
+<!-- comment 1 --> asdf
+<!-- comment 2 -->
+!! result
+<pre>asdf
+</pre>
+
+!! end
+
+!! test
+Comment test 2
+!! input
+asdf
+<!-- comment 1 -->
+jkl
+!! result
+<p>asdf
+jkl
+</p>
+!! end
+
+!! test
+Comment test 3
+!! input
+asdf
+<!-- comment 1 -->
+<!-- comment 2 -->
+jkl
+!! result
+<p>asdf
+jkl
+</p>
+!! end
+
+!! test
+Comment test 4
+!! input
+asdf<!-- comment 1 -->jkl
+!! result
+<p>asdfjkl
+</p>
+!! end
+
+!! test
+Comment spacing
+!! input
+a
+ <!-- foo --> b <!-- bar -->
+c
+!! result
+<p>a
+</p>
+<pre> b
+</pre>
+<p>c
+</p>
+!! end
+
+!! test
+Comment whitespace
+!! input
+<!-- returns a single newline, not nothing, since the newline after > is not stripped -->
+!! result
+
+!! end
+
+!! test
+Comment semantics and delimiters
+!! input
+<!-- --><!----><!-----><!------>
+!! result
+
+!! end
+
+!! test
+Comment semantics and delimiters, redux
+!! input
+<!-- In SGML every "foo" here would actually show up in the text -- foo -- bar
+-- foo -- funky huh? ... -->
+!! result
+
+!! end
+
+!! test
+Comment semantics and delimiters: directors cut
+!! input
+<!-- ... However we like to keep things simple and somewhat XML-ish so we eat
+everything starting with < followed by !-- until the first -- and > we see,
+that wouldn't be valid XML however, since in XML -- has to terminate a comment
+-->-->
+!! result
+<p>-->
+</p>
+!! end
+
+!! test
+Comment semantics: nesting
+!! input
+<!--<!-- no, we're not going to do anything fancy here -->-->
+!! result
+<p>-->
+</p>
+!! end
+
+!! test
+Comment semantics: unclosed comment at end
+!! input
+<!--This comment will run out to the end of the document
+!! result
+
+!! end
+
+
+###
+### Preformatted text
+###
+!! test
+Preformatted text
+!! input
+ This is some
+ Preformatted text
+ With ''italic''
+ And '''bold'''
+ And a [[Main Page|link]]
+!! result
+<pre>This is some
+Preformatted text
+With <i>italic</i>
+And <b>bold</b>
+And a <a href="/wiki/Main_Page" title="Main Page">link</a>
+</pre>
+!! end
+
+!! test
+<pre> with <nowiki> inside (compatibility with 1.6 and earlier)
+!! input
+<pre><nowiki>
+<b>
+<cite>
+<em>
+</nowiki></pre>
+!! result
+<pre>
+&lt;b&gt;
+&lt;cite&gt;
+&lt;em&gt;
+</pre>
+
+!! end
+
+!! test
+Regression with preformatted in <center>
+!! input
+<center>
+ Blah
+</center>
+!! result
+<center>
+<pre>Blah
+</pre>
+</center>
+
+!! end
+
+!! test
+<pre> with attributes (bug 3202)
+!! input
+<pre style="background: blue; color:white">Bluescreen of WikiDeath</pre>
+!! result
+<pre style="background: blue; color:white">Bluescreen of WikiDeath</pre>
+
+!! end
+
+!! test
+<pre> with width attribute (bug 3202)
+!! input
+<pre width="8">Narrow screen goodies</pre>
+!! result
+<pre width="8">Narrow screen goodies</pre>
+
+!! end
+
+!! test
+<pre> with forbidden attribute (bug 3202)
+!! input
+<pre width="8" onmouseover="alert(document.cookie)">Narrow screen goodies</pre>
+!! result
+<pre width="8">Narrow screen goodies</pre>
+
+!! end
+
+!! test
+<pre> with forbidden attribute values (bug 3202)
+!! input
+<pre width="8" style="border-width: expression(alert(document.cookie))">Narrow screen goodies</pre>
+!! result
+<pre width="8">Narrow screen goodies</pre>
+
+!! end
+
+###
+### Definition lists
+###
+!! test
+Simple definition
+!! input
+; name : Definition
+!! result
+<dl><dt> name&nbsp;</dt><dd> Definition
+</dd></dl>
+
+!! end
+
+!! test
+Definition list for indentation only
+!! input
+: Indented text
+!! result
+<dl><dd> Indented text
+</dd></dl>
+
+!! end
+
+!! test
+Definition list with no space
+!! input
+;name:Definition
+!! result
+<dl><dt>name</dt><dd>Definition
+</dd></dl>
+
+!!end
+
+!! test
+Definition list with URL link
+!! input
+; http://example.com/ : definition
+!! result
+<dl><dt> <a href="http://example.com/" class="external free" title="http://example.com/" rel="nofollow">http://example.com/</a>&nbsp;</dt><dd> definition
+</dd></dl>
+
+!! end
+
+!! test
+Definition list with bracketed URL link
+!! input
+;[http://www.example.com/ Example]:Something about it
+!! result
+<dl><dt><a href="http://www.example.com/" class="external text" title="http://www.example.com/" rel="nofollow">Example</a></dt><dd>Something about it
+</dd></dl>
+
+!! end
+
+!! test
+Definition list with wikilink containing colon
+!! input
+; [[Help:FAQ]]: The least-read page on Wikipedia
+!! result
+<dl><dt> <a href="/index.php?title=Help:FAQ&amp;action=edit" class="new" title="Help:FAQ">Help:FAQ</a></dt><dd> The least-read page on Wikipedia
+</dd></dl>
+
+!! end
+
+# At Brion's and JeLuF's insistence... :)
+!! test
+Definition list with news link containing colon
+!! input
+; news:alt.wikipedia.rox: This isn't even a real newsgroup!
+!! result
+<dl><dt> <a href="news:alt.wikipedia.rox" class="external free" title="news:alt.wikipedia.rox" rel="nofollow">news:alt.wikipedia.rox</a></dt><dd> This isn't even a real newsgroup!
+</dd></dl>
+
+!! end
+
+!! test
+Malformed definition list with colon
+!! input
+; news:alt.wikipedia.rox -- don't crash or enter an infinite loop
+!! result
+<dl><dt> <a href="news:alt.wikipedia.rox" class="external free" title="news:alt.wikipedia.rox" rel="nofollow">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop
+</dt></dl>
+
+!! end
+
+!! test
+Definition lists: colon in external link text
+!! input
+; [http://www.wikipedia2.org/ Wikipedia : The Next Generation]: OK, I made that up
+!! result
+<dl><dt> <a href="http://www.wikipedia2.org/" class="external text" title="http://www.wikipedia2.org/" rel="nofollow">Wikipedia&nbsp;: The Next Generation</a></dt><dd> OK, I made that up
+</dd></dl>
+
+!! end
+
+!! test
+Definition lists: colon in HTML attribute
+!! input
+;<b style="display: inline">bold</b>
+!! result
+<dl><dt><b style="display: inline">bold</b>
+</dt></dl>
+
+!! end
+
+
+!! test
+Definition lists: self-closed tag
+!! input
+;one<br/>two : two-line fun
+!! result
+<dl><dt>one<br />two&nbsp;</dt><dd> two-line fun
+</dd></dl>
+
+!! end
+
+
+###
+### External links
+###
+!! test
+External links: non-bracketed
+!! input
+Non-bracketed: http://example.com
+!! result
+<p>Non-bracketed: <a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a>
+</p>
+!! end
+
+!! test
+External links: numbered
+!! input
+Numbered: [http://example.com]
+Numbered: [http://example.net]
+Numbered: [http://example.org]
+!! result
+<p>Numbered: <a href="http://example.com" class="external autonumber" title="http://example.com" rel="nofollow">[1]</a>
+Numbered: <a href="http://example.net" class="external autonumber" title="http://example.net" rel="nofollow">[2]</a>
+Numbered: <a href="http://example.org" class="external autonumber" title="http://example.org" rel="nofollow">[3]</a>
+</p>
+!!end
+
+!! test
+External links: specified text
+!! input
+Specified text: [http://example.com link]
+!! result
+<p>Specified text: <a href="http://example.com" class="external text" title="http://example.com" rel="nofollow">link</a>
+</p>
+!!end
+
+!! test
+External links: trail
+!! input
+Linktrails should not work for external links: [http://example.com link]s
+!! result
+<p>Linktrails should not work for external links: <a href="http://example.com" class="external text" title="http://example.com" rel="nofollow">link</a>s
+</p>
+!! end
+
+!! test
+External links: dollar sign in URL
+!! input
+http://example.com/1$2345
+!! result
+<p><a href="http://example.com/1$2345" class="external free" title="http://example.com/1$2345" rel="nofollow">http://example.com/1$2345</a>
+</p>
+!! end
+
+!! test
+External links: dollar sign in URL (named)
+!! input
+[http://example.com/1$2345]
+!! result
+<p><a href="http://example.com/1$2345" class="external autonumber" title="http://example.com/1$2345" rel="nofollow">[1]</a>
+</p>
+!!end
+
+!! test
+External links: open square bracket forbidden in URL (bug 4377)
+!! input
+http://example.com/1[2345
+!! result
+<p><a href="http://example.com/1" class="external free" title="http://example.com/1" rel="nofollow">http://example.com/1</a>[2345
+</p>
+!! end
+
+!! test
+External links: open square bracket forbidden in URL (named) (bug 4377)
+!! input
+[http://example.com/1[2345]
+!! result
+<p><a href="http://example.com/1" class="external text" title="http://example.com/1" rel="nofollow">[2345</a>
+</p>
+!!end
+
+!! test
+External links: nowiki in URL link text (bug 6230)
+!!input
+[http://example.com/ <nowiki>''example site''</nowiki>]
+!! result
+<p><a href="http://example.com/" class="external text" title="http://example.com/" rel="nofollow">''example site''</a>
+</p>
+!! end
+
+!! test
+External links: newline forbidden in text (bug 6230 regression check)
+!! input
+[http://example.com/ first
+second]
+!! result
+<p>[<a href="http://example.com/" class="external free" title="http://example.com/" rel="nofollow">http://example.com/</a> first
+second]
+</p>
+!!end
+
+!! test
+External image
+!! input
+External image: http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png
+!! result
+<p>External image: <img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" />
+</p>
+!! end
+
+!! test
+External image from https
+!! input
+External image from https: https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png
+!! result
+<p>External image from https: <img src="https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" />
+</p>
+!! end
+
+!! test
+Link to non-http image, no img tag
+!! input
+Link to non-http image, no img tag: ftp://example.com/test.jpg
+!! result
+<p>Link to non-http image, no img tag: <a href="ftp://example.com/test.jpg" class="external free" title="ftp://example.com/test.jpg" rel="nofollow">ftp://example.com/test.jpg</a>
+</p>
+!! end
+
+!! test
+External links: terminating separator
+!! input
+Terminating separator: http://example.com/thing,
+!! result
+<p>Terminating separator: <a href="http://example.com/thing" class="external free" title="http://example.com/thing" rel="nofollow">http://example.com/thing</a>,
+</p>
+!! end
+
+!! test
+External links: intervening separator
+!! input
+Intervening separator: http://example.com/1,2,3
+!! result
+<p>Intervening separator: <a href="http://example.com/1,2,3" class="external free" title="http://example.com/1,2,3" rel="nofollow">http://example.com/1,2,3</a>
+</p>
+!! end
+
+!! test
+External links: old bug with URL in query
+!! input
+Old bug with URL in query: [http://example.com/thing?url=http://example.com link]
+!! result
+<p>Old bug with URL in query: <a href="http://example.com/thing?url=http://example.com" class="external text" title="http://example.com/thing?url=http://example.com" rel="nofollow">link</a>
+</p>
+!! end
+
+!! test
+External links: old URL-in-URL bug, mixed protocols
+!! input
+And again with mixed protocols: [ftp://example.com?url=http://example.com link]
+!! result
+<p>And again with mixed protocols: <a href="ftp://example.com?url=http://example.com" class="external text" title="ftp://example.com?url=http://example.com" rel="nofollow">link</a>
+</p>
+!!end
+
+!! test
+External links: URL in text
+!! input
+URL in text: [http://example.com http://example.com]
+!! result
+<p>URL in text: <a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a>
+</p>
+!! end
+
+!! test
+External links: Clickable images
+!! input
+ja-style clickable images: [http://example.com http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png]
+!! result
+<p>ja-style clickable images: <a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"><img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" /></a>
+</p>
+!!end
+
+!! test
+External links: raw ampersand
+!! input
+Old &amp; use: http://x&y
+!! result
+<p>Old &amp; use: <a href="http://x&amp;y" class="external free" title="http://x&amp;y" rel="nofollow">http://x&amp;y</a>
+</p>
+!! end
+
+!! test
+External links: encoded ampersand
+!! input
+Old &amp; use: http://x&amp;y
+!! result
+<p>Old &amp; use: <a href="http://x&amp;y" class="external free" title="http://x&amp;y" rel="nofollow">http://x&amp;y</a>
+</p>
+!! end
+
+!! test
+External links: encoded equals (bug 6102)
+!! input
+http://example.com/?foo&#61;bar
+!! result
+<p><a href="http://example.com/?foo=bar" class="external free" title="http://example.com/?foo=bar" rel="nofollow">http://example.com/?foo=bar</a>
+</p>
+!! end
+
+!! test
+External links: [raw ampersand]
+!! input
+Old &amp; use: [http://x&y]
+!! result
+<p>Old &amp; use: <a href="http://x&amp;y" class="external autonumber" title="http://x&amp;y" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+External links: [encoded ampersand]
+!! input
+Old &amp; use: [http://x&amp;y]
+!! result
+<p>Old &amp; use: <a href="http://x&amp;y" class="external autonumber" title="http://x&amp;y" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+External links: [encoded equals] (bug 6102)
+!! input
+[http://example.com/?foo&#61;bar]
+!! result
+<p><a href="http://example.com/?foo=bar" class="external autonumber" title="http://example.com/?foo=bar" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+External links: [IDN ignored character reference in hostname; strip it right off]
+!! input
+[http://e&zwnj;xample.com/]
+!! result
+<p><a href="http://example.com/" class="external autonumber" title="http://example.com/" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+External links: IDN ignored character reference in hostname; strip it right off
+!! input
+http://e&zwnj;xample.com/
+!! result
+<p><a href="http://example.com/" class="external free" title="http://example.com/" rel="nofollow">http://example.com/</a>
+</p>
+!! end
+
+!! test
+External links: www.jpeg.org (bug 554)
+!! input
+http://www.jpeg.org
+!!result
+<p><a href="http://www.jpeg.org" class="external free" title="http://www.jpeg.org" rel="nofollow">http://www.jpeg.org</a>
+</p>
+!! end
+
+!! test
+External links: URL within URL (original bug 2)
+!! input
+[http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp]
+!! result
+<p><a href="http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp" class="external autonumber" title="http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+BUG 361: URL inside bracketed URL
+!! input
+[http://www.example.com/foo http://www.example.com/bar]
+!! result
+<p><a href="http://www.example.com/foo" class="external text" title="http://www.example.com/foo" rel="nofollow">http://www.example.com/bar</a>
+</p>
+!! end
+
+!! test
+BUG 361: URL within URL, not bracketed
+!! input
+http://www.example.com/foo?=http://www.example.com/bar
+!! result
+<p><a href="http://www.example.com/foo?=http://www.example.com/bar" class="external free" title="http://www.example.com/foo?=http://www.example.com/bar" rel="nofollow">http://www.example.com/foo?=http://www.example.com/bar</a>
+</p>
+!! end
+
+!! test
+BUG 289: ">"-token in URL-tail
+!! input
+http://www.example.com/<hello>
+!! result
+<p><a href="http://www.example.com/" class="external free" title="http://www.example.com/" rel="nofollow">http://www.example.com/</a>&lt;hello&gt;
+</p>
+!!end
+
+!! test
+BUG 289: literal ">"-token in URL-tail
+!! input
+http://www.example.com/<b>html</b>
+!! result
+<p><a href="http://www.example.com/" class="external free" title="http://www.example.com/" rel="nofollow">http://www.example.com/</a><b>html</b>
+</p>
+!!end
+
+!! test
+BUG 289: ">"-token in bracketed URL
+!! input
+[http://www.example.com/<hello> stuff]
+!! result
+<p><a href="http://www.example.com/" class="external text" title="http://www.example.com/" rel="nofollow">&lt;hello&gt; stuff</a>
+</p>
+!!end
+
+!! test
+BUG 289: literal ">"-token in bracketed URL
+!! input
+[http://www.example.com/<b>html</b> stuff]
+!! result
+<p><a href="http://www.example.com/" class="external text" title="http://www.example.com/" rel="nofollow"><b>html</b> stuff</a>
+</p>
+!!end
+
+!! test
+BUG 289: literal double quote at end of URL
+!! input
+http://www.example.com/"hello"
+!! result
+<p><a href="http://www.example.com/" class="external free" title="http://www.example.com/" rel="nofollow">http://www.example.com/</a>"hello"
+</p>
+!!end
+
+!! test
+BUG 289: literal double quote in bracketed URL
+!! input
+[http://www.example.com/"hello" stuff]
+!! result
+<p><a href="http://www.example.com/" class="external text" title="http://www.example.com/" rel="nofollow">"hello" stuff</a>
+</p>
+!!end
+
+!! test
+External links: invalid character
+Fixme: the missing char seems to have gone missing
+!! options
+disabled
+!! input
+[http://www.example.com test]
+!! result
+<p>[<a href="http://www.example.com" class="external free" title="http://www.example.com" rel="nofollow">http://www.example.com</a> test]
+</p>
+!! end
+
+!! test
+External links: multiple legal whitespace is fine, Magnus. Don't break it please. (bug 5081)
+!! input
+[http://www.example.com test]
+!! result
+<p><a href="http://www.example.com" class="external text" title="http://www.example.com" rel="nofollow">test</a>
+</p>
+!! end
+
+!! test
+External links: wiki links within external link (Bug 3695)
+!! input
+[http://example.com [[wikilink]] embedded in ext link]
+!! result
+<p><a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"></a><a href="/index.php?title=Wikilink&amp;action=edit" class="new" title="Wikilink">wikilink</a><a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"> embedded in ext link</a>
+</p>
+!! end
+
+!! test
+BUG 787: Links with one slash after the url protocol are invalid
+!! input
+http:/example.com
+
+[http:/example.com title]
+!! result
+<p>http:/example.com
+</p><p>[http:/example.com title]
+</p>
+!! end
+
+!! test
+Bug 2702: Mismatched <i>, <b> and <a> tags are invalid
+!! input
+''[http://example.com text'']
+[http://example.com '''text]'''
+''Something [http://example.com in italic'']
+''Something [http://example.com mixed''''', even bold]'''
+'''''Now [http://example.com both''''']
+!! result
+<p><a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"><i>text</i></a>
+<a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"><b>text</b></a>
+<i>Something </i><a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"><i>in italic</i></a>
+<i>Something </i><a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"><i>mixed</i><b>, even bold</b></a>
+<i><b>Now </b></i><a href="http://example.com" class="external text" title="http://example.com" rel="nofollow"><i><b>both</b></i></a>
+</p>
+!! end
+
+
+!! test
+Bug 4781: %26 in URL
+!! input
+http://www.example.com/?title=AT%26T
+!! result
+<p><a href="http://www.example.com/?title=AT%26T" class="external free" title="http://www.example.com/?title=AT%26T" rel="nofollow">http://www.example.com/?title=AT%26T</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %26 in URL
+!! input
+http://www.example.com/?title=100%25_Bran
+!! result
+<p><a href="http://www.example.com/?title=100%25_Bran" class="external free" title="http://www.example.com/?title=100%25_Bran" rel="nofollow">http://www.example.com/?title=100%25_Bran</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %28, %29 in URL
+!! input
+http://www.example.com/?title=Ben-Hur_%281959_film%29
+!! result
+<p><a href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external free" title="http://www.example.com/?title=Ben-Hur_%281959_film%29" rel="nofollow">http://www.example.com/?title=Ben-Hur_%281959_film%29</a>
+</p>
+!! end
+
+
+!! test
+Bug 4781: %26 in autonumber URL
+!! input
+[http://www.example.com/?title=AT%26T]
+!! result
+<p><a href="http://www.example.com/?title=AT%26T" class="external autonumber" title="http://www.example.com/?title=AT%26T" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %26 in autonumber URL
+!! input
+[http://www.example.com/?title=100%25_Bran]
+!! result
+<p><a href="http://www.example.com/?title=100%25_Bran" class="external autonumber" title="http://www.example.com/?title=100%25_Bran" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %28, %29 in autonumber URL
+!! input
+[http://www.example.com/?title=Ben-Hur_%281959_film%29]
+!! result
+<p><a href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external autonumber" title="http://www.example.com/?title=Ben-Hur_%281959_film%29" rel="nofollow">[1]</a>
+</p>
+!! end
+
+
+!! test
+Bug 4781: %26 in bracketed URL
+!! input
+[http://www.example.com/?title=AT%26T link]
+!! result
+<p><a href="http://www.example.com/?title=AT%26T" class="external text" title="http://www.example.com/?title=AT%26T" rel="nofollow">link</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %26 in bracketed URL
+!! input
+[http://www.example.com/?title=100%25_Bran link]
+!! result
+<p><a href="http://www.example.com/?title=100%25_Bran" class="external text" title="http://www.example.com/?title=100%25_Bran" rel="nofollow">link</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %28, %29 in bracketed URL
+!! input
+[http://www.example.com/?title=Ben-Hur_%281959_film%29 link]
+!! result
+<p><a href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external text" title="http://www.example.com/?title=Ben-Hur_%281959_film%29" rel="nofollow">link</a>
+</p>
+!! end
+
+!! test
+External link containing double-single-quotes in text '' (bug 4598 sanity check)
+!! input
+Some [http://example.com/ pretty ''italics'' and stuff]!
+!! result
+<p>Some <a href="http://example.com/" class="external text" title="http://example.com/" rel="nofollow">pretty <i>italics</i> and stuff</a>!
+</p>
+!! end
+
+!! test
+External link containing double-single-quotes in text embedded in italics (bug 4598 sanity check)
+!! input
+''Some [http://example.com/ pretty ''italics'' and stuff]!''
+!! result
+<p><i>Some </i><a href="http://example.com/" class="external text" title="http://example.com/" rel="nofollow"><i>pretty </i>italics<i> and stuff</i></a><i>!</i>
+</p>
+!! end
+
+
+
+###
+### Quotes
+###
+
+!! test
+Quotes
+!! input
+Normal text. '''Bold text.''' Normal text. ''Italic text.''
+
+Normal text. '''''Bold italic text.''''' Normal text.
+!!result
+<p>Normal text. <b>Bold text.</b> Normal text. <i>Italic text.</i>
+</p><p>Normal text. <i><b>Bold italic text.</b></i> Normal text.
+</p>
+!! end
+
+
+!! test
+Unclosed and unmatched quotes
+!! input
+'''''Bold italic text '''with bold deactivated''' in between.'''''
+
+'''''Bold italic text ''with italic deactivated'' in between.'''''
+
+'''Bold text..
+
+..spanning two paragraphs (should not work).'''
+
+'''Bold tag left open
+
+''Italic tag left open
+
+Normal text.
+
+<!-- Unmatching number of opening, closing tags: -->
+'''This year''''s election ''should'' beat '''last year''''s.
+
+''Tom'''s car is bigger than ''Susan'''s.
+!! result
+<p><i><b>Bold italic text </b>with bold deactivated<b> in between.</b></i>
+</p><p><b><i>Bold italic text </i>with italic deactivated<i> in between.</i></b>
+</p><p><b>Bold text..</b>
+</p><p>..spanning two paragraphs (should not work).
+</p><p><b>Bold tag left open</b>
+</p><p><i>Italic tag left open</i>
+</p><p>Normal text.
+</p><p><b>This year'</b>s election <i>should</i> beat <b>last year'</b>s.
+</p><p><i>Tom<b>s car is bigger than </b></i><b>Susan</b>s.
+</p>
+!! end
+
+###
+### Tables
+###
+### some content taken from http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide:_Using_tables
+###
+
+# This should not produce <table></table> as <table><tr><td></td></tr></table>
+# is the bare minimun required by the spec, see:
+# http://www.w3.org/TR/xhtml-modularization/dtd_module_defs.html#a_module_Basic_Tables
+!! test
+A table with no data.
+!! input
+{||}
+!! result
+!! end
+
+# A table with nothing but a caption is invalid XHTML, we might want to render
+# this as <p>caption</p>
+!! test
+A table with nothing but a caption
+!! input
+{|
+|+ caption
+|}
+!! result
+<table>
+<caption> caption
+</caption><tr><td></td></tr></table>
+
+!! end
+
+!! test
+Simple table
+!! input
+{|
+| 1 || 2
+|-
+| 3 || 4
+|}
+!! result
+<table>
+<tr>
+<td> 1 </td><td> 2
+</td></tr>
+<tr>
+<td> 3 </td><td> 4
+</td></tr></table>
+
+!! end
+
+!! test
+Multiplication table
+!! input
+{| border="1" cellpadding="2"
+|+Multiplication table
+|-
+! &times; !! 1 !! 2 !! 3
+|-
+! 1
+| 1 || 2 || 3
+|-
+! 2
+| 2 || 4 || 6
+|-
+! 3
+| 3 || 6 || 9
+|-
+! 4
+| 4 || 8 || 12
+|-
+! 5
+| 5 || 10 || 15
+|}
+!! result
+<table border="1" cellpadding="2">
+<caption>Multiplication table
+</caption>
+<tr>
+<th> &times; </th><th> 1 </th><th> 2 </th><th> 3
+</th></tr>
+<tr>
+<th> 1
+</th><td> 1 </td><td> 2 </td><td> 3
+</td></tr>
+<tr>
+<th> 2
+</th><td> 2 </td><td> 4 </td><td> 6
+</td></tr>
+<tr>
+<th> 3
+</th><td> 3 </td><td> 6 </td><td> 9
+</td></tr>
+<tr>
+<th> 4
+</th><td> 4 </td><td> 8 </td><td> 12
+</td></tr>
+<tr>
+<th> 5
+</th><td> 5 </td><td> 10 </td><td> 15
+</td></tr></table>
+
+!! end
+
+!! test
+Table rowspan
+!! input
+{| align=right border=1
+| Cell 1, row 1
+|rowspan=2| Cell 2, row 1 (and 2)
+| Cell 3, row 1
+|-
+| Cell 1, row 2
+| Cell 3, row 2
+|}
+!! result
+<table align="right" border="1">
+<tr>
+<td> Cell 1, row 1
+</td><td rowspan="2"> Cell 2, row 1 (and 2)
+</td><td> Cell 3, row 1
+</td></tr>
+<tr>
+<td> Cell 1, row 2
+</td><td> Cell 3, row 2
+</td></tr></table>
+
+!! end
+
+!! test
+Nested table
+!! input
+{| border=1
+| &alpha;
+|
+{| bgcolor=#ABCDEF border=2
+|nested
+|-
+|table
+|}
+|the original table again
+|}
+!! result
+<table border="1">
+<tr>
+<td> &alpha;
+</td><td>
+<table bgcolor="#ABCDEF" border="2">
+<tr>
+<td>nested
+</td></tr>
+<tr>
+<td>table
+</td></tr></table>
+</td><td>the original table again
+</td></tr></table>
+
+!! end
+
+!! test
+Invalid attributes in table cell (bug 1830)
+!! input
+{|
+|Cell:|broken
+|}
+!! result
+<table>
+<tr>
+<td>broken
+</td></tr></table>
+
+!! end
+
+
+# FIXME: this one has incorrect tag nesting still.
+!! test
+TODO: Table security: embedded pipes (http://mail.wikipedia.org/pipermail/wikitech-l/2006-April/034637.html)
+!! input
+{|
+| |[ftp://|x||]" onmouseover="alert(document.cookie)">test
+!! result
+<table>
+<tr>
+<td><a href="ftp://|x||" class="external autonumber" title="ftp://|x||" rel="nofollow">[1]</td><td></a>" onmouseover="alert(document.cookie)">test
+</td>
+</tr>
+</table>
+
+!! end
+
+
+###
+### Internal links
+###
+!! test
+Plain link, capitalized
+!! input
+[[Main Page]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>
+</p>
+!! end
+
+!! test
+Plain link, uncapitalized
+!! input
+[[main Page]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">main Page</a>
+</p>
+!! end
+
+!! test
+Piped link
+!! input
+[[Main Page|The Main Page]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">The Main Page</a>
+</p>
+!! end
+
+!! test
+Broken link
+!! input
+[[Zigzagzogzagzig]]
+!! result
+<p><a href="/index.php?title=Zigzagzogzagzig&amp;action=edit" class="new" title="Zigzagzogzagzig">Zigzagzogzagzig</a>
+</p>
+!! end
+
+!! test
+Link with prefix
+!! input
+xxx[[main Page]], xxx[[Main Page]], Xxx[[main Page]] XXX[[main Page]], XXX[[Main Page]]
+!! result
+<p>xxx<a href="/wiki/Main_Page" title="Main Page">main Page</a>, xxx<a href="/wiki/Main_Page" title="Main Page">Main Page</a>, Xxx<a href="/wiki/Main_Page" title="Main Page">main Page</a> XXX<a href="/wiki/Main_Page" title="Main Page">main Page</a>, XXX<a href="/wiki/Main_Page" title="Main Page">Main Page</a>
+</p>
+!! end
+
+!! test
+Link with suffix
+!! input
+[[Main Page]]xxx, [[Main Page]]XXX
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">Main Pagexxx</a>, <a href="/wiki/Main_Page" title="Main Page">Main Page</a>XXX
+</p>
+!! end
+
+!! test
+Link with 3 brackets
+!! input
+[[[main page]]]
+!! result
+<p>[[[main page]]]
+</p>
+!! end
+
+!! test
+Piped link with 3 brackets
+!! input
+[[[main page|the main page]]]
+!! result
+<p>[[[main page|the main page]]]
+</p>
+!! end
+
+!! test
+Link with multiple pipes
+!! input
+[[Main Page|The|Main|Page]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">The|Main|Page</a>
+</p>
+!! end
+
+!! test
+Link to namespaces
+!! input
+[[Talk:Parser testing]], [[Meta:Disclaimers]]
+!! result
+<p><a href="/index.php?title=Talk:Parser_testing&amp;action=edit" class="new" title="Talk:Parser testing">Talk:Parser testing</a>, <a href="/index.php?title=Meta:Disclaimers&amp;action=edit" class="new" title="Meta:Disclaimers">Meta:Disclaimers</a>
+</p>
+!! end
+
+!! test
+Piped link to namespace
+!! input
+[[Meta:Disclaimers|The disclaimers]]
+!! result
+<p><a href="/index.php?title=Meta:Disclaimers&amp;action=edit" class="new" title="Meta:Disclaimers">The disclaimers</a>
+</p>
+!! end
+
+!! test
+Link containing }
+!! input
+[[Usually caused by a typo (oops}]]
+!! result
+<p>[[Usually caused by a typo (oops}]]
+</p>
+!! end
+
+!! test
+Link containing % (not as a hex sequence)
+!! input
+[[7% Solution]]
+!! result
+<p><a href="/index.php?title=7%25_Solution&amp;action=edit" class="new" title="7% Solution">7% Solution</a>
+</p>
+!! end
+
+!! test
+Link containing % as a single hex sequence interpreted to char
+!! input
+[[7%25 Solution]]
+!! result
+<p><a href="/index.php?title=7%25_Solution&amp;action=edit" class="new" title="7% Solution">7% Solution</a>
+</p>
+!!end
+
+!! test
+Link containing % as a double hex sequence interpreted to hex sequence
+!! input
+[[7%2525 Solution]]
+!! result
+<p>[[7%2525 Solution]]
+</p>
+!!end
+
+!! test
+Link containing "#<" and "#>" % as a hex sequences- these are valid section anchors
+Example for such a section: == < ==
+!! input
+[[%23%3c]][[%23%3e]]
+!! result
+<p><a href="#.3C" title="">#&lt;</a><a href="#.3E" title="">#&gt;</a>
+</p>
+!! end
+
+!! test
+Link containing "<#" and ">#" as a hex sequences
+!! input
+[[%3c%23]][[%3e%23]]
+!! result
+<p>[[%3c%23]][[%3e%23]]
+</p>
+!! end
+
+!! test
+TODO: Link containing double-single-quotes '' (bug 4598)
+!! input
+[[Lista d''e paise d''o munno]]
+!! result
+<p><a href="/index.php?title=Lista_d%27%27e_paise_d%27%27o_munno&amp;action=edit" class="new" title="Lista d''e paise d''o munno">Lista d''e paise d''o munno</a>
+</p>
+!! end
+
+!! test
+Link containing double-single-quotes '' in text (bug 4598 sanity check)
+!! input
+Some [[Link|pretty ''italics'' and stuff]]!
+!! result
+<p>Some <a href="/index.php?title=Link&amp;action=edit" class="new" title="Link">pretty <i>italics</i> and stuff</a>!
+</p>
+!! end
+
+!! test
+Link containing double-single-quotes '' in text embedded in italics (bug 4598 sanity check)
+!! input
+''Some [[Link|pretty ''italics'' and stuff]]!
+!! result
+<p><i>Some </i><a href="/index.php?title=Link&amp;action=edit" class="new" title="Link"><i>pretty </i>italics<i> and stuff</i></a><i>!</i>
+</p>
+!! end
+
+!! test
+Plain link to URL
+!! input
+[[http://www.example.org]]
+!! result
+<p>[<a href="http://www.example.org" class="external autonumber" title="http://www.example.org" rel="nofollow">[1]</a>]
+</p>
+!! end
+
+# I'm fairly sure the expected result here is wrong.
+# We want these to be URL links, not pseudo-pages with URLs for titles....
+# However the current output is also pretty screwy.
+#
+# ----
+# I'm changing it to match the current output--it arguably makes more
+# sense in the light of the test above. Old expected result was:
+#<p>Piped link to URL: <a href="/index.php?title=Http://www.example.org&amp;action=edit" class="new" title="Http://www.example.org">an example URL</a>
+#</p>
+# But I think this test is bordering on "garbage in, garbage out" anyway.
+# -- wtm
+!! test
+Piped link to URL
+!! input
+Piped link to URL: [[http://www.example.org|an example URL]]
+!! result
+<p>Piped link to URL: [<a href="http://www.example.org|an" class="external text" title="http://www.example.org|an" rel="nofollow">example URL</a>]
+</p>
+!! end
+
+!! test
+BUG 2: [[page|http://url/]] should link to page, not http://url/
+!! input
+[[Main Page|http://url/]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">http://url/</a>
+</p>
+!! end
+
+!! test
+BUG 337: Escaped self-links should be bold
+!! options
+title=[[Bug462]]
+!! input
+[[Bu&#103;462]] [[Bug462]]
+!! result
+<p><strong class="selflink">Bu&#103;462</strong> <strong class="selflink">Bug462</strong>
+</p>
+!! end
+
+!! test
+Self-link to section should not be bold
+!! options
+title=[[Main Page]]
+!! input
+[[Main Page#section]]
+!! result
+<p><a href="/wiki/Main_Page#section" title="Main Page">Main Page#section</a>
+</p>
+!! end
+
+!! test
+<nowiki> inside a link
+!! input
+[[Main<nowiki> Page</nowiki>]] [[Main Page|the main page <nowiki>[it's not very good]</nowiki>]]
+!! result
+<p>[[Main Page]] <a href="/wiki/Main_Page" title="Main Page">the main page [it's not very good]</a>
+</p>
+!! end
+
+###
+### Interwiki links (see maintenance/interwiki.sql)
+###
+
+!! test
+Inline interwiki link
+!! input
+[[MeatBall:SoftSecurity]]
+!! result
+<p><a href="http://www.usemod.com/cgi-bin/mb.pl?SoftSecurity" class="extiw" title="meatball:SoftSecurity">MeatBall:SoftSecurity</a>
+</p>
+!! end
+
+!! test
+Inline interwiki link with empty title (bug 2372)
+!! input
+[[MeatBall:]]
+!! result
+<p><a href="http://www.usemod.com/cgi-bin/mb.pl?" class="extiw" title="meatball:">MeatBall:</a>
+</p>
+!! end
+
+!! test
+Interwiki link encoding conversion (bug 1636)
+!! input
+*[[Wikipedia:ro:Olteni&#0355;a]]
+*[[Wikipedia:ro:Olteni&#355;a]]
+!! result
+<ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a>
+</li><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a>
+</li></ul>
+
+!! end
+
+!! test
+Interwiki link with fragment (bug 2130)
+!! input
+[[MeatBall:SoftSecurity#foo]]
+!! result
+<p><a href="http://www.usemod.com/cgi-bin/mb.pl?SoftSecurity#foo" class="extiw" title="meatball:SoftSecurity">MeatBall:SoftSecurity#foo</a>
+</p>
+!! end
+
+##
+## XHTML tidiness
+###
+
+!! test
+<br> to <br />
+!! input
+1<br>2<br />3
+!! result
+<p>1<br />2<br />3
+</p>
+!! end
+
+!! test
+Incorrecly removing closing slashes from correctly formed XHTML
+!! input
+<br style="clear:both;" />
+!! result
+<p><br style="clear:both;" />
+</p>
+!! end
+
+!! test
+Failing to transform badly formed HTML into correct XHTML
+!! input
+<br clear=left>
+<br clear=right>
+<br clear=all>
+!! result
+<p><br clear="left" />
+<br clear="right" />
+<br clear="all" />
+</p>
+!!end
+
+!! test
+Horizontal ruler (should it add that extra space?)
+!! input
+<hr>
+<hr >
+foo <hr
+> bar
+!! result
+<hr />
+<hr />
+foo <hr /> bar
+
+!! end
+
+###
+### Block-level elements
+###
+!! test
+Common list
+!! input
+*Common list
+* item 2
+*item 3
+!! result
+<ul><li>Common list
+</li><li> item 2
+</li><li>item 3
+</li></ul>
+
+!! end
+
+!! test
+Numbered list
+!! input
+#Numbered list
+#item 2
+# item 3
+!! result
+<ol><li>Numbered list
+</li><li>item 2
+</li><li> item 3
+</li></ol>
+
+!! end
+
+!! test
+Mixed list
+!! input
+*Mixed list
+*# with numbers
+** and bullets
+*# and numbers
+*bullets again
+**bullet level 2
+***bullet level 3
+***#Number on level 4
+**bullet level 2
+**#Number on level 3
+**#Number on level 3
+*#number level 2
+*Level 1
+!! result
+<ul><li>Mixed list
+<ol><li> with numbers
+</li></ol>
+<ul><li> and bullets
+</li></ul>
+<ol><li> and numbers
+</li></ol>
+</li><li>bullets again
+<ul><li>bullet level 2
+<ul><li>bullet level 3
+<ol><li>Number on level 4
+</li></ol>
+</li></ul>
+</li><li>bullet level 2
+<ol><li>Number on level 3
+</li><li>Number on level 3
+</li></ol>
+</li></ul>
+<ol><li>number level 2
+</li></ol>
+</li><li>Level 1
+</li></ul>
+
+!! end
+
+!! test
+List items are not parsed correctly following a <pre> block (bug 785)
+!! input
+* <pre>foo</pre>
+* <pre>bar</pre>
+* zar
+!! result
+<ul><li> <pre>foo</pre>
+</li><li> <pre>bar</pre>
+</li><li> zar
+</li></ul>
+
+!! end
+
+###
+### Magic Words
+###
+
+!! test
+Magic Word: {{CURRENTDAY}}
+!! input
+{{CURRENTDAY}}
+!! result
+<p>1
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTDAY2}}
+!! input
+{{CURRENTDAY2}}
+!! result
+<p>01
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTDAYNAME}}
+!! input
+{{CURRENTDAYNAME}}
+!! result
+<p>Thursday
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTDOW}}
+!! input
+{{CURRENTDOW}}
+!! result
+<p>4
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTMONTH}}
+!! input
+{{CURRENTMONTH}}
+!! result
+<p>01
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTMONTHABBREV}}
+!! input
+{{CURRENTMONTHABBREV}}
+!! result
+<p>Jan
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTMONTHNAME}}
+!! input
+{{CURRENTMONTHNAME}}
+!! result
+<p>January
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTMONTHNAMEGEN}}
+!! input
+{{CURRENTMONTHNAMEGEN}}
+!! result
+<p>January
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTTIME}}
+!! input
+{{CURRENTTIME}}
+!! result
+<p>00:02
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTWEEK}} (@bug 4594)
+!! input
+{{CURRENTWEEK}}
+!! result
+<p>1
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTYEAR}}
+!! input
+{{CURRENTYEAR}}
+!! result
+<p>1970
+</p>
+!! end
+
+!! test
+Magic Word: {{FULLPAGENAME}}
+!! options
+title=[[User:Ævar Arnfjörð Bjarmason]]
+!! input
+{{FULLPAGENAME}}
+!! result
+<p>User:Ævar Arnfjörð Bjarmason
+</p>
+!! end
+
+!! test
+Magic Word: {{FULLPAGENAMEE}}
+!! options
+title=[[User:Ævar Arnfjörð Bjarmason]]
+!! input
+{{FULLPAGENAMEE}}
+!! result
+<p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
+</p>
+!! end
+
+!! test
+Magic Word: {{NAMESPACE}}
+!! options
+title=[[User:Ævar Arnfjörð Bjarmason]]
+disabled # FIXME
+!! input
+{{NAMESPACE}}
+!! result
+<p>User
+</p>
+!! end
+
+!! test
+Magic Word: {{NAMESPACEE}}
+!! options
+title=[[User:Ævar Arnfjörð Bjarmason]]
+disabled # FIXME
+!! input
+{{NAMESPACEE}}
+!! result
+<p>User
+</p>
+!! end
+
+!! test
+Magic Word: {{NUMBEROFARTICLES}}
+!! input
+{{NUMBEROFARTICLES}}
+!! result
+<p>1
+</p>
+!! end
+
+!! test
+Magic Word: {{NUMBEROFFILES}}
+!! input
+{{NUMBEROFFILES}}
+!! result
+<p>1
+</p>
+!! end
+
+!! test
+Magic Word: {{PAGENAME}}
+!! options
+title=[[User:Ævar Arnfjörð Bjarmason]]
+disabled # FIXME
+!! input
+{{PAGENAME}}
+!! result
+<p>Ævar Arnfjörð Bjarmason
+</p>
+!! end
+
+!! test
+Magic Word: {{PAGENAMEE}}
+!! options
+title=[[User:Ævar Arnfjörð Bjarmason]]
+!! input
+{{PAGENAMEE}}
+!! result
+<p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
+</p>
+!! end
+
+!! test
+Magic Word: {{REVISIONID}}
+!! input
+{{REVISIONID}}
+!! result
+<p>1337
+</p>
+!! end
+
+!! test
+Magic Word: {{SCRIPTPATH}}
+!! input
+{{SCRIPTPATH}}
+!! result
+<p>/
+</p>
+!! end
+
+!! test
+Magic Word: {{SERVER}}
+!! input
+{{SERVER}}
+!! result
+<p><a href="http://localhost" class="external free" title="http://localhost" rel="nofollow">http://localhost</a>
+</p>
+!! end
+
+!! test
+Magic Word: {{SERVERNAME}}
+!! input
+{{SERVERNAME}}
+!! result
+<p>Britney Spears
+</p>
+!! end
+
+!! test
+Magic Word: {{SITENAME}}
+!! input
+{{SITENAME}}
+!! result
+<p>MediaWiki
+</p>
+!! end
+
+!! test
+Namespace 1 {{ns:1}}
+!! input
+{{ns:1}}
+!! result
+<p>Talk
+</p>
+!! end
+
+!! test
+Namespace 1 {{ns:01}}
+!! input
+{{ns:01}}
+!! result
+<p>Talk
+</p>
+!! end
+
+!! test
+Namespace 0 {{ns:0}} (bug 4783)
+!! input
+{{ns:0}}
+!! result
+
+!! end
+
+!! test
+Namespace 0 {{ns:00}} (bug 4783)
+!! input
+{{ns:00}}
+!! result
+
+!! end
+
+!! test
+Namespace -1 {{ns:-1}}
+!! input
+{{ns:-1}}
+!! result
+<p>Special
+</p>
+!! end
+
+!! test
+Namespace Project {{ns:User}}
+!! input
+{{ns:User}}
+!! result
+<p>User
+</p>
+!! end
+
+
+###
+### Magic links
+###
+!! test
+Magic links: internal link to RFC (bug 479)
+!! input
+[[RFC 123]]
+!! result
+<p><a href="/index.php?title=RFC_123&amp;action=edit" class="new" title="RFC 123">RFC 123</a>
+</p>
+!! end
+
+!! test
+Magic links: RFC (bug 479)
+!! input
+RFC 822
+!! result
+<p><a href="http://www.ietf.org/rfc/rfc822.txt" class="external" title="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>
+</p>
+!! end
+
+!! test
+Magic links: ISBN (bug 1937)
+!! input
+ISBN 0-306-40615-2
+!! result
+<p><a href="/index.php?title=Special:Booksources&amp;isbn=0306406152" class="internal">ISBN 0-306-40615-2</a>
+</p>
+!! end
+
+!! test
+Magic links: PMID incorrectly converts space to underscore
+!! input
+PMID 1234
+!! result
+<p><a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&amp;db=pubmed&amp;dopt=Abstract&amp;list_uids=1234" class="external" title="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&amp;db=pubmed&amp;dopt=Abstract&amp;list_uids=1234">PMID 1234</a>
+</p>
+!! end
+
+###
+### Templates
+####
+
+!! test
+Nonexistant template
+!! input
+{{thistemplatedoesnotexist}}
+!! result
+<p><a href="/index.php?title=Template:Thistemplatedoesnotexist&amp;action=edit" class="new" title="Template:Thistemplatedoesnotexist">Template:Thistemplatedoesnotexist</a>
+</p>
+!! end
+
+!! article
+Template:test
+!! text
+This is a test template
+!! endarticle
+
+!! test
+Simple template
+!! input
+{{test}}
+!! result
+<p>This is a test template
+</p>
+!! end
+
+!! test
+Template with explicit namespace
+!! input
+{{Template:test}}
+!! result
+<p>This is a test template
+</p>
+!! end
+
+
+!! article
+Template:paramtest
+!! text
+This is a test template with parameter {{{param}}}
+!! endarticle
+
+!! test
+Template parameter
+!! input
+{{paramtest|param=foo}}
+!! result
+<p>This is a test template with parameter foo
+</p>
+!! end
+
+!! article
+Template:paramtestnum
+!! text
+[[{{{1}}}|{{{2}}}]]
+!! endarticle
+
+!! test
+Template unnamed parameter
+!! input
+{{paramtestnum|Main Page|the main page}}
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">the main page</a>
+</p>
+!! end
+
+!! article
+Template:templatesimple
+!! text
+(test)
+!! endarticle
+
+!! article
+Template:templateredirect
+!! text
+#redirect [[Template:templatesimple]]
+!! endarticle
+
+!! article
+Template:templateasargtestnum
+!! text
+{{{{{1}}}}}
+!! endarticle
+
+!! article
+Template:templateasargtest
+!! text
+{{template{{{templ}}}}}
+!! endarticle
+
+!! article
+Template:templateasargtest2
+!! text
+{{{{{templ}}}}}
+!! endarticle
+
+!! test
+Template with template name as unnamed argument
+!! input
+{{templateasargtestnum|templatesimple}}
+!! result
+<p>(test)
+</p>
+!! end
+
+!! test
+Template with template name as argument
+!! input
+{{templateasargtest|templ=simple}}
+!! result
+<p>(test)
+</p>
+!! end
+
+!! test
+Template with template name as argument (2)
+!! input
+{{templateasargtest2|templ=templatesimple}}
+!! result
+<p>(test)
+</p>
+!! end
+
+!! article
+Template:templateasargtestdefault
+!! text
+{{{{{templ|templatesimple}}}}}
+!! endarticle
+
+!! article
+Template:templa
+!! text
+'''templ'''
+!! endarticle
+
+!! test
+Template with default value
+!! input
+{{templateasargtestdefault}}
+!! result
+<p>(test)
+</p>
+!! end
+
+!! test
+Template with default value (value set)
+!! input
+{{templateasargtestdefault|templ=templa}}
+!! result
+<p><b>templ</b>
+</p>
+!! end
+
+!! test
+Template redirect
+!! input
+{{templateredirect}}
+!! result
+<p>(test)
+</p>
+!! end
+
+!! test
+Template with argument in separate line
+!! input
+{{ templateasargtest |
+ templ = simple }}
+!! result
+<p>(test)
+</p>
+!! end
+
+!! test
+Template with complex template as argument
+!! input
+{{paramtest|
+ param ={{ templateasargtest |
+ templ = simple }}}}
+!! result
+<p>This is a test template with parameter (test)
+</p>
+!! end
+
+!! test
+Template with thumb image (with link in description)
+!! input
+{{paramtest|
+ param =[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]}}
+!! result
+This is a test template with parameter <div class="thumb tright"><div class="thumbinner" style="width:122px;"><a href="/index.php?title=Special:Upload&amp;wpDestFile=Noimage.png" class="new" title="Image:Noimage.png">Image:Noimage.png</a> <div class="thumbcaption"><a href="/index.php?title=No_link&amp;action=edit" class="new" title="No link">link</a> <a href="/index.php?title=No_link&amp;action=edit" class="new" title="No link">caption</a></div></div></div>
+
+!! end
+
+!! article
+Template:complextemplate
+!! text
+{{{1}}} {{paramtest|
+ param ={{{param}}}}}
+!! endarticle
+
+!! test
+Template with complex arguments
+!! input
+{{complextemplate|
+ param ={{ templateasargtest |
+ templ = simple }}|[[Template:complextemplate|link]]}}
+!! result
+<p><a href="/wiki/Template:Complextemplate" title="Template:Complextemplate">link</a> This is a test template with parameter (test)
+</p>
+!! end
+
+!! test
+BUG 553: link with two variables in a piped link
+!! input
+{|
+|[[{{{1}}}|{{{2}}}]]
+|}
+!! result
+<table>
+<tr>
+<td>[[{{{1}}}|{{{2}}}]]
+</td></tr></table>
+
+!! end
+
+!! test
+Magic variable as template parameter
+!! input
+{{paramtest|param={{SITENAME}}}}
+!! result
+<p>This is a test template with parameter MediaWiki
+</p>
+!! end
+
+!! article
+Template:linktest
+!! text
+[[{{{param}}}|link]]
+!! endarticle
+
+!! test
+Template parameter as link source
+!! input
+{{linktest|param=Main Page}}
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">link</a>
+</p>
+!! end
+
+
+!!article
+Template:paramtest2
+!! text
+including another template, {{paramtest|param={{{arg}}}}}
+!! endarticle
+
+!! test
+Template passing argument to another template
+!! input
+{{paramtest2|arg='hmm'}}
+!! result
+<p>including another template, This is a test template with parameter 'hmm'
+</p>
+!! end
+
+!! article
+Template:Linktest2
+!! text
+Main Page
+!! endarticle
+
+!! test
+Template as link source
+!! input
+[[{{linktest2}}]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>
+</p>
+!! end
+
+
+!! article
+Template:loop1
+!! text
+{{loop2}}
+!! endarticle
+
+!! article
+Template:loop2
+!! text
+{{loop1}}
+!! endarticle
+
+!! test
+Template infinite loop
+!! input
+{{loop1}}
+!! result
+<p><a href="/index.php?title=Loop1&amp;action=edit" class="new" title="Loop1">loop1</a><!-- WARNING: template loop detected -->
+</p>
+!! end
+
+!! test
+Template from main namespace
+!! input
+{{:Main Page}}
+!! result
+<p>blah blah
+</p>
+!! end
+
+!! article
+Template:table
+!! text
+{|
+| 1 || 2
+|-
+| 3 || 4
+|}
+!! endarticle
+
+!! test
+BUG 529: Template with table, not included at beginning of line
+!! input
+foo {{table}}
+!! result
+<p>foo
+</p>
+<table>
+<tr>
+<td> 1 </td><td> 2
+</td></tr>
+<tr>
+<td> 3 </td><td> 4
+</td></tr></table>
+
+!! end
+
+!! test
+BUG 523: Template shouldn't eat newline (or add an extra one before table)
+!! input
+foo
+{{table}}
+!! result
+<p>foo
+</p>
+<table>
+<tr>
+<td> 1 </td><td> 2
+</td></tr>
+<tr>
+<td> 3 </td><td> 4
+</td></tr></table>
+
+!! end
+
+!! test
+BUG 41: Template parameters shown as broken links
+!! input
+{{{parameter}}}
+!! result
+<p>{{{parameter}}}
+</p>
+!! end
+
+
+!! article
+Template:MSGNW test
+!! text
+''None'' of '''this''' should be
+* interepreted
+ but rather passed unmodified
+{{test}}
+!! endarticle
+
+# hmm, fix this or just deprecate msgnw and document its behavior?
+!! test
+msgnw keyword
+!! options
+disabled
+!! input
+{{msgnw:MSGNW test}}
+!! result
+<p>''None'' of '''this''' should be
+* interepreted
+ but rather passed unmodified
+{{test}}
+</p>
+!! end
+
+!! test
+int keyword
+!! input
+{{int:youhavenewmessages|lots of money|not!}}
+!! result
+<p>You have lots of money (not!).
+</p>
+!! end
+
+!! article
+Template:Includes
+!! text
+Foo<noinclude>zar</noinclude><includeonly>bar</includeonly>
+!! endarticle
+
+!! test
+<includeonly> and <noinclude> being included
+!! input
+{{Includes}}
+!! result
+<p>Foobar
+</p>
+!! end
+
+!! article
+Template:Includes2
+!! text
+<onlyinclude>Foo</onlyinclude>bar
+!! endarticle
+
+!! test
+<onlyinclude> being included
+!! input
+{{Includes2}}
+!! result
+<p>Foo
+</p>
+!! end
+
+
+!! article
+Template:Includes3
+!! text
+<onlyinclude>Foo</onlyinclude>bar<includeonly>zar</includeonly>
+!! endarticle
+
+!! test
+<onlyinclude> and <includeonly> being included
+!! input
+{{Includes3}}
+!! result
+<p>Foo
+</p>
+!! end
+
+!! test
+<includeonly> and <noinclude> on a page
+!! input
+Foo<noinclude>zar</noinclude><includeonly>bar</includeonly>
+!! result
+<p>Foozar
+</p>
+!! end
+
+!! test
+<onlyinclude> on a page
+!! input
+<onlyinclude>Foo</onlyinclude>bar
+!! result
+<p>Foobar
+</p>
+!! end
+
+###
+### Pre-save transform tests
+###
+!! test
+pre-save transform: subst:
+!! options
+PST
+!! input
+{{subst:test}}
+!! result
+This is a test template
+!! end
+
+!! test
+pre-save transform: normal template
+!! options
+PST
+!! input
+{{test}}
+!! result
+{{test}}
+!! end
+
+!! test
+pre-save transform: nonexistant template
+!! options
+PST
+!! input
+{{thistemplatedoesnotexist}}
+!! result
+{{thistemplatedoesnotexist}}
+!! end
+
+
+!! test
+pre-save transform: subst magic variables
+!! options
+PST
+!! input
+{{subst:SITENAME}}
+!! result
+MediaWiki
+!! end
+
+# This is bug 89, which I fixed. -- wtm
+!! test
+pre-save transform: subst: templates with parameters
+!! options
+pst
+!! input
+{{subst:paramtest|param="something else"}}
+!! result
+This is a test template with parameter "something else"
+!! end
+
+!! article
+Template:nowikitest
+!! text
+<nowiki>'''not wiki'''</nowiki>
+!! endarticle
+
+!! test
+pre-save transform: nowiki in subst (bug 1188)
+!! options
+pst
+!! input
+{{subst:nowikitest}}
+!! result
+<nowiki>'''not wiki'''</nowiki>
+!! end
+
+
+!! article
+Template:commenttest
+!! text
+This template has <!-- a comment --> in it.
+!! endarticle
+
+!! test
+pre-save transform: comment in subst (bug 1936)
+!! options
+pst
+!! input
+{{subst:commenttest}}
+!! result
+This template has <!-- a comment --> in it.
+!! end
+
+!! test
+pre-save transform: unclosed tag
+!! options
+pst noxml
+!! input
+<nowiki>'''not wiki'''
+!! result
+<nowiki>'''not wiki'''
+!! end
+
+!! test
+pre-save transform: mixed tag case
+!! options
+pst noxml
+!! input
+<NOwiki>'''not wiki'''</noWIKI>
+!! result
+<NOwiki>'''not wiki'''</noWIKI>
+!! end
+
+!! test
+pre-save transform: unclosed comment in <nowiki>
+!! options
+pst noxml
+!! input
+wiki<nowiki>nowiki<!--nowiki</nowiki>wiki
+!! result
+wiki<nowiki>nowiki<!--nowiki</nowiki>wiki
+!!end
+
+!! article
+Template:dangerous
+!!text
+<span onmouseover="alert('crap')">Oh no</span>
+!!endarticle
+
+!!test
+(confirming safety of fix for subst bug 1936)
+!! input
+{{Template:dangerous}}
+!! result
+<p><span>Oh no</span>
+</p>
+!! end
+
+!! test
+pre-save transform: comment containing gallery (bug 5024)
+!! options
+pst
+!! input
+<!-- <gallery>data</gallery> -->
+!!result
+<!-- <gallery>data</gallery> -->
+!!end
+
+!! test
+pre-save transform: comment containing extension
+!! options
+pst
+!! input
+<!-- <tag>data</tag> -->
+!!result
+<!-- <tag>data</tag> -->
+!!end
+
+!! test
+pre-save transform: comment containing nowiki
+!! options
+pst
+!! input
+<!-- <nowiki>data</nowiki> -->
+!!result
+<!-- <nowiki>data</nowiki> -->
+!!end
+
+!! test
+pre-save transform: comment containing math
+!! options
+pst
+!! input
+<!-- <math>data</math> -->
+!!result
+<!-- <math>data</math> -->
+!!end
+
+!! test
+pre-save transform: <noinclude> in subst (bug 3298)
+!! options
+pst
+!! input
+{{subst:Includes}}
+!! result
+Foobar
+!! end
+
+!! test
+pre-save transform: <onlyinclude> in subst (bug 3298)
+!! options
+pst
+!! input
+{{subst:Includes2}}
+!! result
+Foo
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick")
+!! options
+pst
+!! input
+[[Article (context)|]]
+[[Bar:Article|]]
+[[:Bar:Article|]]
+[[Bar:Article (context)|]]
+[[:Bar:Article (context)|]]
+[[|Article]]
+[[|Article (context)]]
+[[Bar:X (Y) Z|]]
+[[:Bar:X (Y) Z|]]
+!! result
+[[Article (context)|Article]]
+[[Bar:Article|Article]]
+[[:Bar:Article|Article]]
+[[Bar:Article (context)|Article]]
+[[:Bar:Article (context)|Article]]
+[[Article]]
+[[Article (context)]]
+[[Bar:X (Y) Z|X (Y) Z]]
+[[:Bar:X (Y) Z|X (Y) Z]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with interwiki prefix
+!! options
+pst
+!! input
+[[interwiki:Article|]]
+[[:interwiki:Article|]]
+[[interwiki:Bar:Article|]]
+[[:interwiki:Bar:Article|]]
+!! result
+[[interwiki:Article|Article]]
+[[:interwiki:Article|Article]]
+[[interwiki:Bar:Article|Bar:Article]]
+[[:interwiki:Bar:Article|Bar:Article]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with parens in title
+!! options
+pst title=[[Somearticle (context)]]
+!! input
+[[|Article]]
+!! result
+[[Article (context)|Article]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with comma in title
+!! options
+pst title=[[Someplace, Somewhere]]
+!! input
+[[|Otherplace]]
+[[Otherplace, Elsewhere|]]
+[[Otherplace, Elsewhere, Anywhere|]]
+!! result
+[[Otherplace, Somewhere|Otherplace]]
+[[Otherplace, Elsewhere|Otherplace]]
+[[Otherplace, Elsewhere, Anywhere|Otherplace]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with parens and comma
+!! options
+pst title=[[Someplace (IGNORED), Somewhere]]
+!! input
+[[|Otherplace]]
+[[Otherplace (place), Elsewhere|]]
+!! result
+[[Otherplace, Somewhere|Otherplace]]
+[[Otherplace (place), Elsewhere|Otherplace]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with comma and parens
+!! options
+pst title=[[Who, me? (context)]]
+!! input
+[[|Yes, you.]]
+[[Me, Myself, and I (1937 song)|]]
+!! result
+[[Yes, you. (context)|Yes, you.]]
+[[Me, Myself, and I (1937 song)|Me, Myself, and I]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with namespace
+!! options
+pst title=[[Ns:Somearticle]]
+!! input
+[[|Article]]
+!! result
+[[Ns:Article|Article]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with namespace and parens
+!! options
+pst title=[[Ns:Somearticle (context)]]
+!! input
+[[|Article]]
+!! result
+[[Ns:Article (context)|Article]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with namespace and comma
+!! options
+pst title=[[Ns:Somearticle, Context, Whatever]]
+!! input
+[[|Article]]
+!! result
+[[Ns:Article, Context, Whatever|Article]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with namespace, comma and parens
+!! options
+pst title=[[Ns:Somearticle, Context (context)]]
+!! input
+[[|Article]]
+!! result
+[[Ns:Article (context)|Article]]
+!! end
+
+!! test
+pre-save transform: context links ("pipe trick") with namespace, parens and comma
+!! options
+pst title=[[Ns:Somearticle (IGNORED), Context]]
+!! input
+[[|Article]]
+!! result
+[[Ns:Article, Context|Article]]
+!! end
+
+
+###
+### Message transform tests
+###
+!! test
+message transform: magic variables
+!! options
+msg
+!! input
+{{SITENAME}}
+!! result
+MediaWiki
+!! end
+
+!! test
+message transform: should not transform wiki markup
+!! options
+msg
+!! input
+''test''
+!! result
+''test''
+!! end
+
+!! test
+TODO: message transform: <noinclude> in transcluded template (bug 4926)
+!! options
+msg
+!! input
+{{Includes}}
+!! result
+Foobar
+!! end
+
+!! test
+TODO: message transform: <onlyinclude> in transcluded template (bug 4926)
+!! options
+msg
+!! input
+{{Includes2}}
+!! result
+Foo
+!! end
+
+!! test
+{{#special:}} page name, known
+!! options
+msg
+!! input
+{{#special:Recentchanges}}
+!! result
+Special:Recentchanges
+!! end
+
+!! test
+{{#special:}} page name, unknown
+!! options
+msg
+!! input
+{{#special:foobarnonexistent}}
+!! result
+No such special page
+!! end
+
+###
+### Images
+###
+!! test
+Simple image
+!! input
+[[Image:foobar.jpg]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="Image:foobar.jpg"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="Image:foobar.jpg" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+Right-aligned image
+!! input
+[[Image:foobar.jpg|right]]
+!! result
+<div class="floatright"><span><a href="/wiki/Image:Foobar.jpg" class="image" title=""><img src="http://example.com/images/3/3a/Foobar.jpg" alt="" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a></span></div>
+
+!! end
+
+!! test
+Image with caption
+!! input
+[[Image:foobar.jpg|right|Caption text]]
+!! result
+<div class="floatright"><span><a href="/wiki/Image:Foobar.jpg" class="image" title="Caption text"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="Caption text" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a></span></div>
+
+!! end
+
+!! test
+Image with frame and link
+!! input
+[[Image:Foobar.jpg|frame|left|This is a test image [[Main Page]]]]
+!! result
+<div class="thumb tleft"><div class="thumbinner" style="width:1943px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="This is a test image Main Page"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="This is a test image Main Page" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption">This is a test image <a href="/wiki/Main_Page" title="Main Page">Main Page</a></div></div></div>
+
+!! end
+
+!! test
+Link to image page- image page normally doesn't exists, hence edit link
+TODO: Add test with existing image page
+#<p><a href="/wiki/Image:Test" title="Image:Test">Image:test</a>
+!! input
+[[:Image:test]]
+!! result
+<p><a href="/index.php?title=Image:Test&amp;action=edit" class="new" title="Image:Test">Image:test</a>
+</p>
+!! end
+
+!! test
+Frameless image caption with a free URL
+!! input
+[[Image:foobar.jpg|http://example.com]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="http://example.com"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="http://example.com" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+Thumbnail image caption with a free URL
+!! input
+[[Image:foobar.jpg|thumb|http://example.com]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="http://example.com"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="http://example.com" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a></div></div></div>
+
+!! end
+
+!! test
+BUG 1887: A ISBN with a thumbnail
+!! input
+[[Image:foobar.jpg|thumb|ISBN 1235467890]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="ISBN 1235467890"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="ISBN 1235467890" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a href="/index.php?title=Special:Booksources&amp;isbn=1235467890" class="internal">ISBN 1235467890</a></div></div></div>
+
+!! end
+
+!! test
+BUG 1887: A RFC with a thumbnail
+!! input
+[[Image:foobar.jpg|thumb|This is RFC 12354]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="This is RFC 12354"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="This is RFC 12354" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is <a href="http://www.ietf.org/rfc/rfc12354.txt" class="external" title="http://www.ietf.org/rfc/rfc12354.txt">RFC 12354</a></div></div></div>
+
+!! end
+
+!! test
+BUG 1887: A mailto link with a thumbnail
+!! input
+[[Image:foobar.jpg|thumb|Please mailto:nobody@example.com]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Please mailto:nobody@example.com"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="Please mailto:nobody@example.com" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Please <a href="mailto:nobody@example.com" class="external free" title="mailto:nobody@example.com" rel="nofollow">mailto:nobody@example.com</a></div></div></div>
+
+!! end
+
+!! test
+BUG 1887: A <math> with a thumbnail- we don't render math in the parsertests by default,
+so math is not stripped and turns up as escaped &lt;math&gt; tags.
+!! input
+[[Image:foobar.jpg|thumb|<math>2+2</math>]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="&lt;math&gt;2+2&lt;/math&gt;"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="&lt;math&gt;2+2&lt;/math&gt;" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>&lt;math&gt;2+2&lt;/math&gt;</div></div></div>
+
+!! end
+
+!! test
+BUG 1887, part 2: A <math> with a thumbnail- math enabled
+!! options
+math
+!! input
+[[Image:foobar.jpg|thumb|<math>2+2</math>]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="2 + 2"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="2 + 2" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><span class="texhtml">2 + 2</span></div></div></div>
+
+!! end
+
+# Pending resolution to bug 368
+!! test
+BUG 648: Frameless image caption with a link
+!! input
+[[Image:foobar.jpg|text with a [[link]] in it]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="text with a link in it"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="text with a link in it" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+BUG 648: Frameless image caption with a link (suffix)
+!! input
+[[Image:foobar.jpg|text with a [[link]]foo in it]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="text with a linkfoo in it"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="text with a linkfoo in it" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+BUG 648: Frameless image caption with an interwiki link
+!! input
+[[Image:foobar.jpg|text with a [[MeatBall:Link]] in it]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="text with a MeatBall:Link in it"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="text with a MeatBall:Link in it" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+BUG 648: Frameless image caption with a piped interwiki link
+!! input
+[[Image:foobar.jpg|text with a [[MeatBall:Link|link]] in it]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="text with a link in it"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="text with a link in it" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+Escape HTML special chars in image alt text
+!! input
+[[Image:foobar.jpg|& < > "]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="&amp; &lt; &gt; &quot;"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="&amp; &lt; &gt; &quot;" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+BUG 499: Alt text should have &#1234;, not &amp;1234;
+!! input
+[[Image:foobar.jpg|&#9792;]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="&#9792;"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="&#9792;" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!! end
+
+!! test
+Broken image caption with link
+!! input
+[[Image:Foobar.jpg|thumb|This is a broken caption. But [[Main Page|this]] is just an ordinary link.
+!! result
+<p>[[Image:Foobar.jpg|thumb|This is a broken caption. But <a href="/wiki/Main_Page" title="Main Page">this</a> is just an ordinary link.
+</p>
+!! end
+
+!! test
+Image caption containing another image
+!! input
+[[Image:Foobar.jpg|thumb|This is a caption with another [[Image:icon.png|image]] inside it!]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="This is a caption with another Image:Icon.png inside it!"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="This is a caption with another Image:Icon.png inside it!" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is a caption with another <a href="/index.php?title=Special:Upload&amp;wpDestFile=Icon.png" class="new" title="Image:Icon.png">Image:Icon.png</a> inside it!</div></div></div>
+
+!! end
+
+!! test
+Image caption containing a newline
+!! input
+[[Image:Foobar.jpg|This
+*is some text]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title="This *is some text"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="This *is some text" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!!end
+
+
+!! test
+Bug 3090: External links other than http: in image captions
+!! input
+[[Image:Foobar.jpg|thumb|200px|This caption has [irc://example.net irc] and [https://example.com Secure] ext links in it.]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="This caption has irc and Secure ext links in it."><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" alt="This caption has irc and Secure ext links in it." width="200" height="23" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This caption has <a href="irc://example.net" class="external text" title="irc://example.net" rel="nofollow">irc</a> and <a href="https://example.com" class="external text" title="https://example.com" rel="nofollow">Secure</a> ext links in it.</div></div></div>
+
+!! end
+
+
+###
+### Subpages
+###
+!! article
+Subpage test/subpage
+!! text
+foo
+!! endarticle
+
+!! test
+Subpage link
+!! options
+subpage title=[[Subpage test]]
+!! input
+[[/subpage]]
+!! result
+<p><a href="/wiki/Subpage_test/subpage" title="Subpage test/subpage">/subpage</a>
+</p>
+!! end
+
+!! test
+Subpage noslash link
+!! options
+subpage title=[[Subpage test]]
+!!input
+[[/subpage/]]
+!! result
+<p><a href="/wiki/Subpage_test/subpage" title="Subpage test/subpage">subpage</a>
+</p>
+!! end
+
+!! test
+Disabled subpages
+!! input
+[[/subpage]]
+!! result
+<p><a href="/index.php?title=/subpage&amp;action=edit" class="new" title="/subpage">/subpage</a>
+</p>
+!! end
+
+!! test
+BUG 561: {{/Subpage}}
+!! options
+subpage title=[[Page]]
+!! input
+{{/Subpage}}
+!! result
+<p><a href="/index.php?title=Page/Subpage&amp;action=edit" class="new" title="Page/Subpage">Page/Subpage</a>
+</p>
+!! end
+
+###
+### Categories
+###
+!! article
+Category:MediaWiki User's Guide
+!! text
+blah
+!! endarticle
+
+!! test
+Link to category
+!! input
+[[:Category:MediaWiki User's Guide]]
+!! result
+<p><a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">Category:MediaWiki User's Guide</a>
+</p>
+!! end
+
+!! test
+Simple category
+!! options
+cat
+!! input
+[[Category:MediaWiki User's Guide]]
+!! result
+<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a>
+!! end
+
+###
+### Inter-language links
+###
+!! test
+Inter-language links
+!! options
+ill
+!! input
+[[es:Alimento]]
+[[fr:Nourriture]]
+[[zh:&#39135;&#21697;]]
+!! result
+es:Alimento fr:Nourriture zh:食品
+!! end
+
+###
+### Sections
+###
+!! test
+Basic section headings
+!! input
+== Headline 1 ==
+Some text
+
+==Headline 2==
+More
+===Smaller headline===
+Blah blah
+!! result
+<a name="Headline_1"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline"> Headline 1 </span></h2>
+<p>Some text
+</p>
+<a name="Headline_2"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline">Headline 2</span></h2>
+<p>More
+</p>
+<a name="Smaller_headline"></a><h3><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Smaller headline">edit</a>]</span> <span class="mw-headline">Smaller headline</span></h3>
+<p>Blah blah
+</p>
+!! end
+
+!! test
+Section headings with TOC
+!! input
+== Headline 1 ==
+=== Subheadline 1 ===
+===== Skipping a level =====
+====== Skipping a level ======
+
+== Headline 2 ==
+Some text
+===Another headline===
+!! result
+<table id="toc" class="toc" summary="Contents"><tr><td><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1"><a href="#Headline_1"><span class="tocnumber">1</span> <span class="toctext">Headline 1</span></a>
+<ul>
+<li class="toclevel-2"><a href="#Subheadline_1"><span class="tocnumber">1.1</span> <span class="toctext">Subheadline 1</span></a>
+<ul>
+<li class="toclevel-3"><a href="#Skipping_a_level"><span class="tocnumber">1.1.1</span> <span class="toctext">Skipping a level</span></a>
+<ul>
+<li class="toclevel-4"><a href="#Skipping_a_level_2"><span class="tocnumber">1.1.1.1</span> <span class="toctext">Skipping a level</span></a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+<li class="toclevel-1"><a href="#Headline_2"><span class="tocnumber">2</span> <span class="toctext">Headline 2</span></a>
+<ul>
+<li class="toclevel-2"><a href="#Another_headline"><span class="tocnumber">2.1</span> <span class="toctext">Another headline</span></a></li>
+</ul>
+</li>
+</ul>
+</td></tr></table><script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>
+<a name="Headline_1"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline"> Headline 1 </span></h2>
+<a name="Subheadline_1"></a><h3><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Subheadline 1">edit</a>]</span> <span class="mw-headline"> Subheadline 1 </span></h3>
+<a name="Skipping_a_level"></a><h5><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline"> Skipping a level </span></h5>
+<a name="Skipping_a_level_2"></a><h6><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline"> Skipping a level </span></h6>
+<a name="Headline_2"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline"> Headline 2 </span></h2>
+<p>Some text
+</p>
+<a name="Another_headline"></a><h3><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Another headline">edit</a>]</span> <span class="mw-headline">Another headline</span></h3>
+
+!! end
+
+# perl -e 'print "="x$_," Level $_ heading","="x$_,"\n" for 1..10'
+!! test
+Handling of sections up to level 6 and beyond
+!! input
+= Level 1 Heading=
+== Level 2 Heading==
+=== Level 3 Heading===
+==== Level 4 Heading====
+===== Level 5 Heading=====
+====== Level 6 Heading======
+======= Level 7 Heading=======
+======== Level 8 Heading========
+========= Level 9 Heading=========
+========== Level 10 Heading==========
+!! result
+<table id="toc" class="toc" summary="Contents"><tr><td><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1"><a href="#Level_1_Heading"><span class="tocnumber">1</span> <span class="toctext">Level 1 Heading</span></a>
+<ul>
+<li class="toclevel-2"><a href="#Level_2_Heading"><span class="tocnumber">1.1</span> <span class="toctext">Level 2 Heading</span></a>
+<ul>
+<li class="toclevel-3"><a href="#Level_3_Heading"><span class="tocnumber">1.1.1</span> <span class="toctext">Level 3 Heading</span></a>
+<ul>
+<li class="toclevel-4"><a href="#Level_4_Heading"><span class="tocnumber">1.1.1.1</span> <span class="toctext">Level 4 Heading</span></a>
+<ul>
+<li class="toclevel-5"><a href="#Level_5_Heading"><span class="tocnumber">1.1.1.1.1</span> <span class="toctext">Level 5 Heading</span></a>
+<ul>
+<li class="toclevel-6"><a href="#Level_6_Heading"><span class="tocnumber">1.1.1.1.1.1</span> <span class="toctext">Level 6 Heading</span></a></li>
+<li class="toclevel-6"><a href="#.3D_Level_7_Heading.3D"><span class="tocnumber">1.1.1.1.1.2</span> <span class="toctext">= Level 7 Heading=</span></a></li>
+<li class="toclevel-6"><a href="#.3D.3D_Level_8_Heading.3D.3D"><span class="tocnumber">1.1.1.1.1.3</span> <span class="toctext">== Level 8 Heading==</span></a></li>
+<li class="toclevel-6"><a href="#.3D.3D.3D_Level_9_Heading.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.4</span> <span class="toctext">=== Level 9 Heading===</span></a></li>
+<li class="toclevel-6"><a href="#.3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.5</span> <span class="toctext">==== Level 10 Heading====</span></a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</td></tr></table><script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>
+<a name="Level_1_Heading"></a><h1><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Level 1 Heading">edit</a>]</span> <span class="mw-headline"> Level 1 Heading</span></h1>
+<a name="Level_2_Heading"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Level 2 Heading">edit</a>]</span> <span class="mw-headline"> Level 2 Heading</span></h2>
+<a name="Level_3_Heading"></a><h3><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Level 3 Heading">edit</a>]</span> <span class="mw-headline"> Level 3 Heading</span></h3>
+<a name="Level_4_Heading"></a><h4><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Level 4 Heading">edit</a>]</span> <span class="mw-headline"> Level 4 Heading</span></h4>
+<a name="Level_5_Heading"></a><h5><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: Level 5 Heading">edit</a>]</span> <span class="mw-headline"> Level 5 Heading</span></h5>
+<a name="Level_6_Heading"></a><h6><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Level 6 Heading">edit</a>]</span> <span class="mw-headline"> Level 6 Heading</span></h6>
+<a name=".3D_Level_7_Heading.3D"></a><h6><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=7" title="Edit section: = Level 7 Heading=">edit</a>]</span> <span class="mw-headline">= Level 7 Heading=</span></h6>
+<a name=".3D.3D_Level_8_Heading.3D.3D"></a><h6><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=8" title="Edit section: == Level 8 Heading==">edit</a>]</span> <span class="mw-headline">== Level 8 Heading==</span></h6>
+<a name=".3D.3D.3D_Level_9_Heading.3D.3D.3D"></a><h6><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=9" title="Edit section: === Level 9 Heading===">edit</a>]</span> <span class="mw-headline">=== Level 9 Heading===</span></h6>
+<a name=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D"></a><h6><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=10" title="Edit section: ==== Level 10 Heading====">edit</a>]</span> <span class="mw-headline">==== Level 10 Heading====</span></h6>
+
+!! end
+
+!! test
+Resolving duplicate section names
+!! input
+== Foo bar ==
+== Foo bar ==
+!! result
+<a name="Foo_bar"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline"> Foo bar </span></h2>
+<a name="Foo_bar_2"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline"> Foo bar </span></h2>
+
+!! end
+
+!! article
+Template:sections
+!! text
+===Section 1===
+==Section 2==
+!! endarticle
+
+!! test
+Template with sections, __NOTOC__
+!! input
+__NOTOC__
+==Section 0==
+{{sections}}
+==Section 4==
+!! result
+<a name="Section_0"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Section 0">edit</a>]</span> <span class="mw-headline">Section 0</span></h2>
+<a name="Section_1"></a><h3><span class="editsection">[<a href="/index.php?title=Template:Sections&amp;action=edit&amp;section=1" title="Template:Sections">edit</a>]</span> <span class="mw-headline">Section 1</span></h3>
+<a name="Section_2"></a><h2><span class="editsection">[<a href="/index.php?title=Template:Sections&amp;action=edit&amp;section=2" title="Template:Sections">edit</a>]</span> <span class="mw-headline">Section 2</span></h2>
+<a name="Section_4"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Section 4">edit</a>]</span> <span class="mw-headline">Section 4</span></h2>
+
+!! end
+
+!! test
+__NOEDITSECTION__ keyword
+!! input
+__NOEDITSECTION__
+==Section 1==
+==Section 2==
+!! result
+<a name="Section_1"></a><h2> <span class="mw-headline">Section 1</span></h2>
+<a name="Section_2"></a><h2> <span class="mw-headline">Section 2</span></h2>
+
+!! end
+
+!! test
+Link inside a section heading
+!! input
+==Section with a [[Main Page|link]] in it==
+!! result
+<a name="Section_with_a_link_in_it"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Section with a link in it">edit</a>]</span> <span class="mw-headline">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span></h2>
+
+!! end
+
+
+!! test
+BUG 1219 URL next to image (good)
+!! input
+http://example.com [[Image:foobar.jpg]]
+!! result
+<p><a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a> <a href="/wiki/Image:Foobar.jpg" class="image" title="Image:foobar.jpg"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="Image:foobar.jpg" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!!end
+
+!! test
+BUG 1219 URL next to image (broken)
+!! input
+http://example.com[[Image:foobar.jpg]]
+!! result
+<p><a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a><a href="/wiki/Image:Foobar.jpg" class="image" title="Image:foobar.jpg"><img src="http://example.com/images/3/3a/Foobar.jpg" alt="Image:foobar.jpg" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!!end
+
+!! test
+Bug 1186 news: in the middle of text
+!! input
+http://en.wikinews.org/wiki/Wikinews:Workplace
+!! result
+<p><a href="http://en.wikinews.org/wiki/Wikinews:Workplace" class="external free" title="http://en.wikinews.org/wiki/Wikinews:Workplace" rel="nofollow">http://en.wikinews.org/wiki/Wikinews:Workplace</a>
+</p>
+!!end
+
+
+!! test
+Namespaced link must have a title
+!! input
+[[Project:]]
+!! result
+<p>[[Project:]]
+</p>
+!!end
+
+!! test
+Namespaced link must have a title (bad fragment version)
+!! input
+[[Project:#fragment]]
+!! result
+<p>[[Project:#fragment]]
+</p>
+!!end
+
+
+!! test
+div with no attributes
+!! input
+<div>HTML rocks</div>
+!! result
+<div>HTML rocks</div>
+
+!! end
+
+!! test
+div with double-quoted attribute
+!! input
+<div id="rock">HTML rocks</div>
+!! result
+<div id="rock">HTML rocks</div>
+
+!! end
+
+!! test
+div with single-quoted attribute
+!! input
+<div id='rock'>HTML rocks</div>
+!! result
+<div id="rock">HTML rocks</div>
+
+!! end
+
+!! test
+div with unquoted attribute
+!! input
+<div id=rock>HTML rocks</div>
+!! result
+<div id="rock">HTML rocks</div>
+
+!! end
+
+!! test
+div with illegal double attributes
+!! input
+<div align="center" align="right">HTML rocks</div>
+!! result
+<div align="right">HTML rocks</div>
+
+!!end
+
+!! test
+HTML multiple attributes correction
+!! input
+<p class="error" class="awesome">Awesome!</p>
+!! result
+<p class="awesome">Awesome!</p>
+
+!!end
+
+!! test
+Table multiple attributes correction
+!! input
+{|
+!+ class="error" class="awesome"| status
+|}
+!! result
+<table>
+<tr>
+<th class="awesome"> status
+</th></tr></table>
+
+!!end
+
+!! test
+DIV IN UPPERCASE
+!! input
+<DIV ALIGN="center">HTML ROCKS</DIV>
+!! result
+<div align="center">HTML ROCKS</div>
+
+!!end
+
+
+!! test
+text with amp in the middle of nowhere
+!! input
+Remember AT&T?
+!!result
+<p>Remember AT&amp;T?
+</p>
+!! end
+
+!! test
+text with character entity: eacute
+!! input
+I always thought &eacute; was a cute letter.
+!! result
+<p>I always thought &eacute; was a cute letter.
+</p>
+!! end
+
+!! test
+text with undefined character entity: xacute
+!! input
+I always thought &xacute; was a cute letter.
+!! result
+<p>I always thought &amp;xacute; was a cute letter.
+</p>
+!! end
+
+
+###
+### Media links
+###
+
+!! test
+Media link
+!! input
+[[Media:Foobar.jpg]]
+!! result
+<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Media:Foobar.jpg</a>
+</p>
+!! end
+
+!! test
+Media link with text
+!! input
+[[Media:Foobar.jpg|A neat file to look at]]
+!! result
+<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">A neat file to look at</a>
+</p>
+!! end
+
+# FIXME: this is still bad HTML tag nesting
+!! test
+Media link with nasty text
+fixme: doBlockLevels won't wrap this in a paragraph because it contains a div
+!! input
+[[Media:Foobar.jpg|Safe Link<div style=display:none>" onmouseover="alert(document.cookie)" onfoo="</div>]]
+!! result
+<a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link&lt;div style="display:none"&gt;" onmouseover="alert(document.cookie)" onfoo="&lt;/div&gt;</a>
+
+!! end
+
+!! test
+Media link to nonexistent file (bug 1702)
+!! input
+[[Media:No such.jpg]]
+!! result
+<p><a href="/index.php?title=Special:Upload&amp;wpDestFile=No_such.jpg" class="new" title="No such.jpg">Media:No such.jpg</a>
+</p>
+!! end
+
+!! test
+Image link to nonexistent file (bug 1850 - good)
+!! input
+[[Image:No such.jpg]]
+!! result
+<p><a href="/index.php?title=Special:Upload&amp;wpDestFile=No_such.jpg" class="new" title="Image:No such.jpg">Image:No such.jpg</a>
+</p>
+!! end
+
+!! test
+:Image link to nonexistent file (bug 1850 - bad)
+!! input
+[[:Image:No such.jpg]]
+!! result
+<p><a href="/index.php?title=Image:No_such.jpg&amp;action=edit" class="new" title="Image:No such.jpg">Image:No such.jpg</a>
+</p>
+!! end
+
+
+
+!! test
+Character reference normalization in link text (bug 1938)
+!! input
+[[Main Page|this&that]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">this&amp;that</a>
+</p>
+!!end
+
+!! test
+Empty attribute crash test (bug 2067)
+!! input
+<font color="">foo</font>
+!! result
+<p><font color="">foo</font>
+</p>
+!! end
+
+!! test
+Empty attribute crash test single-quotes (bug 2067)
+!! input
+<font color=''>foo</font>
+!! result
+<p><font color="">foo</font>
+</p>
+!! end
+
+!! test
+Attribute test: equals, then nothing
+!! input
+<font color=>foo</font>
+!! result
+<p><font>foo</font>
+</p>
+!! end
+
+!! test
+Attribute test: unquoted value
+!! input
+<font color=x>foo</font>
+!! result
+<p><font color="x">foo</font>
+</p>
+!! end
+
+!! test
+Attribute test: unquoted but illegal value (hash)
+!! input
+<font color=#x>foo</font>
+!! result
+<p><font color="#x">foo</font>
+</p>
+!! end
+
+!! test
+Attribute test: no value
+!! input
+<font color>foo</font>
+!! result
+<p><font color="color">foo</font>
+</p>
+!! end
+
+!! test
+Bug 2095: link with three closing brackets
+!! input
+[[Main Page]]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>]
+</p>
+!! end
+
+!! test
+Bug 2095: link with pipe and three closing brackets
+!! input
+[[Main Page|link]]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">link</a>]
+</p>
+!! end
+
+!! test
+Bug 2095: link with pipe and three closing brackets, version 2
+!! input
+[[Main Page|[http://example.com/]]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">[http://example.com/]</a>
+</p>
+!! end
+
+
+###
+### Safety
+###
+
+!! article
+Template:Dangerous attribute
+!! text
+" onmouseover="alert(document.cookie)
+!! endarticle
+
+!! article
+Template:Dangerous style attribute
+!! text
+border-size: expression(alert(document.cookie))
+!! endarticle
+
+!! article
+Template:Div style
+!! text
+<div style="float: right; {{{1}}}">Magic div</div>
+!! endarticle
+
+!! test
+Bug 2304: HTML attribute safety (safe template; regression bug 2309)
+!! input
+<div title="{{test}}"></div>
+!! result
+<div title="This is a test template"></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (dangerous template; 2309)
+!! input
+<div title="{{dangerous attribute}}"></div>
+!! result
+<div title=""></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (dangerous style template; 2309)
+!! input
+<div style="{{dangerous style attribute}}"></div>
+!! result
+<div></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (safe parameter; 2309)
+!! input
+{{div style|width: 200px}}
+!! result
+<div style="float: right; width: 200px">Magic div</div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (unsafe parameter; 2309)
+!! input
+{{div style|width: expression(alert(document.cookie))}}
+!! result
+<div>Magic div</div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (unsafe breakout parameter; 2309)
+!! input
+{{div style|"><script>alert(document.cookie)</script>}}
+!! result
+<div>Magic div</div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (unsafe breakout parameter 2; 2309)
+!! input
+{{div style|" ><script>alert(document.cookie)</script>}}
+!! result
+<div style="float: right;">Magic div</div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (link)
+!! input
+<div title="[[Main Page]]"></div>
+!! result
+<div title="&#91;&#91;Main Page]]"></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (italics)
+!! input
+<div title="''foobar''"></div>
+!! result
+<div title="&#39;&#39;foobar&#39;&#39;"></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (bold)
+!! input
+<div title="'''foobar'''"></div>
+!! result
+<div title="&#39;&#39;'foobar&#39;&#39;'"></div>
+
+!! end
+
+
+!! test
+Bug 2304: HTML attribute safety (ISBN)
+!! input
+<div title="ISBN 1234567890"></div>
+!! result
+<div title="&#73;SBN 1234567890"></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (RFC)
+!! input
+<div title="RFC 1234"></div>
+!! result
+<div title="&#82;FC 1234"></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (PMID)
+!! input
+<div title="PMID 1234567890"></div>
+!! result
+<div title="&#80;MID 1234567890"></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (web link)
+!! input
+<div title="http://example.com/"></div>
+!! result
+<div title="http&#58;//example.com/"></div>
+
+!! end
+
+!! test
+Bug 2304: HTML attribute safety (named web link)
+!! input
+<div title="[http://example.com/ link]"></div>
+!! result
+<div title="&#91;http&#58;//example.com/ link]"></div>
+
+!! end
+
+!! test
+Bug 3244: HTML attribute safety (extension; safe)
+!! input
+<div style="<nowiki>background:blue</nowiki>"></div>
+!! result
+<div style="background:blue"></div>
+
+!! end
+
+!! test
+Bug 3244: HTML attribute safety (extension; unsafe)
+!! input
+<div style="<nowiki>border-left:expression(alert(document.cookie))</nowiki>"></div>
+!! result
+<div></div>
+
+!! end
+
+!! test
+Math section safety when disabled
+!! input
+<math><script>alert(document.cookies);</script></math>
+!! result
+<p>&lt;math&gt;&lt;script&gt;alert(document.cookies);&lt;/script&gt;&lt;/math&gt;
+</p>
+!! end
+
+# More MSIE fun discovered by Tom Gilder
+
+!! test
+MSIE CSS safety test: spurious slash
+!! input
+<div style="background-image:u\rl(javascript:alert('boo'))">evil</div>
+!! result
+<div>evil</div>
+
+!! end
+
+!! test
+MSIE CSS safety test: hex code
+!! input
+<div style="background-image:u\72l(javascript:alert('boo'))">evil</div>
+!! result
+<div>evil</div>
+
+!! end
+
+!! test
+MSIE CSS safety test: comment in url
+!! input
+<div style="background-image:u/**/rl(javascript:alert('boo'))">evil</div>
+!! result
+<div style="background-image:u rl(javascript:alert('boo'))">evil</div>
+
+!! end
+
+!! test
+MSIE CSS safety test: comment in expression
+!! input
+<div style="background-image:expres/**/sion(alert('boo4'))">evil4</div>
+!! result
+<div style="background-image:expres sion(alert('boo4'))">evil4</div>
+
+!! end
+
+
+!! test
+Table attribute legitimate extension
+!! input
+{|
+!+ style="<nowiki>color:blue</nowiki>"| status
+|}
+!! result
+<table>
+<tr>
+<th style="color:blue"> status
+</th></tr></table>
+
+!!end
+
+!! test
+Table attribute safety
+!! input
+{|
+!+ style="<nowiki>border-width:expression(0+alert(document.cookie))</nowiki>"| status
+|}
+!! result
+<table>
+<tr>
+<th> status
+</th></tr></table>
+
+!! end
+
+
+!! article
+Template:Identity
+!! text
+{{{1}}}
+!! endarticle
+
+!! test
+Expansion of multi-line templates in attribute values (bug 6255)
+!! input
+<div style="background: {{identity|#00FF00}}">-</div>
+!! result
+<div style="background: #00FF00">-</div>
+
+!! end
+
+
+!! test
+Expansion of multi-line templates in attribute values (bug 6255 sanity check)
+!! input
+<div style="background:
+#00FF00">-</div>
+!! result
+<div style="background: #00FF00">-</div>
+
+!! end
+
+!! test
+Expansion of multi-line templates in attribute values (bug 6255 sanity check 2)
+!! input
+<div style="background: &#10;#00FF00">-</div>
+!! result
+<div style="background: &#10;#00FF00">-</div>
+
+!! end
+
+###
+### Parser hooks (see maintenance/parserTestsParserHook.php for the <tag> extension)
+###
+!! test
+Parser hook: empty input
+!! input
+<tag></tag>
+!! result
+<pre>
+string(0) ""
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: empty input using terminated empty elements
+!! input
+<tag/>
+!! result
+<pre>
+NULL
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: empty input using terminated empty elements (space before)
+!! input
+<tag />
+!! result
+<pre>
+NULL
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: basic input
+!! input
+<tag>input</tag>
+!! result
+<pre>
+string(5) "input"
+array(0) {
+}
+</pre>
+
+!! end
+
+
+!! test
+Parser hook: case insensetive
+!! input
+<TAG>input</TAG>
+!! result
+<pre>
+string(5) "input"
+array(0) {
+}
+</pre>
+
+!! end
+
+
+!! test
+Parser hook: case insensetive, redux
+!! input
+<TaG>input</TAg>
+!! result
+<pre>
+string(5) "input"
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: nested tags
+!! options
+noxml
+!! input
+<tag><tag></tag></tag>
+!! result
+<pre>
+string(5) "<tag>"
+array(0) {
+}
+</pre>&lt;/tag&gt;
+
+!! end
+
+!! test
+Parser hook: basic arguments
+!! input
+<tag width=200 height = "100" depth = '50' square></tag>
+!! result
+<pre>
+string(0) ""
+array(4) {
+ ["width"]=>
+ string(3) "200"
+ ["height"]=>
+ string(3) "100"
+ ["depth"]=>
+ string(2) "50"
+ ["square"]=>
+ string(6) "square"
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: argument containing a forward slash (bug 5344)
+!! input
+<tag filename='/tmp/bla'></tag>
+!! result
+<pre>
+string(0) ""
+array(1) {
+ ["filename"]=>
+ string(8) "/tmp/bla"
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: empty input using terminated empty elements (bug 2374)
+!! input
+<tag foo=bar/>text
+!! result
+<pre>
+NULL
+array(1) {
+ ["foo"]=>
+ string(3) "bar"
+}
+</pre>text
+
+!! end
+
+# </tag> should be output literally since there is no matching tag that begins it
+!! test
+Parser hook: basic arguments using terminated empty elements (bug 2374)
+!! input
+<tag width=200 height = "100" depth = '50' square/>
+other stuff
+</tag>
+!! result
+<pre>
+NULL
+array(4) {
+ ["width"]=>
+ string(3) "200"
+ ["height"]=>
+ string(3) "100"
+ ["depth"]=>
+ string(2) "50"
+ ["square"]=>
+ string(6) "square"
+}
+</pre>
+<p>other stuff
+&lt;/tag&gt;
+</p>
+!! end
+
+###
+### (see maintenance/parserTestsStaticParserHook.php for the <statictag> extension)
+###
+
+!! test
+Parser hook: static parser hook not inside a comment
+!! input
+<statictag>hello, world</statictag>
+<statictag action=flush/>
+!! result
+<p>hello, world
+</p>
+!! end
+
+
+!! test
+Parser hook: static parser hook inside a comment
+!! input
+<!-- <statictag>hello, world</statictag> -->
+<statictag action=flush/>
+!! result
+<p><br />
+</p>
+!! end
+
+# Nested template calls; this case was broken by Parser.php rev 1.506,
+# since reverted.
+
+!! article
+Template:One-parameter
+!! text
+(My parameter is: {{{1}}})
+!! endarticle
+
+!! article
+Template:Map-one-parameter
+!! text
+{{{{{1}}}|{{{2}}}}}
+!! endarticle
+
+!! test
+Nested template calls
+!! input
+{{Map-one-parameter|One-parameter|param}}
+!! result
+<p>(My parameter is: param)
+</p>
+!! end
+
+
+###
+### Sanitizer
+###
+!! test
+Sanitizer: Closing of open tags
+!! input
+<s></s><table></table>
+!! result
+<s></s><table></table>
+
+!! end
+
+!! test
+Sanitizer: Closing of open but not closed tags
+!! input
+<s>foo
+!! result
+<p><s>foo</s>
+</p>
+!! end
+
+!! test
+Sanitizer: Closing of closed but not open tags
+!! input
+</s>
+!! result
+<p>&lt;/s&gt;
+</p>
+!! end
+
+!! test
+Sanitizer: Closing of closed but not open table tags
+!! input
+Table not started</td></tr></table>
+!! result
+<p>Table not started&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
+</p>
+!! end
+
+!! test
+Sanitizer: Escaping of spaces, multibyte characters, colons & other stuff in id=""
+!! input
+<span id="æ: v">byte</span>[[#æ: v|backlink]]
+!! result
+<p><span id=".C3.A6:_v">byte</span><a href="#.C3.A6:_v" title="">backlink</a>
+</p>
+!! end
+
+!! test
+Sanitizer: Validating the contents of the id attribute (bug 4515)
+!! options
+disabled
+!! input
+<br id=9 />
+!! result
+Something, but defenetly not <br id="9" />...
+!! end
+
+!! test
+Sanitizer: Validating id attribute uniqueness (bug 4515, bug 6301)
+!! options
+disabled
+!! input
+<br id="foo" /><br id="foo" />
+!! result
+Something need to be done. foo-2 ?
+!! end
+
+!! test
+Language converter: output gets cut off unexpectedly (bug 5757)
+!! options
+language=zh
+!! input
+this bit is safe: }-
+
+but if we add a conversion instance: -{zh-cn:xxx;zh-tw:yyy}-
+
+then we get cut off here: }-
+
+all additional text is vanished
+!! result
+<p>this bit is safe: }-
+</p><p>but if we add a conversion instance: xxx
+</p><p>then we get cut off here: }-
+</p><p>all additional text is vanished
+</p>
+!! end
+
+!! test
+Self closed html pairs (bug 5487)
+!! options
+!! input
+<center><font id="bug" />Centered text</center>
+<div><font id="bug2" />In div text</div>
+!! result
+<center>&lt;font id="bug" /&gt;Centered text</center>
+<div>&lt;font id="bug2" /&gt;In div text</div>
+
+!! end
+
+#
+#
+#
+
+!! test
+HTML bullet list, closed tags (bug 5497)
+!! input
+<ul>
+<li>One</li>
+<li>Two</li>
+</ul>
+!! result
+<ul>
+<li>One</li>
+<li>Two</li>
+</ul>
+
+!! end
+
+!! test
+TODO: HTML bullet list, unclosed tags (bug 5497)
+!! input
+<ul>
+<li>One
+<li>Two
+</ul>
+!! result
+<ul>
+<li>One
+</li><li>Two
+</li></ul>
+
+!! end
+
+!! test
+HTML ordered list, closed tags (bug 5497)
+!! input
+<ol>
+<li>One</li>
+<li>Two</li>
+</ol>
+!! result
+<ol>
+<li>One</li>
+<li>Two</li>
+</ol>
+
+!! end
+
+!! test
+TODO: HTML ordered list, unclosed tags (bug 5497)
+!! input
+<ol>
+<li>One
+<li>Two
+</ol>
+!! result
+<ol>
+<li>One
+</li><li>Two
+</li></ol>
+
+!! end
+
+!! test
+HTML nested bullet list, closed tags (bug 5497)
+!! input
+<ul>
+<li>One</li>
+<li>Two:
+<ul>
+<li>Sub-one</li>
+<li>Sub-two</li>
+</ul>
+</li>
+</ul>
+!! result
+<ul>
+<li>One</li>
+<li>Two:
+<ul>
+<li>Sub-one</li>
+<li>Sub-two</li>
+</ul>
+</li>
+</ul>
+
+!! end
+
+!! test
+TODO: HTML nested bullet list, open tags (bug 5497)
+!! input
+<ul>
+<li>One
+<li>Two:
+<ul>
+<li>Sub-one
+<li>Sub-two
+</ul>
+</ul>
+!! result
+<ul>
+<li>One
+</li><li>Two:
+<ul>
+<li>Sub-one
+</li><li>Sub-two
+</li></ul>
+</li></ul>
+
+!! end
+
+!! test
+HTML nested ordered list, closed tags (bug 5497)
+!! input
+<ol>
+<li>One</li>
+<li>Two:
+<ol>
+<li>Sub-one</li>
+<li>Sub-two</li>
+</ol>
+</li>
+</ol>
+!! result
+<ol>
+<li>One</li>
+<li>Two:
+<ol>
+<li>Sub-one</li>
+<li>Sub-two</li>
+</ol>
+</li>
+</ol>
+
+!! end
+
+!! test
+TODO: HTML nested ordered list, open tags (bug 5497)
+!! input
+<ol>
+<li>One
+<li>Two:
+<ol>
+<li>Sub-one
+<li>Sub-two
+</ol>
+</ol>
+!! result
+<ol>
+<li>One
+</li><li>Two:
+<ol>
+<li>Sub-one
+</li><li>Sub-two
+</li></ol>
+</li></ol>
+
+!! end
+
+!! test
+HTML ordered list item with parameters oddity
+!! input
+<ol><li id="fragment">One</li></ol>
+!! result
+<ol><li id="fragment">One</li></ol>
+
+!! end
+
+!!test
+bug 5918: autonumbering
+!! input
+[http://first/] [http://second] [ftp://ftp]
+
+ftp://inlineftp
+
+[mailto:enclosed@mail.tld With target]
+
+[mailto:enclosed@mail.tld]
+
+mailto:inline@mail.tld
+!! result
+<p><a href="http://first/" class="external autonumber" title="http://first/" rel="nofollow">[1]</a> <a href="http://second" class="external autonumber" title="http://second" rel="nofollow">[2]</a> <a href="ftp://ftp" class="external autonumber" title="ftp://ftp" rel="nofollow">[3]</a>
+</p><p><a href="ftp://inlineftp" class="external free" title="ftp://inlineftp" rel="nofollow">ftp://inlineftp</a>
+</p><p><a href="mailto:enclosed@mail.tld" class="external text" title="mailto:enclosed@mail.tld" rel="nofollow">With target</a>
+</p><p><a href="mailto:enclosed@mail.tld" class="external autonumber" title="mailto:enclosed@mail.tld" rel="nofollow">[4]</a>
+</p><p><a href="mailto:inline@mail.tld" class="external free" title="mailto:inline@mail.tld" rel="nofollow">mailto:inline@mail.tld</a>
+</p>
+!! end
+
+
+#
+# Security and HTML correctness
+# From Nick Jenkins' fuzz testing
+#
+
+!! test
+Fuzz testing: Parser13
+!! input
+{|
+| http://a|
+!! result
+<table>
+<tr>
+<td>
+</td>
+</tr>
+</table>
+
+!! end
+
+!! test
+Fuzz testing: Parser14
+!! input
+== onmouseover= ==
+http://__TOC__
+!! result
+<a name="onmouseover.3D"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: onmouseover=">edit</a>]</span> <span class="mw-headline"> onmouseover= </span></h2>
+http://<table id="toc" class="toc" summary="Contents"><tr><td><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
+</ul>
+</td></tr></table><script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>
+
+!! end
+
+!! test
+Fuzz testing: Parser14-table
+!! input
+==a==
+{| STYLE=__TOC__
+!! result
+<a name="a"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: a">edit</a>]</span> <span class="mw-headline">a</span></h2>
+<table style="&#95;_TOC&#95;_">
+<tr><td></td></tr>
+</table>
+
+!! end
+
+# Known to produce bogus xml (extra </td>)
+!! test
+Fuzz testing: Parser16
+!! options
+noxml
+!! input
+{|
+!https://||||||
+!! result
+<table>
+<tr>
+<th>https://</th><th></th><th></th><th>
+</td>
+</tr>
+</table>
+
+!! end
+
+!! test
+Fuzz testing: Parser21
+!! input
+{|
+! irc://{{ftp://a" onmouseover="alert('hello world');"
+|
+!! result
+<table>
+<tr>
+<th> <a href="irc://{{ftp://a" class="external free" title="irc://{{ftp://a" rel="nofollow">irc://{{ftp://a</a>" onmouseover="alert('hello world');"
+</th><td>
+</td>
+</tr>
+</table>
+
+!! end
+
+!! test
+Fuzz testing: Parser22
+!! input
+http://===r:::https://b
+
+{|
+!!result
+<p><a href="http://===r:::https://b" class="external free" title="http://===r:::https://b" rel="nofollow">http://===r:::https://b</a>
+</p>
+<table>
+<tr><td></td></tr>
+</table>
+
+!! end
+
+# Known to produce bad XML for now
+!! test
+Fuzz testing: Parser24
+!! options
+noxml
+!! input
+{|
+{{{|
+<u CLASS=
+| {{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--><noinclude>}}}} >
+<br style="onmouseover='alert(document.cookie);' " />
+
+MOVE YOUR MOUSE CURSOR OVER THIS TEXT
+|
+!! result
+<table>
+
+<u class="&#124;">} &gt;
+<br style="onmouseover='alert(document.cookie);'" />
+
+MOVE YOUR MOUSE CURSOR OVER THIS TEXT
+<tr>
+<td></u>
+</td>
+</tr>
+</table>
+
+!! end
+
+# Known to produce bad XML for now
+!!test
+Fuzz testing: Parser25 (bug 6055)
+!! options
+noxml
+!! input
+{{{
+|
+<LI CLASS=||
+ >
+}}}blah" onmouseover="alert('hello world');" align="left"'''MOVE MOUSE CURSOR OVER HERE
+!! result
+<li class="&#124;&#124;">
+blah" onmouseover="alert('hello world');" align="left"<b>MOVE MOUSE CURSOR OVER HERE</b>
+
+!! end
+
+!!test
+Fuzz testing: URL adjacent extension (with space, clean)
+!! options
+!! input
+http://example.com <nowiki>junk</nowiki>
+!! result
+<p><a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a> junk
+</p>
+!!end
+
+!!test
+Fuzz testing: URL adjacent extension (no space, dirty; nowiki)
+!! options
+!! input
+http://example.com<nowiki>junk</nowiki>
+!! result
+<p><a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a>junk
+</p>
+!!end
+
+!!test
+Fuzz testing: URL adjacent extension (no space, dirty; pre)
+!! options
+!! input
+http://example.com<pre>junk</pre>
+!! result
+<a href="http://example.com" class="external free" title="http://example.com" rel="nofollow">http://example.com</a><pre>junk</pre>
+
+!!end
+
+!!test
+Fuzz testing: image with bogus manual thumbnail
+!!input
+[[Image:foobar.jpg|thumbnail= ]]
+!!result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title=""><img src="http://example.com/images/3/3a/Foobar.jpg" alt="" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div></div></div></div>
+
+!!end
+
+!! test
+Fuzz testing: encoded newline in generated HTML replacements (bug 6577)
+!! input
+<pre dir="&#10;"></pre>
+!! result
+<pre dir="&#10;"></pre>
+
+!! end
+
+!! test
+TODO: Parsing optional HTML elements (Bug 6171)
+!! options
+!! input
+<table>
+ <tr>
+ <td> Some tabular data</td>
+ <td> More tabular data ...
+ <td> And yet som tabular data</td>
+ </tr>
+</table>
+!! result
+<table>
+ <tr>
+ <td> Some tabular data</td>
+ <td> More tabular data ...
+ </td><td> And yet som tabular data</td>
+ </tr>
+</table>
+
+!! end
+
+!! test
+Correct handling of <td>, <tr> (Bug 6171)
+!! options
+!! input
+<table>
+ <tr>
+ <td> Some tabular data</td>
+ <td> More tabular data ...</td>
+ <td> And yet som tabular data</td>
+ </tr>
+</table>
+!! result
+<table>
+ <tr>
+ <td> Some tabular data</td>
+ <td> More tabular data ...</td>
+ <td> And yet som tabular data</td>
+ </tr>
+</table>
+
+!! end
+
+
+!! test
+Parsing crashing regression (fr:JavaScript)
+!! input
+</body></x>
+!! result
+<p>&lt;/body&gt;&lt;/x&gt;
+</p>
+!! end
+
+!! test
+Inline wiki vs wiki block nesting
+!! input
+'''Bold paragraph
+
+New wiki paragraph
+!! result
+<p><b>Bold paragraph</b>
+</p><p>New wiki paragraph
+</p>
+!! end
+
+!! test
+TODO: Inline HTML vs wiki block nesting
+!! input
+<b>Bold paragraph
+
+New wiki paragraph
+!! result
+<p><b>Bold paragraph</b>
+</p><p>New wiki paragraph
+</p>
+!! end
+
+
+!!test
+TODO: Mixing markup for italics and bold
+!! options
+!! input
+'''bold''''''bold''bolditalics'''''
+!! result
+<p><b>bold</b><b>bold<i>bolditalics</i></b>
+</p>
+!! end
+
+
+!! article
+Xyzzyx
+!! text
+Article for special page transclusion test
+!! endarticle
+
+!! test
+Special page transclusion
+!! options
+!! input
+{{Special:Prefixindex/Xyzzyx}}
+!! result
+<p><br />
+</p>
+<table style="background: inherit;" border="0" width="100%"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table>
+
+!! end
+
+!! test
+Special page transclusion twice (bug 5021)
+!! options
+!! input
+{{Special:Prefixindex/Xyzzyx}}
+{{Special:Prefixindex/Xyzzyx}}
+!! result
+<p><br />
+</p>
+<table style="background: inherit;" border="0" width="100%"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table>
+<p><br />
+</p>
+<table style="background: inherit;" border="0" width="100%"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table>
+
+!! end
+
+!! test
+Transclusion of default MediaWiki message
+!! input
+{{MediaWiki:Mainpage}}
+!!result
+<p>Main Page
+</p>
+!! end
+
+!! test
+Transclusion of nonexistent MediaWiki message
+!! input
+{{MediaWiki:Mainpagexxx}}
+!!result
+<p><a href="/index.php?title=MediaWiki:Mainpagexxx&amp;action=edit" class="new" title="MediaWiki:Mainpagexxx">MediaWiki:Mainpagexxx</a>
+</p>
+!! end
+
+!! test
+Transclusion of MediaWiki message with underscore
+!! input
+{{MediaWiki:history_short}}
+!! result
+<p>History
+</p>
+!! end
+
+!! test
+Transclusion of MediaWiki message with space
+!! input
+{{MediaWiki:history short}}
+!! result
+<p>History
+</p>
+!! end
+
+!! test
+Invalid header with following text
+!! input
+= x = y
+!! result
+<p>= x = y
+</p>
+!! end
+
+
+!! test
+Section extraction test (section 0)
+!! options
+section=0
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+!! end
+
+!! test
+Section extraction test (section 1)
+!! options
+section=1
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+==a==
+===aa===
+====aaa====
+!! end
+
+!! test
+Section extraction test (section 2)
+!! options
+section=2
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+===aa===
+====aaa====
+!! end
+
+!! test
+Section extraction test (section 3)
+!! options
+section=3
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+====aaa====
+!! end
+
+!! test
+Section extraction test (section 4)
+!! options
+section=4
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+!! end
+
+!! test
+Section extraction test (section 5)
+!! options
+section=5
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+===ba===
+!! end
+
+!! test
+Section extraction test (section 6)
+!! options
+section=6
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+===bb===
+====bba====
+!! end
+
+!! test
+Section extraction test (section 7)
+!! options
+section=7
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+====bba====
+!! end
+
+!! test
+Section extraction test (section 8)
+!! options
+section=8
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+===bc===
+!! end
+
+!! test
+Section extraction test (section 9)
+!! options
+section=9
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+==c==
+===ca===
+!! end
+
+!! test
+Section extraction test (section 10)
+!! options
+section=10
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+===ca===
+!! end
+
+!! test
+Section extraction test (nonexistent section 11)
+!! options
+section=11
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+!! end
+
+!! test
+Section extraction test with bogus heading (section 1)
+!! options
+section=1
+!! input
+==a==
+==bogus== not a legal section
+==b==
+!! result
+==a==
+==bogus== not a legal section
+!! end
+
+!! test
+Section extraction test with bogus heading (section 2)
+!! options
+section=2
+!! input
+==a==
+==bogus== not a legal section
+==b==
+!! result
+==b==
+!! end
+
+!! test
+Section extraction test with comment after heading (section 1)
+!! options
+section=1
+!! input
+==a==
+==legal== <!-- a legal section -->
+==b==
+!! result
+==a==
+!! end
+
+!! test
+Section extraction test with comment after heading (section 2)
+!! options
+section=2
+!! input
+==a==
+==legal== <!-- a legal section -->
+==b==
+!! result
+==legal== <!-- a legal section -->
+!! end
+
+!! test
+Section extraction test with bogus <nowiki> heading (section 1)
+!! options
+section=1
+!! input
+==a==
+==bogus== <nowiki>not a legal section</nowiki>
+==b==
+!! result
+==a==
+==bogus== <nowiki>not a legal section</nowiki>
+!! end
+
+!! test
+Section extraction test with bogus <nowiki> heading (section 2)
+!! options
+section=2
+!! input
+==a==
+==bogus== <nowiki>not a legal section</nowiki>
+==b==
+!! result
+==b==
+!! end
+
+
+!! test
+Section extraction prefixed by comment (section 1) (bug 2587)
+!! options
+section=1
+!! input
+<!-- -->==sec1==
+==sec2==
+!!result
+<!-- -->==sec1==
+!!end
+
+!! test
+Section extraction prefixed by comment (section 2) (bug 2587)
+!! options
+section=2
+!! input
+<!-- -->==sec1==
+==sec2==
+!!result
+==sec2==
+!!end
+
+
+!! test
+Section extraction, mixed wiki and html (section 1) (bug 2607)
+!! options
+section=1
+!! input
+<h2>1</h2>
+one
+==2==
+two
+==3==
+three
+!! result
+<h2>1</h2>
+one
+!! end
+
+!! test
+Section extraction, mixed wiki and html (section 2) (bug 2607)
+!! options
+section=2
+!! input
+<h2>1</h2>
+one
+==2==
+two
+==3==
+three
+!! result
+==2==
+two
+!! end
+
+
+!! test
+Section extraction, heading surrounded by <noinclude> (bug 3342)
+!! options
+section=1
+!! input
+<noinclude>==a==</noinclude>
+text
+!! result
+<noinclude>==a==</noinclude>
+text
+!!end
+
+
+!! test
+Section extraction, HTML heading subsections (bug 5272)
+!! options
+section=1
+!! input
+<h2>a</h2>
+<h3>aa</h3>
+<h2>b</h2>
+!! result
+<h2>a</h2>
+<h3>aa</h3>
+!! end
+
+!! test
+Section extraction, HTML headings should be ignored in extensions (bug 3476)
+!! options
+section=2
+!! input
+<h2>a</h2>
+<tag>
+<h2>not b</h2>
+</tag>
+<h2>b</h2>
+!! result
+<h2>b</h2>
+!! end
+
+!! test
+Section replacement test (section 0)
+!! options
+replace=0,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+xxx
+
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 1)
+!! options
+replace=1,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+xxx
+
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 2)
+!! options
+replace=2,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+xxx
+
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 3)
+!! options
+replace=3,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+xxx
+
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 4)
+!! options
+replace=4,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+xxx
+
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 5)
+!! options
+replace=5,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+xxx
+
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 6)
+!! options
+replace=6,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+xxx
+
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 7)
+!! options
+replace=7,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+xxx
+
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 8)
+!! options
+replace=8,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+xxx
+
+==c==
+===ca===
+!!end
+
+!! test
+Section replacement test (section 9)
+!! options
+replace=9,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+xxx
+!! end
+
+!! test
+Section replacement test (section 10)
+!! options
+replace=10,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+xxx
+!! end
+
+
+!! test
+Section extraction, HTML headings not at line boundaries (section 0)
+!! options
+section=0
+!! input
+<h2>Evil</h2><i>blah blah blah</i>
+
+evil blah
+
+<h2>Nice</h2>
+
+nice blah
+
+<i>extra evil</i><h2>Extra nasty</h2>
+
+extra nasty
+!! result
+!! end
+
+!! test
+Section extraction, HTML headings not at line boundaries (section 1)
+!! options
+section=1
+!! input
+<h2>Evil</h2><i>blah blah blah</i>
+
+evil blah
+
+<h2>Nice</h2>
+
+nice blah
+
+<i>extra evil</i><h2>Extra nasty</h2>
+
+extra nasty
+!! result
+<h2>Evil</h2><i>blah blah blah</i>
+
+evil blah
+!! end
+
+!! test
+Section extraction, HTML headings not at line boundaries (section 2)
+!! options
+section=2
+!! input
+<h2>Evil</h2><i>blah blah blah</i>
+
+evil blah
+
+<h2>Nice</h2>
+
+nice blah
+
+<i>extra evil</i><h2>Extra nasty</h2>
+
+extra nasty
+!! result
+<h2>Nice</h2>
+
+nice blah
+
+<i>extra evil</i>
+!! end
+
+!! test
+Section extraction, HTML headings not at line boundaries (section 3)
+!! options
+section=3
+!! input
+<h2>Evil</h2><i>blah blah blah</i>
+
+evil blah
+
+<h2>Nice</h2>
+
+nice blah
+
+<i>extra evil</i><h2>Extra nasty</h2>
+
+extra nasty
+!! result
+<h2>Extra nasty</h2>
+
+extra nasty
+!! end
+
+
+!! test
+Section extraction, heading followed by pre with 20 spaces (bug 6398)
+!! options
+section=1
+!! input
+==a==
+ a
+!! result
+==a==
+ a
+!! end
+
+!! test
+Section extraction, heading followed by pre with 19 spaces (bug 6398 sanity check)
+!! options
+section=1
+!! input
+==a==
+ a
+!! result
+==a==
+ a
+!! end
+
+!! test
+Handling of &#x0A; in URLs
+!! input
+**irc://&#x0A;a
+!! result
+<ul><li><ul><li><a href="irc://%0Aa" class="external free" title="irc://%0Aa" rel="nofollow">irc://%0Aa</a>
+</li></ul>
+</li></ul>
+
+!!end
+
+!! test
+TODO: 5 quotes, code coverage +1 line
+!! input
+'''''
+!! result
+!! end
+
+!! test
+Special:Search page linking.
+!! input
+{{Special:search}}
+!! result
+<p><a href="/wiki/Special:Search" title="Special:Search">Special:Search</a>
+</p>
+!! end
+
+!! test
+Say the magic word
+!! input
+* {{PAGENAME}}
+* {{BASEPAGENAME}}
+* {{SUBPAGENAME}}
+* {{SUBPAGENAMEE}}
+* {{BASEPAGENAME}}
+* {{BASEPAGENAMEE}}
+* {{TALKPAGENAME}}
+* {{TALKPAGENAMEE}}
+* {{SUBJECTPAGENAME}}
+* {{SUBJECTPAGENAMEE}}
+* {{NAMESPACEE}}
+* {{NAMESPACE}}
+* {{TALKSPACE}}
+* {{TALKSPACEE}}
+* {{SUBJECTSPACE}}
+* {{SUBJECTSPACEE}}
+* {{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}}
+!! result
+<ul><li> Parser test
+</li><li> Parser test
+</li><li> Parser test
+</li><li> Parser_test
+</li><li> Parser test
+</li><li> Parser_test
+</li><li> Talk:Parser test
+</li><li> Talk:Parser_test
+</li><li> Parser test
+</li><li> Parser_test
+</li><li>
+</li><li>
+</li><li> Talk
+</li><li> Talk
+</li><li>
+</li><li>
+</li><li> <a href="/index.php?title=Template:Dynamic&amp;action=edit" class="new" title="Template:Dynamic">Template:Dynamic</a>
+</li></ul>
+
+!! end
+### Note: Above tests excludes the "{{NUMBEROFADMINS}}" magic word because it generates a MySQL error when included.
+
+!! test
+Gallery
+!! input
+<gallery>
+image1.png |
+image2.gif|||||
+
+image3|
+image4 |300px| centre
+ image5.svg| http://///////
+[[x|xx]]]]
+* image6
+</gallery>
+!! result
+<table class="gallery" cellspacing="0" cellpadding="0"><tr><td><div class="gallerybox"><div style="height: 152px;">Image1.png</div><div class="gallerytext">
+</div></div></td>
+<td><div class="gallerybox"><div style="height: 152px;">Image2.gif</div><div class="gallerytext">
+||||</div></div></td>
+<td><div class="gallerybox"><div style="height: 152px;">Image3</div><div class="gallerytext">
+</div></div></td>
+<td><div class="gallerybox"><div style="height: 152px;">Image4</div><div class="gallerytext">
+300px| centre</div></div></td>
+</tr><tr><td><div class="gallerybox"><div style="height: 152px;">Image5.svg</div><div class="gallerytext">
+ <a href="http://///////" class="external free" title="http://///////" rel="nofollow">http://///////</a></div></div></td>
+<td><div class="gallerybox"><div style="height: 152px;">* image6</div><div class="gallerytext">
+</div></div></td>
+</tr>
+</table>
+
+!! end
+
+!! test
+HTML Hex character encoding (spells the word "JavaScript")
+!! input
+&#x4A;&#x061;&#x0076;&#x00061;&#x000053;&#x0000063;&#114;&#x0000069;&#00000112;&#x0000000074;
+!! result
+<p>&#x4a;&#x61;&#x76;&#x61;&#x53;&#x63;&#114;&#x69;&#112;&#x74;
+</p>
+!! end
+
+!! test
+__FORCETOC__ override
+!! input
+__NEWSECTIONLINK__
+__FORCETOC__
+!! result
+<p><br />
+</p>
+!! end
+
+!! test
+ISBN code coverage
+!! input
+ISBN 978-0-1234-56&#x20;789
+!! result
+<p><a href="/index.php?title=Special:Booksources&amp;isbn=9780123456" class="internal">ISBN 978-0-1234-56</a>&#x20;789
+</p>
+!! end
+
+!! test
+ISBN followed by 5 spaces
+!! input
+ISBN
+!! result
+<p>ISBN
+</p>
+!! end
+
+!! test
+Double ISBN
+!! input
+ISBN ISBN 1234567890
+!! result
+<p>ISBN <a href="/index.php?title=Special:Booksources&amp;isbn=1234567890" class="internal">ISBN 1234567890</a>
+</p>
+!! end
+
+!! test
+Double RFC
+!! input
+RFC RFC 1234
+!! result
+<p>RFC <a href="http://www.ietf.org/rfc/rfc1234.txt" class="external" title="http://www.ietf.org/rfc/rfc1234.txt">RFC 1234</a>
+</p>
+!! end
+
+!! test
+Double RFC with a wiki link
+!! input
+RFC [[RFC 1234]]
+!! result
+<p>RFC <a href="/index.php?title=RFC_1234&amp;action=edit" class="new" title="RFC 1234">RFC 1234</a>
+</p>
+!! end
+
+!! test
+RFC code coverage
+!! input
+RFC 983&#x20;987
+!! result
+<p><a href="http://www.ietf.org/rfc/rfc983.txt" class="external" title="http://www.ietf.org/rfc/rfc983.txt">RFC 983</a>&#x20;987
+</p>
+!! end
+
+!! test
+Centre-aligned image
+!! input
+[[Image:foobar.jpg|centre]]
+!! result
+<div class="center"><div class="floatnone"><span><a href="/wiki/Image:Foobar.jpg" class="image" title=""><img src="http://example.com/images/3/3a/Foobar.jpg" alt="" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a></span></div></div>
+
+!!end
+
+!! test
+None-aligned image
+!! input
+[[Image:foobar.jpg|none]]
+!! result
+<div class="floatnone"><span><a href="/wiki/Image:Foobar.jpg" class="image" title=""><img src="http://example.com/images/3/3a/Foobar.jpg" alt="" width="1941" height="220" longdesc="/wiki/Image:Foobar.jpg" /></a></span></div>
+
+!!end
+
+!! test
+Width + Height sized image (using px) (height is ignored)
+!! input
+[[Image:foobar.jpg|640x480px]]
+!! result
+<p><a href="/wiki/Image:Foobar.jpg" class="image" title=""><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" alt="" width="640" height="73" longdesc="/wiki/Image:Foobar.jpg" /></a>
+</p>
+!!end
+
+!! test
+Another italics / bold test
+!! input
+ ''' ''x'
+!! result
+<pre>'<i> </i>x'
+</pre>
+!!end
+
+# Note the results may be incorrect, as parserTest output included this:
+# XML error: Mismatched tag at byte 6120:
+# ...<dd> </dt></dl> </dd...
+!! test
+TODO: dt/dd/dl test
+!! input
+:;;;::
+!! result
+<dl><dd><dl><dt><dl><dt><dl><dt><dl><dd><dl><dd>
+</dt></dl>
+</dd></dl>
+</dd></dl>
+</dd></dl>
+</dd></dl>
+</dd></dl>
+
+!!end
+
+
+# Images with the "|" character in external URLs in comment tags; Eats half the comment, leaves unmatched "</a>" tag.
+!! test
+TODO: Images with the "|" character in the comment
+!! input
+[[image:Foobar.jpg|thumb|An [http://test/?param1=|left|&param2=|x external] URL]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/Image:Foobar.jpg" class="internal" title="An external URL"><img src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" alt="An external URL" width="180" height="20" longdesc="/wiki/Image:Foobar.jpg" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify" style="float:right"><a href="/wiki/Image:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>An <a href="http://test/?param1=|left|&amp;param2=|x" class="external text" title="http://test/?param1=|left|&amp;param2=|x" rel="nofollow">external</a> URL</div></div></div>
+
+!!end
+
+!! test
+[Before] HTML without raw HTML enabled ($wgRawHtml==false)
+!! input
+<html><script>alert(1);</script></html>
+!! result
+<p>&lt;html&gt;&lt;script&gt;alert(1);&lt;/script&gt;&lt;/html&gt;
+</p>
+!! end
+
+!! test
+HTML with raw HTML ($wgRawHtml==true)
+!! options
+rawhtml
+!! input
+<html><script>alert(1);</script></html>
+!! result
+<p><script>alert(1);</script>
+</p>
+!! end
+
+!! test
+Parents of subpages, one level up
+!! options
+subpage title=[[Subpage test/L1/L2/L3]]
+!! input
+[[../|L2]]
+!! result
+<p><a href="/index.php?title=Subpage_test/L1/L2&amp;action=edit" class="new" title="Subpage test/L1/L2">L2</a>
+</p>
+!! end
+
+
+!! test
+Parents of subpages, one level up, not named
+!! options
+subpage title=[[Subpage test/L1/L2/L3]]
+!! input
+[[../]]
+!! result
+<p><a href="/index.php?title=Subpage_test/L1/L2&amp;action=edit" class="new" title="Subpage test/L1/L2">Subpage test/L1/L2</a>
+</p>
+!! end
+
+
+
+!! test
+Parents of subpages, two levels up
+!! options
+disabled
+subpage title=[[Subpage test/L1/L2/L3]]
+!! input
+[[../../|L1]]2
+!! result
+<p><a href="/index.php?title=Subpage_test/L1&amp;action=edit" class="new" title="Subpage test/L1">L1</a>
+</p>
+!! end
+
+
+# Question: should result be "/index.php?title=Subpage_test/L1&amp;action=edit" instead?
+!! test
+TODO: Parents of subpages, two levels up, without trailing slash or name.
+!! options
+subpage title=[[Subpage test/L1/L2/L3]]
+!! input
+[[../..]]
+!! result
+<p><a href="/index.php?title=Subpage_test/L1/L2/..&amp;action=edit" class="new" title="Subpage test/L1">../..</a>
+</p>
+!! end
+
+# Question: Why should the link text in the above test be "../..", yet in this test the "../.." part is silently dropped?
+# Current result: <p><a href="/index.php?title=Subpage_test/L1////&amp;action=edit" class="new" title="Subpage test/L1////">///
+!! test
+TODO: Parents of subpages, two levels up, with lots of extra trailing slashes.
+!! options
+subpage title=[[Subpage test/L1/L2/L3]]
+!! input
+[[../../////]]
+!! result
+<p><a href="/index.php?title=Subpage_test/L1&amp;action=edit" class="new" title="Subpage test/L1">Subpage test/L1</a>
+</p>
+!! end
+
+!! test
+Definition list code coverage
+!! input
+; title : def
+; title : def
+;title: def
+!! result
+<dl><dt> title &nbsp;</dt><dd> def
+</dd><dt> title&nbsp;</dt><dd> def
+</dd><dt>title</dt><dd> def
+</dd></dl>
+
+!! end
+
+!! test
+TODO: Don't fall for the self-closing div
+!! input
+<div>hello world</div/>
+!! result
+<div>hello world</div>
+
+!! end
+
+!! test
+MSGNW magic word
+!! input
+{{MSGNW:msg}}
+!! result
+<p>&#91;&#91;:Template:Msg]]
+</p>
+!! end
+
+!! test
+RAW magic word
+!! input
+{{RAW:QUERTY}}
+!! result
+<p><a href="/index.php?title=Template:QUERTY&amp;action=edit" class="new" title="Template:QUERTY">Template:QUERTY</a>
+</p>
+!! end
+
+# This isn't needed for XHTML conformance, but would be handy as a fallback security measure
+!! test
+TODO: Always escape literal '>' in output, not just after '<'
+!! input
+><>
+!! result
+<p>&gt;&lt;&gt;
+</p>
+!! end
+
+!! test
+Template caching
+!! input
+{{Test}}
+{{Test}}
+!! result
+<p>This is a test template
+This is a test template
+</p>
+!! end
+
+
+!! article
+MediaWiki:Fake
+!! text
+==header==
+!! endarticle
+
+!! test
+Inclusion of !userCanEdit() content
+!! input
+{{MediaWiki:Fake}}
+!! result
+<a name="header"></a><h2><span class="editsection">[<a href="/index.php?title=MediaWiki:Fake&amp;action=edit&amp;section=1" title="MediaWiki:Fake">edit</a>]</span> <span class="mw-headline">header</span></h2>
+
+!! end
+
+
+!! test
+Out-of-order TOC heading levels
+!! input
+==2==
+======6======
+===3===
+=1=
+=====5=====
+==2==
+!! result
+<table id="toc" class="toc" summary="Contents"><tr><td><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1"><a href="#2"><span class="tocnumber">1</span> <span class="toctext">2</span></a>
+<ul>
+<li class="toclevel-2"><a href="#6"><span class="tocnumber">1.1</span> <span class="toctext">6</span></a></li>
+<li class="toclevel-2"><a href="#3"><span class="tocnumber">1.2</span> <span class="toctext">3</span></a></li>
+</ul>
+</li>
+<li class="toclevel-1"><a href="#1_7"><span class="tocnumber">2</span> <span class="toctext">1</span></a>
+<ul>
+<li class="toclevel-2"><a href="#5"><span class="tocnumber">2.1</span> <span class="toctext">5</span></a></li>
+<li class="toclevel-2"><a href="#2_4"><span class="tocnumber">2.2</span> <span class="toctext">2</span></a></li>
+</ul>
+</li>
+</ul>
+</td></tr></table><script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>
+<a name="2"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 2">edit</a>]</span> <span class="mw-headline">2</span></h2>
+<a name="6"></a><h6><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: 6">edit</a>]</span> <span class="mw-headline">6</span></h6>
+<a name="3"></a><h3><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: 3">edit</a>]</span> <span class="mw-headline">3</span></h3>
+<a name="1_7"></a><h1><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 1">edit</a>]</span> <span class="mw-headline">1</span></h1>
+<a name="5"></a><h5><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: 5">edit</a>]</span> <span class="mw-headline">5</span></h5>
+<a name="2_4"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: 2">edit</a>]</span> <span class="mw-headline">2</span></h2>
+
+!! end
+
+
+!! test
+ISBN with a dummy number
+!! input
+ISBN ---
+!! result
+<p>ISBN ---
+</p>
+!! end
+
+
+!! test
+ISBN with space-delimited number
+!! input
+ISBN 92 9017 032 8
+!! result
+<p><a href="/index.php?title=Special:Booksources&amp;isbn=9290170328" class="internal">ISBN 92 9017 032 8</a>
+</p>
+!! end
+
+
+!! test
+ISBN with multiple spaces, no number
+!! input
+ISBN foo
+!! result
+<p>ISBN foo
+</p>
+!! end
+
+
+!! test
+ISBN length
+!! input
+ISBN 123456789
+
+ISBN 1234567890
+
+ISBN 12345678901
+!! result
+<p>ISBN 123456789
+</p><p><a href="/index.php?title=Special:Booksources&amp;isbn=1234567890" class="internal">ISBN 1234567890</a>
+</p><p>ISBN 12345678901
+</p>
+!! end
+
+
+!! test
+ISBN with trailing year (bug 8110)
+!! input
+ISBN 1-234-56789-0 - 2006
+
+ISBN 1 234 56789 0 - 2006
+!! result
+<p><a href="/index.php?title=Special:Booksources&amp;isbn=1234567890" class="internal">ISBN 1-234-56789-0</a> - 2006
+</p><p><a href="/index.php?title=Special:Booksources&amp;isbn=1234567890" class="internal">ISBN 1 234 56789 0</a> - 2006
+</p>
+!! end
+
+
+!! test
+Pages in namespace (Magic word disabled currently)
+!! input
+{{PAGESINNAMESPACE:}}
+!! result
+
+!! end
+
+
+!! test
+anchorencode
+!! input
+{{anchorencode:foo bar©#%n}}
+!! result
+<p>foo_bar.C2.A9.23.25n
+</p>
+!! end
+
+
+!! test
+Bug 8293: Use of center tag ruins paragraph formatting
+!! input
+<center>
+foo
+</center>
+
+bar
+
+ baz
+!! result
+<center>
+<p>foo
+</p>
+</center>
+<p>bar
+</p>
+<pre>baz
+</pre>
+!! end
+
+
+###
+### Language variants related tests
+###
+!! test
+Self-link in language variants
+!! options
+title=[[Dunav]] language=sr
+!! input
+Both [[Dunav]] and [[Дунав]] are names for this river.
+!! result
+<p>Both <strong class="selflink">Dunav</strong> and <strong class="selflink">Дунав</strong> are names for this river.
+</p>
+!!end
+
+
+!! test
+Link to pages in language variants
+!! options
+language=sr
+!! input
+Main Page can be written as [[Маин Паге]]
+!! result
+<p>Main Page can be written as <a href="/wiki/Main_Page" title="Main Page">Маин Паге</a>
+</p>
+!!end
+
+
+!! test
+Multiple links to pages in language variants
+!! options
+language=sr
+!! input
+[[Main Page]] can be written as [[Маин Паге]] same as [[Маин Паге]].
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a> can be written as <a href="/wiki/Main_Page" title="Main Page">Маин Паге</a> same as <a href="/wiki/Main_Page" title="Main Page">Маин Паге</a>.
+</p>
+!!end
+
+
+!! test
+Simple template in language variants
+!! options
+language=sr
+!! input
+{{тест}}
+!! result
+<p>This is a test template
+</p>
+!! end
+
+
+!! test
+Template with explicit namespace in language variants
+!! options
+language=sr
+!! input
+{{Template:тест}}
+!! result
+<p>This is a test template
+</p>
+!! end
+
+
+!! test
+Basic test for template parameter in language variants
+!! options
+language=sr
+!! input
+{{парамтест|param=foo}}
+!! result
+<p>This is a test template with parameter foo
+</p>
+!! end
+
+
+!! test
+Simple category in language variants
+!! options
+language=sr cat
+!! input
+[[:Category:МедиаWики Усер'с Гуиде]]
+!! result
+<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a>
+!! end
+
+
+!! test
+Stripping -{}- tags (language variants)
+!! options
+language=sr
+!! input
+Latin proverb: -{Ne nuntium necare}-
+!! result
+<p>Latin proverb: Ne nuntium necare
+</p>
+!! end
+
+
+!! test
+Prevent conversion with -{}- tags (language variants)
+!! options
+language=sr variant=sr-ec
+!! input
+Latinski: -{Ne nuntium necare}-
+!! result
+<p>Латински: Ne nuntium necare
+</p>
+!! end
+
+
+!! test
+Prevent conversion of text with -{}- tags (language variants)
+!! options
+language=sr variant=sr-ec
+!! input
+Latinski: -{Ne nuntium necare}-
+!! result
+<p>Латински: Ne nuntium necare
+</p>
+!! end
+
+
+!! test
+Prevent conversion of links with -{}- tags (language variants)
+!! options
+language=sr variant=sr-ec
+!! input
+-{[[Main Page]]}-
+!! result
+<p><a href="/index.php?title=Main_Page&amp;variant=sr-ec" title="Main Page">Main Page</a>
+</p>
+!! end
+
+
+!! test
+-{}- tags within headlines (within html for parserConvert())
+!! options
+language=sr variant=sr-ec
+!! input
+== -{Naslov}- ==
+!! result
+<a name="-.7BNaslov.7D-"></a><h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Уреди део: Naslov">уреди</a>]</span> <span class="mw-headline"> Naslov </span></h2>
+
+!! end
+
+
+!! test
+Explicit definition of language variant alternatives
+!! options
+language=zh variant=zh-tw
+!! input
+-{zh:China;zh-tw:Taiwan}-, not China
+!! result
+<p>Taiwan, not China
+</p>
+!! end
+
+
+!! test
+Adding explicit session-wise language variant mapping (A flag)
+!! options
+language=zh variant=zh-tw
+!! input
+-{A|zh:China;zh-tw:Taiwan}- is China
+!! result
+<p>Taiwan is Taiwan
+</p>
+!! end
+
+
+!! test
+Adding explicit conversion rule for title (T flag)
+!! options
+language=zh variant=zh-tw
+!! input
+Should be stripped-{T|zh:China;zh-tw:Taiwan}-!
+!! result
+<p>Should be stripped!
+</p>
+!! end
+
+
+!! test
+Raw output of variant escape tags (R flag)
+!! options
+language=zh variant=zh-tw
+!! input
+Raw: -{R|zh:China;zh-tw:Taiwan}-
+!! result
+<p>Raw: zh:China;zh-tw:Taiwan
+</p>
+!! end
+
+
+!! test
+Do not convert roman numbers to language variants
+!! options
+language=sr variant=sr-ec
+!! input
+Fridrih IV je car.
+!! result
+<p>Фридрих IV је цар.
+</p>
+!! end
+
+
+#
+#
+#
+
+TODO:
+more images
+more tables
+math
+character entities
+and much more
+Try for 100% code coverage
diff --git a/maintenance/parserTestsParserHook.php b/maintenance/parserTestsParserHook.php
new file mode 100644
index 000000000000..65e41aaee64c
--- /dev/null
+++ b/maintenance/parserTestsParserHook.php
@@ -0,0 +1,34 @@
+<?php
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( -1 );
+/**
+ * A basic extension that's used by the parser tests to test whether input and
+ * arguments are passed to extensions properly.
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, 2006 Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+$wgHooks['ParserTestParser'][] = 'wfParserTestParserHookSetup';
+
+function wfParserTestParserHookSetup( &$parser ) {
+ $parser->setHook( 'tag', 'wfParserTestParserHookHook' );
+
+ return true;
+}
+
+function wfParserTestParserHookHook( $in, $argv ) {
+ ob_start();
+ var_dump(
+ $in,
+ $argv
+ );
+ $ret = ob_get_clean();
+
+ return "<pre>\n$ret</pre>";
+}
+?>
diff --git a/maintenance/parserTestsParserTime.php b/maintenance/parserTestsParserTime.php
new file mode 100644
index 000000000000..705f9ce79ad1
--- /dev/null
+++ b/maintenance/parserTestsParserTime.php
@@ -0,0 +1,26 @@
+<?php
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( -1 );
+/**
+ * A basic extension that's used by the parser tests to test date magic words
+ *
+ * Handy so that we don't have to upgrade the parsertests every second to
+ * compensate with the passage of time and certainly less expensive than a
+ * time-freezing device, get yours now!
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, 2006 Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+$wgHooks['ParserGetVariableValueTs'][] = 'wfParserTimeSetup';
+
+function wfParserTimeSetup( &$parser, &$ts ) {
+ $ts = 123; //$ perl -le 'print scalar localtime 123' ==> Thu Jan 1 00:02:03 1970
+
+ return true;
+}
+?>
diff --git a/maintenance/parserTestsStaticParserHook.php b/maintenance/parserTestsStaticParserHook.php
new file mode 100644
index 000000000000..ac365acafc3b
--- /dev/null
+++ b/maintenance/parserTestsStaticParserHook.php
@@ -0,0 +1,44 @@
+<?php
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( -1 );
+/**
+ * A basic extension that's used by the parser tests to test whether the parser
+ * calls extensions when they're called inside comments, it shouldn't do that
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, 2006 Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+$wgHooks['ParserTestParser'][] = 'wfParserTestStaticParserHookSetup';
+
+function wfParserTestStaticParserHookSetup( &$parser ) {
+ $parser->setHook( 'statictag', 'wfParserTestStaticParserHookHook' );
+
+ return true;
+}
+
+function wfParserTestStaticParserHookHook( $in, $argv ) {
+ static $buf = null;
+
+ if ( ! count( $argv ) ) {
+ $buf = $in;
+ return '';
+ } else if ( count( $argv ) === 1 && $argv['action'] === 'flush' && $in === null ) {
+ // Clear the buffer, we probably don't need to
+ $tmp = $buf;
+ $buf = null;
+ return $tmp;
+ } else
+ // wtf?
+ die(
+ "\nCall this extension as <statictag>string</statictag> or as" .
+ " <statictag action=flush/>, not in any other way.\n" .
+ "text: " . var_export( $in, true ) . "\n" .
+ "argv: " . var_export( $argv, true ) . "\n"
+ );
+}
+?>
diff --git a/maintenance/postgres/compare_schemas.pl b/maintenance/postgres/compare_schemas.pl
new file mode 100644
index 000000000000..cdbbdf411bca
--- /dev/null
+++ b/maintenance/postgres/compare_schemas.pl
@@ -0,0 +1,243 @@
+#!/usr/bin/perl
+
+## Rough check that the base and postgres "tables.sql" are in sync
+## Should be run from maintenance/postgres
+
+use strict;
+use warnings;
+use Data::Dumper;
+
+my @old = ("../tables.sql", "../mysql5/tables.sql", "../mysql5/tables-binary.sql");
+my $new = "tables.sql";
+my @xfile;
+
+## Read in exceptions and other metadata
+my %ok;
+while (<DATA>) {
+ next unless /^(\w+)\s*:\s*([^#]+)/;
+ my ($name,$val) = ($1,$2);
+ chomp $val;
+ if ($name eq 'RENAME') {
+ die "Invalid rename\n" unless $val =~ /(\w+)\s+(\w+)/;
+ $ok{OLD}{$1} = $2;
+ $ok{NEW}{$2} = $1;
+ next;
+ }
+ if ($name eq 'XFILE') {
+ push @xfile, $val;
+ next;
+ }
+ for (split(/\s+/ => $val)) {
+ $ok{$name}{$_} = 0;
+ }
+}
+
+my $datatype = join '|' => qw(
+bool
+tinyint int bigint real float
+tinytext mediumtext text char varchar varbinary
+timestamp datetime
+tinyblob mediumblob blob
+);
+$datatype .= q{|ENUM\([\"\w, ]+\)};
+$datatype = qr{($datatype)};
+
+my $typeval = qr{(\(\d+\))?};
+
+my $typeval2 = qr{ unsigned| binary| NOT NULL| NULL| auto_increment| default ['\-\d\w"]+| REFERENCES .+CASCADE};
+
+my $indextype = join '|' => qw(INDEX KEY FULLTEXT), "PRIMARY KEY", "UNIQUE INDEX", "UNIQUE KEY";
+$indextype = qr{$indextype};
+
+my $engine = qr{TYPE|ENGINE};
+
+my $tabletype = qr{InnoDB|MyISAM|HEAP|HEAP MAX_ROWS=\d+};
+
+my $charset = qr{utf8|binary};
+
+open my $newfh, "<", $new or die qq{Could not open $new: $!\n};
+
+
+my ($table,%old);
+
+## Read in the xfiles
+my %xinfo;
+for my $xfile (@xfile) {
+ print "Loading $xfile\n";
+ my $info = &parse_sql($xfile);
+ for (keys %$info) {
+ $xinfo{$_} = $info->{$_};
+ }
+}
+
+for my $oldfile (@old) {
+ print "Loading $oldfile\n";
+ my $info = &parse_sql($oldfile);
+ for (keys %xinfo) {
+ $info->{$_} = $xinfo{$_};
+ }
+ $old{$oldfile} = $info;
+}
+
+sub parse_sql {
+
+ my $oldfile = shift;
+
+ open my $oldfh, "<", $oldfile or die qq{Could not open $oldfile: $!\n};
+
+ my %info;
+ while (<$oldfh>) {
+ next if /^\s*\-\-/ or /^\s+$/;
+ s/\s*\-\- [\w ]+$//;
+ chomp;
+
+ if (/CREATE\s*TABLE/i) {
+ m{^CREATE TABLE /\*\$wgDBprefix\*/(\w+) \($}
+ or die qq{Invalid CREATE TABLE at line $. of $oldfile\n};
+ $table = $1;
+ $info{$table}{name}=$table;
+ }
+ elsif (/^\) ($engine)=($tabletype);$/) {
+ $info{$table}{engine}=$1;
+ $info{$table}{type}=$2;
+ }
+ elsif (/^\) ($engine)=($tabletype), DEFAULT CHARSET=($charset);$/) {
+ $info{$table}{engine}=$1;
+ $info{$table}{type}=$2;
+ $info{$table}{charset}=$3;
+ }
+ elsif (/^ (\w+) $datatype$typeval$typeval2{0,3},?$/) {
+ $info{$table}{column}{$1} = $2;
+ }
+ elsif (/^ ($indextype)(?: (\w+))? \(([\w, \(\)]+)\),?$/) {
+ $info{$table}{lc $1."_name"} = $2 ? $2 : "";
+ $info{$table}{lc $1."pk_target"} = $3;
+ }
+ else {
+ die "Cannot parse line $. of $oldfile:\n$_\n";
+ }
+
+ }
+ close $oldfh;
+
+ return \%info;
+
+} ## end of parse_sql
+
+for my $oldfile (@old) {
+
+## Begin non-standard indent
+
+## MySQL sanity checks
+for my $table (sort keys %{$old{$oldfile}}) {
+ my $t = $old{$oldfile}{$table};
+ if (($oldfile =~ /5/ and $t->{engine} ne 'ENGINE')
+ or
+ ($oldfile !~ /5/ and $t->{engine} ne 'TYPE')) {
+ die "Invalid engine for $oldfile: $t->{engine}\n" unless $t->{name} eq 'profiling';
+ }
+ my $charset = $t->{charset} || '';
+ if ($oldfile !~ /binary/ and $charset eq 'binary') {
+ die "Invalid charset for $oldfile: $charset\n";
+ }
+}
+
+my $dtype = join '|' => qw(
+SMALLINT INTEGER BIGINT NUMERIC SERIAL
+TEXT CHAR VARCHAR
+BYTEA
+TIMESTAMPTZ
+CIDR
+);
+$dtype = qr{($dtype)};
+my %new;
+my ($infunction,$inview,$inrule) = (0,0,0);
+seek $newfh, 0, 0;
+while (<$newfh>) {
+ next if /^\s*\-\-/ or /^\s*$/;
+ s/\s*\-\- [\w ']+$//;
+ next if /^BEGIN;/ or /^SET / or /^COMMIT;/;
+ next if /^CREATE SEQUENCE/;
+ next if /^CREATE(?: UNIQUE)? INDEX/;
+ next if /^CREATE FUNCTION/;
+ next if /^CREATE TRIGGER/ or /^ FOR EACH ROW/;
+ next if /^INSERT INTO/ or /^ VALUES \(/;
+ next if /^ALTER TABLE/;
+ chomp;
+
+ if (/^\$mw\$;?$/) {
+ $infunction = $infunction ? 0 : 1;
+ next;
+ }
+ next if $infunction;
+
+ next if /^CREATE VIEW/ and $inview = 1;
+ if ($inview) {
+ /;$/ and $inview = 0;
+ next;
+ }
+
+ next if /^CREATE RULE/ and $inrule = 1;
+ if ($inrule) {
+ /;$/ and $inrule = 0;
+ next;
+ }
+
+ if (/^CREATE TABLE "?(\w+)"? \($/) {
+ $table = $1;
+ $new{$table}{name}=$table;
+ }
+ elsif (/^\);$/) {
+ }
+ elsif (/^ (\w+) +$dtype/) {
+ $new{$table}{column}{$1} = $2;
+ }
+ else {
+ die "Cannot parse line $. of $new:\n$_\n";
+ }
+}
+
+## Old but not new
+for my $t (sort keys %{$old{$oldfile}}) {
+ if (!exists $new{$t} and !exists $ok{OLD}{$t}) {
+ print "Table not in $new: $t\n";
+ next;
+ }
+ next if exists $ok{OLD}{$t} and !$ok{OLD}{$t};
+ my $newt = exists $ok{OLD}{$t} ? $ok{OLD}{$t} : $t;
+ my $oldcol = $old{$oldfile}{$t}{column};
+ my $newcol = $new{$newt}{column};
+ for my $c (keys %$oldcol) {
+ if (!exists $newcol->{$c}) {
+ print "Column $t.$c not in new\n";
+ next;
+ }
+ }
+ for my $c (keys %$newcol) {
+ if (!exists $oldcol->{$c}) {
+ print "Column $t.$c not in old\n";
+ next;
+ }
+ }
+}
+## New but not old:
+for (sort keys %new) {
+ if (!exists $old{$oldfile}{$_} and !exists $ok{NEW}{$_}) {
+ print "Not in old: $_\n";
+ next;
+ }
+}
+
+
+} ## end each file to be parsed
+
+
+__DATA__
+## Known exceptions
+OLD: searchindex ## We use tsearch2 directly on the page table instead
+OLD: archive ## This is a view due to the char(14) timestamp hack
+RENAME: user mwuser ## Reserved word causing lots of problems
+RENAME: text pagecontent ## Reserved word
+NEW: archive2 ## The real archive table
+NEW: mediawiki_version ## Just us, for now
+XFILE: ../archives/patch-profiling.sql
diff --git a/maintenance/postgres/tables.sql b/maintenance/postgres/tables.sql
new file mode 100644
index 000000000000..00d8259a22ba
--- /dev/null
+++ b/maintenance/postgres/tables.sql
@@ -0,0 +1,502 @@
+-- SQL to create the initial tables for the MediaWiki database.
+-- This is read and executed by the install script; you should
+-- not have to run it by itself unless doing a manual install.
+-- This is the PostgreSQL version.
+-- For information about each table, please see the notes in maintenance/tables.sql
+-- Please make sure all dollar-quoting uses $mw$ at the start of the line
+-- We can't use SERIAL everywhere: the sequence names are hard-coded into the PHP
+-- TODO: Change CHAR to BOOL
+
+BEGIN;
+SET client_min_messages = 'ERROR';
+
+CREATE SEQUENCE user_user_id_seq MINVALUE 0 START WITH 0;
+CREATE TABLE mwuser ( -- replace reserved word 'user'
+ user_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('user_user_id_seq'),
+ user_name TEXT NOT NULL UNIQUE,
+ user_real_name TEXT,
+ user_password TEXT,
+ user_newpassword TEXT,
+ user_newpass_time TIMESTAMPTZ,
+ user_token CHAR(32),
+ user_email TEXT,
+ user_email_token CHAR(32),
+ user_email_token_expires TIMESTAMPTZ,
+ user_email_authenticated TIMESTAMPTZ,
+ user_options TEXT,
+ user_touched TIMESTAMPTZ,
+ user_registration TIMESTAMPTZ,
+ user_editcount INTEGER
+);
+CREATE INDEX user_email_token_idx ON mwuser (user_email_token);
+
+-- Create a dummy user to satisfy fk contraints especially with revisions
+INSERT INTO mwuser
+ VALUES (DEFAULT,'Anonymous','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,now(),now());
+
+CREATE TABLE user_groups (
+ ug_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
+ ug_group TEXT NOT NULL
+);
+CREATE UNIQUE INDEX user_groups_unique ON user_groups (ug_user, ug_group);
+
+CREATE TABLE user_newtalk (
+ user_id INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
+ user_ip CIDR NULL
+);
+CREATE INDEX user_newtalk_id_idx ON user_newtalk (user_id);
+CREATE INDEX user_newtalk_ip_idx ON user_newtalk (user_ip);
+
+
+CREATE SEQUENCE page_page_id_seq;
+CREATE TABLE page (
+ page_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('page_page_id_seq'),
+ page_namespace SMALLINT NOT NULL,
+ page_title TEXT NOT NULL,
+ page_restrictions TEXT,
+ page_counter BIGINT NOT NULL DEFAULT 0,
+ page_is_redirect CHAR NOT NULL DEFAULT 0,
+ page_is_new CHAR NOT NULL DEFAULT 0,
+ page_random NUMERIC(15,14) NOT NULL DEFAULT RANDOM(),
+ page_touched TIMESTAMPTZ,
+ page_latest INTEGER NOT NULL, -- FK?
+ page_len INTEGER NOT NULL
+);
+CREATE UNIQUE INDEX page_unique_name ON page (page_namespace, page_title);
+CREATE INDEX page_main_title ON page (page_title) WHERE page_namespace = 0;
+CREATE INDEX page_talk_title ON page (page_title) WHERE page_namespace = 1;
+CREATE INDEX page_user_title ON page (page_title) WHERE page_namespace = 2;
+CREATE INDEX page_utalk_title ON page (page_title) WHERE page_namespace = 3;
+CREATE INDEX page_project_title ON page (page_title) WHERE page_namespace = 4;
+CREATE INDEX page_random_idx ON page (page_random);
+CREATE INDEX page_len_idx ON page (page_len);
+
+CREATE FUNCTION page_deleted() RETURNS TRIGGER LANGUAGE plpgsql AS
+$mw$
+BEGIN
+DELETE FROM recentchanges WHERE rc_namespace = OLD.page_namespace AND rc_title = OLD.page_title;
+RETURN NULL;
+END;
+$mw$;
+
+CREATE TRIGGER page_deleted AFTER DELETE ON page
+ FOR EACH ROW EXECUTE PROCEDURE page_deleted();
+
+CREATE SEQUENCE rev_rev_id_val;
+CREATE TABLE revision (
+ rev_id INTEGER NOT NULL UNIQUE DEFAULT nextval('rev_rev_id_val'),
+ rev_page INTEGER NULL REFERENCES page (page_id) ON DELETE CASCADE,
+ rev_text_id INTEGER NULL, -- FK
+ rev_comment TEXT,
+ rev_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE RESTRICT,
+ rev_user_text TEXT NOT NULL,
+ rev_timestamp TIMESTAMPTZ NOT NULL,
+ rev_minor_edit CHAR NOT NULL DEFAULT '0',
+ rev_deleted CHAR NOT NULL DEFAULT '0'
+);
+CREATE UNIQUE INDEX revision_unique ON revision (rev_page, rev_id);
+CREATE INDEX rev_timestamp_idx ON revision (rev_timestamp);
+CREATE INDEX rev_user_idx ON revision (rev_user);
+CREATE INDEX rev_user_text_idx ON revision (rev_user_text);
+
+
+CREATE SEQUENCE text_old_id_val;
+CREATE TABLE pagecontent ( -- replaces reserved word 'text'
+ old_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('text_old_id_val'),
+ old_text TEXT,
+ old_flags TEXT
+);
+
+
+CREATE TABLE archive2 (
+ ar_namespace SMALLINT NOT NULL,
+ ar_title TEXT NOT NULL,
+ ar_text TEXT,
+ ar_comment TEXT,
+ ar_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ ar_user_text TEXT NOT NULL,
+ ar_timestamp TIMESTAMPTZ NOT NULL,
+ ar_minor_edit CHAR NOT NULL DEFAULT '0',
+ ar_flags TEXT,
+ ar_rev_id INTEGER,
+ ar_text_id INTEGER
+);
+CREATE INDEX archive_name_title_timestamp ON archive2 (ar_namespace,ar_title,ar_timestamp);
+
+-- This is the easiest way to work around the char(15) timestamp hack without modifying PHP code
+CREATE VIEW archive AS
+SELECT
+ ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
+ ar_minor_edit, ar_flags, ar_rev_id, ar_text_id,
+ TO_CHAR(ar_timestamp, 'YYYYMMDDHH24MISS') AS ar_timestamp
+FROM archive2;
+
+CREATE RULE archive_insert AS ON INSERT TO archive
+DO INSTEAD INSERT INTO archive2 VALUES (
+ NEW.ar_namespace, NEW.ar_title, NEW.ar_text, NEW.ar_comment, NEW.ar_user, NEW.ar_user_text,
+ TO_DATE(NEW.ar_timestamp, 'YYYYMMDDHH24MISS'),
+ NEW.ar_minor_edit, NEW.ar_flags, NEW.ar_rev_id, NEW.ar_text_id
+);
+
+
+CREATE TABLE redirect (
+ rd_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ rd_namespace SMALLINT NOT NULL,
+ rd_title TEXT NOT NULL
+);
+CREATE INDEX redirect_ns_title ON redirect (rd_namespace,rd_title,rd_from);
+
+
+CREATE TABLE pagelinks (
+ pl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ pl_namespace SMALLINT NOT NULL,
+ pl_title TEXT NOT NULL
+);
+CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title);
+
+CREATE TABLE templatelinks (
+ tl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ tl_namespace TEXT NOT NULL,
+ tl_title TEXT NOT NULL
+);
+CREATE UNIQUE INDEX templatelinks_unique ON templatelinks (tl_namespace,tl_title,tl_from);
+
+CREATE TABLE imagelinks (
+ il_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ il_to TEXT NOT NULL
+);
+CREATE UNIQUE INDEX il_from ON imagelinks (il_to,il_from);
+
+CREATE TABLE categorylinks (
+ cl_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ cl_to TEXT NOT NULL,
+ cl_sortkey TEXT,
+ cl_timestamp TIMESTAMPTZ NOT NULL
+);
+CREATE UNIQUE INDEX cl_from ON categorylinks (cl_from, cl_to);
+CREATE INDEX cl_sortkey ON categorylinks (cl_to, cl_sortkey);
+
+CREATE TABLE externallinks (
+ el_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ el_to TEXT NOT NULL,
+ el_index TEXT NOT NULL
+);
+CREATE INDEX externallinks_from_to ON externallinks (el_from,el_to);
+CREATE INDEX externallinks_index ON externallinks (el_index);
+
+CREATE TABLE langlinks (
+ ll_from INTEGER NOT NULL REFERENCES page (page_id) ON DELETE CASCADE,
+ ll_lang TEXT,
+ ll_title TEXT
+);
+CREATE UNIQUE INDEX langlinks_unique ON langlinks (ll_from,ll_lang);
+CREATE INDEX langlinks_lang_title ON langlinks (ll_lang,ll_title);
+
+
+CREATE TABLE site_stats (
+ ss_row_id INTEGER NOT NULL UNIQUE,
+ ss_total_views INTEGER DEFAULT 0,
+ ss_total_edits INTEGER DEFAULT 0,
+ ss_good_articles INTEGER DEFAULT 0,
+ ss_total_pages INTEGER DEFAULT -1,
+ ss_users INTEGER DEFAULT -1,
+ ss_admins INTEGER DEFAULT -1,
+ ss_images INTEGER DEFAULT 0
+);
+
+CREATE TABLE hitcounter (
+ hc_id BIGINT NOT NULL
+);
+
+
+CREATE SEQUENCE ipblocks_ipb_id_val;
+CREATE TABLE ipblocks (
+ ipb_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('ipblocks_ipb_id_val'),
+ ipb_address TEXT NULL,
+ ipb_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ ipb_by INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
+ ipb_reason TEXT NOT NULL,
+ ipb_timestamp TIMESTAMPTZ NOT NULL,
+ ipb_auto CHAR NOT NULL DEFAULT '0',
+ ipb_anon_only CHAR NOT NULL DEFAULT '0',
+ ipb_create_account CHAR NOT NULL DEFAULT '1',
+ ipb_enable_autoblock CHAR NOT NULL DEFAULT '1',
+ ipb_expiry TIMESTAMPTZ NOT NULL,
+ ipb_range_start TEXT,
+ ipb_range_end TEXT
+);
+CREATE INDEX ipb_address ON ipblocks (ipb_address);
+CREATE INDEX ipb_user ON ipblocks (ipb_user);
+CREATE INDEX ipb_range ON ipblocks (ipb_range_start,ipb_range_end);
+
+
+CREATE TABLE image (
+ img_name TEXT NOT NULL PRIMARY KEY,
+ img_size INTEGER NOT NULL,
+ img_width INTEGER NOT NULL,
+ img_height INTEGER NOT NULL,
+ img_metadata TEXT,
+ img_bits SMALLINT,
+ img_media_type TEXT,
+ img_major_mime TEXT DEFAULT 'unknown',
+ img_minor_mime TEXT DEFAULT 'unknown',
+ img_description TEXT NOT NULL,
+ img_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ img_user_text TEXT NOT NULL,
+ img_timestamp TIMESTAMPTZ
+);
+CREATE INDEX img_size_idx ON image (img_size);
+CREATE INDEX img_timestamp_idx ON image (img_timestamp);
+
+CREATE TABLE oldimage (
+ oi_name TEXT NOT NULL REFERENCES image(img_name),
+ oi_archive_name TEXT NOT NULL,
+ oi_size INTEGER NOT NULL,
+ oi_width INTEGER NOT NULL,
+ oi_height INTEGER NOT NULL,
+ oi_bits SMALLINT NOT NULL,
+ oi_description TEXT,
+ oi_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ oi_user_text TEXT NOT NULL,
+ oi_timestamp TIMESTAMPTZ NOT NULL
+);
+CREATE INDEX oi_name ON oldimage (oi_name);
+
+
+CREATE TABLE filearchive (
+ fa_id SERIAL NOT NULL PRIMARY KEY,
+ fa_name TEXT NOT NULL,
+ fa_archive_name TEXT,
+ fa_storage_group VARCHAR(16),
+ fa_storage_key CHAR(64),
+ fa_deleted_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ fa_deleted_timestamp TIMESTAMPTZ NOT NULL,
+ fa_deleted_reason TEXT,
+ fa_size SMALLINT NOT NULL,
+ fa_width SMALLINT NOT NULL,
+ fa_height SMALLINT NOT NULL,
+ fa_metadata TEXT,
+ fa_bits SMALLINT,
+ fa_media_type TEXT,
+ fa_major_mime TEXT DEFAULT 'unknown',
+ fa_minor_mime TEXT DEFAULT 'unknown',
+ fa_description TEXT NOT NULL,
+ fa_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ fa_user_text TEXT NOT NULL,
+ fa_timestamp TIMESTAMPTZ
+);
+CREATE INDEX fa_name_time ON filearchive (fa_name, fa_timestamp);
+CREATE INDEX fa_dupe ON filearchive (fa_storage_group, fa_storage_key);
+CREATE INDEX fa_notime ON filearchive (fa_deleted_timestamp);
+CREATE INDEX fa_nouser ON filearchive (fa_deleted_user);
+
+
+CREATE SEQUENCE rc_rc_id_seq;
+CREATE TABLE recentchanges (
+ rc_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('rc_rc_id_seq'),
+ rc_timestamp TIMESTAMPTZ NOT NULL,
+ rc_cur_time TIMESTAMPTZ NOT NULL,
+ rc_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ rc_user_text TEXT NOT NULL,
+ rc_namespace SMALLINT NOT NULL,
+ rc_title TEXT NOT NULL,
+ rc_comment TEXT,
+ rc_minor CHAR NOT NULL DEFAULT '0',
+ rc_bot CHAR NOT NULL DEFAULT '0',
+ rc_new CHAR NOT NULL DEFAULT '0',
+ rc_cur_id INTEGER NULL REFERENCES page(page_id) ON DELETE SET NULL,
+ rc_this_oldid INTEGER NOT NULL,
+ rc_last_oldid INTEGER NOT NULL,
+ rc_type CHAR NOT NULL DEFAULT '0',
+ rc_moved_to_ns SMALLINT,
+ rc_moved_to_title TEXT,
+ rc_patrolled CHAR NOT NULL DEFAULT '0',
+ rc_ip CIDR,
+ rc_old_len INTEGER,
+ rc_new_len INTEGER
+);
+CREATE INDEX rc_timestamp ON recentchanges (rc_timestamp);
+CREATE INDEX rc_namespace_title ON recentchanges (rc_namespace, rc_title);
+CREATE INDEX rc_cur_id ON recentchanges (rc_cur_id);
+CREATE INDEX new_name_timestamp ON recentchanges (rc_new, rc_namespace, rc_timestamp);
+CREATE INDEX rc_ip ON recentchanges (rc_ip);
+
+
+CREATE TABLE watchlist (
+ wl_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE,
+ wl_namespace SMALLINT NOT NULL DEFAULT 0,
+ wl_title TEXT NOT NULL,
+ wl_notificationtimestamp TIMESTAMPTZ
+);
+CREATE UNIQUE INDEX wl_user_namespace_title ON watchlist (wl_namespace, wl_title, wl_user);
+
+
+CREATE TABLE math (
+ math_inputhash TEXT NOT NULL UNIQUE,
+ math_outputhash TEXT NOT NULL,
+ math_html_conservativeness SMALLINT NOT NULL,
+ math_html TEXT,
+ math_mathml TEXT
+);
+
+
+CREATE TABLE interwiki (
+ iw_prefix TEXT NOT NULL UNIQUE,
+ iw_url TEXT NOT NULL,
+ iw_local CHAR NOT NULL,
+ iw_trans CHAR NOT NULL DEFAULT '0'
+);
+
+
+CREATE TABLE querycache (
+ qc_type TEXT NOT NULL,
+ qc_value SMALLINT NOT NULL,
+ qc_namespace SMALLINT NOT NULL,
+ qc_title TEXT NOT NULL
+);
+CREATE INDEX querycache_type_value ON querycache (qc_type, qc_value);
+
+CREATE TABLE querycache_info (
+ qci_type TEXT UNIQUE,
+ qci_timestamp TIMESTAMPTZ NULL
+);
+
+CREATE TABLE querycachetwo (
+ qcc_type TEXT NOT NULL,
+ qcc_value SMALLINT NOT NULL DEFAULT 0,
+ qcc_namespace INTEGER NOT NULL DEFAULT 0,
+ qcc_title TEXT NOT NULL DEFAULT '',
+ qcc_namespacetwo INTEGER NOT NULL DEFAULT 0,
+ qcc_titletwo TEXT NOT NULL DEFAULT ''
+);
+CREATE INDEX querycachetwo_type_value ON querycachetwo (qcc_type, qcc_value);
+CREATE INDEX querycachetwo_title ON querycachetwo (qcc_type,qcc_namespace,qcc_title);
+CREATE INDEX querycachetwo_titletwo ON querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
+
+
+CREATE TABLE objectcache (
+ keyname CHAR(255) UNIQUE,
+ value BYTEA NOT NULL DEFAULT '',
+ exptime TIMESTAMPTZ NOT NULL
+);
+CREATE INDEX objectcacache_exptime ON objectcache (exptime);
+
+CREATE TABLE transcache (
+ tc_url TEXT NOT NULL UNIQUE,
+ tc_contents TEXT NOT NULL,
+ tc_time TIMESTAMPTZ NOT NULL
+);
+
+
+CREATE TABLE logging (
+ log_type TEXT NOT NULL,
+ log_action TEXT NOT NULL,
+ log_timestamp TIMESTAMPTZ NOT NULL,
+ log_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
+ log_namespace SMALLINT NOT NULL,
+ log_title TEXT NOT NULL,
+ log_comment TEXT,
+ log_params TEXT
+);
+CREATE INDEX logging_type_name ON logging (log_type, log_timestamp);
+CREATE INDEX logging_user_time ON logging (log_timestamp, log_user);
+CREATE INDEX logging_page_time ON logging (log_namespace, log_title, log_timestamp);
+
+
+CREATE TABLE trackbacks (
+ tb_id SERIAL NOT NULL PRIMARY KEY,
+ tb_page INTEGER REFERENCES page(page_id) ON DELETE CASCADE,
+ tb_title TEXT NOT NULL,
+ tb_url TEXT NOT NULL,
+ tb_ex TEXT,
+ tb_name TEXT
+);
+CREATE INDEX trackback_page ON trackbacks (tb_page);
+
+
+CREATE SEQUENCE job_job_id_seq;
+CREATE TABLE job (
+ job_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('job_job_id_seq'),
+ job_cmd TEXT NOT NULL,
+ job_namespace SMALLINT NOT NULL,
+ job_title TEXT NOT NULL,
+ job_params TEXT NOT NULL
+);
+CREATE INDEX job_cmd_namespace_title ON job (job_cmd, job_namespace, job_title);
+
+-- Tsearch2 2 stuff. Will fail if we don't have proper access to the tsearch2 tables
+
+ALTER TABLE page ADD titlevector tsvector;
+CREATE INDEX ts2_page_title ON page USING gist(titlevector);
+CREATE FUNCTION ts2_page_title() RETURNS TRIGGER LANGUAGE plpgsql AS
+$mw$
+BEGIN
+IF TG_OP = 'INSERT' THEN
+ NEW.titlevector = to_tsvector('default',NEW.page_title);
+ELSIF NEW.page_title != OLD.page_title THEN
+ NEW.titlevector := to_tsvector('default',NEW.page_title);
+END IF;
+RETURN NEW;
+END;
+$mw$;
+
+CREATE TRIGGER ts2_page_title BEFORE INSERT OR UPDATE ON page
+ FOR EACH ROW EXECUTE PROCEDURE ts2_page_title();
+
+
+ALTER TABLE pagecontent ADD textvector tsvector;
+CREATE INDEX ts2_page_text ON pagecontent USING gist(textvector);
+CREATE FUNCTION ts2_page_text() RETURNS TRIGGER LANGUAGE plpgsql AS
+$mw$
+BEGIN
+IF TG_OP = 'INSERT' THEN
+ NEW.textvector = to_tsvector('default',NEW.old_text);
+ELSIF NEW.old_text != OLD.old_text THEN
+ NEW.textvector := to_tsvector('default',NEW.old_text);
+END IF;
+RETURN NEW;
+END;
+$mw$;
+
+CREATE TRIGGER ts2_page_text BEFORE INSERT OR UPDATE ON pagecontent
+ FOR EACH ROW EXECUTE PROCEDURE ts2_page_text();
+
+CREATE FUNCTION add_interwiki (TEXT,INT,CHAR) RETURNS INT LANGUAGE SQL AS
+$mw$
+ INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES ($1,$2,$3);
+ SELECT 1;
+$mw$;
+
+-- This table is not used unless profiling is turned on
+CREATE TABLE profiling (
+ pf_count INTEGER NOT NULL DEFAULT 0,
+ pf_time NUMERIC(18,10) NOT NULL DEFAULT 0,
+ pf_name TEXT NOT NULL,
+ pf_server TEXT NULL
+);
+CREATE UNIQUE INDEX pf_name_server ON profiling (pf_name, pf_server);
+
+
+CREATE TABLE mediawiki_version (
+ type TEXT NOT NULL,
+ mw_version TEXT NOT NULL,
+ notes TEXT NULL,
+
+ pg_version TEXT NULL,
+ pg_dbname TEXT NULL,
+ pg_user TEXT NULL,
+ pg_port TEXT NULL,
+ mw_schema TEXT NULL,
+ ts2_schema TEXT NULL,
+ ctype TEXT NULL,
+
+ sql_version TEXT NULL,
+ sql_date TEXT NULL,
+ cdate TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+INSERT INTO mediawiki_version (type,mw_version,sql_version,sql_date)
+ VALUES ('Creation','??','$LastChangedRevision$','$LastChangedDate$');
+
+
+COMMIT;
diff --git a/maintenance/postgres/wp_mysql2postgres.pl b/maintenance/postgres/wp_mysql2postgres.pl
new file mode 100644
index 000000000000..57e32e960acb
--- /dev/null
+++ b/maintenance/postgres/wp_mysql2postgres.pl
@@ -0,0 +1,400 @@
+#!/usr/bin/perl
+
+## Convert data from a MySQL mediawiki database into a Postgres mediawiki database
+## svn: $Id$
+
+use strict;
+use warnings;
+use Data::Dumper;
+use Getopt::Long;
+
+use vars qw(%table %tz %special @torder $COM);
+my $VERSION = "1.0";
+
+## The following options can be changed via command line arguments:
+my $MYSQLDB = 'wikidb';
+my $MYSQLUSER = 'wikiuser';
+
+## If the following are zero-length, we omit their arguments entirely:
+my $MYSQLHOST = '';
+my $MYSQLPASSWORD = '';
+my $MYSQLSOCKET = '';
+
+## Name of the dump file created
+my $MYSQLDUMPFILE = "mediawiki_upgrade.pg";
+
+## How verbose should this script be (0, 1, or 2)
+my $verbose = 0;
+
+my $USAGE = "
+Usage: $0 [OPTION]...
+Convert a MediaWiki schema from MySQL to Postgres
+Example: $0 --db=wikidb --user=wikiuser --pass=sushi
+Options:
+ db Name of the MySQL database
+ user MySQL database username
+ pass MySQL database password
+ host MySQL database host
+ socket MySQL database socket
+ verbose Verbosity, increases with multiple uses
+";
+
+GetOptions
+ (
+ "db=s" => \$MYSQLDB,
+ "user=s" => \$MYSQLUSER,
+ "pass=s" => \$MYSQLPASSWORD,
+ "host=s" => \$MYSQLHOST,
+ "socket=s" => \$MYSQLSOCKET,
+ "verbose+" => \$verbose
+ );
+
+## The Postgres schema file: should not be changed
+my $PG_SCHEMA = "tables.sql";
+
+## What version we default to when we can't parse the old schema
+my $MW_DEFAULT_VERSION = '1.8';
+
+## Try and find a working version of mysqldump
+$verbose and warn "Locating the mysqldump executable\n";
+my @MYSQLDUMP = ("/usr/local/bin/mysqldump", "/usr/bin/mysqldump");
+my $MYSQLDUMP;
+for my $mytry (@MYSQLDUMP) {
+ next if ! -e $mytry;
+ -x $mytry or die qq{Not an executable file: "$mytry"\n};
+ my $version = qx{$mytry -V};
+ $version =~ /^mysqldump\s+Ver\s+\d+/ or die qq{Program at "$mytry" does not act like mysqldump\n};
+ $MYSQLDUMP = $mytry;
+}
+$MYSQLDUMP or die qq{Could not find the mysqldump program\n};
+
+## Flags we use for mysqldump
+my @MYSQLDUMPARGS = qw(
+--skip-lock-tables
+--complete-insert
+--skip-extended-insert
+--skip-add-drop-table
+--skip-add-locks
+--skip-disable-keys
+--skip-set-charset
+--skip-comments
+--skip-quote-names
+);
+
+
+$verbose and warn "Checking that mysqldump can handle our flags\n";
+## Make sure this version can handle all the flags we want.
+## Combine with user dump below
+my $MYSQLDUMPARGS = join " " => @MYSQLDUMPARGS;
+## Argh. Any way to make this work on Win32?
+my $version = qx{$MYSQLDUMP $MYSQLDUMPARGS 2>&1};
+if ($version =~ /unknown option/) {
+ die qq{Sorry, you need to use a newer version of the mysqldump program than the one at "$MYSQLDUMP"\n};
+}
+
+push @MYSQLDUMPARGS, "--user=$MYSQLUSER";
+length $MYSQLPASSWORD and push @MYSQLDUMPARGS, "--password=$MYSQLPASSWORD";
+length $MYSQLHOST and push @MYSQLDUMPARGS, "--host=$MYSQLHOST";
+
+## Open the dump file to hold the mysqldump output
+open my $mdump, "+>", $MYSQLDUMPFILE or die qq{Could not open "$MYSQLDUMPFILE": $!\n};
+$verbose and warn qq{Writing file "$MYSQLDUMPFILE"\n};
+
+open my $mfork2, "-|" or exec $MYSQLDUMP, @MYSQLDUMPARGS, "--no-data", $MYSQLDB;
+my $oldselect = select $mdump;
+
+print while <$mfork2>;
+
+## Slurp in the current schema
+my $current_schema;
+seek $mdump, 0, 0;
+{
+ local $/;
+ $current_schema = <$mdump>;
+}
+seek $mdump, 0, 0;
+truncate $mdump, 0;
+
+warn qq{Trying to determine database version...\n} if $verbose;
+
+my $current_version = 0;
+if ($current_schema =~ /CREATE TABLE \S+cur /) {
+ $current_version = '1.3';
+}
+elsif ($current_schema =~ /CREATE TABLE \S+brokenlinks /) {
+ $current_version = '1.4';
+}
+elsif ($current_schema !~ /CREATE TABLE \S+templatelinks /) {
+ $current_version = '1.5';
+}
+elsif ($current_schema !~ /CREATE TABLE \S+validate /) {
+ $current_version = '1.6';
+}
+elsif ($current_schema !~ /ipb_auto tinyint/) {
+ $current_version = '1.7';
+}
+else {
+ $current_version = '1.8';
+}
+
+if (!$current_version) {
+ warn qq{WARNING! Could not figure out the old version, assuming MediaWiki $MW_DEFAULT_VERSION\n};
+ $current_version = $MW_DEFAULT_VERSION;
+}
+
+## Check for a table prefix:
+my $table_prefix = '';
+if ($current_version =~ /CREATE TABLE (\S+)archive /) {
+ $table_prefix = $1;
+}
+
+warn qq{Old schema is from MediaWiki version $current_version\n} if $verbose;
+warn qq{Table prefix is "$table_prefix"\n} if $verbose and length $table_prefix;
+
+$verbose and warn qq{Writing file "$MYSQLDUMPFILE"\n};
+my $now = scalar localtime();
+my $conninfo = '';
+$MYSQLHOST and $conninfo .= "\n-- host $MYSQLHOST";
+$MYSQLSOCKET and $conninfo .= "\n-- socket $MYSQLSOCKET";
+
+print qq{
+-- Dump of MySQL Mediawiki tables for import into a Postgres Mediawiki schema
+-- Performed by the program: $0
+-- Version: $VERSION (subversion }.q{$LastChangedRevision$}.qq{)
+-- Author: Greg Sabino Mullane <greg\@turnstep.com> Comments welcome
+--
+-- This file was created: $now
+-- Executable used: $MYSQLDUMP
+-- Connection information:
+-- database: $MYSQLDB
+-- user: $MYSQLUSER$conninfo
+
+-- This file can be imported manually with psql like so:
+-- psql -p port# -h hostname -U username -f $MYSQLDUMPFILE databasename
+-- This will overwrite any existing MediaWiki information, so be careful
+
+
+};
+
+warn qq{Reading in the Postgres schema information\n} if $verbose;
+open my $schema, "<", $PG_SCHEMA
+ or die qq{Could not open "$PG_SCHEMA": make sure this script is run from maintenance/postgres/\n};
+my $t;
+while (<$schema>) {
+ if (/CREATE TABLE\s+(\S+)/) {
+ $t = $1;
+ $table{$t}={};
+ }
+ elsif (/^ +(\w+)\s+TIMESTAMP/) {
+ $tz{$t}{$1}++;
+ }
+ elsif (/REFERENCES\s*([^( ]+)/) {
+ my $ref = $1;
+ exists $table{$ref} or die qq{No parent table $ref found for $t\n};
+ $table{$t}{$ref}++;
+ }
+}
+close $schema;
+
+## Read in special cases and table/version information
+$verbose and warn qq{Reading in schema exception information\n};
+my %version_tables;
+while (<DATA>) {
+ if (/^VERSION\s+(\d+\.\d+):\s+(.+)/) {
+ my $list = join '|' => split /\s+/ => $2;
+ $version_tables{$1} = qr{\b$list\b};
+ next;
+ }
+ next unless /^(\w+)\s*(.*)/;
+ $special{$1} = $2||'';
+ $special{$2} = $1 if length $2;
+}
+
+## Determine the order of tables based on foreign key constraints
+$verbose and warn qq{Figuring out order of tables to dump\n};
+my %dumped;
+my $bail = 0;
+{
+ my $found=0;
+ T: for my $t (sort keys %table) {
+ next if exists $dumped{$t} and $dumped{$t} >= 1;
+ $found=1;
+ for my $dep (sort keys %{$table{$t}}) {
+ next T if ! exists $dumped{$dep} or $dumped{$dep} < 0;
+ }
+ $dumped{$t} = -1 if ! exists $dumped{$t};
+ ## Skip certain tables that are not imported
+ next if exists $special{$t} and !$special{$t};
+ push @torder, $special{$t} || $t;
+ }
+ last if !$found;
+ push @torder, "---";
+ for (values %dumped) { $_+=2; }
+ die "Too many loops!\n" if $bail++ > 1000;
+ redo;
+}
+
+## Prepare the Postgres database for the move
+$verbose and warn qq{Writing Postgres transformation information\n};
+
+print "\n-- Empty out all existing tables\n";
+$verbose and warn qq{Writing truncates to empty existing tables\n};
+for my $t (@torder) {
+ next if $t eq '---';
+ my $tname = $special{$t}||$t;
+ printf qq{TRUNCATE TABLE %-18s CASCADE;\n}, qq{"$tname"};
+}
+print "\n\n";
+
+print qq{-- Rename the "text" table\n};
+print qq{ALTER TABLE pagecontent RENAME TO "text";\n\n};
+
+print qq{-- Allow rc_ip to contain empty string, will convert at end\n};
+print qq{ALTER TABLE recentchanges ALTER rc_ip TYPE text USING host(rc_ip);\n\n};
+
+print "-- Changing all timestamp fields to handle raw integers\n";
+for my $t (sort keys %tz) {
+ next if $t eq "archive2";
+ for my $c (sort keys %{$tz{$t}}) {
+ printf "ALTER TABLE %-18s ALTER %-25s TYPE TEXT;\n", $t, $c;
+ }
+}
+print "\n";
+
+print qq{
+INSERT INTO page VALUES (0,-1,'Dummy Page','',0,0,0,default,now(),0,10);
+};
+
+## If we have a table _prefix, we need to temporarily rename all of our Postgres
+## tables temporarily for the import. Perhaps consider making this an auto-schema
+## thing in the future.
+if (length $table_prefix) {
+ print qq{\n\n-- Temporarily renaming tables to accomodate the table_prefix "$table_prefix"\n\n};
+ for my $t (@torder) {
+ next if $t eq '---';
+ my $tname = $special{$t}||$t;
+ printf qq{ALTER TABLE %-18s RENAME TO "${table_prefix}$tname"\n}, qq{"$tname"};
+ }
+}
+
+
+## Try and dump the ill-named "user" table:
+## We do this table alone because "user" is a reserved word.
+print qq{
+
+SET escape_string_warning TO 'off';
+\\o /dev/null
+
+-- Postgres uses a table name of "mwuser" instead of "user"
+
+-- Create a dummy user to satisfy fk contraints especially with revisions
+SELECT setval('user_user_id_seq',0,'false');
+INSERT INTO mwuser
+ VALUES (DEFAULT,'Anonymous','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,now(),now());
+
+};
+
+push @MYSQLDUMPARGS, "--no-create-info";
+
+$verbose and warn qq{Dumping "user" table\n};
+$verbose > 2 and warn Dumper \@MYSQLDUMPARGS;
+my $usertable = "${table_prefix}user";
+open my $mfork, "-|" or exec $MYSQLDUMP, @MYSQLDUMPARGS, $MYSQLDB, $usertable;
+## Unfortunately, there is no easy way to catch errors
+my $numusers = 0;
+while (<$mfork>) {
+ ++$numusers and print if s/INSERT INTO $usertable/INSERT INTO mwuser/;
+}
+close $mfork;
+if ($numusers < 1) {
+ warn qq{No users found, probably a connection error.\n};
+ print qq{ERROR: No users found, connection failed, or table "$usertable" does not exist. Dump aborted.\n};
+ close $mdump;
+ exit;
+}
+print "\n-- Users loaded: $numusers\n\n-- Loading rest of the mediawiki schema:\n";
+
+warn qq{Dumping all other tables from the MySQL schema\n} if $verbose;
+
+## Dump the rest of the tables, in chunks based on constraints
+## We do not need the user table:
+my @dumplist = grep { $_ ne 'user'} @torder;
+my @alist;
+{
+ undef @alist;
+ PICKATABLE: {
+ my $tname = shift @dumplist;
+ ## XXX Make this dynamic below
+ for my $ver (sort {$b <=> $a } keys %version_tables) {
+ redo PICKATABLE if $tname =~ $version_tables{$ver};
+ }
+ $tname = "${table_prefix}$tname" if length $table_prefix;
+ push @alist, $tname;
+ pop @alist and last if index($alist[-1],'---') >= 0;
+ redo if @dumplist;
+ }
+
+ ## Dump everything else
+ open my $mfork2, "-|" or exec $MYSQLDUMP, @MYSQLDUMPARGS, $MYSQLDB, @alist;
+ print while <$mfork2>;
+ close $mfork2;
+ warn qq{Finished dumping from MySQL\n} if $verbose;
+
+ redo if @dumplist;
+}
+
+warn qq{Writing information to return Postgres database to normal\n} if $verbose;
+print qq{ALTER TABLE "${table_prefix}text" RENAME TO pagecontent;\n};
+print qq{ALTER TABLE ${table_prefix}recentchanges ALTER rc_ip TYPE cidr USING\n};
+print qq{ CASE WHEN rc_ip = '' THEN NULL ELSE rc_ip::cidr END;\n};
+
+## Return tables to their original names if a table prefix was used.
+if (length $table_prefix) {
+ print qq{\n\n-- Renaming tables by removing table prefix "$table_prefix"\n\n};
+ my $maxsize = 18;
+ for (@torder) {
+ $maxsize = length "$_$table_prefix" if length "$_$table_prefix" > $maxsize;
+ }
+ for my $t (@torder) {
+ next if $t eq '---' or $t eq 'text';
+ my $tname = $special{$t}||$t;
+ printf qq{ALTER TABLE %*s RENAME TO "$tname"\n}, $maxsize+1, qq{"${table_prefix}$tname"};
+ }
+}
+
+print qq{\n\n--Returning timestamps to normal\n};
+for my $t (sort keys %tz) {
+ next if $t eq "archive2";
+ for my $c (sort keys %{$tz{$t}}) {
+ printf "ALTER TABLE %-18s ALTER %-25s TYPE timestamptz\n".
+ " USING TO_TIMESTAMP($c,'YYYYMMDDHHMISS');\n", $t, $c;
+ }
+}
+
+## Finally, make a record in the mediawiki_version table about this import
+print qq{
+INSERT INTO mediawiki_version (type,mw_version,notes) VALUES ('MySQL import','??',
+'Imported from file created on $now. Old version: $current_version');
+};
+
+
+print "\\o\n\n-- End of dump\n\n";
+select $oldselect;
+close $mdump;
+exit;
+
+
+__DATA__
+## Known remappings: either indicate the MySQL name,
+## or leave blank if it should be skipped
+pagecontent text
+mwuser user
+mediawiki_version
+archive2
+profiling
+objectcache
+
+## Which tables to ignore depending on the version
+VERSION 1.5: trackback
+VERSION 1.6: externallinks job templatelinks transcache
+VERSION 1.7: filearchive langlinks querycache_info
diff --git a/maintenance/purgeList.php b/maintenance/purgeList.php
new file mode 100644
index 000000000000..9bf7c1bfcdc4
--- /dev/null
+++ b/maintenance/purgeList.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * Send purge requests for listed pages to squid
+ */
+
+require_once( "commandLine.inc" );
+
+$stdin = fopen( "php://stdin", "rt" );
+$urls = array();
+
+while( !feof( $stdin ) ) {
+ $page = trim( fgets( $stdin ) );
+ if ( substr( $page, 0, 7 ) == 'http://' ) {
+ $urls[] = $page;
+ } elseif( $page !== '' ) {
+ $title = Title::newFromText( $page );
+ if( $title ) {
+ $url = $title->getFullUrl();
+ echo "$url\n";
+ $urls[] = $url;
+ } else {
+ echo "(Invalid title '$page')\n";
+ }
+ }
+}
+
+echo "Purging " . count( $urls ) . " urls...\n";
+$u = new SquidUpdate( $urls );
+$u->doUpdate();
+
+echo "Done!\n";
+
+?>
diff --git a/maintenance/purgeOldText.inc b/maintenance/purgeOldText.inc
new file mode 100644
index 000000000000..0bf6225adfa9
--- /dev/null
+++ b/maintenance/purgeOldText.inc
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * Support functions for cleaning up redundant text records
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+function PurgeRedundantText( $delete = false ) {
+
+ # Data should come off the master, wrapped in a transaction
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->begin();
+
+ $tbl_arc = $dbw->tableName( 'archive' );
+ $tbl_rev = $dbw->tableName( 'revision' );
+ $tbl_txt = $dbw->tableName( 'text' );
+
+ # Get "active" text records from the revisions table
+ echo( "Searching for active text records in revisions table..." );
+ $res = $dbw->query( "SELECT DISTINCTROW rev_text_id FROM $tbl_rev" );
+ while( $row = $dbw->fetchObject( $res ) ) {
+ $cur[] = $row->rev_text_id;
+ }
+ echo( "done.\n" );
+
+ # Get "active" text records from the archive table
+ echo( "Searching for active text records in archive table..." );
+ $res = $dbw->query( "SELECT DISTINCTROW ar_text_id FROM $tbl_arc" );
+ while( $row = $dbw->fetchObject( $res ) ) {
+ $cur[] = $row->ar_text_id;
+ }
+ echo( "done.\n" );
+
+ # Get the IDs of all text records not in these sets
+ echo( "Searching for inactive text records..." );
+ $set = implode( ', ', $cur );
+ $res = $dbw->query( "SELECT old_id FROM $tbl_txt WHERE old_id NOT IN ( $set )" );
+ while( $row = $dbw->fetchObject( $res ) ) {
+ $old[] = $row->old_id;
+ }
+ echo( "done.\n" );
+
+ # Inform the user of what we're going to do
+ $count = count( $old );
+ echo( "$count inactive items found.\n" );
+
+ # Delete as appropriate
+ if( $delete && $count ) {
+ echo( "Deleting..." );
+ $set = implode( ', ', $old );
+ $dbw->query( "DELETE FROM $tbl_txt WHERE old_id IN ( $set )" );
+ echo( "done.\n" );
+ }
+
+ # Done
+ $dbw->commit();
+
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/purgeOldText.php b/maintenance/purgeOldText.php
new file mode 100644
index 000000000000..e8a738ad285c
--- /dev/null
+++ b/maintenance/purgeOldText.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * Purge old text records from the database
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+$options = array( 'purge', 'help' );
+require_once( 'commandLine.inc' );
+require_once( 'purgeOldText.inc' );
+
+echo( "Purge Old Text\n\n" );
+
+if( @$options['help'] ) {
+ ShowUsage();
+} else {
+ PurgeRedundantText( @$options['purge'] );
+}
+
+function ShowUsage() {
+ echo( "Prunes unused text records from the database.\n\n" );
+ echo( "Usage: php purgeOldText.php [--purge]\n\n" );
+ echo( "purge : Performs the deletion\n" );
+ echo( " help : Show this usage information\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/reassignEdits.inc.php b/maintenance/reassignEdits.inc.php
new file mode 100644
index 000000000000..6e54aea14f54
--- /dev/null
+++ b/maintenance/reassignEdits.inc.php
@@ -0,0 +1,144 @@
+<?php
+
+/**
+ * Support functions for the reassignEdits script
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ * @licence GNU General Public Licence 2.0 or later
+ */
+
+/**
+ * Reassign edits from one user to another
+ *
+ * @param $from User to take edits from
+ * @param $to User to assign edits to
+ * @param $rc Update the recent changes table
+ * @param $report Don't change things; just echo numbers
+ * @return integer Number of entries changed, or that would be changed
+ */
+function reassignEdits( &$from, &$to, $rc = false, $report = false ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->immediateBegin();
+ $fname = 'reassignEdits';
+
+ # Count things
+ out( "Checking current edits..." );
+ $res = $dbw->select( 'revision', 'COUNT(*) AS count', userConditions( $from, 'rev_user', 'rev_user_text' ), $fname );
+ $row = $dbw->fetchObject( $res );
+ $cur = $row->count;
+ out( "found {$cur}.\n" );
+
+ out( "Checking deleted edits..." );
+ $res = $dbw->select( 'archive', 'COUNT(*) AS count', userConditions( $from, 'ar_user', 'ar_user_text' ), $fname );
+ $row = $dbw->fetchObject( $res );
+ $del = $row->count;
+ out( "found {$del}.\n" );
+
+ # Don't count recent changes if we're not supposed to
+ if( $rc ) {
+ out( "Checking recent changes..." );
+ $res = $dbw->select( 'recentchanges', 'COUNT(*) AS count', userConditions( $from, 'rc_user', 'rc_user_text' ), $fname );
+ $row = $dbw->fetchObject( $res );
+ $rec = $row->count;
+ out( "found {$rec}.\n" );
+ } else {
+ $rec = 0;
+ }
+
+ $total = $cur + $del + $rec;
+ out( "\nTotal entries to change: {$total}\n" );
+
+ if( !$report ) {
+ if( $total ) {
+ # Reassign edits
+ out( "\nReassigning current edits..." );
+ $res = $dbw->update( 'revision', userSpecification( $to, 'rev_user', 'rev_user_text' ), userConditions( $from, 'rev_user', 'rev_user_text' ), $fname );
+ out( "done.\nReassigning deleted edits..." );
+ $res = $dbw->update( 'archive', userSpecification( $to, 'ar_user', 'ar_user_text' ), userConditions( $from, 'ar_user', 'ar_user_text' ), $fname );
+ out( "done.\n" );
+ # Update recent changes if required
+ if( $rc ) {
+ out( "Updating recent changes..." );
+ $res = $dbw->update( 'recentchanges', userSpecification( $to, 'rc_user', 'rc_user_text' ), userConditions( $from, 'rc_user', 'rc_user_text' ), $fname );
+ out( "done.\n" );
+ }
+ }
+ }
+
+ $dbw->immediateCommit();
+ return (int)$total;
+}
+
+/**
+ * Return the most efficient set of user conditions
+ * i.e. a user => id mapping, or a user_text => text mapping
+ *
+ * @param $user User for the condition
+ * @param $idfield Field name containing the identifier
+ * @param $utfield Field name containing the user text
+ * @return array
+ */
+function userConditions( &$user, $idfield, $utfield ) {
+ return $user->getId() ? array( $idfield => $user->getID() ) : array( $utfield => $user->getName() );
+}
+
+/**
+ * Return user specifications
+ * i.e. user => id, user_text => text
+ *
+ * @param $user User for the spec
+ * @param $idfield Field name containing the identifier
+ * @param $utfield Field name containing the user text
+ * @return array
+ */
+function userSpecification( &$user, $idfield, $utfield ) {
+ return array( $idfield => $user->getId(), $utfield => $user->getName() );
+}
+
+/**
+ * Echo output if $wgSilent is off
+ *
+ * @param $output Output to echo
+ * @return bool True if the output was echoed
+ */
+function out( $output ) {
+ global $wgSilent;
+ if( !$wgSilent ) {
+ echo( $output );
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Mutator for $wgSilent
+ *
+ * @param $silent Switch on $wgSilent
+ */
+function silent( $silent = true ) {
+ global $wgSilent;
+ $wgSilent = $silent;
+}
+
+/**
+ * Initialise the user object
+ *
+ * @param $username Username or IP address
+ * @return User
+ */
+function initialiseUser( $username ) {
+ if( User::isIP( $username ) ) {
+ $user = new User();
+ $user->setId( 0 );
+ $user->setName( $username );
+ } else {
+ $user = User::newFromName( $username );
+ }
+ $user->loadFromDatabase();
+ return $user;
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/reassignEdits.php b/maintenance/reassignEdits.php
new file mode 100644
index 000000000000..4ac566af2e58
--- /dev/null
+++ b/maintenance/reassignEdits.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * Reassign edits from a user or IP address to another user
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ * @licence GNU General Public Licence 2.0 or later
+ */
+
+$options = array( 'force', 'norc', 'quiet', 'report' );
+require_once( 'commandLine.inc' );
+require_once( 'reassignEdits.inc.php' );
+
+# Set silent mode; --report overrides --quiet
+if( !@$options['report'] && @$options['quiet'] )
+ setSilent();
+
+out( "Reassign Edits\n\n" );
+
+if( @$args[0] && @$args[1] ) {
+
+ # Set up the users involved
+ $from =& initialiseUser( $args[0] );
+ $to =& initialiseUser( $args[1] );
+
+ # If the target doesn't exist, and --force is not set, stop here
+ if( $to->getId() || @$options['force'] ) {
+ # Reassign the edits
+ $report = @$options['report'];
+ $count = reassignEdits( $from, $to, !@$options['norc'], $report );
+ # If reporting, and there were items, advise the user to run without --report
+ if( $report )
+ out( "Run the script again without --report to update.\n" );
+ } else {
+ $ton = $to->getName();
+ echo( "User '{$ton}' not found.\n" );
+ }
+
+} else {
+ ShowUsage();
+}
+
+/** Show script usage information */
+function ShowUsage() {
+ echo( "Reassign edits from one user to another.\n\n" );
+ echo( "Usage: php reassignEdits.php [--force|--quiet|--norc|--report] <from> <to>\n\n" );
+ echo( " <from> : Name of the user to assign edits from\n" );
+ echo( " <to> : Name of the user to assign edits to\n" );
+ echo( " --force : Reassign even if the target user doesn't exist\n" );
+ echo( " --quiet : Don't print status information (except for errors)\n" );
+ echo( " --norc : Don't update the recent changes table\n" );
+ echo( " --report : Print out details of what would be changed, but don't update it\n\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/rebuildImages.php b/maintenance/rebuildImages.php
new file mode 100644
index 000000000000..38b89a4805f9
--- /dev/null
+++ b/maintenance/rebuildImages.php
@@ -0,0 +1,275 @@
+<?php
+/*
+ * Script to update image metadata records
+ *
+ * Usage: php rebuildImages.php [--missing] [--dry-run]
+ * Options:
+ * --missing Crawl the uploads dir for images without records, and
+ * add them only.
+ *
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @author Brion Vibber <brion at pobox.com>
+ * @package MediaWiki
+ * @subpackage maintenance
+ */
+
+$options = array( 'missing', 'dry-run' );
+
+require_once( 'commandLine.inc' );
+require_once( 'FiveUpgrade.inc' );
+
+class ImageBuilder extends FiveUpgrade {
+ function ImageBuilder( $dryrun = false ) {
+ parent::FiveUpgrade();
+
+ $this->maxLag = 10; # if slaves are lagged more than 10 secs, wait
+ $this->dryrun = $dryrun;
+ }
+
+ function build() {
+ $this->buildImage();
+ $this->buildOldImage();
+ }
+
+ function init( $count, $table ) {
+ $this->processed = 0;
+ $this->updated = 0;
+ $this->count = $count;
+ $this->startTime = wfTime();
+ $this->table = $table;
+ }
+
+ function progress( $updated ) {
+ $this->updated += $updated;
+ $this->processed++;
+ if( $this->processed % 100 != 0 ) {
+ return;
+ }
+ $portion = $this->processed / $this->count;
+ $updateRate = $this->updated / $this->processed;
+
+ $now = wfTime();
+ $delta = $now - $this->startTime;
+ $estimatedTotalTime = $delta / $portion;
+ $eta = $this->startTime + $estimatedTotalTime;
+
+ printf( "%s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n",
+ wfTimestamp( TS_DB, intval( $now ) ),
+ $portion * 100.0,
+ $this->table,
+ wfTimestamp( TS_DB, intval( $eta ) ),
+ $completed,
+ $this->count,
+ $rate,
+ $updateRate * 100.0 );
+ flush();
+ }
+
+ function buildTable( $table, $key, $callback ) {
+ $fname = 'ImageBuilder::buildTable';
+
+ $count = $this->dbw->selectField( $table, 'count(*)', '', $fname );
+ $this->init( $count, $table );
+ $this->log( "Processing $table..." );
+
+ $tableName = $this->dbr->tableName( $table );
+ $sql = "SELECT * FROM $tableName";
+ $result = $this->dbr->query( $sql, $fname );
+
+ while( $row = $this->dbr->fetchObject( $result ) ) {
+ $update = call_user_func( $callback, $row );
+ if( is_array( $update ) ) {
+ if( !$this->dryrun ) {
+ $this->dbw->update( $table,
+ $update,
+ array( $key => $row->$key ),
+ $fname );
+ }
+ $this->progress( 1 );
+ } else {
+ $this->progress( 0 );
+ }
+ }
+ $this->log( "Finished $table... $this->updated of $this->processed rows updated" );
+ $this->dbr->freeResult( $result );
+ }
+
+ function buildImage() {
+ $callback = array( &$this, 'imageCallback' );
+ $this->buildTable( 'image', 'img_name', $callback );
+ }
+
+ function imageCallback( $row ) {
+ if( $row->img_width ) {
+ // Already processed
+ return null;
+ }
+
+ // Fill in the new image info fields
+ $info = $this->imageInfo( $row->img_name );
+
+ global $wgMemc;
+ $key = wfMemcKey( "Image", md5( $row->img_name ) );
+ $wgMemc->delete( $key );
+
+ return array(
+ 'img_width' => $info['width'],
+ 'img_height' => $info['height'],
+ 'img_bits' => $info['bits'],
+ 'img_media_type' => $info['media'],
+ 'img_major_mime' => $info['major'],
+ 'img_minor_mime' => $info['minor'] );
+ }
+
+
+ function buildOldImage() {
+ $this->buildTable( 'oldimage', 'oi_archive_name',
+ array( &$this, 'oldimageCallback' ) );
+ }
+
+ function oldimageCallback( $row ) {
+ if( $row->oi_width ) {
+ return null;
+ }
+
+ // Fill in the new image info fields
+ $info = $this->imageInfo( $row->oi_archive_name, 'wfImageArchiveDir', $row->oi_name );
+ return array(
+ 'oi_width' => $info['width' ],
+ 'oi_height' => $info['height'],
+ 'oi_bits' => $info['bits' ] );
+ }
+
+ function crawlMissing() {
+ global $wgUploadDirectory, $wgHashedUploadDirectory;
+ if( $wgHashedUploadDirectory ) {
+ for( $i = 0; $i < 16; $i++ ) {
+ for( $j = 0; $j < 16; $j++ ) {
+ $dir = sprintf( '%s%s%01x%s%02x',
+ $wgUploadDirectory,
+ DIRECTORY_SEPARATOR,
+ $i,
+ DIRECTORY_SEPARATOR,
+ $i * 16 + $j );
+ $this->crawlDirectory( $dir );
+ }
+ }
+ } else {
+ $this->crawlDirectory( $wgUploadDirectory );
+ }
+ }
+
+ function crawlDirectory( $dir ) {
+ if( !file_exists( $dir ) ) {
+ return $this->log( "no directory, skipping $dir" );
+ }
+ if( !is_dir( $dir ) ) {
+ return $this->log( "not a directory?! skipping $dir" );
+ }
+ if( !is_readable( $dir ) ) {
+ return $this->log( "dir not readable, skipping $dir" );
+ }
+ $source = opendir( $dir );
+ if( $source === false ) {
+ return $this->log( "couldn't open dir, skipping $dir" );
+ }
+
+ $this->log( "crawling $dir" );
+ while( false !== ( $filename = readdir( $source ) ) ) {
+ $fullpath = $dir . DIRECTORY_SEPARATOR . $filename;
+ if( is_dir( $fullpath ) ) {
+ continue;
+ }
+ if( is_link( $fullpath ) ) {
+ $this->log( "skipping symlink at $fullpath" );
+ continue;
+ }
+ $this->checkMissingImage( $filename, $fullpath );
+ }
+ closedir( $source );
+ }
+
+ function checkMissingImage( $filename, $fullpath ) {
+ $fname = 'ImageBuilder::checkMissingImage';
+ $row = $this->dbw->selectRow( 'image',
+ array( 'img_name' ),
+ array( 'img_name' => $filename ),
+ $fname );
+
+ if( $row ) {
+ // already known, move on
+ return;
+ } else {
+ $this->addMissingImage( $filename, $fullpath );
+ }
+ }
+
+ function addMissingImage( $filename, $fullpath ) {
+ $fname = 'ImageBuilder::addMissingImage';
+
+ $size = filesize( $fullpath );
+ $info = $this->imageInfo( $filename );
+ $timestamp = $this->dbw->timestamp( filemtime( $fullpath ) );
+
+ global $wgContLang;
+ $altname = $wgContLang->checkTitleEncoding( $filename );
+ if( $altname != $filename ) {
+ if( $this->dryrun ) {
+ $filename = $altname;
+ $this->log( "Estimating transcoding... $altname" );
+ } else {
+ $filename = $this->renameFile( $filename );
+ }
+ }
+
+ if( $filename == '' ) {
+ $this->log( "Empty filename for $fullpath" );
+ return;
+ }
+
+ $fields = array(
+ 'img_name' => $filename,
+ 'img_size' => $size,
+ 'img_width' => $info['width'],
+ 'img_height' => $info['height'],
+ 'img_metadata' => '', // filled in on-demand
+ 'img_bits' => $info['bits'],
+ 'img_media_type' => $info['media'],
+ 'img_major_mime' => $info['major'],
+ 'img_minor_mime' => $info['minor'],
+ 'img_description' => '(recovered file, missing upload log entry)',
+ 'img_user' => 0,
+ 'img_user_text' => 'Conversion script',
+ 'img_timestamp' => $timestamp );
+ if( !$this->dryrun ) {
+ $this->dbw->insert( 'image', $fields, $fname );
+ }
+ $this->log( $fullpath );
+ }
+}
+
+$builder = new ImageBuilder( isset( $options['dry-run'] ) );
+if( isset( $options['missing'] ) ) {
+ $builder->crawlMissing();
+} else {
+ $builder->build();
+}
+
+?>
diff --git a/maintenance/rebuildInterwiki.inc b/maintenance/rebuildInterwiki.inc
new file mode 100644
index 000000000000..d719fd401002
--- /dev/null
+++ b/maintenance/rebuildInterwiki.inc
@@ -0,0 +1,260 @@
+<?php
+/**
+ * Rebuild interwiki table using the file on meta and the language list
+ * Wikimedia specific!
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+class Site {
+ var $suffix, $lateral, $url;
+
+ function Site( $s, $l, $u ) {
+ $this->suffix = $s;
+ $this->lateral = $l;
+ $this->url = $u;
+ }
+
+ function getURL( $lang ) {
+ $xlang = str_replace( '_', '-', $lang );
+ return "http://$xlang.{$this->url}/wiki/\$1";
+ }
+}
+
+function getRebuildInterwikiSQL() {
+ global $langlist, $languageAliases, $prefixRewrites;
+
+ # Multi-language sites
+ # db suffix => db suffix, iw prefix, hostname
+ $sites = array(
+ 'wiki' => new Site( 'wiki', 'w', 'wikipedia.org' ),
+ 'wiktionary' => new Site( 'wiktionary', 'wikt', 'wiktionary.org' ),
+ 'wikiquote' => new Site( 'wikiquote', 'q', 'wikiquote.org' ),
+ 'wikibooks' => new Site( 'wikibooks', 'b', 'wikibooks.org' ),
+ 'wikinews' => new Site( 'wikinews', 'n', 'wikinews.org' ),
+ 'wikisource' => new Site( 'wikisource', 's', 'wikisource.org' ),
+ 'wikimedia' => new Site( 'wikimedia', 'chapter', 'wikimedia.org' ),
+ );
+
+ # List of language prefixes likely to be found in multi-language sites
+ $langlist = array_map( "trim", file( "/home/wikipedia/common/langlist" ) );
+
+ # List of all database names
+ $dblist = array_map( "trim", file( "/home/wikipedia/common/all.dblist" ) );
+
+ # Special-case hostnames
+ $specials = array(
+ 'sourceswiki' => 'sources.wikipedia.org',
+ 'quotewiki' => 'wikiquote.org',
+ 'textbookwiki' => 'wikibooks.org',
+ 'sep11wiki' => 'sep11.wikipedia.org',
+ 'metawiki' => 'meta.wikimedia.org',
+ 'commonswiki' => 'commons.wikimedia.org',
+ );
+
+ # Extra interwiki links that can't be in the intermap for some reason
+ $extraLinks = array(
+ array( 'm', 'http://meta.wikimedia.org/wiki/$1', 1 ),
+ array( 'meta', 'http://meta.wikimedia.org/wiki/$1', 1 ),
+ array( 'sep11', 'http://sep11.wikipedia.org/wiki/$1', 1 ),
+ );
+
+ # Language aliases, usually configured as redirects to the real wiki in apache
+ # Interlanguage links are made directly to the real wiki
+ # Something horrible happens if you forget to list an alias here, I can't
+ # remember what
+ $languageAliases = array(
+ 'zh-cn' => 'zh',
+ 'zh-tw' => 'zh',
+ 'dk' => 'da',
+ 'nb' => 'no',
+ );
+
+ # Special case prefix rewrites, for the benefit of Swedish which uses s:t
+ # as an abbreviation for saint
+ $prefixRewrites = array(
+ 'svwiki' => array( 's' => 'src' ),
+ );
+
+ # Construct a list of reserved prefixes
+ $reserved = array();
+ foreach ( $langlist as $lang ) {
+ $reserved[$lang] = 1;
+ }
+ foreach ( $languageAliases as $alias => $lang ) {
+ $reserved[$alias] = 1;
+ }
+ foreach( $sites as $site ) {
+ $reserved[$site->lateral] = 1;
+ }
+
+ # Extract the intermap from meta
+ $intermap = wfGetHTTP( 'http://meta.wikimedia.org/w/index.php?title=Interwiki_map&action=raw', 30 );
+ $lines = array_map( 'trim', explode( "\n", trim( $intermap ) ) );
+
+ if ( !$lines || count( $lines ) < 2 ) {
+ wfDie( "m:Interwiki_map not found" );
+ }
+
+ $iwArray = array();
+
+ foreach ( $lines as $line ) {
+ if ( preg_match( '/^\|\s*(.*?)\s*\|\|\s*(https?:\/\/.*?)\s*$/', $line, $matches ) ) {
+ $prefix = strtolower( $matches[1] );
+ $url = $matches[2];
+ if ( preg_match( '/(wikipedia|wiktionary|wikisource|wikiquote|wikibooks|wikimedia)\.org/', $url ) ) {
+ $local = 1;
+ } else {
+ $local = 0;
+ }
+
+ if ( empty( $reserved[$prefix] ) ) {
+ $iwArray[$prefix] = array( "iw_prefix" => $prefix, "iw_url" => $url, "iw_local" => $local );
+ }
+ }
+ }
+
+ $sql = "-- Generated by rebuildInterwiki.php";
+
+
+ foreach ( $dblist as $db ) {
+ if ( isset( $specials[$db] ) ) {
+ # Special wiki
+ # Has interwiki links and interlanguage links to wikipedia
+
+ $host = $specials[$db];
+ $sql .= "\n--$host\n\n";
+ $sql .= "USE $db;\n" .
+ "TRUNCATE TABLE interwiki;\n" .
+ "INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES \n";
+ $first = true;
+
+ # Intermap links
+ foreach ( $iwArray as $iwEntry ) {
+ $sql .= makeLink( $iwEntry, $first, $db );
+ }
+
+ # Links to multilanguage sites
+ foreach ( $sites as $targetSite ) {
+ $sql .= makeLink( array( $targetSite->lateral, $targetSite->getURL( 'en' ), 1 ), $first, $db );
+ }
+
+ # Interlanguage links to wikipedia
+ $sql .= makeLanguageLinks( $sites['wiki'], $first, $db );
+
+ # Extra links
+ foreach ( $extraLinks as $link ) {
+ $sql .= makeLink( $link, $first, $db );
+ }
+
+ $sql .= ";\n";
+ } else {
+ # Find out which site this DB belongs to
+ $site = false;
+ foreach( $sites as $candidateSite ) {
+ $suffix = $candidateSite->suffix;
+ if ( preg_match( "/(.*)$suffix$/", $db, $matches ) ) {
+ $site = $candidateSite;
+ break;
+ }
+ }
+ if ( !$site ) {
+ print "Invalid database $db\n";
+ continue;
+ }
+ $lang = $matches[1];
+ $host = "$lang." . $site->url;
+ $sql .= "\n--$host\n\n";
+
+ $sql .= "USE $db;\n" .
+ "TRUNCATE TABLE interwiki;\n" .
+ "INSERT INTO interwiki (iw_prefix,iw_url,iw_local) VALUES\n";
+ $first = true;
+
+ # Intermap links
+ foreach ( $iwArray as $iwEntry ) {
+ # Suppress links with the same name as the site
+ if ( ( $suffix == 'wiki' && $iwEntry['iw_prefix'] != 'wikipedia' ) ||
+ ( $suffix != 'wiki' && $suffix != $iwEntry['iw_prefix'] ) )
+ {
+ $sql .= makeLink( $iwEntry, $first, $db );
+ }
+ }
+
+ # Lateral links
+ foreach ( $sites as $targetSite ) {
+ # Suppress link to self
+ if ( $targetSite->suffix != $site->suffix ) {
+ $sql .= makeLink( array( $targetSite->lateral, $targetSite->getURL( $lang ), 1 ), $first, $db );
+ }
+ }
+
+ # Interlanguage links
+ $sql .= makeLanguageLinks( $site, $first, $db );
+
+ # w link within wikipedias
+ # Other sites already have it as a lateral link
+ if ( $site->suffix == "wiki" ) {
+ $sql .= makeLink( array("w", "http://en.wikipedia.org/wiki/$1", 1), $first, $db );
+ }
+
+ # Extra links
+ foreach ( $extraLinks as $link ){
+ $sql .= makeLink( $link, $first, $db );
+ }
+ $sql .= ";\n\n";
+ }
+ }
+ return $sql;
+}
+
+# ------------------------------------------------------------------------------------------
+
+# Returns part of an INSERT statement, corresponding to all interlanguage links to a particular site
+function makeLanguageLinks( &$site, &$first, $source ) {
+ global $langlist, $languageAliases;
+
+ $sql = "";
+
+ # Actual languages with their own databases
+ foreach ( $langlist as $targetLang ) {
+ $sql .= makeLink( array( $targetLang, $site->getURL( $targetLang ), 1 ), $first, $source );
+ }
+
+ # Language aliases
+ foreach ( $languageAliases as $alias => $lang ) {
+ $sql .= makeLink( array( $alias, $site->getURL( $lang ), 1 ), $first, $source );
+ }
+ return $sql;
+}
+
+# Make SQL for a single link from an array
+function makeLink( $entry, &$first, $source ) {
+ global $prefixRewrites;
+
+ if ( isset( $prefixRewrites[$source] ) && isset( $prefixRewrites[$source][$entry[0]] ) ) {
+ $entry[0] = $prefixRewrites[$source][$entry[0]];
+ }
+
+ $sql = "";
+ # Add comma
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",\n";
+ }
+ $dbr =& wfGetDB( DB_SLAVE );
+ $sql .= "(" . $dbr->makeList( $entry ) . ")";
+ return $sql;
+}
+
+?>
diff --git a/maintenance/rebuildInterwiki.php b/maintenance/rebuildInterwiki.php
new file mode 100644
index 000000000000..19e081adbcfa
--- /dev/null
+++ b/maintenance/rebuildInterwiki.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Rebuild interwiki table using the file on meta and the language list
+ * Wikimedia specific!
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+$oldCwd = getcwd();
+
+$optionsWithArgs = array( "o" );
+include_once( "commandLine.inc" );
+include_once( "rebuildInterwiki.inc" );
+chdir( $oldCwd );
+
+$sql = getRebuildInterwikiSQL();
+
+# Output
+if ( isset( $options['o'] ) ) {
+ # To file specified with -o
+ $file = fopen( $options['o'], "w" );
+ fwrite( $file, $sql );
+ fclose( $file );
+} else {
+ # To stdout
+ print $sql;
+}
+
+?>
diff --git a/maintenance/rebuildall.php b/maintenance/rebuildall.php
new file mode 100644
index 000000000000..7c44e300285f
--- /dev/null
+++ b/maintenance/rebuildall.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Rebuild link tracking tables from scratch. This takes several
+ * hours, depending on the database size and server configuration.
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( "commandLine.inc" );
+
+#require_once( "rebuildlinks.inc" );
+require_once( "refreshLinks.inc" );
+require_once( "rebuildtextindex.inc" );
+require_once( "rebuildrecentchanges.inc" );
+
+$database = Database::newFromParams( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname );
+
+print "** Rebuilding fulltext search index (if you abort this will break searching; run this script again to fix):\n";
+dropTextIndex( $database );
+rebuildTextIndex( $database );
+createTextIndex( $database );
+
+print "\n\n** Rebuilding recentchanges table:\n";
+rebuildRecentChangesTablePass1();
+rebuildRecentChangesTablePass2();
+
+# Doesn't work anymore
+# rebuildLinkTables();
+
+# Use the slow incomplete one instead. It's designed to work in the background
+print "\n\n** Rebuilding links tables -- this can take a long time. It should be safe to abort via ctrl+C if you get bored.\n";
+refreshLinks( 1 );
+
+print "Done.\n";
+exit();
+
+?>
diff --git a/maintenance/rebuildrecentchanges.inc b/maintenance/rebuildrecentchanges.inc
new file mode 100644
index 000000000000..e077da52214e
--- /dev/null
+++ b/maintenance/rebuildrecentchanges.inc
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Rebuild recent changes table.
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+function rebuildRecentChangesTablePass1()
+{
+ $fname = 'rebuildRecentChangesTablePass1';
+ $dbw =& wfGetDB( DB_MASTER );
+ extract( $dbw->tableNames( 'recentchanges', 'cur', 'old' ) );
+
+ $dbw->delete( 'recentchanges', '*' );
+
+ print( "Loading from page and revision tables...\n" );
+
+ global $wgRCMaxAge;
+ $cutoff = time() - $wgRCMaxAge;
+ $dbw->insertSelect( 'recentchanges', array( 'page', 'revision' ),
+ array(
+ 'rc_timestamp' => 'rev_timestamp',
+ 'rc_cur_time' => 'rev_timestamp',
+ 'rc_user' => 'rev_user',
+ 'rc_user_text' => 'rev_user_text',
+ 'rc_namespace' => 'page_namespace',
+ 'rc_title' => 'page_title',
+ 'rc_comment' => 'rev_comment',
+ 'rc_minor' => 'rev_minor_edit',
+ 'rc_bot' => 0,
+ 'rc_new' => 'page_is_new',
+ 'rc_cur_id' => 'page_id',
+ 'rc_this_oldid' => 'rev_id',
+ 'rc_last_oldid' => 0, // is this ok?
+ 'rc_type' => $dbw->conditional( 'page_is_new != 0', RC_NEW, RC_EDIT ),
+ ), array(
+ 'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $cutoff ) ),
+ 'rev_page=page_id'
+ ), $fname,
+ array(), // INSERT options
+ array( 'ORDER BY' => 'rev_timestamp', 'LIMIT' => 5000 ) // SELECT options
+ );
+}
+
+function rebuildRecentChangesTablePass2()
+{
+ $dbw =& wfGetDB( DB_MASTER );
+ extract( $dbw->tableNames( 'recentchanges', 'revision' ) );
+
+ $ns = $id = $count = 0;
+ $title = $ct = "";
+
+ print( "Updating links...\n" );
+
+ # Fill in the rc_last_oldid field, which points to the previous edit
+ #
+ $sql = "SELECT rc_cur_id,rc_this_oldid,rc_timestamp FROM $recentchanges " .
+ "ORDER BY rc_cur_id,rc_timestamp";
+ $res = $dbw->query( $sql, DB_MASTER );
+
+ $lastCurId = 0;
+ $lastOldId = 0;
+ while ( $obj = $dbw->fetchObject( $res ) ) {
+ $new = 0;
+ if( $obj->rc_cur_id != $lastCurId ) {
+ # Switch! Look up the previous last edit, if any
+ $lastCurId = intval( $obj->rc_cur_id );
+ $emit = $obj->rc_timestamp;
+ $sql2 = "SELECT rev_id FROM $revision " .
+ "WHERE rev_page={$lastCurId} ".
+ "AND rev_timestamp<'{$emit}' ORDER BY rev_timestamp DESC LIMIT 1";
+ $res2 = $dbw->query( $sql2 );
+ if( $row = $dbw->fetchObject( $res2 ) ) {
+ $lastOldId = intval( $row->rev_id );
+ } else {
+ # No previous edit
+ $lastOldId = 0;
+ $new = 1;
+ }
+ $dbw->freeResult( $res2 );
+ }
+ if( $lastCurId == 0 ) {
+ print "Uhhh, something wrong? No curid\n";
+ } else {
+ $sql3 = "UPDATE $recentchanges SET rc_last_oldid=$lastOldId,rc_new=$new,rc_type=$new " .
+ "WHERE rc_cur_id={$lastCurId} AND rc_this_oldid={$obj->rc_this_oldid}";
+ $dbw->query( $sql3 );
+ $lastOldId = intval( $obj->rc_this_oldid );
+ }
+ }
+ $dbw->freeResult( $res );
+}
+
+?>
diff --git a/maintenance/rebuildrecentchanges.php b/maintenance/rebuildrecentchanges.php
new file mode 100644
index 000000000000..77816cf8b2c4
--- /dev/null
+++ b/maintenance/rebuildrecentchanges.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Rebuild link tracking tables from scratch. This takes several
+ * hours, depending on the database size and server configuration.
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( "commandLine.inc" );
+require_once( "rebuildrecentchanges.inc" );
+$wgTitle = Title::newFromText( "Rebuild recent changes script" );
+
+$wgDBuser = $wgDBadminuser;
+$wgDBpassword = $wgDBadminpassword;
+
+rebuildRecentChangesTablePass1();
+rebuildRecentChangesTablePass2();
+
+print "Done.\n";
+exit();
+
+?>
diff --git a/maintenance/rebuildtextindex.inc b/maintenance/rebuildtextindex.inc
new file mode 100644
index 000000000000..5035b5641fd6
--- /dev/null
+++ b/maintenance/rebuildtextindex.inc
@@ -0,0 +1,68 @@
+<?php
+require_once 'counter.php';
+/**
+ * Rebuild the fulltext search indexes. This may take a while
+ * depending on the database size and server configuration.
+ *
+ * Rebuilding is faster if you drop the index and recreate it,
+ * but that will prevent searches from working while it runs.
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+define( "RTI_CHUNK_SIZE", 500 );
+
+function dropTextIndex( &$database )
+{
+ $searchindex = $database->tableName( 'searchindex' );
+ if ( $database->indexExists( "searchindex", "si_title" ) ) {
+ echo "Dropping index...\n";
+ $sql = "ALTER TABLE $searchindex DROP INDEX si_title, DROP INDEX si_text";
+ $database->query($sql, "dropTextIndex" );
+ }
+}
+
+function createTextIndex( &$database )
+{
+ $searchindex = $database->tableName( 'searchindex' );
+ echo "\nRebuild the index...\n";
+ $sql = "ALTER TABLE $searchindex ADD FULLTEXT si_title (si_title), " .
+ "ADD FULLTEXT si_text (si_text)";
+ $database->query($sql, "createTextIndex" );
+}
+
+function rebuildTextIndex( &$database )
+{
+ extract( $database->tableNames( 'page', 'revision', 'text', 'searchindex' ) );
+
+ $sql = "SELECT MAX(page_id) AS count FROM $page";
+ $res = $database->query($sql, "rebuildTextIndex" );
+ $s = $database->fetchObject($res);
+ $count = $s->count;
+ echo "Rebuilding index fields for {$count} pages...\n";
+ $n = 0;
+
+ while ( $n < $count ) {
+ print_c( $n - 1, $n);
+ $end = $n + RTI_CHUNK_SIZE - 1;
+ $sql = "SELECT page_id, page_namespace, page_title, old_flags, old_text
+ FROM $page, $revision, $text
+ WHERE page_id BETWEEN $n AND $end
+ AND page_latest=rev_id
+ AND rev_text_id=old_id";
+ $res = $database->query($sql, "rebuildTextIndex" );
+
+ while( $s = $database->fetchObject($res) ) {
+ $revtext = Revision::getRevisionText( $s );
+ $u = new SearchUpdate( $s->page_id, $s->page_title, $revtext );
+ $u->doUpdate();
+ }
+ $database->freeResult( $res );
+ $n += RTI_CHUNK_SIZE;
+ }
+}
+
+?>
diff --git a/maintenance/rebuildtextindex.php b/maintenance/rebuildtextindex.php
new file mode 100644
index 000000000000..54672d21d57a
--- /dev/null
+++ b/maintenance/rebuildtextindex.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Rebuild search index table from scratch. This takes several
+ * hours, depending on the database size and server configuration.
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( "commandLine.inc" );
+require_once( "rebuildtextindex.inc" );
+$wgTitle = Title::newFromText( "Rebuild text index script" );
+
+$database = Database::newFromParams( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname );
+
+dropTextIndex( $database );
+rebuildTextIndex( $database );
+createTextIndex( $database );
+
+print "Done.\n";
+exit();
+
+?>
diff --git a/maintenance/refreshImageCount.php b/maintenance/refreshImageCount.php
new file mode 100644
index 000000000000..88ac3c52c31d
--- /dev/null
+++ b/maintenance/refreshImageCount.php
@@ -0,0 +1,25 @@
+<?php
+
+// Quickie hack; patch-ss_images.sql uses variables which don't
+// replicate properly.
+
+require_once( "commandLine.inc" );
+
+$dbw =& wfGetDB( DB_MASTER );
+
+// Load the current value from the master
+$count = $dbw->selectField( 'site_stats', 'ss_images' );
+
+echo wfWikiID().": forcing ss_images to $count\n";
+
+// First set to NULL so that it changes on the master
+$dbw->update( 'site_stats',
+ array( 'ss_images' => null ),
+ array( 'ss_row_id' => 1 ) );
+
+// Now this update will be forced to go out
+$dbw->update( 'site_stats',
+ array( 'ss_images' => $count ),
+ array( 'ss_row_id' => 1 ) );
+
+?>
diff --git a/maintenance/refreshLinks.inc b/maintenance/refreshLinks.inc
new file mode 100644
index 000000000000..34ea6294d09b
--- /dev/null
+++ b/maintenance/refreshLinks.inc
@@ -0,0 +1,131 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+define( "REPORTING_INTERVAL", 100 );
+#define( "REPORTING_INTERVAL", 1 );
+
+function refreshLinks( $start, $newOnly = false, $maxLag = false, $end = 0 ) {
+ global $wgUser, $wgParser, $wgUseImageResize, $wgUseTidy;
+
+ $fname = 'refreshLinks';
+ $dbr =& wfGetDB( DB_SLAVE );
+ $start = intval( $start );
+
+ # Don't generate TeX PNGs (lack of a sensible current directory causes errors anyway)
+ $wgUser->setOption('math', MW_MATH_SOURCE);
+
+ # Don't generate extension images (e.g. Timeline)
+ $wgParser->mTagHooks = array();
+
+ # Don't generate thumbnail images
+ $wgUseImageResize = false;
+ $wgUseTidy = false;
+
+ if ( $newOnly ) {
+ print "Refreshing links from ";
+ $res = $dbr->select( 'page',
+ array( 'page_id' ),
+ array(
+ 'page_is_new' => 1,
+ "page_id > $start" ),
+ $fname
+ );
+ $num = $dbr->numRows( $res );
+ print "$num new articles...\n";
+
+ $i = 0;
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ( !( ++$i % REPORTING_INTERVAL ) ) {
+ print "$i\n";
+ wfWaitForSlaves( $maxLag );
+ }
+
+ fixLinksFromArticle( $row->page_id );
+ }
+ } else {
+ print "Refreshing link table.\n";
+ if ( !$end ) {
+ $end = $dbr->selectField( 'page', 'max(page_id)', false );
+ }
+ print("Starting from page_id $start of $end.\n");
+
+ for ($id = $start; $id <= $end; $id++) {
+
+ if ( !($id % REPORTING_INTERVAL) ) {
+ print "$id\n";
+ wfWaitForSlaves( $maxLag );
+ }
+ fixLinksFromArticle( $id );
+ }
+ }
+}
+
+function fixLinksFromArticle( $id ) {
+ global $wgTitle, $wgParser;
+
+ $wgTitle = Title::newFromID( $id );
+ $dbw =& wfGetDB( DB_MASTER );
+
+ $linkCache =& LinkCache::singleton();
+ $linkCache->clear();
+
+ if ( is_null( $wgTitle ) ) {
+ return;
+ }
+ $dbw->begin();
+
+ $revision = Revision::newFromTitle( $wgTitle );
+ if ( !$revision ) {
+ return;
+ }
+
+ $options = new ParserOptions;
+ $parserOutput = $wgParser->parse( $revision->getText(), $wgTitle, $options, true, true, $revision->getId() );
+ $update = new LinksUpdate( $wgTitle, $parserOutput, false );
+ $update->doUpdate();
+ $dbw->immediateCommit();
+}
+
+function deleteLinksFromNonexistent( $maxLag = 0 ) {
+ $fname = 'deleteLinksFromNonexistent';
+
+ wfWaitForSlaves( $maxLag );
+
+ $dbw =& wfGetDB( DB_WRITE );
+
+ $linksTables = array(
+ 'pagelinks' => 'pl_from',
+ 'imagelinks' => 'il_from',
+ 'categorylinks' => 'cl_from',
+ 'templatelinks' => 'tl_from',
+ 'externallinks' => 'el_from',
+ );
+
+ $page = $dbw->tableName( 'page' );
+
+
+ foreach ( $linksTables as $table => $field ) {
+ if ( !$dbw->ping() ) {
+ print "DB disconnected, reconnecting...";
+ while ( !$dbw->ping() ) {
+ print ".";
+ sleep(10);
+ }
+ print "\n";
+ }
+
+ $pTable = $dbw->tableName( $table );
+ $sql = "DELETE $pTable FROM $pTable LEFT JOIN $page ON page_id=$field WHERE page_id IS NULL";
+
+ print "Deleting $table from non-existent articles...";
+ $dbw->query( $sql, $fname );
+ print " fixed " .$dbw->affectedRows() . " row(s)\n";
+ }
+}
+
+?>
diff --git a/maintenance/refreshLinks.php b/maintenance/refreshLinks.php
new file mode 100644
index 000000000000..e59124aaf57d
--- /dev/null
+++ b/maintenance/refreshLinks.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+$optionsWithArgs = array( 'm', 'e' );
+require_once( "commandLine.inc" );
+require_once( "refreshLinks.inc" );
+
+error_reporting( E_ALL & (~E_NOTICE) );
+
+if ( !$options['dfn-only'] ) {
+ if ($args[0]) {
+ $start = (int)$args[0];
+ } else {
+ $start = 1;
+ }
+
+ refreshLinks( $start, $options['new-only'], $options['m'], $options['e'] );
+}
+// this bit's bad for replication: disabling temporarily
+// --brion 2005-07-16
+//deleteLinksFromNonexistent();
+
+if ( $options['globals'] ) {
+ print_r( $GLOBALS );
+}
+
+?>
diff --git a/maintenance/removeUnusedAccounts.inc b/maintenance/removeUnusedAccounts.inc
new file mode 100644
index 000000000000..ac15ebef820a
--- /dev/null
+++ b/maintenance/removeUnusedAccounts.inc
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * Support functions for the removeUnusedAccounts maintenance script
+ *
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+/**
+ * Could the specified user account be deemed inactive?
+ * (No edits, no deleted edits, no log entries, no current/old uploads)
+ *
+ * @param $id User's ID
+ * @param $master Perform checking on the master
+ * @return bool
+ */
+function isInactiveAccount( $id, $master = false ) {
+ $dbo =& wfGetDB( $master ? DB_MASTER : DB_SLAVE );
+ $fname = 'isInactiveAccount';
+ $checks = array( 'revision' => 'rev', 'archive' => 'ar', 'logging' => 'log',
+ 'image' => 'img', 'oldimage' => 'oi' );
+ $count = 0;
+
+ $dbo->immediateBegin();
+ foreach( $checks as $table => $fprefix ) {
+ $conds = array( $fprefix . '_user' => $id );
+ $count += (int)$dbo->selectField( $table, 'COUNT(*)', $conds, $fname );
+ }
+ $dbo->immediateCommit();
+
+ return $count == 0;
+}
+
+/**
+ * Show help for the maintenance script
+ */
+function showHelp() {
+ echo( "Delete unused user accounts from the database.\n\n" );
+ echo( "USAGE: php removeUnusedAccounts.php [--delete]\n\n" );
+ echo( " --delete : Delete accounts which are discovered to be inactive\n" );
+ echo( "\n" );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/removeUnusedAccounts.php b/maintenance/removeUnusedAccounts.php
new file mode 100644
index 000000000000..33b9a0c1baff
--- /dev/null
+++ b/maintenance/removeUnusedAccounts.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * Remove unused user accounts from the database
+ * An unused account is one which has made no edits
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+/**
+ * @todo Don't delete sysops or bureaucrats
+ */
+
+$options = array( 'help', 'delete' );
+require_once( 'commandLine.inc' );
+require_once( 'removeUnusedAccounts.inc' );
+echo( "Remove Unused Accounts\n\n" );
+$fname = 'removeUnusedAccounts';
+
+if( isset( $options['help'] ) ) {
+ showHelp();
+ exit();
+}
+
+# Do an initial scan for inactive accounts and report the result
+echo( "Checking for unused user accounts...\n" );
+$del = array();
+$dbr =& wfGetDB( DB_SLAVE );
+$res = $dbr->select( 'user', array( 'user_id', 'user_name' ), '', $fname );
+while( $row = $dbr->fetchObject( $res ) ) {
+ # Check the account, but ignore it if it's the primary administrator
+ if( $row->user_id > 1 && isInactiveAccount( $row->user_id, true ) ) {
+ # Inactive; print out the name and flag it
+ $del[] = $row->user_id;
+ echo( $row->user_name . "\n" );
+ }
+}
+$count = count( $del );
+echo( "...found {$count}.\n" );
+
+# If required, go back and delete each marked account
+if( $count > 0 && isset( $options['delete'] ) ) {
+ echo( "\nDeleting inactive accounts..." );
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'user', array( 'user_id' => $del ), $fname );
+ echo( "done.\n" );
+ # Update the site_stats.ss_users field
+ $users = $dbw->selectField( 'user', 'COUNT(*)', array(), $fname );
+ $dbw->update( 'site_stats', array( 'ss_users' => $users ), array( 'ss_row_id' => 1 ), $fname );
+} else {
+ if( $count > 0 )
+ echo( "\nRun the script again with --delete to remove them from the database.\n" );
+}
+echo( "\n" );
+
+?>
diff --git a/maintenance/renderDump.php b/maintenance/renderDump.php
new file mode 100644
index 000000000000..10986f2c787f
--- /dev/null
+++ b/maintenance/renderDump.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Take page text out of an XML dump file and render basic HTML out to files.
+ * This is *NOT* suitable for publishing or offline use; it's intended for
+ * running comparitive tests of parsing behavior using real-world data.
+ *
+ * Templates etc are pulled from the local wiki database, not from the dump.
+ *
+ * Copyright (C) 2006 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.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
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+$optionsWithArgs = array( 'report' );
+
+require_once( 'commandLine.inc' );
+require_once( 'SpecialImport.php' );
+
+class DumpRenderer {
+ function __construct( $dir ) {
+ $this->stderr = fopen( "php://stderr", "wt" );
+ $this->outputDirectory = $dir;
+ $this->count = 0;
+ }
+
+ function handleRevision( $rev ) {
+ $title = $rev->getTitle();
+ if (!$title) {
+ fprintf( $this->stderr, "Got bogus revision with null title!" );
+ return;
+ }
+ $display = $title->getPrefixedText();
+
+ $this->count++;
+
+ $sanitized = rawurlencode( $display );
+ $filename = sprintf( "%s/wiki-%07d-%s.html",
+ $this->outputDirectory,
+ $this->count,
+ $sanitized );
+ fprintf( $this->stderr, "%s\n", $filename, $display );
+
+ // fixme
+ $user = new User();
+ $parser = new Parser();
+ $options = ParserOptions::newFromUser( $user );
+
+ $output = $parser->parse( $rev->getText(), $title, $options );
+
+ file_put_contents( $filename,
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " .
+ "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" .
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" .
+ "<head>\n" .
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n" .
+ "<title>" . htmlspecialchars( $display ) . "</title>\n" .
+ "</head>\n" .
+ "<body>\n" .
+ $output->getText() .
+ "</body>\n" .
+ "</html>" );
+ }
+
+ function run() {
+ $this->startTime = wfTime();
+
+ $file = fopen( 'php://stdin', 'rt' );
+ $source = new ImportStreamSource( $file );
+ $importer = new WikiImporter( $source );
+
+ $importer->setRevisionCallback(
+ array( &$this, 'handleRevision' ) );
+
+ return $importer->doImport();
+ }
+}
+
+if( isset( $options['output-dir'] ) ) {
+ $dir = $options['output-dir'];
+} else {
+ wfDie( "Must use --output-dir=/some/dir\n" );
+}
+$render = new DumpRenderer( $dir );
+$render->run();
+
+?>
diff --git a/maintenance/runJobs.php b/maintenance/runJobs.php
new file mode 100644
index 000000000000..343cda8a3a0c
--- /dev/null
+++ b/maintenance/runJobs.php
@@ -0,0 +1,32 @@
+<?php
+
+$optionsWithArgs = array( 'maxjobs' );
+$wgUseNormalUser = true;
+require_once( 'commandLine.inc' );
+require_once( "$IP/includes/JobQueue.php" );
+require_once( "$IP/includes/FakeTitle.php" );
+
+if ( isset( $options['maxjobs'] ) ) {
+ $maxJobs = $options['maxjobs'];
+} else {
+ $maxJobs = 10000;
+}
+
+// Trigger errors on inappropriate use of $wgTitle
+$wgTitle = new FakeTitle;
+
+$dbw =& wfGetDB( DB_MASTER );
+$n = 0;
+while ( $dbw->selectField( 'job', 'count(*)', '', 'runJobs.php' ) ) {
+ while ( false != ($job = Job::pop()) ) {
+ wfWaitForSlaves( 5 );
+ print $job->id . " " . $job->toString() . "\n";
+ if ( !$job->run() ) {
+ print "Error: {$job->error}\n";
+ }
+ if ( $maxJobs && ++$n > $maxJobs ) {
+ break 2;
+ }
+ }
+}
+?>
diff --git a/maintenance/showJobs.php b/maintenance/showJobs.php
new file mode 100644
index 000000000000..98e47de2fef6
--- /dev/null
+++ b/maintenance/showJobs.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Based on runJobs.php
+ *
+ * @author Tim Starling
+ * @author Ashar Voultoiz
+ */
+require_once( 'commandLine.inc' );
+require_once( "$IP/includes/JobQueue.php" );
+require_once( "$IP/includes/FakeTitle.php" );
+
+// Trigger errors on inappropriate use of $wgTitle
+$wgTitle = new FakeTitle;
+
+$dbw =& wfGetDB( DB_MASTER );
+$count = $dbw->selectField( 'job', 'count(*)', '', 'runJobs.php' );
+print $count."\n";
+
+?>
diff --git a/maintenance/showStats.php b/maintenance/showStats.php
new file mode 100644
index 000000000000..27f9be6b01a1
--- /dev/null
+++ b/maintenance/showStats.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * Maintenance script to show the cached statistics.
+ * Give out the same output as [[Special:Statistics]]
+ *
+ * @author Ashar Voultoiz <hashar@altern.org>
+ * Based on initStats.php by:
+ * @author Brion Vibber
+ * @author Rob Church <robchur@gmail.com>
+ *
+ * @licence GNU General Public License 2.0 or later
+ */
+
+require_once( 'commandLine.inc' );
+
+#
+# Configuration
+#
+$fields = array(
+ 'ss_total_views' => 'Total views',
+ 'ss_total_edits' => 'Total edits',
+ 'ss_good_articles' => 'Number of articles',
+ 'ss_total_pages' => 'Total pages',
+ 'ss_users' => 'Number of users',
+ 'ss_admins' => 'Number of admins',
+ 'ss_images' => 'Number of images',
+);
+
+// Get cached stats from slave database
+$dbr =& wfGetDB( DB_SLAVE );
+$fname = 'showStats';
+$stats = $dbr->selectRow( 'site_stats', '*', '' );
+
+// Get maximum size for each column
+$max_length_value = $max_length_desc = 0;
+foreach( $fields as $field => $desc ) {
+ $max_length_value = max( $max_length_value, strlen( $stats->$field ) );
+ $max_length_desc = max( $max_length_desc , strlen( $desc )) ;
+}
+
+// Show them
+foreach( $fields as $field => $desc ) {
+ printf( "%-{$max_length_desc}s: %{$max_length_value}d\n", $desc, $stats->$field );
+}
+?>
diff --git a/maintenance/stats.php b/maintenance/stats.php
new file mode 100644
index 000000000000..25bb9cc79d1b
--- /dev/null
+++ b/maintenance/stats.php
@@ -0,0 +1,49 @@
+<?php
+require_once('commandLine.inc');
+
+if( get_class( $wgMemc ) == 'FakeMemCachedClient' ) {
+ die("You are running FakeMemCachedClient, I can not provide any statistics.\n");
+}
+
+print "Requests\n";
+$session = intval($wgMemc->get(wfMemcKey('stats','request_with_session')));
+$noSession = intval($wgMemc->get(wfMemcKey('stats','request_without_session')));
+$total = $session + $noSession;
+printf( "with session: %-10d %6.2f%%\n", $session, $session/$total*100 );
+printf( "without session: %-10d %6.2f%%\n", $noSession, $noSession/$total*100 );
+printf( "total: %-10d %6.2f%%\n", $total, 100 );
+
+
+print "\nParser cache\n";
+$hits = intval($wgMemc->get(wfMemcKey('stats','pcache_hit')));
+$invalid = intval($wgMemc->get(wfMemcKey('stats','pcache_miss_invalid')));
+$expired = intval($wgMemc->get(wfMemcKey('stats','pcache_miss_expired')));
+$absent = intval($wgMemc->get(wfMemcKey('stats','pcache_miss_absent')));
+$stub = intval($wgMemc->get(wfMemcKey('stats','pcache_miss_stub')));
+$total = $hits + $invalid + $expired + $absent + $stub;
+printf( "hits: %-10d %6.2f%%\n", $hits, $hits/$total*100 );
+printf( "invalid: %-10d %6.2f%%\n", $invalid, $invalid/$total*100 );
+printf( "expired: %-10d %6.2f%%\n", $expired, $expired/$total*100 );
+printf( "absent: %-10d %6.2f%%\n", $absent, $absent/$total*100 );
+printf( "stub threshold: %-10d %6.2f%%\n", $stub, $stub/$total*100 );
+printf( "total: %-10d %6.2f%%\n", $total, 100 );
+
+$hits = intval($wgMemc->get(wfMemcKey('stats','image_cache_hit')));
+$misses = intval($wgMemc->get(wfMemcKey('stats','image_cache_miss')));
+$updates = intval($wgMemc->get(wfMemcKey('stats','image_cache_update')));
+$total = $hits + $misses;
+print("\nImage cache\n");
+printf( "hits: %-10d %6.2f%%\n", $hits, $hits/$total*100 );
+printf( "misses: %-10d %6.2f%%\n", $misses, $misses/$total*100 );
+printf( "updates: %-10d\n", $updates );
+
+$hits = intval($wgMemc->get(wfMemcKey('stats','diff_cache_hit')));
+$misses = intval($wgMemc->get(wfMemcKey('stats','diff_cache_miss')));
+$uncacheable = intval($wgMemc->get(wfMemcKey('stats','diff_uncacheable')));
+$total = $hits + $misses + $uncacheable;
+print("\nDiff cache\n");
+printf( "hits: %-10d %6.2f%%\n", $hits, $hits/$total*100 );
+printf( "misses: %-10d %6.2f%%\n", $misses, $misses/$total*100 );
+printf( "uncacheable: %-10d %6.2f%%\n", $uncacheable, $uncacheable/$total*100 );
+
+?>
diff --git a/maintenance/storage/blobs.sql b/maintenance/storage/blobs.sql
new file mode 100644
index 000000000000..5782ac47b75f
--- /dev/null
+++ b/maintenance/storage/blobs.sql
@@ -0,0 +1,8 @@
+-- Blobs table for external storage
+
+CREATE TABLE /*$wgDBprefix*/blobs (
+ blob_id int(8) NOT NULL AUTO_INCREMENT,
+ blob_text mediumtext,
+ PRIMARY KEY (blob_id)
+) TYPE=InnoDB;
+
diff --git a/maintenance/storage/checkStorage.php b/maintenance/storage/checkStorage.php
new file mode 100644
index 000000000000..579954d50e5c
--- /dev/null
+++ b/maintenance/storage/checkStorage.php
@@ -0,0 +1,468 @@
+<?php
+
+/**
+ * Fsck for MediaWiki
+ */
+
+define( 'CONCAT_HEADER', 'O:27:"concatenatedgziphistoryblob"' );
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ require_once( dirname(__FILE__) . '/../commandLine.inc' );
+ require_once( 'ExternalStore.php' );
+ require_once( 'ExternalStoreDB.php' );
+ require_once( 'SpecialImport.php' );
+
+ $cs = new CheckStorage;
+ $fix = isset( $options['fix'] );
+ if ( isset( $args[0] ) ) {
+ $xml = $args[0];
+ } else {
+ $xml = false;
+ }
+ $cs->check( $fix, $xml );
+}
+
+
+//----------------------------------------------------------------------------------
+
+class CheckStorage
+{
+ var $oldIdMap, $errors;
+ var $dbStore = null;
+
+ var $errorDescriptions = array(
+ 'restore text' => 'Damaged text, need to be restored from a backup',
+ 'restore revision' => 'Damaged revision row, need to be restored from a backup',
+ 'unfixable' => 'Unexpected errors with no automated fixing method',
+ 'fixed' => 'Errors already fixed',
+ 'fixable' => 'Errors which would already be fixed if --fix was specified',
+ );
+
+ function check( $fix = false, $xml = '' ) {
+ $fname = 'checkStorage';
+ $dbr =& wfGetDB( DB_SLAVE );
+ if ( $fix ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ print "Checking, will fix errors if possible...\n";
+ } else {
+ print "Checking...\n";
+ }
+ $maxRevId = $dbr->selectField( 'revision', 'MAX(rev_id)', false, $fname );
+ $chunkSize = 1000;
+ $flagStats = array();
+ $objectStats = array();
+ $knownFlags = array( 'external', 'gzip', 'object', 'utf-8' );
+ $this->errors = array(
+ 'restore text' => array(),
+ 'restore revision' => array(),
+ 'unfixable' => array(),
+ 'fixed' => array(),
+ 'fixable' => array(),
+ );
+
+ for ( $chunkStart = 1 ; $chunkStart < $maxRevId; $chunkStart += $chunkSize ) {
+ $chunkEnd = $chunkStart + $chunkSize - 1;
+ //print "$chunkStart of $maxRevId\n";
+
+ // Fetch revision rows
+ $this->oldIdMap = array();
+ $dbr->ping();
+ $res = $dbr->select( 'revision', array( 'rev_id', 'rev_text_id' ),
+ array( "rev_id BETWEEN $chunkStart AND $chunkEnd" ), $fname );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $this->oldIdMap[$row->rev_id] = $row->rev_text_id;
+ }
+ $dbr->freeResult( $res );
+
+ if ( !count( $this->oldIdMap ) ) {
+ continue;
+ }
+
+ // Fetch old_flags
+ $missingTextRows = array_flip( $this->oldIdMap );
+ $externalRevs = array();
+ $objectRevs = array();
+ $res = $dbr->select( 'text', array( 'old_id', 'old_flags' ),
+ 'old_id IN (' . implode( ',', $this->oldIdMap ) . ')', $fname );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $flags = $row->old_flags;
+ $id = $row->old_id;
+
+ // Create flagStats row if it doesn't exist
+ $flagStats = $flagStats + array( $flags => 0 );
+ // Increment counter
+ $flagStats[$flags]++;
+
+ // Not missing
+ unset( $missingTextRows[$row->old_id] );
+
+ // Check for external or object
+ if ( $flags == '' ) {
+ $flagArray = array();
+ } else {
+ $flagArray = explode( ',', $flags );
+ }
+ if ( in_array( 'external', $flagArray ) ) {
+ $externalRevs[] = $id;
+ } elseif ( in_array( 'object', $flagArray ) ) {
+ $objectRevs[] = $id;
+ }
+
+ // Check for unrecognised flags
+ if ( $flags == '0' ) {
+ // This is a known bug from 2004
+ // It's safe to just erase the old_flags field
+ if ( $fix ) {
+ $this->error( 'fixed', "Warning: old_flags set to 0", $id );
+ $dbw->ping();
+ $dbw->update( 'text', array( 'old_flags' => '' ),
+ array( 'old_id' => $id ), $fname );
+ echo "Fixed\n";
+ } else {
+ $this->error( 'fixable', "Warning: old_flags set to 0", $id );
+ }
+ } elseif ( count( array_diff( $flagArray, $knownFlags ) ) ) {
+ $this->error( 'unfixable', "Error: invalid flags field \"$flags\"", $id );
+ }
+ }
+ $dbr->freeResult( $res );
+
+ // Output errors for any missing text rows
+ foreach ( $missingTextRows as $oldId => $revId ) {
+ $this->error( 'restore revision', "Error: missing text row", $oldId );
+ }
+
+ // Verify external revisions
+ $externalConcatBlobs = array();
+ $externalNormalBlobs = array();
+ if ( count( $externalRevs ) ) {
+ $res = $dbr->select( 'text', array( 'old_id', 'old_flags', 'old_text' ),
+ array( 'old_id IN (' . implode( ',', $externalRevs ) . ')' ), $fname );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $urlParts = explode( '://', $row->old_text, 2 );
+ if ( count( $urlParts ) !== 2 || $urlParts[1] == '' ) {
+ $this->error( 'restore text', "Error: invalid URL \"{$row->old_text}\"", $row->old_id );
+ continue;
+ }
+ list( $proto, $path ) = $urlParts;
+ if ( $proto != 'DB' ) {
+ $this->error( 'restore text', "Error: invalid external protocol \"$proto\"", $row->old_id );
+ continue;
+ }
+ $path = explode( '/', $row->old_text );
+ $cluster = $path[2];
+ $id = $path[3];
+ if ( isset( $path[4] ) ) {
+ $externalConcatBlobs[$cluster][$id][] = $row->old_id;
+ } else {
+ $externalNormalBlobs[$cluster][$id][] = $row->old_id;
+ }
+ }
+ $dbr->freeResult( $res );
+ }
+
+ // Check external concat blobs for the right header
+ $this->checkExternalConcatBlobs( $externalConcatBlobs );
+
+ // Check external normal blobs for existence
+ if ( count( $externalNormalBlobs ) ) {
+ if ( is_null( $this->dbStore ) ) {
+ $this->dbStore = new ExternalStoreDB;
+ }
+ foreach ( $externalConcatBlobs as $cluster => $xBlobIds ) {
+ $blobIds = array_keys( $xBlobIds );
+ $extDb =& $this->dbStore->getSlave( $cluster );
+ $blobsTable = $this->dbStore->getTable( $extDb );
+ $res = $extDb->select( $blobsTable,
+ array( 'blob_id' ),
+ array( 'blob_id IN( ' . implode( ',', $blobIds ) . ')' ), $fname );
+ while ( $row = $extDb->fetchObject( $res ) ) {
+ unset( $xBlobIds[$row->blob_id] );
+ }
+ $extDb->freeResult( $res );
+ // Print errors for missing blobs rows
+ foreach ( $xBlobIds as $blobId => $oldId ) {
+ $this->error( 'restore text', "Error: missing target $blobId for one-part ES URL", $oldId );
+ }
+ }
+ }
+
+ // Check local objects
+ $dbr->ping();
+ $concatBlobs = array();
+ $curIds = array();
+ if ( count( $objectRevs ) ) {
+ $headerLength = 300;
+ $res = $dbr->select( 'text', array( 'old_id', 'old_flags', "LEFT(old_text, $headerLength) AS header" ),
+ array( 'old_id IN (' . implode( ',', $objectRevs ) . ')' ), $fname );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $oldId = $row->old_id;
+ if ( !preg_match( '/^O:(\d+):"(\w+)"/', $row->header, $matches ) ) {
+ $this->error( 'restore text', "Error: invalid object header", $oldId );
+ continue;
+ }
+
+ $className = strtolower( $matches[2] );
+ if ( strlen( $className ) != $matches[1] ) {
+ $this->error( 'restore text', "Error: invalid object header, wrong class name length", $oldId );
+ continue;
+ }
+
+ $objectStats = $objectStats + array( $className => 0 );
+ $objectStats[$className]++;
+
+ switch ( $className ) {
+ case 'concatenatedgziphistoryblob':
+ // Good
+ break;
+ case 'historyblobstub':
+ case 'historyblobcurstub':
+ if ( strlen( $row->header ) == $headerLength ) {
+ $this->error( 'unfixable', "Error: overlong stub header", $oldId );
+ continue;
+ }
+ $stubObj = unserialize( $row->header );
+ if ( !is_object( $stubObj ) ) {
+ $this->error( 'restore text', "Error: unable to unserialize stub object", $oldId );
+ continue;
+ }
+ if ( $className == 'historyblobstub' ) {
+ $concatBlobs[$stubObj->mOldId][] = $oldId;
+ } else {
+ $curIds[$stubObj->mCurId][] = $oldId;
+ }
+ break;
+ default:
+ $this->error( 'unfixable', "Error: unrecognised object class \"$className\"", $oldId );
+ }
+ }
+ $dbr->freeResult( $res );
+ }
+
+ // Check local concat blob validity
+ $externalConcatBlobs = array();
+ if ( count( $concatBlobs ) ) {
+ $headerLength = 300;
+ $res = $dbr->select( 'text', array( 'old_id', 'old_flags', "LEFT(old_text, $headerLength) AS header" ),
+ array( 'old_id IN (' . implode( ',', array_keys( $concatBlobs ) ) . ')' ), $fname );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $flags = explode( ',', $row->old_flags );
+ if ( in_array( 'external', $flags ) ) {
+ // Concat blob is in external storage?
+ if ( in_array( 'object', $flags ) ) {
+ $urlParts = explode( '/', $row->header );
+ if ( $urlParts[0] != 'DB:' ) {
+ $this->error( 'unfixable', "Error: unrecognised external storage type \"{$urlParts[0]}", $row->old_id );
+ } else {
+ $cluster = $urlParts[2];
+ $id = $urlParts[3];
+ if ( !isset( $externalConcatBlobs[$cluster][$id] ) ) {
+ $externalConcatBlobs[$cluster][$id] = array();
+ }
+ $externalConcatBlobs[$cluster][$id] = array_merge(
+ $externalConcatBlobs[$cluster][$id], $concatBlobs[$row->old_id]
+ );
+ }
+ } else {
+ $this->error( 'unfixable', "Error: invalid flags \"{$row->old_flags}\" on concat bulk row {$row->old_id}",
+ $concatBlobs[$row->old_id] );
+ }
+ } elseif ( strcasecmp( substr( $row->header, 0, strlen( CONCAT_HEADER ) ), CONCAT_HEADER ) ) {
+ $this->error( 'restore text', "Error: Incorrect object header for concat bulk row {$row->old_id}",
+ $concatBlobs[$row->old_id] );
+ } # else good
+
+ unset( $concatBlobs[$row->old_id] );
+ }
+ $dbr->freeResult( $res );
+ }
+
+ // Check targets of unresolved stubs
+ $this->checkExternalConcatBlobs( $externalConcatBlobs );
+
+ // next chunk
+ }
+
+ print "\n\nErrors:\n";
+ foreach( $this->errors as $name => $errors ) {
+ if ( count( $errors ) ) {
+ $description = $this->errorDescriptions[$name];
+ echo "$description: " . implode( ',', array_keys( $errors ) ) . "\n";
+ }
+ }
+
+ if ( count( $this->errors['restore text'] ) && $fix ) {
+ if ( (string)$xml !== '' ) {
+ $this->restoreText( array_keys( $this->errors['restore text'] ), $xml );
+ } else {
+ echo "Can't fix text, no XML backup specified\n";
+ }
+ }
+
+ print "\nFlag statistics:\n";
+ $total = array_sum( $flagStats );
+ foreach ( $flagStats as $flag => $count ) {
+ printf( "%-30s %10d %5.2f%%\n", $flag, $count, $count / $total * 100 );
+ }
+ print "\nLocal object statistics:\n";
+ $total = array_sum( $objectStats );
+ foreach ( $objectStats as $className => $count ) {
+ printf( "%-30s %10d %5.2f%%\n", $className, $count, $count / $total * 100 );
+ }
+ }
+
+
+ function error( $type, $msg, $ids ) {
+ if ( is_array( $ids ) && count( $ids ) == 1 ) {
+ $ids = reset( $ids );
+ }
+ if ( is_array( $ids ) ) {
+ $revIds = array();
+ foreach ( $ids as $id ) {
+ $revIds = array_merge( $revIds, array_keys( $this->oldIdMap, $id ) );
+ }
+ print "$msg in text rows " . implode( ', ', $ids ) .
+ ", revisions " . implode( ', ', $revIds ) . "\n";
+ } else {
+ $id = $ids;
+ $revIds = array_keys( $this->oldIdMap, $id );
+ if ( count( $revIds ) == 1 ) {
+ print "$msg in old_id $id, rev_id {$revIds[0]}\n";
+ } else {
+ print "$msg in old_id $id, revisions " . implode( ', ', $revIds ) . "\n";
+ }
+ }
+ $this->errors[$type] = $this->errors[$type] + array_flip( $revIds );
+ }
+
+ function checkExternalConcatBlobs( $externalConcatBlobs ) {
+ $fname = 'CheckStorage::checkExternalConcatBlobs';
+ if ( !count( $externalConcatBlobs ) ) {
+ return;
+ }
+
+ if ( is_null( $this->dbStore ) ) {
+ $this->dbStore = new ExternalStoreDB;
+ }
+
+ foreach ( $externalConcatBlobs as $cluster => $oldIds ) {
+ $blobIds = array_keys( $oldIds );
+ $extDb =& $this->dbStore->getSlave( $cluster );
+ $blobsTable = $this->dbStore->getTable( $extDb );
+ $headerLength = strlen( CONCAT_HEADER );
+ $res = $extDb->select( $blobsTable,
+ array( 'blob_id', "LEFT(blob_text, $headerLength) AS header" ),
+ array( 'blob_id IN( ' . implode( ',', $blobIds ) . ')' ), $fname );
+ while ( $row = $extDb->fetchObject( $res ) ) {
+ if ( strcasecmp( $row->header, CONCAT_HEADER ) ) {
+ $this->error( 'restore text', "Error: invalid header on target $cluster/{$row->blob_id} of two-part ES URL",
+ $oldIds[$row->blob_id] );
+ }
+ unset( $oldIds[$row->blob_id] );
+
+ }
+ $extDb->freeResult( $res );
+
+ // Print errors for missing blobs rows
+ foreach ( $oldIds as $blobId => $oldIds ) {
+ $this->error( 'restore text', "Error: missing target $cluster/$blobId for two-part ES URL", $oldIds );
+ }
+ }
+ }
+
+ function restoreText( $revIds, $xml ) {
+ global $wgTmpDirectory, $wgDBname;
+
+ if ( !count( $revIds ) ) {
+ return;
+ }
+
+ print "Restoring text from XML backup...\n";
+
+ $revFileName = "$wgTmpDirectory/broken-revlist-$wgDBname";
+ $filteredXmlFileName = "$wgTmpDirectory/filtered-$wgDBname.xml";
+
+ // Write revision list
+ if ( !file_put_contents( $revFileName, implode( "\n", $revIds ) ) ) {
+ echo "Error writing revision list, can't restore text\n";
+ return;
+ }
+
+ // Run mwdumper
+ echo "Filtering XML dump...\n";
+ $exitStatus = 0;
+ passthru( 'mwdumper ' .
+ wfEscapeShellArg(
+ "--output=file:$filteredXmlFileName",
+ "--filter=revlist:$revFileName",
+ $xml
+ ), $exitStatus
+ );
+
+ if ( $exitStatus ) {
+ echo "mwdumper died with exit status $exitStatus\n";
+ return;
+ }
+
+ $file = fopen( $filteredXmlFileName, 'r' );
+ if ( !$file ) {
+ echo "Unable to open filtered XML file\n";
+ return;
+ }
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbr->ping();
+ $dbw->ping();
+
+ $source = new ImportStreamSource( $file );
+ $importer = new WikiImporter( $source );
+ $importer->setRevisionCallback( array( &$this, 'importRevision' ) );
+ $importer->doImport();
+ }
+
+ function importRevision( &$revision, &$importer ) {
+ $fname = 'CheckStorage::importRevision';
+
+ $id = $revision->getID();
+ $text = $revision->getText();
+ if ( $text === '' ) {
+ // This is what happens if the revision was broken at the time the
+ // dump was made. Unfortunately, it also happens if the revision was
+ // legitimately blank, so there's no way to tell the difference. To
+ // be safe, we'll skip it and leave it broken
+ $id = $id ? $id : '';
+ echo "Revision $id is blank in the dump, may have been broken before export\n";
+ return;
+ }
+
+ if ( !$id ) {
+ // No ID, can't import
+ echo "No id tag in revision, can't import\n";
+ return;
+ }
+
+ // Find text row again
+ $dbr =& wfGetDB( DB_SLAVE );
+ $oldId = $dbr->selectField( 'revision', 'rev_text_id', array( 'rev_id' => $id ), $fname );
+ if ( !$oldId ) {
+ echo "Missing revision row for rev_id $id\n";
+ return;
+ }
+
+ // Compress the text
+ $flags = Revision::compressRevisionText( $text );
+
+ // Update the text row
+ $dbw->update( 'text',
+ array( 'old_flags' => $flags, 'old_text' => $text ),
+ array( 'old_id' => $oldId ),
+ $fname, array( 'LIMIT' => 1 )
+ );
+
+ // Remove it from the unfixed list and add it to the fixed list
+ unset( $this->errors['restore text'][$id] );
+ $this->errors['fixed'][$id] = true;
+ }
+}
+?>
diff --git a/maintenance/storage/compressOld.inc b/maintenance/storage/compressOld.inc
new file mode 100644
index 000000000000..d38bb74143d1
--- /dev/null
+++ b/maintenance/storage/compressOld.inc
@@ -0,0 +1,311 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+require_once( 'Revision.php' );
+require_once( 'ExternalStoreDB.php' );
+
+/** @todo document */
+function compressOldPages( $start = 0, $extdb = '' ) {
+ $fname = 'compressOldPages';
+
+ $chunksize = 50;
+ print "Starting from old_id $start...\n";
+ $dbw =& wfGetDB( DB_MASTER );
+ do {
+ $end = $start + $chunksize;
+ $res = $dbw->select( 'text', array( 'old_id','old_flags','old_namespace','old_title','old_text' ),
+ "old_id>=$start", $fname, array( 'ORDER BY' => 'old_id', 'LIMIT' => $chunksize, 'FOR UPDATE' ) );
+ if( $dbw->numRows( $res ) == 0 ) {
+ break;
+ }
+ $last = $start;
+ while( $row = $dbw->fetchObject( $res ) ) {
+ # print " {$row->old_id} - {$row->old_namespace}:{$row->old_title}\n";
+ compressPage( $row, $extdb );
+ $last = $row->old_id;
+ }
+ $dbw->freeResult( $res );
+ $start = $last + 1; # Deletion may leave long empty stretches
+ print "$start...\n";
+ } while( true );
+}
+
+/** @todo document */
+function compressPage( $row, $extdb ) {
+ $fname = 'compressPage';
+ if ( false !== strpos( $row->old_flags, 'gzip' ) || false !== strpos( $row->old_flags, 'object' ) ) {
+ #print "Already compressed row {$row->old_id}\n";
+ return false;
+ }
+ $dbw =& wfGetDB( DB_MASTER );
+ $flags = $row->old_flags ? "{$row->old_flags},gzip" : "gzip";
+ $compress = gzdeflate( $row->old_text );
+
+ # Store in external storage if required
+ if ( $extdb !== '' ) {
+ $storeObj = new ExternalStoreDB;
+ $compress = $storeObj->store( $extdb, $compress );
+ if ( $compress === false ) {
+ print "Unable to store object\n";
+ return false;
+ }
+ }
+
+ # Update text row
+ $dbw->update( 'text',
+ array( /* SET */
+ 'old_flags' => $flags,
+ 'old_text' => $compress
+ ), array( /* WHERE */
+ 'old_id' => $row->old_id
+ ), $fname, 'LIMIT 1'
+ );
+ return true;
+}
+
+define( 'LS_INDIVIDUAL', 0 );
+define( 'LS_CHUNKED', 1 );
+
+/** @todo document */
+function compressWithConcat( $startId, $maxChunkSize, $maxChunkFactor, $factorThreshold, $beginDate,
+ $endDate, $extdb="", $maxPageId = false )
+{
+ $fname = 'compressWithConcat';
+ $loadStyle = LS_CHUNKED;
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $dbw =& wfGetDB( DB_MASTER );
+
+ # Set up external storage
+ if ( $extdb != '' ) {
+ $storeObj = new ExternalStoreDB;
+ }
+
+ # Get all articles by page_id
+ if ( !$maxPageId ) {
+ $maxPageId = $dbr->selectField( 'page', 'max(page_id)', '', $fname );
+ }
+ print "Starting from $startId of $maxPageId\n";
+ $pageConds = array();
+
+ /*
+ if ( $exclude_ns0 ) {
+ print "Excluding main namespace\n";
+ $pageConds[] = 'page_namespace<>0';
+ }
+ if ( $queryExtra ) {
+ $pageConds[] = $queryExtra;
+ }
+ */
+
+ # For each article, get a list of revisions which fit the criteria
+
+ # No recompression, use a condition on old_flags
+ # Don't compress object type entities, because that might produce data loss when
+ # overwriting bulk storage concat rows. Don't compress external references, because
+ # the script doesn't yet delete rows from external storage.
+ $conds = array(
+ "old_flags NOT LIKE '%object%' AND old_flags NOT LIKE '%external%'");
+
+ if ( $beginDate ) {
+ $conds[] = "rev_timestamp>'" . $beginDate . "'";
+ }
+ if ( $endDate ) {
+ $conds[] = "rev_timestamp<'" . $endDate . "'";
+ }
+ if ( $loadStyle == LS_CHUNKED ) {
+ $tables = array( 'revision', 'text' );
+ $fields = array( 'rev_id', 'rev_text_id', 'old_flags', 'old_text' );
+ $conds[] = 'rev_text_id=old_id';
+ $revLoadOptions = 'FOR UPDATE';
+ } else {
+ $tables = array( 'revision' );
+ $fields = array( 'rev_id', 'rev_text_id' );
+ $revLoadOptions = array();
+ }
+
+ # Don't work with current revisions
+ # Don't lock the page table for update either -- TS 2006-04-04
+ #$tables[] = 'page';
+ #$conds[] = 'page_id=rev_page AND rev_id != page_latest';
+
+ $oldReadsSinceLastSlaveWait = 0; #check slave lag periodically
+ $totalMatchingRevisions = 0;
+ $masterPos = false;
+ for ( $pageId = $startId; $pageId <= $maxPageId; $pageId++ ) {
+ wfWaitForSlaves( 5 );
+
+ # Wake up
+ $dbr->ping();
+
+ # Get the page row
+ $pageRes = $dbr->select( 'page',
+ array('page_id', 'page_namespace', 'page_title','page_latest'),
+ $pageConds + array('page_id' => $pageId), $fname );
+ if ( $dbr->numRows( $pageRes ) == 0 ) {
+ continue;
+ }
+ $pageRow = $dbr->fetchObject( $pageRes );
+
+ # Display progress
+ $titleObj = Title::makeTitle( $pageRow->page_namespace, $pageRow->page_title );
+ print "$pageId\t" . $titleObj->getPrefixedDBkey() . " ";
+
+ print_r(
+ array(
+ 'rev_page' => $pageRow->page_id,
+ # Don't operate on the current revision
+ # Use < instead of <> in case the current revision has changed
+ # since the page select, which wasn't locking
+ 'rev_id < ' . $pageRow->page_latest
+ ) + $conds
+ );
+ exit;
+
+ # Load revisions
+ $revRes = $dbw->select( $tables, $fields,
+ array(
+ 'rev_page' => $pageRow->page_id,
+ # Don't operate on the current revision
+ # Use < instead of <> in case the current revision has changed
+ # since the page select, which wasn't locking
+ 'rev_id < ' . $pageRow->page_latest
+ ) + $conds,
+ $fname,
+ $revLoadOptions
+ );
+ $revs = array();
+ while ( $revRow = $dbw->fetchObject( $revRes ) ) {
+ $revs[] = $revRow;
+ }
+
+ if ( count( $revs ) < 2) {
+ # No revisions matching, no further processing
+ print "\n";
+ continue;
+ }
+
+ # For each chunk
+ $i = 0;
+ while ( $i < count( $revs ) ) {
+ if ( $i < count( $revs ) - $maxChunkSize ) {
+ $thisChunkSize = $maxChunkSize;
+ } else {
+ $thisChunkSize = count( $revs ) - $i;
+ }
+
+ $chunk = new ConcatenatedGzipHistoryBlob();
+ $stubs = array();
+ $dbw->begin();
+ $usedChunk = false;
+ $primaryOldid = $revs[$i]->rev_text_id;
+
+ # Get the text of each revision and add it to the object
+ for ( $j = 0; $j < $thisChunkSize && $chunk->isHappy( $maxChunkFactor, $factorThreshold ); $j++ ) {
+ $oldid = $revs[$i + $j]->rev_text_id;
+
+ # Get text
+ if ( $loadStyle == LS_INDIVIDUAL ) {
+ $textRow = $dbw->selectRow( 'text',
+ array( 'old_flags', 'old_text' ),
+ array( 'old_id' => $oldid ),
+ $fname,
+ 'FOR UPDATE'
+ );
+ $text = Revision::getRevisionText( $textRow );
+ } else {
+ $text = Revision::getRevisionText( $revs[$i + $j] );
+ }
+
+ if ( $text === false ) {
+ print "\nError, unable to get text in old_id $oldid\n";
+ #$dbw->delete( 'old', array( 'old_id' => $oldid ) );
+ }
+
+ if ( $extdb == "" && $j == 0 ) {
+ $chunk->setText( $text );
+ print '.';
+ } else {
+ # Don't make a stub if it's going to be longer than the article
+ # Stubs are typically about 100 bytes
+ if ( strlen( $text ) < 120 ) {
+ $stub = false;
+ print 'x';
+ } else {
+ $stub = $chunk->addItem( $text );
+ $stub->setLocation( $primaryOldid );
+ $stub->setReferrer( $oldid );
+ print '.';
+ $usedChunk = true;
+ }
+ $stubs[$j] = $stub;
+ }
+ }
+ $thisChunkSize = $j;
+
+ # If we couldn't actually use any stubs because the pages were too small, do nothing
+ if ( $usedChunk ) {
+ if ( $extdb != "" ) {
+ # Move blob objects to External Storage
+ $stored = $storeObj->store( $extdb, serialize( $chunk ));
+ if ($stored === false) {
+ print "Unable to store object\n";
+ return false;
+ }
+ # Store External Storage URLs instead of Stub placeholders
+ foreach ($stubs as $stub) {
+ if ($stub===false)
+ continue;
+ # $stored should provide base path to a BLOB
+ $url = $stored."/".$stub->getHash();
+ $dbw->update( 'text',
+ array( /* SET */
+ 'old_text' => $url,
+ 'old_flags' => 'external,utf-8',
+ ), array ( /* WHERE */
+ 'old_id' => $stub->getReferrer(),
+ )
+ );
+ }
+ } else {
+ # Store the main object locally
+ $dbw->update( 'text',
+ array( /* SET */
+ 'old_text' => serialize( $chunk ),
+ 'old_flags' => 'object,utf-8',
+ ), array( /* WHERE */
+ 'old_id' => $primaryOldid
+ )
+ );
+
+ # Store the stub objects
+ for ( $j = 1; $j < $thisChunkSize; $j++ ) {
+ # Skip if not compressing and don't overwrite the first revision
+ if ( $stubs[$j] !== false && $revs[$i + $j]->rev_text_id != $primaryOldid ) {
+ $dbw->update( 'text',
+ array( /* SET */
+ 'old_text' => serialize($stubs[$j]),
+ 'old_flags' => 'object,utf-8',
+ ), array( /* WHERE */
+ 'old_id' => $revs[$i + $j]->rev_text_id
+ )
+ );
+ }
+ }
+ }
+ }
+ # Done, next
+ print "/";
+ $dbw->commit();
+ $i += $thisChunkSize;
+ wfWaitForSlaves( 5 );
+ }
+ print "\n";
+ }
+ return true;
+}
+?>
diff --git a/maintenance/storage/compressOld.php b/maintenance/storage/compressOld.php
new file mode 100644
index 000000000000..d597f1dfc557
--- /dev/null
+++ b/maintenance/storage/compressOld.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Compress the text of a wiki
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+
+/**
+ * Usage:
+ *
+ * Non-wikimedia
+ * php compressOld.php [options...]
+ *
+ * Wikimedia
+ * php compressOld.php <database> [options...]
+ *
+ * Options are:
+ * -t <type> set compression type to either:
+ * gzip: compress revisions independently
+ * concat: concatenate revisions and compress in chunks (default)
+ * -c <chunk-size> maximum number of revisions in a concat chunk
+ * -b <begin-date> earliest date to check for uncompressed revisions
+ * -e <end-date> latest revision date to compress
+ * -s <start-id> the old_id to start from
+ * -f <max-factor> the maximum ratio of compressed chunk bytes to uncompressed avg. revision bytes
+ * -h <threshold> is a minimum number of KB, where <max-factor> cuts in
+ * --extdb <cluster> store specified revisions in an external cluster (untested)
+ *
+ */
+
+$optionsWithArgs = array( 't', 'c', 's', 'f', 'h', 'extdb', 'endid' );
+require_once( "../commandLine.inc" );
+require_once( "compressOld.inc" );
+
+if( !function_exists( "gzdeflate" ) ) {
+ print "You must enable zlib support in PHP to compress old revisions!\n";
+ print "Please see http://www.php.net/manual/en/ref.zlib.php\n\n";
+ wfDie();
+}
+
+$defaults = array(
+ 't' => 'concat',
+ 'c' => 20,
+ 's' => 0,
+ 'f' => 5,
+ 'h' => 100,
+ 'b' => '',
+ 'e' => '',
+ 'extdb' => '',
+ 'endid' => false,
+);
+
+$options = $options + $defaults;
+
+if ( $options['t'] != 'concat' && $options['t'] != 'gzip' ) {
+ print "Type \"{$options['t']}\" not supported\n";
+}
+
+if ( $options['extdb'] != '' ) {
+ print "Compressing database $wgDBname to external cluster {$options['extdb']}\n" . str_repeat('-', 76) . "\n\n";
+} else {
+ print "Compressing database $wgDBname\n" . str_repeat('-', 76) . "\n\n";
+}
+
+$success = true;
+if ( $options['t'] == 'concat' ) {
+ $success = compressWithConcat( $options['s'], $options['c'], $options['f'], $options['h'], $options['b'],
+ $options['e'], $options['extdb'], $options['endid'] );
+} else {
+ compressOldPages( $options['s'], $options['extdb'] );
+}
+
+if ( $success ) {
+ print "Done.\n";
+}
+
+exit();
+
+?>
diff --git a/maintenance/storage/dumpRev.php b/maintenance/storage/dumpRev.php
new file mode 100644
index 000000000000..4d0ccb5853af
--- /dev/null
+++ b/maintenance/storage/dumpRev.php
@@ -0,0 +1,14 @@
+<?php
+
+require_once( 'commandLine.inc' );
+$dbr =& wfGetDB( DB_SLAVE );
+$row = $dbr->selectRow( 'old', array( 'old_flags', 'old_text' ), array( 'old_id' => $args[0] ) );
+$obj = unserialize( $row->old_text );
+
+if ( get_class( $obj ) == 'concatenatedgziphistoryblob' ) {
+ print_r( array_keys( $obj->mItems ) );
+} else {
+ var_dump( $obj );
+}
+
+?>
diff --git a/maintenance/storage/make-blobs b/maintenance/storage/make-blobs
new file mode 100755
index 000000000000..9eb7e83e7bf1
--- /dev/null
+++ b/maintenance/storage/make-blobs
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+if [ X$2 == X ];then
+ echo 'Usage: make-blobs <server> <db>'
+ exit 1
+fi
+
+echo "CREATE DATABASE $2" | mysql -u wikiadmin -p`wikiadmin_pass` -h $1 && \
+mysql -u wikiadmin -p`wikiadmin_pass` -h $1 $2 < blobs.sql
+
+
diff --git a/maintenance/storage/moveToExternal.php b/maintenance/storage/moveToExternal.php
new file mode 100644
index 000000000000..0b46f70bdf93
--- /dev/null
+++ b/maintenance/storage/moveToExternal.php
@@ -0,0 +1,97 @@
+<?php
+
+define( 'REPORTING_INTERVAL', 100 );
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ $optionsWithArgs = array( 'm' );
+
+ require_once( '../commandLine.inc' );
+ require_once( 'ExternalStoreDB.php' );
+ require_once( 'resolveStubs.php' );
+
+ $fname = 'moveToExternal';
+
+ if ( !isset( $args[0] ) ) {
+ print "Usage: php moveToExternal.php [-m <maxid>] <cluster>\n";
+ exit;
+ }
+
+ $cluster = $args[0];
+ $dbw =& wfGetDB( DB_MASTER );
+
+ if ( isset( $options['m'] ) ) {
+ $maxID = $options['m'];
+ } else {
+ $maxID = $dbw->selectField( 'text', 'MAX(old_id)', false, $fname );
+ }
+
+ moveToExternal( $cluster, $maxID );
+}
+
+
+
+function moveToExternal( $cluster, $maxID ) {
+ $fname = 'moveToExternal';
+ $dbw =& wfGetDB( DB_MASTER );
+
+ print "Moving $maxID text rows to external storage\n";
+ $ext = new ExternalStoreDB;
+ for ( $id = 1; $id <= $maxID; $id++ ) {
+ if ( !($id % REPORTING_INTERVAL) ) {
+ print "$id\n";
+ wfWaitForSlaves( 5 );
+ }
+ $row = $dbw->selectRow( 'text', array( 'old_flags', 'old_text' ),
+ array(
+ 'old_id' => $id,
+ "old_flags NOT LIKE '%external%'",
+ ), $fname );
+ if ( !$row ) {
+ # Non-existent or already done
+ continue;
+ }
+
+ # Resolve stubs
+ $text = $row->old_text;
+ if ( $row->old_flags === '' ) {
+ $flags = 'external';
+ } else {
+ $flags = "{$row->old_flags},external";
+ }
+
+ if ( strpos( $flags, 'object' ) !== false ) {
+ $obj = unserialize( $text );
+ $className = strtolower( get_class( $obj ) );
+ if ( $className == 'historyblobstub' ) {
+ resolveStub( $id, $row->old_text, $row->old_flags );
+ continue;
+ } elseif ( $className == 'historyblobcurstub' ) {
+ $text = gzdeflate( $obj->getText() );
+ $flags = 'utf-8,gzip,external';
+ } elseif ( $className == 'concatenatedgziphistoryblob' ) {
+ // Do nothing
+ } else {
+ print "Warning: unrecognised object class \"$className\"\n";
+ continue;
+ }
+ }
+
+ if ( strlen( $text ) < 100 ) {
+ // Don't move tiny revisions
+ continue;
+ }
+
+ #print "Storing " . strlen( $text ) . " bytes to $url\n";
+
+ $url = $ext->store( $cluster, $text );
+ if ( !$url ) {
+ print "Error writing to external storage\n";
+ exit;
+ }
+ $dbw->update( 'text',
+ array( 'old_flags' => $flags, 'old_text' => $url ),
+ array( 'old_id' => $id ), $fname );
+ }
+}
+
+?>
diff --git a/maintenance/storage/resolveStubs.php b/maintenance/storage/resolveStubs.php
new file mode 100644
index 000000000000..e93d5c972fd0
--- /dev/null
+++ b/maintenance/storage/resolveStubs.php
@@ -0,0 +1,100 @@
+<?php
+
+define( 'REPORTING_INTERVAL', 100 );
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ $optionsWithArgs = array( 'm' );
+
+ require_once( '../commandLine.inc' );
+ require_once( 'includes/ExternalStoreDB.php' );
+
+ resolveStubs();
+}
+
+/**
+ * Convert history stubs that point to an external row to direct
+ * external pointers
+ */
+function resolveStubs() {
+ $fname = 'resolveStubs';
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $dbw =& wfGetDB( DB_MASTER );
+ $maxID = $dbr->selectField( 'text', 'MAX(old_id)', false, $fname );
+ $blockSize = 10000;
+ $numBlocks = intval( $maxID / $blockSize ) + 1;
+
+ for ( $b = 0; $b < $numBlocks; $b++ ) {
+ wfWaitForSlaves( 5 );
+
+ printf( "%5.2f%%\n", $b / $numBlocks * 100 );
+ $start = intval($maxID / $numBlocks) * $b + 1;
+ $end = intval($maxID / $numBlocks) * ($b + 1);
+ $stubs = array();
+ $flagsArray = array();
+
+
+ $res = $dbr->select( 'text', array( 'old_id', 'old_text', 'old_flags' ),
+ "old_id>=$start AND old_id<=$end " .
+ # Using a more restrictive flag set for now, until I do some more analysis -- TS
+ #"AND old_flags LIKE '%object%' AND old_flags NOT LIKE '%external%' ".
+
+ "AND old_flags='object' " .
+ "AND old_text LIKE 'O:15:\"historyblobstub\"%'", $fname );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ resolveStub( $row->old_id, $row->old_text, $row->old_flags );
+ }
+ $dbr->freeResult( $res );
+
+
+ }
+ print "100%\n";
+}
+
+/**
+ * Resolve a history stub
+ */
+function resolveStub( $id, $stubText, $flags ) {
+ $fname = 'resolveStub';
+
+ $stub = unserialize( $stubText );
+ $flags = explode( ',', $flags );
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ $dbw =& wfGetDB( DB_MASTER );
+
+ if ( strtolower( get_class( $stub ) ) !== 'historyblobstub' ) {
+ print "Error found object of class " . get_class( $stub ) . ", expecting historyblobstub\n";
+ return;
+ }
+
+ # Get the (maybe) external row
+ $externalRow = $dbr->selectRow( 'text', array( 'old_text' ),
+ array( 'old_id' => $stub->mOldId, "old_flags LIKE '%external%'" ),
+ $fname
+ );
+
+ if ( !$externalRow ) {
+ # Object wasn't external
+ return;
+ }
+
+ # Preserve the legacy encoding flag, but switch from object to external
+ if ( in_array( 'utf-8', $flags ) ) {
+ $newFlags = 'external,utf-8';
+ } else {
+ $newFlags = 'external';
+ }
+
+ # Update the row
+ $dbw->update( 'text',
+ array( /* SET */
+ 'old_flags' => $newFlags,
+ 'old_text' => $externalRow->old_text . '/' . $stub->mHash
+ ),
+ array( /* WHERE */
+ 'old_id' => $id
+ ), $fname
+ );
+}
+?>
diff --git a/maintenance/tables.sql b/maintenance/tables.sql
new file mode 100644
index 000000000000..188ca63e3683
--- /dev/null
+++ b/maintenance/tables.sql
@@ -0,0 +1,1078 @@
+-- SQL to create the initial tables for the MediaWiki database.
+-- This is read and executed by the install script; you should
+-- not have to run it by itself unless doing a manual install.
+
+--
+-- General notes:
+--
+-- If possible, create tables as InnoDB to benefit from the
+-- superior resiliency against crashes and ability to read
+-- during writes (and write during reads!)
+--
+-- Only the 'searchindex' table requires MyISAM due to the
+-- requirement for fulltext index support, which is missing
+-- from InnoDB.
+--
+--
+-- The MySQL table backend for MediaWiki currently uses
+-- 14-character CHAR or VARCHAR fields to store timestamps.
+-- The format is YYYYMMDDHHMMSS, which is derived from the
+-- text format of MySQL's TIMESTAMP fields.
+--
+-- Historically TIMESTAMP fields were used, but abandoned
+-- in early 2002 after a lot of trouble with the fields
+-- auto-updating.
+--
+-- The Postgres backend uses DATETIME fields for timestamps,
+-- and we will migrate the MySQL definitions at some point as
+-- well.
+--
+--
+-- The /*$wgDBprefix*/ comments in this and other files are
+-- replaced with the defined table prefix by the installer
+-- and updater scripts. If you are installing or running
+-- updates manually, you will need to manually insert the
+-- table prefix if any when running these scripts.
+--
+
+
+--
+-- The user table contains basic account information,
+-- authentication keys, etc.
+--
+-- Some multi-wiki sites may share a single central user table
+-- between separate wikis using the $wgSharedDB setting.
+--
+-- Note that when a external authentication plugin is used,
+-- user table entries still need to be created to store
+-- preferences and to key tracking information in the other
+-- tables.
+--
+CREATE TABLE /*$wgDBprefix*/user (
+ user_id int(5) unsigned NOT NULL auto_increment,
+
+ -- Usernames must be unique, must not be in the form of
+ -- an IP address. _Shouldn't_ allow slashes or case
+ -- conflicts. Spaces are allowed, and are _not_ converted
+ -- to underscores like titles. See the User::newFromName() for
+ -- the specific tests that usernames have to pass.
+ user_name varchar(255) binary NOT NULL default '',
+
+ -- Optional 'real name' to be displayed in credit listings
+ user_real_name varchar(255) binary NOT NULL default '',
+
+ -- Password hashes, normally hashed like so:
+ -- MD5(CONCAT(user_id,'-',MD5(plaintext_password))), see
+ -- wfEncryptPassword() in GlobalFunctions.php
+ user_password tinyblob NOT NULL,
+
+ -- When using 'mail me a new password', a random
+ -- password is generated and the hash stored here.
+ -- The previous password is left in place until
+ -- someone actually logs in with the new password,
+ -- at which point the hash is moved to user_password
+ -- and the old password is invalidated.
+ user_newpassword tinyblob NOT NULL,
+
+ -- Timestamp of the last time when a new password was
+ -- sent, for throttling purposes
+ user_newpass_time char(14) binary,
+
+ -- Note: email should be restricted, not public info.
+ -- Same with passwords.
+ user_email tinytext NOT NULL,
+
+ -- Newline-separated list of name=value defining the user
+ -- preferences
+ user_options blob NOT NULL,
+
+ -- This is a timestamp which is updated when a user
+ -- logs in, logs out, changes preferences, or performs
+ -- some other action requiring HTML cache invalidation
+ -- to ensure that the UI is updated.
+ user_touched char(14) binary NOT NULL default '',
+
+ -- A pseudorandomly generated value that is stored in
+ -- a cookie when the "remember password" feature is
+ -- used (previously, a hash of the password was used, but
+ -- this was vulnerable to cookie-stealing attacks)
+ user_token char(32) binary NOT NULL default '',
+
+ -- Initially NULL; when a user's e-mail address has been
+ -- validated by returning with a mailed token, this is
+ -- set to the current timestamp.
+ user_email_authenticated char(14) binary,
+
+ -- Randomly generated token created when the e-mail address
+ -- is set and a confirmation test mail sent.
+ user_email_token char(32) binary,
+
+ -- Expiration date for the user_email_token
+ user_email_token_expires char(14) binary,
+
+ -- Timestamp of account registration.
+ -- Accounts predating this schema addition may contain NULL.
+ user_registration char(14) binary,
+
+ -- Count of edits and edit-like actions.
+ --
+ -- *NOT* intended to be an accurate copy of COUNT(*) WHERE rev_user=user_id
+ -- May contain NULL for old accounts if batch-update scripts haven't been
+ -- run, as well as listing deleted edits and other myriad ways it could be
+ -- out of sync.
+ --
+ -- Meant primarily for heuristic checks to give an impression of whether
+ -- the account has been used much.
+ --
+ user_editcount int,
+
+ PRIMARY KEY user_id (user_id),
+ UNIQUE INDEX user_name (user_name),
+ INDEX (user_email_token)
+
+) TYPE=InnoDB;
+
+--
+-- User permissions have been broken out to a separate table;
+-- this allows sites with a shared user table to have different
+-- permissions assigned to a user in each project.
+--
+-- This table replaces the old user_rights field which used a
+-- comma-separated blob.
+--
+CREATE TABLE /*$wgDBprefix*/user_groups (
+ -- Key to user_id
+ ug_user int(5) unsigned NOT NULL default '0',
+
+ -- Group names are short symbolic string keys.
+ -- The set of group names is open-ended, though in practice
+ -- only some predefined ones are likely to be used.
+ --
+ -- At runtime $wgGroupPermissions will associate group keys
+ -- with particular permissions. A user will have the combined
+ -- permissions of any group they're explicitly in, plus
+ -- the implicit '*' and 'user' groups.
+ ug_group char(16) NOT NULL default '',
+
+ PRIMARY KEY (ug_user,ug_group),
+ KEY (ug_group)
+) TYPE=InnoDB;
+
+-- Stores notifications of user talk page changes, for the display
+-- of the "you have new messages" box
+CREATE TABLE /*$wgDBprefix*/user_newtalk (
+ -- Key to user.user_id
+ user_id int(5) NOT NULL default '0',
+ -- If the user is an anonymous user hir IP address is stored here
+ -- since the user_id of 0 is ambiguous
+ user_ip varchar(40) NOT NULL default '',
+ INDEX user_id (user_id),
+ INDEX user_ip (user_ip)
+
+) TYPE=InnoDB;
+
+
+--
+-- Core of the wiki: each page has an entry here which identifies
+-- it by title and contains some essential metadata.
+--
+CREATE TABLE /*$wgDBprefix*/page (
+ -- Unique identifier number. The page_id will be preserved across
+ -- edits and rename operations, but not deletions and recreations.
+ page_id int(8) unsigned NOT NULL auto_increment,
+
+ -- A page name is broken into a namespace and a title.
+ -- The namespace keys are UI-language-independent constants,
+ -- defined in includes/Defines.php
+ page_namespace int NOT NULL,
+
+ -- The rest of the title, as text.
+ -- Spaces are transformed into underscores in title storage.
+ page_title varchar(255) binary NOT NULL,
+
+ -- Comma-separated set of permission keys indicating who
+ -- can move or edit the page.
+ page_restrictions tinyblob NOT NULL,
+
+ -- Number of times this page has been viewed.
+ page_counter bigint(20) unsigned NOT NULL default '0',
+
+ -- 1 indicates the article is a redirect.
+ page_is_redirect tinyint(1) unsigned NOT NULL default '0',
+
+ -- 1 indicates this is a new entry, with only one edit.
+ -- Not all pages with one edit are new pages.
+ page_is_new tinyint(1) unsigned NOT NULL default '0',
+
+ -- Random value between 0 and 1, used for Special:Randompage
+ page_random real unsigned NOT NULL,
+
+ -- This timestamp is updated whenever the page changes in
+ -- a way requiring it to be re-rendered, invalidating caches.
+ -- Aside from editing this includes permission changes,
+ -- creation or deletion of linked pages, and alteration
+ -- of contained templates.
+ page_touched char(14) binary NOT NULL default '',
+
+ -- Handy key to revision.rev_id of the current revision.
+ -- This may be 0 during page creation, but that shouldn't
+ -- happen outside of a transaction... hopefully.
+ page_latest int(8) unsigned NOT NULL,
+
+ -- Uncompressed length in bytes of the page's current source text.
+ page_len int(8) unsigned NOT NULL,
+
+ PRIMARY KEY page_id (page_id),
+ UNIQUE INDEX name_title (page_namespace,page_title),
+
+ -- Special-purpose indexes
+ INDEX (page_random),
+ INDEX (page_len)
+
+) TYPE=InnoDB;
+
+--
+-- Every edit of a page creates also a revision row.
+-- This stores metadata about the revision, and a reference
+-- to the text storage backend.
+--
+CREATE TABLE /*$wgDBprefix*/revision (
+ rev_id int(8) unsigned NOT NULL auto_increment,
+
+ -- Key to page_id. This should _never_ be invalid.
+ rev_page int(8) unsigned NOT NULL,
+
+ -- Key to text.old_id, where the actual bulk text is stored.
+ -- It's possible for multiple revisions to use the same text,
+ -- for instance revisions where only metadata is altered
+ -- or a rollback to a previous version.
+ rev_text_id int(8) unsigned NOT NULL,
+
+ -- Text comment summarizing the change.
+ -- This text is shown in the history and other changes lists,
+ -- rendered in a subset of wiki markup by Linker::formatComment()
+ rev_comment tinyblob NOT NULL,
+
+ -- Key to user.user_id of the user who made this edit.
+ -- Stores 0 for anonymous edits and for some mass imports.
+ rev_user int(5) unsigned NOT NULL default '0',
+
+ -- Text username or IP address of the editor.
+ rev_user_text varchar(255) binary NOT NULL default '',
+
+ -- Timestamp
+ rev_timestamp char(14) binary NOT NULL default '',
+
+ -- Records whether the user marked the 'minor edit' checkbox.
+ -- Many automated edits are marked as minor.
+ rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
+
+ -- Not yet used; reserved for future changes to the deletion system.
+ rev_deleted tinyint(1) 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)
+
+) TYPE=InnoDB;
+
+
+--
+-- Holds text of individual page revisions.
+--
+-- Field names are a holdover from the 'old' revisions table in
+-- MediaWiki 1.4 and earlier: an upgrade will transform that
+-- table into the 'text' table to minimize unnecessary churning
+-- and downtime. If upgrading, the other fields will be left unused.
+--
+CREATE TABLE /*$wgDBprefix*/text (
+ -- Unique text storage key number.
+ -- Note that the 'oldid' parameter used in URLs does *not*
+ -- refer to this number anymore, but to rev_id.
+ --
+ -- revision.rev_text_id is a key to this column
+ old_id int(8) unsigned NOT NULL auto_increment,
+
+ -- Depending on the contents of the old_flags field, the text
+ -- may be convenient plain text, or it may be funkily encoded.
+ old_text mediumblob NOT NULL,
+
+ -- Comma-separated list of flags:
+ -- gzip: text is compressed with PHP's gzdeflate() function.
+ -- utf8: text was stored as UTF-8.
+ -- If $wgLegacyEncoding option is on, rows *without* this flag
+ -- will be converted to UTF-8 transparently at load time.
+ -- object: text field contained a serialized PHP object.
+ -- The object either contains multiple versions compressed
+ -- together to achieve a better compression ratio, or it refers
+ -- to another row where the text can be found.
+ old_flags tinyblob NOT NULL,
+
+ PRIMARY KEY old_id (old_id)
+
+) TYPE=InnoDB;
+
+--
+-- Holding area for deleted articles, which may be viewed
+-- or restored by admins through the Special:Undelete interface.
+-- The fields generally correspond to the page, revision, and text
+-- fields, with several caveats.
+--
+CREATE TABLE /*$wgDBprefix*/archive (
+ ar_namespace int NOT NULL default '0',
+ ar_title varchar(255) binary NOT NULL default '',
+
+ -- Newly deleted pages will not store text in this table,
+ -- but will reference the separately existing text rows.
+ -- This field is retained for backwards compatibility,
+ -- so old archived pages will remain accessible after
+ -- upgrading from 1.4 to 1.5.
+ -- Text may be gzipped or otherwise funky.
+ ar_text mediumblob NOT NULL,
+
+ -- Basic revision stuff...
+ ar_comment tinyblob NOT NULL,
+ ar_user int(5) unsigned NOT NULL default '0',
+ ar_user_text varchar(255) binary NOT NULL,
+ ar_timestamp char(14) binary NOT NULL default '',
+ ar_minor_edit tinyint(1) NOT NULL default '0',
+
+ -- See ar_text note.
+ ar_flags tinyblob NOT NULL,
+
+ -- When revisions are deleted, their unique rev_id is stored
+ -- here so it can be retained after undeletion. This is necessary
+ -- to retain permalinks to given revisions after accidental delete
+ -- cycles or messy operations like history merges.
+ --
+ -- Old entries from 1.4 will be NULL here, and a new rev_id will
+ -- be created on undeletion for those revisions.
+ ar_rev_id int(8) unsigned,
+
+ -- For newly deleted revisions, this is the text.old_id key to the
+ -- actual stored text. To avoid breaking the block-compression scheme
+ -- and otherwise making storage changes harder, the actual text is
+ -- *not* deleted from the text table, merely hidden by removal of the
+ -- page and revision entries.
+ --
+ -- Old entries deleted under 1.2-1.4 will have NULL here, and their
+ -- ar_text and ar_flags fields will be used to create a new text
+ -- row upon undeletion.
+ ar_text_id int(8) unsigned,
+
+ KEY name_title_timestamp (ar_namespace,ar_title,ar_timestamp)
+
+) TYPE=InnoDB;
+
+
+--
+-- Track page-to-page hyperlinks within the wiki.
+--
+CREATE TABLE /*$wgDBprefix*/pagelinks (
+ -- Key to the page_id of the page containing the link.
+ pl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ pl_namespace int NOT NULL default '0',
+ pl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY pl_from (pl_from,pl_namespace,pl_title),
+ KEY (pl_namespace,pl_title,pl_from)
+
+) TYPE=InnoDB;
+
+
+--
+-- Track template inclusions.
+--
+CREATE TABLE /*$wgDBprefix*/templatelinks (
+ -- Key to the page_id of the page containing the link.
+ tl_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ tl_namespace int NOT NULL default '0',
+ tl_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY tl_from (tl_from,tl_namespace,tl_title),
+ KEY (tl_namespace,tl_title,tl_from)
+
+) TYPE=InnoDB;
+
+--
+-- Track links to images *used inline*
+-- We don't distinguish live from broken links here, so
+-- they do not need to be changed on upload/removal.
+--
+CREATE TABLE /*$wgDBprefix*/imagelinks (
+ -- Key to page_id of the page containing the image / media link.
+ il_from int(8) unsigned NOT NULL default '0',
+
+ -- Filename of target image.
+ -- This is also the page_title of the file's description page;
+ -- all such pages are in namespace 6 (NS_IMAGE).
+ il_to varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY il_from (il_from,il_to),
+ KEY (il_to,il_from)
+
+) TYPE=InnoDB;
+
+--
+-- Track category inclusions *used inline*
+-- This tracks a single level of category membership
+-- (folksonomic tagging, really).
+--
+CREATE TABLE /*$wgDBprefix*/categorylinks (
+ -- Key to page_id of the page defined as a category member.
+ cl_from int(8) unsigned NOT NULL default '0',
+
+ -- Name of the category.
+ -- This is also the page_title of the category's description page;
+ -- all such pages are in namespace 14 (NS_CATEGORY).
+ cl_to varchar(255) binary NOT NULL default '',
+
+ -- The title of the linking page, or an optional override
+ -- to determine sort order. Sorting is by binary order, which
+ -- isn't always ideal, but collations seem to be an exciting
+ -- and dangerous new world in MySQL... The sortkey is updated
+ -- if no override exists and cl_from is renamed.
+ --
+ -- For MySQL 4.1+ with charset set to utf8, the sort key *index*
+ -- needs cut to be smaller than 1024 bytes (at 3 bytes per char).
+ -- To sort properly on the shorter key, this field needs to be
+ -- the same shortness.
+ cl_sortkey varchar(86) binary NOT NULL default '',
+
+ -- This isn't really used at present. Provided for an optional
+ -- sorting method by approximate addition time.
+ cl_timestamp timestamp NOT NULL,
+
+ UNIQUE KEY cl_from (cl_from,cl_to),
+
+ -- We always sort within a given category...
+ KEY cl_sortkey (cl_to,cl_sortkey),
+
+ -- Not really used?
+ KEY cl_timestamp (cl_to,cl_timestamp)
+
+) TYPE=InnoDB;
+
+--
+-- Track links to external URLs
+--
+CREATE TABLE /*$wgDBprefix*/externallinks (
+ -- page_id of the referring page
+ el_from int(8) unsigned NOT NULL default '0',
+
+ -- The URL
+ el_to blob NOT NULL,
+
+ -- In the case of HTTP URLs, this is the URL with any username or password
+ -- removed, and with the labels in the hostname reversed and converted to
+ -- lower case. An extra dot is added to allow for matching of either
+ -- example.com or *.example.com in a single scan.
+ -- Example:
+ -- http://user:password@sub.example.com/page.html
+ -- becomes
+ -- http://com.example.sub./page.html
+ -- which allows for fast searching for all pages under example.com with the
+ -- clause:
+ -- WHERE el_index LIKE 'http://com.example.%'
+ el_index blob NOT NULL,
+
+ KEY (el_from, el_to(40)),
+ KEY (el_to(60), el_from),
+ KEY (el_index(60))
+) TYPE=InnoDB;
+
+--
+-- Track interlanguage links
+--
+CREATE TABLE /*$wgDBprefix*/langlinks (
+ -- page_id of the referring page
+ ll_from int(8) unsigned NOT NULL default '0',
+
+ -- Language code of the target
+ ll_lang varchar(10) binary NOT NULL default '',
+
+ -- Title of the target, including namespace
+ ll_title varchar(255) binary NOT NULL default '',
+
+ UNIQUE KEY (ll_from, ll_lang),
+ KEY (ll_lang, ll_title)
+) TYPE=InnoDB;
+
+--
+-- Contains a single row with some aggregate info
+-- on the state of the site.
+--
+CREATE TABLE /*$wgDBprefix*/site_stats (
+ -- The single row should contain 1 here.
+ ss_row_id int(8) unsigned NOT NULL,
+
+ -- Total number of page views, if hit counters are enabled.
+ ss_total_views bigint(20) unsigned default '0',
+
+ -- Total number of edits performed.
+ ss_total_edits bigint(20) unsigned default '0',
+
+ -- An approximate count of pages matching the following criteria:
+ -- * in namespace 0
+ -- * not a redirect
+ -- * contains the text '[['
+ -- See Article::isCountable() in includes/Article.php
+ ss_good_articles bigint(20) unsigned default '0',
+
+ -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster
+ ss_total_pages bigint(20) default '-1',
+
+ -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
+ ss_users bigint(20) default '-1',
+
+ -- Deprecated, no longer updated as of 1.5
+ ss_admins int(10) default '-1',
+
+ -- Number of images, equivalent to SELECT COUNT(*) FROM image
+ ss_images int(10) default '0',
+
+ UNIQUE KEY ss_row_id (ss_row_id)
+
+) TYPE=InnoDB;
+
+--
+-- Stores an ID for every time any article is visited;
+-- depending on $wgHitcounterUpdateFreq, it is
+-- periodically cleared and the page_counter column
+-- in the page table updated for the all articles
+-- that have been visited.)
+--
+CREATE TABLE /*$wgDBprefix*/hitcounter (
+ hc_id int unsigned NOT NULL
+) TYPE=HEAP MAX_ROWS=25000;
+
+
+--
+-- The internet is full of jerks, alas. Sometimes it's handy
+-- to block a vandal or troll account.
+--
+CREATE TABLE /*$wgDBprefix*/ipblocks (
+ -- Primary key, introduced for privacy.
+ ipb_id int(8) NOT NULL auto_increment,
+
+ -- Blocked IP address in dotted-quad form or user name.
+ ipb_address tinyblob NOT NULL,
+
+ -- Blocked user ID or 0 for IP blocks.
+ ipb_user int(8) unsigned NOT NULL default '0',
+
+ -- User ID who made the block.
+ ipb_by int(8) unsigned NOT NULL default '0',
+
+ -- Text comment made by blocker.
+ ipb_reason tinyblob NOT NULL,
+
+ -- Creation (or refresh) date in standard YMDHMS form.
+ -- IP blocks expire automatically.
+ ipb_timestamp char(14) binary NOT NULL default '',
+
+ -- Indicates that the IP address was banned because a banned
+ -- user accessed a page through it. If this is 1, ipb_address
+ -- will be hidden, and the block identified by block ID number.
+ ipb_auto bool NOT NULL default 0,
+
+ -- If set to 1, block applies only to logged-out users
+ ipb_anon_only bool NOT NULL default 0,
+
+ -- Block prevents account creation from matching IP addresses
+ ipb_create_account bool NOT NULL default 1,
+
+ -- Block triggers autoblocks
+ ipb_enable_autoblock bool NOT NULL default '1',
+
+ -- Time at which the block will expire.
+ ipb_expiry char(14) binary NOT NULL default '',
+
+ -- Start and end of an address range, in hexadecimal
+ -- Size chosen to allow IPv6
+ ipb_range_start tinyblob NOT NULL,
+ ipb_range_end tinyblob NOT NULL,
+
+ PRIMARY KEY ipb_id (ipb_id),
+
+ -- Unique index to support "user already blocked" messages
+ -- Any new options which prevent collisions should be included
+ UNIQUE INDEX ipb_address (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only),
+
+ INDEX ipb_user (ipb_user),
+ INDEX ipb_range (ipb_range_start(8), ipb_range_end(8)),
+ INDEX ipb_timestamp (ipb_timestamp),
+ INDEX ipb_expiry (ipb_expiry)
+
+) TYPE=InnoDB;
+
+
+--
+-- Uploaded images and other files.
+--
+CREATE TABLE /*$wgDBprefix*/image (
+ -- Filename.
+ -- This is also the title of the associated description page,
+ -- which will be in namespace 6 (NS_IMAGE).
+ img_name varchar(255) binary NOT NULL default '',
+
+ -- File size in bytes.
+ img_size int(8) unsigned NOT NULL default '0',
+
+ -- For images, size in pixels.
+ img_width int(5) NOT NULL default '0',
+ img_height int(5) NOT NULL default '0',
+
+ -- Extracted EXIF metadata stored as a serialized PHP array.
+ img_metadata mediumblob NOT NULL,
+
+ -- For images, bits per pixel if known.
+ img_bits int(3) NOT NULL default '0',
+
+ -- Media type as defined by the MEDIATYPE_xxx constants
+ img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+
+ -- major part of a MIME media type as defined by IANA
+ -- see http://www.iana.org/assignments/media-types/
+ img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown",
+
+ -- minor part of a MIME media type as defined by IANA
+ -- the minor parts are not required to adher to any standard
+ -- but should be consistent throughout the database
+ -- see http://www.iana.org/assignments/media-types/
+ img_minor_mime varchar(32) NOT NULL default "unknown",
+
+ -- Description field as entered by the uploader.
+ -- This is displayed in image upload history and logs.
+ img_description tinyblob NOT NULL,
+
+ -- user_id and user_name of uploader.
+ img_user int(5) unsigned NOT NULL default '0',
+ img_user_text varchar(255) binary NOT NULL,
+
+ -- Time of the upload.
+ img_timestamp char(14) binary NOT NULL default '',
+
+ PRIMARY KEY img_name (img_name),
+
+ -- Used by Special:Imagelist for sort-by-size
+ INDEX img_size (img_size),
+
+ -- Used by Special:Newimages and Special:Imagelist
+ INDEX img_timestamp (img_timestamp)
+
+) TYPE=InnoDB;
+
+--
+-- Previous revisions of uploaded files.
+-- Awkwardly, image rows have to be moved into
+-- this table at re-upload time.
+--
+CREATE TABLE /*$wgDBprefix*/oldimage (
+ -- Base filename: key to image.img_name
+ oi_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of the archived file.
+ -- This is generally a timestamp and '!' prepended to the base name.
+ oi_archive_name varchar(255) binary NOT NULL default '',
+
+ -- Other fields as in image...
+ oi_size int(8) unsigned NOT NULL default 0,
+ oi_width int(5) NOT NULL default 0,
+ oi_height int(5) NOT NULL default 0,
+ oi_bits int(3) NOT NULL default 0,
+ oi_description tinyblob NOT NULL,
+ oi_user int(5) unsigned NOT NULL default '0',
+ oi_user_text varchar(255) binary NOT NULL,
+ oi_timestamp char(14) binary NOT NULL default '',
+
+ INDEX oi_name (oi_name(10))
+
+) TYPE=InnoDB;
+
+--
+-- Record of deleted file data
+--
+CREATE TABLE /*$wgDBprefix*/filearchive (
+ -- Unique row id
+ fa_id int NOT NULL auto_increment,
+
+ -- Original base filename; key to image.img_name, page.page_title, etc
+ fa_name varchar(255) binary NOT NULL default '',
+
+ -- Filename of archived file, if an old revision
+ fa_archive_name varchar(255) binary default '',
+
+ -- Which storage bin (directory tree or object store) the file data
+ -- is stored in. Should be 'deleted' for files that have been deleted;
+ -- any other bin is not yet in use.
+ fa_storage_group varchar(16),
+
+ -- SHA-1 of the file contents plus extension, used as a key for storage.
+ -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg
+ --
+ -- If NULL, the file was missing at deletion time or has been purged
+ -- from the archival storage.
+ fa_storage_key varchar(64) binary default '',
+
+ -- Deletion information, if this file is deleted.
+ fa_deleted_user int,
+ fa_deleted_timestamp char(14) binary default '',
+ fa_deleted_reason text,
+
+ -- Duped fields from image
+ fa_size int(8) unsigned default '0',
+ fa_width int(5) default '0',
+ fa_height int(5) default '0',
+ fa_metadata mediumblob,
+ fa_bits int(3) default '0',
+ fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+ fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") default "unknown",
+ fa_minor_mime varchar(32) default "unknown",
+ fa_description tinyblob,
+ fa_user int(5) unsigned default '0',
+ fa_user_text varchar(255) binary,
+ fa_timestamp char(14) binary default '',
+
+ PRIMARY KEY (fa_id),
+ INDEX (fa_name, fa_timestamp), -- pick out by image name
+ INDEX (fa_storage_group, fa_storage_key), -- pick out dupe files
+ INDEX (fa_deleted_timestamp), -- sort by deletion time
+ INDEX (fa_deleted_user) -- sort by deleter
+
+) TYPE=InnoDB;
+
+--
+-- Primarily a summary table for Special:Recentchanges,
+-- this table contains some additional info on edits from
+-- the last few days, see Article::editUpdates()
+--
+CREATE TABLE /*$wgDBprefix*/recentchanges (
+ rc_id int(8) NOT NULL auto_increment,
+ rc_timestamp varchar(14) binary NOT NULL default '',
+ rc_cur_time varchar(14) binary NOT NULL default '',
+
+ -- As in revision
+ rc_user int(10) unsigned NOT NULL default '0',
+ rc_user_text varchar(255) binary NOT NULL,
+
+ -- When pages are renamed, their RC entries do _not_ change.
+ rc_namespace int NOT NULL default '0',
+ rc_title varchar(255) binary NOT NULL default '',
+
+ -- as in revision...
+ rc_comment varchar(255) binary NOT NULL default '',
+ rc_minor tinyint(3) unsigned NOT NULL default '0',
+
+ -- Edits by user accounts with the 'bot' rights key are
+ -- marked with a 1 here, and will be hidden from the
+ -- default view.
+ rc_bot tinyint(3) unsigned NOT NULL default '0',
+
+ rc_new tinyint(3) unsigned NOT NULL default '0',
+
+ -- Key to page_id (was cur_id prior to 1.5).
+ -- This will keep links working after moves while
+ -- retaining the at-the-time name in the changes list.
+ rc_cur_id int(10) unsigned NOT NULL default '0',
+
+ -- rev_id of the given revision
+ rc_this_oldid int(10) unsigned NOT NULL default '0',
+
+ -- rev_id of the prior revision, for generating diff links.
+ rc_last_oldid int(10) unsigned NOT NULL default '0',
+
+ -- These may no longer be used, with the new move log.
+ rc_type tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0',
+ rc_moved_to_title varchar(255) binary NOT NULL default '',
+
+ -- If the Recent Changes Patrol option is enabled,
+ -- users may mark edits as having been reviewed to
+ -- remove a warning flag on the RC list.
+ -- A value of 1 indicates the page has been reviewed.
+ rc_patrolled tinyint(3) unsigned NOT NULL default '0',
+
+ -- Recorded IP address the edit was made from, if the
+ -- $wgPutIPinRC option is enabled.
+ rc_ip char(15) NOT NULL default '',
+
+ -- Text length in characters before
+ -- and after the edit
+ rc_old_len int(10),
+ rc_new_len int(10),
+
+ PRIMARY KEY rc_id (rc_id),
+ INDEX rc_timestamp (rc_timestamp),
+ INDEX rc_namespace_title (rc_namespace, rc_title),
+ INDEX rc_cur_id (rc_cur_id),
+ INDEX new_name_timestamp (rc_new,rc_namespace,rc_timestamp),
+ INDEX rc_ip (rc_ip),
+ INDEX rc_ns_usertext (rc_namespace, rc_user_text),
+ INDEX rc_user_text (rc_user_text, rc_timestamp)
+
+) TYPE=InnoDB;
+
+CREATE TABLE /*$wgDBprefix*/watchlist (
+ -- Key to user.user_id
+ wl_user int(5) unsigned NOT NULL,
+
+ -- Key to page_namespace/page_title
+ -- Note that users may watch pages which do not exist yet,
+ -- or existed in the past but have been deleted.
+ wl_namespace int NOT NULL default '0',
+ wl_title varchar(255) binary NOT NULL default '',
+
+ -- Timestamp when user was last sent a notification e-mail;
+ -- cleared when the user visits the page.
+ wl_notificationtimestamp varchar(14) binary,
+
+ UNIQUE KEY (wl_user, wl_namespace, wl_title),
+ KEY namespace_title (wl_namespace, wl_title)
+
+) TYPE=InnoDB;
+
+
+--
+-- Used by the math module to keep track
+-- of previously-rendered items.
+--
+CREATE TABLE /*$wgDBprefix*/math (
+ -- Binary MD5 hash of the latex fragment, used as an identifier key.
+ math_inputhash varchar(16) NOT NULL,
+
+ -- Not sure what this is, exactly...
+ math_outputhash varchar(16) NOT NULL,
+
+ -- texvc reports how well it thinks the HTML conversion worked;
+ -- if it's a low level the PNG rendering may be preferred.
+ math_html_conservativeness tinyint(1) NOT NULL,
+
+ -- HTML output from texvc, if any
+ math_html text,
+
+ -- MathML output from texvc, if any
+ math_mathml text,
+
+ UNIQUE KEY math_inputhash (math_inputhash)
+
+) TYPE=InnoDB;
+
+--
+-- When using the default MySQL search backend, page titles
+-- and text are munged to strip markup, do Unicode case folding,
+-- and prepare the result for MySQL's fulltext index.
+--
+-- This table must be MyISAM; InnoDB does not support the needed
+-- fulltext index.
+--
+CREATE TABLE /*$wgDBprefix*/searchindex (
+ -- Key to page_id
+ si_page int(8) unsigned NOT NULL,
+
+ -- Munged version of title
+ si_title varchar(255) NOT NULL default '',
+
+ -- Munged version of body text
+ si_text mediumtext NOT NULL,
+
+ UNIQUE KEY (si_page),
+ FULLTEXT si_title (si_title),
+ FULLTEXT si_text (si_text)
+
+) TYPE=MyISAM;
+
+--
+-- Recognized interwiki link prefixes
+--
+CREATE TABLE /*$wgDBprefix*/interwiki (
+ -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
+ iw_prefix char(32) NOT NULL,
+
+ -- The URL of the wiki, with "$1" as a placeholder for an article name.
+ -- Any spaces in the name will be transformed to underscores before
+ -- insertion.
+ iw_url char(127) NOT NULL,
+
+ -- A boolean value indicating whether the wiki is in this project
+ -- (used, for example, to detect redirect loops)
+ iw_local bool NOT NULL,
+
+ -- Boolean value indicating whether interwiki transclusions are allowed.
+ iw_trans tinyint(1) NOT NULL default 0,
+
+ UNIQUE KEY iw_prefix (iw_prefix)
+
+) TYPE=InnoDB;
+
+--
+-- Used for caching expensive grouped queries
+--
+CREATE TABLE /*$wgDBprefix*/querycache (
+ -- A key name, generally the base name of of the special page.
+ qc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qc_namespace int NOT NULL default '0',
+ qc_title char(255) binary NOT NULL default '',
+
+ KEY (qc_type,qc_value)
+
+) TYPE=InnoDB;
+
+--
+-- For a few generic cache operations if not using Memcached
+--
+CREATE TABLE /*$wgDBprefix*/objectcache (
+ keyname char(255) binary NOT NULL default '',
+ value mediumblob,
+ exptime datetime,
+ UNIQUE KEY (keyname),
+ KEY (exptime)
+
+) TYPE=InnoDB;
+
+--
+-- Cache of interwiki transclusion
+--
+CREATE TABLE /*$wgDBprefix*/transcache (
+ tc_url varchar(255) NOT NULL,
+ tc_contents text,
+ tc_time int NOT NULL,
+ UNIQUE INDEX tc_url_idx (tc_url)
+) TYPE=InnoDB;
+
+CREATE TABLE /*$wgDBprefix*/logging (
+ -- Symbolic keys for the general log type and the action type
+ -- within the log. The output format will be controlled by the
+ -- action field, but only the type controls categorization.
+ log_type char(10) NOT NULL default '',
+ log_action char(10) NOT NULL default '',
+
+ -- Timestamp. Duh.
+ log_timestamp char(14) NOT NULL default '19700101000000',
+
+ -- The user who performed this action; key to user_id
+ log_user int unsigned NOT NULL default 0,
+
+ -- Key to the page affected. Where a user is the target,
+ -- this will point to the user page.
+ log_namespace int NOT NULL default 0,
+ log_title varchar(255) binary NOT NULL default '',
+
+ -- Freeform text. Interpreted as edit history comments.
+ log_comment varchar(255) NOT NULL default '',
+
+ -- LF separated list of miscellaneous parameters
+ log_params blob NOT NULL,
+
+ KEY type_time (log_type, log_timestamp),
+ KEY user_time (log_user, log_timestamp),
+ KEY page_time (log_namespace, log_title, log_timestamp),
+ KEY times (log_timestamp)
+
+) TYPE=InnoDB;
+
+CREATE TABLE /*$wgDBprefix*/trackbacks (
+ tb_id int auto_increment,
+ tb_page int REFERENCES page(page_id) ON DELETE CASCADE,
+ tb_title varchar(255) NOT NULL,
+ tb_url varchar(255) NOT NULL,
+ tb_ex text,
+ tb_name varchar(255),
+
+ PRIMARY KEY (tb_id),
+ INDEX (tb_page)
+) TYPE=InnoDB;
+
+
+-- Jobs performed by parallel apache threads or a command-line daemon
+CREATE TABLE /*$wgDBprefix*/job (
+ job_id int(9) unsigned NOT NULL auto_increment,
+
+ -- Command name, currently only refreshLinks is defined
+ job_cmd varchar(255) NOT NULL default '',
+
+ -- Namespace and title to act on
+ -- Should be 0 and '' if the command does not operate on a title
+ job_namespace int NOT NULL,
+ job_title varchar(255) binary NOT NULL,
+
+ -- Any other parameters to the command
+ -- Presently unused, format undefined
+ job_params blob NOT NULL,
+
+ PRIMARY KEY job_id (job_id),
+ KEY (job_cmd, job_namespace, job_title)
+) TYPE=InnoDB;
+
+
+-- Details of updates to cached special pages
+CREATE TABLE /*$wgDBprefix*/querycache_info (
+
+ -- Special page name
+ -- Corresponds to a qc_type value
+ qci_type varchar(32) NOT NULL default '',
+
+ -- Timestamp of last update
+ qci_timestamp char(14) NOT NULL default '19700101000000',
+
+ UNIQUE KEY ( qci_type )
+
+) TYPE=InnoDB;
+
+-- For each redirect, this table contains exactly one row defining its target
+CREATE TABLE /*$wgDBprefix*/redirect (
+ -- Key to the page_id of the redirect page
+ rd_from int(8) unsigned NOT NULL default '0',
+
+ -- Key to page_namespace/page_title of the target page.
+ -- The target page may or may not exist, and due to renames
+ -- and deletions may refer to different page records as time
+ -- goes by.
+ rd_namespace int NOT NULL default '0',
+ rd_title varchar(255) binary NOT NULL default '',
+
+ PRIMARY KEY rd_from (rd_from),
+ KEY rd_ns_title (rd_namespace,rd_title,rd_from)
+) TYPE=InnoDB;
+
+-- Used for caching expensive grouped queries that need two links (for example double-redirects)
+CREATE TABLE /*$wgDBprefix*/querycachetwo (
+ -- A key name, generally the base name of of the special page.
+ qcc_type char(32) NOT NULL,
+
+ -- Some sort of stored value. Sizes, counts...
+ qcc_value int(5) unsigned NOT NULL default '0',
+
+ -- Target namespace+title
+ qcc_namespace int NOT NULL default '0',
+ qcc_title char(255) binary NOT NULL default '',
+
+ -- Target namespace+title2
+ qcc_namespacetwo int NOT NULL default '0',
+ qcc_titletwo char(255) binary NOT NULL default '',
+
+ KEY qcc_type (qcc_type,qcc_value),
+ KEY qcc_title (qcc_type,qcc_namespace,qcc_title),
+ KEY qcc_titletwo (qcc_type,qcc_namespacetwo,qcc_titletwo)
+
+) TYPE=InnoDB;
+
+-- vim: sw=2 sts=2 et
diff --git a/maintenance/testRunner.sql b/maintenance/testRunner.sql
new file mode 100644
index 000000000000..8591d81df459
--- /dev/null
+++ b/maintenance/testRunner.sql
@@ -0,0 +1,35 @@
+--
+-- Optional tables for parserTests recording mode
+-- With --record option, success data will be saved to these tables,
+-- and comparisons of what's changed from the previous run will be
+-- displayed at the end of each run.
+--
+-- These tables currently require MySQL 5 (or maybe 4.1?) for subselects.
+--
+
+drop table if exists /*$wgDBprefix*/testitem;
+drop table if exists /*$wgDBprefix*/testrun;
+
+create table /*$wgDBprefix*/testrun (
+ tr_id int not null auto_increment,
+
+ tr_date char(14) binary,
+ tr_mw_version blob,
+ tr_php_version blob,
+ tr_db_version blob,
+ tr_uname blob,
+
+ primary key (tr_id)
+) engine=InnoDB;
+
+create table /*$wgDBprefix*/testitem (
+ ti_run int not null,
+ ti_name varchar(255),
+ ti_success bool,
+
+ unique key (ti_run, ti_name),
+ key (ti_run, ti_success),
+
+ foreign key (ti_run) references /*$wgDBprefix*/testrun(tr_id)
+ on delete cascade
+) engine=InnoDB;
diff --git a/maintenance/update.php b/maintenance/update.php
new file mode 100644
index 000000000000..490c3f6370e2
--- /dev/null
+++ b/maintenance/update.php
@@ -0,0 +1,64 @@
+<?php
+require_once 'counter.php';
+/**
+ * Run all updaters.
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+$wgUseMasterForMaintenance = true;
+$options = array( 'quick', 'nopurge' );
+require_once( "commandLine.inc" );
+require_once( "updaters.inc" );
+$wgTitle = Title::newFromText( "MediaWiki database updater" );
+$dbclass = 'Database' . ucfirst( $wgDBtype ) ;
+
+echo( "MediaWiki {$wgVersion} Updater\n\n" );
+
+install_version_checks();
+
+# Do a pre-emptive check to ensure we've got credentials supplied
+# We can't, at this stage, check them, but we can detect their absence,
+# which seems to cause most of the problems people whinge about
+if( !isset( $wgDBadminuser ) || !isset( $wgDBadminpassword ) ) {
+ echo( "No superuser credentials could be found. Please provide the details\n" );
+ echo( "of a user with appropriate permissions to update the database. See\n" );
+ echo( "AdminSettings.sample for more details.\n\n" );
+ exit();
+}
+
+# Attempt to connect to the database as a privileged user
+# This will vomit up an error if there are permissions problems
+$wgDatabase = new $dbclass( $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname, 1 );
+
+if( !$wgDatabase->isOpen() ) {
+ # Appears to have failed
+ echo( "A connection to the database could not be established. Check the\n" );
+ echo( "values of \$wgDBadminuser and \$wgDBadminpassword.\n" );
+ exit();
+}
+
+print "Going to run database updates for ".wfWikiID()."\n";
+print "Depending on the size of your database this may take a while!\n";
+
+if( !isset( $options['quick'] ) ) {
+ print "Abort with control-c in the next five seconds... ";
+
+ for ($i = 6; $i >= 1;) {
+ print_c($i, --$i);
+ sleep(1);
+ }
+ echo "\n";
+}
+
+$shared = isset( $options['doshared'] );
+$purge = !isset( $options['nopurge'] );
+
+do_all_updates( $shared, $purge );
+
+print "Done.\n";
+
+?>
diff --git a/maintenance/updateArticleCount.inc.php b/maintenance/updateArticleCount.inc.php
new file mode 100644
index 000000000000..7eaea7491262
--- /dev/null
+++ b/maintenance/updateArticleCount.inc.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * Support class for the updateArticleCount.php maintenance script
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+class ArticleCounter {
+
+ var $dbr;
+ var $namespaces;
+
+ function ArticleCounter() {
+ global $wgContentNamespaces;
+ $this->namespaces = $wgContentNamespaces;
+ $this->dbr =& wfGetDB( DB_SLAVE );
+ }
+
+ /**
+ * Produce a comma-delimited set of namespaces
+ * Includes paranoia
+ *
+ * @return string
+ */
+ function makeNsSet() {
+ foreach( $this->namespaces as $namespace )
+ $namespaces[] = intval( $namespace );
+ return implode( ', ', $namespaces );
+ }
+
+ /**
+ * Produce SQL for the query
+ *
+ * @return string
+ */
+ function makeSql() {
+ extract( $this->dbr->tableNames( 'page', 'pagelinks' ) );
+ $nsset = $this->makeNsSet();
+ return "SELECT DISTINCT page_namespace,page_title FROM $page,$pagelinks " .
+ "WHERE pl_from=page_id and page_namespace IN ( $nsset ) " .
+ "AND page_is_redirect = 0 AND page_len > 0";
+ }
+
+ /**
+ * Count the number of valid content pages in the wiki
+ *
+ * @return mixed Integer, or false if there's a problem
+ */
+ function count() {
+ $res = $this->dbr->query( $this->makeSql(), __METHOD__ );
+ if( $res ) {
+ $count = $this->dbr->numRows( $res );
+ $this->dbr->freeResult( $res );
+ return $count;
+ } else {
+ # Look out for this when handling the result
+ # - Actually it's unreachable, !$res throws an exception -- TS
+ return false;
+ }
+ }
+
+}
+
+?>
diff --git a/maintenance/updateArticleCount.php b/maintenance/updateArticleCount.php
new file mode 100644
index 000000000000..112274d25531
--- /dev/null
+++ b/maintenance/updateArticleCount.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Maintenance script to provide a better count of the number of articles
+ * and update the site statistics table, if desired
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ * @author Rob Church <robchur@gmail.com>
+ */
+
+$options = array( 'update', 'help' );
+require_once( 'commandLine.inc' );
+require_once( 'updateArticleCount.inc.php' );
+echo( "Update Article Count\n\n" );
+
+if( isset( $options['help'] ) && $options['help'] ) {
+ echo( "Usage: php updateArticleCount.php [--update]\n\n" );
+ echo( "--update : Update site statistics table\n" );
+ exit( 0 );
+}
+
+echo( "Counting articles..." );
+$counter = new ArticleCounter();
+$result = $counter->count();
+
+if( $result !== false ) {
+ echo( "found {$result}.\n" );
+ if( isset( $options['update'] ) && $options['update'] ) {
+ echo( "Updating site statistics table... " );
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'site_stats', array( 'ss_good_articles' => $result ), array( 'ss_row_id' => 1 ), __METHOD__ );
+ echo( "done.\n" );
+ } else {
+ echo( "To update the site statistics table, run the script with the --update option.\n" );
+ }
+} else {
+ echo( "failed.\n" );
+}
+echo( "\n" );
+
+?> \ No newline at end of file
diff --git a/maintenance/updateSearchIndex.inc b/maintenance/updateSearchIndex.inc
new file mode 100644
index 000000000000..ed01575c32b4
--- /dev/null
+++ b/maintenance/updateSearchIndex.inc
@@ -0,0 +1,115 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+function updateSearchIndex( $start, $end, $maxLockTime, $quiet ) {
+ global $wgQuiet;
+ global $wgDisableSearchUpdate;
+
+ $fname = "updateSearchIndex";
+
+ $wgQuiet = $quiet;
+ $wgDisableSearchUpdate = false;
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $recentchanges = $dbw->tableName( 'recentchanges' );
+
+ output( "Updating searchindex between $start and $end\n" );
+
+ # Select entries from recentchanges which are on top and between the specified times
+ $start = $dbw->strencode( $start );
+ $end = $dbw->strencode( $end );
+
+ $page = $dbw->tableName( 'page' );
+ $sql = "SELECT rc_cur_id,rc_type,rc_moved_to_ns,rc_moved_to_title FROM $recentchanges
+ JOIN $page ON rc_cur_id=page_id AND rc_this_oldid=page_latest
+ WHERE rc_timestamp BETWEEN '$start' AND '$end'
+ ";
+ $res = $dbw->query( $sql, $fname );
+
+
+ # Lock searchindex
+ if ( $maxLockTime ) {
+ output( " --- Waiting for lock ---" );
+ lockSearchindex( $dbw );
+ $lockTime = time();
+ output( "\n" );
+ }
+
+ # Loop through the results and do a search update
+ while ( $row = $dbw->fetchObject( $res ) ) {
+ # Allow reads to be processed
+ if ( $maxLockTime && time() > $lockTime + $maxLockTime ) {
+ output( " --- Relocking ---" );
+ relockSearchindex( $dbw );
+ $lockTime = time();
+ output( "\n" );
+ }
+ if ( $row->rc_type == RC_LOG ) {
+ continue;
+ } elseif ( $row->rc_type == RC_MOVE || $row->rc_type == RC_MOVE_OVER_REDIRECT ) {
+ # Rename searchindex entry
+ $titleObj = Title::makeTitle( $row->rc_moved_to_ns, $row->rc_moved_to_title );
+ $title = $titleObj->getPrefixedDBkey();
+ output( "$title..." );
+ $u = new SearchUpdate( $row->rc_cur_id, $title, false );
+ output( "\n" );
+ } else {
+ // Get current revision
+ $rev = Revision::loadFromPageId( $dbw, $row->rc_cur_id );
+ if( $rev ) {
+ $titleObj = $rev->getTitle();
+ $title = $titleObj->getPrefixedDBkey();
+ output( $title );
+ # Update searchindex
+ $u = new SearchUpdate( $row->rc_cur_id, $titleObj->getText(), $rev->getText() );
+ $u->doUpdate();
+ output( "\n" );
+ }
+ }
+ }
+
+ # Unlock searchindex
+ if ( $maxLockTime ) {
+ unlockSearchindex( $dbw );
+ }
+ output( "Done\n" );
+}
+
+function lockSearchindex( &$db ) {
+ $write = array( 'searchindex' );
+ $read = array( 'page', 'revision', 'text', 'interwiki' );
+ $items = array();
+
+ foreach( $write as $table ) {
+ $items[] = $db->tableName( $table ) . ' LOW_PRIORITY WRITE';
+ }
+ foreach( $read as $table ) {
+ $items[] = $db->tableName( $table ) . ' READ';
+ }
+ $sql = "LOCK TABLES " . implode( ',', $items );
+ $db->query( $sql );
+}
+
+function unlockSearchindex( &$db ) {
+ $db->query( "UNLOCK TABLES" );
+}
+
+# Unlock and lock again
+# Since the lock is low-priority, queued reads will be able to complete
+function relockSearchindex( &$db ) {
+ unlockSearchindex( $db );
+ lockSearchindex( $db );
+}
+
+function output( $text ) {
+ global $wgQuiet;
+ if ( !$wgQuiet ) {
+ print $text;
+ }
+}
+
+?>
diff --git a/maintenance/updateSearchIndex.php b/maintenance/updateSearchIndex.php
new file mode 100644
index 000000000000..b03dc00d652a
--- /dev/null
+++ b/maintenance/updateSearchIndex.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Script for periodic off-peak updating of the search index
+ *
+ * Usage: php updateSearchIndex.php [-s START] [-e END] [-p POSFILE] [-l LOCKTIME] [-q]
+ * Where START is the starting timestamp
+ * END is the ending timestamp
+ * POSFILE is a file to load timestamps from and save them to, searchUpdate.pos by default
+ * LOCKTIME is how long the searchindex and cur tables will be locked for
+ * -q means quiet
+ *
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+/** */
+$optionsWithArgs = array( 's', 'e', 'p' );
+
+require_once( 'commandLine.inc' );
+require_once( 'updateSearchIndex.inc' );
+
+if ( isset( $options['p'] ) ) {
+ $posFile = $options['p'];
+} else {
+ $posFile = 'searchUpdate.pos';
+}
+
+if ( isset( $options['e'] ) ) {
+ $end = $options['e'];
+} else {
+ $end = wfTimestampNow();
+}
+
+if ( isset( $options['s'] ) ) {
+ $start = $options['s'];
+} else {
+ $start = @file_get_contents( $posFile );
+ if ( !$start ) {
+ $start = wfTimestamp( TS_MW, time() - 86400 );
+ }
+}
+
+if ( isset( $options['l'] ) ) {
+ $lockTime = $options['l'];
+} else {
+ $lockTime = 20;
+}
+
+$quiet = (bool)(@$options['q']);
+
+updateSearchIndex( $start, $end, $lockTime, $quiet );
+
+$file = fopen( $posFile, 'w' );
+fwrite( $file, $end );
+fclose( $file );
+
+?>
diff --git a/maintenance/updateSpecialPages.php b/maintenance/updateSpecialPages.php
new file mode 100644
index 000000000000..89b5aa94f6fa
--- /dev/null
+++ b/maintenance/updateSpecialPages.php
@@ -0,0 +1,104 @@
+<?php
+
+# Run this script periodically if you have miser mode enabled, to refresh the caches
+$options = array('only','help');
+
+require_once( 'commandLine.inc' );
+
+require_once( 'SpecialPage.php' );
+require_once( 'QueryPage.php' );
+
+if(@$options['help']) {
+ print "usage:updateSpecialPages.php [--help] [--only=page]\n";
+ print " --help : this help message\n";
+ print " --list : list special pages names\n";
+ print " --only=page : only update 'page'. Ex: --only=BrokenRedirects\n";
+ wfDie();
+}
+
+$wgOut->disable();
+$dbw =& wfGetDB( DB_MASTER );
+
+foreach ( $wgQueryPages as $page ) {
+ @list( $class, $special, $limit ) = $page;
+
+ # --list : just show the name of pages
+ if( @$options['list'] ) {
+ print "$special\n";
+ continue;
+ }
+
+ if ( in_array( $special, $wgDisableQueryPageUpdate ) ) {
+ printf("%-30s disabled\n", $special);
+ continue;
+ }
+
+ $specialObj = SpecialPage::getPage( $special );
+ if ( !$specialObj ) {
+ print "No such special page: $special\n";
+ exit;
+ }
+ if ( !class_exists( $class ) ) {
+ $file = $specialObj->getFile();
+ require_once( $file );
+ }
+ $queryPage = new $class;
+
+ if( !(isset($options['only'])) or ($options['only'] == $queryPage->getName()) ) {
+ printf( '%-30s ', $special );
+
+ if ( $queryPage->isExpensive() ) {
+ $t1 = explode( ' ', microtime() );
+ # Do the query
+ $num = $queryPage->recache( $limit === null ? $wgQueryCacheLimit : $limit );
+ $t2 = explode( ' ', microtime() );
+
+ if ( $num === false ) {
+ print "FAILED: database error\n";
+ } else {
+ print "got $num rows in ";
+
+ $elapsed = ($t2[0] - $t1[0]) + ($t2[1] - $t1[1]);
+ $hours = intval( $elapsed / 3600 );
+ $minutes = intval( $elapsed % 3600 / 60 );
+ $seconds = $elapsed - $hours * 3600 - $minutes * 60;
+ if ( $hours ) {
+ print $hours . 'h ';
+ }
+ if ( $minutes ) {
+ print $minutes . 'm ';
+ }
+ printf( "%.2fs\n", $seconds );
+ }
+
+ # Reopen any connections that have closed
+ if ( !$wgLoadBalancer->pingAll()) {
+ print "\n";
+ do {
+ print "Connection failed, reconnecting in 10 seconds...\n";
+ sleep(10);
+ } while ( !$wgLoadBalancer->pingAll() );
+ print "Reconnected\n\n";
+ } else {
+ # Commit the results
+ $dbw->immediateCommit();
+ }
+
+ # Wait for the slave to catch up
+ /*
+ $slaveDB =& wfGetDB( DB_SLAVE, array('QueryPage::recache', 'vslow' ) );
+ while( $slaveDB->getLag() > 600 ) {
+ print "Slave lagged, waiting...\n";
+ sleep(30);
+
+ }
+ */
+ wfWaitForSlaves( 5 );
+
+ } else {
+ print "cheap, skipped\n";
+ }
+ }
+}
+
+?>
diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc
new file mode 100644
index 000000000000..9641d60da2ed
--- /dev/null
+++ b/maintenance/updaters.inc
@@ -0,0 +1,1099 @@
+<?php
+/**
+ * @package MediaWiki
+ * @subpackage Maintenance
+ */
+
+ /** */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ echo "This file is not a valid entry point\n";
+ exit( 1 );
+}
+
+require_once 'convertLinks.inc';
+require_once 'userDupes.inc';
+require_once 'deleteDefaultMessages.php';
+
+$wgRenamedTables = array(
+# from to patch file
+# array( 'group', 'groups', 'patch-rename-group.sql' ),
+);
+
+$wgNewTables = array(
+# table patch file (in maintenance/archives)
+ array( 'hitcounter', 'patch-hitcounter.sql' ),
+ array( 'querycache', 'patch-querycache.sql' ),
+ array( 'objectcache', 'patch-objectcache.sql' ),
+ array( 'categorylinks', 'patch-categorylinks.sql' ),
+ array( 'logging', 'patch-logging.sql' ),
+ array( 'user_newtalk', 'patch-usernewtalk2.sql' ),
+ array( 'transcache', 'patch-transcache.sql' ),
+ array( 'trackbacks', 'patch-trackbacks.sql' ),
+ array( 'externallinks', 'patch-externallinks.sql' ),
+ array( 'job', 'patch-job.sql' ),
+ array( 'langlinks', 'patch-langlinks.sql' ),
+ array( 'querycache_info', 'patch-querycacheinfo.sql' ),
+ array( 'filearchive', 'patch-filearchive.sql' ),
+ array( 'querycachetwo', 'patch-querycachetwo.sql' ),
+);
+
+$wgNewFields = array(
+# table field patch file (in maintenance/archives)
+ array( 'ipblocks', 'ipb_id', 'patch-ipblocks.sql' ),
+ array( 'ipblocks', 'ipb_expiry', 'patch-ipb_expiry.sql' ),
+ array( 'recentchanges', 'rc_type', 'patch-rc_type.sql' ),
+ array( 'recentchanges', 'rc_ip', 'patch-rc_ip.sql' ),
+ array( 'recentchanges', 'rc_id', 'patch-rc_id.sql' ),
+ array( 'recentchanges', 'rc_patrolled', 'patch-rc-patrol.sql' ),
+ array( 'recentchanges', 'rc_old_len', 'patch-rc_len.sql' ),
+ array( 'user', 'user_real_name', 'patch-user-realname.sql' ),
+ array( 'user', 'user_token', 'patch-user_token.sql' ),
+ array( 'user', 'user_email_token', 'patch-user_email_token.sql' ),
+ array( 'user', 'user_registration','patch-user_registration.sql' ),
+ array( 'logging', 'log_params', 'patch-log_params.sql' ),
+ array( 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ),
+ array( 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ),
+ array( 'page', 'page_len', 'patch-page_len.sql' ),
+ array( 'revision', 'rev_deleted', 'patch-rev_deleted.sql' ),
+ array( 'image', 'img_width', 'patch-img_width.sql' ),
+ array( 'image', 'img_metadata', 'patch-img_metadata.sql' ),
+ array( 'image', 'img_media_type', 'patch-img_media_type.sql' ),
+ array( 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ),
+ array( 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ),
+ array( 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ),
+ array( 'site_stats', 'ss_images', 'patch-ss_images.sql' ),
+ array( 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ),
+ array( 'ipblocks', 'ipb_enable_autoblock', 'patch-ipb_optional_autoblock.sql' ),
+ array( 'user', 'user_newpass_time','patch-user_newpass_time.sql' ),
+ array( 'user', 'user_editcount', 'patch-user_editcount.sql' ),
+);
+
+function rename_table( $from, $to, $patch ) {
+ global $wgDatabase;
+ if ( $wgDatabase->tableExists( $from ) ) {
+ if ( $wgDatabase->tableExists( $to ) ) {
+ echo "...can't move table $from to $to, $to already exists.\n";
+ } else {
+ echo "Moving table $from to $to...";
+ dbsource( archive($patch), $wgDatabase );
+ echo "ok\n";
+ }
+ } else {
+ // Source table does not exist
+ // Renames are done before creations, so this is typical for a new installation
+ // Ignore silently
+ }
+}
+
+function add_table( $name, $patch ) {
+ global $wgDatabase;
+ if ( $wgDatabase->tableExists( $name ) ) {
+ echo "...$name table already exists.\n";
+ } else {
+ echo "Creating $name table...";
+ dbsource( archive($patch), $wgDatabase );
+ echo "ok\n";
+ }
+}
+
+function add_field( $table, $field, $patch ) {
+ global $wgDatabase;
+ if ( !$wgDatabase->tableExists( $table ) ) {
+ echo "...$table table does not exist, skipping new field patch\n";
+ } elseif ( $wgDatabase->fieldExists( $table, $field ) ) {
+ echo "...have $field field in $table table.\n";
+ } else {
+ echo "Adding $field field to table $table...";
+ dbsource( archive($patch) , $wgDatabase );
+ echo "ok\n";
+ }
+}
+
+function do_revision_updates() {
+ global $wgSoftwareRevision;
+ if ( $wgSoftwareRevision < 1001 ) {
+ update_passwords();
+ }
+}
+
+function update_passwords() {
+ wfDebugDieBacktrace( "This function needs to be updated or removed.\n" );
+
+ global $wgDatabase;
+ $fname = "Update script: update_passwords()";
+ print "\nIt appears that you need to update the user passwords in your\n" .
+ "database. If you have already done this (if you've run this update\n" .
+ "script once before, for example), doing so again will make all your\n" .
+ "user accounts inaccessible, so be sure you only do this once.\n" .
+ "Update user passwords? (yes/no)";
+
+ $resp = readconsole();
+ if ( ! ( "Y" == $resp{0} || "y" == $resp{0} ) ) { return; }
+
+ $sql = "SELECT user_id,user_password FROM user";
+ $source = $wgDatabase->query( $sql, $fname );
+
+ while ( $row = $wgDatabase->fetchObject( $source ) ) {
+ $id = $row->user_id;
+ $oldpass = $row->user_password;
+ $newpass = md5( "{$id}-{$oldpass}" );
+
+ $sql = "UPDATE user SET user_password='{$newpass}' " .
+ "WHERE user_id={$id}";
+ $wgDatabase->query( $sql, $fname );
+ }
+}
+
+function do_interwiki_update() {
+ # Check that interwiki table exists; if it doesn't source it
+ global $wgDatabase, $IP;
+ if( $wgDatabase->tableExists( "interwiki" ) ) {
+ echo "...already have interwiki table\n";
+ return true;
+ }
+ echo "Creating interwiki table: ";
+ dbsource( archive("patch-interwiki.sql") );
+ echo "ok\n";
+ echo "Adding default interwiki definitions: ";
+ dbsource( "$IP/maintenance/interwiki.sql" );
+ echo "ok\n";
+}
+
+function do_index_update() {
+ # Check that proper indexes are in place
+ global $wgDatabase;
+ $meta = $wgDatabase->fieldInfo( "recentchanges", "rc_timestamp" );
+ if( $meta->multiple_key == 0 ) {
+ echo "Updating indexes to 20031107: ";
+ dbsource( archive("patch-indexes.sql") );
+ echo "ok\n";
+ return true;
+ }
+ echo "...indexes seem up to 20031107 standards\n";
+ return false;
+}
+
+function do_image_index_update() {
+ global $wgDatabase;
+
+ $meta = $wgDatabase->fieldInfo( "image", "img_major_mime" );
+ if( $meta->multiple_key == 0 ) {
+ echo "Updating indexes to 20050912: ";
+ dbsource( archive("patch-mimesearch-indexes.sql") );
+ echo "ok\n";
+ return true;
+ }
+ echo "...indexes seem up to 20050912 standards\n";
+ return false;
+}
+
+function do_image_name_unique_update() {
+ global $wgDatabase;
+ if( $wgDatabase->indexExists( 'image', 'PRIMARY' ) ) {
+ echo "...image primary key already set.\n";
+ } else {
+ echo "Making img_name the primary key... ";
+ dbsource( archive("patch-image_name_primary.sql"), $wgDatabase );
+ echo "ok\n";
+ }
+}
+
+function do_logging_timestamp_index() {
+ global $wgDatabase;
+ if( $wgDatabase->indexExists( 'logging', 'times' ) ) {
+ echo "...timestamp key on logging already exists.\n";
+ } else {
+ echo "Adding timestamp key on logging table... ";
+ dbsource( archive("patch-logging-times-index.sql"), $wgDatabase );
+ echo "ok\n";
+ }
+}
+
+
+function do_watchlist_update() {
+ global $wgDatabase;
+ $fname = 'do_watchlist_update';
+ if( $wgDatabase->fieldExists( 'watchlist', 'wl_notificationtimestamp' ) ) {
+ echo "The watchlist table is already set up for email notification.\n";
+ } else {
+ echo "Adding wl_notificationtimestamp field for email notification management.";
+ /* ALTER TABLE watchlist ADD (wl_notificationtimestamp varchar(14) binary NOT NULL default '0'); */
+ dbsource( archive( 'patch-email-notification.sql' ), $wgDatabase );
+ echo "ok\n";
+ }
+ # Check if we need to add talk page rows to the watchlist
+ $talk = $wgDatabase->selectField( 'watchlist', 'count(*)', 'wl_namespace & 1', $fname );
+ $nontalk = $wgDatabase->selectField( 'watchlist', 'count(*)', 'NOT (wl_namespace & 1)', $fname );
+ if ( $talk != $nontalk ) {
+ echo "Adding missing watchlist talk page rows... ";
+ flush();
+
+ $wgDatabase->insertSelect( 'watchlist', 'watchlist',
+ array(
+ 'wl_user' => 'wl_user',
+ 'wl_namespace' => 'wl_namespace | 1',
+ 'wl_title' => 'wl_title',
+ 'wl_notificationtimestamp' => 'wl_notificationtimestamp'
+ ), array( 'NOT (wl_namespace & 1)' ), $fname, 'IGNORE' );
+ echo "ok\n";
+ } else {
+ echo "...watchlist talk page rows already present\n";
+ }
+}
+
+function do_copy_newtalk_to_watchlist() {
+ global $wgDatabase;
+ global $wgCommandLineMode; # this needs to be saved while getID() and getName() are called
+
+ $res = $wgDatabase->safeQuery( 'SELECT user_id, user_ip FROM !',
+ $wgDatabase->tableName( 'user_newtalk' ) );
+ $num_newtalks=$wgDatabase->numRows($res);
+ echo "Now converting ".$num_newtalks." user_newtalk entries to watchlist table entries ... \n";
+
+ $user = new User();
+ for ( $i = 1; $i <= $num_newtalks; $i++ ) {
+ $wluser = $wgDatabase->fetchObject( $res );
+ if ($wluser->user_id == 0) { # anonymous users ... have IP numbers as "names"
+ if ($user->isIP($wluser->user_ip)) { # do only if it really looks like an IP number (double checked)
+ $wgDatabase->replace( 'watchlist',
+ array(array('wl_user','wl_namespace', 'wl_title', 'wl_notificationtimestamp' )),
+ array('wl_user' => 0,
+ 'wl_namespace' => NS_USER_TALK,
+ 'wl_title' => $wluser->user_ip,
+ 'wl_notificationtimestamp' => '19700101000000'
+ ), 'updaters.inc::do_watchlist_update2'
+ );
+ }
+ } else { # normal users ... have user_ids
+ $user->setID($wluser->user_id);
+ $wgDatabase->replace( 'watchlist',
+ array(array('wl_user','wl_namespace', 'wl_title', 'wl_notificationtimestamp' )),
+ array('wl_user' => $user->getID(),
+ 'wl_namespace' => NS_USER_TALK,
+ 'wl_title' => $user->getName(),
+ 'wl_notificationtimestamp' => '19700101000000'
+ ), 'updaters.inc::do_watchlist_update3'
+ );
+ }
+ }
+ echo "Done.\n";
+}
+
+
+function do_user_update() {
+ global $wgDatabase;
+ if( $wgDatabase->fieldExists( 'user', 'user_emailauthenticationtimestamp' ) ) {
+ echo "User table contains old email authentication field. Dropping... ";
+ dbsource( archive( 'patch-email-authentication.sql' ), $wgDatabase );
+ echo "ok\n";
+ } else {
+ echo "...user table does not contain old email authentication field.\n";
+ }
+}
+
+/**
+ * 1.4 betas were missing the 'binary' marker from logging.log_title,
+ * which causes a collation mismatch error on joins in MySQL 4.1.
+ */
+function do_logging_encoding() {
+ global $wgDatabase, $wgDBtype;
+ if ($wgDBtype != 'mysql')
+ return;
+ $logging = $wgDatabase->tableName( 'logging' );
+ $res = $wgDatabase->query( "SELECT log_title FROM $logging LIMIT 0" );
+ $flags = explode( ' ', mysql_field_flags( $res, 0 ) );
+ $wgDatabase->freeResult( $res );
+
+ if( in_array( 'binary', $flags ) ) {
+ echo "Logging table has correct title encoding.\n";
+ } else {
+ echo "Fixing title encoding on logging table... ";
+ dbsource( archive( 'patch-logging-title.sql' ), $wgDatabase );
+ echo "ok\n";
+ }
+}
+
+function do_schema_restructuring() {
+ global $wgDatabase;
+ $fname="do_schema_restructuring";
+ if ( $wgDatabase->tableExists( 'page' ) ) {
+ echo "...page table already exists.\n";
+ } else {
+ echo "...converting from cur/old to page/revision/text DB structure.\n"; flush();
+ echo wfTimestamp();
+ echo "......checking for duplicate entries.\n"; flush();
+
+ extract( $wgDatabase->tableNames( 'cur', 'old', 'page', 'revision', 'text' ) );
+
+ $rows = $wgDatabase->query( "SELECT cur_title, cur_namespace, COUNT(cur_namespace) AS c
+ FROM $cur GROUP BY cur_title, cur_namespace HAVING c>1", $fname );
+
+ if ( $wgDatabase->numRows( $rows ) > 0 ) {
+ echo wfTimestamp();
+ echo "......<b>Found duplicate entries</b>\n";
+ echo ( sprintf( "<b> %-60s %3s %5s</b>\n", 'Title', 'NS', 'Count' ) );
+ while ( $row = $wgDatabase->fetchObject( $rows ) ) {
+ if ( ! isset( $duplicate[$row->cur_namespace] ) ) {
+ $duplicate[$row->cur_namespace] = array();
+ }
+ $duplicate[$row->cur_namespace][] = $row->cur_title;
+ echo ( sprintf( " %-60s %3s %5s\n", $row->cur_title, $row->cur_namespace, $row->c ) );
+ }
+ $sql = "SELECT cur_title, cur_namespace, cur_id, cur_timestamp FROM $cur WHERE ";
+ $firstCond = true;
+ foreach ( $duplicate as $ns => $titles ) {
+ if ( $firstCond ) {
+ $firstCond = false;
+ } else {
+ $sql .= ' OR ';
+ }
+ $sql .= "( cur_namespace = {$ns} AND cur_title in (";
+ $first = true;
+ foreach ( $titles as $t ) {
+ if ( $first ) {
+ $sql .= $wgDatabase->addQuotes( $t );
+ $first = false;
+ } else {
+ $sql .= ', ' . $wgDatabase->addQuotes( $t );
+ }
+ }
+ $sql .= ") ) \n";
+ }
+ # By sorting descending, the most recent entry will be the first in the list.
+ # All following entries will be deleted by the next while-loop.
+ $sql .= 'ORDER BY cur_namespace, cur_title, cur_timestamp DESC';
+
+ $rows = $wgDatabase->query( $sql, $fname );
+
+ $prev_title = $prev_namespace = false;
+ $deleteId = array();
+
+ while ( $row = $wgDatabase->fetchObject( $rows ) ) {
+ if ( $prev_title == $row->cur_title && $prev_namespace == $row->cur_namespace ) {
+ $deleteId[] = $row->cur_id;
+ }
+ $prev_title = $row->cur_title;
+ $prev_namespace = $row->cur_namespace;
+ }
+ $sql = "DELETE FROM $cur WHERE cur_id IN ( " . join( ',', $deleteId ) . ')';
+ $rows = $wgDatabase->query( $sql, $fname );
+ echo wfTimestamp();
+ echo "......<b>Deleted</b> ".$wgDatabase->affectedRows()." records.\n";
+ }
+
+
+ echo wfTimestamp();
+ echo "......Creating tables.\n";
+ $wgDatabase->query("CREATE TABLE $page (
+ page_id int(8) unsigned NOT NULL auto_increment,
+ page_namespace int NOT NULL,
+ page_title varchar(255) binary NOT NULL,
+ page_restrictions tinyblob NOT NULL,
+ page_counter bigint(20) unsigned NOT NULL default '0',
+ page_is_redirect tinyint(1) unsigned NOT NULL default '0',
+ page_is_new tinyint(1) unsigned NOT NULL default '0',
+ page_random real unsigned NOT NULL,
+ page_touched char(14) binary NOT NULL default '',
+ page_latest int(8) unsigned NOT NULL,
+ page_len int(8) unsigned NOT NULL,
+
+ PRIMARY KEY page_id (page_id),
+ UNIQUE INDEX name_title (page_namespace,page_title),
+ INDEX (page_random),
+ INDEX (page_len)
+ ) TYPE=InnoDB", $fname );
+ $wgDatabase->query("CREATE TABLE $revision (
+ rev_id int(8) unsigned NOT NULL auto_increment,
+ rev_page int(8) unsigned NOT NULL,
+ rev_comment tinyblob NOT NULL,
+ rev_user int(5) unsigned NOT NULL default '0',
+ rev_user_text varchar(255) binary NOT NULL default '',
+ rev_timestamp char(14) binary NOT NULL default '',
+ rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
+ rev_deleted tinyint(1) 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)
+ ) TYPE=InnoDB", $fname );
+
+ echo wfTimestamp();
+ echo "......Locking tables.\n";
+ $wgDatabase->query( "LOCK TABLES $page WRITE, $revision WRITE, $old WRITE, $cur WRITE", $fname );
+
+ $maxold = intval( $wgDatabase->selectField( 'old', 'max(old_id)', '', $fname ) );
+ echo wfTimestamp();
+ echo "......maxold is {$maxold}\n";
+
+ echo wfTimestamp();
+ global $wgLegacySchemaConversion;
+ if( $wgLegacySchemaConversion ) {
+ // Create HistoryBlobCurStub entries.
+ // Text will be pulled from the leftover 'cur' table at runtime.
+ echo "......Moving metadata from cur; using blob references to text in cur table.\n";
+ $cur_text = "concat('O:18:\"historyblobcurstub\":1:{s:6:\"mCurId\";i:',cur_id,';}')";
+ $cur_flags = "'object'";
+ } else {
+ // Copy all cur text in immediately: this may take longer but avoids
+ // having to keep an extra table around.
+ echo "......Moving text from cur.\n";
+ $cur_text = 'cur_text';
+ $cur_flags = "''";
+ }
+ $wgDatabase->query( "INSERT INTO $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, $cur_flags
+ FROM $cur", $fname );
+
+ echo wfTimestamp();
+ echo "......Setting up revision table.\n";
+ $wgDatabase->query( "INSERT INTO $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 $old,$cur WHERE old_namespace=cur_namespace AND old_title=cur_title", $fname );
+
+ echo wfTimestamp();
+ echo "......Setting up page table.\n";
+ $wgDatabase->query( "INSERT INTO $page (page_id, page_namespace, page_title, page_restrictions, page_counter,
+ page_is_redirect, page_is_new, page_random, page_touched, page_latest, page_len)
+ SELECT cur_id, cur_namespace, cur_title, cur_restrictions, cur_counter, cur_is_redirect, cur_is_new,
+ cur_random, cur_touched, rev_id, LENGTH(cur_text)
+ FROM $cur,$revision
+ WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}", $fname );
+
+ echo wfTimestamp();
+ echo "......Unlocking tables.\n";
+ $wgDatabase->query( "UNLOCK TABLES", $fname );
+
+ echo wfTimestamp();
+ echo "......Renaming old.\n";
+ $wgDatabase->query( "ALTER TABLE $old RENAME TO $text", $fname );
+
+ echo wfTimestamp();
+ echo "...done.\n";
+ }
+}
+
+function do_inverse_timestamp() {
+ global $wgDatabase;
+ $fname="do_schema_restructuring";
+ if( $wgDatabase->fieldExists( 'revision', 'inverse_timestamp' ) ) {
+ echo "Removing revision.inverse_timestamp and fixing indexes... ";
+ dbsource( archive( 'patch-inverse_timestamp.sql' ), $wgDatabase );
+ echo "ok\n";
+ } else {
+ echo "revision timestamp indexes already up to 2005-03-13\n";
+ }
+}
+
+function do_text_id() {
+ global $wgDatabase;
+ if( $wgDatabase->fieldExists( 'revision', 'rev_text_id' ) ) {
+ echo "...rev_text_id already in place.\n";
+ } else {
+ echo "Adding rev_text_id field... ";
+ dbsource( archive( 'patch-rev_text_id.sql' ), $wgDatabase );
+ echo "ok\n";
+ }
+}
+
+function do_namespace_size() {
+ $tables = array(
+ 'page' => 'page',
+ 'archive' => 'ar',
+ 'recentchanges' => 'rc',
+ 'watchlist' => 'wl',
+ 'querycache' => 'qc',
+ 'logging' => 'log',
+ );
+ foreach( $tables as $table => $prefix ) {
+ do_namespace_size_on( $table, $prefix );
+ flush();
+ }
+}
+
+function do_namespace_size_on( $table, $prefix ) {
+ global $wgDatabase, $wgDBtype;
+ if ($wgDBtype != 'mysql')
+ return;
+ $field = $prefix . '_namespace';
+
+ $tablename = $wgDatabase->tableName( $table );
+ $result = $wgDatabase->query( "SHOW COLUMNS FROM $tablename LIKE '$field'" );
+ $info = $wgDatabase->fetchObject( $result );
+ $wgDatabase->freeResult( $result );
+
+ if( substr( $info->Type, 0, 3 ) == 'int' ) {
+ echo "...$field is already a full int ($info->Type).\n";
+ } else {
+ echo "Promoting $field from $info->Type to int... ";
+
+ $sql = "ALTER TABLE $tablename MODIFY $field int NOT NULL";
+ $wgDatabase->query( $sql );
+
+ echo "ok\n";
+ }
+}
+
+function do_pagelinks_update() {
+ global $wgDatabase;
+ if( $wgDatabase->tableExists( 'pagelinks' ) ) {
+ echo "...already have pagelinks table.\n";
+ } else {
+ echo "Converting links and brokenlinks tables to pagelinks... ";
+ dbsource( archive( 'patch-pagelinks.sql' ), $wgDatabase );
+ echo "ok\n";
+ flush();
+
+ global $wgCanonicalNamespaceNames;
+ foreach( $wgCanonicalNamespaceNames as $ns => $name ) {
+ if( $ns != 0 ) {
+ do_pagelinks_namespace( $ns );
+ }
+ }
+ }
+}
+
+function do_pagelinks_namespace( $namespace ) {
+ global $wgDatabase, $wgContLang;
+
+ $ns = intval( $namespace );
+ echo "Cleaning up broken links for namespace $ns... ";
+
+ $pagelinks = $wgDatabase->tableName( 'pagelinks' );
+ $name = $wgContLang->getNsText( $ns );
+ $prefix = $wgDatabase->strencode( $name );
+ $likeprefix = str_replace( '_', '\\_', $prefix);
+
+ $sql = "UPDATE $pagelinks
+ SET pl_namespace=$ns,
+ pl_title=TRIM(LEADING '$prefix:' FROM pl_title)
+ WHERE pl_namespace=0
+ AND pl_title LIKE '$likeprefix:%'";
+
+ $wgDatabase->query( $sql, 'do_pagelinks_namespace' );
+ echo "ok\n";
+}
+
+function do_drop_img_type() {
+ global $wgDatabase;
+
+ if( $wgDatabase->fieldExists( 'image', 'img_type' ) ) {
+ echo "Dropping unused img_type field in image table... ";
+ dbsource( archive( 'patch-drop_img_type.sql' ), $wgDatabase );
+ echo "ok\n";
+ } else {
+ echo "No img_type field in image table; Good.\n";
+ }
+}
+
+function do_old_links_update() {
+ global $wgDatabase;
+ if( $wgDatabase->tableExists( 'pagelinks' ) ) {
+ echo "Already have pagelinks; skipping old links table updates.\n";
+ } else {
+ convertLinks(); flush();
+ }
+}
+
+function do_user_unique_update() {
+ global $wgDatabase;
+ $duper = new UserDupes( $wgDatabase );
+ if( $duper->hasUniqueIndex() ) {
+ echo "Already have unique user_name index.\n";
+ } else {
+ if( !$duper->clearDupes() ) {
+ echo "WARNING: This next step will probably fail due to unfixed duplicates...\n";
+ }
+ echo "Adding unique index on user_name... ";
+ dbsource( archive( 'patch-user_nameindex.sql' ), $wgDatabase );
+ echo "ok\n";
+ }
+}
+
+function do_user_groups_update() {
+ $fname = 'do_user_groups_update';
+ global $wgDatabase;
+
+ if( $wgDatabase->tableExists( 'user_groups' ) ) {
+ echo "...user_groups table already exists.\n";
+ return do_user_groups_reformat();
+ }
+
+ echo "Adding user_groups table... ";
+ dbsource( archive( 'patch-user_groups.sql' ), $wgDatabase );
+ echo "ok\n";
+
+ if( !$wgDatabase->tableExists( 'user_rights' ) ) {
+ if( $wgDatabase->fieldExists( 'user', 'user_rights' ) ) {
+ echo "Upgrading from a 1.3 or older database? Breaking out user_rights for conversion...";
+ dbsource( archive( 'patch-user_rights.sql' ), $wgDatabase );
+ echo "ok\n";
+ } else {
+ echo "*** WARNING: couldn't locate user_rights table or field for upgrade.\n";
+ echo "*** You may need to manually configure some sysops by manipulating\n";
+ echo "*** the user_groups table.\n";
+ return;
+ }
+ }
+
+ echo "Converting user_rights table to user_groups... ";
+ $result = $wgDatabase->select( 'user_rights',
+ array( 'ur_user', 'ur_rights' ),
+ array( "ur_rights != ''" ),
+ $fname );
+
+ while( $row = $wgDatabase->fetchObject( $result ) ) {
+ $groups = array_unique(
+ array_map( 'trim',
+ explode( ',', $row->ur_rights ) ) );
+
+ foreach( $groups as $group ) {
+ $wgDatabase->insert( 'user_groups',
+ array(
+ 'ug_user' => $row->ur_user,
+ 'ug_group' => $group ),
+ $fname );
+ }
+ }
+ $wgDatabase->freeResult( $result );
+ echo "ok\n";
+}
+
+function do_user_groups_reformat() {
+ # Check for bogus formats from previous 1.5 alpha code.
+ global $wgDatabase;
+ $info = $wgDatabase->fieldInfo( 'user_groups', 'ug_group' );
+
+ if( $info->type == 'int' ) {
+ $oldug = $wgDatabase->tableName( 'user_groups' );
+ $newug = $wgDatabase->tableName( 'user_groups_bogus' );
+ echo "user_groups is in bogus intermediate format. Renaming to $newug... ";
+ $wgDatabase->query( "ALTER TABLE $oldug RENAME TO $newug" );
+ echo "ok\n";
+
+ echo "Re-adding fresh user_groups table... ";
+ dbsource( archive( 'patch-user_groups.sql' ), $wgDatabase );
+ echo "ok\n";
+
+ echo "***\n";
+ echo "*** WARNING: You will need to manually fix up user permissions in the user_groups\n";
+ echo "*** table. Old 1.5 alpha versions did some pretty funky stuff...\n";
+ echo "***\n";
+ } else {
+ echo "...user_groups is in current format.\n";
+ }
+
+}
+
+function do_watchlist_null() {
+ # Make sure wl_notificationtimestamp can be NULL,
+ # and update old broken items.
+ global $wgDatabase;
+ $info = $wgDatabase->fieldInfo( 'watchlist', 'wl_notificationtimestamp' );
+
+ if( $info->not_null ) {
+ echo "Making wl_notificationtimestamp nullable... ";
+ dbsource( archive( 'patch-watchlist-null.sql' ), $wgDatabase );
+ echo "ok\n";
+ } else {
+ echo "...wl_notificationtimestamp is already nullable.\n";
+ }
+
+}
+
+/**
+ * @bug 3946
+ */
+function do_page_random_update() {
+ global $wgDatabase;
+
+ echo "Setting page_random to a random value on rows where it equals 0...";
+
+ $page = $wgDatabase->tableName( 'page' );
+ $wgDatabase->query( "UPDATE $page SET page_random = RAND() WHERE page_random = 0", 'do_page_random_update' );
+ $rows = $wgDatabase->affectedRows();
+
+ echo "changed $rows rows\n";
+}
+
+function do_templatelinks_update() {
+ global $wgDatabase, $wgLoadBalancer;
+ $fname = 'do_templatelinks_update';
+
+ if ( $wgDatabase->tableExists( 'templatelinks' ) ) {
+ echo "...templatelinks table already exists\n";
+ return;
+ }
+ echo "Creating templatelinks table...\n";
+ dbsource( archive('patch-templatelinks.sql'), $wgDatabase );
+ echo "Populating...\n";
+ if ( isset( $wgLoadBalancer ) && $wgLoadBalancer->getServerCount() > 1 ) {
+ // Slow, replication-friendly update
+ $res = $wgDatabase->select( 'pagelinks', array( 'pl_from', 'pl_namespace', 'pl_title' ),
+ array( 'pl_namespace' => NS_TEMPLATE ), $fname );
+ $count = 0;
+ while ( $row = $wgDatabase->fetchObject( $res ) ) {
+ $count = ($count + 1) % 100;
+ if ( $count == 0 ) {
+ if ( function_exists( 'wfWaitForSlaves' ) ) {
+ wfWaitForSlaves( 10 );
+ } else {
+ sleep( 1 );
+ }
+ }
+ $wgDatabase->insert( 'templatelinks',
+ array(
+ 'tl_from' => $row->pl_from,
+ 'tl_namespace' => $row->pl_namespace,
+ 'tl_title' => $row->pl_title,
+ ), $fname
+ );
+
+ }
+ $wgDatabase->freeResult( $res );
+ } else {
+ // Fast update
+ $wgDatabase->insertSelect( 'templatelinks', 'pagelinks',
+ array(
+ 'tl_from' => 'pl_from',
+ 'tl_namespace' => 'pl_namespace',
+ 'tl_title' => 'pl_title'
+ ), array(
+ 'pl_namespace' => 10
+ ), $fname
+ );
+ }
+ echo "Done. Please run maintenance/refreshLinks.php for a more thorough templatelinks update.\n";
+}
+
+# July 2006
+# Add ( rc_namespace, rc_user_text ) index [R. Church]
+function do_rc_indices_update() {
+ global $wgDatabase;
+ echo( "Checking for additional recent changes indices...\n" );
+ # See if we can find the index we want
+ $info = $wgDatabase->indexInfo( 'recentchanges', 'rc_ns_usertext', __METHOD__ );
+ if( !$info ) {
+ # None, so create
+ echo( "...index on ( rc_namespace, rc_user_text ) not found; creating\n" );
+ dbsource( archive( 'patch-recentchanges-utindex.sql' ) );
+ } else {
+ # Index seems to exist
+ echo( "...index on ( rc_namespace, rc_user_text ) seems to be ok\n" );
+ }
+
+ #Add (rc_user_text, rc_timestamp) index [A. Garrett], November 2006
+ # See if we can find the index we want
+ $info = $wgDatabase->indexInfo( 'recentchanges', 'rc_user_text', __METHOD__ );
+ if( !$info ) {
+ # None, so create
+ echo( "...index on ( rc_user_text, rc_timestamp ) not found; creating\n" );
+ dbsource( archive( 'patch-rc_user_text-index.sql' ) );
+ } else {
+ # Index seems to exist
+ echo( "...index on ( rc_user_text, rc_timestamp ) seems to be ok\n" );
+ }
+}
+
+function index_has_field($table, $index, $field) {
+ global $wgDatabase;
+ echo( "Checking if $table index $index includes field $field...\n" );
+ $info = $wgDatabase->indexInfo( $table, $index, __METHOD__ );
+ if( $info ) {
+ foreach($info as $row) {
+ if($row->Column_name == $field) {
+ echo( "...index $index on table $table seems to be ok\n" );
+ return true;
+ }
+ }
+ }
+ echo( "...index $index on table $table has no field $field; adding\n" );
+ return false;
+}
+
+function do_backlinking_indices_update() {
+ echo( "Checking for backlinking indices...\n" );
+ if (!index_has_field('pagelinks', 'pl_namespace', 'pl_from') ||
+ !index_has_field('templatelinks', 'tl_namespace', 'tl_from') ||
+ !index_has_field('imagelinks', 'il_to', 'il_from'))
+ {
+ dbsource( archive( 'patch-backlinkindexes.sql' ) );
+ }
+}
+
+function purge_cache() {
+ global $wgDatabase;
+ # We can't guarantee that the user will be able to use TRUNCATE,
+ # but we know that DELETE is available to us
+ echo( "Purging caches..." );
+ $wgDatabase->delete( 'objectcache', '*', __METHOD__ );
+ echo( "done.\n" );
+}
+
+function do_all_updates( $shared = false, $purge = true ) {
+ global $wgNewTables, $wgNewFields, $wgRenamedTables, $wgSharedDB, $wgDatabase, $wgDBtype, $IP;
+
+ $doUser = !$wgSharedDB || $doShared;
+
+ if ($wgDBtype === 'postgres') {
+ do_postgres_updates();
+ return;
+ }
+
+ # Rename tables
+ foreach ( $wgRenamedTables as $tableRecord ) {
+ rename_table( $tableRecord[0], $tableRecord[1], $tableRecord[2] );
+ }
+
+ # Add missing tables
+ foreach ( $wgNewTables as $tableRecord ) {
+ add_table( $tableRecord[0], $tableRecord[1] );
+ flush();
+ }
+
+ # Add missing fields
+ foreach ( $wgNewFields as $fieldRecord ) {
+ if ( $fieldRecord[0] != 'user' || $doUser ) {
+ add_field( $fieldRecord[0], $fieldRecord[1], $fieldRecord[2] );
+ }
+ flush();
+ }
+
+ # Do schema updates which require special handling
+ do_interwiki_update(); flush();
+ do_index_update(); flush();
+ do_old_links_update(); flush();
+ do_image_name_unique_update(); flush();
+ do_watchlist_update(); flush();
+ if ( $doUser ) {
+ do_user_update(); flush();
+ }
+###### do_copy_newtalk_to_watchlist(); flush();
+ do_logging_encoding(); flush();
+
+ do_schema_restructuring(); flush();
+ do_inverse_timestamp(); flush();
+ do_text_id(); flush();
+ do_namespace_size(); flush();
+
+ do_pagelinks_update(); flush();
+ do_templatelinks_update(); flush(); // after pagelinks
+
+ do_drop_img_type(); flush();
+
+ if ( $doUser ) {
+ do_user_unique_update(); flush();
+ }
+ do_user_groups_update(); flush();
+
+ do_watchlist_null(); flush();
+
+ //do_image_index_update(); flush();
+
+ do_logging_timestamp_index(); flush();
+
+ do_page_random_update(); flush();
+
+ do_rc_indices_update(); flush();
+
+ add_table( 'redirect', 'patch-redirect.sql' );
+
+ do_backlinking_indices_update(); flush();
+
+ echo "Deleting old default messages..."; flush();
+ deleteDefaultMessages();
+ echo "Done\n"; flush();
+
+ if( $purge ) {
+ purge_cache();
+ flush();
+ }
+}
+
+function archive($name) {
+ global $wgDBtype, $IP;
+ switch ($wgDBtype) {
+ case "oracle":
+ return "$IP/maintenance/oracle/archives/$name";
+ default:
+ return "$IP/maintenance/archives/$name";
+ }
+}
+
+function do_postgres_updates() {
+ global $wgDatabase, $wgVersion, $wgDBmwschema;
+
+ # Just in case their LocalSetings.php does not have this:
+ if ( !isset( $wgDBmwschema ))
+ $wgDBmwschema = 'mediawiki';
+
+ ## Default to the oldest supported version
+ $version = 1.7;
+
+ if ($wgDatabase->tableExists("mediawiki_version")) {
+ $version = "1.8";
+ $sql = "SELECT mw_version FROM mediawiki_version ORDER BY cdate DESC LIMIT 1";
+ $tempversion = pg_fetch_result($wgDatabase->doQuery($sql),0,0);
+ $thisver = array();
+ if (preg_match('/(\d+\.\d+)/', $tempversion, $thisver)) {
+ $version = $thisver[1];
+ }
+ }
+
+ print " Detected version: $version ";
+ $upgrade = '';
+
+ if ($version <= 1.7) {
+ $upgrade = <<<PGEND
+
+-- Type tweaking:
+ALTER TABLE oldimage ALTER oi_size TYPE INTEGER;
+ALTER TABLE oldimage ALTER oi_width TYPE INTEGER;
+ALTER TABLE oldimage ALTER oi_height TYPE INTEGER;
+
+ALTER TABLE image ALTER img_size TYPE INTEGER;
+ALTER TABLE image ALTER img_width TYPE INTEGER;
+ALTER TABLE image ALTER img_height TYPE INTEGER;
+
+-- Constraint tweaking:
+ALTER TABLE recentchanges ALTER rc_cur_id DROP NOT NULL;
+
+-- New columns:
+ALTER TABLE ipblocks ADD ipb_anon_only CHAR NOT NULL DEFAULT '0';
+ALTER TABLE ipblocks ADD ipb_create_account CHAR NOT NULL DEFAULT '1';
+
+-- Index order rearrangements:
+DROP INDEX pagelink_unique;
+CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title);
+
+-- Rename tables
+ALTER TABLE "user" RENAME TO mwuser;
+ALTER TABLE "text" RENAME to pagecontent;
+
+-- New tables:
+CREATE TABLE profiling (
+ pf_count INTEGER NOT NULL DEFAULT 0,
+ pf_time NUMERIC(18,10) NOT NULL DEFAULT 0,
+ pf_name TEXT NOT NULL,
+ pf_server TEXT NULL
+);
+CREATE UNIQUE INDEX pf_name_server ON profiling (pf_name, pf_server);
+
+CREATE TABLE mediawiki_version (
+ type TEXT NOT NULL,
+ mw_version TEXT NOT NULL,
+ notes TEXT NULL,
+
+ pg_version TEXT NULL,
+ pg_dbname TEXT NULL,
+ pg_user TEXT NULL,
+ pg_port TEXT NULL,
+ mw_schema TEXT NULL,
+ ts2_schema TEXT NULL,
+ ctype TEXT NULL,
+
+ sql_version TEXT NULL,
+ sql_date TEXT NULL,
+ cdate TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- Special modifications
+ALTER TABLE archive RENAME to archive2;
+CREATE VIEW archive AS
+SELECT
+ ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text,
+ ar_minor_edit, ar_flags, ar_rev_id, ar_text_id,
+ TO_CHAR(ar_timestamp, 'YYYYMMDDHH24MISS') AS ar_timestamp
+FROM archive2;
+
+CREATE RULE archive_insert AS ON INSERT TO archive
+DO INSTEAD INSERT INTO archive2 VALUES (
+ NEW.ar_namespace, NEW.ar_title, NEW.ar_text, NEW.ar_comment, NEW.ar_user, NEW.ar_user_text,
+ TO_DATE(NEW.ar_timestamp, 'YYYYMMDDHH24MISS'),
+ NEW.ar_minor_edit, NEW.ar_flags, NEW.ar_rev_id, NEW.ar_text_id
+);
+
+CREATE FUNCTION page_deleted() RETURNS TRIGGER LANGUAGE plpgsql AS
+\$mw\$
+BEGIN
+DELETE FROM recentchanges WHERE rc_namespace = OLD.page_namespace AND rc_title = OLD.page_title;
+RETURN NULL;
+END;
+\$mw\$;
+
+CREATE TRIGGER page_deleted AFTER DELETE ON page
+ FOR EACH ROW EXECUTE PROCEDURE page_deleted();
+
+PGEND;
+
+ } ## end version 1.7
+
+ else if ($version <= 1.8) {
+ $upgrade = <<<PGEND
+
+-- Tighten up restrictions on the revision table so we don't lose data:
+ALTER TABLE revision DROP CONSTRAINT revision_rev_user_fkey;
+ALTER TABLE revision ADD CONSTRAINT revision_rev_user_fkey
+ FOREIGN KEY (rev_user) REFERENCES mwuser(user_id) ON DELETE RESTRICT;
+
+-- New columns for better password tracking:
+ALTER TABLE mwuser ADD user_newpass_time TIMESTAMPTZ;
+ALTER TABLE mwuser ADD user_editcount INTEGER;
+
+-- New column for autoblocking problem users
+ALTER TABLE ipblocks ADD ipb_enable_autoblock CHAR NOT NULL DEFAULT '1';
+
+-- Despite it's name, ipb_address does not necessarily contain IP addresses :)
+ALTER TABLE ipblocks ALTER ipb_address TYPE TEXT USING ipb_address::TEXT;
+
+-- New tables:
+CREATE TABLE redirect (
+ rd_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+ rd_namespace SMALLINT NOT NULL,
+ rd_title TEXT NOT NULL
+);
+CREATE INDEX redirect_ns_title ON redirect (rd_namespace,rd_title,rd_from);
+
+CREATE TABLE querycachetwo (
+ qcc_type TEXT NOT NULL,
+ qcc_value SMALLINT NOT NULL DEFAULT 0,
+ qcc_namespace INTEGER NOT NULL DEFAULT 0,
+ qcc_title TEXT NOT NULL DEFAULT '',
+ qcc_namespacetwo INTEGER NOT NULL DEFAULT 0,
+ qcc_titletwo TEXT NOT NULL DEFAULT ''
+);
+CREATE INDEX querycachetwo_type_value ON querycachetwo (qcc_type, qcc_value);
+CREATE INDEX querycachetwo_title ON querycachetwo (qcc_type,qcc_namespace,qcc_title);
+CREATE INDEX querycachetwo_titletwo ON querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
+
+-- New columns for fancy recentchanges display
+ALTER TABLE recentchanges ADD rc_old_len INT;
+ALTER TABLE recentchanges ADD rc_new_len INT;
+
+-- Note this upgrade
+INSERT INTO mediawiki_version (type,mw_version,notes)
+VALUES ('Upgrade','MWVERSION','Upgrade from older version THISVERSION');
+
+PGEND;
+
+ }
+
+ if ( !strlen($upgrade)) {
+ print "No updates needed for version $version\n";
+ return;
+ }
+
+ $upgrade = str_replace( 'MWVERSION', $wgVersion, $upgrade );
+ $upgrade = str_replace( 'THISVERSION', $version, $upgrade );
+ $res = $wgDatabase->query("BEGIN;\n\n $upgrade\n\nCOMMIT;\n");
+
+ return;
+}
+
+?>
diff --git a/maintenance/upgrade1_5.php b/maintenance/upgrade1_5.php
new file mode 100644
index 000000000000..a269c335154b
--- /dev/null
+++ b/maintenance/upgrade1_5.php
@@ -0,0 +1,24 @@
+<?php
+
+// Alternate 1.4 -> 1.5 schema upgrade
+// This does only the main tables + UTF-8
+// and is designed to allow upgrades to interleave
+// with other updates on the replication stream so
+// that large wikis can be upgraded without disrupting
+// other services.
+//
+// Note: this script DOES NOT apply every update, nor
+// will it probably handle much older versions, etc.
+// Run this, FOLLOWED BY update.php, for upgrading
+// from 1.4.5 release to 1.5.
+
+$options = array( 'step', 'noimages' );
+
+require_once( 'commandLine.inc' );
+require_once( 'FiveUpgrade.inc' );
+
+$upgrade = new FiveUpgrade();
+$step = isset( $options['step'] ) ? $options['step'] : null;
+$upgrade->upgrade( $step );
+
+?>
diff --git a/maintenance/userDupes.inc b/maintenance/userDupes.inc
new file mode 100644
index 000000000000..9af66f116d8a
--- /dev/null
+++ b/maintenance/userDupes.inc
@@ -0,0 +1,326 @@
+<?php
+# Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+/**
+ * Look for duplicate user table entries and optionally prune them.
+ */
+class UserDupes {
+ var $db;
+ var $reassigned;
+ var $trimmed;
+ var $failed;
+
+ function UserDupes( &$database ) {
+ $this->db =& $database;
+ }
+
+ /**
+ * Check if this database's user table has already had a unique
+ * user_name index applied.
+ * @return bool
+ */
+ function hasUniqueIndex() {
+ $fname = 'UserDupes::hasUniqueIndex';
+ $info = $this->db->indexInfo( 'user', 'user_name', $fname );
+ if( !$info ) {
+ echo "WARNING: doesn't seem to have user_name index at all!\n";
+ return false;
+ }
+
+ # Confusingly, 'Non_unique' is 0 for *unique* indexes,
+ # and 1 for *non-unique* indexes. Pass the crack, MySQL,
+ # it's obviously some good stuff!
+ return ( $info[0]->Non_unique == 0 );
+ }
+
+ /**
+ * Checks the database for duplicate user account records
+ * and remove them in preparation for application of a unique
+ * index on the user_name field. Returns true if the table is
+ * clean or if duplicates have been resolved automatically.
+ *
+ * May return false if there are unresolvable problems.
+ * Status information will be echo'd to stdout.
+ *
+ * @return bool
+ */
+ function clearDupes() {
+ return $this->checkDupes( true );
+ }
+
+ /**
+ * Checks the database for duplicate user account records
+ * in preparation for application of a unique index on the
+ * user_name field. Returns true if the table is clean or
+ * if duplicates can be resolved automatically.
+ *
+ * Returns false if there are duplicates and resolution was
+ * not requested. (If doing resolution, edits may be reassigned.)
+ * Status information will be echo'd to stdout.
+ *
+ * @param bool $doDelete pass true to actually remove things
+ * from the database; false to just check.
+ * @return bool
+ */
+ function checkDupes( $doDelete = false ) {
+ if( $this->hasUniqueIndex() ) {
+ echo wfWikiID()." already has a unique index on its user table.\n";
+ return true;
+ }
+
+ $this->lock();
+
+ echo "Checking for duplicate accounts...\n";
+ $dupes = $this->getDupes();
+ $count = count( $dupes );
+
+ echo "Found $count accounts with duplicate records on ".wfWikiID().".\n";
+ $this->trimmed = 0;
+ $this->reassigned = 0;
+ $this->failed = 0;
+ foreach( $dupes as $name ) {
+ $this->examine( $name, $doDelete );
+ }
+
+ $this->unlock();
+
+ echo "\n";
+
+ if( $this->reassigned > 0 ) {
+ if( $doDelete ) {
+ echo "$this->reassigned duplicate accounts had edits reassigned to a canonical record id.\n";
+ } else {
+ echo "$this->reassigned duplicate accounts need to have edits reassigned.\n";
+ }
+ }
+
+ if( $this->trimmed > 0 ) {
+ if( $doDelete ) {
+ echo "$this->trimmed duplicate user records were deleted from ".wfWikiID().".\n";
+ } else {
+ echo "$this->trimmed duplicate user accounts were found on ".wfWikiID()." which can be removed safely.\n";
+ }
+ }
+
+ if( $this->failed > 0 ) {
+ echo "Something terribly awry; $this->failed duplicate accounts were not removed.\n";
+ return false;
+ }
+
+ if( $this->trimmed == 0 || $doDelete ) {
+ echo "It is now safe to apply the unique index on user_name.\n";
+ return true;
+ } else {
+ echo "Run this script again with the --fix option to automatically delete them.\n";
+ return false;
+ }
+ }
+
+ /**
+ * We don't want anybody to mess with our stuff...
+ * @access private
+ */
+ function lock() {
+ $fname = 'UserDupes::lock';
+ if( $this->newSchema() ) {
+ $set = array( 'user', 'revision' );
+ } else {
+ $set = array( 'user', 'cur', 'old' );
+ }
+ $names = array_map( array( $this, 'lockTable' ), $set );
+ $tables = implode( ',', $names );
+
+ $result = $this->db->query( "LOCK TABLES $tables", $fname );
+ }
+
+ function lockTable( $table ) {
+ return $this->db->tableName( $table ) . ' WRITE';
+ }
+
+ /**
+ * @return bool
+ * @access private
+ */
+ function newSchema() {
+ return class_exists( 'Revision' );
+ }
+
+ /**
+ * @access private
+ */
+ function unlock() {
+ $fname = 'UserDupes::unlock';
+ $result = $this->db->query( "UNLOCK TABLES", $fname );
+ }
+
+ /**
+ * Grab usernames for which multiple records are present in the database.
+ * @return array
+ * @access private
+ */
+ function getDupes() {
+ $fname = 'UserDupes::listDupes';
+ $user = $this->db->tableName( 'user' );
+ $result = $this->db->query(
+ "SELECT user_name,COUNT(*) AS n
+ FROM $user
+ GROUP BY user_name
+ HAVING n > 1", $fname );
+
+ $list = array();
+ while( $row = $this->db->fetchObject( $result ) ) {
+ $list[] = $row->user_name;
+ }
+ $this->db->freeResult( $result );
+
+ return $list;
+ }
+
+ /**
+ * Examine user records for the given name. Try to see which record
+ * will be the one that actually gets used, then check remaining records
+ * for edits. If the dupes have no edits, we can safely remove them.
+ * @param string $name
+ * @param bool $doDelete
+ * @access private
+ */
+ function examine( $name, $doDelete ) {
+ $fname = 'UserDupes::listDupes';
+ $result = $this->db->select( 'user',
+ array( 'user_id' ),
+ array( 'user_name' => $name ),
+ $fname );
+
+ $firstRow = $this->db->fetchObject( $result );
+ $firstId = $firstRow->user_id;
+ echo "Record that will be used for '$name' is user_id=$firstId\n";
+
+ while( $row = $this->db->fetchObject( $result ) ) {
+ $dupeId = $row->user_id;
+ echo "... dupe id $dupeId: ";
+ $edits = $this->editCount( $dupeId );
+ if( $edits > 0 ) {
+ $this->reassigned++;
+ echo "has $edits edits! ";
+ if( $doDelete ) {
+ $this->reassignEdits( $dupeId, $firstId );
+ $newEdits = $this->editCount( $dupeId );
+ if( $newEdits == 0 ) {
+ echo "confirmed cleaned. ";
+ } else {
+ $this->failed++;
+ echo "WARNING! $newEdits remaining edits for $dupeId; NOT deleting user.\n";
+ continue;
+ }
+ } else {
+ echo "(will need to reassign edits on fix)";
+ }
+ } else {
+ echo "ok, no edits. ";
+ }
+ $this->trimmed++;
+ if( $doDelete ) {
+ $this->trimAccount( $dupeId );
+ }
+ echo "\n";
+ }
+ $this->db->freeResult( $result );
+ }
+
+ /**
+ * Count the number of edits attributed to this user.
+ * Does not currently check log table or other things
+ * where it might show up...
+ * @param int $userid
+ * @return int
+ * @access private
+ */
+ function editCount( $userid ) {
+ if( $this->newSchema() ) {
+ return $this->editCountOn( 'revision', 'rev_user', $userid );
+ } else {
+ return $this->editCountOn( 'cur', 'cur_user', $userid ) +
+ $this->editCountOn( 'old', 'old_user', $userid );
+ }
+ }
+
+ /**
+ * Count the number of hits on a given table for this account.
+ * @param string $table
+ * @param string $field
+ * @param int $userid
+ * @return int
+ * @access private
+ */
+ function editCountOn( $table, $field, $userid ) {
+ $fname = 'UserDupes::editCountOn';
+ return intval( $this->db->selectField(
+ $table,
+ 'COUNT(*)',
+ array( $field => $userid ),
+ $fname ) );
+ }
+
+ /**
+ * @param int $from
+ * @param int $to
+ * @access private
+ */
+ function reassignEdits( $from, $to ) {
+ $set = $this->newSchema()
+ ? array( 'revision' => 'rev_user' )
+ : array( 'cur' => 'cur_user', 'old' => 'old_user' );
+ foreach( $set as $table => $field ) {
+ $this->reassignEditsOn( $table, $field, $from, $to );
+ }
+ }
+
+ /**
+ * @param string $table
+ * @param string $field
+ * @param int $from
+ * @param int $to
+ * @access private
+ */
+ function reassignEditsOn( $table, $field, $from, $to ) {
+ $fname = 'UserDupes::reassignEditsOn';
+ echo "reassigning on $table... ";
+ $result = $this->db->update( $table,
+ array( $field => $to ),
+ array( $field => $from ),
+ $fname );
+ echo "ok. ";
+ }
+
+ /**
+ * Remove a user account line.
+ * @param int $userid
+ * @access private
+ */
+ function trimAccount( $userid ) {
+ $fname = 'UserDupes::trimAccount';
+ echo "deleting...";
+ $this->db->delete( 'user', array( 'user_id' => $userid ), $fname );
+ echo " ok";
+ }
+
+}
+
+
+?>
diff --git a/maintenance/userDupes.php b/maintenance/userDupes.php
new file mode 100644
index 000000000000..2469c6eb0c2e
--- /dev/null
+++ b/maintenance/userDupes.php
@@ -0,0 +1,41 @@
+<?php
+# Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+# http://www.mediawiki.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
+
+$options = array( 'fix' );
+
+/** */
+require_once( 'commandLine.inc' );
+require_once( 'maintenance/userDupes.inc' );
+
+$wgTitle = Title::newFromText( 'Dupe user entry cleanup script' );
+
+$fix = isset( $options['fix'] );
+$dbw =& wfGetDB( DB_MASTER );
+$duper = new UserDupes( $dbw );
+$retval = $duper->checkDupes( $fix );
+
+if( $retval ) {
+ echo "\nLooks good!\n";
+ exit( 0 );
+} else {
+ echo "\nOh noeees\n";
+ exit( -1 );
+}
+
+?> \ No newline at end of file
diff --git a/maintenance/users.sql b/maintenance/users.sql
new file mode 100644
index 000000000000..755bf9f7007d
--- /dev/null
+++ b/maintenance/users.sql
@@ -0,0 +1,12 @@
+-- SQL script to create required database users with proper
+-- access rights. This is run from the installation script
+-- which replaces the password variables with their values
+-- from local settings.
+--
+
+GRANT DELETE,INSERT,SELECT,UPDATE,CREATE TEMPORARY TABLES ON `{$wgDBname}`.*
+ TO '{$wgDBuser}'@'%' IDENTIFIED BY '{$wgDBpassword}';
+GRANT DELETE,INSERT,SELECT,UPDATE,CREATE TEMPORARY TABLES ON `{$wgDBname}`.*
+ TO '{$wgDBuser}'@localhost IDENTIFIED BY '{$wgDBpassword}';
+GRANT DELETE,INSERT,SELECT,UPDATE,CREATE TEMPORARY TABLES ON `{$wgDBname}`.*
+ TO '{$wgDBuser}'@localhost.localdomain IDENTIFIED BY '{$wgDBpassword}';
diff --git a/maintenance/wikipedia-interwiki.sql b/maintenance/wikipedia-interwiki.sql
new file mode 100644
index 000000000000..c6e4883f0f46
--- /dev/null
+++ b/maintenance/wikipedia-interwiki.sql
@@ -0,0 +1,220 @@
+-- For convenience, here are the *in-project* interwiki prefixes
+-- for Wikipedia.
+
+REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES
+('q','http://en.wikiquote.org/wiki/$1',1),
+('b','http://en.wikibooks.org/wiki/$1',1),
+('n','http://en.wikinews.org/wiki/$1',1),
+('aa','http://aa.wikipedia.org/wiki/$1',1),
+('ab','http://ab.wikipedia.org/wiki/$1',1),
+('af','http://af.wikipedia.org/wiki/$1',1),
+('ak','http://ak.wikipedia.org/wiki/$1',1),
+('als','http://als.wikipedia.org/wiki/$1',1),
+('am','http://am.wikipedia.org/wiki/$1',1),
+('an','http://an.wikipedia.org/wiki/$1',1),
+('ang','http://ang.wikipedia.org/wiki/$1',1),
+('ar','http://ar.wikipedia.org/wiki/$1',1),
+('arc','http://arc.wikipedia.org/wiki/$1',1),
+('as','http://as.wikipedia.org/wiki/$1',1),
+('ast','http://ast.wikipedia.org/wiki/$1',1),
+('av','http://av.wikipedia.org/wiki/$1',1),
+('ay','http://ay.wikipedia.org/wiki/$1',1),
+('az','http://az.wikipedia.org/wiki/$1',1),
+('ba','http://ba.wikipedia.org/wiki/$1',1),
+('be','http://be.wikipedia.org/wiki/$1',1),
+('bg','http://bg.wikipedia.org/wiki/$1',1),
+('bh','http://bh.wikipedia.org/wiki/$1',1),
+('bi','http://bi.wikipedia.org/wiki/$1',1),
+('bm','http://bm.wikipedia.org/wiki/$1',1),
+('bn','http://bn.wikipedia.org/wiki/$1',1),
+('bo','http://bo.wikipedia.org/wiki/$1',1),
+('br','http://br.wikipedia.org/wiki/$1',1),
+('bs','http://bs.wikipedia.org/wiki/$1',1),
+('ca','http://ca.wikipedia.org/wiki/$1',1),
+('ce','http://ce.wikipedia.org/wiki/$1',1),
+('ch','http://ch.wikipedia.org/wiki/$1',1),
+('cho','http://cho.wikipedia.org/wiki/$1',1),
+('chr','http://chr.wikipedia.org/wiki/$1',1),
+('chy','http://chy.wikipedia.org/wiki/$1',1),
+('co','http://co.wikipedia.org/wiki/$1',1),
+('cr','http://cr.wikipedia.org/wiki/$1',1),
+('cs','http://cs.wikipedia.org/wiki/$1',1),
+('csb','http://csb.wikipedia.org/wiki/$1',1),
+('cv','http://cv.wikipedia.org/wiki/$1',1),
+('cy','http://cy.wikipedia.org/wiki/$1',1),
+('da','http://da.wikipedia.org/wiki/$1',1),
+('de','http://de.wikipedia.org/wiki/$1',1),
+('dv','http://dv.wikipedia.org/wiki/$1',1),
+('dz','http://dz.wikipedia.org/wiki/$1',1),
+('ee','http://ee.wikipedia.org/wiki/$1',1),
+('el','http://el.wikipedia.org/wiki/$1',1),
+('en','http://en.wikipedia.org/wiki/$1',1),
+('eo','http://eo.wikipedia.org/wiki/$1',1),
+('es','http://es.wikipedia.org/wiki/$1',1),
+('et','http://et.wikipedia.org/wiki/$1',1),
+('eu','http://eu.wikipedia.org/wiki/$1',1),
+('fa','http://fa.wikipedia.org/wiki/$1',1),
+('ff','http://ff.wikipedia.org/wiki/$1',1),
+('fi','http://fi.wikipedia.org/wiki/$1',1),
+('fj','http://fj.wikipedia.org/wiki/$1',1),
+('fo','http://fo.wikipedia.org/wiki/$1',1),
+('fr','http://fr.wikipedia.org/wiki/$1',1),
+('fy','http://fy.wikipedia.org/wiki/$1',1),
+('fur','http://fur.wikipedia.org/wiki/$1',1),
+('ga','http://ga.wikipedia.org/wiki/$1',1),
+('gd','http://gd.wikipedia.org/wiki/$1',1),
+('gl','http://gl.wikipedia.org/wiki/$1',1),
+('gn','http://gn.wikipedia.org/wiki/$1',1),
+('got','http://got.wikipedia.org/wiki/$1',1),
+('gu','http://gu.wikipedia.org/wiki/$1',1),
+('gv','http://gv.wikipedia.org/wiki/$1',1),
+('ha','http://ha.wikipedia.org/wiki/$1',1),
+('haw','http://haw.wikipedia.org/wiki/$1',1),
+('he','http://he.wikipedia.org/wiki/$1',1),
+('hi','http://hi.wikipedia.org/wiki/$1',1),
+('ho','http://ho.wikipedia.org/wiki/$1',1),
+('hr','http://hr.wikipedia.org/wiki/$1',1),
+('ht','http://ht.wikipedia.org/wiki/$1',1),
+('hu','http://hu.wikipedia.org/wiki/$1',1),
+('hy','http://hy.wikipedia.org/wiki/$1',1),
+('hz','http://hz.wikipedia.org/wiki/$1',1),
+('ia','http://ia.wikipedia.org/wiki/$1',1),
+('id','http://id.wikipedia.org/wiki/$1',1),
+('ie','http://ie.wikipedia.org/wiki/$1',1),
+('ig','http://ig.wikipedia.org/wiki/$1',1),
+('ii','http://ii.wikipedia.org/wiki/$1',1),
+('ik','http://ik.wikipedia.org/wiki/$1',1),
+('io','http://io.wikipedia.org/wiki/$1',1),
+('is','http://is.wikipedia.org/wiki/$1',1),
+('it','http://it.wikipedia.org/wiki/$1',1),
+('iu','http://iu.wikipedia.org/wiki/$1',1),
+('ja','http://ja.wikipedia.org/wiki/$1',1),
+('jbo','http://jbo.wikipedia.org/wiki/$1',1),
+('jv','http://jv.wikipedia.org/wiki/$1',1),
+('ka','http://ka.wikipedia.org/wiki/$1',1),
+('kg','http://kg.wikipedia.org/wiki/$1',1),
+('ki','http://ki.wikipedia.org/wiki/$1',1),
+('kj','http://kj.wikipedia.org/wiki/$1',1),
+('kk','http://kk.wikipedia.org/wiki/$1',1),
+('kl','http://kl.wikipedia.org/wiki/$1',1),
+('km','http://km.wikipedia.org/wiki/$1',1),
+('kn','http://kn.wikipedia.org/wiki/$1',1),
+('ko','http://ko.wikipedia.org/wiki/$1',1),
+('kr','http://kr.wikipedia.org/wiki/$1',1),
+('ks','http://ks.wikipedia.org/wiki/$1',1),
+('ku','http://ku.wikipedia.org/wiki/$1',1),
+('kv','http://kv.wikipedia.org/wiki/$1',1),
+('kw','http://kw.wikipedia.org/wiki/$1',1),
+('ky','http://ky.wikipedia.org/wiki/$1',1),
+('la','http://la.wikipedia.org/wiki/$1',1),
+('lb','http://lb.wikipedia.org/wiki/$1',1),
+('lg','http://lg.wikipedia.org/wiki/$1',1),
+('li','http://li.wikipedia.org/wiki/$1',1),
+('ln','http://ln.wikipedia.org/wiki/$1',1),
+('lo','http://lo.wikipedia.org/wiki/$1',1),
+('lt','http://lt.wikipedia.org/wiki/$1',1),
+('lv','http://lv.wikipedia.org/wiki/$1',1),
+('mg','http://mg.wikipedia.org/wiki/$1',1),
+('mh','http://mh.wikipedia.org/wiki/$1',1),
+('mi','http://mi.wikipedia.org/wiki/$1',1),
+('mk','http://mk.wikipedia.org/wiki/$1',1),
+('ml','http://ml.wikipedia.org/wiki/$1',1),
+('mn','http://mn.wikipedia.org/wiki/$1',1),
+('mo','http://mo.wikipedia.org/wiki/$1',1),
+('mr','http://mr.wikipedia.org/wiki/$1',1),
+('ms','http://ms.wikipedia.org/wiki/$1',1),
+('mt','http://mt.wikipedia.org/wiki/$1',1),
+('mus','http://mus.wikipedia.org/wiki/$1',1),
+('my','http://my.wikipedia.org/wiki/$1',1),
+('na','http://na.wikipedia.org/wiki/$1',1),
+('nah','http://nah.wikipedia.org/wiki/$1',1),
+('nb','http://nb.wikipedia.org/wiki/$1',1),
+('nds','http://nds.wikipedia.org/wiki/$1',1),
+('ne','http://ne.wikipedia.org/wiki/$1',1),
+('ng','http://ng.wikipedia.org/wiki/$1',1),
+('nl','http://nl.wikipedia.org/wiki/$1',1),
+('nn','http://nn.wikipedia.org/wiki/$1',1),
+('no','http://no.wikipedia.org/wiki/$1',1),
+('nv','http://nv.wikipedia.org/wiki/$1',1),
+('ny','http://ny.wikipedia.org/wiki/$1',1),
+('oc','http://oc.wikipedia.org/wiki/$1',1),
+('om','http://om.wikipedia.org/wiki/$1',1),
+('or','http://or.wikipedia.org/wiki/$1',1),
+('pa','http://pa.wikipedia.org/wiki/$1',1),
+('pi','http://pi.wikipedia.org/wiki/$1',1),
+('pl','http://pl.wikipedia.org/wiki/$1',1),
+('ps','http://ps.wikipedia.org/wiki/$1',1),
+('pt','http://pt.wikipedia.org/wiki/$1',1),
+('qu','http://qu.wikipedia.org/wiki/$1',1),
+('rm','http://rm.wikipedia.org/wiki/$1',1),
+('rn','http://rn.wikipedia.org/wiki/$1',1),
+('ro','http://ro.wikipedia.org/wiki/$1',1),
+('roa-rup','http://roa-rup.wikipedia.org/wiki/$1',1),
+('ru','http://ru.wikipedia.org/wiki/$1',1),
+('rw','http://rw.wikipedia.org/wiki/$1',1),
+('sa','http://sa.wikipedia.org/wiki/$1',1),
+('sc','http://sc.wikipedia.org/wiki/$1',1),
+('scn','http://scn.wikipedia.org/wiki/$1',1),
+('sd','http://sd.wikipedia.org/wiki/$1',1),
+('se','http://se.wikipedia.org/wiki/$1',1),
+('sg','http://sg.wikipedia.org/wiki/$1',1),
+('sh','http://sh.wikipedia.org/wiki/$1',1),
+('si','http://si.wikipedia.org/wiki/$1',1),
+('simple','http://simple.wikipedia.org/wiki/$1',1),
+('sk','http://sk.wikipedia.org/wiki/$1',1),
+('sl','http://sl.wikipedia.org/wiki/$1',1),
+('sm','http://sm.wikipedia.org/wiki/$1',1),
+('sn','http://sn.wikipedia.org/wiki/$1',1),
+('so','http://so.wikipedia.org/wiki/$1',1),
+('sq','http://sq.wikipedia.org/wiki/$1',1),
+('sr','http://sr.wikipedia.org/wiki/$1',1),
+('ss','http://ss.wikipedia.org/wiki/$1',1),
+('st','http://st.wikipedia.org/wiki/$1',1),
+('su','http://su.wikipedia.org/wiki/$1',1),
+('sv','http://sv.wikipedia.org/wiki/$1',1),
+('sw','http://sw.wikipedia.org/wiki/$1',1),
+('ta','http://ta.wikipedia.org/wiki/$1',1),
+('te','http://te.wikipedia.org/wiki/$1',1),
+('tg','http://tg.wikipedia.org/wiki/$1',1),
+('th','http://th.wikipedia.org/wiki/$1',1),
+('ti','http://ti.wikipedia.org/wiki/$1',1),
+('tk','http://tk.wikipedia.org/wiki/$1',1),
+('tl','http://tl.wikipedia.org/wiki/$1',1),
+('tlh','http://tlh.wikipedia.org/wiki/$1',1),
+('tn','http://tn.wikipedia.org/wiki/$1',1),
+('to','http://to.wikipedia.org/wiki/$1',1),
+('tokipona','http://tokipona.wikipedia.org/wiki/$1',1),
+('tpi','http://tpi.wikipedia.org/wiki/$1',1),
+('tr','http://tr.wikipedia.org/wiki/$1',1),
+('ts','http://ts.wikipedia.org/wiki/$1',1),
+('tt','http://tt.wikipedia.org/wiki/$1',1),
+('tum','http://tum.wikipedia.org/wiki/$1',1),
+('tw','http://tw.wikipedia.org/wiki/$1',1),
+('ty','http://ty.wikipedia.org/wiki/$1',1),
+('ug','http://ug.wikipedia.org/wiki/$1',1),
+('uk','http://uk.wikipedia.org/wiki/$1',1),
+('ur','http://ur.wikipedia.org/wiki/$1',1),
+('uz','http://uz.wikipedia.org/wiki/$1',1),
+('ve','http://ve.wikipedia.org/wiki/$1',1),
+('vi','http://vi.wikipedia.org/wiki/$1',1),
+('vo','http://vo.wikipedia.org/wiki/$1',1),
+('wa','http://wa.wikipedia.org/wiki/$1',1),
+('wo','http://wo.wikipedia.org/wiki/$1',1),
+('xh','http://xh.wikipedia.org/wiki/$1',1),
+('yi','http://yi.wikipedia.org/wiki/$1',1),
+('yo','http://yo.wikipedia.org/wiki/$1',1),
+('za','http://za.wikipedia.org/wiki/$1',1),
+('zh','http://zh.wikipedia.org/wiki/$1',1),
+('zh-min-nan','http://zh-min-nan.wikipedia.org/wiki/$1',1),
+('zu','http://zu.wikipedia.org/wiki/$1',1),
+('zh-cn','http://zh.wikipedia.org/wiki/$1',1),
+('zh-tw','http://zh.wikipedia.org/wiki/$1',1),
+('minnan','http://zh-min-nan.wikipedia.org/wiki/$1',1),
+('zh-cfr','http://zh-min-nan.wikipedia.org/wiki/$1',1),
+('dk','http://da.wikipedia.org/wiki/$1',1),
+('w','http://en.wikipedia.org/wiki/$1',1),
+('m','http://meta.wikimedia.org/wiki/$1',1),
+('meta','http://meta.wikimedia.org/wiki/$1',1),
+('sep11','http://sep11.wikipedia.org/wiki/$1',1),
+('os','http://os.wikipedia.org/wiki/$1',1);
+
diff --git a/maintenance/wiktionary-interwiki.sql b/maintenance/wiktionary-interwiki.sql
new file mode 100644
index 000000000000..787962d5b7a4
--- /dev/null
+++ b/maintenance/wiktionary-interwiki.sql
@@ -0,0 +1,160 @@
+-- For convenience, here are the *in-project* interwiki prefixes
+-- for Wikipedia.
+
+REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES
+('w','http://www.wikipedia.org/wiki/$1',1),
+('m','http://meta.wikipedia.org/wiki/$1',1),
+('meta','http://meta.wikipedia.org/wiki/$1',1),
+('sep11','http://sep11.wikipedia.org/wiki/$1',1),
+('simple','http://simple.wiktionary.org/wiki/$1',1),
+('aa','http://aa.wiktionary.org/wiki/$1',1),
+('ab','http://ab.wiktionary.org/wiki/$1',1),
+('af','http://af.wiktionary.org/wiki/$1',1),
+('als','http://als.wiktionary.org/wiki/$1',1),
+('am','http://am.wiktionary.org/wiki/$1',1),
+('ar','http://ar.wiktionary.org/wiki/$1',1),
+('as','http://as.wiktionary.org/wiki/$1',1),
+('ay','http://ay.wiktionary.org/wiki/$1',1),
+('az','http://az.wiktionary.org/wiki/$1',1),
+('ba','http://ba.wiktionary.org/wiki/$1',1),
+('be','http://be.wiktionary.org/wiki/$1',1),
+('bg','http://bg.wiktionary.org/wiki/$1',1),
+('bh','http://bh.wiktionary.org/wiki/$1',1),
+('bi','http://bi.wiktionary.org/wiki/$1',1),
+('bn','http://bn.wiktionary.org/wiki/$1',1),
+('bo','http://bo.wiktionary.org/wiki/$1',1),
+('bs','http://bs.wiktionary.org/wiki/$1',1),
+('ca','http://ca.wiktionary.org/wiki/$1',1),
+('chr','http://chr.wiktionary.org/wiki/$1',1),
+('co','http://co.wiktionary.org/wiki/$1',1),
+('cs','http://cs.wiktionary.org/wiki/$1',1),
+('csb','http://csb.wiktionary.org/wiki/$1',1),
+('cy','http://cy.wiktionary.org/wiki/$1',1),
+('da','http://da.wiktionary.org/wiki/$1',1),
+('de','http://de.wiktionary.org/wiki/$1',1),
+('dk','http://da.wiktionary.org/wiki/$1',1),
+('dz','http://dz.wiktionary.org/wiki/$1',1),
+('el','http://el.wiktionary.org/wiki/$1',1),
+('en','http://en.wiktionary.org/wiki/$1',1),
+('eo','http://eo.wiktionary.org/wiki/$1',1),
+('es','http://es.wiktionary.org/wiki/$1',1),
+('et','http://et.wiktionary.org/wiki/$1',1),
+('eu','http://eu.wiktionary.org/wiki/$1',1),
+('fa','http://fa.wiktionary.org/wiki/$1',1),
+('fi','http://fi.wiktionary.org/wiki/$1',1),
+('fj','http://fj.wiktionary.org/wiki/$1',1),
+('fo','http://fo.wiktionary.org/wiki/$1',1),
+('fr','http://fr.wiktionary.org/wiki/$1',1),
+('fy','http://fy.wiktionary.org/wiki/$1',1),
+('ga','http://ga.wiktionary.org/wiki/$1',1),
+('gd','http://gd.wiktionary.org/wiki/$1',1),
+('gl','http://gl.wiktionary.org/wiki/$1',1),
+('gn','http://gn.wiktionary.org/wiki/$1',1),
+('gu','http://gu.wiktionary.org/wiki/$1',1),
+('gv','http://gv.wiktionary.org/wiki/$1',1),
+('ha','http://ha.wiktionary.org/wiki/$1',1),
+('he','http://he.wiktionary.org/wiki/$1',1),
+('hi','http://hi.wiktionary.org/wiki/$1',1),
+('hr','http://hr.wiktionary.org/wiki/$1',1),
+('hu','http://hu.wiktionary.org/wiki/$1',1),
+('hy','http://hy.wiktionary.org/wiki/$1',1),
+('ia','http://ia.wiktionary.org/wiki/$1',1),
+('id','http://id.wiktionary.org/wiki/$1',1),
+('ik','http://ik.wiktionary.org/wiki/$1',1),
+('io','http://io.wiktionary.org/wiki/$1',1),
+('is','http://is.wiktionary.org/wiki/$1',1),
+('it','http://it.wiktionary.org/wiki/$1',1),
+('iu','http://iu.wiktionary.org/wiki/$1',1),
+('ja','http://ja.wiktionary.org/wiki/$1',1),
+('jv','http://jv.wiktionary.org/wiki/$1',1),
+('ka','http://ka.wiktionary.org/wiki/$1',1),
+('kk','http://kk.wiktionary.org/wiki/$1',1),
+('kl','http://kl.wiktionary.org/wiki/$1',1),
+('km','http://km.wiktionary.org/wiki/$1',1),
+('kn','http://kn.wiktionary.org/wiki/$1',1),
+('ko','http://ko.wiktionary.org/wiki/$1',1),
+('ks','http://ks.wiktionary.org/wiki/$1',1),
+('ku','http://ku.wiktionary.org/wiki/$1',1),
+('ky','http://ky.wiktionary.org/wiki/$1',1),
+('la','http://la.wiktionary.org/wiki/$1',1),
+('lo','http://lo.wiktionary.org/wiki/$1',1),
+('lt','http://lt.wiktionary.org/wiki/$1',1),
+('lv','http://lv.wiktionary.org/wiki/$1',1),
+('mg','http://mg.wiktionary.org/wiki/$1',1),
+('mi','http://mi.wiktionary.org/wiki/$1',1),
+('mk','http://mk.wiktionary.org/wiki/$1',1),
+('ml','http://ml.wiktionary.org/wiki/$1',1),
+('mn','http://mn.wiktionary.org/wiki/$1',1),
+('mo','http://mo.wiktionary.org/wiki/$1',1),
+('mr','http://mr.wiktionary.org/wiki/$1',1),
+('ms','http://ms.wiktionary.org/wiki/$1',1),
+('my','http://my.wiktionary.org/wiki/$1',1),
+('na','http://na.wiktionary.org/wiki/$1',1),
+('nah','http://nah.wiktionary.org/wiki/$1',1),
+('nb', 'http://no.wiktionary.org/wiki/$1',1),
+('nds','http://nds.wiktionary.org/wiki/$1',1),
+('ne','http://ne.wiktionary.org/wiki/$1',1),
+('nl','http://nl.wiktionary.org/wiki/$1',1),
+('no','http://no.wiktionary.org/wiki/$1',1),
+('oc','http://oc.wiktionary.org/wiki/$1',1),
+('om','http://om.wiktionary.org/wiki/$1',1),
+('or','http://or.wiktionary.org/wiki/$1',1),
+('pa','http://pa.wiktionary.org/wiki/$1',1),
+('pl','http://pl.wiktionary.org/wiki/$1',1),
+('ps','http://ps.wiktionary.org/wiki/$1',1),
+('pt','http://pt.wiktionary.org/wiki/$1',1),
+('qu','http://qu.wiktionary.org/wiki/$1',1),
+('rm','http://rm.wiktionary.org/wiki/$1',1),
+('rn','http://rn.wiktionary.org/wiki/$1',1),
+('ro','http://ro.wiktionary.org/wiki/$1',1),
+('ru','http://ru.wiktionary.org/wiki/$1',1),
+('rw','http://rw.wiktionary.org/wiki/$1',1),
+('sa','http://sa.wiktionary.org/wiki/$1',1),
+('sd','http://sd.wiktionary.org/wiki/$1',1),
+('sg','http://sg.wiktionary.org/wiki/$1',1),
+('sh','http://sh.wiktionary.org/wiki/$1',1),
+('si','http://si.wiktionary.org/wiki/$1',1),
+('sk','http://sk.wiktionary.org/wiki/$1',1),
+('sl','http://sl.wiktionary.org/wiki/$1',1),
+('sm','http://sm.wiktionary.org/wiki/$1',1),
+('sn','http://sn.wiktionary.org/wiki/$1',1),
+('so','http://so.wiktionary.org/wiki/$1',1),
+('sq','http://sq.wiktionary.org/wiki/$1',1),
+('sr','http://sr.wiktionary.org/wiki/$1',1),
+('ss','http://ss.wiktionary.org/wiki/$1',1),
+('st','http://st.wiktionary.org/wiki/$1',1),
+('su','http://su.wiktionary.org/wiki/$1',1),
+('sv','http://sv.wiktionary.org/wiki/$1',1),
+('sw','http://sw.wiktionary.org/wiki/$1',1),
+('ta','http://ta.wiktionary.org/wiki/$1',1),
+('te','http://te.wiktionary.org/wiki/$1',1),
+('tg','http://tg.wiktionary.org/wiki/$1',1),
+('th','http://th.wiktionary.org/wiki/$1',1),
+('ti','http://ti.wiktionary.org/wiki/$1',1),
+('tk','http://tk.wiktionary.org/wiki/$1',1),
+('tl','http://tl.wiktionary.org/wiki/$1',1),
+('tn','http://tn.wiktionary.org/wiki/$1',1),
+('to','http://to.wiktionary.org/wiki/$1',1),
+('tokipona','http://tokipona.wiktionary.org/wiki/$1',1),
+('tpi','http://tpi.wiktionary.org/wiki/$1',1),
+('tr','http://tr.wiktionary.org/wiki/$1',1),
+('ts','http://ts.wiktionary.org/wiki/$1',1),
+('tt','http://tt.wiktionary.org/wiki/$1',1),
+('tw','http://tw.wiktionary.org/wiki/$1',1),
+('ug','http://ug.wiktionary.org/wiki/$1',1),
+('uk','http://uk.wiktionary.org/wiki/$1',1),
+('ur','http://ur.wiktionary.org/wiki/$1',1),
+('uz','http://uz.wiktionary.org/wiki/$1',1),
+('vi','http://vi.wiktionary.org/wiki/$1',1),
+('vo','http://vo.wiktionary.org/wiki/$1',1),
+('wa','http://wa.wiktionary.org/wiki/$1',1),
+('wo','http://wo.wiktionary.org/wiki/$1',1),
+('xh','http://xh.wiktionary.org/wiki/$1',1),
+('yi','http://yi.wiktionary.org/wiki/$1',1),
+('yo','http://yo.wiktionary.org/wiki/$1',1),
+('za','http://za.wiktionary.org/wiki/$1',1),
+('zh','http://zh.wiktionary.org/wiki/$1',1),
+('zh-cn','http://zh.wiktionary.org/wiki/$1',1),
+('zh-tw','http://zh.wiktionary.org/wiki/$1',1),
+('zu','http://zu.wiktionary.org/wiki/$1',1);
+
diff --git a/math/.htaccess b/math/.htaccess
new file mode 100644
index 000000000000..3a4288278871
--- /dev/null
+++ b/math/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/math/.svnignore b/math/.svnignore
new file mode 100644
index 000000000000..6aa96403f87d
--- /dev/null
+++ b/math/.svnignore
@@ -0,0 +1,7 @@
+texvc
+texvc_test
+texvc_tex
+*.cmi
+*.cmx
+*.mli
+*~
diff --git a/math/Makefile b/math/Makefile
new file mode 100644
index 000000000000..47c40f96f181
--- /dev/null
+++ b/math/Makefile
@@ -0,0 +1,64 @@
+OBJ=render_info.cmo tex.cmo texutil.cmo parser.cmo lexer.cmo texvc.cmo \
+render_info.cmx tex.cmx texutil.cmx parser.cmx lexer.cmx texvc.cmx \
+lexer.cmi parser.cmi render_info.cmi tex.cmi texutil.cmi texvc.cmi \
+lexer.o parser.o render_info.o tex.o texutil.o texvc.o \
+lexer.ml parser.ml parser.mli texvc texvc.bc texvc_test.cmo \
+texvc_test.cmx texvc_test.cmi texvc_test.o texvc_test util.o \
+util.cmo util.cmx util.cmi texvc_cgi.cmi texvc_cgi texvc_cgi.cmo \
+render.o render.cmi render.cmo render.cmx texvc_tex.cmx \
+texvc_tex.o texvc_tex.cmi texvc_tex html.cmi html.cmo html.cmx \
+html.o mathml.cmi mathml.cmo mathml.cmx mathml.o
+CGIPATH=-I /usr/lib/ocaml/cgi -I /usr/lib/ocaml/netstring -I /usr/lib/ocaml/pcre
+
+all: texvc texvc_test texvc_tex
+texvc.bc: util.cmo parser.cmo html.cmo mathml.cmo texutil.cmo render.cmo lexer.cmo texvc.cmo
+ ocamlc -o $@ unix.cma $^
+texvc: util.cmx parser.cmx html.cmx mathml.cmx texutil.cmx render.cmx lexer.cmx texvc.cmx
+ ocamlopt -o $@ unix.cmxa $^
+texvc_test: util.cmx parser.cmx html.cmx mathml.cmx texutil.cmx lexer.cmx texvc_test.cmx
+ ocamlopt -o $@ $^
+texvc_tex: util.cmx parser.cmx html.cmx mathml.cmx texutil.cmx lexer.cmx texvc_tex.cmx
+ ocamlopt -o $@ $^
+%.ml: %.mll
+ ocamllex $<
+%.mli %.ml: %.mly
+ ocamlyacc $<
+%.cmo: %.ml
+ ocamlc -c $<
+%.cmx: %.ml
+ ocamlopt -c $<
+%.cmi: %.mli
+ ocamlc -c $<
+texvc_cgi.cmo: texvc_cgi.ml
+ ocamlc -c $(CGIPATH) $<
+texvc_cgi: util.cmo parser.cmo texutil.cmo render.cmo lexer.cmo texvc_cgi.cmo
+ ocamlc -o $@ unix.cma $(CGIPATH) pcre.cma netstring.cma cgi.cma $^
+ chmod g-w $@
+clean:
+ rm -f $(OBJ)
+
+html.cmo: render_info.cmi tex.cmi util.cmo html.cmi
+html.cmx: render_info.cmi tex.cmi util.cmx html.cmi
+html.cmi: tex.cmi
+lexer.cmo: parser.cmi render_info.cmi tex.cmi texutil.cmi
+lexer.cmx: parser.cmx render_info.cmi tex.cmi texutil.cmx
+mathml.cmo: tex.cmi mathml.cmi
+mathml.cmx: tex.cmi mathml.cmi
+mathml.cmi: tex.cmi
+parser.cmo: render_info.cmi tex.cmi parser.cmi
+parser.cmx: render_info.cmi tex.cmi parser.cmi
+parser.cmi: render_info.cmi tex.cmi
+render.cmo: texutil.cmi util.cmo
+render.cmx: texutil.cmx util.cmx
+tex.cmi: render_info.cmi
+texutil.cmo: html.cmi parser.cmi render_info.cmi tex.cmi util.cmo texutil.cmi
+texutil.cmx: html.cmx parser.cmx render_info.cmi tex.cmi util.cmx texutil.cmi
+texutil.cmi: parser.cmi tex.cmi
+texvc.cmo: html.cmi lexer.cmo mathml.cmi parser.cmi render.cmo texutil.cmi util.cmo
+texvc.cmx: html.cmx lexer.cmx mathml.cmx parser.cmx render.cmx texutil.cmx util.cmx
+texvc_cgi.cmo: lexer.cmo parser.cmi render.cmo texutil.cmi util.cmo
+texvc_cgi.cmx: lexer.cmx parser.cmx render.cmx texutil.cmx util.cmx
+texvc_test.cmo: html.cmi lexer.cmo parser.cmi texutil.cmi util.cmo
+texvc_test.cmx: html.cmx lexer.cmx parser.cmx texutil.cmx util.cmx
+texvc_tex.cmo: lexer.cmo parser.cmi texutil.cmi util.cmo
+texvc_tex.cmx: lexer.cmx parser.cmx texutil.cmx util.cmx
diff --git a/math/README b/math/README
new file mode 100644
index 000000000000..818ce6bd457e
--- /dev/null
+++ b/math/README
@@ -0,0 +1,120 @@
+== About texvc ==
+
+texvc takes LaTeX-compatible equations and produces formatted output in
+HTML, MathML, and (via LaTeX/dvipng) rasterized PNG images.
+Input data is parsed and scrutinized for safety, and the output includes
+an estimate of whether the code is simple enough that HTML rendering will
+look acceptable.
+
+The program was written by Tomasz Wegrzanowski for use with MediaWiki;
+it's included as part of the MediaWiki package (http://wikipedia.sf.net)
+and is under the GPL license.
+
+Please report bugs at: http://bugzilla.wikimedia.org/ (under "MediaWiki")
+
+== Setup ==
+
+=== Requirements ===
+
+OCaml 3.06 or later is required to compile texvc; this can be acquired
+from http://caml.inria.fr/ if your system doesn't have it available.
+
+The makefile requires GNU make.
+
+Rasterization is done via LaTeX, dvipng. These need
+to be installed and in the PATH: latex, dvipng
+
+AMS* packages for LaTeX also need to be installed. Without AMS* some
+equations will render correctly while others won't render.
+Most distributions of TeX already contain AMS*.
+In Debian/Ubuntu you need to install tetex-extra.
+
+To work properly with rendering non-ASCII Unicode characters, a
+supplemental TeX package is needed (cjk-latex in Debian)
+
+=== Installation ===
+
+Run 'make' (or 'gmake' if GNU make is not your default make). This should
+produce the texvc executable.
+
+If you're using MediaWiki's install.php and have enabled $wgUseTeX in your
+LocalSettings.php, the installer will try to copy texvc into place, in the
+'math' subdirectory under where wiki.phtml is installed.
+
+
+== Usage ==
+
+Normally texvc is called from MediaWiki's Math.php modules and everything
+Just Works. It can be run manually for testing or for use in another app.
+
+=== Command-line parameters ===
+
+ texvc <temp directory> <output directory> <TeX code> <encoding>
+
+Be sure to properly quote the TeX code!
+
+Example:
+
+ texvc /home/wiki/tmp /home/wiki/math "y=x+2" iso-8859-1
+
+=== Output format ===
+
+Status codes and HTML/MathML transformations are returned on stdout.
+A rasterized PNG file will be written to the output directory, named
+for the MD5 hash code.
+
+texvc output format is like this:
+ +%5 ok, but not html or mathml
+ c%5%h ok, conservative html, no mathml
+ m%5%h ok, moderate html, no mathml
+ l%5%h ok, liberal html, no mathml
+ C%5%h\0%m ok, conservative html, with mathml
+ M%5%h\0%m ok, moderate html, with mathml
+ L%5%h\0%m ok, liberal html, with mathml
+ X%5%m ok, no html, with mathml
+ S syntax error
+ E lexing error
+ F%s unknown function %s
+ - other error
+
+ \0 - null character
+ %5 - md5, 32 hex characters
+ %h - html code, without \0 characters
+ %m - mathml code, without \0 characters
+
+
+== Troubleshooting ==
+
+Unforunately, many error conditions with rasterization are not well reported.
+texvc will return as though everything is successful, and the only obvious
+sign of problems for the user is a big X on a wiki page where an equation
+should be.
+
+Try running texvc from the command line to ensure that the software it relies
+upon is all set up.
+
+Ensure that the temporary and math directories exist and can be written to by
+the user account the web server runs under; if you don't control the server,
+you may have to make them world-writable.
+
+If some equations render correctly while others don't, you probably don't have
+AMS* packages for LaTeX installed. Most distributions of TeX come with AMS*.
+In Debian/Ubuntu AMS* is in tetex-extra package.
+To check if that is the problem you can try those two equations:
+ x + y
+ x \implies y
+The first uses only standard LaTeX, while the second uses symbol \implies from AMS*.
+If the first renders, but the second doesn't, you need to install AMS*.
+
+== Hacking ==
+
+Before you start hacking on the math package its good to know the workflow,
+which is basically:
+
+1. texvc gets called by includes/Math.php (check out the line begining with "$cmd")
+2. texvc does its magic, which is basically to check for invalid latex code.
+3. texvc takes the user input if valid and creates a latex file containing it, see
+ get_preface in texutil.ml
+4. dvipng(1) gets called to create a .png file
+ See render.ml for this process (commenting out the removal of
+ the temporary file is useful for debugging).
diff --git a/math/TODO b/math/TODO
new file mode 100644
index 000000000000..bd8d1f4fb951
--- /dev/null
+++ b/math/TODO
@@ -0,0 +1,3 @@
+* It would be better if PNGs were transparent
+* CJK support
+* Documentation, in particular about instalation of Latex support for Unicode
diff --git a/math/html.ml b/math/html.ml
new file mode 100644
index 000000000000..e880f07350b4
--- /dev/null
+++ b/math/html.ml
@@ -0,0 +1,142 @@
+open Render_info
+open Tex
+open Util
+
+exception Too_difficult_for_html
+type context = CTX_NORMAL | CTX_IT | CTX_RM
+type conservativeness_t = CONSERVATIVE | MODERATE | LIBERAL
+
+let conservativeness = ref CONSERVATIVE
+let html_liberal () = conservativeness := LIBERAL
+let html_moderate () = if !conservativeness = CONSERVATIVE then conservativeness := MODERATE else ()
+
+
+let new_ctx = function
+ FONTFORCE_IT -> CTX_IT
+ | FONTFORCE_RM -> CTX_RM
+let font_render lit = function
+ (_, FONT_UFH) -> lit
+ | (_, FONT_UF) -> lit
+ | (CTX_IT,FONT_RTI) -> raise Too_difficult_for_html
+ | (_, FONT_RTI) -> lit
+ | (CTX_IT,FONT_RM) -> "<i>"^lit^"</i>"
+ | (_, FONT_RM) -> lit
+ | (CTX_RM,FONT_IT) -> lit
+ | (_, FONT_IT) -> "<i>"^lit^"</i>"
+
+let rec html_render_flat ctx = function
+ TEX_LITERAL (HTMLABLE (ft,_,sh))::r -> (html_liberal (); (font_render sh (ctx,ft))^html_render_flat ctx r)
+ | TEX_LITERAL (HTMLABLEC(ft,_,sh))::r -> (font_render sh (ctx,ft))^html_render_flat ctx r
+ | TEX_LITERAL (MHTMLABLEC(ft,_,sh,_,_))::r -> (font_render sh (ctx,ft))^html_render_flat ctx r
+ | TEX_LITERAL (HTMLABLEM(ft,_,sh))::r -> (html_moderate(); (font_render sh (ctx,ft))^html_render_flat ctx r)
+ | TEX_LITERAL (HTMLABLE_BIG (_,sh))::r -> (html_liberal (); sh^html_render_flat ctx r)
+ | TEX_FUN1hl (_,(f1,f2),a)::r -> f1^(html_render_flat ctx [a])^f2^html_render_flat ctx r
+ | TEX_FUN1hf (_,ff,a)::r -> (html_render_flat (new_ctx ff) [a])^html_render_flat ctx r
+ | TEX_DECLh (_,ff,a)::r -> (html_render_flat (new_ctx ff) a)^html_render_flat ctx r
+ | TEX_CURLY ls::r -> html_render_flat ctx (ls @ r)
+ | TEX_DQ (a,b)::r -> (html_liberal ();
+ let bs = html_render_flat ctx [b] in match html_render_size ctx a with
+ true, s -> raise Too_difficult_for_html
+ | false, s -> s^"<sub>"^bs^"</sub>")^html_render_flat ctx r
+ | TEX_UQ (a,b)::r -> (html_liberal ();
+ let bs = html_render_flat ctx [b] in match html_render_size ctx a with
+ true, s -> raise Too_difficult_for_html
+ | false, s -> s^"<sup>"^bs^"</sup>")^html_render_flat ctx r
+ | TEX_FQ (a,b,c)::r -> (html_liberal ();
+ (let bs = html_render_flat ctx [b] in let cs = html_render_flat ctx [c] in
+ match html_render_size ctx a with
+ true, s -> raise Too_difficult_for_html
+ | false, s -> s^"<sub>"^bs^"</sub><sup>"^cs^"</sup>")^html_render_flat ctx r)
+ | TEX_DQN (a)::r -> (html_liberal ();
+ let bs = html_render_flat ctx [a] in "<sub>"^bs^"</sub>")^html_render_flat ctx r
+ | TEX_UQN (a)::r -> (html_liberal ();
+ let bs = html_render_flat ctx [a] in "<sup>"^bs^"</sup>")^html_render_flat ctx r
+ | TEX_FQN (a,b)::r -> (html_liberal ();
+ (let bs = html_render_flat ctx [a] in let cs = html_render_flat ctx [b] in "<sub>"^bs^"</sub><sup>"^cs^"</sup>")^html_render_flat ctx r)
+ | TEX_BOX (_,s)::r -> s^html_render_flat ctx r
+ | TEX_LITERAL (TEX_ONLY _)::_ -> raise Too_difficult_for_html
+ | TEX_FUN1 _::_ -> raise Too_difficult_for_html
+ | TEX_FUN2 _::_ -> raise Too_difficult_for_html
+ | TEX_FUN2nb _::_ -> raise Too_difficult_for_html
+ | TEX_FUN2h _::_ -> raise Too_difficult_for_html
+ | TEX_FUN2sq _::_ -> raise Too_difficult_for_html
+ | TEX_INFIX _::_ -> raise Too_difficult_for_html
+ | TEX_INFIXh _::_ -> raise Too_difficult_for_html
+ | TEX_MATRIX _::_ -> raise Too_difficult_for_html
+ | TEX_LR _::_ -> raise Too_difficult_for_html
+ | TEX_BIG _::_ -> raise Too_difficult_for_html
+ | [] -> ""
+and html_render_size ctx = function
+ TEX_LITERAL (HTMLABLE_BIG (_,sh)) -> true,sh
+ | x -> false,html_render_flat ctx [x]
+
+let rec html_render_deep ctx = function
+ TEX_LITERAL (HTMLABLE (ft,_,sh))::r -> (html_liberal (); ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r)
+ | TEX_LITERAL (HTMLABLEM(ft,_,sh))::r -> (html_moderate(); ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r)
+ | TEX_LITERAL (HTMLABLEC(ft,_,sh))::r -> ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r
+ | TEX_LITERAL (MHTMLABLEC(ft,_,sh,_,_))::r -> ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r
+ | TEX_LITERAL (HTMLABLE_BIG (_,sh))::r -> (html_liberal (); ("",sh,"")::html_render_deep ctx r)
+ | TEX_FUN2h (_,f,a,b)::r -> (html_liberal (); (f a b)::html_render_deep ctx r)
+ | TEX_INFIXh (_,f,a,b)::r -> (html_liberal (); (f a b)::html_render_deep ctx r)
+ | TEX_CURLY ls::r -> html_render_deep ctx (ls @ r)
+ | TEX_DQ (a,b)::r -> (let bs = html_render_flat ctx [b] in match html_render_size ctx a with
+ true, s -> "","<span style='font-size: x-large; font-family: serif;'>"^s^"</span>",bs
+ | false, s -> "",(s^"<sub>"^bs^"</sub>"),"")::html_render_deep ctx r
+ | TEX_UQ (a,b)::r -> (let bs = html_render_flat ctx [b] in match html_render_size ctx a with
+ true, s -> bs,"<span style='font-size: x-large; font-family: serif;'>"^s^"</span>",""
+ | false, s -> "",(s^"<sup>"^bs^"</sup>"),"")::html_render_deep ctx r
+ | TEX_FQ (a,b,c)::r -> (html_liberal ();
+ (let bs = html_render_flat ctx [b] in let cs = html_render_flat ctx [c] in
+ match html_render_size ctx a with
+ true, s -> (cs,"<span style='font-size: x-large; font-family: serif;'>"^s^"</span>",bs)
+ | false, s -> ("",(s^"<sub>"^bs^"</sub><sup>"^cs^"</sup>"),""))::html_render_deep ctx r)
+ | TEX_DQN (a)::r -> (let bs = html_render_flat ctx [a] in "",("<sub>"^bs^"</sub>"),"")::html_render_deep ctx r
+ | TEX_UQN (a)::r -> (let bs = html_render_flat ctx [a] in "",("<sup>"^bs^"</sup>"),"")::html_render_deep ctx r
+ | TEX_FQN (a,b)::r -> (html_liberal ();
+ (let bs = html_render_flat ctx [a] in let cs = html_render_flat ctx [b] in
+ ("",("<sub>"^bs^"</sub><sup>"^cs^"</sup>"),""))::html_render_deep ctx r)
+ | TEX_FUN1hl (_,(f1,f2),a)::r -> ("",f1,"")::(html_render_deep ctx [a]) @ ("",f2,"")::html_render_deep ctx r
+ | TEX_FUN1hf (_,ff,a)::r -> (html_render_deep (new_ctx ff) [a]) @ html_render_deep ctx r
+ | TEX_DECLh (_,ff,a)::r -> (html_render_deep (new_ctx ff) a) @ html_render_deep ctx r
+ | TEX_BOX (_,s)::r -> ("",s,"")::html_render_deep ctx r
+ | TEX_LITERAL (TEX_ONLY _)::_ -> raise Too_difficult_for_html
+ | TEX_FUN1 _::_ -> raise Too_difficult_for_html
+ | TEX_FUN2 _::_ -> raise Too_difficult_for_html
+ | TEX_FUN2nb _::_ -> raise Too_difficult_for_html
+ | TEX_FUN2sq _::_ -> raise Too_difficult_for_html
+ | TEX_INFIX _::_ -> raise Too_difficult_for_html
+ | TEX_MATRIX _::_ -> raise Too_difficult_for_html
+ | TEX_LR _::_ -> raise Too_difficult_for_html
+ | TEX_BIG _::_ -> raise Too_difficult_for_html
+ | [] -> []
+
+let rec html_render_table = function
+ sf,u,d,("",a,"")::("",b,"")::r -> html_render_table (sf,u,d,(("",a^b,"")::r))
+ | sf,u,d,(("",a,"") as c)::r -> html_render_table (c::sf,u,d,r)
+ | sf,u,d,((_,a,"") as c)::r -> html_render_table (c::sf,true,d,r)
+ | sf,u,d,(("",a,_) as c)::r -> html_render_table (c::sf,u,true,r)
+ | sf,u,d,((_,a,_) as c)::r -> html_render_table (c::sf,true,true,r)
+ | sf,false,false,[] -> mapjoin (function (u,m,d) -> m) (List.rev sf)
+ | sf,true,false,[] -> let ustr,mstr = List.fold_left (fun (us,ms) (u,m,d) -> (us^"<td>"^u^"</td>",ms^"<td>"^u^"</td>"))
+ ("","") (List.rev sf) in
+ "\n<table>\n" ^
+ "\t\t<tr style='text-align: center; vertical-align: bottom;'>" ^ ustr ^ "</tr>\n" ^
+ "\t\t<tr style='text-align: center;'>" ^ mstr ^ "</tr>\n" ^
+ "</table>\n"
+ | sf,false,true,[] -> let mstr,dstr = List.fold_left (fun (ms,ds) (u,m,d) -> (ms^"<td>"^m^"</td>",ds^"<td>"^d^"</td>"))
+ ("","") (List.rev sf) in
+ "\n<table>\n" ^
+ "\t\t<tr style='text-align: center;'>" ^ mstr ^ "</tr>\n" ^
+ "\t\t<tr style='text-align: center; vertical-align: top;'>" ^ dstr ^ "</tr>\n" ^
+ "</table>\n"
+ | sf,true,true,[] -> let ustr,mstr,dstr = List.fold_left (fun (us,ms,ds) (u,m,d) ->
+ (us^"<td>"^u^"</td>",ms^"<td>"^m^"</td>",ds^"<td>"^d^"</td>")) ("","","") (List.rev sf) in
+ "\n<table>\n" ^
+ "\t\t<tr style='text-align: center; vertical-align: bottom;'>" ^ ustr ^ "</tr>\n" ^
+ "\t\t<tr style='text-align: center;'>" ^ mstr ^ "</tr>\n" ^
+ "\t\t<tr style='text-align: center; vertical-align: top;'>" ^ dstr ^ "</tr>\n" ^
+ "</table>\n"
+
+let html_render tree = html_render_table ([],false,false,html_render_deep CTX_NORMAL tree)
+
+let render tree = try Some (html_render tree) with _ -> None
diff --git a/math/html.mli b/math/html.mli
new file mode 100644
index 000000000000..00b41cf4391b
--- /dev/null
+++ b/math/html.mli
@@ -0,0 +1,5 @@
+val render : Tex.t list -> string option
+val html_render : Tex.t list -> string
+
+type conservativeness_t = CONSERVATIVE | MODERATE | LIBERAL
+val conservativeness : conservativeness_t ref
diff --git a/math/lexer.mll b/math/lexer.mll
new file mode 100644
index 000000000000..4dd31e0ecc0c
--- /dev/null
+++ b/math/lexer.mll
@@ -0,0 +1,107 @@
+{
+ open Parser
+ open Render_info
+ open Tex
+}
+let space = [' ' '\t' '\n' '\r']
+let alpha = ['a'-'z' 'A'-'Z']
+let literal_id = ['a'-'z' 'A'-'Z']
+let literal_mn = ['0'-'9']
+let literal_uf_lt = [',' ':' ';' '?' '!' '\'']
+let delimiter_uf_lt = ['(' ')' '.']
+let literal_uf_op = ['+' '-' '*' '=']
+let delimiter_uf_op = ['/' '|']
+let boxchars = ['0'-'9' 'a'-'z' 'A'-'Z' '+' '-' '*' ',' '=' '(' ')' ':' '/' ';' '?' '.' '!' ' ' '\128'-'\255']
+let aboxchars = ['0'-'9' 'a'-'z' 'A'-'Z' '+' '-' '*' ',' '=' '(' ')' ':' '/' ';' '?' '.' '!' ' ']
+
+rule token = parse
+ space + { token lexbuf }
+ | "\\text" space * '{' boxchars + '}'
+ { Texutil.tex_use_ams (); let str = Lexing.lexeme lexbuf in
+ let n = String.index str '{' + 1 in
+ BOX ("\\text", String.sub str n (String.length str - n - 1)) }
+ | "\\mbox" space * '{' aboxchars + '}'
+ { let str = Lexing.lexeme lexbuf in
+ let n = String.index str '{' + 1 in
+ BOX ("\\mbox", String.sub str n (String.length str - n - 1)) }
+ | "\\hbox" space * '{' aboxchars + '}'
+ { let str = Lexing.lexeme lexbuf in
+ let n = String.index str '{' + 1 in
+ BOX ("\\hbox", String.sub str n (String.length str - n - 1)) }
+ | "\\vbox" space * '{' aboxchars + '}'
+ { let str = Lexing.lexeme lexbuf in
+ let n = String.index str '{' + 1 in
+ BOX ("\\vbox", String.sub str n (String.length str - n - 1)) }
+ | "\\mbox" space * '{' boxchars + '}'
+ { let str = Lexing.lexeme lexbuf in
+ let n = String.index str '{' + 1 in
+ Texutil.tex_use_nonascii();
+ BOX ("\\mbox", String.sub str n (String.length str - n - 1)) }
+ | "\\hbox" space * '{' boxchars + '}'
+ { let str = Lexing.lexeme lexbuf in
+ let n = String.index str '{' + 1 in
+ Texutil.tex_use_nonascii();
+ BOX ("\\hbox", String.sub str n (String.length str - n - 1)) }
+ | "\\vbox" space * '{' boxchars + '}'
+ { let str = Lexing.lexeme lexbuf in
+ let n = String.index str '{' + 1 in
+ Texutil.tex_use_nonascii();
+ BOX ("\\vbox", String.sub str n (String.length str - n - 1)) }
+ | literal_id { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_IT, str,str,MI,str)) }
+ | literal_mn { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_RM, str,str,MN,str)) }
+ | literal_uf_lt { let str = Lexing.lexeme lexbuf in LITERAL (HTMLABLEC (FONT_UFH, str,str)) }
+ | delimiter_uf_lt { let str = Lexing.lexeme lexbuf in DELIMITER (HTMLABLEC (FONT_UFH, str,str)) }
+ | "-" { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_UFH,"-"," &minus; ",MO,str))}
+ | literal_uf_op { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_UFH, str," "^str^" ",MO,str)) }
+ | delimiter_uf_op { let str = Lexing.lexeme lexbuf in DELIMITER (MHTMLABLEC (FONT_UFH, str," "^str^" ",MO,str)) }
+ | "\\" alpha + { Texutil.find (Lexing.lexeme lexbuf) }
+ | "\\sqrt" space * "[" { FUN_AR1opt "\\sqrt" }
+ | "\\xleftarrow" space * "[" { Texutil.tex_use_ams(); FUN_AR1opt "\\xleftarrow" }
+ | "\\xrightarrow" space * "[" { Texutil.tex_use_ams(); FUN_AR1opt "\\xrightarrow" }
+ | "\\," { LITERAL (HTMLABLE (FONT_UF, "\\,","&nbsp;")) }
+ | "\\ " { LITERAL (HTMLABLE (FONT_UF, "\\ ","&nbsp;")) }
+ | "\\;" { LITERAL (HTMLABLE (FONT_UF, "\\;","&nbsp;")) }
+ | "\\!" { LITERAL (TEX_ONLY "\\!") }
+ | "\\{" { DELIMITER (HTMLABLEC(FONT_UFH,"\\{","{")) }
+ | "\\}" { DELIMITER (HTMLABLEC(FONT_UFH,"\\}","}")) }
+ | "\\|" { DELIMITER (HTMLABLE (FONT_UFH,"\\|","||")) }
+ | "\\_" { LITERAL (HTMLABLEC(FONT_UFH,"\\_","_")) }
+ | "\\#" { LITERAL (HTMLABLE (FONT_UFH,"\\#","#")) }
+ | "\\%" { LITERAL (HTMLABLE (FONT_UFH,"\\%","%")) }
+ | "\\$" { LITERAL (HTMLABLE (FONT_UFH,"\\$","$")) }
+ | "&" { NEXT_CELL }
+ | "\\\\" { NEXT_ROW }
+ | "\\begin{matrix}" { Texutil.tex_use_ams(); BEGIN__MATRIX }
+ | "\\end{matrix}" { END__MATRIX }
+ | "\\begin{pmatrix}" { Texutil.tex_use_ams(); BEGIN_PMATRIX }
+ | "\\end{pmatrix}" { END_PMATRIX }
+ | "\\begin{bmatrix}" { Texutil.tex_use_ams(); BEGIN_BMATRIX }
+ | "\\end{bmatrix}" { END_BMATRIX }
+ | "\\begin{Bmatrix}" { Texutil.tex_use_ams(); BEGIN_BBMATRIX }
+ | "\\end{Bmatrix}" { END_BBMATRIX }
+ | "\\begin{vmatrix}" { Texutil.tex_use_ams(); BEGIN_VMATRIX }
+ | "\\end{vmatrix}" { END_VMATRIX }
+ | "\\begin{Vmatrix}" { Texutil.tex_use_ams(); BEGIN_VVMATRIX }
+ | "\\end{Vmatrix}" { END_VVMATRIX }
+ | "\\begin{array}" { Texutil.tex_use_ams(); BEGIN_ARRAY }
+ | "\\end{array}" { END_ARRAY }
+ | "\\begin{align}" { Texutil.tex_use_ams(); BEGIN_ALIGN }
+ | "\\end{align}" { END_ALIGN }
+ | "\\begin{alignat}" { Texutil.tex_use_ams(); BEGIN_ALIGNAT }
+ | "\\end{alignat}" { END_ALIGNAT }
+ | "\\begin{smallmatrix}" { Texutil.tex_use_ams(); BEGIN_SMALLMATRIX }
+ | "\\end{smallmatrix}" { END_SMALLMATRIX }
+ | "\\begin{cases}" { Texutil.tex_use_ams(); BEGIN_CASES }
+ | "\\end{cases}" { END_CASES }
+ | '>' { LITERAL (HTMLABLEC(FONT_UFH,">"," &gt; ")) }
+ | '<' { LITERAL (HTMLABLEC(FONT_UFH,"<"," &lt; ")) }
+ | '%' { LITERAL (HTMLABLEC(FONT_UFH,"\\%","%")) }
+ | '$' { LITERAL (HTMLABLEC(FONT_UFH,"\\$","$")) }
+ | '~' { LITERAL (HTMLABLE (FONT_UF, "~","&nbsp;")) }
+ | '[' { DELIMITER (HTMLABLEC(FONT_UFH,"[","[")) }
+ | ']' { SQ_CLOSE }
+ | '{' { CURLY_OPEN }
+ | '}' { CURLY_CLOSE }
+ | '^' { SUP }
+ | '_' { SUB }
+ | eof { EOF }
diff --git a/math/mathml.ml b/math/mathml.ml
new file mode 100644
index 000000000000..b6c76af26e6a
--- /dev/null
+++ b/math/mathml.ml
@@ -0,0 +1,20 @@
+open Tex
+open Render_info
+
+type t = TREE_MN of string | TREE_MO of string | TREE_MI of string
+
+let rec make_mathml_tree = function
+ TREE_MN a::otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MN,b))::itr -> make_mathml_tree(TREE_MN (a^b)::otr,itr)
+ | otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MN,a))::itr -> make_mathml_tree(TREE_MN a::otr,itr)
+ | otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MO,a))::itr -> make_mathml_tree(TREE_MO a::otr,itr)
+ | otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MI,a))::itr -> make_mathml_tree(TREE_MI a::otr,itr)
+ | otr,TEX_CURLY(crl)::itr -> make_mathml_tree(otr,crl@itr)
+ | otr,[] -> List.rev otr
+ | _ -> failwith "failed to render mathml"
+
+let render_mathml_tree = function
+ TREE_MN s -> "<mn>"^s^"</mn>"
+ | TREE_MI s -> "<mi>"^s^"</mi>"
+ | TREE_MO s -> "<mo>"^s^"</mo>"
+
+let render tree = try Some (Util.mapjoin render_mathml_tree (make_mathml_tree ([],tree))) with _ -> None
diff --git a/math/mathml.mli b/math/mathml.mli
new file mode 100644
index 000000000000..fcc2cd4cf169
--- /dev/null
+++ b/math/mathml.mli
@@ -0,0 +1 @@
+val render : Tex.t list -> string option
diff --git a/math/parser.mly b/math/parser.mly
new file mode 100644
index 000000000000..29882fb4066f
--- /dev/null
+++ b/math/parser.mly
@@ -0,0 +1,118 @@
+%{
+ open Tex
+ open Render_info
+
+ let sq_close_ri = HTMLABLEC(FONT_UFH,"]", "]")
+%}
+%token <Render_info.t> LITERAL DELIMITER
+%token <string> FUN_AR2 FUN_INFIX FUN_AR1 DECL FUN_AR1opt BIG FUN_AR2nb
+%token <string*string> BOX
+%token <string*(string*string)> FUN_AR1hl
+%token <string*Render_info.font_force> FUN_AR1hf DECLh
+%token <string*(Tex.t->Tex.t->string*string*string)> FUN_AR2h
+%token <string*(Tex.t list->Tex.t list->string*string*string)> FUN_INFIXh
+%token EOF CURLY_OPEN CURLY_CLOSE SUB SUP SQ_CLOSE NEXT_CELL NEXT_ROW
+%token BEGIN__MATRIX BEGIN_PMATRIX BEGIN_BMATRIX BEGIN_BBMATRIX BEGIN_VMATRIX BEGIN_VVMATRIX BEGIN_CASES BEGIN_ARRAY BEGIN_ALIGN BEGIN_ALIGNAT BEGIN_SMALLMATRIX
+%token END__MATRIX END_PMATRIX END_BMATRIX END_BBMATRIX END_VMATRIX END_VVMATRIX END_CASES END_ARRAY END_ALIGN END_ALIGNAT END_SMALLMATRIX
+%token LEFT RIGHT
+%type <Tex.t list> tex_expr
+%start tex_expr
+
+%%
+tex_expr:
+ expr EOF { $1 }
+ | ne_expr FUN_INFIX ne_expr EOF
+ { [TEX_INFIX($2,$1,$3)] }
+ | ne_expr FUN_INFIXh ne_expr EOF
+ { let t,h=$2 in [TEX_INFIXh(t,h,$1,$3)] }
+expr:
+ /* */ { [] }
+ | ne_expr { $1 }
+ne_expr:
+ lit_aq expr { $1 :: $2 }
+ | litsq_aq expr { $1 :: $2 }
+ | DECLh expr { let t,h = $1 in [TEX_DECLh(t,h,$2)] }
+litsq_aq:
+ litsq_zq { $1 }
+ | litsq_dq { let base,downi = $1 in TEX_DQ(base,downi) }
+ | litsq_uq { let base,upi = $1 in TEX_UQ(base,upi)}
+ | litsq_fq { $1 }
+litsq_fq:
+ litsq_dq SUP lit { let base,downi = $1 in TEX_FQ(base,downi,$3) }
+ | litsq_uq SUB lit { let base,upi = $1 in TEX_FQ(base,$3,upi) }
+litsq_uq:
+ litsq_zq SUP lit { $1,$3 }
+litsq_dq:
+ litsq_zq SUB lit { $1,$3 }
+litsq_zq:
+ | SQ_CLOSE { TEX_LITERAL sq_close_ri }
+expr_nosqc:
+ /* */ { [] }
+ | lit_aq expr_nosqc { $1 :: $2 }
+lit_aq:
+ lit { $1 }
+ | lit_dq { let base,downi = $1 in TEX_DQ(base,downi) }
+ | lit_uq { let base,upi = $1 in TEX_UQ(base,upi)}
+ | lit_dqn { TEX_DQN($1) }
+ | lit_uqn { TEX_UQN($1) }
+ | lit_fq { $1 }
+
+lit_fq:
+ lit_dq SUP lit { let base,downi = $1 in TEX_FQ(base,downi,$3) }
+ | lit_uq SUB lit { let base,upi = $1 in TEX_FQ(base,$3,upi) }
+ | lit_dqn SUP lit { TEX_FQN($1, $3) }
+
+lit_uq:
+ lit SUP lit { $1,$3 }
+lit_dq:
+ lit SUB lit { $1,$3 }
+lit_uqn:
+ SUP lit { $2 }
+lit_dqn:
+ SUB lit { $2 }
+
+
+left:
+ LEFT DELIMITER { $2 }
+ | LEFT SQ_CLOSE { sq_close_ri }
+right:
+ RIGHT DELIMITER { $2 }
+ | RIGHT SQ_CLOSE { sq_close_ri }
+lit:
+ LITERAL { TEX_LITERAL $1 }
+ | DELIMITER { TEX_LITERAL $1 }
+ | BIG DELIMITER { TEX_BIG ($1,$2) }
+ | BIG SQ_CLOSE { TEX_BIG ($1,sq_close_ri) }
+ | left expr right { TEX_LR ($1,$3,$2) }
+ | FUN_AR1 lit { TEX_FUN1($1,$2) }
+ | FUN_AR1hl lit { let t,h=$1 in TEX_FUN1hl(t,h,$2) }
+ | FUN_AR1hf lit { let t,h=$1 in TEX_FUN1hf(t,h,$2) }
+ | FUN_AR1opt expr_nosqc SQ_CLOSE lit { TEX_FUN2sq($1,TEX_CURLY $2,$4) }
+ | FUN_AR2 lit lit { TEX_FUN2($1,$2,$3) }
+ | FUN_AR2nb lit lit { TEX_FUN2nb($1,$2,$3) }
+ | FUN_AR2h lit lit { let t,h=$1 in TEX_FUN2h(t,h,$2,$3) }
+ | BOX { let bt,s = $1 in TEX_BOX (bt,s) }
+ | CURLY_OPEN expr CURLY_CLOSE
+ { TEX_CURLY $2 }
+ | CURLY_OPEN ne_expr FUN_INFIX ne_expr CURLY_CLOSE
+ { TEX_INFIX($3,$2,$4) }
+ | CURLY_OPEN ne_expr FUN_INFIXh ne_expr CURLY_CLOSE
+ { let t,h=$3 in TEX_INFIXh(t,h,$2,$4) }
+ | BEGIN__MATRIX matrix END__MATRIX { TEX_MATRIX ("matrix", $2) }
+ | BEGIN_PMATRIX matrix END_PMATRIX { TEX_MATRIX ("pmatrix", $2) }
+ | BEGIN_BMATRIX matrix END_BMATRIX { TEX_MATRIX ("bmatrix", $2) }
+ | BEGIN_BBMATRIX matrix END_BBMATRIX { TEX_MATRIX ("Bmatrix", $2) }
+ | BEGIN_VMATRIX matrix END_VMATRIX { TEX_MATRIX ("vmatrix", $2) }
+ | BEGIN_VVMATRIX matrix END_VVMATRIX { TEX_MATRIX ("Vmatrix", $2) }
+ | BEGIN_ARRAY matrix END_ARRAY { TEX_MATRIX ("array", $2) }
+ | BEGIN_ALIGN matrix END_ALIGN { TEX_MATRIX ("aligned", $2) }
+ | BEGIN_ALIGNAT matrix END_ALIGNAT { TEX_MATRIX ("alignedat", $2) }
+ | BEGIN_SMALLMATRIX matrix END_SMALLMATRIX { TEX_MATRIX ("smallmatrix", $2) }
+ | BEGIN_CASES matrix END_CASES { TEX_MATRIX ("cases", $2) }
+matrix:
+ line { [$1] }
+ | line NEXT_ROW matrix { $1::$3 }
+line:
+ expr { [$1] }
+ | expr NEXT_CELL line { $1::$3 }
+;;
diff --git a/math/render.ml b/math/render.ml
new file mode 100644
index 000000000000..e9a21687072d
--- /dev/null
+++ b/math/render.ml
@@ -0,0 +1,40 @@
+let cmd_dvips tmpprefix = "dvips -R -E " ^ tmpprefix ^ ".dvi -f >" ^ tmpprefix ^ ".ps"
+let cmd_latex tmpprefix = "latex " ^ tmpprefix ^ ".tex >/dev/null"
+(* Putting -transparent white in converts arguments will sort-of give you transperancy *)
+let cmd_convert tmpprefix finalpath = "convert -quality 100 -density 120 " ^ tmpprefix ^ ".ps " ^ finalpath ^ " >/dev/null 2>/dev/null"
+(* Putting -bg Transparent in dvipng's arguments will give full-alpha transparency *)
+(* Note that IE have problems with such PNGs and need an additional javascript snippet *)
+(* Putting -bg transparent in dvipng's arguments will give binary transparency *)
+let cmd_dvipng tmpprefix finalpath = "dvipng -gamma 1.5 -D 120 -T tight --strict " ^ tmpprefix ^ ".dvi -o " ^ finalpath ^ " >/dev/null 2>/dev/null"
+
+exception ExternalCommandFailure of string
+
+let render tmppath finalpath outtex md5 =
+ let tmpprefix0 = (string_of_int (Unix.getpid ()))^"_"^md5 in
+ let tmpprefix = (tmppath^"/"^tmpprefix0) in
+ let unlink_all () =
+ begin
+ (* Commenting this block out will aid in debugging *)
+ Sys.remove (tmpprefix ^ ".dvi");
+ Sys.remove (tmpprefix ^ ".aux");
+ Sys.remove (tmpprefix ^ ".log");
+ Sys.remove (tmpprefix ^ ".tex");
+ if Sys.file_exists (tmpprefix ^ ".ps")
+ then Sys.remove (tmpprefix ^ ".ps");
+ end in
+ let f = (Util.open_out_unless_exists (tmpprefix ^ ".tex")) in
+ begin
+ output_string f (Texutil.get_preface ());
+ output_string f outtex;
+ output_string f (Texutil.get_footer ());
+ close_out f;
+ if Util.run_in_other_directory tmppath (cmd_latex tmpprefix0) != 0
+ then (unlink_all (); raise (ExternalCommandFailure "latex"))
+ else if (Sys.command (cmd_dvipng tmpprefix (finalpath^"/"^md5^".png")) != 0)
+ then (if (Sys.command (cmd_dvips tmpprefix) != 0)
+ then (unlink_all (); raise (ExternalCommandFailure "dvips"))
+ else if (Sys.command (cmd_convert tmpprefix (finalpath^"/"^md5^".png")) != 0)
+ then (unlink_all (); raise (ExternalCommandFailure "convert"))
+ else unlink_all ())
+ else unlink_all ()
+ end
diff --git a/math/render_info.mli b/math/render_info.mli
new file mode 100644
index 000000000000..d5e7fde99ed9
--- /dev/null
+++ b/math/render_info.mli
@@ -0,0 +1,20 @@
+type font_force =
+ FONTFORCE_IT
+ | FONTFORCE_RM
+type font_class =
+ FONT_IT (* IT default, may be forced to be RM *)
+ | FONT_RM (* RM default, may be forced to be IT *)
+ | FONT_UF (* not affected by IT/RM setting *)
+ | FONT_RTI (* RM - any, IT - not available in HTML *)
+ | FONT_UFH (* in TeX UF, in HTML RM *)
+type math_class =
+ MN
+ | MI
+ | MO
+type t =
+ HTMLABLEC of font_class * string * string
+ | HTMLABLEM of font_class * string * string
+ | HTMLABLE of font_class * string * string
+ | MHTMLABLEC of font_class * string * string * math_class * string
+ | HTMLABLE_BIG of string * string
+ | TEX_ONLY of string
diff --git a/math/tex.mli b/math/tex.mli
new file mode 100644
index 000000000000..f2ed37cf077a
--- /dev/null
+++ b/math/tex.mli
@@ -0,0 +1,23 @@
+type t =
+ TEX_LITERAL of Render_info.t
+ | TEX_CURLY of t list
+ | TEX_FQ of t * t * t
+ | TEX_DQ of t * t
+ | TEX_UQ of t * t
+ | TEX_FQN of t * t
+ | TEX_DQN of t
+ | TEX_UQN of t
+ | TEX_LR of Render_info.t * Render_info.t * t list
+ | TEX_BOX of string * string
+ | TEX_BIG of string * Render_info.t
+ | TEX_FUN1 of string * t
+ | TEX_FUN2 of string * t * t
+ | TEX_FUN2nb of string * t * t
+ | TEX_INFIX of string * t list * t list
+ | TEX_FUN2sq of string * t * t
+ | TEX_FUN1hl of string * (string * string) * t
+ | TEX_FUN1hf of string * Render_info.font_force * t
+ | TEX_FUN2h of string * (t -> t -> string * string * string) * t * t
+ | TEX_INFIXh of string * (t list -> t list -> string * string * string) * t list * t list
+ | TEX_MATRIX of string * t list list list
+ | TEX_DECLh of string * Render_info.font_force * t list
diff --git a/math/texutil.ml b/math/texutil.ml
new file mode 100644
index 000000000000..f9ebb2589596
--- /dev/null
+++ b/math/texutil.ml
@@ -0,0 +1,720 @@
+open Parser
+open Render_info
+open Tex
+open Util
+
+let tex_part = function
+ HTMLABLE (_,t,_) -> t
+ | HTMLABLEM (_,t,_) -> t
+ | HTMLABLEC (_,t,_) -> t
+ | MHTMLABLEC (_,t,_,_,_) -> t
+ | HTMLABLE_BIG (t,_) -> t
+ | TEX_ONLY t -> t
+let rec render_tex = function
+ TEX_FQ (a,b,c) -> (render_tex a) ^ "_{" ^ (render_tex b) ^ "}^{" ^ (render_tex c) ^ "}"
+ | TEX_DQ (a,b) -> (render_tex a) ^ "_{" ^ (render_tex b) ^ "}"
+ | TEX_UQ (a,b) -> (render_tex a) ^ "^{" ^ (render_tex b) ^ "}"
+ | TEX_FQN (a,b) -> "_{" ^ (render_tex a) ^ "}^{" ^ (render_tex b) ^ "}"
+ | TEX_DQN (a) -> "_{" ^ (render_tex a) ^ "}"
+ | TEX_UQN (a) -> "^{" ^ (render_tex a) ^ "}"
+ | TEX_LITERAL s -> tex_part s
+ | TEX_FUN1 (f,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
+ | TEX_FUN1hl (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
+ | TEX_FUN1hf (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
+ | TEX_DECLh (f,_,a) -> "{" ^ f ^ "{" ^ (mapjoin render_tex a) ^ "}}"
+ | TEX_FUN2 (f,a,b) -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
+ | TEX_FUN2nb (f,a,b) -> f ^ (render_tex a) ^ (render_tex b)
+ | TEX_FUN2h (f,_,a,b) -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
+ | TEX_FUN2sq (f,a,b) -> "{" ^ f ^ "[ " ^ (render_tex a) ^ "]" ^ (render_tex b) ^ "}"
+ | TEX_CURLY (tl) -> "{" ^ (mapjoin render_tex tl) ^ "}"
+ | TEX_INFIX (s,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
+ | TEX_INFIXh (s,_,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
+ | TEX_BOX (bt,s) -> "{"^bt^"{" ^ s ^ "}}"
+ | TEX_BIG (bt,d) -> "{"^bt^(tex_part d)^"}"
+ | TEX_MATRIX (t,rows) -> "{\\begin{"^t^"}"^(mapjoine "\\\\" (mapjoine "&" (mapjoin render_tex)) rows)^"\\end{"^t^"}}"
+ | TEX_LR (l,r,tl) -> "\\left "^(tex_part l)^(mapjoin render_tex tl)^"\\right "^(tex_part r)
+
+
+(* Dynamic loading*)
+type encoding_t = LATIN1 | LATIN2 | UTF8
+
+let modules_ams = ref false
+let modules_nonascii = ref false
+let modules_encoding = ref UTF8
+let modules_color = ref false
+
+let tex_use_ams () = modules_ams := true
+let tex_use_nonascii () = modules_nonascii := true
+let tex_use_color () = modules_color := true
+let tex_mod_reset () = (modules_ams := false; modules_nonascii := false; modules_encoding := UTF8; modules_color := false)
+
+let get_encoding = function
+ UTF8 -> "\\usepackage{ucs}\n\\usepackage[utf8]{inputenc}\n"
+ | LATIN1 -> "\\usepackage[latin1]{inputenc}\n"
+ | LATIN2 -> "\\usepackage[latin2]{inputenc}\n"
+
+let get_preface () = "\\nonstopmode\n\\documentclass[12pt]{article}\n" ^
+ (if !modules_nonascii then get_encoding !modules_encoding else "") ^
+ (if !modules_ams then "\\usepackage{amsmath}\n\\usepackage{amsfonts}\n\\usepackage{amssymb}\n" else "") ^
+ (if !modules_color then "\\usepackage[dvips,usenames]{color}\n" else "") ^
+ "\\pagestyle{empty}\n\\begin{document}\n$$\n"
+let get_footer () = "\n$$\n\\end{document}\n"
+
+let set_encoding = function
+ "ISO-8859-1" -> modules_encoding := LATIN1
+ | "iso-8859-1" -> modules_encoding := LATIN1
+ | "ISO-8859-2" -> modules_encoding := LATIN2
+ | _ -> modules_encoding := UTF8
+
+(* Turn that into hash table lookup *)
+exception Illegal_tex_function of string
+
+let find = function
+ "\\alpha" -> LITERAL (HTMLABLEC (FONT_UF, "\\alpha ", "&alpha;"))
+ | "\\Alpha" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{A}", "&Alpha;")))
+ | "\\beta" -> LITERAL (HTMLABLEC (FONT_UF, "\\beta ", "&beta;"))
+ | "\\Beta" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{B}", "&Beta;")))
+ | "\\gamma" -> LITERAL (HTMLABLEC (FONT_UF, "\\gamma ", "&gamma;"))
+ | "\\Gamma" -> LITERAL (HTMLABLEC (FONT_UF, "\\Gamma ", "&Gamma;"))
+ | "\\delta" -> LITERAL (HTMLABLEC (FONT_UF, "\\delta ", "&delta;"))
+ | "\\Delta" -> LITERAL (HTMLABLEC (FONT_UF, "\\Delta ", "&Delta;"))
+ | "\\epsilon" -> LITERAL (HTMLABLEC (FONT_UF, "\\epsilon ", "&epsilon;"))
+ | "\\Epsilon" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{E}", "&Epsilon;")))
+ | "\\varepsilon" -> LITERAL (TEX_ONLY "\\varepsilon ")
+ | "\\zeta" -> LITERAL (HTMLABLEC (FONT_UF, "\\zeta ", "&zeta;"))
+ | "\\Zeta" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{Z}", "&Zeta;")))
+ | "\\eta" -> LITERAL (HTMLABLEC (FONT_UF, "\\eta ", "&eta;"))
+ | "\\Eta" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{H}", "&Eta;")))
+ | "\\theta" -> LITERAL (HTMLABLEC (FONT_UF, "\\theta ", "&theta;"))
+ | "\\Theta" -> LITERAL (HTMLABLEC (FONT_UF, "\\Theta ", "&Theta;"))
+ | "\\vartheta" -> LITERAL (HTMLABLE (FONT_UF, "\\vartheta ", "&thetasym;"))
+ | "\\thetasym" -> LITERAL (HTMLABLE (FONT_UF, "\\vartheta ", "&thetasym;"))
+ | "\\iota" -> LITERAL (HTMLABLEC (FONT_UF, "\\iota ", "&iota;"))
+ | "\\Iota" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{I}", "&Iota;")))
+ | "\\kappa" -> LITERAL (HTMLABLEC (FONT_UF, "\\kappa ", "&kappa;"))
+ | "\\Kappa" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{K}", "&Kappa;")))
+ | "\\lambda" -> LITERAL (HTMLABLEC (FONT_UF, "\\lambda ", "&lambda;"))
+ | "\\Lambda" -> LITERAL (HTMLABLEC (FONT_UF, "\\Lambda ", "&Lambda;"))
+ | "\\mu" -> LITERAL (HTMLABLEC (FONT_UF, "\\mu ", "&mu;"))
+ | "\\Mu" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{M}", "&Mu;")))
+ | "\\nu" -> LITERAL (HTMLABLEC (FONT_UF, "\\nu ", "&nu;"))
+ | "\\Nu" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{N}", "&Nu;")))
+ | "\\pi" -> LITERAL (HTMLABLEC (FONT_UF, "\\pi ", "&pi;"))
+ | "\\Pi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Pi ", "&Pi;"))
+ | "\\varpi" -> LITERAL (TEX_ONLY "\\varpi ")
+ | "\\rho" -> LITERAL (HTMLABLEC (FONT_UF, "\\rho ", "&rho;"))
+ | "\\Rho" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{P}", "&Rho;")))
+ | "\\varrho" -> LITERAL (TEX_ONLY "\\varrho ")
+ | "\\sim" -> LITERAL (HTMLABLEC (FONT_UF, "\\sim ", "&tilde;"))
+ | "\\sigma" -> LITERAL (HTMLABLEC (FONT_UF, "\\sigma ", "&sigma;"))
+ | "\\Sigma" -> LITERAL (HTMLABLEC (FONT_UF, "\\Sigma ", "&Sigma;"))
+ | "\\varsigma" -> LITERAL (TEX_ONLY "\\varsigma ")
+ | "\\tau" -> LITERAL (HTMLABLEC (FONT_UF, "\\tau ", "&tau;"))
+ | "\\Tau" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{T}", "&Tau;")))
+ | "\\upsilon" -> LITERAL (HTMLABLEC (FONT_UF, "\\upsilon ", "&upsilon;"))
+ | "\\Upsilon" -> LITERAL (HTMLABLEC (FONT_UF, "\\Upsilon ", "&Upsilon;"))
+ | "\\phi" -> LITERAL (HTMLABLEC (FONT_UF, "\\phi ", "&phi;"))
+ | "\\Phi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Phi ", "&Phi;"))
+ | "\\varphi" -> LITERAL (TEX_ONLY "\\varphi ")
+ | "\\chi" -> LITERAL (HTMLABLEC (FONT_UF, "\\chi ", "&chi;"))
+ | "\\Chi" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
+ "\\mathrm{X}", "&Chi;")))
+ | "\\psi" -> LITERAL (HTMLABLEC (FONT_UF, "\\psi ", "&psi;"))
+ | "\\Psi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Psi ", "&Psi;"))
+ | "\\omega" -> LITERAL (HTMLABLEC (FONT_UF, "\\omega ", "&omega;"))
+ | "\\Omega" -> LITERAL (HTMLABLEC (FONT_UF, "\\Omega ", "&Omega;"))
+ | "\\xi" -> LITERAL (HTMLABLEC (FONT_UF, "\\xi ", "&xi;"))
+ | "\\Xi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Xi ", "&Xi;"))
+ | "\\aleph" -> LITERAL (HTMLABLE (FONT_UF, "\\aleph ", "&alefsym;"))
+ | "\\alef" -> LITERAL (HTMLABLE (FONT_UF, "\\aleph ", "&alefsym;"))
+ | "\\alefsym" -> LITERAL (HTMLABLE (FONT_UF, "\\aleph ", "&alefsym;"))
+ | "\\larr" -> LITERAL (HTMLABLEM (FONT_UF, "\\leftarrow ", "&larr;"))
+ | "\\leftarrow" -> LITERAL (HTMLABLEM (FONT_UF, "\\leftarrow ", "&larr;"))
+ | "\\rarr" -> LITERAL (HTMLABLEM (FONT_UF, "\\rightarrow ", "&rarr;"))
+ | "\\to" -> LITERAL (HTMLABLEM (FONT_UF, "\\to ", "&rarr;"))
+ | "\\gets" -> LITERAL (HTMLABLEM (FONT_UF, "\\gets ", "&larr;"))
+ | "\\rightarrow" -> LITERAL (HTMLABLEM (FONT_UF, "\\rightarrow ", "&rarr;"))
+ | "\\longleftarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\longleftarrow ", "&larr;"))
+ | "\\longrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\longrightarrow ", "&rarr;"))
+ | "\\Larr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftarrow ", "&lArr;"))
+ | "\\lArr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftarrow ", "&lArr;"))
+ | "\\Leftarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftarrow ", "&lArr;"))
+ | "\\Rarr" -> LITERAL (HTMLABLE (FONT_UF, "\\Rightarrow ", "&rArr;"))
+ | "\\rArr" -> LITERAL (HTMLABLE (FONT_UF, "\\Rightarrow ", "&rArr;"))
+ | "\\Rightarrow" -> LITERAL (HTMLABLEM (FONT_UF, "\\Rightarrow ", "&rArr;"))
+ | "\\mapsto" -> LITERAL (HTMLABLE (FONT_UF, "\\mapsto ", "&rarr;"))
+ | "\\longmapsto" -> LITERAL (HTMLABLE (FONT_UF, "\\longmapsto ", "&rarr;"))
+ | "\\Longleftarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Longleftarrow ", "&lArr;"))
+ | "\\Longrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Longrightarrow ", "&rArr;"))
+ | "\\uarr" -> DELIMITER (HTMLABLEM (FONT_UF, "\\uparrow ", "&uarr;"))
+ | "\\uparrow" -> DELIMITER (HTMLABLEM (FONT_UF, "\\uparrow ", "&uarr;"))
+ | "\\uArr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Uparrow ", "&uArr;"))
+ | "\\Uarr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Uparrow ", "&uArr;"))
+ | "\\Uparrow" -> DELIMITER (HTMLABLE (FONT_UF, "\\Uparrow ", "&uArr;"))
+ | "\\darr" -> DELIMITER (HTMLABLEM (FONT_UF, "\\downarrow ", "&darr;"))
+ | "\\downarrow" -> DELIMITER (HTMLABLEM (FONT_UF, "\\downarrow ", "&darr;"))
+ | "\\dArr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Downarrow ", "&dArr;"))
+ | "\\Darr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Downarrow ", "&dArr;"))
+ | "\\Downarrow" -> DELIMITER (HTMLABLE (FONT_UF, "\\Downarrow ", "&dArr;"))
+ | "\\updownarrow" -> DELIMITER (TEX_ONLY "\\updownarrow ")
+ | "\\Updownarrow" -> DELIMITER (TEX_ONLY "\\Updownarrow ")
+ | "\\ulcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\ulcorner "))
+ | "\\urcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\urcorner "))
+ | "\\llcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\llcorner "))
+ | "\\lrcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\lrcorner "))
+ | "\\twoheadleftarrow" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\twoheadleftarrow "))
+ | "\\twoheadrightarrow" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\twoheadrightarrow "))
+ | "\\xleftarrow" -> (tex_use_ams (); FUN_AR1 "\\xleftarrow ")
+ | "\\xrightarrow" -> (tex_use_ams (); FUN_AR1 "\\xrightarrow ")
+ | "\\rightleftharpoons" -> DELIMITER (TEX_ONLY "\\rightleftharpoons ")
+ | "\\leftrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\leftrightarrow ", "&harr;"))
+ | "\\lrarr" -> LITERAL (HTMLABLE (FONT_UF, "\\leftrightarrow ", "&harr;"))
+ | "\\harr" -> LITERAL (HTMLABLE (FONT_UF, "\\leftrightarrow ", "&harr;"))
+ | "\\Leftrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "&hArr;"))
+ | "\\Lrarr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "&hArr;"))
+ | "\\Harr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "&hArr;"))
+ | "\\lrArr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "&hArr;"))
+ | "\\hAar" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "&hArr;"))
+ | "\\longleftrightarrow"->LITERAL (HTMLABLE (FONT_UF, "\\longleftrightarrow ", "&harr;"))
+ | "\\Longleftrightarrow"->LITERAL (HTMLABLE (FONT_UF, "\\Longleftrightarrow ", "&harr;"))
+ | "\\iff" -> LITERAL (HTMLABLE (FONT_UF, "\\iff ", "&harr;"))
+ | "\\ll" -> LITERAL (TEX_ONLY "\\ll ")
+ | "\\gg" -> LITERAL (TEX_ONLY "\\gg ")
+ | "\\div" -> LITERAL (TEX_ONLY "\\div ")
+ | "\\searrow" -> LITERAL (TEX_ONLY "\\searrow ")
+ | "\\nearrow" -> LITERAL (TEX_ONLY "\\nearrow ")
+ | "\\swarrow" -> LITERAL (TEX_ONLY "\\swarrow ")
+ | "\\nwarrow" -> LITERAL (TEX_ONLY "\\nwarrow ")
+ | "\\simeq" -> LITERAL (TEX_ONLY "\\simeq ")
+ | "\\ast" -> LITERAL (TEX_ONLY "\\ast ")
+ | "\\star" -> LITERAL (TEX_ONLY "\\star ")
+ | "\\ell" -> LITERAL (TEX_ONLY "\\ell ")
+ | "\\P" -> LITERAL (TEX_ONLY "\\P ")
+ | "\\smile" -> LITERAL (TEX_ONLY "\\smile ")
+ | "\\frown" -> LITERAL (TEX_ONLY "\\frown ")
+ | "\\bigcap" -> LITERAL (TEX_ONLY "\\bigcap ")
+ | "\\bigodot" -> LITERAL (TEX_ONLY "\\bigodot ")
+ | "\\bigcup" -> LITERAL (TEX_ONLY "\\bigcup ")
+ | "\\bigotimes" -> LITERAL (TEX_ONLY "\\bigotimes ")
+ | "\\coprod" -> LITERAL (TEX_ONLY "\\coprod ")
+ | "\\bigsqcup" -> LITERAL (TEX_ONLY "\\bigsqcup ")
+ | "\\bigoplus" -> LITERAL (TEX_ONLY "\\bigoplus ")
+ | "\\bigvee" -> LITERAL (TEX_ONLY "\\bigvee ")
+ | "\\biguplus" -> LITERAL (TEX_ONLY "\\biguplus ")
+ | "\\oint" -> LITERAL (TEX_ONLY "\\oint ")
+ | "\\bigwedge" -> LITERAL (TEX_ONLY "\\bigwedge ")
+ | "\\models" -> LITERAL (TEX_ONLY "\\models ")
+ | "\\vdash" -> LITERAL (TEX_ONLY "\\vdash ")
+ | "\\triangle" -> LITERAL (TEX_ONLY "\\triangle ")
+ | "\\bowtie" -> LITERAL (TEX_ONLY "\\bowtie ")
+ | "\\wr" -> LITERAL (TEX_ONLY "\\wr ")
+ | "\\triangleleft" -> LITERAL (TEX_ONLY "\\triangleleft ")
+ | "\\triangleright" -> LITERAL (TEX_ONLY "\\triangleright ")
+ | "\\textvisiblespace" -> LITERAL (TEX_ONLY "\\textvisiblespace ")
+ | "\\ker" -> LITERAL (TEX_ONLY "\\ker ")
+ | "\\lim" -> LITERAL (TEX_ONLY "\\lim ")
+ | "\\limsup" -> LITERAL (TEX_ONLY "\\limsup ")
+ | "\\liminf" -> LITERAL (TEX_ONLY "\\liminf ")
+ | "\\sup" -> LITERAL (TEX_ONLY "\\sup ")
+ | "\\Pr" -> LITERAL (TEX_ONLY "\\Pr ")
+ | "\\hom" -> LITERAL (TEX_ONLY "\\hom ")
+ | "\\arg" -> LITERAL (TEX_ONLY "\\arg ")
+ | "\\dim" -> LITERAL (TEX_ONLY "\\dim ")
+ | "\\inf" -> LITERAL (TEX_ONLY "\\inf ")
+ | "\\circ" -> LITERAL (TEX_ONLY "\\circ ")
+ | "\\hbar" -> LITERAL (TEX_ONLY "\\hbar ")
+ | "\\imath" -> LITERAL (TEX_ONLY "\\imath ")
+ | "\\jmath" -> LITERAL (TEX_ONLY "\\jmath ")
+ | "\\lnot" -> LITERAL (TEX_ONLY "\\lnot ")
+ | "\\hookrightarrow" -> LITERAL (TEX_ONLY "\\hookrightarrow ")
+ | "\\hookleftarrow" -> LITERAL (TEX_ONLY "\\hookleftarrow ")
+ | "\\mp" -> LITERAL (TEX_ONLY "\\mp ")
+ | "\\approx" -> LITERAL (TEX_ONLY "\\approx ")
+ | "\\propto" -> LITERAL (TEX_ONLY "\\propto ")
+ | "\\flat" -> LITERAL (TEX_ONLY "\\flat ")
+ | "\\sharp" -> LITERAL (TEX_ONLY "\\sharp ")
+ | "\\natural" -> LITERAL (TEX_ONLY "\\natural ")
+ | "\\int" -> LITERAL (HTMLABLE_BIG ("\\int ", "&int;"))
+ | "\\sum" -> LITERAL (HTMLABLE_BIG ("\\sum ", "&sum;"))
+ | "\\prod" -> LITERAL (HTMLABLE_BIG ("\\prod ", "&prod;"))
+ | "\\vdots" -> LITERAL (TEX_ONLY "\\vdots ")
+ | "\\limits" -> LITERAL (TEX_ONLY "\\limits ")
+ | "\\nolimits" -> LITERAL (TEX_ONLY "\\nolimits ")
+ | "\\top" -> LITERAL (TEX_ONLY "\\top ")
+ | "\\sin" -> LITERAL (HTMLABLEC(FONT_UFH,"\\sin ","sin"))
+ | "\\cos" -> LITERAL (HTMLABLEC(FONT_UFH,"\\cos ","cos"))
+ | "\\sinh" -> LITERAL (HTMLABLEC(FONT_UFH,"\\sinh ","sinh"))
+ | "\\cosh" -> LITERAL (HTMLABLEC(FONT_UFH,"\\cosh ","cosh"))
+ | "\\tan" -> LITERAL (HTMLABLEC(FONT_UFH,"\\tan ","tan"))
+ | "\\tanh" -> LITERAL (HTMLABLEC(FONT_UFH,"\\tanh ","tanh"))
+ | "\\sec" -> LITERAL (HTMLABLEC(FONT_UFH,"\\sec ","sec"))
+ | "\\csc" -> LITERAL (HTMLABLEC(FONT_UFH,"\\csc ","csc"))
+ | "\\arcsin" -> LITERAL (HTMLABLEC(FONT_UFH,"\\arcsin ","arcsin"))
+ | "\\arctan" -> LITERAL (HTMLABLEC(FONT_UFH,"\\arctan ","arctan"))
+ | "\\arccos" -> (tex_use_ams (); LITERAL (HTMLABLEC(FONT_UFH,"\\mathop{\\mathrm{arccos}}","arccos")))
+ | "\\arccot" -> (tex_use_ams (); LITERAL (HTMLABLEC(FONT_UFH,"\\mathop{\\mathrm{arccot}}","arccot")))
+ | "\\arcsec" -> (tex_use_ams (); LITERAL (HTMLABLEC(FONT_UFH,"\\mathop{\\mathrm{arcsec}}","arcsec")))
+ | "\\arccsc" -> (tex_use_ams (); LITERAL (HTMLABLEC(FONT_UFH,"\\mathop{\\mathrm{arccsc}}","arccsc")))
+ | "\\sgn" -> (tex_use_ams (); LITERAL (HTMLABLEC(FONT_UFH,"\\mathop{\\mathrm{sgn}}","sgn")))
+ | "\\cot" -> LITERAL (HTMLABLEC(FONT_UFH,"\\cot ","cot"))
+ | "\\coth" -> LITERAL (HTMLABLEC(FONT_UFH,"\\coth ","coth"))
+ | "\\log" -> LITERAL (HTMLABLEC(FONT_UFH,"\\log ", "log"))
+ | "\\lg" -> LITERAL (HTMLABLEC(FONT_UFH,"\\lg ", "lg"))
+ | "\\ln" -> LITERAL (HTMLABLEC(FONT_UFH,"\\ln ", "ln"))
+ | "\\exp" -> LITERAL (HTMLABLEC(FONT_UFH,"\\exp ", "exp"))
+ | "\\min" -> LITERAL (HTMLABLEC(FONT_UFH,"\\min ", "min"))
+ | "\\max" -> LITERAL (HTMLABLEC(FONT_UFH,"\\max ", "max"))
+ | "\\gcd" -> LITERAL (HTMLABLEC(FONT_UFH,"\\gcd ", "gcd"))
+ | "\\deg" -> LITERAL (HTMLABLEC(FONT_UFH,"\\deg ", "deg"))
+ | "\\det" -> LITERAL (HTMLABLEC(FONT_UFH,"\\det ", "det"))
+ | "\\bullet" -> LITERAL (HTMLABLE (FONT_UFH, "\\bullet ", "&bull;"))
+ | "\\bull" -> LITERAL (HTMLABLE (FONT_UFH, "\\bullet ", "&bull;"))
+ | "\\angle" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\angle ", "&ang;")))
+ | "\\dagger" -> LITERAL (HTMLABLEM(FONT_UFH, "\\dagger ", "&dagger;"))
+ | "\\ddagger" -> LITERAL (HTMLABLEM(FONT_UFH, "\\ddagger ", "&Dagger;"))
+ | "\\Dagger" -> LITERAL (HTMLABLEM(FONT_UFH, "\\ddagger ", "&Dagger;"))
+ | "\\colon" -> LITERAL (HTMLABLEC(FONT_UFH, "\\colon ", ":"))
+ | "\\Vert" -> DELIMITER (HTMLABLEM(FONT_UFH, "\\Vert ", "||"))
+ | "\\vert" -> DELIMITER (HTMLABLEM(FONT_UFH, "\\vert ", "|"))
+ | "\\wp" -> LITERAL (HTMLABLE (FONT_UF, "\\wp ", "&weierp;"))
+ | "\\weierp" -> LITERAL (HTMLABLE (FONT_UF, "\\wp ", "&weierp;"))
+ | "\\wedge" -> LITERAL (HTMLABLE (FONT_UF, "\\wedge ", "&and;"))
+ | "\\and" -> LITERAL (HTMLABLE (FONT_UF, "\\land ", "&and;"))
+ | "\\land" -> LITERAL (HTMLABLE (FONT_UF, "\\land ", "&and;"))
+ | "\\vee" -> LITERAL (HTMLABLE (FONT_UF, "\\vee ", "&or;"))
+ | "\\or" -> LITERAL (HTMLABLE (FONT_UF, "\\lor ", "&or;"))
+ | "\\lor" -> LITERAL (HTMLABLE (FONT_UF, "\\lor ", "&or;"))
+ | "\\sub" -> LITERAL (HTMLABLE (FONT_UF, "\\subset ", "&sub;"))
+ | "\\supe" -> LITERAL (HTMLABLE (FONT_UF, "\\supseteq ", "&supe;"))
+ | "\\sube" -> LITERAL (HTMLABLE (FONT_UF, "\\subseteq ", "&sube;"))
+ | "\\supset" -> LITERAL (HTMLABLE (FONT_UF, "\\supset ", "&sup;"))
+ | "\\subset" -> LITERAL (HTMLABLE (FONT_UF, "\\subset ", "&sub;"))
+ | "\\supseteq" -> LITERAL (HTMLABLE (FONT_UF, "\\supseteq ", "&supe;"))
+ | "\\subseteq" -> LITERAL (HTMLABLE (FONT_UF, "\\subseteq ", "&sube;"))
+ | "\\sqsupset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsupset "))
+ | "\\sqsubset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsubset "))
+ | "\\sqsupseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsupseteq "))
+ | "\\sqsubseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsubseteq "))
+ | "\\perp" -> LITERAL (HTMLABLE (FONT_UF, "\\perp ", "&perp;"))
+ | "\\bot" -> LITERAL (HTMLABLE (FONT_UF, "\\bot ", "&perp;"))
+ | "\\lfloor" -> DELIMITER (HTMLABLE (FONT_UF, "\\lfloor ", "&lfloor;"))
+ | "\\rfloor" -> DELIMITER (HTMLABLE (FONT_UF, "\\rfloor ", "&rfloor;"))
+ | "\\lceil" -> DELIMITER (HTMLABLE (FONT_UF, "\\lceil ", "&lceil;"))
+ | "\\rceil" -> DELIMITER (HTMLABLE (FONT_UF, "\\rceil ", "&rceil;"))
+ | "\\lbrace" -> DELIMITER (HTMLABLEC(FONT_UFH, "\\lbrace ", "{"))
+ | "\\rbrace" -> DELIMITER (HTMLABLEC(FONT_UFH, "\\rbrace ", "}"))
+ | "\\infty" -> LITERAL (HTMLABLEM(FONT_UF, "\\infty ", "&infin;"))
+ | "\\infin" -> LITERAL (HTMLABLEM(FONT_UF, "\\infty ", "&infin;"))
+ | "\\isin" -> LITERAL (HTMLABLE (FONT_UF, "\\in ", "&isin;"))
+ | "\\in" -> LITERAL (HTMLABLE (FONT_UF, "\\in ", "&isin;"))
+ | "\\ni" -> LITERAL (HTMLABLE (FONT_UF, "\\ni ", "&ni;"))
+ | "\\notin" -> LITERAL (HTMLABLE (FONT_UF, "\\notin ", "&notin;"))
+ | "\\smallsetminus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\smallsetminus "))
+ | "\\And" -> (tex_use_ams (); LITERAL (HTMLABLEM(FONT_UFH, "\\And ", "&nbsp;&amp;&nbsp;")))
+ | "\\forall" -> LITERAL (HTMLABLE (FONT_UFH, "\\forall ", "&forall;"))
+ | "\\exists" -> LITERAL (HTMLABLE (FONT_UFH, "\\exists ", "&exist;"))
+ | "\\exist" -> LITERAL (HTMLABLE (FONT_UFH, "\\exists ", "&exist;"))
+ | "\\equiv" -> LITERAL (HTMLABLEM(FONT_UFH, "\\equiv ", "&equiv;"))
+ | "\\ne" -> LITERAL (HTMLABLEM(FONT_UFH, "\\neq ", "&ne;"))
+ | "\\neq" -> LITERAL (HTMLABLEM(FONT_UFH, "\\neq ", "&ne;"))
+ | "\\Re" -> LITERAL (HTMLABLE (FONT_UF, "\\Re ", "&real;"))
+ | "\\real" -> LITERAL (HTMLABLE (FONT_UF, "\\Re ", "&real;"))
+ | "\\Im" -> LITERAL (HTMLABLE (FONT_UF, "\\Im ", "&image;"))
+ | "\\image" -> LITERAL (HTMLABLE (FONT_UF, "\\Im ", "&image;"))
+ | "\\prime" -> LITERAL (HTMLABLE (FONT_UFH,"\\prime ", "&prime;"))
+ | "\\backslash" -> DELIMITER (HTMLABLEM(FONT_UFH,"\\backslash ", "\\"))
+ | "\\setminus" -> LITERAL (HTMLABLEM(FONT_UFH,"\\setminus ", "\\"))
+ | "\\times" -> LITERAL (HTMLABLEM(FONT_UFH,"\\times ", "&times;"))
+ | "\\pm" -> LITERAL (HTMLABLEM(FONT_UFH,"\\pm ", "&plusmn;"))
+ | "\\plusmn" -> LITERAL (HTMLABLEM(FONT_UFH,"\\pm ", "&plusmn;"))
+ | "\\cdot" -> LITERAL (HTMLABLE (FONT_UFH,"\\cdot ", "&sdot;"))
+ | "\\AA" -> LITERAL (HTMLABLE (FONT_UFH,"\\AA ", "&Aring;"))
+ | "\\cdots" -> LITERAL (HTMLABLE (FONT_UFH,"\\cdots ", "&sdot;&sdot;&sdot;"))
+ | "\\sdot" -> LITERAL (HTMLABLE (FONT_UFH,"\\cdot ", "&sdot;"))
+ | "\\oplus" -> LITERAL (HTMLABLE (FONT_UF, "\\oplus ", "&oplus;"))
+ | "\\otimes" -> LITERAL (HTMLABLE (FONT_UF, "\\otimes ", "&otimes;"))
+ | "\\cap" -> LITERAL (HTMLABLEM(FONT_UF, "\\cap ", "&cap;"))
+ | "\\cup" -> LITERAL (HTMLABLE (FONT_UF, "\\cup ", "&cup;"))
+ | "\\uplus" -> LITERAL (TEX_ONLY "\\uplus ")
+ | "\\sqcap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqcap "))
+ | "\\sqcup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqcup "))
+ | "\\empty" -> LITERAL (HTMLABLE (FONT_UF, "\\emptyset ", "&empty;"))
+ | "\\emptyset" -> LITERAL (HTMLABLE (FONT_UF, "\\emptyset ", "&empty;"))
+ | "\\O" -> LITERAL (HTMLABLE (FONT_UF, "\\emptyset ", "&empty;"))
+ | "\\S" -> LITERAL (HTMLABLEM(FONT_UFH,"\\S ", "&sect;"))
+ | "\\sect" -> LITERAL (HTMLABLEM(FONT_UFH,"\\S ", "&sect;"))
+ | "\\nabla" -> LITERAL (HTMLABLE (FONT_UF, "\\nabla ", "&nabla;"))
+ | "\\geq" -> LITERAL (HTMLABLE (FONT_UFH,"\\geq ", "&ge;"))
+ | "\\ge" -> LITERAL (HTMLABLE (FONT_UFH,"\\geq ", "&ge;"))
+ | "\\leq" -> LITERAL (HTMLABLE (FONT_UFH,"\\leq ", "&le;"))
+ | "\\le" -> LITERAL (HTMLABLE (FONT_UFH,"\\leq ", "&le;"))
+ | "\\cong" -> LITERAL (HTMLABLE (FONT_UF, "\\cong ", "&cong;"))
+ | "\\ang" -> LITERAL (HTMLABLE (FONT_UF, "\\angle ", "&ang;"))
+ | "\\part" -> LITERAL (HTMLABLEM(FONT_UF, "\\partial ", "&part;"))
+ | "\\partial" -> LITERAL (HTMLABLEM(FONT_UF, "\\partial ", "&part;"))
+ | "\\ldots" -> LITERAL (HTMLABLEM(FONT_UFH,"\\ldots ", "..."))
+ | "\\dots" -> LITERAL (HTMLABLEM(FONT_UFH,"\\dots ", "..."))
+ | "\\quad" -> LITERAL (HTMLABLE (FONT_UF, "\\quad ","&nbsp;&nbsp;"))
+ | "\\qquad" -> LITERAL (HTMLABLE (FONT_UF, "\\qquad ","&nbsp;&nbsp;&nbsp;&nbsp;"))
+ | "\\mid" -> LITERAL (HTMLABLEM(FONT_UFH,"\\mid ", " | "))
+ | "\\neg" -> LITERAL (HTMLABLEM(FONT_UFH,"\\neg ", "&not;"))
+ | "\\langle" -> DELIMITER (HTMLABLE (FONT_UFH,"\\langle ","&lang;"))
+ | "\\rangle" -> DELIMITER (HTMLABLE (FONT_UFH,"\\rangle ","&rang;"))
+ | "\\lang" -> DELIMITER (HTMLABLE (FONT_UFH,"\\langle ","&lang;"))
+ | "\\rang" -> DELIMITER (HTMLABLE (FONT_UFH,"\\rangle ","&rang;"))
+ | "\\lbrack" -> DELIMITER (HTMLABLEC(FONT_UFH,"[","["))
+ | "\\rbrack" -> DELIMITER (HTMLABLEC(FONT_UFH,"]","]"))
+ | "\\surd" -> LITERAL (TEX_ONLY "\\surd ")
+ | "\\ddots" -> LITERAL (TEX_ONLY "\\ddots ")
+ | "\\clubs" -> LITERAL (TEX_ONLY "\\clubsuit ")
+ | "\\clubsuit" -> LITERAL (TEX_ONLY "\\clubsuit ")
+ | "\\spades" -> LITERAL (TEX_ONLY "\\spadesuit ")
+ | "\\spadesuit" -> LITERAL (TEX_ONLY "\\spadesuit ")
+ | "\\hearts" -> LITERAL (TEX_ONLY "\\heartsuit ")
+ | "\\heartsuit" -> LITERAL (TEX_ONLY "\\heartsuit ")
+ | "\\diamonds" -> LITERAL (TEX_ONLY "\\diamondsuit ")
+ | "\\diamond" -> LITERAL (TEX_ONLY "\\diamond ")
+ | "\\bigtriangleup" -> LITERAL (TEX_ONLY "\\bigtriangleup ")
+ | "\\bigtriangledown" -> LITERAL (TEX_ONLY "\\bigtriangledown ")
+ | "\\diamondsuit" -> LITERAL (TEX_ONLY "\\diamondsuit ")
+ | "\\ominus" -> LITERAL (TEX_ONLY "\\ominus ")
+ | "\\oslash" -> LITERAL (TEX_ONLY "\\oslash ")
+ | "\\odot" -> LITERAL (TEX_ONLY "\\odot ")
+ | "\\bigcirc" -> LITERAL (TEX_ONLY "\\bigcirc ")
+ | "\\amalg" -> LITERAL (TEX_ONLY "\\amalg ")
+ | "\\prec" -> LITERAL (TEX_ONLY "\\prec ")
+ | "\\succ" -> LITERAL (TEX_ONLY "\\succ ")
+ | "\\preceq" -> LITERAL (TEX_ONLY "\\preceq ")
+ | "\\succeq" -> LITERAL (TEX_ONLY "\\succeq ")
+ | "\\dashv" -> LITERAL (TEX_ONLY "\\dashv ")
+ | "\\asymp" -> LITERAL (TEX_ONLY "\\asymp ")
+ | "\\doteq" -> LITERAL (TEX_ONLY "\\doteq ")
+ | "\\parallel" -> LITERAL (TEX_ONLY "\\parallel ")
+ | "\\implies" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\implies ", "&rArr;")))
+ | "\\mod" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mod ", "mod")))
+ | "\\Diamond" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\Diamond ", "&loz;")))
+ | "\\dotsb" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\dotsb ", "&sdot;&sdot;&sdot;")))
+ | "\\reals" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{R}", "<b>R</b>")))
+ | "\\Reals" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{R}", "<b>R</b>")))
+ | "\\R" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{R}", "<b>R</b>")))
+ | "\\cnums" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{C}", "<b>C</b>")))
+ | "\\Complex" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{C}", "<b>C</b>")))
+ | "\\Z" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{Z}", "<b>Z</b>")))
+ | "\\natnums" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{N}", "<b>N</b>")))
+ | "\\N" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{N}", "<b>N</b>")))
+ | "\\lVert" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\lVert ", "||")))
+ | "\\rVert" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\rVert ", "||")))
+ | "\\nmid" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nmid "))
+ | "\\lesssim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lesssim "))
+ | "\\ngeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngeq "))
+ | "\\smallsmile" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\smallsmile "))
+ | "\\smallfrown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\smallfrown "))
+ | "\\nleftarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleftarrow "))
+ | "\\nrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nrightarrow "))
+ | "\\trianglelefteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\trianglelefteq "))
+ | "\\trianglerighteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\trianglerighteq "))
+ | "\\square" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\square "))
+ | "\\checkmark" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\checkmark "))
+ | "\\supsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\supsetneq "))
+ | "\\subsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\subsetneq "))
+ | "\\Box" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Box "))
+ | "\\nleq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleq "))
+ | "\\upharpoonright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upharpoonright "))
+ | "\\restriction" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upharpoonright "))
+ | "\\upharpoonleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upharpoonleft "))
+ | "\\downharpoonright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\downharpoonright "))
+ | "\\downharpoonleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\downharpoonleft "))
+ | "\\rightharpoonup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightharpoonup "))
+ | "\\rightharpoondown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightharpoondown "))
+ | "\\leftharpoonup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftharpoonup "))
+ | "\\leftharpoondown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftharpoondown "))
+ | "\\nless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nless "))
+ | "\\Vdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Vdash "))
+ | "\\vDash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vDash "))
+ | "\\varkappa" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varkappa "))
+ | "\\digamma" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\digamma "))
+ | "\\beth" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\beth "))
+ | "\\daleth" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\daleth "))
+ | "\\gimel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gimel "))
+ | "\\complement" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\complement "))
+ | "\\eth" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eth "))
+ | "\\hslash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\hslash "))
+ | "\\mho" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\mho "))
+ | "\\Finv" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Finv "))
+ | "\\Game" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Game "))
+ | "\\varlimsup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varlimsup "))
+ | "\\varliminf" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varliminf "))
+ | "\\varinjlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varinjlim "))
+ | "\\varprojlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varprojlim "))
+ | "\\injlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\injlim "))
+ | "\\projlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\projlim "))
+ | "\\iint" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\iint "))
+ | "\\iiint" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\iiint "))
+ | "\\iiiint" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\iiiint "))
+ | "\\varnothing" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varnothing "))
+ | "\\left" -> LEFT
+ | "\\right" -> RIGHT
+ | "\\hat" -> FUN_AR1 "\\hat "
+ | "\\widehat" -> LITERAL (TEX_ONLY "\\widehat ")
+ | "\\overline" -> LITERAL (TEX_ONLY "\\overline ")
+ | "\\overbrace" -> LITERAL (TEX_ONLY "\\overbrace ")
+ | "\\underline" -> LITERAL (TEX_ONLY "\\underline ")
+ | "\\underbrace" -> LITERAL (TEX_ONLY "\\underbrace ")
+ | "\\overleftarrow" -> LITERAL (TEX_ONLY "\\overleftarrow ")
+ | "\\overrightarrow" -> LITERAL (TEX_ONLY "\\overrightarrow ")
+ | "\\overleftrightarrow"->LITERAL (TEX_ONLY "\\overleftrightarrow ")
+ | "\\check" -> FUN_AR1 "\\check "
+ | "\\acute" -> FUN_AR1 "\\acute "
+ | "\\grave" -> FUN_AR1 "\\grave "
+ | "\\bar" -> FUN_AR1 "\\bar "
+ | "\\vec" -> FUN_AR1 "\\vec "
+ | "\\dot" -> FUN_AR1 "\\dot "
+ | "\\ddot" -> FUN_AR1 "\\ddot "
+ | "\\breve" -> FUN_AR1 "\\breve "
+ | "\\tilde" -> FUN_AR1 "\\tilde "
+ | "\\not" -> LITERAL (TEX_ONLY "\\not ")
+ | "\\choose" -> FUN_INFIX "\\choose "
+ | "\\atop" -> FUN_INFIX "\\atop "
+ | "\\binom" -> (tex_use_ams (); FUN_AR2 "\\binom ")
+ | "\\dbinom" -> (tex_use_ams (); FUN_AR2 "\\dbinom ")
+ | "\\tbinom" -> (tex_use_ams (); FUN_AR2 "\\tbinom ")
+ | "\\stackrel" -> FUN_AR2 "\\stackrel "
+ | "\\sideset" -> (tex_use_ams (); FUN_AR2nb "\\sideset ")
+ | "\\underset" -> (tex_use_ams (); FUN_AR2 "\\underset ")
+ | "\\overset" -> (tex_use_ams (); FUN_AR2 "\\overset ")
+ | "\\frac" -> FUN_AR2h ("\\frac ", fun num den -> Html.html_render [num], "<hr style=\"{background: black}\"/>", Html.html_render [den])
+ | "\\dfrac" -> (tex_use_ams () ; FUN_AR2 "\\dfrac ")
+ | "\\tfrac" -> (tex_use_ams () ; FUN_AR2h ("\\tfrac ", fun num den -> Html.html_render [num], "<hr style=\"background: black\">", Html.html_render [den]))
+ | "\\cfrac" -> (tex_use_ams (); FUN_AR2h ("\\cfrac ", fun num den -> Html.html_render [num], "<hr style=\"{background: black}\">", Html.html_render [den]))
+ | "\\over" -> FUN_INFIXh ("\\over ", fun num den -> Html.html_render num, "<hr style=\"{background: black}\"/>", Html.html_render den)
+ | "\\sqrt" -> FUN_AR1 "\\sqrt "
+ | "\\pmod" -> FUN_AR1hl ("\\pmod ", ("(mod ", ")"))
+ | "\\bmod" -> FUN_AR1hl ("\\bmod ", ("mod ", ""))
+ | "\\emph" -> FUN_AR1 "\\emph "
+ | "\\texttt" -> FUN_AR1 "\\texttt "
+ | "\\textbf" -> FUN_AR1 "\\textbf "
+ | "\\textit" -> FUN_AR1hf ("\\textit ", FONTFORCE_IT)
+ | "\\textrm" -> FUN_AR1hf ("\\textrm ", FONTFORCE_RM)
+ | "\\rm" -> DECLh ("\\rm ", FONTFORCE_RM)
+ | "\\it" -> DECLh ("\\it ", FONTFORCE_IT)
+ | "\\cal" -> DECL "\\cal "
+ | "\\displaystyle" -> LITERAL (TEX_ONLY "\\displaystyle ")
+ | "\\scriptstyle" -> LITERAL (TEX_ONLY "\\scriptstyle ")
+ | "\\textstyle" -> LITERAL (TEX_ONLY "\\textstyle ")
+ | "\\scriptscriptstyle"-> LITERAL (TEX_ONLY "\\scriptscriptstyle ")
+ | "\\bf" -> DECL "\\bf "
+ | "\\big" -> BIG "\\big "
+ | "\\Big" -> BIG "\\Big "
+ | "\\bigg" -> BIG "\\bigg "
+ | "\\Bigg" -> BIG "\\Bigg "
+ | "\\bigl" -> (tex_use_ams ();BIG "\\bigl ")
+ | "\\bigr" -> (tex_use_ams ();BIG "\\bigr ")
+ | "\\Bigl" -> (tex_use_ams ();BIG "\\Bigl ")
+ | "\\Bigr" -> (tex_use_ams ();BIG "\\Bigr ")
+ | "\\biggl" -> (tex_use_ams ();BIG "\\biggl ")
+ | "\\biggr" -> (tex_use_ams ();BIG "\\biggr ")
+ | "\\Biggl" -> (tex_use_ams ();BIG "\\Biggl ")
+ | "\\Biggr" -> (tex_use_ams ();BIG "\\Biggr ")
+ | "\\vartriangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vartriangle "))
+ | "\\triangledown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\triangledown "))
+ | "\\lozenge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lozenge "))
+ | "\\circledS" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circledS "))
+ | "\\measuredangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\measuredangle "))
+ | "\\nexists" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nexists "))
+ | "\\Bbbk" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Bbbk "))
+ | "\\backprime" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backprime "))
+ | "\\blacktriangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangle "))
+ | "\\blacktriangledown"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangledown "))
+ | "\\blacksquare" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacksquare "))
+ | "\\blacklozenge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacklozenge "))
+ | "\\bigstar" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\bigstar "))
+ | "\\sphericalangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sphericalangle "))
+ | "\\diagup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\diagup "))
+ | "\\diagdown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\diagdown "))
+ | "\\dotplus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\dotplus "))
+ | "\\Cap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cap "))
+ | "\\doublecap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cap "))
+ | "\\Cup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cup "))
+ | "\\doublecup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cup "))
+ | "\\barwedge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\barwedge "))
+ | "\\veebar" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\veebar "))
+ | "\\doublebarwedge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\doublebarwedge "))
+ | "\\boxminus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxminus "))
+ | "\\boxtimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxtimes "))
+ | "\\boxdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxdot "))
+ | "\\boxplus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxplus "))
+ | "\\divideontimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\divideontimes "))
+ | "\\ltimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ltimes "))
+ | "\\rtimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rtimes "))
+ | "\\leftthreetimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftthreetimes "))
+ | "\\rightthreetimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightthreetimes "))
+ | "\\curlywedge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlywedge "))
+ | "\\curlyvee" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlyvee "))
+ | "\\circleddash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circleddash "))
+ | "\\circledast" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circledast "))
+ | "\\circledcirc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circledcirc "))
+ | "\\centerdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\centerdot "))
+ | "\\intercal" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\intercal "))
+ | "\\leqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leqq "))
+ | "\\leqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leqslant "))
+ | "\\eqslantless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqslantless "))
+ | "\\lessapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lessapprox "))
+ | "\\approxeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\approxeq "))
+ | "\\lessdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lessdot "))
+ | "\\lll" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lll "))
+ | "\\lessgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lessgtr "))
+ | "\\lesseqgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lesseqgtr "))
+ | "\\lesseqqgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lesseqqgtr "))
+ | "\\doteqdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\doteqdot "))
+ | "\\Doteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\doteqdot "))
+ | "\\risingdotseq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\risingdotseq "))
+ | "\\fallingdotseq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\fallingdotseq "))
+ | "\\backsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backsim "))
+ | "\\backsimeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backsimeq "))
+ | "\\subseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\subseteqq "))
+ | "\\Subset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Subset "))
+ | "\\preccurlyeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\preccurlyeq "))
+ | "\\curlyeqprec" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlyeqprec "))
+ | "\\precsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precsim "))
+ | "\\precapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precapprox "))
+ | "\\vartriangleleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vartriangleleft "))
+ | "\\Vvdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Vvdash "))
+ | "\\bumpeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\bumpeq "))
+ | "\\Bumpeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Bumpeq "))
+ | "\\geqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\geqq "))
+ | "\\geqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\geqslant "))
+ | "\\eqslantgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqslantgtr "))
+ | "\\gtrsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrsim "))
+ | "\\gtrapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrapprox "))
+ | "\\eqsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqsim "))
+ | "\\gtrdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrdot "))
+ | "\\ggg" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ggg "))
+ | "\\gggtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ggg "))
+ | "\\gtrless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrless "))
+ | "\\gtreqless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtreqless "))
+ | "\\gtreqqless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtreqqless "))
+ | "\\eqcirc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqcirc "))
+ | "\\circeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circeq "))
+ | "\\triangleq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\triangleq "))
+ | "\\thicksim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\thicksim "))
+ | "\\thickapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\thickapprox "))
+ | "\\supseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\supseteqq "))
+ | "\\Supset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Supset "))
+ | "\\succcurlyeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succcurlyeq "))
+ | "\\curlyeqsucc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlyeqsucc "))
+ | "\\succsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succsim "))
+ | "\\succapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succapprox "))
+ | "\\vartriangleright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vartriangleright "))
+ | "\\shortmid" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\shortmid "))
+ | "\\shortparallel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\shortparallel "))
+ | "\\between" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\between "))
+ | "\\pitchfork" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\pitchfork "))
+ | "\\varpropto" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varpropto "))
+ | "\\blacktriangleleft"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangleleft "))
+ | "\\therefore" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\therefore "))
+ | "\\backepsilon" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backepsilon "))
+ | "\\blacktriangleright"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangleright "))
+ | "\\because" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\because "))
+ | "\\nleqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleqslant "))
+ | "\\nleqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleqq "))
+ | "\\lneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lneq "))
+ | "\\lneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lneqq "))
+ | "\\lvertneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lvertneqq "))
+ | "\\lnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lnsim "))
+ | "\\lnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lnapprox "))
+ | "\\nprec" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nprec "))
+ | "\\npreceq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\npreceq "))
+ | "\\precneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precneqq "))
+ | "\\precnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precnsim "))
+ | "\\precnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precnapprox "))
+ | "\\nsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsim "))
+ | "\\nshortmid" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nshortmid "))
+ | "\\nvdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nvdash "))
+ | "\\nVdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nVdash "))
+ | "\\ntriangleleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntriangleleft "))
+ | "\\ntrianglelefteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntrianglelefteq "))
+ | "\\nsubseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsubseteq "))
+ | "\\nsubseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsubseteqq "))
+ | "\\varsubsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsubsetneq "))
+ | "\\subsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\subsetneqq "))
+ | "\\varsubsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsubsetneqq "))
+ | "\\ngtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngtr "))
+ | "\\ngeqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngeqslant "))
+ | "\\ngeqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngeqq "))
+ | "\\gneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gneq "))
+ | "\\gneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gneqq "))
+ | "\\gvertneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gvertneqq "))
+ | "\\gnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gnsim "))
+ | "\\gnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gnapprox "))
+ | "\\nsucc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsucc "))
+ | "\\nsucceq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsucceq "))
+ | "\\succneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succneqq "))
+ | "\\succnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succnsim "))
+ | "\\succnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succnapprox "))
+ | "\\ncong" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ncong "))
+ | "\\nshortparallel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nshortparallel "))
+ | "\\nparallel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nparallel "))
+ | "\\nvDash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nvDash "))
+ | "\\nVDash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nVDash "))
+ | "\\ntriangleright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntriangleright "))
+ | "\\ntrianglerighteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntrianglerighteq "))
+ | "\\nsupseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsupseteq "))
+ | "\\nsupseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsupseteqq "))
+ | "\\varsupsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsupsetneq "))
+ | "\\supsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\supsetneqq "))
+ | "\\varsupsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsupsetneqq "))
+ | "\\leftleftarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftleftarrows "))
+ | "\\leftrightarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftrightarrows "))
+ | "\\Lleftarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Lleftarrow "))
+ | "\\leftarrowtail" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftarrowtail "))
+ | "\\looparrowleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\looparrowleft "))
+ | "\\leftrightharpoons"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftrightharpoons "))
+ | "\\curvearrowleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curvearrowleft "))
+ | "\\circlearrowleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circlearrowleft "))
+ | "\\Lsh" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Lsh "))
+ | "\\upuparrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upuparrows "))
+ | "\\rightrightarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightrightarrows "))
+ | "\\rightleftarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightleftarrows "))
+ | "\\Rrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Rrightarrow "))
+ | "\\rightarrowtail" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightarrowtail "))
+ | "\\looparrowright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\looparrowright "))
+ | "\\curvearrowright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curvearrowright "))
+ | "\\circlearrowright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circlearrowright "))
+ | "\\Rsh" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Rsh "))
+ | "\\downdownarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\downdownarrows "))
+ | "\\multimap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\multimap "))
+ | "\\leftrightsquigarrow"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftrightsquigarrow "))
+ | "\\rightsquigarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightsquigarrow "))
+ | "\\nLeftarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nLeftarrow "))
+ | "\\nleftrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleftrightarrow "))
+ | "\\nRightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nRightarrow "))
+ | "\\nLeftrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nLeftrightarrow "))
+ | "\\mathit" -> (tex_use_ams (); FUN_AR1hf ("\\mathit ", FONTFORCE_IT))
+ | "\\mathrm" -> (tex_use_ams (); FUN_AR1hf ("\\mathrm ", FONTFORCE_RM))
+ | "\\mathop" -> (tex_use_ams (); FUN_AR1 "\\mathop ")
+ | "\\boldsymbol" -> (tex_use_ams (); FUN_AR1 "\\boldsymbol ")
+ | "\\bold" -> (tex_use_ams (); FUN_AR1 "\\mathbf ")
+ | "\\Bbb" -> (tex_use_ams (); FUN_AR1 "\\mathbb ")
+ | "\\mathbf" -> (tex_use_ams (); FUN_AR1 "\\mathbf ")
+ | "\\mathsf" -> (tex_use_ams (); FUN_AR1 "\\mathsf ")
+ | "\\mathcal" -> (tex_use_ams (); FUN_AR1 "\\mathcal ")
+ | "\\mathbb" -> (tex_use_ams (); FUN_AR1 "\\mathbb ")
+ | "\\mathfrak" -> (tex_use_ams (); FUN_AR1 "\\mathfrak ")
+ | "\\operatorname" -> (tex_use_ams (); FUN_AR1 "\\operatorname ")
+ | "\\text" -> raise (Failure "malformatted \\text")
+ | "\\mbox" -> raise (Failure "malformatted \\mbox")
+ | "\\vbox" -> raise (Failure "malformatted \\vbox")
+ | "\\hbox" -> raise (Failure "malformatted \\hbox")
+ | "\\color" -> (tex_use_color (); LITERAL (TEX_ONLY "\\color"))
+ | s -> raise (Illegal_tex_function s)
diff --git a/math/texutil.mli b/math/texutil.mli
new file mode 100644
index 000000000000..99d0e4ecaf56
--- /dev/null
+++ b/math/texutil.mli
@@ -0,0 +1,11 @@
+val render_tex : Tex.t -> string
+
+val set_encoding : string -> unit
+val tex_use_nonascii: unit -> unit
+val tex_use_ams: unit -> unit
+
+val get_preface : unit -> string
+val get_footer : unit -> string
+
+exception Illegal_tex_function of string
+val find: string -> Parser.token
diff --git a/math/texvc.ml b/math/texvc.ml
new file mode 100644
index 000000000000..abddd3d0d6d4
--- /dev/null
+++ b/math/texvc.ml
@@ -0,0 +1,34 @@
+exception LexerException of string
+let lexer_token_safe lexbuf =
+ try Lexer.token lexbuf
+ with Failure s -> raise (LexerException s)
+
+let render tmppath finalpath tree =
+ let outtex = Util.mapjoin Texutil.render_tex tree in
+ let md5 = Digest.to_hex (Digest.string outtex) in
+ begin
+ let mathml = Mathml.render tree
+ and html = Html.render tree
+ in print_string (match (html,!Html.conservativeness,mathml) with
+ None,_,None -> "+" ^ md5
+ | Some h,Html.CONSERVATIVE,None -> "c" ^ md5 ^ h
+ | Some h,Html.MODERATE,None -> "m" ^ md5 ^ h
+ | Some h,Html.LIBERAL,None -> "l" ^ md5 ^ h
+ | Some h,Html.CONSERVATIVE,Some m -> "C" ^ md5 ^ h ^ "\000" ^ m
+ | Some h,Html.MODERATE,Some m -> "M" ^ md5 ^ h ^ "\000" ^ m
+ | Some h,Html.LIBERAL,Some m -> "L" ^ md5 ^ h ^ "\000" ^ m
+ | None,_,Some m -> "X" ^ md5 ^ m
+ );
+ Render.render tmppath finalpath outtex md5
+ end
+let _ =
+ Texutil.set_encoding (try Sys.argv.(4) with _ -> "UTF-8");
+ try render Sys.argv.(1) Sys.argv.(2) (Parser.tex_expr lexer_token_safe (Lexing.from_string Sys.argv.(3)))
+ with Parsing.Parse_error -> print_string "S"
+ | LexerException _ -> print_string "E"
+ | Texutil.Illegal_tex_function s -> print_string ("F" ^ s)
+ | Util.FileAlreadyExists -> print_string "-"
+ | Invalid_argument _ -> print_string "-"
+ | Failure _ -> print_string "-"
+ | Render.ExternalCommandFailure s -> ()
+ | _ -> print_string "-"
diff --git a/math/texvc_cgi.ml b/math/texvc_cgi.ml
new file mode 100644
index 000000000000..2e6079feda66
--- /dev/null
+++ b/math/texvc_cgi.ml
@@ -0,0 +1,62 @@
+open Netcgi;;
+open Netcgi_types;;
+open Netcgi_env;;
+open Netchannels;;
+
+let cgi = new Netcgi.std_activation ()
+let out = cgi # output # output_string
+let math = cgi # argument_value ~default:"" "math"
+let tmppath = "/home/taw/public_html/wiki/tmp/"
+let finalpath = "/home/taw/public_html/wiki/math/"
+let finalurl = "http://wroclaw.taw.pl.eu.org/~taw/wiki/math/"
+;;
+
+let h_header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\""^
+ " \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"^
+ "<html><head><title>texvc</title></head><body>"^
+ "<form method=post action=\"http://wroclaw.taw.pl.eu.org/~taw/cgi-bin/newcodebase/math/texvc_cgi\">"^
+ "<textarea name='math' rows=10 cols=80>"
+let h_middle = "</textarea><br /><input type=submit value=\"Preview\" name='preview'></form>"
+let h_footer = "</body></html>\n"
+
+let render tmppath finalpath tree =
+ let outtex = Texutil.mapjoin Texutil.print tree in
+ let md5 = Digest.to_hex (Digest.string outtex) in
+ begin
+ out "<h3>TeX</h3>";
+ out outtex; (* <, & and > should be protected *)
+ (try out ("<h3>HTML</h3>" ^ (Texutil.html_render tree))
+ with _ -> out "<h3>HTML could not be rendered</h3>");
+ try Render.render tmppath finalpath outtex md5;
+ out ("<h3>Image:</h3><img src=\""^finalurl^md5^".png\">")
+ with Util.FileAlreadyExists -> out ("<h3>Image:</h3><img src=\""^finalurl^md5^".png\">")
+ | Failure s -> out ("<h3>Other failure: " ^ s ^ "</h3>")
+ | Render.ExternalCommandFailure "latex" -> out "<h3>latex failed</h3>"
+ | Render.ExternalCommandFailure "dvips" -> out "<h3>dvips failed</h3>"
+ | _ -> out "<h3>Other failure</h3>"
+ end
+;;
+
+cgi#set_header ();;
+
+out h_header;;
+out math;;
+out h_middle;;
+
+exception LexerException of string
+let lexer_token_safe lexbuf =
+ try Lexer.token lexbuf
+ with Failure s -> raise (LexerException s)
+;;
+if math = ""
+then ()
+else try
+ render tmppath finalpath (Parser.tex_expr lexer_token_safe (Lexing.from_string math))
+ with Parsing.Parse_error -> out "<h3>Parse error</h3>"
+ | LexerException s -> out "<h3>Lexing failure</h3>"
+ | Texutil.Illegal_tex_function s -> out ("<h3>Illegal TeX function: " ^ s ^ "</h3>")
+ | Failure s -> out ("<h3>Other failure: " ^ s ^ "</h3>")
+ | _ -> out "<h3>Other failure</h3>"
+;;
+
+out h_footer
diff --git a/math/texvc_test.ml b/math/texvc_test.ml
new file mode 100644
index 000000000000..cd3a1dfae9a9
--- /dev/null
+++ b/math/texvc_test.ml
@@ -0,0 +1,24 @@
+exception LexerException of string
+let lexer_token_safe lexbuf =
+ try Lexer.token lexbuf
+ with Failure s -> raise (LexerException s)
+
+let rec foo () =
+ try
+ let line = input_line stdin in
+ (try
+ let tree = Parser.tex_expr lexer_token_safe (Lexing.from_string line) in
+ (match Html.render tree with
+ Some _ -> print_string "$^\n"
+ | None -> print_string "$_\n";
+ )
+ with
+ Texutil.Illegal_tex_function s -> print_string ("$T" ^ s ^ " " ^ line ^ "\n")
+ | LexerException s -> print_string ("$L" ^ line ^ "\n")
+ | _ -> print_string ("$ " ^ line ^ "\n"));
+ flush stdout;
+ foo ();
+ with
+ End_of_file -> ()
+;;
+foo ();;
diff --git a/math/texvc_tex.ml b/math/texvc_tex.ml
new file mode 100644
index 000000000000..30c0f671bfba
--- /dev/null
+++ b/math/texvc_tex.ml
@@ -0,0 +1,3 @@
+Texutil.set_encoding (try Sys.argv.(2) with _ -> "UTF-8");
+try print_string (Util.mapjoin Texutil.render_tex (Parser.tex_expr Lexer.token (Lexing.from_string Sys.argv.(1))))
+with _ -> ()
diff --git a/math/util.ml b/math/util.ml
new file mode 100644
index 000000000000..f0458562746a
--- /dev/null
+++ b/math/util.ml
@@ -0,0 +1,17 @@
+let mapjoin f l = (List.fold_left (fun a b -> a ^ (f b)) "" l)
+let mapjoine e f = function
+ [] -> ""
+ | h::t -> (List.fold_left (fun a b -> a ^ e ^ (f b)) (f h) t)
+
+exception FileAlreadyExists
+let open_out_unless_exists path =
+ if Sys.file_exists path
+ then raise FileAlreadyExists
+ else open_out path
+
+let run_in_other_directory tmppath cmd =
+ let prevdir = Sys.getcwd () in(
+ Sys.chdir tmppath;
+ let retval = Sys.command cmd in
+ (Sys.chdir prevdir; retval)
+ )
diff --git a/opensearch_desc.php b/opensearch_desc.php
new file mode 100644
index 000000000000..b06b7feecf51
--- /dev/null
+++ b/opensearch_desc.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * Generate an OpenSearch description file
+ */
+
+require_once( dirname(__FILE__) . '/includes/WebStart.php' );
+require_once( dirname(__FILE__) . '/languages/Names.php' );
+$fullName = "$wgSitename ({$wgLanguageNames[$wgLanguageCode]})";
+$shortName = htmlspecialchars( mb_substr( $fullName, 0, 24 ) );
+$siteName = htmlspecialchars( $fullName );
+
+if ( !preg_match( '/^https?:/', $wgFavicon ) ) {
+ $favicon = htmlspecialchars( $wgServer . $wgFavicon );
+} else {
+ $favicon = htmlspecialchars( $wgFavicon );
+}
+
+$title = SpecialPage::getTitleFor( 'Search' );
+$template = $title->escapeFullURL( 'search={searchTerms}' );
+
+$suggest = htmlspecialchars($wgServer . $wgScriptPath . '/api.php?action=opensearch&search={searchTerms}');
+
+
+$response = $wgRequest->response();
+$response->header( 'Content-type: application/opensearchdescription+xml' );
+
+# Set an Expires header so that squid can cache it for a short time
+# Short enough so that the sysadmin barely notices when $wgSitename is changed
+$expiryTime = 300; # 5 minutes
+$response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expiryTime ) . ' GMT' );
+
+echo <<<EOT
+<?xml version="1.0"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+<ShortName>$shortName</ShortName>
+<Description>$siteName</Description>
+<Image height="16" width="16" type="image/x-icon">$favicon</Image>
+<Url type="text/html" method="get" template="$template"/>
+<Url type="application/x-suggestions+json" method="GET" template="$suggest"/>
+</OpenSearchDescription>
+EOT;
+
+
+?>
diff --git a/profileinfo.php b/profileinfo.php
new file mode 100644
index 000000000000..4e2a3d76ac89
--- /dev/null
+++ b/profileinfo.php
@@ -0,0 +1,247 @@
+<!--
+ Show profiling data.
+
+ Copyright 2005 Kate Turner.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+-->
+<html>
+<head>
+<title>Profiling data</title>
+<style type="text/css">
+ th {
+ text-align: left;
+ border-bottom: solid 1px black;
+ }
+
+ th, td {
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+ }
+
+ td.time, td.count {
+ text-align: right;
+ }
+</style>
+</head>
+<body>
+<?php
+
+$wgDBadminuser = $wgDBadminpassword = $wgDBserver = $wgDBname = $wgEnableProfileInfo = false;
+
+define( 'MW_NO_SETUP', 1 );
+require_once( './includes/WebStart.php' );
+require_once("./AdminSettings.php");
+
+if (!$wgEnableProfileInfo) {
+ echo "disabled\n";
+ exit( 1 );
+}
+
+foreach (array("wgDBadminuser", "wgDBadminpassword", "wgDBserver", "wgDBname") as $var)
+ if ($$var === false) {
+ echo "AdminSettings.php not correct\n";
+ exit( 1 );
+ }
+
+
+$expand = array();
+if (isset($_REQUEST['expand']))
+ foreach(explode(",", $_REQUEST['expand']) as $f)
+ $expand[$f] = true;
+
+class profile_point {
+ var $name;
+ var $count;
+ var $time;
+ var $children;
+
+ function profile_point($name, $count, $time) {
+ $this->name = $name;
+ $this->count = $count;
+ $this->time = $time;
+ $this->children = array();
+ }
+
+ function add_child($child) {
+ $this->children[] = $child;
+ }
+
+ function display($indent = 0.0) {
+ global $expand;
+ usort($this->children, "compare_point");
+
+ $extet = '';
+ if (isset($expand[$this->name()]))
+ $ex = true;
+ else $ex = false;
+ if (!$ex) {
+ if (count($this->children)) {
+ $url = makeurl(false, false, $expand + array($this->name() => true));
+ $extet = " <a href=\"$url\">[+]</a>";
+ } else $extet = '';
+ } else {
+ $e = array();
+ foreach ($expand as $name => $ep)
+ if ($name != $this->name())
+ $e += array($name => $ep);
+
+ $extet = " <a href=\"" . makeurl(false, false, $e) . "\">[&ndash;]</a>";
+ }
+ ?>
+ <tr>
+ <td class="time"><tt><?php echo $this->fmttime() ?></tt></td>
+ <td class="count"><?php echo $this->count() ?></td>
+ <td class="name" style="padding-left: <?php echo $indent ?>em">
+ <?php echo htmlspecialchars($this->name()) . $extet ?>
+ </td>
+ </tr>
+ <?php
+ if ($ex)
+ foreach ($this->children as $child)
+ $child->display($indent + 2);
+ }
+
+ function name() {
+ return $this->name;
+ }
+
+ function count() {
+ return $this->count;
+ }
+
+ function time() {
+ return $this->time;
+ }
+
+ function fmttime() {
+ return sprintf("%5.02f", $this->time);
+ }
+};
+
+function compare_point($a, $b) {
+ global $sort;
+ switch ($sort) {
+ case "name":
+ return strcmp($a->name(), $b->name());
+ case "time":
+ return $a->time() > $b->time() ? -1 : 1;
+ case "count":
+ return $a->count() > $b->count() ? -1 : 1;
+ }
+}
+
+$sorts = array("time", "count", "name");
+$sort = 'time';
+if (isset($_REQUEST['sort']) && in_array($_REQUEST['sort'], $sorts))
+ $sort = $_REQUEST['sort'];
+
+$dbh = mysql_connect($wgDBserver, $wgDBadminuser, $wgDBadminpassword)
+ or die("mysql server failed: " . mysql_error());
+mysql_select_db($wgDBname, $dbh) or die(mysql_error($dbh));
+$res = mysql_query("
+ SELECT pf_count, pf_time, pf_name
+ FROM profiling
+ ORDER BY pf_name ASC
+", $dbh) or die("query failed: " . mysql_error());
+
+if (isset($_REQUEST['filter']))
+ $filter = $_REQUEST['filter'];
+else $filter = '';
+
+?>
+<form method="profiling.php">
+<p>
+<input type="text" name="filter" value="<?php echo htmlspecialchars($filter)?>"/>
+<input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort)?>"/>
+<input type="hidden" name="expand" value="<?php echo htmlspecialchars(implode(",", array_keys($expand)))?>"/>
+<input type="submit" value="Filter" />
+</p>
+</form>
+
+<table cellspacing="0">
+<tr id="top">
+<th><a href="<?php echo makeurl(false, "time") ?>">Time</a></th>
+<th><a href="<?php echo makeurl(false, "count") ?>">Count</a></th>
+<th><a href="<?php echo makeurl(false, "name") ?>">Name</a></th>
+</tr>
+<?php
+$totaltime = 0.0;
+
+function makeurl($_filter = false, $_sort = false, $_expand = false) {
+ global $filter, $sort, $expand;
+
+ if ($_expand === false)
+ $_expand = $expand;
+
+ $nfilter = $_filter ? $_filter : $filter;
+ $nsort = $_sort ? $_sort : $sort;
+ $exp = urlencode(implode(',', array_keys($_expand)));
+ return "?filter=$nfilter&amp;sort=$nsort&amp;expand=$exp";
+}
+
+$points = array();
+$queries = array();
+$sqltotal = 0.0;
+
+$last = false;
+while (($o = mysql_fetch_object($res)) !== false) {
+ $next = new profile_point($o->pf_name, $o->pf_count, $o->pf_time);
+ $totaltime += $next->time();
+ if ($last !== false) {
+ if (preg_match("/^".preg_quote($last->name(), "/")."/", $next->name())) {
+ $last->add_child($next);
+ continue;
+ }
+ }
+ $last = $next;
+ if (preg_match("/^query: /", $next->name())) {
+ $sqltotal += $next->time();
+ $queries[] = $next;
+ } else {
+ $points[] = $next;
+ }
+}
+
+$s = new profile_point("SQL Queries", 0, $sqltotal);
+foreach ($queries as $q)
+ $s->add_child($q);
+$points[] = $s;
+
+usort($points, "compare_point");
+
+foreach ($points as $point) {
+ if (strlen($filter) && !strstr($point->name(), $filter))
+ continue;
+
+ $point->display();
+}
+?>
+</table>
+
+<p>Total time: <tt><?php printf("%5.02f", $totaltime) ?></p>
+<?php
+
+mysql_free_result($res);
+mysql_close($dbh);
+
+?>
+</body>
+</html>
diff --git a/redirect.php b/redirect.php
new file mode 100644
index 000000000000..4718600d6ca9
--- /dev/null
+++ b/redirect.php
@@ -0,0 +1,14 @@
+<?php
+define( 'MW_NO_SETUP', 1 );
+require_once( './includes/WebStart.php' );
+global $wgArticlePath;
+
+require_once( 'includes/WebRequest.php' );
+$wgRequest = new WebRequest();
+
+$page = $wgRequest->getVal( 'wpDropdown' );
+
+$url = str_replace( "$1", urlencode( $page ), $wgArticlePath );
+
+header( "Location: {$url}" );
+?>
diff --git a/redirect.phtml b/redirect.phtml
new file mode 100644
index 000000000000..79e3cea66807
--- /dev/null
+++ b/redirect.phtml
@@ -0,0 +1,4 @@
+<?php
+// stub file for compatibility with older versions
+include_once('./redirect.php');
+?> \ No newline at end of file
diff --git a/serialized/Makefile b/serialized/Makefile
new file mode 100644
index 000000000000..04a560df5bc3
--- /dev/null
+++ b/serialized/Makefile
@@ -0,0 +1,28 @@
+
+MESSAGE_SOURCES=$(wildcard ../languages/messages/Messages*.php)
+MESSAGE_TARGETS=$(patsubst ../languages/messages/Messages%.php, Messages%.ser, $(MESSAGE_SOURCES))
+SPECIAL_TARGETS=Utf8Case.ser
+ALL_TARGETS=$(MESSAGE_TARGETS) $(SPECIAL_TARGETS)
+DIST_TARGETS=$(SPECIAL_TARGETS) \
+ MessagesDe.ser \
+ MessagesEn.ser \
+ MessagesFr.ser \
+ MessagesJa.ser \
+ MessagesNl.ser \
+ MessagesPl.ser \
+ MessagesSv.ser
+
+.PHONY: all dist clean
+
+all: $(ALL_TARGETS)
+
+dist: $(DIST_TARGETS)
+
+clean:
+ rm -f $(ALL_TARGETS)
+
+Utf8Case.ser : ../includes/Utf8Case.php
+ php serialize.php -o $@ $<
+
+Messages%.ser : ../languages/messages/Messages%.php ../languages/messages/MessagesEn.php
+ php serialize-localisation.php -o $@ $<
diff --git a/serialized/README b/serialized/README
new file mode 100644
index 000000000000..c02444c71d8d
--- /dev/null
+++ b/serialized/README
@@ -0,0 +1,37 @@
+This directory contains data files in the format of PHP's serialize() function.
+The source data are typically array literals in PHP source files. We have
+observed that unserialize(file_get_contents(...)) is faster than executing such
+a file from an oparray cache like APC, and very much faster than loading it by
+parsing the source file without such a cache. It should also be faster than
+loading the data across the network with memcached, as long as you are careful
+to put your MediaWiki root directory on a local hard drive rather than on NFS.
+This is a good idea for performance in any case.
+
+To generate all data files:
+
+ cd /path/to/wiki/serialized
+ make
+
+This requires GNU Make. At present, the only serialized data file which is
+strictly required is Utf8Case.ser. This contains UTF-8 case conversion tables,
+which have essentially never changed since MediaWiki was invented.
+
+The Messages*.ser files are localisation files, containing user interface text
+and various other data related to language-specific behaviour. Because they
+are merged with the fallback language (usually English) before caching, they
+are all quite large, about 100KB each at the time of writing. If you generate
+all of them, they take up about 15 MB. Hence, I don't expect we will include
+all of them in the release tarballs. However, to obtain optimum performance,
+YOU SHOULD GENERATE ALL THE LOCALISATION FILES THAT YOU WILL BE USING ON YOUR
+WIKIS.
+
+You can generate individual files by typing a command such as:
+ cd /path/to/wiki/serialized
+ make MessagesAr.ser
+
+If you change a Messages*.php source file, you must recompile any serialized
+data files which are present. If you change MessagesEn.php, this will
+invalidate *all* Messages*.ser files.
+
+I think we should distribute a few Messages*.ser files in the release tarballs,
+specifically the ones created by "make dist".
diff --git a/serialized/Utf8Case.ser b/serialized/Utf8Case.ser
new file mode 100644
index 000000000000..1398008e0db0
--- /dev/null
+++ b/serialized/Utf8Case.ser
@@ -0,0 +1 @@
+a:2:{s:14:"wikiUpperChars";a:745:{s:1:"a";s:1:"A";s:1:"b";s:1:"B";s:1:"c";s:1:"C";s:1:"d";s:1:"D";s:1:"e";s:1:"E";s:1:"f";s:1:"F";s:1:"g";s:1:"G";s:1:"h";s:1:"H";s:1:"i";s:1:"I";s:1:"j";s:1:"J";s:1:"k";s:1:"K";s:1:"l";s:1:"L";s:1:"m";s:1:"M";s:1:"n";s:1:"N";s:1:"o";s:1:"O";s:1:"p";s:1:"P";s:1:"q";s:1:"Q";s:1:"r";s:1:"R";s:1:"s";s:1:"S";s:1:"t";s:1:"T";s:1:"u";s:1:"U";s:1:"v";s:1:"V";s:1:"w";s:1:"W";s:1:"x";s:1:"X";s:1:"y";s:1:"Y";s:1:"z";s:1:"Z";s:2:"µ";s:2:"Μ";s:2:"à";s:2:"À";s:2:"á";s:2:"Á";s:2:"â";s:2:"Â";s:2:"ã";s:2:"Ã";s:2:"ä";s:2:"Ä";s:2:"å";s:2:"Å";s:2:"æ";s:2:"Æ";s:2:"ç";s:2:"Ç";s:2:"è";s:2:"È";s:2:"é";s:2:"É";s:2:"ê";s:2:"Ê";s:2:"ë";s:2:"Ë";s:2:"ì";s:2:"Ì";s:2:"í";s:2:"Í";s:2:"î";s:2:"Î";s:2:"ï";s:2:"Ï";s:2:"ð";s:2:"Ð";s:2:"ñ";s:2:"Ñ";s:2:"ò";s:2:"Ò";s:2:"ó";s:2:"Ó";s:2:"ô";s:2:"Ô";s:2:"õ";s:2:"Õ";s:2:"ö";s:2:"Ö";s:2:"ø";s:2:"Ø";s:2:"ù";s:2:"Ù";s:2:"ú";s:2:"Ú";s:2:"û";s:2:"Û";s:2:"ü";s:2:"Ü";s:2:"ý";s:2:"Ý";s:2:"þ";s:2:"Þ";s:2:"ÿ";s:2:"Ÿ";s:2:"ā";s:2:"Ā";s:2:"ă";s:2:"Ă";s:2:"ą";s:2:"Ą";s:2:"ć";s:2:"Ć";s:2:"ĉ";s:2:"Ĉ";s:2:"ċ";s:2:"Ċ";s:2:"č";s:2:"Č";s:2:"ď";s:2:"Ď";s:2:"đ";s:2:"Đ";s:2:"ē";s:2:"Ē";s:2:"ĕ";s:2:"Ĕ";s:2:"ė";s:2:"Ė";s:2:"ę";s:2:"Ę";s:2:"ě";s:2:"Ě";s:2:"ĝ";s:2:"Ĝ";s:2:"ğ";s:2:"Ğ";s:2:"ġ";s:2:"Ġ";s:2:"ģ";s:2:"Ģ";s:2:"ĥ";s:2:"Ĥ";s:2:"ħ";s:2:"Ħ";s:2:"ĩ";s:2:"Ĩ";s:2:"ī";s:2:"Ī";s:2:"ĭ";s:2:"Ĭ";s:2:"į";s:2:"Į";s:2:"ı";s:1:"I";s:2:"ij";s:2:"IJ";s:2:"ĵ";s:2:"Ĵ";s:2:"ķ";s:2:"Ķ";s:2:"ĺ";s:2:"Ĺ";s:2:"ļ";s:2:"Ļ";s:2:"ľ";s:2:"Ľ";s:2:"ŀ";s:2:"Ŀ";s:2:"ł";s:2:"Ł";s:2:"ń";s:2:"Ń";s:2:"ņ";s:2:"Ņ";s:2:"ň";s:2:"Ň";s:2:"ŋ";s:2:"Ŋ";s:2:"ō";s:2:"Ō";s:2:"ŏ";s:2:"Ŏ";s:2:"ő";s:2:"Ő";s:2:"œ";s:2:"Œ";s:2:"ŕ";s:2:"Ŕ";s:2:"ŗ";s:2:"Ŗ";s:2:"ř";s:2:"Ř";s:2:"ś";s:2:"Ś";s:2:"ŝ";s:2:"Ŝ";s:2:"ş";s:2:"Ş";s:2:"š";s:2:"Š";s:2:"ţ";s:2:"Ţ";s:2:"ť";s:2:"Ť";s:2:"ŧ";s:2:"Ŧ";s:2:"ũ";s:2:"Ũ";s:2:"ū";s:2:"Ū";s:2:"ŭ";s:2:"Ŭ";s:2:"ů";s:2:"Ů";s:2:"ű";s:2:"Ű";s:2:"ų";s:2:"Ų";s:2:"ŵ";s:2:"Ŵ";s:2:"ŷ";s:2:"Ŷ";s:2:"ź";s:2:"Ź";s:2:"ż";s:2:"Ż";s:2:"ž";s:2:"Ž";s:2:"ſ";s:1:"S";s:2:"ƃ";s:2:"Ƃ";s:2:"ƅ";s:2:"Ƅ";s:2:"ƈ";s:2:"Ƈ";s:2:"ƌ";s:2:"Ƌ";s:2:"ƒ";s:2:"Ƒ";s:2:"ƕ";s:2:"Ƕ";s:2:"ƙ";s:2:"Ƙ";s:2:"ơ";s:2:"Ơ";s:2:"ƣ";s:2:"Ƣ";s:2:"ƥ";s:2:"Ƥ";s:2:"ƨ";s:2:"Ƨ";s:2:"ƭ";s:2:"Ƭ";s:2:"ư";s:2:"Ư";s:2:"ƴ";s:2:"Ƴ";s:2:"ƶ";s:2:"Ƶ";s:2:"ƹ";s:2:"Ƹ";s:2:"ƽ";s:2:"Ƽ";s:2:"ƿ";s:2:"Ƿ";s:2:"Dž";s:2:"DŽ";s:2:"dž";s:2:"DŽ";s:2:"Lj";s:2:"LJ";s:2:"lj";s:2:"LJ";s:2:"Nj";s:2:"NJ";s:2:"nj";s:2:"NJ";s:2:"ǎ";s:2:"Ǎ";s:2:"ǐ";s:2:"Ǐ";s:2:"ǒ";s:2:"Ǒ";s:2:"ǔ";s:2:"Ǔ";s:2:"ǖ";s:2:"Ǖ";s:2:"ǘ";s:2:"Ǘ";s:2:"ǚ";s:2:"Ǚ";s:2:"ǜ";s:2:"Ǜ";s:2:"ǝ";s:2:"Ǝ";s:2:"ǟ";s:2:"Ǟ";s:2:"ǡ";s:2:"Ǡ";s:2:"ǣ";s:2:"Ǣ";s:2:"ǥ";s:2:"Ǥ";s:2:"ǧ";s:2:"Ǧ";s:2:"ǩ";s:2:"Ǩ";s:2:"ǫ";s:2:"Ǫ";s:2:"ǭ";s:2:"Ǭ";s:2:"ǯ";s:2:"Ǯ";s:2:"Dz";s:2:"DZ";s:2:"dz";s:2:"DZ";s:2:"ǵ";s:2:"Ǵ";s:2:"ǹ";s:2:"Ǹ";s:2:"ǻ";s:2:"Ǻ";s:2:"ǽ";s:2:"Ǽ";s:2:"ǿ";s:2:"Ǿ";s:2:"ȁ";s:2:"Ȁ";s:2:"ȃ";s:2:"Ȃ";s:2:"ȅ";s:2:"Ȅ";s:2:"ȇ";s:2:"Ȇ";s:2:"ȉ";s:2:"Ȉ";s:2:"ȋ";s:2:"Ȋ";s:2:"ȍ";s:2:"Ȍ";s:2:"ȏ";s:2:"Ȏ";s:2:"ȑ";s:2:"Ȑ";s:2:"ȓ";s:2:"Ȓ";s:2:"ȕ";s:2:"Ȕ";s:2:"ȗ";s:2:"Ȗ";s:2:"ș";s:2:"Ș";s:2:"ț";s:2:"Ț";s:2:"ȝ";s:2:"Ȝ";s:2:"ȟ";s:2:"Ȟ";s:2:"ȣ";s:2:"Ȣ";s:2:"ȥ";s:2:"Ȥ";s:2:"ȧ";s:2:"Ȧ";s:2:"ȩ";s:2:"Ȩ";s:2:"ȫ";s:2:"Ȫ";s:2:"ȭ";s:2:"Ȭ";s:2:"ȯ";s:2:"Ȯ";s:2:"ȱ";s:2:"Ȱ";s:2:"ȳ";s:2:"Ȳ";s:2:"ɓ";s:2:"Ɓ";s:2:"ɔ";s:2:"Ɔ";s:2:"ɖ";s:2:"Ɖ";s:2:"ɗ";s:2:"Ɗ";s:2:"ə";s:2:"Ə";s:2:"ɛ";s:2:"Ɛ";s:2:"ɠ";s:2:"Ɠ";s:2:"ɣ";s:2:"Ɣ";s:2:"ɨ";s:2:"Ɨ";s:2:"ɩ";s:2:"Ɩ";s:2:"ɯ";s:2:"Ɯ";s:2:"ɲ";s:2:"Ɲ";s:2:"ɵ";s:2:"Ɵ";s:2:"ʀ";s:2:"Ʀ";s:2:"ʃ";s:2:"Ʃ";s:2:"ʈ";s:2:"Ʈ";s:2:"ʊ";s:2:"Ʊ";s:2:"ʋ";s:2:"Ʋ";s:2:"ʒ";s:2:"Ʒ";s:2:"ͅ";s:2:"Ι";s:2:"ά";s:2:"Ά";s:2:"έ";s:2:"Έ";s:2:"ή";s:2:"Ή";s:2:"ί";s:2:"Ί";s:2:"α";s:2:"Α";s:2:"β";s:2:"Β";s:2:"γ";s:2:"Γ";s:2:"δ";s:2:"Δ";s:2:"ε";s:2:"Ε";s:2:"ζ";s:2:"Ζ";s:2:"η";s:2:"Η";s:2:"θ";s:2:"Θ";s:2:"ι";s:2:"Ι";s:2:"κ";s:2:"Κ";s:2:"λ";s:2:"Λ";s:2:"μ";s:2:"Μ";s:2:"ν";s:2:"Ν";s:2:"ξ";s:2:"Ξ";s:2:"ο";s:2:"Ο";s:2:"π";s:2:"Π";s:2:"ρ";s:2:"Ρ";s:2:"ς";s:2:"Σ";s:2:"σ";s:2:"Σ";s:2:"τ";s:2:"Τ";s:2:"υ";s:2:"Υ";s:2:"φ";s:2:"Φ";s:2:"χ";s:2:"Χ";s:2:"ψ";s:2:"Ψ";s:2:"ω";s:2:"Ω";s:2:"ϊ";s:2:"Ϊ";s:2:"ϋ";s:2:"Ϋ";s:2:"ό";s:2:"Ό";s:2:"ύ";s:2:"Ύ";s:2:"ώ";s:2:"Ώ";s:2:"ϐ";s:2:"Β";s:2:"ϑ";s:2:"Θ";s:2:"ϕ";s:2:"Φ";s:2:"ϖ";s:2:"Π";s:2:"ϛ";s:2:"Ϛ";s:2:"ϝ";s:2:"Ϝ";s:2:"ϟ";s:2:"Ϟ";s:2:"ϡ";s:2:"Ϡ";s:2:"ϣ";s:2:"Ϣ";s:2:"ϥ";s:2:"Ϥ";s:2:"ϧ";s:2:"Ϧ";s:2:"ϩ";s:2:"Ϩ";s:2:"ϫ";s:2:"Ϫ";s:2:"ϭ";s:2:"Ϭ";s:2:"ϯ";s:2:"Ϯ";s:2:"ϰ";s:2:"Κ";s:2:"ϱ";s:2:"Ρ";s:2:"ϲ";s:2:"Σ";s:2:"ϵ";s:2:"Ε";s:2:"а";s:2:"А";s:2:"б";s:2:"Б";s:2:"в";s:2:"В";s:2:"г";s:2:"Г";s:2:"д";s:2:"Д";s:2:"е";s:2:"Е";s:2:"ж";s:2:"Ж";s:2:"з";s:2:"З";s:2:"и";s:2:"И";s:2:"й";s:2:"Й";s:2:"к";s:2:"К";s:2:"л";s:2:"Л";s:2:"м";s:2:"М";s:2:"н";s:2:"Н";s:2:"о";s:2:"О";s:2:"п";s:2:"П";s:2:"р";s:2:"Р";s:2:"с";s:2:"С";s:2:"т";s:2:"Т";s:2:"у";s:2:"У";s:2:"ф";s:2:"Ф";s:2:"х";s:2:"Х";s:2:"ц";s:2:"Ц";s:2:"ч";s:2:"Ч";s:2:"ш";s:2:"Ш";s:2:"щ";s:2:"Щ";s:2:"ъ";s:2:"Ъ";s:2:"ы";s:2:"Ы";s:2:"ь";s:2:"Ь";s:2:"э";s:2:"Э";s:2:"ю";s:2:"Ю";s:2:"я";s:2:"Я";s:2:"ѐ";s:2:"Ѐ";s:2:"ё";s:2:"Ё";s:2:"ђ";s:2:"Ђ";s:2:"ѓ";s:2:"Ѓ";s:2:"є";s:2:"Є";s:2:"ѕ";s:2:"Ѕ";s:2:"і";s:2:"І";s:2:"ї";s:2:"Ї";s:2:"ј";s:2:"Ј";s:2:"љ";s:2:"Љ";s:2:"њ";s:2:"Њ";s:2:"ћ";s:2:"Ћ";s:2:"ќ";s:2:"Ќ";s:2:"ѝ";s:2:"Ѝ";s:2:"ў";s:2:"Ў";s:2:"џ";s:2:"Џ";s:2:"ѡ";s:2:"Ѡ";s:2:"ѣ";s:2:"Ѣ";s:2:"ѥ";s:2:"Ѥ";s:2:"ѧ";s:2:"Ѧ";s:2:"ѩ";s:2:"Ѩ";s:2:"ѫ";s:2:"Ѫ";s:2:"ѭ";s:2:"Ѭ";s:2:"ѯ";s:2:"Ѯ";s:2:"ѱ";s:2:"Ѱ";s:2:"ѳ";s:2:"Ѳ";s:2:"ѵ";s:2:"Ѵ";s:2:"ѷ";s:2:"Ѷ";s:2:"ѹ";s:2:"Ѹ";s:2:"ѻ";s:2:"Ѻ";s:2:"ѽ";s:2:"Ѽ";s:2:"ѿ";s:2:"Ѿ";s:2:"ҁ";s:2:"Ҁ";s:2:"ҍ";s:2:"Ҍ";s:2:"ҏ";s:2:"Ҏ";s:2:"ґ";s:2:"Ґ";s:2:"ғ";s:2:"Ғ";s:2:"ҕ";s:2:"Ҕ";s:2:"җ";s:2:"Җ";s:2:"ҙ";s:2:"Ҙ";s:2:"қ";s:2:"Қ";s:2:"ҝ";s:2:"Ҝ";s:2:"ҟ";s:2:"Ҟ";s:2:"ҡ";s:2:"Ҡ";s:2:"ң";s:2:"Ң";s:2:"ҥ";s:2:"Ҥ";s:2:"ҧ";s:2:"Ҧ";s:2:"ҩ";s:2:"Ҩ";s:2:"ҫ";s:2:"Ҫ";s:2:"ҭ";s:2:"Ҭ";s:2:"ү";s:2:"Ү";s:2:"ұ";s:2:"Ұ";s:2:"ҳ";s:2:"Ҳ";s:2:"ҵ";s:2:"Ҵ";s:2:"ҷ";s:2:"Ҷ";s:2:"ҹ";s:2:"Ҹ";s:2:"һ";s:2:"Һ";s:2:"ҽ";s:2:"Ҽ";s:2:"ҿ";s:2:"Ҿ";s:2:"ӂ";s:2:"Ӂ";s:2:"ӄ";s:2:"Ӄ";s:2:"ӈ";s:2:"Ӈ";s:2:"ӌ";s:2:"Ӌ";s:2:"ӑ";s:2:"Ӑ";s:2:"ӓ";s:2:"Ӓ";s:2:"ӕ";s:2:"Ӕ";s:2:"ӗ";s:2:"Ӗ";s:2:"ә";s:2:"Ә";s:2:"ӛ";s:2:"Ӛ";s:2:"ӝ";s:2:"Ӝ";s:2:"ӟ";s:2:"Ӟ";s:2:"ӡ";s:2:"Ӡ";s:2:"ӣ";s:2:"Ӣ";s:2:"ӥ";s:2:"Ӥ";s:2:"ӧ";s:2:"Ӧ";s:2:"ө";s:2:"Ө";s:2:"ӫ";s:2:"Ӫ";s:2:"ӭ";s:2:"Ӭ";s:2:"ӯ";s:2:"Ӯ";s:2:"ӱ";s:2:"Ӱ";s:2:"ӳ";s:2:"Ӳ";s:2:"ӵ";s:2:"Ӵ";s:2:"ӹ";s:2:"Ӹ";s:2:"ա";s:2:"Ա";s:2:"բ";s:2:"Բ";s:2:"գ";s:2:"Գ";s:2:"դ";s:2:"Դ";s:2:"ե";s:2:"Ե";s:2:"զ";s:2:"Զ";s:2:"է";s:2:"Է";s:2:"ը";s:2:"Ը";s:2:"թ";s:2:"Թ";s:2:"ժ";s:2:"Ժ";s:2:"ի";s:2:"Ի";s:2:"լ";s:2:"Լ";s:2:"խ";s:2:"Խ";s:2:"ծ";s:2:"Ծ";s:2:"կ";s:2:"Կ";s:2:"հ";s:2:"Հ";s:2:"ձ";s:2:"Ձ";s:2:"ղ";s:2:"Ղ";s:2:"ճ";s:2:"Ճ";s:2:"մ";s:2:"Մ";s:2:"յ";s:2:"Յ";s:2:"ն";s:2:"Ն";s:2:"շ";s:2:"Շ";s:2:"ո";s:2:"Ո";s:2:"չ";s:2:"Չ";s:2:"պ";s:2:"Պ";s:2:"ջ";s:2:"Ջ";s:2:"ռ";s:2:"Ռ";s:2:"ս";s:2:"Ս";s:2:"վ";s:2:"Վ";s:2:"տ";s:2:"Տ";s:2:"ր";s:2:"Ր";s:2:"ց";s:2:"Ց";s:2:"ւ";s:2:"Ւ";s:2:"փ";s:2:"Փ";s:2:"ք";s:2:"Ք";s:2:"օ";s:2:"Օ";s:2:"ֆ";s:2:"Ֆ";s:3:"ḁ";s:3:"Ḁ";s:3:"ḃ";s:3:"Ḃ";s:3:"ḅ";s:3:"Ḅ";s:3:"ḇ";s:3:"Ḇ";s:3:"ḉ";s:3:"Ḉ";s:3:"ḋ";s:3:"Ḋ";s:3:"ḍ";s:3:"Ḍ";s:3:"ḏ";s:3:"Ḏ";s:3:"ḑ";s:3:"Ḑ";s:3:"ḓ";s:3:"Ḓ";s:3:"ḕ";s:3:"Ḕ";s:3:"ḗ";s:3:"Ḗ";s:3:"ḙ";s:3:"Ḙ";s:3:"ḛ";s:3:"Ḛ";s:3:"ḝ";s:3:"Ḝ";s:3:"ḟ";s:3:"Ḟ";s:3:"ḡ";s:3:"Ḡ";s:3:"ḣ";s:3:"Ḣ";s:3:"ḥ";s:3:"Ḥ";s:3:"ḧ";s:3:"Ḧ";s:3:"ḩ";s:3:"Ḩ";s:3:"ḫ";s:3:"Ḫ";s:3:"ḭ";s:3:"Ḭ";s:3:"ḯ";s:3:"Ḯ";s:3:"ḱ";s:3:"Ḱ";s:3:"ḳ";s:3:"Ḳ";s:3:"ḵ";s:3:"Ḵ";s:3:"ḷ";s:3:"Ḷ";s:3:"ḹ";s:3:"Ḹ";s:3:"ḻ";s:3:"Ḻ";s:3:"ḽ";s:3:"Ḽ";s:3:"ḿ";s:3:"Ḿ";s:3:"ṁ";s:3:"Ṁ";s:3:"ṃ";s:3:"Ṃ";s:3:"ṅ";s:3:"Ṅ";s:3:"ṇ";s:3:"Ṇ";s:3:"ṉ";s:3:"Ṉ";s:3:"ṋ";s:3:"Ṋ";s:3:"ṍ";s:3:"Ṍ";s:3:"ṏ";s:3:"Ṏ";s:3:"ṑ";s:3:"Ṑ";s:3:"ṓ";s:3:"Ṓ";s:3:"ṕ";s:3:"Ṕ";s:3:"ṗ";s:3:"Ṗ";s:3:"ṙ";s:3:"Ṙ";s:3:"ṛ";s:3:"Ṛ";s:3:"ṝ";s:3:"Ṝ";s:3:"ṟ";s:3:"Ṟ";s:3:"ṡ";s:3:"Ṡ";s:3:"ṣ";s:3:"Ṣ";s:3:"ṥ";s:3:"Ṥ";s:3:"ṧ";s:3:"Ṧ";s:3:"ṩ";s:3:"Ṩ";s:3:"ṫ";s:3:"Ṫ";s:3:"ṭ";s:3:"Ṭ";s:3:"ṯ";s:3:"Ṯ";s:3:"ṱ";s:3:"Ṱ";s:3:"ṳ";s:3:"Ṳ";s:3:"ṵ";s:3:"Ṵ";s:3:"ṷ";s:3:"Ṷ";s:3:"ṹ";s:3:"Ṹ";s:3:"ṻ";s:3:"Ṻ";s:3:"ṽ";s:3:"Ṽ";s:3:"ṿ";s:3:"Ṿ";s:3:"ẁ";s:3:"Ẁ";s:3:"ẃ";s:3:"Ẃ";s:3:"ẅ";s:3:"Ẅ";s:3:"ẇ";s:3:"Ẇ";s:3:"ẉ";s:3:"Ẉ";s:3:"ẋ";s:3:"Ẋ";s:3:"ẍ";s:3:"Ẍ";s:3:"ẏ";s:3:"Ẏ";s:3:"ẑ";s:3:"Ẑ";s:3:"ẓ";s:3:"Ẓ";s:3:"ẕ";s:3:"Ẕ";s:3:"ẛ";s:3:"Ṡ";s:3:"ạ";s:3:"Ạ";s:3:"ả";s:3:"Ả";s:3:"ấ";s:3:"Ấ";s:3:"ầ";s:3:"Ầ";s:3:"ẩ";s:3:"Ẩ";s:3:"ẫ";s:3:"Ẫ";s:3:"ậ";s:3:"Ậ";s:3:"ắ";s:3:"Ắ";s:3:"ằ";s:3:"Ằ";s:3:"ẳ";s:3:"Ẳ";s:3:"ẵ";s:3:"Ẵ";s:3:"ặ";s:3:"Ặ";s:3:"ẹ";s:3:"Ẹ";s:3:"ẻ";s:3:"Ẻ";s:3:"ẽ";s:3:"Ẽ";s:3:"ế";s:3:"Ế";s:3:"ề";s:3:"Ề";s:3:"ể";s:3:"Ể";s:3:"ễ";s:3:"Ễ";s:3:"ệ";s:3:"Ệ";s:3:"ỉ";s:3:"Ỉ";s:3:"ị";s:3:"Ị";s:3:"ọ";s:3:"Ọ";s:3:"ỏ";s:3:"Ỏ";s:3:"ố";s:3:"Ố";s:3:"ồ";s:3:"Ồ";s:3:"ổ";s:3:"Ổ";s:3:"ỗ";s:3:"Ỗ";s:3:"ộ";s:3:"Ộ";s:3:"ớ";s:3:"Ớ";s:3:"ờ";s:3:"Ờ";s:3:"ở";s:3:"Ở";s:3:"ỡ";s:3:"Ỡ";s:3:"ợ";s:3:"Ợ";s:3:"ụ";s:3:"Ụ";s:3:"ủ";s:3:"Ủ";s:3:"ứ";s:3:"Ứ";s:3:"ừ";s:3:"Ừ";s:3:"ử";s:3:"Ử";s:3:"ữ";s:3:"Ữ";s:3:"ự";s:3:"Ự";s:3:"ỳ";s:3:"Ỳ";s:3:"ỵ";s:3:"Ỵ";s:3:"ỷ";s:3:"Ỷ";s:3:"ỹ";s:3:"Ỹ";s:3:"ἀ";s:3:"Ἀ";s:3:"ἁ";s:3:"Ἁ";s:3:"ἂ";s:3:"Ἂ";s:3:"ἃ";s:3:"Ἃ";s:3:"ἄ";s:3:"Ἄ";s:3:"ἅ";s:3:"Ἅ";s:3:"ἆ";s:3:"Ἆ";s:3:"ἇ";s:3:"Ἇ";s:3:"ἐ";s:3:"Ἐ";s:3:"ἑ";s:3:"Ἑ";s:3:"ἒ";s:3:"Ἒ";s:3:"ἓ";s:3:"Ἓ";s:3:"ἔ";s:3:"Ἔ";s:3:"ἕ";s:3:"Ἕ";s:3:"ἠ";s:3:"Ἠ";s:3:"ἡ";s:3:"Ἡ";s:3:"ἢ";s:3:"Ἢ";s:3:"ἣ";s:3:"Ἣ";s:3:"ἤ";s:3:"Ἤ";s:3:"ἥ";s:3:"Ἥ";s:3:"ἦ";s:3:"Ἦ";s:3:"ἧ";s:3:"Ἧ";s:3:"ἰ";s:3:"Ἰ";s:3:"ἱ";s:3:"Ἱ";s:3:"ἲ";s:3:"Ἲ";s:3:"ἳ";s:3:"Ἳ";s:3:"ἴ";s:3:"Ἴ";s:3:"ἵ";s:3:"Ἵ";s:3:"ἶ";s:3:"Ἶ";s:3:"ἷ";s:3:"Ἷ";s:3:"ὀ";s:3:"Ὀ";s:3:"ὁ";s:3:"Ὁ";s:3:"ὂ";s:3:"Ὂ";s:3:"ὃ";s:3:"Ὃ";s:3:"ὄ";s:3:"Ὄ";s:3:"ὅ";s:3:"Ὅ";s:3:"ὑ";s:3:"Ὑ";s:3:"ὓ";s:3:"Ὓ";s:3:"ὕ";s:3:"Ὕ";s:3:"ὗ";s:3:"Ὗ";s:3:"ὠ";s:3:"Ὠ";s:3:"ὡ";s:3:"Ὡ";s:3:"ὢ";s:3:"Ὢ";s:3:"ὣ";s:3:"Ὣ";s:3:"ὤ";s:3:"Ὤ";s:3:"ὥ";s:3:"Ὥ";s:3:"ὦ";s:3:"Ὦ";s:3:"ὧ";s:3:"Ὧ";s:3:"ὰ";s:3:"Ὰ";s:3:"ά";s:3:"Ά";s:3:"ὲ";s:3:"Ὲ";s:3:"έ";s:3:"Έ";s:3:"ὴ";s:3:"Ὴ";s:3:"ή";s:3:"Ή";s:3:"ὶ";s:3:"Ὶ";s:3:"ί";s:3:"Ί";s:3:"ὸ";s:3:"Ὸ";s:3:"ό";s:3:"Ό";s:3:"ὺ";s:3:"Ὺ";s:3:"ύ";s:3:"Ύ";s:3:"ὼ";s:3:"Ὼ";s:3:"ώ";s:3:"Ώ";s:3:"ᾀ";s:3:"ᾈ";s:3:"ᾁ";s:3:"ᾉ";s:3:"ᾂ";s:3:"ᾊ";s:3:"ᾃ";s:3:"ᾋ";s:3:"ᾄ";s:3:"ᾌ";s:3:"ᾅ";s:3:"ᾍ";s:3:"ᾆ";s:3:"ᾎ";s:3:"ᾇ";s:3:"ᾏ";s:3:"ᾐ";s:3:"ᾘ";s:3:"ᾑ";s:3:"ᾙ";s:3:"ᾒ";s:3:"ᾚ";s:3:"ᾓ";s:3:"ᾛ";s:3:"ᾔ";s:3:"ᾜ";s:3:"ᾕ";s:3:"ᾝ";s:3:"ᾖ";s:3:"ᾞ";s:3:"ᾗ";s:3:"ᾟ";s:3:"ᾠ";s:3:"ᾨ";s:3:"ᾡ";s:3:"ᾩ";s:3:"ᾢ";s:3:"ᾪ";s:3:"ᾣ";s:3:"ᾫ";s:3:"ᾤ";s:3:"ᾬ";s:3:"ᾥ";s:3:"ᾭ";s:3:"ᾦ";s:3:"ᾮ";s:3:"ᾧ";s:3:"ᾯ";s:3:"ᾰ";s:3:"Ᾰ";s:3:"ᾱ";s:3:"Ᾱ";s:3:"ᾳ";s:3:"ᾼ";s:3:"ι";s:2:"Ι";s:3:"ῃ";s:3:"ῌ";s:3:"ῐ";s:3:"Ῐ";s:3:"ῑ";s:3:"Ῑ";s:3:"ῠ";s:3:"Ῠ";s:3:"ῡ";s:3:"Ῡ";s:3:"ῥ";s:3:"Ῥ";s:3:"ῳ";s:3:"ῼ";s:3:"ⅰ";s:3:"Ⅰ";s:3:"ⅱ";s:3:"Ⅱ";s:3:"ⅲ";s:3:"Ⅲ";s:3:"ⅳ";s:3:"Ⅳ";s:3:"ⅴ";s:3:"Ⅴ";s:3:"ⅵ";s:3:"Ⅵ";s:3:"ⅶ";s:3:"Ⅶ";s:3:"ⅷ";s:3:"Ⅷ";s:3:"ⅸ";s:3:"Ⅸ";s:3:"ⅹ";s:3:"Ⅹ";s:3:"ⅺ";s:3:"Ⅺ";s:3:"ⅻ";s:3:"Ⅻ";s:3:"ⅼ";s:3:"Ⅼ";s:3:"ⅽ";s:3:"Ⅽ";s:3:"ⅾ";s:3:"Ⅾ";s:3:"ⅿ";s:3:"Ⅿ";s:3:"ⓐ";s:3:"Ⓐ";s:3:"ⓑ";s:3:"Ⓑ";s:3:"ⓒ";s:3:"Ⓒ";s:3:"ⓓ";s:3:"Ⓓ";s:3:"ⓔ";s:3:"Ⓔ";s:3:"ⓕ";s:3:"Ⓕ";s:3:"ⓖ";s:3:"Ⓖ";s:3:"ⓗ";s:3:"Ⓗ";s:3:"ⓘ";s:3:"Ⓘ";s:3:"ⓙ";s:3:"Ⓙ";s:3:"ⓚ";s:3:"Ⓚ";s:3:"ⓛ";s:3:"Ⓛ";s:3:"ⓜ";s:3:"Ⓜ";s:3:"ⓝ";s:3:"Ⓝ";s:3:"ⓞ";s:3:"Ⓞ";s:3:"ⓟ";s:3:"Ⓟ";s:3:"ⓠ";s:3:"Ⓠ";s:3:"ⓡ";s:3:"Ⓡ";s:3:"ⓢ";s:3:"Ⓢ";s:3:"ⓣ";s:3:"Ⓣ";s:3:"ⓤ";s:3:"Ⓤ";s:3:"ⓥ";s:3:"Ⓥ";s:3:"ⓦ";s:3:"Ⓦ";s:3:"ⓧ";s:3:"Ⓧ";s:3:"ⓨ";s:3:"Ⓨ";s:3:"ⓩ";s:3:"Ⓩ";s:3:"a";s:3:"A";s:3:"b";s:3:"B";s:3:"c";s:3:"C";s:3:"d";s:3:"D";s:3:"e";s:3:"E";s:3:"f";s:3:"F";s:3:"g";s:3:"G";s:3:"h";s:3:"H";s:3:"i";s:3:"I";s:3:"j";s:3:"J";s:3:"k";s:3:"K";s:3:"l";s:3:"L";s:3:"m";s:3:"M";s:3:"n";s:3:"N";s:3:"o";s:3:"O";s:3:"p";s:3:"P";s:3:"q";s:3:"Q";s:3:"r";s:3:"R";s:3:"s";s:3:"S";s:3:"t";s:3:"T";s:3:"u";s:3:"U";s:3:"v";s:3:"V";s:3:"w";s:3:"W";s:3:"x";s:3:"X";s:3:"y";s:3:"Y";s:3:"z";s:3:"Z";s:4:"𐐨";s:4:"𐐀";s:4:"𐐩";s:4:"𐐁";s:4:"𐐪";s:4:"𐐂";s:4:"𐐫";s:4:"𐐃";s:4:"𐐬";s:4:"𐐄";s:4:"𐐭";s:4:"𐐅";s:4:"𐐮";s:4:"𐐆";s:4:"𐐯";s:4:"𐐇";s:4:"𐐰";s:4:"𐐈";s:4:"𐐱";s:4:"𐐉";s:4:"𐐲";s:4:"𐐊";s:4:"𐐳";s:4:"𐐋";s:4:"𐐴";s:4:"𐐌";s:4:"𐐵";s:4:"𐐍";s:4:"𐐶";s:4:"𐐎";s:4:"𐐷";s:4:"𐐏";s:4:"𐐸";s:4:"𐐐";s:4:"𐐹";s:4:"𐐑";s:4:"𐐺";s:4:"𐐒";s:4:"𐐻";s:4:"𐐓";s:4:"𐐼";s:4:"𐐔";s:4:"𐐽";s:4:"𐐕";s:4:"𐐾";s:4:"𐐖";s:4:"𐐿";s:4:"𐐗";s:4:"𐑀";s:4:"𐐘";s:4:"𐑁";s:4:"𐐙";s:4:"𐑂";s:4:"𐐚";s:4:"𐑃";s:4:"𐐛";s:4:"𐑄";s:4:"𐐜";s:4:"𐑅";s:4:"𐐝";s:4:"𐑆";s:4:"𐐞";s:4:"𐑇";s:4:"𐐟";s:4:"𐑈";s:4:"𐐠";s:4:"𐑉";s:4:"𐐡";s:4:"𐑊";s:4:"𐐢";s:4:"𐑋";s:4:"𐐣";s:4:"𐑌";s:4:"𐐤";s:4:"𐑍";s:4:"𐐥";}s:14:"wikiLowerChars";a:735:{s:1:"A";s:1:"a";s:1:"B";s:1:"b";s:1:"C";s:1:"c";s:1:"D";s:1:"d";s:1:"E";s:1:"e";s:1:"F";s:1:"f";s:1:"G";s:1:"g";s:1:"H";s:1:"h";s:1:"I";s:1:"i";s:1:"J";s:1:"j";s:1:"K";s:1:"k";s:1:"L";s:1:"l";s:1:"M";s:1:"m";s:1:"N";s:1:"n";s:1:"O";s:1:"o";s:1:"P";s:1:"p";s:1:"Q";s:1:"q";s:1:"R";s:1:"r";s:1:"S";s:1:"s";s:1:"T";s:1:"t";s:1:"U";s:1:"u";s:1:"V";s:1:"v";s:1:"W";s:1:"w";s:1:"X";s:1:"x";s:1:"Y";s:1:"y";s:1:"Z";s:1:"z";s:2:"À";s:2:"à";s:2:"Á";s:2:"á";s:2:"Â";s:2:"â";s:2:"Ã";s:2:"ã";s:2:"Ä";s:2:"ä";s:2:"Å";s:2:"å";s:2:"Æ";s:2:"æ";s:2:"Ç";s:2:"ç";s:2:"È";s:2:"è";s:2:"É";s:2:"é";s:2:"Ê";s:2:"ê";s:2:"Ë";s:2:"ë";s:2:"Ì";s:2:"ì";s:2:"Í";s:2:"í";s:2:"Î";s:2:"î";s:2:"Ï";s:2:"ï";s:2:"Ð";s:2:"ð";s:2:"Ñ";s:2:"ñ";s:2:"Ò";s:2:"ò";s:2:"Ó";s:2:"ó";s:2:"Ô";s:2:"ô";s:2:"Õ";s:2:"õ";s:2:"Ö";s:2:"ö";s:2:"Ø";s:2:"ø";s:2:"Ù";s:2:"ù";s:2:"Ú";s:2:"ú";s:2:"Û";s:2:"û";s:2:"Ü";s:2:"ü";s:2:"Ý";s:2:"ý";s:2:"Þ";s:2:"þ";s:2:"Ā";s:2:"ā";s:2:"Ă";s:2:"ă";s:2:"Ą";s:2:"ą";s:2:"Ć";s:2:"ć";s:2:"Ĉ";s:2:"ĉ";s:2:"Ċ";s:2:"ċ";s:2:"Č";s:2:"č";s:2:"Ď";s:2:"ď";s:2:"Đ";s:2:"đ";s:2:"Ē";s:2:"ē";s:2:"Ĕ";s:2:"ĕ";s:2:"Ė";s:2:"ė";s:2:"Ę";s:2:"ę";s:2:"Ě";s:2:"ě";s:2:"Ĝ";s:2:"ĝ";s:2:"Ğ";s:2:"ğ";s:2:"Ġ";s:2:"ġ";s:2:"Ģ";s:2:"ģ";s:2:"Ĥ";s:2:"ĥ";s:2:"Ħ";s:2:"ħ";s:2:"Ĩ";s:2:"ĩ";s:2:"Ī";s:2:"ī";s:2:"Ĭ";s:2:"ĭ";s:2:"Į";s:2:"į";s:2:"İ";s:1:"i";s:2:"IJ";s:2:"ij";s:2:"Ĵ";s:2:"ĵ";s:2:"Ķ";s:2:"ķ";s:2:"Ĺ";s:2:"ĺ";s:2:"Ļ";s:2:"ļ";s:2:"Ľ";s:2:"ľ";s:2:"Ŀ";s:2:"ŀ";s:2:"Ł";s:2:"ł";s:2:"Ń";s:2:"ń";s:2:"Ņ";s:2:"ņ";s:2:"Ň";s:2:"ň";s:2:"Ŋ";s:2:"ŋ";s:2:"Ō";s:2:"ō";s:2:"Ŏ";s:2:"ŏ";s:2:"Ő";s:2:"ő";s:2:"Œ";s:2:"œ";s:2:"Ŕ";s:2:"ŕ";s:2:"Ŗ";s:2:"ŗ";s:2:"Ř";s:2:"ř";s:2:"Ś";s:2:"ś";s:2:"Ŝ";s:2:"ŝ";s:2:"Ş";s:2:"ş";s:2:"Š";s:2:"š";s:2:"Ţ";s:2:"ţ";s:2:"Ť";s:2:"ť";s:2:"Ŧ";s:2:"ŧ";s:2:"Ũ";s:2:"ũ";s:2:"Ū";s:2:"ū";s:2:"Ŭ";s:2:"ŭ";s:2:"Ů";s:2:"ů";s:2:"Ű";s:2:"ű";s:2:"Ų";s:2:"ų";s:2:"Ŵ";s:2:"ŵ";s:2:"Ŷ";s:2:"ŷ";s:2:"Ÿ";s:2:"ÿ";s:2:"Ź";s:2:"ź";s:2:"Ż";s:2:"ż";s:2:"Ž";s:2:"ž";s:2:"Ɓ";s:2:"ɓ";s:2:"Ƃ";s:2:"ƃ";s:2:"Ƅ";s:2:"ƅ";s:2:"Ɔ";s:2:"ɔ";s:2:"Ƈ";s:2:"ƈ";s:2:"Ɖ";s:2:"ɖ";s:2:"Ɗ";s:2:"ɗ";s:2:"Ƌ";s:2:"ƌ";s:2:"Ǝ";s:2:"ǝ";s:2:"Ə";s:2:"ə";s:2:"Ɛ";s:2:"ɛ";s:2:"Ƒ";s:2:"ƒ";s:2:"Ɠ";s:2:"ɠ";s:2:"Ɣ";s:2:"ɣ";s:2:"Ɩ";s:2:"ɩ";s:2:"Ɨ";s:2:"ɨ";s:2:"Ƙ";s:2:"ƙ";s:2:"Ɯ";s:2:"ɯ";s:2:"Ɲ";s:2:"ɲ";s:2:"Ɵ";s:2:"ɵ";s:2:"Ơ";s:2:"ơ";s:2:"Ƣ";s:2:"ƣ";s:2:"Ƥ";s:2:"ƥ";s:2:"Ʀ";s:2:"ʀ";s:2:"Ƨ";s:2:"ƨ";s:2:"Ʃ";s:2:"ʃ";s:2:"Ƭ";s:2:"ƭ";s:2:"Ʈ";s:2:"ʈ";s:2:"Ư";s:2:"ư";s:2:"Ʊ";s:2:"ʊ";s:2:"Ʋ";s:2:"ʋ";s:2:"Ƴ";s:2:"ƴ";s:2:"Ƶ";s:2:"ƶ";s:2:"Ʒ";s:2:"ʒ";s:2:"Ƹ";s:2:"ƹ";s:2:"Ƽ";s:2:"ƽ";s:2:"DŽ";s:2:"dž";s:2:"Dž";s:2:"dž";s:2:"LJ";s:2:"lj";s:2:"Lj";s:2:"lj";s:2:"NJ";s:2:"nj";s:2:"Nj";s:2:"nj";s:2:"Ǎ";s:2:"ǎ";s:2:"Ǐ";s:2:"ǐ";s:2:"Ǒ";s:2:"ǒ";s:2:"Ǔ";s:2:"ǔ";s:2:"Ǖ";s:2:"ǖ";s:2:"Ǘ";s:2:"ǘ";s:2:"Ǚ";s:2:"ǚ";s:2:"Ǜ";s:2:"ǜ";s:2:"Ǟ";s:2:"ǟ";s:2:"Ǡ";s:2:"ǡ";s:2:"Ǣ";s:2:"ǣ";s:2:"Ǥ";s:2:"ǥ";s:2:"Ǧ";s:2:"ǧ";s:2:"Ǩ";s:2:"ǩ";s:2:"Ǫ";s:2:"ǫ";s:2:"Ǭ";s:2:"ǭ";s:2:"Ǯ";s:2:"ǯ";s:2:"DZ";s:2:"dz";s:2:"Dz";s:2:"dz";s:2:"Ǵ";s:2:"ǵ";s:2:"Ƕ";s:2:"ƕ";s:2:"Ƿ";s:2:"ƿ";s:2:"Ǹ";s:2:"ǹ";s:2:"Ǻ";s:2:"ǻ";s:2:"Ǽ";s:2:"ǽ";s:2:"Ǿ";s:2:"ǿ";s:2:"Ȁ";s:2:"ȁ";s:2:"Ȃ";s:2:"ȃ";s:2:"Ȅ";s:2:"ȅ";s:2:"Ȇ";s:2:"ȇ";s:2:"Ȉ";s:2:"ȉ";s:2:"Ȋ";s:2:"ȋ";s:2:"Ȍ";s:2:"ȍ";s:2:"Ȏ";s:2:"ȏ";s:2:"Ȑ";s:2:"ȑ";s:2:"Ȓ";s:2:"ȓ";s:2:"Ȕ";s:2:"ȕ";s:2:"Ȗ";s:2:"ȗ";s:2:"Ș";s:2:"ș";s:2:"Ț";s:2:"ț";s:2:"Ȝ";s:2:"ȝ";s:2:"Ȟ";s:2:"ȟ";s:2:"Ȣ";s:2:"ȣ";s:2:"Ȥ";s:2:"ȥ";s:2:"Ȧ";s:2:"ȧ";s:2:"Ȩ";s:2:"ȩ";s:2:"Ȫ";s:2:"ȫ";s:2:"Ȭ";s:2:"ȭ";s:2:"Ȯ";s:2:"ȯ";s:2:"Ȱ";s:2:"ȱ";s:2:"Ȳ";s:2:"ȳ";s:2:"Ά";s:2:"ά";s:2:"Έ";s:2:"έ";s:2:"Ή";s:2:"ή";s:2:"Ί";s:2:"ί";s:2:"Ό";s:2:"ό";s:2:"Ύ";s:2:"ύ";s:2:"Ώ";s:2:"ώ";s:2:"Α";s:2:"α";s:2:"Β";s:2:"β";s:2:"Γ";s:2:"γ";s:2:"Δ";s:2:"δ";s:2:"Ε";s:2:"ε";s:2:"Ζ";s:2:"ζ";s:2:"Η";s:2:"η";s:2:"Θ";s:2:"θ";s:2:"Ι";s:2:"ι";s:2:"Κ";s:2:"κ";s:2:"Λ";s:2:"λ";s:2:"Μ";s:2:"μ";s:2:"Ν";s:2:"ν";s:2:"Ξ";s:2:"ξ";s:2:"Ο";s:2:"ο";s:2:"Π";s:2:"π";s:2:"Ρ";s:2:"ρ";s:2:"Σ";s:2:"σ";s:2:"Τ";s:2:"τ";s:2:"Υ";s:2:"υ";s:2:"Φ";s:2:"φ";s:2:"Χ";s:2:"χ";s:2:"Ψ";s:2:"ψ";s:2:"Ω";s:2:"ω";s:2:"Ϊ";s:2:"ϊ";s:2:"Ϋ";s:2:"ϋ";s:2:"Ϛ";s:2:"ϛ";s:2:"Ϝ";s:2:"ϝ";s:2:"Ϟ";s:2:"ϟ";s:2:"Ϡ";s:2:"ϡ";s:2:"Ϣ";s:2:"ϣ";s:2:"Ϥ";s:2:"ϥ";s:2:"Ϧ";s:2:"ϧ";s:2:"Ϩ";s:2:"ϩ";s:2:"Ϫ";s:2:"ϫ";s:2:"Ϭ";s:2:"ϭ";s:2:"Ϯ";s:2:"ϯ";s:2:"ϴ";s:2:"θ";s:2:"Ѐ";s:2:"ѐ";s:2:"Ё";s:2:"ё";s:2:"Ђ";s:2:"ђ";s:2:"Ѓ";s:2:"ѓ";s:2:"Є";s:2:"є";s:2:"Ѕ";s:2:"ѕ";s:2:"І";s:2:"і";s:2:"Ї";s:2:"ї";s:2:"Ј";s:2:"ј";s:2:"Љ";s:2:"љ";s:2:"Њ";s:2:"њ";s:2:"Ћ";s:2:"ћ";s:2:"Ќ";s:2:"ќ";s:2:"Ѝ";s:2:"ѝ";s:2:"Ў";s:2:"ў";s:2:"Џ";s:2:"џ";s:2:"А";s:2:"а";s:2:"Б";s:2:"б";s:2:"В";s:2:"в";s:2:"Г";s:2:"г";s:2:"Д";s:2:"д";s:2:"Е";s:2:"е";s:2:"Ж";s:2:"ж";s:2:"З";s:2:"з";s:2:"И";s:2:"и";s:2:"Й";s:2:"й";s:2:"К";s:2:"к";s:2:"Л";s:2:"л";s:2:"М";s:2:"м";s:2:"Н";s:2:"н";s:2:"О";s:2:"о";s:2:"П";s:2:"п";s:2:"Р";s:2:"р";s:2:"С";s:2:"с";s:2:"Т";s:2:"т";s:2:"У";s:2:"у";s:2:"Ф";s:2:"ф";s:2:"Х";s:2:"х";s:2:"Ц";s:2:"ц";s:2:"Ч";s:2:"ч";s:2:"Ш";s:2:"ш";s:2:"Щ";s:2:"щ";s:2:"Ъ";s:2:"ъ";s:2:"Ы";s:2:"ы";s:2:"Ь";s:2:"ь";s:2:"Э";s:2:"э";s:2:"Ю";s:2:"ю";s:2:"Я";s:2:"я";s:2:"Ѡ";s:2:"ѡ";s:2:"Ѣ";s:2:"ѣ";s:2:"Ѥ";s:2:"ѥ";s:2:"Ѧ";s:2:"ѧ";s:2:"Ѩ";s:2:"ѩ";s:2:"Ѫ";s:2:"ѫ";s:2:"Ѭ";s:2:"ѭ";s:2:"Ѯ";s:2:"ѯ";s:2:"Ѱ";s:2:"ѱ";s:2:"Ѳ";s:2:"ѳ";s:2:"Ѵ";s:2:"ѵ";s:2:"Ѷ";s:2:"ѷ";s:2:"Ѹ";s:2:"ѹ";s:2:"Ѻ";s:2:"ѻ";s:2:"Ѽ";s:2:"ѽ";s:2:"Ѿ";s:2:"ѿ";s:2:"Ҁ";s:2:"ҁ";s:2:"Ҍ";s:2:"ҍ";s:2:"Ҏ";s:2:"ҏ";s:2:"Ґ";s:2:"ґ";s:2:"Ғ";s:2:"ғ";s:2:"Ҕ";s:2:"ҕ";s:2:"Җ";s:2:"җ";s:2:"Ҙ";s:2:"ҙ";s:2:"Қ";s:2:"қ";s:2:"Ҝ";s:2:"ҝ";s:2:"Ҟ";s:2:"ҟ";s:2:"Ҡ";s:2:"ҡ";s:2:"Ң";s:2:"ң";s:2:"Ҥ";s:2:"ҥ";s:2:"Ҧ";s:2:"ҧ";s:2:"Ҩ";s:2:"ҩ";s:2:"Ҫ";s:2:"ҫ";s:2:"Ҭ";s:2:"ҭ";s:2:"Ү";s:2:"ү";s:2:"Ұ";s:2:"ұ";s:2:"Ҳ";s:2:"ҳ";s:2:"Ҵ";s:2:"ҵ";s:2:"Ҷ";s:2:"ҷ";s:2:"Ҹ";s:2:"ҹ";s:2:"Һ";s:2:"һ";s:2:"Ҽ";s:2:"ҽ";s:2:"Ҿ";s:2:"ҿ";s:2:"Ӂ";s:2:"ӂ";s:2:"Ӄ";s:2:"ӄ";s:2:"Ӈ";s:2:"ӈ";s:2:"Ӌ";s:2:"ӌ";s:2:"Ӑ";s:2:"ӑ";s:2:"Ӓ";s:2:"ӓ";s:2:"Ӕ";s:2:"ӕ";s:2:"Ӗ";s:2:"ӗ";s:2:"Ә";s:2:"ә";s:2:"Ӛ";s:2:"ӛ";s:2:"Ӝ";s:2:"ӝ";s:2:"Ӟ";s:2:"ӟ";s:2:"Ӡ";s:2:"ӡ";s:2:"Ӣ";s:2:"ӣ";s:2:"Ӥ";s:2:"ӥ";s:2:"Ӧ";s:2:"ӧ";s:2:"Ө";s:2:"ө";s:2:"Ӫ";s:2:"ӫ";s:2:"Ӭ";s:2:"ӭ";s:2:"Ӯ";s:2:"ӯ";s:2:"Ӱ";s:2:"ӱ";s:2:"Ӳ";s:2:"ӳ";s:2:"Ӵ";s:2:"ӵ";s:2:"Ӹ";s:2:"ӹ";s:2:"Ա";s:2:"ա";s:2:"Բ";s:2:"բ";s:2:"Գ";s:2:"գ";s:2:"Դ";s:2:"դ";s:2:"Ե";s:2:"ե";s:2:"Զ";s:2:"զ";s:2:"Է";s:2:"է";s:2:"Ը";s:2:"ը";s:2:"Թ";s:2:"թ";s:2:"Ժ";s:2:"ժ";s:2:"Ի";s:2:"ի";s:2:"Լ";s:2:"լ";s:2:"Խ";s:2:"խ";s:2:"Ծ";s:2:"ծ";s:2:"Կ";s:2:"կ";s:2:"Հ";s:2:"հ";s:2:"Ձ";s:2:"ձ";s:2:"Ղ";s:2:"ղ";s:2:"Ճ";s:2:"ճ";s:2:"Մ";s:2:"մ";s:2:"Յ";s:2:"յ";s:2:"Ն";s:2:"ն";s:2:"Շ";s:2:"շ";s:2:"Ո";s:2:"ո";s:2:"Չ";s:2:"չ";s:2:"Պ";s:2:"պ";s:2:"Ջ";s:2:"ջ";s:2:"Ռ";s:2:"ռ";s:2:"Ս";s:2:"ս";s:2:"Վ";s:2:"վ";s:2:"Տ";s:2:"տ";s:2:"Ր";s:2:"ր";s:2:"Ց";s:2:"ց";s:2:"Ւ";s:2:"ւ";s:2:"Փ";s:2:"փ";s:2:"Ք";s:2:"ք";s:2:"Օ";s:2:"օ";s:2:"Ֆ";s:2:"ֆ";s:3:"Ḁ";s:3:"ḁ";s:3:"Ḃ";s:3:"ḃ";s:3:"Ḅ";s:3:"ḅ";s:3:"Ḇ";s:3:"ḇ";s:3:"Ḉ";s:3:"ḉ";s:3:"Ḋ";s:3:"ḋ";s:3:"Ḍ";s:3:"ḍ";s:3:"Ḏ";s:3:"ḏ";s:3:"Ḑ";s:3:"ḑ";s:3:"Ḓ";s:3:"ḓ";s:3:"Ḕ";s:3:"ḕ";s:3:"Ḗ";s:3:"ḗ";s:3:"Ḙ";s:3:"ḙ";s:3:"Ḛ";s:3:"ḛ";s:3:"Ḝ";s:3:"ḝ";s:3:"Ḟ";s:3:"ḟ";s:3:"Ḡ";s:3:"ḡ";s:3:"Ḣ";s:3:"ḣ";s:3:"Ḥ";s:3:"ḥ";s:3:"Ḧ";s:3:"ḧ";s:3:"Ḩ";s:3:"ḩ";s:3:"Ḫ";s:3:"ḫ";s:3:"Ḭ";s:3:"ḭ";s:3:"Ḯ";s:3:"ḯ";s:3:"Ḱ";s:3:"ḱ";s:3:"Ḳ";s:3:"ḳ";s:3:"Ḵ";s:3:"ḵ";s:3:"Ḷ";s:3:"ḷ";s:3:"Ḹ";s:3:"ḹ";s:3:"Ḻ";s:3:"ḻ";s:3:"Ḽ";s:3:"ḽ";s:3:"Ḿ";s:3:"ḿ";s:3:"Ṁ";s:3:"ṁ";s:3:"Ṃ";s:3:"ṃ";s:3:"Ṅ";s:3:"ṅ";s:3:"Ṇ";s:3:"ṇ";s:3:"Ṉ";s:3:"ṉ";s:3:"Ṋ";s:3:"ṋ";s:3:"Ṍ";s:3:"ṍ";s:3:"Ṏ";s:3:"ṏ";s:3:"Ṑ";s:3:"ṑ";s:3:"Ṓ";s:3:"ṓ";s:3:"Ṕ";s:3:"ṕ";s:3:"Ṗ";s:3:"ṗ";s:3:"Ṙ";s:3:"ṙ";s:3:"Ṛ";s:3:"ṛ";s:3:"Ṝ";s:3:"ṝ";s:3:"Ṟ";s:3:"ṟ";s:3:"Ṡ";s:3:"ṡ";s:3:"Ṣ";s:3:"ṣ";s:3:"Ṥ";s:3:"ṥ";s:3:"Ṧ";s:3:"ṧ";s:3:"Ṩ";s:3:"ṩ";s:3:"Ṫ";s:3:"ṫ";s:3:"Ṭ";s:3:"ṭ";s:3:"Ṯ";s:3:"ṯ";s:3:"Ṱ";s:3:"ṱ";s:3:"Ṳ";s:3:"ṳ";s:3:"Ṵ";s:3:"ṵ";s:3:"Ṷ";s:3:"ṷ";s:3:"Ṹ";s:3:"ṹ";s:3:"Ṻ";s:3:"ṻ";s:3:"Ṽ";s:3:"ṽ";s:3:"Ṿ";s:3:"ṿ";s:3:"Ẁ";s:3:"ẁ";s:3:"Ẃ";s:3:"ẃ";s:3:"Ẅ";s:3:"ẅ";s:3:"Ẇ";s:3:"ẇ";s:3:"Ẉ";s:3:"ẉ";s:3:"Ẋ";s:3:"ẋ";s:3:"Ẍ";s:3:"ẍ";s:3:"Ẏ";s:3:"ẏ";s:3:"Ẑ";s:3:"ẑ";s:3:"Ẓ";s:3:"ẓ";s:3:"Ẕ";s:3:"ẕ";s:3:"Ạ";s:3:"ạ";s:3:"Ả";s:3:"ả";s:3:"Ấ";s:3:"ấ";s:3:"Ầ";s:3:"ầ";s:3:"Ẩ";s:3:"ẩ";s:3:"Ẫ";s:3:"ẫ";s:3:"Ậ";s:3:"ậ";s:3:"Ắ";s:3:"ắ";s:3:"Ằ";s:3:"ằ";s:3:"Ẳ";s:3:"ẳ";s:3:"Ẵ";s:3:"ẵ";s:3:"Ặ";s:3:"ặ";s:3:"Ẹ";s:3:"ẹ";s:3:"Ẻ";s:3:"ẻ";s:3:"Ẽ";s:3:"ẽ";s:3:"Ế";s:3:"ế";s:3:"Ề";s:3:"ề";s:3:"Ể";s:3:"ể";s:3:"Ễ";s:3:"ễ";s:3:"Ệ";s:3:"ệ";s:3:"Ỉ";s:3:"ỉ";s:3:"Ị";s:3:"ị";s:3:"Ọ";s:3:"ọ";s:3:"Ỏ";s:3:"ỏ";s:3:"Ố";s:3:"ố";s:3:"Ồ";s:3:"ồ";s:3:"Ổ";s:3:"ổ";s:3:"Ỗ";s:3:"ỗ";s:3:"Ộ";s:3:"ộ";s:3:"Ớ";s:3:"ớ";s:3:"Ờ";s:3:"ờ";s:3:"Ở";s:3:"ở";s:3:"Ỡ";s:3:"ỡ";s:3:"Ợ";s:3:"ợ";s:3:"Ụ";s:3:"ụ";s:3:"Ủ";s:3:"ủ";s:3:"Ứ";s:3:"ứ";s:3:"Ừ";s:3:"ừ";s:3:"Ử";s:3:"ử";s:3:"Ữ";s:3:"ữ";s:3:"Ự";s:3:"ự";s:3:"Ỳ";s:3:"ỳ";s:3:"Ỵ";s:3:"ỵ";s:3:"Ỷ";s:3:"ỷ";s:3:"Ỹ";s:3:"ỹ";s:3:"Ἀ";s:3:"ἀ";s:3:"Ἁ";s:3:"ἁ";s:3:"Ἂ";s:3:"ἂ";s:3:"Ἃ";s:3:"ἃ";s:3:"Ἄ";s:3:"ἄ";s:3:"Ἅ";s:3:"ἅ";s:3:"Ἆ";s:3:"ἆ";s:3:"Ἇ";s:3:"ἇ";s:3:"Ἐ";s:3:"ἐ";s:3:"Ἑ";s:3:"ἑ";s:3:"Ἒ";s:3:"ἒ";s:3:"Ἓ";s:3:"ἓ";s:3:"Ἔ";s:3:"ἔ";s:3:"Ἕ";s:3:"ἕ";s:3:"Ἠ";s:3:"ἠ";s:3:"Ἡ";s:3:"ἡ";s:3:"Ἢ";s:3:"ἢ";s:3:"Ἣ";s:3:"ἣ";s:3:"Ἤ";s:3:"ἤ";s:3:"Ἥ";s:3:"ἥ";s:3:"Ἦ";s:3:"ἦ";s:3:"Ἧ";s:3:"ἧ";s:3:"Ἰ";s:3:"ἰ";s:3:"Ἱ";s:3:"ἱ";s:3:"Ἲ";s:3:"ἲ";s:3:"Ἳ";s:3:"ἳ";s:3:"Ἴ";s:3:"ἴ";s:3:"Ἵ";s:3:"ἵ";s:3:"Ἶ";s:3:"ἶ";s:3:"Ἷ";s:3:"ἷ";s:3:"Ὀ";s:3:"ὀ";s:3:"Ὁ";s:3:"ὁ";s:3:"Ὂ";s:3:"ὂ";s:3:"Ὃ";s:3:"ὃ";s:3:"Ὄ";s:3:"ὄ";s:3:"Ὅ";s:3:"ὅ";s:3:"Ὑ";s:3:"ὑ";s:3:"Ὓ";s:3:"ὓ";s:3:"Ὕ";s:3:"ὕ";s:3:"Ὗ";s:3:"ὗ";s:3:"Ὠ";s:3:"ὠ";s:3:"Ὡ";s:3:"ὡ";s:3:"Ὢ";s:3:"ὢ";s:3:"Ὣ";s:3:"ὣ";s:3:"Ὤ";s:3:"ὤ";s:3:"Ὥ";s:3:"ὥ";s:3:"Ὦ";s:3:"ὦ";s:3:"Ὧ";s:3:"ὧ";s:3:"ᾈ";s:3:"ᾀ";s:3:"ᾉ";s:3:"ᾁ";s:3:"ᾊ";s:3:"ᾂ";s:3:"ᾋ";s:3:"ᾃ";s:3:"ᾌ";s:3:"ᾄ";s:3:"ᾍ";s:3:"ᾅ";s:3:"ᾎ";s:3:"ᾆ";s:3:"ᾏ";s:3:"ᾇ";s:3:"ᾘ";s:3:"ᾐ";s:3:"ᾙ";s:3:"ᾑ";s:3:"ᾚ";s:3:"ᾒ";s:3:"ᾛ";s:3:"ᾓ";s:3:"ᾜ";s:3:"ᾔ";s:3:"ᾝ";s:3:"ᾕ";s:3:"ᾞ";s:3:"ᾖ";s:3:"ᾟ";s:3:"ᾗ";s:3:"ᾨ";s:3:"ᾠ";s:3:"ᾩ";s:3:"ᾡ";s:3:"ᾪ";s:3:"ᾢ";s:3:"ᾫ";s:3:"ᾣ";s:3:"ᾬ";s:3:"ᾤ";s:3:"ᾭ";s:3:"ᾥ";s:3:"ᾮ";s:3:"ᾦ";s:3:"ᾯ";s:3:"ᾧ";s:3:"Ᾰ";s:3:"ᾰ";s:3:"Ᾱ";s:3:"ᾱ";s:3:"Ὰ";s:3:"ὰ";s:3:"Ά";s:3:"ά";s:3:"ᾼ";s:3:"ᾳ";s:3:"Ὲ";s:3:"ὲ";s:3:"Έ";s:3:"έ";s:3:"Ὴ";s:3:"ὴ";s:3:"Ή";s:3:"ή";s:3:"ῌ";s:3:"ῃ";s:3:"Ῐ";s:3:"ῐ";s:3:"Ῑ";s:3:"ῑ";s:3:"Ὶ";s:3:"ὶ";s:3:"Ί";s:3:"ί";s:3:"Ῠ";s:3:"ῠ";s:3:"Ῡ";s:3:"ῡ";s:3:"Ὺ";s:3:"ὺ";s:3:"Ύ";s:3:"ύ";s:3:"Ῥ";s:3:"ῥ";s:3:"Ὸ";s:3:"ὸ";s:3:"Ό";s:3:"ό";s:3:"Ὼ";s:3:"ὼ";s:3:"Ώ";s:3:"ώ";s:3:"ῼ";s:3:"ῳ";s:3:"Ω";s:2:"ω";s:3:"K";s:1:"k";s:3:"Å";s:2:"å";s:3:"Ⅰ";s:3:"ⅰ";s:3:"Ⅱ";s:3:"ⅱ";s:3:"Ⅲ";s:3:"ⅲ";s:3:"Ⅳ";s:3:"ⅳ";s:3:"Ⅴ";s:3:"ⅴ";s:3:"Ⅵ";s:3:"ⅵ";s:3:"Ⅶ";s:3:"ⅶ";s:3:"Ⅷ";s:3:"ⅷ";s:3:"Ⅸ";s:3:"ⅸ";s:3:"Ⅹ";s:3:"ⅹ";s:3:"Ⅺ";s:3:"ⅺ";s:3:"Ⅻ";s:3:"ⅻ";s:3:"Ⅼ";s:3:"ⅼ";s:3:"Ⅽ";s:3:"ⅽ";s:3:"Ⅾ";s:3:"ⅾ";s:3:"Ⅿ";s:3:"ⅿ";s:3:"Ⓐ";s:3:"ⓐ";s:3:"Ⓑ";s:3:"ⓑ";s:3:"Ⓒ";s:3:"ⓒ";s:3:"Ⓓ";s:3:"ⓓ";s:3:"Ⓔ";s:3:"ⓔ";s:3:"Ⓕ";s:3:"ⓕ";s:3:"Ⓖ";s:3:"ⓖ";s:3:"Ⓗ";s:3:"ⓗ";s:3:"Ⓘ";s:3:"ⓘ";s:3:"Ⓙ";s:3:"ⓙ";s:3:"Ⓚ";s:3:"ⓚ";s:3:"Ⓛ";s:3:"ⓛ";s:3:"Ⓜ";s:3:"ⓜ";s:3:"Ⓝ";s:3:"ⓝ";s:3:"Ⓞ";s:3:"ⓞ";s:3:"Ⓟ";s:3:"ⓟ";s:3:"Ⓠ";s:3:"ⓠ";s:3:"Ⓡ";s:3:"ⓡ";s:3:"Ⓢ";s:3:"ⓢ";s:3:"Ⓣ";s:3:"ⓣ";s:3:"Ⓤ";s:3:"ⓤ";s:3:"Ⓥ";s:3:"ⓥ";s:3:"Ⓦ";s:3:"ⓦ";s:3:"Ⓧ";s:3:"ⓧ";s:3:"Ⓨ";s:3:"ⓨ";s:3:"Ⓩ";s:3:"ⓩ";s:3:"A";s:3:"a";s:3:"B";s:3:"b";s:3:"C";s:3:"c";s:3:"D";s:3:"d";s:3:"E";s:3:"e";s:3:"F";s:3:"f";s:3:"G";s:3:"g";s:3:"H";s:3:"h";s:3:"I";s:3:"i";s:3:"J";s:3:"j";s:3:"K";s:3:"k";s:3:"L";s:3:"l";s:3:"M";s:3:"m";s:3:"N";s:3:"n";s:3:"O";s:3:"o";s:3:"P";s:3:"p";s:3:"Q";s:3:"q";s:3:"R";s:3:"r";s:3:"S";s:3:"s";s:3:"T";s:3:"t";s:3:"U";s:3:"u";s:3:"V";s:3:"v";s:3:"W";s:3:"w";s:3:"X";s:3:"x";s:3:"Y";s:3:"y";s:3:"Z";s:3:"z";s:4:"𐐀";s:4:"𐐨";s:4:"𐐁";s:4:"𐐩";s:4:"𐐂";s:4:"𐐪";s:4:"𐐃";s:4:"𐐫";s:4:"𐐄";s:4:"𐐬";s:4:"𐐅";s:4:"𐐭";s:4:"𐐆";s:4:"𐐮";s:4:"𐐇";s:4:"𐐯";s:4:"𐐈";s:4:"𐐰";s:4:"𐐉";s:4:"𐐱";s:4:"𐐊";s:4:"𐐲";s:4:"𐐋";s:4:"𐐳";s:4:"𐐌";s:4:"𐐴";s:4:"𐐍";s:4:"𐐵";s:4:"𐐎";s:4:"𐐶";s:4:"𐐏";s:4:"𐐷";s:4:"𐐐";s:4:"𐐸";s:4:"𐐑";s:4:"𐐹";s:4:"𐐒";s:4:"𐐺";s:4:"𐐓";s:4:"𐐻";s:4:"𐐔";s:4:"𐐼";s:4:"𐐕";s:4:"𐐽";s:4:"𐐖";s:4:"𐐾";s:4:"𐐗";s:4:"𐐿";s:4:"𐐘";s:4:"𐑀";s:4:"𐐙";s:4:"𐑁";s:4:"𐐚";s:4:"𐑂";s:4:"𐐛";s:4:"𐑃";s:4:"𐐜";s:4:"𐑄";s:4:"𐐝";s:4:"𐑅";s:4:"𐐞";s:4:"𐑆";s:4:"𐐟";s:4:"𐑇";s:4:"𐐠";s:4:"𐑈";s:4:"𐐡";s:4:"𐑉";s:4:"𐐢";s:4:"𐑊";s:4:"𐐣";s:4:"𐑋";s:4:"𐐤";s:4:"𐑌";s:4:"𐐥";s:4:"𐑍";}} \ No newline at end of file
diff --git a/serialized/serialize-localisation.php b/serialized/serialize-localisation.php
new file mode 100644
index 000000000000..925806b0b594
--- /dev/null
+++ b/serialized/serialize-localisation.php
@@ -0,0 +1,35 @@
+<?php
+
+$wgNoDBParam = true;
+$optionsWithArgs = array( 'o' );
+require_once( dirname(__FILE__).'/../maintenance/commandLine.inc' );
+require_once( dirname(__FILE__).'/serialize.php' );
+
+$stderr = fopen( 'php://stderr', 'w' );
+if ( !isset( $args[0] ) ) {
+ fwrite( $stderr, "No input file specified\n" );
+ exit( 1 );
+}
+$file = $args[0];
+$code = str_replace( 'Messages', '', basename( $file ) );
+$code = str_replace( '.php', '', $code );
+$code = strtolower( str_replace( '_', '-', $code ) );
+
+$localisation = Language::getLocalisationArray( $code, true );
+if ( wfIsWindows() ) {
+ $localisation = unixLineEndings( $localisation );
+}
+
+if ( isset( $options['o'] ) ) {
+ $out = fopen( $options['o'], 'wb' );
+ if ( !$out ) {
+ fwrite( $stderr, "Unable to open file \"{$options['o']}\" for output\n" );
+ exit( 1 );
+ }
+} else {
+ $out = fopen( 'php://stdout', 'wb' );
+}
+
+fwrite( $out, serialize( $localisation ) );
+
+?>
diff --git a/serialized/serialize.php b/serialized/serialize.php
new file mode 100644
index 000000000000..0eaf0b14729b
--- /dev/null
+++ b/serialized/serialize.php
@@ -0,0 +1,75 @@
+<?php
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ $wgNoDBParam = true;
+ $optionsWithArgs = array( 'o' );
+ require_once( dirname(__FILE__).'/../maintenance/commandLine.inc' );
+
+ $stderr = fopen( 'php://stderr', 'w' );
+ if ( !isset( $args[0] ) ) {
+ fwrite( $stderr, "No input file specified\n" );
+ exit( 1 );
+ }
+ if ( wfIsWindows() ) {
+ $files = array();
+ foreach ( $args as $arg ) {
+ $files = array_merge( $files, glob( $arg ) );
+ }
+ if ( !$files ) {
+ fwrite( $stderr, "No files found\n" );
+ }
+ } else {
+ $files = $args;
+ }
+
+ if ( isset( $options['o'] ) ) {
+ $out = fopen( $options['o'], 'wb' );
+ if ( !$out ) {
+ fwrite( $stderr, "Unable to open file \"{$options['o']}\" for output\n" );
+ exit( 1 );
+ }
+ } else {
+ $out = fopen( 'php://stdout', 'wb' );
+ }
+
+ $vars = array();
+ foreach ( $files as $inputFile ) {
+ $vars = array_merge( $vars, getVars( $inputFile ) );
+ }
+ fwrite( $out, serialize( $vars ) );
+ fclose( $out );
+ exit( 0 );
+}
+
+//----------------------------------------------------------------------------
+
+function getVars( $_gv_filename ) {
+ require( $_gv_filename );
+ $vars = get_defined_vars();
+ unset( $vars['_gv_filename'] );
+
+ # Clean up line endings
+ if ( wfIsWindows() ) {
+ $vars = unixLineEndings( $vars );
+ }
+ return $vars;
+}
+
+function unixLineEndings( $var ) {
+ static $recursionLevel = 0;
+ if ( $recursionLevel > 50 ) {
+ global $stderr;
+ fwrite( $stderr, "Error: Recursion limit exceeded. Possible circular reference in array variable.\n" );
+ exit( 2 );
+ }
+
+ if ( is_array( $var ) ) {
+ ++$recursionLevel;
+ $var = array_map( 'unixLineEndings', $var );
+ --$recursionLevel;
+ } elseif ( is_string( $var ) ) {
+ $var = str_replace( "\r\n", "\n", $var );
+ }
+ return $var;
+}
+?>
diff --git a/skins/Chick.deps.php b/skins/Chick.deps.php
new file mode 100644
index 000000000000..a178a79195f1
--- /dev/null
+++ b/skins/Chick.deps.php
@@ -0,0 +1,13 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// Chick.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+require_once('includes/SkinTemplate.php');
+require_once('MonoBook.php');
+?>
diff --git a/skins/Chick.php b/skins/Chick.php
new file mode 100644
index 000000000000..d5a4a080e5e7
--- /dev/null
+++ b/skins/Chick.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * See skin.txt
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/** */
+require_once('MonoBook.php');
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinChick extends SkinTemplate {
+ function initPage( &$out ) {
+ SkinTemplate::initPage( $out );
+ $this->skinname = 'chick';
+ $this->stylename = 'chick';
+ $this->template = 'MonoBookTemplate';
+ }
+}
+
+?>
diff --git a/skins/CologneBlue.php b/skins/CologneBlue.php
new file mode 100644
index 000000000000..6862274a561e
--- /dev/null
+++ b/skins/CologneBlue.php
@@ -0,0 +1,314 @@
+<?php
+/**
+ * See skin.txt
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinCologneBlue extends Skin {
+
+ private $searchboxes = '';
+ // How many search boxes have we made? Avoid duplicate id's.
+
+ function getStylesheet() {
+ return 'common/cologneblue.css';
+ }
+ function getSkinName() {
+ return "cologneblue";
+ }
+
+ function doBeforeContent() {
+
+ $s = "";
+ $qb = $this->qbSetting();
+ $mainPageObj = Title::newMainPage();
+
+ $s .= "\n<div id='content'>\n<div id='topbar'>" .
+ "<table width='100%' border='0' cellspacing='0' cellpadding='8'><tr>";
+
+ $s .= "<td class='top' align='left' valign='middle' nowrap='nowrap'>";
+ $s .= "<a href=\"" . $mainPageObj->escapeLocalURL() . "\">";
+ $s .= "<span id='sitetitle'>" . wfMsg( "sitetitle" ) . "</span></a>";
+
+ $s .= "</td><td class='top' align='right' valign='bottom' width='100%'>";
+ $s .= $this->sysLinks();
+ $s .= "</td></tr><tr><td valign='top'>";
+
+ $s .= "<font size='-1'><span id='sitesub'>";
+ $s .= htmlspecialchars( wfMsg( "sitesubtitle" ) ) . "</span></font>";
+ $s .= "</td><td align='right'>" ;
+
+ $s .= "<font size='-1'><span id='langlinks'>" ;
+ $s .= str_replace ( "<br />" , "" , $this->otherLanguages() );
+ $cat = $this->getCategoryLinks();
+ if( $cat ) $s .= "<br />$cat\n";
+ $s .= "<br />" . $this->pageTitleLinks();
+ $s .= "</span></font>";
+
+ $s .= "</td></tr></table>\n";
+
+ $s .= "\n</div>\n<div id='article'>";
+
+ $notice = wfGetSiteNotice();
+ if( $notice ) {
+ $s .= "\n<div id='siteNotice'>$notice</div>\n";
+ }
+ $s .= $this->pageTitle();
+ $s .= $this->pageSubtitle() . "\n";
+ return $s;
+ }
+
+ function doAfterContent()
+ {
+ global $wgOut;
+
+ $s = "\n</div><br clear='all' />\n";
+
+ $s .= "\n<div id='footer'>";
+ $s .= "<table width='98%' border='0' cellspacing='0'><tr>";
+
+ $qb = $this->qbSetting();
+ if ( 1 == $qb || 3 == $qb ) { # Left
+ $s .= $this->getQuickbarCompensator();
+ }
+ $s .= "<td class='bottom' align='center' valign='top'>";
+
+ $s .= $this->bottomLinks();
+ $s .= "\n<br />" . $this->makeKnownLinkObj( Title::newMainPage() ) . " | "
+ . $this->aboutLink() . " | "
+ . $this->searchForm( wfMsg( "qbfind" ) );
+
+ $s .= "\n<br />" . $this->pageStats();
+
+ $s .= "</td>";
+ if ( 2 == $qb ) { # Right
+ $s .= $this->getQuickbarCompensator();
+ }
+ $s .= "</tr></table>\n</div>\n</div>\n";
+
+ if ( 0 != $qb ) { $s .= $this->quickBar(); }
+ return $s;
+ }
+
+ function doGetUserStyles() {
+ global $wgOut;
+ $s = parent::doGetUserStyles();
+ $qb = $this->qbSetting();
+
+ if ( 2 == $qb ) { # Right
+ $s .= "#quickbar { position: absolute; right: 4px; }\n" .
+ "#article { margin-left: 4px; margin-right: 148px; }\n";
+ } else if ( 1 == $qb ) {
+ $s .= "#quickbar { position: absolute; left: 4px; }\n" .
+ "#article { margin-left: 148px; margin-right: 4px; }\n";
+ } else if ( 3 == $qb ) { # Floating left
+ $s .= "#quickbar { position:absolute; left:4px } \n" .
+ "#topbar { margin-left: 148px }\n" .
+ "#article { margin-left:148px; margin-right: 4px; } \n" .
+ "body>#quickbar { position:fixed; left:4px; top:4px; overflow:auto ;bottom:4px;} \n"; # Hides from IE
+ } else if ( 4 == $qb ) { # Floating right
+ $s .= "#quickbar { position: fixed; right: 4px; } \n" .
+ "#topbar { margin-right: 148px }\n" .
+ "#article { margin-right: 148px; margin-left: 4px; } \n" .
+ "body>#quickbar { position: fixed; right: 4px; top: 4px; overflow: auto ;bottom:4px;} \n"; # Hides from IE
+ }
+ return $s;
+ }
+
+ function sysLinks() {
+ global $wgUser, $wgContLang, $wgTitle;
+ $li = $wgContLang->specialPage("Userlogin");
+ $lo = $wgContLang->specialPage("Userlogout");
+
+ $rt = $wgTitle->getPrefixedURL();
+ if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
+ $q = "";
+ } else {
+ $q = "returnto={$rt}";
+ }
+
+ $s = "" .
+ $this->mainPageLink()
+ . " | " .
+ $this->makeKnownLink( wfMsgForContent( "aboutpage" ), wfMsg( "about" ) )
+ . " | " .
+ $this->makeKnownLink( wfMsgForContent( "helppage" ), wfMsg( "help" ) )
+ . " | " .
+ $this->makeKnownLink( wfMsgForContent( "faqpage" ), wfMsg("faq") )
+ . " | " .
+ $this->specialLink( "specialpages" );
+
+ /* show links to different language variants */
+ $s .= $this->variantLinks();
+ $s .= $this->extensionTabLinks();
+
+ $s .= " | ";
+ if ( $wgUser->isLoggedIn() ) {
+ $s .= $this->makeKnownLink( $lo, wfMsg( "logout" ), $q );
+ } else {
+ $s .= $this->makeKnownLink( $li, wfMsg( "login" ), $q );
+ }
+
+ return $s;
+ }
+
+ /**
+ * Compute the sidebar
+ * @access private
+ */
+ function quickBar()
+ {
+ global $wgOut, $wgTitle, $wgUser, $wgLang, $wgContLang, $wgEnableUploads;
+
+ $tns=$wgTitle->getNamespace();
+
+ $s = "\n<div id='quickbar'>";
+
+ $sep = "<br />";
+ $s .= $this->menuHead( "qbfind" );
+ $s .= $this->searchForm();
+
+ $s .= $this->menuHead( "qbbrowse" );
+
+ # Use the first heading from the Monobook sidebar as the "browse" section
+ $bar = $this->buildSidebar();
+ $browseLinks = reset( $bar );
+
+ foreach ( $browseLinks as $link ) {
+ if ( $link['text'] != '-' ) {
+ $s .= "<a href=\"{$link['href']}\">" .
+ htmlspecialchars( $link['text'] ) . '</a>' . $sep;
+ }
+ }
+
+ if ( $wgOut->isArticle() ) {
+ $s .= $this->menuHead( "qbedit" );
+ $s .= "<strong>" . $this->editThisPage() . "</strong>";
+
+ $s .= $sep . $this->makeKnownLink( wfMsgForContent( "edithelppage" ), wfMsg( "edithelp" ) );
+
+ if( $wgUser->isLoggedIn() ) {
+ $s .= $sep . $this->moveThisPage();
+ }
+ if ( $wgUser->isAllowed('delete') ) {
+ $dtp = $this->deleteThisPage();
+ if ( "" != $dtp ) {
+ $s .= $sep . $dtp;
+ }
+ }
+ if ( $wgUser->isAllowed('protect') ) {
+ $ptp = $this->protectThisPage();
+ if ( "" != $ptp ) {
+ $s .= $sep . $ptp;
+ }
+ }
+ $s .= $sep;
+
+ $s .= $this->menuHead( "qbpageoptions" );
+ $s .= $this->talkLink()
+ . $sep . $this->commentLink()
+ . $sep . $this->printableLink();
+ if ( $wgUser->isLoggedIn() ) {
+ $s .= $sep . $this->watchThisPage();
+ }
+
+ $s .= $sep;
+
+ $s .= $this->menuHead("qbpageinfo")
+ . $this->historyLink()
+ . $sep . $this->whatLinksHere()
+ . $sep . $this->watchPageLinksLink();
+
+ if( $tns == NS_USER || $tns == NS_USER_TALK ) {
+ $id=User::idFromName($wgTitle->getText());
+ if ($id != 0) {
+ $s .= $sep . $this->userContribsLink();
+ if( $this->showEmailUser( $id ) ) {
+ $s .= $sep . $this->emailUserLink();
+ }
+ }
+ }
+ $s .= $sep;
+ }
+
+ $s .= $this->menuHead( "qbmyoptions" );
+ if ( $wgUser->isLoggedIn() ) {
+ $name = $wgUser->getName();
+ $tl = $this->makeKnownLinkObj( $wgUser->getTalkPage(),
+ wfMsg( 'mytalk' ) );
+ if ( $wgUser->getNewtalk() ) {
+ $tl .= " *";
+ }
+
+ $s .= $this->makeKnownLinkObj( $wgUser->getUserPage(),
+ wfMsg( "mypage" ) )
+ . $sep . $tl
+ . $sep . $this->specialLink( "watchlist" )
+ . $sep . $this->makeKnownLinkObj( SpecialPage::getSafeTitleFor( "Contributions", $wgUser->getName() ),
+ wfMsg( "mycontris" ) )
+ . $sep . $this->specialLink( "preferences" )
+ . $sep . $this->specialLink( "userlogout" );
+ } else {
+ $s .= $this->specialLink( "userlogin" );
+ }
+
+ $s .= $this->menuHead( "qbspecialpages" )
+ . $this->specialLink( "newpages" )
+ . $sep . $this->specialLink( "imagelist" )
+ . $sep . $this->specialLink( "statistics" )
+ . $sep . $this->bugReportsLink();
+ if ( $wgUser->isLoggedIn() && $wgEnableUploads ) {
+ $s .= $sep . $this->specialLink( "upload" );
+ }
+ global $wgSiteSupportPage;
+ if( $wgSiteSupportPage) {
+ $s .= $sep."<a href=\"".htmlspecialchars($wgSiteSupportPage)."\" class =\"internal\">"
+ .wfMsg( "sitesupport" )."</a>";
+ }
+
+ $s .= $sep . $this->makeKnownLinkObj(
+ SpecialPage::getTitleFor( 'Specialpages' ),
+ wfMsg( 'moredotdotdot' ) );
+
+ $s .= $sep . "\n</div>\n";
+ return $s;
+ }
+
+ function menuHead( $key )
+ {
+ $s = "\n<h6>" . wfMsg( $key ) . "</h6>";
+ return $s;
+ }
+
+ function searchForm( $label = "" )
+ {
+ global $wgRequest;
+
+ $search = $wgRequest->getText( 'search' );
+ $action = $this->escapeSearchLink();
+ $s = "<form id=\"searchform{$this->searchboxes}\" method=\"get\" class=\"inline\" action=\"$action\">";
+ if ( "" != $label ) { $s .= "{$label}: "; }
+
+ $s .= "<input type='text' id=\"searchInput{$this->searchboxes}\" class=\"mw-searchInput\" name=\"search\" size=\"14\" value=\""
+ . htmlspecialchars(substr($search,0,256)) . "\" /><br />"
+ . "<input type='submit' id=\"searchGoButton{$this->searchboxes}\" class=\"searchButton\" name=\"go\" value=\"" . htmlspecialchars( wfMsg( "searcharticle" ) ) . "\" />"
+ . "<input type='submit' id=\"mw-searchButton{$this->searchboxes}\" class=\"searchButton\" name=\"fulltext\" value=\"" . htmlspecialchars( wfMsg( "search" ) ) . "\" /></form>";
+
+ // Ensure unique id's for search boxes made after the first
+ $this->searchboxes = $this->searchboxes == '' ? 2 : $this->searchboxes + 1;
+
+ return $s;
+ }
+}
+
+?>
diff --git a/skins/MonoBook.deps.php b/skins/MonoBook.deps.php
new file mode 100644
index 000000000000..b054c840c2c8
--- /dev/null
+++ b/skins/MonoBook.deps.php
@@ -0,0 +1,12 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// MonoBook.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+require_once('includes/SkinTemplate.php');
+?>
diff --git a/skins/MonoBook.php b/skins/MonoBook.php
new file mode 100644
index 000000000000..0b9619a277a4
--- /dev/null
+++ b/skins/MonoBook.php
@@ -0,0 +1,289 @@
+<?php
+/**
+ * MonoBook nouveau
+ *
+ * Translated from gwicke's previous TAL template version to remove
+ * dependency on PHPTAL.
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/** */
+require_once('includes/SkinTemplate.php');
+
+/**
+ * Inherit main code from SkinTemplate, set the CSS and template filter.
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinMonoBook extends SkinTemplate {
+ /** Using monobook. */
+ function initPage( &$out ) {
+ SkinTemplate::initPage( $out );
+ $this->skinname = 'monobook';
+ $this->stylename = 'monobook';
+ $this->template = 'MonoBookTemplate';
+ }
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class MonoBookTemplate extends QuickTemplate {
+ /**
+ * Template filter callback for MonoBook skin.
+ * Takes an associative array of data set from a SkinTemplate-based
+ * class, and a wrapper for MediaWiki's localization database, and
+ * outputs a formatted page.
+ *
+ * @access private
+ */
+ function execute() {
+ // Suppress warnings to prevent notices about missing indexes in $this->data
+ wfSuppressWarnings();
+
+?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="<?php $this->text('xhtmldefaultnamespace') ?>" <?php
+ foreach($this->data['xhtmlnamespaces'] as $tag => $ns) {
+ ?>xmlns:<?php echo "{$tag}=\"{$ns}\" ";
+ } ?>xml:lang="<?php $this->text('lang') ?>" lang="<?php $this->text('lang') ?>" dir="<?php $this->text('dir') ?>">
+ <head>
+ <meta http-equiv="Content-Type" content="<?php $this->text('mimetype') ?>; charset=<?php $this->text('charset') ?>" />
+ <?php $this->html('headlinks') ?>
+ <title><?php $this->text('pagetitle') ?></title>
+ <style type="text/css" media="screen,projection">/*<![CDATA[*/ @import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/main.css?<?php echo $GLOBALS['wgStyleVersion'] ?>"; /*]]>*/</style>
+ <link rel="stylesheet" type="text/css" <?php if(empty($this->data['printable']) ) { ?>media="print"<?php } ?> href="<?php $this->text('stylepath') ?>/common/commonPrint.css?<?php echo $GLOBALS['wgStyleVersion'] ?>" />
+ <link rel="stylesheet" type="text/css" media="handheld" href="<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/handheld.css?<?php echo $GLOBALS['wgStyleVersion'] ?>" />
+ <!--[if lt IE 5.5000]><style type="text/css">@import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/IE50Fixes.css?<?php echo $GLOBALS['wgStyleVersion'] ?>";</style><![endif]-->
+ <!--[if IE 5.5000]><style type="text/css">@import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/IE55Fixes.css?<?php echo $GLOBALS['wgStyleVersion'] ?>";</style><![endif]-->
+ <!--[if IE 6]><style type="text/css">@import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/IE60Fixes.css?<?php echo $GLOBALS['wgStyleVersion'] ?>";</style><![endif]-->
+ <!--[if IE 7]><style type="text/css">@import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/IE70Fixes.css?<?php echo $GLOBALS['wgStyleVersion'] ?>";</style><![endif]-->
+ <!--[if lt IE 7]><script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath') ?>/common/IEFixes.js?<?php echo $GLOBALS['wgStyleVersion'] ?>"></script>
+ <meta http-equiv="imagetoolbar" content="no" /><![endif]-->
+
+ <?php print Skin::makeGlobalVariablesScript( $this->data ); ?>
+
+ <script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath' ) ?>/common/wikibits.js?<?php echo $GLOBALS['wgStyleVersion'] ?>"><!-- wikibits js --></script>
+<?php if($this->data['jsvarurl' ]) { ?>
+ <script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('jsvarurl' ) ?>"><!-- site js --></script>
+<?php } ?>
+<?php if($this->data['pagecss' ]) { ?>
+ <style type="text/css"><?php $this->html('pagecss' ) ?></style>
+<?php }
+ if($this->data['usercss' ]) { ?>
+ <style type="text/css"><?php $this->html('usercss' ) ?></style>
+<?php }
+ if($this->data['userjs' ]) { ?>
+ <script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('userjs' ) ?>"></script>
+<?php }
+ if($this->data['userjsprev']) { ?>
+ <script type="<?php $this->text('jsmimetype') ?>"><?php $this->html('userjsprev') ?></script>
+<?php }
+ if($this->data['trackbackhtml']) print $this->data['trackbackhtml']; ?>
+ <!-- Head Scripts -->
+ <?php $this->html('headscripts') ?>
+ </head>
+<body <?php if($this->data['body_ondblclick']) { ?>ondblclick="<?php $this->text('body_ondblclick') ?>"<?php } ?>
+<?php if($this->data['body_onload' ]) { ?>onload="<?php $this->text('body_onload') ?>"<?php } ?>
+ class="mediawiki <?php $this->text('nsclass') ?> <?php $this->text('dir') ?> <?php $this->text('pageclass') ?>">
+ <div id="globalWrapper">
+ <div id="column-content">
+ <div id="content">
+ <a name="top" id="top"></a>
+ <?php if($this->data['sitenotice']) { ?><div id="siteNotice"><?php $this->html('sitenotice') ?></div><?php } ?>
+ <h1 class="firstHeading"><?php $this->data['displaytitle']!=""?$this->html('title'):$this->text('title') ?></h1>
+ <div id="bodyContent">
+ <h3 id="siteSub"><?php $this->msg('tagline') ?></h3>
+ <div id="contentSub"><?php $this->html('subtitle') ?></div>
+ <?php if($this->data['undelete']) { ?><div id="contentSub2"><?php $this->html('undelete') ?></div><?php } ?>
+ <?php if($this->data['newtalk'] ) { ?><div class="usermessage"><?php $this->html('newtalk') ?></div><?php } ?>
+ <?php if($this->data['showjumplinks']) { ?><div id="jump-to-nav"><?php $this->msg('jumpto') ?> <a href="#column-one"><?php $this->msg('jumptonavigation') ?></a>, <a href="#searchInput"><?php $this->msg('jumptosearch') ?></a></div><?php } ?>
+ <!-- start content -->
+ <?php $this->html('bodytext') ?>
+ <?php if($this->data['catlinks']) { ?><div id="catlinks"><?php $this->html('catlinks') ?></div><?php } ?>
+ <!-- end content -->
+ <div class="visualClear"></div>
+ </div>
+ </div>
+ </div>
+ <div id="column-one">
+ <div id="p-cactions" class="portlet">
+ <h5><?php $this->msg('views') ?></h5>
+ <div class="pBody">
+ <ul>
+ <?php foreach($this->data['content_actions'] as $key => $tab) { ?>
+ <li id="ca-<?php echo Sanitizer::escapeId($key) ?>"<?php
+ if($tab['class']) { ?> class="<?php echo htmlspecialchars($tab['class']) ?>"<?php }
+ ?>><a href="<?php echo htmlspecialchars($tab['href']) ?>"><?php
+ echo htmlspecialchars($tab['text']) ?></a></li>
+ <?php } ?>
+ </ul>
+ </div>
+ </div>
+ <div class="portlet" id="p-personal">
+ <h5><?php $this->msg('personaltools') ?></h5>
+ <div class="pBody">
+ <ul>
+<?php foreach($this->data['personal_urls'] as $key => $item) { ?>
+ <li id="pt-<?php echo Sanitizer::escapeId($key) ?>"<?php
+ if ($item['active']) { ?> class="active"<?php } ?>><a href="<?php
+ echo htmlspecialchars($item['href']) ?>"<?php
+ if(!empty($item['class'])) { ?> class="<?php
+ echo htmlspecialchars($item['class']) ?>"<?php } ?>><?php
+ echo htmlspecialchars($item['text']) ?></a></li>
+<?php } ?>
+ </ul>
+ </div>
+ </div>
+ <div class="portlet" id="p-logo">
+ <a style="background-image: url(<?php $this->text('logopath') ?>);" <?php
+ ?>href="<?php echo htmlspecialchars($this->data['nav_urls']['mainpage']['href'])?>" <?php
+ ?>title="<?php $this->msg('mainpage') ?>"></a>
+ </div>
+ <script type="<?php $this->text('jsmimetype') ?>"> if (window.isMSIE55) fixalpha(); </script>
+ <?php foreach ($this->data['sidebar'] as $bar => $cont) { ?>
+ <div class='portlet' id='p-<?php echo Sanitizer::escapeId($bar) ?>'>
+ <h5><?php $out = wfMsg( $bar ); if (wfEmptyMsg($bar, $out)) echo $bar; else echo $out; ?></h5>
+ <div class='pBody'>
+ <ul>
+<?php foreach($cont as $key => $val) { ?>
+ <li id="<?php echo Sanitizer::escapeId($val['id']) ?>"<?php
+ if ( $val['active'] ) { ?> class="active" <?php }
+ ?>><a href="<?php echo htmlspecialchars($val['href']) ?>"><?php echo htmlspecialchars($val['text']) ?></a></li>
+<?php } ?>
+ </ul>
+ </div>
+ </div>
+ <?php } ?>
+ <div id="p-search" class="portlet">
+ <h5><label for="searchInput"><?php $this->msg('search') ?></label></h5>
+ <div id="searchBody" class="pBody">
+ <form action="<?php $this->text('searchaction') ?>" id="searchform"><div>
+ <input id="searchInput" name="search" type="text" <?php
+ if($this->haveMsg('accesskey-search')) {
+ ?>accesskey="<?php $this->msg('accesskey-search') ?>"<?php }
+ if( isset( $this->data['search'] ) ) {
+ ?> value="<?php $this->text('search') ?>"<?php } ?> />
+ <input type='submit' name="go" class="searchButton" id="searchGoButton" value="<?php $this->msg('searcharticle') ?>" />&nbsp;
+ <input type='submit' name="fulltext" class="searchButton" id="mw-searchButton" value="<?php $this->msg('searchbutton') ?>" />
+ </div></form>
+ </div>
+ </div>
+ <div class="portlet" id="p-tb">
+ <h5><?php $this->msg('toolbox') ?></h5>
+ <div class="pBody">
+ <ul>
+<?php
+ if($this->data['notspecialpage']) { ?>
+ <li id="t-whatlinkshere"><a href="<?php
+ echo htmlspecialchars($this->data['nav_urls']['whatlinkshere']['href'])
+ ?>"><?php $this->msg('whatlinkshere') ?></a></li>
+<?php
+ if( $this->data['nav_urls']['recentchangeslinked'] ) { ?>
+ <li id="t-recentchangeslinked"><a href="<?php
+ echo htmlspecialchars($this->data['nav_urls']['recentchangeslinked']['href'])
+ ?>"><?php $this->msg('recentchangeslinked') ?></a></li>
+<?php }
+ }
+ if(isset($this->data['nav_urls']['trackbacklink'])) { ?>
+ <li id="t-trackbacklink"><a href="<?php
+ echo htmlspecialchars($this->data['nav_urls']['trackbacklink']['href'])
+ ?>"><?php $this->msg('trackbacklink') ?></a></li>
+<?php }
+ if($this->data['feeds']) { ?>
+ <li id="feedlinks"><?php foreach($this->data['feeds'] as $key => $feed) {
+ ?><span id="feed-<?php echo Sanitizer::escapeId($key) ?>"><a href="<?php
+ echo htmlspecialchars($feed['href']) ?>"><?php echo htmlspecialchars($feed['text'])?></a>&nbsp;</span>
+ <?php } ?></li><?php
+ }
+
+ foreach( array('contributions', 'blockip', 'emailuser', 'upload', 'specialpages') as $special ) {
+
+ if($this->data['nav_urls'][$special]) {
+ ?><li id="t-<?php echo $special ?>"><a href="<?php echo htmlspecialchars($this->data['nav_urls'][$special]['href'])
+ ?>"><?php $this->msg($special) ?></a></li>
+<?php }
+ }
+
+ if(!empty($this->data['nav_urls']['print']['href'])) { ?>
+ <li id="t-print"><a href="<?php echo htmlspecialchars($this->data['nav_urls']['print']['href'])
+ ?>"><?php $this->msg('printableversion') ?></a></li><?php
+ }
+
+ if(!empty($this->data['nav_urls']['permalink']['href'])) { ?>
+ <li id="t-permalink"><a href="<?php echo htmlspecialchars($this->data['nav_urls']['permalink']['href'])
+ ?>"><?php $this->msg('permalink') ?></a></li><?php
+ } elseif ($this->data['nav_urls']['permalink']['href'] === '') { ?>
+ <li id="t-ispermalink"><?php $this->msg('permalink') ?></li><?php
+ }
+
+ wfRunHooks( 'MonoBookTemplateToolboxEnd', array( &$this ) );
+?>
+ </ul>
+ </div>
+ </div>
+<?php
+ if( $this->data['language_urls'] ) { ?>
+ <div id="p-lang" class="portlet">
+ <h5><?php $this->msg('otherlanguages') ?></h5>
+ <div class="pBody">
+ <ul>
+<?php foreach($this->data['language_urls'] as $langlink) { ?>
+ <li class="<?php echo htmlspecialchars($langlink['class'])?>"><?php
+ ?><a href="<?php echo htmlspecialchars($langlink['href']) ?>"><?php echo $langlink['text'] ?></a></li>
+<?php } ?>
+ </ul>
+ </div>
+ </div>
+<?php } ?>
+ </div><!-- end of the left (by default at least) column -->
+ <div class="visualClear"></div>
+ <div id="footer">
+<?php
+ if($this->data['poweredbyico']) { ?>
+ <div id="f-poweredbyico"><?php $this->html('poweredbyico') ?></div>
+<?php }
+ if($this->data['copyrightico']) { ?>
+ <div id="f-copyrightico"><?php $this->html('copyrightico') ?></div>
+<?php }
+
+ // Generate additional footer links
+?>
+ <ul id="f-list">
+<?php
+ $footerlinks = array(
+ 'lastmod', 'viewcount', 'numberofwatchingusers', 'credits', 'copyright',
+ 'privacy', 'about', 'disclaimer', 'tagline',
+ );
+ foreach( $footerlinks as $aLink ) {
+ if( isset( $this->data[$aLink] ) && $this->data[$aLink] ) {
+?> <li id="<?php echo$aLink?>"><?php $this->html($aLink) ?></li>
+<?php }
+ }
+?>
+ </ul>
+ </div>
+
+ <?php $this->html('bottomscripts'); /* JS call to runBodyOnloadHook */ ?>
+</div>
+<?php $this->html('reporttime') ?>
+<?php if ( $this->data['debug'] ): ?>
+<!-- Debug output:
+<?php $this->text( 'debug' ); ?>
+
+-->
+<?php endif; ?>
+</body></html>
+<?php
+ wfRestoreWarnings();
+ } // end of execute() method
+} // end of class
+?>
diff --git a/skins/MySkin.deps.php b/skins/MySkin.deps.php
new file mode 100644
index 000000000000..ba00558b1071
--- /dev/null
+++ b/skins/MySkin.deps.php
@@ -0,0 +1,13 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// MySkin.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+require_once('includes/SkinTemplate.php');
+require_once('MonoBook.php');
+?>
diff --git a/skins/MySkin.php b/skins/MySkin.php
new file mode 100644
index 000000000000..cb24fdc4d87e
--- /dev/null
+++ b/skins/MySkin.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * See skin.txt
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/** */
+require_once('MonoBook.php');
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinMySkin extends SkinTemplate {
+ function initPage( &$out ) {
+ SkinTemplate::initPage( $out );
+ $this->skinname = 'myskin';
+ $this->stylename = 'myskin';
+ $this->template = 'MonoBookTemplate';
+ }
+}
+
+?>
diff --git a/skins/Nostalgia.php b/skins/Nostalgia.php
new file mode 100644
index 000000000000..3b19e41e6406
--- /dev/null
+++ b/skins/Nostalgia.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * See skin.txt
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinNostalgia extends Skin {
+
+ function getStylesheet() {
+ return 'common/nostalgia.css';
+ }
+ function getSkinName() {
+ return "nostalgia";
+ }
+
+ function doBeforeContent() {
+
+ $s = "\n<div id='content'>\n<div id='topbar'>";
+ $s .= $this->logoText( "right" );
+
+ $s .= $this->pageTitle();
+ $s .= $this->pageSubtitle() . "\n";
+
+ $s .= $this->topLinks() . "\n<br />";
+
+ $notice = wfGetSiteNotice();
+ if( $notice ) {
+ $s .= "\n<div id='siteNotice'>$notice</div>\n";
+ }
+ $s .= $this->pageTitleLinks();
+
+ $ol = $this->otherLanguages();
+ if($ol) $s .= "<br />" . $ol;
+
+ $cat = $this->getCategoryLinks();
+ if($cat) $s .= "<br />" . $cat;
+
+ $s .= "<br clear='all' /><hr />\n</div>\n";
+ $s .= "\n<div id='article'>";
+
+ return $s;
+ }
+
+ function topLinks() {
+ global $wgOut, $wgUser;
+ $sep = " |\n";
+
+ $s = $this->mainPageLink() . $sep
+ . $this->specialLink( "recentchanges" );
+
+ if ( $wgOut->isArticle() ) {
+ $s .= $sep . $this->editThisPage()
+ . $sep . $this->historyLink();
+ }
+
+ /* show links to different language variants */
+ $s .= $this->variantLinks();
+ $s .= $this->extensionTabLinks();
+
+ if ( $wgUser->isAnon() ) {
+ $s .= $sep . $this->specialLink( "userlogin" );
+ } else {
+ $s .= $sep . $this->specialLink( "userlogout" );
+ }
+
+ $s .= $sep . $this->specialPagesList();
+
+ return $s;
+ }
+
+ function doAfterContent() {
+ $s = "\n</div><br clear='all' />\n";
+
+ $s .= "\n<div id='footer'><hr />";
+
+ $s .= $this->bottomLinks();
+ $s .= "\n<br />" . $this->pageStats();
+ $s .= "\n<br />" . $this->mainPageLink()
+ . " | " . $this->aboutLink()
+ . " | " . $this->searchForm();
+
+ $s .= "\n</div>\n</div>\n";
+
+ return $s;
+ }
+}
+
+?>
diff --git a/skins/Simple.deps.php b/skins/Simple.deps.php
new file mode 100644
index 000000000000..369f6b00cecd
--- /dev/null
+++ b/skins/Simple.deps.php
@@ -0,0 +1,13 @@
+<?php
+// This file exists to ensure that base classes are preloaded before
+// Simple.php is compiled, working around a bug in the APC opcode
+// cache on PHP 5, where cached code can break if the include order
+// changed on a subsequent page view.
+// see http://mail.wikipedia.org/pipermail/wikitech-l/2006-January/033660.html
+
+if ( ! defined( 'MEDIAWIKI' ) )
+ die( 1 );
+
+require_once('includes/SkinTemplate.php');
+require_once('MonoBook.php');
+?>
diff --git a/skins/Simple.php b/skins/Simple.php
new file mode 100644
index 000000000000..d1ebd7d954e7
--- /dev/null
+++ b/skins/Simple.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * See skin.txt
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/** */
+require_once('MonoBook.php');
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinSimple extends SkinTemplate {
+ function initPage( &$out ) {
+ SkinTemplate::initPage( $out );
+ $this->skinname = 'simple';
+ $this->stylename = 'simple';
+ $this->template = 'MonoBookTemplate';
+ }
+
+ function reallyDoGetUserStyles() {
+ global $wgUser;
+ $s = '';
+ if (($undopt = $wgUser->getOption("underline")) != 2) {
+ $underline = $undopt ? 'underline' : 'none';
+ $s .= "a { text-decoration: $underline; }\n";
+ }
+ if ($wgUser->getOption('highlightbroken')) {
+ $s .= "a.new, #quickbar a.new { text-decoration: line-through; }\n";
+ } else {
+ $s .= <<<END
+a.new, #quickbar a.new,
+a.stub, #quickbar a.stub {
+ color: inherit;
+ text-decoration: inherit;
+}
+a.new:after, #quickbar a.new:after {
+ content: "?";
+ color: #CC2200;
+ text-decoration: $underline;
+}
+a.stub:after, #quickbar a.stub:after {
+ content: "!";
+ color: #772233;
+ text-decoration: $underline;
+}
+END;
+ }
+ if ($wgUser->getOption('justify')) {
+ $s .= "#article, #bodyContent { text-align: justify; }\n";
+ }
+ if (!$wgUser->getOption('showtoc')) {
+ $s .= "#toc { display: none; }\n";
+ }
+ if (!$wgUser->getOption('editsection')) {
+ $s .= ".editsection { display: none; }\n";
+ }
+ return $s;
+ }
+}
+
+?>
diff --git a/skins/Skin.sample b/skins/Skin.sample
new file mode 100644
index 000000000000..c011c143f50c
--- /dev/null
+++ b/skins/Skin.sample
@@ -0,0 +1,19 @@
+<?php
+# Your class extension is defined there.
+#
+# Do NOT use PHPTal with this sample, if you want PHPTal support have a look at
+# the other sample : SkinPHPTal.sample.
+#
+# The class name MUST begin with 'Skin' and the rest is the name of the file
+# excluding '.php'
+# This file is named Skin.sample (but it should end with php). So the
+# class name will be 'Skin' . 'Skin'
+
+class SkinSkin extends Skin {
+# Override method below
+#
+
+}
+
+}
+?>
diff --git a/skins/SkinPHPTal.sample b/skins/SkinPHPTal.sample
new file mode 100644
index 000000000000..683c20807068
--- /dev/null
+++ b/skins/SkinPHPTal.sample
@@ -0,0 +1,28 @@
+<?php
+require_once('includes/SkinPHPTal.php');
+
+# Test if PHPTal is enabled. If not MediaWiki will load the 'standard' skin
+# which doesnt use PHPTal
+if( class_exists( 'SkinPHPTal' ) ) {
+
+ # Your class extension is defined there.
+ #
+ # The class name MUST begin with 'Skin' and the rest is the name of the file
+ # excluding '.php'
+ # This file is named SkinPHPTal.sample (but it should end with php). So the
+ # class name will be 'Skin' . 'SkinPHPTal'
+
+ class SkinSkinPHPTal extends SkinPHPTal {
+ function initPage( &$out ) {
+ SkinPHPTal::initPage( $out );
+ $this->skinname = 'name of your skin all lower case';
+ $this->template = 'phptal template used do not put the .pt';
+ }
+
+ # Override method below
+ #
+
+ }
+
+}
+?>
diff --git a/skins/Standard.php b/skins/Standard.php
new file mode 100644
index 000000000000..517fd194307c
--- /dev/null
+++ b/skins/Standard.php
@@ -0,0 +1,304 @@
+<?php
+/**
+ * See skin.txt
+ *
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinStandard extends Skin {
+
+ /**
+ *
+ */
+ function getHeadScripts() {
+ global $wgStylePath, $wgJsMimeType, $wgStyleVersion;
+
+ $s = parent::getHeadScripts();
+ if ( 3 == $this->qbSetting() ) { # Floating left
+ $s .= "<script language='javascript' type='$wgJsMimeType' " .
+ "src='{$wgStylePath}/common/sticky.js?$wgStyleVersion'></script>\n";
+ }
+ return $s;
+ }
+
+ /**
+ *
+ */
+ function getUserStyles() {
+ global $wgStylePath, $wgStyleVersion;
+ $s = '';
+ if ( 3 == $this->qbSetting() ) { # Floating left
+ $s .= "<style type='text/css'>\n" .
+ "@import '{$wgStylePath}/common/quickbar.css?$wgStyleVersion';\n</style>\n";
+ } else if ( 4 == $this->qbSetting() ) { # Floating right
+ $s .= "<style type='text/css'>\n" .
+ "@import '{$wgStylePath}/common/quickbar-right.css?$wgStyleVersion';\n</style>\n";
+ }
+ $s .= parent::getUserStyles();
+ return $s;
+ }
+
+ /**
+ *
+ */
+ function doGetUserStyles() {
+ global $wgStylePath;
+
+ $s = parent::doGetUserStyles();
+ $qb = $this->qbSetting();
+
+ if ( 2 == $qb ) { # Right
+ $s .= "#quickbar { position: absolute; top: 4px; right: 4px; " .
+ "border-left: 2px solid #000000; }\n" .
+ "#article { margin-left: 4px; margin-right: 152px; }\n";
+ } else if ( 1 == $qb || 3 == $qb ) {
+ $s .= "#quickbar { position: absolute; top: 4px; left: 4px; " .
+ "border-right: 1px solid gray; }\n" .
+ "#article { margin-left: 152px; margin-right: 4px; }\n";
+ } else if ( 4 == $qb) {
+ $s .= "#quickbar { border-right: 1px solid gray; }\n" .
+ "#article { margin-right: 152px; margin-left: 4px; }\n";
+ }
+ return $s;
+ }
+
+ /**
+ *
+ */
+ function getBodyOptions() {
+ $a = parent::getBodyOptions();
+
+ if ( 3 == $this->qbSetting() ) { # Floating left
+ $qb = "setup(\"quickbar\")";
+ if($a["onload"]) {
+ $a["onload"] .= ";$qb";
+ } else {
+ $a["onload"] = $qb;
+ }
+ }
+ return $a;
+ }
+
+ function doAfterContent() {
+ global $wgContLang;
+ $fname = 'SkinStandard::doAfterContent';
+ wfProfileIn( $fname );
+ wfProfileIn( $fname.'-1' );
+
+ $s = "\n</div><br style=\"clear:both\" />\n";
+ $s .= "\n<div id='footer'>";
+ $s .= '<table border="0" cellspacing="0"><tr>';
+
+ wfProfileOut( $fname.'-1' );
+ wfProfileIn( $fname.'-2' );
+
+ $qb = $this->qbSetting();
+ $shove = ($qb != 0);
+ $left = ($qb == 1 || $qb == 3);
+ if($wgContLang->isRTL()) $left = !$left;
+
+ if ( $shove && $left ) { # Left
+ $s .= $this->getQuickbarCompensator();
+ }
+ wfProfileOut( $fname.'-2' );
+ wfProfileIn( $fname.'-3' );
+ $l = $wgContLang->isRTL() ? 'right' : 'left';
+ $s .= "<td class='bottom' align='$l' valign='top'>";
+
+ $s .= $this->bottomLinks();
+ $s .= "\n<br />" . $this->mainPageLink()
+ . ' | ' . $this->aboutLink()
+ . ' | ' . $this->specialLink( 'recentchanges' )
+ . ' | ' . $this->searchForm()
+ . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
+
+ $s .= "</td>";
+ if ( $shove && !$left ) { # Right
+ $s .= $this->getQuickbarCompensator();
+ }
+ $s .= "</tr></table>\n</div>\n</div>\n";
+
+ wfProfileOut( $fname.'-3' );
+ wfProfileIn( $fname.'-4' );
+ if ( 0 != $qb ) { $s .= $this->quickBar(); }
+ wfProfileOut( $fname.'-4' );
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+ function quickBar() {
+ global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgContLang;
+ global $wgEnableUploads, $wgRemoteUploads;
+
+ $fname = 'Skin::quickBar';
+ wfProfileIn( $fname );
+
+ $action = $wgRequest->getText( 'action' );
+ $wpPreview = $wgRequest->getBool( 'wpPreview' );
+ $tns=$wgTitle->getNamespace();
+
+ $s = "\n<div id='quickbar'>";
+ $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
+
+ $sep = "\n<br />";
+
+ # Use the first heading from the Monobook sidebar as the "browse" section
+ $bar = $this->buildSidebar();
+ $browseLinks = reset( $bar );
+
+ foreach ( $browseLinks as $link ) {
+ if ( $link['text'] != '-' ) {
+ $s .= "<a href=\"{$link['href']}\">" .
+ htmlspecialchars( $link['text'] ) . '</a>' . $sep;
+ }
+ }
+
+ if( $wgUser->isLoggedIn() ) {
+ $s.= $this->specialLink( 'watchlist' ) ;
+ $s .= $sep . $this->makeKnownLink( $wgContLang->specialPage( 'Contributions' ),
+ wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
+ }
+ // only show watchlist link if logged in
+ $s .= "\n<hr class='sep' />";
+ $articleExists = $wgTitle->getArticleId();
+ if ( $wgOut->isArticle() || $action =='edit' || $action =='history' || $wpPreview) {
+ if($wgOut->isArticle()) {
+ $s .= '<strong>' . $this->editThisPage() . '</strong>';
+ } else { # backlink to the article in edit or history mode
+ if($articleExists){ # no backlink if no article
+ switch($tns) {
+ case NS_TALK:
+ case NS_USER_TALK:
+ case NS_PROJECT_TALK:
+ case NS_IMAGE_TALK:
+ case NS_MEDIAWIKI_TALK:
+ case NS_TEMPLATE_TALK:
+ case NS_HELP_TALK:
+ case NS_CATEGORY_TALK:
+ $text = wfMsg('viewtalkpage');
+ break;
+ case NS_MAIN:
+ $text = wfMsg( 'articlepage' );
+ break;
+ case NS_USER:
+ $text = wfMsg( 'userpage' );
+ break;
+ case NS_PROJECT:
+ $text = wfMsg( 'projectpage' );
+ break;
+ case NS_IMAGE:
+ $text = wfMsg( 'imagepage' );
+ break;
+ case NS_MEDIAWIKI:
+ $text = wfMsg( 'mediawikipage' );
+ break;
+ case NS_TEMPLATE:
+ $text = wfMsg( 'templatepage' );
+ break;
+ case NS_HELP:
+ $text = wfMsg( 'viewhelppage' );
+ break;
+ case NS_CATEGORY:
+ $text = wfMsg( 'categorypage' );
+ break;
+ default:
+ $text= wfMsg( 'articlepage' );
+ }
+
+ $link = $wgTitle->getText();
+ if ($nstext = $wgContLang->getNsText($tns) ) { # add namespace if necessary
+ $link = $nstext . ':' . $link ;
+ }
+
+ $s .= $this->makeLink( $link, $text );
+ } elseif( $wgTitle->getNamespace() != NS_SPECIAL ) {
+ # we just throw in a "New page" text to tell the user that he's in edit mode,
+ # and to avoid messing with the separator that is prepended to the next item
+ $s .= '<strong>' . wfMsg('newpage') . '</strong>';
+ }
+
+ }
+
+ # "Post a comment" link
+ if( ( $wgTitle->isTalkPage() || $wgOut->showNewSectionLink() ) && $action != 'edit' && !$wpPreview )
+ $s .= '<br />' . $this->makeKnownLinkObj( $wgTitle, wfMsg( 'postcomment' ), 'action=edit&section=new' );
+
+ #if( $tns%2 && $action!='edit' && !$wpPreview) {
+ #$s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit&section=new');
+ #}
+
+ /*
+ watching could cause problems in edit mode:
+ if user edits article, then loads "watch this article" in background and then saves
+ article with "Watch this article" checkbox disabled, the article is transparently
+ unwatched. Therefore we do not show the "Watch this page" link in edit mode
+ */
+ if ( $wgUser->isLoggedIn() && $articleExists) {
+ if($action!='edit' && $action != 'submit' )
+ {
+ $s .= $sep . $this->watchThisPage();
+ }
+ if ( $wgTitle->userCanEdit() )
+ $s .= $sep . $this->moveThisPage();
+ }
+ if ( $wgUser->isAllowed('delete') and $articleExists ) {
+ $s .= $sep . $this->deleteThisPage() .
+ $sep . $this->protectThisPage();
+ }
+ $s .= $sep . $this->talkLink();
+ if ($articleExists && $action !='history') {
+ $s .= $sep . $this->historyLink();
+ }
+ $s.=$sep . $this->whatLinksHere();
+
+ if($wgOut->isArticleRelated()) {
+ $s .= $sep . $this->watchPageLinksLink();
+ }
+
+ if ( NS_USER == $wgTitle->getNamespace()
+ || $wgTitle->getNamespace() == NS_USER_TALK ) {
+
+ $id=User::idFromName($wgTitle->getText());
+ $ip=User::isIP($wgTitle->getText());
+
+ if($id||$ip) {
+ $s .= $sep . $this->userContribsLink();
+ }
+ if( $this->showEmailUser( $id ) ) {
+ $s .= $sep . $this->emailUserLink();
+ }
+ }
+ $s .= "\n<br /><hr class='sep' />";
+ }
+
+ if ( $wgUser->isLoggedIn() && ( $wgEnableUploads || $wgRemoteUploads ) ) {
+ $s .= $this->specialLink( 'upload' ) . $sep;
+ }
+ $s .= $this->specialLink( 'specialpages' )
+ . $sep . $this->bugReportsLink();
+
+ global $wgSiteSupportPage;
+ if( $wgSiteSupportPage ) {
+ $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
+ '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
+ }
+
+ $s .= "\n<br /></div>\n";
+ wfProfileOut( $fname );
+ return $s;
+ }
+
+
+}
+
+?>
diff --git a/skins/chick/IE50Fixes.css b/skins/chick/IE50Fixes.css
new file mode 100644
index 000000000000..dd9eda3e5feb
--- /dev/null
+++ b/skins/chick/IE50Fixes.css
@@ -0,0 +1,67 @@
+/*
+** IE5.0 Fix Stylesheet
+*/
+
+#column-content {
+ margin: 0 !important;
+ float: none;
+}
+#column-content #content {
+ margin-top: 3em;
+ height: 1%;
+}
+#column-one {
+ position: absolute;
+ overflow: visible;
+ top: 0;
+ left: 0;
+ z-index: 3;
+}
+#footer {
+ margin: 0 0 0 13.6em;
+}
+
+/* IE 5 & 5.5 interpret keyword sizes one off */
+body { font-size: xx-small; }
+/*
+** the edit tabs
+*/
+#p-cactions li {
+ float: left;
+ padding-top: 0;
+ padding-bottom: 0 !important;
+ height: 0.9em;
+}
+#p-cactions li a {
+ display: block;
+ padding-bottom: 0.045em;
+}
+#p-cactions li.selected a {
+ padding-bottom: 0.17em;
+}
+#p-cactions li a:hover {
+ padding-bottom: 0.17em;
+}
+/* 5.0 doesn't like the background icon for external links and user */
+.link-external,
+.external {
+ background: none;
+ padding: 0;
+}
+#p-personal ul { float: right }
+#p-personal li { float: left }
+li#pt-userpage,
+li#pt-anonuserpage,
+li#pt-login,
+li#pt-logout {
+ background: none;
+ padding-left: none;
+}
+.visualClear {
+ width:100%;
+ height: 0px;
+ padding:0;
+ margin:0;
+}
+.firstHeading { margin-bottom: 0.3em; }
+/*div{ border:1px solid Red !important;}*/
diff --git a/skins/chick/IE55Fixes.css b/skins/chick/IE55Fixes.css
new file mode 100644
index 000000000000..2f7856123ad4
--- /dev/null
+++ b/skins/chick/IE55Fixes.css
@@ -0,0 +1,81 @@
+/* IE5.5/win- only fixes */
+
+#column-content {
+ float: none;
+ margin-left: 0;
+ height: 1%;
+}
+#column-content #content {
+ position: relative;
+ z-index: 5;
+ margin-left: 12.2em;
+ margin-top: 3em;
+ height: 1%;
+}
+#column-one {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 4;
+ width: 100%;
+}
+#footer {
+ margin-left: 13.6em;
+ border-left: 1px solid #fabd23;
+}
+
+/*#bodyContent div,
+#bodyContent pre { overflow: auto; }*/
+
+#p-personal { padding-bottom: 0.1em; }
+
+body { font-size: xx-small; }
+
+#p-cactions {
+ width: 76% !important;
+ z-index: 3 !important;
+ float: none;
+}
+#p-cactions li {
+ padding-bottom: 0 !important;
+ border: none;
+ background-color: transparent;
+ cursor: default;
+ float: none !important;
+}
+#p-cactions li a {
+ display: inline-block !important;
+ vertical-align: top;
+ padding-bottom: 0;
+ border: solid #aaa;
+ border-width: 1px 1px 0;
+}
+#p-cactions li.selected a {
+ border-color: #fabd23;
+ padding-bottom: 0.17em;
+}
+#p-cactions li a:hover {
+ padding-bottom: 0.17em;
+}
+.portlet {
+ overflow:hidden;
+}
+#bodyContent a.external {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
+/* show the hand */
+#p-logo a,
+#p-logo a:hover {
+ cursor: pointer;
+}
+.visualClear {
+ width:90%;
+ height: 1px;
+ padding:0;
+ margin:0;
+}
+
+#editform {
+ width: 100%;
+}
diff --git a/skins/chick/IE60Fixes.css b/skins/chick/IE60Fixes.css
new file mode 100644
index 000000000000..feec15f166e6
--- /dev/null
+++ b/skins/chick/IE60Fixes.css
@@ -0,0 +1,79 @@
+/* 6.0 - only fixes */
+/* content area */
+/* workaround for various ie float bugs */
+#column-content {
+ float: none;
+ margin-left: 0;
+ height: 1%;
+}
+#column-content #content {
+ margin-left: 12.2em;
+ margin-top: 3em;
+ height: 1%;
+}
+#column-one {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 4;
+}
+#footer {
+ margin-left: 13.6em;
+ border-left: 1px solid #fabd23;
+}
+
+/* the tabs */
+
+#p-cactions {
+ z-index: 3;
+}
+
+#p-cactions li {
+ padding-bottom: 0 !important;
+ border: none;
+ background-color: transparent;
+ cursor: default;
+ float: none !important;
+}
+#p-cactions li a {
+ display: inline-block !important;
+ vertical-align: top;
+ padding-bottom: 0;
+ border: solid #aaa;
+ border-width: 1px 1px 0;
+}
+#p-cactions li.selected a {
+ border-color: #fabd23;
+ padding-bottom: 0.17em;
+}
+#p-cactions li a:hover {
+ padding-bottom: 0.17em;
+}
+#portal-personaltools {
+ padding-bottom: 0.1em;
+}
+#bodyContent a.external {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
+
+/* show the hand */
+#p-logo a,
+#p-logo a:hover {
+ cursor: pointer;
+}
+div.visualClear {
+ width:100%;
+ line-height: 0;
+}
+textarea {
+ width: 96%;
+}
+
+div.editsection,
+#catlinks,
+div.tright,
+div.tleft {
+ position: relative;
+}
+/*{ border:1px solid Red !important;}*/
diff --git a/skins/chick/main.css b/skins/chick/main.css
new file mode 100644
index 000000000000..b84b291e5a1e
--- /dev/null
+++ b/skins/chick/main.css
@@ -0,0 +1,499 @@
+/*
+** MediaWiki 'chick' style sheet for PDAs or other small-screen devices.
+** Copyright Timwi
+** License: GPL (http://www.gnu.org/copyleft/gpl.html)
+**
+** Loosely based on Monobook by Gabriel Wicke
+*/
+
+body {
+ font-family: sans-serif;
+ color: Black;
+ margin: 0;
+ padding: 0.3em;
+}
+
+a { color: #002bb8; }
+a:visited { color: #5a3696; }
+a:active { color: #ffa500; }
+a.stub { color: #772233; }
+a.new,
+#p-personal a.new { color:#ba0000; }
+a.new:visited,
+#p-personal a.new:visited { color:#a55858; }
+
+img {
+ border: none;
+ vertical-align: middle;
+}
+p {
+ margin: 0.4em 0em 0.5em 0em;
+ line-height: 1.5em;
+}
+
+p img { margin: 0; }
+
+hr {
+ height: 1px;
+ color: #aaaaaa;
+ background-color: #aaaaaa;
+ border: 0;
+ margin: 0.2em 0 0.2em 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: Black;
+ background: none;
+ font-weight: normal;
+ margin: 0;
+ padding-top: 0.5em;
+ padding-bottom: 0.17em;
+ border-bottom: 1px solid #aaaaaa;
+}
+.editsection {
+ font-weight: normal;
+ float: right;
+ margin-left: 5px;
+}
+h1 { font-size: 188%; }
+h1 .editsection { font-size: 53.2%; }
+h2 { font-size: 150%; }
+h2 .editsection { font-size: 66.7%; }
+h3, h4, h5, h6 {
+ border-bottom: none;
+ font-weight: bold;
+}
+h3 { font-size: 132%; }
+h3 .editsection { font-size: 75.8%; }
+h4 { font-size: 116%; }
+h4 .editsection { font-size: 86.2%; }
+h5 { font-size: 100%; }
+h6 { font-size: 80%; }
+h6 .editsection { font-size: 125%; }
+
+ul {
+ line-height: 1.5em;
+ margin: 0.3em 0 0 1.5em;
+ padding:0;
+}
+ol {
+ line-height: 1.5em;
+ margin: 0.3em 0 0 3.2em;
+ padding:0;
+ list-style-image: none;
+}
+li { margin-bottom: 0.1em; }
+dt {
+ font-weight: bold;
+ margin-bottom: 0.1em;
+}
+dl{
+ margin-top: 0.2em;
+ margin-bottom: 0.5em;
+}
+dd {
+ line-height: 1.5em;
+ margin-left: 2em;
+ margin-bottom: 0.1em;
+}
+
+fieldset {
+ border: 1px solid #2f6fab;
+ margin: 1em 0em 1em 0em;
+ padding: 0em 1em 1em 1em;
+ line-height: 1.5em;
+}
+legend {
+ background: White;
+ padding: 0.5em;
+ font-size: 95%;
+}
+form {
+ border: none;
+ margin: 0;
+}
+
+textarea {
+ border: 1px solid #2f6fab;
+ color: Black;
+ background-color: white;
+ width: 100%;
+ padding: 0.1em;
+ overflow: auto;
+}
+/* hide this from ie/mac and konq2.2 */
+@media All {
+ head:first-child+body input {
+ visibility: visible;
+ border: 1px solid #2f6fab;
+ color: Black;
+ background-color: white;
+ vertical-align: middle;
+ padding: 0.2em;
+ }
+}
+input.historysubmit {
+ padding: 0 0.3em 0.3em 0.3em !important;
+ font-size: 94%;
+ cursor: pointer;
+ height: 1.7em !important;
+ margin-left: 1.6em;
+}
+input[type="radio"],
+input[type="checkbox"] { border:none; }
+select {
+ border: 1px solid #2f6fab;
+ color: Black;
+ vertical-align: top;
+}
+abbr, acronym, .explain {
+ border-bottom: 1px dotted Black;
+ color: Black;
+ background: none;
+ cursor: help;
+}
+q {
+ font-family: Times, "Times New Roman", serif;
+ font-style: italic;
+}
+code { background-color: #f9f9f9; }
+pre {
+ padding: 1em;
+ border: 1px dashed #2f6fab;
+ color: Black;
+ background-color: #f9f9f9;
+ line-height: 1.1em;
+}
+
+/*
+** the main content area
+*/
+
+span.subpages { display: block; }
+
+/* Some space under the headers in the content area */
+#bodyContent h1, #bodyContent h2 { margin-bottom:0.6em; }
+#bodyContent h3,
+#bodyContent h4,
+#bodyContent h5 {
+ margin-bottom: 0.3em;
+}
+.firstHeading { margin-bottom:0.1em; }
+
+/* user notification thing */
+.usermessage {
+ background-color: #ffce7b;
+ border: 1px solid #ffa500;
+ color: Black;
+ font-weight: bold;
+ margin: 0.1em 0 0 0;
+ padding: 2px 5px;
+ vertical-align: middle;
+}
+#siteNotice {
+ text-align: center;
+ font-size: 95%;
+ padding: 0 0.9em 0 0.9em;
+}
+#siteNotice p { margin: 0; padding: 0; }
+.error {
+ color: red;
+ font-size: larger;
+}
+#catlinks {
+ border:1px solid #aaaaaa;
+ background-color:#f9f9f9;
+ padding: 2px 5px;
+ margin: 0.1em 0 0 0;
+ clear: both;
+}
+p.catlinks { margin: 0; padding: 0; }
+
+
+/* currently unused, intended to be used by a metadata box
+in the bottom-right corner of the content area */
+.documentDescription {
+ /* The summary text describing the document */
+ font-weight: bold;
+ display: block;
+ margin: 1em 0em;
+ line-height: 1.5em;
+}
+.documentByLine {
+ text-align: right;
+ font-size: 90%;
+ clear: both;
+ font-weight: normal;
+ color: #76797c;
+}
+
+/* emulate center */
+.center {
+ width: 100%;
+ text-align: center;
+}
+*.center * {
+ margin-left: auto;
+ margin-right: auto;
+}
+/* small for tables and similar */
+.small, .small * { font-size: 94%; }
+table.small { font-size: 100% }
+
+/*
+** content styles
+*/
+
+#toc {
+ /*border:1px solid #2f6fab;*/
+ border:1px solid #aaaaaa;
+ background-color:#f9f9f9;
+ padding:5px;
+ font-size: 95%;
+}
+#toc ul { margin-left: 2em; }
+#toc .toctoggle { font-size: 94%; }
+#toc .editsection {
+ margin-top: 0.7em;
+ font-size: 94%;
+}
+
+/* images */
+div.floatright, table.floatright {
+ clear: right;
+ float: right;
+ margin: 0;
+ position: relative;
+ border: 0.5em solid White;
+ border-width: 0.5em 0 0.8em 1.4em;
+}
+div.floatright p { font-style: italic; }
+div.floatleft, table.floatleft {
+ float: left;
+ clear: left;
+ margin: 0.3em 0.5em 0.5em 0;
+ position: relative;
+ border: 0.5em solid White;
+ border-width: 0.5em 1.4em 0.8em 0;
+}
+div.floatleft p { font-style: italic; }
+/* thumbnails */
+div.thumb {
+ margin-bottom: 0.5em;
+ border-style: solid; border-color: White;
+ width: auto;
+}
+div.thumb div {
+ border:1px solid #cccccc;
+ padding: 3px !important;
+ background-color:#f9f9f9;
+ font-size: 94%;
+ text-align: center;
+ overflow: hidden;
+}
+div.thumb div a img {
+ border:1px solid #cccccc;
+}
+div.thumb div div.thumbcaption {
+ border: none;
+ text-align: left;
+ line-height: 1.4em;
+ padding: 0.3em 0 0.1em 0;
+}
+div.magnify {
+ float: right;
+ border: none !important;
+ background: none !important;
+}
+div.magnify a, div.magnify img {
+ display: block;
+ border: none !important;
+ background: none !important;
+}
+div.tright {
+ clear: right;
+ float: right;
+ border-width: 0.5em 0 0.8em 1.4em;
+}
+div.tleft {
+ float: left;
+ clear: left;
+ margin-right:0.5em;
+ border-width: 0.5em 1.4em 0.8em 0;
+}
+
+.hiddenStructure {
+ display: none;
+}
+img.tex { vertical-align: middle; }
+span.texhtml { font-family: serif; }
+
+/*
+** classes for special content elements like town boxes
+** intended to be referenced directly from the wiki src
+*/
+
+/*
+** User styles
+*/
+/* table standards */
+table.rimage {
+ float:right;
+ position:relative;
+ margin-left:1em;
+ margin-bottom:1em;
+ text-align:center;
+}
+.toccolours {
+ border:1px solid #aaaaaa;
+ background-color:#f9f9f9;
+ padding:5px;
+ font-size: 95%;
+}
+div.townBox {
+ position:relative;
+ float:right;
+ background:White;
+ margin-left:1em;
+ border: 1px solid gray;
+ padding:0.3em;
+ width: 200px;
+ overflow: hidden;
+ clear: right;
+}
+div.townBox dl {
+ padding: 0;
+ margin: 0 0 0.3em 0;
+ font-size: 96%;
+}
+div.townBox dl dt {
+ background: none;
+ margin: 0.4em 0 0 0;
+}
+div.townBox dl dd {
+ margin: 0.1em 0 0 1.1em;
+ background-color: #f3f3f3;
+}
+
+/*
+** edit views etc
+*/
+.special li {
+ line-height: 1.4em;
+ margin: 0;
+ padding: 0;
+}
+
+/* Page history styling */
+/* the auto-generated edit comments */
+.autocomment { color: gray; }
+#pagehistory span.user {
+ margin-left: 1.4em;
+ margin-right: 0.4em;
+}
+#pagehistory span.minor { font-weight: bold; }
+#pagehistory li { border: 1px solid White; }
+#pagehistory li.selected {
+ background-color:#f9f9f9;
+ border:1px dashed #aaaaaa;
+}
+/*
+** Diff rendering
+*/
+table.diff { background:white; }
+td.diff-otitle { background:#ffffff; }
+td.diff-ntitle { background:#ffffff; }
+td.diff-addedline {
+ background:#ccffcc;
+ font-size: smaller;
+}
+td.diff-deletedline {
+ background:#ffffaa;
+ font-size: smaller;
+}
+td.diff-context {
+ background:#eeeeee;
+ font-size: smaller;
+}
+span.diffchange { color: red; }
+
+a.external { color: #3366bb; }
+
+div#footer { text-align: center; }
+
+ul#f-list li { list-style: none; text-align: center; }
+
+div.portlet { margin: 0.5em 0; }
+
+.redirectText {
+ font-size:150%;
+ margin:5px;
+}
+
+ul.special li.not-patrolled, ol.special li.not-patrolled {
+ background-color: #ffa;
+}
+div.patrollink {
+ font-size: 75%;
+ text-align: right;
+}
+span.newpage, span.minor {
+ font-weight: bold;
+}
+
+span.updatedmarker {
+ color:black;
+ background-color:#00FF00;
+}
+span.newpageletter {
+ font-weight:bold;
+ color:black;
+ background-color:yellow;
+}
+span.minoreditletter {
+ color:black;
+ background-color:#C5FFE6;
+}
+
+table.gallery {
+ border: 1px solid #cccccc;
+ margin: 2px;
+ padding: 2px;
+ background-color:#ffffff;
+}
+
+table.gallery tr {
+ vertical-align:top;
+}
+
+table.gallery td {
+ vertical-align:top;
+ background-color:#f9f9f9;
+ border: solid 2px white;
+}
+
+div.gallerybox {
+ margin: 2px;
+ width: 150px;
+}
+
+div.gallerybox div.thumb {
+ text-align: center;
+ border: 1px solid #cccccc;
+ margin: 2px;
+}
+
+div.gallerytext {
+ font-size: 94%;
+ padding: 2px 4px;
+}
+
+#jump-to-nav {
+ display: none;
+}
+
+.templatesUsed { margin-top: 1.5em; }
+
+#toolbar { clear: both; }
+
+.mw-plusminus-null { color: #aaa; } \ No newline at end of file
diff --git a/skins/common/IEFixes.js b/skins/common/IEFixes.js
new file mode 100644
index 000000000000..9c25adf0d30a
--- /dev/null
+++ b/skins/common/IEFixes.js
@@ -0,0 +1,127 @@
+// IE fixes javascript
+
+var isMSIE55 = (window.showModalDialog && window.clipboardData && window.createPopup);
+var doneIETransform;
+var doneIEAlphaFix;
+
+if (document.attachEvent)
+ document.attachEvent('onreadystatechange', hookit);
+
+function hookit() {
+ if (!doneIETransform && document.getElementById && document.getElementById('bodyContent')) {
+ doneIETransform = true;
+ relativeforfloats();
+ fixalpha();
+ }
+}
+
+// png alpha transparency fixes
+function fixalpha() {
+ // bg
+ if (isMSIE55 && !doneIEAlphaFix)
+ {
+ var plogo = document.getElementById('p-logo');
+ if (!plogo) return;
+
+ var logoa = plogo.getElementsByTagName('a')[0];
+ if (!logoa) return;
+
+ var bg = logoa.currentStyle.backgroundImage;
+ var imageUrl = bg.substring(5, bg.length-2);
+
+ doneIEAlphaFix = true;
+
+ if (imageUrl.substr(imageUrl.length-4).toLowerCase() == '.png') {
+ var logospan = logoa.appendChild(document.createElement('span'));
+
+ logoa.style.backgroundImage = 'none';
+ logospan.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + imageUrl + ')';
+ logospan.style.height = '100%';
+ logospan.style.position = 'absolute';
+ logospan.style.width = logoa.currentStyle.width;
+ logospan.style.cursor = 'hand';
+ // Center image with hack for IE5.5
+ if (document.documentElement.dir == "rtl")
+ {
+ logospan.style.right = '50%';
+ logospan.style.setExpression('marginRight', '"-" + (this.offsetWidth / 2) + "px"');
+ }
+ else
+ {
+ logospan.style.left = '50%';
+ logospan.style.setExpression('marginLeft', '"-" + (this.offsetWidth / 2) + "px"');
+ }
+ logospan.style.top = '50%';
+ logospan.style.setExpression('marginTop', '"-" + (this.offsetHeight / 2) + "px"');
+
+ var linkFix = logoa.appendChild(logoa.cloneNode());
+ linkFix.style.position = 'absolute';
+ linkFix.style.height = '100%';
+ linkFix.style.width = '100%';
+ }
+ }
+}
+
+// fix ie6 disappering float bug
+function relativeforfloats() {
+ var bc = document.getElementById('bodyContent');
+ if (bc) {
+ var tables = bc.getElementsByTagName('table');
+ var divs = bc.getElementsByTagName('div');
+ }
+ setrelative(tables);
+ setrelative(divs);
+}
+function setrelative (nodes) {
+ var i = 0;
+ while (i < nodes.length) {
+ if(((nodes[i].style.float && nodes[i].style.float != ('none') ||
+ (nodes[i].align && nodes[i].align != ('none'))) &&
+ (!nodes[i].style.position || nodes[i].style.position != 'relative')))
+ {
+ nodes[i].style.position = 'relative';
+ }
+ i++;
+ }
+}
+
+
+// Expand links for printing
+
+String.prototype.hasClass = function(classWanted)
+{
+ var classArr = this.split(/\s/);
+ for (var i=0; i<classArr.length; i++)
+ if (classArr[i].toLowerCase() == classWanted.toLowerCase()) return true;
+ return false;
+}
+
+var expandedURLs;
+
+onbeforeprint = function() {
+ expandedURLs = [];
+
+ var contentEl = document.getElementById("content");
+
+ if (contentEl)
+ {
+ var allLinks = contentEl.getElementsByTagName("a");
+
+ for (var i=0; i < allLinks.length; i++) {
+ if (allLinks[i].className.hasClass("external") && !allLinks[i].className.hasClass("free")) {
+ var expandedLink = document.createElement("span");
+ var expandedText = document.createTextNode(" (" + allLinks[i].href + ")");
+ expandedLink.appendChild(expandedText);
+ allLinks[i].parentNode.insertBefore(expandedLink, allLinks[i].nextSibling);
+ expandedURLs[i] = expandedLink;
+ }
+ }
+ }
+}
+
+onafterprint = function()
+{
+ for (var i=0; i < expandedURLs.length; i++)
+ if (expandedURLs[i])
+ expandedURLs[i].removeNode(true);
+} \ No newline at end of file
diff --git a/skins/common/ajax.js b/skins/common/ajax.js
new file mode 100644
index 000000000000..4006559361b1
--- /dev/null
+++ b/skins/common/ajax.js
@@ -0,0 +1,149 @@
+// remote scripting library
+// (c) copyright 2005 modernmethod, inc
+var sajax_debug_mode = false;
+var sajax_request_type = "GET";
+
+/**
+* if sajax_debug_mode is true, this function outputs given the message into
+* the element with id = sajax_debug; if no such element exists in the document,
+* it is injected.
+*/
+function sajax_debug(text) {
+ if (!sajax_debug_mode) return false;
+
+ var e= document.getElementById('sajax_debug');
+
+ if (!e) {
+ e= document.createElement("p");
+ e.className= 'sajax_debug';
+ e.id= 'sajax_debug';
+
+ var b= document.getElementsByTagName("body")[0];
+
+ if (b.firstChild) b.insertBefore(e, b.firstChild);
+ else b.appendChild(e);
+ }
+
+ var m= document.createElement("div");
+ m.appendChild( document.createTextNode( text ) );
+
+ e.appendChild( m );
+
+ return true;
+}
+
+/**
+* compatibility wrapper for creating a new XMLHttpRequest object.
+*/
+function sajax_init_object() {
+ sajax_debug("sajax_init_object() called..")
+ var A;
+ try {
+ A=new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ A=new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (oc) {
+ A=null;
+ }
+ }
+ if(!A && typeof XMLHttpRequest != "undefined")
+ A = new XMLHttpRequest();
+ if (!A)
+ sajax_debug("Could not create connection object.");
+
+ return A;
+}
+
+/**
+* Perform an ajax call to mediawiki. Calls are handeled by AjaxDispatcher.php
+* func_name - the name of the function to call. Must be registered in $wgAjaxExportList
+* args - an array of arguments to that function
+* target - the target that will handle the result of the call. If this is a function,
+* if will be called with the XMLHttpRequest as a parameter; if it's an input
+* element, its value will be set to the resultText; if it's another type of
+* element, its innerHTML will be set to the resultText.
+*
+* Example:
+* sajax_do_call('doFoo', [1, 2, 3], document.getElementById("showFoo"));
+*
+* This will call the doFoo function via MediaWiki's AjaxDispatcher, with
+* (1, 2, 3) as the parameter list, and will show the result in the element
+* with id = showFoo
+*/
+function sajax_do_call(func_name, args, target) {
+ var i, x, n;
+ var uri;
+ var post_data;
+ uri = wgServer + wgScriptPath + "/index.php?action=ajax";
+ if (sajax_request_type == "GET") {
+ if (uri.indexOf("?") == -1)
+ uri = uri + "?rs=" + encodeURIComponent(func_name);
+ else
+ uri = uri + "&rs=" + encodeURIComponent(func_name);
+ for (i = 0; i < args.length; i++)
+ uri = uri + "&rsargs[]=" + encodeURIComponent(args[i]);
+ //uri = uri + "&rsrnd=" + new Date().getTime();
+ post_data = null;
+ } else {
+ post_data = "rs=" + encodeURIComponent(func_name);
+ for (i = 0; i < args.length; i++)
+ post_data = post_data + "&rsargs[]=" + encodeURIComponent(args[i]);
+ }
+ x = sajax_init_object();
+ if (!x) {
+ alert("AJAX not supported");
+ return false;
+ }
+
+ try {
+ x.open(sajax_request_type, uri, true);
+ } catch (e) {
+ if (window.location.hostname == "localhost") {
+ alert("Your browser blocks XMLHttpRequest to 'localhost', try using a real hostname for development/testing.");
+ }
+ throw e;
+ }
+ if (sajax_request_type == "POST") {
+ x.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");
+ x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ }
+ x.setRequestHeader("Pragma", "cache=yes");
+ x.setRequestHeader("Cache-Control", "no-transform");
+ x.onreadystatechange = function() {
+ if (x.readyState != 4)
+ return;
+
+ sajax_debug("received (" + x.status + " " + x.statusText + ") " + x.responseText);
+
+ //if (x.status != 200)
+ // alert("Error: " + x.status + " " + x.statusText + ": " + x.responseText);
+ //else
+
+ if ( typeof( target ) == 'function' ) {
+ target( x );
+ }
+ else if ( typeof( target ) == 'object' ) {
+ if ( target.tagName == 'INPUT' ) {
+ if (x.status == 200) target.value= x.responseText;
+ //else alert("Error: " + x.status + " " + x.statusText + " (" + x.responseText + ")");
+ }
+ else {
+ if (x.status == 200) target.innerHTML = x.responseText;
+ else target.innerHTML= "<div class='error'>Error: " + x.status + " " + x.statusText + " (" + x.responseText + ")</div>";
+ }
+ }
+ else {
+ alert("bad target for sajax_do_call: not a function or object: " + target);
+ }
+
+ return;
+ }
+
+ sajax_debug(func_name + " uri = " + uri + " / post = " + post_data);
+ x.send(post_data);
+ sajax_debug(func_name + " waiting..");
+ delete x;
+
+ return true;
+}
diff --git a/skins/common/ajaxsearch.js b/skins/common/ajaxsearch.js
new file mode 100644
index 000000000000..e6ea31ab3567
--- /dev/null
+++ b/skins/common/ajaxsearch.js
@@ -0,0 +1,104 @@
+// remote scripting library
+// (c) copyright 2005 modernmethod, inc
+
+var started;
+var typing;
+var memory=null;
+var body=null;
+var oldbody=null;
+
+// Remove the typing barrier to allow call() to complete
+function Search_doneTyping()
+{
+ typing=false;
+}
+
+// Wait 500ms to run call()
+function Searching_Go()
+{
+ setTimeout("Searching_Call()", 500);
+}
+
+// If the user is typing wait until they are done.
+function Search_Typing() {
+ started=true;
+ typing=true;
+ window.status = "Waiting until you're done typing...";
+ setTimeout("Search_doneTyping()", 500);
+
+ // I believe these are needed by IE for when the users press return?
+ if (window.event)
+ {
+ if (event.keyCode == 13)
+ {
+ event.cancelBubble = true;
+ event.returnValue = false;
+ }
+ }
+}
+
+// Set the body div to the results
+function Searching_SetResult( request )
+{
+ if ( request.status != 200 ) {
+ alert("Error: " + request.status + " " + request.statusText + ": " + request.responseText);
+ return;
+ }
+
+ var result = request.responseText;
+
+ //body.innerHTML = result;
+ t = document.getElementById("searchTarget");
+ if ( t == null ) {
+ oldbody=body.innerHTML;
+ body.innerHTML= '<div id="searchTargetContainer"><div id="searchTarget" ></div></div>' ;
+ t = document.getElementById("searchTarget");
+ }
+ t.innerHTML = result;
+ t.style.display='block';
+}
+
+function Searching_Hide_Results()
+{
+ t = document.getElementById("searchTarget");
+ t.style.display='none';
+ body.innerHTML = oldbody;
+}
+
+
+// This will call the php function that will eventually
+// return a results table
+function Searching_Call()
+{
+ var x;
+ Searching_Go();
+
+ //Don't proceed if user is typing
+ if (typing)
+ return;
+
+ x = document.getElementById("searchInput").value;
+
+ // Don't search again if the query is the same
+ if (x==memory)
+ return;
+
+ memory=x;
+ if (started) {
+ // Don't search for blank or < 3 chars.
+ if ((x=="") || (x.length < 3))
+ {
+ return;
+ }
+
+ sajax_do_call( "wfSajaxSearch", [ x ], Searching_SetResult );
+ }
+}
+
+//Initialize
+function sajax_onload() {
+ x = document.getElementById( 'searchInput' );
+ x.onkeypress= function() { Search_Typing(); };
+ Searching_Go();
+ body = document.getElementById("content");
+}
diff --git a/skins/common/ajaxwatch.js b/skins/common/ajaxwatch.js
new file mode 100644
index 000000000000..16e4fdc455d9
--- /dev/null
+++ b/skins/common/ajaxwatch.js
@@ -0,0 +1,127 @@
+// dependencies:
+// * ajax.js:
+ /*extern sajax_init_object, sajax_do_call */
+// * wikibits.js:
+ /*extern changeText, akeytt, hookEvent */
+
+// These should have been initialized in the generated js
+/*extern wgAjaxWatch, wgArticleId */
+
+if(typeof wgAjaxWatch === "undefined" || !wgAjaxWatch) {
+ var wgAjaxWatch = {
+ watchMsg: "Watch",
+ unwatchMsg: "Unwatch",
+ watchingMsg: "Watching...",
+ unwatchingMsg: "Unwatching..."
+ };
+}
+
+wgAjaxWatch.supported = true; // supported on current page and by browser
+wgAjaxWatch.watching = false; // currently watching page
+wgAjaxWatch.inprogress = false; // ajax request in progress
+wgAjaxWatch.timeoutID = null; // see wgAjaxWatch.ajaxCall
+wgAjaxWatch.watchLink1 = null; // "watch"/"unwatch" link
+wgAjaxWatch.watchLink2 = null; // second one, for (some?) non-Monobook-based
+wgAjaxWatch.oldHref = null; // url for action=watch/action=unwatch
+
+wgAjaxWatch.setLinkText = function(newText) {
+ changeText(wgAjaxWatch.watchLink1, newText);
+ if (wgAjaxWatch.watchLink2) {
+ changeText(wgAjaxWatch.watchLink2, newText);
+ }
+};
+
+wgAjaxWatch.setLinkID = function(newId) {
+ wgAjaxWatch.watchLink1.id = newId;
+ akeytt(newId); // update tooltips for Monobook
+};
+
+wgAjaxWatch.ajaxCall = function() {
+ if(!wgAjaxWatch.supported || wgAjaxWatch.inprogress) {
+ return;
+ }
+ wgAjaxWatch.inprogress = true;
+ wgAjaxWatch.setLinkText(wgAjaxWatch.watching ? wgAjaxWatch.unwatchingMsg : wgAjaxWatch.watchingMsg);
+ sajax_do_call("wfAjaxWatch", [wgArticleId, (wgAjaxWatch.watching ? "u" : "w")], wgAjaxWatch.processResult);
+ // if the request isn't done in 10 seconds, allow user to try again
+ wgAjaxWatch.timeoutID = window.setTimeout(function() { wgAjaxWatch.inprogress = false; }, 10000);
+ return;
+};
+
+wgAjaxWatch.processResult = function(request) {
+ if(!wgAjaxWatch.supported) {
+ return;
+ }
+ var response = request.responseText;
+ if(response == "<err#>") {
+ window.location.href = wgAjaxWatch.oldHref;
+ return;
+ } else if(response == "<w#>") {
+ wgAjaxWatch.watching = true;
+ wgAjaxWatch.setLinkText(wgAjaxWatch.unwatchMsg);
+ wgAjaxWatch.setLinkID("ca-unwatch");
+ wgAjaxWatch.oldHref = wgAjaxWatch.oldHref.replace(/action=watch/, "action=unwatch");
+ } else if(response == "<u#>") {
+ wgAjaxWatch.watching = false;
+ wgAjaxWatch.setLinkText(wgAjaxWatch.watchMsg);
+ wgAjaxWatch.setLinkID("ca-watch");
+ wgAjaxWatch.oldHref = wgAjaxWatch.oldHref.replace(/action=unwatch/, "action=watch");
+ }
+ wgAjaxWatch.inprogress = false;
+ if(wgAjaxWatch.timeoutID) {
+ window.clearTimeout(wgAjaxWatch.timeoutID);
+ }
+ return;
+};
+
+wgAjaxWatch.onLoad = function() {
+ var el1 = document.getElementById("ca-unwatch");
+ var el2 = null;
+ if (!el1) {
+ el1 = document.getElementById("mw-unwatch-link1");
+ el2 = document.getElementById("mw-unwatch-link2");
+ }
+ if(el1) {
+ wgAjaxWatch.watching = true;
+ } else {
+ wgAjaxWatch.watching = false;
+ el1 = document.getElementById("ca-watch");
+ if (!el1) {
+ el1 = document.getElementById("mw-watch-link1");
+ el2 = document.getElementById("mw-watch-link2");
+ }
+ if(!el1) {
+ wgAjaxWatch.supported = false;
+ return;
+ }
+ }
+
+ if(!wfSupportsAjax()) {
+ wgAjaxWatch.supported = false;
+ return;
+ }
+
+ // The id can be either for the parent (Monobook-based) or the element
+ // itself (non-Monobook)
+ wgAjaxWatch.watchLink1 = el1.tagName.toLowerCase() == "a" ? el1 : el1.firstChild;
+ wgAjaxWatch.watchLink2 = el2 ? el2 : null;
+
+ wgAjaxWatch.oldHref = wgAjaxWatch.watchLink1.getAttribute("href");
+ wgAjaxWatch.watchLink1.setAttribute("href", "javascript:wgAjaxWatch.ajaxCall()");
+ if (wgAjaxWatch.watchLink2) {
+ wgAjaxWatch.watchLink2.setAttribute("href", "javascript:wgAjaxWatch.ajaxCall()");
+ }
+ return;
+};
+
+hookEvent("load", wgAjaxWatch.onLoad);
+
+/**
+ * @return boolean whether the browser supports XMLHttpRequest
+ */
+function wfSupportsAjax() {
+ var request = sajax_init_object();
+ var supportsAjax = request ? true : false;
+ delete request;
+ return supportsAjax;
+} \ No newline at end of file
diff --git a/skins/common/cologneblue.css b/skins/common/cologneblue.css
new file mode 100644
index 000000000000..5b6e5bca1a2d
--- /dev/null
+++ b/skins/common/cologneblue.css
@@ -0,0 +1,96 @@
+body { margin: 0px; padding: 0px; color: black; }
+#specialform { display: inline; }
+#content { top: 0; margin: 0; padding: 0; }
+#topbar { padding: 0px; }
+#powersearch {
+ background: #DDEEFF; border-style: solid; border-width: 1px; padding: 2px;
+}
+#quickbar {
+ width: 140px; top: 18ex; padding: 2px; visibility: visible; z-index: 99;
+}
+#article, #article td, #article th, #article p {
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 10pt; color: black;
+}
+#article p {
+ padding-top: 0; padding-bottom: 0;
+ margin-top: 1ex; margin-bottom: 0;
+}
+p, pre, td, th, li, dd, dt { line-height: 12pt; }
+textarea { overflow: auto; }
+
+#footer { padding: 4px; }
+#footer form { display: inline; }
+#sitetitle {
+ font-family: Times, serif;
+ color: white;
+ font-weight: normal; font-size: 32pt;
+ line-height: 32pt;
+}
+td.top {
+ background-color: #6688AA; color: white;
+ margin-top: 4px; margin-bottom: 4px;
+ padding-top: 0; padding-bottom: 0;
+ text-transform: uppercase;
+ font-family: Verdana, Arial, sans-serif; font-size: 8pt;
+}
+td.top a {
+ font-family: Verdana, Arial, sans-serif;
+ background-color: #6688AA; color: white;
+ text-decoration: none; font-size: 10pt;
+}
+td.bottom {
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 10pt;
+ padding: 0;
+}
+#pagestats {
+ font-family: Verdana, Arial, sans-serif;
+ color: black;
+ font-size: 9pt;
+}
+#sitesub {
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 9pt; font-weight: bold;
+ color: black;
+ padding-top: 0;
+}
+#quickbar {
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 8pt; font-weight: bold; line-height: 9.5pt;
+ text-decoration: none;
+ color: black;
+ padding: 0; margin-top: 0;
+}
+#quickbar a { color: #446688; }
+
+#quickbar h6 {
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 10pt; font-weight: bold; line-height: 12pt;
+ text-decoration: none;
+ color: #666666;
+ padding: 0; margin-bottom: 2px; margin-top: 6px;
+}
+#quickbar form { padding: 0; margin-top: 0; }
+
+h1 {
+ color: #666666;
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 180%; line-height: 21pt;
+}
+h1 .editsection { font-size: 55.6%; }
+h1.pagetitle { padding-bottom: 0; margin-bottom: 0; }
+#article p.subtitle {
+ color: #666666; font-size: 11pt; font-weight: bold;
+ padding-top: 0; margin-top: 0; padding-bottom: 1ex;
+}
+
+a { color: #223366; }
+a.external { color: #336644; }
+a:visited { color: #8D0749; }
+a.printable { text-decoration: underline; }
+a.stub, #quickbar a.stub { color:#772233; text-decoration:none; }
+a.new, #quickbar a.new { color: #CC2200; }
+h2, h3, h4, h5, h6 { margin-bottom: 0; }
+small { font-size: 75%; }
+input.mw-searchInput { width: 106px; } \ No newline at end of file
diff --git a/skins/common/common.css b/skins/common/common.css
new file mode 100644
index 000000000000..f3e5b574fd45
--- /dev/null
+++ b/skins/common/common.css
@@ -0,0 +1,467 @@
+/*
+ * common.css
+ * This file contains CSS settings common to Wikistandard, Nostalgia and CologneBlue
+ */
+
+/* For clarity, explicitly state some recommendations from <http://www.w3.org/
+ TR/CSS21/sample.html> to make sure the editsection links scale right */
+
+h1 { font-size: 2em; }
+h2 { font-size: 1.5em; }
+h3 { font-size: 1.17em; }
+h5 { font-size: .83em; }
+h6 { font-size: .75em; }
+h1, h2, h3, h4, h5, h6 { font-weight: bolder }
+
+/* Now the custom parts */
+
+/* Make edit sections (which are inside h# tags) normal-sized */
+.editsection {
+ font-weight: normal;
+ float: right;
+ margin-left: 5px;
+}
+h1 .editsection { font-size: 50% }
+h2 .editsection { font-size: 66.7% }
+h3 .editsection { font-size: 85.5% }
+h5 .editsection { font-size: 120% }
+h6 .editsection { font-size: 133% }
+
+#footer { clear: both }
+/* images */
+div.floatright { float: right; clear: right; margin: 0 0 1em 1em; }
+div.floatright p { font-style: italic; }
+div.floatleft { float: left; clear: left; margin: 0.3em 0.5em 0.5em 0; }
+div.floatleft p { font-style: italic; }
+
+
+/* Print-specific things to hide */
+.printfooter {
+ display: none;
+}
+
+/* table standards */
+table.rimage {
+ float:right;
+ margin-left:1em;
+ margin-bottom:1em;
+ text-align:center;
+ font-size:smaller;
+}
+
+/* thumbnails */
+div.thumb {
+ margin-bottom: .5em;
+ border-style: solid;
+ border-color: white;
+ width: auto;
+}
+div.thumbinner {
+ border: 1px solid #ccc;
+ padding: 3px !important;
+ background-color: #f9f9f9;
+ font-size: 94%;
+ text-align: center;
+ overflow: hidden;
+}
+html .thumbimage {
+ border: 1px solid #ccc;
+}
+html .thumbcaption {
+ border: none;
+ text-align: left;
+ line-height: 1.4em;
+ padding: 3px !important;
+ font-size: 94%;
+}
+div.magnify {
+ float: right;
+ border: none !important;
+ background: none !important;
+}
+div.magnify a, div.magnify img {
+ display: block;
+ border: none !important;
+ background: none !important;
+}
+div.tright {
+ clear: right;
+ float: right;
+ border-width: .5em 0 .8em 1.4em;
+}
+div.tleft {
+ float: left;
+ clear: left;
+ margin-right: .5em;
+ border-width: .5em 1.4em .8em 0;
+}
+
+/* Page history styling */
+/* the auto-generated edit comments */
+.autocomment { color: #4b4b4b; }
+#pagehistory span.user {
+ margin-left: 1.4em;
+ margin-right: 0.4em;
+}
+#pagehistory span.minor { font-weight: bold; }
+#pagehistory li { border: 1px solid White; }
+#pagehistory li.selected {
+ background-color:#f9f9f9;
+ border:1px dashed #aaaaaa;
+}
+
+table.diff { background:white; }
+td.diff-otitle { background:#cccccc; }
+td.diff-ntitle { background:#cccccc; }
+td.diff-addedline {
+ background:#ccffcc;
+ font-size: 94%;
+}
+td.diff-deletedline {
+ background:#ffffaa;
+ font-size: 94%;
+}
+td.diff-context {
+ background:#eeeeee;
+ font-size: 94%;
+}
+span.diffchange { color: red; font-weight: bold; }
+
+img { border: none; }
+img.tex { vertical-align: middle; }
+span.texhtml { font-family: serif; }
+
+
+#toc,
+.toc {
+ border: 1px solid #bba;
+ background-color: #f7f8ff;
+ padding: 5px;
+ font-size: 95%;
+ text-align: center;
+}
+#toc h2,
+.toc h2 {
+ display: inline;
+ border: none;
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+}
+#toc ul,
+.toc ul {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 0;
+ padding-left: 0;
+ text-align: left;
+}
+#toc ul ul,
+.toc ul ul {
+ margin: 0 0 0 2em;
+}
+#toc .toctoggle,
+.toc .toctoggle {
+ font-size: 94%;
+}
+
+
+.error {
+ color: red;
+ font-size: larger;
+}
+
+/* preference page with js-genrated toc */
+#preftoc {
+ float: left;
+ margin: 1em 1em 1em 1em;
+ width: 13em;
+}
+#preftoc li { border: 1px solid White; }
+#preftoc li.selected {
+ background-color:#f9f9f9;
+ border:1px dashed #aaaaaa;
+}
+#preftoc a,
+#preftoc a:active {
+ display: block;
+ color: #005189;
+}
+#prefcontrol {
+ clear: left;
+ float: left;
+ margin-top: 1em;
+}
+div.prefsectiontip {
+ font-size: 94%;
+ margin-top: 1em;
+}
+fieldset.prefsection { margin-top: 1em }
+fieldset.operaprefsection { margin-left: 15em }
+
+/* emulate center */
+.center {
+ width: 100%;
+ text-align: center;
+}
+*.center * {
+ margin-left: auto;
+ margin-right: auto;
+}
+/* small for tables and similar */
+.small, .small * { font-size: 94%; }
+table.small { font-size: 100% }
+
+div.townBox {
+ position:relative;
+ float:right;
+ background:White;
+ margin-left:1em;
+ border: 1px solid gray;
+ padding:0.3em;
+ width: 200px;
+ overflow: hidden;
+ clear: right;
+}
+div.townBox dl {
+ padding: 0;
+ margin: 0 0 0.3em 0;
+ font-size: 96%;
+}
+div.townBox dl dt {
+ background: none;
+ margin: 0.4em 0 0 0;
+}
+div.townBox dl dd {
+ margin: 0.1em 0 0 1.1em;
+ background-color: #f3f3f3;
+}
+/* use this instead of #toc for page content */
+.toccolours {
+ border:1px solid #aaaaaa;
+ background-color:#f9f9f9;
+ padding:5px;
+ font-size: 95%;
+}
+#siteNotice {
+ border:1px solid #aaaaaa;
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+}
+.redirectText {
+ font-size:150%;
+ margin:5px;
+}
+.searchmatch {
+ color: red;
+ font-weight: bold;
+}
+.sharedUploadNotice {
+ font-style: italic;
+}
+span.unpatrolled {
+ font-weight:bold;
+ color:red;
+}
+
+span.updatedmarker {
+ color:black;
+ background-color:#00FF00;
+}
+span.newpageletter {
+ font-weight:bold;
+ color:black;
+ background-color:yellow;
+}
+span.minoreditletter {
+ color:black;
+ background-color:#C5FFE6;
+}
+
+table.gallery {
+ border: 1px solid #cccccc;
+ margin: 2px;
+ padding: 2px;
+ background-color:#ffffff;
+}
+
+table.gallery tr {
+ vertical-align:top;
+}
+
+table.gallery td {
+ vertical-align:top;
+ background-color:#f9f9f9;
+ border: solid 2px white;
+}
+
+div.gallerybox {
+ margin: 2px;
+ width: 150px;
+}
+
+div.gallerybox div.thumb {
+ text-align: center;
+ border: 1px solid #cccccc;
+ margin: 2px;
+}
+
+div.gallerytext {
+ font-size: 94%;
+ padding: 2px 4px;
+}
+
+span.comment {
+ font-style: italic;
+}
+
+span.changedby {
+ font-size: 95%;
+}
+
+.previewnote {
+ text-align: center;
+ color: #cc0000;
+}
+.editExternally {
+ border-style:solid;
+ border-width:1px;
+ border-color:gray;
+ background: #ffffff;
+ padding:3px;
+ margin-top:0.5em;
+ float:left;
+ font-size:small;
+ text-align:center;
+}
+.editExternallyHelp {
+ font-style:italic;
+ color:gray;
+}
+
+li span.deleted {
+ text-decoration: line-through;
+ color: #888;
+ font-style: italic;
+}
+
+/* Classes for EXIF data display */
+table.mw_metadata {
+ margin-left: 0.5em;
+}
+
+table.mw_metadata caption { font-weight: bold; }
+table.mw_metadata th { font-weight: normal; }
+table.mw_metadata td { padding: 0.1em; }
+
+table.mw_metadata {
+ border: none;
+ border-collapse: collapse;
+}
+table.mw_metadata td, table.mw_metadata th {
+ border: 1px solid #aaaaaa;
+ padding-left: 4px;
+ padding-right: 4px;
+}
+table.mw_metadata th {
+ background-color: #f9f9f9;
+}
+table.mw_metadata td {
+ background-color: #fcfcfc;
+}
+table.mw_metadata td.spacer {
+ background: inherit;
+ border-top: none;
+ border-bottom: none;
+}
+table.collapsed tr.collapsable {
+ display: none;
+}
+
+.visualClear {
+ clear: both;
+}
+
+#mw_trackbacks {
+ border: solid 1px #bbbbff;
+ background-color: #eeeeff;
+ padding: 0.2em;
+}
+
+/* Allmessages table */
+
+#allmessagestable th {
+ background-color: #b2b2ff;
+}
+
+#allmessagestable tr.orig {
+ background-color: #ffe2e2;
+}
+
+#allmessagestable tr.new {
+ background-color: #e2ffe2;
+}
+
+#allmessagestable tr.def {
+ background-color: #f0f0ff;
+}
+
+#jump-to-nav {
+ display: none;
+}
+
+table.gallery td.galleryheader {
+ text-align: center;
+ font-weight: bold;
+}
+
+div.multipageimagenavbox {
+ border: solid 1px silver;
+ padding: 4px;
+ margin: 1em;
+ -moz-border-radius: 6px;
+ background: #f0f0f0;
+}
+
+div.multipageimagenavbox div.thumb {
+ border: none;
+ margin-left: 2em;
+ margin-right: 2em;
+}
+
+div.multipageimagenavbox hr {
+ margin: 6px;
+}
+
+table.multipageimage td {
+ text-align: center;
+}
+
+/*
+ Table pager (e.g. Special:Imagelist)
+ - remove underlines from the navigation link
+ - collapse borders
+ - set the borders to outsets (similar to Special:Allmessages)
+ - remove line wrapping for all td and th, set background color
+ - restore line wrapping for the last two table cells (description and size)
+*/
+.TablePager_nav a { text-decoration: none; }
+.TablePager { border-collapse: collapse; }
+.TablePager, .TablePager td, .TablePager th {
+ border: 0.15em solid #777777;
+ padding: 0 0.15em 0 0.15em;
+}
+.TablePager th { background-color: #eeeeff }
+.TablePager td { background-color: #ffffff }
+.TablePager tr:hover td { background-color: #eeeeff }
+
+.imagelist td, .imagelist th { white-space: nowrap }
+.imagelist .TablePager_col_links { background-color: #eeeeff }
+.imagelist .TablePager_col_img_description { white-space: normal }
+.imagelist th.TablePager_sort { background-color: #ccccff }
+
+.templatesUsed { margin-top: 1em; }
+
+#toolbar { clear: both; }
+
+.mw-plusminus-null { color: #aaa; } \ No newline at end of file
diff --git a/skins/common/commonPrint.css b/skins/common/commonPrint.css
new file mode 100644
index 000000000000..992ac4dbb138
--- /dev/null
+++ b/skins/common/commonPrint.css
@@ -0,0 +1,288 @@
+/*
+** MediaWiki Print style sheet for CSS2-capable browsers.
+** Copyright Gabriel Wicke, http://www.aulinx.de/
+**
+** Derived from the plone (http://plone.org/) styles
+** Copyright Alexander Limi
+*/
+
+/* Thanks to A List Apart (http://alistapart.com/) for useful extras */
+a.stub,
+a.new{ color:#ba0000; text-decoration:none; }
+
+#toc {
+ /*border:1px solid #2f6fab;*/
+ border:1px solid #aaaaaa;
+ background-color:#f9f9f9;
+ padding:5px;
+}
+.tocindent {
+ margin-left: 2em;
+}
+.tocline {
+ margin-bottom: 0px;
+}
+
+/* images */
+div.floatright {
+ float: right;
+ clear: right;
+ margin: 0;
+ position:relative;
+ border: 0.5em solid White;
+ border-width: 0.5em 0 0.8em 1.4em;
+}
+div.floatright p { font-style: italic;}
+div.floatleft {
+ float: left;
+ margin: 0.3em 0.5em 0.5em 0;
+ position:relative;
+ border: 0.5em solid White;
+ border-width: 0.5em 1.4em 0.8em 0;
+}
+div.floatleft p { font-style: italic; }
+/* thumbnails */
+div.thumb {
+ margin-bottom: 0.5em;
+ border-style: solid; border-color: White;
+ width: auto;
+ overflow: hidden;
+}
+div.thumb div {
+ border:1px solid #cccccc;
+ padding: 3px !important;
+ background-color:#f9f9f9;
+ font-size: 94%;
+ text-align: center;
+}
+div.thumb div a img {
+ border:1px solid #cccccc;
+}
+div.thumb div div.thumbcaption {
+ border: none;
+ padding: 0.3em 0 0.1em 0;
+}
+div.magnify { display: none; }
+div.tright {
+ float: right;
+ clear: right;
+ border-width: 0.5em 0 0.8em 1.4em;
+}
+div.tleft {
+ float: left;
+ margin-right:0.5em;
+ border-width: 0.5em 1.4em 0.8em 0;
+}
+
+/* table standards */
+table.rimage {
+ float:right;
+ width:1pt;
+ position:relative;
+ margin-left:1em;
+ margin-bottom:1em;
+ text-align:center;
+}
+
+body {
+ background: White;
+ /*font-size: 11pt !important;*/
+ color: Black;
+ margin: 0;
+ padding: 0;
+}
+
+.noprint,
+div#jump-to-nav,
+div.top,
+div#column-one,
+#colophon,
+.editsection,
+.toctoggle,
+.tochidden,
+div#f-poweredbyico,
+div#f-copyrightico,
+li#viewcount,
+li#about,
+li#disclaimer,
+li#privacy {
+ /* Hides all the elements irrelevant for printing */
+ display: none;
+}
+
+ul {
+ list-style-type: square;
+}
+
+#content {
+ background: none;
+ border: none ! important;
+ font-size: 11pt;
+ padding: 0 ! important;
+ margin: 0 ! important;
+}
+#footer {
+ background : white;
+ color : black;
+ border-top: 1px solid black;
+}
+
+h1, h2, h3, h4, h5, h6
+{
+ font-weight: bold;
+}
+
+p, .documentDescription {
+ margin: 1em 0 ! important;
+ line-height: 1.2em;
+}
+
+.tocindent p {
+ margin: 0 0 0 0 ! important;
+}
+
+pre {
+ border: 1pt dashed black;
+ white-space: pre;
+ font-size: 8pt;
+ overflow: auto;
+ padding: 1em 0;
+ background : white;
+ color : black;
+}
+
+table.listing,
+table.listing td {
+ border: 1pt solid black;
+ border-collapse: collapse;
+}
+
+a {
+ color: Black !important;
+ background: none !important;
+ padding: 0 !important;
+}
+
+a:link, a:visited {
+ color: #520;
+ background: transparent;
+ text-decoration: underline;
+}
+
+#content a.external.text:after, #content a.external.autonumber:after {
+ /* Expand URLs for printing */
+ content: " (" attr(href) ") ";
+}
+
+#globalWrapper {
+ width: 100% !important;
+ min-width: 0 !important;
+}
+
+#content {
+ background : white;
+ color : black;
+}
+
+#column-content {
+ margin: 0 !important;
+}
+
+#column-content #content {
+ padding: 1em;
+ margin: 0 !important;
+}
+/* MSIE/Win doesn't understand 'inherit' */
+a, a.external, a.new, a.stub {
+ color: black ! important;
+ text-decoration: none ! important;
+}
+
+/* Continue ... */
+a, a.external, a.new, a.stub {
+ color: inherit ! important;
+ text-decoration: inherit ! important;
+}
+
+img { border: none; }
+img.tex { vertical-align: middle; }
+span.texhtml { font-family: serif; }
+
+div.townBox {
+ position:relative;
+ float:right;
+ background:White;
+ margin-left:1em;
+ border: 1px solid gray;
+ padding:0.3em;
+ width: 200px;
+ overflow: hidden;
+ clear: right;
+}
+div.townBox dl {
+ padding: 0;
+ margin: 0 0 0.3em 0;
+ font-size: 96%;
+}
+div.townBox dl dt {
+ background: none;
+ margin: 0.4em 0 0 0;
+}
+div.townBox dl dd {
+ margin: 0.1em 0 0 1.1em;
+ background-color: #f3f3f3;
+}
+
+#siteNotice { display: none; }
+
+table.gallery {
+ border: 1px solid #cccccc;
+ margin: 2px;
+ padding: 2px;
+ background-color:#ffffff;
+}
+
+table.gallery tr {
+ vertical-align:top;
+}
+
+div.gallerybox {
+ border: 1px solid #cccccc;
+ margin: 2px;
+ background-color:#f9f9f9;
+ width: 150px;
+}
+
+div.gallerybox div.thumb {
+ text-align: center;
+ border: 1px solid #cccccc;
+ margin: 2px;
+}
+
+div.gallerytext {
+ font-size: 94%;
+ padding: 2px 4px;
+}
+
+/*
+** Diff rendering
+*/
+table.diff { background:white; }
+td.diff-otitle { background:#ffffff; }
+td.diff-ntitle { background:#ffffff; }
+td.diff-addedline {
+ background:#ccffcc;
+ font-size: smaller;
+ border: solid 2px black;
+}
+td.diff-deletedline {
+ background:#ffffaa;
+ font-size: smaller;
+ border: dotted 2px black;
+}
+td.diff-context {
+ background:#eeeeee;
+ font-size: smaller;
+}
+span.diffchange { color: silver; font-weight: bold; text-decoration: underline; }
+
diff --git a/skins/common/common_rtl.css b/skins/common/common_rtl.css
new file mode 100644
index 000000000000..54186bb88259
--- /dev/null
+++ b/skins/common/common_rtl.css
@@ -0,0 +1,28 @@
+/* This CSS file is called from absolutely every wiki that's RTL: unlike
+ * common.css, it's actually common to all skins. */
+
+/* js pref toc */
+#preftoc { float: right; }
+/* workaround for moz bug, displayed bullets on left side */
+#preftoc li { list-style: none; }
+#prefcontrol { float: right; }
+fieldset.prefsection,
+fieldset.operaprefsection {
+ margin-left: 0;
+ margin-right: 18em;
+}
+/* page history */
+#pagehistory span.user {
+ margin-right: 1.4em;
+ margin-left: 0.4em;
+}
+.editsection {
+ float: left;
+ margin-right: 5px;
+}
+div.tright, div.floatright {
+ clear: none;
+}
+div.tleft, div.floatleft {
+ clear: left;
+} \ No newline at end of file
diff --git a/skins/common/feed.css b/skins/common/feed.css
new file mode 100644
index 000000000000..94396639c817
--- /dev/null
+++ b/skins/common/feed.css
@@ -0,0 +1,95 @@
+/*
+Make RSS and Atom feeds at least semi-legible to folk who accidentally
+load them in a browser...
+
+Compatibility:
+* Mozilla is fine.
+* Safari 1.2: the RSS <link> text isn't shown
+* Opera 7.5 uses the style sheet instead of its native RSS mode.
+* IE/Mac 5.2: none of the :before content works; doesn't get the charset right and displays garbage for non-ASCII.
+* IE/Win 6.0: No background color, borders, font size, font weight, or :before content.
+
+*/
+
+/* RSS: */ rss, channel, title, link, description, language, generator, lastBuildDate, item, pubDate, author, comments, creator,
+/* Atom: */ feed, id, modified, tagline, entry, issued, created, updated, summary, comment {
+ display: block;
+}
+
+rss, feed {
+ background: white;
+ color: black;
+ margin: 1em;
+ font-family: "Verdana", "Tahoma", "Arial", "Helvetica", sans-serif;
+ line-height: 1.5em;
+ font-size: 76%;
+}
+
+rss:before {
+ content: "This RSS feed is meant to be read in a syndicated news reader, and isn't ideal for a web browser.";
+}
+
+feed:before {
+ content: "This Atom feed is meant to be read in a syndicated news reader, and isn't ideal for a web browser.";
+}
+rss:before, feed:before {
+ color: red;
+ text-align: center;
+ line-height: 2em;
+}
+
+channel>title,
+item>title,
+feed>title,
+entry>title {
+ font-weight: bold;
+ border-bottom: solid 1px #aaa;
+ margin-left: -0.5em;
+}
+channel>title, feed>title {
+ font-size: larger;
+}
+item>title, entry>title {
+ font-size: large;
+}
+item, entry {
+ margin-top: 1em;
+ margin-left: 2em;
+}
+
+item>description, entry>summary {
+ white-space: pre;
+ overflow: auto;
+ background: #f8f8ff;
+}
+
+pubDate:before { content: "Date: " }
+link:before { content: "Link: " }
+author:before, creator:before { content: "Author: " }
+description:before { content: "Description: " }
+id:before { content: "Id: " }
+
+generator:before { content: "Generator: " }
+language:before { content: "Language: " }
+lastBuildDate:before { content: "Updated: " }
+comments:before { content: "Comments page: " }
+
+tagline:before { content: "Tagline: " }
+issued:before { content: "Issued: " }
+created:before { content: "Created: " }
+modified:before { content: "Modified: " }
+updated:before { content: "Updated: " }
+summary:before { content: "Summary: " }
+comment:before { content: "Comment: " }
+
+pubDate:before, link:before, author:before, description:before,
+language:before, generator:before, lastBuildDate:before, comments:before,
+tagline:before, issued:before, created:before, modified:before,
+summary:before, comment:before, creator:before, id:before, updated:before {
+ color: #224;
+ font-weight: bold;
+}
+
+feed link:after {
+ content: attr(href);
+}
diff --git a/skins/common/images/Arr_.png b/skins/common/images/Arr_.png
new file mode 100644
index 000000000000..83fafc740b04
--- /dev/null
+++ b/skins/common/images/Arr_.png
Binary files differ
diff --git a/skins/common/images/Arr_d.png b/skins/common/images/Arr_d.png
new file mode 100644
index 000000000000..421dd101536e
--- /dev/null
+++ b/skins/common/images/Arr_d.png
Binary files differ
diff --git a/skins/common/images/Arr_l.png b/skins/common/images/Arr_l.png
new file mode 100644
index 000000000000..9db66232e34c
--- /dev/null
+++ b/skins/common/images/Arr_l.png
Binary files differ
diff --git a/skins/common/images/Arr_r.png b/skins/common/images/Arr_r.png
new file mode 100644
index 000000000000..d1b161b07908
--- /dev/null
+++ b/skins/common/images/Arr_r.png
Binary files differ
diff --git a/skins/common/images/Arr_r.xcf b/skins/common/images/Arr_r.xcf
new file mode 100644
index 000000000000..83b7b2a8768b
--- /dev/null
+++ b/skins/common/images/Arr_r.xcf
Binary files differ
diff --git a/skins/common/images/Arr_u.png b/skins/common/images/Arr_u.png
new file mode 100644
index 000000000000..b8e3b6c6a1ed
--- /dev/null
+++ b/skins/common/images/Arr_u.png
Binary files differ
diff --git a/skins/common/images/Zoom_sans.gif b/skins/common/images/Zoom_sans.gif
new file mode 100644
index 000000000000..6ba0adca5c98
--- /dev/null
+++ b/skins/common/images/Zoom_sans.gif
Binary files differ
diff --git a/skins/common/images/arrow_disabled_first_25.png b/skins/common/images/arrow_disabled_first_25.png
new file mode 100644
index 000000000000..aaa4bec45f2e
--- /dev/null
+++ b/skins/common/images/arrow_disabled_first_25.png
Binary files differ
diff --git a/skins/common/images/arrow_disabled_last_25.png b/skins/common/images/arrow_disabled_last_25.png
new file mode 100644
index 000000000000..7882fd8c918c
--- /dev/null
+++ b/skins/common/images/arrow_disabled_last_25.png
Binary files differ
diff --git a/skins/common/images/arrow_disabled_left_25.png b/skins/common/images/arrow_disabled_left_25.png
new file mode 100644
index 000000000000..e0c300429273
--- /dev/null
+++ b/skins/common/images/arrow_disabled_left_25.png
Binary files differ
diff --git a/skins/common/images/arrow_disabled_right_25.png b/skins/common/images/arrow_disabled_right_25.png
new file mode 100644
index 000000000000..bfec3e246759
--- /dev/null
+++ b/skins/common/images/arrow_disabled_right_25.png
Binary files differ
diff --git a/skins/common/images/arrow_first.svg b/skins/common/images/arrow_first.svg
new file mode 100644
index 000000000000..c1d8e364e145
--- /dev/null
+++ b/skins/common/images/arrow_first.svg
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="512.85712"
+ height="600"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.44"
+ version="1.0"
+ sodipodi:docbase="C:\htdocs\w\skins\common\images"
+ sodipodi:docname="big_arrow_first.svg"
+ inkscape:export-filename="C:\htdocs\w\skins\common\images\big_arrow_left.png"
+ inkscape:export-xdpi="5.0520902"
+ inkscape:export-ydpi="5.0520902">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="375"
+ inkscape:cy="520"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="600.24px"
+ height="600.88px"
+ inkscape:window-width="853"
+ inkscape:window-height="573"
+ inkscape:window-x="66"
+ inkscape:window-y="87" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-239.3783,-208.0743)">
+ <path
+ sodipodi:type="star"
+ style="fill:#00a;fill-opacity:1;fill-rule:evenodd;stroke:#00a;stroke-width:10.35552788;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path1874"
+ sodipodi:sides="3"
+ sodipodi:cx="94.285713"
+ sodipodi:cy="343.79074"
+ sodipodi:r1="75.484825"
+ sodipodi:r2="37.742413"
+ sodipodi:arg1="1.056345"
+ sodipodi:arg2="2.1035426"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M 131.42857,409.50502 L 18.804046,343.10026 L 132.62452,278.76694 L 131.42857,409.50502 z "
+ transform="matrix(3.596688,0,0,4.278606,254.9147,-964.348)" />
+ <rect
+ style="fill:#00a;fill-opacity:1;stroke:#00a;stroke-width:39.31948471;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3737"
+ width="20.680517"
+ height="560.68054"
+ x="259.03799"
+ y="227.73401" />
+ </g>
+</svg>
diff --git a/skins/common/images/arrow_first_25.png b/skins/common/images/arrow_first_25.png
new file mode 100644
index 000000000000..b6351c50f85a
--- /dev/null
+++ b/skins/common/images/arrow_first_25.png
Binary files differ
diff --git a/skins/common/images/arrow_last_25.png b/skins/common/images/arrow_last_25.png
new file mode 100644
index 000000000000..d416ab393af0
--- /dev/null
+++ b/skins/common/images/arrow_last_25.png
Binary files differ
diff --git a/skins/common/images/arrow_left.svg b/skins/common/images/arrow_left.svg
new file mode 100644
index 000000000000..bd4bbc746616
--- /dev/null
+++ b/skins/common/images/arrow_left.svg
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="450"
+ height="600"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.44"
+ version="1.0"
+ sodipodi:docbase="C:\htdocs\w\skins\common\images"
+ sodipodi:docname="big_arrow_left.svg"
+ inkscape:export-filename="C:\htdocs\w\skins\common\images\big_arrow_left.png"
+ inkscape:export-xdpi="5.0520902"
+ inkscape:export-ydpi="5.0520902">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="375"
+ inkscape:cy="520"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="600.24px"
+ height="600.88px"
+ inkscape:window-width="853"
+ inkscape:window-height="573"
+ inkscape:window-x="66"
+ inkscape:window-y="87" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-302.2354,-208.0743)">
+ <path
+ sodipodi:type="star"
+ style="fill:#00a;fill-opacity:1;fill-rule:evenodd;stroke:#00a;stroke-width:10.35552788;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path1874"
+ sodipodi:sides="3"
+ sodipodi:cx="94.285713"
+ sodipodi:cy="343.79074"
+ sodipodi:r1="75.484825"
+ sodipodi:r2="37.742413"
+ sodipodi:arg1="1.056345"
+ sodipodi:arg2="2.1035426"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M 131.42857,409.50502 L 18.804046,343.10026 L 132.62452,278.76694 L 131.42857,409.50502 z "
+ transform="matrix(3.596688,0,0,4.278606,254.9147,-964.348)" />
+ </g>
+</svg>
diff --git a/skins/common/images/arrow_left_25.png b/skins/common/images/arrow_left_25.png
new file mode 100644
index 000000000000..fd05fa6f4650
--- /dev/null
+++ b/skins/common/images/arrow_left_25.png
Binary files differ
diff --git a/skins/common/images/arrow_right_25.png b/skins/common/images/arrow_right_25.png
new file mode 100644
index 000000000000..cf1845c61bc9
--- /dev/null
+++ b/skins/common/images/arrow_right_25.png
Binary files differ
diff --git a/skins/common/images/bullet.gif b/skins/common/images/bullet.gif
new file mode 100644
index 000000000000..b43de48a4701
--- /dev/null
+++ b/skins/common/images/bullet.gif
Binary files differ
diff --git a/skins/common/images/button_bold.png b/skins/common/images/button_bold.png
new file mode 100644
index 000000000000..5e52deed0670
--- /dev/null
+++ b/skins/common/images/button_bold.png
Binary files differ
diff --git a/skins/common/images/button_extlink.png b/skins/common/images/button_extlink.png
new file mode 100644
index 000000000000..12ec5f2ea104
--- /dev/null
+++ b/skins/common/images/button_extlink.png
Binary files differ
diff --git a/skins/common/images/button_headline.png b/skins/common/images/button_headline.png
new file mode 100644
index 000000000000..aa0ca540e348
--- /dev/null
+++ b/skins/common/images/button_headline.png
Binary files differ
diff --git a/skins/common/images/button_hr.png b/skins/common/images/button_hr.png
new file mode 100644
index 000000000000..19cfc48042a7
--- /dev/null
+++ b/skins/common/images/button_hr.png
Binary files differ
diff --git a/skins/common/images/button_image.png b/skins/common/images/button_image.png
new file mode 100644
index 000000000000..6c3c3308ed71
--- /dev/null
+++ b/skins/common/images/button_image.png
Binary files differ
diff --git a/skins/common/images/button_italic.png b/skins/common/images/button_italic.png
new file mode 100644
index 000000000000..96b1fb9fc28d
--- /dev/null
+++ b/skins/common/images/button_italic.png
Binary files differ
diff --git a/skins/common/images/button_link.png b/skins/common/images/button_link.png
new file mode 100644
index 000000000000..e9507b970c0c
--- /dev/null
+++ b/skins/common/images/button_link.png
Binary files differ
diff --git a/skins/common/images/button_math.png b/skins/common/images/button_math.png
new file mode 100644
index 000000000000..e91fb6130150
--- /dev/null
+++ b/skins/common/images/button_math.png
Binary files differ
diff --git a/skins/common/images/button_media.png b/skins/common/images/button_media.png
new file mode 100644
index 000000000000..020707901baf
--- /dev/null
+++ b/skins/common/images/button_media.png
Binary files differ
diff --git a/skins/common/images/button_nowiki.png b/skins/common/images/button_nowiki.png
new file mode 100644
index 000000000000..7b2d53929667
--- /dev/null
+++ b/skins/common/images/button_nowiki.png
Binary files differ
diff --git a/skins/common/images/button_sig.png b/skins/common/images/button_sig.png
new file mode 100644
index 000000000000..ef3a46d24bf6
--- /dev/null
+++ b/skins/common/images/button_sig.png
Binary files differ
diff --git a/skins/common/images/button_template.png b/skins/common/images/button_template.png
new file mode 100644
index 000000000000..8e9cc2671e58
--- /dev/null
+++ b/skins/common/images/button_template.png
Binary files differ
diff --git a/skins/common/images/fileicon.xcf b/skins/common/images/fileicon.xcf
new file mode 100644
index 000000000000..85a0a6108442
--- /dev/null
+++ b/skins/common/images/fileicon.xcf
Binary files differ
diff --git a/skins/common/images/gnu-fdl.png b/skins/common/images/gnu-fdl.png
new file mode 100644
index 000000000000..1371aba886e5
--- /dev/null
+++ b/skins/common/images/gnu-fdl.png
Binary files differ
diff --git a/skins/common/images/gnu-fdl.xcf b/skins/common/images/gnu-fdl.xcf
new file mode 100644
index 000000000000..364440dd7779
--- /dev/null
+++ b/skins/common/images/gnu-fdl.xcf
Binary files differ
diff --git a/skins/common/images/icons/COPYING b/skins/common/images/icons/COPYING
new file mode 100644
index 000000000000..136530a91e4b
--- /dev/null
+++ b/skins/common/images/icons/COPYING
@@ -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/skins/common/images/icons/fileicon-c.png b/skins/common/images/icons/fileicon-c.png
new file mode 100644
index 000000000000..6da6916e9c57
--- /dev/null
+++ b/skins/common/images/icons/fileicon-c.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-cpp.png b/skins/common/images/icons/fileicon-cpp.png
new file mode 100644
index 000000000000..ba54e77f8f85
--- /dev/null
+++ b/skins/common/images/icons/fileicon-cpp.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-deb.png b/skins/common/images/icons/fileicon-deb.png
new file mode 100644
index 000000000000..ac1e2cf93300
--- /dev/null
+++ b/skins/common/images/icons/fileicon-deb.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-djvu.png b/skins/common/images/icons/fileicon-djvu.png
new file mode 100644
index 000000000000..2e1e2c9b888b
--- /dev/null
+++ b/skins/common/images/icons/fileicon-djvu.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-djvu.xcf b/skins/common/images/icons/fileicon-djvu.xcf
new file mode 100644
index 000000000000..8043dcdb51b1
--- /dev/null
+++ b/skins/common/images/icons/fileicon-djvu.xcf
Binary files differ
diff --git a/skins/common/images/icons/fileicon-dvi.png b/skins/common/images/icons/fileicon-dvi.png
new file mode 100644
index 000000000000..6c7aa1a1d158
--- /dev/null
+++ b/skins/common/images/icons/fileicon-dvi.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-exe.png b/skins/common/images/icons/fileicon-exe.png
new file mode 100644
index 000000000000..6ccf1821594d
--- /dev/null
+++ b/skins/common/images/icons/fileicon-exe.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-h.png b/skins/common/images/icons/fileicon-h.png
new file mode 100644
index 000000000000..d091afffa047
--- /dev/null
+++ b/skins/common/images/icons/fileicon-h.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-html.png b/skins/common/images/icons/fileicon-html.png
new file mode 100644
index 000000000000..7c47952513a7
--- /dev/null
+++ b/skins/common/images/icons/fileicon-html.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-iso.png b/skins/common/images/icons/fileicon-iso.png
new file mode 100644
index 000000000000..b4192e9e71b6
--- /dev/null
+++ b/skins/common/images/icons/fileicon-iso.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-java.png b/skins/common/images/icons/fileicon-java.png
new file mode 100644
index 000000000000..757c6aec9ae2
--- /dev/null
+++ b/skins/common/images/icons/fileicon-java.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-mid.png b/skins/common/images/icons/fileicon-mid.png
new file mode 100644
index 000000000000..aa82607029a4
--- /dev/null
+++ b/skins/common/images/icons/fileicon-mid.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-mov.png b/skins/common/images/icons/fileicon-mov.png
new file mode 100644
index 000000000000..2c0da0d8771c
--- /dev/null
+++ b/skins/common/images/icons/fileicon-mov.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-o.png b/skins/common/images/icons/fileicon-o.png
new file mode 100644
index 000000000000..bf051cb807cc
--- /dev/null
+++ b/skins/common/images/icons/fileicon-o.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-ogg.png b/skins/common/images/icons/fileicon-ogg.png
new file mode 100644
index 000000000000..b8ba77141c1d
--- /dev/null
+++ b/skins/common/images/icons/fileicon-ogg.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-ogg.xcf b/skins/common/images/icons/fileicon-ogg.xcf
new file mode 100644
index 000000000000..a91024bf219a
--- /dev/null
+++ b/skins/common/images/icons/fileicon-ogg.xcf
Binary files differ
diff --git a/skins/common/images/icons/fileicon-pdf.png b/skins/common/images/icons/fileicon-pdf.png
new file mode 100644
index 000000000000..ee39b6c3c986
--- /dev/null
+++ b/skins/common/images/icons/fileicon-pdf.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-ps.png b/skins/common/images/icons/fileicon-ps.png
new file mode 100644
index 000000000000..f1f504d77e69
--- /dev/null
+++ b/skins/common/images/icons/fileicon-ps.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-rm.png b/skins/common/images/icons/fileicon-rm.png
new file mode 100644
index 000000000000..5ba04e5a0658
--- /dev/null
+++ b/skins/common/images/icons/fileicon-rm.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-rpm.png b/skins/common/images/icons/fileicon-rpm.png
new file mode 100644
index 000000000000..0f1c3b87a8f2
--- /dev/null
+++ b/skins/common/images/icons/fileicon-rpm.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-svg.png b/skins/common/images/icons/fileicon-svg.png
new file mode 100644
index 000000000000..8dc6d30fd564
--- /dev/null
+++ b/skins/common/images/icons/fileicon-svg.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-tar.png b/skins/common/images/icons/fileicon-tar.png
new file mode 100644
index 000000000000..a4b15d7f75cc
--- /dev/null
+++ b/skins/common/images/icons/fileicon-tar.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-tex.png b/skins/common/images/icons/fileicon-tex.png
new file mode 100644
index 000000000000..ee8c0226b8ba
--- /dev/null
+++ b/skins/common/images/icons/fileicon-tex.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-ttf.png b/skins/common/images/icons/fileicon-ttf.png
new file mode 100644
index 000000000000..1b53066ea19e
--- /dev/null
+++ b/skins/common/images/icons/fileicon-ttf.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon-txt.png b/skins/common/images/icons/fileicon-txt.png
new file mode 100644
index 000000000000..76e98909bd39
--- /dev/null
+++ b/skins/common/images/icons/fileicon-txt.png
Binary files differ
diff --git a/skins/common/images/icons/fileicon.png b/skins/common/images/icons/fileicon.png
new file mode 100644
index 000000000000..5675170b103f
--- /dev/null
+++ b/skins/common/images/icons/fileicon.png
Binary files differ
diff --git a/skins/common/images/link_icon.gif b/skins/common/images/link_icon.gif
new file mode 100644
index 000000000000..815ccb1b1ca0
--- /dev/null
+++ b/skins/common/images/link_icon.gif
Binary files differ
diff --git a/skins/common/images/magnify-clip.png b/skins/common/images/magnify-clip.png
new file mode 100644
index 000000000000..50abcb6823f1
--- /dev/null
+++ b/skins/common/images/magnify-clip.png
Binary files differ
diff --git a/skins/common/images/mediawiki-large.xcf b/skins/common/images/mediawiki-large.xcf
new file mode 100644
index 000000000000..5e42f874b929
--- /dev/null
+++ b/skins/common/images/mediawiki-large.xcf
Binary files differ
diff --git a/skins/common/images/mediawiki-largesquare.xcf b/skins/common/images/mediawiki-largesquare.xcf
new file mode 100644
index 000000000000..7547e5d52614
--- /dev/null
+++ b/skins/common/images/mediawiki-largesquare.xcf
Binary files differ
diff --git a/skins/common/images/mediawiki-small.xcf b/skins/common/images/mediawiki-small.xcf
new file mode 100644
index 000000000000..75355171dc6b
--- /dev/null
+++ b/skins/common/images/mediawiki-small.xcf
Binary files differ
diff --git a/skins/common/images/mediawiki.png b/skins/common/images/mediawiki.png
new file mode 100644
index 000000000000..69fce98855c2
--- /dev/null
+++ b/skins/common/images/mediawiki.png
Binary files differ
diff --git a/skins/common/images/poweredby_mediawiki_88x31.png b/skins/common/images/poweredby_mediawiki_88x31.png
new file mode 100644
index 000000000000..ce1765d163e2
--- /dev/null
+++ b/skins/common/images/poweredby_mediawiki_88x31.png
Binary files differ
diff --git a/skins/common/images/redirectltr.png b/skins/common/images/redirectltr.png
new file mode 100644
index 000000000000..9110ca137bee
--- /dev/null
+++ b/skins/common/images/redirectltr.png
Binary files differ
diff --git a/skins/common/images/redirectrtl.png b/skins/common/images/redirectrtl.png
new file mode 100644
index 000000000000..60fd59d3e89d
--- /dev/null
+++ b/skins/common/images/redirectrtl.png
Binary files differ
diff --git a/skins/common/images/sort_down.gif b/skins/common/images/sort_down.gif
new file mode 100644
index 000000000000..5ff08160ca77
--- /dev/null
+++ b/skins/common/images/sort_down.gif
Binary files differ
diff --git a/skins/common/images/sort_none.gif b/skins/common/images/sort_none.gif
new file mode 100644
index 000000000000..6bb028242d0f
--- /dev/null
+++ b/skins/common/images/sort_none.gif
Binary files differ
diff --git a/skins/common/images/sort_up.gif b/skins/common/images/sort_up.gif
new file mode 100644
index 000000000000..53002968590e
--- /dev/null
+++ b/skins/common/images/sort_up.gif
Binary files differ
diff --git a/skins/common/images/wiki.png b/skins/common/images/wiki.png
new file mode 100644
index 000000000000..49913f6a45ef
--- /dev/null
+++ b/skins/common/images/wiki.png
Binary files differ
diff --git a/skins/common/metadata.js b/skins/common/metadata.js
new file mode 100644
index 000000000000..9f7a8e01b7cd
--- /dev/null
+++ b/skins/common/metadata.js
@@ -0,0 +1,49 @@
+// Exif metadata display for MediaWiki file uploads
+//
+// Add an expand/collapse link and collapse by default if set to
+// (with JS disabled, user will see all items)
+//
+// attachMetadataToggle("mw_metadata", "More...", "Fewer...");
+
+
+function attachMetadataToggle(tableId, showText, hideText) {
+ if (document.createTextNode) {
+ var box = document.getElementById(tableId);
+ if (!box)
+ return false;
+
+ var tbody = box.getElementsByTagName('tbody')[0];
+
+ var row = document.createElement('tr');
+
+ var col = document.createElement('td');
+ col.colSpan = 2;
+
+ var link = document.createElement('a');
+ link.href = '#';
+
+ link.onclick = function() {
+ if (box.className == 'mw_metadata collapsed') {
+ changeText(link, hideText);
+ box.className = 'mw_metadata expanded';
+ } else {
+ changeText(link, showText);
+ box.className = 'mw_metadata collapsed';
+ }
+ return false;
+ }
+
+ var text = document.createTextNode(hideText);
+
+ link.appendChild(text);
+ col.appendChild(link);
+ row.appendChild(col);
+ tbody.appendChild(row);
+
+ // And collapse!
+ link.onclick();
+
+ return true;
+ }
+ return false;
+}
diff --git a/skins/common/nostalgia.css b/skins/common/nostalgia.css
new file mode 100644
index 000000000000..c9b36a70b0fb
--- /dev/null
+++ b/skins/common/nostalgia.css
@@ -0,0 +1,17 @@
+body {
+ /* Background color is set separately on page type */
+ color: black;
+}
+#specialform { display: inline; }
+#powersearch {
+ background: #DDEEFF; border-style: solid; border-width: 1px; padding: 2px;
+}
+a.interwiki, a.external { color: #3366BB; }
+a.printable { text-decoration: underline; }
+a.stub { color:#772233; text-decoration:none; }
+h1.pagetitle { padding-top: 0; margin-top: 0; padding-bottom: 0; margin-bottom: 0; }
+h2, h3, h4, h5, h6 { margin-bottom: 0; }
+textarea { overflow: auto; }
+p.subtitle { padding-top: 0; margin-top: 0; }
+
+
diff --git a/skins/common/preview.js b/skins/common/preview.js
new file mode 100644
index 000000000000..b117e85b7ba9
--- /dev/null
+++ b/skins/common/preview.js
@@ -0,0 +1,53 @@
+// Live preview
+
+function openXMLHttpRequest() {
+ if( window.XMLHttpRequest ) {
+ return new XMLHttpRequest();
+ } else if( window.ActiveXObject && navigator.platform != 'MacPPC' ) {
+ // IE/Mac has an ActiveXObject but it doesn't work.
+ return new ActiveXObject("Microsoft.XMLHTTP");
+ } else {
+ return null;
+ }
+}
+
+/**
+ * Returns true if could open the request,
+ * false otherwise (eg no browser support).
+ */
+function livePreview(target, text, postUrl) {
+ prevTarget = target;
+ if( !target ) {
+ window.alert('Live preview failed!\nTry normal preview.');
+ var fallback = document.getElementById('wpPreview');
+ if ( fallback ) { fallback.style.display = 'inline'; }
+ }
+ prevReq = openXMLHttpRequest();
+ if( !prevReq ) return false;
+
+ prevReq.onreadystatechange = updatePreviewText;
+ prevReq.open("POST", postUrl, true);
+
+ var postData = 'wpTextbox1=' + encodeURIComponent(text);
+ prevReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ prevReq.send(postData);
+ return true;
+}
+
+function updatePreviewText() {
+ if( prevReq.readyState != 4 ) {
+ return;
+ }
+ if( prevReq.status != 200 ) {
+ window.alert('Failed to connect: ' + prevReq.status +
+ ' "' + prevReq.statusText + '"');
+ var fallback = document.getElementById('wpPreview');
+ if ( fallback ) { fallback.style.display = 'inline'; }
+ return;
+ }
+ prevTarget.innerHTML = prevReq.responseText;
+
+ /* Hide the active diff if it exists */
+ var diff = document.getElementById('wikiDiff');
+ if ( diff ) { diff.style.display = 'none'; }
+}
diff --git a/skins/common/protect.js b/skins/common/protect.js
new file mode 100644
index 000000000000..4baa5e4c04cf
--- /dev/null
+++ b/skins/common/protect.js
@@ -0,0 +1,129 @@
+function protectInitialize(tableId, labelText) {
+ if (document.createTextNode) {
+ var box = document.getElementById(tableId);
+ if (!box)
+ return false;
+
+ var tbody = box.getElementsByTagName('tbody')[0];
+ var row = document.createElement('tr');
+ tbody.appendChild(row);
+
+ row.appendChild(document.createElement('td'));
+ var col2 = document.createElement('td');
+ row.appendChild(col2);
+
+ var check = document.createElement('input');
+ check.id = "mwProtectUnchained";
+ check.type = "checkbox";
+ check.onclick = protectChainUpdate;
+ col2.appendChild(check);
+
+ var space = document.createTextNode(" ");
+ col2.appendChild(space);
+
+ var label = document.createElement('label');
+ label.setAttribute("for", "mwProtectUnchained");
+ label.appendChild(document.createTextNode(labelText));
+ col2.appendChild(label);
+
+ if (protectAllMatch()) {
+ check.checked = false;
+ protectEnable(false);
+ } else {
+ check.checked = true;
+ protectEnable(true);
+ }
+
+ return true;
+ }
+ return false;
+}
+
+function protectLevelsUpdate(source) {
+ if (!protectUnchained()) {
+ protectUpdateAll(source.selectedIndex);
+ }
+}
+
+function protectChainUpdate() {
+ if (protectUnchained()) {
+ protectEnable(true);
+ } else {
+ protectChain();
+ protectEnable(false);
+ }
+}
+
+
+function protectAllMatch() {
+ var values = new Array();
+ protectForSelectors(function(set) {
+ values[values.length] = set.selectedIndex;
+ });
+ for (var i = 1; i < values.length; i++) {
+ if (values[i] != values[0]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+function protectUnchained() {
+ var unchain = document.getElementById("mwProtectUnchained");
+ if (!unchain) {
+ alert("This shouldn't happen");
+ return false;
+ }
+ return unchain.checked;
+}
+
+function protectChain() {
+ // Find the highest-protected action and bump them all to this level
+ var maxIndex = -1;
+ protectForSelectors(function(set) {
+ if (set.selectedIndex > maxIndex) {
+ maxIndex = set.selectedIndex;
+ }
+ });
+ protectUpdateAll(maxIndex);
+}
+
+function protectUpdateAll(index) {
+ protectForSelectors(function(set) {
+ if (set.selectedIndex != index) {
+ set.selectedIndex = index;
+ }
+ });
+}
+
+function protectForSelectors(func) {
+ var selectors = protectSelectors();
+ for (var i = 0; i < selectors.length; i++) {
+ func(selectors[i]);
+ }
+}
+
+function protectSelectors() {
+ var all = document.getElementsByTagName("select");
+ var ours = new Array();
+ for (var i = 0; i < all.length; i++) {
+ var set = all[i];
+ if (set.id.match(/^mwProtect-level-/)) {
+ ours[ours.length] = set;
+ }
+ }
+ return ours;
+}
+
+function protectEnable(val) {
+ // fixme
+ var first = true;
+ protectForSelectors(function(set) {
+ if (first) {
+ first = false;
+ } else {
+ set.disabled = !val;
+ set.style.visible = val ? "visible" : "hidden";
+ }
+ });
+}
diff --git a/skins/common/quickbar-right.css b/skins/common/quickbar-right.css
new file mode 100644
index 000000000000..43bd427aebb4
--- /dev/null
+++ b/skins/common/quickbar-right.css
@@ -0,0 +1 @@
+#quickbar { position: fixed; right: 0px; top: 0px; padding: 4px;}
diff --git a/skins/common/quickbar.css b/skins/common/quickbar.css
new file mode 100644
index 000000000000..d7930c2abc82
--- /dev/null
+++ b/skins/common/quickbar.css
@@ -0,0 +1 @@
+#quickbar { position: fixed; padding: 4px; }
diff --git a/skins/common/sorttable.js b/skins/common/sorttable.js
new file mode 100644
index 000000000000..229b4c3a83ab
--- /dev/null
+++ b/skins/common/sorttable.js
@@ -0,0 +1,358 @@
+/*
+ * Table sorting script by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
+ * Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
+ * Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html .
+ *
+ * Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.
+ *
+ * @todo don't break on colspans/rowspans (bug 8028)
+ * @todo language-specific digit grouping/decimals (bug 8063)
+ * @todo support all accepted date formats (bug 8226)
+ */
+
+var image_path = stylepath+"/common/images/";
+var image_up = "sort_up.gif";
+var image_down = "sort_down.gif";
+var image_none = "sort_none.gif";
+var europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true"
+
+var alternate_row_colors = true;
+
+
+hookEvent( "load", sortables_init);
+
+var SORT_COLUMN_INDEX;
+var thead = false;
+
+function sortables_init() {
+ var idnum = 0;
+ // Find all tables with class sortable and make them sortable
+ if (!document.getElementsByTagName) return;
+ tbls = document.getElementsByTagName("table");
+ for (ti=0;ti<tbls.length;ti++) {
+ thisTbl = tbls[ti];
+ if ( (' '+thisTbl.className+' ').indexOf("sortable") != -1 ) {
+ if (!thisTbl.id) {
+ thisTbl.setAttribute('id','sortable_table_id_'+idnum);
+ ++idnum;
+ }
+ ts_makeSortable(thisTbl);
+ }
+ }
+}
+
+function ts_makeSortable(table) {
+ if (table.rows && table.rows.length > 0) {
+ if (table.tHead && table.tHead.rows.length > 0) {
+ var firstRow = table.tHead.rows[table.tHead.rows.length-1];
+ thead = true;
+ } else {
+ var firstRow = table.rows[0];
+ }
+ }
+ if (!firstRow) return;
+
+ // We have a first row: assume it's the header, and make its contents clickable links
+ for (var i=0;i<firstRow.cells.length;i++) {
+ var cell = firstRow.cells[i];
+ if (cell.className != "unsortable" && cell.className.indexOf("unsortable") == -1) {
+ cell.innerHTML += '&nbsp;&nbsp;<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;"><span class="sortarrow"><img src="'+ image_path + image_none + '" alt="&darr;"/></span></a>';
+ }
+ }
+ if (alternate_row_colors) {
+ alternate(table);
+ }
+}
+
+function ts_getInnerText(el) {
+ if (typeof el == "string") return el;
+ if (typeof el == "undefined") { return el };
+ if (el.innerText) return el.innerText; //Not needed but it is faster
+ var str = "";
+
+ var cs = el.childNodes;
+ var l = cs.length;
+ for (var i = 0; i < l; i++) {
+ switch (cs[i].nodeType) {
+ case 1: //ELEMENT_NODE
+ str += ts_getInnerText(cs[i]);
+ break;
+ case 3: //TEXT_NODE
+ str += cs[i].nodeValue;
+ break;
+ }
+ }
+ return str;
+}
+
+function ts_resortTable(lnk) {
+ // get the span
+ var span;
+ for (var ci=0;ci<lnk.childNodes.length;ci++) {
+ if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span') span = lnk.childNodes[ci];
+ }
+ var spantext = ts_getInnerText(span);
+ var td = lnk.parentNode;
+ var column = td.cellIndex;
+ var table = getParent(td,'TABLE');
+
+ // Work out a type for the column
+ if (table.rows.length <= 1) return;
+
+ for( var i = 1, itm = ""; itm.match(/^([\s]|\n|\&nbsp;|<!--[^-]+-->)*$/); i++) {
+ var itm = ts_getInnerText(table.tBodies[0].rows[i].cells[column]);
+ itm = trim(itm);
+ }
+ sortfn = ts_sort_caseinsensitive;
+ if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/)) sortfn = ts_sort_date;
+ if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/)) sortfn = ts_sort_date;
+ if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/)) sortfn = ts_sort_date;
+ if (itm.match(/^[$ۢ]/)) sortfn = ts_sort_currency;
+ if (itm.match(/^[\d.,]+\%?$/)) sortfn = ts_sort_numeric;
+ SORT_COLUMN_INDEX = column;
+ var firstRow = new Array();
+ var newRows = new Array();
+
+ for (k=0;k<table.tBodies.length;k++) {
+ for (i=0;i<table.tBodies[k].rows[0].length;i++) {
+ firstRow[i] = table.tBodies[k].rows[0][i];
+ }
+ }
+
+ for (k=0;k<table.tBodies.length;k++) {
+ if (!thead) {
+ // Skip the first row
+ for (j=1;j<table.tBodies[k].rows.length;j++) {
+ newRows[j-1] = table.tBodies[k].rows[j];
+ }
+ } else {
+ // Do NOT skip the first row
+ for (j=0;j<table.tBodies[k].rows.length;j++) {
+ newRows[j] = table.tBodies[k].rows[j];
+ }
+ }
+ }
+
+ newRows.sort(sortfn);
+
+ if (span.getAttribute("sortdir") == 'down') {
+ ARROW = '<img src="'+ image_path + image_down + '" alt="&darr;"/>';
+ newRows.reverse();
+ span.setAttribute('sortdir','up');
+ } else {
+ ARROW = '<img src="'+ image_path + image_up + '" alt="&uarr;"/>';
+ span.setAttribute('sortdir','down');
+ }
+
+ // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
+ // don't do sortbottom rows
+ for (i=0; i<newRows.length; i++) {
+ if (!newRows[i].className || (newRows[i].className && (newRows[i].className.indexOf('sortbottom') == -1))) {
+ table.tBodies[0].appendChild(newRows[i]);
+ }
+ }
+ // do sortbottom rows only
+ for (i=0; i<newRows.length; i++) {
+ if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1))
+ table.tBodies[0].appendChild(newRows[i]);
+ }
+
+ // Delete any other arrows there may be showing
+ var allspans = document.getElementsByTagName("span");
+ for (var ci=0;ci<allspans.length;ci++) {
+ if (allspans[ci].className == 'sortarrow') {
+ if (getParent(allspans[ci],"table") == getParent(lnk,"table")) { // in the same table as us?
+ allspans[ci].innerHTML = '<img src="'+ image_path + image_none + '" alt="&darr;"/>';
+ }
+ }
+ }
+
+ span.innerHTML = ARROW;
+ alternate(table);
+}
+
+function getParent(el, pTagName) {
+ if (el == null) {
+ return null;
+ } else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) { // Gecko bug, supposed to be uppercase
+ return el;
+ } else {
+ return getParent(el.parentNode, pTagName);
+ }
+}
+
+function sort_date(date) {
+ // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
+ dt = "00000000";
+ if (date.length == 11) {
+ monthstr = date.substr(3,3);
+ monthstr = monthstr.toLowerCase();
+ switch(monthstr) {
+ case "jan": var month = "01"; break;
+ case "feb": var month = "02"; break;
+ case "mar": var month = "03"; break;
+ case "apr": var month = "04"; break;
+ case "may": var month = "05"; break;
+ case "jun": var month = "06"; break;
+ case "jul": var month = "07"; break;
+ case "aug": var month = "08"; break;
+ case "sep": var month = "09"; break;
+ case "oct": var month = "10"; break;
+ case "nov": var month = "11"; break;
+ case "dec": var month = "12"; break;
+ // default: var month = "00";
+ }
+ dt = date.substr(7,4)+month+date.substr(0,2);
+ return dt;
+ } else if (date.length == 10) {
+ if (europeandate == false) {
+ dt = date.substr(6,4)+date.substr(0,2)+date.substr(3,2);
+ return dt;
+ } else {
+ dt = date.substr(6,4)+date.substr(3,2)+date.substr(0,2);
+ return dt;
+ }
+ } else if (date.length == 8) {
+ yr = date.substr(6,2);
+ if (parseInt(yr) < 50) {
+ yr = '20'+yr;
+ } else {
+ yr = '19'+yr;
+ }
+ if (europeandate == true) {
+ dt = yr+date.substr(3,2)+date.substr(0,2);
+ return dt;
+ } else {
+ dt = yr+date.substr(0,2)+date.substr(3,2);
+ return dt;
+ }
+ }
+ return dt;
+}
+
+function ts_sort_date(a,b) {
+ dt1 = sort_date(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]));
+ dt2 = sort_date(ts_getInnerText(b.cells[SORT_COLUMN_INDEX]));
+
+ if (dt1==dt2) {
+ return 0;
+ }
+ if (dt1<dt2) {
+ return -1;
+ }
+ return 1;
+}
+
+function ts_sort_currency(a,b) {
+ aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
+ bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
+ return compare_numeric(aa,bb);
+}
+
+function ts_sort_numeric(a,b) {
+ aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
+ bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
+ return compare_numeric(aa,bb);
+}
+
+function compare_numeric(a,b) {
+ a = parseFloat(a.replace(/,/, ""));
+ a = (isNaN(a) ? 0 : a);
+ b = parseFloat(b.replace(/,/, ""));
+ b = (isNaN(b) ? 0 : b);
+ return a - b;
+}
+
+function ts_sort_caseinsensitive(a,b) {
+ aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
+ bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
+ if (aa==bb) {
+ return 0;
+ }
+ if (aa<bb) {
+ return -1;
+ }
+ return 1;
+}
+
+function ts_sort_default(a,b) {
+ aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
+ bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
+ if (aa==bb) {
+ return 0;
+ }
+ if (aa<bb) {
+ return -1;
+ }
+ return 1;
+}
+
+function addEvent(elm, evType, fn, useCapture)
+// addEvent and removeEvent
+// cross-browser event handling for IE5+, NS6 and Mozilla
+// By Scott Andrew
+{
+ if (elm.addEventListener){
+ elm.addEventListener(evType, fn, useCapture);
+ return true;
+ } else if (elm.attachEvent){
+ var r = elm.attachEvent("on"+evType, fn);
+ return r;
+ } else {
+ alert("Handler could not be removed");
+ }
+}
+
+function replace(s, t, u) {
+ /*
+ ** Replace a token in a string
+ ** s string to be processed
+ ** t token to be found and removed
+ ** u token to be inserted
+ ** returns new String
+ */
+ i = s.indexOf(t);
+ r = "";
+ if (i == -1) return s;
+ r += s.substring(0,i) + u;
+ if ( i + t.length < s.length) {
+ r += replace(s.substring(i + t.length, s.length), t, u);
+ }
+ return r;
+}
+
+function trim(s) {
+ return s.replace(/^([ \t]|\n|\&nbsp;|<!--[^-]+-->)*/, "").replace(/([ \t]|\n|\&nbsp;|<!--[^-]+-->)*$/, "");
+}
+
+function alternate(table) {
+ // Take object table and get all it's tbodies.
+ var tableBodies = table.getElementsByTagName("tbody");
+ // Loop through these tbodies
+ for (var i = 0; i < tableBodies.length; i++) {
+ // Take the tbody, and get all it's rows
+ var tableRows = tableBodies[i].getElementsByTagName("tr");
+ // Loop through these rows
+ // Start at 1 because we want to leave the heading row untouched
+ for (var j = 0; j < tableRows.length; j++) {
+ // Check if j is even, and apply classes for both possible results
+ if ( (j % 2) == 0 ) {
+ if ( !(tableRows[j].className.indexOf('odd') == -1) ) {
+ tableRows[j].className = replace(tableRows[j].className, 'odd', 'even');
+ } else {
+ if ( tableRows[j].className.indexOf('even') == -1 ) {
+ tableRows[j].className += " even";
+ }
+ }
+ } else {
+ if ( !(tableRows[j].className.indexOf('even') == -1) ) {
+ tableRows[j].className = replace(tableRows[j].className, 'even', 'odd');
+ } else {
+ if ( tableRows[j].className.indexOf('odd') == -1 ) {
+ tableRows[j].className += " odd";
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/skins/common/sticky.js b/skins/common/sticky.js
new file mode 100644
index 000000000000..cf248c3e3606
--- /dev/null
+++ b/skins/common/sticky.js
@@ -0,0 +1,124 @@
+// Make a layer that stays in the same place on screen when scrolling the browser window.
+// Version 1.2
+// See http://www.mark.ac/help for browser support.
+
+var mySticky;
+var theLayer;
+
+// Setup variables for sliding.
+// lastY and staticYOffset should match your CSS top definition.
+
+lastY=10;YOffset=0;staticYOffset=10;refreshMS=25;
+
+
+// Setup function that runs when the page loads.
+ function setup(eID){
+ bw=new checkBrowser;
+ if(bw.ns4||bw.opera){MM_reloadPage(true);}
+ var noFix=bw.ie4||bw.ns4||(bw.macie50)?true:false;
+ if (window.attachEvent){fix_bind()}
+ else if(noFix){
+ if(bw.ns6){document.getElementById(eID).style.position="absolute";}
+ if(bw.macie50){document.getElementById(eID).style.position="absolute";document.getElementById(eID).style.backgroundColor="#ccffcc";}
+ if(bw.ns6&&YOffset==0){YOffset=-15}
+ mySticky=new makeLayerObj(eID);
+ layerSlide(eID)}
+ else{
+ mySticky=new makeLayerObj(eID);
+ mySticky.css.position="fixed";}
+
+ if(!mySticky){mySticky=new makeLayerObj(eID);}
+ //mySticky.css.visibility="visible";
+ }
+
+
+// -------------------------
+// emulate css 'position: fixed' in IE5+ Win
+// code by aclover@1value.com
+ fix_elements = new Array();
+
+ function fix_event(){
+ var i;
+ for (i=0; i < fix_elements.length; i++){
+ fix_elements[i].style.left = parseInt(fix_elements[i].fix_left)+document.getElementsByTagName('html')[0].scrollLeft+document.getElementsByTagName('body')[0].scrollLeft+'px';
+ fix_elements[i].style.top = parseInt(fix_elements[i].fix_top)+document.getElementsByTagName('html')[0].scrollTop+document.getElementsByTagName('body')[0].scrollTop+'px';
+ }
+ }
+
+ function fix_bind(){
+ var i;
+ for (i=0; i < document.all.length; i++){
+ if (document.all[i].currentStyle.position=='fixed'){
+ document.all[i].fix_left = document.all[i].currentStyle.left;
+ document.all[i].fix_top = document.all[i].currentStyle.top;
+ document.all[i].style.position = 'absolute';
+ fix_elements[fix_elements.length] = document.all[i];
+ window.attachEvent('onscroll', fix_event);
+ window.attachEvent('onresize', fix_event);
+ }
+ }
+ }
+// -------------------------
+
+
+// -------------------------
+// DHTML menu sliding. Requires checkBrowser()
+// Based on source at http://www.simplythebest.net/
+ function layerSlide(layerID) {
+ if(bw.dhtml){
+ if(!mySticky){mySticky=new makeLayerObj(layerID);}
+ if (bw.ns) {winY = window.pageYOffset;}
+ else if (bw.ie) {winY = document.body.scrollTop;}
+ if (bw.ie||bw.ns) {
+ if (winY!=lastY&&winY>YOffset-staticYOffset){smooth = .3 * (winY - lastY - YOffset + staticYOffset);}
+ else if (YOffset-staticYOffset+lastY>YOffset-staticYOffset){smooth = .3 * (winY - lastY - (YOffset-(YOffset-winY)));}
+ else{smooth=0}
+ if(smooth > 0) {smooth = Math.ceil(smooth);}
+ else{smooth = Math.floor(smooth);}
+ if (bw.ie){mySticky.css.pixelTop+=smooth;}
+ else if (bw.ns){mySticky.css.top=parseInt(mySticky.css.top)+smooth;}
+ lastY = lastY+smooth;
+ top.window.status=new Date()
+ setTimeout('layerSlide("'+layerID+'")', refreshMS)}}}
+// -------------------------
+
+// Netscape 4.x browser resize fix
+ function MM_reloadPage(init) {
+ if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
+ document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; top.onresize=MM_reloadPage; }}
+ else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) {location.reload();}}
+
+// Create browser-independent layer and browser objects
+ function makeLayerObj(eID){
+ if(document.getElementById){this.css=document.getElementById(eID).style}
+ else if(document.layers){this.css=document.layers[eID];}
+ else if(document.all){this.css=document.all[eID].style;}
+ return this
+ }
+
+ function checkBrowser(){
+ this.ver=navigator.appVersion;
+ this.name=navigator.appName;
+ this.mac=(navigator.platform.toLowerCase().indexOf('mac')>-1)?true:false;
+ this.opera=(navigator.userAgent.toLowerCase().indexOf('opera')>-1)?true:false;
+ this.dom=document.getElementById?true:false;
+ this.ns=(this.name=='Netscape');
+ this.ie4=(document.all && !this.dom)?true:false;
+ this.ie=(this.name =='Microsoft Internet Explorer'&&!this.opera)?true:false;
+ this.ie5=(this.ie && (navigator.userAgent.indexOf("MSIE 5")!=-1))?true:false;
+ this.macie50=(this.mac&&this.ie5&&(navigator.userAgent.indexOf("MSIE 5.0")!=-1))?true:false
+ this.ns4=(this.ns && parseInt(this.ver) == 4)?true:false;
+ this.ns6=((this.name=="Netscape")&&(parseInt(this.ver)==5))?true:false
+ this.standards=document.getElementById?true:false;
+ this.dhtml=this.standards||this.ie4||this.ns4;
+ }
+
+ function showMe(eID){
+ myFloater=new makeLayerObj(eID)
+ myFloater.css.visibility="visible";
+ }
+
+ function hideMe(eID){
+ myFloater=new makeLayerObj(eID)
+ myFloater.css.visibility="hidden";
+ } \ No newline at end of file
diff --git a/skins/common/upload.js b/skins/common/upload.js
new file mode 100644
index 000000000000..160fbf27a289
--- /dev/null
+++ b/skins/common/upload.js
@@ -0,0 +1,23 @@
+function licenseSelectorCheck() {
+ var selector = document.getElementById("wpLicense");
+ if (selector.selectedIndex > 0 &&
+ selector.options[selector.selectedIndex].value == "" ) {
+ // Browser is broken, doesn't respect disabled attribute on <option>
+ selector.selectedIndex = 0;
+ }
+}
+
+function licenseSelectorFixup() {
+ // for MSIE/Mac; non-breaking spaces cause the <option> not to render
+ // but, for some reason, setting the text to itself works
+ var selector = document.getElementById("wpLicense");
+ var ua = navigator.userAgent;
+ var isMacIe = (ua.indexOf("MSIE") != -1) && (ua.indexOf("Mac") != -1);
+ if (isMacIe) {
+ for (var i = 0; i < selector.options.length; i++) {
+ selector.options[i].text = selector.options[i].text;
+ }
+ }
+}
+
+addOnloadHook(licenseSelectorFixup);
diff --git a/skins/common/wikibits.js b/skins/common/wikibits.js
new file mode 100644
index 000000000000..1e8e10ae7390
--- /dev/null
+++ b/skins/common/wikibits.js
@@ -0,0 +1,908 @@
+// MediaWiki JavaScript support functions
+
+var clientPC = navigator.userAgent.toLowerCase(); // Get client info
+var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
+ && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
+var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
+var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
+// For accesskeys
+var is_ff2_win = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('windows')!=-1;
+var is_ff2_x11 = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('x11')!=-1;
+if (clientPC.indexOf('opera') != -1) {
+ var is_opera = true;
+ var is_opera_preseven = (window.opera && !document.childNodes);
+ var is_opera_seven = (window.opera && document.childNodes);
+}
+
+// Global external objects used by this script.
+/*extern ta, stylepath, skin */
+
+// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
+var doneOnloadHook;
+
+if (!window.onloadFuncts) {
+ var onloadFuncts = [];
+}
+
+function addOnloadHook(hookFunct) {
+ // Allows add-on scripts to add onload functions
+ onloadFuncts[onloadFuncts.length] = hookFunct;
+}
+
+function hookEvent(hookName, hookFunct) {
+ if (window.addEventListener) {
+ window.addEventListener(hookName, hookFunct, false);
+ } else if (window.attachEvent) {
+ window.attachEvent("on" + hookName, hookFunct);
+ }
+}
+
+// document.write special stylesheet links
+if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
+ if (is_opera_preseven) {
+ document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
+ } else if (is_opera_seven) {
+ document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
+ } else if (is_khtml) {
+ document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
+ }
+}
+
+if (wgBreakFrames) {
+ // Un-trap us from framesets
+ if (window.top != window) {
+ window.top.location = window.location;
+ }
+}
+
+// for enhanced RecentChanges
+function toggleVisibility(_levelId, _otherId, _linkId) {
+ var thisLevel = document.getElementById(_levelId);
+ var otherLevel = document.getElementById(_otherId);
+ var linkLevel = document.getElementById(_linkId);
+ if (thisLevel.style.display == 'none') {
+ thisLevel.style.display = 'block';
+ otherLevel.style.display = 'none';
+ linkLevel.style.display = 'inline';
+ } else {
+ thisLevel.style.display = 'none';
+ otherLevel.style.display = 'inline';
+ linkLevel.style.display = 'none';
+ }
+}
+
+function historyRadios(parent) {
+ var inputs = parent.getElementsByTagName('input');
+ var radios = [];
+ for (var i = 0; i < inputs.length; i++) {
+ if (inputs[i].name == "diff" || inputs[i].name == "oldid") {
+ radios[radios.length] = inputs[i];
+ }
+ }
+ return radios;
+}
+
+// check selection and tweak visibility/class onclick
+function diffcheck() {
+ var dli = false; // the li where the diff radio is checked
+ var oli = false; // the li where the oldid radio is checked
+ var hf = document.getElementById('pagehistory');
+ if (!hf) {
+ return true;
+ }
+ var lis = hf.getElementsByTagName('li');
+ for (var i=0;i<lis.length;i++) {
+ var inputs = historyRadios(lis[i]);
+ if (inputs[1] && inputs[0]) {
+ if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
+ if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) {
+ return false;
+ }
+ if (oli) { // it's the second checked radio
+ if (inputs[1].checked) {
+ oli.className = "selected";
+ return false;
+ }
+ } else if (inputs[0].checked) {
+ return false;
+ }
+ if (inputs[0].checked) {
+ dli = lis[i];
+ }
+ if (!oli) {
+ inputs[0].style.visibility = 'hidden';
+ }
+ if (dli) {
+ inputs[1].style.visibility = 'hidden';
+ }
+ lis[i].className = "selected";
+ oli = lis[i];
+ } else { // no radio is checked in this row
+ if (!oli) {
+ inputs[0].style.visibility = 'hidden';
+ } else {
+ inputs[0].style.visibility = 'visible';
+ }
+ if (dli) {
+ inputs[1].style.visibility = 'hidden';
+ } else {
+ inputs[1].style.visibility = 'visible';
+ }
+ lis[i].className = "";
+ }
+ }
+ }
+ return true;
+}
+
+// page history stuff
+// attach event handlers to the input elements on history page
+function histrowinit() {
+ var hf = document.getElementById('pagehistory');
+ if (!hf) {
+ return;
+ }
+ var lis = hf.getElementsByTagName('li');
+ for (var i = 0; i < lis.length; i++) {
+ var inputs = historyRadios(lis[i]);
+ if (inputs[0] && inputs[1]) {
+ inputs[0].onclick = diffcheck;
+ inputs[1].onclick = diffcheck;
+ }
+ }
+ diffcheck();
+}
+
+// generate toc from prefs form, fold sections
+// XXX: needs testing on IE/Mac and safari
+// more comments to follow
+function tabbedprefs() {
+ var prefform = document.getElementById('preferences');
+ if (!prefform || !document.createElement) {
+ return;
+ }
+ if (prefform.nodeName.toLowerCase() == 'a') {
+ return; // Occasional IE problem
+ }
+ prefform.className = prefform.className + 'jsprefs';
+ var sections = [];
+ var children = prefform.childNodes;
+ var seci = 0;
+ for (var i = 0; i < children.length; i++) {
+ if (children[i].nodeName.toLowerCase() == 'fieldset') {
+ children[i].id = 'prefsection-' + seci;
+ children[i].className = 'prefsection';
+ if (is_opera || is_khtml) {
+ children[i].className = 'prefsection operaprefsection';
+ }
+ var legends = children[i].getElementsByTagName('legend');
+ sections[seci] = {};
+ legends[0].className = 'mainLegend';
+ if (legends[0] && legends[0].firstChild.nodeValue) {
+ sections[seci].text = legends[0].firstChild.nodeValue;
+ } else {
+ sections[seci].text = '# ' + seci;
+ }
+ sections[seci].secid = children[i].id;
+ seci++;
+ if (sections.length != 1) {
+ children[i].style.display = 'none';
+ } else {
+ var selectedid = children[i].id;
+ }
+ }
+ }
+ var toc = document.createElement('ul');
+ toc.id = 'preftoc';
+ toc.selectedid = selectedid;
+ for (i = 0; i < sections.length; i++) {
+ var li = document.createElement('li');
+ if (i === 0) {
+ li.className = 'selected';
+ }
+ var a = document.createElement('a');
+ a.href = '#' + sections[i].secid;
+ a.onmousedown = a.onclick = uncoversection;
+ a.appendChild(document.createTextNode(sections[i].text));
+ a.secid = sections[i].secid;
+ li.appendChild(a);
+ toc.appendChild(li);
+ }
+ prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
+ document.getElementById('prefsubmit').id = 'prefcontrol';
+}
+
+function uncoversection() {
+ var oldsecid = this.parentNode.parentNode.selectedid;
+ var newsec = document.getElementById(this.secid);
+ if (oldsecid != this.secid) {
+ var ul = document.getElementById('preftoc');
+ document.getElementById(oldsecid).style.display = 'none';
+ newsec.style.display = 'block';
+ ul.selectedid = this.secid;
+ var lis = ul.getElementsByTagName('li');
+ for (var i = 0; i< lis.length; i++) {
+ lis[i].className = '';
+ }
+ this.parentNode.className = 'selected';
+ }
+ return false;
+}
+
+// Timezone stuff
+// tz in format [+-]HHMM
+function checkTimezone(tz, msg) {
+ var localclock = new Date();
+ // returns negative offset from GMT in minutes
+ var tzRaw = localclock.getTimezoneOffset();
+ var tzHour = Math.floor( Math.abs(tzRaw) / 60);
+ var tzMin = Math.abs(tzRaw) % 60;
+ var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
+ if (tz != tzString) {
+ var junk = msg.split('$1');
+ document.write(junk[0] + "UTC" + tzString + junk[1]);
+ }
+}
+
+function unhidetzbutton() {
+ var tzb = document.getElementById('guesstimezonebutton');
+ if (tzb) {
+ tzb.style.display = 'inline';
+ }
+}
+
+// in [-]HH:MM format...
+// won't yet work with non-even tzs
+function fetchTimezone() {
+ // FIXME: work around Safari bug
+ var localclock = new Date();
+ // returns negative offset from GMT in minutes
+ var tzRaw = localclock.getTimezoneOffset();
+ var tzHour = Math.floor( Math.abs(tzRaw) / 60);
+ var tzMin = Math.abs(tzRaw) % 60;
+ var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
+ ":" + ((tzMin < 10) ? "0" : "") + tzMin;
+ return tzString;
+}
+
+function guessTimezone(box) {
+ document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
+}
+
+function showTocToggle() {
+ if (document.createTextNode) {
+ // Uses DOM calls to avoid document.write + XHTML issues
+
+ var linkHolder = document.getElementById('toctitle');
+ if (!linkHolder) {
+ return;
+ }
+
+ var outerSpan = document.createElement('span');
+ outerSpan.className = 'toctoggle';
+
+ var toggleLink = document.createElement('a');
+ toggleLink.id = 'togglelink';
+ toggleLink.className = 'internal';
+ toggleLink.href = 'javascript:toggleToc()';
+ toggleLink.appendChild(document.createTextNode(tocHideText));
+
+ outerSpan.appendChild(document.createTextNode('['));
+ outerSpan.appendChild(toggleLink);
+ outerSpan.appendChild(document.createTextNode(']'));
+
+ linkHolder.appendChild(document.createTextNode(' '));
+ linkHolder.appendChild(outerSpan);
+
+ var cookiePos = document.cookie.indexOf("hidetoc=");
+ if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) {
+ toggleToc();
+ }
+ }
+}
+
+function changeText(el, newText) {
+ // Safari work around
+ if (el.innerText) {
+ el.innerText = newText;
+ } else if (el.firstChild && el.firstChild.nodeValue) {
+ el.firstChild.nodeValue = newText;
+ }
+}
+
+function toggleToc() {
+ var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
+ var toggleLink = document.getElementById('togglelink');
+
+ if (toc && toggleLink && toc.style.display == 'none') {
+ changeText(toggleLink, tocHideText);
+ toc.style.display = 'block';
+ document.cookie = "hidetoc=0";
+ } else {
+ changeText(toggleLink, tocShowText);
+ toc.style.display = 'none';
+ document.cookie = "hidetoc=1";
+ }
+}
+
+var mwEditButtons = [];
+var mwCustomEditButtons = []; // eg to add in MediaWiki:Common.js
+
+// this function generates the actual toolbar buttons with localized text
+// we use it to avoid creating the toolbar where javascript is not enabled
+function addButton(imageFile, speedTip, tagOpen, tagClose, sampleText) {
+ // Don't generate buttons for browsers which don't fully
+ // support it.
+ mwEditButtons[mwEditButtons.length] =
+ {"imageFile": imageFile,
+ "speedTip": speedTip,
+ "tagOpen": tagOpen,
+ "tagClose": tagClose,
+ "sampleText": sampleText};
+}
+
+// this function generates the actual toolbar buttons with localized text
+// we use it to avoid creating the toolbar where javascript is not enabled
+function mwInsertEditButton(parent, item) {
+ var image = document.createElement("img");
+ image.width = 23;
+ image.height = 22;
+ image.src = item.imageFile;
+ image.border = 0;
+ image.alt = item.speedTip;
+ image.title = item.speedTip;
+ image.style.cursor = "pointer";
+ image.onclick = function() {
+ insertTags(item.tagOpen, item.tagClose, item.sampleText);
+ return false;
+ };
+
+ parent.appendChild(image);
+ return true;
+}
+
+function mwSetupToolbar() {
+ var toolbar = document.getElementById('toolbar');
+ if (!toolbar) { return false; }
+
+ var textbox = document.getElementById('wpTextbox1');
+ if (!textbox) { return false; }
+
+ // Don't generate buttons for browsers which don't fully
+ // support it.
+ if (!document.selection && textbox.selectionStart === null) {
+ return false;
+ }
+
+ for (var i in mwEditButtons) {
+ mwInsertEditButton(toolbar, mwEditButtons[i]);
+ }
+ for (i in mwCustomEditButtons) {
+ mwInsertEditButton(toolbar, mwCustomEditButtons[i]);
+ }
+ return true;
+}
+
+function escapeQuotes(text) {
+ var re = new RegExp("'","g");
+ text = text.replace(re,"\\'");
+ re = new RegExp("\\n","g");
+ text = text.replace(re,"\\n");
+ return escapeQuotesHTML(text);
+}
+
+function escapeQuotesHTML(text) {
+ var re = new RegExp('&',"g");
+ text = text.replace(re,"&amp;");
+ re = new RegExp('"',"g");
+ text = text.replace(re,"&quot;");
+ re = new RegExp('<',"g");
+ text = text.replace(re,"&lt;");
+ re = new RegExp('>',"g");
+ text = text.replace(re,"&gt;");
+ return text;
+}
+
+// apply tagOpen/tagClose to selection in textarea,
+// use sampleText instead of selection if there is none
+// copied and adapted from phpBB
+function insertTags(tagOpen, tagClose, sampleText) {
+ var txtarea;
+ if (document.editform) {
+ txtarea = document.editform.wpTextbox1;
+ } else {
+ // some alternate form? take the first one we can find
+ var areas = document.getElementsByTagName('textarea');
+ txtarea = areas[0];
+ }
+
+ // IE
+ if (document.selection && !is_gecko) {
+ var theSelection = document.selection.createRange().text;
+ if (!theSelection) {
+ theSelection=sampleText;
+ }
+ txtarea.focus();
+ if (theSelection.charAt(theSelection.length - 1) == " ") { // exclude ending space char, if any
+ theSelection = theSelection.substring(0, theSelection.length - 1);
+ document.selection.createRange().text = tagOpen + theSelection + tagClose + " ";
+ } else {
+ document.selection.createRange().text = tagOpen + theSelection + tagClose;
+ }
+
+ // Mozilla
+ } else if(txtarea.selectionStart || txtarea.selectionStart == '0') {
+ var replaced = false;
+ var startPos = txtarea.selectionStart;
+ var endPos = txtarea.selectionEnd;
+ if (endPos-startPos) {
+ replaced = true;
+ }
+ var scrollTop = txtarea.scrollTop;
+ var myText = (txtarea.value).substring(startPos, endPos);
+ if (!myText) {
+ myText=sampleText;
+ }
+ var subst;
+ if (myText.charAt(myText.length - 1) == " ") { // exclude ending space char, if any
+ subst = tagOpen + myText.substring(0, (myText.length - 1)) + tagClose + " ";
+ } else {
+ subst = tagOpen + myText + tagClose;
+ }
+ txtarea.value = txtarea.value.substring(0, startPos) + subst +
+ txtarea.value.substring(endPos, txtarea.value.length);
+ txtarea.focus();
+ //set new selection
+ if (replaced) {
+ var cPos = startPos+(tagOpen.length+myText.length+tagClose.length);
+ txtarea.selectionStart = cPos;
+ txtarea.selectionEnd = cPos;
+ } else {
+ txtarea.selectionStart = startPos+tagOpen.length;
+ txtarea.selectionEnd = startPos+tagOpen.length+myText.length;
+ }
+ txtarea.scrollTop = scrollTop;
+
+ // All other browsers get no toolbar.
+ // There was previously support for a crippled "help"
+ // bar, but that caused more problems than it solved.
+ }
+ // reposition cursor if possible
+ if (txtarea.createTextRange) {
+ txtarea.caretPos = document.selection.createRange().duplicate();
+ }
+}
+
+/**
+ * Set up accesskeys/tooltips. If doId is specified, only set up for that id.
+ *
+ * @param mixed doId string or null
+ */
+function akeytt( doId ) {
+ if (typeof ta == "undefined" || !ta) {
+ return;
+ }
+
+ var pref;
+ if (is_opera) {
+ pref = 'shift-esc-';
+ } else if (is_safari || navigator.userAgent.toLowerCase().indexOf('mac') + 1
+ || navigator.userAgent.toLowerCase().indexOf('konqueror') + 1 ) {
+ pref = 'control-';
+ } else if (is_ff2_win || is_ff2_x11) {
+ pref = 'alt-shift-';
+ } else {
+ pref = 'alt-';
+ }
+
+ if ( doId ) {
+ ta = [ta[doId]];
+ }
+
+ for (var id in ta) {
+ var n = document.getElementById(id);
+ if (n) {
+ var a = null;
+ var ak = '';
+ // Are we putting accesskey in it
+ if (ta[id][0].length > 0) {
+ // Is this object a object? If not assume it's the next child.
+
+ if (n.nodeName.toLowerCase() == "a") {
+ a = n;
+ } else {
+ a = n.childNodes[0];
+ }
+ // Don't add an accesskey for the watch tab if the watch
+ // checkbox is also available.
+ if (a && ((id != 'ca-watch' && id != 'ca-unwatch') ||
+ !(window.location.search.match(/[\?&](action=edit|action=submit)/i)))) {
+ a.accessKey = ta[id][0];
+ ak = ' ['+pref+ta[id][0]+']';
+ }
+ } else {
+ // We don't care what type the object is when assigning tooltip
+ a = n;
+ ak = '';
+ }
+
+ if (a) {
+ a.title = ta[id][1]+ak;
+ }
+ }
+ }
+}
+
+function setupRightClickEdit() {
+ if (document.getElementsByTagName) {
+ var spans = document.getElementsByTagName('span');
+ for (var i = 0; i < spans.length; i++) {
+ var el = spans[i];
+ if(el.className == 'editsection') {
+ addRightClickEditHandler(el);
+ }
+ }
+ }
+}
+
+function addRightClickEditHandler(el) {
+ for (var i = 0; i < el.childNodes.length; i++) {
+ var link = el.childNodes[i];
+ if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
+ var editHref = link.getAttribute('href');
+ // find the enclosing (parent) header
+ var prev = el.parentNode;
+ if (prev && prev.nodeType == 1 &&
+ prev.nodeName.match(/^[Hh][1-6]$/)) {
+ prev.oncontextmenu = function(e) {
+ if (!e) { e = window.event; }
+ // e is now the event in all browsers
+ var targ;
+ if (e.target) { targ = e.target; }
+ else if (e.srcElement) { targ = e.srcElement; }
+ if (targ.nodeType == 3) { // defeat Safari bug
+ targ = targ.parentNode;
+ }
+ // targ is now the target element
+
+ // We don't want to deprive the noble reader of a context menu
+ // for the section edit link, do we? (Might want to extend this
+ // to all <a>'s?)
+ if (targ.nodeName.toLowerCase() != 'a'
+ || targ.parentNode.className != 'editsection') {
+ document.location = editHref;
+ return false;
+ }
+ return true;
+ };
+ }
+ }
+ }
+}
+
+function setupCheckboxShiftClick() {
+ if (document.getElementsByTagName) {
+ var uls = document.getElementsByTagName('ul');
+ var len = uls.length;
+ for (var i = 0; i < len; ++i) {
+ addCheckboxClickHandlers(uls[i]);
+ }
+ }
+}
+
+function addCheckboxClickHandlers(ul, start, finish) {
+ if (ul.checkboxHandlersTimer) {
+ clearInterval(ul.checkboxHandlersTimer);
+ }
+ if ( !ul.childNodes ) {
+ return;
+ }
+ var len = ul.childNodes.length;
+ if (len < 2) {
+ return;
+ }
+ start = start || 0;
+ finish = finish || start + 250;
+ if ( finish > len ) { finish = len; }
+ ul.checkboxes = ul.checkboxes || [];
+ ul.lastCheckbox = ul.lastCheckbox || null;
+ for (var i = start; i<finish; ++i) {
+ var child = ul.childNodes[i];
+ if ( child && child.childNodes && child.childNodes[0] ) {
+ var cb = child.childNodes[0];
+ if ( !cb.nodeName || cb.nodeName.toLowerCase() != 'input' ||
+ !cb.type || cb.type.toLowerCase() != 'checkbox' ) {
+ return;
+ }
+ cb.index = ul.checkboxes.push(cb) - 1;
+ cb.container = ul;
+ cb.onmouseup = checkboxMouseupHandler;
+ }
+ }
+ if (finish < len) {
+ var f=function(){ addCheckboxClickHandlers(ul, finish, finish+250); };
+ ul.checkboxHandlersTimer=setInterval(f, 200);
+ }
+}
+
+function checkboxMouseupHandler(e) {
+ if (typeof e == 'undefined') {
+ e = window.event;
+ }
+ if ( !e.shiftKey || this.container.lastCheckbox === null ) {
+ this.container.lastCheckbox = this.index;
+ return true;
+ }
+ var endState = !this.checked;
+ if ( is_opera ) { // opera has already toggled the checkbox by this point
+ endState = !endState;
+ }
+ var start, finish;
+ if ( this.index < this.container.lastCheckbox ) {
+ start = this.index + 1;
+ finish = this.container.lastCheckbox;
+ } else {
+ start = this.container.lastCheckbox;
+ finish = this.index - 1;
+ }
+ for (var i = start; i <= finish; ++i ) {
+ this.container.checkboxes[i].checked = endState;
+ }
+ this.container.lastCheckbox = this.index;
+ return true;
+}
+
+function toggle_element_activation(ida,idb) {
+ if (!document.getElementById) {
+ return;
+ }
+ document.getElementById(ida).disabled=true;
+ document.getElementById(idb).disabled=false;
+}
+
+function toggle_element_check(ida,idb) {
+ if (!document.getElementById) {
+ return;
+ }
+ document.getElementById(ida).checked=true;
+ document.getElementById(idb).checked=false;
+}
+
+function fillDestFilename(id) {
+ if (!document.getElementById) {
+ return;
+ }
+ var path = document.getElementById(id).value;
+ // Find trailing part
+ var slash = path.lastIndexOf('/');
+ var backslash = path.lastIndexOf('\\');
+ var fname;
+ if (slash == -1 && backslash == -1) {
+ fname = path;
+ } else if (slash > backslash) {
+ fname = path.substring(slash+1, 10000);
+ } else {
+ fname = path.substring(backslash+1, 10000);
+ }
+
+ // Capitalise first letter and replace spaces by underscores
+ fname = fname.charAt(0).toUpperCase().concat(fname.substring(1,10000)).replace(/ /g, '_');
+
+ // Output result
+ var destFile = document.getElementById('wpDestFile');
+ if (destFile) {
+ destFile.value = fname;
+ }
+}
+
+
+function considerChangingExpiryFocus() {
+ if (!document.getElementById) {
+ return;
+ }
+ var drop = document.getElementById('wpBlockExpiry');
+ if (!drop) {
+ return;
+ }
+ var field = document.getElementById('wpBlockOther');
+ if (!field) {
+ return;
+ }
+ var opt = drop.value;
+ if (opt == 'other') {
+ field.style.display = '';
+ } else {
+ field.style.display = 'none';
+ }
+}
+
+function scrollEditBox() {
+ var editBoxEl = document.getElementById("wpTextbox1");
+ var scrollTopEl = document.getElementById("wpScrolltop");
+ var editFormEl = document.getElementById("editform");
+
+ if (editBoxEl && scrollTopEl) {
+ if (scrollTopEl.value) { editBoxEl.scrollTop = scrollTopEl.value; }
+ editFormEl.onsubmit = function() {
+ document.getElementById("wpScrolltop").value = document.getElementById("wpTextbox1").scrollTop;
+ };
+ }
+}
+
+hookEvent("load", scrollEditBox);
+
+var allmessages_nodelist = false;
+var allmessages_modified = false;
+var allmessages_timeout = false;
+var allmessages_running = false;
+
+function allmessagesmodified() {
+ allmessages_modified = !allmessages_modified;
+ allmessagesfilter();
+}
+
+function allmessagesfilter() {
+ if ( allmessages_timeout )
+ window.clearTimeout( allmessages_timeout );
+
+ if ( !allmessages_running )
+ allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
+}
+
+function allmessagesfilter_do() {
+ if ( !allmessages_nodelist )
+ return;
+
+ var text = document.getElementById('allmessagesinput').value;
+ var nodef = allmessages_modified;
+
+ allmessages_running = true;
+
+ for ( var name in allmessages_nodelist ) {
+ var nodes = allmessages_nodelist[name];
+ var display = ( name.indexOf( text ) == -1 ? 'none' : '' );
+
+ for ( var i = 0; i < nodes.length; i++)
+ nodes[i].style.display =
+ ( nodes[i].className == "def" && nodef
+ ? 'none' : display );
+ }
+
+ if ( text != document.getElementById('allmessagesinput').value ||
+ nodef != allmessages_modified )
+ allmessagesfilter_do(); // repeat
+
+ allmessages_running = false;
+}
+
+function allmessagesfilter_init() {
+ if ( allmessages_nodelist )
+ return;
+
+ var nodelist = new Array();
+ var templist = new Array();
+
+ var table = document.getElementById('allmessagestable');
+ if ( !table ) return;
+
+ var rows = document.getElementsByTagName('tr');
+ for ( var i = 0; i < rows.length; i++ ) {
+ var id = rows[i].getAttribute('id')
+ if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
+ templist[ id ] = rows[i];
+ }
+
+ var spans = table.getElementsByTagName('span');
+ for ( var i = 0; i < spans.length; i++ ) {
+ var id = spans[i].getAttribute('id')
+ if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
+ if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;
+
+ var nodes = new Array();
+ var row1 = templist[ id.replace('i', 'r1') ];
+ var row2 = templist[ id.replace('i', 'r2') ];
+
+ if ( row1 ) nodes[nodes.length] = row1;
+ if ( row2 ) nodes[nodes.length] = row2;
+ nodelist[ spans[i].firstChild.nodeValue ] = nodes;
+ }
+
+ var k = document.getElementById('allmessagesfilter');
+ if (k) { k.style.display = ''; }
+
+ allmessages_nodelist = nodelist;
+}
+
+hookEvent( "load", allmessagesfilter_init );
+
+/*
+ Written by Jonathan Snook, http://www.snook.ca/jonathan
+ Add-ons by Robert Nyman, http://www.robertnyman.com
+ Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
+ From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
+*/
+function getElementsByClassName(oElm, strTagName, oClassNames){
+ var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
+ var arrReturnElements = new Array();
+ var arrRegExpClassNames = new Array();
+ if(typeof oClassNames == "object"){
+ for(var i=0; i<oClassNames.length; i++){
+ arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"));
+ }
+ }
+ else{
+ arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"));
+ }
+ var oElement;
+ var bMatchesAll;
+ for(var j=0; j<arrElements.length; j++){
+ oElement = arrElements[j];
+ bMatchesAll = true;
+ for(var k=0; k<arrRegExpClassNames.length; k++){
+ if(!arrRegExpClassNames[k].test(oElement.className)){
+ bMatchesAll = false;
+ break;
+ }
+ }
+ if(bMatchesAll){
+ arrReturnElements.push(oElement);
+ }
+ }
+ return (arrReturnElements)
+}
+
+function sortableTables() {
+ if (getElementsByClassName(document, "table", "sortable").length != 0) {
+ document.write('<script type="text/javascript" src="'+stylepath+'/common/sorttable.js?1"></script>');
+ }
+}
+
+function redirectToFragment(fragment) {
+ var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
+ if (match) {
+ var webKitVersion = parseInt(match[1]);
+ if (webKitVersion < 420) {
+ // Released Safari w/ WebKit 418.9.1 messes up horribly
+ // Nightlies of 420+ are ok
+ return;
+ }
+ }
+ if (is_gecko) {
+ // Mozilla needs to wait until after load, otherwise the window doesn't scroll
+ addOnloadHook(function () {
+ if (window.location.hash == "")
+ window.location.hash = fragment;
+ });
+ } else {
+ if (window.location.hash == "")
+ window.location.hash = fragment;
+ }
+}
+
+function runOnloadHook() {
+ // don't run anything below this for non-dom browsers
+ if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) {
+ return;
+ }
+
+ histrowinit();
+ unhidetzbutton();
+ tabbedprefs();
+ akeytt( null );
+ scrollEditBox();
+ setupCheckboxShiftClick();
+ sortableTables();
+
+ // Run any added-on functions
+ for (var i = 0; i < onloadFuncts.length; i++) {
+ onloadFuncts[i]();
+ }
+
+ doneOnloadHook = true;
+}
+
+//note: all skins should call runOnloadHook() at the end of html output,
+// so the below should be redundant. It's there just in case.
+hookEvent("load", runOnloadHook);
+
+hookEvent("load", mwSetupToolbar);
diff --git a/skins/common/wikiprintable.css b/skins/common/wikiprintable.css
new file mode 100644
index 000000000000..58e132d6cf93
--- /dev/null
+++ b/skins/common/wikiprintable.css
@@ -0,0 +1,46 @@
+/* MediaWiki print stylesheet */
+
+body {
+ color: #000000; background: #ffffff;
+}
+
+
+/* MSIE/Win doesn't understand 'inherit' */
+a, a.external, a.new, a.stub {
+ color: black ! important;
+ text-decoration: none ! important;
+}
+#article {
+ margin: 0 ! important;
+}
+
+/* Continue ... */
+a, a.external, a.new, a.stub {
+ color: inherit ! important;
+ text-decoration: inherit ! important;
+}
+
+/* Hide ugly UI stuff */
+#quickbar, #topbar, #footer, #siteNotice,
+.editsection, .toctoggle {
+ display: none;
+}
+
+/* */
+#article {
+ position: relative;
+ margin: inherit ! important;
+}
+
+.printfooter {
+ border-top: solid 1px black;
+ display: block ! important;
+}
+
+/* Old stuff, fixme:
+a.CBlink { color: #0000AA; text-decoration: none; font-size: 12pt; }
+a.interwiki, a.external { color: #3333BB; text-decoration: none; }
+h1.pagetitle { padding-bottom: 0; margin-bottom: 0; }
+i.link, u.link { color: #000066; }
+p.subtitle { padding-top: 0; margin-top: 0; }
+*/
diff --git a/skins/common/wikistandard.css b/skins/common/wikistandard.css
new file mode 100644
index 000000000000..532e4fdca845
--- /dev/null
+++ b/skins/common/wikistandard.css
@@ -0,0 +1,48 @@
+#article { padding: 4px; }
+#content { margin: 0; padding: 0; }
+#footer { padding: 4px;font-size:95%;clear: both; }
+#pagestats { font-size: 9pt; }
+#powersearch {
+ background: #DDEEFF; border-style: solid; border-width: 1px; padding: 2px;
+}
+#quickbar { width: 140px; padding: 4px; visibility: visible; z-index:99;font-size:95%;}
+#topbar { padding: 4px;font-size:95%; }
+
+
+/* Table of contents */
+.toctoggle, .editsection { font-size: smaller; }
+
+/* ... */
+#toolbar { padding:0px; }
+#infobox { background:#eeeeff;color:black;}
+#editform { margin-top:1px; }
+a.interwiki, a.external { color: #3366BB; }
+a.printable { text-decoration: underline; }
+a.stub { color:#772233; text-decoration:none; }
+a:visited { color: #5A3696; }
+body { margin: 0px; padding: 4px; color: black; }
+form.inline { display: inline; }
+textarea { overflow: auto; }
+
+
+h1.pagetitle { padding-top: 0; margin-top: 0; padding-bottom: 0; margin-bottom: 0;
+font-size:150%; }
+h1.pagetitle .editsection { font-size: 66.7%; }
+h2 { font-size: 120%; }
+h2 .editsection { font-size: 83.3%; }
+h2, h3, h4, h5, h6 { margin-bottom: 0;}
+h3 { font-size: 106.25%; }
+h3 .editsection { font-size: 94.1%; }
+h4 { font-size: 103.125%; }
+h4 .editsection { font-size: 97.0%; }
+h5 { font-size: 100%; }
+h5 .editsection { font-size: 100%; }
+h6 { font-size: 95%; }
+h6 .editsection { font-size: 105.3%; }
+hr.sep { color:gray;height:1px;background-color:gray;}
+p.subpages { font-size:small;}
+p.subtitle { padding-top: 0; margin-top: 0;}
+p.catlinks { font-size:small; margin-top:0; text-align:right;}
+td { empty-cells:show; }
+td.bottom { border-top: 1px solid gray; }
+td.top { border-bottom: 1px solid gray; }
diff --git a/skins/disabled/HTMLDump.php b/skins/disabled/HTMLDump.php
new file mode 100644
index 000000000000..5f739a379d6f
--- /dev/null
+++ b/skins/disabled/HTMLDump.php
@@ -0,0 +1,234 @@
+<?php
+
+/**
+ * Default skin for HTML dumps, based on MonoBook.php
+ */
+
+if( !defined( 'MEDIAWIKI' ) )
+ die( -1 );
+
+/** */
+require_once( 'includes/SkinTemplate.php' );
+
+/**
+ * Inherit main code from SkinTemplate, set the CSS and template filter.
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class SkinHTMLDump extends SkinTemplate {
+ /** Using monobook. */
+ function initPage( &$out ) {
+ SkinTemplate::initPage( $out );
+ $this->template = 'HTMLDumpTemplate';
+ }
+
+ function buildSidebar() {
+ $sections = parent::buildSidebar();
+ $badMessages = array( 'recentchanges-url', 'randompage-url' );
+ $badUrls = array();
+ foreach ( $badMessages as $msg ) {
+ $badUrls[] = self::makeInternalOrExternalUrl( wfMsgForContent( $msg ) );
+ }
+
+ foreach ( $sections as $heading => $section ) {
+ foreach ( $section as $index => $link ) {
+ if ( in_array( $link['href'], $badUrls ) ) {
+ unset( $sections[$heading][$index] );
+ }
+ }
+ }
+ return $sections;
+ }
+
+ function buildContentActionUrls() {
+ global $wgHTMLDump;
+
+ $content_actions = array();
+ $nskey = $this->getNameSpaceKey();
+ $content_actions[$nskey] = $this->tabAction(
+ $this->mTitle->getSubjectPage(),
+ $nskey,
+ !$this->mTitle->isTalkPage() );
+
+ $content_actions['talk'] = $this->tabAction(
+ $this->mTitle->getTalkPage(),
+ 'talk',
+ $this->mTitle->isTalkPage(),
+ '',
+ true);
+
+ if ( isset( $wgHTMLDump ) ) {
+ $content_actions['current'] = array(
+ 'text' => wfMsg( 'currentrev' ),
+ 'href' => str_replace( '$1', wfUrlencode( $this->mTitle->getPrefixedDBkey() ),
+ $wgHTMLDump->oldArticlePath ),
+ 'class' => false
+ );
+ }
+ return $content_actions;
+ }
+
+ function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ if ( !isset( $nt ) ) {
+ return "<!-- ERROR -->{$prefix}{$text}{$trail}";
+ }
+
+ if ( $nt->getNamespace() == NS_CATEGORY ) {
+ # Determine if the category has any articles in it
+ $dbr =& wfGetDB( DB_SLAVE );
+ $hasMembers = $dbr->selectField( 'categorylinks', '1',
+ array( 'cl_to' => $nt->getDBkey() ), __METHOD__ );
+ if ( $hasMembers ) {
+ return $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+ }
+ }
+
+ if ( $text == '' ) {
+ $text = $nt->getPrefixedText();
+ }
+ return $prefix . $text . $trail;
+ }
+}
+
+/**
+ * @todo document
+ * @package MediaWiki
+ * @subpackage Skins
+ */
+class HTMLDumpTemplate extends QuickTemplate {
+ /**
+ * Template filter callback for MonoBook skin.
+ * Takes an associative array of data set from a SkinTemplate-based
+ * class, and a wrapper for MediaWiki's localization database, and
+ * outputs a formatted page.
+ *
+ * @access private
+ */
+ function execute() {
+ wfSuppressWarnings();
+?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php $this->text('lang') ?>" lang="<?php $this->text('lang') ?>" dir="<?php $this->text('dir') ?>">
+ <head>
+ <meta http-equiv="Content-Type" content="<?php $this->text('mimetype') ?>; charset=<?php $this->text('charset') ?>" />
+ <?php $this->html('headlinks') ?>
+ <title><?php $this->text('pagetitle') ?></title>
+ <style type="text/css">/*<![CDATA[*/ @import "<?php $this->text('stylepath') ?>/htmldump/main.css"; /*]]>*/</style>
+ <link rel="stylesheet" type="text/css" media="print" href="<?php $this->text('stylepath') ?>/common/commonPrint.css" />
+ <!--[if lt IE 5.5000]><style type="text/css">@import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/IE50Fixes.css";</style><![endif]-->
+ <!--[if IE 5.5000]><style type="text/css">@import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/IE55Fixes.css";</style><![endif]-->
+ <!--[if IE 6]><style type="text/css">@import "<?php $this->text('stylepath') ?>/<?php $this->text('stylename') ?>/IE60Fixes.css";</style><![endif]-->
+ <!--[if IE]><script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath') ?>/common/IEFixes.js"></script>
+ <meta http-equiv="imagetoolbar" content="no" /><![endif]-->
+ <script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath' ) ?>/common/wikibits.js"></script>
+ <script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath' ) ?>/htmldump/md5.js"></script>
+ <script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath' ) ?>/htmldump/utf8.js"></script>
+ <script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath' ) ?>/htmldump/lookup.js"></script>
+ <?php if($this->data['jsvarurl' ]) { ?><script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('jsvarurl' ) ?>"></script><?php } ?>
+ <?php if($this->data['pagecss' ]) { ?><style type="text/css"><?php $this->html('pagecss' ) ?></style><?php } ?>
+ <?php if($this->data['usercss' ]) { ?><style type="text/css"><?php $this->html('usercss' ) ?></style><?php } ?>
+ <?php if($this->data['userjs' ]) { ?><script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('userjs' ) ?>"></script><?php } ?>
+ <?php if($this->data['userjsprev']) { ?><script type="<?php $this->text('jsmimetype') ?>"><?php $this->html('userjsprev') ?></script><?php } ?>
+ </head>
+ <body
+ <?php if($this->data['nsclass' ]) { ?>class="<?php $this->text('nsclass') ?>"<?php } ?>>
+ <div id="globalWrapper">
+ <div id="column-content">
+ <div id="content">
+ <a name="top" id="contentTop"></a>
+ <?php if($this->data['sitenotice']) { ?><div id="siteNotice"><?php $this->html('sitenotice') ?></div><?php } ?>
+ <h1 class="firstHeading"><?php $this->data['displaytitle']!=""?$this->html('title'):$this->text('title') ?></h1>
+ <div id="bodyContent">
+ <h3 id="siteSub"><?php $this->msg('tagline') ?></h3>
+ <div id="contentSub"><?php $this->html('subtitle') ?></div>
+ <?php if($this->data['undelete']) { ?><div id="contentSub"><?php $this->html('undelete') ?></div><?php } ?>
+ <?php if($this->data['newtalk'] ) { ?><div class="usermessage"><?php $this->html('newtalk') ?></div><?php } ?>
+ <!-- start content -->
+ <?php $this->html('bodytext') ?>
+ <?php if($this->data['catlinks']) { ?><div id="catlinks"><?php $this->html('catlinks') ?></div><?php } ?>
+ <!-- end content -->
+ <div class="visualClear"></div>
+ </div>
+ </div>
+ </div>
+ <div id="column-one">
+ <div id="p-cactions" class="portlet">
+ <h5>Views</h5>
+ <ul>
+ <?php foreach($this->data['content_actions'] as $key => $action) {
+ ?><li id="ca-<?php echo htmlspecialchars($key) ?>"
+ <?php if($action['class']) { ?>class="<?php echo htmlspecialchars($action['class']) ?>"<?php } ?>
+ ><a href="<?php echo htmlspecialchars($action['href']) ?>"><?php
+ echo htmlspecialchars($action['text']) ?></a></li><?php
+ } ?>
+ </ul>
+ </div>
+ <div class="portlet" id="p-logo">
+ <a style="background-image: url(<?php $this->text('logopath') ?>);"
+ href="<?php echo htmlspecialchars($this->data['nav_urls']['mainpage']['href'])?>"
+ title="<?php $this->msg('mainpage') ?>"></a>
+ </div>
+ <script type="<?php $this->text('jsmimetype') ?>"> if (window.isMSIE55) fixalpha(); </script>
+ <?php foreach ($this->data['sidebar'] as $bar => $cont) { ?>
+ <div class='portlet' id='p-<?php echo htmlspecialchars($bar) ?>'>
+ <h5><?php $out = wfMsg( $bar ); if (wfEmptyMsg($bar, $out)) echo $bar; else echo $out; ?></h5>
+ <div class='pBody'>
+ <ul>
+ <?php foreach($cont as $key => $val) { ?>
+ <li id="<?php echo htmlspecialchars($val['id']) ?>"><a href="<?php echo htmlspecialchars($val['href']) ?>"><?php echo htmlspecialchars($val['text'])?></a></li>
+ <?php } ?>
+ </ul>
+ </div>
+ </div>
+ <?php } ?>
+ <div id="p-search" class="portlet">
+ <h5><label for="searchInput"><?php $this->msg('search') ?></label></h5>
+ <div id="searchBody" class="pBody">
+ <form action="javascript:goToStatic(3)" id="searchform"><div>
+ <input id="searchInput" name="search" type="text"
+ <?php if($this->haveMsg('accesskey-search')) {
+ ?>accesskey="<?php $this->msg('accesskey-search') ?>"<?php }
+ if( isset( $this->data['search'] ) ) {
+ ?> value="<?php $this->text('search') ?>"<?php } ?> />
+ <input type='submit' name="go" class="searchButton" id="searchGoButton"
+ value="<?php $this->msg('go') ?>" />
+ </div></form>
+ </div>
+ </div>
+ <?php if( $this->data['language_urls'] ) { ?><div id="p-lang" class="portlet">
+ <h5><?php $this->msg('otherlanguages') ?></h5>
+ <div class="pBody">
+ <ul>
+ <?php foreach($this->data['language_urls'] as $langlink) { ?>
+ <li>
+ <a href="<?php echo htmlspecialchars($langlink['href'])
+ ?>"><?php echo $langlink['text'] ?></a>
+ </li>
+ <?php } ?>
+ </ul>
+ </div>
+ </div>
+ <?php } ?>
+ </div><!-- end of the left (by default at least) column -->
+ <div class="visualClear"></div>
+ <div id="footer">
+ <?php if($this->data['poweredbyico']) { ?><div id="f-poweredbyico"><?php $this->html('poweredbyico') ?></div><?php } ?>
+ <?php if($this->data['copyrightico']) { ?><div id="f-copyrightico"><?php $this->html('copyrightico') ?></div><?php } ?>
+ <ul id="f-list">
+ <?php if($this->data['lastmod' ]) { ?><li id="f-lastmod"><?php $this->html('lastmod') ?></li><?php } ?>
+ <?php if($this->data['numberofwatchingusers' ]) { ?><li id="f-numberofwatchingusers"><?php $this->html('numberofwatchingusers') ?></li><?php } ?>
+ <?php if($this->data['credits' ]) { ?><li id="f-credits"><?php $this->html('credits') ?></li><?php } ?>
+ <?php if($this->data['copyright' ]) { ?><li id="f-copyright"><?php $this->html('copyright') ?></li><?php } ?>
+ <?php if($this->data['about' ]) { ?><li id="f-about"><?php $this->html('about') ?></li><?php } ?>
+ <?php if($this->data['disclaimer']) { ?><li id="f-disclaimer"><?php $this->html('disclaimer') ?></li><?php } ?>
+ <?php if($this->data['tagline']) { ?><li id="f-tagline"><?php echo $this->data['tagline'] ?></li><?php } ?>
+ </ul>
+ </div>
+ </div>
+ </body>
+</html>
+<?php
+ wfRestoreWarnings();
+ }
+}
+?>
diff --git a/skins/disabled/MonoBook.tpl b/skins/disabled/MonoBook.tpl
new file mode 100644
index 000000000000..a5a259c8e315
--- /dev/null
+++ b/skins/disabled/MonoBook.tpl
@@ -0,0 +1,200 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{lang}" lang="{lang}" dir="{dir}">
+<head>
+ <meta http-equiv="Content-Type" content="{~ mimetype}; charset={~ charset}" />
+ {headlinks}
+ {headscripts}
+ <title>{pagetitle}</title>
+ <style type="text/css" media="screen,projection">/*<![CDATA[*/ @import "{~ stylepath}/{~ stylename}/main.css?5"; /*]]>*/</style>
+ <link rel="stylesheet" type="text/css" {if notprintable {media="print"}} href="{~ stylepath}/common/commonPrint.css" />
+ <!--[if lt IE 5.5000]><style type="text/css">@import "{~ stylepath}/{~ stylename}/IE50Fixes.css";</style><![endif]-->
+ <!--[if IE 5.5000]><style type="text/css">@import "{~ stylepath}/{~ stylename}/IE55Fixes.css";</style><![endif]-->
+ <!--[if IE 6]><style type="text/css">@import "{~ stylepath}/{~ stylename}/IE60Fixes.css";</style><![endif]-->
+ <!--[if IE 7]><style type="text/css">@import "{~ stylepath}/{~ stylename}/IE70Fixes.css?1";</style><![endif]-->
+ <!--[if lt IE 7]><script type="{jsmimetype}" src="{~ stylepath}/common/IEFixes.js"></script>
+ <meta http-equiv="imagetoolbar" content="no" /><![endif]-->
+ <script type="{jsmimetype}">var skin = '{~ skinname}';var stylepath = '{~ stylepath}';</script>
+ <script type="{jsmimetype}" src="{~ stylepath}/common/wikibits.js"><!-- wikibits js --></script>
+ {if jsvarurl {<script type="{jsmimetype}" src="{jsvarurl}"><!-- site js --></script>}}
+ {if pagecss {<style type="text/css">{pagecss}</style>}}
+ {usercss}
+ {sitecss}
+ {gencss}
+ {if userjs {<script type="{jsmimetype}" src="{userjs}"></script>}}
+ {if userjsprev {<script type="{jsmimetype}">{userjsprev}</script>}}
+ {trackbackhtml}
+</head>
+<body {if body_ondblclick {ondblclick="{body_ondblclick}"}} {if body_onload {onload="{body_onload}" }} class="{~ nsclass} {~ dir}">
+<div id="globalWrapper">
+ <div id="column-content">
+ <div id="content">
+ <a name="top" id="top"></a>
+ {if sitenotice {<div id="siteNotice">{sitenotice}</div> }}
+ <h1 class="firstHeading">{title}</h1>
+ <div id="bodyContent">
+ <h3 id="siteSub">{msg {tagline}}</h3>
+ <div id="contentSub">{subtitle}</div>
+ {if undelete {<div id="contentSub2"><span class="subpages">{undelete}</span></div> }}
+ {if newtalk {<div class="usermessage">{newtalk}</div> }}
+ {if showjumplinks {
+ <div id="jump-to-nav">{msg {jumpto}} <a href="#column-one">{msg {jumptonavigation}}</a>,
+ <a href="#searchInput">{msg {jumptosearch}}</a></div>
+ }}
+ <!-- start content -->
+ {bodytext}
+ {if catlinks {<div id="catlinks">{catlinks}</div> }}
+ <!-- end content -->
+ <div class="visualClear"></div>
+ </div>
+ </div>
+ </div>
+ <div id="column-one">
+ <div id="p-cactions" class="portlet">
+ <h5>{msg {views}}</h5>
+ <ul>
+ {if is_special {
+ <li id="ca-article" class="selected"><a href="{request_url}">{msg {specialpage}}</a></li>
+ } {
+ <li id="ca-{nskey}" {selecttab {subject} subject_newclass}><a href="{subject_url}">{msg nskey}</a></li>
+ <li id="ca-talk" {selecttab {talk} talk_newclass}><a href="{talk_url}">{msg {talk}}</a></li>
+ {if can_edit {
+ {if is_talk {
+ <li id="ca-edit" {selecttab {edit} {istalk}}><a href="{edit_url}">{msg {edit}}</a></li>
+ <li id="ca-addsection" {selecttab {addsection}}><a href="{localurl {action=edit&section=new}}">{msg {addsection}}</a></li>
+ } {
+ <li id="ca-edit" {selecttab {edit}}><a href="{edit_url}">{msg {edit}}</a></li>
+ }}
+ } {
+ <li id="ca-viewsource" {selecttab {edit}}><a href="{edit_url}">{msg {viewsource}}</a></li>
+ }}
+
+ {if article_exists {
+ <li id="ca-history" {selecttab {history}}><a href="{localurl {action=history}}">{msg {history_short}}</a></li>
+ {if {{ is_allowed {protect} }} {
+ {if is_ns_mediawiki {} {
+ {if is_protected {
+ <li id="ca-protect" {selecttab {protect}}><a href="{localurl {action=unprotect}}">{msg {unprotect}}</a></li>
+ } {
+ <li id="ca-protect" {selecttab {protect}}><a href="{localurl {action=protect}}">{msg {protect}}</a></li>
+ }}
+ }}
+ }}
+
+ {if {{ is_allowed {delete} }} {
+ <li id="ca-delete" {selecttab {delete}}><a href="{localurl {action=delete}}">{msg {delete}}</a></li>
+ }}
+ {if {{ is_allowed {move} }} {
+ {if can_move {
+ <li id="ca-move" {selecttab {move}}><a href="{move_url}">{msg {move}}</a></li>
+ }}
+ }}
+ {if is_loggedin {
+ {if is_watching {
+ <li id="ca-unwatch" {selecttab {watch}}><a href="{localurl {action=unwatch}}">{msg {unwatch}}</a></li>
+ } {
+ <li id="ca-watch" {selecttab {watch}}><a href="{localurl {action=watch}}">{msg {watch}}</a></li>
+ }}
+ }}
+ }}
+ }}
+ {extratabs {<li id="ca-$id" $class><a href="$href">$text</a></li>}}
+ </ul>
+ </div>
+ <div class="portlet" id="p-personal">
+ <h5>{msg {personaltools}}</h5>
+ <div class="pBody">
+ <ul>
+ {personal_urls { <li id="pt-$key" $classactive ><a href="$href" $class>$text</a></li> }}
+ </ul>
+ </div>
+ </div>
+ <div class="portlet" id="p-logo">
+ <a style="background-image: url({~ logopath});" href="{mainpage}" title="{msg {mainpage}}"></a>
+ </div>
+ <script type="{jsmimetype}"> if (window.isMSIE55) fixalpha(); </script>
+ {sidebar {
+ <div class='portlet' id="p-$bar">
+ <h5>$barname</h5>
+ <div class='pBody'>
+ <ul>
+ } {
+ </ul>
+ </div>
+ </div>
+ } {<li id="$id" $classactive><a href="$href">$text</a></li>
+ }
+ }
+
+ <div id="p-search" class="portlet">
+ <h5><label for="searchInput">{msg {search}}</label></h5>
+ <div id="searchBody" class="pBody">
+ <form action="{searchaction}" id="searchform"><div>
+ <input id="searchInput" name="search" type="text" {
+ }{if {{fallbackmsg {accesskey-search} {} }} {accesskey="{fallbackmsg {accesskey-search} {} }"}}{
+ }{if search { value="{search}"}} />
+ <input type='submit' name="go" class="searchButton" id="searchGoButton" value="{msg {go}}" />&nbsp;
+ <input type='submit' name="fulltext" class="searchButton" value="{msg {search}}" />
+ </div></form>
+ </div>
+ </div>
+ <div class="portlet" id="p-tb">
+ <h5>{msg {toolbox}}</h5>
+ <div class="pBody">
+ <ul>
+ {if notspecialpage {<li id="t-whatlinkshere"><a href="{nav_whatlinkshere}">{msg {whatlinkshere}}</a></li> }}
+ {if article_exists {<li id="t-recentchangeslinked"><a href="{nav_recentchangeslinked}">{msg {recentchangeslinked}}</a></li> }}
+ {if nav_trackbacklink {<li id="t-trackbacklink"><a href="{nav_trackbacklink}">{msg {trackbacklink}}</a></li>}}
+ {if feeds
+ {<li id="feedlinks">{feeds {<span id="feed-$key"><a href="$href">$text</a>&nbsp;</span>}}
+ </li>}}
+ {if is_userpage {
+ <li id="t-contributions"><a href="{nav_contributions}">{msg {contributions}}</a></li>
+ {if {{is_allowed {block}}} {<li id="t-blockip"><a href="{nav_blockip}">{msg {blockip}}</a></li>}}
+ {if is_loggedin {<li id="t-emailuser"><a href="{nav_emailuser}">{msg {emailuser}}</a></li>}}
+ }}
+ {if nav_upload {<li id="t-upload"><a href="{nav_upload}">{msg {upload}}</a></li>}}
+ {if nav_specialpages {<li id="t-specialpages"><a href="{nav_specialpages}">{msg {specialpages}}</a></li>}}
+ {if nav_print {<li id="t-print"><a href="{nav_print}">{msg {printableversion}}</a></li>}}
+ {if nav_permalink {<li id="t-permalink"><a href="{nav_permalink}">{msg {permalink}}</a></li>}}
+ {if is_permalink {<li id="t-ispermalink">{msg {permalink}}</li>}}
+
+ {toolboxend}
+ </ul>
+ </div>
+ </div>
+ {language_urls {
+ <div id="p-lang" class="portlet">
+ <h5>{msg {otherlanguages}}</h5>
+ <div class="pBody">
+ <ul>
+ $body
+ </ul>
+ </div>
+ </div>
+ } {
+ <li class="$class"><a href="$href">$text</a></li>
+ }}
+ </div><!-- end of the left (by default at least) column -->
+ <div class="visualClear"></div>
+ <div id="footer">
+ {if poweredbyico { <div id="f-poweredbyico">{poweredbyico}</div> }}
+ {if copyrightico { <div id="f-copyrightico">{copyrightico}</div> }}
+
+ <ul id="f-list">
+ {if lastmod { <li id="lastmod">{lastmod}</li> }}
+ {if viewcount { <li id="viewcount">{viewcount}</li> }}
+ {if numberofwatchingusers { <li id="numberofwatchingusers">{numberofwatchingusers}</li> }}
+ {if credits { <li id="credits">{credits}</li> }}
+ {if is_currentview { <li id="copyright">{normalcopyright}</li> }}
+ {if usehistorycopyright { <li id="copyright">{historycopyright}</li> }}
+ {if privacy { <li id="privacy">{privacy}</li> }}
+ {if about { <li id="about">{about}</li> }}
+ {if disclaimer { <li id="disclaimer">{disclaimer}</li> }}
+ {if tagline { <li id="tagline">{tagline}</li> }}
+ </ul>
+ </div>
+ <script type="text/javascript"> if (window.runOnloadHook) runOnloadHook();</script>
+</div>
+{reporttime}
+{if {} { vim: set syn=html ts=2 : }}
+</body></html>
diff --git a/skins/disabled/MonoBookCBT.php b/skins/disabled/MonoBookCBT.php
new file mode 100644
index 000000000000..3d145b24ad4e
--- /dev/null
+++ b/skins/disabled/MonoBookCBT.php
@@ -0,0 +1,1389 @@
+<?php
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ die( "This file is part of MediaWiki, it is not a valid entry point\n" );
+}
+
+require_once( 'includes/cbt/CBTProcessor.php' );
+require_once( 'includes/cbt/CBTCompiler.php' );
+require_once( 'includes/SkinTemplate.php' );
+
+/**
+ * MonoBook clone using the new dependency-tracking template processor.
+ * EXPERIMENTAL - use only for testing and profiling at this stage.
+ *
+ * See includes/cbt/README for an explanation.
+ *
+ * The main thing that's missing is cache invalidation, on change of:
+ * * messages
+ * * user preferences
+ * * source template
+ * * source code and configuration files
+ *
+ * The other thing is that lots of dependencies that are declared in the callbacks
+ * are not intelligently handled. There's some room for improvement there.
+ *
+ * The class is derived from SkinTemplate, but that's only temporary. Eventually
+ * it'll be derived from Skin, and I've avoided using SkinTemplate functions as
+ * much as possible. In fact, the only SkinTemplate dependencies I know of at the
+ * moment are the functions to generate the gen=css and gen=js files.
+ *
+ */
+class SkinMonoBookCBT extends SkinTemplate {
+ var $mOut, $mTitle;
+ var $mStyleName = 'monobook';
+ var $mCompiling = false;
+ var $mFunctionCache = array();
+
+ /******************************************************
+ * General functions *
+ ******************************************************/
+
+ /** Execute the template and write out the result */
+ function outputPage( &$out ) {
+ echo $this->execute( $out );
+ }
+
+ function execute( &$out ) {
+ global $wgTitle, $wgStyleDirectory, $wgParserCacheType;
+ $fname = 'SkinMonoBookCBT::execute';
+ wfProfileIn( $fname );
+ wfProfileIn( "$fname-setup" );
+ Skin::initPage( $out );
+
+ $this->mOut =& $out;
+ $this->mTitle =& $wgTitle;
+
+ $sourceFile = "$wgStyleDirectory/MonoBook.tpl";
+
+ wfProfileOut( "$fname-setup" );
+
+ if ( $wgParserCacheType == CACHE_NONE ) {
+ $template = file_get_contents( $sourceFile );
+ $text = $this->executeTemplate( $template );
+ } else {
+ $compiled = $this->getCompiledTemplate( $sourceFile );
+
+ wfProfileIn( "$fname-eval" );
+ $text = eval( $compiled );
+ wfProfileOut( "$fname-eval" );
+ }
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ function getCompiledTemplate( $sourceFile ) {
+ global $wgDBname, $wgMemc, $wgRequest, $wgUser, $parserMemc;
+ $fname = 'SkinMonoBookCBT::getCompiledTemplate';
+
+ $expiry = 3600;
+
+ // Sandbox template execution
+ if ( $this->mCompiling ) {
+ return;
+ }
+
+ wfProfileIn( $fname );
+
+ // Is the request an ordinary page view?
+ if ( $wgRequest->wasPosted() ||
+ count( array_diff( array_keys( $_GET ), array( 'title', 'useskin', 'recompile' ) ) ) != 0 )
+ {
+ $type = 'nonview';
+ } else {
+ $type = 'view';
+ }
+
+ // Per-user compiled template
+ // Put all logged-out users on the same cache key
+ $cacheKey = "$wgDBname:monobookcbt:$type:" . $wgUser->getId();
+
+ $recompile = $wgRequest->getVal( 'recompile' );
+ if ( $recompile == 'user' ) {
+ $recompileUser = true;
+ $recompileGeneric = false;
+ } elseif ( $recompile ) {
+ $recompileUser = true;
+ $recompileGeneric = true;
+ } else {
+ $recompileUser = false;
+ $recompileGeneric = false;
+ }
+
+ if ( !$recompileUser ) {
+ $php = $parserMemc->get( $cacheKey );
+ }
+ if ( $recompileUser || !$php ) {
+ if ( $wgUser->isLoggedIn() ) {
+ // Perform staged compilation
+ // First compile a generic template for all logged-in users
+ $genericKey = "$wgDBname:monobookcbt:$type:loggedin";
+ if ( !$recompileGeneric ) {
+ $template = $parserMemc->get( $genericKey );
+ }
+ if ( $recompileGeneric || !$template ) {
+ $template = file_get_contents( $sourceFile );
+ $ignore = array( 'loggedin', '!loggedin dynamic' );
+ if ( $type == 'view' ) {
+ $ignore[] = 'nonview dynamic';
+ }
+ $template = $this->compileTemplate( $template, $ignore );
+ $parserMemc->set( $genericKey, $template, $expiry );
+ }
+ } else {
+ $template = file_get_contents( $sourceFile );
+ }
+
+ $ignore = array( 'lang', 'loggedin', 'user' );
+ if ( $wgUser->isLoggedIn() ) {
+ $ignore[] = '!loggedin dynamic';
+ } else {
+ $ignore[] = 'loggedin dynamic';
+ }
+ if ( $type == 'view' ) {
+ $ignore[] = 'nonview dynamic';
+ }
+ $compiled = $this->compileTemplate( $template, $ignore );
+
+ // Reduce whitespace
+ // This is done here instead of in CBTProcessor because we can be
+ // more sure it is safe here.
+ $compiled = preg_replace( '/^[ \t]+/m', '', $compiled );
+ $compiled = preg_replace( '/[\r\n]+/', "\n", $compiled );
+
+ // Compile to PHP
+ $compiler = new CBTCompiler( $compiled );
+ $ret = $compiler->compile();
+ if ( $ret !== true ) {
+ echo $ret;
+ wfErrorExit();
+ }
+ $php = $compiler->generatePHP( '$this' );
+
+ $parserMemc->set( $cacheKey, $php, $expiry );
+ }
+ wfProfileOut( $fname );
+ return $php;
+ }
+
+ function compileTemplate( $template, $ignore ) {
+ $tp = new CBTProcessor( $template, $this, $ignore );
+ $tp->mFunctionCache = $this->mFunctionCache;
+
+ $this->mCompiling = true;
+ $compiled = $tp->compile();
+ $this->mCompiling = false;
+
+ if ( $tp->getLastError() ) {
+ // If there was a compile error, don't save the template
+ // Instead just print the error and exit
+ echo $compiled;
+ wfErrorExit();
+ }
+ $this->mFunctionCache = $tp->mFunctionCache;
+ return $compiled;
+ }
+
+ function executeTemplate( $template ) {
+ $fname = 'SkinMonoBookCBT::executeTemplate';
+ wfProfileIn( $fname );
+ $tp = new CBTProcessor( $template, $this );
+ $tp->mFunctionCache = $this->mFunctionCache;
+
+ $this->mCompiling = true;
+ $text = $tp->execute();
+ $this->mCompiling = false;
+
+ $this->mFunctionCache = $tp->mFunctionCache;
+ wfProfileOut( $fname );
+ return $text;
+ }
+
+ /******************************************************
+ * Callbacks *
+ ******************************************************/
+
+ function lang() { return $GLOBALS['wgContLanguageCode']; }
+
+ function dir() {
+ global $wgContLang;
+ return $wgContLang->isRTL() ? 'rtl' : 'ltr';
+ }
+
+ function mimetype() { return $GLOBALS['wgMimeType']; }
+ function charset() { return $GLOBALS['wgOutputEncoding']; }
+ function headlinks() {
+ return cbt_value( $this->mOut->getHeadLinks(), 'dynamic' );
+ }
+ function headscripts() {
+ return cbt_value( $this->mOut->getScript(), 'dynamic' );
+ }
+
+ function pagetitle() {
+ return cbt_value( $this->mOut->getHTMLTitle(), array( 'title', 'lang' ) );
+ }
+
+ function stylepath() { return $GLOBALS['wgStylePath']; }
+ function stylename() { return $this->mStyleName; }
+
+ function notprintable() {
+ global $wgRequest;
+ return cbt_value( !$wgRequest->getBool( 'printable' ), 'nonview dynamic' );
+ }
+
+ function jsmimetype() { return $GLOBALS['wgJsMimeType']; }
+
+ function jsvarurl() {
+ global $wgUseSiteJs, $wgUser;
+ if ( !$wgUseSiteJs ) return '';
+
+ if ( $wgUser->isLoggedIn() ) {
+ $url = self::makeUrl( '-','action=raw&smaxage=0&gen=js' );
+ } else {
+ $url = self::makeUrl( '-','action=raw&gen=js' );
+ }
+ return cbt_value( $url, 'loggedin' );
+ }
+
+ function pagecss() {
+ global $wgHooks;
+
+ $out = false;
+ wfRunHooks( 'SkinTemplateSetupPageCss', array( &$out ) );
+
+ // Unknown dependencies
+ return cbt_value( $out, 'dynamic' );
+ }
+
+ function usercss() {
+ if ( $this->isCssPreview() ) {
+ global $wgRequest;
+ $usercss = $this->makeStylesheetCdata( $wgRequest->getText('wpTextbox1') );
+ } else {
+ $usercss = $this->makeStylesheetLink( self::makeUrl($this->getUserPageText() .
+ '/'.$this->mStyleName.'.css', 'action=raw&ctype=text/css' ) );
+ }
+
+ // Dynamic when not an ordinary page view, also depends on the username
+ return cbt_value( $usercss, array( 'nonview dynamic', 'user' ) );
+ }
+
+ function sitecss() {
+ global $wgUseSiteCss;
+ if ( !$wgUseSiteCss ) {
+ return '';
+ }
+
+ global $wgSquidMaxage, $wgContLang, $wgStylePath;
+
+ $query = "action=raw&ctype=text/css&smaxage=$wgSquidMaxage";
+
+ $sitecss = '';
+ if ( $wgContLang->isRTL() ) {
+ $sitecss .= $this->makeStylesheetLink( $wgStylePath . '/' . $this->mStyleName . '/rtl.css' ) . "\n";
+ }
+
+ $sitecss .= $this->makeStylesheetLink( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) ) . "\n";
+ $sitecss .= $this->makeStylesheetLink( self::makeNSUrl( ucfirst( $this->mStyleName ) . '.css', $query, NS_MEDIAWIKI ) ) . "\n";
+
+ // No deps
+ return $sitecss;
+ }
+
+ function gencss() {
+ global $wgUseSiteCss;
+ if ( !$wgUseSiteCss ) return '';
+
+ global $wgSquidMaxage, $wgUser, $wgAllowUserCss;
+ if ( $this->isCssPreview() ) {
+ $siteargs = '&smaxage=0&maxage=0';
+ } else {
+ $siteargs = '&maxage=' . $wgSquidMaxage;
+ }
+ if ( $wgAllowUserCss && $wgUser->isLoggedIn() ) {
+ $siteargs .= '&ts={user_touched}';
+ $isTemplate = true;
+ } else {
+ $isTemplate = false;
+ }
+
+ $link = $this->makeStylesheetLink( self::makeUrl('-','action=raw&gen=css' . $siteargs) ) . "\n";
+
+ if ( $wgAllowUserCss ) {
+ $deps = 'loggedin';
+ } else {
+ $deps = array();
+ }
+ return cbt_value( $link, $deps, $isTemplate );
+ }
+
+ function user_touched() {
+ global $wgUser;
+ return cbt_value( $wgUser->mTouched, 'dynamic' );
+ }
+
+ function userjs() {
+ global $wgAllowUserJs, $wgJsMimeType;
+ if ( !$wgAllowUserJs ) return '';
+
+ if ( $this->isJsPreview() ) {
+ $url = '';
+ } else {
+ $url = self::makeUrl($this->getUserPageText().'/'.$this->mStyleName.'.js', 'action=raw&ctype='.$wgJsMimeType.'&dontcountme=s');
+ }
+ return cbt_value( $url, array( 'nonview dynamic', 'user' ) );
+ }
+
+ function userjsprev() {
+ global $wgAllowUserJs, $wgRequest;
+ if ( !$wgAllowUserJs ) return '';
+ if ( $this->isJsPreview() ) {
+ $js = '/*<![CDATA[*/ ' . $wgRequest->getText('wpTextbox1') . ' /*]]>*/';
+ } else {
+ $js = '';
+ }
+ return cbt_value( $js, array( 'nonview dynamic' ) );
+ }
+
+ function trackbackhtml() {
+ global $wgUseTrackbacks;
+ if ( !$wgUseTrackbacks ) return '';
+
+ if ( $this->mOut->isArticleRelated() ) {
+ $tb = $this->mTitle->trackbackRDF();
+ } else {
+ $tb = '';
+ }
+ return cbt_value( $tb, 'dynamic' );
+ }
+
+ function body_ondblclick() {
+ global $wgUser;
+ if( $this->isEditable() && $wgUser->getOption("editondblclick") ) {
+ $js = 'document.location = "' . $this->getEditUrl() .'";';
+ } else {
+ $js = '';
+ }
+
+ if ( User::getDefaultOption('editondblclick') ) {
+ return cbt_value( $js, 'user', 'title' );
+ } else {
+ // Optimise away for logged-out users
+ return cbt_value( $js, 'loggedin dynamic' );
+ }
+ }
+
+ function body_onload() {
+ global $wgUser;
+ if ( $this->isEditable() && $wgUser->getOption( 'editsectiononrightclick' ) ) {
+ $js = 'setupRightClickEdit()';
+ } else {
+ $js = '';
+ }
+ return cbt_value( $js, 'loggedin dynamic' );
+ }
+
+ function nsclass() {
+ return cbt_value( 'ns-' . $this->mTitle->getNamespace(), 'title' );
+ }
+
+ function sitenotice() {
+ // Perhaps this could be given special dependencies using our knowledge of what
+ // wfGetSiteNotice() depends on.
+ return cbt_value( wfGetSiteNotice(), 'dynamic' );
+ }
+
+ function title() {
+ return cbt_value( $this->mOut->getPageTitle(), array( 'title', 'lang' ) );
+ }
+
+ function title_urlform() {
+ return cbt_value( $this->getThisTitleUrlForm(), 'title' );
+ }
+
+ function title_userurl() {
+ return cbt_value( urlencode( $this->mTitle->getDBkey() ), 'title' );
+ }
+
+ function subtitle() {
+ $subpagestr = $this->subPageSubtitle();
+ if ( !empty( $subpagestr ) ) {
+ $s = '<span class="subpages">'.$subpagestr.'</span>'.$this->mOut->getSubtitle();
+ } else {
+ $s = $this->mOut->getSubtitle();
+ }
+ return cbt_value( $s, array( 'title', 'nonview dynamic' ) );
+ }
+
+ function undelete() {
+ return cbt_value( $this->getUndeleteLink(), array( 'title', 'lang' ) );
+ }
+
+ function newtalk() {
+ global $wgUser, $wgDBname;
+ $newtalks = $wgUser->getNewMessageLinks();
+
+ if (count($newtalks) == 1 && $newtalks[0]["wiki"] === $wgDBname) {
+ $usertitle = $this->getUserPageTitle();
+ $usertalktitle = $usertitle->getTalkPage();
+ if( !$usertalktitle->equals( $this->mTitle ) ) {
+ $ntl = wfMsg( 'youhavenewmessages',
+ $this->makeKnownLinkObj(
+ $usertalktitle,
+ wfMsgHtml( 'newmessageslink' ),
+ 'redirect=no'
+ ),
+ $this->makeKnownLinkObj(
+ $usertalktitle,
+ wfMsgHtml( 'newmessagesdifflink' ),
+ 'diff=cur'
+ )
+ );
+ # Disable Cache
+ $this->mOut->setSquidMaxage(0);
+ }
+ } else if (count($newtalks)) {
+ $sep = str_replace("_", " ", wfMsgHtml("newtalkseperator"));
+ $msgs = array();
+ foreach ($newtalks as $newtalk) {
+ $msgs[] = wfElement("a",
+ array('href' => $newtalk["link"]), $newtalk["wiki"]);
+ }
+ $parts = implode($sep, $msgs);
+ $ntl = wfMsgHtml('youhavenewmessagesmulti', $parts);
+ $this->mOut->setSquidMaxage(0);
+ } else {
+ $ntl = '';
+ }
+ return cbt_value( $ntl, 'dynamic' );
+ }
+
+ function showjumplinks() {
+ global $wgUser;
+ return cbt_value( $wgUser->getOption( 'showjumplinks' ) ? 'true' : '', 'user' );
+ }
+
+ function bodytext() {
+ return cbt_value( $this->mOut->getHTML(), 'dynamic' );
+ }
+
+ function catlinks() {
+ if ( !isset( $this->mCatlinks ) ) {
+ $this->mCatlinks = $this->getCategories();
+ }
+ return cbt_value( $this->mCatlinks, 'dynamic' );
+ }
+
+ function extratabs( $itemTemplate ) {
+ global $wgContLang, $wgDisableLangConversion;
+
+ $etpl = cbt_escape( $itemTemplate );
+
+ /* show links to different language variants */
+ $variants = $wgContLang->getVariants();
+ $s = '';
+ if ( !$wgDisableLangConversion && count( $wgContLang->getVariants() ) > 1 ) {
+ $vcount=0;
+ foreach ( $variants as $code ) {
+ $name = $wgContLang->getVariantname( $code );
+ if ( $name == 'disable' ) {
+ continue;
+ }
+ $code = cbt_escape( $code );
+ $name = cbt_escape( $name );
+ $s .= "{ca_variant {{$code}} {{$name}} {{$vcount}} {{$etpl}}}\n";
+ $vcount ++;
+ }
+ }
+ return cbt_value( $s, array(), true );
+ }
+
+ function is_special() { return cbt_value( $this->mTitle->getNamespace() == NS_SPECIAL, 'title' ); }
+ function can_edit() { return cbt_value( (string)($this->mTitle->userCanEdit()), 'dynamic' ); }
+ function can_move() { return cbt_value( (string)($this->mTitle->userCanMove()), 'dynamic' ); }
+ function is_talk() { return cbt_value( (string)($this->mTitle->isTalkPage()), 'title' ); }
+ function is_protected() { return cbt_value( (string)$this->mTitle->isProtected(), 'dynamic' ); }
+ function nskey() { return cbt_value( $this->mTitle->getNamespaceKey(), 'title' ); }
+
+ function request_url() {
+ global $wgRequest;
+ return cbt_value( $wgRequest->getRequestURL(), 'dynamic' );
+ }
+
+ function subject_url() {
+ $title = $this->getSubjectPage();
+ if ( $title->exists() ) {
+ $url = $title->getLocalUrl();
+ } else {
+ $url = $title->getLocalUrl( 'action=edit' );
+ }
+ return cbt_value( $url, 'title' );
+ }
+
+ function talk_url() {
+ $title = $this->getTalkPage();
+ if ( $title->exists() ) {
+ $url = $title->getLocalUrl();
+ } else {
+ $url = $title->getLocalUrl( 'action=edit' );
+ }
+ return cbt_value( $url, 'title' );
+ }
+
+ function edit_url() {
+ return cbt_value( $this->getEditUrl(), array( 'title', 'nonview dynamic' ) );
+ }
+
+ function move_url() {
+ return cbt_value( $this->makeSpecialParamUrl( 'Movepage' ), array(), true );
+ }
+
+ function localurl( $query ) {
+ return cbt_value( $this->mTitle->getLocalURL( $query ), 'title' );
+ }
+
+ function selecttab( $tab, $extraclass = '' ) {
+ if ( !isset( $this->mSelectedTab ) ) {
+ $prevent_active_tabs = false ;
+ wfRunHooks( 'SkinTemplatePreventOtherActiveTabs', array( &$this , &$preventActiveTabs ) );
+
+ $actionTabs = array(
+ 'edit' => 'edit',
+ 'submit' => 'edit',
+ 'history' => 'history',
+ 'protect' => 'protect',
+ 'unprotect' => 'protect',
+ 'delete' => 'delete',
+ 'watch' => 'watch',
+ 'unwatch' => 'watch',
+ );
+ if ( $preventActiveTabs ) {
+ $this->mSelectedTab = false;
+ } else {
+ $action = $this->getAction();
+ $section = $this->getSection();
+
+ if ( isset( $actionTabs[$action] ) ) {
+ $this->mSelectedTab = $actionTabs[$action];
+
+ if ( $this->mSelectedTab == 'edit' && $section == 'new' ) {
+ $this->mSelectedTab = 'addsection';
+ }
+ } elseif ( $this->mTitle->isTalkPage() ) {
+ $this->mSelectedTab = 'talk';
+ } else {
+ $this->mSelectedTab = 'subject';
+ }
+ }
+ }
+ if ( $extraclass ) {
+ if ( $this->mSelectedTab == $tab ) {
+ $s = 'class="selected ' . htmlspecialchars( $extraclass ) . '"';
+ } else {
+ $s = 'class="' . htmlspecialchars( $extraclass ) . '"';
+ }
+ } else {
+ if ( $this->mSelectedTab == $tab ) {
+ $s = 'class="selected"';
+ } else {
+ $s = '';
+ }
+ }
+ return cbt_value( $s, array( 'nonview dynamic', 'title' ) );
+ }
+
+ function subject_newclass() {
+ $title = $this->getSubjectPage();
+ $class = $title->exists() ? '' : 'new';
+ return cbt_value( $class, 'dynamic' );
+ }
+
+ function talk_newclass() {
+ $title = $this->getTalkPage();
+ $class = $title->exists() ? '' : 'new';
+ return cbt_value( $class, 'dynamic' );
+ }
+
+ function ca_variant( $code, $name, $index, $template ) {
+ global $wgContLang;
+ $selected = ($code == $wgContLang->getPreferredVariant());
+ $action = $this->getAction();
+ $actstr = '';
+ if( $action )
+ $actstr = 'action=' . $action . '&';
+ $s = strtr( $template, array(
+ '$id' => htmlspecialchars( 'varlang-' . $index ),
+ '$class' => $selected ? 'class="selected"' : '',
+ '$text' => $name,
+ '$href' => htmlspecialchars( $this->mTitle->getLocalUrl( $actstr . 'variant=' . $code ) )
+ ));
+ return cbt_value( $s, 'dynamic' );
+ }
+
+ function is_watching() {
+ return cbt_value( (string)$this->mTitle->userIsWatching(), array( 'dynamic' ) );
+ }
+
+
+ function personal_urls( $itemTemplate ) {
+ global $wgShowIPinHeader, $wgContLang;
+
+ # Split this function up into many small functions, to obtain the
+ # best specificity in the dependencies of each one. The template below
+ # has no dependencies, so its generation, and any static subfunctions,
+ # can be optimised away.
+ $etpl = cbt_escape( $itemTemplate );
+ $s = "
+ {userpage {{$etpl}}}
+ {mytalk {{$etpl}}}
+ {preferences {{$etpl}}}
+ {watchlist {{$etpl}}}
+ {mycontris {{$etpl}}}
+ {logout {{$etpl}}}
+ ";
+
+ if ( $wgShowIPinHeader ) {
+ $s .= "
+ {anonuserpage {{$etpl}}}
+ {anontalk {{$etpl}}}
+ {anonlogin {{$etpl}}}
+ ";
+ } else {
+ $s .= "{login {{$etpl}}}\n";
+ }
+ // No dependencies
+ return cbt_value( $s, array(), true /*this is a template*/ );
+ }
+
+ function userpage( $itemTemplate ) {
+ global $wgUser;
+ if ( $this->isLoggedIn() ) {
+ $userPage = $this->getUserPageTitle();
+ $s = $this->makeTemplateLink( $itemTemplate, 'userpage', $userPage, $wgUser->getName() );
+ } else {
+ $s = '';
+ }
+ return cbt_value( $s, 'user' );
+ }
+
+ function mytalk( $itemTemplate ) {
+ global $wgUser;
+ if ( $this->isLoggedIn() ) {
+ $userPage = $this->getUserPageTitle();
+ $talkPage = $userPage->getTalkPage();
+ $s = $this->makeTemplateLink( $itemTemplate, 'mytalk', $talkPage, wfMsg('mytalk') );
+ } else {
+ $s = '';
+ }
+ return cbt_value( $s, 'user' );
+ }
+
+ function preferences( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ $s = $this->makeSpecialTemplateLink( $itemTemplate, 'preferences',
+ 'Preferences', wfMsg( 'preferences' ) );
+ } else {
+ $s = '';
+ }
+ return cbt_value( $s, array( 'loggedin', 'lang' ) );
+ }
+
+ function watchlist( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ $s = $this->makeSpecialTemplateLink( $itemTemplate, 'watchlist',
+ 'Watchlist', wfMsg( 'watchlist' ) );
+ } else {
+ $s = '';
+ }
+ return cbt_value( $s, array( 'loggedin', 'lang' ) );
+ }
+
+ function mycontris( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ global $wgUser;
+ $s = $this->makeSpecialTemplateLink( $itemTemplate, 'mycontris',
+ "Contributions/" . $wgUser->getTitleKey(), wfMsg('mycontris') );
+ } else {
+ $s = '';
+ }
+ return cbt_value( $s, 'user' );
+ }
+
+ function logout( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ $s = $this->makeSpecialTemplateLink( $itemTemplate, 'logout',
+ 'Userlogout', wfMsg( 'userlogout' ),
+ $this->mTitle->getNamespace() === NS_SPECIAL && $this->mTitle->getText() === 'Preferences'
+ ? '' : "returnto=" . $this->mTitle->getPrefixedURL() );
+ } else {
+ $s = '';
+ }
+ return cbt_value( $s, 'loggedin dynamic' );
+ }
+
+ function anonuserpage( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ $s = '';
+ } else {
+ global $wgUser;
+ $userPage = $this->getUserPageTitle();
+ $s = $this->makeTemplateLink( $itemTemplate, 'userpage', $userPage, $wgUser->getName() );
+ }
+ return cbt_value( $s, '!loggedin dynamic' );
+ }
+
+ function anontalk( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ $s = '';
+ } else {
+ $userPage = $this->getUserPageTitle();
+ $talkPage = $userPage->getTalkPage();
+ $s = $this->makeTemplateLink( $itemTemplate, 'mytalk', $talkPage, wfMsg('anontalk') );
+ }
+ return cbt_value( $s, '!loggedin dynamic' );
+ }
+
+ function anonlogin( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ $s = '';
+ } else {
+ $s = $this->makeSpecialTemplateLink( $itemTemplate, 'anonlogin', 'Userlogin',
+ wfMsg( 'userlogin' ), 'returnto=' . urlencode( $this->getThisPDBK() ) );
+ }
+ return cbt_value( $s, '!loggedin dynamic' );
+ }
+
+ function login( $itemTemplate ) {
+ if ( $this->isLoggedIn() ) {
+ $s = '';
+ } else {
+ $s = $this->makeSpecialTemplateLink( $itemTemplate, 'login', 'Userlogin',
+ wfMsg( 'userlogin' ), 'returnto=' . urlencode( $this->getThisPDBK() ) );
+ }
+ return cbt_value( $s, '!loggedin dynamic' );
+ }
+
+ function logopath() { return $GLOBALS['wgLogo']; }
+ function mainpage() { return self::makeMainPageUrl(); }
+
+ function sidebar( $startSection, $endSection, $innerTpl ) {
+ $s = '';
+ $lines = explode( "\n", wfMsgForContent( 'sidebar' ) );
+ $firstSection = true;
+ foreach ($lines as $line) {
+ if (strpos($line, '*') !== 0)
+ continue;
+ if (strpos($line, '**') !== 0) {
+ $bar = trim($line, '* ');
+ $name = wfMsg( $bar );
+ if (wfEmptyMsg($bar, $name)) {
+ $name = $bar;
+ }
+ if ( $firstSection ) {
+ $firstSection = false;
+ } else {
+ $s .= $endSection;
+ }
+ $s .= strtr( $startSection,
+ array(
+ '$bar' => htmlspecialchars( $bar ),
+ '$barname' => $name
+ ) );
+ } else {
+ if (strpos($line, '|') !== false) { // sanity check
+ $line = explode( '|' , trim($line, '* '), 2 );
+ $link = wfMsgForContent( $line[0] );
+ if ($link == '-')
+ continue;
+ if (wfEmptyMsg($line[1], $text = wfMsg($line[1])))
+ $text = $line[1];
+ if (wfEmptyMsg($line[0], $link))
+ $link = $line[0];
+ $href = self::makeInternalOrExternalUrl( $link );
+
+ $s .= strtr( $innerTpl,
+ array(
+ '$text' => htmlspecialchars( $text ),
+ '$href' => htmlspecialchars( $href ),
+ '$id' => htmlspecialchars( 'n-' . strtr($line[1], ' ', '-') ),
+ '$classactive' => ''
+ ) );
+ } else { continue; }
+ }
+ }
+ if ( !$firstSection ) {
+ $s .= $endSection;
+ }
+
+ // Depends on user language only
+ return cbt_value( $s, 'lang' );
+ }
+
+ function searchaction() {
+ // Static link
+ return $this->getSearchLink();
+ }
+
+ function search() {
+ global $wgRequest;
+ return cbt_value( trim( $this->getSearch() ), 'special dynamic' );
+ }
+
+ function notspecialpage() {
+ return cbt_value( $this->mTitle->getNamespace() != NS_SPECIAL, 'special' );
+ }
+
+ function nav_whatlinkshere() {
+ return cbt_value( $this->makeSpecialParamUrl('Whatlinkshere' ), array(), true );
+ }
+
+ function article_exists() {
+ return cbt_value( (string)($this->mTitle->getArticleId() !== 0), 'title' );
+ }
+
+ function nav_recentchangeslinked() {
+ return cbt_value( $this->makeSpecialParamUrl('Recentchangeslinked' ), array(), true );
+ }
+
+ function feeds( $itemTemplate = '' ) {
+ if ( !$this->mOut->isSyndicated() ) {
+ $feeds = '';
+ } elseif ( $itemTemplate == '' ) {
+ // boolean only required
+ $feeds = 'true';
+ } else {
+ $feeds = '';
+ global $wgFeedClasses, $wgRequest;
+ foreach( $wgFeedClasses as $format => $class ) {
+ $feeds .= strtr( $itemTemplate,
+ array(
+ '$key' => htmlspecialchars( $format ),
+ '$text' => $format,
+ '$href' => $wgRequest->appendQuery( "feed=$format" )
+ ) );
+ }
+ }
+ return cbt_value( $feeds, 'special dynamic' );
+ }
+
+ function is_userpage() {
+ list( $id, $ip ) = $this->getUserPageIdIp();
+ return cbt_value( (string)($id || $ip), 'title' );
+ }
+
+ function is_ns_mediawiki() {
+ return cbt_value( (string)$this->mTitle->getNamespace() == NS_MEDIAWIKI, 'title' );
+ }
+
+ function is_loggedin() {
+ global $wgUser;
+ return cbt_value( (string)($wgUser->isLoggedIn()), 'loggedin' );
+ }
+
+ function nav_contributions() {
+ $url = $this->makeSpecialParamUrl( 'Contributions', '', '{title_userurl}' );
+ return cbt_value( $url, array(), true );
+ }
+
+ function is_allowed( $right ) {
+ global $wgUser;
+ return cbt_value( (string)$wgUser->isAllowed( $right ), 'user' );
+ }
+
+ function nav_blockip() {
+ $url = $this->makeSpecialParamUrl( 'Blockip', '', '{title_userurl}' );
+ return cbt_value( $url, array(), true );
+ }
+
+ function nav_emailuser() {
+ global $wgEnableEmail, $wgEnableUserEmail, $wgUser;
+ if ( !$wgEnableEmail || !$wgEnableUserEmail ) return '';
+
+ $url = $this->makeSpecialParamUrl( 'Emailuser', '', '{title_userurl}' );
+ return cbt_value( $url, array(), true );
+ }
+
+ function nav_upload() {
+ global $wgEnableUploads, $wgUploadNavigationUrl;
+ if ( !$wgEnableUploads ) {
+ return '';
+ } elseif ( $wgUploadNavigationUrl ) {
+ return $wgUploadNavigationUrl;
+ } else {
+ return self::makeSpecialUrl('Upload');
+ }
+ }
+
+ function nav_specialpages() {
+ return self::makeSpecialUrl('Specialpages');
+ }
+
+ function nav_print() {
+ global $wgRequest, $wgArticle;
+ $action = $this->getAction();
+ $url = '';
+ if( $this->mTitle->getNamespace() !== NS_SPECIAL
+ && ($action == '' || $action == 'view' || $action == 'purge' ) )
+ {
+ $revid = $wgArticle->getLatest();
+ if ( $revid != 0 ) {
+ $url = $wgRequest->appendQuery( 'printable=yes' );
+ }
+ }
+ return cbt_value( $url, array( 'nonview dynamic', 'title' ) );
+ }
+
+ function nav_permalink() {
+ $url = (string)$this->getPermalink();
+ return cbt_value( $url, 'dynamic' );
+ }
+
+ function nav_trackbacklink() {
+ global $wgUseTrackbacks;
+ if ( !$wgUseTrackbacks ) return '';
+
+ return cbt_value( $this->mTitle->trackbackURL(), 'title' );
+ }
+
+ function is_permalink() {
+ return cbt_value( (string)($this->getPermalink() === false), 'nonview dynamic' );
+ }
+
+ function toolboxend() {
+ // This is where the MonoBookTemplateToolboxEnd hook went in the old skin
+ return '';
+ }
+
+ function language_urls( $outer, $inner ) {
+ global $wgHideInterlanguageLinks, $wgOut, $wgContLang;
+ if ( $wgHideInterlanguageLinks ) return '';
+
+ $links = $wgOut->getLanguageLinks();
+ $s = '';
+ if ( count( $links ) ) {
+ foreach( $links as $l ) {
+ $tmp = explode( ':', $l, 2 );
+ $nt = Title::newFromText( $l );
+ $s .= strtr( $inner,
+ array(
+ '$class' => htmlspecialchars( 'interwiki-' . $tmp[0] ),
+ '$href' => htmlspecialchars( $nt->getFullURL() ),
+ '$text' => ($wgContLang->getLanguageName( $nt->getInterwiki() ) != ''?
+ $wgContLang->getLanguageName( $nt->getInterwiki() ) : $l ),
+ )
+ );
+ }
+ $s = str_replace( '$body', $s, $outer );
+ }
+ return cbt_value( $s, 'dynamic' );
+ }
+
+ function poweredbyico() { return $this->getPoweredBy(); }
+ function copyrightico() { return $this->getCopyrightIcon(); }
+
+ function lastmod() {
+ global $wgMaxCredits;
+ if ( $wgMaxCredits ) return '';
+
+ if ( !isset( $this->mLastmod ) ) {
+ if ( $this->isCurrentArticleView() ) {
+ $this->mLastmod = $this->lastModified();
+ } else {
+ $this->mLastmod = '';
+ }
+ }
+ return cbt_value( $this->mLastmod, 'dynamic' );
+ }
+
+ function viewcount() {
+ global $wgDisableCounters;
+ if ( $wgDisableCounters ) return '';
+
+ global $wgLang, $wgArticle;
+ if ( is_object( $wgArticle ) ) {
+ $viewcount = $wgLang->formatNum( $wgArticle->getCount() );
+ if ( $viewcount ) {
+ $viewcount = wfMsg( "viewcount", $viewcount );
+ } else {
+ $viewcount = '';
+ }
+ } else {
+ $viewcount = '';
+ }
+ return cbt_value( $viewcount, 'dynamic' );
+ }
+
+ function numberofwatchingusers() {
+ global $wgPageShowWatchingUsers;
+ if ( !$wgPageShowWatchingUsers ) return '';
+
+ $dbr =& wfGetDB( DB_SLAVE );
+ extract( $dbr->tableNames( 'watchlist' ) );
+ $sql = "SELECT COUNT(*) AS n FROM $watchlist
+ WHERE wl_title='" . $dbr->strencode($this->mTitle->getDBKey()) .
+ "' AND wl_namespace=" . $this->mTitle->getNamespace() ;
+ $res = $dbr->query( $sql, 'SkinTemplate::outputPage');
+ $row = $dbr->fetchObject( $res );
+ $num = $row->n;
+ if ($num > 0) {
+ $s = wfMsg('number_of_watching_users_pageview', $num);
+ } else {
+ $s = '';
+ }
+ return cbt_value( $s, 'dynamic' );
+ }
+
+ function credits() {
+ global $wgMaxCredits;
+ if ( !$wgMaxCredits ) return '';
+
+ if ( $this->isCurrentArticleView() ) {
+ require_once("Credits.php");
+ global $wgArticle, $wgShowCreditsIfMax;
+ $credits = getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
+ } else {
+ $credits = '';
+ }
+ return cbt_value( $credits, 'view dynamic' );
+ }
+
+ function normalcopyright() {
+ return $this->getCopyright( 'normal' );
+ }
+
+ function historycopyright() {
+ return $this->getCopyright( 'history' );
+ }
+
+ function is_currentview() {
+ global $wgRequest;
+ return cbt_value( (string)$this->isCurrentArticleView(), 'view' );
+ }
+
+ function usehistorycopyright() {
+ global $wgRequest;
+ if ( wfMsgForContent( 'history_copyright' ) == '-' ) return '';
+
+ $oldid = $this->getOldId();
+ $diff = $this->getDiff();
+ $use = (string)(!is_null( $oldid ) && is_null( $diff ));
+ return cbt_value( $use, 'nonview dynamic' );
+ }
+
+ function privacy() {
+ return cbt_value( $this->privacyLink(), 'lang' );
+ }
+ function about() {
+ return cbt_value( $this->aboutLink(), 'lang' );
+ }
+ function disclaimer() {
+ return cbt_value( $this->disclaimerLink(), 'lang' );
+ }
+ function tagline() {
+ # A reference to this tag existed in the old MonoBook.php, but the
+ # template data wasn't set anywhere
+ return '';
+ }
+ function reporttime() {
+ return cbt_value( $this->mOut->reportTime(), 'dynamic' );
+ }
+
+ function msg( $name ) {
+ return cbt_value( wfMsg( $name ), 'lang' );
+ }
+
+ function fallbackmsg( $name, $fallback ) {
+ $text = wfMsg( $name );
+ if ( wfEmptyMsg( $name, $text ) ) {
+ $text = $fallback;
+ }
+ return cbt_value( $text, 'lang' );
+ }
+
+ /******************************************************
+ * Utility functions *
+ ******************************************************/
+
+ /** Return true if this request is a valid, secure CSS preview */
+ function isCssPreview() {
+ if ( !isset( $this->mCssPreview ) ) {
+ global $wgRequest, $wgAllowUserCss, $wgUser;
+ $this->mCssPreview =
+ $wgAllowUserCss &&
+ $wgUser->isLoggedIn() &&
+ $this->mTitle->isCssSubpage() &&
+ $this->userCanPreview( $this->getAction() );
+ }
+ return $this->mCssPreview;
+ }
+
+ /** Return true if this request is a valid, secure JS preview */
+ function isJsPreview() {
+ if ( !isset( $this->mJsPreview ) ) {
+ global $wgRequest, $wgAllowUserJs, $wgUser;
+ $this->mJsPreview =
+ $wgAllowUserJs &&
+ $wgUser->isLoggedIn() &&
+ $this->mTitle->isJsSubpage() &&
+ $this->userCanPreview( $this->getAction() );
+ }
+ return $this->mJsPreview;
+ }
+
+ /** Get the title of the $wgUser's user page */
+ function getUserPageTitle() {
+ if ( !isset( $this->mUserPageTitle ) ) {
+ global $wgUser;
+ $this->mUserPageTitle = $wgUser->getUserPage();
+ }
+ return $this->mUserPageTitle;
+ }
+
+ /** Get the text of the user page title */
+ function getUserPageText() {
+ if ( !isset( $this->mUserPageText ) ) {
+ $userPage = $this->getUserPageTitle();
+ $this->mUserPageText = $userPage->getPrefixedText();
+ }
+ return $this->mUserPageText;
+ }
+
+ /** Make an HTML element for a stylesheet link */
+ function makeStylesheetLink( $url ) {
+ return '<link rel="stylesheet" type="text/css" href="' . htmlspecialchars( $url ) . "\"/>";
+ }
+
+ /** Make an XHTML element for inline CSS */
+ function makeStylesheetCdata( $style ) {
+ return "<style type=\"text/css\"> /*<![CDATA[*/ {$style} /*]]>*/ </style>";
+ }
+
+ /** Get the edit URL for this page */
+ function getEditUrl() {
+ if ( !isset( $this->mEditUrl ) ) {
+ $this->mEditUrl = $this->mTitle->getLocalUrl( $this->editUrlOptions() );
+ }
+ return $this->mEditUrl;
+ }
+
+ /** Get the prefixed DB key for this page */
+ function getThisPDBK() {
+ if ( !isset( $this->mThisPDBK ) ) {
+ $this->mThisPDBK = $this->mTitle->getPrefixedDbKey();
+ }
+ return $this->mThisPDBK;
+ }
+
+ function getThisTitleUrlForm() {
+ if ( !isset( $this->mThisTitleUrlForm ) ) {
+ $this->mThisTitleUrlForm = $this->mTitle->getPrefixedURL();
+ }
+ return $this->mThisTitleUrlForm;
+ }
+
+ /**
+ * If the current page is a user page, get the user's ID and IP. Otherwise return array(0,false)
+ */
+ function getUserPageIdIp() {
+ if ( !isset( $this->mUserPageId ) ) {
+ if( $this->mTitle->getNamespace() == NS_USER || $this->mTitle->getNamespace() == NS_USER_TALK ) {
+ $this->mUserPageId = User::idFromName($this->mTitle->getText());
+ $this->mUserPageIp = User::isIP($this->mTitle->getText());
+ } else {
+ $this->mUserPageId = 0;
+ $this->mUserPageIp = false;
+ }
+ }
+ return array( $this->mUserPageId, $this->mUserPageIp );
+ }
+
+ /**
+ * Returns a permalink URL, or false if the current page is already a
+ * permalink, or blank if a permalink shouldn't be displayed
+ */
+ function getPermalink() {
+ if ( !isset( $this->mPermalink ) ) {
+ global $wgRequest, $wgArticle;
+ $action = $this->getAction();
+ $oldid = $this->getOldId();
+ $url = '';
+ if( $this->mTitle->getNamespace() !== NS_SPECIAL
+ && $this->mTitle->getArticleId() != 0
+ && ($action == '' || $action == 'view' || $action == 'purge' ) )
+ {
+ if ( !$oldid ) {
+ $revid = $wgArticle->getLatest();
+ $url = $this->mTitle->getLocalURL( "oldid=$revid" );
+ } else {
+ $url = false;
+ }
+ } else {
+ $url = '';
+ }
+ }
+ return $url;
+ }
+
+ /**
+ * Returns true if the current page is an article, not a special page,
+ * and we are viewing a revision, not a diff
+ */
+ function isArticleView() {
+ global $wgOut, $wgArticle, $wgRequest;
+ if ( !isset( $this->mIsArticleView ) ) {
+ $oldid = $this->getOldId();
+ $diff = $this->getDiff();
+ $this->mIsArticleView = $wgOut->isArticle() and
+ (!is_null( $oldid ) or is_null( $diff )) and 0 != $wgArticle->getID();
+ }
+ return $this->mIsArticleView;
+ }
+
+ function isCurrentArticleView() {
+ if ( !isset( $this->mIsCurrentArticleView ) ) {
+ global $wgOut, $wgArticle, $wgRequest;
+ $oldid = $this->getOldId();
+ $this->mIsCurrentArticleView = $wgOut->isArticle() && is_null( $oldid ) && 0 != $wgArticle->getID();
+ }
+ return $this->mIsCurrentArticleView;
+ }
+
+
+ /**
+ * Return true if the current page is editable; if edit section on right
+ * click should be enabled.
+ */
+ function isEditable() {
+ global $wgRequest;
+ $action = $this->getAction();
+ return ($this->mTitle->getNamespace() != NS_SPECIAL and !($action == 'edit' or $action == 'submit'));
+ }
+
+ /** Return true if the user is logged in */
+ function isLoggedIn() {
+ global $wgUser;
+ return $wgUser->isLoggedIn();
+ }
+
+ /** Get the local URL of the current page */
+ function getPageUrl() {
+ if ( !isset( $this->mPageUrl ) ) {
+ $this->mPageUrl = $this->mTitle->getLocalURL();
+ }
+ return $this->mPageUrl;
+ }
+
+ /** Make a link to a title using a template */
+ function makeTemplateLink( $template, $key, $title, $text ) {
+ $url = $title->getLocalUrl();
+ return strtr( $template,
+ array(
+ '$key' => $key,
+ '$classactive' => ($url == $this->getPageUrl()) ? 'class="active"' : '',
+ '$class' => $title->getArticleID() == 0 ? 'class="new"' : '',
+ '$href' => htmlspecialchars( $url ),
+ '$text' => $text
+ ) );
+ }
+
+ /** Make a link to a URL using a template */
+ function makeTemplateLinkUrl( $template, $key, $url, $text ) {
+ return strtr( $template,
+ array(
+ '$key' => $key,
+ '$classactive' => ($url == $this->getPageUrl()) ? 'class="active"' : '',
+ '$class' => '',
+ '$href' => htmlspecialchars( $url ),
+ '$text' => $text
+ ) );
+ }
+
+ /** Make a link to a special page using a template */
+ function makeSpecialTemplateLink( $template, $key, $specialName, $text, $query = '' ) {
+ $url = self::makeSpecialUrl( $specialName, $query );
+ // Ignore the query when comparing
+ $active = ($this->mTitle->getNamespace() == NS_SPECIAL && $this->mTitle->getDBkey() == $specialName);
+ return strtr( $template,
+ array(
+ '$key' => $key,
+ '$classactive' => $active ? 'class="active"' : '',
+ '$class' => '',
+ '$href' => htmlspecialchars( $url ),
+ '$text' => $text
+ ) );
+ }
+
+ function loadRequestValues() {
+ global $wgRequest;
+ $this->mAction = $wgRequest->getText( 'action' );
+ $this->mOldId = $wgRequest->getVal( 'oldid' );
+ $this->mDiff = $wgRequest->getVal( 'diff' );
+ $this->mSection = $wgRequest->getVal( 'section' );
+ $this->mSearch = $wgRequest->getVal( 'search' );
+ $this->mRequestValuesLoaded = true;
+ }
+
+
+
+ /** Get the action parameter of the request */
+ function getAction() {
+ if ( !isset( $this->mRequestValuesLoaded ) ) {
+ $this->loadRequestValues();
+ }
+ return $this->mAction;
+ }
+
+ /** Get the oldid parameter */
+ function getOldId() {
+ if ( !isset( $this->mRequestValuesLoaded ) ) {
+ $this->loadRequestValues();
+ }
+ return $this->mOldId;
+ }
+
+ /** Get the diff parameter */
+ function getDiff() {
+ if ( !isset( $this->mRequestValuesLoaded ) ) {
+ $this->loadRequestValues();
+ }
+ return $this->mDiff;
+ }
+
+ function getSection() {
+ if ( !isset( $this->mRequestValuesLoaded ) ) {
+ $this->loadRequestValues();
+ }
+ return $this->mSection;
+ }
+
+ function getSearch() {
+ if ( !isset( $this->mRequestValuesLoaded ) ) {
+ $this->loadRequestValues();
+ }
+ return $this->mSearch;
+ }
+
+ /** Make a special page URL of the form [[Special:Somepage/{title_urlform}]] */
+ function makeSpecialParamUrl( $name, $query = '', $param = '{title_urlform}' ) {
+ // Abuse makeTitle's lax validity checking to slip a control character into the URL
+ $title = Title::makeTitle( NS_SPECIAL, "$name/\x1a" );
+ $url = cbt_escape( $title->getLocalURL( $query ) );
+ // Now replace it with the parameter
+ return str_replace( '%1A', $param, $url );
+ }
+
+ function getSubjectPage() {
+ if ( !isset( $this->mSubjectPage ) ) {
+ $this->mSubjectPage = $this->mTitle->getSubjectPage();
+ }
+ return $this->mSubjectPage;
+ }
+
+ function getTalkPage() {
+ if ( !isset( $this->mTalkPage ) ) {
+ $this->mTalkPage = $this->mTitle->getTalkPage();
+ }
+ return $this->mTalkPage;
+ }
+}
+?>
diff --git a/skins/htmldump/lookup.js b/skins/htmldump/lookup.js
new file mode 100644
index 000000000000..5fd8d019a131
--- /dev/null
+++ b/skins/htmldump/lookup.js
@@ -0,0 +1,91 @@
+/**
+ * "Go" function for static HTML dump
+ */
+function goToStatic(depth) {
+ var url = getStaticURL(document.getElementById("searchInput").value, depth);
+ if (url != "") {
+ location = url;
+ } else {
+ alert("Invalid title");
+ }
+}
+
+/**
+ * Determine relative path for a given non-canonical title
+ */
+function getStaticURL(text, depth) {
+ var pdbk = getPDBK(text);
+ if (pdbk == "") {
+ return "";
+ } else {
+ var i;
+ var path = getHashedDirectory(pdbk, depth) + "/" + getFriendlyName(pdbk) + ".html";
+ if (!/(index\.html|\/)$/.exec(location)) {
+ for (i = 0; i < depth; i++) {
+ path = "../" + path;
+ }
+ }
+ return path;
+ }
+}
+
+function getPDBK(text) {
+ // Spaces to underscores
+ text = text.replace(/ /g, "_");
+
+ // Trim leading and trailing space
+ text = text.replace(/^_+/g, "");
+ text = text.replace(/_+$/g, "");
+
+ // Capitalise first letter
+ return ucfirst(text);
+}
+
+function getHashedDirectory(pdbk, depth) {
+ // Find the first colon if there is one, use characters after it
+ var dbk = pdbk.replace(/^[^:]*:_*(.*)$/, "$1");
+ var i, c, dir = "";
+
+ for (i=0; i < depth; i++) {
+ if (i) {
+ dir += "/";
+ }
+ if (i >= dbk.length) {
+ dir += "_";
+ } else {
+ c = dbk.charAt(i);
+ cc = dbk.charCodeAt(i);
+
+ if (cc >= 128 || /[a-zA-Z0-9!#$%&()+,[\]^_`{}-]/.exec(c)) {
+ dir += c.toLowerCase();
+ } else {
+ dir += binl2hex([cc]).substr(0,2).toUpperCase();
+ }
+ }
+ }
+ return dir;
+}
+
+function ucfirst(s) {
+ return s.charAt(0).toUpperCase() + s.substring(1, s.length);
+}
+
+function getFriendlyName(name) {
+ // Replace illegal characters for Windows paths with underscores
+ var friendlyName = name.replace(/[\/\\*?"<>|~]/g, "_");
+
+ // Work out lower case form. We assume we're on a system with case-insensitive
+ // filenames, so unless the case is of a special form, we have to disambiguate
+ var lowerCase = ucfirst(name.toLowerCase());
+
+ // Make it mostly unique
+ if (lowerCase != friendlyName) {
+ friendlyName += "_" + hex_md5(_to_utf8(name)).substring(0, 4);
+ }
+ // Handle colon specially by replacing it with tilde
+ // Thus we reduce the number of paths with hashes appended
+ friendlyName = friendlyName.replace(":", "~");
+
+ return friendlyName;
+}
+
diff --git a/skins/htmldump/main.css b/skins/htmldump/main.css
new file mode 100644
index 000000000000..d1b4a92b11bd
--- /dev/null
+++ b/skins/htmldump/main.css
@@ -0,0 +1,9 @@
+@import "../monobook/main.css";
+
+#footer li {
+ display: block;
+}
+head:first-child + body #footer li { white-space: normal; }
+.usermessage { display: none; }
+.editsection { display: none; }
+
diff --git a/skins/htmldump/md5.js b/skins/htmldump/md5.js
new file mode 100644
index 000000000000..46d2aab7d140
--- /dev/null
+++ b/skins/htmldump/md5.js
@@ -0,0 +1,256 @@
+/*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
+var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
+function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
+function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
+function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
+function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
+function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function md5_vm_test()
+{
+ return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length
+ */
+function core_md5(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+ d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+ d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
+ d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
+ d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+ d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+ c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+ d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
+ c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
+ d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+ c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+ d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+ c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+ d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+ d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
+ d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+ d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+ d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
+ d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
+ d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+ d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return Array(a, b, c, d);
+
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t)
+{
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data
+ */
+function core_hmac_md5(key, data)
+{
+ var bkey = str2binl(key);
+ if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
+ return core_md5(opad.concat(hash), 512 + 128);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
+
+/*
+ * Convert a string to an array of little-endian words
+ * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
+ */
+function str2binl(str)
+{
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
+ return bin;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2str(bin)
+{
+ var str = "";
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < bin.length * 32; i += chrsz)
+ str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a hex string.
+ */
+function binl2hex(binarray)
+{
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i++)
+ {
+ str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
+ hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
+ }
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a base-64 string
+ */
+function binl2b64(binarray)
+{
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i += 3)
+ {
+ var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
+ | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
+ | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+ else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+ }
+ }
+ return str;
+}
diff --git a/skins/htmldump/utf8.js b/skins/htmldump/utf8.js
new file mode 100644
index 000000000000..ea3b890c6456
--- /dev/null
+++ b/skins/htmldump/utf8.js
@@ -0,0 +1,72 @@
+/**
+ * Obtained from http://homepage3.nifty.com/aokura/jscript/index.html
+ * The webpage says, among other things:
+ * * ソースコードの全てあるいは一部を使用したことにより生じた損害に関しては一切責任を負いません。
+ * * ソースコードの使用、配布に制限はありません。ご自由にお使いください。
+ * * 動作チェックが不充分な場合もありますので、注意してください。
+ *
+ * Which, loosely translated, means:
+ * * The author takes no responsibility for damage which occurs due to the use of this code.
+ * * There is no restriction on the use and distribution of the source code. Please use freely.
+ * * Please be careful, testing may have been insufficient.
+ */
+
+
+/**********************************************************************
+ *
+ * Unicode ⇔ UTF-8
+ *
+ * Copyright (c) 2005 AOK <soft@aokura.com>
+ *
+ **********************************************************************/
+
+function _to_utf8(s) {
+ var c, d = "";
+ for (var i = 0; i < s.length; i++) {
+ c = s.charCodeAt(i);
+ if (c <= 0x7f) {
+ d += s.charAt(i);
+ } else if (c >= 0x80 && c <= 0x7ff) {
+ d += String.fromCharCode(((c >> 6) & 0x1f) | 0xc0);
+ d += String.fromCharCode((c & 0x3f) | 0x80);
+ } else {
+ d += String.fromCharCode((c >> 12) | 0xe0);
+ d += String.fromCharCode(((c >> 6) & 0x3f) | 0x80);
+ d += String.fromCharCode((c & 0x3f) | 0x80);
+ }
+ }
+ return d;
+}
+
+function _from_utf8(s) {
+ var c, d = "", flag = 0, tmp;
+ for (var i = 0; i < s.length; i++) {
+ c = s.charCodeAt(i);
+ if (flag == 0) {
+ if ((c & 0xe0) == 0xe0) {
+ flag = 2;
+ tmp = (c & 0x0f) << 12;
+ } else if ((c & 0xc0) == 0xc0) {
+ flag = 1;
+ tmp = (c & 0x1f) << 6;
+ } else if ((c & 0x80) == 0) {
+ d += s.charAt(i);
+ } else {
+ flag = 0;
+ }
+ } else if (flag == 1) {
+ flag = 0;
+ d += String.fromCharCode(tmp | (c & 0x3f));
+ } else if (flag == 2) {
+ flag = 3;
+ tmp |= (c & 0x3f) << 6;
+ } else if (flag == 3) {
+ flag = 0;
+ d += String.fromCharCode(tmp | (c & 0x3f));
+ } else {
+ flag = 0;
+ }
+ }
+ return d;
+}
+
diff --git a/skins/monobook/IE50Fixes.css b/skins/monobook/IE50Fixes.css
new file mode 100644
index 000000000000..027e32ed0c46
--- /dev/null
+++ b/skins/monobook/IE50Fixes.css
@@ -0,0 +1,67 @@
+/*
+** IE5.0 Fix Stylesheet
+*/
+
+#column-content {
+ margin: 0 !important;
+ float: none;
+}
+#column-content #content {
+ margin-top: 3em;
+ height: 1%;
+}
+#column-one {
+ position: absolute;
+ overflow: visible;
+ top: 0;
+ left: 0;
+ z-index: 3;
+}
+#footer {
+ margin: 0 0 0 13.6em;
+}
+
+/* IE 5 & 5.5 interpret keyword sizes one off */
+body { font-size: xx-small; }
+/*
+** the edit tabs
+*/
+#p-cactions li {
+ float: left;
+ padding-top: 0;
+ padding-bottom: 0 !important;
+ height: 0.9em;
+}
+#p-cactions li a {
+ display: block;
+ padding-bottom: 0.045em;
+}
+#p-cactions li.selected a {
+ padding-bottom: 0.17em;
+}
+#p-cactions li a:hover {
+ padding-bottom: 0.17em;
+}
+/* 5.0 doesn't like the background icon for external links and user */
+.link-external,
+.external {
+ background: none;
+ padding: 0;
+}
+#p-personal ul { float: right }
+#p-personal li { float: left }
+li#pt-userpage,
+li#pt-anonuserpage,
+li#pt-login,
+li#pt-logout {
+ background: none;
+ padding-left: none;
+}
+.visualClear {
+ width: 100%;
+ height: 0px;
+ padding:0;
+ margin: 0;
+}
+.firstHeading { margin-bottom: .3em; }
+/*div{ border:1px solid Red !important;}*/
diff --git a/skins/monobook/IE55Fixes.css b/skins/monobook/IE55Fixes.css
new file mode 100644
index 000000000000..637daae17fbb
--- /dev/null
+++ b/skins/monobook/IE55Fixes.css
@@ -0,0 +1,85 @@
+/* IE5.5/win- only fixes */
+
+#column-content {
+ float: none;
+ margin-left: 0;
+ height: 1%;
+}
+#column-content #content {
+ position: relative;
+ z-index: 5;
+ margin-left: 12.2em;
+ margin-top: 3em;
+ height: 1%;
+}
+#column-one {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 4;
+ width: 100%;
+}
+#footer {
+ margin-left: 13.6em;
+ border-left: 1px solid #fabd23;
+}
+
+/*#bodyContent div,
+#bodyContent pre { overflow: auto; }*/
+
+#p-personal { padding-bottom: .1em; }
+
+body { font-size: xx-small; }
+
+#p-cactions {
+ width: 76% !important;
+ z-index: 3 !important;
+ float: none;
+}
+#p-cactions li {
+ padding-bottom: 0 !important;
+ border: none;
+ background-color: transparent;
+ cursor: default;
+ float: none !important;
+}
+#p-cactions li a {
+ display: inline-block !important;
+ vertical-align: top;
+ padding-bottom: 0;
+ border: solid #aaa;
+ border-width: 1px 1px 0;
+}
+#p-cactions li.selected a {
+ border-color: #fabd23;
+ padding-bottom: 0.17em;
+}
+#p-cactions li a:hover {
+ padding-bottom: 0.17em;
+}
+#p-navigation a {
+ display: inline-block;
+ width: 100%;
+}
+.portlet {
+ overflow: hidden;
+}
+#bodyContent a.external {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
+/* show the hand */
+#p-logo a,
+#p-logo a:hover {
+ cursor: pointer;
+}
+.visualClear {
+ width: 90%;
+ height: 1px;
+ padding: 0;
+ margin: 0;
+}
+
+#editform {
+ width: 100%;
+}
diff --git a/skins/monobook/IE60Fixes.css b/skins/monobook/IE60Fixes.css
new file mode 100644
index 000000000000..6b646c703b0a
--- /dev/null
+++ b/skins/monobook/IE60Fixes.css
@@ -0,0 +1,84 @@
+/* 6.0 - only fixes */
+/* content area */
+/* workaround for various ie float bugs */
+#column-content {
+ float: none;
+ margin-left: 0;
+ height: 1%;
+}
+#column-content #content {
+ margin-left: 12.2em;
+ margin-top: 3em;
+ height: 1%;
+}
+#column-one {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 4;
+}
+#footer {
+ margin-left: 13.6em;
+ border-left: 1px solid #fabd23;
+}
+
+/* the tabs */
+
+#p-cactions {
+ z-index: 3;
+}
+
+#p-cactions li {
+ padding-bottom: 0 !important;
+ border: none;
+ background-color: transparent;
+ cursor: default;
+ float: none !important;
+}
+#p-cactions li a {
+ display: inline-block !important;
+ vertical-align: top;
+ padding-bottom: 0;
+ border: solid #aaa;
+ border-width: 1px 1px 0;
+}
+#p-cactions li.selected a {
+ border-color: #fabd23;
+ padding-bottom: 0.17em;
+}
+#p-cactions li a:hover {
+ padding-bottom: 0.17em;
+}
+#p-navigation a {
+ display: inline-block;
+ width: 100%;
+}
+#portal-personaltools {
+ padding-bottom: 0.1em;
+}
+#bodyContent a.external {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
+
+/* show the hand */
+#p-logo a,
+#p-logo a:hover {
+ cursor: pointer;
+}
+div.visualClear {
+ width:100%;
+ line-height: 0;
+}
+textarea {
+ width: 96%;
+}
+
+div.editsection,
+#catlinks,
+div.tright,
+div.tleft {
+ position: relative;
+}
+/*{ border:1px solid Red !important;}*/
+
diff --git a/skins/monobook/IE70Fixes.css b/skins/monobook/IE70Fixes.css
new file mode 100644
index 000000000000..43ff7076d5e8
--- /dev/null
+++ b/skins/monobook/IE70Fixes.css
@@ -0,0 +1,74 @@
+/* 7.0 - only fixes */
+/* content area */
+/* workaround for various ie float bugs */
+
+/* This bit is needed to make links clickable... WTF */
+#column-content #content {
+ margin-left: 12.2em;
+ margin-top: 3em;
+ height: 1%;
+}
+
+.rtl #column-one {
+ /* For some reason it tries to inherit the padding-top into every div,
+ * and I can't figure out how to get it back off.
+ * Margin works correctly for this use, though.
+ */
+ padding-top: 0;
+ margin-top: 160px;
+}
+
+/* the tabs */
+
+#p-cactions {
+ z-index: 3;
+}
+
+
+#p-cactions li {
+ padding-bottom: 0 !important;
+ border: none;
+ background-color: transparent;
+ cursor: default;
+ float: none !important;
+}
+
+#p-cactions li a {
+ display: inline-block !important;
+ vertical-align: top;
+ padding-bottom: 0;
+ border: solid #aaa;
+ border-width: 1px 1px 0;
+}
+#p-cactions li.selected a {
+ border-color: #fabd23;
+ padding-bottom: 0.17em;
+}
+#p-cactions li a:hover {
+ padding-bottom: 0.17em;
+}
+#p-navigation a {
+ display: inline-block;
+ width: 100%;
+}
+#portal-personaltools {
+ padding-bottom: 0.1em;
+}
+textarea {
+ width: 96%;
+}
+
+/*
+div.editsection,
+#catlinks,
+div.tright,
+div.tleft {
+ position: relative;
+}
+*/
+
+
+#footer li {
+ /* Work around bug with inline <li> tags with right margins and nowrap */
+ margin-right: 0;
+}
diff --git a/skins/monobook/IEMacFixes.css b/skins/monobook/IEMacFixes.css
new file mode 100644
index 000000000000..f1b057195305
--- /dev/null
+++ b/skins/monobook/IEMacFixes.css
@@ -0,0 +1,44 @@
+/* IE/Mac only fix stylesheet, imported from main.css */
+#portal-column-content {
+ margin: 0 0 4.8em 0;
+ float: none;
+}
+#portal-column-content #content {
+ z-index: 0;
+}
+#portal-column-one {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 3;
+}
+#portal-footer {
+ margin-left: 12em;
+}
+/*
+#portlet-contentViews {
+ top: 0.6em !important;
+ left: 14.5em !important;
+}
+*/
+#portlet-contentViews li,
+#portlet-contentViews .selected {
+ border: none !important;
+}
+#portlet-contentViews li a {
+ border: 1px solid #aaaaaa;
+ border-bottom: none;
+}
+#portlet-contentViews li.selected a {
+ border: 1px solid #fabd23;
+ border-bottom: none;
+}
+/* no background images */
+li#personaltools-userpage,
+li#personaltools-login/* */ {
+ background: none;
+ padding-left: none;
+}
+#mactest {
+ color: green;
+}
diff --git a/skins/monobook/KHTMLFixes.css b/skins/monobook/KHTMLFixes.css
new file mode 100644
index 000000000000..97fba0c42a46
--- /dev/null
+++ b/skins/monobook/KHTMLFixes.css
@@ -0,0 +1,3 @@
+/* KHTML fix stylesheet */
+/* work around the horizontal scrollbars */
+#column-content { margin-left: 0; }
diff --git a/skins/monobook/Opera6Fixes.css b/skins/monobook/Opera6Fixes.css
new file mode 100644
index 000000000000..88704739ae34
--- /dev/null
+++ b/skins/monobook/Opera6Fixes.css
@@ -0,0 +1,14 @@
+/* opera 6 fixes */
+#column-one {
+ position: relative;
+ max-width: 11.7em;
+}
+#p-personal {
+ width: 45em;
+ margin-left: 8.6em;
+ right: 0;
+}
+#bodyContent a.external {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
diff --git a/skins/monobook/Opera7Fixes.css b/skins/monobook/Opera7Fixes.css
new file mode 100644
index 000000000000..446ea44cdbbf
--- /dev/null
+++ b/skins/monobook/Opera7Fixes.css
@@ -0,0 +1,11 @@
+/* small tweaks for opera seven */
+#p-cactions {
+ margin-top: .1em;
+}
+#p-cactions li a {
+ top: 2px;
+}
+#bodyContent a.external {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
diff --git a/skins/monobook/audio.png b/skins/monobook/audio.png
new file mode 100644
index 000000000000..1c56bdc8d8bc
--- /dev/null
+++ b/skins/monobook/audio.png
Binary files differ
diff --git a/skins/monobook/bullet.gif b/skins/monobook/bullet.gif
new file mode 100644
index 000000000000..b43de48a4701
--- /dev/null
+++ b/skins/monobook/bullet.gif
Binary files differ
diff --git a/skins/monobook/discussionitem_icon.gif b/skins/monobook/discussionitem_icon.gif
new file mode 100644
index 000000000000..baec471afc09
--- /dev/null
+++ b/skins/monobook/discussionitem_icon.gif
Binary files differ
diff --git a/skins/monobook/document.png b/skins/monobook/document.png
new file mode 100644
index 000000000000..b48138e90e81
--- /dev/null
+++ b/skins/monobook/document.png
Binary files differ
diff --git a/skins/monobook/external.png b/skins/monobook/external.png
new file mode 100644
index 000000000000..419c06fb960b
--- /dev/null
+++ b/skins/monobook/external.png
Binary files differ
diff --git a/skins/monobook/file_icon.gif b/skins/monobook/file_icon.gif
new file mode 100644
index 000000000000..847f6485efb4
--- /dev/null
+++ b/skins/monobook/file_icon.gif
Binary files differ
diff --git a/skins/monobook/handheld.css b/skins/monobook/handheld.css
new file mode 100644
index 000000000000..38fe1ebe7231
--- /dev/null
+++ b/skins/monobook/handheld.css
@@ -0,0 +1,1337 @@
+/*
+** MediaWiki 'monobook' style sheet for CSS2-capable browsers.
+** Copyright Gabriel Wicke - http://wikidev.net/
+** License: GPL (http://www.gnu.org/copyleft/gpl.html)
+**
+** Loosely based on http://www.positioniseverything.net/ordered-floats.html by Big John
+** and the Plone 2.0 styles, see http://plone.org/ (Alexander Limi,Joe Geldart & Tom Croucher,
+** Michael Zeltner and Geir Bækholt)
+** All you guys rock :)
+*/
+
+/**
+ * Stylesheet for handhelds. All rules not marked media-specific are shared
+ * with main.css and should be updated in tandem. The rules can't be in the
+ * same file because old browsers like IE5 won't obey @media rules.
+ *
+ * Rules that are handheld-specific are given @media rules in case old browsers
+ * don't recognize the media attribute and load this file anyway.
+ */
+
+#content {
+ background: white;
+ color: black;
+ border: 1px solid #aaa;
+ border-right: none;
+ line-height: 1.5em;
+}
+/* the left column width is specified in class .portlet */
+
+/* Font size:
+** We take advantage of keyword scaling- browsers won't go below 9px
+** More at http://www.w3.org/2003/07/30-font-size
+** http://style.cleverchimp.com/font_size_intervals/altintervals.html
+*/
+
+body {
+ font: x-small sans-serif;
+ background: #f9f9f9 url(headbg.jpg) 0 0 no-repeat;
+ color: black;
+ margin: 0;
+ padding: 0;
+}
+
+/* scale back up to a sane default */
+#globalWrapper {
+ font-size: 127%;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+}
+.visualClear {
+ clear: both;
+}
+
+/* general styles */
+
+table {
+ font-size: 100%;
+ color: black;
+ /* we don't want the bottom borders of <h2>s to be visible through
+ floated tables */
+ background-color: white;
+}
+a {
+ text-decoration: none;
+ color: #002bb8;
+ background: none;
+}
+a:visited {
+ color: #5a3696;
+}
+a:active {
+ color: #faa700;
+}
+a:hover {
+ text-decoration: underline;
+}
+a.stub {
+ color: #772233;
+}
+a.new, #p-personal a.new {
+ color: #ba0000;
+}
+a.new:visited, #p-personal a.new:visited {
+ color: #a55858;
+}
+
+img {
+ border: none;
+ vertical-align: middle;
+}
+p img {
+ margin: 0;
+}
+
+hr {
+ height: 1px;
+ color: #aaa;
+ background-color: #aaa;
+ border: 0;
+ margin: .2em 0 .2em 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: black;
+ background: none;
+ font-weight: normal;
+ margin: 0;
+ padding-top: .5em;
+ padding-bottom: .17em;
+ border-bottom: 1px solid #aaa;
+}
+h1 { font-size: 188%; }
+h1 .editsection { font-size: 53%; }
+h2 { font-size: 150%; }
+h2 .editsection { font-size: 67%; }
+h3, h4, h5, h6 {
+ border-bottom: none;
+ font-weight: bold;
+}
+h3 { font-size: 132%; }
+h3 .editsection { font-size: 76%; font-weight: normal; }
+h4 { font-size: 116%; }
+h4 .editsection { font-size: 86%; font-weight: normal; }
+h5 { font-size: 100%; }
+h5 .editsection { font-weight: normal; }
+h6 { font-size: 80%; }
+h6 .editsection { font-size: 125%; font-weight: normal; }
+
+.editsection {
+ float: right;
+ margin-left: 5px;
+}
+
+ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ margin: .3em 0 0 1.5em;
+ padding: 0;
+ list-style-image: url(bullet.gif);
+}
+ol {
+ line-height: 1.5em;
+ margin: .3em 0 0 3.2em;
+ padding: 0;
+ list-style-image: none;
+}
+li {
+ margin-bottom: .1em;
+}
+dt {
+ font-weight: bold;
+ margin-bottom: .1em;
+}
+dl {
+ margin-top: .2em;
+ margin-bottom: .5em;
+}
+dd {
+ line-height: 1.5em;
+ margin-left: 2em;
+ margin-bottom: .1em;
+}
+
+fieldset {
+ border: 1px solid #2f6fab;
+ margin: 1em 0 1em 0;
+ padding: 0 1em 1em;
+ line-height: 1.5em;
+}
+legend {
+ padding: .5em;
+ font-size: 95%;
+}
+form {
+ border: none;
+ margin: 0;
+}
+
+textarea {
+ width: 100%;
+ padding: .1em;
+}
+
+input.historysubmit {
+ padding: 0 .3em .3em .3em !important;
+ font-size: 94%;
+ cursor: pointer;
+ height: 1.7em !important;
+ margin-left: 1.6em;
+}
+select {
+ vertical-align: top;
+}
+abbr, acronym, .explain {
+ border-bottom: 1px dotted black;
+ color: black;
+ background: none;
+ cursor: help;
+}
+q {
+ font-family: Times, "Times New Roman", serif;
+ font-style: italic;
+}
+/* disabled for now
+blockquote {
+ font-family: Times, "Times New Roman", serif;
+ font-style: italic;
+}*/
+code {
+ background-color: #f9f9f9;
+}
+pre {
+ padding: 1em;
+ border: 1px dashed #2f6fab;
+ color: black;
+ background-color: #f9f9f9;
+ line-height: 1.1em;
+}
+
+/*
+** the main content area
+*/
+
+#contentSub, #contentSub2 {
+ font-size: 84%;
+ line-height: 1.2em;
+ margin: 0 0 1.4em 1em;
+ color: #7d7d7d;
+ width: auto;
+}
+span.subpages {
+ display: block;
+}
+
+/* Some space under the headers in the content area */
+#bodyContent h1, #bodyContent h2 {
+ margin-bottom: .6em;
+}
+#bodyContent h3, #bodyContent h4, #bodyContent h5 {
+ margin-bottom: .3em;
+}
+.firstHeading {
+ margin-bottom: .1em;
+}
+
+/* user notification thing */
+.usermessage {
+ background-color: #ffce7b;
+ border: 1px solid #ffa500;
+ color: black;
+ font-weight: bold;
+ margin: 2em 0 1em;
+ padding: .5em 1em;
+ vertical-align: middle;
+}
+#siteNotice {
+ text-align: center;
+ font-size: 95%;
+ padding: 0 .9em;
+}
+#siteNotice p {
+ margin: 0;
+ padding: 0;
+}
+.error {
+ color: red;
+ font-size: larger;
+}
+.errorbox, .successbox {
+ font-size: larger;
+ border: 2px solid;
+ padding: .5em 1em;
+ float: left;
+ margin-bottom: 2em;
+ color: #000;
+}
+.errorbox {
+ border-color: red;
+ background-color: #fff2f2;
+}
+.successbox {
+ border-color: green;
+ background-color: #dfd;
+}
+.errorbox h2, .successbox h2 {
+ font-size: 1em;
+ font-weight: bold;
+ display: inline;
+ margin: 0 .5em 0 0;
+ border: none;
+}
+
+#catlinks {
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ margin-top: 1em;
+ clear: both;
+}
+/* currently unused, intended to be used by a metadata box
+in the bottom-right corner of the content area */
+.documentDescription {
+ /* The summary text describing the document */
+ font-weight: bold;
+ display: block;
+ margin: 1em 0;
+ line-height: 1.5em;
+}
+.documentByLine {
+ text-align: right;
+ font-size: 90%;
+ clear: both;
+ font-weight: normal;
+ color: #76797c;
+}
+
+/* emulate center */
+.center {
+ width: 100%;
+ text-align: center;
+}
+*.center * {
+ margin-left: auto;
+ margin-right: auto;
+}
+/* small for tables and similar */
+.small, .small * {
+ font-size: 94%;
+}
+table.small {
+ font-size: 100%;
+}
+
+/*
+** content styles
+*/
+
+#toc,
+.toc,
+.mw-warning {
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+}
+#toc h2,
+.toc h2 {
+ display: inline;
+ border: none;
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+}
+#toc #toctitle,
+.toc #toctitle,
+#toc .toctitle,
+.toc .toctitle {
+ text-align: center;
+}
+#toc ul,
+.toc ul {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 0;
+ padding-left: 0;
+ text-align: left;
+}
+#toc ul ul,
+.toc ul ul {
+ margin: 0 0 0 2em;
+}
+#toc .toctoggle,
+.toc .toctoggle {
+ font-size: 94%;
+}
+
+.mw-warning {
+ margin-left: 50px;
+ margin-right: 50px;
+ text-align: center;
+}
+
+/* images */
+div.floatright, table.floatright {
+ clear: right;
+ float: right;
+ position: relative;
+ margin: 0 0 .5em .5em;
+ border: 0;
+/*
+ border: .5em solid white;
+ border-width: .5em 0 .8em 1.4em;
+*/
+}
+div.floatright p { font-style: italic; }
+div.floatleft, table.floatleft {
+ float: left;
+ clear: left;
+ position: relative;
+ margin: 0 .5em .5em 0;
+ border: 0;
+/*
+ margin: .3em .5em .5em 0;
+ border: .5em solid white;
+ border-width: .5em 1.4em .8em 0;
+*/
+}
+div.floatleft p { font-style: italic; }
+/* thumbnails */
+div.thumb {
+ margin-bottom: .5em;
+ border-style: solid;
+ border-color: white;
+ width: auto;
+}
+div.thumbinner {
+ border: 1px solid #ccc;
+ padding: 3px !important;
+ background-color: #f9f9f9;
+ font-size: 94%;
+ text-align: center;
+ overflow: hidden;
+}
+html .thumbimage {
+ border: 1px solid #ccc;
+}
+html .thumbcaption {
+ border: none;
+ text-align: left;
+ line-height: 1.4em;
+ padding: 3px !important;
+ font-size: 94%;
+}
+div.magnify {
+ float: right;
+ border: none !important;
+ background: none !important;
+}
+div.magnify a, div.magnify img {
+ display: block;
+ border: none !important;
+ background: none !important;
+}
+div.tright {
+ clear: right;
+ float: right;
+ border-width: .5em 0 .8em 1.4em;
+}
+div.tleft {
+ float: left;
+ clear: left;
+ margin-right: .5em;
+ border-width: .5em 1.4em .8em 0;
+}
+
+.hiddenStructure {
+ display: none;
+ speak: none;
+}
+img.tex {
+ vertical-align: middle;
+}
+span.texhtml {
+ font-family: serif;
+}
+
+/*
+** classes for special content elements like town boxes
+** intended to be referenced directly from the wiki src
+*/
+
+/*
+** User styles
+*/
+/* table standards */
+table.rimage {
+ float: right;
+ position: relative;
+ margin-left: 1em;
+ margin-bottom: 1em;
+ text-align: center;
+}
+.toccolours {
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+}
+div.townBox {
+ position: relative;
+ float: right;
+ background: white;
+ margin-left: 1em;
+ border: 1px solid gray;
+ padding: .3em;
+ width: 200px;
+ overflow: hidden;
+ clear: right;
+}
+div.townBox dl {
+ padding: 0;
+ margin: 0 0 .3em;
+ font-size: 96%;
+}
+div.townBox dl dt {
+ background: none;
+ margin: .4em 0 0;
+}
+div.townBox dl dd {
+ margin: .1em 0 0 1.1em;
+ background-color: #f3f3f3;
+}
+
+/*
+** edit views etc
+*/
+.special li {
+ line-height: 1.4em;
+ margin: 0;
+ padding: 0;
+}
+
+/* Page history styling */
+/* the auto-generated edit comments */
+.autocomment {
+ color: gray;
+}
+#pagehistory span.user {
+ margin-left: 1.4em;
+ margin-right: .4em;
+}
+#pagehistory span.minor {
+ font-weight: bold;
+}
+#pagehistory li {
+ border: 1px solid white;
+}
+#pagehistory li.selected {
+ background-color: #f9f9f9;
+ border: 1px dashed #aaa;
+}
+
+/*
+** Diff rendering
+*/
+table.diff, td.diff-otitle, td.diff-ntitle {
+ background-color: white;
+}
+td.diff-addedline {
+ background: #cfc;
+ font-size: smaller;
+}
+td.diff-deletedline {
+ background: #ffa;
+ font-size: smaller;
+}
+td.diff-context {
+ background: #eee;
+ font-size: smaller;
+}
+span.diffchange {
+ color: red;
+ font-weight: bold;
+}
+
+/*
+** keep the whitespace in front of the ^=, hides rule from konqueror
+** this is css3, the validator doesn't like it when validating as css2
+*/
+#bodyContent a.external,
+#bodyContent a[href ^="gopher://"] {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
+#bodyContent a[href ^="https://"],
+.link-https {
+ background: url(lock_icon.gif) center right no-repeat;
+ padding-right: 16px;
+}
+#bodyContent a[href ^="mailto:"],
+.link-mailto {
+ background: url(mail_icon.gif) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="news://"] {
+ background: url(news_icon.png) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="ftp://"],
+.link-ftp {
+ background: url(file_icon.gif) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="irc://"],
+.link-irc {
+ background: url(discussionitem_icon.gif) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a.external[href $=".ogg"], #bodyContent a.external[href $=".OGG"],
+#bodyContent a.external[href $=".mid"], #bodyContent a.external[href $=".MID"],
+#bodyContent a.external[href $=".midi"], #bodyContent a.external[href $=".MIDI"],
+#bodyContent a.external[href $=".mp3"], #bodyContent a.external[href $=".MP3"],
+#bodyContent a.external[href $=".wav"], #bodyContent a.external[href $=".WAV"],
+#bodyContent a.external[href $=".wma"], #bodyContent a.external[href $=".WMA"],
+.link-audio {
+ background: url("audio.png") center right no-repeat;
+ padding-right: 13px;
+}
+#bodyContent a.external[href $=".ogm"], #bodyContent a.external[href $=".OGM"],
+#bodyContent a.external[href $=".avi"], #bodyContent a.external[href $=".AVI"],
+#bodyContent a.external[href $=".mpeg"], #bodyContent a.external[href $=".MPEG"],
+#bodyContent a.external[href $=".mpg"], #bodyContent a.external[href $=".MPG"],
+.link-video {
+ background: url("video.png") center right no-repeat;
+ padding-right: 13px;
+}
+#bodyContent a.external[href $=".pdf"], #bodyContent a.external[href $=".PDF"],
+#bodyContent a.external[href *=".pdf#"], #bodyContent a.external[href *=".PDF#"],
+#bodyContent a.external[href *=".pdf?"], #bodyContent a.external[href *=".PDF?"],
+.link-document {
+ background: url("document.png") center right no-repeat;
+ padding-right: 12px;
+}
+
+/* disable interwiki styling */
+#bodyContent a.extiw,
+#bodyContent a.extiw:active {
+ color: #36b;
+ background: none;
+ padding: 0;
+}
+#bodyContent a.external {
+ color: #36b;
+}
+/* this can be used in the content area to switch off
+special external link styling */
+#bodyContent .plainlinks a {
+ background: none !important;
+ padding: 0 !important;
+}
+/*
+** Structural Elements
+*/
+
+/*
+** general portlet styles (elements in the quickbar)
+*/
+.portlet {
+ border: none;
+ margin: 0 0 .5em;
+ padding: 0;
+ float: none;
+ width: 11.6em;
+ overflow: hidden;
+}
+.portlet h4 {
+ font-size: 95%;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.portlet h5 {
+ background: transparent;
+ padding: 0 1em 0 .5em;
+ display: inline;
+ height: 1em;
+ text-transform: lowercase;
+ font-size: 91%;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.portlet h6 {
+ background: #ffae2e;
+ border: 1px solid #2f6fab;
+ border-style: solid solid none solid;
+ padding: 0 1em 0 1em;
+ text-transform: lowercase;
+ display: block;
+ font-size: 1em;
+ height: 1.2em;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.pBody {
+ font-size: 95%;
+ background-color: white;
+ color: black;
+ border-collapse: collapse;
+ border: 1px solid #aaa;
+ padding: 0 .8em .3em .5em;
+}
+.portlet h1,
+.portlet h2,
+.portlet h3,
+.portlet h4 {
+ margin: 0;
+ padding: 0;
+}
+.portlet ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ list-style-image: url(bullet.gif);
+ font-size: 95%;
+}
+.portlet li {
+ padding: 0;
+ margin: 0;
+}
+
+/*
+** Logo properties
+*/
+
+@media handheld {
+ #p-logo { display: none }
+}
+
+/*
+** the navigation portlet
+*/
+
+#p-navigation .pBody {
+ padding-right: 0;
+}
+
+#p-navigation li.active a, #p-navigation li.active a:hover {
+ text-decoration: none;
+ font-weight: bold;
+}
+
+
+/*
+** Search portlet
+*/
+input.searchButton {
+ margin-top: 1px;
+ font-size: 95%;
+}
+#searchGoButton {
+ padding-left: .5em;
+ padding-right: .5em;
+ font-weight: bold;
+}
+#searchInput {
+ width: 10.9em;
+ margin: 0;
+ font-size: 95%;
+}
+#p-search .pBody {
+ padding: .5em .4em .4em .4em;
+ text-align: center;
+}
+
+/*
+** the personal toolbar
+*/
+#p-personal ul {
+ text-transform: lowercase;
+}
+#p-personal li.active {
+ font-weight: bold;
+}
+/*
+** the page-related actions- page/talk, edit etc
+*/
+#p-cactions .hiddenStructure {
+ display: none;
+}
+#p-cactions li a {
+ text-transform: lowercase;
+}
+
+/* TODO: #t-iscite is only used by the Cite extension, come up with some
+ * system which allows extensions to add to this file on the fly
+ */
+#t-ispermalink, #t-iscite {
+ color: #999;
+}
+/*
+** footer
+*/
+#footer {
+ background-color: white;
+ border-top: 1px solid #fabd23;
+ border-bottom: 1px solid #fabd23;
+ margin: .6em 0 1em 0;
+ padding: .4em 0 1.2em 0;
+ text-align: center;
+ font-size: 90%;
+}
+#footer li {
+ display: inline;
+ margin: 0 1.3em;
+}
+/* hide from incapable browsers */
+head:first-child+body #footer li { white-space: nowrap; }
+#f-poweredbyico, #f-copyrightico {
+ margin: 0 8px;
+ position: relative;
+ top: -2px; /* Bump it up just a tad */
+}
+#f-poweredbyico {
+ float: right;
+ height: 1%;
+}
+#f-copyrightico {
+ float: left;
+ height: 1%;
+}
+
+/* js pref toc */
+#preftoc {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ clear: both;
+}
+#preftoc li {
+ background-color: #f0f0f0;
+ color: #000;
+}
+#preftoc li.selected {
+ font-weight: bold;
+ background-color: #f9f9f9;
+ border: 1px solid #aaa;
+ border-bottom: none;
+ cursor: default;
+ top: 1px;
+ padding-top: 2px;
+ margin-right: -3px;
+}
+#preftoc > li.selected {
+ top: 2px;
+}
+#preftoc a,
+#preftoc a:active {
+ display: block;
+ color: #000;
+ padding: 0 .7em;
+ position: relative;
+ text-decoration: none;
+}
+#preftoc li.selected a {
+ cursor: default;
+ text-decoration: none;
+}
+#prefcontrol {
+ padding-top: 2em;
+ clear: both;
+}
+#preferences {
+ margin: 0;
+ border: 1px solid #aaa;
+ clear: both;
+ padding: 1.5em;
+ background-color: #F9F9F9;
+}
+.prefsection {
+ border: none;
+ padding: 0;
+ margin: 0;
+}
+.prefsection fieldset {
+ border: 1px solid #aaa;
+ float: left;
+ margin-right: 2em;
+}
+.prefsection legend {
+ font-weight: bold;
+}
+.prefsection table, .prefsection legend {
+ background-color: #F9F9F9;
+}
+div.prefsectiontip {
+ font-size: 95%;
+ margin-top: 0;
+ background-color: #FFC1C1;
+ padding: .2em .7em;
+ clear: both;
+}
+.btnSavePrefs {
+ font-weight: bold;
+ padding-left: .3em;
+ padding-right: .3em;
+}
+
+.preferences-login {
+ clear: both;
+ margin-bottom: 1.5em;
+}
+
+.prefcache {
+ font-size: 90%;
+ margin-top: 2em;
+}
+
+div#userloginForm form,
+div#userlogin form#userlogin2 {
+ margin: 0 3em 1em 0;
+ border: 1px solid #aaa;
+ clear: both;
+ padding: 1.5em 2em;
+ background-color: #f9f9f9;
+ float: left;
+}
+
+div#userloginForm table,
+div#userlogin form#userlogin2 table {
+ background-color: #f9f9f9;
+}
+
+div#userloginForm h2,
+div#userlogin form#userlogin2 h2 {
+ padding-top: 0;
+}
+
+div#userlogin .captcha {
+ border: 1px solid #bbb;
+ padding: 1.5em 2em;
+ width: 400px;
+ background-color: white;
+}
+
+
+#userloginprompt, #languagelinks {
+ font-size: 85%;
+}
+
+#login-sectiontip {
+ font-size: 85%;
+ line-height: 1.2;
+ padding-top: 2em;
+}
+
+#userlogin .loginText, #userlogin .loginPassword {
+ width: 12em;
+}
+
+#userloginlink a, #wpLoginattempt, #wpCreateaccount {
+ font-weight: bold;
+}
+
+/* more IE fixes */
+/* float/negative margin brokenness */
+* html #footer {margin-top: 0;}
+* html #column-content {
+ display: inline;
+ margin-bottom: 0;
+}
+* html div.editsection { font-size: smaller; }
+#pagehistory li.selected { position: relative; }
+
+/* Mac IE 5.0 fix; floated content turns invisible */
+* > html #column-content {
+ float: none;
+}
+* > html #column-one {
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+* > html #footer {
+ margin-left: 13.2em;
+}
+.redirectText {
+ font-size: 150%;
+ margin: 5px;
+}
+
+.printfooter {
+ display: none;
+}
+
+.not-patrolled {
+ background-color: #ffa;
+}
+div.patrollink {
+ font-size: 75%;
+ text-align: right;
+}
+span.newpage, span.minor, span.searchmatch, span.bot {
+ font-weight: bold;
+}
+span.unpatrolled {
+ font-weight: bold;
+ color: red;
+}
+
+span.searchmatch {
+ color: red;
+}
+.sharedUploadNotice {
+ font-style: italic;
+}
+
+span.updatedmarker {
+ color: black;
+ background-color: #0f0;
+}
+span.newpageletter {
+ font-weight: bold;
+ color: black;
+ background-color: yellow;
+}
+span.minoreditletter {
+ color: black;
+ background-color: #c5ffe6;
+}
+
+table.gallery {
+ border: 1px solid #ccc;
+ margin: 2px;
+ padding: 2px;
+ background-color: white;
+}
+
+table.gallery tr {
+ vertical-align: top;
+}
+
+table.gallery td {
+ vertical-align: top;
+ background-color: #f9f9f9;
+ border: solid 2px white;
+}
+
+table.gallery td.galleryheader {
+ text-align: center;
+ font-weight: bold;
+}
+
+div.gallerybox {
+ margin: 2px;
+ width: 150px;
+}
+
+div.gallerybox div.thumb {
+ text-align: center;
+ border: 1px solid #ccc;
+ margin: 2px;
+}
+
+div.gallerytext {
+ font-size: 94%;
+ padding: 2px 4px;
+}
+
+span.comment {
+ font-style: italic;
+}
+
+span.changedby {
+ font-size: 95%;
+}
+
+.previewnote {
+ text-indent: 3em;
+ color: #c00;
+ border-bottom: 1px solid #aaa;
+ padding-bottom: 1em;
+ margin-bottom: 1em;
+}
+
+.previewnote p {
+ margin: 0;
+ padding: 0;
+}
+
+.editExternally {
+ border: 1px solid gray;
+ background-color: #ffffff;
+ padding: 3px;
+ margin-top: 0.5em;
+ float: left;
+ font-size: small;
+ text-align: center;
+}
+.editExternallyHelp {
+ font-style: italic;
+ color: gray;
+}
+
+li span.deleted, span.history-deleted {
+ text-decoration: line-through;
+ color: #888;
+ font-style: italic;
+}
+
+.toggle {
+ margin-left: 2em;
+ text-indent: -2em;
+}
+
+/* Classes for EXIF data display */
+table.mw_metadata {
+ font-size: 0.8em;
+ margin-left: 0.5em;
+ margin-bottom: 0.5em;
+ width: 300px;
+}
+
+table.mw_metadata caption {
+ font-weight: bold;
+}
+
+table.mw_metadata th {
+ font-weight: normal;
+}
+
+table.mw_metadata td {
+ padding: 0.1em;
+}
+
+table.mw_metadata {
+ border: none;
+ border-collapse: collapse;
+}
+
+table.mw_metadata td, table.mw_metadata th {
+ text-align: center;
+ border: 1px solid #aaaaaa;
+ padding-left: 0.1em;
+ padding-right: 0.1em;
+}
+
+table.mw_metadata th {
+ background-color: #f9f9f9;
+}
+
+table.mw_metadata td {
+ background-color: #fcfcfc;
+}
+
+table.collapsed tr.collapsable {
+ display: none;
+}
+
+
+/* filetoc */
+ul#filetoc {
+ text-align: center;
+ border: 1px solid #aaaaaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+ margin-bottom: 0.5em;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+#filetoc li {
+ display: inline;
+ list-style-type: none;
+ padding-right: 2em;
+}
+
+input#wpSummary {
+ width: 80%;
+}
+
+/* @bug 1714 */
+input#wpSave, input#wpDiff {
+ margin-right: 0.33em;
+}
+
+#editform .editOptions {
+ display: inline;
+}
+
+#wpSave {
+ font-weight: bold;
+}
+
+/* Classes for article validation */
+
+table.revisionform_default {
+ border: 1px solid #000000;
+}
+
+table.revisionform_focus {
+ border: 1px solid #000000;
+ background-color:#00BBFF;
+}
+
+tr.revision_tr_default {
+ background-color:#EEEEEE;
+}
+
+tr.revision_tr_first {
+ background-color:#DDDDDD;
+}
+
+p.revision_saved {
+ color: green;
+ font-weight:bold;
+}
+
+#mw_trackbacks {
+ border: solid 1px #bbbbff;
+ background-color: #eeeeff;
+ padding: 0.2em;
+}
+
+
+/* Allmessages table */
+
+#allmessagestable th {
+ background-color: #b2b2ff;
+}
+
+#allmessagestable tr.orig {
+ background-color: #ffe2e2;
+}
+
+#allmessagestable tr.new {
+ background-color: #e2ffe2;
+}
+
+#allmessagestable tr.def {
+ background-color: #f0f0ff;
+}
+
+
+/* noarticletext */
+div.noarticletext {
+ border: 1px solid #ccc;
+ background: #fff;
+ padding: .2em 1em;
+ color: #000;
+}
+
+div#searchTargetContainer {
+ left: 10px;
+ top: 10px;
+ width: 90%;
+ background: white;
+}
+
+div#searchTarget {
+ padding: 3px;
+ margin: 5px;
+ background: #F0F0F0;
+ border: solid 1px blue;
+}
+
+div#searchTarget ul li {
+ list-style: none;
+}
+
+div#searchTarget ul li:before {
+ color: orange;
+ content: "\00BB \0020";
+}
+
+div.multipageimagenavbox {
+ border: solid 1px silver;
+ padding: 4px;
+ margin: 1em;
+ -moz-border-radius: 6px;
+ background: #f0f0f0;
+}
+
+div.multipageimagenavbox div.thumb {
+ border: none;
+ margin-left: 2em;
+ margin-right: 2em;
+}
+
+div.multipageimagenavbox hr {
+ margin: 6px;
+}
+
+table.multipageimage td {
+ text-align: center;
+}
+
+/** Special:Version */
+
+table#sv-ext, table#sv-hooks {
+ margin: 1em;
+ padding:0em;
+}
+
+#sv-ext td, #sv-hooks td,
+#sv-ext th, #sv-hooks th {
+ border: 1px solid #A0A0A0;
+ padding: 0 0.15em 0 0.15em;
+}
+#sv-ext th, #sv-hooks th {
+ background-color: #F0F0F0;
+ color: black;
+ padding: 0 0.15em 0 0.15em;
+}
+tr.sv-space{
+ height: 0.8em;
+ border:none;
+}
+tr.sv-space td { display: none; }
+
+/*
+ Table pager (e.g. Special:Imagelist)
+ - remove underlines from the navigation link
+ - collapse borders
+ - set the borders to outsets (similar to Special:Allmessages)
+ - remove line wrapping for all td and th, set background color
+ - restore line wrapping for the last two table cells (description and size)
+*/
+.TablePager_nav a { text-decoration: none; }
+.TablePager { border-collapse: collapse; }
+.TablePager, .TablePager td, .TablePager th {
+ border: 0.15em solid #777777;
+ padding: 0 0.15em 0 0.15em;
+}
+.TablePager th { background-color: #eeeeff }
+.TablePager td { background-color: #ffffff }
+.TablePager tr:hover td { background-color: #eeeeff }
+
+.imagelist td, .imagelist th { white-space: nowrap }
+.imagelist .TablePager_col_links { background-color: #eeeeff }
+.imagelist .TablePager_col_img_description { white-space: normal }
+.imagelist th.TablePager_sort { background-color: #ccccff }
+
+.templatesUsed { margin-top: 1.5em; }
+
+.mw-summary-preview {
+ margin: 0.1em 0;
+}
+#toolbar { clear: both; }
+
+.mw-plusminus-null { color: #aaa; }
+
+@media handheld {
+ .nonessential {
+ /* Kill big bulky stuff that will clog up the screen */
+ display: none;
+ }
+} \ No newline at end of file
diff --git a/skins/monobook/headbg.jpg b/skins/monobook/headbg.jpg
new file mode 100644
index 000000000000..5491c6e4acbc
--- /dev/null
+++ b/skins/monobook/headbg.jpg
Binary files differ
diff --git a/skins/monobook/link_icon.gif b/skins/monobook/link_icon.gif
new file mode 100644
index 000000000000..815ccb1b1ca0
--- /dev/null
+++ b/skins/monobook/link_icon.gif
Binary files differ
diff --git a/skins/monobook/lock_icon.gif b/skins/monobook/lock_icon.gif
new file mode 100644
index 000000000000..8a87e2833069
--- /dev/null
+++ b/skins/monobook/lock_icon.gif
Binary files differ
diff --git a/skins/monobook/magnify-clip.png b/skins/monobook/magnify-clip.png
new file mode 100644
index 000000000000..992aa2e326c8
--- /dev/null
+++ b/skins/monobook/magnify-clip.png
Binary files differ
diff --git a/skins/monobook/mail_icon.gif b/skins/monobook/mail_icon.gif
new file mode 100644
index 000000000000..50a87a9a0689
--- /dev/null
+++ b/skins/monobook/mail_icon.gif
Binary files differ
diff --git a/skins/monobook/main.css b/skins/monobook/main.css
new file mode 100644
index 000000000000..dbfc080190d2
--- /dev/null
+++ b/skins/monobook/main.css
@@ -0,0 +1,1616 @@
+/*
+** MediaWiki 'monobook' style sheet for CSS2-capable browsers.
+** Copyright Gabriel Wicke - http://wikidev.net/
+** License: GPL (http://www.gnu.org/copyleft/gpl.html)
+**
+** Loosely based on http://www.positioniseverything.net/ordered-floats.html by Big John
+** and the Plone 2.0 styles, see http://plone.org/ (Alexander Limi,Joe Geldart & Tom Croucher,
+** Michael Zeltner and Geir Bækholt)
+** All you guys rock :)
+*/
+
+/**
+ * Stylesheet for screen/projection. All rules not marked media-specific are
+ * shared with handheld.css and should be updated in tandem. The rules can't
+ * be in the same file because old browsers like IE5 won't obey @media rules.
+ *
+ * Rules that are screen/projection-specific are marked with commented-out
+ * @media rules and indentation.
+ */
+
+/* @media screen, projection { */
+ #column-content {
+ width: 100%;
+ float: right;
+ margin: 0 0 .6em -12.2em;
+ padding: 0;
+ }
+ #content {
+ margin: 2.8em 0 0 12.2em;
+ padding: 0 1em 1.5em 1em;
+ position: relative;
+ z-index: 2;
+ }
+ #column-one {
+ padding-top: 160px;
+ }
+/* } */
+#content {
+ background: white;
+ color: black;
+ border: 1px solid #aaa;
+ border-right: none;
+ line-height: 1.5em;
+}
+/* the left column width is specified in class .portlet */
+
+/* Font size:
+** We take advantage of keyword scaling- browsers won't go below 9px
+** More at http://www.w3.org/2003/07/30-font-size
+** http://style.cleverchimp.com/font_size_intervals/altintervals.html
+*/
+
+body {
+ font: x-small sans-serif;
+ background: #f9f9f9 url(headbg.jpg) 0 0 no-repeat;
+ color: black;
+ margin: 0;
+ padding: 0;
+}
+
+/* scale back up to a sane default */
+#globalWrapper {
+ font-size: 127%;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+}
+.visualClear {
+ clear: both;
+}
+
+/* general styles */
+
+table {
+ font-size: 100%;
+ color: black;
+ /* we don't want the bottom borders of <h2>s to be visible through
+ floated tables */
+ background-color: white;
+}
+a {
+ text-decoration: none;
+ color: #002bb8;
+ background: none;
+}
+a:visited {
+ color: #5a3696;
+}
+a:active {
+ color: #faa700;
+}
+a:hover {
+ text-decoration: underline;
+}
+a.stub {
+ color: #772233;
+}
+a.new, #p-personal a.new {
+ color: #ba0000;
+}
+a.new:visited, #p-personal a.new:visited {
+ color: #a55858;
+}
+
+img {
+ border: none;
+ vertical-align: middle;
+}
+/* @media screen, projection { */
+ p {
+ margin: .4em 0 .5em 0;
+ line-height: 1.5em;
+ }
+/* } */
+p img {
+ margin: 0;
+}
+
+hr {
+ height: 1px;
+ color: #aaa;
+ background-color: #aaa;
+ border: 0;
+ margin: .2em 0 .2em 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: black;
+ background: none;
+ font-weight: normal;
+ margin: 0;
+ padding-top: .5em;
+ padding-bottom: .17em;
+ border-bottom: 1px solid #aaa;
+}
+h1 { font-size: 188%; }
+h1 .editsection { font-size: 53%; }
+h2 { font-size: 150%; }
+h2 .editsection { font-size: 67%; }
+h3, h4, h5, h6 {
+ border-bottom: none;
+ font-weight: bold;
+}
+h3 { font-size: 132%; }
+h3 .editsection { font-size: 76%; font-weight: normal; }
+h4 { font-size: 116%; }
+h4 .editsection { font-size: 86%; font-weight: normal; }
+h5 { font-size: 100%; }
+h5 .editsection { font-weight: normal; }
+h6 { font-size: 80%; }
+h6 .editsection { font-size: 125%; font-weight: normal; }
+
+.editsection {
+ float: right;
+ margin-left: 5px;
+}
+
+ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ margin: .3em 0 0 1.5em;
+ padding: 0;
+ list-style-image: url(bullet.gif);
+}
+ol {
+ line-height: 1.5em;
+ margin: .3em 0 0 3.2em;
+ padding: 0;
+ list-style-image: none;
+}
+li {
+ margin-bottom: .1em;
+}
+dt {
+ font-weight: bold;
+ margin-bottom: .1em;
+}
+dl {
+ margin-top: .2em;
+ margin-bottom: .5em;
+}
+dd {
+ line-height: 1.5em;
+ margin-left: 2em;
+ margin-bottom: .1em;
+}
+
+fieldset {
+ border: 1px solid #2f6fab;
+ margin: 1em 0 1em 0;
+ padding: 0 1em 1em;
+ line-height: 1.5em;
+}
+legend {
+ padding: .5em;
+ font-size: 95%;
+}
+form {
+ border: none;
+ margin: 0;
+}
+
+textarea {
+ width: 100%;
+ padding: .1em;
+}
+
+input.historysubmit {
+ padding: 0 .3em .3em .3em !important;
+ font-size: 94%;
+ cursor: pointer;
+ height: 1.7em !important;
+ margin-left: 1.6em;
+}
+select {
+ vertical-align: top;
+}
+abbr, acronym, .explain {
+ border-bottom: 1px dotted black;
+ color: black;
+ background: none;
+ cursor: help;
+}
+q {
+ font-family: Times, "Times New Roman", serif;
+ font-style: italic;
+}
+/* disabled for now
+blockquote {
+ font-family: Times, "Times New Roman", serif;
+ font-style: italic;
+}*/
+code {
+ background-color: #f9f9f9;
+}
+pre {
+ padding: 1em;
+ border: 1px dashed #2f6fab;
+ color: black;
+ background-color: #f9f9f9;
+ line-height: 1.1em;
+}
+
+/*
+** the main content area
+*/
+
+/* @media screen, projection { */
+ #siteSub {
+ display: none;
+ }
+ #jump-to-nav {
+ display: none;
+ }
+/* } */
+
+#contentSub, #contentSub2 {
+ font-size: 84%;
+ line-height: 1.2em;
+ margin: 0 0 1.4em 1em;
+ color: #7d7d7d;
+ width: auto;
+}
+span.subpages {
+ display: block;
+}
+
+/* Some space under the headers in the content area */
+#bodyContent h1, #bodyContent h2 {
+ margin-bottom: .6em;
+}
+#bodyContent h3, #bodyContent h4, #bodyContent h5 {
+ margin-bottom: .3em;
+}
+.firstHeading {
+ margin-bottom: .1em;
+}
+
+/* user notification thing */
+.usermessage {
+ background-color: #ffce7b;
+ border: 1px solid #ffa500;
+ color: black;
+ font-weight: bold;
+ margin: 2em 0 1em;
+ padding: .5em 1em;
+ vertical-align: middle;
+}
+#siteNotice {
+ text-align: center;
+ font-size: 95%;
+ padding: 0 .9em;
+}
+#siteNotice p {
+ margin: 0;
+ padding: 0;
+}
+.error {
+ color: red;
+ font-size: larger;
+}
+.errorbox, .successbox {
+ font-size: larger;
+ border: 2px solid;
+ padding: .5em 1em;
+ float: left;
+ margin-bottom: 2em;
+ color: #000;
+}
+.errorbox {
+ border-color: red;
+ background-color: #fff2f2;
+}
+.successbox {
+ border-color: green;
+ background-color: #dfd;
+}
+.errorbox h2, .successbox h2 {
+ font-size: 1em;
+ font-weight: bold;
+ display: inline;
+ margin: 0 .5em 0 0;
+ border: none;
+}
+
+#catlinks {
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ margin-top: 1em;
+ clear: both;
+}
+/* currently unused, intended to be used by a metadata box
+in the bottom-right corner of the content area */
+.documentDescription {
+ /* The summary text describing the document */
+ font-weight: bold;
+ display: block;
+ margin: 1em 0;
+ line-height: 1.5em;
+}
+.documentByLine {
+ text-align: right;
+ font-size: 90%;
+ clear: both;
+ font-weight: normal;
+ color: #76797c;
+}
+
+/* emulate center */
+.center {
+ width: 100%;
+ text-align: center;
+}
+*.center * {
+ margin-left: auto;
+ margin-right: auto;
+}
+/* small for tables and similar */
+.small, .small * {
+ font-size: 94%;
+}
+table.small {
+ font-size: 100%;
+}
+
+/*
+** content styles
+*/
+
+#toc,
+.toc,
+.mw-warning {
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+}
+#toc h2,
+.toc h2 {
+ display: inline;
+ border: none;
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+}
+#toc #toctitle,
+.toc #toctitle,
+#toc .toctitle,
+.toc .toctitle {
+ text-align: center;
+}
+#toc ul,
+.toc ul {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 0;
+ padding-left: 0;
+ text-align: left;
+}
+#toc ul ul,
+.toc ul ul {
+ margin: 0 0 0 2em;
+}
+#toc .toctoggle,
+.toc .toctoggle {
+ font-size: 94%;
+}
+
+.mw-warning {
+ margin-left: 50px;
+ margin-right: 50px;
+ text-align: center;
+}
+
+/* images */
+div.floatright, table.floatright {
+ clear: right;
+ float: right;
+ position: relative;
+ margin: 0 0 .5em .5em;
+ border: 0;
+/*
+ border: .5em solid white;
+ border-width: .5em 0 .8em 1.4em;
+*/
+}
+div.floatright p { font-style: italic; }
+div.floatleft, table.floatleft {
+ float: left;
+ clear: left;
+ position: relative;
+ margin: 0 .5em .5em 0;
+ border: 0;
+/*
+ margin: .3em .5em .5em 0;
+ border: .5em solid white;
+ border-width: .5em 1.4em .8em 0;
+*/
+}
+div.floatleft p { font-style: italic; }
+/* thumbnails */
+div.thumb {
+ margin-bottom: .5em;
+ border-style: solid;
+ border-color: white;
+ width: auto;
+}
+div.thumbinner {
+ border: 1px solid #ccc;
+ padding: 3px !important;
+ background-color: #f9f9f9;
+ font-size: 94%;
+ text-align: center;
+ overflow: hidden;
+}
+html .thumbimage {
+ border: 1px solid #ccc;
+}
+html .thumbcaption {
+ border: none;
+ text-align: left;
+ line-height: 1.4em;
+ padding: 3px !important;
+ font-size: 94%;
+}
+div.magnify {
+ float: right;
+ border: none !important;
+ background: none !important;
+}
+div.magnify a, div.magnify img {
+ display: block;
+ border: none !important;
+ background: none !important;
+}
+div.tright {
+ clear: right;
+ float: right;
+ border-width: .5em 0 .8em 1.4em;
+}
+div.tleft {
+ float: left;
+ clear: left;
+ margin-right: .5em;
+ border-width: .5em 1.4em .8em 0;
+}
+
+.hiddenStructure {
+ display: none;
+ speak: none;
+}
+img.tex {
+ vertical-align: middle;
+}
+span.texhtml {
+ font-family: serif;
+}
+
+/*
+** classes for special content elements like town boxes
+** intended to be referenced directly from the wiki src
+*/
+
+/*
+** User styles
+*/
+/* table standards */
+table.rimage {
+ float: right;
+ position: relative;
+ margin-left: 1em;
+ margin-bottom: 1em;
+ text-align: center;
+}
+.toccolours {
+ border: 1px solid #aaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+}
+div.townBox {
+ position: relative;
+ float: right;
+ background: white;
+ margin-left: 1em;
+ border: 1px solid gray;
+ padding: .3em;
+ width: 200px;
+ overflow: hidden;
+ clear: right;
+}
+div.townBox dl {
+ padding: 0;
+ margin: 0 0 .3em;
+ font-size: 96%;
+}
+div.townBox dl dt {
+ background: none;
+ margin: .4em 0 0;
+}
+div.townBox dl dd {
+ margin: .1em 0 0 1.1em;
+ background-color: #f3f3f3;
+}
+
+/*
+** edit views etc
+*/
+.special li {
+ line-height: 1.4em;
+ margin: 0;
+ padding: 0;
+}
+
+/* Page history styling */
+/* the auto-generated edit comments */
+.autocomment {
+ color: gray;
+}
+#pagehistory span.user {
+ margin-left: 1.4em;
+ margin-right: .4em;
+}
+#pagehistory span.minor {
+ font-weight: bold;
+}
+#pagehistory li {
+ border: 1px solid white;
+}
+#pagehistory li.selected {
+ background-color: #f9f9f9;
+ border: 1px dashed #aaa;
+}
+
+/*
+** Diff rendering
+*/
+table.diff, td.diff-otitle, td.diff-ntitle {
+ background-color: white;
+}
+td.diff-addedline {
+ background: #cfc;
+ font-size: smaller;
+}
+td.diff-deletedline {
+ background: #ffa;
+ font-size: smaller;
+}
+td.diff-context {
+ background: #eee;
+ font-size: smaller;
+}
+span.diffchange {
+ color: red;
+ font-weight: bold;
+}
+
+/*
+** keep the whitespace in front of the ^=, hides rule from konqueror
+** this is css3, the validator doesn't like it when validating as css2
+*/
+#bodyContent a.external,
+#bodyContent a[href ^="gopher://"] {
+ background: url(external.png) center right no-repeat;
+ padding-right: 13px;
+}
+#bodyContent a[href ^="https://"],
+.link-https {
+ background: url(lock_icon.gif) center right no-repeat;
+ padding-right: 16px;
+}
+#bodyContent a[href ^="mailto:"],
+.link-mailto {
+ background: url(mail_icon.gif) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="news://"] {
+ background: url(news_icon.png) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="ftp://"],
+.link-ftp {
+ background: url(file_icon.gif) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="irc://"],
+.link-irc {
+ background: url(discussionitem_icon.gif) center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a.external[href $=".ogg"], #bodyContent a.external[href $=".OGG"],
+#bodyContent a.external[href $=".mid"], #bodyContent a.external[href $=".MID"],
+#bodyContent a.external[href $=".midi"], #bodyContent a.external[href $=".MIDI"],
+#bodyContent a.external[href $=".mp3"], #bodyContent a.external[href $=".MP3"],
+#bodyContent a.external[href $=".wav"], #bodyContent a.external[href $=".WAV"],
+#bodyContent a.external[href $=".wma"], #bodyContent a.external[href $=".WMA"],
+.link-audio {
+ background: url("audio.png") center right no-repeat;
+ padding-right: 13px;
+}
+#bodyContent a.external[href $=".ogm"], #bodyContent a.external[href $=".OGM"],
+#bodyContent a.external[href $=".avi"], #bodyContent a.external[href $=".AVI"],
+#bodyContent a.external[href $=".mpeg"], #bodyContent a.external[href $=".MPEG"],
+#bodyContent a.external[href $=".mpg"], #bodyContent a.external[href $=".MPG"],
+.link-video {
+ background: url("video.png") center right no-repeat;
+ padding-right: 13px;
+}
+#bodyContent a.external[href $=".pdf"], #bodyContent a.external[href $=".PDF"],
+#bodyContent a.external[href *=".pdf#"], #bodyContent a.external[href *=".PDF#"],
+#bodyContent a.external[href *=".pdf?"], #bodyContent a.external[href *=".PDF?"],
+.link-document {
+ background: url("document.png") center right no-repeat;
+ padding-right: 12px;
+}
+
+/* disable interwiki styling */
+#bodyContent a.extiw,
+#bodyContent a.extiw:active {
+ color: #36b;
+ background: none;
+ padding: 0;
+}
+#bodyContent a.external {
+ color: #36b;
+}
+/* this can be used in the content area to switch off
+special external link styling */
+#bodyContent .plainlinks a {
+ background: none !important;
+ padding: 0 !important;
+}
+/*
+** Structural Elements
+*/
+
+/*
+** general portlet styles (elements in the quickbar)
+*/
+.portlet {
+ border: none;
+ margin: 0 0 .5em;
+ padding: 0;
+ float: none;
+ width: 11.6em;
+ overflow: hidden;
+}
+.portlet h4 {
+ font-size: 95%;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.portlet h5 {
+ background: transparent;
+ padding: 0 1em 0 .5em;
+ display: inline;
+ height: 1em;
+ text-transform: lowercase;
+ font-size: 91%;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.portlet h6 {
+ background: #ffae2e;
+ border: 1px solid #2f6fab;
+ border-style: solid solid none solid;
+ padding: 0 1em 0 1em;
+ text-transform: lowercase;
+ display: block;
+ font-size: 1em;
+ height: 1.2em;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.pBody {
+ font-size: 95%;
+ background-color: white;
+ color: black;
+ border-collapse: collapse;
+ border: 1px solid #aaa;
+ padding: 0 .8em .3em .5em;
+}
+.portlet h1,
+.portlet h2,
+.portlet h3,
+.portlet h4 {
+ margin: 0;
+ padding: 0;
+}
+.portlet ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ list-style-image: url(bullet.gif);
+ font-size: 95%;
+}
+.portlet li {
+ padding: 0;
+ margin: 0;
+}
+
+/*
+** Logo properties
+*/
+
+/* @media screen, projection { */
+ #p-logo {
+ top: 0;
+ left: 0;
+ position: absolute; /*needed to use z-index */
+ z-index: 3;
+ height: 155px;
+ width: 12em;
+ overflow: visible;
+ }
+ #p-logo h5 {
+ display: none;
+ }
+ #p-logo a,
+ #p-logo a:hover {
+ display: block;
+ height: 155px;
+ width: 12.2em;
+ background-repeat: no-repeat;
+ background-position: 35% 50% !important;
+ text-decoration: none;
+ }
+/* } */
+/*
+** the navigation portlet
+*/
+
+/* @media screen, projection { */
+ #p-navigation {
+ position: relative;
+ z-index: 3;
+ }
+ #p-navigation a {
+ display: block;
+ }
+ #p-navigation li.active a, #p-navigation li.active a:hover {
+ display: inline;
+ }
+/* } */
+
+#p-navigation .pBody {
+ padding-right: 0;
+}
+
+#p-navigation li.active a, #p-navigation li.active a:hover {
+ text-decoration: none;
+ font-weight: bold;
+}
+
+
+/*
+** Search portlet
+*/
+/* @media screen, projection { */
+ #p-search {
+ position: relative;
+ z-index: 3;
+ }
+/* } */
+input.searchButton {
+ margin-top: 1px;
+ font-size: 95%;
+}
+#searchGoButton {
+ padding-left: .5em;
+ padding-right: .5em;
+ font-weight: bold;
+}
+#searchInput {
+ width: 10.9em;
+ margin: 0;
+ font-size: 95%;
+}
+#p-search .pBody {
+ padding: .5em .4em .4em .4em;
+ text-align: center;
+}
+
+/*
+** the personal toolbar
+*/
+/* @media screen, projection { */
+ #p-personal {
+ position: absolute;
+ left: 0;
+ top: 0;
+ z-index: 0;
+ }
+ #p-personal {
+ width: 100%;
+ white-space: nowrap;
+ padding: 0;
+ margin: 0;
+ border: none;
+ background: none;
+ overflow: visible;
+ line-height: 1.2em;
+ }
+ #p-personal h5 {
+ display: none;
+ }
+ #p-personal .portlet,
+ #p-personal .pBody {
+ z-index: 0;
+ padding: 0;
+ margin: 0;
+ border: none;
+ overflow: visible;
+ background: none;
+ }
+/* this is the ul contained in the portlet */
+ #p-personal ul {
+ border: none;
+ line-height: 1.4em;
+ color: #2f6fab;
+ padding: 0 2em 0 3em;
+ margin: 0;
+ text-align: right;
+ list-style: none;
+ z-index: 0;
+ background: none;
+ cursor: default;
+ }
+ #p-personal li {
+ z-index: 0;
+ border: none;
+ padding: 0;
+ display: inline;
+ color: #2f6fab;
+ margin-left: 1em;
+ line-height: 1.2em;
+ background: none;
+ }
+ #p-personal li a {
+ text-decoration: none;
+ color: #005896;
+ padding-bottom: .2em;
+ background: none;
+ }
+ #p-personal li a:hover {
+ background-color: white;
+ padding-bottom: .2em;
+ text-decoration: none;
+ }
+ #p-personal li.active a:hover {
+ background-color: transparent;
+ }
+ /* the icon in front of the user name, single quotes
+ in bg url to hide it from iemac */
+ li#pt-userpage,
+ li#pt-anonuserpage,
+ li#pt-login {
+ background: url(user.gif) top left no-repeat;
+ padding-left: 20px;
+ text-transform: none;
+ }
+/* } */
+#p-personal ul {
+ text-transform: lowercase;
+}
+#p-personal li.active {
+ font-weight: bold;
+}
+/*
+** the page-related actions- page/talk, edit etc
+*/
+/* @media screen, projection { */
+ #p-cactions {
+ position: absolute;
+ top: 1.3em;
+ left: 11.5em;
+ margin: 0;
+ white-space: nowrap;
+ width: 76%;
+ line-height: 1.1em;
+ overflow: visible;
+ background: none;
+ border-collapse: collapse;
+ padding-left: 1em;
+ list-style: none;
+ font-size: 95%;
+ }
+ #p-cactions ul {
+ list-style: none;
+ }
+ #p-cactions li {
+ display: inline;
+ border: 1px solid #aaa;
+ border-bottom: none;
+ padding: 0 0 .1em 0;
+ margin: 0 .3em 0 0;
+ overflow: visible;
+ background: white;
+ }
+ #p-cactions li.selected {
+ border-color: #fabd23;
+ padding: 0 0 .2em 0;
+ font-weight: bold;
+ }
+ #p-cactions li a {
+ background-color: #fbfbfb;
+ color: #002bb8;
+ border: none;
+ padding: 0 .8em .3em;
+ position: relative;
+ z-index: 0;
+ margin: 0;
+ text-decoration: none;
+ }
+ #p-cactions li.selected a {
+ z-index: 3;
+ padding: 0 1em .2em!important;
+ background-color: white;
+ }
+ #p-cactions .new a {
+ color: #ba0000;
+ }
+ #p-cactions li a:hover {
+ z-index: 3;
+ text-decoration: none;
+ background-color: white;
+ }
+ #p-cactions h5 {
+ display: none;
+ }
+ #p-cactions li.istalk {
+ margin-right: 0;
+ }
+ #p-cactions li.istalk a {
+ padding-right: .5em;
+ }
+ #p-cactions #ca-addsection a {
+ padding-left: .4em;
+ padding-right: .4em;
+ }
+ /* offsets to distinguish the tab groups */
+ li#ca-talk {
+ margin-right: 1.6em;
+ }
+ li#ca-watch, li#ca-unwatch, li#ca-varlang-0, li#ca-print {
+ margin-left: 1.6em;
+ }
+ #p-cactions .pBody {
+ font-size: 1em;
+ background-color: transparent;
+ color: inherit;
+ border-collapse: inherit;
+ border: 0;
+ padding: 0;
+ }
+/* } */
+#p-cactions .hiddenStructure {
+ display: none;
+}
+#p-cactions li a {
+ text-transform: lowercase;
+}
+
+/*
+** the remaining portlets
+*/
+/* @media screen, projection { */
+ #p-tbx,
+ #p-lang {
+ position: relative;
+ z-index: 3;
+ }
+/* } */
+
+/* TODO: #t-iscite is only used by the Cite extension, come up with some
+ * system which allows extensions to add to this file on the fly
+ */
+#t-ispermalink, #t-iscite {
+ color: #999;
+}
+/*
+** footer
+*/
+#footer {
+ background-color: white;
+ border-top: 1px solid #fabd23;
+ border-bottom: 1px solid #fabd23;
+ margin: .6em 0 1em 0;
+ padding: .4em 0 1.2em 0;
+ text-align: center;
+ font-size: 90%;
+}
+#footer li {
+ display: inline;
+ margin: 0 1.3em;
+}
+/* hide from incapable browsers */
+head:first-child+body #footer li { white-space: nowrap; }
+#f-poweredbyico, #f-copyrightico {
+ margin: 0 8px;
+ position: relative;
+ top: -2px; /* Bump it up just a tad */
+}
+#f-poweredbyico {
+ float: right;
+ height: 1%;
+}
+#f-copyrightico {
+ float: left;
+ height: 1%;
+}
+
+/* js pref toc */
+#preftoc {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ clear: both;
+}
+#preftoc li {
+ background-color: #f0f0f0;
+ color: #000;
+}
+/* @media screen, projection { */
+ #preftoc li {
+ margin: 1px -2px 1px 2px;
+ float: left;
+ padding: 2px 0 3px 0;
+ border: 1px solid #fff;
+ border-right-color: #716f64;
+ border-bottom: 0;
+ position: relative;
+ white-space: nowrap;
+ list-style-type: none;
+ list-style-image: none;
+ z-index: 3;
+ }
+/* } */
+#preftoc li.selected {
+ font-weight: bold;
+ background-color: #f9f9f9;
+ border: 1px solid #aaa;
+ border-bottom: none;
+ cursor: default;
+ top: 1px;
+ padding-top: 2px;
+ margin-right: -3px;
+}
+#preftoc > li.selected {
+ top: 2px;
+}
+#preftoc a,
+#preftoc a:active {
+ display: block;
+ color: #000;
+ padding: 0 .7em;
+ position: relative;
+ text-decoration: none;
+}
+#preftoc li.selected a {
+ cursor: default;
+ text-decoration: none;
+}
+#prefcontrol {
+ padding-top: 2em;
+ clear: both;
+}
+#preferences {
+ margin: 0;
+ border: 1px solid #aaa;
+ clear: both;
+ padding: 1.5em;
+ background-color: #F9F9F9;
+}
+.prefsection {
+ border: none;
+ padding: 0;
+ margin: 0;
+}
+.prefsection fieldset {
+ border: 1px solid #aaa;
+ float: left;
+ margin-right: 2em;
+}
+.prefsection legend {
+ font-weight: bold;
+}
+.prefsection table, .prefsection legend {
+ background-color: #F9F9F9;
+}
+/* @media screen, projection { */
+ .mainLegend {
+ display: none;
+ }
+/* } */
+div.prefsectiontip {
+ font-size: 95%;
+ margin-top: 0;
+ background-color: #FFC1C1;
+ padding: .2em .7em;
+ clear: both;
+}
+.btnSavePrefs {
+ font-weight: bold;
+ padding-left: .3em;
+ padding-right: .3em;
+}
+
+.preferences-login {
+ clear: both;
+ margin-bottom: 1.5em;
+}
+
+.prefcache {
+ font-size: 90%;
+ margin-top: 2em;
+}
+
+div#userloginForm form,
+div#userlogin form#userlogin2 {
+ margin: 0 3em 1em 0;
+ border: 1px solid #aaa;
+ clear: both;
+ padding: 1.5em 2em;
+ background-color: #f9f9f9;
+ float: left;
+}
+
+div#userloginForm table,
+div#userlogin form#userlogin2 table {
+ background-color: #f9f9f9;
+}
+
+div#userloginForm h2,
+div#userlogin form#userlogin2 h2 {
+ padding-top: 0;
+}
+
+div#userlogin .captcha {
+ border: 1px solid #bbb;
+ padding: 1.5em 2em;
+ width: 400px;
+ background-color: white;
+}
+
+
+#userloginprompt, #languagelinks {
+ font-size: 85%;
+}
+
+#login-sectiontip {
+ font-size: 85%;
+ line-height: 1.2;
+ padding-top: 2em;
+}
+
+#userlogin .loginText, #userlogin .loginPassword {
+ width: 12em;
+}
+
+#userloginlink a, #wpLoginattempt, #wpCreateaccount {
+ font-weight: bold;
+}
+
+/* @media screen, projection { */
+ /*
+ ** IE/Mac fixes, hope to find a validating way to move this
+ ** to a separate stylesheet. This would work but doesn't validate:
+ ** @import("IEMacFixes.css");
+ */
+ /* tabs: border on the a, not the div */
+ * > html #p-cactions li { border: none; }
+ * > html #p-cactions li a {
+ border: 1px solid #aaa;
+ border-bottom: none;
+ }
+ * > html #p-cactions li.selected a { border-color: #fabd23; }
+ /* footer icons need a fixed width */
+ * > html #f-poweredbyico,
+ * > html #f-copyrightico { width: 88px; }
+ * > html #bodyContent,
+ * > html #bodyContent pre {
+ overflow-x: auto;
+ width: 100%;
+ padding-bottom: 25px;
+ }
+/* } */
+
+/* more IE fixes */
+/* float/negative margin brokenness */
+* html #footer {margin-top: 0;}
+* html #column-content {
+ display: inline;
+ margin-bottom: 0;
+}
+* html div.editsection { font-size: smaller; }
+#pagehistory li.selected { position: relative; }
+
+/* Mac IE 5.0 fix; floated content turns invisible */
+* > html #column-content {
+ float: none;
+}
+* > html #column-one {
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+* > html #footer {
+ margin-left: 13.2em;
+}
+.redirectText {
+ font-size: 150%;
+ margin: 5px;
+}
+
+.printfooter {
+ display: none;
+}
+
+.not-patrolled {
+ background-color: #ffa;
+}
+div.patrollink {
+ font-size: 75%;
+ text-align: right;
+}
+span.newpage, span.minor, span.searchmatch, span.bot {
+ font-weight: bold;
+}
+span.unpatrolled {
+ font-weight: bold;
+ color: red;
+}
+
+span.searchmatch {
+ color: red;
+}
+.sharedUploadNotice {
+ font-style: italic;
+}
+
+span.updatedmarker {
+ color: black;
+ background-color: #0f0;
+}
+span.newpageletter {
+ font-weight: bold;
+ color: black;
+ background-color: yellow;
+}
+span.minoreditletter {
+ color: black;
+ background-color: #c5ffe6;
+}
+
+table.gallery {
+ border: 1px solid #ccc;
+ margin: 2px;
+ padding: 2px;
+ background-color: white;
+}
+
+table.gallery tr {
+ vertical-align: top;
+}
+
+table.gallery td {
+ vertical-align: top;
+ background-color: #f9f9f9;
+ border: solid 2px white;
+}
+
+table.gallery td.galleryheader {
+ text-align: center;
+ font-weight: bold;
+}
+
+div.gallerybox {
+ margin: 2px;
+ width: 150px;
+}
+
+div.gallerybox div.thumb {
+ text-align: center;
+ border: 1px solid #ccc;
+ margin: 2px;
+}
+
+div.gallerytext {
+ font-size: 94%;
+ padding: 2px 4px;
+}
+
+span.comment {
+ font-style: italic;
+}
+
+span.changedby {
+ font-size: 95%;
+}
+
+.previewnote {
+ text-indent: 3em;
+ color: #c00;
+ border-bottom: 1px solid #aaa;
+ padding-bottom: 1em;
+ margin-bottom: 1em;
+}
+
+.previewnote p {
+ margin: 0;
+ padding: 0;
+}
+
+.editExternally {
+ border: 1px solid gray;
+ background-color: #ffffff;
+ padding: 3px;
+ margin-top: 0.5em;
+ float: left;
+ font-size: small;
+ text-align: center;
+}
+.editExternallyHelp {
+ font-style: italic;
+ color: gray;
+}
+
+li span.deleted, span.history-deleted {
+ text-decoration: line-through;
+ color: #888;
+ font-style: italic;
+}
+
+.toggle {
+ margin-left: 2em;
+ text-indent: -2em;
+}
+
+/* Classes for EXIF data display */
+table.mw_metadata {
+ font-size: 0.8em;
+ margin-left: 0.5em;
+ margin-bottom: 0.5em;
+ width: 300px;
+}
+
+table.mw_metadata caption {
+ font-weight: bold;
+}
+
+table.mw_metadata th {
+ font-weight: normal;
+}
+
+table.mw_metadata td {
+ padding: 0.1em;
+}
+
+table.mw_metadata {
+ border: none;
+ border-collapse: collapse;
+}
+
+table.mw_metadata td, table.mw_metadata th {
+ text-align: center;
+ border: 1px solid #aaaaaa;
+ padding-left: 0.1em;
+ padding-right: 0.1em;
+}
+
+table.mw_metadata th {
+ background-color: #f9f9f9;
+}
+
+table.mw_metadata td {
+ background-color: #fcfcfc;
+}
+
+table.collapsed tr.collapsable {
+ display: none;
+}
+
+
+/* filetoc */
+ul#filetoc {
+ text-align: center;
+ border: 1px solid #aaaaaa;
+ background-color: #f9f9f9;
+ padding: 5px;
+ font-size: 95%;
+ margin-bottom: 0.5em;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+#filetoc li {
+ display: inline;
+ list-style-type: none;
+ padding-right: 2em;
+}
+
+input#wpSummary {
+ width: 80%;
+}
+
+/* @bug 1714 */
+input#wpSave, input#wpDiff {
+ margin-right: 0.33em;
+}
+
+#editform .editOptions {
+ display: inline;
+}
+
+#wpSave {
+ font-weight: bold;
+}
+
+/* Classes for article validation */
+
+table.revisionform_default {
+ border: 1px solid #000000;
+}
+
+table.revisionform_focus {
+ border: 1px solid #000000;
+ background-color:#00BBFF;
+}
+
+tr.revision_tr_default {
+ background-color:#EEEEEE;
+}
+
+tr.revision_tr_first {
+ background-color:#DDDDDD;
+}
+
+p.revision_saved {
+ color: green;
+ font-weight:bold;
+}
+
+#mw_trackbacks {
+ border: solid 1px #bbbbff;
+ background-color: #eeeeff;
+ padding: 0.2em;
+}
+
+
+/* Allmessages table */
+
+#allmessagestable th {
+ background-color: #b2b2ff;
+}
+
+#allmessagestable tr.orig {
+ background-color: #ffe2e2;
+}
+
+#allmessagestable tr.new {
+ background-color: #e2ffe2;
+}
+
+#allmessagestable tr.def {
+ background-color: #f0f0ff;
+}
+
+
+/* noarticletext */
+div.noarticletext {
+ border: 1px solid #ccc;
+ background: #fff;
+ padding: .2em 1em;
+ color: #000;
+}
+
+div#searchTargetContainer {
+ left: 10px;
+ top: 10px;
+ width: 90%;
+ background: white;
+}
+
+div#searchTarget {
+ padding: 3px;
+ margin: 5px;
+ background: #F0F0F0;
+ border: solid 1px blue;
+}
+
+div#searchTarget ul li {
+ list-style: none;
+}
+
+div#searchTarget ul li:before {
+ color: orange;
+ content: "\00BB \0020";
+}
+
+div.multipageimagenavbox {
+ border: solid 1px silver;
+ padding: 4px;
+ margin: 1em;
+ -moz-border-radius: 6px;
+ background: #f0f0f0;
+}
+
+div.multipageimagenavbox div.thumb {
+ border: none;
+ margin-left: 2em;
+ margin-right: 2em;
+}
+
+div.multipageimagenavbox hr {
+ margin: 6px;
+}
+
+table.multipageimage td {
+ text-align: center;
+}
+
+/** Special:Version */
+
+table#sv-ext, table#sv-hooks {
+ margin: 1em;
+ padding:0em;
+}
+
+#sv-ext td, #sv-hooks td,
+#sv-ext th, #sv-hooks th {
+ border: 1px solid #A0A0A0;
+ padding: 0 0.15em 0 0.15em;
+}
+#sv-ext th, #sv-hooks th {
+ background-color: #F0F0F0;
+ color: black;
+ padding: 0 0.15em 0 0.15em;
+}
+tr.sv-space{
+ height: 0.8em;
+ border:none;
+}
+tr.sv-space td { display: none; }
+
+/*
+ Table pager (e.g. Special:Imagelist)
+ - remove underlines from the navigation link
+ - collapse borders
+ - set the borders to outsets (similar to Special:Allmessages)
+ - remove line wrapping for all td and th, set background color
+ - restore line wrapping for the last two table cells (description and size)
+*/
+.TablePager_nav a { text-decoration: none; }
+.TablePager { border-collapse: collapse; }
+.TablePager, .TablePager td, .TablePager th {
+ border: 0.15em solid #777777;
+ padding: 0 0.15em 0 0.15em;
+}
+.TablePager th { background-color: #eeeeff }
+.TablePager td { background-color: #ffffff }
+.TablePager tr:hover td { background-color: #eeeeff }
+
+.imagelist td, .imagelist th { white-space: nowrap }
+.imagelist .TablePager_col_links { background-color: #eeeeff }
+.imagelist .TablePager_col_img_description { white-space: normal }
+.imagelist th.TablePager_sort { background-color: #ccccff }
+
+.templatesUsed { margin-top: 1.5em; }
+
+.mw-summary-preview {
+ margin: 0.1em 0;
+}
+#toolbar { clear: both; }
+
+.mw-plusminus-null { color: #aaa; } \ No newline at end of file
diff --git a/skins/monobook/news_icon.png b/skins/monobook/news_icon.png
new file mode 100644
index 000000000000..dd1541d13c18
--- /dev/null
+++ b/skins/monobook/news_icon.png
Binary files differ
diff --git a/skins/monobook/required.gif b/skins/monobook/required.gif
new file mode 100644
index 000000000000..bd7197698e1c
--- /dev/null
+++ b/skins/monobook/required.gif
Binary files differ
diff --git a/skins/monobook/rtl.css b/skins/monobook/rtl.css
new file mode 100644
index 000000000000..f4a67683ca1d
--- /dev/null
+++ b/skins/monobook/rtl.css
@@ -0,0 +1,216 @@
+/*
+Right-to-left fixes for MonoBook.
+Places sidebar on right, tweaks various alignment issues.
+
+Works mostly ok nicely on Safari 1.2.1; fine in Mozilla.
+
+Safari bugs (1.2.1):
+* Tabs are still appearing in left-to-right order. (Try after localizing)
+
+Opera bugs (7.23 linux):
+* Some bits of ltr text (sidebar box titles) have forward and backward versions overlapping each other
+
+IE/mac bugs:
+* The thing barfs on Hebrew and Arabic anyway, so no point testing.
+
+Missing features due to lack of support:
+* external link icons
+
+To test:
+* Opera6
+* IE 5.0
+* etc
+
+*/
+body {
+ direction: rtl;
+/* unicode-bidi: bidi-override;*/
+ unicode-bidi: embed;
+}
+#column-content {
+ margin: 0 -12.2em 0 0;
+ float: left;
+}
+#column-content #content{
+ margin-left: 0;
+ margin-right: 12.2em;
+ border-right: 1px solid #aaaaaa;
+ border-left: none;
+}
+html>body .portlet {
+ float: right;
+ clear: right;
+}
+.editsection {
+ float: left;
+ margin-right: 5px;
+}
+/* recover IEMac (might be fine with the float, but usually it's close to IE */
+*>body .portlet {
+ float: none;
+ clear: none;
+}
+.pBody {
+ padding-right: 0.8em;
+ padding-left: 0.5em;
+}
+
+/* Fix alignment */
+.documentByLine,
+.portletDetails,
+.portletMore,
+#p-personal {
+ text-align: left;
+}
+
+div div.thumbcaption {
+ text-align: right;
+}
+
+div.magnify,
+#div.townBox,
+#p-logo {
+ left: auto;
+ right: 0;
+}
+#p-personal {
+ left: auto;
+ right: 0;
+}
+
+#p-cactions {
+ left: auto;
+ right: 11.5em;
+ padding-left: 0;
+ padding-right: 1em;
+}
+#p-cactions li {
+ margin-left: 0.3em;
+ margin-right: 0;
+ float: right;
+}
+* html #p-cactions li a {
+ display: block;
+ padding-bottom: 0;
+}
+* html #p-cactions li a:hover {
+ padding-bottom: 0.2em;
+}
+/* offsets to distinguish the tab groups */
+li#ca-talk {
+ margin-right: auto;
+ margin-left: 1.6em;
+}
+li#ca-watch,li#ca-unwatch {
+ margin-right: 1.6em !important;
+}
+
+/* Fix margins for non-css2 browsers */
+/* top right bottom left */
+
+ul {
+ margin-left: 0;
+ margin-right: 1.5em;
+}
+ol {
+ margin-left: 0;
+ margin-right: 2.4em;
+}
+dd {
+ margin-left: 0;
+ margin-right: 1.6em;
+}
+#contentSub {
+ margin-right: 1em;
+ margin-left: 0;
+}
+.tocindent {
+ margin-left: 0;
+ margin-right: 2em;
+}
+div.tright, div.floatright, table.floatright {
+ clear: none;
+}
+div.tleft, div.floatleft, table.floatleft {
+ clear: left;
+}
+div.townBox {
+ margin-left: 0;
+ margin-right: 1em;
+}
+div.townBox dl dd {
+ margin-left: 0;
+ margin-right: 1.1em;
+}
+#p-personal li {
+ margin-left: 0;
+ margin-right: 1em;
+}
+
+li#ca-talk,
+li#ca-watch {
+ margin-right: auto;
+ margin-left: 1.6em;
+}
+
+#p-personal li {
+ float: left;
+}
+/* Fix link icons */
+.external {
+ padding: 0 !important;
+ background: none !important;
+}
+#footer {
+ clear: both;
+}
+* html #footer {
+ margin-left: 0;
+ margin-right: 13.6em;
+ border-left: 0;
+ border-right: 1px solid #fabd23;
+}
+* html #column-content {
+ float: none;
+ margin-left: 0;
+ margin-right: 0;
+}
+* html #column-content #content {
+ margin-left: 0;
+ margin-top: 3em;
+}
+* html #column-one { right: 0; }
+
+/* js pref toc */
+
+#preftoc {
+ margin-right: 1em;
+}
+
+.errorbox, .successbox, #preftoc li, .prefsection fieldset {
+ float: right;
+}
+
+.prefsection {
+ padding-right: 2em;
+}
+
+/* workaround for moz bug, displayed bullets on left side */
+
+#toc ul {
+ text-align: right;
+}
+
+#toc ul ul {
+ margin: 0 2em 0 0;
+}
+
+input#wpSave, input#wpDiff {
+ margin-right: 0;
+ margin-left: .33em;
+}
+
+#userlogin {
+ float: right;
+ margin: 0 0 1em 3em;
+}
diff --git a/skins/monobook/user.gif b/skins/monobook/user.gif
new file mode 100644
index 000000000000..bc9343960fe6
--- /dev/null
+++ b/skins/monobook/user.gif
Binary files differ
diff --git a/skins/monobook/video.png b/skins/monobook/video.png
new file mode 100644
index 000000000000..38103dac285e
--- /dev/null
+++ b/skins/monobook/video.png
Binary files differ
diff --git a/skins/monobook/wiki-indexed.png b/skins/monobook/wiki-indexed.png
new file mode 100644
index 000000000000..189a2ae3d772
--- /dev/null
+++ b/skins/monobook/wiki-indexed.png
Binary files differ
diff --git a/skins/monobook/wiki.png b/skins/monobook/wiki.png
new file mode 100644
index 000000000000..69fce98855c2
--- /dev/null
+++ b/skins/monobook/wiki.png
Binary files differ
diff --git a/skins/myskin/main.css b/skins/myskin/main.css
new file mode 100644
index 000000000000..f3ab020480a6
--- /dev/null
+++ b/skins/myskin/main.css
@@ -0,0 +1 @@
+/* this file must be empty */
diff --git a/skins/simple/discussionitem_icon.gif b/skins/simple/discussionitem_icon.gif
new file mode 100644
index 000000000000..baec471afc09
--- /dev/null
+++ b/skins/simple/discussionitem_icon.gif
Binary files differ
diff --git a/skins/simple/external.png b/skins/simple/external.png
new file mode 100644
index 000000000000..419c06fb960b
--- /dev/null
+++ b/skins/simple/external.png
Binary files differ
diff --git a/skins/simple/file_icon.gif b/skins/simple/file_icon.gif
new file mode 100644
index 000000000000..847f6485efb4
--- /dev/null
+++ b/skins/simple/file_icon.gif
Binary files differ
diff --git a/skins/simple/link_icon.gif b/skins/simple/link_icon.gif
new file mode 100644
index 000000000000..815ccb1b1ca0
--- /dev/null
+++ b/skins/simple/link_icon.gif
Binary files differ
diff --git a/skins/simple/lock_icon.gif b/skins/simple/lock_icon.gif
new file mode 100644
index 000000000000..8a87e2833069
--- /dev/null
+++ b/skins/simple/lock_icon.gif
Binary files differ
diff --git a/skins/simple/mail_icon.gif b/skins/simple/mail_icon.gif
new file mode 100644
index 000000000000..50a87a9a0689
--- /dev/null
+++ b/skins/simple/mail_icon.gif
Binary files differ
diff --git a/skins/simple/main.css b/skins/simple/main.css
new file mode 100644
index 000000000000..e474f436a6f5
--- /dev/null
+++ b/skins/simple/main.css
@@ -0,0 +1,442 @@
+/* For clarity, explicitly state some recommendations from <http://www.w3.org/
+ TR/CSS21/sample.html> to make sure the editsection links scale right */
+
+h1 { font-size: 2em; }
+h2 { font-size: 1.5em; }
+h3 { font-size: 1.17em; }
+h5 { font-size: .83em; }
+h6 { font-size: .75em; }
+h1, h2, h3, h4, h5, h6 { font-weight: bolder }
+
+/* Now the custom parts */
+
+/* Make edit sections (which are inside h# tags) normal-sized
+ and otherwise format */
+.editsection {
+ font-weight: normal;
+ float: right;
+ margin-left: 5px;
+}
+h1 .editsection { font-size: 50% }
+h2 .editsection { font-size: 66.7% }
+h3 .editsection { font-size: 85.5% }
+h5 .editsection { font-size: 120% }
+h6 .editsection { font-size: 133% }
+
+
+#toolbar {
+ display: none;
+}
+
+div.center {
+ text-align: center;
+}
+
+#contentSub {
+ padding-left: 2em;
+}
+
+a {
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+#column-content {
+ width: 100%;
+ float: right;
+ margin: 0 0 0.6em -12.2em;
+ padding:0;
+}
+
+#content {
+ margin: 0em 0 0 12.2em;
+ padding: 0em 1em 1.5em 1em;
+ border-left: 1px solid #959595;
+ line-height: 1.5em;
+}
+
+#column-one {
+ position: absolute;
+ top: 0px; left: 0px;
+}
+
+#footer {
+ display: none;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+#globalWrapper {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+.visualClear { clear: both; }
+
+img {
+ border: none;
+}
+p {
+ margin: 0.4em 0em 0.5em 0em;
+ line-height: 1.5em;
+}
+p img { margin: 0; }
+
+h1, h2, h3, h4, h5, h6 {
+ margin: 0;
+ padding-top: 0.5em;
+ padding-bottom: 0.17em;
+}
+fieldset {
+ margin: 1em 0em 1em 0em;
+ padding: 0em 1em 1em 1em;
+}
+.usermessage {
+ background-color: #ffce7b;
+ border: 1px solid #ffa500;
+ color: Black;
+ font-weight: bold;
+ margin: 2em 0em 1em 0em;
+ padding: 0.5em 1em;
+ vertical-align: middle;
+}
+.error {
+ color: red;
+ font-size: larger;
+}
+
+table.rimage {
+ float:right;
+ position:relative;
+ margin-left:1em;
+ margin-bottom:1em;
+ text-align:center;
+}
+
+div.townBox {
+ position:relative;
+ float:right;
+ margin-left:1em;
+ padding:0.3em;
+ width: 200px;
+ overflow: hidden;
+ clear: right;
+}
+div.townBox dl {
+ padding: 0;
+ margin: 0 0 0.3em 0;
+}
+div.townBox dl dt {
+ background: none;
+ margin: 0.4em 0 0 0;
+}
+div.townBox dl dd {
+ margin: 0.1em 0 0 1.1em;
+}
+.portlet {
+ border: none;
+ float: none;
+ padding: 0;
+ width: 11.8em;
+ overflow: hidden;
+}
+.portlet h4 {
+ font-weight: normal;
+ white-space: nowrap;
+}
+.portlet h5 {
+ padding: 0em 1em 0em 0.5em;
+ display: inline;
+ height: 1em;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.portlet h6 {
+ padding: 0em 1em 0em 1em;
+ display: block;
+ height: 1.2em;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.pBody {
+ border-collapse: collapse;
+ padding: 0 0.8em 0.3em 0.5em;
+}
+.portlet h1,
+.portlet h2,
+.portlet h3,
+.portlet h4 {
+ margin: 0;
+ padding: 0;
+ font-size: small;
+}
+
+#p-search .pBody {
+ text-align: center;
+}
+
+#searchInput {
+ width: 100%;
+ clear: both;
+ margin: 0 0 0 0;
+}
+
+input.searchButton {
+ margin-top:1px;
+ padding: 0 0.4em;
+ cursor: pointer;
+}
+
+#p-search .pBody {
+ padding: 0.5em 0.4em 0.4em 0.4em;
+}
+
+textarea {
+ width: 100%;
+}
+
+#p-personal li, #p-personal ul,
+#p-tb li, #p-tb ul,
+#p-navigation li, #p-navigation ul,
+#p-cactions li, #p-cactions ul,
+#p-newlinks li, #p-newlinks ul {
+ padding-left: 0em;
+ margin-left: 0.5em;
+}
+
+#p-cactions li, #p-cactions ul {
+ margin-left: 0.7em;
+}
+
+pre {
+ margin: 2em;
+ border: solid 1px black;
+}
+
+h1.firstHeading, h2 {
+ border-bottom: solid 1px black;
+}
+#bodyContent a[href ^="http://"],
+#bodyContent a[href ^="gopher://"] {
+ background: url("external.png") center right no-repeat;
+ padding-right: 13px;
+}
+#bodyContent a[href ^="https://"],
+.link-https {
+ background: url("lock_icon.gif") center right no-repeat;
+ padding-right: 16px;
+}
+#bodyContent a[href ^="mailto:"],
+.link-mailto {
+ background: url("mail_icon.gif") center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="news://"] {
+ background: url("news_icon.png") center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="ftp://"],
+.link-ftp {
+ background: url("file_icon.gif") center right no-repeat;
+ padding-right: 18px;
+}
+#bodyContent a[href ^="irc://"],
+.link-irc {
+ background: url("discussionitem_icon.gif") center right no-repeat;
+ padding-right: 18px;
+}
+
+#bodyContent a.extiw,
+#bodyContent a.extiw:active {
+ color: #5E7CFF;
+ background: none;
+ padding: 0;
+}
+
+td.diff-addedline {
+ background-color: #B9FFB0;
+}
+
+td.diff-deletedline {
+ background-color: #f8ffaa;
+}
+
+span.diffchange { background-color: #FFCDF3; }
+.autocomment { color: grey; }
+#pagehistory span.user {
+ margin-left: 1.4em;
+ margin-right: 0.4em;
+}
+#pagehistory span.minor { font-weight: bold; }
+#pagehistory li.selected {
+ background-color:#f9f9f9;
+ border:1px dashed #aaaaaa;
+}
+span.urlexpansion {
+ display: none;
+}
+
+div.tocindent {
+ margin-left: 2em;
+}
+#toc {
+ text-align: left;
+ border-top: solid 1px black;
+ border-bottom: solid 1px black;
+}
+
+div.floatright, table.floatright {
+ clear: right;
+ float: right;
+ margin: 0;
+ position: relative;
+ border-width: 0.5em 0 0.8em 1.4em;
+}
+div.floatright p { font-style: italic; }
+div.floatleft, table.floatleft {
+ float: left;
+ clear: left;
+ margin: 0.3em 0.5em 0.5em 0;
+ position: relative;
+ border-width: 0.5em 1.4em 0.8em 0;
+}
+div.floatleft p { font-style: italic; }
+/* thumbnails */
+div.thumb {
+ margin-bottom: 0.5em;
+ width: auto;
+}
+div.thumb div {
+ padding: 3px !important;
+ text-align: center;
+ overflow: hidden;
+}
+
+div.thumb div div.thumbcaption {
+ border: none;
+ text-align: left;
+ line-height: 1.4;
+ padding: 0.3em 0 0.1em 0;
+}
+div.magnify {
+ float: right;
+ border: none !important;
+ background: none !important;
+}
+div.magnify a, div.magnify img {
+ display: block;
+ border: none !important;
+ background: none !important;
+}
+div.tright {
+ clear: right;
+ float: right;
+ border-width: 0.5em 0 0.8em 1.4em;
+}
+div.tleft {
+ float: left;
+ clear: left;
+ margin-right:0.5em;
+ border-width: 0.5em 1.4em 0.8em 0;
+}
+
+a.stub { color: #772233; }
+a.new,
+#p-personal a.new {
+ text-decoration: line-through;
+}
+li.new {
+ text-decoration: line-through;
+}
+p.catlinks {
+ text-align: center;
+ width: 80%;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 3px;
+}
+
+#mytabs {
+ background-color: inherit;
+}
+#p-cactions {
+ background-color: inherit;
+}
+div.printfooter {
+ display: none;
+}
+
+
+#ca-addsection a:before {
+ content: "Add section";
+ font-size: 10pt;
+}
+
+#ca-addsection a {
+ font-size: 0px;
+}
+
+#n-portal,
+#n-currentevents,
+#n-help,
+#n-sitesupport {
+ display: none;
+}
+
+span.searchmatch {
+ font-weight: bold;
+}
+
+#preftoc {
+ float: left;
+ margin: 1em;
+ width: 13em;
+}
+#preftoc li {
+}
+#preftoc li.selected {
+ border: 1px dashed #aaa;
+}
+#preftoc a,
+#preftoc a:active {
+ display: block;
+}
+#prefcontrol {
+ clear: both;
+ float: left;
+ margin-top: 1em;
+}
+div.prefsectiontip {
+ font-size: 95%;
+ margin-top: 1em;
+}
+
+#mw_trackbacks {
+ border-style: groove;
+ padding: 0.2em;
+}
+
+#jump-to-nav {
+ display: none;
+}
+
+table.collapsed tr.collapsable {
+ display: none;
+}
+
+.editsection {
+ float: right;
+ margin-left: 5px;
+}
+
+.templatesUsed { margin-top: 1.5em; }
+#toolbar { clear: both; }
+
+.mw-plusminus-null { color: #aaa; } \ No newline at end of file
diff --git a/t/00-test.t b/t/00-test.t
new file mode 100644
index 000000000000..c3defa404a6e
--- /dev/null
+++ b/t/00-test.t
@@ -0,0 +1,8 @@
+#!/usr/bin/env php
+<?php
+require 'Test.php';
+
+plan(1);
+
+ok(0 == 0);
+?>
diff --git a/t/README b/t/README
new file mode 100644
index 000000000000..3141f2c65831
--- /dev/null
+++ b/t/README
@@ -0,0 +1,10 @@
+=head1 NAME
+
+F<t> - MediaWiki test tree
+
+=head1 DESCRIPTION
+
+This is the MediaWiki test tree (well, one of them), tests here
+produce TAP output, see L<TAP>.
+
+=cut
diff --git a/t/inc/IP.t b/t/inc/IP.t
new file mode 100644
index 000000000000..eb4978b932d0
--- /dev/null
+++ b/t/inc/IP.t
@@ -0,0 +1,60 @@
+#!/usr/bin/env php
+<?php
+
+require 'Test.php';
+
+plan( 1120 );
+
+require_ok( 'includes/IP.php' );
+
+# some of this test data was taken from Data::Validate::IP
+
+#
+# isValid()
+#
+
+foreach ( range( 0, 255 ) as $i ) {
+ $a = sprintf( "%03d", $i );
+ $b = sprintf( "%02d", $i );
+ $c = sprintf( "%01d", $i );
+ foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
+ $ip = "$f.$f.$f.$f";
+ ok( IP::isValid( $ip ), "$ip is a valid IPv4 address" );
+ }
+}
+
+# A bit excessive perhaps? meh..
+foreach ( range( 256, 999 ) as $i ) {
+ $a = sprintf( "%03d", $i );
+ $b = sprintf( "%02d", $i );
+ $c = sprintf( "%01d", $i );
+ foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
+ $ip = "$f.$f.$f.$f";
+ ok( ! IP::isValid( $ip ), "$ip is not a valid IPv4 address" );
+ }
+}
+
+$invalid = array(
+ 'www.xn--var-xla.net',
+ '216.17.184.G',
+ '216.17.184.1.',
+ '216.17.184',
+ '216.17.184.',
+ '256.17.184.1'
+);
+
+foreach ( $invalid as $i ) {
+ ok( ! IP::isValid( $i ), "$i is an invalid IPv4 address" );
+}
+
+#
+# isPublic()
+#
+
+$private = array( '10.0.0.1', '172.16.0.1', '192.168.0.1' );
+
+foreach ( $private as $p ) {
+ ok( ! IP::isPublic( $p ), "$p is not a public IP address" );
+}
+
+?>
diff --git a/t/inc/Licenses.t b/t/inc/Licenses.t
new file mode 100644
index 000000000000..86202bd67094
--- /dev/null
+++ b/t/inc/Licenses.t
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+<?php
+require 'Test.php';
+
+plan(3);
+
+error_reporting( E_ALL );
+
+define( 'MEDIAWIKI', 1 ); // Hack
+
+require_ok( 'languages/Language.php' );
+require_ok( 'includes/GlobalFunctions.php' );
+require_ok( 'includes/Licenses.php' );
+
+$str = "
+* Free licenses:
+** GFLD|Debian disagrees
+";
+
+#$lc = new Licenses ( $str );
+
+#isa_ok( $lc, 'Licenses' );
+
+#echo $lc->html;
+
+
+
+
+?> \ No newline at end of file
diff --git a/t/inc/Sanitizer.t b/t/inc/Sanitizer.t
new file mode 100644
index 000000000000..812cebc9d8f2
--- /dev/null
+++ b/t/inc/Sanitizer.t
@@ -0,0 +1,55 @@
+#!/usr/bin/env php
+<?php
+
+require 'Test.php';
+
+plan( 11 );
+
+require_ok( 'includes/Defines.php' );
+require_ok( 'includes/GlobalFunctions.php' );
+require_ok( 'includes/Sanitizer.php' );
+require_ok( 'includes/normal/UtfNormal.php' );
+
+
+#
+# decodeCharReferences
+#
+
+cmp_ok(
+ Sanitizer::decodeCharReferences( '&eacute;cole' ),
+ '==',
+ "\xc3\xa9cole",
+ 'decode named entities'
+);
+
+cmp_ok(
+ Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&#233;cole!" ),
+ '==',
+ "\xc4\x88io bonas dans l'\xc3\xa9cole!",
+ 'decode numeric entities'
+);
+
+cmp_ok(
+ Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&eacute;cole!" ),
+ '==',
+ "\xc4\x88io bonas dans l'\xc3\xa9cole!",
+ 'decode mixed numeric/named entities'
+);
+
+cmp_ok(
+ Sanitizer::decodeCharReferences(
+ "&#x108;io bonas dans l'&eacute;cole! (mais pas &amp;#x108;io dans l'&#38;eacute;cole)"
+ ),
+ '==',
+ "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas &#x108;io dans l'&eacute;cole)",
+ 'decode mixed complex entities'
+);
+
+cmp_ok( Sanitizer::decodeCharReferences( 'a & b' ), '==', 'a & b', 'Invalid ampersand' );
+
+cmp_ok( Sanitizer::decodeCharReferences( '&foo;' ), '==', '&foo;', 'Invalid named entity' );
+
+cmp_ok( Sanitizer::decodeCharReferences( "&#88888888888888;" ), '==', UTF8_REPLACEMENT, 'Invalid numbered entity' );
+
+
+
diff --git a/t/inc/Xml.t b/t/inc/Xml.t
new file mode 100644
index 000000000000..bf95cce2b846
--- /dev/null
+++ b/t/inc/Xml.t
@@ -0,0 +1,56 @@
+#!/usr/bin/env php
+<?php
+
+require 'Test.php';
+
+plan( 8 );
+
+require_ok( 'includes/Sanitizer.php' );
+require_ok( 'includes/Xml.php' );
+
+#
+# element
+#
+
+cmp_ok(
+ Xml::element( 'element', null, null ),
+ '==',
+ '<element>',
+ 'Opening element with no attributes'
+);
+
+cmp_ok(
+ Xml::element( 'element', null, '' ),
+ '==',
+ '<element />',
+ 'Terminated empty element'
+);
+
+cmp_ok(
+ Xml::element( 'element', null, 'hello <there> you & you' ),
+ '==',
+ '<element>hello &lt;there&gt; you &amp; you</element>',
+ 'Element with no attributes and content that needs escaping'
+);
+
+cmp_ok(
+ Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ),
+ '==',
+ '<element key="value" <>="&lt;&gt;">',
+ 'Element attributes, keys are not escaped'
+);
+
+#
+# open/close element
+#
+
+cmp_ok(
+ Xml::openElement( 'element', array( 'k' => 'v' ) ),
+ '==',
+ '<element k="v">',
+ 'openElement() shortcut'
+);
+
+cmp_ok( Xml::closeElement( 'element' ), '==', '</element>', 'closeElement() shortcut' );
+
+?> \ No newline at end of file
diff --git a/tests/.htaccess b/tests/.htaccess
new file mode 100644
index 000000000000..3a4288278871
--- /dev/null
+++ b/tests/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/tests/.svnignore b/tests/.svnignore
new file mode 100644
index 000000000000..20cb61e90c1e
--- /dev/null
+++ b/tests/.svnignore
@@ -0,0 +1,6 @@
+LocalTestSettings.php
+*~
+bin
+.classpath
+.project
+project.index
diff --git a/tests/ArticleTest.php b/tests/ArticleTest.php
new file mode 100644
index 000000000000..bd678565c8c7
--- /dev/null
+++ b/tests/ArticleTest.php
@@ -0,0 +1,150 @@
+<?php
+
+require_once( 'PHPUnit.php' );
+require_once( '../includes/Defines.php' );
+require_once( '../includes/Article.php' );
+
+class ArticleTest extends PHPUnit_TestCase {
+ var $saveGlobals = array();
+
+ function ArticleTest( $name ) {
+ $this->PHPUnit_TestCase( $name );
+ }
+
+ function setUp() {
+ $globalSet = array(
+ 'wgLegacyEncoding' => false,
+ 'wgUseLatin1' => false,
+ 'wgCompressRevisions' => false,
+ 'wgInputEncoding' => 'utf-8',
+ 'wgOutputEncoding' => 'utf-8' );
+ foreach( $globalSet as $var => $data ) {
+ $this->saveGlobals[$var] = $GLOBALS[$var];
+ $GLOBALS[$var] = $data;
+ }
+ }
+
+ function tearDown() {
+ foreach( $this->saveGlobals as $var => $data ) {
+ $GLOBALS[$var] = $data;
+ }
+ }
+
+ function testGetRevisionText() {
+ $row = new stdClass;
+ $row->old_flags = '';
+ $row->old_text = 'This is a bunch of revision text.';
+ $this->assertEquals(
+ 'This is a bunch of revision text.',
+ Revision::getRevisionText( $row ) );
+ }
+
+ function testGetRevisionTextGzip() {
+ $row = new stdClass;
+ $row->old_flags = 'gzip';
+ $row->old_text = gzdeflate( 'This is a bunch of revision text.' );
+ $this->assertEquals(
+ 'This is a bunch of revision text.',
+ Revision::getRevisionText( $row ) );
+ }
+
+ function testGetRevisionTextUtf8Native() {
+ $row = new stdClass;
+ $row->old_flags = 'utf-8';
+ $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
+ $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
+ $this->assertEquals(
+ "Wiki est l'\xc3\xa9cole superieur !",
+ Revision::getRevisionText( $row ) );
+ }
+
+ function testGetRevisionTextUtf8Legacy() {
+ $row = new stdClass;
+ $row->old_flags = '';
+ $row->old_text = "Wiki est l'\xe9cole superieur !";
+ $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
+ $this->assertEquals(
+ "Wiki est l'\xc3\xa9cole superieur !",
+ Revision::getRevisionText( $row ) );
+ }
+
+ function testGetRevisionTextUtf8NativeGzip() {
+ $row = new stdClass;
+ $row->old_flags = 'gzip,utf-8';
+ $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" );
+ $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
+ $this->assertEquals(
+ "Wiki est l'\xc3\xa9cole superieur !",
+ Revision::getRevisionText( $row ) );
+ }
+
+ function testGetRevisionTextUtf8LegacyGzip() {
+ $row = new stdClass;
+ $row->old_flags = 'gzip';
+ $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" );
+ $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
+ $this->assertEquals(
+ "Wiki est l'\xc3\xa9cole superieur !",
+ Revision::getRevisionText( $row ) );
+ }
+
+ function testCompressRevisionTextUtf8() {
+ $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
+ $row->old_flags = Revision::compressRevisionText( $row->old_text );
+ $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ),
+ "Flags should contain 'utf-8'" );
+ $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ),
+ "Flags should not contain 'gzip'" );
+ $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
+ $row->old_text, "Direct check" );
+ $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
+ Revision::getRevisionText( $row ), "getRevisionText" );
+ }
+
+ function testCompressRevisionTextLatin1() {
+ $GLOBALS['wgUseLatin1'] = true;
+ $row->old_text = "Wiki est l'\xe9cole superieur !";
+ $row->old_flags = Revision::compressRevisionText( $row->old_text );
+ $this->assertFalse( false !== strpos( $row->old_flags, 'utf-8' ),
+ "Flags should not contain 'utf-8'" );
+ $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ),
+ "Flags should not contain 'gzip'" );
+ $this->assertEquals( "Wiki est l'\xe9cole superieur !",
+ $row->old_text, "Direct check" );
+ $this->assertEquals( "Wiki est l'\xe9cole superieur !",
+ Revision::getRevisionText( $row ), "getRevisionText" );
+ }
+
+ function testCompressRevisionTextUtf8Gzip() {
+ $GLOBALS['wgCompressRevisions'] = true;
+ $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
+ $row->old_flags = Revision::compressRevisionText( $row->old_text );
+ $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ),
+ "Flags should contain 'utf-8'" );
+ $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ),
+ "Flags should contain 'gzip'" );
+ $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
+ gzinflate( $row->old_text ), "Direct check" );
+ $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
+ Revision::getRevisionText( $row ), "getRevisionText" );
+ }
+
+ function testCompressRevisionTextLatin1Gzip() {
+ $GLOBALS['wgCompressRevisions'] = true;
+ $GLOBALS['wgUseLatin1'] = true;
+ $row = new stdClass;
+ $row->old_text = "Wiki est l'\xe9cole superieur !";
+ $row->old_flags = Revision::compressRevisionText( $row->old_text );
+ $this->assertFalse( false !== strpos( $row->old_flags, 'utf-8' ),
+ "Flags should not contain 'utf-8'" );
+ $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ),
+ "Flags should contain 'gzip'" );
+ $this->assertEquals( "Wiki est l'\xe9cole superieur !",
+ gzinflate( $row->old_text ), "Direct check" );
+ $this->assertEquals( "Wiki est l'\xe9cole superieur !",
+ Revision::getRevisionText( $row ), "getRevisionText" );
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/tests/DatabaseTest.php b/tests/DatabaseTest.php
new file mode 100644
index 000000000000..edb785dd0195
--- /dev/null
+++ b/tests/DatabaseTest.php
@@ -0,0 +1,93 @@
+<?php
+
+require_once( 'PHPUnit.php' );
+require_once( '../includes/Defines.php' );
+require_once( '../includes/Database.php' );
+require_once( '../includes/GlobalFunctions.php' );
+
+class DatabaseTest extends PHPUnit_TestCase {
+ var $db;
+
+ function DatabaseTest( $name ) {
+ $this->PHPUnit_TestCase( $name );
+ }
+
+ function setUp() {
+ $this->db = new Database();
+ }
+
+ function tearDown() {
+ unset( $this->db );
+ }
+
+ function testAddQuotesNull() {
+ $this->assertEquals(
+ 'NULL',
+ $this->db->addQuotes( NULL ) );
+ }
+
+ function testAddQuotesInt() {
+ # returning just "1234" should be ok too, though...
+ # maybe
+ $this->assertEquals(
+ "'1234'",
+ $this->db->addQuotes( 1234 ) );
+ }
+
+ function testAddQuotesFloat() {
+ # returning just "1234.5678" would be ok too, though
+ $this->assertEquals(
+ "'1234.5678'",
+ $this->db->addQuotes( 1234.5678 ) );
+ }
+
+ function testAddQuotesString() {
+ $this->assertEquals(
+ "'string'",
+ $this->db->addQuotes( 'string' ) );
+ }
+
+ function testAddQuotesStringQuote() {
+ $this->assertEquals(
+ "'string\'s cause trouble'",
+ $this->db->addQuotes( "string's cause trouble" ) );
+ }
+
+ function testFillPreparedEmpty() {
+ $sql = $this->db->fillPrepared(
+ 'SELECT * FROM interwiki', array() );
+ $this->assertEquals(
+ "SELECT * FROM interwiki",
+ $sql);
+ }
+
+ function testFillPreparedQuestion() {
+ $sql = $this->db->fillPrepared(
+ 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?',
+ array( 4, "Snicker's_paradox" ) );
+ $this->assertEquals(
+ "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'",
+ $sql);
+ }
+
+ function testFillPreparedBang() {
+ $sql = $this->db->fillPrepared(
+ 'SELECT user_id FROM ! WHERE user_name=?',
+ array( '"user"', "Slash's Dot" ) );
+ $this->assertEquals(
+ "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'",
+ $sql);
+ }
+
+ function testFillPreparedRaw() {
+ $sql = $this->db->fillPrepared(
+ "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'",
+ array( '"user"', "Slash's Dot" ) );
+ $this->assertEquals(
+ "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'",
+ $sql);
+ }
+
+}
+
+?>
diff --git a/tests/GlobalTest.php b/tests/GlobalTest.php
new file mode 100644
index 000000000000..1567a18908ae
--- /dev/null
+++ b/tests/GlobalTest.php
@@ -0,0 +1,211 @@
+<?php
+
+require_once( 'PHPUnit.php' );
+require_once( '../includes/Defines.php' );
+require_once( '../includes/Profiling.php' );
+require_once( '../includes/GlobalFunctions.php' );
+
+class GlobalTest extends PHPUnit_TestCase {
+ function GlobalTest( $name ) {
+ $this->PHPUnit_TestCase( $name );
+ }
+
+ function setUp() {
+ $this->save = array();
+ $saveVars = array( 'wgReadOnlyFile' );
+ foreach( $saveVars as $var ) {
+ if( isset( $GLOBALS[$var] ) ) {
+ $this->save[$var] = $GLOBALS[$var];
+ }
+ }
+ $GLOBALS['wgReadOnlyFile'] = wfTempDir() . '/testReadOnly-' . mt_rand();
+ }
+
+ function tearDown() {
+ foreach( $this->save as $var => $data ) {
+ $GLOBALS[$var] = $data;
+ }
+ }
+
+ function testRandom() {
+ # This could hypothetically fail, but it shouldn't ;)
+ $this->assertFalse(
+ wfRandom() == wfRandom() );
+ }
+
+ function testUrlencode() {
+ $this->assertEquals(
+ "%E7%89%B9%E5%88%A5:Contributions/Foobar",
+ wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) );
+ }
+
+ function testReadOnlyEmpty() {
+ $this->assertFalse( wfReadOnly() );
+ }
+
+ function testReadOnlySet() {
+ $f = fopen( $GLOBALS['wgReadOnlyFile'], "wt" );
+ fwrite( $f, 'Message' );
+ fclose( $f );
+ $this->assertTrue( wfReadOnly() );
+
+ unlink( $GLOBALS['wgReadOnlyFile'] );
+ $this->assertFalse( wfReadOnly() );
+ }
+
+ function testQuotedPrintable() {
+ $this->assertEquals(
+ "=?UTF-8?Q?=C4=88u=20legebla=3F?=",
+ wfQuotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) );
+ }
+
+ function testTime() {
+ $start = wfTime();
+ $this->assertType( 'double', $start );
+ $end = wfTime();
+ $this->assertTrue( $end > $start, "Time is running backwards!" );
+ }
+
+ function testArrayToCGI() {
+ $this->assertEquals(
+ "baz=AT%26T&foo=bar",
+ wfArrayToCGI(
+ array( 'baz' => 'AT&T', 'ignore' => '' ),
+ array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) );
+ }
+
+ function testMimeTypeMatch() {
+ $this->assertEquals(
+ 'text/html',
+ mimeTypeMatch( 'text/html',
+ array( 'application/xhtml+xml' => 1.0,
+ 'text/html' => 0.7,
+ 'text/plain' => 0.3 ) ) );
+ $this->assertEquals(
+ 'text/*',
+ mimeTypeMatch( 'text/html',
+ array( 'image/*' => 1.0,
+ 'text/*' => 0.5 ) ) );
+ $this->assertEquals(
+ '*/*',
+ mimeTypeMatch( 'text/html',
+ array( '*/*' => 1.0 ) ) );
+ $this->assertNull(
+ mimeTypeMatch( 'text/html',
+ array( 'image/png' => 1.0,
+ 'image/svg+xml' => 0.5 ) ) );
+ }
+
+ function testNegotiateType() {
+ $this->assertEquals(
+ 'text/html',
+ wfNegotiateType(
+ array( 'application/xhtml+xml' => 1.0,
+ 'text/html' => 0.7,
+ 'text/plain' => 0.5,
+ 'text/*' => 0.2 ),
+ array( 'text/html' => 1.0 ) ) );
+ $this->assertEquals(
+ 'application/xhtml+xml',
+ wfNegotiateType(
+ array( 'application/xhtml+xml' => 1.0,
+ 'text/html' => 0.7,
+ 'text/plain' => 0.5,
+ 'text/*' => 0.2 ),
+ array( 'application/xhtml+xml' => 1.0,
+ 'text/html' => 0.5 ) ) );
+ $this->assertEquals(
+ 'text/html',
+ wfNegotiateType(
+ array( 'text/html' => 1.0,
+ 'text/plain' => 0.5,
+ 'text/*' => 0.5,
+ 'application/xhtml+xml' => 0.2 ),
+ array( 'application/xhtml+xml' => 1.0,
+ 'text/html' => 0.5 ) ) );
+ $this->assertEquals(
+ 'text/html',
+ wfNegotiateType(
+ array( 'text/*' => 1.0,
+ 'image/*' => 0.7,
+ '*/*' => 0.3 ),
+ array( 'application/xhtml+xml' => 1.0,
+ 'text/html' => 0.5 ) ) );
+ $this->assertNull(
+ wfNegotiateType(
+ array( 'text/*' => 1.0 ),
+ array( 'application/xhtml+xml' => 1.0 ) ) );
+ }
+
+ function testTimestamp() {
+ $t = gmmktime( 12, 34, 56, 1, 15, 2001 );
+ $this->assertEquals(
+ '20010115123456',
+ wfTimestamp( TS_MW, $t ),
+ 'TS_UNIX to TS_MW' );
+ $this->assertEquals(
+ 979562096,
+ wfTimestamp( TS_UNIX, $t ),
+ 'TS_UNIX to TS_UNIX' );
+ $this->assertEquals(
+ '2001-01-15 12:34:56',
+ wfTimestamp( TS_DB, $t ),
+ 'TS_UNIX to TS_DB' );
+
+ $this->assertEquals(
+ '20010115123456',
+ wfTimestamp( TS_MW, '20010115123456' ),
+ 'TS_MW to TS_MW' );
+ $this->assertEquals(
+ 979562096,
+ wfTimestamp( TS_UNIX, '20010115123456' ),
+ 'TS_MW to TS_UNIX' );
+ $this->assertEquals(
+ '2001-01-15 12:34:56',
+ wfTimestamp( TS_DB, '20010115123456' ),
+ 'TS_MW to TS_DB' );
+
+ $this->assertEquals(
+ '20010115123456',
+ wfTimestamp( TS_MW, '2001-01-15 12:34:56' ),
+ 'TS_DB to TS_MW' );
+ $this->assertEquals(
+ 979562096,
+ wfTimestamp( TS_UNIX, '2001-01-15 12:34:56' ),
+ 'TS_DB to TS_UNIX' );
+ $this->assertEquals(
+ '2001-01-15 12:34:56',
+ wfTimestamp( TS_DB, '2001-01-15 12:34:56' ),
+ 'TS_DB to TS_DB' );
+ }
+
+ function testBasename() {
+ $sets = array(
+ '' => '',
+ '/' => '',
+ '\\' => '',
+ '//' => '',
+ '\\\\' => '',
+ 'a' => 'a',
+ 'aaaa' => 'aaaa',
+ '/a' => 'a',
+ '\\a' => 'a',
+ '/aaaa' => 'aaaa',
+ '\\aaaa' => 'aaaa',
+ '/aaaa/' => 'aaaa',
+ '\\aaaa\\' => 'aaaa',
+ '\\aaaa\\' => 'aaaa',
+ '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg' => '93px-Zork_Grand_Inquisitor_box_cover.jpg',
+ 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE' => 'VIEWER.EXE',
+ 'Östergötland_coat_of_arms.png' => 'Östergötland_coat_of_arms.png',
+ );
+ foreach( $sets as $from => $to ) {
+ $this->assertEquals( $to, wfBaseName( $from ),
+ "wfBaseName('$from') => '$to'");
+ }
+ }
+
+ /* TODO: many more! */
+}
+
+?> \ No newline at end of file
diff --git a/tests/ImageTest.php b/tests/ImageTest.php
new file mode 100644
index 000000000000..b06d4cbf9086
--- /dev/null
+++ b/tests/ImageTest.php
@@ -0,0 +1,66 @@
+<?php
+
+require_once( 'PHPUnit.php' );
+require_once( '../includes/Defines.php' );
+require_once( '../includes/Profiling.php' );
+require_once( '../includes/GlobalFunctions.php' );
+require_once( '../includes/Image.php' );
+
+class ImageTest extends PHPUnit_TestCase {
+ function ImageTest( $name ) {
+ $this->PHPUnit_TestCase( $name );
+ }
+
+ function setUp() {
+ }
+
+ function tearDown() {
+ }
+
+ function testFitBoxWidth() {
+ $vals = array(
+ array(
+ 'width' => 50,
+ 'height' => 50,
+ 'tests' => array(
+ 50 => 50,
+ 17 => 17,
+ 18 => 18 ) ),
+ array(
+ 'width' => 366,
+ 'height' => 300,
+ 'tests' => array(
+ 50 => 61,
+ 17 => 21,
+ 18 => 22 ) ),
+ array(
+ 'width' => 300,
+ 'height' => 366,
+ 'tests' => array(
+ 50 => 41,
+ 17 => 14,
+ 18 => 15 ) ),
+ array(
+ 'width' => 100,
+ 'height' => 400,
+ 'tests' => array(
+ 50 => 12,
+ 17 => 4,
+ 18 => 4 ) ) );
+ foreach( $vals as $row ) {
+ extract( $row );
+ foreach( $tests as $max => $expected ) {
+ $y = round( $expected * $height / $width );
+ $result = wfFitBoxWidth( $width, $height, $max );
+ $y2 = round( $result * $height / $width );
+ $this->assertEquals( $expected,
+ $result,
+ "($width, $height, $max) wanted: {$expected}x$y, got: {$result}x$y2" );
+ }
+ }
+ }
+
+ /* TODO: many more! */
+}
+
+?> \ No newline at end of file
diff --git a/tests/LocalTestSettings.sample b/tests/LocalTestSettings.sample
new file mode 100644
index 000000000000..7ada2fda9113
--- /dev/null
+++ b/tests/LocalTestSettings.sample
@@ -0,0 +1,29 @@
+<?php
+# This contains basic configuration values that are needed
+# for RunTests.php.
+
+# Full path to the mediawiki source code you want to test
+$IP = '/var/www/mediawiki-cvs';
+
+# Now we add that path to the default include_path
+ini_set('include_path',ini_get('include_path').':'.$IP);
+
+# Some options needed for database testing
+$testOptions = array(
+ 'mysql3' => array(
+ 'server' => null,
+ 'user' => null,
+ 'password' => null,
+ 'database' => null ),
+ 'mysql4' => array(
+ 'server' => null,
+ 'user' => null,
+ 'password' => null,
+ 'database' => null ),
+ 'postgres' => array(
+ 'server' => null,
+ 'user' => null,
+ 'password' => null,
+ 'database' => null ),
+ );
+?>
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 000000000000..0a649927ed17
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,15 @@
+.PHONY: help test
+all test:
+ php RunTests.php
+install:
+ cvs -z9 -d:pserver:cvsread:@cvs.php.net:/repository/ co -P pear/PHPUnit
+ mv pear/PHPUnit .
+ rm -rf pear
+clean:
+ rm -rf PHPUnit pear
+help:
+ # Options:
+ # test (default) Run the unit tests
+ # install Install PHPUnit from CVS
+ # clean Remove local PHPUnit install
+ # help You're looking at it!
diff --git a/tests/README b/tests/README
new file mode 100644
index 000000000000..de153184fabf
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,8 @@
+Some quickie unit tests done with the PHPUnit testing framework. To run the
+test suite, run 'make test' in this dir or 'php RunTests.php'
+
+You can install PHPUnit via pear like this:
+# pear install PHPUnit
+
+Or fetch and install it manually:
+http://pear.php.net/package/PHPUnit
diff --git a/tests/RunTests.php b/tests/RunTests.php
new file mode 100644
index 000000000000..2b539a479598
--- /dev/null
+++ b/tests/RunTests.php
@@ -0,0 +1,100 @@
+<?php
+
+if( php_sapi_name() != 'cli' ) {
+ echo 'Must be run from the command line.';
+ die( -1 );
+}
+
+error_reporting( E_ALL );
+define( "MEDIAWIKI", true );
+
+set_include_path( get_include_path() . PATH_SEPARATOR . 'PHPUnit' );
+set_include_path( get_include_path() . PATH_SEPARATOR . '..' );
+require_once( 'PHPUnit.php' );
+
+$testOptions = array(
+ 'mysql4' => array(
+ 'server' => null,
+ 'user' => null,
+ 'password' => null,
+ 'database' => null ),
+ 'postgres' => array(
+ 'server' => null,
+ 'user' => null,
+ 'password' => null,
+ 'database' => null ),
+ );
+
+if( file_exists( 'LocalTestSettings.php' ) ) {
+ include( './LocalTestSettings.php' );
+}
+
+$tests = array(
+ 'GlobalTest',
+ 'DatabaseTest',
+ 'SearchMySQL4Test',
+ 'ArticleTest',
+ 'SanitizerTest',
+ 'ImageTest'
+ );
+
+if( isset( $_SERVER['argv'][1] ) ) {
+ // to override...
+ $tests = array( $_SERVER['argv'][1] );
+}
+
+foreach( $tests as $test ) {
+ require_once( $test . '.php' );
+ $suite = new PHPUnit_TestSuite( $test );
+ $result = PHPUnit::run( $suite );
+ echo $result->toString();
+}
+
+/**
+ * @param string $serverType
+ * @param array $tables
+ */
+function &buildTestDatabase( $serverType, $tables ) {
+ global $testOptions, $wgDBprefix;
+ $wgDBprefix = 'parsertest';
+ $db = new Database(
+ $testOptions[$serverType]['server'],
+ $testOptions[$serverType]['user'],
+ $testOptions[$serverType]['password'],
+ $testOptions[$serverType]['database'] );
+ if( $db->isOpen() ) {
+ if (!(strcmp($db->getServerVersion(), '4.1') < 0 and stristr($db->getSoftwareLink(), 'MySQL'))) {
+ # Database that supports CREATE TABLE ... LIKE
+ foreach ($tables as $tbl) {
+ $newTableName = $db->tableName( $tbl );
+ #$tableName = $this->oldTableNames[$tbl];
+ $tableName = $tbl;
+ $db->query("CREATE TEMPORARY TABLE $newTableName (LIKE $tableName INCLUDING DEFAULTS)");
+ }
+ } else {
+ # Hack for MySQL versions < 4.1, which don't support
+ # "CREATE TABLE ... LIKE". Note that
+ # "CREATE TEMPORARY TABLE ... SELECT * FROM ... LIMIT 0"
+ # would not create the indexes we need....
+ foreach ($tables as $tbl) {
+ $res = $db->query("SHOW CREATE TABLE $tbl");
+ $row = $db->fetchRow($res);
+ $create = $row[1];
+ $create_tmp = preg_replace('/CREATE TABLE `(.*?)`/', 'CREATE TEMPORARY TABLE `'
+ . $wgDBprefix . '\\1`', $create);
+ if ($create === $create_tmp) {
+ # Couldn't do replacement
+ wfDie( "could not create temporary table $tbl" );
+ }
+ $db->query($create_tmp);
+ }
+
+ }
+ return $db;
+ } else {
+ // Something amiss
+ return null;
+ }
+}
+
+?>
diff --git a/tests/SanitizerTest.php b/tests/SanitizerTest.php
new file mode 100644
index 000000000000..5babf0ae776b
--- /dev/null
+++ b/tests/SanitizerTest.php
@@ -0,0 +1,65 @@
+<?php
+
+require_once( 'PHPUnit.php' );
+require_once( '../includes/Defines.php' );
+require_once( '../includes/Profiling.php' );
+require_once( '../includes/GlobalFunctions.php' );
+require_once( '../includes/Sanitizer.php' );
+
+class SanitizerTest extends PHPUnit_TestCase {
+ function SanitizerTest( $name ) {
+ $this->PHPUnit_TestCase( $name );
+ }
+
+ function setUp() {
+ }
+
+ function tearDown() {
+ }
+
+ function testDecodeNamed() {
+ $this->assertEquals(
+ "\xc3\xa9cole",
+ Sanitizer::decodeCharReferences( '&eacute;cole' ) );
+ }
+
+ function testDecodeNumbered() {
+ $this->assertEquals(
+ "\xc4\x88io bonas dans l'\xc3\xa9cole!",
+ Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&#233;cole!" ) );
+ }
+
+ function testDecodeMixed() {
+ $this->assertEquals(
+ "\xc4\x88io bonas dans l'\xc3\xa9cole!",
+ Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&eacute;cole!" ) );
+ }
+
+ function testDecodeMixedComplex() {
+ $this->assertEquals(
+ "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas &#x108;io dans l'&eacute;cole)",
+ Sanitizer::decodeCharReferences( "&#x108;io bonas dans l'&eacute;cole! (mais pas &amp;#x108;io dans l'&#38;eacute;cole)" ) );
+ }
+
+ function testDecodeInvalidAmp() {
+ $this->assertEquals(
+ "a & b",
+ Sanitizer::decodeCharReferences( "a & b" ) );
+ }
+
+ function testDecodeInvalidNamed() {
+ $this->assertEquals(
+ "&foo;",
+ Sanitizer::decodeCharReferences( "&foo;" ) );
+ }
+
+ function testDecodeInvalidNumbered() {
+ $this->assertEquals(
+ UTF8_REPLACEMENT,
+ Sanitizer::decodeCharReferences( "&#88888888888888;" ) );
+ }
+
+ /* TODO: many more! */
+}
+
+?> \ No newline at end of file
diff --git a/tests/SearchEngineTest.php b/tests/SearchEngineTest.php
new file mode 100644
index 000000000000..0a02c49c9c18
--- /dev/null
+++ b/tests/SearchEngineTest.php
@@ -0,0 +1,135 @@
+<?php
+
+$IP = '..';
+require_once( 'PHPUnit.php' );
+require_once( '../includes/Defines.php' );
+require_once( '../includes/DefaultSettings.php' );
+require_once( '../includes/Profiling.php' );
+require_once( '../includes/Hooks.php' );
+require_once( '../includes/MagicWord.php' );
+require_once( '../languages/Language.php' );
+
+require_once( '../includes/SearchEngine.php' );
+
+/** @todo document */
+class SearchEngine_TestCase extends PHPUnit_TestCase {
+ var $db, $search;
+
+ function insertSearchData() {
+ $this->db->safeQuery( <<<END
+ INSERT INTO ! (page_id,page_namespace,page_title,page_latest)
+ VALUES (1, 0, 'Main_Page', 1),
+ (2, 1, 'Main_Page', 2),
+ (3, 0, 'Smithee', 3),
+ (4, 1, 'Smithee', 4),
+ (5, 0, 'Unrelated_page', 5),
+ (6, 0, 'Another_page', 6),
+ (7, 4, 'Help', 7),
+ (8, 0, 'Thppt', 8),
+ (9, 0, 'Alan_Smithee', 9),
+ (10, 0, 'Pages', 10)
+END
+ , $this->db->tableName( 'page' ) );
+ $this->db->safeQuery( <<<END
+ INSERT INTO ! (rev_id,rev_page)
+ VALUES (1, 1),
+ (2, 2),
+ (3, 3),
+ (4, 4),
+ (5, 5),
+ (6, 6),
+ (7, 7),
+ (8, 8),
+ (9, 9),
+ (10, 10)
+END
+ , $this->db->tableName( 'revision' ) );
+ $this->db->safeQuery( <<<END
+ INSERT INTO ! (old_id,old_text)
+ VALUES (1, 'This is a main page'),
+ (2, 'This is a talk page to the main page, see [[smithee]]'),
+ (3, 'A smithee is one who smiths. See also [[Alan Smithee]]'),
+ (4, 'This article sucks.'),
+ (5, 'Nothing in this page is about the S word.'),
+ (6, 'This page also is unrelated.'),
+ (7, 'Help me!'),
+ (8, 'Blah blah'),
+ (9, 'yum'),
+ (10,'are food')
+END
+ , $this->db->tableName( 'text' ) );
+ $this->db->safeQuery( <<<END
+ INSERT INTO ! (si_page,si_title,si_text)
+ VALUES (1, 'main page', 'this is a main page'),
+ (2, 'main page', 'this is a talk page to the main page, see smithee'),
+ (3, 'smithee', 'a smithee is one who smiths see also alan smithee'),
+ (4, 'smithee', 'this article sucks'),
+ (5, 'unrelated page', 'nothing in this page is about the s word'),
+ (6, 'another page', 'this page also is unrelated'),
+ (7, 'help', 'help me'),
+ (8, 'thppt', 'blah blah'),
+ (9, 'alan smithee', 'yum'),
+ (10, 'pages', 'are food')
+END
+ , $this->db->tableName( 'searchindex' ) );
+ }
+
+ function fetchIds( &$results ) {
+ $matches = array();
+ while( $row = $results->fetchObject() ) {
+ $matches[] = intval( $row->page_id );
+ }
+ $results->free();
+ # Search is not guaranteed to return results in a certain order;
+ # sort them numerically so we will compare simply that we received
+ # the expected matches.
+ sort( $matches );
+ return $matches;
+ }
+
+ function testTextSearch() {
+ $this->assertFalse( is_null( $this->db ), "Can't find a database to test with." );
+ if( !is_null( $this->db ) ) {
+ $this->assertEquals(
+ array( 3 ),
+ $this->fetchIds( $this->search->searchText( 'smithee' ) ),
+ "Plain search failed" );
+ }
+ }
+
+ function testTextPowerSearch() {
+ $this->assertFalse( is_null( $this->db ), "Can't find a database to test with." );
+ if( !is_null( $this->db ) ) {
+ $this->search->setNamespaces( array( 0, 1, 4 ) );
+ $this->assertEquals(
+ array( 2, 3 ),
+ $this->fetchIds( $this->search->searchText( 'smithee' ) ),
+ "Power search failed" );
+ }
+ }
+
+ function testTitleSearch() {
+ $this->assertFalse( is_null( $this->db ), "Can't find a database to test with." );
+ if( !is_null( $this->db ) ) {
+ $this->assertEquals(
+ array( 3, 9 ),
+ $this->fetchIds( $this->search->searchTitle( 'smithee' ) ),
+ "Title search failed" );
+ }
+ }
+
+ function testTextTitlePowerSearch() {
+ $this->assertFalse( is_null( $this->db ), "Can't find a database to test with." );
+ if( !is_null( $this->db ) ) {
+ $this->search->setNamespaces( array( 0, 1, 4 ) );
+ $this->assertEquals(
+ array( 3, 4, 9 ),
+ $this->fetchIds( $this->search->searchTitle( 'smithee' ) ),
+ "Title power search failed" );
+ }
+ }
+
+}
+
+
+?>
diff --git a/tests/SearchMySQL4Test.php b/tests/SearchMySQL4Test.php
new file mode 100644
index 000000000000..6277e6ca34c2
--- /dev/null
+++ b/tests/SearchMySQL4Test.php
@@ -0,0 +1,34 @@
+<?php
+
+require_once( 'SearchEngineTest.php' );
+require_once( '../includes/SearchMySQL4.php' );
+
+class SearchMySQL4Test extends SearchEngine_TestCase {
+ var $db;
+
+ function SearchMySQL4Test( $name ) {
+ $this->PHPUnit_TestCase( $name );
+ }
+
+ function setUp() {
+ $GLOBALS['wgContLang'] = new Language;
+ $this->db =& buildTestDatabase(
+ 'mysql4',
+ array( 'page', 'revision', 'text', 'searchindex' ) );
+ if( $this->db ) {
+ $this->insertSearchData();
+ }
+ $this->search = new SearchMySQL4( $this->db );
+ }
+
+ function tearDown() {
+ if( !is_null( $this->db ) ) {
+ $this->db->close();
+ }
+ unset( $this->db );
+ unset( $this->search );
+ }
+
+}
+
+?>
diff --git a/tests/test-prefetch-current.xml b/tests/test-prefetch-current.xml
new file mode 100644
index 000000000000..a4c8bda30bad
--- /dev/null
+++ b/tests/test-prefetch-current.xml
@@ -0,0 +1,75 @@
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en">
+<siteinfo>
+ <sitename>DemoWiki</sitename>
+ <base>http://example.com/wiki/Main_Page</base>
+ <generator>MediaWiki 1.5.0</generator>
+ <case>first-letter</case>
+ <namespaces>
+ <namespace key="-2">Media</namespace>
+ <namespace key="-1">Special</namespace>
+ <namespace key="0"></namespace>
+ <namespace key="1">Talk</namespace>
+ <namespace key="2">User</namespace>
+ <namespace key="3">User talk</namespace>
+ <namespace key="4">DemoWiki</namespace>
+ <namespace key="5">DemoWIki talk</namespace>
+ <namespace key="6">Image</namespace>
+ <namespace key="7">Image talk</namespace>
+ <namespace key="8">MediaWiki</namespace>
+ <namespace key="9">MediaWiki talk</namespace>
+ <namespace key="10">Template</namespace>
+ <namespace key="11">Template talk</namespace>
+ <namespace key="12">Help</namespace>
+ <namespace key="13">Help talk</namespace>
+ <namespace key="14">Category</namespace>
+ <namespace key="15">Category talk</namespace>
+ </namespaces>
+</siteinfo>
+<page>
+ <title>First page</title>
+ <id>1</id>
+ <revision>
+ <id>1</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 1</comment>
+ <text>page 1, rev 1</text>
+ </revision>
+ <revision>
+ <id>2</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 2</comment>
+ <text>page 1, rev 2</text>
+ </revision>
+ <revision>
+ <id>4</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 4</comment>
+ <text>page 1, rev 4</text>
+ </revision>
+</page>
+<page>
+ <title>Second page</title>
+ <id>2</id>
+ <revision>
+ <id>3</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 2, rev 3</comment>
+ <text>page 2, rev 3</text>
+ </revision>
+</page>
+<page>
+ <title>Third page</title>
+ <id>3</id>
+ <revision>
+ <id>5</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 3, rev 5</comment>
+ <text>page 3, rev 5</text>
+ </revision>
+</page>
+</mediawiki>
diff --git a/tests/test-prefetch-previous.xml b/tests/test-prefetch-previous.xml
new file mode 100644
index 000000000000..95eb82dd4f52
--- /dev/null
+++ b/tests/test-prefetch-previous.xml
@@ -0,0 +1,57 @@
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en">
+<siteinfo>
+ <sitename>DemoWiki</sitename>
+ <base>http://example.com/wiki/Main_Page</base>
+ <generator>MediaWiki 1.5.0</generator>
+ <case>first-letter</case>
+ <namespaces>
+ <namespace key="-2">Media</namespace>
+ <namespace key="-1">Special</namespace>
+ <namespace key="0"></namespace>
+ <namespace key="1">Talk</namespace>
+ <namespace key="2">User</namespace>
+ <namespace key="3">User talk</namespace>
+ <namespace key="4">DemoWiki</namespace>
+ <namespace key="5">DemoWIki talk</namespace>
+ <namespace key="6">Image</namespace>
+ <namespace key="7">Image talk</namespace>
+ <namespace key="8">MediaWiki</namespace>
+ <namespace key="9">MediaWiki talk</namespace>
+ <namespace key="10">Template</namespace>
+ <namespace key="11">Template talk</namespace>
+ <namespace key="12">Help</namespace>
+ <namespace key="13">Help talk</namespace>
+ <namespace key="14">Category</namespace>
+ <namespace key="15">Category talk</namespace>
+ </namespaces>
+</siteinfo>
+<page>
+ <title>First page</title>
+ <id>1</id>
+ <revision>
+ <id>1</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 1</comment>
+ <text>page 1, rev 1</text>
+ </revision>
+ <revision>
+ <id>2</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 2</comment>
+ <text>page 1, rev 2</text>
+ </revision>
+</page>
+<page>
+ <title>Second page</title>
+ <id>2</id>
+ <revision>
+ <id>3</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 2, rev 3</comment>
+ <text>page 2, rev 3</text>
+ </revision>
+</page>
+</mediawiki>
diff --git a/tests/test-prefetch-stub.xml b/tests/test-prefetch-stub.xml
new file mode 100644
index 000000000000..59d43d2f353c
--- /dev/null
+++ b/tests/test-prefetch-stub.xml
@@ -0,0 +1,75 @@
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en">
+<siteinfo>
+ <sitename>DemoWiki</sitename>
+ <base>http://example.com/wiki/Main_Page</base>
+ <generator>MediaWiki 1.5.0</generator>
+ <case>first-letter</case>
+ <namespaces>
+ <namespace key="-2">Media</namespace>
+ <namespace key="-1">Special</namespace>
+ <namespace key="0"></namespace>
+ <namespace key="1">Talk</namespace>
+ <namespace key="2">User</namespace>
+ <namespace key="3">User talk</namespace>
+ <namespace key="4">DemoWiki</namespace>
+ <namespace key="5">DemoWIki talk</namespace>
+ <namespace key="6">Image</namespace>
+ <namespace key="7">Image talk</namespace>
+ <namespace key="8">MediaWiki</namespace>
+ <namespace key="9">MediaWiki talk</namespace>
+ <namespace key="10">Template</namespace>
+ <namespace key="11">Template talk</namespace>
+ <namespace key="12">Help</namespace>
+ <namespace key="13">Help talk</namespace>
+ <namespace key="14">Category</namespace>
+ <namespace key="15">Category talk</namespace>
+ </namespaces>
+</siteinfo>
+<page>
+ <title>First page</title>
+ <id>1</id>
+ <revision>
+ <id>1</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 1</comment>
+ <text id="1" />
+ </revision>
+ <revision>
+ <id>2</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 2</comment>
+ <text id="2" />
+ </revision>
+ <revision>
+ <id>4</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 1, rev 4</comment>
+ <text id="4" />
+ </revision>
+</page>
+<page>
+ <title>Second page</title>
+ <id>2</id>
+ <revision>
+ <id>3</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 2, rev 3</comment>
+ <text id="3" />
+ </revision>
+</page>
+<page>
+ <title>Third page</title>
+ <id>3</id>
+ <revision>
+ <id>5</id>
+ <timestamp>2001-01-15T12:00:00Z</timestamp>
+ <contributor><ip>10.0.0.1</ip></contributor>
+ <comment>page 3, rev 5</comment>
+ <text id="5" />
+ </revision>
+</page>
+</mediawiki>
diff --git a/thumb.php b/thumb.php
new file mode 100644
index 000000000000..206019dfd1d8
--- /dev/null
+++ b/thumb.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * PHP script to stream out an image thumbnail.
+ * If the file exists, we make do with abridged MediaWiki initialisation.
+ */
+define( 'MW_NO_SETUP', 1 );
+require_once( './includes/WebStart.php' );
+wfProfileIn( 'thumb.php' );
+wfProfileIn( 'thumb.php-start' );
+require_once( 'GlobalFunctions.php' );
+require_once( 'ImageFunctions.php' );
+
+$wgTrivialMimeDetection = true; //don't use fancy mime detection, just check the file extension for jpg/gif/png.
+
+require_once( 'Image.php' );
+require_once( 'StreamFile.php' );
+
+// Get input parameters
+$fileName = isset( $_REQUEST['f'] ) ? $_REQUEST['f'] : '';
+$width = isset( $_REQUEST['w'] ) ? intval( $_REQUEST['w'] ) : 0;
+$page = isset( $_REQUEST['p'] ) ? intval( $_REQUEST['p'] ) : null;
+
+if ( get_magic_quotes_gpc() ) {
+ $fileName = stripslashes( $fileName );
+}
+
+$pre_render= isset($_REQUEST['r']) && $_REQUEST['r']!="0";
+
+// Some basic input validation
+$fileName = strtr( $fileName, '\\/', '__' );
+
+// Work out paths, carefully avoiding constructing an Image object because that won't work yet
+
+$imagePath = wfImageDir( $fileName ) . '/' . $fileName;
+$thumbName = "{$width}px-$fileName";
+if ( ! is_null( $page ) ) {
+ $thumbName = 'page' . $page . '-' . $thumbName;
+}
+if ( $pre_render ) {
+ $thumbName .= '.png';
+}
+$thumbPath = wfImageThumbDir( $fileName ) . '/' . $thumbName;
+
+if ( is_file( $thumbPath ) && filemtime( $thumbPath ) >= filemtime( $imagePath ) ) {
+ wfStreamFile( $thumbPath );
+ // Can't log profiling data with no Setup.php
+ exit;
+}
+
+// OK, no valid thumbnail, time to get out the heavy machinery
+wfProfileOut( 'thumb.php-start' );
+require_once( 'Setup.php' );
+wfProfileIn( 'thumb.php-render' );
+
+$img = Image::newFromName( $fileName );
+try {
+ if ( $img ) {
+ if ( ! is_null( $page ) ) {
+ $img->selectPage( $page );
+ }
+ $thumb = $img->renderThumb( $width, false );
+ } else {
+ $thumb = false;
+ }
+} catch( Exception $ex ) {
+ // Tried to select a page on a non-paged file?
+ $thumb = false;
+}
+
+if ( $thumb && $thumb->path ) {
+ wfStreamFile( $thumb->path );
+} else {
+ $badtitle = wfMsg( 'badtitle' );
+ $badtitletext = wfMsg( 'badtitletext' );
+ header( 'Cache-Control: no-cache' );
+ header( 'Content-Type: text/html; charset=utf-8' );
+ echo "<html><head>
+ <title>$badtitle</title>
+ <body>
+<h1>$badtitle</h1>
+<p>$badtitletext</p>
+</body></html>
+";
+}
+
+wfProfileOut( 'thumb.php-render' );
+wfProfileOut( 'thumb.php' );
+wfLogProfilingData();
+
+?>
diff --git a/trackback.php b/trackback.php
new file mode 100644
index 000000000000..6e4ee9828eed
--- /dev/null
+++ b/trackback.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Provide functions to handle article trackbacks.
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+require_once( './includes/WebStart.php' );
+
+require_once('DatabaseFunctions.php');
+
+/**
+ *
+ */
+function XMLsuccess() {
+ header("Content-Type: application/xml; charset=utf-8");
+ echo "
+<?xml version=\"1.0\" encoding=\"utf-8\"?>
+<response>
+<error>0</error>
+</response>
+ ";
+ exit;
+}
+
+function XMLerror($err = "Invalid request.") {
+ header("HTTP/1.0 400 Bad Request");
+ header("Content-Type: application/xml; charset=utf-8");
+ echo "
+<?xml version=\"1.0\" encoding=\"utf-8\"?>
+<response>
+<error>1</error>
+<message>Invalid request: $err</message>
+</response>
+";
+ exit;
+}
+
+if (!$wgUseTrackbacks)
+ XMLerror("Trackbacks are disabled.");
+
+if ( !isset($_POST['url'])
+ || !isset($_POST['blog_name'])
+ || !isset($_REQUEST['article']))
+ XMLerror("Required field not specified");
+
+$dbw =& wfGetDB(DB_MASTER);
+
+$tbtitle = $_POST['title'];
+$tbex = $_POST['excerpt'];
+$tburl = $_POST['url'];
+$tbname = $_POST['blog_name'];
+$tbarticle = $_REQUEST['article'];
+
+$title = Title::newFromText($tbarticle);
+if (!isset($title) || !$title->exists())
+ XMLerror("Specified article does not exist.");
+
+$dbw->insert('trackbacks', array(
+ 'tb_page' => $title->getArticleID(),
+ 'tb_title' => $tbtitle,
+ 'tb_url' => $tburl,
+ 'tb_ex' => $tbex,
+ 'tb_name' => $tbname
+));
+
+XMLsuccess();
+exit;
+?>
diff --git a/wiki.phtml b/wiki.phtml
new file mode 100644
index 000000000000..5f6b019965b6
--- /dev/null
+++ b/wiki.phtml
@@ -0,0 +1,4 @@
+<?php
+// stub file for compatibility with older versions
+include_once('./index.php');
+?> \ No newline at end of file